summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-06-18 11:18:50 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-06-18 11:18:50 +0000
commit8c7f4e9d5f36cff46365a7f8c4b9c21578c1e781 (patch)
treea77e7fe7a93de11213032ed4ab1f33a3db51b738
parent00b35af3db1abfe813a778f643dad221aad51fca (diff)
downloadgitlab-ce-8c7f4e9d5f36cff46365a7f8c4b9c21578c1e781.tar.gz
Add latest changes from gitlab-org/gitlab@13-1-stable-ee
-rw-r--r--.editorconfig3
-rw-r--r--.eslintignore1
-rw-r--r--.gitignore4
-rw-r--r--.gitlab-ci.yml2
-rw-r--r--.gitlab/CODEOWNERS14
-rw-r--r--.gitlab/ci/docs.gitlab-ci.yml2
-rw-r--r--.gitlab/ci/frontend.gitlab-ci.yml273
-rw-r--r--.gitlab/ci/global.gitlab-ci.yml61
-rw-r--r--.gitlab/ci/memory.gitlab-ci.yml5
-rw-r--r--.gitlab/ci/pages.gitlab-ci.yml7
-rw-r--r--.gitlab/ci/qa.gitlab-ci.yml19
-rw-r--r--.gitlab/ci/rails.gitlab-ci.yml80
-rw-r--r--.gitlab/ci/reports.gitlab-ci.yml67
-rw-r--r--.gitlab/ci/review.gitlab-ci.yml311
-rw-r--r--.gitlab/ci/rules.gitlab-ci.yml105
-rw-r--r--.gitlab/ci/setup.gitlab-ci.yml2
-rw-r--r--.gitlab/ci/test-metadata.gitlab-ci.yml9
-rw-r--r--.gitlab/issue_templates/Acceptance Testing.md (renamed from .gitlab/issue_templates/Acceptance_Testing.md)0
-rw-r--r--.gitlab/issue_templates/Problem Validation.md (renamed from .gitlab/issue_templates/Problem_Validation.md)0
-rw-r--r--.gitlab/issue_templates/QA Failure.md (renamed from .gitlab/issue_templates/QA failure.md)0
-rw-r--r--.gitlab/issue_templates/Solution Validation.md (renamed from .gitlab/issue_templates/Solution_validation)0
-rw-r--r--.gitlab/issue_templates/Test Plan.md (renamed from .gitlab/issue_templates/Test plan.md)0
-rw-r--r--.gitlab/merge_request_templates/Change Documentation Location.md (renamed from .gitlab/merge_request_templates/Change documentation location.md)0
-rw-r--r--.gitlab/merge_request_templates/Documentation.md2
-rw-r--r--.gitlab/merge_request_templates/New Static Analysis Check.md (renamed from .gitlab/merge_request_templates/New static analysis check.md)0
-rw-r--r--.haml-lint.yml5
-rw-r--r--.haml-lint_todo.yml7
-rw-r--r--.markdownlint.json3
-rw-r--r--.rubocop.yml64
-rw-r--r--.rubocop_todo.yml892
-rw-r--r--.ruby-version2
-rw-r--r--CHANGELOG-EE.md51
-rw-r--r--CHANGELOG.md84
-rw-r--r--Dangerfile16
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--GITLAB_SHELL_VERSION2
-rw-r--r--GITLAB_WORKHORSE_VERSION2
-rw-r--r--Gemfile23
-rw-r--r--Gemfile.lock185
-rw-r--r--app/assets/images/aws_logo.svg38
-rw-r--r--app/assets/images/experienced.svg1
-rw-r--r--app/assets/images/learn-gitlab-avatar.jpgbin0 -> 4237 bytes
-rw-r--r--app/assets/images/novice.svg1
-rw-r--r--app/assets/javascripts/alert_management/components/alert_details.vue262
-rw-r--r--app/assets/javascripts/alert_management/components/alert_management_list.vue216
-rw-r--r--app/assets/javascripts/alert_management/components/alert_sidebar.vue61
-rw-r--r--app/assets/javascripts/alert_management/components/sidebar/sidebar_assignee.vue51
-rw-r--r--app/assets/javascripts/alert_management/components/sidebar/sidebar_assignees.vue278
-rw-r--r--app/assets/javascripts/alert_management/components/sidebar/sidebar_header.vue34
-rw-r--r--app/assets/javascripts/alert_management/components/sidebar/sidebar_status.vue189
-rw-r--r--app/assets/javascripts/alert_management/components/sidebar/sidebar_todo.vue29
-rw-r--r--app/assets/javascripts/alert_management/components/system_notes/system_note.vue46
-rw-r--r--app/assets/javascripts/alert_management/constants.js57
-rw-r--r--app/assets/javascripts/alert_management/details.js4
-rw-r--r--app/assets/javascripts/alert_management/graphql/fragments/alert_note.fragment.graphql16
-rw-r--r--app/assets/javascripts/alert_management/graphql/fragments/detailItem.fragment.graphql11
-rw-r--r--app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql17
-rw-r--r--app/assets/javascripts/alert_management/graphql/fragments/listItem.fragment.graphql9
-rw-r--r--app/assets/javascripts/alert_management/graphql/fragments/list_item.fragment.graphql15
-rw-r--r--app/assets/javascripts/alert_management/graphql/mutations/alert_set_assignees.graphql15
-rw-r--r--app/assets/javascripts/alert_management/graphql/mutations/create_issue_from_alert.graphql8
-rw-r--r--app/assets/javascripts/alert_management/graphql/mutations/update_alert_status.graphql1
-rw-r--r--app/assets/javascripts/alert_management/graphql/queries/details.query.graphql2
-rw-r--r--app/assets/javascripts/alert_management/graphql/queries/getAlerts.query.graphql11
-rw-r--r--app/assets/javascripts/alert_management/graphql/queries/get_alerts.query.graphql32
-rw-r--r--app/assets/javascripts/alert_management/graphql/queries/get_count_by_status.query.graphql11
-rw-r--r--app/assets/javascripts/alert_management/services/index.js7
-rw-r--r--app/assets/javascripts/alerts_service_settings/components/alerts_service_form.vue74
-rw-r--r--app/assets/javascripts/alerts_service_settings/index.js12
-rw-r--r--app/assets/javascripts/api.js39
-rw-r--r--app/assets/javascripts/authentication/mount_2fa.js14
-rw-r--r--app/assets/javascripts/authentication/u2f/authenticate.js107
-rw-r--r--app/assets/javascripts/authentication/u2f/error.js (renamed from app/assets/javascripts/u2f/error.js)0
-rw-r--r--app/assets/javascripts/authentication/u2f/index.js17
-rw-r--r--app/assets/javascripts/authentication/u2f/register.js94
-rw-r--r--app/assets/javascripts/authentication/u2f/util.js (renamed from app/assets/javascripts/u2f/util.js)0
-rw-r--r--app/assets/javascripts/avatar_picker.js16
-rw-r--r--app/assets/javascripts/badges/components/badge.vue9
-rw-r--r--app/assets/javascripts/badges/components/badge_list_row.vue2
-rw-r--r--app/assets/javascripts/batch_comments/components/diff_file_drafts.vue41
-rw-r--r--app/assets/javascripts/batch_comments/components/draft_note.vue113
-rw-r--r--app/assets/javascripts/batch_comments/components/drafts_count.vue15
-rw-r--r--app/assets/javascripts/batch_comments/components/inline_draft_comment_row.vue32
-rw-r--r--app/assets/javascripts/batch_comments/components/parallel_draft_comment_row.vue45
-rw-r--r--app/assets/javascripts/batch_comments/components/preview_dropdown.vue111
-rw-r--r--app/assets/javascripts/batch_comments/components/preview_item.vue143
-rw-r--r--app/assets/javascripts/batch_comments/components/publish_button.vue55
-rw-r--r--app/assets/javascripts/batch_comments/components/review_bar.vue70
-rw-r--r--app/assets/javascripts/batch_comments/constants.js3
-rw-r--r--app/assets/javascripts/batch_comments/index.js24
-rw-r--r--app/assets/javascripts/batch_comments/mixins/resolved_status.js54
-rw-r--r--app/assets/javascripts/batch_comments/services/drafts_service.js33
-rw-r--r--app/assets/javascripts/batch_comments/stores/index.js14
-rw-r--r--app/assets/javascripts/batch_comments/stores/modules/batch_comments/actions.js151
-rw-r--r--app/assets/javascripts/batch_comments/stores/modules/batch_comments/getters.js87
-rw-r--r--app/assets/javascripts/batch_comments/stores/modules/batch_comments/index.js12
-rw-r--r--app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutation_types.js23
-rw-r--r--app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutations.js81
-rw-r--r--app/assets/javascripts/batch_comments/stores/modules/batch_comments/state.js9
-rw-r--r--app/assets/javascripts/batch_comments/utils.js35
-rw-r--r--app/assets/javascripts/behaviors/markdown/render_mermaid.js3
-rw-r--r--app/assets/javascripts/blob/components/blob_content.vue1
-rw-r--r--app/assets/javascripts/blob/components/blob_header.vue6
-rw-r--r--app/assets/javascripts/blob/components/blob_header_default_actions.vue7
-rw-r--r--app/assets/javascripts/blob/components/blob_header_filepath.vue2
-rw-r--r--app/assets/javascripts/boards/components/board_column.vue254
-rw-r--r--app/assets/javascripts/boards/components/board_content.vue82
-rw-r--r--app/assets/javascripts/boards/components/board_delete.js7
-rw-r--r--app/assets/javascripts/boards/components/board_list.vue4
-rw-r--r--app/assets/javascripts/boards/components/board_list_header.vue291
-rw-r--r--app/assets/javascripts/boards/components/board_new_issue.vue2
-rw-r--r--app/assets/javascripts/boards/components/board_sidebar.js2
-rw-r--r--app/assets/javascripts/boards/components/issue_card_inner.vue8
-rw-r--r--app/assets/javascripts/boards/index.js12
-rw-r--r--app/assets/javascripts/boards/models/issue.js39
-rw-r--r--app/assets/javascripts/boards/models/list.js66
-rw-r--r--app/assets/javascripts/boards/stores/actions.js6
-rw-r--r--app/assets/javascripts/boards/stores/boards_store.js144
-rw-r--r--app/assets/javascripts/boards/stores/mutations.js4
-rw-r--r--app/assets/javascripts/boards/stores/state.js1
-rw-r--r--app/assets/javascripts/boards/toggle_epics_swimlanes.js1
-rw-r--r--app/assets/javascripts/ci_variable_list/components/ci_key_field.vue2
-rw-r--r--app/assets/javascripts/ci_variable_list/components/ci_variable_modal.vue100
-rw-r--r--app/assets/javascripts/ci_variable_list/components/ci_variable_table.vue2
-rw-r--r--app/assets/javascripts/ci_variable_list/constants.js6
-rw-r--r--app/assets/javascripts/ci_variable_list/index.js26
-rw-r--r--app/assets/javascripts/clusters/clusters_bundle.js6
-rw-r--r--app/assets/javascripts/clusters/components/application_row.vue130
-rw-r--r--app/assets/javascripts/clusters/components/applications.vue402
-rw-r--r--app/assets/javascripts/clusters/components/fluentd_output_settings.vue4
-rw-r--r--app/assets/javascripts/clusters/components/ingress_modsecurity_settings.vue6
-rw-r--r--app/assets/javascripts/clusters/components/knative_domain_editor.vue5
-rw-r--r--app/assets/javascripts/clusters/components/remove_cluster_confirmation.vue2
-rw-r--r--app/assets/javascripts/clusters/components/update_application_confirmation_modal.vue65
-rw-r--r--app/assets/javascripts/clusters_list/components/clusters.vue200
-rw-r--r--app/assets/javascripts/clusters_list/constants.js3
-rw-r--r--app/assets/javascripts/clusters_list/index.js4
-rw-r--r--app/assets/javascripts/clusters_list/store/actions.js49
-rw-r--r--app/assets/javascripts/clusters_list/store/state.js5
-rw-r--r--app/assets/javascripts/code_navigation/components/doc_line.vue22
-rw-r--r--app/assets/javascripts/code_navigation/components/popover.vue5
-rw-r--r--app/assets/javascripts/commit/image_file.js1
-rw-r--r--app/assets/javascripts/commons/bootstrap.js7
-rw-r--r--app/assets/javascripts/commons/jquery.js2
-rw-r--r--app/assets/javascripts/custom_metrics/components/custom_metrics_form.vue2
-rw-r--r--app/assets/javascripts/design_management/components/design_note_pin.vue4
-rw-r--r--app/assets/javascripts/design_management/components/design_notes/design_discussion.vue158
-rw-r--r--app/assets/javascripts/design_management/components/design_notes/design_note.vue40
-rw-r--r--app/assets/javascripts/design_management/components/design_notes/design_reply_form.vue3
-rw-r--r--app/assets/javascripts/design_management/components/design_notes/toggle_replies_widget.vue70
-rw-r--r--app/assets/javascripts/design_management/components/design_overlay.vue42
-rw-r--r--app/assets/javascripts/design_management/components/design_presentation.vue10
-rw-r--r--app/assets/javascripts/design_management/components/design_sidebar.vue178
-rw-r--r--app/assets/javascripts/design_management/components/upload/button.vue2
-rw-r--r--app/assets/javascripts/design_management/constants.js2
-rw-r--r--app/assets/javascripts/design_management/graphql/fragments/design.fragment.graphql2
-rw-r--r--app/assets/javascripts/design_management/graphql/fragments/designNote.fragment.graphql1
-rw-r--r--app/assets/javascripts/design_management/graphql/fragments/discussion_resolved_status.fragment.graphql9
-rw-r--r--app/assets/javascripts/design_management/graphql/mutations/toggle_resolve_discussion.mutation.graphql17
-rw-r--r--app/assets/javascripts/design_management/pages/design/index.vue114
-rw-r--r--app/assets/javascripts/design_management/pages/index.vue2
-rw-r--r--app/assets/javascripts/design_management/router/index.js15
-rw-r--r--app/assets/javascripts/design_management/utils/cache_update.js4
-rw-r--r--app/assets/javascripts/design_management/utils/design_management_utils.js5
-rw-r--r--app/assets/javascripts/diff_notes/components/jump_to_discussion.js12
-rw-r--r--app/assets/javascripts/diffs/components/commit_item.vue2
-rw-r--r--app/assets/javascripts/diffs/components/compare_versions.vue24
-rw-r--r--app/assets/javascripts/diffs/components/diff_content.vue8
-rw-r--r--app/assets/javascripts/diffs/components/diff_line_note_form.vue38
-rw-r--r--app/assets/javascripts/diffs/components/inline_diff_view.vue8
-rw-r--r--app/assets/javascripts/diffs/components/parallel_diff_view.vue6
-rw-r--r--app/assets/javascripts/diffs/components/tree_list.vue2
-rw-r--r--app/assets/javascripts/diffs/constants.js19
-rw-r--r--app/assets/javascripts/diffs/mixins/draft_comments.js17
-rw-r--r--app/assets/javascripts/diffs/store/actions.js24
-rw-r--r--app/assets/javascripts/diffs/store/utils.js2
-rw-r--r--app/assets/javascripts/diffs/utils/uuids.js79
-rw-r--r--app/assets/javascripts/environments/components/environments_app.vue14
-rw-r--r--app/assets/javascripts/error_tracking/components/constants.js4
-rw-r--r--app/assets/javascripts/error_tracking/components/error_details.vue51
-rw-r--r--app/assets/javascripts/error_tracking/components/error_tracking_list.vue21
-rw-r--r--app/assets/javascripts/error_tracking/store/list/actions.js14
-rw-r--r--app/assets/javascripts/error_tracking/utils.js26
-rw-r--r--app/assets/javascripts/file_pickers.js21
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js32
-rw-r--r--app/assets/javascripts/filtered_search/services/recent_searches_service_error.js7
-rw-r--r--app/assets/javascripts/frequent_items/index.js76
-rw-r--r--app/assets/javascripts/gl_dropdown.js2
-rw-r--r--app/assets/javascripts/global_search_input.js425
-rw-r--r--app/assets/javascripts/graphql_shared/fragments/pageInfo.fragment.graphql2
-rw-r--r--app/assets/javascripts/group.js70
-rw-r--r--app/assets/javascripts/groups/components/group_item.vue19
-rw-r--r--app/assets/javascripts/groups/components/item_actions.vue4
-rw-r--r--app/assets/javascripts/groups/components/item_stats.vue8
-rw-r--r--app/assets/javascripts/header.js2
-rw-r--r--app/assets/javascripts/ide/commit_icon.js11
-rw-r--r--app/assets/javascripts/ide/components/activity_bar.vue7
-rw-r--r--app/assets/javascripts/ide/components/branches/item.vue3
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/editor_header.vue4
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/empty_state.vue5
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/form.vue51
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/list.vue6
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/list_item.vue4
-rw-r--r--app/assets/javascripts/ide/components/file_row_extra.vue2
-rw-r--r--app/assets/javascripts/ide/components/ide.vue23
-rw-r--r--app/assets/javascripts/ide/components/ide_side_bar.vue9
-rw-r--r--app/assets/javascripts/ide/components/ide_sidebar_nav.vue83
-rw-r--r--app/assets/javascripts/ide/components/ide_status_bar.vue2
-rw-r--r--app/assets/javascripts/ide/components/ide_status_list.vue12
-rw-r--r--app/assets/javascripts/ide/components/jobs/detail/description.vue2
-rw-r--r--app/assets/javascripts/ide/components/jobs/stage.vue4
-rw-r--r--app/assets/javascripts/ide/components/merge_requests/item.vue3
-rw-r--r--app/assets/javascripts/ide/components/mr_file_icon.vue2
-rw-r--r--app/assets/javascripts/ide/components/new_dropdown/modal.vue11
-rw-r--r--app/assets/javascripts/ide/components/new_dropdown/upload.vue1
-rw-r--r--app/assets/javascripts/ide/components/panes/collapsible_sidebar.vue92
-rw-r--r--app/assets/javascripts/ide/components/panes/right.vue35
-rw-r--r--app/assets/javascripts/ide/components/pipelines/list.vue8
-rw-r--r--app/assets/javascripts/ide/components/preview/navigator.vue2
-rw-r--r--app/assets/javascripts/ide/components/repo_commit_section.vue48
-rw-r--r--app/assets/javascripts/ide/components/repo_editor.vue89
-rw-r--r--app/assets/javascripts/ide/components/repo_tabs.vue14
-rw-r--r--app/assets/javascripts/ide/components/resizable_panel.vue13
-rw-r--r--app/assets/javascripts/ide/components/terminal/empty_state.vue71
-rw-r--r--app/assets/javascripts/ide/components/terminal/session.vue53
-rw-r--r--app/assets/javascripts/ide/components/terminal/terminal.vue117
-rw-r--r--app/assets/javascripts/ide/components/terminal/terminal_controls.vue27
-rw-r--r--app/assets/javascripts/ide/components/terminal/view.vue41
-rw-r--r--app/assets/javascripts/ide/components/terminal_sync/terminal_sync_status.vue76
-rw-r--r--app/assets/javascripts/ide/components/terminal_sync/terminal_sync_status_safe.vue22
-rw-r--r--app/assets/javascripts/ide/constants.js8
-rw-r--r--app/assets/javascripts/ide/ide_router.js153
-rw-r--r--app/assets/javascripts/ide/index.js3
-rw-r--r--app/assets/javascripts/ide/lib/common/model.js35
-rw-r--r--app/assets/javascripts/ide/lib/create_diff.js85
-rw-r--r--app/assets/javascripts/ide/lib/create_file_diff.js112
-rw-r--r--app/assets/javascripts/ide/lib/diff/controller.js9
-rw-r--r--app/assets/javascripts/ide/lib/diff/diff.js9
-rw-r--r--app/assets/javascripts/ide/lib/editor.js32
-rw-r--r--app/assets/javascripts/ide/lib/editor_options.js22
-rw-r--r--app/assets/javascripts/ide/lib/editorconfig/parser.js55
-rw-r--r--app/assets/javascripts/ide/lib/editorconfig/rules_mapper.js33
-rw-r--r--app/assets/javascripts/ide/lib/files.js5
-rw-r--r--app/assets/javascripts/ide/lib/languages/README.md21
-rw-r--r--app/assets/javascripts/ide/lib/mirror.js154
-rw-r--r--app/assets/javascripts/ide/services/terminals.js15
-rw-r--r--app/assets/javascripts/ide/stores/actions.js42
-rw-r--r--app/assets/javascripts/ide/stores/actions/file.js23
-rw-r--r--app/assets/javascripts/ide/stores/actions/project.js3
-rw-r--r--app/assets/javascripts/ide/stores/extend.js14
-rw-r--r--app/assets/javascripts/ide/stores/getters.js20
-rw-r--r--app/assets/javascripts/ide/stores/index.js35
-rw-r--r--app/assets/javascripts/ide/stores/modules/branches/index.js2
-rw-r--r--app/assets/javascripts/ide/stores/modules/clientside/actions.js3
-rw-r--r--app/assets/javascripts/ide/stores/modules/commit/actions.js8
-rw-r--r--app/assets/javascripts/ide/stores/modules/commit/getters.js3
-rw-r--r--app/assets/javascripts/ide/stores/modules/commit/index.js2
-rw-r--r--app/assets/javascripts/ide/stores/modules/file_templates/actions.js3
-rw-r--r--app/assets/javascripts/ide/stores/modules/pane/actions.js3
-rw-r--r--app/assets/javascripts/ide/stores/modules/pane/getters.js7
-rw-r--r--app/assets/javascripts/ide/stores/modules/router/actions.js6
-rw-r--r--app/assets/javascripts/ide/stores/modules/router/index.js10
-rw-r--r--app/assets/javascripts/ide/stores/modules/router/mutation_types.js2
-rw-r--r--app/assets/javascripts/ide/stores/modules/router/mutations.js7
-rw-r--r--app/assets/javascripts/ide/stores/modules/router/state.js3
-rw-r--r--app/assets/javascripts/ide/stores/modules/terminal/actions/checks.js98
-rw-r--r--app/assets/javascripts/ide/stores/modules/terminal/actions/index.js5
-rw-r--r--app/assets/javascripts/ide/stores/modules/terminal/actions/session_controls.js118
-rw-r--r--app/assets/javascripts/ide/stores/modules/terminal/actions/session_status.js64
-rw-r--r--app/assets/javascripts/ide/stores/modules/terminal/actions/setup.js14
-rw-r--r--app/assets/javascripts/ide/stores/modules/terminal/constants.js9
-rw-r--r--app/assets/javascripts/ide/stores/modules/terminal/getters.js19
-rw-r--r--app/assets/javascripts/ide/stores/modules/terminal/index.js12
-rw-r--r--app/assets/javascripts/ide/stores/modules/terminal/messages.js55
-rw-r--r--app/assets/javascripts/ide/stores/modules/terminal/mutation_types.js11
-rw-r--r--app/assets/javascripts/ide/stores/modules/terminal/mutations.js64
-rw-r--r--app/assets/javascripts/ide/stores/modules/terminal/state.js13
-rw-r--r--app/assets/javascripts/ide/stores/modules/terminal/utils.js5
-rw-r--r--app/assets/javascripts/ide/stores/modules/terminal_sync/actions.js41
-rw-r--r--app/assets/javascripts/ide/stores/modules/terminal_sync/index.js10
-rw-r--r--app/assets/javascripts/ide/stores/modules/terminal_sync/messages.js5
-rw-r--r--app/assets/javascripts/ide/stores/modules/terminal_sync/mutation_types.js4
-rw-r--r--app/assets/javascripts/ide/stores/modules/terminal_sync/mutations.js22
-rw-r--r--app/assets/javascripts/ide/stores/modules/terminal_sync/state.js6
-rw-r--r--app/assets/javascripts/ide/stores/mutation_types.js2
-rw-r--r--app/assets/javascripts/ide/stores/mutations.js12
-rw-r--r--app/assets/javascripts/ide/stores/mutations/file.js8
-rw-r--r--app/assets/javascripts/ide/stores/mutations/tree.js5
-rw-r--r--app/assets/javascripts/ide/stores/plugins/terminal.js25
-rw-r--r--app/assets/javascripts/ide/stores/plugins/terminal_sync.js49
-rw-r--r--app/assets/javascripts/ide/stores/state.js3
-rw-r--r--app/assets/javascripts/ide/stores/utils.js44
-rw-r--r--app/assets/javascripts/ide/sync_router_and_store.js55
-rw-r--r--app/assets/javascripts/ide/utils.js61
-rw-r--r--app/assets/javascripts/import_projects/components/bitbucket_status_table.vue74
-rw-r--r--app/assets/javascripts/import_projects/components/import_projects_table.vue65
-rw-r--r--app/assets/javascripts/import_projects/components/incompatible_repo_table_row.vue30
-rw-r--r--app/assets/javascripts/import_projects/components/provider_repo_table_row.vue6
-rw-r--r--app/assets/javascripts/import_projects/index.js52
-rw-r--r--app/assets/javascripts/import_projects/store/actions.js66
-rw-r--r--app/assets/javascripts/import_projects/store/getters.js2
-rw-r--r--app/assets/javascripts/import_projects/store/index.js4
-rw-r--r--app/assets/javascripts/import_projects/store/mutation_types.js2
-rw-r--r--app/assets/javascripts/import_projects/store/mutations.js10
-rw-r--r--app/assets/javascripts/import_projects/store/state.js1
-rw-r--r--app/assets/javascripts/integrations/edit/components/active_toggle.vue17
-rw-r--r--app/assets/javascripts/integrations/edit/components/dynamic_field.vue172
-rw-r--r--app/assets/javascripts/integrations/edit/components/integration_form.vue8
-rw-r--r--app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue103
-rw-r--r--app/assets/javascripts/integrations/edit/index.js3
-rw-r--r--app/assets/javascripts/integrations/integration_settings_form.js11
-rw-r--r--app/assets/javascripts/issuable_bulk_update_actions.js5
-rw-r--r--app/assets/javascripts/issuable_suggestions/components/item.vue2
-rw-r--r--app/assets/javascripts/issuables_list/components/issuable_list_root_app.vue6
-rw-r--r--app/assets/javascripts/issuables_list/components/issuables_list_app.vue2
-rw-r--r--app/assets/javascripts/issue.js26
-rw-r--r--app/assets/javascripts/issue_show/components/app.vue79
-rw-r--r--app/assets/javascripts/issue_show/components/pinned_links.vue39
-rw-r--r--app/assets/javascripts/issue_show/constants.js17
-rw-r--r--app/assets/javascripts/jira_import/components/jira_import_app.vue108
-rw-r--r--app/assets/javascripts/jira_import/index.js1
-rw-r--r--app/assets/javascripts/jira_import/queries/get_jira_import_details.query.graphql12
-rw-r--r--app/assets/javascripts/jira_import/utils.js59
-rw-r--r--app/assets/javascripts/jira_import/utils/cache_update.js37
-rw-r--r--app/assets/javascripts/jira_import/utils/jira_import_utils.js70
-rw-r--r--app/assets/javascripts/jobs/components/artifacts_block.vue32
-rw-r--r--app/assets/javascripts/jobs/components/commit_block.vue2
-rw-r--r--app/assets/javascripts/jobs/components/environments_block.vue2
-rw-r--r--app/assets/javascripts/jobs/components/stages_dropdown.vue2
-rw-r--r--app/assets/javascripts/jobs/components/stuck_block.vue12
-rw-r--r--app/assets/javascripts/jobs/components/trigger_block.vue2
-rw-r--r--app/assets/javascripts/jobs/components/unmet_prerequisites_block.vue2
-rw-r--r--app/assets/javascripts/lazy_loader.js2
-rw-r--r--app/assets/javascripts/lib/utils/common_utils.js14
-rw-r--r--app/assets/javascripts/lib/utils/constants.js8
-rw-r--r--app/assets/javascripts/lib/utils/datetime_range.js15
-rw-r--r--app/assets/javascripts/lib/utils/dom_utils.js13
-rw-r--r--app/assets/javascripts/lib/utils/text_utility.js9
-rw-r--r--app/assets/javascripts/lib/utils/url_utility.js17
-rw-r--r--app/assets/javascripts/logs/components/environment_logs.vue4
-rw-r--r--app/assets/javascripts/logs/constants.js8
-rw-r--r--app/assets/javascripts/logs/logs_tracking_helper.js18
-rw-r--r--app/assets/javascripts/logs/stores/actions.js23
-rw-r--r--app/assets/javascripts/logs/stores/mutation_types.js1
-rw-r--r--app/assets/javascripts/main.js16
-rw-r--r--app/assets/javascripts/merge_request_tabs.js50
-rw-r--r--app/assets/javascripts/milestone_select.js9
-rw-r--r--app/assets/javascripts/monitoring/components/alert_widget.vue6
-rw-r--r--app/assets/javascripts/monitoring/components/alert_widget_form.vue2
-rw-r--r--app/assets/javascripts/monitoring/components/charts/column.vue13
-rw-r--r--app/assets/javascripts/monitoring/components/charts/empty_chart.vue4
-rw-r--r--app/assets/javascripts/monitoring/components/charts/heatmap.vue9
-rw-r--r--app/assets/javascripts/monitoring/components/charts/options.js29
-rw-r--r--app/assets/javascripts/monitoring/components/charts/stacked_column.vue68
-rw-r--r--app/assets/javascripts/monitoring/components/charts/time_series.vue60
-rw-r--r--app/assets/javascripts/monitoring/components/dashboard.vue407
-rw-r--r--app/assets/javascripts/monitoring/components/dashboard_header.vue369
-rw-r--r--app/assets/javascripts/monitoring/components/dashboard_panel.vue43
-rw-r--r--app/assets/javascripts/monitoring/components/graph_group.vue11
-rw-r--r--app/assets/javascripts/monitoring/components/links_section.vue32
-rw-r--r--app/assets/javascripts/monitoring/components/variables_section.vue16
-rw-r--r--app/assets/javascripts/monitoring/constants.js23
-rw-r--r--app/assets/javascripts/monitoring/format_date.js39
-rw-r--r--app/assets/javascripts/monitoring/monitoring_app.js59
-rw-r--r--app/assets/javascripts/monitoring/monitoring_bundle.js32
-rw-r--r--app/assets/javascripts/monitoring/monitoring_bundle_with_alerts.js13
-rw-r--r--app/assets/javascripts/monitoring/pages/dashboard_page.vue18
-rw-r--r--app/assets/javascripts/monitoring/router/constants.js3
-rw-r--r--app/assets/javascripts/monitoring/router/index.js15
-rw-r--r--app/assets/javascripts/monitoring/router/routes.js18
-rw-r--r--app/assets/javascripts/monitoring/stores/actions.js16
-rw-r--r--app/assets/javascripts/monitoring/stores/getters.js22
-rw-r--r--app/assets/javascripts/monitoring/stores/index.js12
-rw-r--r--app/assets/javascripts/monitoring/stores/mutation_types.js2
-rw-r--r--app/assets/javascripts/monitoring/stores/mutations.js26
-rw-r--r--app/assets/javascripts/monitoring/stores/state.js17
-rw-r--r--app/assets/javascripts/monitoring/stores/utils.js110
-rw-r--r--app/assets/javascripts/monitoring/stores/variable_mapping.js2
-rw-r--r--app/assets/javascripts/monitoring/utils.js16
-rw-r--r--app/assets/javascripts/mr_notes/index.js2
-rw-r--r--app/assets/javascripts/mr_notes/init_notes.js2
-rw-r--r--app/assets/javascripts/mr_notes/stores/index.js2
-rw-r--r--app/assets/javascripts/namespace_storage_limit_alert.js20
-rw-r--r--app/assets/javascripts/notes/components/comment_form.vue11
-rw-r--r--app/assets/javascripts/notes/components/diff_with_note.vue1
-rw-r--r--app/assets/javascripts/notes/components/multiline_comment_form.vue68
-rw-r--r--app/assets/javascripts/notes/components/multiline_comment_utils.js57
-rw-r--r--app/assets/javascripts/notes/components/note_actions.vue65
-rw-r--r--app/assets/javascripts/notes/components/note_body.vue36
-rw-r--r--app/assets/javascripts/notes/components/note_form.vue70
-rw-r--r--app/assets/javascripts/notes/components/noteable_discussion.vue5
-rw-r--r--app/assets/javascripts/notes/components/noteable_note.vue98
-rw-r--r--app/assets/javascripts/notes/mixins/description_version_history.js2
-rw-r--r--app/assets/javascripts/notes/mixins/diff_line_note_form.js98
-rw-r--r--app/assets/javascripts/notes/mixins/discussion_navigation.js4
-rw-r--r--app/assets/javascripts/notes/mixins/draft.js8
-rw-r--r--app/assets/javascripts/notes/mixins/get_discussion.js7
-rw-r--r--app/assets/javascripts/notes/mixins/note_form.js24
-rw-r--r--app/assets/javascripts/notes/stores/actions.js53
-rw-r--r--app/assets/javascripts/notes/stores/modules/index.js1
-rw-r--r--app/assets/javascripts/notes/stores/mutation_types.js5
-rw-r--r--app/assets/javascripts/notes/stores/mutations.js36
-rw-r--r--app/assets/javascripts/onboarding_issues/index.js120
-rw-r--r--app/assets/javascripts/operation_settings/components/external_dashboard.vue72
-rw-r--r--app/assets/javascripts/operation_settings/components/form_group/dashboard_timezone.vue60
-rw-r--r--app/assets/javascripts/operation_settings/components/form_group/external_dashboard.vue48
-rw-r--r--app/assets/javascripts/operation_settings/components/metrics_settings.vue53
-rw-r--r--app/assets/javascripts/operation_settings/index.js4
-rw-r--r--app/assets/javascripts/operation_settings/store/actions.js18
-rw-r--r--app/assets/javascripts/operation_settings/store/mutation_types.js3
-rw-r--r--app/assets/javascripts/operation_settings/store/mutations.js5
-rw-r--r--app/assets/javascripts/operation_settings/store/state.js9
-rw-r--r--app/assets/javascripts/pager.js5
-rw-r--r--app/assets/javascripts/pages/admin/application_settings/index.js4
-rw-r--r--app/assets/javascripts/pages/admin/groups/edit/index.js4
-rw-r--r--app/assets/javascripts/pages/admin/groups/new/index.js7
-rw-r--r--app/assets/javascripts/pages/admin/projects/index/components/delete_project_modal.vue2
-rw-r--r--app/assets/javascripts/pages/groups/clusters/index.js (renamed from app/assets/javascripts/pages/groups/index.js)0
-rw-r--r--app/assets/javascripts/pages/groups/edit/index.js7
-rw-r--r--app/assets/javascripts/pages/groups/new/index.js7
-rw-r--r--app/assets/javascripts/pages/groups/shared/group_details.js3
-rw-r--r--app/assets/javascripts/pages/ide/index.js3
-rw-r--r--app/assets/javascripts/pages/import/bitbucket/status/index.js19
-rw-r--r--app/assets/javascripts/pages/import/bitbucket_server/status/components/bitbucket_server_status_table.vue30
-rw-r--r--app/assets/javascripts/pages/import/bitbucket_server/status/index.js20
-rw-r--r--app/assets/javascripts/pages/import/fogbugz/status/index.js7
-rw-r--r--app/assets/javascripts/pages/import/gitlab/status/index.js7
-rw-r--r--app/assets/javascripts/pages/ldap/omniauth_callbacks/index.js4
-rw-r--r--app/assets/javascripts/pages/omniauth_callbacks/index.js4
-rw-r--r--app/assets/javascripts/pages/profiles/two_factor_auths/index.js6
-rw-r--r--app/assets/javascripts/pages/projects/clusters/index.js5
-rw-r--r--app/assets/javascripts/pages/projects/edit/index.js4
-rw-r--r--app/assets/javascripts/pages/projects/environments/metrics/index.js4
-rw-r--r--app/assets/javascripts/pages/projects/graphs/charts/index.js14
-rw-r--r--app/assets/javascripts/pages/projects/graphs/components/code_coverage.vue177
-rw-r--r--app/assets/javascripts/pages/projects/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/issues/index/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/labels/components/promote_label_modal.vue2
-rw-r--r--app/assets/javascripts/pages/projects/merge_requests/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/new/index.js39
-rw-r--r--app/assets/javascripts/pages/projects/pipelines/index/index.js1
-rw-r--r--app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue98
-rw-r--r--app/assets/javascripts/pages/projects/show/index.js7
-rw-r--r--app/assets/javascripts/pages/projects/tree/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/wikis/index.js42
-rw-r--r--app/assets/javascripts/pages/sessions/index.js4
-rw-r--r--app/assets/javascripts/pages/sessions/new/oauth_remember_me.js10
-rw-r--r--app/assets/javascripts/pages/sessions/new/preserve_url_fragment.js10
-rw-r--r--app/assets/javascripts/pages/shared/wikis/components/delete_wiki_modal.vue (renamed from app/assets/javascripts/pages/projects/wikis/components/delete_wiki_modal.vue)0
-rw-r--r--app/assets/javascripts/pages/shared/wikis/index.js41
-rw-r--r--app/assets/javascripts/pages/shared/wikis/wikis.js (renamed from app/assets/javascripts/pages/projects/wikis/wikis.js)0
-rw-r--r--app/assets/javascripts/performance_bar/components/detailed_metric.vue11
-rw-r--r--app/assets/javascripts/performance_bar/components/performance_bar_app.vue12
-rw-r--r--app/assets/javascripts/persistent_user_callouts.js15
-rw-r--r--app/assets/javascripts/pipelines/components/dag/constants.js10
-rw-r--r--app/assets/javascripts/pipelines/components/dag/dag.vue136
-rw-r--r--app/assets/javascripts/pipelines/components/dag/dag_graph.vue299
-rw-r--r--app/assets/javascripts/pipelines/components/dag/drawing_utils.js134
-rw-r--r--app/assets/javascripts/pipelines/components/dag/interactions.js134
-rw-r--r--app/assets/javascripts/pipelines/components/dag/parsing_utils.js164
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines.vue24
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_artifacts.vue2
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_filtered_search.vue84
-rw-r--r--app/assets/javascripts/pipelines/components/test_reports/test_summary.vue2
-rw-r--r--app/assets/javascripts/pipelines/components/tokens/pipeline_branch_name_token.vue15
-rw-r--r--app/assets/javascripts/pipelines/components/tokens/pipeline_status_token.vue104
-rw-r--r--app/assets/javascripts/pipelines/components/tokens/pipeline_tag_name_token.vue64
-rw-r--r--app/assets/javascripts/pipelines/components/tokens/pipeline_trigger_author_token.vue13
-rw-r--r--app/assets/javascripts/pipelines/constants.js3
-rw-r--r--app/assets/javascripts/pipelines/pipeline_details_bundle.js25
-rw-r--r--app/assets/javascripts/pipelines/services/pipelines_service.js13
-rw-r--r--app/assets/javascripts/pipelines/utils.js8
-rw-r--r--app/assets/javascripts/projects/commits/components/author_select.vue4
-rw-r--r--app/assets/javascripts/projects/commits/store/actions.js5
-rw-r--r--app/assets/javascripts/projects/experiment_new_project_creation/components/app.vue160
-rw-r--r--app/assets/javascripts/projects/experiment_new_project_creation/components/legacy_container.vue31
-rw-r--r--app/assets/javascripts/projects/experiment_new_project_creation/components/welcome.vue70
-rw-r--r--app/assets/javascripts/projects/experiment_new_project_creation/illustrations/blank-project.svg27
-rw-r--r--app/assets/javascripts/projects/experiment_new_project_creation/illustrations/ci-cd-project.svg73
-rw-r--r--app/assets/javascripts/projects/experiment_new_project_creation/illustrations/create-from-template.svg54
-rw-r--r--app/assets/javascripts/projects/experiment_new_project_creation/illustrations/import-project.svg95
-rw-r--r--app/assets/javascripts/projects/experiment_new_project_creation/index.js14
-rw-r--r--app/assets/javascripts/registry/explorer/components/details_page/delete_alert.vue70
-rw-r--r--app/assets/javascripts/registry/explorer/components/details_page/delete_modal.vue67
-rw-r--r--app/assets/javascripts/registry/explorer/components/details_page/details_header.vue30
-rw-r--r--app/assets/javascripts/registry/explorer/components/details_page/empty_tags_state.vue33
-rw-r--r--app/assets/javascripts/registry/explorer/components/details_page/tags_loader.vue34
-rw-r--r--app/assets/javascripts/registry/explorer/components/details_page/tags_table.vue210
-rw-r--r--app/assets/javascripts/registry/explorer/components/image_list.vue124
-rw-r--r--app/assets/javascripts/registry/explorer/components/list_page/cli_commands.vue103
-rw-r--r--app/assets/javascripts/registry/explorer/components/list_page/group_empty_state.vue (renamed from app/assets/javascripts/registry/explorer/components/group_empty_state.vue)0
-rw-r--r--app/assets/javascripts/registry/explorer/components/list_page/image_list.vue52
-rw-r--r--app/assets/javascripts/registry/explorer/components/list_page/image_list_row.vue136
-rw-r--r--app/assets/javascripts/registry/explorer/components/list_page/project_empty_state.vue107
-rw-r--r--app/assets/javascripts/registry/explorer/components/list_page/registry_header.vue138
-rw-r--r--app/assets/javascripts/registry/explorer/components/project_empty_state.vue102
-rw-r--r--app/assets/javascripts/registry/explorer/components/project_policy_alert.vue68
-rw-r--r--app/assets/javascripts/registry/explorer/components/quickstart_dropdown.vue103
-rw-r--r--app/assets/javascripts/registry/explorer/constants.js130
-rw-r--r--app/assets/javascripts/registry/explorer/constants/details.js60
-rw-r--r--app/assets/javascripts/registry/explorer/constants/expiration_policies.js11
-rw-r--r--app/assets/javascripts/registry/explorer/constants/index.js4
-rw-r--r--app/assets/javascripts/registry/explorer/constants/list.js48
-rw-r--r--app/assets/javascripts/registry/explorer/constants/quick_start.js9
-rw-r--r--app/assets/javascripts/registry/explorer/pages/details.vue401
-rw-r--r--app/assets/javascripts/registry/explorer/pages/list.vue52
-rw-r--r--app/assets/javascripts/registry/explorer/router.js4
-rw-r--r--app/assets/javascripts/registry/explorer/stores/actions.js2
-rw-r--r--app/assets/javascripts/registry/explorer/stores/getters.js6
-rw-r--r--app/assets/javascripts/registry/explorer/stores/index.js4
-rw-r--r--app/assets/javascripts/registry/explorer/stores/mutations.js8
-rw-r--r--app/assets/javascripts/releases/components/asset_links_form.vue65
-rw-r--r--app/assets/javascripts/releases/components/evidence_block.vue4
-rw-r--r--app/assets/javascripts/releases/components/release_block.vue2
-rw-r--r--app/assets/javascripts/releases/components/release_block_assets.vue187
-rw-r--r--app/assets/javascripts/releases/components/release_block_author.vue2
-rw-r--r--app/assets/javascripts/releases/components/release_block_metadata.vue4
-rw-r--r--app/assets/javascripts/releases/components/release_block_milestone_info.vue2
-rw-r--r--app/assets/javascripts/releases/constants.js9
-rw-r--r--app/assets/javascripts/releases/stores/modules/detail/actions.js30
-rw-r--r--app/assets/javascripts/releases/stores/modules/detail/mutation_types.js1
-rw-r--r--app/assets/javascripts/releases/stores/modules/detail/mutations.js7
-rw-r--r--app/assets/javascripts/reports/components/grouped_test_reports_app.vue40
-rw-r--r--app/assets/javascripts/reports/components/summary_row.vue5
-rw-r--r--app/assets/javascripts/reports/components/test_issue_body.vue2
-rw-r--r--app/assets/javascripts/repository/components/last_commit.vue2
-rw-r--r--app/assets/javascripts/repository/components/table/row.vue7
-rw-r--r--app/assets/javascripts/repository/queries/getVueFileListLfsBadge.query.graphql2
-rw-r--r--app/assets/javascripts/search_autocomplete.js482
-rw-r--r--app/assets/javascripts/serverless/components/function_row.vue2
-rw-r--r--app/assets/javascripts/set_status_modal/set_status_modal_wrapper.vue3
-rw-r--r--app/assets/javascripts/shared/sessions/u2f.js17
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/help_state.vue9
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue6
-rw-r--r--app/assets/javascripts/sidebar/mount_milestone_sidebar.js1
-rw-r--r--app/assets/javascripts/snippets/components/edit.vue60
-rw-r--r--app/assets/javascripts/snippets/components/snippet_blob_edit.vue2
-rw-r--r--app/assets/javascripts/snippets/components/snippet_blob_view.vue10
-rw-r--r--app/assets/javascripts/snippets/components/snippet_description_edit.vue32
-rw-r--r--app/assets/javascripts/snippets/components/snippet_description_view.vue2
-rw-r--r--app/assets/javascripts/snippets/components/snippet_header.vue3
-rw-r--r--app/assets/javascripts/snippets/components/snippet_title.vue2
-rw-r--r--app/assets/javascripts/snippets/constants.js3
-rw-r--r--app/assets/javascripts/static_site_editor/components/edit_area.vue45
-rw-r--r--app/assets/javascripts/static_site_editor/components/unsaved_changes_confirm_dialog.vue27
-rw-r--r--app/assets/javascripts/static_site_editor/constants.js2
-rw-r--r--app/assets/javascripts/static_site_editor/pages/home.vue6
-rw-r--r--app/assets/javascripts/static_site_editor/services/parse_source_file.js55
-rw-r--r--app/assets/javascripts/static_site_editor/services/submit_content_changes.js13
-rw-r--r--app/assets/javascripts/u2f/authenticate.js107
-rw-r--r--app/assets/javascripts/u2f/register.js94
-rw-r--r--app/assets/javascripts/user_callout.js13
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_action_button.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_view_button.vue4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_terraform_plan.vue20
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/source_branch_removal_status.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/changed_file_icon.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/content_viewer/viewers/download_viewer.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue106
-rw-r--r--app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker_input.vue4
-rw-r--r--app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker_lib.js65
-rw-r--r--app/assets/javascripts/vue_shared/components/diff_viewer/diff_viewer.vue5
-rw-r--r--app/assets/javascripts/vue_shared/components/diff_viewer/viewers/renamed.vue107
-rw-r--r--app/assets/javascripts/vue_shared/components/file_finder/index.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/file_finder/item.vue8
-rw-r--r--app/assets/javascripts/vue_shared/components/filtered_search_bar/constants.js8
-rw-r--r--app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue253
-rw-r--r--app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/author_token.vue114
-rw-r--r--app/assets/javascripts/vue_shared/components/gl_mentions.vue84
-rw-r--r--app/assets/javascripts/vue_shared/components/issue/related_issuable_item.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/field.vue8
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/header.vue4
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/suggestion_diff.vue28
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/suggestion_diff_header.vue119
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/suggestions.vue21
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/toolbar.vue72
-rw-r--r--app/assets/javascripts/vue_shared/components/notes/system_note.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/project_selector/project_selector.vue58
-rw-r--r--app/assets/javascripts/vue_shared/components/rich_content_editor/constants.js10
-rw-r--r--app/assets/javascripts/vue_shared/components/rich_content_editor/editor_service.js42
-rw-r--r--app/assets/javascripts/vue_shared/components/rich_content_editor/modals/add_image_modal.vue74
-rw-r--r--app/assets/javascripts/vue_shared/components/rich_content_editor/rich_content_editor.vue97
-rw-r--r--app/assets/javascripts/vue_shared/components/rich_content_editor/toolbar_item.vue13
-rw-r--r--app/assets/javascripts/vue_shared/components/rich_content_editor/toolbar_service.js32
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/constants.js3
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue23
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/label_item.vue16
-rw-r--r--app/assets/javascripts/vue_shared/components/url_sync.vue25
-rw-r--r--app/assets/javascripts/vue_shared/mixins/ci_pagination_api_mixin.js14
-rw-r--r--app/assets/javascripts/vue_shared/mixins/related_issuable_mixin.js4
-rw-r--r--app/assets/stylesheets/application_dark.scss3
-rw-r--r--app/assets/stylesheets/bootstrap_migration.scss4
-rw-r--r--app/assets/stylesheets/components/avatar.scss11
-rw-r--r--app/assets/stylesheets/components/dashboard_skeleton.scss6
-rw-r--r--app/assets/stylesheets/components/design_management/design.scss59
-rw-r--r--app/assets/stylesheets/components/popover.scss2
-rw-r--r--app/assets/stylesheets/components/related_items_list.scss27
-rw-r--r--app/assets/stylesheets/components/rich_content_editor.scss22
-rw-r--r--app/assets/stylesheets/framework/animations.scss9
-rw-r--r--app/assets/stylesheets/framework/badges.scss10
-rw-r--r--app/assets/stylesheets/framework/blank.scss14
-rw-r--r--app/assets/stylesheets/framework/broadcast_messages.scss5
-rw-r--r--app/assets/stylesheets/framework/common.scss46
-rw-r--r--app/assets/stylesheets/framework/contextual_sidebar.scss2
-rw-r--r--app/assets/stylesheets/framework/dropdowns.scss5
-rw-r--r--app/assets/stylesheets/framework/files.scss2
-rw-r--r--app/assets/stylesheets/framework/filters.scss17
-rw-r--r--app/assets/stylesheets/framework/gitlab_theme.scss49
-rw-r--r--app/assets/stylesheets/framework/markdown_area.scss2
-rw-r--r--app/assets/stylesheets/framework/selects.scss41
-rw-r--r--app/assets/stylesheets/framework/system_messages.scss12
-rw-r--r--app/assets/stylesheets/framework/tables.scss2
-rw-r--r--app/assets/stylesheets/framework/typography.scss18
-rw-r--r--app/assets/stylesheets/framework/variables.scss244
-rw-r--r--app/assets/stylesheets/framework/variables_overrides.scss23
-rw-r--r--app/assets/stylesheets/notify.scss2
-rw-r--r--app/assets/stylesheets/page_bundles/_ide_monaco_overrides.scss3
-rw-r--r--app/assets/stylesheets/page_bundles/_ide_theme_overrides.scss326
-rw-r--r--app/assets/stylesheets/page_bundles/ide.scss67
-rw-r--r--app/assets/stylesheets/page_bundles/ide_themes/README.md14
-rw-r--r--app/assets/stylesheets/page_bundles/ide_themes/_solarized-dark.scss50
-rw-r--r--app/assets/stylesheets/pages/alert_management/details.scss33
-rw-r--r--app/assets/stylesheets/pages/alert_management/list.scss93
-rw-r--r--app/assets/stylesheets/pages/boards.scss29
-rw-r--r--app/assets/stylesheets/pages/diff.scss2
-rw-r--r--app/assets/stylesheets/pages/experience_level.scss29
-rw-r--r--app/assets/stylesheets/pages/groups.scss32
-rw-r--r--app/assets/stylesheets/pages/issuable.scss5
-rw-r--r--app/assets/stylesheets/pages/issues.scss66
-rw-r--r--app/assets/stylesheets/pages/labels.scss4
-rw-r--r--app/assets/stylesheets/pages/login.scss13
-rw-r--r--app/assets/stylesheets/pages/note_form.scss4
-rw-r--r--app/assets/stylesheets/pages/notes.scss6
-rw-r--r--app/assets/stylesheets/pages/pipelines.scss5
-rw-r--r--app/assets/stylesheets/pages/profiles/preferences.scss14
-rw-r--r--app/assets/stylesheets/pages/projects.scss2
-rw-r--r--app/assets/stylesheets/pages/prometheus.scss8
-rw-r--r--app/assets/stylesheets/pages/storage_quota.scss17
-rw-r--r--app/assets/stylesheets/themes/_dark.scss134
-rw-r--r--app/assets/stylesheets/utilities.scss70
-rw-r--r--app/channels/application_cable/channel.rb11
-rw-r--r--app/channels/application_cable/connection.rb8
-rw-r--r--app/channels/application_cable/logging.rb17
-rw-r--r--app/controllers/admin/application_settings_controller.rb5
-rw-r--r--app/controllers/admin/runners_controller.rb2
-rw-r--r--app/controllers/admin/users_controller.rb3
-rw-r--r--app/controllers/application_controller.rb1
-rw-r--r--app/controllers/clusters/base_controller.rb2
-rw-r--r--app/controllers/clusters/clusters_controller.rb1
-rw-r--r--app/controllers/concerns/enforces_two_factor_authentication.rb3
-rw-r--r--app/controllers/concerns/find_snippet.rb24
-rw-r--r--app/controllers/concerns/integrations_actions.rb6
-rw-r--r--app/controllers/concerns/issuable_actions.rb29
-rw-r--r--app/controllers/concerns/issuable_collections.rb3
-rw-r--r--app/controllers/concerns/issuable_collections_action.rb4
-rw-r--r--app/controllers/concerns/known_sign_in.rb2
-rw-r--r--app/controllers/concerns/milestone_actions.rb8
-rw-r--r--app/controllers/concerns/notes_actions.rb6
-rw-r--r--app/controllers/concerns/preview_markdown.rb2
-rw-r--r--app/controllers/concerns/service_params.rb3
-rw-r--r--app/controllers/concerns/snippet_authorizations.rb23
-rw-r--r--app/controllers/concerns/snippets_actions.rb61
-rw-r--r--app/controllers/concerns/wiki_actions.rb232
-rw-r--r--app/controllers/concerns/workhorse_import_export_upload.rb33
-rw-r--r--app/controllers/dashboard/milestones_controller.rb32
-rw-r--r--app/controllers/dashboard/todos_controller.rb10
-rw-r--r--app/controllers/groups/boards_controller.rb1
-rw-r--r--app/controllers/groups/group_links_controller.rb2
-rw-r--r--app/controllers/groups/imports_controller.rb19
-rw-r--r--app/controllers/groups/milestones_controller.rb71
-rw-r--r--app/controllers/groups_controller.rb15
-rw-r--r--app/controllers/ide_controller.rb6
-rw-r--r--app/controllers/import/base_controller.rb76
-rw-r--r--app/controllers/import/bitbucket_controller.rb53
-rw-r--r--app/controllers/import/bitbucket_server_controller.rb77
-rw-r--r--app/controllers/import/fogbugz_controller.rb33
-rw-r--r--app/controllers/import/github_controller.rb2
-rw-r--r--app/controllers/import/gitlab_controller.rb29
-rw-r--r--app/controllers/import/gitlab_groups_controller.rb65
-rw-r--r--app/controllers/import/gitlab_projects_controller.rb27
-rw-r--r--app/controllers/projects/alert_management_controller.rb4
-rw-r--r--app/controllers/projects/alerting/notifications_controller.rb16
-rw-r--r--app/controllers/projects/badges_controller.rb11
-rw-r--r--app/controllers/projects/blame_controller.rb3
-rw-r--r--app/controllers/projects/blob_controller.rb6
-rw-r--r--app/controllers/projects/branches_controller.rb14
-rw-r--r--app/controllers/projects/ci/daily_build_group_report_results_controller.rb11
-rw-r--r--app/controllers/projects/discussions_controller.rb2
-rw-r--r--app/controllers/projects/environments_controller.rb2
-rw-r--r--app/controllers/projects/graphs_controller.rb10
-rw-r--r--app/controllers/projects/group_links_controller.rb7
-rw-r--r--app/controllers/projects/import/jira_controller.rb54
-rw-r--r--app/controllers/projects/issues_controller.rb1
-rw-r--r--app/controllers/projects/jobs_controller.rb40
-rw-r--r--app/controllers/projects/merge_requests/diffs_controller.rb11
-rw-r--r--app/controllers/projects/merge_requests/drafts_controller.rb129
-rw-r--r--app/controllers/projects/merge_requests_controller.rb3
-rw-r--r--app/controllers/projects/milestones_controller.rb4
-rw-r--r--app/controllers/projects/pipelines_controller.rb16
-rw-r--r--app/controllers/projects/refs_controller.rb2
-rw-r--r--app/controllers/projects/releases_controller.rb1
-rw-r--r--app/controllers/projects/services_controller.rb15
-rw-r--r--app/controllers/projects/settings/operations_controller.rb2
-rw-r--r--app/controllers/projects/snippets/application_controller.rb19
-rw-r--r--app/controllers/projects/snippets_controller.rb86
-rw-r--r--app/controllers/projects/tags_controller.rb18
-rw-r--r--app/controllers/projects/web_ide_terminals_controller.rb98
-rw-r--r--app/controllers/projects/wikis_controller.rb199
-rw-r--r--app/controllers/projects_controller.rb21
-rw-r--r--app/controllers/registrations/experience_levels_controller.rb44
-rw-r--r--app/controllers/registrations_controller.rb4
-rw-r--r--app/controllers/repositories/git_http_controller.rb2
-rw-r--r--app/controllers/search_controller.rb31
-rw-r--r--app/controllers/snippets/application_controller.rb22
-rw-r--r--app/controllers/snippets_controller.rb92
-rw-r--r--app/finders/admin/runners_finder.rb71
-rw-r--r--app/finders/ci/daily_build_group_report_results_finder.rb20
-rw-r--r--app/finders/ci/runners_finder.rb92
-rw-r--r--app/finders/events_finder.rb5
-rw-r--r--app/finders/issuable_finder.rb2
-rw-r--r--app/finders/issuable_finder/params.rb10
-rw-r--r--app/finders/labels_finder.rb9
-rw-r--r--app/finders/milestones_finder.rb6
-rw-r--r--app/finders/notes_finder.rb2
-rw-r--r--app/finders/resource_label_event_finder.rb41
-rw-r--r--app/finders/resource_milestone_event_finder.rb69
-rw-r--r--app/finders/uploader_finder.rb34
-rw-r--r--app/finders/users_finder.rb19
-rw-r--r--app/graphql/mutations/alert_management/alerts/set_assignees.rb56
-rw-r--r--app/graphql/mutations/alert_management/base.rb4
-rw-r--r--app/graphql/mutations/alert_management/update_alert_status.rb2
-rw-r--r--app/graphql/mutations/base_mutation.rb2
-rw-r--r--app/graphql/mutations/branches/create.rb2
-rw-r--r--app/graphql/mutations/commits/create.rb60
-rw-r--r--app/graphql/mutations/concerns/mutations/resolves_issuable.rb16
-rw-r--r--app/graphql/mutations/concerns/mutations/resolves_project.rb15
-rw-r--r--app/graphql/mutations/container_expiration_policies/update.rb62
-rw-r--r--app/graphql/mutations/discussions/toggle_resolve.rb73
-rw-r--r--app/graphql/mutations/issues/set_confidential.rb2
-rw-r--r--app/graphql/mutations/issues/set_due_date.rb2
-rw-r--r--app/graphql/mutations/issues/update.rb2
-rw-r--r--app/graphql/mutations/jira_import/import_users.rb44
-rw-r--r--app/graphql/mutations/jira_import/start.rb16
-rw-r--r--app/graphql/mutations/merge_requests/create.rb63
-rw-r--r--app/graphql/mutations/merge_requests/set_assignees.rb2
-rw-r--r--app/graphql/mutations/merge_requests/set_labels.rb7
-rw-r--r--app/graphql/mutations/merge_requests/set_locked.rb2
-rw-r--r--app/graphql/mutations/merge_requests/set_milestone.rb2
-rw-r--r--app/graphql/mutations/merge_requests/set_subscription.rb2
-rw-r--r--app/graphql/mutations/merge_requests/set_wip.rb2
-rw-r--r--app/graphql/mutations/metrics/dashboard/annotations/base.rb18
-rw-r--r--app/graphql/mutations/metrics/dashboard/annotations/delete.rb32
-rw-r--r--app/graphql/mutations/snippets/create.rb4
-rw-r--r--app/graphql/mutations/todos/mark_all_done.rb4
-rw-r--r--app/graphql/mutations/todos/mark_done.rb2
-rw-r--r--app/graphql/mutations/todos/restore.rb6
-rw-r--r--app/graphql/mutations/todos/restore_many.rb2
-rw-r--r--app/graphql/resolvers/alert_management/alert_resolver.rb42
-rw-r--r--app/graphql/resolvers/alert_management/alert_status_counts_resolver.rb4
-rw-r--r--app/graphql/resolvers/alert_management_alert_resolver.rb31
-rw-r--r--app/graphql/resolvers/assigned_merge_requests_resolver.rb9
-rw-r--r--app/graphql/resolvers/authored_merge_requests_resolver.rb9
-rw-r--r--app/graphql/resolvers/base_resolver.rb33
-rw-r--r--app/graphql/resolvers/concerns/looks_ahead.rb52
-rw-r--r--app/graphql/resolvers/concerns/resolves_merge_requests.rb67
-rw-r--r--app/graphql/resolvers/concerns/resolves_project.rb15
-rw-r--r--app/graphql/resolvers/full_path_resolver.rb7
-rw-r--r--app/graphql/resolvers/merge_request_resolver.rb18
-rw-r--r--app/graphql/resolvers/merge_requests_resolver.rb52
-rw-r--r--app/graphql/resolvers/project_members_resolver.rb21
-rw-r--r--app/graphql/resolvers/project_pipeline_resolver.rb17
-rw-r--r--app/graphql/resolvers/projects/jira_imports_resolver.rb2
-rw-r--r--app/graphql/resolvers/projects/jira_projects_resolver.rb76
-rw-r--r--app/graphql/resolvers/user_merge_requests_resolver.rb68
-rw-r--r--app/graphql/resolvers/user_resolver.rb43
-rw-r--r--app/graphql/resolvers/users_resolver.rb57
-rw-r--r--app/graphql/types/access_level_enum.rb15
-rw-r--r--app/graphql/types/access_level_type.rb17
-rw-r--r--app/graphql/types/alert_management/alert_sort_enum.rb12
-rw-r--r--app/graphql/types/alert_management/alert_type.rb11
-rw-r--r--app/graphql/types/base_object.rb4
-rw-r--r--app/graphql/types/board_type.rb2
-rw-r--r--app/graphql/types/ci/pipeline_type.rb2
-rw-r--r--app/graphql/types/commit_action_mode_enum.rb14
-rw-r--r--app/graphql/types/commit_action_type.rb22
-rw-r--r--app/graphql/types/commit_encoding_enum.rb10
-rw-r--r--app/graphql/types/container_expiration_policy_cadence_enum.rb17
-rw-r--r--app/graphql/types/container_expiration_policy_keep_enum.rb18
-rw-r--r--app/graphql/types/container_expiration_policy_older_than_enum.rb16
-rw-r--r--app/graphql/types/container_expiration_policy_type.rb21
-rw-r--r--app/graphql/types/evidence_type.rb21
-rw-r--r--app/graphql/types/group_member_type.rb17
-rw-r--r--app/graphql/types/group_type.rb39
-rw-r--r--app/graphql/types/jira_import_type.rb6
-rw-r--r--app/graphql/types/jira_user_type.rb19
-rw-r--r--app/graphql/types/member_interface.rb22
-rw-r--r--app/graphql/types/merge_request_type.rb12
-rw-r--r--app/graphql/types/metrics/dashboard_type.rb3
-rw-r--r--app/graphql/types/milestone_type.rb12
-rw-r--r--app/graphql/types/mutation_type.rb7
-rw-r--r--app/graphql/types/notes/discussion_type.rb2
-rw-r--r--app/graphql/types/notes/note_type.rb12
-rw-r--r--app/graphql/types/notes/noteable_type.rb2
-rw-r--r--app/graphql/types/permission_types/ci/pipeline.rb3
-rw-r--r--app/graphql/types/permission_types/merge_request.rb12
-rw-r--r--app/graphql/types/project_member_type.rb25
-rw-r--r--app/graphql/types/project_type.rb63
-rw-r--r--app/graphql/types/projects/service_type.rb2
-rw-r--r--app/graphql/types/projects/services/jira_project_type.rb21
-rw-r--r--app/graphql/types/projects/services/jira_service_type.rb11
-rw-r--r--app/graphql/types/query_type.rb14
-rw-r--r--app/graphql/types/release_assets_type.rb20
-rw-r--r--app/graphql/types/release_link_type.rb20
-rw-r--r--app/graphql/types/release_link_type_enum.rb12
-rw-r--r--app/graphql/types/release_source_type.rb14
-rw-r--r--app/graphql/types/release_type.rb4
-rw-r--r--app/graphql/types/resolvable_interface.rb28
-rw-r--r--app/graphql/types/snippet_type.rb10
-rw-r--r--app/graphql/types/snippets/file_input_action_enum.rb15
-rw-r--r--app/graphql/types/snippets/file_input_type.rb26
-rw-r--r--app/graphql/types/user_state_enum.rb12
-rw-r--r--app/graphql/types/user_type.rb22
-rw-r--r--app/helpers/active_sessions_helper.rb2
-rw-r--r--app/helpers/application_helper.rb3
-rw-r--r--app/helpers/application_settings_helper.rb14
-rw-r--r--app/helpers/auto_devops_helper.rb2
-rw-r--r--app/helpers/clusters_helper.rb24
-rw-r--r--app/helpers/environments_helper.rb15
-rw-r--r--app/helpers/events_helper.rb2
-rw-r--r--app/helpers/gitlab_routing_helper.rb29
-rw-r--r--app/helpers/issuables_helper.rb5
-rw-r--r--app/helpers/issues_helper.rb39
-rw-r--r--app/helpers/markup_helper.rb6
-rw-r--r--app/helpers/milestones_helper.rb309
-rw-r--r--app/helpers/milestones_routing_helper.rb19
-rw-r--r--app/helpers/namespaces_helper.rb41
-rw-r--r--app/helpers/notes_helper.rb23
-rw-r--r--app/helpers/notifications_helper.rb2
-rw-r--r--app/helpers/numbers_helper.rb5
-rw-r--r--app/helpers/page_layout_helper.rb10
-rw-r--r--app/helpers/projects/alert_management_helper.rb2
-rw-r--r--app/helpers/projects_helper.rb51
-rw-r--r--app/helpers/search_helper.rb107
-rw-r--r--app/helpers/services_helper.rb22
-rw-r--r--app/helpers/subscribable_banner_helper.rb9
-rw-r--r--app/helpers/timeboxes_helper.rb302
-rw-r--r--app/helpers/timeboxes_routing_helper.rb21
-rw-r--r--app/helpers/todos_helper.rb14
-rw-r--r--app/helpers/visibility_level_helper.rb11
-rw-r--r--app/helpers/wiki_helper.rb51
-rw-r--r--app/mailers/emails/issues.rb2
-rw-r--r--app/mailers/emails/profile.rb11
-rw-r--r--app/mailers/emails/reviews.rb33
-rw-r--r--app/mailers/notify.rb3
-rw-r--r--app/mailers/previews/notify_preview.rb2
-rw-r--r--app/models/active_session.rb2
-rw-r--r--app/models/alert_management.rb7
-rw-r--r--app/models/alert_management/alert.rb48
-rw-r--r--app/models/alert_management/alert_assignee.rb11
-rw-r--r--app/models/alert_management/alert_user_mention.rb8
-rw-r--r--app/models/application_record.rb4
-rw-r--r--app/models/application_setting.rb29
-rw-r--r--app/models/application_setting_implementation.rb33
-rw-r--r--app/models/audit_event.rb3
-rw-r--r--app/models/badge.rb2
-rw-r--r--app/models/blob.rb2
-rw-r--r--app/models/blob_viewer/go_mod.rb43
-rw-r--r--app/models/blob_viewer/metrics_dashboard_yml.rb44
-rw-r--r--app/models/board_group_recent_visit.rb2
-rw-r--r--app/models/board_project_recent_visit.rb2
-rw-r--r--app/models/chat_team.rb2
-rw-r--r--app/models/ci/bridge.rb3
-rw-r--r--app/models/ci/build.rb49
-rw-r--r--app/models/ci/build_dependencies.rb2
-rw-r--r--app/models/ci/build_report_result.rb45
-rw-r--r--app/models/ci/build_runner_session.rb15
-rw-r--r--app/models/ci/daily_build_group_report_result.rb2
-rw-r--r--app/models/ci/freeze_period.rb2
-rw-r--r--app/models/ci/group.rb2
-rw-r--r--app/models/ci/instance_variable.rb53
-rw-r--r--app/models/ci/job_artifact.rb29
-rw-r--r--app/models/ci/pipeline.rb50
-rw-r--r--app/models/ci/pipeline_enums.rb5
-rw-r--r--app/models/ci/processable.rb4
-rw-r--r--app/models/ci/ref.rb71
-rw-r--r--app/models/ci/runner.rb32
-rw-r--r--app/models/clusters/applications/cert_manager.rb6
-rw-r--r--app/models/clusters/applications/crossplane.rb3
-rw-r--r--app/models/clusters/applications/elastic_stack.rb12
-rw-r--r--app/models/clusters/applications/fluentd.rb3
-rw-r--r--app/models/clusters/applications/helm.rb6
-rw-r--r--app/models/clusters/applications/ingress.rb3
-rw-r--r--app/models/clusters/applications/jupyter.rb3
-rw-r--r--app/models/clusters/applications/knative.rb6
-rw-r--r--app/models/clusters/applications/prometheus.rb11
-rw-r--r--app/models/clusters/applications/runner.rb5
-rw-r--r--app/models/clusters/cluster.rb22
-rw-r--r--app/models/clusters/concerns/application_core.rb2
-rw-r--r--app/models/clusters/concerns/application_data.rb5
-rw-r--r--app/models/clusters/concerns/application_status.rb22
-rw-r--r--app/models/commit_status.rb25
-rw-r--r--app/models/concerns/cacheable_attributes.rb2
-rw-r--r--app/models/concerns/ci/contextable.rb2
-rw-r--r--app/models/concerns/each_batch.rb2
-rw-r--r--app/models/concerns/featurable.rb99
-rw-r--r--app/models/concerns/has_status.rb4
-rw-r--r--app/models/concerns/import_state/sidekiq_job_tracker.rb7
-rw-r--r--app/models/concerns/integration.rb19
-rw-r--r--app/models/concerns/issuable.rb30
-rw-r--r--app/models/concerns/limitable.rb29
-rw-r--r--app/models/concerns/mentionable.rb4
-rw-r--r--app/models/concerns/milestoneish.rb20
-rw-r--r--app/models/concerns/noteable.rb2
-rw-r--r--app/models/concerns/prometheus_adapter.rb2
-rw-r--r--app/models/concerns/relative_positioning.rb2
-rw-r--r--app/models/concerns/resolvable_discussion.rb7
-rw-r--r--app/models/concerns/resolvable_note.rb4
-rw-r--r--app/models/concerns/storage/legacy_namespace.rb2
-rw-r--r--app/models/concerns/timebox.rb51
-rw-r--r--app/models/concerns/token_authenticatable.rb5
-rw-r--r--app/models/concerns/update_highest_role.rb4
-rw-r--r--app/models/container_expiration_policy.rb6
-rw-r--r--app/models/container_repository.rb14
-rw-r--r--app/models/dashboard_group_milestone.rb29
-rw-r--r--app/models/dashboard_milestone.rb19
-rw-r--r--app/models/data_list.rb25
-rw-r--r--app/models/deployment.rb2
-rw-r--r--app/models/design_management/design.rb68
-rw-r--r--app/models/design_management/version.rb2
-rw-r--r--app/models/diff_note.rb2
-rw-r--r--app/models/discussion.rb1
-rw-r--r--app/models/draft_note.rb122
-rw-r--r--app/models/environment.rb2
-rw-r--r--app/models/event.rb194
-rw-r--r--app/models/global_milestone.rb108
-rw-r--r--app/models/group.rb59
-rw-r--r--app/models/group_deploy_key.rb11
-rw-r--r--app/models/group_group_link.rb1
-rw-r--r--app/models/group_import_state.rb7
-rw-r--r--app/models/group_milestone.rb49
-rw-r--r--app/models/internal_id.rb24
-rw-r--r--app/models/issue.rb27
-rw-r--r--app/models/issue/metrics.rb4
-rw-r--r--app/models/iteration.rb25
-rw-r--r--app/models/jira_import_state.rb27
-rw-r--r--app/models/label.rb4
-rw-r--r--app/models/lfs_object.rb4
-rw-r--r--app/models/license_template.rb2
-rw-r--r--app/models/member.rb2
-rw-r--r--app/models/members/group_member.rb11
-rw-r--r--app/models/members/project_member.rb2
-rw-r--r--app/models/merge_request.rb32
-rw-r--r--app/models/merge_request_context_commit.rb2
-rw-r--r--app/models/merge_request_context_commit_diff_file.rb2
-rw-r--r--app/models/merge_request_diff.rb4
-rw-r--r--app/models/merge_request_diff_commit.rb2
-rw-r--r--app/models/metrics/dashboard/annotation.rb13
-rw-r--r--app/models/milestone.rb49
-rw-r--r--app/models/namespace.rb8
-rw-r--r--app/models/note.rb25
-rw-r--r--app/models/pages_domain.rb8
-rw-r--r--app/models/pages_domain_acme_order.rb2
-rw-r--r--app/models/performance_monitoring/prometheus_dashboard.rb43
-rw-r--r--app/models/performance_monitoring/prometheus_metric.rb26
-rw-r--r--app/models/performance_monitoring/prometheus_panel.rb25
-rw-r--r--app/models/performance_monitoring/prometheus_panel_group.rb21
-rw-r--r--app/models/project.rb132
-rw-r--r--app/models/project_ci_cd_setting.rb13
-rw-r--r--app/models/project_feature.rb106
-rw-r--r--app/models/project_group_link.rb6
-rw-r--r--app/models/project_import_state.rb6
-rw-r--r--app/models/project_metrics_setting.rb7
-rw-r--r--app/models/project_repository_storage_move.rb22
-rw-r--r--app/models/project_services/alerts_service.rb2
-rw-r--r--app/models/project_services/chat_message/alert_message.rb74
-rw-r--r--app/models/project_services/chat_message/merge_message.rb2
-rw-r--r--app/models/project_services/chat_message/pipeline_message.rb6
-rw-r--r--app/models/project_services/hipchat_service.rb4
-rw-r--r--app/models/project_services/jira_service.rb23
-rw-r--r--app/models/project_services/pipelines_email_service.rb6
-rw-r--r--app/models/project_services/prometheus_service.rb43
-rw-r--r--app/models/project_services/slack_service.rb16
-rw-r--r--app/models/project_setting.rb4
-rw-r--r--app/models/prometheus_alert_event.rb6
-rw-r--r--app/models/push_event.rb4
-rw-r--r--app/models/releases/evidence.rb55
-rw-r--r--app/models/releases/link.rb7
-rw-r--r--app/models/remote_mirror.rb12
-rw-r--r--app/models/repository.rb8
-rw-r--r--app/models/repository_language.rb2
-rw-r--r--app/models/resource_label_event.rb8
-rw-r--r--app/models/resource_milestone_event.rb10
-rw-r--r--app/models/review.rb30
-rw-r--r--app/models/route.rb2
-rw-r--r--app/models/self_managed_prometheus_alert_event.rb6
-rw-r--r--app/models/service.rb26
-rw-r--r--app/models/service_list.rb27
-rw-r--r--app/models/snippet.rb2
-rw-r--r--app/models/snippet_input_action.rb62
-rw-r--r--app/models/snippet_input_action_collection.rb25
-rw-r--r--app/models/ssh_host_key.rb2
-rw-r--r--app/models/storage/legacy_project.rb2
-rw-r--r--app/models/terraform/state.rb2
-rw-r--r--app/models/todo.rb18
-rw-r--r--app/models/uploads/base.rb2
-rw-r--r--app/models/user.rb61
-rw-r--r--app/models/user_interacted_project.rb14
-rw-r--r--app/models/user_preference.rb2
-rw-r--r--app/models/web_ide_terminal.rb51
-rw-r--r--app/models/wiki.rb2
-rw-r--r--app/models/wiki_directory.rb2
-rw-r--r--app/models/wiki_page.rb8
-rw-r--r--app/models/wiki_page/meta.rb2
-rw-r--r--app/models/wiki_page/slug.rb4
-rw-r--r--app/policies/ci/build_policy.rb22
-rw-r--r--app/policies/container_expiration_policy_policy.rb5
-rw-r--r--app/policies/draft_note_policy.rb13
-rw-r--r--app/policies/project_policy.rb35
-rw-r--r--app/policies/releases/link_policy.rb7
-rw-r--r--app/policies/releases/source_policy.rb13
-rw-r--r--app/presenters/gitlab/blame_presenter.rb82
-rw-r--r--app/presenters/projects/prometheus/alert_presenter.rb8
-rw-r--r--app/presenters/release_presenter.rb2
-rw-r--r--app/presenters/snippet_presenter.rb8
-rw-r--r--app/serializers/build_artifact_entity.rb34
-rw-r--r--app/serializers/ci/dag_job_entity.rb1
-rw-r--r--app/serializers/ci/dag_pipeline_entity.rb6
-rw-r--r--app/serializers/ci/daily_build_group_report_result_entity.rb13
-rw-r--r--app/serializers/ci/daily_build_group_report_result_serializer.rb28
-rw-r--r--app/serializers/cluster_entity.rb1
-rw-r--r--app/serializers/cluster_serializer.rb1
-rw-r--r--app/serializers/container_repository_entity.rb2
-rw-r--r--app/serializers/diff_file_base_entity.rb6
-rw-r--r--app/serializers/diff_file_metadata_entity.rb5
-rw-r--r--app/serializers/diffs_entity.rb14
-rw-r--r--app/serializers/draft_note_entity.rb39
-rw-r--r--app/serializers/draft_note_serializer.rb4
-rw-r--r--app/serializers/import/base_provider_repo_entity.rb8
-rw-r--r--app/serializers/import/bitbucket_provider_repo_entity.rb15
-rw-r--r--app/serializers/import/bitbucket_server_provider_repo_entity.rb7
-rw-r--r--app/serializers/import/fogbugz_provider_repo_entity.rb17
-rw-r--r--app/serializers/import/githubish_provider_repo_entity.rb19
-rw-r--r--app/serializers/import/gitlab_provider_repo_entity.rb19
-rw-r--r--app/serializers/import/provider_repo_serializer.rb23
-rw-r--r--app/serializers/merge_request_noteable_entity.rb2
-rw-r--r--app/serializers/paginated_diff_entity.rb10
-rw-r--r--app/serializers/pipeline_details_entity.rb3
-rw-r--r--app/serializers/pipeline_serializer.rb36
-rw-r--r--app/serializers/provider_repo_entity.rb25
-rw-r--r--app/serializers/provider_repo_serializer.rb5
-rw-r--r--app/serializers/service_field_entity.rb24
-rw-r--r--app/serializers/service_field_serializer.rb5
-rw-r--r--app/serializers/web_ide_terminal_entity.rb12
-rw-r--r--app/serializers/web_ide_terminal_serializer.rb11
-rw-r--r--app/services/admin/propagate_integration_service.rb142
-rw-r--r--app/services/alert_management/alerts/update_service.rb98
-rw-r--r--app/services/alert_management/create_alert_issue_service.rb3
-rw-r--r--app/services/alert_management/process_prometheus_alert_service.rb6
-rw-r--r--app/services/auto_merge/base_service.rb54
-rw-r--r--app/services/award_emojis/destroy_service.rb2
-rw-r--r--app/services/ci/authorize_job_artifact_service.rb53
-rw-r--r--app/services/ci/build_report_result_service.rb36
-rw-r--r--app/services/ci/create_cross_project_pipeline_service.rb1
-rw-r--r--app/services/ci/create_web_ide_terminal_service.rb123
-rw-r--r--app/services/ci/extract_sections_from_build_trace_service.rb2
-rw-r--r--app/services/ci/process_pipeline_service.rb2
-rw-r--r--app/services/ci/update_ci_ref_status_service.rb1
-rw-r--r--app/services/ci/web_ide_config_service.rb59
-rw-r--r--app/services/clusters/applications/prometheus_config_service.rb12
-rw-r--r--app/services/clusters/parse_cluster_applications_artifact_service.rb27
-rw-r--r--app/services/commits/create_service.rb2
-rw-r--r--app/services/concerns/exclusive_lease_guard.rb2
-rw-r--r--app/services/concerns/integrations/project_test_data.rb62
-rw-r--r--app/services/concerns/measurable.rb2
-rw-r--r--app/services/concerns/spam_check_methods.rb11
-rw-r--r--app/services/container_expiration_policies/update_service.rb38
-rw-r--r--app/services/container_expiration_policy_service.rb7
-rw-r--r--app/services/design_management/delete_designs_service.rb5
-rw-r--r--app/services/design_management/save_designs_service.rb17
-rw-r--r--app/services/discussions/resolve_service.rb55
-rw-r--r--app/services/draft_notes/base_service.rb21
-rw-r--r--app/services/draft_notes/create_service.rb56
-rw-r--r--app/services/draft_notes/destroy_service.rb23
-rw-r--r--app/services/draft_notes/publish_service.rb67
-rw-r--r--app/services/event_create_service.rb132
-rw-r--r--app/services/git/wiki_push_service/change.rb6
-rw-r--r--app/services/groups/destroy_service.rb2
-rw-r--r--app/services/groups/group_links/create_service.rb2
-rw-r--r--app/services/groups/group_links/destroy_service.rb6
-rw-r--r--app/services/groups/import_export/export_service.rb29
-rw-r--r--app/services/groups/import_export/import_service.rb23
-rw-r--r--app/services/groups/transfer_service.rb10
-rw-r--r--app/services/import/github_service.rb29
-rw-r--r--app/services/integrations/test/base_service.rb36
-rw-r--r--app/services/integrations/test/project_service.rb47
-rw-r--r--app/services/issuable/bulk_update_service.rb13
-rw-r--r--app/services/issuable/clone/attributes_rewriter.rb2
-rw-r--r--app/services/issuable_base_service.rb12
-rw-r--r--app/services/issues/create_service.rb7
-rw-r--r--app/services/issues/import_csv_service.rb2
-rw-r--r--app/services/issues/update_service.rb6
-rw-r--r--app/services/jira/requests/base.rb52
-rw-r--r--app/services/jira/requests/projects.rb32
-rw-r--r--app/services/jira_import/start_import_service.rb4
-rw-r--r--app/services/jira_import/users_importer.rb43
-rw-r--r--app/services/jira_import/users_mapper.rb31
-rw-r--r--app/services/keys/create_service.rb8
-rw-r--r--app/services/labels/available_labels_service.rb6
-rw-r--r--app/services/labels/create_service.rb2
-rw-r--r--app/services/labels/promote_service.rb2
-rw-r--r--app/services/merge_requests/merge_service.rb4
-rw-r--r--app/services/merge_requests/update_service.rb4
-rw-r--r--app/services/metrics/dashboard/base_service.rb3
-rw-r--r--app/services/metrics/dashboard/self_monitoring_dashboard_service.rb4
-rw-r--r--app/services/metrics/dashboard/system_dashboard_service.rb4
-rw-r--r--app/services/milestones/promote_service.rb2
-rw-r--r--app/services/namespaces/check_storage_size_service.rb5
-rw-r--r--app/services/notes/create_service.rb8
-rw-r--r--app/services/notes/post_process_service.rb2
-rw-r--r--app/services/notification_recipients/build_service.rb6
-rw-r--r--app/services/notification_recipients/builder/new_review.rb43
-rw-r--r--app/services/notification_service.rb29
-rw-r--r--app/services/pages/delete_service.rb2
-rw-r--r--app/services/projects/after_import_service.rb8
-rw-r--r--app/services/projects/alerting/notify_service.rb33
-rw-r--r--app/services/projects/container_repository/cleanup_tags_service.rb12
-rw-r--r--app/services/projects/create_service.rb24
-rw-r--r--app/services/projects/destroy_service.rb2
-rw-r--r--app/services/projects/detect_repository_languages_service.rb2
-rw-r--r--app/services/projects/group_links/create_service.rb1
-rw-r--r--app/services/projects/group_links/destroy_service.rb4
-rw-r--r--app/services/projects/group_links/update_service.rb29
-rw-r--r--app/services/projects/hashed_storage/base_attachment_service.rb2
-rw-r--r--app/services/projects/import_export/export_service.rb14
-rw-r--r--app/services/projects/import_service.rb2
-rw-r--r--app/services/projects/lfs_pointers/lfs_link_service.rb2
-rw-r--r--app/services/projects/lsif_data_service.rb101
-rw-r--r--app/services/projects/move_deploy_keys_projects_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_group_links_service.rb2
-rw-r--r--app/services/projects/move_project_members_service.rb2
-rw-r--r--app/services/projects/operations/update_service.rb4
-rw-r--r--app/services/projects/prometheus/alerts/create_events_service.rb8
-rw-r--r--app/services/projects/prometheus/alerts/notify_service.rb35
-rw-r--r--app/services/projects/propagate_service_template.rb48
-rw-r--r--app/services/projects/update_remote_mirror_service.rb6
-rw-r--r--app/services/projects/update_repository_storage_service.rb7
-rw-r--r--app/services/projects/update_service.rb13
-rw-r--r--app/services/projects/update_statistics_service.rb2
-rw-r--r--app/services/prometheus/create_default_alerts_service.rb11
-rw-r--r--app/services/prometheus/proxy_service.rb4
-rw-r--r--app/services/prometheus/proxy_variable_substitution_service.rb24
-rw-r--r--app/services/protected_branches/legacy_api_update_service.rb4
-rw-r--r--app/services/releases/create_evidence_service.rb25
-rw-r--r--app/services/releases/create_service.rb33
-rw-r--r--app/services/resource_events/change_labels_service.rb2
-rw-r--r--app/services/resource_events/change_state_service.rb36
-rw-r--r--app/services/resource_events/merge_into_notes_service.rb5
-rw-r--r--app/services/resource_events/synthetic_state_notes_builder_service.rb20
-rw-r--r--app/services/search_service.rb22
-rw-r--r--app/services/service_response.rb6
-rw-r--r--app/services/snippets/base_service.rb33
-rw-r--r--app/services/snippets/bulk_destroy_service.rb6
-rw-r--r--app/services/snippets/create_service.rb31
-rw-r--r--app/services/snippets/update_service.rb41
-rw-r--r--app/services/spam/akismet_service.rb4
-rw-r--r--app/services/spam/spam_action_service.rb21
-rw-r--r--app/services/spam/spam_constants.rb22
-rw-r--r--app/services/spam/spam_verdict_service.rb76
-rw-r--r--app/services/submit_usage_ping_service.rb2
-rw-r--r--app/services/suggestions/apply_service.rb110
-rw-r--r--app/services/suggestions/create_service.rb2
-rw-r--r--app/services/system_notes/issuables_service.rb14
-rw-r--r--app/services/test_hooks/base_service.rb28
-rw-r--r--app/services/test_hooks/project_service.rb72
-rw-r--r--app/services/test_hooks/system_service.rb25
-rw-r--r--app/services/todo_service.rb98
-rw-r--r--app/services/user_project_access_changed_service.rb3
-rw-r--r--app/services/users/build_service.rb3
-rw-r--r--app/services/users/destroy_service.rb2
-rw-r--r--app/services/users/migrate_to_ghost_user_service.rb5
-rw-r--r--app/services/web_hook_service.rb2
-rw-r--r--app/services/wiki_pages/create_service.rb2
-rw-r--r--app/services/wiki_pages/destroy_service.rb2
-rw-r--r--app/services/wiki_pages/update_service.rb2
-rw-r--r--app/uploaders/file_mover.rb2
-rw-r--r--app/validators/json_schema_validator.rb38
-rw-r--r--app/validators/json_schemas/build_report_result_data.json12
-rw-r--r--app/validators/json_schemas/build_report_result_data_tests.json13
-rw-r--r--app/validators/json_schemas/daily_build_group_report_result_data.json8
-rw-r--r--app/views/admin/appearances/_form.html.haml10
-rw-r--r--app/views/admin/appearances/_system_header_footer_form.html.haml2
-rw-r--r--app/views/admin/application_settings/_account_and_limit.html.haml5
-rw-r--r--app/views/admin/application_settings/_issue_limits.html.haml2
-rw-r--r--app/views/admin/application_settings/_outbound.html.haml4
-rw-r--r--app/views/admin/application_settings/_repository_storage.html.haml8
-rw-r--r--app/views/admin/application_settings/_spam.html.haml9
-rw-r--r--app/views/admin/application_settings/ci/_header.html.haml20
-rw-r--r--app/views/admin/application_settings/ci_cd.html.haml11
-rw-r--r--app/views/admin/broadcast_messages/_form.html.haml4
-rw-r--r--app/views/admin/broadcast_messages/index.html.haml4
-rw-r--r--app/views/admin/groups/_group.html.haml43
-rw-r--r--app/views/admin/groups/show.html.haml2
-rw-r--r--app/views/admin/hook_logs/_index.html.haml2
-rw-r--r--app/views/admin/hooks/edit.html.haml2
-rw-r--r--app/views/admin/projects/show.html.haml2
-rw-r--r--app/views/admin/sessions/_two_factor_u2f.html.haml17
-rw-r--r--app/views/admin/sessions/two_factor.html.haml2
-rw-r--r--app/views/admin/users/_admin_notes.html.haml7
-rw-r--r--app/views/admin/users/_form.html.haml2
-rw-r--r--app/views/admin/users/_user_detail.html.haml4
-rw-r--r--app/views/admin/users/_user_detail_note.html.haml7
-rw-r--r--app/views/admin/users/_user_listing_note.html.haml3
-rw-r--r--app/views/admin/users/show.html.haml8
-rw-r--r--app/views/ci/variables/_index.html.haml13
-rw-r--r--app/views/clusters/clusters/_banner.html.haml2
-rw-r--r--app/views/clusters/clusters/_gcp_signup_offer_banner.html.haml2
-rw-r--r--app/views/clusters/clusters/_gitlab_integration_form.html.haml2
-rw-r--r--app/views/clusters/clusters/_sidebar.html.haml2
-rw-r--r--app/views/clusters/clusters/index.html.haml2
-rw-r--r--app/views/clusters/clusters/show.html.haml2
-rw-r--r--app/views/dashboard/milestones/_milestone.html.haml1
-rw-r--r--app/views/dashboard/milestones/show.html.haml5
-rw-r--r--app/views/devise/confirmations/almost_there.haml2
-rw-r--r--app/views/devise/sessions/two_factor.html.haml2
-rw-r--r--app/views/devise/shared/_omniauth_box.html.haml2
-rw-r--r--app/views/doorkeeper/applications/index.html.haml4
-rw-r--r--app/views/events/event/_note.html.haml6
-rw-r--r--app/views/groups/_flash_messages.html.haml1
-rw-r--r--app/views/groups/_home_panel.html.haml6
-rw-r--r--app/views/groups/_import_group_pane.html.haml52
-rw-r--r--app/views/groups/_new_group_fields.html.haml22
-rw-r--r--app/views/groups/imports/show.html.haml10
-rw-r--r--app/views/groups/milestones/_form.html.haml4
-rw-r--r--app/views/groups/milestones/_milestone.html.haml2
-rw-r--r--app/views/groups/milestones/index.html.haml5
-rw-r--r--app/views/groups/new.html.haml73
-rw-r--r--app/views/groups/registry/repositories/index.html.haml4
-rw-r--r--app/views/groups/settings/_export.html.haml2
-rw-r--r--app/views/groups/settings/_general.html.haml2
-rw-r--r--app/views/groups/show.html.haml4
-rw-r--r--app/views/groups/sidebar/_packages.html.haml6
-rw-r--r--app/views/import/_githubish_status.html.haml5
-rw-r--r--app/views/import/bitbucket/status.html.haml167
-rw-r--r--app/views/import/bitbucket_server/new.html.haml6
-rw-r--r--app/views/import/bitbucket_server/status.html.haml165
-rw-r--r--app/views/import/fogbugz/status.html.haml99
-rw-r--r--app/views/import/gitlab/status.html.haml95
-rw-r--r--app/views/import/phabricator/new.html.haml6
-rw-r--r--app/views/layouts/_head.html.haml10
-rw-r--r--app/views/layouts/_page.html.haml4
-rw-r--r--app/views/layouts/_search.html.haml32
-rw-r--r--app/views/layouts/group.html.haml1
-rw-r--r--app/views/layouts/header/_current_user_dropdown.html.haml4
-rw-r--r--app/views/layouts/header/_default.html.haml15
-rw-r--r--app/views/layouts/header/_logo_with_title.html.haml2
-rw-r--r--app/views/layouts/nav/breadcrumbs/_collapsed_dropdown.html.haml2
-rw-r--r--app/views/layouts/nav/sidebar/_group.html.haml4
-rw-r--r--app/views/layouts/nav/sidebar/_project.html.haml35
-rw-r--r--app/views/layouts/project.html.haml3
-rw-r--r--app/views/layouts/terms.html.haml4
-rw-r--r--app/views/notify/merged_merge_request_email.html.haml2
-rw-r--r--app/views/notify/merged_merge_request_email.text.haml2
-rw-r--r--app/views/notify/new_issue_email.html.haml2
-rw-r--r--app/views/notify/new_review_email.html.haml16
-rw-r--r--app/views/notify/new_review_email.text.erb13
-rw-r--r--app/views/notify/unknown_sign_in_email.html.haml66
-rw-r--r--app/views/profiles/_event_table.html.haml2
-rw-r--r--app/views/profiles/accounts/show.html.haml8
-rw-r--r--app/views/profiles/active_sessions/index.html.haml2
-rw-r--r--app/views/profiles/audit_log.html.haml2
-rw-r--r--app/views/profiles/chat_names/index.html.haml2
-rw-r--r--app/views/profiles/emails/index.html.haml6
-rw-r--r--app/views/profiles/gpg_keys/index.html.haml4
-rw-r--r--app/views/profiles/keys/index.html.haml4
-rw-r--r--app/views/profiles/notifications/show.html.haml4
-rw-r--r--app/views/profiles/passwords/edit.html.haml4
-rw-r--r--app/views/profiles/personal_access_tokens/index.html.haml8
-rw-r--r--app/views/profiles/preferences/_sourcegraph.html.haml2
-rw-r--r--app/views/profiles/preferences/show.html.haml10
-rw-r--r--app/views/profiles/show.html.haml10
-rw-r--r--app/views/profiles/two_factor_auths/show.html.haml12
-rw-r--r--app/views/projects/_export.html.haml2
-rw-r--r--app/views/projects/_find_file_link.html.haml3
-rw-r--r--app/views/projects/_flash_messages.html.haml3
-rw-r--r--app/views/projects/_home_panel.html.haml10
-rw-r--r--app/views/projects/_import_project_pane.html.haml6
-rw-r--r--app/views/projects/_md_preview.html.haml36
-rw-r--r--app/views/projects/_merge_request_merge_checks_settings.html.haml7
-rw-r--r--app/views/projects/_merge_request_merge_suggestions_settings.html.haml4
-rw-r--r--app/views/projects/_new_project_fields.html.haml2
-rw-r--r--app/views/projects/_wiki.html.haml2
-rw-r--r--app/views/projects/_zen.html.haml19
-rw-r--r--app/views/projects/blame/_blame_group.html.haml26
-rw-r--r--app/views/projects/blame/show.html.haml47
-rw-r--r--app/views/projects/blob/_editor.html.haml2
-rw-r--r--app/views/projects/blob/_header_content.html.haml2
-rw-r--r--app/views/projects/blob/_markdown_buttons.html.haml13
-rw-r--r--app/views/projects/blob/viewers/_metrics_dashboard_yml.html.haml11
-rw-r--r--app/views/projects/blob/viewers/_metrics_dashboard_yml_loading.html.haml4
-rw-r--r--app/views/projects/blob/viewers/_readme.html.haml2
-rw-r--r--app/views/projects/blob/viewers/_route_map.html.haml2
-rw-r--r--app/views/projects/blob/viewers/_route_map_loading.html.haml2
-rw-r--r--app/views/projects/branches/_branch.html.haml8
-rw-r--r--app/views/projects/branches/_panel.html.haml2
-rw-r--r--app/views/projects/branches/index.html.haml2
-rw-r--r--app/views/projects/buttons/_fork.html.haml2
-rw-r--r--app/views/projects/buttons/_star.html.haml4
-rw-r--r--app/views/projects/cleanup/_show.html.haml8
-rw-r--r--app/views/projects/commit/_commit_box.html.haml4
-rw-r--r--app/views/projects/commits/_commit.html.haml2
-rw-r--r--app/views/projects/diffs/_file.html.haml2
-rw-r--r--app/views/projects/diffs/_stats.html.haml4
-rw-r--r--app/views/projects/empty.html.haml6
-rw-r--r--app/views/projects/environments/_form.html.haml4
-rw-r--r--app/views/projects/environments/empty_metrics.html.haml2
-rw-r--r--app/views/projects/environments/index.html.haml2
-rw-r--r--app/views/projects/environments/metrics.html.haml2
-rw-r--r--app/views/projects/environments/show.html.haml4
-rw-r--r--app/views/projects/forks/_fork_button.html.haml2
-rw-r--r--app/views/projects/forks/new.html.haml4
-rw-r--r--app/views/projects/graphs/charts.html.haml2
-rw-r--r--app/views/projects/hook_logs/_index.html.haml4
-rw-r--r--app/views/projects/hook_logs/show.html.haml2
-rw-r--r--app/views/projects/hooks/edit.html.haml2
-rw-r--r--app/views/projects/import/jira/show.html.haml39
-rw-r--r--app/views/projects/issues/_issue.html.haml1
-rw-r--r--app/views/projects/issues/_issue_estimate.html.haml7
-rw-r--r--app/views/projects/issues/_new_branch.html.haml2
-rw-r--r--app/views/projects/issues/import_csv/_button.html.haml28
-rw-r--r--app/views/projects/issues/index.html.haml9
-rw-r--r--app/views/projects/issues/show.html.haml1
-rw-r--r--app/views/projects/logs/empty_logs.html.haml2
-rw-r--r--app/views/projects/merge_requests/show.html.haml2
-rw-r--r--app/views/projects/milestones/_form.html.haml4
-rw-r--r--app/views/projects/milestones/_milestone.html.haml1
-rw-r--r--app/views/projects/new.html.haml14
-rw-r--r--app/views/projects/pipeline_schedules/_form.html.haml2
-rw-r--r--app/views/projects/pipelines/_with_tabs.html.haml12
-rw-r--r--app/views/projects/pipelines/charts.html.haml2
-rw-r--r--app/views/projects/pipelines/index.html.haml1
-rw-r--r--app/views/projects/project_templates/_built_in_templates.html.haml2
-rw-r--r--app/views/projects/protected_branches/show.html.haml2
-rw-r--r--app/views/projects/protected_tags/show.html.haml2
-rw-r--r--app/views/projects/registry/repositories/_tag.html.haml33
-rw-r--r--app/views/projects/registry/repositories/index.html.haml3
-rw-r--r--app/views/projects/services/_form.html.haml3
-rw-r--r--app/views/projects/services/alerts/_help.html.haml5
-rw-r--r--app/views/projects/services/prometheus/_show.html.haml2
-rw-r--r--app/views/projects/settings/access_tokens/index.html.haml2
-rw-r--r--app/views/projects/settings/ci_cd/_form.html.haml2
-rw-r--r--app/views/projects/settings/integrations/show.html.haml6
-rw-r--r--app/views/projects/settings/operations/_external_dashboard.html.haml3
-rw-r--r--app/views/projects/settings/operations/_incidents.html.haml2
-rw-r--r--app/views/projects/settings/operations/_metrics_dashboard.html.haml5
-rw-r--r--app/views/projects/settings/operations/show.html.haml2
-rw-r--r--app/views/projects/snippets/_actions.html.haml2
-rw-r--r--app/views/projects/tags/_tag.html.haml6
-rw-r--r--app/views/projects/tags/new.html.haml4
-rw-r--r--app/views/projects/tags/releases/edit.html.haml4
-rw-r--r--app/views/projects/triggers/_index.html.haml2
-rw-r--r--app/views/projects/triggers/edit.html.haml2
-rw-r--r--app/views/projects/wikis/_form.html.haml72
-rw-r--r--app/views/projects/wikis/_main_links.html.haml9
-rw-r--r--app/views/projects/wikis/_pages_wiki_page.html.haml6
-rw-r--r--app/views/projects/wikis/_sidebar.html.haml22
-rw-r--r--app/views/projects/wikis/_sidebar_wiki_page.html.haml3
-rw-r--r--app/views/projects/wikis/_wiki_page.html.haml1
-rw-r--r--app/views/projects/wikis/edit.html.haml31
-rw-r--r--app/views/projects/wikis/git_access.html.haml10
-rw-r--r--app/views/projects/wikis/history.html.haml42
-rw-r--r--app/views/projects/wikis/pages.html.haml32
-rw-r--r--app/views/projects/wikis/show.html.haml32
-rw-r--r--app/views/registrations/experience_levels/show.html.haml28
-rw-r--r--app/views/shared/_broadcast_message.html.haml4
-rw-r--r--app/views/shared/_choose_avatar_button.html.haml5
-rw-r--r--app/views/shared/_custom_attributes.html.haml12
-rw-r--r--app/views/shared/_field.html.haml5
-rw-r--r--app/views/shared/_file_highlight.html.haml2
-rw-r--r--app/views/shared/_file_picker_button.html.haml6
-rw-r--r--app/views/shared/_group_form.html.haml4
-rw-r--r--app/views/shared/_md_preview.html.haml36
-rw-r--r--app/views/shared/_namespace_storage_limit_alert.html.haml26
-rw-r--r--app/views/shared/_new_merge_request_checkbox.html.haml2
-rw-r--r--app/views/shared/_promo.html.haml6
-rw-r--r--app/views/shared/_service_settings.html.haml10
-rw-r--r--app/views/shared/_visibility_level.html.haml2
-rw-r--r--app/views/shared/_visibility_radios.html.haml7
-rw-r--r--app/views/shared/_zen.html.haml19
-rw-r--r--app/views/shared/access_tokens/_created_container.html.haml2
-rw-r--r--app/views/shared/access_tokens/_form.html.haml2
-rw-r--r--app/views/shared/blob/_markdown_buttons.html.haml13
-rw-r--r--app/views/shared/boards/_show.html.haml29
-rw-r--r--app/views/shared/deploy_keys/_form.html.haml2
-rw-r--r--app/views/shared/deploy_keys/_index.html.haml2
-rw-r--r--app/views/shared/deploy_keys/_project_group_form.html.haml4
-rw-r--r--app/views/shared/deploy_tokens/_index.html.haml2
-rw-r--r--app/views/shared/deploy_tokens/_new_deploy_token.html.haml2
-rw-r--r--app/views/shared/empty_states/_snippets.html.haml4
-rw-r--r--app/views/shared/empty_states/_wikis.html.haml19
-rw-r--r--app/views/shared/file_hooks/_index.html.haml2
-rw-r--r--app/views/shared/form_elements/_description.html.haml4
-rw-r--r--app/views/shared/groups/_group.html.haml37
-rw-r--r--app/views/shared/issuable/_form.html.haml2
-rw-r--r--app/views/shared/issuable/_search_bar.html.haml2
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml3
-rw-r--r--app/views/shared/issuable/_sidebar_assignees.html.haml15
-rw-r--r--app/views/shared/issuable/form/_metadata.html.haml8
-rw-r--r--app/views/shared/milestones/_deprecation_message.html.haml4
-rw-r--r--app/views/shared/milestones/_form_dates.html.haml12
-rw-r--r--app/views/shared/milestones/_header.html.haml6
-rw-r--r--app/views/shared/milestones/_milestone.html.haml92
-rw-r--r--app/views/shared/milestones/_sidebar.html.haml56
-rw-r--r--app/views/shared/milestones/_top.html.haml27
-rw-r--r--app/views/shared/notes/_edit_form.html.haml4
-rw-r--r--app/views/shared/notes/_form.html.haml4
-rw-r--r--app/views/shared/notifications/_custom_notifications.html.haml4
-rw-r--r--app/views/shared/notifications/_new_button.html.haml2
-rw-r--r--app/views/shared/projects/_project.html.haml12
-rw-r--r--app/views/shared/snippets/_form.html.haml8
-rw-r--r--app/views/shared/snippets/_header.html.haml6
-rw-r--r--app/views/shared/tokens/_scopes_list.html.haml2
-rw-r--r--app/views/shared/web_hooks/_hook.html.haml4
-rw-r--r--app/views/shared/web_hooks/_title_and_docs.html.haml13
-rw-r--r--app/views/shared/wikis/_form.html.haml79
-rw-r--r--app/views/shared/wikis/_main_links.html.haml9
-rw-r--r--app/views/shared/wikis/_pages_wiki_page.html.haml6
-rw-r--r--app/views/shared/wikis/_sidebar.html.haml22
-rw-r--r--app/views/shared/wikis/_sidebar_wiki_page.html.haml3
-rw-r--r--app/views/shared/wikis/_wiki_directory.html.haml (renamed from app/views/projects/wikis/_wiki_directory.html.haml)0
-rw-r--r--app/views/shared/wikis/_wiki_page.html.haml1
-rw-r--r--app/views/shared/wikis/edit.html.haml31
-rw-r--r--app/views/shared/wikis/empty.html.haml (renamed from app/views/projects/wikis/empty.html.haml)0
-rw-r--r--app/views/shared/wikis/history.html.haml41
-rw-r--r--app/views/shared/wikis/pages.html.haml32
-rw-r--r--app/views/shared/wikis/show.html.haml32
-rw-r--r--app/views/snippets/_actions.html.haml2
-rw-r--r--app/views/u2f/_authenticate.html.haml19
-rw-r--r--app/views/u2f/_register.html.haml2
-rw-r--r--app/views/users/_deletion_guidance.html.haml2
-rw-r--r--app/views/users/terms/index.html.haml6
-rw-r--r--app/workers/all_queues.yml259
-rw-r--r--app/workers/authorized_keys_worker.rb1
-rw-r--r--app/workers/authorized_project_update/user_refresh_with_low_urgency_worker.rb1
-rw-r--r--app/workers/authorized_projects_worker.rb2
-rw-r--r--app/workers/background_migration_worker.rb1
-rw-r--r--app/workers/build_finished_worker.rb1
-rw-r--r--app/workers/ci/build_report_result_worker.rb16
-rw-r--r--app/workers/cleanup_container_repository_worker.rb1
-rw-r--r--app/workers/cluster_install_app_worker.rb1
-rw-r--r--app/workers/cluster_patch_app_worker.rb1
-rw-r--r--app/workers/cluster_update_app_worker.rb1
-rw-r--r--app/workers/cluster_upgrade_app_worker.rb1
-rw-r--r--app/workers/cluster_wait_for_app_installation_worker.rb1
-rw-r--r--app/workers/cluster_wait_for_app_update_worker.rb2
-rw-r--r--app/workers/cluster_wait_for_ingress_ip_address_worker.rb1
-rw-r--r--app/workers/clusters/applications/activate_service_worker.rb2
-rw-r--r--app/workers/clusters/applications/check_prometheus_health_worker.rb30
-rw-r--r--app/workers/clusters/applications/deactivate_service_worker.rb2
-rw-r--r--app/workers/clusters/applications/uninstall_worker.rb1
-rw-r--r--app/workers/clusters/applications/wait_for_uninstall_app_worker.rb1
-rw-r--r--app/workers/concerns/application_worker.rb27
-rw-r--r--app/workers/concerns/gitlab/github_import/queue.rb11
-rw-r--r--app/workers/concerns/gitlab/jira_import/import_worker.rb2
-rw-r--r--app/workers/concerns/project_import_options.rb2
-rw-r--r--app/workers/concerns/reactive_cacheable_worker.rb1
-rw-r--r--app/workers/concerns/worker_attributes.rb22
-rw-r--r--app/workers/container_expiration_policy_worker.rb2
-rw-r--r--app/workers/create_commit_signature_worker.rb4
-rw-r--r--app/workers/create_evidence_worker.rb9
-rw-r--r--app/workers/create_pipeline_worker.rb1
-rw-r--r--app/workers/delete_stored_files_worker.rb1
-rw-r--r--app/workers/delete_user_worker.rb3
-rw-r--r--app/workers/email_receiver_worker.rb2
-rw-r--r--app/workers/expire_build_instance_artifacts_worker.rb2
-rw-r--r--app/workers/export_csv_worker.rb1
-rw-r--r--app/workers/file_hook_worker.rb1
-rw-r--r--app/workers/git_garbage_collect_worker.rb1
-rw-r--r--app/workers/gitlab/github_import/advance_stage_worker.rb1
-rw-r--r--app/workers/gitlab/import/stuck_import_job.rb82
-rw-r--r--app/workers/gitlab/import/stuck_project_import_jobs_worker.rb22
-rw-r--r--app/workers/gitlab/jira_import/import_issue_worker.rb6
-rw-r--r--app/workers/gitlab/jira_import/stage/start_import_worker.rb1
-rw-r--r--app/workers/gitlab/jira_import/stuck_jira_import_jobs_worker.rb21
-rw-r--r--app/workers/gitlab/phabricator_import/base_worker.rb2
-rw-r--r--app/workers/gitlab_shell_worker.rb1
-rw-r--r--app/workers/group_export_worker.rb1
-rw-r--r--app/workers/group_import_worker.rb9
-rw-r--r--app/workers/hashed_storage/project_migrate_worker.rb1
-rw-r--r--app/workers/hashed_storage/project_rollback_worker.rb1
-rw-r--r--app/workers/incident_management/process_prometheus_alert_worker.rb16
-rw-r--r--app/workers/irker_worker.rb117
-rw-r--r--app/workers/mail_scheduler/notification_service_worker.rb1
-rw-r--r--app/workers/merge_worker.rb1
-rw-r--r--app/workers/metrics/dashboard/prune_old_annotations_worker.rb23
-rw-r--r--app/workers/metrics/dashboard/schedule_annotations_prune_worker.rb23
-rw-r--r--app/workers/new_note_worker.rb9
-rw-r--r--app/workers/object_storage/background_move_worker.rb1
-rw-r--r--app/workers/object_storage/migrate_uploads_worker.rb1
-rw-r--r--app/workers/pages_worker.rb1
-rw-r--r--app/workers/personal_access_tokens/expiring_worker.rb4
-rw-r--r--app/workers/pipeline_notification_worker.rb5
-rw-r--r--app/workers/pipeline_process_worker.rb1
-rw-r--r--app/workers/pipeline_update_ci_ref_status_worker.rb1
-rw-r--r--app/workers/post_receive.rb1
-rw-r--r--app/workers/process_commit_worker.rb2
-rw-r--r--app/workers/project_cache_worker.rb4
-rw-r--r--app/workers/project_export_worker.rb1
-rw-r--r--app/workers/propagate_integration_worker.rb16
-rw-r--r--app/workers/rebase_worker.rb1
-rw-r--r--app/workers/remove_expired_group_links_worker.rb6
-rw-r--r--app/workers/repository_check/batch_worker.rb2
-rw-r--r--app/workers/repository_import_worker.rb7
-rw-r--r--app/workers/repository_remove_remote_worker.rb1
-rw-r--r--app/workers/repository_update_remote_mirror_worker.rb1
-rw-r--r--app/workers/stuck_import_jobs_worker.rb70
-rw-r--r--app/workers/todos_destroyer/entity_leave_worker.rb2
-rw-r--r--app/workers/update_external_pull_requests_worker.rb1
-rw-r--r--app/workers/update_merge_requests_worker.rb1
-rw-r--r--app/workers/web_hook_worker.rb1
-rw-r--r--babel.config.js13
-rwxr-xr-xbin/background_jobs_sk2
-rwxr-xr-xbin/background_jobs_sk_cluster2
-rwxr-xr-xbin/secpick26
-rwxr-xr-xbin/web21
-rw-r--r--cable/config.ru2
-rw-r--r--changelogs/unreleased/11805-support-first-name-and-last-name-attributes-in-ldap-user-sync.yml5
-rw-r--r--changelogs/unreleased/118613-spam-api-call.yml5
-rw-r--r--changelogs/unreleased/13049-design-view-allow-comment-pins-on-designs-to-be-resolvable.yml5
-rw-r--r--changelogs/unreleased/13049-graphql-resolve-discussion.yml5
-rw-r--r--changelogs/unreleased/17555-custom-text-for-badges.yml5
-rw-r--r--changelogs/unreleased/191455-add-a-button-to-assign-users-who-have-commented-on-an-issue.yml5
-rw-r--r--changelogs/unreleased/191455-add-a-button-to-quickly-assign-users-who-have-commented-on-an-issu.yml5
-rw-r--r--changelogs/unreleased/195692-too-much-x-axis-padding-on-the-environments-dashboard-content.yml5
-rw-r--r--changelogs/unreleased/196544-nodemetrics-size.yml5
-rw-r--r--changelogs/unreleased/196630-commit-tab.yml5
-rw-r--r--changelogs/unreleased/196784-add-container-expiration-policy-to-graphql-project.yml5
-rw-r--r--changelogs/unreleased/196784-graphql-mutations-for-container-expiration-policies.yml5
-rw-r--r--changelogs/unreleased/197426-error-details-timeago-tooltip.yml5
-rw-r--r--changelogs/unreleased/199245-search-api-seems-to-ignore-ref-returns-spurious-results-from-maste.yml5
-rw-r--r--changelogs/unreleased/199250-expose-release-yaml-as-steps-via-api-2.yml5
-rw-r--r--changelogs/unreleased/199732-show-more-context-to-jump-unresolved-button.yml5
-rw-r--r--changelogs/unreleased/200016-display-downstream-pipeline-errors.yml5
-rw-r--r--changelogs/unreleased/20069-ci-secrets-rake-task.yml5
-rw-r--r--changelogs/unreleased/205424-add-api-for-share-groups-with-groups.yml5
-rw-r--r--changelogs/unreleased/207257-specify-asset-types-in-releases-2.yml5
-rw-r--r--changelogs/unreleased/207257-specify-asset-types-in-releases-3.yml5
-rw-r--r--changelogs/unreleased/207257-specify-asset-types-in-releases.yml5
-rw-r--r--changelogs/unreleased/207990-secret-detection-ci-template.yml5
-rw-r--r--changelogs/unreleased/208412-featurable.yml5
-rw-r--r--changelogs/unreleased/208970-group_auth_update_to_consider_shared_groups.yml5
-rw-r--r--changelogs/unreleased/209025-design-filename-limit-migrations.yml6
-rw-r--r--changelogs/unreleased/209345-add-ds-detect-kotlin-build-file.yml5
-rw-r--r--changelogs/unreleased/21002-slack-opened-merge-request-webhook-message-is-malformed.yml5
-rw-r--r--changelogs/unreleased/210281-label-for-pipeline-schedule-active.yml5
-rw-r--r--changelogs/unreleased/210482-update-descriptions-on-the-integrations-and-webhooks-pages-at-the-.yml5
-rw-r--r--changelogs/unreleased/210550-conan-export-tgz.yml5
-rw-r--r--changelogs/unreleased/211340-change-chart-legend-format-to-tabular-format.yml5
-rw-r--r--changelogs/unreleased/211461-destroy-annotations-graphql-endpoint.yml5
-rw-r--r--changelogs/unreleased/211828-placement-of-add-designs-button-could-be-confusing-with-the-additi.yml5
-rw-r--r--changelogs/unreleased/212063-images-overflow-at-releases-list-panel.yml5
-rw-r--r--changelogs/unreleased/212848.yml5
-rw-r--r--changelogs/unreleased/212882-add-cpu-mem-charts.yml5
-rw-r--r--changelogs/unreleased/212882-add-instance-variable.yml5
-rw-r--r--changelogs/unreleased/213009-when-filtering-by-groups-icons-are-misaligned.yml6
-rw-r--r--changelogs/unreleased/213587-ide-ipad-scroll-issue.yml5
-rw-r--r--changelogs/unreleased/213597-add-in-this-group-option-to-search-dropdown-where-not-present.yml5
-rw-r--r--changelogs/unreleased/213699-remove-search-results-autocomplete.yml5
-rw-r--r--changelogs/unreleased/213824-update-red-variables-in-gitlab-scss-to-match-gitlab-ui.yml5
-rw-r--r--changelogs/unreleased/213881-alerts-list-pagination.yml5
-rw-r--r--changelogs/unreleased/213923-add-range-var.yml5
-rw-r--r--changelogs/unreleased/214102-move-the-members-section-from-settings-to-the-side-nav-for-project.yml5
-rw-r--r--changelogs/unreleased/214109-date-time-format-should-be-consistent-in-the-incident.yml5
-rw-r--r--changelogs/unreleased/214250-usage-ping-counts-for-all-search.yml5
-rw-r--r--changelogs/unreleased/214281-modify-dashboard-title.yml5
-rw-r--r--changelogs/unreleased/214370-add-timezone-setting.yml5
-rw-r--r--changelogs/unreleased/214370-extend-metrics-settings.yml5
-rw-r--r--changelogs/unreleased/214493-invaid-uri.yml5
-rw-r--r--changelogs/unreleased/214556-user-defined-alert-identification.yml5
-rw-r--r--changelogs/unreleased/214921-improve-tabbing-behavior-when-creating-new-projects.yml5
-rw-r--r--changelogs/unreleased/215497-add-custom-links-to-panel.yml5
-rw-r--r--changelogs/unreleased/215517-tab-docs-ff.yml5
-rw-r--r--changelogs/unreleased/215618_mutation_to_create_a_commit.yml5
-rw-r--r--changelogs/unreleased/215619_add_mutation_to_create_mr.yml5
-rw-r--r--changelogs/unreleased/215658-add-users-graphql.yml5
-rw-r--r--changelogs/unreleased/215658-graphql-memberships.yml5
-rw-r--r--changelogs/unreleased/215658-root-users-query.yml5
-rw-r--r--changelogs/unreleased/215668-settings-auto-fix.yml5
-rw-r--r--changelogs/unreleased/215711-improve-performance-of-search-api-advanced-users-scope.yml5
-rw-r--r--changelogs/unreleased/215946-add-gitlab-to-do-for-user-when-they-are-assigned-to-an-alert.yml5
-rw-r--r--changelogs/unreleased/216045-capture-todo-resolution.yml5
-rw-r--r--changelogs/unreleased/216088-disable-container-expiration-policy-when-invalid-regex-is-present.yml5
-rw-r--r--changelogs/unreleased/216088-regex-validation-on-container-expiration-policy.yml5
-rw-r--r--changelogs/unreleased/216097-add-application-limits-to-ci-instancevariable.yml5
-rw-r--r--changelogs/unreleased/216103-personal-access-token-pat-expiry-is-notifying-a-for-impersonation-.yml5
-rw-r--r--changelogs/unreleased/216142-resolve-alert-when-associated-issue-closes.yml5
-rw-r--r--changelogs/unreleased/216145-jira-users-import-endpoint.yml5
-rw-r--r--changelogs/unreleased/216145-project-members-graphql.yml5
-rw-r--r--changelogs/unreleased/216160-fix-label-any-with-custom-sorting.yml5
-rw-r--r--changelogs/unreleased/216174-track-mr-usage.yml5
-rw-r--r--changelogs/unreleased/216326-send-alerts-to-slack-db-settings.yml5
-rw-r--r--changelogs/unreleased/216385-add-related-dashboard-links-in-metrics-dashboard-mvc1.yml5
-rw-r--r--changelogs/unreleased/216640-insert-image-modal.yml5
-rw-r--r--changelogs/unreleased/216677-track-static-site-editor-initializations.yml5
-rw-r--r--changelogs/unreleased/216678-sse-track-merge-requests.yml5
-rw-r--r--changelogs/unreleased/216735-fix-prometheus-alerts-not-being-created.yml5
-rw-r--r--changelogs/unreleased/216749-improve-the-container-registry-ui-header-section-with-relevant-met.yml5
-rw-r--r--changelogs/unreleased/216757-add-tags-count.yml5
-rw-r--r--changelogs/unreleased/216757-include-tag-count-in-the-image-repository-list-view-of-the-contain.yml5
-rw-r--r--changelogs/unreleased/216785-use-ci-job-token-for-terraform-state-auth.yml5
-rw-r--r--changelogs/unreleased/216797-style-toastui-menus.yml5
-rw-r--r--changelogs/unreleased/216834-frontmatter-wysiwyg-removal.yml5
-rw-r--r--changelogs/unreleased/216835-instrument-db-calls.yml6
-rw-r--r--changelogs/unreleased/216865-confirm-leave-site.yml5
-rw-r--r--changelogs/unreleased/216871-snippets-author-can-t-be-blank-error.yml5
-rw-r--r--changelogs/unreleased/216880-frontend-add-sticky-issue-titles.yml5
-rw-r--r--changelogs/unreleased/216908-pass-limit-and-offset-when-searching-for-commits.yml5
-rw-r--r--changelogs/unreleased/216939-remove-async-mr-check-ff.yml5
-rw-r--r--changelogs/unreleased/217034-auto-creation-of-issues-for-alerts-off-by-default.yml5
-rw-r--r--changelogs/unreleased/217105-remove-FF-hide_token_from_runners_api.yml5
-rw-r--r--changelogs/unreleased/217168-close-open-reply-input-fields-in-the-design-view-sidebar-when-leav.yml6
-rw-r--r--changelogs/unreleased/217366-expose-jira-successfully-imported-issues-count-in-graphql.yml5
-rw-r--r--changelogs/unreleased/217566-add-warning-of-potential-data-loss-on-elastic-stack-upgrade-2.yml5
-rw-r--r--changelogs/unreleased/217570-improve-performance-for-blame-api.yml5
-rw-r--r--changelogs/unreleased/217616-fix-note-confidential.yml5
-rw-r--r--changelogs/unreleased/217666-prometheus-api-client.yml5
-rw-r--r--changelogs/unreleased/217670-alerts-count.yml5
-rw-r--r--changelogs/unreleased/217680-health-metric-instrumentation.yml5
-rw-r--r--changelogs/unreleased/217680-health-metrics-instrumentation.yml5
-rw-r--r--changelogs/unreleased/217692-design-view-highlight-focused-design-pins-follow-up.yml5
-rw-r--r--changelogs/unreleased/217736-add-related-dashboard-links-in-metrics-dashboard-mvc2.yml5
-rw-r--r--changelogs/unreleased/217743-match-commits-filter-author-button-to-spec.yml5
-rw-r--r--changelogs/unreleased/217748-pipeline-index-endpoint-performance.yml5
-rw-r--r--changelogs/unreleased/217816-add-evidence-to-releases-graphql-endpoint.yml5
-rw-r--r--changelogs/unreleased/217834-remove-FF-ci_dependency_variables.yml5
-rw-r--r--changelogs/unreleased/217934-snippet-description-files.yml5
-rw-r--r--changelogs/unreleased/217936-validate-the-size-of-the-value-for-instance-level-variables.yml5
-rw-r--r--changelogs/unreleased/217985-use-glinfinitescroll-s-default-slot-in-the-project-selector-vue-co.yml5
-rw-r--r--changelogs/unreleased/218007-fix-incomplete-kubernetes-cluster-status-list.yml5
-rw-r--r--changelogs/unreleased/218025-xff-is-a-400-error.yml5
-rw-r--r--changelogs/unreleased/218036-cannot-delete-account-on-gitlab-com.yml5
-rw-r--r--changelogs/unreleased/218045-feature-flag-remove-feature-flag-for-create-issue-from-alert-detai.yml5
-rw-r--r--changelogs/unreleased/218045-remove-create-issue-feature-flag-FE.yml5
-rw-r--r--changelogs/unreleased/218165-add-note-no-extend-ecs.yml5
-rw-r--r--changelogs/unreleased/218230-bugfix-save-wiki-page-modifications-with-certain-characters.yml5
-rw-r--r--changelogs/unreleased/218287-release-evidence-is-not-being-collected-if-release-is-created-via-.yml5
-rw-r--r--changelogs/unreleased/218340-graphql-haspreviouspage-and-hasnextpage.yml5
-rw-r--r--changelogs/unreleased/218414-refine-sast-analyzer-language-detection.yml5
-rw-r--r--changelogs/unreleased/218464-expiration-policy-defaults.yml5
-rw-r--r--changelogs/unreleased/218510-hide-copy-btn-for-rendering-error.yml5
-rw-r--r--changelogs/unreleased/218560-allow-generic-endpoint-to-receive-alerts-from-external-prometheus.yml5
-rw-r--r--changelogs/unreleased/218569-dont-show-import-from-jira-button-for-non-entitled-users.yml5
-rw-r--r--changelogs/unreleased/218582-fix-artifact-downloads-without-new-route.yml5
-rw-r--r--changelogs/unreleased/218648-remove-jira-httperror-non-actionable-exceptions.yml5
-rw-r--r--changelogs/unreleased/218707-search-criteria-for-alert-status-counts.yml5
-rw-r--r--changelogs/unreleased/218716-iterate-on-epic-tree-card-spacing.yml5
-rw-r--r--changelogs/unreleased/218733-add-manual-rollout-resource-group.yml6
-rw-r--r--changelogs/unreleased/218757-fix-polling-for-events.yml5
-rw-r--r--changelogs/unreleased/218823-wiki-base-path-relative-url-root.yml5
-rw-r--r--changelogs/unreleased/219002-remove-ghost-column.yml5
-rw-r--r--changelogs/unreleased/219022-fix-pipelines-apps-not-loading.yml5
-rw-r--r--changelogs/unreleased/219074-safe-link-validation.yml5
-rw-r--r--changelogs/unreleased/219145-comment-button-does-not-show-up-on-mr-when-comments-are-set-to-new.yml5
-rw-r--r--changelogs/unreleased/219151-follow-up-from-fallback-to-lowest-visibility-level-in-snippet-visi.yml5
-rw-r--r--changelogs/unreleased/219210-column-date-format.yml5
-rw-r--r--changelogs/unreleased/219210-stacked-column-date-format.yml5
-rw-r--r--changelogs/unreleased/219228-add-web-ide-solarized-dark-theme-support.yml5
-rw-r--r--changelogs/unreleased/219391-follow-up-from-add-type-field-to-asset-links-on-edit-release-page.yml5
-rw-r--r--changelogs/unreleased/219395-metrics-dashboard-validation-fix-500-for-empty-.yml6
-rw-r--r--changelogs/unreleased/219582-fix-ambiguous_string_concat_on_cleanup_projects_with_missing_names.yml5
-rw-r--r--changelogs/unreleased/219658-add-route-to-ghost-lost-and-found-group.yml5
-rw-r--r--changelogs/unreleased/220014-default-for-SAST_EXCLUDED_PATHS-DS_EXCLUDED_PATHS.yml5
-rw-r--r--changelogs/unreleased/220051-duplicate-issues-created-when-importing-from-csv.yml5
-rw-r--r--changelogs/unreleased/220058.yml5
-rw-r--r--changelogs/unreleased/220144-substitute-variables-in-alerts.yml5
-rw-r--r--changelogs/unreleased/220148-fix-vsa-issue-summary-title.yml5
-rw-r--r--changelogs/unreleased/220185-mask-key-comments-when-exposing-ssh-deploy-keys-via-the-api.yml5
-rw-r--r--changelogs/unreleased/220192-fix-pagination-pd.yml5
-rw-r--r--changelogs/unreleased/220195-display-epics-on-swimlanes.yml5
-rw-r--r--changelogs/unreleased/220209-optimize-container-repository-query.yml5
-rw-r--r--changelogs/unreleased/220300-do-not-create-duplicate-alert-issues.yml5
-rw-r--r--changelogs/unreleased/220415-feature-flag-enable-alert-slack-notifications.yml5
-rw-r--r--changelogs/unreleased/220477-harden-ci-pipelines-usage-data-queries.yml5
-rw-r--r--changelogs/unreleased/220616-group-code-icons-in-toolbar.yml5
-rw-r--r--changelogs/unreleased/220954-replace-fa-file-image-o-with-gitlab-media-icon.yml5
-rw-r--r--changelogs/unreleased/221052-fix-custom-slashcommand-receiving-500.yml5
-rw-r--r--changelogs/unreleased/221136-docs-product-feedback-slack-notifications-service-doc-outdated.yml5
-rw-r--r--changelogs/unreleased/221174-graphql-pagination-bug.yml5
-rw-r--r--changelogs/unreleased/22691-externalize-i18n-strings-from---app-views-shared-milestones-_form_d.yml5
-rw-r--r--changelogs/unreleased/22691-externalize-i18n-strings-from---app-views-shared-milestones-_sideba.yml5
-rw-r--r--changelogs/unreleased/22691-externelize-i18n-strings-from---app-views-shared-_promo-html-haml.yml5
-rw-r--r--changelogs/unreleased/22822-ide-paste-images.yml5
-rw-r--r--changelogs/unreleased/22834-ff-merge-msg.yml5
-rw-r--r--changelogs/unreleased/22868-fix-remove-button-alignment.yml5
-rw-r--r--changelogs/unreleased/23352-editorconfig.yml5
-rw-r--r--changelogs/unreleased/25486-batch-suggestions.yml5
-rw-r--r--changelogs/unreleased/25830-find-file-button.yml5
-rw-r--r--changelogs/unreleased/28154-move-controllers-outside-ee.yml5
-rw-r--r--changelogs/unreleased/28589-emoji-status-popover-doesn-t-show-emoji-when-it-s-in-the-message.yml5
-rw-r--r--changelogs/unreleased/30707-show-outdated-status-of-suggestions.yml5
-rw-r--r--changelogs/unreleased/30853-footer-system-message-covers-horizontal-scrollbar.yml5
-rw-r--r--changelogs/unreleased/32230-reorder-diffs-compare-versions-dropdowns.yml5
-rw-r--r--changelogs/unreleased/33040-doc-cicd-yaml-clarify-rules-if-when-behaviour.yml5
-rw-r--r--changelogs/unreleased/33185-add-missing-install-instruction.yml5
-rw-r--r--changelogs/unreleased/33743-graph-code-coverage-changes-over-time-for-a-project.yml5
-rw-r--r--changelogs/unreleased/37412-update-error-tracking-list-message.yml5
-rw-r--r--changelogs/unreleased/39545-cleanup-dynamic-milestone-pages.yml5
-rw-r--r--changelogs/unreleased/500-metrics-creation.yml5
-rw-r--r--changelogs/unreleased/Fix-spelling-error.yml5
-rw-r--r--changelogs/unreleased/Remove-addAssignee-logic-from-issues-model.yml5
-rw-r--r--changelogs/unreleased/Remove-addLabel-function-logic-from-issue-models.yml5
-rw-r--r--changelogs/unreleased/Remove-addMilestone-logic-from-issue-models.yml5
-rw-r--r--changelogs/unreleased/Remove-clickable-styling-from-loading-row.yml5
-rw-r--r--changelogs/unreleased/Remove-destroy-function-logic-from-list-model.yml5
-rw-r--r--changelogs/unreleased/Remove-findAssignee-logic-from-issues-model.yml5
-rw-r--r--changelogs/unreleased/Remove-findLabel-logic-from-issues-model.yml5
-rw-r--r--changelogs/unreleased/Remove-findissue-logic-from-list-model.yml5
-rw-r--r--changelogs/unreleased/Remove-moveIssue-logic-from-list-model.yml5
-rw-r--r--changelogs/unreleased/Remove-newIssue-logic-from-list-model.yml5
-rw-r--r--changelogs/unreleased/Remove-nextPage-function-logic-from-listmodel.yml5
-rw-r--r--changelogs/unreleased/Remove-removeAllAssignees-logic-from-issue-model.yml5
-rw-r--r--changelogs/unreleased/Remove-removeAssignee-logic-from-issue-model.yml5
-rw-r--r--changelogs/unreleased/Remove-removeIssue-function-logic-from-list-model.yml5
-rw-r--r--changelogs/unreleased/Remove-removeLabel-logic-from-issues-model.yml5
-rw-r--r--changelogs/unreleased/Remove-removeLabels-logic-from-issues-model.yml5
-rw-r--r--changelogs/unreleased/Remove-removeMilestone-logic-from-issue-model.yml5
-rw-r--r--changelogs/unreleased/Remove-removeMultipleIssues-logic-from-list-model.yml5
-rw-r--r--changelogs/unreleased/Remove-setFetchingState-logic-from-issue-model.yml5
-rw-r--r--changelogs/unreleased/Remove-setLoadingState-logic-From-issue-model.yml5
-rw-r--r--changelogs/unreleased/Remove-update-fuction-logic-from-list-model.yml5
-rw-r--r--changelogs/unreleased/Remove-updateData-logic-from-issue-model.yml5
-rw-r--r--changelogs/unreleased/aalakkad-fix-time-tracking-help-link.yml5
-rw-r--r--changelogs/unreleased/ab-alert-usage-ping.yml5
-rw-r--r--changelogs/unreleased/ab-cleanup-migrations.yml5
-rw-r--r--changelogs/unreleased/ab-monitor-demo-environments-2.yml5
-rw-r--r--changelogs/unreleased/ab-services-partial-indexes.yml5
-rw-r--r--changelogs/unreleased/add-api-endpoint-for-resource-milestone-events-pd.yml5
-rw-r--r--changelogs/unreleased/add-doc-custom-validators.yml5
-rw-r--r--changelogs/unreleased/add-experience-level-to-user-preferences.yml5
-rw-r--r--changelogs/unreleased/add-global-plans.yml5
-rw-r--r--changelogs/unreleased/add-group-runners-finder.yml5
-rw-r--r--changelogs/unreleased/add-tags-to-queue-attributes.yml5
-rw-r--r--changelogs/unreleased/add_build_reference.yml5
-rw-r--r--changelogs/unreleased/ajk-GQL-user-mrs.yml5
-rw-r--r--changelogs/unreleased/ajk-design-ref-filter.yml5
-rw-r--r--changelogs/unreleased/ajk-gql-add-mr-author.yml5
-rw-r--r--changelogs/unreleased/ajk-gql-labels.yml5
-rw-r--r--changelogs/unreleased/ajk-gql-lookahead.yml5
-rw-r--r--changelogs/unreleased/ajk-gql-mr-resolvers-split.yml5
-rw-r--r--changelogs/unreleased/ajk-safe-wiki-event-url.yml5
-rw-r--r--changelogs/unreleased/ak-update-google-auth.yml5
-rw-r--r--changelogs/unreleased/al-214420-pass-hard-delete-on-snippets-destroy.yml5
-rw-r--r--changelogs/unreleased/al-215200-snippets-by-type-usage-counter.yml5
-rw-r--r--changelogs/unreleased/al-217784-add-blobs-field-to-snippets-in-graphql.yml5
-rw-r--r--changelogs/unreleased/alert-assignee-dropdown.yml5
-rw-r--r--changelogs/unreleased/alert-assignee-list-view.yml5
-rw-r--r--changelogs/unreleased/alert-management-mobile-alignment.yml5
-rw-r--r--changelogs/unreleased/alert-system-notes-tool-tip.yml5
-rw-r--r--changelogs/unreleased/alert-system-notes.yml5
-rw-r--r--changelogs/unreleased/alert-table-classes-hotfix.yml5
-rw-r--r--changelogs/unreleased/allow_skipped.yml5
-rw-r--r--changelogs/unreleased/andr3-218471-code-review-diff-overlaps-sidebar.yml5
-rw-r--r--changelogs/unreleased/asciidoc-alignment-roles.yml5
-rw-r--r--changelogs/unreleased/assign-alerts-sidebar-base.yml5
-rw-r--r--changelogs/unreleased/assign-alerts-sidebar-container-fix.yml5
-rw-r--r--changelogs/unreleased/autodevops-secrets.yml5
-rw-r--r--changelogs/unreleased/aws-guidance.yml5
-rw-r--r--changelogs/unreleased/browse-locked-artifact.yml5
-rw-r--r--changelogs/unreleased/bump_ci_auto_deploy_0_16.yml5
-rw-r--r--changelogs/unreleased/bump_cluster_applications_version.yml5
-rw-r--r--changelogs/unreleased/cablett-email-link.yml5
-rw-r--r--changelogs/unreleased/cablett-merge-request-merged-email-ref.yml5
-rw-r--r--changelogs/unreleased/calebw-update-stuck-runner-message.yml5
-rw-r--r--changelogs/unreleased/change_from_vendor_specific_to_gitlab.yml5
-rw-r--r--changelogs/unreleased/chore-bump-omniauth_openid_connect.yml5
-rw-r--r--changelogs/unreleased/chore-styles-removal.yml5
-rw-r--r--changelogs/unreleased/ci-rust-cargo-test-workspace-option.yml5
-rw-r--r--changelogs/unreleased/clean-up-install-from-source-gitlab-shell.yml5
-rw-r--r--changelogs/unreleased/cngo-add-link-text-to-collapsed-left-sidebar.yml5
-rw-r--r--changelogs/unreleased/cngo-improve-header-accessibility.yml5
-rw-r--r--changelogs/unreleased/cngo-make-markdown-textarea-links-tab-accessible.yml5
-rw-r--r--changelogs/unreleased/create-branch-url.yml5
-rw-r--r--changelogs/unreleased/create-ops-ff-issues-table.yml5
-rw-r--r--changelogs/unreleased/curd-auto-merge-in-transaction.yml5
-rw-r--r--changelogs/unreleased/data-endpoint-for-dag-visualization-2.yml5
-rw-r--r--changelogs/unreleased/dblessing-new-sign-in-email-beautification.yml5
-rw-r--r--changelogs/unreleased/dennis-project-templates-add-gitbook-logo.yml5
-rw-r--r--changelogs/unreleased/dennis-project-templates-add-gomicro-logo.yml5
-rw-r--r--changelogs/unreleased/dennis-project-templates-add-hexo-logo.yml5
-rw-r--r--changelogs/unreleased/dennis-project-templates-add-hugo-logo.yml5
-rw-r--r--changelogs/unreleased/dennis-project-templates-add-jekyll-logo.yml5
-rw-r--r--changelogs/unreleased/dennis-update-webhooks-page-from-whitelist-to-allowlist.yml5
-rw-r--r--changelogs/unreleased/design-view-scrolling-issue-bug.yml5
-rw-r--r--changelogs/unreleased/docs-auto-build-cnb-custom-builder.yml5
-rw-r--r--changelogs/unreleased/docs-firefox-u2f-api.yml5
-rw-r--r--changelogs/unreleased/docs-fj-update-web-ide-terminal-doc-core.yml5
-rw-r--r--changelogs/unreleased/docs-saml-sso-from-core-at-self-hosted.yml5
-rw-r--r--changelogs/unreleased/docs-u2f-version-history.yml5
-rw-r--r--changelogs/unreleased/downloadable_reports.yml5
-rw-r--r--changelogs/unreleased/dz-redirect-unscoped-pipelines-routes.yml5
-rw-r--r--changelogs/unreleased/ee-app-services-1.yml5
-rw-r--r--changelogs/unreleased/emilyring-cluster-list-refactor-provider-icon.yml5
-rw-r--r--changelogs/unreleased/emilyring-remove-tf-plan-name.yml5
-rw-r--r--changelogs/unreleased/emilyring-tf-widget-multiple.yml5
-rw-r--r--changelogs/unreleased/enable-atomic-processing-by-default.yml5
-rw-r--r--changelogs/unreleased/exclude-server-fields-from-exceptions-log.yml5
-rw-r--r--changelogs/unreleased/experimentation-cookie-domain.yml5
-rw-r--r--changelogs/unreleased/feat-admin-pages-show-custom-attributes.yml5
-rw-r--r--changelogs/unreleased/feature-api-add-bridge-api-endpoint.yml5
-rw-r--r--changelogs/unreleased/feature-bump-cluster-applications-to-0-16-0.yml5
-rw-r--r--changelogs/unreleased/feature-gb-artifacts-exclude-feature-flag.yml5
-rw-r--r--changelogs/unreleased/feature-show-memory-cpu-on-cluster-list.yml5
-rw-r--r--changelogs/unreleased/filter-from-url-query-params-pipeline.yml5
-rw-r--r--changelogs/unreleased/filter-pipelines-by-status.yml5
-rw-r--r--changelogs/unreleased/filter-pipelines-by-tag-name.yml5
-rw-r--r--changelogs/unreleased/fix-atomic-processing-lock-version.yml5
-rw-r--r--changelogs/unreleased/fix-design-notes-filename-duplication.yml5
-rw-r--r--changelogs/unreleased/fix-design-todos-filename-duplication.yml5
-rw-r--r--changelogs/unreleased/fix-ecs-detached-branch-pipeline.yml5
-rw-r--r--changelogs/unreleased/fix-group-transfer-to-subgroup.yml5
-rw-r--r--changelogs/unreleased/fix-invalid-error-tracking-method.yml5
-rw-r--r--changelogs/unreleased/fix-max_import_size.yml5
-rw-r--r--changelogs/unreleased/fix-omniauth-buttons-js.yml5
-rw-r--r--changelogs/unreleased/fix-pagination-link.yml5
-rw-r--r--changelogs/unreleased/fix-runner-hearbeat.yml5
-rw-r--r--changelogs/unreleased/fix-selecting-status-emoji-twice.yml5
-rw-r--r--changelogs/unreleased/fix-typo-issues-limit-settings-template.yml5
-rw-r--r--changelogs/unreleased/fix-vertically-center-action-icon.yml5
-rw-r--r--changelogs/unreleased/fix_back_button_when_switching_mr_tabs.yml5
-rw-r--r--changelogs/unreleased/fix_default_path_when_creating_project_from_group_template.yml5
-rw-r--r--changelogs/unreleased/fix_deleting_user_psql_error_on_events_table_v2.yml5
-rw-r--r--changelogs/unreleased/fix_mr_note_label_urls.yml5
-rw-r--r--changelogs/unreleased/fix_nil_class_for_bytesize_error.yml5
-rw-r--r--changelogs/unreleased/fix_preconnect_typo.yml5
-rw-r--r--changelogs/unreleased/fj-add-allowed-actions-to-snippet-input-action.yml5
-rw-r--r--changelogs/unreleased/fj-add-snippet-file-input-action.yml5
-rw-r--r--changelogs/unreleased/fj-add-snippet-files-param-to-snippet-create-service.yml5
-rw-r--r--changelogs/unreleased/fj-add-snippet-files-param-to-snippet-update-service.yml5
-rw-r--r--changelogs/unreleased/fj-add-validations-snippet-input-action.yml5
-rw-r--r--changelogs/unreleased/fj-backfill-imported-snippet-repositories.yml5
-rw-r--r--changelogs/unreleased/fj-bump-lfs-token-default-expiration-time.yml5
-rw-r--r--changelogs/unreleased/fj-change-snippet-author-nullable-graphql-type.yml5
-rw-r--r--changelogs/unreleased/fj-fix-import-from-different-types-exports.yml5
-rw-r--r--changelogs/unreleased/fj-fix-single-param-update.yml5
-rw-r--r--changelogs/unreleased/fj-fix-snippet-create-mutation-non-activerecord-errors.yml5
-rw-r--r--changelogs/unreleased/fj-fix-snippet-import-from-database.yml5
-rw-r--r--changelogs/unreleased/fj-fix-snippet-import-when-fails.yml5
-rw-r--r--changelogs/unreleased/followup-leakyconst-master-check.yml5
-rw-r--r--changelogs/unreleased/fox-comment-icons-commits.yml5
-rw-r--r--changelogs/unreleased/georgekoltsov-import-export-tmp-folder-cleanup.yml5
-rw-r--r--changelogs/unreleased/gitaly-version-v13.1.0-rc1.yml5
-rw-r--r--changelogs/unreleased/gitlab-ui-badge-integration-2.yml5
-rw-r--r--changelogs/unreleased/gl-cluster-applications-json.yml6
-rw-r--r--changelogs/unreleased/id-code-nav-500-error.yml5
-rw-r--r--changelogs/unreleased/id-code-navigation-enable-feature.yml5
-rw-r--r--changelogs/unreleased/improve_issue_labels_api.yml5
-rw-r--r--changelogs/unreleased/improve_storage_move_workflow.yml5
-rw-r--r--changelogs/unreleased/increase-events-count-for-prometheus-alerts.yml5
-rw-r--r--changelogs/unreleased/instance-variables-ui.yml5
-rw-r--r--changelogs/unreleased/instance_auto_devops_enabled_usage_ping.yml5
-rw-r--r--changelogs/unreleased/issue-bulk-update.yml5
-rw-r--r--changelogs/unreleased/jc-pick-weighted-repository.yml5
-rw-r--r--changelogs/unreleased/jc-show-all-storages.yml5
-rw-r--r--changelogs/unreleased/jc-ui-repository-storages-weighted.yml5
-rw-r--r--changelogs/unreleased/jc-weighted-repository-storages.yml5
-rw-r--r--changelogs/unreleased/jcunha-bump-deploy-image-to-0-17-0.yml6
-rw-r--r--changelogs/unreleased/jdb-mutliline-comment-fe.yml5
-rw-r--r--changelogs/unreleased/jej-api-for-root-groups.yml5
-rw-r--r--changelogs/unreleased/jh-drop_jid_null_constraint.yml5
-rw-r--r--changelogs/unreleased/jh-group_import_status.yml5
-rw-r--r--changelogs/unreleased/jh-group_import_ui_frontend.yml5
-rw-r--r--changelogs/unreleased/jh-rate_limit_project_export.yml5
-rw-r--r--changelogs/unreleased/jira-projects-api-wrapper.yml5
-rw-r--r--changelogs/unreleased/jivanvl-add-snowplow-logs.yml5
-rw-r--r--changelogs/unreleased/jivanvl-make-chart-panels-focusable-keyboard.yml5
-rw-r--r--changelogs/unreleased/kborges-github-import-rake-add-rate-limit-doc.yml5
-rw-r--r--changelogs/unreleased/leaky-constant-fix-11.yml5
-rw-r--r--changelogs/unreleased/leaky-constant-fix-14.yml5
-rw-r--r--changelogs/unreleased/leaky-constant-fix-22.yml5
-rw-r--r--changelogs/unreleased/leaky-constant-fix-28.yml5
-rw-r--r--changelogs/unreleased/leaky-constant-fix-29.yml5
-rw-r--r--changelogs/unreleased/leaky-constant-fix-3.yml5
-rw-r--r--changelogs/unreleased/leaky-constant-fix-30.yml5
-rw-r--r--changelogs/unreleased/leaky-constant-fix-32.yml5
-rw-r--r--changelogs/unreleased/leaky-constant-fix-33.yml5
-rw-r--r--changelogs/unreleased/leaky-constant-fix-34.yml5
-rw-r--r--changelogs/unreleased/leaky-constant-fix-36.yml5
-rw-r--r--changelogs/unreleased/leaky-constant-fix-37.yml5
-rw-r--r--changelogs/unreleased/leaky-constant-fix-38.yml5
-rw-r--r--changelogs/unreleased/leaky-constant-fix-39.yml5
-rw-r--r--changelogs/unreleased/leaky-constant-fix-5.yml5
-rw-r--r--changelogs/unreleased/leaky-constant-fix-9.yml5
-rw-r--r--changelogs/unreleased/lm-change-sorting.yml5
-rw-r--r--changelogs/unreleased/lm-hover-state-sort.yml5
-rw-r--r--changelogs/unreleased/lm-sorting-list.yml5
-rw-r--r--changelogs/unreleased/long-path-mr-bug.yml5
-rw-r--r--changelogs/unreleased/markdown-toolbar-list-style.yml5
-rw-r--r--changelogs/unreleased/mattkasa-207510-terraform-state-usage-ping.yml5
-rw-r--r--changelogs/unreleased/mattkasa-207532-add-usage-ping-for-terraform-reports.yml5
-rw-r--r--changelogs/unreleased/mg-fix-katex-fonts.yml5
-rw-r--r--changelogs/unreleased/mo-add-build-report-result.yml5
-rw-r--r--changelogs/unreleased/move_migration_to_post_deployment.yml5
-rw-r--r--changelogs/unreleased/mwaw-210289-add-metrics-dashboard-validation-to-grapql.yml5
-rw-r--r--changelogs/unreleased/mwaw-210289-metrics-dashboard-file-validation-mvc-1.yml5
-rw-r--r--changelogs/unreleased/mwaw-211433-metrics-dashboard-annotations-reaper-job-database-layer.yml6
-rw-r--r--changelogs/unreleased/mwaw-211433-metrics-dashboard-annotations-reaper-job-worker.yml5
-rw-r--r--changelogs/unreleased/nfriend-enable-release_asset_link_type-f.yml5
-rw-r--r--changelogs/unreleased/nfriend-fix-release-button-alignment.yml5
-rw-r--r--changelogs/unreleased/nicolasdular-broadcast-notification-close-btn.yml5
-rw-r--r--changelogs/unreleased/notes-ee-feature.yml5
-rw-r--r--changelogs/unreleased/ntepluhina-fix-note-scrolling.yml5
-rw-r--r--changelogs/unreleased/optimize-milestones-page.yml5
-rw-r--r--changelogs/unreleased/osw-add-redis-metrics-to-sidekiq-job-run.yml5
-rw-r--r--changelogs/unreleased/osw-add-redis-metrics-to-web-requests.yml5
-rw-r--r--changelogs/unreleased/osw-pass-state-id-instead-state-to-background-migration.yml5
-rw-r--r--changelogs/unreleased/osw-separate-redis-logs.yml6
-rw-r--r--changelogs/unreleased/perf-use-build-stubbed.yml5
-rw-r--r--changelogs/unreleased/ph-28154-moveFrontendBatchCommentsFiles.yml5
-rw-r--r--changelogs/unreleased/pl-alert-management-fix-multiple-issue-creation.yml5
-rw-r--r--changelogs/unreleased/psi-dark-theme.yml5
-rw-r--r--changelogs/unreleased/rails-logger-cop-1.yml5
-rw-r--r--changelogs/unreleased/rails-logger-cop-10.yml5
-rw-r--r--changelogs/unreleased/rails-logger-cop-11.yml5
-rw-r--r--changelogs/unreleased/rails-logger-cop-12.yml5
-rw-r--r--changelogs/unreleased/rails-logger-cop-13.yml5
-rw-r--r--changelogs/unreleased/rails-logger-cop-14.yml5
-rw-r--r--changelogs/unreleased/rails-logger-cop-15.yml5
-rw-r--r--changelogs/unreleased/rails-logger-cop-16.yml5
-rw-r--r--changelogs/unreleased/rails-logger-cop-17.yml5
-rw-r--r--changelogs/unreleased/rails-logger-cop-18.yml5
-rw-r--r--changelogs/unreleased/rails-logger-cop-19.yml5
-rw-r--r--changelogs/unreleased/rails-logger-cop-2.yml5
-rw-r--r--changelogs/unreleased/rails-logger-cop-20.yml5
-rw-r--r--changelogs/unreleased/rails-logger-cop-21.yml5
-rw-r--r--changelogs/unreleased/rails-logger-cop-22.yml5
-rw-r--r--changelogs/unreleased/rails-logger-cop-23.yml5
-rw-r--r--changelogs/unreleased/rails-logger-cop-3.yml5
-rw-r--r--changelogs/unreleased/rails-logger-cop-4.yml5
-rw-r--r--changelogs/unreleased/rails-logger-cop-5.yml5
-rw-r--r--changelogs/unreleased/rails-logger-cop-6.yml5
-rw-r--r--changelogs/unreleased/rails-logger-cop-7.yml5
-rw-r--r--changelogs/unreleased/rails-logger-cop-8.yml5
-rw-r--r--changelogs/unreleased/rails-logger-cop-9.yml5
-rw-r--r--changelogs/unreleased/rc-add_dashboard_timezone.yml5
-rw-r--r--changelogs/unreleased/rearchitect-fixed-pipelines-notification-v2.yml5
-rw-r--r--changelogs/unreleased/reduce-repo-size.yml5
-rw-r--r--changelogs/unreleased/refactor-stuck-imports-jobs-worker.yml5
-rw-r--r--changelogs/unreleased/remove-a11y-widget-ff.yml5
-rw-r--r--changelogs/unreleased/remove-redundant-modsecurity-indexes.yml5
-rw-r--r--changelogs/unreleased/remove_scoped_approval_rules_feature_flag.yml5
-rw-r--r--changelogs/unreleased/replace-slot-for-vue-3-migration.yml5
-rw-r--r--changelogs/unreleased/reword-addMultipleToDiscussionWarning.yml5
-rw-r--r--changelogs/unreleased/rf-brakeman-to-core.yml5
-rw-r--r--changelogs/unreleased/rp-use-gitlab-yaml-loader-blob-viewer.yml5
-rw-r--r--changelogs/unreleased/rspec-rails-fast-failure-template.yml5
-rw-r--r--changelogs/unreleased/sav-1566-pat-for-projects-db-changes.yml5
-rw-r--r--changelogs/unreleased/schedule_storage_move_api.yml5
-rw-r--r--changelogs/unreleased/services-usage-1.yml5
-rw-r--r--changelogs/unreleased/services-usage-2.yml5
-rw-r--r--changelogs/unreleased/sh-add-partial-index-locked-merge-requests.yml5
-rw-r--r--changelogs/unreleased/sh-avoid-extra-route-reload.yml5
-rw-r--r--changelogs/unreleased/sh-extend-remember-me-token.yml5
-rw-r--r--changelogs/unreleased/sh-fix-auto-merge-after-resolve-discussions.yml5
-rw-r--r--changelogs/unreleased/sh-fix-delete-blob-failure.yml5
-rw-r--r--changelogs/unreleased/sh-fix-issue-219991.yml5
-rw-r--r--changelogs/unreleased/sh-update-workhorse-8-34-0.yml5
-rw-r--r--changelogs/unreleased/sh-workhorse-direct-access-upload.yml5
-rw-r--r--changelogs/unreleased/show-redis-instance-in-performance-bar.yml5
-rw-r--r--changelogs/unreleased/show_build_status_in_branch_list.yml5
-rw-r--r--changelogs/unreleased/show_estimate_on_issues_list.yml5
-rw-r--r--changelogs/unreleased/sidekiq-arguments-logging-tokens.yml5
-rw-r--r--changelogs/unreleased/skip-importing-failed-jira-issue-instead-of-entrire-batch.yml5
-rw-r--r--changelogs/unreleased/support-grafana-links-in-metrics-dashboard.yml5
-rw-r--r--changelogs/unreleased/switch-diff-view-fix.yml6
-rw-r--r--changelogs/unreleased/sy-publish-command.yml6
-rw-r--r--changelogs/unreleased/sy-publish-status-ui-fe.yml5
-rw-r--r--changelogs/unreleased/templates-current-folder-fix.yml5
-rw-r--r--changelogs/unreleased/tidy_put_projects_issues_spec.yml5
-rw-r--r--changelogs/unreleased/tr-avoid-alert-refetch.yml5
-rw-r--r--changelogs/unreleased/tr-fix-broken-incident-link.yml5
-rw-r--r--changelogs/unreleased/tr-reword-alert-service.yml5
-rw-r--r--changelogs/unreleased/track-pod-logs-refresh-action.yml5
-rw-r--r--changelogs/unreleased/update-deprecated-slot-syntax-in---app-assets-javascripts-pages-admin-pro.yml5
-rw-r--r--changelogs/unreleased/update-deprecated-slot-syntax-in---app-assets-javascripts-pages-projects-.yml5
-rw-r--r--changelogs/unreleased/update-deprecated-slot-syntax-in---clusters-applications-vue.yml5
-rw-r--r--changelogs/unreleased/update-deprecated-slot-syntax-in---javascripts-environments_app-vue.yml5
-rw-r--r--changelogs/unreleased/update-deprecated-slot-syntax-in-app-assets-javascripts-reports-component.yml5
-rw-r--r--changelogs/unreleased/update-gitlab-runner-helm-chart-to-0-17-0.yml5
-rw-r--r--changelogs/unreleased/update-gitlab-runner-helm-chart-to-0-17-1.yml5
-rw-r--r--changelogs/unreleased/update-index-artifacts-expire.yml6
-rw-r--r--changelogs/unreleased/update-validates-hostname-gem.yml5
-rw-r--r--changelogs/unreleased/update-workhorse-version-master.yml5
-rw-r--r--changelogs/unreleased/upgrade-renamed-diff-show-full-diff-for-renamed-files.yml5
-rw-r--r--changelogs/unreleased/vs-fix-account-delete-plural-msg.yml5
-rw-r--r--changelogs/unreleased/xanf-use-new-import-ui-templates.yml5
-rw-r--r--config/application.rb12
-rw-r--r--config/dependency_decisions.yml6
-rw-r--r--config/feature_categories.yml4
-rw-r--r--config/gitlab.yml.example12
-rw-r--r--config/initializers/01_secret_token.rb2
-rw-r--r--config/initializers/1_settings.rb24
-rw-r--r--config/initializers/7_prometheus_metrics.rb11
-rw-r--r--config/initializers/8_devise.rb7
-rw-r--r--config/initializers/action_cable.rb10
-rw-r--r--config/initializers/actionpack_generate_old_csrf_token.rb33
-rw-r--r--config/initializers/bullet.rb11
-rw-r--r--config/initializers/database_config.rb2
-rw-r--r--config/initializers/doorkeeper.rb5
-rw-r--r--config/initializers/fill_shards.rb5
-rw-r--r--config/initializers/google_api_client.rb19
-rw-r--r--config/initializers/grape_validators.rb1
-rw-r--r--config/initializers/kaminari_active_record_relation_methods_with_limit.rb8
-rw-r--r--config/initializers/lograge.rb6
-rw-r--r--config/initializers/peek.rb2
-rw-r--r--config/initializers/rack_attack.rb (renamed from config/initializers/rack_attack_new.rb)0
-rw-r--r--config/initializers/zz_metrics.rb2
-rw-r--r--config/locales/doorkeeper.en.yml2
-rw-r--r--config/locales/en.yml1
-rw-r--r--config/prometheus/self_monitoring_default.yml30
-rw-r--r--config/pseudonymizer.yml1
-rw-r--r--config/routes.rb13
-rw-r--r--config/routes/dashboard.rb8
-rw-r--r--config/routes/group.rb3
-rw-r--r--config/routes/import.rb8
-rw-r--r--config/routes/merge_requests.rb9
-rw-r--r--config/routes/project.rb38
-rw-r--r--config/settings.rb6
-rw-r--r--config/sidekiq_queues.yml10
-rw-r--r--config/webpack.config.js23
-rw-r--r--config/webpack.vendor.config.js20
-rw-r--r--danger/bundle_size/Dangerfile38
-rw-r--r--danger/changelog/Dangerfile21
-rw-r--r--danger/commit_messages/Dangerfile16
-rw-r--r--danger/roulette/Dangerfile76
-rw-r--r--danger/specs/Dangerfile27
-rw-r--r--danger/telemetry/Dangerfile15
-rw-r--r--db/fixtures/development/10_merge_requests.rb2
-rw-r--r--db/fixtures/development/17_cycle_analytics.rb4
-rw-r--r--db/gitlab_structure.sql4
-rw-r--r--db/migrate/20171230123729_init_schema.rb1859
-rw-r--r--db/migrate/20180101160629_create_prometheus_metrics.rb20
-rw-r--r--db/migrate/20180101160630_change_project_id_for_prometheus_metrics.rb11
-rw-r--r--db/migrate/20180102220145_add_pages_https_only_to_projects.rb9
-rw-r--r--db/migrate/20180103123548_add_confidential_note_events_to_services.rb16
-rw-r--r--db/migrate/20180105212544_add_commits_count_to_merge_request_diff.rb29
-rw-r--r--db/migrate/20180109183319_change_default_value_for_pages_https_only.rb13
-rw-r--r--db/migrate/20180113220114_rework_redirect_routes_indexes.rb60
-rw-r--r--db/migrate/20180115094742_add_default_project_creation_setting.rb19
-rw-r--r--db/migrate/20180115113902_add_project_creation_level_to_groups.rb17
-rw-r--r--db/migrate/20180115201419_add_index_updated_at_to_issues.rb15
-rw-r--r--db/migrate/20180116193854_create_lfs_file_locks.rb30
-rw-r--r--db/migrate/20180119135717_add_uploader_index_to_uploads.rb20
-rw-r--r--db/migrate/20180119160751_optimize_ci_job_artifacts.rb23
-rw-r--r--db/migrate/20180122162010_add_auto_devops_domain_to_application_settings.rb15
-rw-r--r--db/migrate/20180125214301_create_user_callouts.rb16
-rw-r--r--db/migrate/20180129193323_add_uploads_builder_context.rb16
-rw-r--r--db/migrate/20180201102129_add_unique_constraint_to_trending_projects_project_id.rb19
-rw-r--r--db/migrate/20180201110056_add_foreign_keys_to_todos.rb38
-rw-r--r--db/migrate/20180201145907_migrate_remaining_issues_closed_at.rb56
-rw-r--r--db/migrate/20180206200543_reset_events_primary_key_sequence.rb21
-rw-r--r--db/migrate/20180208183958_schedule_populate_untracked_uploads_if_needed.rb47
-rw-r--r--db/migrate/20180209115333_create_chatops_tables.rb26
-rw-r--r--db/migrate/20180209165249_add_closed_by_to_issues.rb20
-rw-r--r--db/migrate/20180212030105_add_external_ip_to_clusters_applications_ingress.rb11
-rw-r--r--db/migrate/20180213131630_add_partial_index_to_projects_for_index_only_scans.rb21
-rw-r--r--db/migrate/20180214093516_create_badges.rb21
-rw-r--r--db/migrate/20180214155405_create_clusters_applications_runners.rb32
-rw-r--r--db/migrate/20180215181245_users_name_lower_index.rb21
-rw-r--r--db/migrate/20180216120000_add_pages_domain_verification.rb8
-rw-r--r--db/migrate/20180216120010_add_pages_domain_verified_at_index.rb15
-rw-r--r--db/migrate/20180216120020_allow_domain_verification_to_be_disabled.rb7
-rw-r--r--db/migrate/20180216120030_add_pages_domain_enabled_until.rb7
-rw-r--r--db/migrate/20180216120040_add_pages_domain_enabled_until_index.rb17
-rw-r--r--db/migrate/20180216120050_pages_domains_verification_grace_period.rb26
-rw-r--r--db/migrate/20180219153455_add_maximum_timeout_to_ci_runners.rb9
-rw-r--r--db/migrate/20180221151752_add_allow_maintainer_to_push_to_merge_requests.rb18
-rw-r--r--db/migrate/20180222043024_add_ip_address_to_runner.rb9
-rw-r--r--db/migrate/20180223120443_create_user_interacted_projects_table.rb20
-rw-r--r--db/migrate/20180223144945_add_allow_local_requests_from_hooks_and_services_to_application_settings.rb18
-rw-r--r--db/migrate/20180226050030_add_checksum_to_ci_job_artifacts.rb7
-rw-r--r--db/migrate/20180227182112_add_group_id_to_boards_ce.rb36
-rw-r--r--db/migrate/20180228172924_add_include_private_contributions_to_users.rb7
-rw-r--r--db/migrate/20180301010859_create_ci_builds_metadata_table.rb20
-rw-r--r--db/migrate/20180302152117_ensure_foreign_keys_on_clusters_applications.rb51
-rw-r--r--db/migrate/20180305095250_create_internal_ids_table.rb15
-rw-r--r--db/migrate/20180305144721_add_privileged_to_runner.rb18
-rw-r--r--db/migrate/20180306134842_add_missing_indexes_acts_as_taggable_on_engine.rb21
-rw-r--r--db/migrate/20180308052825_add_section_name_id_index_on_ci_build_trace_sections.rb17
-rw-r--r--db/migrate/20180308125206_add_user_internal_regex_to_application_setting.rb15
-rw-r--r--db/migrate/20180309121820_reschedule_commits_count_for_merge_request_diff.rb30
-rw-r--r--db/migrate/20180309160427_add_partial_indexes_on_todos.rb29
-rw-r--r--db/migrate/20180314100728_add_external_authorization_service_timeout_to_application_settings.rb18
-rw-r--r--db/migrate/20180314145917_add_header_and_footer_banners_to_appearances_table.rb20
-rw-r--r--db/migrate/20180315160435_add_external_auth_mutual_tls_fields_to_project_settings.rb20
-rw-r--r--db/migrate/20180319190020_create_deploy_tokens.rb21
-rw-r--r--db/migrate/20180320182229_add_indexes_for_user_activity_queries.rb18
-rw-r--r--db/migrate/20180323150945_add_push_to_merge_request_to_notification_settings.rb9
-rw-r--r--db/migrate/20180326202229_create_ci_build_trace_chunks.rb17
-rw-r--r--db/migrate/20180327101207_remove_index_from_events_table.rb18
-rw-r--r--db/migrate/20180330121048_add_issue_due_to_notification_settings.rb9
-rw-r--r--db/migrate/20180403035759_create_project_ci_cd_settings.rb62
-rw-r--r--db/migrate/20180405142733_create_project_deploy_tokens.rb16
-rw-r--r--db/migrate/20180408143354_rename_users_rss_token_to_feed_token.rb16
-rw-r--r--db/migrate/20180413022611_create_missing_namespace_for_internal_users.rb66
-rw-r--r--db/migrate/20180416155103_add_further_scope_columns_to_internal_id_table.rb15
-rw-r--r--db/migrate/20180417090132_add_index_constraints_to_internal_id_table.rb41
-rw-r--r--db/migrate/20180417101040_add_tmp_stage_priority_index_to_ci_builds.rb16
-rw-r--r--db/migrate/20180417101940_add_index_to_ci_stage.rb9
-rw-r--r--db/migrate/20180418053107_add_index_to_ci_job_artifacts_file_store.rb16
-rw-r--r--db/migrate/20180420010016_add_pipeline_build_foreign_key.rb27
-rw-r--r--db/migrate/20180420010616_cleanup_build_stage_migration.rb63
-rw-r--r--db/migrate/20180423204600_add_pages_access_level_to_project_feature.rb20
-rw-r--r--db/migrate/20180424090541_add_enforce_terms_to_application_settings.rb10
-rw-r--r--db/migrate/20180424134533_create_application_setting_terms.rb15
-rw-r--r--db/migrate/20180424160449_add_pipeline_iid_to_ci_pipelines.rb13
-rw-r--r--db/migrate/20180425075446_create_term_agreements.rb29
-rw-r--r--db/migrate/20180425131009_assure_commits_count_for_merge_request_diff.rb27
-rw-r--r--db/migrate/20180425205249_add_index_constraints_to_pipeline_iid.rb15
-rw-r--r--db/migrate/20180426102016_add_accepted_term_to_users.rb23
-rw-r--r--db/migrate/20180430101916_add_runner_type_to_ci_runners.rb9
-rw-r--r--db/migrate/20180502122856_create_project_mirror_data.rb32
-rw-r--r--db/migrate/20180503131624_create_remote_mirrors.rb36
-rw-r--r--db/migrate/20180503141722_add_remote_mirror_available_overridden_to_projects.rb15
-rw-r--r--db/migrate/20180503150427_add_index_to_namespaces_runners_token.rb21
-rw-r--r--db/migrate/20180503175053_ensure_missing_columns_to_project_mirror_data.rb19
-rw-r--r--db/migrate/20180503175054_add_indexes_to_project_mirror_data.rb18
-rw-r--r--db/migrate/20180503193542_add_indexes_to_remote_mirror.rb17
-rw-r--r--db/migrate/20180503193953_add_mirror_available_to_application_settings.rb17
-rw-r--r--db/migrate/20180503200320_enable_prometheus_metrics_by_default.rb11
-rw-r--r--db/migrate/20180504195842_project_name_lower_index.rb24
-rw-r--r--db/migrate/20180508055821_make_remote_mirrors_disabled_by_default.rb11
-rw-r--r--db/migrate/20180508100222_add_not_null_constraint_to_project_mirror_data_foreign_key.rb21
-rw-r--r--db/migrate/20180508102840_add_unique_constraint_to_project_mirror_data_project_id_index.rb31
-rw-r--r--db/migrate/20180508135515_set_runner_type_not_null.rb9
-rw-r--r--db/migrate/20180511090724_add_index_on_ci_runners_runner_type.rb16
-rw-r--r--db/migrate/20180511131058_create_clusters_applications_jupyter.rb25
-rw-r--r--db/migrate/20180515005612_add_squash_to_merge_requests.rb20
-rw-r--r--db/migrate/20180515121227_create_notes_diff_files.rb27
-rw-r--r--db/migrate/20180517082340_add_not_null_constraints_to_project_authorizations.rb24
-rw-r--r--db/migrate/20180523042841_rename_merge_requests_allow_maintainer_to_push.rb17
-rw-r--r--db/migrate/20180524132016_merge_requests_target_id_iid_state_partial_index.rb27
-rw-r--r--db/migrate/20180529093006_ensure_remote_mirror_columns.rb28
-rw-r--r--db/migrate/20180530135500_add_index_to_stages_position.rb15
-rw-r--r--db/migrate/20180531185349_add_repository_languages.rb30
-rw-r--r--db/migrate/20180531220618_change_default_value_for_dsa_key_restriction.rb16
-rw-r--r--db/migrate/20180601213245_add_deploy_strategy_to_project_auto_devops.rb19
-rw-r--r--db/migrate/20180607071808_add_push_events_branch_filter_to_web_hooks.rb12
-rw-r--r--db/migrate/20180608091413_add_group_to_todos.rb36
-rw-r--r--db/migrate/20180608110058_rename_merge_requests_allow_collaboration.rb22
-rw-r--r--db/migrate/20180612103626_add_columns_for_helm_tiller_certificates.rb14
-rw-r--r--db/migrate/20180613081317_create_ci_builds_runner_session.rb23
-rw-r--r--db/migrate/20180625113853_create_import_export_uploads.rb18
-rw-r--r--db/migrate/20180626125654_add_index_on_deployable_for_deployments.rb18
-rw-r--r--db/migrate/20180628124813_alter_web_hook_logs_indexes.rb28
-rw-r--r--db/migrate/20180629153018_create_site_statistics.rb18
-rw-r--r--db/migrate/20180702124358_remove_orphaned_routes.rb49
-rw-r--r--db/migrate/20180702134423_generate_missing_routes.rb144
-rw-r--r--db/migrate/20180704204006_add_hide_third_party_offers_to_application_settings.rb18
-rw-r--r--db/migrate/20180705160945_add_file_format_to_ci_job_artifacts.rb7
-rw-r--r--db/migrate/20180710162338_add_foreign_key_from_notification_settings_to_users.rb30
-rw-r--r--db/migrate/20180711103851_drop_duplicate_protected_tags.rb38
-rw-r--r--db/migrate/20180711103922_add_protected_tags_index.rb18
-rw-r--r--db/migrate/20180713092803_create_user_statuses.rb22
-rw-r--r--db/migrate/20180717125853_remove_restricted_todos.rb31
-rw-r--r--db/migrate/20180718005113_add_instance_statistics_visibility_to_application_setting.rb20
-rw-r--r--db/migrate/20180720023512_add_receive_max_input_size_to_application_settings.rb11
-rw-r--r--db/migrate/20180722103201_add_private_profile_to_users.rb10
-rw-r--r--db/migrate/20180723135214_add_web_ide_client_side_preview_enabled_to_application_settings.rb20
-rw-r--r--db/migrate/20180726172057_create_resource_label_events.rb18
-rw-r--r--db/migrate/20180807153545_remove_redundant_status_index_on_ci_builds.rb17
-rw-r--r--db/migrate/20180808162000_add_user_show_add_ssh_key_message_to_application_settings.rb21
-rw-r--r--db/migrate/20180813101999_change_default_of_auto_devops_instance_wide.rb15
-rw-r--r--db/migrate/20180813102000_enable_auto_devops_instance_wide_for_everyone.rb15
-rw-r--r--db/migrate/20180814153625_add_commit_email_to_users.rb37
-rw-r--r--db/migrate/20180815040323_add_authorization_type_to_cluster_platforms_kubernetes.rb11
-rw-r--r--db/migrate/20180815160409_add_file_location_to_ci_job_artifacts.rb9
-rw-r--r--db/migrate/20180815170510_add_partial_index_to_ci_builds_artifacts_file.rb16
-rw-r--r--db/migrate/20180815175440_add_index_on_list_type.rb16
-rw-r--r--db/migrate/20180824202952_add_outbound_requests_whitelist_to_application_settings.rb11
-rw-r--r--db/migrate/20180831164905_add_common_to_prometheus_metrics.rb17
-rw-r--r--db/migrate/20180831164907_add_index_on_common_for_prometheus_metrics.rb17
-rw-r--r--db/migrate/20180831164908_add_identifier_to_prometheus_metric.rb11
-rw-r--r--db/migrate/20180831164909_add_index_for_identifier_to_prometheus_metric.rb17
-rw-r--r--db/migrate/20180831164910_import_common_metrics.rb15
-rw-r--r--db/migrate/20180901171833_add_project_config_source_status_index_to_pipeline.rb17
-rw-r--r--db/migrate/20180901200537_add_resource_label_event_reference_fields.rb13
-rw-r--r--db/migrate/20180902070406_create_group_group_links.rb32
-rw-r--r--db/migrate/20180906101639_add_user_ping_consent_to_application_settings.rb19
-rw-r--r--db/migrate/20180907015926_add_legacy_abac_to_cluster_providers_gcp.rb17
-rw-r--r--db/migrate/20180910115836_add_attr_encrypted_columns_to_web_hook.rb17
-rw-r--r--db/migrate/20180910153412_add_token_digest_to_personal_access_tokens.rb19
-rw-r--r--db/migrate/20180910153413_add_index_to_token_digest_on_personal_access_tokens.rb17
-rw-r--r--db/migrate/20180912111628_add_knative_application.rb22
-rw-r--r--db/migrate/20180916011959_add_index_pipelines_project_id_source.rb20
-rw-r--r--db/migrate/20180924141949_add_diff_max_patch_bytes_to_application_settings.rb25
-rw-r--r--db/migrate/20180924190739_add_scheduled_at_to_ci_builds.rb9
-rw-r--r--db/migrate/20180924201039_add_partial_index_to_scheduled_at.rb18
-rw-r--r--db/migrate/20180925200829_create_user_preferences.rb31
-rw-r--r--db/migrate/20180927073410_add_index_to_project_deploy_tokens_deploy_token_id.rb17
-rw-r--r--db/migrate/20181002172433_remove_restricted_todos_with_cte.rb32
-rw-r--r--db/migrate/20181005110927_add_index_to_lfs_objects_file_store.rb17
-rw-r--r--db/migrate/20181005125926_add_index_to_uploads_store.rb17
-rw-r--r--db/migrate/20181006004100_import_common_metrics_nginx_vts.rb13
-rw-r--r--db/migrate/20181009190428_create_clusters_kubernetes_namespaces.rb26
-rw-r--r--db/migrate/20181010235606_create_board_project_recent_visits.rb19
-rw-r--r--db/migrate/20181014203236_create_cluster_groups.rb17
-rw-r--r--db/migrate/20181015155839_add_finished_at_to_deployments.rb15
-rw-r--r--db/migrate/20181016141739_add_status_to_deployments.rb33
-rw-r--r--db/migrate/20181016152238_create_board_group_recent_visits.rb20
-rw-r--r--db/migrate/20181017001059_add_cluster_type_to_clusters.rb18
-rw-r--r--db/migrate/20181019032400_add_shards_table.rb11
-rw-r--r--db/migrate/20181019032408_add_repositories_table.rb15
-rw-r--r--db/migrate/20181019105553_add_projects_pool_repository_id_foreign_key.rb22
-rw-r--r--db/migrate/20181022135539_add_index_on_status_to_deployments.rb19
-rw-r--r--db/migrate/20181023104858_add_archive_builds_duration_to_application_settings.rb11
-rw-r--r--db/migrate/20181023144439_add_partial_index_for_legacy_successful_deployments.rb18
-rw-r--r--db/migrate/20181025115728_add_private_commit_email_hostname_to_application_settings.rb13
-rw-r--r--db/migrate/20181026143227_migrate_snippets_access_level_default_value.rb42
-rw-r--r--db/migrate/20181027114222_add_first_day_of_week_to_user_preferences.rb9
-rw-r--r--db/migrate/20181028120717_add_first_day_of_week_to_application_settings.rb16
-rw-r--r--db/migrate/20181030154446_add_missing_indexes_for_foreign_keys.rb61
-rw-r--r--db/migrate/20181031145139_add_protected_ci_variables_to_application_settings.rb17
-rw-r--r--db/migrate/20181031190558_drop_fk_gcp_clusters_table.rb37
-rw-r--r--db/migrate/20181031190559_drop_gcp_clusters_table.rb53
-rw-r--r--db/migrate/20181101144347_add_index_for_stuck_mr_query.rb16
-rw-r--r--db/migrate/20181101191341_create_clusters_applications_cert_manager.rb21
-rw-r--r--db/migrate/20181106135939_add_index_to_deployments.rb17
-rw-r--r--db/migrate/20181108091549_cleanup_environments_external_url.rb18
-rw-r--r--db/migrate/20181112103239_drop_default_value_on_status_deployments.rb14
-rw-r--r--db/migrate/20181115140140_add_encrypted_runners_token_to_settings.rb13
-rw-r--r--db/migrate/20181116050532_knative_external_ip.rb16
-rw-r--r--db/migrate/20181116141415_add_encrypted_runners_token_to_namespaces.rb13
-rw-r--r--db/migrate/20181116141504_add_encrypted_runners_token_to_projects.rb15
-rw-r--r--db/migrate/20181119081539_add_merge_request_id_to_ci_pipelines.rb13
-rw-r--r--db/migrate/20181119132520_add_indexes_to_ci_builds_and_pipelines.rb44
-rw-r--r--db/migrate/20181120082911_rename_repositories_pool_repositories.rb11
-rw-r--r--db/migrate/20181120091639_add_foreign_key_to_ci_pipelines_merge_requests.rb22
-rw-r--r--db/migrate/20181120151656_add_token_encrypted_to_ci_runners.rb11
-rw-r--r--db/migrate/20181121101842_add_ci_builds_partial_index_on_project_id_and_status.rb33
-rw-r--r--db/migrate/20181121101843_remove_redundant_ci_builds_partial_index.rb33
-rw-r--r--db/migrate/20181122160027_create_project_repositories.rb18
-rw-r--r--db/migrate/20181123135036_drop_not_null_constraint_pool_repository_disk_path.rb9
-rw-r--r--db/migrate/20181123144235_create_suggestions.rb24
-rw-r--r--db/migrate/20181126150622_add_events_index_on_project_id_and_created_at.rb32
-rw-r--r--db/migrate/20181126153547_remove_notes_index_on_updated_at.rb32
-rw-r--r--db/migrate/20181128123704_add_state_to_pool_repository.rb23
-rw-r--r--db/migrate/20181129104854_add_token_encrypted_to_ci_builds.rb15
-rw-r--r--db/migrate/20181129104944_add_index_to_ci_builds_token_encrypted.rb17
-rw-r--r--db/migrate/20181203002526_add_project_bfg_object_map_column.rb13
-rw-r--r--db/migrate/20181205171941_create_project_daily_statistics.rb18
-rw-r--r--db/migrate/20181211092510_add_name_author_id_and_sha_to_releases.rb15
-rw-r--r--db/migrate/20181211092514_add_author_id_index_and_fk_to_releases.rb21
-rw-r--r--db/migrate/20181212104941_backfill_releases_name_with_tag_name.rb17
-rw-r--r--db/migrate/20181212171634_create_error_tracking_settings.rb19
-rw-r--r--db/migrate/20181219145521_add_options_to_build_metadata.rb15
-rw-r--r--db/migrate/20181228175414_create_releases_link_table.rb21
-rw-r--r--db/migrate/20181228175414_init_schema.rb2562
-rw-r--r--db/migrate/20190315191339_create_merge_request_assignees_table.rb2
-rw-r--r--db/migrate/20190402150158_backport_enterprise_schema.rb2
-rw-r--r--db/migrate/20190722144316_create_milestone_releases_table.rb2
-rw-r--r--db/migrate/20190927055500_create_description_versions.rb2
-rw-r--r--db/migrate/20191118053631_add_group_deletion_schedules.rb2
-rw-r--r--db/migrate/20191127151619_create_gitlab_subscription_histories.rb2
-rw-r--r--db/migrate/20200123091622_drop_analytics_repository_files_table.rb2
-rw-r--r--db/migrate/20200123091734_drop_analytics_repository_file_commits_table.rb2
-rw-r--r--db/migrate/20200123091854_drop_analytics_repository_file_edits_table.rb2
-rw-r--r--db/migrate/20200214025454_add_canonical_emails.rb2
-rw-r--r--db/migrate/20200215225103_drop_forked_project_links_table.rb2
-rw-r--r--db/migrate/20200227165129_create_user_details.rb2
-rw-r--r--db/migrate/20200306160521_add_index_on_author_id_and_created_at_to_events.rb5
-rw-r--r--db/migrate/20200311093210_create_user_highest_roles.rb2
-rw-r--r--db/migrate/20200325094612_add_allow_merge_on_skipped_pipeline_to_project_settings.rb9
-rw-r--r--db/migrate/20200326122700_create_diff_note_positions.rb2
-rw-r--r--db/migrate/20200330203826_drop_fk_in_ci_ref.rb32
-rw-r--r--db/migrate/20200330203837_recreate_ci_ref.rb45
-rw-r--r--db/migrate/20200331103637_add_ci_ref_id_to_ci_pipelines.rb19
-rw-r--r--db/migrate/20200331113728_add_index_to_ci_ref_id.rb16
-rw-r--r--db/migrate/20200331113738_add_fk_to_ci_ref_id.rb18
-rw-r--r--db/migrate/20200331132103_add_project_compliance_framework_settings_table.rb2
-rw-r--r--db/migrate/20200407182205_create_partitioned_foreign_keys.rb2
-rw-r--r--db/migrate/20200407222647_create_project_repository_storage_moves.rb2
-rw-r--r--db/migrate/20200408125046_create_ci_freeze_periods.rb2
-rw-r--r--db/migrate/20200416005331_create_status_page_published_incidents.rb2
-rw-r--r--db/migrate/20200417044453_create_alert_management_alerts.rb2
-rw-r--r--db/migrate/20200420104303_add_group_import_states_table.rb2
-rw-r--r--db/migrate/20200420115948_create_metrics_users_starred_dashboard.rb2
-rw-r--r--db/migrate/20200421054930_remove_index_on_pipeline_id_from_ci_pipeline_variables.rb18
-rw-r--r--db/migrate/20200421054948_remove_index_on_pipeline_id_from_ci_variables.rb18
-rw-r--r--db/migrate/20200422091541_create_ci_instance_variables.rb2
-rw-r--r--db/migrate/20200424135319_create_nuget_dependency_link_metadata.rb4
-rw-r--r--db/migrate/20200429023324_add_composer_metadata.rb12
-rw-r--r--db/migrate/20200430123614_create_project_access_tokens.rb14
-rw-r--r--db/migrate/20200430130048_create_packages_nuget_metadata.rb2
-rw-r--r--db/migrate/20200430174637_create_group_deploy_keys.rb38
-rw-r--r--db/migrate/20200507221434_add_container_registry_features_to_application_settings.rb2
-rw-r--r--db/migrate/20200508021128_remove_ultraauth_provider_from_identities.rb18
-rw-r--r--db/migrate/20200508050301_add_spam_check_endpoint_to_application_settings.rb34
-rw-r--r--db/migrate/20200508140959_add_elasticsearch_pause_indexing_to_application_settings.rb19
-rw-r--r--db/migrate/20200508203901_add_repository_storages_weighted_to_application_settings.rb13
-rw-r--r--db/migrate/20200511181027_create_test_reports.rb18
-rw-r--r--db/migrate/20200511191027_add_author_foreign_key_to_test_reports.rb19
-rw-r--r--db/migrate/20200511208012_add_pipeline_foreign_key_to_test_reports.rb19
-rw-r--r--db/migrate/20200512160004_add_index_to_ci_job_artifacts_for_terraform_reports.rb18
-rw-r--r--db/migrate/20200512195442_update_index_on_name_type_eq_ci_build_to_ci_builds.rb36
-rw-r--r--db/migrate/20200518091745_add_index_to_personal_access_token_impersonation.rb26
-rw-r--r--db/migrate/20200519074709_update_resource_state_events_constraint_to_support_epic_id.rb24
-rw-r--r--db/migrate/20200519101002_add_error_message_column_to_jira_imports.rb22
-rw-r--r--db/migrate/20200519115908_add_epics_confidential_index.rb17
-rw-r--r--db/migrate/20200519141534_add_instance_level_variables_column_to_plan_limits.rb9
-rw-r--r--db/migrate/20200519194042_update_container_expiration_policies_defaults.rb23
-rw-r--r--db/migrate/20200520103514_add_todo_resolved_by_action.rb19
-rw-r--r--db/migrate/20200521022725_add_experience_level_to_user_preferences.rb9
-rw-r--r--db/migrate/20200521225327_create_alert_management_alert_assignees.rb24
-rw-r--r--db/migrate/20200521225337_add_foreign_key_to_user_id_on_alert_management_alert_assignees.rb19
-rw-r--r--db/migrate/20200521225346_add_foreign_key_to_alert_id_on_alert_mangagement_alert_assignees.rb19
-rw-r--r--db/migrate/20200522235146_add_index_on_snippet_type_and_id.rb17
-rw-r--r--db/migrate/20200525114553_rename_user_type_index.rb19
-rw-r--r--db/migrate/20200526013844_add_alert_events_to_services.rb19
-rw-r--r--db/migrate/20200526120714_change_partial_indexes_on_services.rb26
-rw-r--r--db/migrate/20200526142550_drop_null_constraint_on_group_import_state_jid.rb13
-rw-r--r--db/migrate/20200526153844_add_issues_last_edited_by_id_index.rb19
-rw-r--r--db/migrate/20200526164946_create_operations_feature_flags_issues.rb15
-rw-r--r--db/migrate/20200526164947_add_foreign_key_to_ops_feature_flags_issues.rb19
-rw-r--r--db/migrate/20200527092027_add_link_type_to_release_links.rb19
-rw-r--r--db/migrate/20200527135313_add_requirements_build_reference.rb23
-rw-r--r--db/migrate/20200527151413_create_ci_build_report_results_table.rb13
-rw-r--r--db/migrate/20200527152116_add_foreign_key_to_build_id_on_build_report_results.rb19
-rw-r--r--db/migrate/20200527152657_add_foreign_key_to_project_id_on_build_report_results.rb19
-rw-r--r--db/migrate/20200527170649_create_alert_management_alert_user_mentions.rb20
-rw-r--r--db/migrate/20200527211000_add_max_import_size.rb15
-rw-r--r--db/migrate/20200528054112_add_index_to_package_name.rb19
-rw-r--r--db/migrate/20200528125905_add_project_id_user_id_status_ref_index_to_ci_pipelines.rb27
-rw-r--r--db/migrate/20200528171933_remove_not_null_from_external_dashboard_url.rb12
-rw-r--r--db/migrate/20200601210148_add_dashboard_timezone_to_project_metrics_setting.rb12
-rw-r--r--db/migrate/20200603073101_change_constraint_name_on_resource_state_events.rb16
-rw-r--r--db/migrate/20200603180338_add_enforce_pat_expiration_to_application_settings.rb9
-rw-r--r--db/migrate/20200604143628_create_project_security_settings.rb29
-rw-r--r--db/migrate/20200604145731_create_board_user_preferences.rb22
-rw-r--r--db/migrate/20200604174544_add_users_foreign_key_to_board_user_preferences.rb19
-rw-r--r--db/migrate/20200604174558_add_boards_foreign_key_to_board_user_preferences.rb19
-rw-r--r--db/migrate/20200605003204_add_foreign_key_to_alert_management_alert_user_mentions.rb19
-rw-r--r--db/migrate/20200605093113_add_ip_address_to_audit_events.rb9
-rw-r--r--db/migrate/20200608214008_change_column_default_project_incident_management_settings.rb13
-rw-r--r--db/migrate/20200609142506_remove_not_null_constraint_from_weight_events_table.rb9
-rw-r--r--db/migrate/20200609142507_remove_not_null_constraint_from_milestone_events_table.rb9
-rw-r--r--db/migrate/20200609142508_remove_not_null_constraint_from_state_events_table.rb9
-rw-r--r--db/migrate/20200609212701_add_incident_settings_to_all_existing_projects.rb40
-rw-r--r--db/migrate/20200615083635_add_composer_json_to_metadata.rb9
-rw-r--r--db/migrate/20200615121217_add_projects_foreign_key_to_project_access_tokens.rb17
-rw-r--r--db/migrate/20200615123055_add_personal_access_token_foreign_key_to_project_access_tokens.rb17
-rw-r--r--db/migrate/20200615232735_add_index_to_composer_metadata.rb17
-rw-r--r--db/post_migrate/20180104131052_schedule_set_confidential_note_events_on_webhooks.rb23
-rw-r--r--db/post_migrate/20180119121225_remove_redundant_pipeline_stages.rb58
-rw-r--r--db/post_migrate/20180122154930_schedule_set_confidential_note_events_on_services.rb23
-rw-r--r--db/post_migrate/20180204200836_change_author_id_to_not_null_in_todos.rb26
-rw-r--r--db/post_migrate/20180212101828_add_tmp_partial_null_index_to_builds.rb14
-rw-r--r--db/post_migrate/20180212101928_schedule_build_stage_migration.rb14
-rw-r--r--db/post_migrate/20180212102028_remove_tmp_partial_null_index_from_builds.rb14
-rw-r--r--db/post_migrate/20180216121020_fill_pages_domain_verification_code.rb41
-rw-r--r--db/post_migrate/20180216121030_enqueue_verify_pages_domain_workers.rb16
-rw-r--r--db/post_migrate/20180220150310_remove_empty_extern_uid_auth0_identities.rb25
-rw-r--r--db/post_migrate/20180223124427_build_user_interacted_projects_table.rb139
-rw-r--r--db/post_migrate/20180301084653_change_project_namespace_id_not_null.rb29
-rw-r--r--db/post_migrate/20180305100050_remove_permanent_from_redirect_routes.rb33
-rw-r--r--db/post_migrate/20180306074045_migrate_create_trace_artifact_sidekiq_queue.rb13
-rw-r--r--db/post_migrate/20180306164012_add_path_index_to_redirect_routes.rb31
-rw-r--r--db/post_migrate/20180307012445_migrate_update_head_pipeline_for_merge_request_sidekiq_queue.rb15
-rw-r--r--db/post_migrate/20180405101928_reschedule_builds_stages_migration.rb33
-rw-r--r--db/post_migrate/20180408143355_cleanup_users_rss_token_rename.rb14
-rw-r--r--db/post_migrate/20180409170809_populate_missing_project_ci_cd_settings.rb30
-rw-r--r--db/post_migrate/20180420080616_schedule_stages_index_migration.rb29
-rw-r--r--db/post_migrate/20180424151928_fill_file_store.rb72
-rw-r--r--db/post_migrate/20180430143705_backfill_runner_type_for_ci_runners_post_migrate.rb24
-rw-r--r--db/post_migrate/20180507083701_set_minimal_project_build_timeout.rb21
-rw-r--r--db/post_migrate/20180511174224_add_unique_constraint_to_project_features_project_id.rb43
-rw-r--r--db/post_migrate/20180512061621_add_not_null_constraint_to_project_features_project_id.rb21
-rw-r--r--db/post_migrate/20180514161336_remove_gemnasium_service.rb15
-rw-r--r--db/post_migrate/20180523125103_cleanup_merge_requests_allow_maintainer_to_push_rename.rb18
-rw-r--r--db/post_migrate/20180529152628_schedule_to_archive_legacy_traces.rb35
-rw-r--r--db/post_migrate/20180603190921_migrate_object_storage_upload_sidekiq_queue.rb16
-rw-r--r--db/post_migrate/20180604123514_cleanup_stages_position_migration.rb45
-rw-r--r--db/post_migrate/20180608201435_cleanup_merge_requests_allow_collaboration_rename.rb20
-rw-r--r--db/post_migrate/20180629191052_add_partial_index_to_projects_for_last_repository_check_at.rb18
-rw-r--r--db/post_migrate/20180702120647_enqueue_fix_cross_project_label_links.rb30
-rw-r--r--db/post_migrate/20180704145007_update_project_indexes.rb23
-rw-r--r--db/post_migrate/20180706223200_populate_site_statistics.rb25
-rw-r--r--db/post_migrate/20180809195358_migrate_null_wiki_access_levels.rb32
-rw-r--r--db/post_migrate/20180816161409_migrate_legacy_artifacts_to_job_artifacts.rb32
-rw-r--r--db/post_migrate/20180816193530_rename_login_root_namespaces.rb22
-rw-r--r--db/post_migrate/20180826111825_recalculate_site_statistics.rb27
-rw-r--r--db/post_migrate/20180913142237_schedule_digest_personal_access_tokens.rb28
-rw-r--r--db/post_migrate/20180914162043_encrypt_web_hooks_columns.rb33
-rw-r--r--db/post_migrate/20180914201132_remove_sidekiq_throttling_from_application_settings.rb17
-rw-r--r--db/post_migrate/20180917172041_remove_wikis_count_from_site_statistics.rb6
-rw-r--r--db/post_migrate/20181008145341_steal_encrypt_columns.rb15
-rw-r--r--db/post_migrate/20181008145359_remove_web_hooks_token_and_url.rb10
-rw-r--r--db/post_migrate/20181008200441_remove_circuit_breaker.rb32
-rw-r--r--db/post_migrate/20181010133639_backfill_store_project_full_path_in_repo.rb27
-rw-r--r--db/post_migrate/20181013005024_remove_koding_from_application_settings.rb17
-rw-r--r--db/post_migrate/20181022173835_enqueue_populate_cluster_kubernetes_namespace.rb18
-rw-r--r--db/post_migrate/20181026091631_migrate_forbidden_redirect_uris.rb32
-rw-r--r--db/post_migrate/20181030135124_fill_empty_finished_at_in_deployments.rb27
-rw-r--r--db/post_migrate/20181101091005_steal_digest_column.rb17
-rw-r--r--db/post_migrate/20181101091124_remove_token_from_personal_access_tokens.rb11
-rw-r--r--db/post_migrate/20181105201455_steal_fill_store_upload.rb31
-rw-r--r--db/post_migrate/20181107054254_remove_restricted_todos_again.rb32
-rw-r--r--db/post_migrate/20181121111200_schedule_runners_token_encryption.rb38
-rw-r--r--db/post_migrate/20181123042307_drop_site_statistics.rb22
-rw-r--r--db/post_migrate/20181130102132_backfill_hashed_project_repositories.rb26
-rw-r--r--db/post_migrate/20181219130552_update_project_import_visibility_level.rb60
-rw-r--r--db/post_migrate/20181219145520_migrate_cluster_configure_worker_sidekiq_queue.rb15
-rw-r--r--db/post_migrate/20200310215714_migrate_saml_identities_to_scim_identities.rb2
-rw-r--r--db/post_migrate/20200406102120_backfill_deployment_clusters_from_deployments.rb2
-rw-r--r--db/post_migrate/20200408132152_remove_namespaces_trial_ends_on.rb27
-rw-r--r--db/post_migrate/20200421195234_backfill_status_page_published_incidents.rb48
-rw-r--r--db/post_migrate/20200518114540_schedule_fix_ruby_object_in_audit_events.rb41
-rw-r--r--db/post_migrate/20200518133123_add_index_on_starting_ending_at_to_metrics_dashboard_annotations.rb18
-rw-r--r--db/post_migrate/20200519171058_update_index_ci_builds_on_commit_id_and_artifacts_expireatandidpartial.rb35
-rw-r--r--db/post_migrate/20200525121014_drop_users_ghost_column.rb29
-rw-r--r--db/post_migrate/20200525144525_migrate_stuck_import_jobs_queue_to_stuck_project_import_jobs.rb15
-rw-r--r--db/post_migrate/20200526000407_seed_repository_storages_weighted.rb23
-rw-r--r--db/post_migrate/20200527094322_drop_vulnerability_confidence_index.rb20
-rw-r--r--db/post_migrate/20200527095401_drop_vulnerability_occurrence_confidence_index.rb20
-rw-r--r--db/post_migrate/20200528123703_add_merge_request_partial_index_to_events.rb24
-rw-r--r--db/post_migrate/20200602013900_add_limit_to_designs_filename.rb17
-rw-r--r--db/post_migrate/20200602013901_cap_designs_filename_length_to_new_limit.rb40
-rw-r--r--db/post_migrate/20200602143020_update_routes_for_lost_and_found_group_and_orphaned_projects.rb178
-rw-r--r--db/post_migrate/20200608072931_backfill_imported_snippet_repositories.rb47
-rw-r--r--db/post_migrate/20200608075553_add_index_on_user_id_and_created_at_and_source_to_ci_pipelines.rb19
-rw-r--r--db/post_migrate/20200609002841_add_partial_index_on_locked_state_id_to_merge_requests.rb19
-rw-r--r--db/structure.sql793
-rw-r--r--doc/.vale/gitlab/Acronyms.yml71
-rw-r--r--doc/.vale/gitlab/BadgeCapitalization.yml4
-rw-r--r--doc/.vale/gitlab/British.yml6
-rw-r--r--doc/.vale/gitlab/CodeblockFences.yml13
-rw-r--r--doc/.vale/gitlab/Contractions.yml4
-rw-r--r--doc/.vale/gitlab/CurlStringsQuoted.yml13
-rw-r--r--doc/.vale/gitlab/FirstPerson.yml5
-rw-r--r--doc/.vale/gitlab/InternalLinkExtension.yml4
-rw-r--r--doc/.vale/gitlab/LatinTerms.yml6
-rw-r--r--doc/.vale/gitlab/MeaningfulLinkWords.yml15
-rw-r--r--doc/.vale/gitlab/MergeConflictMarkers.yml13
-rw-r--r--doc/.vale/gitlab/OxfordComma.yml4
-rw-r--r--doc/.vale/gitlab/Profanity.yml30
-rw-r--r--doc/.vale/gitlab/ReferenceLinks.yml3
-rw-r--r--doc/.vale/gitlab/RelativeLinks.yml4
-rw-r--r--doc/.vale/gitlab/Repetition.yml3
-rw-r--r--doc/.vale/gitlab/SentenceLength.yml13
-rw-r--r--doc/.vale/gitlab/SentenceSpacing.yml2
-rw-r--r--doc/.vale/gitlab/Spelling.yml3
-rw-r--r--doc/.vale/gitlab/SubstitutionWarning.yml4
-rw-r--r--doc/.vale/gitlab/Substitutions.yml3
-rw-r--r--doc/.vale/gitlab/VersionText.yml2
-rw-r--r--doc/.vale/gitlab/spelling-exceptions.txt140
-rw-r--r--doc/README.md4
-rw-r--r--doc/administration/audit_events.md26
-rw-r--r--doc/administration/auth/README.md12
-rw-r--r--doc/administration/auth/authentiq.md3
-rw-r--r--doc/administration/auth/cognito.md11
-rw-r--r--doc/administration/auth/crowd.md3
-rw-r--r--doc/administration/auth/google_secure_ldap.md218
-rw-r--r--doc/administration/auth/how_to_configure_ldap_gitlab_ce/img/gitlab_ou.pngbin11991 -> 0 bytes
-rw-r--r--doc/administration/auth/how_to_configure_ldap_gitlab_ce/img/ldap_ou.gifbin222162 -> 0 bytes
-rw-r--r--doc/administration/auth/how_to_configure_ldap_gitlab_ce/img/user_auth.gifbin110971 -> 0 bytes
-rw-r--r--doc/administration/auth/how_to_configure_ldap_gitlab_ce/index.md272
-rw-r--r--doc/administration/auth/how_to_configure_ldap_gitlab_ee/img/admin_group.pngbin17543 -> 0 bytes
-rw-r--r--doc/administration/auth/how_to_configure_ldap_gitlab_ee/img/group_link_final.pngbin14524 -> 0 bytes
-rw-r--r--doc/administration/auth/how_to_configure_ldap_gitlab_ee/img/group_linking.gifbin1328162 -> 0 bytes
-rw-r--r--doc/administration/auth/how_to_configure_ldap_gitlab_ee/img/manual_permissions.gifbin1029427 -> 0 bytes
-rw-r--r--doc/administration/auth/how_to_configure_ldap_gitlab_ee/img/multi_login.gifbin180218 -> 0 bytes
-rw-r--r--doc/administration/auth/how_to_configure_ldap_gitlab_ee/index.md124
-rw-r--r--doc/administration/auth/jwt.md3
-rw-r--r--doc/administration/auth/ldap-ee.md416
-rw-r--r--doc/administration/auth/ldap-troubleshooting.md654
-rw-r--r--doc/administration/auth/ldap.md554
-rw-r--r--doc/administration/auth/ldap/google_secure_ldap.md222
-rw-r--r--doc/administration/auth/ldap/img/google_secure_ldap_add_step_1.png (renamed from doc/administration/auth/img/google_secure_ldap_add_step_1.png)bin9083 -> 9083 bytes
-rw-r--r--doc/administration/auth/ldap/img/google_secure_ldap_add_step_2.png (renamed from doc/administration/auth/img/google_secure_ldap_add_step_2.png)bin27207 -> 27207 bytes
-rw-r--r--doc/administration/auth/ldap/img/google_secure_ldap_client_settings.png (renamed from doc/administration/auth/img/google_secure_ldap_client_settings.png)bin21302 -> 21302 bytes
-rw-r--r--doc/administration/auth/ldap/img/multi_login.gifbin0 -> 321518 bytes
-rw-r--r--doc/administration/auth/ldap/index.md756
-rw-r--r--doc/administration/auth/ldap/ldap-troubleshooting.md678
-rw-r--r--doc/administration/auth/oidc.md7
-rw-r--r--doc/administration/auth/okta.md9
-rw-r--r--doc/administration/auth/smartcard.md12
-rw-r--r--doc/administration/compliance.md4
-rw-r--r--doc/administration/environment_variables.md12
-rw-r--r--doc/administration/external_database.md44
-rw-r--r--doc/administration/external_pipeline_validation.md7
-rw-r--r--doc/administration/feature_flags.md17
-rw-r--r--doc/administration/geo/disaster_recovery/background_verification.md7
-rw-r--r--doc/administration/geo/disaster_recovery/bring_primary_back.md7
-rw-r--r--doc/administration/geo/disaster_recovery/index.md42
-rw-r--r--doc/administration/geo/disaster_recovery/planned_failover.md9
-rw-r--r--doc/administration/geo/replication/configuration.md9
-rw-r--r--doc/administration/geo/replication/database.md17
-rw-r--r--doc/administration/geo/replication/datatypes.md24
-rw-r--r--doc/administration/geo/replication/docker_registry.md13
-rw-r--r--doc/administration/geo/replication/external_database.md11
-rw-r--r--doc/administration/geo/replication/faq.md7
-rw-r--r--doc/administration/geo/replication/geo_validation_tests.md15
-rw-r--r--doc/administration/geo/replication/index.md17
-rw-r--r--doc/administration/geo/replication/location_aware_git_url.md9
-rw-r--r--doc/administration/geo/replication/multiple_servers.md11
-rw-r--r--doc/administration/geo/replication/object_storage.md9
-rw-r--r--doc/administration/geo/replication/remove_geo_node.md7
-rw-r--r--doc/administration/geo/replication/security_review.md11
-rw-r--r--doc/administration/geo/replication/troubleshooting.md17
-rw-r--r--doc/administration/geo/replication/tuning.md7
-rw-r--r--doc/administration/geo/replication/updating_the_geo_nodes.md7
-rw-r--r--doc/administration/geo/replication/using_a_geo_server.md7
-rw-r--r--doc/administration/geo/replication/version_specific_updates.md13
-rw-r--r--doc/administration/git_annex.md2
-rw-r--r--doc/administration/git_protocol.md8
-rw-r--r--doc/administration/gitaly/index.md458
-rw-r--r--doc/administration/gitaly/praefect.md72
-rw-r--r--doc/administration/gitaly/reference.md9
-rw-r--r--doc/administration/high_availability/consul.md4
-rw-r--r--doc/administration/high_availability/database.md1097
-rw-r--r--doc/administration/high_availability/gitaly.md9
-rw-r--r--doc/administration/high_availability/gitlab.md8
-rw-r--r--doc/administration/high_availability/load_balancer.md12
-rw-r--r--doc/administration/high_availability/monitoring_node.md4
-rw-r--r--doc/administration/high_availability/nfs.md10
-rw-r--r--doc/administration/high_availability/pgbouncer.md121
-rw-r--r--doc/administration/high_availability/redis.md6
-rw-r--r--doc/administration/housekeeping.md2
-rw-r--r--doc/administration/incoming_email.md14
-rw-r--r--doc/administration/index.md4
-rw-r--r--doc/administration/instance_limits.md42
-rw-r--r--doc/administration/integration/plantuml.md15
-rw-r--r--doc/administration/job_artifacts.md58
-rw-r--r--doc/administration/job_logs.md24
-rw-r--r--doc/administration/lfs/index.md2
-rw-r--r--doc/administration/libravatar.md2
-rw-r--r--doc/administration/logs.md74
-rw-r--r--doc/administration/merge_request_diffs.md2
-rw-r--r--doc/administration/monitoring/github_imports.md6
-rw-r--r--doc/administration/monitoring/gitlab_self_monitoring_project/index.md24
-rw-r--r--doc/administration/monitoring/index.md6
-rw-r--r--doc/administration/monitoring/ip_whitelist.md6
-rw-r--r--doc/administration/monitoring/performance/gitlab_configuration.md6
-rw-r--r--doc/administration/monitoring/performance/grafana_configuration.md8
-rw-r--r--doc/administration/monitoring/performance/img/request_profiling_token.pngbin17396 -> 0 bytes
-rw-r--r--doc/administration/monitoring/performance/index.md6
-rw-r--r--doc/administration/monitoring/performance/performance_bar.md8
-rw-r--r--doc/administration/monitoring/performance/request_profiling.md46
-rw-r--r--doc/administration/monitoring/prometheus/gitlab_metrics.md120
-rw-r--r--doc/administration/monitoring/prometheus/index.md2
-rw-r--r--doc/administration/monitoring/prometheus/node_exporter.md25
-rw-r--r--doc/administration/monitoring/prometheus/pgbouncer_exporter.md29
-rw-r--r--doc/administration/monitoring/prometheus/postgres_exporter.md72
-rw-r--r--doc/administration/monitoring/prometheus/redis_exporter.md23
-rw-r--r--doc/administration/object_storage.md88
-rw-r--r--doc/administration/operations/extra_sidekiq_processes.md15
-rw-r--r--doc/administration/operations/fast_ssh_key_lookup.md6
-rw-r--r--doc/administration/operations/filesystem_benchmarking.md2
-rw-r--r--doc/administration/operations/puma.md15
-rw-r--r--doc/administration/operations/ssh_certificates.md2
-rw-r--r--doc/administration/operations/unicorn.md4
-rw-r--r--doc/administration/packages/container_registry.md62
-rw-r--r--doc/administration/packages/dependency_proxy.md8
-rw-r--r--doc/administration/packages/index.md8
-rw-r--r--doc/administration/pages/index.md88
-rw-r--r--doc/administration/pages/source.md14
-rw-r--r--doc/administration/postgresql/external.md41
-rw-r--r--doc/administration/postgresql/img/pg_ha_architecture.png (renamed from doc/administration/high_availability/img/pg_ha_architecture.png)bin18412 -> 18412 bytes
-rw-r--r--doc/administration/postgresql/replication_and_failover.md1129
-rw-r--r--doc/administration/postgresql/standalone.md65
-rw-r--r--doc/administration/raketasks/github_import.md5
-rw-r--r--doc/administration/raketasks/ldap.md4
-rw-r--r--doc/administration/raketasks/maintenance.md50
-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/raketasks/uploads/migrate.md2
-rw-r--r--doc/administration/raketasks/uploads/sanitize.md2
-rw-r--r--doc/administration/reference_architectures/10k_users.md9
-rw-r--r--doc/administration/reference_architectures/1k_users.md24
-rw-r--r--doc/administration/reference_architectures/25k_users.md37
-rw-r--r--doc/administration/reference_architectures/2k_users.md947
-rw-r--r--doc/administration/reference_architectures/3k_users.md31
-rw-r--r--doc/administration/reference_architectures/50k_users.md37
-rw-r--r--doc/administration/reference_architectures/5k_users.md31
-rw-r--r--doc/administration/reference_architectures/index.md43
-rw-r--r--doc/administration/reference_architectures/troubleshooting.md329
-rw-r--r--doc/administration/repository_storage_paths.md4
-rw-r--r--doc/administration/repository_storage_types.md4
-rw-r--r--doc/administration/server_hooks.md20
-rw-r--r--doc/administration/snippets/index.md2
-rw-r--r--doc/administration/timezone.md2
-rw-r--r--doc/administration/troubleshooting/debug.md2
-rw-r--r--doc/administration/troubleshooting/elasticsearch.md8
-rw-r--r--doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md63
-rw-r--r--doc/administration/troubleshooting/index.md20
-rw-r--r--doc/administration/troubleshooting/kubernetes_cheat_sheet.md4
-rw-r--r--doc/administration/troubleshooting/postgresql.md22
-rw-r--r--doc/administration/troubleshooting/sidekiq.md23
-rw-r--r--doc/administration/troubleshooting/test_environments.md2
-rw-r--r--doc/administration/uploads.md4
-rw-r--r--doc/api/README.md28
-rw-r--r--doc/api/access_requests.md30
-rw-r--r--doc/api/admin_sidekiq_queues.md2
-rw-r--r--doc/api/appearance.md8
-rw-r--r--doc/api/applications.md6
-rw-r--r--doc/api/audit_events.md122
-rw-r--r--doc/api/avatar.md2
-rw-r--r--doc/api/award_emoji.md22
-rw-r--r--doc/api/boards.md71
-rw-r--r--doc/api/branches.md10
-rw-r--r--doc/api/broadcast_messages.md10
-rw-r--r--doc/api/commits.md6
-rw-r--r--doc/api/container_registry.md16
-rw-r--r--doc/api/custom_attributes.md8
-rw-r--r--doc/api/dependencies.md2
-rw-r--r--doc/api/deploy_keys.md10
-rw-r--r--doc/api/deploy_tokens.md14
-rw-r--r--doc/api/deployments.md2
-rw-r--r--doc/api/discussions.md78
-rw-r--r--doc/api/environments.md8
-rw-r--r--doc/api/epic_issues.md14
-rw-r--r--doc/api/epic_links.md10
-rw-r--r--doc/api/epics.md20
-rw-r--r--doc/api/error_tracking.md6
-rw-r--r--doc/api/events.md6
-rw-r--r--doc/api/feature_flag_specs.md25
-rw-r--r--doc/api/feature_flag_user_lists.md16
-rw-r--r--doc/api/feature_flags.md368
-rw-r--r--doc/api/feature_flags_legacy.md317
-rw-r--r--doc/api/features.md10
-rw-r--r--doc/api/geo_nodes.md20
-rw-r--r--doc/api/graphql/index.md6
-rw-r--r--doc/api/graphql/reference/gitlab_schema.graphql2128
-rw-r--r--doc/api/graphql/reference/gitlab_schema.json5927
-rw-r--r--doc/api/graphql/reference/index.md279
-rw-r--r--doc/api/group_activity_analytics.md6
-rw-r--r--doc/api/group_badges.md12
-rw-r--r--doc/api/group_boards.md26
-rw-r--r--doc/api/group_clusters.md10
-rw-r--r--doc/api/group_import_export.md10
-rw-r--r--doc/api/group_labels.md20
-rw-r--r--doc/api/group_level_variables.md2
-rw-r--r--doc/api/group_milestones.md13
-rw-r--r--doc/api/groups.md85
-rw-r--r--doc/api/import.md2
-rw-r--r--doc/api/instance_level_ci_variables.md5
-rw-r--r--doc/api/issues.md56
-rw-r--r--doc/api/issues_statistics.md6
-rw-r--r--doc/api/jobs.md88
-rw-r--r--doc/api/keys.md10
-rw-r--r--doc/api/labels.md14
-rw-r--r--doc/api/lint.md2
-rw-r--r--doc/api/managed_licenses.md2
-rw-r--r--doc/api/markdown.md8
-rw-r--r--doc/api/members.md62
-rw-r--r--doc/api/merge_request_approvals.md30
-rw-r--r--doc/api/merge_requests.md36
-rw-r--r--doc/api/merge_trains.md10
-rw-r--r--doc/api/metrics_dashboard_annotations.md6
-rw-r--r--doc/api/milestones.md15
-rw-r--r--doc/api/namespaces.md8
-rw-r--r--doc/api/notes.md38
-rw-r--r--doc/api/notification_settings.md12
-rw-r--r--doc/api/oauth2.md11
-rw-r--r--doc/api/packages.md20
-rw-r--r--doc/api/pages.md8
-rw-r--r--doc/api/pages_domains.md30
-rw-r--r--doc/api/pipeline_schedules.md24
-rw-r--r--doc/api/project_aliases.md2
-rw-r--r--doc/api/project_badges.md12
-rw-r--r--doc/api/project_clusters.md10
-rw-r--r--doc/api/project_import_export.md16
-rw-r--r--doc/api/project_repository_storage_moves.md137
-rw-r--r--doc/api/project_snippets.md14
-rw-r--r--doc/api/project_templates.md4
-rw-r--r--doc/api/project_vulnerabilities.md16
-rw-r--r--doc/api/projects.md38
-rw-r--r--doc/api/protected_branches.md12
-rw-r--r--doc/api/protected_environments.md10
-rw-r--r--doc/api/protected_tags.md8
-rw-r--r--doc/api/releases/index.md27
-rw-r--r--doc/api/releases/links.md36
-rw-r--r--doc/api/remote_mirrors.md12
-rw-r--r--doc/api/repositories.md2
-rw-r--r--doc/api/repository_files.md18
-rw-r--r--doc/api/repository_submodules.md2
-rw-r--r--doc/api/resource_label_events.md12
-rw-r--r--doc/api/resource_milestone_events.md224
-rw-r--r--doc/api/runners.md6
-rw-r--r--doc/api/scim.md8
-rw-r--r--doc/api/search.md64
-rw-r--r--doc/api/services.md6
-rw-r--r--doc/api/settings.md9
-rw-r--r--doc/api/sidekiq_metrics.md8
-rw-r--r--doc/api/snippets.md18
-rw-r--r--doc/api/statistics.md2
-rw-r--r--doc/api/suggestions.md2
-rw-r--r--doc/api/system_hooks.md6
-rw-r--r--doc/api/tags.md4
-rw-r--r--doc/api/todos.md12
-rw-r--r--doc/api/users.md165
-rw-r--r--doc/api/v3_to_v4.md2
-rw-r--r--doc/api/version.md2
-rw-r--r--doc/api/visual_review_discussions.md2
-rw-r--r--doc/api/vulnerabilities.md12
-rw-r--r--doc/api/vulnerability_exports.md16
-rw-r--r--doc/api/vulnerability_findings.md10
-rw-r--r--doc/api/wikis.md6
-rw-r--r--doc/articles/how_to_configure_ldap_gitlab_ce/index.md4
-rw-r--r--doc/articles/how_to_configure_ldap_gitlab_ee/index.md4
-rw-r--r--doc/articles/index.md2
-rw-r--r--doc/ci/README.md48
-rw-r--r--doc/ci/caching/index.md9
-rw-r--r--doc/ci/chatops/README.md3
-rw-r--r--doc/ci/ci_cd_for_external_repos/bitbucket_integration.md3
-rw-r--r--doc/ci/ci_cd_for_external_repos/github_integration.md13
-rw-r--r--doc/ci/ci_cd_for_external_repos/index.md9
-rw-r--r--doc/ci/cloud_deployment/index.md67
-rw-r--r--doc/ci/directed_acyclic_graph/img/dag_graph_example_clicked_v13_1.pngbin0 -> 54491 bytes
-rw-r--r--doc/ci/directed_acyclic_graph/img/dag_graph_example_v13_1.pngbin0 -> 54919 bytes
-rw-r--r--doc/ci/directed_acyclic_graph/index.md36
-rw-r--r--doc/ci/docker/README.md3
-rw-r--r--doc/ci/docker/using_docker_build.md73
-rw-r--r--doc/ci/docker/using_docker_images.md28
-rw-r--r--doc/ci/docker/using_kaniko.md11
-rw-r--r--doc/ci/enable_or_disable_ci.md3
-rw-r--r--doc/ci/environments/deployment_safety.md106
-rw-r--r--doc/ci/environments/environments_dashboard.md2
-rw-r--r--doc/ci/environments/incremental_rollouts.md30
-rw-r--r--doc/ci/environments/index.md31
-rw-r--r--doc/ci/environments/protected_environments.md2
-rw-r--r--doc/ci/examples/README.md60
-rw-r--r--doc/ci/examples/artifactory_and_gitlab/index.md17
-rw-r--r--doc/ci/examples/authenticating-with-hashicorp-vault/index.md3
-rw-r--r--doc/ci/examples/deploy_spring_boot_to_cloud_foundry/index.md5
-rw-r--r--doc/ci/examples/deployment/README.md5
-rw-r--r--doc/ci/examples/deployment/composer-npm-deploy.md11
-rw-r--r--doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/index.md13
-rw-r--r--doc/ci/examples/end_to_end_testing_webdriverio/index.md3
-rw-r--r--doc/ci/examples/laravel_with_gitlab_and_envoy/index.md7
-rw-r--r--doc/ci/examples/php.md11
-rw-r--r--doc/ci/examples/test-and-deploy-python-application-to-heroku.md3
-rw-r--r--doc/ci/examples/test-and-deploy-ruby-application-to-heroku.md3
-rw-r--r--doc/ci/examples/test-clojure-application.md3
-rw-r--r--doc/ci/examples/test-scala-application.md3
-rw-r--r--doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/index.md13
-rw-r--r--doc/ci/git_submodules.md3
-rw-r--r--doc/ci/interactive_web_terminal/index.md9
-rw-r--r--doc/ci/introduction/index.md3
-rw-r--r--doc/ci/jenkins/index.md25
-rw-r--r--doc/ci/junit_test_reports.md32
-rw-r--r--doc/ci/large_repositories/index.md13
-rw-r--r--doc/ci/merge_request_pipelines/index.md7
-rw-r--r--doc/ci/merge_request_pipelines/pipelines_for_merged_results/index.md13
-rw-r--r--doc/ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.md15
-rw-r--r--doc/ci/metrics_reports.md7
-rw-r--r--doc/ci/migration/circleci.md332
-rw-r--r--doc/ci/multi_project_pipelines.md21
-rw-r--r--doc/ci/parent_child_pipelines.md9
-rw-r--r--doc/ci/pipelines/img/code_coverage_graph_v13_1.pngbin0 -> 29299 bytes
-rw-r--r--doc/ci/pipelines/index.md15
-rw-r--r--doc/ci/pipelines/job_artifacts.md35
-rw-r--r--doc/ci/pipelines/pipeline_architectures.md3
-rw-r--r--doc/ci/pipelines/schedules.md3
-rw-r--r--doc/ci/pipelines/settings.md41
-rw-r--r--doc/ci/quick_start/README.md7
-rw-r--r--doc/ci/review_apps/index.md15
-rw-r--r--doc/ci/runners/README.md482
-rw-r--r--doc/ci/services/README.md3
-rw-r--r--doc/ci/services/mysql.md5
-rw-r--r--doc/ci/services/postgres.md5
-rw-r--r--doc/ci/services/redis.md5
-rw-r--r--doc/ci/ssh_keys/README.md3
-rw-r--r--doc/ci/triggers/README.md7
-rw-r--r--doc/ci/variables/README.md178
-rw-r--r--doc/ci/variables/deprecated_variables.md3
-rw-r--r--doc/ci/variables/img/ci_job_stage_output_example.pngbin156322 -> 55081 bytes
-rw-r--r--doc/ci/variables/img/inherited_group_variables_v12_5.pngbin58215 -> 20448 bytes
-rw-r--r--doc/ci/variables/img/override_value_via_manual_pipeline_output.pngbin310224 -> 110898 bytes
-rw-r--r--doc/ci/variables/img/override_variable_manual_pipeline.pngbin52678 -> 17876 bytes
-rw-r--r--doc/ci/variables/predefined_variables.md19
-rw-r--r--doc/ci/variables/where_variables_can_be_used.md7
-rw-r--r--doc/ci/yaml/README.md254
-rw-r--r--doc/ci/yaml/includes.md7
-rw-r--r--doc/development/README.md47
-rw-r--r--doc/development/adding_database_indexes.md4
-rw-r--r--doc/development/api_graphql_styleguide.md277
-rw-r--r--doc/development/api_styleguide.md67
-rw-r--r--doc/development/application_limits.md35
-rw-r--r--doc/development/architecture.md42
-rw-r--r--doc/development/background_migrations.md4
-rw-r--r--doc/development/build_test_package.md6
-rw-r--r--doc/development/changelog.md6
-rw-r--r--doc/development/cicd/index.md4
-rw-r--r--doc/development/code_comments.md2
-rw-r--r--doc/development/code_review.md23
-rw-r--r--doc/development/contributing/index.md105
-rw-r--r--doc/development/contributing/issue_workflow.md14
-rw-r--r--doc/development/contributing/merge_request_workflow.md2
-rw-r--r--doc/development/creating_enums.md2
-rw-r--r--doc/development/database/index.md48
-rw-r--r--doc/development/database/not_null_constraints.md217
-rw-r--r--doc/development/database/strings_and_the_text_data_type.md288
-rw-r--r--doc/development/database_debugging.md6
-rw-r--r--doc/development/database_review.md14
-rw-r--r--doc/development/db_dump.md4
-rw-r--r--doc/development/deleting_migrations.md4
-rw-r--r--doc/development/distributed_tracing.md2
-rw-r--r--doc/development/documentation/feature_flags.md22
-rw-r--r--doc/development/documentation/index.md65
-rw-r--r--doc/development/documentation/site_architecture/global_nav.md2
-rw-r--r--doc/development/documentation/site_architecture/index.md22
-rw-r--r--doc/development/documentation/site_architecture/release_process.md26
-rw-r--r--doc/development/documentation/structure.md2
-rw-r--r--doc/development/documentation/styleguide.md145
-rw-r--r--doc/development/documentation/workflow.md8
-rw-r--r--doc/development/ee_features.md4
-rw-r--r--doc/development/elasticsearch.md63
-rw-r--r--doc/development/emails.md15
-rw-r--r--doc/development/fe_guide/axios.md16
-rw-r--r--doc/development/fe_guide/dependencies.md2
-rw-r--r--doc/development/fe_guide/development_process.md2
-rw-r--r--doc/development/fe_guide/droplab/plugins/ajax.md2
-rw-r--r--doc/development/fe_guide/droplab/plugins/filter.md2
-rw-r--r--doc/development/fe_guide/droplab/plugins/input_setter.md4
-rw-r--r--doc/development/fe_guide/emojis.md4
-rw-r--r--doc/development/fe_guide/frontend_faq.md4
-rw-r--r--doc/development/fe_guide/graphql.md107
-rw-r--r--doc/development/fe_guide/icons.md8
-rw-r--r--doc/development/fe_guide/performance.md2
-rw-r--r--doc/development/fe_guide/style/vue.md2
-rw-r--r--doc/development/fe_guide/vue.md10
-rw-r--r--doc/development/feature_flags/controls.md63
-rw-r--r--doc/development/feature_flags/development.md36
-rw-r--r--doc/development/filtering_by_label.md8
-rw-r--r--doc/development/geo.md6
-rw-r--r--doc/development/geo/framework.md11
-rw-r--r--doc/development/git_object_deduplication.md6
-rw-r--r--doc/development/gitaly.md10
-rw-r--r--doc/development/github_importer.md12
-rw-r--r--doc/development/go_guide/dependencies.md175
-rw-r--r--doc/development/go_guide/index.md22
-rw-r--r--doc/development/gotchas.md2
-rw-r--r--doc/development/hash_indexes.md4
-rw-r--r--doc/development/i18n/externalization.md20
-rw-r--r--doc/development/i18n/merging_translations.md21
-rw-r--r--doc/development/i18n/proofreader.md22
-rw-r--r--doc/development/i18n/translation.md14
-rw-r--r--doc/development/img/bullet_v13_0.pngbin0 -> 1085958 bytes
-rw-r--r--doc/development/import_export.md55
-rw-r--r--doc/development/insert_into_tables_in_batches.md2
-rw-r--r--doc/development/instrumentation.md6
-rw-r--r--doc/development/integrations/jenkins.md2
-rw-r--r--doc/development/integrations/secure.md38
-rw-r--r--doc/development/integrations/secure_partner_integration.md14
-rw-r--r--doc/development/internal_api.md4
-rw-r--r--doc/development/issue_types.md4
-rw-r--r--doc/development/licensing.md8
-rw-r--r--doc/development/logging.md6
-rw-r--r--doc/development/merge_request_performance_guidelines.md4
-rw-r--r--doc/development/migration_style_guide.md27
-rw-r--r--doc/development/module_with_instance_variables.md4
-rw-r--r--doc/development/multi_version_compatibility.md2
-rw-r--r--doc/development/namespaces_storage_statistics.md10
-rw-r--r--doc/development/new_fe_guide/development/accessibility.md4
-rw-r--r--doc/development/new_fe_guide/development/performance.md4
-rw-r--r--doc/development/omnibus.md2
-rw-r--r--doc/development/packages.md10
-rw-r--r--doc/development/performance.md3
-rw-r--r--doc/development/permissions.md25
-rw-r--r--doc/development/pipelines.md423
-rw-r--r--doc/development/polling.md2
-rw-r--r--doc/development/profiling.md10
-rw-r--r--doc/development/rake_tasks.md8
-rw-r--r--doc/development/redis.md4
-rw-r--r--doc/development/refactoring_guide/index.md8
-rw-r--r--doc/development/reference_processing.md2
-rw-r--r--doc/development/renaming_features.md2
-rw-r--r--doc/development/routing.md12
-rw-r--r--doc/development/scalability.md22
-rw-r--r--doc/development/secure_coding_guidelines.md38
-rw-r--r--doc/development/service_measurement.md81
-rw-r--r--doc/development/shell_scripting_guide/index.md2
-rw-r--r--doc/development/sidekiq_style_guide.md118
-rw-r--r--doc/development/telemetry/index.md100
-rw-r--r--doc/development/telemetry/snowplow.md16
-rw-r--r--doc/development/telemetry/usage_ping.md898
-rw-r--r--doc/development/testing_guide/best_practices.md83
-rw-r--r--doc/development/testing_guide/end_to_end/best_practices.md2
-rw-r--r--doc/development/testing_guide/end_to_end/feature_flags.md2
-rw-r--r--doc/development/testing_guide/end_to_end/index.md20
-rw-r--r--doc/development/testing_guide/end_to_end/page_objects.md8
-rw-r--r--doc/development/testing_guide/end_to_end/rspec_metadata_tests.md3
-rw-r--r--doc/development/testing_guide/end_to_end/running_tests_that_require_special_setup.md12
-rw-r--r--doc/development/testing_guide/end_to_end/style_guide.md8
-rw-r--r--doc/development/testing_guide/flaky_tests.md36
-rw-r--r--doc/development/testing_guide/frontend_testing.md42
-rw-r--r--doc/development/testing_guide/index.md4
-rw-r--r--doc/development/testing_guide/review_apps.md22
-rw-r--r--doc/development/testing_guide/testing_levels.md4
-rw-r--r--doc/development/understanding_explain_plans.md34
-rw-r--r--doc/development/uploads.md6
-rw-r--r--doc/development/utilities.md4
-rw-r--r--doc/development/value_stream_analytics.md2
-rw-r--r--doc/development/what_requires_downtime.md36
-rw-r--r--doc/development/windows.md14
-rw-r--r--doc/gitlab-basics/create-project.md4
-rw-r--r--doc/gitlab-basics/start-using-git.md7
-rw-r--r--doc/install/aws/img/aws_ha_architecture_diagram.pngbin42452 -> 144735 bytes
-rw-r--r--doc/install/aws/img/rds_subnet_group.pngbin30107 -> 0 bytes
-rw-r--r--doc/install/aws/index.md49
-rw-r--r--doc/install/azure/index.md2
-rw-r--r--doc/install/digitaloceandocker.md12
-rw-r--r--doc/install/google_cloud_platform/img/boot_disk.pngbin37786 -> 0 bytes
-rw-r--r--doc/install/google_cloud_platform/img/vm_details.pngbin50191 -> 77743 bytes
-rw-r--r--doc/install/google_cloud_platform/index.md8
-rw-r--r--doc/install/installation.md45
-rw-r--r--doc/install/ldap.md4
-rw-r--r--doc/install/openshift_and_gitlab/index.md4
-rw-r--r--doc/install/requirements.md160
-rw-r--r--doc/integration/akismet.md22
-rw-r--r--doc/integration/azure.md40
-rw-r--r--doc/integration/elasticsearch.md21
-rw-r--r--doc/integration/gmail_action_buttons_for_gitlab.md2
-rw-r--r--doc/integration/img/ultra_auth_credentials.pngbin53737 -> 0 bytes
-rw-r--r--doc/integration/img/ultra_auth_edit_callback_url.pngbin39410 -> 0 bytes
-rw-r--r--doc/integration/img/ultra_auth_edit_callback_url_highlighted.pngbin68383 -> 0 bytes
-rw-r--r--doc/integration/jira_development_panel.md6
-rw-r--r--doc/integration/kerberos.md4
-rw-r--r--doc/integration/ldap.md4
-rw-r--r--doc/integration/omniauth.md1
-rw-r--r--doc/integration/saml.md2
-rw-r--r--doc/integration/ultra_auth.md87
-rw-r--r--doc/integration/vault.md8
-rw-r--r--doc/policy/maintenance.md204
-rw-r--r--doc/public_access/public_access.md6
-rw-r--r--doc/push_rules/push_rules.md6
-rw-r--r--doc/raketasks/README.md4
-rw-r--r--doc/raketasks/backup_restore.md14
-rw-r--r--doc/raketasks/cleanup.md15
-rw-r--r--doc/raketasks/import.md12
-rw-r--r--doc/raketasks/migrate_snippets.md4
-rw-r--r--doc/security/img/allowlist_v13_0.pngbin0 -> 16076 bytes
-rw-r--r--doc/security/img/whitelist.pngbin10650 -> 0 bytes
-rw-r--r--doc/security/rack_attack.md3
-rw-r--r--doc/security/webhooks.md20
-rw-r--r--doc/ssh/README.md85
-rw-r--r--doc/subscriptions/index.md16
-rw-r--r--doc/system_hooks/system_hooks.md8
-rw-r--r--doc/topics/airgap/index.md142
-rw-r--r--doc/topics/airgap/quick_start_guide.md157
-rw-r--r--doc/topics/authentication/index.md7
-rw-r--r--doc/topics/autodevops/customize.md43
-rw-r--r--doc/topics/autodevops/img/guide_pipeline_stages_v12_3.pngbin40329 -> 0 bytes
-rw-r--r--doc/topics/autodevops/img/guide_pipeline_stages_v13_0.pngbin0 -> 65686 bytes
-rw-r--r--doc/topics/autodevops/index.md205
-rw-r--r--doc/topics/autodevops/quick_start_guide.md14
-rw-r--r--doc/topics/autodevops/requirements.md134
-rw-r--r--doc/topics/autodevops/stages.md60
-rw-r--r--doc/topics/git/feature_branch_development.md86
-rw-r--r--doc/topics/git/img/create_merge_request_v13_1.pngbin0 -> 16387 bytes
-rw-r--r--doc/topics/git/img/modify_branches_v13_1.pngbin0 -> 75159 bytes
-rw-r--r--doc/topics/git/index.md3
-rw-r--r--doc/topics/git/lfs/index.md20
-rw-r--r--doc/topics/git/lfs/migrate_from_git_annex_to_git_lfs.md6
-rw-r--r--doc/topics/git/lfs/migrate_to_git_lfs.md12
-rw-r--r--doc/topics/git/numerous_undo_possibilities_in_git/index.md5
-rw-r--r--doc/topics/git/partial_clone.md4
-rw-r--r--doc/topics/gitlab_flow.md2
-rw-r--r--doc/topics/index.md1
-rw-r--r--doc/topics/offline/index.md138
-rw-r--r--doc/topics/offline/quick_start_guide.md157
-rw-r--r--doc/topics/web_application_firewall/index.md4
-rw-r--r--doc/topics/web_application_firewall/quick_start_guide.md4
-rw-r--r--doc/university/README.md6
-rw-r--r--doc/university/support/README.md202
-rw-r--r--doc/university/training/user_training.md4
-rw-r--r--doc/update/README.md14
-rw-r--r--doc/update/patch_versions.md9
-rw-r--r--doc/update/upgrading_from_ce_to_ee.md2
-rw-r--r--doc/update/upgrading_from_source.md39
-rw-r--r--doc/update/upgrading_postgresql_using_slony.md4
-rw-r--r--doc/user/admin_area/abuse_reports.md3
-rw-r--r--doc/user/admin_area/activating_deactivating_users.md9
-rw-r--r--doc/user/admin_area/appearance.md6
-rw-r--r--doc/user/admin_area/blocking_unblocking_users.md3
-rw-r--r--doc/user/admin_area/broadcast_messages.md2
-rw-r--r--doc/user/admin_area/credentials_inventory.md7
-rw-r--r--doc/user/admin_area/custom_project_templates.md5
-rw-r--r--doc/user/admin_area/diff_limits.md3
-rw-r--r--doc/user/admin_area/geo_nodes.md3
-rw-r--r--doc/user/admin_area/labels.md3
-rw-r--r--doc/user/admin_area/license.md7
-rw-r--r--doc/user/admin_area/merge_requests_approvals.md5
-rw-r--r--doc/user/admin_area/settings/account_and_limit_settings.md15
-rw-r--r--doc/user/admin_area/settings/continuous_integration.md7
-rw-r--r--doc/user/admin_area/settings/email.md4
-rw-r--r--doc/user/admin_area/settings/external_authorization.md6
-rw-r--r--doc/user/admin_area/settings/gitaly_timeouts.md2
-rw-r--r--doc/user/admin_area/settings/img/rate_limit_on_issues_creation.pngbin11476 -> 0 bytes
-rw-r--r--doc/user/admin_area/settings/img/rate_limit_on_issues_creation_v13_1.pngbin0 -> 13479 bytes
-rw-r--r--doc/user/admin_area/settings/index.md2
-rw-r--r--doc/user/admin_area/settings/instance_template_repository.md2
-rw-r--r--doc/user/admin_area/settings/push_event_activities_limit.md2
-rw-r--r--doc/user/admin_area/settings/rate_limit_on_issues_creation.md5
-rw-r--r--doc/user/admin_area/settings/visibility_and_access_controls.md2
-rw-r--r--doc/user/analytics/code_review_analytics.md5
-rw-r--r--doc/user/analytics/img/vsa_time_metrics_v13_0.pngbin0 -> 240523 bytes
-rw-r--r--doc/user/analytics/index.md7
-rw-r--r--doc/user/analytics/productivity_analytics.md9
-rw-r--r--doc/user/analytics/repository_analytics.md4
-rw-r--r--doc/user/analytics/value_stream_analytics.md28
-rw-r--r--doc/user/application_security/configuration/index.md3
-rw-r--r--doc/user/application_security/container_scanning/index.md217
-rw-r--r--doc/user/application_security/dast/index.md111
-rw-r--r--doc/user/application_security/dependency_list/index.md15
-rw-r--r--doc/user/application_security/dependency_scanning/index.md162
-rw-r--r--doc/user/application_security/img/security_configuration_page_v13_1.pngbin63337 -> 199472 bytes
-rw-r--r--doc/user/application_security/img/vulnerability-check_v13_0.pngbin0 -> 51019 bytes
-rw-r--r--doc/user/application_security/index.md48
-rw-r--r--doc/user/application_security/offline_deployments/index.md5
-rw-r--r--doc/user/application_security/sast/analyzers.md8
-rw-r--r--doc/user/application_security/sast/index.md89
-rw-r--r--doc/user/application_security/secret_detection/index.md119
-rw-r--r--doc/user/application_security/security_dashboard/img/group_security_dashboard_export_csv_v13_1.pngbin0 -> 536756 bytes
-rw-r--r--doc/user/application_security/security_dashboard/img/group_security_dashboard_v13_0.pngbin212401 -> 69236 bytes
-rw-r--r--doc/user/application_security/security_dashboard/img/project_security_dashboard_v13_0.pngbin199457 -> 66337 bytes
-rw-r--r--doc/user/application_security/security_dashboard/index.md23
-rw-r--r--doc/user/application_security/threat_monitoring/index.md52
-rw-r--r--doc/user/application_security/vulnerabilities/img/standalone_vulnerability_page_download_patch_button_v13_1.pngbin0 -> 8979 bytes
-rw-r--r--doc/user/application_security/vulnerabilities/img/standalone_vulnerability_page_merge_request_button_dropdown_v13_1.pngbin0 -> 144464 bytes
-rw-r--r--doc/user/application_security/vulnerabilities/img/standalone_vulnerability_page_merge_request_button_v13_1.pngbin0 -> 40058 bytes
-rw-r--r--doc/user/application_security/vulnerabilities/index.md28
-rw-r--r--doc/user/award_emojis.md12
-rw-r--r--doc/user/clusters/applications.md107
-rw-r--r--doc/user/clusters/crossplane.md2
-rw-r--r--doc/user/clusters/environments.md4
-rw-r--r--doc/user/clusters/management_project.md2
-rw-r--r--doc/user/compliance/compliance_dashboard/index.md5
-rw-r--r--doc/user/compliance/index.md7
-rw-r--r--doc/user/compliance/license_compliance/index.md245
-rw-r--r--doc/user/discussions/img/add_another_suggestion_to_batch_v13_1.jpgbin0 -> 23078 bytes
-rw-r--r--doc/user/discussions/img/add_first_suggestion_to_batch_v13_1.jpgbin0 -> 24694 bytes
-rw-r--r--doc/user/discussions/img/apply_batch_of_suggestions_v13_1.jpgbin0 -> 26551 bytes
-rw-r--r--doc/user/discussions/img/quickly_assign_commenter_v13_1.pngbin0 -> 216812 bytes
-rw-r--r--doc/user/discussions/img/remove_suggestion_from_batch_v13_1.jpgbin0 -> 24101 bytes
-rw-r--r--doc/user/discussions/img/suggestions_custom_commit_messages_v12_7.pngbin21720 -> 0 bytes
-rw-r--r--doc/user/discussions/img/suggestions_custom_commit_messages_v13_1.jpgbin0 -> 35055 bytes
-rw-r--r--doc/user/discussions/index.md86
-rw-r--r--doc/user/feature_highlight.md4
-rw-r--r--doc/user/gitlab_com/index.md87
-rw-r--r--doc/user/group/bulk_editing/index.md87
-rw-r--r--doc/user/group/clusters/index.md10
-rw-r--r--doc/user/group/contribution_analytics/img/group_stats_table.pngbin8473 -> 22691 bytes
-rw-r--r--doc/user/group/contribution_analytics/index.md7
-rw-r--r--doc/user/group/custom_project_templates.md5
-rw-r--r--doc/user/group/epics/img/bulk_editing.pngbin72912 -> 0 bytes
-rw-r--r--doc/user/group/epics/img/issue_list_v13_1.pngbin0 -> 24946 bytes
-rw-r--r--doc/user/group/epics/index.md17
-rw-r--r--doc/user/group/epics/manage_epics.md83
-rw-r--r--doc/user/group/img/ldap_sync_cn_v13_1.pngbin0 -> 120390 bytes
-rw-r--r--doc/user/group/img/ldap_sync_filter_v13_1.pngbin0 -> 135425 bytes
-rw-r--r--doc/user/group/img/manual_permissions_v13_1.pngbin0 -> 31008 bytes
-rw-r--r--doc/user/group/index.md89
-rw-r--r--doc/user/group/insights/index.md3
-rw-r--r--doc/user/group/issues_analytics/img/issues_table_v13_1.pngbin0 -> 125190 bytes
-rw-r--r--doc/user/group/issues_analytics/index.md18
-rw-r--r--doc/user/group/iterations/index.md85
-rw-r--r--doc/user/group/roadmap/index.md13
-rw-r--r--doc/user/group/saml_sso/index.md23
-rw-r--r--doc/user/group/saml_sso/scim_setup.md5
-rw-r--r--doc/user/group/settings/img/export_panel.pngbin200162 -> 0 bytes
-rw-r--r--doc/user/group/settings/img/export_panel_v13_0.pngbin0 -> 47857 bytes
-rw-r--r--doc/user/group/settings/img/import_panel_v13_1.pngbin0 -> 23446 bytes
-rw-r--r--doc/user/group/settings/img/new_group_navigation_v13_1.pngbin0 -> 83427 bytes
-rw-r--r--doc/user/group/settings/import_export.md42
-rw-r--r--doc/user/group/subgroups/index.md4
-rw-r--r--doc/user/incident_management/index.md81
-rw-r--r--doc/user/infrastructure/index.md345
-rw-r--r--doc/user/instance/clusters/index.md5
-rw-r--r--doc/user/instance_statistics/dev_ops_score.md4
-rw-r--r--doc/user/instance_statistics/index.md2
-rw-r--r--doc/user/instance_statistics/user_cohorts.md4
-rw-r--r--doc/user/markdown.md35
-rw-r--r--doc/user/operations_dashboard/index.md2
-rw-r--r--doc/user/packages/composer_repository/index.md155
-rw-r--r--doc/user/packages/conan_repository/index.md12
-rw-r--r--doc/user/packages/container_registry/img/container_registry_group_repositories_v13_0.pngbin41813 -> 0 bytes
-rw-r--r--doc/user/packages/container_registry/img/container_registry_group_repositories_v13_1.pngbin0 -> 45865 bytes
-rw-r--r--doc/user/packages/container_registry/img/container_registry_repositories_v13_0.pngbin44925 -> 0 bytes
-rw-r--r--doc/user/packages/container_registry/img/container_registry_repositories_v13_1.pngbin0 -> 46734 bytes
-rw-r--r--doc/user/packages/container_registry/img/container_registry_repositories_with_quickstart_v13_0.pngbin48708 -> 0 bytes
-rw-r--r--doc/user/packages/container_registry/img/container_registry_repositories_with_quickstart_v13_1.pngbin0 -> 51791 bytes
-rw-r--r--doc/user/packages/container_registry/index.md98
-rw-r--r--doc/user/packages/dependency_proxy/index.md8
-rw-r--r--doc/user/packages/go_proxy/index.md169
-rw-r--r--doc/user/packages/index.md35
-rw-r--r--doc/user/packages/maven_repository/index.md8
-rw-r--r--doc/user/packages/npm_registry/index.md16
-rw-r--r--doc/user/packages/nuget_repository/index.md10
-rw-r--r--doc/user/packages/pypi_repository/index.md6
-rw-r--r--doc/user/permissions.md26
-rw-r--r--doc/user/profile/account/create_accounts.md5
-rw-r--r--doc/user/profile/account/delete_account.md3
-rw-r--r--doc/user/profile/account/two_factor_authentication.md12
-rw-r--r--doc/user/profile/active_sessions.md2
-rw-r--r--doc/user/profile/img/unknown_sign_in_email_v13_1.pngbin0 -> 20230 bytes
-rw-r--r--doc/user/profile/index.md27
-rw-r--r--doc/user/profile/notifications.md7
-rw-r--r--doc/user/profile/personal_access_tokens.md55
-rw-r--r--doc/user/profile/preferences.md23
-rw-r--r--doc/user/profile/unknown_sign_in_notification.md11
-rw-r--r--doc/user/project/badges.md2
-rw-r--r--doc/user/project/bulk_editing.md66
-rw-r--r--doc/user/project/canary_deployments.md2
-rw-r--r--doc/user/project/clusters/add_eks_clusters.md147
-rw-r--r--doc/user/project/clusters/add_gke_clusters.md13
-rw-r--r--doc/user/project/clusters/add_remove_clusters.md260
-rw-r--r--doc/user/project/clusters/index.md13
-rw-r--r--doc/user/project/clusters/kubernetes_pod_logs.md12
-rw-r--r--doc/user/project/clusters/runbooks/index.md2
-rw-r--r--doc/user/project/clusters/serverless/aws.md12
-rw-r--r--doc/user/project/clusters/serverless/index.md22
-rw-r--r--doc/user/project/code_owners.md28
-rw-r--r--doc/user/project/deploy_boards.md15
-rw-r--r--doc/user/project/deploy_keys/img/deploy_keys_v13_0.pngbin0 -> 74337 bytes
-rw-r--r--doc/user/project/deploy_keys/img/public_deploy_key_v13_0.pngbin0 -> 45326 bytes
-rw-r--r--doc/user/project/deploy_keys/index.md164
-rw-r--r--doc/user/project/deploy_tokens/index.md11
-rw-r--r--doc/user/project/description_templates.md8
-rw-r--r--doc/user/project/img/status_page_detail_link_v13_1.pngbin0 -> 107718 bytes
-rw-r--r--doc/user/project/import/bitbucket.md7
-rw-r--r--doc/user/project/import/bitbucket_server.md7
-rw-r--r--doc/user/project/import/clearcase.md7
-rw-r--r--doc/user/project/import/cvs.md7
-rw-r--r--doc/user/project/import/fogbugz.md7
-rw-r--r--doc/user/project/import/gemnasium.md7
-rw-r--r--doc/user/project/import/gitea.md7
-rw-r--r--doc/user/project/import/github.md7
-rw-r--r--doc/user/project/import/gitlab_com.md7
-rw-r--r--doc/user/project/import/index.md11
-rw-r--r--doc/user/project/import/jira.md7
-rw-r--r--doc/user/project/import/manifest.md9
-rw-r--r--doc/user/project/import/perforce.md7
-rw-r--r--doc/user/project/import/phabricator.md9
-rw-r--r--doc/user/project/import/repo_by_url.md7
-rw-r--r--doc/user/project/import/svn.md11
-rw-r--r--doc/user/project/import/tfvc.md2
-rw-r--r--doc/user/project/index.md17
-rw-r--r--doc/user/project/insights/index.md2
-rw-r--r--doc/user/project/integrations/bamboo.md2
-rw-r--r--doc/user/project/integrations/custom_issue_tracker.md43
-rw-r--r--doc/user/project/integrations/generic_alerts.md12
-rw-r--r--doc/user/project/integrations/github.md4
-rw-r--r--doc/user/project/integrations/gitlab_slack_application.md4
-rw-r--r--doc/user/project/integrations/hangouts_chat.md2
-rw-r--r--doc/user/project/integrations/img/prometheus_dashboard_yaml_validation_v13_1.pngbin0 -> 27694 bytes
-rw-r--r--doc/user/project/integrations/img/prometheus_monitoring_dashboard_v12_8.pngbin29683 -> 0 bytes
-rw-r--r--doc/user/project/integrations/img/prometheus_monitoring_dashboard_v13_1.pngbin0 -> 40765 bytes
-rw-r--r--doc/user/project/integrations/img/related_links_v13_1.pngbin0 -> 4086 bytes
-rw-r--r--doc/user/project/integrations/img/slack_configuration.pngbin41458 -> 0 bytes
-rw-r--r--doc/user/project/integrations/jira_cloud_configuration.md2
-rw-r--r--doc/user/project/integrations/prometheus.md161
-rw-r--r--doc/user/project/integrations/prometheus_units.md4
-rw-r--r--doc/user/project/integrations/slack.md18
-rw-r--r--doc/user/project/integrations/webex_teams.md2
-rw-r--r--doc/user/project/integrations/webhooks.md2
-rw-r--r--doc/user/project/issue_board.md20
-rw-r--r--doc/user/project/issues/associate_zoom_meeting.md6
-rw-r--r--doc/user/project/issues/confidential_issues.md8
-rw-r--r--doc/user/project/issues/crosslinking_issues.md6
-rw-r--r--doc/user/project/issues/design_management.md87
-rw-r--r--doc/user/project/issues/due_dates.md6
-rw-r--r--doc/user/project/issues/img/new_issue.pngbin28734 -> 0 bytes
-rw-r--r--doc/user/project/issues/img/new_issue_v13_1.pngbin0 -> 69721 bytes
-rw-r--r--doc/user/project/issues/img/resolve_design-discussion_checkbox_v13_1.pngbin0 -> 56634 bytes
-rw-r--r--doc/user/project/issues/img/resolve_design-discussion_icon_v13_1.pngbin0 -> 36747 bytes
-rw-r--r--doc/user/project/issues/index.md10
-rw-r--r--doc/user/project/issues/issue_data_and_actions.md16
-rw-r--r--doc/user/project/issues/issue_weight.md3
-rw-r--r--doc/user/project/issues/managing_issues.md56
-rw-r--r--doc/user/project/issues/multiple_assignees_for_issues.md8
-rw-r--r--doc/user/project/issues/related_issues.md6
-rw-r--r--doc/user/project/issues/sorting_issue_lists.md10
-rw-r--r--doc/user/project/labels.md14
-rw-r--r--doc/user/project/members/index.md4
-rw-r--r--doc/user/project/members/share_project_with_groups.md2
-rw-r--r--doc/user/project/merge_requests/accessibility_testing.md10
-rw-r--r--doc/user/project/merge_requests/browser_performance_testing.md4
-rw-r--r--doc/user/project/merge_requests/cherry_pick_changes.md2
-rw-r--r--doc/user/project/merge_requests/code_quality.md64
-rw-r--r--doc/user/project/merge_requests/creating_merge_requests.md6
-rw-r--r--doc/user/project/merge_requests/getting_started.md4
-rw-r--r--doc/user/project/merge_requests/index.md32
-rw-r--r--doc/user/project/merge_requests/merge_request_approvals.md29
-rw-r--r--doc/user/project/merge_requests/merge_request_dependencies.md8
-rw-r--r--doc/user/project/merge_requests/merge_when_pipeline_succeeds.md15
-rw-r--r--doc/user/project/merge_requests/reviewing_and_managing_merge_requests.md8
-rw-r--r--doc/user/project/merge_requests/test_coverage_visualization.md4
-rw-r--r--doc/user/project/merge_requests/testing_and_reports_in_merge_requests.md36
-rw-r--r--doc/user/project/merge_requests/versions.md6
-rw-r--r--doc/user/project/milestones/burndown_charts.md3
-rw-r--r--doc/user/project/milestones/index.md3
-rw-r--r--doc/user/project/new_ci_build_permissions_model.md15
-rw-r--r--doc/user/project/operations/alert_management.md107
-rw-r--r--doc/user/project/operations/dashboard_settings.md47
-rw-r--r--doc/user/project/operations/error_tracking.md6
-rw-r--r--doc/user/project/operations/feature_flags.md201
-rw-r--r--doc/user/project/operations/img/alert_detail_full_v13_1.pngbin0 -> 26957 bytes
-rw-r--r--doc/user/project/operations/img/alert_detail_overview_v13_1.pngbin0 -> 14827 bytes
-rw-r--r--doc/user/project/operations/img/alert_detail_system_notes_v13_1.pngbin0 -> 22329 bytes
-rw-r--r--doc/user/project/operations/img/alert_detail_v13_0.pngbin24097 -> 0 bytes
-rw-r--r--doc/user/project/operations/img/alert_details_assignees_v13_1.pngbin0 -> 31091 bytes
-rw-r--r--doc/user/project/operations/img/alert_issue_v13_1.pngbin0 -> 38546 bytes
-rw-r--r--doc/user/project/operations/img/alert_list_assignees_v13_1.pngbin0 -> 29011 bytes
-rw-r--r--doc/user/project/operations/img/alert_management_1_v13_1.pngbin57133 -> 40053 bytes
-rw-r--r--doc/user/project/operations/img/alert_todo_assignees_v13_1.pngbin0 -> 10157 bytes
-rw-r--r--doc/user/project/operations/img/dashboard_external_link_v13_1.pngbin0 -> 12708 bytes
-rw-r--r--doc/user/project/operations/img/dashboard_local_timezone_v13_1.pngbin0 -> 65094 bytes
-rw-r--r--doc/user/project/operations/img/external_dashboard_settings.pngbin33248 -> 0 bytes
-rw-r--r--doc/user/project/operations/index.md2
-rw-r--r--doc/user/project/operations/linking_to_an_external_dashboard.md22
-rw-r--r--doc/user/project/pages/custom_domains_ssl_tls_certification/index.md5
-rw-r--r--doc/user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration.md4
-rw-r--r--doc/user/project/pages/getting_started/fork_sample_project.md108
-rw-r--r--doc/user/project/pages/getting_started/new_or_existing_website.md63
-rw-r--r--doc/user/project/pages/getting_started/pages_bundled_template.md33
-rw-r--r--doc/user/project/pages/getting_started_part_four.md433
-rw-r--r--doc/user/project/pages/img/change_path_v12_10.pngbin29490 -> 61162 bytes
-rw-r--r--doc/user/project/pages/img/choose_ci_template.pngbin23532 -> 0 bytes
-rw-r--r--doc/user/project/pages/img/choose_ci_template_v13_1.pngbin0 -> 33333 bytes
-rw-r--r--doc/user/project/pages/img/pages_project_templates_v11_8.pngbin69675 -> 0 bytes
-rw-r--r--doc/user/project/pages/img/pages_project_templates_v13_1.pngbin0 -> 181998 bytes
-rw-r--r--doc/user/project/pages/img/remove_fork_relationship.pngbin13642 -> 0 bytes
-rw-r--r--doc/user/project/pages/img/remove_fork_relationship_v13_1.pngbin0 -> 34206 bytes
-rw-r--r--doc/user/project/pages/img/setup_ci.pngbin10032 -> 0 bytes
-rw-r--r--doc/user/project/pages/img/setup_ci_v13_1.pngbin0 -> 15480 bytes
-rw-r--r--doc/user/project/pages/index.md145
-rw-r--r--doc/user/project/pages/introduction.md6
-rw-r--r--doc/user/project/pages/lets_encrypt_for_gitlab_pages.md2
-rw-r--r--doc/user/project/pages/pages_access_control.md2
-rw-r--r--doc/user/project/protected_branches.md12
-rw-r--r--doc/user/project/protected_tags.md6
-rw-r--r--doc/user/project/push_options.md8
-rw-r--r--doc/user/project/quick_actions.md131
-rw-r--r--doc/user/project/releases/index.md37
-rw-r--r--doc/user/project/repository/forking_workflow.md2
-rw-r--r--doc/user/project/repository/git_blame.md2
-rw-r--r--doc/user/project/repository/img/repository_cleanup.pngbin8114 -> 0 bytes
-rw-r--r--doc/user/project/repository/index.md16
-rw-r--r--doc/user/project/repository/jupyter_notebooks/index.md2
-rw-r--r--doc/user/project/repository/reducing_the_repo_size_using_git.md274
-rw-r--r--doc/user/project/repository/repository_mirroring.md28
-rw-r--r--doc/user/project/repository/x509_signed_commits/index.md4
-rw-r--r--doc/user/project/requirements/img/requirement_edit_save_v12_10.pngbin123899 -> 0 bytes
-rw-r--r--doc/user/project/requirements/index.md105
-rw-r--r--doc/user/project/service_desk.md43
-rw-r--r--doc/user/project/settings/import_export.md16
-rw-r--r--doc/user/project/settings/index.md19
-rw-r--r--doc/user/project/settings/project_access_tokens.md32
-rw-r--r--doc/user/project/status_page/index.md30
-rw-r--r--doc/user/project/time_tracking.md3
-rw-r--r--doc/user/project/web_ide/index.md52
-rw-r--r--doc/user/project/wiki/index.md10
-rw-r--r--doc/user/search/advanced_global_search.md7
-rw-r--r--doc/user/search/advanced_search_syntax.md7
-rw-r--r--doc/user/search/index.md22
-rw-r--r--doc/user/shortcuts.md2
-rw-r--r--doc/user/snippets.md8
-rw-r--r--doc/user/todos.md3
-rw-r--r--jest.config.js (renamed from jest.config.unit.js)0
-rw-r--r--lib/api/api.rb2
-rw-r--r--lib/api/deploy_keys.rb5
-rw-r--r--lib/api/discussions.rb2
-rw-r--r--lib/api/entities/bridge.rb9
-rw-r--r--lib/api/entities/container_registry.rb1
-rw-r--r--lib/api/entities/group_detail.rb3
-rw-r--r--lib/api/entities/merge_request_basic.rb8
-rw-r--r--lib/api/entities/project.rb4
-rw-r--r--lib/api/entities/releases/evidence.rb2
-rw-r--r--lib/api/entities/releases/link.rb1
-rw-r--r--lib/api/entities/resource_milestone_event.rb20
-rw-r--r--lib/api/entities/runner_details.rb7
-rw-r--r--lib/api/entities/shared_group.rb17
-rw-r--r--lib/api/entities/shared_group_with_group.rb17
-rw-r--r--lib/api/entities/shared_group_with_project.rb17
-rw-r--r--lib/api/entities/ssh_key.rb3
-rw-r--r--lib/api/entities/user_with_admin.rb3
-rw-r--r--lib/api/features.rb4
-rw-r--r--lib/api/group_container_repositories.rb3
-rw-r--r--lib/api/group_export.rb6
-rw-r--r--lib/api/group_import.rb9
-rw-r--r--lib/api/groups.rb57
-rw-r--r--lib/api/helpers.rb2
-rw-r--r--lib/api/helpers/issues_helpers.rb2
-rw-r--r--lib/api/helpers/notes_helpers.rb2
-rw-r--r--lib/api/helpers/projects_helpers.rb2
-rw-r--r--lib/api/helpers/runner.rb32
-rw-r--r--lib/api/helpers/services_helpers.rb12
-rw-r--r--lib/api/issues.rb9
-rw-r--r--lib/api/jobs.rb26
-rw-r--r--lib/api/lsif_data.rb40
-rw-r--r--lib/api/merge_requests.rb9
-rw-r--r--lib/api/project_container_repositories.rb9
-rw-r--r--lib/api/project_export.rb4
-rw-r--r--lib/api/project_import.rb5
-rw-r--r--lib/api/project_repository_storage_moves.rb57
-rw-r--r--lib/api/projects.rb4
-rw-r--r--lib/api/release/links.rb2
-rw-r--r--lib/api/releases.rb11
-rw-r--r--lib/api/repositories.rb4
-rw-r--r--lib/api/resource_label_events.rb5
-rw-r--r--lib/api/resource_milestone_events.rb54
-rw-r--r--lib/api/runner.rb18
-rw-r--r--lib/api/search.rb15
-rw-r--r--lib/api/settings.rb6
-rw-r--r--lib/api/suggestions.rb43
-rw-r--r--lib/api/terraform/state.rb10
-rw-r--r--lib/api/todos.rb10
-rw-r--r--lib/api/users.rb19
-rw-r--r--lib/api/validations/validators/file_path.rb2
-rw-r--r--lib/api/validations/validators/untrusted_regexp.rb19
-rw-r--r--lib/api/wikis.rb2
-rw-r--r--lib/backup/files.rb3
-rw-r--r--lib/banzai/filter/ascii_doc_sanitization_filter.rb3
-rw-r--r--lib/banzai/filter/design_reference_filter.rb121
-rw-r--r--lib/banzai/filter/external_issue_reference_filter.rb36
-rw-r--r--lib/banzai/filter/gollum_tags_filter.rb20
-rw-r--r--lib/banzai/filter/issue_reference_filter.rb14
-rw-r--r--lib/banzai/filter/iteration_reference_filter.rb16
-rw-r--r--lib/banzai/filter/label_reference_filter.rb15
-rw-r--r--lib/banzai/filter/reference_filter.rb6
-rw-r--r--lib/banzai/filter/repository_link_filter.rb4
-rw-r--r--lib/banzai/filter/wiki_link_filter.rb10
-rw-r--r--lib/banzai/pipeline/gfm_pipeline.rb1
-rw-r--r--lib/banzai/reference_parser/iteration_parser.rb22
-rw-r--r--lib/event_filter.rb10
-rw-r--r--lib/extracts_path.rb124
-rw-r--r--lib/extracts_ref.rb128
-rw-r--r--lib/feature.rb105
-rw-r--r--lib/gitaly/server.rb9
-rw-r--r--lib/gitlab.rb9
-rw-r--r--lib/gitlab/alert_management/alert_params.rb3
-rw-r--r--lib/gitlab/alert_management/fingerprint.rb27
-rw-r--r--lib/gitlab/alerting/alert.rb11
-rw-r--r--lib/gitlab/alerting/notification_payload_parser.rb7
-rw-r--r--lib/gitlab/analytics/cycle_analytics/base_query_builder.rb56
-rw-r--r--lib/gitlab/analytics/cycle_analytics/median.rb4
-rw-r--r--lib/gitlab/analytics/cycle_analytics/records_fetcher.rb20
-rw-r--r--lib/gitlab/application_rate_limiter.rb9
-rw-r--r--lib/gitlab/auth/auth_finders.rb1
-rw-r--r--lib/gitlab/auth/ldap/person.rb2
-rw-r--r--lib/gitlab/auth/o_auth/provider.rb4
-rw-r--r--lib/gitlab/background_migration/.rubocop.yml2
-rw-r--r--lib/gitlab/background_migration/backfill_project_repositories.rb2
-rw-r--r--lib/gitlab/background_migration/fix_projects_without_prometheus_service.rb2
-rw-r--r--lib/gitlab/background_migration/fix_ruby_object_in_audit_events.rb13
-rw-r--r--lib/gitlab/background_migration/migrate_fingerprint_sha256_within_keys.rb2
-rw-r--r--lib/gitlab/background_migration/migrate_issue_trackers_sensitive_data.rb2
-rw-r--r--lib/gitlab/background_migration/populate_cluster_kubernetes_namespace_table.rb2
-rw-r--r--lib/gitlab/background_migration/populate_untracked_uploads.rb2
-rw-r--r--lib/gitlab/background_migration/reset_merge_status.rb2
-rw-r--r--lib/gitlab/background_migration/user_mentions/create_resource_user_mention.rb2
-rw-r--r--lib/gitlab/badge/coverage/report.rb10
-rw-r--r--lib/gitlab/badge/coverage/template.rb14
-rw-r--r--lib/gitlab/badge/pipeline/status.rb8
-rw-r--r--lib/gitlab/badge/pipeline/template.rb14
-rw-r--r--lib/gitlab/badge/template.rb2
-rw-r--r--lib/gitlab/bitbucket_import/importer.rb2
-rw-r--r--lib/gitlab/cache/import/caching.rb11
-rw-r--r--lib/gitlab/ci/build/releaser.rb24
-rw-r--r--lib/gitlab/ci/build/step.rb13
-rw-r--r--lib/gitlab/ci/config/entry/job.rb2
-rw-r--r--lib/gitlab/ci/config/entry/reports.rb7
-rw-r--r--lib/gitlab/ci/features.rb30
-rw-r--r--lib/gitlab/ci/parsers/terraform/tfplan.rb24
-rw-r--r--lib/gitlab/ci/pipeline/chain/command.rb19
-rw-r--r--lib/gitlab/ci/pipeline/chain/metrics.rb35
-rw-r--r--lib/gitlab/ci/pipeline/chain/seed.rb1
-rw-r--r--lib/gitlab/ci/pipeline/chain/sequence.rb1
-rw-r--r--lib/gitlab/ci/reports/terraform_reports.rb8
-rw-r--r--lib/gitlab/ci/status/bridge/failed.rb8
-rw-r--r--lib/gitlab/ci/status/core.rb2
-rw-r--r--lib/gitlab/ci/templates/AWS/Deploy-ECS.gitlab-ci.yml13
-rw-r--r--lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Deploy-ECS.gitlab-ci.yml18
-rw-r--r--lib/gitlab/ci/templates/Jobs/Browser-Performance-Testing.gitlab-ci.yml4
-rw-r--r--lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml4
-rw-r--r--lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml4
-rw-r--r--lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/Jobs/Deploy/ECS.gitlab-ci.yml18
-rw-r--r--lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml7
-rw-r--r--lib/gitlab/ci/templates/Rust.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Security/License-Scanning.gitlab-ci.yml1
-rw-r--r--lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml9
-rw-r--r--lib/gitlab/ci/templates/Security/Secret-Detection.gitlab-ci.yml24
-rw-r--r--lib/gitlab/ci/templates/Terraform.gitlab-ci.yml1
-rw-r--r--lib/gitlab/ci/templates/Verify/FailFast.gitlab-ci.yml17
-rw-r--r--lib/gitlab/ci/trace.rb2
-rw-r--r--lib/gitlab/ci/yaml_processor.rb2
-rw-r--r--lib/gitlab/code_navigation_path.rb2
-rw-r--r--lib/gitlab/config/loader/yaml.rb8
-rw-r--r--lib/gitlab/contributions_calendar.rb8
-rw-r--r--lib/gitlab/cycle_analytics/summary/commit.rb2
-rw-r--r--lib/gitlab/cycle_analytics/summary/deploy.rb2
-rw-r--r--lib/gitlab/cycle_analytics/summary/issue.rb2
-rw-r--r--lib/gitlab/cycle_analytics/summary/value.rb12
-rw-r--r--lib/gitlab/danger/emoji_checker.rb6
-rw-r--r--lib/gitlab/danger/helper.rb2
-rw-r--r--lib/gitlab/danger/request_helper.rb2
-rw-r--r--lib/gitlab/danger/roulette.rb67
-rw-r--r--lib/gitlab/data_builder/alert.rb27
-rw-r--r--lib/gitlab/data_builder/note.rb2
-rw-r--r--lib/gitlab/database/custom_structure.rb44
-rw-r--r--lib/gitlab/database/migration_helpers.rb14
-rw-r--r--lib/gitlab/database/partitioning_migration_helpers.rb116
-rw-r--r--lib/gitlab/database/partitioning_migration_helpers/foreign_key_helpers.rb140
-rw-r--r--lib/gitlab/database/partitioning_migration_helpers/table_management_helpers.rb198
-rw-r--r--lib/gitlab/database/schema_cleaner.rb18
-rw-r--r--lib/gitlab/database/schema_helpers.rb36
-rw-r--r--lib/gitlab/dependency_linker.rb4
-rw-r--r--lib/gitlab/dependency_linker/go_mod_linker.rb34
-rw-r--r--lib/gitlab/dependency_linker/go_sum_linker.rb38
-rw-r--r--lib/gitlab/diff/file.rb8
-rw-r--r--lib/gitlab/diff/formatters/base_formatter.rb11
-rw-r--r--lib/gitlab/diff/position.rb13
-rw-r--r--lib/gitlab/doctor/secrets.rb87
-rw-r--r--lib/gitlab/error_tracking.rb3
-rw-r--r--lib/gitlab/error_tracking/processor/sidekiq_processor.rb66
-rw-r--r--lib/gitlab/exception_log_formatter.rb10
-rw-r--r--lib/gitlab/experimentation.rb15
-rw-r--r--lib/gitlab/export/logger.rb11
-rw-r--r--lib/gitlab/file_detector.rb2
-rw-r--r--lib/gitlab/gfm/uploads_rewriter.rb15
-rw-r--r--lib/gitlab/git/commit.rb15
-rw-r--r--lib/gitlab/git/diff.rb2
-rw-r--r--lib/gitlab/git/rugged_impl/use_rugged.rb5
-rw-r--r--lib/gitlab/git_access.rb37
-rw-r--r--lib/gitlab/git_access_project.rb44
-rw-r--r--lib/gitlab/git_access_snippet.rb13
-rw-r--r--lib/gitlab/git_access_wiki.rb8
-rw-r--r--lib/gitlab/gitaly_client.rb12
-rw-r--r--lib/gitlab/gitaly_client/commit_service.rb9
-rw-r--r--lib/gitlab/github_import/bulk_importing.rb2
-rw-r--r--lib/gitlab/github_import/importer/diff_note_importer.rb2
-rw-r--r--lib/gitlab/github_import/importer/issue_importer.rb2
-rw-r--r--lib/gitlab/github_import/importer/label_links_importer.rb2
-rw-r--r--lib/gitlab/github_import/importer/lfs_objects_importer.rb5
-rw-r--r--lib/gitlab/github_import/importer/note_importer.rb2
-rw-r--r--lib/gitlab/github_import/importer/pull_requests_importer.rb6
-rw-r--r--lib/gitlab/gl_repository.rb19
-rw-r--r--lib/gitlab/gl_repository/identifier.rb74
-rw-r--r--lib/gitlab/gl_repository/repo_type.rb27
-rw-r--r--lib/gitlab/golang.rb99
-rw-r--r--lib/gitlab/graphql/authorize/authorize_field_service.rb14
-rw-r--r--lib/gitlab/graphql/authorize/instrumentation.rb6
-rw-r--r--lib/gitlab/graphql/filterable_array.rb14
-rw-r--r--lib/gitlab/graphql/loaders/full_path_model_loader.rb26
-rw-r--r--lib/gitlab/graphql/pagination/connections.rb4
-rw-r--r--lib/gitlab/graphql/pagination/filterable_array_connection.rb17
-rw-r--r--lib/gitlab/graphql/pagination/keyset/connection.rb100
-rw-r--r--lib/gitlab/import/database_helpers.rb2
-rw-r--r--lib/gitlab/import/set_async_jid.rb7
-rw-r--r--lib/gitlab/import_export/attributes_finder.rb2
-rw-r--r--lib/gitlab/import_export/attributes_permitter.rb105
-rw-r--r--lib/gitlab/import_export/importer.rb18
-rw-r--r--lib/gitlab/import_export/json/streaming_serializer.rb15
-rw-r--r--lib/gitlab/import_export/legacy_relation_tree_saver.rb8
-rw-r--r--lib/gitlab/import_export/members_mapper.rb2
-rw-r--r--lib/gitlab/import_export/merge_request_parser.rb8
-rw-r--r--lib/gitlab/import_export/project/import_export.yml2
-rw-r--r--lib/gitlab/import_export/repo_restorer.rb2
-rw-r--r--lib/gitlab/import_export/saver.rb21
-rw-r--r--lib/gitlab/import_export/snippet_repo_restorer.rb13
-rw-r--r--lib/gitlab/import_export/snippets_repo_restorer.rb6
-rw-r--r--lib/gitlab/import_export/version_checker.rb6
-rw-r--r--lib/gitlab/instrumentation/elasticsearch_transport.rb68
-rw-r--r--lib/gitlab/instrumentation/redis.rb81
-rw-r--r--lib/gitlab/instrumentation/redis_base.rb102
-rw-r--r--lib/gitlab/instrumentation/redis_interceptor.rb86
-rw-r--r--lib/gitlab/instrumentation/redis_payload.rb37
-rw-r--r--lib/gitlab/instrumentation_helper.rb54
-rw-r--r--lib/gitlab/issuable_metadata.rb101
-rw-r--r--lib/gitlab/jira/http_client.rb7
-rw-r--r--lib/gitlab/jira_import.rb40
-rw-r--r--lib/gitlab/jira_import/base_importer.rb2
-rw-r--r--lib/gitlab/jira_import/issues_importer.rb32
-rw-r--r--lib/gitlab/kubernetes/helm.rb6
-rw-r--r--lib/gitlab/kubernetes/helm/base_command.rb31
-rw-r--r--lib/gitlab/kubernetes/helm/client_command.rb4
-rw-r--r--lib/gitlab/kubernetes/helm/delete_command.rb14
-rw-r--r--lib/gitlab/kubernetes/helm/init_command.rb16
-rw-r--r--lib/gitlab/kubernetes/helm/install_command.rb15
-rw-r--r--lib/gitlab/kubernetes/helm/patch_command.rb16
-rw-r--r--lib/gitlab/kubernetes/helm/reset_command.rb15
-rw-r--r--lib/gitlab/kubernetes/network_policy.rb45
-rw-r--r--lib/gitlab/lfs_token.rb2
-rw-r--r--lib/gitlab/lograge/custom_options.rb18
-rw-r--r--lib/gitlab/looping_batcher.rb99
-rw-r--r--lib/gitlab/metrics/dashboard/stages/url_validator.rb19
-rw-r--r--lib/gitlab/metrics/elasticsearch_rack_middleware.rb41
-rw-r--r--lib/gitlab/metrics/methods.rb2
-rw-r--r--lib/gitlab/metrics/redis_rack_middleware.rb39
-rw-r--r--lib/gitlab/metrics/samplers/base_sampler.rb4
-rw-r--r--lib/gitlab/metrics/samplers/puma_sampler.rb2
-rw-r--r--lib/gitlab/metrics/samplers/ruby_sampler.rb3
-rw-r--r--lib/gitlab/metrics/sidekiq_middleware.rb15
-rw-r--r--lib/gitlab/metrics/subscribers/active_record.rb18
-rw-r--r--lib/gitlab/metrics/transaction.rb10
-rw-r--r--lib/gitlab/middleware/handle_ip_spoof_attack_error.rb33
-rw-r--r--lib/gitlab/monitor/demo_projects.rb27
-rw-r--r--lib/gitlab/pagination/keyset/request_context.rb4
-rw-r--r--lib/gitlab/pagination/offset_pagination.rb8
-rw-r--r--lib/gitlab/phabricator_import/cache/map.rb2
-rw-r--r--lib/gitlab/phabricator_import/worker_state.rb2
-rw-r--r--lib/gitlab/process_memory_cache/helper.rb51
-rw-r--r--lib/gitlab/project_search_results.rb26
-rw-r--r--lib/gitlab/project_template.rb10
-rw-r--r--lib/gitlab/prometheus/query_variables.rb14
-rw-r--r--lib/gitlab/prometheus_client.rb13
-rw-r--r--lib/gitlab/quick_actions/merge_request_actions.rb17
-rw-r--r--lib/gitlab/redis/cache.rb4
-rw-r--r--lib/gitlab/redis/queues.rb4
-rw-r--r--lib/gitlab/redis/shared_state.rb4
-rw-r--r--lib/gitlab/redis/wrapper.rb6
-rw-r--r--lib/gitlab/reference_extractor.rb2
-rw-r--r--lib/gitlab/regex.rb90
-rw-r--r--lib/gitlab/routing.rb42
-rw-r--r--lib/gitlab/rugged_instrumentation.rb7
-rw-r--r--lib/gitlab/search_context.rb162
-rw-r--r--lib/gitlab/search_results.rb2
-rw-r--r--lib/gitlab/setup_helper.rb4
-rw-r--r--lib/gitlab/sidekiq_config.rb4
-rw-r--r--lib/gitlab/sidekiq_config/cli_methods.rb7
-rw-r--r--lib/gitlab/sidekiq_config/dummy_worker.rb3
-rw-r--r--lib/gitlab/sidekiq_config/worker.rb5
-rw-r--r--lib/gitlab/sidekiq_logging/json_formatter.rb18
-rw-r--r--lib/gitlab/sidekiq_logging/structured_logger.rb7
-rw-r--r--lib/gitlab/sidekiq_middleware/duplicate_jobs/client.rb3
-rw-r--r--lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb45
-rw-r--r--lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executing.rb26
-rw-r--r--lib/gitlab/sidekiq_middleware/server_metrics.rb42
-rw-r--r--lib/gitlab/slash_commands/presenters/help.rb2
-rw-r--r--lib/gitlab/snippet_search_results.rb2
-rw-r--r--lib/gitlab/sourcegraph.rb2
-rw-r--r--lib/gitlab/suggestions/commit_message.rb54
-rw-r--r--lib/gitlab/suggestions/file_suggestion.rb107
-rw-r--r--lib/gitlab/suggestions/suggestion_set.rb120
-rw-r--r--lib/gitlab/themes.rb3
-rw-r--r--lib/gitlab/url_builder.rb23
-rw-r--r--lib/gitlab/usage_data.rb169
-rw-r--r--lib/gitlab/usage_data_concerns/topology.rb137
-rw-r--r--lib/gitlab/usage_data_counters/base_counter.rb6
-rw-r--r--lib/gitlab/usage_data_counters/designs_counter.rb2
-rw-r--r--lib/gitlab/usage_data_counters/search_counter.rb24
-rw-r--r--lib/gitlab/utils.rb21
-rw-r--r--lib/gitlab/utils/log_limited_array.rb4
-rw-r--r--lib/gitlab/utils/usage_data.rb110
-rw-r--r--lib/gitlab/web_ide/config.rb44
-rw-r--r--lib/gitlab/web_ide/config/entry/global.rb29
-rw-r--r--lib/gitlab/web_ide/config/entry/terminal.rb75
-rw-r--r--lib/milestone_array.rb42
-rw-r--r--lib/object_storage/direct_upload.rb30
-rw-r--r--lib/peek/views/bullet_detailed.rb47
-rw-r--r--lib/peek/views/elasticsearch.rb47
-rw-r--r--lib/peek/views/gitaly.rb6
-rw-r--r--lib/peek/views/redis_detailed.rb7
-rw-r--r--lib/quality/test_level.rb1
-rwxr-xr-xlib/support/init.d/gitlab58
-rw-r--r--lib/tasks/gemojione.rake16
-rw-r--r--lib/tasks/gitlab/container_registry.rake35
-rw-r--r--lib/tasks/gitlab/db.rake35
-rw-r--r--lib/tasks/gitlab/doctor/secrets.rake12
-rw-r--r--lib/tasks/gitlab/features.rake2
-rw-r--r--lib/tasks/gitlab/shell.rake15
-rw-r--r--locale/am_ET/gitlab.po2304
-rw-r--r--locale/ar_SA/gitlab.po2348
-rw-r--r--locale/az_AZ/gitlab.po27339
-rw-r--r--locale/bg/gitlab.po2312
-rw-r--r--locale/bn_BD/gitlab.po2304
-rw-r--r--locale/bn_IN/gitlab.po2304
-rw-r--r--locale/bs_BA/gitlab.po2321
-rw-r--r--locale/ca_ES/gitlab.po2346
-rw-r--r--locale/cs_CZ/gitlab.po2326
-rw-r--r--locale/cy_GB/gitlab.po2348
-rw-r--r--locale/da_DK/gitlab.po2310
-rw-r--r--locale/de/gitlab.po2470
-rw-r--r--locale/el_GR/gitlab.po2304
-rw-r--r--locale/eo/gitlab.po2312
-rw-r--r--locale/es/gitlab.po3154
-rw-r--r--locale/et_EE/gitlab.po2304
-rw-r--r--locale/fa_IR/gitlab.po2304
-rw-r--r--locale/fi_FI/gitlab.po2304
-rw-r--r--locale/fil_PH/gitlab.po2304
-rw-r--r--locale/fr/gitlab.po2334
-rw-r--r--locale/gitlab.pot1632
-rw-r--r--locale/gl_ES/gitlab.po2304
-rw-r--r--locale/he_IL/gitlab.po2326
-rw-r--r--locale/hi_IN/gitlab.po2304
-rw-r--r--locale/hr_HR/gitlab.po2315
-rw-r--r--locale/hu_HU/gitlab.po2304
-rw-r--r--locale/id_ID/gitlab.po2293
-rw-r--r--locale/is_IS/gitlab.po27339
-rw-r--r--locale/it/gitlab.po2312
-rw-r--r--locale/ja/gitlab.po6453
-rw-r--r--locale/ka_GE/gitlab.po2304
-rw-r--r--locale/ko/gitlab.po2329
-rw-r--r--locale/ku_TR/gitlab.po2304
-rw-r--r--locale/mn_MN/gitlab.po2304
-rw-r--r--locale/nb_NO/gitlab.po2304
-rw-r--r--locale/nl_NL/gitlab.po2304
-rw-r--r--locale/pa_IN/gitlab.po2304
-rw-r--r--locale/pl_PL/gitlab.po2328
-rw-r--r--locale/pt_BR/gitlab.po2360
-rw-r--r--locale/pt_PT/gitlab.po2320
-rw-r--r--locale/ro_RO/gitlab.po2315
-rw-r--r--locale/ru/gitlab.po3834
-rw-r--r--locale/sk_SK/gitlab.po2326
-rw-r--r--locale/sl_SI/gitlab.po2326
-rw-r--r--locale/sq_AL/gitlab.po2304
-rw-r--r--locale/sr_CS/gitlab.po2319
-rw-r--r--locale/sr_SP/gitlab.po2315
-rw-r--r--locale/sv_SE/gitlab.po2304
-rw-r--r--locale/sw_KE/gitlab.po2304
-rw-r--r--locale/tr_TR/gitlab.po3086
-rw-r--r--locale/uk/gitlab.po3202
-rw-r--r--locale/ur_PK/gitlab.po2304
-rw-r--r--locale/uz_UZ/gitlab.po2304
-rw-r--r--locale/vi_VN/gitlab.po2293
-rw-r--r--locale/zh_CN/gitlab.po2441
-rw-r--r--locale/zh_HK/gitlab.po2305
-rw-r--r--locale/zh_TW/gitlab.po2307
-rw-r--r--package.json47
-rw-r--r--public/-/emojis/1/emojis.json10760
-rw-r--r--public/robots.txt1
-rw-r--r--qa/Dockerfile28
-rw-r--r--qa/Gemfile2
-rw-r--r--qa/Gemfile.lock6
-rw-r--r--qa/qa.rb35
-rw-r--r--qa/qa/flow/project.rb12
-rw-r--r--qa/qa/git/repository.rb2
-rw-r--r--qa/qa/page/base.rb25
-rw-r--r--qa/qa/page/component/issue_board/show.rb138
-rw-r--r--qa/qa/page/component/web_ide/modal/create_new_file.rb19
-rw-r--r--qa/qa/page/dashboard/snippet/new.rb17
-rw-r--r--qa/qa/page/dashboard/snippet/show.rb38
-rw-r--r--qa/qa/page/group/new.rb2
-rw-r--r--qa/qa/page/issuable/new.rb58
-rw-r--r--qa/qa/page/merge_request/new.rb53
-rw-r--r--qa/qa/page/merge_request/show.rb89
-rw-r--r--qa/qa/page/project/fork/new.rb4
-rw-r--r--qa/qa/page/project/issue/new.rb18
-rw-r--r--qa/qa/page/project/members.rb60
-rw-r--r--qa/qa/page/project/menu.rb14
-rw-r--r--qa/qa/page/project/new_experiment.rb26
-rw-r--r--qa/qa/page/project/operations/metrics/show.rb3
-rw-r--r--qa/qa/page/project/settings/advanced.rb4
-rw-r--r--qa/qa/page/project/settings/ci_cd.rb2
-rw-r--r--qa/qa/page/project/settings/integrations.rb7
-rw-r--r--qa/qa/page/project/settings/main.rb2
-rw-r--r--qa/qa/page/project/settings/members.rb62
-rw-r--r--qa/qa/page/project/settings/services/jira.rb60
-rw-r--r--qa/qa/page/project/snippet/new.rb29
-rw-r--r--qa/qa/page/project/sub_menus/settings.rb9
-rw-r--r--qa/qa/page/project/web_ide/edit.rb22
-rw-r--r--qa/qa/page/project/wiki/edit.rb30
-rw-r--r--qa/qa/page/project/wiki/new.rb61
-rw-r--r--qa/qa/page/project/wiki/show.rb57
-rw-r--r--qa/qa/resource/group.rb5
-rw-r--r--qa/qa/resource/issue.rb4
-rw-r--r--qa/qa/resource/project.rb36
-rw-r--r--qa/qa/resource/project_milestone.rb7
-rw-r--r--qa/qa/resource/project_snippet.rb29
-rw-r--r--qa/qa/resource/protected_branch.rb33
-rw-r--r--qa/qa/resource/repository/project_push.rb4
-rw-r--r--qa/qa/resource/repository/push.rb6
-rw-r--r--qa/qa/resource/repository/wiki_push.rb17
-rw-r--r--qa/qa/resource/sandbox.rb1
-rw-r--r--qa/qa/resource/ssh_key.rb17
-rw-r--r--qa/qa/resource/wiki.rb48
-rw-r--r--qa/qa/resource/wiki/project_page.rb68
-rw-r--r--qa/qa/runtime/api/repository_storage_moves.rb33
-rw-r--r--qa/qa/runtime/env.rb12
-rw-r--r--qa/qa/runtime/feature.rb37
-rw-r--r--qa/qa/scenario/test/instance/airgapped.rb19
-rw-r--r--qa/qa/service/docker_run/base.rb9
-rw-r--r--qa/qa/service/docker_run/gitlab_runner.rb19
-rw-r--r--qa/qa/service/docker_run/jenkins.rb8
-rw-r--r--qa/qa/specs/features/api/3_create/repository/changing_repository_storage_spec.rb53
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb21
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb4
-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/3_create/jira/jira_basic_integration_spec.rb105
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb10
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb101
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_spec.rb29
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_spec.rb30
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/create_snippet_spec.rb29
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb39
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/wiki/create_edit_clone_push_wiki_spec.rb42
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/wiki/project_based_content_creation_spec.rb93
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/wiki/project_based_content_manipulation_spec.rb51
-rw-r--r--qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_dependent_relationship_spec.rb12
-rw-r--r--qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb12
-rw-r--r--qa/qa/specs/features/browser_ui/7_configure/kubernetes/kubernetes_integration_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb111
-rw-r--r--qa/qa/support/api.rb23
-rw-r--r--qa/qa/support/repeater.rb5
-rw-r--r--qa/qa/vendor/jira/jira_api.rb54
-rw-r--r--qa/spec/runtime/feature_spec.rb31
-rw-r--r--qa/spec/scenario/test/instance/airgapped_spec.rb8
-rw-r--r--qa/spec/support/shared_examples/merge_with_code_owner_shared_examples.rb71
-rw-r--r--rubocop/cop/default_scope.rb24
-rw-r--r--rubocop/cop/gitlab/avoid_feature_get.rb27
-rw-r--r--rubocop/cop/gitlab/bulk_insert.rb23
-rw-r--r--rubocop/cop/inject_enterprise_edition_module.rb23
-rw-r--r--rubocop/cop/migration/add_limit_to_text_columns.rb3
-rw-r--r--rubocop/cop/migration/drop_table.rb52
-rw-r--r--rubocop/cop/migration/prevent_strings.rb3
-rw-r--r--rubocop/cop/migration/update_large_table.rb49
-rw-r--r--rubocop/cop/rspec/empty_line_after_shared_example.rb64
-rw-r--r--rubocop/migration_helpers.rb55
-rw-r--r--rubocop/rubocop-migrations.yml40
-rwxr-xr-xscripts/build_assets_image2
-rwxr-xr-xscripts/gemfile_lock_changed.sh2
-rwxr-xr-xscripts/gitaly-test-build1
-rw-r--r--scripts/gitaly_test.rb27
-rwxr-xr-xscripts/lint-changelog-filenames4
-rwxr-xr-xscripts/lint-conflicts.sh2
-rwxr-xr-xscripts/lint-doc.sh4
-rw-r--r--scripts/review_apps/base-config.yaml2
-rwxr-xr-xscripts/review_apps/review-apps.sh12
-rw-r--r--scripts/rspec_helpers.sh24
-rwxr-xr-xscripts/static-analysis181
-rw-r--r--scripts/sync-stable-branch.sh54
-rwxr-xr-xscripts/trigger-build26
-rw-r--r--scripts/utils.sh26
-rw-r--r--spec/bin/changelog_spec.rb2
-rw-r--r--spec/bin/sidekiq_cluster_spec.rb2
-rw-r--r--spec/channels/application_cable/connection_spec.rb2
-rw-r--r--spec/channels/issues_channel_spec.rb6
-rw-r--r--spec/config/application_spec.rb2
-rw-r--r--spec/config/mail_room_spec.rb2
-rw-r--r--spec/config/object_store_settings_spec.rb2
-rw-r--r--spec/config/settings_spec.rb2
-rw-r--r--spec/config/smime_signature_settings_spec.rb2
-rw-r--r--spec/controllers/abuse_reports_controller_spec.rb2
-rw-r--r--spec/controllers/acme_challenges_controller_spec.rb2
-rw-r--r--spec/controllers/admin/appearances_controller_spec.rb2
-rw-r--r--spec/controllers/admin/application_settings_controller_spec.rb14
-rw-r--r--spec/controllers/admin/applications_controller_spec.rb2
-rw-r--r--spec/controllers/admin/ci/variables_controller_spec.rb2
-rw-r--r--spec/controllers/admin/clusters/applications_controller_spec.rb2
-rw-r--r--spec/controllers/admin/clusters_controller_spec.rb9
-rw-r--r--spec/controllers/admin/dashboard_controller_spec.rb2
-rw-r--r--spec/controllers/admin/gitaly_servers_controller_spec.rb2
-rw-r--r--spec/controllers/admin/groups_controller_spec.rb2
-rw-r--r--spec/controllers/admin/health_check_controller_spec.rb2
-rw-r--r--spec/controllers/admin/hooks_controller_spec.rb2
-rw-r--r--spec/controllers/admin/identities_controller_spec.rb2
-rw-r--r--spec/controllers/admin/impersonations_controller_spec.rb2
-rw-r--r--spec/controllers/admin/integrations_controller_spec.rb14
-rw-r--r--spec/controllers/admin/projects_controller_spec.rb2
-rw-r--r--spec/controllers/admin/requests_profiles_controller_spec.rb2
-rw-r--r--spec/controllers/admin/runners_controller_spec.rb2
-rw-r--r--spec/controllers/admin/serverless/domains_controller_spec.rb2
-rw-r--r--spec/controllers/admin/services_controller_spec.rb2
-rw-r--r--spec/controllers/admin/sessions_controller_spec.rb2
-rw-r--r--spec/controllers/admin/spam_logs_controller_spec.rb2
-rw-r--r--spec/controllers/admin/users_controller_spec.rb28
-rw-r--r--spec/controllers/application_controller_spec.rb9
-rw-r--r--spec/controllers/autocomplete_controller_spec.rb2
-rw-r--r--spec/controllers/boards/issues_controller_spec.rb2
-rw-r--r--spec/controllers/boards/lists_controller_spec.rb2
-rw-r--r--spec/controllers/chaos_controller_spec.rb2
-rw-r--r--spec/controllers/concerns/boards_responses_spec.rb2
-rw-r--r--spec/controllers/concerns/checks_collaboration_spec.rb2
-rw-r--r--spec/controllers/concerns/confirm_email_warning_spec.rb2
-rw-r--r--spec/controllers/concerns/continue_params_spec.rb2
-rw-r--r--spec/controllers/concerns/controller_with_cross_project_access_check_spec.rb2
-rw-r--r--spec/controllers/concerns/enforces_admin_authentication_spec.rb2
-rw-r--r--spec/controllers/concerns/group_tree_spec.rb2
-rw-r--r--spec/controllers/concerns/import_url_params_spec.rb2
-rw-r--r--spec/controllers/concerns/internal_redirect_spec.rb2
-rw-r--r--spec/controllers/concerns/issuable_actions_spec.rb2
-rw-r--r--spec/controllers/concerns/issuable_collections_spec.rb2
-rw-r--r--spec/controllers/concerns/lfs_request_spec.rb2
-rw-r--r--spec/controllers/concerns/metrics_dashboard_spec.rb4
-rw-r--r--spec/controllers/concerns/page_limiter_spec.rb2
-rw-r--r--spec/controllers/concerns/project_unauthorized_spec.rb2
-rw-r--r--spec/controllers/concerns/redirects_for_missing_path_on_tree_spec.rb2
-rw-r--r--spec/controllers/concerns/renders_commits_spec.rb2
-rw-r--r--spec/controllers/concerns/routable_actions_spec.rb2
-rw-r--r--spec/controllers/concerns/send_file_upload_spec.rb2
-rw-r--r--spec/controllers/concerns/sorting_preference_spec.rb2
-rw-r--r--spec/controllers/concerns/sourcegraph_decorator_spec.rb8
-rw-r--r--spec/controllers/concerns/static_object_external_storage_spec.rb2
-rw-r--r--spec/controllers/dashboard/groups_controller_spec.rb2
-rw-r--r--spec/controllers/dashboard/labels_controller_spec.rb2
-rw-r--r--spec/controllers/dashboard/milestones_controller_spec.rb27
-rw-r--r--spec/controllers/dashboard/projects_controller_spec.rb2
-rw-r--r--spec/controllers/dashboard/snippets_controller_spec.rb2
-rw-r--r--spec/controllers/dashboard/todos_controller_spec.rb2
-rw-r--r--spec/controllers/dashboard_controller_spec.rb2
-rw-r--r--spec/controllers/explore/groups_controller_spec.rb2
-rw-r--r--spec/controllers/explore/projects_controller_spec.rb2
-rw-r--r--spec/controllers/explore/snippets_controller_spec.rb2
-rw-r--r--spec/controllers/google_api/authorizations_controller_spec.rb2
-rw-r--r--spec/controllers/graphql_controller_spec.rb2
-rw-r--r--spec/controllers/groups/avatars_controller_spec.rb2
-rw-r--r--spec/controllers/groups/boards_controller_spec.rb2
-rw-r--r--spec/controllers/groups/children_controller_spec.rb2
-rw-r--r--spec/controllers/groups/clusters/applications_controller_spec.rb2
-rw-r--r--spec/controllers/groups/clusters_controller_spec.rb9
-rw-r--r--spec/controllers/groups/group_links_controller_spec.rb2
-rw-r--r--spec/controllers/groups/group_members_controller_spec.rb2
-rw-r--r--spec/controllers/groups/imports_controller_spec.rb85
-rw-r--r--spec/controllers/groups/labels_controller_spec.rb2
-rw-r--r--spec/controllers/groups/milestones_controller_spec.rb81
-rw-r--r--spec/controllers/groups/registry/repositories_controller_spec.rb3
-rw-r--r--spec/controllers/groups/runners_controller_spec.rb2
-rw-r--r--spec/controllers/groups/settings/ci_cd_controller_spec.rb2
-rw-r--r--spec/controllers/groups/settings/integrations_controller_spec.rb2
-rw-r--r--spec/controllers/groups/settings/repository_controller_spec.rb2
-rw-r--r--spec/controllers/groups/shared_projects_controller_spec.rb2
-rw-r--r--spec/controllers/groups/uploads_controller_spec.rb2
-rw-r--r--spec/controllers/groups/variables_controller_spec.rb2
-rw-r--r--spec/controllers/groups_controller_spec.rb98
-rw-r--r--spec/controllers/health_check_controller_spec.rb2
-rw-r--r--spec/controllers/help_controller_spec.rb2
-rw-r--r--spec/controllers/ide_controller_spec.rb2
-rw-r--r--spec/controllers/import/bitbucket_controller_spec.rb38
-rw-r--r--spec/controllers/import/bitbucket_server_controller_spec.rb35
-rw-r--r--spec/controllers/import/fogbugz_controller_spec.rb13
-rw-r--r--spec/controllers/import/gitea_controller_spec.rb2
-rw-r--r--spec/controllers/import/github_controller_spec.rb2
-rw-r--r--spec/controllers/import/gitlab_controller_spec.rb13
-rw-r--r--spec/controllers/import/google_code_controller_spec.rb2
-rw-r--r--spec/controllers/import/phabricator_controller_spec.rb2
-rw-r--r--spec/controllers/instance_statistics/cohorts_controller_spec.rb2
-rw-r--r--spec/controllers/instance_statistics/dev_ops_score_controller_spec.rb2
-rw-r--r--spec/controllers/invites_controller_spec.rb2
-rw-r--r--spec/controllers/ldap/omniauth_callbacks_controller_spec.rb2
-rw-r--r--spec/controllers/metrics_controller_spec.rb2
-rw-r--r--spec/controllers/notification_settings_controller_spec.rb2
-rw-r--r--spec/controllers/oauth/applications_controller_spec.rb2
-rw-r--r--spec/controllers/oauth/authorizations_controller_spec.rb2
-rw-r--r--spec/controllers/oauth/authorized_applications_controller_spec.rb2
-rw-r--r--spec/controllers/omniauth_callbacks_controller_spec.rb4
-rw-r--r--spec/controllers/passwords_controller_spec.rb2
-rw-r--r--spec/controllers/profiles/accounts_controller_spec.rb2
-rw-r--r--spec/controllers/profiles/avatars_controller_spec.rb2
-rw-r--r--spec/controllers/profiles/emails_controller_spec.rb2
-rw-r--r--spec/controllers/profiles/keys_controller_spec.rb2
-rw-r--r--spec/controllers/profiles/notifications_controller_spec.rb2
-rw-r--r--spec/controllers/profiles/personal_access_tokens_controller_spec.rb2
-rw-r--r--spec/controllers/profiles/preferences_controller_spec.rb2
-rw-r--r--spec/controllers/profiles/two_factor_auths_controller_spec.rb2
-rw-r--r--spec/controllers/profiles_controller_spec.rb2
-rw-r--r--spec/controllers/projects/alert_management_controller_spec.rb2
-rw-r--r--spec/controllers/projects/alerting/notifications_controller_spec.rb109
-rw-r--r--spec/controllers/projects/artifacts_controller_spec.rb7
-rw-r--r--spec/controllers/projects/autocomplete_sources_controller_spec.rb2
-rw-r--r--spec/controllers/projects/avatars_controller_spec.rb2
-rw-r--r--spec/controllers/projects/badges_controller_spec.rb42
-rw-r--r--spec/controllers/projects/blame_controller_spec.rb2
-rw-r--r--spec/controllers/projects/blob_controller_spec.rb18
-rw-r--r--spec/controllers/projects/boards_controller_spec.rb2
-rw-r--r--spec/controllers/projects/branches_controller_spec.rb105
-rw-r--r--spec/controllers/projects/ci/daily_build_group_report_results_controller_spec.rb146
-rw-r--r--spec/controllers/projects/ci/lints_controller_spec.rb2
-rw-r--r--spec/controllers/projects/clusters/applications_controller_spec.rb2
-rw-r--r--spec/controllers/projects/clusters_controller_spec.rb9
-rw-r--r--spec/controllers/projects/commit_controller_spec.rb2
-rw-r--r--spec/controllers/projects/commits_controller_spec.rb2
-rw-r--r--spec/controllers/projects/compare_controller_spec.rb2
-rw-r--r--spec/controllers/projects/cycle_analytics/events_controller_spec.rb2
-rw-r--r--spec/controllers/projects/cycle_analytics_controller_spec.rb2
-rw-r--r--spec/controllers/projects/deploy_keys_controller_spec.rb2
-rw-r--r--spec/controllers/projects/deployments_controller_spec.rb2
-rw-r--r--spec/controllers/projects/design_management/designs/raw_images_controller_spec.rb2
-rw-r--r--spec/controllers/projects/design_management/designs/resized_image_controller_spec.rb2
-rw-r--r--spec/controllers/projects/discussions_controller_spec.rb2
-rw-r--r--spec/controllers/projects/environments/prometheus_api_controller_spec.rb2
-rw-r--r--spec/controllers/projects/environments/sample_metrics_controller_spec.rb2
-rw-r--r--spec/controllers/projects/environments_controller_spec.rb59
-rw-r--r--spec/controllers/projects/error_tracking/projects_controller_spec.rb2
-rw-r--r--spec/controllers/projects/error_tracking/stack_traces_controller_spec.rb2
-rw-r--r--spec/controllers/projects/error_tracking_controller_spec.rb2
-rw-r--r--spec/controllers/projects/find_file_controller_spec.rb2
-rw-r--r--spec/controllers/projects/forks_controller_spec.rb2
-rw-r--r--spec/controllers/projects/grafana_api_controller_spec.rb2
-rw-r--r--spec/controllers/projects/graphs_controller_spec.rb51
-rw-r--r--spec/controllers/projects/group_links_controller_spec.rb2
-rw-r--r--spec/controllers/projects/hooks_controller_spec.rb2
-rw-r--r--spec/controllers/projects/import/jira_controller_spec.rb245
-rw-r--r--spec/controllers/projects/imports_controller_spec.rb2
-rw-r--r--spec/controllers/projects/issues_controller_spec.rb11
-rw-r--r--spec/controllers/projects/jobs_controller_spec.rb196
-rw-r--r--spec/controllers/projects/labels_controller_spec.rb2
-rw-r--r--spec/controllers/projects/logs_controller_spec.rb2
-rw-r--r--spec/controllers/projects/mattermosts_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests/conflicts_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests/content_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests/creations_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests/diffs_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests/drafts_controller_spec.rb455
-rw-r--r--spec/controllers/projects/merge_requests_controller_spec.rb34
-rw-r--r--spec/controllers/projects/milestones_controller_spec.rb4
-rw-r--r--spec/controllers/projects/mirrors_controller_spec.rb2
-rw-r--r--spec/controllers/projects/notes_controller_spec.rb8
-rw-r--r--spec/controllers/projects/pages_controller_spec.rb2
-rw-r--r--spec/controllers/projects/pages_domains_controller_spec.rb2
-rw-r--r--spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb2
-rw-r--r--spec/controllers/projects/pipeline_schedules_controller_spec.rb2
-rw-r--r--spec/controllers/projects/pipelines_controller_spec.rb115
-rw-r--r--spec/controllers/projects/pipelines_settings_controller_spec.rb2
-rw-r--r--spec/controllers/projects/project_members_controller_spec.rb2
-rw-r--r--spec/controllers/projects/prometheus/alerts_controller_spec.rb2
-rw-r--r--spec/controllers/projects/prometheus/metrics_controller_spec.rb2
-rw-r--r--spec/controllers/projects/protected_branches_controller_spec.rb2
-rw-r--r--spec/controllers/projects/protected_tags_controller_spec.rb2
-rw-r--r--spec/controllers/projects/raw_controller_spec.rb2
-rw-r--r--spec/controllers/projects/refs_controller_spec.rb4
-rw-r--r--spec/controllers/projects/registry/repositories_controller_spec.rb4
-rw-r--r--spec/controllers/projects/registry/tags_controller_spec.rb2
-rw-r--r--spec/controllers/projects/releases/evidences_controller_spec.rb63
-rw-r--r--spec/controllers/projects/releases_controller_spec.rb2
-rw-r--r--spec/controllers/projects/repositories_controller_spec.rb2
-rw-r--r--spec/controllers/projects/runners_controller_spec.rb2
-rw-r--r--spec/controllers/projects/serverless/functions_controller_spec.rb2
-rw-r--r--spec/controllers/projects/service_hook_logs_controller_spec.rb2
-rw-r--r--spec/controllers/projects/services_controller_spec.rb42
-rw-r--r--spec/controllers/projects/settings/access_tokens_controller_spec.rb2
-rw-r--r--spec/controllers/projects/settings/ci_cd_controller_spec.rb2
-rw-r--r--spec/controllers/projects/settings/integrations_controller_spec.rb2
-rw-r--r--spec/controllers/projects/settings/operations_controller_spec.rb2
-rw-r--r--spec/controllers/projects/settings/repository_controller_spec.rb2
-rw-r--r--spec/controllers/projects/snippets_controller_spec.rb2
-rw-r--r--spec/controllers/projects/stages_controller_spec.rb2
-rw-r--r--spec/controllers/projects/starrers_controller_spec.rb2
-rw-r--r--spec/controllers/projects/static_site_editor_controller_spec.rb2
-rw-r--r--spec/controllers/projects/tags/releases_controller_spec.rb4
-rw-r--r--spec/controllers/projects/tags_controller_spec.rb68
-rw-r--r--spec/controllers/projects/templates_controller_spec.rb2
-rw-r--r--spec/controllers/projects/todos_controller_spec.rb2
-rw-r--r--spec/controllers/projects/tree_controller_spec.rb2
-rw-r--r--spec/controllers/projects/uploads_controller_spec.rb2
-rw-r--r--spec/controllers/projects/usage_ping_controller_spec.rb2
-rw-r--r--spec/controllers/projects/variables_controller_spec.rb2
-rw-r--r--spec/controllers/projects/web_ide_terminals_controller_spec.rb304
-rw-r--r--spec/controllers/projects/wikis_controller_spec.rb282
-rw-r--r--spec/controllers/projects_controller_spec.rb55
-rw-r--r--spec/controllers/registrations/experience_levels_controller_spec.rb143
-rw-r--r--spec/controllers/registrations_controller_spec.rb2
-rw-r--r--spec/controllers/repositories/git_http_controller_spec.rb2
-rw-r--r--spec/controllers/root_controller_spec.rb2
-rw-r--r--spec/controllers/search_controller_spec.rb7
-rw-r--r--spec/controllers/sent_notifications_controller_spec.rb2
-rw-r--r--spec/controllers/sessions_controller_spec.rb2
-rw-r--r--spec/controllers/snippets/notes_controller_spec.rb2
-rw-r--r--spec/controllers/snippets_controller_spec.rb2
-rw-r--r--spec/controllers/uploads_controller_spec.rb8
-rw-r--r--spec/controllers/user_callouts_controller_spec.rb2
-rw-r--r--spec/controllers/users/terms_controller_spec.rb2
-rw-r--r--spec/controllers/users_controller_spec.rb2
-rw-r--r--spec/db/development/import_common_metrics_spec.rb2
-rw-r--r--spec/db/production/import_common_metrics_spec.rb2
-rw-r--r--spec/db/production/settings_spec.rb2
-rw-r--r--spec/db/schema_spec.rb5
-rw-r--r--spec/dependencies/omniauth_saml_spec.rb2
-rw-r--r--spec/factories/alert_management/alerts.rb14
-rw-r--r--spec/factories/ci/build_report_results.rb35
-rw-r--r--spec/factories/ci/builds.rb23
-rw-r--r--spec/factories/ci/job_artifacts.rb7
-rw-r--r--spec/factories/ci/pipelines.rb12
-rw-r--r--spec/factories/ci/ref.rb10
-rw-r--r--spec/factories/clusters/clusters.rb17
-rw-r--r--spec/factories/design_management/designs.rb2
-rw-r--r--spec/factories/draft_note.rb31
-rw-r--r--spec/factories/events.rb49
-rw-r--r--spec/factories/evidences.rb2
-rw-r--r--spec/factories/group_import_states.rb25
-rw-r--r--spec/factories/keys.rb4
-rw-r--r--spec/factories/labels.rb12
-rw-r--r--spec/factories/merge_requests.rb16
-rw-r--r--spec/factories/notes.rb24
-rw-r--r--spec/factories/project_group_links.rb5
-rw-r--r--spec/factories/project_repository_storage_moves.rb4
-rw-r--r--spec/factories/projects.rb6
-rw-r--r--spec/factories/releases/link.rb1
-rw-r--r--spec/factories/reviews.rb9
-rw-r--r--spec/factories/services.rb13
-rw-r--r--spec/factories/usage_data.rb7
-rw-r--r--spec/factories_spec.rb2
-rw-r--r--spec/fast_spec_helper.rb1
-rw-r--r--spec/features/abuse_report_spec.rb2
-rw-r--r--spec/features/action_cable_logging_spec.rb47
-rw-r--r--spec/features/admin/admin_abuse_reports_spec.rb2
-rw-r--r--spec/features/admin/admin_appearance_spec.rb2
-rw-r--r--spec/features/admin/admin_broadcast_messages_spec.rb2
-rw-r--r--spec/features/admin/admin_browse_spam_logs_spec.rb2
-rw-r--r--spec/features/admin/admin_builds_spec.rb2
-rw-r--r--spec/features/admin/admin_disables_git_access_protocol_spec.rb2
-rw-r--r--spec/features/admin/admin_disables_two_factor_spec.rb2
-rw-r--r--spec/features/admin/admin_groups_spec.rb4
-rw-r--r--spec/features/admin/admin_health_check_spec.rb2
-rw-r--r--spec/features/admin/admin_hook_logs_spec.rb2
-rw-r--r--spec/features/admin/admin_hooks_spec.rb2
-rw-r--r--spec/features/admin/admin_mode/login_spec.rb2
-rw-r--r--spec/features/admin/admin_mode/logout_spec.rb2
-rw-r--r--spec/features/admin/admin_mode/workers_spec.rb2
-rw-r--r--spec/features/admin/admin_mode_spec.rb2
-rw-r--r--spec/features/admin/admin_projects_spec.rb2
-rw-r--r--spec/features/admin/admin_requests_profiles_spec.rb2
-rw-r--r--spec/features/admin/admin_runners_spec.rb2
-rw-r--r--spec/features/admin/admin_sees_project_statistics_spec.rb2
-rw-r--r--spec/features/admin/admin_sees_projects_statistics_spec.rb2
-rw-r--r--spec/features/admin/admin_serverless_domains_spec.rb2
-rw-r--r--spec/features/admin/admin_settings_spec.rb38
-rw-r--r--spec/features/admin/admin_system_info_spec.rb2
-rw-r--r--spec/features/admin/admin_users_impersonation_tokens_spec.rb2
-rw-r--r--spec/features/admin/admin_users_spec.rb2
-rw-r--r--spec/features/admin/admin_uses_repository_checks_spec.rb2
-rw-r--r--spec/features/admin/clusters/applications_spec.rb2
-rw-r--r--spec/features/admin/clusters/eks_spec.rb2
-rw-r--r--spec/features/admin/dashboard_spec.rb2
-rw-r--r--spec/features/admin/services/admin_activates_prometheus_spec.rb2
-rw-r--r--spec/features/atom/dashboard_issues_spec.rb2
-rw-r--r--spec/features/atom/dashboard_spec.rb2
-rw-r--r--spec/features/atom/issues_spec.rb2
-rw-r--r--spec/features/atom/users_spec.rb2
-rw-r--r--spec/features/boards/add_issues_modal_spec.rb2
-rw-r--r--spec/features/boards/boards_spec.rb2
-rw-r--r--spec/features/boards/focus_mode_spec.rb2
-rw-r--r--spec/features/boards/issue_ordering_spec.rb2
-rw-r--r--spec/features/boards/keyboard_shortcut_spec.rb2
-rw-r--r--spec/features/boards/modal_filter_spec.rb2
-rw-r--r--spec/features/boards/multi_select_spec.rb2
-rw-r--r--spec/features/boards/multiple_boards_spec.rb2
-rw-r--r--spec/features/boards/new_issue_spec.rb2
-rw-r--r--spec/features/boards/reload_boards_on_browser_back_spec.rb2
-rw-r--r--spec/features/boards/sidebar_spec.rb2
-rw-r--r--spec/features/boards/sub_group_project_spec.rb2
-rw-r--r--spec/features/broadcast_messages_spec.rb2
-rw-r--r--spec/features/calendar_spec.rb4
-rw-r--r--spec/features/clusters/cluster_detail_page_spec.rb2
-rw-r--r--spec/features/clusters/installing_applications_shared_examples.rb4
-rw-r--r--spec/features/commits/user_uses_quick_actions_spec.rb2
-rw-r--r--spec/features/commits/user_view_commits_spec.rb2
-rw-r--r--spec/features/commits_spec.rb2
-rw-r--r--spec/features/contextual_sidebar_spec.rb2
-rw-r--r--spec/features/cycle_analytics_spec.rb2
-rw-r--r--spec/features/dashboard/activity_spec.rb2
-rw-r--r--spec/features/dashboard/datetime_on_tooltips_spec.rb4
-rw-r--r--spec/features/dashboard/group_dashboard_with_external_authorization_service_spec.rb2
-rw-r--r--spec/features/dashboard/groups_list_spec.rb2
-rw-r--r--spec/features/dashboard/instance_statistics_spec.rb2
-rw-r--r--spec/features/dashboard/issuables_counter_spec.rb2
-rw-r--r--spec/features/dashboard/issues_filter_spec.rb2
-rw-r--r--spec/features/dashboard/label_filter_spec.rb2
-rw-r--r--spec/features/dashboard/merge_requests_spec.rb2
-rw-r--r--spec/features/dashboard/milestone_tabs_spec.rb42
-rw-r--r--spec/features/dashboard/milestones_spec.rb2
-rw-r--r--spec/features/dashboard/project_member_activity_index_spec.rb8
-rw-r--r--spec/features/dashboard/projects_spec.rb4
-rw-r--r--spec/features/dashboard/root_explore_spec.rb2
-rw-r--r--spec/features/dashboard/shortcuts_spec.rb2
-rw-r--r--spec/features/dashboard/snippets_spec.rb2
-rw-r--r--spec/features/dashboard/todos/target_state_spec.rb2
-rw-r--r--spec/features/dashboard/todos/todos_filtering_spec.rb2
-rw-r--r--spec/features/dashboard/todos/todos_sorting_spec.rb2
-rw-r--r--spec/features/dashboard/todos/todos_spec.rb4
-rw-r--r--spec/features/dashboard/user_filters_projects_spec.rb2
-rw-r--r--spec/features/discussion_comments/commit_spec.rb2
-rw-r--r--spec/features/discussion_comments/issue_spec.rb2
-rw-r--r--spec/features/discussion_comments/merge_request_spec.rb2
-rw-r--r--spec/features/discussion_comments/snippets_spec.rb2
-rw-r--r--spec/features/display_system_header_and_footer_bar_spec.rb2
-rw-r--r--spec/features/error_pages_spec.rb2
-rw-r--r--spec/features/error_tracking/user_filters_errors_by_status_spec.rb2
-rw-r--r--spec/features/error_tracking/user_searches_sentry_errors_spec.rb2
-rw-r--r--spec/features/error_tracking/user_sees_error_details_spec.rb2
-rw-r--r--spec/features/error_tracking/user_sees_error_index_spec.rb2
-rw-r--r--spec/features/expand_collapse_diffs_spec.rb2
-rw-r--r--spec/features/explore/groups_list_spec.rb2
-rw-r--r--spec/features/explore/groups_spec.rb2
-rw-r--r--spec/features/explore/user_explores_projects_spec.rb2
-rw-r--r--spec/features/global_search_spec.rb5
-rw-r--r--spec/features/graphiql_spec.rb2
-rw-r--r--spec/features/group_variables_spec.rb2
-rw-r--r--spec/features/groups/activity_spec.rb2
-rw-r--r--spec/features/groups/board_sidebar_spec.rb2
-rw-r--r--spec/features/groups/board_spec.rb2
-rw-r--r--spec/features/groups/clusters/applications_spec.rb2
-rw-r--r--spec/features/groups/clusters/eks_spec.rb2
-rw-r--r--spec/features/groups/clusters/user_spec.rb2
-rw-r--r--spec/features/groups/container_registry_spec.rb11
-rw-r--r--spec/features/groups/empty_states_spec.rb2
-rw-r--r--spec/features/groups/group_page_with_external_authorization_service_spec.rb2
-rw-r--r--spec/features/groups/group_settings_spec.rb2
-rw-r--r--spec/features/groups/import_export/export_file_spec.rb2
-rw-r--r--spec/features/groups/import_export/import_file_spec.rb104
-rw-r--r--spec/features/groups/issues_spec.rb2
-rw-r--r--spec/features/groups/labels/create_spec.rb2
-rw-r--r--spec/features/groups/labels/edit_spec.rb2
-rw-r--r--spec/features/groups/labels/index_spec.rb2
-rw-r--r--spec/features/groups/labels/search_labels_spec.rb2
-rw-r--r--spec/features/groups/labels/sort_labels_spec.rb2
-rw-r--r--spec/features/groups/labels/subscription_spec.rb2
-rw-r--r--spec/features/groups/labels/user_sees_links_to_issuables_spec.rb2
-rw-r--r--spec/features/groups/members/filter_members_spec.rb2
-rw-r--r--spec/features/groups/members/leave_group_spec.rb3
-rw-r--r--spec/features/groups/members/list_members_spec.rb2
-rw-r--r--spec/features/groups/members/manage_groups_spec.rb2
-rw-r--r--spec/features/groups/members/manage_members_spec.rb2
-rw-r--r--spec/features/groups/members/master_adds_member_with_expiration_date_spec.rb2
-rw-r--r--spec/features/groups/members/master_manages_access_requests_spec.rb2
-rw-r--r--spec/features/groups/members/request_access_spec.rb2
-rw-r--r--spec/features/groups/members/search_members_spec.rb2
-rw-r--r--spec/features/groups/members/sort_members_spec.rb2
-rw-r--r--spec/features/groups/merge_requests_spec.rb2
-rw-r--r--spec/features/groups/milestone_spec.rb84
-rw-r--r--spec/features/groups/milestones_sorting_spec.rb19
-rw-r--r--spec/features/groups/navbar_spec.rb3
-rw-r--r--spec/features/groups/settings/ci_cd_spec.rb2
-rw-r--r--spec/features/groups/settings/group_badges_spec.rb2
-rw-r--r--spec/features/groups/settings/repository_spec.rb2
-rw-r--r--spec/features/groups/share_lock_spec.rb2
-rw-r--r--spec/features/groups/show_spec.rb2
-rw-r--r--spec/features/groups/user_browse_projects_group_page_spec.rb2
-rw-r--r--spec/features/groups/user_sees_package_sidebar_spec.rb2
-rw-r--r--spec/features/groups/user_sees_users_dropdowns_in_issuables_list_spec.rb2
-rw-r--r--spec/features/groups_spec.rb2
-rw-r--r--spec/features/help_pages_spec.rb2
-rw-r--r--spec/features/ics/dashboard_issues_spec.rb2
-rw-r--r--spec/features/ics/group_issues_spec.rb2
-rw-r--r--spec/features/ics/project_issues_spec.rb2
-rw-r--r--spec/features/ide/clientside_preview_csp_spec.rb2
-rw-r--r--spec/features/ide/static_object_external_storage_csp_spec.rb2
-rw-r--r--spec/features/ide/user_commits_changes_spec.rb12
-rw-r--r--spec/features/ide/user_opens_merge_request_spec.rb2
-rw-r--r--spec/features/ide_spec.rb2
-rw-r--r--spec/features/import/manifest_import_spec.rb2
-rw-r--r--spec/features/instance_statistics/cohorts_spec.rb2
-rw-r--r--spec/features/instance_statistics/dev_ops_score_spec.rb2
-rw-r--r--spec/features/instance_statistics/instance_statistics_spec.rb2
-rw-r--r--spec/features/invites_spec.rb2
-rw-r--r--spec/features/issuables/close_reopen_report_toggle_spec.rb2
-rw-r--r--spec/features/issuables/discussion_lock_spec.rb2
-rw-r--r--spec/features/issuables/issuable_list_spec.rb2
-rw-r--r--spec/features/issuables/markdown_references/internal_references_spec.rb2
-rw-r--r--spec/features/issuables/markdown_references/jira_spec.rb2
-rw-r--r--spec/features/issuables/shortcuts_issuable_spec.rb2
-rw-r--r--spec/features/issuables/sorting_list_spec.rb2
-rw-r--r--spec/features/issuables/user_sees_sidebar_spec.rb2
-rw-r--r--spec/features/issues/bulk_assignment_labels_spec.rb20
-rw-r--r--spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb2
-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/dropdown_assignee_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/dropdown_author_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/dropdown_base_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/dropdown_emoji_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/dropdown_hint_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/dropdown_label_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/dropdown_milestone_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/dropdown_release_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/filter_issues_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/recent_searches_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/search_bar_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/visual_tokens_spec.rb2
-rw-r--r--spec/features/issues/form_spec.rb2
-rw-r--r--spec/features/issues/gfm_autocomplete_spec.rb2
-rw-r--r--spec/features/issues/group_label_sidebar_spec.rb2
-rw-r--r--spec/features/issues/issue_detail_spec.rb2
-rw-r--r--spec/features/issues/issue_sidebar_spec.rb139
-rw-r--r--spec/features/issues/keyboard_shortcut_spec.rb2
-rw-r--r--spec/features/issues/markdown_toolbar_spec.rb2
-rw-r--r--spec/features/issues/move_spec.rb2
-rw-r--r--spec/features/issues/note_polling_spec.rb2
-rw-r--r--spec/features/issues/notes_on_issues_spec.rb2
-rw-r--r--spec/features/issues/resource_label_events_spec.rb2
-rw-r--r--spec/features/issues/rss_spec.rb2
-rw-r--r--spec/features/issues/spam_issues_spec.rb6
-rw-r--r--spec/features/issues/todo_spec.rb2
-rw-r--r--spec/features/issues/update_issues_spec.rb2
-rw-r--r--spec/features/issues/user_comments_on_issue_spec.rb2
-rw-r--r--spec/features/issues/user_creates_branch_and_merge_request_spec.rb2
-rw-r--r--spec/features/issues/user_creates_confidential_merge_request_spec.rb2
-rw-r--r--spec/features/issues/user_creates_issue_by_email_spec.rb2
-rw-r--r--spec/features/issues/user_creates_issue_spec.rb2
-rw-r--r--spec/features/issues/user_edits_issue_spec.rb2
-rw-r--r--spec/features/issues/user_filters_issues_spec.rb2
-rw-r--r--spec/features/issues/user_interacts_with_awards_spec.rb2
-rw-r--r--spec/features/issues/user_resets_their_incoming_email_token_spec.rb2
-rw-r--r--spec/features/issues/user_sees_breadcrumb_links_spec.rb2
-rw-r--r--spec/features/issues/user_sees_empty_state_spec.rb2
-rw-r--r--spec/features/issues/user_sees_live_update_spec.rb2
-rw-r--r--spec/features/issues/user_sees_sidebar_updates_in_realtime_spec.rb2
-rw-r--r--spec/features/issues/user_sorts_issue_comments_spec.rb2
-rw-r--r--spec/features/issues/user_sorts_issues_spec.rb2
-rw-r--r--spec/features/issues/user_toggles_subscription_spec.rb2
-rw-r--r--spec/features/issues/user_uses_quick_actions_spec.rb2
-rw-r--r--spec/features/issues/user_views_issue_spec.rb26
-rw-r--r--spec/features/issues/user_views_issues_spec.rb2
-rw-r--r--spec/features/labels_hierarchy_spec.rb2
-rw-r--r--spec/features/markdown/copy_as_gfm_spec.rb4
-rw-r--r--spec/features/markdown/gitlab_flavored_markdown_spec.rb2
-rw-r--r--spec/features/markdown/markdown_spec.rb12
-rw-r--r--spec/features/markdown/math_spec.rb2
-rw-r--r--spec/features/markdown/mermaid_spec.rb7
-rw-r--r--spec/features/markdown/metrics_spec.rb2
-rw-r--r--spec/features/merge_request/batch_comments_spec.rb259
-rw-r--r--spec/features/merge_request/maintainer_edits_fork_spec.rb2
-rw-r--r--spec/features/merge_request/user_accepts_merge_request_spec.rb2
-rw-r--r--spec/features/merge_request/user_allows_commits_from_memebers_who_can_merge_spec.rb2
-rw-r--r--spec/features/merge_request/user_assigns_themselves_spec.rb2
-rw-r--r--spec/features/merge_request/user_awards_emoji_spec.rb2
-rw-r--r--spec/features/merge_request/user_clicks_merge_request_tabs_spec.rb24
-rw-r--r--spec/features/merge_request/user_closes_merge_request_spec.rb2
-rw-r--r--spec/features/merge_request/user_comments_on_commit_spec.rb2
-rw-r--r--spec/features/merge_request/user_comments_on_diff_spec.rb46
-rw-r--r--spec/features/merge_request/user_comments_on_merge_request_spec.rb2
-rw-r--r--spec/features/merge_request/user_creates_image_diff_notes_spec.rb2
-rw-r--r--spec/features/merge_request/user_creates_merge_request_spec.rb2
-rw-r--r--spec/features/merge_request/user_creates_mr_spec.rb2
-rw-r--r--spec/features/merge_request/user_customizes_merge_commit_message_spec.rb2
-rw-r--r--spec/features/merge_request/user_edits_assignees_sidebar_spec.rb103
-rw-r--r--spec/features/merge_request/user_edits_merge_request_spec.rb2
-rw-r--r--spec/features/merge_request/user_edits_mr_spec.rb2
-rw-r--r--spec/features/merge_request/user_expands_diff_spec.rb2
-rw-r--r--spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb6
-rw-r--r--spec/features/merge_request/user_locks_discussion_spec.rb2
-rw-r--r--spec/features/merge_request/user_manages_subscription_spec.rb2
-rw-r--r--spec/features/merge_request/user_merges_immediately_spec.rb2
-rw-r--r--spec/features/merge_request/user_merges_merge_request_spec.rb2
-rw-r--r--spec/features/merge_request/user_merges_only_if_pipeline_succeeds_spec.rb2
-rw-r--r--spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb2
-rw-r--r--spec/features/merge_request/user_posts_diff_notes_spec.rb4
-rw-r--r--spec/features/merge_request/user_posts_notes_spec.rb4
-rw-r--r--spec/features/merge_request/user_rebases_merge_request_spec.rb2
-rw-r--r--spec/features/merge_request/user_reopens_merge_request_spec.rb2
-rw-r--r--spec/features/merge_request/user_resolves_conflicts_spec.rb2
-rw-r--r--spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb27
-rw-r--r--spec/features/merge_request/user_resolves_outdated_diff_discussions_spec.rb2
-rw-r--r--spec/features/merge_request/user_resolves_wip_mr_spec.rb2
-rw-r--r--spec/features/merge_request/user_reverts_merge_request_spec.rb2
-rw-r--r--spec/features/merge_request/user_reviews_image_spec.rb37
-rw-r--r--spec/features/merge_request/user_scrolls_to_note_on_load_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb8
-rw-r--r--spec/features/merge_request/user_sees_breadcrumb_links_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_check_out_branch_modal_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_cherry_pick_modal_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_closing_issues_message_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_deleted_target_branch_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_deployment_widget_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_diff_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_discussions_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_empty_state_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_merge_button_depending_on_unresolved_discussions_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_merge_widget_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_mini_pipeline_graph_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_mr_from_deleted_forked_project_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_mr_with_deleted_source_branch_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_notes_from_forked_project_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_pipelines_from_forked_project_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_pipelines_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_system_notes_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_versions_spec.rb4
-rw-r--r--spec/features/merge_request/user_sees_wip_help_message_spec.rb2
-rw-r--r--spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb2
-rw-r--r--spec/features/merge_request/user_suggests_changes_on_diff_spec.rb108
-rw-r--r--spec/features/merge_request/user_toggles_whitespace_changes_spec.rb2
-rw-r--r--spec/features/merge_request/user_tries_to_access_private_project_info_through_new_mr_spec.rb2
-rw-r--r--spec/features/merge_request/user_uses_quick_actions_spec.rb2
-rw-r--r--spec/features/merge_request/user_views_diffs_spec.rb2
-rw-r--r--spec/features/merge_request/user_views_merge_request_from_deleted_fork_spec.rb2
-rw-r--r--spec/features/merge_request/user_views_open_merge_request_spec.rb2
-rw-r--r--spec/features/merge_request/user_views_user_status_on_merge_request_spec.rb2
-rw-r--r--spec/features/merge_requests/filters_generic_behavior_spec.rb2
-rw-r--r--spec/features/merge_requests/user_filters_by_assignees_spec.rb2
-rw-r--r--spec/features/merge_requests/user_filters_by_labels_spec.rb2
-rw-r--r--spec/features/merge_requests/user_filters_by_milestones_spec.rb2
-rw-r--r--spec/features/merge_requests/user_filters_by_multiple_criteria_spec.rb2
-rw-r--r--spec/features/merge_requests/user_filters_by_target_branch_spec.rb2
-rw-r--r--spec/features/merge_requests/user_lists_merge_requests_spec.rb2
-rw-r--r--spec/features/merge_requests/user_mass_updates_spec.rb2
-rw-r--r--spec/features/merge_requests/user_sorts_merge_requests_spec.rb2
-rw-r--r--spec/features/merge_requests/user_squashes_merge_request_spec.rb2
-rw-r--r--spec/features/merge_requests/user_views_all_merge_requests_spec.rb2
-rw-r--r--spec/features/merge_requests/user_views_closed_merge_requests_spec.rb2
-rw-r--r--spec/features/merge_requests/user_views_merged_merge_requests_spec.rb2
-rw-r--r--spec/features/merge_requests/user_views_open_merge_requests_spec.rb2
-rw-r--r--spec/features/milestone_spec.rb16
-rw-r--r--spec/features/milestones/user_creates_milestone_spec.rb2
-rw-r--r--spec/features/milestones/user_deletes_milestone_spec.rb2
-rw-r--r--spec/features/milestones/user_edits_milestone_spec.rb2
-rw-r--r--spec/features/milestones/user_promotes_milestone_spec.rb2
-rw-r--r--spec/features/milestones/user_sees_breadcrumb_links_spec.rb2
-rw-r--r--spec/features/milestones/user_views_milestone_spec.rb2
-rw-r--r--spec/features/milestones/user_views_milestones_spec.rb4
-rw-r--r--spec/features/oauth_login_spec.rb2
-rw-r--r--spec/features/oauth_provider_authorize_spec.rb2
-rw-r--r--spec/features/participants_autocomplete_spec.rb2
-rw-r--r--spec/features/password_reset_spec.rb2
-rw-r--r--spec/features/populate_new_pipeline_vars_with_params_spec.rb2
-rw-r--r--spec/features/profile_spec.rb2
-rw-r--r--spec/features/profiles/account_spec.rb33
-rw-r--r--spec/features/profiles/active_sessions_spec.rb2
-rw-r--r--spec/features/profiles/chat_names_spec.rb2
-rw-r--r--spec/features/profiles/emails_spec.rb2
-rw-r--r--spec/features/profiles/gpg_keys_spec.rb2
-rw-r--r--spec/features/profiles/keys_spec.rb2
-rw-r--r--spec/features/profiles/oauth_applications_spec.rb2
-rw-r--r--spec/features/profiles/password_spec.rb2
-rw-r--r--spec/features/profiles/personal_access_tokens_spec.rb2
-rw-r--r--spec/features/profiles/user_changes_notified_of_own_activity_spec.rb2
-rw-r--r--spec/features/profiles/user_edit_preferences_spec.rb2
-rw-r--r--spec/features/profiles/user_edit_profile_spec.rb11
-rw-r--r--spec/features/profiles/user_manages_applications_spec.rb2
-rw-r--r--spec/features/profiles/user_manages_emails_spec.rb2
-rw-r--r--spec/features/profiles/user_visits_notifications_tab_spec.rb2
-rw-r--r--spec/features/profiles/user_visits_profile_account_page_spec.rb2
-rw-r--r--spec/features/profiles/user_visits_profile_authentication_log_spec.rb2
-rw-r--r--spec/features/profiles/user_visits_profile_preferences_page_spec.rb2
-rw-r--r--spec/features/profiles/user_visits_profile_spec.rb2
-rw-r--r--spec/features/profiles/user_visits_profile_ssh_keys_page_spec.rb2
-rw-r--r--spec/features/project_group_variables_spec.rb2
-rw-r--r--spec/features/project_variables_spec.rb2
-rw-r--r--spec/features/projects/active_tabs_spec.rb4
-rw-r--r--spec/features/projects/activity/rss_spec.rb2
-rw-r--r--spec/features/projects/activity/user_sees_activity_spec.rb2
-rw-r--r--spec/features/projects/activity/user_sees_design_comment_spec.rb2
-rw-r--r--spec/features/projects/activity/user_sees_private_activity_spec.rb2
-rw-r--r--spec/features/projects/artifacts/file_spec.rb2
-rw-r--r--spec/features/projects/artifacts/raw_spec.rb2
-rw-r--r--spec/features/projects/artifacts/user_browses_artifacts_spec.rb2
-rw-r--r--spec/features/projects/artifacts/user_downloads_artifacts_spec.rb2
-rw-r--r--spec/features/projects/badges/coverage_spec.rb2
-rw-r--r--spec/features/projects/badges/list_spec.rb2
-rw-r--r--spec/features/projects/badges/pipeline_badge_spec.rb2
-rw-r--r--spec/features/projects/blobs/blob_line_permalink_updater_spec.rb2
-rw-r--r--spec/features/projects/blobs/blob_show_spec.rb49
-rw-r--r--spec/features/projects/blobs/edit_spec.rb2
-rw-r--r--spec/features/projects/blobs/shortcuts_blob_spec.rb2
-rw-r--r--spec/features/projects/blobs/user_creates_new_blob_in_new_project_spec.rb2
-rw-r--r--spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb2
-rw-r--r--spec/features/projects/branches/download_buttons_spec.rb2
-rw-r--r--spec/features/projects/branches/new_branch_ref_dropdown_spec.rb2
-rw-r--r--spec/features/projects/branches/user_creates_branch_spec.rb2
-rw-r--r--spec/features/projects/branches/user_deletes_branch_spec.rb2
-rw-r--r--spec/features/projects/branches/user_views_branches_spec.rb2
-rw-r--r--spec/features/projects/branches_spec.rb40
-rw-r--r--spec/features/projects/ci/lint_spec.rb2
-rw-r--r--spec/features/projects/classification_label_on_project_pages_spec.rb2
-rw-r--r--spec/features/projects/clusters/applications_spec.rb2
-rw-r--r--spec/features/projects/clusters/eks_spec.rb2
-rw-r--r--spec/features/projects/clusters/gcp_spec.rb2
-rw-r--r--spec/features/projects/clusters/user_spec.rb2
-rw-r--r--spec/features/projects/clusters_spec.rb2
-rw-r--r--spec/features/projects/commit/builds_spec.rb2
-rw-r--r--spec/features/projects/commit/cherry_pick_spec.rb2
-rw-r--r--spec/features/projects/commit/comments/user_adds_comment_spec.rb2
-rw-r--r--spec/features/projects/commit/comments/user_deletes_comments_spec.rb2
-rw-r--r--spec/features/projects/commit/comments/user_edits_comments_spec.rb2
-rw-r--r--spec/features/projects/commit/diff_notes_spec.rb2
-rw-r--r--spec/features/projects/commit/mini_pipeline_graph_spec.rb2
-rw-r--r--spec/features/projects/commit/user_comments_on_commit_spec.rb2
-rw-r--r--spec/features/projects/commit/user_reverts_commit_spec.rb2
-rw-r--r--spec/features/projects/commit/user_views_user_status_on_commit_spec.rb2
-rw-r--r--spec/features/projects/commits/rss_spec.rb2
-rw-r--r--spec/features/projects/commits/user_browses_commits_spec.rb2
-rw-r--r--spec/features/projects/compare_spec.rb2
-rw-r--r--spec/features/projects/container_registry_spec.rb8
-rw-r--r--spec/features/projects/deploy_keys_spec.rb2
-rw-r--r--spec/features/projects/diffs/diff_show_spec.rb2
-rw-r--r--spec/features/projects/environments/environment_metrics_spec.rb2
-rw-r--r--spec/features/projects/environments/environment_spec.rb2
-rw-r--r--spec/features/projects/environments/environments_spec.rb2
-rw-r--r--spec/features/projects/environments_pod_logs_spec.rb2
-rw-r--r--spec/features/projects/features_visibility_spec.rb4
-rw-r--r--spec/features/projects/files/dockerfile_dropdown_spec.rb2
-rw-r--r--spec/features/projects/files/download_buttons_spec.rb2
-rw-r--r--spec/features/projects/files/edit_file_soft_wrap_spec.rb2
-rw-r--r--spec/features/projects/files/editing_a_file_spec.rb2
-rw-r--r--spec/features/projects/files/files_sort_submodules_with_folders_spec.rb2
-rw-r--r--spec/features/projects/files/find_file_keyboard_spec.rb2
-rw-r--r--spec/features/projects/files/gitignore_dropdown_spec.rb2
-rw-r--r--spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb2
-rw-r--r--spec/features/projects/files/project_owner_creates_license_file_spec.rb2
-rw-r--r--spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb2
-rw-r--r--spec/features/projects/files/template_selector_menu_spec.rb2
-rw-r--r--spec/features/projects/files/template_type_dropdown_spec.rb2
-rw-r--r--spec/features/projects/files/undo_template_spec.rb2
-rw-r--r--spec/features/projects/files/user_browses_a_tree_with_a_folder_containing_only_a_folder_spec.rb2
-rw-r--r--spec/features/projects/files/user_browses_files_spec.rb2
-rw-r--r--spec/features/projects/files/user_browses_lfs_files_spec.rb2
-rw-r--r--spec/features/projects/files/user_creates_directory_spec.rb2
-rw-r--r--spec/features/projects/files/user_creates_files_spec.rb2
-rw-r--r--spec/features/projects/files/user_deletes_files_spec.rb2
-rw-r--r--spec/features/projects/files/user_edits_files_spec.rb2
-rw-r--r--spec/features/projects/files/user_find_file_spec.rb2
-rw-r--r--spec/features/projects/files/user_reads_pipeline_status_spec.rb2
-rw-r--r--spec/features/projects/files/user_replaces_files_spec.rb2
-rw-r--r--spec/features/projects/files/user_searches_for_files_spec.rb2
-rw-r--r--spec/features/projects/files/user_uploads_files_spec.rb2
-rw-r--r--spec/features/projects/fork_spec.rb2
-rw-r--r--spec/features/projects/forks/fork_list_spec.rb2
-rw-r--r--spec/features/projects/gfm_autocomplete_load_spec.rb2
-rw-r--r--spec/features/projects/graph_spec.rb2
-rw-r--r--spec/features/projects/hook_logs/user_reads_log_spec.rb2
-rw-r--r--spec/features/projects/import_export/export_file_spec.rb2
-rw-r--r--spec/features/projects/import_export/import_file_spec.rb2
-rw-r--r--spec/features/projects/issuable_templates_spec.rb2
-rw-r--r--spec/features/projects/issues/design_management/user_links_to_designs_in_issue_spec.rb123
-rw-r--r--spec/features/projects/issues/design_management/user_paginates_designs_spec.rb2
-rw-r--r--spec/features/projects/issues/design_management/user_permissions_upload_spec.rb2
-rw-r--r--spec/features/projects/issues/design_management/user_uploads_designs_spec.rb2
-rw-r--r--spec/features/projects/issues/design_management/user_views_design_images_spec.rb2
-rw-r--r--spec/features/projects/issues/design_management/user_views_design_spec.rb2
-rw-r--r--spec/features/projects/issues/design_management/user_views_designs_spec.rb2
-rw-r--r--spec/features/projects/issues/design_management/user_views_designs_with_svg_xss_spec.rb2
-rw-r--r--spec/features/projects/issues/viewing_issues_with_external_authorization_enabled_spec.rb2
-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/jobs/user_browses_jobs_spec.rb2
-rw-r--r--spec/features/projects/jobs_spec.rb6
-rw-r--r--spec/features/projects/labels/issues_sorted_by_priority_spec.rb2
-rw-r--r--spec/features/projects/labels/search_labels_spec.rb2
-rw-r--r--spec/features/projects/labels/sort_labels_spec.rb2
-rw-r--r--spec/features/projects/labels/subscription_spec.rb2
-rw-r--r--spec/features/projects/labels/update_prioritization_spec.rb2
-rw-r--r--spec/features/projects/labels/user_creates_labels_spec.rb2
-rw-r--r--spec/features/projects/labels/user_edits_labels_spec.rb2
-rw-r--r--spec/features/projects/labels/user_promotes_label_spec.rb2
-rw-r--r--spec/features/projects/labels/user_removes_labels_spec.rb2
-rw-r--r--spec/features/projects/labels/user_sees_breadcrumb_links_spec.rb2
-rw-r--r--spec/features/projects/labels/user_sees_links_to_issuables_spec.rb2
-rw-r--r--spec/features/projects/labels/user_views_labels_spec.rb2
-rw-r--r--spec/features/projects/members/anonymous_user_sees_members_spec.rb2
-rw-r--r--spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb2
-rw-r--r--spec/features/projects/members/group_member_cannot_request_access_to_his_group_project_spec.rb2
-rw-r--r--spec/features/projects/members/group_members_spec.rb12
-rw-r--r--spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb2
-rw-r--r--spec/features/projects/members/groups_with_access_list_spec.rb6
-rw-r--r--spec/features/projects/members/invite_group_spec.rb16
-rw-r--r--spec/features/projects/members/list_spec.rb4
-rw-r--r--spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb2
-rw-r--r--spec/features/projects/members/master_manages_access_requests_spec.rb2
-rw-r--r--spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb2
-rw-r--r--spec/features/projects/members/member_leaves_project_spec.rb2
-rw-r--r--spec/features/projects/members/owner_cannot_leave_project_spec.rb2
-rw-r--r--spec/features/projects/members/owner_cannot_request_access_to_his_project_spec.rb2
-rw-r--r--spec/features/projects/members/sorting_spec.rb2
-rw-r--r--spec/features/projects/members/user_requests_access_spec.rb2
-rw-r--r--spec/features/projects/merge_request_button_spec.rb2
-rw-r--r--spec/features/projects/milestones/milestone_spec.rb2
-rw-r--r--spec/features/projects/milestones/milestones_sorting_spec.rb2
-rw-r--r--spec/features/projects/milestones/new_spec.rb2
-rw-r--r--spec/features/projects/milestones/user_interacts_with_labels_spec.rb2
-rw-r--r--spec/features/projects/navbar_spec.rb2
-rw-r--r--spec/features/projects/network_graph_spec.rb2
-rw-r--r--spec/features/projects/new_project_spec.rb2
-rw-r--r--spec/features/projects/pages_lets_encrypt_spec.rb2
-rw-r--r--spec/features/projects/pages_spec.rb4
-rw-r--r--spec/features/projects/pipeline_schedules_spec.rb2
-rw-r--r--spec/features/projects/pipelines/pipeline_spec.rb2
-rw-r--r--spec/features/projects/pipelines/pipelines_spec.rb8
-rw-r--r--spec/features/projects/raw/user_interacts_with_raw_endpoint_spec.rb2
-rw-r--r--spec/features/projects/releases/user_views_edit_release_spec.rb2
-rw-r--r--spec/features/projects/releases/user_views_release_spec.rb2
-rw-r--r--spec/features/projects/releases/user_views_releases_spec.rb70
-rw-r--r--spec/features/projects/remote_mirror_spec.rb2
-rw-r--r--spec/features/projects/serverless/functions_spec.rb2
-rw-r--r--spec/features/projects/services/disable_triggers_spec.rb4
-rw-r--r--spec/features/projects/services/prometheus_external_alerts_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_alerts_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_asana_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_assembla_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_atlassian_bamboo_ci_spec.rb4
-rw-r--r--spec/features/projects/services/user_activates_emails_on_push_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_flowdock_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_hipchat_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_irker_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_issue_tracker_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_jetbrains_teamcity_ci_spec.rb4
-rw-r--r--spec/features/projects/services/user_activates_jira_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_packagist_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_pivotaltracker_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_prometheus_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_pushover_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_slack_notifications_spec.rb18
-rw-r--r--spec/features/projects/services/user_activates_slack_slash_command_spec.rb12
-rw-r--r--spec/features/projects/services/user_views_services_spec.rb2
-rw-r--r--spec/features/projects/settings/access_tokens_spec.rb2
-rw-r--r--spec/features/projects/settings/external_authorization_service_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/forked_project_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/lfs_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/operations_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/pipelines_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/project_badges_spec.rb2
-rw-r--r--spec/features/projects/settings/project_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/registry_settings_spec.rb17
-rw-r--r--spec/features/projects/settings/repository_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/user_archives_project_spec.rb2
-rw-r--r--spec/features/projects/settings/user_changes_avatar_spec.rb2
-rw-r--r--spec/features/projects/settings/user_changes_default_branch_spec.rb2
-rw-r--r--spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb2
-rw-r--r--spec/features/projects/settings/user_manages_group_links_spec.rb44
-rw-r--r--spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/user_manages_project_members_spec.rb2
-rw-r--r--spec/features/projects/settings/user_renames_a_project_spec.rb2
-rw-r--r--spec/features/projects/settings/user_sees_revoke_deploy_token_modal_spec.rb2
-rw-r--r--spec/features/projects/settings/user_tags_project_spec.rb2
-rw-r--r--spec/features/projects/settings/user_transfers_a_project_spec.rb2
-rw-r--r--spec/features/projects/settings/visibility_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/webhooks_settings_spec.rb2
-rw-r--r--spec/features/projects/show/developer_views_empty_project_instructions_spec.rb2
-rw-r--r--spec/features/projects/show/download_buttons_spec.rb2
-rw-r--r--spec/features/projects/show/no_password_spec.rb2
-rw-r--r--spec/features/projects/show/redirects_spec.rb2
-rw-r--r--spec/features/projects/show/rss_spec.rb2
-rw-r--r--spec/features/projects/show/user_interacts_with_auto_devops_banner_spec.rb2
-rw-r--r--spec/features/projects/show/user_interacts_with_stars_spec.rb2
-rw-r--r--spec/features/projects/show/user_manages_notifications_spec.rb2
-rw-r--r--spec/features/projects/show/user_sees_collaboration_links_spec.rb2
-rw-r--r--spec/features/projects/show/user_sees_deletion_failure_message_spec.rb2
-rw-r--r--spec/features/projects/show/user_sees_git_instructions_spec.rb2
-rw-r--r--spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb2
-rw-r--r--spec/features/projects/show/user_sees_readme_spec.rb2
-rw-r--r--spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb2
-rw-r--r--spec/features/projects/show/user_uploads_files_spec.rb2
-rw-r--r--spec/features/projects/snippets/create_snippet_spec.rb4
-rw-r--r--spec/features/projects/snippets/show_spec.rb2
-rw-r--r--spec/features/projects/snippets/user_comments_on_snippet_spec.rb2
-rw-r--r--spec/features/projects/snippets/user_deletes_snippet_spec.rb2
-rw-r--r--spec/features/projects/snippets/user_updates_snippet_spec.rb2
-rw-r--r--spec/features/projects/snippets/user_views_snippets_spec.rb2
-rw-r--r--spec/features/projects/sourcegraph_csp_spec.rb2
-rw-r--r--spec/features/projects/sub_group_issuables_spec.rb2
-rw-r--r--spec/features/projects/tags/download_buttons_spec.rb2
-rw-r--r--spec/features/projects/tags/user_edits_tags_spec.rb2
-rw-r--r--spec/features/projects/tags/user_views_tags_spec.rb2
-rw-r--r--spec/features/projects/tree/create_directory_spec.rb2
-rw-r--r--spec/features/projects/tree/create_file_spec.rb2
-rw-r--r--spec/features/projects/tree/rss_spec.rb2
-rw-r--r--spec/features/projects/tree/tree_show_spec.rb8
-rw-r--r--spec/features/projects/tree/upload_file_spec.rb2
-rw-r--r--spec/features/projects/user_changes_project_visibility_spec.rb2
-rw-r--r--spec/features/projects/user_creates_project_spec.rb2
-rw-r--r--spec/features/projects/user_sees_sidebar_spec.rb2
-rw-r--r--spec/features/projects/user_sees_user_popover_spec.rb2
-rw-r--r--spec/features/projects/user_uses_shortcuts_spec.rb2
-rw-r--r--spec/features/projects/user_views_empty_project_spec.rb2
-rw-r--r--spec/features/projects/view_on_env_spec.rb2
-rw-r--r--spec/features/projects/wiki/markdown_preview_spec.rb2
-rw-r--r--spec/features/projects/wiki/shortcuts_spec.rb2
-rw-r--r--spec/features/projects/wiki/user_creates_wiki_page_spec.rb2
-rw-r--r--spec/features/projects/wiki/user_deletes_wiki_page_spec.rb2
-rw-r--r--spec/features/projects/wiki/user_git_access_wiki_page_spec.rb2
-rw-r--r--spec/features/projects/wiki/user_updates_wiki_page_spec.rb4
-rw-r--r--spec/features/projects/wiki/user_views_wiki_empty_spec.rb8
-rw-r--r--spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb2
-rw-r--r--spec/features/projects/wiki/user_views_wiki_page_spec.rb2
-rw-r--r--spec/features/projects/wiki/user_views_wiki_pages_spec.rb2
-rw-r--r--spec/features/projects/wiki/users_views_asciidoc_page_with_includes_spec.rb2
-rw-r--r--spec/features/projects_spec.rb2
-rw-r--r--spec/features/protected_branches_spec.rb2
-rw-r--r--spec/features/protected_tags_spec.rb2
-rw-r--r--spec/features/read_only_spec.rb2
-rw-r--r--spec/features/reportable_note/commit_spec.rb2
-rw-r--r--spec/features/reportable_note/issue_spec.rb2
-rw-r--r--spec/features/reportable_note/merge_request_spec.rb2
-rw-r--r--spec/features/reportable_note/snippets_spec.rb2
-rw-r--r--spec/features/runners_spec.rb2
-rw-r--r--spec/features/search/user_searches_for_code_spec.rb2
-rw-r--r--spec/features/search/user_searches_for_comments_spec.rb2
-rw-r--r--spec/features/search/user_searches_for_commits_spec.rb2
-rw-r--r--spec/features/search/user_searches_for_issues_spec.rb2
-rw-r--r--spec/features/search/user_searches_for_merge_requests_spec.rb2
-rw-r--r--spec/features/search/user_searches_for_milestones_spec.rb2
-rw-r--r--spec/features/search/user_searches_for_projects_spec.rb2
-rw-r--r--spec/features/search/user_searches_for_users_spec.rb2
-rw-r--r--spec/features/search/user_searches_for_wiki_pages_spec.rb2
-rw-r--r--spec/features/search/user_uses_header_search_field_spec.rb10
-rw-r--r--spec/features/search/user_uses_search_filters_spec.rb2
-rw-r--r--spec/features/security/admin_access_spec.rb2
-rw-r--r--spec/features/security/dashboard_access_spec.rb2
-rw-r--r--spec/features/security/group/internal_access_spec.rb2
-rw-r--r--spec/features/security/group/private_access_spec.rb2
-rw-r--r--spec/features/security/group/public_access_spec.rb2
-rw-r--r--spec/features/security/profile_access_spec.rb2
-rw-r--r--spec/features/security/project/internal_access_spec.rb6
-rw-r--r--spec/features/security/project/private_access_spec.rb6
-rw-r--r--spec/features/security/project/public_access_spec.rb6
-rw-r--r--spec/features/security/project/snippet/internal_access_spec.rb2
-rw-r--r--spec/features/security/project/snippet/private_access_spec.rb2
-rw-r--r--spec/features/security/project/snippet/public_access_spec.rb2
-rw-r--r--spec/features/sentry_js_spec.rb6
-rw-r--r--spec/features/signed_commits_spec.rb2
-rw-r--r--spec/features/snippets/embedded_snippet_spec.rb2
-rw-r--r--spec/features/snippets/explore_spec.rb2
-rw-r--r--spec/features/snippets/internal_snippet_spec.rb2
-rw-r--r--spec/features/snippets/notes_on_personal_snippets_spec.rb2
-rw-r--r--spec/features/snippets/private_snippets_spec.rb2
-rw-r--r--spec/features/snippets/public_snippets_spec.rb2
-rw-r--r--spec/features/snippets/search_snippets_spec.rb2
-rw-r--r--spec/features/snippets/show_spec.rb2
-rw-r--r--spec/features/snippets/spam_snippets_spec.rb6
-rw-r--r--spec/features/snippets/user_creates_snippet_spec.rb40
-rw-r--r--spec/features/snippets/user_deletes_snippet_spec.rb2
-rw-r--r--spec/features/snippets/user_edits_snippet_spec.rb2
-rw-r--r--spec/features/snippets/user_snippets_spec.rb2
-rw-r--r--spec/features/snippets_spec.rb2
-rw-r--r--spec/features/static_site_editor_spec.rb2
-rw-r--r--spec/features/tags/developer_creates_tag_spec.rb2
-rw-r--r--spec/features/tags/developer_deletes_tag_spec.rb2
-rw-r--r--spec/features/tags/developer_updates_tag_spec.rb2
-rw-r--r--spec/features/tags/developer_views_tags_spec.rb2
-rw-r--r--spec/features/task_lists_spec.rb2
-rw-r--r--spec/features/triggers_spec.rb2
-rw-r--r--spec/features/u2f_spec.rb4
-rw-r--r--spec/features/unsubscribe_links_spec.rb2
-rw-r--r--spec/features/uploads/user_uploads_avatar_to_group_spec.rb2
-rw-r--r--spec/features/uploads/user_uploads_avatar_to_profile_spec.rb2
-rw-r--r--spec/features/uploads/user_uploads_file_to_note_spec.rb2
-rw-r--r--spec/features/usage_stats_consent_spec.rb2
-rw-r--r--spec/features/user_can_display_performance_bar_spec.rb2
-rw-r--r--spec/features/user_opens_link_to_comment_spec.rb2
-rw-r--r--spec/features/user_sees_revert_modal_spec.rb2
-rw-r--r--spec/features/user_sorts_things_spec.rb2
-rw-r--r--spec/features/users/active_sessions_spec.rb2
-rw-r--r--spec/features/users/add_email_to_existing_account_spec.rb2
-rw-r--r--spec/features/users/anonymous_sessions_spec.rb2
-rw-r--r--spec/features/users/login_spec.rb2
-rw-r--r--spec/features/users/logout_spec.rb2
-rw-r--r--spec/features/users/overview_spec.rb2
-rw-r--r--spec/features/users/rss_spec.rb2
-rw-r--r--spec/features/users/show_spec.rb2
-rw-r--r--spec/features/users/signup_spec.rb8
-rw-r--r--spec/features/users/snippets_spec.rb2
-rw-r--r--spec/features/users/terms_spec.rb2
-rw-r--r--spec/features/users/user_browses_projects_on_user_page_spec.rb2
-rw-r--r--spec/finders/abuse_reports_finder_spec.rb2
-rw-r--r--spec/finders/access_requests_finder_spec.rb2
-rw-r--r--spec/finders/admin/projects_finder_spec.rb2
-rw-r--r--spec/finders/admin/runners_finder_spec.rb81
-rw-r--r--spec/finders/alert_management/alerts_finder_spec.rb14
-rw-r--r--spec/finders/applications_finder_spec.rb2
-rw-r--r--spec/finders/autocomplete/acts_as_taggable_on/tags_finder_spec.rb2
-rw-r--r--spec/finders/autocomplete/group_finder_spec.rb2
-rw-r--r--spec/finders/autocomplete/move_to_project_finder_spec.rb2
-rw-r--r--spec/finders/autocomplete/project_finder_spec.rb2
-rw-r--r--spec/finders/autocomplete/users_finder_spec.rb2
-rw-r--r--spec/finders/award_emojis_finder_spec.rb2
-rw-r--r--spec/finders/boards/visits_finder_spec.rb2
-rw-r--r--spec/finders/branches_finder_spec.rb2
-rw-r--r--spec/finders/ci/daily_build_group_report_results_finder_spec.rb28
-rw-r--r--spec/finders/ci/job_artifacts_finder_spec.rb2
-rw-r--r--spec/finders/ci/jobs_finder_spec.rb2
-rw-r--r--spec/finders/ci/pipeline_schedules_finder_spec.rb2
-rw-r--r--spec/finders/ci/pipelines_finder_spec.rb2
-rw-r--r--spec/finders/ci/pipelines_for_merge_request_finder_spec.rb2
-rw-r--r--spec/finders/ci/runner_jobs_finder_spec.rb2
-rw-r--r--spec/finders/ci/runners_finder_spec.rb304
-rw-r--r--spec/finders/cluster_ancestors_finder_spec.rb2
-rw-r--r--spec/finders/clusters/knative_services_finder_spec.rb2
-rw-r--r--spec/finders/clusters_finder_spec.rb2
-rw-r--r--spec/finders/concerns/finder_methods_spec.rb2
-rw-r--r--spec/finders/concerns/finder_with_cross_project_access_spec.rb2
-rw-r--r--spec/finders/container_repositories_finder_spec.rb2
-rw-r--r--spec/finders/context_commits_finder_spec.rb2
-rw-r--r--spec/finders/contributed_projects_finder_spec.rb2
-rw-r--r--spec/finders/deployments_finder_spec.rb2
-rw-r--r--spec/finders/design_management/designs_finder_spec.rb2
-rw-r--r--spec/finders/design_management/versions_finder_spec.rb2
-rw-r--r--spec/finders/environments_finder_spec.rb2
-rw-r--r--spec/finders/events_finder_spec.rb14
-rw-r--r--spec/finders/fork_projects_finder_spec.rb2
-rw-r--r--spec/finders/fork_targets_finder_spec.rb2
-rw-r--r--spec/finders/freeze_periods_finder_spec.rb2
-rw-r--r--spec/finders/group_descendants_finder_spec.rb2
-rw-r--r--spec/finders/group_labels_finder_spec.rb2
-rw-r--r--spec/finders/group_members_finder_spec.rb2
-rw-r--r--spec/finders/group_projects_finder_spec.rb2
-rw-r--r--spec/finders/groups_finder_spec.rb8
-rw-r--r--spec/finders/issues_finder_spec.rb2
-rw-r--r--spec/finders/joined_groups_finder_spec.rb2
-rw-r--r--spec/finders/keys_finder_spec.rb2
-rw-r--r--spec/finders/labels_finder_spec.rb92
-rw-r--r--spec/finders/license_template_finder_spec.rb2
-rw-r--r--spec/finders/members_finder_spec.rb2
-rw-r--r--spec/finders/merge_request_target_project_finder_spec.rb2
-rw-r--r--spec/finders/merge_requests_finder_spec.rb79
-rw-r--r--spec/finders/metrics/dashboards/annotations_finder_spec.rb2
-rw-r--r--spec/finders/metrics/users_starred_dashboards_finder_spec.rb2
-rw-r--r--spec/finders/milestones_finder_spec.rb2
-rw-r--r--spec/finders/notes_finder_spec.rb2
-rw-r--r--spec/finders/pending_todos_finder_spec.rb2
-rw-r--r--spec/finders/personal_access_tokens_finder_spec.rb2
-rw-r--r--spec/finders/personal_projects_finder_spec.rb2
-rw-r--r--spec/finders/projects/export_job_finder_spec.rb2
-rw-r--r--spec/finders/projects/prometheus/alerts_finder_spec.rb2
-rw-r--r--spec/finders/projects/serverless/functions_finder_spec.rb2
-rw-r--r--spec/finders/projects_finder_spec.rb2
-rw-r--r--spec/finders/prometheus_metrics_finder_spec.rb2
-rw-r--r--spec/finders/protected_branches_finder_spec.rb2
-rw-r--r--spec/finders/releases_finder_spec.rb2
-rw-r--r--spec/finders/resource_label_event_finder_spec.rb61
-rw-r--r--spec/finders/resource_milestone_event_finder_spec.rb83
-rw-r--r--spec/finders/sentry_issue_finder_spec.rb2
-rw-r--r--spec/finders/serverless_domain_finder_spec.rb2
-rw-r--r--spec/finders/snippets_finder_spec.rb2
-rw-r--r--spec/finders/starred_projects_finder_spec.rb2
-rw-r--r--spec/finders/tags_finder_spec.rb2
-rw-r--r--spec/finders/template_finder_spec.rb2
-rw-r--r--spec/finders/todos_finder_spec.rb2
-rw-r--r--spec/finders/uploader_finder_spec.rb55
-rw-r--r--spec/finders/user_finder_spec.rb2
-rw-r--r--spec/finders/user_recent_events_finder_spec.rb2
-rw-r--r--spec/finders/users_finder_spec.rb14
-rw-r--r--spec/finders/users_star_projects_finder_spec.rb2
-rw-r--r--spec/finders/users_with_pending_todos_finder_spec.rb2
-rw-r--r--spec/fixtures/api/schemas/entities/merge_request_noteable.json3
-rw-r--r--spec/fixtures/api/schemas/evidences/issue.json1
-rw-r--r--spec/fixtures/api/schemas/evidences/milestone.json9
-rw-r--r--spec/fixtures/api/schemas/public_api/v4/board.json3
-rw-r--r--spec/fixtures/api/schemas/registry/repository.json15
-rw-r--r--spec/fixtures/api/schemas/release/link.json3
-rw-r--r--spec/fixtures/gitlab/database/structure_example.sql1
-rw-r--r--spec/fixtures/gitlab/database/structure_example_cleaned.sql2
-rw-r--r--spec/fixtures/lib/gitlab/metrics/dashboard/sample_dashboard.yml13
-rw-r--r--spec/fixtures/lib/gitlab/metrics/dashboard/schemas/dashboard.json4
-rw-r--r--spec/fixtures/lib/gitlab/metrics/dashboard/schemas/links.json9
-rw-r--r--spec/fixtures/lib/gitlab/metrics/dashboard/schemas/templating.json8
-rw-r--r--spec/fixtures/lib/gitlab/metrics/dashboard/schemas/text_variable_full_syntax.json12
-rw-r--r--spec/fixtures/lib/gitlab/metrics/dashboard/schemas/text_variable_options.json7
-rw-r--r--spec/fixtures/lib/gitlab/metrics/dashboard/schemas/variables.json12
-rw-r--r--spec/fixtures/lsif.json.gzbin759 -> 0 bytes
-rw-r--r--spec/fixtures/packages/conan/package_files/conan_package.tgzbin0 -> 2125 bytes
-rw-r--r--spec/fixtures/packages/conan/package_files/conaninfo.txt33
-rw-r--r--spec/fixtures/packages/conan/package_files/conanmanifest.txt4
-rw-r--r--spec/fixtures/packages/conan/recipe_files/conanfile.py47
-rw-r--r--spec/fixtures/packages/conan/recipe_files/conanmanifest.txt2
-rw-r--r--spec/fixtures/packages/maven/maven-metadata.xml25
-rw-r--r--spec/fixtures/packages/maven/my-app-1.0-20180724.124855-1.jarbin0 -> 2526 bytes
-rw-r--r--spec/fixtures/packages/maven/my-app-1.0-20180724.124855-1.pom34
-rw-r--r--spec/fixtures/packages/npm/foo-1.0.1.tgzbin0 -> 134 bytes
-rw-r--r--spec/fixtures/packages/npm/payload.json30
-rw-r--r--spec/fixtures/packages/npm/payload_with_duplicated_packages.json44
-rw-r--r--spec/fixtures/packages/nuget/package.nupkgbin0 -> 3513 bytes
-rw-r--r--spec/fixtures/packages/nuget/with_dependencies.nuspec19
-rw-r--r--spec/fixtures/packages/nuget/with_metadata.nuspec19
-rw-r--r--spec/fixtures/packages/pypi/sample-project.tar.gzbin0 -> 1149 bytes
-rw-r--r--spec/fixtures/trace/sample_trace3
-rw-r--r--spec/frontend/.eslintrc.yml2
-rw-r--r--spec/frontend/__mocks__/lodash/throttle.js4
-rw-r--r--spec/frontend/__mocks__/monaco-editor/index.js3
-rw-r--r--spec/frontend/alert_management/components/alert_management_detail_spec.js161
-rw-r--r--spec/frontend/alert_management/components/alert_management_list_spec.js280
-rw-r--r--spec/frontend/alert_management/components/alert_management_system_note_spec.js34
-rw-r--r--spec/frontend/alert_management/components/alert_managment_sidebar_assignees_spec.js133
-rw-r--r--spec/frontend/alert_management/components/alert_sidebar_spec.js55
-rw-r--r--spec/frontend/alert_management/components/alert_sidebar_status_spec.js107
-rw-r--r--spec/frontend/alert_management/mocks/alerts.json91
-rw-r--r--spec/frontend/alerts_service_settings/components/__snapshots__/alerts_service_form_spec.js.snap2
-rw-r--r--spec/frontend/alerts_service_settings/components/alerts_service_form_spec.js7
-rw-r--r--spec/frontend/api_spec.js56
-rw-r--r--spec/frontend/authentication/u2f/authenticate_spec.js109
-rw-r--r--spec/frontend/authentication/u2f/mock_u2f_device.js (renamed from spec/frontend/u2f/mock_u2f_device.js)0
-rw-r--r--spec/frontend/authentication/u2f/register_spec.js83
-rw-r--r--spec/frontend/authentication/u2f/util_spec.js61
-rw-r--r--spec/frontend/awards_handler_spec.js403
-rw-r--r--spec/frontend/batch_comments/components/diff_file_drafts_spec.js61
-rw-r--r--spec/frontend/batch_comments/components/draft_note_spec.js125
-rw-r--r--spec/frontend/batch_comments/components/drafts_count_spec.js43
-rw-r--r--spec/frontend/batch_comments/components/preview_item_spec.js130
-rw-r--r--spec/frontend/batch_comments/components/publish_button_spec.js52
-rw-r--r--spec/frontend/batch_comments/components/publish_dropdown_spec.js96
-rw-r--r--spec/frontend/batch_comments/mock_data.js27
-rw-r--r--spec/frontend/batch_comments/stores/modules/batch_comments/actions_spec.js403
-rw-r--r--spec/frontend/batch_comments/stores/modules/batch_comments/getters_spec.js27
-rw-r--r--spec/frontend/batch_comments/stores/modules/batch_comments/mutations_spec.js159
-rw-r--r--spec/frontend/behaviors/autosize_spec.js (renamed from spec/javascripts/behaviors/autosize_spec.js)0
-rw-r--r--spec/frontend/behaviors/bind_in_out_spec.js10
-rw-r--r--spec/frontend/behaviors/copy_as_gfm_spec.js125
-rw-r--r--spec/frontend/behaviors/gl_emoji/unicode_support_map_spec.js52
-rw-r--r--spec/frontend/behaviors/markdown/highlight_current_user_spec.js (renamed from spec/javascripts/behaviors/markdown/highlight_current_user_spec.js)0
-rw-r--r--spec/frontend/behaviors/requires_input_spec.js (renamed from spec/javascripts/behaviors/requires_input_spec.js)0
-rw-r--r--spec/frontend/behaviors/shortcuts/shortcuts_issuable_spec.js322
-rw-r--r--spec/frontend/blob/components/__snapshots__/blob_header_filepath_spec.js.snap2
-rw-r--r--spec/frontend/blob/components/blob_header_default_actions_spec.js8
-rw-r--r--spec/frontend/blob/components/blob_header_filepath_spec.js5
-rw-r--r--spec/frontend/blob/components/blob_header_spec.js11
-rw-r--r--spec/frontend/boards/board_list_helper.js (renamed from spec/javascripts/boards/board_list_common_spec.js)0
-rw-r--r--spec/frontend/boards/board_list_spec.js2
-rw-r--r--spec/frontend/boards/components/board_column_spec.js88
-rw-r--r--spec/frontend/boards/components/board_list_header_spec.js166
-rw-r--r--spec/frontend/boards/stores/actions_spec.js17
-rw-r--r--spec/frontend/boards/stores/mutations_spec.js147
-rw-r--r--spec/frontend/ci_variable_list/components/ci_variable_modal_spec.js40
-rw-r--r--spec/frontend/clusters/clusters_bundle_spec.js9
-rw-r--r--spec/frontend/clusters/components/__snapshots__/applications_spec.js.snap89
-rw-r--r--spec/frontend/clusters/components/application_row_spec.js439
-rw-r--r--spec/frontend/clusters/components/applications_spec.js418
-rw-r--r--spec/frontend/clusters/components/fluentd_output_settings_spec.js12
-rw-r--r--spec/frontend/clusters/components/update_application_confirmation_modal_spec.js52
-rw-r--r--spec/frontend/clusters_list/components/clusters_spec.js158
-rw-r--r--spec/frontend/clusters_list/mock_data.js75
-rw-r--r--spec/frontend/clusters_list/store/actions_spec.js144
-rw-r--r--spec/frontend/code_navigation/components/__snapshots__/popover_spec.js.snap22
-rw-r--r--spec/frontend/code_navigation/components/popover_spec.js19
-rw-r--r--spec/frontend/collapsed_sidebar_todo_spec.js172
-rw-r--r--spec/frontend/comment_type_toggle_spec.js169
-rw-r--r--spec/frontend/confirm_modal_spec.js6
-rw-r--r--spec/frontend/contributors/component/__snapshots__/contributors_spec.js.snap6
-rw-r--r--spec/frontend/create_cluster/eks_cluster/store/actions_spec.js8
-rw-r--r--spec/frontend/design_management/components/__snapshots__/design_note_pin_spec.js.snap12
-rw-r--r--spec/frontend/design_management/components/design_note_pin_spec.js4
-rw-r--r--spec/frontend/design_management/components/design_notes/__snapshots__/design_note_spec.js.snap8
-rw-r--r--spec/frontend/design_management/components/design_notes/design_discussion_spec.js241
-rw-r--r--spec/frontend/design_management/components/design_notes/design_reply_form_spec.js6
-rw-r--r--spec/frontend/design_management/components/design_notes/toggle_replies_widget_spec.js98
-rw-r--r--spec/frontend/design_management/components/design_overlay_spec.js103
-rw-r--r--spec/frontend/design_management/components/design_presentation_spec.js9
-rw-r--r--spec/frontend/design_management/components/design_sidebar_spec.js236
-rw-r--r--spec/frontend/design_management/components/upload/__snapshots__/button_spec.js.snap6
-rw-r--r--spec/frontend/design_management/mock_data/design.js20
-rw-r--r--spec/frontend/design_management/mock_data/notes.js14
-rw-r--r--spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap116
-rw-r--r--spec/frontend/design_management/pages/design/index_spec.js137
-rw-r--r--spec/frontend/design_management/pages/index_spec.js34
-rw-r--r--spec/frontend/design_management/router_spec.js1
-rw-r--r--spec/frontend/design_management/utils/design_management_utils_spec.js8
-rw-r--r--spec/frontend/diffs/components/diff_file_spec.js2
-rw-r--r--spec/frontend/diffs/components/diff_line_note_form_spec.js14
-rw-r--r--spec/frontend/diffs/components/inline_diff_view_spec.js2
-rw-r--r--spec/frontend/diffs/components/parallel_diff_view_spec.js2
-rw-r--r--spec/frontend/diffs/mock_data/diff_file.js1
-rw-r--r--spec/frontend/diffs/mock_data/diff_metadata.js58
-rw-r--r--spec/frontend/diffs/store/actions_spec.js228
-rw-r--r--spec/frontend/diffs/store/utils_spec.js243
-rw-r--r--spec/frontend/diffs/utils/uuids_spec.js92
-rw-r--r--spec/frontend/droplab/drop_down_spec.js662
-rw-r--r--spec/frontend/droplab/hook_spec.js94
-rw-r--r--spec/frontend/droplab/plugins/input_setter_spec.js259
-rw-r--r--spec/frontend/dropzone_input_spec.js97
-rw-r--r--spec/frontend/environment.js2
-rw-r--r--spec/frontend/environments/environments_app_spec.js4
-rw-r--r--spec/frontend/error_tracking/components/error_details_spec.js72
-rw-r--r--spec/frontend/error_tracking/components/error_tracking_list_spec.js36
-rw-r--r--spec/frontend/filtered_search/filtered_search_dropdown_manager_spec.js130
-rw-r--r--spec/frontend/filtered_search/filtered_search_visual_tokens_spec.js732
-rw-r--r--spec/frontend/fixtures/abuse_reports.rb2
-rw-r--r--spec/frontend/fixtures/admin_users.rb2
-rw-r--r--spec/frontend/fixtures/application_settings.rb2
-rw-r--r--spec/frontend/fixtures/autocomplete_sources.rb2
-rw-r--r--spec/frontend/fixtures/blob.rb2
-rw-r--r--spec/frontend/fixtures/boards.rb2
-rw-r--r--spec/frontend/fixtures/branches.rb2
-rw-r--r--spec/frontend/fixtures/clusters.rb2
-rw-r--r--spec/frontend/fixtures/commit.rb2
-rw-r--r--spec/frontend/fixtures/deploy_keys.rb2
-rw-r--r--spec/frontend/fixtures/groups.rb2
-rw-r--r--spec/frontend/fixtures/issues.rb4
-rw-r--r--spec/frontend/fixtures/jobs.rb2
-rw-r--r--spec/frontend/fixtures/labels.rb2
-rw-r--r--spec/frontend/fixtures/merge_requests.rb2
-rw-r--r--spec/frontend/fixtures/merge_requests_diffs.rb2
-rw-r--r--spec/frontend/fixtures/metrics_dashboard.rb2
-rw-r--r--spec/frontend/fixtures/pipeline_schedules.rb2
-rw-r--r--spec/frontend/fixtures/pipelines.rb2
-rw-r--r--spec/frontend/fixtures/projects.rb2
-rw-r--r--spec/frontend/fixtures/prometheus_service.rb2
-rw-r--r--spec/frontend/fixtures/raw.rb2
-rw-r--r--spec/frontend/fixtures/search.rb2
-rw-r--r--spec/frontend/fixtures/services.rb2
-rw-r--r--spec/frontend/fixtures/sessions.rb2
-rw-r--r--spec/frontend/fixtures/snippet.rb2
-rw-r--r--spec/frontend/fixtures/static/global_search_input.html (renamed from spec/frontend/fixtures/static/search_autocomplete.html)0
-rw-r--r--spec/frontend/fixtures/static/oauth_remember_me.html22
-rw-r--r--spec/frontend/fixtures/test_report.rb2
-rw-r--r--spec/frontend/fixtures/todos.rb2
-rw-r--r--spec/frontend/fixtures/u2f.rb2
-rw-r--r--spec/frontend/gl_dropdown_spec.js345
-rw-r--r--spec/frontend/gl_form_spec.js115
-rw-r--r--spec/frontend/global_search_input_spec.js215
-rw-r--r--spec/frontend/header_spec.js4
-rw-r--r--spec/frontend/helpers/dom_shims/element_scroll_to.js6
-rw-r--r--spec/frontend/helpers/dom_shims/image_element_properties.js2
-rw-r--r--spec/frontend/helpers/dom_shims/index.js2
-rw-r--r--spec/frontend/helpers/dom_shims/mutation_observer.js7
-rw-r--r--spec/frontend/helpers/local_storage_helper.js20
-rw-r--r--spec/frontend/helpers/local_storage_helper_spec.js21
-rw-r--r--spec/frontend/helpers/mock_dom_observer.js94
-rw-r--r--spec/frontend/helpers/mock_window_location_helper.js43
-rw-r--r--spec/frontend/helpers/scroll_into_view_promise.js28
-rw-r--r--spec/frontend/helpers/set_window_location_helper_spec.js2
-rw-r--r--spec/frontend/helpers/vue_mock_directive.js17
-rw-r--r--spec/frontend/helpers/wait_for_attribute_change.js16
-rw-r--r--spec/frontend/ide/commit_icon_spec.js45
-rw-r--r--spec/frontend/ide/components/branches/item_spec.js11
-rw-r--r--spec/frontend/ide/components/commit_sidebar/form_spec.js136
-rw-r--r--spec/frontend/ide/components/commit_sidebar/list_item_spec.js13
-rw-r--r--spec/frontend/ide/components/commit_sidebar/message_field_spec.js170
-rw-r--r--spec/frontend/ide/components/ide_sidebar_nav_spec.js118
-rw-r--r--spec/frontend/ide/components/ide_spec.js9
-rw-r--r--spec/frontend/ide/components/ide_status_list_spec.js16
-rw-r--r--spec/frontend/ide/components/jobs/__snapshots__/stage_spec.js.snap4
-rw-r--r--spec/frontend/ide/components/jobs/detail_spec.js187
-rw-r--r--spec/frontend/ide/components/merge_requests/item_spec.js106
-rw-r--r--spec/frontend/ide/components/new_dropdown/modal_spec.js40
-rw-r--r--spec/frontend/ide/components/new_dropdown/upload_spec.js2
-rw-r--r--spec/frontend/ide/components/panes/collapsible_sidebar_spec.js113
-rw-r--r--spec/frontend/ide/components/panes/right_spec.js57
-rw-r--r--spec/frontend/ide/components/pipelines/list_spec.js2
-rw-r--r--spec/frontend/ide/components/repo_commit_section_spec.js46
-rw-r--r--spec/frontend/ide/components/repo_editor_spec.js664
-rw-r--r--spec/frontend/ide/components/repo_tab_spec.js12
-rw-r--r--spec/frontend/ide/components/repo_tabs_spec.js2
-rw-r--r--spec/frontend/ide/components/resizable_panel_spec.js114
-rw-r--r--spec/frontend/ide/components/terminal/empty_state_spec.js107
-rw-r--r--spec/frontend/ide/components/terminal/session_spec.js96
-rw-r--r--spec/frontend/ide/components/terminal/terminal_controls_spec.js65
-rw-r--r--spec/frontend/ide/components/terminal/terminal_spec.js225
-rw-r--r--spec/frontend/ide/components/terminal/view_spec.js91
-rw-r--r--spec/frontend/ide/components/terminal_sync/terminal_sync_status_safe_spec.js47
-rw-r--r--spec/frontend/ide/components/terminal_sync/terminal_sync_status_spec.js99
-rw-r--r--spec/frontend/ide/file_helpers.js35
-rw-r--r--spec/frontend/ide/ide_router_spec.js37
-rw-r--r--spec/frontend/ide/lib/common/model_spec.js72
-rw-r--r--spec/frontend/ide/lib/create_diff_spec.js182
-rw-r--r--spec/frontend/ide/lib/create_file_diff_spec.js163
-rw-r--r--spec/frontend/ide/lib/diff/diff_spec.js8
-rw-r--r--spec/frontend/ide/lib/editor_options_spec.js11
-rw-r--r--spec/frontend/ide/lib/editor_spec.js46
-rw-r--r--spec/frontend/ide/lib/editorconfig/mock_data.js146
-rw-r--r--spec/frontend/ide/lib/editorconfig/parser_spec.js18
-rw-r--r--spec/frontend/ide/lib/editorconfig/rules_mapper_spec.js43
-rw-r--r--spec/frontend/ide/lib/files_spec.js4
-rw-r--r--spec/frontend/ide/lib/mirror_spec.js184
-rw-r--r--spec/frontend/ide/stores/actions/file_spec.js40
-rw-r--r--spec/frontend/ide/stores/actions/merge_request_spec.js504
-rw-r--r--spec/frontend/ide/stores/actions/project_spec.js397
-rw-r--r--spec/frontend/ide/stores/actions/tree_spec.js218
-rw-r--r--spec/frontend/ide/stores/actions_spec.js1062
-rw-r--r--spec/frontend/ide/stores/extend_spec.js74
-rw-r--r--spec/frontend/ide/stores/getters_spec.js65
-rw-r--r--spec/frontend/ide/stores/modules/commit/actions_spec.js598
-rw-r--r--spec/frontend/ide/stores/modules/pane/getters_spec.js32
-rw-r--r--spec/frontend/ide/stores/modules/router/actions_spec.js19
-rw-r--r--spec/frontend/ide/stores/modules/router/mutations_spec.js23
-rw-r--r--spec/frontend/ide/stores/modules/terminal/actions/checks_spec.js289
-rw-r--r--spec/frontend/ide/stores/modules/terminal/actions/session_controls_spec.js300
-rw-r--r--spec/frontend/ide/stores/modules/terminal/actions/session_status_spec.js169
-rw-r--r--spec/frontend/ide/stores/modules/terminal/actions/setup_spec.js40
-rw-r--r--spec/frontend/ide/stores/modules/terminal/getters_spec.js50
-rw-r--r--spec/frontend/ide/stores/modules/terminal/messages_spec.js38
-rw-r--r--spec/frontend/ide/stores/modules/terminal/mutations_spec.js142
-rw-r--r--spec/frontend/ide/stores/modules/terminal_sync/actions_spec.js118
-rw-r--r--spec/frontend/ide/stores/modules/terminal_sync/mutations_spec.js89
-rw-r--r--spec/frontend/ide/stores/mutations/file_spec.js37
-rw-r--r--spec/frontend/ide/stores/mutations_spec.js36
-rw-r--r--spec/frontend/ide/stores/plugins/terminal_spec.js58
-rw-r--r--spec/frontend/ide/stores/plugins/terminal_sync_spec.js72
-rw-r--r--spec/frontend/ide/stores/utils_spec.js93
-rw-r--r--spec/frontend/ide/sync_router_and_store_spec.js150
-rw-r--r--spec/frontend/ide/utils_spec.js137
-rw-r--r--spec/frontend/import_projects/components/bitbucket_status_table_spec.js59
-rw-r--r--spec/frontend/import_projects/components/import_projects_table_spec.js286
-rw-r--r--spec/frontend/import_projects/components/provider_repo_table_row_spec.js11
-rw-r--r--spec/frontend/import_projects/store/actions_spec.js189
-rw-r--r--spec/frontend/import_projects/store/getters_spec.js15
-rw-r--r--spec/frontend/importer_status_spec.js141
-rw-r--r--spec/frontend/integrations/edit/components/dynamic_field_spec.js179
-rw-r--r--spec/frontend/integrations/edit/components/integration_form_spec.js21
-rw-r--r--spec/frontend/issue_show/components/app_spec.js335
-rw-r--r--spec/frontend/issue_show/components/pinned_links_spec.js34
-rw-r--r--spec/frontend/jira_import/components/jira_import_app_spec.js28
-rw-r--r--spec/frontend/jira_import/mock_data.js72
-rw-r--r--spec/frontend/jira_import/utils/cache_update_spec.js64
-rw-r--r--spec/frontend/jira_import/utils/jira_import_utils_spec.js91
-rw-r--r--spec/frontend/jira_import/utils_spec.js62
-rw-r--r--spec/frontend/jobs/components/artifacts_block_spec.js150
-rw-r--r--spec/frontend/jobs/components/job_log_spec.js2
-rw-r--r--spec/frontend/jobs/components/log/mock_data.js2
-rw-r--r--spec/frontend/labels_issue_sidebar_spec.js99
-rw-r--r--spec/frontend/lazy_loader_spec.js153
-rw-r--r--spec/frontend/lib/utils/common_utils_spec.js81
-rw-r--r--spec/frontend/lib/utils/text_markdown_spec.js16
-rw-r--r--spec/frontend/lib/utils/text_utility_spec.js16
-rw-r--r--spec/frontend/lib/utils/url_utility_spec.js17
-rw-r--r--spec/frontend/line_highlighter_spec.js268
-rw-r--r--spec/frontend/logs/components/environment_logs_spec.js4
-rw-r--r--spec/frontend/logs/stores/actions_spec.js73
-rw-r--r--spec/frontend/matchers.js33
-rw-r--r--spec/frontend/matchers_spec.js48
-rw-r--r--spec/frontend/merge_request_spec.js191
-rw-r--r--spec/frontend/merge_request_tabs_spec.js293
-rw-r--r--spec/frontend/mini_pipeline_graph_dropdown_spec.js106
-rw-r--r--spec/frontend/monitoring/__snapshots__/alert_widget_spec.js.snap6
-rw-r--r--spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap10
-rw-r--r--spec/frontend/monitoring/components/charts/anomaly_spec.js2
-rw-r--r--spec/frontend/monitoring/components/charts/column_spec.js52
-rw-r--r--spec/frontend/monitoring/components/charts/heatmap_spec.js107
-rw-r--r--spec/frontend/monitoring/components/charts/stacked_column_spec.js193
-rw-r--r--spec/frontend/monitoring/components/charts/time_series_spec.js368
-rw-r--r--spec/frontend/monitoring/components/dashboard_panel_spec.js160
-rw-r--r--spec/frontend/monitoring/components/dashboard_spec.js215
-rw-r--r--spec/frontend/monitoring/components/dashboard_template_spec.js13
-rw-r--r--spec/frontend/monitoring/components/dashboard_url_time_spec.js5
-rw-r--r--spec/frontend/monitoring/components/duplicate_dashboard_form_spec.js2
-rw-r--r--spec/frontend/monitoring/components/embeds/metric_embed_spec.js3
-rw-r--r--spec/frontend/monitoring/components/embeds/mock_data.js1
-rw-r--r--spec/frontend/monitoring/components/graph_group_spec.js20
-rw-r--r--spec/frontend/monitoring/components/links_section_spec.js64
-rw-r--r--spec/frontend/monitoring/components/variables_section_spec.js17
-rw-r--r--spec/frontend/monitoring/mock_data.js137
-rw-r--r--spec/frontend/monitoring/pages/dashboard_page_spec.js36
-rw-r--r--spec/frontend/monitoring/store/actions_spec.js116
-rw-r--r--spec/frontend/monitoring/store/getters_spec.js40
-rw-r--r--spec/frontend/monitoring/store/index_spec.js23
-rw-r--r--spec/frontend/monitoring/store/mutations_spec.js26
-rw-r--r--spec/frontend/monitoring/store/utils_spec.js188
-rw-r--r--spec/frontend/monitoring/store/variable_mapping_spec.js27
-rw-r--r--spec/frontend/monitoring/store_utils.js23
-rw-r--r--spec/frontend/namespace_storage_limit_alert_spec.js36
-rw-r--r--spec/frontend/notes/components/diff_with_note_spec.js9
-rw-r--r--spec/frontend/notes/components/discussion_reply_placeholder_spec.js2
-rw-r--r--spec/frontend/notes/components/multiline_comment_utils_spec.js49
-rw-r--r--spec/frontend/notes/components/note_actions_spec.js60
-rw-r--r--spec/frontend/notes/components/note_form_spec.js54
-rw-r--r--spec/frontend/notes/components/noteable_note_spec.js53
-rw-r--r--spec/frontend/notes/mixins/discussion_navigation_spec.js12
-rw-r--r--spec/frontend/notes/mock_data.js13
-rw-r--r--spec/frontend/notes/stores/actions_spec.js214
-rw-r--r--spec/frontend/notes/stores/mutation_spec.js117
-rw-r--r--spec/frontend/oauth_remember_me_spec.js26
-rw-r--r--spec/frontend/onboarding_issues/index_spec.js137
-rw-r--r--spec/frontend/operation_settings/components/external_dashboard_spec.js168
-rw-r--r--spec/frontend/operation_settings/components/metrics_settings_spec.js214
-rw-r--r--spec/frontend/operation_settings/store/mutations_spec.js12
-rw-r--r--spec/frontend/pager_spec.js167
-rw-r--r--spec/frontend/pages/dashboard/todos/index/todos_spec.js111
-rw-r--r--spec/frontend/pages/import/bitbucket_server/components/bitbucket_server_status_table_spec.js47
-rw-r--r--spec/frontend/pages/projects/graphs/__snapshots__/code_coverage_spec.js.snap88
-rw-r--r--spec/frontend/pages/projects/graphs/code_coverage_spec.js164
-rw-r--r--spec/frontend/pages/projects/graphs/mock_data.js60
-rw-r--r--spec/frontend/pages/sessions/new/preserve_url_fragment_spec.js25
-rw-r--r--spec/frontend/pages/sessions/new/signin_tabs_memoizer_spec.js218
-rw-r--r--spec/frontend/pdf/index_spec.js62
-rw-r--r--spec/frontend/pdf/page_spec.js39
-rw-r--r--spec/frontend/performance_bar/components/detailed_metric_spec.js98
-rw-r--r--spec/frontend/performance_bar/index_spec.js85
-rw-r--r--spec/frontend/persistent_user_callout_spec.js158
-rw-r--r--spec/frontend/pipelines/components/dag/__snapshots__/dag_graph_spec.js.snap230
-rw-r--r--spec/frontend/pipelines/components/dag/dag_graph_spec.js218
-rw-r--r--spec/frontend/pipelines/components/dag/dag_spec.js137
-rw-r--r--spec/frontend/pipelines/components/dag/drawing_utils_spec.js57
-rw-r--r--spec/frontend/pipelines/components/dag/mock_data.js390
-rw-r--r--spec/frontend/pipelines/components/dag/parsing_utils_spec.js133
-rw-r--r--spec/frontend/pipelines/components/pipelines_filtered_search_spec.js123
-rw-r--r--spec/frontend/pipelines/graph/graph_component_spec.js5
-rw-r--r--spec/frontend/pipelines/mock_data.js98
-rw-r--r--spec/frontend/pipelines/pipelines_spec.js9
-rw-r--r--spec/frontend/pipelines/tokens/pipeline_branch_name_token_spec.js17
-rw-r--r--spec/frontend/pipelines/tokens/pipeline_status_token_spec.js62
-rw-r--r--spec/frontend/pipelines/tokens/pipeline_tag_name_token_spec.js98
-rw-r--r--spec/frontend/pipelines/tokens/pipeline_trigger_author_token_spec.js10
-rw-r--r--spec/frontend/projects/experiment_new_project_creation/components/app_spec.js70
-rw-r--r--spec/frontend/projects/experiment_new_project_creation/components/legacy_container_spec.js63
-rw-r--r--spec/frontend/projects/experiment_new_project_creation/components/welcome_spec.js31
-rw-r--r--spec/frontend/projects/pipelines/charts/components/__snapshots__/pipelines_area_chart_spec.js.snap3
-rw-r--r--spec/frontend/read_more_spec.js (renamed from spec/javascripts/read_more_spec.js)0
-rw-r--r--spec/frontend/registry/explorer/components/__snapshots__/project_empty_state_spec.js.snap119
-rw-r--r--spec/frontend/registry/explorer/components/details_page/__snapshots__/tags_loader_spec.js.snap63
-rw-r--r--spec/frontend/registry/explorer/components/details_page/delete_alert_spec.js116
-rw-r--r--spec/frontend/registry/explorer/components/details_page/delete_modal_spec.js79
-rw-r--r--spec/frontend/registry/explorer/components/details_page/details_header_spec.js32
-rw-r--r--spec/frontend/registry/explorer/components/details_page/empty_tags_state.js43
-rw-r--r--spec/frontend/registry/explorer/components/details_page/tags_loader_spec.js49
-rw-r--r--spec/frontend/registry/explorer/components/details_page/tags_table_spec.js286
-rw-r--r--spec/frontend/registry/explorer/components/group_empty_state_spec.js40
-rw-r--r--spec/frontend/registry/explorer/components/image_list_spec.js74
-rw-r--r--spec/frontend/registry/explorer/components/list_page/__snapshots__/group_empty_state_spec.js.snap (renamed from spec/frontend/registry/explorer/components/__snapshots__/group_empty_state_spec.js.snap)0
-rw-r--r--spec/frontend/registry/explorer/components/list_page/__snapshots__/project_empty_state_spec.js.snap119
-rw-r--r--spec/frontend/registry/explorer/components/list_page/cli_commands_spec.js120
-rw-r--r--spec/frontend/registry/explorer/components/list_page/group_empty_state_spec.js40
-rw-r--r--spec/frontend/registry/explorer/components/list_page/image_list_row_spec.js140
-rw-r--r--spec/frontend/registry/explorer/components/list_page/image_list_spec.js62
-rw-r--r--spec/frontend/registry/explorer/components/list_page/project_empty_state_spec.js46
-rw-r--r--spec/frontend/registry/explorer/components/list_page/registry_header_spec.js221
-rw-r--r--spec/frontend/registry/explorer/components/project_empty_state_spec.js46
-rw-r--r--spec/frontend/registry/explorer/components/project_policy_alert_spec.js132
-rw-r--r--spec/frontend/registry/explorer/components/quickstart_dropdown_spec.js120
-rw-r--r--spec/frontend/registry/explorer/mock_data.js4
-rw-r--r--spec/frontend/registry/explorer/pages/details_spec.js456
-rw-r--r--spec/frontend/registry/explorer/pages/index_spec.js4
-rw-r--r--spec/frontend/registry/explorer/pages/list_spec.js57
-rw-r--r--spec/frontend/registry/explorer/stores/getters_spec.js29
-rw-r--r--spec/frontend/registry/explorer/stores/mutations_spec.js9
-rw-r--r--spec/frontend/registry/explorer/stubs.js21
-rw-r--r--spec/frontend/releases/components/app_index_spec.js150
-rw-r--r--spec/frontend/releases/components/asset_links_form_spec.js34
-rw-r--r--spec/frontend/releases/components/release_block_assets_spec.js137
-rw-r--r--spec/frontend/releases/mock_data.js91
-rw-r--r--spec/frontend/releases/stores/modules/detail/actions_spec.js49
-rw-r--r--spec/frontend/releases/stores/modules/detail/mutations_spec.js41
-rw-r--r--spec/frontend/releases/stores/modules/list/actions_spec.js131
-rw-r--r--spec/frontend/releases/stores/modules/list/helpers.js (renamed from spec/javascripts/releases/stores/modules/list/helpers.js)0
-rw-r--r--spec/frontend/releases/stores/modules/list/mutations_spec.js (renamed from spec/javascripts/releases/stores/modules/list/mutations_spec.js)0
-rw-r--r--spec/frontend/reports/components/grouped_test_reports_app_spec.js320
-rw-r--r--spec/frontend/reports/mock_data/new_errors_report.json20
-rw-r--r--spec/frontend/right_sidebar_spec.js87
-rw-r--r--spec/frontend/shortcuts_spec.js46
-rw-r--r--spec/frontend/sidebar/confidential_issue_sidebar_spec.js7
-rw-r--r--spec/frontend/snippets/components/__snapshots__/snippet_blob_edit_spec.js.snap2
-rw-r--r--spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap82
-rw-r--r--spec/frontend/snippets/components/__snapshots__/snippet_description_view_spec.js.snap2
-rw-r--r--spec/frontend/snippets/components/edit_spec.js136
-rw-r--r--spec/frontend/snippets/components/snippet_blob_view_spec.js20
-rw-r--r--spec/frontend/snippets/components/snippet_description_edit_spec.js4
-rw-r--r--spec/frontend/static_site_editor/components/edit_area_spec.js36
-rw-r--r--spec/frontend/static_site_editor/components/unsaved_changes_confirm_dialog_spec.js44
-rw-r--r--spec/frontend/static_site_editor/mock_data.js11
-rw-r--r--spec/frontend/static_site_editor/pages/home_spec.js16
-rw-r--r--spec/frontend/static_site_editor/services/parse_source_file_spec.js64
-rw-r--r--spec/frontend/static_site_editor/services/submit_content_changes_spec.js30
-rw-r--r--spec/frontend/test_setup.js15
-rw-r--r--spec/frontend/toggle_buttons_spec.js115
-rw-r--r--spec/frontend/tracking_spec.js25
-rw-r--r--spec/frontend/u2f/authenticate_spec.js109
-rw-r--r--spec/frontend/u2f/register_spec.js83
-rw-r--r--spec/frontend/u2f/util_spec.js61
-rw-r--r--spec/frontend/user_popovers_spec.js99
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_widget_alert_message_spec.js (renamed from spec/javascripts/vue_mr_widget/components/mr_widget_alert_message_spec.js)0
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_widget_author_spec.js39
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_widget_author_time_spec.js44
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_widget_header_spec.js313
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_widget_memory_usage_spec.js239
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_widget_merge_help_spec.js70
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_widget_pipeline_spec.js326
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_widget_rebase_spec.js139
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_widget_related_links_spec.js85
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_widget_status_icon_spec.js48
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_widget_terraform_plan_spec.js10
-rw-r--r--spec/frontend/vue_mr_widget/components/review_app_link_spec.js52
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_archived_spec.js31
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_auto_merge_enabled_spec.js230
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_checking_spec.js31
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_closed_spec.js69
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_conflicts_spec.js226
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js156
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_merged_spec.js219
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_merging_spec.js43
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js40
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_not_allowed_spec.js26
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js (renamed from spec/javascripts/vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js)0
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js26
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js19
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js981
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js25
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_squash_before_merge_spec.js (renamed from spec/javascripts/vue_mr_widget/components/states/mr_widget_squash_before_merge_spec.js)0
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_unresolved_discussions_spec.js46
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_wip_spec.js104
-rw-r--r--spec/frontend/vue_shared/components/date_time_picker/date_time_picker_lib_spec.js178
-rw-r--r--spec/frontend/vue_shared/components/date_time_picker/date_time_picker_spec.js274
-rw-r--r--spec/frontend/vue_shared/components/deprecated_modal_2_spec.js258
-rw-r--r--spec/frontend/vue_shared/components/deprecated_modal_spec.js73
-rw-r--r--spec/frontend/vue_shared/components/diff_viewer/diff_viewer_spec.js30
-rw-r--r--spec/frontend/vue_shared/components/diff_viewer/viewers/renamed_spec.js283
-rw-r--r--spec/frontend/vue_shared/components/file_finder/index_spec.js368
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js259
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js64
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js150
-rw-r--r--spec/frontend/vue_shared/components/icon_spec.js78
-rw-r--r--spec/frontend/vue_shared/components/issue/related_issuable_item_spec.js14
-rw-r--r--spec/frontend/vue_shared/components/markdown/__snapshots__/suggestion_diff_spec.js.snap3
-rw-r--r--spec/frontend/vue_shared/components/markdown/field_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/markdown/suggestion_diff_header_spec.js163
-rw-r--r--spec/frontend/vue_shared/components/markdown/suggestion_diff_spec.js34
-rw-r--r--spec/frontend/vue_shared/components/panel_resizer_spec.js85
-rw-r--r--spec/frontend/vue_shared/components/pikaday_spec.js38
-rw-r--r--spec/frontend/vue_shared/components/project_selector/project_selector_spec.js23
-rw-r--r--spec/frontend/vue_shared/components/rich_content_editor/editor_service_spec.js77
-rw-r--r--spec/frontend/vue_shared/components/rich_content_editor/modals/add_image_modal_spec.js41
-rw-r--r--spec/frontend/vue_shared/components/rich_content_editor/rich_content_editor_spec.js59
-rw-r--r--spec/frontend/vue_shared/components/rich_content_editor/toolbar_item_spec.js51
-rw-r--r--spec/frontend/vue_shared/components/rich_content_editor/toolbar_service_spec.js29
-rw-r--r--spec/frontend/vue_shared/components/sidebar/date_picker_spec.js162
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js5
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/label_item_spec.js27
-rw-r--r--spec/frontend/vue_shared/components/smart_virtual_list_spec.js83
-rw-r--r--spec/frontend/vue_shared/directives/autofocusonshow_spec.js46
-rw-r--r--spec/frontend/vue_shared/directives/tooltip_spec.js98
-rw-r--r--spec/frontend/vue_shared/translate_spec.js214
-rw-r--r--spec/frontend/vuex_shared/modules/modal/actions_spec.js31
-rw-r--r--spec/frontend/wikis_spec.js2
-rw-r--r--spec/frontend/zen_mode_spec.js112
-rw-r--r--spec/frontend_integration/ide/__snapshots__/ide_integration_spec.js.snap2
-rw-r--r--spec/graphql/features/authorization_spec.rb2
-rw-r--r--spec/graphql/features/feature_flag_spec.rb2
-rw-r--r--spec/graphql/gitlab_schema_spec.rb8
-rw-r--r--spec/graphql/mutations/alert_management/alerts/set_assignees_spec.rb167
-rw-r--r--spec/graphql/mutations/alert_management/create_alert_issue_spec.rb2
-rw-r--r--spec/graphql/mutations/alert_management/update_alert_status_spec.rb4
-rw-r--r--spec/graphql/mutations/branches/create_spec.rb2
-rw-r--r--spec/graphql/mutations/commits/create_spec.rb180
-rw-r--r--spec/graphql/mutations/concerns/mutations/resolves_group_spec.rb2
-rw-r--r--spec/graphql/mutations/concerns/mutations/resolves_issuable_spec.rb2
-rw-r--r--spec/graphql/mutations/concerns/mutations/resolves_project_spec.rb22
-rw-r--r--spec/graphql/mutations/container_expiration_policies/update_spec.rb96
-rw-r--r--spec/graphql/mutations/design_management/delete_spec.rb2
-rw-r--r--spec/graphql/mutations/design_management/upload_spec.rb2
-rw-r--r--spec/graphql/mutations/discussions/toggle_resolve_spec.rb155
-rw-r--r--spec/graphql/mutations/issues/set_confidential_spec.rb2
-rw-r--r--spec/graphql/mutations/issues/set_due_date_spec.rb2
-rw-r--r--spec/graphql/mutations/merge_requests/create_spec.rb87
-rw-r--r--spec/graphql/resolvers/alert_management/alert_resolver_spec.rb63
-rw-r--r--spec/graphql/resolvers/alert_management_alert_resolver_spec.rb63
-rw-r--r--spec/graphql/resolvers/base_resolver_spec.rb52
-rw-r--r--spec/graphql/resolvers/concerns/looks_ahead_spec.rb177
-rw-r--r--spec/graphql/resolvers/concerns/resolves_project_spec.rb37
-rw-r--r--spec/graphql/resolvers/merge_requests_resolver_spec.rb157
-rw-r--r--spec/graphql/resolvers/project_members_resolver_spec.rb62
-rw-r--r--spec/graphql/resolvers/project_pipeline_resolver_spec.rb36
-rw-r--r--spec/graphql/resolvers/projects/jira_imports_resolver_spec.rb10
-rw-r--r--spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb81
-rw-r--r--spec/graphql/resolvers/user_resolver_spec.rb45
-rw-r--r--spec/graphql/resolvers/users_resolver_spec.rb51
-rw-r--r--spec/graphql/types/access_level_enum_spec.rb11
-rw-r--r--spec/graphql/types/access_level_type_spec.rb13
-rw-r--r--spec/graphql/types/alert_management/alert_type_spec.rb3
-rw-r--r--spec/graphql/types/base_field_spec.rb19
-rw-r--r--spec/graphql/types/commit_action_mode_enum_spec.rb11
-rw-r--r--spec/graphql/types/commit_encoding_enum_spec.rb11
-rw-r--r--spec/graphql/types/container_expiration_policy_cadence_enum_spec.rb9
-rw-r--r--spec/graphql/types/container_expiration_policy_keep_enum_spec.rb9
-rw-r--r--spec/graphql/types/container_expiration_policy_older_than_enum_spec.rb9
-rw-r--r--spec/graphql/types/container_expiration_policy_type_spec.rb27
-rw-r--r--spec/graphql/types/evidence_type_spec.rb15
-rw-r--r--spec/graphql/types/group_member_type_spec.rb19
-rw-r--r--spec/graphql/types/group_type_spec.rb2
-rw-r--r--spec/graphql/types/jira_import_type_spec.rb5
-rw-r--r--spec/graphql/types/merge_request_type_spec.rb5
-rw-r--r--spec/graphql/types/metrics/dashboard_type_spec.rb2
-rw-r--r--spec/graphql/types/notes/diff_position_type_spec.rb17
-rw-r--r--spec/graphql/types/notes/discussion_type_spec.rb16
-rw-r--r--spec/graphql/types/notes/note_type_spec.rb22
-rw-r--r--spec/graphql/types/notes/noteable_type_spec.rb11
-rw-r--r--spec/graphql/types/project_member_type_spec.rb19
-rw-r--r--spec/graphql/types/project_type_spec.rb34
-rw-r--r--spec/graphql/types/projects/jira_project_type_spec.rb11
-rw-r--r--spec/graphql/types/projects/jira_service_type_spec.rb2
-rw-r--r--spec/graphql/types/query_type_spec.rb13
-rw-r--r--spec/graphql/types/release_assets_type_spec.rb27
-rw-r--r--spec/graphql/types/release_links_type_spec.rb15
-rw-r--r--spec/graphql/types/release_source_type_spec.rb15
-rw-r--r--spec/graphql/types/release_type_spec.rb14
-rw-r--r--spec/graphql/types/resolvable_interface_spec.rb16
-rw-r--r--spec/graphql/types/snippet_type_spec.rb114
-rw-r--r--spec/graphql/types/snippets/file_input_action_enum_spec.rb11
-rw-r--r--spec/graphql/types/snippets/file_input_type_spec.rb15
-rw-r--r--spec/graphql/types/user_type_spec.rb14
-rw-r--r--spec/helpers/application_helper_spec.rb25
-rw-r--r--spec/helpers/application_settings_helper_spec.rb23
-rw-r--r--spec/helpers/auto_devops_helper_spec.rb4
-rw-r--r--spec/helpers/clusters_helper_spec.rb16
-rw-r--r--spec/helpers/environments_helper_spec.rb4
-rw-r--r--spec/helpers/events_helper_spec.rb15
-rw-r--r--spec/helpers/gitlab_routing_helper_spec.rb30
-rw-r--r--spec/helpers/issues_helper_spec.rb53
-rw-r--r--spec/helpers/markup_helper_spec.rb4
-rw-r--r--spec/helpers/milestones_helper_spec.rb103
-rw-r--r--spec/helpers/milestones_routing_helper_spec.rb48
-rw-r--r--spec/helpers/namespaces_helper_spec.rb92
-rw-r--r--spec/helpers/notes_helper_spec.rb30
-rw-r--r--spec/helpers/page_layout_helper_spec.rb15
-rw-r--r--spec/helpers/projects/alert_management_helper_spec.rb4
-rw-r--r--spec/helpers/projects_helper_spec.rb34
-rw-r--r--spec/helpers/recaptcha_experiment_helper_spec.rb6
-rw-r--r--spec/helpers/search_helper_spec.rb93
-rw-r--r--spec/helpers/subscribable_banner_helper_spec.rb11
-rw-r--r--spec/helpers/timeboxes_helper_spec.rb114
-rw-r--r--spec/helpers/timeboxes_routing_helper_spec.rb48
-rw-r--r--spec/helpers/todos_helper_spec.rb63
-rw-r--r--spec/helpers/visibility_level_helper_spec.rb78
-rw-r--r--spec/helpers/wiki_helper_spec.rb6
-rw-r--r--spec/initializers/actionpack_generate_old_csrf_token_spec.rb47
-rw-r--r--spec/initializers/database_config_spec.rb15
-rw-r--r--spec/initializers/google_api_client_spec.rb17
-rw-r--r--spec/initializers/lograge_spec.rb2
-rw-r--r--spec/javascripts/awards_handler_spec.js400
-rw-r--r--spec/javascripts/behaviors/copy_as_gfm_spec.js125
-rw-r--r--spec/javascripts/behaviors/gl_emoji/unicode_support_map_spec.js52
-rw-r--r--spec/javascripts/behaviors/shortcuts/shortcuts_issuable_spec.js315
-rw-r--r--spec/javascripts/collapsed_sidebar_todo_spec.js171
-rw-r--r--spec/javascripts/comment_type_toggle_spec.js168
-rw-r--r--spec/javascripts/droplab/drop_down_spec.js650
-rw-r--r--spec/javascripts/droplab/hook_spec.js73
-rw-r--r--spec/javascripts/droplab/plugins/input_setter_spec.js214
-rw-r--r--spec/javascripts/dropzone_input_spec.js109
-rw-r--r--spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js126
-rw-r--r--spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js722
-rw-r--r--spec/javascripts/gl_dropdown_spec.js341
-rw-r--r--spec/javascripts/gl_form_spec.js110
-rw-r--r--spec/javascripts/helpers/scroll_into_view_promise.js28
-rw-r--r--spec/javascripts/helpers/vuex_action_helper_spec.js166
-rw-r--r--spec/javascripts/helpers/wait_for_attribute_change.js16
-rw-r--r--spec/javascripts/ide/components/commit_sidebar/message_field_spec.js170
-rw-r--r--spec/javascripts/ide/components/jobs/detail_spec.js184
-rw-r--r--spec/javascripts/ide/components/repo_editor_spec.js512
-rw-r--r--spec/javascripts/ide/helpers.js1
-rw-r--r--spec/javascripts/ide/mock_data.js1
-rw-r--r--spec/javascripts/ide/stores/actions/merge_request_spec.js510
-rw-r--r--spec/javascripts/ide/stores/actions/project_spec.js404
-rw-r--r--spec/javascripts/ide/stores/actions/tree_spec.js216
-rw-r--r--spec/javascripts/ide/stores/actions_spec.js1116
-rw-r--r--spec/javascripts/ide/stores/modules/commit/actions_spec.js603
-rw-r--r--spec/javascripts/importer_status_spec.js138
-rw-r--r--spec/javascripts/labels_issue_sidebar_spec.js97
-rw-r--r--spec/javascripts/lazy_loader_spec.js244
-rw-r--r--spec/javascripts/line_highlighter_spec.js261
-rw-r--r--spec/javascripts/merge_request_spec.js187
-rw-r--r--spec/javascripts/merge_request_tabs_spec.js283
-rw-r--r--spec/javascripts/mini_pipeline_graph_dropdown_spec.js106
-rw-r--r--spec/javascripts/pager_spec.js162
-rw-r--r--spec/javascripts/pdf/index_spec.js58
-rw-r--r--spec/javascripts/pdf/page_spec.js49
-rw-r--r--spec/javascripts/performance_bar/index_spec.js80
-rw-r--r--spec/javascripts/persistent_user_callout_spec.js175
-rw-r--r--spec/javascripts/releases/components/app_index_spec.js184
-rw-r--r--spec/javascripts/releases/mock_data.js148
-rw-r--r--spec/javascripts/releases/stores/modules/list/actions_spec.js131
-rw-r--r--spec/javascripts/right_sidebar_spec.js87
-rw-r--r--spec/javascripts/search_autocomplete_spec.js215
-rw-r--r--spec/javascripts/shortcuts_spec.js46
-rw-r--r--spec/javascripts/signin_tabs_memoizer_spec.js216
-rw-r--r--spec/javascripts/todos_spec.js108
-rw-r--r--spec/javascripts/toggle_buttons_spec.js127
-rw-r--r--spec/javascripts/user_popovers_spec.js95
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_author_spec.js39
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_author_time_spec.js44
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_header_spec.js313
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js223
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_merge_help_spec.js70
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js326
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_rebase_spec.js141
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_related_links_spec.js85
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_status_icon_spec.js48
-rw-r--r--spec/javascripts/vue_mr_widget/components/review_app_link_spec.js52
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_archived_spec.js31
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_enabled_spec.js230
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js31
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_closed_spec.js69
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js225
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js156
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js219
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_merging_spec.js43
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js40
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_not_allowed_spec.js26
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js26
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js19
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js983
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js25
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_unresolved_discussions_spec.js45
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js99
-rw-r--r--spec/javascripts/vue_mr_widget/mock_data.js2
-rw-r--r--spec/javascripts/vue_shared/components/deprecated_modal_2_spec.js261
-rw-r--r--spec/javascripts/vue_shared/components/deprecated_modal_spec.js71
-rw-r--r--spec/javascripts/vue_shared/components/file_finder/index_spec.js368
-rw-r--r--spec/javascripts/vue_shared/components/icon_spec.js73
-rw-r--r--spec/javascripts/vue_shared/components/issue/related_issuable_mock_data.js1
-rw-r--r--spec/javascripts/vue_shared/components/panel_resizer_spec.js85
-rw-r--r--spec/javascripts/vue_shared/components/smart_virtual_list_spec.js83
-rw-r--r--spec/javascripts/vue_shared/directives/autofocusonshow_spec.js38
-rw-r--r--spec/javascripts/vue_shared/directives/tooltip_spec.js89
-rw-r--r--spec/javascripts/vue_shared/translate_spec.js251
-rw-r--r--spec/javascripts/vuex_shared/modules/modal/actions_spec.js31
-rw-r--r--spec/javascripts/zen_mode_spec.js106
-rw-r--r--spec/lib/api/entities/release_spec.rb6
-rw-r--r--spec/lib/api/validations/validators/untrusted_regexp_spec.rb28
-rw-r--r--spec/lib/banzai/filter/design_reference_filter_spec.rb307
-rw-r--r--spec/lib/banzai/filter/external_issue_reference_filter_spec.rb30
-rw-r--r--spec/lib/banzai/filter/gollum_tags_filter_spec.rb34
-rw-r--r--spec/lib/banzai/filter/issue_reference_filter_spec.rb44
-rw-r--r--spec/lib/banzai/filter/label_reference_filter_spec.rb22
-rw-r--r--spec/lib/banzai/filter/repository_link_filter_spec.rb8
-rw-r--r--spec/lib/banzai/filter/wiki_link_filter_spec.rb16
-rw-r--r--spec/lib/banzai/pipeline/description_pipeline_spec.rb4
-rw-r--r--spec/lib/banzai/pipeline/wiki_pipeline_spec.rb67
-rw-r--r--spec/lib/constraints/feature_constrainer_spec.rb7
-rw-r--r--spec/lib/extracts_path_spec.rb126
-rw-r--r--spec/lib/extracts_ref_spec.rb23
-rw-r--r--spec/lib/feature/gitaly_spec.rb2
-rw-r--r--spec/lib/feature_spec.rb164
-rw-r--r--spec/lib/gitaly/server_spec.rb19
-rw-r--r--spec/lib/gitlab/alert_management/alert_params_spec.rb3
-rw-r--r--spec/lib/gitlab/alert_management/alert_status_counts_spec.rb13
-rw-r--r--spec/lib/gitlab/alert_management/fingerprint_spec.rb48
-rw-r--r--spec/lib/gitlab/alerting/alert_spec.rb4
-rw-r--r--spec/lib/gitlab/alerting/notification_payload_parser_spec.rb35
-rw-r--r--spec/lib/gitlab/analytics/cycle_analytics/base_query_builder_spec.rb4
-rw-r--r--spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb4
-rw-r--r--spec/lib/gitlab/auth/auth_finders_spec.rb24
-rw-r--r--spec/lib/gitlab/auth/ldap/person_spec.rb7
-rw-r--r--spec/lib/gitlab/background_migration/merge_request_assignees_migration_progress_check_spec.rb8
-rw-r--r--spec/lib/gitlab/background_migration/reset_merge_status_spec.rb24
-rw-r--r--spec/lib/gitlab/badge/coverage/report_spec.rb2
-rw-r--r--spec/lib/gitlab/badge/coverage/template_spec.rb46
-rw-r--r--spec/lib/gitlab/badge/pipeline/template_spec.rb50
-rw-r--r--spec/lib/gitlab/bitbucket_import/importer_spec.rb5
-rw-r--r--spec/lib/gitlab/cache/import/caching_spec.rb15
-rw-r--r--spec/lib/gitlab/chat_spec.rb10
-rw-r--r--spec/lib/gitlab/ci/build/credentials/factory_spec.rb10
-rw-r--r--spec/lib/gitlab/ci/build/releaser_spec.rb51
-rw-r--r--spec/lib/gitlab/ci/build/step_spec.rb26
-rw-r--r--spec/lib/gitlab/ci/config/entry/reports_spec.rb1
-rw-r--r--spec/lib/gitlab/ci/config/entry/retry_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/parsers/terraform/tfplan_spec.rb72
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/seed_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb15
-rw-r--r--spec/lib/gitlab/ci/pipeline/seed/build/cache_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/reports/terraform_reports_spec.rb14
-rw-r--r--spec/lib/gitlab/ci/status/bridge/factory_spec.rb3
-rw-r--r--spec/lib/gitlab/ci/status/stage/play_manual_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/yaml_processor_spec.rb2
-rw-r--r--spec/lib/gitlab/cleanup/orphan_lfs_file_references_spec.rb45
-rw-r--r--spec/lib/gitlab/cluster/mixins/puma_cluster_spec.rb4
-rw-r--r--spec/lib/gitlab/cluster/mixins/unicorn_http_server_spec.rb4
-rw-r--r--spec/lib/gitlab/code_navigation_path_spec.rb17
-rw-r--r--spec/lib/gitlab/config/entry/factory_spec.rb11
-rw-r--r--spec/lib/gitlab/config/loader/yaml_spec.rb47
-rw-r--r--spec/lib/gitlab/contributions_calendar_spec.rb8
-rw-r--r--spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb80
-rw-r--r--spec/lib/gitlab/danger/changelog_spec.rb4
-rw-r--r--spec/lib/gitlab/danger/helper_spec.rb2
-rw-r--r--spec/lib/gitlab/danger/roulette_spec.rb183
-rw-r--r--spec/lib/gitlab/data_builder/alert_spec.rb26
-rw-r--r--spec/lib/gitlab/database/custom_structure_spec.rb65
-rw-r--r--spec/lib/gitlab/database/migration_helpers_spec.rb151
-rw-r--r--spec/lib/gitlab/database/obsolete_ignored_columns_spec.rb55
-rw-r--r--spec/lib/gitlab/database/partitioning_migration_helpers/foreign_key_helpers_spec.rb193
-rw-r--r--spec/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers_spec.rb289
-rw-r--r--spec/lib/gitlab/database/partitioning_migration_helpers_spec.rb230
-rw-r--r--spec/lib/gitlab/database/schema_cleaner_spec.rb4
-rw-r--r--spec/lib/gitlab/database/with_lock_retries_spec.rb5
-rw-r--r--spec/lib/gitlab/dependency_linker/go_mod_linker_spec.rb94
-rw-r--r--spec/lib/gitlab/dependency_linker/go_sum_linker_spec.rb65
-rw-r--r--spec/lib/gitlab/dependency_linker_spec.rb16
-rw-r--r--spec/lib/gitlab/diff/file_spec.rb12
-rw-r--r--spec/lib/gitlab/diff/formatters/image_formatter_spec.rb1
-rw-r--r--spec/lib/gitlab/diff/formatters/text_formatter_spec.rb1
-rw-r--r--spec/lib/gitlab/diff/position_spec.rb80
-rw-r--r--spec/lib/gitlab/doctor/secrets_spec.rb42
-rw-r--r--spec/lib/gitlab/email/handler/create_note_handler_spec.rb28
-rw-r--r--spec/lib/gitlab/error_tracking/processor/sidekiq_processor_spec.rb165
-rw-r--r--spec/lib/gitlab/error_tracking_spec.rb30
-rw-r--r--spec/lib/gitlab/etag_caching/router_spec.rb12
-rw-r--r--spec/lib/gitlab/experimentation_spec.rb2
-rw-r--r--spec/lib/gitlab/gfm/uploads_rewriter_spec.rb18
-rw-r--r--spec/lib/gitlab/git/diff_collection_spec.rb46
-rw-r--r--spec/lib/gitlab/git/diff_spec.rb30
-rw-r--r--spec/lib/gitlab/git/rugged_impl/use_rugged_spec.rb14
-rw-r--r--spec/lib/gitlab/git_access_project_spec.rb166
-rw-r--r--spec/lib/gitlab/git_access_spec.rb150
-rw-r--r--spec/lib/gitlab/gitaly_client/commit_service_spec.rb66
-rw-r--r--spec/lib/gitlab/gitaly_client_spec.rb6
-rw-r--r--spec/lib/gitlab/github_import/importer/pull_requests_importer_spec.rb8
-rw-r--r--spec/lib/gitlab/gl_repository/identifier_spec.rb82
-rw-r--r--spec/lib/gitlab/gl_repository/repo_type_spec.rb10
-rw-r--r--spec/lib/gitlab/gl_repository_spec.rb2
-rw-r--r--spec/lib/gitlab/gon_helper_spec.rb10
-rw-r--r--spec/lib/gitlab/graphql/pagination/filterable_array_connection_spec.rb29
-rw-r--r--spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb114
-rw-r--r--spec/lib/gitlab/import/merge_request_creator_spec.rb2
-rw-r--r--spec/lib/gitlab/import/set_async_jid_spec.rb2
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml15
-rw-r--r--spec/lib/gitlab/import_export/attributes_permitter_spec.rb77
-rw-r--r--spec/lib/gitlab/import_export/import_test_coverage_spec.rb101
-rw-r--r--spec/lib/gitlab/import_export/importer_spec.rb51
-rw-r--r--spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb22
-rw-r--r--spec/lib/gitlab/import_export/legacy_relation_tree_saver_spec.rb34
-rw-r--r--spec/lib/gitlab/import_export/project/relation_factory_spec.rb47
-rw-r--r--spec/lib/gitlab/import_export/project/tree_restorer_spec.rb2
-rw-r--r--spec/lib/gitlab/import_export/project/tree_saver_spec.rb2
-rw-r--r--spec/lib/gitlab/import_export/repo_restorer_spec.rb27
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml13
-rw-r--r--spec/lib/gitlab/import_export/saver_spec.rb12
-rw-r--r--spec/lib/gitlab/import_export/snippet_repo_restorer_spec.rb16
-rw-r--r--spec/lib/gitlab/import_export/snippets_repo_restorer_spec.rb83
-rw-r--r--spec/lib/gitlab/instrumentation/redis_base_spec.rb144
-rw-r--r--spec/lib/gitlab/instrumentation/redis_interceptor_spec.rb45
-rw-r--r--spec/lib/gitlab/instrumentation/redis_spec.rb114
-rw-r--r--spec/lib/gitlab/instrumentation_helper_spec.rb57
-rw-r--r--spec/lib/gitlab/issuable_metadata_spec.rb10
-rw-r--r--spec/lib/gitlab/jira_import/base_importer_spec.rb16
-rw-r--r--spec/lib/gitlab/jira_import/issues_importer_spec.rb35
-rw-r--r--spec/lib/gitlab/jira_import/labels_importer_spec.rb1
-rw-r--r--spec/lib/gitlab/jira_import_spec.rb125
-rw-r--r--spec/lib/gitlab/kubernetes/helm/api_spec.rb5
-rw-r--r--spec/lib/gitlab/kubernetes/helm/base_command_spec.rb25
-rw-r--r--spec/lib/gitlab/kubernetes/helm/delete_command_spec.rb7
-rw-r--r--spec/lib/gitlab/kubernetes/helm/init_command_spec.rb2
-rw-r--r--spec/lib/gitlab/kubernetes/helm/install_command_spec.rb8
-rw-r--r--spec/lib/gitlab/kubernetes/helm/patch_command_spec.rb8
-rw-r--r--spec/lib/gitlab/kubernetes/helm/reset_command_spec.rb2
-rw-r--r--spec/lib/gitlab/kubernetes/network_policy_spec.rb288
-rw-r--r--spec/lib/gitlab/lfs_token_spec.rb78
-rw-r--r--spec/lib/gitlab/lograge/custom_options_spec.rb57
-rw-r--r--spec/lib/gitlab/looping_batcher_spec.rb71
-rw-r--r--spec/lib/gitlab/metrics/dashboard/finder_spec.rb4
-rw-r--r--spec/lib/gitlab/metrics/dashboard/processor_spec.rb24
-rw-r--r--spec/lib/gitlab/metrics/elasticsearch_rack_middleware_spec.rb57
-rw-r--r--spec/lib/gitlab/metrics/method_call_spec.rb4
-rw-r--r--spec/lib/gitlab/metrics/methods_spec.rb4
-rw-r--r--spec/lib/gitlab/metrics/redis_rack_middleware_spec.rb61
-rw-r--r--spec/lib/gitlab/metrics/samplers/database_sampler_spec.rb12
-rw-r--r--spec/lib/gitlab/metrics/samplers/puma_sampler_spec.rb12
-rw-r--r--spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb12
-rw-r--r--spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb20
-rw-r--r--spec/lib/gitlab/metrics/subscribers/active_record_spec.rb132
-rw-r--r--spec/lib/gitlab/metrics/transaction_spec.rb40
-rw-r--r--spec/lib/gitlab/middleware/handle_ip_spoof_attack_error_spec.rb24
-rw-r--r--spec/lib/gitlab/monitor/demo_projects_spec.rb37
-rw-r--r--spec/lib/gitlab/no_cache_headers_spec.rb7
-rw-r--r--spec/lib/gitlab/pagination/keyset/request_context_spec.rb12
-rw-r--r--spec/lib/gitlab/patch/action_dispatch_journey_formatter_spec.rb2
-rw-r--r--spec/lib/gitlab/path_regex_spec.rb21
-rw-r--r--spec/lib/gitlab/phabricator_import/cache/map_spec.rb2
-rw-r--r--spec/lib/gitlab/process_memory_cache/helper_spec.rb52
-rw-r--r--spec/lib/gitlab/project_search_results_spec.rb75
-rw-r--r--spec/lib/gitlab/project_template_spec.rb33
-rw-r--r--spec/lib/gitlab/prometheus/query_variables_spec.rb40
-rw-r--r--spec/lib/gitlab/prometheus_client_spec.rb52
-rw-r--r--spec/lib/gitlab/redis/wrapper_spec.rb16
-rw-r--r--spec/lib/gitlab/reference_extractor_spec.rb6
-rw-r--r--spec/lib/gitlab/regex_spec.rb134
-rw-r--r--spec/lib/gitlab/routing_spec.rb21
-rw-r--r--spec/lib/gitlab/rugged_instrumentation_spec.rb6
-rw-r--r--spec/lib/gitlab/search_context/builder_spec.rb152
-rw-r--r--spec/lib/gitlab/search_context/controller_concern_spec.rb82
-rw-r--r--spec/lib/gitlab/sidekiq_config/cli_methods_spec.rb45
-rw-r--r--spec/lib/gitlab/sidekiq_config/worker_spec.rb9
-rw-r--r--spec/lib/gitlab/sidekiq_config_spec.rb3
-rw-r--r--spec/lib/gitlab/sidekiq_logging/json_formatter_spec.rb47
-rw-r--r--spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb10
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/client_metrics_spec.rb7
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/client_spec.rb49
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job_spec.rb65
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executing_spec.rb85
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb60
-rw-r--r--spec/lib/gitlab/sidekiq_middleware_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_versioning/manager_spec.rb3
-rw-r--r--spec/lib/gitlab/sourcegraph_spec.rb2
-rw-r--r--spec/lib/gitlab/suggestions/commit_message_spec.rb87
-rw-r--r--spec/lib/gitlab/suggestions/file_suggestion_spec.rb241
-rw-r--r--spec/lib/gitlab/suggestions/suggestion_set_spec.rb110
-rw-r--r--spec/lib/gitlab/tracking_spec.rb11
-rw-r--r--spec/lib/gitlab/url_builder_spec.rb32
-rw-r--r--spec/lib/gitlab/usage_data_concerns/topology_spec.rb220
-rw-r--r--spec/lib/gitlab/usage_data_counters/search_counter_spec.rb18
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb937
-rw-r--r--spec/lib/gitlab/utils/usage_data_spec.rb111
-rw-r--r--spec/lib/gitlab/utils_spec.rb13
-rw-r--r--spec/lib/gitlab/web_ide/config/entry/global_spec.rb164
-rw-r--r--spec/lib/gitlab/web_ide/config/entry/terminal_spec.rb156
-rw-r--r--spec/lib/gitlab/web_ide/config_spec.rb78
-rw-r--r--spec/lib/gitlab/wiki_pages/front_matter_parser_spec.rb2
-rw-r--r--spec/lib/gitlab_spec.rb42
-rw-r--r--spec/lib/milestone_array_spec.rb36
-rw-r--r--spec/lib/object_storage/direct_upload_spec.rb117
-rw-r--r--spec/lib/peek/views/bullet_detailed_spec.rb54
-rw-r--r--spec/lib/peek/views/redis_detailed_spec.rb13
-rw-r--r--spec/lib/peek/views/rugged_spec.rb2
-rw-r--r--spec/lib/quality/test_level_spec.rb8
-rw-r--r--spec/mailers/emails/profile_spec.rb32
-rw-r--r--spec/mailers/notify_spec.rb61
-rw-r--r--spec/migrations/20191125114345_add_admin_mode_protected_path_spec.rb9
-rw-r--r--spec/migrations/active_record/schedule_set_confidential_note_events_on_services_spec.rb46
-rw-r--r--spec/migrations/add_foreign_key_from_notification_settings_to_users_spec.rb36
-rw-r--r--spec/migrations/add_foreign_keys_to_todos_spec.rb69
-rw-r--r--spec/migrations/add_incident_settings_to_all_existing_projects_spec.rb93
-rw-r--r--spec/migrations/add_not_null_constraint_to_project_mirror_data_foreign_key_spec.rb20
-rw-r--r--spec/migrations/add_pages_access_level_to_project_feature_spec.rb32
-rw-r--r--spec/migrations/add_pipeline_build_foreign_key_spec.rb34
-rw-r--r--spec/migrations/add_unique_constraint_to_project_features_project_id_spec.rb61
-rw-r--r--spec/migrations/assure_commits_count_for_merge_request_diff_spec.rb34
-rw-r--r--spec/migrations/backfill_imported_snippet_repositories_spec.rb52
-rw-r--r--spec/migrations/backfill_releases_name_with_tag_name_spec.rb23
-rw-r--r--spec/migrations/backfill_status_page_published_incidents_spec.rb54
-rw-r--r--spec/migrations/backfill_store_project_full_path_in_repo_spec.rb98
-rw-r--r--spec/migrations/cap_designs_filename_length_to_new_limit_spec.rb60
-rw-r--r--spec/migrations/change_default_value_for_dsa_key_restriction_spec.rb35
-rw-r--r--spec/migrations/cleanup_build_stage_migration_spec.rb55
-rw-r--r--spec/migrations/cleanup_environments_external_url_spec.rb30
-rw-r--r--spec/migrations/cleanup_projects_with_missing_namespace_spec.rb32
-rw-r--r--spec/migrations/cleanup_stages_position_migration_spec.rb69
-rw-r--r--spec/migrations/create_missing_namespace_for_internal_users_spec.rb39
-rw-r--r--spec/migrations/drop_duplicate_protected_tags_spec.rb42
-rw-r--r--spec/migrations/encrypt_deploy_tokens_tokens_spec.rb47
-rw-r--r--spec/migrations/enqueue_verify_pages_domain_workers_spec.rb29
-rw-r--r--spec/migrations/fill_empty_finished_at_in_deployments_spec.rb72
-rw-r--r--spec/migrations/fill_file_store_spec.rb45
-rw-r--r--spec/migrations/generate_missing_routes_spec.rb86
-rw-r--r--spec/migrations/import_common_metrics_spec.rb16
-rw-r--r--spec/migrations/migrate_cluster_configure_worker_sidekiq_queue_spec.rb64
-rw-r--r--spec/migrations/migrate_create_trace_artifact_sidekiq_queue_spec.rb62
-rw-r--r--spec/migrations/migrate_forbidden_redirect_uris_spec.rb48
-rw-r--r--spec/migrations/migrate_legacy_artifacts_to_job_artifacts_spec.rb75
-rw-r--r--spec/migrations/migrate_null_wiki_access_levels_spec.rb29
-rw-r--r--spec/migrations/migrate_object_storage_upload_sidekiq_queue_spec.rb29
-rw-r--r--spec/migrations/migrate_update_head_pipeline_for_merge_request_sidekiq_queue_spec.rb60
-rw-r--r--spec/migrations/remove_empty_extern_uid_auth0_identities_spec.rb24
-rw-r--r--spec/migrations/remove_redundant_pipeline_stages_spec.rb61
-rw-r--r--spec/migrations/reschedule_builds_stages_migration_spec.rb39
-rw-r--r--spec/migrations/reschedule_commits_count_for_merge_request_diff_spec.rb39
-rw-r--r--spec/migrations/schedule_digest_personal_access_tokens_spec.rb48
-rw-r--r--spec/migrations/schedule_runners_token_encryption_spec.rb40
-rw-r--r--spec/migrations/schedule_set_confidential_note_events_on_webhooks_spec.rb46
-rw-r--r--spec/migrations/schedule_stages_index_migration_spec.rb37
-rw-r--r--spec/migrations/schedule_to_archive_legacy_traces_spec.rb47
-rw-r--r--spec/migrations/seed_repository_storages_weighted_spec.rb31
-rw-r--r--spec/migrations/steal_fill_store_upload_spec.rb40
-rw-r--r--spec/migrations/update_project_import_visibility_level_spec.rb86
-rw-r--r--spec/migrations/update_routes_for_lost_and_found_group_and_orphaned_projects_spec.rb182
-rw-r--r--spec/models/active_session_spec.rb2
-rw-r--r--spec/models/alert_management/alert_assignee_spec.rb21
-rw-r--r--spec/models/alert_management/alert_spec.rb20
-rw-r--r--spec/models/alert_management/alert_user_mention_spec.rb12
-rw-r--r--spec/models/application_setting_spec.rb53
-rw-r--r--spec/models/blob_viewer/go_mod_spec.rb63
-rw-r--r--spec/models/blob_viewer/metrics_dashboard_yml_spec.rb127
-rw-r--r--spec/models/broadcast_message_spec.rb6
-rw-r--r--spec/models/ci/bridge_spec.rb5
-rw-r--r--spec/models/ci/build_report_result_spec.rb74
-rw-r--r--spec/models/ci/build_runner_session_spec.rb60
-rw-r--r--spec/models/ci/build_spec.rb99
-rw-r--r--spec/models/ci/build_trace_chunk_spec.rb2
-rw-r--r--spec/models/ci/daily_build_group_report_result_spec.rb24
-rw-r--r--spec/models/ci/instance_variable_spec.rb33
-rw-r--r--spec/models/ci/job_artifact_spec.rb79
-rw-r--r--spec/models/ci/pipeline_schedule_spec.rb2
-rw-r--r--spec/models/ci/pipeline_spec.rb184
-rw-r--r--spec/models/ci/ref_spec.rb153
-rw-r--r--spec/models/ci/runner_spec.rb10
-rw-r--r--spec/models/clusters/applications/elastic_stack_spec.rb10
-rw-r--r--spec/models/clusters/applications/prometheus_spec.rb8
-rw-r--r--spec/models/clusters/cluster_spec.rb159
-rw-r--r--spec/models/commit_status_spec.rb19
-rw-r--r--spec/models/concerns/bulk_insert_safe_spec.rb4
-rw-r--r--spec/models/concerns/cacheable_attributes_spec.rb4
-rw-r--r--spec/models/concerns/each_batch_spec.rb2
-rw-r--r--spec/models/concerns/featurable_spec.rb184
-rw-r--r--spec/models/concerns/issuable_spec.rb22
-rw-r--r--spec/models/concerns/limitable_spec.rb55
-rw-r--r--spec/models/concerns/milestoneish_spec.rb4
-rw-r--r--spec/models/concerns/resolvable_discussion_spec.rb22
-rw-r--r--spec/models/concerns/sortable_spec.rb2
-rw-r--r--spec/models/container_expiration_policy_spec.rb41
-rw-r--r--spec/models/container_repository_spec.rb6
-rw-r--r--spec/models/deployment_spec.rb8
-rw-r--r--spec/models/design_management/design_spec.rb89
-rw-r--r--spec/models/diff_note_spec.rb30
-rw-r--r--spec/models/draft_note_spec.rb42
-rw-r--r--spec/models/environment_spec.rb2
-rw-r--r--spec/models/event_spec.rb170
-rw-r--r--spec/models/fork_network_member_spec.rb2
-rw-r--r--spec/models/global_milestone_spec.rb208
-rw-r--r--spec/models/group_deploy_key_spec.rb11
-rw-r--r--spec/models/group_group_link_spec.rb26
-rw-r--r--spec/models/group_import_state_spec.rb72
-rw-r--r--spec/models/group_milestone_spec.rb57
-rw-r--r--spec/models/group_spec.rb29
-rw-r--r--spec/models/hooks/system_hook_spec.rb4
-rw-r--r--spec/models/instance_configuration_spec.rb2
-rw-r--r--spec/models/integration_spec.rb21
-rw-r--r--spec/models/internal_id_spec.rb41
-rw-r--r--spec/models/issue/metrics_spec.rb10
-rw-r--r--spec/models/issue_spec.rb55
-rw-r--r--spec/models/iteration_spec.rb16
-rw-r--r--spec/models/jira_import_state_spec.rb37
-rw-r--r--spec/models/member_spec.rb6
-rw-r--r--spec/models/members/group_member_spec.rb32
-rw-r--r--spec/models/members/project_member_spec.rb6
-rw-r--r--spec/models/merge_request_diff_commit_spec.rb2
-rw-r--r--spec/models/merge_request_spec.rb178
-rw-r--r--spec/models/metrics/dashboard/annotation_spec.rb33
-rw-r--r--spec/models/milestone_spec.rb155
-rw-r--r--spec/models/note_spec.rb52
-rw-r--r--spec/models/pages_domain_spec.rb8
-rw-r--r--spec/models/performance_monitoring/prometheus_dashboard_spec.rb174
-rw-r--r--spec/models/performance_monitoring/prometheus_metric_spec.rb8
-rw-r--r--spec/models/performance_monitoring/prometheus_panel_group_spec.rb10
-rw-r--r--spec/models/performance_monitoring/prometheus_panel_spec.rb10
-rw-r--r--spec/models/personal_access_token_spec.rb9
-rw-r--r--spec/models/project_ci_cd_setting_spec.rb19
-rw-r--r--spec/models/project_feature_spec.rb131
-rw-r--r--spec/models/project_group_link_spec.rb16
-rw-r--r--spec/models/project_import_state_spec.rb24
-rw-r--r--spec/models/project_metrics_setting_spec.rb16
-rw-r--r--spec/models/project_repository_storage_move_spec.rb46
-rw-r--r--spec/models/project_services/chat_message/alert_message_spec.rb57
-rw-r--r--spec/models/project_services/chat_message/merge_message_spec.rb8
-rw-r--r--spec/models/project_services/chat_message/pipeline_message_spec.rb34
-rw-r--r--spec/models/project_services/emails_on_push_service_spec.rb22
-rw-r--r--spec/models/project_services/hipchat_service_spec.rb4
-rw-r--r--spec/models/project_services/jira_service_spec.rb16
-rw-r--r--spec/models/project_services/pipelines_email_service_spec.rb16
-rw-r--r--spec/models/project_services/prometheus_service_spec.rb45
-rw-r--r--spec/models/project_spec.rb271
-rw-r--r--spec/models/project_team_spec.rb16
-rw-r--r--spec/models/project_wiki_spec.rb4
-rw-r--r--spec/models/prometheus_alert_event_spec.rb4
-rw-r--r--spec/models/push_event_spec.rb6
-rw-r--r--spec/models/release_spec.rb8
-rw-r--r--spec/models/releases/evidence_spec.rb80
-rw-r--r--spec/models/remote_mirror_spec.rb24
-rw-r--r--spec/models/repository_spec.rb24
-rw-r--r--spec/models/resource_label_event_spec.rb44
-rw-r--r--spec/models/resource_milestone_event_spec.rb30
-rw-r--r--spec/models/review_spec.rb44
-rw-r--r--spec/models/service_spec.rb58
-rw-r--r--spec/models/snippet_input_action_collection_spec.rb47
-rw-r--r--spec/models/snippet_input_action_spec.rb89
-rw-r--r--spec/models/todo_spec.rb24
-rw-r--r--spec/models/user_interacted_project_spec.rb17
-rw-r--r--spec/models/user_spec.rb87
-rw-r--r--spec/models/web_ide_terminal_spec.rb82
-rw-r--r--spec/models/wiki_directory_spec.rb2
-rw-r--r--spec/models/wiki_page_spec.rb11
-rw-r--r--spec/policies/ci/build_policy_spec.rb125
-rw-r--r--spec/policies/group_policy_spec.rb2
-rw-r--r--spec/policies/project_policy_spec.rb181
-rw-r--r--spec/policies/releases/source_policy_spec.rb88
-rw-r--r--spec/presenters/gitlab/blame_presenter_spec.rb45
-rw-r--r--spec/presenters/projects/prometheus/alert_presenter_spec.rb35
-rw-r--r--spec/presenters/snippet_presenter_spec.rb21
-rw-r--r--spec/requests/api/admin/ci/variables_spec.rb16
-rw-r--r--spec/requests/api/commits_spec.rb31
-rw-r--r--spec/requests/api/deploy_keys_spec.rb54
-rw-r--r--spec/requests/api/events_spec.rb6
-rw-r--r--spec/requests/api/features_spec.rb38
-rw-r--r--spec/requests/api/files_spec.rb26
-rw-r--r--spec/requests/api/graphql/boards/board_lists_query_spec.rb64
-rw-r--r--spec/requests/api/graphql/group/labels_query_spec.rb19
-rw-r--r--spec/requests/api/graphql/metrics/dashboard_query_spec.rb56
-rw-r--r--spec/requests/api/graphql/mutations/alert_management/alerts/create_alert_issue_spec.rb74
-rw-r--r--spec/requests/api/graphql/mutations/alert_management/alerts/set_assignees_spec.rb65
-rw-r--r--spec/requests/api/graphql/mutations/alert_management/alerts/update_alert_status_spec.rb20
-rw-r--r--spec/requests/api/graphql/mutations/commits/create_spec.rb52
-rw-r--r--spec/requests/api/graphql/mutations/container_expiration_policy/update_spec.rb110
-rw-r--r--spec/requests/api/graphql/mutations/discussions/toggle_resolve_spec.rb49
-rw-r--r--spec/requests/api/graphql/mutations/jira_import/import_users_spec.rb104
-rw-r--r--spec/requests/api/graphql/mutations/jira_import/start_spec.rb62
-rw-r--r--spec/requests/api/graphql/mutations/merge_requests/create_spec.rb51
-rw-r--r--spec/requests/api/graphql/mutations/metrics/dashboard/annotations/delete_spec.rb80
-rw-r--r--spec/requests/api/graphql/mutations/snippets/create_spec.rb40
-rw-r--r--spec/requests/api/graphql/project/alert_management/alert/assignees_spec.rb78
-rw-r--r--spec/requests/api/graphql/project/alert_management/alert/notes_spec.rb67
-rw-r--r--spec/requests/api/graphql/project/alert_management/alert_status_counts_spec.rb16
-rw-r--r--spec/requests/api/graphql/project/alert_management/alerts_spec.rb3
-rw-r--r--spec/requests/api/graphql/project/container_expiration_policy_spec.rb30
-rw-r--r--spec/requests/api/graphql/project/issues_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/jira_import_spec.rb36
-rw-r--r--spec/requests/api/graphql/project/jira_projects_spec.rb114
-rw-r--r--spec/requests/api/graphql/project/labels_query_spec.rb19
-rw-r--r--spec/requests/api/graphql/project/merge_request_spec.rb24
-rw-r--r--spec/requests/api/graphql/project/merge_requests_spec.rb174
-rw-r--r--spec/requests/api/graphql/project/pipeline_spec.rb32
-rw-r--r--spec/requests/api/graphql/project/release_spec.rb206
-rw-r--r--spec/requests/api/graphql/project_query_spec.rb48
-rw-r--r--spec/requests/api/graphql/tasks/task_completion_status_spec.rb8
-rw-r--r--spec/requests/api/graphql/user/group_member_query_spec.rb32
-rw-r--r--spec/requests/api/graphql/user/project_member_query_spec.rb32
-rw-r--r--spec/requests/api/graphql/user_query_spec.rb260
-rw-r--r--spec/requests/api/graphql/user_spec.rb55
-rw-r--r--spec/requests/api/graphql/users_spec.rb90
-rw-r--r--spec/requests/api/graphql_spec.rb58
-rw-r--r--spec/requests/api/group_export_spec.rb34
-rw-r--r--spec/requests/api/groups_spec.rb219
-rw-r--r--spec/requests/api/internal/base_spec.rb30
-rw-r--r--spec/requests/api/issues/issues_spec.rb6
-rw-r--r--spec/requests/api/issues/put_projects_issues_spec.rb223
-rw-r--r--spec/requests/api/jobs_spec.rb172
-rw-r--r--spec/requests/api/labels_spec.rb4
-rw-r--r--spec/requests/api/lsif_data_spec.rb95
-rw-r--r--spec/requests/api/markdown_spec.rb15
-rw-r--r--spec/requests/api/merge_requests_spec.rb34
-rw-r--r--spec/requests/api/oauth_tokens_spec.rb61
-rw-r--r--spec/requests/api/project_container_repositories_spec.rb34
-rw-r--r--spec/requests/api/project_events_spec.rb12
-rw-r--r--spec/requests/api/project_export_spec.rb41
-rw-r--r--spec/requests/api/project_repository_storage_moves_spec.rb118
-rw-r--r--spec/requests/api/projects_spec.rb105
-rw-r--r--spec/requests/api/releases_spec.rb104
-rw-r--r--spec/requests/api/repositories_spec.rb8
-rw-r--r--spec/requests/api/resource_milestone_events_spec.rb27
-rw-r--r--spec/requests/api/runner_spec.rb150
-rw-r--r--spec/requests/api/runners_spec.rb26
-rw-r--r--spec/requests/api/search_spec.rb48
-rw-r--r--spec/requests/api/settings_spec.rb19
-rw-r--r--spec/requests/api/suggestions_spec.rb140
-rw-r--r--spec/requests/api/terraform/state_spec.rb73
-rw-r--r--spec/requests/api/users_spec.rb481
-rw-r--r--spec/requests/groups/registry/repositories_controller_spec.rb2
-rw-r--r--spec/requests/import/gitlab_groups_controller_spec.rb258
-rw-r--r--spec/requests/user_spoofs_ip_spec.rb12
-rw-r--r--spec/routing/project_routing_spec.rb2
-rw-r--r--spec/rubocop/cop/active_record_association_reload_spec.rb12
-rw-r--r--spec/rubocop/cop/avoid_route_redirect_leading_slash_spec.rb4
-rw-r--r--spec/rubocop/cop/default_scope_spec.rb48
-rw-r--r--spec/rubocop/cop/destroy_all_spec.rb6
-rw-r--r--spec/rubocop/cop/filename_length_spec.rb5
-rw-r--r--spec/rubocop/cop/gitlab/bulk_insert_spec.rb19
-rw-r--r--spec/rubocop/cop/gitlab/change_timezone_spec.rb2
-rw-r--r--spec/rubocop/cop/gitlab/const_get_inherit_false_spec.rb12
-rw-r--r--spec/rubocop/cop/gitlab/duplicate_spec_location_spec.rb14
-rw-r--r--spec/rubocop/cop/inject_enterprise_edition_module_spec.rb14
-rw-r--r--spec/rubocop/cop/migration/add_index_spec.rb4
-rw-r--r--spec/rubocop/cop/migration/add_limit_to_text_columns_spec.rb21
-rw-r--r--spec/rubocop/cop/migration/drop_table_spec.rb62
-rw-r--r--spec/rubocop/cop/migration/prevent_strings_spec.rb21
-rw-r--r--spec/rubocop/cop/migration/update_large_table_spec.rb91
-rw-r--r--spec/rubocop/cop/performance/ar_count_each_spec.rb3
-rw-r--r--spec/rubocop/cop/performance/ar_exists_and_present_blank_spec.rb3
-rw-r--r--spec/rubocop/cop/performance/readlines_each_spec.rb3
-rw-r--r--spec/rubocop/cop/put_group_routes_under_scope_spec.rb6
-rw-r--r--spec/rubocop/cop/put_project_routes_under_scope_spec.rb6
-rw-r--r--spec/rubocop/cop/rspec/empty_line_after_shared_example_spec.rb86
-rw-r--r--spec/rubocop/cop/rspec/modify_sidekiq_middleware_spec.rb3
-rw-r--r--spec/rubocop/cop/rspec/top_level_describe_path_spec.rb10
-rw-r--r--spec/rubocop/cop/scalability/bulk_perform_with_context_spec.rb13
-rw-r--r--spec/rubocop/cop/scalability/cron_worker_context_spec.rb15
-rw-r--r--spec/rubocop/cop/scalability/file_uploads_spec.rb11
-rw-r--r--spec/rubocop/cop/scalability/idempotent_worker_spec.rb7
-rw-r--r--spec/serializers/build_artifact_entity_spec.rb9
-rw-r--r--spec/serializers/ci/dag_job_entity_spec.rb13
-rw-r--r--spec/serializers/ci/dag_pipeline_entity_spec.rb49
-rw-r--r--spec/serializers/ci/daily_build_group_report_result_entity_spec.rb26
-rw-r--r--spec/serializers/ci/daily_build_group_report_result_serializer_spec.rb38
-rw-r--r--spec/serializers/cluster_serializer_spec.rb1
-rw-r--r--spec/serializers/commit_entity_spec.rb6
-rw-r--r--spec/serializers/container_repository_entity_spec.rb4
-rw-r--r--spec/serializers/diffs_entity_spec.rb10
-rw-r--r--spec/serializers/evidences/evidence_entity_spec.rb60
-rw-r--r--spec/serializers/import/bitbucket_provider_repo_entity_spec.rb34
-rw-r--r--spec/serializers/import/bitbucket_server_provider_repo_entity_spec.rb36
-rw-r--r--spec/serializers/import/fogbugz_provider_repo_entity_spec.rb27
-rw-r--r--spec/serializers/import/githubish_provider_repo_entity_spec.rb27
-rw-r--r--spec/serializers/import/gitlab_provider_repo_entity_spec.rb27
-rw-r--r--spec/serializers/import/provider_repo_serializer_spec.rb29
-rw-r--r--spec/serializers/merge_request_widget_entity_spec.rb2
-rw-r--r--spec/serializers/paginated_diff_entity_spec.rb10
-rw-r--r--spec/serializers/pipeline_details_entity_spec.rb39
-rw-r--r--spec/serializers/pipeline_serializer_spec.rb4
-rw-r--r--spec/serializers/provider_repo_entity_spec.rb24
-rw-r--r--spec/serializers/provider_repo_serializer_spec.rb9
-rw-r--r--spec/serializers/service_field_entity_spec.rb99
-rw-r--r--spec/serializers/web_ide_terminal_entity_spec.rb27
-rw-r--r--spec/serializers/web_ide_terminal_serializer_spec.rb27
-rw-r--r--spec/services/admin/propagate_integration_service_spec.rb149
-rw-r--r--spec/services/alert_management/alerts/update_service_spec.rb134
-rw-r--r--spec/services/alert_management/create_alert_issue_service_spec.rb17
-rw-r--r--spec/services/alert_management/process_prometheus_alert_service_spec.rb40
-rw-r--r--spec/services/audit_event_service_spec.rb6
-rw-r--r--spec/services/authorized_project_update/project_create_service_spec.rb50
-rw-r--r--spec/services/auto_merge/base_service_spec.rb99
-rw-r--r--spec/services/ci/build_report_result_service_spec.rb51
-rw-r--r--spec/services/ci/create_cross_project_pipeline_service_spec.rb30
-rw-r--r--spec/services/ci/create_pipeline_service_spec.rb12
-rw-r--r--spec/services/ci/create_web_ide_terminal_service_spec.rb143
-rw-r--r--spec/services/ci/expire_pipeline_cache_service_spec.rb4
-rw-r--r--spec/services/ci/generate_terraform_reports_service_spec.rb26
-rw-r--r--spec/services/ci/pipeline_bridge_status_service_spec.rb2
-rw-r--r--spec/services/ci/retry_build_service_spec.rb7
-rw-r--r--spec/services/ci/update_ci_ref_status_service_spec.rb169
-rw-r--r--spec/services/ci/web_ide_config_service_spec.rb91
-rw-r--r--spec/services/clusters/applications/check_uninstall_progress_service_spec.rb4
-rw-r--r--spec/services/clusters/applications/prometheus_config_service_spec.rb16
-rw-r--r--spec/services/clusters/parse_cluster_applications_artifact_service_spec.rb14
-rw-r--r--spec/services/concerns/exclusive_lease_guard_spec.rb121
-rw-r--r--spec/services/container_expiration_policies/update_service_spec.rb101
-rw-r--r--spec/services/container_expiration_policy_service_spec.rb15
-rw-r--r--spec/services/design_management/delete_designs_service_spec.rb26
-rw-r--r--spec/services/design_management/save_designs_service_spec.rb25
-rw-r--r--spec/services/discussions/resolve_service_spec.rb95
-rw-r--r--spec/services/draft_notes/create_service_spec.rb94
-rw-r--r--spec/services/draft_notes/destroy_service_spec.rb52
-rw-r--r--spec/services/draft_notes/publish_service_spec.rb261
-rw-r--r--spec/services/event_create_service_spec.rb102
-rw-r--r--spec/services/git/branch_hooks_service_spec.rb8
-rw-r--r--spec/services/git/wiki_push_service/change_spec.rb6
-rw-r--r--spec/services/git/wiki_push_service_spec.rb16
-rw-r--r--spec/services/groups/group_links/destroy_service_spec.rb10
-rw-r--r--spec/services/groups/import_export/export_service_spec.rb21
-rw-r--r--spec/services/groups/import_export/import_service_spec.rb63
-rw-r--r--spec/services/groups/transfer_service_spec.rb9
-rw-r--r--spec/services/import/github_service_spec.rb55
-rw-r--r--spec/services/integrations/test/project_service_spec.rb195
-rw-r--r--spec/services/issuable/bulk_update_service_spec.rb89
-rw-r--r--spec/services/issues/close_service_spec.rb23
-rw-r--r--spec/services/issues/create_service_spec.rb2
-rw-r--r--spec/services/issues/import_csv_service_spec.rb20
-rw-r--r--spec/services/issues/update_service_spec.rb34
-rw-r--r--spec/services/jira/requests/projects_spec.rb95
-rw-r--r--spec/services/jira_import/start_import_service_spec.rb26
-rw-r--r--spec/services/jira_import/users_importer_spec.rb77
-rw-r--r--spec/services/jira_import/users_mapper_spec.rb43
-rw-r--r--spec/services/labels/available_labels_service_spec.rb6
-rw-r--r--spec/services/merge_requests/close_service_spec.rb65
-rw-r--r--spec/services/merge_requests/create_service_spec.rb6
-rw-r--r--spec/services/merge_requests/delete_non_latest_diffs_service_spec.rb4
-rw-r--r--spec/services/merge_requests/ff_merge_service_spec.rb105
-rw-r--r--spec/services/merge_requests/merge_service_spec.rb41
-rw-r--r--spec/services/merge_requests/refresh_service_spec.rb164
-rw-r--r--spec/services/merge_requests/reopen_service_spec.rb22
-rw-r--r--spec/services/namespaces/check_storage_size_service_spec.rb8
-rw-r--r--spec/services/notification_recipients/build_service_spec.rb52
-rw-r--r--spec/services/notification_service_spec.rb56
-rw-r--r--spec/services/projects/alerting/notify_service_spec.rb65
-rw-r--r--spec/services/projects/container_repository/cleanup_tags_service_spec.rb43
-rw-r--r--spec/services/projects/create_service_spec.rb162
-rw-r--r--spec/services/projects/group_links/create_service_spec.rb15
-rw-r--r--spec/services/projects/group_links/destroy_service_spec.rb18
-rw-r--r--spec/services/projects/group_links/update_service_spec.rb56
-rw-r--r--spec/services/projects/import_export/export_service_spec.rb6
-rw-r--r--spec/services/projects/lsif_data_service_spec.rb126
-rw-r--r--spec/services/projects/operations/update_service_spec.rb29
-rw-r--r--spec/services/projects/prometheus/alerts/create_events_service_spec.rb2
-rw-r--r--spec/services/projects/prometheus/alerts/notify_service_spec.rb146
-rw-r--r--spec/services/projects/propagate_service_template_spec.rb4
-rw-r--r--spec/services/projects/update_pages_service_spec.rb17
-rw-r--r--spec/services/projects/update_remote_mirror_service_spec.rb17
-rw-r--r--spec/services/projects/update_repository_storage_service_spec.rb6
-rw-r--r--spec/services/projects/update_service_spec.rb78
-rw-r--r--spec/services/prometheus/create_default_alerts_service_spec.rb19
-rw-r--r--spec/services/prometheus/proxy_service_spec.rb39
-rw-r--r--spec/services/prometheus/proxy_variable_substitution_service_spec.rb14
-rw-r--r--spec/services/quick_actions/interpret_service_spec.rb23
-rw-r--r--spec/services/releases/create_evidence_service_spec.rb28
-rw-r--r--spec/services/releases/create_service_spec.rb177
-rw-r--r--spec/services/resource_events/change_state_service_spec.rb39
-rw-r--r--spec/services/service_response_spec.rb10
-rw-r--r--spec/services/snippets/bulk_destroy_service_spec.rb12
-rw-r--r--spec/services/snippets/create_service_spec.rb59
-rw-r--r--spec/services/snippets/update_service_spec.rb78
-rw-r--r--spec/services/spam/akismet_service_spec.rb8
-rw-r--r--spec/services/spam/spam_action_service_spec.rb12
-rw-r--r--spec/services/spam/spam_verdict_service_spec.rb250
-rw-r--r--spec/services/submit_usage_ping_service_spec.rb3
-rw-r--r--spec/services/suggestions/apply_service_spec.rb553
-rw-r--r--spec/services/system_notes/issuables_service_spec.rb15
-rw-r--r--spec/services/test_hooks/project_service_spec.rb16
-rw-r--r--spec/services/test_hooks/system_service_spec.rb2
-rw-r--r--spec/services/todo_service_spec.rb302
-rw-r--r--spec/services/user_project_access_changed_service_spec.rb6
-rw-r--r--spec/services/users/destroy_service_spec.rb12
-rw-r--r--spec/services/users/migrate_to_ghost_user_service_spec.rb9
-rw-r--r--spec/services/wiki_pages/event_create_service_spec.rb8
-rw-r--r--spec/spec_helper.rb51
-rw-r--r--spec/support/action_cable.rb7
-rw-r--r--spec/support/helpers/api_helpers.rb11
-rw-r--r--spec/support/helpers/design_management_test_helpers.rb3
-rw-r--r--spec/support/helpers/filter_spec_helper.rb16
-rw-r--r--spec/support/helpers/graphql_helpers.rb65
-rw-r--r--spec/support/helpers/http_basic_auth_helpers.rb26
-rw-r--r--spec/support/helpers/login_helpers.rb6
-rw-r--r--spec/support/helpers/markdown_feature.rb8
-rw-r--r--spec/support/helpers/partitioning_helpers.rb54
-rw-r--r--spec/support/helpers/prometheus_helpers.rb47
-rw-r--r--spec/support/helpers/stub_action_cable_connection.rb7
-rw-r--r--spec/support/helpers/stub_feature_flags.rb58
-rw-r--r--spec/support/helpers/stub_gitlab_calls.rb6
-rw-r--r--spec/support/helpers/trigger_helpers.rb65
-rw-r--r--spec/support/helpers/usage_data_helpers.rb24
-rw-r--r--spec/support/helpers/wiki_helpers.rb4
-rw-r--r--spec/support/import_export/common_util.rb2
-rw-r--r--spec/support/let_it_be.rb9
-rw-r--r--spec/support/matchers/exceed_query_limit.rb101
-rw-r--r--spec/support/matchers/graphql_matchers.rb22
-rw-r--r--spec/support/rspec.rb3
-rw-r--r--spec/support/shared_contexts/finders/merge_requests_finder_shared_contexts.rb31
-rw-r--r--spec/support/shared_contexts/navbar_structure_context.rb5
-rw-r--r--spec/support/shared_contexts/project_service_shared_context.rb1
-rw-r--r--spec/support/shared_contexts/requests/api/graphql/jira_import/jira_projects_context.rb104
-rw-r--r--spec/support/shared_contexts/spam_constants.rb9
-rw-r--r--spec/support/shared_examples/controllers/import_controller_new_import_ui_shared_examples.rb36
-rw-r--r--spec/support/shared_examples/controllers/issuables_list_metadata_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/controllers/milestone_tabs_shared_examples.rb10
-rw-r--r--spec/support/shared_examples/controllers/namespace_storage_limit_alert_shared_examples.rb53
-rw-r--r--spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb302
-rw-r--r--spec/support/shared_examples/features/comments_on_merge_request_files_shared_examples.rb3
-rw-r--r--spec/support/shared_examples/features/discussion_comments_shared_example.rb6
-rw-r--r--spec/support/shared_examples/graphql/container_expiration_policy_shared_examples.rb12
-rw-r--r--spec/support/shared_examples/graphql/label_fields.rb124
-rw-r--r--spec/support/shared_examples/graphql/members_shared_examples.rb22
-rw-r--r--spec/support/shared_examples/graphql/resolves_issuable_shared_examples.rb14
-rw-r--r--spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb18
-rw-r--r--spec/support/shared_examples/integrations/test_examples.rb11
-rw-r--r--spec/support/shared_examples/lib/gitlab/gl_repository_shared_examples.rb12
-rw-r--r--spec/support/shared_examples/lib/gitlab/import/stuck_import_job_workers_shared_examples.rb44
-rw-r--r--spec/support/shared_examples/lib/gitlab/position_formatters_shared_examples.rb16
-rw-r--r--spec/support/shared_examples/lib/gitlab/repo_type_shared_examples.rb20
-rw-r--r--spec/support/shared_examples/models/application_setting_shared_examples.rb34
-rw-r--r--spec/support/shared_examples/models/cluster_application_helm_cert_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/models/cluster_application_initial_status_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/models/cluster_application_status_shared_examples.rb63
-rw-r--r--spec/support/shared_examples/models/concerns/blob_replicator_strategy_shared_examples.rb117
-rw-r--r--spec/support/shared_examples/models/concerns/has_repository_shared_examples.rb8
-rw-r--r--spec/support/shared_examples/models/concerns/limitable_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/models/wiki_shared_examples.rb7
-rw-r--r--spec/support/shared_examples/path_extraction_shared_examples.rb118
-rw-r--r--spec/support/shared_examples/quick_actions/issuable/time_tracking_quick_action_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/requests/api/container_repositories_shared_examples.rb23
-rw-r--r--spec/support/shared_examples/requests/api/diff_discussions_shared_examples.rb4
-rw-r--r--spec/support/shared_examples/requests/api/graphql/group_and_project_boards_query_shared_examples.rb55
-rw-r--r--spec/support/shared_examples/requests/api/issuable_update_shared_examples.rb38
-rw-r--r--spec/support/shared_examples/requests/api/resource_label_events_api_shared_examples.rb14
-rw-r--r--spec/support/shared_examples/requests/api/resource_milestone_events_api_shared_examples.rb66
-rw-r--r--spec/support/shared_examples/serializers/diff_file_entity_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/serializers/import/import_entity_shared_examples.rb21
-rw-r--r--spec/support/shared_examples/services/container_expiration_policy_shared_examples.rb40
-rw-r--r--spec/support/shared_examples/services/wiki_pages/create_service_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/services/wiki_pages/destroy_service_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/services/wiki_pages/update_service_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/uncached_response_shared_examples.rb12
-rw-r--r--spec/support_specs/helpers/graphql_helpers_spec.rb57
-rw-r--r--spec/support_specs/helpers/stub_feature_flags_spec.rb72
-rw-r--r--spec/support_specs/matchers/exceed_query_limit_helpers_spec.rb21
-rw-r--r--spec/tasks/gitlab/container_registry_rake_spec.rb123
-rw-r--r--spec/tasks/gitlab/db_rake_spec.rb59
-rw-r--r--spec/tooling/lib/tooling/test_file_finder_spec.rb111
-rw-r--r--spec/uploaders/uploader_helper_spec.rb2
-rw-r--r--spec/validators/json_schema_validator_spec.rb50
-rw-r--r--spec/views/admin/application_settings/_repository_storage.html.haml_spec.rb20
-rw-r--r--spec/views/layouts/_head.html.haml_spec.rb13
-rw-r--r--spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb6
-rw-r--r--spec/views/profiles/preferences/show.html.haml_spec.rb3
-rw-r--r--spec/views/projects/edit.html.haml_spec.rb16
-rw-r--r--spec/views/projects/issues/import_csv/_button.html.haml_spec.rb43
-rw-r--r--spec/views/projects/merge_requests/show.html.haml_spec.rb4
-rw-r--r--spec/views/projects/services/_form.haml_spec.rb4
-rw-r--r--spec/views/shared/milestones/_top.html.haml_spec.rb16
-rw-r--r--spec/workers/build_finished_worker_spec.rb33
-rw-r--r--spec/workers/ci/build_report_result_worker_spec.rb30
-rw-r--r--spec/workers/clusters/applications/check_prometheus_health_worker_spec.rb19
-rw-r--r--spec/workers/concerns/application_worker_spec.rb40
-rw-r--r--spec/workers/concerns/project_import_options_spec.rb2
-rw-r--r--spec/workers/container_expiration_policy_worker_spec.rb17
-rw-r--r--spec/workers/create_evidence_worker_spec.rb17
-rw-r--r--spec/workers/every_sidekiq_worker_spec.rb6
-rw-r--r--spec/workers/expire_job_cache_worker_spec.rb2
-rw-r--r--spec/workers/gitlab/import/stuck_project_import_jobs_worker_spec.rb27
-rw-r--r--spec/workers/gitlab/jira_import/stage/finish_import_worker_spec.rb48
-rw-r--r--spec/workers/gitlab/jira_import/stage/import_attachments_worker_spec.rb25
-rw-r--r--spec/workers/gitlab/jira_import/stage/import_issues_worker_spec.rb66
-rw-r--r--spec/workers/gitlab/jira_import/stage/import_labels_worker_spec.rb43
-rw-r--r--spec/workers/gitlab/jira_import/stage/import_notes_worker_spec.rb25
-rw-r--r--spec/workers/gitlab/jira_import/stage/start_import_worker_spec.rb76
-rw-r--r--spec/workers/gitlab/jira_import/stuck_jira_import_jobs_worker_spec.rb39
-rw-r--r--spec/workers/group_import_worker_spec.rb13
-rw-r--r--spec/workers/incident_management/process_alert_worker_spec.rb7
-rw-r--r--spec/workers/incident_management/process_prometheus_alert_worker_spec.rb4
-rw-r--r--spec/workers/irker_worker_spec.rb99
-rw-r--r--spec/workers/metrics/dashboard/prune_old_annotations_worker_spec.rb40
-rw-r--r--spec/workers/metrics/dashboard/schedule_annotations_prune_worker_spec.rb13
-rw-r--r--spec/workers/new_note_worker_spec.rb12
-rw-r--r--spec/workers/personal_access_tokens/expiring_worker_spec.rb22
-rw-r--r--spec/workers/pipeline_update_ci_ref_status_worker_service_spec.rb1
-rw-r--r--spec/workers/post_receive_spec.rb2
-rw-r--r--spec/workers/propagate_integration_worker_spec.rb26
-rw-r--r--spec/workers/remove_expired_group_links_worker_spec.rb41
-rw-r--r--spec/workers/repository_check/single_repository_worker_spec.rb4
-rw-r--r--spec/workers/stuck_import_jobs_worker_spec.rb47
-rwxr-xr-xtooling/bin/find_foss_tests29
-rw-r--r--tooling/lib/tooling/test_file_finder.rb78
-rw-r--r--tooling/overcommit/Gemfile2
-rw-r--r--tooling/overcommit/Gemfile.lock61
-rw-r--r--[-rwxr-xr-x]vendor/gitignore/C++.gitignore0
-rw-r--r--[-rwxr-xr-x]vendor/gitignore/Java.gitignore0
-rw-r--r--vendor/project_templates/learn_gitlab.tar.gzbin0 -> 114701 bytes
-rw-r--r--yarn.lock2800
6092 files changed, 313381 insertions, 93943 deletions
diff --git a/.editorconfig b/.editorconfig
index d704f20c726..56ce6d87145 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -13,3 +13,6 @@ indent_size = 2
[*.{js,json,vue,scss,rb,haml,yml,md}]
indent_style = space
charset = utf-8
+
+[*.{md,markdown}]
+trim_trailing_whitespace = false
diff --git a/.eslintignore b/.eslintignore
index f364771e54f..c41556f6aae 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -9,6 +9,7 @@
/scripts/
/tmp/
/vendor/
+jest.config.js
jest.config.*.js
karma.config.js
webpack.config.js
diff --git a/.gitignore b/.gitignore
index 3120c1c1bdc..29180b76e26 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,7 +35,6 @@ eslint-report.html
/config/gitlab.yml
/config/gitlab_ci.yml
/config/Gitlab.gitlab-license
-/config/initializers/rack_attack.rb
/config/initializers/smtp_settings.rb
/config/initializers/relative_url.rb
/config/resque.yml
@@ -92,3 +91,6 @@ jsdoc/
webpack-dev-server.json
/.nvimrc
.solargraph.yml
+apollo.config.js
+/tmp/matching_foss_tests.txt
+ee/changelogs/unreleased-ee
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 21dfd6563e2..4bbf411c233 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -15,7 +15,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.6.6-golang-1.14-git-2.26-lfs-2.9-chrome-73.0-node-12.x-yarn-1.21-postgresql-9.6-graphicsmagick-1.3.34"
+ image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-golang-1.14-git-2.27-lfs-2.9-chrome-83-node-12.x-yarn-1.21-postgresql-11-graphicsmagick-1.3.34"
tags:
- gitlab-org
# All jobs are interruptible by default
diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS
index e71e74fd4d3..6cd316349c8 100644
--- a/.gitlab/CODEOWNERS
+++ b/.gitlab/CODEOWNERS
@@ -8,11 +8,15 @@
# Technical writing team are the default reviewers for all markdown docs
/doc/ @gl-docsteam
-# Dev and Doc guidelines
+# Doc subpaths
+/doc/administration/monitoring/ @aqualls
/doc/development/ @marcia @mjang1
/doc/development/documentation/ @mikelewis
/doc/ci @marcel.amirault @sselhorn
-/doc/.linting @marcel.amirault @eread @aqualls @mikelewis
+/doc/user/clusters @aqualls
+/doc/user/infrastructure @aqualls
+/doc/user/project/clusters @aqualls
+/doc/.vale/ @marcel.amirault @eread @aqualls @mikelewis
# Frontend maintainers should see everything in `app/assets/`
*.scss @annabeldunstone @gitlab-org/maintainers/frontend
@@ -37,7 +41,6 @@
/ee/app/finders/ @gitlab-org/maintainers/database
# Feature specific owners
-/ee/lib/gitlab/code_owners/ @reprazent @kerrizor
/ee/lib/ee/gitlab/auth/ldap/ @dblessing @mkozono
/lib/gitlab/auth/ldap/ @dblessing @mkozono
/lib/gitlab/ci/templates/ @nolith @zj
@@ -46,6 +49,11 @@
/ee/app/models/project_alias.rb @patrickbajao
/ee/lib/api/project_aliases.rb @patrickbajao
+# Code Owners
+#
+/ee/lib/gitlab/code_owners/ @reprazent @kerrizor @garyh
+/doc/user/project/code_owners.md @reprazent @kerrizor @garyh
+
# Quality owned files
/qa/ @gl-quality
diff --git a/.gitlab/ci/docs.gitlab-ci.yml b/.gitlab/ci/docs.gitlab-ci.yml
index 50dbef44598..5a6f2aacf93 100644
--- a/.gitlab/ci/docs.gitlab-ci.yml
+++ b/.gitlab/ci/docs.gitlab-ci.yml
@@ -62,7 +62,7 @@ docs lint:
graphql-reference-verify:
extends:
- .default-retry
- - .default-cache
+ - .rails-cache
- .default-before_script
- .docs:rules:graphql-reference-verify
- .use-pg11
diff --git a/.gitlab/ci/frontend.gitlab-ci.yml b/.gitlab/ci/frontend.gitlab-ci.yml
index 6e9119f295a..4403187d422 100644
--- a/.gitlab/ci/frontend.gitlab-ci.yml
+++ b/.gitlab/ci/frontend.gitlab-ci.yml
@@ -1,157 +1,128 @@
-.assets-compile-cache:
- cache:
- paths:
- - vendor/ruby/
- - public/assets/webpack/
- - assets-hash.txt
- - .yarn-cache/
- - tmp/cache/assets/sprockets
- - tmp/cache/babel-loader
- - tmp/cache/vue-loader
- - tmp/cache/webpack-dlls
-
-.gitlab:assets:compile-metadata:
+.frontend-base:
extends:
- .default-retry
- .default-before_script
- .assets-compile-cache
- image: registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-git-2.26-lfs-2.9-chrome-73.0-node-12.x-yarn-1.21-graphicsmagick-1.3.34-docker-19.03.1
+ variables:
+ SETUP_DB: "false"
+ # we override the max_old_space_size to prevent OOM errors
+ NODE_OPTIONS: --max_old_space_size=3584
+ WEBPACK_VENDOR_DLL: "true"
+
+.compile-assets-base:
+ extends: .frontend-base
+ image: registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-git-2.27-lfs-2.9-node-12.x-yarn-1.21-graphicsmagick-1.3.34
stage: prepare
+ script:
+ - node --version
+ - run_timed_command "retry yarn install --frozen-lockfile"
+ - free -m
+ - run_timed_command "bin/rake gitlab:assets:compile > assets-compile.log 2>&1"
+ - run_timed_command "scripts/clean-old-cached-assets"
+
+compile-production-assets:
+ extends:
+ - .compile-assets-base
+ - .frontend:rules:compile-production-assets
variables:
NODE_ENV: "production"
RAILS_ENV: "production"
- SETUP_DB: "false"
- SKIP_STORAGE_VALIDATION: "true"
WEBPACK_REPORT: "true"
- # we override the max_old_space_size to prevent OOM errors
- NODE_OPTIONS: --max_old_space_size=3584
- cache:
- key: "assets-compile:production:v1"
artifacts:
name: webpack-report
expire_in: 31d
paths:
- - webpack-report/
- assets-compile.log
# These assets are used in multiple locations:
# - in `build-assets-image` job to create assets image for packaging systems
# - GitLab UI for integration tests: https://gitlab.com/gitlab-org/gitlab-ui/-/blob/e88493b3c855aea30bf60baee692a64606b0eb1e/.storybook/preview-head.pug#L1
- - public/assets
+ - public/assets/
+ - webpack-report/
when: always
- script:
- - node --version
- - retry yarn install --frozen-lockfile --production --cache-folder .yarn-cache --prefer-offline
- - free -m
- - time bin/rake gitlab:assets:compile > assets-compile.log 2>&1
- - scripts/clean-old-cached-assets
+ after_script:
- rm -f /etc/apt/sources.list.d/google*.list # We don't need to update Chrome here
-gitlab:assets:compile pull-push-cache:
+compile-test-assets:
extends:
- - .gitlab:assets:compile-metadata
- - .frontend:rules:gitlab-assets-compile-pull-push-cache
- cache:
- policy: pull-push
-
-gitlab:assets:compile pull-cache:
- extends:
- - .gitlab:assets:compile-metadata
- - .frontend:rules:gitlab-assets-compile-pull-cache
- cache:
- policy: pull
-
-build-assets-image:
- extends:
- - .use-kaniko
- - .frontend:rules:gitlab-assets-compile-pull-cache
- stage: build-images
- needs: ["gitlab:assets:compile pull-cache"]
- variables:
- GIT_DEPTH: "1"
- script:
- # TODO: Change the image tag to be the MD5 of assets files and skip image building if the image exists
- # We'll also need to pass GITLAB_ASSETS_TAG to the trigerred omnibus-gitlab pipeline similarly to how we do it for trigerred CNG pipelines
- # https://gitlab.com/gitlab-org/gitlab/issues/208389
- - scripts/build_assets_image
-
-.compile-assets-metadata:
- extends:
- - .default-retry
- - .default-before_script
- - .assets-compile-cache
- stage: prepare
- script:
- - node --version
- - retry yarn install --frozen-lockfile --cache-folder .yarn-cache --prefer-offline
- - free -m
- - time bin/rake gitlab:assets:compile > assets-compile.log 2>&1
- - scripts/clean-old-cached-assets
- variables:
- SETUP_DB: "false"
- # we override the max_old_space_size to prevent OOM errors
- NODE_OPTIONS: --max_old_space_size=3584
- WEBPACK_VENDOR_DLL: "true"
- cache:
- key: "assets-compile:test:v1"
+ - .compile-assets-base
+ - .frontend:rules:compile-test-assets
artifacts:
expire_in: 7d
paths:
- - node_modules
- - public/assets
- assets-compile.log
+ - public/assets/
+ - node_modules/@gitlab/svgs/dist/icons.json # app/helpers/icons_helper.rb uses this file
when: always
-compile-assets pull-push-cache:
+compile-test-assets as-if-foss:
extends:
- - .compile-assets-metadata
- - .frontend:rules:compile-assets-pull-push-cache
- cache:
- policy: pull-push
+ - compile-test-assets
+ - .frontend:rules:compile-test-assets-as-if-foss
+ - .as-if-foss
-compile-assets pull-push-cache as-if-foss:
+update-assets-compile-production-cache:
extends:
- - .compile-assets-metadata
- - .frontend:rules:compile-assets-pull-push-cache-as-if-foss
- - .as-if-foss
+ - compile-production-assets
+ - .shared:rules:update-cache
+ stage: prepare
+ artifacts: {} # This job's purpose is only to update the cache.
cache:
- policy: pull-push
- key: "assets-compile:test:as-if-foss:v1"
+ policy: push # We want to rebuild the cache from scratch to ensure stale dependencies are cleaned up.
-compile-assets pull-cache:
+update-assets-compile-test-cache:
extends:
- - .compile-assets-metadata
- - .frontend:rules:compile-assets-pull-cache
+ - compile-test-assets
+ - .shared:rules:update-cache
+ stage: prepare
+ artifacts: {} # This job's purpose is only to update the cache.
cache:
- policy: pull
+ policy: push # We want to rebuild the cache from scratch to ensure stale dependencies are cleaned up.
-compile-assets pull-cache as-if-foss:
+update-yarn-cache:
extends:
- - .compile-assets-metadata
- - .frontend:rules:compile-assets-pull-cache-as-if-foss
- - .as-if-foss
+ - .default-retry
+ - .yarn-cache
+ - .shared:rules:update-cache
+ stage: prepare
+ script:
+ - source scripts/utils.sh
+ - run_timed_command "retry yarn install --frozen-lockfile"
cache:
- policy: pull
- key: "assets-compile:test:as-if-foss:v1"
+ policy: push
+
+build-assets-image:
+ extends:
+ - .use-kaniko
+ - .frontend:rules:compile-production-assets
+ stage: build-images
+ needs: ["compile-production-assets"]
+ variables:
+ GIT_DEPTH: "1"
+ script:
+ # TODO: Change the image tag to be the MD5 of assets files and skip image building if the image exists
+ # We'll also need to pass GITLAB_ASSETS_TAG to the trigerred omnibus-gitlab pipeline similarly to how we do it for trigerred CNG pipelines
+ # https://gitlab.com/gitlab-org/gitlab/issues/208389
+ - run_timed_command "scripts/build_assets_image"
+ retry: 2
.frontend-fixtures-base:
extends:
- - .default-retry
+ - .frontend-base
- .rails-cache
- - .default-before_script
- .use-pg11
stage: fixtures
- needs: ["setup-test-env", "compile-assets pull-cache"]
+ needs: ["setup-test-env", "compile-test-assets"]
+ variables:
+ SETUP_DB: "true"
script:
- run_timed_command "scripts/gitaly-test-build"
- run_timed_command "scripts/gitaly-test-spawn"
- - run_timed_command "bundle exec rake frontend:fixtures"
+ - run_timed_command "bin/rake frontend:fixtures"
artifacts:
name: frontend-fixtures
expire_in: 31d
when: always
paths:
- - node_modules
- - public/assets
- tmp/tests/frontend/
frontend-fixtures:
@@ -165,25 +136,27 @@ frontend-fixtures-as-if-foss:
- .frontend:rules:default-frontend-jobs-as-if-foss
- .as-if-foss
-.frontend-job-base:
+.frontend-test-base:
extends:
- .default-retry
- - .default-cache
- - .default-before_script
+ - .yarn-cache
variables:
USE_BUNDLE_INSTALL: "false"
SETUP_DB: "false"
stage: test
+ before_script:
+ - source scripts/utils.sh
.karma-base:
- extends: .frontend-job-base
+ extends: .frontend-test-base
variables:
# we override the max_old_space_size to prevent OOM errors
NODE_OPTIONS: --max_old_space_size=3584
script:
+ - source scripts/utils.sh
- export BABEL_ENV=coverage CHROME_LOG_FILE=chrome_debug.log
- - date
- - yarn karma
+ - run_timed_command "retry yarn install --frozen-lockfile"
+ - run_timed_command "yarn karma"
karma:
extends:
@@ -210,15 +183,11 @@ karma-as-if-foss:
needs: ["frontend-fixtures-as-if-foss"]
.jest-base:
- extends: .frontend-job-base
+ extends: .frontend-test-base
script:
- - date
- - yarn jest --ci --coverage --testSequencer ./scripts/frontend/parallel_ci_sequencer.js
- cache:
- key: jest
- paths:
- - tmp/cache/jest/
- policy: pull-push
+ - source scripts/utils.sh
+ - run_timed_command "retry yarn install --frozen-lockfile"
+ - run_timed_command "yarn jest --ci --coverage --testSequencer ./scripts/frontend/parallel_ci_sequencer.js"
jest:
extends:
@@ -235,21 +204,17 @@ jest:
- tmp/tests/frontend/
reports:
junit: junit_jest.xml
- parallel: 2
+ parallel: 4
jest-integration:
extends:
- - .frontend-job-base
+ - .frontend-test-base
- .frontend:rules:default-frontend-jobs
script:
- - date
- - yarn jest:integration --ci
+ - source scripts/utils.sh
+ - run_timed_command "retry yarn install --frozen-lockfile"
+ - run_timed_command "yarn jest:integration --ci"
needs: ["frontend-fixtures"]
- cache:
- key: jest-integration
- paths:
- - tmp/cache/jest/
- policy: pull-push
jest-as-if-foss:
extends:
@@ -257,8 +222,7 @@ jest-as-if-foss:
- .frontend:rules:default-frontend-jobs-as-if-foss
- .as-if-foss
needs: ["frontend-fixtures-as-if-foss"]
- cache:
- policy: pull
+ parallel: 2
coverage-frontend:
extends:
@@ -269,33 +233,26 @@ coverage-frontend:
stage: post-test
before_script:
- source scripts/utils.sh
- - retry yarn install --frozen-lockfile
+ - run_timed_command "retry yarn install --frozen-lockfile"
script:
- - yarn node scripts/frontend/merge_coverage_frontend.js
+ - run_timed_command "yarn node scripts/frontend/merge_coverage_frontend.js"
artifacts:
name: coverage-frontend
expire_in: 31d
paths:
- coverage-frontend/
- cache:
- policy: pull
.qa-frontend-node:
extends:
- .default-retry
+ - .yarn-cache
- .frontend:rules:qa-frontend-node
stage: test
dependencies: []
- cache:
- key: "$CI_JOB_NAME"
- paths:
- - .yarn-cache/
- policy: pull-push
script:
- - date
- - yarn install --frozen-lockfile --cache-folder .yarn-cache --prefer-offline
- - date
- - yarn run webpack-prod
+ - source scripts/utils.sh
+ - run_timed_command "yarn install --frozen-lockfile"
+ - run_timed_command "yarn run webpack-prod"
qa-frontend-node:10:
extends: .qa-frontend-node
@@ -310,27 +267,39 @@ qa-frontend-node:latest:
webpack-dev-server:
extends:
- .default-retry
+ - .yarn-cache
- .frontend:rules:default-frontend-jobs
stage: test
needs: []
variables:
WEBPACK_MEMORY_TEST: "true"
WEBPACK_VENDOR_DLL: "true"
- cache:
- key:
- files:
- - yarn.lock
- prefix: "v1"
- paths:
- - node_modules/
- - tmp/cache/webpack-dlls/
script:
- source scripts/utils.sh
- - retry yarn install --frozen-lockfile
- - retry yarn webpack-vendor
- - node --expose-gc node_modules/.bin/webpack-dev-server --config config/webpack.config.js
+ - run_timed_command "retry yarn install --frozen-lockfile"
+ - run_timed_command "retry yarn webpack-vendor"
+ - run_timed_command "node --expose-gc node_modules/.bin/webpack-dev-server --config config/webpack.config.js"
artifacts:
name: webpack-dev-server
expire_in: 31d
paths:
- webpack-dev-server.json
+
+bundle-size-review:
+ extends:
+ - .default-retry
+ - .frontend:rules:bundle-size-review
+ image: registry.gitlab.com/gitlab-org/gitlab-build-images:danger
+ stage: test
+ needs: ["compile-production-assets"]
+ script:
+ - mkdir -p bundle-size-review
+ - cp webpack-report/index.html bundle-size-review/bundle-report.html
+ - yarn global add https://gitlab.com/gitlab-org/frontend/playground/webpack-memory-metrics.git
+ - danger --dangerfile=danger/bundle_size/Dangerfile --fail-on-errors=true --verbose --danger_id=bundle-size-review
+ artifacts:
+ when: always
+ name: bundle-size-review
+ expire_in: 31d
+ paths:
+ - bundle-size-review
diff --git a/.gitlab/ci/global.gitlab-ci.yml b/.gitlab/ci/global.gitlab-ci.yml
index e6619ff2b6d..30e3abf13be 100644
--- a/.gitlab/ci/global.gitlab-ci.yml
+++ b/.gitlab/ci/global.gitlab-ci.yml
@@ -10,49 +10,61 @@
.default-before_script:
before_script:
- - date
- '[ "$FOSS_ONLY" = "1" ] && rm -rf ee/ qa/spec/ee/ qa/qa/specs/features/ee/ qa/qa/ee/ qa/qa/ee.rb'
- export GOPATH=$CI_PROJECT_DIR/.go
- mkdir -p $GOPATH
- source scripts/utils.sh
- source scripts/prepare_build.sh
- - date
-# Jobs that only need to pull cache
-.default-cache:
+.rails-cache:
cache:
- key: "debian-stretch-ruby-2.6.6-pg11-node-12.x"
+ key: "rails-v1"
paths:
- - .go/pkg/mod
- - vendor/ruby
- - .yarn-cache/
- - vendor/gitaly-ruby
+ - vendor/ruby/
+ - vendor/gitaly-ruby/
+ - .go/pkg/mod/
policy: pull
-.rails-cache:
+.static-analysis-cache:
+ cache:
+ key: "static-analysis-v1"
+ paths:
+ - vendor/ruby/
+ - node_modules/
+ - tmp/rubocop_cache/
+ policy: pull
+
+.qa-cache:
cache:
- key:
- files:
- - Gemfile.lock
- - GITALY_SERVER_VERSION
- prefix: "ruby-go-cache-v1"
+ key: "qa-v1"
paths:
- - vendor/ruby
- - vendor/gitaly-ruby
- - .go/pkg/mod
+ - qa/vendor/ruby/
policy: pull
.yarn-cache:
cache:
- key:
- files:
- - yarn.lock
- prefix: "v1"
+ key: "yarn-v1"
paths:
- node_modules/
+ - tmp/cache/webpack-dlls/
+ policy: pull
+
+.assets-compile-cache:
+ cache:
+ key: "assets-compile-${NODE_ENV}-v1"
+ paths:
+ - vendor/ruby/
+ - node_modules/
+ - assets-hash.txt
+ - public/assets/webpack/
+ - tmp/cache/assets/sprockets/
+ - tmp/cache/babel-loader/
+ - tmp/cache/vue-loader/
+ - tmp/cache/webpack-dlls/
+ policy: pull
.use-pg11:
- image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-golang-1.14-git-2.26-lfs-2.9-chrome-73.0-node-12.x-yarn-1.21-postgresql-11-graphicsmagick-1.3.34"
+ image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-golang-1.14-git-2.27-lfs-2.9-chrome-83-node-12.x-yarn-1.21-postgresql-11-graphicsmagick-1.3.34"
services:
- name: postgres:11.6
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
@@ -61,7 +73,7 @@
POSTGRES_HOST_AUTH_METHOD: trust
.use-pg11-ee:
- image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-golang-1.14-git-2.26-lfs-2.9-chrome-73.0-node-12.x-yarn-1.21-postgresql-11-graphicsmagick-1.3.34"
+ image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.6-golang-1.14-git-2.27-lfs-2.9-chrome-83-node-12.x-yarn-1.21-postgresql-11-graphicsmagick-1.3.34"
services:
- name: postgres:11.6
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
@@ -75,6 +87,7 @@
name: gcr.io/kaniko-project/executor:debug-v0.20.0
entrypoint: [""]
before_script:
+ - source scripts/utils.sh
- mkdir -p /kaniko/.docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
diff --git a/.gitlab/ci/memory.gitlab-ci.yml b/.gitlab/ci/memory.gitlab-ci.yml
index 79dfc88d132..ef6c9b9c8ff 100644
--- a/.gitlab/ci/memory.gitlab-ci.yml
+++ b/.gitlab/ci/memory.gitlab-ci.yml
@@ -1,7 +1,7 @@
.only-code-memory-job-base:
extends:
- .default-retry
- - .default-cache
+ - .rails-cache
- .default-before_script
- .memory:rules
@@ -39,12 +39,11 @@ memory-on-boot:
- .only-code-memory-job-base
- .use-pg11
stage: test
- needs: ["setup-test-env", "compile-assets pull-cache"]
+ needs: ["setup-test-env", "compile-test-assets"]
variables:
NODE_ENV: "production"
RAILS_ENV: "production"
SETUP_DB: "true"
- SKIP_STORAGE_VALIDATION: "true"
# we override the max_old_space_size to prevent OOM errors
NODE_OPTIONS: --max_old_space_size=3584
script:
diff --git a/.gitlab/ci/pages.gitlab-ci.yml b/.gitlab/ci/pages.gitlab-ci.yml
index 218ec7043d9..a66e0d88db3 100644
--- a/.gitlab/ci/pages.gitlab-ci.yml
+++ b/.gitlab/ci/pages.gitlab-ci.yml
@@ -3,11 +3,16 @@ pages:
- .default-retry
- .pages:rules
stage: pages
- dependencies: ["rspec:coverage", "karma", "gitlab:assets:compile pull-cache"]
+ dependencies:
+ - rspec:coverage
+ - coverage-frontend
+ - karma
+ - compile-production-assets
script:
- mv public/ .public/
- mkdir public/
- mv coverage/ public/coverage-ruby/ || true
+ - mv coverage-frontend/ public/coverage-frontend/ || true
- mv coverage-javascript/ public/coverage-javascript/ || true
- mv webpack-report/ public/webpack-report/ || true
- cp .public/assets/application-*.css public/application.css || true
diff --git a/.gitlab/ci/qa.gitlab-ci.yml b/.gitlab/ci/qa.gitlab-ci.yml
index 40ef13dd92b..20527b690a7 100644
--- a/.gitlab/ci/qa.gitlab-ci.yml
+++ b/.gitlab/ci/qa.gitlab-ci.yml
@@ -1,12 +1,9 @@
.qa-job-base:
extends:
- .default-retry
+ - .qa-cache
stage: test
needs: []
- cache:
- key: "qa-framework-jobs:v1"
- paths:
- - vendor/ruby
before_script:
- '[ "$FOSS_ONLY" = "1" ] && rm -rf ee/ qa/spec/ee/ qa/qa/specs/features/ee/ qa/qa/ee/ qa/qa/ee.rb'
- cd qa/
@@ -22,11 +19,9 @@ qa:internal:
qa:internal-as-if-foss:
extends:
- - .qa-job-base
+ - qa:internal
- .qa:rules:as-if-foss
- .as-if-foss
- script:
- - bundle exec rspec
qa:selectors:
extends:
@@ -41,6 +36,16 @@ qa:selectors-as-if-foss:
- .qa:rules:as-if-foss
- .as-if-foss
+update-qa-cache:
+ extends:
+ - .qa-job-base
+ - .shared:rules:update-cache
+ stage: prepare
+ script:
+ - echo "Cache has been updated and ready to be uploaded."
+ cache:
+ policy: push # We want to rebuild the cache from scratch to ensure stale dependencies are cleaned up.
+
.package-and-qa-base:
image: ruby:2.6-alpine
stage: qa
diff --git a/.gitlab/ci/rails.gitlab-ci.yml b/.gitlab/ci/rails.gitlab-ci.yml
index e8087aebcef..f73e0c1d503 100644
--- a/.gitlab/ci/rails.gitlab-ci.yml
+++ b/.gitlab/ci/rails.gitlab-ci.yml
@@ -1,6 +1,3 @@
-.rails:needs:setup-and-assets:
- needs: ["setup-test-env", "compile-assets pull-cache"]
-
.rails-job-base:
extends:
- .default-retry
@@ -35,32 +32,54 @@ setup-test-env:
- tmp/tests/repositories
- tmp/tests/second_storage
when: always
+
+update-rails-cache:
+ extends:
+ - setup-test-env
+ - .shared:rules:update-cache
+ artifacts: {} # This job's purpose is only to update the cache.
+ cache:
+ policy: push # We want to rebuild the cache from scratch to ensure stale dependencies are cleaned up.
+
+.static-analysis-base:
+ extends:
+ - .default-retry
+ - .default-before_script
+ - .static-analysis-cache
+ needs: []
+ variables:
+ SETUP_DB: "false"
+ ENABLE_SPRING: "1"
+
+update-static-analysis-cache:
+ extends:
+ - .static-analysis-base
+ - .shared:rules:update-cache
+ stage: prepare
+ script:
+ - rm -rf ./node_modules # We remove node_modules because there's no mechanism to remove stall entries.
+ - run_timed_command "retry yarn install --frozen-lockfile"
+ - bundle exec rubocop --parallel # For the moment we only cache `vendor/ruby/`, `node_modules/`, and `tmp/rubocop_cache` so we don't need to run all the tasks,
cache:
+ # We want to rebuild the cache from scratch to ensure stale dependencies are cleaned up but RuboCop has a mechanism
+ # for keeping only the N latest cache files, so we take advantage of it with `pull-push` and removing `node_modules` at the start of the job.
policy: pull-push
static-analysis:
extends:
- - .rails-job-base
+ - .static-analysis-base
- .rails:rules:default-refs-code-backstage-qa
- - .rails:needs:setup-and-assets
stage: test
- variables:
- SETUP_DB: "false"
- parallel: 2
+ parallel: 4
script:
+ - run_timed_command "retry yarn install --frozen-lockfile"
- scripts/static-analysis
- cache:
- key: "ruby-2.6.6-pg11-rubocop"
- paths:
- - vendor/ruby
- - tmp/rubocop_cache
- policy: pull-push
downtime_check:
extends:
- .rails-job-base
- .rails:rules:downtime_check
- needs: ["setup-test-env"]
+ needs: []
stage: test
variables:
SETUP_DB: "false"
@@ -70,7 +89,7 @@ downtime_check:
.rspec-base:
extends: .rails-job-base
stage: test
- needs: ["setup-test-env", "retrieve-tests-metadata", "compile-assets pull-cache"]
+ needs: ["setup-test-env", "retrieve-tests-metadata", "compile-test-assets"]
script:
- run_timed_command "scripts/gitaly-test-build"
- run_timed_command "scripts/gitaly-test-spawn"
@@ -173,7 +192,7 @@ db:migrate-from-v12.10.0:
db:rollback:
extends: .db-job-base
script:
- - bundle exec rake db:migrate VERSION=20180101160629
+ - bundle exec rake db:migrate VERSION=20181228175414
- bundle exec rake db:migrate SKIP_SCHEMA_VERSION_CHECK=true
gitlab:setup:
@@ -218,8 +237,6 @@ rspec:coverage:
- memory-on-boot
variables:
SETUP_DB: "false"
- cache:
- policy: pull
script:
- bundle exec scripts/merge-simplecov
- bundle exec scripts/gather-test-memory-data
@@ -247,7 +264,7 @@ rspec:coverage:
- .rails:rules:as-if-foss
- .as-if-foss
- .use-pg11
- needs: ["setup-test-env", "retrieve-tests-metadata", "compile-assets pull-cache as-if-foss"]
+ needs: ["setup-test-env", "retrieve-tests-metadata", "compile-test-assets as-if-foss"]
.rspec-ee-base-pg11:
extends:
@@ -323,3 +340,26 @@ db:rollback geo:
- bundle exec rake geo:db:migrate
# EE: default refs (MRs, master, schedules) jobs #
##################################################
+
+##################################################
+# EE: Canonical MR pipelines
+rspec foss-impact:
+ extends:
+ - .rspec-base
+ - .as-if-foss
+ - .rails:rules:ee-mr-only
+ - .use-pg11
+ script:
+ - install_gitlab_gem
+ - run_timed_command "scripts/gitaly-test-build"
+ - run_timed_command "scripts/gitaly-test-spawn"
+ - source scripts/rspec_helpers.sh
+ - tooling/bin/find_foss_tests tmp/matching_foss_tests.txt
+ - rspec_matched_tests tmp/matching_foss_tests.txt "--tag ~quarantine --tag ~geo --tag ~level:migration"
+ artifacts:
+ expire_in: 7d
+ paths:
+ - tmp/matching_foss_tests.txt
+ - tmp/capybara/
+# EE: Merge Request pipelines
+##################################################
diff --git a/.gitlab/ci/reports.gitlab-ci.yml b/.gitlab/ci/reports.gitlab-ci.yml
index 153334e1aff..65abb6c5cba 100644
--- a/.gitlab/ci/reports.gitlab-ci.yml
+++ b/.gitlab/ci/reports.gitlab-ci.yml
@@ -94,9 +94,9 @@ dependency_scanning:
stage: test
needs: []
variables:
+ DS_MAJOR_VERSION: 2
DS_EXCLUDED_PATHS: "qa/qa/ee/fixtures/secure_premade_reports,spec,ee/spec" # GitLab-specific
script:
- - export DS_VERSION=${SP_VERSION:-$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')}
- |
if ! docker info &>/dev/null; then
if [ -z "$DOCKER_HOST" -a "$KUBERNETES_PORT" ]; then
@@ -138,7 +138,7 @@ dependency_scanning:
) \
--volume "$PWD:/code" \
--volume /var/run/docker.sock:/var/run/docker.sock \
- "registry.gitlab.com/gitlab-org/security-products/dependency-scanning:$DS_VERSION" /code
+ "registry.gitlab.com/gitlab-org/security-products/dependency-scanning:$DS_MAJOR_VERSION" /code
artifacts:
paths:
- gl-dependency-scanning-report.json # GitLab-specific
@@ -146,37 +146,38 @@ dependency_scanning:
dependency_scanning: gl-dependency-scanning-report.json
expire_in: 1 week # GitLab-specific
-# We need to duplicate this job's definition because it seems it's impossible to
-# override an included `only.refs`.
-# See https://gitlab.com/gitlab-org/gitlab/issues/31371.
-dast:
- extends:
- - .default-retry
- - .reports:rules:dast
- # This is needed so that manual jobs with needs don't block the pipeline.
- # See https://gitlab.com/gitlab-org/gitlab/-/issues/199979.
- dependencies: ["review-deploy"]
- stage: qa # GitLab-specific
- image:
- name: "registry.gitlab.com/gitlab-org/security-products/dast:$DAST_VERSION"
- variables:
- # To be done in a later iteration
- # DAST_USERNAME: "root"
- # DAST_USERNAME_FIELD: "user[login]"
- # DAST_PASSWORD_FIELD: "user[passowrd]"
- DAST_VERSION: 1
- script:
- - 'export DAST_WEBSITE="${DAST_WEBSITE:-$(cat environment_url.txt)}"'
- # To be done in a later iteration
- # - 'export DAST_AUTH_URL="${DAST_WEBSITE}/users/sign_in"'
- # - 'export DAST_PASSWORD="${REVIEW_APPS_ROOT_PASSWORD}"'
- - /analyze -t $DAST_WEBSITE
- artifacts:
- paths:
- - gl-dast-report.json # GitLab-specific
- reports:
- dast: gl-dast-report.json
- expire_in: 1 week # GitLab-specific
+# Temporarily disabling review apps
+## We need to duplicate this job's definition because it seems it's impossible to
+## override an included `only.refs`.
+## See https://gitlab.com/gitlab-org/gitlab/issues/31371.
+#dast:
+# extends:
+# - .default-retry
+# - .reports:rules:dast
+# # This is needed so that manual jobs with needs don't block the pipeline.
+# # See https://gitlab.com/gitlab-org/gitlab/-/issues/199979.
+# dependencies: ["review-deploy"]
+# stage: qa # GitLab-specific
+# image:
+# name: "registry.gitlab.com/gitlab-org/security-products/dast:$DAST_VERSION"
+# variables:
+# # To be done in a later iteration
+# # DAST_USERNAME: "root"
+# # DAST_USERNAME_FIELD: "user[login]"
+# # DAST_PASSWORD_FIELD: "user[passowrd]"
+# DAST_VERSION: 1
+# script:
+# - 'export DAST_WEBSITE="${DAST_WEBSITE:-$(cat environment_url.txt)}"'
+# # To be done in a later iteration
+# # - 'export DAST_AUTH_URL="${DAST_WEBSITE}/users/sign_in"'
+# # - 'export DAST_PASSWORD="${REVIEW_APPS_ROOT_PASSWORD}"'
+# - /analyze -t $DAST_WEBSITE
+# artifacts:
+# paths:
+# - gl-dast-report.json # GitLab-specific
+# reports:
+# dast: gl-dast-report.json
+# expire_in: 1 week # GitLab-specific
# To be done in a later iteration: https://gitlab.com/gitlab-org/gitlab/issues/31160#note_278188255
# schedule:dast:
diff --git a/.gitlab/ci/review.gitlab-ci.yml b/.gitlab/ci/review.gitlab-ci.yml
index 46a281cd48f..6898da95c15 100644
--- a/.gitlab/ci/review.gitlab-ci.yml
+++ b/.gitlab/ci/review.gitlab-ci.yml
@@ -1,13 +1,13 @@
build-qa-image:
extends:
- .use-kaniko
- - .default-retry
- .review:rules:build-qa-image
stage: build-images
needs: []
script:
- export QA_IMAGE="${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_COMMIT_REF_SLUG}"
- /kaniko/executor --context=${CI_PROJECT_DIR} --dockerfile=${CI_PROJECT_DIR}/qa/Dockerfile --destination=${QA_IMAGE} --cache=true
+ retry: 2
review-cleanup:
extends:
@@ -27,24 +27,25 @@ review-cleanup:
- ruby -rrubygems scripts/review_apps/automated_cleanup.rb
- gcp_cleanup
-review-build-cng:
- extends:
- - .default-retry
- - .review:rules:review-build-cng
- image: ruby:2.6-alpine
- stage: review-prepare
- before_script:
- - source scripts/utils.sh
- - install_api_client_dependencies_with_apk
- - install_gitlab_gem
- needs:
- - job: gitlab:assets:compile pull-cache
- artifacts: false
- script:
- - BUILD_TRIGGER_TOKEN=$REVIEW_APPS_BUILD_TRIGGER_TOKEN ./scripts/trigger-build cng
- # When the job is manual, review-deploy is also manual and we don't want people
- # to have to manually start the jobs in sequence, so we do it for them.
- - '[ -z $CI_JOB_MANUAL ] || play_job "review-deploy"'
+# Temporarily disabling review apps
+#review-build-cng:
+# extends:
+# - .default-retry
+# - .review:rules:review-build-cng
+# image: ruby:2.6-alpine
+# stage: review-prepare
+# before_script:
+# - source scripts/utils.sh
+# - install_api_client_dependencies_with_apk
+# - install_gitlab_gem
+# needs:
+# - job: compile-production-assets
+# artifacts: false
+# script:
+# - BUILD_TRIGGER_TOKEN=$REVIEW_APPS_BUILD_TRIGGER_TOKEN ./scripts/trigger-build cng
+# # When the job is manual, review-deploy is also manual and we don't want people
+# # to have to manually start the jobs in sequence, so we do it for them.
+# - '[ -z $CI_JOB_MANUAL ] || play_job "review-deploy"'
.review-workflow-base:
extends:
@@ -53,43 +54,44 @@ review-build-cng:
variables:
HOST_SUFFIX: "${CI_ENVIRONMENT_SLUG}"
DOMAIN: "-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}"
- GITLAB_HELM_CHART_REF: "v3.3.3"
+ GITLAB_HELM_CHART_REF: "master"
environment:
name: review/${CI_COMMIT_REF_NAME}
url: https://gitlab-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}
on_stop: review-stop
auto_stop_in: 48 hours
-review-deploy:
- extends:
- - .review-workflow-base
- - .review:rules:mr-and-schedule-auto-if-frontend-manual-otherwise
- stage: review
- dependencies: []
- resource_group: "review/${CI_COMMIT_REF_NAME}"
- before_script:
- - export GITLAB_SHELL_VERSION=$(<GITLAB_SHELL_VERSION)
- - export GITALY_VERSION=$(<GITALY_SERVER_VERSION)
- - export GITLAB_WORKHORSE_VERSION=$(<GITLAB_WORKHORSE_VERSION)
- - echo "${CI_ENVIRONMENT_URL}" > environment_url.txt
- - source ./scripts/utils.sh
- - install_api_client_dependencies_with_apk
- - source scripts/review_apps/review-apps.sh
- script:
- - check_kube_domain
- - ensure_namespace
- - install_external_dns
- - download_chart
- - date
- - deploy || (display_deployment_debug && exit 1)
- # When the job is manual, review-qa-smoke is also manual and we don't want people
- # to have to manually start the jobs in sequence, so we do it for them.
- - '[ -z $CI_JOB_MANUAL ] || play_job "review-qa-smoke"'
- - '[ -z $CI_JOB_MANUAL ] || play_job "review-performance"'
- artifacts:
- paths: [environment_url.txt]
- expire_in: 2 days
- when: always
+# Temporarily disabling review apps
+#review-deploy:
+# extends:
+# - .review-workflow-base
+# - .review:rules:mr-and-schedule-auto-if-frontend-manual-otherwise
+# stage: review
+# dependencies: []
+# resource_group: "review/${CI_COMMIT_REF_NAME}"
+# before_script:
+# - export GITLAB_SHELL_VERSION=$(<GITLAB_SHELL_VERSION)
+# - export GITALY_VERSION=$(<GITALY_SERVER_VERSION)
+# - export GITLAB_WORKHORSE_VERSION=$(<GITLAB_WORKHORSE_VERSION)
+# - echo "${CI_ENVIRONMENT_URL}" > environment_url.txt
+# - source ./scripts/utils.sh
+# - install_api_client_dependencies_with_apk
+# - source scripts/review_apps/review-apps.sh
+# script:
+# - check_kube_domain
+# - ensure_namespace
+# - install_external_dns
+# - download_chart
+# - date
+# - deploy || (display_deployment_debug && exit 1)
+# # When the job is manual, review-qa-smoke is also manual and we don't want people
+# # to have to manually start the jobs in sequence, so we do it for them.
+# - '[ -z $CI_JOB_MANUAL ] || play_job "review-qa-smoke"'
+# - '[ -z $CI_JOB_MANUAL ] || play_job "review-performance"'
+# artifacts:
+# paths: [environment_url.txt]
+# expire_in: 2 days
+# when: always
.review-stop-base:
extends: .review-workflow-base
@@ -122,109 +124,110 @@ review-stop:
script:
- delete_release
-.review-qa-base:
- extends:
- - .default-retry
- - .use-docker-in-docker
- image: registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-qa-alpine-ruby-2.6
- stage: qa
- # This is needed so that manual jobs with needs don't block the pipeline.
- # See https://gitlab.com/gitlab-org/gitlab/-/issues/199979.
- dependencies: ["review-deploy"]
- variables:
- QA_ARTIFACTS_DIR: "${CI_PROJECT_DIR}/qa"
- QA_CAN_TEST_GIT_PROTOCOL_V2: "false"
- QA_DEBUG: "true"
- GITLAB_USERNAME: "root"
- GITLAB_PASSWORD: "${REVIEW_APPS_ROOT_PASSWORD}"
- GITLAB_ADMIN_USERNAME: "root"
- GITLAB_ADMIN_PASSWORD: "${REVIEW_APPS_ROOT_PASSWORD}"
- GITHUB_ACCESS_TOKEN: "${REVIEW_APPS_QA_GITHUB_ACCESS_TOKEN}"
- EE_LICENSE: "${REVIEW_APPS_EE_LICENSE}"
- before_script:
- - export QA_IMAGE="${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_COMMIT_REF_SLUG}"
- - export CI_ENVIRONMENT_URL="$(cat environment_url.txt)"
- - echo "${CI_ENVIRONMENT_URL}"
- - echo "${QA_IMAGE}"
- - source scripts/utils.sh
- - install_api_client_dependencies_with_apk
- - gem install gitlab-qa --no-document ${GITLAB_QA_VERSION:+ --version ${GITLAB_QA_VERSION}}
- artifacts:
- paths:
- - ./qa/gitlab-qa-run-*
- expire_in: 7 days
- when: always
-
-review-qa-smoke:
- extends:
- - .review-qa-base
- - .review:rules:review-qa-smoke
- script:
- - gitlab-qa Test::Instance::Smoke "${QA_IMAGE}" "${CI_ENVIRONMENT_URL}"
-
-review-qa-all:
- extends:
- - .review-qa-base
- - .review:rules:mr-only-manual
- parallel: 5
- script:
- - export KNAPSACK_REPORT_PATH=knapsack/master_report.json
- - export KNAPSACK_TEST_FILE_PATTERN=qa/specs/features/**/*_spec.rb
- - gitlab-qa Test::Instance::Any "${QA_IMAGE}" "${CI_ENVIRONMENT_URL}" -- --format RspecJunitFormatter --out tmp/rspec-${CI_JOB_ID}.xml --format html --out tmp/rspec.htm --color --format documentation
-
-review-performance:
- extends:
- - .default-retry
- - .review:rules:mr-and-schedule-auto-if-frontend-manual-otherwise
- image:
- name: sitespeedio/sitespeed.io:6.3.1
- entrypoint: [""]
- stage: qa
- # This is needed so that manual jobs with needs don't block the pipeline.
- # See https://gitlab.com/gitlab-org/gitlab/-/issues/199979.
- dependencies: ["review-deploy"]
- before_script:
- - export CI_ENVIRONMENT_URL="$(cat environment_url.txt)"
- - echo "${CI_ENVIRONMENT_URL}"
- - mkdir -p gitlab-exporter
- - wget -O ./gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/master/index.js
- - mkdir -p sitespeed-results
- script:
- - /start.sh --plugins.add ./gitlab-exporter --outputFolder sitespeed-results "${CI_ENVIRONMENT_URL}"
- after_script:
- - mv sitespeed-results/data/performance.json performance.json
- artifacts:
- paths:
- - sitespeed-results/
- reports:
- performance: performance.json
- expire_in: 31d
-
-parallel-spec-reports:
- extends:
- - .review:rules:mr-only-manual
- image: ruby:2.6-alpine
- stage: post-qa
- dependencies: ["review-qa-all"]
- variables:
- NEW_PARALLEL_SPECS_REPORT: qa/report-new.html
- BASE_ARTIFACT_URL: "${CI_PROJECT_URL}/-/jobs/${CI_JOB_ID}/artifacts/file/qa/"
- script:
- - apk add --update build-base libxml2-dev libxslt-dev && rm -rf /var/cache/apk/*
- - gem install nokogiri --no-document
- - cd qa/gitlab-qa-run-*/gitlab-*
- - ARTIFACT_DIRS=$(pwd |rev| awk -F / '{print $1,$2}' | rev | sed s_\ _/_)
- - cd -
- - '[[ -f $NEW_PARALLEL_SPECS_REPORT ]] || echo "{}" > ${NEW_PARALLEL_SPECS_REPORT}'
- - scripts/merge-html-reports ${NEW_PARALLEL_SPECS_REPORT} ${BASE_ARTIFACT_URL}${ARTIFACT_DIRS} qa/gitlab-qa-run-*/**/rspec.htm
- artifacts:
- when: always
- paths:
- - qa/report-new.html
- - qa/gitlab-qa-run-*
- reports:
- junit: qa/gitlab-qa-run-*/**/rspec-*.xml
- expire_in: 31d
+# Temporarily disabling review apps
+#.review-qa-base:
+# extends:
+# - .default-retry
+# - .use-docker-in-docker
+# image: registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-qa-alpine-ruby-2.6
+# stage: qa
+# # This is needed so that manual jobs with needs don't block the pipeline.
+# # See https://gitlab.com/gitlab-org/gitlab/-/issues/199979.
+# dependencies: ["review-deploy"]
+# variables:
+# QA_ARTIFACTS_DIR: "${CI_PROJECT_DIR}/qa"
+# QA_CAN_TEST_GIT_PROTOCOL_V2: "false"
+# QA_DEBUG: "true"
+# GITLAB_USERNAME: "root"
+# GITLAB_PASSWORD: "${REVIEW_APPS_ROOT_PASSWORD}"
+# GITLAB_ADMIN_USERNAME: "root"
+# GITLAB_ADMIN_PASSWORD: "${REVIEW_APPS_ROOT_PASSWORD}"
+# GITHUB_ACCESS_TOKEN: "${REVIEW_APPS_QA_GITHUB_ACCESS_TOKEN}"
+# EE_LICENSE: "${REVIEW_APPS_EE_LICENSE}"
+# before_script:
+# - export QA_IMAGE="${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_COMMIT_REF_SLUG}"
+# - export CI_ENVIRONMENT_URL="$(cat environment_url.txt)"
+# - echo "${CI_ENVIRONMENT_URL}"
+# - echo "${QA_IMAGE}"
+# - source scripts/utils.sh
+# - install_api_client_dependencies_with_apk
+# - gem install gitlab-qa --no-document ${GITLAB_QA_VERSION:+ --version ${GITLAB_QA_VERSION}}
+# artifacts:
+# paths:
+# - ./qa/gitlab-qa-run-*
+# expire_in: 7 days
+# when: always
+#
+#review-qa-smoke:
+# extends:
+# - .review-qa-base
+# - .review:rules:review-qa-smoke
+# script:
+# - gitlab-qa Test::Instance::Smoke "${QA_IMAGE}" "${CI_ENVIRONMENT_URL}"
+#
+#review-qa-all:
+# extends:
+# - .review-qa-base
+# - .review:rules:mr-only-manual
+# parallel: 5
+# script:
+# - export KNAPSACK_REPORT_PATH=knapsack/master_report.json
+# - export KNAPSACK_TEST_FILE_PATTERN=qa/specs/features/**/*_spec.rb
+# - gitlab-qa Test::Instance::Any "${QA_IMAGE}" "${CI_ENVIRONMENT_URL}" -- --format RspecJunitFormatter --out tmp/rspec-${CI_JOB_ID}.xml --format html --out tmp/rspec.htm --color --format documentation
+#
+#review-performance:
+# extends:
+# - .default-retry
+# - .review:rules:mr-and-schedule-auto-if-frontend-manual-otherwise
+# image:
+# name: sitespeedio/sitespeed.io:6.3.1
+# entrypoint: [""]
+# stage: qa
+# # This is needed so that manual jobs with needs don't block the pipeline.
+# # See https://gitlab.com/gitlab-org/gitlab/-/issues/199979.
+# dependencies: ["review-deploy"]
+# before_script:
+# - export CI_ENVIRONMENT_URL="$(cat environment_url.txt)"
+# - echo "${CI_ENVIRONMENT_URL}"
+# - mkdir -p gitlab-exporter
+# - wget -O ./gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/master/index.js
+# - mkdir -p sitespeed-results
+# script:
+# - /start.sh --plugins.add ./gitlab-exporter --outputFolder sitespeed-results "${CI_ENVIRONMENT_URL}"
+# after_script:
+# - mv sitespeed-results/data/performance.json performance.json
+# artifacts:
+# paths:
+# - sitespeed-results/
+# reports:
+# performance: performance.json
+# expire_in: 31d
+#
+#parallel-spec-reports:
+# extends:
+# - .review:rules:mr-only-manual
+# image: ruby:2.6-alpine
+# stage: post-qa
+# dependencies: ["review-qa-all"]
+# variables:
+# NEW_PARALLEL_SPECS_REPORT: qa/report-new.html
+# BASE_ARTIFACT_URL: "${CI_PROJECT_URL}/-/jobs/${CI_JOB_ID}/artifacts/file/qa/"
+# script:
+# - apk add --update build-base libxml2-dev libxslt-dev && rm -rf /var/cache/apk/*
+# - gem install nokogiri --no-document
+# - cd qa/gitlab-qa-run-*/gitlab-*
+# - ARTIFACT_DIRS=$(pwd |rev| awk -F / '{print $1,$2}' | rev | sed s_\ _/_)
+# - cd -
+# - '[[ -f $NEW_PARALLEL_SPECS_REPORT ]] || echo "{}" > ${NEW_PARALLEL_SPECS_REPORT}'
+# - scripts/merge-html-reports ${NEW_PARALLEL_SPECS_REPORT} ${BASE_ARTIFACT_URL}${ARTIFACT_DIRS} qa/gitlab-qa-run-*/**/rspec.htm
+# artifacts:
+# when: always
+# paths:
+# - qa/report-new.html
+# - qa/gitlab-qa-run-*
+# reports:
+# junit: qa/gitlab-qa-run-*/**/rspec-*.xml
+# expire_in: 31d
danger-review:
extends:
@@ -238,5 +241,3 @@ danger-review:
- source scripts/utils.sh
- retry yarn install --frozen-lockfile
- danger --fail-on-errors=true --verbose
- cache:
- policy: pull
diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml
index 383aca0043b..fbbb0391ec5 100644
--- a/.gitlab/ci/rules.gitlab-ci.yml
+++ b/.gitlab/ci/rules.gitlab-ci.yml
@@ -37,6 +37,9 @@
.if-merge-request-title-as-if-foss: &if-merge-request-title-as-if-foss
if: '$CI_MERGE_REQUEST_TITLE =~ /RUN AS-IF-FOSS/'
+.if-merge-request-title-update-caches: &if-merge-request-title-update-caches
+ if: '$CI_MERGE_REQUEST_TITLE =~ /UPDATE CACHE/'
+
.if-security-merge-request: &if-security-merge-request
if: '$CI_PROJECT_NAMESPACE == "gitlab-org/security" && $CI_MERGE_REQUEST_IID'
@@ -49,6 +52,9 @@
.if-dot-com-gitlab-org-merge-request: &if-dot-com-gitlab-org-merge-request
if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE == "gitlab-org" && $CI_MERGE_REQUEST_IID'
+.if-dot-com-gitlab-org-and-security-merge-request: &if-dot-com-gitlab-org-and-security-merge-request
+ if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE =~ /^gitlab-org($|\/security$)/ && $CI_MERGE_REQUEST_IID'
+
.if-dot-com-gitlab-org-and-security-tag: &if-dot-com-gitlab-org-and-security-tag
if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE =~ /^gitlab-org($|\/security$)/ && $CI_COMMIT_TAG'
@@ -78,9 +84,11 @@
.frontend-patterns: &frontend-patterns
- "{package.json,yarn.lock}"
- - "{babel.config,jest.config}.js"
+ - "babel.config.js"
+ - "jest.config.{base,integration,unit}.js"
- ".csscomb.json"
- "Dockerfile.assets"
+ - "config/**/*.js"
- "vendor/assets/**/*"
- "{,ee/}{app/assets,app/helpers,app/presenters,app/views,locale,public,symbol}/**/*"
@@ -93,7 +101,8 @@
.code-patterns: &code-patterns
- "{package.json,yarn.lock}"
- - "{babel.config,jest.config}.js"
+ - "babel.config.js"
+ - "jest.config.{base,integration,unit}.js"
- ".csscomb.json"
- "Dockerfile.assets"
- "vendor/assets/**/*"
@@ -113,7 +122,8 @@
.code-backstage-patterns: &code-backstage-patterns
- "{package.json,yarn.lock}"
- - "{babel.config,jest.config}.js"
+ - "babel.config.js"
+ - "jest.config.{base,integration,unit}.js"
- ".csscomb.json"
- "Dockerfile.assets"
- "vendor/assets/**/*"
@@ -135,7 +145,8 @@
.code-qa-patterns: &code-qa-patterns
- "{package.json,yarn.lock}"
- - "{babel.config,jest.config}.js"
+ - "babel.config.js"
+ - "jest.config.{base,integration,unit}.js"
- ".csscomb.json"
- "Dockerfile.assets"
- "vendor/assets/**/*"
@@ -154,7 +165,8 @@
.code-backstage-qa-patterns: &code-backstage-qa-patterns
- "{package.json,yarn.lock}"
- - "{babel.config,jest.config}.js"
+ - "babel.config.js"
+ - "jest.config.{base,integration,unit}.js"
- ".csscomb.json"
- "Dockerfile.assets"
- "vendor/assets/**/*"
@@ -177,6 +189,14 @@
- ".dockerignore"
- "qa/**/*"
+################
+# Shared rules #
+################
+.shared:rules:update-cache:
+ rules:
+ - <<: *if-master-schedule-2-hourly
+ - <<: *if-merge-request-title-update-caches
+
####################
# Cache repo rules #
####################
@@ -238,51 +258,21 @@
##################
# Frontend rules #
##################
-# This job only runs on `master` since it pushes to the cache.
-.frontend:rules:gitlab-assets-compile-pull-push-cache:
- rules:
- - <<: *if-not-canonical-namespace
- when: never
- - <<: *if-master-refs
- changes: *code-backstage-qa-patterns
- when: on_success
-
-.frontend:rules:gitlab-assets-compile-pull-cache:
+.frontend:rules:compile-production-assets:
rules:
- <<: *if-not-canonical-namespace
when: never
- <<: *if-default-refs
changes: *code-backstage-qa-patterns
- when: on_success
-.frontend:rules:compile-assets-pull-push-cache:
+.frontend:rules:compile-test-assets:
rules:
- - <<: *if-master-refs
- changes: *code-backstage-qa-patterns
- when: on_success
-
-# This job only runs on `master` since it pushes to the cache.
-.frontend:rules:compile-assets-pull-push-cache-as-if-foss:
- rules:
- - <<: *if-not-ee
- when: never
- - <<: *if-master-push
- changes: *code-backstage-qa-patterns
- - <<: *if-master-schedule-2-hourly
-
-.frontend:rules:compile-assets-pull-cache:
- rules:
- - <<: *if-default-refs
- changes: *code-backstage-qa-patterns
- when: on_success
+ - changes: *code-backstage-qa-patterns
-.frontend:rules:compile-assets-pull-cache-as-if-foss:
+.frontend:rules:compile-test-assets-as-if-foss:
rules:
- <<: *if-not-ee
when: never
- - <<: *if-master-push
- changes: *code-backstage-qa-patterns
- - <<: *if-master-schedule-2-hourly
- <<: *if-security-merge-request
changes: *code-backstage-qa-patterns
- <<: *if-merge-request-title-as-if-foss
@@ -293,15 +283,11 @@
rules:
- <<: *if-default-refs
changes: *code-backstage-patterns
- when: on_success
.frontend:rules:default-frontend-jobs-as-if-foss:
rules:
- <<: *if-not-ee
when: never
- - <<: *if-master-push
- changes: *code-backstage-patterns
- - <<: *if-master-schedule-2-hourly
- <<: *if-security-merge-request
changes: *code-backstage-patterns
- <<: *if-merge-request-title-as-if-foss
@@ -321,10 +307,8 @@
rules:
- <<: *if-master-refs
changes: *frontend-dependency-patterns
- when: on_success
- <<: *if-merge-request
changes: *frontend-dependency-patterns
- when: on_success
.frontend:rules:qa-frontend-node-latest:
rules:
@@ -335,6 +319,12 @@
changes: *frontend-dependency-patterns
allow_failure: true
+.frontend:rules:bundle-size-review:
+ rules:
+ - if: '$DANGER_GITLAB_API_TOKEN && $CI_MERGE_REQUEST_IID && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"'
+ changes: *frontend-patterns
+ allow_failure: true
+
################
# Memory rules #
################
@@ -368,9 +358,6 @@
rules:
- <<: *if-not-ee
when: never
- - <<: *if-master-push
- changes: *code-qa-patterns
- - <<: *if-master-schedule-2-hourly
- <<: *if-security-merge-request
changes: *code-qa-patterns
- <<: *if-merge-request-title-as-if-foss
@@ -379,13 +366,13 @@
.qa:rules:package-and-qa:
rules:
- - <<: *if-dot-com-gitlab-org-merge-request
+ - <<: *if-dot-com-gitlab-org-and-security-merge-request
changes: *ci-patterns
allow_failure: true
- - <<: *if-dot-com-gitlab-org-merge-request
+ - <<: *if-dot-com-gitlab-org-and-security-merge-request
changes: *qa-patterns
allow_failure: true
- - <<: *if-dot-com-gitlab-org-merge-request
+ - <<: *if-dot-com-gitlab-org-and-security-merge-request
changes: *code-patterns
when: manual
allow_failure: true
@@ -416,9 +403,6 @@
rules:
- <<: *if-not-ee
when: never
- - <<: *if-master-push
- changes: *code-backstage-patterns
- - <<: *if-master-schedule-2-hourly
- <<: *if-security-merge-request
changes: *code-backstage-patterns
- <<: *if-merge-request-title-as-if-foss
@@ -434,6 +418,17 @@
- <<: *if-master-refs
changes: *code-backstage-patterns
+.rails:rules:ee-mr-only:
+ rules:
+ - <<: *if-not-ee
+ when: never
+ - <<: *if-merge-request-title-as-if-foss
+ when: never
+ - <<: *if-security-merge-request
+ changes: *code-backstage-patterns
+ - <<: *if-dot-com-gitlab-org-merge-request
+ changes: *code-backstage-patterns
+
.rails:rules:downtime_check:
rules:
- <<: *if-merge-request
@@ -505,7 +500,7 @@
rules:
- <<: *if-not-ee
when: never
- - <<: *if-dot-com-gitlab-org-merge-request
+ - <<: *if-dot-com-gitlab-org-and-security-merge-request
changes: *code-qa-patterns
- <<: *if-dot-com-gitlab-org-schedule
diff --git a/.gitlab/ci/setup.gitlab-ci.yml b/.gitlab/ci/setup.gitlab-ci.yml
index 9be495f1ef2..b878bec3751 100644
--- a/.gitlab/ci/setup.gitlab-ci.yml
+++ b/.gitlab/ci/setup.gitlab-ci.yml
@@ -3,7 +3,7 @@
cache gems:
extends:
- .default-retry
- - .default-cache
+ - .rails-cache
- .default-before_script
- .setup:rules:cache-gems
stage: test
diff --git a/.gitlab/ci/test-metadata.gitlab-ci.yml b/.gitlab/ci/test-metadata.gitlab-ci.yml
index 65cce76fc48..1764e9136a1 100644
--- a/.gitlab/ci/test-metadata.gitlab-ci.yml
+++ b/.gitlab/ci/test-metadata.gitlab-ci.yml
@@ -3,11 +3,6 @@
TESTS_METADATA_S3_BUCKET: "gitlab-ce-cache"
before_script:
- source scripts/utils.sh
- cache:
- key: tests_metadata
- paths:
- - knapsack/
- - rspec_flaky/
artifacts:
expire_in: 31d
paths:
@@ -20,8 +15,6 @@ retrieve-tests-metadata:
- .tests-metadata-state
- .test-metadata:rules:retrieve-tests-metadata
stage: prepare
- cache:
- policy: pull
script:
- source scripts/rspec_helpers.sh
- retrieve_tests_metadata
@@ -44,8 +37,6 @@ update-tests-metadata:
- rspec-ee unit pg11 geo
- rspec-ee integration pg11 geo
- rspec-ee system pg11 geo
- cache:
- policy: push
script:
- retry gem install fog-aws mime-types activesupport rspec_profiling postgres-copy --no-document
- source scripts/rspec_helpers.sh
diff --git a/.gitlab/issue_templates/Acceptance_Testing.md b/.gitlab/issue_templates/Acceptance Testing.md
index 5a6c35f28ad..5a6c35f28ad 100644
--- a/.gitlab/issue_templates/Acceptance_Testing.md
+++ b/.gitlab/issue_templates/Acceptance Testing.md
diff --git a/.gitlab/issue_templates/Problem_Validation.md b/.gitlab/issue_templates/Problem Validation.md
index f7515c07218..f7515c07218 100644
--- a/.gitlab/issue_templates/Problem_Validation.md
+++ b/.gitlab/issue_templates/Problem Validation.md
diff --git a/.gitlab/issue_templates/QA failure.md b/.gitlab/issue_templates/QA Failure.md
index 2a8b1b2d2f9..2a8b1b2d2f9 100644
--- a/.gitlab/issue_templates/QA failure.md
+++ b/.gitlab/issue_templates/QA Failure.md
diff --git a/.gitlab/issue_templates/Solution_validation b/.gitlab/issue_templates/Solution Validation.md
index 27f97d8dd12..27f97d8dd12 100644
--- a/.gitlab/issue_templates/Solution_validation
+++ b/.gitlab/issue_templates/Solution Validation.md
diff --git a/.gitlab/issue_templates/Test plan.md b/.gitlab/issue_templates/Test Plan.md
index a202c0bf546..a202c0bf546 100644
--- a/.gitlab/issue_templates/Test plan.md
+++ b/.gitlab/issue_templates/Test Plan.md
diff --git a/.gitlab/merge_request_templates/Change documentation location.md b/.gitlab/merge_request_templates/Change Documentation Location.md
index f18957fdaaa..f18957fdaaa 100644
--- a/.gitlab/merge_request_templates/Change documentation location.md
+++ b/.gitlab/merge_request_templates/Change Documentation Location.md
diff --git a/.gitlab/merge_request_templates/Documentation.md b/.gitlab/merge_request_templates/Documentation.md
index 72bfd2cdec4..282e80d700a 100644
--- a/.gitlab/merge_request_templates/Documentation.md
+++ b/.gitlab/merge_request_templates/Documentation.md
@@ -24,6 +24,8 @@
- ~"development guidelines" and ~"Description templates (.gitlab/\*)" when creating/updating issue and MR description templates.
- [ ] Assign the [designated Technical Writer](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments).
+Do not add the ~"feature", ~"frontend", ~"backend", ~"bug", or ~"database" labels if you are only updating documentation. These labels will cause the MR to be added to code verification QA issues.
+
When applicable:
- [ ] Update the [permissions table](https://docs.gitlab.com/ee/user/permissions.html).
diff --git a/.gitlab/merge_request_templates/New static analysis check.md b/.gitlab/merge_request_templates/New Static Analysis Check.md
index 8bbb3effb1c..8bbb3effb1c 100644
--- a/.gitlab/merge_request_templates/New static analysis check.md
+++ b/.gitlab/merge_request_templates/New Static Analysis Check.md
diff --git a/.haml-lint.yml b/.haml-lint.yml
index 399fa9656a0..33a960f7efe 100644
--- a/.haml-lint.yml
+++ b/.haml-lint.yml
@@ -80,8 +80,8 @@ linters:
ignored_cops:
- Layout/BlockAlignment
- Layout/EndAlignment
+ - Layout/LineLength
- Lint/Void
- - Metrics/LineLength
- Naming/FileName
- Style/AlignParameters
- Style/BlockNesting
@@ -92,7 +92,6 @@ linters:
- Style/IfUnlessModifier
- Style/IndentationWidth
- Style/Next
- - Style/TrailingBlankLines
- Style/TrailingWhitespace
- Style/WhileUntilModifier
@@ -112,7 +111,7 @@ linters:
- Layout/SpaceInsideArrayLiteralBrackets
- Layout/SpaceInsideHashLiteralBraces
- Layout/SpaceInsideStringInterpolation
- - Layout/TrailingBlankLines
+ - Layout/TrailingEmptyLines
- Lint/BooleanSymbol
- Lint/LiteralInInterpolation
- Lint/ParenthesesAsGroupedExpression
diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml
index a79bba24edb..5bd7dc18831 100644
--- a/.haml-lint_todo.yml
+++ b/.haml-lint_todo.yml
@@ -1,6 +1,6 @@
# This configuration was generated by
# `haml-lint --auto-gen-config`
-# on 2020-04-20 07:11:26 +0000 using Haml-Lint version 0.34.0.
+# on 2020-05-21 10:58:59 -0400 using Haml-Lint version 0.34.0.
# The point is for the user to remove these configuration records
# one by one as the lints are removed from the code base.
# Note that changes in the inspected code, or installation of new
@@ -162,7 +162,6 @@ linters:
- "app/views/projects/_home_panel.html.haml"
- "app/views/projects/_import_project_pane.html.haml"
- "app/views/projects/_issuable_by_email.html.haml"
- - "app/views/projects/_md_preview.html.haml"
- "app/views/projects/_readme.html.haml"
- "app/views/projects/artifacts/_artifact.html.haml"
- "app/views/projects/artifacts/_tree_file.html.haml"
@@ -267,7 +266,6 @@ linters:
- "app/views/projects/triggers/_index.html.haml"
- "app/views/projects/triggers/_trigger.html.haml"
- "app/views/projects/triggers/edit.html.haml"
- - "app/views/projects/wikis/_pages_wiki_page.html.haml"
- "app/views/search/results/_issue.html.haml"
- "app/views/search/results/_note.html.haml"
- "app/views/search/results/_snippet_blob.html.haml"
@@ -277,6 +275,7 @@ linters:
- "app/views/shared/_delete_label_modal.html.haml"
- "app/views/shared/_group_form.html.haml"
- "app/views/shared/_group_tips.html.haml"
+ - "app/views/shared/_md_preview.html.haml"
- "app/views/shared/_milestone_expired.html.haml"
- "app/views/shared/_no_password.html.haml"
- "app/views/shared/_ping_consent.html.haml"
@@ -313,6 +312,7 @@ linters:
- "app/views/shared/snippets/_snippet.html.haml"
- "app/views/shared/web_hooks/_form.html.haml"
- "app/views/shared/web_hooks/_hook.html.haml"
+ - "app/views/shared/wikis/_pages_wiki_page.html.haml"
- "app/views/u2f/_authenticate.html.haml"
- "app/views/u2f/_register.html.haml"
- "app/views/users/_deletion_guidance.html.haml"
@@ -324,7 +324,6 @@ linters:
- "ee/app/views/admin/geo/projects/_registry_never.html.haml"
- "ee/app/views/admin/licenses/_upload_trial_license.html.haml"
- "ee/app/views/admin/licenses/new.html.haml"
- - "ee/app/views/admin/licenses/show.html.haml"
- "ee/app/views/admin/monitoring/ee/_nav.html.haml"
- "ee/app/views/admin/projects/_shared_runner_status.html.haml"
- "ee/app/views/admin/users/_auditor_access_level_radio.html.haml"
diff --git a/.markdownlint.json b/.markdownlint.json
index 88e3d5f7759..b4da68989f3 100644
--- a/.markdownlint.json
+++ b/.markdownlint.json
@@ -43,8 +43,10 @@
"Consul",
"Debian",
"DevOps",
+ "Docker",
"Elasticsearch",
"Facebook",
+ "fastlane",
"GDK",
"Geo",
"Git LFS",
@@ -101,6 +103,7 @@
"OpenShift",
"PgBouncer",
"PostgreSQL",
+ "Praefect",
"Prometheus",
"Puma",
"puma-worker-killer",
diff --git a/.rubocop.yml b/.rubocop.yml
index 3d013a650e7..ed17799478a 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -2,18 +2,21 @@ inherit_gem:
gitlab-styles:
- rubocop-default.yml
-inherit_from: .rubocop_todo.yml
require:
- ./rubocop/rubocop
- rubocop-rspec
+inherit_from:
+ - .rubocop_todo.yml
+ - ./rubocop/rubocop-migrations.yml
+
inherit_mode:
merge:
- Include
AllCops:
TargetRubyVersion: 2.6
- TargetRailsVersion: 5.0
+ TargetRailsVersion: 6.0
Exclude:
- 'vendor/**/*'
- 'node_modules/**/*'
@@ -27,6 +30,7 @@ AllCops:
- 'plugins/**/*'
- 'file_hooks/**/*'
CacheRootDirectory: tmp
+ MaxFilesInCache: 18000
Cop/AvoidKeywordArgumentsInSidekiqWorkers:
Enabled: true
@@ -178,6 +182,9 @@ Rails/ApplicationRecord:
- ee/db/**/*.rb
- ee/spec/**/*.rb
+Cop/DefaultScope:
+ Enabled: true
+
Rails/FindBy:
Enabled: true
Include:
@@ -186,6 +193,14 @@ Rails/FindBy:
- 'spec/**/*.rb'
- 'ee/spec/**/*.rb'
+# This is currently exiting with a rubocop exception error and should be
+# resolved hopefully a future update
+# An error occurred while Rails/UniqueValidationWithoutIndex cop was inspecting
+# app/models/abuse_report.rb:15:2.
+# To see the complete backtrace run rubocop -d.
+Rails/UniqueValidationWithoutIndex:
+ Enabled: false
+
# GitLab ###################################################################
Gitlab/ModuleWithInstanceVariables:
@@ -225,6 +240,7 @@ Gitlab/Json:
- 'scripts/**/*'
- 'lib/rspec_flaky/**/*'
- 'lib/quality/**/*'
+ - 'lib/gitlab/danger/**/*'
GitlabSecurity/PublicSend:
Enabled: true
@@ -240,10 +256,7 @@ GitlabSecurity/PublicSend:
- 'ee/spec/**/*'
Gitlab/DuplicateSpecLocation:
- Exclude:
- - ee/spec/lib/gitlab/gl_repository_spec.rb
- - ee/spec/services/merge_requests/refresh_service_spec.rb
- - ee/spec/services/ee/merge_requests/refresh_service_spec.rb
+ Enabled: true
Cop/InjectEnterpriseEditionModule:
Enabled: true
@@ -259,12 +272,15 @@ Style/ReturnNil:
Performance/RegexpMatch:
Enabled: false
-ActiveRecordAssociationReload:
+Cop/ActiveRecordAssociationReload:
Enabled: true
Exclude:
- 'spec/**/*'
- 'ee/spec/**/*'
+Gitlab/AvoidFeatureGet:
+ Enabled: true
+
Naming/PredicateName:
Enabled: true
Exclude:
@@ -349,39 +365,17 @@ RSpec/LeakyConstantDeclaration:
Exclude:
- 'spec/db/schema_spec.rb'
- 'spec/lib/feature_spec.rb'
- - 'spec/lib/gitlab/ci/build/credentials/factory_spec.rb'
- - 'spec/lib/gitlab/ci/config/entry/retry_spec.rb'
- - 'spec/lib/gitlab/cluster/mixins/puma_cluster_spec.rb'
- - 'spec/lib/gitlab/cluster/mixins/unicorn_http_server_spec.rb'
- - 'spec/lib/gitlab/config/entry/factory_spec.rb'
- 'spec/lib/gitlab/config/entry/simplifiable_spec.rb'
- - 'spec/lib/gitlab/database/migration_helpers_spec.rb'
- - 'spec/lib/gitlab/database/obsolete_ignored_columns_spec.rb'
- - 'spec/lib/gitlab/database/with_lock_retries_spec.rb'
- - 'spec/lib/gitlab/git/diff_collection_spec.rb'
- - 'spec/lib/gitlab/import_export/import_test_coverage_spec.rb'
- - 'spec/lib/gitlab/import_export/project/relation_factory_spec.rb'
- - 'spec/lib/gitlab/jira_import/issues_importer_spec.rb'
- - 'spec/lib/gitlab/no_cache_headers_spec.rb'
- - 'spec/lib/gitlab/path_regex_spec.rb'
- 'spec/lib/gitlab/quick_actions/dsl_spec.rb'
- - 'spec/lib/gitlab/sidekiq_middleware/client_metrics_spec.rb'
- - 'spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb'
- 'spec/lib/marginalia_spec.rb'
- 'spec/mailers/notify_spec.rb'
- - 'spec/migrations/20191125114345_add_admin_mode_protected_path_spec.rb'
- 'spec/models/concerns/batch_destroy_dependent_associations_spec.rb'
- 'spec/models/concerns/bulk_insert_safe_spec.rb'
- 'spec/models/concerns/bulk_insertable_associations_spec.rb'
- 'spec/models/concerns/triggerable_hooks_spec.rb'
- 'spec/models/repository_spec.rb'
- - 'spec/requests/api/graphql/tasks/task_completion_status_spec.rb'
- - 'spec/serializers/commit_entity_spec.rb'
- 'spec/services/clusters/applications/check_installation_progress_service_spec.rb'
- - 'spec/services/clusters/applications/check_uninstall_progress_service_spec.rb'
- - 'spec/support/shared_contexts/spam_constants.rb'
- 'spec/support/shared_examples/quick_actions/issuable/issuable_quick_actions_shared_examples.rb'
- - 'spec/support_specs/matchers/exceed_query_limit_helpers_spec.rb'
RSpec/EmptyLineAfterHook:
Enabled: false
@@ -452,4 +446,16 @@ Rails/TimeZone:
- 'ee/app/services/**/*'
- 'ee/spec/controllers/**/*'
- 'ee/spec/services/**/*'
+ - 'app/models/**/*'
+ - 'spec/models/**/*'
+ - 'ee/app/models/**/*'
+ - 'ee/spec/models/**/*'
+# WIP: See https://gitlab.com/gitlab-org/gitlab/-/issues/220040
+Rails/SaveBang:
+ Enabled: true
+ Include:
+ - 'spec/**/*.rb'
+ - 'ee/spec/**/*.rb'
+ - 'qa/spec/**/*.rb'
+ - 'qa/qa/specs/**/*.rb'
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index bd0f9184cd6..9e3a54fa7e9 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -1,30 +1,21 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
-# on 2020-01-16 11:53:06 -0800 using RuboCop version 0.74.0.
+# on 2020-05-20 16:32:14 -0400 using RuboCop version 0.82.0.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
-# Offense count: 299
+# Offense count: 308
# Cop supports --auto-correct.
Capybara/CurrentPathExpectation:
Enabled: false
-# Offense count: 1432
+# Offense count: 1715
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: with_first_argument, with_fixed_indentation
-Layout/AlignArguments:
- Enabled: false
-
-# Offense count: 1630
-# Cop supports --auto-correct.
-# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
-# SupportedHashRocketStyles: key, separator, table
-# SupportedColonStyles: key, separator, table
-# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
-Layout/AlignHash:
+Layout/ArgumentAlignment:
Enabled: false
# Offense count: 13
@@ -41,7 +32,7 @@ Layout/ClosingHeredocIndentation:
- 'spec/rubocop/cop/active_record_association_reload_spec.rb'
- 'spec/services/task_list_toggle_service_spec.rb'
-# Offense count: 9
+# Offense count: 13
# Cop supports --auto-correct.
Layout/ClosingParenthesisIndentation:
Exclude:
@@ -52,7 +43,7 @@ Layout/ClosingParenthesisIndentation:
- 'spec/support/helpers/stub_object_storage.rb'
- 'spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb'
-# Offense count: 69
+# Offense count: 72
# Cop supports --auto-correct.
Layout/EmptyLinesAroundArguments:
Exclude:
@@ -60,46 +51,61 @@ Layout/EmptyLinesAroundArguments:
- 'app/models/concerns/resolvable_discussion.rb'
- 'app/models/diff_discussion.rb'
- 'app/models/discussion.rb'
- - 'ee/app/helpers/license_helper.rb'
- 'ee/spec/models/geo/project_registry_spec.rb'
- 'lib/banzai/pipeline/broadcast_message_pipeline.rb'
- 'lib/banzai/pipeline/gfm_pipeline.rb'
- 'lib/banzai/pipeline/single_line_pipeline.rb'
- 'spec/features/markdown/copy_as_gfm_spec.rb'
-# Offense count: 305
+# Offense count: 413
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: special_inside_parentheses, consistent, align_brackets
-Layout/IndentFirstArrayElement:
+Layout/FirstArrayElementIndentation:
Enabled: false
-# Offense count: 1005
+# Offense count: 1218
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: special_inside_parentheses, consistent, align_braces
-Layout/IndentFirstHashElement:
+Layout/FirstHashElementIndentation:
Enabled: false
# Offense count: 4
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: consistent, align_parentheses
-Layout/IndentFirstParameter:
+Layout/FirstParameterIndentation:
Exclude:
- 'lib/gitlab/cross_project_access.rb'
- 'lib/gitlab/data_builder/push.rb'
- 'spec/support/helpers/repo_helpers.rb'
- 'spec/support/helpers/stub_object_storage.rb'
-# Offense count: 54
+# Offense count: 2164
+# Cop supports --auto-correct.
+# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
+# SupportedHashRocketStyles: key, separator, table
+# SupportedColonStyles: key, separator, table
+# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
+Layout/HashAlignment:
+ Enabled: false
+
+# Offense count: 9396
+# Cop supports --auto-correct.
+# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
+# URISchemes: http, https
+Layout/LineLength:
+ Max: 1313
+
+# Offense count: 94
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: aligned, indented
Layout/MultilineOperationIndentation:
Enabled: false
-# Offense count: 10
+# Offense count: 9
# Cop supports --auto-correct.
Layout/RescueEnsureAlignment:
Exclude:
@@ -107,21 +113,33 @@ Layout/RescueEnsureAlignment:
- 'app/models/project.rb'
- 'app/services/prometheus/proxy_service.rb'
- 'app/workers/delete_stored_files_worker.rb'
- - 'app/workers/reactive_caching_worker.rb'
- 'config/initializers/1_settings.rb'
- 'config/initializers/trusted_proxies.rb'
- 'lib/gitlab/background_migration/archive_legacy_traces.rb'
- 'lib/gitlab/highlight.rb'
- 'lib/tasks/gitlab/lfs/migrate.rake'
-# Offense count: 522
+# Offense count: 36
+# Cop supports --auto-correct.
+Layout/SpaceAroundMethodCallOperator:
+ Enabled: false
+
+# Offense count: 2
+# Cop supports --auto-correct.
+# Configuration parameters: AllowForAlignment.
+Layout/SpaceBeforeFirstArg:
+ Exclude:
+ - 'spec/requests/api/runner_spec.rb'
+ - 'spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb'
+
+# Offense count: 642
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: require_no_space, require_space
Layout/SpaceInLambdaLiteral:
Enabled: false
-# Offense count: 796
+# Offense count: 926
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters.
# SupportedStyles: space, no_space
@@ -129,7 +147,7 @@ Layout/SpaceInLambdaLiteral:
Layout/SpaceInsideBlockBraces:
Enabled: false
-# Offense count: 315
+# Offense count: 401
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: space, no_space
@@ -153,12 +171,47 @@ Lint/DuplicateMethods:
- 'lib/gitlab/git/tree.rb'
- 'lib/gitlab/git/wiki_page.rb'
-# Offense count: 122
+# Offense count: 157
# Configuration parameters: MaximumRangeSize.
Lint/MissingCopEnableDirective:
Enabled: false
-# Offense count: 6
+# Offense count: 11
+# Cop supports --auto-correct.
+Lint/NonDeterministicRequireOrder:
+ Exclude:
+ - 'ee/spec/spec_helper.rb'
+ - 'qa/spec/spec_helper.rb'
+ - 'spec/spec_helper.rb'
+
+# Offense count: 3
+# Configuration parameters: AllowedImplicitNamespaces.
+# AllowedImplicitNamespaces: Gem
+Lint/RaiseException:
+ Exclude:
+ - 'db/migrate/20190402150158_backport_enterprise_schema.rb'
+ - 'ee/spec/requests/api/helpers_spec.rb'
+ - 'spec/requests/api/helpers_spec.rb'
+
+# Offense count: 27
+# Cop supports --auto-correct.
+Lint/RedundantCopDisableDirective:
+ Enabled: false
+
+# Offense count: 1
+# Cop supports --auto-correct.
+Lint/SendWithMixinArgument:
+ Exclude:
+ - 'config/initializers/trusted_proxies.rb'
+
+# Offense count: 3
+Lint/StructNewOverride:
+ Exclude:
+ - 'app/presenters/sentry_error_presenter.rb'
+ - 'app/serializers/environment_serializer.rb'
+ - 'lib/gitlab/ci/pipeline/duration.rb'
+
+# Offense count: 7
Lint/UriEscapeUnescape:
Exclude:
- 'app/controllers/application_controller.rb'
@@ -166,14 +219,20 @@ Lint/UriEscapeUnescape:
- 'spec/lib/google_api/auth_spec.rb'
- 'spec/requests/api/files_spec.rb'
-# Offense count: 165
+# Offense count: 3
# Cop supports --auto-correct.
-# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
-# URISchemes: http, https
-Metrics/LineLength:
- Max: 176
+Lint/UriRegexp:
+ Exclude:
+ - 'app/models/concerns/mentionable/reference_regexes.rb'
+ - 'app/services/projects/download_service.rb'
+ - 'lib/gitlab/ci/pipeline/chain/config/content/remote.rb'
+
+# Offense count: 65
+# Cop supports --auto-correct.
+Migration/DepartmentName:
+ Enabled: false
-# Offense count: 143
+# Offense count: 156
# Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms.
# AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS
Naming/FileName:
@@ -190,43 +249,78 @@ Naming/HeredocDelimiterCase:
- 'spec/support/helpers/repo_helpers.rb'
- 'spec/support/helpers/seed_repo.rb'
-# Offense count: 211
-# Configuration parameters: Blacklist.
-# Blacklist: (?-mix:(^|\s)(EO[A-Z]{1}|END)(\s|$))
+# Offense count: 239
+# Configuration parameters: ForbiddenDelimiters.
+# ForbiddenDelimiters: (?-mix:(^|\s)(EO[A-Z]{1}|END)(\s|$))
Naming/HeredocDelimiterNaming:
Enabled: false
-# Offense count: 139
+# Offense count: 5
+# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
+# AllowedNames: io, id, to, by, on, in, at, ip, db, os, pp
+Naming/MethodParameterName:
+ Exclude:
+ - 'lib/gitlab/diff/inline_diff.rb'
+ - 'spec/support/helpers/key_generator_helper.rb'
+
+# Offense count: 162
# Cop supports --auto-correct.
# Configuration parameters: PreferredName.
Naming/RescuedExceptionsVariableName:
Enabled: false
-# Offense count: 9913
+# Offense count: 20
+# Cop supports --auto-correct.
+Performance/Count:
+ Exclude:
+ - 'app/helpers/groups_helper.rb'
+ - 'app/services/merge_requests/add_context_service.rb'
+ - 'ee/lib/gitlab/geo/fdw.rb'
+ - 'ee/lib/gitlab/graphql/aggregations/epics/epic_node.rb'
+ - 'ee/spec/controllers/projects/feature_flags_controller_spec.rb'
+ - 'ee/spec/requests/api/feature_flags_spec.rb'
+ - 'lib/gitlab/sidekiq_status.rb'
+ - 'spec/lib/gitlab/conflict/file_spec.rb'
+ - 'spec/lib/gitlab/git/tree_spec.rb'
+ - 'spec/models/ci/build_spec.rb'
+ - 'spec/support/matchers/exceed_query_limit.rb'
+
+# Offense count: 25
+# Cop supports --auto-correct.
+Performance/Detect:
+ Exclude:
+ - 'ee/spec/controllers/projects/dependencies_controller_spec.rb'
+ - 'ee/spec/controllers/projects/feature_flags_controller_spec.rb'
+ - 'ee/spec/requests/api/unleash_spec.rb'
+ - 'spec/lib/gitlab/git/tree_spec.rb'
+ - 'spec/lib/gitlab/import_export/project/tree_restorer_spec.rb'
+ - 'spec/models/event_spec.rb'
+ - 'spec/requests/api/jobs_spec.rb'
+
+# Offense count: 11832
# Configuration parameters: Prefixes.
# Prefixes: when, with, without
RSpec/ContextWording:
Enabled: false
-# Offense count: 879
+# Offense count: 1121
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: method_call, block
RSpec/ExpectChange:
Enabled: false
-# Offense count: 660
+# Offense count: 751
RSpec/ExpectInHook:
Enabled: false
-# Offense count: 10
+# Offense count: 9
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: it_behaves_like, it_should_behave_like
RSpec/ItBehavesLike:
Exclude:
- 'spec/lib/gitlab/git/commit_spec.rb'
- - 'spec/lib/gitlab/git/repository_spec.rb'
- 'spec/services/notification_service_spec.rb'
# Offense count: 68
@@ -244,30 +338,28 @@ RSpec/LetBeforeExamples:
- 'spec/rubocop/cop/migration/update_column_in_batches_spec.rb'
- 'spec/serializers/pipeline_details_entity_spec.rb'
-# Offense count: 2018
+# Offense count: 2188
# Cop supports --auto-correct.
# Configuration parameters: Strict, EnforcedStyle, AllowedExplicitMatchers.
# SupportedStyles: inflected, explicit
RSpec/PredicateMatcher:
Enabled: false
-# Offense count: 584
+# Offense count: 635
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: and_return, block
RSpec/ReturnFromStub:
Enabled: false
-# Offense count: 380
+# Offense count: 518
RSpec/ScatteredLet:
Enabled: false
-# Offense count: 8
+# Offense count: 4
RSpec/ScatteredSetup:
Exclude:
- - 'spec/lib/gitlab/bitbucket_import/importer_spec.rb'
- 'spec/requests/api/jobs_spec.rb'
- - 'spec/services/projects/create_service_spec.rb'
# Offense count: 10
# Cop supports --auto-correct.
@@ -284,67 +376,92 @@ Rails/ApplicationController:
- 'spec/controllers/concerns/continue_params_spec.rb'
- 'spec/lib/marginalia_spec.rb'
-# Offense count: 8
+# Offense count: 3
# Cop supports --auto-correct.
Rails/BelongsTo:
Exclude:
- 'app/models/deployment.rb'
- 'app/models/environment.rb'
- - 'ee/app/models/prometheus_alert.rb'
- - 'ee/app/models/prometheus_alert_event.rb'
-# Offense count: 151
+# Offense count: 71
+# Configuration parameters: Database, Include.
+# SupportedDatabases: mysql, postgresql
+# Include: db/migrate/*.rb
+Rails/BulkChangeTable:
+ Enabled: false
+
+# Offense count: 208
# Configuration parameters: Include.
# Include: db/migrate/*.rb
Rails/CreateTableWithTimestamps:
Enabled: false
-# Offense count: 266
+# Offense count: 346
# Configuration parameters: EnforcedStyle.
# SupportedStyles: slashes, arguments
Rails/FilePath:
Enabled: false
-# Offense count: 211
+# Offense count: 264
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/HasManyOrHasOneDependent:
Enabled: false
-# Offense count: 431
+# Offense count: 467
# Configuration parameters: Include.
# Include: app/helpers/**/*.rb
Rails/HelperInstanceVariable:
Enabled: false
-# Offense count: 103
+# Offense count: 15
+# Cop supports --auto-correct.
+Rails/IndexBy:
+ Exclude:
+ - 'app/models/ci/pipeline.rb'
+ - 'app/services/ci/pipeline_processing/atomic_processing_service/status_collection.rb'
+ - 'ee/app/services/projects/update_mirror_service.rb'
+ - 'ee/app/services/security/store_report_service.rb'
+ - 'ee/lib/ee/gitlab/auth/ldap/sync/group.rb'
+ - 'ee/lib/ee/gitlab/background_migration/backfill_version_data_from_gitaly.rb'
+ - 'ee/lib/gitlab/analytics/type_of_work/tasks_by_type.rb'
+ - 'ee/lib/gitlab/elastic/document_reference.rb'
+ - 'ee/lib/gitlab/group_plans_preloader.rb'
+ - 'lib/gitlab/database/count/reltuples_count_strategy.rb'
+ - 'lib/gitlab/language_detection.rb'
+
+# Offense count: 36
+# Cop supports --auto-correct.
+Rails/IndexWith:
+ Enabled: false
+
+# Offense count: 105
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/InverseOf:
Enabled: false
-# Offense count: 51
+# Offense count: 55
# Configuration parameters: Include.
# Include: app/controllers/**/*.rb
Rails/LexicallyScopedActionFilter:
Enabled: false
-# Offense count: 4
+# Offense count: 3
# Cop supports --auto-correct.
Rails/LinkToBlank:
Exclude:
- 'app/helpers/projects_helper.rb'
- 'app/helpers/wiki_helper.rb'
- 'ee/app/helpers/ee/user_callouts_helper.rb'
- - 'ee/app/helpers/license_helper.rb'
-# Offense count: 35
+# Offense count: 34
# Configuration parameters: Include.
# Include: **/Rakefile, **/*.rake
Rails/RakeEnvironment:
Enabled: false
-# Offense count: 868
+# Offense count: 926
# Configuration parameters: Blacklist, Whitelist.
# Blacklist: decrement!, decrement_counter, increment!, increment_counter, toggle!, touch, update_all, update_attribute, update_column, update_columns, update_counters
Rails/SkipsModelValidations:
@@ -360,13 +477,18 @@ Security/YAMLLoad:
- 'spec/initializers/secret_token_spec.rb'
- 'spec/lib/gitlab/prometheus/additional_metrics_parser_spec.rb'
-# Offense count: 34
-# Configuration parameters: EnforcedStyle.
+# Offense count: 10
+# Configuration parameters: EnforcedStyle, AllowModifiersOnSymbols.
# SupportedStyles: inline, group
Style/AccessModifierDeclarations:
- Enabled: false
+ Exclude:
+ - 'app/helpers/issues_helper.rb'
+ - 'app/helpers/lazy_image_tag_helper.rb'
+ - 'lib/gitlab/cache/request_cache.rb'
+ - 'lib/gitlab/request_profiler.rb'
+ - 'spec/support/forgery_protection.rb'
-# Offense count: 127
+# Offense count: 148
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: percent_q, bare_percent
@@ -379,7 +501,7 @@ Style/CommentedKeyword:
- 'lib/tasks/gitlab/backup.rake'
- 'spec/tasks/gitlab/backup_rake_spec.rb'
-# Offense count: 6
+# Offense count: 5
# Cop supports --auto-correct.
Style/EachWithObject:
Exclude:
@@ -388,9 +510,8 @@ Style/EachWithObject:
- 'lib/gitlab/hook_data/issuable_builder.rb'
- 'lib/gitlab/i18n/po_linter.rb'
- 'lib/gitlab/import_export/members_mapper.rb'
- - 'lib/gitlab/import_export/relation_factory.rb'
-# Offense count: 41
+# Offense count: 46
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: empty, nil, both
@@ -404,7 +525,7 @@ Style/EmptyLambdaParameter:
- 'app/models/ci/build.rb'
- 'app/models/ci/runner.rb'
-# Offense count: 8
+# Offense count: 7
# Cop supports --auto-correct.
Style/EmptyLiteral:
Exclude:
@@ -414,38 +535,66 @@ Style/EmptyLiteral:
- 'spec/helpers/merge_requests_helper_spec.rb'
- 'spec/lib/gitlab/workhorse_spec.rb'
- 'spec/requests/api/jobs_spec.rb'
- - 'spec/support/shared_examples/chat_slash_commands_shared_examples.rb'
-# Offense count: 148
+# Offense count: 170
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: compact, expanded
Style/EmptyMethod:
Enabled: false
-# Offense count: 346
+# Offense count: 431
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: format, sprintf, percent
Style/FormatString:
Enabled: false
-# Offense count: 692
+# Offense count: 769
# Configuration parameters: MinBodyLength.
Style/GuardClause:
Enabled: false
-# Offense count: 27
+# Offense count: 47
+# Cop supports --auto-correct.
+Style/HashEachMethods:
+ Enabled: false
+
+# Offense count: 6
+# Cop supports --auto-correct.
+Style/HashTransformKeys:
+ Exclude:
+ - 'ee/app/models/vulnerabilities/occurrence.rb'
+ - 'ee/spec/lib/gitlab/ci/templates/dependency_scanning_gitlab_ci_yaml_spec.rb'
+ - 'lib/banzai/filter/commit_trailers_filter.rb'
+ - 'lib/gitlab/analytics/cycle_analytics/stage_events.rb'
+
+# Offense count: 10
+# Cop supports --auto-correct.
+Style/HashTransformValues:
+ Exclude:
+ - 'app/validators/addressable_url_validator.rb'
+ - 'config/initializers/action_dispatch_journey_formatter.rb'
+ - 'ee/app/helpers/compliance_management/compliance_framework/project_settings_helper.rb'
+ - 'ee/app/services/packages/nuget/metadata_extraction_service.rb'
+ - 'lib/gitlab/config/entry/configurable.rb'
+ - 'lib/gitlab/config/entry/node.rb'
+ - 'lib/gitlab/discussions_diff/file_collection.rb'
+ - 'lib/gitlab/error_tracking.rb'
+ - 'lib/rspec_flaky/flaky_examples_collection.rb'
+ - 'spec/lib/gitlab/database_importers/common_metrics/prometheus_metric_spec.rb'
+
+# Offense count: 31
# Configuration parameters: AllowIfModifier.
Style/IfInsideElse:
Enabled: false
-# Offense count: 1474
+# Offense count: 1313
# Cop supports --auto-correct.
Style/IfUnlessModifier:
Enabled: false
-# Offense count: 314
+# Offense count: 377
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: line_count_dependent, lambda, literal
@@ -460,51 +609,49 @@ Style/MethodMissingSuper:
Style/MissingRespondToMissing:
Enabled: false
-# Offense count: 6
+# Offense count: 5
Style/MixinUsage:
Exclude:
- 'spec/factories/ci/builds.rb'
- 'spec/factories/ci/job_artifacts.rb'
- 'spec/factories/lfs_objects.rb'
- 'spec/factories/notes.rb'
- - 'spec/lib/gitlab/import_export/project_tree_restorer_spec.rb'
- 'spec/lib/gitlab/import_export/version_checker_spec.rb'
-# Offense count: 4
+# Offense count: 2
# Cop supports --auto-correct.
Style/MultilineIfModifier:
Exclude:
- - 'app/helpers/snippets_helper.rb'
- 'app/services/ci/process_pipeline_service.rb'
- 'lib/api/commit_statuses.rb'
-# Offense count: 25
+# Offense count: 29
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, MinBodyLength.
# SupportedStyles: skip_modifier_ifs, always
Style/Next:
Enabled: false
-# Offense count: 71
+# Offense count: 89
# Cop supports --auto-correct.
# Configuration parameters: EnforcedOctalStyle.
# SupportedOctalStyles: zero_with_o, zero_only
Style/NumericLiteralPrefix:
Enabled: false
-# Offense count: 234
+# Offense count: 255
# Cop supports --auto-correct.
# Configuration parameters: AutoCorrect, EnforcedStyle, IgnoredMethods.
# SupportedStyles: predicate, comparison
Style/NumericPredicate:
Enabled: false
-# Offense count: 106
+# Offense count: 117
# Cop supports --auto-correct.
Style/ParallelAssignment:
Enabled: false
-# Offense count: 1692
+# Offense count: 2035
# Cop supports --auto-correct.
# Configuration parameters: PreferredDelimiters.
Style/PercentLiteralDelimiters:
@@ -526,51 +673,60 @@ Style/PerlBackrefs:
- 'lib/gitlab/search_results.rb'
- 'lib/gitlab/sherlock/query.rb'
-# Offense count: 165
+# Offense count: 200
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: compact, exploded
Style/RaiseArgs:
Enabled: false
-# Offense count: 221
+# Offense count: 246
# Cop supports --auto-correct.
Style/RedundantFreeze:
Enabled: false
-# Offense count: 15
+# Offense count: 123
+# Cop supports --auto-correct.
+Style/RedundantInterpolation:
+ Enabled: false
+
+# Offense count: 6
+# Cop supports --auto-correct.
+Style/RedundantParentheses:
+ Exclude:
+ - 'ee/app/models/ee/merge_request.rb'
+
+# Offense count: 33
# Cop supports --auto-correct.
# Configuration parameters: AllowMultipleReturnValues.
Style/RedundantReturn:
- Exclude:
- - 'app/controllers/application_controller.rb'
- - 'app/controllers/concerns/issuable_actions.rb'
- - 'app/controllers/groups/application_controller.rb'
- - 'app/controllers/omniauth_callbacks_controller.rb'
- - 'app/controllers/profiles/keys_controller.rb'
- - 'app/controllers/projects/application_controller.rb'
- - 'app/services/access_token_validation_service.rb'
- - 'lib/gitlab/utils.rb'
- - 'lib/google_api/auth.rb'
+ Enabled: false
-# Offense count: 739
+# Offense count: 801
# Cop supports --auto-correct.
Style/RedundantSelf:
Enabled: false
-# Offense count: 80
+# Offense count: 2
+# Cop supports --auto-correct.
+Style/RedundantSort:
+ Exclude:
+ - 'ee/app/presenters/packages/nuget/search_results_presenter.rb'
+ - 'ee/spec/presenters/packages/nuget/search_results_presenter_spec.rb'
+
+# Offense count: 120
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, AllowInnerSlashes.
# SupportedStyles: slashes, percent_r, mixed
Style/RegexpLiteral:
Enabled: false
-# Offense count: 42
+# Offense count: 46
# Cop supports --auto-correct.
Style/RescueModifier:
Enabled: false
-# Offense count: 237
+# Offense count: 286
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: implicit, explicit
@@ -592,28 +748,544 @@ Style/SingleLineMethods:
Exclude:
- 'lib/gitlab/ci/ansi2html.rb'
-# Offense count: 94
+# Offense count: 102
# Cop supports --auto-correct.
# Configuration parameters: .
# SupportedStyles: use_perl_names, use_english_names
Style/SpecialGlobalVars:
EnforcedStyle: use_perl_names
-# Offense count: 75
+# Offense count: 93
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: single_quotes, double_quotes
Style/StringLiteralsInInterpolation:
Enabled: false
-# Offense count: 216
+# Offense count: 233
# Cop supports --auto-correct.
# Configuration parameters: IgnoredMethods.
# IgnoredMethods: respond_to, define_method
Style/SymbolProc:
Enabled: false
-# Offense count: 99
+# Offense count: 1478
# Cop supports --auto-correct.
-Style/UnneededInterpolation:
- Enabled: false
+# Configuration parameters: AllowImplicitReturn, AllowedReceivers.
+Rails/SaveBang:
+ Exclude:
+ - 'ee/spec/controllers/groups/epic_issues_controller_spec.rb'
+ - 'ee/spec/controllers/groups/epic_links_controller_spec.rb'
+ - 'ee/spec/controllers/groups/epics_controller_spec.rb'
+ - 'ee/spec/controllers/groups/roadmap_controller_spec.rb'
+ - 'ee/spec/controllers/projects/environments_controller_spec.rb'
+ - 'ee/spec/controllers/projects/issues_controller_spec.rb'
+ - 'ee/spec/controllers/projects/merge_requests/creations_controller_spec.rb'
+ - 'ee/spec/controllers/projects/merge_requests_controller_spec.rb'
+ - 'ee/spec/controllers/projects/service_desk_controller_spec.rb'
+ - 'ee/spec/controllers/projects/subscriptions_controller_spec.rb'
+ - 'ee/spec/controllers/projects/vulnerability_feedback_controller_spec.rb'
+ - 'ee/spec/controllers/subscriptions_controller_spec.rb'
+ - 'ee/spec/factories/merge_requests.rb'
+ - 'ee/spec/features/admin/geo/admin_geo_nodes_spec.rb'
+ - 'ee/spec/features/boards/scoped_issue_board_spec.rb'
+ - 'ee/spec/features/ci_shared_runner_warnings_spec.rb'
+ - 'ee/spec/features/dashboards/operations_spec.rb'
+ - 'ee/spec/features/issues/gfm_autocomplete_ee_spec.rb'
+ - 'ee/spec/features/merge_request/user_approves_spec.rb'
+ - 'ee/spec/features/merge_requests/user_views_all_merge_requests_spec.rb'
+ - 'ee/spec/features/projects/members/invite_group_and_members_spec.rb'
+ - 'ee/spec/features/projects/merge_requests/user_approves_merge_request_spec.rb'
+ - 'ee/spec/features/projects/new_project_spec.rb'
+ - 'ee/spec/features/projects/settings/user_manages_approval_settings_spec.rb'
+ - 'ee/spec/features/projects/settings/user_manages_members_spec.rb'
+ - 'ee/spec/features/search/elastic/global_search_spec.rb'
+ - 'ee/spec/finders/epics_finder_spec.rb'
+ - 'ee/spec/frontend/fixtures/analytics.rb'
+ - 'ee/spec/helpers/application_helper_spec.rb'
+ - 'ee/spec/helpers/ee/issues_helper_spec.rb'
+ - 'ee/spec/initializers/fog_google_https_private_urls_spec.rb'
+ - 'ee/spec/lib/analytics/merge_request_metrics_calculator_spec.rb'
+ - 'ee/spec/lib/ee/gitlab/auth/ldap/sync/group_spec.rb'
+ - 'ee/spec/lib/ee/gitlab/background_migration/migrate_approver_to_approval_rules_spec.rb'
+ - 'ee/spec/lib/ee/gitlab/background_migration/move_epic_issues_after_epics_spec.rb'
+ - 'ee/spec/lib/ee/gitlab/background_migration/populate_any_approval_rule_for_merge_requests_spec.rb'
+ - 'ee/spec/lib/ee/gitlab/background_migration/populate_any_approval_rule_for_projects_spec.rb'
+ - 'ee/spec/lib/ee/gitlab/checks/push_rules/commit_check_spec.rb'
+ - 'ee/spec/lib/ee/gitlab/ci/pipeline/quota/activity_spec.rb'
+ - 'ee/spec/lib/gitlab/auth/ldap/access_spec.rb'
+ - 'ee/spec/lib/gitlab/auth/o_auth/user_spec.rb'
+ - 'ee/spec/lib/gitlab/auth/saml/user_spec.rb'
+ - 'ee/spec/lib/gitlab/elastic/search_results_spec.rb'
+ - 'ee/spec/lib/gitlab/email/handler/ee/service_desk_handler_spec.rb'
+ - 'ee/spec/lib/gitlab/geo/jwt_request_decoder_spec.rb'
+ - 'ee/spec/lib/gitlab/geo/oauth/session_spec.rb'
+ - 'ee/spec/lib/gitlab/geo_spec.rb'
+ - 'ee/spec/lib/gitlab/git_access_spec.rb'
+ - 'ee/spec/mailers/notify_spec.rb'
+ - 'ee/spec/migrations/geo/migrate_ci_job_artifacts_to_separate_registry_spec.rb'
+ - 'ee/spec/migrations/geo/migrate_lfs_objects_to_separate_registry_spec.rb'
+ - 'ee/spec/migrations/schedule_project_any_approval_rule_migration_spec.rb'
+ - 'ee/spec/models/application_setting_spec.rb'
+ - 'ee/spec/models/approval_merge_request_rule_spec.rb'
+ - 'ee/spec/models/approval_state_spec.rb'
+ - 'ee/spec/models/burndown_spec.rb'
+ - 'ee/spec/models/ci/build_spec.rb'
+ - 'ee/spec/models/ci/pipeline_spec.rb'
+ - 'ee/spec/models/ci/subscriptions/project_spec.rb'
+ - 'ee/spec/models/concerns/deprecated_approvals_before_merge_spec.rb'
+ - 'ee/spec/models/concerns/elastic/note_spec.rb'
+ - 'ee/spec/models/ee/protected_branch_spec.rb'
+ - 'ee/spec/models/ee/protected_ref_access_spec.rb'
+ - 'ee/spec/models/ee/protected_ref_spec.rb'
+ - 'ee/spec/models/epic_spec.rb'
+ - 'ee/spec/models/geo/project_registry_spec.rb'
+ - 'ee/spec/models/geo_node_spec.rb'
+ - 'ee/spec/models/geo_node_status_spec.rb'
+ - 'ee/spec/models/group_spec.rb'
+ - 'ee/spec/models/issue_spec.rb'
+ - 'ee/spec/models/label_note_spec.rb'
+ - 'ee/spec/models/license_spec.rb'
+ - 'ee/spec/models/merge_request_spec.rb'
+ - 'ee/spec/models/operations/feature_flag_scope_spec.rb'
+ - 'ee/spec/models/operations/feature_flag_spec.rb'
+ - 'ee/spec/models/operations/feature_flags/strategy_spec.rb'
+ - 'ee/spec/models/operations/feature_flags/user_list_spec.rb'
+ - 'ee/spec/models/project_services/github_service_spec.rb'
+ - 'ee/spec/models/project_services/jenkins_service_spec.rb'
+ - 'ee/spec/models/project_spec.rb'
+ - 'ee/spec/models/scim_identity_spec.rb'
+ - 'ee/spec/models/scim_oauth_access_token_spec.rb'
+ - 'ee/spec/models/user_preference_spec.rb'
+ - 'ee/spec/models/user_spec.rb'
+ - 'ee/spec/models/visible_approvable_spec.rb'
+ - 'ee/spec/models/vulnerabilities/feedback_spec.rb'
+ - 'ee/spec/models/vulnerabilities/issue_link_spec.rb'
+ - 'ee/spec/policies/protected_branch_policy_spec.rb'
+ - 'ee/spec/presenters/audit_event_presenter_spec.rb'
+ - 'ee/spec/presenters/epic_presenter_spec.rb'
+ - 'ee/spec/presenters/packages/conan/package_presenter_spec.rb'
+ - 'ee/spec/requests/api/boards_spec.rb'
+ - 'ee/spec/requests/api/epic_issues_spec.rb'
+ - 'ee/spec/requests/api/epic_links_spec.rb'
+ - 'ee/spec/requests/api/epics_spec.rb'
+ - 'ee/spec/requests/api/geo_nodes_spec.rb'
+ - 'ee/spec/requests/api/geo_spec.rb'
+ - 'ee/spec/requests/api/graphql/group/epics_spec.rb'
+ - 'ee/spec/requests/api/graphql/mutations/epic_tree/reorder_spec.rb'
+ - 'ee/spec/requests/api/groups_spec.rb'
+ - 'ee/spec/requests/api/issues_spec.rb'
+ - 'ee/spec/requests/api/ldap_group_links_spec.rb'
+ - 'ee/spec/requests/api/maven_packages_spec.rb'
+ - 'ee/spec/requests/api/merge_request_approval_rules_spec.rb'
+ - 'ee/spec/requests/api/merge_request_approvals_spec.rb'
+ - 'ee/spec/requests/api/merge_requests_spec.rb'
+ - 'ee/spec/requests/api/project_approvals_spec.rb'
+ - 'ee/spec/requests/api/projects_spec.rb'
+ - 'ee/spec/requests/api/protected_branches_spec.rb'
+ - 'ee/spec/requests/api/scim_spec.rb'
+ - 'ee/spec/requests/api/todos_spec.rb'
+ - 'ee/spec/services/approval_rules/finalize_service_spec.rb'
+ - 'ee/spec/services/ci/register_job_service_spec.rb'
+ - 'ee/spec/services/ee/boards/issues/create_service_spec.rb'
+ - 'ee/spec/services/ee/issuable/clone/attributes_rewriter_spec.rb'
+ - 'ee/spec/services/ee/issuable/common_system_notes_service_spec.rb'
+ - 'ee/spec/services/ee/issues/update_service_spec.rb'
+ - 'ee/spec/services/ee/merge_requests/refresh_service_spec.rb'
+ - 'ee/spec/services/ee/merge_requests/update_service_spec.rb'
+ - 'ee/spec/services/ee/notes/quick_actions_service_spec.rb'
+ - 'ee/spec/services/ee/notification_service_spec.rb'
+ - 'ee/spec/services/ee/resource_events/change_weight_service_spec.rb'
+ - 'ee/spec/services/elastic/index_record_service_spec.rb'
+ - 'ee/spec/services/epic_links/create_service_spec.rb'
+ - 'ee/spec/services/epics/issue_promote_service_spec.rb'
+ - 'ee/spec/services/epics/tree_reorder_service_spec.rb'
+ - 'ee/spec/services/epics/update_dates_service_spec.rb'
+ - 'ee/spec/services/epics/update_service_spec.rb'
+ - 'ee/spec/services/geo/blob_verification_secondary_service_spec.rb'
+ - 'ee/spec/services/geo/metrics_update_service_spec.rb'
+ - 'ee/spec/services/geo/registry_consistency_service_spec.rb'
+ - 'ee/spec/services/geo/repository_verification_secondary_service_spec.rb'
+ - 'ee/spec/services/groups/autocomplete_service_spec.rb'
+ - 'ee/spec/services/ldap_group_reset_service_spec.rb'
+ - 'ee/spec/services/lfs/unlock_file_service_spec.rb'
+ - 'ee/spec/services/merge_requests/approval_service_spec.rb'
+ - 'ee/spec/services/merge_requests/remove_approval_service_spec.rb'
+ - 'ee/spec/services/merge_trains/refresh_merge_request_service_spec.rb'
+ - 'ee/spec/services/projects/after_rename_service_spec.rb'
+ - 'ee/spec/services/projects/update_service_spec.rb'
+ - 'ee/spec/services/quick_actions/interpret_service_spec.rb'
+ - 'ee/spec/services/slash_commands/global_slack_handler_spec.rb'
+ - 'ee/spec/services/start_pull_mirroring_service_spec.rb'
+ - 'ee/spec/services/status_page/trigger_publish_service_spec.rb'
+ - 'ee/spec/services/todo_service_spec.rb'
+ - 'ee/spec/services/update_build_minutes_service_spec.rb'
+ - 'ee/spec/support/shared_examples/lib/analytics/common_merge_request_metrics_refresh_shared_examples.rb'
+ - 'ee/spec/support/shared_examples/models/concerns/replicator_shared_examples.rb'
+ - 'ee/spec/support/shared_examples/models/member_shared_examples.rb'
+ - 'ee/spec/support/shared_examples/models/mentionable_shared_examples.rb'
+ - 'ee/spec/support/shared_examples/policies/protected_environments_shared_examples.rb'
+ - 'ee/spec/support/shared_examples/requests/api/project_approval_rules_api_shared_examples.rb'
+ - 'ee/spec/support/shared_examples/services/issue_epic_shared_examples.rb'
+ - 'ee/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb'
+ - 'ee/spec/workers/adjourned_project_deletion_worker_spec.rb'
+ - 'ee/spec/workers/create_github_webhook_worker_spec.rb'
+ - 'ee/spec/workers/elastic_indexer_worker_spec.rb'
+ - 'ee/spec/workers/geo/container_repository_sync_dispatch_worker_spec.rb'
+ - 'ee/spec/workers/geo/file_download_dispatch_worker_spec.rb'
+ - 'ee/spec/workers/geo/repository_shard_sync_worker_spec.rb'
+ - 'ee/spec/workers/repository_import_worker_spec.rb'
+ - 'ee/spec/workers/update_all_mirrors_worker_spec.rb'
+ - 'qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb'
+ - 'qa/qa/specs/features/ee/browser_ui/3_create/repository/pull_mirroring_over_http_spec.rb'
+ - 'spec/controllers/abuse_reports_controller_spec.rb'
+ - 'spec/controllers/admin/impersonations_controller_spec.rb'
+ - 'spec/controllers/admin/runners_controller_spec.rb'
+ - 'spec/controllers/boards/issues_controller_spec.rb'
+ - 'spec/controllers/groups/runners_controller_spec.rb'
+ - 'spec/controllers/oauth/authorizations_controller_spec.rb'
+ - 'spec/controllers/omniauth_callbacks_controller_spec.rb'
+ - 'spec/controllers/profiles/emails_controller_spec.rb'
+ - 'spec/controllers/profiles/notifications_controller_spec.rb'
+ - 'spec/controllers/projects/artifacts_controller_spec.rb'
+ - 'spec/controllers/projects/cycle_analytics_controller_spec.rb'
+ - 'spec/controllers/projects/issues_controller_spec.rb'
+ - 'spec/controllers/projects/labels_controller_spec.rb'
+ - 'spec/controllers/projects/merge_requests_controller_spec.rb'
+ - 'spec/controllers/projects/milestones_controller_spec.rb'
+ - 'spec/controllers/projects/notes_controller_spec.rb'
+ - 'spec/controllers/projects/pipelines_controller_spec.rb'
+ - 'spec/controllers/projects/runners_controller_spec.rb'
+ - 'spec/controllers/projects_controller_spec.rb'
+ - 'spec/factories/ci/pipelines.rb'
+ - 'spec/factories/design_management/designs.rb'
+ - 'spec/factories/design_management/versions.rb'
+ - 'spec/factories/labels.rb'
+ - 'spec/factories/projects.rb'
+ - 'spec/features/admin/admin_mode/login_spec.rb'
+ - 'spec/features/admin/admin_runners_spec.rb'
+ - 'spec/features/admin/admin_users_impersonation_tokens_spec.rb'
+ - 'spec/features/admin/admin_users_spec.rb'
+ - 'spec/features/boards/sidebar_spec.rb'
+ - 'spec/features/calendar_spec.rb'
+ - 'spec/features/commits_spec.rb'
+ - 'spec/features/dashboard/datetime_on_tooltips_spec.rb'
+ - 'spec/features/dashboard/issuables_counter_spec.rb'
+ - 'spec/features/dashboard/project_member_activity_index_spec.rb'
+ - 'spec/features/dashboard/projects_spec.rb'
+ - 'spec/features/error_tracking/user_sees_error_index_spec.rb'
+ - 'spec/features/groups/members/request_access_spec.rb'
+ - 'spec/features/issues/bulk_assignment_labels_spec.rb'
+ - 'spec/features/issues/gfm_autocomplete_spec.rb'
+ - 'spec/features/issues/issue_sidebar_spec.rb'
+ - 'spec/features/issues/note_polling_spec.rb'
+ - 'spec/features/issues/user_creates_branch_and_merge_request_spec.rb'
+ - 'spec/features/issues/user_creates_confidential_merge_request_spec.rb'
+ - 'spec/features/issues/user_edits_issue_spec.rb'
+ - 'spec/features/issues/user_filters_issues_spec.rb'
+ - 'spec/features/issues/user_sees_live_update_spec.rb'
+ - 'spec/features/issues/user_sorts_issues_spec.rb'
+ - 'spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb'
+ - 'spec/features/merge_request/user_posts_diff_notes_spec.rb'
+ - 'spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb'
+ - 'spec/features/merge_request/user_sees_cherry_pick_modal_spec.rb'
+ - 'spec/features/merge_request/user_sees_merge_widget_spec.rb'
+ - 'spec/features/merge_requests/user_mass_updates_spec.rb'
+ - 'spec/features/profiles/emails_spec.rb'
+ - 'spec/features/profiles/password_spec.rb'
+ - 'spec/features/profiles/personal_access_tokens_spec.rb'
+ - 'spec/features/projects/features_visibility_spec.rb'
+ - 'spec/features/projects/jobs_spec.rb'
+ - 'spec/features/projects/members/user_requests_access_spec.rb'
+ - 'spec/features/projects/pages_lets_encrypt_spec.rb'
+ - 'spec/features/projects/pages_spec.rb'
+ - 'spec/features/projects/remote_mirror_spec.rb'
+ - 'spec/features/projects/services/user_activates_slack_notifications_spec.rb'
+ - 'spec/features/projects/settings/access_tokens_spec.rb'
+ - 'spec/features/projects/show/user_sees_deletion_failure_message_spec.rb'
+ - 'spec/features/projects/user_sees_sidebar_spec.rb'
+ - 'spec/features/projects/wiki/user_updates_wiki_page_spec.rb'
+ - 'spec/features/projects/wiki/users_views_asciidoc_page_with_includes_spec.rb'
+ - 'spec/features/security/project/private_access_spec.rb'
+ - 'spec/features/users/login_spec.rb'
+ - 'spec/features/users/show_spec.rb'
+ - 'spec/finders/autocomplete/move_to_project_finder_spec.rb'
+ - 'spec/finders/group_descendants_finder_spec.rb'
+ - 'spec/finders/issues_finder_spec.rb'
+ - 'spec/finders/merge_requests_finder_spec.rb'
+ - 'spec/finders/projects_finder_spec.rb'
+ - 'spec/finders/uploader_finder_spec.rb'
+ - 'spec/frontend/fixtures/issues.rb'
+ - 'spec/frontend/fixtures/merge_requests.rb'
+ - 'spec/graphql/mutations/merge_requests/set_locked_spec.rb'
+ - 'spec/graphql/mutations/merge_requests/set_wip_spec.rb'
+ - 'spec/graphql/resolvers/boards_resolver_spec.rb'
+ - 'spec/helpers/appearances_helper_spec.rb'
+ - 'spec/helpers/profiles_helper_spec.rb'
+ - 'spec/helpers/projects/alert_management_helper_spec.rb'
+ - 'spec/helpers/projects_helper_spec.rb'
+ - 'spec/helpers/visibility_level_helper_spec.rb'
+ - 'spec/initializers/active_record_locking_spec.rb'
+ - 'spec/initializers/fog_google_https_private_urls_spec.rb'
+ - 'spec/lib/after_commit_queue_spec.rb'
+ - 'spec/lib/backup/manager_spec.rb'
+ - 'spec/lib/banzai/reference_parser/external_issue_parser_spec.rb'
+ - 'spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb'
+ - 'spec/lib/gitlab/auth/ldap/user_spec.rb'
+ - 'spec/lib/gitlab/auth/o_auth/user_spec.rb'
+ - 'spec/lib/gitlab/auth/saml/user_spec.rb'
+ - 'spec/lib/gitlab/auth_spec.rb'
+ - 'spec/lib/gitlab/background_migration/backfill_deployment_clusters_from_deployments_spec.rb'
+ - 'spec/lib/gitlab/background_migration/backfill_project_repositories_spec.rb'
+ - 'spec/lib/gitlab/background_migration/backfill_project_settings_spec.rb'
+ - 'spec/lib/gitlab/background_migration/backfill_push_rules_id_in_projects_spec.rb'
+ - 'spec/lib/gitlab/background_migration/digest_column_spec.rb'
+ - 'spec/lib/gitlab/background_migration/encrypt_columns_spec.rb'
+ - 'spec/lib/gitlab/background_migration/fix_cross_project_label_links_spec.rb'
+ - 'spec/lib/gitlab/background_migration/fix_projects_without_prometheus_service_spec.rb'
+ - 'spec/lib/gitlab/background_migration/fix_user_namespace_names_spec.rb'
+ - 'spec/lib/gitlab/background_migration/fix_user_project_route_names_spec.rb'
+ - 'spec/lib/gitlab/background_migration/legacy_upload_mover_spec.rb'
+ - 'spec/lib/gitlab/background_migration/legacy_uploads_migrator_spec.rb'
+ - 'spec/lib/gitlab/background_migration/link_lfs_objects_projects_spec.rb'
+ - 'spec/lib/gitlab/background_migration/migrate_issue_trackers_sensitive_data_spec.rb'
+ - 'spec/lib/gitlab/background_migration/migrate_stage_index_spec.rb'
+ - 'spec/lib/gitlab/background_migration/migrate_users_bio_to_user_details_spec.rb'
+ - 'spec/lib/gitlab/background_migration/populate_canonical_emails_spec.rb'
+ - 'spec/lib/gitlab/background_migration/populate_merge_request_assignees_table_spec.rb'
+ - 'spec/lib/gitlab/background_migration/populate_user_highest_roles_table_spec.rb'
+ - 'spec/lib/gitlab/background_migration/recalculate_project_authorizations_spec.rb'
+ - 'spec/lib/gitlab/background_migration/remove_restricted_todos_spec.rb'
+ - 'spec/lib/gitlab/background_migration/set_confidential_note_events_on_services_spec.rb'
+ - 'spec/lib/gitlab/background_migration/set_confidential_note_events_on_webhooks_spec.rb'
+ - 'spec/lib/gitlab/bitbucket_server_import/importer_spec.rb'
+ - 'spec/lib/gitlab/ci/ansi2json/style_spec.rb'
+ - 'spec/lib/gitlab/cycle_analytics/base_event_fetcher_spec.rb'
+ - 'spec/lib/gitlab/cycle_analytics/events_spec.rb'
+ - 'spec/lib/gitlab/database/custom_structure_spec.rb'
+ - 'spec/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers_spec.rb'
+ - 'spec/lib/gitlab/database_importers/self_monitoring/project/create_service_spec.rb'
+ - 'spec/lib/gitlab/git/remote_mirror_spec.rb'
+ - 'spec/lib/gitlab/git_access_spec.rb'
+ - 'spec/lib/gitlab/gitaly_client/repository_service_spec.rb'
+ - 'spec/lib/gitlab/import_export/avatar_saver_spec.rb'
+ - 'spec/lib/gitlab/import_export/design_repo_restorer_spec.rb'
+ - 'spec/lib/gitlab/import_export/fast_hash_serializer_spec.rb'
+ - 'spec/lib/gitlab/import_export/fork_spec.rb'
+ - 'spec/lib/gitlab/import_export/group/legacy_tree_saver_spec.rb'
+ - 'spec/lib/gitlab/import_export/importer_spec.rb'
+ - 'spec/lib/gitlab/import_export/lfs_restorer_spec.rb'
+ - 'spec/lib/gitlab/import_export/lfs_saver_spec.rb'
+ - 'spec/lib/gitlab/import_export/members_mapper_spec.rb'
+ - 'spec/lib/gitlab/import_export/project/tree_restorer_spec.rb'
+ - 'spec/lib/gitlab/import_export/project/tree_saver_spec.rb'
+ - 'spec/lib/gitlab/import_export/repo_restorer_spec.rb'
+ - 'spec/lib/gitlab/import_export/saver_spec.rb'
+ - 'spec/lib/gitlab/import_export/snippet_repo_saver_spec.rb'
+ - 'spec/lib/gitlab/import_export/snippets_repo_restorer_spec.rb'
+ - 'spec/lib/gitlab/import_export/snippets_repo_saver_spec.rb'
+ - 'spec/lib/gitlab/import_export/uploads_manager_spec.rb'
+ - 'spec/lib/gitlab/import_export/uploads_saver_spec.rb'
+ - 'spec/lib/gitlab/import_export/wiki_restorer_spec.rb'
+ - 'spec/lib/gitlab/lets_encrypt/client_spec.rb'
+ - 'spec/lib/gitlab/markdown_cache/active_record/extension_spec.rb'
+ - 'spec/lib/gitlab/markdown_cache/redis/store_spec.rb'
+ - 'spec/lib/gitlab/shard_health_cache_spec.rb'
+ - 'spec/mailers/notify_spec.rb'
+ - 'spec/migrations/20200122123016_backfill_project_settings_spec.rb'
+ - 'spec/migrations/20200123155929_remove_invalid_jira_data_spec.rb'
+ - 'spec/migrations/20200127090233_remove_invalid_issue_tracker_data_spec.rb'
+ - 'spec/migrations/20200406102120_backfill_deployment_clusters_from_deployments_spec.rb'
+ - 'spec/migrations/add_unique_constraint_to_approvals_user_id_and_merge_request_id_spec.rb'
+ - 'spec/migrations/backfill_and_add_not_null_constraint_to_released_at_column_on_releases_table_spec.rb'
+ - 'spec/migrations/backfill_releases_table_updated_at_and_add_not_null_constraints_to_timestamps_spec.rb'
+ - 'spec/migrations/encrypt_plaintext_attributes_on_application_settings_spec.rb'
+ - 'spec/migrations/fill_file_store_lfs_objects_spec.rb'
+ - 'spec/migrations/fill_store_uploads_spec.rb'
+ - 'spec/migrations/fix_null_type_labels_spec.rb'
+ - 'spec/migrations/fix_pool_repository_source_project_id_spec.rb'
+ - 'spec/migrations/fix_wrong_pages_access_level_spec.rb'
+ - 'spec/migrations/insert_project_hooks_plan_limits_spec.rb'
+ - 'spec/migrations/migrate_auto_dev_ops_domain_to_cluster_domain_spec.rb'
+ - 'spec/migrations/schedule_link_lfs_objects_projects_spec.rb'
+ - 'spec/models/appearance_spec.rb'
+ - 'spec/models/application_setting_spec.rb'
+ - 'spec/models/ci/build_spec.rb'
+ - 'spec/models/ci/instance_variable_spec.rb'
+ - 'spec/models/ci/pipeline_spec.rb'
+ - 'spec/models/ci/runner_spec.rb'
+ - 'spec/models/clusters/applications/helm_spec.rb'
+ - 'spec/models/concerns/avatarable_spec.rb'
+ - 'spec/models/concerns/bulk_insertable_associations_spec.rb'
+ - 'spec/models/concerns/cache_markdown_field_spec.rb'
+ - 'spec/models/concerns/featurable_spec.rb'
+ - 'spec/models/concerns/issuable_spec.rb'
+ - 'spec/models/concerns/mentionable_spec.rb'
+ - 'spec/models/concerns/milestoneable_spec.rb'
+ - 'spec/models/concerns/routable_spec.rb'
+ - 'spec/models/concerns/subscribable_spec.rb'
+ - 'spec/models/concerns/token_authenticatable_spec.rb'
+ - 'spec/models/container_repository_spec.rb'
+ - 'spec/models/cycle_analytics/issue_spec.rb'
+ - 'spec/models/cycle_analytics/plan_spec.rb'
+ - 'spec/models/deploy_keys_project_spec.rb'
+ - 'spec/models/deploy_token_spec.rb'
+ - 'spec/models/deployment_spec.rb'
+ - 'spec/models/design_management/version_spec.rb'
+ - 'spec/models/diff_note_spec.rb'
+ - 'spec/models/email_spec.rb'
+ - 'spec/models/environment_spec.rb'
+ - 'spec/models/event_spec.rb'
+ - 'spec/models/fork_network_spec.rb'
+ - 'spec/models/generic_commit_status_spec.rb'
+ - 'spec/models/grafana_integration_spec.rb'
+ - 'spec/models/group_spec.rb'
+ - 'spec/models/hooks/system_hook_spec.rb'
+ - 'spec/models/hooks/web_hook_spec.rb'
+ - 'spec/models/identity_spec.rb'
+ - 'spec/models/issue_spec.rb'
+ - 'spec/models/key_spec.rb'
+ - 'spec/models/lfs_objects_project_spec.rb'
+ - 'spec/models/member_spec.rb'
+ - 'spec/models/members/group_member_spec.rb'
+ - 'spec/models/members/project_member_spec.rb'
+ - 'spec/models/merge_request_spec.rb'
+ - 'spec/models/milestone_spec.rb'
+ - 'spec/models/namespace_spec.rb'
+ - 'spec/models/note_spec.rb'
+ - 'spec/models/notification_setting_spec.rb'
+ - 'spec/models/pages_domain_spec.rb'
+ - 'spec/models/project_services/bamboo_service_spec.rb'
+ - 'spec/models/project_services/jira_service_spec.rb'
+ - 'spec/models/project_services/pipelines_email_service_spec.rb'
+ - 'spec/models/project_services/teamcity_service_spec.rb'
+ - 'spec/models/project_spec.rb'
+ - 'spec/models/project_team_spec.rb'
+ - 'spec/models/release_spec.rb'
+ - 'spec/models/remote_mirror_spec.rb'
+ - 'spec/models/resource_milestone_event_spec.rb'
+ - 'spec/models/route_spec.rb'
+ - 'spec/models/sentry_issue_spec.rb'
+ - 'spec/models/service_spec.rb'
+ - 'spec/models/snippet_spec.rb'
+ - 'spec/models/upload_spec.rb'
+ - 'spec/models/user_preference_spec.rb'
+ - 'spec/models/user_spec.rb'
+ - 'spec/models/wiki_page/meta_spec.rb'
+ - 'spec/models/wiki_page_spec.rb'
+ - 'spec/policies/ci/build_policy_spec.rb'
+ - 'spec/policies/ci/pipeline_policy_spec.rb'
+ - 'spec/policies/ci/pipeline_schedule_policy_spec.rb'
+ - 'spec/policies/merge_request_policy_spec.rb'
+ - 'spec/policies/project_policy_spec.rb'
+ - 'spec/requests/api/boards_spec.rb'
+ - 'spec/requests/api/deployments_spec.rb'
+ - 'spec/requests/api/environments_spec.rb'
+ - 'spec/requests/api/graphql/mutations/merge_requests/set_labels_spec.rb'
+ - 'spec/requests/api/graphql/user_query_spec.rb'
+ - 'spec/requests/api/graphql_spec.rb'
+ - 'spec/requests/api/group_milestones_spec.rb'
+ - 'spec/requests/api/internal/base_spec.rb'
+ - 'spec/requests/api/issues/get_group_issues_spec.rb'
+ - 'spec/requests/api/jobs_spec.rb'
+ - 'spec/requests/api/labels_spec.rb'
+ - 'spec/requests/api/members_spec.rb'
+ - 'spec/requests/api/merge_request_diffs_spec.rb'
+ - 'spec/requests/api/merge_requests_spec.rb'
+ - 'spec/requests/api/pipeline_schedules_spec.rb'
+ - 'spec/requests/api/project_import_spec.rb'
+ - 'spec/requests/api/projects_spec.rb'
+ - 'spec/requests/api/runners_spec.rb'
+ - 'spec/requests/api/snippets_spec.rb'
+ - 'spec/requests/git_http_spec.rb'
+ - 'spec/requests/profiles/notifications_controller_spec.rb'
+ - 'spec/requests/projects/cycle_analytics_events_spec.rb'
+ - 'spec/serializers/environment_status_entity_spec.rb'
+ - 'spec/serializers/merge_request_poll_widget_entity_spec.rb'
+ - 'spec/serializers/merge_request_widget_entity_spec.rb'
+ - 'spec/services/ci/create_pipeline_service_spec.rb'
+ - 'spec/services/ci/register_job_service_spec.rb'
+ - 'spec/services/ci/retry_build_service_spec.rb'
+ - 'spec/services/deployments/after_create_service_spec.rb'
+ - 'spec/services/design_management/generate_image_versions_service_spec.rb'
+ - 'spec/services/draft_notes/destroy_service_spec.rb'
+ - 'spec/services/emails/confirm_service_spec.rb'
+ - 'spec/services/groups/destroy_service_spec.rb'
+ - 'spec/services/groups/import_export/import_service_spec.rb'
+ - 'spec/services/issuable/clone/attributes_rewriter_spec.rb'
+ - 'spec/services/issuable/common_system_notes_service_spec.rb'
+ - 'spec/services/issues/close_service_spec.rb'
+ - 'spec/services/issues/create_service_spec.rb'
+ - 'spec/services/issues/export_csv_service_spec.rb'
+ - 'spec/services/issues/reopen_service_spec.rb'
+ - 'spec/services/issues/update_service_spec.rb'
+ - 'spec/services/labels/promote_service_spec.rb'
+ - 'spec/services/members/destroy_service_spec.rb'
+ - 'spec/services/merge_requests/conflicts/list_service_spec.rb'
+ - 'spec/services/merge_requests/create_service_spec.rb'
+ - 'spec/services/merge_requests/merge_service_spec.rb'
+ - 'spec/services/merge_requests/post_merge_service_spec.rb'
+ - 'spec/services/merge_requests/refresh_service_spec.rb'
+ - 'spec/services/merge_requests/update_service_spec.rb'
+ - 'spec/services/milestones/destroy_service_spec.rb'
+ - 'spec/services/milestones/promote_service_spec.rb'
+ - 'spec/services/milestones/transfer_service_spec.rb'
+ - 'spec/services/notification_recipients/build_service_spec.rb'
+ - 'spec/services/notification_service_spec.rb'
+ - 'spec/services/projects/after_rename_service_spec.rb'
+ - 'spec/services/projects/create_service_spec.rb'
+ - 'spec/services/projects/fork_service_spec.rb'
+ - 'spec/services/projects/move_access_service_spec.rb'
+ - 'spec/services/projects/move_project_group_links_service_spec.rb'
+ - 'spec/services/projects/overwrite_project_service_spec.rb'
+ - 'spec/services/projects/propagate_service_template_spec.rb'
+ - 'spec/services/projects/unlink_fork_service_spec.rb'
+ - 'spec/services/projects/update_pages_service_spec.rb'
+ - 'spec/services/projects/update_service_spec.rb'
+ - 'spec/services/quick_actions/interpret_service_spec.rb'
+ - 'spec/services/system_hooks_service_spec.rb'
+ - 'spec/services/system_note_service_spec.rb'
+ - 'spec/services/system_notes/issuables_service_spec.rb'
+ - 'spec/services/todo_service_spec.rb'
+ - 'spec/services/todos/destroy/confidential_issue_service_spec.rb'
+ - 'spec/services/users/destroy_service_spec.rb'
+ - 'spec/services/users/repair_ldap_blocked_service_spec.rb'
+ - 'spec/support/helpers/cycle_analytics_helpers.rb'
+ - 'spec/support/helpers/jira_service_helper.rb'
+ - 'spec/support/helpers/login_helpers.rb'
+ - 'spec/support/helpers/notification_helpers.rb'
+ - 'spec/support/helpers/stub_action_cable_connection.rb'
+ - 'spec/support/helpers/stub_object_storage.rb'
+ - 'spec/support/migrations_helpers/cluster_helpers.rb'
+ - 'spec/support/migrations_helpers/track_untracked_uploads_helpers.rb'
+ - 'spec/support/shared_contexts/finders/group_projects_finder_shared_contexts.rb'
+ - 'spec/support/shared_contexts/mailers/notify_shared_context.rb'
+ - 'spec/support/shared_examples/controllers/githubish_import_controller_shared_examples.rb'
+ - 'spec/support/shared_examples/controllers/sessionless_auth_controller_shared_examples.rb'
+ - 'spec/support/shared_examples/features/editable_merge_request_shared_examples.rb'
+ - 'spec/support/shared_examples/lib/gitlab/ci/ci_trace_shared_examples.rb'
+ - 'spec/support/shared_examples/models/diff_note_after_commit_shared_examples.rb'
+ - 'spec/support/shared_examples/models/member_shared_examples.rb'
+ - 'spec/support/shared_examples/models/members_notifications_shared_example.rb'
+ - 'spec/support/shared_examples/models/mentionable_shared_examples.rb'
+ - 'spec/support/shared_examples/models/relative_positioning_shared_examples.rb'
+ - 'spec/support/shared_examples/models/slack_mattermost_notifications_shared_examples.rb'
+ - 'spec/support/shared_examples/models/update_project_statistics_shared_examples.rb'
+ - 'spec/support/shared_examples/models/with_uploads_shared_examples.rb'
+ - 'spec/support/shared_examples/quick_actions/issuable/issuable_quick_actions_shared_examples.rb'
+ - 'spec/support/shared_examples/quick_actions/merge_request/merge_quick_action_shared_examples.rb'
+ - 'spec/support/shared_examples/requests/api/boards_shared_examples.rb'
+ - 'spec/support/shared_examples/services/common_system_notes_shared_examples.rb'
+ - 'spec/support/shared_examples/services/issuable_shared_examples.rb'
+ - 'spec/tasks/gitlab/web_hook_rake_spec.rb'
+ - 'spec/views/projects/imports/new.html.haml_spec.rb'
+ - 'spec/views/projects/merge_requests/show.html.haml_spec.rb'
+ - 'spec/views/shared/_label_row.html.haml_spec.rb'
+ - 'spec/workers/migrate_external_diffs_worker_spec.rb'
+ - 'spec/workers/namespaceless_project_destroy_worker_spec.rb'
+ - 'spec/workers/pages_domain_verification_worker_spec.rb'
+ - 'spec/workers/propagate_service_template_worker_spec.rb'
+ - 'spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb'
+ - 'spec/workers/repository_cleanup_worker_spec.rb'
+ - 'spec/workers/repository_import_worker_spec.rb'
+ - 'spec/workers/repository_update_remote_mirror_worker_spec.rb'
diff --git a/.ruby-version b/.ruby-version
index 57cf282ebbc..338a5b5d8fe 100644
--- a/.ruby-version
+++ b/.ruby-version
@@ -1 +1 @@
-2.6.5
+2.6.6
diff --git a/CHANGELOG-EE.md b/CHANGELOG-EE.md
index 7f911dc4b3e..1fe9715d332 100644
--- a/CHANGELOG-EE.md
+++ b/CHANGELOG-EE.md
@@ -7,10 +7,6 @@ Please view this file on the master branch, on stable branches it's out of date.
- Do not set fallback mirror user.
-## 13.0.5 (2020-06-04)
-
-- No changes.
-
## 13.0.4 (2020-06-03)
- No changes.
@@ -19,10 +15,6 @@ Please view this file on the master branch, on stable branches it's out of date.
- No changes.
-## 13.0.2 (2020-05-28)
-
-- No changes.
-
## 13.0.1 (2020-05-27)
### Security (3 changes)
@@ -358,6 +350,33 @@ Please view this file on the master branch, on stable branches it's out of date.
- Translate unauthenticated user string for Audit Event. !31856 (Sashi Kumar)
+## 12.10.11 (2020-06-10)
+
+### Security (1 change)
+
+- Do not set fallback mirror user.
+
+
+## 12.10.8 (2020-05-28)
+
+### Fixed (1 change)
+
+- Geo: Fix empty synchronisation status when nothing is synchronised. !30710
+
+
+## 12.10.7 (2020-05-27)
+
+### Security (3 changes)
+
+- Change the mirror user along with pull mirror settings.
+- Allow only users with a verified email to be member of a group when the group has restricted membership based on email domain.
+- Do not auto-confirm email in Trial registration.
+
+
+## 12.10.6 (2020-05-15)
+
+- No changes.
+
## 12.10.5 (2020-05-13)
### Fixed (1 change)
@@ -428,6 +447,22 @@ Please view this file on the master branch, on stable branches it's out of date.
- Add health status counts to usage data. !28964
+## 12.9.10 (2020-06-10)
+
+### Security (1 change)
+
+- Do not set fallback mirror user.
+
+
+## 12.9.8 (2020-05-27)
+
+### Security (3 changes)
+
+- Change the mirror user along with pull mirror settings.
+- Allow only users with a verified email to be member of a group when the group has restricted membership based on email domain.
+- Do not auto-confirm email in Trial registration.
+
+
## 12.9.6 (2020-05-05)
- No changes.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a10f9b92844..da2f5700b3d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,20 +6,6 @@ entry.
- No changes.
-## 13.0.5 (2020-06-04)
-
-### Fixed (4 changes)
-
-- Fix NoMethodError by using the correct method to report exceptions to Sentry. !33260
-- Fix bug in snippets updating only file_name or content. !33375
-- Fix ambiguous string concatenation on CleanupProjectsWithMissingNamespace. !33497
-- Fix linking alerts to created issues for the Generic alerts intergration. !33647
-
-### Other (1 change)
-
-- Update GitLab Workhorse to v8.31.2. !33818
-
-
## 13.0.4 (2020-06-03)
### Security (1 change)
@@ -41,10 +27,6 @@ entry.
- Fix close issue when user created the issue. !33294
-## 13.0.2 (2020-05-28)
-
-- No changes.
-
## 13.0.1 (2020-05-27)
### Security (12 changes)
@@ -632,6 +614,49 @@ entry.
- Use visitUrl in Alert management. !32414
+## 12.10.11 (2020-06-10)
+
+- No changes.
+
+## 12.10.8 (2020-05-28)
+
+### Fixed (2 changes)
+
+- Fix Geo replication for design thumbnails. !32703
+- Fix 404s downloading build artifacts. !32741
+
+
+## 12.10.7 (2020-05-27)
+
+### Security (14 changes)
+
+- Add an extra validation to Static Site Editor payload.
+- Hide EKS secret key in admin integrations settings.
+- Added data integrity check before updating a deploy key.
+- Display only verified emails on notifications and profile page.
+- Disable caching on repo/blobs/[sha]/raw endpoint.
+- Require confirmed email address for GitLab OAuth authentication.
+- Kubernetes cluster details page no longer exposes Service Token.
+- Fix confirming unverified emails with soft email confirmation flow enabled.
+- Disallow user to control PUT request using mermaid markdown in issue description.
+- Check forked project permissions before allowing fork.
+- Limit memory footprint of a command that generates ZIP artifacts metadata.
+- Fix file enuming using Group Import.
+- Prevent XSS in the monitoring dashboard.
+- Use `gsub` instead of the Ruby `%` operator to perform variable substitution in Prometheus proxy API.
+
+
+## 12.10.6 (2020-05-15)
+
+### Fixed (5 changes)
+
+- Fix duplicate index removal on ci_pipelines.project_id. !31043
+- Fix 500 on creating an invalid domains and verification. !31190
+- Fix incorrect number of errors returned when querying sentry errors. !31252
+- Add instance column to services table if it's missing. !31631
+- Fix incorrect regex used in FileUploader#extract_dynamic_path. !32271
+
+
## 12.10.5 (2020-05-13)
### Added (1 change)
@@ -1121,6 +1146,29 @@ entry.
- Remove store_mentions! in Snippets::CreateService. !29581 (Sashi Kumar)
+## 12.9.10 (2020-06-10)
+
+- No changes.
+
+## 12.9.8 (2020-05-27)
+
+### Security (13 changes)
+
+- Hide EKS secret key in admin integrations settings.
+- Added data integrity check before updating a deploy key.
+- Display only verified emails on notifications and profile page.
+- Disable caching on repo/blobs/[sha]/raw endpoint.
+- Require confirmed email address for GitLab OAuth authentication.
+- Kubernetes cluster details page no longer exposes Service Token.
+- Fix confirming unverified emails with soft email confirmation flow enabled.
+- Disallow user to control PUT request using mermaid markdown in issue description.
+- Check forked project permissions before allowing fork.
+- Limit memory footprint of a command that generates ZIP artifacts metadata.
+- Fix file enuming using Group Import.
+- Prevent XSS in the monitoring dashboard.
+- Use `gsub` instead of the Ruby `%` operator to perform variable substitution in Prometheus proxy API.
+
+
## 12.9.6 (2020-05-05)
### Fixed (1 change)
diff --git a/Dangerfile b/Dangerfile
index 7879c14b31e..cc6ebc27d4e 100644
--- a/Dangerfile
+++ b/Dangerfile
@@ -7,8 +7,16 @@ danger.import_plugin('danger/plugins/helper.rb')
danger.import_plugin('danger/plugins/roulette.rb')
danger.import_plugin('danger/plugins/changelog.rb')
-unless helper.release_automation?
- GitlabDanger.new(helper.gitlab_helper).rule_names.each do |file|
- danger.import_dangerfile(path: File.join('danger', file))
- end
+return if helper.release_automation?
+
+gitlab_danger = GitlabDanger.new(helper.gitlab_helper)
+
+gitlab_danger.rule_names.each do |file|
+ danger.import_dangerfile(path: File.join('danger', file))
+end
+
+anything_to_post = status_report.values.any? { |data| data.any? }
+
+if gitlab_danger.ci? && anything_to_post
+ markdown("**If needed, you can retry the [`danger-review` job](#{ENV['CI_JOB_URL']}) that generated this comment.**")
end
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 6fe535b5ba5..9e6fba6c2ce 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-13.0.6
+203182ffe94da165d4ff81332b1b3fff9771e631
diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION
index 67aee23940e..ac565bc1cab 100644
--- a/GITLAB_SHELL_VERSION
+++ b/GITLAB_SHELL_VERSION
@@ -1 +1 @@
-13.2.0
+13.3.0
diff --git a/GITLAB_WORKHORSE_VERSION b/GITLAB_WORKHORSE_VERSION
index 594580cb92f..13afb01d493 100644
--- a/GITLAB_WORKHORSE_VERSION
+++ b/GITLAB_WORKHORSE_VERSION
@@ -1 +1 @@
-8.31.2
+8.35.0
diff --git a/Gemfile b/Gemfile
index 9c8c5e8b30d..5477ee3d181 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,6 +1,6 @@
source 'https://rubygems.org'
-gem 'rails', '~> 6.0.3'
+gem 'rails', '~> 6.0.3.1'
gem 'bootsnap', '~> 1.4.6'
@@ -43,8 +43,7 @@ gem 'omniauth-shibboleth', '~> 1.3.0'
gem 'omniauth-twitter', '~> 1.4'
gem 'omniauth_crowd', '~> 2.2.0'
gem 'omniauth-authentiq', '~> 0.3.3'
-gem 'omniauth_openid_connect', '~> 0.3.3'
-gem "omniauth-ultraauth", '~> 0.0.2'
+gem 'omniauth_openid_connect', '~> 0.3.5'
gem 'omniauth-salesforce', '~> 1.0.5'
gem 'rack-oauth2', '~> 1.9.3'
gem 'jwt', '~> 2.1.0'
@@ -64,7 +63,7 @@ gem 'attr_encrypted', '~> 3.1.0'
gem 'u2f', '~> 0.2.1'
# GitLab Pages
-gem 'validates_hostname', '~> 1.0.6'
+gem 'validates_hostname', '~> 1.0.10'
gem 'rubyzip', '~> 2.0.0', require: 'zip'
# GitLab Pages letsencrypt support
gem 'acme-client', '~> 2.0.5'
@@ -113,14 +112,14 @@ gem 'fog-aws', '~> 3.5'
# 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'
-gem 'fog-google', '~> 1.9'
+gem 'fog-google', '~> 1.10'
gem 'fog-local', '~> 0.6'
gem 'fog-openstack', '~> 1.0'
gem 'fog-rackspace', '~> 0.1.1'
gem 'fog-aliyun', '~> 0.3'
# for Google storage
-gem 'google-api-client', '~> 0.23'
+gem 'google-api-client', '~> 0.33'
# for aws storage
gem 'unf', '~> 0.1.4'
@@ -343,7 +342,7 @@ group :development do
end
group :development, :test do
- gem 'bullet', '~> 6.0.2', require: !!ENV['ENABLE_BULLET']
+ gem 'bullet', '~> 6.0.2'
gem 'pry-byebug', '~> 3.5.1', platform: :mri
gem 'pry-rails', '~> 0.3.9'
@@ -362,10 +361,10 @@ group :development, :test do
gem 'spring', '~> 2.0.0'
gem 'spring-commands-rspec', '~> 1.0.4'
- gem 'gitlab-styles', '~> 3.2.0', require: false
+ gem 'gitlab-styles', '~> 4.2.0', require: false
# Pin these dependencies, otherwise a new rule could break the CI pipelines
- gem 'rubocop', '~> 0.74.0'
- gem 'rubocop-performance', '~> 1.4.1'
+ gem 'rubocop', '~> 0.82.0'
+ gem 'rubocop-performance', '~> 1.5.2'
gem 'rubocop-rspec', '~> 1.37.0'
gem 'scss_lint', '~> 0.56.0', require: false
@@ -403,7 +402,6 @@ group :test do
gem 'shoulda-matchers', '~> 4.0.1', require: false
gem 'email_spec', '~> 2.2.0'
- gem 'json-schema', '~> 2.8.0'
gem 'webmock', '~> 3.5.1'
gem 'rails-controller-testing'
gem 'concurrent-ruby', '~> 1.1'
@@ -454,7 +452,7 @@ group :ed25519 do
end
# Gitaly GRPC protocol definitions
-gem 'gitaly', '~> 13.0.0.pre.rc1'
+gem 'gitaly', '~> 13.1.0.pre.rc1'
gem 'grpc', '~> 1.24.0'
@@ -498,3 +496,4 @@ gem 'valid_email', '~> 0.1'
# JSON
gem 'json', '~> 2.3.0'
+gem 'json-schema', '~> 2.8.0'
diff --git a/Gemfile.lock b/Gemfile.lock
index ffff576e8b0..319c4df3f9d 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -6,59 +6,59 @@ GEM
ace-rails-ap (4.1.2)
acme-client (2.0.5)
faraday (~> 0.9, >= 0.9.1)
- actioncable (6.0.3)
- actionpack (= 6.0.3)
+ actioncable (6.0.3.1)
+ actionpack (= 6.0.3.1)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
- actionmailbox (6.0.3)
- actionpack (= 6.0.3)
- activejob (= 6.0.3)
- activerecord (= 6.0.3)
- activestorage (= 6.0.3)
- activesupport (= 6.0.3)
+ actionmailbox (6.0.3.1)
+ actionpack (= 6.0.3.1)
+ activejob (= 6.0.3.1)
+ activerecord (= 6.0.3.1)
+ activestorage (= 6.0.3.1)
+ activesupport (= 6.0.3.1)
mail (>= 2.7.1)
- actionmailer (6.0.3)
- actionpack (= 6.0.3)
- actionview (= 6.0.3)
- activejob (= 6.0.3)
+ actionmailer (6.0.3.1)
+ actionpack (= 6.0.3.1)
+ actionview (= 6.0.3.1)
+ activejob (= 6.0.3.1)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
- actionpack (6.0.3)
- actionview (= 6.0.3)
- activesupport (= 6.0.3)
+ actionpack (6.0.3.1)
+ actionview (= 6.0.3.1)
+ activesupport (= 6.0.3.1)
rack (~> 2.0, >= 2.0.8)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
- actiontext (6.0.3)
- actionpack (= 6.0.3)
- activerecord (= 6.0.3)
- activestorage (= 6.0.3)
- activesupport (= 6.0.3)
+ actiontext (6.0.3.1)
+ actionpack (= 6.0.3.1)
+ activerecord (= 6.0.3.1)
+ activestorage (= 6.0.3.1)
+ activesupport (= 6.0.3.1)
nokogiri (>= 1.8.5)
- actionview (6.0.3)
- activesupport (= 6.0.3)
+ actionview (6.0.3.1)
+ activesupport (= 6.0.3.1)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
- activejob (6.0.3)
- activesupport (= 6.0.3)
+ activejob (6.0.3.1)
+ activesupport (= 6.0.3.1)
globalid (>= 0.3.6)
- activemodel (6.0.3)
- activesupport (= 6.0.3)
- activerecord (6.0.3)
- activemodel (= 6.0.3)
- activesupport (= 6.0.3)
+ activemodel (6.0.3.1)
+ activesupport (= 6.0.3.1)
+ activerecord (6.0.3.1)
+ activemodel (= 6.0.3.1)
+ activesupport (= 6.0.3.1)
activerecord-explain-analyze (0.1.0)
activerecord (>= 4)
pg
- activestorage (6.0.3)
- actionpack (= 6.0.3)
- activejob (= 6.0.3)
- activerecord (= 6.0.3)
+ activestorage (6.0.3.1)
+ actionpack (= 6.0.3.1)
+ activejob (= 6.0.3.1)
+ activerecord (= 6.0.3.1)
marcel (~> 0.3.1)
- activesupport (6.0.3)
+ activesupport (6.0.3.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
@@ -286,7 +286,7 @@ GEM
factory_bot_rails (5.1.0)
factory_bot (~> 5.1.0)
railties (>= 4.2.0)
- faraday (0.15.4)
+ faraday (0.17.3)
multipart-post (>= 1.2, < 3)
faraday-http-cache (2.0.0)
faraday (~> 0.8)
@@ -330,11 +330,11 @@ GEM
excon (~> 0.58)
formatador (~> 0.2)
mime-types
- fog-google (1.9.1)
+ fog-google (1.10.0)
fog-core (<= 2.1.0)
fog-json (~> 1.2)
fog-xml (~> 0.1.0)
- google-api-client (~> 0.23.0)
+ google-api-client (>= 0.32, < 0.34)
fog-json (1.2.0)
fog-core
multi_json (~> 1.10)
@@ -377,7 +377,7 @@ GEM
po_to_json (>= 1.0.0)
rails (>= 3.2.0)
git (1.5.0)
- gitaly (13.0.0.pre.rc1)
+ gitaly (13.1.0.pre.rc1)
grpc (~> 1.0)
github-markup (1.7.0)
gitlab-chronic (0.10.5)
@@ -400,11 +400,11 @@ GEM
gitlab-puma (>= 2.7, < 5)
gitlab-sidekiq-fetcher (0.5.2)
sidekiq (~> 5)
- gitlab-styles (3.2.0)
- rubocop (~> 0.74.0)
+ gitlab-styles (4.2.0)
+ rubocop (~> 0.82.0)
rubocop-gitlab-security (~> 0.1.0)
- rubocop-performance (~> 1.4.1)
- rubocop-rails (~> 2.0)
+ rubocop-performance (~> 1.5.2)
+ rubocop-rails (~> 2.5)
rubocop-rspec (~> 1.36)
gitlab_chronic_duration (0.10.6.2)
numerizer (~> 0.2)
@@ -419,23 +419,24 @@ GEM
actionpack (>= 3.0)
multi_json
request_store (>= 1.0)
- google-api-client (0.23.4)
+ google-api-client (0.33.2)
addressable (~> 2.5, >= 2.5.1)
- googleauth (>= 0.5, < 0.7.0)
+ googleauth (~> 0.9)
httpclient (>= 2.8.1, < 3.0)
- mime-types (~> 3.0)
+ mini_mime (~> 1.0)
representable (~> 3.0)
retriable (>= 2.0, < 4.0)
+ signet (~> 0.12)
google-protobuf (3.8.0)
googleapis-common-protos-types (1.0.4)
google-protobuf (~> 3.0)
- googleauth (0.6.6)
- faraday (~> 0.12)
+ googleauth (0.12.0)
+ faraday (>= 0.17.3, < 2.0)
jwt (>= 1.4, < 3.0)
- memoist (~> 0.12)
+ memoist (~> 0.16)
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
- signet (~> 0.7)
+ signet (~> 0.14)
gpgme (2.0.20)
mini_portile2 (~> 2.3)
grape (1.1.0)
@@ -529,7 +530,7 @@ GEM
mime-types (~> 3.0)
multi_xml (>= 0.5.2)
httpclient (2.8.3)
- i18n (1.8.2)
+ i18n (1.8.3)
concurrent-ruby (~> 1.0)
i18n_data (0.8.0)
icalendar (2.4.1)
@@ -604,7 +605,7 @@ GEM
ruby_dep (~> 1.2)
locale (2.1.2)
lockbox (0.3.3)
- lograge (0.10.0)
+ lograge (0.11.2)
actionpack (>= 4)
activesupport (>= 4)
railties (>= 4)
@@ -661,8 +662,8 @@ GEM
shellany (~> 0.0)
numerizer (0.2.0)
oauth (0.5.4)
- oauth2 (1.4.1)
- faraday (>= 0.8, < 0.16.0)
+ oauth2 (1.4.4)
+ faraday (>= 0.8, < 2.0)
jwt (>= 1.0, < 3.0)
multi_json (~> 1.3)
multi_xml (~> 0.5)
@@ -722,13 +723,11 @@ GEM
omniauth-twitter (1.4.0)
omniauth-oauth (~> 1.1)
rack
- omniauth-ultraauth (0.0.2)
- omniauth_openid_connect (~> 0.3.0)
omniauth_crowd (2.2.3)
activesupport
nokogiri (>= 1.4.4)
omniauth (~> 1.0)
- omniauth_openid_connect (0.3.3)
+ omniauth_openid_connect (0.3.5)
addressable (~> 2.5)
omniauth (~> 1.9)
openid_connect (~> 1.1)
@@ -750,7 +749,7 @@ GEM
orm_adapter (0.5.0)
os (1.0.0)
parallel (1.19.1)
- parser (2.7.0.4)
+ parser (2.7.1.2)
ast (~> 2.4.0)
parslet (1.8.2)
peek (1.1.0)
@@ -803,20 +802,20 @@ GEM
rack-test (1.1.0)
rack (>= 1.0, < 3)
rack-timeout (0.5.1)
- rails (6.0.3)
- actioncable (= 6.0.3)
- actionmailbox (= 6.0.3)
- actionmailer (= 6.0.3)
- actionpack (= 6.0.3)
- actiontext (= 6.0.3)
- actionview (= 6.0.3)
- activejob (= 6.0.3)
- activemodel (= 6.0.3)
- activerecord (= 6.0.3)
- activestorage (= 6.0.3)
- activesupport (= 6.0.3)
+ rails (6.0.3.1)
+ actioncable (= 6.0.3.1)
+ actionmailbox (= 6.0.3.1)
+ actionmailer (= 6.0.3.1)
+ actionpack (= 6.0.3.1)
+ actiontext (= 6.0.3.1)
+ actionview (= 6.0.3.1)
+ activejob (= 6.0.3.1)
+ activemodel (= 6.0.3.1)
+ activerecord (= 6.0.3.1)
+ activestorage (= 6.0.3.1)
+ activesupport (= 6.0.3.1)
bundler (>= 1.3.0)
- railties (= 6.0.3)
+ railties (= 6.0.3.1)
sprockets-rails (>= 2.0.0)
rails-controller-testing (1.0.4)
actionpack (>= 5.0.1.x)
@@ -830,9 +829,9 @@ GEM
rails-i18n (6.0.0)
i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 7)
- railties (6.0.3)
- actionpack (= 6.0.3)
- activesupport (= 6.0.3)
+ railties (6.0.3.1)
+ actionpack (= 6.0.3.1)
+ activesupport (= 6.0.3.1)
method_source
rake (>= 0.8.7)
thor (>= 0.20.3, < 2.0)
@@ -888,6 +887,7 @@ GEM
mime-types (>= 1.16, < 4.0)
netrc (~> 0.8)
retriable (3.1.2)
+ rexml (3.2.4)
rinku (2.0.0)
rotp (2.1.2)
rouge (3.19.0)
@@ -931,18 +931,20 @@ GEM
pg
rails
sqlite3
- rubocop (0.74.0)
+ rubocop (0.82.0)
jaro_winkler (~> 1.5.1)
parallel (~> 1.10)
- parser (>= 2.6)
+ parser (>= 2.7.0.1)
rainbow (>= 2.2.2, < 4.0)
+ rexml
ruby-progressbar (~> 1.7)
- unicode-display_width (>= 1.4.0, < 1.7)
+ unicode-display_width (>= 1.4.0, < 2.0)
rubocop-gitlab-security (0.1.1)
rubocop (>= 0.51)
- rubocop-performance (1.4.1)
+ rubocop-performance (1.5.2)
rubocop (>= 0.71.0)
- rubocop-rails (2.4.0)
+ rubocop-rails (2.5.2)
+ activesupport
rack (>= 1.1)
rubocop (>= 0.72.0)
rubocop-rspec (1.37.0)
@@ -1009,9 +1011,9 @@ GEM
sidekiq-cron (1.0.4)
fugit (~> 1.1)
sidekiq (>= 4.2.1)
- signet (0.11.0)
+ signet (0.14.0)
addressable (~> 2.3)
- faraday (~> 0.9)
+ faraday (>= 0.17.3, < 2.0)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
simple_po_parser (1.1.2)
@@ -1083,7 +1085,7 @@ GEM
unf (0.1.4)
unf_ext
unf_ext (0.0.7.5)
- unicode-display_width (1.6.0)
+ unicode-display_width (1.7.0)
unicode_plot (0.0.4)
enumerable-statistics (>= 2.0.1)
unicode_utils (1.4.0)
@@ -1113,7 +1115,7 @@ GEM
validate_url (1.0.8)
activemodel (>= 3.0.0)
public_suffix
- validates_hostname (1.0.6)
+ validates_hostname (1.0.10)
activerecord (>= 3.0)
activesupport (>= 3.0)
version_sorter (2.2.4)
@@ -1223,7 +1225,7 @@ DEPENDENCIES
fog-aliyun (~> 0.3)
fog-aws (~> 3.5)
fog-core (= 2.1.0)
- fog-google (~> 1.9)
+ fog-google (~> 1.10)
fog-local (~> 0.6)
fog-openstack (~> 1.0)
fog-rackspace (~> 0.1.1)
@@ -1234,7 +1236,7 @@ DEPENDENCIES
gettext (~> 3.2.2)
gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.3)
- gitaly (~> 13.0.0.pre.rc1)
+ gitaly (~> 13.1.0.pre.rc1)
github-markup (~> 1.7.0)
gitlab-chronic (~> 0.10.5)
gitlab-labkit (= 0.12.0)
@@ -1245,11 +1247,11 @@ DEPENDENCIES
gitlab-puma (~> 4.3.3.gitlab.2)
gitlab-puma_worker_killer (~> 0.1.1.gitlab.1)
gitlab-sidekiq-fetcher (= 0.5.2)
- gitlab-styles (~> 3.2.0)
+ gitlab-styles (~> 4.2.0)
gitlab_chronic_duration (~> 0.10.6.2)
gitlab_omniauth-ldap (~> 2.1.1)
gon (~> 6.2)
- google-api-client (~> 0.23)
+ google-api-client (~> 0.33)
google-protobuf (~> 3.8.0)
gpgme (~> 2.0.19)
grape (~> 1.1.0)
@@ -1317,9 +1319,8 @@ DEPENDENCIES
omniauth-saml (~> 1.10)
omniauth-shibboleth (~> 1.3.0)
omniauth-twitter (~> 1.4)
- omniauth-ultraauth (~> 0.0.2)
omniauth_crowd (~> 2.2.0)
- omniauth_openid_connect (~> 0.3.3)
+ omniauth_openid_connect (~> 0.3.5)
org-ruby (~> 0.9.12)
parallel (~> 1.19)
peek (~> 1.1)
@@ -1335,7 +1336,7 @@ DEPENDENCIES
rack-oauth2 (~> 1.9.3)
rack-proxy (~> 0.6.0)
rack-timeout
- rails (~> 6.0.3)
+ rails (~> 6.0.3.1)
rails-controller-testing
rails-i18n (~> 6.0)
rainbow (~> 3.0)
@@ -1358,8 +1359,8 @@ DEPENDENCIES
rspec-retry (~> 0.6.1)
rspec_junit_formatter
rspec_profiling (~> 0.0.5)
- rubocop (~> 0.74.0)
- rubocop-performance (~> 1.4.1)
+ rubocop (~> 0.82.0)
+ rubocop-performance (~> 1.5.2)
rubocop-rspec (~> 1.37.0)
ruby-fogbugz (~> 0.2.1)
ruby-prof (~> 1.3.0)
@@ -1400,7 +1401,7 @@ DEPENDENCIES
unicorn-worker-killer (~> 0.4.4)
unleash (~> 0.1.5)
valid_email (~> 0.1)
- validates_hostname (~> 1.0.6)
+ validates_hostname (~> 1.0.10)
version_sorter (~> 2.2.4)
vmstat (~> 2.3.0)
webmock (~> 3.5.1)
diff --git a/app/assets/images/aws_logo.svg b/app/assets/images/aws_logo.svg
new file mode 100644
index 00000000000..e028fd1b1c0
--- /dev/null
+++ b/app/assets/images/aws_logo.svg
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 19.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
+ viewBox="0 0 304 182" style="enable-background:new 0 0 304 182;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill:#252F3E;}
+ .st1{fill-rule:evenodd;clip-rule:evenodd;fill:#FF9900;}
+</style>
+<g>
+ <path class="st0" d="M86.4,66.4c0,3.7,0.4,6.7,1.1,8.9c0.8,2.2,1.8,4.6,3.2,7.2c0.5,0.8,0.7,1.6,0.7,2.3c0,1-0.6,2-1.9,3l-6.3,4.2
+ c-0.9,0.6-1.8,0.9-2.6,0.9c-1,0-2-0.5-3-1.4C76.2,90,75,88.4,74,86.8c-1-1.7-2-3.6-3.1-5.9c-7.8,9.2-17.6,13.8-29.4,13.8
+ c-8.4,0-15.1-2.4-20-7.2c-4.9-4.8-7.4-11.2-7.4-19.2c0-8.5,3-15.4,9.1-20.6c6.1-5.2,14.2-7.8,24.5-7.8c3.4,0,6.9,0.3,10.6,0.8
+ c3.7,0.5,7.5,1.3,11.5,2.2v-7.3c0-7.6-1.6-12.9-4.7-16c-3.2-3.1-8.6-4.6-16.3-4.6c-3.5,0-7.1,0.4-10.8,1.3c-3.7,0.9-7.3,2-10.8,3.4
+ c-1.6,0.7-2.8,1.1-3.5,1.3c-0.7,0.2-1.2,0.3-1.6,0.3c-1.4,0-2.1-1-2.1-3.1v-4.9c0-1.6,0.2-2.8,0.7-3.5c0.5-0.7,1.4-1.4,2.8-2.1
+ c3.5-1.8,7.7-3.3,12.6-4.5c4.9-1.3,10.1-1.9,15.6-1.9c11.9,0,20.6,2.7,26.2,8.1c5.5,5.4,8.3,13.6,8.3,24.6V66.4z M45.8,81.6
+ c3.3,0,6.7-0.6,10.3-1.8c3.6-1.2,6.8-3.4,9.5-6.4c1.6-1.9,2.8-4,3.4-6.4c0.6-2.4,1-5.3,1-8.7v-4.2c-2.9-0.7-6-1.3-9.2-1.7
+ c-3.2-0.4-6.3-0.6-9.4-0.6c-6.7,0-11.6,1.3-14.9,4c-3.3,2.7-4.9,6.5-4.9,11.5c0,4.7,1.2,8.2,3.7,10.6
+ C37.7,80.4,41.2,81.6,45.8,81.6z M126.1,92.4c-1.8,0-3-0.3-3.8-1c-0.8-0.6-1.5-2-2.1-3.9L96.7,10.2c-0.6-2-0.9-3.3-0.9-4
+ c0-1.6,0.8-2.5,2.4-2.5h9.8c1.9,0,3.2,0.3,3.9,1c0.8,0.6,1.4,2,2,3.9l16.8,66.2l15.6-66.2c0.5-2,1.1-3.3,1.9-3.9c0.8-0.6,2.2-1,4-1
+ h8c1.9,0,3.2,0.3,4,1c0.8,0.6,1.5,2,1.9,3.9l15.8,67l17.3-67c0.6-2,1.3-3.3,2-3.9c0.8-0.6,2.1-1,3.9-1h9.3c1.6,0,2.5,0.8,2.5,2.5
+ c0,0.5-0.1,1-0.2,1.6c-0.1,0.6-0.3,1.4-0.7,2.5l-24.1,77.3c-0.6,2-1.3,3.3-2.1,3.9c-0.8,0.6-2.1,1-3.8,1h-8.6c-1.9,0-3.2-0.3-4-1
+ c-0.8-0.7-1.5-2-1.9-4L156,23l-15.4,64.4c-0.5,2-1.1,3.3-1.9,4c-0.8,0.7-2.2,1-4,1H126.1z M254.6,95.1c-5.2,0-10.4-0.6-15.4-1.8
+ c-5-1.2-8.9-2.5-11.5-4c-1.6-0.9-2.7-1.9-3.1-2.8c-0.4-0.9-0.6-1.9-0.6-2.8v-5.1c0-2.1,0.8-3.1,2.3-3.1c0.6,0,1.2,0.1,1.8,0.3
+ c0.6,0.2,1.5,0.6,2.5,1c3.4,1.5,7.1,2.7,11,3.5c4,0.8,7.9,1.2,11.9,1.2c6.3,0,11.2-1.1,14.6-3.3c3.4-2.2,5.2-5.4,5.2-9.5
+ c0-2.8-0.9-5.1-2.7-7c-1.8-1.9-5.2-3.6-10.1-5.2L246,52c-7.3-2.3-12.7-5.7-16-10.2c-3.3-4.4-5-9.3-5-14.5c0-4.2,0.9-7.9,2.7-11.1
+ c1.8-3.2,4.2-6,7.2-8.2c3-2.3,6.4-4,10.4-5.2c4-1.2,8.2-1.7,12.6-1.7c2.2,0,4.5,0.1,6.7,0.4c2.3,0.3,4.4,0.7,6.5,1.1
+ c2,0.5,3.9,1,5.7,1.6c1.8,0.6,3.2,1.2,4.2,1.8c1.4,0.8,2.4,1.6,3,2.5c0.6,0.8,0.9,1.9,0.9,3.3v4.7c0,2.1-0.8,3.2-2.3,3.2
+ c-0.8,0-2.1-0.4-3.8-1.2c-5.7-2.6-12.1-3.9-19.2-3.9c-5.7,0-10.2,0.9-13.3,2.8c-3.1,1.9-4.7,4.8-4.7,8.9c0,2.8,1,5.2,3,7.1
+ c2,1.9,5.7,3.8,11,5.5l14.2,4.5c7.2,2.3,12.4,5.5,15.5,9.6c3.1,4.1,4.6,8.8,4.6,14c0,4.3-0.9,8.2-2.6,11.6
+ c-1.8,3.4-4.2,6.4-7.3,8.8c-3.1,2.5-6.8,4.3-11.1,5.6C264.4,94.4,259.7,95.1,254.6,95.1z"/>
+ <g>
+ <path class="st1" d="M273.5,143.7c-32.9,24.3-80.7,37.2-121.8,37.2c-57.6,0-109.5-21.3-148.7-56.7c-3.1-2.8-0.3-6.6,3.4-4.4
+ c42.4,24.6,94.7,39.5,148.8,39.5c36.5,0,76.6-7.6,113.5-23.2C274.2,133.6,278.9,139.7,273.5,143.7z"/>
+ <path class="st1" d="M287.2,128.1c-4.2-5.4-27.8-2.6-38.5-1.3c-3.2,0.4-3.7-2.4-0.8-4.5c18.8-13.2,49.7-9.4,53.3-5
+ c3.6,4.5-1,35.4-18.6,50.2c-2.7,2.3-5.3,1.1-4.1-1.9C282.5,155.7,291.4,133.4,287.2,128.1z"/>
+ </g>
+</g>
+</svg>
diff --git a/app/assets/images/experienced.svg b/app/assets/images/experienced.svg
new file mode 100644
index 00000000000..1c93cfcf1ee
--- /dev/null
+++ b/app/assets/images/experienced.svg
@@ -0,0 +1 @@
+<svg height="82" viewBox="0 0 78 82" width="78" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><g fill-rule="nonzero"><path d="m2.12 42c-.08 1-.12 2-.12 3 0 20.43 16.57 37 37 37s37-16.57 37-37c0-1-.04-2-.12-3-1.53 19.03-17.46 34-36.88 34s-35.35-14.97-36.88-34z" fill="#000" fill-opacity=".03"/><path d="m39 78c-21.54 0-39-17.46-39-39s17.46-39 39-39 39 17.46 39 39-17.46 39-39 39zm0-4c19.33 0 35-15.67 35-35s-15.67-35-35-35-35 15.67-35 35 15.67 35 35 35z" fill="#eee"/><path d="m44 31-2.5-3-2.5 3-2.5-3-2.5 3-2.5-3-2.5 3h-2.72c2.65-4.2 7.36-7 12.72-7s10.07 2.8 12.72 7h-2.72l-2.5-3z" fill="#e1dbf2"/><path d="m39 57c-9.4 0-17-7.6-17-17s7.6-17 17-17 17 7.6 17 17-7.6 17-17 17zm0-4c7.18 0 13-5.82 13-13s-5.82-13-13-13-13 5.82-13 13 5.82 13 13 13z" fill="#e1dbf2"/></g><g fill="#e2ba3e" stroke="#fff" transform="translate(14 18)"><path d="m8.5 12.75-4.99617464 2.6266445.95418445-5.56332227-4.0419902-3.93996668 5.58589307-.81167778 2.49808732-5.06167777 2.4980873 5.06167777 5.5858931.81167778-4.0419902 3.93996668.9541844 5.56332227z"/><path d="m24.5 12.75-4.9961746 2.6266445.9541844-5.56332227-4.0419902-3.93996668 5.5858931-.81167778 2.4980873-5.06167777 2.4980873 5.06167777 5.5858931.81167778-4.0419902 3.93996668.9541844 5.56332227z"/><path d="m40.5 12.75-4.9961746 2.6266445.9541844-5.56332227-4.0419902-3.93996668 5.5858931-.81167778 2.4980873-5.06167777 2.4980873 5.06167777 5.5858931.81167778-4.0419902 3.93996668.9541844 5.56332227z"/></g><path d="m35 45h8c0 2.2-1.8 4-4 4s-4-1.8-4-4zm-1.5-2c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm11 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z" fill="#6b4fbb" fill-rule="nonzero"/></g></svg> \ No newline at end of file
diff --git a/app/assets/images/learn-gitlab-avatar.jpg b/app/assets/images/learn-gitlab-avatar.jpg
new file mode 100644
index 00000000000..65ec29444cb
--- /dev/null
+++ b/app/assets/images/learn-gitlab-avatar.jpg
Binary files differ
diff --git a/app/assets/images/novice.svg b/app/assets/images/novice.svg
new file mode 100644
index 00000000000..c6744fa4550
--- /dev/null
+++ b/app/assets/images/novice.svg
@@ -0,0 +1 @@
+<svg width="78" height="82" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path d="M2.12 42C2.04 43 2 44 2 45c0 20.43 16.57 37 37 37s37-16.57 37-37c0-1-.04-2-.12-3C74.35 61.03 58.42 76 39 76S3.65 61.03 2.12 42z" fill-opacity=".03" fill="#000" fill-rule="nonzero"/><path d="M39 78C17.46 78 0 60.54 0 39S17.46 0 39 0s39 17.46 39 39-17.46 39-39 39zm0-4c19.33 0 35-15.67 35-35S58.33 4 39 4 4 19.67 4 39s15.67 35 35 35z" fill="#EEE" fill-rule="nonzero"/><path d="M44 31l-2.5-3-2.5 3-2.5-3-2.5 3-2.5-3-2.5 3h-2.72c2.65-4.2 7.36-7 12.72-7s10.07 2.8 12.72 7H49l-2.5-3-2.5 3z" fill="#E1DBF2" fill-rule="nonzero"/><path d="M39 57c-9.4 0-17-7.6-17-17s7.6-17 17-17 17 7.6 17 17-7.6 17-17 17zm0-4c7.18 0 13-5.82 13-13s-5.82-13-13-13-13 5.82-13 13 5.82 13 13 13z" fill="#E1DBF2" fill-rule="nonzero"/><g transform="translate(20 13)"><path d="M5.731 15.24V8.736H33.75v6.504c0 4.851-6.272 8.784-14.01 8.784-7.737 0-14.009-3.933-14.009-8.784z" fill="#0B2630"/><path d="M.75 7.662L18.824.182a2.4 2.4 0 0 1 1.835 0l18.072 7.48a1.2 1.2 0 0 1 0 2.218l-18.072 7.48a2.4 2.4 0 0 1-1.835 0L.75 9.88a1.2 1.2 0 0 1 0-2.218z" fill="#29424E"/><path d="M19.295 9.771a1.194 1.194 0 0 1-.66-1.557c.248-.612.948-.907 1.562-.659l11.516 4.657v11.766c0 .66-.538 1.195-1.2 1.195-.663 0-1.2-.535-1.2-1.195V13.822l-10.018-4.05z" fill="#FFCF00" fill-rule="nonzero"/><path d="M32.613 23.373v3.807h-4.2v-3.807c0-.711.353-1.34.894-1.72h2.411c.541.38.895 1.009.895 1.72z" fill="#FCA326"/><path fill="#FFCF00" d="M28.413 23.592H32.613V27.18H28.413z"/></g><path d="M35 45h8c0 2.2-1.8 4-4 4s-4-1.8-4-4zm-1.5-2c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm11 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z" fill="#6B4FBB" fill-rule="nonzero"/></g></svg> \ No newline at end of file
diff --git a/app/assets/javascripts/alert_management/components/alert_details.vue b/app/assets/javascripts/alert_management/components/alert_details.vue
index 89db7db77d5..ed6b4b7fdb2 100644
--- a/app/assets/javascripts/alert_management/components/alert_details.vue
+++ b/app/assets/javascripts/alert_management/components/alert_details.vue
@@ -2,31 +2,32 @@
import * as Sentry from '@sentry/browser';
import {
GlAlert,
+ GlBadge,
GlIcon,
GlLoadingIcon,
- GlDropdown,
- GlDropdownItem,
GlSprintf,
GlTabs,
GlTab,
GlButton,
GlTable,
} from '@gitlab/ui';
-import createFlash from '~/flash';
import { s__ } from '~/locale';
import query from '../graphql/queries/details.query.graphql';
import { fetchPolicies } from '~/lib/graphql';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
-import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
-import { ALERTS_SEVERITY_LABELS } from '../constants';
-import updateAlertStatus from '../graphql/mutations/update_alert_status.graphql';
+import highlightCurrentUser from '~/behaviors/markdown/highlight_current_user';
+import initUserPopovers from '~/user_popovers';
+import { ALERTS_SEVERITY_LABELS, trackAlertsDetailsViewsOptions } from '../constants';
+import createIssueQuery from '../graphql/mutations/create_issue_from_alert.graphql';
+import { visitUrl, joinPaths } from '~/lib/utils/url_utility';
+import Tracking from '~/tracking';
+import { toggleContainerClasses } from '~/lib/utils/dom_utils';
+import SystemNote from './system_notes/system_note.vue';
+import AlertSidebar from './alert_sidebar.vue';
+
+const containerEl = document.querySelector('.page-with-contextual-sidebar');
export default {
- statuses: {
- TRIGGERED: s__('AlertManagement|Triggered'),
- ACKNOWLEDGED: s__('AlertManagement|Acknowledged'),
- RESOLVED: s__('AlertManagement|Resolved'),
- },
i18n: {
errorMsg: s__(
'AlertManagement|There was an error displaying the alert. Please refresh the page to try again.',
@@ -38,19 +39,19 @@ export default {
},
severityLabels: ALERTS_SEVERITY_LABELS,
components: {
+ GlBadge,
GlAlert,
GlIcon,
GlLoadingIcon,
GlSprintf,
- GlDropdown,
- GlDropdownItem,
GlTab,
GlTabs,
GlButton,
GlTable,
TimeAgoTooltip,
+ AlertSidebar,
+ SystemNote,
},
- mixins: [glFeatureFlagsMixin()],
props: {
alertId: {
type: String,
@@ -60,7 +61,7 @@ export default {
type: String,
required: true,
},
- newIssuePath: {
+ projectIssuesPath: {
type: String,
required: true,
},
@@ -85,7 +86,15 @@ export default {
},
},
data() {
- return { alert: null, errored: false, isErrorDismissed: false };
+ return {
+ alert: null,
+ errored: false,
+ isErrorDismissed: false,
+ createIssueError: '',
+ issueCreationInProgress: false,
+ sidebarCollapsed: false,
+ sidebarErrorMessage: '',
+ };
},
computed: {
loading() {
@@ -100,38 +109,92 @@ export default {
return this.errored && !this.isErrorDismissed;
},
},
+ mounted() {
+ this.trackPageViews();
+ toggleContainerClasses(containerEl, {
+ 'issuable-bulk-update-sidebar': true,
+ 'right-sidebar-expanded': true,
+ });
+ },
+ updated() {
+ this.$nextTick(() => {
+ highlightCurrentUser(this.$el.querySelectorAll('.gfm-project_member'));
+ initUserPopovers(this.$el.querySelectorAll('.js-user-link'));
+ });
+ },
methods: {
dismissError() {
this.isErrorDismissed = true;
+ this.sidebarErrorMessage = '';
},
- updateAlertStatus(status) {
+ toggleSidebar() {
+ this.sidebarCollapsed = !this.sidebarCollapsed;
+ toggleContainerClasses(containerEl, {
+ 'right-sidebar-collapsed': this.sidebarCollapsed,
+ 'right-sidebar-expanded': !this.sidebarCollapsed,
+ });
+ },
+ handleAlertSidebarError(errorMessage) {
+ this.errored = true;
+ this.sidebarErrorMessage = errorMessage;
+ },
+ createIssue() {
+ this.issueCreationInProgress = true;
+
this.$apollo
.mutate({
- mutation: updateAlertStatus,
+ mutation: createIssueQuery,
variables: {
- iid: this.alertId,
- status: status.toUpperCase(),
+ iid: this.alert.iid,
projectPath: this.projectPath,
},
})
- .catch(() => {
- createFlash(
- s__(
- 'AlertManagement|There was an error while updating the status of the alert. Please try again.',
- ),
- );
+ .then(({ data: { createAlertIssue: { errors, issue } } }) => {
+ if (errors?.length) {
+ [this.createIssueError] = errors;
+ this.issueCreationInProgress = false;
+ } else if (issue) {
+ visitUrl(this.issuePath(issue.iid));
+ }
+ })
+ .catch(error => {
+ this.createIssueError = error;
+ this.issueCreationInProgress = false;
});
},
+ issuePath(issueId) {
+ return joinPaths(this.projectIssuesPath, issueId);
+ },
+ trackPageViews() {
+ const { category, action } = trackAlertsDetailsViewsOptions;
+ Tracking.event(category, action);
+ },
+ alertRefresh() {
+ this.$apollo.queries.alert.refetch();
+ },
},
};
</script>
+
<template>
<div>
<gl-alert v-if="showErrorMsg" variant="danger" @dismiss="dismissError">
- {{ $options.i18n.errorMsg }}
+ {{ sidebarErrorMessage || $options.i18n.errorMsg }}
+ </gl-alert>
+ <gl-alert
+ v-if="createIssueError"
+ variant="danger"
+ data-testid="issueCreationError"
+ @dismiss="createIssueError = null"
+ >
+ {{ createIssueError }}
</gl-alert>
<div v-if="loading"><gl-loading-icon size="lg" class="gl-mt-5" /></div>
- <div v-if="alert" class="alert-management-details gl-relative">
+ <div
+ v-if="alert"
+ class="alert-management-details gl-relative"
+ :class="{ 'pr-sm-8': sidebarCollapsed }"
+ >
<div
class="gl-display-flex gl-justify-content-space-between gl-align-items-baseline gl-px-1 py-3 py-md-4 gl-border-b-1 gl-border-b-gray-200 gl-border-b-solid flex-column flex-sm-row"
>
@@ -142,32 +205,50 @@ export default {
<div
class="gl-display-inline-flex gl-align-items-center gl-justify-content-space-between"
>
- <gl-icon
- class="gl-mr-3 align-middle"
- :size="12"
- :name="`severity-${alert.severity.toLowerCase()}`"
- :class="`icon-${alert.severity.toLowerCase()}`"
- />
- <strong>{{ $options.severityLabels[alert.severity] }}</strong>
+ <gl-badge class="gl-mr-3">
+ <strong>{{ s__('AlertManagement|Alert') }}</strong>
+ </gl-badge>
</div>
- <span class="mx-2">&bull;</span>
- <gl-sprintf :message="reportedAtMessage">
- <template #when>
- <time-ago-tooltip :time="alert.createdAt" class="gl-ml-3" />
- </template>
- <template #tool>{{ alert.monitoringTool }}</template>
- </gl-sprintf>
+ <span>
+ <gl-sprintf :message="reportedAtMessage">
+ <template #when>
+ <time-ago-tooltip :time="alert.createdAt" />
+ </template>
+ <template #tool>{{ alert.monitoringTool }}</template>
+ </gl-sprintf>
+ </span>
</div>
<gl-button
- v-if="glFeatures.createIssueFromAlertEnabled"
- class="gl-mt-3 mt-sm-0 align-self-center align-self-sm-baseline alert-details-create-issue-button"
+ v-if="alert.issueIid"
+ class="gl-mt-3 mt-sm-0 align-self-center align-self-sm-baseline alert-details-issue-button"
+ data-testid="viewIssueBtn"
+ :href="issuePath(alert.issueIid)"
+ category="primary"
+ variant="success"
+ >
+ {{ s__('AlertManagement|View issue') }}
+ </gl-button>
+ <gl-button
+ v-else
+ class="gl-mt-3 mt-sm-0 align-self-center align-self-sm-baseline alert-details-issue-button"
data-testid="createIssueBtn"
- :href="newIssuePath"
+ :loading="issueCreationInProgress"
category="primary"
variant="success"
+ @click="createIssue()"
>
{{ s__('AlertManagement|Create issue') }}
</gl-button>
+ <gl-button
+ :aria-label="__('Toggle sidebar')"
+ category="primary"
+ variant="default"
+ class="d-sm-none gl-absolute toggle-sidebar-mobile-button"
+ type="button"
+ @click="toggleSidebar"
+ >
+ <i class="fa fa-angle-double-left"></i>
+ </gl-button>
</div>
<div
v-if="alert"
@@ -175,44 +256,57 @@ export default {
>
<h2 data-testid="title">{{ alert.title }}</h2>
</div>
- <gl-dropdown :text="$options.statuses[alert.status]" class="gl-absolute gl-right-0" right>
- <gl-dropdown-item
- v-for="(label, field) in $options.statuses"
- :key="field"
- data-testid="statusDropdownItem"
- class="gl-vertical-align-middle"
- @click="updateAlertStatus(label)"
- >
- <span class="d-flex">
- <gl-icon
- class="flex-shrink-0 append-right-4"
- :class="{ invisible: label.toUpperCase() !== alert.status }"
- name="mobile-issue-close"
- />
- {{ label }}
- </span>
- </gl-dropdown-item>
- </gl-dropdown>
<gl-tabs v-if="alert" data-testid="alertDetailsTabs">
<gl-tab data-testid="overviewTab" :title="$options.i18n.overviewTitle">
- <ul class="pl-4 mb-n1">
- <li v-if="alert.startedAt" class="my-2">
- <strong class="bold">{{ s__('AlertManagement|Start time') }}:</strong>
+ <div v-if="alert.severity" class="gl-mt-3 gl-mb-5 gl-display-flex">
+ <div class="gl-font-weight-bold gl-w-13 gl-text-right gl-pr-3">
+ {{ s__('AlertManagement|Severity') }}:
+ </div>
+ <div class="gl-pl-2" data-testid="severity">
+ <span>
+ <gl-icon
+ class="gl-vertical-align-middle"
+ :size="12"
+ :name="`severity-${alert.severity.toLowerCase()}`"
+ :class="`icon-${alert.severity.toLowerCase()}`"
+ />
+ </span>
+ {{ $options.severityLabels[alert.severity] }}
+ </div>
+ </div>
+ <div v-if="alert.startedAt" class="gl-my-5 gl-display-flex">
+ <div class="gl-font-weight-bold gl-w-13 gl-text-right gl-pr-3">
+ {{ s__('AlertManagement|Start time') }}:
+ </div>
+ <div class="gl-pl-2">
<time-ago-tooltip data-testid="startTimeItem" :time="alert.startedAt" />
- </li>
- <li v-if="alert.eventCount" class="my-2">
- <strong class="bold">{{ s__('AlertManagement|Events') }}:</strong>
- <span data-testid="eventCount">{{ alert.eventCount }}</span>
- </li>
- <li v-if="alert.monitoringTool" class="my-2">
- <strong class="bold">{{ s__('AlertManagement|Tool') }}:</strong>
- <span data-testid="monitoringTool">{{ alert.monitoringTool }}</span>
- </li>
- <li v-if="alert.service" class="my-2">
- <strong class="bold">{{ s__('AlertManagement|Service') }}:</strong>
- <span data-testid="service">{{ alert.service }}</span>
- </li>
- </ul>
+ </div>
+ </div>
+ <div v-if="alert.eventCount" class="gl-my-5 gl-display-flex">
+ <div class="gl-font-weight-bold gl-w-13 gl-text-right gl-pr-3">
+ {{ s__('AlertManagement|Events') }}:
+ </div>
+ <div class="gl-pl-2" data-testid="eventCount">{{ alert.eventCount }}</div>
+ </div>
+ <div v-if="alert.monitoringTool" class="gl-my-5 gl-display-flex">
+ <div class="gl-font-weight-bold gl-w-13 gl-text-right gl-pr-3">
+ {{ s__('AlertManagement|Tool') }}:
+ </div>
+ <div class="gl-pl-2" data-testid="monitoringTool">{{ alert.monitoringTool }}</div>
+ </div>
+ <div v-if="alert.service" class="gl-my-5 gl-display-flex">
+ <div class="bold gl-w-13 gl-text-right gl-pr-3">
+ {{ s__('AlertManagement|Service') }}:
+ </div>
+ <div class="gl-pl-2" data-testid="service">{{ alert.service }}</div>
+ </div>
+ <template>
+ <div v-if="alert.notes.nodes" class="issuable-discussion py-5">
+ <ul class="notes main-notes-list timeline">
+ <system-note v-for="note in alert.notes.nodes" :key="note.id" :note="note" />
+ </ul>
+ </div>
+ </template>
</gl-tab>
<gl-tab data-testid="fullDetailsTab" :title="$options.i18n.fullAlertDetailsTitle">
<gl-table
@@ -231,6 +325,14 @@ export default {
</gl-table>
</gl-tab>
</gl-tabs>
+ <alert-sidebar
+ :project-path="projectPath"
+ :alert="alert"
+ :sidebar-collapsed="sidebarCollapsed"
+ @alert-refresh="alertRefresh"
+ @toggle-sidebar="toggleSidebar"
+ @alert-sidebar-error="handleAlertSidebarError"
+ />
</div>
</div>
</template>
diff --git a/app/assets/javascripts/alert_management/components/alert_management_list.vue b/app/assets/javascripts/alert_management/components/alert_management_list.vue
index 74fc19ff3d4..37901c21f9b 100644
--- a/app/assets/javascripts/alert_management/components/alert_management_list.vue
+++ b/app/assets/javascripts/alert_management/components/alert_management_list.vue
@@ -10,23 +10,41 @@ import {
GlDropdownItem,
GlTabs,
GlTab,
+ GlBadge,
+ GlPagination,
} from '@gitlab/ui';
import createFlash from '~/flash';
import { s__ } from '~/locale';
import { joinPaths, visitUrl } from '~/lib/utils/url_utility';
+import { fetchPolicies } from '~/lib/graphql';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
-import getAlerts from '../graphql/queries/getAlerts.query.graphql';
-import { ALERTS_STATUS, ALERTS_STATUS_TABS, ALERTS_SEVERITY_LABELS } from '../constants';
-import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+import getAlerts from '../graphql/queries/get_alerts.query.graphql';
+import getAlertsCountByStatus from '../graphql/queries/get_count_by_status.query.graphql';
+import {
+ ALERTS_STATUS_TABS,
+ ALERTS_SEVERITY_LABELS,
+ DEFAULT_PAGE_SIZE,
+ trackAlertListViewsOptions,
+ trackAlertStatusUpdateOptions,
+} from '../constants';
import updateAlertStatus from '../graphql/mutations/update_alert_status.graphql';
-import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';
+import { convertToSnakeCase } from '~/lib/utils/text_utility';
+import Tracking from '~/tracking';
-const tdClass = 'table-col d-flex d-md-table-cell align-items-center';
+const tdClass = 'table-col gl-display-flex d-md-table-cell gl-align-items-center';
+const thClass = 'gl-hover-bg-blue-50';
const bodyTrClass =
- 'gl-border-1 gl-border-t-solid gl-border-gray-100 hover-bg-blue-50 hover-gl-cursor-pointer hover-gl-border-b-solid hover-gl-border-blue-200';
+ 'gl-border-1 gl-border-t-solid gl-border-gray-100 gl-hover-bg-blue-50 gl-hover-cursor-pointer gl-hover-border-b-solid gl-hover-border-blue-200';
+
+const initialPaginationState = {
+ currentPage: 1,
+ prevPageCursor: '',
+ nextPageCursor: '',
+ firstPageSize: DEFAULT_PAGE_SIZE,
+ lastPageSize: null,
+};
export default {
- bodyTrClass,
i18n: {
noAlertsMsg: s__(
"AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page.",
@@ -40,40 +58,54 @@ export default {
key: 'severity',
label: s__('AlertManagement|Severity'),
tdClass: `${tdClass} rounded-top text-capitalize`,
+ thClass,
+ sortable: true,
},
{
key: 'startedAt',
label: s__('AlertManagement|Start time'),
+ thClass: `${thClass} js-started-at`,
tdClass,
+ sortable: true,
},
{
key: 'endedAt',
label: s__('AlertManagement|End time'),
+ thClass,
tdClass,
+ sortable: true,
},
{
key: 'title',
label: s__('AlertManagement|Alert'),
- thClass: 'w-30p',
+ thClass: `${thClass} w-30p gl-pointer-events-none`,
tdClass,
+ sortable: false,
},
{
key: 'eventCount',
label: s__('AlertManagement|Events'),
- thClass: 'text-right event-count',
- tdClass: `${tdClass} text-md-right event-count`,
+ thClass: `${thClass} text-right gl-pr-9 w-3rem`,
+ tdClass: `${tdClass} text-md-right`,
+ sortable: true,
+ },
+ {
+ key: 'assignees',
+ label: s__('AlertManagement|Assignees'),
+ tdClass,
},
{
key: 'status',
- thClass: 'w-15p',
+ thClass: `${thClass} w-15p`,
label: s__('AlertManagement|Status'),
tdClass: `${tdClass} rounded-bottom`,
+ sortable: true,
},
],
statuses: {
- [ALERTS_STATUS.TRIGGERED]: s__('AlertManagement|Triggered'),
- [ALERTS_STATUS.ACKNOWLEDGED]: s__('AlertManagement|Acknowledged'),
- [ALERTS_STATUS.RESOLVED]: s__('AlertManagement|Resolved'),
+ TRIGGERED: s__('AlertManagement|Triggered'),
+ ACKNOWLEDGED: s__('AlertManagement|Acknowledged'),
+ RESOLVED: s__('AlertManagement|Resolved'),
},
severityLabels: ALERTS_SEVERITY_LABELS,
statusTabs: ALERTS_STATUS_TABS,
@@ -89,8 +121,9 @@ export default {
GlIcon,
GlTabs,
GlTab,
+ GlBadge,
+ GlPagination,
},
- mixins: [glFeatureFlagsMixin()],
props: {
projectPath: {
type: String,
@@ -115,33 +148,63 @@ export default {
},
apollo: {
alerts: {
+ fetchPolicy: fetchPolicies.CACHE_AND_NETWORK,
query: getAlerts,
variables() {
return {
projectPath: this.projectPath,
statuses: this.statusFilter,
+ sort: this.sort,
+ firstPageSize: this.pagination.firstPageSize,
+ lastPageSize: this.pagination.lastPageSize,
+ prevPageCursor: this.pagination.prevPageCursor,
+ nextPageCursor: this.pagination.nextPageCursor,
};
},
update(data) {
- return data.project.alertManagementAlerts.nodes;
+ const { alertManagementAlerts: { nodes: list = [], pageInfo = {} } = {} } =
+ data.project || {};
+
+ return {
+ list,
+ pageInfo,
+ };
},
error() {
this.errored = true;
},
},
+ alertsCount: {
+ query: getAlertsCountByStatus,
+ variables() {
+ return {
+ projectPath: this.projectPath,
+ };
+ },
+ update(data) {
+ return data.project?.alertManagementAlertStatusCounts;
+ },
+ },
},
data() {
return {
- alerts: null,
errored: false,
isAlertDismissed: false,
isErrorAlertDismissed: false,
- statusFilter: this.$options.statusTabs[4].filters,
+ sort: 'STARTED_AT_DESC',
+ statusFilter: [],
+ filteredByStatus: '',
+ pagination: initialPaginationState,
+ sortBy: 'startedAt',
+ sortDesc: true,
+ sortDirection: 'desc',
};
},
computed: {
showNoAlertsMsg() {
- return !this.errored && !this.loading && !this.alerts?.length && !this.isAlertDismissed;
+ return (
+ !this.errored && !this.loading && this.alertsCount?.all === 0 && !this.isAlertDismissed
+ );
},
showErrorMsg() {
return this.errored && !this.isErrorAlertDismissed;
@@ -149,12 +212,43 @@ export default {
loading() {
return this.$apollo.queries.alerts.loading;
},
+ hasAlerts() {
+ return this.alerts?.list?.length;
+ },
+ tbodyTrClass() {
+ return !this.loading && this.hasAlerts ? bodyTrClass : '';
+ },
+ showPaginationControls() {
+ return Boolean(this.prevPage || this.nextPage);
+ },
+ alertsForCurrentTab() {
+ return this.alertsCount ? this.alertsCount[this.filteredByStatus.toLowerCase()] : 0;
+ },
+ prevPage() {
+ return Math.max(this.pagination.currentPage - 1, 0);
+ },
+ nextPage() {
+ const nextPage = this.pagination.currentPage + 1;
+ return nextPage > Math.ceil(this.alertsForCurrentTab / DEFAULT_PAGE_SIZE) ? null : nextPage;
+ },
+ },
+ mounted() {
+ this.trackPageViews();
},
methods: {
filterAlertsByStatus(tabIndex) {
- this.statusFilter = this.$options.statusTabs[tabIndex].filters;
+ this.resetPagination();
+ const { filters, status } = this.$options.statusTabs[tabIndex];
+ this.statusFilter = filters;
+ this.filteredByStatus = status;
+ },
+ fetchSortedData({ sortBy, sortDesc }) {
+ const sortingDirection = sortDesc ? 'DESC' : 'ASC';
+ const sortingColumn = convertToSnakeCase(sortBy).toUpperCase();
+
+ this.resetPagination();
+ this.sort = `${sortingColumn}_${sortingDirection}`;
},
- capitalizeFirstCharacter,
updateAlertStatus(status, iid) {
this.$apollo
.mutate({
@@ -166,7 +260,10 @@ export default {
},
})
.then(() => {
+ this.trackStatusUpdate(status);
this.$apollo.queries.alerts.refetch();
+ this.$apollo.queries.alertsCount.refetch();
+ this.resetPagination();
})
.catch(() => {
createFlash(
@@ -179,6 +276,42 @@ export default {
navigateToAlertDetails({ iid }) {
return visitUrl(joinPaths(window.location.pathname, iid, 'details'));
},
+ trackPageViews() {
+ const { category, action } = trackAlertListViewsOptions;
+ Tracking.event(category, action);
+ },
+ trackStatusUpdate(status) {
+ const { category, action, label } = trackAlertStatusUpdateOptions;
+ Tracking.event(category, action, { label, property: status });
+ },
+ getAssignees(assignees) {
+ // TODO: Update to show list of assignee(s) after https://gitlab.com/gitlab-org/gitlab/-/issues/218405
+ return assignees.nodes?.length > 0
+ ? assignees.nodes[0]?.username
+ : s__('AlertManagement|Unassigned');
+ },
+ handlePageChange(page) {
+ const { startCursor, endCursor } = this.alerts.pageInfo;
+
+ if (page > this.pagination.currentPage) {
+ this.pagination = {
+ ...initialPaginationState,
+ nextPageCursor: endCursor,
+ currentPage: page,
+ };
+ } else {
+ this.pagination = {
+ lastPageSize: DEFAULT_PAGE_SIZE,
+ firstPageSize: null,
+ prevPageCursor: startCursor,
+ nextPageCursor: '',
+ currentPage: page,
+ };
+ }
+ },
+ resetPagination() {
+ this.pagination = initialPaginationState;
+ },
},
};
</script>
@@ -192,10 +325,13 @@ export default {
{{ $options.i18n.errorMsg }}
</gl-alert>
- <gl-tabs v-if="glFeatures.alertListStatusFilteringEnabled" @input="filterAlertsByStatus">
+ <gl-tabs @input="filterAlertsByStatus">
<gl-tab v-for="tab in $options.statusTabs" :key="tab.status">
<template slot="title">
<span>{{ tab.title }}</span>
+ <gl-badge v-if="alertsCount" pill size="sm" class="gl-tab-counter-badge">
+ {{ alertsCount[tab.status.toLowerCase()] }}
+ </gl-badge>
</template>
</gl-tab>
</gl-tabs>
@@ -205,13 +341,19 @@ export default {
</h4>
<gl-table
class="alert-management-table mt-3"
- :items="alerts"
+ :items="alerts ? alerts.list : []"
:fields="$options.fields"
:show-empty="true"
:busy="loading"
stacked="md"
- :tbody-tr-class="$options.bodyTrClass"
+ :tbody-tr-class="tbodyTrClass"
+ :no-local-sorting="true"
+ :sort-direction="sortDirection"
+ :sort-desc.sync="sortDesc"
+ :sort-by.sync="sortBy"
+ sort-icon-left
@row-clicked="navigateToAlertDetails"
+ @sort-changed="fetchSortedData"
>
<template #cell(severity)="{ item }">
<div
@@ -236,16 +378,22 @@ export default {
<time-ago v-if="item.endedAt" :time="item.endedAt" />
</template>
+ <template #cell(eventCount)="{ item }">
+ {{ item.eventCount }}
+ </template>
+
<template #cell(title)="{ item }">
<div class="gl-max-w-full text-truncate">{{ item.title }}</div>
</template>
+ <template #cell(assignees)="{ item }">
+ <div class="gl-max-w-full text-truncate" data-testid="assigneesField">
+ {{ getAssignees(item.assignees) }}
+ </div>
+ </template>
+
<template #cell(status)="{ item }">
- <gl-dropdown
- :text="capitalizeFirstCharacter(item.status.toLowerCase())"
- class="w-100"
- right
- >
+ <gl-dropdown :text="$options.statuses[item.status]" class="w-100" right>
<gl-dropdown-item
v-for="(label, field) in $options.statuses"
:key="field"
@@ -271,6 +419,16 @@ export default {
<gl-loading-icon size="lg" color="dark" class="mt-3" />
</template>
</gl-table>
+
+ <gl-pagination
+ v-if="showPaginationControls"
+ :value="pagination.currentPage"
+ :prev-page="prevPage"
+ :next-page="nextPage"
+ align="center"
+ class="gl-pagination prepend-top-default"
+ @input="handlePageChange"
+ />
</div>
<gl-empty-state
v-else
diff --git a/app/assets/javascripts/alert_management/components/alert_sidebar.vue b/app/assets/javascripts/alert_management/components/alert_sidebar.vue
new file mode 100644
index 00000000000..dcd22e2062e
--- /dev/null
+++ b/app/assets/javascripts/alert_management/components/alert_sidebar.vue
@@ -0,0 +1,61 @@
+<script>
+import SidebarHeader from './sidebar/sidebar_header.vue';
+import SidebarTodo from './sidebar/sidebar_todo.vue';
+import SidebarStatus from './sidebar/sidebar_status.vue';
+import SidebarAssignees from './sidebar/sidebar_assignees.vue';
+
+export default {
+ components: {
+ SidebarAssignees,
+ SidebarHeader,
+ SidebarTodo,
+ SidebarStatus,
+ },
+ props: {
+ sidebarCollapsed: {
+ type: Boolean,
+ required: true,
+ },
+ projectPath: {
+ type: String,
+ required: true,
+ },
+ alert: {
+ type: Object,
+ required: true,
+ },
+ },
+ computed: {
+ sidebarCollapsedClass() {
+ return this.sidebarCollapsed ? 'right-sidebar-collapsed' : 'right-sidebar-expanded';
+ },
+ },
+};
+</script>
+
+<template>
+ <aside :class="sidebarCollapsedClass" class="right-sidebar alert-sidebar">
+ <div class="issuable-sidebar js-issuable-update">
+ <sidebar-header
+ :sidebar-collapsed="sidebarCollapsed"
+ @toggle-sidebar="$emit('toggle-sidebar')"
+ />
+ <sidebar-todo v-if="sidebarCollapsed" :sidebar-collapsed="sidebarCollapsed" />
+ <sidebar-status
+ :project-path="projectPath"
+ :alert="alert"
+ @toggle-sidebar="$emit('toggle-sidebar')"
+ @alert-sidebar-error="$emit('alert-sidebar-error', $event)"
+ />
+ <sidebar-assignees
+ :project-path="projectPath"
+ :alert="alert"
+ :sidebar-collapsed="sidebarCollapsed"
+ @alert-refresh="$emit('alert-refresh')"
+ @toggle-sidebar="$emit('toggle-sidebar')"
+ @alert-sidebar-error="$emit('alert-sidebar-error', $event)"
+ />
+ <div class="block"></div>
+ </div>
+ </aside>
+</template>
diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignee.vue b/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignee.vue
new file mode 100644
index 00000000000..df07038151e
--- /dev/null
+++ b/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignee.vue
@@ -0,0 +1,51 @@
+<script>
+import { GlDropdownItem } from '@gitlab/ui';
+
+export default {
+ components: {
+ GlDropdownItem,
+ },
+ props: {
+ user: {
+ type: Object,
+ required: true,
+ },
+ active: {
+ type: Boolean,
+ required: true,
+ },
+ },
+ methods: {
+ isActive(name) {
+ return this.alert.assignees.nodes.some(({ username }) => username === name);
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-dropdown-item
+ :key="user.username"
+ data-testid="assigneeDropdownItem"
+ class="assignee-dropdown-item gl-vertical-align-middle"
+ :active="active"
+ active-class="is-active"
+ @click="$emit('update-alert-assignees', user.username)"
+ >
+ <span class="gl-relative mr-2">
+ <img
+ :alt="user.username"
+ :src="user.avatar_url"
+ :width="32"
+ class="avatar avatar-inline gl-m-0 s32"
+ data-qa-selector="avatar_image"
+ />
+ </span>
+ <span class="d-flex gl-flex-direction-column gl-overflow-hidden">
+ <strong class="dropdown-menu-user-full-name">
+ {{ user.name }}
+ </strong>
+ <span class="dropdown-menu-user-username"> {{ user.username }}</span>
+ </span>
+ </gl-dropdown-item>
+</template>
diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignees.vue b/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignees.vue
new file mode 100644
index 00000000000..453a3901665
--- /dev/null
+++ b/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignees.vue
@@ -0,0 +1,278 @@
+<script>
+import {
+ GlIcon,
+ GlDropdown,
+ GlDropdownDivider,
+ GlDropdownHeader,
+ GlDropdownItem,
+ GlLoadingIcon,
+ GlTooltip,
+ GlButton,
+ GlSprintf,
+} from '@gitlab/ui';
+import axios from '~/lib/utils/axios_utils';
+import { s__ } from '~/locale';
+import alertSetAssignees from '../../graphql/mutations/alert_set_assignees.graphql';
+import SidebarAssignee from './sidebar_assignee.vue';
+import { debounce } from 'lodash';
+
+const DATA_REFETCH_DELAY = 250;
+
+export default {
+ FETCH_USERS_ERROR: s__(
+ 'AlertManagement|There was an error while updating the assignee(s) list. Please try again.',
+ ),
+ UPDATE_ALERT_ASSIGNEES_ERROR: s__(
+ 'AlertManagement|There was an error while updating the assignee(s) of the alert. Please try again.',
+ ),
+ components: {
+ GlIcon,
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownDivider,
+ GlDropdownHeader,
+ GlLoadingIcon,
+ GlTooltip,
+ GlButton,
+ GlSprintf,
+ SidebarAssignee,
+ },
+ props: {
+ projectPath: {
+ type: String,
+ required: true,
+ },
+ alert: {
+ type: Object,
+ required: true,
+ },
+ isEditable: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
+ sidebarCollapsed: {
+ type: Boolean,
+ required: false,
+ },
+ },
+ data() {
+ return {
+ isDropdownShowing: false,
+ isDropdownSearching: false,
+ isUpdating: false,
+ search: '',
+ users: [],
+ };
+ },
+ computed: {
+ currentUser() {
+ return gon?.current_username;
+ },
+ userName() {
+ return this.alert?.assignees?.nodes[0]?.username;
+ },
+ assignedUser() {
+ return this.userName || s__('AlertManagement|None');
+ },
+ sortedUsers() {
+ return this.users
+ .map(user => ({ ...user, active: this.isActive(user.username) }))
+ .sort((a, b) => (a.active === b.active ? 0 : a.active ? -1 : 1)); // eslint-disable-line no-nested-ternary
+ },
+ dropdownClass() {
+ return this.isDropdownShowing ? 'show' : 'gl-display-none';
+ },
+ userListValid() {
+ return !this.isDropdownSearching && this.users.length > 0;
+ },
+ userListEmpty() {
+ return !this.isDropdownSearching && this.users.length === 0;
+ },
+ },
+ watch: {
+ search: debounce(function debouncedUserSearch() {
+ this.updateAssigneesDropdown();
+ }, DATA_REFETCH_DELAY),
+ },
+ mounted() {
+ this.updateAssigneesDropdown();
+ },
+ methods: {
+ hideDropdown() {
+ this.isDropdownShowing = false;
+ },
+ toggleFormDropdown() {
+ this.isDropdownShowing = !this.isDropdownShowing;
+ const { dropdown } = this.$refs.dropdown.$refs;
+ if (dropdown && this.isDropdownShowing) {
+ dropdown.show();
+ }
+ },
+ isActive(name) {
+ return this.alert.assignees.nodes.some(({ username }) => username === name);
+ },
+ buildUrl(urlRoot, url) {
+ let newUrl;
+ if (urlRoot != null) {
+ newUrl = urlRoot.replace(/\/$/, '') + url;
+ }
+ return newUrl;
+ },
+ updateAssigneesDropdown() {
+ this.isDropdownSearching = true;
+ return axios
+ .get(this.buildUrl(gon.relative_url_root, '/autocomplete/users.json'), {
+ params: {
+ search: this.search,
+ per_page: 20,
+ active: true,
+ current_user: true,
+ project_id: gon?.current_project_id,
+ },
+ })
+ .then(({ data }) => {
+ this.users = data;
+ })
+ .catch(() => {
+ this.$emit('alert-sidebar-error', this.$options.FETCH_USERS_ERROR);
+ })
+ .finally(() => {
+ this.isDropdownSearching = false;
+ });
+ },
+ updateAlertAssignees(assignees) {
+ this.isUpdating = true;
+ this.$apollo
+ .mutate({
+ mutation: alertSetAssignees,
+ variables: {
+ iid: this.alert.iid,
+ assigneeUsernames: [this.isActive(assignees) ? '' : assignees],
+ projectPath: this.projectPath,
+ },
+ })
+ .then(() => {
+ this.hideDropdown();
+ this.$emit('alert-refresh');
+ })
+ .catch(() => {
+ this.$emit('alert-sidebar-error', this.$options.UPDATE_ALERT_ASSIGNEES_ERROR);
+ })
+ .finally(() => {
+ this.isUpdating = false;
+ });
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="block alert-status">
+ <div ref="status" class="sidebar-collapsed-icon" @click="$emit('toggle-sidebar')">
+ <gl-icon name="user" :size="14" />
+ <gl-loading-icon v-if="isUpdating" />
+ </div>
+ <gl-tooltip :target="() => $refs.status" boundary="viewport" placement="left">
+ <gl-sprintf :message="s__('AlertManagement|Alert assignee(s): %{assignees}')">
+ <template #assignees>
+ {{ assignedUser }}
+ </template>
+ </gl-sprintf>
+ </gl-tooltip>
+
+ <div class="hide-collapsed">
+ <p class="title gl-display-flex gl-justify-content-space-between">
+ {{ s__('AlertManagement|Assignee') }}
+ <a
+ v-if="isEditable"
+ ref="editButton"
+ class="btn-link"
+ href="#"
+ @click="toggleFormDropdown"
+ @keydown.esc="hideDropdown"
+ >
+ {{ s__('AlertManagement|Edit') }}
+ </a>
+ </p>
+
+ <div class="dropdown dropdown-menu-selectable" :class="dropdownClass">
+ <gl-dropdown
+ ref="dropdown"
+ :text="assignedUser"
+ class="w-100"
+ toggle-class="dropdown-menu-toggle"
+ variant="outline-default"
+ @keydown.esc.native="hideDropdown"
+ @hide="hideDropdown"
+ >
+ <div class="dropdown-title">
+ <span class="alert-title">{{ s__('AlertManagement|Assign To') }}</span>
+ <gl-button
+ :aria-label="__('Close')"
+ variant="link"
+ class="dropdown-title-button dropdown-menu-close"
+ icon="close"
+ @click="hideDropdown"
+ />
+ </div>
+ <div class="dropdown-input">
+ <input
+ v-model.trim="search"
+ class="dropdown-input-field"
+ type="search"
+ :placeholder="__('Search users')"
+ />
+ <gl-icon name="search" class="dropdown-input-search ic-search" data-hidden="true" />
+ </div>
+ <div class="dropdown-content dropdown-body">
+ <template v-if="userListValid">
+ <gl-dropdown-item
+ :active="!userName"
+ active-class="is-active"
+ @click="updateAlertAssignees('')"
+ >
+ {{ s__('AlertManagement|Unassigned') }}
+ </gl-dropdown-item>
+ <gl-dropdown-divider />
+
+ <gl-dropdown-header class="mt-0">
+ {{ s__('AlertManagement|Assignee') }}
+ </gl-dropdown-header>
+ <sidebar-assignee
+ v-for="user in sortedUsers"
+ :key="user.username"
+ :user="user"
+ :active="user.active"
+ @update-alert-assignees="updateAlertAssignees"
+ />
+ </template>
+ <gl-dropdown-item v-else-if="userListEmpty">
+ {{ s__('AlertManagement|No Matching Results') }}
+ </gl-dropdown-item>
+ <gl-loading-icon v-else />
+ </div>
+ </gl-dropdown>
+ </div>
+
+ <gl-loading-icon v-if="isUpdating" :inline="true" />
+ <p v-else-if="!isDropdownShowing" class="value gl-m-0" :class="{ 'no-value': !userName }">
+ <span v-if="userName" class="gl-text-gray-700" data-testid="assigned-users">{{
+ assignedUser
+ }}</span>
+ <span v-else class="gl-display-flex gl-align-items-center">
+ {{ s__('AlertManagement|None -') }}
+ <gl-button
+ class="gl-pl-2"
+ href="#"
+ variant="link"
+ data-testid="unassigned-users"
+ @click="updateAlertAssignees(currentUser)"
+ >
+ {{ s__('AlertManagement| assign yourself') }}
+ </gl-button>
+ </span>
+ </p>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_header.vue b/app/assets/javascripts/alert_management/components/sidebar/sidebar_header.vue
new file mode 100644
index 00000000000..047793d8cee
--- /dev/null
+++ b/app/assets/javascripts/alert_management/components/sidebar/sidebar_header.vue
@@ -0,0 +1,34 @@
+<script>
+import ToggleSidebar from '~/vue_shared/components/sidebar/toggle_sidebar.vue';
+import SidebarTodo from './sidebar_todo.vue';
+
+export default {
+ components: {
+ ToggleSidebar,
+ SidebarTodo,
+ },
+ props: {
+ sidebarCollapsed: {
+ type: Boolean,
+ required: true,
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="block d-flex justify-content-between">
+ <span class="issuable-header-text hide-collapsed">
+ {{ __('Quick actions') }}
+ </span>
+ <toggle-sidebar
+ :collapsed="sidebarCollapsed"
+ css-classes="ml-auto"
+ @toggle="$emit('toggle-sidebar')"
+ />
+ <!-- TODO: Implement after or as part of: https://gitlab.com/gitlab-org/gitlab/-/issues/215946 -->
+ <template v-if="false">
+ <sidebar-todo v-if="!sidebarCollapsed" :sidebar-collapsed="sidebarCollapsed" />
+ </template>
+ </div>
+</template>
diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_status.vue b/app/assets/javascripts/alert_management/components/sidebar/sidebar_status.vue
new file mode 100644
index 00000000000..89dbbedd9c1
--- /dev/null
+++ b/app/assets/javascripts/alert_management/components/sidebar/sidebar_status.vue
@@ -0,0 +1,189 @@
+<script>
+import {
+ GlIcon,
+ GlDropdown,
+ GlDropdownItem,
+ GlLoadingIcon,
+ GlTooltip,
+ GlButton,
+ GlSprintf,
+} from '@gitlab/ui';
+import { s__ } from '~/locale';
+import Tracking from '~/tracking';
+import { trackAlertStatusUpdateOptions } from '../../constants';
+import updateAlertStatus from '../../graphql/mutations/update_alert_status.graphql';
+
+export default {
+ statuses: {
+ TRIGGERED: s__('AlertManagement|Triggered'),
+ ACKNOWLEDGED: s__('AlertManagement|Acknowledged'),
+ RESOLVED: s__('AlertManagement|Resolved'),
+ },
+ components: {
+ GlIcon,
+ GlDropdown,
+ GlDropdownItem,
+ GlLoadingIcon,
+ GlTooltip,
+ GlButton,
+ GlSprintf,
+ },
+ props: {
+ projectPath: {
+ type: String,
+ required: true,
+ },
+ alert: {
+ type: Object,
+ required: true,
+ },
+ isEditable: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
+ },
+ data() {
+ return {
+ isDropdownShowing: false,
+ isUpdating: false,
+ };
+ },
+ computed: {
+ dropdownClass() {
+ return this.isDropdownShowing ? 'show' : 'gl-display-none';
+ },
+ },
+ methods: {
+ hideDropdown() {
+ this.isDropdownShowing = false;
+ },
+ toggleFormDropdown() {
+ this.isDropdownShowing = !this.isDropdownShowing;
+ const { dropdown } = this.$refs.dropdown.$refs;
+ if (dropdown && this.isDropdownShowing) {
+ dropdown.show();
+ }
+ },
+ isSelected(status) {
+ return this.alert.status === status;
+ },
+ updateAlertStatus(status) {
+ this.isUpdating = true;
+ this.$apollo
+ .mutate({
+ mutation: updateAlertStatus,
+ variables: {
+ iid: this.alert.iid,
+ status: status.toUpperCase(),
+ projectPath: this.projectPath,
+ },
+ })
+ .then(() => {
+ this.trackStatusUpdate(status);
+ this.hideDropdown();
+ })
+ .catch(() => {
+ this.$emit(
+ 'alert-sidebar-error',
+ s__(
+ 'AlertManagement|There was an error while updating the status of the alert. Please try again.',
+ ),
+ );
+ })
+ .finally(() => {
+ this.isUpdating = false;
+ });
+ },
+ trackStatusUpdate(status) {
+ const { category, action, label } = trackAlertStatusUpdateOptions;
+ Tracking.event(category, action, { label, property: status });
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="block alert-status">
+ <div ref="status" class="sidebar-collapsed-icon" @click="$emit('toggle-sidebar')">
+ <gl-icon name="status" :size="14" />
+ <gl-loading-icon v-if="isUpdating" />
+ </div>
+ <gl-tooltip :target="() => $refs.status" boundary="viewport" placement="left">
+ <gl-sprintf :message="s__('AlertManagement|Alert status: %{status}')">
+ <template #status>
+ {{ alert.status.toLowerCase() }}
+ </template>
+ </gl-sprintf>
+ </gl-tooltip>
+
+ <div class="hide-collapsed">
+ <p class="title gl-display-flex justify-content-between">
+ {{ s__('AlertManagement|Status') }}
+ <a
+ v-if="isEditable"
+ ref="editButton"
+ class="btn-link"
+ href="#"
+ @click="toggleFormDropdown"
+ @keydown.esc="hideDropdown"
+ >
+ {{ s__('AlertManagement|Edit') }}
+ </a>
+ </p>
+
+ <div class="dropdown dropdown-menu-selectable" :class="dropdownClass">
+ <gl-dropdown
+ ref="dropdown"
+ :text="$options.statuses[alert.status]"
+ class="w-100"
+ toggle-class="dropdown-menu-toggle"
+ variant="outline-default"
+ @keydown.esc.native="hideDropdown"
+ @hide="hideDropdown"
+ >
+ <div class="dropdown-title">
+ <span class="alert-title">{{ s__('AlertManagement|Assign status') }}</span>
+ <gl-button
+ :aria-label="__('Close')"
+ variant="link"
+ class="dropdown-title-button dropdown-menu-close"
+ icon="close"
+ @click="hideDropdown"
+ />
+ </div>
+ <div class="dropdown-content dropdown-body">
+ <gl-dropdown-item
+ v-for="(label, field) in $options.statuses"
+ :key="field"
+ data-testid="statusDropdownItem"
+ class="gl-vertical-align-middle"
+ :active="label.toUpperCase() === alert.status"
+ :active-class="'is-active'"
+ @click="updateAlertStatus(label)"
+ >
+ {{ label }}
+ </gl-dropdown-item>
+ </div>
+ </gl-dropdown>
+ </div>
+
+ <gl-loading-icon v-if="isUpdating" :inline="true" />
+ <p
+ v-else-if="!isDropdownShowing"
+ class="value gl-m-0"
+ :class="{ 'no-value': !$options.statuses[alert.status] }"
+ >
+ <span
+ v-if="$options.statuses[alert.status]"
+ class="gl-text-gray-700"
+ data-testid="status"
+ >{{ $options.statuses[alert.status] }}</span
+ >
+ <span v-else>
+ {{ s__('AlertManagement|None') }}
+ </span>
+ </p>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_todo.vue b/app/assets/javascripts/alert_management/components/sidebar/sidebar_todo.vue
new file mode 100644
index 00000000000..87090165f82
--- /dev/null
+++ b/app/assets/javascripts/alert_management/components/sidebar/sidebar_todo.vue
@@ -0,0 +1,29 @@
+<script>
+import Todo from '~/sidebar/components/todo_toggle/todo.vue';
+
+export default {
+ components: {
+ Todo,
+ },
+ props: {
+ sidebarCollapsed: {
+ type: Boolean,
+ required: true,
+ },
+ },
+};
+</script>
+
+<!-- TODO: Implement after or as part of: https://gitlab.com/gitlab-org/gitlab/-/issues/215946 -->
+<template>
+ <div v-if="false" :class="{ 'block todo': sidebarCollapsed }">
+ <todo
+ :collapsed="sidebarCollapsed"
+ :issuable-id="1"
+ :is-todo="false"
+ :is-action-active="false"
+ issuable-type="alert"
+ @toggleTodo="() => {}"
+ />
+ </div>
+</template>
diff --git a/app/assets/javascripts/alert_management/components/system_notes/system_note.vue b/app/assets/javascripts/alert_management/components/system_notes/system_note.vue
new file mode 100644
index 00000000000..9042d51aecf
--- /dev/null
+++ b/app/assets/javascripts/alert_management/components/system_notes/system_note.vue
@@ -0,0 +1,46 @@
+<script>
+import NoteHeader from '~/notes/components/note_header.vue';
+import { spriteIcon } from '~/lib/utils/common_utils';
+
+export default {
+ components: {
+ NoteHeader,
+ },
+ props: {
+ note: {
+ type: Object,
+ required: true,
+ },
+ },
+ computed: {
+ noteAnchorId() {
+ return `note_${this.note?.id?.split('/').pop()}`;
+ },
+ noteAuthor() {
+ const {
+ author,
+ author: { id },
+ } = this.note;
+ return { ...author, id: id?.split('/').pop() };
+ },
+ iconHtml() {
+ return spriteIcon('user');
+ },
+ },
+};
+</script>
+
+<template>
+ <li :id="noteAnchorId" class="timeline-entry note system-note note-wrapper">
+ <div class="timeline-entry-inner">
+ <div class="timeline-icon" v-html="iconHtml"></div>
+ <div class="timeline-content">
+ <div class="note-header">
+ <note-header :author="noteAuthor" :created-at="note.createdAt" :note-id="note.id">
+ <span v-html="note.bodyHtml"></span>
+ </note-header>
+ </div>
+ </div>
+ </div>
+ </li>
+</template>
diff --git a/app/assets/javascripts/alert_management/constants.js b/app/assets/javascripts/alert_management/constants.js
index 9df01d9d0b5..b9670466c0f 100644
--- a/app/assets/javascripts/alert_management/constants.js
+++ b/app/assets/javascripts/alert_management/constants.js
@@ -9,38 +9,59 @@ export const ALERTS_SEVERITY_LABELS = {
UNKNOWN: s__('AlertManagement|Unknown'),
};
-export const ALERTS_STATUS = {
- OPEN: 'OPEN',
- TRIGGERED: 'TRIGGERED',
- ACKNOWLEDGED: 'ACKNOWLEDGED',
- RESOLVED: 'RESOLVED',
- ALL: 'ALL',
-};
-
export const ALERTS_STATUS_TABS = [
{
title: s__('AlertManagement|Open'),
- status: ALERTS_STATUS.OPEN,
- filters: [ALERTS_STATUS.TRIGGERED, ALERTS_STATUS.ACKNOWLEDGED],
+ status: 'OPEN',
+ filters: ['TRIGGERED', 'ACKNOWLEDGED'],
},
{
title: s__('AlertManagement|Triggered'),
- status: ALERTS_STATUS.TRIGGERED,
- filters: [ALERTS_STATUS.TRIGGERED],
+ status: 'TRIGGERED',
+ filters: 'TRIGGERED',
},
{
title: s__('AlertManagement|Acknowledged'),
- status: ALERTS_STATUS.ACKNOWLEDGED,
- filters: [ALERTS_STATUS.ACKNOWLEDGED],
+ status: 'ACKNOWLEDGED',
+ filters: 'ACKNOWLEDGED',
},
{
title: s__('AlertManagement|Resolved'),
- status: ALERTS_STATUS.RESOLVED,
- filters: [ALERTS_STATUS.RESOLVED],
+ status: 'RESOLVED',
+ filters: 'RESOLVED',
},
{
title: s__('AlertManagement|All alerts'),
- status: ALERTS_STATUS.ALL,
- filters: [ALERTS_STATUS.TRIGGERED, ALERTS_STATUS.ACKNOWLEDGED, ALERTS_STATUS.RESOLVED],
+ status: 'ALL',
+ filters: ['TRIGGERED', 'ACKNOWLEDGED', 'RESOLVED'],
},
];
+
+/* eslint-disable @gitlab/require-i18n-strings */
+
+/**
+ * Tracks snowplow event when user views alerts list
+ */
+export const trackAlertListViewsOptions = {
+ category: 'Alert Management',
+ action: 'view_alerts_list',
+};
+
+/**
+ * Tracks snowplow event when user views alert details
+ */
+export const trackAlertsDetailsViewsOptions = {
+ category: 'Alert Management',
+ action: 'view_alert_details',
+};
+
+/**
+ * Tracks snowplow event when alert status is updated
+ */
+export const trackAlertStatusUpdateOptions = {
+ category: 'Alert Management',
+ action: 'update_alert_status',
+ label: 'Status',
+};
+
+export const DEFAULT_PAGE_SIZE = 10;
diff --git a/app/assets/javascripts/alert_management/details.js b/app/assets/javascripts/alert_management/details.js
index d3523e0a29d..aa8a839ea3f 100644
--- a/app/assets/javascripts/alert_management/details.js
+++ b/app/assets/javascripts/alert_management/details.js
@@ -8,7 +8,7 @@ Vue.use(VueApollo);
export default selector => {
const domEl = document.querySelector(selector);
- const { alertId, projectPath, newIssuePath } = domEl.dataset;
+ const { alertId, projectPath, projectIssuesPath } = domEl.dataset;
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(
@@ -39,7 +39,7 @@ export default selector => {
props: {
alertId,
projectPath,
- newIssuePath,
+ projectIssuesPath,
},
});
},
diff --git a/app/assets/javascripts/alert_management/graphql/fragments/alert_note.fragment.graphql b/app/assets/javascripts/alert_management/graphql/fragments/alert_note.fragment.graphql
new file mode 100644
index 00000000000..c72300e9757
--- /dev/null
+++ b/app/assets/javascripts/alert_management/graphql/fragments/alert_note.fragment.graphql
@@ -0,0 +1,16 @@
+#import "~/graphql_shared/fragments/author.fragment.graphql"
+
+fragment AlertNote on Note {
+ id
+ author {
+ id
+ state
+ ...Author
+ }
+ body
+ bodyHtml
+ createdAt
+ discussion {
+ id
+ }
+}
diff --git a/app/assets/javascripts/alert_management/graphql/fragments/detailItem.fragment.graphql b/app/assets/javascripts/alert_management/graphql/fragments/detailItem.fragment.graphql
deleted file mode 100644
index df802616e97..00000000000
--- a/app/assets/javascripts/alert_management/graphql/fragments/detailItem.fragment.graphql
+++ /dev/null
@@ -1,11 +0,0 @@
-#import "./listItem.fragment.graphql"
-
-fragment AlertDetailItem on AlertManagementAlert {
- ...AlertListItem
- createdAt
- monitoringTool
- service
- description
- updatedAt
- details
-}
diff --git a/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql b/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql
new file mode 100644
index 00000000000..cbe7e169be3
--- /dev/null
+++ b/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql
@@ -0,0 +1,17 @@
+#import "./list_item.fragment.graphql"
+#import "./alert_note.fragment.graphql"
+
+fragment AlertDetailItem on AlertManagementAlert {
+ ...AlertListItem
+ createdAt
+ monitoringTool
+ service
+ description
+ updatedAt
+ details
+ notes {
+ nodes {
+ ...AlertNote
+ }
+ }
+}
diff --git a/app/assets/javascripts/alert_management/graphql/fragments/listItem.fragment.graphql b/app/assets/javascripts/alert_management/graphql/fragments/listItem.fragment.graphql
deleted file mode 100644
index fffe07b0cfd..00000000000
--- a/app/assets/javascripts/alert_management/graphql/fragments/listItem.fragment.graphql
+++ /dev/null
@@ -1,9 +0,0 @@
-fragment AlertListItem on AlertManagementAlert {
- iid
- title
- severity
- status
- startedAt
- endedAt
- eventCount
-}
diff --git a/app/assets/javascripts/alert_management/graphql/fragments/list_item.fragment.graphql b/app/assets/javascripts/alert_management/graphql/fragments/list_item.fragment.graphql
new file mode 100644
index 00000000000..746c4435f38
--- /dev/null
+++ b/app/assets/javascripts/alert_management/graphql/fragments/list_item.fragment.graphql
@@ -0,0 +1,15 @@
+fragment AlertListItem on AlertManagementAlert {
+ iid
+ title
+ severity
+ status
+ startedAt
+ endedAt
+ eventCount
+ issueIid
+ assignees {
+ nodes {
+ username
+ }
+ }
+}
diff --git a/app/assets/javascripts/alert_management/graphql/mutations/alert_set_assignees.graphql b/app/assets/javascripts/alert_management/graphql/mutations/alert_set_assignees.graphql
new file mode 100644
index 00000000000..efeaf8fa372
--- /dev/null
+++ b/app/assets/javascripts/alert_management/graphql/mutations/alert_set_assignees.graphql
@@ -0,0 +1,15 @@
+mutation($projectPath: ID!, $assigneeUsernames: [String!]!, $iid: String!) {
+ alertSetAssignees(
+ input: { iid: $iid, assigneeUsernames: $assigneeUsernames, projectPath: $projectPath }
+ ) {
+ errors
+ alert {
+ iid
+ assignees {
+ nodes {
+ username
+ }
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/alert_management/graphql/mutations/create_issue_from_alert.graphql b/app/assets/javascripts/alert_management/graphql/mutations/create_issue_from_alert.graphql
new file mode 100644
index 00000000000..664596ab88f
--- /dev/null
+++ b/app/assets/javascripts/alert_management/graphql/mutations/create_issue_from_alert.graphql
@@ -0,0 +1,8 @@
+mutation ($projectPath: ID!, $iid: String!) {
+ createAlertIssue(input: { iid: $iid, projectPath: $projectPath }) {
+ errors
+ issue {
+ iid
+ }
+ }
+}
diff --git a/app/assets/javascripts/alert_management/graphql/mutations/update_alert_status.graphql b/app/assets/javascripts/alert_management/graphql/mutations/update_alert_status.graphql
index 009ae0b2930..09151f233f5 100644
--- a/app/assets/javascripts/alert_management/graphql/mutations/update_alert_status.graphql
+++ b/app/assets/javascripts/alert_management/graphql/mutations/update_alert_status.graphql
@@ -4,6 +4,7 @@ mutation ($projectPath: ID!, $status: AlertManagementStatus!, $iid: String!) {
alert {
iid,
status,
+ endedAt
}
}
}
diff --git a/app/assets/javascripts/alert_management/graphql/queries/details.query.graphql b/app/assets/javascripts/alert_management/graphql/queries/details.query.graphql
index 7c77715fad2..c02b8accdd1 100644
--- a/app/assets/javascripts/alert_management/graphql/queries/details.query.graphql
+++ b/app/assets/javascripts/alert_management/graphql/queries/details.query.graphql
@@ -1,4 +1,4 @@
-#import "../fragments/detailItem.fragment.graphql"
+#import "../fragments/detail_item.fragment.graphql"
query alertDetails($fullPath: ID!, $alertId: String) {
project(fullPath: $fullPath) {
diff --git a/app/assets/javascripts/alert_management/graphql/queries/getAlerts.query.graphql b/app/assets/javascripts/alert_management/graphql/queries/getAlerts.query.graphql
deleted file mode 100644
index 54b66389d5b..00000000000
--- a/app/assets/javascripts/alert_management/graphql/queries/getAlerts.query.graphql
+++ /dev/null
@@ -1,11 +0,0 @@
-#import "../fragments/listItem.fragment.graphql"
-
-query getAlerts($projectPath: ID!, $statuses: [AlertManagementStatus!]) {
- project(fullPath: $projectPath) {
- alertManagementAlerts(statuses: $statuses) {
- nodes {
- ...AlertListItem
- }
- }
- }
-}
diff --git a/app/assets/javascripts/alert_management/graphql/queries/get_alerts.query.graphql b/app/assets/javascripts/alert_management/graphql/queries/get_alerts.query.graphql
new file mode 100644
index 00000000000..1d3c3c83cc1
--- /dev/null
+++ b/app/assets/javascripts/alert_management/graphql/queries/get_alerts.query.graphql
@@ -0,0 +1,32 @@
+#import "../fragments/list_item.fragment.graphql"
+
+query getAlerts(
+ $projectPath: ID!,
+ $statuses: [AlertManagementStatus!],
+ $sort: AlertManagementAlertSort,
+ $firstPageSize: Int,
+ $lastPageSize: Int,
+ $prevPageCursor: String = ""
+ $nextPageCursor: String = ""
+) {
+ project(fullPath: $projectPath, ) {
+ alertManagementAlerts(
+ statuses: $statuses,
+ sort: $sort,
+ first: $firstPageSize
+ last: $lastPageSize,
+ after: $nextPageCursor,
+ before: $prevPageCursor
+ ) {
+ nodes {
+ ...AlertListItem
+ },
+ pageInfo {
+ hasNextPage
+ endCursor
+ hasPreviousPage
+ startCursor
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/alert_management/graphql/queries/get_count_by_status.query.graphql b/app/assets/javascripts/alert_management/graphql/queries/get_count_by_status.query.graphql
new file mode 100644
index 00000000000..1143050200c
--- /dev/null
+++ b/app/assets/javascripts/alert_management/graphql/queries/get_count_by_status.query.graphql
@@ -0,0 +1,11 @@
+query getAlertsCount($projectPath: ID!) {
+ project(fullPath: $projectPath) {
+ alertManagementAlertStatusCounts {
+ all
+ open
+ acknowledged
+ resolved
+ triggered
+ }
+ }
+}
diff --git a/app/assets/javascripts/alert_management/services/index.js b/app/assets/javascripts/alert_management/services/index.js
deleted file mode 100644
index 787603d3e7a..00000000000
--- a/app/assets/javascripts/alert_management/services/index.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import axios from '~/lib/utils/axios_utils';
-
-export default {
- getAlertManagementList({ endpoint }) {
- return axios.get(endpoint);
- },
-};
diff --git a/app/assets/javascripts/alerts_service_settings/components/alerts_service_form.vue b/app/assets/javascripts/alerts_service_settings/components/alerts_service_form.vue
index 410c5c00e8a..ac30b086875 100644
--- a/app/assets/javascripts/alerts_service_settings/components/alerts_service_form.vue
+++ b/app/assets/javascripts/alerts_service_settings/components/alerts_service_form.vue
@@ -1,26 +1,37 @@
<script>
import {
- GlDeprecatedButton,
+ GlButton,
GlFormGroup,
GlFormInput,
+ GlLink,
GlModal,
GlModalDirective,
+ GlSprintf,
} from '@gitlab/ui';
-import { escape } from 'lodash';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import ToggleButton from '~/vue_shared/components/toggle_button.vue';
import axios from '~/lib/utils/axios_utils';
-import { s__, __, sprintf } from '~/locale';
+import { s__, __ } from '~/locale';
import createFlash from '~/flash';
export default {
+ i18n: {
+ usageSection: s__(
+ 'AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page.',
+ ),
+ setupSection: s__(
+ "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint.",
+ ),
+ },
COPY_TO_CLIPBOARD: __('Copy'),
RESET_KEY: __('Reset key'),
components: {
- GlDeprecatedButton,
+ GlButton,
GlFormGroup,
GlFormInput,
+ GlLink,
GlModal,
+ GlSprintf,
ClipboardButton,
ToggleButton,
},
@@ -28,6 +39,14 @@ export default {
'gl-modal': GlModalDirective,
},
props: {
+ alertsSetupUrl: {
+ type: String,
+ required: true,
+ },
+ alertsUsageUrl: {
+ type: String,
+ required: true,
+ },
initialAuthorizationKey: {
type: String,
required: false,
@@ -41,11 +60,6 @@ export default {
type: String,
required: true,
},
- learnMoreUrl: {
- type: String,
- required: false,
- default: '',
- },
initialActivated: {
type: Boolean,
required: true,
@@ -59,27 +73,17 @@ export default {
};
},
computed: {
- learnMoreDescription() {
- return sprintf(
- s__(
- 'AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts.',
- ),
+ sections() {
+ return [
{
- linkStart: `<a href="${escape(
- this.learnMoreUrl,
- )}" target="_blank" rel="noopener noreferrer">`,
- linkEnd: '</a>',
+ text: this.$options.i18n.usageSection,
+ url: this.alertsUsageUrl,
},
- false,
- );
- },
- sectionDescription() {
- const desc = s__(
- 'AlertService|Each alert source must be authorized using the following URL and authorization key.',
- );
- const learnMoreDesc = this.learnMoreDescription ? ` ${this.learnMoreDescription}` : '';
-
- return `${desc}${learnMoreDesc}`;
+ {
+ text: this.$options.i18n.setupSection,
+ url: this.alertsSetupUrl,
+ },
+ ];
},
},
watch: {
@@ -126,7 +130,15 @@ export default {
<template>
<div>
- <p v-html="sectionDescription"></p>
+ <div data-testid="description">
+ <p v-for="section in sections" :key="section.text">
+ <gl-sprintf :message="section.text">
+ <template #link="{ content }">
+ <gl-link :href="section.url" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </p>
+ </div>
<gl-form-group :label="__('Active')" label-for="activated" label-class="label-bold">
<toggle-button
id="activated"
@@ -155,9 +167,7 @@ export default {
<clipboard-button :text="authorizationKey" :title="$options.COPY_TO_CLIPBOARD" />
</span>
</div>
- <gl-deprecated-button v-gl-modal.authKeyModal class="mt-2">{{
- $options.RESET_KEY
- }}</gl-deprecated-button>
+ <gl-button v-gl-modal.authKeyModal class="mt-2">{{ $options.RESET_KEY }}</gl-button>
<gl-modal
modal-id="authKeyModal"
:title="$options.RESET_KEY"
diff --git a/app/assets/javascripts/alerts_service_settings/index.js b/app/assets/javascripts/alerts_service_settings/index.js
index d49725c6a4d..c26adf24a7f 100644
--- a/app/assets/javascripts/alerts_service_settings/index.js
+++ b/app/assets/javascripts/alerts_service_settings/index.js
@@ -7,7 +7,14 @@ export default el => {
return null;
}
- const { activated: activatedStr, formPath, authorizationKey, url, learnMoreUrl } = el.dataset;
+ const {
+ activated: activatedStr,
+ alertsSetupUrl,
+ alertsUsageUrl,
+ formPath,
+ authorizationKey,
+ url,
+ } = el.dataset;
const activated = parseBoolean(activatedStr);
return new Vue({
@@ -15,9 +22,10 @@ export default el => {
render(createElement) {
return createElement(AlertsServiceForm, {
props: {
+ alertsSetupUrl,
+ alertsUsageUrl,
initialActivated: activated,
formPath,
- learnMoreUrl,
initialAuthorizationKey: authorizationKey,
url,
},
diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js
index e527659a939..94d155840ea 100644
--- a/app/assets/javascripts/api.js
+++ b/app/assets/javascripts/api.js
@@ -38,6 +38,7 @@ const Api = {
userPostStatusPath: '/api/:version/user/status',
commitPath: '/api/:version/projects/:id/repository/commits',
applySuggestionPath: '/api/:version/suggestions/:id/apply',
+ applySuggestionBatchPath: '/api/:version/suggestions/batch_apply',
commitPipelinesPath: '/:project_id/commit/:sha/pipelines',
branchSinglePath: '/api/:version/projects/:id/repository/branches/:branch',
createBranchPath: '/api/:version/projects/:id/repository/branches',
@@ -51,8 +52,10 @@ const Api = {
pipelinesPath: '/api/:version/projects/:id/pipelines/',
environmentsPath: '/api/:version/projects/:id/environments',
rawFilePath: '/api/:version/projects/:id/repository/files/:path/raw',
+ issuePath: '/api/:version/projects/:id/issues/:issue_iid',
+ tagsPath: '/api/:version/projects/:id/repository/tags',
- group(groupId, callback) {
+ group(groupId, callback = () => {}) {
const url = Api.buildUrl(Api.groupPath).replace(':id', groupId);
return axios.get(url).then(({ data }) => {
callback(data);
@@ -321,6 +324,12 @@ const Api = {
return axios.put(url);
},
+ applySuggestionBatch(ids) {
+ const url = Api.buildUrl(Api.applySuggestionBatchPath);
+
+ return axios.put(url, { ids });
+ },
+
commitPipelines(projectId, sha) {
const encodedProjectId = projectId
.split('/')
@@ -540,6 +549,34 @@ const Api = {
return axios.get(url, { params });
},
+ updateIssue(project, issue, data = {}) {
+ const url = Api.buildUrl(Api.issuePath)
+ .replace(':id', encodeURIComponent(project))
+ .replace(':issue_iid', encodeURIComponent(issue));
+
+ return axios.put(url, data);
+ },
+
+ updateMergeRequest(project, mergeRequest, data = {}) {
+ const url = Api.buildUrl(Api.projectMergeRequestPath)
+ .replace(':id', encodeURIComponent(project))
+ .replace(':mrid', encodeURIComponent(mergeRequest));
+
+ return axios.put(url, data);
+ },
+
+ tags(id, query = '', options = {}) {
+ const url = Api.buildUrl(this.tagsPath).replace(':id', encodeURIComponent(id));
+
+ return axios.get(url, {
+ params: {
+ search: query,
+ per_page: DEFAULT_PER_PAGE,
+ ...options,
+ },
+ });
+ },
+
buildUrl(url) {
return joinPaths(gon.relative_url_root || '', url.replace(':version', gon.api_version));
},
diff --git a/app/assets/javascripts/authentication/mount_2fa.js b/app/assets/javascripts/authentication/mount_2fa.js
new file mode 100644
index 00000000000..9917151ac81
--- /dev/null
+++ b/app/assets/javascripts/authentication/mount_2fa.js
@@ -0,0 +1,14 @@
+import $ from 'jquery';
+import initU2F from './u2f';
+import U2FRegister from './u2f/register';
+
+export const mount2faAuthentication = () => {
+ // Soon this will conditionally mount a webauthn app (see https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26692)
+ initU2F();
+};
+
+export const mount2faRegistration = () => {
+ // Soon this will conditionally mount a webauthn app (see https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26692)
+ const u2fRegister = new U2FRegister($('#js-register-u2f'), gon.u2f);
+ u2fRegister.start();
+};
diff --git a/app/assets/javascripts/authentication/u2f/authenticate.js b/app/assets/javascripts/authentication/u2f/authenticate.js
new file mode 100644
index 00000000000..201cd5c2e61
--- /dev/null
+++ b/app/assets/javascripts/authentication/u2f/authenticate.js
@@ -0,0 +1,107 @@
+import $ from 'jquery';
+import { template as lodashTemplate, omit } from 'lodash';
+import importU2FLibrary from './util';
+import U2FError from './error';
+
+// Authenticate U2F (universal 2nd factor) devices for users to authenticate with.
+//
+// State Flow #1: setup -> in_progress -> authenticated -> POST to server
+// State Flow #2: setup -> in_progress -> error -> setup
+export default class U2FAuthenticate {
+ constructor(container, form, u2fParams, fallbackButton, fallbackUI) {
+ this.u2fUtils = null;
+ this.container = container;
+ this.renderAuthenticated = this.renderAuthenticated.bind(this);
+ this.renderError = this.renderError.bind(this);
+ this.renderInProgress = this.renderInProgress.bind(this);
+ this.renderTemplate = this.renderTemplate.bind(this);
+ this.authenticate = this.authenticate.bind(this);
+ this.start = this.start.bind(this);
+ this.appId = u2fParams.app_id;
+ this.challenge = u2fParams.challenge;
+ this.form = form;
+ this.fallbackButton = fallbackButton;
+ this.fallbackUI = fallbackUI;
+ if (this.fallbackButton) {
+ this.fallbackButton.addEventListener('click', this.switchToFallbackUI.bind(this));
+ }
+
+ // The U2F Javascript API v1.1 requires a single challenge, with
+ // _no challenges per-request_. The U2F Javascript API v1.0 requires a
+ // challenge per-request, which is done by copying the single challenge
+ // into every request.
+ //
+ // In either case, we don't need the per-request challenges that the server
+ // has generated, so we can remove them.
+ //
+ // Note: The server library fixes this behaviour in (unreleased) version 1.0.0.
+ // This can be removed once we upgrade.
+ // https://github.com/castle/ruby-u2f/commit/103f428071a81cd3d5f80c2e77d522d5029946a4
+ this.signRequests = u2fParams.sign_requests.map(request => omit(request, 'challenge'));
+
+ this.templates = {
+ setup: '#js-authenticate-token-2fa-setup',
+ inProgress: '#js-authenticate-token-2fa-in-progress',
+ error: '#js-authenticate-token-2fa-error',
+ authenticated: '#js-authenticate-token-2fa-authenticated',
+ };
+ }
+
+ start() {
+ return importU2FLibrary()
+ .then(utils => {
+ this.u2fUtils = utils;
+ this.renderInProgress();
+ })
+ .catch(() => this.switchToFallbackUI());
+ }
+
+ authenticate() {
+ return this.u2fUtils.sign(
+ this.appId,
+ this.challenge,
+ this.signRequests,
+ response => {
+ if (response.errorCode) {
+ const error = new U2FError(response.errorCode, 'authenticate');
+ return this.renderError(error);
+ }
+ return this.renderAuthenticated(JSON.stringify(response));
+ },
+ 10,
+ );
+ }
+
+ renderTemplate(name, params) {
+ const templateString = $(this.templates[name]).html();
+ const template = lodashTemplate(templateString);
+ return this.container.html(template(params));
+ }
+
+ renderInProgress() {
+ this.renderTemplate('inProgress');
+ return this.authenticate();
+ }
+
+ renderError(error) {
+ this.renderTemplate('error', {
+ error_message: error.message(),
+ error_code: error.errorCode,
+ });
+ return this.container.find('#js-token-2fa-try-again').on('click', this.renderInProgress);
+ }
+
+ renderAuthenticated(deviceResponse) {
+ this.renderTemplate('authenticated');
+ const container = this.container[0];
+ container.querySelector('#js-device-response').value = deviceResponse;
+ container.querySelector(this.form).submit();
+ this.fallbackButton.classList.add('hidden');
+ }
+
+ switchToFallbackUI() {
+ this.fallbackButton.classList.add('hidden');
+ this.container[0].classList.add('hidden');
+ this.fallbackUI.classList.remove('hidden');
+ }
+}
diff --git a/app/assets/javascripts/u2f/error.js b/app/assets/javascripts/authentication/u2f/error.js
index ca0fc0700ad..ca0fc0700ad 100644
--- a/app/assets/javascripts/u2f/error.js
+++ b/app/assets/javascripts/authentication/u2f/error.js
diff --git a/app/assets/javascripts/authentication/u2f/index.js b/app/assets/javascripts/authentication/u2f/index.js
new file mode 100644
index 00000000000..f129acca1c3
--- /dev/null
+++ b/app/assets/javascripts/authentication/u2f/index.js
@@ -0,0 +1,17 @@
+import $ from 'jquery';
+import U2FAuthenticate from './authenticate';
+
+export default () => {
+ if (!gon.u2f) return;
+
+ const u2fAuthenticate = new U2FAuthenticate(
+ $('#js-authenticate-token-2fa'),
+ '#js-login-token-2fa-form',
+ gon.u2f,
+ document.querySelector('#js-login-2fa-device'),
+ document.querySelector('.js-2fa-form'),
+ );
+ u2fAuthenticate.start();
+ // needed in rspec (FakeU2fDevice)
+ gl.u2fAuthenticate = u2fAuthenticate;
+};
diff --git a/app/assets/javascripts/authentication/u2f/register.js b/app/assets/javascripts/authentication/u2f/register.js
new file mode 100644
index 00000000000..52c0ce1fc04
--- /dev/null
+++ b/app/assets/javascripts/authentication/u2f/register.js
@@ -0,0 +1,94 @@
+import $ from 'jquery';
+import { template as lodashTemplate } from 'lodash';
+import importU2FLibrary from './util';
+import U2FError from './error';
+
+// Register U2F (universal 2nd factor) devices for users to authenticate with.
+//
+// State Flow #1: setup -> in_progress -> registered -> POST to server
+// State Flow #2: setup -> in_progress -> error -> setup
+export default class U2FRegister {
+ constructor(container, u2fParams) {
+ this.u2fUtils = null;
+ this.container = container;
+ this.renderNotSupported = this.renderNotSupported.bind(this);
+ this.renderRegistered = this.renderRegistered.bind(this);
+ this.renderError = this.renderError.bind(this);
+ this.renderInProgress = this.renderInProgress.bind(this);
+ this.renderSetup = this.renderSetup.bind(this);
+ this.renderTemplate = this.renderTemplate.bind(this);
+ this.register = this.register.bind(this);
+ this.start = this.start.bind(this);
+ this.appId = u2fParams.app_id;
+ this.registerRequests = u2fParams.register_requests;
+ this.signRequests = u2fParams.sign_requests;
+
+ this.templates = {
+ notSupported: '#js-register-u2f-not-supported',
+ setup: '#js-register-u2f-setup',
+ inProgress: '#js-register-u2f-in-progress',
+ error: '#js-register-u2f-error',
+ registered: '#js-register-u2f-registered',
+ };
+ }
+
+ start() {
+ return importU2FLibrary()
+ .then(utils => {
+ this.u2fUtils = utils;
+ this.renderSetup();
+ })
+ .catch(() => this.renderNotSupported());
+ }
+
+ register() {
+ return this.u2fUtils.register(
+ this.appId,
+ this.registerRequests,
+ this.signRequests,
+ response => {
+ if (response.errorCode) {
+ const error = new U2FError(response.errorCode, 'register');
+ return this.renderError(error);
+ }
+ return this.renderRegistered(JSON.stringify(response));
+ },
+ 10,
+ );
+ }
+
+ renderTemplate(name, params) {
+ const templateString = $(this.templates[name]).html();
+ const template = lodashTemplate(templateString);
+ return this.container.html(template(params));
+ }
+
+ renderSetup() {
+ this.renderTemplate('setup');
+ return this.container.find('#js-setup-u2f-device').on('click', this.renderInProgress);
+ }
+
+ renderInProgress() {
+ this.renderTemplate('inProgress');
+ return this.register();
+ }
+
+ renderError(error) {
+ this.renderTemplate('error', {
+ error_message: error.message(),
+ error_code: error.errorCode,
+ });
+ return this.container.find('#js-token-2fa-try-again').on('click', this.renderSetup);
+ }
+
+ renderRegistered(deviceResponse) {
+ this.renderTemplate('registered');
+ // Prefer to do this instead of interpolating using Underscore templates
+ // because of JSON escaping issues.
+ return this.container.find('#js-device-response').val(deviceResponse);
+ }
+
+ renderNotSupported() {
+ return this.renderTemplate('notSupported');
+ }
+}
diff --git a/app/assets/javascripts/u2f/util.js b/app/assets/javascripts/authentication/u2f/util.js
index b706481c02f..b706481c02f 100644
--- a/app/assets/javascripts/u2f/util.js
+++ b/app/assets/javascripts/authentication/u2f/util.js
diff --git a/app/assets/javascripts/avatar_picker.js b/app/assets/javascripts/avatar_picker.js
deleted file mode 100644
index d38e0b4abaa..00000000000
--- a/app/assets/javascripts/avatar_picker.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import $ from 'jquery';
-
-export default function initAvatarPicker() {
- $('.js-choose-avatar-button').on('click', function onClickAvatar() {
- const form = $(this).closest('form');
- return form.find('.js-avatar-input').click();
- });
-
- $('.js-avatar-input').on('change', function onChangeAvatarInput() {
- const form = $(this).closest('form');
- const filename = $(this)
- .val()
- .replace(/^.*[\\\/]/, ''); // eslint-disable-line no-useless-escape
- return form.find('.js-avatar-filename').text(filename);
- });
-}
diff --git a/app/assets/javascripts/badges/components/badge.vue b/app/assets/javascripts/badges/components/badge.vue
index f9dd153eba0..3242993b06a 100644
--- a/app/assets/javascripts/badges/components/badge.vue
+++ b/app/assets/javascripts/badges/components/badge.vue
@@ -84,15 +84,10 @@ export default {
<div v-show="hasError" class="btn-group">
<div class="btn btn-default btn-sm disabled">
- <icon
- :size="16"
- class="prepend-left-8 append-right-8"
- name="doc-image"
- aria-hidden="true"
- />
+ <icon :size="16" class="gl-ml-3 gl-mr-3" name="doc-image" aria-hidden="true" />
</div>
<div class="btn btn-default btn-sm disabled">
- <span class="prepend-left-8 append-right-8">{{ s__('Badges|No badge image') }}</span>
+ <span class="gl-ml-3 gl-mr-3">{{ s__('Badges|No badge image') }}</span>
</div>
</div>
diff --git a/app/assets/javascripts/badges/components/badge_list_row.vue b/app/assets/javascripts/badges/components/badge_list_row.vue
index bb363b8d85e..bad14666bb2 100644
--- a/app/assets/javascripts/badges/components/badge_list_row.vue
+++ b/app/assets/javascripts/badges/components/badge_list_row.vue
@@ -54,7 +54,7 @@ export default {
<div v-if="canEditBadge" class="table-action-buttons">
<button
:disabled="badge.isDeleting"
- class="btn btn-default append-right-8"
+ class="btn btn-default gl-mr-3"
type="button"
@click="editBadge(badge)"
>
diff --git a/app/assets/javascripts/batch_comments/components/diff_file_drafts.vue b/app/assets/javascripts/batch_comments/components/diff_file_drafts.vue
new file mode 100644
index 00000000000..570954c7200
--- /dev/null
+++ b/app/assets/javascripts/batch_comments/components/diff_file_drafts.vue
@@ -0,0 +1,41 @@
+<script>
+import { mapGetters } from 'vuex';
+import imageDiff from '~/diffs/mixins/image_diff';
+import DraftNote from './draft_note.vue';
+
+export default {
+ components: {
+ DraftNote,
+ },
+ mixins: [imageDiff],
+ props: {
+ fileHash: {
+ type: String,
+ required: true,
+ },
+ },
+ computed: {
+ ...mapGetters('batchComments', ['draftsForFile']),
+ drafts() {
+ return this.draftsForFile(this.fileHash);
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <div
+ v-for="(draft, index) in drafts"
+ :key="draft.id"
+ class="discussion-notes diff-discussions position-relative"
+ >
+ <div class="notes">
+ <span class="d-block btn-transparent badge badge-pill is-draft js-diff-notes-index">
+ {{ toggleText(draft, index) }}
+ </span>
+ <draft-note :draft="draft" />
+ </div>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/batch_comments/components/draft_note.vue b/app/assets/javascripts/batch_comments/components/draft_note.vue
new file mode 100644
index 00000000000..963d104b6b3
--- /dev/null
+++ b/app/assets/javascripts/batch_comments/components/draft_note.vue
@@ -0,0 +1,113 @@
+<script>
+import { mapActions, mapGetters, mapState } from 'vuex';
+import NoteableNote from '~/notes/components/noteable_note.vue';
+import LoadingButton from '~/vue_shared/components/loading_button.vue';
+import PublishButton from './publish_button.vue';
+
+export default {
+ components: {
+ NoteableNote,
+ PublishButton,
+ LoadingButton,
+ },
+ props: {
+ draft: {
+ type: Object,
+ required: true,
+ },
+ diffFile: {
+ type: Object,
+ required: false,
+ default: () => ({}),
+ },
+ line: {
+ type: Object,
+ required: false,
+ default: null,
+ },
+ },
+ data() {
+ return {
+ isEditingDraft: false,
+ };
+ },
+ computed: {
+ ...mapState('batchComments', ['isPublishing']),
+ ...mapGetters('batchComments', ['isPublishingDraft']),
+ draftCommands() {
+ return this.draft.references.commands;
+ },
+ },
+ mounted() {
+ if (window.location.hash && window.location.hash === `#note_${this.draft.id}`) {
+ this.scrollToDraft(this.draft);
+ }
+ },
+ methods: {
+ ...mapActions('batchComments', [
+ 'deleteDraft',
+ 'updateDraft',
+ 'publishSingleDraft',
+ 'scrollToDraft',
+ 'toggleResolveDiscussion',
+ ]),
+ update(data) {
+ this.updateDraft(data);
+ },
+ publishNow() {
+ this.publishSingleDraft(this.draft.id);
+ },
+ handleEditing() {
+ this.isEditingDraft = true;
+ },
+ handleNotEditing() {
+ this.isEditingDraft = false;
+ },
+ },
+};
+</script>
+<template>
+ <article class="draft-note-component note-wrapper">
+ <ul class="notes draft-notes">
+ <noteable-note
+ :note="draft"
+ :diff-lines="diffFile.highlighted_diff_lines"
+ :line="line"
+ class="draft-note"
+ @handleEdit="handleEditing"
+ @cancelForm="handleNotEditing"
+ @updateSuccess="handleNotEditing"
+ @handleDeleteNote="deleteDraft"
+ @handleUpdateNote="update"
+ @toggleResolveStatus="toggleResolveDiscussion(draft.id)"
+ >
+ <strong slot="note-header-info" class="badge draft-pending-label append-right-4">
+ {{ __('Pending') }}
+ </strong>
+ </noteable-note>
+ </ul>
+
+ <template v-if="!isEditingDraft">
+ <div
+ v-if="draftCommands"
+ class="referenced-commands draft-note-commands"
+ v-html="draftCommands"
+ ></div>
+
+ <p class="draft-note-actions d-flex">
+ <publish-button
+ :show-count="true"
+ :should-publish="false"
+ class="btn btn-success btn-inverted gl-mr-3"
+ />
+ <loading-button
+ ref="publishNowButton"
+ :loading="isPublishingDraft(draft.id) || isPublishing"
+ :label="__('Add comment now')"
+ container-class="btn btn-inverted"
+ @click="publishNow"
+ />
+ </p>
+ </template>
+ </article>
+</template>
diff --git a/app/assets/javascripts/batch_comments/components/drafts_count.vue b/app/assets/javascripts/batch_comments/components/drafts_count.vue
new file mode 100644
index 00000000000..f1180760c4d
--- /dev/null
+++ b/app/assets/javascripts/batch_comments/components/drafts_count.vue
@@ -0,0 +1,15 @@
+<script>
+import { mapGetters } from 'vuex';
+
+export default {
+ computed: {
+ ...mapGetters('batchComments', ['draftsCount']),
+ },
+};
+</script>
+<template>
+ <span class="drafts-count-component">
+ <span class="drafts-count-number">{{ draftsCount }}</span>
+ <span class="sr-only"> {{ n__('draft', 'drafts', draftsCount) }} </span>
+ </span>
+</template>
diff --git a/app/assets/javascripts/batch_comments/components/inline_draft_comment_row.vue b/app/assets/javascripts/batch_comments/components/inline_draft_comment_row.vue
new file mode 100644
index 00000000000..385725cd109
--- /dev/null
+++ b/app/assets/javascripts/batch_comments/components/inline_draft_comment_row.vue
@@ -0,0 +1,32 @@
+<script>
+import DraftNote from './draft_note.vue';
+
+export default {
+ components: {
+ DraftNote,
+ },
+ props: {
+ draft: {
+ type: Object,
+ required: true,
+ },
+ diffFile: {
+ type: Object,
+ required: true,
+ },
+ line: {
+ type: Object,
+ required: false,
+ default: null,
+ },
+ },
+};
+</script>
+
+<template>
+ <tr class="notes_holder js-temp-notes-holder">
+ <td class="notes-content" colspan="4">
+ <div class="content"><draft-note :draft="draft" :diff-file="diffFile" :line="line" /></div>
+ </td>
+ </tr>
+</template>
diff --git a/app/assets/javascripts/batch_comments/components/parallel_draft_comment_row.vue b/app/assets/javascripts/batch_comments/components/parallel_draft_comment_row.vue
new file mode 100644
index 00000000000..68fd20e56bc
--- /dev/null
+++ b/app/assets/javascripts/batch_comments/components/parallel_draft_comment_row.vue
@@ -0,0 +1,45 @@
+<script>
+import { mapGetters } from 'vuex';
+import DraftNote from './draft_note.vue';
+
+export default {
+ components: {
+ DraftNote,
+ },
+ props: {
+ line: {
+ type: Object,
+ required: true,
+ },
+ diffFileContentSha: {
+ type: String,
+ required: true,
+ },
+ },
+ computed: {
+ ...mapGetters('batchComments', ['draftForLine']),
+ className() {
+ return this.leftDraft > 0 || this.rightDraft > 0 ? '' : 'js-temp-notes-holder';
+ },
+ leftDraft() {
+ return this.draftForLine(this.diffFileContentSha, this.line, 'left');
+ },
+ rightDraft() {
+ return this.draftForLine(this.diffFileContentSha, this.line, 'right');
+ },
+ },
+};
+</script>
+
+<template>
+ <tr :class="className" class="notes_holder">
+ <td class="notes_line old"></td>
+ <td class="notes-content parallel old" colspan="2">
+ <div v-if="leftDraft.isDraft" class="content"><draft-note :draft="leftDraft" /></div>
+ </td>
+ <td class="notes_line new"></td>
+ <td class="notes-content parallel new" colspan="2">
+ <div v-if="rightDraft.isDraft" class="content"><draft-note :draft="rightDraft" /></div>
+ </td>
+ </tr>
+</template>
diff --git a/app/assets/javascripts/batch_comments/components/preview_dropdown.vue b/app/assets/javascripts/batch_comments/components/preview_dropdown.vue
new file mode 100644
index 00000000000..195e1b7ec5c
--- /dev/null
+++ b/app/assets/javascripts/batch_comments/components/preview_dropdown.vue
@@ -0,0 +1,111 @@
+<script>
+import { mapActions, mapGetters, mapState } from 'vuex';
+import { GlLoadingIcon } from '@gitlab/ui';
+import { sprintf, n__ } from '~/locale';
+import Icon from '~/vue_shared/components/icon.vue';
+import DraftsCount from './drafts_count.vue';
+import PublishButton from './publish_button.vue';
+import PreviewItem from './preview_item.vue';
+
+export default {
+ components: {
+ GlLoadingIcon,
+ Icon,
+ DraftsCount,
+ PublishButton,
+ PreviewItem,
+ },
+ computed: {
+ ...mapGetters(['isNotesFetched']),
+ ...mapGetters('batchComments', ['draftsCount', 'sortedDrafts']),
+ ...mapState('batchComments', ['showPreviewDropdown']),
+ dropdownTitle() {
+ return sprintf(
+ n__('%{count} pending comment', '%{count} pending comments', this.draftsCount),
+ { count: this.draftsCount },
+ );
+ },
+ },
+ watch: {
+ showPreviewDropdown() {
+ if (this.showPreviewDropdown && this.$refs.dropdown) {
+ this.$nextTick(() => this.$refs.dropdown.focus());
+ }
+ },
+ },
+ mounted() {
+ document.addEventListener('click', this.onClickDocument);
+ },
+ beforeDestroy() {
+ document.removeEventListener('click', this.onClickDocument);
+ },
+ methods: {
+ ...mapActions('batchComments', ['toggleReviewDropdown']),
+ isLast(index) {
+ return index === this.sortedDrafts.length - 1;
+ },
+ onClickDocument({ target }) {
+ if (
+ this.showPreviewDropdown &&
+ !target.closest('.review-preview-dropdown, .js-publish-draft-button')
+ ) {
+ this.toggleReviewDropdown();
+ }
+ },
+ },
+};
+</script>
+
+<template>
+ <div
+ class="dropdown float-right review-preview-dropdown"
+ :class="{
+ show: showPreviewDropdown,
+ }"
+ >
+ <button
+ ref="dropdown"
+ type="button"
+ class="btn btn-success review-preview-dropdown-toggle qa-review-preview-toggle"
+ @click="toggleReviewDropdown"
+ >
+ {{ __('Finish review') }}
+ <drafts-count />
+ <icon name="angle-up" />
+ </button>
+ <div
+ class="dropdown-menu dropdown-menu-large dropdown-menu-right dropdown-open-top"
+ :class="{
+ show: showPreviewDropdown,
+ }"
+ >
+ <div class="dropdown-title">
+ {{ dropdownTitle }}
+ <button
+ :aria-label="__('Close')"
+ type="button"
+ class="dropdown-title-button dropdown-menu-close"
+ @click="toggleReviewDropdown"
+ >
+ <icon name="close" />
+ </button>
+ </div>
+ <div class="dropdown-content">
+ <ul v-if="isNotesFetched">
+ <li v-for="(draft, index) in sortedDrafts" :key="draft.id">
+ <preview-item :draft="draft" :is-last="isLast(index)" />
+ </li>
+ </ul>
+ <gl-loading-icon v-else size="lg" class="prepend-top-default append-bottom-default" />
+ </div>
+ <div class="dropdown-footer">
+ <publish-button
+ :show-count="false"
+ :should-publish="true"
+ :label="__('Submit review')"
+ class="float-right gl-mr-3"
+ />
+ </div>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/batch_comments/components/preview_item.vue b/app/assets/javascripts/batch_comments/components/preview_item.vue
new file mode 100644
index 00000000000..22495eb4d7d
--- /dev/null
+++ b/app/assets/javascripts/batch_comments/components/preview_item.vue
@@ -0,0 +1,143 @@
+<script>
+import { mapActions, mapGetters } from 'vuex';
+import { IMAGE_DIFF_POSITION_TYPE } from '~/diffs/constants';
+import { sprintf, __ } from '~/locale';
+import Icon from '~/vue_shared/components/icon.vue';
+import resolvedStatusMixin from '../mixins/resolved_status';
+import { GlSprintf } from '@gitlab/ui';
+import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+import {
+ getStartLineNumber,
+ getEndLineNumber,
+ getLineClasses,
+} from '~/notes/components/multiline_comment_utils';
+
+export default {
+ components: {
+ Icon,
+ GlSprintf,
+ },
+ mixins: [resolvedStatusMixin, glFeatureFlagsMixin()],
+ props: {
+ draft: {
+ type: Object,
+ required: true,
+ },
+ isLast: {
+ type: Boolean,
+ required: true,
+ },
+ },
+ computed: {
+ ...mapGetters('diffs', ['getDiffFileByHash']),
+ ...mapGetters(['getDiscussion']),
+ iconName() {
+ return this.isDiffDiscussion || this.draft.line_code ? 'doc-text' : 'comment';
+ },
+ discussion() {
+ return this.getDiscussion(this.draft.discussion_id);
+ },
+ isDiffDiscussion() {
+ return this.discussion && this.discussion.diff_discussion;
+ },
+ titleText() {
+ const file = this.discussion ? this.discussion.diff_file : this.draft;
+
+ if (file) {
+ return file.file_path;
+ }
+
+ return sprintf(__("%{authorsName}'s thread"), {
+ authorsName: this.discussion.notes.find(note => !note.system).author.name,
+ });
+ },
+ linePosition() {
+ if (this.draft.position && this.draft.position.position_type === IMAGE_DIFF_POSITION_TYPE) {
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ return `${this.draft.position.x}x ${this.draft.position.y}y`;
+ }
+
+ const position = this.discussion ? this.discussion.position : this.draft.position;
+
+ return position?.new_line || position?.old_line;
+ },
+ content() {
+ const el = document.createElement('div');
+ el.innerHTML = this.draft.note_html;
+
+ return el.textContent;
+ },
+ showLinePosition() {
+ return this.draft.file_hash || this.isDiffDiscussion;
+ },
+ startLineNumber() {
+ return getStartLineNumber(this.draft.position?.line_range);
+ },
+ endLineNumber() {
+ return getEndLineNumber(this.draft.position?.line_range);
+ },
+ },
+ methods: {
+ ...mapActions('batchComments', ['scrollToDraft']),
+ getLineClasses(lineNumber) {
+ return getLineClasses(lineNumber);
+ },
+ },
+ showStaysResolved: false,
+};
+</script>
+
+<template>
+ <button
+ type="button"
+ class="review-preview-item menu-item"
+ :class="[
+ componentClasses,
+ {
+ 'is-last': isLast,
+ },
+ ]"
+ @click="scrollToDraft(draft)"
+ >
+ <span class="review-preview-item-header">
+ <icon class="flex-shrink-0" :name="iconName" />
+ <span
+ class="bold text-nowrap"
+ :class="{ 'gl-align-items-center': glFeatures.multilineComments }"
+ >
+ <span class="review-preview-item-header-text block-truncated">
+ {{ titleText }}
+ </span>
+ <template v-if="showLinePosition">
+ <template v-if="!glFeatures.multilineComments"
+ >:{{ linePosition }}</template
+ >
+ <template v-else-if="startLineNumber === endLineNumber">
+ :<span :class="getLineClasses(startLineNumber)">{{ startLineNumber }}</span>
+ </template>
+ <gl-sprintf v-else :message="__(':%{startLine} to %{endLine}')">
+ <template #startLine>
+ <span class="gl-mr-2" :class="getLineClasses(startLineNumber)">{{
+ startLineNumber
+ }}</span>
+ </template>
+ <template #endLine>
+ <span class="gl-ml-2" :class="getLineClasses(endLineNumber)">{{
+ endLineNumber
+ }}</span>
+ </template>
+ </gl-sprintf>
+ </template>
+ </span>
+ </span>
+ <span class="review-preview-item-content">
+ <p>{{ content }}</p>
+ </span>
+ <span
+ v-if="draft.discussion_id && resolvedStatusMessage"
+ class="review-preview-item-footer draft-note-resolution p-0"
+ >
+ <icon class="gl-mr-3" name="status_success" /> {{ resolvedStatusMessage }}
+ </span>
+ </button>
+</template>
diff --git a/app/assets/javascripts/batch_comments/components/publish_button.vue b/app/assets/javascripts/batch_comments/components/publish_button.vue
new file mode 100644
index 00000000000..f4dc0f04dc3
--- /dev/null
+++ b/app/assets/javascripts/batch_comments/components/publish_button.vue
@@ -0,0 +1,55 @@
+<script>
+import { mapActions, mapState } from 'vuex';
+import { __ } from '~/locale';
+import LoadingButton from '~/vue_shared/components/loading_button.vue';
+import DraftsCount from './drafts_count.vue';
+
+export default {
+ components: {
+ LoadingButton,
+ DraftsCount,
+ },
+ props: {
+ showCount: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ label: {
+ type: String,
+ required: false,
+ default: __('Finish review'),
+ },
+ shouldPublish: {
+ type: Boolean,
+ required: true,
+ },
+ },
+ computed: {
+ ...mapState('batchComments', ['isPublishing']),
+ },
+ methods: {
+ ...mapActions('batchComments', ['publishReview', 'toggleReviewDropdown']),
+ onClick() {
+ if (this.shouldPublish) {
+ this.publishReview();
+ } else {
+ this.toggleReviewDropdown();
+ }
+ },
+ },
+};
+</script>
+
+<template>
+ <loading-button
+ :loading="isPublishing"
+ container-class="btn btn-success js-publish-draft-button qa-submit-review"
+ @click="onClick"
+ >
+ <span>
+ {{ label }}
+ <drafts-count v-if="showCount" />
+ </span>
+ </loading-button>
+</template>
diff --git a/app/assets/javascripts/batch_comments/components/review_bar.vue b/app/assets/javascripts/batch_comments/components/review_bar.vue
new file mode 100644
index 00000000000..b0e8b806701
--- /dev/null
+++ b/app/assets/javascripts/batch_comments/components/review_bar.vue
@@ -0,0 +1,70 @@
+<script>
+import { mapActions, mapState, mapGetters } from 'vuex';
+import { GlModal, GlModalDirective } from '@gitlab/ui';
+import { sprintf, s__ } from '~/locale';
+import LoadingButton from '~/vue_shared/components/loading_button.vue';
+import PreviewDropdown from './preview_dropdown.vue';
+
+export default {
+ components: {
+ LoadingButton,
+ GlModal,
+ PreviewDropdown,
+ },
+ directives: {
+ 'gl-modal': GlModalDirective,
+ },
+ computed: {
+ ...mapGetters(['isNotesFetched']),
+ ...mapState('batchComments', ['isDiscarding']),
+ ...mapGetters('batchComments', ['draftsCount']),
+ },
+ watch: {
+ isNotesFetched() {
+ if (this.isNotesFetched) {
+ this.expandAllDiscussions();
+ }
+ },
+ },
+ methods: {
+ ...mapActions('batchComments', ['discardReview', 'expandAllDiscussions']),
+ },
+ modalId: 'discard-draft-review',
+ text: sprintf(
+ s__(
+ `BatchComments|You're about to discard your review which will delete all of your pending comments.
+ The deleted comments %{strong_start}cannot%{strong_end} be restored.`,
+ ),
+ {
+ strong_start: '<strong>',
+ strong_end: '</strong>',
+ },
+ false,
+ ),
+};
+</script>
+<template>
+ <div v-show="draftsCount > 0">
+ <nav class="review-bar-component">
+ <div class="review-bar-content qa-review-bar">
+ <preview-dropdown />
+ <loading-button
+ v-gl-modal="$options.modalId"
+ :loading="isDiscarding"
+ :label="__('Discard review')"
+ class="qa-discard-review float-right"
+ />
+ </div>
+ </nav>
+ <gl-modal
+ :title="s__('BatchComments|Discard review?')"
+ :ok-title="s__('BatchComments|Delete all pending comments')"
+ :modal-id="$options.modalId"
+ title-tag="h4"
+ ok-variant="danger qa-modal-delete-pending-comments"
+ @ok="discardReview"
+ >
+ <p v-html="$options.text"></p>
+ </gl-modal>
+ </div>
+</template>
diff --git a/app/assets/javascripts/batch_comments/constants.js b/app/assets/javascripts/batch_comments/constants.js
new file mode 100644
index 00000000000..b309c339fc8
--- /dev/null
+++ b/app/assets/javascripts/batch_comments/constants.js
@@ -0,0 +1,3 @@
+export const CHANGES_TAB = 'diffs';
+export const DISCUSSION_TAB = 'notes';
+export const SHOW_TAB = 'show';
diff --git a/app/assets/javascripts/batch_comments/index.js b/app/assets/javascripts/batch_comments/index.js
new file mode 100644
index 00000000000..e06285c0b37
--- /dev/null
+++ b/app/assets/javascripts/batch_comments/index.js
@@ -0,0 +1,24 @@
+import Vue from 'vue';
+import { mapActions } from 'vuex';
+import store from '~/mr_notes/stores';
+import ReviewBar from './components/review_bar.vue';
+
+// eslint-disable-next-line import/prefer-default-export
+export const initReviewBar = () => {
+ const el = document.getElementById('js-review-bar');
+
+ // eslint-disable-next-line no-new
+ new Vue({
+ el,
+ store,
+ mounted() {
+ this.fetchDrafts();
+ },
+ methods: {
+ ...mapActions('batchComments', ['fetchDrafts']),
+ },
+ render(createElement) {
+ return createElement(ReviewBar);
+ },
+ });
+};
diff --git a/app/assets/javascripts/batch_comments/mixins/resolved_status.js b/app/assets/javascripts/batch_comments/mixins/resolved_status.js
index 3bbbaa86b51..2517fb198f0 100644
--- a/app/assets/javascripts/batch_comments/mixins/resolved_status.js
+++ b/app/assets/javascripts/batch_comments/mixins/resolved_status.js
@@ -1,9 +1,58 @@
-import { sprintf, __ } from '~/locale';
+import { mapGetters } from 'vuex';
+import { sprintf, s__, __ } from '~/locale';
export default {
+ props: {
+ discussionId: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ resolveDiscussion: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ isDraft: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
computed: {
+ ...mapGetters(['isDiscussionResolved']),
+ resolvedStatusMessage() {
+ let message;
+ const discussionResolved = this.isDiscussionResolved(
+ this.draft ? this.draft.discussion_id : this.discussionId,
+ );
+ const discussionToBeResolved = this.draft
+ ? this.draft.resolve_discussion
+ : this.resolveDiscussion;
+
+ if (discussionToBeResolved && discussionResolved && !this.$options.showStaysResolved) {
+ return undefined;
+ }
+
+ if (discussionToBeResolved) {
+ message = discussionResolved
+ ? s__('MergeRequests|Thread stays resolved')
+ : s__('MergeRequests|Thread will be resolved');
+ } else if (discussionResolved) {
+ message = s__('MergeRequests|Thread will be unresolved');
+ } else if (this.$options.showStaysResolved) {
+ message = s__('MergeRequests|Thread stays unresolved');
+ }
+
+ return message;
+ },
+ componentClasses() {
+ return this.resolveDiscussion ? 'is-resolving-discussion' : 'is-unresolving-discussion';
+ },
resolveButtonTitle() {
- let title = __('Mark comment as resolved');
+ if (this.isDraft || this.discussionId) return this.resolvedStatusMessage;
+
+ let title = __('Mark as resolved');
if (this.resolvedBy) {
title = sprintf(__('Resolved by %{name}'), { name: this.resolvedBy.name });
@@ -12,4 +61,5 @@ export default {
return title;
},
},
+ showStaysResolved: true,
};
diff --git a/app/assets/javascripts/batch_comments/services/drafts_service.js b/app/assets/javascripts/batch_comments/services/drafts_service.js
new file mode 100644
index 00000000000..36d2f8df612
--- /dev/null
+++ b/app/assets/javascripts/batch_comments/services/drafts_service.js
@@ -0,0 +1,33 @@
+import axios from '~/lib/utils/axios_utils';
+
+export default {
+ createNewDraft(endpoint, data) {
+ const postData = { ...data, draft_note: data.note };
+ delete postData.note;
+
+ return axios.post(endpoint, postData);
+ },
+ deleteDraft(endpoint, draftId) {
+ return axios.delete(`${endpoint}/${draftId}`);
+ },
+ publishDraft(endpoint, draftId) {
+ return axios.post(endpoint, { id: draftId });
+ },
+ addDraftToDiscussion(endpoint, data) {
+ return axios.post(endpoint, data);
+ },
+ fetchDrafts(endpoint) {
+ return axios.get(endpoint);
+ },
+ publish(endpoint) {
+ return axios.post(endpoint);
+ },
+ discard(endpoint) {
+ return axios.delete(endpoint);
+ },
+ update(endpoint, { draftId, note, resolveDiscussion, position }) {
+ return axios.put(`${endpoint}/${draftId}`, {
+ draft_note: { note, resolve_discussion: resolveDiscussion, position },
+ });
+ },
+};
diff --git a/app/assets/javascripts/batch_comments/stores/index.js b/app/assets/javascripts/batch_comments/stores/index.js
new file mode 100644
index 00000000000..08dc9ea70f8
--- /dev/null
+++ b/app/assets/javascripts/batch_comments/stores/index.js
@@ -0,0 +1,14 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import batchComments from './modules/batch_comments';
+
+Vue.use(Vuex);
+
+export const createStore = () =>
+ new Vuex.Store({
+ modules: {
+ batchComments: batchComments(),
+ },
+ });
+
+export default createStore();
diff --git a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/actions.js b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/actions.js
new file mode 100644
index 00000000000..1ef012696c5
--- /dev/null
+++ b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/actions.js
@@ -0,0 +1,151 @@
+import flash from '~/flash';
+import { __ } from '~/locale';
+import { scrollToElement } from '~/lib/utils/common_utils';
+import service from '../../../services/drafts_service';
+import * as types from './mutation_types';
+import { CHANGES_TAB, DISCUSSION_TAB, SHOW_TAB } from '../../../constants';
+
+export const saveDraft = ({ dispatch }, draft) =>
+ dispatch('saveNote', { ...draft, isDraft: true }, { root: true });
+
+export const addDraftToDiscussion = ({ commit }, { endpoint, data }) =>
+ service
+ .addDraftToDiscussion(endpoint, data)
+ .then(res => res.data)
+ .then(res => {
+ commit(types.ADD_NEW_DRAFT, res);
+ return res;
+ })
+ .catch(() => {
+ flash(__('An error occurred adding a draft to the thread.'));
+ });
+
+export const createNewDraft = ({ commit }, { endpoint, data }) =>
+ service
+ .createNewDraft(endpoint, data)
+ .then(res => res.data)
+ .then(res => {
+ commit(types.ADD_NEW_DRAFT, res);
+ return res;
+ })
+ .catch(() => {
+ flash(__('An error occurred adding a new draft.'));
+ });
+
+export const deleteDraft = ({ commit, getters }, draft) =>
+ service
+ .deleteDraft(getters.getNotesData.draftsPath, draft.id)
+ .then(() => {
+ commit(types.DELETE_DRAFT, draft.id);
+ })
+ .catch(() => flash(__('An error occurred while deleting the comment')));
+
+export const fetchDrafts = ({ commit, getters }) =>
+ service
+ .fetchDrafts(getters.getNotesData.draftsPath)
+ .then(res => res.data)
+ .then(data => commit(types.SET_BATCH_COMMENTS_DRAFTS, data))
+ .catch(() => flash(__('An error occurred while fetching pending comments')));
+
+export const publishSingleDraft = ({ commit, dispatch, getters }, draftId) => {
+ commit(types.REQUEST_PUBLISH_DRAFT, draftId);
+
+ service
+ .publishDraft(getters.getNotesData.draftsPublishPath, draftId)
+ .then(() => dispatch('updateDiscussionsAfterPublish'))
+ .then(() => commit(types.RECEIVE_PUBLISH_DRAFT_SUCCESS, draftId))
+ .catch(() => commit(types.RECEIVE_PUBLISH_DRAFT_ERROR, draftId));
+};
+
+export const publishReview = ({ commit, dispatch, getters }) => {
+ commit(types.REQUEST_PUBLISH_REVIEW);
+
+ return service
+ .publish(getters.getNotesData.draftsPublishPath)
+ .then(() => dispatch('updateDiscussionsAfterPublish'))
+ .then(() => commit(types.RECEIVE_PUBLISH_REVIEW_SUCCESS))
+ .catch(() => commit(types.RECEIVE_PUBLISH_REVIEW_ERROR));
+};
+
+export const updateDiscussionsAfterPublish = ({ dispatch, getters, rootGetters }) =>
+ dispatch('fetchDiscussions', { path: getters.getNotesData.discussionsPath }, { root: true }).then(
+ () =>
+ dispatch('diffs/assignDiscussionsToDiff', rootGetters.discussionsStructuredByLineCode, {
+ root: true,
+ }),
+ );
+
+export const discardReview = ({ commit, getters }) => {
+ commit(types.REQUEST_DISCARD_REVIEW);
+
+ return service
+ .discard(getters.getNotesData.draftsDiscardPath)
+ .then(() => commit(types.RECEIVE_DISCARD_REVIEW_SUCCESS))
+ .catch(() => commit(types.RECEIVE_DISCARD_REVIEW_ERROR));
+};
+
+export const updateDraft = (
+ { commit, getters },
+ { note, noteText, resolveDiscussion, position, callback },
+) =>
+ service
+ .update(getters.getNotesData.draftsPath, {
+ draftId: note.id,
+ note: noteText,
+ resolveDiscussion,
+ position: JSON.stringify(position),
+ })
+ .then(res => res.data)
+ .then(data => commit(types.RECEIVE_DRAFT_UPDATE_SUCCESS, data))
+ .then(callback)
+ .catch(() => flash(__('An error occurred while updating the comment')));
+
+export const scrollToDraft = ({ dispatch, rootGetters }, draft) => {
+ const discussion = draft.discussion_id && rootGetters.getDiscussion(draft.discussion_id);
+ const tab =
+ draft.file_hash || (discussion && discussion.diff_discussion) ? CHANGES_TAB : SHOW_TAB;
+ const tabEl = tab === CHANGES_TAB ? CHANGES_TAB : DISCUSSION_TAB;
+ const draftID = `note_${draft.id}`;
+ const el = document.querySelector(`#${tabEl} #${draftID}`);
+
+ dispatch('closeReviewDropdown');
+
+ window.location.hash = draftID;
+
+ if (window.mrTabs.currentAction !== tab) {
+ window.mrTabs.tabShown(tab);
+ }
+
+ if (discussion) {
+ dispatch('expandDiscussion', { discussionId: discussion.id }, { root: true });
+ }
+
+ if (el) {
+ setTimeout(() => scrollToElement(el.closest('.draft-note-component')));
+ }
+};
+
+export const toggleReviewDropdown = ({ dispatch, state }) => {
+ if (state.showPreviewDropdown) {
+ dispatch('closeReviewDropdown');
+ } else {
+ dispatch('openReviewDropdown');
+ }
+};
+
+export const openReviewDropdown = ({ commit }) => commit(types.OPEN_REVIEW_DROPDOWN);
+export const closeReviewDropdown = ({ commit }) => commit(types.CLOSE_REVIEW_DROPDOWN);
+
+export const expandAllDiscussions = ({ dispatch, state }) =>
+ state.drafts
+ .filter(draft => draft.discussion_id)
+ .forEach(draft => {
+ dispatch('expandDiscussion', { discussionId: draft.discussion_id }, { root: true });
+ });
+
+export const toggleResolveDiscussion = ({ commit }, draftId) => {
+ commit(types.TOGGLE_RESOLVE_DISCUSSION, draftId);
+};
+
+// prevent babel-plugin-rewire from generating an invalid default during karma tests
+export default () => {};
diff --git a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/getters.js b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/getters.js
new file mode 100644
index 00000000000..43f43c983aa
--- /dev/null
+++ b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/getters.js
@@ -0,0 +1,87 @@
+import { parallelLineKey, showDraftOnSide } from '../../../utils';
+
+export const draftsCount = state => state.drafts.length;
+
+export const getNotesData = (state, getters, rootState, rootGetters) => rootGetters.getNotesData;
+
+export const hasDrafts = state => state.drafts.length > 0;
+
+export const draftsPerDiscussionId = state =>
+ state.drafts.reduce((acc, draft) => {
+ if (draft.discussion_id) {
+ acc[draft.discussion_id] = draft;
+ }
+
+ return acc;
+ }, {});
+
+export const draftsPerFileHashAndLine = state =>
+ state.drafts.reduce((acc, draft) => {
+ if (draft.file_hash) {
+ if (!acc[draft.file_hash]) {
+ acc[draft.file_hash] = {};
+ }
+
+ acc[draft.file_hash][draft.line_code] = draft;
+ }
+
+ return acc;
+ }, {});
+
+export const shouldRenderDraftRow = (state, getters) => (diffFileSha, line) =>
+ Boolean(
+ diffFileSha in getters.draftsPerFileHashAndLine &&
+ getters.draftsPerFileHashAndLine[diffFileSha][line.line_code],
+ );
+
+export const shouldRenderParallelDraftRow = (state, getters) => (diffFileSha, line) => {
+ const draftsForFile = getters.draftsPerFileHashAndLine[diffFileSha];
+ const [lkey, rkey] = [parallelLineKey(line, 'left'), parallelLineKey(line, 'right')];
+
+ return draftsForFile ? Boolean(draftsForFile[lkey] || draftsForFile[rkey]) : false;
+};
+
+export const hasParallelDraftLeft = (state, getters) => (diffFileSha, line) => {
+ const draftsForFile = getters.draftsPerFileHashAndLine[diffFileSha];
+ const lkey = parallelLineKey(line, 'left');
+
+ return draftsForFile ? Boolean(draftsForFile[lkey]) : false;
+};
+
+export const hasParallelDraftRight = (state, getters) => (diffFileSha, line) => {
+ const draftsForFile = getters.draftsPerFileHashAndLine[diffFileSha];
+ const rkey = parallelLineKey(line, 'left');
+
+ return draftsForFile ? Boolean(draftsForFile[rkey]) : false;
+};
+
+export const shouldRenderDraftRowInDiscussion = (state, getters) => discussionId =>
+ typeof getters.draftsPerDiscussionId[discussionId] !== 'undefined';
+
+export const draftForDiscussion = (state, getters) => discussionId =>
+ getters.draftsPerDiscussionId[discussionId] || {};
+
+export const draftForLine = (state, getters) => (diffFileSha, line, side = null) => {
+ const draftsForFile = getters.draftsPerFileHashAndLine[diffFileSha];
+
+ const key = side !== null ? parallelLineKey(line, side) : line.line_code;
+
+ if (draftsForFile) {
+ const draft = draftsForFile[key];
+ if (draft && showDraftOnSide(line, side)) {
+ return draft;
+ }
+ }
+ return {};
+};
+
+export const draftsForFile = state => diffFileSha =>
+ state.drafts.filter(draft => draft.file_hash === diffFileSha);
+
+export const isPublishingDraft = state => draftId =>
+ state.currentlyPublishingDrafts.indexOf(draftId) !== -1;
+
+export const sortedDrafts = state => [...state.drafts].sort((a, b) => a.id > b.id);
+
+// prevent babel-plugin-rewire from generating an invalid default during karma tests
+export default () => {};
diff --git a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/index.js b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/index.js
new file mode 100644
index 00000000000..81dab0566c1
--- /dev/null
+++ b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/index.js
@@ -0,0 +1,12 @@
+import state from './state';
+import mutations from './mutations';
+import * as actions from './actions';
+import * as getters from './getters';
+
+export default () => ({
+ namespaced: true,
+ state: state(),
+ mutations,
+ actions,
+ getters,
+});
diff --git a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutation_types.js b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutation_types.js
new file mode 100644
index 00000000000..c8f0658c21c
--- /dev/null
+++ b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutation_types.js
@@ -0,0 +1,23 @@
+export const ENABLE_BATCH_COMMENTS = 'ENABLE_BATCH_COMMENTS';
+export const ADD_NEW_DRAFT = 'ADD_NEW_DRAFT';
+export const DELETE_DRAFT = 'DELETE_DRAFT';
+export const SET_BATCH_COMMENTS_DRAFTS = 'SET_BATCH_COMMENTS_DRAFTS';
+
+export const REQUEST_PUBLISH_DRAFT = 'REQUEST_PUBLISH_DRAFT';
+export const RECEIVE_PUBLISH_DRAFT_SUCCESS = 'RECEIVE_PUBLISH_DRAFT_SUCCESS';
+export const RECEIVE_PUBLISH_DRAFT_ERROR = 'RECEIVE_PUBLISH_DRAFT_ERROR';
+
+export const REQUEST_PUBLISH_REVIEW = 'REQUEST_PUBLISH_REVIEW';
+export const RECEIVE_PUBLISH_REVIEW_SUCCESS = 'RECEIVE_PUBLISH_REVIEW_SUCCESS';
+export const RECEIVE_PUBLISH_REVIEW_ERROR = 'RECEIVE_PUBLISH_REVIEW_ERROR';
+
+export const REQUEST_DISCARD_REVIEW = 'REQUEST_DISCARD_REVIEW';
+export const RECEIVE_DISCARD_REVIEW_SUCCESS = 'RECEIVE_DISCARD_REVIEW_SUCCESS';
+export const RECEIVE_DISCARD_REVIEW_ERROR = 'RECEIVE_DISCARD_REVIEW_ERROR';
+
+export const RECEIVE_DRAFT_UPDATE_SUCCESS = 'RECEIVE_DRAFT_UPDATE_SUCCESS';
+
+export const OPEN_REVIEW_DROPDOWN = 'OPEN_REVIEW_DROPDOWN';
+export const CLOSE_REVIEW_DROPDOWN = 'CLOSE_REVIEW_DROPDOWN';
+
+export const TOGGLE_RESOLVE_DISCUSSION = 'TOGGLE_RESOLVE_DISCUSSION';
diff --git a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutations.js b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutations.js
new file mode 100644
index 00000000000..81ceef7b160
--- /dev/null
+++ b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutations.js
@@ -0,0 +1,81 @@
+import * as types from './mutation_types';
+
+const processDraft = draft => ({
+ ...draft,
+ isDraft: true,
+});
+
+export default {
+ [types.ADD_NEW_DRAFT](state, draft) {
+ state.drafts.push(processDraft(draft));
+ },
+
+ [types.DELETE_DRAFT](state, draftId) {
+ state.drafts = state.drafts.filter(draft => draft.id !== draftId);
+ },
+
+ [types.SET_BATCH_COMMENTS_DRAFTS](state, drafts) {
+ state.drafts = drafts.map(processDraft);
+ },
+
+ [types.REQUEST_PUBLISH_DRAFT](state, draftId) {
+ state.currentlyPublishingDrafts.push(draftId);
+ },
+ [types.RECEIVE_PUBLISH_DRAFT_SUCCESS](state, draftId) {
+ state.currentlyPublishingDrafts = state.currentlyPublishingDrafts.filter(
+ publishingDraftId => publishingDraftId !== draftId,
+ );
+ state.drafts = state.drafts.filter(d => d.id !== draftId);
+ },
+ [types.RECEIVE_PUBLISH_DRAFT_ERROR](state, draftId) {
+ state.currentlyPublishingDrafts = state.currentlyPublishingDrafts.filter(
+ publishingDraftId => publishingDraftId !== draftId,
+ );
+ },
+
+ [types.REQUEST_PUBLISH_REVIEW](state) {
+ state.isPublishing = true;
+ },
+ [types.RECEIVE_PUBLISH_REVIEW_SUCCESS](state) {
+ state.isPublishing = false;
+ state.drafts = [];
+ },
+ [types.RECEIVE_PUBLISH_REVIEW_ERROR](state) {
+ state.isPublishing = false;
+ },
+ [types.REQUEST_DISCARD_REVIEW](state) {
+ state.isDiscarding = true;
+ },
+ [types.RECEIVE_DISCARD_REVIEW_SUCCESS](state) {
+ state.isDiscarding = false;
+ state.drafts = [];
+ },
+ [types.RECEIVE_DISCARD_REVIEW_ERROR](state) {
+ state.isDiscarding = false;
+ },
+ [types.RECEIVE_DRAFT_UPDATE_SUCCESS](state, data) {
+ const index = state.drafts.findIndex(draft => draft.id === data.id);
+
+ if (index >= 0) {
+ state.drafts.splice(index, 1, processDraft(data));
+ }
+ },
+ [types.OPEN_REVIEW_DROPDOWN](state) {
+ state.showPreviewDropdown = true;
+ },
+ [types.CLOSE_REVIEW_DROPDOWN](state) {
+ state.showPreviewDropdown = false;
+ },
+ [types.TOGGLE_RESOLVE_DISCUSSION](state, draftId) {
+ state.drafts = state.drafts.map(draft => {
+ if (draft.id === draftId) {
+ return {
+ ...draft,
+ resolve_discussion: !draft.resolve_discussion,
+ };
+ }
+
+ return draft;
+ });
+ },
+};
diff --git a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/state.js b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/state.js
new file mode 100644
index 00000000000..80c710deab0
--- /dev/null
+++ b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/state.js
@@ -0,0 +1,9 @@
+export default () => ({
+ withBatchComments: true,
+ isDraftsFetched: false,
+ drafts: [],
+ isPublishing: false,
+ currentlyPublishingDrafts: [],
+ isDiscarding: false,
+ showPreviewDropdown: false,
+});
diff --git a/app/assets/javascripts/batch_comments/utils.js b/app/assets/javascripts/batch_comments/utils.js
new file mode 100644
index 00000000000..cf4f7af0ebb
--- /dev/null
+++ b/app/assets/javascripts/batch_comments/utils.js
@@ -0,0 +1,35 @@
+import { getFormData } from '~/diffs/store/utils';
+
+export const getDraftReplyFormData = data => ({
+ endpoint: data.notesData.draftsPath,
+ data,
+});
+
+export const getDraftFormData = params => ({
+ endpoint: params.notesData.draftsPath,
+ data: getFormData(params),
+});
+
+export const parallelLineKey = (line, side) => (line[side] ? line[side].line_code : '');
+
+export const showDraftOnSide = (line, side) => {
+ // inline mode
+ if (side === null) {
+ return true;
+ }
+
+ // parallel
+ if (side === 'left' || side === 'right') {
+ const otherSide = side === 'left' ? 'right' : 'left';
+ const thisCode = (line[side] && line[side].line_code) || '';
+ const otherCode = (line[otherSide] && line[otherSide].line_code) || '';
+
+ // either the lineCodes are different
+ // or if they're the same, only show on the left side
+ if (thisCode !== otherCode || (side === 'left' && thisCode === otherCode)) {
+ return true;
+ }
+ }
+
+ return false;
+};
diff --git a/app/assets/javascripts/behaviors/markdown/render_mermaid.js b/app/assets/javascripts/behaviors/markdown/render_mermaid.js
index 057cdb6cc4c..e4c69a114e0 100644
--- a/app/assets/javascripts/behaviors/markdown/render_mermaid.js
+++ b/app/assets/javascripts/behaviors/markdown/render_mermaid.js
@@ -25,9 +25,10 @@ function importMermaidModule() {
return import(/* webpackChunkName: 'mermaid' */ 'mermaid')
.then(mermaid => {
let theme = 'neutral';
+ const ideDarkThemes = ['dark', 'solarized-dark'];
if (
- window.gon?.user_color_scheme === 'dark' &&
+ ideDarkThemes.includes(window.gon?.user_color_scheme) &&
// if on the Web IDE page
document.querySelector('.ide')
) {
diff --git a/app/assets/javascripts/blob/components/blob_content.vue b/app/assets/javascripts/blob/components/blob_content.vue
index 4f433bd8dfd..eb7f45cba6f 100644
--- a/app/assets/javascripts/blob/components/blob_content.vue
+++ b/app/assets/javascripts/blob/components/blob_content.vue
@@ -66,6 +66,7 @@ export default {
ref="contentViewer"
:content="content"
:type="activeViewer.fileType"
+ data-qa-selector="file_content"
/>
</template>
</div>
diff --git a/app/assets/javascripts/blob/components/blob_header.vue b/app/assets/javascripts/blob/components/blob_header.vue
index e5e01caa9a5..76c5779f3ae 100644
--- a/app/assets/javascripts/blob/components/blob_header.vue
+++ b/app/assets/javascripts/blob/components/blob_header.vue
@@ -30,6 +30,11 @@ export default {
required: false,
default: SIMPLE_BLOB_VIEWER,
},
+ hasRenderError: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
data() {
return {
@@ -75,6 +80,7 @@ export default {
v-if="showDefaultActions"
:raw-path="blob.rawPath"
:active-viewer="viewer"
+ :has-render-error="hasRenderError"
@copy="proxyCopyRequest"
/>
</div>
diff --git a/app/assets/javascripts/blob/components/blob_header_default_actions.vue b/app/assets/javascripts/blob/components/blob_header_default_actions.vue
index 63ae70a37f4..62fef108b47 100644
--- a/app/assets/javascripts/blob/components/blob_header_default_actions.vue
+++ b/app/assets/javascripts/blob/components/blob_header_default_actions.vue
@@ -27,6 +27,11 @@ export default {
default: SIMPLE_BLOB_VIEWER,
required: false,
},
+ hasRenderError: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
computed: {
downloadUrl() {
@@ -44,11 +49,13 @@ export default {
<template>
<gl-button-group>
<gl-deprecated-button
+ v-if="!hasRenderError"
v-gl-tooltip.hover
:aria-label="$options.BTN_COPY_CONTENTS_TITLE"
:title="$options.BTN_COPY_CONTENTS_TITLE"
:disabled="copyDisabled"
data-clipboard-target="#blob-code-content"
+ data-testid="copyContentsButton"
>
<gl-icon name="copy-to-clipboard" :size="14" />
</gl-deprecated-button>
diff --git a/app/assets/javascripts/blob/components/blob_header_filepath.vue b/app/assets/javascripts/blob/components/blob_header_filepath.vue
index e9be7fbcf9b..601b694db87 100644
--- a/app/assets/javascripts/blob/components/blob_header_filepath.vue
+++ b/app/assets/javascripts/blob/components/blob_header_filepath.vue
@@ -32,7 +32,7 @@ export default {
<file-icon :file-name="blob.path" :size="18" aria-hidden="true" css-classes="mr-2" />
<strong
class="file-title-name mr-1 js-blob-header-filepath"
- data-qa-selector="file_title_name"
+ data-qa-selector="file_title_content"
>{{ blob.path }}</strong
>
</template>
diff --git a/app/assets/javascripts/boards/components/board_column.vue b/app/assets/javascripts/boards/components/board_column.vue
index fb854616a04..0ed7579e8e1 100644
--- a/app/assets/javascripts/boards/components/board_column.vue
+++ b/app/assets/javascripts/boards/components/board_column.vue
@@ -1,33 +1,22 @@
<script>
-import $ from 'jquery';
import Sortable from 'sortablejs';
-import { GlButtonGroup, GlDeprecatedButton, GlLabel, GlTooltip, GlIcon } from '@gitlab/ui';
import isWipLimitsOn from 'ee_else_ce/boards/mixins/is_wip_limits';
-import { s__, __, sprintf } from '~/locale';
import Tooltip from '~/vue_shared/directives/tooltip';
import EmptyComponent from '~/vue_shared/components/empty_component';
-import AccessorUtilities from '../../lib/utils/accessor';
import BoardBlankState from './board_blank_state.vue';
-import BoardDelete from './board_delete';
+import BoardListHeader from 'ee_else_ce/boards/components/board_list_header.vue';
import BoardList from './board_list.vue';
-import IssueCount from './issue_count.vue';
import boardsStore from '../stores/boards_store';
+import eventHub from '../eventhub';
import { getBoardSortableDefaultOptions, sortableEnd } from '../mixins/sortable_default_options';
import { ListType } from '../constants';
-import { isScopedLabel } from '~/lib/utils/common_utils';
export default {
components: {
BoardPromotionState: EmptyComponent,
BoardBlankState,
- BoardDelete,
+ BoardListHeader,
BoardList,
- GlButtonGroup,
- IssueCount,
- GlDeprecatedButton,
- GlLabel,
- GlTooltip,
- GlIcon,
},
directives: {
Tooltip,
@@ -70,42 +59,9 @@ export default {
return {
detailIssue: boardsStore.detail,
filter: boardsStore.filter,
- weightFeatureAvailable: false,
};
},
computed: {
- isLoggedIn() {
- return Boolean(gon.current_user_id);
- },
- showListHeaderButton() {
- return (
- !this.disabled &&
- this.list.type !== ListType.closed &&
- this.list.type !== ListType.blank &&
- this.list.type !== ListType.promotion
- );
- },
- issuesTooltip() {
- const { issuesSize } = this.list;
-
- return sprintf(__('%{issuesSize} issues'), { issuesSize });
- },
- // Only needed to make karma pass.
- weightCountToolTip() {}, // eslint-disable-line vue/return-in-computed-property
- caretTooltip() {
- return this.list.isExpanded ? s__('Boards|Collapse') : s__('Boards|Expand');
- },
- isNewIssueShown() {
- return this.list.type === ListType.backlog || this.showListHeaderButton;
- },
- isSettingsShown() {
- return (
- this.list.type !== ListType.backlog &&
- this.showListHeaderButton &&
- this.list.isExpanded &&
- this.isWipLimitsOn
- );
- },
showBoardListAndBoardInfo() {
return this.list.type !== ListType.blank && this.list.type !== ListType.promotion;
},
@@ -151,41 +107,9 @@ export default {
Sortable.create(this.$el.parentNode, sortableOptions);
},
- created() {
- if (
- this.list.isExpandable &&
- AccessorUtilities.isLocalStorageAccessSafe() &&
- !this.isLoggedIn
- ) {
- const isCollapsed = localStorage.getItem(`${this.uniqueKey}.expanded`) === 'false';
-
- this.list.isExpanded = !isCollapsed;
- }
- },
methods: {
- showScopedLabels(label) {
- return boardsStore.scopedLabels.enabled && isScopedLabel(label);
- },
-
- showNewIssueForm() {
- this.$refs['board-list'].showIssueForm = !this.$refs['board-list'].showIssueForm;
- },
- toggleExpanded() {
- if (this.list.isExpandable) {
- this.list.isExpanded = !this.list.isExpanded;
-
- if (AccessorUtilities.isLocalStorageAccessSafe() && !this.isLoggedIn) {
- localStorage.setItem(`${this.uniqueKey}.expanded`, this.list.isExpanded);
- }
-
- if (this.isLoggedIn) {
- this.list.update();
- }
-
- // When expanding/collapsing, the tooltip on the caret button sometimes stays open.
- // Close all tooltips manually to prevent dangling tooltips.
- $('.tooltip').tooltip('hide');
- }
+ showListNewIssueForm(listId) {
+ eventHub.$emit('showForm', listId);
},
},
};
@@ -200,166 +124,18 @@ export default {
'board-type-assignee': list.type === 'assignee',
}"
:data-id="list.id"
- class="board h-100 px-2 align-top ws-normal"
+ class="board gl-h-full gl-px-3 gl-vertical-align-top gl-white-space-normal"
data-qa-selector="board_list"
>
- <div class="board-inner d-flex flex-column position-relative h-100 rounded">
- <header
- :class="{
- 'has-border': list.label && list.label.color,
- 'position-relative': list.isExpanded,
- 'position-absolute position-top-0 position-left-0 w-100 h-100': !list.isExpanded,
- }"
- :style="{ borderTopColor: list.label && list.label.color ? list.label.color : null }"
- class="board-header"
- data-qa-selector="board_list_header"
- >
- <h3
- :class="{
- 'user-can-drag': !disabled && !list.preset,
- 'border-bottom-0': !list.isExpanded,
- }"
- class="board-title m-0 d-flex js-board-handle"
- >
- <div
- v-if="list.isExpandable"
- v-tooltip=""
- :aria-label="caretTooltip"
- :title="caretTooltip"
- aria-hidden="true"
- class="board-title-caret no-drag"
- data-placement="bottom"
- @click="toggleExpanded"
- >
- <i
- :class="{ 'fa-caret-right': list.isExpanded, 'fa-caret-down': !list.isExpanded }"
- class="fa fa-fw"
- ></i>
- </div>
- <!-- The following is only true in EE and if it is a milestone -->
- <span
- v-if="list.type === 'milestone' && list.milestone"
- aria-hidden="true"
- class="append-right-5 milestone-icon"
- >
- <gl-icon name="timer" />
- </span>
-
- <a
- v-if="list.type === 'assignee'"
- :href="list.assignee.path"
- class="user-avatar-link js-no-trigger"
- >
- <img
- :alt="list.assignee.name"
- :src="list.assignee.avatar"
- class="avatar s20 has-tooltip"
- height="20"
- width="20"
- />
- </a>
- <div class="board-title-text">
- <span
- v-if="list.type !== 'label'"
- :class="{
- 'has-tooltip': !['backlog', 'closed'].includes(list.type),
- 'd-block': list.type === 'milestone',
- }"
- :title="(list.label && list.label.description) || list.title || ''"
- class="board-title-main-text block-truncated"
- data-container="body"
- >
- {{ list.title }}
- </span>
- <span
- v-if="list.type === 'assignee'"
- :title="(list.assignee && list.assignee.username) || ''"
- class="board-title-sub-text prepend-left-5 has-tooltip"
- >
- @{{ list.assignee.username }}
- </span>
- <gl-label
- v-if="list.type === 'label'"
- :background-color="list.label.color"
- :description="list.label.description"
- :scoped="showScopedLabels(list.label)"
- :size="!list.isExpanded ? 'sm' : ''"
- :title="list.label.title"
- tooltip-placement="bottom"
- />
- </div>
- <board-delete
- v-if="canAdminList && !list.preset && list.id"
- :list="list"
- inline-template="true"
- >
- <button
- :class="{ 'd-none': !list.isExpanded }"
- :aria-label="__(`Delete list`)"
- class="board-delete no-drag p-0 border-0 has-tooltip float-right"
- data-placement="bottom"
- title="Delete list"
- type="button"
- @click.stop="deleteBoard"
- >
- <i aria-hidden="true" data-hidden="true" class="fa fa-trash"></i>
- </button>
- </board-delete>
- <div
- v-if="showBoardListAndBoardInfo"
- class="issue-count-badge pr-0 no-drag text-secondary"
- >
- <span class="d-inline-flex">
- <gl-tooltip :target="() => $refs.issueCount" :title="issuesTooltip" />
- <span ref="issueCount" class="issue-count-badge-count">
- <gl-icon class="mr-1" name="issues" />
- <issue-count :issues-size="list.issuesSize" :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="d-inline-flex ml-2">
- <gl-icon class="mr-1" name="weight" />
- {{ list.totalWeight }}
- </span>
- </template>
- </span>
- </div>
- <gl-button-group
- v-if="isNewIssueShown || isSettingsShown"
- class="board-list-button-group pl-2"
- >
- <gl-deprecated-button
- v-if="isNewIssueShown"
- ref="newIssueBtn"
- :class="{
- 'd-none': !list.isExpanded,
- 'rounded-right': isNewIssueShown && !isSettingsShown,
- }"
- :aria-label="__(`New issue`)"
- class="issue-count-badge-add-button no-drag"
- type="button"
- @click="showNewIssueForm"
- >
- <i aria-hidden="true" data-hidden="true" class="fa fa-plus"></i>
- </gl-deprecated-button>
- <gl-tooltip :target="() => $refs.newIssueBtn">{{ __('New Issue') }}</gl-tooltip>
-
- <gl-deprecated-button
- v-if="isSettingsShown"
- ref="settingsBtn"
- :aria-label="__(`List settings`)"
- class="no-drag rounded-right js-board-settings-button"
- title="List settings"
- type="button"
- @click="openSidebarSettings"
- >
- <gl-icon name="settings" />
- </gl-deprecated-button>
- <gl-tooltip :target="() => $refs.settingsBtn">{{ __('List settings') }}</gl-tooltip>
- </gl-button-group>
- </h3>
- </header>
+ <div
+ class="board-inner gl-display-flex gl-flex-direction-column gl-relative gl-h-full gl-rounded-base"
+ >
+ <board-list-header
+ :can-admin-list="canAdminList"
+ :list="list"
+ :disabled="disabled"
+ :board-id="boardId"
+ />
<board-list
v-if="showBoardListAndBoardInfo"
ref="board-list"
diff --git a/app/assets/javascripts/boards/components/board_content.vue b/app/assets/javascripts/boards/components/board_content.vue
new file mode 100644
index 00000000000..f0497ea0b64
--- /dev/null
+++ b/app/assets/javascripts/boards/components/board_content.vue
@@ -0,0 +1,82 @@
+<script>
+import { mapState } from 'vuex';
+import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+import BoardColumn from 'ee_else_ce/boards/components/board_column.vue';
+import EpicsSwimlanes from 'ee_component/boards/components/epics_swimlanes.vue';
+
+export default {
+ components: {
+ BoardColumn,
+ EpicsSwimlanes,
+ },
+ mixins: [glFeatureFlagMixin()],
+ props: {
+ lists: {
+ type: Array,
+ required: true,
+ },
+ canAdminList: {
+ type: Boolean,
+ required: true,
+ },
+ groupId: {
+ type: Number,
+ required: false,
+ default: null,
+ },
+ disabled: {
+ type: Boolean,
+ required: true,
+ },
+ issueLinkBase: {
+ type: String,
+ required: true,
+ },
+ rootPath: {
+ type: String,
+ required: true,
+ },
+ boardId: {
+ type: String,
+ required: true,
+ },
+ },
+ computed: {
+ ...mapState(['isShowingEpicsSwimlanes']),
+ isSwimlanesOn() {
+ return this.glFeatures.boardsWithSwimlanes && this.isShowingEpicsSwimlanes;
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <div
+ v-if="!isSwimlanesOn"
+ class="boards-list w-100 py-3 px-2 text-nowrap"
+ data-qa-selector="boards_list"
+ >
+ <board-column
+ v-for="list in lists"
+ :key="list.id"
+ ref="board"
+ :can-admin-list="canAdminList"
+ :group-id="groupId"
+ :list="list"
+ :disabled="disabled"
+ :issue-link-base="issueLinkBase"
+ :root-path="rootPath"
+ :board-id="boardId"
+ />
+ </div>
+ <epics-swimlanes
+ v-else
+ ref="swimlanes"
+ :lists="lists"
+ :can-admin-list="canAdminList"
+ :disabled="disabled"
+ :board-id="boardId"
+ />
+ </div>
+</template>
diff --git a/app/assets/javascripts/boards/components/board_delete.js b/app/assets/javascripts/boards/components/board_delete.js
index cc15dc82db9..b74234a2e3c 100644
--- a/app/assets/javascripts/boards/components/board_delete.js
+++ b/app/assets/javascripts/boards/components/board_delete.js
@@ -1,8 +1,15 @@
import $ from 'jquery';
import Vue from 'vue';
+import { GlButton, GlTooltipDirective } from '@gitlab/ui';
import { __ } from '~/locale';
export default Vue.extend({
+ components: {
+ GlButton,
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
props: {
list: {
type: Object,
diff --git a/app/assets/javascripts/boards/components/board_list.vue b/app/assets/javascripts/boards/components/board_list.vue
index c4e2c398d45..4270ad5783d 100644
--- a/app/assets/javascripts/boards/components/board_list.vue
+++ b/app/assets/javascripts/boards/components/board_list.vue
@@ -104,7 +104,7 @@ export default {
},
},
created() {
- eventHub.$on(`hide-issue-form-${this.list.id}`, this.toggleForm);
+ eventHub.$on(`toggle-issue-form-${this.list.id}`, this.toggleForm);
eventHub.$on(`scroll-board-list-${this.list.id}`, this.scrollToTop);
},
mounted() {
@@ -381,7 +381,7 @@ export default {
this.$refs.list.addEventListener('scroll', this.onScroll);
},
beforeDestroy() {
- eventHub.$off(`hide-issue-form-${this.list.id}`, this.toggleForm);
+ 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);
},
diff --git a/app/assets/javascripts/boards/components/board_list_header.vue b/app/assets/javascripts/boards/components/board_list_header.vue
new file mode 100644
index 00000000000..eb12617a66e
--- /dev/null
+++ b/app/assets/javascripts/boards/components/board_list_header.vue
@@ -0,0 +1,291 @@
+<script>
+import {
+ GlButton,
+ GlButtonGroup,
+ GlLabel,
+ GlTooltip,
+ GlIcon,
+ GlTooltipDirective,
+} from '@gitlab/ui';
+import isWipLimitsOn from 'ee_else_ce/boards/mixins/is_wip_limits';
+import { s__, __, sprintf } from '~/locale';
+import AccessorUtilities from '../../lib/utils/accessor';
+import BoardDelete from './board_delete';
+import IssueCount from './issue_count.vue';
+import boardsStore from '../stores/boards_store';
+import eventHub from '../eventhub';
+import { ListType } from '../constants';
+import { isScopedLabel } from '~/lib/utils/common_utils';
+
+export default {
+ components: {
+ BoardDelete,
+ GlButtonGroup,
+ GlButton,
+ GlLabel,
+ GlTooltip,
+ GlIcon,
+ IssueCount,
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
+ mixins: [isWipLimitsOn],
+ props: {
+ list: {
+ type: Object,
+ default: () => ({}),
+ required: false,
+ },
+ disabled: {
+ type: Boolean,
+ required: true,
+ },
+ boardId: {
+ type: String,
+ required: true,
+ },
+ canAdminList: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ isSwimlanesHeader: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+ data() {
+ return {
+ weightFeatureAvailable: false,
+ };
+ },
+ computed: {
+ isLoggedIn() {
+ return Boolean(gon.current_user_id);
+ },
+ 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 &&
+ this.listType !== ListType.blank &&
+ this.listType !== ListType.promotion
+ );
+ },
+ issuesTooltip() {
+ const { issuesSize } = this.list;
+
+ return sprintf(__('%{issuesSize} issues'), { issuesSize });
+ },
+ 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 &&
+ this.isWipLimitsOn
+ );
+ },
+ showBoardListAndBoardInfo() {
+ return this.listType !== ListType.blank && this.listType !== ListType.promotion;
+ },
+ uniqueKey() {
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ return `boards.${this.boardId}.${this.listType}.${this.list.id}`;
+ },
+ },
+ methods: {
+ showScopedLabels(label) {
+ return boardsStore.scopedLabels.enabled && isScopedLabel(label);
+ },
+
+ showNewIssueForm() {
+ eventHub.$emit(`toggle-issue-form-${this.list.id}`);
+ },
+ toggleExpanded() {
+ if (this.list.isExpandable) {
+ this.list.isExpanded = !this.list.isExpanded;
+
+ if (AccessorUtilities.isLocalStorageAccessSafe() && !this.isLoggedIn) {
+ localStorage.setItem(`${this.uniqueKey}.expanded`, this.list.isExpanded);
+ }
+
+ if (this.isLoggedIn) {
+ this.list.update();
+ }
+
+ // 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');
+ }
+ },
+ },
+};
+</script>
+
+<template>
+ <header
+ :class="{
+ 'has-border': list.label && list.label.color,
+ 'gl-relative': list.isExpanded,
+ 'gl-h-full': !list.isExpanded,
+ 'board-inner gl-rounded-base gl-border-b-0': 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-border-b-0': !list.isExpanded,
+ }"
+ class="board-title gl-m-0 gl-display-flex 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"
+ variant="link"
+ @click="toggleExpanded"
+ />
+ <!-- The following is only true in EE and if it is a milestone -->
+ <span
+ v-if="list.type === 'milestone' && list.milestone"
+ aria-hidden="true"
+ class="gl-mr-2 milestone-icon"
+ >
+ <gl-icon name="timer" />
+ </span>
+
+ <a
+ v-if="list.type === 'assignee'"
+ :href="list.assignee.path"
+ class="user-avatar-link js-no-trigger"
+ >
+ <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">
+ <span
+ v-if="list.type !== 'label'"
+ v-gl-tooltip.hover
+ :class="{
+ 'gl-display-inline-block': list.type === 'milestone',
+ }"
+ :title="listTitle"
+ class="board-title-main-text block-truncated"
+ >
+ {{ list.title }}
+ </span>
+ <span v-if="list.type === 'assignee'" class="board-title-sub-text gl-ml-2">
+ @{{ list.assignee.username }}
+ </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>
+ <board-delete
+ v-if="canAdminList && !list.preset && list.id"
+ :list="list"
+ inline-template="true"
+ >
+ <gl-button
+ v-gl-tooltip.hover.bottom
+ :class="{ 'gl-display-none': !list.isExpanded }"
+ :aria-label="__('Delete list')"
+ class="board-delete no-drag gl-pr-0 gl-shadow-none gl-mr-3"
+ :title="__('Delete list')"
+ icon="remove"
+ size="small"
+ @click.stop="deleteBoard"
+ />
+ </board-delete>
+ <div
+ v-if="showBoardListAndBoardInfo"
+ class="issue-count-badge gl-pr-0 no-drag text-secondary"
+ >
+ <span class="gl-display-inline-flex">
+ <gl-tooltip :target="() => $refs.issueCount" :title="issuesTooltip" />
+ <span ref="issueCount" class="issue-count-badge-count">
+ <gl-icon class="gl-mr-2" name="issues" />
+ <issue-count :issues-size="list.issuesSize" :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="isNewIssueShown || isSettingsShown"
+ 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.vue b/app/assets/javascripts/boards/components/board_new_issue.vue
index deebe122109..c72fb7b30f9 100644
--- a/app/assets/javascripts/boards/components/board_new_issue.vue
+++ b/app/assets/javascripts/boards/components/board_new_issue.vue
@@ -92,7 +92,7 @@ export default {
},
cancel() {
this.title = '';
- eventHub.$emit(`hide-issue-form-${this.list.id}`);
+ eventHub.$emit(`toggle-issue-form-${this.list.id}`);
},
setSelectedProject(selectedProject) {
this.selectedProject = selectedProject;
diff --git a/app/assets/javascripts/boards/components/board_sidebar.js b/app/assets/javascripts/boards/components/board_sidebar.js
index c8953158811..056a7b48212 100644
--- a/app/assets/javascripts/boards/components/board_sidebar.js
+++ b/app/assets/javascripts/boards/components/board_sidebar.js
@@ -54,7 +54,7 @@ export default Vue.extend({
return this.issue.milestone ? this.issue.milestone.title : __('No milestone');
},
canRemove() {
- return !this.list.preset;
+ return !this.list?.preset;
},
hasLabels() {
return this.issue.labels && this.issue.labels.length;
diff --git a/app/assets/javascripts/boards/components/issue_card_inner.vue b/app/assets/javascripts/boards/components/issue_card_inner.vue
index a589fb325b2..f2e198eaedb 100644
--- a/app/assets/javascripts/boards/components/issue_card_inner.vue
+++ b/app/assets/javascripts/boards/components/issue_card_inner.vue
@@ -147,7 +147,7 @@ export default {
<template>
<div>
<div class="d-flex board-card-header" dir="auto">
- <h4 class="board-card-title append-bottom-0 prepend-top-0">
+ <h4 class="board-card-title gl-mb-0 gl-mt-0">
<icon
v-if="issue.blocked"
v-gl-tooltip
@@ -169,7 +169,7 @@ export default {
}}</a>
</h4>
</div>
- <div v-if="showLabelFooter" class="board-card-labels prepend-top-4 d-flex flex-wrap">
+ <div v-if="showLabelFooter" class="board-card-labels gl-mt-2 d-flex flex-wrap">
<template v-for="label in orderedLabels">
<gl-label
:key="label.id"
@@ -188,7 +188,7 @@ export default {
>
<span
v-if="issue.referencePath"
- class="board-card-number overflow-hidden d-flex append-right-8 prepend-top-8"
+ class="board-card-number overflow-hidden d-flex gl-mr-3 gl-mt-3"
>
<tooltip-on-truncate
v-if="issueReferencePath"
@@ -199,7 +199,7 @@ export default {
>
#{{ issue.iid }}
</span>
- <span class="board-info-items prepend-top-8 d-inline-block">
+ <span class="board-info-items gl-mt-3 d-inline-block">
<issue-due-date v-if="issue.dueDate" :date="issue.dueDate" :closed="issue.closed" />
<issue-time-estimate v-if="issue.timeEstimate" :estimate="issue.timeEstimate" />
<issue-card-weight
diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js
index 9ff7575ae09..a882cd1cdfa 100644
--- a/app/assets/javascripts/boards/index.js
+++ b/app/assets/javascripts/boards/index.js
@@ -1,12 +1,15 @@
import $ from 'jquery';
import Vue from 'vue';
+import { mapActions } from 'vuex';
import 'ee_else_ce/boards/models/issue';
import 'ee_else_ce/boards/models/list';
+import BoardContent from '~/boards/components/board_content.vue';
import BoardSidebar from 'ee_else_ce/boards/components/board_sidebar';
import initNewListDropdown from 'ee_else_ce/boards/components/new_list_dropdown';
import boardConfigToggle from 'ee_else_ce/boards/config_toggle';
import toggleLabels from 'ee_else_ce/boards/toggle_labels';
+import toggleEpicsSwimlanes from 'ee_else_ce/boards/toggle_epics_swimlanes';
import {
setPromotionState,
setWeigthFetchingState,
@@ -76,6 +79,7 @@ export default () => {
issueBoardsApp = new Vue({
el: $boardApp,
components: {
+ BoardContent,
Board: () =>
window?.gon?.features?.sfcIssueBoards
? import('ee_else_ce/boards/components/board_column.vue')
@@ -114,14 +118,16 @@ export default () => {
},
},
created() {
- boardsStore.setEndpoints({
+ const endpoints = {
boardsEndpoint: this.boardsEndpoint,
recentBoardsEndpoint: this.recentBoardsEndpoint,
listsEndpoint: this.listsEndpoint,
bulkUpdatePath: this.bulkUpdatePath,
boardId: this.boardId,
fullPath: $boardApp.dataset.fullPath,
- });
+ };
+ this.setEndpoints(endpoints);
+ boardsStore.setEndpoints(endpoints);
boardsStore.rootPath = this.boardsEndpoint;
eventHub.$on('updateTokens', this.updateTokens);
@@ -192,6 +198,7 @@ export default () => {
}
},
methods: {
+ ...mapActions(['setEndpoints']),
updateTokens() {
this.filterManager.updateTokens();
},
@@ -371,5 +378,6 @@ export default () => {
toggleFocusMode(ModalStore, boardsStore);
toggleLabels();
+ toggleEpicsSwimlanes();
mountMultipleBoardsSwitcher();
};
diff --git a/app/assets/javascripts/boards/models/issue.js b/app/assets/javascripts/boards/models/issue.js
index 878f49cc6be..98eac35b2ed 100644
--- a/app/assets/javascripts/boards/models/issue.js
+++ b/app/assets/javascripts/boards/models/issue.js
@@ -30,56 +30,43 @@ class ListIssue {
}
addLabel(label) {
- if (!this.findLabel(label)) {
- this.labels.push(new ListLabel(label));
- }
+ boardsStore.addIssueLabel(this, label);
}
findLabel(findLabel) {
- return this.labels.find(label => label.id === findLabel.id);
+ return boardsStore.findIssueLabel(this, findLabel);
}
removeLabel(removeLabel) {
- if (removeLabel) {
- this.labels = this.labels.filter(label => removeLabel.id !== label.id);
- }
+ boardsStore.removeIssueLabel(this, removeLabel);
}
removeLabels(labels) {
- labels.forEach(this.removeLabel.bind(this));
+ boardsStore.removeIssueLabels(this, labels);
}
addAssignee(assignee) {
- if (!this.findAssignee(assignee)) {
- this.assignees.push(new ListAssignee(assignee));
- }
+ boardsStore.addIssueAssignee(this, assignee);
}
findAssignee(findAssignee) {
- return this.assignees.find(assignee => assignee.id === findAssignee.id);
+ return boardsStore.findIssueAssignee(this, findAssignee);
}
removeAssignee(removeAssignee) {
- if (removeAssignee) {
- this.assignees = this.assignees.filter(assignee => assignee.id !== removeAssignee.id);
- }
+ boardsStore.removeIssueAssignee(this, removeAssignee);
}
removeAllAssignees() {
- this.assignees = [];
+ boardsStore.removeAllIssueAssignees(this);
}
addMilestone(milestone) {
- const miletoneId = this.milestone ? this.milestone.id : null;
- if (IS_EE && milestone.id !== miletoneId) {
- this.milestone = new ListMilestone(milestone);
- }
+ boardsStore.addIssueMilestone(this, milestone);
}
removeMilestone(removeMilestone) {
- if (IS_EE && removeMilestone && removeMilestone.id === this.milestone.id) {
- this.milestone = {};
- }
+ boardsStore.removeIssueMilestone(this, removeMilestone);
}
getLists() {
@@ -87,15 +74,15 @@ class ListIssue {
}
updateData(newData) {
- Object.assign(this, newData);
+ boardsStore.updateIssueData(this, newData);
}
setFetchingState(key, value) {
- this.isFetching[key] = value;
+ boardsStore.setIssueFetchingState(this, key, value);
}
setLoadingState(key, value) {
- this.isLoading[key] = value;
+ boardsStore.setIssueLoadingState(this, key, value);
}
update() {
diff --git a/app/assets/javascripts/boards/models/list.js b/app/assets/javascripts/boards/models/list.js
index 31c372b7a75..0bd606c6297 100644
--- a/app/assets/javascripts/boards/models/list.js
+++ b/app/assets/javascripts/boards/models/list.js
@@ -1,4 +1,4 @@
-/* eslint-disable no-underscore-dangle, class-methods-use-this, consistent-return */
+/* eslint-disable no-underscore-dangle, class-methods-use-this */
import ListIssue from 'ee_else_ce/boards/models/issue';
import { __ } from '~/locale';
@@ -8,8 +8,6 @@ import flash from '~/flash';
import boardsStore from '../stores/boards_store';
import ListMilestone from './milestone';
-const PER_PAGE = 20;
-
const TYPES = {
backlog: {
isPreset: true,
@@ -83,30 +81,15 @@ class List {
}
destroy() {
- const index = boardsStore.state.lists.indexOf(this);
- boardsStore.state.lists.splice(index, 1);
- boardsStore.updateNewListDropdown(this.id);
-
- boardsStore.destroyList(this.id).catch(() => {
- // TODO: handle request error
- });
+ boardsStore.destroy(this);
}
update() {
- const collapsed = !this.isExpanded;
- return boardsStore.updateList(this.id, this.position, collapsed).catch(() => {
- // TODO: handle request error
- });
+ return boardsStore.updateListFunc(this);
}
nextPage() {
- if (this.issuesSize > this.issues.length) {
- if (this.issues.length / PER_PAGE >= 1) {
- this.page += 1;
- }
-
- return this.getIssues(false);
- }
+ return boardsStore.goToNextPage(this);
}
getIssues(emptyIssues = true) {
@@ -114,13 +97,7 @@ class List {
}
newIssue(issue) {
- this.addIssue(issue, null, 0);
- this.issuesSize += 1;
-
- return boardsStore
- .newIssue(this.id, issue)
- .then(res => res.data)
- .then(data => this.onNewIssueResponse(issue, data));
+ return boardsStore.newListIssue(this, issue);
}
createIssues(data) {
@@ -138,12 +115,7 @@ class List {
}
moveIssue(issue, oldIndex, newIndex, moveBeforeId, moveAfterId) {
- this.issues.splice(oldIndex, 1);
- this.issues.splice(newIndex, 0, issue);
-
- boardsStore.moveIssue(issue.id, null, null, moveBeforeId, moveAfterId).catch(() => {
- // TODO: handle request error
- });
+ boardsStore.moveListIssues(this, issue, oldIndex, newIndex, moveBeforeId, moveAfterId);
}
moveMultipleIssues({ issues, oldIndicies, newIndex, moveBeforeId, moveAfterId }) {
@@ -182,35 +154,15 @@ class List {
}
findIssue(id) {
- return this.issues.find(issue => issue.id === id);
+ return boardsStore.findListIssue(this, id);
}
removeMultipleIssues(removeIssues) {
- const ids = removeIssues.map(issue => issue.id);
-
- this.issues = this.issues.filter(issue => {
- const matchesRemove = ids.includes(issue.id);
-
- if (matchesRemove) {
- this.issuesSize -= 1;
- issue.removeLabel(this.label);
- }
-
- return !matchesRemove;
- });
+ return boardsStore.removeListMultipleIssues(this, removeIssues);
}
removeIssue(removeIssue) {
- this.issues = this.issues.filter(issue => {
- const matchesRemove = removeIssue.id === issue.id;
-
- if (matchesRemove) {
- this.issuesSize -= 1;
- issue.removeLabel(this.label);
- }
-
- return !matchesRemove;
- });
+ return boardsStore.removeListIssues(this, removeIssue);
}
getTypeInfo(type) {
diff --git a/app/assets/javascripts/boards/stores/actions.js b/app/assets/javascripts/boards/stores/actions.js
index 34598d66f45..08fedb14dff 100644
--- a/app/assets/javascripts/boards/stores/actions.js
+++ b/app/assets/javascripts/boards/stores/actions.js
@@ -1,11 +1,13 @@
+import * as types from './mutation_types';
+
const notImplemented = () => {
/* eslint-disable-next-line @gitlab/require-i18n-strings */
throw new Error('Not implemented!');
};
export default {
- setEndpoints: () => {
- notImplemented();
+ setEndpoints: ({ commit }, endpoints) => {
+ commit(types.SET_ENDPOINTS, endpoints);
},
fetchLists: () => {
diff --git a/app/assets/javascripts/boards/stores/boards_store.js b/app/assets/javascripts/boards/stores/boards_store.js
index fdbd7e89bfb..a930f39189e 100644
--- a/app/assets/javascripts/boards/stores/boards_store.js
+++ b/app/assets/javascripts/boards/stores/boards_store.js
@@ -1,4 +1,4 @@
-/* eslint-disable no-shadow, no-param-reassign */
+/* eslint-disable no-shadow, no-param-reassign,consistent-return */
/* global List */
import $ from 'jquery';
@@ -22,6 +22,7 @@ import ListLabel from '../models/label';
import ListAssignee from '../models/assignee';
import ListMilestone from '../models/milestone';
+const PER_PAGE = 20;
const boardsStore = {
disabled: false,
timeTracking: {
@@ -42,6 +43,7 @@ const boardsStore = {
},
detail: {
issue: {},
+ list: {},
},
moving: {
issue: {},
@@ -73,6 +75,7 @@ const boardsStore = {
this.filter.path = getUrlParamsArray().join('&');
this.detail = {
issue: {},
+ list: {},
};
},
showPage(page) {
@@ -133,6 +136,21 @@ const boardsStore = {
path: '',
});
},
+
+ 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;
@@ -177,6 +195,10 @@ const boardsStore = {
}
}
},
+ findListIssue(list, id) {
+ return list.issues.find(issue => issue.id === id);
+ },
+
welcomeIsHidden() {
return parseBoolean(Cookies.get('issue_board_welcome_hidden'));
},
@@ -243,6 +265,33 @@ const boardsStore = {
}
},
+ 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 });
},
@@ -516,9 +565,25 @@ const boardsStore = {
});
},
+ 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;
@@ -591,6 +656,15 @@ const boardsStore = {
});
},
+ 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,
@@ -607,6 +681,15 @@ const boardsStore = {
});
},
+ newListIssue(list, issue) {
+ list.addIssue(issue, null, 0);
+ list.issuesSize += 1;
+
+ return this.newIssue(list.id, issue)
+ .then(res => res.data)
+ .then(data => list.onNewIssueResponse(issue, data));
+ },
+
getBacklog(data) {
return axios.get(
mergeUrlParams(
@@ -615,6 +698,21 @@ const boardsStore = {
),
);
},
+ 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));
+ }
+ },
+
+ removeIssueLabels(issue, labels) {
+ labels.forEach(issue.removeLabel.bind(issue));
+ },
bulkUpdate(issueIds, extraData = {}) {
const data = {
@@ -682,10 +780,49 @@ const boardsStore = {
...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) {
issue.id = obj.id;
issue.iid = obj.iid;
@@ -718,6 +855,11 @@ const boardsStore = {
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: {
diff --git a/app/assets/javascripts/boards/stores/mutations.js b/app/assets/javascripts/boards/stores/mutations.js
index 7a287400265..e4459cdcc07 100644
--- a/app/assets/javascripts/boards/stores/mutations.js
+++ b/app/assets/javascripts/boards/stores/mutations.js
@@ -6,8 +6,8 @@ const notImplemented = () => {
};
export default {
- [mutationTypes.SET_ENDPOINTS]: () => {
- notImplemented();
+ [mutationTypes.SET_ENDPOINTS]: (state, endpoints) => {
+ state.endpoints = endpoints;
},
[mutationTypes.REQUEST_ADD_LIST]: () => {
diff --git a/app/assets/javascripts/boards/stores/state.js b/app/assets/javascripts/boards/stores/state.js
index 10aac2f649e..aca93c4d7c6 100644
--- a/app/assets/javascripts/boards/stores/state.js
+++ b/app/assets/javascripts/boards/stores/state.js
@@ -1,6 +1,7 @@
import { inactiveListId } from '~/boards/constants';
export default () => ({
+ endpoints: {},
isShowingLabels: true,
activeListId: inactiveListId,
});
diff --git a/app/assets/javascripts/boards/toggle_epics_swimlanes.js b/app/assets/javascripts/boards/toggle_epics_swimlanes.js
new file mode 100644
index 00000000000..2d1ec238274
--- /dev/null
+++ b/app/assets/javascripts/boards/toggle_epics_swimlanes.js
@@ -0,0 +1 @@
+export default () => {};
diff --git a/app/assets/javascripts/ci_variable_list/components/ci_key_field.vue b/app/assets/javascripts/ci_variable_list/components/ci_key_field.vue
index f5c2cc57f3f..c15d638d92b 100644
--- a/app/assets/javascripts/ci_variable_list/components/ci_key_field.vue
+++ b/app/assets/javascripts/ci_variable_list/components/ci_key_field.vue
@@ -154,7 +154,7 @@ export default {
v-for="(result, i) in results"
:key="i"
role="option"
- :class="{ 'gl-bg-gray-100': i === arrowCounter }"
+ :class="{ 'gl-bg-gray-50': i === arrowCounter }"
:aria-selected="i === arrowCounter"
>
<gl-button tabindex="-1" class="btn-transparent pl-2" @click="selectToken(result)">{{
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 f6ade0867cd..6531b945212 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
@@ -1,19 +1,29 @@
<script>
import {
+ GlAlert,
+ GlButton,
+ GlCollapse,
GlDeprecatedButton,
- GlModal,
- GlFormSelect,
+ GlFormCheckbox,
GlFormGroup,
GlFormInput,
+ GlFormSelect,
GlFormTextarea,
- GlFormCheckbox,
- GlLink,
GlIcon,
+ GlLink,
+ GlModal,
+ GlSprintf,
} from '@gitlab/ui';
+import Cookies from 'js-cookie';
import { mapActions, mapState } from 'vuex';
import { __ } from '~/locale';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
-import { ADD_CI_VARIABLE_MODAL_ID } from '../constants';
+import {
+ AWS_TOKEN_CONSTANTS,
+ ADD_CI_VARIABLE_MODAL_ID,
+ AWS_TIP_DISMISSED_COOKIE_NAME,
+ AWS_TIP_MESSAGE,
+} from '../constants';
import { awsTokens, awsTokenList } from './ci_variable_autocomplete_tokens';
import CiKeyField from './ci_key_field.vue';
import CiEnvironmentsDropdown from './ci_environments_dropdown.vue';
@@ -23,19 +33,29 @@ export default {
components: {
CiEnvironmentsDropdown,
CiKeyField,
+ GlAlert,
+ GlButton,
+ GlCollapse,
GlDeprecatedButton,
- GlModal,
- GlFormSelect,
+ GlFormCheckbox,
GlFormGroup,
GlFormInput,
+ GlFormSelect,
GlFormTextarea,
- GlFormCheckbox,
- GlLink,
GlIcon,
+ GlLink,
+ GlModal,
+ GlSprintf,
},
mixins: [glFeatureFlagsMixin()],
tokens: awsTokens,
tokenList: awsTokenList,
+ awsTipMessage: AWS_TIP_MESSAGE,
+ data() {
+ return {
+ isTipDismissed: Cookies.get(AWS_TIP_DISMISSED_COOKIE_NAME) === 'true',
+ };
+ },
computed: {
...mapState([
'projectId',
@@ -47,7 +67,16 @@ export default {
'maskableRegex',
'selectedEnvironment',
'isProtectedByDefault',
+ 'awsLogoSvgPath',
+ 'awsTipDeployLink',
+ 'awsTipCommandsLink',
+ 'awsTipLearnLink',
+ 'protectedEnvironmentVariablesLink',
+ 'maskedEnvironmentVariablesLink',
]),
+ isTipVisible() {
+ return !this.isTipDismissed && AWS_TOKEN_CONSTANTS.includes(this.variableData.key);
+ },
canSubmit() {
return (
this.variableValidationState &&
@@ -126,6 +155,10 @@ export default {
'setSelectedEnvironment',
'setVariableProtected',
]),
+ dismissTip() {
+ Cookies.set(AWS_TIP_DISMISSED_COOKIE_NAME, 'true', { expires: 90 });
+ this.isTipDismissed = true;
+ },
deleteVarAndClose() {
this.deleteVariable(this.variableBeingEdited);
this.hideModal();
@@ -232,10 +265,10 @@ export default {
<gl-form-group :label="__('Flags')" label-for="ci-variable-flags">
<gl-form-checkbox v-model="variableData.protected" class="mb-0">
{{ __('Protect variable') }}
- <gl-link href="/help/ci/variables/README#protected-environment-variables">
+ <gl-link target="_blank" :href="protectedEnvironmentVariablesLink">
<gl-icon name="question" :size="12" />
</gl-link>
- <p class="prepend-top-4 text-secondary">
+ <p class="gl-mt-2 text-secondary">
{{ __('Export variable to pipelines running on protected branches and tags only.') }}
</p>
</gl-form-checkbox>
@@ -246,10 +279,10 @@ export default {
data-qa-selector="ci_variable_masked_checkbox"
>
{{ __('Mask variable') }}
- <gl-link href="/help/ci/variables/README#masked-variables">
+ <gl-link target="_blank" :href="maskedEnvironmentVariablesLink">
<gl-icon name="question" :size="12" />
</gl-link>
- <p class="prepend-top-4 append-bottom-0 text-secondary">
+ <p class="gl-mt-2 gl-mb-0 text-secondary">
{{ __('Variable will be masked in job logs.') }}
<span
:class="{
@@ -258,13 +291,52 @@ export default {
>
{{ __('Requires values to meet regular expression requirements.') }}</span
>
- <gl-link href="/help/ci/variables/README#masked-variables">{{
+ <gl-link target="_blank" :href="maskedEnvironmentVariablesLink">{{
__('More information')
}}</gl-link>
</p>
</gl-form-checkbox>
</gl-form-group>
</form>
+ <gl-collapse :visible="isTipVisible">
+ <gl-alert
+ :title="__('Deploying to AWS is easy with GitLab')"
+ variant="tip"
+ data-testid="aws-guidance-tip"
+ @dismiss="dismissTip"
+ >
+ <div class="gl-display-flex gl-flex-direction-row">
+ <div>
+ <p>
+ <gl-sprintf :message="$options.awsTipMessage">
+ <template #deployLink="{ content }">
+ <gl-link :href="awsTipDeployLink" target="_blank">{{ content }}</gl-link>
+ </template>
+ <template #commandsLink="{ content }">
+ <gl-link :href="awsTipCommandsLink" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </p>
+ <p>
+ <gl-button
+ :href="awsTipLearnLink"
+ target="_blank"
+ category="secondary"
+ variant="info"
+ class="gl-overflow-wrap-break"
+ >{{ __('Learn more about deploying to AWS') }}</gl-button
+ >
+ </p>
+ </div>
+ <img
+ class="gl-mt-3"
+ :alt="__('Amazon Web Services Logo')"
+ :src="awsLogoSvgPath"
+ height="32"
+ />
+ </div>
+ </gl-alert>
+ </gl-collapse>
<template #modal-footer>
<gl-deprecated-button @click="hideModal">{{ __('Cancel') }}</gl-deprecated-button>
<gl-deprecated-button
diff --git a/app/assets/javascripts/ci_variable_list/components/ci_variable_table.vue b/app/assets/javascripts/ci_variable_list/components/ci_variable_table.vue
index 7eb791f97e4..7b703c5ede1 100644
--- a/app/assets/javascripts/ci_variable_list/components/ci_variable_table.vue
+++ b/app/assets/javascripts/ci_variable_list/components/ci_variable_table.vue
@@ -170,7 +170,7 @@ export default {
v-if="tableIsNotEmpty"
ref="secret-value-reveal-button"
data-qa-selector="reveal_ci_variable_value_button"
- class="append-right-8"
+ class="gl-mr-3"
@click="toggleValues(!valuesHidden)"
>{{ valuesButtonText }}</gl-deprecated-button
>
diff --git a/app/assets/javascripts/ci_variable_list/constants.js b/app/assets/javascripts/ci_variable_list/constants.js
index a4db6481720..ef304c7ccee 100644
--- a/app/assets/javascripts/ci_variable_list/constants.js
+++ b/app/assets/javascripts/ci_variable_list/constants.js
@@ -15,7 +15,13 @@ export const types = {
allEnvironmentsType: '*',
};
+export const AWS_TIP_DISMISSED_COOKIE_NAME = 'ci_variable_list_constants_aws_tip_dismissed';
+export const AWS_TIP_MESSAGE = __(
+ '%{deployLinkStart}Use a template to deploy to ECS%{deployLinkEnd}, or use a docker image to %{commandsLinkStart}run AWS commands in GitLab CI/CD%{commandsLinkEnd}.',
+);
+
// AWS TOKEN CONSTANTS
export const AWS_ACCESS_KEY_ID = 'AWS_ACCESS_KEY_ID';
export const AWS_DEFAULT_REGION = 'AWS_DEFAULT_REGION';
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];
diff --git a/app/assets/javascripts/ci_variable_list/index.js b/app/assets/javascripts/ci_variable_list/index.js
index 2b4a56a4e6d..a28b52d6b57 100644
--- a/app/assets/javascripts/ci_variable_list/index.js
+++ b/app/assets/javascripts/ci_variable_list/index.js
@@ -3,9 +3,21 @@ import CiVariableSettings from './components/ci_variable_settings.vue';
import createStore from './store';
import { parseBoolean } from '~/lib/utils/common_utils';
-export default () => {
- const el = document.getElementById('js-ci-project-variables');
- const { endpoint, projectId, group, maskableRegex, protectedByDefault } = el.dataset;
+export default (containerId = 'js-ci-project-variables') => {
+ const containerEl = document.getElementById(containerId);
+ const {
+ endpoint,
+ projectId,
+ group,
+ maskableRegex,
+ protectedByDefault,
+ awsLogoSvgPath,
+ awsTipDeployLink,
+ awsTipCommandsLink,
+ awsTipLearnLink,
+ protectedEnvironmentVariablesLink,
+ maskedEnvironmentVariablesLink,
+ } = containerEl.dataset;
const isGroup = parseBoolean(group);
const isProtectedByDefault = parseBoolean(protectedByDefault);
@@ -15,10 +27,16 @@ export default () => {
isGroup,
maskableRegex,
isProtectedByDefault,
+ awsLogoSvgPath,
+ awsTipDeployLink,
+ awsTipCommandsLink,
+ awsTipLearnLink,
+ protectedEnvironmentVariablesLink,
+ maskedEnvironmentVariablesLink,
});
return new Vue({
- el,
+ el: containerEl,
store,
render(createElement) {
return createElement(CiVariableSettings);
diff --git a/app/assets/javascripts/clusters/clusters_bundle.js b/app/assets/javascripts/clusters/clusters_bundle.js
index d8bfbdb458c..f15efb2fdeb 100644
--- a/app/assets/javascripts/clusters/clusters_bundle.js
+++ b/app/assets/javascripts/clusters/clusters_bundle.js
@@ -468,6 +468,11 @@ export default class Clusters {
return;
}
+ if (appId === KNATIVE && !params.hostname && !params.pages_domain_id) {
+ reject(s__('ClusterIntegration|You must specify a domain before you can install Knative.'));
+ return;
+ }
+
resolve();
});
}
@@ -520,6 +525,7 @@ export default class Clusters {
this.store.updateAppProperty(appId, 'isEditingDomain', true);
this.store.updateAppProperty(appId, 'hostname', domain);
this.store.updateAppProperty(appId, 'pagesDomain', domainId ? { id: domainId, domain } : null);
+ this.store.updateAppProperty(appId, 'validationError', null);
}
setCrossplaneProviderStack(data) {
diff --git a/app/assets/javascripts/clusters/components/application_row.vue b/app/assets/javascripts/clusters/components/application_row.vue
index 53bc079a4e1..ba6de41e025 100644
--- a/app/assets/javascripts/clusters/components/application_row.vue
+++ b/app/assets/javascripts/clusters/components/application_row.vue
@@ -1,23 +1,24 @@
<script>
-/* eslint-disable vue/require-default-prop */
-/* eslint-disable @gitlab/vue-require-i18n-strings */
-import { GlLink, GlModalDirective } from '@gitlab/ui';
+import { GlLink, GlModalDirective, GlSprintf } from '@gitlab/ui';
import { s__, __, sprintf } from '~/locale';
import eventHub from '../event_hub';
import identicon from '../../vue_shared/components/identicon.vue';
import loadingButton from '../../vue_shared/components/loading_button.vue';
import UninstallApplicationButton from './uninstall_application_button.vue';
import UninstallApplicationConfirmationModal from './uninstall_application_confirmation_modal.vue';
+import UpdateApplicationConfirmationModal from './update_application_confirmation_modal.vue';
-import { APPLICATION_STATUS } from '../constants';
+import { APPLICATION_STATUS, ELASTIC_STACK } from '../constants';
export default {
components: {
loadingButton,
identicon,
GlLink,
+ GlSprintf,
UninstallApplicationButton,
UninstallApplicationConfirmationModal,
+ UpdateApplicationConfirmationModal,
},
directives: {
GlModalDirective,
@@ -34,15 +35,17 @@ export default {
titleLink: {
type: String,
required: false,
+ default: '',
},
manageLink: {
type: String,
required: false,
+ default: '',
},
logoUrl: {
type: String,
required: false,
- default: null,
+ default: '',
},
disabled: {
type: Boolean,
@@ -57,14 +60,17 @@ export default {
status: {
type: String,
required: false,
+ default: '',
},
statusReason: {
type: String,
required: false,
+ default: '',
},
requestReason: {
type: String,
required: false,
+ default: '',
},
installed: {
type: Boolean,
@@ -76,17 +82,15 @@ export default {
required: false,
default: false,
},
- installedVia: {
- type: String,
- required: false,
- },
version: {
type: String,
required: false,
+ default: '',
},
chartRepo: {
type: String,
required: false,
+ default: '',
},
updateAvailable: {
type: Boolean,
@@ -204,15 +208,6 @@ export default {
return sprintf(errorDescription, { title: this.title });
},
- versionLabel() {
- if (this.updateFailed) {
- return __('Update failed');
- } else if (this.isUpdating) {
- return __('Updating');
- }
-
- return this.updateSuccessful ? __('Updated to') : __('Updated');
- },
updateFailureDescription() {
return s__('ClusterIntegration|Update failed. Please check the logs and try again.');
},
@@ -233,6 +228,17 @@ export default {
return label;
},
+ updatingNeedsConfirmation() {
+ if (this.version) {
+ const majorVersion = parseInt(this.version.split('.')[0], 10);
+
+ if (!Number.isNaN(majorVersion)) {
+ return this.id === ELASTIC_STACK && majorVersion < 3;
+ }
+ }
+
+ return false;
+ },
isUpdating() {
// Since upgrading is handled asynchronously on the backend we need this check to prevent any delay on the frontend
return this.status === APPLICATION_STATUS.UPDATING;
@@ -248,6 +254,12 @@ export default {
title: this.title,
});
},
+ updateModalId() {
+ return `update-${this.id}`;
+ },
+ uninstallModalId() {
+ return `uninstall-${this.id}`;
+ },
},
watch: {
updateSuccessful(updateSuccessful) {
@@ -263,12 +275,16 @@ export default {
},
methods: {
installClicked() {
+ if (this.disabled || this.installButtonDisabled) return;
+
eventHub.$emit('installApplication', {
id: this.id,
params: this.installApplicationRequestParams,
});
},
- updateClicked() {
+ updateConfirmed() {
+ if (this.isUpdating) return;
+
eventHub.$emit('updateApplication', {
id: this.id,
params: this.installApplicationRequestParams,
@@ -294,7 +310,7 @@ export default {
:data-qa-selector="id"
>
<div class="gl-responsive-table-row-layout" role="row">
- <div class="table-section append-right-8 section-align-top" role="gridcell">
+ <div class="table-section gl-mr-3 section-align-top" role="gridcell">
<img
v-if="hasLogo"
:src="logoUrl"
@@ -315,14 +331,12 @@ export default {
>
<span v-else class="js-cluster-application-title">{{ title }}</span>
</strong>
- <span
- v-if="installedVia"
- class="js-cluster-application-installed-via"
- v-html="installedVia"
- ></span>
- <slot name="description"></slot>
+ <slot name="installedVia"></slot>
+ <div>
+ <slot name="description"></slot>
+ </div>
<div v-if="hasError" class="cluster-application-error text-danger prepend-top-10">
- <p class="js-cluster-application-general-error-message append-bottom-0">
+ <p class="js-cluster-application-general-error-message gl-mb-0">
{{ generalErrorDescription }}
</p>
<ul v-if="statusReason || requestReason">
@@ -340,14 +354,20 @@ export default {
v-if="shouldShowUpdateDetails"
class="form-text text-muted label p-0 js-cluster-application-update-details"
>
- {{ versionLabel }}
- <gl-link
- v-if="updateSuccessful"
- :href="chartRepo"
- target="_blank"
- class="js-cluster-application-update-version"
- >chart v{{ version }}</gl-link
- >
+ <template v-if="updateFailed">{{ __('Update failed') }}</template>
+ <template v-else-if="isUpdating">{{ __('Updating') }}</template>
+ <template v-else>
+ <gl-sprintf :message="__('Updated to %{linkStart}chart v%{linkEnd}')">
+ <template #link="{ content }">
+ <gl-link
+ :href="chartRepo"
+ target="_blank"
+ class="js-cluster-application-update-version"
+ >{{ content }}{{ version }}</gl-link
+ >
+ </template>
+ </gl-sprintf>
+ </template>
</div>
<div
@@ -356,14 +376,36 @@ export default {
>
{{ updateFailureDescription }}
</div>
- <loading-button
- v-if="updateAvailable || updateFailed || isUpdating"
- class="btn btn-primary js-cluster-application-update-button mt-2"
- :loading="isUpdating"
- :disabled="isUpdating"
- :label="updateButtonLabel"
- @click="updateClicked"
- />
+ <template v-if="updateAvailable || updateFailed || isUpdating">
+ <template v-if="updatingNeedsConfirmation">
+ <loading-button
+ v-gl-modal-directive="updateModalId"
+ class="btn btn-primary js-cluster-application-update-button mt-2"
+ :loading="isUpdating"
+ :disabled="isUpdating"
+ :label="updateButtonLabel"
+ data-qa-selector="update_button_with_confirmation"
+ :data-qa-application="id"
+ />
+
+ <update-application-confirmation-modal
+ :application="id"
+ :application-title="title"
+ @confirm="updateConfirmed()"
+ />
+ </template>
+
+ <loading-button
+ v-else
+ class="btn btn-primary js-cluster-application-update-button mt-2"
+ :loading="isUpdating"
+ :disabled="isUpdating"
+ :label="updateButtonLabel"
+ data-qa-selector="update_button"
+ :data-qa-application="id"
+ @click="updateConfirmed"
+ />
+ </template>
</div>
</div>
<div
@@ -389,7 +431,7 @@ export default {
/>
<uninstall-application-button
v-if="displayUninstallButton"
- v-gl-modal-directive="'uninstall-' + id"
+ v-gl-modal-directive="uninstallModalId"
:status="status"
data-qa-selector="uninstall_button"
:data-qa-application="id"
diff --git a/app/assets/javascripts/clusters/components/applications.vue b/app/assets/javascripts/clusters/components/applications.vue
index f11502a7dde..214906021ad 100644
--- a/app/assets/javascripts/clusters/components/applications.vue
+++ b/app/assets/javascripts/clusters/components/applications.vue
@@ -1,21 +1,16 @@
<script>
-import { escape } from 'lodash';
import helmInstallIllustration from '@gitlab/svgs/dist/illustrations/kubernetes-installation.svg';
-import { GlLoadingIcon } from '@gitlab/ui';
-import elasticsearchLogo from 'images/cluster_app_logos/elasticsearch.png';
+import { GlLoadingIcon, GlSprintf, GlLink } from '@gitlab/ui';
import gitlabLogo from 'images/cluster_app_logos/gitlab.png';
import helmLogo from 'images/cluster_app_logos/helm.png';
-import jeagerLogo from 'images/cluster_app_logos/jeager.png';
import jupyterhubLogo from 'images/cluster_app_logos/jupyterhub.png';
import kubernetesLogo from 'images/cluster_app_logos/kubernetes.png';
import certManagerLogo from 'images/cluster_app_logos/cert_manager.png';
import crossplaneLogo from 'images/cluster_app_logos/crossplane.png';
import knativeLogo from 'images/cluster_app_logos/knative.png';
-import meltanoLogo from 'images/cluster_app_logos/meltano.png';
import prometheusLogo from 'images/cluster_app_logos/prometheus.png';
import elasticStackLogo from 'images/cluster_app_logos/elastic_stack.png';
import fluentdLogo from 'images/cluster_app_logos/fluentd.png';
-import { s__, sprintf } from '../../locale';
import applicationRow from './application_row.vue';
import clipboardButton from '../../vue_shared/components/clipboard_button.vue';
import KnativeDomainEditor from './knative_domain_editor.vue';
@@ -30,6 +25,8 @@ export default {
applicationRow,
clipboardButton,
GlLoadingIcon,
+ GlSprintf,
+ GlLink,
KnativeDomainEditor,
CrossplaneProviderStack,
IngressModsecuritySettings,
@@ -92,25 +89,7 @@ export default {
default: false,
},
},
- data: () => ({
- elasticsearchLogo,
- gitlabLogo,
- helmLogo,
- jeagerLogo,
- jupyterhubLogo,
- kubernetesLogo,
- certManagerLogo,
- crossplaneLogo,
- knativeLogo,
- meltanoLogo,
- prometheusLogo,
- elasticStackLogo,
- fluentdLogo,
- }),
computed: {
- isProjectCluster() {
- return this.type === CLUSTER_TYPE.PROJECT;
- },
managedAppsLocalTillerEnabled() {
return Boolean(gon.features?.managedAppsLocalTiller);
},
@@ -133,84 +112,12 @@ export default {
certManagerInstalled() {
return this.applications.cert_manager.status === APPLICATION_STATUS.INSTALLED;
},
- crossplaneInstalled() {
- return this.applications.crossplane.status === APPLICATION_STATUS.INSTALLED;
- },
- ingressDescription() {
- return sprintf(
- escape(
- s__(
- `ClusterIntegration|Installing Ingress may incur additional costs. Learn more about %{pricingLink}.`,
- ),
- ),
- {
- pricingLink: `<a href="https://cloud.google.com/compute/pricing#lb"
- target="_blank" rel="noopener noreferrer">
- ${escape(s__('ClusterIntegration|pricing'))}</a>`,
- },
- false,
- );
- },
- certManagerDescription() {
- return sprintf(
- escape(
- s__(
- `ClusterIntegration|Cert-Manager is a native Kubernetes certificate management controller that helps with issuing certificates.
- Installing Cert-Manager on your cluster will issue a certificate by %{letsEncrypt} and ensure that certificates
- are valid and up-to-date.`,
- ),
- ),
- {
- letsEncrypt: `<a href="https://letsencrypt.org/"
- target="_blank" rel="noopener noreferrer">
- ${escape(s__("ClusterIntegration|Let's Encrypt"))}</a>`,
- },
- false,
- );
- },
- crossplaneDescription() {
- return sprintf(
- escape(
- s__(
- `ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}.
-Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on.`,
- ),
- ),
- {
- gitlabIntegrationLink: `<a href="https://docs.gitlab.com/ee/user/clusters/applications.html#crossplane"
- target="_blank" rel="noopener noreferrer">
- ${escape(s__('ClusterIntegration|Gitlab Integration'))}</a>`,
- kubectl: `<code>kubectl</code>`,
- },
- false,
- );
- },
-
- prometheusDescription() {
- return sprintf(
- escape(
- s__(
- `ClusterIntegration|Prometheus is an open-source monitoring system
- with %{gitlabIntegrationLink} to monitor deployed applications.`,
- ),
- ),
- {
- gitlabIntegrationLink: `<a href="https://docs.gitlab.com/ce/user/project/integrations/prometheus.html"
- target="_blank" rel="noopener noreferrer">
- ${escape(s__('ClusterIntegration|GitLab Integration'))}</a>`,
- },
- false,
- );
- },
jupyterInstalled() {
return this.applications.jupyter.status === APPLICATION_STATUS.INSTALLED;
},
jupyterHostname() {
return this.applications.jupyter.hostname;
},
- elasticStackInstalled() {
- return this.applications.elastic_stack.status === APPLICATION_STATUS.INSTALLED;
- },
knative() {
return this.applications.knative;
},
@@ -220,29 +127,10 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
cloudRun() {
return this.providerType === PROVIDER_TYPE.GCP && this.preInstalledKnative;
},
- installedVia() {
- if (this.cloudRun) {
- return sprintf(
- escape(s__(`ClusterIntegration|installed via %{installed_via}`)),
- {
- installed_via: `<a href="${
- this.cloudRunHelpPath
- }" target="_blank" rel="noopener noreferrer">${escape(
- s__('ClusterIntegration|Cloud Run'),
- )}</a>`,
- },
- false,
- );
- }
- return null;
- },
ingress() {
return this.applications.ingress;
},
},
- created() {
- this.helmInstallIllustration = helmInstallIllustration;
- },
methods: {
saveKnativeDomain() {
eventHub.$emit('saveKnativeDomain', {
@@ -267,24 +155,37 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
});
},
},
+ logos: {
+ gitlabLogo,
+ helmLogo,
+ jupyterhubLogo,
+ kubernetesLogo,
+ certManagerLogo,
+ crossplaneLogo,
+ knativeLogo,
+ prometheusLogo,
+ elasticStackLogo,
+ fluentdLogo,
+ },
+ helmInstallIllustration,
};
</script>
<template>
<section id="cluster-applications">
- <p class="append-bottom-0">
+ <p class="gl-mb-0">
{{
s__(`ClusterIntegration|Choose which applications to install on your Kubernetes cluster.
Helm Tiller is required to install any of the following applications.`)
}}
- <a :href="helpPath">{{ __('More information') }}</a>
+ <gl-link :href="helpPath">{{ __('More information') }}</gl-link>
</p>
<div class="cluster-application-list prepend-top-10">
<application-row
v-if="!managedAppsLocalTillerEnabled"
id="helm"
- :logo-url="helmLogo"
+ :logo-url="$options.logos.helmLogo"
:title="applications.helm.title"
:status="applications.helm.status"
:status-reason="applications.helm.statusReason"
@@ -298,17 +199,17 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
class="rounded-top"
title-link="https://docs.helm.sh/"
>
- <div slot="description">
+ <template #description>
{{
s__(`ClusterIntegration|Helm streamlines installing
and managing Kubernetes applications.
Tiller runs inside of your Kubernetes Cluster,
and manages releases of your charts.`)
}}
- </div>
+ </template>
</application-row>
<div v-show="!helmInstalled" class="cluster-application-warning">
- <div class="svg-container" v-html="helmInstallIllustration"></div>
+ <div class="svg-container" v-html="$options.helmInstallIllustration"></div>
{{
s__(`ClusterIntegration|You must first install Helm Tiller before
installing the applications below`)
@@ -316,7 +217,7 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
</div>
<application-row
:id="ingressId"
- :logo-url="kubernetesLogo"
+ :logo-url="$options.logos.kubernetesLogo"
:title="applications.ingress.title"
:status="applications.ingress.status"
:status-reason="applications.ingress.statusReason"
@@ -335,7 +236,7 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
:updateable="false"
title-link="https://kubernetes.io/docs/concepts/services-networking/ingress/"
>
- <div slot="description">
+ <template #description>
<p>
{{
s__(`ClusterIntegration|Ingress gives you a way to route
@@ -352,27 +253,29 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
<template v-if="ingressInstalled">
<div class="form-group">
<label for="ingress-endpoint">{{ s__('ClusterIntegration|Ingress Endpoint') }}</label>
- <div v-if="ingressExternalEndpoint" class="input-group">
- <input
- id="ingress-endpoint"
- :value="ingressExternalEndpoint"
- type="text"
- class="form-control js-endpoint"
- readonly
- />
- <span class="input-group-append">
- <clipboard-button
- :text="ingressExternalEndpoint"
- :title="s__('ClusterIntegration|Copy Ingress Endpoint')"
- class="input-group-text js-clipboard-btn"
+ <div class="input-group">
+ <template v-if="ingressExternalEndpoint">
+ <input
+ id="ingress-endpoint"
+ :value="ingressExternalEndpoint"
+ type="text"
+ class="form-control js-endpoint"
+ readonly
/>
- </span>
- </div>
- <div v-else class="input-group">
- <input type="text" class="form-control js-endpoint" readonly />
- <gl-loading-icon
- class="position-absolute align-self-center ml-2 js-ingress-ip-loading-icon"
- />
+ <span class="input-group-append">
+ <clipboard-button
+ :text="ingressExternalEndpoint"
+ :title="s__('ClusterIntegration|Copy Ingress Endpoint')"
+ class="input-group-text js-clipboard-btn"
+ />
+ </span>
+ </template>
+ <template v-else>
+ <input type="text" class="form-control js-endpoint" readonly />
+ <gl-loading-icon
+ class="position-absolute align-self-center ml-2 js-ingress-ip-loading-icon"
+ />
+ </template>
</div>
<p class="form-text text-muted">
{{
@@ -380,9 +283,9 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
generated endpoint in order to access
your application after it has been deployed.`)
}}
- <a :href="ingressDnsHelpPath" target="_blank" rel="noopener noreferrer">
+ <gl-link :href="ingressDnsHelpPath" target="_blank">
{{ __('More information') }}
- </a>
+ </gl-link>
</p>
</div>
@@ -392,21 +295,35 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
the process of being assigned. Please check your Kubernetes
cluster or Quotas on Google Kubernetes Engine if it takes a long time.`)
}}
- <a :href="ingressDnsHelpPath" target="_blank" rel="noopener noreferrer">
+ <gl-link :href="ingressDnsHelpPath" target="_blank">
{{ __('More information') }}
- </a>
+ </gl-link>
</p>
</template>
- <template v-if="!ingressInstalled">
+ <template v-else>
<div class="bs-callout bs-callout-info">
- <strong v-html="ingressDescription"></strong>
+ <strong data-testid="ingressCostWarning">
+ <gl-sprintf
+ :message="
+ s__(
+ 'ClusterIntegration|Installing Ingress may incur additional costs. Learn more about %{linkStart}pricing%{linkEnd}.',
+ )
+ "
+ >
+ <template #link="{ content }">
+ <gl-link href="https://cloud.google.com/compute/pricing#lb" target="_blank">{{
+ content
+ }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </strong>
</div>
</template>
- </div>
+ </template>
</application-row>
<application-row
id="cert_manager"
- :logo-url="certManagerLogo"
+ :logo-url="$options.logos.certManagerLogo"
:title="applications.cert_manager.title"
:status="applications.cert_manager.status"
:status-reason="applications.cert_manager.statusReason"
@@ -421,40 +338,50 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
:disabled="!helmInstalled"
title-link="https://cert-manager.readthedocs.io/en/latest/#"
>
- <template>
- <div slot="description">
- <p v-html="certManagerDescription"></p>
- <div class="form-group">
- <label for="cert-manager-issuer-email">
- {{ s__('ClusterIntegration|Issuer Email') }}
- </label>
- <div class="input-group">
- <input
- v-model="applications.cert_manager.email"
- :readonly="certManagerInstalled"
- type="text"
- class="form-control js-email"
- />
- </div>
- <p class="form-text text-muted">
- {{
- s__(`ClusterIntegration|Issuers represent a certificate authority.
- You must provide an email address for your Issuer. `)
- }}
- <a
- href="http://docs.cert-manager.io/en/latest/reference/issuers.html?highlight=email"
- target="_blank"
- rel="noopener noreferrer"
- >{{ __('More information') }}</a
- >
- </p>
+ <template #description>
+ <p data-testid="certManagerDescription">
+ <gl-sprintf
+ :message="
+ s__(`ClusterIntegration|Cert-Manager is a native Kubernetes certificate management controller that helps with issuing certificates.
+ Installing Cert-Manager on your cluster will issue a certificate by %{linkStart}Let's Encrypt%{linkEnd} and ensure that certificates
+ are valid and up-to-date.`)
+ "
+ >
+ <template #link="{ content }">
+ <gl-link href="https://letsencrypt.org/" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </p>
+ <div class="form-group">
+ <label for="cert-manager-issuer-email">
+ {{ s__('ClusterIntegration|Issuer Email') }}
+ </label>
+ <div class="input-group">
+ <input
+ id="cert-manager-issuer-email"
+ v-model="applications.cert_manager.email"
+ :readonly="certManagerInstalled"
+ type="text"
+ class="form-control js-email"
+ />
</div>
+ <p class="form-text text-muted">
+ {{
+ s__(`ClusterIntegration|Issuers represent a certificate authority.
+ You must provide an email address for your Issuer.`)
+ }}
+ <gl-link
+ href="http://docs.cert-manager.io/en/latest/reference/issuers.html?highlight=email"
+ target="_blank"
+ >{{ __('More information') }}</gl-link
+ >
+ </p>
</div>
</template>
</application-row>
<application-row
id="prometheus"
- :logo-url="prometheusLogo"
+ :logo-url="$options.logos.prometheusLogo"
:title="applications.prometheus.title"
:manage-link="managePrometheusPath"
:status="applications.prometheus.status"
@@ -469,11 +396,28 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
:disabled="!helmInstalled"
title-link="https://prometheus.io/docs/introduction/overview/"
>
- <div slot="description" v-html="prometheusDescription"></div>
+ <template #description>
+ <span data-testid="prometheusDescription">
+ <gl-sprintf
+ :message="
+ s__(`ClusterIntegration|Prometheus is an open-source monitoring system
+ with %{linkStart}GitLab Integration%{linkEnd} to monitor deployed applications.`)
+ "
+ >
+ <template #link="{ content }">
+ <gl-link
+ href="https://docs.gitlab.com/ce/user/project/integrations/prometheus.html"
+ target="_blank"
+ >{{ content }}</gl-link
+ >
+ </template>
+ </gl-sprintf>
+ </span>
+ </template>
</application-row>
<application-row
id="runner"
- :logo-url="gitlabLogo"
+ :logo-url="$options.logos.gitlabLogo"
:title="applications.runner.title"
:status="applications.runner.status"
:status-reason="applications.runner.statusReason"
@@ -492,18 +436,18 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
:disabled="!helmInstalled"
title-link="https://docs.gitlab.com/runner/"
>
- <div slot="description">
+ <template #description>
{{
s__(`ClusterIntegration|GitLab Runner connects to the
repository and executes CI/CD jobs,
pushing results back and deploying
applications to production.`)
}}
- </div>
+ </template>
</application-row>
<application-row
id="crossplane"
- :logo-url="crossplaneLogo"
+ :logo-url="$options.logos.crossplaneLogo"
:title="applications.crossplane.title"
:status="applications.crossplane.status"
:status-reason="applications.crossplane.statusReason"
@@ -518,19 +462,37 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
:disabled="!helmInstalled"
title-link="https://crossplane.io"
>
- <template>
- <div slot="description">
- <p v-html="crossplaneDescription"></p>
- <div class="form-group">
- <CrossplaneProviderStack :crossplane="crossplane" @set="setCrossplaneProviderStack" />
- </div>
+ <template #description>
+ <p data-testid="crossplaneDescription">
+ <gl-sprintf
+ :message="
+ s__(
+ `ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{linkStart}GitLab Integration%{linkEnd}.
+ Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on.`,
+ )
+ "
+ >
+ <template #code="{content}">
+ <code>{{ content }}</code>
+ </template>
+ <template #link="{ content }">
+ <gl-link
+ href="https://docs.gitlab.com/ee/user/clusters/applications.html#crossplane"
+ target="_blank"
+ >{{ content }}</gl-link
+ >
+ </template>
+ </gl-sprintf>
+ </p>
+ <div class="form-group">
+ <CrossplaneProviderStack :crossplane="crossplane" @set="setCrossplaneProviderStack" />
</div>
</template>
</application-row>
<application-row
id="jupyter"
- :logo-url="jupyterhubLogo"
+ :logo-url="$options.logos.jupyterhubLogo"
:title="applications.jupyter.title"
:status="applications.jupyter.status"
:status-reason="applications.jupyter.statusReason"
@@ -545,7 +507,7 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
:disabled="!helmInstalled"
title-link="https://jupyterhub.readthedocs.io/en/stable/"
>
- <div slot="description">
+ <template #description>
<p>
{{
s__(`ClusterIntegration|JupyterHub, a multi-user Hub, spawns,
@@ -562,6 +524,7 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
<div class="input-group">
<input
+ id="jupyter-hostname"
v-model="applications.jupyter.hostname"
:readonly="jupyterInstalled"
type="text"
@@ -581,17 +544,17 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
s__(`ClusterIntegration|Replace this with your own hostname if you want.
If you do so, point hostname to Ingress IP Address from above.`)
}}
- <a :href="ingressDnsHelpPath" target="_blank" rel="noopener noreferrer">
+ <gl-link :href="ingressDnsHelpPath" target="_blank">
{{ __('More information') }}
- </a>
+ </gl-link>
</p>
</div>
</template>
- </div>
+ </template>
</application-row>
<application-row
id="knative"
- :logo-url="knativeLogo"
+ :logo-url="$options.logos.knativeLogo"
:title="applications.knative.title"
:status="applications.knative.status"
:status-reason="applications.knative.statusReason"
@@ -603,7 +566,6 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
hostname: applications.knative.hostname,
pages_domain_id: applications.knative.pagesDomain && applications.knative.pagesDomain.id,
}"
- :installed-via="installedVia"
:uninstallable="applications.knative.uninstallable"
:uninstall-successful="applications.knative.uninstallSuccessful"
:uninstall-failed="applications.knative.uninstallFailed"
@@ -612,19 +574,14 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
v-bind="applications.knative"
title-link="https://github.com/knative/docs"
>
- <div slot="description">
- <span v-if="!rbac">
- <p v-if="!rbac" class="rbac-notice bs-callout bs-callout-info append-bottom-0">
- {{
- s__(`ClusterIntegration|You must have an RBAC-enabled cluster
- to install Knative.`)
- }}
- <a :href="helpPath" target="_blank" rel="noopener noreferrer">
- {{ __('More information') }}
- </a>
- </p>
- <br />
- </span>
+ <template #description>
+ <p v-if="!rbac" class="rbac-notice bs-callout bs-callout-info">
+ {{
+ s__(`ClusterIntegration|You must have an RBAC-enabled cluster
+ to install Knative.`)
+ }}
+ <gl-link :href="helpPath" target="_blank">{{ __('More information') }}</gl-link>
+ </p>
<p>
{{
s__(`ClusterIntegration|Knative extends Kubernetes to provide
@@ -641,11 +598,22 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
@save="saveKnativeDomain"
@set="setKnativeDomain"
/>
- </div>
+ </template>
+ <template v-if="cloudRun" #installedVia>
+ <span data-testid="installedVia">
+ <gl-sprintf
+ :message="s__('ClusterIntegration|installed via %{linkStart}Cloud Run%{linkEnd}')"
+ >
+ <template #link="{ content }">
+ <gl-link :href="cloudRunHelpPath" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </span>
+ </template>
</application-row>
<application-row
id="elastic_stack"
- :logo-url="elasticStackLogo"
+ :logo-url="$options.logos.elasticStackLogo"
:title="applications.elastic_stack.title"
:status="applications.elastic_stack.status"
:status-reason="applications.elastic_stack.statusReason"
@@ -664,7 +632,7 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
:disabled="!helmInstalled"
title-link="https://gitlab.com/gitlab-org/charts/elastic-stack"
>
- <div slot="description">
+ <template #description>
<p>
{{
s__(
@@ -672,12 +640,12 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
)
}}
</p>
- </div>
+ </template>
</application-row>
<application-row
id="fluentd"
- :logo-url="fluentdLogo"
+ :logo-url="$options.logos.fluentdLogo"
:title="applications.fluentd.title"
:status="applications.fluentd.status"
:status-reason="applications.fluentd.statusReason"
@@ -699,7 +667,7 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
:updateable="false"
title-link="https://github.com/helm/charts/tree/master/stable/fluentd"
>
- <div slot="description">
+ <template #description>
<p>
{{
s__(
@@ -717,7 +685,7 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
:status="applications.fluentd.status"
:update-failed="applications.fluentd.updateFailed"
/>
- </div>
+ </template>
</application-row>
</div>
</section>
diff --git a/app/assets/javascripts/clusters/components/fluentd_output_settings.vue b/app/assets/javascripts/clusters/components/fluentd_output_settings.vue
index 1884b501a20..20f6210aba8 100644
--- a/app/assets/javascripts/clusters/components/fluentd_output_settings.vue
+++ b/app/assets/javascripts/clusters/components/fluentd_output_settings.vue
@@ -215,10 +215,10 @@ export default {
</div>
<div class="form-group flex flex-wrap">
<gl-form-checkbox :checked="wafLogEnabled" @input="wafLogChanged">
- <strong>{{ s__('ClusterIntegration|Send ModSecurity Logs') }}</strong>
+ <strong>{{ s__('ClusterIntegration|Send Web Application Firewall Logs') }}</strong>
</gl-form-checkbox>
<gl-form-checkbox :checked="ciliumLogEnabled" @input="ciliumLogChanged">
- <strong>{{ s__('ClusterIntegration|Send Cilium Logs') }}</strong>
+ <strong>{{ s__('ClusterIntegration|Send Container Network Policies Logs') }}</strong>
</gl-form-checkbox>
</div>
<div v-if="showButtons" class="mt-3">
diff --git a/app/assets/javascripts/clusters/components/ingress_modsecurity_settings.vue b/app/assets/javascripts/clusters/components/ingress_modsecurity_settings.vue
index c2f963f0b34..54f5468bdd0 100644
--- a/app/assets/javascripts/clusters/components/ingress_modsecurity_settings.vue
+++ b/app/assets/javascripts/clusters/components/ingress_modsecurity_settings.vue
@@ -13,12 +13,12 @@ import {
GlIcon,
} from '@gitlab/ui';
import eventHub from '~/clusters/event_hub';
-import modSecurityLogo from 'images/cluster_app_logos/modsecurity.png';
+import modSecurityLogo from 'images/cluster_app_logos/gitlab.png';
const { UPDATING, UNINSTALLING, INSTALLING, INSTALLED, UPDATED } = APPLICATION_STATUS;
export default {
- title: 'ModSecurity Web Application Firewall',
+ title: __('Web Application Firewall'),
modsecurityUrl: 'https://modsecurity.org/about.html',
components: {
GlAlert,
@@ -168,7 +168,7 @@ export default {
}}
</gl-alert>
<div class="gl-responsive-table-row-layout" role="row">
- <div class="table-section append-right-8 section-align-top" role="gridcell">
+ <div class="table-section gl-mr-3 section-align-top" role="gridcell">
<img
:src="modSecurityLogo"
:alt="`${$options.title} logo`"
diff --git a/app/assets/javascripts/clusters/components/knative_domain_editor.vue b/app/assets/javascripts/clusters/components/knative_domain_editor.vue
index 8136704d13b..ac61cd8e242 100644
--- a/app/assets/javascripts/clusters/components/knative_domain_editor.vue
+++ b/app/assets/javascripts/clusters/components/knative_domain_editor.vue
@@ -82,6 +82,9 @@ export default {
showDomainsDropdown() {
return this.availableDomains.length > 0;
},
+ validationError() {
+ return this.knative.validationError;
+ },
},
watch: {
knativeUpdateSuccessful(updateSuccessful) {
@@ -157,6 +160,8 @@ export default {
type="text"
class="form-control js-knative-domainname"
/>
+
+ <span v-if="validationError" class="gl-field-error">{{ validationError }}</span>
</div>
<template v-if="knativeInstalled">
diff --git a/app/assets/javascripts/clusters/components/remove_cluster_confirmation.vue b/app/assets/javascripts/clusters/components/remove_cluster_confirmation.vue
index 271f9f74838..c5375cbfbdc 100644
--- a/app/assets/javascripts/clusters/components/remove_cluster_confirmation.vue
+++ b/app/assets/javascripts/clusters/components/remove_cluster_confirmation.vue
@@ -147,7 +147,7 @@ export default {
)
}}</span>
</template>
- <template slot="modal-footer">
+ <template #modal-footer>
<gl-deprecated-button variant="secondary" @click="handleCancel">{{
s__('Cancel')
}}</gl-deprecated-button>
diff --git a/app/assets/javascripts/clusters/components/update_application_confirmation_modal.vue b/app/assets/javascripts/clusters/components/update_application_confirmation_modal.vue
new file mode 100644
index 00000000000..04aa28e9b74
--- /dev/null
+++ b/app/assets/javascripts/clusters/components/update_application_confirmation_modal.vue
@@ -0,0 +1,65 @@
+<script>
+import { GlModal } from '@gitlab/ui';
+import { sprintf, s__ } from '~/locale';
+import { ELASTIC_STACK } from '../constants';
+
+const CUSTOM_APP_WARNING_TEXT = {
+ [ELASTIC_STACK]: s__(
+ 'ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days.',
+ ),
+};
+
+export default {
+ components: {
+ GlModal,
+ },
+ props: {
+ application: {
+ type: String,
+ required: true,
+ },
+ applicationTitle: {
+ type: String,
+ required: true,
+ },
+ },
+ computed: {
+ title() {
+ return sprintf(s__('ClusterIntegration|Update %{appTitle}'), {
+ appTitle: this.applicationTitle,
+ });
+ },
+ warningText() {
+ return sprintf(
+ s__('ClusterIntegration|You are about to update %{appTitle} on your cluster.'),
+ {
+ appTitle: this.applicationTitle,
+ },
+ );
+ },
+ customAppWarningText() {
+ return CUSTOM_APP_WARNING_TEXT[this.application];
+ },
+ modalId() {
+ return `update-${this.application}`;
+ },
+ },
+ methods: {
+ confirmUpdate() {
+ this.$emit('confirm');
+ },
+ },
+};
+</script>
+<template>
+ <gl-modal
+ ok-variant="danger"
+ cancel-variant="light"
+ :ok-title="title"
+ :modal-id="modalId"
+ :title="title"
+ @ok="confirmUpdate()"
+ >
+ {{ warningText }} <span v-html="customAppWarningText"></span>
+ </gl-modal>
+</template>
diff --git a/app/assets/javascripts/clusters_list/components/clusters.vue b/app/assets/javascripts/clusters_list/components/clusters.vue
index af3f1437c64..a3104038c17 100644
--- a/app/assets/javascripts/clusters_list/components/clusters.vue
+++ b/app/assets/javascripts/clusters_list/components/clusters.vue
@@ -1,23 +1,34 @@
<script>
+import * as Sentry from '@sentry/browser';
import { mapState, mapActions } from 'vuex';
-import { GlBadge, GlLink, GlLoadingIcon, GlPagination, GlTable } from '@gitlab/ui';
+import {
+ GlDeprecatedBadge as GlBadge,
+ GlLink,
+ GlLoadingIcon,
+ GlPagination,
+ GlSprintf,
+ GlTable,
+} from '@gitlab/ui';
import tooltip from '~/vue_shared/directives/tooltip';
import { CLUSTER_TYPES, STATUSES } from '../constants';
import { __, sprintf } from '~/locale';
export default {
+ nodeMemoryText: __('%{totalMemory} (%{freeSpacePercentage}%{percentSymbol} free)'),
+ nodeCpuText: __('%{totalCpu} (%{freeSpacePercentage}%{percentSymbol} free)'),
components: {
GlBadge,
GlLink,
GlLoadingIcon,
GlPagination,
+ GlSprintf,
GlTable,
},
directives: {
tooltip,
},
computed: {
- ...mapState(['clusters', 'clustersPerPage', 'loading', 'page', 'totalCulsters']),
+ ...mapState(['clusters', 'clustersPerPage', 'loading', 'page', 'providers', 'totalCulsters']),
currentPage: {
get() {
return this.page;
@@ -37,19 +48,18 @@ export default {
key: 'environment_scope',
label: __('Environment scope'),
},
- // Wait for backend to send these fields
- // {
- // key: 'size',
- // label: __('Size'),
- // },
- // {
- // key: 'cpu',
- // label: __('Total cores (vCPUs)'),
- // },
- // {
- // key: 'memory',
- // label: __('Total memory (GB)'),
- // },
+ {
+ key: 'node_size',
+ label: __('Nodes'),
+ },
+ {
+ key: 'total_cpu',
+ label: __('Total cores (CPUs)'),
+ },
+ {
+ key: 'total_memory',
+ label: __('Total memory (GB)'),
+ },
{
key: 'cluster_type',
label: __('Cluster level'),
@@ -66,14 +76,105 @@ export default {
},
methods: {
...mapActions(['fetchClusters', 'setPage']),
- statusClass(status) {
- const iconClass = STATUSES[status] || STATUSES.default;
- return iconClass.className;
+ k8sQuantityToGb(quantity) {
+ if (!quantity) {
+ return 0;
+ } else if (quantity.endsWith(__('Ki'))) {
+ return parseInt(quantity.substr(0, quantity.length - 2), 10) * 0.000001024;
+ } else if (quantity.endsWith(__('Mi'))) {
+ return parseInt(quantity.substr(0, quantity.length - 2), 10) * 0.001048576;
+ }
+
+ // We are trying to track quantity types coming from Kubernetes.
+ // Sentry will notify us if we are missing types.
+ throw new Error(`UnknownK8sMemoryQuantity:${quantity}`);
+ },
+ k8sQuantityToCpu(quantity) {
+ if (!quantity) {
+ return 0;
+ } else if (quantity.endsWith('m')) {
+ return parseInt(quantity.substr(0, quantity.length - 1), 10) / 1000.0;
+ } else if (quantity.endsWith('n')) {
+ return parseInt(quantity.substr(0, quantity.length - 1), 10) / 1000000000.0;
+ }
+
+ // We are trying to track quantity types coming from Kubernetes.
+ // Sentry will notify us if we are missing types.
+ throw new Error(`UnknownK8sCpuQuantity:${quantity}`);
+ },
+ selectedProvider(provider) {
+ return this.providers[provider] || this.providers.default;
},
statusTitle(status) {
const iconTitle = STATUSES[status] || STATUSES.default;
return sprintf(__('Status: %{title}'), { title: iconTitle.title }, false);
},
+ totalMemoryAndUsage(nodes) {
+ try {
+ // For EKS node.usage will not be present unless the user manually
+ // install the metrics server
+ if (nodes && nodes[0].usage) {
+ let totalAllocatableMemory = 0;
+ let totalUsedMemory = 0;
+
+ nodes.reduce((total, node) => {
+ const allocatableMemoryQuantity = node.status.allocatable.memory;
+ const allocatableMemoryGb = this.k8sQuantityToGb(allocatableMemoryQuantity);
+ totalAllocatableMemory += allocatableMemoryGb;
+
+ const usedMemoryQuantity = node.usage.memory;
+ const usedMemoryGb = this.k8sQuantityToGb(usedMemoryQuantity);
+ totalUsedMemory += usedMemoryGb;
+
+ return null;
+ }, 0);
+
+ const freeSpacePercentage = (1 - totalUsedMemory / totalAllocatableMemory) * 100;
+
+ return {
+ totalMemory: totalAllocatableMemory.toFixed(2),
+ freeSpacePercentage: Math.round(freeSpacePercentage),
+ };
+ }
+ } catch (error) {
+ Sentry.captureException(error);
+ }
+
+ return { totalMemory: null, freeSpacePercentage: null };
+ },
+ totalCpuAndUsage(nodes) {
+ try {
+ // For EKS node.usage will not be present unless the user manually
+ // install the metrics server
+ if (nodes && nodes[0].usage) {
+ let totalAllocatableCpu = 0;
+ let totalUsedCpu = 0;
+
+ nodes.reduce((total, node) => {
+ const allocatableCpuQuantity = node.status.allocatable.cpu;
+ const allocatableCpu = this.k8sQuantityToCpu(allocatableCpuQuantity);
+ totalAllocatableCpu += allocatableCpu;
+
+ const usedCpuQuantity = node.usage.cpu;
+ const usedCpuGb = this.k8sQuantityToCpu(usedCpuQuantity);
+ totalUsedCpu += usedCpuGb;
+
+ return null;
+ }, 0);
+
+ const freeSpacePercentage = (1 - totalUsedCpu / totalAllocatableCpu) * 100;
+
+ return {
+ totalCpu: totalAllocatableCpu.toFixed(2),
+ freeSpacePercentage: Math.round(freeSpacePercentage),
+ };
+ }
+ } catch (error) {
+ Sentry.captureException(error);
+ }
+
+ return { totalCpu: null, freeSpacePercentage: null };
+ },
},
};
</script>
@@ -84,27 +185,68 @@ export default {
<section v-else>
<gl-table :items="clusters" :fields="fields" stacked="md" class="qa-clusters-table">
<template #cell(name)="{ item }">
- <div class="d-flex flex-row-reverse flex-md-row js-status">
- <gl-link data-qa-selector="cluster" :data-qa-cluster-name="item.name" :href="item.path">
+ <div
+ class="gl-display-flex gl-align-items-center gl-justify-content-end gl-justify-content-md-start js-status"
+ >
+ <img
+ :src="selectedProvider(item.provider_type).path"
+ :alt="selectedProvider(item.provider_type).text"
+ class="gl-w-6 gl-h-6 gl-display-flex gl-align-items-center"
+ />
+
+ <gl-link
+ data-qa-selector="cluster"
+ :data-qa-cluster-name="item.name"
+ :href="item.path"
+ class="gl-px-3"
+ >
{{ item.name }}
</gl-link>
<gl-loading-icon
- v-if="item.status === 'deleting'"
+ v-if="item.status === 'deleting' || item.status === 'creating'"
v-tooltip
:title="statusTitle(item.status)"
size="sm"
- class="mr-2 ml-md-2"
/>
- <div
- v-else
- v-tooltip
- class="cluster-status-indicator rounded-circle align-self-center gl-w-4 gl-h-4 mr-2 ml-md-2"
- :class="statusClass(item.status)"
- :title="statusTitle(item.status)"
- ></div>
</div>
</template>
+
+ <template #cell(node_size)="{ item }">
+ <span v-if="item.nodes">{{ item.nodes.length }}</span>
+ <small v-else class="gl-font-sm gl-font-style-italic gl-text-gray-400">{{
+ __('Unknown')
+ }}</small>
+ </template>
+
+ <template #cell(total_cpu)="{ item }">
+ <span v-if="item.nodes">
+ <gl-sprintf :message="$options.nodeCpuText">
+ <template #totalCpu>{{ totalCpuAndUsage(item.nodes).totalCpu }}</template>
+ <template #freeSpacePercentage>{{
+ totalCpuAndUsage(item.nodes).freeSpacePercentage
+ }}</template>
+ <template #percentSymbol
+ >%</template
+ >
+ </gl-sprintf>
+ </span>
+ </template>
+
+ <template #cell(total_memory)="{ item }">
+ <span v-if="item.nodes">
+ <gl-sprintf :message="$options.nodeMemoryText">
+ <template #totalMemory>{{ totalMemoryAndUsage(item.nodes).totalMemory }}</template>
+ <template #freeSpacePercentage>{{
+ totalMemoryAndUsage(item.nodes).freeSpacePercentage
+ }}</template>
+ <template #percentSymbol
+ >%</template
+ >
+ </gl-sprintf>
+ </span>
+ </template>
+
<template #cell(cluster_type)="{value}">
<gl-badge variant="light">
{{ value }}
diff --git a/app/assets/javascripts/clusters_list/constants.js b/app/assets/javascripts/clusters_list/constants.js
index eebcaa086f9..3e8ef3151a6 100644
--- a/app/assets/javascripts/clusters_list/constants.js
+++ b/app/assets/javascripts/clusters_list/constants.js
@@ -6,6 +6,8 @@ export const CLUSTER_TYPES = {
instance_type: __('Instance'),
};
+export const MAX_REQUESTS = 3;
+
export const STATUSES = {
default: { className: 'bg-white', title: __('Unknown') },
disabled: { className: 'disabled', title: __('Disabled') },
@@ -13,4 +15,5 @@ export const STATUSES = {
unreachable: { className: 'bg-danger', title: __('Unreachable') },
authentication_failure: { className: 'bg-warning', title: __('Authentication Failure') },
deleting: { title: __('Deleting') },
+ creating: { title: __('Creating') },
};
diff --git a/app/assets/javascripts/clusters_list/index.js b/app/assets/javascripts/clusters_list/index.js
index 67d0a33030b..51ad8769250 100644
--- a/app/assets/javascripts/clusters_list/index.js
+++ b/app/assets/javascripts/clusters_list/index.js
@@ -9,12 +9,10 @@ export default () => {
return;
}
- const { endpoint } = entryPoint.dataset;
-
// eslint-disable-next-line no-new
new Vue({
el: '#js-clusters-list-app',
- store: createStore({ endpoint }),
+ store: createStore(entryPoint.dataset),
render(createElement) {
return createElement(Clusters);
},
diff --git a/app/assets/javascripts/clusters_list/store/actions.js b/app/assets/javascripts/clusters_list/store/actions.js
index 919625f69b4..5245c307c8c 100644
--- a/app/assets/javascripts/clusters_list/store/actions.js
+++ b/app/assets/javascripts/clusters_list/store/actions.js
@@ -2,10 +2,23 @@ import Poll from '~/lib/utils/poll';
import axios from '~/lib/utils/axios_utils';
import flash from '~/flash';
import { __ } from '~/locale';
+import { MAX_REQUESTS } from '../constants';
import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils';
+import * as Sentry from '@sentry/browser';
import * as types from './mutation_types';
+const allNodesPresent = (clusters, retryCount) => {
+ /*
+ Nodes are coming from external Kubernetes clusters.
+ They may fail for reasons GitLab cannot control.
+ MAX_REQUESTS will ensure this poll stops at some point.
+ */
+ return retryCount > MAX_REQUESTS || clusters.every(cluster => cluster.nodes != null);
+};
+
export const fetchClusters = ({ state, commit }) => {
+ let retryCount = 0;
+
const poll = new Poll({
resource: {
fetchClusters: paginatedEndPoint => axios.get(paginatedEndPoint),
@@ -13,16 +26,40 @@ export const fetchClusters = ({ state, commit }) => {
data: `${state.endpoint}?page=${state.page}`,
method: 'fetchClusters',
successCallback: ({ data, headers }) => {
- if (data.clusters) {
- const normalizedHeaders = normalizeHeaders(headers);
- const paginationInformation = parseIntPagination(normalizedHeaders);
+ retryCount += 1;
+
+ try {
+ if (data.clusters) {
+ const normalizedHeaders = normalizeHeaders(headers);
+ const paginationInformation = parseIntPagination(normalizedHeaders);
+
+ commit(types.SET_CLUSTERS_DATA, { data, paginationInformation });
+ commit(types.SET_LOADING_STATE, false);
- commit(types.SET_CLUSTERS_DATA, { data, paginationInformation });
- commit(types.SET_LOADING_STATE, false);
+ if (allNodesPresent(data.clusters, retryCount)) {
+ poll.stop();
+ }
+ }
+ } catch (error) {
poll.stop();
+
+ Sentry.withScope(scope => {
+ scope.setTag('javascript_clusters_list', 'fetchClustersSuccessCallback');
+ Sentry.captureException(error);
+ });
}
},
- errorCallback: () => flash(__('An error occurred while loading clusters')),
+ errorCallback: response => {
+ poll.stop();
+
+ commit(types.SET_LOADING_STATE, false);
+ flash(__('Clusters|An error occurred while loading clusters'));
+
+ Sentry.withScope(scope => {
+ scope.setTag('javascript_clusters_list', 'fetchClustersErrorCallback');
+ Sentry.captureException(response);
+ });
+ },
});
poll.makeRequest();
diff --git a/app/assets/javascripts/clusters_list/store/state.js b/app/assets/javascripts/clusters_list/store/state.js
index d590ea09e66..0023b43ed92 100644
--- a/app/assets/javascripts/clusters_list/store/state.js
+++ b/app/assets/javascripts/clusters_list/store/state.js
@@ -5,5 +5,10 @@ export default (initialState = {}) => ({
clusters: [],
clustersPerPage: 0,
page: 1,
+ providers: {
+ aws: { path: initialState.imgTagsAwsPath, text: initialState.imgTagsAwsText },
+ default: { path: initialState.imgTagsDefaultPath, text: initialState.imgTagsDefaultText },
+ gcp: { path: initialState.imgTagsGcpPath, text: initialState.imgTagsGcpText },
+ },
totalCulsters: 0,
});
diff --git a/app/assets/javascripts/code_navigation/components/doc_line.vue b/app/assets/javascripts/code_navigation/components/doc_line.vue
new file mode 100644
index 00000000000..69d398893d9
--- /dev/null
+++ b/app/assets/javascripts/code_navigation/components/doc_line.vue
@@ -0,0 +1,22 @@
+<script>
+export default {
+ props: {
+ language: {
+ type: String,
+ required: true,
+ },
+ tokens: {
+ type: Array,
+ required: true,
+ },
+ },
+};
+</script>
+
+<template>
+ <span class="line" :lang="language">
+ <span v-for="(token, tokenIndex) in tokens" :key="tokenIndex" :class="token.class">{{
+ token.value
+ }}</span>
+ </span>
+</template>
diff --git a/app/assets/javascripts/code_navigation/components/popover.vue b/app/assets/javascripts/code_navigation/components/popover.vue
index 7147ce227e8..df5f89e4faf 100644
--- a/app/assets/javascripts/code_navigation/components/popover.vue
+++ b/app/assets/javascripts/code_navigation/components/popover.vue
@@ -1,9 +1,11 @@
<script>
import { GlButton } from '@gitlab/ui';
+import DocLine from './doc_line.vue';
export default {
components: {
GlButton,
+ DocLine,
},
props: {
position: {
@@ -83,8 +85,7 @@ export default {
ref="code-output"
:class="$options.colorScheme"
class="border-0 bg-transparent m-0 code highlight"
- v-html="hover.value"
- ></pre>
+ ><doc-line v-for="(tokens, tokenIndex) in hover.tokens" :key="tokenIndex" :language="hover.language" :tokens="tokens"/></pre>
<p v-else ref="doc-output" class="p-3 m-0">
{{ hover.value }}
</p>
diff --git a/app/assets/javascripts/commit/image_file.js b/app/assets/javascripts/commit/image_file.js
index ddb129f36f4..542890d9b04 100644
--- a/app/assets/javascripts/commit/image_file.js
+++ b/app/assets/javascripts/commit/image_file.js
@@ -1,6 +1,7 @@
/* 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;
diff --git a/app/assets/javascripts/commons/bootstrap.js b/app/assets/javascripts/commons/bootstrap.js
index e5e1cbb1e62..df0fa1ae88b 100644
--- a/app/assets/javascripts/commons/bootstrap.js
+++ b/app/assets/javascripts/commons/bootstrap.js
@@ -70,7 +70,12 @@ whitelist.acronym = [];
whitelist.blockquote = [];
whitelist.del = [];
whitelist.ins = [];
-whitelist['gl-emoji'] = [];
+whitelist['gl-emoji'] = [
+ 'data-name',
+ 'data-unicode-version',
+ 'data-fallback-src',
+ 'data-fallback-sprite-class',
+];
// Whitelisting SVG tags and attributes
whitelist.svg = ['viewBox'];
diff --git a/app/assets/javascripts/commons/jquery.js b/app/assets/javascripts/commons/jquery.js
index 25640f71af2..c4d663dfc8d 100644
--- a/app/assets/javascripts/commons/jquery.js
+++ b/app/assets/javascripts/commons/jquery.js
@@ -2,8 +2,6 @@ import 'jquery';
// common jQuery plugins
import 'jquery-ujs';
-import 'vendor/jquery.endless-scroll';
import 'jquery.caret'; // must be imported before at.js
import '@gitlab/at.js';
import 'vendor/jquery.scrollTo';
-import 'jquery.waitforimages';
diff --git a/app/assets/javascripts/custom_metrics/components/custom_metrics_form.vue b/app/assets/javascripts/custom_metrics/components/custom_metrics_form.vue
index e5c0d1e4970..f60be52d6ca 100644
--- a/app/assets/javascripts/custom_metrics/components/custom_metrics_form.vue
+++ b/app/assets/javascripts/custom_metrics/components/custom_metrics_form.vue
@@ -66,7 +66,7 @@ export default {
</script>
<template>
<div class="row my-3">
- <h4 class="prepend-top-0 col-lg-8 offset-lg-2">{{ titleText }}</h4>
+ <h4 class="gl-mt-0 col-lg-8 offset-lg-2">{{ titleText }}</h4>
<form ref="form" class="col-lg-8 offset-lg-2" :action="customMetricsPath" method="post">
<custom-metrics-form-fields
:form-operation="formOperation"
diff --git a/app/assets/javascripts/design_management/components/design_note_pin.vue b/app/assets/javascripts/design_management/components/design_note_pin.vue
index 50ea69d52ce..0811397fbad 100644
--- a/app/assets/javascripts/design_management/components/design_note_pin.vue
+++ b/app/assets/javascripts/design_management/components/design_note_pin.vue
@@ -13,7 +13,7 @@ export default {
required: true,
},
label: {
- type: String,
+ type: Number,
required: false,
default: null,
},
@@ -47,7 +47,7 @@ export default {
'btn-transparent comment-indicator': isNewNote,
'js-image-badge badge badge-pill': !isNewNote,
}"
- class="position-absolute"
+ class="design-pin gl-absolute gl-display-flex gl-align-items-center gl-justify-content-center"
type="button"
@mousedown="$emit('mousedown', $event)"
@mouseup="$emit('mouseup', $event)"
diff --git a/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue b/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue
index c6c5ee88a93..7e442bb295f 100644
--- a/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue
+++ b/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue
@@ -1,14 +1,19 @@
<script>
import { ApolloMutation } from 'vue-apollo';
+import { GlTooltipDirective, GlIcon, GlLoadingIcon, GlLink } from '@gitlab/ui';
+import { s__ } from '~/locale';
import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue';
+import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import allVersionsMixin from '../../mixins/all_versions';
import createNoteMutation from '../../graphql/mutations/createNote.mutation.graphql';
+import toggleResolveDiscussionMutation from '../../graphql/mutations/toggle_resolve_discussion.mutation.graphql';
import getDesignQuery from '../../graphql/queries/getDesign.query.graphql';
import activeDiscussionQuery from '../../graphql/queries/active_discussion.query.graphql';
import DesignNote from './design_note.vue';
import DesignReplyForm from './design_reply_form.vue';
import { updateStoreAfterAddDiscussionComment } from '../../utils/cache_update';
import { ACTIVE_DISCUSSION_SOURCE_TYPES } from '../../constants';
+import ToggleRepliesWidget from './toggle_replies_widget.vue';
export default {
components: {
@@ -16,6 +21,14 @@ export default {
DesignNote,
ReplyPlaceholder,
DesignReplyForm,
+ GlIcon,
+ GlLoadingIcon,
+ GlLink,
+ ToggleRepliesWidget,
+ TimeAgoTooltip,
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
},
mixins: [allVersionsMixin],
props: {
@@ -31,21 +44,28 @@ export default {
type: String,
required: true,
},
- discussionIndex: {
- type: Number,
- required: true,
- },
markdownPreviewPath: {
type: String,
required: false,
default: '',
},
+ resolvedDiscussionsExpanded: {
+ type: Boolean,
+ required: true,
+ },
+ discussionWithOpenForm: {
+ type: String,
+ required: true,
+ },
},
apollo: {
activeDiscussion: {
query: activeDiscussionQuery,
result({ data }) {
const discussionId = data.activeDiscussion.id;
+ if (this.discussion.resolved && !this.resolvedDiscussionsExpanded) {
+ return;
+ }
// We watch any changes to the active discussion from the design pins and scroll to this discussion if it exists
// We don't want scrollIntoView to be triggered from the discussion click itself
if (
@@ -66,6 +86,9 @@ export default {
discussionComment: '',
isFormRendered: false,
activeDiscussion: {},
+ isResolving: false,
+ shouldChangeResolvedStatus: false,
+ areRepliesCollapsed: this.discussion.resolved,
};
},
computed: {
@@ -87,6 +110,32 @@ export default {
isDiscussionHighlighted() {
return this.discussion.notes[0].id === this.activeDiscussion.id;
},
+ resolveCheckboxText() {
+ return this.discussion.resolved
+ ? s__('DesignManagement|Unresolve thread')
+ : s__('DesignManagement|Resolve thread');
+ },
+ firstNote() {
+ return this.discussion.notes[0];
+ },
+ discussionReplies() {
+ return this.discussion.notes.slice(1);
+ },
+ areRepliesShown() {
+ return !this.discussion.resolved || !this.areRepliesCollapsed;
+ },
+ resolveIconName() {
+ return this.discussion.resolved ? 'check-circle-filled' : 'check-circle';
+ },
+ isRepliesWidgetVisible() {
+ return this.discussion.resolved && this.discussionReplies.length > 0;
+ },
+ isReplyPlaceholderVisible() {
+ return this.areRepliesShown || !this.discussionReplies.length;
+ },
+ isFormVisible() {
+ return this.isFormRendered && this.discussionWithOpenForm === this.discussion.id;
+ },
},
methods: {
addDiscussionComment(
@@ -106,17 +155,40 @@ export default {
onDone() {
this.discussionComment = '';
this.hideForm();
+ if (this.shouldChangeResolvedStatus) {
+ this.toggleResolvedStatus();
+ }
},
- onError(err) {
- this.$emit('error', err);
+ onCreateNoteError(err) {
+ this.$emit('createNoteError', err);
},
hideForm() {
this.isFormRendered = false;
this.discussionComment = '';
},
showForm() {
+ this.$emit('openForm', this.discussion.id);
this.isFormRendered = true;
},
+ toggleResolvedStatus() {
+ this.isResolving = true;
+ this.$apollo
+ .mutate({
+ mutation: toggleResolveDiscussionMutation,
+ variables: { id: this.discussion.id, resolve: !this.discussion.resolved },
+ })
+ .then(({ data }) => {
+ if (data.errors?.length > 0) {
+ this.$emit('resolveDiscussionError', data.errors[0]);
+ }
+ })
+ .catch(err => {
+ this.$emit('resolveDiscussionError', err);
+ })
+ .finally(() => {
+ this.isResolving = false;
+ });
+ },
},
createNoteMutation,
};
@@ -124,22 +196,71 @@ export default {
<template>
<div class="design-discussion-wrapper">
- <div class="badge badge-pill" type="button">{{ discussionIndex }}</div>
<div
- class="design-discussion bordered-box position-relative"
+ class="badge badge-pill gl-display-flex gl-align-items-center gl-justify-content-center"
+ :class="{ resolved: discussion.resolved }"
+ type="button"
+ >
+ {{ discussion.index }}
+ </div>
+ <ul
+ class="design-discussion bordered-box gl-relative gl-p-0 gl-list-style-none"
data-qa-selector="design_discussion_content"
>
<design-note
- v-for="note in discussion.notes"
+ :note="firstNote"
+ :markdown-preview-path="markdownPreviewPath"
+ :is-resolving="isResolving"
+ :class="{ 'gl-bg-blue-50': isDiscussionHighlighted }"
+ @error="$emit('updateNoteError', $event)"
+ >
+ <template v-if="discussion.resolvable" #resolveDiscussion>
+ <button
+ v-gl-tooltip
+ :class="{ 'is-active': discussion.resolved }"
+ :title="resolveCheckboxText"
+ :aria-label="resolveCheckboxText"
+ type="button"
+ class="line-resolve-btn note-action-button gl-mr-3"
+ data-testid="resolve-button"
+ @click.stop="toggleResolvedStatus"
+ >
+ <gl-icon v-if="!isResolving" :name="resolveIconName" data-testid="resolve-icon" />
+ <gl-loading-icon v-else inline />
+ </button>
+ </template>
+ <template v-if="discussion.resolved" #resolvedStatus>
+ <p class="gl-text-gray-700 gl-font-sm gl-m-0 gl-mt-5" data-testid="resolved-message">
+ {{ __('Resolved by') }}
+ <gl-link
+ class="gl-text-gray-700 gl-text-decoration-none gl-font-sm link-inherit-color"
+ :href="discussion.resolvedBy.webUrl"
+ target="_blank"
+ >{{ discussion.resolvedBy.name }}</gl-link
+ >
+ <time-ago-tooltip :time="discussion.resolvedAt" tooltip-placement="bottom" />
+ </p>
+ </template>
+ </design-note>
+ <toggle-replies-widget
+ v-if="isRepliesWidgetVisible"
+ :collapsed="areRepliesCollapsed"
+ :replies="discussionReplies"
+ @toggle="areRepliesCollapsed = !areRepliesCollapsed"
+ />
+ <design-note
+ v-for="note in discussionReplies"
+ v-show="areRepliesShown"
:key="note.id"
:note="note"
:markdown-preview-path="markdownPreviewPath"
+ :is-resolving="isResolving"
:class="{ 'gl-bg-blue-50': isDiscussionHighlighted }"
@error="$emit('updateNoteError', $event)"
/>
- <div class="reply-wrapper">
+ <li v-show="isReplyPlaceholderVisible" class="reply-wrapper">
<reply-placeholder
- v-if="!isFormRendered"
+ v-if="!isFormVisible"
class="qa-discussion-reply"
:button-text="__('Reply...')"
@onClick="showForm"
@@ -153,7 +274,7 @@ export default {
}"
:update="addDiscussionComment"
@done="onDone"
- @error="onError"
+ @error="onCreateNoteError"
>
<design-reply-form
v-model="discussionComment"
@@ -161,9 +282,16 @@ export default {
:markdown-preview-path="markdownPreviewPath"
@submitForm="mutate"
@cancelForm="hideForm"
- />
+ >
+ <template v-if="discussion.resolvable" #resolveCheckbox>
+ <label data-testid="resolve-checkbox">
+ <input v-model="shouldChangeResolvedStatus" type="checkbox" />
+ {{ resolveCheckboxText }}
+ </label>
+ </template>
+ </design-reply-form>
</apollo-mutation>
- </div>
- </div>
+ </li>
+ </ul>
</div>
</template>
diff --git a/app/assets/javascripts/design_management/components/design_notes/design_note.vue b/app/assets/javascripts/design_management/components/design_notes/design_note.vue
index c1c19c0a597..b1f3a43a66d 100644
--- a/app/assets/javascripts/design_management/components/design_notes/design_note.vue
+++ b/app/assets/javascripts/design_management/components/design_notes/design_note.vue
@@ -54,6 +54,9 @@ export default {
body: this.noteText,
};
},
+ isEditButtonVisible() {
+ return !this.isEditing && this.note.userPermissions.adminNote;
+ },
},
mounted() {
if (this.isNoteLinked) {
@@ -107,23 +110,28 @@ export default {
</template>
</span>
</div>
- <button
- v-if="!isEditing && note.userPermissions.adminNote"
- v-gl-tooltip
- type="button"
- title="Edit comment"
- class="note-action-button js-note-edit btn btn-transparent qa-note-edit-button"
- @click="isEditing = true"
- >
- <gl-icon name="pencil" class="link-highlight" />
- </button>
+ <div class="gl-display-flex">
+ <slot name="resolveDiscussion"></slot>
+ <button
+ v-if="isEditButtonVisible"
+ v-gl-tooltip
+ type="button"
+ :title="__('Edit comment')"
+ class="note-action-button js-note-edit btn btn-transparent qa-note-edit-button"
+ @click="isEditing = true"
+ >
+ <gl-icon name="pencil" class="link-highlight" />
+ </button>
+ </div>
</div>
- <div
- v-if="!isEditing"
- class="note-text js-note-text md"
- data-qa-selector="note_content"
- v-html="note.bodyHtml"
- ></div>
+ <template v-if="!isEditing">
+ <div
+ class="note-text js-note-text md"
+ data-qa-selector="note_content"
+ v-html="note.bodyHtml"
+ ></div>
+ <slot name="resolvedStatus"></slot>
+ </template>
<apollo-mutation
v-else
#default="{ mutate, loading }"
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 40be9867fee..756da7f55aa 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
@@ -107,7 +107,8 @@ export default {
</textarea>
</template>
</markdown-field>
- <div class="note-form-actions d-flex justify-content-between">
+ <slot name="resolveCheckbox"></slot>
+ <div class="note-form-actions gl-display-flex gl-justify-content-space-between">
<gl-deprecated-button
ref="submitButton"
:disabled="!hasValue || isSaving"
diff --git a/app/assets/javascripts/design_management/components/design_notes/toggle_replies_widget.vue b/app/assets/javascripts/design_management/components/design_notes/toggle_replies_widget.vue
new file mode 100644
index 00000000000..46c73e3eea8
--- /dev/null
+++ b/app/assets/javascripts/design_management/components/design_notes/toggle_replies_widget.vue
@@ -0,0 +1,70 @@
+<script>
+import { GlIcon, GlButton, GlLink } from '@gitlab/ui';
+import { __, n__ } from '~/locale';
+import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
+
+export default {
+ name: 'ToggleNotesWidget',
+ components: {
+ GlIcon,
+ GlButton,
+ GlLink,
+ TimeAgoTooltip,
+ },
+ props: {
+ collapsed: {
+ type: Boolean,
+ required: true,
+ },
+ replies: {
+ type: Array,
+ required: true,
+ },
+ },
+ computed: {
+ lastReply() {
+ return this.replies[this.replies.length - 1];
+ },
+ iconName() {
+ return this.collapsed ? 'chevron-right' : 'chevron-down';
+ },
+ toggleText() {
+ return this.collapsed
+ ? `${this.replies.length} ${n__('reply', 'replies', this.replies.length)}`
+ : __('Collapse replies');
+ },
+ },
+};
+</script>
+
+<template>
+ <li
+ class="toggle-comments gl-bg-gray-50 gl-display-flex gl-align-items-center gl-py-3"
+ :class="{ expanded: !collapsed }"
+ data-testid="toggle-comments-wrapper"
+ >
+ <gl-icon :name="iconName" class="gl-ml-3" @click.stop="$emit('toggle')" />
+ <gl-button
+ variant="link"
+ class="toggle-comments-button gl-ml-2 gl-mr-2"
+ @click.stop="$emit('toggle')"
+ >
+ {{ toggleText }}
+ </gl-button>
+ <template v-if="collapsed">
+ <span class="gl-text-gray-700">{{ __('Last reply by') }}</span>
+ <gl-link
+ :href="lastReply.author.webUrl"
+ target="_blank"
+ class="link-inherit-color gl-text-black-normal gl-text-decoration-none gl-font-weight-bold gl-ml-2 gl-mr-2"
+ >
+ {{ lastReply.author.name }}
+ </gl-link>
+ <time-ago-tooltip
+ :time="lastReply.createdAt"
+ tooltip-placement="bottom"
+ class="gl-text-gray-700"
+ />
+ </template>
+ </li>
+</template>
diff --git a/app/assets/javascripts/design_management/components/design_overlay.vue b/app/assets/javascripts/design_management/components/design_overlay.vue
index beb51647821..926e7c74802 100644
--- a/app/assets/javascripts/design_management/components/design_overlay.vue
+++ b/app/assets/javascripts/design_management/components/design_overlay.vue
@@ -33,6 +33,10 @@ export default {
required: false,
default: false,
},
+ resolvedDiscussionsExpanded: {
+ type: Boolean,
+ required: true,
+ },
},
apollo: {
activeDiscussion: {
@@ -140,7 +144,7 @@ export default {
},
onExistingNoteMove(e) {
const note = this.notes.find(({ id }) => id === this.movingNoteStartPosition.noteId);
- if (!note) return;
+ if (!note || !this.canMoveNote(note)) return;
const { position } = note;
const { width, height } = position;
@@ -186,8 +190,6 @@ export default {
});
},
onNoteMousedown({ clientX, clientY }, note) {
- if (note && !this.canMoveNote(note)) return;
-
this.movingNoteStartPosition = {
noteId: note?.id,
discussionId: note?.discussion.id,
@@ -236,6 +238,9 @@ export default {
isNoteInactive(note) {
return this.activeDiscussion.id && this.activeDiscussion.id !== note.id;
},
+ designPinClass(note) {
+ return { inactive: this.isNoteInactive(note), resolved: note.resolved };
+ },
},
};
</script>
@@ -254,20 +259,23 @@ export default {
data-qa-selector="design_image_button"
@mouseup="onAddCommentMouseup"
></button>
- <design-note-pin
- v-for="(note, index) in notes"
- :key="note.id"
- :label="`${index + 1}`"
- :repositioning="isMovingNote(note.id)"
- :position="
- isMovingNote(note.id) && movingNoteNewPosition
- ? getNotePositionStyle(movingNoteNewPosition)
- : getNotePositionStyle(note.position)
- "
- :class="{ inactive: isNoteInactive(note) }"
- @mousedown.stop="onNoteMousedown($event, note)"
- @mouseup.stop="onNoteMouseup(note)"
- />
+ <template v-for="note in notes">
+ <design-note-pin
+ v-if="resolvedDiscussionsExpanded || !note.resolved"
+ :key="note.id"
+ :label="note.index"
+ :repositioning="isMovingNote(note.id)"
+ :position="
+ isMovingNote(note.id) && movingNoteNewPosition
+ ? getNotePositionStyle(movingNoteNewPosition)
+ : getNotePositionStyle(note.position)
+ "
+ :class="designPinClass(note)"
+ @mousedown.stop="onNoteMousedown($event, note)"
+ @mouseup.stop="onNoteMouseup(note)"
+ />
+ </template>
+
<design-note-pin
v-if="currentCommentForm"
:position="currentCommentPositionStyle"
diff --git a/app/assets/javascripts/design_management/components/design_presentation.vue b/app/assets/javascripts/design_management/components/design_presentation.vue
index 5c113b3dbed..84dbb2809d9 100644
--- a/app/assets/javascripts/design_management/components/design_presentation.vue
+++ b/app/assets/javascripts/design_management/components/design_presentation.vue
@@ -35,6 +35,10 @@ export default {
required: false,
default: 1,
},
+ resolvedDiscussionsExpanded: {
+ type: Boolean,
+ required: true,
+ },
},
data() {
return {
@@ -54,7 +58,10 @@ export default {
},
computed: {
discussionStartingNotes() {
- return this.discussions.map(discussion => discussion.notes[0]);
+ return this.discussions.map(discussion => ({
+ ...discussion.notes[0],
+ index: discussion.index,
+ }));
},
currentCommentForm() {
return (this.isAnnotating && this.currentAnnotationPosition) || null;
@@ -305,6 +312,7 @@ export default {
:notes="discussionStartingNotes"
:current-comment-form="currentCommentForm"
:disable-commenting="isDraggingDesign"
+ :resolved-discussions-expanded="resolvedDiscussionsExpanded"
@openCommentForm="openCommentForm"
@closeCommentForm="closeCommentForm"
@moveNote="moveNote"
diff --git a/app/assets/javascripts/design_management/components/design_sidebar.vue b/app/assets/javascripts/design_management/components/design_sidebar.vue
new file mode 100644
index 00000000000..333ad2557e8
--- /dev/null
+++ b/app/assets/javascripts/design_management/components/design_sidebar.vue
@@ -0,0 +1,178 @@
+<script>
+import { s__ } from '~/locale';
+import Cookies from 'js-cookie';
+import { parseBoolean } from '~/lib/utils/common_utils';
+import { GlCollapse, GlButton, GlPopover } from '@gitlab/ui';
+import updateActiveDiscussionMutation from '../graphql/mutations/update_active_discussion.mutation.graphql';
+import { extractDiscussions, extractParticipants } from '../utils/design_management_utils';
+import { ACTIVE_DISCUSSION_SOURCE_TYPES } from '../constants';
+import DesignDiscussion from './design_notes/design_discussion.vue';
+import Participants from '~/sidebar/components/participants/participants.vue';
+
+export default {
+ components: {
+ DesignDiscussion,
+ Participants,
+ GlCollapse,
+ GlButton,
+ GlPopover,
+ },
+ props: {
+ design: {
+ type: Object,
+ required: true,
+ },
+ resolvedDiscussionsExpanded: {
+ type: Boolean,
+ required: true,
+ },
+ markdownPreviewPath: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ isResolvedCommentsPopoverHidden: parseBoolean(Cookies.get(this.$options.cookieKey)),
+ discussionWithOpenForm: '',
+ };
+ },
+ computed: {
+ discussions() {
+ return extractDiscussions(this.design.discussions);
+ },
+ issue() {
+ return {
+ ...this.design.issue,
+ webPath: this.design.issue.webPath.substr(1),
+ };
+ },
+ discussionParticipants() {
+ return extractParticipants(this.issue.participants);
+ },
+ resolvedDiscussions() {
+ return this.discussions.filter(discussion => discussion.resolved);
+ },
+ unresolvedDiscussions() {
+ return this.discussions.filter(discussion => !discussion.resolved);
+ },
+ resolvedCommentsToggleIcon() {
+ return this.resolvedDiscussionsExpanded ? 'chevron-down' : 'chevron-right';
+ },
+ },
+ methods: {
+ handleSidebarClick() {
+ this.isResolvedCommentsPopoverHidden = true;
+ Cookies.set(this.$options.cookieKey, 'true', { expires: 365 * 10 });
+ this.updateActiveDiscussion();
+ },
+ updateActiveDiscussion(id) {
+ this.$apollo.mutate({
+ mutation: updateActiveDiscussionMutation,
+ variables: {
+ id,
+ source: ACTIVE_DISCUSSION_SOURCE_TYPES.discussion,
+ },
+ });
+ },
+ closeCommentForm() {
+ this.comment = '';
+ this.$emit('closeCommentForm');
+ },
+ updateDiscussionWithOpenForm(id) {
+ this.discussionWithOpenForm = id;
+ },
+ },
+ resolveCommentsToggleText: s__('DesignManagement|Resolved Comments'),
+ cookieKey: 'hide_design_resolved_comments_popover',
+};
+</script>
+
+<template>
+ <div class="image-notes" @click="handleSidebarClick">
+ <h2 class="gl-font-weight-bold gl-mt-0">
+ {{ issue.title }}
+ </h2>
+ <a
+ class="gl-text-gray-600 gl-text-decoration-none gl-mb-6 gl-display-block"
+ :href="issue.webUrl"
+ >{{ issue.webPath }}</a
+ >
+ <participants
+ :participants="discussionParticipants"
+ :show-participant-label="false"
+ class="gl-mb-4"
+ />
+ <h2
+ v-if="unresolvedDiscussions.length === 0"
+ class="new-discussion-disclaimer gl-font-base gl-m-0 gl-mb-4"
+ data-testid="new-discussion-disclaimer"
+ >
+ {{ s__("DesignManagement|Click the image where you'd like to start a new discussion") }}
+ </h2>
+ <design-discussion
+ v-for="discussion in unresolvedDiscussions"
+ :key="discussion.id"
+ :discussion="discussion"
+ :design-id="$route.params.id"
+ :noteable-id="design.id"
+ :markdown-preview-path="markdownPreviewPath"
+ :resolved-discussions-expanded="resolvedDiscussionsExpanded"
+ :discussion-with-open-form="discussionWithOpenForm"
+ data-testid="unresolved-discussion"
+ @createNoteError="$emit('onDesignDiscussionError', $event)"
+ @updateNoteError="$emit('updateNoteError', $event)"
+ @resolveDiscussionError="$emit('resolveDiscussionError', $event)"
+ @click.native.stop="updateActiveDiscussion(discussion.notes[0].id)"
+ @openForm="updateDiscussionWithOpenForm"
+ />
+ <template v-if="resolvedDiscussions.length > 0">
+ <gl-button
+ id="resolved-comments"
+ data-testid="resolved-comments"
+ :icon="resolvedCommentsToggleIcon"
+ variant="link"
+ class="link-inherit-color gl-text-black-normal gl-text-decoration-none gl-font-weight-bold gl-mb-4"
+ @click="$emit('toggleResolvedComments')"
+ >{{ $options.resolveCommentsToggleText }} ({{ resolvedDiscussions.length }})
+ </gl-button>
+ <gl-popover
+ v-if="!isResolvedCommentsPopoverHidden"
+ :show="!isResolvedCommentsPopoverHidden"
+ target="resolved-comments"
+ container="popovercontainer"
+ placement="top"
+ :title="s__('DesignManagement|Resolved Comments')"
+ >
+ <p>
+ {{
+ s__(
+ 'DesignManagement|Comments you resolve can be viewed and unresolved by going to the "Resolved Comments" section below',
+ )
+ }}
+ </p>
+ <a href="#" rel="noopener noreferrer" target="_blank">{{
+ s__('DesignManagement|Learn more about resolving comments')
+ }}</a>
+ </gl-popover>
+ <gl-collapse :visible="resolvedDiscussionsExpanded" class="gl-mt-3">
+ <design-discussion
+ v-for="discussion in resolvedDiscussions"
+ :key="discussion.id"
+ :discussion="discussion"
+ :design-id="$route.params.id"
+ :noteable-id="design.id"
+ :markdown-preview-path="markdownPreviewPath"
+ :resolved-discussions-expanded="resolvedDiscussionsExpanded"
+ :discussion-with-open-form="discussionWithOpenForm"
+ data-testid="resolved-discussion"
+ @error="$emit('onDesignDiscussionError', $event)"
+ @updateNoteError="$emit('updateNoteError', $event)"
+ @openForm="updateDiscussionWithOpenForm"
+ @click.native.stop="updateActiveDiscussion(discussion.notes[0].id)"
+ />
+ </gl-collapse>
+ </template>
+ <slot name="replyForm"></slot>
+ </div>
+</template>
diff --git a/app/assets/javascripts/design_management/components/upload/button.vue b/app/assets/javascripts/design_management/components/upload/button.vue
index e3c5e369170..68555104a3c 100644
--- a/app/assets/javascripts/design_management/components/upload/button.vue
+++ b/app/assets/javascripts/design_management/components/upload/button.vue
@@ -41,7 +41,7 @@ export default {
variant="success"
@click="openFileUpload"
>
- {{ s__('DesignManagement|Add designs') }}
+ {{ s__('DesignManagement|Upload designs') }}
<gl-loading-icon v-if="isSaving" inline class="ml-1" />
</gl-deprecated-button>
diff --git a/app/assets/javascripts/design_management/constants.js b/app/assets/javascripts/design_management/constants.js
index 59d34669ad7..21ff361a277 100644
--- a/app/assets/javascripts/design_management/constants.js
+++ b/app/assets/javascripts/design_management/constants.js
@@ -12,3 +12,5 @@ export const ACTIVE_DISCUSSION_SOURCE_TYPES = {
pin: 'pin',
discussion: 'discussion',
};
+
+export const DESIGN_DETAIL_LAYOUT_CLASSLIST = ['design-detail-layout', 'overflow-hidden', 'm-0'];
diff --git a/app/assets/javascripts/design_management/graphql/fragments/design.fragment.graphql b/app/assets/javascripts/design_management/graphql/fragments/design.fragment.graphql
index ca5b5a52c71..c1439c56ff5 100644
--- a/app/assets/javascripts/design_management/graphql/fragments/design.fragment.graphql
+++ b/app/assets/javascripts/design_management/graphql/fragments/design.fragment.graphql
@@ -1,6 +1,7 @@
#import "./designNote.fragment.graphql"
#import "./designList.fragment.graphql"
#import "./diffRefs.fragment.graphql"
+#import "./discussion_resolved_status.fragment.graphql"
fragment DesignItem on Design {
...DesignListItem
@@ -12,6 +13,7 @@ fragment DesignItem on Design {
nodes {
id
replyId
+ ...ResolvedStatus
notes {
nodes {
...DesignNote
diff --git a/app/assets/javascripts/design_management/graphql/fragments/designNote.fragment.graphql b/app/assets/javascripts/design_management/graphql/fragments/designNote.fragment.graphql
index 2ad84f9cb17..cb7cfd89abf 100644
--- a/app/assets/javascripts/design_management/graphql/fragments/designNote.fragment.graphql
+++ b/app/assets/javascripts/design_management/graphql/fragments/designNote.fragment.graphql
@@ -10,6 +10,7 @@ fragment DesignNote on Note {
body
bodyHtml
createdAt
+ resolved
position {
diffRefs {
...DesignDiffRefs
diff --git a/app/assets/javascripts/design_management/graphql/fragments/discussion_resolved_status.fragment.graphql b/app/assets/javascripts/design_management/graphql/fragments/discussion_resolved_status.fragment.graphql
new file mode 100644
index 00000000000..7483b508721
--- /dev/null
+++ b/app/assets/javascripts/design_management/graphql/fragments/discussion_resolved_status.fragment.graphql
@@ -0,0 +1,9 @@
+fragment ResolvedStatus on Discussion {
+ resolvable
+ resolved
+ resolvedAt
+ resolvedBy {
+ name
+ webUrl
+ }
+}
diff --git a/app/assets/javascripts/design_management/graphql/mutations/toggle_resolve_discussion.mutation.graphql b/app/assets/javascripts/design_management/graphql/mutations/toggle_resolve_discussion.mutation.graphql
new file mode 100644
index 00000000000..d5f54ec9b58
--- /dev/null
+++ b/app/assets/javascripts/design_management/graphql/mutations/toggle_resolve_discussion.mutation.graphql
@@ -0,0 +1,17 @@
+#import "../fragments/designNote.fragment.graphql"
+#import "../fragments/discussion_resolved_status.fragment.graphql"
+
+mutation toggleResolveDiscussion($id: ID!, $resolve: Boolean!) {
+ discussionToggleResolve(input: { id: $id, resolve: $resolve }) {
+ discussion {
+ id
+ ...ResolvedStatus
+ notes {
+ nodes {
+ ...DesignNote
+ }
+ }
+ }
+ errors
+ }
+}
diff --git a/app/assets/javascripts/design_management/pages/design/index.vue b/app/assets/javascripts/design_management/pages/design/index.vue
index 7ff3271394d..fe121b6530a 100644
--- a/app/assets/javascripts/design_management/pages/design/index.vue
+++ b/app/assets/javascripts/design_management/pages/design/index.vue
@@ -1,17 +1,16 @@
<script>
-import { ApolloMutation } from 'vue-apollo';
import Mousetrap from 'mousetrap';
import { GlLoadingIcon, GlAlert } from '@gitlab/ui';
+import { ApolloMutation } from 'vue-apollo';
import createFlash from '~/flash';
import { fetchPolicies } from '~/lib/graphql';
import allVersionsMixin from '../../mixins/all_versions';
import Toolbar from '../../components/toolbar/index.vue';
-import DesignDiscussion from '../../components/design_notes/design_discussion.vue';
-import DesignReplyForm from '../../components/design_notes/design_reply_form.vue';
import DesignDestroyer from '../../components/design_destroyer.vue';
import DesignScaler from '../../components/design_scaler.vue';
-import Participants from '~/sidebar/components/participants/participants.vue';
import DesignPresentation from '../../components/design_presentation.vue';
+import DesignReplyForm from '../../components/design_notes/design_reply_form.vue';
+import DesignSidebar from '../../components/design_sidebar.vue';
import getDesignQuery from '../../graphql/queries/getDesign.query.graphql';
import appDataQuery from '../../graphql/queries/appData.query.graphql';
import createImageDiffNoteMutation from '../../graphql/mutations/createImageDiffNote.mutation.graphql';
@@ -20,7 +19,6 @@ import updateActiveDiscussionMutation from '../../graphql/mutations/update_activ
import {
extractDiscussions,
extractDesign,
- extractParticipants,
updateImageDiffNoteOptimisticResponse,
} from '../../utils/design_management_utils';
import {
@@ -43,15 +41,14 @@ import { ACTIVE_DISCUSSION_SOURCE_TYPES } from '../../constants';
export default {
components: {
ApolloMutation,
+ DesignReplyForm,
DesignPresentation,
- DesignDiscussion,
DesignScaler,
DesignDestroyer,
Toolbar,
- DesignReplyForm,
GlLoadingIcon,
GlAlert,
- Participants,
+ DesignSidebar,
},
mixins: [allVersionsMixin],
props: {
@@ -69,6 +66,7 @@ export default {
errorMessage: '',
issueIid: '',
scale: 1,
+ resolvedDiscussionsExpanded: false,
};
},
apollo: {
@@ -103,20 +101,17 @@ export default {
return this.$apollo.queries.design.loading && !this.design.filename;
},
discussions() {
+ if (!this.design.discussions) {
+ return [];
+ }
return extractDiscussions(this.design.discussions);
},
- discussionParticipants() {
- return extractParticipants(this.design.issue.participants);
- },
markdownPreviewPath() {
return `/${this.projectPath}/preview_markdown?target_type=Issue`;
},
isSubmitButtonDisabled() {
return this.comment.trim().length === 0;
},
- renderDiscussions() {
- return this.discussions.length || this.annotationCoordinates;
- },
designVariables() {
return {
fullPath: this.projectPath,
@@ -144,18 +139,25 @@ export default {
},
};
},
- issue() {
- return {
- ...this.design.issue,
- webPath: this.design.issue.webPath.substr(1),
- };
- },
isAnnotating() {
return Boolean(this.annotationCoordinates);
},
+ resolvedDiscussions() {
+ return this.discussions.filter(discussion => discussion.resolved);
+ },
+ },
+ watch: {
+ resolvedDiscussions(val) {
+ if (!val.length) {
+ this.resolvedDiscussionsExpanded = false;
+ }
+ },
},
mounted() {
Mousetrap.bind('esc', this.closeDesign);
+ this.trackEvent();
+ // We need to reset the active discussion when opening a new design
+ this.updateActiveDiscussion();
},
beforeDestroy() {
Mousetrap.unbind('esc', this.closeDesign);
@@ -247,6 +249,9 @@ export default {
onDesignDeleteError(e) {
this.onError(designDeletionError({ singular: true }), e);
},
+ onResolveDiscussionError(e) {
+ this.onError(UPDATE_IMAGE_DIFF_NOTE_ERROR, e);
+ },
openCommentForm(annotationCoordinates) {
this.annotationCoordinates = annotationCoordinates;
},
@@ -278,23 +283,9 @@ export default {
},
});
},
- },
- beforeRouteEnter(to, from, next) {
- next(vm => {
- vm.trackEvent();
- });
- },
- beforeRouteUpdate(to, from, next) {
- this.trackEvent();
- this.closeCommentForm();
- // We need to reset the active discussion when opening a new design
- this.updateActiveDiscussion();
- next();
- },
- beforeRouteLeave(to, from, next) {
- // We need to reset the active discussion when moving to design list view
- this.updateActiveDiscussion();
- next();
+ toggleResolvedComments() {
+ this.resolvedDiscussionsExpanded = !this.resolvedDiscussionsExpanded;
+ },
},
createImageDiffNoteMutation,
DESIGNS_ROUTE_NAME,
@@ -337,6 +328,7 @@ export default {
:discussions="discussions"
:is-annotating="isAnnotating"
:scale="scale"
+ :resolved-discussions-expanded="resolvedDiscussionsExpanded"
@openCommentForm="openCommentForm"
@closeCommentForm="closeCommentForm"
@moveNote="onMoveNote"
@@ -346,33 +338,19 @@ export default {
<design-scaler @scale="scale = $event" />
</div>
</div>
- <div class="image-notes" @click="updateActiveDiscussion()">
- <h2 class="gl-font-size-20-deprecated-no-really-do-not-use-me font-weight-bold mt-0">
- {{ issue.title }}
- </h2>
- <a class="text-tertiary text-decoration-none mb-3 d-block" :href="issue.webUrl">{{
- issue.webPath
- }}</a>
- <participants
- :participants="discussionParticipants"
- :show-participant-label="false"
- class="mb-4"
- />
- <template v-if="renderDiscussions">
- <design-discussion
- v-for="(discussion, index) in discussions"
- :key="discussion.id"
- :discussion="discussion"
- :design-id="id"
- :noteable-id="design.id"
- :discussion-index="index + 1"
- :markdown-preview-path="markdownPreviewPath"
- @error="onDesignDiscussionError"
- @updateNoteError="onUpdateNoteError"
- @click.native.stop="updateActiveDiscussion(discussion.notes[0].id)"
- />
+ <design-sidebar
+ :design="design"
+ :resolved-discussions-expanded="resolvedDiscussionsExpanded"
+ :markdown-preview-path="markdownPreviewPath"
+ @onDesignDiscussionError="onDesignDiscussionError"
+ @onCreateImageDiffNoteError="onCreateImageDiffNoteError"
+ @updateNoteError="onUpdateNoteError"
+ @resolveDiscussionError="onResolveDiscussionError"
+ @toggleResolvedComments="toggleResolvedComments"
+ >
+ <template #replyForm>
<apollo-mutation
- v-if="annotationCoordinates"
+ v-if="isAnnotating"
#default="{ mutate, loading }"
:mutation="$options.createImageDiffNoteMutation"
:variables="{
@@ -388,13 +366,9 @@ export default {
:markdown-preview-path="markdownPreviewPath"
@submitForm="mutate"
@cancelForm="closeCommentForm"
- />
- </apollo-mutation>
- </template>
- <h2 v-else class="new-discussion-disclaimer gl-font-base m-0">
- {{ __("Click the image where you'd like to start a new discussion") }}
- </h2>
- </div>
+ /> </apollo-mutation
+ ></template>
+ </design-sidebar>
</template>
</div>
</template>
diff --git a/app/assets/javascripts/design_management/pages/index.vue b/app/assets/javascripts/design_management/pages/index.vue
index 7d419bc3ded..922c800009f 100644
--- a/app/assets/javascripts/design_management/pages/index.vue
+++ b/app/assets/javascripts/design_management/pages/index.vue
@@ -318,6 +318,6 @@ export default {
</li>
</ol>
</div>
- <router-view />
+ <router-view :key="$route.fullPath" />
</div>
</template>
diff --git a/app/assets/javascripts/design_management/router/index.js b/app/assets/javascripts/design_management/router/index.js
index 7dc92f55d47..7494da002c8 100644
--- a/app/assets/javascripts/design_management/router/index.js
+++ b/app/assets/javascripts/design_management/router/index.js
@@ -2,6 +2,9 @@ import $ from 'jquery';
import Vue from 'vue';
import VueRouter from 'vue-router';
import routes from './routes';
+import { DESIGN_ROUTE_NAME } from './constants';
+import { getPageLayoutElement } from '~/design_management/utils/design_management_utils';
+import { DESIGN_DETAIL_LAYOUT_CLASSLIST } from '../constants';
Vue.use(VueRouter);
@@ -11,10 +14,20 @@ export default function createRouter(base) {
mode: 'history',
routes,
});
+ const pageEl = getPageLayoutElement();
- router.beforeEach(({ meta: { el } }, from, next) => {
+ router.beforeEach(({ meta: { el }, name }, _, next) => {
$(`#${el}`).tab('show');
+ // apply a fullscreen layout style in Design View (a.k.a design detail)
+ if (pageEl) {
+ if (name === DESIGN_ROUTE_NAME) {
+ pageEl.classList.add(...DESIGN_DETAIL_LAYOUT_CLASSLIST);
+ } else {
+ pageEl.classList.remove(...DESIGN_DETAIL_LAYOUT_CLASSLIST);
+ }
+ }
+
next();
});
diff --git a/app/assets/javascripts/design_management/utils/cache_update.js b/app/assets/javascripts/design_management/utils/cache_update.js
index 01c073bddc2..24b374b79fd 100644
--- a/app/assets/javascripts/design_management/utils/cache_update.js
+++ b/app/assets/javascripts/design_management/utils/cache_update.js
@@ -95,6 +95,10 @@ const addImageDiffNoteToStore = (store, createImageDiffNote, query, variables) =
__typename: 'Discussion',
id: createImageDiffNote.note.discussion.id,
replyId: createImageDiffNote.note.discussion.replyId,
+ resolvable: true,
+ resolved: false,
+ resolvedAt: null,
+ resolvedBy: null,
notes: {
__typename: 'NoteConnection',
nodes: [createImageDiffNote.note],
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 e6d8796ffa4..22705cf67a1 100644
--- a/app/assets/javascripts/design_management/utils/design_management_utils.js
+++ b/app/assets/javascripts/design_management/utils/design_management_utils.js
@@ -21,8 +21,9 @@ export const extractNodes = elements => elements.edges.map(({ node }) => node);
*/
export const extractDiscussions = discussions =>
- discussions.nodes.map(discussion => ({
+ discussions.nodes.map((discussion, index) => ({
...discussion,
+ index: index + 1,
notes: discussion.notes.nodes,
}));
@@ -123,3 +124,5 @@ const normalizeAuthor = author => ({
});
export const extractParticipants = users => users.edges.map(({ node }) => normalizeAuthor(node));
+
+export const getPageLayoutElement = () => document.querySelector('.layout-page');
diff --git a/app/assets/javascripts/diff_notes/components/jump_to_discussion.js b/app/assets/javascripts/diff_notes/components/jump_to_discussion.js
index 0c521fa29bd..0991f5282a8 100644
--- a/app/assets/javascripts/diff_notes/components/jump_to_discussion.js
+++ b/app/assets/javascripts/diff_notes/components/jump_to_discussion.js
@@ -1,4 +1,4 @@
-/* eslint-disable func-names, guard-for-in, no-restricted-syntax, no-lonely-if, no-continue */
+/* eslint-disable func-names, no-continue */
/* global CommentsStore */
import $ from 'jquery';
@@ -42,13 +42,13 @@ const JumpToDiscussion = Vue.extend({
},
lastResolvedId() {
let lastId;
- for (const discussionId in this.discussions) {
+ Object.keys(this.discussions).forEach(discussionId => {
const discussion = this.discussions[discussionId];
if (!discussion.isResolved()) {
lastId = discussion.id;
}
- }
+ });
return lastId;
},
},
@@ -95,12 +95,10 @@ const JumpToDiscussion = Vue.extend({
if (unresolvedDiscussionCount === 1) {
hasDiscussionsToJumpTo = false;
}
- } else {
+ } else if (unresolvedDiscussionCount === 0) {
// If there are no unresolved discussions on the diffs tab at all,
// there are no discussions to jump to.
- if (unresolvedDiscussionCount === 0) {
- hasDiscussionsToJumpTo = false;
- }
+ hasDiscussionsToJumpTo = false;
}
} else if (activeTab !== 'show') {
// If we are on the commits or builds tabs,
diff --git a/app/assets/javascripts/diffs/components/commit_item.vue b/app/assets/javascripts/diffs/components/commit_item.vue
index ee93ca020e8..99bc1b5c040 100644
--- a/app/assets/javascripts/diffs/components/commit_item.vue
+++ b/app/assets/javascripts/diffs/components/commit_item.vue
@@ -144,7 +144,7 @@ export default {
<pre
v-if="commit.description_html"
- class="commit-row-description js-toggle-content append-bottom-8"
+ class="commit-row-description js-toggle-content gl-mb-3"
v-html="commit.description_html"
></pre>
</div>
diff --git a/app/assets/javascripts/diffs/components/compare_versions.vue b/app/assets/javascripts/diffs/components/compare_versions.vue
index c680c3f4600..6f6fa312865 100644
--- a/app/assets/javascripts/diffs/components/compare_versions.vue
+++ b/app/assets/javascripts/diffs/components/compare_versions.vue
@@ -86,7 +86,7 @@ export default {
<button
v-gl-tooltip.hover
type="button"
- class="btn btn-default append-right-8 js-toggle-tree-list"
+ class="btn btn-default gl-mr-3 js-toggle-tree-list"
:class="{
active: showTreeList,
}"
@@ -98,20 +98,20 @@ export default {
<gl-sprintf
v-if="showDropdowns"
class="d-flex align-items-center compare-versions-container"
- :message="s__('MergeRequest|Compare %{source} and %{target}')"
+ :message="s__('MergeRequest|Compare %{target} and %{source}')"
>
- <template #source>
- <compare-dropdown-layout
- :versions="diffCompareDropdownSourceVersions"
- class="mr-version-dropdown"
- />
- </template>
<template #target>
<compare-dropdown-layout
:versions="diffCompareDropdownTargetVersions"
class="mr-version-compare-dropdown"
/>
</template>
+ <template #source>
+ <compare-dropdown-layout
+ :versions="diffCompareDropdownSourceVersions"
+ class="mr-version-dropdown"
+ />
+ </template>
</gl-sprintf>
<div v-else-if="commit">
{{ __('Viewing commit') }}
@@ -126,15 +126,11 @@ export default {
<gl-deprecated-button
v-if="commit || startVersion"
:href="latestVersionPath"
- class="append-right-8 js-latest-version"
+ class="gl-mr-3 js-latest-version"
>
{{ __('Show latest version') }}
</gl-deprecated-button>
- <gl-deprecated-button
- v-show="hasCollapsedFile"
- class="append-right-8"
- @click="expandAllFiles"
- >
+ <gl-deprecated-button v-show="hasCollapsedFile" class="gl-mr-3" @click="expandAllFiles">
{{ __('Expand all') }}
</gl-deprecated-button>
<settings-dropdown />
diff --git a/app/assets/javascripts/diffs/components/diff_content.vue b/app/assets/javascripts/diffs/components/diff_content.vue
index 5656bfc4707..741462a849c 100644
--- a/app/assets/javascripts/diffs/components/diff_content.vue
+++ b/app/assets/javascripts/diffs/components/diff_content.vue
@@ -1,11 +1,12 @@
<script>
import { mapActions, mapGetters, mapState } from 'vuex';
import { GlLoadingIcon } from '@gitlab/ui';
-import diffLineNoteFormMixin from 'ee_else_ce/notes/mixins/diff_line_note_form';
-import draftCommentsMixin from 'ee_else_ce/diffs/mixins/draft_comments';
+import diffLineNoteFormMixin from '~/notes/mixins/diff_line_note_form';
+import draftCommentsMixin from '~/diffs/mixins/draft_comments';
import DiffViewer from '~/vue_shared/components/diff_viewer/diff_viewer.vue';
import NotDiffableViewer from '~/vue_shared/components/diff_viewer/viewers/not_diffable.vue';
import NoPreviewViewer from '~/vue_shared/components/diff_viewer/viewers/no_preview.vue';
+import DiffFileDrafts from '~/batch_comments/components/diff_file_drafts.vue';
import InlineDiffView from './inline_diff_view.vue';
import ParallelDiffView from './parallel_diff_view.vue';
import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue';
@@ -29,7 +30,7 @@ export default {
NotDiffableViewer,
NoPreviewViewer,
userAvatarLink,
- DiffFileDrafts: () => import('ee_component/batch_comments/components/diff_file_drafts.vue'),
+ DiffFileDrafts,
},
mixins: [diffLineNoteFormMixin, draftCommentsMixin],
props: {
@@ -128,6 +129,7 @@ export default {
<no-preview-viewer v-else-if="noPreview" />
<diff-viewer
v-else
+ :diff-file="diffFile"
:diff-mode="diffMode"
:diff-viewer-mode="diffViewerMode"
:new-path="diffFile.new_path"
diff --git a/app/assets/javascripts/diffs/components/diff_line_note_form.vue b/app/assets/javascripts/diffs/components/diff_line_note_form.vue
index f81f50f8490..74305ee69bc 100644
--- a/app/assets/javascripts/diffs/components/diff_line_note_form.vue
+++ b/app/assets/javascripts/diffs/components/diff_line_note_form.vue
@@ -1,18 +1,22 @@
<script>
import { mapState, mapGetters, mapActions } from 'vuex';
-import diffLineNoteFormMixin from 'ee_else_ce/notes/mixins/diff_line_note_form';
+import diffLineNoteFormMixin from '~/notes/mixins/diff_line_note_form';
+import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { s__ } from '~/locale';
import noteForm from '../../notes/components/note_form.vue';
+import MultilineCommentForm from '../../notes/components/multiline_comment_form.vue';
import autosave from '../../notes/mixins/autosave';
import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue';
import { DIFF_NOTE_TYPE } from '../constants';
+import { commentLineOptions } from '../../notes/components/multiline_comment_utils';
export default {
components: {
noteForm,
userAvatarLink,
+ MultilineCommentForm,
},
- mixins: [autosave, diffLineNoteFormMixin],
+ mixins: [autosave, diffLineNoteFormMixin, glFeatureFlagsMixin()],
props: {
diffFileHash: {
type: String,
@@ -37,6 +41,14 @@ export default {
default: '',
},
},
+ data() {
+ return {
+ commentLineStart: {
+ lineCode: this.line.line_code,
+ type: this.line.type,
+ },
+ };
+ },
computed: {
...mapState({
noteableData: state => state.notes.noteableData,
@@ -62,11 +74,20 @@ export default {
diffViewType: this.diffViewType,
diffFile: this.diffFile,
linePosition: this.linePosition,
+ lineRange: {
+ start_line_code: this.commentLineStart.lineCode,
+ start_line_type: this.commentLineStart.type,
+ end_line_code: this.line.line_code,
+ end_line_type: this.line.type,
+ },
};
},
diffFile() {
return this.getDiffFileByHash(this.diffFileHash);
},
+ commentLineOptions() {
+ return commentLineOptions(this.diffFile.highlighted_diff_lines, this.line.line_code);
+ },
},
mounted() {
if (this.isLoggedIn) {
@@ -83,7 +104,6 @@ export default {
methods: {
...mapActions('diffs', [
'cancelCommentForm',
- 'assignDiscussionsToDiff',
'saveDiffDiscussion',
'setSuggestPopoverDismissed',
]),
@@ -116,6 +136,16 @@ export default {
<template>
<div class="content discussion-form discussion-form-container discussion-notes">
+ <div
+ v-if="glFeatures.multilineComments"
+ class="gl-mb-3 gl-text-gray-700 gl-border-gray-200 gl-border-b-solid gl-border-b-1 gl-pb-3"
+ >
+ <multiline-comment-form
+ v-model="commentLineStart"
+ :line="line"
+ :comment-line-options="commentLineOptions"
+ />
+ </div>
<user-avatar-link
v-if="author"
:link-href="author.path"
@@ -133,7 +163,7 @@ export default {
:diff-file="diffFile"
:show-suggest-popover="showSuggestPopover"
save-button-title="Comment"
- class="diff-comment-form"
+ class="diff-comment-form prepend-top-10"
@handleFormUpdateAddToReview="addToReview"
@cancelForm="handleCancelCommentForm"
@handleFormUpdate="handleSaveNote"
diff --git a/app/assets/javascripts/diffs/components/inline_diff_view.vue b/app/assets/javascripts/diffs/components/inline_diff_view.vue
index 8b25cdc2887..ad72016f03b 100644
--- a/app/assets/javascripts/diffs/components/inline_diff_view.vue
+++ b/app/assets/javascripts/diffs/components/inline_diff_view.vue
@@ -1,6 +1,7 @@
<script>
import { mapGetters } from 'vuex';
-import draftCommentsMixin from 'ee_else_ce/diffs/mixins/draft_comments';
+import draftCommentsMixin from '~/diffs/mixins/draft_comments';
+import InlineDraftCommentRow from '~/batch_comments/components/inline_draft_comment_row.vue';
import inlineDiffTableRow from './inline_diff_table_row.vue';
import inlineDiffCommentRow from './inline_diff_comment_row.vue';
import inlineDiffExpansionRow from './inline_diff_expansion_row.vue';
@@ -9,8 +10,7 @@ export default {
components: {
inlineDiffCommentRow,
inlineDiffTableRow,
- InlineDraftCommentRow: () =>
- import('ee_component/batch_comments/components/inline_draft_comment_row.vue'),
+ InlineDraftCommentRow,
inlineDiffExpansionRow,
},
mixins: [draftCommentsMixin],
@@ -80,6 +80,8 @@ export default {
v-if="shouldRenderDraftRow(diffFile.file_hash, line)"
:key="`draft_${index}`"
:draft="draftForLine(diffFile.file_hash, line)"
+ :diff-file="diffFile"
+ :line="line"
/>
</template>
</tbody>
diff --git a/app/assets/javascripts/diffs/components/parallel_diff_view.vue b/app/assets/javascripts/diffs/components/parallel_diff_view.vue
index d796aad9d06..b5fcc50ce26 100644
--- a/app/assets/javascripts/diffs/components/parallel_diff_view.vue
+++ b/app/assets/javascripts/diffs/components/parallel_diff_view.vue
@@ -1,6 +1,7 @@
<script>
import { mapGetters } from 'vuex';
-import draftCommentsMixin from 'ee_else_ce/diffs/mixins/draft_comments';
+import draftCommentsMixin from '~/diffs/mixins/draft_comments';
+import ParallelDraftCommentRow from '~/batch_comments/components/parallel_draft_comment_row.vue';
import parallelDiffTableRow from './parallel_diff_table_row.vue';
import parallelDiffCommentRow from './parallel_diff_comment_row.vue';
import parallelDiffExpansionRow from './parallel_diff_expansion_row.vue';
@@ -10,8 +11,7 @@ export default {
parallelDiffExpansionRow,
parallelDiffTableRow,
parallelDiffCommentRow,
- ParallelDraftCommentRow: () =>
- import('ee_component/batch_comments/components/parallel_draft_comment_row.vue'),
+ ParallelDraftCommentRow,
},
mixins: [draftCommentsMixin],
props: {
diff --git a/app/assets/javascripts/diffs/components/tree_list.vue b/app/assets/javascripts/diffs/components/tree_list.vue
index eca9091f92f..52611f3c82a 100644
--- a/app/assets/javascripts/diffs/components/tree_list.vue
+++ b/app/assets/javascripts/diffs/components/tree_list.vue
@@ -64,7 +64,7 @@ export default {
<template>
<div class="tree-list-holder d-flex flex-column">
- <div class="append-bottom-8 position-relative tree-list-search d-flex">
+ <div class="gl-mb-3 position-relative tree-list-search d-flex">
<div class="flex-fill d-flex">
<icon name="search" class="position-absolute tree-list-icon" />
<label for="diff-tree-search" class="sr-only">{{ $options.searchPlaceholder }}</label>
diff --git a/app/assets/javascripts/diffs/constants.js b/app/assets/javascripts/diffs/constants.js
index 40e1aec42ed..9269dacd582 100644
--- a/app/assets/javascripts/diffs/constants.js
+++ b/app/assets/javascripts/diffs/constants.js
@@ -61,3 +61,22 @@ export const DIFFS_PER_PAGE = 20;
export const DIFF_COMPARE_BASE_VERSION_INDEX = -1;
export const DIFF_COMPARE_HEAD_VERSION_INDEX = -2;
+
+// State machine states
+export const STATE_IDLING = 'idle';
+export const STATE_LOADING = 'loading';
+export const STATE_ERRORED = 'errored';
+
+// State machine transitions
+export const TRANSITION_LOAD_START = 'LOAD_START';
+export const TRANSITION_LOAD_ERROR = 'LOAD_ERROR';
+export const TRANSITION_LOAD_SUCCEED = 'LOAD_SUCCEED';
+export const TRANSITION_ACKNOWLEDGE_ERROR = 'ACKNOWLEDGE_ERROR';
+
+export const RENAMED_DIFF_TRANSITIONS = {
+ [`${STATE_IDLING}:${TRANSITION_LOAD_START}`]: STATE_LOADING,
+ [`${STATE_LOADING}:${TRANSITION_LOAD_ERROR}`]: STATE_ERRORED,
+ [`${STATE_LOADING}:${TRANSITION_LOAD_SUCCEED}`]: STATE_IDLING,
+ [`${STATE_ERRORED}:${TRANSITION_LOAD_START}`]: STATE_LOADING,
+ [`${STATE_ERRORED}:${TRANSITION_ACKNOWLEDGE_ERROR}`]: STATE_IDLING,
+};
diff --git a/app/assets/javascripts/diffs/mixins/draft_comments.js b/app/assets/javascripts/diffs/mixins/draft_comments.js
index b6c9b132aeb..693b4a84694 100644
--- a/app/assets/javascripts/diffs/mixins/draft_comments.js
+++ b/app/assets/javascripts/diffs/mixins/draft_comments.js
@@ -1,12 +1,17 @@
+import { mapGetters } from 'vuex';
+
export default {
computed: {
- shouldRenderDraftRow: () => () => false,
- shouldRenderParallelDraftRow: () => () => false,
- draftForLine: () => () => ({}),
+ ...mapGetters('batchComments', [
+ 'shouldRenderDraftRow',
+ 'shouldRenderParallelDraftRow',
+ 'draftForLine',
+ 'draftsForFile',
+ 'hasParallelDraftLeft',
+ 'hasParallelDraftRight',
+ ]),
imageDiscussions() {
- return this.diffFile.discussions;
+ return this.diffFile.discussions.concat(this.draftsForFile(this.diffFile.file_hash));
},
- hasParallelDraftLeft: () => () => false,
- hasParallelDraftRight: () => () => false,
},
};
diff --git a/app/assets/javascripts/diffs/store/actions.js b/app/assets/javascripts/diffs/store/actions.js
index 1975d6996a5..a8d348e1836 100644
--- a/app/assets/javascripts/diffs/store/actions.js
+++ b/app/assets/javascripts/diffs/store/actions.js
@@ -118,12 +118,7 @@ export const fetchDiffFilesBatch = ({ commit, state }) => {
const getBatch = (page = 1) =>
axios
- .get(state.endpointBatch, {
- params: {
- ...urlParams,
- page,
- },
- })
+ .get(mergeUrlParams({ ...urlParams, page }, state.endpointBatch))
.then(({ data: { pagination, diff_files } }) => {
commit(types.SET_DIFF_DATA_BATCH, { diff_files });
commit(types.SET_BATCH_LOADING, false);
@@ -507,9 +502,6 @@ export const cacheTreeListWidth = (_, size) => {
localStorage.setItem(TREE_LIST_WIDTH_STORAGE_KEY, size);
};
-export const requestFullDiff = ({ commit }, filePath) => commit(types.REQUEST_FULL_DIFF, filePath);
-export const receiveFullDiffSucess = ({ commit }, { filePath }) =>
- commit(types.RECEIVE_FULL_DIFF_SUCCESS, { filePath });
export const receiveFullDiffError = ({ commit }, filePath) => {
commit(types.RECEIVE_FULL_DIFF_ERROR, filePath);
createFlash(s__('MergeRequest|Error loading full diff. Please try again.'));
@@ -600,7 +592,7 @@ export const setExpandedDiffLines = ({ commit, state }, { file, data }) => {
}
};
-export const fetchFullDiff = ({ dispatch }, file) =>
+export const fetchFullDiff = ({ commit, dispatch }, file) =>
axios
.get(file.context_lines_path, {
params: {
@@ -609,15 +601,16 @@ export const fetchFullDiff = ({ dispatch }, file) =>
},
})
.then(({ data }) => {
- dispatch('receiveFullDiffSucess', { filePath: file.file_path });
+ commit(types.RECEIVE_FULL_DIFF_SUCCESS, { filePath: file.file_path });
+
dispatch('setExpandedDiffLines', { file, data });
})
.catch(() => dispatch('receiveFullDiffError', file.file_path));
-export const toggleFullDiff = ({ dispatch, getters, state }, filePath) => {
+export const toggleFullDiff = ({ dispatch, commit, getters, state }, filePath) => {
const file = state.diffFiles.find(f => f.file_path === filePath);
- dispatch('requestFullDiff', filePath);
+ commit(types.REQUEST_FULL_DIFF, filePath);
if (file.isShowingFullFile) {
dispatch('loadCollapsedDiff', file)
@@ -656,11 +649,6 @@ export function switchToFullDiffFromRenamedFile({ commit, dispatch, state }, { d
commit(types.SET_CURRENT_VIEW_DIFF_FILE_LINES, { filePath: diffFile.file_path, lines });
dispatch('startRenderDiffsQueue');
- })
- .catch(error => {
- dispatch('receiveFullDiffError', diffFile.file_path);
-
- throw error;
});
}
diff --git a/app/assets/javascripts/diffs/store/utils.js b/app/assets/javascripts/diffs/store/utils.js
index 2be71c77087..d261be1b550 100644
--- a/app/assets/javascripts/diffs/store/utils.js
+++ b/app/assets/javascripts/diffs/store/utils.js
@@ -40,6 +40,7 @@ export function getFormData(params) {
diffViewType,
linePosition,
positionType,
+ lineRange,
} = params;
const position = JSON.stringify({
@@ -55,6 +56,7 @@ export function getFormData(params) {
y: params.y,
width: params.width,
height: params.height,
+ line_range: lineRange,
});
const postData = {
diff --git a/app/assets/javascripts/diffs/utils/uuids.js b/app/assets/javascripts/diffs/utils/uuids.js
new file mode 100644
index 00000000000..1a529c07ccc
--- /dev/null
+++ b/app/assets/javascripts/diffs/utils/uuids.js
@@ -0,0 +1,79 @@
+/**
+ * @module uuids
+ */
+
+/**
+ * A string or number representing a start state for a random generator
+ * @typedef {(Number|String)} Seed
+ */
+/**
+ * A UUIDv4 string in the format <code>Hex{8}-Hex{4}-4Hex{3}-[89ab]Hex{3}-Hex{12}</code>
+ * @typedef {String} UUIDv4
+ */
+
+// https://gitlab.com/gitlab-org/frontend/rfcs/-/issues/20
+/* eslint-disable import/prefer-default-export */
+
+import MersenneTwister from 'mersenne-twister';
+import stringHash from 'string-hash';
+import { isString } from 'lodash';
+import { v4 } from 'uuid';
+
+function getSeed(seeds) {
+ return seeds.reduce((seedling, seed, i) => {
+ let thisSeed = 0;
+
+ if (Number.isInteger(seed)) {
+ thisSeed = seed;
+ } else if (isString(seed)) {
+ thisSeed = stringHash(seed);
+ }
+
+ return seedling + (seeds.length - i) * thisSeed;
+ }, 0);
+}
+
+function getPseudoRandomNumberGenerator(...seeds) {
+ let seedNumber;
+
+ if (seeds.length) {
+ seedNumber = getSeed(seeds);
+ } else {
+ seedNumber = Math.floor(Math.random() * 10 ** 15);
+ }
+
+ return new MersenneTwister(seedNumber);
+}
+
+function randomValuesForUuid(prng) {
+ const randomValues = [];
+
+ for (let i = 0; i <= 3; i += 1) {
+ const buffer = new ArrayBuffer(4);
+ const view = new DataView(buffer);
+
+ view.setUint32(0, prng.random_int());
+
+ randomValues.push(view.getUint8(0), view.getUint8(1), view.getUint8(2), view.getUint8(3));
+ }
+
+ return randomValues;
+}
+
+/**
+ * Get an array of UUIDv4s
+ * @param {Object} [options={}]
+ * @param {Seed[]} [options.seeds=[]] - A list of mixed strings or numbers to seed the UUIDv4 generator
+ * @param {Number} [options.count=1] - A total number of UUIDv4s to generate
+ * @returns {UUIDv4[]} An array of UUIDv4s
+ */
+export function uuids({ seeds = [], count = 1 } = {}) {
+ const rng = getPseudoRandomNumberGenerator(...seeds);
+ return (
+ // Create an array the same size as the number of UUIDs requested
+ Array(count)
+ .fill(0)
+ // Replace each slot in the array with a UUID which needs 16 (pseudo)random values to generate
+ .map(() => v4({ random: randomValuesForUuid(rng) }))
+ );
+}
diff --git a/app/assets/javascripts/environments/components/environments_app.vue b/app/assets/javascripts/environments/components/environments_app.vue
index 0a5538237f9..b8bcca814cd 100644
--- a/app/assets/javascripts/environments/components/environments_app.vue
+++ b/app/assets/javascripts/environments/components/environments_app.vue
@@ -158,13 +158,13 @@ export default {
:deploy-boards-help-path="deployBoardsHelpPath"
@onChangePage="onChangePage"
>
- <empty-state
- v-if="!isLoading && state.environments.length === 0"
- slot="emptyState"
- :new-path="newEnvironmentPath"
- :help-path="helpPagePath"
- :can-create-environment="canCreateEnvironment"
- />
+ <template v-if="!isLoading && state.environments.length === 0" #emptyState>
+ <empty-state
+ :new-path="newEnvironmentPath"
+ :help-path="helpPagePath"
+ :can-create-environment="canCreateEnvironment"
+ />
+ </template>
</container>
</div>
</template>
diff --git a/app/assets/javascripts/error_tracking/components/constants.js b/app/assets/javascripts/error_tracking/components/constants.js
index 60b217443de..41b952e26d8 100644
--- a/app/assets/javascripts/error_tracking/components/constants.js
+++ b/app/assets/javascripts/error_tracking/components/constants.js
@@ -8,10 +8,10 @@ export const severityLevel = {
export const severityLevelVariant = {
[severityLevel.FATAL]: 'danger',
- [severityLevel.ERROR]: 'dark',
+ [severityLevel.ERROR]: 'neutral',
[severityLevel.WARNING]: 'warning',
[severityLevel.INFO]: 'info',
- [severityLevel.DEBUG]: 'light',
+ [severityLevel.DEBUG]: 'muted',
};
export const errorStatus = {
diff --git a/app/assets/javascripts/error_tracking/components/error_details.vue b/app/assets/javascripts/error_tracking/components/error_details.vue
index 148edfe3a51..1e8f5a26125 100644
--- a/app/assets/javascripts/error_tracking/components/error_details.vue
+++ b/app/assets/javascripts/error_tracking/components/error_details.vue
@@ -1,6 +1,5 @@
<script>
import { mapActions, mapGetters, mapState } from 'vuex';
-import dateFormat from 'dateformat';
import createFlash from '~/flash';
import {
GlDeprecatedButton,
@@ -19,9 +18,14 @@ import Icon from '~/vue_shared/components/icon.vue';
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue';
import Stacktrace from './stacktrace.vue';
import TrackEventDirective from '~/vue_shared/directives/track_event';
-import timeagoMixin from '~/vue_shared/mixins/timeago';
-import { trackClickErrorLinkToSentryOptions } from '../utils';
+import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import { severityLevel, severityLevelVariant, errorStatus } from './constants';
+import Tracking from '~/tracking';
+import {
+ trackClickErrorLinkToSentryOptions,
+ trackErrorDetailsViewsOptions,
+ trackErrorStatusUpdateOptions,
+} from '../utils';
import query from '../queries/details.query.graphql';
@@ -42,11 +46,11 @@ export default {
GlDropdown,
GlDropdownItem,
GlDropdownDivider,
+ TimeAgoTooltip,
},
directives: {
TrackEvent: TrackEventDirective,
},
- mixins: [timeagoMixin],
props: {
issueUpdatePath: {
type: String,
@@ -172,6 +176,7 @@ export default {
},
},
mounted() {
+ this.trackPageViews();
this.startPollingStacktrace(this.issueStackTracePath);
this.errorPollTimeout = Date.now() + SENTRY_TIMEOUT;
this.$apollo.queries.error.setOptions({
@@ -194,7 +199,10 @@ export default {
onIgnoreStatusUpdate() {
const status =
this.errorStatus === errorStatus.IGNORED ? errorStatus.UNRESOLVED : errorStatus.IGNORED;
- this.updateIgnoreStatus({ endpoint: this.issueUpdatePath, status });
+ // eslint-disable-next-line promise/catch-or-return
+ this.updateIgnoreStatus({ endpoint: this.issueUpdatePath, status }).then(() => {
+ this.trackStatusUpdate(status);
+ });
},
onResolveStatusUpdate() {
const status =
@@ -206,6 +214,7 @@ export default {
if (this.closedIssueId) {
this.isAlertVisible = true;
}
+ this.trackStatusUpdate(status);
});
},
onNoApolloResult() {
@@ -215,8 +224,13 @@ export default {
createFlash(__('Could not connect to Sentry. Refresh the page to try again.'), 'warning');
}
},
- formatDate(date) {
- return `${this.timeFormatted(date)} (${dateFormat(date, 'UTC:yyyy-mm-dd h:MM:ssTT Z')})`;
+ trackPageViews() {
+ const { category, action } = trackErrorDetailsViewsOptions;
+ Tracking.event(category, action);
+ },
+ trackStatusUpdate(status) {
+ const { category, action } = trackErrorStatusUpdateOptions(status);
+ Tracking.event(category, action);
},
},
};
@@ -251,7 +265,7 @@ export default {
<strong class="error-details-meta-culprit">{{ error.culprit }}</strong>
</template>
<template #timeAgo>
- {{ timeFormatted(stacktraceData.date_received) }}
+ <time-ago-tooltip :time="stacktraceData.date_received" />
</template>
</gl-sprintf>
</div>
@@ -259,7 +273,7 @@ export default {
<div class="d-inline-flex bv-d-sm-down-none">
<gl-deprecated-button
:loading="updatingIgnoreStatus"
- data-qa-selector="update_ignore_status_button"
+ data-testid="update-ignore-status-btn"
@click="onIgnoreStatusUpdate"
>
{{ ignoreBtnLabel }}
@@ -267,7 +281,7 @@ export default {
<gl-deprecated-button
class="btn-outline-info ml-2"
:loading="updatingResolveStatus"
- data-qa-selector="update_resolve_status_button"
+ data-testid="update-resolve-status-btn"
@click="onResolveStatusUpdate"
>
{{ resolveBtnLabel }}
@@ -275,7 +289,7 @@ export default {
<gl-deprecated-button
v-if="error.gitlabIssuePath"
class="ml-2"
- data-qa-selector="view_issue_button"
+ data-testid="view_issue_button"
:href="error.gitlabIssuePath"
variant="success"
>
@@ -345,16 +359,10 @@ export default {
<h2 class="text-truncate">{{ error.title }}</h2>
</tooltip-on-truncate>
<template v-if="error.tags">
- <gl-badge
- v-if="error.tags.level"
- :variant="errorSeverityVariant"
- class="rounded-pill mr-2"
- >
+ <gl-badge v-if="error.tags.level" :variant="errorSeverityVariant" class="mr-2">
{{ errorLevel }}
</gl-badge>
- <gl-badge v-if="error.tags.logger" variant="light" class="rounded-pill"
- >{{ error.tags.logger }}
- </gl-badge>
+ <gl-badge v-if="error.tags.logger" variant="muted">{{ error.tags.logger }} </gl-badge>
</template>
<ul>
<li v-if="error.gitlabCommit">
@@ -375,6 +383,7 @@ export default {
v-track-event="trackClickErrorLinkToSentryOptions(error.externalUrl)"
:href="error.externalUrl"
target="_blank"
+ data-testid="external-url-link"
>
<span class="text-truncate">{{ error.externalUrl }}</span>
<icon name="external-link" class="ml-1 flex-shrink-0" />
@@ -382,14 +391,14 @@ export default {
</li>
<li v-if="error.firstReleaseShortVersion">
<strong class="bold">{{ __('First seen') }}:</strong>
- {{ formatDate(error.firstSeen) }}
+ <time-ago-tooltip :time="error.firstSeen" />
<gl-link :href="firstReleaseLink" target="_blank">
<span>{{ __('Release') }}: {{ error.firstReleaseShortVersion.substr(0, 10) }}</span>
</gl-link>
</li>
<li v-if="error.lastReleaseShortVersion">
<strong class="bold">{{ __('Last seen') }}:</strong>
- {{ formatDate(error.lastSeen) }}
+ <time-ago-tooltip :time="error.lastSeen" />
<gl-link :href="lastReleaseLink" target="_blank">
<span>{{ __('Release') }}: {{ error.lastReleaseShortVersion.substr(0, 10) }}</span>
</gl-link>
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 45432e8ebd8..62a73e21096 100644
--- a/app/assets/javascripts/error_tracking/components/error_tracking_list.vue
+++ b/app/assets/javascripts/error_tracking/components/error_tracking_list.vue
@@ -19,6 +19,8 @@ import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import { __ } from '~/locale';
import { isEmpty } from 'lodash';
import ErrorTrackingActions from './error_tracking_actions.vue';
+import Tracking from '~/tracking';
+import { trackErrorListViewsOptions, trackErrorStatusUpdateOptions } from '../utils';
export const tableDataClass = 'table-col d-flex d-md-table-cell align-items-center';
@@ -150,6 +152,9 @@ export default {
this.startPolling();
}
},
+ mounted() {
+ this.trackPageViews();
+ },
methods: {
...mapActions('list', [
'startPolling',
@@ -197,13 +202,25 @@ export default {
this.filterValue = label;
return this.filterByStatus(status);
},
- updateIssueStatus({ errorId, status }) {
+ updateErrosStatus({ errorId, status }) {
+ // eslint-disable-next-line promise/catch-or-return
this.updateStatus({
endpoint: this.getIssueUpdatePath(errorId),
status,
+ }).then(() => {
+ this.trackStatusUpdate(status);
});
+
this.removeIgnoredResolvedErrors(errorId);
},
+ trackPageViews() {
+ const { category, action } = trackErrorListViewsOptions;
+ Tracking.event(category, action);
+ },
+ trackStatusUpdate(status) {
+ const { category, action } = trackErrorStatusUpdateOptions(status);
+ Tracking.event(category, action);
+ },
},
};
</script>
@@ -359,7 +376,7 @@ export default {
</div>
</template>
<template #cell(status)="errors">
- <error-tracking-actions :error="errors.item" @update-issue-status="updateIssueStatus" />
+ <error-tracking-actions :error="errors.item" @update-issue-status="updateErrosStatus" />
</template>
<template #empty>
{{ __('No errors to display.') }}
diff --git a/app/assets/javascripts/error_tracking/store/list/actions.js b/app/assets/javascripts/error_tracking/store/list/actions.js
index 4170c1bf759..94cf444d2e4 100644
--- a/app/assets/javascripts/error_tracking/store/list/actions.js
+++ b/app/assets/javascripts/error_tracking/store/list/actions.js
@@ -2,7 +2,7 @@ import Service from '../../services';
import * as types from './mutation_types';
import createFlash from '~/flash';
import Poll from '~/lib/utils/poll';
-import { __, sprintf } from '~/locale';
+import { __ } from '~/locale';
let eTagPoll;
@@ -31,17 +31,9 @@ export function startPolling({ state, commit, dispatch }) {
commit(types.SET_LOADING, false);
dispatch('stopPolling');
},
- errorCallback: ({ response }) => {
- let errorMessage = '';
- if (response && response.data && response.data.message) {
- errorMessage = response.data.message;
- }
+ errorCallback: () => {
commit(types.SET_LOADING, false);
- createFlash(
- sprintf(__(`Failed to load errors from Sentry. Error message: %{errorMessage}`), {
- errorMessage,
- }),
- );
+ createFlash(__('Failed to load errors from Sentry.'));
},
});
diff --git a/app/assets/javascripts/error_tracking/utils.js b/app/assets/javascripts/error_tracking/utils.js
index d1cd70a72fa..5b705cc5510 100644
--- a/app/assets/javascripts/error_tracking/utils.js
+++ b/app/assets/javascripts/error_tracking/utils.js
@@ -1,4 +1,4 @@
-/* eslint-disable @gitlab/require-i18n-strings, import/prefer-default-export */
+/* eslint-disable @gitlab/require-i18n-strings */
/**
* Tracks snowplow event when User clicks on error link to Sentry
@@ -10,3 +10,27 @@ export const trackClickErrorLinkToSentryOptions = url => ({
label: 'Error Link',
property: url,
});
+
+/**
+ * Tracks snowplow event when user views error list
+ */
+export const trackErrorListViewsOptions = {
+ category: 'Error Tracking',
+ action: 'view_errors_list',
+};
+
+/**
+ * Tracks snowplow event when user views error details
+ */
+export const trackErrorDetailsViewsOptions = {
+ category: 'Error Tracking',
+ action: 'view_error_details',
+};
+
+/**
+ * Tracks snowplow event when error status is updated
+ */
+export const trackErrorStatusUpdateOptions = status => ({
+ category: 'Error Tracking',
+ action: `update_${status}_status`,
+});
diff --git a/app/assets/javascripts/file_pickers.js b/app/assets/javascripts/file_pickers.js
new file mode 100644
index 00000000000..956a4954afb
--- /dev/null
+++ b/app/assets/javascripts/file_pickers.js
@@ -0,0 +1,21 @@
+export default function initFilePickers() {
+ const filePickers = document.querySelectorAll('.js-filepicker');
+
+ filePickers.forEach(filePicker => {
+ const button = filePicker.querySelector('.js-filepicker-button');
+
+ button.addEventListener('click', () => {
+ const form = button.closest('form');
+ form.querySelector('.js-filepicker-input').click();
+ });
+
+ const input = filePicker.querySelector('.js-filepicker-input');
+
+ input.addEventListener('change', () => {
+ const form = input.closest('form');
+ const filename = input.value.replace(/^.*[\\\/]/, ''); // eslint-disable-line no-useless-escape
+
+ form.querySelector('.js-filepicker-filename').textContent = filename;
+ });
+ });
+}
diff --git a/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js b/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js
index d41d5a543b0..5298e20557d 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js
+++ b/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js
@@ -95,7 +95,7 @@ export default class FilteredSearchVisualTokens {
const tokenType = tokenName.toLowerCase();
const tokenValueContainer = parentElement.querySelector('.value-container');
const tokenValueElement = tokenValueContainer.querySelector('.value');
- tokenValueElement.innerText = tokenValue;
+ tokenValueElement.textContent = tokenValue;
const visualTokenValue = new VisualTokenValue(tokenValue, tokenType, tokenOperator);
@@ -140,9 +140,9 @@ export default class FilteredSearchVisualTokens {
li.innerHTML = nameHTML + operatorHTML;
}
- li.querySelector('.name').innerText = name;
+ li.querySelector('.name').textContent = name;
if (hasOperator) {
- li.querySelector('.operator').innerText = operator;
+ li.querySelector('.operator').textContent = operator;
}
const tokensContainer = FilteredSearchContainer.container.querySelector('.tokens-container');
@@ -162,8 +162,8 @@ export default class FilteredSearchVisualTokens {
lastVisualToken.innerHTML = FilteredSearchVisualTokens.createVisualTokenElementHTML({
hasOperator: Boolean(operator),
});
- lastVisualToken.querySelector('.name').innerText = name;
- lastVisualToken.querySelector('.operator').innerText = operator;
+ lastVisualToken.querySelector('.name').textContent = name;
+ lastVisualToken.querySelector('.operator').textContent = operator;
FilteredSearchVisualTokens.renderVisualTokenValue(lastVisualToken, name, value, operator);
}
}
@@ -208,8 +208,8 @@ export default class FilteredSearchVisualTokens {
},
});
} else {
- const previousTokenName = lastVisualToken.querySelector('.name').innerText;
- const previousTokenOperator = lastVisualToken.querySelector('.operator').innerText;
+ const previousTokenName = lastVisualToken.querySelector('.name').textContent;
+ const previousTokenOperator = lastVisualToken.querySelector('.operator').textContent;
const tokensContainer = FilteredSearchContainer.container.querySelector('.tokens-container');
tokensContainer.removeChild(lastVisualToken);
@@ -234,7 +234,7 @@ export default class FilteredSearchVisualTokens {
const { lastVisualToken } = FilteredSearchVisualTokens.getLastVisualTokenBeforeInput();
if (lastVisualToken && lastVisualToken.classList.contains('filtered-search-term')) {
- lastVisualToken.querySelector('.name').innerText += ` ${searchTerm}`;
+ lastVisualToken.querySelector('.name').textContent += ` ${searchTerm}`;
} else {
FilteredSearchVisualTokens.addVisualTokenElement({
name: searchTerm,
@@ -261,12 +261,12 @@ export default class FilteredSearchVisualTokens {
const value = lastVisualToken.querySelector('.value');
const name = lastVisualToken.querySelector('.name');
- const valueText = value ? value.innerText : '';
- const nameText = name ? name.innerText : '';
+ const valueText = value ? value.textContent : '';
+ const nameText = name ? name.textContent : '';
if (includeOperator) {
const operator = lastVisualToken.querySelector('.operator');
- const operatorText = operator ? operator.innerText : '';
+ const operatorText = operator ? operator.textContent : '';
return valueText || operatorText || nameText;
}
@@ -278,7 +278,7 @@ export default class FilteredSearchVisualTokens {
const operator = lastVisualToken && lastVisualToken.querySelector('.operator');
- return operator?.innerText;
+ return operator?.textContent;
}
static removeLastTokenPartial() {
@@ -346,8 +346,8 @@ export default class FilteredSearchVisualTokens {
if (token.classList.contains('filtered-search-token')) {
FilteredSearchVisualTokens.addFilterVisualToken(
- nameElement.innerText,
- operatorElement.innerText,
+ nameElement.textContent,
+ operatorElement.textContent,
null,
{
uppercaseTokenName: nameElement.classList.contains('text-uppercase'),
@@ -359,13 +359,13 @@ export default class FilteredSearchVisualTokens {
if (!value) {
const valueElement = valueContainerElement.querySelector('.value');
- value = valueElement.innerText;
+ value = valueElement.textContent;
}
}
// token is a search term
if (!value) {
- value = nameElement.innerText;
+ value = nameElement.textContent;
}
input.value = value;
diff --git a/app/assets/javascripts/filtered_search/services/recent_searches_service_error.js b/app/assets/javascripts/filtered_search/services/recent_searches_service_error.js
index 011b37e218d..d8c2c6d79c6 100644
--- a/app/assets/javascripts/filtered_search/services/recent_searches_service_error.js
+++ b/app/assets/javascripts/filtered_search/services/recent_searches_service_error.js
@@ -1,13 +1,10 @@
import { __ } from '~/locale';
-class RecentSearchesServiceError {
+class RecentSearchesServiceError extends Error {
constructor(message) {
+ super(message || __('Recent Searches Service is unavailable'));
this.name = 'RecentSearchesServiceError';
- this.message = message || __('Recent Searches Service is unavailable');
}
}
-// Can't use `extends` for builtin prototypes and get true inheritance yet
-RecentSearchesServiceError.prototype = Error.prototype;
-
export default RecentSearchesServiceError;
diff --git a/app/assets/javascripts/frequent_items/index.js b/app/assets/javascripts/frequent_items/index.js
index 6263acbab8e..c074f173776 100644
--- a/app/assets/javascripts/frequent_items/index.js
+++ b/app/assets/javascripts/frequent_items/index.js
@@ -1,8 +1,7 @@
import $ from 'jquery';
import Vue from 'vue';
import Translate from '~/vue_shared/translate';
-import eventHub from '~/frequent_items/event_hub';
-import frequentItems from './components/app.vue';
+import eventHub from './event_hub';
Vue.use(Translate);
@@ -17,7 +16,7 @@ const frequentItemDropdowns = [
},
];
-const initFrequentItemDropdowns = () => {
+export default function initFrequentItemDropdowns() {
frequentItemDropdowns.forEach(dropdown => {
const { namespace, key } = dropdown;
const el = document.getElementById(`js-${namespace}-dropdown`);
@@ -29,45 +28,40 @@ const initFrequentItemDropdowns = () => {
return;
}
- $(navEl).on('shown.bs.dropdown', () => {
- eventHub.$emit(`${namespace}-dropdownOpen`);
- });
+ $(navEl).on('shown.bs.dropdown', () =>
+ import('./components/app.vue').then(({ default: FrequentItems }) => {
+ // eslint-disable-next-line no-new
+ new Vue({
+ el,
+ data() {
+ const { dataset } = this.$options.el;
+ const item = {
+ id: Number(dataset[`${key}Id`]),
+ name: dataset[`${key}Name`],
+ namespace: dataset[`${key}Namespace`],
+ webUrl: dataset[`${key}WebUrl`],
+ avatarUrl: dataset[`${key}AvatarUrl`] || null,
+ lastAccessedOn: Date.now(),
+ };
- // eslint-disable-next-line no-new
- new Vue({
- el,
- components: {
- frequentItems,
- },
- data() {
- const { dataset } = this.$options.el;
- const item = {
- id: Number(dataset[`${key}Id`]),
- name: dataset[`${key}Name`],
- namespace: dataset[`${key}Namespace`],
- webUrl: dataset[`${key}WebUrl`],
- avatarUrl: dataset[`${key}AvatarUrl`] || null,
- lastAccessedOn: Date.now(),
- };
-
- return {
- currentUserName: dataset.userName,
- currentItem: item,
- };
- },
- render(createElement) {
- return createElement('frequent-items', {
- props: {
- namespace,
- currentUserName: this.currentUserName,
- currentItem: this.currentItem,
+ return {
+ currentUserName: dataset.userName,
+ currentItem: item,
+ };
+ },
+ render(createElement) {
+ return createElement(FrequentItems, {
+ props: {
+ namespace,
+ currentUserName: this.currentUserName,
+ currentItem: this.currentItem,
+ },
+ });
},
});
- },
- });
- });
-};
-document.addEventListener('DOMContentLoaded', () => {
- requestIdleCallback(initFrequentItemDropdowns);
-});
+ eventHub.$emit(`${namespace}-dropdownOpen`);
+ }),
+ );
+ });
+}
diff --git a/app/assets/javascripts/gl_dropdown.js b/app/assets/javascripts/gl_dropdown.js
index be4b4b5f87d..ec0d0cf6aef 100644
--- a/app/assets/javascripts/gl_dropdown.js
+++ b/app/assets/javascripts/gl_dropdown.js
@@ -4,7 +4,7 @@ import $ from 'jquery';
import { escape } from 'lodash';
import fuzzaldrinPlus from 'fuzzaldrin-plus';
import axios from './lib/utils/axios_utils';
-import { visitUrl } from './lib/utils/url_utility';
+import { visitUrl } from '~/lib/utils/url_utility';
import { isObject } from './lib/utils/type_utility';
import renderItem from './gl_dropdown/render';
diff --git a/app/assets/javascripts/global_search_input.js b/app/assets/javascripts/global_search_input.js
new file mode 100644
index 00000000000..a7c121259d4
--- /dev/null
+++ b/app/assets/javascripts/global_search_input.js
@@ -0,0 +1,425 @@
+/* eslint-disable no-return-assign, consistent-return, class-methods-use-this */
+
+import $ from 'jquery';
+import { throttle } from 'lodash';
+import { s__, __, sprintf } from '~/locale';
+import {
+ isInGroupsPage,
+ isInProjectPage,
+ getGroupSlug,
+ getProjectSlug,
+ spriteIcon,
+} from './lib/utils/common_utils';
+
+/**
+ * Search input in top navigation bar.
+ * On click, opens a dropdown
+ * As the user types it filters the results
+ * When the user clicks `x` button it cleans the input and closes the dropdown.
+ */
+
+const KEYCODE = {
+ ESCAPE: 27,
+ BACKSPACE: 8,
+ ENTER: 13,
+ UP: 38,
+ DOWN: 40,
+};
+
+function setSearchOptions() {
+ const $projectOptionsDataEl = $('.js-search-project-options');
+ const $groupOptionsDataEl = $('.js-search-group-options');
+ const $dashboardOptionsDataEl = $('.js-search-dashboard-options');
+
+ if ($projectOptionsDataEl.length) {
+ gl.projectOptions = gl.projectOptions || {};
+
+ const projectPath = $projectOptionsDataEl.data('projectPath');
+
+ gl.projectOptions[projectPath] = {
+ name: $projectOptionsDataEl.data('name'),
+ issuesPath: $projectOptionsDataEl.data('issuesPath'),
+ issuesDisabled: $projectOptionsDataEl.data('issuesDisabled'),
+ mrPath: $projectOptionsDataEl.data('mrPath'),
+ };
+ }
+
+ if ($groupOptionsDataEl.length) {
+ gl.groupOptions = gl.groupOptions || {};
+
+ const groupPath = $groupOptionsDataEl.data('groupPath');
+
+ gl.groupOptions[groupPath] = {
+ name: $groupOptionsDataEl.data('name'),
+ issuesPath: $groupOptionsDataEl.data('issuesPath'),
+ mrPath: $groupOptionsDataEl.data('mrPath'),
+ };
+ }
+
+ if ($dashboardOptionsDataEl.length) {
+ gl.dashboardOptions = {
+ name: s__('SearchAutocomplete|All GitLab'),
+ issuesPath: $dashboardOptionsDataEl.data('issuesPath'),
+ mrPath: $dashboardOptionsDataEl.data('mrPath'),
+ };
+ }
+}
+
+export class GlobalSearchInput {
+ constructor({ wrap } = {}) {
+ setSearchOptions();
+ this.bindEventContext();
+ this.wrap = wrap || $('.search');
+ this.dropdown = this.wrap.find('.dropdown');
+ this.dropdownToggle = this.wrap.find('.js-dropdown-search-toggle');
+ this.dropdownMenu = this.dropdown.find('.dropdown-menu');
+ this.dropdownContent = this.dropdown.find('.dropdown-content');
+ this.scopeInputEl = this.getElement('#scope');
+ this.searchInput = this.getElement('.search-input');
+ this.projectInputEl = this.getElement('#search_project_id');
+ this.groupInputEl = this.getElement('#group_id');
+ this.searchCodeInputEl = this.getElement('#search_code');
+ this.repositoryInputEl = this.getElement('#repository_ref');
+ this.clearInput = this.getElement('.js-clear-input');
+ this.scrollFadeInitialized = false;
+ this.saveOriginalState();
+
+ // Only when user is logged in
+ if (gon.current_user_id) {
+ this.createGlobalSearchInput();
+ }
+
+ this.bindEvents();
+ this.dropdownToggle.dropdown();
+ this.searchInput.addClass('js-autocomplete-disabled');
+ }
+
+ // Finds an element inside wrapper element
+ bindEventContext() {
+ this.onSearchInputBlur = this.onSearchInputBlur.bind(this);
+ this.onClearInputClick = this.onClearInputClick.bind(this);
+ this.onSearchInputFocus = this.onSearchInputFocus.bind(this);
+ this.onSearchInputKeyUp = this.onSearchInputKeyUp.bind(this);
+ this.onSearchInputChange = this.onSearchInputChange.bind(this);
+ this.setScrollFade = this.setScrollFade.bind(this);
+ }
+ getElement(selector) {
+ return this.wrap.find(selector);
+ }
+
+ saveOriginalState() {
+ return (this.originalState = this.serializeState());
+ }
+
+ createGlobalSearchInput() {
+ return this.searchInput.glDropdown({
+ filterInputBlur: false,
+ filterable: true,
+ filterRemote: true,
+ highlight: true,
+ icon: true,
+ enterCallback: false,
+ filterInput: 'input#search',
+ search: {
+ fields: ['text'],
+ },
+ id: this.getSearchText,
+ data: this.getData.bind(this),
+ selectable: true,
+ clicked: this.onClick.bind(this),
+ });
+ }
+
+ getSearchText(selectedObject) {
+ return selectedObject.id ? selectedObject.text : '';
+ }
+
+ getData(term, callback) {
+ if (!term) {
+ const contents = this.getCategoryContents();
+ if (contents) {
+ const glDropdownInstance = this.searchInput.data('glDropdown');
+
+ if (glDropdownInstance) {
+ glDropdownInstance.filter.options.callback(contents);
+ }
+ this.enableDropdown();
+ }
+ return;
+ }
+
+ const options = this.scopedSearchOptions(term);
+
+ callback(options);
+
+ this.highlightFirstRow();
+ this.setScrollFade();
+ }
+
+ // Add option to proceed with the search for each
+ // scope that is currently available, namely:
+ //
+ // - Search in this project
+ // - Search in this group (or project's group)
+ // - Search in all GitLab
+ scopedSearchOptions(term) {
+ const icon = spriteIcon('search', 's16 inline-search-icon');
+ const projectId = this.projectInputEl.val();
+ const groupId = this.groupInputEl.val();
+ const options = [];
+
+ if (projectId) {
+ const projectOptions = gl.projectOptions[getProjectSlug()];
+ const url = groupId
+ ? `${gon.relative_url_root}/search?search=${term}&project_id=${projectId}&group_id=${groupId}`
+ : `${gon.relative_url_root}/search?search=${term}&project_id=${projectId}`;
+
+ options.push({
+ icon,
+ text: term,
+ template: sprintf(
+ s__(`SearchAutocomplete|in project %{projectName}`),
+ {
+ projectName: `<i>${projectOptions.name}</i>`,
+ },
+ false,
+ ),
+ url,
+ });
+ }
+
+ if (groupId) {
+ const groupOptions = gl.groupOptions[getGroupSlug()];
+ options.push({
+ icon,
+ text: term,
+ template: sprintf(
+ s__(`SearchAutocomplete|in group %{groupName}`),
+ {
+ groupName: `<i>${groupOptions.name}</i>`,
+ },
+ false,
+ ),
+ url: `${gon.relative_url_root}/search?search=${term}&group_id=${groupId}`,
+ });
+ }
+
+ options.push({
+ icon,
+ text: term,
+ template: s__('SearchAutocomplete|in all GitLab'),
+ url: `${gon.relative_url_root}/search?search=${term}`,
+ });
+
+ return options;
+ }
+
+ serializeState() {
+ return {
+ // Search Criteria
+ search_project_id: this.projectInputEl.val(),
+ group_id: this.groupInputEl.val(),
+ search_code: this.searchCodeInputEl.val(),
+ repository_ref: this.repositoryInputEl.val(),
+ scope: this.scopeInputEl.val(),
+ };
+ }
+
+ bindEvents() {
+ this.searchInput.on('input', this.onSearchInputChange);
+ this.searchInput.on('keyup', this.onSearchInputKeyUp);
+ this.searchInput.on('focus', this.onSearchInputFocus);
+ this.searchInput.on('blur', this.onSearchInputBlur);
+ this.clearInput.on('click', this.onClearInputClick);
+ this.dropdownContent.on('scroll', throttle(this.setScrollFade, 250));
+
+ this.searchInput.on('click', e => {
+ e.stopPropagation();
+ });
+ }
+
+ enableDropdown() {
+ this.setScrollFade();
+
+ // No need to enable anything if user is not logged in
+ if (!gon.current_user_id) {
+ return;
+ }
+
+ // If the dropdown is closed, we'll open it
+ if (!this.dropdown.hasClass('show')) {
+ this.loadingSuggestions = false;
+ this.dropdownToggle.dropdown('toggle');
+ return this.searchInput.removeClass('js-autocomplete-disabled');
+ }
+ }
+
+ onSearchInputChange() {
+ this.enableDropdown();
+ }
+
+ onSearchInputKeyUp(e) {
+ switch (e.keyCode) {
+ case KEYCODE.ESCAPE:
+ this.restoreOriginalState();
+ break;
+ case KEYCODE.ENTER:
+ this.disableDropdown();
+ break;
+ default:
+ }
+ this.wrap.toggleClass('has-value', Boolean(e.target.value));
+ }
+
+ onSearchInputFocus() {
+ this.isFocused = true;
+ this.wrap.addClass('search-active');
+ if (this.getValue() === '') {
+ return this.getData();
+ }
+ }
+
+ getValue() {
+ return this.searchInput.val();
+ }
+
+ onClearInputClick(e) {
+ e.preventDefault();
+ this.wrap.toggleClass('has-value', Boolean(e.target.value));
+ return this.searchInput.val('').focus();
+ }
+
+ onSearchInputBlur() {
+ this.isFocused = false;
+ this.wrap.removeClass('search-active');
+ // If input is blank then restore state
+ if (this.searchInput.val() === '') {
+ this.restoreOriginalState();
+ }
+ this.dropdownMenu.removeClass('show');
+ }
+
+ restoreOriginalState() {
+ const inputs = Object.keys(this.originalState);
+ for (let i = 0, len = inputs.length; i < len; i += 1) {
+ const input = inputs[i];
+ this.getElement(`#${input}`).val(this.originalState[input]);
+ }
+ }
+
+ resetSearchState() {
+ const inputs = Object.keys(this.originalState);
+ const results = [];
+ for (let i = 0, len = inputs.length; i < len; i += 1) {
+ const input = inputs[i];
+ results.push(this.getElement(`#${input}`).val(''));
+ }
+ return results;
+ }
+
+ disableDropdown() {
+ if (!this.searchInput.hasClass('js-autocomplete-disabled') && this.dropdown.hasClass('show')) {
+ this.searchInput.addClass('js-autocomplete-disabled');
+ this.dropdownToggle.dropdown('toggle');
+ this.restoreMenu();
+ }
+ }
+
+ restoreMenu() {
+ const html = `<ul><li class="dropdown-menu-empty-item"><a>${__('Loading...')}</a></li></ul>`;
+ return this.dropdownContent.html(html);
+ }
+
+ onClick(item, $el, e) {
+ if (window.location.pathname.indexOf(item.url) !== -1) {
+ if (!e.metaKey) e.preventDefault();
+ $el.removeClass('is-active');
+ this.disableDropdown();
+ return this.searchInput.val('').focus();
+ }
+ }
+
+ highlightFirstRow() {
+ this.searchInput.data('glDropdown').highlightRowAtIndex(null, 0);
+ }
+
+ getCategoryContents() {
+ const userName = gon.current_username;
+ const { projectOptions, groupOptions, dashboardOptions } = gl;
+
+ // Get options
+ let options;
+ if (isInProjectPage() && projectOptions) {
+ options = projectOptions[getProjectSlug()];
+ } else if (isInGroupsPage() && groupOptions) {
+ options = groupOptions[getGroupSlug()];
+ } else if (dashboardOptions) {
+ options = dashboardOptions;
+ }
+
+ const { issuesPath, mrPath, name, issuesDisabled } = options;
+ const baseItems = [];
+
+ if (name) {
+ baseItems.push({
+ type: 'header',
+ content: `${name}`,
+ });
+ }
+
+ const issueItems = [
+ {
+ text: s__('SearchAutocomplete|Issues assigned to me'),
+ url: `${issuesPath}/?assignee_username=${userName}`,
+ },
+ {
+ text: s__("SearchAutocomplete|Issues I've created"),
+ url: `${issuesPath}/?author_username=${userName}`,
+ },
+ ];
+ const mergeRequestItems = [
+ {
+ text: s__('SearchAutocomplete|Merge requests assigned to me'),
+ url: `${mrPath}/?assignee_username=${userName}`,
+ },
+ {
+ text: s__("SearchAutocomplete|Merge requests I've created"),
+ url: `${mrPath}/?author_username=${userName}`,
+ },
+ ];
+
+ let items;
+ if (issuesDisabled) {
+ items = baseItems.concat(mergeRequestItems);
+ } else {
+ items = baseItems.concat(...issueItems, ...mergeRequestItems);
+ }
+ return items;
+ }
+
+ isScrolledUp() {
+ const el = this.dropdownContent[0];
+ const currentPosition = this.contentClientHeight + el.scrollTop;
+
+ return currentPosition < this.maxPosition;
+ }
+
+ initScrollFade() {
+ const el = this.dropdownContent[0];
+ this.scrollFadeInitialized = true;
+
+ this.contentClientHeight = el.clientHeight;
+ this.maxPosition = el.scrollHeight;
+ this.dropdownMenu.addClass('dropdown-content-faded-mask');
+ }
+
+ setScrollFade() {
+ this.initScrollFade();
+
+ this.dropdownMenu.toggleClass('fade-out', !this.isScrolledUp());
+ }
+}
+
+export default function initGlobalSearchInput(opts) {
+ return new GlobalSearchInput(opts);
+}
diff --git a/app/assets/javascripts/graphql_shared/fragments/pageInfo.fragment.graphql b/app/assets/javascripts/graphql_shared/fragments/pageInfo.fragment.graphql
index 7403fd6d3c2..e6f5d7db11a 100644
--- a/app/assets/javascripts/graphql_shared/fragments/pageInfo.fragment.graphql
+++ b/app/assets/javascripts/graphql_shared/fragments/pageInfo.fragment.graphql
@@ -1,4 +1,6 @@
fragment PageInfo on PageInfo {
hasNextPage
+ hasPreviousPage
+ startCursor
endCursor
}
diff --git a/app/assets/javascripts/group.js b/app/assets/javascripts/group.js
index eda0f5d1d23..ec8a238192a 100644
--- a/app/assets/javascripts/group.js
+++ b/app/assets/javascripts/group.js
@@ -1,4 +1,3 @@
-import $ from 'jquery';
import { slugify } from './lib/utils/text_utility';
import fetchGroupPathAvailability from '~/pages/groups/new/fetch_group_path_availability';
import flash from '~/flash';
@@ -6,44 +5,69 @@ import { __ } from '~/locale';
export default class Group {
constructor() {
- this.groupPath = $('#group_path');
- this.groupName = $('#group_name');
- this.parentId = $('#group_parent_id');
+ this.groupPaths = Array.from(document.querySelectorAll('.js-autofill-group-path'));
+ this.groupNames = Array.from(document.querySelectorAll('.js-autofill-group-name'));
+ this.parentId = document.getElementById('group_parent_id');
this.updateHandler = this.update.bind(this);
this.resetHandler = this.reset.bind(this);
this.updateGroupPathSlugHandler = this.updateGroupPathSlug.bind(this);
- if (this.groupName.val() === '') {
- this.groupName.on('keyup', this.updateHandler);
- this.groupPath.on('keydown', this.resetHandler);
- if (!this.parentId.val()) {
- this.groupName.on('blur', this.updateGroupPathSlugHandler);
+
+ this.groupNames.forEach(groupName => {
+ if (groupName.value === '') {
+ groupName.addEventListener('keyup', this.updateHandler);
+
+ if (!this.parentId.value) {
+ groupName.addEventListener('blur', this.updateGroupPathSlugHandler);
+ }
}
- }
+ });
+
+ this.groupPaths.forEach(groupPath => {
+ groupPath.addEventListener('keydown', this.resetHandler);
+ });
}
- update() {
- const slug = slugify(this.groupName.val());
- this.groupPath.val(slug);
+ update({ currentTarget: { value: updatedValue } }) {
+ const slug = slugify(updatedValue);
+
+ this.groupNames.forEach(element => {
+ element.value = updatedValue;
+ });
+ this.groupPaths.forEach(element => {
+ element.value = slug;
+ });
}
reset() {
- this.groupName.off('keyup', this.updateHandler);
- this.groupPath.off('keydown', this.resetHandler);
- this.groupName.off('blur', this.checkPathHandler);
+ this.groupNames.forEach(groupName => {
+ groupName.removeEventListener('keyup', this.updateHandler);
+ groupName.removeEventListener('blur', this.checkPathHandler);
+ });
+
+ this.groupPaths.forEach(groupPath => {
+ groupPath.removeEventListener('keydown', this.resetHandler);
+ });
}
- updateGroupPathSlug() {
- const slug = this.groupPath.val() || slugify(this.groupName.val());
+ updateGroupPathSlug({ currentTarget: { value } = '' } = {}) {
+ const slug = this.groupPaths[0]?.value || slugify(value);
if (!slug) return;
fetchGroupPathAvailability(slug)
.then(({ data }) => data)
- .then(data => {
- if (data.exists && data.suggests.length > 0) {
- const suggestedSlug = data.suggests[0];
- this.groupPath.val(suggestedSlug);
+ .then(({ exists, suggests }) => {
+ if (exists && suggests.length) {
+ const [suggestedSlug] = suggests;
+
+ this.groupPaths.forEach(element => {
+ element.value = suggestedSlug;
+ });
+ } else if (exists && !suggests.length) {
+ flash(__('Unable to suggest a path. Please refresh and try again.'));
}
})
- .catch(() => flash(__('An error occurred while checking group path')));
+ .catch(() =>
+ flash(__('An error occurred while checking group path. Please refresh and try again.')),
+ );
}
}
diff --git a/app/assets/javascripts/groups/components/group_item.vue b/app/assets/javascripts/groups/components/group_item.vue
index 1b8c75202fb..6b9748bb725 100644
--- a/app/assets/javascripts/groups/components/group_item.vue
+++ b/app/assets/javascripts/groups/components/group_item.vue
@@ -12,6 +12,8 @@ import itemStats from './item_stats.vue';
import itemStatsValue from './item_stats_value.vue';
import itemActions from './item_actions.vue';
+import { showLearnGitLabGroupItemPopover } from '~/onboarding_issues';
+
export default {
directives: {
tooltip,
@@ -73,6 +75,11 @@ export default {
return GROUP_VISIBILITY_TYPE[this.group.visibility];
},
},
+ mounted() {
+ if (this.group.name === 'Learn GitLab') {
+ showLearnGitLabGroupItemPopover(this.group.id);
+ }
+ },
methods: {
onClickRowGroup(e) {
const NO_EXPAND_CLS = 'no-expand';
@@ -104,7 +111,7 @@ export default {
<gl-loading-icon
v-if="group.isChildrenLoading"
size="lg"
- class="d-none d-sm-inline-flex flex-shrink-0 append-right-8"
+ class="d-none d-sm-inline-flex flex-shrink-0 gl-mr-3"
/>
<div
:class="{ 'd-sm-flex': !group.isChildrenLoading }"
@@ -117,12 +124,12 @@ export default {
</div>
<div class="group-text-container d-flex flex-fill align-items-center">
<div class="group-text flex-grow-1 flex-shrink-1">
- <div class="d-flex align-items-center flex-wrap title namespace-title append-right-8">
+ <div class="d-flex align-items-center flex-wrap title namespace-title gl-mr-3">
<a
v-tooltip
:href="group.relativePath"
:title="group.fullName"
- class="no-expand prepend-top-8 append-right-8"
+ class="no-expand gl-mt-3 gl-mr-3 gl-text-gray-900!"
data-placement="bottom"
>{{
// ending bracket must be by closing tag to prevent
@@ -133,9 +140,9 @@ export default {
<item-stats-value
:icon-name="visibilityIcon"
:title="visibilityTooltip"
- css-class="item-visibility d-inline-flex align-items-center prepend-top-8 append-right-4 text-secondary"
+ css-class="item-visibility d-inline-flex align-items-center gl-mt-3 append-right-4 text-secondary"
/>
- <span v-if="group.permission" class="user-access-role prepend-top-8">
+ <span v-if="group.permission" class="user-access-role gl-mt-3">
{{ group.permission }}
</span>
</div>
@@ -150,7 +157,7 @@ export default {
class="metadata align-items-md-center d-flex flex-grow-1 flex-shrink-0 flex-wrap justify-content-md-between"
>
<item-actions v-if="isGroup" :group="group" :parent-group="parentGroup" />
- <item-stats :item="group" class="group-stats prepend-top-2 d-none d-md-flex" />
+ <item-stats :item="group" class="group-stats gl-mt-2 d-none d-md-flex" />
</div>
</div>
</div>
diff --git a/app/assets/javascripts/groups/components/item_actions.vue b/app/assets/javascripts/groups/components/item_actions.vue
index 5454480e61a..985ea5a9019 100644
--- a/app/assets/javascripts/groups/components/item_actions.vue
+++ b/app/assets/javascripts/groups/components/item_actions.vue
@@ -53,7 +53,7 @@ export default {
:aria-label="leaveBtnTitle"
data-container="body"
data-placement="bottom"
- class="leave-group btn btn-xs no-expand"
+ class="leave-group btn btn-xs no-expand gl-text-gray-700 gl-ml-5"
@click.prevent="onLeaveGroup"
>
<icon name="leave" class="position-top-0" />
@@ -66,7 +66,7 @@ export default {
:aria-label="editBtnTitle"
data-container="body"
data-placement="bottom"
- class="edit-group btn btn-xs no-expand"
+ class="edit-group btn btn-xs no-expand gl-text-gray-700 gl-ml-5"
>
<icon name="settings" class="position-top-0 align-middle" />
</a>
diff --git a/app/assets/javascripts/groups/components/item_stats.vue b/app/assets/javascripts/groups/components/item_stats.vue
index 53da3f7b2ee..ffe4b18dea1 100644
--- a/app/assets/javascripts/groups/components/item_stats.vue
+++ b/app/assets/javascripts/groups/components/item_stats.vue
@@ -44,26 +44,26 @@ export default {
</script>
<template>
- <div class="stats">
+ <div class="stats gl-text-gray-700">
<item-stats-value
v-if="isGroup"
:title="__('Subgroups')"
:value="item.subgroupCount"
- css-class="number-subgroups"
+ css-class="number-subgroups gl-ml-5"
icon-name="folder-o"
/>
<item-stats-value
v-if="isGroup"
:title="__('Projects')"
:value="item.projectCount"
- css-class="number-projects"
+ css-class="number-projects gl-ml-5"
icon-name="bookmark"
/>
<item-stats-value
v-if="isGroup"
:title="__('Members')"
:value="item.memberCount"
- css-class="number-users"
+ css-class="number-users gl-ml-5"
icon-name="users"
/>
<item-stats-value
diff --git a/app/assets/javascripts/header.js b/app/assets/javascripts/header.js
index 67b068f1c6b..d151cecf5be 100644
--- a/app/assets/javascripts/header.js
+++ b/app/assets/javascripts/header.js
@@ -86,7 +86,7 @@ function trackShowUserDropdownLink(trackEvent, elToTrack, el) {
}
export function initNavUserDropdownTracking() {
const el = document.querySelector('.js-nav-user-dropdown');
- const buyEl = document.querySelector('.js-buy-ci-minutes-link');
+ const buyEl = document.querySelector('.js-buy-pipeline-minutes-link');
const upgradeEl = document.querySelector('.js-upgrade-plan-link');
if (el && buyEl) {
diff --git a/app/assets/javascripts/ide/commit_icon.js b/app/assets/javascripts/ide/commit_icon.js
new file mode 100644
index 00000000000..4984b5bb91d
--- /dev/null
+++ b/app/assets/javascripts/ide/commit_icon.js
@@ -0,0 +1,11 @@
+import { commitItemIconMap } from './constants';
+
+export default file => {
+ if (file.deleted) {
+ return commitItemIconMap.deleted;
+ } else if (file.tempFile && !file.prevPath) {
+ return commitItemIconMap.addition;
+ }
+
+ return commitItemIconMap.modified;
+};
diff --git a/app/assets/javascripts/ide/components/activity_bar.vue b/app/assets/javascripts/ide/components/activity_bar.vue
index 186d4b6d7d2..a65af55fcac 100644
--- a/app/assets/javascripts/ide/components/activity_bar.vue
+++ b/app/assets/javascripts/ide/components/activity_bar.vue
@@ -1,6 +1,6 @@
<script>
import $ from 'jquery';
-import { mapActions, mapGetters, mapState } from 'vuex';
+import { mapActions, mapState } from 'vuex';
import Icon from '~/vue_shared/components/icon.vue';
import tooltip from '~/vue_shared/directives/tooltip';
import { leftSidebarViews } from '../constants';
@@ -13,7 +13,6 @@ export default {
tooltip,
},
computed: {
- ...mapGetters(['hasChanges']),
...mapState(['currentActivityView']),
},
methods: {
@@ -23,6 +22,8 @@ export default {
this.updateActivityBarView(view);
+ // TODO: We must use JQuery here to interact with the Bootstrap tooltip API
+ // https://gitlab.com/gitlab-org/gitlab/-/issues/217577
$(e.currentTarget).tooltip('hide');
},
},
@@ -67,7 +68,7 @@ export default {
<icon name="file-modified" />
</button>
</li>
- <li v-show="hasChanges">
+ <li>
<button
v-tooltip
:class="{
diff --git a/app/assets/javascripts/ide/components/branches/item.vue b/app/assets/javascripts/ide/components/branches/item.vue
index 58a0631ee0d..e7f4cd796b5 100644
--- a/app/assets/javascripts/ide/components/branches/item.vue
+++ b/app/assets/javascripts/ide/components/branches/item.vue
@@ -2,7 +2,6 @@
/* eslint-disable @gitlab/vue-require-i18n-strings */
import Icon from '~/vue_shared/components/icon.vue';
import Timeago from '~/vue_shared/components/time_ago_tooltip.vue';
-import router from '../../ide_router';
export default {
components: {
@@ -26,7 +25,7 @@ export default {
},
computed: {
branchHref() {
- return router.resolve(`/project/${this.projectId}/edit/${this.item.name}`).href;
+ return this.$router.resolve(`/project/${this.projectId}/edit/${this.item.name}`).href;
},
},
};
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/editor_header.vue b/app/assets/javascripts/ide/components/commit_sidebar/editor_header.vue
index 24499fb9f6d..59a32dd477e 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/editor_header.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/editor_header.vue
@@ -29,7 +29,7 @@ export default {
},
},
methods: {
- ...mapActions(['stageChange', 'unstageChange', 'discardFileChanges']),
+ ...mapActions(['unstageChange', 'discardFileChanges']),
showDiscardModal() {
this.$refs.discardModal.show();
},
@@ -56,7 +56,7 @@ export default {
v-if="canDiscard"
ref="discardButton"
type="button"
- class="btn btn-remove btn-inverted append-right-8"
+ class="btn btn-remove btn-inverted gl-mr-3"
@click="showDiscardModal"
>
{{ __('Discard changes') }}
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/empty_state.vue b/app/assets/javascripts/ide/components/commit_sidebar/empty_state.vue
index a23bae8e4c7..a13ca0cd138 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/empty_state.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/empty_state.vue
@@ -9,10 +9,7 @@ export default {
</script>
<template>
- <div
- v-if="!lastCommitMsg"
- class="multi-file-commit-panel-section ide-commit-empty-state js-empty-state"
- >
+ <div v-if="!lastCommitMsg" class="multi-file-commit-panel-section ide-commit-empty-state">
<div class="ide-commit-empty-state-container">
<div class="svg-content svg-80"><img :src="noChangesStateSvgPath" /></div>
<div class="append-right-default prepend-left-default">
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/form.vue b/app/assets/javascripts/ide/components/commit_sidebar/form.vue
index 4cbd33e6ed6..3bba4fbc906 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/form.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/form.vue
@@ -26,7 +26,7 @@ export default {
computed: {
...mapState(['changedFiles', 'stagedFiles', 'currentActivityView', 'lastCommitMsg']),
...mapState('commit', ['commitMessage', 'submitCommitLoading']),
- ...mapGetters(['hasChanges']),
+ ...mapGetters(['someUncommittedChanges']),
...mapGetters('commit', ['discardDraftButtonDisabled', 'preBuiltCommitMessage']),
overviewText() {
return n__('%d changed file', '%d changed files', this.stagedFiles.length);
@@ -40,20 +40,9 @@ export default {
},
},
watch: {
- currentActivityView() {
- if (this.lastCommitMsg) {
- this.isCompact = false;
- } else {
- this.isCompact = !(
- this.currentViewIsCommitView && window.innerHeight >= MAX_WINDOW_HEIGHT_COMPACT
- );
- }
- },
-
- lastCommitMsg() {
- this.isCompact =
- this.currentActivityView !== leftSidebarViews.commit.name && this.lastCommitMsg === '';
- },
+ currentActivityView: 'handleCompactState',
+ someUncommittedChanges: 'handleCompactState',
+ lastCommitMsg: 'handleCompactState',
},
methods: {
...mapActions(['updateActivityBarView']),
@@ -71,19 +60,24 @@ export default {
forceCreateNewBranch() {
return this.updateCommitAction(consts.COMMIT_TO_NEW_BRANCH).then(() => this.commit());
},
- toggleIsCompact() {
- if (this.currentViewIsCommitView) {
- this.isCompact = !this.isCompact;
+ handleCompactState() {
+ if (this.lastCommitMsg) {
+ this.isCompact = false;
} else {
- this.updateActivityBarView(leftSidebarViews.commit.name)
- .then(() => {
- this.isCompact = false;
- })
- .catch(e => {
- throw e;
- });
+ this.isCompact =
+ !this.someUncommittedChanges ||
+ !this.currentViewIsCommitView ||
+ window.innerHeight < MAX_WINDOW_HEIGHT_COMPACT;
}
},
+ toggleIsCompact() {
+ this.isCompact = !this.isCompact;
+ },
+ beginCommit() {
+ return this.updateActivityBarView(leftSidebarViews.commit.name).then(() => {
+ this.isCompact = false;
+ });
+ },
beforeEnterTransition() {
const elHeight = this.isCompact
? this.$refs.formEl && this.$refs.formEl.offsetHeight
@@ -126,16 +120,17 @@ export default {
>
<div v-if="isCompact" ref="compactEl" class="commit-form-compact">
<button
- :disabled="!hasChanges"
+ :disabled="!someUncommittedChanges"
type="button"
class="btn btn-primary btn-sm btn-block qa-begin-commit-button"
- @click="toggleIsCompact"
+ data-testid="begin-commit-button"
+ @click="beginCommit"
>
{{ __('Commit…') }}
</button>
<p class="text-center bold">{{ overviewText }}</p>
</div>
- <form v-if="!isCompact" ref="formEl" @submit.prevent.stop="commit">
+ <form v-else ref="formEl" @submit.prevent.stop="commit">
<transition name="fade"> <success-message v-show="lastCommitMsg" /> </transition>
<commit-message-field
:text="commitMessage"
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list.vue b/app/assets/javascripts/ide/components/commit_sidebar/list.vue
index e6a1a1ba73c..5cff1079eb0 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/list.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/list.vue
@@ -55,7 +55,7 @@ export default {
},
},
methods: {
- ...mapActions(['stageAllChanges', 'unstageAllChanges', 'discardAllChanges']),
+ ...mapActions(['unstageAllChanges', 'discardAllChanges']),
openDiscardModal() {
this.$refs.discardAllModal.show();
},
@@ -74,7 +74,7 @@ export default {
<div class="ide-commit-list-container">
<header class="multi-file-commit-panel-header d-flex mb-0">
<div class="d-flex align-items-center flex-fill">
- <icon v-once :name="iconName" :size="18" class="append-right-8" />
+ <icon v-once :name="iconName" :size="18" class="gl-mr-3" />
<strong> {{ titleText }} </strong>
<div class="d-flex ml-auto">
<button
@@ -98,7 +98,7 @@ export default {
</div>
</div>
</header>
- <ul v-if="filesLength" class="multi-file-commit-list list-unstyled append-bottom-0">
+ <ul v-if="filesLength" class="multi-file-commit-list list-unstyled gl-mb-0">
<li v-for="file in fileList" :key="file.key">
<list-item
:file="file"
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue b/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue
index e70e251c117..c65169f5d31 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue
@@ -4,7 +4,7 @@ import tooltip from '~/vue_shared/directives/tooltip';
import Icon from '~/vue_shared/components/icon.vue';
import FileIcon from '~/vue_shared/components/file_icon.vue';
import { viewerTypes } from '../../constants';
-import { getCommitIconMap } from '../../utils';
+import getCommitIconMap from '../../commit_icon';
export default {
components: {
@@ -87,7 +87,7 @@ export default {
@click="openFileInEditor"
>
<span class="multi-file-commit-list-file-path d-flex align-items-center">
- <file-icon :file-name="file.name" class="append-right-8" />
+ <file-icon :file-name="file.name" class="gl-mr-3" />
<template v-if="file.prevName && file.prevName !== file.name">
{{ file.prevName }} &#x2192;
</template>
diff --git a/app/assets/javascripts/ide/components/file_row_extra.vue b/app/assets/javascripts/ide/components/file_row_extra.vue
index 32822a75772..51509cd5fe6 100644
--- a/app/assets/javascripts/ide/components/file_row_extra.vue
+++ b/app/assets/javascripts/ide/components/file_row_extra.vue
@@ -89,7 +89,7 @@ export default {
:type="file.type"
:path="file.path"
:is-open="dropdownOpen"
- class="prepend-left-8"
+ class="gl-ml-3"
v-on="$listeners"
/>
</div>
diff --git a/app/assets/javascripts/ide/components/ide.vue b/app/assets/javascripts/ide/components/ide.vue
index 36c8b18e205..e9f84eb8648 100644
--- a/app/assets/javascripts/ide/components/ide.vue
+++ b/app/assets/javascripts/ide/components/ide.vue
@@ -1,5 +1,4 @@
<script>
-import Vue from 'vue';
import { mapActions, mapGetters, mapState } from 'vuex';
import { GlDeprecatedButton, GlLoadingIcon } from '@gitlab/ui';
import { __ } from '~/locale';
@@ -27,20 +26,13 @@ export default {
CommitEditorHeader,
GlDeprecatedButton,
GlLoadingIcon,
+ RightPane,
},
mixins: [glFeatureFlagsMixin()],
- props: {
- rightPaneComponent: {
- type: Vue.Component,
- required: false,
- default: () => RightPane,
- },
- },
computed: {
...mapState([
'openFiles',
'viewer',
- 'currentMergeRequestId',
'fileFindVisible',
'emptyStateSvgPath',
'currentProjectId',
@@ -49,7 +41,6 @@ export default {
]),
...mapGetters([
'activeFile',
- 'hasChanges',
'someUncommittedChanges',
'isCommitModeActive',
'allBlobs',
@@ -108,14 +99,7 @@ export default {
<div class="multi-file-edit-pane">
<template v-if="activeFile">
<commit-editor-header v-if="isCommitModeActive" :active-file="activeFile" />
- <repo-tabs
- v-else
- :active-file="activeFile"
- :files="openFiles"
- :viewer="viewer"
- :has-changes="hasChanges"
- :merge-request-id="currentMergeRequestId"
- />
+ <repo-tabs v-else :active-file="activeFile" :files="openFiles" :viewer="viewer" />
<repo-editor :file="activeFile" class="multi-file-edit-pane-content" />
</template>
<template v-else>
@@ -141,6 +125,7 @@ export default {
variant="success"
:title="__('New file')"
:aria-label="__('New file')"
+ data-qa-selector="first_file_button"
@click="createNewFile()"
>
{{ __('New file') }}
@@ -160,7 +145,7 @@ export default {
</div>
</template>
</div>
- <component :is="rightPaneComponent" v-if="currentProjectId" />
+ <right-pane v-if="currentProjectId" />
</div>
<ide-status-bar />
<new-modal ref="newModal" />
diff --git a/app/assets/javascripts/ide/components/ide_side_bar.vue b/app/assets/javascripts/ide/components/ide_side_bar.vue
index 7cb31df85ce..1eb89b41495 100644
--- a/app/assets/javascripts/ide/components/ide_side_bar.vue
+++ b/app/assets/javascripts/ide/components/ide_side_bar.vue
@@ -9,7 +9,7 @@ import CommitForm from './commit_sidebar/form.vue';
import IdeReview from './ide_review.vue';
import SuccessMessage from './commit_sidebar/success_message.vue';
import IdeProjectHeader from './ide_project_header.vue';
-import { leftSidebarViews } from '../constants';
+import { leftSidebarViews, SIDEBAR_INIT_WIDTH } from '../constants';
export default {
components: {
@@ -33,11 +33,16 @@ export default {
);
},
},
+ SIDEBAR_INIT_WIDTH,
};
</script>
<template>
- <resizable-panel :initial-width="340" side="left" class="flex-column">
+ <resizable-panel
+ :initial-width="$options.SIDEBAR_INIT_WIDTH"
+ side="left"
+ class="multi-file-commit-panel flex-column"
+ >
<template v-if="loading">
<div class="multi-file-commit-panel-inner">
<div v-for="n in 3" :key="n" class="multi-file-loading-container">
diff --git a/app/assets/javascripts/ide/components/ide_sidebar_nav.vue b/app/assets/javascripts/ide/components/ide_sidebar_nav.vue
new file mode 100644
index 00000000000..966c36d6e71
--- /dev/null
+++ b/app/assets/javascripts/ide/components/ide_sidebar_nav.vue
@@ -0,0 +1,83 @@
+<script>
+import { GlTooltipDirective, GlIcon } from '@gitlab/ui';
+import { otherSide } from '../utils';
+import { SIDE_RIGHT } from '../constants';
+
+export default {
+ directives: {
+ tooltip: GlTooltipDirective,
+ },
+ components: {
+ GlIcon,
+ },
+ props: {
+ tabs: {
+ type: Array,
+ required: true,
+ },
+ side: {
+ type: String,
+ required: true,
+ },
+ currentView: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ isOpen: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+ computed: {
+ otherSide() {
+ return otherSide(this.side);
+ },
+ },
+ methods: {
+ isActiveTab(tab) {
+ return this.isOpen && tab.views.some(view => view.name === this.currentView);
+ },
+ buttonClasses(tab) {
+ return [
+ {
+ 'is-right': this.side === SIDE_RIGHT,
+ active: this.isActiveTab(tab),
+ },
+ ...(tab.buttonClasses || []),
+ ];
+ },
+ clickTab(e, tab) {
+ e.currentTarget.blur();
+ this.$root.$emit('bv::hide::tooltip');
+
+ if (this.isActiveTab(tab)) {
+ this.$emit('close');
+ } else {
+ this.$emit('open', tab.views[0]);
+ }
+ },
+ },
+};
+</script>
+<template>
+ <nav class="ide-activity-bar">
+ <ul class="list-unstyled">
+ <li v-for="tab of tabs" :key="tab.title">
+ <button
+ v-tooltip="{ container: 'body', placement: otherSide }"
+ :title="tab.title"
+ :aria-label="tab.title"
+ :class="buttonClasses(tab)"
+ :data-qa-selector="`${tab.title.toLowerCase()}_tab_button`"
+ class="ide-sidebar-link"
+ type="button"
+ @click="clickTab($event, tab)"
+ >
+ <gl-icon :size="16" :name="tab.icon" />
+ </button>
+ </li>
+ </ul>
+ </nav>
+</template>
diff --git a/app/assets/javascripts/ide/components/ide_status_bar.vue b/app/assets/javascripts/ide/components/ide_status_bar.vue
index 5585343f367..ddc126c3d77 100644
--- a/app/assets/javascripts/ide/components/ide_status_bar.vue
+++ b/app/assets/javascripts/ide/components/ide_status_bar.vue
@@ -1,7 +1,7 @@
<script>
/* eslint-disable @gitlab/vue-require-i18n-strings */
import { mapActions, mapState, mapGetters } from 'vuex';
-import IdeStatusList from 'ee_else_ce/ide/components/ide_status_list.vue';
+import IdeStatusList from './ide_status_list.vue';
import IdeStatusMr from './ide_status_mr.vue';
import icon from '~/vue_shared/components/icon.vue';
import tooltip from '~/vue_shared/directives/tooltip';
diff --git a/app/assets/javascripts/ide/components/ide_status_list.vue b/app/assets/javascripts/ide/components/ide_status_list.vue
index 364e3f081a1..92d25709bd5 100644
--- a/app/assets/javascripts/ide/components/ide_status_list.vue
+++ b/app/assets/javascripts/ide/components/ide_status_list.vue
@@ -1,9 +1,17 @@
<script>
import { mapGetters } from 'vuex';
+import TerminalSyncStatusSafe from './terminal_sync/terminal_sync_status_safe.vue';
+import { getFileEOL } from '../utils';
export default {
+ components: {
+ TerminalSyncStatusSafe,
+ },
computed: {
...mapGetters(['activeFile']),
+ activeFileEOL() {
+ return getFileEOL(this.activeFile.content);
+ },
},
};
</script>
@@ -12,12 +20,12 @@ export default {
<div class="ide-status-list d-flex">
<template v-if="activeFile">
<div class="ide-status-file">{{ activeFile.name }}</div>
- <div class="ide-status-file">{{ activeFile.eol }}</div>
+ <div class="ide-status-file">{{ activeFileEOL }}</div>
<div v-if="!activeFile.binary" class="ide-status-file">
{{ activeFile.editorRow }}:{{ activeFile.editorColumn }}
</div>
<div class="ide-status-file">{{ activeFile.fileLanguage }}</div>
</template>
- <slot></slot>
+ <terminal-sync-status-safe />
</div>
</template>
diff --git a/app/assets/javascripts/ide/components/jobs/detail/description.vue b/app/assets/javascripts/ide/components/jobs/detail/description.vue
index 9c0c97bc5ae..f1ba102fffe 100644
--- a/app/assets/javascripts/ide/components/jobs/detail/description.vue
+++ b/app/assets/javascripts/ide/components/jobs/detail/description.vue
@@ -24,7 +24,7 @@ export default {
<template>
<div class="d-flex align-items-center">
<ci-icon :status="job.status" :borderless="true" :size="24" class="d-flex" />
- <span class="prepend-left-8">
+ <span class="gl-ml-3">
{{ job.name }}
<a :href="job.path" target="_blank" class="ide-external-link position-relative">
{{ jobId }} <icon :size="12" name="external-link" />
diff --git a/app/assets/javascripts/ide/components/jobs/stage.vue b/app/assets/javascripts/ide/components/jobs/stage.vue
index ba8407382f4..169a948c2da 100644
--- a/app/assets/javascripts/ide/components/jobs/stage.vue
+++ b/app/assets/javascripts/ide/components/jobs/stage.vue
@@ -71,11 +71,11 @@ export default {
v-tooltip="showTooltip"
:title="showTooltip ? stage.name : null"
data-container="body"
- class="prepend-left-8 text-truncate"
+ class="gl-ml-3 text-truncate"
>
{{ stage.name }}
</strong>
- <div v-if="!stage.isLoading || stage.jobs.length" class="append-right-8 prepend-left-4">
+ <div v-if="!stage.isLoading || stage.jobs.length" class="gl-mr-3 gl-ml-2">
<span class="badge badge-pill"> {{ jobsCount }} </span>
</div>
<icon :name="collapseIcon" class="ide-stage-collapse-icon" />
diff --git a/app/assets/javascripts/ide/components/merge_requests/item.vue b/app/assets/javascripts/ide/components/merge_requests/item.vue
index 60889c893cf..3f060392686 100644
--- a/app/assets/javascripts/ide/components/merge_requests/item.vue
+++ b/app/assets/javascripts/ide/components/merge_requests/item.vue
@@ -1,6 +1,5 @@
<script>
import Icon from '../../../vue_shared/components/icon.vue';
-import router from '../../ide_router';
export default {
components: {
@@ -33,7 +32,7 @@ export default {
mergeRequestHref() {
const path = `/project/${this.item.projectPathWithNamespace}/merge_requests/${this.item.iid}`;
- return router.resolve(path).href;
+ return this.$router.resolve(path).href;
},
},
};
diff --git a/app/assets/javascripts/ide/components/mr_file_icon.vue b/app/assets/javascripts/ide/components/mr_file_icon.vue
index cf8a1abbde4..4fab57b6f3e 100644
--- a/app/assets/javascripts/ide/components/mr_file_icon.vue
+++ b/app/assets/javascripts/ide/components/mr_file_icon.vue
@@ -18,6 +18,6 @@ export default {
:title="__('Part of merge request changes')"
:size="12"
name="git-merge"
- class="append-right-8"
+ class="gl-mr-3"
/>
</template>
diff --git a/app/assets/javascripts/ide/components/new_dropdown/modal.vue b/app/assets/javascripts/ide/components/new_dropdown/modal.vue
index 4766a2fe6ae..586d6867ab4 100644
--- a/app/assets/javascripts/ide/components/new_dropdown/modal.vue
+++ b/app/assets/javascripts/ide/components/new_dropdown/modal.vue
@@ -4,7 +4,7 @@ import flash from '~/flash';
import { __, sprintf, s__ } from '~/locale';
import { GlModal } from '@gitlab/ui';
import { modalTypes } from '../../constants';
-import { trimPathComponents } from '../../utils';
+import { trimPathComponents, getPathParent } from '../../utils';
export default {
components: {
@@ -85,8 +85,10 @@ export default {
}
},
createFromTemplate(template) {
+ const parent = getPathParent(this.entryName);
+ const name = parent ? `${parent}/${template.name}` : template.name;
this.createTempEntry({
- name: template.name,
+ name,
type: this.modalType,
});
@@ -133,7 +135,7 @@ export default {
<gl-modal
ref="modal"
modal-id="ide-new-entry"
- modal-class="qa-new-file-modal"
+ data-qa-selector="new_file_modal"
:title="modalTitle"
:ok-title="buttonLabel"
ok-variant="success"
@@ -148,7 +150,8 @@ export default {
ref="fieldName"
v-model.trim="entryName"
type="text"
- class="form-control qa-full-file-path"
+ class="form-control"
+ data-qa-selector="file_name_field"
:placeholder="placeholder"
/>
<ul
diff --git a/app/assets/javascripts/ide/components/new_dropdown/upload.vue b/app/assets/javascripts/ide/components/new_dropdown/upload.vue
index 7261e0590c8..b2141c13d9f 100644
--- a/app/assets/javascripts/ide/components/new_dropdown/upload.vue
+++ b/app/assets/javascripts/ide/components/new_dropdown/upload.vue
@@ -35,7 +35,6 @@ export default {
name: `${this.path ? `${this.path}/` : ''}${name}`,
type: 'blob',
content,
- base64: !isText,
binary: !isText,
rawPath: !isText ? target.result : '',
});
diff --git a/app/assets/javascripts/ide/components/panes/collapsible_sidebar.vue b/app/assets/javascripts/ide/components/panes/collapsible_sidebar.vue
index 91e80be7d18..4e8e1e3a470 100644
--- a/app/assets/javascripts/ide/components/panes/collapsible_sidebar.vue
+++ b/app/assets/javascripts/ide/components/panes/collapsible_sidebar.vue
@@ -2,8 +2,7 @@
import { mapActions, mapState } from 'vuex';
import tooltip from '~/vue_shared/directives/tooltip';
import Icon from '~/vue_shared/components/icon.vue';
-import ResizablePanel from '../resizable_panel.vue';
-import { GlSkeletonLoading } from '@gitlab/ui';
+import IdeSidebarNav from '../ide_sidebar_nav.vue';
export default {
name: 'CollapsibleSidebar',
@@ -12,8 +11,7 @@ export default {
},
components: {
Icon,
- ResizablePanel,
- GlSkeletonLoading,
+ IdeSidebarNav,
},
props: {
extensionTabs: {
@@ -25,13 +23,8 @@ export default {
type: String,
required: true,
},
- width: {
- type: Number,
- required: true,
- },
},
computed: {
- ...mapState(['loading']),
...mapState({
isOpen(state) {
return state[this.namespace].isOpen;
@@ -39,9 +32,6 @@ export default {
currentView(state) {
return state[this.namespace].currentView;
},
- isActiveView(state, getters) {
- return getters[`${this.namespace}/isActiveView`];
- },
isAliveView(_state, getters) {
return getters[`${this.namespace}/isAliveView`];
},
@@ -59,9 +49,6 @@ export default {
aliveTabViews() {
return this.tabViews.filter(view => this.isAliveView(view.name));
},
- otherSide() {
- return this.side === 'right' ? 'left' : 'right';
- },
},
methods: {
...mapActions({
@@ -72,25 +59,6 @@ export default {
return dispatch(`${this.namespace}/open`, view);
},
}),
- clickTab(e, tab) {
- e.target.blur();
-
- if (this.isActiveTab(tab)) {
- this.toggleOpen();
- } else {
- this.open(tab.views[0]);
- }
- },
- isActiveTab(tab) {
- return tab.views.some(view => this.isActiveView(view.name));
- },
- buttonClasses(tab) {
- return [
- this.side === 'right' ? 'is-right' : '',
- this.isActiveTab(tab) && this.isOpen ? 'active' : '',
- ...(tab.buttonClasses || []),
- ];
- },
},
};
</script>
@@ -101,49 +69,27 @@ export default {
:data-qa-selector="`ide_${side}_sidebar`"
class="multi-file-commit-panel ide-sidebar"
>
- <resizable-panel
+ <div
v-show="isOpen"
- :initial-width="width"
- :min-size="width"
:class="`ide-${side}-sidebar-${currentView}`"
- :side="side"
class="multi-file-commit-panel-inner"
>
- <div class="h-100 d-flex flex-column align-items-stretch">
- <slot v-if="isOpen" name="header"></slot>
- <div
- v-for="tabView in aliveTabViews"
- v-show="isActiveView(tabView.name)"
- :key="tabView.name"
- class="flex-fill gl-overflow-hidden js-tab-view"
- >
- <component :is="tabView.component" />
- </div>
- <slot name="footer"></slot>
+ <div
+ v-for="tabView in aliveTabViews"
+ v-show="tabView.name === currentView"
+ :key="tabView.name"
+ class="flex-fill gl-overflow-hidden js-tab-view gl-h-full"
+ >
+ <component :is="tabView.component" />
</div>
- </resizable-panel>
- <nav class="ide-activity-bar">
- <ul class="list-unstyled">
- <li>
- <slot name="header-icon"></slot>
- </li>
- <li v-for="tab of tabs" :key="tab.title">
- <button
- v-tooltip
- :title="tab.title"
- :aria-label="tab.title"
- :class="buttonClasses(tab)"
- data-container="body"
- :data-placement="otherSide"
- :data-qa-selector="`${tab.title.toLowerCase()}_tab_button`"
- class="ide-sidebar-link"
- type="button"
- @click="clickTab($event, tab)"
- >
- <icon :size="16" :name="tab.icon" />
- </button>
- </li>
- </ul>
- </nav>
+ </div>
+ <ide-sidebar-nav
+ :tabs="tabs"
+ :side="side"
+ :current-view="currentView"
+ :is-open="isOpen"
+ @open="open"
+ @close="toggleOpen"
+ />
</div>
</template>
diff --git a/app/assets/javascripts/ide/components/panes/right.vue b/app/assets/javascripts/ide/components/panes/right.vue
index 4a9de9e0c03..46ef08a45a9 100644
--- a/app/assets/javascripts/ide/components/panes/right.vue
+++ b/app/assets/javascripts/ide/components/panes/right.vue
@@ -2,26 +2,27 @@
import { mapGetters, mapState } from 'vuex';
import { __ } from '~/locale';
import CollapsibleSidebar from './collapsible_sidebar.vue';
-import { rightSidebarViews } from '../../constants';
+import ResizablePanel from '../resizable_panel.vue';
+import { rightSidebarViews, SIDEBAR_INIT_WIDTH, SIDEBAR_NAV_WIDTH } from '../../constants';
import PipelinesList from '../pipelines/list.vue';
import JobsDetail from '../jobs/detail.vue';
import Clientside from '../preview/clientside.vue';
+import TerminalView from '../terminal/view.vue';
+
+// Need to add the width of the nav buttons since the resizable container contains those as well
+const WIDTH = SIDEBAR_INIT_WIDTH + SIDEBAR_NAV_WIDTH;
export default {
name: 'RightPane',
components: {
CollapsibleSidebar,
- },
- props: {
- extensionTabs: {
- type: Array,
- required: false,
- default: () => [],
- },
+ ResizablePanel,
},
computed: {
+ ...mapState('terminal', { isTerminalVisible: 'isVisible' }),
...mapState(['currentMergeRequestId', 'clientsidePreviewEnabled']),
...mapGetters(['packageJson']),
+ ...mapState('rightPane', ['isOpen']),
showLivePreview() {
return this.packageJson && this.clientsidePreviewEnabled;
},
@@ -42,13 +43,27 @@ export default {
views: [{ component: Clientside, ...rightSidebarViews.clientSidePreview }],
icon: 'live-preview',
},
- ...this.extensionTabs,
+ {
+ show: this.isTerminalVisible,
+ title: __('Terminal'),
+ views: [{ component: TerminalView, ...rightSidebarViews.terminal }],
+ icon: 'terminal',
+ },
];
},
},
+ WIDTH,
};
</script>
<template>
- <collapsible-sidebar :extension-tabs="rightExtensionTabs" side="right" :width="350" />
+ <resizable-panel
+ class="gl-display-flex gl-overflow-hidden"
+ side="right"
+ :initial-width="$options.WIDTH"
+ :min-size="$options.WIDTH"
+ :resizable="isOpen"
+ >
+ <collapsible-sidebar class="gl-w-full" :extension-tabs="rightExtensionTabs" side="right" />
+ </resizable-panel>
</template>
diff --git a/app/assets/javascripts/ide/components/pipelines/list.vue b/app/assets/javascripts/ide/components/pipelines/list.vue
index cf6d01b6351..6958a5d2526 100644
--- a/app/assets/javascripts/ide/components/pipelines/list.vue
+++ b/app/assets/javascripts/ide/components/pipelines/list.vue
@@ -63,7 +63,7 @@ export default {
<template v-else-if="hasLoadedPipeline">
<header v-if="latestPipeline" class="ide-tree-header ide-pipeline-header">
<ci-icon :status="latestPipeline.details.status" :size="24" class="d-flex" />
- <span class="prepend-left-8">
+ <span class="gl-ml-3">
<strong> {{ __('Pipeline') }} </strong>
<a
:href="latestPipeline.path"
@@ -82,9 +82,9 @@ export default {
class="mb-auto mt-auto"
/>
<div v-else-if="latestPipeline.yamlError" class="bs-callout bs-callout-danger">
- <p class="append-bottom-0">{{ __('Found errors in your .gitlab-ci.yml:') }}</p>
- <p class="append-bottom-0 break-word">{{ latestPipeline.yamlError }}</p>
- <p class="append-bottom-0" v-html="ciLintText"></p>
+ <p class="gl-mb-0">{{ __('Found errors in your .gitlab-ci.yml:') }}</p>
+ <p class="gl-mb-0 break-word">{{ latestPipeline.yamlError }}</p>
+ <p class="gl-mb-0" v-html="ciLintText"></p>
</div>
<tabs v-else class="ide-pipeline-list">
<tab :active="!pipelineFailed">
diff --git a/app/assets/javascripts/ide/components/preview/navigator.vue b/app/assets/javascripts/ide/components/preview/navigator.vue
index ff23485f0f0..0de9dfd8827 100644
--- a/app/assets/javascripts/ide/components/preview/navigator.vue
+++ b/app/assets/javascripts/ide/components/preview/navigator.vue
@@ -119,7 +119,7 @@ export default {
>
<icon :size="18" name="retry" class="m-auto" />
</button>
- <div class="position-relative w-100 prepend-left-4">
+ <div class="position-relative w-100 gl-ml-2">
<input
:value="path || '/'"
type="text"
diff --git a/app/assets/javascripts/ide/components/repo_commit_section.vue b/app/assets/javascripts/ide/components/repo_commit_section.vue
index 530fba49df2..5eed57bb6c5 100644
--- a/app/assets/javascripts/ide/components/repo_commit_section.vue
+++ b/app/assets/javascripts/ide/components/repo_commit_section.vue
@@ -3,7 +3,7 @@ import { mapState, mapActions, mapGetters } from 'vuex';
import tooltip from '~/vue_shared/directives/tooltip';
import CommitFilesList from './commit_sidebar/list.vue';
import EmptyState from './commit_sidebar/empty_state.vue';
-import { leftSidebarViews, stageKeys } from '../constants';
+import { stageKeys } from '../constants';
export default {
components: {
@@ -14,39 +14,37 @@ export default {
tooltip,
},
computed: {
- ...mapState(['changedFiles', 'stagedFiles', 'lastCommitMsg', 'unusedSeal']),
+ ...mapState(['changedFiles', 'stagedFiles', 'lastCommitMsg']),
...mapState('commit', ['commitMessage', 'submitCommitLoading']),
- ...mapGetters(['lastOpenedFile', 'hasChanges', 'someUncommittedChanges', 'activeFile']),
+ ...mapGetters(['lastOpenedFile', 'someUncommittedChanges', 'activeFile']),
...mapGetters('commit', ['discardDraftButtonDisabled']),
showStageUnstageArea() {
- return Boolean(this.someUncommittedChanges || this.lastCommitMsg || !this.unusedSeal);
+ return Boolean(this.someUncommittedChanges || this.lastCommitMsg);
},
activeFileKey() {
return this.activeFile ? this.activeFile.key : null;
},
},
- watch: {
- hasChanges() {
- if (!this.hasChanges) {
- this.updateActivityBarView(leftSidebarViews.edit.name);
- }
- },
- },
mounted() {
- if (this.lastOpenedFile && this.lastOpenedFile.type !== 'tree') {
- this.openPendingTab({
- file: this.lastOpenedFile,
- keyPrefix: this.lastOpenedFile.staged ? stageKeys.staged : stageKeys.unstaged,
+ const file =
+ this.lastOpenedFile && this.lastOpenedFile.type !== 'tree'
+ ? this.lastOpenedFile
+ : this.activeFile;
+
+ if (!file) return;
+
+ this.openPendingTab({
+ file,
+ keyPrefix: file.staged ? stageKeys.staged : stageKeys.unstaged,
+ })
+ .then(changeViewer => {
+ if (changeViewer) {
+ this.updateViewer('diff');
+ }
})
- .then(changeViewer => {
- if (changeViewer) {
- this.updateViewer('diff');
- }
- })
- .catch(e => {
- throw e;
- });
- }
+ .catch(e => {
+ throw e;
+ });
},
methods: {
...mapActions(['openPendingTab', 'updateViewer', 'updateActivityBarView']),
@@ -67,6 +65,6 @@ export default {
icon-name="unstaged"
/>
</template>
- <empty-state v-if="unusedSeal" />
+ <empty-state v-else />
</div>
</template>
diff --git a/app/assets/javascripts/ide/components/repo_editor.vue b/app/assets/javascripts/ide/components/repo_editor.vue
index c72a8b2b0d0..a7646083428 100644
--- a/app/assets/javascripts/ide/components/repo_editor.vue
+++ b/app/assets/javascripts/ide/components/repo_editor.vue
@@ -14,6 +14,9 @@ import Editor from '../lib/editor';
import FileTemplatesBar from './file_templates/bar.vue';
import { __ } from '~/locale';
import { extractMarkdownImagesFromEntries } from '../stores/utils';
+import { getPathParent, readFileAsDataURL } from '../utils';
+import { getRulesWithTraversal } from '../lib/editorconfig/parser';
+import mapRulesToMonaco from '../lib/editorconfig/rules_mapper';
export default {
components: {
@@ -31,6 +34,7 @@ export default {
return {
content: '',
images: {},
+ rules: {},
};
},
computed: {
@@ -50,7 +54,6 @@ export default {
'getStagedFile',
'isEditModeActive',
'isCommitModeActive',
- 'isReviewModeActive',
'currentBranch',
]),
...mapGetters('fileTemplates', ['showFileTemplatesBar']),
@@ -82,10 +85,6 @@ export default {
active: this.isPreviewViewMode,
};
},
- fileType() {
- const info = viewerInformationForPath(this.file.path);
- return (info && info.id) || '';
- },
showEditor() {
return !this.shouldHideEditor && this.isEditorViewMode;
},
@@ -98,6 +97,12 @@ export default {
currentBranchCommit() {
return this.currentBranch?.commit.id;
},
+ previewMode() {
+ return viewerInformationForPath(this.file.path);
+ },
+ fileType() {
+ return this.previewMode?.id || '';
+ },
},
watch: {
file(newVal, oldVal) {
@@ -165,6 +170,12 @@ export default {
this.editor = Editor.create(this.editorOptions);
}
this.initEditor();
+
+ // listen in capture phase to be able to override Monaco's behaviour.
+ window.addEventListener('paste', this.onPaste, true);
+ },
+ destroyed() {
+ window.removeEventListener('paste', this.onPaste, true);
},
methods: {
...mapActions([
@@ -174,10 +185,10 @@ export default {
'setFileLanguage',
'setEditorPosition',
'setFileViewMode',
- 'setFileEOL',
'updateViewer',
'removePendingTab',
'triggerFilesChange',
+ 'addTempImage',
]),
initEditor() {
if (this.shouldHideEditor && (this.file.content || this.file.raw)) {
@@ -186,7 +197,7 @@ export default {
this.editor.clearEditor();
- this.fetchFileData()
+ Promise.all([this.fetchFileData(), this.fetchEditorconfigRules()])
.then(() => {
this.createEditorInstance();
})
@@ -223,7 +234,7 @@ export default {
if (this.viewer === viewerTypes.edit) {
this.editor.createInstance(this.$refs.editor);
} else {
- this.editor.createDiffInstance(this.$refs.editor, !this.isReviewModeActive);
+ this.editor.createDiffInstance(this.$refs.editor);
}
this.setupEditor();
@@ -245,15 +256,15 @@ export default {
this.editor.attachModel(this.model);
}
+ this.model.updateOptions(this.rules);
+
this.model.onChange(model => {
const { file } = model;
+ if (!file.active) return;
- if (file.active) {
- this.changeFileContent({
- path: file.path,
- content: model.getModel().getValue(),
- });
- }
+ const monacoModel = model.getModel();
+ const content = monacoModel.getValue();
+ this.changeFileContent({ path: file.path, content });
});
// Handle Cursor Position
@@ -274,16 +285,51 @@ export default {
fileLanguage: this.model.language,
});
- // Get File eol
- this.setFileEOL({
- eol: this.model.eol,
- });
+ this.$emit('editorSetup');
},
refreshEditorDimensions() {
if (this.showEditor) {
this.editor.updateDimensions();
}
},
+ fetchEditorconfigRules() {
+ return getRulesWithTraversal(this.file.path, path => {
+ const entry = this.entries[path];
+ if (!entry) return Promise.resolve(null);
+
+ const content = entry.content || entry.raw;
+ if (content) return Promise.resolve(content);
+
+ return this.getFileData({ path: entry.path, makeFileActive: false }).then(() =>
+ this.getRawFileData({ path: entry.path }),
+ );
+ }).then(rules => {
+ this.rules = mapRulesToMonaco(rules);
+ });
+ },
+ onPaste(event) {
+ const editor = this.editor.instance;
+ const reImage = /^image\/(png|jpg|jpeg|gif)$/;
+ const file = event.clipboardData.files[0];
+
+ if (editor.hasTextFocus() && this.fileType === 'markdown' && reImage.test(file?.type)) {
+ // don't let the event be passed on to Monaco.
+ event.preventDefault();
+ event.stopImmediatePropagation();
+
+ return readFileAsDataURL(file).then(content => {
+ const parentPath = getPathParent(this.file.path);
+ const path = `${parentPath ? `${parentPath}/` : ''}${file.name}`;
+
+ return this.addTempImage({ name: path, rawPath: content }).then(({ name: fileName }) => {
+ this.editor.replaceSelectedText(`![${fileName}](./${fileName})`);
+ });
+ });
+ }
+
+ // do nothing if no image is found in the clipboard
+ return Promise.resolve();
+ },
},
viewerTypes,
FILE_VIEW_MODE_EDITOR,
@@ -301,16 +347,15 @@ export default {
role="button"
@click.prevent="setFileViewMode({ file, viewMode: $options.FILE_VIEW_MODE_EDITOR })"
>
- <template v-if="viewer === $options.viewerTypes.edit">{{ __('Edit') }}</template>
- <template v-else>{{ __('Review') }}</template>
+ {{ __('Edit') }}
</a>
</li>
- <li v-if="file.previewMode" :class="previewTabCSS">
+ <li v-if="previewMode" :class="previewTabCSS">
<a
href="javascript:void(0);"
role="button"
@click.prevent="setFileViewMode({ file, viewMode: $options.FILE_VIEW_MODE_PREVIEW })"
- >{{ file.previewMode.previewTitle }}</a
+ >{{ previewMode.previewTitle }}</a
>
</li>
</ul>
diff --git a/app/assets/javascripts/ide/components/repo_tabs.vue b/app/assets/javascripts/ide/components/repo_tabs.vue
index 1b7f149097b..47c75be3f7c 100644
--- a/app/assets/javascripts/ide/components/repo_tabs.vue
+++ b/app/assets/javascripts/ide/components/repo_tabs.vue
@@ -1,7 +1,6 @@
<script>
import { mapActions } from 'vuex';
import RepoTab from './repo_tab.vue';
-import router from '../ide_router';
export default {
components: {
@@ -20,15 +19,6 @@ export default {
type: String,
required: true,
},
- hasChanges: {
- type: Boolean,
- required: true,
- },
- mergeRequestId: {
- type: String,
- required: false,
- default: '',
- },
},
methods: {
...mapActions(['updateViewer', 'removePendingTab']),
@@ -37,7 +27,7 @@ export default {
if (this.activeFile.pending) {
return this.removePendingTab(this.activeFile).then(() => {
- router.push(`/project${this.activeFile.url}`);
+ this.$router.push(`/project${this.activeFile.url}`);
});
}
@@ -49,7 +39,7 @@ export default {
<template>
<div class="multi-file-tabs">
- <ul ref="tabsScroller" class="list-unstyled append-bottom-0">
+ <ul ref="tabsScroller" class="list-unstyled gl-mb-0">
<repo-tab v-for="tab in files" :key="tab.key" :tab="tab" />
</ul>
</div>
diff --git a/app/assets/javascripts/ide/components/resizable_panel.vue b/app/assets/javascripts/ide/components/resizable_panel.vue
index 86a4622401c..b49d743d877 100644
--- a/app/assets/javascripts/ide/components/resizable_panel.vue
+++ b/app/assets/javascripts/ide/components/resizable_panel.vue
@@ -1,6 +1,7 @@
<script>
import { mapActions } from 'vuex';
import PanelResizer from '~/vue_shared/components/panel_resizer.vue';
+import { SIDEBAR_MIN_WIDTH } from '../constants';
export default {
components: {
@@ -14,12 +15,17 @@ export default {
minSize: {
type: Number,
required: false,
- default: 340,
+ default: SIDEBAR_MIN_WIDTH,
},
side: {
type: String,
required: true,
},
+ resizable: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
},
data() {
return {
@@ -28,7 +34,7 @@ export default {
},
computed: {
panelStyle() {
- if (!this.collapsed) {
+ if (this.resizable) {
return {
width: `${this.width}px`,
};
@@ -45,9 +51,10 @@ export default {
</script>
<template>
- <div :style="panelStyle" class="multi-file-commit-panel">
+ <div class="gl-relative" :style="panelStyle">
<slot></slot>
<panel-resizer
+ v-show="resizable"
:size.sync="width"
:start-size="initialWidth"
:min-size="minSize"
diff --git a/app/assets/javascripts/ide/components/terminal/empty_state.vue b/app/assets/javascripts/ide/components/terminal/empty_state.vue
new file mode 100644
index 00000000000..9841f1ece48
--- /dev/null
+++ b/app/assets/javascripts/ide/components/terminal/empty_state.vue
@@ -0,0 +1,71 @@
+<script>
+import { GlLoadingIcon } from '@gitlab/ui';
+
+export default {
+ components: {
+ GlLoadingIcon,
+ },
+ props: {
+ isLoading: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
+ isValid: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ message: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ helpPath: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ illustrationPath: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ },
+ methods: {
+ onStart() {
+ this.$emit('start');
+ },
+ },
+};
+</script>
+<template>
+ <div class="text-center p-3">
+ <div v-if="illustrationPath" class="svg-content svg-130"><img :src="illustrationPath" /></div>
+ <h4>{{ __('Web Terminal') }}</h4>
+ <gl-loading-icon v-if="isLoading" size="lg" class="prepend-top-default" />
+ <template v-else>
+ <p>{{ __('Run tests against your code live using the Web Terminal') }}</p>
+ <p>
+ <button
+ :disabled="!isValid"
+ class="btn btn-info"
+ type="button"
+ data-qa-selector="start_web_terminal_button"
+ @click="onStart"
+ >
+ {{ __('Start Web Terminal') }}
+ </button>
+ </p>
+ <div v-if="!isValid && message" class="bs-callout text-left" v-html="message"></div>
+ <p v-else>
+ <a
+ v-if="helpPath"
+ :href="helpPath"
+ target="_blank"
+ v-text="__('Learn more about Web Terminal')"
+ ></a>
+ </p>
+ </template>
+ </div>
+</template>
diff --git a/app/assets/javascripts/ide/components/terminal/session.vue b/app/assets/javascripts/ide/components/terminal/session.vue
new file mode 100644
index 00000000000..a8fe9ea6866
--- /dev/null
+++ b/app/assets/javascripts/ide/components/terminal/session.vue
@@ -0,0 +1,53 @@
+<script>
+import { mapActions, mapState } from 'vuex';
+import { __ } from '~/locale';
+import Terminal from './terminal.vue';
+import { isEndingStatus } from '../../stores/modules/terminal/utils';
+
+export default {
+ components: {
+ Terminal,
+ },
+ computed: {
+ ...mapState('terminal', ['session']),
+ actionButton() {
+ if (isEndingStatus(this.session.status)) {
+ return {
+ action: () => this.restartSession(),
+ text: __('Restart Terminal'),
+ class: 'btn-primary',
+ };
+ }
+
+ return {
+ action: () => this.stopSession(),
+ text: __('Stop Terminal'),
+ class: 'btn-inverted btn-remove',
+ };
+ },
+ },
+ methods: {
+ ...mapActions('terminal', ['restartSession', 'stopSession']),
+ },
+};
+</script>
+
+<template>
+ <div v-if="session" class="ide-terminal d-flex flex-column">
+ <header class="ide-job-header d-flex align-items-center">
+ <h5>{{ __('Web Terminal') }}</h5>
+ <div class="ml-auto align-self-center">
+ <button
+ v-if="actionButton"
+ type="button"
+ class="btn btn-sm"
+ :class="actionButton.class"
+ @click="actionButton.action"
+ >
+ {{ actionButton.text }}
+ </button>
+ </div>
+ </header>
+ <terminal :terminal-path="session.terminalPath" :status="session.status" />
+ </div>
+</template>
diff --git a/app/assets/javascripts/ide/components/terminal/terminal.vue b/app/assets/javascripts/ide/components/terminal/terminal.vue
new file mode 100644
index 00000000000..0ee4107f9ab
--- /dev/null
+++ b/app/assets/javascripts/ide/components/terminal/terminal.vue
@@ -0,0 +1,117 @@
+<script>
+import { mapState } from 'vuex';
+import { GlLoadingIcon } from '@gitlab/ui';
+import { __ } from '~/locale';
+import GLTerminal from '~/terminal/terminal';
+import TerminalControls from './terminal_controls.vue';
+import { RUNNING, STOPPING } from '../../stores/modules/terminal/constants';
+import { isStartingStatus } from '../../stores/modules/terminal/utils';
+
+export default {
+ components: {
+ GlLoadingIcon,
+ TerminalControls,
+ },
+ props: {
+ terminalPath: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ status: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ glterminal: null,
+ canScrollUp: false,
+ canScrollDown: false,
+ };
+ },
+ computed: {
+ ...mapState(['panelResizing']),
+ loadingText() {
+ if (isStartingStatus(this.status)) {
+ return __('Starting...');
+ } else if (this.status === STOPPING) {
+ return __('Stopping...');
+ }
+
+ return '';
+ },
+ },
+ watch: {
+ panelResizing() {
+ if (!this.panelResizing && this.glterminal) {
+ this.glterminal.fit();
+ }
+ },
+ status() {
+ this.refresh();
+ },
+ terminalPath() {
+ this.refresh();
+ },
+ },
+ beforeDestroy() {
+ this.destroyTerminal();
+ },
+ methods: {
+ refresh() {
+ if (this.status === RUNNING && this.terminalPath) {
+ this.createTerminal();
+ } else if (this.status === STOPPING) {
+ this.stopTerminal();
+ }
+ },
+ createTerminal() {
+ this.destroyTerminal();
+ this.glterminal = new GLTerminal(this.$refs.terminal);
+ this.glterminal.addScrollListener(({ canScrollUp, canScrollDown }) => {
+ this.canScrollUp = canScrollUp;
+ this.canScrollDown = canScrollDown;
+ });
+ },
+ destroyTerminal() {
+ if (this.glterminal) {
+ this.glterminal.dispose();
+ this.glterminal = null;
+ }
+ },
+ stopTerminal() {
+ if (this.glterminal) {
+ this.glterminal.disable();
+ }
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="d-flex flex-column flex-fill min-height-0 pr-3">
+ <div class="top-bar d-flex border-left-0 align-items-center">
+ <div v-if="loadingText" data-qa-selector="loading_container">
+ <gl-loading-icon :inline="true" />
+ <span>{{ loadingText }}</span>
+ </div>
+ <terminal-controls
+ v-if="glterminal"
+ class="ml-auto"
+ :can-scroll-up="canScrollUp"
+ :can-scroll-down="canScrollDown"
+ @scroll-up="glterminal.scrollToTop()"
+ @scroll-down="glterminal.scrollToBottom()"
+ />
+ </div>
+ <div class="terminal-wrapper d-flex flex-fill min-height-0">
+ <div
+ ref="terminal"
+ class="ide-terminal-trace flex-fill min-height-0 w-100"
+ :data-project-path="terminalPath"
+ data-qa-selector="terminal_screen"
+ ></div>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/ide/components/terminal/terminal_controls.vue b/app/assets/javascripts/ide/components/terminal/terminal_controls.vue
new file mode 100644
index 00000000000..4c13b4ef103
--- /dev/null
+++ b/app/assets/javascripts/ide/components/terminal/terminal_controls.vue
@@ -0,0 +1,27 @@
+<script>
+import ScrollButton from '~/ide/components/jobs/detail/scroll_button.vue';
+
+export default {
+ components: {
+ ScrollButton,
+ },
+ props: {
+ canScrollUp: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ canScrollDown: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+};
+</script>
+<template>
+ <div class="controllers">
+ <scroll-button :disabled="!canScrollUp" direction="up" @click="$emit('scroll-up')" />
+ <scroll-button :disabled="!canScrollDown" direction="down" @click="$emit('scroll-down')" />
+ </div>
+</template>
diff --git a/app/assets/javascripts/ide/components/terminal/view.vue b/app/assets/javascripts/ide/components/terminal/view.vue
new file mode 100644
index 00000000000..db97e95eed9
--- /dev/null
+++ b/app/assets/javascripts/ide/components/terminal/view.vue
@@ -0,0 +1,41 @@
+<script>
+import { mapActions, mapGetters, mapState } from 'vuex';
+import EmptyState from './empty_state.vue';
+import TerminalSession from './session.vue';
+
+export default {
+ components: {
+ EmptyState,
+ TerminalSession,
+ },
+ computed: {
+ ...mapState('terminal', ['isShowSplash', 'paths']),
+ ...mapGetters('terminal', ['allCheck']),
+ },
+ methods: {
+ ...mapActions('terminal', ['startSession', 'hideSplash']),
+ start() {
+ this.startSession();
+ this.hideSplash();
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="h-100">
+ <div v-if="isShowSplash" class="h-100 d-flex flex-column justify-content-center">
+ <empty-state
+ :is-loading="allCheck.isLoading"
+ :is-valid="allCheck.isValid"
+ :message="allCheck.message"
+ :help-path="paths.webTerminalHelpPath"
+ :illustration-path="paths.webTerminalSvgPath"
+ @start="start()"
+ />
+ </div>
+ <template v-else>
+ <terminal-session />
+ </template>
+ </div>
+</template>
diff --git a/app/assets/javascripts/ide/components/terminal_sync/terminal_sync_status.vue b/app/assets/javascripts/ide/components/terminal_sync/terminal_sync_status.vue
new file mode 100644
index 00000000000..deb13b5615e
--- /dev/null
+++ b/app/assets/javascripts/ide/components/terminal_sync/terminal_sync_status.vue
@@ -0,0 +1,76 @@
+<script>
+import { throttle } from 'lodash';
+import { GlTooltipDirective, GlLoadingIcon } from '@gitlab/ui';
+import { mapState } from 'vuex';
+import Icon from '~/vue_shared/components/icon.vue';
+import {
+ MSG_TERMINAL_SYNC_CONNECTING,
+ MSG_TERMINAL_SYNC_UPLOADING,
+ MSG_TERMINAL_SYNC_RUNNING,
+} from '../../stores/modules/terminal_sync/messages';
+
+export default {
+ components: {
+ Icon,
+ GlLoadingIcon,
+ },
+ directives: {
+ 'gl-tooltip': GlTooltipDirective,
+ },
+ data() {
+ return { isLoading: false };
+ },
+ computed: {
+ ...mapState('terminalSync', ['isError', 'isStarted', 'message']),
+ ...mapState('terminalSync', {
+ isLoadingState: 'isLoading',
+ }),
+ status() {
+ if (this.isLoading) {
+ return {
+ icon: '',
+ text: this.isStarted ? MSG_TERMINAL_SYNC_UPLOADING : MSG_TERMINAL_SYNC_CONNECTING,
+ };
+ } else if (this.isError) {
+ return {
+ icon: 'warning',
+ text: this.message,
+ };
+ } else if (this.isStarted) {
+ return {
+ icon: 'mobile-issue-close',
+ text: MSG_TERMINAL_SYNC_RUNNING,
+ };
+ }
+
+ return null;
+ },
+ },
+ watch: {
+ // We want to throttle the `isLoading` updates so that
+ // the user actually sees an indicator that changes are sent.
+ isLoadingState: throttle(function watchIsLoadingState(val) {
+ this.isLoading = val;
+ }, 150),
+ },
+ created() {
+ this.isLoading = this.isLoadingState;
+ },
+};
+</script>
+
+<template>
+ <div
+ v-if="status"
+ v-gl-tooltip
+ :title="status.text"
+ role="note"
+ class="d-flex align-items-center"
+ >
+ <span>{{ __('Terminal') }}:</span>
+ <span class="square s16 d-flex-center ml-1" :aria-label="status.text">
+ <gl-loading-icon v-if="isLoading" inline size="sm" class="d-flex-center" />
+ <icon v-else-if="status.icon" :name="status.icon" :size="16" />
+ </span>
+ </div>
+</template>
diff --git a/app/assets/javascripts/ide/components/terminal_sync/terminal_sync_status_safe.vue b/app/assets/javascripts/ide/components/terminal_sync/terminal_sync_status_safe.vue
new file mode 100644
index 00000000000..afaf06f7f68
--- /dev/null
+++ b/app/assets/javascripts/ide/components/terminal_sync/terminal_sync_status_safe.vue
@@ -0,0 +1,22 @@
+<script>
+import { mapState } from 'vuex';
+import TerminalSyncStatus from './terminal_sync_status.vue';
+
+/**
+ * It is possible that the vuex module is not registered.
+ *
+ * This component will gracefully handle this so the actual one can simply use `mapState(moduleName, ...)`.
+ */
+export default {
+ components: {
+ TerminalSyncStatus,
+ },
+ computed: {
+ ...mapState(['terminalSync']),
+ },
+};
+</script>
+
+<template>
+ <terminal-sync-status v-if="terminalSync" />
+</template>
diff --git a/app/assets/javascripts/ide/constants.js b/app/assets/javascripts/ide/constants.js
index ae8550cba76..59b1969face 100644
--- a/app/assets/javascripts/ide/constants.js
+++ b/app/assets/javascripts/ide/constants.js
@@ -4,6 +4,10 @@ export const MAX_WINDOW_HEIGHT_COMPACT = 750;
export const MAX_TITLE_LENGTH = 50;
export const MAX_BODY_LENGTH = 72;
+export const SIDEBAR_INIT_WIDTH = 340;
+export const SIDEBAR_MIN_WIDTH = 340;
+export const SIDEBAR_NAV_WIDTH = 60;
+
// File view modes
export const FILE_VIEW_MODE_EDITOR = 'editor';
export const FILE_VIEW_MODE_PREVIEW = 'preview';
@@ -53,6 +57,7 @@ export const rightSidebarViews = {
jobsDetail: { name: 'jobs-detail', keepAlive: false },
mergeRequestInfo: { name: 'merge-request-info', keepAlive: true },
clientSidePreview: { name: 'clientside', keepAlive: false },
+ terminal: { name: 'terminal', keepAlive: true },
};
export const stageKeys = {
@@ -89,3 +94,6 @@ export const commitActionTypes = {
};
export const packageJsonPath = 'package.json';
+
+export const SIDE_LEFT = 'left';
+export const SIDE_RIGHT = 'right';
diff --git a/app/assets/javascripts/ide/ide_router.js b/app/assets/javascripts/ide/ide_router.js
index 0fab3ee0f3b..152f77effa3 100644
--- a/app/assets/javascripts/ide/ide_router.js
+++ b/app/assets/javascripts/ide/ide_router.js
@@ -2,8 +2,8 @@ import Vue from 'vue';
import IdeRouter from '~/ide/ide_router_extension';
import { joinPaths } from '~/lib/utils/url_utility';
import flash from '~/flash';
-import store from './stores';
import { __ } from '~/locale';
+import { syncRouterAndStore } from './sync_router_and_store';
Vue.use(IdeRouter);
@@ -33,80 +33,85 @@ const EmptyRouterComponent = {
},
};
-const router = new IdeRouter({
- mode: 'history',
- base: joinPaths(gon.relative_url_root || '', '/-/ide/'),
- routes: [
- {
- path: '/project/:namespace+/:project',
- component: EmptyRouterComponent,
- children: [
- {
- path: ':targetmode(edit|tree|blob)/:branchid+/-/*',
- component: EmptyRouterComponent,
- },
- {
- path: ':targetmode(edit|tree|blob)/:branchid+/',
- redirect: to => joinPaths(to.path, '/-/'),
- },
- {
- path: ':targetmode(edit|tree|blob)',
- redirect: to => joinPaths(to.path, '/master/-/'),
- },
- {
- path: 'merge_requests/:mrid',
- component: EmptyRouterComponent,
- },
- {
- path: '',
- redirect: to => joinPaths(to.path, '/edit/master/-/'),
- },
- ],
- },
- ],
-});
+// eslint-disable-next-line import/prefer-default-export
+export const createRouter = store => {
+ const router = new IdeRouter({
+ mode: 'history',
+ base: joinPaths(gon.relative_url_root || '', '/-/ide/'),
+ routes: [
+ {
+ path: '/project/:namespace+/:project',
+ component: EmptyRouterComponent,
+ children: [
+ {
+ path: ':targetmode(edit|tree|blob)/:branchid+/-/*',
+ component: EmptyRouterComponent,
+ },
+ {
+ path: ':targetmode(edit|tree|blob)/:branchid+/',
+ redirect: to => joinPaths(to.path, '/-/'),
+ },
+ {
+ path: ':targetmode(edit|tree|blob)',
+ redirect: to => joinPaths(to.path, '/master/-/'),
+ },
+ {
+ path: 'merge_requests/:mrid',
+ component: EmptyRouterComponent,
+ },
+ {
+ path: '',
+ redirect: to => joinPaths(to.path, '/edit/master/-/'),
+ },
+ ],
+ },
+ ],
+ });
-router.beforeEach((to, from, next) => {
- if (to.params.namespace && to.params.project) {
- store
- .dispatch('getProjectData', {
- namespace: to.params.namespace,
- projectId: to.params.project,
- })
- .then(() => {
- const basePath = to.params.pathMatch || '';
- const projectId = `${to.params.namespace}/${to.params.project}`;
- const branchId = to.params.branchid;
- const mergeRequestId = to.params.mrid;
+ router.beforeEach((to, from, next) => {
+ if (to.params.namespace && to.params.project) {
+ store
+ .dispatch('getProjectData', {
+ namespace: to.params.namespace,
+ projectId: to.params.project,
+ })
+ .then(() => {
+ const basePath = to.params.pathMatch || '';
+ const projectId = `${to.params.namespace}/${to.params.project}`;
+ const branchId = to.params.branchid;
+ const mergeRequestId = to.params.mrid;
- if (branchId) {
- store.dispatch('openBranch', {
- projectId,
- branchId,
- basePath,
- });
- } else if (mergeRequestId) {
- store.dispatch('openMergeRequest', {
- projectId,
- mergeRequestId,
- targetProjectId: to.query.target_project,
- });
- }
- })
- .catch(e => {
- flash(
- __('Error while loading the project data. Please try again.'),
- 'alert',
- document,
- null,
- false,
- true,
- );
- throw e;
- });
- }
+ if (branchId) {
+ store.dispatch('openBranch', {
+ projectId,
+ branchId,
+ basePath,
+ });
+ } else if (mergeRequestId) {
+ store.dispatch('openMergeRequest', {
+ projectId,
+ mergeRequestId,
+ targetProjectId: to.query.target_project,
+ });
+ }
+ })
+ .catch(e => {
+ flash(
+ __('Error while loading the project data. Please try again.'),
+ 'alert',
+ document,
+ null,
+ false,
+ true,
+ );
+ throw e;
+ });
+ }
- next();
-});
+ next();
+ });
-export default router;
+ syncRouterAndStore(router, store);
+
+ return router;
+};
diff --git a/app/assets/javascripts/ide/index.js b/app/assets/javascripts/ide/index.js
index 55a0dd848c8..850cfcb05e3 100644
--- a/app/assets/javascripts/ide/index.js
+++ b/app/assets/javascripts/ide/index.js
@@ -4,7 +4,7 @@ import Translate from '~/vue_shared/translate';
import { identity } from 'lodash';
import ide from './components/ide.vue';
import store from './stores';
-import router from './ide_router';
+import { createRouter } from './ide_router';
import { parseBoolean } from '../lib/utils/common_utils';
import { resetServiceWorkersPublicPath } from '../lib/utils/webpack';
import { DEFAULT_THEME } from './lib/themes';
@@ -32,6 +32,7 @@ export function initIde(el, options = {}) {
if (!el) return null;
const { rootComponent = ide, extendStore = identity } = options;
+ const router = createRouter(store);
return new Vue({
el,
diff --git a/app/assets/javascripts/ide/lib/common/model.js b/app/assets/javascripts/ide/lib/common/model.js
index a15f04075d9..c5bb00c3dee 100644
--- a/app/assets/javascripts/ide/lib/common/model.js
+++ b/app/assets/javascripts/ide/lib/common/model.js
@@ -1,6 +1,8 @@
import { editor as monacoEditor, Uri } from 'monaco-editor';
import Disposable from './disposable';
import eventHub from '../../eventhub';
+import { trimTrailingWhitespace, insertFinalNewline } from '../../utils';
+import { defaultModelOptions } from '../editor_options';
export default class Model {
constructor(file, head = null) {
@@ -8,6 +10,7 @@ export default class Model {
this.file = file;
this.head = head;
this.content = file.content !== '' || file.deleted ? file.content : file.raw;
+ this.options = { ...defaultModelOptions };
this.disposable.add(
(this.originalModel = monacoEditor.createModel(
@@ -50,10 +53,6 @@ export default class Model {
return this.model.getModeId();
}
- get eol() {
- return this.model.getEOL() === '\n' ? 'LF' : 'CRLF';
- }
-
get path() {
return this.file.key;
}
@@ -94,8 +93,32 @@ export default class Model {
this.getModel().setValue(content);
}
+ updateOptions(obj = {}) {
+ Object.assign(this.options, obj);
+ this.model.updateOptions(obj);
+ this.applyCustomOptions();
+ }
+
+ applyCustomOptions() {
+ this.updateNewContent(
+ Object.entries(this.options).reduce((content, [key, value]) => {
+ switch (key) {
+ case 'endOfLine':
+ this.model.pushEOL(value);
+ return this.model.getValue();
+ case 'insertFinalNewline':
+ return value ? insertFinalNewline(content) : content;
+ case 'trimTrailingWhitespace':
+ return value ? trimTrailingWhitespace(content) : content;
+ default:
+ return content;
+ }
+ }, this.model.getValue()),
+ );
+ }
+
dispose() {
- this.disposable.dispose();
+ if (!this.model.isDisposed()) this.applyCustomOptions();
this.events.forEach(cb => {
if (typeof cb === 'function') cb();
@@ -106,5 +129,7 @@ export default class Model {
eventHub.$off(`editor.update.model.dispose.${this.file.key}`, this.dispose);
eventHub.$off(`editor.update.model.content.${this.file.key}`, this.updateContent);
eventHub.$off(`editor.update.model.new.content.${this.file.key}`, this.updateNewContent);
+
+ this.disposable.dispose();
}
}
diff --git a/app/assets/javascripts/ide/lib/create_diff.js b/app/assets/javascripts/ide/lib/create_diff.js
new file mode 100644
index 00000000000..3e915afdbcb
--- /dev/null
+++ b/app/assets/javascripts/ide/lib/create_diff.js
@@ -0,0 +1,85 @@
+import { commitActionForFile } from '~/ide/stores/utils';
+import { commitActionTypes } from '~/ide/constants';
+import createFileDiff from './create_file_diff';
+
+const getDeletedParents = (entries, file) => {
+ const parent = file.parentPath && entries[file.parentPath];
+
+ if (parent && parent.deleted) {
+ return [parent, ...getDeletedParents(entries, parent)];
+ }
+
+ return [];
+};
+
+const filesWithChanges = ({ stagedFiles = [], changedFiles = [], entries = {} }) => {
+ // We need changed files to overwrite staged, so put them at the end.
+ const changes = stagedFiles.concat(changedFiles).reduce((acc, file) => {
+ const key = file.path;
+ const action = commitActionForFile(file);
+ const prev = acc[key];
+
+ // If a file was deleted, which was previously added, then we should do nothing.
+ if (action === commitActionTypes.delete && prev && prev.action === commitActionTypes.create) {
+ delete acc[key];
+ } else {
+ acc[key] = { action, file };
+ }
+
+ return acc;
+ }, {});
+
+ // We need to clean "move" actions, because we can only support 100% similarity moves at the moment.
+ // This is because the previous file's content might not be loaded.
+ Object.values(changes)
+ .filter(change => change.action === commitActionTypes.move)
+ .forEach(change => {
+ const prev = changes[change.file.prevPath];
+
+ if (!prev) {
+ return;
+ }
+
+ if (change.file.content === prev.file.content) {
+ // If content is the same, continue with the move but don't do the prevPath's delete.
+ delete changes[change.file.prevPath];
+ } else {
+ // Otherwise, treat the move as a delete / create.
+ Object.assign(change, { action: commitActionTypes.create });
+ }
+ });
+
+ // Next, we need to add deleted directories by looking at the parents
+ Object.values(changes)
+ .filter(change => change.action === commitActionTypes.delete && change.file.parentPath)
+ .forEach(({ file }) => {
+ // Do nothing if we've already visited this directory.
+ if (changes[file.parentPath]) {
+ return;
+ }
+
+ getDeletedParents(entries, file).forEach(parent => {
+ changes[parent.path] = { action: commitActionTypes.delete, file: parent };
+ });
+ });
+
+ return Object.values(changes);
+};
+
+const createDiff = state => {
+ const changes = filesWithChanges(state);
+
+ const toDelete = changes.filter(x => x.action === commitActionTypes.delete).map(x => x.file.path);
+
+ const patch = changes
+ .filter(x => x.action !== commitActionTypes.delete)
+ .map(({ file, action }) => createFileDiff(file, action))
+ .join('');
+
+ return {
+ patch,
+ toDelete,
+ };
+};
+
+export default createDiff;
diff --git a/app/assets/javascripts/ide/lib/create_file_diff.js b/app/assets/javascripts/ide/lib/create_file_diff.js
new file mode 100644
index 00000000000..5ae4993321c
--- /dev/null
+++ b/app/assets/javascripts/ide/lib/create_file_diff.js
@@ -0,0 +1,112 @@
+/* eslint-disable @gitlab/require-i18n-strings */
+import { createTwoFilesPatch } from 'diff';
+import { commitActionTypes } from '~/ide/constants';
+
+const DEV_NULL = '/dev/null';
+const DEFAULT_MODE = '100644';
+const NO_NEW_LINE = '\\ No newline at end of file';
+const NEW_LINE = '\n';
+
+/**
+ * Cleans patch generated by `diff` package.
+ *
+ * - Removes "=======" separator added at the beginning
+ */
+const cleanTwoFilesPatch = text => text.replace(/^(=+\s*)/, '');
+
+const endsWithNewLine = val => !val || val[val.length - 1] === NEW_LINE;
+
+const addEndingNewLine = val => (endsWithNewLine(val) ? val : val + NEW_LINE);
+
+const removeEndingNewLine = val => (endsWithNewLine(val) ? val.substr(0, val.length - 1) : val);
+
+const diffHead = (prevPath, newPath = '') =>
+ `diff --git "a/${prevPath}" "b/${newPath || prevPath}"`;
+
+const createDiffBody = (path, content, isCreate) => {
+ if (!content) {
+ return '';
+ }
+
+ const prefix = isCreate ? '+' : '-';
+ const fromPath = isCreate ? DEV_NULL : `a/${path}`;
+ const toPath = isCreate ? `b/${path}` : DEV_NULL;
+
+ const hasNewLine = endsWithNewLine(content);
+ const lines = removeEndingNewLine(content).split(NEW_LINE);
+
+ const chunkHead = isCreate ? `@@ -0,0 +1,${lines.length} @@` : `@@ -1,${lines.length} +0,0 @@`;
+ const chunk = lines
+ .map(line => `${prefix}${line}`)
+ .concat(!hasNewLine ? [NO_NEW_LINE] : [])
+ .join(NEW_LINE);
+
+ return `--- ${fromPath}
++++ ${toPath}
+${chunkHead}
+${chunk}`;
+};
+
+const createMoveFileDiff = (prevPath, newPath) => `${diffHead(prevPath, newPath)}
+rename from ${prevPath}
+rename to ${newPath}`;
+
+const createNewFileDiff = (path, content) => {
+ const diff = createDiffBody(path, content, true);
+
+ return `${diffHead(path)}
+new file mode ${DEFAULT_MODE}
+${diff}`;
+};
+
+const createDeleteFileDiff = (path, content) => {
+ const diff = createDiffBody(path, content, false);
+
+ return `${diffHead(path)}
+deleted file mode ${DEFAULT_MODE}
+${diff}`;
+};
+
+const createUpdateFileDiff = (path, oldContent, newContent) => {
+ const patch = createTwoFilesPatch(`a/${path}`, `b/${path}`, oldContent, newContent);
+
+ return `${diffHead(path)}
+${cleanTwoFilesPatch(patch)}`;
+};
+
+const createFileDiffRaw = (file, action) => {
+ switch (action) {
+ case commitActionTypes.move:
+ return createMoveFileDiff(file.prevPath, file.path);
+ case commitActionTypes.create:
+ return createNewFileDiff(file.path, file.content);
+ case commitActionTypes.delete:
+ return createDeleteFileDiff(file.path, file.content);
+ case commitActionTypes.update:
+ return createUpdateFileDiff(file.path, file.raw || '', file.content);
+ default:
+ return '';
+ }
+};
+
+/**
+ * Create a git diff for a single IDE file.
+ *
+ * ## Notes:
+ * When called with `commitActionType.move`, it assumes that the move
+ * is a 100% similarity move. No diff will be generated. This is because
+ * generating a move with changes is not support by the current IDE, since
+ * the source file might not have it's content loaded yet.
+ *
+ * When called with `commitActionType.delete`, it does not support
+ * deleting files with a mode different than 100644. For the IDE mirror, this
+ * isn't needed because deleting is handled outside the unified patch.
+ *
+ * ## References:
+ * - https://git-scm.com/docs/git-diff#_generating_patches_with_p
+ */
+const createFileDiff = (file, action) =>
+ // It's important that the file diff ends in a new line - git expects this.
+ addEndingNewLine(createFileDiffRaw(file, action));
+
+export default createFileDiff;
diff --git a/app/assets/javascripts/ide/lib/diff/controller.js b/app/assets/javascripts/ide/lib/diff/controller.js
index 234a7f903a1..35fcda6a6c5 100644
--- a/app/assets/javascripts/ide/lib/diff/controller.js
+++ b/app/assets/javascripts/ide/lib/diff/controller.js
@@ -50,10 +50,15 @@ export default class DirtyDiffController {
}
computeDiff(model) {
+ const originalModel = model.getOriginalModel();
+ const newModel = model.getModel();
+
+ if (originalModel.isDisposed() || newModel.isDisposed()) return;
+
this.dirtyDiffWorker.postMessage({
path: model.path,
- originalContent: model.getOriginalModel().getValue(),
- newContent: model.getModel().getValue(),
+ originalContent: originalModel.getValue(),
+ newContent: newModel.getValue(),
});
}
diff --git a/app/assets/javascripts/ide/lib/diff/diff.js b/app/assets/javascripts/ide/lib/diff/diff.js
index 29e29d7fcd3..3a456b7c4d6 100644
--- a/app/assets/javascripts/ide/lib/diff/diff.js
+++ b/app/assets/javascripts/ide/lib/diff/diff.js
@@ -1,8 +1,15 @@
import { diffLines } from 'diff';
+import { defaultDiffOptions } from '../editor_options';
+// See: https://gitlab.com/gitlab-org/frontend/rfcs/-/issues/20
// eslint-disable-next-line import/prefer-default-export
export const computeDiff = (originalContent, newContent) => {
- const changes = diffLines(originalContent, newContent);
+ // prevent EOL changes from highlighting the entire file
+ const changes = diffLines(
+ originalContent.replace(/\r\n/g, '\n'),
+ newContent.replace(/\r\n/g, '\n'),
+ defaultDiffOptions,
+ );
let lineNumber = 1;
return changes.reduce((acc, change) => {
diff --git a/app/assets/javascripts/ide/lib/editor.js b/app/assets/javascripts/ide/lib/editor.js
index 25224abd77c..4dfc27117c0 100644
--- a/app/assets/javascripts/ide/lib/editor.js
+++ b/app/assets/javascripts/ide/lib/editor.js
@@ -1,11 +1,11 @@
import { debounce } from 'lodash';
-import { editor as monacoEditor, KeyCode, KeyMod } from 'monaco-editor';
+import { editor as monacoEditor, KeyCode, KeyMod, Range } from 'monaco-editor';
import store from '../stores';
import DecorationsController from './decorations/controller';
import DirtyDiffController from './diff/controller';
import Disposable from './common/disposable';
import ModelManager from './common/model_manager';
-import editorOptions, { defaultEditorOptions } from './editor_options';
+import { editorOptions, defaultEditorOptions, defaultDiffEditorOptions } from './editor_options';
import { themes } from './themes';
import languages from './languages';
import keymap from './keymap.json';
@@ -37,6 +37,10 @@ export default class Editor {
...defaultEditorOptions,
...options,
};
+ this.diffOptions = {
+ ...defaultDiffEditorOptions,
+ ...options,
+ };
setupThemes();
registerLanguages(...languages);
@@ -66,19 +70,14 @@ export default class Editor {
}
}
- createDiffInstance(domElement, readOnly = true) {
+ createDiffInstance(domElement) {
if (!this.instance) {
clearDomElement(domElement);
this.disposable.add(
(this.instance = monacoEditor.createDiffEditor(domElement, {
- ...this.options,
- quickSuggestions: false,
- occurrencesHighlight: false,
+ ...this.diffOptions,
renderSideBySide: Editor.renderSideBySide(domElement),
- readOnly,
- renderLineHighlight: readOnly ? 'all' : 'none',
- hideCursorInOverviewRuler: !readOnly,
})),
);
@@ -187,6 +186,21 @@ export default class Editor {
});
}
+ replaceSelectedText(text) {
+ let selection = this.instance.getSelection();
+ const range = new Range(
+ selection.startLineNumber,
+ selection.startColumn,
+ selection.endLineNumber,
+ selection.endColumn,
+ );
+
+ this.instance.executeEdits('', [{ range, text }]);
+
+ selection = this.instance.getSelection();
+ this.instance.setPosition({ lineNumber: selection.endLineNumber, column: selection.endColumn });
+ }
+
get isDiffEditorType() {
return this.instance.getEditorType() === 'vs.editor.IDiffEditor';
}
diff --git a/app/assets/javascripts/ide/lib/editor_options.js b/app/assets/javascripts/ide/lib/editor_options.js
index dac2a8e8b51..f182a1ec50e 100644
--- a/app/assets/javascripts/ide/lib/editor_options.js
+++ b/app/assets/javascripts/ide/lib/editor_options.js
@@ -9,7 +9,27 @@ export const defaultEditorOptions = {
wordWrap: 'on',
};
-export default [
+export const defaultDiffOptions = {
+ ignoreWhitespace: false,
+};
+
+export const defaultDiffEditorOptions = {
+ ...defaultEditorOptions,
+ quickSuggestions: false,
+ occurrencesHighlight: false,
+ ignoreTrimWhitespace: false,
+ readOnly: false,
+ renderLineHighlight: 'none',
+ hideCursorInOverviewRuler: true,
+};
+
+export const defaultModelOptions = {
+ endOfLine: 0,
+ insertFinalNewline: true,
+ trimTrailingWhitespace: false,
+};
+
+export const editorOptions = [
{
readOnly: model => Boolean(model.file.file_lock),
quickSuggestions: model => !(model.language === 'markdown'),
diff --git a/app/assets/javascripts/ide/lib/editorconfig/parser.js b/app/assets/javascripts/ide/lib/editorconfig/parser.js
new file mode 100644
index 00000000000..a30a8cb868d
--- /dev/null
+++ b/app/assets/javascripts/ide/lib/editorconfig/parser.js
@@ -0,0 +1,55 @@
+import { parseString } from 'editorconfig/src/lib/ini';
+import minimatch from 'minimatch';
+import { getPathParents } from '../../utils';
+
+const dirname = path => path.replace(/\.editorconfig$/, '');
+
+function isRootConfig(config) {
+ return config.some(([pattern, rules]) => !pattern && rules?.root === 'true');
+}
+
+function getRulesForSection(path, [pattern, rules]) {
+ if (!pattern) {
+ return {};
+ }
+ if (minimatch(path, pattern, { matchBase: true })) {
+ return rules;
+ }
+
+ return {};
+}
+
+function getRulesWithConfigs(filePath, configFiles = [], rules = {}) {
+ if (!configFiles.length) return rules;
+
+ const [{ content, path: configPath }, ...nextConfigs] = configFiles;
+ const configDir = dirname(configPath);
+
+ if (!filePath.startsWith(configDir)) return rules;
+
+ const parsed = parseString(content);
+ const isRoot = isRootConfig(parsed);
+ const relativeFilePath = filePath.slice(configDir.length);
+
+ const sectionRules = parsed.reduce(
+ (acc, section) => Object.assign(acc, getRulesForSection(relativeFilePath, section)),
+ {},
+ );
+
+ // prefer existing rules by overwriting to section rules
+ const result = Object.assign(sectionRules, rules);
+
+ return isRoot ? result : getRulesWithConfigs(filePath, nextConfigs, result);
+}
+
+// eslint-disable-next-line import/prefer-default-export
+export function getRulesWithTraversal(filePath, getFileContent) {
+ const editorconfigPaths = [
+ ...getPathParents(filePath).map(x => `${x}/.editorconfig`),
+ '.editorconfig',
+ ];
+
+ return Promise.all(
+ editorconfigPaths.map(path => getFileContent(path).then(content => ({ path, content }))),
+ ).then(results => getRulesWithConfigs(filePath, results.filter(x => x.content)));
+}
diff --git a/app/assets/javascripts/ide/lib/editorconfig/rules_mapper.js b/app/assets/javascripts/ide/lib/editorconfig/rules_mapper.js
new file mode 100644
index 00000000000..f9d5579511a
--- /dev/null
+++ b/app/assets/javascripts/ide/lib/editorconfig/rules_mapper.js
@@ -0,0 +1,33 @@
+import { isBoolean, isNumber } from 'lodash';
+
+const map = (key, validValues) => value =>
+ value in validValues ? { [key]: validValues[value] } : {};
+
+const bool = key => value => (isBoolean(value) ? { [key]: value } : {});
+
+const int = (key, isValid) => value =>
+ isNumber(value) && isValid(value) ? { [key]: Math.trunc(value) } : {};
+
+const rulesMapper = {
+ indent_style: map('insertSpaces', { tab: false, space: true }),
+ indent_size: int('tabSize', n => n > 0),
+ tab_width: int('tabSize', n => n > 0),
+ trim_trailing_whitespace: bool('trimTrailingWhitespace'),
+ end_of_line: map('endOfLine', { crlf: 1, lf: 0 }),
+ insert_final_newline: bool('insertFinalNewline'),
+};
+
+const parseValue = x => {
+ let value = typeof x === 'string' ? x.toLowerCase() : x;
+ if (/^[0-9.-]+$/.test(value)) value = Number(value);
+ if (value === 'true') value = true;
+ if (value === 'false') value = false;
+
+ return value;
+};
+
+export default function mapRulesToMonaco(rules) {
+ return Object.entries(rules).reduce((obj, [key, value]) => {
+ return Object.assign(obj, rulesMapper[key]?.(parseValue(value)) || {});
+ }, {});
+}
diff --git a/app/assets/javascripts/ide/lib/files.js b/app/assets/javascripts/ide/lib/files.js
index 26518a2abac..6d85e225fd5 100644
--- a/app/assets/javascripts/ide/lib/files.js
+++ b/app/assets/javascripts/ide/lib/files.js
@@ -19,7 +19,6 @@ export const decorateFiles = ({
branchId,
tempFile = false,
content = '',
- base64 = false,
binary = false,
rawPath = '',
}) => {
@@ -49,7 +48,6 @@ export const decorateFiles = ({
path,
url: `/${projectId}/tree/${branchId}/-/${path}/`,
type: 'tree',
- parentTreeUrl: parentFolder ? parentFolder.url : `/${projectId}/tree/${branchId}/`,
tempFile,
changed: tempFile,
opened: tempFile,
@@ -86,14 +84,11 @@ export const decorateFiles = ({
path,
url: `/${projectId}/blob/${branchId}/-/${path}`,
type: 'blob',
- parentTreeUrl: fileFolder ? fileFolder.url : `/${projectId}/blob/${branchId}`,
tempFile,
changed: tempFile,
content,
- base64,
binary: (previewMode && previewMode.binary) || binary,
rawPath,
- previewMode,
parentPath,
});
diff --git a/app/assets/javascripts/ide/lib/languages/README.md b/app/assets/javascripts/ide/lib/languages/README.md
new file mode 100644
index 00000000000..e4d1a4c7818
--- /dev/null
+++ b/app/assets/javascripts/ide/lib/languages/README.md
@@ -0,0 +1,21 @@
+# Web IDE Languages
+
+The Web IDE uses the [Monaco editor](https://microsoft.github.io/monaco-editor/) which uses the [Monarch library](https://microsoft.github.io/monaco-editor/monarch.html) for syntax highlighting.
+The Web IDE currently supports all langauges defined in the [monaco-languages](https://github.com/microsoft/monaco-languages/tree/master/src) repository.
+
+## Adding New Languages
+
+While Monaco supports a wide variety of languages, there's always the chance that it's missing something.
+You'll find a list of [unsupported languages in this epic](https://gitlab.com/groups/gitlab-org/-/epics/1474), which is the right place to add more if needed.
+
+Should you be willing to help us and add support to GitLab for any missing languages, here are the steps to do so:
+
+1. Create a new issue and add it to [this epic](https://gitlab.com/groups/gitlab-org/-/epics/1474), if it doesn't already exist.
+2. Create a new file in this folder called `{languageName}.js`, where `{languageName}` is the name of the language you want to add support for.
+3. Follow the [Monarch documentation](https://microsoft.github.io/monaco-editor/monarch.html) to add a configuration for the new language.
+ - Example: The [`vue.js`](./vue.js) file in the current directory adds support for Vue.js Syntax Highlighting.
+4. Add tests for the new langauge implementation in `spec/frontend/ide/lib/languages/{langaugeName}.js`.
+ - Example: See [`vue_spec.js`](spec/frontend/ide/lib/languages/vue_spec.js).
+5. Create a [Merge Request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) with your newly added language.
+
+Thank you!
diff --git a/app/assets/javascripts/ide/lib/mirror.js b/app/assets/javascripts/ide/lib/mirror.js
new file mode 100644
index 00000000000..a516c28ad7a
--- /dev/null
+++ b/app/assets/javascripts/ide/lib/mirror.js
@@ -0,0 +1,154 @@
+import createDiff from './create_diff';
+import { getWebSocketUrl, mergeUrlParams } from '~/lib/utils/url_utility';
+import { __ } from '~/locale';
+
+export const SERVICE_NAME = 'webide-file-sync';
+export const PROTOCOL = 'webfilesync.gitlab.com';
+export const MSG_CONNECTION_ERROR = __('Could not connect to Web IDE file mirror service.');
+
+// Before actually connecting to the service, we must delay a bit
+// so that the service has sufficiently started.
+
+const noop = () => {};
+export const SERVICE_DELAY = 8000;
+
+const cancellableWait = time => {
+ let timeoutId = 0;
+
+ const cancel = () => clearTimeout(timeoutId);
+
+ const promise = new Promise(resolve => {
+ timeoutId = setTimeout(resolve, time);
+ });
+
+ return [promise, cancel];
+};
+
+const isErrorResponse = error => error && error.code !== 0;
+
+const isErrorPayload = payload => payload && payload.status_code !== 200;
+
+const getErrorFromResponse = data => {
+ if (isErrorResponse(data.error)) {
+ return { message: data.error.Message };
+ } else if (isErrorPayload(data.payload)) {
+ return { message: data.payload.error_message };
+ }
+
+ return null;
+};
+
+const getFullPath = path => mergeUrlParams({ service: SERVICE_NAME }, getWebSocketUrl(path));
+
+const createWebSocket = fullPath =>
+ new Promise((resolve, reject) => {
+ const socket = new WebSocket(fullPath, [PROTOCOL]);
+ const resetCallbacks = () => {
+ socket.onopen = null;
+ socket.onerror = null;
+ };
+
+ socket.onopen = () => {
+ resetCallbacks();
+ resolve(socket);
+ };
+
+ socket.onerror = () => {
+ resetCallbacks();
+ reject(new Error(MSG_CONNECTION_ERROR));
+ };
+ });
+
+export const canConnect = ({ services = [] }) => services.some(name => name === SERVICE_NAME);
+
+export const createMirror = () => {
+ let socket = null;
+ let cancelHandler = noop;
+ let nextMessageHandler = noop;
+
+ const cancelConnect = () => {
+ cancelHandler();
+ cancelHandler = noop;
+ };
+
+ const onCancelConnect = fn => {
+ cancelHandler = fn;
+ };
+
+ const receiveMessage = ev => {
+ const handle = nextMessageHandler;
+ nextMessageHandler = noop;
+ handle(JSON.parse(ev.data));
+ };
+
+ const onNextMessage = fn => {
+ nextMessageHandler = fn;
+ };
+
+ const waitForNextMessage = () =>
+ new Promise((resolve, reject) => {
+ onNextMessage(data => {
+ const err = getErrorFromResponse(data);
+
+ if (err) {
+ reject(err);
+ } else {
+ resolve();
+ }
+ });
+ });
+
+ const uploadDiff = ({ toDelete, patch }) => {
+ if (!socket) {
+ return Promise.resolve();
+ }
+
+ const response = waitForNextMessage();
+
+ const msg = {
+ code: 'EVENT',
+ namespace: '/files',
+ event: 'PATCH',
+ payload: { diff: patch, delete_files: toDelete },
+ };
+
+ socket.send(JSON.stringify(msg));
+
+ return response;
+ };
+
+ return {
+ upload(state) {
+ return uploadDiff(createDiff(state));
+ },
+ connect(path) {
+ if (socket) {
+ this.disconnect();
+ }
+
+ const fullPath = getFullPath(path);
+ const [wait, cancelWait] = cancellableWait(SERVICE_DELAY);
+
+ onCancelConnect(cancelWait);
+
+ return wait
+ .then(() => createWebSocket(fullPath))
+ .then(newSocket => {
+ socket = newSocket;
+ socket.onmessage = receiveMessage;
+ });
+ },
+ disconnect() {
+ cancelConnect();
+
+ if (!socket) {
+ return;
+ }
+
+ socket.close();
+ socket = null;
+ },
+ };
+};
+
+export default createMirror();
diff --git a/app/assets/javascripts/ide/services/terminals.js b/app/assets/javascripts/ide/services/terminals.js
new file mode 100644
index 00000000000..17b4329037d
--- /dev/null
+++ b/app/assets/javascripts/ide/services/terminals.js
@@ -0,0 +1,15 @@
+import axios from '~/lib/utils/axios_utils';
+
+export const baseUrl = projectPath => `/${projectPath}/ide_terminals`;
+
+export const checkConfig = (projectPath, branch) =>
+ axios.post(`${baseUrl(projectPath)}/check_config`, {
+ branch,
+ format: 'json',
+ });
+
+export const create = (projectPath, branch) =>
+ axios.post(baseUrl(projectPath), {
+ branch,
+ format: 'json',
+ });
diff --git a/app/assets/javascripts/ide/stores/actions.js b/app/assets/javascripts/ide/stores/actions.js
index e32b5ac7bdc..c881f1221e5 100644
--- a/app/assets/javascripts/ide/stores/actions.js
+++ b/app/assets/javascripts/ide/stores/actions.js
@@ -7,7 +7,6 @@ import * as types from './mutation_types';
import { decorateFiles } from '../lib/files';
import { stageKeys } from '../constants';
import service from '../services';
-import router from '../ide_router';
import eventHub from '../eventhub';
export const redirectToUrl = (self, url) => visitUrl(url);
@@ -20,21 +19,25 @@ export const discardAllChanges = ({ state, commit, dispatch }) => {
commit(types.REMOVE_ALL_CHANGES_FILES);
};
-export const closeAllFiles = ({ state, dispatch }) => {
- state.openFiles.forEach(file => dispatch('closeFile', file));
-};
-
export const setResizingStatus = ({ commit }, resizing) => {
commit(types.SET_RESIZING_STATUS, resizing);
};
export const createTempEntry = (
{ state, commit, dispatch, getters },
- { name, type, content = '', base64 = false, binary = false, rawPath = '' },
+ {
+ name,
+ type,
+ content = '',
+ binary = false,
+ rawPath = '',
+ openFile = true,
+ makeFileActive = true,
+ },
) => {
const fullName = name.slice(-1) !== '/' && type === 'tree' ? `${name}/` : name;
- if (state.entries[name] && !state.entries[name].deleted) {
+ if (getters.entryExists(name)) {
flash(
sprintf(__('The name "%{name}" is already taken in this directory.'), {
name: name.split('/').pop(),
@@ -46,7 +49,7 @@ export const createTempEntry = (
true,
);
- return;
+ return undefined;
}
const data = decorateFiles({
@@ -56,7 +59,6 @@ export const createTempEntry = (
type,
tempFile: true,
content,
- base64,
binary,
rawPath,
});
@@ -69,18 +71,31 @@ export const createTempEntry = (
});
if (type === 'blob') {
- commit(types.TOGGLE_FILE_OPEN, file.path);
+ if (openFile) commit(types.TOGGLE_FILE_OPEN, file.path);
commit(types.STAGE_CHANGE, { path: file.path, diffInfo: getters.getDiffInfo(file.path) });
- dispatch('setFileActive', file.path);
+ if (openFile && makeFileActive) dispatch('setFileActive', file.path);
dispatch('triggerFilesChange');
}
if (parentPath && !state.entries[parentPath].opened) {
commit(types.TOGGLE_TREE_OPEN, parentPath);
}
+
+ return file;
};
+export const addTempImage = ({ dispatch, getters }, { name, rawPath = '' }) =>
+ dispatch('createTempEntry', {
+ name: getters.getAvailableFileName(name),
+ type: 'blob',
+ content: rawPath.split('base64,')[1],
+ binary: true,
+ rawPath,
+ openFile: false,
+ makeFileActive: false,
+ });
+
export const scrollToTab = () => {
Vue.nextTick(() => {
const tabs = document.getElementById('tabs');
@@ -239,7 +254,7 @@ export const renameEntry = ({ dispatch, commit, state, getters }, { path, name,
}
if (newEntry.opened) {
- router.push(`/project${newEntry.url}`);
+ dispatch('router/push', `/project${newEntry.url}`, { root: true });
}
}
@@ -297,6 +312,3 @@ export * from './actions/tree';
export * from './actions/file';
export * from './actions/project';
export * from './actions/merge_request';
-
-// prevent babel-plugin-rewire from generating an invalid default during karma tests
-export default () => {};
diff --git a/app/assets/javascripts/ide/stores/actions/file.js b/app/assets/javascripts/ide/stores/actions/file.js
index da7d4a44bde..47f9337a288 100644
--- a/app/assets/javascripts/ide/stores/actions/file.js
+++ b/app/assets/javascripts/ide/stores/actions/file.js
@@ -3,8 +3,7 @@ import { __ } from '~/locale';
import eventHub from '../../eventhub';
import service from '../../services';
import * as types from '../mutation_types';
-import router from '../../ide_router';
-import { addFinalNewlineIfNeeded, setPageTitleForFile } from '../utils';
+import { setPageTitleForFile } from '../utils';
import { viewerTypes, stageKeys } from '../../constants';
export const closeFile = ({ commit, state, dispatch }, file) => {
@@ -30,10 +29,10 @@ export const closeFile = ({ commit, state, dispatch }, file) => {
keyPrefix: nextFileToOpen.staged ? 'staged' : 'unstaged',
});
} else {
- router.push(`/project${nextFileToOpen.url}`);
+ dispatch('router/push', `/project${nextFileToOpen.url}`, { root: true });
}
} else if (!state.openFiles.length) {
- router.push(`/project/${file.projectId}/tree/${file.branchId}/`);
+ dispatch('router/push', `/project/${file.projectId}/tree/${file.branchId}/`, { root: true });
}
eventHub.$emit(`editor.update.model.dispose.${file.key}`);
@@ -152,7 +151,7 @@ export const changeFileContent = ({ commit, state, getters }, { path, content })
const file = state.entries[path];
commit(types.UPDATE_FILE_CONTENT, {
path,
- content: addFinalNewlineIfNeeded(content),
+ content,
});
const indexOfChangedFile = state.changedFiles.findIndex(f => f.path === path);
@@ -170,12 +169,6 @@ export const setFileLanguage = ({ getters, commit }, { fileLanguage }) => {
}
};
-export const setFileEOL = ({ getters, commit }, { eol }) => {
- if (getters.activeFile) {
- commit(types.SET_FILE_EOL, { file: getters.activeFile, eol });
- }
-};
-
export const setEditorPosition = ({ getters, commit }, { editorRow, editorColumn }) => {
if (getters.activeFile) {
commit(types.SET_FILE_POSITION, {
@@ -226,7 +219,7 @@ export const discardFileChanges = ({ dispatch, state, commit, getters }, path) =
if (!isDestructiveDiscard && file.path === getters.activeFile?.path) {
dispatch('updateDelayViewerUpdated', true)
.then(() => {
- router.push(`/project${file.url}`);
+ dispatch('router/push', `/project${file.url}`, { root: true });
})
.catch(e => {
throw e;
@@ -275,14 +268,16 @@ export const unstageChange = ({ commit, dispatch, getters }, path) => {
}
};
-export const openPendingTab = ({ commit, getters, state }, { file, keyPrefix }) => {
+export const openPendingTab = ({ commit, dispatch, getters, state }, { file, keyPrefix }) => {
if (getters.activeFile && getters.activeFile.key === `${keyPrefix}-${file.key}`) return false;
state.openFiles.forEach(f => eventHub.$emit(`editor.update.model.dispose.${f.key}`));
commit(types.ADD_PENDING_TAB, { file, keyPrefix });
- router.push(`/project/${file.projectId}/tree/${state.currentBranchId}/`);
+ dispatch('router/push', `/project/${file.projectId}/tree/${state.currentBranchId}/`, {
+ root: true,
+ });
return true;
};
diff --git a/app/assets/javascripts/ide/stores/actions/project.js b/app/assets/javascripts/ide/stores/actions/project.js
index 6c8fb9f90aa..d172bb31ae5 100644
--- a/app/assets/javascripts/ide/stores/actions/project.js
+++ b/app/assets/javascripts/ide/stores/actions/project.js
@@ -4,7 +4,6 @@ import { __, sprintf } from '~/locale';
import service from '../../services';
import api from '../../../api';
import * as types from '../mutation_types';
-import router from '../../ide_router';
export const getProjectData = ({ commit, state }, { namespace, projectId, force = false } = {}) =>
new Promise((resolve, reject) => {
@@ -57,7 +56,7 @@ export const createNewBranchFromDefault = ({ state, dispatch, getters }, branch)
})
.then(() => {
dispatch('setErrorMessage', null);
- router.push(`${router.currentRoute.path}?${Date.now()}`);
+ window.location.reload();
})
.catch(() => {
dispatch('setErrorMessage', {
diff --git a/app/assets/javascripts/ide/stores/extend.js b/app/assets/javascripts/ide/stores/extend.js
new file mode 100644
index 00000000000..1c1636cf6ca
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/extend.js
@@ -0,0 +1,14 @@
+import terminal from './plugins/terminal';
+import terminalSync from './plugins/terminal_sync';
+
+const plugins = () => [
+ terminal,
+ ...(gon.features && gon.features.buildServiceProxy ? [terminalSync] : []),
+];
+
+export default (store, el) => {
+ // plugins is actually an array of plugin factories, so we have to create first then call
+ plugins().forEach(plugin => plugin(el)(store));
+
+ return store;
+};
diff --git a/app/assets/javascripts/ide/stores/getters.js b/app/assets/javascripts/ide/stores/getters.js
index 5d0a8570906..53734fa626b 100644
--- a/app/assets/javascripts/ide/stores/getters.js
+++ b/app/assets/javascripts/ide/stores/getters.js
@@ -50,9 +50,6 @@ export const emptyRepo = state =>
export const currentTree = state =>
state.trees[`${state.currentProjectId}/${state.currentBranchId}`];
-export const hasChanges = state =>
- Boolean(state.changedFiles.length) || Boolean(state.stagedFiles.length);
-
export const hasMergeRequest = state => Boolean(state.currentMergeRequestId);
export const allBlobs = state =>
@@ -162,5 +159,18 @@ export const canCreateMergeRequests = (state, getters) =>
export const canPushCode = (state, getters) =>
Boolean(getters.findProjectPermissions(state.currentProjectId)[PERMISSION_PUSH_CODE]);
-// prevent babel-plugin-rewire from generating an invalid default during karma tests
-export default () => {};
+export const entryExists = state => path =>
+ Boolean(state.entries[path] && !state.entries[path].deleted);
+
+export const getAvailableFileName = (state, getters) => path => {
+ let newPath = path;
+
+ while (getters.entryExists(newPath)) {
+ newPath = newPath.replace(
+ /([ _-]?)(\d*)(\..+?$|$)/,
+ (_, before, number, after) => `${before || '_'}${Number(number) + 1}${after}`,
+ );
+ }
+
+ return newPath;
+};
diff --git a/app/assets/javascripts/ide/stores/index.js b/app/assets/javascripts/ide/stores/index.js
index 85550578e94..18c466cc93d 100644
--- a/app/assets/javascripts/ide/stores/index.js
+++ b/app/assets/javascripts/ide/stores/index.js
@@ -11,24 +11,27 @@ import branches from './modules/branches';
import fileTemplates from './modules/file_templates';
import paneModule from './modules/pane';
import clientsideModule from './modules/clientside';
+import routerModule from './modules/router';
Vue.use(Vuex);
-export const createStore = () =>
- new Vuex.Store({
- state: state(),
- actions,
- mutations,
- getters,
- modules: {
- commit: commitModule,
- pipelines,
- mergeRequests,
- branches,
- fileTemplates: fileTemplates(),
- rightPane: paneModule(),
- clientside: clientsideModule(),
- },
- });
+export const createStoreOptions = () => ({
+ state: state(),
+ actions,
+ mutations,
+ getters,
+ modules: {
+ commit: commitModule,
+ pipelines,
+ mergeRequests,
+ branches,
+ fileTemplates: fileTemplates(),
+ rightPane: paneModule(),
+ clientside: clientsideModule(),
+ router: routerModule,
+ },
+});
+
+export const createStore = () => new Vuex.Store(createStoreOptions());
export default createStore();
diff --git a/app/assets/javascripts/ide/stores/modules/branches/index.js b/app/assets/javascripts/ide/stores/modules/branches/index.js
index 04e7e0f08f1..deda95cd0c9 100644
--- a/app/assets/javascripts/ide/stores/modules/branches/index.js
+++ b/app/assets/javascripts/ide/stores/modules/branches/index.js
@@ -4,7 +4,7 @@ import mutations from './mutations';
export default {
namespaced: true,
- state: state(),
+ state,
actions,
mutations,
};
diff --git a/app/assets/javascripts/ide/stores/modules/clientside/actions.js b/app/assets/javascripts/ide/stores/modules/clientside/actions.js
index eb3bcdff2ae..2bebf8b90ce 100644
--- a/app/assets/javascripts/ide/stores/modules/clientside/actions.js
+++ b/app/assets/javascripts/ide/stores/modules/clientside/actions.js
@@ -8,5 +8,4 @@ export const pingUsage = ({ rootGetters }) => {
return axios.post(url);
};
-// prevent babel-plugin-rewire from generating an invalid default during karma tests
-export default () => {};
+export default pingUsage;
diff --git a/app/assets/javascripts/ide/stores/modules/commit/actions.js b/app/assets/javascripts/ide/stores/modules/commit/actions.js
index 592c7e15918..005bd0240e2 100644
--- a/app/assets/javascripts/ide/stores/modules/commit/actions.js
+++ b/app/assets/javascripts/ide/stores/modules/commit/actions.js
@@ -3,7 +3,6 @@ import flash from '~/flash';
import httpStatusCodes from '~/lib/utils/http_status';
import * as rootTypes from '../../mutation_types';
import { createCommitPayload, createNewMergeRequestUrl } from '../../utils';
-import router from '../../../ide_router';
import service from '../../../services';
import * as types from './mutation_types';
import consts from './constants';
@@ -196,8 +195,10 @@ export const commitChanges = ({ commit, state, getters, dispatch, rootState, roo
dispatch('updateViewer', 'editor', { root: true });
if (rootGetters.activeFile) {
- router.push(
+ dispatch(
+ 'router/push',
`/project/${rootState.currentProjectId}/blob/${branchName}/-/${rootGetters.activeFile.path}`,
+ { root: true },
);
}
}
@@ -234,6 +235,3 @@ export const commitChanges = ({ commit, state, getters, dispatch, rootState, roo
window.dispatchEvent(new Event('resize'));
});
};
-
-// prevent babel-plugin-rewire from generating an invalid default during karma tests
-export default () => {};
diff --git a/app/assets/javascripts/ide/stores/modules/commit/getters.js b/app/assets/javascripts/ide/stores/modules/commit/getters.js
index 413c4b0110d..37f887bcf0a 100644
--- a/app/assets/javascripts/ide/stores/modules/commit/getters.js
+++ b/app/assets/javascripts/ide/stores/modules/commit/getters.js
@@ -59,6 +59,3 @@ export const shouldDisableNewMrOption = (state, getters, rootState, rootGetters)
export const shouldCreateMR = (state, getters) =>
state.shouldCreateMR && !getters.shouldDisableNewMrOption;
-
-// prevent babel-plugin-rewire from generating an invalid default during karma tests
-export default () => {};
diff --git a/app/assets/javascripts/ide/stores/modules/commit/index.js b/app/assets/javascripts/ide/stores/modules/commit/index.js
index 3bf65b02847..5cec73bde2e 100644
--- a/app/assets/javascripts/ide/stores/modules/commit/index.js
+++ b/app/assets/javascripts/ide/stores/modules/commit/index.js
@@ -5,7 +5,7 @@ import * as getters from './getters';
export default {
namespaced: true,
- state: state(),
+ state,
mutations,
actions,
getters,
diff --git a/app/assets/javascripts/ide/stores/modules/file_templates/actions.js b/app/assets/javascripts/ide/stores/modules/file_templates/actions.js
index 59ead8a3dcf..6b2c929cd44 100644
--- a/app/assets/javascripts/ide/stores/modules/file_templates/actions.js
+++ b/app/assets/javascripts/ide/stores/modules/file_templates/actions.js
@@ -117,6 +117,3 @@ export const undoFileTemplate = ({ dispatch, commit, rootGetters }) => {
dispatch('discardFileChanges', file.path, { root: true });
}
};
-
-// prevent babel-plugin-rewire from generating an invalid default during karma tests
-export default () => {};
diff --git a/app/assets/javascripts/ide/stores/modules/pane/actions.js b/app/assets/javascripts/ide/stores/modules/pane/actions.js
index a8fcdf539ec..b7cff368fe4 100644
--- a/app/assets/javascripts/ide/stores/modules/pane/actions.js
+++ b/app/assets/javascripts/ide/stores/modules/pane/actions.js
@@ -25,6 +25,3 @@ export const open = ({ state, commit }, view) => {
export const close = ({ commit }) => {
commit(types.SET_OPEN, false);
};
-
-// prevent babel-plugin-rewire from generating an invalid default during karma tests
-export default () => {};
diff --git a/app/assets/javascripts/ide/stores/modules/pane/getters.js b/app/assets/javascripts/ide/stores/modules/pane/getters.js
index c346cf13689..7816172bb6f 100644
--- a/app/assets/javascripts/ide/stores/modules/pane/getters.js
+++ b/app/assets/javascripts/ide/stores/modules/pane/getters.js
@@ -1,4 +1,3 @@
-export const isActiveView = state => view => state.currentView === view;
-
-export const isAliveView = (state, getters) => view =>
- state.keepAliveViews[view] || (state.isOpen && getters.isActiveView(view));
+// eslint-disable-next-line import/prefer-default-export
+export const isAliveView = state => view =>
+ state.keepAliveViews[view] || (state.isOpen && state.currentView === view);
diff --git a/app/assets/javascripts/ide/stores/modules/router/actions.js b/app/assets/javascripts/ide/stores/modules/router/actions.js
new file mode 100644
index 00000000000..849067599f2
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/router/actions.js
@@ -0,0 +1,6 @@
+import * as types from './mutation_types';
+
+// eslint-disable-next-line import/prefer-default-export
+export const push = ({ commit }, fullPath) => {
+ commit(types.PUSH, fullPath);
+};
diff --git a/app/assets/javascripts/ide/stores/modules/router/index.js b/app/assets/javascripts/ide/stores/modules/router/index.js
new file mode 100644
index 00000000000..68c81bb4509
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/router/index.js
@@ -0,0 +1,10 @@
+import state from './state';
+import mutations from './mutations';
+import * as actions from './actions';
+
+export default {
+ namespaced: true,
+ state,
+ mutations,
+ actions,
+};
diff --git a/app/assets/javascripts/ide/stores/modules/router/mutation_types.js b/app/assets/javascripts/ide/stores/modules/router/mutation_types.js
new file mode 100644
index 00000000000..ae99073cc4c
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/router/mutation_types.js
@@ -0,0 +1,2 @@
+// eslint-disable-next-line import/prefer-default-export
+export const PUSH = 'PUSH';
diff --git a/app/assets/javascripts/ide/stores/modules/router/mutations.js b/app/assets/javascripts/ide/stores/modules/router/mutations.js
new file mode 100644
index 00000000000..471cace314c
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/router/mutations.js
@@ -0,0 +1,7 @@
+import * as types from './mutation_types';
+
+export default {
+ [types.PUSH](state, fullPath) {
+ state.fullPath = fullPath;
+ },
+};
diff --git a/app/assets/javascripts/ide/stores/modules/router/state.js b/app/assets/javascripts/ide/stores/modules/router/state.js
new file mode 100644
index 00000000000..abb6c5239e4
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/router/state.js
@@ -0,0 +1,3 @@
+export default () => ({
+ fullPath: '',
+});
diff --git a/app/assets/javascripts/ide/stores/modules/terminal/actions/checks.js b/app/assets/javascripts/ide/stores/modules/terminal/actions/checks.js
new file mode 100644
index 00000000000..43b6650b241
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/terminal/actions/checks.js
@@ -0,0 +1,98 @@
+import Api from '~/api';
+import httpStatus from '~/lib/utils/http_status';
+import * as types from '../mutation_types';
+import * as messages from '../messages';
+import { CHECK_CONFIG, CHECK_RUNNERS, RETRY_RUNNERS_INTERVAL } from '../constants';
+import * as terminalService from '../../../../services/terminals';
+
+export const requestConfigCheck = ({ commit }) => {
+ commit(types.REQUEST_CHECK, CHECK_CONFIG);
+};
+
+export const receiveConfigCheckSuccess = ({ commit }) => {
+ commit(types.SET_VISIBLE, true);
+ commit(types.RECEIVE_CHECK_SUCCESS, CHECK_CONFIG);
+};
+
+export const receiveConfigCheckError = ({ commit, state }, e) => {
+ const { status } = e.response;
+ const { paths } = state;
+
+ const isVisible = status !== httpStatus.FORBIDDEN && status !== httpStatus.NOT_FOUND;
+ commit(types.SET_VISIBLE, isVisible);
+
+ const message = messages.configCheckError(status, paths.webTerminalConfigHelpPath);
+ commit(types.RECEIVE_CHECK_ERROR, { type: CHECK_CONFIG, message });
+};
+
+export const fetchConfigCheck = ({ dispatch, rootState, rootGetters }) => {
+ dispatch('requestConfigCheck');
+
+ const { currentBranchId } = rootState;
+ const { currentProject } = rootGetters;
+
+ terminalService
+ .checkConfig(currentProject.path_with_namespace, currentBranchId)
+ .then(() => {
+ dispatch('receiveConfigCheckSuccess');
+ })
+ .catch(e => {
+ dispatch('receiveConfigCheckError', e);
+ });
+};
+
+export const requestRunnersCheck = ({ commit }) => {
+ commit(types.REQUEST_CHECK, CHECK_RUNNERS);
+};
+
+export const receiveRunnersCheckSuccess = ({ commit, dispatch, state }, data) => {
+ if (data.length) {
+ commit(types.RECEIVE_CHECK_SUCCESS, CHECK_RUNNERS);
+ } else {
+ const { paths } = state;
+
+ commit(types.RECEIVE_CHECK_ERROR, {
+ type: CHECK_RUNNERS,
+ message: messages.runnersCheckEmpty(paths.webTerminalRunnersHelpPath),
+ });
+
+ dispatch('retryRunnersCheck');
+ }
+};
+
+export const receiveRunnersCheckError = ({ commit }) => {
+ commit(types.RECEIVE_CHECK_ERROR, {
+ type: CHECK_RUNNERS,
+ message: messages.UNEXPECTED_ERROR_RUNNERS,
+ });
+};
+
+export const retryRunnersCheck = ({ dispatch, state }) => {
+ // if the overall check has failed, don't worry about retrying
+ const check = state.checks[CHECK_CONFIG];
+ if (!check.isLoading && !check.isValid) {
+ return;
+ }
+
+ setTimeout(() => {
+ dispatch('fetchRunnersCheck', { background: true });
+ }, RETRY_RUNNERS_INTERVAL);
+};
+
+export const fetchRunnersCheck = ({ dispatch, rootGetters }, options = {}) => {
+ const { background = false } = options;
+
+ if (!background) {
+ dispatch('requestRunnersCheck');
+ }
+
+ const { currentProject } = rootGetters;
+
+ Api.projectRunners(currentProject.id, { params: { scope: 'active' } })
+ .then(({ data }) => {
+ dispatch('receiveRunnersCheckSuccess', data);
+ })
+ .catch(e => {
+ dispatch('receiveRunnersCheckError', e);
+ });
+};
diff --git a/app/assets/javascripts/ide/stores/modules/terminal/actions/index.js b/app/assets/javascripts/ide/stores/modules/terminal/actions/index.js
new file mode 100644
index 00000000000..112b3794114
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/terminal/actions/index.js
@@ -0,0 +1,5 @@
+export * from './setup';
+export * from './checks';
+export * from './session_controls';
+export * from './session_status';
+export default () => {};
diff --git a/app/assets/javascripts/ide/stores/modules/terminal/actions/session_controls.js b/app/assets/javascripts/ide/stores/modules/terminal/actions/session_controls.js
new file mode 100644
index 00000000000..d3dcb9dd125
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/terminal/actions/session_controls.js
@@ -0,0 +1,118 @@
+import axios from '~/lib/utils/axios_utils';
+import httpStatus from '~/lib/utils/http_status';
+import flash from '~/flash';
+import * as types from '../mutation_types';
+import * as messages from '../messages';
+import * as terminalService from '../../../../services/terminals';
+import { STARTING, STOPPING, STOPPED } from '../constants';
+
+export const requestStartSession = ({ commit }) => {
+ commit(types.SET_SESSION_STATUS, STARTING);
+};
+
+export const receiveStartSessionSuccess = ({ commit, dispatch }, data) => {
+ commit(types.SET_SESSION, {
+ id: data.id,
+ status: data.status,
+ showPath: data.show_path,
+ cancelPath: data.cancel_path,
+ retryPath: data.retry_path,
+ terminalPath: data.terminal_path,
+ proxyWebsocketPath: data.proxy_websocket_path,
+ services: data.services,
+ });
+
+ dispatch('pollSessionStatus');
+};
+
+export const receiveStartSessionError = ({ dispatch }) => {
+ flash(messages.UNEXPECTED_ERROR_STARTING);
+ dispatch('killSession');
+};
+
+export const startSession = ({ state, dispatch, rootGetters, rootState }) => {
+ if (state.session && state.session.status === STARTING) {
+ return;
+ }
+
+ const { currentProject } = rootGetters;
+ const { currentBranchId } = rootState;
+
+ dispatch('requestStartSession');
+
+ terminalService
+ .create(currentProject.path_with_namespace, currentBranchId)
+ .then(({ data }) => {
+ dispatch('receiveStartSessionSuccess', data);
+ })
+ .catch(error => {
+ dispatch('receiveStartSessionError', error);
+ });
+};
+
+export const requestStopSession = ({ commit }) => {
+ commit(types.SET_SESSION_STATUS, STOPPING);
+};
+
+export const receiveStopSessionSuccess = ({ dispatch }) => {
+ dispatch('killSession');
+};
+
+export const receiveStopSessionError = ({ dispatch }) => {
+ flash(messages.UNEXPECTED_ERROR_STOPPING);
+ dispatch('killSession');
+};
+
+export const stopSession = ({ state, dispatch }) => {
+ const { cancelPath } = state.session;
+
+ dispatch('requestStopSession');
+
+ axios
+ .post(cancelPath)
+ .then(() => {
+ dispatch('receiveStopSessionSuccess');
+ })
+ .catch(err => {
+ dispatch('receiveStopSessionError', err);
+ });
+};
+
+export const killSession = ({ commit, dispatch }) => {
+ dispatch('stopPollingSessionStatus');
+ commit(types.SET_SESSION_STATUS, STOPPED);
+};
+
+export const restartSession = ({ state, dispatch, rootState }) => {
+ const { status, retryPath } = state.session;
+ const { currentBranchId } = rootState;
+
+ if (status !== STOPPED) {
+ return;
+ }
+
+ if (!retryPath) {
+ dispatch('startSession');
+ return;
+ }
+
+ dispatch('requestStartSession');
+
+ axios
+ .post(retryPath, { branch: currentBranchId, format: 'json' })
+ .then(({ data }) => {
+ dispatch('receiveStartSessionSuccess', data);
+ })
+ .catch(error => {
+ const responseStatus = error.response && error.response.status;
+ // We may have removed the build, in this case we'll just create a new session
+ if (
+ responseStatus === httpStatus.NOT_FOUND ||
+ responseStatus === httpStatus.UNPROCESSABLE_ENTITY
+ ) {
+ dispatch('startSession');
+ } else {
+ dispatch('receiveStartSessionError', error);
+ }
+ });
+};
diff --git a/app/assets/javascripts/ide/stores/modules/terminal/actions/session_status.js b/app/assets/javascripts/ide/stores/modules/terminal/actions/session_status.js
new file mode 100644
index 00000000000..59ba1605c47
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/terminal/actions/session_status.js
@@ -0,0 +1,64 @@
+import axios from '~/lib/utils/axios_utils';
+import flash from '~/flash';
+import * as types from '../mutation_types';
+import * as messages from '../messages';
+import { isEndingStatus } from '../utils';
+
+export const pollSessionStatus = ({ state, dispatch, commit }) => {
+ dispatch('stopPollingSessionStatus');
+ dispatch('fetchSessionStatus');
+
+ const interval = setInterval(() => {
+ if (!state.session) {
+ dispatch('stopPollingSessionStatus');
+ } else {
+ dispatch('fetchSessionStatus');
+ }
+ }, 5000);
+
+ commit(types.SET_SESSION_STATUS_INTERVAL, interval);
+};
+
+export const stopPollingSessionStatus = ({ state, commit }) => {
+ const { sessionStatusInterval } = state;
+
+ if (!sessionStatusInterval) {
+ return;
+ }
+
+ clearInterval(sessionStatusInterval);
+
+ commit(types.SET_SESSION_STATUS_INTERVAL, 0);
+};
+
+export const receiveSessionStatusSuccess = ({ commit, dispatch }, data) => {
+ const status = data && data.status;
+
+ commit(types.SET_SESSION_STATUS, status);
+
+ if (isEndingStatus(status)) {
+ dispatch('killSession');
+ }
+};
+
+export const receiveSessionStatusError = ({ dispatch }) => {
+ flash(messages.UNEXPECTED_ERROR_STATUS);
+ dispatch('killSession');
+};
+
+export const fetchSessionStatus = ({ dispatch, state }) => {
+ if (!state.session) {
+ return;
+ }
+
+ const { showPath } = state.session;
+
+ axios
+ .get(showPath)
+ .then(({ data }) => {
+ dispatch('receiveSessionStatusSuccess', data);
+ })
+ .catch(error => {
+ dispatch('receiveSessionStatusError', error);
+ });
+};
diff --git a/app/assets/javascripts/ide/stores/modules/terminal/actions/setup.js b/app/assets/javascripts/ide/stores/modules/terminal/actions/setup.js
new file mode 100644
index 00000000000..78ad94f8a91
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/terminal/actions/setup.js
@@ -0,0 +1,14 @@
+import * as types from '../mutation_types';
+
+export const init = ({ dispatch }) => {
+ dispatch('fetchConfigCheck');
+ dispatch('fetchRunnersCheck');
+};
+
+export const hideSplash = ({ commit }) => {
+ commit(types.HIDE_SPLASH);
+};
+
+export const setPaths = ({ commit }, paths) => {
+ commit(types.SET_PATHS, paths);
+};
diff --git a/app/assets/javascripts/ide/stores/modules/terminal/constants.js b/app/assets/javascripts/ide/stores/modules/terminal/constants.js
new file mode 100644
index 00000000000..f7ae9d8f4ea
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/terminal/constants.js
@@ -0,0 +1,9 @@
+export const CHECK_CONFIG = 'config';
+export const CHECK_RUNNERS = 'runners';
+export const RETRY_RUNNERS_INTERVAL = 10000;
+
+export const STARTING = 'starting';
+export const PENDING = 'pending';
+export const RUNNING = 'running';
+export const STOPPING = 'stopping';
+export const STOPPED = 'stopped';
diff --git a/app/assets/javascripts/ide/stores/modules/terminal/getters.js b/app/assets/javascripts/ide/stores/modules/terminal/getters.js
new file mode 100644
index 00000000000..6d64ee4ab6e
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/terminal/getters.js
@@ -0,0 +1,19 @@
+export const allCheck = state => {
+ const checks = Object.values(state.checks);
+
+ if (checks.some(check => check.isLoading)) {
+ return { isLoading: true };
+ }
+
+ const invalidCheck = checks.find(check => !check.isValid);
+ const isValid = !invalidCheck;
+ const message = !invalidCheck ? '' : invalidCheck.message;
+
+ return {
+ isLoading: false,
+ isValid,
+ message,
+ };
+};
+
+export default () => {};
diff --git a/app/assets/javascripts/ide/stores/modules/terminal/index.js b/app/assets/javascripts/ide/stores/modules/terminal/index.js
new file mode 100644
index 00000000000..ef1289e1722
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/terminal/index.js
@@ -0,0 +1,12 @@
+import * as actions from './actions';
+import * as getters from './getters';
+import mutations from './mutations';
+import state from './state';
+
+export default () => ({
+ namespaced: true,
+ actions,
+ getters,
+ mutations,
+ state: state(),
+});
diff --git a/app/assets/javascripts/ide/stores/modules/terminal/messages.js b/app/assets/javascripts/ide/stores/modules/terminal/messages.js
new file mode 100644
index 00000000000..38c5a8a28d8
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/terminal/messages.js
@@ -0,0 +1,55 @@
+import { escape } from 'lodash';
+import { __, sprintf } from '~/locale';
+import httpStatus from '~/lib/utils/http_status';
+
+export const UNEXPECTED_ERROR_CONFIG = __(
+ 'An unexpected error occurred while checking the project environment.',
+);
+export const UNEXPECTED_ERROR_RUNNERS = __(
+ 'An unexpected error occurred while checking the project runners.',
+);
+export const UNEXPECTED_ERROR_STATUS = __(
+ 'An unexpected error occurred while communicating with the Web Terminal.',
+);
+export const UNEXPECTED_ERROR_STARTING = __(
+ 'An unexpected error occurred while starting the Web Terminal.',
+);
+export const UNEXPECTED_ERROR_STOPPING = __(
+ 'An unexpected error occurred while stopping the Web Terminal.',
+);
+export const EMPTY_RUNNERS = __(
+ 'Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}',
+);
+export const ERROR_CONFIG = __(
+ 'Configure a <code>.gitlab-webide.yml</code> file in the <code>.gitlab</code> directory to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}',
+);
+export const ERROR_PERMISSION = __(
+ 'You do not have permission to run the Web Terminal. Please contact a project administrator.',
+);
+
+export const configCheckError = (status, helpUrl) => {
+ if (status === httpStatus.UNPROCESSABLE_ENTITY) {
+ return sprintf(
+ ERROR_CONFIG,
+ {
+ helpStart: `<a href="${escape(helpUrl)}" target="_blank">`,
+ helpEnd: '</a>',
+ },
+ false,
+ );
+ } else if (status === httpStatus.FORBIDDEN) {
+ return ERROR_PERMISSION;
+ }
+
+ return UNEXPECTED_ERROR_CONFIG;
+};
+
+export const runnersCheckEmpty = helpUrl =>
+ sprintf(
+ EMPTY_RUNNERS,
+ {
+ helpStart: `<a href="${escape(helpUrl)}" target="_blank">`,
+ helpEnd: '</a>',
+ },
+ false,
+ );
diff --git a/app/assets/javascripts/ide/stores/modules/terminal/mutation_types.js b/app/assets/javascripts/ide/stores/modules/terminal/mutation_types.js
new file mode 100644
index 00000000000..b6a6f28abfa
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/terminal/mutation_types.js
@@ -0,0 +1,11 @@
+export const SET_VISIBLE = 'SET_VISIBLE';
+export const HIDE_SPLASH = 'HIDE_SPLASH';
+export const SET_PATHS = 'SET_PATHS';
+
+export const REQUEST_CHECK = 'REQUEST_CHECK';
+export const RECEIVE_CHECK_SUCCESS = 'RECEIVE_CHECK_SUCCESS';
+export const RECEIVE_CHECK_ERROR = 'RECEIVE_CHECK_ERROR';
+
+export const SET_SESSION = 'SET_SESSION';
+export const SET_SESSION_STATUS = 'SET_SESSION_STATUS';
+export const SET_SESSION_STATUS_INTERVAL = 'SET_SESSION_STATUS_INTERVAL';
diff --git a/app/assets/javascripts/ide/stores/modules/terminal/mutations.js b/app/assets/javascripts/ide/stores/modules/terminal/mutations.js
new file mode 100644
index 00000000000..37f40af9c2e
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/terminal/mutations.js
@@ -0,0 +1,64 @@
+import * as types from './mutation_types';
+
+export default {
+ [types.SET_VISIBLE](state, isVisible) {
+ Object.assign(state, {
+ isVisible,
+ });
+ },
+ [types.HIDE_SPLASH](state) {
+ Object.assign(state, {
+ isShowSplash: false,
+ });
+ },
+ [types.SET_PATHS](state, paths) {
+ Object.assign(state, {
+ paths,
+ });
+ },
+ [types.REQUEST_CHECK](state, type) {
+ Object.assign(state.checks, {
+ [type]: {
+ isLoading: true,
+ },
+ });
+ },
+ [types.RECEIVE_CHECK_ERROR](state, { type, message }) {
+ Object.assign(state.checks, {
+ [type]: {
+ isLoading: false,
+ isValid: false,
+ message,
+ },
+ });
+ },
+ [types.RECEIVE_CHECK_SUCCESS](state, type) {
+ Object.assign(state.checks, {
+ [type]: {
+ isLoading: false,
+ isValid: true,
+ message: null,
+ },
+ });
+ },
+ [types.SET_SESSION](state, session) {
+ Object.assign(state, {
+ session,
+ });
+ },
+ [types.SET_SESSION_STATUS](state, status) {
+ const session = {
+ ...(state.session || {}),
+ status,
+ };
+
+ Object.assign(state, {
+ session,
+ });
+ },
+ [types.SET_SESSION_STATUS_INTERVAL](state, sessionStatusInterval) {
+ Object.assign(state, {
+ sessionStatusInterval,
+ });
+ },
+};
diff --git a/app/assets/javascripts/ide/stores/modules/terminal/state.js b/app/assets/javascripts/ide/stores/modules/terminal/state.js
new file mode 100644
index 00000000000..f35a10ed2fe
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/terminal/state.js
@@ -0,0 +1,13 @@
+import { CHECK_CONFIG, CHECK_RUNNERS } from './constants';
+
+export default () => ({
+ checks: {
+ [CHECK_CONFIG]: { isLoading: true },
+ [CHECK_RUNNERS]: { isLoading: true },
+ },
+ isVisible: false,
+ isShowSplash: true,
+ paths: {},
+ session: null,
+ sessionStatusInterval: 0,
+});
diff --git a/app/assets/javascripts/ide/stores/modules/terminal/utils.js b/app/assets/javascripts/ide/stores/modules/terminal/utils.js
new file mode 100644
index 00000000000..c30136b5277
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/terminal/utils.js
@@ -0,0 +1,5 @@
+import { STARTING, PENDING, RUNNING } from './constants';
+
+export const isStartingStatus = status => status === STARTING || status === PENDING;
+export const isRunningStatus = status => status === RUNNING;
+export const isEndingStatus = status => !isStartingStatus(status) && !isRunningStatus(status);
diff --git a/app/assets/javascripts/ide/stores/modules/terminal_sync/actions.js b/app/assets/javascripts/ide/stores/modules/terminal_sync/actions.js
new file mode 100644
index 00000000000..2fee6b4e974
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/terminal_sync/actions.js
@@ -0,0 +1,41 @@
+import * as types from './mutation_types';
+import mirror, { canConnect } from '../../../lib/mirror';
+
+export const upload = ({ rootState, commit }) => {
+ commit(types.START_LOADING);
+
+ return mirror
+ .upload(rootState)
+ .then(() => {
+ commit(types.SET_SUCCESS);
+ })
+ .catch(err => {
+ commit(types.SET_ERROR, err);
+ });
+};
+
+export const stop = ({ commit }) => {
+ mirror.disconnect();
+
+ commit(types.STOP);
+};
+
+export const start = ({ rootState, commit }) => {
+ const { session } = rootState.terminal;
+ const path = session && session.proxyWebsocketPath;
+ if (!path || !canConnect(session)) {
+ return Promise.reject();
+ }
+
+ commit(types.START_LOADING);
+
+ return mirror
+ .connect(path)
+ .then(() => {
+ commit(types.SET_SUCCESS);
+ })
+ .catch(err => {
+ commit(types.SET_ERROR, err);
+ throw err;
+ });
+};
diff --git a/app/assets/javascripts/ide/stores/modules/terminal_sync/index.js b/app/assets/javascripts/ide/stores/modules/terminal_sync/index.js
new file mode 100644
index 00000000000..795c2fad724
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/terminal_sync/index.js
@@ -0,0 +1,10 @@
+import state from './state';
+import * as actions from './actions';
+import mutations from './mutations';
+
+export default () => ({
+ namespaced: true,
+ actions,
+ mutations,
+ state: state(),
+});
diff --git a/app/assets/javascripts/ide/stores/modules/terminal_sync/messages.js b/app/assets/javascripts/ide/stores/modules/terminal_sync/messages.js
new file mode 100644
index 00000000000..e50e1a1406b
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/terminal_sync/messages.js
@@ -0,0 +1,5 @@
+import { __ } from '~/locale';
+
+export const MSG_TERMINAL_SYNC_CONNECTING = __('Connecting to terminal sync service');
+export const MSG_TERMINAL_SYNC_UPLOADING = __('Uploading changes to terminal');
+export const MSG_TERMINAL_SYNC_RUNNING = __('Terminal sync service is running');
diff --git a/app/assets/javascripts/ide/stores/modules/terminal_sync/mutation_types.js b/app/assets/javascripts/ide/stores/modules/terminal_sync/mutation_types.js
new file mode 100644
index 00000000000..ec809540c18
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/terminal_sync/mutation_types.js
@@ -0,0 +1,4 @@
+export const START_LOADING = 'START_LOADING';
+export const SET_ERROR = 'SET_ERROR';
+export const SET_SUCCESS = 'SET_SUCCESS';
+export const STOP = 'STOP';
diff --git a/app/assets/javascripts/ide/stores/modules/terminal_sync/mutations.js b/app/assets/javascripts/ide/stores/modules/terminal_sync/mutations.js
new file mode 100644
index 00000000000..70ed137776a
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/terminal_sync/mutations.js
@@ -0,0 +1,22 @@
+import * as types from './mutation_types';
+
+export default {
+ [types.START_LOADING](state) {
+ state.isLoading = true;
+ state.isError = false;
+ },
+ [types.SET_ERROR](state, { message }) {
+ state.isLoading = false;
+ state.isError = true;
+ state.message = message;
+ },
+ [types.SET_SUCCESS](state) {
+ state.isLoading = false;
+ state.isError = false;
+ state.isStarted = true;
+ },
+ [types.STOP](state) {
+ state.isLoading = false;
+ state.isStarted = false;
+ },
+};
diff --git a/app/assets/javascripts/ide/stores/modules/terminal_sync/state.js b/app/assets/javascripts/ide/stores/modules/terminal_sync/state.js
new file mode 100644
index 00000000000..7ec3e38f675
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/terminal_sync/state.js
@@ -0,0 +1,6 @@
+export default () => ({
+ isLoading: false,
+ isStarted: false,
+ isError: false,
+ message: '',
+});
diff --git a/app/assets/javascripts/ide/stores/mutation_types.js b/app/assets/javascripts/ide/stores/mutation_types.js
index 5c78bfefa04..d94adc3760f 100644
--- a/app/assets/javascripts/ide/stores/mutation_types.js
+++ b/app/assets/javascripts/ide/stores/mutation_types.js
@@ -27,7 +27,6 @@ export const TOGGLE_BRANCH_OPEN = 'TOGGLE_BRANCH_OPEN';
export const SET_DIRECTORY_DATA = 'SET_DIRECTORY_DATA';
export const TOGGLE_TREE_OPEN = 'TOGGLE_TREE_OPEN';
export const SET_TREE_OPEN = 'SET_TREE_OPEN';
-export const SET_LAST_COMMIT_URL = 'SET_LAST_COMMIT_URL';
export const CREATE_TREE = 'CREATE_TREE';
export const REMOVE_ALL_CHANGES_FILES = 'REMOVE_ALL_CHANGES_FILES';
@@ -41,7 +40,6 @@ export const UPDATE_FILE_CONTENT = 'UPDATE_FILE_CONTENT';
export const SET_FILE_LANGUAGE = 'SET_FILE_LANGUAGE';
export const SET_FILE_POSITION = 'SET_FILE_POSITION';
export const SET_FILE_VIEWMODE = 'SET_FILE_VIEWMODE';
-export const SET_FILE_EOL = 'SET_FILE_EOL';
export const DISCARD_FILE_CHANGES = 'DISCARD_FILE_CHANGES';
export const ADD_FILE_TO_CHANGED = 'ADD_FILE_TO_CHANGED';
export const REMOVE_FILE_FROM_CHANGED = 'REMOVE_FILE_FROM_CHANGED';
diff --git a/app/assets/javascripts/ide/stores/mutations.js b/app/assets/javascripts/ide/stores/mutations.js
index 12ac10df206..e827aacac13 100644
--- a/app/assets/javascripts/ide/stores/mutations.js
+++ b/app/assets/javascripts/ide/stores/mutations.js
@@ -65,14 +65,10 @@ export default {
// NOTE: We can't clone `entry` in any of the below assignments because
// we need `state.entries` and the `entry.tree` to reference the same object.
- if (!foundEntry) {
+ if (!foundEntry || foundEntry.deleted) {
Object.assign(state.entries, {
[key]: entry,
});
- } else if (foundEntry.deleted) {
- Object.assign(state.entries, {
- [key]: Object.assign(entry, { replaces: true }),
- });
} else {
const tree = entry.tree.filter(
f => foundEntry.tree.find(e => e.path === f.path) === undefined,
@@ -147,7 +143,6 @@ export default {
raw: file.content,
changed: Boolean(changedFile),
staged: false,
- replaces: false,
lastCommitSha: lastCommit.commit.id,
prevId: undefined,
@@ -164,9 +159,6 @@ export default {
Object.assign(state.entries[file.path], {
rawPath: file.rawPath.replace(regex, file.path),
- permalink: file.permalink.replace(regex, file.path),
- commitsPath: file.commitsPath.replace(regex, file.path),
- blamePath: file.blamePath.replace(regex, file.path),
});
}
},
@@ -207,8 +199,6 @@ export default {
state.changedFiles = state.changedFiles.concat(entry);
}
}
-
- state.unusedSeal = false;
},
[types.RENAME_ENTRY](state, { path, name, parentPath }) {
const oldEntry = state.entries[path];
diff --git a/app/assets/javascripts/ide/stores/mutations/file.js b/app/assets/javascripts/ide/stores/mutations/file.js
index 5c5920a3027..c90bc2a3320 100644
--- a/app/assets/javascripts/ide/stores/mutations/file.js
+++ b/app/assets/javascripts/ide/stores/mutations/file.js
@@ -99,11 +99,6 @@ export default {
fileLanguage,
});
},
- [types.SET_FILE_EOL](state, { file, eol }) {
- Object.assign(state.entries[file.path], {
- eol,
- });
- },
[types.SET_FILE_POSITION](state, { file, editorRow, editorColumn }) {
Object.assign(state.entries[file.path], {
editorRow,
@@ -153,13 +148,11 @@ export default {
[types.ADD_FILE_TO_CHANGED](state, path) {
Object.assign(state, {
changedFiles: state.changedFiles.concat(state.entries[path]),
- unusedSeal: false,
});
},
[types.REMOVE_FILE_FROM_CHANGED](state, path) {
Object.assign(state, {
changedFiles: state.changedFiles.filter(f => f.path !== path),
- unusedSeal: false,
});
},
[types.STAGE_CHANGE](state, { path, diffInfo }) {
@@ -175,7 +168,6 @@ export default {
deleted: diffInfo.deleted,
}),
}),
- unusedSeal: false,
});
if (stagedFile) {
diff --git a/app/assets/javascripts/ide/stores/mutations/tree.js b/app/assets/javascripts/ide/stores/mutations/tree.js
index c8f14a680c2..cce43a99bd9 100644
--- a/app/assets/javascripts/ide/stores/mutations/tree.js
+++ b/app/assets/javascripts/ide/stores/mutations/tree.js
@@ -34,11 +34,6 @@ export default {
Object.assign(selectedTree, { tree });
},
- [types.SET_LAST_COMMIT_URL](state, { tree = state, url }) {
- Object.assign(tree, {
- lastCommitPath: url,
- });
- },
[types.REMOVE_ALL_CHANGES_FILES](state) {
Object.assign(state, {
changedFiles: [],
diff --git a/app/assets/javascripts/ide/stores/plugins/terminal.js b/app/assets/javascripts/ide/stores/plugins/terminal.js
new file mode 100644
index 00000000000..66539c7bd4f
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/plugins/terminal.js
@@ -0,0 +1,25 @@
+import * as mutationTypes from '~/ide/stores/mutation_types';
+import terminalModule from '../modules/terminal';
+
+function getPathsFromData(el) {
+ return {
+ webTerminalSvgPath: el.dataset.eeWebTerminalSvgPath,
+ webTerminalHelpPath: el.dataset.eeWebTerminalHelpPath,
+ webTerminalConfigHelpPath: el.dataset.eeWebTerminalConfigHelpPath,
+ webTerminalRunnersHelpPath: el.dataset.eeWebTerminalRunnersHelpPath,
+ };
+}
+
+export default function createTerminalPlugin(el) {
+ return store => {
+ store.registerModule('terminal', terminalModule());
+
+ store.dispatch('terminal/setPaths', getPathsFromData(el));
+
+ store.subscribe(({ type }) => {
+ if (type === mutationTypes.SET_BRANCH_WORKING_REFERENCE) {
+ store.dispatch('terminal/init');
+ }
+ });
+ };
+}
diff --git a/app/assets/javascripts/ide/stores/plugins/terminal_sync.js b/app/assets/javascripts/ide/stores/plugins/terminal_sync.js
new file mode 100644
index 00000000000..c60bba4293a
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/plugins/terminal_sync.js
@@ -0,0 +1,49 @@
+import { debounce } from 'lodash';
+import eventHub from '~/ide/eventhub';
+import terminalSyncModule from '../modules/terminal_sync';
+import { isEndingStatus, isRunningStatus } from '../modules/terminal/utils';
+
+const UPLOAD_DEBOUNCE = 200;
+
+/**
+ * Registers and controls the terminalSync vuex module based on IDE events.
+ *
+ * - Watches the terminal session status state to control start/stop.
+ * - Listens for file change event to control upload.
+ */
+export default function createMirrorPlugin() {
+ return store => {
+ store.registerModule('terminalSync', terminalSyncModule());
+
+ const upload = debounce(() => {
+ store.dispatch(`terminalSync/upload`);
+ }, UPLOAD_DEBOUNCE);
+
+ const stop = () => {
+ store.dispatch(`terminalSync/stop`);
+ eventHub.$off('ide.files.change', upload);
+ };
+
+ const start = () => {
+ store
+ .dispatch(`terminalSync/start`)
+ .then(() => {
+ eventHub.$on('ide.files.change', upload);
+ })
+ .catch(() => {
+ // error is handled in store
+ });
+ };
+
+ store.watch(
+ x => x.terminal && x.terminal.session && x.terminal.session.status,
+ val => {
+ if (isRunningStatus(val)) {
+ start();
+ } else if (isEndingStatus(val)) {
+ stop();
+ }
+ },
+ );
+ };
+}
diff --git a/app/assets/javascripts/ide/stores/state.js b/app/assets/javascripts/ide/stores/state.js
index 0c95c22e8f8..c1a83bf0726 100644
--- a/app/assets/javascripts/ide/stores/state.js
+++ b/app/assets/javascripts/ide/stores/state.js
@@ -9,10 +9,8 @@ export default () => ({
stagedFiles: [],
endpoints: {},
lastCommitMsg: '',
- lastCommitPath: '',
loading: false,
openFiles: [],
- parentTreeUrl: '',
trees: {},
projects: {},
panelResizing: false,
@@ -20,7 +18,6 @@ export default () => ({
viewer: viewerTypes.edit,
delayViewerUpdated: false,
currentActivityView: leftSidebarViews.edit.name,
- unusedSeal: true,
fileFindVisible: false,
links: {},
errorMessage: null,
diff --git a/app/assets/javascripts/ide/stores/utils.js b/app/assets/javascripts/ide/stores/utils.js
index 56671142bd4..1c5fe9fe9a5 100644
--- a/app/assets/javascripts/ide/stores/utils.js
+++ b/app/assets/javascripts/ide/stores/utils.js
@@ -1,5 +1,10 @@
import { commitActionTypes, FILE_VIEW_MODE_EDITOR } from '../constants';
-import { relativePathToAbsolute, isAbsolute, isRootRelative } from '~/lib/utils/url_utility';
+import {
+ relativePathToAbsolute,
+ isAbsolute,
+ isRootRelative,
+ isBase64DataUrl,
+} from '~/lib/utils/url_utility';
export const dataStructure = () => ({
id: '',
@@ -19,8 +24,6 @@ export const dataStructure = () => ({
active: false,
changed: false,
staged: false,
- replaces: false,
- lastCommitPath: '',
lastCommitSha: '',
lastCommit: {
id: '',
@@ -29,23 +32,14 @@ export const dataStructure = () => ({
updatedAt: '',
author: '',
},
- blamePath: '',
- commitsPath: '',
- permalink: '',
rawPath: '',
binary: false,
- html: '',
raw: '',
content: '',
- parentTreeUrl: '',
- renderError: false,
- base64: false,
editorRow: 1,
editorColumn: 1,
fileLanguage: '',
- eol: '',
viewMode: FILE_VIEW_MODE_EDITOR,
- previewMode: null,
size: 0,
parentPath: null,
lastOpenedAt: 0,
@@ -63,19 +57,14 @@ export const decorateData = entity => {
url,
name,
path,
- renderError,
content = '',
tempFile = false,
active = false,
opened = false,
changed = false,
- parentTreeUrl = '',
- base64 = false,
binary = false,
rawPath = '',
- previewMode,
file_lock,
- html,
parentPath = '',
} = entity;
@@ -91,25 +80,15 @@ export const decorateData = entity => {
tempFile,
opened,
active,
- parentTreeUrl,
changed,
- renderError,
content,
- base64,
binary,
rawPath,
- previewMode,
file_lock,
- html,
parentPath,
});
};
-export const findEntry = (tree, type, name, prop = 'name') =>
- tree.find(f => f.type === type && f[prop] === name);
-
-export const findIndexOfFile = (state, file) => state.findIndex(f => f.path === file.path);
-
export const setPageTitle = title => {
document.title = title;
};
@@ -124,7 +103,7 @@ export const commitActionForFile = file => {
return commitActionTypes.move;
} else if (file.deleted) {
return commitActionTypes.delete;
- } else if (file.tempFile && !file.replaces) {
+ } else if (file.tempFile) {
return commitActionTypes.create;
}
@@ -155,9 +134,8 @@ export const createCommitPayload = ({
file_path: f.path,
previous_path: f.prevPath || undefined,
content: f.prevPath && !f.changed ? null : f.content || undefined,
- encoding: f.base64 ? 'base64' : 'text',
- last_commit_id:
- newBranch || f.deleted || f.prevPath || f.replaces ? undefined : f.lastCommitSha,
+ encoding: isBase64DataUrl(f.rawPath) ? 'base64' : 'text',
+ last_commit_id: newBranch || f.deleted || f.prevPath ? undefined : f.lastCommitSha,
})),
start_sha: newBranch ? rootGetters.lastCommit.id : undefined,
});
@@ -272,10 +250,6 @@ export const pathsAreEqual = (a, b) => {
return cleanA === cleanB;
};
-// if the contents of a file dont end with a newline, this function adds a newline
-export const addFinalNewlineIfNeeded = content =>
- content.charAt(content.length - 1) !== '\n' ? `${content}\n` : content;
-
export function extractMarkdownImagesFromEntries(mdFile, entries) {
/**
* Regex to identify an image tag in markdown, like:
diff --git a/app/assets/javascripts/ide/sync_router_and_store.js b/app/assets/javascripts/ide/sync_router_and_store.js
new file mode 100644
index 00000000000..1782c32b3b2
--- /dev/null
+++ b/app/assets/javascripts/ide/sync_router_and_store.js
@@ -0,0 +1,55 @@
+/* eslint-disable import/prefer-default-export */
+/**
+ * This method adds listeners to the given router and store and syncs their state with eachother
+ *
+ * ### Why?
+ *
+ * Previously the IDE had a circular dependency between a singleton router and a singleton store.
+ * This causes some integration testing headaches...
+ *
+ * At the time, the most effecient way to break this ciruclar dependency was to:
+ *
+ * - Replace the router with a factory function that receives a store reference
+ * - Have the store write to a certain state that can be watched by the router
+ *
+ * Hence... This helper function...
+ */
+export const syncRouterAndStore = (router, store) => {
+ const disposables = [];
+
+ let currentPath = '';
+
+ // sync store to router
+ disposables.push(
+ store.watch(
+ state => state.router.fullPath,
+ fullPath => {
+ if (currentPath === fullPath) {
+ return;
+ }
+
+ currentPath = fullPath;
+
+ router.push(fullPath);
+ },
+ ),
+ );
+
+ // sync router to store
+ disposables.push(
+ router.afterEach(to => {
+ if (currentPath === to.fullPath) {
+ return;
+ }
+
+ currentPath = to.fullPath;
+ store.dispatch('router/push', currentPath, { root: true });
+ }),
+ );
+
+ const unsync = () => {
+ disposables.forEach(fn => fn());
+ };
+
+ return unsync;
+};
diff --git a/app/assets/javascripts/ide/utils.js b/app/assets/javascripts/ide/utils.js
index 1ea2b199237..c28a2bd9f1d 100644
--- a/app/assets/javascripts/ide/utils.js
+++ b/app/assets/javascripts/ide/utils.js
@@ -1,4 +1,4 @@
-import { commitItemIconMap } from './constants';
+import { SIDE_LEFT, SIDE_RIGHT } from './constants';
import { languages } from 'monaco-editor';
import { flatten } from 'lodash';
@@ -53,16 +53,6 @@ export function isTextFile(content, mimeType, fileName) {
return asciiRegex.test(content);
}
-export const getCommitIconMap = file => {
- if (file.deleted) {
- return commitItemIconMap.deleted;
- } else if (file.tempFile && !file.prevPath) {
- return commitItemIconMap.addition;
- }
-
- return commitItemIconMap.modified;
-};
-
export const createPathWithExt = p => {
const ext = p.lastIndexOf('.') >= 0 ? p.substring(p.lastIndexOf('.') + 1) : '';
@@ -84,3 +74,52 @@ export function registerLanguages(def, ...defs) {
languages.setMonarchTokensProvider(languageId, def.language);
languages.setLanguageConfiguration(languageId, def.conf);
}
+
+export const otherSide = side => (side === SIDE_RIGHT ? SIDE_LEFT : SIDE_RIGHT);
+
+export function trimTrailingWhitespace(content) {
+ return content.replace(/[^\S\r\n]+$/gm, '');
+}
+
+export function insertFinalNewline(content, eol = '\n') {
+ return content.slice(-eol.length) !== eol ? `${content}${eol}` : content;
+}
+
+export function getPathParents(path, maxDepth = Infinity) {
+ const pathComponents = path.split('/');
+ const paths = [];
+
+ let depth = 0;
+ while (pathComponents.length && depth < maxDepth) {
+ pathComponents.pop();
+
+ let parentPath = pathComponents.join('/');
+ if (parentPath.startsWith('/')) parentPath = parentPath.slice(1);
+ if (parentPath) paths.push(parentPath);
+
+ depth += 1;
+ }
+
+ return paths;
+}
+
+export function getPathParent(path) {
+ return getPathParents(path, 1)[0];
+}
+
+/**
+ * Takes a file object and returns a data uri of its contents.
+ *
+ * @param {File} file
+ */
+export function readFileAsDataURL(file) {
+ return new Promise(resolve => {
+ const reader = new FileReader();
+ reader.addEventListener('load', e => resolve(e.target.result), { once: true });
+ reader.readAsDataURL(file);
+ });
+}
+
+export function getFileEOL(content = '') {
+ return content.includes('\r\n') ? 'CRLF' : 'LF';
+}
diff --git a/app/assets/javascripts/import_projects/components/bitbucket_status_table.vue b/app/assets/javascripts/import_projects/components/bitbucket_status_table.vue
new file mode 100644
index 00000000000..1a9974db727
--- /dev/null
+++ b/app/assets/javascripts/import_projects/components/bitbucket_status_table.vue
@@ -0,0 +1,74 @@
+<script>
+import { GlAlert, GlSprintf, GlLink } from '@gitlab/ui';
+import ImportProjectsTable from './import_projects_table.vue';
+
+export default {
+ components: {
+ ImportProjectsTable,
+ GlAlert,
+ GlSprintf,
+ GlLink,
+ },
+ props: {
+ providerTitle: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ isWarningDismissed: false,
+ };
+ },
+ computed: {
+ currentPage() {
+ return window.location.href;
+ },
+ },
+};
+</script>
+<template>
+ <import-projects-table provider-title="providerTitle">
+ <template #actions>
+ <slot name="actions"></slot>
+ </template>
+ <template #incompatible-repos-warning>
+ <gl-alert
+ v-if="!isWarningDismissed"
+ variant="warning"
+ class="gl-my-2"
+ @dismiss="isWarningDismissed = true"
+ >
+ <gl-sprintf
+ :message="
+ __(
+ '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.',
+ )
+ "
+ >
+ <template #provider>
+ {{ providerTitle }}
+ </template>
+ </gl-sprintf>
+ <gl-sprintf
+ :message="
+ __(
+ 'Please convert %{linkStart}them to Git%{linkEnd}, and go through the %{linkToImportFlow} again.',
+ )
+ "
+ >
+ <template #link="{ content }">
+ <gl-link
+ href="https://www.atlassian.com/git/tutorials/migrating-overview"
+ target="_blank"
+ >{{ content }}</gl-link
+ >
+ </template>
+ <template #linkToImportFlow>
+ <gl-link :href="currentPage">{{ __('import flow') }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </gl-alert>
+ </template>
+ </import-projects-table>
+</template>
diff --git a/app/assets/javascripts/import_projects/components/import_projects_table.vue b/app/assets/javascripts/import_projects/components/import_projects_table.vue
index 849bda28d03..6a467fb8c6a 100644
--- a/app/assets/javascripts/import_projects/components/import_projects_table.vue
+++ b/app/assets/javascripts/import_projects/components/import_projects_table.vue
@@ -1,11 +1,11 @@
<script>
import { throttle } from 'lodash';
import { mapActions, mapState, mapGetters } from 'vuex';
-import { GlLoadingIcon } from '@gitlab/ui';
-import LoadingButton from '~/vue_shared/components/loading_button.vue';
+import { GlButton, GlLoadingIcon } from '@gitlab/ui';
import { __, sprintf } from '~/locale';
import ImportedProjectTableRow from './imported_project_table_row.vue';
import ProviderRepoTableRow from './provider_repo_table_row.vue';
+import IncompatibleRepoTableRow from './incompatible_repo_table_row.vue';
import eventHub from '../event_hub';
const reposFetchThrottleDelay = 1000;
@@ -15,19 +15,42 @@ export default {
components: {
ImportedProjectTableRow,
ProviderRepoTableRow,
- LoadingButton,
+ IncompatibleRepoTableRow,
GlLoadingIcon,
+ GlButton,
},
props: {
providerTitle: {
type: String,
required: true,
},
+ filterable: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
},
computed: {
- ...mapState(['importedProjects', 'providerRepos', 'isLoadingRepos', 'filter']),
- ...mapGetters(['isImportingAnyRepo', 'hasProviderRepos', 'hasImportedProjects']),
+ ...mapState([
+ 'importedProjects',
+ 'providerRepos',
+ 'incompatibleRepos',
+ 'isLoadingRepos',
+ 'filter',
+ ]),
+ ...mapGetters([
+ 'isImportingAnyRepo',
+ 'hasProviderRepos',
+ 'hasImportedProjects',
+ 'hasIncompatibleRepos',
+ ]),
+
+ importAllButtonText() {
+ return this.hasIncompatibleRepos
+ ? __('Import all compatible repositories')
+ : __('Import all repositories');
+ },
emptyStateText() {
return sprintf(__('No %{providerTitle} repositories found'), {
@@ -68,7 +91,6 @@ export default {
},
throttledFetchRepos: throttle(function fetch() {
- eventHub.$off('importAll');
this.fetchRepos();
}, reposFetchThrottleDelay),
},
@@ -80,17 +102,24 @@ export default {
<p class="light text-nowrap mt-2">
{{ s__('ImportProjects|Select the projects you want to import') }}
</p>
-
- <div class="d-flex justify-content-between align-items-end flex-wrap mb-3">
- <loading-button
- container-class="btn btn-success js-import-all"
+ <template v-if="hasIncompatibleRepos">
+ <slot name="incompatible-repos-warning"> </slot>
+ </template>
+ <div
+ v-if="!isLoadingRepos"
+ class="d-flex justify-content-between align-items-end flex-wrap mb-3"
+ >
+ <gl-button
+ variant="success"
:loading="isImportingAnyRepo"
- :label="__('Import all repositories')"
:disabled="!hasProviderRepos"
type="button"
@click="importAll"
- />
- <form novalidate @submit.prevent>
+ >
+ {{ importAllButtonText }}
+ </gl-button>
+ <slot name="actions"></slot>
+ <form v-if="filterable" class="gl-ml-auto" novalidate @submit.prevent>
<input
:value="filter"
data-qa-selector="githubish_import_filter_field"
@@ -109,7 +138,10 @@ export default {
class="js-loading-button-icon import-projects-loading-icon"
size="md"
/>
- <div v-else-if="hasProviderRepos || hasImportedProjects" class="table-responsive">
+ <div
+ v-else-if="hasProviderRepos || hasImportedProjects || hasIncompatibleRepos"
+ class="table-responsive"
+ >
<table class="table import-table">
<thead>
<th class="import-jobs-from-col">{{ fromHeaderText }}</th>
@@ -124,6 +156,11 @@ export default {
:project="project"
/>
<provider-repo-table-row v-for="repo in providerRepos" :key="repo.id" :repo="repo" />
+ <incompatible-repo-table-row
+ v-for="repo in incompatibleRepos"
+ :key="repo.id"
+ :repo="repo"
+ />
</tbody>
</table>
</div>
diff --git a/app/assets/javascripts/import_projects/components/incompatible_repo_table_row.vue b/app/assets/javascripts/import_projects/components/incompatible_repo_table_row.vue
new file mode 100644
index 00000000000..fa2fb439eac
--- /dev/null
+++ b/app/assets/javascripts/import_projects/components/incompatible_repo_table_row.vue
@@ -0,0 +1,30 @@
+<script>
+import { GlBadge } from '@gitlab/ui';
+
+export default {
+ components: {
+ GlBadge,
+ },
+ props: {
+ repo: {
+ type: Object,
+ required: true,
+ },
+ },
+};
+</script>
+
+<template>
+ <tr class="import-row">
+ <td>
+ <a :href="repo.providerLink" rel="noreferrer noopener" target="_blank">
+ {{ repo.fullName }}
+ </a>
+ </td>
+ <td></td>
+ <td></td>
+ <td>
+ <gl-badge variant="danger">{{ __('Incompatible project') }}</gl-badge>
+ </td>
+ </tr>
+</template>
diff --git a/app/assets/javascripts/import_projects/components/provider_repo_table_row.vue b/app/assets/javascripts/import_projects/components/provider_repo_table_row.vue
index 6e227ab3d82..63524d61146 100644
--- a/app/assets/javascripts/import_projects/components/provider_repo_table_row.vue
+++ b/app/assets/javascripts/import_projects/components/provider_repo_table_row.vue
@@ -53,7 +53,11 @@ export default {
},
created() {
- eventHub.$on('importAll', () => this.importRepo());
+ eventHub.$on('importAll', this.importRepo);
+ },
+
+ beforeDestroy() {
+ eventHub.$off('importAll', this.importRepo);
},
methods: {
diff --git a/app/assets/javascripts/import_projects/index.js b/app/assets/javascripts/import_projects/index.js
index b069dcb7766..68ba04aa9dd 100644
--- a/app/assets/javascripts/import_projects/index.js
+++ b/app/assets/javascripts/import_projects/index.js
@@ -1,5 +1,4 @@
import Vue from 'vue';
-import { mapActions } from 'vuex';
import Translate from '../vue_shared/translate';
import ImportProjectsTable from './components/import_projects_table.vue';
import { parseBoolean } from '../lib/utils/common_utils';
@@ -7,42 +6,45 @@ import createStore from './store';
Vue.use(Translate);
-export default function mountImportProjectsTable(mountElement) {
- if (!mountElement) return undefined;
-
+export function initStoreFromElement(element) {
const {
reposPath,
provider,
- providerTitle,
canSelectNamespace,
jobsPath,
importPath,
ciCdOnly,
- } = mountElement.dataset;
+ } = element.dataset;
- const store = createStore();
- return new Vue({
- el: mountElement,
- store,
+ return createStore({
+ reposPath,
+ provider,
+ jobsPath,
+ importPath,
+ defaultTargetNamespace: gon.current_username,
+ ciCdOnly: parseBoolean(ciCdOnly),
+ canSelectNamespace: parseBoolean(canSelectNamespace),
+ });
+}
- created() {
- this.setInitialData({
- reposPath,
- provider,
- jobsPath,
- importPath,
- defaultTargetNamespace: gon.current_username,
- ciCdOnly: parseBoolean(ciCdOnly),
- canSelectNamespace: parseBoolean(canSelectNamespace),
- });
- },
+export function initPropsFromElement(element) {
+ return {
+ providerTitle: element.dataset.providerTitle,
+ filterable: parseBoolean(element.dataset.filterable),
+ };
+}
- methods: {
- ...mapActions(['setInitialData', 'setFilter']),
- },
+export default function mountImportProjectsTable(mountElement) {
+ if (!mountElement) return undefined;
+
+ const store = initStoreFromElement(mountElement);
+ const props = initPropsFromElement(mountElement);
+ return new Vue({
+ el: mountElement,
+ store,
render(createElement) {
- return createElement(ImportProjectsTable, { props: { providerTitle } });
+ return createElement(ImportProjectsTable, { props });
},
});
}
diff --git a/app/assets/javascripts/import_projects/store/actions.js b/app/assets/javascripts/import_projects/store/actions.js
index 0fb9a4cdfd4..2422a1ed2e4 100644
--- a/app/assets/javascripts/import_projects/store/actions.js
+++ b/app/assets/javascripts/import_projects/store/actions.js
@@ -2,6 +2,7 @@ import Visibility from 'visibilityjs';
import * as types from './mutation_types';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import Poll from '~/lib/utils/poll';
+import { visitUrl } from '~/lib/utils/url_utility';
import createFlash from '~/flash';
import { s__, sprintf } from '~/locale';
import axios from '~/lib/utils/axios_utils';
@@ -9,6 +10,9 @@ import { jobsPathWithFilter, reposPathWithFilter } from './getters';
let eTagPoll;
+const hasRedirectInError = e => e?.response?.data?.error?.redirect;
+const redirectToUrlInError = e => visitUrl(e.response.data.error.redirect);
+
export const clearJobsEtagPoll = () => {
eTagPoll = null;
};
@@ -19,45 +23,39 @@ export const restartJobsPolling = () => {
if (eTagPoll) eTagPoll.restart();
};
-export const setInitialData = ({ commit }, data) => commit(types.SET_INITIAL_DATA, data);
export const setFilter = ({ commit }, filter) => commit(types.SET_FILTER, filter);
-export const requestRepos = ({ commit }, repos) => commit(types.REQUEST_REPOS, repos);
-export const receiveReposSuccess = ({ commit }, repos) =>
- commit(types.RECEIVE_REPOS_SUCCESS, repos);
-export const receiveReposError = ({ commit }) => commit(types.RECEIVE_REPOS_ERROR);
-export const fetchRepos = ({ state, dispatch }) => {
+export const fetchRepos = ({ state, dispatch, commit }) => {
dispatch('stopJobsPolling');
- dispatch('requestRepos');
+ commit(types.REQUEST_REPOS);
const { provider } = state;
return axios
.get(reposPathWithFilter(state))
.then(({ data }) =>
- dispatch('receiveReposSuccess', convertObjectPropsToCamelCase(data, { deep: true })),
+ commit(types.RECEIVE_REPOS_SUCCESS, convertObjectPropsToCamelCase(data, { deep: true })),
)
.then(() => dispatch('fetchJobs'))
- .catch(() => {
- createFlash(
- sprintf(s__('ImportProjects|Requesting your %{provider} repositories failed'), {
- provider,
- }),
- );
-
- dispatch('receiveReposError');
+ .catch(e => {
+ if (hasRedirectInError(e)) {
+ redirectToUrlInError(e);
+ } else {
+ createFlash(
+ sprintf(s__('ImportProjects|Requesting your %{provider} repositories failed'), {
+ provider,
+ }),
+ );
+
+ commit(types.RECEIVE_REPOS_ERROR);
+ }
});
};
-export const requestImport = ({ commit, state }, repoId) => {
- if (!state.reposBeingImported.includes(repoId)) commit(types.REQUEST_IMPORT, repoId);
-};
-export const receiveImportSuccess = ({ commit }, { importedProject, repoId }) =>
- commit(types.RECEIVE_IMPORT_SUCCESS, { importedProject, repoId });
-export const receiveImportError = ({ commit }, repoId) =>
- commit(types.RECEIVE_IMPORT_ERROR, repoId);
-export const fetchImport = ({ state, dispatch }, { newName, targetNamespace, repo }) => {
- dispatch('requestImport', repo.id);
+export const fetchImport = ({ state, commit }, { newName, targetNamespace, repo }) => {
+ if (!state.reposBeingImported.includes(repo.id)) {
+ commit(types.REQUEST_IMPORT, repo.id);
+ }
return axios
.post(state.importPath, {
@@ -67,7 +65,7 @@ export const fetchImport = ({ state, dispatch }, { newName, targetNamespace, rep
target_namespace: targetNamespace,
})
.then(({ data }) =>
- dispatch('receiveImportSuccess', {
+ commit(types.RECEIVE_IMPORT_SUCCESS, {
importedProject: convertObjectPropsToCamelCase(data, { deep: true }),
repoId: repo.id,
}),
@@ -75,13 +73,14 @@ export const fetchImport = ({ state, dispatch }, { newName, targetNamespace, rep
.catch(() => {
createFlash(s__('ImportProjects|Importing the project failed'));
- dispatch('receiveImportError', { repoId: repo.id });
+ commit(types.RECEIVE_IMPORT_ERROR, repo.id);
});
};
export const receiveJobsSuccess = ({ commit }, updatedProjects) =>
commit(types.RECEIVE_JOBS_SUCCESS, updatedProjects);
-export const fetchJobs = ({ state, dispatch }) => {
+
+export const fetchJobs = ({ state, commit, dispatch }) => {
const { filter } = state;
if (eTagPoll) {
@@ -95,9 +94,14 @@ export const fetchJobs = ({ state, dispatch }) => {
},
method: 'fetchJobs',
successCallback: ({ data }) =>
- dispatch('receiveJobsSuccess', convertObjectPropsToCamelCase(data, { deep: true })),
- errorCallback: () =>
- createFlash(s__('ImportProjects|Update of imported projects with realtime changes failed')),
+ commit(types.RECEIVE_JOBS_SUCCESS, convertObjectPropsToCamelCase(data, { deep: true })),
+ errorCallback: e => {
+ if (hasRedirectInError(e)) {
+ redirectToUrlInError(e);
+ } else {
+ createFlash(s__('ImportProjects|Update of imported projects with realtime changes failed'));
+ }
+ },
data: { filter },
});
diff --git a/app/assets/javascripts/import_projects/store/getters.js b/app/assets/javascripts/import_projects/store/getters.js
index b107c293181..e6eb8f523de 100644
--- a/app/assets/javascripts/import_projects/store/getters.js
+++ b/app/assets/javascripts/import_projects/store/getters.js
@@ -21,6 +21,8 @@ export const hasProviderRepos = state => state.providerRepos.length > 0;
export const hasImportedProjects = state => state.importedProjects.length > 0;
+export const hasIncompatibleRepos = state => state.incompatibleRepos.length > 0;
+
export const reposPathWithFilter = ({ reposPath, filter = '' }) =>
filter ? `${reposPath}?filter=${filter}` : reposPath;
export const jobsPathWithFilter = ({ jobsPath, filter = '' }) =>
diff --git a/app/assets/javascripts/import_projects/store/index.js b/app/assets/javascripts/import_projects/store/index.js
index ff1fd1e598e..29deb7868ba 100644
--- a/app/assets/javascripts/import_projects/store/index.js
+++ b/app/assets/javascripts/import_projects/store/index.js
@@ -9,9 +9,9 @@ Vue.use(Vuex);
export { state, actions, getters, mutations };
-export default () =>
+export default initialState =>
new Vuex.Store({
- state: state(),
+ state: { ...state(), ...initialState },
actions,
mutations,
getters,
diff --git a/app/assets/javascripts/import_projects/store/mutation_types.js b/app/assets/javascripts/import_projects/store/mutation_types.js
index 16574f4450f..a23b7eef986 100644
--- a/app/assets/javascripts/import_projects/store/mutation_types.js
+++ b/app/assets/javascripts/import_projects/store/mutation_types.js
@@ -1,5 +1,3 @@
-export const SET_INITIAL_DATA = 'SET_INITIAL_DATA';
-
export const REQUEST_REPOS = 'REQUEST_REPOS';
export const RECEIVE_REPOS_SUCCESS = 'RECEIVE_REPOS_SUCCESS';
export const RECEIVE_REPOS_ERROR = 'RECEIVE_REPOS_ERROR';
diff --git a/app/assets/javascripts/import_projects/store/mutations.js b/app/assets/javascripts/import_projects/store/mutations.js
index 6c56cfa8298..ec62d0640ef 100644
--- a/app/assets/javascripts/import_projects/store/mutations.js
+++ b/app/assets/javascripts/import_projects/store/mutations.js
@@ -2,10 +2,6 @@ import Vue from 'vue';
import * as types from './mutation_types';
export default {
- [types.SET_INITIAL_DATA](state, data) {
- Object.assign(state, data);
- },
-
[types.SET_FILTER](state, filter) {
state.filter = filter;
},
@@ -14,11 +10,15 @@ export default {
state.isLoadingRepos = true;
},
- [types.RECEIVE_REPOS_SUCCESS](state, { importedProjects, providerRepos, namespaces }) {
+ [types.RECEIVE_REPOS_SUCCESS](
+ state,
+ { importedProjects, providerRepos, incompatibleRepos, namespaces },
+ ) {
state.isLoadingRepos = false;
state.importedProjects = importedProjects;
state.providerRepos = providerRepos;
+ state.incompatibleRepos = incompatibleRepos ?? [];
state.namespaces = namespaces;
},
diff --git a/app/assets/javascripts/import_projects/store/state.js b/app/assets/javascripts/import_projects/store/state.js
index 829f3aa4fbb..0418d735b1d 100644
--- a/app/assets/javascripts/import_projects/store/state.js
+++ b/app/assets/javascripts/import_projects/store/state.js
@@ -7,6 +7,7 @@ export default () => ({
currentUsername: '',
importedProjects: [],
providerRepos: [],
+ incompatibleRepos: [],
namespaces: [],
reposBeingImported: [],
isLoadingRepos: false,
diff --git a/app/assets/javascripts/integrations/edit/components/active_toggle.vue b/app/assets/javascripts/integrations/edit/components/active_toggle.vue
index 8b95b04d93c..dc89e139320 100644
--- a/app/assets/javascripts/integrations/edit/components/active_toggle.vue
+++ b/app/assets/javascripts/integrations/edit/components/active_toggle.vue
@@ -1,12 +1,15 @@
<script>
import eventHub from '../event_hub';
-import { GlToggle } from '@gitlab/ui';
+import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+import { GlFormGroup, GlToggle } from '@gitlab/ui';
export default {
name: 'ActiveToggle',
components: {
+ GlFormGroup,
GlToggle,
},
+ mixins: [glFeatureFlagsMixin()],
props: {
initialActivated: {
type: Boolean,
@@ -33,7 +36,17 @@ export default {
</script>
<template>
- <div>
+ <div v-if="glFeatures.integrationFormRefactor">
+ <gl-form-group :label="__('Enable integration')" label-for="service[active]">
+ <gl-toggle
+ v-model="activated"
+ name="service[active]"
+ class="gl-display-block gl-line-height-0"
+ @change="onToggle"
+ />
+ </gl-form-group>
+ </div>
+ <div v-else>
<div class="form-group row" role="group">
<label for="service[active]" class="col-form-label col-sm-2">{{ __('Active') }}</label>
<div class="col-sm-10 pt-1">
diff --git a/app/assets/javascripts/integrations/edit/components/dynamic_field.vue b/app/assets/javascripts/integrations/edit/components/dynamic_field.vue
new file mode 100644
index 00000000000..29318d6aaa8
--- /dev/null
+++ b/app/assets/javascripts/integrations/edit/components/dynamic_field.vue
@@ -0,0 +1,172 @@
+<script>
+import eventHub from '../event_hub';
+import { capitalize, lowerCase, isEmpty } from 'lodash';
+import { __, sprintf } from '~/locale';
+import { GlFormGroup, GlFormCheckbox, GlFormInput, GlFormSelect, GlFormTextarea } from '@gitlab/ui';
+
+export default {
+ name: 'DynamicField',
+ components: {
+ GlFormGroup,
+ GlFormCheckbox,
+ GlFormInput,
+ GlFormSelect,
+ GlFormTextarea,
+ },
+ props: {
+ choices: {
+ type: Array,
+ required: false,
+ default: null,
+ },
+ help: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ name: {
+ type: String,
+ required: true,
+ },
+ placeholder: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ required: {
+ type: Boolean,
+ required: false,
+ },
+ title: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ type: {
+ type: String,
+ required: true,
+ },
+ value: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ },
+ data() {
+ return {
+ model: this.value,
+ validated: false,
+ };
+ },
+ computed: {
+ isCheckbox() {
+ return this.type === 'checkbox';
+ },
+ isPassword() {
+ return this.type === 'password';
+ },
+ isSelect() {
+ return this.type === 'select';
+ },
+ isTextarea() {
+ return this.type === 'textarea';
+ },
+ isNonEmptyPassword() {
+ return this.isPassword && !isEmpty(this.value);
+ },
+ label() {
+ if (this.isNonEmptyPassword) {
+ return sprintf(__('Enter new %{field_title}'), {
+ field_title: this.humanizedTitle,
+ });
+ }
+ return this.humanizedTitle;
+ },
+ humanizedTitle() {
+ return this.title || capitalize(lowerCase(this.name));
+ },
+ passwordRequired() {
+ return isEmpty(this.value) && this.required;
+ },
+ options() {
+ return this.choices.map(choice => {
+ return {
+ value: choice[1],
+ text: choice[0],
+ };
+ });
+ },
+ fieldId() {
+ return `service_${this.name}`;
+ },
+ fieldName() {
+ return `service[${this.name}]`;
+ },
+ sharedProps() {
+ return {
+ id: this.fieldId,
+ name: this.fieldName,
+ };
+ },
+ valid() {
+ return !this.required || !isEmpty(this.model) || !this.validated;
+ },
+ },
+ created() {
+ if (this.isNonEmptyPassword) {
+ this.model = null;
+ }
+ eventHub.$on('validateForm', this.validateForm);
+ },
+ beforeDestroy() {
+ eventHub.$off('validateForm', this.validateForm);
+ },
+ methods: {
+ validateForm() {
+ this.validated = true;
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-form-group
+ :label="label"
+ :label-for="fieldId"
+ :invalid-feedback="__('This field is required.')"
+ :state="valid"
+ :description="help"
+ >
+ <template v-if="isCheckbox">
+ <input :name="fieldName" type="hidden" value="false" />
+ <gl-form-checkbox v-model="model" v-bind="sharedProps">
+ {{ humanizedTitle }}
+ </gl-form-checkbox>
+ </template>
+ <gl-form-select v-else-if="isSelect" v-model="model" v-bind="sharedProps" :options="options" />
+ <gl-form-textarea
+ v-else-if="isTextarea"
+ v-model="model"
+ v-bind="sharedProps"
+ :placeholder="placeholder"
+ :required="required"
+ />
+ <gl-form-input
+ v-else-if="isPassword"
+ v-model="model"
+ v-bind="sharedProps"
+ :type="type"
+ autocomplete="new-password"
+ :placeholder="placeholder"
+ :required="passwordRequired"
+ />
+ <gl-form-input
+ v-else
+ v-model="model"
+ v-bind="sharedProps"
+ :type="type"
+ :placeholder="placeholder"
+ :required="required"
+ />
+ </gl-form-group>
+</template>
diff --git a/app/assets/javascripts/integrations/edit/components/integration_form.vue b/app/assets/javascripts/integrations/edit/components/integration_form.vue
index fbe58c30b13..ef7a4d44b20 100644
--- a/app/assets/javascripts/integrations/edit/components/integration_form.vue
+++ b/app/assets/javascripts/integrations/edit/components/integration_form.vue
@@ -2,6 +2,7 @@
import ActiveToggle from './active_toggle.vue';
import JiraTriggerFields from './jira_trigger_fields.vue';
import TriggerFields from './trigger_fields.vue';
+import DynamicField from './dynamic_field.vue';
export default {
name: 'IntegrationForm',
@@ -9,6 +10,7 @@ export default {
ActiveToggle,
JiraTriggerFields,
TriggerFields,
+ DynamicField,
},
props: {
activeToggleProps: {
@@ -28,6 +30,11 @@ export default {
required: false,
default: () => [],
},
+ fields: {
+ type: Array,
+ required: false,
+ default: () => [],
+ },
type: {
type: String,
required: true,
@@ -46,5 +53,6 @@ export default {
<active-toggle v-if="showActive" v-bind="activeToggleProps" />
<jira-trigger-fields v-if="isJira" v-bind="triggerFieldsProps" />
<trigger-fields v-else-if="triggerEvents.length" :events="triggerEvents" :type="type" />
+ <dynamic-field v-for="field in fields" :key="field.name" v-bind="field" />
</div>
</template>
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 70278e401ce..64e5789764f 100644
--- a/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue
+++ b/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue
@@ -1,12 +1,31 @@
<script>
-import { GlFormCheckbox, GlFormRadio } from '@gitlab/ui';
+import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+import { s__ } from '~/locale';
+import { GlFormGroup, GlFormCheckbox, GlFormRadio } from '@gitlab/ui';
+
+const commentDetailOptions = [
+ {
+ value: 'standard',
+ label: s__('Integrations|Standard'),
+ help: s__('Integrations|Includes commit title and branch'),
+ },
+ {
+ value: 'all_details',
+ label: s__('Integrations|All details'),
+ help: s__(
+ 'Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs',
+ ),
+ },
+];
export default {
name: 'JiraTriggerFields',
components: {
+ GlFormGroup,
GlFormCheckbox,
GlFormRadio,
},
+ mixins: [glFeatureFlagsMixin()],
props: {
initialTriggerCommit: {
type: Boolean,
@@ -32,13 +51,71 @@ export default {
triggerMergeRequest: this.initialTriggerMergeRequest,
enableComments: this.initialEnableComments,
commentDetail: this.initialCommentDetail,
+ commentDetailOptions,
};
},
+ computed: {
+ showEnableComments() {
+ return this.triggerCommit || this.triggerMergeRequest;
+ },
+ },
};
</script>
<template>
- <div class="form-group row pt-2" role="group">
+ <div v-if="glFeatures.integrationFormRefactor">
+ <gl-form-group
+ :label="__('Trigger')"
+ label-for="service[trigger]"
+ :description="
+ s__(
+ 'Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created.',
+ )
+ "
+ >
+ <input name="service[commit_events]" type="hidden" value="false" />
+ <gl-form-checkbox v-model="triggerCommit" name="service[commit_events]">
+ {{ __('Commit') }}
+ </gl-form-checkbox>
+
+ <input name="service[merge_requests_events]" type="hidden" value="false" />
+ <gl-form-checkbox v-model="triggerMergeRequest" name="service[merge_requests_events]">
+ {{ __('Merge request') }}
+ </gl-form-checkbox>
+ </gl-form-group>
+
+ <gl-form-group
+ v-show="showEnableComments"
+ :label="s__('Integrations|Comment settings:')"
+ data-testid="comment-settings"
+ >
+ <input name="service[comment_on_event_enabled]" type="hidden" value="false" />
+ <gl-form-checkbox v-model="enableComments" name="service[comment_on_event_enabled]">
+ {{ s__('Integrations|Enable comments') }}
+ </gl-form-checkbox>
+ </gl-form-group>
+
+ <gl-form-group
+ v-show="showEnableComments && enableComments"
+ :label="s__('Integrations|Comment detail:')"
+ data-testid="comment-detail"
+ >
+ <gl-form-radio
+ v-for="commentDetailOption in commentDetailOptions"
+ :key="commentDetailOption.value"
+ v-model="commentDetail"
+ :value="commentDetailOption.value"
+ name="service[comment_detail]"
+ >
+ {{ commentDetailOption.label }}
+ <template #help>
+ {{ commentDetailOption.help }}
+ </template>
+ </gl-form-radio>
+ </gl-form-group>
+ </div>
+
+ <div v-else class="form-group row pt-2" role="group">
<label for="service[trigger]" class="col-form-label col-sm-2 pt-0">{{ __('Trigger') }}</label>
<div class="col-sm-10">
<label class="weight-normal mb-2">
@@ -76,20 +153,16 @@ export default {
<label>
{{ s__('Integrations|Comment detail:') }}
</label>
- <gl-form-radio v-model="commentDetail" value="standard" name="service[comment_detail]">
- {{ s__('Integrations|Standard') }}
- <template #help>
- {{ s__('Integrations|Includes commit title and branch') }}
- </template>
- </gl-form-radio>
- <gl-form-radio v-model="commentDetail" value="all_details" name="service[comment_detail]">
- {{ s__('Integrations|All details') }}
+ <gl-form-radio
+ v-for="commentDetailOption in commentDetailOptions"
+ :key="commentDetailOption.value"
+ v-model="commentDetail"
+ :value="commentDetailOption.value"
+ name="service[comment_detail]"
+ >
+ {{ commentDetailOption.label }}
<template #help>
- {{
- s__(
- 'Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs',
- )
- }}
+ {{ commentDetailOption.help }}
</template>
</gl-form-radio>
</div>
diff --git a/app/assets/javascripts/integrations/edit/index.js b/app/assets/javascripts/integrations/edit/index.js
index 2ae1342a558..21b5ca17951 100644
--- a/app/assets/javascripts/integrations/edit/index.js
+++ b/app/assets/javascripts/integrations/edit/index.js
@@ -15,7 +15,7 @@ export default el => {
return result;
}
- const { type, commentDetail, triggerEvents, ...booleanAttributes } = el.dataset;
+ const { type, commentDetail, triggerEvents, fields, ...booleanAttributes } = el.dataset;
const {
showActive,
activated,
@@ -41,6 +41,7 @@ export default el => {
initialCommentDetail: commentDetail,
},
triggerEvents: JSON.parse(triggerEvents),
+ fields: JSON.parse(fields),
},
});
},
diff --git a/app/assets/javascripts/integrations/integration_settings_form.js b/app/assets/javascripts/integrations/integration_settings_form.js
index 3067f4090b1..8844cbebe85 100644
--- a/app/assets/javascripts/integrations/integration_settings_form.js
+++ b/app/assets/javascripts/integrations/integration_settings_form.js
@@ -45,10 +45,15 @@ export default class IntegrationSettingsForm {
// 2) If this service can be tested
// If both conditions are true, we override form submission
// and test the service using provided configuration.
- if (this.$form.get(0).checkValidity() && this.canTestService) {
+ if (this.$form.get(0).checkValidity()) {
+ if (this.canTestService) {
+ e.preventDefault();
+ // eslint-disable-next-line no-jquery/no-serialize
+ this.testSettings(this.$form.serialize());
+ }
+ } else {
e.preventDefault();
- // eslint-disable-next-line no-jquery/no-serialize
- this.testSettings(this.$form.serialize());
+ eventHub.$emit('validateForm');
}
}
diff --git a/app/assets/javascripts/issuable_bulk_update_actions.js b/app/assets/javascripts/issuable_bulk_update_actions.js
index 95e10cc75cc..01ea3eee16e 100644
--- a/app/assets/javascripts/issuable_bulk_update_actions.js
+++ b/app/assets/javascripts/issuable_bulk_update_actions.js
@@ -99,8 +99,11 @@ export default {
setOriginalDropdownData() {
const $labelSelect = $('.bulk-update .js-label-select');
+ const dirtyLabelIds = $labelSelect.data('marked') || [];
+ const chosenLabelIds = [...this.getOriginalMarkedIds(), ...dirtyLabelIds];
+
$labelSelect.data('common', this.getOriginalCommonIds());
- $labelSelect.data('marked', this.getOriginalMarkedIds());
+ $labelSelect.data('marked', chosenLabelIds);
$labelSelect.data('indeterminate', this.getOriginalIndeterminateIds());
},
diff --git a/app/assets/javascripts/issuable_suggestions/components/item.vue b/app/assets/javascripts/issuable_suggestions/components/item.vue
index 76e4fac5107..51904c64085 100644
--- a/app/assets/javascripts/issuable_suggestions/components/item.vue
+++ b/app/assets/javascripts/issuable_suggestions/components/item.vue
@@ -128,7 +128,7 @@ export default {
:key="id"
v-gl-tooltip.bottom
:title="tooltipTitle"
- class="suggestion-help-hover prepend-left-8 text-tertiary"
+ class="suggestion-help-hover gl-ml-3 text-tertiary"
>
<icon :name="icon" /> {{ count }}
</span>
diff --git a/app/assets/javascripts/issuables_list/components/issuable_list_root_app.vue b/app/assets/javascripts/issuables_list/components/issuable_list_root_app.vue
index 27a04da9541..49a89d15c35 100644
--- a/app/assets/javascripts/issuables_list/components/issuable_list_root_app.vue
+++ b/app/assets/javascripts/issuables_list/components/issuable_list_root_app.vue
@@ -1,7 +1,11 @@
<script>
import { GlAlert, GlLabel } from '@gitlab/ui';
import getIssuesListDetailsQuery from '../queries/get_issues_list_details.query.graphql';
-import { calculateJiraImportLabel, isFinished, isInProgress } from '~/jira_import/utils';
+import {
+ calculateJiraImportLabel,
+ isFinished,
+ isInProgress,
+} from '~/jira_import/utils/jira_import_utils';
export default {
name: 'IssuableListRoot',
diff --git a/app/assets/javascripts/issuables_list/components/issuables_list_app.vue b/app/assets/javascripts/issuables_list/components/issuables_list_app.vue
index 640827fe564..1c395fd9795 100644
--- a/app/assets/javascripts/issuables_list/components/issuables_list_app.vue
+++ b/app/assets/javascripts/issuables_list/components/issuables_list_app.vue
@@ -245,7 +245,7 @@ export default {
<template>
<ul v-if="loading" class="content-list">
- <li v-for="n in $options.LOADING_LIST_ITEMS_LENGTH" :key="n" class="issue">
+ <li v-for="n in $options.LOADING_LIST_ITEMS_LENGTH" :key="n" class="issue gl-px-5! gl-py-5!">
<gl-skeleton-loading />
</li>
</ul>
diff --git a/app/assets/javascripts/issue.js b/app/assets/javascripts/issue.js
index 4b53225e100..252e8e92f5e 100644
--- a/app/assets/javascripts/issue.js
+++ b/app/assets/javascripts/issue.js
@@ -6,6 +6,7 @@ import { addDelimiter } from './lib/utils/text_utility';
import flash from './flash';
import CreateMergeRequestDropdown from './create_merge_request_dropdown';
import IssuablesHelper from './helpers/issuables_helper';
+import { joinPaths } from '~/lib/utils/url_utility';
import { __ } from './locale';
export default class Issue {
@@ -14,6 +15,16 @@ export default class Issue {
if ($('.js-close-blocked-issue-warning').length) this.initIssueWarningBtnEventListener();
+ if ($('.js-alert-moved-from-service-desk-warning').length) {
+ const trimmedPathname = window.location.pathname.slice(1);
+ this.alertMovedFromServiceDeskDismissedKey = joinPaths(
+ trimmedPathname,
+ 'alert-issue-moved-from-service-desk-dismissed',
+ );
+
+ this.initIssueMovedFromServiceDeskDismissHandler();
+ }
+
Issue.$btnNewBranch = $('#new-branch');
Issue.createMrDropdownWrap = document.querySelector('.create-mr-dropdown-wrap');
@@ -169,6 +180,21 @@ export default class Issue {
});
}
+ initIssueMovedFromServiceDeskDismissHandler() {
+ const alertMovedFromServiceDeskWarning = $('.js-alert-moved-from-service-desk-warning');
+
+ if (!localStorage.getItem(this.alertMovedFromServiceDeskDismissedKey)) {
+ alertMovedFromServiceDeskWarning.show();
+ }
+
+ alertMovedFromServiceDeskWarning.on('click', '.js-close', e => {
+ e.preventDefault();
+ e.stopImmediatePropagation();
+ alertMovedFromServiceDeskWarning.remove();
+ localStorage.setItem(this.alertMovedFromServiceDeskDismissedKey, true);
+ });
+ }
+
static submitNoteForm(form) {
const noteText = form.find('textarea.js-note-text').val();
if (noteText && noteText.trim().length > 0) {
diff --git a/app/assets/javascripts/issue_show/components/app.vue b/app/assets/javascripts/issue_show/components/app.vue
index 8cf2cda64a4..09acfd1cfae 100644
--- a/app/assets/javascripts/issue_show/components/app.vue
+++ b/app/assets/javascripts/issue_show/components/app.vue
@@ -1,9 +1,10 @@
<script>
+import { GlIcon, GlIntersectionObserver } from '@gitlab/ui';
import Visibility from 'visibilityjs';
import { __, s__, sprintf } from '~/locale';
import createFlash from '~/flash';
-import { visitUrl } from '../../lib/utils/url_utility';
-import Poll from '../../lib/utils/poll';
+import { visitUrl } from '~/lib/utils/url_utility';
+import Poll from '~/lib/utils/poll';
import eventHub from '../event_hub';
import Service from '../services/index';
import Store from '../stores';
@@ -12,10 +13,13 @@ import descriptionComponent from './description.vue';
import editedComponent from './edited.vue';
import formComponent from './form.vue';
import PinnedLinks from './pinned_links.vue';
-import recaptchaModalImplementor from '../../vue_shared/mixins/recaptcha_modal_implementor';
+import recaptchaModalImplementor from '~/vue_shared/mixins/recaptcha_modal_implementor';
+import { IssuableStatus, IssuableStatusText, IssuableType } from '../constants';
export default {
components: {
+ GlIcon,
+ GlIntersectionObserver,
descriptionComponent,
titleComponent,
editedComponent,
@@ -58,12 +62,22 @@ export default {
zoomMeetingUrl: {
type: String,
required: false,
- default: null,
+ default: '',
+ },
+ publishedIncidentUrl: {
+ type: String,
+ required: false,
+ default: '',
},
issuableRef: {
type: String,
required: true,
},
+ issuableStatus: {
+ type: String,
+ required: false,
+ default: '',
+ },
initialTitleHtml: {
type: String,
required: true,
@@ -157,6 +171,7 @@ export default {
state: store.state,
showForm: false,
templatesRequested: false,
+ isStickyHeaderShowing: false,
};
},
computed: {
@@ -191,6 +206,18 @@ export default {
defaultErrorMessage() {
return sprintf(s__('Error updating %{issuableType}'), { issuableType: this.issuableType });
},
+ isOpenStatus() {
+ return this.issuableStatus === IssuableStatus.Open;
+ },
+ statusIcon() {
+ return this.isOpenStatus ? 'issue-open-m' : 'mobile-issue-close';
+ },
+ statusText() {
+ return IssuableStatusText[this.issuableStatus];
+ },
+ shouldShowStickyHeader() {
+ return this.isStickyHeaderShowing && this.issuableType === IssuableType.Issue;
+ },
},
created() {
this.service = new Service(this.endpoint);
@@ -344,6 +371,14 @@ export default {
);
});
},
+
+ hideStickyHeader() {
+ this.isStickyHeaderShowing = false;
+ },
+
+ showStickyHeader() {
+ this.isStickyHeaderShowing = true;
+ },
},
};
</script>
@@ -380,7 +415,40 @@ export default {
:title-text="state.titleText"
:show-inline-edit-button="showInlineEditButton"
/>
- <pinned-links :zoom-meeting-url="zoomMeetingUrl" />
+
+ <gl-intersection-observer @appear="hideStickyHeader" @disappear="showStickyHeader">
+ <transition name="issuable-header-slide">
+ <div
+ v-if="shouldShowStickyHeader"
+ class="issue-sticky-header gl-fixed gl-z-index-2 gl-bg-white gl-border-1 gl-border-b-solid gl-border-b-gray-200 gl-py-3"
+ data-testid="issue-sticky-header"
+ >
+ <div
+ class="issue-sticky-header-text gl-display-flex gl-align-items-center gl-mx-auto gl-px-5"
+ >
+ <p
+ class="issuable-status-box status-box gl-my-0"
+ :class="[isOpenStatus ? 'status-box-open' : 'status-box-issue-closed']"
+ >
+ <gl-icon :name="statusIcon" class="gl-display-block d-sm-none gl-h-6!" />
+ <span class="gl-display-none d-sm-block">{{ statusText }}</span>
+ </p>
+ <p
+ class="gl-font-weight-bold gl-overflow-hidden gl-white-space-nowrap gl-text-overflow-ellipsis gl-my-0"
+ :title="state.titleText"
+ >
+ {{ state.titleText }}
+ </p>
+ </div>
+ </div>
+ </transition>
+ </gl-intersection-observer>
+
+ <pinned-links
+ :zoom-meeting-url="zoomMeetingUrl"
+ :published-incident-url="publishedIncidentUrl"
+ />
+
<description-component
v-if="state.descriptionHtml"
:can-update="canUpdate"
@@ -393,6 +461,7 @@ export default {
:lock-version="state.lock_version"
@taskListUpdateFailed="updateStoreState"
/>
+
<edited-component
v-if="hasUpdated"
:updated-at="state.updatedAt"
diff --git a/app/assets/javascripts/issue_show/components/pinned_links.vue b/app/assets/javascripts/issue_show/components/pinned_links.vue
index 965e8a3d751..4b50acceb62 100644
--- a/app/assets/javascripts/issue_show/components/pinned_links.vue
+++ b/app/assets/javascripts/issue_show/components/pinned_links.vue
@@ -11,21 +11,40 @@ export default {
zoomMeetingUrl: {
type: String,
required: false,
- default: null,
+ default: '',
+ },
+ publishedIncidentUrl: {
+ type: String,
+ required: false,
+ default: '',
},
},
};
</script>
<template>
- <div v-if="zoomMeetingUrl" class="border-bottom mb-3 mt-n2">
- <gl-link
- :href="zoomMeetingUrl"
- target="_blank"
- class="btn btn-inverted btn-secondary btn-sm text-dark mb-3"
- >
- <icon name="brand-zoom" :size="14" />
- <strong class="vertical-align-top">{{ __('Join Zoom meeting') }}</strong>
- </gl-link>
+ <div class="border-bottom gl-mb-6 gl-display-flex gl-justify-content-start">
+ <div v-if="publishedIncidentUrl" class="gl-pr-3">
+ <gl-link
+ :href="publishedIncidentUrl"
+ target="_blank"
+ class="btn btn-inverted btn-secondary btn-sm text-dark mb-3"
+ data-testid="publishedIncidentUrl"
+ >
+ <icon name="tanuki" :size="14" />
+ <strong class="vertical-align-top">{{ __('Published on status page') }}</strong>
+ </gl-link>
+ </div>
+ <div v-if="zoomMeetingUrl">
+ <gl-link
+ :href="zoomMeetingUrl"
+ target="_blank"
+ class="btn btn-inverted btn-secondary btn-sm text-dark mb-3"
+ data-testid="zoomMeetingUrl"
+ >
+ <icon name="brand-zoom" :size="14" />
+ <strong class="vertical-align-top">{{ __('Join Zoom meeting') }}</strong>
+ </gl-link>
+ </div>
</div>
</template>
diff --git a/app/assets/javascripts/issue_show/constants.js b/app/assets/javascripts/issue_show/constants.js
new file mode 100644
index 00000000000..d73cc8cf007
--- /dev/null
+++ b/app/assets/javascripts/issue_show/constants.js
@@ -0,0 +1,17 @@
+import { __ } from '~/locale';
+
+export const IssuableStatus = {
+ Open: 'opened',
+ Closed: 'closed',
+};
+
+export const IssuableStatusText = {
+ [IssuableStatus.Open]: __('Open'),
+ [IssuableStatus.Closed]: __('Closed'),
+};
+
+export const IssuableType = {
+ Issue: 'issue',
+ Epic: 'epic',
+ MergeRequest: 'merge_request',
+};
diff --git a/app/assets/javascripts/jira_import/components/jira_import_app.vue b/app/assets/javascripts/jira_import/components/jira_import_app.vue
index d1570f52c8c..ef0fc4716dd 100644
--- a/app/assets/javascripts/jira_import/components/jira_import_app.vue
+++ b/app/assets/javascripts/jira_import/components/jira_import_app.vue
@@ -4,7 +4,8 @@ import { last } from 'lodash';
import { __ } from '~/locale';
import getJiraImportDetailsQuery from '../queries/get_jira_import_details.query.graphql';
import initiateJiraImportMutation from '../queries/initiate_jira_import.mutation.graphql';
-import { IMPORT_STATE, isInProgress } from '../utils';
+import { addInProgressImportToStore } from '../utils/cache_update';
+import { isInProgress, extractJiraProjectsOptions } from '../utils/jira_import_utils';
import JiraImportForm from './jira_import_form.vue';
import JiraImportProgress from './jira_import_progress.vue';
import JiraImportSetup from './jira_import_setup.vue';
@@ -20,14 +21,14 @@ export default {
JiraImportSetup,
},
props: {
- isJiraConfigured: {
- type: Boolean,
- required: true,
- },
inProgressIllustration: {
type: String,
required: true,
},
+ isJiraConfigured: {
+ type: Boolean,
+ required: true,
+ },
issuesPath: {
type: String,
required: true,
@@ -36,10 +37,6 @@ export default {
type: String,
required: true,
},
- jiraProjects: {
- type: Array,
- required: true,
- },
projectPath: {
type: String,
required: true,
@@ -51,6 +48,7 @@ export default {
},
data() {
return {
+ jiraImportDetails: {},
errorMessage: '',
showAlert: false,
selectedProject: undefined,
@@ -65,8 +63,10 @@ export default {
};
},
update: ({ project }) => ({
- status: project.jiraImportStatus,
imports: project.jiraImports.nodes,
+ isInProgress: isInProgress(project.jiraImportStatus),
+ mostRecentImport: last(project.jiraImports.nodes),
+ projects: extractJiraProjectsOptions(project.services.nodes[0].projects.nodes),
}),
skip() {
return !this.isJiraConfigured;
@@ -74,35 +74,22 @@ export default {
},
},
computed: {
- isImportInProgress() {
- return isInProgress(this.jiraImportDetails?.status);
- },
- jiraProjectsOptions() {
- return this.jiraProjects.map(([text, value]) => ({ text, value }));
- },
- mostRecentImport() {
- // The backend returns JiraImports ordered by created_at asc in app/models/project.rb
- return last(this.jiraImportDetails?.imports);
- },
- numberOfPreviousImportsForProject() {
- return this.jiraImportDetails?.imports?.reduce?.(
+ numberOfPreviousImports() {
+ return this.jiraImportDetails.imports?.reduce?.(
(acc, jiraProject) => (jiraProject.jiraProjectKey === this.selectedProject ? acc + 1 : acc),
0,
);
},
+ hasPreviousImports() {
+ return this.numberOfPreviousImports > 0;
+ },
importLabel() {
return this.selectedProject
- ? `jira-import::${this.selectedProject}-${this.numberOfPreviousImportsForProject + 1}`
+ ? `jira-import::${this.selectedProject}-${this.numberOfPreviousImports + 1}`
: 'jira-import::KEY-1';
},
- hasPreviousImports() {
- return this.numberOfPreviousImportsForProject > 0;
- },
},
methods: {
- dismissAlert() {
- this.showAlert = false;
- },
initiateJiraImport(project) {
this.$apollo
.mutate({
@@ -113,39 +100,8 @@ export default {
jiraProjectKey: project,
},
},
- update: (store, { data }) => {
- if (data.jiraImportStart.errors.length) {
- return;
- }
-
- const cacheData = store.readQuery({
- query: getJiraImportDetailsQuery,
- variables: {
- fullPath: this.projectPath,
- },
- });
-
- store.writeQuery({
- query: getJiraImportDetailsQuery,
- variables: {
- fullPath: this.projectPath,
- },
- data: {
- project: {
- jiraImportStatus: IMPORT_STATE.SCHEDULED,
- jiraImports: {
- nodes: [
- ...cacheData.project.jiraImports.nodes,
- data.jiraImportStart.jiraImport,
- ],
- __typename: 'JiraImportConnection',
- },
- // eslint-disable-next-line @gitlab/require-i18n-strings
- __typename: 'Project',
- },
- },
- });
- },
+ update: (store, { data }) =>
+ addInProgressImportToStore(store, data.jiraImportStart, this.projectPath),
})
.then(({ data }) => {
if (data.jiraImportStart.errors.length) {
@@ -160,7 +116,13 @@ export default {
this.errorMessage = message;
this.showAlert = true;
},
+ dismissAlert() {
+ this.showAlert = false;
+ },
},
+ previousImportsMessage: __(
+ 'You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues.',
+ ),
};
</script>
@@ -170,16 +132,8 @@ export default {
{{ errorMessage }}
</gl-alert>
<gl-alert v-if="hasPreviousImports" variant="warning" :dismissible="false">
- <gl-sprintf
- :message="
- __(
- 'You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues.',
- )
- "
- >
- <template #numberOfPreviousImportsForProject>{{
- numberOfPreviousImportsForProject
- }}</template>
+ <gl-sprintf :message="$options.previousImportsMessage">
+ <template #numberOfPreviousImports>{{ numberOfPreviousImports }}</template>
</gl-sprintf>
</gl-alert>
@@ -190,11 +144,11 @@ export default {
/>
<gl-loading-icon v-else-if="$apollo.loading" size="md" class="mt-3" />
<jira-import-progress
- v-else-if="isImportInProgress"
+ v-else-if="jiraImportDetails.isInProgress"
:illustration="inProgressIllustration"
- :import-initiator="mostRecentImport.scheduledBy.name"
- :import-project="mostRecentImport.jiraProjectKey"
- :import-time="mostRecentImport.scheduledAt"
+ :import-initiator="jiraImportDetails.mostRecentImport.scheduledBy.name"
+ :import-project="jiraImportDetails.mostRecentImport.jiraProjectKey"
+ :import-time="jiraImportDetails.mostRecentImport.scheduledAt"
:issues-path="issuesPath"
/>
<jira-import-form
@@ -202,7 +156,7 @@ export default {
v-model="selectedProject"
:import-label="importLabel"
:issues-path="issuesPath"
- :jira-projects="jiraProjectsOptions"
+ :jira-projects="jiraImportDetails.projects"
@initiateJiraImport="initiateJiraImport"
/>
</div>
diff --git a/app/assets/javascripts/jira_import/index.js b/app/assets/javascripts/jira_import/index.js
index b576668fe7c..924cc7e6864 100644
--- a/app/assets/javascripts/jira_import/index.js
+++ b/app/assets/javascripts/jira_import/index.js
@@ -28,7 +28,6 @@ export default function mountJiraImportApp() {
isJiraConfigured: parseBoolean(el.dataset.isJiraConfigured),
issuesPath: el.dataset.issuesPath,
jiraIntegrationPath: el.dataset.jiraIntegrationPath,
- jiraProjects: el.dataset.jiraProjects ? JSON.parse(el.dataset.jiraProjects) : [],
projectPath: el.dataset.projectPath,
setupIllustration: el.dataset.setupIllustration,
},
diff --git a/app/assets/javascripts/jira_import/queries/get_jira_import_details.query.graphql b/app/assets/javascripts/jira_import/queries/get_jira_import_details.query.graphql
index aa8d03c7f17..2aacc5cf668 100644
--- a/app/assets/javascripts/jira_import/queries/get_jira_import_details.query.graphql
+++ b/app/assets/javascripts/jira_import/queries/get_jira_import_details.query.graphql
@@ -8,5 +8,17 @@ query($fullPath: ID!) {
...JiraImport
}
}
+ services(active: true, type: JIRA_SERVICE) {
+ nodes {
+ ... on JiraService {
+ projects {
+ nodes {
+ key
+ name
+ }
+ }
+ }
+ }
+ }
}
}
diff --git a/app/assets/javascripts/jira_import/utils.js b/app/assets/javascripts/jira_import/utils.js
deleted file mode 100644
index aa10dfc8099..00000000000
--- a/app/assets/javascripts/jira_import/utils.js
+++ /dev/null
@@ -1,59 +0,0 @@
-import { last } from 'lodash';
-
-export const IMPORT_STATE = {
- FAILED: 'failed',
- FINISHED: 'finished',
- NONE: 'none',
- SCHEDULED: 'scheduled',
- STARTED: 'started',
-};
-
-export const isInProgress = state =>
- state === IMPORT_STATE.SCHEDULED || state === IMPORT_STATE.STARTED;
-
-export const isFinished = state => state === IMPORT_STATE.FINISHED;
-
-/**
- * Calculates the label title for the most recent Jira import.
- *
- * @param {Object[]} jiraImports - List of Jira imports
- * @param {string} jiraImports[].jiraProjectKey - Jira project key
- * @returns {string} - A label title
- */
-const calculateJiraImportLabelTitle = jiraImports => {
- const mostRecentJiraProjectKey = last(jiraImports)?.jiraProjectKey;
- const jiraProjectImportCount = jiraImports.filter(
- jiraImport => jiraImport.jiraProjectKey === mostRecentJiraProjectKey,
- ).length;
- return `jira-import::${mostRecentJiraProjectKey}-${jiraProjectImportCount}`;
-};
-
-/**
- * Finds the label color from a list of labels.
- *
- * @param {string} labelTitle - Label title
- * @param {Object[]} labels - List of labels
- * @param {string} labels[].title - Label title
- * @param {string} labels[].color - Label color
- * @returns {string} - The label color associated with the given labelTitle
- */
-const calculateJiraImportLabelColor = (labelTitle, labels) =>
- labels.find(label => label.title === labelTitle)?.color;
-
-/**
- * Calculates the label for the most recent Jira import.
- *
- * @param {Object[]} jiraImports - List of Jira imports
- * @param {string} jiraImports[].jiraProjectKey - Jira project key
- * @param {Object[]} labels - List of labels
- * @param {string} labels[].title - Label title
- * @param {string} labels[].color - Label color
- * @returns {{color: string, title: string}} - A label object containing a label color and title
- */
-export const calculateJiraImportLabel = (jiraImports, labels) => {
- const title = calculateJiraImportLabelTitle(jiraImports);
- return {
- color: calculateJiraImportLabelColor(title, labels),
- title,
- };
-};
diff --git a/app/assets/javascripts/jira_import/utils/cache_update.js b/app/assets/javascripts/jira_import/utils/cache_update.js
new file mode 100644
index 00000000000..6aaf2010866
--- /dev/null
+++ b/app/assets/javascripts/jira_import/utils/cache_update.js
@@ -0,0 +1,37 @@
+import getJiraImportDetailsQuery from '../queries/get_jira_import_details.query.graphql';
+import { IMPORT_STATE } from './jira_import_utils';
+
+export const addInProgressImportToStore = (store, jiraImportStart, fullPath) => {
+ if (jiraImportStart.errors.length) {
+ return;
+ }
+
+ const queryDetails = {
+ query: getJiraImportDetailsQuery,
+ variables: {
+ fullPath,
+ },
+ };
+
+ const cacheData = store.readQuery({
+ ...queryDetails,
+ });
+
+ store.writeQuery({
+ ...queryDetails,
+ data: {
+ project: {
+ ...cacheData.project,
+ jiraImportStatus: IMPORT_STATE.SCHEDULED,
+ jiraImports: {
+ ...cacheData.project.jiraImports,
+ nodes: cacheData.project.jiraImports.nodes.concat(jiraImportStart.jiraImport),
+ },
+ },
+ },
+ });
+};
+
+export default {
+ addInProgressImportToStore,
+};
diff --git a/app/assets/javascripts/jira_import/utils/jira_import_utils.js b/app/assets/javascripts/jira_import/utils/jira_import_utils.js
new file mode 100644
index 00000000000..e82a3f44a29
--- /dev/null
+++ b/app/assets/javascripts/jira_import/utils/jira_import_utils.js
@@ -0,0 +1,70 @@
+import { last } from 'lodash';
+
+export const IMPORT_STATE = {
+ FAILED: 'failed',
+ FINISHED: 'finished',
+ NONE: 'none',
+ SCHEDULED: 'scheduled',
+ STARTED: 'started',
+};
+
+export const isInProgress = state =>
+ state === IMPORT_STATE.SCHEDULED || state === IMPORT_STATE.STARTED;
+
+export const isFinished = state => state === IMPORT_STATE.FINISHED;
+
+/**
+ * Converts the list of Jira projects into a format consumable by GlFormSelect.
+ *
+ * @param {Object[]} projects - List of Jira projects
+ * @param {string} projects[].key - Jira project key
+ * @param {string} projects[].name - Jira project name
+ * @returns {Object[]} - List of Jira projects in a format consumable by GlFormSelect
+ */
+export const extractJiraProjectsOptions = projects =>
+ projects.map(({ key, name }) => ({ text: `${name} (${key})`, value: key }));
+
+/**
+ * Calculates the label title for the most recent Jira import.
+ *
+ * @param {Object[]} jiraImports - List of Jira imports
+ * @param {string} jiraImports[].jiraProjectKey - Jira project key
+ * @returns {string} - A label title
+ */
+const calculateJiraImportLabelTitle = jiraImports => {
+ const mostRecentJiraProjectKey = last(jiraImports)?.jiraProjectKey;
+ const jiraProjectImportCount = jiraImports.filter(
+ jiraImport => jiraImport.jiraProjectKey === mostRecentJiraProjectKey,
+ ).length;
+ return `jira-import::${mostRecentJiraProjectKey}-${jiraProjectImportCount}`;
+};
+
+/**
+ * Finds the label color from a list of labels.
+ *
+ * @param {string} labelTitle - Label title
+ * @param {Object[]} labels - List of labels
+ * @param {string} labels[].title - Label title
+ * @param {string} labels[].color - Label color
+ * @returns {string} - The label color associated with the given labelTitle
+ */
+const calculateJiraImportLabelColor = (labelTitle, labels) =>
+ labels.find(label => label.title === labelTitle)?.color;
+
+/**
+ * Calculates the label for the most recent Jira import.
+ *
+ * @param {Object[]} jiraImports - List of Jira imports
+ * @param {string} jiraImports[].jiraProjectKey - Jira project key
+ * @param {Object[]} labels - List of labels
+ * @param {string} labels[].title - Label title
+ * @param {string} labels[].color - Label color
+ * @returns {{color: string, title: string}} - A label object containing a label color and title
+ */
+export const calculateJiraImportLabel = (jiraImports, labels) => {
+ const title = calculateJiraImportLabelTitle(jiraImports);
+ return {
+ color: calculateJiraImportLabelColor(title, labels),
+ title,
+ };
+};
diff --git a/app/assets/javascripts/jobs/components/artifacts_block.vue b/app/assets/javascripts/jobs/components/artifacts_block.vue
index 0bce860df91..b2f9bf2a348 100644
--- a/app/assets/javascripts/jobs/components/artifacts_block.vue
+++ b/app/assets/javascripts/jobs/components/artifacts_block.vue
@@ -17,11 +17,14 @@ export default {
},
computed: {
isExpired() {
- return this.artifact.expired;
+ return this.artifact?.expired && !this.isLocked;
+ },
+ isLocked() {
+ return this.artifact?.locked;
},
// Only when the key is `false` we can render this block
willExpire() {
- return this.artifact.expired === false;
+ return this.artifact?.expired === false && !this.isLocked;
},
},
};
@@ -29,42 +32,45 @@ export default {
<template>
<div class="block">
<div class="title font-weight-bold">{{ s__('Job|Job artifacts') }}</div>
-
<p
v-if="isExpired || willExpire"
- :class="{
- 'js-artifacts-removed': isExpired,
- 'js-artifacts-will-be-removed': willExpire,
- }"
class="build-detail-row"
+ data-testid="artifacts-remove-timeline"
>
<span v-if="isExpired">{{ s__('Job|The artifacts were removed') }}</span>
<span v-if="willExpire">{{ s__('Job|The artifacts will be removed') }}</span>
<timeago-tooltip v-if="artifact.expire_at" :time="artifact.expire_at" />
</p>
-
+ <p v-else-if="isLocked" class="build-detail-row">
+ <span data-testid="job-locked-message">{{
+ s__(
+ 'Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available.',
+ )
+ }}</span>
+ </p>
<div class="btn-group d-flex prepend-top-10" role="group">
<gl-link
v-if="artifact.keep_path"
:href="artifact.keep_path"
- class="js-keep-artifacts btn btn-sm btn-default"
+ class="btn btn-sm btn-default"
data-method="post"
+ data-testid="keep-artifacts"
>{{ s__('Job|Keep') }}</gl-link
>
-
<gl-link
v-if="artifact.download_path"
:href="artifact.download_path"
- class="js-download-artifacts btn btn-sm btn-default"
+ class="btn btn-sm btn-default"
download
rel="nofollow"
+ data-testid="download-artifacts"
>{{ s__('Job|Download') }}</gl-link
>
-
<gl-link
v-if="artifact.browse_path"
:href="artifact.browse_path"
- class="js-browse-artifacts btn btn-sm btn-default"
+ class="btn btn-sm btn-default"
+ data-testid="browse-artifacts"
>{{ s__('Job|Browse') }}</gl-link
>
</div>
diff --git a/app/assets/javascripts/jobs/components/commit_block.vue b/app/assets/javascripts/jobs/components/commit_block.vue
index 88649ddbdb7..72a5ff01672 100644
--- a/app/assets/javascripts/jobs/components/commit_block.vue
+++ b/app/assets/javascripts/jobs/components/commit_block.vue
@@ -53,6 +53,6 @@ export default {
</span>
</p>
- <p class="append-bottom-0">{{ commit.title }}</p>
+ <p class="gl-mb-0">{{ commit.title }}</p>
</div>
</template>
diff --git a/app/assets/javascripts/jobs/components/environments_block.vue b/app/assets/javascripts/jobs/components/environments_block.vue
index 28cc03c88cb..c34a3488dbd 100644
--- a/app/assets/javascripts/jobs/components/environments_block.vue
+++ b/app/assets/javascripts/jobs/components/environments_block.vue
@@ -277,7 +277,7 @@ export default {
<div class="prepend-top-default append-bottom-default js-environment-container">
<div class="environment-information">
<ci-icon :status="iconStatus" />
- <p class="inline append-bottom-0" v-html="environment"></p>
+ <p class="inline gl-mb-0" v-html="environment"></p>
</div>
</div>
</template>
diff --git a/app/assets/javascripts/jobs/components/stages_dropdown.vue b/app/assets/javascripts/jobs/components/stages_dropdown.vue
index ddcfc3d6db6..116331d9549 100644
--- a/app/assets/javascripts/jobs/components/stages_dropdown.vue
+++ b/app/assets/javascripts/jobs/components/stages_dropdown.vue
@@ -81,7 +81,7 @@ export default {
<button
type="button"
data-toggle="dropdown"
- class="js-selected-stage dropdown-menu-toggle prepend-top-8"
+ class="js-selected-stage dropdown-menu-toggle gl-mt-3"
>
{{ selectedStage }} <i class="fa fa-chevron-down"></i>
</button>
diff --git a/app/assets/javascripts/jobs/components/stuck_block.vue b/app/assets/javascripts/jobs/components/stuck_block.vue
index ec52d272168..da01269a50c 100644
--- a/app/assets/javascripts/jobs/components/stuck_block.vue
+++ b/app/assets/javascripts/jobs/components/stuck_block.vue
@@ -26,31 +26,31 @@ export default {
</script>
<template>
<div class="bs-callout bs-callout-warning">
- <p v-if="tags.length" class="js-stuck-with-tags append-bottom-0">
+ <p v-if="tags.length" class="js-stuck-with-tags gl-mb-0">
{{
s__(`This job is stuck because you don't have
- any active runners online with any of these tags assigned to them:`)
+ any active runners online or available with any of these tags assigned to them:`)
}}
<span v-for="(tag, index) in tags" :key="index" class="badge badge-primary append-right-4">
{{ tag }}
</span>
</p>
- <p v-else-if="hasNoRunnersForProject" class="js-stuck-no-runners append-bottom-0">
+ <p v-else-if="hasNoRunnersForProject" class="js-stuck-no-runners gl-mb-0">
{{
s__(`Job|This job is stuck because the project
doesn't have any runners online assigned to it.`)
}}
</p>
- <p v-else class="js-stuck-no-active-runner append-bottom-0">
+ <p v-else class="js-stuck-no-active-runner gl-mb-0">
{{
s__(`This job is stuck because you don't
have any active runners that can run this job.`)
}}
</p>
- {{ __('Go to') }}
+ {{ __('Go to project') }}
<gl-link v-if="runnersPath" :href="runnersPath" class="js-runners-path">
- {{ __('Runners page') }}
+ {{ __('CI settings') }}
</gl-link>
</div>
</template>
diff --git a/app/assets/javascripts/jobs/components/trigger_block.vue b/app/assets/javascripts/jobs/components/trigger_block.vue
index 7c9b2824a43..1a076249fe7 100644
--- a/app/assets/javascripts/jobs/components/trigger_block.vue
+++ b/app/assets/javascripts/jobs/components/trigger_block.vue
@@ -46,7 +46,7 @@ export default {
<p
v-if="trigger.short_token"
class="js-short-token"
- :class="{ 'append-bottom-5': hasVariables, 'append-bottom-0': !hasVariables }"
+ :class="{ 'append-bottom-5': hasVariables, 'gl-mb-0': !hasVariables }"
>
<span class="font-weight-bold">{{ __('Trigger token:') }}</span> {{ trigger.short_token }}
</p>
diff --git a/app/assets/javascripts/jobs/components/unmet_prerequisites_block.vue b/app/assets/javascripts/jobs/components/unmet_prerequisites_block.vue
index 25a8da84873..633561c879e 100644
--- a/app/assets/javascripts/jobs/components/unmet_prerequisites_block.vue
+++ b/app/assets/javascripts/jobs/components/unmet_prerequisites_block.vue
@@ -17,7 +17,7 @@ export default {
</script>
<template>
<div class="bs-callout bs-callout-danger">
- <p class="js-failed-unmet-prerequisites append-bottom-0">
+ <p class="js-failed-unmet-prerequisites gl-mb-0">
{{
s__(`Job|This job failed because the necessary resources were not successfully created.`)
}}
diff --git a/app/assets/javascripts/lazy_loader.js b/app/assets/javascripts/lazy_loader.js
index a464290ffb5..75542267f37 100644
--- a/app/assets/javascripts/lazy_loader.js
+++ b/app/assets/javascripts/lazy_loader.js
@@ -15,7 +15,7 @@ export default class LazyLoader {
}
static supportsIntersectionObserver() {
- return 'IntersectionObserver' in window;
+ return Boolean(window.IntersectionObserver);
}
searchLazyImages() {
diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js
index 4a48852159a..a60748215ab 100644
--- a/app/assets/javascripts/lib/utils/common_utils.js
+++ b/app/assets/javascripts/lib/utils/common_utils.js
@@ -31,7 +31,7 @@ export const getProjectSlug = () => {
};
export const getGroupSlug = () => {
- if (isInGroupsPage()) {
+ if (isInProjectPage() || isInGroupsPage()) {
return $('body').data('group');
}
return null;
@@ -244,22 +244,28 @@ export const contentTop = () => {
);
};
-export const scrollToElement = element => {
+export const scrollToElement = (element, options = {}) => {
let $el = element;
if (!(element instanceof $)) {
$el = $(element);
}
const { top } = $el.offset();
+ const { offset = 0 } = options;
// eslint-disable-next-line no-jquery/no-animate
return $('body, html').animate(
{
- scrollTop: top - contentTop(),
+ scrollTop: top - contentTop() + offset,
},
200,
);
};
+export const scrollToElementWithContext = element => {
+ const offsetMultiplier = -0.1;
+ return scrollToElement(element, { offset: window.innerHeight * offsetMultiplier });
+};
+
/**
* Returns a function that can only be invoked once between
* each browser screen repaint.
@@ -718,6 +724,8 @@ export const convertObjectProps = (conversionFunction, obj = {}, options = {}) =
} else {
acc[conversionFunction(prop)] = convertObjectProps(conversionFunction, val, options);
}
+ } else if (isObjParameterArray) {
+ acc[prop] = val;
} else {
acc[conversionFunction(prop)] = val;
}
diff --git a/app/assets/javascripts/lib/utils/constants.js b/app/assets/javascripts/lib/utils/constants.js
index 9a61003ef30..eb6c9bf7eb6 100644
--- a/app/assets/javascripts/lib/utils/constants.js
+++ b/app/assets/javascripts/lib/utils/constants.js
@@ -1,2 +1,10 @@
export const BYTES_IN_KIB = 1024;
export const HIDDEN_CLASS = 'hidden';
+
+export const DATETIME_RANGE_TYPES = {
+ fixed: 'fixed',
+ anchored: 'anchored',
+ rolling: 'rolling',
+ open: 'open',
+ invalid: 'invalid',
+};
diff --git a/app/assets/javascripts/lib/utils/datetime_range.js b/app/assets/javascripts/lib/utils/datetime_range.js
index 9275b9e74e1..8efbcb89607 100644
--- a/app/assets/javascripts/lib/utils/datetime_range.js
+++ b/app/assets/javascripts/lib/utils/datetime_range.js
@@ -1,5 +1,6 @@
import dateformat from 'dateformat';
import { pick, omit, isEqual, isEmpty } from 'lodash';
+import { DATETIME_RANGE_TYPES } from './constants';
import { secondsToMilliseconds } from './datetime_utility';
const MINIMUM_DATE = new Date(0);
@@ -153,18 +154,22 @@ export function getRangeType(range) {
const { start, end, anchor, duration } = range;
if ((start || end) && !anchor && !duration) {
- return isValidDateString(start) && isValidDateString(end) ? 'fixed' : 'invalid';
+ return isValidDateString(start) && isValidDateString(end)
+ ? DATETIME_RANGE_TYPES.fixed
+ : DATETIME_RANGE_TYPES.invalid;
}
if (anchor && duration) {
- return isValidDateString(anchor) && isValidDuration(duration) ? 'anchored' : 'invalid';
+ return isValidDateString(anchor) && isValidDuration(duration)
+ ? DATETIME_RANGE_TYPES.anchored
+ : DATETIME_RANGE_TYPES.invalid;
}
if (duration && !anchor) {
- return isValidDuration(duration) ? 'rolling' : 'invalid';
+ return isValidDuration(duration) ? DATETIME_RANGE_TYPES.rolling : DATETIME_RANGE_TYPES.invalid;
}
if (anchor && !duration) {
- return isValidDateString(anchor) ? 'open' : 'invalid';
+ return isValidDateString(anchor) ? DATETIME_RANGE_TYPES.open : DATETIME_RANGE_TYPES.invalid;
}
- return 'invalid';
+ return DATETIME_RANGE_TYPES.invalid;
}
/**
diff --git a/app/assets/javascripts/lib/utils/dom_utils.js b/app/assets/javascripts/lib/utils/dom_utils.js
index 7933c234384..8fa235f8afb 100644
--- a/app/assets/javascripts/lib/utils/dom_utils.js
+++ b/app/assets/javascripts/lib/utils/dom_utils.js
@@ -12,3 +12,16 @@ export const canScrollUp = ({ scrollTop }, margin = 0) => scrollTop > margin;
export const canScrollDown = ({ scrollTop, offsetHeight, scrollHeight }, margin = 0) =>
scrollTop + offsetHeight < scrollHeight - margin;
+
+export const toggleContainerClasses = (containerEl, classList) => {
+ if (containerEl) {
+ // eslint-disable-next-line array-callback-return
+ Object.entries(classList).map(([key, value]) => {
+ if (value) {
+ containerEl.classList.add(key);
+ } else {
+ containerEl.classList.remove(key);
+ }
+ });
+ }
+};
diff --git a/app/assets/javascripts/lib/utils/text_utility.js b/app/assets/javascripts/lib/utils/text_utility.js
index 86714471823..be3fe1ed620 100644
--- a/app/assets/javascripts/lib/utils/text_utility.js
+++ b/app/assets/javascripts/lib/utils/text_utility.js
@@ -90,6 +90,13 @@ export const truncatePathMiddleToLength = (text, maxWidth) => {
while (returnText.length >= maxWidth) {
const textSplit = returnText.split('/').filter(s => s !== ELLIPSIS_CHAR);
+
+ if (textSplit.length === 0) {
+ // There are n - 1 path separators for n segments, so 2n - 1 <= maxWidth
+ const maxSegments = Math.floor((maxWidth + 1) / 2);
+ return new Array(maxSegments).fill(ELLIPSIS_CHAR).join('/');
+ }
+
const middleIndex = Math.floor(textSplit.length / 2);
returnText = textSplit
@@ -168,7 +175,7 @@ export const convertToCamelCase = string =>
* @param {*} string
*/
export const convertToSnakeCase = string =>
- slugifyWithUnderscore(string.match(/([a-zA-Z][^A-Z]*)/g).join(' '));
+ slugifyWithUnderscore((string.match(/([a-zA-Z][^A-Z]*)/g) || [string]).join(' '));
/**
* Converts a sentence to lower case from the second word onwards
diff --git a/app/assets/javascripts/lib/utils/url_utility.js b/app/assets/javascripts/lib/utils/url_utility.js
index 966e6d42b80..0472b8cf51f 100644
--- a/app/assets/javascripts/lib/utils/url_utility.js
+++ b/app/assets/javascripts/lib/utils/url_utility.js
@@ -109,9 +109,10 @@ export function mergeUrlParams(params, url) {
*
* @param {string[]} params - the query param names to remove
* @param {string} [url=windowLocation().href] - url from which the query param will be removed
+ * @param {boolean} skipEncoding - set to true when the url does not require encoding
* @returns {string} A copy of the original url but without the query param
*/
-export function removeParams(params, url = window.location.href) {
+export function removeParams(params, url = window.location.href, skipEncoding = false) {
const [rootAndQuery, fragment] = url.split('#');
const [root, query] = rootAndQuery.split('?');
@@ -119,12 +120,13 @@ export function removeParams(params, url = window.location.href) {
return url;
}
- const encodedParams = params.map(param => encodeURIComponent(param));
+ const removableParams = skipEncoding ? params : params.map(param => encodeURIComponent(param));
+
const updatedQuery = query
.split('&')
.filter(paramPair => {
const [foundParam] = paramPair.split('=');
- return encodedParams.indexOf(foundParam) < 0;
+ return removableParams.indexOf(foundParam) < 0;
})
.join('&');
@@ -242,6 +244,15 @@ export function isRootRelative(url) {
}
/**
+ * Returns true if url is a base64 data URL
+ *
+ * @param {String} url
+ */
+export function isBase64DataUrl(url) {
+ return /^data:[.\w+-]+\/[.\w+-]+;base64,/.test(url);
+}
+
+/**
* Returns true if url is an absolute or root-relative URL
*
* @param {String} url
diff --git a/app/assets/javascripts/logs/components/environment_logs.vue b/app/assets/javascripts/logs/components/environment_logs.vue
index 838652f7210..01a4cbd41f6 100644
--- a/app/assets/javascripts/logs/components/environment_logs.vue
+++ b/app/assets/javascripts/logs/components/environment_logs.vue
@@ -91,7 +91,7 @@ export default {
'setInitData',
'showEnvironment',
'fetchEnvironments',
- 'fetchLogs',
+ 'refreshPodLogs',
'fetchMoreLogsPrepend',
'dismissRequestEnvironmentsError',
'dismissInvalidTimeRangeWarning',
@@ -204,7 +204,7 @@ export default {
ref="scrollButtons"
class="flex-grow-0 pr-2 mb-2 controllers"
:scroll-down-button-disabled="scrollDownButtonDisabled"
- @refresh="fetchLogs()"
+ @refresh="refreshPodLogs()"
@scrollDown="scrollDown"
/>
</div>
diff --git a/app/assets/javascripts/logs/constants.js b/app/assets/javascripts/logs/constants.js
index 51770aa7a1c..f83d369c6b8 100644
--- a/app/assets/javascripts/logs/constants.js
+++ b/app/assets/javascripts/logs/constants.js
@@ -1,3 +1,11 @@
export const dateFormatMask = 'mmm dd HH:MM:ss.l';
export const TOKEN_TYPE_POD_NAME = 'TOKEN_TYPE_POD_NAME';
+
+export const tracking = {
+ USED_SEARCH_BAR: 'used_search_bar',
+ POD_LOG_CHANGED: 'pod_log_changed',
+ TIME_RANGE_SET: 'time_range_set',
+ ENVIRONMENT_SELECTED: 'environment_selected',
+ REFRESH_POD_LOGS: 'refresh_pod_logs',
+};
diff --git a/app/assets/javascripts/logs/logs_tracking_helper.js b/app/assets/javascripts/logs/logs_tracking_helper.js
new file mode 100644
index 00000000000..91b0392f71f
--- /dev/null
+++ b/app/assets/javascripts/logs/logs_tracking_helper.js
@@ -0,0 +1,18 @@
+import Tracking from '~/tracking';
+
+/**
+ * The value of 1 in count, means there was one action performed
+ * related to the tracked action, in either of the following categories
+ * 1. Refreshing the logs
+ * 2. Select an environment
+ * 3. Change the time range
+ * 4. Use the search bar
+ */
+const trackLogs = label =>
+ Tracking.event(document.body.dataset.page, 'logs_view', {
+ label,
+ property: 'count',
+ value: 1,
+ });
+
+export default trackLogs;
diff --git a/app/assets/javascripts/logs/stores/actions.js b/app/assets/javascripts/logs/stores/actions.js
index a86d3c775a9..d828e8f8a3e 100644
--- a/app/assets/javascripts/logs/stores/actions.js
+++ b/app/assets/javascripts/logs/stores/actions.js
@@ -2,7 +2,8 @@ import { backOff } from '~/lib/utils/common_utils';
import httpStatusCodes from '~/lib/utils/http_status';
import axios from '~/lib/utils/axios_utils';
import { convertToFixedRange } from '~/lib/utils/datetime_range';
-import { TOKEN_TYPE_POD_NAME } from '../constants';
+import { TOKEN_TYPE_POD_NAME, tracking } from '../constants';
+import trackLogs from '../logs_tracking_helper';
import * as types from './mutation_types';
@@ -81,22 +82,27 @@ export const showFilteredLogs = ({ dispatch, commit }, filters = []) => {
commit(types.SET_CURRENT_POD_NAME, podName);
commit(types.SET_SEARCH, search);
- dispatch('fetchLogs');
+ dispatch('fetchLogs', tracking.USED_SEARCH_BAR);
};
export const showPodLogs = ({ dispatch, commit }, podName) => {
commit(types.SET_CURRENT_POD_NAME, podName);
- dispatch('fetchLogs');
+ dispatch('fetchLogs', tracking.POD_LOG_CHANGED);
};
export const setTimeRange = ({ dispatch, commit }, timeRange) => {
commit(types.SET_TIME_RANGE, timeRange);
- dispatch('fetchLogs');
+ dispatch('fetchLogs', tracking.TIME_RANGE_SET);
};
export const showEnvironment = ({ dispatch, commit }, environmentName) => {
commit(types.SET_PROJECT_ENVIRONMENT, environmentName);
- dispatch('fetchLogs');
+ dispatch('fetchLogs', tracking.ENVIRONMENT_SELECTED);
+};
+
+export const refreshPodLogs = ({ dispatch, commit }) => {
+ commit(types.REFRESH_POD_LOGS);
+ dispatch('fetchLogs', tracking.REFRESH_POD_LOGS);
};
/**
@@ -111,19 +117,22 @@ export const fetchEnvironments = ({ commit, dispatch }, environmentsPath) => {
.get(environmentsPath)
.then(({ data }) => {
commit(types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS, data.environments);
- dispatch('fetchLogs');
+ dispatch('fetchLogs', tracking.ENVIRONMENT_SELECTED);
})
.catch(() => {
commit(types.RECEIVE_ENVIRONMENTS_DATA_ERROR);
});
};
-export const fetchLogs = ({ commit, state }) => {
+export const fetchLogs = ({ commit, state }, trackingLabel) => {
commit(types.REQUEST_LOGS_DATA);
return requestLogsUntilData({ commit, state })
.then(({ data }) => {
const { pod_name, pods, logs, cursor } = data;
+ if (logs && logs.length > 0) {
+ trackLogs(trackingLabel);
+ }
commit(types.RECEIVE_LOGS_DATA_SUCCESS, { logs, cursor });
commit(types.SET_CURRENT_POD_NAME, pod_name);
commit(types.RECEIVE_PODS_DATA_SUCCESS, pods);
diff --git a/app/assets/javascripts/logs/stores/mutation_types.js b/app/assets/javascripts/logs/stores/mutation_types.js
index c1cc7eca52e..9010ec51817 100644
--- a/app/assets/javascripts/logs/stores/mutation_types.js
+++ b/app/assets/javascripts/logs/stores/mutation_types.js
@@ -19,6 +19,7 @@ export const REQUEST_LOGS_DATA_PREPEND = 'REQUEST_LOGS_DATA_PREPEND';
export const RECEIVE_LOGS_DATA_PREPEND_SUCCESS = 'RECEIVE_LOGS_DATA_PREPEND_SUCCESS';
export const RECEIVE_LOGS_DATA_PREPEND_ERROR = 'RECEIVE_LOGS_DATA_PREPEND_ERROR';
export const HIDE_REQUEST_LOGS_ERROR = 'HIDE_REQUEST_LOGS_ERROR';
+export const REFRESH_POD_LOGS = 'REFRESH_POD_LOGS';
export const RECEIVE_PODS_DATA_SUCCESS = 'RECEIVE_PODS_DATA_SUCCESS';
export const RECEIVE_PODS_DATA_ERROR = 'RECEIVE_PODS_DATA_ERROR';
diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js
index 713f57a2b27..5f5fd790f67 100644
--- a/app/assets/javascripts/main.js
+++ b/app/assets/javascripts/main.js
@@ -28,15 +28,15 @@ import initLayoutNav from './layout_nav';
import './feature_highlight/feature_highlight_options';
import LazyLoader from './lazy_loader';
import initLogoAnimation from './logo';
-import './frequent_items';
+import initFrequentItemDropdowns from './frequent_items';
import initBreadcrumbs from './breadcrumb';
import initUsagePingConsent from './usage_ping_consent';
import initPerformanceBar from './performance_bar';
-import initSearchAutocomplete from './search_autocomplete';
+import initGlobalSearchInput from './global_search_input';
import GlFieldErrors from './gl_field_errors';
import initUserPopovers from './user_popovers';
import initBroadcastNotifications from './broadcast_notification';
-import PersistentUserCallout from './persistent_user_callout';
+import initPersistentUserCallouts from './persistent_user_callouts';
import { initUserTracking } from './tracking';
import { __ } from './locale';
@@ -107,14 +107,10 @@ function deferredInitialisation() {
initUsagePingConsent();
initUserPopovers();
initBroadcastNotifications();
+ initFrequentItemDropdowns();
+ initPersistentUserCallouts();
- const recoverySettingsCallout = document.querySelector('.js-recovery-settings-callout');
- PersistentUserCallout.factory(recoverySettingsCallout);
-
- const usersOverLicenseCallout = document.querySelector('.js-users-over-license-callout');
- PersistentUserCallout.factory(usersOverLicenseCallout);
-
- if (document.querySelector('.search')) initSearchAutocomplete();
+ if (document.querySelector('.search')) initGlobalSearchInput();
addSelectOnFocusBehaviour('.js-select-on-focus');
diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js
index 1795a0dbdf8..6c63ab7cf95 100644
--- a/app/assets/javascripts/merge_request_tabs.js
+++ b/app/assets/javascripts/merge_request_tabs.js
@@ -126,6 +126,13 @@ export default class MergeRequestTabs {
bindEvents() {
$('.merge-request-tabs a[data-toggle="tabvue"]').on('click', this.clickTab);
+ window.addEventListener('popstate', event => {
+ if (event.state && event.state.action) {
+ this.tabShown(event.state.action, event.target.location);
+ this.currentAction = event.state.action;
+ this.eventHub.$emit('MergeRequestTabChange', this.getCurrentAction());
+ }
+ });
}
// Used in tests
@@ -155,6 +162,12 @@ export default class MergeRequestTabs {
} else if (action) {
const href = e.currentTarget.getAttribute('href');
this.tabShown(action, href);
+
+ if (this.setUrl) {
+ this.setCurrentAction(action);
+ }
+
+ this.eventHub.$emit('MergeRequestTabChange', this.getCurrentAction());
}
}
}
@@ -213,11 +226,6 @@ export default class MergeRequestTabs {
this.resetViewContainer();
this.destroyPipelinesView();
}
- if (this.setUrl) {
- this.setCurrentAction(action);
- }
-
- this.eventHub.$emit('MergeRequestTabChange', this.getCurrentAction());
} 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');
@@ -287,19 +295,25 @@ export default class MergeRequestTabs {
// Ensure parameters and hash come along for the ride
newState += location.search + location.hash;
- // TODO: Consider refactoring in light of turbolinks removal.
-
- // Replace the current history state with the new one without breaking
- // Turbolinks' history.
- //
- // See https://github.com/rails/turbolinks/issues/363
- window.history.replaceState(
- {
- url: newState,
- },
- document.title,
- newState,
- );
+ if (window.history.state && window.history.state.url && window.location.pathname !== newState) {
+ window.history.pushState(
+ {
+ url: newState,
+ action: this.currentAction,
+ },
+ document.title,
+ newState,
+ );
+ } else {
+ window.history.replaceState(
+ {
+ url: window.location.href,
+ action,
+ },
+ document.title,
+ window.location.href,
+ );
+ }
return newState;
}
diff --git a/app/assets/javascripts/milestone_select.js b/app/assets/javascripts/milestone_select.js
index e14212254a8..caa45184bfc 100644
--- a/app/assets/javascripts/milestone_select.js
+++ b/app/assets/javascripts/milestone_select.js
@@ -130,10 +130,13 @@ export default class MilestoneSelect {
fieldName: $dropdown.data('fieldName'),
text: milestone => escape(milestone.title),
id: milestone => {
- if (!useId && !$dropdown.is('.js-issuable-form-dropdown')) {
- return milestone.name;
+ if (milestone !== undefined) {
+ if (!useId && !$dropdown.is('.js-issuable-form-dropdown')) {
+ return milestone.name;
+ }
+
+ return milestone.id;
}
- return milestone.id;
},
hidden: () => {
$selectBox.hide();
diff --git a/app/assets/javascripts/monitoring/components/alert_widget.vue b/app/assets/javascripts/monitoring/components/alert_widget.vue
index 86a793c854e..5562981fe1c 100644
--- a/app/assets/javascripts/monitoring/components/alert_widget.vue
+++ b/app/assets/javascripts/monitoring/components/alert_widget.vue
@@ -234,11 +234,7 @@ export default {
class="alert-current-setting cursor-pointer d-flex"
@click="showModal"
>
- <gl-badge
- :variant="isFiring ? 'danger' : 'secondary'"
- pill
- class="d-flex-center text-truncate"
- >
+ <gl-badge :variant="isFiring ? 'danger' : 'neutral'" class="d-flex-center text-truncate">
<gl-icon name="warning" :size="16" class="flex-shrink-0" />
<span class="text-truncate gl-pl-1-deprecated-no-really-do-not-use-me">
<gl-sprintf
diff --git a/app/assets/javascripts/monitoring/components/alert_widget_form.vue b/app/assets/javascripts/monitoring/components/alert_widget_form.vue
index 74324daa1e3..b2d7ca0c4e0 100644
--- a/app/assets/javascripts/monitoring/components/alert_widget_form.vue
+++ b/app/assets/javascripts/monitoring/components/alert_widget_form.vue
@@ -238,7 +238,7 @@ export default {
<icon
v-gl-tooltip="$options.alertQueryText.descriptionTooltip"
name="question"
- class="prepend-left-4"
+ class="gl-ml-2"
/>
</div>
</template>
diff --git a/app/assets/javascripts/monitoring/components/charts/column.vue b/app/assets/javascripts/monitoring/components/charts/column.vue
index 7a2e3e1b511..d7d01def45e 100644
--- a/app/assets/javascripts/monitoring/components/charts/column.vue
+++ b/app/assets/javascripts/monitoring/components/charts/column.vue
@@ -5,7 +5,8 @@ import { getSvgIconPathContent } from '~/lib/utils/icon_utils';
import { chartHeight } from '../../constants';
import { makeDataSeries } from '~/helpers/monitor_helper';
import { graphDataValidatorForValues } from '../../utils';
-import { getYAxisOptions, getChartGrid } from './options';
+import { getTimeAxisOptions, getYAxisOptions, getChartGrid } from './options';
+import { timezones } from '../../format_date';
export default {
components: {
@@ -20,6 +21,11 @@ export default {
required: true,
validator: graphDataValidatorForValues.bind(null, false),
},
+ timezone: {
+ type: String,
+ required: false,
+ default: timezones.LOCAL,
+ },
},
data() {
return {
@@ -43,6 +49,8 @@ export default {
};
},
chartOptions() {
+ const xAxis = getTimeAxisOptions({ timezone: this.timezone });
+
const yAxis = {
...getYAxisOptions(this.graphData.yAxis),
scale: false,
@@ -50,8 +58,9 @@ export default {
return {
grid: getChartGrid(),
+ xAxis,
yAxis,
- dataZoom: this.dataZoomConfig,
+ dataZoom: [this.dataZoomConfig],
};
},
xAxisTitle() {
diff --git a/app/assets/javascripts/monitoring/components/charts/empty_chart.vue b/app/assets/javascripts/monitoring/components/charts/empty_chart.vue
index e015ef32d8c..ad176637538 100644
--- a/app/assets/javascripts/monitoring/components/charts/empty_chart.vue
+++ b/app/assets/javascripts/monitoring/components/charts/empty_chart.vue
@@ -23,10 +23,10 @@ export default {
<template>
<div class="d-flex flex-column justify-content-center">
<div
- class="prepend-top-8 svg-w-100 d-flex align-items-center"
+ class="gl-mt-3 svg-w-100 d-flex align-items-center"
:style="svgContainerStyle"
v-html="chartEmptyStateIllustration"
></div>
- <h5 class="text-center prepend-top-8">{{ __('No data to display') }}</h5>
+ <h5 class="text-center gl-mt-3">{{ __('No data to display') }}</h5>
</div>
</template>
diff --git a/app/assets/javascripts/monitoring/components/charts/heatmap.vue b/app/assets/javascripts/monitoring/components/charts/heatmap.vue
index 55a25ee09fd..f6f266dacf3 100644
--- a/app/assets/javascripts/monitoring/components/charts/heatmap.vue
+++ b/app/assets/javascripts/monitoring/components/charts/heatmap.vue
@@ -1,8 +1,8 @@
<script>
import { GlResizeObserverDirective } from '@gitlab/ui';
import { GlHeatmap } from '@gitlab/ui/dist/charts';
-import dateformat from 'dateformat';
import { graphDataValidatorForValues } from '../../utils';
+import { formatDate, timezones, formats } from '../../format_date';
export default {
components: {
@@ -17,6 +17,11 @@ export default {
required: true,
validator: graphDataValidatorForValues.bind(null, false),
},
+ timezone: {
+ type: String,
+ required: false,
+ default: timezones.LOCAL,
+ },
},
data() {
return {
@@ -43,7 +48,7 @@ export default {
return this.result.values.map(val => {
const [yLabel] = val;
- return dateformat(new Date(yLabel), 'HH:MM:ss');
+ return formatDate(new Date(yLabel), { format: formats.shortTime, timezone: this.timezone });
});
},
result() {
diff --git a/app/assets/javascripts/monitoring/components/charts/options.js b/app/assets/javascripts/monitoring/components/charts/options.js
index 09b03774580..f7822e69b1d 100644
--- a/app/assets/javascripts/monitoring/components/charts/options.js
+++ b/app/assets/javascripts/monitoring/components/charts/options.js
@@ -1,5 +1,6 @@
import { SUPPORTED_FORMATS, getFormatter } from '~/lib/utils/unit_format';
-import { s__ } from '~/locale';
+import { __, s__ } from '~/locale';
+import { formatDate, timezones, formats } from '../../format_date';
const yAxisBoundaryGap = [0.1, 0.1];
/**
@@ -21,6 +22,21 @@ const chartGridLeft = 75;
// Axis options
/**
+ * Axis types
+ * @see https://echarts.apache.org/en/option.html#xAxis.type
+ */
+export const axisTypes = {
+ /**
+ * Category axis, suitable for discrete category data.
+ */
+ category: 'category',
+ /**
+ * Time axis, suitable for continuous time series data.
+ */
+ time: 'time',
+};
+
+/**
* Converts .yml parameters to echarts axis options for data axis
* @param {Object} param - Dashboard .yml definition options
*/
@@ -58,6 +74,17 @@ export const getYAxisOptions = ({
};
};
+export const getTimeAxisOptions = ({ timezone = timezones.LOCAL } = {}) => ({
+ name: __('Time'),
+ type: axisTypes.time,
+ axisLabel: {
+ formatter: date => formatDate(date, { format: formats.shortTime, timezone }),
+ },
+ axisPointer: {
+ snap: false,
+ },
+});
+
// Chart grid
/**
diff --git a/app/assets/javascripts/monitoring/components/charts/stacked_column.vue b/app/assets/javascripts/monitoring/components/charts/stacked_column.vue
index 66ba20c125f..ac31d107e63 100644
--- a/app/assets/javascripts/monitoring/components/charts/stacked_column.vue
+++ b/app/assets/javascripts/monitoring/components/charts/stacked_column.vue
@@ -2,8 +2,11 @@
import { GlResizeObserverDirective } from '@gitlab/ui';
import { GlStackedColumnChart } from '@gitlab/ui/dist/charts';
import { getSvgIconPathContent } from '~/lib/utils/icon_utils';
-import { chartHeight } from '../../constants';
+import { chartHeight, legendLayoutTypes } from '../../constants';
+import { s__ } from '~/locale';
import { graphDataValidatorForValues } from '../../utils';
+import { getTimeAxisOptions, axisTypes } from './options';
+import { timezones } from '../../format_date';
export default {
components: {
@@ -18,6 +21,36 @@ export default {
required: true,
validator: graphDataValidatorForValues.bind(null, false),
},
+ timezone: {
+ type: String,
+ required: false,
+ default: timezones.LOCAL,
+ },
+ legendLayout: {
+ type: String,
+ required: false,
+ default: legendLayoutTypes.table,
+ },
+ legendAverageText: {
+ type: String,
+ required: false,
+ default: s__('Metrics|Avg'),
+ },
+ legendCurrentText: {
+ type: String,
+ required: false,
+ default: s__('Metrics|Current'),
+ },
+ legendMaxText: {
+ type: String,
+ required: false,
+ default: s__('Metrics|Max'),
+ },
+ legendMinText: {
+ type: String,
+ required: false,
+ default: s__('Metrics|Min'),
+ },
},
data() {
return {
@@ -28,7 +61,14 @@ export default {
},
computed: {
chartData() {
- return this.graphData.metrics.map(metric => metric.result[0].values.map(val => val[1]));
+ return this.graphData.metrics.map(({ result }) => {
+ // This needs a fix. Not only metrics[0] should be shown.
+ // See https://gitlab.com/gitlab-org/gitlab/-/issues/220492
+ if (!result || result.length === 0) {
+ return [];
+ }
+ return result[0].values.map(val => val[1]);
+ });
},
xAxisTitle() {
return this.graphData.x_label !== undefined ? this.graphData.x_label : '';
@@ -37,10 +77,17 @@ export default {
return this.graphData.y_label !== undefined ? this.graphData.y_label : '';
},
xAxisType() {
- return this.graphData.x_type !== undefined ? this.graphData.x_type : 'category';
+ // stacked-column component requires the x-axis to be of type `category`
+ return axisTypes.category;
},
groupBy() {
- return this.graphData.metrics[0].result[0].values.map(val => val[0]);
+ // This needs a fix. Not only metrics[0] should be shown.
+ // See https://gitlab.com/gitlab-org/gitlab/-/issues/220492
+ const { result } = this.graphData.metrics[0];
+ if (!result || result.length === 0) {
+ return [];
+ }
+ return result[0].values.map(val => val[0]);
},
dataZoomConfig() {
const handleIcon = this.svgs['scroll-handle'];
@@ -49,11 +96,15 @@ export default {
},
chartOptions() {
return {
- dataZoom: this.dataZoomConfig,
+ xAxis: {
+ ...getTimeAxisOptions({ timezone: this.timezone }),
+ type: this.xAxisType,
+ },
+ dataZoom: [this.dataZoomConfig],
};
},
seriesNames() {
- return this.graphData.metrics.map(metric => metric.series_name);
+ return this.graphData.metrics.map(metric => metric.label);
},
},
created() {
@@ -94,6 +145,11 @@ export default {
:width="width"
:height="height"
:series-names="seriesNames"
+ :legend-layout="legendLayout"
+ :legend-average-text="legendAverageText"
+ :legend-current-text="legendCurrentText"
+ :legend-max-text="legendMaxText"
+ :legend-min-text="legendMinText"
/>
</div>
</template>
diff --git a/app/assets/javascripts/monitoring/components/charts/time_series.vue b/app/assets/javascripts/monitoring/components/charts/time_series.vue
index 8f37a12af75..28af2d8ba77 100644
--- a/app/assets/javascripts/monitoring/components/charts/time_series.vue
+++ b/app/assets/javascripts/monitoring/components/charts/time_series.vue
@@ -2,18 +2,19 @@
import { omit, throttle } from 'lodash';
import { GlLink, GlDeprecatedButton, GlTooltip, GlResizeObserverDirective } from '@gitlab/ui';
import { GlAreaChart, GlLineChart, GlChartSeriesLabel } from '@gitlab/ui/dist/charts';
-import dateFormat from 'dateformat';
-import { s__, __ } from '~/locale';
+import { s__ } from '~/locale';
import { getSvgIconPathContent } from '~/lib/utils/icon_utils';
import Icon from '~/vue_shared/components/icon.vue';
-import { panelTypes, chartHeight, lineTypes, lineWidths, dateFormats } from '../../constants';
-import { getYAxisOptions, getChartGrid, getTooltipFormatter } from './options';
+import { panelTypes, chartHeight, lineTypes, lineWidths, legendLayoutTypes } from '../../constants';
+import { getYAxisOptions, getTimeAxisOptions, getChartGrid, getTooltipFormatter } from './options';
import { annotationsYAxis, generateAnnotationsSeries } from './annotations';
import { makeDataSeries } from '~/helpers/monitor_helper';
import { graphDataValidatorForValues } from '../../utils';
+import { formatDate, timezones } from '../../format_date';
+
+export const timestampToISODate = timestamp => new Date(timestamp).toISOString();
const THROTTLED_DATAZOOM_WAIT = 1000; // milliseconds
-const timestampToISODate = timestamp => new Date(timestamp).toISOString();
const events = {
datazoom: 'datazoom',
@@ -74,21 +75,41 @@ export default {
required: false,
default: () => [],
},
+ legendLayout: {
+ type: String,
+ required: false,
+ default: legendLayoutTypes.table,
+ },
legendAverageText: {
type: String,
required: false,
default: s__('Metrics|Avg'),
},
+ legendCurrentText: {
+ type: String,
+ required: false,
+ default: s__('Metrics|Current'),
+ },
legendMaxText: {
type: String,
required: false,
default: s__('Metrics|Max'),
},
+ legendMinText: {
+ type: String,
+ required: false,
+ default: s__('Metrics|Min'),
+ },
groupId: {
type: String,
required: false,
default: '',
},
+ timezone: {
+ type: String,
+ required: false,
+ default: timezones.LOCAL,
+ },
},
data() {
return {
@@ -154,23 +175,16 @@ export default {
const { yAxis, xAxis } = this.option;
const option = omit(this.option, ['series', 'yAxis', 'xAxis']);
+ const timeXAxis = {
+ ...getTimeAxisOptions({ timezone: this.timezone }),
+ ...xAxis,
+ };
+
const dataYAxis = {
...getYAxisOptions(this.graphData.yAxis),
...yAxis,
};
- const timeXAxis = {
- name: __('Time'),
- type: 'time',
- axisLabel: {
- formatter: date => dateFormat(date, dateFormats.timeOfDay),
- },
- axisPointer: {
- snap: true,
- },
- ...xAxis,
- };
-
return {
series: this.chartOptionSeries,
xAxis: timeXAxis,
@@ -271,12 +285,13 @@ export default {
*/
formatAnnotationsTooltipText(params) {
return {
- title: dateFormat(params.data?.tooltipData?.title, dateFormats.default),
+ title: formatDate(params.data?.tooltipData?.title, { timezone: this.timezone }),
content: params.data?.tooltipData?.content,
};
},
formatTooltipText(params) {
- this.tooltip.title = dateFormat(params.value, dateFormats.default);
+ this.tooltip.title = formatDate(params.value, { timezone: this.timezone });
+
this.tooltip.content = [];
params.seriesData.forEach(dataPoint => {
@@ -368,8 +383,11 @@ export default {
:thresholds="thresholds"
:width="width"
:height="height"
- :average-text="legendAverageText"
- :max-text="legendMaxText"
+ :legend-layout="legendLayout"
+ :legend-average-text="legendAverageText"
+ :legend-current-text="legendCurrentText"
+ :legend-max-text="legendMaxText"
+ :legend-min-text="legendMinText"
@created="onChartCreated"
@updated="onChartUpdated"
>
diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue
index 2018c706b11..f54319d283e 100644
--- a/app/assets/javascripts/monitoring/components/dashboard.vue
+++ b/app/assets/javascripts/monitoring/components/dashboard.vue
@@ -1,73 +1,45 @@
<script>
-import { debounce } from 'lodash';
import { mapActions, mapState, mapGetters } from 'vuex';
import VueDraggable from 'vuedraggable';
-import {
- GlIcon,
- GlButton,
- GlDeprecatedButton,
- GlDropdown,
- GlDropdownItem,
- GlDropdownHeader,
- GlDropdownDivider,
- GlModal,
- GlLoadingIcon,
- GlSearchBoxByType,
- GlModalDirective,
- GlTooltipDirective,
-} from '@gitlab/ui';
+import { GlIcon, GlButton, GlModalDirective, GlTooltipDirective } from '@gitlab/ui';
+import DashboardHeader from './dashboard_header.vue';
import DashboardPanel from './dashboard_panel.vue';
import { s__ } from '~/locale';
import createFlash from '~/flash';
import { ESC_KEY, ESC_KEY_IE11 } from '~/lib/utils/keys';
-import CustomMetricsFormFields from '~/custom_metrics/components/custom_metrics_form_fields.vue';
-import { mergeUrlParams, redirectTo, updateHistory } from '~/lib/utils/url_utility';
+import { mergeUrlParams, updateHistory } from '~/lib/utils/url_utility';
import invalidUrl from '~/lib/utils/invalid_url';
import Icon from '~/vue_shared/components/icon.vue';
-import DateTimePicker from '~/vue_shared/components/date_time_picker/date_time_picker.vue';
import GraphGroup from './graph_group.vue';
import EmptyState from './empty_state.vue';
import GroupEmptyState from './group_empty_state.vue';
-import DashboardsDropdown from './dashboards_dropdown.vue';
import VariablesSection from './variables_section.vue';
+import LinksSection from './links_section.vue';
import TrackEventDirective from '~/vue_shared/directives/track_event';
import {
- getAddMetricTrackingOptions,
- timeRangeToUrl,
timeRangeFromUrl,
panelToUrl,
expandedPanelPayloadFromUrl,
convertVariablesForURL,
} from '../utils';
import { metricStates } from '../constants';
-import { defaultTimeRange, timeRanges } from '~/vue_shared/constants';
+import { defaultTimeRange } from '~/vue_shared/constants';
export default {
components: {
VueDraggable,
+ DashboardHeader,
DashboardPanel,
Icon,
GlIcon,
GlButton,
- GlDeprecatedButton,
- GlDropdown,
- GlLoadingIcon,
- GlDropdownItem,
- GlDropdownHeader,
- GlDropdownDivider,
- GlSearchBoxByType,
- GlModal,
- CustomMetricsFormFields,
-
- DateTimePicker,
GraphGroup,
EmptyState,
GroupEmptyState,
- DashboardsDropdown,
-
VariablesSection,
+ LinksSection,
},
directives: {
GlModal: GlModalDirective,
@@ -111,27 +83,10 @@ export default {
type: String,
required: true,
},
- projectPath: {
- type: String,
- required: true,
- },
- logsPath: {
- type: String,
- required: false,
- default: invalidUrl,
- },
defaultBranch: {
type: String,
- required: true,
- },
- metricsEndpoint: {
- type: String,
- required: true,
- },
- deploymentsEndpoint: {
- type: String,
required: false,
- default: null,
+ default: '',
},
emptyGettingStartedSvgPath: {
type: String,
@@ -153,10 +108,6 @@ export default {
type: String,
required: true,
},
- currentEnvironmentName: {
- type: String,
- required: true,
- },
customMetricsAvailable: {
type: Boolean,
required: false,
@@ -172,21 +123,6 @@ export default {
required: false,
default: invalidUrl,
},
- dashboardEndpoint: {
- type: String,
- required: false,
- default: invalidUrl,
- },
- dashboardsEndpoint: {
- type: String,
- required: false,
- default: invalidUrl,
- },
- currentDashboard: {
- type: String,
- required: false,
- default: '',
- },
smallEmptyState: {
type: Boolean,
required: false,
@@ -210,11 +146,9 @@ export default {
},
data() {
return {
- formIsValid: null,
selectedTimeRange: timeRangeFromUrl() || defaultTimeRange,
- hasValidDates: true,
- timeRanges,
isRearrangingPanels: false,
+ originalDocumentTitle: document.title,
};
},
computed: {
@@ -222,36 +156,17 @@ export default {
'dashboard',
'emptyState',
'showEmptyState',
- 'useDashboardEndpoint',
- 'allDashboards',
- 'environmentsLoading',
'expandedPanel',
- 'promVariables',
- 'isUpdatingStarredValue',
- ]),
- ...mapGetters('monitoringDashboard', [
- 'selectedDashboard',
- 'getMetricStates',
- 'filteredEnvironments',
+ 'variables',
+ 'links',
+ 'currentDashboard',
]),
- showRearrangePanelsBtn() {
- return !this.showEmptyState && this.rearrangePanelsAvailable;
- },
- addingMetricsAvailable() {
- return (
- this.customMetricsAvailable &&
- !this.showEmptyState &&
- // Custom metrics only avaialble on system dashboards because
- // they are stored in the database. This can be improved. See:
- // https://gitlab.com/gitlab-org/gitlab/-/issues/28241
- this.selectedDashboard?.system_dashboard
- );
- },
- shouldShowEnvironmentsDropdownNoMatchedMsg() {
- return !this.environmentsLoading && this.filteredEnvironments.length === 0;
- },
+ ...mapGetters('monitoringDashboard', ['selectedDashboard', 'getMetricStates']),
shouldShowVariablesSection() {
- return Object.keys(this.promVariables).length > 0;
+ return Object.keys(this.variables).length > 0;
+ },
+ shouldShowLinksSection() {
+ return Object.keys(this.links).length > 0;
},
},
watch: {
@@ -273,24 +188,17 @@ export default {
handler({ group, panel }) {
const dashboardPath = this.currentDashboard || this.selectedDashboard?.path;
updateHistory({
- url: panelToUrl(dashboardPath, convertVariablesForURL(this.promVariables), group, panel),
+ url: panelToUrl(dashboardPath, convertVariablesForURL(this.variables), group, panel),
title: document.title,
});
},
deep: true,
},
+ selectedDashboard(dashboard) {
+ this.prependToDocumentTitle(dashboard?.display_name);
+ },
},
created() {
- this.setInitialState({
- metricsEndpoint: this.metricsEndpoint,
- deploymentsEndpoint: this.deploymentsEndpoint,
- dashboardEndpoint: this.dashboardEndpoint,
- dashboardsEndpoint: this.dashboardsEndpoint,
- currentDashboard: this.currentDashboard,
- projectPath: this.projectPath,
- logsPath: this.logsPath,
- currentEnvironmentName: this.currentEnvironmentName,
- });
window.addEventListener('keyup', this.onKeyup);
},
destroyed() {
@@ -308,14 +216,10 @@ export default {
...mapActions('monitoringDashboard', [
'setTimeRange',
'fetchData',
- 'fetchDashboardData',
'setGettingStartedEmptyState',
- 'setInitialState',
'setPanelGroupMetrics',
- 'filterEnvironments',
'setExpandedPanel',
'clearExpandedPanel',
- 'toggleStarredValue',
]),
updatePanels(key, panels) {
this.setPanelGroupMetrics({
@@ -329,37 +233,9 @@ export default {
key,
});
},
-
- onDateTimePickerInput(timeRange) {
- redirectTo(timeRangeToUrl(timeRange));
- },
- onDateTimePickerInvalid() {
- createFlash(
- s__(
- 'Metrics|Link contains an invalid time window, please verify the link to see the requested time range.',
- ),
- );
- // As a fallback, switch to default time range instead
- this.selectedTimeRange = defaultTimeRange;
- },
generatePanelUrl(groupKey, panel) {
const dashboardPath = this.currentDashboard || this.selectedDashboard?.path;
- return panelToUrl(dashboardPath, convertVariablesForURL(this.promVariables), groupKey, panel);
- },
- hideAddMetricModal() {
- this.$refs.addMetricModal.hide();
- },
- toggleRearrangingPanels() {
- this.isRearrangingPanels = !this.isRearrangingPanels;
- },
- setFormValidity(isValid) {
- this.formIsValid = isValid;
- },
- debouncedEnvironmentsSearch: debounce(function environmentsSearchOnInput(searchTerm) {
- this.filterEnvironments(searchTerm);
- }, 500),
- submitCustomMetricsForm() {
- this.$refs.customMetricsForm.submit();
+ return panelToUrl(dashboardPath, convertVariablesForURL(this.variables), groupKey, panel);
},
/**
* Return a single empty state for a group.
@@ -387,25 +263,20 @@ export default {
// Collapse group if no data is available
return !this.getMetricStates(groupKey).includes(metricStates.OK);
},
- getAddMetricTrackingOptions,
-
- selectDashboard(dashboard) {
- const params = {
- dashboard: dashboard.path,
- };
- redirectTo(mergeUrlParams(params, window.location.href));
- },
-
- refreshDashboard() {
- this.fetchDashboardData();
+ prependToDocumentTitle(text) {
+ if (text) {
+ document.title = `${text} · ${this.originalDocumentTitle}`;
+ }
},
-
onTimeRangeZoom({ start, end }) {
updateHistory({
url: mergeUrlParams({ start, end }, window.location.href),
title: document.title,
});
this.selectedTimeRange = { start, end };
+ // keep the current dashboard time range
+ // in sync with the Vuex store
+ this.setTimeRange(this.selectedTimeRange);
},
onExpandPanel(group, panel) {
this.setExpandedPanel({ group, panel });
@@ -419,213 +290,45 @@ export default {
this.clearExpandedPanel();
}
},
- },
- addMetric: {
- title: s__('Metrics|Add metric'),
- modalId: 'add-metric',
+ onSetRearrangingPanels(isRearrangingPanels) {
+ this.isRearrangingPanels = isRearrangingPanels;
+ },
+ onDateTimePickerInvalid() {
+ createFlash(
+ s__(
+ 'Metrics|Link contains an invalid time window, please verify the link to see the requested time range.',
+ ),
+ );
+ // As a fallback, switch to default time range instead
+ this.selectedTimeRange = defaultTimeRange;
+ },
},
i18n: {
goBackLabel: s__('Metrics|Go back (Esc)'),
- starDashboard: s__('Metrics|Star dashboard'),
- unstarDashboard: s__('Metrics|Unstar dashboard'),
},
};
</script>
<template>
<div class="prometheus-graphs" data-qa-selector="prometheus_graphs">
- <div
+ <dashboard-header
v-if="showHeader"
ref="prometheusGraphsHeader"
class="prometheus-graphs-header d-sm-flex flex-sm-wrap pt-2 pr-1 pb-0 pl-2 border-bottom bg-gray-light"
- >
- <div class="mb-2 pr-2 d-flex d-sm-block">
- <dashboards-dropdown
- id="monitor-dashboards-dropdown"
- data-qa-selector="dashboards_filter_dropdown"
- class="flex-grow-1"
- toggle-class="dropdown-menu-toggle"
- :default-branch="defaultBranch"
- @selectDashboard="selectDashboard($event)"
- />
- </div>
-
- <div class="mb-2 pr-2 d-flex d-sm-block">
- <gl-dropdown
- id="monitor-environments-dropdown"
- ref="monitorEnvironmentsDropdown"
- class="flex-grow-1"
- data-qa-selector="environments_dropdown"
- toggle-class="dropdown-menu-toggle"
- menu-class="monitor-environment-dropdown-menu"
- :text="currentEnvironmentName"
- >
- <div class="d-flex flex-column overflow-hidden">
- <gl-dropdown-header class="monitor-environment-dropdown-header text-center">
- {{ __('Environment') }}
- </gl-dropdown-header>
- <gl-dropdown-divider />
- <gl-search-box-by-type
- ref="monitorEnvironmentsDropdownSearch"
- class="m-2"
- @input="debouncedEnvironmentsSearch"
- />
- <gl-loading-icon
- v-if="environmentsLoading"
- ref="monitorEnvironmentsDropdownLoading"
- :inline="true"
- />
- <div v-else class="flex-fill overflow-auto">
- <gl-dropdown-item
- v-for="environment in filteredEnvironments"
- :key="environment.id"
- :active="environment.name === currentEnvironmentName"
- active-class="is-active"
- :href="environment.metrics_path"
- >{{ environment.name }}</gl-dropdown-item
- >
- </div>
- <div
- v-show="shouldShowEnvironmentsDropdownNoMatchedMsg"
- ref="monitorEnvironmentsDropdownMsg"
- class="text-secondary no-matches-message"
- >
- {{ __('No matching results') }}
- </div>
- </div>
- </gl-dropdown>
- </div>
-
- <div class="mb-2 pr-2 d-flex d-sm-block">
- <date-time-picker
- ref="dateTimePicker"
- class="flex-grow-1 show-last-dropdown"
- data-qa-selector="range_picker_dropdown"
- :value="selectedTimeRange"
- :options="timeRanges"
- @input="onDateTimePickerInput"
- @invalid="onDateTimePickerInvalid"
- />
- </div>
-
- <div class="mb-2 pr-2 d-flex d-sm-block">
- <gl-deprecated-button
- ref="refreshDashboardBtn"
- v-gl-tooltip
- class="flex-grow-1"
- variant="default"
- :title="s__('Metrics|Refresh dashboard')"
- @click="refreshDashboard"
- >
- <icon name="retry" />
- </gl-deprecated-button>
- </div>
-
- <div class="flex-grow-1"></div>
-
- <div class="d-sm-flex">
- <div v-if="selectedDashboard" class="mb-2 mr-2 d-flex">
- <!--
- wrapper for tooltip as button can be `disabled`
- https://bootstrap-vue.org/docs/components/tooltip#disabled-elements
- -->
- <div
- v-gl-tooltip
- class="flex-grow-1"
- :title="
- selectedDashboard.starred
- ? $options.i18n.unstarDashboard
- : $options.i18n.starDashboard
- "
- >
- <gl-deprecated-button
- ref="toggleStarBtn"
- class="w-100"
- :disabled="isUpdatingStarredValue"
- variant="default"
- @click="toggleStarredValue()"
- >
- <gl-icon :name="selectedDashboard.starred ? 'star' : 'star-o'" />
- </gl-deprecated-button>
- </div>
- </div>
-
- <div v-if="showRearrangePanelsBtn" class="mb-2 mr-2 d-flex">
- <gl-deprecated-button
- :pressed="isRearrangingPanels"
- variant="default"
- class="flex-grow-1 js-rearrange-button"
- @click="toggleRearrangingPanels"
- >
- {{ __('Arrange charts') }}
- </gl-deprecated-button>
- </div>
- <div v-if="addingMetricsAvailable" class="mb-2 mr-2 d-flex d-sm-block">
- <gl-deprecated-button
- ref="addMetricBtn"
- v-gl-modal="$options.addMetric.modalId"
- variant="outline-success"
- data-qa-selector="add_metric_button"
- class="flex-grow-1"
- >
- {{ $options.addMetric.title }}
- </gl-deprecated-button>
- <gl-modal
- ref="addMetricModal"
- :modal-id="$options.addMetric.modalId"
- :title="$options.addMetric.title"
- >
- <form ref="customMetricsForm" :action="customMetricsPath" method="post">
- <custom-metrics-form-fields
- :validate-query-path="validateQueryPath"
- form-operation="post"
- @formValidation="setFormValidity"
- />
- </form>
- <div slot="modal-footer">
- <gl-deprecated-button @click="hideAddMetricModal">
- {{ __('Cancel') }}
- </gl-deprecated-button>
- <gl-deprecated-button
- ref="submitCustomMetricsFormBtn"
- v-track-event="getAddMetricTrackingOptions()"
- :disabled="!formIsValid"
- variant="success"
- @click="submitCustomMetricsForm"
- >
- {{ __('Save changes') }}
- </gl-deprecated-button>
- </div>
- </gl-modal>
- </div>
-
- <div
- v-if="selectedDashboard && selectedDashboard.can_edit"
- class="mb-2 mr-2 d-flex d-sm-block"
- >
- <gl-deprecated-button
- class="flex-grow-1 js-edit-link"
- :href="selectedDashboard.project_blob_path"
- data-qa-selector="edit_dashboard_button"
- >
- {{ __('Edit dashboard') }}
- </gl-deprecated-button>
- </div>
-
- <div v-if="externalDashboardUrl.length" class="mb-2 mr-2 d-flex d-sm-block">
- <gl-deprecated-button
- class="flex-grow-1 js-external-dashboard-link"
- variant="primary"
- :href="externalDashboardUrl"
- target="_blank"
- rel="noopener noreferrer"
- >
- {{ __('View full dashboard') }} <icon name="external-link" />
- </gl-deprecated-button>
- </div>
- </div>
- </div>
+ :default-branch="defaultBranch"
+ :rearrange-panels-available="rearrangePanelsAvailable"
+ :custom-metrics-available="customMetricsAvailable"
+ :custom-metrics-path="customMetricsPath"
+ :validate-query-path="validateQueryPath"
+ :external-dashboard-url="externalDashboardUrl"
+ :has-metrics="hasMetrics"
+ :is-rearranging-panels="isRearrangingPanels"
+ :selected-time-range="selectedTimeRange"
+ @dateTimePickerInvalid="onDateTimePickerInvalid"
+ @setRearrangingPanels="onSetRearrangingPanels"
+ />
<variables-section v-if="shouldShowVariablesSection && !showEmptyState" />
+ <links-section v-if="shouldShowLinksSection && !showEmptyState" />
<div v-if="!showEmptyState">
<dashboard-panel
v-show="expandedPanel.panel"
diff --git a/app/assets/javascripts/monitoring/components/dashboard_header.vue b/app/assets/javascripts/monitoring/components/dashboard_header.vue
new file mode 100644
index 00000000000..16a21ae0d3c
--- /dev/null
+++ b/app/assets/javascripts/monitoring/components/dashboard_header.vue
@@ -0,0 +1,369 @@
+<script>
+import { debounce } from 'lodash';
+import { mapActions, mapState, mapGetters } from 'vuex';
+import {
+ GlIcon,
+ GlDeprecatedButton,
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownHeader,
+ GlDropdownDivider,
+ GlModal,
+ GlLoadingIcon,
+ GlSearchBoxByType,
+ GlModalDirective,
+ GlTooltipDirective,
+} from '@gitlab/ui';
+import { s__ } from '~/locale';
+import CustomMetricsFormFields from '~/custom_metrics/components/custom_metrics_form_fields.vue';
+import { mergeUrlParams, redirectTo } from '~/lib/utils/url_utility';
+import invalidUrl from '~/lib/utils/invalid_url';
+import Icon from '~/vue_shared/components/icon.vue';
+import DateTimePicker from '~/vue_shared/components/date_time_picker/date_time_picker.vue';
+
+import DashboardsDropdown from './dashboards_dropdown.vue';
+
+import TrackEventDirective from '~/vue_shared/directives/track_event';
+import { getAddMetricTrackingOptions, timeRangeToUrl } from '../utils';
+import { timeRanges } from '~/vue_shared/constants';
+import { timezones } from '../format_date';
+
+export default {
+ components: {
+ Icon,
+ GlIcon,
+ GlDeprecatedButton,
+ GlDropdown,
+ GlLoadingIcon,
+ GlDropdownItem,
+ GlDropdownHeader,
+ GlDropdownDivider,
+ GlSearchBoxByType,
+ GlModal,
+ CustomMetricsFormFields,
+
+ DateTimePicker,
+ DashboardsDropdown,
+ },
+ directives: {
+ GlModal: GlModalDirective,
+ GlTooltip: GlTooltipDirective,
+ TrackEvent: TrackEventDirective,
+ },
+ props: {
+ defaultBranch: {
+ type: String,
+ required: true,
+ },
+ rearrangePanelsAvailable: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ customMetricsAvailable: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ customMetricsPath: {
+ type: String,
+ required: false,
+ default: invalidUrl,
+ },
+ validateQueryPath: {
+ type: String,
+ required: false,
+ default: invalidUrl,
+ },
+ externalDashboardUrl: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ hasMetrics: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
+ isRearrangingPanels: {
+ type: Boolean,
+ required: true,
+ },
+ selectedTimeRange: {
+ type: Object,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ formIsValid: null,
+ };
+ },
+ computed: {
+ ...mapState('monitoringDashboard', [
+ 'environmentsLoading',
+ 'currentEnvironmentName',
+ 'isUpdatingStarredValue',
+ 'showEmptyState',
+ 'dashboardTimezone',
+ ]),
+ ...mapGetters('monitoringDashboard', ['selectedDashboard', 'filteredEnvironments']),
+ shouldShowEnvironmentsDropdownNoMatchedMsg() {
+ return !this.environmentsLoading && this.filteredEnvironments.length === 0;
+ },
+ addingMetricsAvailable() {
+ return (
+ this.customMetricsAvailable &&
+ !this.showEmptyState &&
+ // Custom metrics only avaialble on system dashboards because
+ // they are stored in the database. This can be improved. See:
+ // https://gitlab.com/gitlab-org/gitlab/-/issues/28241
+ this.selectedDashboard?.system_dashboard
+ );
+ },
+ showRearrangePanelsBtn() {
+ return !this.showEmptyState && this.rearrangePanelsAvailable;
+ },
+ displayUtc() {
+ return this.dashboardTimezone === timezones.UTC;
+ },
+ },
+ methods: {
+ ...mapActions('monitoringDashboard', [
+ 'filterEnvironments',
+ 'fetchDashboardData',
+ 'toggleStarredValue',
+ ]),
+ selectDashboard(dashboard) {
+ const params = {
+ dashboard: dashboard.path,
+ };
+ redirectTo(mergeUrlParams(params, window.location.href));
+ },
+ debouncedEnvironmentsSearch: debounce(function environmentsSearchOnInput(searchTerm) {
+ this.filterEnvironments(searchTerm);
+ }, 500),
+ onDateTimePickerInput(timeRange) {
+ redirectTo(timeRangeToUrl(timeRange));
+ },
+ onDateTimePickerInvalid() {
+ this.$emit('dateTimePickerInvalid');
+ },
+ refreshDashboard() {
+ this.fetchDashboardData();
+ },
+
+ toggleRearrangingPanels() {
+ this.$emit('setRearrangingPanels', !this.isRearrangingPanels);
+ },
+ setFormValidity(isValid) {
+ this.formIsValid = isValid;
+ },
+ hideAddMetricModal() {
+ this.$refs.addMetricModal.hide();
+ },
+ getAddMetricTrackingOptions,
+ submitCustomMetricsForm() {
+ this.$refs.customMetricsForm.submit();
+ },
+ },
+ addMetric: {
+ title: s__('Metrics|Add metric'),
+ modalId: 'add-metric',
+ },
+ i18n: {
+ starDashboard: s__('Metrics|Star dashboard'),
+ unstarDashboard: s__('Metrics|Unstar dashboard'),
+ },
+ timeRanges,
+};
+</script>
+
+<template>
+ <div ref="prometheusGraphsHeader">
+ <div class="mb-2 pr-2 d-flex d-sm-block">
+ <dashboards-dropdown
+ id="monitor-dashboards-dropdown"
+ data-qa-selector="dashboards_filter_dropdown"
+ class="flex-grow-1"
+ toggle-class="dropdown-menu-toggle"
+ :default-branch="defaultBranch"
+ @selectDashboard="selectDashboard"
+ />
+ </div>
+
+ <div class="mb-2 pr-2 d-flex d-sm-block">
+ <gl-dropdown
+ id="monitor-environments-dropdown"
+ ref="monitorEnvironmentsDropdown"
+ class="flex-grow-1"
+ data-qa-selector="environments_dropdown"
+ toggle-class="dropdown-menu-toggle"
+ menu-class="monitor-environment-dropdown-menu"
+ :text="currentEnvironmentName"
+ >
+ <div class="d-flex flex-column overflow-hidden">
+ <gl-dropdown-header class="monitor-environment-dropdown-header text-center">
+ {{ __('Environment') }}
+ </gl-dropdown-header>
+ <gl-dropdown-divider />
+ <gl-search-box-by-type
+ ref="monitorEnvironmentsDropdownSearch"
+ class="m-2"
+ @input="debouncedEnvironmentsSearch"
+ />
+ <gl-loading-icon
+ v-if="environmentsLoading"
+ ref="monitorEnvironmentsDropdownLoading"
+ :inline="true"
+ />
+ <div v-else class="flex-fill overflow-auto">
+ <gl-dropdown-item
+ v-for="environment in filteredEnvironments"
+ :key="environment.id"
+ :active="environment.name === currentEnvironmentName"
+ active-class="is-active"
+ :href="environment.metrics_path"
+ >{{ environment.name }}</gl-dropdown-item
+ >
+ </div>
+ <div
+ v-show="shouldShowEnvironmentsDropdownNoMatchedMsg"
+ ref="monitorEnvironmentsDropdownMsg"
+ class="text-secondary no-matches-message"
+ >
+ {{ __('No matching results') }}
+ </div>
+ </div>
+ </gl-dropdown>
+ </div>
+
+ <div class="mb-2 pr-2 d-flex d-sm-block">
+ <date-time-picker
+ ref="dateTimePicker"
+ class="flex-grow-1 show-last-dropdown"
+ data-qa-selector="range_picker_dropdown"
+ :value="selectedTimeRange"
+ :options="$options.timeRanges"
+ :utc="displayUtc"
+ @input="onDateTimePickerInput"
+ @invalid="onDateTimePickerInvalid"
+ />
+ </div>
+
+ <div class="mb-2 pr-2 d-flex d-sm-block">
+ <gl-deprecated-button
+ ref="refreshDashboardBtn"
+ v-gl-tooltip
+ class="flex-grow-1"
+ variant="default"
+ :title="s__('Metrics|Refresh dashboard')"
+ @click="refreshDashboard"
+ >
+ <icon name="retry" />
+ </gl-deprecated-button>
+ </div>
+
+ <div class="flex-grow-1"></div>
+
+ <div class="d-sm-flex">
+ <div v-if="selectedDashboard" class="mb-2 mr-2 d-flex">
+ <!--
+ wrapper for tooltip as button can be `disabled`
+ https://bootstrap-vue.org/docs/components/tooltip#disabled-elements
+ -->
+ <div
+ v-gl-tooltip
+ class="flex-grow-1"
+ :title="
+ selectedDashboard.starred ? $options.i18n.unstarDashboard : $options.i18n.starDashboard
+ "
+ >
+ <gl-deprecated-button
+ ref="toggleStarBtn"
+ class="w-100"
+ :disabled="isUpdatingStarredValue"
+ variant="default"
+ @click="toggleStarredValue()"
+ >
+ <gl-icon :name="selectedDashboard.starred ? 'star' : 'star-o'" />
+ </gl-deprecated-button>
+ </div>
+ </div>
+
+ <div v-if="showRearrangePanelsBtn" class="mb-2 mr-2 d-flex">
+ <gl-deprecated-button
+ :pressed="isRearrangingPanels"
+ variant="default"
+ class="flex-grow-1 js-rearrange-button"
+ @click="toggleRearrangingPanels"
+ >
+ {{ __('Arrange charts') }}
+ </gl-deprecated-button>
+ </div>
+ <div v-if="addingMetricsAvailable" class="mb-2 mr-2 d-flex d-sm-block">
+ <gl-deprecated-button
+ ref="addMetricBtn"
+ v-gl-modal="$options.addMetric.modalId"
+ variant="outline-success"
+ data-qa-selector="add_metric_button"
+ class="flex-grow-1"
+ >
+ {{ $options.addMetric.title }}
+ </gl-deprecated-button>
+ <gl-modal
+ ref="addMetricModal"
+ :modal-id="$options.addMetric.modalId"
+ :title="$options.addMetric.title"
+ >
+ <form ref="customMetricsForm" :action="customMetricsPath" method="post">
+ <custom-metrics-form-fields
+ :validate-query-path="validateQueryPath"
+ form-operation="post"
+ @formValidation="setFormValidity"
+ />
+ </form>
+ <div slot="modal-footer">
+ <gl-deprecated-button @click="hideAddMetricModal">
+ {{ __('Cancel') }}
+ </gl-deprecated-button>
+ <gl-deprecated-button
+ ref="submitCustomMetricsFormBtn"
+ v-track-event="getAddMetricTrackingOptions()"
+ :disabled="!formIsValid"
+ variant="success"
+ @click="submitCustomMetricsForm"
+ >
+ {{ __('Save changes') }}
+ </gl-deprecated-button>
+ </div>
+ </gl-modal>
+ </div>
+
+ <div
+ v-if="selectedDashboard && selectedDashboard.can_edit"
+ class="mb-2 mr-2 d-flex d-sm-block"
+ >
+ <gl-deprecated-button
+ class="flex-grow-1 js-edit-link"
+ :href="selectedDashboard.project_blob_path"
+ data-qa-selector="edit_dashboard_button"
+ >
+ {{ __('Edit dashboard') }}
+ </gl-deprecated-button>
+ </div>
+
+ <div v-if="externalDashboardUrl.length" class="mb-2 mr-2 d-flex d-sm-block">
+ <gl-deprecated-button
+ class="flex-grow-1 js-external-dashboard-link"
+ variant="primary"
+ :href="externalDashboardUrl"
+ target="_blank"
+ rel="noopener noreferrer"
+ >
+ {{ __('View full dashboard') }} <icon name="external-link" />
+ </gl-deprecated-button>
+ </div>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/monitoring/components/dashboard_panel.vue b/app/assets/javascripts/monitoring/components/dashboard_panel.vue
index 48825fda5c8..9545a211bbd 100644
--- a/app/assets/javascripts/monitoring/components/dashboard_panel.vue
+++ b/app/assets/javascripts/monitoring/components/dashboard_panel.vue
@@ -6,8 +6,9 @@ import {
GlResizeObserverDirective,
GlIcon,
GlLoadingIcon,
- GlDropdown,
- GlDropdownItem,
+ GlNewDropdown as GlDropdown,
+ GlNewDropdownItem as GlDropdownItem,
+ GlNewDropdownDivider as GlDropdownDivider,
GlModal,
GlModalDirective,
GlTooltip,
@@ -28,6 +29,7 @@ import MonitorStackedColumnChart from './charts/stacked_column.vue';
import TrackEventDirective from '~/vue_shared/directives/track_event';
import AlertWidget from './alert_widget.vue';
import { timeRangeToUrl, downloadCSVOptions, generateLinkToChartOptions } from '../utils';
+import { isSafeURL } from '~/lib/utils/url_utility';
const events = {
timeRangeZoom: 'timerangezoom',
@@ -43,6 +45,7 @@ export default {
GlTooltip,
GlDropdown,
GlDropdownItem,
+ GlDropdownDivider,
GlModal,
},
directives: {
@@ -115,9 +118,15 @@ export default {
timeRange(state) {
return state[this.namespace].timeRange;
},
+ dashboardTimezone(state) {
+ return state[this.namespace].dashboardTimezone;
+ },
metricsSavedToDb(state, getters) {
return getters[`${this.namespace}/metricsSavedToDb`];
},
+ selectedDashboard(state, getters) {
+ return getters[`${this.namespace}/selectedDashboard`];
+ },
}),
title() {
return this.graphData?.title || '';
@@ -266,6 +275,9 @@ export default {
this.$delete(this.allAlerts, alertPath);
}
},
+ safeUrl(url) {
+ return isSafeURL(url) ? url : '#';
+ },
},
panelTypes,
};
@@ -276,7 +288,8 @@ export default {
<slot name="topLeft"></slot>
<h5
ref="graphTitle"
- class="prometheus-graph-title gl-font-lg font-weight-bold text-truncate append-right-8"
+ class="prometheus-graph-title gl-font-lg font-weight-bold text-truncate gl-mr-3"
+ tabindex="0"
>
{{ title }}
</h5>
@@ -304,14 +317,13 @@ export default {
<div class="d-flex align-items-center">
<gl-dropdown
v-gl-tooltip
- toggle-class="btn btn-transparent border-0"
+ toggle-class="shadow-none border-0"
data-qa-selector="prometheus_widgets_dropdown"
right
- no-caret
:title="__('More actions')"
>
<template slot="button-content">
- <gl-icon name="ellipsis_v" class="text-secondary" />
+ <gl-icon name="ellipsis_v" class="dropdown-icon text-secondary" />
</template>
<gl-dropdown-item
v-if="expandBtnAvailable"
@@ -362,6 +374,23 @@ export default {
>
{{ __('Alerts') }}
</gl-dropdown-item>
+
+ <template v-if="graphData.links.length">
+ <gl-dropdown-divider />
+ <gl-dropdown-item
+ v-for="(link, index) in graphData.links"
+ :key="index"
+ :href="safeUrl(link.url)"
+ class="text-break"
+ >{{ link.title }}</gl-dropdown-item
+ >
+ </template>
+ <template v-if="selectedDashboard && selectedDashboard.can_edit">
+ <gl-dropdown-divider />
+ <gl-dropdown-item ref="manageLinksItem" :href="selectedDashboard.project_blob_path">{{
+ s__('Metrics|Manage chart links')
+ }}</gl-dropdown-item>
+ </template>
</gl-dropdown>
</div>
</div>
@@ -372,6 +401,7 @@ export default {
:is="basicChartComponent"
v-else-if="basicChartComponent"
:graph-data="graphData"
+ :timezone="dashboardTimezone"
v-bind="$attrs"
v-on="$listeners"
/>
@@ -385,6 +415,7 @@ export default {
:project-path="projectPath"
:thresholds="getGraphAlertValues(graphData.metrics)"
:group-id="groupId"
+ :timezone="dashboardTimezone"
v-bind="$attrs"
v-on="$listeners"
@datazoom="onDatazoom"
diff --git a/app/assets/javascripts/monitoring/components/graph_group.vue b/app/assets/javascripts/monitoring/components/graph_group.vue
index 5a7981b6534..08fcfa3bc56 100644
--- a/app/assets/javascripts/monitoring/components/graph_group.vue
+++ b/app/assets/javascripts/monitoring/components/graph_group.vue
@@ -52,10 +52,17 @@ export default {
</script>
<template>
- <div v-if="showPanels" ref="graph-group" class="card prometheus-panel">
+ <div v-if="showPanels" ref="graph-group" class="card prometheus-panel" tabindex="0">
<div class="card-header d-flex align-items-center">
<h4 class="flex-grow-1">{{ name }}</h4>
- <a role="button" class="js-graph-group-toggle" @click="collapse">
+ <a
+ data-testid="group-toggle-button"
+ role="button"
+ class="js-graph-group-toggle gl-text-gray-900"
+ tabindex="0"
+ @click="collapse"
+ @keyup.enter="collapse"
+ >
<icon :size="16" :aria-label="__('Toggle collapse')" :name="caretIcon" />
</a>
</div>
diff --git a/app/assets/javascripts/monitoring/components/links_section.vue b/app/assets/javascripts/monitoring/components/links_section.vue
new file mode 100644
index 00000000000..98b07d17694
--- /dev/null
+++ b/app/assets/javascripts/monitoring/components/links_section.vue
@@ -0,0 +1,32 @@
+<script>
+import { mapGetters } from 'vuex';
+import { GlIcon, GlLink } from '@gitlab/ui';
+
+export default {
+ components: {
+ GlIcon,
+ GlLink,
+ },
+ computed: {
+ ...mapGetters('monitoringDashboard', { links: 'linksWithMetadata' }),
+ },
+};
+</script>
+<template>
+ <div
+ ref="linksSection"
+ class="gl-display-sm-flex gl-flex-sm-wrap gl-mt-5 gl-p-3 gl-bg-gray-10 border gl-rounded-base links-section"
+ >
+ <div
+ v-for="(link, key) in links"
+ :key="key"
+ class="gl-mb-1 gl-mr-5 gl-display-flex gl-display-sm-block gl-hover-text-blue-600-children gl-word-break-all"
+ >
+ <gl-link :href="link.url" class="gl-text-gray-900 gl-text-decoration-none!"
+ ><gl-icon name="link" class="gl-text-gray-700 gl-vertical-align-text-bottom gl-mr-2" />{{
+ link.title
+ }}
+ </gl-link>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/monitoring/components/variables_section.vue b/app/assets/javascripts/monitoring/components/variables_section.vue
index e054c9d8e26..3d1d111d5b3 100644
--- a/app/assets/javascripts/monitoring/components/variables_section.vue
+++ b/app/assets/javascripts/monitoring/components/variables_section.vue
@@ -2,7 +2,7 @@
import { mapState, mapActions } from 'vuex';
import CustomVariable from './variables/custom_variable.vue';
import TextVariable from './variables/text_variable.vue';
-import { setPromCustomVariablesFromUrl } from '../utils';
+import { setCustomVariablesFromUrl } from '../utils';
export default {
components: {
@@ -10,23 +10,21 @@ export default {
TextVariable,
},
computed: {
- ...mapState('monitoringDashboard', ['promVariables']),
+ ...mapState('monitoringDashboard', ['variables']),
},
methods: {
- ...mapActions('monitoringDashboard', ['fetchDashboardData', 'updateVariableValues']),
+ ...mapActions('monitoringDashboard', ['updateVariablesAndFetchData']),
refreshDashboard(variable, value) {
- if (this.promVariables[variable].value !== value) {
+ if (this.variables[variable].value !== value) {
const changedVariable = { key: variable, value };
// update the Vuex store
- this.updateVariableValues(changedVariable);
+ this.updateVariablesAndFetchData(changedVariable);
// the below calls can ideally be moved out of the
// component and into the actions and let the
// mutation respond directly.
// This can be further investigate in
// https://gitlab.com/gitlab-org/gitlab/-/issues/217713
- setPromCustomVariablesFromUrl(this.promVariables);
- // fetch data
- this.fetchDashboardData();
+ setCustomVariablesFromUrl(this.variables);
}
},
variableComponent(type) {
@@ -41,7 +39,7 @@ export default {
</script>
<template>
<div ref="variablesSection" class="d-sm-flex flex-sm-wrap pt-2 pr-1 pb-0 pl-2 variables-section">
- <div v-for="(variable, key) in promVariables" :key="key" class="mb-1 pr-2 d-flex d-sm-block">
+ <div v-for="(variable, key) in variables" :key="key" class="mb-1 pr-2 d-flex d-sm-block">
<component
:is="variableComponent(variable.type)"
class="mb-0 flex-grow-1"
diff --git a/app/assets/javascripts/monitoring/constants.js b/app/assets/javascripts/monitoring/constants.js
index 0c2eafeed54..50330046c99 100644
--- a/app/assets/javascripts/monitoring/constants.js
+++ b/app/assets/javascripts/monitoring/constants.js
@@ -127,9 +127,25 @@ export const lineWidths = {
default: 2,
};
-export const dateFormats = {
- timeOfDay: 'h:MM TT',
- default: 'dd mmm yyyy, h:MMTT',
+/**
+ * User-defined links can be passed in dashboard yml file.
+ * These are the supported type of links.
+ */
+export const linkTypes = {
+ GRAFANA: 'grafana',
+};
+
+/**
+ * These are the supported values for the GitLab-UI
+ * chart legend layout.
+ *
+ * Currently defined in
+ * https://gitlab.com/gitlab-org/gitlab-ui/-/blob/master/src/utils/charts/constants.js
+ *
+ */
+export const legendLayoutTypes = {
+ inline: 'inline',
+ table: 'table',
};
/**
@@ -140,7 +156,6 @@ export const dateFormats = {
* Currently used in `receiveMetricsDashboardSuccess` action.
*/
export const endpointKeys = [
- 'metricsEndpoint',
'deploymentsEndpoint',
'dashboardEndpoint',
'dashboardsEndpoint',
diff --git a/app/assets/javascripts/monitoring/format_date.js b/app/assets/javascripts/monitoring/format_date.js
new file mode 100644
index 00000000000..a50d441a09e
--- /dev/null
+++ b/app/assets/javascripts/monitoring/format_date.js
@@ -0,0 +1,39 @@
+import dateFormat from 'dateformat';
+
+export const timezones = {
+ /**
+ * Renders a date with a local timezone
+ */
+ LOCAL: 'LOCAL',
+
+ /**
+ * Renders at date with UTC
+ */
+ UTC: 'UTC',
+};
+
+export const formats = {
+ shortTime: 'h:MM TT',
+ default: 'dd mmm yyyy, h:MMTT (Z)',
+};
+
+/**
+ * Formats a date for a metric dashboard or chart.
+ *
+ * Convenience wrapper of dateFormat with default formats
+ * and settings.
+ *
+ * dateFormat has some limitations and we could use `toLocaleString` instead
+ * See: https://gitlab.com/gitlab-org/gitlab/-/issues/219246
+ *
+ * @param {Date|String|Number} date
+ * @param {Object} options - Formatting options
+ * @param {string} options.format - Format or mask from `formats`.
+ * @param {string} options.timezone - Timezone abbreviation.
+ * Accepts "LOCAL" for the client local timezone.
+ */
+export const formatDate = (date, options = {}) => {
+ const { format = formats.default, timezone = timezones.LOCAL } = options;
+ const useUTC = timezone === timezones.UTC;
+ return dateFormat(date, format, useUTC);
+};
diff --git a/app/assets/javascripts/monitoring/monitoring_app.js b/app/assets/javascripts/monitoring/monitoring_app.js
new file mode 100644
index 00000000000..08543fa6eb3
--- /dev/null
+++ b/app/assets/javascripts/monitoring/monitoring_app.js
@@ -0,0 +1,59 @@
+import Vue from 'vue';
+import { GlToast } from '@gitlab/ui';
+import { parseBoolean } from '~/lib/utils/common_utils';
+import { getParameterValues } from '~/lib/utils/url_utility';
+import { createStore } from './stores';
+import createRouter from './router';
+
+Vue.use(GlToast);
+
+export default (props = {}) => {
+ const el = document.getElementById('prometheus-graphs');
+
+ if (el && el.dataset) {
+ const [currentDashboard] = getParameterValues('dashboard');
+
+ const {
+ deploymentsEndpoint,
+ dashboardEndpoint,
+ dashboardsEndpoint,
+ projectPath,
+ logsPath,
+ currentEnvironmentName,
+ dashboardTimezone,
+ metricsDashboardBasePath,
+ ...dataProps
+ } = el.dataset;
+
+ const store = createStore({
+ currentDashboard,
+ deploymentsEndpoint,
+ dashboardEndpoint,
+ dashboardsEndpoint,
+ dashboardTimezone,
+ projectPath,
+ logsPath,
+ currentEnvironmentName,
+ });
+
+ // HTML attributes are always strings, parse other types.
+ dataProps.hasMetrics = parseBoolean(dataProps.hasMetrics);
+ dataProps.customMetricsAvailable = parseBoolean(dataProps.customMetricsAvailable);
+ dataProps.prometheusAlertsAvailable = parseBoolean(dataProps.prometheusAlertsAvailable);
+
+ const router = createRouter(metricsDashboardBasePath);
+
+ // eslint-disable-next-line no-new
+ new Vue({
+ el,
+ store,
+ router,
+ data() {
+ return {
+ dashboardProps: { ...dataProps, ...props },
+ };
+ },
+ template: `<router-view :dashboardProps="dashboardProps"/>`,
+ });
+ }
+};
diff --git a/app/assets/javascripts/monitoring/monitoring_bundle.js b/app/assets/javascripts/monitoring/monitoring_bundle.js
deleted file mode 100644
index 2bbf9ef9d78..00000000000
--- a/app/assets/javascripts/monitoring/monitoring_bundle.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import Vue from 'vue';
-import { GlToast } from '@gitlab/ui';
-import Dashboard from '~/monitoring/components/dashboard.vue';
-import { parseBoolean } from '~/lib/utils/common_utils';
-import { getParameterValues } from '~/lib/utils/url_utility';
-import store from './stores';
-
-Vue.use(GlToast);
-
-export default (props = {}) => {
- const el = document.getElementById('prometheus-graphs');
-
- if (el && el.dataset) {
- const [currentDashboard] = getParameterValues('dashboard');
-
- // eslint-disable-next-line no-new
- new Vue({
- el,
- store,
- render(createElement) {
- return createElement(Dashboard, {
- props: {
- ...el.dataset,
- currentDashboard,
- hasMetrics: parseBoolean(el.dataset.hasMetrics),
- ...props,
- },
- });
- },
- });
- }
-};
diff --git a/app/assets/javascripts/monitoring/monitoring_bundle_with_alerts.js b/app/assets/javascripts/monitoring/monitoring_bundle_with_alerts.js
deleted file mode 100644
index afe5ee0938d..00000000000
--- a/app/assets/javascripts/monitoring/monitoring_bundle_with_alerts.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import { parseBoolean } from '~/lib/utils/common_utils';
-import initCeBundle from '~/monitoring/monitoring_bundle';
-
-export default () => {
- const el = document.getElementById('prometheus-graphs');
-
- if (el && el.dataset) {
- initCeBundle({
- customMetricsAvailable: parseBoolean(el.dataset.customMetricsAvailable),
- prometheusAlertsAvailable: parseBoolean(el.dataset.prometheusAlertsAvailable),
- });
- }
-};
diff --git a/app/assets/javascripts/monitoring/pages/dashboard_page.vue b/app/assets/javascripts/monitoring/pages/dashboard_page.vue
new file mode 100644
index 00000000000..519a20d7be3
--- /dev/null
+++ b/app/assets/javascripts/monitoring/pages/dashboard_page.vue
@@ -0,0 +1,18 @@
+<script>
+import Dashboard from '../components/dashboard.vue';
+
+export default {
+ components: {
+ Dashboard,
+ },
+ props: {
+ dashboardProps: {
+ type: Object,
+ required: true,
+ },
+ },
+};
+</script>
+<template>
+ <dashboard v-bind="{ ...dashboardProps }" />
+</template>
diff --git a/app/assets/javascripts/monitoring/router/constants.js b/app/assets/javascripts/monitoring/router/constants.js
new file mode 100644
index 00000000000..acfcd03f928
--- /dev/null
+++ b/app/assets/javascripts/monitoring/router/constants.js
@@ -0,0 +1,3 @@
+export const BASE_DASHBOARD_PAGE = 'dashboard';
+
+export default {};
diff --git a/app/assets/javascripts/monitoring/router/index.js b/app/assets/javascripts/monitoring/router/index.js
new file mode 100644
index 00000000000..12692612bbc
--- /dev/null
+++ b/app/assets/javascripts/monitoring/router/index.js
@@ -0,0 +1,15 @@
+import Vue from 'vue';
+import VueRouter from 'vue-router';
+import routes from './routes';
+
+Vue.use(VueRouter);
+
+export default function createRouter(base) {
+ const router = new VueRouter({
+ base,
+ mode: 'history',
+ routes,
+ });
+
+ return router;
+}
diff --git a/app/assets/javascripts/monitoring/router/routes.js b/app/assets/javascripts/monitoring/router/routes.js
new file mode 100644
index 00000000000..1e0cc1715a7
--- /dev/null
+++ b/app/assets/javascripts/monitoring/router/routes.js
@@ -0,0 +1,18 @@
+import DashboardPage from '../pages/dashboard_page.vue';
+
+import { BASE_DASHBOARD_PAGE } from './constants';
+
+/**
+ * Because the cluster health page uses the dashboard
+ * app instead the of the dashboard component, hitting
+ * `/` route is not possible. Hence using `*` until the
+ * health page is refactored.
+ * https://gitlab.com/gitlab-org/gitlab/-/issues/221096
+ */
+export default [
+ {
+ name: BASE_DASHBOARD_PAGE,
+ path: '*',
+ component: DashboardPage,
+ },
+];
diff --git a/app/assets/javascripts/monitoring/stores/actions.js b/app/assets/javascripts/monitoring/stores/actions.js
index 9e3edfb495d..3a9cccec438 100644
--- a/app/assets/javascripts/monitoring/stores/actions.js
+++ b/app/assets/javascripts/monitoring/stores/actions.js
@@ -3,8 +3,6 @@ import * as types from './mutation_types';
import axios from '~/lib/utils/axios_utils';
import createFlash from '~/flash';
import { convertToFixedRange } from '~/lib/utils/datetime_range';
-import { parseTemplatingVariables } from './variable_mapping';
-import { mergeURLVariables } from '../utils';
import {
gqClient,
parseEnvironmentsResponse,
@@ -161,7 +159,6 @@ export const receiveMetricsDashboardSuccess = ({ commit, dispatch }, { response
commit(types.SET_ALL_DASHBOARDS, all_dashboards);
commit(types.RECEIVE_METRICS_DASHBOARD_SUCCESS, dashboard);
- commit(types.SET_VARIABLES, mergeURLVariables(parseTemplatingVariables(dashboard.templating)));
commit(types.SET_ENDPOINTS, convertObjectPropsToCamelCase(metrics_data));
return dispatch('fetchDashboardData');
@@ -223,7 +220,7 @@ export const fetchPrometheusMetric = (
queryParams.step = metric.step;
}
- if (Object.keys(state.promVariables).length > 0) {
+ if (Object.keys(state.variables).length > 0) {
queryParams = {
...queryParams,
...getters.getCustomVariablesParams,
@@ -317,8 +314,7 @@ export const receiveEnvironmentsDataFailure = ({ commit }) => {
export const fetchAnnotations = ({ state, dispatch }) => {
const { start } = convertToFixedRange(state.timeRange);
- const dashboardPath =
- state.currentDashboard === '' ? DEFAULT_DASHBOARD_PATH : state.currentDashboard;
+ const dashboardPath = state.currentDashboard || DEFAULT_DASHBOARD_PATH;
return gqClient
.mutate({
mutation: getAnnotations,
@@ -373,7 +369,7 @@ export const toggleStarredValue = ({ commit, state, getters }) => {
method,
})
.then(() => {
- commit(types.RECEIVE_DASHBOARD_STARRING_SUCCESS, newStarredValue);
+ commit(types.RECEIVE_DASHBOARD_STARRING_SUCCESS, { selectedDashboard, newStarredValue });
})
.catch(() => {
commit(types.RECEIVE_DASHBOARD_STARRING_FAILURE);
@@ -419,8 +415,10 @@ export const duplicateSystemDashboard = ({ state }, payload) => {
// Variables manipulation
-export const updateVariableValues = ({ commit }, updatedVariable) => {
- commit(types.UPDATE_VARIABLE_VALUES, updatedVariable);
+export const updateVariablesAndFetchData = ({ commit, dispatch }, updatedVariable) => {
+ commit(types.UPDATE_VARIABLES, updatedVariable);
+
+ return dispatch('fetchDashboardData');
};
// prevent babel-plugin-rewire from generating an invalid default during karma tests
diff --git a/app/assets/javascripts/monitoring/stores/getters.js b/app/assets/javascripts/monitoring/stores/getters.js
index f309addee6b..b7681012472 100644
--- a/app/assets/javascripts/monitoring/stores/getters.js
+++ b/app/assets/javascripts/monitoring/stores/getters.js
@@ -1,5 +1,5 @@
import { NOT_IN_DB_PREFIX } from '../constants';
-import { addPrefixToCustomVariableParams } from './utils';
+import { addPrefixToCustomVariableParams, addDashboardMetaDataToLink } from './utils';
const metricsIdsInPanel = panel =>
panel.metrics.filter(metric => metric.metricId && metric.result).map(metric => metric.metricId);
@@ -113,6 +113,22 @@ export const filteredEnvironments = state =>
);
/**
+ * User-defined links from the yml file can have other
+ * dashboard-related metadata baked into it. This method
+ * returns modified links which will get rendered in the
+ * metrics dashboard
+ *
+ * @param {Object} state
+ * @returns {Array} modified array of links
+ */
+export const linksWithMetadata = state => {
+ const metadata = {
+ timeRange: state.timeRange,
+ };
+ return state.links?.map(addDashboardMetaDataToLink(metadata));
+};
+
+/**
* Maps an variables object to an array along with stripping
* the variable prefix.
*
@@ -133,8 +149,8 @@ export const filteredEnvironments = state =>
*/
export const getCustomVariablesParams = state =>
- Object.keys(state.promVariables).reduce((acc, variable) => {
- acc[addPrefixToCustomVariableParams(variable)] = state.promVariables[variable]?.value;
+ Object.keys(state.variables).reduce((acc, variable) => {
+ acc[addPrefixToCustomVariableParams(variable)] = state.variables[variable]?.value;
return acc;
}, {});
diff --git a/app/assets/javascripts/monitoring/stores/index.js b/app/assets/javascripts/monitoring/stores/index.js
index f08a6402aa6..213a8508aa2 100644
--- a/app/assets/javascripts/monitoring/stores/index.js
+++ b/app/assets/javascripts/monitoring/stores/index.js
@@ -15,11 +15,15 @@ export const monitoringDashboard = {
state,
};
-export const createStore = () =>
+export const createStore = (initState = {}) =>
new Vuex.Store({
modules: {
- monitoringDashboard,
+ monitoringDashboard: {
+ ...monitoringDashboard,
+ state: {
+ ...state(),
+ ...initState,
+ },
+ },
},
});
-
-export default createStore();
diff --git a/app/assets/javascripts/monitoring/stores/mutation_types.js b/app/assets/javascripts/monitoring/stores/mutation_types.js
index d60334609fd..4593461776b 100644
--- a/app/assets/javascripts/monitoring/stores/mutation_types.js
+++ b/app/assets/javascripts/monitoring/stores/mutation_types.js
@@ -3,7 +3,7 @@ export const REQUEST_METRICS_DASHBOARD = 'REQUEST_METRICS_DASHBOARD';
export const RECEIVE_METRICS_DASHBOARD_SUCCESS = 'RECEIVE_METRICS_DASHBOARD_SUCCESS';
export const RECEIVE_METRICS_DASHBOARD_FAILURE = 'RECEIVE_METRICS_DASHBOARD_FAILURE';
export const SET_VARIABLES = 'SET_VARIABLES';
-export const UPDATE_VARIABLE_VALUES = 'UPDATE_VARIABLE_VALUES';
+export const UPDATE_VARIABLES = 'UPDATE_VARIABLES';
export const REQUEST_DASHBOARD_STARRING = 'REQUEST_DASHBOARD_STARRING';
export const RECEIVE_DASHBOARD_STARRING_SUCCESS = 'RECEIVE_DASHBOARD_STARRING_SUCCESS';
diff --git a/app/assets/javascripts/monitoring/stores/mutations.js b/app/assets/javascripts/monitoring/stores/mutations.js
index f41cf3fc477..2d63fdd6e34 100644
--- a/app/assets/javascripts/monitoring/stores/mutations.js
+++ b/app/assets/javascripts/monitoring/stores/mutations.js
@@ -1,7 +1,6 @@
import Vue from 'vue';
import { pick } from 'lodash';
import * as types from './mutation_types';
-import { selectedDashboard } from './getters';
import { mapToDashboardViewModel, normalizeQueryResult } from './utils';
import { BACKOFF_TIMEOUT } from '../../lib/utils/common_utils';
import { endpointKeys, initialStateKeys, metricStates } from '../constants';
@@ -61,8 +60,14 @@ export default {
state.emptyState = 'loading';
state.showEmptyState = true;
},
- [types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, dashboard) {
- state.dashboard = mapToDashboardViewModel(dashboard);
+ [types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, dashboardYML) {
+ const { dashboard, panelGroups, variables, links } = mapToDashboardViewModel(dashboardYML);
+ state.dashboard = {
+ dashboard,
+ panelGroups,
+ };
+ state.variables = variables;
+ state.links = links;
if (!state.dashboard.panelGroups.length) {
state.emptyState = 'noData';
@@ -76,15 +81,14 @@ export default {
[types.REQUEST_DASHBOARD_STARRING](state) {
state.isUpdatingStarredValue = true;
},
- [types.RECEIVE_DASHBOARD_STARRING_SUCCESS](state, newStarredValue) {
- const dashboard = selectedDashboard(state);
- const index = state.allDashboards.findIndex(d => d === dashboard);
+ [types.RECEIVE_DASHBOARD_STARRING_SUCCESS](state, { selectedDashboard, newStarredValue }) {
+ const index = state.allDashboards.findIndex(d => d === selectedDashboard);
state.isUpdatingStarredValue = false;
// Trigger state updates in the reactivity system for this change
// https://vuejs.org/v2/guide/reactivity.html#For-Arrays
- Vue.set(state.allDashboards, index, { ...dashboard, starred: newStarredValue });
+ Vue.set(state.allDashboards, index, { ...selectedDashboard, starred: newStarredValue });
},
[types.RECEIVE_DASHBOARD_STARRING_FAILURE](state) {
state.isUpdatingStarredValue = false;
@@ -189,11 +193,11 @@ export default {
state.expandedPanel.panel = panel;
},
[types.SET_VARIABLES](state, variables) {
- state.promVariables = variables;
+ state.variables = variables;
},
- [types.UPDATE_VARIABLE_VALUES](state, updatedVariable) {
- Object.assign(state.promVariables[updatedVariable.key], {
- ...state.promVariables[updatedVariable.key],
+ [types.UPDATE_VARIABLES](state, updatedVariable) {
+ Object.assign(state.variables[updatedVariable.key], {
+ ...state.variables[updatedVariable.key],
value: updatedVariable.value,
});
},
diff --git a/app/assets/javascripts/monitoring/stores/state.js b/app/assets/javascripts/monitoring/stores/state.js
index 9ae1da93e5f..8000f27c0d5 100644
--- a/app/assets/javascripts/monitoring/stores/state.js
+++ b/app/assets/javascripts/monitoring/stores/state.js
@@ -1,10 +1,11 @@
import invalidUrl from '~/lib/utils/invalid_url';
+import { timezones } from '../format_date';
export default () => ({
// API endpoints
- metricsEndpoint: null,
deploymentsEndpoint: null,
dashboardEndpoint: invalidUrl,
+ dashboardsEndpoint: invalidUrl,
// Dashboard request parameters
timeRange: null,
@@ -34,14 +35,24 @@ export default () => ({
panel: null,
},
allDashboards: [],
- promVariables: {},
-
+ /**
+ * User-defined custom variables are passed
+ * via the dashboard yml file.
+ */
+ variables: {},
+ /**
+ * User-defined custom links are passed
+ * via the dashboard yml file.
+ */
+ links: [],
// Other project data
+ dashboardTimezone: timezones.LOCAL,
annotations: [],
deploymentData: [],
environments: [],
environmentsSearchTerm: '',
environmentsLoading: false,
+ currentEnvironmentName: null,
// GitLab paths to other pages
projectPath: null,
diff --git a/app/assets/javascripts/monitoring/stores/utils.js b/app/assets/javascripts/monitoring/stores/utils.js
index b6817e7279a..058fab5f4fc 100644
--- a/app/assets/javascripts/monitoring/stores/utils.js
+++ b/app/assets/javascripts/monitoring/stores/utils.js
@@ -2,7 +2,11 @@ import { slugify } from '~/lib/utils/text_utility';
import createGqClient, { fetchPolicies } from '~/lib/graphql';
import { SUPPORTED_FORMATS } from '~/lib/utils/unit_format';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
-import { NOT_IN_DB_PREFIX } from '../constants';
+import { parseTemplatingVariables } from './variable_mapping';
+import { NOT_IN_DB_PREFIX, linkTypes } from '../constants';
+import { DATETIME_RANGE_TYPES } from '~/lib/utils/constants';
+import { timeRangeToParams, getRangeType } from '~/lib/utils/datetime_range';
+import { isSafeURL, mergeUrlParams } from '~/lib/utils/url_utility';
export const gqClient = createGqClient(
{},
@@ -138,6 +142,24 @@ const mapYAxisToViewModel = ({
};
/**
+ * Maps a link to its view model, expects an url and
+ * (optionally) a title.
+ *
+ * Unsafe URLs are ignored.
+ *
+ * @param {Object} Link
+ * @returns {Object} Link object with a `title`, `url` and `type`
+ *
+ */
+const mapLinksToViewModel = ({ url = null, title = '', type } = {}) => {
+ return {
+ title: title || String(url),
+ type,
+ url: url && isSafeURL(url) ? String(url) : '#',
+ };
+};
+
+/**
* Maps a metrics panel to its view model
*
* @param {Object} panel - Metrics panel
@@ -152,6 +174,7 @@ const mapPanelToViewModel = ({
y_label,
y_axis = {},
metrics = [],
+ links = [],
max_value,
}) => {
// Both `x_axis.name` and `x_label` are supported for now
@@ -171,7 +194,8 @@ const mapPanelToViewModel = ({
yAxis,
xAxis,
maxValue: max_value,
- metrics: mapToMetricsViewModel(metrics, yAxis.name),
+ links: links.map(mapLinksToViewModel),
+ metrics: mapToMetricsViewModel(metrics),
};
};
@@ -190,6 +214,66 @@ const mapToPanelGroupViewModel = ({ group = '', panels = [] }, i) => {
};
/**
+ * Convert dashboard time range to Grafana
+ * dashboards time range.
+ *
+ * @param {Object} timeRange
+ * @returns {Object}
+ */
+export const convertToGrafanaTimeRange = timeRange => {
+ const timeRangeType = getRangeType(timeRange);
+ if (timeRangeType === DATETIME_RANGE_TYPES.fixed) {
+ return {
+ from: new Date(timeRange.start).getTime(),
+ to: new Date(timeRange.end).getTime(),
+ };
+ } else if (timeRangeType === DATETIME_RANGE_TYPES.rolling) {
+ const { seconds } = timeRange.duration;
+ return {
+ from: `now-${seconds}s`,
+ to: 'now',
+ };
+ }
+ // fallback to returning the time range as is
+ return timeRange;
+};
+
+/**
+ * Convert dashboard time ranges to other supported
+ * link formats.
+ *
+ * @param {Object} timeRange metrics dashboard time range
+ * @param {String} type type of link
+ * @returns {String}
+ */
+export const convertTimeRanges = (timeRange, type) => {
+ if (type === linkTypes.GRAFANA) {
+ return convertToGrafanaTimeRange(timeRange);
+ }
+ return timeRangeToParams(timeRange);
+};
+
+/**
+ * Adds dashboard-related metadata to the user-defined links.
+ *
+ * As of %13.1, metadata only includes timeRange but in the
+ * future more info will be added to the links.
+ *
+ * @param {Object} metadata
+ * @returns {Function}
+ */
+export const addDashboardMetaDataToLink = metadata => link => {
+ let modifiedLink = { ...link };
+ if (metadata.timeRange) {
+ modifiedLink = {
+ ...modifiedLink,
+ url: mergeUrlParams(convertTimeRanges(metadata.timeRange, link.type), link.url),
+ };
+ }
+ return modifiedLink;
+};
+
+/**
* Maps a dashboard json object to its view model
*
* @param {Object} dashboard - Dashboard object
@@ -197,13 +281,33 @@ const mapToPanelGroupViewModel = ({ group = '', panels = [] }, i) => {
* @param {Array} dashboard.panel_groups - Panel groups array
* @returns {Object}
*/
-export const mapToDashboardViewModel = ({ dashboard = '', panel_groups = [] }) => {
+export const mapToDashboardViewModel = ({
+ dashboard = '',
+ templating = {},
+ links = [],
+ panel_groups = [],
+}) => {
return {
dashboard,
+ variables: parseTemplatingVariables(templating),
+ links: links.map(mapLinksToViewModel),
panelGroups: panel_groups.map(mapToPanelGroupViewModel),
};
};
+/**
+ * Processes a single Range vector, part of the result
+ * of type `matrix` in the form:
+ *
+ * {
+ * "metric": { "<label_name>": "<label_value>", ... },
+ * "values": [ [ <unix_time>, "<sample_value>" ], ... ]
+ * },
+ *
+ * See https://prometheus.io/docs/prometheus/latest/querying/api/#range-vectors
+ *
+ * @param {*} timeSeries
+ */
export const normalizeQueryResult = timeSeries => {
let normalizedResult = {};
diff --git a/app/assets/javascripts/monitoring/stores/variable_mapping.js b/app/assets/javascripts/monitoring/stores/variable_mapping.js
index bfb469da19e..66b9899f673 100644
--- a/app/assets/javascripts/monitoring/stores/variable_mapping.js
+++ b/app/assets/javascripts/monitoring/stores/variable_mapping.js
@@ -47,7 +47,7 @@ const textAdvancedVariableParser = advTextVar => ({
*/
const normalizeCustomVariableOptions = ({ default: defaultOpt = false, text, value }) => ({
default: defaultOpt,
- text,
+ text: text || value,
value,
});
diff --git a/app/assets/javascripts/monitoring/utils.js b/app/assets/javascripts/monitoring/utils.js
index 1f028ffbcad..95d544bd6d4 100644
--- a/app/assets/javascripts/monitoring/utils.js
+++ b/app/assets/javascripts/monitoring/utils.js
@@ -151,7 +151,7 @@ export const removePrefixFromLabel = label =>
/**
* Convert parsed template variables to an object
- * with just keys and values. Prepare the promVariables
+ * with just keys and values. Prepare the variables
* to be added to the URL. Keys of the object will
* have a prefix so that these params can be
* differentiated from other URL params.
@@ -183,15 +183,15 @@ export const getPromCustomVariablesFromUrl = (search = window.location.search) =
};
/**
- * Update the URL with promVariables. This usually get triggered when
+ * Update the URL with variables. This usually get triggered when
* the user interacts with the dynamic input elements in the monitoring
* dashboard header.
*
- * @param {Object} promVariables user defined variables
+ * @param {Object} variables user defined variables
*/
-export const setPromCustomVariablesFromUrl = promVariables => {
+export const setCustomVariablesFromUrl = variables => {
// prep the variables to append to URL
- const parsedVariables = convertVariablesForURL(promVariables);
+ const parsedVariables = convertVariablesForURL(variables);
// update the URL
updateHistory({
url: mergeUrlParams(parsedVariables, window.location.href),
@@ -262,7 +262,7 @@ export const expandedPanelPayloadFromUrl = (dashboard, search = window.location.
* If no group/panel is set, the dashboard URL is returned.
*
* @param {?String} dashboard - Dashboard path, used as identifier for a dashboard
- * @param {?Object} promVariables - Custom variables that came from the URL
+ * @param {?Object} variables - Custom variables that came from the URL
* @param {?String} group - Group Identifier
* @param {?Object} panel - Panel object from the dashboard
* @param {?String} url - Base URL including current search params
@@ -270,14 +270,14 @@ export const expandedPanelPayloadFromUrl = (dashboard, search = window.location.
*/
export const panelToUrl = (
dashboard = null,
- promVariables,
+ variables,
group,
panel,
url = window.location.href,
) => {
const params = {
dashboard,
- ...promVariables,
+ ...variables,
};
if (group && panel) {
diff --git a/app/assets/javascripts/mr_notes/index.js b/app/assets/javascripts/mr_notes/index.js
index c1edf7be870..fb6ef0249bb 100644
--- a/app/assets/javascripts/mr_notes/index.js
+++ b/app/assets/javascripts/mr_notes/index.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import store from 'ee_else_ce/mr_notes/stores';
+import store from '~/mr_notes/stores';
import initNotesApp from './init_notes';
import initDiffsApp from '../diffs';
import discussionCounter from '../notes/components/discussion_counter.vue';
diff --git a/app/assets/javascripts/mr_notes/init_notes.js b/app/assets/javascripts/mr_notes/init_notes.js
index 2580f8e86b1..fcde9bf7849 100644
--- a/app/assets/javascripts/mr_notes/init_notes.js
+++ b/app/assets/javascripts/mr_notes/init_notes.js
@@ -1,7 +1,7 @@
import $ from 'jquery';
import Vue from 'vue';
import { mapActions, mapState, mapGetters } from 'vuex';
-import store from 'ee_else_ce/mr_notes/stores';
+import store from '~/mr_notes/stores';
import notesApp from '../notes/components/notes_app.vue';
import discussionKeyboardNavigator from '../notes/components/discussion_keyboard_navigator.vue';
import initWidget from '../vue_merge_request_widget';
diff --git a/app/assets/javascripts/mr_notes/stores/index.js b/app/assets/javascripts/mr_notes/stores/index.js
index 8fbd0291a7d..8492b8d0aff 100644
--- a/app/assets/javascripts/mr_notes/stores/index.js
+++ b/app/assets/javascripts/mr_notes/stores/index.js
@@ -1,5 +1,6 @@
import Vue from 'vue';
import Vuex from 'vuex';
+import batchCommentsModule from '~/batch_comments/stores/modules/batch_comments';
import notesModule from '~/notes/stores/modules';
import diffsModule from '~/diffs/store/modules';
import mrPageModule from './modules';
@@ -12,6 +13,7 @@ export const createStore = () =>
page: mrPageModule(),
notes: notesModule(),
diffs: diffsModule(),
+ batchComments: batchCommentsModule(),
},
});
diff --git a/app/assets/javascripts/namespace_storage_limit_alert.js b/app/assets/javascripts/namespace_storage_limit_alert.js
new file mode 100644
index 00000000000..34ad93c127d
--- /dev/null
+++ b/app/assets/javascripts/namespace_storage_limit_alert.js
@@ -0,0 +1,20 @@
+import Cookies from 'js-cookie';
+
+const handleOnDismiss = ({ currentTarget }) => {
+ const {
+ dataset: { id, level },
+ } = currentTarget;
+
+ Cookies.set(`hide_storage_limit_alert_${id}_${level}`, true, { expires: 365 });
+
+ const notification = document.querySelector('.js-namespace-storage-alert');
+ notification.parentNode.removeChild(notification);
+};
+
+export default () => {
+ const alert = document.querySelector('.js-namespace-storage-alert-dismiss');
+
+ if (alert) {
+ alert.addEventListener('click', handleOnDismiss);
+ }
+};
diff --git a/app/assets/javascripts/notes/components/comment_form.vue b/app/assets/javascripts/notes/components/comment_form.vue
index a070cf8866a..16dcde46262 100644
--- a/app/assets/javascripts/notes/components/comment_form.vue
+++ b/app/assets/javascripts/notes/components/comment_form.vue
@@ -29,6 +29,7 @@ export default {
name: 'CommentForm',
components: {
issueWarning,
+ epicWarning: () => import('ee_component/vue_shared/components/epic/epic_warning.vue'),
noteSignedOutWidget,
discussionLockedWidget,
markdownField,
@@ -60,6 +61,7 @@ export default {
'getCurrentUserLastNote',
'getUserData',
'getNoteableData',
+ 'getNoteableDataByProp',
'getNotesData',
'openState',
'getBlockedByIssues',
@@ -135,6 +137,9 @@ export default {
? __('merge request')
: __('issue');
},
+ isIssueType() {
+ return this.noteableDisplayName === constants.ISSUE_NOTEABLE_TYPE;
+ },
trackingLabel() {
return slugifyWithUnderscore(`${this.commentButtonTitle} button`);
},
@@ -346,13 +351,13 @@ export default {
<div class="error-alert"></div>
<issue-warning
- v-if="hasWarning(getNoteableData)"
+ v-if="hasWarning(getNoteableData) && isIssueType"
:is-locked="isLocked(getNoteableData)"
:is-confidential="isConfidential(getNoteableData)"
:locked-issue-docs-path="lockedIssueDocsPath"
:confidential-issue-docs-path="confidentialIssueDocsPath"
/>
-
+ <epic-warning :is-confidential="isConfidential(getNoteableData)" />
<markdown-field
ref="markdownField"
:is-submitting="isSubmitting"
@@ -412,7 +417,7 @@ js-gfm-input js-autosize markdown-area js-vue-textarea qa-comment-input"
</gl-alert>
<div class="note-form-actions">
<div
- class="float-left btn-group
+ class="btn-group
append-right-10 comment-type-dropdown js-comment-type-dropdown droplab-dropdown"
>
<button
diff --git a/app/assets/javascripts/notes/components/diff_with_note.vue b/app/assets/javascripts/notes/components/diff_with_note.vue
index cd5cfc09ea0..8897b54fac7 100644
--- a/app/assets/javascripts/notes/components/diff_with_note.vue
+++ b/app/assets/javascripts/notes/components/diff_with_note.vue
@@ -116,6 +116,7 @@ export default {
</div>
<div v-else>
<diff-viewer
+ :diff-file="discussion.diff_file"
:diff-mode="diffMode"
:diff-viewer-mode="diffViewerMode"
:new-path="discussion.diff_file.new_path"
diff --git a/app/assets/javascripts/notes/components/multiline_comment_form.vue b/app/assets/javascripts/notes/components/multiline_comment_form.vue
new file mode 100644
index 00000000000..5fba011a153
--- /dev/null
+++ b/app/assets/javascripts/notes/components/multiline_comment_form.vue
@@ -0,0 +1,68 @@
+<script>
+import { GlFormSelect, GlSprintf } from '@gitlab/ui';
+import { getSymbol, getLineClasses } from './multiline_comment_utils';
+
+export default {
+ components: { GlFormSelect, GlSprintf },
+ props: {
+ lineRange: {
+ type: Object,
+ required: false,
+ default: null,
+ },
+ line: {
+ type: Object,
+ required: true,
+ },
+ commentLineOptions: {
+ type: Array,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ commentLineStart: {
+ lineCode: this.lineRange ? this.lineRange.start_line_code : this.line.line_code,
+ type: this.lineRange ? this.lineRange.start_line_type : this.line.type,
+ },
+ };
+ },
+ methods: {
+ getSymbol({ type }) {
+ return getSymbol(type);
+ },
+ getLineClasses(line) {
+ return getLineClasses(line);
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <gl-sprintf
+ :message="
+ s__('MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}')
+ "
+ >
+ <template #select>
+ <label for="comment-line-start" class="sr-only">{{
+ s__('MergeRequestDiffs|Select comment starting line')
+ }}</label>
+ <gl-form-select
+ id="comment-line-start"
+ :value="commentLineStart"
+ :options="commentLineOptions"
+ size="sm"
+ class="gl-w-auto gl-vertical-align-baseline"
+ @change="$emit('input', $event)"
+ />
+ </template>
+ <template #end>
+ <span :class="getLineClasses(line)">
+ {{ getSymbol(line) + (line.new_line || line.old_line) }}
+ </span>
+ </template>
+ </gl-sprintf>
+ </div>
+</template>
diff --git a/app/assets/javascripts/notes/components/multiline_comment_utils.js b/app/assets/javascripts/notes/components/multiline_comment_utils.js
new file mode 100644
index 00000000000..dc9c55e9b30
--- /dev/null
+++ b/app/assets/javascripts/notes/components/multiline_comment_utils.js
@@ -0,0 +1,57 @@
+import { takeRightWhile } from 'lodash';
+
+export function getSymbol(type) {
+ if (type === 'new') return '+';
+ if (type === 'old') return '-';
+ return '';
+}
+
+function getLineNumber(lineRange, key) {
+ if (!lineRange || !key) return '';
+ const lineCode = lineRange[`${key}_line_code`] || '';
+ const lineType = lineRange[`${key}_line_type`] || '';
+ const lines = lineCode.split('_') || [];
+ const lineNumber = lineType === 'old' ? lines[1] : lines[2];
+ return (lineNumber && getSymbol(lineType) + lineNumber) || '';
+}
+
+export function getStartLineNumber(lineRange) {
+ return getLineNumber(lineRange, 'start');
+}
+
+export function getEndLineNumber(lineRange) {
+ return getLineNumber(lineRange, 'end');
+}
+
+export function getLineClasses(line) {
+ const symbol = typeof line === 'string' ? line.charAt(0) : getSymbol(line?.type);
+
+ if (symbol !== '+' && symbol !== '-') return '';
+
+ return [
+ 'gl-px-1 gl-rounded-small gl-border-solid gl-border-1 gl-border-white',
+ {
+ 'gl-bg-green-100 gl-text-green-800': symbol === '+',
+ 'gl-bg-red-100 gl-text-red-800': symbol === '-',
+ },
+ ];
+}
+
+export function commentLineOptions(diffLines, lineCode) {
+ const selectedIndex = diffLines.findIndex(line => line.line_code === lineCode);
+ const notMatchType = l => l.type !== 'match';
+
+ // We're limiting adding comments to only lines above the current line
+ // to make rendering simpler. Future interations will use a more
+ // intuitive dragging interface that will make this unnecessary
+ const upToSelected = diffLines.slice(0, selectedIndex + 1);
+
+ // Only include the lines up to the first "Show unchanged lines" block
+ // i.e. not a "match" type
+ const lines = takeRightWhile(upToSelected, notMatchType);
+
+ return lines.map(l => ({
+ value: { lineCode: l.line_code, type: l.type },
+ text: `${getSymbol(l.type)}${l.new_line || l.old_line}`,
+ }));
+}
diff --git a/app/assets/javascripts/notes/components/note_actions.vue b/app/assets/javascripts/notes/components/note_actions.vue
index dc514f00801..f1af8be590a 100644
--- a/app/assets/javascripts/notes/components/note_actions.vue
+++ b/app/assets/javascripts/notes/components/note_actions.vue
@@ -1,9 +1,13 @@
<script>
+import { __ } from '~/locale';
import { mapGetters } from 'vuex';
import { GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui';
-import resolvedStatusMixin from 'ee_else_ce/batch_comments/mixins/resolved_status';
+import resolvedStatusMixin from '~/batch_comments/mixins/resolved_status';
import Icon from '~/vue_shared/components/icon.vue';
import ReplyButton from './note_actions/reply_button.vue';
+import eventHub from '~/sidebar/event_hub';
+import Api from '~/api';
+import flash from '~/flash';
export default {
name: 'NoteActions',
@@ -17,6 +21,10 @@ export default {
},
mixins: [resolvedStatusMixin],
props: {
+ author: {
+ type: Object,
+ required: true,
+ },
authorId: {
type: Number,
required: true,
@@ -87,7 +95,7 @@ export default {
},
},
computed: {
- ...mapGetters(['getUserDataByProp']),
+ ...mapGetters(['getUserDataByProp', 'getNoteableData']),
shouldShowActionsDropdown() {
return this.currentUserId && (this.canEdit || this.canReportAsAbuse);
},
@@ -100,6 +108,26 @@ export default {
currentUserId() {
return this.getUserDataByProp('id');
},
+ isUserAssigned() {
+ return this.assignees && this.assignees.some(({ id }) => id === this.author.id);
+ },
+ displayAssignUserText() {
+ return this.isUserAssigned
+ ? __('Unassign from commenting user')
+ : __('Assign to commenting user');
+ },
+ sidebarAction() {
+ return this.isUserAssigned ? 'sidebar.addAssignee' : 'sidebar.removeAssignee';
+ },
+ targetType() {
+ return this.getNoteableData.targetType;
+ },
+ assignees() {
+ return this.getNoteableData.assignees || [];
+ },
+ isIssue() {
+ return this.targetType === 'issue';
+ },
},
methods: {
onEdit() {
@@ -116,6 +144,29 @@ export default {
this.$root.$emit('bv::hide::tooltip');
});
},
+ handleAssigneeUpdate(assignees) {
+ this.$emit('updateAssignees', assignees);
+ eventHub.$emit(this.sidebarAction, this.author);
+ eventHub.$emit('sidebar.saveAssignees');
+ },
+ assignUser() {
+ let { assignees } = this;
+ const { project_id, iid } = this.getNoteableData;
+
+ if (this.isUserAssigned) {
+ assignees = assignees.filter(assignee => assignee.id !== this.author.id);
+ } else {
+ assignees.push({ id: this.author.id });
+ }
+
+ if (this.targetType === 'issue') {
+ Api.updateIssue(project_id, iid, {
+ assignee_ids: assignees.map(assignee => assignee.id),
+ })
+ .then(() => this.handleAssigneeUpdate(assignees))
+ .catch(() => flash(__('Something went wrong while updating assignees')));
+ }
+ },
},
};
</script>
@@ -215,6 +266,16 @@ export default {
<span class="text-danger">{{ __('Delete comment') }}</span>
</button>
</li>
+ <li v-if="isIssue">
+ <button
+ class="btn-default btn-transparent"
+ data-testid="assign-user"
+ type="button"
+ @click="assignUser"
+ >
+ {{ displayAssignUserText }}
+ </button>
+ </li>
</ul>
</div>
</div>
diff --git a/app/assets/javascripts/notes/components/note_body.vue b/app/assets/javascripts/notes/components/note_body.vue
index 358f49deb35..42b78929f8a 100644
--- a/app/assets/javascripts/notes/components/note_body.vue
+++ b/app/assets/javascripts/notes/components/note_body.vue
@@ -1,8 +1,7 @@
<script>
-import { mapActions } from 'vuex';
+import { mapActions, mapGetters, mapState } from 'vuex';
import $ from 'jquery';
import '~/behaviors/markdown/render_gfm';
-import getDiscussion from 'ee_else_ce/notes/mixins/get_discussion';
import noteEditedText from './note_edited_text.vue';
import noteAwardsList from './note_awards_list.vue';
import noteAttachment from './note_attachment.vue';
@@ -18,7 +17,7 @@ export default {
noteForm,
Suggestions,
},
- mixins: [autosave, getDiscussion],
+ mixins: [autosave],
props: {
note: {
type: Object,
@@ -45,6 +44,15 @@ export default {
},
},
computed: {
+ ...mapGetters(['getDiscussion']),
+ discussion() {
+ if (!this.note.isDraft) return {};
+
+ return this.getDiscussion(this.note.discussion_id);
+ },
+ ...mapState({
+ batchSuggestionsInfo: state => state.notes.batchSuggestionsInfo,
+ }),
noteBody() {
return this.note.note;
},
@@ -74,7 +82,12 @@ export default {
}
},
methods: {
- ...mapActions(['submitSuggestion']),
+ ...mapActions([
+ 'submitSuggestion',
+ 'submitSuggestionBatch',
+ 'addSuggestionInfoToBatch',
+ 'removeSuggestionInfoFromBatch',
+ ]),
renderGFM() {
$(this.$refs['note-body']).renderGFM();
},
@@ -91,6 +104,17 @@ export default {
callback,
);
},
+ applySuggestionBatch({ flashContainer }) {
+ return this.submitSuggestionBatch({ flashContainer });
+ },
+ addSuggestionToBatch(suggestionId) {
+ const { discussion_id: discussionId, id: noteId } = this.note;
+
+ this.addSuggestionInfoToBatch({ suggestionId, discussionId, noteId });
+ },
+ removeSuggestionFromBatch(suggestionId) {
+ this.removeSuggestionInfoFromBatch(suggestionId);
+ },
},
};
</script>
@@ -100,10 +124,14 @@ export default {
<suggestions
v-if="hasSuggestion && !isEditing"
:suggestions="note.suggestions"
+ :batch-suggestions-info="batchSuggestionsInfo"
:note-html="note.note_html"
:line-type="lineType"
:help-page-path="helpPagePath"
@apply="applySuggestion"
+ @applyBatch="applySuggestionBatch"
+ @addToBatch="addSuggestionToBatch"
+ @removeFromBatch="removeSuggestionFromBatch"
/>
<div v-else class="note-text md" v-html="note.note_html"></div>
<note-form
diff --git a/app/assets/javascripts/notes/components/note_form.vue b/app/assets/javascripts/notes/components/note_form.vue
index 21d0bffdf1c..795ee10ca0f 100644
--- a/app/assets/javascripts/notes/components/note_form.vue
+++ b/app/assets/javascripts/notes/components/note_form.vue
@@ -1,6 +1,5 @@
<script>
-import { mapGetters, mapActions } from 'vuex';
-import noteFormMixin from 'ee_else_ce/notes/mixins/note_form';
+import { mapGetters, mapActions, mapState } from 'vuex';
import { mergeUrlParams } from '~/lib/utils/url_utility';
import eventHub from '../event_hub';
import issueWarning from '../../vue_shared/components/issue/issue_warning.vue';
@@ -16,7 +15,7 @@ export default {
issueWarning,
markdownField,
},
- mixins: [issuableStateMixin, resolvable, noteFormMixin],
+ mixins: [issuableStateMixin, resolvable],
props: {
noteBody: {
type: String,
@@ -82,6 +81,11 @@ export default {
required: false,
default: false,
},
+ isDraft: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
data() {
let updatedNoteBody = this.noteBody;
@@ -107,6 +111,16 @@ export default {
'getNotesDataByProp',
'getUserDataByProp',
]),
+ ...mapState({
+ withBatchComments: state => state.batchComments?.withBatchComments,
+ }),
+ ...mapGetters('batchComments', ['hasDrafts']),
+ showBatchCommentsActions() {
+ return this.withBatchComments && this.noteId === '' && !this.discussion.for_commit;
+ },
+ showResolveDiscussionToggle() {
+ return (this.discussion?.id && this.discussion.resolvable) || this.isDraft;
+ },
noteHash() {
if (this.noteId) {
return `#note_${this.noteId}`;
@@ -202,8 +216,6 @@ export default {
methods: {
...mapActions(['toggleResolveNote']),
shouldToggleResolved(shouldResolve, beforeSubmitDiscussionState) {
- // shouldBeResolved() checks the actual resolution state,
- // considering batchComments (EEP), if applicable/enabled.
const newResolvedStateAfterUpdate =
this.shouldBeResolved && this.shouldBeResolved(shouldResolve);
@@ -234,6 +246,50 @@ export default {
updateDraft(autosaveKey, text);
}
},
+ handleKeySubmit() {
+ if (this.showBatchCommentsActions) {
+ this.handleAddToReview();
+ } else {
+ this.handleUpdate();
+ }
+ },
+ handleUpdate(shouldResolve) {
+ const beforeSubmitDiscussionState = this.discussionResolved;
+ this.isSubmitting = true;
+
+ this.$emit(
+ 'handleFormUpdate',
+ this.updatedNoteBody,
+ this.$refs.editNoteForm,
+ () => {
+ this.isSubmitting = false;
+
+ if (this.shouldToggleResolved(shouldResolve, beforeSubmitDiscussionState)) {
+ this.resolveHandler(beforeSubmitDiscussionState);
+ }
+ },
+ this.discussionResolved ? !this.isUnresolving : this.isResolving,
+ );
+ },
+ shouldBeResolved(resolveStatus) {
+ if (this.withBatchComments) {
+ return (
+ (this.discussionResolved && !this.isUnresolving) ||
+ (!this.discussionResolved && this.isResolving)
+ );
+ }
+
+ return resolveStatus;
+ },
+ handleAddToReview() {
+ // check if draft should resolve thread
+ const shouldResolve =
+ (this.discussionResolved && !this.isUnresolving) ||
+ (!this.discussionResolved && this.isResolving);
+ this.isSubmitting = true;
+
+ this.$emit('handleFormUpdateAddToReview', this.updatedNoteBody, shouldResolve);
+ },
},
};
</script>
@@ -293,6 +349,7 @@ export default {
<input
v-model="isUnresolving"
type="checkbox"
+ class="js-unresolve-checkbox"
data-qa-selector="unresolve_review_discussion_checkbox"
/>
{{ __('Unresolve thread') }}
@@ -301,6 +358,7 @@ export default {
<input
v-model="isResolving"
type="checkbox"
+ class="js-resolve-checkbox"
data-qa-selector="resolve_review_discussion_checkbox"
/>
{{ __('Resolve thread') }}
@@ -320,7 +378,7 @@ export default {
<button
:disabled="isDisabled"
type="button"
- class="btn qa-comment-now"
+ class="btn qa-comment-now js-comment-button"
@click="handleUpdate()"
>
{{ __('Add comment now') }}
diff --git a/app/assets/javascripts/notes/components/noteable_discussion.vue b/app/assets/javascripts/notes/components/noteable_discussion.vue
index 189ff88feb3..7fe50d36c0c 100644
--- a/app/assets/javascripts/notes/components/noteable_discussion.vue
+++ b/app/assets/javascripts/notes/components/noteable_discussion.vue
@@ -1,11 +1,12 @@
<script>
import { mapActions, mapGetters } from 'vuex';
import { GlTooltipDirective } from '@gitlab/ui';
-import diffLineNoteFormMixin from 'ee_else_ce/notes/mixins/diff_line_note_form';
+import diffLineNoteFormMixin from '~/notes/mixins/diff_line_note_form';
import { s__, __ } from '~/locale';
import { clearDraft, getDiscussionReplyKey } from '~/lib/utils/autosave';
import icon from '~/vue_shared/components/icon.vue';
import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue';
+import DraftNote from '~/batch_comments/components/draft_note.vue';
import Flash from '../../flash';
import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue';
import diffDiscussionHeader from './diff_discussion_header.vue';
@@ -26,7 +27,7 @@ export default {
diffDiscussionHeader,
noteSignedOutWidget,
noteForm,
- DraftNote: () => import('ee_component/batch_comments/components/draft_note.vue'),
+ DraftNote,
TimelineEntryItem,
DiscussionNotes,
DiscussionActions,
diff --git a/app/assets/javascripts/notes/components/noteable_note.vue b/app/assets/javascripts/notes/components/noteable_note.vue
index 37675e20b3d..0e4dd1b9c84 100644
--- a/app/assets/javascripts/notes/components/noteable_note.vue
+++ b/app/assets/javascripts/notes/components/noteable_note.vue
@@ -2,7 +2,8 @@
import $ from 'jquery';
import { mapGetters, mapActions } from 'vuex';
import { escape } from 'lodash';
-import draftMixin from 'ee_else_ce/notes/mixins/draft';
+import { GlSprintf } from '@gitlab/ui';
+import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { truncateSha } from '~/lib/utils/text_utility';
import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue';
import { __, s__, sprintf } from '../../locale';
@@ -15,17 +16,26 @@ import eventHub from '../event_hub';
import noteable from '../mixins/noteable';
import resolvable from '../mixins/resolvable';
import httpStatusCodes from '~/lib/utils/http_status';
+import {
+ getStartLineNumber,
+ getEndLineNumber,
+ getLineClasses,
+ commentLineOptions,
+} from './multiline_comment_utils';
+import MultilineCommentForm from './multiline_comment_form.vue';
export default {
name: 'NoteableNote',
components: {
+ GlSprintf,
userAvatarLink,
noteHeader,
noteActions,
NoteBody,
TimelineEntryItem,
+ MultilineCommentForm,
},
- mixins: [noteable, resolvable, draftMixin],
+ mixins: [noteable, resolvable, glFeatureFlagsMixin()],
props: {
note: {
type: Object,
@@ -51,6 +61,11 @@ export default {
required: false,
default: false,
},
+ diffLines: {
+ type: Object,
+ required: false,
+ default: null,
+ },
},
data() {
return {
@@ -58,9 +73,14 @@ export default {
isDeleting: false,
isRequesting: false,
isResolving: false,
+ commentLineStart: {
+ line_code: this.line?.line_code,
+ type: this.line?.type,
+ },
};
},
computed: {
+ ...mapGetters('diffs', ['getDiffFileByHash']),
...mapGetters(['targetNoteHash', 'getNoteableData', 'getUserData', 'commentsDisabled']),
author() {
return this.note.author;
@@ -105,6 +125,41 @@ export default {
)}</a>`;
return sprintf(s__('MergeRequests|commented on commit %{commitLink}'), { commitLink }, false);
},
+ isDraft() {
+ return this.note.isDraft;
+ },
+ canResolve() {
+ return (
+ this.note.current_user.can_resolve ||
+ (this.note.isDraft && this.note.discussion_id !== null)
+ );
+ },
+ lineRange() {
+ return this.note.position?.line_range;
+ },
+ startLineNumber() {
+ return getStartLineNumber(this.lineRange);
+ },
+ endLineNumber() {
+ return getEndLineNumber(this.lineRange);
+ },
+ showMultiLineComment() {
+ return (
+ this.glFeatures.multilineComments &&
+ this.startLineNumber &&
+ this.endLineNumber &&
+ (this.startLineNumber !== this.endLineNumber || this.isEditing)
+ );
+ },
+ commentLineOptions() {
+ if (this.diffLines) {
+ return commentLineOptions(this.diffLines, this.line.line_code);
+ }
+
+ const diffFile = this.diffFile || this.getDiffFileByHash(this.targetNoteHash);
+ if (!diffFile) return null;
+ return commentLineOptions(diffFile.highlighted_diff_lines, this.line.line_code);
+ },
},
created() {
@@ -129,6 +184,7 @@ export default {
'updateNote',
'toggleResolveNote',
'scrollToNoteIfNeeded',
+ 'updateAssignees',
]),
editHandler() {
this.isEditing = true;
@@ -166,10 +222,20 @@ export default {
this.$emit('updateSuccess');
},
formUpdateHandler(noteText, parentElement, callback, resolveDiscussion) {
+ const position = {
+ ...this.note.position,
+ line_range: {
+ start_line_code: this.commentLineStart?.lineCode,
+ start_line_type: this.commentLineStart?.type,
+ end_line_code: this.line?.line_code,
+ end_line_type: this.line?.type,
+ },
+ };
this.$emit('handleUpdateNote', {
note: this.note,
noteText,
resolveDiscussion,
+ position,
callback: () => this.updateSuccess(),
});
@@ -231,6 +297,12 @@ export default {
noteBody.note.note = noteText;
}
},
+ getLineClasses(lineNumber) {
+ return getLineClasses(lineNumber);
+ },
+ assigneesUpdate(assignees) {
+ this.updateAssignees(assignees);
+ },
},
};
</script>
@@ -243,6 +315,26 @@ export default {
:data-note-id="note.id"
class="note note-wrapper qa-noteable-note-item"
>
+ <div v-if="showMultiLineComment" data-testid="multiline-comment">
+ <multiline-comment-form
+ v-if="isEditing && commentLineOptions && line"
+ v-model="commentLineStart"
+ :line="line"
+ :comment-line-options="commentLineOptions"
+ :line-range="note.position.line_range"
+ class="gl-mb-3 gl-text-gray-700 gl-border-gray-200 gl-border-b-solid gl-border-b-1 gl-pb-3"
+ />
+ <div v-else class="gl-mb-3 gl-text-gray-700">
+ <gl-sprintf :message="__('Comment on lines %{startLine} to %{endLine}')">
+ <template #startLine>
+ <span :class="getLineClasses(startLineNumber)">{{ startLineNumber }}</span>
+ </template>
+ <template #endLine>
+ <span :class="getLineClasses(endLineNumber)">{{ endLineNumber }}</span>
+ </template>
+ </gl-sprintf>
+ </div>
+ </div>
<div v-once class="timeline-icon">
<user-avatar-link
:link-href="author.path"
@@ -267,6 +359,7 @@ export default {
<span v-else-if="note.created_at" class="d-none d-sm-inline">&middot;</span>
</note-header>
<note-actions
+ :author="author"
:author-id="author.id"
:note-id="note.id"
:note-url="note.noteable_note_url"
@@ -289,6 +382,7 @@ export default {
@handleDelete="deleteHandler"
@handleResolve="resolveHandler"
@startReplying="$emit('startReplying')"
+ @updateAssignees="assigneesUpdate"
/>
</div>
<div class="timeline-discussion-body">
diff --git a/app/assets/javascripts/notes/mixins/description_version_history.js b/app/assets/javascripts/notes/mixins/description_version_history.js
index 66e6685cfd8..d1006e37a70 100644
--- a/app/assets/javascripts/notes/mixins/description_version_history.js
+++ b/app/assets/javascripts/notes/mixins/description_version_history.js
@@ -3,7 +3,7 @@
export default {
computed: {
canSeeDescriptionVersion() {},
- canDeleteDescriptionVersion() {},
+ displayDeleteButton() {},
shouldShowDescriptionVersion() {},
descriptionVersionToggleIcon() {},
},
diff --git a/app/assets/javascripts/notes/mixins/diff_line_note_form.js b/app/assets/javascripts/notes/mixins/diff_line_note_form.js
index 188556e8921..5930b5f3321 100644
--- a/app/assets/javascripts/notes/mixins/diff_line_note_form.js
+++ b/app/assets/javascripts/notes/mixins/diff_line_note_form.js
@@ -1,10 +1,100 @@
+import { mapActions, mapGetters, mapState } from 'vuex';
+import { getDraftReplyFormData, getDraftFormData } from '~/batch_comments/utils';
+import { TEXT_DIFF_POSITION_TYPE, IMAGE_DIFF_POSITION_TYPE } from '~/diffs/constants';
+import createFlash from '~/flash';
+import { s__ } from '~/locale';
+import { clearDraft } from '~/lib/utils/autosave';
+
export default {
computed: {
- draftForDiscussion: () => () => ({}),
+ ...mapState({
+ noteableData: state => state.notes.noteableData,
+ notesData: state => state.notes.notesData,
+ withBatchComments: state => state.batchComments?.withBatchComments,
+ }),
+ ...mapGetters('diffs', ['getDiffFileByHash']),
+ ...mapGetters('batchComments', ['shouldRenderDraftRowInDiscussion', 'draftForDiscussion']),
+ ...mapState('diffs', ['commit']),
},
methods: {
- showDraft: () => false,
- addReplyToReview: () => {},
- addToReview: () => {},
+ ...mapActions('diffs', ['cancelCommentForm']),
+ ...mapActions('batchComments', ['addDraftToReview', 'saveDraft', 'insertDraftIntoDrafts']),
+ addReplyToReview(noteText, isResolving) {
+ const postData = getDraftReplyFormData({
+ in_reply_to_discussion_id: this.discussion.reply_id,
+ target_type: this.getNoteableData.targetType,
+ notesData: this.notesData,
+ draft_note: {
+ note: noteText,
+ resolve_discussion: isResolving,
+ },
+ });
+
+ if (this.discussion.for_commit) {
+ postData.note_project_id = this.discussion.project_id;
+ }
+
+ this.isReplying = false;
+
+ this.saveDraft(postData)
+ .then(() => {
+ this.handleClearForm(this.discussion.line_code);
+ })
+ .catch(() => {
+ createFlash(s__('MergeRequests|An error occurred while saving the draft comment.'));
+ });
+ },
+ addToReview(note) {
+ const positionType = this.diffFileCommentForm
+ ? IMAGE_DIFF_POSITION_TYPE
+ : TEXT_DIFF_POSITION_TYPE;
+ const selectedDiffFile = this.getDiffFileByHash(this.diffFileHash);
+ const postData = getDraftFormData({
+ note,
+ notesData: this.notesData,
+ noteableData: this.noteableData,
+ noteableType: this.noteableType,
+ noteTargetLine: this.noteTargetLine,
+ diffViewType: this.diffViewType,
+ diffFile: selectedDiffFile,
+ linePosition: this.position,
+ positionType,
+ ...this.diffFileCommentForm,
+ });
+
+ const diffFileHeadSha = this.commit && this?.diffFile?.diff_refs?.head_sha;
+
+ postData.data.note.commit_id = diffFileHeadSha || null;
+
+ return this.saveDraft(postData)
+ .then(() => {
+ if (positionType === IMAGE_DIFF_POSITION_TYPE) {
+ this.closeDiffFileCommentForm(this.diffFileHash);
+ } else {
+ this.handleClearForm(this.line.line_code);
+ }
+ })
+ .catch(() => {
+ createFlash(s__('MergeRequests|An error occurred while saving the draft comment.'));
+ });
+ },
+ handleClearForm(lineCode) {
+ this.cancelCommentForm({
+ lineCode,
+ fileHash: this.diffFileHash,
+ });
+ this.$nextTick(() => {
+ if (this.autosaveKey) {
+ clearDraft(this.autosaveKey);
+ } else {
+ // TODO: remove the following after replacing the autosave mixin
+ // https://gitlab.com/gitlab-org/gitlab-foss/issues/60587
+ this.resetAutoSave();
+ }
+ });
+ },
+ showDraft(replyId) {
+ return this.withBatchComments && this.shouldRenderDraftRowInDiscussion(replyId);
+ },
},
};
diff --git a/app/assets/javascripts/notes/mixins/discussion_navigation.js b/app/assets/javascripts/notes/mixins/discussion_navigation.js
index c9026352d18..9281149d9d3 100644
--- a/app/assets/javascripts/notes/mixins/discussion_navigation.js
+++ b/app/assets/javascripts/notes/mixins/discussion_navigation.js
@@ -1,5 +1,5 @@
import { mapGetters, mapActions, mapState } from 'vuex';
-import { scrollToElement } from '~/lib/utils/common_utils';
+import { scrollToElementWithContext } from '~/lib/utils/common_utils';
import eventHub from '../event_hub';
/**
@@ -10,7 +10,7 @@ function scrollTo(selector) {
const el = document.querySelector(selector);
if (el) {
- scrollToElement(el);
+ scrollToElementWithContext(el);
return true;
}
diff --git a/app/assets/javascripts/notes/mixins/draft.js b/app/assets/javascripts/notes/mixins/draft.js
deleted file mode 100644
index 1370f3978df..00000000000
--- a/app/assets/javascripts/notes/mixins/draft.js
+++ /dev/null
@@ -1,8 +0,0 @@
-export default {
- computed: {
- isDraft: () => false,
- canResolve() {
- return this.note.current_user.can_resolve;
- },
- },
-};
diff --git a/app/assets/javascripts/notes/mixins/get_discussion.js b/app/assets/javascripts/notes/mixins/get_discussion.js
deleted file mode 100644
index b5d820fe083..00000000000
--- a/app/assets/javascripts/notes/mixins/get_discussion.js
+++ /dev/null
@@ -1,7 +0,0 @@
-export default {
- computed: {
- discussion() {
- return {};
- },
- },
-};
diff --git a/app/assets/javascripts/notes/mixins/note_form.js b/app/assets/javascripts/notes/mixins/note_form.js
deleted file mode 100644
index b74879f2256..00000000000
--- a/app/assets/javascripts/notes/mixins/note_form.js
+++ /dev/null
@@ -1,24 +0,0 @@
-export default {
- data() {
- return {
- showBatchCommentsActions: false,
- };
- },
- methods: {
- handleKeySubmit() {
- this.handleUpdate();
- },
- handleUpdate(shouldResolve) {
- const beforeSubmitDiscussionState = this.discussionResolved;
- this.isSubmitting = true;
-
- this.$emit('handleFormUpdate', this.updatedNoteBody, this.$refs.editNoteForm, () => {
- this.isSubmitting = false;
-
- if (this.shouldToggleResolved(shouldResolve, beforeSubmitDiscussionState)) {
- this.resolveHandler(beforeSubmitDiscussionState);
- }
- });
- },
- },
-};
diff --git a/app/assets/javascripts/notes/stores/actions.js b/app/assets/javascripts/notes/stores/actions.js
index 0999d0aa7ac..a5b006fc301 100644
--- a/app/assets/javascripts/notes/stores/actions.js
+++ b/app/assets/javascripts/notes/stores/actions.js
@@ -524,12 +524,55 @@ export const submitSuggestion = (
const defaultMessage = __(
'Something went wrong while applying the suggestion. Please try again.',
);
- const flashMessage = err.response.data ? `${err.response.data.message}.` : defaultMessage;
+
+ const errorMessage = err.response.data?.message;
+
+ const flashMessage = errorMessage || defaultMessage;
Flash(__(flashMessage), 'alert', flashContainer);
});
};
+export const submitSuggestionBatch = ({ commit, dispatch, state }, { flashContainer }) => {
+ const suggestionIds = state.batchSuggestionsInfo.map(({ suggestionId }) => suggestionId);
+
+ const applyAllSuggestions = () =>
+ state.batchSuggestionsInfo.map(suggestionInfo =>
+ commit(types.APPLY_SUGGESTION, suggestionInfo),
+ );
+
+ const resolveAllDiscussions = () =>
+ state.batchSuggestionsInfo.map(suggestionInfo => {
+ const { discussionId } = suggestionInfo;
+ return dispatch('resolveDiscussion', { discussionId }).catch(() => {});
+ });
+
+ commit(types.SET_APPLYING_BATCH_STATE, true);
+
+ return Api.applySuggestionBatch(suggestionIds)
+ .then(() => Promise.all(applyAllSuggestions()))
+ .then(() => Promise.all(resolveAllDiscussions()))
+ .then(() => commit(types.CLEAR_SUGGESTION_BATCH))
+ .catch(err => {
+ const defaultMessage = __(
+ 'Something went wrong while applying the batch of suggestions. Please try again.',
+ );
+
+ const errorMessage = err.response.data?.message;
+
+ const flashMessage = errorMessage || defaultMessage;
+
+ Flash(__(flashMessage), 'alert', flashContainer);
+ })
+ .finally(() => commit(types.SET_APPLYING_BATCH_STATE, false));
+};
+
+export const addSuggestionInfoToBatch = ({ commit }, { suggestionId, noteId, discussionId }) =>
+ commit(types.ADD_SUGGESTION_TO_BATCH, { suggestionId, noteId, discussionId });
+
+export const removeSuggestionInfoFromBatch = ({ commit }, suggestionId) =>
+ commit(types.REMOVE_SUGGESTION_FROM_BATCH, suggestionId);
+
export const convertToDiscussion = ({ commit }, noteId) =>
commit(types.CONVERT_TO_DISCUSSION, noteId);
@@ -587,6 +630,10 @@ export const softDeleteDescriptionVersion = (
.catch(error => {
dispatch('receiveDeleteDescriptionVersionError', error);
Flash(__('Something went wrong while deleting description changes. Please try again.'));
+
+ // Throw an error here because a component like SystemNote -
+ // needs to know if the request failed to reset its internal state.
+ throw new Error();
});
};
@@ -600,5 +647,9 @@ export const receiveDeleteDescriptionVersionError = ({ commit }, error) => {
commit(types.RECEIVE_DELETE_DESCRIPTION_VERSION_ERROR, error);
};
+export const updateAssignees = ({ commit }, assignees) => {
+ commit(types.UPDATE_ASSIGNEES, assignees);
+};
+
// prevent babel-plugin-rewire from generating an invalid default during karma tests
export default () => {};
diff --git a/app/assets/javascripts/notes/stores/modules/index.js b/app/assets/javascripts/notes/stores/modules/index.js
index 25f0f546103..329bf5e147e 100644
--- a/app/assets/javascripts/notes/stores/modules/index.js
+++ b/app/assets/javascripts/notes/stores/modules/index.js
@@ -11,6 +11,7 @@ export default () => ({
targetNoteHash: null,
lastFetchedAt: null,
currentDiscussionId: null,
+ batchSuggestionsInfo: [],
// View layer
isToggleStateButtonLoading: false,
diff --git a/app/assets/javascripts/notes/stores/mutation_types.js b/app/assets/javascripts/notes/stores/mutation_types.js
index 2f7b2788d8a..538774ee467 100644
--- a/app/assets/javascripts/notes/stores/mutation_types.js
+++ b/app/assets/javascripts/notes/stores/mutation_types.js
@@ -17,8 +17,13 @@ export const SET_NOTES_FETCHED_STATE = 'SET_NOTES_FETCHED_STATE';
export const SET_NOTES_LOADING_STATE = 'SET_NOTES_LOADING_STATE';
export const DISABLE_COMMENTS = 'DISABLE_COMMENTS';
export const APPLY_SUGGESTION = 'APPLY_SUGGESTION';
+export const SET_APPLYING_BATCH_STATE = 'SET_APPLYING_BATCH_STATE';
+export const ADD_SUGGESTION_TO_BATCH = 'ADD_SUGGESTION_TO_BATCH';
+export const REMOVE_SUGGESTION_FROM_BATCH = 'REMOVE_SUGGESTION_FROM_BATCH';
+export const CLEAR_SUGGESTION_BATCH = 'CLEAR_SUGGESTION_BATCH';
export const CONVERT_TO_DISCUSSION = 'CONVERT_TO_DISCUSSION';
export const REMOVE_CONVERTED_DISCUSSION = 'REMOVE_CONVERTED_DISCUSSION';
+export const UPDATE_ASSIGNEES = 'UPDATE_ASSIGNEES';
// DISCUSSION
export const COLLAPSE_DISCUSSION = 'COLLAPSE_DISCUSSION';
diff --git a/app/assets/javascripts/notes/stores/mutations.js b/app/assets/javascripts/notes/stores/mutations.js
index f06874991f0..2aeadcb2da1 100644
--- a/app/assets/javascripts/notes/stores/mutations.js
+++ b/app/assets/javascripts/notes/stores/mutations.js
@@ -225,6 +225,39 @@ export default {
}));
},
+ [types.SET_APPLYING_BATCH_STATE](state, isApplyingBatch) {
+ state.batchSuggestionsInfo.forEach(suggestionInfo => {
+ const { discussionId, noteId, suggestionId } = suggestionInfo;
+
+ const noteObj = utils.findNoteObjectById(state.discussions, discussionId);
+ const comment = utils.findNoteObjectById(noteObj.notes, noteId);
+
+ comment.suggestions = comment.suggestions.map(suggestion => ({
+ ...suggestion,
+ is_applying_batch: suggestion.id === suggestionId && isApplyingBatch,
+ }));
+ });
+ },
+
+ [types.ADD_SUGGESTION_TO_BATCH](state, { noteId, discussionId, suggestionId }) {
+ state.batchSuggestionsInfo.push({
+ suggestionId,
+ noteId,
+ discussionId,
+ });
+ },
+
+ [types.REMOVE_SUGGESTION_FROM_BATCH](state, id) {
+ const index = state.batchSuggestionsInfo.findIndex(({ suggestionId }) => suggestionId === id);
+ if (index !== -1) {
+ state.batchSuggestionsInfo.splice(index, 1);
+ }
+ },
+
+ [types.CLEAR_SUGGESTION_BATCH](state) {
+ state.batchSuggestionsInfo.splice(0, state.batchSuggestionsInfo.length);
+ },
+
[types.UPDATE_DISCUSSION](state, noteData) {
const note = noteData;
const selectedDiscussion = state.discussions.find(disc => disc.id === note.id);
@@ -322,4 +355,7 @@ export default {
[types.RECEIVE_DELETE_DESCRIPTION_VERSION_ERROR](state) {
state.isLoadingDescriptionVersion = false;
},
+ [types.UPDATE_ASSIGNEES](state, assignees) {
+ state.noteableData.assignees = assignees;
+ },
};
diff --git a/app/assets/javascripts/onboarding_issues/index.js b/app/assets/javascripts/onboarding_issues/index.js
new file mode 100644
index 00000000000..5a6f952ffdf
--- /dev/null
+++ b/app/assets/javascripts/onboarding_issues/index.js
@@ -0,0 +1,120 @@
+import $ from 'jquery';
+import { parseBoolean, getCookie, setCookie, removeCookie } from '~/lib/utils/common_utils';
+import { __ } from '~/locale';
+import Tracking from '~/tracking';
+
+const COOKIE_NAME = 'onboarding_issues_settings';
+
+const POPOVER_LOCATIONS = {
+ GROUPS_SHOW: 'groups#show',
+ PROJECTS_SHOW: 'projects#show',
+ ISSUES_INDEX: 'issues#index',
+};
+
+const removeLearnGitLabCookie = () => {
+ removeCookie(COOKIE_NAME);
+};
+
+function disposePopover(event) {
+ event.preventDefault();
+ this.popover('dispose');
+ removeLearnGitLabCookie();
+ Tracking.event('Growth::Conversion::Experiment::OnboardingIssues', 'dismiss_popover');
+}
+
+const showPopover = (el, path, footer, options) => {
+ // Cookie value looks like `{ 'groups#show': true, 'projects#show': true, 'issues#index': true }`. When it doesn't exist, don't show the popover.
+ const cookie = getCookie(COOKIE_NAME);
+ if (!cookie) return;
+
+ // When the popover action has already been taken, don't show the popover.
+ const settings = JSON.parse(cookie);
+ if (!parseBoolean(settings[path])) return;
+
+ const defaultOptions = {
+ boundary: 'window',
+ html: true,
+ placement: 'top',
+ template: `<div class="popover blue learn-gitlab d-none d-xl-block" role="tooltip">
+ <div class="arrow"></div>
+ <div class="close cursor-pointer gl-font-base text-white gl-opacity-10 p-2">&#10005</div>
+ <div class="popover-body gl-font-base gl-line-height-20 pb-0 px-3"></div>
+ <div class="bold text-right text-white p-2">${footer}</div>
+ </div>`,
+ };
+
+ // When one of the popovers is dismissed, remove the cookie.
+ const closeButton = () => document.querySelector('.learn-gitlab.popover .close');
+
+ // We still have to use jQuery, since Bootstrap's Popover is based on jQuery.
+ const jQueryEl = $(el);
+ const clickCloseButton = disposePopover.bind(jQueryEl);
+
+ jQueryEl
+ .popover({ ...defaultOptions, ...options })
+ .on('inserted.bs.popover', () => closeButton().addEventListener('click', clickCloseButton))
+ .on('hide.bs.dropdown', () => closeButton().removeEventListener('click', clickCloseButton))
+ .popover('show');
+
+ // The previous popover actions have been taken, don't show those popovers anymore.
+ Object.keys(settings).forEach(pathSetting => {
+ if (path !== pathSetting) {
+ settings[pathSetting] = false;
+ } else {
+ setCookie(COOKIE_NAME, settings);
+ }
+ });
+
+ // The final popover action will be taken on click, we then no longer need the cookie.
+ if (path === POPOVER_LOCATIONS.ISSUES_INDEX) {
+ el.addEventListener('click', removeLearnGitLabCookie);
+ }
+};
+
+export const showLearnGitLabGroupItemPopover = id => {
+ const el = document.querySelector(`#group-${id} .group-text a`);
+
+ if (!el) return;
+
+ const options = {
+ content: __(
+ 'Here are all your projects in your group, including the one you just created. To start, let’s take a look at your personalized learning project which will help you learn about GitLab at your own pace.',
+ ),
+ };
+
+ showPopover(el, POPOVER_LOCATIONS.GROUPS_SHOW, '1 / 2', options);
+};
+
+export const showLearnGitLabProjectPopover = () => {
+ // Do not show a popover if we are not viewing the 'Learn GitLab' project.
+ if (!window.location.pathname.includes('learn-gitlab')) return;
+
+ const el = document.querySelector('a.shortcuts-issues');
+
+ if (!el) return;
+
+ const options = {
+ content: __(
+ 'Go to <strong>Issues</strong> > <strong>Boards</strong> to access your personalized learning issue board.',
+ ),
+ };
+
+ showPopover(el, POPOVER_LOCATIONS.PROJECTS_SHOW, '2 / 2', options);
+};
+
+export const showLearnGitLabIssuesPopover = () => {
+ // Do not show a popover if we are not viewing the 'Learn GitLab' project.
+ if (!window.location.pathname.includes('learn-gitlab')) return;
+
+ const el = document.querySelector('a[data-qa-selector="issue_boards_link"]');
+
+ if (!el) return;
+
+ const options = {
+ content: __(
+ 'Go to <strong>Issues</strong> > <strong>Boards</strong> to access your personalized learning issue board.',
+ ),
+ };
+
+ showPopover(el, POPOVER_LOCATIONS.ISSUES_INDEX, '2 / 2', options);
+};
diff --git a/app/assets/javascripts/operation_settings/components/external_dashboard.vue b/app/assets/javascripts/operation_settings/components/external_dashboard.vue
deleted file mode 100644
index e9c7d7c5d56..00000000000
--- a/app/assets/javascripts/operation_settings/components/external_dashboard.vue
+++ /dev/null
@@ -1,72 +0,0 @@
-<script>
-import { mapState, mapActions } from 'vuex';
-import { GlDeprecatedButton, GlFormGroup, GlFormInput, GlLink } from '@gitlab/ui';
-
-export default {
- components: {
- GlDeprecatedButton,
- GlFormGroup,
- GlFormInput,
- GlLink,
- },
- computed: {
- ...mapState([
- 'externalDashboardHelpPagePath',
- 'externalDashboardUrl',
- 'operationsSettingsEndpoint',
- ]),
- userDashboardUrl: {
- get() {
- return this.externalDashboardUrl;
- },
- set(url) {
- this.setExternalDashboardUrl(url);
- },
- },
- },
- methods: {
- ...mapActions(['setExternalDashboardUrl', 'updateExternalDashboardUrl']),
- },
-};
-</script>
-
-<template>
- <section class="settings no-animate">
- <div class="settings-header">
- <h3 class="js-section-header h4">
- {{ s__('ExternalMetrics|External Dashboard') }}
- </h3>
- <gl-deprecated-button class="js-settings-toggle">{{ __('Expand') }}</gl-deprecated-button>
- <p class="js-section-sub-header">
- {{
- s__(
- 'ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards.',
- )
- }}
- <gl-link :href="externalDashboardHelpPagePath">{{ __('Learn more') }}</gl-link>
- </p>
- </div>
- <div class="settings-content">
- <form>
- <gl-form-group
- :label="s__('ExternalMetrics|Full dashboard URL')"
- label-for="full-dashboard-url"
- :description="s__('ExternalMetrics|Enter the URL of the dashboard you want to link to')"
- >
- <!-- placeholder with a url is a false positive -->
- <!-- eslint-disable @gitlab/vue-require-i18n-attribute-strings -->
- <gl-form-input
- id="full-dashboard-url"
- v-model="userDashboardUrl"
- placeholder="https://my-org.gitlab.io/my-dashboards"
- @keydown.enter.native.prevent="updateExternalDashboardUrl"
- />
- <!-- eslint-enable @gitlab/vue-require-i18n-attribute-strings -->
- </gl-form-group>
- <gl-deprecated-button variant="success" @click="updateExternalDashboardUrl">
- {{ __('Save Changes') }}
- </gl-deprecated-button>
- </form>
- </div>
- </section>
-</template>
diff --git a/app/assets/javascripts/operation_settings/components/form_group/dashboard_timezone.vue b/app/assets/javascripts/operation_settings/components/form_group/dashboard_timezone.vue
new file mode 100644
index 00000000000..42c9d876595
--- /dev/null
+++ b/app/assets/javascripts/operation_settings/components/form_group/dashboard_timezone.vue
@@ -0,0 +1,60 @@
+<script>
+import { s__ } from '~/locale';
+import { mapState, mapActions } from 'vuex';
+import { GlFormGroup, GlFormSelect } from '@gitlab/ui';
+import { timezones } from '~/monitoring/format_date';
+
+export default {
+ components: {
+ GlFormGroup,
+ GlFormSelect,
+ },
+ computed: {
+ ...mapState(['dashboardTimezone']),
+ dashboardTimezoneModel: {
+ get() {
+ return this.dashboardTimezone.selected;
+ },
+ set(selected) {
+ this.setDashboardTimezone(selected);
+ },
+ },
+ options() {
+ return [
+ {
+ value: timezones.LOCAL,
+ text: s__("MetricsSettings|User's local timezone"),
+ },
+ {
+ value: timezones.UTC,
+ text: s__('MetricsSettings|UTC (Coordinated Universal Time)'),
+ },
+ ];
+ },
+ },
+ methods: {
+ ...mapActions(['setDashboardTimezone']),
+ },
+};
+</script>
+
+<template>
+ <gl-form-group
+ :label="s__('MetricsSettings|Dashboard timezone')"
+ label-for="dashboard-timezone-setting"
+ >
+ <template #description>
+ {{
+ s__(
+ "MetricsSettings|Choose whether to display dashboard metrics in UTC or the user's local timezone.",
+ )
+ }}
+ </template>
+
+ <gl-form-select
+ id="dashboard-timezone-setting"
+ v-model="dashboardTimezoneModel"
+ :options="options"
+ />
+ </gl-form-group>
+</template>
diff --git a/app/assets/javascripts/operation_settings/components/form_group/external_dashboard.vue b/app/assets/javascripts/operation_settings/components/form_group/external_dashboard.vue
new file mode 100644
index 00000000000..812c5a3fe9a
--- /dev/null
+++ b/app/assets/javascripts/operation_settings/components/form_group/external_dashboard.vue
@@ -0,0 +1,48 @@
+<script>
+import { mapState, mapActions } from 'vuex';
+import { GlFormGroup, GlFormInput } from '@gitlab/ui';
+
+export default {
+ components: {
+ GlFormGroup,
+ GlFormInput,
+ },
+ computed: {
+ ...mapState(['externalDashboard']),
+ userDashboardUrl: {
+ get() {
+ return this.externalDashboard.url;
+ },
+ set(url) {
+ this.setExternalDashboardUrl(url);
+ },
+ },
+ },
+ methods: {
+ ...mapActions(['setExternalDashboardUrl']),
+ },
+};
+</script>
+
+<template>
+ <gl-form-group
+ :label="s__('MetricsSettings|External dashboard URL')"
+ label-for="external-dashboard-url"
+ >
+ <template #description>
+ {{
+ s__(
+ 'MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard.',
+ )
+ }}
+ </template>
+ <!-- placeholder with a url is a false positive -->
+ <!-- eslint-disable @gitlab/vue-require-i18n-attribute-strings -->
+ <gl-form-input
+ id="external-dashboard-url"
+ v-model="userDashboardUrl"
+ placeholder="https://my-org.gitlab.io/my-dashboards"
+ />
+ <!-- eslint-enable @gitlab/vue-require-i18n-attribute-strings -->
+ </gl-form-group>
+</template>
diff --git a/app/assets/javascripts/operation_settings/components/metrics_settings.vue b/app/assets/javascripts/operation_settings/components/metrics_settings.vue
new file mode 100644
index 00000000000..77c356e5a7f
--- /dev/null
+++ b/app/assets/javascripts/operation_settings/components/metrics_settings.vue
@@ -0,0 +1,53 @@
+<script>
+import { mapState, mapActions } from 'vuex';
+import { GlDeprecatedButton, GlLink } from '@gitlab/ui';
+import ExternalDashboard from './form_group/external_dashboard.vue';
+import DashboardTimezone from './form_group/dashboard_timezone.vue';
+
+export default {
+ components: {
+ GlDeprecatedButton,
+ GlLink,
+ ExternalDashboard,
+ DashboardTimezone,
+ },
+ computed: {
+ ...mapState(['helpPage']),
+ userDashboardUrl: {
+ get() {
+ return this.externalDashboard.url;
+ },
+ set(url) {
+ this.setExternalDashboardUrl(url);
+ },
+ },
+ },
+ methods: {
+ ...mapActions(['saveChanges']),
+ },
+};
+</script>
+
+<template>
+ <section class="settings no-animate">
+ <div class="settings-header">
+ <h3 class="js-section-header h4">
+ {{ s__('MetricsSettings|Metrics Dashboard') }}
+ </h3>
+ <gl-deprecated-button class="js-settings-toggle">{{ __('Expand') }}</gl-deprecated-button>
+ <p class="js-section-sub-header">
+ {{ s__('MetricsSettings|Manage Metrics Dashboard settings.') }}
+ <gl-link :href="helpPage">{{ __('Learn more') }}</gl-link>
+ </p>
+ </div>
+ <div class="settings-content">
+ <form>
+ <dashboard-timezone />
+ <external-dashboard />
+ <gl-deprecated-button variant="success" @click="saveChanges">
+ {{ __('Save Changes') }}
+ </gl-deprecated-button>
+ </form>
+ </div>
+ </section>
+</template>
diff --git a/app/assets/javascripts/operation_settings/index.js b/app/assets/javascripts/operation_settings/index.js
index f075291ce98..426a060949e 100644
--- a/app/assets/javascripts/operation_settings/index.js
+++ b/app/assets/javascripts/operation_settings/index.js
@@ -1,6 +1,6 @@
import Vue from 'vue';
import store from './store';
-import ExternalDashboardForm from './components/external_dashboard.vue';
+import MetricsSettingsForm from './components/metrics_settings.vue';
export default () => {
const el = document.querySelector('.js-operation-settings');
@@ -9,7 +9,7 @@ export default () => {
el,
store: store(el.dataset),
render(createElement) {
- return createElement(ExternalDashboardForm);
+ return createElement(MetricsSettingsForm);
},
});
};
diff --git a/app/assets/javascripts/operation_settings/store/actions.js b/app/assets/javascripts/operation_settings/store/actions.js
index ec05b0c76cf..122acb6bdcf 100644
--- a/app/assets/javascripts/operation_settings/store/actions.js
+++ b/app/assets/javascripts/operation_settings/store/actions.js
@@ -7,19 +7,23 @@ import * as mutationTypes from './mutation_types';
export const setExternalDashboardUrl = ({ commit }, url) =>
commit(mutationTypes.SET_EXTERNAL_DASHBOARD_URL, url);
-export const updateExternalDashboardUrl = ({ state, dispatch }) =>
+export const setDashboardTimezone = ({ commit }, selected) =>
+ commit(mutationTypes.SET_DASHBOARD_TIMEZONE, selected);
+
+export const saveChanges = ({ state, dispatch }) =>
axios
.patch(state.operationsSettingsEndpoint, {
project: {
metrics_setting_attributes: {
- external_dashboard_url: state.externalDashboardUrl,
+ dashboard_timezone: state.dashboardTimezone.selected,
+ external_dashboard_url: state.externalDashboard.url,
},
},
})
- .then(() => dispatch('receiveExternalDashboardUpdateSuccess'))
- .catch(error => dispatch('receiveExternalDashboardUpdateError', error));
+ .then(() => dispatch('receiveSaveChangesSuccess'))
+ .catch(error => dispatch('receiveSaveChangesError', error));
-export const receiveExternalDashboardUpdateSuccess = () => {
+export const receiveSaveChangesSuccess = () => {
/**
* The operations_controller currently handles successful requests
* by creating a flash banner messsage to notify the user.
@@ -27,8 +31,8 @@ export const receiveExternalDashboardUpdateSuccess = () => {
refreshCurrentPage();
};
-export const receiveExternalDashboardUpdateError = (_, error) => {
- const { response } = error;
+export const receiveSaveChangesError = (_, error) => {
+ const { response = {} } = error;
const message = response.data && response.data.message ? response.data.message : '';
createFlash(`${__('There was an error saving your changes.')} ${message}`, 'alert');
diff --git a/app/assets/javascripts/operation_settings/store/mutation_types.js b/app/assets/javascripts/operation_settings/store/mutation_types.js
index 237d2b6122f..92543fd7f03 100644
--- a/app/assets/javascripts/operation_settings/store/mutation_types.js
+++ b/app/assets/javascripts/operation_settings/store/mutation_types.js
@@ -1,3 +1,2 @@
-/* eslint-disable import/prefer-default-export */
-
export const SET_EXTERNAL_DASHBOARD_URL = 'SET_EXTERNAL_DASHBOARD_URL';
+export const SET_DASHBOARD_TIMEZONE = 'SET_DASHBOARD_TIMEZONE';
diff --git a/app/assets/javascripts/operation_settings/store/mutations.js b/app/assets/javascripts/operation_settings/store/mutations.js
index 64bb33bb89f..f55717f6c98 100644
--- a/app/assets/javascripts/operation_settings/store/mutations.js
+++ b/app/assets/javascripts/operation_settings/store/mutations.js
@@ -2,6 +2,9 @@ import * as types from './mutation_types';
export default {
[types.SET_EXTERNAL_DASHBOARD_URL](state, url) {
- state.externalDashboardUrl = url;
+ state.externalDashboard.url = url;
+ },
+ [types.SET_DASHBOARD_TIMEZONE](state, selected) {
+ state.dashboardTimezone.selected = selected;
},
};
diff --git a/app/assets/javascripts/operation_settings/store/state.js b/app/assets/javascripts/operation_settings/store/state.js
index 72167141c48..c0eca580848 100644
--- a/app/assets/javascripts/operation_settings/store/state.js
+++ b/app/assets/javascripts/operation_settings/store/state.js
@@ -1,5 +1,10 @@
export default (initialState = {}) => ({
- externalDashboardUrl: initialState.externalDashboardUrl || '',
operationsSettingsEndpoint: initialState.operationsSettingsEndpoint,
- externalDashboardHelpPagePath: initialState.externalDashboardHelpPagePath,
+ helpPage: initialState.helpPage,
+ externalDashboard: {
+ url: initialState.externalDashboardUrl,
+ },
+ dashboardTimezone: {
+ selected: initialState.dashboardTimezoneSetting,
+ },
});
diff --git a/app/assets/javascripts/pager.js b/app/assets/javascripts/pager.js
index 46e80ba72e3..2aa37842707 100644
--- a/app/assets/javascripts/pager.js
+++ b/app/assets/javascripts/pager.js
@@ -1,7 +1,8 @@
import $ from 'jquery';
+import 'vendor/jquery.endless-scroll';
import { getParameterByName } from '~/lib/utils/common_utils';
-import axios from './lib/utils/axios_utils';
-import { removeParams } from './lib/utils/url_utility';
+import axios from '~/lib/utils/axios_utils';
+import { removeParams } from '~/lib/utils/url_utility';
const ENDLESS_SCROLL_BOTTOM_PX = 400;
const ENDLESS_SCROLL_FIRE_DELAY_MS = 1000;
diff --git a/app/assets/javascripts/pages/admin/application_settings/index.js b/app/assets/javascripts/pages/admin/application_settings/index.js
index 493c216cc6e..143d15f92cd 100644
--- a/app/assets/javascripts/pages/admin/application_settings/index.js
+++ b/app/assets/javascripts/pages/admin/application_settings/index.js
@@ -2,8 +2,12 @@ import initSettingsPanels from '~/settings_panels';
import projectSelect from '~/project_select';
import selfMonitor from '~/self_monitor';
import maintenanceModeSettings from '~/maintenance_mode_settings';
+import initVariableList from '~/ci_variable_list';
document.addEventListener('DOMContentLoaded', () => {
+ if (gon.features?.ciInstanceVariablesUi) {
+ initVariableList('js-instance-variables');
+ }
selfMonitor();
maintenanceModeSettings();
// Initialize expandable settings panels
diff --git a/app/assets/javascripts/pages/admin/groups/edit/index.js b/app/assets/javascripts/pages/admin/groups/edit/index.js
index ad7276132b9..a4e5df559ff 100644
--- a/app/assets/javascripts/pages/admin/groups/edit/index.js
+++ b/app/assets/javascripts/pages/admin/groups/edit/index.js
@@ -1,3 +1,3 @@
-import initAvatarPicker from '~/avatar_picker';
+import initFilePickers from '~/file_pickers';
-document.addEventListener('DOMContentLoaded', initAvatarPicker);
+document.addEventListener('DOMContentLoaded', initFilePickers);
diff --git a/app/assets/javascripts/pages/admin/groups/new/index.js b/app/assets/javascripts/pages/admin/groups/new/index.js
index 6de740ee9ce..b94c999ed12 100644
--- a/app/assets/javascripts/pages/admin/groups/new/index.js
+++ b/app/assets/javascripts/pages/admin/groups/new/index.js
@@ -1,9 +1,10 @@
import BindInOut from '../../../../behaviors/bind_in_out';
import Group from '../../../../group';
-import initAvatarPicker from '~/avatar_picker';
+import initFilePickers from '~/file_pickers';
document.addEventListener('DOMContentLoaded', () => {
BindInOut.initAll();
- new Group(); // eslint-disable-line no-new
- initAvatarPicker();
+ initFilePickers();
+
+ return new Group();
});
diff --git a/app/assets/javascripts/pages/admin/projects/index/components/delete_project_modal.vue b/app/assets/javascripts/pages/admin/projects/index/components/delete_project_modal.vue
index b22fbf6b833..8bb093da771 100644
--- a/app/assets/javascripts/pages/admin/projects/index/components/delete_project_modal.vue
+++ b/app/assets/javascripts/pages/admin/projects/index/components/delete_project_modal.vue
@@ -92,7 +92,7 @@ export default {
@submit="onSubmit"
@cancel="onCancel"
>
- <template slot="body" slot-scope="props">
+ <template #body="props">
<p v-html="props.text"></p>
<p v-html="confirmationTextLabel"></p>
<form ref="form" :action="deleteProjectUrl" method="post">
diff --git a/app/assets/javascripts/pages/groups/index.js b/app/assets/javascripts/pages/groups/clusters/index.js
index 4d04c37caa7..4d04c37caa7 100644
--- a/app/assets/javascripts/pages/groups/index.js
+++ b/app/assets/javascripts/pages/groups/clusters/index.js
diff --git a/app/assets/javascripts/pages/groups/edit/index.js b/app/assets/javascripts/pages/groups/edit/index.js
index f32392c9e29..33e552cd1ba 100644
--- a/app/assets/javascripts/pages/groups/edit/index.js
+++ b/app/assets/javascripts/pages/groups/edit/index.js
@@ -1,4 +1,4 @@
-import initAvatarPicker from '~/avatar_picker';
+import initFilePickers from '~/file_pickers';
import TransferDropdown from '~/groups/transfer_dropdown';
import initConfirmDangerModal from '~/confirm_danger_modal';
import initSettingsPanels from '~/settings_panels';
@@ -10,8 +10,7 @@ import groupsSelect from '~/groups_select';
import projectSelect from '~/project_select';
document.addEventListener('DOMContentLoaded', () => {
- initAvatarPicker();
- new TransferDropdown(); // eslint-disable-line no-new
+ initFilePickers();
initConfirmDangerModal();
initSettingsPanels();
dirtySubmitFactory(
@@ -24,4 +23,6 @@ document.addEventListener('DOMContentLoaded', () => {
groupsSelect();
projectSelect();
+
+ return new TransferDropdown();
});
diff --git a/app/assets/javascripts/pages/groups/new/index.js b/app/assets/javascripts/pages/groups/new/index.js
index 0710fefe70c..640e64b5d3e 100644
--- a/app/assets/javascripts/pages/groups/new/index.js
+++ b/app/assets/javascripts/pages/groups/new/index.js
@@ -1,8 +1,8 @@
import $ from 'jquery';
import BindInOut from '~/behaviors/bind_in_out';
import Group from '~/group';
-import initAvatarPicker from '~/avatar_picker';
import GroupPathValidator from './group_path_validator';
+import initFilePickers from '~/file_pickers';
document.addEventListener('DOMContentLoaded', () => {
const parentId = $('#group_parent_id');
@@ -10,6 +10,7 @@ document.addEventListener('DOMContentLoaded', () => {
new GroupPathValidator(); // eslint-disable-line no-new
}
BindInOut.initAll();
- new Group(); // eslint-disable-line no-new
- initAvatarPicker();
+ initFilePickers();
+
+ return new Group();
});
diff --git a/app/assets/javascripts/pages/groups/shared/group_details.js b/app/assets/javascripts/pages/groups/shared/group_details.js
index 37b253d7c48..85daff3f60f 100644
--- a/app/assets/javascripts/pages/groups/shared/group_details.js
+++ b/app/assets/javascripts/pages/groups/shared/group_details.js
@@ -8,6 +8,7 @@ import NotificationsForm from '~/notifications_form';
import ProjectsList from '~/projects_list';
import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import GroupTabs from './group_tabs';
+import initNamespaceStorageLimitAlert from '~/namespace_storage_limit_alert';
export default function initGroupDetails(actionName = 'show') {
const newGroupChildWrapper = document.querySelector('.js-new-project-subgroup');
@@ -27,4 +28,6 @@ export default function initGroupDetails(actionName = 'show') {
if (newGroupChildWrapper) {
new NewGroupChild(newGroupChildWrapper);
}
+
+ initNamespaceStorageLimitAlert();
}
diff --git a/app/assets/javascripts/pages/ide/index.js b/app/assets/javascripts/pages/ide/index.js
index d192df3561e..15933256e75 100644
--- a/app/assets/javascripts/pages/ide/index.js
+++ b/app/assets/javascripts/pages/ide/index.js
@@ -1,3 +1,4 @@
import { startIde } from '~/ide/index';
+import extendStore from '~/ide/stores/extend';
-startIde();
+startIde({ extendStore });
diff --git a/app/assets/javascripts/pages/import/bitbucket/status/index.js b/app/assets/javascripts/pages/import/bitbucket/status/index.js
new file mode 100644
index 00000000000..52b5adb79d1
--- /dev/null
+++ b/app/assets/javascripts/pages/import/bitbucket/status/index.js
@@ -0,0 +1,19 @@
+import Vue from 'vue';
+import { initStoreFromElement, initPropsFromElement } from '~/import_projects';
+import BitbucketStatusTable from '~/import_projects/components/bitbucket_status_table.vue';
+
+document.addEventListener('DOMContentLoaded', () => {
+ const mountElement = document.getElementById('import-projects-mount-element');
+ if (!mountElement) return undefined;
+
+ const store = initStoreFromElement(mountElement);
+ const props = initPropsFromElement(mountElement);
+
+ return new Vue({
+ el: mountElement,
+ store,
+ render(createElement) {
+ return createElement(BitbucketStatusTable, { props });
+ },
+ });
+});
diff --git a/app/assets/javascripts/pages/import/bitbucket_server/status/components/bitbucket_server_status_table.vue b/app/assets/javascripts/pages/import/bitbucket_server/status/components/bitbucket_server_status_table.vue
new file mode 100644
index 00000000000..e01c7b80e1a
--- /dev/null
+++ b/app/assets/javascripts/pages/import/bitbucket_server/status/components/bitbucket_server_status_table.vue
@@ -0,0 +1,30 @@
+<script>
+import { GlButton } from '@gitlab/ui';
+import BitbucketStatusTable from '~/import_projects/components/bitbucket_status_table.vue';
+
+export default {
+ components: {
+ BitbucketStatusTable,
+ GlButton,
+ },
+ props: {
+ providerTitle: {
+ type: String,
+ required: true,
+ },
+ reconfigurePath: {
+ type: String,
+ required: true,
+ },
+ },
+};
+</script>
+<template>
+ <bitbucket-status-table :provider-title="providerTitle">
+ <template #actions>
+ <gl-button variant="info" class="gl-ml-3" data-method="post" :href="reconfigurePath">{{
+ __('Reconfigure')
+ }}</gl-button>
+ </template>
+ </bitbucket-status-table>
+</template>
diff --git a/app/assets/javascripts/pages/import/bitbucket_server/status/index.js b/app/assets/javascripts/pages/import/bitbucket_server/status/index.js
new file mode 100644
index 00000000000..88455c9b7b9
--- /dev/null
+++ b/app/assets/javascripts/pages/import/bitbucket_server/status/index.js
@@ -0,0 +1,20 @@
+import Vue from 'vue';
+import { initStoreFromElement, initPropsFromElement } from '~/import_projects';
+import BitbucketServerStatusTable from './components/bitbucket_server_status_table.vue';
+
+document.addEventListener('DOMContentLoaded', () => {
+ const mountElement = document.getElementById('import-projects-mount-element');
+ if (!mountElement) return undefined;
+
+ const store = initStoreFromElement(mountElement);
+ const props = initPropsFromElement(mountElement);
+ const { reconfigurePath } = mountElement.dataset;
+
+ return new Vue({
+ el: mountElement,
+ store,
+ render(createElement) {
+ return createElement(BitbucketServerStatusTable, { props: { ...props, reconfigurePath } });
+ },
+ });
+});
diff --git a/app/assets/javascripts/pages/import/fogbugz/status/index.js b/app/assets/javascripts/pages/import/fogbugz/status/index.js
new file mode 100644
index 00000000000..dcd84f0faf9
--- /dev/null
+++ b/app/assets/javascripts/pages/import/fogbugz/status/index.js
@@ -0,0 +1,7 @@
+import mountImportProjectsTable from '~/import_projects';
+
+document.addEventListener('DOMContentLoaded', () => {
+ const mountElement = document.getElementById('import-projects-mount-element');
+
+ mountImportProjectsTable(mountElement);
+});
diff --git a/app/assets/javascripts/pages/import/gitlab/status/index.js b/app/assets/javascripts/pages/import/gitlab/status/index.js
new file mode 100644
index 00000000000..dcd84f0faf9
--- /dev/null
+++ b/app/assets/javascripts/pages/import/gitlab/status/index.js
@@ -0,0 +1,7 @@
+import mountImportProjectsTable from '~/import_projects';
+
+document.addEventListener('DOMContentLoaded', () => {
+ const mountElement = document.getElementById('import-projects-mount-element');
+
+ mountImportProjectsTable(mountElement);
+});
diff --git a/app/assets/javascripts/pages/ldap/omniauth_callbacks/index.js b/app/assets/javascripts/pages/ldap/omniauth_callbacks/index.js
index edd7e38471b..e93def5323f 100644
--- a/app/assets/javascripts/pages/ldap/omniauth_callbacks/index.js
+++ b/app/assets/javascripts/pages/ldap/omniauth_callbacks/index.js
@@ -1,3 +1,3 @@
-import initU2F from '../../../shared/sessions/u2f';
+import { mount2faAuthentication } from '~/authentication/mount_2fa';
-document.addEventListener('DOMContentLoaded', initU2F);
+document.addEventListener('DOMContentLoaded', mount2faAuthentication);
diff --git a/app/assets/javascripts/pages/omniauth_callbacks/index.js b/app/assets/javascripts/pages/omniauth_callbacks/index.js
index c2c069d1ca8..e93def5323f 100644
--- a/app/assets/javascripts/pages/omniauth_callbacks/index.js
+++ b/app/assets/javascripts/pages/omniauth_callbacks/index.js
@@ -1,3 +1,3 @@
-import initU2F from '../../shared/sessions/u2f';
+import { mount2faAuthentication } from '~/authentication/mount_2fa';
-document.addEventListener('DOMContentLoaded', initU2F);
+document.addEventListener('DOMContentLoaded', mount2faAuthentication);
diff --git a/app/assets/javascripts/pages/profiles/two_factor_auths/index.js b/app/assets/javascripts/pages/profiles/two_factor_auths/index.js
index 95936c2d1db..1aeba6669ee 100644
--- a/app/assets/javascripts/pages/profiles/two_factor_auths/index.js
+++ b/app/assets/javascripts/pages/profiles/two_factor_auths/index.js
@@ -1,6 +1,5 @@
-import $ from 'jquery';
-import U2FRegister from '~/u2f/register';
import { parseBoolean } from '~/lib/utils/common_utils';
+import { mount2faRegistration } from '~/authentication/mount_2fa';
document.addEventListener('DOMContentLoaded', () => {
const twoFactorNode = document.querySelector('.js-two-factor-auth');
@@ -12,6 +11,5 @@ document.addEventListener('DOMContentLoaded', () => {
if (flashAlert) flashAlert.insertAdjacentHTML('beforeend', button);
}
- const u2fRegister = new U2FRegister($('#js-register-u2f'), gon.u2f);
- u2fRegister.start();
+ mount2faRegistration();
});
diff --git a/app/assets/javascripts/pages/projects/clusters/index.js b/app/assets/javascripts/pages/projects/clusters/index.js
new file mode 100644
index 00000000000..4d04c37caa7
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/clusters/index.js
@@ -0,0 +1,5 @@
+import initCreateCluster from '~/create_cluster/init_create_cluster';
+
+document.addEventListener('DOMContentLoaded', () => {
+ initCreateCluster(document, gon);
+});
diff --git a/app/assets/javascripts/pages/projects/edit/index.js b/app/assets/javascripts/pages/projects/edit/index.js
index c9dbe576c4b..9fb07917f9b 100644
--- a/app/assets/javascripts/pages/projects/edit/index.js
+++ b/app/assets/javascripts/pages/projects/edit/index.js
@@ -4,12 +4,12 @@ import setupTransferEdit from '~/transfer_edit';
import initConfirmDangerModal from '~/confirm_danger_modal';
import mountBadgeSettings from '~/pages/shared/mount_badge_settings';
import dirtySubmitFactory from '~/dirty_submit/dirty_submit_factory';
-import initAvatarPicker from '~/avatar_picker';
+import initFilePickers from '~/file_pickers';
import initProjectLoadingSpinner from '../shared/save_project_loader';
import initProjectPermissionsSettings from '../shared/permissions';
document.addEventListener('DOMContentLoaded', () => {
- initAvatarPicker();
+ initFilePickers();
initConfirmDangerModal();
initSettingsPanels();
mountBadgeSettings(PROJECT_BADGE);
diff --git a/app/assets/javascripts/pages/projects/environments/metrics/index.js b/app/assets/javascripts/pages/projects/environments/metrics/index.js
index 31ec4e29ad2..d3028aec313 100644
--- a/app/assets/javascripts/pages/projects/environments/metrics/index.js
+++ b/app/assets/javascripts/pages/projects/environments/metrics/index.js
@@ -1,3 +1,3 @@
-import monitoringBundle from '~/monitoring/monitoring_bundle_with_alerts';
+import monitoringApp from '~/monitoring/monitoring_app';
-document.addEventListener('DOMContentLoaded', monitoringBundle);
+document.addEventListener('DOMContentLoaded', monitoringApp);
diff --git a/app/assets/javascripts/pages/projects/graphs/charts/index.js b/app/assets/javascripts/pages/projects/graphs/charts/index.js
index 803f4e37705..03504fba1ae 100644
--- a/app/assets/javascripts/pages/projects/graphs/charts/index.js
+++ b/app/assets/javascripts/pages/projects/graphs/charts/index.js
@@ -1,10 +1,12 @@
import Vue from 'vue';
import { __ } from '~/locale';
import { GlColumnChart } from '@gitlab/ui/dist/charts';
+import CodeCoverage from '../components/code_coverage.vue';
import SeriesDataMixin from './series_data_mixin';
document.addEventListener('DOMContentLoaded', () => {
const languagesContainer = document.getElementById('js-languages-chart');
+ const codeCoverageContainer = document.getElementById('js-code-coverage-chart');
const monthContainer = document.getElementById('js-month-chart');
const weekdayContainer = document.getElementById('js-weekday-chart');
const hourContainer = document.getElementById('js-hour-chart');
@@ -59,6 +61,18 @@ document.addEventListener('DOMContentLoaded', () => {
// eslint-disable-next-line no-new
new Vue({
+ el: codeCoverageContainer,
+ render(h) {
+ return h(CodeCoverage, {
+ props: {
+ graphEndpoint: codeCoverageContainer.dataset?.graphEndpoint,
+ },
+ });
+ },
+ });
+
+ // eslint-disable-next-line no-new
+ new Vue({
el: monthContainer,
components: {
GlColumnChart,
diff --git a/app/assets/javascripts/pages/projects/graphs/components/code_coverage.vue b/app/assets/javascripts/pages/projects/graphs/components/code_coverage.vue
new file mode 100644
index 00000000000..af8fb032c22
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/graphs/components/code_coverage.vue
@@ -0,0 +1,177 @@
+<script>
+import { GlAlert, GlDropdown, GlDropdownItem, GlIcon, GlSprintf } from '@gitlab/ui';
+import { GlAreaChart } from '@gitlab/ui/dist/charts';
+import dateFormat from 'dateformat';
+import axios from '~/lib/utils/axios_utils';
+import { get } from 'lodash';
+
+import { __ } from '~/locale';
+
+export default {
+ components: {
+ GlAlert,
+ GlAreaChart,
+ GlDropdown,
+ GlDropdownItem,
+ GlIcon,
+ GlSprintf,
+ },
+ props: {
+ graphEndpoint: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ dailyCoverageData: [],
+ hasFetchError: false,
+ isLoading: true,
+ selectedCoverageIndex: 0,
+ tooltipTitle: '',
+ coveragePercentage: '',
+ chartOptions: {
+ yAxis: {
+ name: __('Bi-weekly code coverage'),
+ type: 'value',
+ min: 0,
+ max: 100,
+ },
+ xAxis: {
+ name: '',
+ type: 'category',
+ },
+ },
+ };
+ },
+ computed: {
+ hasData() {
+ return this.dailyCoverageData.length > 0;
+ },
+ isReady() {
+ return !this.isLoading && !this.hasFetchError;
+ },
+ canShowData() {
+ return this.isReady && this.hasData;
+ },
+ noDataAvailable() {
+ return this.isReady && !this.hasData;
+ },
+ selectedDailyCoverage() {
+ return this.hasData && this.dailyCoverageData[this.selectedCoverageIndex];
+ },
+ selectedDailyCoverageName() {
+ return this.selectedDailyCoverage?.group_name;
+ },
+ formattedData() {
+ if (this.selectedDailyCoverage?.data) {
+ return this.selectedDailyCoverage.data.map(value => [
+ dateFormat(value.date, 'mmm dd'),
+ value.coverage,
+ ]);
+ }
+
+ // If the fetching failed, we return an empty array which
+ // allow the graph to render while empty
+ return [];
+ },
+ chartData() {
+ return [
+ {
+ // The default string 'data' will get shown in the legend if we fail to fetch the data
+ name: this.canShowData ? this.selectedDailyCoverageName : __('data'),
+ data: this.formattedData,
+ type: 'line',
+ smooth: true,
+ },
+ ];
+ },
+ },
+ created() {
+ axios
+ .get(this.graphEndpoint)
+ .then(({ data }) => {
+ this.dailyCoverageData = data;
+ })
+ .catch(() => {
+ this.hasFetchError = true;
+ })
+ .finally(() => {
+ this.isLoading = false;
+ });
+ },
+ methods: {
+ setSelectedCoverage(index) {
+ this.selectedCoverageIndex = index;
+ },
+ formatTooltipText(params) {
+ this.tooltipTitle = params.value;
+ this.coveragePercentage = get(params, 'seriesData[0].data[1]', '');
+ },
+ },
+ height: 200,
+};
+</script>
+
+<template>
+ <div>
+ <div class="gl-mt-3 gl-mb-3">
+ <gl-alert
+ v-if="hasFetchError"
+ variant="danger"
+ :title="s__('Code Coverage|Couldn\'t fetch the code coverage data')"
+ :dismissible="false"
+ />
+ <gl-alert
+ v-if="noDataAvailable"
+ variant="info"
+ :title="s__('Code Coverage| Empty code coverage data')"
+ :dismissible="false"
+ >
+ <span>
+ {{ __('It seems that there is currently no available data for code coverage') }}
+ </span>
+ </gl-alert>
+ <gl-dropdown v-if="canShowData" :text="selectedDailyCoverageName">
+ <gl-dropdown-item
+ v-for="({ group_name }, index) in dailyCoverageData"
+ :key="index"
+ :value="group_name"
+ @click="setSelectedCoverage(index)"
+ >
+ <div class="gl-display-flex">
+ <gl-icon
+ v-if="index === selectedCoverageIndex"
+ name="mobile-issue-close"
+ class="gl-absolute"
+ />
+ <span class="gl-display-flex align-items-center ml-4">
+ {{ group_name }}
+ </span>
+ </div>
+ </gl-dropdown-item>
+ </gl-dropdown>
+ </div>
+ <gl-area-chart
+ v-if="!isLoading"
+ :height="$options.height"
+ :data="chartData"
+ :option="chartOptions"
+ :format-tooltip-text="formatTooltipText"
+ >
+ <template v-if="canShowData" #tooltipTitle>
+ {{ tooltipTitle }}
+ </template>
+ <template v-if="canShowData" #tooltipContent>
+ <gl-sprintf :message="__('Code Coverage: %{coveragePercentage}%{percentSymbol}')">
+ <template #coveragePercentage>
+ {{ coveragePercentage }}
+ </template>
+ <template #percentSymbol>
+ %
+ </template>
+ </gl-sprintf>
+ </template>
+ </gl-area-chart>
+ </div>
+</template>
diff --git a/app/assets/javascripts/pages/projects/index.js b/app/assets/javascripts/pages/projects/index.js
index 190d0806c28..8e0af018b61 100644
--- a/app/assets/javascripts/pages/projects/index.js
+++ b/app/assets/javascripts/pages/projects/index.js
@@ -1,10 +1,7 @@
import Project from './project';
import ShortcutsNavigation from '../../behaviors/shortcuts/shortcuts_navigation';
-import initCreateCluster from '~/create_cluster/init_create_cluster';
document.addEventListener('DOMContentLoaded', () => {
- initCreateCluster(document, gon);
-
new Project(); // eslint-disable-line no-new
new ShortcutsNavigation(); // eslint-disable-line no-new
});
diff --git a/app/assets/javascripts/pages/projects/issues/index/index.js b/app/assets/javascripts/pages/projects/issues/index/index.js
index e8e0cda2139..a66b665d152 100644
--- a/app/assets/javascripts/pages/projects/issues/index/index.js
+++ b/app/assets/javascripts/pages/projects/issues/index/index.js
@@ -9,6 +9,7 @@ import { FILTERED_SEARCH } from '~/pages/constants';
import { ISSUABLE_INDEX } from '~/pages/projects/constants';
import initIssuablesList from '~/issuables_list';
import initManualOrdering from '~/manual_ordering';
+import { showLearnGitLabIssuesPopover } from '~/onboarding_issues';
document.addEventListener('DOMContentLoaded', () => {
IssuableFilteredSearchTokenKeys.addExtraTokensForIssues();
@@ -24,4 +25,5 @@ document.addEventListener('DOMContentLoaded', () => {
initManualOrdering();
initIssuablesList();
+ showLearnGitLabIssuesPopover();
});
diff --git a/app/assets/javascripts/pages/projects/labels/components/promote_label_modal.vue b/app/assets/javascripts/pages/projects/labels/components/promote_label_modal.vue
index 3b26047455d..08078fa6b62 100644
--- a/app/assets/javascripts/pages/projects/labels/components/promote_label_modal.vue
+++ b/app/assets/javascripts/pages/projects/labels/components/promote_label_modal.vue
@@ -90,7 +90,7 @@ export default {
footer-primary-button-variant="warning"
@submit="onSubmit"
>
- <div slot="title" class="modal-title-with-label" v-html="title">{{ title }}</div>
+ <div slot="title" class="modal-title-with-label" v-html="title"></div>
{{ text }}
</gl-modal>
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 ddc648702f1..4708970efef 100644
--- a/app/assets/javascripts/pages/projects/merge_requests/show/index.js
+++ b/app/assets/javascripts/pages/projects/merge_requests/show/index.js
@@ -1,4 +1,5 @@
import initMrNotes from '~/mr_notes';
+import { initReviewBar } from '~/batch_comments';
import initSidebarBundle from '~/sidebar/sidebar_bundle';
import initShow from '../init_merge_request_show';
@@ -8,4 +9,5 @@ document.addEventListener('DOMContentLoaded', () => {
initSidebarBundle();
}
initMrNotes();
+ initReviewBar();
});
diff --git a/app/assets/javascripts/pages/projects/new/index.js b/app/assets/javascripts/pages/projects/new/index.js
index 097403ba9e2..e17059dd55a 100644
--- a/app/assets/javascripts/pages/projects/new/index.js
+++ b/app/assets/javascripts/pages/projects/new/index.js
@@ -1,7 +1,46 @@
import initProjectVisibilitySelector from '../../../project_visibility';
import initProjectNew from '../../../projects/project_new';
+import { __ } from '~/locale';
+import createFlash from '~/flash';
+import Tracking from '~/tracking';
document.addEventListener('DOMContentLoaded', () => {
initProjectVisibilitySelector();
initProjectNew.bindEvents();
+
+ const { category, property } = gon.tracking_data ?? { category: 'projects:new' };
+ const hasNewCreateProjectUi = 'newCreateProjectUi' in gon?.features;
+
+ if (!hasNewCreateProjectUi) {
+ // Setting additional tracking for HAML template
+
+ Array.from(
+ document.querySelectorAll('.project-edit-container [data-experiment-track-label]'),
+ ).forEach(node =>
+ node.addEventListener('click', event => {
+ const { experimentTrackLabel: label } = event.currentTarget.dataset;
+ Tracking.event(category, 'click_tab', { property, label });
+ }),
+ );
+ } else {
+ import(
+ /* webpackChunkName: 'experiment_new_project_creation' */ '../../../projects/experiment_new_project_creation'
+ )
+ .then(m => {
+ const el = document.querySelector('.js-experiment-new-project-creation');
+
+ if (!el) {
+ return;
+ }
+
+ const config = {
+ hasErrors: 'hasErrors' in el.dataset,
+ isCiCdAvailable: 'isCiCdAvailable' in el.dataset,
+ };
+ m.default(el, config);
+ })
+ .catch(() => {
+ createFlash(__('An error occurred while loading project creation UI'));
+ });
+ }
});
diff --git a/app/assets/javascripts/pages/projects/pipelines/index/index.js b/app/assets/javascripts/pages/projects/pipelines/index/index.js
index bbad3238ec4..2c37d7da4a7 100644
--- a/app/assets/javascripts/pages/projects/pipelines/index/index.js
+++ b/app/assets/javascripts/pages/projects/pipelines/index/index.js
@@ -51,6 +51,7 @@ document.addEventListener(
ciLintPath: this.dataset.ciLintPath,
resetCachePath: this.dataset.resetCachePath,
projectId: this.dataset.projectId,
+ params: JSON.parse(this.dataset.params),
},
});
},
diff --git a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
index ab32fe18972..7181332a1d6 100644
--- a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
+++ b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
@@ -46,7 +46,11 @@ export default {
allowedVisibilityOptions: {
type: Array,
required: false,
- default: () => [0, 10, 20],
+ default: () => [
+ visibilityOptions.PRIVATE,
+ visibilityOptions.INTERNAL,
+ visibilityOptions.PUBLIC,
+ ],
},
lfsAvailable: {
type: Boolean,
@@ -118,16 +122,14 @@ export default {
const defaults = {
visibilityOptions,
visibilityLevel: visibilityOptions.PUBLIC,
- // TODO: Change all of these to use the visibilityOptions constants
- // https://gitlab.com/gitlab-org/gitlab/-/issues/214667
- issuesAccessLevel: 20,
- repositoryAccessLevel: 20,
- forkingAccessLevel: 20,
- mergeRequestsAccessLevel: 20,
- buildsAccessLevel: 20,
- wikiAccessLevel: 20,
- snippetsAccessLevel: 20,
- pagesAccessLevel: 20,
+ issuesAccessLevel: featureAccessLevel.EVERYONE,
+ repositoryAccessLevel: featureAccessLevel.EVERYONE,
+ forkingAccessLevel: featureAccessLevel.EVERYONE,
+ mergeRequestsAccessLevel: featureAccessLevel.EVERYONE,
+ buildsAccessLevel: featureAccessLevel.EVERYONE,
+ wikiAccessLevel: featureAccessLevel.EVERYONE,
+ snippetsAccessLevel: featureAccessLevel.EVERYONE,
+ pagesAccessLevel: featureAccessLevel.EVERYONE,
metricsDashboardAccessLevel: featureAccessLevel.PROJECT_MEMBERS,
containerRegistryEnabled: true,
lfsEnabled: true,
@@ -180,7 +182,7 @@ export default {
},
repositoryEnabled() {
- return this.repositoryAccessLevel > 0;
+ return this.repositoryAccessLevel > featureAccessLevel.NOT_ENABLED;
},
visibilityLevelDescription() {
@@ -206,40 +208,70 @@ export default {
visibilityLevel(value, oldValue) {
if (value === visibilityOptions.PRIVATE) {
// when private, features are restricted to "only team members"
- this.issuesAccessLevel = Math.min(10, this.issuesAccessLevel);
- this.repositoryAccessLevel = Math.min(10, this.repositoryAccessLevel);
- this.mergeRequestsAccessLevel = Math.min(10, this.mergeRequestsAccessLevel);
- this.buildsAccessLevel = Math.min(10, this.buildsAccessLevel);
- this.wikiAccessLevel = Math.min(10, this.wikiAccessLevel);
- this.snippetsAccessLevel = Math.min(10, this.snippetsAccessLevel);
- this.metricsDashboardAccessLevel = Math.min(10, this.metricsDashboardAccessLevel);
- if (this.pagesAccessLevel === 20) {
+ this.issuesAccessLevel = Math.min(
+ featureAccessLevel.PROJECT_MEMBERS,
+ this.issuesAccessLevel,
+ );
+ this.repositoryAccessLevel = Math.min(
+ featureAccessLevel.PROJECT_MEMBERS,
+ this.repositoryAccessLevel,
+ );
+ this.mergeRequestsAccessLevel = Math.min(
+ featureAccessLevel.PROJECT_MEMBERS,
+ this.mergeRequestsAccessLevel,
+ );
+ this.buildsAccessLevel = Math.min(
+ featureAccessLevel.PROJECT_MEMBERS,
+ this.buildsAccessLevel,
+ );
+ this.wikiAccessLevel = Math.min(featureAccessLevel.PROJECT_MEMBERS, this.wikiAccessLevel);
+ this.snippetsAccessLevel = Math.min(
+ featureAccessLevel.PROJECT_MEMBERS,
+ this.snippetsAccessLevel,
+ );
+ this.metricsDashboardAccessLevel = Math.min(
+ featureAccessLevel.PROJECT_MEMBERS,
+ this.metricsDashboardAccessLevel,
+ );
+ if (this.pagesAccessLevel === featureAccessLevel.EVERYONE) {
// When from Internal->Private narrow access for only members
- this.pagesAccessLevel = 10;
+ this.pagesAccessLevel = featureAccessLevel.PROJECT_MEMBERS;
}
this.highlightChanges();
} else if (oldValue === visibilityOptions.PRIVATE) {
// if changing away from private, make enabled features more permissive
- if (this.issuesAccessLevel > 0) this.issuesAccessLevel = 20;
- if (this.repositoryAccessLevel > 0) this.repositoryAccessLevel = 20;
- if (this.mergeRequestsAccessLevel > 0) this.mergeRequestsAccessLevel = 20;
- if (this.buildsAccessLevel > 0) this.buildsAccessLevel = 20;
- if (this.wikiAccessLevel > 0) this.wikiAccessLevel = 20;
- if (this.snippetsAccessLevel > 0) this.snippetsAccessLevel = 20;
- if (this.pagesAccessLevel === 10) this.pagesAccessLevel = 20;
- if (this.metricsDashboardAccessLevel === 10) this.metricsDashboardAccessLevel = 20;
+ if (this.issuesAccessLevel > featureAccessLevel.NOT_ENABLED)
+ this.issuesAccessLevel = featureAccessLevel.EVERYONE;
+ if (this.repositoryAccessLevel > featureAccessLevel.NOT_ENABLED)
+ this.repositoryAccessLevel = featureAccessLevel.EVERYONE;
+ if (this.mergeRequestsAccessLevel > featureAccessLevel.NOT_ENABLED)
+ this.mergeRequestsAccessLevel = featureAccessLevel.EVERYONE;
+ if (this.buildsAccessLevel > featureAccessLevel.NOT_ENABLED)
+ this.buildsAccessLevel = featureAccessLevel.EVERYONE;
+ if (this.wikiAccessLevel > featureAccessLevel.NOT_ENABLED)
+ this.wikiAccessLevel = featureAccessLevel.EVERYONE;
+ if (this.snippetsAccessLevel > featureAccessLevel.NOT_ENABLED)
+ this.snippetsAccessLevel = featureAccessLevel.EVERYONE;
+ if (this.pagesAccessLevel === featureAccessLevel.PROJECT_MEMBERS)
+ this.pagesAccessLevel = featureAccessLevel.EVERYONE;
+ if (this.metricsDashboardAccessLevel === featureAccessLevel.PROJECT_MEMBERS)
+ this.metricsDashboardAccessLevel = featureAccessLevel.EVERYONE;
this.highlightChanges();
}
},
issuesAccessLevel(value, oldValue) {
- if (value === 0) toggleHiddenClassBySelector('.issues-feature', true);
- else if (oldValue === 0) toggleHiddenClassBySelector('.issues-feature', false);
+ if (value === featureAccessLevel.NOT_ENABLED)
+ toggleHiddenClassBySelector('.issues-feature', true);
+ else if (oldValue === featureAccessLevel.NOT_ENABLED)
+ toggleHiddenClassBySelector('.issues-feature', false);
},
mergeRequestsAccessLevel(value, oldValue) {
- if (value === 0) toggleHiddenClassBySelector('.merge-requests-feature', true);
- else if (oldValue === 0) toggleHiddenClassBySelector('.merge-requests-feature', false);
+ if (value === featureAccessLevel.NOT_ENABLED)
+ toggleHiddenClassBySelector('.merge-requests-feature', true);
+ else if (oldValue === featureAccessLevel.NOT_ENABLED)
+ toggleHiddenClassBySelector('.merge-requests-feature', false);
},
},
diff --git a/app/assets/javascripts/pages/projects/show/index.js b/app/assets/javascripts/pages/projects/show/index.js
index 6ae10c98058..3c44053e2b2 100644
--- a/app/assets/javascripts/pages/projects/show/index.js
+++ b/app/assets/javascripts/pages/projects/show/index.js
@@ -1,4 +1,6 @@
import $ from 'jquery';
+import 'jquery.waitforimages';
+
import initBlob from '~/blob_edit/blob_bundle';
import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import NotificationsForm from '~/notifications_form';
@@ -12,9 +14,12 @@ import initReadMore from '~/read_more';
import leaveByUrl from '~/namespaces/leave_by_url';
import Star from '../../../star';
import notificationsDropdown from '../../../notifications_dropdown';
+import initNamespaceStorageLimitAlert from '~/namespace_storage_limit_alert';
+import { showLearnGitLabProjectPopover } from '~/onboarding_issues';
document.addEventListener('DOMContentLoaded', () => {
initReadMore();
+ initNamespaceStorageLimitAlert();
new Star(); // eslint-disable-line no-new
notificationsDropdown();
new ShortcutsNavigation(); // eslint-disable-line no-new
@@ -55,4 +60,6 @@ document.addEventListener('DOMContentLoaded', () => {
throw e;
});
}
+
+ showLearnGitLabProjectPopover();
});
diff --git a/app/assets/javascripts/pages/projects/tree/show/index.js b/app/assets/javascripts/pages/projects/tree/show/index.js
index 16d71379e31..0d1d32317fe 100644
--- a/app/assets/javascripts/pages/projects/tree/show/index.js
+++ b/app/assets/javascripts/pages/projects/tree/show/index.js
@@ -1,4 +1,6 @@
import $ from 'jquery';
+import 'jquery.waitforimages';
+
import Vue from 'vue';
import initBlob from '~/blob_edit/blob_bundle';
import commitPipelineStatus from '~/projects/tree/components/commit_pipeline_status_component.vue';
diff --git a/app/assets/javascripts/pages/projects/wikis/index.js b/app/assets/javascripts/pages/projects/wikis/index.js
index f5fd84d69ac..9c75531ca40 100644
--- a/app/assets/javascripts/pages/projects/wikis/index.js
+++ b/app/assets/javascripts/pages/projects/wikis/index.js
@@ -1,41 +1,3 @@
-import $ from 'jquery';
-import Vue from 'vue';
-import Translate from '~/vue_shared/translate';
-import csrf from '~/lib/utils/csrf';
-import ShortcutsWiki from '~/behaviors/shortcuts/shortcuts_wiki';
-import Wikis from './wikis';
-import ZenMode from '../../../zen_mode';
-import GLForm from '../../../gl_form';
-import deleteWikiModal from './components/delete_wiki_modal.vue';
+import initWikis from '~/pages/shared/wikis';
-document.addEventListener('DOMContentLoaded', () => {
- new Wikis(); // eslint-disable-line no-new
- new ShortcutsWiki(); // eslint-disable-line no-new
- new ZenMode(); // eslint-disable-line no-new
- new GLForm($('.wiki-form')); // eslint-disable-line no-new
-
- const deleteWikiModalWrapperEl = document.getElementById('delete-wiki-modal-wrapper');
-
- if (deleteWikiModalWrapperEl) {
- Vue.use(Translate);
-
- const { deleteWikiUrl, pageTitle } = deleteWikiModalWrapperEl.dataset;
-
- // eslint-disable-next-line no-new
- new Vue({
- el: deleteWikiModalWrapperEl,
- data: {
- deleteWikiUrl: '',
- },
- render(createElement) {
- return createElement(deleteWikiModal, {
- props: {
- pageTitle,
- deleteWikiUrl,
- csrfToken: csrf.token,
- },
- });
- },
- });
- }
-});
+document.addEventListener('DOMContentLoaded', initWikis);
diff --git a/app/assets/javascripts/pages/sessions/index.js b/app/assets/javascripts/pages/sessions/index.js
index c2c069d1ca8..e93def5323f 100644
--- a/app/assets/javascripts/pages/sessions/index.js
+++ b/app/assets/javascripts/pages/sessions/index.js
@@ -1,3 +1,3 @@
-import initU2F from '../../shared/sessions/u2f';
+import { mount2faAuthentication } from '~/authentication/mount_2fa';
-document.addEventListener('DOMContentLoaded', initU2F);
+document.addEventListener('DOMContentLoaded', mount2faAuthentication);
diff --git a/app/assets/javascripts/pages/sessions/new/oauth_remember_me.js b/app/assets/javascripts/pages/sessions/new/oauth_remember_me.js
index 191221a48cd..8d2d5d41f6a 100644
--- a/app/assets/javascripts/pages/sessions/new/oauth_remember_me.js
+++ b/app/assets/javascripts/pages/sessions/new/oauth_remember_me.js
@@ -5,13 +5,12 @@ import { mergeUrlParams, removeParams } from '~/lib/utils/url_utility';
* OAuth-based login buttons have a separate "remember me" checkbox.
*
* Toggling this checkbox adds/removes a `remember_me` parameter to the
- * login buttons' href, which is passed on to the omniauth callback.
+ * login buttons' parent form action, which is passed on to the omniauth callback.
*/
export default class OAuthRememberMe {
constructor(opts = {}) {
this.container = opts.container || '';
- this.loginLinkSelector = '.oauth-login';
}
bindEvents() {
@@ -22,12 +21,13 @@ export default class OAuthRememberMe {
const rememberMe = $(event.target).is(':checked');
$('.oauth-login', this.container).each((i, element) => {
- const href = $(element).attr('href');
+ const $form = $(element).parent('form');
+ const href = $form.attr('action');
if (rememberMe) {
- $(element).attr('href', mergeUrlParams({ remember_me: 1 }, href));
+ $form.attr('action', mergeUrlParams({ remember_me: 1 }, href));
} else {
- $(element).attr('href', removeParams(['remember_me'], href));
+ $form.attr('action', removeParams(['remember_me'], href));
}
});
}
diff --git a/app/assets/javascripts/pages/sessions/new/preserve_url_fragment.js b/app/assets/javascripts/pages/sessions/new/preserve_url_fragment.js
index e617fecaa0f..1d47a9aed47 100644
--- a/app/assets/javascripts/pages/sessions/new/preserve_url_fragment.js
+++ b/app/assets/javascripts/pages/sessions/new/preserve_url_fragment.js
@@ -12,7 +12,7 @@ export default function preserveUrlFragment(fragment = '') {
// Append the fragment to all sign-in/sign-up form actions so it is preserved when the user is
// eventually redirected back to the originally requested URL.
- const forms = document.querySelectorAll('#signin-container form');
+ const forms = document.querySelectorAll('#signin-container .tab-content form');
Array.prototype.forEach.call(forms, form => {
const actionWithFragment = setUrlFragment(form.getAttribute('action'), `#${normalFragment}`);
form.setAttribute('action', actionWithFragment);
@@ -20,13 +20,13 @@ export default function preserveUrlFragment(fragment = '') {
// Append a redirect_fragment query param to all oauth provider links. The redirect_fragment
// query param will be available in the omniauth callback upon successful authentication
- const anchors = document.querySelectorAll('#signin-container a.oauth-login');
- Array.prototype.forEach.call(anchors, anchor => {
+ const oauthForms = document.querySelectorAll('#signin-container .omniauth-container form');
+ Array.prototype.forEach.call(oauthForms, oauthForm => {
const newHref = mergeUrlParams(
{ redirect_fragment: normalFragment },
- anchor.getAttribute('href'),
+ oauthForm.getAttribute('action'),
);
- anchor.setAttribute('href', newHref);
+ oauthForm.setAttribute('action', newHref);
});
}
}
diff --git a/app/assets/javascripts/pages/projects/wikis/components/delete_wiki_modal.vue b/app/assets/javascripts/pages/shared/wikis/components/delete_wiki_modal.vue
index 580cca49b5e..580cca49b5e 100644
--- a/app/assets/javascripts/pages/projects/wikis/components/delete_wiki_modal.vue
+++ b/app/assets/javascripts/pages/shared/wikis/components/delete_wiki_modal.vue
diff --git a/app/assets/javascripts/pages/shared/wikis/index.js b/app/assets/javascripts/pages/shared/wikis/index.js
new file mode 100644
index 00000000000..5e23b9bab4e
--- /dev/null
+++ b/app/assets/javascripts/pages/shared/wikis/index.js
@@ -0,0 +1,41 @@
+import $ from 'jquery';
+import Vue from 'vue';
+import Translate from '~/vue_shared/translate';
+import csrf from '~/lib/utils/csrf';
+import ShortcutsWiki from '~/behaviors/shortcuts/shortcuts_wiki';
+import Wikis from './wikis';
+import ZenMode from '../../../zen_mode';
+import GLForm from '../../../gl_form';
+import deleteWikiModal from './components/delete_wiki_modal.vue';
+
+export default () => {
+ new Wikis(); // eslint-disable-line no-new
+ new ShortcutsWiki(); // eslint-disable-line no-new
+ new ZenMode(); // eslint-disable-line no-new
+ new GLForm($('.wiki-form')); // eslint-disable-line no-new
+
+ const deleteWikiModalWrapperEl = document.getElementById('delete-wiki-modal-wrapper');
+
+ if (deleteWikiModalWrapperEl) {
+ Vue.use(Translate);
+
+ const { deleteWikiUrl, pageTitle } = deleteWikiModalWrapperEl.dataset;
+
+ // eslint-disable-next-line no-new
+ new Vue({
+ el: deleteWikiModalWrapperEl,
+ data: {
+ deleteWikiUrl: '',
+ },
+ render(createElement) {
+ return createElement(deleteWikiModal, {
+ props: {
+ pageTitle,
+ deleteWikiUrl,
+ csrfToken: csrf.token,
+ },
+ });
+ },
+ });
+ }
+};
diff --git a/app/assets/javascripts/pages/projects/wikis/wikis.js b/app/assets/javascripts/pages/shared/wikis/wikis.js
index ed67219383b..ed67219383b 100644
--- a/app/assets/javascripts/pages/projects/wikis/wikis.js
+++ b/app/assets/javascripts/pages/shared/wikis/wikis.js
diff --git a/app/assets/javascripts/performance_bar/components/detailed_metric.vue b/app/assets/javascripts/performance_bar/components/detailed_metric.vue
index e1a0e2df0e0..ef24dbfb6ce 100644
--- a/app/assets/javascripts/performance_bar/components/detailed_metric.vue
+++ b/app/assets/javascripts/performance_bar/components/detailed_metric.vue
@@ -39,6 +39,11 @@ export default {
metricDetails() {
return this.currentRequest.details[this.metric];
},
+ metricDetailsLabel() {
+ return this.metricDetails.duration
+ ? `${this.metricDetails.duration} / ${this.metricDetails.calls}`
+ : this.metricDetails.calls;
+ },
detailsList() {
return this.metricDetails.details;
},
@@ -68,7 +73,7 @@ export default {
type="button"
data-toggle="modal"
>
- {{ metricDetails.duration }} / {{ metricDetails.calls }}
+ {{ metricDetailsLabel }}
</button>
<gl-modal
:id="`modal-peek-${metric}-details`"
@@ -80,7 +85,9 @@ export default {
<template v-if="detailsList.length">
<tr v-for="(item, index) in detailsList" :key="index">
<td>
- <span>{{ sprintf(__('%{duration}ms'), { duration: item.duration }) }}</span>
+ <span v-if="item.duration">{{
+ sprintf(__('%{duration}ms'), { duration: item.duration })
+ }}</span>
</td>
<td>
<div class="js-toggle-container">
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 1df5562e1b6..cccb5e1be06 100644
--- a/app/assets/javascripts/performance_bar/components/performance_bar_app.vue
+++ b/app/assets/javascripts/performance_bar/components/performance_bar_app.vue
@@ -38,6 +38,11 @@ export default {
keys: ['sql'],
},
{
+ metric: 'bullet',
+ header: s__('PerformanceBar|Bullet notifications'),
+ keys: ['notification'],
+ },
+ {
metric: 'gitaly',
header: s__('PerformanceBar|Gitaly calls'),
keys: ['feature', 'request'],
@@ -50,7 +55,12 @@ export default {
{
metric: 'redis',
header: s__('PerformanceBar|Redis calls'),
- keys: ['cmd'],
+ keys: ['cmd', 'instance'],
+ },
+ {
+ metric: 'es',
+ header: s__('PerformanceBar|Elasticsearch calls'),
+ keys: ['request', 'body'],
},
{
metric: 'total',
diff --git a/app/assets/javascripts/persistent_user_callouts.js b/app/assets/javascripts/persistent_user_callouts.js
new file mode 100644
index 00000000000..6e292299778
--- /dev/null
+++ b/app/assets/javascripts/persistent_user_callouts.js
@@ -0,0 +1,15 @@
+import PersistentUserCallout from './persistent_user_callout';
+
+const PERSISTENT_USER_CALLOUTS = [
+ '.js-recovery-settings-callout',
+ '.js-users-over-license-callout',
+ '.js-admin-licensed-user-count-threshold',
+];
+
+const initCallouts = () => {
+ PERSISTENT_USER_CALLOUTS.forEach(calloutContainer =>
+ PersistentUserCallout.factory(document.querySelector(calloutContainer)),
+ );
+};
+
+export default initCallouts;
diff --git a/app/assets/javascripts/pipelines/components/dag/constants.js b/app/assets/javascripts/pipelines/components/dag/constants.js
new file mode 100644
index 00000000000..51b1fb4f4cc
--- /dev/null
+++ b/app/assets/javascripts/pipelines/components/dag/constants.js
@@ -0,0 +1,10 @@
+/* Error constants */
+export const PARSE_FAILURE = 'parse_failure';
+export const LOAD_FAILURE = 'load_failure';
+export const UNSUPPORTED_DATA = 'unsupported_data';
+export const DEFAULT = 'default';
+
+/* Interaction handles */
+export const IS_HIGHLIGHTED = 'dag-highlighted';
+export const LINK_SELECTOR = 'dag-link';
+export const NODE_SELECTOR = 'dag-node';
diff --git a/app/assets/javascripts/pipelines/components/dag/dag.vue b/app/assets/javascripts/pipelines/components/dag/dag.vue
new file mode 100644
index 00000000000..6e0d23ef87f
--- /dev/null
+++ b/app/assets/javascripts/pipelines/components/dag/dag.vue
@@ -0,0 +1,136 @@
+<script>
+import { GlAlert, GlLink, GlSprintf } from '@gitlab/ui';
+import axios from '~/lib/utils/axios_utils';
+import { __ } from '~/locale';
+import DagGraph from './dag_graph.vue';
+import { DEFAULT, PARSE_FAILURE, LOAD_FAILURE, UNSUPPORTED_DATA } from './constants';
+import { parseData } from './parsing_utils';
+
+export default {
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ name: 'Dag',
+ components: {
+ DagGraph,
+ GlAlert,
+ GlLink,
+ GlSprintf,
+ },
+ props: {
+ graphUrl: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ },
+ data() {
+ return {
+ showFailureAlert: false,
+ showBetaInfo: true,
+ failureType: null,
+ graphData: null,
+ };
+ },
+ errorTexts: {
+ [LOAD_FAILURE]: __('We are currently unable to fetch data for this graph.'),
+ [PARSE_FAILURE]: __('There was an error parsing the data for this graph.'),
+ [UNSUPPORTED_DATA]: __('A DAG must have two dependent jobs to be visualized on this tab.'),
+ [DEFAULT]: __('An unknown error occurred while loading this graph.'),
+ },
+ computed: {
+ betaMessage() {
+ return __(
+ 'This feature is currently in beta. We invite you to %{linkStart}give feedback%{linkEnd}.',
+ );
+ },
+ failure() {
+ switch (this.failureType) {
+ case LOAD_FAILURE:
+ return {
+ text: this.$options.errorTexts[LOAD_FAILURE],
+ variant: 'danger',
+ };
+ case PARSE_FAILURE:
+ return {
+ text: this.$options.errorTexts[PARSE_FAILURE],
+ variant: 'danger',
+ };
+ case UNSUPPORTED_DATA:
+ return {
+ text: this.$options.errorTexts[UNSUPPORTED_DATA],
+ variant: 'info',
+ };
+ default:
+ return {
+ text: this.$options.errorTexts[DEFAULT],
+ vatiant: 'danger',
+ };
+ }
+ },
+ shouldDisplayGraph() {
+ return Boolean(!this.showFailureAlert && this.graphData);
+ },
+ },
+ mounted() {
+ const { processGraphData, reportFailure } = this;
+
+ if (!this.graphUrl) {
+ reportFailure();
+ return;
+ }
+
+ axios
+ .get(this.graphUrl)
+ .then(response => {
+ processGraphData(response.data);
+ })
+ .catch(() => reportFailure(LOAD_FAILURE));
+ },
+ methods: {
+ processGraphData(data) {
+ let parsed;
+
+ try {
+ parsed = parseData(data.stages);
+ } catch {
+ this.reportFailure(PARSE_FAILURE);
+ return;
+ }
+
+ if (parsed.links.length < 2) {
+ this.reportFailure(UNSUPPORTED_DATA);
+ return;
+ }
+
+ this.graphData = parsed;
+ },
+ hideAlert() {
+ this.showFailureAlert = false;
+ },
+ hideBetaInfo() {
+ this.showBetaInfo = false;
+ },
+ reportFailure(type) {
+ this.showFailureAlert = true;
+ this.failureType = type;
+ },
+ },
+};
+</script>
+<template>
+ <div>
+ <gl-alert v-if="showFailureAlert" :variant="failure.variant" @dismiss="hideAlert">
+ {{ failure.text }}
+ </gl-alert>
+
+ <gl-alert v-if="showBetaInfo" @dismiss="hideBetaInfo">
+ <gl-sprintf :message="betaMessage">
+ <template #link="{ content }">
+ <gl-link href="https://gitlab.com/gitlab-org/gitlab/-/issues/220368" target="_blank">
+ {{ content }}
+ </gl-link>
+ </template>
+ </gl-sprintf>
+ </gl-alert>
+ <dag-graph v-if="shouldDisplayGraph" :graph-data="graphData" @onFailure="reportFailure" />
+ </div>
+</template>
diff --git a/app/assets/javascripts/pipelines/components/dag/dag_graph.vue b/app/assets/javascripts/pipelines/components/dag/dag_graph.vue
new file mode 100644
index 00000000000..063ec091e4d
--- /dev/null
+++ b/app/assets/javascripts/pipelines/components/dag/dag_graph.vue
@@ -0,0 +1,299 @@
+<script>
+import * as d3 from 'd3';
+import { uniqueId } from 'lodash';
+import { LINK_SELECTOR, NODE_SELECTOR, PARSE_FAILURE } from './constants';
+import {
+ highlightLinks,
+ restoreLinks,
+ toggleLinkHighlight,
+ togglePathHighlights,
+} from './interactions';
+import { getMaxNodes, removeOrphanNodes } from './parsing_utils';
+import { calculateClip, createLinkPath, createSankey, labelPosition } from './drawing_utils';
+
+export default {
+ viewOptions: {
+ baseHeight: 300,
+ baseWidth: 1000,
+ minNodeHeight: 60,
+ nodeWidth: 16,
+ nodePadding: 25,
+ paddingForLabels: 100,
+ labelMargin: 8,
+
+ baseOpacity: 0.8,
+ containerClasses: ['dag-graph-container', 'gl-display-flex', 'gl-flex-direction-column'].join(
+ ' ',
+ ),
+ },
+ gitLabColorRotation: [
+ '#e17223',
+ '#83ab4a',
+ '#5772ff',
+ '#b24800',
+ '#25d2d2',
+ '#006887',
+ '#487900',
+ '#d84280',
+ '#3547de',
+ '#6f3500',
+ '#006887',
+ '#275600',
+ '#b31756',
+ ],
+ props: {
+ graphData: {
+ type: Object,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ color: () => {},
+ width: 0,
+ height: 0,
+ };
+ },
+ mounted() {
+ let countedAndTransformed;
+
+ try {
+ countedAndTransformed = this.transformData(this.graphData);
+ } catch {
+ this.$emit('onFailure', PARSE_FAILURE);
+ return;
+ }
+
+ this.drawGraph(countedAndTransformed);
+ },
+ methods: {
+ addSvg() {
+ return d3
+ .select('.dag-graph-container')
+ .append('svg')
+ .attr('viewBox', [0, 0, this.width, this.height])
+ .attr('width', this.width)
+ .attr('height', this.height);
+ },
+
+ appendLinks(link) {
+ return (
+ link
+ .append('path')
+ .attr('d', (d, i) => createLinkPath(d, i, this.$options.viewOptions.nodeWidth))
+ .attr('stroke', ({ gradId }) => `url(#${gradId})`)
+ .style('stroke-linejoin', 'round')
+ // minus two to account for the rounded nodes
+ .attr('stroke-width', ({ width }) => Math.max(1, width - 2))
+ .attr('clip-path', ({ clipId }) => `url(#${clipId})`)
+ );
+ },
+
+ appendLinkInteractions(link) {
+ return link
+ .on('mouseover', highlightLinks)
+ .on('mouseout', restoreLinks.bind(null, this.$options.viewOptions.baseOpacity))
+ .on('click', toggleLinkHighlight.bind(null, this.$options.viewOptions.baseOpacity));
+ },
+
+ appendNodeInteractions(node) {
+ return node.on(
+ 'click',
+ togglePathHighlights.bind(null, this.$options.viewOptions.baseOpacity),
+ );
+ },
+
+ appendLabelAsForeignObject(d, i, n) {
+ const currentNode = n[i];
+ const { height, wrapperWidth, width, x, y, textAlign } = labelPosition(d, {
+ ...this.$options.viewOptions,
+ width: this.width,
+ });
+
+ const labelClasses = [
+ 'gl-display-flex',
+ 'gl-pointer-events-none',
+ 'gl-flex-direction-column',
+ 'gl-justify-content-center',
+ 'gl-overflow-wrap-break',
+ ].join(' ');
+
+ return (
+ d3
+ .select(currentNode)
+ .attr('requiredFeatures', 'http://www.w3.org/TR/SVG11/feature#Extensibility')
+ .attr('height', height)
+ /*
+ items with a 'max-content' width will have a wrapperWidth for the foreignObject
+ */
+ .attr('width', wrapperWidth || width)
+ .attr('x', x)
+ .attr('y', y)
+ .classed('gl-overflow-visible', true)
+ .append('xhtml:div')
+ .classed(labelClasses, true)
+ .style('height', height)
+ .style('width', width)
+ .style('text-align', textAlign)
+ .text(({ name }) => name)
+ );
+ },
+
+ createAndAssignId(datum, field, modifier = '') {
+ const id = uniqueId(modifier);
+ /* eslint-disable-next-line no-param-reassign */
+ datum[field] = id;
+ return id;
+ },
+
+ createClip(link) {
+ return link
+ .append('clipPath')
+ .attr('id', d => {
+ return this.createAndAssignId(d, 'clipId', 'dag-clip');
+ })
+ .append('path')
+ .attr('d', calculateClip);
+ },
+
+ createGradient(link) {
+ const gradient = link
+ .append('linearGradient')
+ .attr('id', d => {
+ return this.createAndAssignId(d, 'gradId', 'dag-grad');
+ })
+ .attr('gradientUnits', 'userSpaceOnUse')
+ .attr('x1', ({ source }) => source.x1)
+ .attr('x2', ({ target }) => target.x0);
+
+ gradient
+ .append('stop')
+ .attr('offset', '0%')
+ .attr('stop-color', ({ source }) => this.color(source));
+
+ gradient
+ .append('stop')
+ .attr('offset', '100%')
+ .attr('stop-color', ({ target }) => this.color(target));
+ },
+
+ createLinks(svg, linksData) {
+ const links = this.generateLinks(svg, linksData);
+ this.createGradient(links);
+ this.createClip(links);
+ this.appendLinks(links);
+ this.appendLinkInteractions(links);
+ },
+
+ createNodes(svg, nodeData) {
+ const nodes = this.generateNodes(svg, nodeData);
+ this.labelNodes(svg, nodeData);
+ this.appendNodeInteractions(nodes);
+ },
+
+ drawGraph({ maxNodesPerLayer, linksAndNodes }) {
+ const {
+ baseWidth,
+ baseHeight,
+ minNodeHeight,
+ nodeWidth,
+ nodePadding,
+ paddingForLabels,
+ } = this.$options.viewOptions;
+
+ this.width = baseWidth;
+ this.height = baseHeight + maxNodesPerLayer * minNodeHeight;
+ this.color = this.initColors();
+
+ const { links, nodes } = createSankey({
+ width: this.width,
+ height: this.height,
+ nodeWidth,
+ nodePadding,
+ paddingForLabels,
+ })(linksAndNodes);
+
+ const svg = this.addSvg();
+ this.createLinks(svg, links);
+ this.createNodes(svg, nodes);
+ },
+
+ generateLinks(svg, linksData) {
+ return svg
+ .append('g')
+ .attr('fill', 'none')
+ .attr('stroke-opacity', this.$options.viewOptions.baseOpacity)
+ .selectAll(`.${LINK_SELECTOR}`)
+ .data(linksData)
+ .enter()
+ .append('g')
+ .attr('id', d => {
+ return this.createAndAssignId(d, 'uid', LINK_SELECTOR);
+ })
+ .classed(`${LINK_SELECTOR} gl-cursor-pointer`, true);
+ },
+
+ generateNodes(svg, nodeData) {
+ const { nodeWidth } = this.$options.viewOptions;
+
+ return svg
+ .append('g')
+ .selectAll(`.${NODE_SELECTOR}`)
+ .data(nodeData)
+ .enter()
+ .append('line')
+ .classed(`${NODE_SELECTOR} gl-cursor-pointer`, true)
+ .attr('id', d => {
+ return this.createAndAssignId(d, 'uid', NODE_SELECTOR);
+ })
+ .attr('stroke', d => {
+ const color = this.color(d);
+ /* eslint-disable-next-line no-param-reassign */
+ d.color = color;
+ return color;
+ })
+ .attr('stroke-width', nodeWidth)
+ .attr('stroke-linecap', 'round')
+ .attr('x1', d => Math.floor((d.x1 + d.x0) / 2))
+ .attr('x2', d => Math.floor((d.x1 + d.x0) / 2))
+ .attr('y1', d => d.y0 + 4)
+ .attr('y2', d => d.y1 - 4);
+ },
+
+ labelNodes(svg, nodeData) {
+ return svg
+ .append('g')
+ .classed('gl-font-sm', true)
+ .selectAll('text')
+ .data(nodeData)
+ .enter()
+ .append('foreignObject')
+ .each(this.appendLabelAsForeignObject);
+ },
+
+ initColors() {
+ const colorFn = d3.scaleOrdinal(this.$options.gitLabColorRotation);
+ return ({ name }) => colorFn(name);
+ },
+
+ transformData(parsed) {
+ const baseLayout = createSankey()(parsed);
+ const cleanedNodes = removeOrphanNodes(baseLayout.nodes);
+ const maxNodesPerLayer = getMaxNodes(cleanedNodes);
+
+ return {
+ maxNodesPerLayer,
+ linksAndNodes: {
+ links: parsed.links,
+ nodes: cleanedNodes,
+ },
+ };
+ },
+ },
+};
+</script>
+<template>
+ <div :class="$options.viewOptions.containerClasses" data-testid="dag-graph-container">
+ <!-- graph goes here -->
+ </div>
+</template>
diff --git a/app/assets/javascripts/pipelines/components/dag/drawing_utils.js b/app/assets/javascripts/pipelines/components/dag/drawing_utils.js
new file mode 100644
index 00000000000..d56addc473f
--- /dev/null
+++ b/app/assets/javascripts/pipelines/components/dag/drawing_utils.js
@@ -0,0 +1,134 @@
+import * as d3 from 'd3';
+import { sankey, sankeyLeft } from 'd3-sankey';
+
+export const calculateClip = ({ y0, y1, source, target, width }) => {
+ /*
+ Because large link values can overrun their box, we create a clip path
+ to trim off the excess in charts that have few nodes per column and are
+ therefore tall.
+
+ The box is created by
+ M: moving to outside midpoint of the source node
+ V: drawing a vertical line to maximum of the bottom link edge or
+ the lowest edge of the node (can be d.y0 or d.y1 depending on the link's path)
+ H: drawing a horizontal line to the outside edge of the destination node
+ V: drawing a vertical line back up to the minimum of the top link edge or
+ the highest edge of the node (can be d.y0 or d.y1 depending on the link's path)
+ H: drawing a horizontal line back to the outside edge of the source node
+ Z: closing the path, back to the start point
+ */
+
+ const bottomLinkEdge = Math.max(y1, y0) + width / 2;
+ const topLinkEdge = Math.min(y0, y1) - width / 2;
+
+ /* eslint-disable @gitlab/require-i18n-strings */
+ return `
+ M${source.x0}, ${y1}
+ V${Math.max(bottomLinkEdge, y0, y1)}
+ H${target.x1}
+ V${Math.min(topLinkEdge, y0, y1)}
+ H${source.x0}
+ Z
+ `;
+ /* eslint-enable @gitlab/require-i18n-strings */
+};
+
+export const createLinkPath = ({ y0, y1, source, target, width }, idx, nodeWidth) => {
+ /*
+ Creates a series of staggered midpoints for the link paths, so they
+ don't run along one channel and can be distinguished.
+
+ First, get a point staggered by index and link width, modulated by the link box
+ to find a point roughly between the nodes.
+
+ Then offset it by nodeWidth, so it doesn't run under any nodes at the left.
+
+ Determine where it would overlap at the right.
+
+ Finally, select the leftmost of these options:
+ - offset from the source node based on index + fudge;
+ - a fuzzy offset from the right node, using Math.random adds a little blur
+ - a hard offset from the end node, if random pushes it over
+
+ Then draw a line from the start node to the bottom-most point of the midline
+ up to the topmost point in that line and then to the middle of the end node
+ */
+
+ const xValRaw = source.x1 + (((idx + 1) * width) % (target.x1 - source.x0));
+ const xValMin = xValRaw + nodeWidth;
+ const overlapPoint = source.x1 + (target.x0 - source.x1);
+ const xValMax = overlapPoint - nodeWidth * 1.4;
+
+ const midPointX = Math.min(xValMin, target.x0 - nodeWidth * 4 * Math.random(), xValMax);
+
+ return d3.line()([
+ [(source.x0 + source.x1) / 2, y0],
+ [midPointX, y0],
+ [midPointX, y1],
+ [(target.x0 + target.x1) / 2, y1],
+ ]);
+};
+
+/*
+ createSankey calls the d3 layout to generate the relationships and positioning
+ values for the nodes and links in the graph.
+ */
+
+export const createSankey = ({
+ width = 10,
+ height = 10,
+ nodeWidth = 10,
+ nodePadding = 10,
+ paddingForLabels = 1,
+} = {}) => {
+ const sankeyGenerator = sankey()
+ .nodeId(({ name }) => name)
+ .nodeAlign(sankeyLeft)
+ .nodeWidth(nodeWidth)
+ .nodePadding(nodePadding)
+ .extent([
+ [paddingForLabels, paddingForLabels],
+ [width - paddingForLabels, height - paddingForLabels],
+ ]);
+ return ({ nodes, links }) =>
+ sankeyGenerator({
+ nodes: nodes.map(d => ({ ...d })),
+ links: links.map(d => ({ ...d })),
+ });
+};
+
+export const labelPosition = ({ x0, x1, y0, y1 }, viewOptions) => {
+ const { paddingForLabels, labelMargin, nodePadding, width } = viewOptions;
+
+ const firstCol = x0 <= paddingForLabels;
+ const lastCol = x1 >= width - paddingForLabels;
+
+ if (firstCol) {
+ return {
+ x: 0 + labelMargin,
+ y: y0,
+ height: `${y1 - y0}px`,
+ width: paddingForLabels - 2 * labelMargin,
+ textAlign: 'right',
+ };
+ }
+
+ if (lastCol) {
+ return {
+ x: width - paddingForLabels + labelMargin,
+ y: y0,
+ height: `${y1 - y0}px`,
+ width: paddingForLabels - 2 * labelMargin,
+ textAlign: 'left',
+ };
+ }
+
+ return {
+ x: (x1 + x0) / 2,
+ y: y0 - nodePadding,
+ height: `${nodePadding}px`,
+ width: 'max-content',
+ wrapperWidth: paddingForLabels - 2 * labelMargin,
+ textAlign: x0 < width / 2 ? 'left' : 'right',
+ };
+};
diff --git a/app/assets/javascripts/pipelines/components/dag/interactions.js b/app/assets/javascripts/pipelines/components/dag/interactions.js
new file mode 100644
index 00000000000..c9008730c90
--- /dev/null
+++ b/app/assets/javascripts/pipelines/components/dag/interactions.js
@@ -0,0 +1,134 @@
+import * as d3 from 'd3';
+import { LINK_SELECTOR, NODE_SELECTOR, IS_HIGHLIGHTED } from './constants';
+
+export const highlightIn = 1;
+export const highlightOut = 0.2;
+
+const getCurrent = (idx, collection) => d3.select(collection[idx]);
+const currentIsLive = (idx, collection) => getCurrent(idx, collection).classed(IS_HIGHLIGHTED);
+const getOtherLinks = () => d3.selectAll(`.${LINK_SELECTOR}:not(.${IS_HIGHLIGHTED})`);
+const getNodesNotLive = () => d3.selectAll(`.${NODE_SELECTOR}:not(.${IS_HIGHLIGHTED})`);
+
+const backgroundLinks = selection => selection.style('stroke-opacity', highlightOut);
+const backgroundNodes = selection => selection.attr('stroke', '#f2f2f2');
+const foregroundLinks = selection => selection.style('stroke-opacity', highlightIn);
+const foregroundNodes = selection => selection.attr('stroke', d => d.color);
+const renewLinks = (selection, baseOpacity) => selection.style('stroke-opacity', baseOpacity);
+const renewNodes = selection => selection.attr('stroke', d => d.color);
+
+const getAllLinkAncestors = node => {
+ if (node.targetLinks) {
+ return node.targetLinks.flatMap(n => {
+ return [n.uid, ...getAllLinkAncestors(n.source)];
+ });
+ }
+
+ return [];
+};
+
+const getAllNodeAncestors = node => {
+ let allNodes = [];
+
+ if (node.targetLinks) {
+ allNodes = node.targetLinks.flatMap(n => {
+ return getAllNodeAncestors(n.source);
+ });
+ }
+
+ return [...allNodes, node.uid];
+};
+
+export const highlightLinks = (d, idx, collection) => {
+ const currentLink = getCurrent(idx, collection);
+ const currentSourceNode = d3.select(`#${d.source.uid}`);
+ const currentTargetNode = d3.select(`#${d.target.uid}`);
+
+ /* Higlight selected link, de-emphasize others */
+ backgroundLinks(getOtherLinks());
+ foregroundLinks(currentLink);
+
+ /* Do the same to related nodes */
+ backgroundNodes(getNodesNotLive());
+ foregroundNodes(currentSourceNode);
+ foregroundNodes(currentTargetNode);
+};
+
+const highlightPath = (parentLinks, parentNodes) => {
+ /* de-emphasize everything else */
+ backgroundLinks(getOtherLinks());
+ backgroundNodes(getNodesNotLive());
+
+ /* highlight correct links */
+ parentLinks.forEach(id => {
+ foregroundLinks(d3.select(`#${id}`)).classed(IS_HIGHLIGHTED, true);
+ });
+
+ /* highlight correct nodes */
+ parentNodes.forEach(id => {
+ foregroundNodes(d3.select(`#${id}`)).classed(IS_HIGHLIGHTED, true);
+ });
+};
+
+const restorePath = (parentLinks, parentNodes, baseOpacity) => {
+ parentLinks.forEach(id => {
+ renewLinks(d3.select(`#${id}`), baseOpacity).classed(IS_HIGHLIGHTED, false);
+ });
+
+ parentNodes.forEach(id => {
+ d3.select(`#${id}`).classed(IS_HIGHLIGHTED, false);
+ });
+
+ if (d3.selectAll(`.${IS_HIGHLIGHTED}`).empty()) {
+ renewLinks(getOtherLinks(), baseOpacity);
+ renewNodes(getNodesNotLive());
+ return;
+ }
+
+ backgroundLinks(getOtherLinks());
+ backgroundNodes(getNodesNotLive());
+};
+
+export const restoreLinks = (baseOpacity, d, idx, collection) => {
+ /* in this case, it has just been clicked */
+ if (currentIsLive(idx, collection)) {
+ return;
+ }
+
+ /*
+ if there exist live links, reset to highlight out / pale
+ otherwise, reset to base
+ */
+
+ if (d3.selectAll(`.${IS_HIGHLIGHTED}`).empty()) {
+ renewLinks(d3.selectAll(`.${LINK_SELECTOR}`), baseOpacity);
+ renewNodes(d3.selectAll(`.${NODE_SELECTOR}`));
+ return;
+ }
+
+ backgroundLinks(getOtherLinks());
+ backgroundNodes(getNodesNotLive());
+};
+
+export const toggleLinkHighlight = (baseOpacity, d, idx, collection) => {
+ if (currentIsLive(idx, collection)) {
+ restorePath([d.uid], [d.source.uid, d.target.uid], baseOpacity);
+ return;
+ }
+
+ highlightPath([d.uid], [d.source.uid, d.target.uid]);
+};
+
+export const togglePathHighlights = (baseOpacity, d, idx, collection) => {
+ const parentLinks = getAllLinkAncestors(d);
+ const parentNodes = getAllNodeAncestors(d);
+ const currentNode = getCurrent(idx, collection);
+
+ /* if this node is already live, make it unlive and reset its path */
+ if (currentIsLive(idx, collection)) {
+ currentNode.classed(IS_HIGHLIGHTED, false);
+ restorePath(parentLinks, parentNodes, baseOpacity);
+ return;
+ }
+
+ highlightPath(parentLinks, parentNodes);
+};
diff --git a/app/assets/javascripts/pipelines/components/dag/parsing_utils.js b/app/assets/javascripts/pipelines/components/dag/parsing_utils.js
new file mode 100644
index 00000000000..3234f80ee91
--- /dev/null
+++ b/app/assets/javascripts/pipelines/components/dag/parsing_utils.js
@@ -0,0 +1,164 @@
+import { uniqWith, isEqual } from 'lodash';
+
+/*
+ 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:
+ [stages]
+ stages: {name, groups}
+ groups: [{ name, size, jobs }]
+ 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
+
+ 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, 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 NODES
+ stage.name -> node.category
+ stage.group.name -> node.name (this is the group name if there are parallel jobs)
+ stage.group.jobs -> node.jobs
+ stage.group.size -> node.size
+
+ CREATE LINKS
+ stages.groups.name -> target
+ stages.groups.needs.each -> source (source is the name of the group, not the parallel job)
+ 10 -> value (constant)
+ */
+
+export const createNodes = data => {
+ return data.flatMap(({ groups, name }) => {
+ return groups.map(group => {
+ return { ...group, category: name };
+ });
+ });
+};
+
+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 createNodesStructure = data => {
+ const nodes = createNodes(data);
+ const nodeDict = createNodeDict(nodes);
+
+ return { nodes, nodeDict };
+};
+
+export const makeLinksFromNodes = (nodes, nodeDict) => {
+ const constantLinkValue = 10; // all links are the same weight
+ return nodes
+ .map(group => {
+ return group.jobs.map(job => {
+ if (!job.needs) {
+ return [];
+ }
+
+ return job.needs.map(needed => {
+ return {
+ source: nodeDict[needed]?.name,
+ target: group.name,
+ value: constantLinkValue,
+ };
+ });
+ });
+ })
+ .flat(2);
+};
+
+export const getAllAncestors = (nodes, nodeDict) => {
+ const needs = nodes
+ .map(node => {
+ return nodeDict[node].needs || '';
+ })
+ .flat()
+ .filter(Boolean);
+
+ if (needs.length) {
+ return [...needs, ...getAllAncestors(needs, nodeDict)];
+ }
+
+ return [];
+};
+
+export const filterByAncestors = (links, nodeDict) =>
+ links.filter(({ target, source }) => {
+ /*
+
+ for every link, check out it's target
+ for every target, get the target node's needs
+ then drop the current link source from that list
+
+ call a function to get all ancestors, recursively
+ is the current link's source in the list of all parents?
+ then we drop this link
+
+ */
+ const targetNode = target;
+ const targetNodeNeeds = nodeDict[targetNode].needs;
+ const targetNodeNeedsMinusSource = targetNodeNeeds.filter(need => need !== source);
+
+ const allAncestors = getAllAncestors(targetNodeNeedsMinusSource, nodeDict);
+ return !allAncestors.includes(source);
+ });
+
+export const parseData = data => {
+ const { nodes, nodeDict } = createNodesStructure(data);
+ const allLinks = makeLinksFromNodes(nodes, nodeDict);
+ const filteredLinks = filterByAncestors(allLinks, nodeDict);
+ const links = uniqWith(filteredLinks, isEqual);
+
+ return { nodes, links };
+};
+
+/*
+ The number of nodes in the most populous generation drives the height of the graph.
+*/
+
+export const getMaxNodes = nodes => {
+ const counts = nodes.reduce((acc, { layer }) => {
+ if (!acc[layer]) {
+ acc[layer] = 0;
+ }
+
+ acc[layer] += 1;
+
+ return acc;
+ }, []);
+
+ return Math.max(...counts);
+};
+
+/*
+ Because we cannot know if a node is part of a relationship until after we
+ generate the links with createSankey, this function is used after the first call
+ to find nodes that have no relations.
+*/
+
+export const removeOrphanNodes = sankeyfiedNodes => {
+ return sankeyfiedNodes.filter(node => node.sourceLinks.length || node.targetLinks.length);
+};
diff --git a/app/assets/javascripts/pipelines/components/pipelines.vue b/app/assets/javascripts/pipelines/components/pipelines.vue
index fc93635bdb5..dbf29b0c29c 100644
--- a/app/assets/javascripts/pipelines/components/pipelines.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines.vue
@@ -10,7 +10,8 @@ import NavigationControls from './nav_controls.vue';
import { getParameterByName } from '../../lib/utils/common_utils';
import CIPaginationMixin from '../../vue_shared/mixins/ci_pagination_api_mixin';
import PipelinesFilteredSearch from './pipelines_filtered_search.vue';
-import { ANY_TRIGGER_AUTHOR, RAW_TEXT_WARNING } from '../constants';
+import { validateParams } from '../utils';
+import { ANY_TRIGGER_AUTHOR, RAW_TEXT_WARNING, FILTER_TAG_IDENTIFIER } from '../constants';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
export default {
@@ -86,6 +87,10 @@ export default {
type: String,
required: true,
},
+ params: {
+ type: Object,
+ required: true,
+ },
},
data() {
return {
@@ -220,10 +225,13 @@ export default {
canFilterPipelines() {
return this.glFeatures.filterPipelinesSearch;
},
+ validatedParams() {
+ return validateParams(this.params);
+ },
},
created() {
this.service = new PipelinesService(this.endpoint);
- this.requestData = { page: this.page, scope: this.scope };
+ this.requestData = { page: this.page, scope: this.scope, ...this.validatedParams };
},
methods: {
successCallback(resp) {
@@ -258,10 +266,18 @@ export default {
filters.forEach(filter => {
// do not add Any for username query param, so we
// can fetch all trigger authors
- if (filter.type && filter.value.data !== ANY_TRIGGER_AUTHOR) {
+ if (
+ filter.type &&
+ filter.value.data !== ANY_TRIGGER_AUTHOR &&
+ filter.type !== FILTER_TAG_IDENTIFIER
+ ) {
this.requestData[filter.type] = filter.value.data;
}
+ if (filter.type === FILTER_TAG_IDENTIFIER) {
+ this.requestData.ref = filter.value.data;
+ }
+
if (!filter.type) {
createFlash(RAW_TEXT_WARNING, 'warning');
}
@@ -304,8 +320,8 @@ export default {
<pipelines-filtered-search
v-if="canFilterPipelines"
- :pipelines="state.pipelines"
:project-id="projectId"
+ :params="validatedParams"
@filterPipelines="filterPipelines"
/>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_artifacts.vue b/app/assets/javascripts/pipelines/components/pipelines_artifacts.vue
index 2212428ced5..59c066b2683 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_artifacts.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_artifacts.vue
@@ -35,7 +35,7 @@ export default {
<ul class="dropdown-menu dropdown-menu-right">
<li v-for="(artifact, i) in artifacts" :key="i">
<gl-link :href="artifact.path" rel="nofollow" download
- >Download {{ artifact.name }} artifacts</gl-link
+ >Download {{ artifact.name }} artifact</gl-link
>
</li>
</ul>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_filtered_search.vue b/app/assets/javascripts/pipelines/components/pipelines_filtered_search.vue
index 8f9c3eb70a2..0505a8668d1 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_filtered_search.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_filtered_search.vue
@@ -3,74 +3,93 @@ import { GlFilteredSearch } from '@gitlab/ui';
import { __, s__ } from '~/locale';
import PipelineTriggerAuthorToken from './tokens/pipeline_trigger_author_token.vue';
import PipelineBranchNameToken from './tokens/pipeline_branch_name_token.vue';
-import Api from '~/api';
-import createFlash from '~/flash';
-import { FETCH_AUTHOR_ERROR_MESSAGE, FETCH_BRANCH_ERROR_MESSAGE } from '../constants';
+import PipelineStatusToken from './tokens/pipeline_status_token.vue';
+import PipelineTagNameToken from './tokens/pipeline_tag_name_token.vue';
+import { map } from 'lodash';
export default {
+ userType: 'username',
+ branchType: 'ref',
+ tagType: 'tag',
+ statusType: 'status',
+ defaultTokensLength: 1,
components: {
GlFilteredSearch,
},
props: {
- pipelines: {
- type: Array,
- required: true,
- },
projectId: {
type: String,
required: true,
},
+ params: {
+ type: Object,
+ required: true,
+ },
},
data() {
return {
- projectUsers: null,
- projectBranches: null,
+ internalValue: [],
};
},
computed: {
+ selectedTypes() {
+ return this.value.map(i => i.type);
+ },
tokens() {
return [
{
- type: 'username',
+ type: this.$options.userType,
icon: 'user',
title: s__('Pipeline|Trigger author'),
unique: true,
token: PipelineTriggerAuthorToken,
operators: [{ value: '=', description: __('is'), default: 'true' }],
- triggerAuthors: this.projectUsers,
projectId: this.projectId,
},
{
- type: 'ref',
+ type: this.$options.branchType,
icon: 'branch',
title: s__('Pipeline|Branch name'),
unique: true,
token: PipelineBranchNameToken,
operators: [{ value: '=', description: __('is'), default: 'true' }],
- branches: this.projectBranches,
projectId: this.projectId,
+ disabled: this.selectedTypes.includes(this.$options.tagType),
+ },
+ {
+ type: this.$options.tagType,
+ icon: 'tag',
+ title: s__('Pipeline|Tag name'),
+ unique: true,
+ token: PipelineTagNameToken,
+ operators: [{ value: '=', description: __('is'), default: 'true' }],
+ projectId: this.projectId,
+ disabled: this.selectedTypes.includes(this.$options.branchType),
+ },
+ {
+ type: this.$options.statusType,
+ icon: 'status',
+ title: s__('Pipeline|Status'),
+ unique: true,
+ token: PipelineStatusToken,
+ operators: [{ value: '=', description: __('is'), default: 'true' }],
},
];
},
- },
- created() {
- Api.projectUsers(this.projectId)
- .then(users => {
- this.projectUsers = users;
- })
- .catch(err => {
- createFlash(FETCH_AUTHOR_ERROR_MESSAGE);
- throw err;
- });
-
- Api.branches(this.projectId)
- .then(({ data }) => {
- this.projectBranches = data.map(branch => branch.name);
- })
- .catch(err => {
- createFlash(FETCH_BRANCH_ERROR_MESSAGE);
- throw err;
- });
+ parsedParams() {
+ return map(this.params, (val, key) => ({
+ type: key,
+ value: { data: val, operator: '=' },
+ }));
+ },
+ value: {
+ get() {
+ return this.internalValue.length > 0 ? this.internalValue : this.parsedParams;
+ },
+ set(value) {
+ this.internalValue = value;
+ },
+ },
},
methods: {
onSubmit(filters) {
@@ -83,6 +102,7 @@ export default {
<template>
<div class="row-content-block">
<gl-filtered-search
+ v-model="value"
:placeholder="__('Filter pipelines')"
:available-tokens="tokens"
@submit="onSubmit"
diff --git a/app/assets/javascripts/pipelines/components/test_reports/test_summary.vue b/app/assets/javascripts/pipelines/components/test_reports/test_summary.vue
index 80a1c83f171..67646c537bd 100644
--- a/app/assets/javascripts/pipelines/components/test_reports/test_summary.vue
+++ b/app/assets/javascripts/pipelines/components/test_reports/test_summary.vue
@@ -68,7 +68,7 @@ export default {
<template>
<div>
<div class="row">
- <div class="col-12 d-flex prepend-top-8 align-items-center">
+ <div class="col-12 d-flex gl-mt-3 align-items-center">
<gl-deprecated-button
v-if="showBack"
size="sm"
diff --git a/app/assets/javascripts/pipelines/components/tokens/pipeline_branch_name_token.vue b/app/assets/javascripts/pipelines/components/tokens/pipeline_branch_name_token.vue
index a7a3f986255..da14bb2d308 100644
--- a/app/assets/javascripts/pipelines/components/tokens/pipeline_branch_name_token.vue
+++ b/app/assets/javascripts/pipelines/components/tokens/pipeline_branch_name_token.vue
@@ -23,15 +23,18 @@ export default {
},
data() {
return {
- branches: this.config.branches,
+ branches: null,
loading: true,
};
},
+ created() {
+ this.fetchBranches();
+ },
methods: {
- fetchBranchBySearchTerm(searchTerm) {
- Api.branches(this.config.projectId, searchTerm)
- .then(res => {
- this.branches = res.data.map(branch => branch.name);
+ fetchBranches(searchterm) {
+ Api.branches(this.config.projectId, searchterm)
+ .then(({ data }) => {
+ this.branches = data.map(branch => branch.name);
this.loading = false;
})
.catch(err => {
@@ -41,7 +44,7 @@ export default {
});
},
searchBranches: debounce(function debounceSearch({ data }) {
- this.fetchBranchBySearchTerm(data);
+ this.fetchBranches(data);
}, FILTER_PIPELINES_SEARCH_DELAY),
},
};
diff --git a/app/assets/javascripts/pipelines/components/tokens/pipeline_status_token.vue b/app/assets/javascripts/pipelines/components/tokens/pipeline_status_token.vue
new file mode 100644
index 00000000000..dc43d94f4fd
--- /dev/null
+++ b/app/assets/javascripts/pipelines/components/tokens/pipeline_status_token.vue
@@ -0,0 +1,104 @@
+<script>
+import { GlFilteredSearchToken, GlFilteredSearchSuggestion, GlIcon } from '@gitlab/ui';
+import { s__ } from '~/locale';
+
+export default {
+ components: {
+ GlFilteredSearchToken,
+ GlFilteredSearchSuggestion,
+ GlIcon,
+ },
+ props: {
+ config: {
+ type: Object,
+ required: true,
+ },
+ value: {
+ type: Object,
+ required: true,
+ },
+ },
+ computed: {
+ statuses() {
+ return [
+ {
+ class: 'ci-status-icon-canceled',
+ icon: 'status_canceled',
+ text: s__('Pipeline|Canceled'),
+ value: 'canceled',
+ },
+ {
+ class: 'ci-status-icon-created',
+ icon: 'status_created',
+ text: s__('Pipeline|Created'),
+ value: 'created',
+ },
+ {
+ class: 'ci-status-icon-failed',
+ icon: 'status_failed',
+ text: s__('Pipeline|Failed'),
+ value: 'failed',
+ },
+ {
+ class: 'ci-status-icon-manual',
+ icon: 'status_manual',
+ text: s__('Pipeline|Manual'),
+ value: 'manual',
+ },
+ {
+ class: 'ci-status-icon-success',
+ icon: 'status_success',
+ text: s__('Pipeline|Passed'),
+ value: 'success',
+ },
+ {
+ class: 'ci-status-icon-pending',
+ icon: 'status_pending',
+ text: s__('Pipeline|Pending'),
+ value: 'pending',
+ },
+ {
+ class: 'ci-status-icon-running',
+ icon: 'status_running',
+ text: s__('Pipeline|Running'),
+ value: 'running',
+ },
+ {
+ class: 'ci-status-icon-skipped',
+ icon: 'status_skipped',
+ text: s__('Pipeline|Skipped'),
+ value: 'skipped',
+ },
+ ];
+ },
+ findActiveStatus() {
+ return this.statuses.find(status => status.value === this.value.data);
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-filtered-search-token v-bind="{ ...$props, ...$attrs }" v-on="$listeners">
+ <template #view>
+ <div class="gl-display-flex gl-align-items-center">
+ <div :class="findActiveStatus.class">
+ <gl-icon :name="findActiveStatus.icon" class="gl-mr-2 gl-display-block" />
+ </div>
+ <span>{{ findActiveStatus.text }}</span>
+ </div>
+ </template>
+ <template #suggestions>
+ <gl-filtered-search-suggestion
+ v-for="(status, index) in statuses"
+ :key="index"
+ :value="status.value"
+ >
+ <div class="gl-display-flex" :class="status.class">
+ <gl-icon :name="status.icon" class="gl-mr-3" />
+ <span>{{ status.text }}</span>
+ </div>
+ </gl-filtered-search-suggestion>
+ </template>
+ </gl-filtered-search-token>
+</template>
diff --git a/app/assets/javascripts/pipelines/components/tokens/pipeline_tag_name_token.vue b/app/assets/javascripts/pipelines/components/tokens/pipeline_tag_name_token.vue
new file mode 100644
index 00000000000..7b209c5fa12
--- /dev/null
+++ b/app/assets/javascripts/pipelines/components/tokens/pipeline_tag_name_token.vue
@@ -0,0 +1,64 @@
+<script>
+import { GlFilteredSearchToken, GlFilteredSearchSuggestion, GlLoadingIcon } from '@gitlab/ui';
+import Api from '~/api';
+import { FETCH_TAG_ERROR_MESSAGE, FILTER_PIPELINES_SEARCH_DELAY } from '../../constants';
+import createFlash from '~/flash';
+import { debounce } from 'lodash';
+
+export default {
+ components: {
+ GlFilteredSearchToken,
+ GlFilteredSearchSuggestion,
+ GlLoadingIcon,
+ },
+ props: {
+ config: {
+ type: Object,
+ required: true,
+ },
+ value: {
+ type: Object,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ tags: null,
+ loading: true,
+ };
+ },
+ created() {
+ this.fetchTags();
+ },
+ methods: {
+ fetchTags(searchTerm) {
+ Api.tags(this.config.projectId, searchTerm)
+ .then(({ data }) => {
+ this.tags = data.map(tag => tag.name);
+ this.loading = false;
+ })
+ .catch(err => {
+ createFlash(FETCH_TAG_ERROR_MESSAGE);
+ this.loading = false;
+ throw err;
+ });
+ },
+ searchTags: debounce(function debounceSearch({ data }) {
+ this.fetchTags(data);
+ }, FILTER_PIPELINES_SEARCH_DELAY),
+ },
+};
+</script>
+
+<template>
+ <gl-filtered-search-token v-bind="{ ...$props, ...$attrs }" v-on="$listeners" @input="searchTags">
+ <template #suggestions>
+ <gl-loading-icon v-if="loading" />
+ <template v-else>
+ <gl-filtered-search-suggestion v-for="(tag, index) in tags" :key="index" :value="tag">
+ {{ tag }}
+ </gl-filtered-search-suggestion>
+ </template>
+ </template>
+ </gl-filtered-search-token>
+</template>
diff --git a/app/assets/javascripts/pipelines/components/tokens/pipeline_trigger_author_token.vue b/app/assets/javascripts/pipelines/components/tokens/pipeline_trigger_author_token.vue
index 83e3558e1a1..4062a3b11bb 100644
--- a/app/assets/javascripts/pipelines/components/tokens/pipeline_trigger_author_token.vue
+++ b/app/assets/javascripts/pipelines/components/tokens/pipeline_trigger_author_token.vue
@@ -36,7 +36,7 @@ export default {
},
data() {
return {
- users: this.config.triggerAuthors,
+ users: [],
loading: true,
};
},
@@ -50,11 +50,14 @@ export default {
});
},
},
+ created() {
+ this.fetchProjectUsers();
+ },
methods: {
- fetchAuthorBySearchTerm(searchTerm) {
+ fetchProjectUsers(searchTerm) {
Api.projectUsers(this.config.projectId, searchTerm)
- .then(res => {
- this.users = res;
+ .then(users => {
+ this.users = users;
this.loading = false;
})
.catch(err => {
@@ -64,7 +67,7 @@ export default {
});
},
searchAuthors: debounce(function debounceSearch({ data }) {
- this.fetchAuthorBySearchTerm(data);
+ this.fetchProjectUsers(data);
}, FILTER_PIPELINES_SEARCH_DELAY),
},
};
diff --git a/app/assets/javascripts/pipelines/constants.js b/app/assets/javascripts/pipelines/constants.js
index d694430830b..c709f329728 100644
--- a/app/assets/javascripts/pipelines/constants.js
+++ b/app/assets/javascripts/pipelines/constants.js
@@ -5,6 +5,8 @@ export const PIPELINES_TABLE = 'PIPELINES_TABLE';
export const LAYOUT_CHANGE_DELAY = 300;
export const FILTER_PIPELINES_SEARCH_DELAY = 200;
export const ANY_TRIGGER_AUTHOR = 'Any';
+export const SUPPORTED_FILTER_PARAMETERS = ['username', 'ref', 'status'];
+export const FILTER_TAG_IDENTIFIER = 'tag';
export const TestStatus = {
FAILED: 'failed',
@@ -14,6 +16,7 @@ export const TestStatus = {
export const FETCH_AUTHOR_ERROR_MESSAGE = __('There was a problem fetching project users.');
export const FETCH_BRANCH_ERROR_MESSAGE = __('There was a problem fetching project branches.');
+export const FETCH_TAG_ERROR_MESSAGE = __('There was a problem fetching project tags.');
export const RAW_TEXT_WARNING = s__(
'Pipeline|Raw text search is not currently supported. Please use the available search tokens.',
);
diff --git a/app/assets/javascripts/pipelines/pipeline_details_bundle.js b/app/assets/javascripts/pipelines/pipeline_details_bundle.js
index 01295874e56..90109598542 100644
--- a/app/assets/javascripts/pipelines/pipeline_details_bundle.js
+++ b/app/assets/javascripts/pipelines/pipeline_details_bundle.js
@@ -4,6 +4,7 @@ import Translate from '~/vue_shared/translate';
import { __ } from '~/locale';
import { setUrlFragment, redirectTo } from '~/lib/utils/url_utility';
import pipelineGraph from './components/graph/graph_component.vue';
+import Dag from './components/dag/dag.vue';
import GraphBundleMixin from './mixins/graph_pipeline_bundle_mixin';
import PipelinesMediator from './pipeline_details_mediator';
import pipelineHeader from './components/header_component.vue';
@@ -144,6 +145,29 @@ const createTestDetails = detailsEndpoint => {
.catch(() => {});
};
+const createDagApp = () => {
+ if (!window.gon?.features?.dagPipelineTab) {
+ return;
+ }
+
+ const el = document.querySelector('#js-pipeline-dag-vue');
+ const graphUrl = el?.dataset?.pipelineDataPath;
+ // eslint-disable-next-line no-new
+ new Vue({
+ el,
+ components: {
+ Dag,
+ },
+ render(createElement) {
+ return createElement('dag', {
+ props: {
+ graphUrl,
+ },
+ });
+ },
+ });
+};
+
export default () => {
const { dataset } = document.querySelector('.js-pipeline-details-vue');
const mediator = new PipelinesMediator({ endpoint: dataset.endpoint });
@@ -153,4 +177,5 @@ export default () => {
createPipelineHeaderApp(mediator);
createPipelinesTabs(dataset);
createTestDetails(dataset.testReportsCountEndpoint);
+ createDagApp();
};
diff --git a/app/assets/javascripts/pipelines/services/pipelines_service.js b/app/assets/javascripts/pipelines/services/pipelines_service.js
index ae94d7a7ca0..0b06bcf243a 100644
--- a/app/assets/javascripts/pipelines/services/pipelines_service.js
+++ b/app/assets/javascripts/pipelines/services/pipelines_service.js
@@ -1,5 +1,6 @@
import axios from '../../lib/utils/axios_utils';
import Api from '~/api';
+import { validateParams } from '../utils';
export default class PipelinesService {
/**
@@ -19,18 +20,10 @@ export default class PipelinesService {
}
getPipelines(data = {}) {
- const { scope, page, username, ref } = data;
+ const { scope, page } = data;
const { CancelToken } = axios;
- const queryParams = { scope, page };
-
- if (username) {
- queryParams.username = username;
- }
-
- if (ref) {
- queryParams.ref = ref;
- }
+ const queryParams = { scope, page, ...validateParams(data) };
this.cancelationSource = CancelToken.source();
diff --git a/app/assets/javascripts/pipelines/utils.js b/app/assets/javascripts/pipelines/utils.js
new file mode 100644
index 00000000000..9dbc8073d3a
--- /dev/null
+++ b/app/assets/javascripts/pipelines/utils.js
@@ -0,0 +1,8 @@
+import { pickBy } from 'lodash';
+import { SUPPORTED_FILTER_PARAMETERS } from './constants';
+
+export const validateParams = params => {
+ return pickBy(params, (val, key) => SUPPORTED_FILTER_PARAMETERS.includes(key) && val);
+};
+
+export default () => {};
diff --git a/app/assets/javascripts/projects/commits/components/author_select.vue b/app/assets/javascripts/projects/commits/components/author_select.vue
index eb514b5c070..a8589b50899 100644
--- a/app/assets/javascripts/projects/commits/components/author_select.vue
+++ b/app/assets/javascripts/projects/commits/components/author_select.vue
@@ -110,8 +110,8 @@ export default {
<gl-new-dropdown
:text="dropdownText"
:disabled="hasSearchParam"
- toggle-class="gl-py-3"
- class="gl-dropdown w-100 mt-2 mt-sm-0"
+ toggle-class="gl-py-3 gl-border-0"
+ class="w-100 mt-2 mt-sm-0"
>
<gl-new-dropdown-header>
{{ __('Search by author') }}
diff --git a/app/assets/javascripts/projects/commits/store/actions.js b/app/assets/javascripts/projects/commits/store/actions.js
index a3a53c2f975..0a52a92ae9d 100644
--- a/app/assets/javascripts/projects/commits/store/actions.js
+++ b/app/assets/javascripts/projects/commits/store/actions.js
@@ -3,6 +3,7 @@ import * as types from './mutation_types';
import axios from '~/lib/utils/axios_utils';
import createFlash from '~/flash';
import { __ } from '~/locale';
+import { joinPaths } from '~/lib/utils/url_utility';
export default {
setInitialData({ commit }, data) {
@@ -16,10 +17,8 @@ export default {
},
fetchAuthors({ dispatch, state }, author = null) {
const { projectId } = state;
- const path = '/autocomplete/users.json';
-
return axios
- .get(path, {
+ .get(joinPaths(gon.relative_url_root || '', '/autocomplete/users.json'), {
params: {
project_id: projectId,
active: true,
diff --git a/app/assets/javascripts/projects/experiment_new_project_creation/components/app.vue b/app/assets/javascripts/projects/experiment_new_project_creation/components/app.vue
new file mode 100644
index 00000000000..e553599357c
--- /dev/null
+++ b/app/assets/javascripts/projects/experiment_new_project_creation/components/app.vue
@@ -0,0 +1,160 @@
+<script>
+import WelcomePage from './welcome.vue';
+import LegacyContainer from './legacy_container.vue';
+import { GlBreadcrumb, GlIcon } from '@gitlab/ui';
+import { __, s__ } from '~/locale';
+
+import blankProjectIllustration from '../illustrations/blank-project.svg';
+import createFromTemplateIllustration from '../illustrations/create-from-template.svg';
+import importProjectIllustration from '../illustrations/import-project.svg';
+import ciCdProjectIllustration from '../illustrations/ci-cd-project.svg';
+
+const BLANK_PANEL = 'blank_project';
+const CI_CD_PANEL = 'cicd_for_external_repo';
+const PANELS = [
+ {
+ name: BLANK_PANEL,
+ selector: '#blank-project-pane',
+ title: s__('ProjectsNew|Create blank project'),
+ description: s__(
+ 'ProjectsNew|Create a blank project to house your files, plan your work, and collaborate on code, among other things.',
+ ),
+ illustration: blankProjectIllustration,
+ },
+ {
+ name: 'create_from_template',
+ selector: '#create-from-template-pane',
+ title: s__('ProjectsNew|Create from template'),
+ description: s__(
+ 'Create a project pre-populated with the necessary files to get you started quickly.',
+ ),
+ illustration: createFromTemplateIllustration,
+ },
+ {
+ name: 'import_project',
+ selector: '#import-project-pane',
+ title: s__('ProjectsNew|Import project'),
+ description: s__(
+ 'Migrate your data from an external source like GitHub, Bitbucket, or another instance of GitLab.',
+ ),
+ illustration: importProjectIllustration,
+ },
+ {
+ name: CI_CD_PANEL,
+ selector: '#ci-cd-project-pane',
+ title: s__('ProjectsNew|Run CI/CD for external repository'),
+ description: s__('ProjectsNew|Connect your external repository to GitLab CI/CD.'),
+ illustration: ciCdProjectIllustration,
+ },
+];
+
+export default {
+ components: {
+ GlBreadcrumb,
+ GlIcon,
+ WelcomePage,
+ LegacyContainer,
+ },
+
+ props: {
+ hasErrors: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ isCiCdAvailable: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+
+ data() {
+ return {
+ activeTab: null,
+ };
+ },
+
+ computed: {
+ availablePanels() {
+ if (this.isCiCdAvailable) {
+ return PANELS;
+ }
+
+ return PANELS.filter(p => p.name !== CI_CD_PANEL);
+ },
+
+ activePanel() {
+ return PANELS.find(p => p.name === this.activeTab);
+ },
+
+ breadcrumbs() {
+ if (!this.activeTab || !this.activePanel) {
+ return null;
+ }
+
+ return [
+ { text: __('New project'), href: '#' },
+ { text: this.activePanel.title, href: `#${this.activeTab}` },
+ ];
+ },
+ },
+
+ created() {
+ this.handleLocationHashChange();
+
+ if (this.hasErrors) {
+ this.activeTab = BLANK_PANEL;
+ }
+
+ window.addEventListener('hashchange', () => {
+ this.handleLocationHashChange();
+ this.resetProjectErrors();
+ });
+ this.$root.$on('clicked::link', e => {
+ window.location = e.target.href;
+ });
+ },
+
+ methods: {
+ resetProjectErrors() {
+ const errorsContainer = document.querySelector('.project-edit-errors');
+ if (errorsContainer) {
+ errorsContainer.innerHTML = '';
+ }
+ },
+
+ handleLocationHashChange() {
+ this.activeTab = window.location.hash.substring(1) || null;
+ },
+ },
+
+ PANELS,
+};
+</script>
+
+<template>
+ <welcome-page v-if="activeTab === null" :panels="availablePanels" />
+ <div v-else class="row">
+ <div class="col-lg-3">
+ <div class="text-center" v-html="activePanel.illustration"></div>
+ <h4>{{ activePanel.title }}</h4>
+ <p>{{ activePanel.description }}</p>
+ </div>
+ <div class="col-lg-9">
+ <gl-breadcrumb v-if="breadcrumbs" :items="breadcrumbs">
+ <template #separator>
+ <gl-icon name="chevron-right" :size="8" />
+ </template>
+ </gl-breadcrumb>
+ <template v-for="panel in $options.PANELS">
+ <legacy-container
+ v-if="activeTab === panel.name"
+ :key="panel.name"
+ class="gl-mt-3"
+ :selector="panel.selector"
+ />
+ </template>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/projects/experiment_new_project_creation/components/legacy_container.vue b/app/assets/javascripts/projects/experiment_new_project_creation/components/legacy_container.vue
new file mode 100644
index 00000000000..d2fc2c66924
--- /dev/null
+++ b/app/assets/javascripts/projects/experiment_new_project_creation/components/legacy_container.vue
@@ -0,0 +1,31 @@
+<script>
+export default {
+ inheritAttrs: false,
+ props: {
+ selector: {
+ type: String,
+ required: true,
+ },
+ },
+ mounted() {
+ const legacyEntry = document.querySelector(this.selector);
+ if (legacyEntry.tagName === 'TEMPLATE') {
+ this.$el.innerHTML = legacyEntry.innerHTML;
+ } else {
+ this.source = legacyEntry.parentNode;
+ this.$el.appendChild(legacyEntry);
+ legacyEntry.classList.add('active');
+ }
+ },
+
+ beforeDestroy() {
+ if (this.source) {
+ this.$el.firstChild.classList.remove('active');
+ this.source.appendChild(this.$el.firstChild);
+ }
+ },
+};
+</script>
+<template>
+ <div></div>
+</template>
diff --git a/app/assets/javascripts/projects/experiment_new_project_creation/components/welcome.vue b/app/assets/javascripts/projects/experiment_new_project_creation/components/welcome.vue
new file mode 100644
index 00000000000..ea22818da0e
--- /dev/null
+++ b/app/assets/javascripts/projects/experiment_new_project_creation/components/welcome.vue
@@ -0,0 +1,70 @@
+<script>
+import Tracking from '~/tracking';
+import { GlPopover } from '@gitlab/ui';
+import LegacyContainer from './legacy_container.vue';
+
+const trackingMixin = Tracking.mixin(gon.tracking_data);
+
+export default {
+ components: {
+ GlPopover,
+ LegacyContainer,
+ },
+ mixins: [trackingMixin],
+ props: {
+ panels: {
+ type: Array,
+ required: true,
+ },
+ },
+};
+</script>
+<template>
+ <div class="container">
+ <div class="blank-state-welcome">
+ <h2 class="blank-state-welcome-title gl-mt-5! gl-mb-3!">
+ {{ s__('ProjectsNew|Create new project') }}
+ </h2>
+ <p div class="blank-state-text">&nbsp;</p>
+ </div>
+ <div class="row blank-state-row">
+ <a
+ v-for="panel in panels"
+ :key="panel.name"
+ :href="`#${panel.name}`"
+ :data-qa-selector="`${panel.name}_link`"
+ class="blank-state blank-state-link experiment-new-project-page-blank-state"
+ @click="track('click_tab', { label: panel.name })"
+ >
+ <div class="blank-state-icon" v-html="panel.illustration"></div>
+ <div class="blank-state-body gl-pl-4!">
+ <h3 class="blank-state-title experiment-new-project-page-blank-state-title">
+ {{ panel.title }}
+ </h3>
+ <p class="blank-state-text">
+ {{ panel.description }}
+ </p>
+ </div>
+ </a>
+ </div>
+ <div class="blank-state-welcome">
+ <p>
+ {{ __('You can also create a project from the command line.') }}
+ <a
+ id="cli-tip"
+ href="#"
+ click.prevent
+ class="push-new-project-tip"
+ data-title="Push to create a project"
+ rel="noopener noreferrer"
+ >
+ {{ __('Show command') }}
+ </a>
+
+ <gl-popover target="cli-tip" triggers="click blur" placement="top">
+ <legacy-container selector=".push-new-project-tip-template" />
+ </gl-popover>
+ </p>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/projects/experiment_new_project_creation/illustrations/blank-project.svg b/app/assets/javascripts/projects/experiment_new_project_creation/illustrations/blank-project.svg
new file mode 100644
index 00000000000..0d8021658d1
--- /dev/null
+++ b/app/assets/javascripts/projects/experiment_new_project_creation/illustrations/blank-project.svg
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="215px" height="115px" viewBox="0 0 215 115" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: Sketch 61.2 (89653) - https://sketch.com -->
+ <title>create-new-project-md</title>
+ <desc>Created with Sketch.</desc>
+ <g id="create-new-project-md" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="Group-3" transform="translate(71.000000, 18.000000)" fill-rule="nonzero">
+ <g id="New-Blank1">
+ <path d="M6.11141667,3.90697674 L62.6947849,3.90697674 C65.9485064,3.90697674 68.5891473,6.56494969 68.5891473,9.8400273 L68.5891473,78.0669494 C68.5891473,81.342027 65.9485064,84 62.6947849,84 L6.11141667,84 C2.85769514,84 0.217054264,81.342027 0.217054264,78.0669494 L0.217054264,9.8400273 C0.217054264,6.56494969 2.85769514,3.90697674 6.11141667,3.90697674 Z" id="Path" fill="#F9F9F9"></path>
+ <path d="M8.89436241,1 L65.4777306,1 C68.7314521,1 71.372093,3.65598929 71.372093,6.9286227 L71.372093,74.5132378 C71.372093,77.7858712 68.7314521,80.4418605 65.4777306,80.4418605 L8.89436241,80.4418605 C5.64064088,80.4418605 3,77.7858712 3,74.5132378 L3,6.9286227 C3.00209243,3.65598929 5.64064088,1 8.89436241,1 Z" id="Path" fill="#FFFFFF"></path>
+ <path d="M9.2677971,2.35980136 C6.65357171,2.35980136 4.53489427,4.47043114 4.53489427,7.07940407 L4.53489427,74.3201325 C4.53489427,76.9270116 6.65147193,79.0397352 9.2677971,79.0397352 L66.0500324,79.0397352 C68.6642577,79.0397352 70.7829352,76.9291055 70.7829352,74.3201325 L70.7829352,7.07731019 C70.7829352,4.47043114 68.6663575,2.35770748 66.0500324,2.35770748 L9.2677971,2.35980136 L9.2677971,2.35980136 Z M9.2677971,0 L66.0500324,0 C69.9724203,0 73.1472868,3.16803856 73.1472868,7.07731019 L73.1472868,74.3180386 C73.1472868,78.2294042 69.9703205,81.3953488 66.0500324,81.3953488 L9.2677971,81.3953488 C5.34540913,81.3953488 2.17054264,78.2273103 2.17054264,74.3180386 L2.17054264,7.07731019 C2.17054264,3.17222631 5.34750891,0 9.2677971,0 Z" id="Shape" fill="#EEEEEE"></path>
+ <path d="M21.6234891,28.6511628 L28.9501543,28.6511628 C29.6221266,28.6511628 30.1705426,29.2387129 30.1705426,29.9534884 C30.1705426,30.6682639 29.6199589,31.255814 28.9501543,31.255814 L21.6234891,31.255814 C20.9515168,31.255814 20.4031008,30.6682639 20.4031008,29.9534884 C20.4031008,29.2387129 20.9515168,28.6511628 21.6234891,28.6511628 Z" id="Path" fill="#E1DBF1"></path>
+ <path d="M33.9142229,35.8139535 L36.1943042,35.8139535 C36.8214783,35.8139535 37.3333333,36.4015036 37.3333333,37.1162791 C37.3333333,37.8333678 36.8194552,38.4186047 36.1943042,38.4186047 L33.9142229,38.4186047 C33.2870488,38.4186047 32.7751938,37.8310546 32.7751938,37.1162791 C32.7751938,36.4015036 33.2890719,35.8139535 33.9142229,35.8139535 Z" id="Path" fill="#FC6D26"></path>
+ <path d="M24.200844,42.9767442 L28.9774506,42.9767442 C29.6343929,42.9767442 30.1705426,43.5642943 30.1705426,44.2790698 C30.1705426,44.9961585 29.6322737,45.5813953 28.9774506,45.5813953 L24.200844,45.5813953 C23.5439017,45.5813953 23.0077519,44.9938453 23.0077519,44.2790698 C23.0077519,43.5642943 23.5439017,42.9767442 24.200844,42.9767442 Z" id="Path" fill="#E1DBF1"></path>
+ <path d="M41.0770181,35.8139535 L43.3570964,35.8139535 C43.9842697,35.8139535 44.496124,36.4015036 44.496124,37.1162791 C44.496124,37.8333678 43.9822466,38.4186047 43.3570964,38.4186047 L41.0770181,38.4186047 C40.4498448,38.4186047 39.9379845,37.8310546 39.9379845,37.1162791 C39.9359673,36.4015036 40.4498448,35.8139535 41.0770181,35.8139535 Z" id="Path" fill="#FC6D26"></path>
+ <path d="M33.9372473,28.6511628 L47.89221,28.6511628 C48.5320619,28.6511628 49.0542636,29.2387129 49.0542636,29.9534884 C49.0542636,30.6682639 48.5299978,31.255814 47.89221,31.255814 L33.9372473,31.255814 C33.2973955,31.255814 32.7751938,30.6682639 32.7751938,29.9534884 C32.7751938,29.2387129 33.2994595,28.6511628 33.9372473,28.6511628 Z" id="Path" fill="#C3B8E3"></path>
+ <path d="M33.9142229,42.9767442 L36.1943042,42.9767442 C36.8214783,42.9767442 37.3333333,43.5642943 37.3333333,44.2790698 C37.3333333,44.9961585 36.8194552,45.5813953 36.1943042,45.5813953 L33.9142229,45.5813953 C33.2870488,45.5813953 32.7751938,44.9938453 32.7751938,44.2790698 C32.7751938,43.5642943 33.2890719,42.9767442 33.9142229,42.9767442 Z" id="Path" fill="#6B4FBB"></path>
+ <g id="Group" transform="translate(16.000000, 19.000000)">
+ <circle id="Oval" fill="#FFFFFF" cx="20.8396947" cy="20.8396947" r="20.7533889"></circle>
+ <path d="M20.8396947,41.5930835 C9.3778626,41.5930835 0.0863058062,32.3015267 0.0863058062,20.8396947 C0.0863058062,9.3778626 9.3778626,0.0863058062 20.8396947,0.0863058062 C32.3015267,0.0863058062 41.5930835,9.3778626 41.5930835,20.8396947 C41.5930835,32.3015267 32.3015267,41.5930835 20.8396947,41.5930835 Z M20.8396947,39.2207263 C30.9922045,39.2207263 39.2207263,30.9900995 39.2207263,20.8396947 C39.2207263,10.6892898 30.9900995,2.45866297 20.8396947,2.45866297 C10.6892898,2.45866297 2.45866297,10.6892898 2.45866297,20.8396947 C2.45866297,30.9900995 10.6871848,39.2207263 20.8396947,39.2207263 Z" id="Shape" fill="#EEEEEE"></path>
+ <path d="M13.7647236,19.060953 L27.9967615,19.060953 C28.6493176,19.060953 29.1818876,19.595628 29.1818876,20.2460791 C29.1818876,20.8986352 28.6472126,21.4312052 27.9967615,21.4312052 L13.7647236,21.4312052 C13.1121675,21.4312052 12.5795975,20.8965302 12.5795975,20.2460791 C12.5795975,19.593523 13.1142725,19.060953 13.7647236,19.060953 Z" id="Path" fill="#6B4FBB"></path>
+ <path d="M22.0669211,13.1311127 L22.0669211,27.3631506 C22.0669211,28.0157067 21.5322461,28.5482767 20.881795,28.5482767 C20.231344,28.5482767 19.696669,28.0136017 19.696669,27.3631506 L19.696669,13.1311127 C19.696669,12.4785566 20.231344,11.9459866 20.881795,11.9459866 C21.5322461,11.9459866 22.0669211,12.4785566 22.0669211,13.1311127 Z" id="Path" fill="#6B4FBB"></path>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/app/assets/javascripts/projects/experiment_new_project_creation/illustrations/ci-cd-project.svg b/app/assets/javascripts/projects/experiment_new_project_creation/illustrations/ci-cd-project.svg
new file mode 100644
index 00000000000..c85e1a245b8
--- /dev/null
+++ b/app/assets/javascripts/projects/experiment_new_project_creation/illustrations/ci-cd-project.svg
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="215px" height="115px" viewBox="0 0 215 115" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: Sketch 61.2 (89653) - https://sketch.com -->
+ <title>run-CICD-pipelines-md</title>
+ <desc>Created with Sketch.</desc>
+ <g id="run-CICD-pipelines-md" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="CICD-Repoj1" transform="translate(22.000000, 16.000000)">
+ <g id="Group" transform="translate(100.000000, 0.000000)">
+ <path d="M5.88230137,4.144 L61.8884384,4.144 C65.1195616,4.144 67.7155068,6.804 67.7155068,10.052 L67.7155068,78.064 C67.7155068,81.34 65.0919452,83.972 61.8884384,83.972 L5.88230137,83.972 C2.65117808,83.972 0.0552328767,81.312 0.0552328767,78.064 L0.0552328767,10.052 C0.0552328767,6.804 2.67879452,4.144 5.88230137,4.144 Z" id="Path" fill="#F9F9F9" fill-rule="nonzero"></path>
+ <path d="M8.80964384,1.176 L64.8157808,1.176 C68.0469041,1.176 70.6428493,3.836 70.6428493,7.084 L70.6428493,74.508 C70.6428493,77.784 68.0192877,80.416 64.8157808,80.416 L8.80964384,80.416 C5.57852055,80.416 2.98257534,77.756 2.98257534,74.508 L2.98257534,7.112 C2.98257534,3.836 5.57852055,1.176 8.80964384,1.176 Z" id="Path" fill="#FFFFFF" fill-rule="nonzero"></path>
+ <path d="M8.80964384,2.38 C6.24131507,2.38 4.14246575,4.508 4.14246575,7.112 L4.14246575,74.536 C4.14246575,77.14 6.24131507,79.268 8.80964384,79.268 L64.8157808,79.268 C67.3841096,79.268 69.4829589,77.14 69.4829589,74.536 L69.4829589,7.112 C69.4829589,4.508 67.3841096,2.38 64.8157808,2.38 L8.80964384,2.38 L8.80964384,2.38 Z M8.80964384,0 L64.8157808,0 C68.6820822,0 71.8027397,3.164 71.8027397,7.084 L71.8027397,74.508 C71.8027397,78.428 68.6820822,81.592 64.8157808,81.592 L8.80964384,81.592 C4.94334247,81.592 1.82250462,78.4 1.82250462,74.508 L1.82250462,7.112 C1.79506849,3.192 4.94334247,0 8.80964384,0 Z" id="Shape" fill="#EEEEEE" fill-rule="nonzero"></path>
+ <path d="M14.6367123,14.784 L21.6236712,14.784 C22.2588493,14.784 22.7835616,15.316 22.7835616,15.96 C22.7835616,16.604 22.2588493,17.136 21.6236712,17.136 L14.6367123,17.136 C14.0015342,17.136 13.4768219,16.604 13.4768219,15.96 C13.4768219,15.316 14.0015342,14.784 14.6367123,14.784 Z M33.3054247,21.896 L40.2923836,21.896 C40.9275616,21.896 41.452274,22.428 41.452274,23.072 C41.452274,23.716 40.9275616,24.248 40.2923836,24.248 L33.3054247,24.248 C32.6702466,24.248 32.1455342,23.716 32.1455342,23.072 C32.1455342,22.428 32.6702466,21.896 33.3054247,21.896 Z" id="Shape" fill="#E1DBF1" fill-rule="nonzero"></path>
+ <path d="M40.32,14.784 L47.3069589,14.784 C47.942137,14.784 48.4668493,15.316 48.4668493,15.96 C48.4668493,16.604 47.942137,17.136 47.3069589,17.136 L40.32,17.136 C39.6848219,17.136 39.1601096,16.604 39.1601096,15.96 C39.1324932,15.316 39.6572055,14.784 40.32,14.784 Z" id="Path" fill="#EEEEEE" fill-rule="nonzero"></path>
+ <path d="M21.6512877,28.98 L28.6382466,28.98 C29.2734247,28.98 29.798137,29.512 29.798137,30.156 C29.798137,30.8 29.2734247,31.332 28.6382466,31.332 L21.6512877,31.332 C21.0161096,31.332 20.4913973,30.8 20.4913973,30.156 C20.4637808,29.512 20.9884932,28.98 21.6512877,28.98 Z" id="Path" fill="#E1DBF1" fill-rule="nonzero"></path>
+ <path d="M26.2908493,14.784 L28.6382466,14.784 C29.2734247,14.784 29.798137,15.316 29.798137,15.96 C29.798137,16.604 29.2734247,17.136 28.6382466,17.136 L26.2908493,17.136 C25.6556712,17.136 25.1309589,16.604 25.1309589,15.96 C25.1309589,15.316 25.6556712,14.784 26.2908493,14.784 Z" id="Path" fill="#FEE1D3" fill-rule="nonzero"></path>
+ <path d="M33.3054247,36.092 L35.6528219,36.092 C36.288,36.092 36.8127123,36.624 36.8127123,37.268 C36.8127123,37.912 36.288,38.444 35.6528219,38.444 L33.3054247,38.444 C32.6702466,38.444 32.1455342,37.912 32.1455342,37.268 C32.1455342,36.624 32.6702466,36.092 33.3054247,36.092 Z" id="Path" fill="#FC6D26" fill-rule="nonzero"></path>
+ <path d="M44.9595616,21.896 L47.3069589,21.896 C47.942137,21.896 48.4668493,22.428 48.4668493,23.072 C48.4668493,23.716 47.942137,24.248 47.3069589,24.248 L44.9595616,24.248 C44.3243836,24.248 43.7996712,23.716 43.7996712,23.072 C43.7996712,22.428 44.3243836,21.896 44.9595616,21.896 Z M51.974137,14.784 L54.3215342,14.784 C54.9567123,14.784 55.4814247,15.316 55.4814247,15.96 C55.4814247,16.604 54.9567123,17.136 54.3215342,17.136 L51.974137,17.136 C51.3389589,17.136 50.8142466,16.604 50.8142466,15.96 C50.8142466,15.316 51.3389589,14.784 51.974137,14.784 Z" id="Shape" fill="#FEF0E8" fill-rule="nonzero"></path>
+ <path d="M23.9710685,43.176 L28.6382466,43.176 C29.2734247,43.176 29.798137,43.708 29.798137,44.352 C29.798137,44.996 29.2734247,45.528 28.6382466,45.528 L23.9710685,45.528 C23.3358904,45.528 22.8111781,44.996 22.8111781,44.352 C22.8111781,43.708 23.3358904,43.176 23.9710685,43.176 Z" id="Path" fill="#E1DBF1" fill-rule="nonzero"></path>
+ <path d="M40.32,36.092 L42.6673973,36.092 C43.3025753,36.092 43.8272877,36.624 43.8272877,37.268 C43.8272877,37.912 43.3025753,38.444 42.6673973,38.444 L40.32,38.444 C39.6848219,38.444 39.1601096,37.912 39.1601096,37.268 C39.1324932,36.624 39.6572055,36.092 40.32,36.092 Z" id="Path" fill="#FC6D26" fill-rule="nonzero"></path>
+ <path d="M52.2503014,33.712 C53.0511781,33.712 53.7139726,34.384 53.7139726,35.196 C53.7139726,36.008 53.0511781,36.68 52.2503014,36.68 C51.4494247,36.68 50.7866301,36.008 50.7866301,35.196 C50.8142466,34.384 51.4494247,33.712 52.2503014,33.712 Z M58.1049863,50.876 C58.905863,50.876 59.5686575,51.548 59.5686575,52.36 C59.5686575,53.172 58.905863,53.844 58.1049863,53.844 C57.3041096,53.844 56.6413151,53.172 56.6413151,52.36 C56.6413151,51.548 57.3041096,50.876 58.1049863,50.876 Z" id="Shape" fill="#E1DBF1" fill-rule="nonzero"></path>
+ <path d="M63.3521096,50.876 C64.1529863,50.876 64.8157808,51.548 64.8157808,52.36 C64.8157808,53.172 64.1529863,53.844 63.3521096,53.844 C62.5512329,53.844 61.8884384,53.172 61.8884384,52.36 C61.8884384,51.548 62.5512329,50.876 63.3521096,50.876 Z M33.3054247,14.784 L35.6528219,14.784 C36.288,14.784 36.8127123,15.316 36.8127123,15.96 C36.8127123,16.604 36.288,17.136 35.6528219,17.136 L33.3054247,17.136 C32.6702466,17.136 32.1455342,16.604 32.1455342,15.96 C32.1455342,15.316 32.6702466,14.784 33.3054247,14.784 Z" id="Shape" fill="#FC6D26" fill-rule="nonzero"></path>
+ <path d="M14.6367123,36.092 L28.6382466,36.092 C29.2734247,36.092 29.798137,36.624 29.798137,37.268 C29.798137,37.912 29.2734247,38.444 28.6382466,38.444 L14.6367123,38.444 C14.0015342,38.444 13.4768219,37.912 13.4768219,37.268 C13.4768219,36.624 14.0015342,36.092 14.6367123,36.092 Z M44.0482192,42 L61.0599452,42 C61.8332055,42 62.4683836,42.672 62.4683836,43.484 C62.4683836,44.296 61.8332055,44.968 61.0599452,44.968 L44.0758356,44.968 C43.3025753,44.968 42.6673973,44.296 42.6673973,43.484 C42.6673973,42.672 43.2749589,42 44.0482192,42 L44.0482192,42 L44.0482192,42 Z" id="Shape" fill="#EEEEEE" fill-rule="nonzero"></path>
+ <path d="M35.3214247,50.876 L52.3055342,50.876 C53.0787945,50.876 53.7139726,51.548 53.7139726,52.36 C53.7139726,53.172 53.0787945,53.844 52.3055342,53.844 L35.3214247,53.844 C34.5481644,53.844 33.9129863,53.172 33.9129863,52.36 C33.8853699,51.548 34.5205479,50.876 35.3214247,50.876 L35.3214247,50.876 L35.3214247,50.876 Z" id="Path" fill="#EFEDF8" fill-rule="nonzero"></path>
+ <path d="M14.6367123,21.896 L28.6382466,21.896 C29.2734247,21.896 29.798137,22.428 29.798137,23.072 C29.798137,23.716 29.2734247,24.248 28.6382466,24.248 L14.6367123,24.248 C14.0015342,24.248 13.4768219,23.716 13.4768219,23.072 C13.4768219,22.428 14.0015342,21.896 14.6367123,21.896 Z" id="Path" fill="#6B4FBB" fill-rule="nonzero"></path>
+ <path d="M33.3054247,28.98 L47.3069589,28.98 C47.942137,28.98 48.4668493,29.512 48.4668493,30.156 C48.4668493,30.8 47.942137,31.332 47.3069589,31.332 L33.3054247,31.332 C32.6702466,31.332 32.1455342,30.8 32.1455342,30.156 C32.1455342,29.512 32.6702466,28.98 33.3054247,28.98 Z" id="Path" fill="#C3B8E3" fill-rule="nonzero"></path>
+ <path d="M14.6367123,28.98 L16.9841096,28.98 C17.6192877,28.98 18.144,29.512 18.144,30.156 C18.144,30.8 17.6192877,31.332 16.9841096,31.332 L14.6367123,31.332 C14.0015342,31.332 13.4768219,30.8 13.4768219,30.156 C13.4768219,29.512 14.0015342,28.98 14.6367123,28.98 Z" id="Path" fill="#FEF0E8" fill-rule="nonzero"></path>
+ <path d="M33.3054247,43.176 L35.6528219,43.176 C36.288,43.176 36.8127123,43.708 36.8127123,44.352 C36.8127123,44.996 36.288,45.528 35.6528219,45.528 L33.3054247,45.528 C32.6702466,45.528 32.1455342,44.996 32.1455342,44.352 C32.1455342,43.708 32.6702466,43.176 33.3054247,43.176 Z" id="Path" fill="#6B4FBB" fill-rule="nonzero"></path>
+ <path d="M14.6367123,43.176 L19.3038904,43.176 C19.9390685,43.176 20.4637808,43.708 20.4637808,44.352 C20.4637808,44.996 19.9390685,45.528 19.3038904,45.528 L14.6367123,45.528 C14.0015342,45.528 13.4768219,44.996 13.4768219,44.352 C13.4768219,43.708 14.0015342,43.176 14.6367123,43.176 Z" id="Path" fill="#FC6D26" fill-rule="nonzero"></path>
+ <path d="M14.6367123,50.288 L19.3038904,50.288 C19.9390685,50.288 20.4637808,50.82 20.4637808,51.464 C20.4637808,52.108 19.9390685,52.64 19.3038904,52.64 L14.6367123,52.64 C14.0015342,52.64 13.4768219,52.108 13.4768219,51.464 C13.4768219,50.82 14.0015342,50.288 14.6367123,50.288 Z M23.9710685,50.288 L28.6382466,50.288 C29.2734247,50.288 29.798137,50.82 29.798137,51.464 C29.798137,52.108 29.2734247,52.64 28.6382466,52.64 L23.9710685,52.64 C23.3358904,52.64 22.8111781,52.108 22.8111781,51.464 C22.8111781,50.82 23.3358904,50.288 23.9710685,50.288 Z" id="Shape" fill="#FEF0E8" fill-rule="nonzero"></path>
+ <path d="M14.6367123,57.372 L21.6236712,57.372 C22.2588493,57.372 22.7835616,57.904 22.7835616,58.548 C22.7835616,59.192 22.2588493,59.724 21.6236712,59.724 L14.6367123,59.724 C14.0015342,59.724 13.4768219,59.192 13.4768219,58.548 C13.4768219,57.904 14.0015342,57.372 14.6367123,57.372 Z" id="Path" fill="#EFEDF8" fill-rule="nonzero"></path>
+ <path d="M25.3518904,64.484 L33.6644384,64.484 C34.4376986,64.484 35.0452603,65.016 35.0452603,65.66 C35.0452603,66.304 34.4376986,66.836 33.6644384,66.836 L25.3518904,66.836 C24.5786301,66.836 23.9710685,66.304 23.9710685,65.66 C23.9710685,65.016 24.5786301,64.484 25.3518904,64.484 Z" id="Path" fill="#FC6D26" fill-rule="nonzero"></path>
+ <path d="M44.0206027,59.136 L52.3331507,59.136 C53.106411,59.136 53.7139726,59.808 53.7139726,60.62 C53.7139726,61.432 53.106411,62.104 52.3331507,62.104 L44.0206027,62.104 C43.2473425,62.104 42.6397808,61.432 42.6397808,60.62 C42.6397808,59.808 43.2473425,59.136 44.0206027,59.136 Z" id="Path" fill="#6B4FBB" fill-rule="nonzero"></path>
+ <path d="M26.2908493,57.372 L28.6382466,57.372 C29.2734247,57.372 29.798137,57.904 29.798137,58.548 C29.798137,59.192 29.2734247,59.724 28.6382466,59.724 L26.2908493,59.724 C25.6556712,59.724 25.1309589,59.192 25.1309589,58.548 C25.1309589,57.904 25.6556712,57.372 26.2908493,57.372 Z" id="Path" fill="#FEE1D3" fill-rule="nonzero"></path>
+ <path d="M36.8127123,64.484 L39.1601096,64.484 C39.7952877,64.484 40.32,65.016 40.32,65.66 C40.32,66.304 39.7952877,66.836 39.1601096,66.836 L36.8127123,66.836 C36.1775342,66.836 35.6528219,66.304 35.6528219,65.66 C35.6528219,65.016 36.1775342,64.484 36.8127123,64.484 Z M58.1049863,59.136 L61.0323288,59.136 C61.8332055,59.136 62.496,59.808 62.496,60.62 C62.496,61.432 61.8332055,62.104 61.0323288,62.104 L58.1049863,62.104 C57.3041096,62.104 56.6413151,61.432 56.6413151,60.62 C56.6413151,59.808 57.3041096,59.136 58.1049863,59.136 Z" id="Shape" fill="#FEF0E8" fill-rule="nonzero"></path>
+ <path d="M35.3490411,59.136 L38.2763836,59.136 C39.0772603,59.136 39.7400548,59.808 39.7400548,60.62 C39.7400548,61.432 39.0772603,62.104 38.2763836,62.104 L35.3490411,62.104 C34.5481644,62.104 33.8853699,61.432 33.8853699,60.62 C33.8853699,59.808 34.5481644,59.136 35.3490411,59.136 Z" id="Path" fill="#FC6D26" fill-rule="nonzero"></path>
+ <path d="M14.6367123,64.484 L20.4637808,64.484 C21.0989589,64.484 21.6236712,65.016 21.6236712,65.66 C21.6236712,66.304 21.0989589,66.836 20.4637808,66.836 L14.6367123,66.836 C14.0015342,66.836 13.4768219,66.304 13.4768219,65.66 C13.4768219,65.016 14.0015342,64.484 14.6367123,64.484 Z" id="Path" fill="#EEEEEE" fill-rule="nonzero"></path>
+ <ellipse id="Oval" fill="#FFFFFF" fill-rule="nonzero" cx="36.7574795" cy="38.612" rx="20.4085479" ry="20.692"></ellipse>
+ <path d="M36.7574795,59.304 C25.4899726,59.304 16.3489315,50.036 16.3489315,38.612 C16.3489315,27.188 25.4899726,17.92 36.7574795,17.92 C48.0249863,17.92 57.1660274,27.188 57.1660274,38.612 C57.1660274,50.036 48.0526027,59.304 36.7574795,59.304 Z M36.7574795,56.952 C46.7546301,56.952 54.8462466,48.748 54.8462466,38.612 C54.8462466,28.476 46.7546301,20.272 36.7574795,20.272 C26.7603288,20.272 18.6687123,28.476 18.6687123,38.612 C18.6687123,48.748 26.7879452,56.952 36.7574795,56.952 Z" id="Shape" fill="#EEEEEE" fill-rule="nonzero"></path>
+ <g transform="translate(26.787945, 29.400000)" id="Path">
+ <path d="M19.7457534,10.528 L18.6410959,7.112 L16.4593973,0.336 C16.3489315,7.97972799e-15 15.8794521,7.97972799e-15 15.7413699,0.336 L13.5872877,7.112 L6.37939726,7.112 L4.19769863,0.336 C4.08723288,7.97972799e-15 3.61775342,7.97972799e-15 3.47967123,0.336 L1.2979726,7.112 L0.193315068,10.528 C0.0828493151,10.836 0.193315068,11.172 0.469479452,11.368 L9.94191781,18.34 L19.4143562,11.368 C19.718137,11.172 19.8286027,10.836 19.7457534,10.528" fill="#FC6D26"></path>
+ <polygon fill="#E24329" points="9.96953425 18.34 13.5596712 7.112 6.35178082 7.112"></polygon>
+ <polygon fill="#FC6D26" points="9.96953425 18.34 6.37939726 7.112 1.32558904 7.112"></polygon>
+ <path d="M1.32558904,7.112 L0.220931507,10.528 C0.110465753,10.836 0.220931507,11.172 0.49709589,11.368 L9.96953425,18.34 L1.32558904,7.112 Z" fill="#FCA326"></path>
+ <path d="M1.32558904,7.112 L6.37939726,7.112 L4.19769863,0.336 C4.08723288,7.9658502e-15 3.61775342,7.9658502e-15 3.47967123,0.336 L1.32558904,7.112 Z" fill="#E24329"></path>
+ <polygon fill="#FC6D26" points="9.96953425 18.34 13.5596712 7.112 18.6134795 7.112"></polygon>
+ <path d="M18.6410959,7.112 L19.7457534,10.528 C19.8562192,10.836 19.7457534,11.172 19.469589,11.368 L9.99715068,18.34 L18.6410959,7.112 Z" fill="#FCA326"></path>
+ <path d="M18.6410959,7.112 L13.5872877,7.112 L15.7689863,0.336 C15.8794521,7.9658502e-15 16.3489315,7.9658502e-15 16.4870137,0.336 L18.6410959,7.112 Z" fill="#E24329"></path>
+ </g>
+ </g>
+ <path d="M76,41.475 C76,40.660967 76.8066938,40 77.8150611,40 L81.4537653,40 C82.4578417,40 83.2688264,40.6540094 83.2688264,41.475 C83.2688264,42.289033 82.4621326,42.95 81.4537653,42.95 L77.8150611,42.95 C76.8152757,42.95 76,42.2959906 76,41.4819575 C76,41.4784788 76,41.4784788 76,41.475 Z M88.7311736,41.475 C88.7311736,40.660967 89.5378674,40 90.5462347,40 L94.1849389,40 C95.1890152,40 96,40.6540094 96,41.475 C96,42.289033 95.1933062,42.95 94.1849389,42.95 L90.5462347,42.95 C89.5464493,42.95 88.7311736,42.2959906 88.7311736,41.4819575 C88.7311736,41.4784788 88.7311736,41.4784788 88.7311736,41.475 Z" id="Shape" fill="#E5E5E5" fill-rule="nonzero"></path>
+ <g id="Group">
+ <g transform="translate(3.686038, 58.800000)">
+ <path d="M6.33328302,0.207529412 L17.1233208,0.207529412 C20.541283,0.207529412 23.2890566,3.04376471 23.2890566,6.57176471 L23.2890566,17.7091765 C23.2890566,21.2025882 20.541283,24.0734118 17.1233208,24.0734118 L6.33328302,24.0734118 C2.94883019,24.0734118 0.16754717,21.2371765 0.16754717,17.7091765 L0.16754717,6.57176471 C0.16754717,3.04376471 2.91532075,0.207529412 6.33328302,0.207529412 Z" id="Path" fill="#FFFFFF"></path>
+ <path d="M6.33328302,3.38964706 C4.62430189,3.38964706 3.25041509,4.80776471 3.25041509,6.57176471 L3.25041509,17.7091765 C3.25041509,19.4731765 4.62430189,20.8912941 6.33328302,20.8912941 L17.1233208,20.8912941 C18.8323019,20.8912941 20.2061887,19.4731765 20.2061887,17.7091765 L20.2061887,6.57176471 C20.2061887,4.80776471 18.8323019,3.38964706 17.1233208,3.38964706 L6.33328302,3.38964706 Z M6.33328302,0.207529412 L17.1233208,0.207529412 C20.541283,0.207529412 23.2890566,3.04376471 23.2890566,6.57176471 L23.2890566,17.7091765 C23.2890566,21.2025882 20.541283,24.0734118 17.1233208,24.0734118 L6.33328302,24.0734118 C2.94883019,24.0734118 0.16754717,21.2371765 0.16754717,17.7091765 L0.16754717,6.57176471 C0.16754717,3.04376471 2.91532075,0.207529412 6.33328302,0.207529412 Z" id="Shape" fill="#E1DBF1" fill-rule="nonzero"></path>
+ <path d="M11.7283019,8.12823529 L11.7283019,8.12823529 C13.8393962,8.12823529 15.5818868,9.89223529 15.5818868,12.1058824 L15.5818868,12.1058824 C15.5818868,14.3195294 13.8729057,16.0835294 11.7283019,16.0835294 L11.7283019,16.0835294 C9.61720755,16.0835294 7.87471698,14.3195294 7.87471698,12.1058824 L7.87471698,12.1058824 C7.87471698,9.92682353 9.58369811,8.12823529 11.7283019,8.12823529 Z" id="Path" fill="#6B4FBB"></path>
+ </g>
+ <path d="M4.62430189,3.35505882 C3.78656604,3.35505882 3.08286792,4.08141176 3.08286792,4.94611765 L3.08286792,14.4924706 C3.08286792,15.3571765 3.78656604,16.0835294 4.62430189,16.0835294 L13.8729057,16.0835294 C14.7106415,16.0835294 15.4143396,15.3571765 15.4143396,14.4924706 L15.4143396,4.94611765 C15.4143396,4.08141176 14.7106415,3.35505882 13.8729057,3.35505882 L4.62430189,3.35505882 Z" id="Path" fill="#FFFFFF"></path>
+ <path d="M4.62430189,3.35505882 C3.78656604,3.35505882 3.08286792,4.08141176 3.08286792,4.94611765 L3.08286792,14.4924706 C3.08286792,15.3571765 3.78656604,16.0835294 4.62430189,16.0835294 L13.8729057,16.0835294 C14.7106415,16.0835294 15.4143396,15.3571765 15.4143396,14.4924706 L15.4143396,4.94611765 C15.4143396,4.08141176 14.7106415,3.35505882 13.8729057,3.35505882 L4.62430189,3.35505882 Z M4.62430189,0.172941176 L13.8729057,0.172941176 C16.4196226,0.172941176 18.4972075,2.31741176 18.4972075,4.94611765 L18.4972075,14.4924706 C18.4972075,17.1211765 16.4196226,19.2656471 13.8729057,19.2656471 L4.62430189,19.2656471 C2.07758491,19.2656471 -1.19049424e-15,17.1211765 -1.19049424e-15,14.4924706 L-1.19049424e-15,4.94611765 C-1.19049424e-15,2.31741176 2.07758491,0.172941176 4.62430189,0.172941176 Z" id="Shape" fill="#FDC4A8" fill-rule="nonzero"></path>
+ <path d="M9.24860377,6.53717647 L9.24860377,6.53717647 C10.9575849,6.53717647 12.3314717,7.95529412 12.3314717,9.71929412 L12.3314717,9.71929412 C12.3314717,11.4832941 10.9575849,12.9014118 9.24860377,12.9014118 L9.24860377,12.9014118 C7.53962264,12.9014118 6.16573585,11.4832941 6.16573585,9.71929412 L6.16573585,9.71929412 C6.16573585,7.95529412 7.53962264,6.53717647 9.24860377,6.53717647 Z" id="Path" fill="#FC6D26"></path>
+ <g transform="translate(35.184906, 23.174118)">
+ <path d="M7.94173585,1.62564706 L27.9803774,1.62564706 C32.2360755,1.62564706 35.6875472,5.18823529 35.6875472,9.58094118 L35.6875472,30.2647059 C35.6875472,34.6574118 32.2360755,38.22 27.9803774,38.22 L7.94173585,38.22 C3.68603774,38.22 0.234566038,34.6574118 0.234566038,30.2647059 L0.234566038,9.58094118 C0.234566038,5.18823529 3.68603774,1.62564706 7.94173585,1.62564706 Z" id="Path" fill="#E1DBF1"></path>
+ <path d="M7.94173585,0.0345882353 L27.9803774,0.0345882353 C32.2360755,0.0345882353 35.6875472,3.59717647 35.6875472,7.98988235 L35.6875472,28.6736471 C35.6875472,33.0663529 32.2360755,36.6289412 27.9803774,36.6289412 L7.94173585,36.6289412 C3.68603774,36.6289412 0.234566038,33.0663529 0.234566038,28.6736471 L0.234566038,7.98988235 C0.234566038,3.59717647 3.68603774,0.0345882353 7.94173585,0.0345882353 Z" id="Path" fill="#E1DBF1"></path>
+ <path d="M7.94173585,3.21670588 C5.39501887,3.21670588 3.31743396,5.36117647 3.31743396,7.98988235 L3.31743396,28.6736471 C3.31743396,31.3023529 5.39501887,33.4468235 7.94173585,33.4468235 L27.9803774,33.4468235 C30.5270943,33.4468235 32.6046792,31.3023529 32.6046792,28.6736471 L32.6046792,7.98988235 C32.6046792,5.36117647 30.5270943,3.21670588 27.9803774,3.21670588 C27.9468679,3.21670588 7.94173585,3.21670588 7.94173585,3.21670588 Z M7.94173585,0.0345882353 L27.9803774,0.0345882353 C32.2360755,0.0345882353 35.6875472,3.59717647 35.6875472,7.98988235 L35.6875472,28.6736471 C35.6875472,33.0663529 32.2360755,36.6289412 27.9803774,36.6289412 L7.94173585,36.6289412 C3.68603774,36.6289412 0.234566038,33.0663529 0.234566038,28.6736471 L0.234566038,7.98988235 C0.234566038,3.59717647 3.68603774,0.0345882353 7.94173585,0.0345882353 Z" id="Shape" fill="#C3B8E3" fill-rule="nonzero"></path>
+ <path d="M14.1074717,12.7630588 L21.8146415,12.7630588 C22.6523774,12.7630588 23.3560755,13.4894118 23.3560755,14.3541176 L23.3560755,22.3094118 C23.3560755,23.1741176 22.6523774,23.9004706 21.8146415,23.9004706 L14.1074717,23.9004706 C13.2697358,23.9004706 12.5660377,23.1741176 12.5660377,22.3094118 L12.5660377,14.3541176 C12.5660377,13.4894118 13.2362264,12.7630588 14.1074717,12.7630588 Z" id="Path" fill="#6B4FBB"></path>
+ </g>
+ <path d="M32.6716981,71.4592941 C32.0685283,72.0818824 31.0967547,72.0818824 30.4935849,71.4592941 C29.8904151,70.8367059 29.8904151,69.8336471 30.4935849,69.2110588 L32.1355472,67.5162353 C32.738717,66.8936471 33.7104906,66.8936471 34.3136604,67.5162353 C34.9168302,68.1388235 34.9168302,69.1418824 34.3136604,69.7644706 L32.6716981,71.4592941 Z" id="Path" fill="#C3B8E3" fill-rule="nonzero"></path>
+ <path d="M37.5640755,66.4094118 C36.9609057,67.032 35.9891321,67.032 35.3859623,66.4094118 C34.7827925,65.7868235 34.7827925,64.7837647 35.3859623,64.1611765 L37.0279245,62.4663529 C37.6310943,61.8437647 38.6028679,61.8437647 39.2060377,62.4663529 C39.8092075,63.0889412 39.8092075,64.092 39.2060377,64.7145882 L37.5640755,66.4094118 Z" id="Path" fill="#E1DBF1"></path>
+ <path d="M21.3455094,21.2717647 C20.7088302,20.7183529 20.6083019,19.7152941 21.1444528,19.0235294 C21.6806038,18.3663529 22.6523774,18.2625882 23.322566,18.816 L25.098566,20.3378824 C25.7352453,20.8912941 25.8357736,21.8943529 25.2996226,22.5861176 C24.7634717,23.2432941 23.7916981,23.3470588 23.1215094,22.7936471 L21.3455094,21.2717647 Z" id="Path" fill="#E1DBF1" fill-rule="nonzero"></path>
+ <path d="M26.64,25.872 C26.0033208,25.3185882 25.9027925,24.3155294 26.4389434,23.6237647 C26.9750943,22.9665882 27.9468679,22.8628235 28.6170566,23.4162353 L30.3930566,24.9381176 C31.0297358,25.4915294 31.1302642,26.4945882 30.5941132,27.1863529 C30.0579623,27.8781176 29.0861887,27.9472941 28.416,27.3938824 L26.64,25.872 Z" id="Path" fill="#C3B8E3"></path>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/app/assets/javascripts/projects/experiment_new_project_creation/illustrations/create-from-template.svg b/app/assets/javascripts/projects/experiment_new_project_creation/illustrations/create-from-template.svg
new file mode 100644
index 00000000000..e90c354fe65
--- /dev/null
+++ b/app/assets/javascripts/projects/experiment_new_project_creation/illustrations/create-from-template.svg
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="215px" height="115px" viewBox="0 0 215 115" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: Sketch 61.2 (89653) - https://sketch.com -->
+ <title>create-project-from-template-md</title>
+ <desc>Created with Sketch.</desc>
+ <g id="create-project-from-template-md" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="New-Template1" transform="translate(71.000000, 15.000000)">
+ <g id="Group">
+ <path d="M5.88230137,4.144 L61.8884384,4.144 C65.1195616,4.144 67.7155068,6.804 67.7155068,10.052 L67.7155068,78.064 C67.7155068,81.34 65.0919452,83.972 61.8884384,83.972 L5.88230137,83.972 C2.65117808,83.972 0.0552328767,81.312 0.0552328767,78.064 L0.0552328767,10.052 C0.0552328767,6.804 2.67879452,4.144 5.88230137,4.144 Z" id="Path" fill="#F9F9F9" fill-rule="nonzero"></path>
+ <path d="M8.82706849,1 L64.8332055,1 C68.0643288,1 70.660274,3.66 70.660274,6.908 L70.660274,74.332 C70.660274,77.608 68.0367123,80.24 64.8332055,80.24 L8.82706849,80.24 C5.59594521,80.24 3,77.58 3,74.332 L3,6.936 C3,3.66 5.59594521,1 8.82706849,1 Z" id="Path" fill="#FFFFFF" fill-rule="nonzero"></path>
+ <path d="M8.80964384,2.38 C6.24131507,2.38 4.14246575,4.508 4.14246575,7.112 L4.14246575,74.536 C4.14246575,77.14 6.24131507,79.268 8.80964384,79.268 L64.8157808,79.268 C67.3841096,79.268 69.4829589,77.14 69.4829589,74.536 L69.4829589,7.112 C69.4829589,4.508 67.3841096,2.38 64.8157808,2.38 L8.80964384,2.38 L8.80964384,2.38 Z M8.80964384,0 L64.8157808,0 C68.6820822,0 71.8027397,3.164 71.8027397,7.084 L71.8027397,74.508 C71.8027397,78.428 68.6820822,81.592 64.8157808,81.592 L8.80964384,81.592 C4.94334247,81.592 1.82250462,78.4 1.82250462,74.508 L1.82250462,7.112 C1.79506849,3.192 4.94334247,0 8.80964384,0 Z" id="Shape" fill="#EEEEEE" fill-rule="nonzero"></path>
+ <path d="M14.6367123,14.784 L21.6236712,14.784 C22.2588493,14.784 22.7835616,15.316 22.7835616,15.96 C22.7835616,16.604 22.2588493,17.136 21.6236712,17.136 L14.6367123,17.136 C14.0015342,17.136 13.4768219,16.604 13.4768219,15.96 C13.4768219,15.316 14.0015342,14.784 14.6367123,14.784 Z M33.3054247,21.896 L40.2923836,21.896 C40.9275616,21.896 41.452274,22.428 41.452274,23.072 C41.452274,23.716 40.9275616,24.248 40.2923836,24.248 L33.3054247,24.248 C32.6702466,24.248 32.1455342,23.716 32.1455342,23.072 C32.1455342,22.428 32.6702466,21.896 33.3054247,21.896 Z" id="Shape" fill="#E1DBF1" fill-rule="nonzero"></path>
+ <path d="M40.32,14.784 L47.3069589,14.784 C47.942137,14.784 48.4668493,15.316 48.4668493,15.96 C48.4668493,16.604 47.942137,17.136 47.3069589,17.136 L40.32,17.136 C39.6848219,17.136 39.1601096,16.604 39.1601096,15.96 C39.1324932,15.316 39.6572055,14.784 40.32,14.784 Z" id="Path" fill="#EEEEEE" fill-rule="nonzero"></path>
+ <path d="M21.6512877,28.98 L28.6382466,28.98 C29.2734247,28.98 29.798137,29.512 29.798137,30.156 C29.798137,30.8 29.2734247,31.332 28.6382466,31.332 L21.6512877,31.332 C21.0161096,31.332 20.4913973,30.8 20.4913973,30.156 C20.4637808,29.512 20.9884932,28.98 21.6512877,28.98 Z" id="Path" fill="#E1DBF1" fill-rule="nonzero"></path>
+ <path d="M26.2908493,14.784 L28.6382466,14.784 C29.2734247,14.784 29.798137,15.316 29.798137,15.96 C29.798137,16.604 29.2734247,17.136 28.6382466,17.136 L26.2908493,17.136 C25.6556712,17.136 25.1309589,16.604 25.1309589,15.96 C25.1309589,15.316 25.6556712,14.784 26.2908493,14.784 Z" id="Path" fill="#FEE1D3" fill-rule="nonzero"></path>
+ <path d="M33.3054247,36.092 L35.6528219,36.092 C36.288,36.092 36.8127123,36.624 36.8127123,37.268 C36.8127123,37.912 36.288,38.444 35.6528219,38.444 L33.3054247,38.444 C32.6702466,38.444 32.1455342,37.912 32.1455342,37.268 C32.1455342,36.624 32.6702466,36.092 33.3054247,36.092 Z" id="Path" fill="#FC6D26" fill-rule="nonzero"></path>
+ <path d="M44.9595616,21.896 L47.3069589,21.896 C47.942137,21.896 48.4668493,22.428 48.4668493,23.072 C48.4668493,23.716 47.942137,24.248 47.3069589,24.248 L44.9595616,24.248 C44.3243836,24.248 43.7996712,23.716 43.7996712,23.072 C43.7996712,22.428 44.3243836,21.896 44.9595616,21.896 Z M51.974137,14.784 L54.3215342,14.784 C54.9567123,14.784 55.4814247,15.316 55.4814247,15.96 C55.4814247,16.604 54.9567123,17.136 54.3215342,17.136 L51.974137,17.136 C51.3389589,17.136 50.8142466,16.604 50.8142466,15.96 C50.8142466,15.316 51.3389589,14.784 51.974137,14.784 Z" id="Shape" fill="#FEF0E8" fill-rule="nonzero"></path>
+ <path d="M23.9710685,43.176 L28.6382466,43.176 C29.2734247,43.176 29.798137,43.708 29.798137,44.352 C29.798137,44.996 29.2734247,45.528 28.6382466,45.528 L23.9710685,45.528 C23.3358904,45.528 22.8111781,44.996 22.8111781,44.352 C22.8111781,43.708 23.3358904,43.176 23.9710685,43.176 Z" id="Path" fill="#E1DBF1" fill-rule="nonzero"></path>
+ <path d="M40.32,36.092 L42.6673973,36.092 C43.3025753,36.092 43.8272877,36.624 43.8272877,37.268 C43.8272877,37.912 43.3025753,38.444 42.6673973,38.444 L40.32,38.444 C39.6848219,38.444 39.1601096,37.912 39.1601096,37.268 C39.1324932,36.624 39.6572055,36.092 40.32,36.092 Z" id="Path" fill="#FC6D26" fill-rule="nonzero"></path>
+ <path d="M52.2503014,33.712 C53.0511781,33.712 53.7139726,34.384 53.7139726,35.196 C53.7139726,36.008 53.0511781,36.68 52.2503014,36.68 C51.4494247,36.68 50.7866301,36.008 50.7866301,35.196 C50.8142466,34.384 51.4494247,33.712 52.2503014,33.712 Z M58.1049863,50.876 C58.905863,50.876 59.5686575,51.548 59.5686575,52.36 C59.5686575,53.172 58.905863,53.844 58.1049863,53.844 C57.3041096,53.844 56.6413151,53.172 56.6413151,52.36 C56.6413151,51.548 57.3041096,50.876 58.1049863,50.876 Z" id="Shape" fill="#E1DBF1" fill-rule="nonzero"></path>
+ <path d="M63.3521096,50.876 C64.1529863,50.876 64.8157808,51.548 64.8157808,52.36 C64.8157808,53.172 64.1529863,53.844 63.3521096,53.844 C62.5512329,53.844 61.8884384,53.172 61.8884384,52.36 C61.8884384,51.548 62.5512329,50.876 63.3521096,50.876 Z M33.3054247,14.784 L35.6528219,14.784 C36.288,14.784 36.8127123,15.316 36.8127123,15.96 C36.8127123,16.604 36.288,17.136 35.6528219,17.136 L33.3054247,17.136 C32.6702466,17.136 32.1455342,16.604 32.1455342,15.96 C32.1455342,15.316 32.6702466,14.784 33.3054247,14.784 Z" id="Shape" fill="#FC6D26" fill-rule="nonzero"></path>
+ <path d="M14.6367123,36.092 L28.6382466,36.092 C29.2734247,36.092 29.798137,36.624 29.798137,37.268 C29.798137,37.912 29.2734247,38.444 28.6382466,38.444 L14.6367123,38.444 C14.0015342,38.444 13.4768219,37.912 13.4768219,37.268 C13.4768219,36.624 14.0015342,36.092 14.6367123,36.092 Z M44.0482192,42 L61.0599452,42 C61.8332055,42 62.4683836,42.672 62.4683836,43.484 C62.4683836,44.296 61.8332055,44.968 61.0599452,44.968 L44.0758356,44.968 C43.3025753,44.968 42.6673973,44.296 42.6673973,43.484 C42.6673973,42.672 43.2749589,42 44.0482192,42 L44.0482192,42 L44.0482192,42 Z" id="Shape" fill="#EEEEEE" fill-rule="nonzero"></path>
+ <path d="M35.3214247,50.876 L52.3055342,50.876 C53.0787945,50.876 53.7139726,51.548 53.7139726,52.36 C53.7139726,53.172 53.0787945,53.844 52.3055342,53.844 L35.3214247,53.844 C34.5481644,53.844 33.9129863,53.172 33.9129863,52.36 C33.8853699,51.548 34.5205479,50.876 35.3214247,50.876 L35.3214247,50.876 L35.3214247,50.876 Z" id="Path" fill="#EFEDF8" fill-rule="nonzero"></path>
+ <path d="M14.6367123,21.896 L28.6382466,21.896 C29.2734247,21.896 29.798137,22.428 29.798137,23.072 C29.798137,23.716 29.2734247,24.248 28.6382466,24.248 L14.6367123,24.248 C14.0015342,24.248 13.4768219,23.716 13.4768219,23.072 C13.4768219,22.428 14.0015342,21.896 14.6367123,21.896 Z" id="Path" fill="#6B4FBB" fill-rule="nonzero"></path>
+ <path d="M33.3054247,28.98 L47.3069589,28.98 C47.942137,28.98 48.4668493,29.512 48.4668493,30.156 C48.4668493,30.8 47.942137,31.332 47.3069589,31.332 L33.3054247,31.332 C32.6702466,31.332 32.1455342,30.8 32.1455342,30.156 C32.1455342,29.512 32.6702466,28.98 33.3054247,28.98 Z" id="Path" fill="#C3B8E3" fill-rule="nonzero"></path>
+ <path d="M14.6367123,28.98 L16.9841096,28.98 C17.6192877,28.98 18.144,29.512 18.144,30.156 C18.144,30.8 17.6192877,31.332 16.9841096,31.332 L14.6367123,31.332 C14.0015342,31.332 13.4768219,30.8 13.4768219,30.156 C13.4768219,29.512 14.0015342,28.98 14.6367123,28.98 Z" id="Path" fill="#FEF0E8" fill-rule="nonzero"></path>
+ <path d="M33.3054247,43.176 L35.6528219,43.176 C36.288,43.176 36.8127123,43.708 36.8127123,44.352 C36.8127123,44.996 36.288,45.528 35.6528219,45.528 L33.3054247,45.528 C32.6702466,45.528 32.1455342,44.996 32.1455342,44.352 C32.1455342,43.708 32.6702466,43.176 33.3054247,43.176 Z" id="Path" fill="#6B4FBB" fill-rule="nonzero"></path>
+ <path d="M14.6367123,43.176 L19.3038904,43.176 C19.9390685,43.176 20.4637808,43.708 20.4637808,44.352 C20.4637808,44.996 19.9390685,45.528 19.3038904,45.528 L14.6367123,45.528 C14.0015342,45.528 13.4768219,44.996 13.4768219,44.352 C13.4768219,43.708 14.0015342,43.176 14.6367123,43.176 Z" id="Path" fill="#FC6D26" fill-rule="nonzero"></path>
+ <path d="M14.6367123,50.288 L19.3038904,50.288 C19.9390685,50.288 20.4637808,50.82 20.4637808,51.464 C20.4637808,52.108 19.9390685,52.64 19.3038904,52.64 L14.6367123,52.64 C14.0015342,52.64 13.4768219,52.108 13.4768219,51.464 C13.4768219,50.82 14.0015342,50.288 14.6367123,50.288 Z M23.9710685,50.288 L28.6382466,50.288 C29.2734247,50.288 29.798137,50.82 29.798137,51.464 C29.798137,52.108 29.2734247,52.64 28.6382466,52.64 L23.9710685,52.64 C23.3358904,52.64 22.8111781,52.108 22.8111781,51.464 C22.8111781,50.82 23.3358904,50.288 23.9710685,50.288 Z" id="Shape" fill="#FEF0E8" fill-rule="nonzero"></path>
+ <path d="M14.6367123,57.372 L21.6236712,57.372 C22.2588493,57.372 22.7835616,57.904 22.7835616,58.548 C22.7835616,59.192 22.2588493,59.724 21.6236712,59.724 L14.6367123,59.724 C14.0015342,59.724 13.4768219,59.192 13.4768219,58.548 C13.4768219,57.904 14.0015342,57.372 14.6367123,57.372 Z" id="Path" fill="#EFEDF8" fill-rule="nonzero"></path>
+ <path d="M25.3518904,64.484 L33.6644384,64.484 C34.4376986,64.484 35.0452603,65.016 35.0452603,65.66 C35.0452603,66.304 34.4376986,66.836 33.6644384,66.836 L25.3518904,66.836 C24.5786301,66.836 23.9710685,66.304 23.9710685,65.66 C23.9710685,65.016 24.5786301,64.484 25.3518904,64.484 Z" id="Path" fill="#FC6D26" fill-rule="nonzero"></path>
+ <path d="M44.0206027,59.136 L52.3331507,59.136 C53.106411,59.136 53.7139726,59.808 53.7139726,60.62 C53.7139726,61.432 53.106411,62.104 52.3331507,62.104 L44.0206027,62.104 C43.2473425,62.104 42.6397808,61.432 42.6397808,60.62 C42.6397808,59.808 43.2473425,59.136 44.0206027,59.136 Z" id="Path" fill="#6B4FBB" fill-rule="nonzero"></path>
+ <path d="M26.2908493,57.372 L28.6382466,57.372 C29.2734247,57.372 29.798137,57.904 29.798137,58.548 C29.798137,59.192 29.2734247,59.724 28.6382466,59.724 L26.2908493,59.724 C25.6556712,59.724 25.1309589,59.192 25.1309589,58.548 C25.1309589,57.904 25.6556712,57.372 26.2908493,57.372 Z" id="Path" fill="#FEE1D3" fill-rule="nonzero"></path>
+ <path d="M36.8127123,64.484 L39.1601096,64.484 C39.7952877,64.484 40.32,65.016 40.32,65.66 C40.32,66.304 39.7952877,66.836 39.1601096,66.836 L36.8127123,66.836 C36.1775342,66.836 35.6528219,66.304 35.6528219,65.66 C35.6528219,65.016 36.1775342,64.484 36.8127123,64.484 Z M58.1049863,59.136 L61.0323288,59.136 C61.8332055,59.136 62.496,59.808 62.496,60.62 C62.496,61.432 61.8332055,62.104 61.0323288,62.104 L58.1049863,62.104 C57.3041096,62.104 56.6413151,61.432 56.6413151,60.62 C56.6413151,59.808 57.3041096,59.136 58.1049863,59.136 Z" id="Shape" fill="#FEF0E8" fill-rule="nonzero"></path>
+ <path d="M35.3490411,59.136 L38.2763836,59.136 C39.0772603,59.136 39.7400548,59.808 39.7400548,60.62 C39.7400548,61.432 39.0772603,62.104 38.2763836,62.104 L35.3490411,62.104 C34.5481644,62.104 33.8853699,61.432 33.8853699,60.62 C33.8853699,59.808 34.5481644,59.136 35.3490411,59.136 Z" id="Path" fill="#FC6D26" fill-rule="nonzero"></path>
+ <path d="M14.6367123,64.484 L20.4637808,64.484 C21.0989589,64.484 21.6236712,65.016 21.6236712,65.66 C21.6236712,66.304 21.0989589,66.836 20.4637808,66.836 L14.6367123,66.836 C14.0015342,66.836 13.4768219,66.304 13.4768219,65.66 C13.4768219,65.016 14.0015342,64.484 14.6367123,64.484 Z" id="Path" fill="#EEEEEE" fill-rule="nonzero"></path>
+ <g id="Group-2" transform="translate(16.000000, 20.000000)">
+ <ellipse id="Oval" fill="#FFFFFF" fill-rule="nonzero" cx="20.4085479" cy="20.692" rx="20.4085479" ry="20.692"></ellipse>
+ <path d="M20.4085479,41.384 C9.1410411,41.384 8.17124146e-14,32.116 8.17124146e-14,20.692 C8.17124146e-14,9.268 9.1410411,1.0658141e-14 20.4085479,1.0658141e-14 C31.6760548,1.0658141e-14 40.8170959,9.268 40.8170959,20.692 C40.8170959,32.116 31.7036712,41.384 20.4085479,41.384 Z M20.4085479,39.032 C30.4056986,39.032 38.4973151,30.828 38.4973151,20.692 C38.4973151,10.556 30.4056986,2.352 20.4085479,2.352 C10.4113973,2.352 2.31978082,10.556 2.31978082,20.692 C2.31978082,30.828 10.4390137,39.032 20.4085479,39.032 Z" id="Shape" fill="#EEEEEE" fill-rule="nonzero"></path>
+ <g id="Group" transform="translate(10.439014, 11.480000)">
+ <path d="M19.7457534,10.528 L18.6410959,7.112 L16.4593973,0.336 C16.3489315,7.97972799e-15 15.8794521,7.97972799e-15 15.7413699,0.336 L13.5872877,7.112 L6.37939726,7.112 L4.19769863,0.336 C4.08723288,7.97972799e-15 3.61775342,7.97972799e-15 3.47967123,0.336 L1.2979726,7.112 L0.193315068,10.528 C0.0828493151,10.836 0.193315068,11.172 0.469479452,11.368 L9.94191781,18.34 L19.4143562,11.368 C19.718137,11.172 19.8286027,10.836 19.7457534,10.528" id="Path" fill="#FC6D26"></path>
+ <polygon id="Path" fill="#E24329" points="9.96953425 18.34 13.5596712 7.112 6.35178082 7.112"></polygon>
+ <polygon id="Path" fill="#FC6D26" points="9.96953425 18.34 6.37939726 7.112 1.32558904 7.112"></polygon>
+ <path d="M1.32558904,7.112 L0.220931507,10.528 C0.110465753,10.836 0.220931507,11.172 0.49709589,11.368 L9.96953425,18.34 L1.32558904,7.112 Z" id="Path" fill="#FCA326"></path>
+ <path d="M1.32558904,7.112 L6.37939726,7.112 L4.19769863,0.336 C4.08723288,7.9658502e-15 3.61775342,7.9658502e-15 3.47967123,0.336 L1.32558904,7.112 Z" id="Path" fill="#E24329"></path>
+ <polygon id="Path" fill="#FC6D26" points="9.96953425 18.34 13.5596712 7.112 18.6134795 7.112"></polygon>
+ <path d="M18.6410959,7.112 L19.7457534,10.528 C19.8562192,10.836 19.7457534,11.172 19.469589,11.368 L9.99715068,18.34 L18.6410959,7.112 Z" id="Path" fill="#FCA326"></path>
+ <path d="M18.6410959,7.112 L13.5872877,7.112 L15.7689863,0.336 C15.8794521,7.9658502e-15 16.3489315,7.9658502e-15 16.4870137,0.336 L18.6410959,7.112 Z" id="Path" fill="#E24329"></path>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/app/assets/javascripts/projects/experiment_new_project_creation/illustrations/import-project.svg b/app/assets/javascripts/projects/experiment_new_project_creation/illustrations/import-project.svg
new file mode 100644
index 00000000000..c507fb8d73d
--- /dev/null
+++ b/app/assets/javascripts/projects/experiment_new_project_creation/illustrations/import-project.svg
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="215px" height="115px" viewBox="0 0 215 115" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: Sketch 61.2 (89653) - https://sketch.com -->
+ <title>import-project-md</title>
+ <desc>Created with Sketch.</desc>
+ <g id="import-project-md" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="Group-4" transform="translate(14.000000, 15.000000)">
+ <g id="Group-7" transform="translate(0.000000, 0.007864)" fill-rule="nonzero">
+ <path d="M5.84551724,4.12490066 L61.9641379,4.12490066 C65.1917241,4.12490066 67.8096552,6.76450331 67.8096552,10.0188079 L67.8096552,77.8001325 C67.8096552,81.0544371 65.1917241,83.6940397 61.9641379,83.6940397 L5.84551724,83.6940397 C2.61793103,83.6940397 2.84217094e-14,81.0544371 2.84217094e-14,77.8001325 L2.84217094e-14,10.0188079 C2.84217094e-14,6.76450331 2.61793103,4.12490066 5.84551724,4.12490066 Z" id="Path" fill="#F9F9F9"></path>
+ <path d="M8.76965517,1.17933775 L64.8882759,1.17933775 C68.1158621,1.17933775 70.7337931,3.8189404 70.7337931,7.07324503 L70.7337931,74.2649007 C70.7337931,77.5192053 68.1158621,80.1588079 64.8882759,80.1588079 L8.76965517,80.1588079 C5.54206897,80.1588079 2.92413793,77.5192053 2.92413793,74.2649007 L2.92413793,7.07324503 C2.92413793,3.81615894 5.53931034,1.17933775 8.76965517,1.17933775 Z" id="Path" fill="#FFFFFF"></path>
+ <path d="M64.8882759,2.20268248e-13 C68.7613793,2.20268248e-13 71.9034483,3.16807947 71.9034483,7.07324503 L71.9024828,19.847 L69.5634828,19.847 L69.5641379,7.07324503 C69.5641379,4.46980132 67.4703448,2.3586755 64.8882759,2.3586755 L8.76965517,2.3586755 L8.76965517,2.35589404 C6.18758621,2.35589404 4.0937931,4.46701987 4.0937931,7.07046358 L4.0937931,74.2621192 C4.0937931,76.8655629 6.18758621,78.9766887 8.76965517,78.9766887 L64.8882759,78.9766887 C67.4703448,78.9766887 69.5641379,76.8655629 69.5641379,74.2621192 L69.5624828,54.847 L71.9014828,54.847 L71.9034483,74.2649007 C71.9034483,78.1700662 68.7613793,81.3381457 64.8882759,81.3381457 L8.76965517,81.3381457 C4.89655172,81.3381457 1.75448276,78.1700662 1.75448276,74.2649007 L1.75448276,7.07324503 C1.75448276,3.16529801 4.8937931,2.20268248e-13 8.76965517,2.20268248e-13 L64.8882759,2.20268248e-13 Z M71.9014828,44.847 L71.9004828,48.847 L69.5614828,48.847 L69.5624828,44.847 L71.9014828,44.847 Z M71.9024828,26.847 L71.9014828,31.847 L69.5624828,31.847 L69.5634828,26.847 L71.9024828,26.847 Z" id="Combined-Shape" fill="#EEEEEE"></path>
+ <path d="M14.6151724,14.7333775 L21.6275862,14.7333775 C22.2731034,14.7333775 22.7972414,15.2618543 22.7972414,15.9127152 C22.7972414,16.5635762 22.2731034,17.092053 21.6275862,17.092053 L14.6151724,17.092053 C13.9696552,17.092053 13.4455172,16.5635762 13.4455172,15.9127152 C13.4455172,15.2618543 13.9696552,14.7333775 14.6151724,14.7333775 Z M33.3213793,21.8066225 L40.3365517,21.8066225 C40.982069,21.8066225 41.5062069,22.3350993 41.5062069,22.9859603 C41.5062069,23.6368212 40.982069,24.165298 40.3365517,24.165298 L33.3213793,24.165298 C32.6758621,24.165298 32.1517241,23.6368212 32.1517241,22.9859603 C32.1517241,22.3350993 32.6731034,21.8066225 33.3213793,21.8066225 Z" id="Shape" fill="#E1DBF1"></path>
+ <path d="M40.3337931,14.7333775 L47.3489655,14.7333775 C47.9944828,14.7333775 48.5186207,15.2618543 48.5186207,15.9127152 C48.5186207,16.5635762 47.9944828,17.092053 47.3489655,17.092053 L40.3337931,17.092053 C39.6882759,17.092053 39.1641379,16.5635762 39.1641379,15.9127152 C39.1668966,15.2618543 39.6882759,14.7333775 40.3337931,14.7333775 Z" id="Path" fill="#EEEEEE"></path>
+ <path d="M21.6275862,28.8798675 L28.6427586,28.8798675 C29.2882759,28.8798675 29.8124138,29.4083444 29.8124138,30.0592053 C29.8124138,30.7100662 29.2882759,31.238543 28.6427586,31.238543 L21.6275862,31.238543 C20.982069,31.238543 20.457931,30.7100662 20.457931,30.0592053 C20.4606897,29.4083444 20.982069,28.8798675 21.6275862,28.8798675 Z" id="Path" fill="#E1DBF1"></path>
+ <path d="M26.3062069,14.7333775 L28.6455172,14.7333775 C29.2910345,14.7333775 29.8151724,15.2618543 29.8151724,15.9127152 C29.8151724,16.5635762 29.2910345,17.092053 28.6455172,17.092053 L26.3062069,17.092053 C25.6606897,17.092053 25.1365517,16.5635762 25.1365517,15.9127152 C25.1365517,15.2618543 25.6606897,14.7333775 26.3062069,14.7333775 Z" id="Path" fill="#FEE1D3"></path>
+ <path d="M33.3213793,35.9531126 L35.6606897,35.9531126 C36.3062069,35.9531126 36.8303448,36.4815894 36.8303448,37.1324503 C36.8303448,37.7833113 36.3062069,38.3117881 35.6606897,38.3117881 L33.3213793,38.3117881 C32.6758621,38.3117881 32.1517241,37.7833113 32.1517241,37.1324503 C32.1517241,36.4815894 32.6731034,35.9531126 33.3213793,35.9531126 Z" id="Path" fill="#FC6D26"></path>
+ <path d="M52.0248276,14.7333775 L54.3641379,14.7333775 C55.0096552,14.7333775 55.5337931,15.2618543 55.5337931,15.9127152 C55.5337931,16.5635762 55.0096552,17.092053 54.3641379,17.092053 L52.0248276,17.092053 C51.3793103,17.092053 50.8551724,16.5635762 50.8551724,15.9127152 C50.857931,15.2618543 51.3793103,14.7333775 52.0248276,14.7333775 Z" id="Shape" fill="#FEF0E8"></path>
+ <path d="M23.9668966,43.0263576 L28.6427586,43.0263576 C29.2882759,43.0263576 29.8124138,43.5548344 29.8124138,44.2056954 C29.8124138,44.8565563 29.2882759,45.3850331 28.6427586,45.3850331 L23.9668966,45.3850331 C23.3213793,45.3850331 22.7972414,44.8565563 22.7972414,44.2056954 C22.7972414,43.5548344 23.3213793,43.0263576 23.9668966,43.0263576 Z" id="Path" fill="#E1DBF1"></path>
+ <path d="M40.3337931,35.9531126 L42.6731034,35.9531126 C43.3186207,35.9531126 43.8427586,36.4815894 43.8427586,37.1324503 C43.8427586,37.7833113 43.3186207,38.3117881 42.6731034,38.3117881 L40.3337931,38.3117881 C39.6882759,38.3117881 39.1641379,37.7833113 39.1641379,37.1324503 C39.1641379,36.4815894 39.6882759,35.9531126 40.3337931,35.9531126 Z" id="Path" fill="#FC6D26"></path>
+ <path d="M52.3172414,33.5944371 C53.1255172,33.5944371 53.7793103,34.2536424 53.7793103,35.0686093 C53.7793103,35.8835762 53.1255172,36.5427815 52.3172414,36.5427815 C51.5089655,36.5427815 50.8551724,35.8835762 50.8551724,35.0686093 C50.8551724,34.2536424 51.5117241,33.5944371 52.3172414,33.5944371 Z M58.1627586,50.6892715 C58.9710345,50.6892715 59.6248276,51.3484768 59.6248276,52.1634437 C59.6248276,52.9784106 58.9710345,53.6376159 58.1627586,53.6376159 C57.3544828,53.6376159 56.7006897,52.9784106 56.7006897,52.1634437 C56.7006897,51.3484768 57.3572414,50.6892715 58.1627586,50.6892715 Z" id="Shape" fill="#E1DBF1"></path>
+ <path d="M63.4262069,50.6892715 C64.2344828,50.6892715 64.8882759,51.3484768 64.8882759,52.1634437 C64.8882759,52.9784106 64.2344828,53.6376159 63.4262069,53.6376159 C62.617931,53.6376159 61.9641379,52.9784106 61.9641379,52.1634437 C61.9641379,51.3484768 62.617931,50.6892715 63.4262069,50.6892715 Z M33.3213793,14.7333775 L35.6606897,14.7333775 C36.3062069,14.7333775 36.8303448,15.2618543 36.8303448,15.9127152 C36.8303448,16.5635762 36.3062069,17.092053 35.6606897,17.092053 L33.3213793,17.092053 C32.6758621,17.092053 32.1517241,16.5635762 32.1517241,15.9127152 C32.1517241,15.2618543 32.6731034,14.7333775 33.3213793,14.7333775 Z" id="Shape" fill="#FC6D26"></path>
+ <path d="M59.1696552,33.8470199 L66.182069,33.8470199 C66.8275862,33.8470199 67.3517241,34.3754967 67.3517241,35.0263576 C67.3517241,35.6772185 66.8275862,36.2056954 66.182069,36.2056954 L59.1696552,36.2056954 C58.5241379,36.2056954 58,35.6772185 58,35.0263576 C58,34.3754967 58.5241379,33.8470199 59.1696552,33.8470199 Z" id="Shape" fill="#E1DBF1"></path>
+ <path d="M70.8606897,33.8470199 L73.2,33.8470199 C73.8455172,33.8470199 74.3696552,34.3754967 74.3696552,35.0263576 C74.3696552,35.6772185 73.8455172,36.2056954 73.2,36.2056954 L70.8606897,36.2056954 C70.2151724,36.2056954 69.6910345,35.6772185 69.6910345,35.0263576 C69.6910345,34.3754967 70.2151724,33.8470199 70.8606897,33.8470199 Z" id="Path" fill="#FEE1D3"></path>
+ <path d="M77.8758621,33.8470199 L80.2151724,33.8470199 C80.8606897,33.8470199 81.3848276,34.3754967 81.3848276,35.0263576 C81.3848276,35.6772185 80.8606897,36.2056954 80.2151724,36.2056954 L77.8758621,36.2056954 C77.2303448,36.2056954 76.7062069,35.6772185 76.7062069,35.0263576 C76.7062069,34.3754967 77.2275862,33.8470199 77.8758621,33.8470199 Z" id="Shape" fill="#FC6D26"></path>
+ <path d="M14.6151724,35.9531126 L28.6455172,35.9531126 C29.2910345,35.9531126 29.8151724,36.4815894 29.8151724,37.1324503 C29.8151724,37.7833113 29.2910345,38.3117881 28.6455172,38.3117881 L14.6151724,38.3117881 C13.9696552,38.3117881 13.4455172,37.7833113 13.4455172,37.1324503 C13.4455172,36.4815894 13.9696552,35.9531126 14.6151724,35.9531126 Z M44.0937931,41.8470199 L61.1282759,41.8470199 C61.9117241,41.8470199 62.5489655,42.5062252 62.5489655,43.3211921 C62.5489655,44.1361589 61.9144828,44.7953642 61.1282759,44.7953642 L44.0937931,44.7953642 C43.3103448,44.7953642 42.6731034,44.1361589 42.6731034,43.3211921 C42.6731034,42.5062252 43.3103448,41.8470199 44.0937931,41.8470199 L44.0937931,41.8470199 L44.0937931,41.8470199 Z" id="Shape" fill="#EEEEEE"></path>
+ <path d="M35.3241379,50.6892715 L52.3586207,50.6892715 C53.142069,50.6892715 53.7793103,51.3484768 53.7793103,52.1634437 C53.7793103,52.9784106 53.1448276,53.6376159 52.3586207,53.6376159 L35.3241379,53.6376159 C34.5406897,53.6376159 33.9034483,52.9784106 33.9034483,52.1634437 C33.9034483,51.3484768 34.5406897,50.6892715 35.3241379,50.6892715 L35.3241379,50.6892715 L35.3241379,50.6892715 Z" id="Path" fill="#EFEDF8"></path>
+ <path d="M14.6151724,21.8066225 L28.6455172,21.8066225 C29.2910345,21.8066225 29.8151724,22.3350993 29.8151724,22.9859603 C29.8151724,23.6368212 29.2910345,24.165298 28.6455172,24.165298 L14.6151724,24.165298 C13.9696552,24.165298 13.4455172,23.6368212 13.4455172,22.9859603 C13.4455172,22.3350993 13.9696552,21.8066225 14.6151724,21.8066225 Z" id="Path" fill="#6B4FBB"></path>
+ <path d="M33.3213793,28.8798675 L47.3517241,28.8798675 C47.9972414,28.8798675 48.5213793,29.4083444 48.5213793,30.0592053 C48.5213793,30.7100662 47.9972414,31.238543 47.3517241,31.238543 L33.3213793,31.238543 C32.6758621,31.238543 32.1517241,30.7100662 32.1517241,30.0592053 C32.1517241,29.4083444 32.6731034,28.8798675 33.3213793,28.8798675 Z" id="Path" fill="#C3B8E3"></path>
+ <path d="M14.6151724,28.8798675 L16.9544828,28.8798675 C17.6,28.8798675 18.1241379,29.4083444 18.1241379,30.0592053 C18.1241379,30.7100662 17.6,31.238543 16.9544828,31.238543 L14.6151724,31.238543 C13.9696552,31.238543 13.4455172,30.7100662 13.4455172,30.0592053 C13.4455172,29.4083444 13.9696552,28.8798675 14.6151724,28.8798675 Z" id="Path" fill="#FEF0E8"></path>
+ <path d="M75.182069,50.8470199 L82.1972414,50.8470199 C82.8427586,50.8470199 83.3668966,51.3754967 83.3668966,52.0263576 C83.3668966,52.6772185 82.8427586,53.2056954 82.1972414,53.2056954 L75.182069,53.2056954 C74.5365517,53.2056954 74.0124138,52.6772185 74.0124138,52.0263576 C74.0151724,51.3754967 74.5365517,50.8470199 75.182069,50.8470199 Z" id="Path" fill="#E1DBF1"></path>
+ <path d="M86.8758621,50.8470199 L100.906207,50.8470199 C101.551724,50.8470199 102.075862,51.5079868 102.075862,52.3220199 C102.075862,53.1360529 101.551724,53.7970199 100.906207,53.7970199 L86.8758621,53.7970199 C86.2303448,53.7970199 85.7062069,53.1360529 85.7062069,52.3220199 C85.7062069,51.5079868 86.2275862,50.8470199 86.8758621,50.8470199 Z" id="Path" fill="#C3B8E3"></path>
+ <path d="M68.1696552,50.8470199 L70.5089655,50.8470199 C71.1544828,50.8470199 71.6786207,51.3754967 71.6786207,52.0263576 C71.6786207,52.6772185 71.1544828,53.2056954 70.5089655,53.2056954 L68.1696552,53.2056954 C67.5241379,53.2056954 67,52.6772185 67,52.0263576 C67,51.3754967 67.5241379,50.8470199 68.1696552,50.8470199 Z" id="Path" fill="#FEF0E8"></path>
+ <path d="M33.3213793,43.0263576 L35.6606897,43.0263576 C36.3062069,43.0263576 36.8303448,43.5548344 36.8303448,44.2056954 C36.8303448,44.8565563 36.3062069,45.3850331 35.6606897,45.3850331 L33.3213793,45.3850331 C32.6758621,45.3850331 32.1517241,44.8565563 32.1517241,44.2056954 C32.1517241,43.5548344 32.6731034,43.0263576 33.3213793,43.0263576 Z" id="Path" fill="#6B4FBB"></path>
+ <path d="M14.6151724,43.0263576 L19.2910345,43.0263576 C19.9365517,43.0263576 20.4606897,43.5548344 20.4606897,44.2056954 C20.4606897,44.8565563 19.9365517,45.3850331 19.2910345,45.3850331 L14.6151724,45.3850331 C13.9696552,45.3850331 13.4455172,44.8565563 13.4455172,44.2056954 C13.4455172,43.5548344 13.9696552,43.0263576 14.6151724,43.0263576 Z" id="Path" fill="#FC6D26"></path>
+ <path d="M14.6151724,50.0996026 L19.2910345,50.0996026 C19.9365517,50.0996026 20.4606897,50.6280795 20.4606897,51.2789404 C20.4606897,51.9298013 19.9365517,52.4582781 19.2910345,52.4582781 L14.6151724,52.4582781 C13.9696552,52.4582781 13.4455172,51.9298013 13.4455172,51.2789404 C13.4455172,50.625298 13.9696552,50.0996026 14.6151724,50.0996026 Z M23.9668966,50.0996026 L28.6427586,50.0996026 C29.2882759,50.0996026 29.8124138,50.6280795 29.8124138,51.2789404 C29.8124138,51.9298013 29.2882759,52.4582781 28.6427586,52.4582781 L23.9668966,52.4582781 C23.3213793,52.4582781 22.7972414,51.9298013 22.7972414,51.2789404 C22.7972414,50.625298 23.3213793,50.0996026 23.9668966,50.0996026 Z" id="Shape" fill="#FEF0E8"></path>
+ <path d="M88.7172414,21.8029139 C89.5255172,21.8029139 90.1793103,22.4621192 90.1793103,23.2770861 C90.1793103,24.092053 89.5255172,24.7512583 88.7172414,24.7512583 C87.9089655,24.7512583 87.2551724,24.092053 87.2551724,23.2770861 C87.2551724,22.4621192 87.9117241,21.8029139 88.7172414,21.8029139 Z" id="Shape" fill="#FEE1D3"></path>
+ <path d="M93.9806897,21.8029139 C94.7889655,21.8029139 95.4427586,22.4621192 95.4427586,23.2770861 C95.4427586,24.092053 94.7889655,24.7512583 93.9806897,24.7512583 C93.1724138,24.7512583 92.5186207,24.092053 92.5186207,23.2770861 C92.5186207,22.4621192 93.1724138,21.8029139 93.9806897,21.8029139 Z" id="Shape" fill="#6B4FBB"></path>
+ <path d="M65.8786207,21.8029139 L82.9131034,21.8029139 C83.6965517,21.8029139 84.3337931,22.4624894 84.3337931,23.2779139 C84.3337931,24.0933384 83.6993103,24.7529139 82.9131034,24.7529139 L65.8786207,24.7529139 C65.0951724,24.7529139 64.457931,24.0933384 64.457931,23.2779139 C64.457931,22.4624894 65.0951724,21.8029139 65.8786207,21.8029139 L65.8786207,21.8029139 L65.8786207,21.8029139 Z" id="Path" fill="#FC6D26"></path>
+ <path d="M54.5213793,21.213245 L59.1972414,21.213245 C59.8427586,21.213245 60.3668966,21.7417219 60.3668966,22.3925828 C60.3668966,23.0434437 59.8427586,23.5719205 59.1972414,23.5719205 L54.5213793,23.5719205 C53.8758621,23.5719205 53.3517241,23.0434437 53.3517241,22.3925828 C53.3517241,21.7389404 53.8758621,21.213245 54.5213793,21.213245 Z" id="Shape" fill="#FEF0E8"></path>
+ <path d="M45.1696552,21.213245 L49.8455172,21.213245 C50.4910345,21.213245 51.0151724,21.7417219 51.0151724,22.3925828 C51.0151724,23.0434437 50.4910345,23.5719205 49.8455172,23.5719205 L45.1696552,23.5719205 C44.5241379,23.5719205 44,23.0434437 44,22.3925828 C44,21.7389404 44.5241379,21.213245 45.1696552,21.213245 Z" id="Path" fill="#EEEEEE"></path>
+ <path d="M14.6151724,57.1728477 L21.6275862,57.1728477 C22.2731034,57.1728477 22.7972414,57.7013245 22.7972414,58.3521854 C22.7972414,59.0030464 22.2731034,59.5315232 21.6275862,59.5315232 L14.6151724,59.5315232 C13.9696552,59.5315232 13.4455172,59.0030464 13.4455172,58.3521854 C13.4455172,57.698543 13.9696552,57.1728477 14.6151724,57.1728477 Z" id="Path" fill="#EFEDF8"></path>
+ <path d="M25.3544828,64.2433113 L33.6855172,64.2433113 C34.4524138,64.2433113 35.0731034,64.7717881 35.0731034,65.422649 C35.0731034,66.0735099 34.4524138,66.6019868 33.6855172,66.6019868 L25.3544828,66.6019868 C24.5875862,66.6019868 23.9668966,66.0735099 23.9668966,65.422649 C23.9668966,64.7717881 24.5875862,64.2433113 25.3544828,64.2433113 Z" id="Path" fill="#FC6D26"></path>
+ <path d="M44.0606897,58.9390728 L52.3917241,58.9390728 C53.1586207,58.9390728 53.7793103,59.5982781 53.7793103,60.413245 C53.7793103,61.2254305 53.1586207,61.8874172 52.3917241,61.8874172 L44.0606897,61.8874172 C43.2937931,61.8874172 42.6731034,61.2282119 42.6731034,60.413245 C42.6731034,59.6010596 43.2937931,58.9390728 44.0606897,58.9390728 Z" id="Path" fill="#6B4FBB"></path>
+ <path d="M26.3062069,57.1728477 L28.6455172,57.1728477 C29.2910345,57.1728477 29.8151724,57.7013245 29.8151724,58.3521854 C29.8151724,59.0030464 29.2910345,59.5315232 28.6455172,59.5315232 L26.3062069,59.5315232 C25.6606897,59.5315232 25.1365517,59.0030464 25.1365517,58.3521854 C25.1365517,57.698543 25.6606897,57.1728477 26.3062069,57.1728477 Z" id="Path" fill="#FEE1D3"></path>
+ <path d="M36.8275862,64.2433113 L39.1668966,64.2433113 C39.8124138,64.2433113 40.3365517,64.7717881 40.3365517,65.422649 C40.3365517,66.0735099 39.8124138,66.6019868 39.1668966,66.6019868 L36.8275862,66.6019868 C36.182069,66.6019868 35.657931,66.0735099 35.657931,65.422649 C35.657931,64.7717881 36.182069,64.2433113 36.8275862,64.2433113 Z M58.1627586,58.9390728 L61.0868966,58.9390728 C61.8951724,58.9390728 62.5489655,59.5982781 62.5489655,60.413245 C62.5489655,61.2282119 61.8951724,61.8874172 61.0868966,61.8874172 L58.1627586,61.8874172 C57.3544828,61.8874172 56.7006897,61.2282119 56.7006897,60.413245 C56.7034483,59.5982781 57.3572414,58.9390728 58.1627586,58.9390728 Z" id="Shape" fill="#FEF0E8"></path>
+ <path d="M35.3655172,58.9390728 L38.2896552,58.9390728 C39.097931,58.9390728 39.7517241,59.5982781 39.7517241,60.413245 C39.7517241,61.2282119 39.097931,61.8874172 38.2896552,61.8874172 L35.3655172,61.8874172 C34.5572414,61.8874172 33.9034483,61.2282119 33.9034483,60.413245 C33.9034483,59.5982781 34.56,58.9390728 35.3655172,58.9390728 Z" id="Path" fill="#FC6D26"></path>
+ <path d="M66.1696552,40.8470199 L73.182069,40.8470199 C73.8275862,40.8470199 74.3517241,41.3754967 74.3517241,42.0263576 C74.3517241,42.6772185 73.8275862,43.2056954 73.182069,43.2056954 L66.1696552,43.2056954 C65.5241379,43.2056954 65,42.6772185 65,42.0263576 C65,41.3727152 65.5241379,40.8470199 66.1696552,40.8470199 Z" id="Path" fill="#EFEDF8"></path>
+ <path d="M95.6151724,42.613245 L103.946207,42.613245 C104.713103,42.613245 105.333793,43.1409054 105.333793,43.793245 C105.333793,44.4433582 104.713103,44.973245 103.946207,44.973245 L95.6151724,44.973245 C94.8482759,44.973245 94.2275862,44.4455847 94.2275862,43.793245 C94.2275862,43.1431318 94.8482759,42.613245 95.6151724,42.613245 Z" id="Path" fill="#6B4FBB"></path>
+ <path d="M77.8606897,40.8470199 L80.2,40.8470199 C80.8455172,40.8470199 81.3696552,41.3754967 81.3696552,42.0263576 C81.3696552,42.6772185 80.8455172,43.2056954 80.2,43.2056954 L77.8606897,43.2056954 C77.2151724,43.2056954 76.6910345,42.6772185 76.6910345,42.0263576 C76.6910345,41.3727152 77.2151724,40.8470199 77.8606897,40.8470199 Z" id="Path" fill="#FEE1D3"></path>
+ <path d="M86.92,42.613245 L89.8441379,42.613245 C90.6524138,42.613245 91.3062069,43.1409054 91.3062069,43.793245 C91.3062069,44.4455847 90.6524138,44.973245 89.8441379,44.973245 L86.92,44.973245 C86.1117241,44.973245 85.457931,44.4455847 85.457931,43.793245 C85.457931,43.1409054 86.1144828,42.613245 86.92,42.613245 Z" id="Path" fill="#FC6D26"></path>
+ <path d="M14.6151724,64.2433113 L20.4606897,64.2433113 C21.1062069,64.2433113 21.6303448,64.7717881 21.6303448,65.422649 C21.6303448,66.0735099 21.1062069,66.6019868 20.4606897,66.6019868 L14.6151724,66.6019868 C13.9696552,66.6019868 13.4455172,66.0735099 13.4455172,65.422649 C13.4455172,64.7717881 13.9696552,64.2433113 14.6151724,64.2433113 Z" id="Path" fill="#EEEEEE"></path>
+ </g>
+ <g id="Group-12" transform="translate(112.058152, -0.000000)">
+ <path d="M5.84861758,4.12465116 L62.0003099,4.12465116 C65.229233,4.12465116 67.8489253,6.76465116 67.8489253,10.0186047 L67.8489253,77.8046512 C67.8489253,81.0586047 65.229233,83.6986047 62.0003099,83.6986047 L5.84861758,83.6986047 C2.6196945,83.6986047 1.42108547e-14,81.0586047 1.42108547e-14,77.8046512 L1.42108547e-14,10.0213953 C-0.00276703963,6.76744186 2.6196945,4.12465116 5.84861758,4.12465116 Z" id="Path" fill="#F9F9F9" fill-rule="nonzero"></path>
+ <path d="M8.77292527,1.17767442 L64.9246176,1.17767442 C68.1535407,1.17767442 70.773233,3.81767442 70.773233,7.07162791 L70.773233,74.2688372 C70.773233,77.5227907 68.1535407,80.1627907 64.9246176,80.1627907 L8.77292527,80.1627907 C5.54400219,80.1627907 2.92430988,77.5227907 2.92430988,74.2688372 L2.92430988,7.07162791 C2.92430988,3.81767442 5.54400219,1.17767442 8.77292527,1.17767442 Z" id="Path" fill="#FFFFFF" fill-rule="nonzero"></path>
+ <path d="M8.77292527,2.35813953 C6.18646373,2.35813953 4.09292527,4.46790698 4.09292527,7.0744186 L4.09292527,74.2716279 C4.09292527,76.8781395 6.18646373,78.987907 8.77292527,78.987907 L64.9246176,78.987907 C67.5110791,78.987907 69.6046176,76.8781395 69.6046176,74.2716279 L69.6046176,7.07162791 C69.6046176,4.46511628 67.5110791,2.35534884 64.9246176,2.35534884 L8.77292527,2.35813953 L8.77292527,2.35813953 Z M8.77292527,-4.19220214e-13 L64.9246176,-4.19220214e-13 C68.8043099,-4.19220214e-13 71.9418483,3.16744186 71.9418483,7.07162791 L71.9418483,74.2688372 C71.9418483,78.1786047 68.7987714,81.3404651 64.9246176,81.3404651 L8.77292527,81.3404651 C4.89323296,81.3404651 1.75569267,78.1730233 1.75569267,74.2688372 L1.75569267,7.07162791 C1.75292527,3.17023256 4.89600219,-4.19220214e-13 8.77292527,-4.19220214e-13 Z" id="Shape" fill="#EEEEEE" fill-rule="nonzero"></path>
+ <path d="M14.6215407,14.7348837 L21.6387714,14.7348837 C22.281233,14.7348837 22.8073868,15.2651163 22.8073868,15.9125581 C22.8073868,16.56 22.281233,17.0902326 21.6387714,17.0902326 L14.6215407,17.0902326 C13.9790791,17.0902326 13.4529253,16.56 13.4529253,15.9125581 C13.4529253,15.2651163 13.9763099,14.7348837 14.6215407,14.7348837 Z M33.3387714,21.8093023 L40.3560022,21.8093023 C40.9984637,21.8093023 41.5246176,22.3395349 41.5246176,22.9869767 C41.5246176,23.6344186 40.9984637,24.1646512 40.3560022,24.1646512 L33.3387714,24.1646512 C32.6963099,24.1646512 32.170156,23.6344186 32.170156,22.9869767 C32.170156,22.3395349 32.6963099,21.8093023 33.3387714,21.8093023 Z" id="Shape" fill="#E1DBF1" fill-rule="nonzero"></path>
+ <path d="M40.3587714,14.7348837 L47.3760022,14.7348837 C48.0184637,14.7348837 48.5446176,15.2651163 48.5446176,15.9125581 C48.5446176,16.56 48.0184637,17.0902326 47.3760022,17.0902326 L40.3587714,17.0902326 C39.7163099,17.0902326 39.1901452,16.56 39.1901452,15.9125581 C39.1873868,15.267907 39.7163099,14.7348837 40.3587714,14.7348837 Z" id="Path" fill="#EEEEEE" fill-rule="nonzero"></path>
+ <path d="M21.6415407,28.8837209 L28.6587714,28.8837209 C29.301233,28.8837209 29.8273868,29.4139535 29.8273868,30.0613953 C29.8273868,30.7088372 29.301233,31.2390698 28.6587714,31.2390698 L21.6415407,31.2390698 C20.9990791,31.2390698 20.4729253,30.7088372 20.4729253,30.0613953 C20.4729253,29.4139535 20.9990791,28.8837209 21.6415407,28.8837209 Z" id="Path" fill="#E1DBF1" fill-rule="nonzero"></path>
+ <path d="M26.3187714,14.7348837 L28.6587714,14.7348837 C29.301233,14.7348837 29.8273868,15.2651163 29.8273868,15.9125581 C29.8273868,16.56 29.301233,17.0902326 28.6587714,17.0902326 L26.3187714,17.0902326 C25.6763099,17.0902326 25.150156,16.56 25.150156,15.9125581 C25.150156,15.2651163 25.6763099,14.7348837 26.3187714,14.7348837 Z" id="Path" fill="#FEE1D3" fill-rule="nonzero"></path>
+ <path d="M33.3387714,35.9553488 L35.6787714,35.9553488 C36.321233,35.9553488 36.8473868,36.4855814 36.8473868,37.1330233 C36.8473868,37.7804651 36.321233,38.3106977 35.6787714,38.3106977 L33.3387714,38.3106977 C32.6963099,38.3106977 32.170156,37.7804651 32.170156,37.1330233 C32.170156,36.4855814 32.6963099,35.9553488 33.3387714,35.9553488 Z" id="Path" fill="#FC6D26" fill-rule="nonzero"></path>
+ <path d="M45.0360022,21.8093023 L47.3760022,21.8093023 C48.0184637,21.8093023 48.5446176,22.3395349 48.5446176,22.9869767 C48.5446176,23.6344186 48.0184637,24.1646512 47.3760022,24.1646512 L45.0360022,24.1646512 C44.3935407,24.1646512 43.8673868,23.6344186 43.8673868,22.9869767 C43.8673868,22.3395349 44.3935407,21.8093023 45.0360022,21.8093023 Z M52.0560022,14.7348837 L54.3960022,14.7348837 C55.0384637,14.7348837 55.5646176,15.2651163 55.5646176,15.9125581 C55.5646176,16.56 55.0384637,17.0902326 54.3960022,17.0902326 L52.0560022,17.0902326 C51.4135407,17.0902326 50.8873868,16.56 50.8873868,15.9125581 C50.8873868,15.2651163 51.4135407,14.7348837 52.0560022,14.7348837 Z" id="Shape" fill="#FEF0E8" fill-rule="nonzero"></path>
+ <path d="M23.9787714,43.0297674 L28.6587714,43.0297674 C29.301233,43.0297674 29.8273868,43.56 29.8273868,44.2074419 C29.8273868,44.8548837 29.301233,45.3851163 28.6587714,45.3851163 L23.9787714,45.3851163 C23.3363099,45.3851163 22.810156,44.8548837 22.810156,44.2074419 C22.810156,43.56 23.3363099,43.0297674 23.9787714,43.0297674 Z" id="Path" fill="#E1DBF1" fill-rule="nonzero"></path>
+ <path d="M40.3587714,35.9553488 L42.6987714,35.9553488 C43.341233,35.9553488 43.8673868,36.4855814 43.8673868,37.1330233 C43.8673868,37.7804651 43.341233,38.3106977 42.6987714,38.3106977 L40.3587714,38.3106977 C39.7163099,38.3106977 39.1901452,37.7804651 39.1901452,37.1330233 C39.1873868,36.4883721 39.7163099,35.9553488 40.3587714,35.9553488 Z" id="Path" fill="#FC6D26" fill-rule="nonzero"></path>
+ <path d="M52.3495407,33.5972093 C53.158156,33.5972093 53.8116945,34.255814 53.8116945,35.0706977 C53.8116945,35.8855814 53.158156,36.544186 52.3495407,36.544186 C51.5409253,36.544186 50.8873868,35.8855814 50.8873868,35.0706977 C50.8873868,34.2586047 51.5436945,33.5972093 52.3495407,33.5972093 Z M58.198156,50.6930233 C59.0067714,50.6930233 59.6603099,51.3516279 59.6603099,52.1665116 C59.6603099,52.9813953 59.0067714,53.64 58.198156,53.64 C57.3895407,53.64 56.7360022,52.9813953 56.7360022,52.1665116 C56.7360022,51.3516279 57.3895407,50.6930233 58.198156,50.6930233 Z" id="Shape" fill="#E1DBF1" fill-rule="nonzero"></path>
+ <path d="M63.4624637,50.6930233 C64.2710791,50.6930233 64.9246176,51.3516279 64.9246176,52.1665116 C64.9246176,52.9813953 64.2710791,53.64 63.4624637,53.64 C62.6538483,53.64 62.0003099,52.9813953 62.0003099,52.1665116 C62.0003099,51.3516279 62.6566176,50.6930233 63.4624637,50.6930233 Z M33.3387714,14.7348837 L35.6787714,14.7348837 C36.321233,14.7348837 36.8473868,15.2651163 36.8473868,15.9125581 C36.8473868,16.56 36.321233,17.0902326 35.6787714,17.0902326 L33.3387714,17.0902326 C32.6963099,17.0902326 32.170156,16.56 32.170156,15.9125581 C32.170156,15.2651163 32.6963099,14.7348837 33.3387714,14.7348837 Z" id="Shape" fill="#FC6D26" fill-rule="nonzero"></path>
+ <path d="M14.6215407,35.9553488 L28.6615407,35.9553488 C29.3040022,35.9553488 29.830156,36.4855814 29.830156,37.1330233 C29.830156,37.7804651 29.3040022,38.3106977 28.6615407,38.3106977 L14.6215407,38.3106977 C13.9790791,38.3106977 13.4529253,37.7804651 13.4529253,37.1330233 C13.4529253,36.4855814 13.9763099,35.9553488 14.6215407,35.9553488 Z M44.1193868,41.8493023 L61.1640022,41.8493023 C61.9476945,41.8493023 62.5873868,42.507907 62.5873868,43.3227907 C62.5873868,44.1376744 61.9504637,44.7962791 61.1640022,44.7962791 L44.1193868,44.7962791 C43.3356945,44.7962791 42.6960022,44.1376744 42.6960022,43.3227907 C42.6960022,42.507907 43.3356945,41.8493023 44.1193868,41.8493023 L44.1193868,41.8493023 L44.1193868,41.8493023 Z" id="Shape" fill="#EEEEEE" fill-rule="nonzero"></path>
+ <path d="M35.3464637,50.6930233 L52.3910791,50.6930233 C53.1747714,50.6930233 53.8144637,51.3516279 53.8144637,52.1665116 C53.8144637,52.9813953 53.1775407,53.64 52.3910791,53.64 L35.3464637,53.64 C34.5627714,53.64 33.9230791,52.9813953 33.9230791,52.1665116 C33.9230791,51.3516279 34.5600022,50.6930233 35.3464637,50.6930233 L35.3464637,50.6930233 L35.3464637,50.6930233 Z" id="Path" fill="#EFEDF8" fill-rule="nonzero"></path>
+ <path d="M14.6215407,21.8093023 L28.6615407,21.8093023 C29.3040022,21.8093023 29.830156,22.3395349 29.830156,22.9869767 C29.830156,23.6344186 29.3040022,24.1646512 28.6615407,24.1646512 L14.6215407,24.1646512 C13.9790791,24.1646512 13.4529253,23.6344186 13.4529253,22.9869767 C13.4529253,22.3395349 13.9763099,21.8093023 14.6215407,21.8093023 Z" id="Path" fill="#6B4FBB" fill-rule="nonzero"></path>
+ <path d="M33.3387714,28.8837209 L47.3787714,28.8837209 C48.021233,28.8837209 48.5473868,29.4139535 48.5473868,30.0613953 C48.5473868,30.7088372 48.021233,31.2390698 47.3787714,31.2390698 L33.3387714,31.2390698 C32.6963099,31.2390698 32.170156,30.7088372 32.170156,30.0613953 C32.170156,29.4139535 32.6963099,28.8837209 33.3387714,28.8837209 Z" id="Path" fill="#C3B8E3" fill-rule="nonzero"></path>
+ <path d="M14.6215407,28.8837209 L16.9615407,28.8837209 C17.6040022,28.8837209 18.130156,29.4139535 18.130156,30.0613953 C18.130156,30.7088372 17.6040022,31.2390698 16.9615407,31.2390698 L14.6215407,31.2390698 C13.9790791,31.2390698 13.4529253,30.7088372 13.4529253,30.0613953 C13.4529253,29.4139535 13.9763099,28.8837209 14.6215407,28.8837209 Z" id="Path" fill="#FEF0E8" fill-rule="nonzero"></path>
+ <path d="M33.3387714,43.0297674 L35.6787714,43.0297674 C36.321233,43.0297674 36.8473868,43.56 36.8473868,44.2074419 C36.8473868,44.8548837 36.321233,45.3851163 35.6787714,45.3851163 L33.3387714,45.3851163 C32.6963099,45.3851163 32.170156,44.8548837 32.170156,44.2074419 C32.170156,43.56 32.6963099,43.0297674 33.3387714,43.0297674 Z" id="Path" fill="#6B4FBB" fill-rule="nonzero"></path>
+ <path d="M14.6215407,43.0297674 L19.3015407,43.0297674 C19.9440022,43.0297674 20.470156,43.56 20.470156,44.2074419 C20.470156,44.8548837 19.9440022,45.3851163 19.3015407,45.3851163 L14.6215407,45.3851163 C13.9790791,45.3851163 13.4529253,44.8548837 13.4529253,44.2074419 C13.4529253,43.56 13.9763099,43.0297674 14.6215407,43.0297674 Z" id="Path" fill="#FC6D26" fill-rule="nonzero"></path>
+ <path d="M14.6215407,50.104186 L19.3015407,50.104186 C19.9440022,50.104186 20.470156,50.6344186 20.470156,51.2818605 C20.470156,51.9293023 19.9440022,52.4595349 19.3015407,52.4595349 L14.6215407,52.4595349 C13.9790791,52.4595349 13.4529253,51.9293023 13.4529253,51.2818605 C13.4529253,50.6344186 13.9763099,50.104186 14.6215407,50.104186 Z M23.9787714,50.104186 L28.6587714,50.104186 C29.301233,50.104186 29.8273868,50.6344186 29.8273868,51.2818605 C29.8273868,51.9293023 29.301233,52.4595349 28.6587714,52.4595349 L23.9787714,52.4595349 C23.3363099,52.4595349 22.810156,51.9293023 22.810156,51.2818605 C22.810156,50.6344186 23.3363099,50.104186 23.9787714,50.104186 Z" id="Shape" fill="#FEF0E8" fill-rule="nonzero"></path>
+ <path d="M14.6215407,57.175814 L21.6387714,57.175814 C22.281233,57.175814 22.8073868,57.7060465 22.8073868,58.3534884 C22.8073868,59.0009302 22.281233,59.5311628 21.6387714,59.5311628 L14.6215407,59.5311628 C13.9790791,59.5311628 13.4529253,59.0009302 13.4529253,58.3534884 C13.4529253,57.7060465 13.9763099,57.175814 14.6215407,57.175814 Z" id="Path" fill="#EFEDF8" fill-rule="nonzero"></path>
+ <path d="M25.366156,64.2502326 L33.7015407,64.2502326 C34.4686176,64.2502326 35.0916945,64.7748837 35.0916945,65.427907 C35.0916945,66.0753488 34.4713868,66.6055814 33.7015407,66.6055814 L25.366156,66.6055814 C24.5990791,66.6055814 23.9760022,66.0753488 23.9760022,65.427907 C23.9787714,64.7804651 24.6018483,64.2502326 25.366156,64.2502326 Z" id="Path" fill="#FC6D26" fill-rule="nonzero"></path>
+ <path d="M44.0833868,58.9451163 L52.4187714,58.9451163 C53.1858483,58.9451163 53.8089253,59.6037209 53.8089253,60.4186047 C53.8089253,61.2334884 53.1886176,61.892093 52.4187714,61.892093 L44.0833868,61.892093 C43.3163099,61.892093 42.693233,61.2334884 42.693233,60.4186047 C42.6960022,59.6065116 43.3190791,58.9451163 44.0833868,58.9451163 Z" id="Path" fill="#6B4FBB" fill-rule="nonzero"></path>
+ <path d="M26.3187714,57.175814 L28.6587714,57.175814 C29.301233,57.175814 29.8273868,57.7060465 29.8273868,58.3534884 C29.8273868,59.0009302 29.301233,59.5311628 28.6587714,59.5311628 L26.3187714,59.5311628 C25.6763099,59.5311628 25.150156,59.0009302 25.150156,58.3534884 C25.150156,57.7060465 25.6763099,57.175814 26.3187714,57.175814 Z" id="Path" fill="#FEE1D3" fill-rule="nonzero"></path>
+ <path d="M36.850156,64.2502326 L39.190156,64.2502326 C39.8326176,64.2502326 40.3587714,64.7804651 40.3587714,65.427907 C40.3587714,66.0753488 39.8326176,66.6055814 39.190156,66.6055814 L36.850156,66.6055814 C36.2076945,66.6055814 35.6815407,66.0753488 35.6815407,65.427907 C35.6815407,64.7804651 36.2049253,64.2502326 36.850156,64.2502326 Z M58.198156,58.9451163 L61.1224637,58.9451163 C61.9310791,58.9451163 62.5846176,59.6037209 62.5846176,60.4186047 C62.5846176,61.2334884 61.9310791,61.892093 61.1224637,61.892093 L58.198156,61.892093 C57.3895407,61.892093 56.7360022,61.2334884 56.7360022,60.4186047 C56.7360022,59.6065116 57.3895407,58.9451163 58.198156,58.9451163 Z" id="Shape" fill="#FEF0E8" fill-rule="nonzero"></path>
+ <path d="M35.385233,58.9451163 L38.3095407,58.9451163 C39.118156,58.9451163 39.7716945,59.6037209 39.7716945,60.4186047 C39.7716945,61.2334884 39.118156,61.892093 38.3095407,61.892093 L35.385233,61.892093 C34.5766176,61.892093 33.9230791,61.2334884 33.9230791,60.4186047 C33.9230791,59.6065116 34.5793868,58.9451163 35.385233,58.9451163 Z" id="Path" fill="#FC6D26" fill-rule="nonzero"></path>
+ <path d="M14.6215407,64.2502326 L20.470156,64.2502326 C21.1126176,64.2502326 21.6387714,64.7804651 21.6387714,65.427907 C21.6387714,66.0753488 21.1126176,66.6055814 20.470156,66.6055814 L14.6215407,66.6055814 C13.9790791,66.6055814 13.4529253,66.0753488 13.4529253,65.427907 C13.4529253,64.7804651 13.9763099,64.2502326 14.6215407,64.2502326 Z" id="Path" fill="#EEEEEE" fill-rule="nonzero"></path>
+ <ellipse id="Oval" fill="#FFFFFF" fill-rule="nonzero" cx="36.814156" cy="38.4725581" rx="20.4729231" ry="20.6316279"></ellipse>
+ <path d="M36.814156,59.104186 C25.5073868,59.104186 16.341233,49.8669767 16.341233,38.4725581 C16.341233,27.0781395 25.5073868,17.8409302 36.814156,17.8409302 C48.1209253,17.8409302 57.2870791,27.0781395 57.2870791,38.4725581 C57.2870791,49.8669767 48.1209253,59.104186 36.814156,59.104186 Z M36.814156,56.7460465 C46.8276945,56.7460465 54.9470791,48.5637209 54.9470791,38.4725581 C54.9470791,28.3813953 46.8276945,20.1990698 36.814156,20.1990698 C26.8006176,20.1990698 18.681233,28.3813953 18.681233,38.4725581 C18.681233,48.5637209 26.8006176,56.7460465 36.814156,56.7460465 Z" id="Shape" fill="#EEEEEE" fill-rule="nonzero"></path>
+ <path d="M46.5895407,39.7813953 L45.490156,36.3739535 L43.3135407,29.6260465 C43.2027714,29.28 42.718156,29.28 42.5990791,29.6260465 L40.4280022,36.3739535 L33.2030791,36.3739535 L31.0264637,29.6260465 C30.9156945,29.28 30.4310791,29.28 30.3120022,29.6260465 L28.1353868,36.3739535 L27.0360022,39.7813953 C26.9363099,40.0939535 27.0470791,40.4288372 27.3046176,40.624186 L36.8086176,47.5786047 L46.3126176,40.624186 C46.581233,40.4288372 46.689233,40.0883721 46.5895407,39.7813953" id="Path" fill="#FC6D26"></path>
+ <polygon id="Path" fill="#E24329" points="36.814156 47.5813953 40.4280022 36.3767442 33.2030791 36.3767442"></polygon>
+ <polygon id="Path" fill="#FC6D26" points="36.814156 47.5813953 33.2003099 36.3767442 28.1353868 36.3767442"></polygon>
+ <path d="M28.138156,36.3739535 L27.0387714,39.7813953 C26.9390791,40.0939535 27.0498483,40.4288372 27.3073868,40.624186 L36.8113868,47.5786047 L28.138156,36.3739535 Z" id="Path" fill="#FCA326"></path>
+ <path d="M28.138156,36.3739535 L33.2030791,36.3739535 L31.0264637,29.6260465 C30.9156945,29.28 30.4310791,29.28 30.3120022,29.6260465 L28.138156,36.3739535 Z" id="Path" fill="#E24329"></path>
+ <polygon id="Path" fill="#FC6D26" points="36.814156 47.5813953 40.4280022 36.3767442 45.4929253 36.3767442"></polygon>
+ <path d="M45.4929253,36.3739535 L46.5923099,39.7813953 C46.6920022,40.0939535 46.581233,40.4288372 46.3236945,40.624186 L36.8196945,47.5786047 L45.4929253,36.3739535 Z" id="Path" fill="#FCA326"></path>
+ <path d="M45.4929253,36.3739535 L40.4280022,36.3739535 L42.6046176,29.6260465 C42.7153868,29.28 43.2000022,29.28 43.3190791,29.6260465 L45.4929253,36.3739535 Z" id="Path" fill="#E24329"></path>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/app/assets/javascripts/projects/experiment_new_project_creation/index.js b/app/assets/javascripts/projects/experiment_new_project_creation/index.js
new file mode 100644
index 00000000000..3715c52b6b9
--- /dev/null
+++ b/app/assets/javascripts/projects/experiment_new_project_creation/index.js
@@ -0,0 +1,14 @@
+import Vue from 'vue';
+import NewProjectCreationApp from './components/app.vue';
+
+export default function(el, props) {
+ return new Vue({
+ el,
+ components: {
+ NewProjectCreationApp,
+ },
+ render(h) {
+ return h(NewProjectCreationApp, { props });
+ },
+ });
+}
diff --git a/app/assets/javascripts/registry/explorer/components/details_page/delete_alert.vue b/app/assets/javascripts/registry/explorer/components/details_page/delete_alert.vue
new file mode 100644
index 00000000000..8bdf043a106
--- /dev/null
+++ b/app/assets/javascripts/registry/explorer/components/details_page/delete_alert.vue
@@ -0,0 +1,70 @@
+<script>
+import { GlSprintf, GlAlert, GlLink } from '@gitlab/ui';
+
+import { ALERT_MESSAGES, ADMIN_GARBAGE_COLLECTION_TIP } from '../../constants/index';
+
+export default {
+ components: {
+ GlSprintf,
+ GlAlert,
+ GlLink,
+ },
+ model: {
+ prop: 'deleteAlertType',
+ event: 'change',
+ },
+ props: {
+ deleteAlertType: {
+ type: String,
+ default: null,
+ required: false,
+ validator(value) {
+ return !value || ALERT_MESSAGES[value] !== undefined;
+ },
+ },
+ garbageCollectionHelpPagePath: { type: String, required: false, default: '' },
+ isAdmin: {
+ type: Boolean,
+ default: false,
+ required: false,
+ },
+ },
+ computed: {
+ deleteAlertConfig() {
+ const config = {
+ title: '',
+ message: '',
+ type: 'success',
+ };
+ if (this.deleteAlertType) {
+ [config.type] = this.deleteAlertType.split('_');
+
+ config.message = ALERT_MESSAGES[this.deleteAlertType];
+
+ if (this.isAdmin && config.type === 'success') {
+ config.title = config.message;
+ config.message = ADMIN_GARBAGE_COLLECTION_TIP;
+ }
+ }
+ return config;
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-alert
+ v-if="deleteAlertType"
+ :variant="deleteAlertConfig.type"
+ :title="deleteAlertConfig.title"
+ @dismiss="$emit('change', null)"
+ >
+ <gl-sprintf :message="deleteAlertConfig.message">
+ <template #docLink="{content}">
+ <gl-link :href="garbageCollectionHelpPagePath" target="_blank">
+ {{ content }}
+ </gl-link>
+ </template>
+ </gl-sprintf>
+ </gl-alert>
+</template>
diff --git a/app/assets/javascripts/registry/explorer/components/details_page/delete_modal.vue b/app/assets/javascripts/registry/explorer/components/details_page/delete_modal.vue
new file mode 100644
index 00000000000..96f221bf71d
--- /dev/null
+++ b/app/assets/javascripts/registry/explorer/components/details_page/delete_modal.vue
@@ -0,0 +1,67 @@
+<script>
+import { GlModal, GlSprintf } from '@gitlab/ui';
+import { n__ } from '~/locale';
+import { REMOVE_TAG_CONFIRMATION_TEXT, REMOVE_TAGS_CONFIRMATION_TEXT } from '../../constants/index';
+
+export default {
+ components: {
+ GlModal,
+ GlSprintf,
+ },
+ props: {
+ itemsToBeDeleted: {
+ type: Array,
+ required: false,
+ default: () => [],
+ },
+ },
+ computed: {
+ modalAction() {
+ return n__(
+ 'ContainerRegistry|Remove tag',
+ 'ContainerRegistry|Remove tags',
+ this.itemsToBeDeleted.length,
+ );
+ },
+ modalDescription() {
+ if (this.itemsToBeDeleted.length > 1) {
+ return {
+ message: REMOVE_TAGS_CONFIRMATION_TEXT,
+ item: this.itemsToBeDeleted.length,
+ };
+ }
+ const [first] = this.itemsToBeDeleted;
+
+ return {
+ message: REMOVE_TAG_CONFIRMATION_TEXT,
+ item: first?.path,
+ };
+ },
+ },
+ methods: {
+ show() {
+ this.$refs.deleteModal.show();
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-modal
+ ref="deleteModal"
+ modal-id="delete-tag-modal"
+ ok-variant="danger"
+ @ok="$emit('confirmDelete')"
+ @cancel="$emit('cancelDelete')"
+ >
+ <template #modal-title>{{ modalAction }}</template>
+ <template #modal-ok>{{ modalAction }}</template>
+ <p v-if="modalDescription" data-testid="description">
+ <gl-sprintf :message="modalDescription.message">
+ <template #item
+ ><b>{{ modalDescription.item }}</b></template
+ >
+ </gl-sprintf>
+ </p>
+ </gl-modal>
+</template>
diff --git a/app/assets/javascripts/registry/explorer/components/details_page/details_header.vue b/app/assets/javascripts/registry/explorer/components/details_page/details_header.vue
new file mode 100644
index 00000000000..c254dd05aa4
--- /dev/null
+++ b/app/assets/javascripts/registry/explorer/components/details_page/details_header.vue
@@ -0,0 +1,30 @@
+<script>
+import { GlSprintf } from '@gitlab/ui';
+import { DETAILS_PAGE_TITLE } from '../../constants/index';
+
+export default {
+ components: { GlSprintf },
+ props: {
+ imageName: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ },
+ i18n: {
+ DETAILS_PAGE_TITLE,
+ },
+};
+</script>
+
+<template>
+ <div class="gl-display-flex gl-my-2 gl-align-items-center">
+ <h4>
+ <gl-sprintf :message="$options.i18n.DETAILS_PAGE_TITLE">
+ <template #imageName>
+ {{ imageName }}
+ </template>
+ </gl-sprintf>
+ </h4>
+ </div>
+</template>
diff --git a/app/assets/javascripts/registry/explorer/components/details_page/empty_tags_state.vue b/app/assets/javascripts/registry/explorer/components/details_page/empty_tags_state.vue
new file mode 100644
index 00000000000..0c684d124d5
--- /dev/null
+++ b/app/assets/javascripts/registry/explorer/components/details_page/empty_tags_state.vue
@@ -0,0 +1,33 @@
+<script>
+import { GlEmptyState } from '@gitlab/ui';
+import {
+ EMPTY_IMAGE_REPOSITORY_TITLE,
+ EMPTY_IMAGE_REPOSITORY_MESSAGE,
+} from '../../constants/index';
+
+export default {
+ components: {
+ GlEmptyState,
+ },
+ props: {
+ noContainersImage: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ },
+ i18n: {
+ EMPTY_IMAGE_REPOSITORY_TITLE,
+ EMPTY_IMAGE_REPOSITORY_MESSAGE,
+ },
+};
+</script>
+
+<template>
+ <gl-empty-state
+ :title="$options.i18n.EMPTY_IMAGE_REPOSITORY_TITLE"
+ :svg-path="noContainersImage"
+ :description="$options.i18n.EMPTY_IMAGE_REPOSITORY_MESSAGE"
+ class="gl-mx-auto gl-my-0"
+ />
+</template>
diff --git a/app/assets/javascripts/registry/explorer/components/details_page/tags_loader.vue b/app/assets/javascripts/registry/explorer/components/details_page/tags_loader.vue
new file mode 100644
index 00000000000..b7afa5fba33
--- /dev/null
+++ b/app/assets/javascripts/registry/explorer/components/details_page/tags_loader.vue
@@ -0,0 +1,34 @@
+<script>
+import { GlSkeletonLoader } from '@gitlab/ui';
+
+export default {
+ components: {
+ GlSkeletonLoader,
+ },
+ loader: {
+ repeat: 10,
+ width: 1000,
+ height: 40,
+ },
+};
+</script>
+
+<template>
+ <div>
+ <gl-skeleton-loader
+ v-for="index in $options.loader.repeat"
+ :key="index"
+ :width="$options.loader.width"
+ :height="$options.loader.height"
+ preserve-aspect-ratio="xMinYMax meet"
+ >
+ <rect width="15" x="0" y="12.5" height="15" rx="4" />
+ <rect width="250" x="25" y="10" height="20" rx="4" />
+ <circle cx="290" cy="20" r="10" />
+ <rect width="100" x="315" y="10" height="20" rx="4" />
+ <rect width="100" x="500" y="10" height="20" rx="4" />
+ <rect width="100" x="630" y="10" height="20" rx="4" />
+ <rect x="960" y="0" width="40" height="40" rx="4" />
+ </gl-skeleton-loader>
+ </div>
+</template>
diff --git a/app/assets/javascripts/registry/explorer/components/details_page/tags_table.vue b/app/assets/javascripts/registry/explorer/components/details_page/tags_table.vue
new file mode 100644
index 00000000000..81be778e1e5
--- /dev/null
+++ b/app/assets/javascripts/registry/explorer/components/details_page/tags_table.vue
@@ -0,0 +1,210 @@
+<script>
+import { GlTable, GlFormCheckbox, GlButton, GlTooltipDirective } from '@gitlab/ui';
+import { n__ } from '~/locale';
+import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
+import { numberToHumanSize } from '~/lib/utils/number_utils';
+import timeagoMixin from '~/vue_shared/mixins/timeago';
+import {
+ LIST_KEY_TAG,
+ LIST_KEY_IMAGE_ID,
+ LIST_KEY_SIZE,
+ LIST_KEY_LAST_UPDATED,
+ LIST_KEY_ACTIONS,
+ LIST_KEY_CHECKBOX,
+ LIST_LABEL_TAG,
+ LIST_LABEL_IMAGE_ID,
+ LIST_LABEL_SIZE,
+ LIST_LABEL_LAST_UPDATED,
+ REMOVE_TAGS_BUTTON_TITLE,
+ REMOVE_TAG_BUTTON_TITLE,
+} from '../../constants/index';
+
+export default {
+ components: {
+ GlTable,
+ GlFormCheckbox,
+ GlButton,
+ ClipboardButton,
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
+ mixins: [timeagoMixin],
+ props: {
+ tags: {
+ type: Array,
+ required: false,
+ default: () => [],
+ },
+ isLoading: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ isDesktop: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+ i18n: {
+ REMOVE_TAGS_BUTTON_TITLE,
+ REMOVE_TAG_BUTTON_TITLE,
+ },
+ data() {
+ return {
+ selectedItems: [],
+ };
+ },
+ computed: {
+ fields() {
+ const tagClass = this.isDesktop ? 'w-25' : '';
+ const tagInnerClass = this.isDesktop ? 'mw-m' : 'gl-justify-content-end';
+ return [
+ { key: LIST_KEY_CHECKBOX, label: '', class: 'gl-w-16' },
+ {
+ key: LIST_KEY_TAG,
+ label: LIST_LABEL_TAG,
+ class: `${tagClass} js-tag-column`,
+ innerClass: tagInnerClass,
+ },
+ { key: LIST_KEY_IMAGE_ID, label: LIST_LABEL_IMAGE_ID },
+ { key: LIST_KEY_SIZE, label: LIST_LABEL_SIZE },
+ { key: LIST_KEY_LAST_UPDATED, label: LIST_LABEL_LAST_UPDATED },
+ { key: LIST_KEY_ACTIONS, label: '' },
+ ].filter(f => f.key !== LIST_KEY_CHECKBOX || this.isDesktop);
+ },
+ tagsNames() {
+ return this.tags.map(t => t.name);
+ },
+ selectAllChecked() {
+ return this.selectedItems.length === this.tags.length && this.tags.length > 0;
+ },
+ },
+ watch: {
+ tagsNames: {
+ immediate: false,
+ handler(tagsNames) {
+ this.selectedItems = this.selectedItems.filter(t => tagsNames.includes(t));
+ },
+ },
+ },
+ methods: {
+ formatSize(size) {
+ return numberToHumanSize(size);
+ },
+ layers(layers) {
+ return layers ? n__('%d layer', '%d layers', layers) : '';
+ },
+ onSelectAllChange() {
+ if (this.selectAllChecked) {
+ this.selectedItems = [];
+ } else {
+ this.selectedItems = this.tags.map(x => x.name);
+ }
+ },
+ updateSelectedItems(name) {
+ const delIndex = this.selectedItems.findIndex(x => x === name);
+
+ if (delIndex > -1) {
+ this.selectedItems.splice(delIndex, 1);
+ } else {
+ this.selectedItems.push(name);
+ }
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-table :items="tags" :fields="fields" :stacked="!isDesktop" show-empty :busy="isLoading">
+ <template v-if="isDesktop" #head(checkbox)>
+ <gl-form-checkbox
+ data-testid="mainCheckbox"
+ :checked="selectAllChecked"
+ @change="onSelectAllChange"
+ />
+ </template>
+ <template #head(actions)>
+ <span class="gl-display-flex gl-justify-content-end">
+ <gl-button
+ v-gl-tooltip
+ data-testid="bulkDeleteButton"
+ :disabled="!selectedItems || selectedItems.length === 0"
+ icon="remove"
+ variant="danger"
+ :title="$options.i18n.REMOVE_TAGS_BUTTON_TITLE"
+ :aria-label="$options.i18n.REMOVE_TAGS_BUTTON_TITLE"
+ @click="$emit('delete', selectedItems)"
+ />
+ </span>
+ </template>
+
+ <template #cell(checkbox)="{item}">
+ <gl-form-checkbox
+ data-testid="rowCheckbox"
+ :checked="selectedItems.includes(item.name)"
+ @change="updateSelectedItems(item.name)"
+ />
+ </template>
+ <template #cell(name)="{item, field}">
+ <div data-testid="rowName" :class="[field.innerClass, 'gl-display-flex']">
+ <span
+ v-gl-tooltip
+ data-testid="rowNameText"
+ :title="item.name"
+ class="gl-text-overflow-ellipsis gl-overflow-hidden gl-white-space-nowrap"
+ >
+ {{ item.name }}
+ </span>
+ <clipboard-button
+ v-if="item.location"
+ data-testid="rowClipboardButton"
+ :title="item.location"
+ :text="item.location"
+ css-class="btn-default btn-transparent btn-clipboard"
+ />
+ </div>
+ </template>
+ <template #cell(short_revision)="{value}">
+ <span data-testid="rowShortRevision">
+ {{ value }}
+ </span>
+ </template>
+ <template #cell(total_size)="{item}">
+ <span data-testid="rowSize">
+ {{ formatSize(item.total_size) }}
+ <template v-if="item.total_size && item.layers">
+ &middot;
+ </template>
+ {{ layers(item.layers) }}
+ </span>
+ </template>
+ <template #cell(created_at)="{value}">
+ <span v-gl-tooltip data-testid="rowTime" :title="tooltipTitle(value)">
+ {{ timeFormatted(value) }}
+ </span>
+ </template>
+ <template #cell(actions)="{item}">
+ <span class="gl-display-flex gl-justify-content-end">
+ <gl-button
+ data-testid="singleDeleteButton"
+ :title="$options.i18n.REMOVE_TAG_BUTTON_TITLE"
+ :aria-label="$options.i18n.REMOVE_TAG_BUTTON_TITLE"
+ :disabled="!item.destroy_path"
+ variant="danger"
+ icon="remove"
+ category="secondary"
+ @click="$emit('delete', [item.name])"
+ />
+ </span>
+ </template>
+
+ <template #empty>
+ <slot name="empty"></slot>
+ </template>
+ <template #table-busy>
+ <slot name="loader"></slot>
+ </template>
+ </gl-table>
+</template>
diff --git a/app/assets/javascripts/registry/explorer/components/image_list.vue b/app/assets/javascripts/registry/explorer/components/image_list.vue
deleted file mode 100644
index bc209b12738..00000000000
--- a/app/assets/javascripts/registry/explorer/components/image_list.vue
+++ /dev/null
@@ -1,124 +0,0 @@
-<script>
-import { GlPagination, GlTooltipDirective, GlDeprecatedButton, GlIcon } from '@gitlab/ui';
-import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
-
-import {
- ASYNC_DELETE_IMAGE_ERROR_MESSAGE,
- LIST_DELETE_BUTTON_DISABLED,
- REMOVE_REPOSITORY_LABEL,
- ROW_SCHEDULED_FOR_DELETION,
-} from '../constants';
-
-export default {
- name: 'ImageList',
- components: {
- GlPagination,
- ClipboardButton,
- GlDeprecatedButton,
- GlIcon,
- },
- directives: {
- GlTooltip: GlTooltipDirective,
- },
- props: {
- images: {
- type: Array,
- required: true,
- },
- pagination: {
- type: Object,
- required: true,
- },
- },
- i18n: {
- LIST_DELETE_BUTTON_DISABLED,
- REMOVE_REPOSITORY_LABEL,
- ROW_SCHEDULED_FOR_DELETION,
- ASYNC_DELETE_IMAGE_ERROR_MESSAGE,
- },
- computed: {
- currentPage: {
- get() {
- return this.pagination.page;
- },
- set(page) {
- this.$emit('pageChange', page);
- },
- },
- },
- methods: {
- encodeListItem(item) {
- const params = JSON.stringify({ name: item.path, tags_path: item.tags_path, id: item.id });
- return window.btoa(params);
- },
- },
-};
-</script>
-
-<template>
- <div class="gl-display-flex gl-flex-direction-column">
- <div
- v-for="(listItem, index) in images"
- :key="index"
- v-gl-tooltip="{
- placement: 'left',
- disabled: !listItem.deleting,
- title: $options.i18n.ROW_SCHEDULED_FOR_DELETION,
- }"
- data-testid="rowItem"
- >
- <div
- class="gl-display-flex gl-justify-content-space-between gl-align-items-center gl-py-2 gl-px-1 border-bottom"
- :class="{ 'border-top': index === 0, 'disabled-content': listItem.deleting }"
- >
- <div class="gl-display-flex gl-align-items-center">
- <router-link
- data-testid="detailsLink"
- :to="{ name: 'details', params: { id: encodeListItem(listItem) } }"
- >
- {{ listItem.path }}
- </router-link>
- <clipboard-button
- v-if="listItem.location"
- :disabled="listItem.deleting"
- :text="listItem.location"
- :title="listItem.location"
- css-class="btn-default btn-transparent btn-clipboard"
- />
- <gl-icon
- v-if="listItem.failedDelete"
- v-gl-tooltip
- :title="$options.i18n.ASYNC_DELETE_IMAGE_ERROR_MESSAGE"
- name="warning"
- class="text-warning align-middle"
- />
- </div>
- <div
- v-gl-tooltip="{ disabled: listItem.destroy_path }"
- class="d-none d-sm-block"
- :title="$options.i18n.LIST_DELETE_BUTTON_DISABLED"
- >
- <gl-deprecated-button
- v-gl-tooltip
- data-testid="deleteImageButton"
- :disabled="!listItem.destroy_path || listItem.deleting"
- :title="$options.i18n.REMOVE_REPOSITORY_LABEL"
- :aria-label="$options.i18n.REMOVE_REPOSITORY_LABEL"
- class="btn-inverted"
- variant="danger"
- @click="$emit('delete', listItem)"
- >
- <gl-icon name="remove" />
- </gl-deprecated-button>
- </div>
- </div>
- </div>
- <gl-pagination
- v-model="currentPage"
- :per-page="pagination.perPage"
- :total-items="pagination.total"
- align="center"
- class="w-100 gl-mt-2"
- />
- </div>
-</template>
diff --git a/app/assets/javascripts/registry/explorer/components/list_page/cli_commands.vue b/app/assets/javascripts/registry/explorer/components/list_page/cli_commands.vue
new file mode 100644
index 00000000000..8b06797c0ae
--- /dev/null
+++ b/app/assets/javascripts/registry/explorer/components/list_page/cli_commands.vue
@@ -0,0 +1,103 @@
+<script>
+import { GlDropdown, GlFormGroup, GlFormInputGroup } from '@gitlab/ui';
+import { mapGetters } from 'vuex';
+import Tracking from '~/tracking';
+import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
+import {
+ QUICK_START,
+ LOGIN_COMMAND_LABEL,
+ COPY_LOGIN_TITLE,
+ BUILD_COMMAND_LABEL,
+ COPY_BUILD_TITLE,
+ PUSH_COMMAND_LABEL,
+ COPY_PUSH_TITLE,
+} from '../../constants/index';
+
+export default {
+ components: {
+ GlDropdown,
+ GlFormGroup,
+ GlFormInputGroup,
+ ClipboardButton,
+ },
+ mixins: [Tracking.mixin({ label: 'quickstart_dropdown' })],
+ i18n: {
+ dropdownTitle: QUICK_START,
+ loginCommandLabel: LOGIN_COMMAND_LABEL,
+ copyLoginTitle: COPY_LOGIN_TITLE,
+ buildCommandLabel: BUILD_COMMAND_LABEL,
+ copyBuildTitle: COPY_BUILD_TITLE,
+ pushCommandLabel: PUSH_COMMAND_LABEL,
+ copyPushTitle: COPY_PUSH_TITLE,
+ },
+ computed: {
+ ...mapGetters(['dockerBuildCommand', 'dockerPushCommand', 'dockerLoginCommand']),
+ },
+};
+</script>
+<template>
+ <gl-dropdown
+ :text="$options.i18n.dropdownTitle"
+ variant="primary"
+ size="sm"
+ right
+ @shown="track('click_dropdown')"
+ >
+ <!-- This li is used as a container since gl-dropdown produces a root ul, this mimics the functionality exposed by b-dropdown-form -->
+ <li role="presentation" class="px-2 py-1 dropdown-menu-large">
+ <form>
+ <gl-form-group
+ label-size="sm"
+ label-for="docker-login-btn"
+ :label="$options.i18n.loginCommandLabel"
+ >
+ <gl-form-input-group id="docker-login-btn" :value="dockerLoginCommand" readonly>
+ <template #append>
+ <clipboard-button
+ class="border"
+ :text="dockerLoginCommand"
+ :title="$options.i18n.copyLoginTitle"
+ @click.native="track('click_copy_login')"
+ />
+ </template>
+ </gl-form-input-group>
+ </gl-form-group>
+
+ <gl-form-group
+ label-size="sm"
+ label-for="docker-build-btn"
+ :label="$options.i18n.buildCommandLabel"
+ >
+ <gl-form-input-group id="docker-build-btn" :value="dockerBuildCommand" readonly>
+ <template #append>
+ <clipboard-button
+ class="border"
+ :text="dockerBuildCommand"
+ :title="$options.i18n.copyBuildTitle"
+ @click.native="track('click_copy_build')"
+ />
+ </template>
+ </gl-form-input-group>
+ </gl-form-group>
+
+ <gl-form-group
+ class="mb-0"
+ label-size="sm"
+ label-for="docker-push-btn"
+ :label="$options.i18n.pushCommandLabel"
+ >
+ <gl-form-input-group id="docker-push-btn" :value="dockerPushCommand" readonly>
+ <template #append>
+ <clipboard-button
+ class="border"
+ :text="dockerPushCommand"
+ :title="$options.i18n.copyPushTitle"
+ @click.native="track('click_copy_push')"
+ />
+ </template>
+ </gl-form-input-group>
+ </gl-form-group>
+ </form>
+ </li>
+ </gl-dropdown>
+</template>
diff --git a/app/assets/javascripts/registry/explorer/components/group_empty_state.vue b/app/assets/javascripts/registry/explorer/components/list_page/group_empty_state.vue
index a29a9bd23c3..a29a9bd23c3 100644
--- a/app/assets/javascripts/registry/explorer/components/group_empty_state.vue
+++ b/app/assets/javascripts/registry/explorer/components/list_page/group_empty_state.vue
diff --git a/app/assets/javascripts/registry/explorer/components/list_page/image_list.vue b/app/assets/javascripts/registry/explorer/components/list_page/image_list.vue
new file mode 100644
index 00000000000..9d48769cbad
--- /dev/null
+++ b/app/assets/javascripts/registry/explorer/components/list_page/image_list.vue
@@ -0,0 +1,52 @@
+<script>
+import { GlPagination } from '@gitlab/ui';
+import ImageListRow from './image_list_row.vue';
+
+export default {
+ name: 'ImageList',
+ components: {
+ GlPagination,
+ ImageListRow,
+ },
+ props: {
+ images: {
+ type: Array,
+ required: true,
+ },
+ pagination: {
+ type: Object,
+ required: true,
+ },
+ },
+ computed: {
+ currentPage: {
+ get() {
+ return this.pagination.page;
+ },
+ set(page) {
+ this.$emit('pageChange', page);
+ },
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="gl-display-flex gl-flex-direction-column">
+ <image-list-row
+ v-for="(listItem, index) in images"
+ :key="index"
+ :item="listItem"
+ :show-top-border="index === 0"
+ @delete="$emit('delete', $event)"
+ />
+
+ <gl-pagination
+ v-model="currentPage"
+ :per-page="pagination.perPage"
+ :total-items="pagination.total"
+ align="center"
+ class="w-100 gl-mt-3"
+ />
+ </div>
+</template>
diff --git a/app/assets/javascripts/registry/explorer/components/list_page/image_list_row.vue b/app/assets/javascripts/registry/explorer/components/list_page/image_list_row.vue
new file mode 100644
index 00000000000..cd878c38081
--- /dev/null
+++ b/app/assets/javascripts/registry/explorer/components/list_page/image_list_row.vue
@@ -0,0 +1,136 @@
+<script>
+import { GlTooltipDirective, GlButton, GlIcon, GlSprintf } from '@gitlab/ui';
+import { n__ } from '~/locale';
+import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
+
+import {
+ ASYNC_DELETE_IMAGE_ERROR_MESSAGE,
+ LIST_DELETE_BUTTON_DISABLED,
+ REMOVE_REPOSITORY_LABEL,
+ ROW_SCHEDULED_FOR_DELETION,
+} from '../../constants/index';
+
+export default {
+ name: 'ImageListrow',
+ components: {
+ ClipboardButton,
+ GlButton,
+ GlSprintf,
+ GlIcon,
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
+ props: {
+ item: {
+ type: Object,
+ required: true,
+ },
+ showTopBorder: {
+ type: Boolean,
+ default: false,
+ required: false,
+ },
+ },
+ i18n: {
+ LIST_DELETE_BUTTON_DISABLED,
+ REMOVE_REPOSITORY_LABEL,
+ ROW_SCHEDULED_FOR_DELETION,
+ ASYNC_DELETE_IMAGE_ERROR_MESSAGE,
+ },
+ computed: {
+ encodedItem() {
+ const params = JSON.stringify({
+ name: this.item.path,
+ tags_path: this.item.tags_path,
+ id: this.item.id,
+ });
+ return window.btoa(params);
+ },
+ disabledDelete() {
+ return !this.item.destroy_path || this.item.deleting;
+ },
+ tagsCountText() {
+ return n__(
+ 'ContainerRegistry|%{count} Tag',
+ 'ContainerRegistry|%{count} Tags',
+ this.item.tags_count,
+ );
+ },
+ },
+};
+</script>
+
+<template>
+ <div
+ v-gl-tooltip="{
+ placement: 'left',
+ disabled: !item.deleting,
+ title: $options.i18n.ROW_SCHEDULED_FOR_DELETION,
+ }"
+ >
+ <div
+ class="gl-display-flex gl-justify-content-space-between gl-align-items-center gl-py-2 gl-px-1 gl-border-gray-200 gl-border-b-solid gl-border-b-1 gl-py-4 "
+ :class="{
+ 'gl-border-t-solid gl-border-t-1': showTopBorder,
+ 'disabled-content': item.deleting,
+ }"
+ >
+ <div class="gl-display-flex gl-flex-direction-column">
+ <div class="gl-display-flex gl-align-items-center">
+ <router-link
+ class="gl-text-black-normal gl-font-weight-bold"
+ data-testid="detailsLink"
+ :to="{ name: 'details', params: { id: encodedItem } }"
+ >
+ {{ item.path }}
+ </router-link>
+ <clipboard-button
+ v-if="item.location"
+ :disabled="item.deleting"
+ :text="item.location"
+ :title="item.location"
+ css-class="btn-default btn-transparent btn-clipboard gl-text-gray-500"
+ />
+ <gl-icon
+ v-if="item.failedDelete"
+ v-gl-tooltip
+ :title="$options.i18n.ASYNC_DELETE_IMAGE_ERROR_MESSAGE"
+ name="warning"
+ class="text-warning"
+ />
+ </div>
+ <div class="gl-font-sm gl-text-gray-500">
+ <span class="gl-display-flex gl-align-items-center" data-testid="tagsCount">
+ <gl-icon name="tag" class="gl-mr-2" />
+ <gl-sprintf :message="tagsCountText">
+ <template #count>
+ {{ item.tags_count }}
+ </template>
+ </gl-sprintf>
+ </span>
+ </div>
+ </div>
+ <div
+ v-gl-tooltip="{
+ disabled: item.destroy_path,
+ title: $options.i18n.LIST_DELETE_BUTTON_DISABLED,
+ }"
+ class="d-none d-sm-block"
+ data-testid="deleteButtonWrapper"
+ >
+ <gl-button
+ v-gl-tooltip
+ data-testid="deleteImageButton"
+ :disabled="disabledDelete"
+ :title="$options.i18n.REMOVE_REPOSITORY_LABEL"
+ :aria-label="$options.i18n.REMOVE_REPOSITORY_LABEL"
+ category="secondary"
+ variant="danger"
+ icon="remove"
+ @click="$emit('delete', item)"
+ />
+ </div>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/registry/explorer/components/list_page/project_empty_state.vue b/app/assets/javascripts/registry/explorer/components/list_page/project_empty_state.vue
new file mode 100644
index 00000000000..c27d53f4351
--- /dev/null
+++ b/app/assets/javascripts/registry/explorer/components/list_page/project_empty_state.vue
@@ -0,0 +1,107 @@
+<script>
+import { GlEmptyState, GlSprintf, GlLink } from '@gitlab/ui';
+import { mapState, mapGetters } from 'vuex';
+import { s__ } from '~/locale';
+import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
+import {
+ COPY_LOGIN_TITLE,
+ COPY_BUILD_TITLE,
+ COPY_PUSH_TITLE,
+ QUICK_START,
+} from '../../constants/index';
+
+export default {
+ name: 'ProjectEmptyState',
+ components: {
+ ClipboardButton,
+ GlEmptyState,
+ GlSprintf,
+ GlLink,
+ },
+ i18n: {
+ quickStart: QUICK_START,
+ copyLoginTitle: COPY_LOGIN_TITLE,
+ copyBuildTitle: COPY_BUILD_TITLE,
+ copyPushTitle: COPY_PUSH_TITLE,
+ introText: s__(
+ `ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}`,
+ ),
+ notLoggedInMessage: s__(
+ `ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password.`,
+ ),
+ addImageText: s__(
+ 'ContainerRegistry|You can add an image to this registry with the following commands:',
+ ),
+ },
+ computed: {
+ ...mapState(['config']),
+ ...mapGetters(['dockerBuildCommand', 'dockerPushCommand', 'dockerLoginCommand']),
+ },
+};
+</script>
+<template>
+ <gl-empty-state
+ :title="s__('ContainerRegistry|There are no container images stored for this project')"
+ :svg-path="config.noContainersImage"
+ class="container-message"
+ >
+ <template #description>
+ <p class="js-no-container-images-text">
+ <gl-sprintf :message="$options.i18n.introText">
+ <template #docLink="{content}">
+ <gl-link :href="config.helpPagePath" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </p>
+ <h5>{{ $options.i18n.quickStart }}</h5>
+ <p class="js-not-logged-in-to-registry-text">
+ <gl-sprintf :message="$options.i18n.notLoggedInMessage">
+ <template #twofaDocLink="{content}">
+ <gl-link :href="config.twoFactorAuthHelpLink" target="_blank">{{ content }}</gl-link>
+ </template>
+ <template #personalAccessTokensDocLink="{content}">
+ <gl-link :href="config.personalAccessTokensHelpLink" target="_blank">{{
+ content
+ }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </p>
+ <div class="input-group append-bottom-10">
+ <input :value="dockerLoginCommand" type="text" class="form-control monospace" readonly />
+ <span class="input-group-append">
+ <clipboard-button
+ :text="dockerLoginCommand"
+ :title="$options.i18n.copyLoginTitle"
+ class="input-group-text"
+ />
+ </span>
+ </div>
+ <p></p>
+ <p>
+ {{ $options.i18n.addImageText }}
+ </p>
+
+ <div class="input-group append-bottom-10">
+ <input :value="dockerBuildCommand" type="text" class="form-control monospace" readonly />
+ <span class="input-group-append">
+ <clipboard-button
+ :text="dockerBuildCommand"
+ :title="$options.i18n.copyBuildTitle"
+ class="input-group-text"
+ />
+ </span>
+ </div>
+
+ <div class="input-group">
+ <input :value="dockerPushCommand" type="text" class="form-control monospace" readonly />
+ <span class="input-group-append">
+ <clipboard-button
+ :text="dockerPushCommand"
+ :title="$options.i18n.copyPushTitle"
+ class="input-group-text"
+ />
+ </span>
+ </div>
+ </template>
+ </gl-empty-state>
+</template>
diff --git a/app/assets/javascripts/registry/explorer/components/list_page/registry_header.vue b/app/assets/javascripts/registry/explorer/components/list_page/registry_header.vue
new file mode 100644
index 00000000000..d4ff84447bb
--- /dev/null
+++ b/app/assets/javascripts/registry/explorer/components/list_page/registry_header.vue
@@ -0,0 +1,138 @@
+<script>
+import { GlSprintf, GlLink, GlIcon } from '@gitlab/ui';
+import { n__ } from '~/locale';
+import { approximateDuration, calculateRemainingMilliseconds } from '~/lib/utils/datetime_utility';
+
+import {
+ CONTAINER_REGISTRY_TITLE,
+ LIST_INTRO_TEXT,
+ EXPIRATION_POLICY_WILL_RUN_IN,
+ EXPIRATION_POLICY_DISABLED_TEXT,
+ EXPIRATION_POLICY_DISABLED_MESSAGE,
+} from '../../constants/index';
+
+export default {
+ components: {
+ GlIcon,
+ GlSprintf,
+ GlLink,
+ },
+ props: {
+ expirationPolicy: {
+ type: Object,
+ default: () => ({}),
+ required: false,
+ },
+ imagesCount: {
+ type: Number,
+ default: 0,
+ required: false,
+ },
+ helpPagePath: {
+ type: String,
+ default: '',
+ required: false,
+ },
+ expirationPolicyHelpPagePath: {
+ type: String,
+ default: '',
+ required: false,
+ },
+ hideExpirationPolicyData: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+ loader: {
+ repeat: 10,
+ width: 1000,
+ height: 40,
+ },
+ i18n: {
+ CONTAINER_REGISTRY_TITLE,
+ LIST_INTRO_TEXT,
+ EXPIRATION_POLICY_DISABLED_MESSAGE,
+ },
+ computed: {
+ imagesCountText() {
+ return n__(
+ 'ContainerRegistry|%{count} Image repository',
+ 'ContainerRegistry|%{count} Image repositories',
+ this.imagesCount,
+ );
+ },
+ timeTillRun() {
+ const difference = calculateRemainingMilliseconds(this.expirationPolicy?.next_run_at);
+ return approximateDuration(difference / 1000);
+ },
+ expirationPolicyEnabled() {
+ return this.expirationPolicy?.enabled;
+ },
+ expirationPolicyText() {
+ return this.expirationPolicyEnabled
+ ? EXPIRATION_POLICY_WILL_RUN_IN
+ : EXPIRATION_POLICY_DISABLED_TEXT;
+ },
+ showExpirationPolicyTip() {
+ return (
+ !this.expirationPolicyEnabled && this.imagesCount > 0 && !this.hideExpirationPolicyData
+ );
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <div
+ class="gl-display-flex gl-justify-content-space-between gl-align-items-center"
+ data-testid="header"
+ >
+ <h4 data-testid="title">{{ $options.i18n.CONTAINER_REGISTRY_TITLE }}</h4>
+ <div class="gl-display-none d-sm-block" data-testid="commands-slot">
+ <slot name="commands"></slot>
+ </div>
+ </div>
+ <div
+ v-if="imagesCount"
+ class="gl-display-flex gl-align-items-center gl-mt-1 gl-mb-3 gl-text-gray-700"
+ data-testid="subheader"
+ >
+ <span class="gl-mr-3" data-testid="images-count">
+ <gl-icon class="gl-mr-1" name="container-image" />
+ <gl-sprintf :message="imagesCountText">
+ <template #count>
+ {{ imagesCount }}
+ </template>
+ </gl-sprintf>
+ </span>
+ <span v-if="!hideExpirationPolicyData" data-testid="expiration-policy">
+ <gl-icon class="gl-mr-1" name="expire" />
+ <gl-sprintf :message="expirationPolicyText">
+ <template #time>
+ {{ timeTillRun }}
+ </template>
+ </gl-sprintf>
+ </span>
+ </div>
+ <div data-testid="info-area">
+ <p>
+ <span data-testid="default-intro">
+ <gl-sprintf :message="$options.i18n.LIST_INTRO_TEXT">
+ <template #docLink="{content}">
+ <gl-link :href="helpPagePath" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </span>
+ <span v-if="showExpirationPolicyTip" data-testid="expiration-disabled-message">
+ <gl-sprintf :message="$options.i18n.EXPIRATION_POLICY_DISABLED_MESSAGE">
+ <template #docLink="{content}">
+ <gl-link :href="expirationPolicyHelpPagePath" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </span>
+ </p>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/registry/explorer/components/project_empty_state.vue b/app/assets/javascripts/registry/explorer/components/project_empty_state.vue
deleted file mode 100644
index 0ce38c4a9ec..00000000000
--- a/app/assets/javascripts/registry/explorer/components/project_empty_state.vue
+++ /dev/null
@@ -1,102 +0,0 @@
-<script>
-import { GlEmptyState, GlSprintf, GlLink } from '@gitlab/ui';
-import { mapState, mapGetters } from 'vuex';
-import { s__ } from '~/locale';
-import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
-import { COPY_LOGIN_TITLE, COPY_BUILD_TITLE, COPY_PUSH_TITLE, QUICK_START } from '../constants';
-
-export default {
- name: 'ProjectEmptyState',
- components: {
- ClipboardButton,
- GlEmptyState,
- GlSprintf,
- GlLink,
- },
- i18n: {
- quickStart: QUICK_START,
- copyLoginTitle: COPY_LOGIN_TITLE,
- copyBuildTitle: COPY_BUILD_TITLE,
- copyPushTitle: COPY_PUSH_TITLE,
- introText: s__(
- `ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}`,
- ),
- notLoggedInMessage: s__(
- `ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password.`,
- ),
- addImageText: s__(
- 'ContainerRegistry|You can add an image to this registry with the following commands:',
- ),
- },
- computed: {
- ...mapState(['config']),
- ...mapGetters(['dockerBuildCommand', 'dockerPushCommand', 'dockerLoginCommand']),
- },
-};
-</script>
-<template>
- <gl-empty-state
- :title="s__('ContainerRegistry|There are no container images stored for this project')"
- :svg-path="config.noContainersImage"
- class="container-message"
- >
- <template #description>
- <p class="js-no-container-images-text">
- <gl-sprintf :message="$options.i18n.introText">
- <template #docLink="{content}">
- <gl-link :href="config.helpPagePath" target="_blank">{{ content }}</gl-link>
- </template>
- </gl-sprintf>
- </p>
- <h5>{{ $options.i18n.quickStart }}</h5>
- <p class="js-not-logged-in-to-registry-text">
- <gl-sprintf :message="$options.i18n.notLoggedInMessage">
- <template #twofaDocLink="{content}">
- <gl-link :href="config.twoFactorAuthHelpLink" target="_blank">{{ content }}</gl-link>
- </template>
- <template #personalAccessTokensDocLink="{content}">
- <gl-link :href="config.personalAccessTokensHelpLink" target="_blank">{{
- content
- }}</gl-link>
- </template>
- </gl-sprintf>
- </p>
- <div class="input-group append-bottom-10">
- <input :value="dockerLoginCommand" type="text" class="form-control monospace" readonly />
- <span class="input-group-append">
- <clipboard-button
- :text="dockerLoginCommand"
- :title="$options.i18n.copyLoginTitle"
- class="input-group-text"
- />
- </span>
- </div>
- <p></p>
- <p>
- {{ $options.i18n.addImageText }}
- </p>
-
- <div class="input-group append-bottom-10">
- <input :value="dockerBuildCommand" type="text" class="form-control monospace" readonly />
- <span class="input-group-append">
- <clipboard-button
- :text="dockerBuildCommand"
- :title="$options.i18n.copyBuildTitle"
- class="input-group-text"
- />
- </span>
- </div>
-
- <div class="input-group">
- <input :value="dockerPushCommand" type="text" class="form-control monospace" readonly />
- <span class="input-group-append">
- <clipboard-button
- :text="dockerPushCommand"
- :title="$options.i18n.copyPushTitle"
- class="input-group-text"
- />
- </span>
- </div>
- </template>
- </gl-empty-state>
-</template>
diff --git a/app/assets/javascripts/registry/explorer/components/project_policy_alert.vue b/app/assets/javascripts/registry/explorer/components/project_policy_alert.vue
deleted file mode 100644
index 88a0710574f..00000000000
--- a/app/assets/javascripts/registry/explorer/components/project_policy_alert.vue
+++ /dev/null
@@ -1,68 +0,0 @@
-<script>
-import { GlAlert, GlSprintf, GlLink } from '@gitlab/ui';
-import { mapState } from 'vuex';
-import { approximateDuration, calculateRemainingMilliseconds } from '~/lib/utils/datetime_utility';
-import {
- EXPIRATION_POLICY_ALERT_TITLE,
- EXPIRATION_POLICY_ALERT_PRIMARY_BUTTON,
- EXPIRATION_POLICY_ALERT_FULL_MESSAGE,
- EXPIRATION_POLICY_ALERT_SHORT_MESSAGE,
-} from '../constants';
-
-export default {
- components: {
- GlAlert,
- GlSprintf,
- GlLink,
- },
-
- computed: {
- ...mapState(['config', 'images', 'isLoading']),
- isEmpty() {
- return !this.images || this.images.length === 0;
- },
- showAlert() {
- return this.config.expirationPolicy?.enabled;
- },
- timeTillRun() {
- const difference = calculateRemainingMilliseconds(this.config.expirationPolicy?.next_run_at);
- return approximateDuration(difference / 1000);
- },
- alertConfiguration() {
- if (this.isEmpty || this.isLoading) {
- return {
- title: null,
- primaryButton: null,
- message: EXPIRATION_POLICY_ALERT_SHORT_MESSAGE,
- };
- }
- return {
- title: EXPIRATION_POLICY_ALERT_TITLE,
- primaryButton: EXPIRATION_POLICY_ALERT_PRIMARY_BUTTON,
- message: EXPIRATION_POLICY_ALERT_FULL_MESSAGE,
- };
- },
- },
-};
-</script>
-
-<template>
- <gl-alert
- v-if="showAlert"
- :dismissible="false"
- :primary-button-text="alertConfiguration.primaryButton"
- :primary-button-link="config.settingsPath"
- :title="alertConfiguration.title"
- >
- <gl-sprintf :message="alertConfiguration.message">
- <template #days>
- <strong>{{ timeTillRun }}</strong>
- </template>
- <template #link="{content}">
- <gl-link :href="config.expirationPolicyHelpPagePath" target="_blank">
- {{ content }}
- </gl-link>
- </template>
- </gl-sprintf>
- </gl-alert>
-</template>
diff --git a/app/assets/javascripts/registry/explorer/components/quickstart_dropdown.vue b/app/assets/javascripts/registry/explorer/components/quickstart_dropdown.vue
deleted file mode 100644
index 96455496239..00000000000
--- a/app/assets/javascripts/registry/explorer/components/quickstart_dropdown.vue
+++ /dev/null
@@ -1,103 +0,0 @@
-<script>
-import { GlDropdown, GlFormGroup, GlFormInputGroup } from '@gitlab/ui';
-import { mapGetters } from 'vuex';
-import Tracking from '~/tracking';
-import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
-import {
- QUICK_START,
- LOGIN_COMMAND_LABEL,
- COPY_LOGIN_TITLE,
- BUILD_COMMAND_LABEL,
- COPY_BUILD_TITLE,
- PUSH_COMMAND_LABEL,
- COPY_PUSH_TITLE,
-} from '../constants';
-
-export default {
- components: {
- GlDropdown,
- GlFormGroup,
- GlFormInputGroup,
- ClipboardButton,
- },
- mixins: [Tracking.mixin({ label: 'quickstart_dropdown' })],
- i18n: {
- dropdownTitle: QUICK_START,
- loginCommandLabel: LOGIN_COMMAND_LABEL,
- copyLoginTitle: COPY_LOGIN_TITLE,
- buildCommandLabel: BUILD_COMMAND_LABEL,
- copyBuildTitle: COPY_BUILD_TITLE,
- pushCommandLabel: PUSH_COMMAND_LABEL,
- copyPushTitle: COPY_PUSH_TITLE,
- },
- computed: {
- ...mapGetters(['dockerBuildCommand', 'dockerPushCommand', 'dockerLoginCommand']),
- },
-};
-</script>
-<template>
- <gl-dropdown
- :text="$options.i18n.dropdownTitle"
- variant="primary"
- size="sm"
- right
- @shown="track('click_dropdown')"
- >
- <!-- This li is used as a container since gl-dropdown produces a root ul, this mimics the functionality exposed by b-dropdown-form -->
- <li role="presentation" class="px-2 py-1 dropdown-menu-large">
- <form>
- <gl-form-group
- label-size="sm"
- label-for="docker-login-btn"
- :label="$options.i18n.loginCommandLabel"
- >
- <gl-form-input-group id="docker-login-btn" :value="dockerLoginCommand" readonly>
- <template #append>
- <clipboard-button
- class="border"
- :text="dockerLoginCommand"
- :title="$options.i18n.copyLoginTitle"
- @click.native="track('click_copy_login')"
- />
- </template>
- </gl-form-input-group>
- </gl-form-group>
-
- <gl-form-group
- label-size="sm"
- label-for="docker-build-btn"
- :label="$options.i18n.buildCommandLabel"
- >
- <gl-form-input-group id="docker-build-btn" :value="dockerBuildCommand" readonly>
- <template #append>
- <clipboard-button
- class="border"
- :text="dockerBuildCommand"
- :title="$options.i18n.copyBuildTitle"
- @click.native="track('click_copy_build')"
- />
- </template>
- </gl-form-input-group>
- </gl-form-group>
-
- <gl-form-group
- class="mb-0"
- label-size="sm"
- label-for="docker-push-btn"
- :label="$options.i18n.pushCommandLabel"
- >
- <gl-form-input-group id="docker-push-btn" :value="dockerPushCommand" readonly>
- <template #append>
- <clipboard-button
- class="border"
- :text="dockerPushCommand"
- :title="$options.i18n.copyPushTitle"
- @click.native="track('click_copy_push')"
- />
- </template>
- </gl-form-input-group>
- </gl-form-group>
- </form>
- </li>
- </gl-dropdown>
-</template>
diff --git a/app/assets/javascripts/registry/explorer/constants.js b/app/assets/javascripts/registry/explorer/constants.js
deleted file mode 100644
index 7cbe657bfc0..00000000000
--- a/app/assets/javascripts/registry/explorer/constants.js
+++ /dev/null
@@ -1,130 +0,0 @@
-import { s__ } from '~/locale';
-
-// List page
-
-export const CONTAINER_REGISTRY_TITLE = s__('ContainerRegistry|Container Registry');
-export const CONNECTION_ERROR_TITLE = s__('ContainerRegistry|Docker connection error');
-export const CONNECTION_ERROR_MESSAGE = s__(
- `ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}`,
-);
-export const LIST_INTRO_TEXT = s__(
- `ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}`,
-);
-
-export const LIST_DELETE_BUTTON_DISABLED = s__(
- 'ContainerRegistry|Missing or insufficient permission, delete button disabled',
-);
-export const REMOVE_REPOSITORY_LABEL = s__('ContainerRegistry|Remove repository');
-export const REMOVE_REPOSITORY_MODAL_TEXT = s__(
- 'ContainerRegistry|You are about to remove repository %{title}. Once you confirm, this repository will be permanently deleted.',
-);
-export const ROW_SCHEDULED_FOR_DELETION = s__(
- `ContainerRegistry|This image repository is scheduled for deletion`,
-);
-export const FETCH_IMAGES_LIST_ERROR_MESSAGE = s__(
- 'ContainerRegistry|Something went wrong while fetching the repository list.',
-);
-export const FETCH_TAGS_LIST_ERROR_MESSAGE = s__(
- 'ContainerRegistry|Something went wrong while fetching the tags list.',
-);
-export const DELETE_IMAGE_ERROR_MESSAGE = s__(
- 'ContainerRegistry|Something went wrong while scheduling %{title} for deletion. Please try again.',
-);
-export const ASYNC_DELETE_IMAGE_ERROR_MESSAGE = s__(
- `ContainerRegistry|There was an error during the deletion of this image repository, please try again.`,
-);
-export const DELETE_IMAGE_SUCCESS_MESSAGE = s__(
- 'ContainerRegistry|%{title} was successfully scheduled for deletion',
-);
-
-export const IMAGE_REPOSITORY_LIST_LABEL = s__('ContainerRegistry|Image Repositories');
-
-export const SEARCH_PLACEHOLDER_TEXT = s__('ContainerRegistry|Filter by name');
-
-export const EMPTY_RESULT_TITLE = s__('ContainerRegistry|Sorry, your filter produced no results.');
-export const EMPTY_RESULT_MESSAGE = s__(
- 'ContainerRegistry|To widen your search, change or remove the filters above.',
-);
-
-// Image details page
-
-export const DETAILS_PAGE_TITLE = s__('ContainerRegistry|%{imageName} tags');
-
-export const DELETE_TAG_ERROR_MESSAGE = s__(
- 'ContainerRegistry|Something went wrong while marking the tag for deletion.',
-);
-export const DELETE_TAG_SUCCESS_MESSAGE = s__(
- 'ContainerRegistry|Tag successfully marked for deletion.',
-);
-export const DELETE_TAGS_ERROR_MESSAGE = s__(
- 'ContainerRegistry|Something went wrong while marking the tags for deletion.',
-);
-export const DELETE_TAGS_SUCCESS_MESSAGE = s__(
- 'ContainerRegistry|Tags successfully marked for deletion.',
-);
-
-export const DEFAULT_PAGE = 1;
-export const DEFAULT_PAGE_SIZE = 10;
-
-export const GROUP_PAGE_TYPE = 'groups';
-
-export const LIST_KEY_TAG = 'name';
-export const LIST_KEY_IMAGE_ID = 'short_revision';
-export const LIST_KEY_SIZE = 'total_size';
-export const LIST_KEY_LAST_UPDATED = 'created_at';
-export const LIST_KEY_ACTIONS = 'actions';
-export const LIST_KEY_CHECKBOX = 'checkbox';
-
-export const LIST_LABEL_TAG = s__('ContainerRegistry|Tag');
-export const LIST_LABEL_IMAGE_ID = s__('ContainerRegistry|Image ID');
-export const LIST_LABEL_SIZE = s__('ContainerRegistry|Compressed Size');
-export const LIST_LABEL_LAST_UPDATED = s__('ContainerRegistry|Last Updated');
-
-export const REMOVE_TAG_BUTTON_TITLE = s__('ContainerRegistry|Remove tag');
-export const REMOVE_TAGS_BUTTON_TITLE = s__('ContainerRegistry|Remove selected tags');
-
-export const REMOVE_TAG_CONFIRMATION_TEXT = s__(
- `ContainerRegistry|You are about to remove %{item}. Are you sure?`,
-);
-export const REMOVE_TAGS_CONFIRMATION_TEXT = s__(
- `ContainerRegistry|You are about to remove %{item} tags. Are you sure?`,
-);
-
-export const EMPTY_IMAGE_REPOSITORY_TITLE = s__('ContainerRegistry|This image has no active tags');
-export const EMPTY_IMAGE_REPOSITORY_MESSAGE = s__(
- `ContainerRegistry|The last tag related to this image was recently removed.
-This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process.
-If you have any questions, contact your administrator.`,
-);
-
-export const ADMIN_GARBAGE_COLLECTION_TIP = s__(
- 'ContainerRegistry|Remember to run %{docLinkStart}garbage collection%{docLinkEnd} to remove the stale data from storage.',
-);
-
-// Expiration policies
-
-export const EXPIRATION_POLICY_ALERT_TITLE = s__(
- 'ContainerRegistry|Retention policy has been Enabled',
-);
-export const EXPIRATION_POLICY_ALERT_PRIMARY_BUTTON = s__('ContainerRegistry|Edit Settings');
-export const EXPIRATION_POLICY_ALERT_FULL_MESSAGE = s__(
- 'ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}',
-);
-export const EXPIRATION_POLICY_ALERT_SHORT_MESSAGE = s__(
- 'ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}',
-);
-
-// Quick Start
-
-export const QUICK_START = s__('ContainerRegistry|Quick Start');
-export const LOGIN_COMMAND_LABEL = s__('ContainerRegistry|Login');
-export const COPY_LOGIN_TITLE = s__('ContainerRegistry|Copy login command');
-export const BUILD_COMMAND_LABEL = s__('ContainerRegistry|Build an image');
-export const COPY_BUILD_TITLE = s__('ContainerRegistry|Copy build command');
-export const PUSH_COMMAND_LABEL = s__('ContainerRegistry|Push an image');
-export const COPY_PUSH_TITLE = s__('ContainerRegistry|Copy push command');
-
-// Image state
-
-export const IMAGE_DELETE_SCHEDULED_STATUS = 'delete_scheduled';
-export const IMAGE_FAILED_DELETED_STATUS = 'delete_failed';
diff --git a/app/assets/javascripts/registry/explorer/constants/details.js b/app/assets/javascripts/registry/explorer/constants/details.js
new file mode 100644
index 00000000000..a1fa995c17f
--- /dev/null
+++ b/app/assets/javascripts/registry/explorer/constants/details.js
@@ -0,0 +1,60 @@
+import { s__ } from '~/locale';
+
+// Translations strings
+export const DETAILS_PAGE_TITLE = s__('ContainerRegistry|%{imageName} tags');
+export const DELETE_TAG_ERROR_MESSAGE = s__(
+ 'ContainerRegistry|Something went wrong while marking the tag for deletion.',
+);
+export const DELETE_TAG_SUCCESS_MESSAGE = s__(
+ 'ContainerRegistry|Tag successfully marked for deletion.',
+);
+export const DELETE_TAGS_ERROR_MESSAGE = s__(
+ 'ContainerRegistry|Something went wrong while marking the tags for deletion.',
+);
+export const DELETE_TAGS_SUCCESS_MESSAGE = s__(
+ 'ContainerRegistry|Tags successfully marked for deletion.',
+);
+export const LIST_LABEL_TAG = s__('ContainerRegistry|Tag');
+export const LIST_LABEL_IMAGE_ID = s__('ContainerRegistry|Image ID');
+export const LIST_LABEL_SIZE = s__('ContainerRegistry|Compressed Size');
+export const LIST_LABEL_LAST_UPDATED = s__('ContainerRegistry|Last Updated');
+export const REMOVE_TAG_BUTTON_TITLE = s__('ContainerRegistry|Remove tag');
+export const REMOVE_TAGS_BUTTON_TITLE = s__('ContainerRegistry|Remove selected tags');
+export const REMOVE_TAG_CONFIRMATION_TEXT = s__(
+ `ContainerRegistry|You are about to remove %{item}. Are you sure?`,
+);
+export const REMOVE_TAGS_CONFIRMATION_TEXT = s__(
+ `ContainerRegistry|You are about to remove %{item} tags. Are you sure?`,
+);
+export const EMPTY_IMAGE_REPOSITORY_TITLE = s__('ContainerRegistry|This image has no active tags');
+export const EMPTY_IMAGE_REPOSITORY_MESSAGE = s__(
+ `ContainerRegistry|The last tag related to this image was recently removed.
+This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process.
+If you have any questions, contact your administrator.`,
+);
+export const ADMIN_GARBAGE_COLLECTION_TIP = s__(
+ 'ContainerRegistry|Remember to run %{docLinkStart}garbage collection%{docLinkEnd} to remove the stale data from storage.',
+);
+
+// Parameters
+
+export const DEFAULT_PAGE = 1;
+export const DEFAULT_PAGE_SIZE = 10;
+export const GROUP_PAGE_TYPE = 'groups';
+export const LIST_KEY_TAG = 'name';
+export const LIST_KEY_IMAGE_ID = 'short_revision';
+export const LIST_KEY_SIZE = 'total_size';
+export const LIST_KEY_LAST_UPDATED = 'created_at';
+export const LIST_KEY_ACTIONS = 'actions';
+export const LIST_KEY_CHECKBOX = 'checkbox';
+export const ALERT_SUCCESS_TAG = 'success_tag';
+export const ALERT_DANGER_TAG = 'danger_tag';
+export const ALERT_SUCCESS_TAGS = 'success_tags';
+export const ALERT_DANGER_TAGS = 'danger_tags';
+
+export const ALERT_MESSAGES = {
+ [ALERT_SUCCESS_TAG]: DELETE_TAG_SUCCESS_MESSAGE,
+ [ALERT_DANGER_TAG]: DELETE_TAG_ERROR_MESSAGE,
+ [ALERT_SUCCESS_TAGS]: DELETE_TAGS_SUCCESS_MESSAGE,
+ [ALERT_DANGER_TAGS]: DELETE_TAGS_ERROR_MESSAGE,
+};
diff --git a/app/assets/javascripts/registry/explorer/constants/expiration_policies.js b/app/assets/javascripts/registry/explorer/constants/expiration_policies.js
new file mode 100644
index 00000000000..8af25ca6ecc
--- /dev/null
+++ b/app/assets/javascripts/registry/explorer/constants/expiration_policies.js
@@ -0,0 +1,11 @@
+import { s__ } from '~/locale';
+
+export const EXPIRATION_POLICY_WILL_RUN_IN = s__(
+ 'ContainerRegistry|Expiration policy will run in %{time}',
+);
+export const EXPIRATION_POLICY_DISABLED_TEXT = s__(
+ 'ContainerRegistry|Expiration policy is disabled',
+);
+export const EXPIRATION_POLICY_DISABLED_MESSAGE = s__(
+ 'ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}',
+);
diff --git a/app/assets/javascripts/registry/explorer/constants/index.js b/app/assets/javascripts/registry/explorer/constants/index.js
new file mode 100644
index 00000000000..10816e12ead
--- /dev/null
+++ b/app/assets/javascripts/registry/explorer/constants/index.js
@@ -0,0 +1,4 @@
+export * from './expiration_policies';
+export * from './quick_start';
+export * from './list';
+export * from './details';
diff --git a/app/assets/javascripts/registry/explorer/constants/list.js b/app/assets/javascripts/registry/explorer/constants/list.js
new file mode 100644
index 00000000000..39f63d2a153
--- /dev/null
+++ b/app/assets/javascripts/registry/explorer/constants/list.js
@@ -0,0 +1,48 @@
+import { s__ } from '~/locale';
+
+// Translations strings
+
+export const CONTAINER_REGISTRY_TITLE = s__('ContainerRegistry|Container Registry');
+export const CONNECTION_ERROR_TITLE = s__('ContainerRegistry|Docker connection error');
+export const CONNECTION_ERROR_MESSAGE = s__(
+ `ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}`,
+);
+export const LIST_INTRO_TEXT = s__(
+ `ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}`,
+);
+export const LIST_DELETE_BUTTON_DISABLED = s__(
+ 'ContainerRegistry|Missing or insufficient permission, delete button disabled',
+);
+export const REMOVE_REPOSITORY_LABEL = s__('ContainerRegistry|Remove repository');
+export const REMOVE_REPOSITORY_MODAL_TEXT = s__(
+ 'ContainerRegistry|You are about to remove repository %{title}. Once you confirm, this repository will be permanently deleted.',
+);
+export const ROW_SCHEDULED_FOR_DELETION = s__(
+ `ContainerRegistry|This image repository is scheduled for deletion`,
+);
+export const FETCH_IMAGES_LIST_ERROR_MESSAGE = s__(
+ 'ContainerRegistry|Something went wrong while fetching the repository list.',
+);
+export const FETCH_TAGS_LIST_ERROR_MESSAGE = s__(
+ 'ContainerRegistry|Something went wrong while fetching the tags list.',
+);
+export const DELETE_IMAGE_ERROR_MESSAGE = s__(
+ 'ContainerRegistry|Something went wrong while scheduling %{title} for deletion. Please try again.',
+);
+export const ASYNC_DELETE_IMAGE_ERROR_MESSAGE = s__(
+ `ContainerRegistry|There was an error during the deletion of this image repository, please try again.`,
+);
+export const DELETE_IMAGE_SUCCESS_MESSAGE = s__(
+ 'ContainerRegistry|%{title} was successfully scheduled for deletion',
+);
+export const IMAGE_REPOSITORY_LIST_LABEL = s__('ContainerRegistry|Image Repositories');
+export const SEARCH_PLACEHOLDER_TEXT = s__('ContainerRegistry|Filter by name');
+export const EMPTY_RESULT_TITLE = s__('ContainerRegistry|Sorry, your filter produced no results.');
+export const EMPTY_RESULT_MESSAGE = s__(
+ 'ContainerRegistry|To widen your search, change or remove the filters above.',
+);
+
+// Parameters
+
+export const IMAGE_DELETE_SCHEDULED_STATUS = 'delete_scheduled';
+export const IMAGE_FAILED_DELETED_STATUS = 'delete_failed';
diff --git a/app/assets/javascripts/registry/explorer/constants/quick_start.js b/app/assets/javascripts/registry/explorer/constants/quick_start.js
new file mode 100644
index 00000000000..6a39c07eba2
--- /dev/null
+++ b/app/assets/javascripts/registry/explorer/constants/quick_start.js
@@ -0,0 +1,9 @@
+import { s__ } from '~/locale';
+
+export const QUICK_START = s__('ContainerRegistry|CLI Commands');
+export const LOGIN_COMMAND_LABEL = s__('ContainerRegistry|Login');
+export const COPY_LOGIN_TITLE = s__('ContainerRegistry|Copy login command');
+export const BUILD_COMMAND_LABEL = s__('ContainerRegistry|Build an image');
+export const COPY_BUILD_TITLE = s__('ContainerRegistry|Copy build command');
+export const PUSH_COMMAND_LABEL = s__('ContainerRegistry|Push an image');
+export const COPY_PUSH_TITLE = s__('ContainerRegistry|Copy push command');
diff --git a/app/assets/javascripts/registry/explorer/pages/details.vue b/app/assets/javascripts/registry/explorer/pages/details.vue
index cc2dc531dc8..598e643ce1a 100644
--- a/app/assets/javascripts/registry/explorer/pages/details.vue
+++ b/app/assets/javascripts/registry/explorer/pages/details.vue
@@ -1,139 +1,56 @@
<script>
-import { mapState, mapActions, mapGetters } from 'vuex';
-import {
- GlTable,
- GlFormCheckbox,
- GlDeprecatedButton,
- GlIcon,
- GlTooltipDirective,
- GlPagination,
- GlModal,
- GlSprintf,
- GlAlert,
- GlLink,
- GlEmptyState,
- GlResizeObserverDirective,
- GlSkeletonLoader,
-} from '@gitlab/ui';
+import { mapState, mapActions } from 'vuex';
+import { GlPagination, GlResizeObserverDirective } from '@gitlab/ui';
import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
-import { n__ } from '~/locale';
-import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
-import { numberToHumanSize } from '~/lib/utils/number_utils';
-import timeagoMixin from '~/vue_shared/mixins/timeago';
import Tracking from '~/tracking';
+import DeleteAlert from '../components/details_page/delete_alert.vue';
+import DeleteModal from '../components/details_page/delete_modal.vue';
+import DetailsHeader from '../components/details_page/details_header.vue';
+import TagsTable from '../components/details_page/tags_table.vue';
+import TagsLoader from '../components/details_page/tags_loader.vue';
+import EmptyTagsState from '../components/details_page/empty_tags_state.vue';
+
import { decodeAndParse } from '../utils';
import {
- LIST_KEY_TAG,
- LIST_KEY_IMAGE_ID,
- LIST_KEY_SIZE,
- LIST_KEY_LAST_UPDATED,
- LIST_KEY_ACTIONS,
- LIST_KEY_CHECKBOX,
- LIST_LABEL_TAG,
- LIST_LABEL_IMAGE_ID,
- LIST_LABEL_SIZE,
- LIST_LABEL_LAST_UPDATED,
- DELETE_TAG_SUCCESS_MESSAGE,
- DELETE_TAG_ERROR_MESSAGE,
- DELETE_TAGS_SUCCESS_MESSAGE,
- DELETE_TAGS_ERROR_MESSAGE,
- REMOVE_TAG_CONFIRMATION_TEXT,
- REMOVE_TAGS_CONFIRMATION_TEXT,
- DETAILS_PAGE_TITLE,
- REMOVE_TAGS_BUTTON_TITLE,
- REMOVE_TAG_BUTTON_TITLE,
- EMPTY_IMAGE_REPOSITORY_TITLE,
- EMPTY_IMAGE_REPOSITORY_MESSAGE,
- ADMIN_GARBAGE_COLLECTION_TIP,
-} from '../constants';
+ ALERT_SUCCESS_TAG,
+ ALERT_DANGER_TAG,
+ ALERT_SUCCESS_TAGS,
+ ALERT_DANGER_TAGS,
+} from '../constants/index';
export default {
components: {
- GlTable,
- GlFormCheckbox,
- GlDeprecatedButton,
- GlIcon,
- ClipboardButton,
+ DeleteAlert,
+ DetailsHeader,
GlPagination,
- GlModal,
- GlSkeletonLoader,
- GlSprintf,
- GlEmptyState,
- GlAlert,
- GlLink,
+ DeleteModal,
+ TagsTable,
+ TagsLoader,
+ EmptyTagsState,
},
directives: {
- GlTooltip: GlTooltipDirective,
GlResizeObserver: GlResizeObserverDirective,
},
- mixins: [timeagoMixin, Tracking.mixin()],
- loader: {
- repeat: 10,
- width: 1000,
- height: 40,
- },
- i18n: {
- DETAILS_PAGE_TITLE,
- REMOVE_TAGS_BUTTON_TITLE,
- REMOVE_TAG_BUTTON_TITLE,
- EMPTY_IMAGE_REPOSITORY_TITLE,
- EMPTY_IMAGE_REPOSITORY_MESSAGE,
- },
- alertMessages: {
- success_tag: DELETE_TAG_SUCCESS_MESSAGE,
- danger_tag: DELETE_TAG_ERROR_MESSAGE,
- success_tags: DELETE_TAGS_SUCCESS_MESSAGE,
- danger_tags: DELETE_TAGS_ERROR_MESSAGE,
- },
+ mixins: [Tracking.mixin()],
data() {
return {
- selectedItems: [],
itemsToBeDeleted: [],
- selectAllChecked: false,
- modalDescription: null,
isDesktop: true,
- deleteAlertType: false,
+ deleteAlertType: null,
};
},
computed: {
- ...mapGetters(['tags']),
- ...mapState(['tagsPagination', 'isLoading', 'config']),
+ ...mapState(['tagsPagination', 'isLoading', 'config', 'tags']),
imageName() {
const { name } = decodeAndParse(this.$route.params.id);
return name;
},
- fields() {
- const tagClass = this.isDesktop ? 'w-25' : '';
- const tagInnerClass = this.isDesktop ? 'mw-m' : 'gl-justify-content-end';
- return [
- { key: LIST_KEY_CHECKBOX, label: '', class: 'gl-w-16' },
- {
- key: LIST_KEY_TAG,
- label: LIST_LABEL_TAG,
- class: `${tagClass} js-tag-column`,
- innerClass: tagInnerClass,
- },
- { key: LIST_KEY_IMAGE_ID, label: LIST_LABEL_IMAGE_ID },
- { key: LIST_KEY_SIZE, label: LIST_LABEL_SIZE },
- { key: LIST_KEY_LAST_UPDATED, label: LIST_LABEL_LAST_UPDATED },
- { key: LIST_KEY_ACTIONS, label: '' },
- ].filter(f => f.key !== LIST_KEY_CHECKBOX || this.isDesktop);
- },
- isMultiDelete() {
- return this.itemsToBeDeleted.length > 1;
- },
tracking() {
return {
- label: this.isMultiDelete ? 'bulk_registry_tag_delete' : 'registry_tag_delete',
+ label:
+ this.itemsToBeDeleted?.length > 1 ? 'bulk_registry_tag_delete' : 'registry_tag_delete',
};
},
- modalAction() {
- return n__(
- 'ContainerRegistry|Remove tag',
- 'ContainerRegistry|Remove tags',
- this.isMultiDelete ? this.itemsToBeDeleted.length : 1,
- );
- },
currentPage: {
get() {
return this.tagsPagination.page;
@@ -142,132 +59,51 @@ export default {
this.requestTagsList({ pagination: { page }, params: this.$route.params.id });
},
},
- deleteAlertConfig() {
- const config = {
- title: '',
- message: '',
- type: 'success',
- };
- if (this.deleteAlertType) {
- [config.type] = this.deleteAlertType.split('_');
-
- const defaultMessage = this.$options.alertMessages[this.deleteAlertType];
-
- if (this.config.isAdmin && config.type === 'success') {
- config.title = defaultMessage;
- config.message = ADMIN_GARBAGE_COLLECTION_TIP;
- } else {
- config.message = defaultMessage;
- }
- }
- return config;
- },
},
mounted() {
this.requestTagsList({ params: this.$route.params.id });
},
methods: {
...mapActions(['requestTagsList', 'requestDeleteTag', 'requestDeleteTags']),
- setModalDescription(itemIndex = -1) {
- if (itemIndex === -1) {
- this.modalDescription = {
- message: REMOVE_TAGS_CONFIRMATION_TEXT,
- item: this.itemsToBeDeleted.length,
- };
- } else {
- const { path } = this.tags[itemIndex];
-
- this.modalDescription = {
- message: REMOVE_TAG_CONFIRMATION_TEXT,
- item: path,
- };
- }
- },
- formatSize(size) {
- return numberToHumanSize(size);
- },
- layers(layers) {
- return layers ? n__('%d layer', '%d layers', layers) : '';
- },
- onSelectAllChange() {
- if (this.selectAllChecked) {
- this.deselectAll();
- } else {
- this.selectAll();
- }
- },
- selectAll() {
- this.selectedItems = this.tags.map((x, index) => index);
- this.selectAllChecked = true;
- },
- deselectAll() {
- this.selectedItems = [];
- this.selectAllChecked = false;
- },
- updateSelectedItems(index) {
- const delIndex = this.selectedItems.findIndex(x => x === index);
-
- if (delIndex > -1) {
- this.selectedItems.splice(delIndex, 1);
- this.selectAllChecked = false;
- } else {
- this.selectedItems.push(index);
-
- if (this.selectedItems.length === this.tags.length) {
- this.selectAllChecked = true;
- }
- }
- },
- deleteSingleItem(index) {
- this.setModalDescription(index);
- this.itemsToBeDeleted = [index];
+ deleteTags(toBeDeletedList) {
+ this.itemsToBeDeleted = toBeDeletedList.map(name => ({
+ ...this.tags.find(t => t.name === name),
+ }));
this.track('click_button');
this.$refs.deleteModal.show();
},
- deleteMultipleItems() {
- this.itemsToBeDeleted = [...this.selectedItems];
- if (this.selectedItems.length === 1) {
- this.setModalDescription(this.itemsToBeDeleted[0]);
- } else if (this.selectedItems.length > 1) {
- this.setModalDescription();
- }
- this.track('click_button');
- this.$refs.deleteModal.show();
- },
- handleSingleDelete(index) {
- const itemToDelete = this.tags[index];
+ handleSingleDelete() {
+ const [itemToDelete] = this.itemsToBeDeleted;
this.itemsToBeDeleted = [];
- this.selectedItems = this.selectedItems.filter(i => i !== index);
return this.requestDeleteTag({ tag: itemToDelete, params: this.$route.params.id })
.then(() => {
- this.deleteAlertType = 'success_tag';
+ this.deleteAlertType = ALERT_SUCCESS_TAG;
})
.catch(() => {
- this.deleteAlertType = 'danger_tag';
+ this.deleteAlertType = ALERT_DANGER_TAG;
});
},
handleMultipleDelete() {
const { itemsToBeDeleted } = this;
this.itemsToBeDeleted = [];
- this.selectedItems = [];
return this.requestDeleteTags({
- ids: itemsToBeDeleted.map(x => this.tags[x].name),
+ ids: itemsToBeDeleted.map(x => x.name),
params: this.$route.params.id,
})
.then(() => {
- this.deleteAlertType = 'success_tags';
+ this.deleteAlertType = ALERT_SUCCESS_TAGS;
})
.catch(() => {
- this.deleteAlertType = 'danger_tags';
+ this.deleteAlertType = ALERT_DANGER_TAGS;
});
},
onDeletionConfirmed() {
this.track('confirm_delete');
- if (this.isMultiDelete) {
+ if (this.itemsToBeDeleted.length > 1) {
this.handleMultipleDelete();
} else {
- this.handleSingleDelete(this.itemsToBeDeleted[0]);
+ this.handleSingleDelete();
}
},
handleResize() {
@@ -279,141 +115,23 @@ export default {
<template>
<div v-gl-resize-observer="handleResize" class="my-3 w-100 slide-enter-to-element">
- <gl-alert
- v-if="deleteAlertType"
- :variant="deleteAlertConfig.type"
- :title="deleteAlertConfig.title"
+ <delete-alert
+ v-model="deleteAlertType"
+ :garbage-collection-help-page-path="config.garbageCollectionHelpPagePath"
+ :is-admin="config.isAdmin"
class="my-2"
- @dismiss="deleteAlertType = null"
- >
- <gl-sprintf :message="deleteAlertConfig.message">
- <template #docLink="{content}">
- <gl-link :href="config.garbageCollectionHelpPagePath" target="_blank">
- {{ content }}
- </gl-link>
- </template>
- </gl-sprintf>
- </gl-alert>
- <div class="d-flex my-3 align-items-center">
- <h4>
- <gl-sprintf :message="$options.i18n.DETAILS_PAGE_TITLE">
- <template #imageName>
- {{ imageName }}
- </template>
- </gl-sprintf>
- </h4>
- </div>
-
- <gl-table :items="tags" :fields="fields" :stacked="!isDesktop" show-empty>
- <template v-if="isDesktop" #head(checkbox)>
- <gl-form-checkbox
- ref="mainCheckbox"
- :checked="selectAllChecked"
- @change="onSelectAllChange"
- />
- </template>
- <template #head(actions)>
- <gl-deprecated-button
- ref="bulkDeleteButton"
- v-gl-tooltip
- :disabled="!selectedItems || selectedItems.length === 0"
- class="float-right"
- variant="danger"
- :title="$options.i18n.REMOVE_TAGS_BUTTON_TITLE"
- :aria-label="$options.i18n.REMOVE_TAGS_BUTTON_TITLE"
- @click="deleteMultipleItems()"
- >
- <gl-icon name="remove" />
- </gl-deprecated-button>
- </template>
+ />
- <template #cell(checkbox)="{index}">
- <gl-form-checkbox
- ref="rowCheckbox"
- class="js-row-checkbox"
- :checked="selectedItems.includes(index)"
- @change="updateSelectedItems(index)"
- />
- </template>
- <template #cell(name)="{item, field}">
- <div ref="rowName" :class="[field.innerClass, 'gl-display-flex']">
- <span
- v-gl-tooltip
- data-testid="rowNameText"
- :title="item.name"
- class="gl-text-overflow-ellipsis gl-overflow-hidden gl-white-space-nowrap"
- >
- {{ item.name }}
- </span>
- <clipboard-button
- v-if="item.location"
- ref="rowClipboardButton"
- :title="item.location"
- :text="item.location"
- css-class="btn-default btn-transparent btn-clipboard"
- />
- </div>
- </template>
- <template #cell(short_revision)="{value}">
- <span ref="rowShortRevision">
- {{ value }}
- </span>
- </template>
- <template #cell(total_size)="{item}">
- <span ref="rowSize">
- {{ formatSize(item.total_size) }}
- <template v-if="item.total_size && item.layers">
- &middot;
- </template>
- {{ layers(item.layers) }}
- </span>
- </template>
- <template #cell(created_at)="{value}">
- <span ref="rowTime" v-gl-tooltip :title="tooltipTitle(value)">
- {{ timeFormatted(value) }}
- </span>
- </template>
- <template #cell(actions)="{index, item}">
- <gl-deprecated-button
- ref="singleDeleteButton"
- :title="$options.i18n.REMOVE_TAG_BUTTON_TITLE"
- :aria-label="$options.i18n.REMOVE_TAG_BUTTON_TITLE"
- :disabled="!item.destroy_path"
- variant="danger"
- class="js-delete-registry float-right btn-inverted btn-border-color btn-icon"
- @click="deleteSingleItem(index)"
- >
- <gl-icon name="remove" />
- </gl-deprecated-button>
- </template>
+ <details-header :image-name="imageName" />
+ <tags-table :tags="tags" :is-loading="isLoading" :is-desktop="isDesktop" @delete="deleteTags">
<template #empty>
- <template v-if="isLoading">
- <gl-skeleton-loader
- v-for="index in $options.loader.repeat"
- :key="index"
- :width="$options.loader.width"
- :height="$options.loader.height"
- preserve-aspect-ratio="xMinYMax meet"
- >
- <rect width="15" x="0" y="12.5" height="15" rx="4" />
- <rect width="250" x="25" y="10" height="20" rx="4" />
- <circle cx="290" cy="20" r="10" />
- <rect width="100" x="315" y="10" height="20" rx="4" />
- <rect width="100" x="500" y="10" height="20" rx="4" />
- <rect width="100" x="630" y="10" height="20" rx="4" />
- <rect x="960" y="0" width="40" height="40" rx="4" />
- </gl-skeleton-loader>
- </template>
- <gl-empty-state
- v-else
- :title="$options.i18n.EMPTY_IMAGE_REPOSITORY_TITLE"
- :svg-path="config.noContainersImage"
- :description="$options.i18n.EMPTY_IMAGE_REPOSITORY_MESSAGE"
- class="mx-auto my-0"
- />
+ <empty-tags-state :no-containers-image="config.noContainersImage" />
</template>
- </gl-table>
+ <template #loader>
+ <tags-loader v-once />
+ </template>
+ </tags-table>
<gl-pagination
v-if="!isLoading"
@@ -425,22 +143,11 @@ export default {
class="w-100"
/>
- <gl-modal
+ <delete-modal
ref="deleteModal"
- modal-id="delete-tag-modal"
- ok-variant="danger"
- @ok="onDeletionConfirmed"
+ :items-to-be-deleted="itemsToBeDeleted"
+ @confirmDelete="onDeletionConfirmed"
@cancel="track('cancel_delete')"
- >
- <template #modal-title>{{ modalAction }}</template>
- <template #modal-ok>{{ modalAction }}</template>
- <p v-if="modalDescription">
- <gl-sprintf :message="modalDescription.message">
- <template #item>
- <b>{{ modalDescription.item }}</b>
- </template>
- </gl-sprintf>
- </p>
- </gl-modal>
+ />
</div>
</template>
diff --git a/app/assets/javascripts/registry/explorer/pages/list.vue b/app/assets/javascripts/registry/explorer/pages/list.vue
index 4efa6f08d84..e8a26dc58f2 100644
--- a/app/assets/javascripts/registry/explorer/pages/list.vue
+++ b/app/assets/javascripts/registry/explorer/pages/list.vue
@@ -12,26 +12,24 @@ import {
} from '@gitlab/ui';
import Tracking from '~/tracking';
-import ProjectEmptyState from '../components/project_empty_state.vue';
-import GroupEmptyState from '../components/group_empty_state.vue';
-import ProjectPolicyAlert from '../components/project_policy_alert.vue';
-import QuickstartDropdown from '../components/quickstart_dropdown.vue';
-import ImageList from '../components/image_list.vue';
+import ProjectEmptyState from '../components/list_page/project_empty_state.vue';
+import GroupEmptyState from '../components/list_page/group_empty_state.vue';
+import RegistryHeader from '../components/list_page/registry_header.vue';
+import ImageList from '../components/list_page/image_list.vue';
+import CliCommands from '../components/list_page/cli_commands.vue';
import {
DELETE_IMAGE_SUCCESS_MESSAGE,
DELETE_IMAGE_ERROR_MESSAGE,
- CONTAINER_REGISTRY_TITLE,
CONNECTION_ERROR_TITLE,
CONNECTION_ERROR_MESSAGE,
- LIST_INTRO_TEXT,
REMOVE_REPOSITORY_MODAL_TEXT,
REMOVE_REPOSITORY_LABEL,
SEARCH_PLACEHOLDER_TEXT,
IMAGE_REPOSITORY_LIST_LABEL,
EMPTY_RESULT_TITLE,
EMPTY_RESULT_MESSAGE,
-} from '../constants';
+} from '../constants/index';
export default {
name: 'RegistryListApp',
@@ -39,8 +37,6 @@ export default {
GlEmptyState,
ProjectEmptyState,
GroupEmptyState,
- ProjectPolicyAlert,
- QuickstartDropdown,
ImageList,
GlModal,
GlSprintf,
@@ -48,6 +44,8 @@ export default {
GlAlert,
GlSkeletonLoader,
GlSearchBoxByClick,
+ RegistryHeader,
+ CliCommands,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -59,10 +57,8 @@ export default {
height: 40,
},
i18n: {
- CONTAINER_REGISTRY_TITLE,
CONNECTION_ERROR_TITLE,
CONNECTION_ERROR_MESSAGE,
- LIST_INTRO_TEXT,
REMOVE_REPOSITORY_MODAL_TEXT,
REMOVE_REPOSITORY_LABEL,
SEARCH_PLACEHOLDER_TEXT,
@@ -85,7 +81,7 @@ export default {
label: 'registry_repository_delete',
};
},
- showQuickStartDropdown() {
+ showCommands() {
return Boolean(!this.isLoading && !this.config?.isGroupPage && this.images?.length);
},
showDeleteAlert() {
@@ -149,8 +145,6 @@ export default {
</gl-sprintf>
</gl-alert>
- <project-policy-alert v-if="!config.isGroupPage" class="mt-2" />
-
<gl-empty-state
v-if="config.characterError"
:title="$options.i18n.CONNECTION_ERROR_TITLE"
@@ -170,21 +164,17 @@ export default {
</gl-empty-state>
<template v-else>
- <div>
- <div class="d-flex justify-content-between align-items-center">
- <h4>{{ $options.i18n.CONTAINER_REGISTRY_TITLE }}</h4>
- <quickstart-dropdown v-if="showQuickStartDropdown" class="d-none d-sm-block" />
- </div>
- <p>
- <gl-sprintf :message="$options.i18n.LIST_INTRO_TEXT">
- <template #docLink="{content}">
- <gl-link :href="config.helpPagePath" target="_blank">
- {{ content }}
- </gl-link>
- </template>
- </gl-sprintf>
- </p>
- </div>
+ <registry-header
+ :images-count="pagination.total"
+ :expiration-policy="config.expirationPolicy"
+ :help-page-path="config.helpPagePath"
+ :expiration-policy-help-page-path="config.expirationPolicyHelpPagePath"
+ :hide-expiration-policy-data="config.isGroupPage"
+ >
+ <template #commands>
+ <cli-commands v-if="showCommands" />
+ </template>
+ </registry-header>
<div v-if="isLoading" class="mt-2">
<gl-skeleton-loader
@@ -201,7 +191,7 @@ export default {
</div>
<template v-else>
<template v-if="!isEmpty">
- <div class="gl-display-flex gl-p-1" data-testid="listHeader">
+ <div class="gl-display-flex gl-p-1 gl-mt-3" data-testid="listHeader">
<div class="gl-flex-fill-1">
<h5>{{ $options.i18n.IMAGE_REPOSITORY_LIST_LABEL }}</h5>
</div>
diff --git a/app/assets/javascripts/registry/explorer/router.js b/app/assets/javascripts/registry/explorer/router.js
index 478eaca1a68..f570987023b 100644
--- a/app/assets/javascripts/registry/explorer/router.js
+++ b/app/assets/javascripts/registry/explorer/router.js
@@ -1,9 +1,9 @@
import Vue from 'vue';
import VueRouter from 'vue-router';
-import { s__ } from '~/locale';
import List from './pages/list.vue';
import Details from './pages/details.vue';
import { decodeAndParse } from './utils';
+import { CONTAINER_REGISTRY_TITLE } from './constants/index';
Vue.use(VueRouter);
@@ -17,7 +17,7 @@ export default function createRouter(base) {
path: '/',
component: List,
meta: {
- nameGenerator: () => s__('ContainerRegistry|Container Registry'),
+ nameGenerator: () => CONTAINER_REGISTRY_TITLE,
root: true,
},
},
diff --git a/app/assets/javascripts/registry/explorer/stores/actions.js b/app/assets/javascripts/registry/explorer/stores/actions.js
index 7f80bc21d6e..3d73ffbd23f 100644
--- a/app/assets/javascripts/registry/explorer/stores/actions.js
+++ b/app/assets/javascripts/registry/explorer/stores/actions.js
@@ -6,7 +6,7 @@ import {
DEFAULT_PAGE,
DEFAULT_PAGE_SIZE,
FETCH_TAGS_LIST_ERROR_MESSAGE,
-} from '../constants';
+} from '../constants/index';
import { decodeAndParse } from '../utils';
export const setInitialState = ({ commit }, data) => commit(types.SET_INITIAL_STATE, data);
diff --git a/app/assets/javascripts/registry/explorer/stores/getters.js b/app/assets/javascripts/registry/explorer/stores/getters.js
index a371d0e6356..7b5d1bd6da3 100644
--- a/app/assets/javascripts/registry/explorer/stores/getters.js
+++ b/app/assets/javascripts/registry/explorer/stores/getters.js
@@ -1,9 +1,3 @@
-export const tags = state => {
- // to show the loader inside the table we need to pass an empty array to gl-table whenever the table is loading
- // this is to take in account isLoading = true and state.tags =[1,2,3] during pagination and delete
- return state.isLoading ? [] : state.tags;
-};
-
export const dockerBuildCommand = state => {
/* eslint-disable @gitlab/require-i18n-strings */
return `docker build -t ${state.config.repositoryUrl} .`;
diff --git a/app/assets/javascripts/registry/explorer/stores/index.js b/app/assets/javascripts/registry/explorer/stores/index.js
index 153032e37d3..54a8e0e1c1c 100644
--- a/app/assets/javascripts/registry/explorer/stores/index.js
+++ b/app/assets/javascripts/registry/explorer/stores/index.js
@@ -7,6 +7,7 @@ import state from './state';
Vue.use(Vuex);
+// eslint-disable-next-line import/prefer-default-export
export const createStore = () =>
new Vuex.Store({
state,
@@ -14,6 +15,3 @@ export const createStore = () =>
actions,
mutations,
});
-
-// Deprecated and to be removed
-export default createStore();
diff --git a/app/assets/javascripts/registry/explorer/stores/mutations.js b/app/assets/javascripts/registry/explorer/stores/mutations.js
index b25a0221dc1..706f6489287 100644
--- a/app/assets/javascripts/registry/explorer/stores/mutations.js
+++ b/app/assets/javascripts/registry/explorer/stores/mutations.js
@@ -1,14 +1,14 @@
import * as types from './mutation_types';
-import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils';
-import { IMAGE_DELETE_SCHEDULED_STATUS, IMAGE_FAILED_DELETED_STATUS } from '../constants';
+import { parseIntPagination, normalizeHeaders, parseBoolean } from '~/lib/utils/common_utils';
+import { IMAGE_DELETE_SCHEDULED_STATUS, IMAGE_FAILED_DELETED_STATUS } from '../constants/index';
export default {
[types.SET_INITIAL_STATE](state, config) {
state.config = {
...config,
expirationPolicy: config.expirationPolicy ? JSON.parse(config.expirationPolicy) : undefined,
- isGroupPage: config.isGroupPage !== undefined,
- isAdmin: config.isAdmin !== undefined,
+ isGroupPage: parseBoolean(config.isGroupPage),
+ isAdmin: parseBoolean(config.isAdmin),
};
},
diff --git a/app/assets/javascripts/releases/components/asset_links_form.vue b/app/assets/javascripts/releases/components/asset_links_form.vue
index 0698ca5e31f..d0d1485d8e7 100644
--- a/app/assets/javascripts/releases/components/asset_links_form.vue
+++ b/app/assets/javascripts/releases/components/asset_links_form.vue
@@ -8,12 +8,25 @@ import {
GlIcon,
GlTooltipDirective,
GlFormInput,
+ GlFormSelect,
} from '@gitlab/ui';
+import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+import { DEFAULT_ASSET_LINK_TYPE, ASSET_LINK_TYPE } from '../constants';
+import { s__ } from '~/locale';
export default {
name: 'AssetLinksForm',
- components: { GlSprintf, GlLink, GlFormGroup, GlButton, GlIcon, GlFormInput },
+ components: {
+ GlSprintf,
+ GlLink,
+ GlFormGroup,
+ GlButton,
+ GlIcon,
+ GlFormInput,
+ GlFormSelect,
+ },
directives: { GlTooltip: GlTooltipDirective },
+ mixins: [glFeatureFlagsMixin()],
computed: {
...mapState('detail', ['release', 'releaseAssetsDocsPath']),
...mapGetters('detail', ['validationErrors']),
@@ -26,6 +39,7 @@ export default {
'addEmptyAssetLink',
'updateAssetLinkUrl',
'updateAssetLinkName',
+ 'updateAssetLinkType',
'removeAssetLink',
]),
onAddAnotherClicked() {
@@ -35,12 +49,6 @@ export default {
this.removeAssetLink(linkId);
this.ensureAtLeastOneLink();
},
- onUrlInput(linkIdToUpdate, newUrl) {
- this.updateAssetLinkUrl({ linkIdToUpdate, newUrl });
- },
- onLinkTitleInput(linkIdToUpdate, newName) {
- this.updateAssetLinkName({ linkIdToUpdate, newName });
- },
hasDuplicateUrl(link) {
return Boolean(this.getLinkErrors(link).isDuplicate);
},
@@ -73,6 +81,13 @@ export default {
}
},
},
+ typeOptions: [
+ { value: ASSET_LINK_TYPE.IMAGE, text: s__('ReleaseAssetLinkType|Image') },
+ { value: ASSET_LINK_TYPE.PACKAGE, text: s__('ReleaseAssetLinkType|Package') },
+ { value: ASSET_LINK_TYPE.RUNBOOK, text: s__('ReleaseAssetLinkType|Runbook') },
+ { value: ASSET_LINK_TYPE.OTHER, text: s__('ReleaseAssetLinkType|Other') },
+ ],
+ defaultTypeOptionValue: DEFAULT_ASSET_LINK_TYPE,
};
</script>
@@ -109,10 +124,10 @@ export default {
<div
v-for="(link, index) in release.assets.links"
:key="link.id"
- class="row flex-column flex-sm-row align-items-stretch align-items-sm-start"
+ class="row flex-column flex-sm-row align-items-stretch align-items-sm-start no-gutters"
>
<gl-form-group
- class="url-field form-group col"
+ class="url-field form-group col pr-sm-2"
:label="__('URL')"
:label-for="`asset-url-${index}`"
>
@@ -123,7 +138,7 @@ export default {
type="text"
class="form-control"
:state="isUrlValid(link)"
- @change="onUrlInput(link.id, $event)"
+ @change="updateAssetLinkUrl({ linkIdToUpdate: link.id, newUrl: $event })"
/>
<template #invalid-feedback>
<span v-if="hasEmptyUrl(link)" class="invalid-feedback d-inline">
@@ -149,7 +164,7 @@ export default {
</gl-form-group>
<gl-form-group
- class="link-title-field col"
+ class="link-title-field col px-sm-2"
:label="__('Link title')"
:label-for="`asset-link-name-${index}`"
>
@@ -160,7 +175,7 @@ export default {
type="text"
class="form-control"
:state="isNameValid(link)"
- @change="onLinkTitleInput(link.id, $event)"
+ @change="updateAssetLinkName({ linkIdToUpdate: link.id, newName: $event })"
/>
<template #invalid-feedback>
<span v-if="hasEmptyName(link)" class="invalid-feedback d-inline">
@@ -169,16 +184,34 @@ export default {
</template>
</gl-form-group>
- <div class="mb-5 mb-sm-3 mt-sm-4 col col-sm-auto">
+ <gl-form-group
+ v-if="glFeatures.releaseAssetLinkType"
+ class="link-type-field col-auto px-sm-2"
+ :label="__('Type')"
+ :label-for="`asset-type-${index}`"
+ >
+ <gl-form-select
+ :id="`asset-type-${index}`"
+ ref="typeSelect"
+ :value="link.linkType || $options.defaultTypeOptionValue"
+ class="form-control pr-4"
+ :options="$options.typeOptions"
+ @change="updateAssetLinkType({ linkIdToUpdate: link.id, newType: $event })"
+ />
+ </gl-form-group>
+
+ <div class="mb-5 mb-sm-3 mt-sm-4 col col-sm-auto pl-sm-2">
<gl-button
v-gl-tooltip
- class="remove-button w-100"
+ class="remove-button w-100 form-control"
:aria-label="__('Remove asset link')"
:title="__('Remove asset link')"
@click="onRemoveClicked(link.id)"
>
- <gl-icon class="mr-1 mr-sm-0 mb-1" :size="16" name="remove" />
- <span class="d-inline d-sm-none">{{ __('Remove asset link') }}</span>
+ <div class="d-flex">
+ <gl-icon class="mr-1 mr-sm-0" :size="16" name="remove" />
+ <span class="d-inline d-sm-none">{{ __('Remove asset link') }}</span>
+ </div>
</gl-button>
</div>
</div>
diff --git a/app/assets/javascripts/releases/components/evidence_block.vue b/app/assets/javascripts/releases/components/evidence_block.vue
index acae6fda533..2cc15777343 100644
--- a/app/assets/javascripts/releases/components/evidence_block.vue
+++ b/app/assets/javascripts/releases/components/evidence_block.vue
@@ -71,7 +71,7 @@ export default {
:download="evidenceTitle(index)"
:href="evidenceUrl(index)"
>
- <gl-icon name="review-list" class="align-middle append-right-8" />
+ <gl-icon name="review-list" class="align-middle gl-mr-3" />
<span>{{ evidenceTitle(index) }}</span>
</gl-link>
@@ -96,7 +96,7 @@ export default {
<gl-icon
v-gl-tooltip
name="clock"
- class="align-middle append-right-8"
+ class="align-middle gl-mr-3"
:title="collectedAt(index)"
/>
<span>{{ timeSummary(index) }}</span>
diff --git a/app/assets/javascripts/releases/components/release_block.vue b/app/assets/javascripts/releases/components/release_block.vue
index 58045b57d80..adb0e69b786 100644
--- a/app/assets/javascripts/releases/components/release_block.vue
+++ b/app/assets/javascripts/releases/components/release_block.vue
@@ -109,7 +109,7 @@ export default {
<evidence-block v-if="hasEvidence && shouldShowEvidence" :release="release" />
<div ref="gfm-content" class="card-text prepend-top-default">
- <div v-html="release.descriptionHtml"></div>
+ <div class="md" v-html="release.descriptionHtml"></div>
</div>
</div>
diff --git a/app/assets/javascripts/releases/components/release_block_assets.vue b/app/assets/javascripts/releases/components/release_block_assets.vue
index f4b92416e47..e07646e9a9f 100644
--- a/app/assets/javascripts/releases/components/release_block_assets.vue
+++ b/app/assets/javascripts/releases/components/release_block_assets.vue
@@ -1,65 +1,190 @@
<script>
-import { GlTooltipDirective, GlLink } from '@gitlab/ui';
+import { GlTooltipDirective, GlLink, GlButton, GlCollapse, GlIcon, GlBadge } from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue';
+import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+import { ASSET_LINK_TYPE } from '../constants';
+import { __, s__, sprintf } from '~/locale';
+import { difference } from 'lodash';
export default {
name: 'ReleaseBlockAssets',
components: {
GlLink,
+ GlButton,
+ GlCollapse,
+ GlIcon,
Icon,
+ GlBadge,
},
directives: {
GlTooltip: GlTooltipDirective,
},
+ mixins: [glFeatureFlagsMixin()],
props: {
assets: {
type: Object,
required: true,
},
},
+ data() {
+ return {
+ isAssetsExpanded: true,
+ };
+ },
computed: {
hasAssets() {
return Boolean(this.assets.count);
},
+ imageLinks() {
+ return this.linksForType(ASSET_LINK_TYPE.IMAGE);
+ },
+ packageLinks() {
+ return this.linksForType(ASSET_LINK_TYPE.PACKAGE);
+ },
+ runbookLinks() {
+ return this.linksForType(ASSET_LINK_TYPE.RUNBOOK);
+ },
+ otherLinks() {
+ return difference(this.assets.links, [
+ ...this.imageLinks,
+ ...this.packageLinks,
+ ...this.runbookLinks,
+ ]);
+ },
+ sections() {
+ return [
+ {
+ links: this.assets.sources.map(s => ({
+ url: s.url,
+ name: sprintf(__('Source code (%{fileExtension})'), { fileExtension: s.format }),
+ })),
+ iconName: 'doc-code',
+ },
+ {
+ title: s__('ReleaseAssetLinkType|Images'),
+ links: this.imageLinks,
+ iconName: 'container-image',
+ },
+ {
+ title: s__('ReleaseAssetLinkType|Packages'),
+ links: this.packageLinks,
+ iconName: 'package',
+ },
+ {
+ title: s__('ReleaseAssetLinkType|Runbooks'),
+ links: this.runbookLinks,
+ iconName: 'book',
+ },
+ {
+ title: s__('ReleaseAssetLinkType|Other'),
+ links: this.otherLinks,
+ iconName: 'link',
+ },
+ ].filter(section => section.links.length > 0);
+ },
+ },
+ methods: {
+ toggleAssetsExpansion() {
+ this.isAssetsExpanded = !this.isAssetsExpanded;
+ },
+ linksForType(type) {
+ return this.assets.links.filter(l => l.linkType === type);
+ },
},
+ externalLinkTooltipText: __('This link points to external content'),
};
</script>
<template>
<div class="card-text prepend-top-default">
- <b>
- {{ __('Assets') }}
- <span class="js-assets-count badge badge-pill">{{ assets.count }}</span>
- </b>
-
- <ul v-if="assets.links.length" class="pl-0 mb-0 prepend-top-8 list-unstyled js-assets-list">
- <li v-for="link in assets.links" :key="link.name" class="append-bottom-8">
- <gl-link v-gl-tooltip.bottom :title="__('Download asset')" :href="link.directAssetUrl">
- <icon name="package" class="align-middle append-right-4 align-text-bottom" />
- {{ link.name }}
- <span v-if="link.external">{{ __('(external source)') }}</span>
- </gl-link>
- </li>
- </ul>
-
- <div v-if="hasAssets" class="dropdown">
- <button
- type="button"
- class="btn btn-link"
- data-toggle="dropdown"
- aria-haspopup="true"
- aria-expanded="false"
+ <template v-if="glFeatures.releaseAssetLinkType">
+ <gl-button
+ data-testid="accordion-button"
+ variant="link"
+ class="gl-font-weight-bold"
+ @click="toggleAssetsExpansion"
>
- <icon name="doc-code" class="align-top append-right-4" />
- {{ __('Source code') }}
- <icon name="chevron-down" />
- </button>
+ <gl-icon
+ name="chevron-right"
+ class="gl-transition-medium"
+ :class="{ 'gl-rotate-90': isAssetsExpanded }"
+ />
+ {{ __('Assets') }}
+ <gl-badge size="sm" variant="neutral" class="gl-display-inline-block">{{
+ assets.count
+ }}</gl-badge>
+ </gl-button>
+ <gl-collapse v-model="isAssetsExpanded">
+ <div class="gl-pl-6 gl-pt-3 js-assets-list">
+ <template v-for="(section, index) in sections">
+ <h5 v-if="section.title" :key="`section-header-${index}`" class="gl-mb-2">
+ {{ section.title }}
+ </h5>
+ <ul :key="`section-body-${index}`" class="list-unstyled gl-m-0">
+ <li v-for="link in section.links" :key="link.url">
+ <gl-link
+ :href="link.directAssetUrl || link.url"
+ class="gl-display-flex gl-align-items-center gl-line-height-24"
+ >
+ <gl-icon
+ :name="section.iconName"
+ class="gl-mr-2 gl-flex-shrink-0 gl-flex-grow-0"
+ />
+ {{ link.name }}
+ <gl-icon
+ v-if="link.external"
+ v-gl-tooltip
+ name="external-link"
+ :aria-label="$options.externalLinkTooltipText"
+ :title="$options.externalLinkTooltipText"
+ data-testid="external-link-indicator"
+ class="gl-ml-2 gl-flex-shrink-0 gl-flex-grow-0 gl-text-gray-600"
+ />
+ </gl-link>
+ </li>
+ </ul>
+ </template>
+ </div>
+ </gl-collapse>
+ </template>
- <div class="js-sources-dropdown dropdown-menu">
- <li v-for="asset in assets.sources" :key="asset.url">
- <gl-link :href="asset.url">{{ __('Download') }} {{ asset.format }}</gl-link>
+ <template v-else>
+ <b>
+ {{ __('Assets') }}
+ <span class="js-assets-count badge badge-pill">{{ assets.count }}</span>
+ </b>
+
+ <ul v-if="assets.links.length" class="pl-0 mb-0 gl-mt-3 list-unstyled js-assets-list">
+ <li v-for="link in assets.links" :key="link.name" class="gl-mb-3">
+ <gl-link v-gl-tooltip.bottom :title="__('Download asset')" :href="link.directAssetUrl">
+ <icon name="package" class="align-middle append-right-4 align-text-bottom" />
+ {{ link.name }}
+ <span v-if="link.external" data-testid="external-link-indicator">{{
+ __('(external source)')
+ }}</span>
+ </gl-link>
</li>
+ </ul>
+
+ <div v-if="hasAssets" class="dropdown">
+ <button
+ type="button"
+ class="btn btn-link"
+ data-toggle="dropdown"
+ aria-haspopup="true"
+ aria-expanded="false"
+ >
+ <icon name="doc-code" class="align-top append-right-4" />
+ {{ __('Source code') }}
+ <icon name="chevron-down" />
+ </button>
+
+ <div class="js-sources-dropdown dropdown-menu">
+ <li v-for="asset in assets.sources" :key="asset.url">
+ <gl-link :href="asset.url">{{ __('Download') }} {{ asset.format }}</gl-link>
+ </li>
+ </div>
</div>
- </div>
+ </template>
</div>
</template>
diff --git a/app/assets/javascripts/releases/components/release_block_author.vue b/app/assets/javascripts/releases/components/release_block_author.vue
index 0432d45b2dc..94f2b1795f0 100644
--- a/app/assets/javascripts/releases/components/release_block_author.vue
+++ b/app/assets/javascripts/releases/components/release_block_author.vue
@@ -30,7 +30,7 @@ export default {
<gl-sprintf :message="__('by %{user}')">
<template #user>
<user-avatar-link
- class="prepend-left-4"
+ class="gl-ml-2"
:link-href="author.webUrl"
:img-src="author.avatarUrl"
:img-alt="userImageAltDescription"
diff --git a/app/assets/javascripts/releases/components/release_block_metadata.vue b/app/assets/javascripts/releases/components/release_block_metadata.vue
index 40133941011..a3377ce044a 100644
--- a/app/assets/javascripts/releases/components/release_block_metadata.vue
+++ b/app/assets/javascripts/releases/components/release_block_metadata.vue
@@ -57,7 +57,7 @@ export default {
<template>
<div class="card-subtitle d-flex flex-wrap text-secondary">
- <div class="append-right-8">
+ <div class="gl-mr-3">
<icon name="commit" class="align-middle" />
<gl-link v-if="commitUrl" v-gl-tooltip.bottom :title="commit.title" :href="commitUrl">
{{ commit.shortId }}
@@ -65,7 +65,7 @@ export default {
<span v-else v-gl-tooltip.bottom :title="commit.title">{{ commit.shortId }}</span>
</div>
- <div class="append-right-8">
+ <div class="gl-mr-3">
<icon name="tag" class="align-middle" />
<gl-link v-if="tagUrl" v-gl-tooltip.bottom :title="__('Tag')" :href="tagUrl">
{{ release.tagName }}
diff --git a/app/assets/javascripts/releases/components/release_block_milestone_info.vue b/app/assets/javascripts/releases/components/release_block_milestone_info.vue
index d9fbd2884b7..4f75e15a149 100644
--- a/app/assets/javascripts/releases/components/release_block_milestone_info.vue
+++ b/app/assets/javascripts/releases/components/release_block_milestone_info.vue
@@ -144,7 +144,7 @@ export default {
<div class="d-flex flex-column align-items-start flex-shrink-0 mr-4 mb-3 js-issues-container">
<span class="mb-1">
{{ __('Issues') }}
- <gl-badge pill variant="light" class="font-weight-bold">{{ totalIssuesCount }}</gl-badge>
+ <gl-badge variant="muted" size="sm">{{ totalIssuesCount }}</gl-badge>
</span>
<div class="d-flex">
<gl-link v-if="openIssuesPath" ref="openIssuesLink" :href="openIssuesPath">
diff --git a/app/assets/javascripts/releases/constants.js b/app/assets/javascripts/releases/constants.js
index 1db93323a87..361cee70747 100644
--- a/app/assets/javascripts/releases/constants.js
+++ b/app/assets/javascripts/releases/constants.js
@@ -1,3 +1,12 @@
export const MAX_MILESTONES_TO_DISPLAY = 5;
export const BACK_URL_PARAM = 'back_url';
+
+export const ASSET_LINK_TYPE = Object.freeze({
+ OTHER: 'other',
+ IMAGE: 'image',
+ PACKAGE: 'package',
+ RUNBOOK: 'runbook',
+});
+
+export const DEFAULT_ASSET_LINK_TYPE = ASSET_LINK_TYPE.OTHER;
diff --git a/app/assets/javascripts/releases/stores/modules/detail/actions.js b/app/assets/javascripts/releases/stores/modules/detail/actions.js
index 3bc427dfa16..2026eeba880 100644
--- a/app/assets/javascripts/releases/stores/modules/detail/actions.js
+++ b/app/assets/javascripts/releases/stores/modules/detail/actions.js
@@ -3,7 +3,10 @@ import api from '~/api';
import createFlash from '~/flash';
import { s__ } from '~/locale';
import { redirectTo } from '~/lib/utils/url_utility';
-import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
+import {
+ convertObjectPropsToCamelCase,
+ convertObjectPropsToSnakeCase,
+} from '~/lib/utils/common_utils';
export const requestRelease = ({ commit }) => commit(types.REQUEST_RELEASE);
export const receiveReleaseSuccess = ({ commit }, data) =>
@@ -54,13 +57,18 @@ export const updateRelease = ({ dispatch, state, getters }) => {
const { release } = state;
const milestones = release.milestones ? release.milestones.map(milestone => milestone.title) : [];
+ const updatedRelease = convertObjectPropsToSnakeCase(
+ {
+ name: release.name,
+ description: release.description,
+ milestones,
+ },
+ { deep: true },
+ );
+
return (
api
- .updateRelease(state.projectId, state.tagName, {
- name: release.name,
- description: release.description,
- milestones,
- })
+ .updateRelease(state.projectId, state.tagName, updatedRelease)
/**
* Currently, we delete all existing links and then
@@ -91,7 +99,11 @@ export const updateRelease = ({ dispatch, state, getters }) => {
// Create a new link for each link in the form
return Promise.all(
getters.releaseLinksToCreate.map(l =>
- api.createReleaseLink(state.projectId, release.tagName, l),
+ api.createReleaseLink(
+ state.projectId,
+ release.tagName,
+ convertObjectPropsToSnakeCase(l, { deep: true }),
+ ),
),
);
})
@@ -118,6 +130,10 @@ export const updateAssetLinkName = ({ commit }, { linkIdToUpdate, newName }) =>
commit(types.UPDATE_ASSET_LINK_NAME, { linkIdToUpdate, newName });
};
+export const updateAssetLinkType = ({ commit }, { linkIdToUpdate, newType }) => {
+ commit(types.UPDATE_ASSET_LINK_TYPE, { linkIdToUpdate, newType });
+};
+
export const removeAssetLink = ({ commit }, linkIdToRemove) => {
commit(types.REMOVE_ASSET_LINK, linkIdToRemove);
};
diff --git a/app/assets/javascripts/releases/stores/modules/detail/mutation_types.js b/app/assets/javascripts/releases/stores/modules/detail/mutation_types.js
index 1d6356990ce..7b694120126 100644
--- a/app/assets/javascripts/releases/stores/modules/detail/mutation_types.js
+++ b/app/assets/javascripts/releases/stores/modules/detail/mutation_types.js
@@ -13,4 +13,5 @@ export const RECEIVE_UPDATE_RELEASE_ERROR = 'RECEIVE_UPDATE_RELEASE_ERROR';
export const ADD_EMPTY_ASSET_LINK = 'ADD_EMPTY_ASSET_LINK';
export const UPDATE_ASSET_LINK_URL = 'UPDATE_ASSET_LINK_URL';
export const UPDATE_ASSET_LINK_NAME = 'UPDATE_ASSET_LINK_NAME';
+export const UPDATE_ASSET_LINK_TYPE = 'UPDATE_ASSET_LINK_TYPE';
export const REMOVE_ASSET_LINK = 'REMOVE_ASSET_LINK';
diff --git a/app/assets/javascripts/releases/stores/modules/detail/mutations.js b/app/assets/javascripts/releases/stores/modules/detail/mutations.js
index 5c29b402cba..ca544151323 100644
--- a/app/assets/javascripts/releases/stores/modules/detail/mutations.js
+++ b/app/assets/javascripts/releases/stores/modules/detail/mutations.js
@@ -1,5 +1,6 @@
import * as types from './mutation_types';
import { uniqueId, cloneDeep } from 'lodash';
+import { DEFAULT_ASSET_LINK_TYPE } from '../../../constants';
const findReleaseLink = (release, id) => {
return release.assets.links.find(l => l.id === id);
@@ -49,6 +50,7 @@ export default {
id: uniqueId('new-link-'),
url: '',
name: '',
+ linkType: DEFAULT_ASSET_LINK_TYPE,
});
},
@@ -62,6 +64,11 @@ export default {
linkToUpdate.name = newName;
},
+ [types.UPDATE_ASSET_LINK_TYPE](state, { linkIdToUpdate, newType }) {
+ const linkToUpdate = findReleaseLink(state.release, linkIdToUpdate);
+ linkToUpdate.linkType = newType;
+ },
+
[types.REMOVE_ASSET_LINK](state, linkIdToRemove) {
state.release.assets.links = state.release.assets.links.filter(l => l.id !== linkIdToRemove);
},
diff --git a/app/assets/javascripts/reports/components/grouped_test_reports_app.vue b/app/assets/javascripts/reports/components/grouped_test_reports_app.vue
index 0f7a0e60dc0..a670cad5f9f 100644
--- a/app/assets/javascripts/reports/components/grouped_test_reports_app.vue
+++ b/app/assets/javascripts/reports/components/grouped_test_reports_app.vue
@@ -98,25 +98,27 @@ export default {
:has-issues="reports.length > 0"
class="mr-widget-section grouped-security-reports mr-report"
>
- <div slot="body" class="mr-widget-grouped-section report-block">
- <template v-for="(report, i) in reports">
- <summary-row
- :key="`summary-row-${i}`"
- :summary="reportText(report)"
- :status-icon="getReportIcon(report)"
- />
- <issues-list
- v-if="shouldRenderIssuesList(report)"
- :key="`issues-list-${i}`"
- :unresolved-issues="unresolvedIssues(report)"
- :new-issues="newIssues(report)"
- :resolved-issues="resolvedIssues(report)"
- :component="$options.componentNames.TestIssueBody"
- class="report-block-group-list"
- />
- </template>
+ <template #body>
+ <div class="mr-widget-grouped-section report-block">
+ <template v-for="(report, i) in reports">
+ <summary-row
+ :key="`summary-row-${i}`"
+ :summary="reportText(report)"
+ :status-icon="getReportIcon(report)"
+ />
+ <issues-list
+ v-if="shouldRenderIssuesList(report)"
+ :key="`issues-list-${i}`"
+ :unresolved-issues="unresolvedIssues(report)"
+ :new-issues="newIssues(report)"
+ :resolved-issues="resolvedIssues(report)"
+ :component="$options.componentNames.TestIssueBody"
+ class="report-block-group-list"
+ />
+ </template>
- <modal :title="modalTitle" :modal-data="modalData" />
- </div>
+ <modal :title="modalTitle" :modal-data="modalData" />
+ </div>
+ </template>
</report-section>
</template>
diff --git a/app/assets/javascripts/reports/components/summary_row.vue b/app/assets/javascripts/reports/components/summary_row.vue
index 9cbe2a690a0..b9fc902cd3a 100644
--- a/app/assets/javascripts/reports/components/summary_row.vue
+++ b/app/assets/javascripts/reports/components/summary_row.vue
@@ -54,7 +54,10 @@ export default {
<ci-icon v-else :status="iconStatus" :size="24" />
</div>
<div class="report-block-list-issue-description">
- <div class="report-block-list-issue-description-text">
+ <div
+ class="report-block-list-issue-description-text"
+ data-testid="test-summary-row-description"
+ >
{{ summary
}}<span v-if="popoverOptions" class="text-nowrap"
>&nbsp;<popover v-if="popoverOptions" :options="popoverOptions" class="align-top" />
diff --git a/app/assets/javascripts/reports/components/test_issue_body.vue b/app/assets/javascripts/reports/components/test_issue_body.vue
index 7700f49bf7d..c41238070b1 100644
--- a/app/assets/javascripts/reports/components/test_issue_body.vue
+++ b/app/assets/javascripts/reports/components/test_issue_body.vue
@@ -26,7 +26,7 @@ export default {
</script>
<template>
<div class="report-block-list-issue-description prepend-top-5 append-bottom-5">
- <div class="report-block-list-issue-description-text">
+ <div class="report-block-list-issue-description-text" data-testid="test-issue-body-description">
<button
type="button"
class="btn-link btn-blank text-left break-link vulnerability-name-button"
diff --git a/app/assets/javascripts/repository/components/last_commit.vue b/app/assets/javascripts/repository/components/last_commit.vue
index 010fc9a5d1a..c5c99d56e2a 100644
--- a/app/assets/javascripts/repository/components/last_commit.vue
+++ b/app/assets/javascripts/repository/components/last_commit.vue
@@ -149,7 +149,7 @@ export default {
<pre
v-if="commit.description"
:class="{ 'd-block': showDescription }"
- class="commit-row-description append-bottom-8"
+ class="commit-row-description gl-mb-3"
>{{ commit.description }}</pre
>
</div>
diff --git a/app/assets/javascripts/repository/components/table/row.vue b/app/assets/javascripts/repository/components/table/row.vue
index 34424121390..d5363016335 100644
--- a/app/assets/javascripts/repository/components/table/row.vue
+++ b/app/assets/javascripts/repository/components/table/row.vue
@@ -147,8 +147,11 @@ export default {
class="mr-1 position-relative text-secondary"
/><span class="position-relative">{{ fullPath }}</span>
</component>
- <!-- eslint-disable-next-line @gitlab/vue-require-i18n-strings -->
- <gl-badge v-if="lfsOid" variant="default" class="label-lfs ml-1">LFS</gl-badge>
+ <!-- eslint-disable @gitlab/vue-require-i18n-strings -->
+ <gl-badge v-if="lfsOid" variant="muted" size="sm" class="ml-1" data-qa-selector="label-lfs"
+ >LFS</gl-badge
+ >
+ <!-- eslint-enable @gitlab/vue-require-i18n-strings -->
<template v-if="isSubmodule">
@ <gl-link :href="submoduleTreeUrl" class="commit-sha">{{ shortSha }}</gl-link>
</template>
diff --git a/app/assets/javascripts/repository/queries/getVueFileListLfsBadge.query.graphql b/app/assets/javascripts/repository/queries/getVueFileListLfsBadge.query.graphql
index 3c3d14881da..eb21c1e73d8 100644
--- a/app/assets/javascripts/repository/queries/getVueFileListLfsBadge.query.graphql
+++ b/app/assets/javascripts/repository/queries/getVueFileListLfsBadge.query.graphql
@@ -1,3 +1,3 @@
-query getProjectShortPath {
+query getVueFileListLfsBadge {
vueFileListLfsBadge @client
}
diff --git a/app/assets/javascripts/search_autocomplete.js b/app/assets/javascripts/search_autocomplete.js
deleted file mode 100644
index d8eb981c106..00000000000
--- a/app/assets/javascripts/search_autocomplete.js
+++ /dev/null
@@ -1,482 +0,0 @@
-/* eslint-disable no-return-assign, consistent-return, class-methods-use-this */
-
-import $ from 'jquery';
-import { escape, throttle } from 'lodash';
-import { s__, __ } from '~/locale';
-import { getIdenticonBackgroundClass, getIdenticonTitle } from '~/helpers/avatar_helper';
-import axios from './lib/utils/axios_utils';
-import {
- isInGroupsPage,
- isInProjectPage,
- getGroupSlug,
- getProjectSlug,
- spriteIcon,
-} from './lib/utils/common_utils';
-
-/**
- * Search input in top navigation bar.
- * On click, opens a dropdown
- * As the user types it filters the results
- * When the user clicks `x` button it cleans the input and closes the dropdown.
- */
-
-const KEYCODE = {
- ESCAPE: 27,
- BACKSPACE: 8,
- ENTER: 13,
- UP: 38,
- DOWN: 40,
-};
-
-function setSearchOptions() {
- const $projectOptionsDataEl = $('.js-search-project-options');
- const $groupOptionsDataEl = $('.js-search-group-options');
- const $dashboardOptionsDataEl = $('.js-search-dashboard-options');
-
- if ($projectOptionsDataEl.length) {
- gl.projectOptions = gl.projectOptions || {};
-
- const projectPath = $projectOptionsDataEl.data('projectPath');
-
- gl.projectOptions[projectPath] = {
- name: $projectOptionsDataEl.data('name'),
- issuesPath: $projectOptionsDataEl.data('issuesPath'),
- issuesDisabled: $projectOptionsDataEl.data('issuesDisabled'),
- mrPath: $projectOptionsDataEl.data('mrPath'),
- };
- }
-
- if ($groupOptionsDataEl.length) {
- gl.groupOptions = gl.groupOptions || {};
-
- const groupPath = $groupOptionsDataEl.data('groupPath');
-
- gl.groupOptions[groupPath] = {
- name: $groupOptionsDataEl.data('name'),
- issuesPath: $groupOptionsDataEl.data('issuesPath'),
- mrPath: $groupOptionsDataEl.data('mrPath'),
- };
- }
-
- if ($dashboardOptionsDataEl.length) {
- gl.dashboardOptions = {
- name: s__('SearchAutocomplete|All GitLab'),
- issuesPath: $dashboardOptionsDataEl.data('issuesPath'),
- mrPath: $dashboardOptionsDataEl.data('mrPath'),
- };
- }
-}
-
-export class SearchAutocomplete {
- constructor({ wrap, optsEl, autocompletePath, projectId, projectRef } = {}) {
- setSearchOptions();
- this.bindEventContext();
- this.wrap = wrap || $('.search');
- this.optsEl = optsEl || this.wrap.find('.search-autocomplete-opts');
- this.autocompletePath = autocompletePath || this.optsEl.data('autocompletePath');
- this.projectId = projectId || (this.optsEl.data('autocompleteProjectId') || '');
- this.projectRef = projectRef || (this.optsEl.data('autocompleteProjectRef') || '');
- this.dropdown = this.wrap.find('.dropdown');
- this.dropdownToggle = this.wrap.find('.js-dropdown-search-toggle');
- this.dropdownMenu = this.dropdown.find('.dropdown-menu');
- this.dropdownContent = this.dropdown.find('.dropdown-content');
- this.scopeInputEl = this.getElement('#scope');
- this.searchInput = this.getElement('.search-input');
- this.projectInputEl = this.getElement('#search_project_id');
- this.groupInputEl = this.getElement('#group_id');
- this.searchCodeInputEl = this.getElement('#search_code');
- this.repositoryInputEl = this.getElement('#repository_ref');
- this.clearInput = this.getElement('.js-clear-input');
- this.scrollFadeInitialized = false;
- this.saveOriginalState();
-
- // Only when user is logged in
- if (gon.current_user_id) {
- this.createAutocomplete();
- }
-
- this.bindEvents();
- this.dropdownToggle.dropdown();
- this.searchInput.addClass('js-autocomplete-disabled');
- }
-
- // Finds an element inside wrapper element
- bindEventContext() {
- this.onSearchInputBlur = this.onSearchInputBlur.bind(this);
- this.onClearInputClick = this.onClearInputClick.bind(this);
- this.onSearchInputFocus = this.onSearchInputFocus.bind(this);
- this.onSearchInputKeyUp = this.onSearchInputKeyUp.bind(this);
- this.onSearchInputChange = this.onSearchInputChange.bind(this);
- this.setScrollFade = this.setScrollFade.bind(this);
- }
- getElement(selector) {
- return this.wrap.find(selector);
- }
-
- saveOriginalState() {
- return (this.originalState = this.serializeState());
- }
-
- createAutocomplete() {
- return this.searchInput.glDropdown({
- filterInputBlur: false,
- filterable: true,
- filterRemote: true,
- highlight: true,
- icon: true,
- enterCallback: false,
- filterInput: 'input#search',
- search: {
- fields: ['text'],
- },
- id: this.getSearchText,
- data: this.getData.bind(this),
- selectable: true,
- clicked: this.onClick.bind(this),
- });
- }
-
- getSearchText(selectedObject) {
- return selectedObject.id ? selectedObject.text : '';
- }
-
- getData(term, callback) {
- if (!term) {
- const contents = this.getCategoryContents();
- if (contents) {
- const glDropdownInstance = this.searchInput.data('glDropdown');
-
- if (glDropdownInstance) {
- glDropdownInstance.filter.options.callback(contents);
- }
- this.enableAutocomplete();
- }
- return;
- }
-
- // Prevent multiple ajax calls
- if (this.loadingSuggestions) {
- return;
- }
-
- this.loadingSuggestions = true;
-
- return axios
- .get(this.autocompletePath, {
- params: {
- project_id: this.projectId,
- project_ref: this.projectRef,
- term,
- },
- })
- .then(response => {
- // Hide dropdown menu if no suggestions returns
- if (!response.data.length) {
- this.disableAutocomplete();
- return;
- }
-
- const data = [];
- // List results
- let firstCategory = true;
- let lastCategory;
- for (let i = 0, len = response.data.length; i < len; i += 1) {
- const suggestion = response.data[i];
- // Add group header before list each group
- if (lastCategory !== suggestion.category) {
- if (!firstCategory) {
- data.push({ type: 'separator' });
- }
- if (firstCategory) {
- firstCategory = false;
- }
- data.push({
- type: 'header',
- content: suggestion.category,
- });
- lastCategory = suggestion.category;
- }
- data.push({
- id: `${suggestion.category.toLowerCase()}-${suggestion.id}`,
- icon: this.getAvatar(suggestion),
- category: suggestion.category,
- text: suggestion.label,
- url: suggestion.url,
- });
- }
- // Add option to proceed with the search
- if (data.length) {
- const icon = spriteIcon('search', 's16 inline-search-icon');
- let template;
-
- if (this.projectInputEl.val()) {
- template = s__('SearchAutocomplete|in this project');
- }
- if (this.groupInputEl.val()) {
- template = s__('SearchAutocomplete|in this group');
- }
-
- data.unshift({ type: 'separator' });
- data.unshift({
- icon,
- text: term,
- template: s__('SearchAutocomplete|in all GitLab'),
- url: `${gon.relative_url_root}/search?search=${term}`,
- });
-
- if (template) {
- data.unshift({
- icon,
- text: term,
- template,
- url: `${
- gon.relative_url_root
- }/search?search=${term}&project_id=${this.projectInputEl.val()}&group_id=${this.groupInputEl.val()}`,
- });
- }
- }
-
- callback(data);
-
- this.loadingSuggestions = false;
- this.highlightFirstRow();
- this.setScrollFade();
- })
- .catch(() => {
- this.loadingSuggestions = false;
- });
- }
-
- getCategoryContents() {
- const userName = gon.current_username;
- const { projectOptions, groupOptions, dashboardOptions } = gl;
-
- // Get options
- let options;
- if (isInGroupsPage() && groupOptions) {
- options = groupOptions[getGroupSlug()];
- } else if (isInProjectPage() && projectOptions) {
- options = projectOptions[getProjectSlug()];
- } else if (dashboardOptions) {
- options = dashboardOptions;
- }
-
- const { issuesPath, mrPath, name, issuesDisabled } = options;
- const baseItems = [];
-
- if (name) {
- baseItems.push({
- type: 'header',
- content: `${name}`,
- });
- }
-
- const issueItems = [
- {
- text: s__('SearchAutocomplete|Issues assigned to me'),
- url: `${issuesPath}/?assignee_username=${userName}`,
- },
- {
- text: s__("SearchAutocomplete|Issues I've created"),
- url: `${issuesPath}/?author_username=${userName}`,
- },
- ];
- const mergeRequestItems = [
- {
- text: s__('SearchAutocomplete|Merge requests assigned to me'),
- url: `${mrPath}/?assignee_username=${userName}`,
- },
- {
- text: s__("SearchAutocomplete|Merge requests I've created"),
- url: `${mrPath}/?author_username=${userName}`,
- },
- ];
-
- let items;
- if (issuesDisabled) {
- items = baseItems.concat(mergeRequestItems);
- } else {
- items = baseItems.concat(...issueItems, ...mergeRequestItems);
- }
- return items;
- }
-
- serializeState() {
- return {
- // Search Criteria
- search_project_id: this.projectInputEl.val(),
- group_id: this.groupInputEl.val(),
- search_code: this.searchCodeInputEl.val(),
- repository_ref: this.repositoryInputEl.val(),
- scope: this.scopeInputEl.val(),
- };
- }
-
- bindEvents() {
- this.searchInput.on('input', this.onSearchInputChange);
- this.searchInput.on('keyup', this.onSearchInputKeyUp);
- this.searchInput.on('focus', this.onSearchInputFocus);
- this.searchInput.on('blur', this.onSearchInputBlur);
- this.clearInput.on('click', this.onClearInputClick);
- this.dropdownContent.on('scroll', throttle(this.setScrollFade, 250));
-
- this.searchInput.on('click', e => {
- e.stopPropagation();
- });
- }
-
- enableAutocomplete() {
- this.setScrollFade();
-
- // No need to enable anything if user is not logged in
- if (!gon.current_user_id) {
- return;
- }
-
- // If the dropdown is closed, we'll open it
- if (!this.dropdown.hasClass('show')) {
- this.loadingSuggestions = false;
- this.dropdownToggle.dropdown('toggle');
- return this.searchInput.removeClass('js-autocomplete-disabled');
- }
- }
-
- onSearchInputChange() {
- this.enableAutocomplete();
- }
-
- onSearchInputKeyUp(e) {
- switch (e.keyCode) {
- case KEYCODE.ESCAPE:
- this.restoreOriginalState();
- break;
- case KEYCODE.ENTER:
- this.disableAutocomplete();
- break;
- default:
- }
- this.wrap.toggleClass('has-value', Boolean(e.target.value));
- }
-
- onSearchInputFocus() {
- this.isFocused = true;
- this.wrap.addClass('search-active');
- if (this.getValue() === '') {
- return this.getData();
- }
- }
-
- getValue() {
- return this.searchInput.val();
- }
-
- onClearInputClick(e) {
- e.preventDefault();
- this.wrap.toggleClass('has-value', Boolean(e.target.value));
- return this.searchInput.val('').focus();
- }
-
- onSearchInputBlur() {
- this.isFocused = false;
- this.wrap.removeClass('search-active');
- // If input is blank then restore state
- if (this.searchInput.val() === '') {
- this.restoreOriginalState();
- }
- this.dropdownMenu.removeClass('show');
- }
-
- restoreOriginalState() {
- const inputs = Object.keys(this.originalState);
- for (let i = 0, len = inputs.length; i < len; i += 1) {
- const input = inputs[i];
- this.getElement(`#${input}`).val(this.originalState[input]);
- }
- }
-
- resetSearchState() {
- const inputs = Object.keys(this.originalState);
- const results = [];
- for (let i = 0, len = inputs.length; i < len; i += 1) {
- const input = inputs[i];
- results.push(this.getElement(`#${input}`).val(''));
- }
- return results;
- }
-
- disableAutocomplete() {
- if (!this.searchInput.hasClass('js-autocomplete-disabled') && this.dropdown.hasClass('show')) {
- this.searchInput.addClass('js-autocomplete-disabled');
- this.dropdownToggle.dropdown('toggle');
- this.restoreMenu();
- }
- }
-
- restoreMenu() {
- const html = `<ul><li class="dropdown-menu-empty-item"><a>${__('Loading...')}</a></li></ul>`;
- return this.dropdownContent.html(html);
- }
-
- onClick(item, $el, e) {
- if (window.location.pathname.indexOf(item.url) !== -1) {
- if (!e.metaKey) e.preventDefault();
- /* eslint-disable-next-line @gitlab/require-i18n-strings */
- if (item.category === 'Projects') {
- this.projectInputEl.val(item.id);
- }
- // eslint-disable-next-line @gitlab/require-i18n-strings
- if (item.category === 'Groups') {
- this.groupInputEl.val(item.id);
- }
- $el.removeClass('is-active');
- this.disableAutocomplete();
- return this.searchInput.val('').focus();
- }
- }
-
- highlightFirstRow() {
- this.searchInput.data('glDropdown').highlightRowAtIndex(null, 0);
- }
-
- getAvatar(item) {
- if (!Object.hasOwnProperty.call(item, 'avatar_url')) {
- return false;
- }
-
- const { label, id } = item;
- const avatarUrl = item.avatar_url;
- const avatar = avatarUrl
- ? `<img class="search-item-avatar" src="${avatarUrl}" />`
- : `<div class="s16 avatar identicon ${getIdenticonBackgroundClass(id)}">${getIdenticonTitle(
- escape(label),
- )}</div>`;
-
- return avatar;
- }
-
- isScrolledUp() {
- const el = this.dropdownContent[0];
- const currentPosition = this.contentClientHeight + el.scrollTop;
-
- return currentPosition < this.maxPosition;
- }
-
- initScrollFade() {
- const el = this.dropdownContent[0];
- this.scrollFadeInitialized = true;
-
- this.contentClientHeight = el.clientHeight;
- this.maxPosition = el.scrollHeight;
- this.dropdownMenu.addClass('dropdown-content-faded-mask');
- }
-
- setScrollFade() {
- this.initScrollFade();
-
- this.dropdownMenu.toggleClass('fade-out', !this.isScrolledUp());
- }
-}
-
-export default function initSearchAutocomplete(opts) {
- return new SearchAutocomplete(opts);
-}
diff --git a/app/assets/javascripts/serverless/components/function_row.vue b/app/assets/javascripts/serverless/components/function_row.vue
index bbafdd7f8f1..aac7c46a295 100644
--- a/app/assets/javascripts/serverless/components/function_row.vue
+++ b/app/assets/javascripts/serverless/components/function_row.vue
@@ -71,7 +71,7 @@ export default {
</p>
<b>{{ name }}</b>
<div v-for="line in description.split('\n')" :key="line">{{ line }}</div>
- <url :uri="targetUrl" class="prepend-top-8 no-expand" />
+ <url :uri="targetUrl" class="gl-mt-3 no-expand" />
</div>
</li>
</template>
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 2757d64bd7d..fd1f9eae152 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
@@ -82,7 +82,8 @@ export default {
})
.catch(() => createFlash(__('Failed to load emoji list.')));
},
- showEmojiMenu() {
+ showEmojiMenu(e) {
+ e.stopPropagation();
this.isEmojiMenuVisible = true;
this.emojiMenu.showEmojiMenu($(this.$refs.toggleEmojiMenuButton));
},
diff --git a/app/assets/javascripts/shared/sessions/u2f.js b/app/assets/javascripts/shared/sessions/u2f.js
deleted file mode 100644
index 6ae9faf1dde..00000000000
--- a/app/assets/javascripts/shared/sessions/u2f.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import $ from 'jquery';
-import U2FAuthenticate from '../../u2f/authenticate';
-
-export default () => {
- if (!gon.u2f) return;
-
- const u2fAuthenticate = new U2FAuthenticate(
- $('#js-authenticate-u2f'),
- '#js-login-u2f-form',
- gon.u2f,
- document.querySelector('#js-login-2fa-device'),
- document.querySelector('.js-2fa-form'),
- );
- u2fAuthenticate.start();
- // needed in rspec
- gl.u2fAuthenticate = u2fAuthenticate;
-};
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/help_state.vue b/app/assets/javascripts/sidebar/components/time_tracking/help_state.vue
index 51cd5810ac0..67abde0c22a 100644
--- a/app/assets/javascripts/sidebar/components/time_tracking/help_state.vue
+++ b/app/assets/javascripts/sidebar/components/time_tracking/help_state.vue
@@ -1,17 +1,12 @@
<script>
import { sprintf, s__ } from '../../../locale';
+import { joinPaths } from '~/lib/utils/url_utility';
export default {
name: 'TimeTrackingHelpState',
- props: {
- rootPath: {
- type: String,
- required: true,
- },
- },
computed: {
href() {
- return `${this.rootPath}help/workflow/time_tracking.md`;
+ return joinPaths(gon.relative_url_root || '', '/help/user/project/time_tracking.md');
},
estimateText() {
return sprintf(
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue b/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue
index 1e8a31fff81..5cf574e1387 100644
--- a/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue
+++ b/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue
@@ -42,10 +42,6 @@ export default {
default: false,
required: false,
},
- rootPath: {
- type: String,
- required: true,
- },
},
data() {
return {
@@ -137,7 +133,7 @@ export default {
:limit-to-hours="limitToHours"
/>
<transition name="help-state-toggle">
- <time-tracking-help-state v-if="showHelpState" :root-path="rootPath" />
+ <time-tracking-help-state v-if="showHelpState" />
</transition>
</div>
</div>
diff --git a/app/assets/javascripts/sidebar/mount_milestone_sidebar.js b/app/assets/javascripts/sidebar/mount_milestone_sidebar.js
index d934463382f..0f5f8f2b53b 100644
--- a/app/assets/javascripts/sidebar/mount_milestone_sidebar.js
+++ b/app/assets/javascripts/sidebar/mount_milestone_sidebar.js
@@ -24,7 +24,6 @@ export default class SidebarMilestone {
humanTimeEstimate,
humanTimeSpent,
limitToHours: parseBoolean(limitToHours),
- rootPath: '/',
},
}),
});
diff --git a/app/assets/javascripts/snippets/components/edit.vue b/app/assets/javascripts/snippets/components/edit.vue
index e8d6c005435..a6651515e47 100644
--- a/app/assets/javascripts/snippets/components/edit.vue
+++ b/app/assets/javascripts/snippets/components/edit.vue
@@ -11,7 +11,11 @@ import FormFooterActions from '~/vue_shared/components/form/form_footer_actions.
import UpdateSnippetMutation from '../mutations/updateSnippet.mutation.graphql';
import CreateSnippetMutation from '../mutations/createSnippet.mutation.graphql';
import { getSnippetMixin } from '../mixins/snippets';
-import { SNIPPET_VISIBILITY_PRIVATE } from '../constants';
+import {
+ SNIPPET_VISIBILITY_PRIVATE,
+ SNIPPET_CREATE_MUTATION_ERROR,
+ SNIPPET_UPDATE_MUTATION_ERROR,
+} from '../constants';
import SnippetBlobEdit from './snippet_blob_edit.vue';
import SnippetVisibilityEdit from './snippet_visibility_edit.vue';
import SnippetDescriptionEdit from './snippet_description_edit.vue';
@@ -98,7 +102,11 @@ export default {
this.fileName = newName;
},
flashAPIFailure(err) {
- Flash(sprintf(__("Can't update snippet: %{err}"), { err }));
+ const defaultErrorMsg = this.newSnippet
+ ? SNIPPET_CREATE_MUTATION_ERROR
+ : SNIPPET_UPDATE_MUTATION_ERROR;
+ Flash(sprintf(defaultErrorMsg, { err }));
+ this.isUpdating = false;
},
onNewSnippetFetched() {
this.newSnippet = true;
@@ -129,29 +137,45 @@ export default {
this.onExistingSnippetFetched();
}
},
+ getAttachedFiles() {
+ const fileInputs = Array.from(this.$el.querySelectorAll('[name="files[]"]'));
+ return fileInputs.map(node => node.value);
+ },
+ createMutation() {
+ return {
+ mutation: CreateSnippetMutation,
+ variables: {
+ input: {
+ ...this.apiData,
+ uploadedFiles: this.getAttachedFiles(),
+ projectPath: this.projectPath,
+ },
+ },
+ };
+ },
+ updateMutation() {
+ return {
+ mutation: UpdateSnippetMutation,
+ variables: {
+ input: this.apiData,
+ },
+ };
+ },
handleFormSubmit() {
this.isUpdating = true;
this.$apollo
- .mutate({
- mutation: this.newSnippet ? CreateSnippetMutation : UpdateSnippetMutation,
- variables: {
- input: {
- ...this.apiData,
- projectPath: this.newSnippet ? this.projectPath : undefined,
- },
- },
- })
+ .mutate(this.newSnippet ? this.createMutation() : this.updateMutation())
.then(({ data }) => {
const baseObj = this.newSnippet ? data?.createSnippet : data?.updateSnippet;
const errors = baseObj?.errors;
if (errors.length) {
this.flashAPIFailure(errors[0]);
+ } else {
+ redirectTo(baseObj.snippet.webUrl);
}
- redirectTo(baseObj.snippet.webUrl);
})
.catch(e => {
- this.isUpdating = false;
this.flashAPIFailure(e);
});
},
@@ -168,6 +192,8 @@ export default {
<form
class="snippet-form js-requires-input js-quick-submit common-note-form"
:data-snippet-type="isProjectSnippet ? 'project' : 'personal'"
+ data-testid="snippet-edit-form"
+ @submit.prevent="handleFormSubmit"
>
<gl-loading-icon
v-if="isLoading"
@@ -179,7 +205,7 @@ export default {
<title-field
:id="titleFieldId"
v-model="snippet.title"
- data-qa-selector="snippet_title"
+ data-qa-selector="snippet_title_field"
required
:autofocus="true"
/>
@@ -203,17 +229,17 @@ export default {
<form-footer-actions>
<template #prepend>
<gl-button
- type="submit"
category="primary"
+ type="submit"
variant="success"
:disabled="updatePrevented"
data-qa-selector="submit_button"
- @click="handleFormSubmit"
+ data-testid="snippet-submit-btn"
>{{ saveButtonLabel }}</gl-button
>
</template>
<template #append>
- <gl-button data-testid="snippet-cancel-btn" :href="cancelButtonHref">{{
+ <gl-button type="cancel" data-testid="snippet-cancel-btn" :href="cancelButtonHref">{{
__('Cancel')
}}</gl-button>
</template>
diff --git a/app/assets/javascripts/snippets/components/snippet_blob_edit.vue b/app/assets/javascripts/snippets/components/snippet_blob_edit.vue
index dd03902417d..62c29b0c7cd 100644
--- a/app/assets/javascripts/snippets/components/snippet_blob_edit.vue
+++ b/app/assets/javascripts/snippets/components/snippet_blob_edit.vue
@@ -35,7 +35,7 @@ export default {
<div class="file-holder snippet">
<blob-header-edit
:value="fileName"
- data-qa-selector="snippet_file_name"
+ data-qa-selector="file_name_field"
@input="$emit('name-change', $event)"
/>
<gl-loading-icon
diff --git a/app/assets/javascripts/snippets/components/snippet_blob_view.vue b/app/assets/javascripts/snippets/components/snippet_blob_view.vue
index 6b218b21e56..7472aff3318 100644
--- a/app/assets/javascripts/snippets/components/snippet_blob_view.vue
+++ b/app/assets/javascripts/snippets/components/snippet_blob_view.vue
@@ -74,6 +74,9 @@ export default {
canBeCloned() {
return this.snippet.sshUrlToRepo || this.snippet.httpUrlToRepo;
},
+ hasRenderError() {
+ return Boolean(this.viewer.renderError);
+ },
},
methods: {
switchViewer(newViewer) {
@@ -92,7 +95,12 @@ export default {
<div>
<blob-embeddable v-if="embeddable" class="mb-3" :url="snippet.webUrl" />
<article class="file-holder snippet-file-content">
- <blob-header :blob="blob" :active-viewer-type="viewer.type" @viewer-changed="switchViewer">
+ <blob-header
+ :blob="blob"
+ :active-viewer-type="viewer.type"
+ :has-render-error="hasRenderError"
+ @viewer-changed="switchViewer"
+ >
<template #actions>
<clone-dropdown-button
v-if="canBeCloned"
diff --git a/app/assets/javascripts/snippets/components/snippet_description_edit.vue b/app/assets/javascripts/snippets/components/snippet_description_edit.vue
index 0fe539a5de7..737845d09b8 100644
--- a/app/assets/javascripts/snippets/components/snippet_description_edit.vue
+++ b/app/assets/javascripts/snippets/components/snippet_description_edit.vue
@@ -30,7 +30,7 @@ export default {
</script>
<template>
<div class="form-group js-description-input">
- <label>{{ s__('Snippets|Description (optional)') }}</label>
+ <label for="snippet-description">{{ s__('Snippets|Description (optional)') }}</label>
<div class="js-collapsible-input">
<div class="js-collapsed" :class="{ 'd-none': value }">
<gl-form-input
@@ -46,22 +46,26 @@ export default {
<markdown-field
class="js-expanded"
:class="{ 'd-none': !value }"
+ :add-spacing-classes="false"
:markdown-preview-path="markdownPreviewPath"
:markdown-docs-path="markdownDocsPath"
>
- <textarea
- slot="textarea"
- class="note-textarea js-gfm-input js-autosize markdown-area"
- dir="auto"
- data-qa-selector="snippet_description_field"
- data-supports-quick-actions="false"
- :value="value"
- :aria-label="__('Description')"
- :placeholder="__('Write a comment or drag your files here…')"
- v-bind="$attrs"
- @input="$emit('input', $event.target.value)"
- >
- </textarea>
+ <template #textarea>
+ <textarea
+ id="snippet-description"
+ ref="textarea"
+ :value="value"
+ class="note-textarea js-gfm-input js-autosize markdown-area"
+ dir="auto"
+ data-qa-selector="snippet_description_field"
+ data-supports-quick-actions="false"
+ :aria-label="__('Description')"
+ :placeholder="__('Write a comment or drag your files here…')"
+ v-bind="$attrs"
+ @input="$emit('input', $event.target.value)"
+ >
+ </textarea>
+ </template>
</markdown-field>
</div>
</div>
diff --git a/app/assets/javascripts/snippets/components/snippet_description_view.vue b/app/assets/javascripts/snippets/components/snippet_description_view.vue
index 72afcc30be6..a5107f09fc7 100644
--- a/app/assets/javascripts/snippets/components/snippet_description_view.vue
+++ b/app/assets/javascripts/snippets/components/snippet_description_view.vue
@@ -15,7 +15,7 @@ export default {
};
</script>
<template>
- <markdown-field-view class="snippet-description" data-qa-selector="snippet_description_field">
+ <markdown-field-view class="snippet-description" data-qa-selector="snippet_description_content">
<div class="md js-snippet-description" v-html="description"></div>
</markdown-field-view>
</template>
diff --git a/app/assets/javascripts/snippets/components/snippet_header.vue b/app/assets/javascripts/snippets/components/snippet_header.vue
index c0967e9093c..2a06296cb15 100644
--- a/app/assets/javascripts/snippets/components/snippet_header.vue
+++ b/app/assets/javascripts/snippets/components/snippet_header.vue
@@ -163,7 +163,8 @@ export default {
<div class="detail-page-header">
<div class="detail-page-header-body">
<div
- class="snippet-box qa-snippet-box has-tooltip d-flex align-items-center append-right-5 mb-1"
+ class="snippet-box has-tooltip d-flex align-items-center append-right-5 mb-1"
+ data-qa-selector="snippet_container"
:title="snippetVisibilityLevelDescription"
data-container="body"
>
diff --git a/app/assets/javascripts/snippets/components/snippet_title.vue b/app/assets/javascripts/snippets/components/snippet_title.vue
index 5267c3748ca..2cf7a1e267b 100644
--- a/app/assets/javascripts/snippets/components/snippet_title.vue
+++ b/app/assets/javascripts/snippets/components/snippet_title.vue
@@ -20,7 +20,7 @@ export default {
</script>
<template>
<div class="snippet-header limited-header-width">
- <h2 class="snippet-title prepend-top-0 mb-3" data-qa-selector="snippet_title">
+ <h2 class="snippet-title gl-mt-0 mb-3" data-qa-selector="snippet_title_content">
{{ snippet.title }}
</h2>
diff --git a/app/assets/javascripts/snippets/constants.js b/app/assets/javascripts/snippets/constants.js
index 7fd5e5b8ee4..b3abc73557c 100644
--- a/app/assets/javascripts/snippets/constants.js
+++ b/app/assets/javascripts/snippets/constants.js
@@ -22,3 +22,6 @@ export const SNIPPET_VISIBILITY = {
description: __('The snippet can be accessed without any authentication.'),
},
};
+
+export const SNIPPET_CREATE_MUTATION_ERROR = __("Can't create snippet: %{err}");
+export const SNIPPET_UPDATE_MUTATION_ERROR = __("Can't update snippet: %{err}");
diff --git a/app/assets/javascripts/static_site_editor/components/edit_area.vue b/app/assets/javascripts/static_site_editor/components/edit_area.vue
index dff21d919a9..e9efef40632 100644
--- a/app/assets/javascripts/static_site_editor/components/edit_area.vue
+++ b/app/assets/javascripts/static_site_editor/components/edit_area.vue
@@ -2,12 +2,16 @@
import RichContentEditor from '~/vue_shared/components/rich_content_editor/rich_content_editor.vue';
import PublishToolbar from './publish_toolbar.vue';
import EditHeader from './edit_header.vue';
+import UnsavedChangesConfirmDialog from './unsaved_changes_confirm_dialog.vue';
+import parseSourceFile from '~/static_site_editor/services/parse_source_file';
+import { EDITOR_TYPES } from '~/vue_shared/components/rich_content_editor/constants';
export default {
components: {
RichContentEditor,
PublishToolbar,
EditHeader,
+ UnsavedChangesConfirmDialog,
},
props: {
title: {
@@ -30,26 +34,57 @@ export default {
},
data() {
return {
- editableContent: this.content,
saveable: false,
+ parsedSource: parseSourceFile(this.content),
+ editorMode: EDITOR_TYPES.wysiwyg,
};
},
computed: {
+ editableContent() {
+ return this.parsedSource.editable;
+ },
+ editableKey() {
+ return this.isWysiwygMode ? 'body' : 'raw';
+ },
+ isWysiwygMode() {
+ return this.editorMode === EDITOR_TYPES.wysiwyg;
+ },
modified() {
- return this.content !== this.editableContent;
+ return this.isWysiwygMode
+ ? this.parsedSource.isModifiedBody()
+ : this.parsedSource.isModifiedRaw();
},
},
methods: {
+ syncSource() {
+ if (this.isWysiwygMode) {
+ this.parsedSource.syncBody();
+ return;
+ }
+
+ this.parsedSource.syncRaw();
+ },
+ onModeChange(mode) {
+ this.editorMode = mode;
+ this.syncSource();
+ },
onSubmit() {
- this.$emit('submit', { content: this.editableContent });
+ this.syncSource();
+ this.$emit('submit', { content: this.editableContent.raw });
},
},
};
</script>
<template>
- <div class="d-flex flex-grow-1 flex-column">
+ <div class="d-flex flex-grow-1 flex-column h-100">
<edit-header class="py-2" :title="title" />
- <rich-content-editor v-model="editableContent" class="mb-9" />
+ <rich-content-editor
+ v-model="editableContent[editableKey]"
+ :initial-edit-type="editorMode"
+ class="mb-9 h-100"
+ @modeChange="onModeChange"
+ />
+ <unsaved-changes-confirm-dialog :modified="modified" />
<publish-toolbar
class="gl-fixed gl-left-0 gl-bottom-0 gl-w-full"
:return-url="returnUrl"
diff --git a/app/assets/javascripts/static_site_editor/components/unsaved_changes_confirm_dialog.vue b/app/assets/javascripts/static_site_editor/components/unsaved_changes_confirm_dialog.vue
new file mode 100644
index 00000000000..255f029bd27
--- /dev/null
+++ b/app/assets/javascripts/static_site_editor/components/unsaved_changes_confirm_dialog.vue
@@ -0,0 +1,27 @@
+<script>
+export default {
+ props: {
+ modified: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+ created() {
+ window.addEventListener('beforeunload', this.requestConfirmation);
+ },
+ destroyed() {
+ window.removeEventListener('beforeunload', this.requestConfirmation);
+ },
+ methods: {
+ requestConfirmation(e) {
+ if (this.modified) {
+ e.preventDefault();
+ // eslint-disable-next-line no-param-reassign
+ e.returnValue = '';
+ }
+ },
+ },
+ render: () => null,
+};
+</script>
diff --git a/app/assets/javascripts/static_site_editor/constants.js b/app/assets/javascripts/static_site_editor/constants.js
index 4794cf5eead..947347922f2 100644
--- a/app/assets/javascripts/static_site_editor/constants.js
+++ b/app/assets/javascripts/static_site_editor/constants.js
@@ -17,3 +17,5 @@ export const LOAD_CONTENT_ERROR = __(
export const DEFAULT_HEADING = s__('StaticSiteEditor|Static site editor');
export const TRACKING_ACTION_CREATE_COMMIT = 'create_commit';
+export const TRACKING_ACTION_CREATE_MERGE_REQUEST = 'create_merge_request';
+export const TRACKING_ACTION_INITIALIZE_EDITOR = 'initialize_editor';
diff --git a/app/assets/javascripts/static_site_editor/pages/home.vue b/app/assets/javascripts/static_site_editor/pages/home.vue
index f65b648acd6..a1314c8a478 100644
--- a/app/assets/javascripts/static_site_editor/pages/home.vue
+++ b/app/assets/javascripts/static_site_editor/pages/home.vue
@@ -7,7 +7,8 @@ import appDataQuery from '../graphql/queries/app_data.query.graphql';
import sourceContentQuery from '../graphql/queries/source_content.query.graphql';
import submitContentChangesMutation from '../graphql/mutations/submit_content_changes.mutation.graphql';
import createFlash from '~/flash';
-import { LOAD_CONTENT_ERROR } from '../constants';
+import Tracking from '~/tracking';
+import { LOAD_CONTENT_ERROR, TRACKING_ACTION_INITIALIZE_EDITOR } from '../constants';
import { SUCCESS_ROUTE } from '../router/constants';
export default {
@@ -59,6 +60,9 @@ export default {
return Boolean(this.sourceContent);
},
},
+ mounted() {
+ Tracking.event(document.body.dataset.page, TRACKING_ACTION_INITIALIZE_EDITOR);
+ },
methods: {
onDismissError() {
this.submitChangesError = null;
diff --git a/app/assets/javascripts/static_site_editor/services/parse_source_file.js b/app/assets/javascripts/static_site_editor/services/parse_source_file.js
new file mode 100644
index 00000000000..f32c693411f
--- /dev/null
+++ b/app/assets/javascripts/static_site_editor/services/parse_source_file.js
@@ -0,0 +1,55 @@
+const parseSourceFile = raw => {
+ const frontMatterRegex = /(^---$[\s\S]*?^---$)/m;
+ const preGroupedRegex = /([\s\S]*?)(^---$[\s\S]*?^---$)(\s*)([\s\S]*)/m; // preFrontMatter, frontMatter, spacing, and content
+ let initial;
+ let editable;
+
+ const hasFrontMatter = source => frontMatterRegex.test(source);
+
+ const buildPayload = (source, header, spacing, body) => {
+ return { raw: source, header, spacing, body };
+ };
+
+ const parse = source => {
+ if (hasFrontMatter(source)) {
+ const match = source.match(preGroupedRegex);
+ const [, preFrontMatter, frontMatter, spacing, content] = match;
+ const header = preFrontMatter + frontMatter;
+
+ return buildPayload(source, header, spacing, content);
+ }
+
+ return buildPayload(source, '', '', source);
+ };
+
+ const computedRaw = () => `${editable.header}${editable.spacing}${editable.body}`;
+
+ const syncBody = () => {
+ /*
+ We re-parse as markdown editing could have added non-body changes (preFrontMatter, frontMatter, or spacing).
+ Re-parsing additionally gets us the desired body that was extracted from the mutated editable.raw
+ Additionally we intentionally mutate the existing editable's key values as opposed to reassigning the object itself so consumers of the potentially reactive property stay in sync.
+ */
+ Object.assign(editable, parse(editable.raw));
+ };
+
+ const syncRaw = () => {
+ editable.raw = computedRaw();
+ };
+
+ const isModifiedRaw = () => initial.raw !== editable.raw;
+ const isModifiedBody = () => initial.raw !== computedRaw();
+
+ initial = parse(raw);
+ editable = parse(raw);
+
+ return {
+ editable,
+ isModifiedRaw,
+ isModifiedBody,
+ syncRaw,
+ syncBody,
+ };
+};
+
+export default parseSourceFile;
diff --git a/app/assets/javascripts/static_site_editor/services/submit_content_changes.js b/app/assets/javascripts/static_site_editor/services/submit_content_changes.js
index 49135d2141b..fce7c1f918f 100644
--- a/app/assets/javascripts/static_site_editor/services/submit_content_changes.js
+++ b/app/assets/javascripts/static_site_editor/services/submit_content_changes.js
@@ -10,6 +10,7 @@ import {
SUBMIT_CHANGES_COMMIT_ERROR,
SUBMIT_CHANGES_MERGE_REQUEST_ERROR,
TRACKING_ACTION_CREATE_COMMIT,
+ TRACKING_ACTION_CREATE_MERGE_REQUEST,
} from '../constants';
const createBranch = (projectId, branch) =>
@@ -41,8 +42,15 @@ const commitContent = (projectId, message, branch, sourcePath, content) => {
});
};
-const createMergeRequest = (projectId, title, sourceBranch, targetBranch = DEFAULT_TARGET_BRANCH) =>
- Api.createProjectMergeRequest(
+const createMergeRequest = (
+ projectId,
+ title,
+ sourceBranch,
+ targetBranch = DEFAULT_TARGET_BRANCH,
+) => {
+ Tracking.event(document.body.dataset.page, TRACKING_ACTION_CREATE_MERGE_REQUEST);
+
+ return Api.createProjectMergeRequest(
projectId,
convertObjectPropsToSnakeCase({
title,
@@ -52,6 +60,7 @@ const createMergeRequest = (projectId, title, sourceBranch, targetBranch = DEFAU
).catch(() => {
throw new Error(SUBMIT_CHANGES_MERGE_REQUEST_ERROR);
});
+};
const submitContentChanges = ({ username, projectId, sourcePath, content }) => {
const branch = generateBranchName(username);
diff --git a/app/assets/javascripts/u2f/authenticate.js b/app/assets/javascripts/u2f/authenticate.js
deleted file mode 100644
index 6244df1180e..00000000000
--- a/app/assets/javascripts/u2f/authenticate.js
+++ /dev/null
@@ -1,107 +0,0 @@
-import $ from 'jquery';
-import { template as lodashTemplate, omit } from 'lodash';
-import importU2FLibrary from './util';
-import U2FError from './error';
-
-// Authenticate U2F (universal 2nd factor) devices for users to authenticate with.
-//
-// State Flow #1: setup -> in_progress -> authenticated -> POST to server
-// State Flow #2: setup -> in_progress -> error -> setup
-export default class U2FAuthenticate {
- constructor(container, form, u2fParams, fallbackButton, fallbackUI) {
- this.u2fUtils = null;
- this.container = container;
- this.renderAuthenticated = this.renderAuthenticated.bind(this);
- this.renderError = this.renderError.bind(this);
- this.renderInProgress = this.renderInProgress.bind(this);
- this.renderTemplate = this.renderTemplate.bind(this);
- this.authenticate = this.authenticate.bind(this);
- this.start = this.start.bind(this);
- this.appId = u2fParams.app_id;
- this.challenge = u2fParams.challenge;
- this.form = form;
- this.fallbackButton = fallbackButton;
- this.fallbackUI = fallbackUI;
- if (this.fallbackButton) {
- this.fallbackButton.addEventListener('click', this.switchToFallbackUI.bind(this));
- }
-
- // The U2F Javascript API v1.1 requires a single challenge, with
- // _no challenges per-request_. The U2F Javascript API v1.0 requires a
- // challenge per-request, which is done by copying the single challenge
- // into every request.
- //
- // In either case, we don't need the per-request challenges that the server
- // has generated, so we can remove them.
- //
- // Note: The server library fixes this behaviour in (unreleased) version 1.0.0.
- // This can be removed once we upgrade.
- // https://github.com/castle/ruby-u2f/commit/103f428071a81cd3d5f80c2e77d522d5029946a4
- this.signRequests = u2fParams.sign_requests.map(request => omit(request, 'challenge'));
-
- this.templates = {
- setup: '#js-authenticate-u2f-setup',
- inProgress: '#js-authenticate-u2f-in-progress',
- error: '#js-authenticate-u2f-error',
- authenticated: '#js-authenticate-u2f-authenticated',
- };
- }
-
- start() {
- return importU2FLibrary()
- .then(utils => {
- this.u2fUtils = utils;
- this.renderInProgress();
- })
- .catch(() => this.switchToFallbackUI());
- }
-
- authenticate() {
- return this.u2fUtils.sign(
- this.appId,
- this.challenge,
- this.signRequests,
- response => {
- if (response.errorCode) {
- const error = new U2FError(response.errorCode, 'authenticate');
- return this.renderError(error);
- }
- return this.renderAuthenticated(JSON.stringify(response));
- },
- 10,
- );
- }
-
- renderTemplate(name, params) {
- const templateString = $(this.templates[name]).html();
- const template = lodashTemplate(templateString);
- return this.container.html(template(params));
- }
-
- renderInProgress() {
- this.renderTemplate('inProgress');
- return this.authenticate();
- }
-
- renderError(error) {
- this.renderTemplate('error', {
- error_message: error.message(),
- error_code: error.errorCode,
- });
- return this.container.find('#js-u2f-try-again').on('click', this.renderInProgress);
- }
-
- renderAuthenticated(deviceResponse) {
- this.renderTemplate('authenticated');
- const container = this.container[0];
- container.querySelector('#js-device-response').value = deviceResponse;
- container.querySelector(this.form).submit();
- this.fallbackButton.classList.add('hidden');
- }
-
- switchToFallbackUI() {
- this.fallbackButton.classList.add('hidden');
- this.container[0].classList.add('hidden');
- this.fallbackUI.classList.remove('hidden');
- }
-}
diff --git a/app/assets/javascripts/u2f/register.js b/app/assets/javascripts/u2f/register.js
deleted file mode 100644
index f5a422727ad..00000000000
--- a/app/assets/javascripts/u2f/register.js
+++ /dev/null
@@ -1,94 +0,0 @@
-import $ from 'jquery';
-import { template as lodashTemplate } from 'lodash';
-import importU2FLibrary from './util';
-import U2FError from './error';
-
-// Register U2F (universal 2nd factor) devices for users to authenticate with.
-//
-// State Flow #1: setup -> in_progress -> registered -> POST to server
-// State Flow #2: setup -> in_progress -> error -> setup
-export default class U2FRegister {
- constructor(container, u2fParams) {
- this.u2fUtils = null;
- this.container = container;
- this.renderNotSupported = this.renderNotSupported.bind(this);
- this.renderRegistered = this.renderRegistered.bind(this);
- this.renderError = this.renderError.bind(this);
- this.renderInProgress = this.renderInProgress.bind(this);
- this.renderSetup = this.renderSetup.bind(this);
- this.renderTemplate = this.renderTemplate.bind(this);
- this.register = this.register.bind(this);
- this.start = this.start.bind(this);
- this.appId = u2fParams.app_id;
- this.registerRequests = u2fParams.register_requests;
- this.signRequests = u2fParams.sign_requests;
-
- this.templates = {
- notSupported: '#js-register-u2f-not-supported',
- setup: '#js-register-u2f-setup',
- inProgress: '#js-register-u2f-in-progress',
- error: '#js-register-u2f-error',
- registered: '#js-register-u2f-registered',
- };
- }
-
- start() {
- return importU2FLibrary()
- .then(utils => {
- this.u2fUtils = utils;
- this.renderSetup();
- })
- .catch(() => this.renderNotSupported());
- }
-
- register() {
- return this.u2fUtils.register(
- this.appId,
- this.registerRequests,
- this.signRequests,
- response => {
- if (response.errorCode) {
- const error = new U2FError(response.errorCode, 'register');
- return this.renderError(error);
- }
- return this.renderRegistered(JSON.stringify(response));
- },
- 10,
- );
- }
-
- renderTemplate(name, params) {
- const templateString = $(this.templates[name]).html();
- const template = lodashTemplate(templateString);
- return this.container.html(template(params));
- }
-
- renderSetup() {
- this.renderTemplate('setup');
- return this.container.find('#js-setup-u2f-device').on('click', this.renderInProgress);
- }
-
- renderInProgress() {
- this.renderTemplate('inProgress');
- return this.register();
- }
-
- renderError(error) {
- this.renderTemplate('error', {
- error_message: error.message(),
- error_code: error.errorCode,
- });
- return this.container.find('#js-u2f-try-again').on('click', this.renderSetup);
- }
-
- renderRegistered(deviceResponse) {
- this.renderTemplate('registered');
- // Prefer to do this instead of interpolating using Underscore templates
- // because of JSON escaping issues.
- return this.container.find('#js-device-response').val(deviceResponse);
- }
-
- renderNotSupported() {
- return this.renderTemplate('notSupported');
- }
-}
diff --git a/app/assets/javascripts/user_callout.js b/app/assets/javascripts/user_callout.js
index 96dfff77859..df00f38dd70 100644
--- a/app/assets/javascripts/user_callout.js
+++ b/app/assets/javascripts/user_callout.js
@@ -21,16 +21,17 @@ export default class UserCallout {
dismissCallout(e) {
const $currentTarget = $(e.currentTarget);
+ const cookieOptions = {};
+ if (!$currentTarget.hasClass('js-close-session')) {
+ cookieOptions.expires = 365;
+ }
if (this.options.setCalloutPerProject) {
- Cookies.set(this.cookieName, 'true', {
- expires: 365,
- path: this.userCalloutBody.data('projectPath'),
- });
- } else {
- Cookies.set(this.cookieName, 'true', { expires: 365 });
+ cookieOptions.path = this.userCalloutBody.data('projectPath');
}
+ Cookies.set(this.cookieName, 'true', cookieOptions);
+
if ($currentTarget.hasClass('close') || $currentTarget.hasClass('js-close')) {
this.userCalloutBody.remove();
}
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_action_button.vue b/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_action_button.vue
index 996e54a1183..7d74d5531b4 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_action_button.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_action_button.vue
@@ -64,7 +64,7 @@ export default {
:title="buttonTitle"
:loading="isLoading"
:disabled="isActionInProgress"
- :class="`btn btn-default btn-sm inline prepend-left-4 ${containerClasses}`"
+ :class="`btn btn-default btn-sm inline gl-ml-2 ${containerClasses}`"
@click="$emit('click')"
>
<span class="d-inline-flex align-items-baseline">
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_view_button.vue b/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_view_button.vue
index 5dabd9fe5fe..bce25ca20ec 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_view_button.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_view_button.vue
@@ -75,11 +75,11 @@ export default {
rel="noopener noreferrer nofollow"
class="js-deploy-url-menu-item menu-item"
>
- <strong class="str-truncated-100 append-bottom-0 d-block">
+ <strong class="str-truncated-100 gl-mb-0 d-block">
{{ slotProps.result.path }}
</strong>
- <p class="text-secondary str-truncated-100 append-bottom-0 d-block">
+ <p class="text-secondary str-truncated-100 gl-mb-0 d-block">
{{ slotProps.result.external_url }}
</p>
</gl-link>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
index 2433ba879aa..0464c4b9c15 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
@@ -117,7 +117,7 @@ export default {
:href="webIdePath"
:title="ideButtonTitle"
:class="{ disabled: !mr.canPushToSourceBranch }"
- class="btn btn-default js-web-ide d-none d-md-inline-block append-right-8"
+ class="btn btn-default js-web-ide d-none d-md-inline-block gl-mr-3"
data-placement="bottom"
tabindex="0"
role="button"
@@ -129,7 +129,7 @@ export default {
:disabled="mr.sourceBranchRemoved"
data-target="#modal_merge_info"
data-toggle="modal"
- class="btn btn-default js-check-out-branch append-right-8"
+ class="btn btn-default js-check-out-branch gl-mr-3"
type="button"
>
{{ s__('mrWidget|Check out branch') }}
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_terraform_plan.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_terraform_plan.vue
index 8313b8afb1b..2ef5e81b36b 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_terraform_plan.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_terraform_plan.vue
@@ -1,16 +1,15 @@
<script>
import { __ } from '~/locale';
-import { GlIcon, GlLoadingIcon, GlSprintf } from '@gitlab/ui';
+import { GlIcon, GlLink, GlLoadingIcon, GlSprintf } from '@gitlab/ui';
import axios from '~/lib/utils/axios_utils';
-import CiIcon from '../../vue_shared/components/ci_icon.vue';
import flash from '~/flash';
import Poll from '~/lib/utils/poll';
export default {
name: 'MRWidgetTerraformPlan',
components: {
- CiIcon,
GlIcon,
+ GlLink,
GlLoadingIcon,
GlSprintf,
},
@@ -36,17 +35,12 @@ export default {
deleteNum() {
return Number(this.plan.delete);
},
- iconStatusObj() {
- return {
- group: 'warning',
- icon: 'status_warning',
- };
- },
logUrl() {
return this.plan.job_path;
},
plan() {
- return this.plans['tfplan.json'] || {};
+ const firstPlanKey = Object.keys(this.plans)[0];
+ return this.plans[firstPlanKey] ?? {};
},
validPlanValues() {
return this.addNum + this.changeNum + this.deleteNum >= 0;
@@ -90,7 +84,7 @@ export default {
<section class="mr-widget-section">
<div class="mr-widget-body media d-flex flex-row">
<span class="append-right-default align-self-start align-self-lg-center">
- <ci-icon :status="iconStatusObj" :size="24" />
+ <gl-icon name="status_warning" :size="24" />
</span>
<div class="d-flex flex-fill flex-column flex-md-row">
@@ -125,7 +119,7 @@ export default {
</div>
<div class="terraform-mr-plan-actions">
- <a
+ <gl-link
v-if="logUrl"
:href="logUrl"
target="_blank"
@@ -137,7 +131,7 @@ export default {
>
{{ __('View full log') }}
<gl-icon name="external-link" />
- </a>
+ </gl-link>
</div>
</div>
</div>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/source_branch_removal_status.vue b/app/assets/javascripts/vue_merge_request_widget/components/source_branch_removal_status.vue
index 6aad2a26a53..a0e76b151f7 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/source_branch_removal_status.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/source_branch_removal_status.vue
@@ -14,7 +14,7 @@ export default {
</script>
<template>
- <p v-once class="mr-info-list mr-links append-bottom-0">
+ <p v-once class="mr-info-list mr-links gl-mb-0">
<span class="status-text" v-html="removesBranchText"> </span>
<i v-tooltip :title="tooltipTitle" :aria-label="tooltipTitle" class="fa fa-question-circle">
</i>
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 b1fb377e47a..c3cc30a1a6f 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
@@ -127,7 +127,7 @@ export default {
</button>
<span v-if="!rebasingError" class="bold">{{
__(
- 'Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged.',
+ 'Fast-forward merge is not possible. Rebase the source branch onto the target branch.',
)
}}</span>
<span v-else class="bold danger">{{ rebasingError }}</span>
diff --git a/app/assets/javascripts/vue_shared/components/changed_file_icon.vue b/app/assets/javascripts/vue_shared/components/changed_file_icon.vue
index 60e41a16854..7431b7e9ed4 100644
--- a/app/assets/javascripts/vue_shared/components/changed_file_icon.vue
+++ b/app/assets/javascripts/vue_shared/components/changed_file_icon.vue
@@ -1,7 +1,7 @@
<script>
import { GlTooltipDirective } from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue';
-import { getCommitIconMap } from '~/ide/utils';
+import getCommitIconMap from '~/ide/commit_icon';
import { __ } from '~/locale';
export default {
diff --git a/app/assets/javascripts/vue_shared/components/content_viewer/viewers/download_viewer.vue b/app/assets/javascripts/vue_shared/components/content_viewer/viewers/download_viewer.vue
index e80cb06edfb..47231c4ad39 100644
--- a/app/assets/javascripts/vue_shared/components/content_viewer/viewers/download_viewer.vue
+++ b/app/assets/javascripts/vue_shared/components/content_viewer/viewers/download_viewer.vue
@@ -52,7 +52,7 @@ export default {
:download="fileName"
target="_blank"
>
- <icon :size="16" name="download" class="float-left append-right-8" />
+ <icon :size="16" name="download" class="float-left gl-mr-3" />
{{ __('Download') }}
</gl-link>
</div>
diff --git a/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue b/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue
index 07748482204..ddbb474bab6 100644
--- a/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue
+++ b/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue
@@ -1,20 +1,17 @@
<script>
-import { GlDeprecatedButton, GlDropdown, GlDropdownItem, GlFormGroup } from '@gitlab/ui';
+import { GlIcon, GlDeprecatedButton, GlDropdown, GlDropdownItem, GlFormGroup } from '@gitlab/ui';
import { __, sprintf } from '~/locale';
import { convertToFixedRange, isEqualTimeRanges, findTimeRange } from '~/lib/utils/datetime_range';
-import Icon from '~/vue_shared/components/icon.vue';
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue';
import DateTimePickerInput from './date_time_picker_input.vue';
import {
defaultTimeRanges,
defaultTimeRange,
- isValidDate,
- stringToISODate,
- ISODateToString,
- truncateZerosInDateTime,
- isDateTimePickerInputValid,
+ isValidInputString,
+ inputStringToIsoDate,
+ isoDateToInputString,
} from './date_time_picker_lib';
const events = {
@@ -24,13 +21,13 @@ const events = {
export default {
components: {
- Icon,
- TooltipOnTruncate,
- DateTimePickerInput,
- GlFormGroup,
+ GlIcon,
GlDeprecatedButton,
GlDropdown,
GlDropdownItem,
+ GlFormGroup,
+ TooltipOnTruncate,
+ DateTimePickerInput,
},
props: {
value: {
@@ -48,20 +45,41 @@ export default {
required: false,
default: true,
},
+ utc: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
data() {
return {
timeRange: this.value,
- startDate: '',
- endDate: '',
+
+ /**
+ * Valid start iso date string, null if not valid value
+ */
+ startDate: null,
+ /**
+ * Invalid start date string as input by the user
+ */
+ startFallbackVal: '',
+
+ /**
+ * Valid end iso date string, null if not valid value
+ */
+ endDate: null,
+ /**
+ * Invalid end date string as input by the user
+ */
+ endFallbackVal: '',
};
},
computed: {
startInputValid() {
- return isValidDate(this.startDate);
+ return isValidInputString(this.startDate);
},
endInputValid() {
- return isValidDate(this.endDate);
+ return isValidInputString(this.endDate);
},
isValid() {
return this.startInputValid && this.endInputValid;
@@ -69,21 +87,31 @@ export default {
startInput: {
get() {
- return this.startInputValid ? this.formatDate(this.startDate) : this.startDate;
+ return this.dateToInput(this.startDate) || this.startFallbackVal;
},
set(val) {
- // Attempt to set a formatted date if possible
- this.startDate = isDateTimePickerInputValid(val) ? stringToISODate(val) : val;
+ try {
+ this.startDate = this.inputToDate(val);
+ this.startFallbackVal = null;
+ } catch (e) {
+ this.startDate = null;
+ this.startFallbackVal = val;
+ }
this.timeRange = null;
},
},
endInput: {
get() {
- return this.endInputValid ? this.formatDate(this.endDate) : this.endDate;
+ return this.dateToInput(this.endDate) || this.endFallbackVal;
},
set(val) {
- // Attempt to set a formatted date if possible
- this.endDate = isDateTimePickerInputValid(val) ? stringToISODate(val) : val;
+ try {
+ this.endDate = this.inputToDate(val);
+ this.endFallbackVal = null;
+ } catch (e) {
+ this.endDate = null;
+ this.endFallbackVal = val;
+ }
this.timeRange = null;
},
},
@@ -96,10 +124,10 @@ export default {
}
const { start, end } = convertToFixedRange(this.value);
- if (isValidDate(start) && isValidDate(end)) {
+ if (isValidInputString(start) && isValidInputString(end)) {
return sprintf(__('%{start} to %{end}'), {
- start: this.formatDate(start),
- end: this.formatDate(end),
+ start: this.stripZerosInDateTime(this.dateToInput(start)),
+ end: this.stripZerosInDateTime(this.dateToInput(end)),
});
}
} catch {
@@ -107,6 +135,13 @@ export default {
}
return '';
},
+
+ customLabel() {
+ if (this.utc) {
+ return __('Custom range (UTC)');
+ }
+ return __('Custom range');
+ },
},
watch: {
value(newValue) {
@@ -132,8 +167,17 @@ export default {
}
},
methods: {
- formatDate(date) {
- return truncateZerosInDateTime(ISODateToString(date));
+ dateToInput(date) {
+ if (date === null) {
+ return null;
+ }
+ return isoDateToInputString(date, this.utc);
+ },
+ inputToDate(value) {
+ return inputStringToIsoDate(value, this.utc);
+ },
+ stripZerosInDateTime(str = '') {
+ return str.replace(' 00:00:00', '');
},
closeDropdown() {
this.$refs.dropdown.hide();
@@ -169,10 +213,16 @@ export default {
menu-class="date-time-picker-menu"
toggle-class="date-time-picker-toggle text-truncate"
>
+ <template #button-content>
+ <span class="gl-flex-grow-1 text-truncate">{{ timeWindowText }}</span>
+ <span v-if="utc" class="text-muted gl-font-weight-bold gl-font-sm">{{ __('UTC') }}</span>
+ <gl-icon class="gl-dropdown-caret" name="chevron-down" aria-hidden="true" />
+ </template>
+
<div class="d-flex justify-content-between gl-p-2-deprecated-no-really-do-not-use-me">
<gl-form-group
v-if="customEnabled"
- :label="__('Custom range')"
+ :label="customLabel"
label-for="custom-from-time"
label-class="gl-pb-1-deprecated-no-really-do-not-use-me"
class="custom-time-range-form-group col-md-7 gl-pl-1-deprecated-no-really-do-not-use-me gl-pr-0 m-0"
@@ -214,7 +264,7 @@ export default {
active-class="active"
@click="setQuickRange(option)"
>
- <icon
+ <gl-icon
name="mobile-issue-close"
class="align-bottom"
:class="{ invisible: !isOptionActive(option) }"
diff --git a/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker_input.vue b/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker_input.vue
index f19f8bd46b3..32a24844d71 100644
--- a/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker_input.vue
+++ b/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker_input.vue
@@ -6,9 +6,9 @@ import { dateFormats } from './date_time_picker_lib';
const inputGroupText = {
invalidFeedback: sprintf(__('Format: %{dateFormat}'), {
- dateFormat: dateFormats.stringDate,
+ dateFormat: dateFormats.inputFormat,
}),
- placeholder: dateFormats.stringDate,
+ placeholder: dateFormats.inputFormat,
};
export default {
diff --git a/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker_lib.js b/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker_lib.js
index 673d981cf07..40708453d79 100644
--- a/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker_lib.js
+++ b/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker_lib.js
@@ -2,12 +2,6 @@ import dateformat from 'dateformat';
import { __ } from '~/locale';
/**
- * Valid strings for this regex are
- * 2019-10-01 and 2019-10-01 01:02:03
- */
-const dateTimePickerRegex = /^(\d{4})-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])(?: (0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]))?$/;
-
-/**
* Default time ranges for the date picker.
* @see app/assets/javascripts/lib/utils/datetime_range.js
*/
@@ -34,23 +28,33 @@ export const defaultTimeRanges = [
export const defaultTimeRange = defaultTimeRanges.find(tr => tr.default);
export const dateFormats = {
- ISODate: "yyyy-mm-dd'T'HH:MM:ss'Z'",
- stringDate: 'yyyy-mm-dd HH:MM:ss',
+ /**
+ * Format used by users to input dates
+ *
+ * Note: Should be a format that can be parsed by Date.parse.
+ */
+ inputFormat: 'yyyy-mm-dd HH:MM:ss',
+ /**
+ * Format used to strip timezone from inputs
+ */
+ stripTimezoneFormat: "yyyy-mm-dd'T'HH:MM:ss'Z'",
};
/**
- * The URL params start and end need to be validated
- * before passing them down to other components.
+ * Returns true if the date can be parsed succesfully after
+ * being typed by a user.
*
- * @param {string} dateString
- * @returns true if the string is a valid date, false otherwise
+ * It allows some ambiguity so validation is not strict.
+ *
+ * @param {string} value - Value as typed by the user
+ * @returns true if the value can be parsed as a valid date, false otherwise
*/
-export const isValidDate = dateString => {
+export const isValidInputString = value => {
try {
// dateformat throws error that can be caught.
// This is better than using `new Date()`
- if (dateString && dateString.trim()) {
- dateformat(dateString, 'isoDateTime');
+ if (value && value.trim()) {
+ dateformat(value, 'isoDateTime');
return true;
}
return false;
@@ -60,25 +64,30 @@ export const isValidDate = dateString => {
};
/**
- * Convert the input in Time picker component to ISO date.
+ * Convert the input in time picker component to an ISO date.
*
- * @param {string} val
- * @returns {string}
+ * @param {string} value
+ * @param {Boolean} utc - If true, it forces the date to by
+ * formatted using UTC format, ignoring the local time.
+ * @returns {Date}
*/
-export const stringToISODate = val =>
- dateformat(new Date(val.replace(/-/g, '/')), dateFormats.ISODate, true);
+export const inputStringToIsoDate = (value, utc = false) => {
+ let date = new Date(value);
+ if (utc) {
+ // Forces date to be interpreted as UTC by stripping the timezone
+ // by formatting to a string with 'Z' and skipping timezone
+ date = dateformat(date, dateFormats.stripTimezoneFormat);
+ }
+ return dateformat(date, 'isoUtcDateTime');
+};
/**
- * Convert the ISO date received from the URL to string
- * for the Time picker component.
+ * Converts a iso date string to a formatted string for the Time picker component.
*
- * @param {Date} date
+ * @param {String} ISO Formatted date
* @returns {string}
*/
-export const ISODateToString = date => dateformat(date, dateFormats.stringDate);
-
-export const truncateZerosInDateTime = datetime => datetime.replace(' 00:00:00', '');
-
-export const isDateTimePickerInputValid = val => dateTimePickerRegex.test(val);
+export const isoDateToInputString = (date, utc = false) =>
+ dateformat(date, dateFormats.inputFormat, utc);
export default {};
diff --git a/app/assets/javascripts/vue_shared/components/diff_viewer/diff_viewer.vue b/app/assets/javascripts/vue_shared/components/diff_viewer/diff_viewer.vue
index bf3c3666300..a2fe19f9672 100644
--- a/app/assets/javascripts/vue_shared/components/diff_viewer/diff_viewer.vue
+++ b/app/assets/javascripts/vue_shared/components/diff_viewer/diff_viewer.vue
@@ -7,6 +7,10 @@ import ModeChanged from './viewers/mode_changed.vue';
export default {
props: {
+ diffFile: {
+ type: Object,
+ required: true,
+ },
diffMode: {
type: String,
required: true,
@@ -92,6 +96,7 @@ export default {
<div v-if="viewer" class="diff-file preview-container">
<component
:is="viewer"
+ :diff-file="diffFile"
:diff-mode="diffMode"
:new-path="fullNewPath"
:old-path="fullOldPath"
diff --git a/app/assets/javascripts/vue_shared/components/diff_viewer/viewers/renamed.vue b/app/assets/javascripts/vue_shared/components/diff_viewer/viewers/renamed.vue
index 5c1ea59b471..eba6dd4d14c 100644
--- a/app/assets/javascripts/vue_shared/components/diff_viewer/viewers/renamed.vue
+++ b/app/assets/javascripts/vue_shared/components/diff_viewer/viewers/renamed.vue
@@ -1,3 +1,108 @@
+<script>
+import { mapActions } from 'vuex';
+import { GlAlert, GlLink, GlLoadingIcon, GlSprintf } from '@gitlab/ui';
+
+import { __ } from '~/locale';
+import {
+ TRANSITION_LOAD_START,
+ TRANSITION_LOAD_ERROR,
+ TRANSITION_LOAD_SUCCEED,
+ TRANSITION_ACKNOWLEDGE_ERROR,
+ STATE_IDLING,
+ STATE_LOADING,
+ STATE_ERRORED,
+ RENAMED_DIFF_TRANSITIONS,
+} from '~/diffs/constants';
+import { truncateSha } from '~/lib/utils/text_utility';
+
+export default {
+ STATE_LOADING,
+ STATE_ERRORED,
+ TRANSITIONS: RENAMED_DIFF_TRANSITIONS,
+ uiText: {
+ showLink: __('Show file contents'),
+ commitLink: __('View file @ %{commitSha}'),
+ description: __('File renamed with no changes.'),
+ loadError: __('Unable to load file contents. Try again later.'),
+ },
+ components: {
+ GlAlert,
+ GlLink,
+ GlLoadingIcon,
+ GlSprintf,
+ },
+ props: {
+ diffFile: {
+ type: Object,
+ required: true,
+ },
+ },
+ data: () => ({
+ state: STATE_IDLING,
+ }),
+ computed: {
+ shortSha() {
+ return truncateSha(this.diffFile.content_sha);
+ },
+ canLoadFullDiff() {
+ return this.diffFile.alternate_viewer.name === 'text';
+ },
+ },
+ methods: {
+ ...mapActions('diffs', ['switchToFullDiffFromRenamedFile']),
+ transition(transitionEvent) {
+ const key = `${this.state}:${transitionEvent}`;
+
+ if (this.$options.TRANSITIONS[key]) {
+ this.state = this.$options.TRANSITIONS[key];
+ }
+ },
+ is(state) {
+ return this.state === state;
+ },
+ switchToFull() {
+ this.transition(TRANSITION_LOAD_START);
+
+ this.switchToFullDiffFromRenamedFile({ diffFile: this.diffFile })
+ .then(() => {
+ this.transition(TRANSITION_LOAD_SUCCEED);
+ })
+ .catch(() => {
+ this.transition(TRANSITION_LOAD_ERROR);
+ });
+ },
+ clickLink(event) {
+ if (this.canLoadFullDiff) {
+ event.preventDefault();
+
+ this.switchToFull();
+ }
+ },
+ dismissError() {
+ this.transition(TRANSITION_ACKNOWLEDGE_ERROR);
+ },
+ },
+};
+</script>
+
<template>
- <div class="nothing-here-block">{{ __('File moved') }}</div>
+ <div class="nothing-here-block">
+ <gl-loading-icon v-if="is($options.STATE_LOADING)" />
+ <template v-else>
+ <gl-alert
+ v-show="is($options.STATE_ERRORED)"
+ class="gl-mb-5 gl-text-left"
+ variant="danger"
+ @dismiss="dismissError"
+ >{{ $options.uiText.loadError }}</gl-alert
+ >
+ <span test-id="plaintext">{{ $options.uiText.description }}</span>
+ <gl-link :href="diffFile.view_path" @click="clickLink">
+ <span v-if="canLoadFullDiff">{{ $options.uiText.showLink }}</span>
+ <gl-sprintf v-else :message="$options.uiText.commitLink">
+ <template #commitSha>{{ shortSha }}</template>
+ </gl-sprintf>
+ </gl-link>
+ </template>
+ </div>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/file_finder/index.vue b/app/assets/javascripts/vue_shared/components/file_finder/index.vue
index b57455adaad..9f6f3d2d63a 100644
--- a/app/assets/javascripts/vue_shared/components/file_finder/index.vue
+++ b/app/assets/javascripts/vue_shared/components/file_finder/index.vue
@@ -261,7 +261,7 @@ export default {
</li>
</template>
<li v-else class="dropdown-menu-empty-item">
- <div class="append-right-default prepend-left-default prepend-top-8 append-bottom-8">
+ <div class="append-right-default prepend-left-default gl-mt-3 gl-mb-3">
<template v-if="loading">
{{ __('Loading...') }}
</template>
diff --git a/app/assets/javascripts/vue_shared/components/file_finder/item.vue b/app/assets/javascripts/vue_shared/components/file_finder/item.vue
index 018e3a84c39..590501a975a 100644
--- a/app/assets/javascripts/vue_shared/components/file_finder/item.vue
+++ b/app/assets/javascripts/vue_shared/components/file_finder/item.vue
@@ -75,12 +75,8 @@ export default {
@mouseover="mouseOverRow"
@mousemove="mouseMove"
>
- <file-icon
- :file-name="file.name"
- :size="16"
- css-classes="diff-file-changed-icon append-right-8"
- />
- <span class="diff-changed-file-content append-right-8">
+ <file-icon :file-name="file.name" :size="16" css-classes="diff-file-changed-icon gl-mr-3" />
+ <span class="diff-changed-file-content gl-mr-3">
<strong class="diff-changed-file-name">
<span
v-for="(char, charIndex) in file.name.split('')"
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
new file mode 100644
index 00000000000..6665a5754b3
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/constants.js
@@ -0,0 +1,8 @@
+export const ANY_AUTHOR = 'Any';
+
+export const DEBOUNCE_DELAY = 200;
+
+export const SortDirection = {
+ descending: 'descending',
+ ascending: 'ascending',
+};
diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue b/app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue
new file mode 100644
index 00000000000..a858ffdbed5
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue
@@ -0,0 +1,253 @@
+<script>
+import {
+ GlFilteredSearch,
+ GlButtonGroup,
+ GlButton,
+ GlNewDropdown as GlDropdown,
+ GlNewDropdownItem as GlDropdownItem,
+ GlTooltipDirective,
+} from '@gitlab/ui';
+
+import { __ } from '~/locale';
+import createFlash from '~/flash';
+
+import RecentSearchesStore from '~/filtered_search/stores/recent_searches_store';
+import RecentSearchesService from '~/filtered_search/services/recent_searches_service';
+import RecentSearchesStorageKeys from 'ee_else_ce/filtered_search/recent_searches_storage_keys';
+
+import { SortDirection } from './constants';
+
+export default {
+ components: {
+ GlFilteredSearch,
+ GlButtonGroup,
+ GlButton,
+ GlDropdown,
+ GlDropdownItem,
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
+ props: {
+ namespace: {
+ type: String,
+ required: true,
+ },
+ recentSearchesStorageKey: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ tokens: {
+ type: Array,
+ required: true,
+ },
+ sortOptions: {
+ type: Array,
+ required: true,
+ },
+ initialFilterValue: {
+ type: Array,
+ required: false,
+ default: () => [],
+ },
+ initialSortBy: {
+ type: String,
+ required: false,
+ default: '',
+ validator: value => value === '' || /(_desc)|(_asc)/g.test(value),
+ },
+ searchInputPlaceholder: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ let selectedSortOption = this.sortOptions[0].sortDirection.descending;
+ let selectedSortDirection = SortDirection.descending;
+
+ // Extract correct sortBy value based on initialSortBy
+ if (this.initialSortBy) {
+ selectedSortOption = this.sortOptions
+ .filter(
+ sortBy =>
+ sortBy.sortDirection.ascending === this.initialSortBy ||
+ sortBy.sortDirection.descending === this.initialSortBy,
+ )
+ .pop();
+ selectedSortDirection = this.initialSortBy.endsWith('_desc')
+ ? SortDirection.descending
+ : SortDirection.ascending;
+ }
+
+ return {
+ initialRender: true,
+ recentSearchesPromise: null,
+ filterValue: this.initialFilterValue,
+ selectedSortOption,
+ selectedSortDirection,
+ };
+ },
+ computed: {
+ tokenSymbols() {
+ return this.tokens.reduce(
+ (tokenSymbols, token) => ({
+ ...tokenSymbols,
+ [token.type]: token.symbol,
+ }),
+ {},
+ );
+ },
+ sortDirectionIcon() {
+ return this.selectedSortDirection === SortDirection.ascending
+ ? 'sort-lowest'
+ : 'sort-highest';
+ },
+ sortDirectionTooltip() {
+ return this.selectedSortDirection === SortDirection.ascending
+ ? __('Sort direction: Ascending')
+ : __('Sort direction: Descending');
+ },
+ },
+ watch: {
+ /**
+ * GlFilteredSearch currently doesn't emit any event when
+ * search field is cleared, but we still want our parent
+ * component to know that filters were cleared and do
+ * necessary data refetch, so this watcher is basically
+ * a dirty hack/workaround to identify if filter input
+ * was cleared. :(
+ */
+ filterValue(value) {
+ const [firstVal] = value;
+ if (
+ !this.initialRender &&
+ value.length === 1 &&
+ firstVal.type === 'filtered-search-term' &&
+ !firstVal.value.data
+ ) {
+ this.$emit('onFilter', []);
+ }
+
+ // Set initial render flag to false
+ // as we don't want to emit event
+ // on initial load when value is empty already.
+ this.initialRender = false;
+ },
+ },
+ created() {
+ if (this.recentSearchesStorageKey) this.setupRecentSearch();
+ },
+ methods: {
+ /**
+ * Initialize service and store instances for
+ * getting Recent Search functional.
+ */
+ setupRecentSearch() {
+ this.recentSearchesService = new RecentSearchesService(
+ `${this.namespace}-${RecentSearchesStorageKeys[this.recentSearchesStorageKey]}`,
+ );
+
+ this.recentSearchesStore = new RecentSearchesStore({
+ isLocalStorageAvailable: RecentSearchesService.isAvailable(),
+ allowedKeys: this.tokens.map(token => token.type),
+ });
+
+ this.recentSearchesPromise = this.recentSearchesService
+ .fetch()
+ .catch(error => {
+ if (error.name === 'RecentSearchesServiceError') return undefined;
+
+ createFlash(__('An error occurred while parsing recent searches'));
+
+ // Gracefully fail to empty array
+ return [];
+ })
+ .then(searches => {
+ if (!searches) return;
+
+ // Put any searches that may have come in before
+ // we fetched the saved searches ahead of the already saved ones
+ const resultantSearches = this.recentSearchesStore.setRecentSearches(
+ this.recentSearchesStore.state.recentSearches.concat(searches),
+ );
+ this.recentSearchesService.save(resultantSearches);
+ });
+ },
+ getRecentSearches() {
+ return this.recentSearchesStore?.state.recentSearches;
+ },
+ handleSortOptionClick(sortBy) {
+ this.selectedSortOption = sortBy;
+ this.$emit('onSort', sortBy.sortDirection[this.selectedSortDirection]);
+ },
+ handleSortDirectionClick() {
+ this.selectedSortDirection =
+ this.selectedSortDirection === SortDirection.ascending
+ ? SortDirection.descending
+ : SortDirection.ascending;
+ this.$emit('onSort', this.selectedSortOption.sortDirection[this.selectedSortDirection]);
+ },
+ handleFilterSubmit(filters) {
+ if (this.recentSearchesStorageKey) {
+ this.recentSearchesPromise
+ .then(() => {
+ if (filters.length) {
+ const searchTokens = filters.map(filter => {
+ // check filter was plain text search
+ if (typeof filter === 'string') {
+ return filter;
+ }
+ // filter was a token.
+ return `${filter.type}:${filter.value.operator}${this.tokenSymbols[filter.type]}${
+ filter.value.data
+ }`;
+ });
+
+ const resultantSearches = this.recentSearchesStore.addRecentSearch(
+ searchTokens.join(' '),
+ );
+ this.recentSearchesService.save(resultantSearches);
+ }
+ })
+ .catch(() => {
+ // https://gitlab.com/gitlab-org/gitlab-foss/issues/30821
+ });
+ }
+ this.$emit('onFilter', filters);
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="vue-filtered-search-bar-container d-md-flex">
+ <gl-filtered-search
+ v-model="filterValue"
+ :placeholder="searchInputPlaceholder"
+ :available-tokens="tokens"
+ :history-items="getRecentSearches()"
+ class="flex-grow-1"
+ @submit="handleFilterSubmit"
+ />
+ <gl-button-group class="sort-dropdown-container d-flex">
+ <gl-dropdown :text="selectedSortOption.title" :right="true" class="w-100">
+ <gl-dropdown-item
+ v-for="sortBy in sortOptions"
+ :key="sortBy.id"
+ :is-check-item="true"
+ :is-checked="sortBy.id === selectedSortOption.id"
+ @click="handleSortOptionClick(sortBy)"
+ >{{ sortBy.title }}</gl-dropdown-item
+ >
+ </gl-dropdown>
+ <gl-button
+ v-gl-tooltip
+ :title="sortDirectionTooltip"
+ :icon="sortDirectionIcon"
+ class="flex-shrink-1"
+ @click="handleSortDirectionClick"
+ />
+ </gl-button-group>
+ </div>
+</template>
diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/author_token.vue b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/author_token.vue
new file mode 100644
index 00000000000..412bfa5aa7f
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/author_token.vue
@@ -0,0 +1,114 @@
+<script>
+import {
+ GlFilteredSearchToken,
+ GlAvatar,
+ GlFilteredSearchSuggestion,
+ GlDropdownDivider,
+ GlLoadingIcon,
+} from '@gitlab/ui';
+import { debounce } from 'lodash';
+
+import createFlash from '~/flash';
+import { __ } from '~/locale';
+
+import { ANY_AUTHOR, DEBOUNCE_DELAY } from '../constants';
+
+export default {
+ anyAuthor: ANY_AUTHOR,
+ components: {
+ GlFilteredSearchToken,
+ GlAvatar,
+ GlFilteredSearchSuggestion,
+ GlDropdownDivider,
+ GlLoadingIcon,
+ },
+ props: {
+ config: {
+ type: Object,
+ required: true,
+ },
+ value: {
+ type: Object,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ authors: this.config.initialAuthors || [],
+ loading: true,
+ };
+ },
+ computed: {
+ currentValue() {
+ return this.value.data.toLowerCase();
+ },
+ activeAuthor() {
+ return this.authors.find(author => author.username.toLowerCase() === this.currentValue);
+ },
+ },
+ methods: {
+ fetchAuthorBySearchTerm(searchTerm) {
+ const fetchPromise = this.config.fetchPath
+ ? this.config.fetchAuthors(this.config.fetchPath, searchTerm)
+ : this.config.fetchAuthors(searchTerm);
+
+ fetchPromise
+ .then(res => {
+ // We'd want to avoid doing this check but
+ // users.json and /groups/:id/members & /projects/:id/users
+ // return response differently.
+ this.authors = Array.isArray(res) ? res : res.data;
+ })
+ .catch(() => createFlash(__('There was a problem fetching users.')))
+ .finally(() => {
+ this.loading = false;
+ });
+ },
+ searchAuthors: debounce(function debouncedSearch({ data }) {
+ this.fetchAuthorBySearchTerm(data);
+ }, DEBOUNCE_DELAY),
+ },
+};
+</script>
+
+<template>
+ <gl-filtered-search-token
+ :config="config"
+ v-bind="{ ...$props, ...$attrs }"
+ v-on="$listeners"
+ @input="searchAuthors"
+ >
+ <template #view="{ inputValue }">
+ <gl-avatar
+ v-if="activeAuthor"
+ :size="16"
+ :src="activeAuthor.avatar_url"
+ shape="circle"
+ class="gl-mr-2"
+ />
+ <span>{{ activeAuthor ? activeAuthor.name : inputValue }}</span>
+ </template>
+ <template #suggestions>
+ <gl-filtered-search-suggestion :value="$options.anyAuthor">{{
+ __('Any')
+ }}</gl-filtered-search-suggestion>
+ <gl-dropdown-divider />
+ <gl-loading-icon v-if="loading" />
+ <template v-else>
+ <gl-filtered-search-suggestion
+ v-for="author in authors"
+ :key="author.username"
+ :value="author.username"
+ >
+ <div class="d-flex">
+ <gl-avatar :size="32" :src="author.avatar_url" />
+ <div>
+ <div>{{ author.name }}</div>
+ <div>@{{ author.username }}</div>
+ </div>
+ </div>
+ </gl-filtered-search-suggestion>
+ </template>
+ </template>
+ </gl-filtered-search-token>
+</template>
diff --git a/app/assets/javascripts/vue_shared/components/gl_mentions.vue b/app/assets/javascripts/vue_shared/components/gl_mentions.vue
index 508f43afe61..a7fba5e760b 100644
--- a/app/assets/javascripts/vue_shared/components/gl_mentions.vue
+++ b/app/assets/javascripts/vue_shared/components/gl_mentions.vue
@@ -1,6 +1,5 @@
<script>
-import escape from 'lodash/escape';
-import sanitize from 'sanitize-html';
+import { escape } from 'lodash';
import Tribute from 'tributejs';
import axios from '~/lib/utils/axios_utils';
import { spriteIcon } from '~/lib/utils/common_utils';
@@ -11,11 +10,11 @@ import { spriteIcon } from '~/lib/utils/common_utils';
* @param original An object from the array returned from the `autocomplete_sources/members` API
* @returns {string} An HTML template
*/
-function createMenuItemTemplate({ original }) {
+function menuItemTemplate({ original }) {
const rectAvatarClass = original.type === 'Group' ? 'rect-avatar' : '';
const avatarClasses = `avatar avatar-inline center s26 ${rectAvatarClass}
- align-items-center d-inline-flex justify-content-center`;
+ gl-display-inline-flex gl-align-items-center gl-justify-content-center`;
const avatarTag = original.avatar_url
? `<img
@@ -24,42 +23,20 @@ function createMenuItemTemplate({ original }) {
class="${avatarClasses}"/>`
: `<div class="${avatarClasses}">${original.username.charAt(0).toUpperCase()}</div>`;
- const name = escape(sanitize(original.name));
+ const name = escape(original.name);
const count = original.count && !original.mentionsDisabled ? ` (${original.count})` : '';
const icon = original.mentionsDisabled
- ? spriteIcon('notifications-off', 's16 vertical-align-middle prepend-left-5')
+ ? spriteIcon('notifications-off', 's16 gl-vertical-align-middle gl-ml-3')
: '';
return `${avatarTag}
${original.username}
- <small class="small font-weight-normal gl-reset-color">${name}${count}</small>
+ <small class="gl-text-small gl-font-weight-normal gl-reset-color">${name}${count}</small>
${icon}`;
}
-/**
- * Creates the list of users to show in the mentions dropdown.
- *
- * @param inputText The text entered by the user in the mentions input field
- * @param processValues Callback function to set the list of users to show in the mentions dropdown
- */
-function getMembers(inputText, processValues) {
- if (this.members) {
- processValues(this.members);
- } else if (this.dataSources.members) {
- axios
- .get(this.dataSources.members)
- .then(response => {
- this.members = response.data;
- processValues(response.data);
- })
- .catch(() => {});
- } else {
- processValues([]);
- }
-}
-
export default {
name: 'GlMentions',
props: {
@@ -72,30 +49,49 @@ export default {
data() {
return {
members: undefined,
- options: {
- trigger: '@',
- fillAttr: 'username',
- lookup(value) {
- return value.name + value.username;
- },
- menuItemTemplate: createMenuItemTemplate.bind(this),
- values: getMembers.bind(this),
- },
};
},
mounted() {
+ this.tribute = new Tribute({
+ trigger: '@',
+ fillAttr: 'username',
+ lookup: value => value.name + value.username,
+ menuItemTemplate,
+ values: this.getMembers,
+ });
+
const input = this.$slots.default[0].elm;
- this.tribute = new Tribute(this.options);
this.tribute.attach(input);
},
beforeDestroy() {
const input = this.$slots.default[0].elm;
- if (this.tribute) {
- this.tribute.detach(input);
- }
+ this.tribute.detach(input);
+ },
+ methods: {
+ /**
+ * Creates the list of users to show in the mentions dropdown.
+ *
+ * @param inputText - The text entered by the user in the mentions input field
+ * @param processValues - Callback function to set the list of users to show in the mentions dropdown
+ */
+ getMembers(inputText, processValues) {
+ if (this.members) {
+ processValues(this.members);
+ } else if (this.dataSources.members) {
+ axios
+ .get(this.dataSources.members)
+ .then(response => {
+ this.members = response.data;
+ processValues(response.data);
+ })
+ .catch(() => {});
+ } else {
+ processValues([]);
+ }
+ },
},
- render(h) {
- return h('div', this.$slots.default);
+ render(createElement) {
+ return createElement('div', this.$slots.default);
},
};
</script>
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 4f1b1c758b2..63de1e009fd 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
@@ -85,7 +85,7 @@ export default {
class="confidential-icon append-right-4 align-self-baseline align-self-md-auto mt-xl-0"
:aria-label="__('Confidential')"
/>
- <a :href="computedPath" class="sortable-link">{{ title }}</a>
+ <a :href="computedPath" class="sortable-link gl-font-weight-normal">{{ title }}</a>
</div>
<!-- Info area: meta, path, and assignees -->
diff --git a/app/assets/javascripts/vue_shared/components/markdown/field.vue b/app/assets/javascripts/vue_shared/components/markdown/field.vue
index 8007ccb91d5..0e05f4a4622 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/field.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/field.vue
@@ -134,7 +134,7 @@ export default {
addMultipleToDiscussionWarning() {
return sprintf(
__(
- '%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution.',
+ '%{icon}You are about to add %{usersTag} people to the discussion. They will all receive a notification.',
),
{
icon: '<i class="fa fa-exclamation-triangle" aria-hidden="true"></i>',
@@ -245,11 +245,11 @@ export default {
<div class="zen-backdrop">
<slot name="textarea"></slot>
<a
- class="zen-control zen-control-leave js-zen-leave"
+ class="zen-control zen-control-leave js-zen-leave gl-text-gray-700"
href="#"
- :aria-label="__('Enter zen mode')"
+ :aria-label="__('Leave zen mode')"
>
- <icon :size="32" name="screen-normal" />
+ <icon :size="16" name="screen-normal" />
</a>
<markdown-toolbar
:markdown-docs-path="markdownDocsPath"
diff --git a/app/assets/javascripts/vue_shared/components/markdown/header.vue b/app/assets/javascripts/vue_shared/components/markdown/header.vue
index 665637f3b9e..aa1abb5adb6 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/header.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/header.vue
@@ -158,7 +158,7 @@ export default {
<div class="d-inline-block ml-md-2 ml-0">
<toolbar-button
:prepend="true"
- tag="* "
+ tag="- "
:button-title="__('Add a bullet list')"
icon="list-bulleted"
/>
@@ -170,7 +170,7 @@ export default {
/>
<toolbar-button
:prepend="true"
- tag="* [ ] "
+ tag="- [ ] "
:button-title="__('Add a task list')"
icon="list-task"
/>
diff --git a/app/assets/javascripts/vue_shared/components/markdown/suggestion_diff.vue b/app/assets/javascripts/vue_shared/components/markdown/suggestion_diff.vue
index a7cd292e01d..6dac448d5de 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/suggestion_diff.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/suggestion_diff.vue
@@ -13,6 +13,11 @@ export default {
type: Object,
required: true,
},
+ batchSuggestionsInfo: {
+ type: Array,
+ required: false,
+ default: () => [],
+ },
disabled: {
type: Boolean,
required: false,
@@ -24,6 +29,14 @@ export default {
},
},
computed: {
+ batchSuggestionsCount() {
+ return this.batchSuggestionsInfo.length;
+ },
+ isBatched() {
+ return Boolean(
+ this.batchSuggestionsInfo.find(({ suggestionId }) => suggestionId === this.suggestion.id),
+ );
+ },
lines() {
return selectDiffLines(this.suggestion.diff_lines);
},
@@ -32,6 +45,15 @@ export default {
applySuggestion(callback) {
this.$emit('apply', { suggestionId: this.suggestion.id, callback });
},
+ applySuggestionBatch() {
+ this.$emit('applyBatch');
+ },
+ addSuggestionToBatch() {
+ this.$emit('addToBatch', this.suggestion.id);
+ },
+ removeSuggestionFromBatch() {
+ this.$emit('removeFromBatch', this.suggestion.id);
+ },
},
};
</script>
@@ -42,8 +64,14 @@ export default {
class="qa-suggestion-diff-header js-suggestion-diff-header"
:can-apply="suggestion.appliable && suggestion.current_user.can_apply && !disabled"
:is-applied="suggestion.applied"
+ :is-batched="isBatched"
+ :is-applying-batch="suggestion.is_applying_batch"
+ :batch-suggestions-count="batchSuggestionsCount"
:help-page-path="helpPagePath"
@apply="applySuggestion"
+ @applyBatch="applySuggestionBatch"
+ @addToBatch="addSuggestionToBatch"
+ @removeFromBatch="removeSuggestionFromBatch"
/>
<table class="mb-3 md-suggestion-diff js-syntax-highlight code">
<tbody>
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 af438ce5619..e26ff51e01e 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
@@ -1,11 +1,19 @@
<script>
import { GlDeprecatedButton, GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue';
+import { __ } from '~/locale';
+import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
export default {
components: { Icon, GlDeprecatedButton, GlLoadingIcon },
directives: { 'gl-tooltip': GlTooltipDirective },
+ mixins: [glFeatureFlagsMixin()],
props: {
+ batchSuggestionsCount: {
+ type: Number,
+ required: false,
+ default: 0,
+ },
canApply: {
type: Boolean,
required: false,
@@ -16,6 +24,16 @@ export default {
required: true,
default: false,
},
+ isBatched: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ isApplyingBatch: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
helpPagePath: {
type: String,
required: true,
@@ -23,17 +41,54 @@ export default {
},
data() {
return {
- isApplying: false,
+ isApplyingSingle: false,
};
},
+ computed: {
+ canBeBatched() {
+ return Boolean(this.glFeatures.batchSuggestions);
+ },
+ isApplying() {
+ return this.isApplyingSingle || this.isApplyingBatch;
+ },
+ tooltipMessage() {
+ return this.canApply
+ ? __('This also resolves the discussion')
+ : __("Can't apply as this line has changed or the suggestion already matches its content.");
+ },
+ tooltipMessageBatch() {
+ return !this.canBeBatched
+ ? __("Suggestions that change line count can't be added to batches, yet.")
+ : this.tooltipMessage;
+ },
+ isDisableButton() {
+ return this.isApplying || !this.canApply;
+ },
+ applyingSuggestionsMessage() {
+ if (this.isApplyingSingle || this.batchSuggestionsCount < 2) {
+ return __('Applying suggestion...');
+ }
+ return __('Applying suggestions...');
+ },
+ },
methods: {
applySuggestion() {
if (!this.canApply) return;
- this.isApplying = true;
+ this.isApplyingSingle = true;
this.$emit('apply', this.applySuggestionCallback);
},
applySuggestionCallback() {
- this.isApplying = false;
+ this.isApplyingSingle = false;
+ },
+ applySuggestionBatch() {
+ if (!this.canApply) return;
+ this.$emit('applyBatch');
+ },
+ addSuggestionToBatch() {
+ this.$emit('addToBatch');
+ },
+ removeSuggestionFromBatch() {
+ this.$emit('removeFromBatch');
},
},
};
@@ -47,20 +102,52 @@ export default {
<icon name="question-o" css-classes="link-highlight" />
</a>
</div>
- <span v-if="isApplied" class="badge badge-success">{{ __('Applied') }}</span>
- <div v-if="isApplying" class="d-flex align-items-center text-secondary">
+ <div v-if="isApplied" class="badge badge-success">{{ __('Applied') }}</div>
+ <div v-else-if="isApplying" class="d-flex align-items-center text-secondary">
<gl-loading-icon class="d-flex-center mr-2" />
- <span>{{ __('Applying suggestion') }}</span>
+ <span>{{ applyingSuggestionsMessage }}</span>
+ </div>
+ <div v-else-if="canApply && canBeBatched && isBatched" class="d-flex align-items-center">
+ <gl-deprecated-button
+ class="btn-inverted js-remove-from-batch-btn btn-grouped"
+ :disabled="isApplying"
+ @click="removeSuggestionFromBatch"
+ >
+ {{ __('Remove from batch') }}
+ </gl-deprecated-button>
+ <gl-deprecated-button
+ v-gl-tooltip.viewport="__('This also resolves all related threads')"
+ class="btn-inverted js-apply-batch-btn btn-grouped"
+ :disabled="isApplying"
+ variant="success"
+ @click="applySuggestionBatch"
+ >
+ {{ __('Apply suggestions') }}
+ <span class="badge badge-pill badge-pill-success">
+ {{ batchSuggestionsCount }}
+ </span>
+ </gl-deprecated-button>
+ </div>
+ <div v-else class="d-flex align-items-center">
+ <span v-if="canBeBatched" v-gl-tooltip.viewport="tooltipMessageBatch" tabindex="0">
+ <gl-deprecated-button
+ class="btn-inverted js-add-to-batch-btn btn-grouped"
+ :disabled="isDisableButton"
+ @click="addSuggestionToBatch"
+ >
+ {{ __('Add suggestion to batch') }}
+ </gl-deprecated-button>
+ </span>
+ <span v-gl-tooltip.viewport="tooltipMessage" tabindex="0">
+ <gl-deprecated-button
+ class="btn-inverted js-apply-btn btn-grouped"
+ :disabled="isDisableButton"
+ variant="success"
+ @click="applySuggestion"
+ >
+ {{ __('Apply suggestion') }}
+ </gl-deprecated-button>
+ </span>
</div>
- <gl-deprecated-button
- v-else-if="canApply"
- v-gl-tooltip.viewport="__('This also resolves the discussion')"
- class="btn-inverted js-apply-btn"
- :disabled="isApplying"
- variant="success"
- @click="applySuggestion"
- >
- {{ __('Apply suggestion') }}
- </gl-deprecated-button>
</div>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/markdown/suggestions.vue b/app/assets/javascripts/vue_shared/components/markdown/suggestions.vue
index 20a14d78f9b..9527c5114f2 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/suggestions.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/suggestions.vue
@@ -16,6 +16,11 @@ export default {
required: false,
default: () => [],
},
+ batchSuggestionsInfo: {
+ type: Array,
+ required: false,
+ default: () => [],
+ },
noteHtml: {
type: String,
required: true,
@@ -68,18 +73,30 @@ export default {
this.isRendered = true;
},
generateDiff(suggestionIndex) {
- const { suggestions, disabled, helpPagePath } = this;
+ const { suggestions, disabled, batchSuggestionsInfo, helpPagePath } = this;
const suggestion =
suggestions && suggestions[suggestionIndex] ? suggestions[suggestionIndex] : {};
const SuggestionDiffComponent = Vue.extend(SuggestionDiff);
const suggestionDiff = new SuggestionDiffComponent({
- propsData: { disabled, suggestion, helpPagePath },
+ propsData: { disabled, suggestion, batchSuggestionsInfo, helpPagePath },
});
suggestionDiff.$on('apply', ({ suggestionId, callback }) => {
this.$emit('apply', { suggestionId, callback, flashContainer: this.$el });
});
+ suggestionDiff.$on('applyBatch', () => {
+ this.$emit('applyBatch', { flashContainer: this.$el });
+ });
+
+ suggestionDiff.$on('addToBatch', suggestionId => {
+ this.$emit('addToBatch', suggestionId);
+ });
+
+ suggestionDiff.$on('removeFromBatch', suggestionId => {
+ this.$emit('removeFromBatch', suggestionId);
+ });
+
return suggestionDiff;
},
reset() {
diff --git a/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue b/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue
index 486d4f6b609..330785c9319 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue
@@ -1,11 +1,13 @@
<script>
-/* eslint-disable @gitlab/vue-require-i18n-strings */
-import { GlLink, GlLoadingIcon } from '@gitlab/ui';
+import { GlButton, GlLink, GlLoadingIcon, GlSprintf, GlIcon } from '@gitlab/ui';
export default {
components: {
+ GlButton,
GlLink,
GlLoadingIcon,
+ GlSprintf,
+ GlIcon,
},
props: {
markdownDocsPath: {
@@ -35,45 +37,69 @@ export default {
<div class="comment-toolbar clearfix">
<div class="toolbar-text">
<template v-if="!hasQuickActionsDocsPath && markdownDocsPath">
- <gl-link :href="markdownDocsPath" target="_blank" tabindex="-1">{{
+ <gl-link :href="markdownDocsPath" target="_blank">{{
__('Markdown is supported')
}}</gl-link>
</template>
<template v-if="hasQuickActionsDocsPath && markdownDocsPath">
- <gl-link :href="markdownDocsPath" target="_blank" tabindex="-1">{{
- __('Markdown')
- }}</gl-link>
- and
- <gl-link :href="quickActionsDocsPath" target="_blank" tabindex="-1">{{
- __('quick actions')
- }}</gl-link>
- are supported
+ <gl-sprintf
+ :message="
+ __(
+ '%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported',
+ )
+ "
+ >
+ <template #markdownDocsLink="{content}">
+ <gl-link :href="markdownDocsPath" target="_blank">{{ content }}</gl-link>
+ </template>
+ <template #quickActionsDocsLink="{content}">
+ <gl-link :href="quickActionsDocsPath" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
</template>
</div>
<span v-if="canAttachFile" class="uploading-container">
<span class="uploading-progress-container hide">
- <i class="fa fa-file-image-o toolbar-button-icon" aria-hidden="true"></i>
+ <template>
+ <gl-icon name="media" :size="16" />
+ </template>
<span class="attaching-file-message"></span>
+ <!-- eslint-disable-next-line @gitlab/vue-require-i18n-strings -->
<span class="uploading-progress">0%</span>
<gl-loading-icon inline class="align-text-bottom" />
</span>
<span class="uploading-error-container hide">
<span class="uploading-error-icon">
- <i class="fa fa-file-image-o toolbar-button-icon" aria-hidden="true"></i>
+ <template>
+ <gl-icon name="media" :size="16" />
+ </template>
</span>
<span class="uploading-error-message"></span>
- <button class="retry-uploading-link" type="button">{{ __('Try again') }}</button> or
- <button class="attach-new-file markdown-selector" type="button">
- {{ __('attach a new file') }}
- </button>
+
+ <gl-sprintf
+ :message="
+ __(
+ '%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}',
+ )
+ "
+ >
+ <template #retryButton="{content}">
+ <button class="retry-uploading-link" type="button">{{ content }}</button>
+ </template>
+ <template #newFileButton="{content}">
+ <button class="attach-new-file markdown-selector" type="button">{{ content }}</button>
+ </template>
+ </gl-sprintf>
</span>
- <button class="markdown-selector button-attach-file btn-link" tabindex="-1" type="button">
- <i class="fa fa-file-image-o toolbar-button-icon" aria-hidden="true"></i
- ><span class="text-attach-file">{{ __('Attach a file') }}</span>
- </button>
- <button class="btn btn-default btn-sm hide button-cancel-uploading-files" type="button">
+ <gl-button class="markdown-selector button-attach-file" variant="link">
+ <template>
+ <gl-icon name="media" :size="16" />
+ </template>
+ <span class="text-attach-file">{{ __('Attach a file') }}</span>
+ </gl-button>
+ <gl-button class="btn btn-default btn-sm hide button-cancel-uploading-files" variant="link">
{{ __('Cancel') }}
- </button>
+ </gl-button>
</span>
</div>
</template>
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 ec7d7e94e5c..b6271a95008 100644
--- a/app/assets/javascripts/vue_shared/components/notes/system_note.vue
+++ b/app/assets/javascripts/vue_shared/components/notes/system_note.vue
@@ -132,7 +132,7 @@ export default {
</pre>
<pre v-else class="wrapper mt-2" v-html="descriptionVersion"></pre>
<gl-deprecated-button
- v-if="canDeleteDescriptionVersion"
+ v-if="displayDeleteButton"
ref="deleteDescriptionVersionButton"
v-gl-tooltip
:title="__('Remove description history')"
diff --git a/app/assets/javascripts/vue_shared/components/project_selector/project_selector.vue b/app/assets/javascripts/vue_shared/components/project_selector/project_selector.vue
index fd45ac52647..15a5ce85046 100644
--- a/app/assets/javascripts/vue_shared/components/project_selector/project_selector.vue
+++ b/app/assets/javascripts/vue_shared/components/project_selector/project_selector.vue
@@ -1,6 +1,7 @@
<script>
import { debounce } from 'lodash';
import { GlLoadingIcon, GlSearchBoxByType, GlInfiniteScroll } from '@gitlab/ui';
+import { __, n__, sprintf } from '~/locale';
import ProjectListItem from './project_list_item.vue';
const SEARCH_INPUT_TIMEOUT_MS = 500;
@@ -24,28 +25,23 @@ export default {
},
showNoResultsMessage: {
type: Boolean,
- required: false,
- default: false,
+ required: true,
},
showMinimumSearchQueryMessage: {
type: Boolean,
- required: false,
- default: false,
+ required: true,
},
showLoadingIndicator: {
type: Boolean,
- required: false,
- default: false,
+ required: true,
},
showSearchErrorMessage: {
type: Boolean,
- required: false,
- default: false,
+ required: true,
},
totalResults: {
type: Number,
- required: false,
- default: 0,
+ required: true,
},
},
data() {
@@ -53,6 +49,20 @@ export default {
searchQuery: '',
};
},
+ computed: {
+ legendText() {
+ const count = this.projectSearchResults.length;
+ const total = this.totalResults;
+
+ if (total > 0) {
+ return sprintf(__('Showing %{count} of %{total} projects'), { count, total });
+ }
+
+ return sprintf(n__('Showing %{count} project', 'Showing %{count} projects', count), {
+ count,
+ });
+ },
+ },
methods: {
projectClicked(project) {
this.$emit('projectClicked', project);
@@ -87,17 +97,23 @@ export default {
:total-items="totalResults"
@bottomReached="bottomReached"
>
- <div v-if="!showLoadingIndicator" slot="items" class="d-flex flex-column">
- <project-list-item
- v-for="project in projectSearchResults"
- :key="project.id"
- :selected="isSelected(project)"
- :project="project"
- :matcher="searchQuery"
- class="js-project-list-item"
- @click="projectClicked(project)"
- />
- </div>
+ <template v-if="!showLoadingIndicator" #items>
+ <div class="d-flex flex-column">
+ <project-list-item
+ v-for="project in projectSearchResults"
+ :key="project.id"
+ :selected="isSelected(project)"
+ :project="project"
+ :matcher="searchQuery"
+ class="js-project-list-item"
+ @click="projectClicked(project)"
+ />
+ </div>
+ </template>
+
+ <template #default>
+ {{ legendText }}
+ </template>
</gl-infinite-scroll>
<div v-if="showNoResultsMessage" class="text-muted ml-2 js-no-results-message">
{{ __('Sorry, no projects matched your search') }}
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/constants.js b/app/assets/javascripts/vue_shared/components/rich_content_editor/constants.js
index 457f1806452..1566c2c784b 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/constants.js
+++ b/app/assets/javascripts/vue_shared/components/rich_content_editor/constants.js
@@ -1,5 +1,9 @@
import { __ } from '~/locale';
-import { generateToolbarItem } from './toolbar_service';
+import { generateToolbarItem } from './editor_service';
+
+export const CUSTOM_EVENTS = {
+ openAddImageModal: 'gl_openAddImageModal',
+};
/* eslint-disable @gitlab/require-i18n-strings */
const TOOLBAR_ITEM_CONFIGS = [
@@ -10,7 +14,6 @@ const TOOLBAR_ITEM_CONFIGS = [
{ isDivider: true },
{ icon: 'quote', command: 'Blockquote', tooltip: __('Insert a quote') },
{ icon: 'link', event: 'openPopupAddLink', tooltip: __('Add a link') },
- { icon: 'doc-code', command: 'CodeBlock', tooltip: __('Insert a code block') },
{ isDivider: true },
{ icon: 'list-bulleted', command: 'UL', tooltip: __('Add a bullet list') },
{ icon: 'list-numbered', command: 'OL', tooltip: __('Add a numbered list') },
@@ -20,8 +23,10 @@ const TOOLBAR_ITEM_CONFIGS = [
{ isDivider: true },
{ icon: 'dash', command: 'HR', tooltip: __('Add a line') },
{ icon: 'table', event: 'openPopupAddTable', classes: 'tui-table', tooltip: __('Add a table') },
+ { icon: 'doc-image', event: CUSTOM_EVENTS.openAddImageModal, tooltip: __('Insert an image') },
{ isDivider: true },
{ icon: 'code', command: 'Code', tooltip: __('Insert inline code') },
+ { icon: 'doc-code', command: 'CodeBlock', tooltip: __('Insert a code block') },
];
export const EDITOR_OPTIONS = {
@@ -29,6 +34,7 @@ export const EDITOR_OPTIONS = {
};
export const EDITOR_TYPES = {
+ markdown: 'markdown',
wysiwyg: 'wysiwyg',
};
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/editor_service.js b/app/assets/javascripts/vue_shared/components/rich_content_editor/editor_service.js
new file mode 100644
index 00000000000..278cd50a947
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/rich_content_editor/editor_service.js
@@ -0,0 +1,42 @@
+import Vue from 'vue';
+import ToolbarItem from './toolbar_item.vue';
+
+const buildWrapper = propsData => {
+ const instance = new Vue({
+ render(createElement) {
+ return createElement(ToolbarItem, propsData);
+ },
+ });
+
+ instance.$mount();
+ return instance.$el;
+};
+
+export const generateToolbarItem = config => {
+ const { icon, classes, event, command, tooltip, isDivider } = config;
+
+ if (isDivider) {
+ return 'divider';
+ }
+
+ return {
+ type: 'button',
+ options: {
+ el: buildWrapper({ props: { icon, tooltip }, class: classes }),
+ event,
+ command,
+ },
+ };
+};
+
+export const addCustomEventListener = (editorApi, event, handler) => {
+ editorApi.eventManager.addEventType(event);
+ editorApi.eventManager.listen(event, handler);
+};
+
+export const removeCustomEventListener = (editorApi, event, handler) =>
+ editorApi.eventManager.removeEventHandler(event, handler);
+
+export const addImage = ({ editor }, image) => editor.exec('AddImage', image);
+
+export const getMarkdown = editorInstance => editorInstance.invoke('getMarkdown');
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/modals/add_image_modal.vue b/app/assets/javascripts/vue_shared/components/rich_content_editor/modals/add_image_modal.vue
new file mode 100644
index 00000000000..40063065926
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/rich_content_editor/modals/add_image_modal.vue
@@ -0,0 +1,74 @@
+<script>
+import { isSafeURL } from '~/lib/utils/url_utility';
+import { GlModal, GlFormGroup, GlFormInput } from '@gitlab/ui';
+import { __ } from '~/locale';
+
+export default {
+ components: {
+ GlModal,
+ GlFormGroup,
+ GlFormInput,
+ },
+ data() {
+ return {
+ error: null,
+ imageUrl: null,
+ altText: null,
+ modalTitle: __('Image Details'),
+ okTitle: __('Insert'),
+ urlLabel: __('Image URL'),
+ descriptionLabel: __('Description'),
+ };
+ },
+ methods: {
+ show() {
+ this.error = null;
+ this.imageUrl = null;
+ this.altText = null;
+
+ this.$refs.modal.show();
+ },
+ onOk(event) {
+ if (!this.isValid()) {
+ event.preventDefault();
+ return;
+ }
+
+ const { imageUrl, altText } = this;
+
+ this.$emit('addImage', { imageUrl, altText: altText || __('image') });
+ },
+ isValid() {
+ if (!isSafeURL(this.imageUrl)) {
+ this.error = __('Please provide a valid URL');
+ this.$refs.urlInput.$el.focus();
+ return false;
+ }
+
+ return true;
+ },
+ },
+};
+</script>
+<template>
+ <gl-modal
+ ref="modal"
+ modal-id="add-image-modal"
+ :title="modalTitle"
+ :ok-title="okTitle"
+ @ok="onOk"
+ >
+ <gl-form-group
+ :label="urlLabel"
+ label-for="url-input"
+ :state="!Boolean(error)"
+ :invalid-feedback="error"
+ >
+ <gl-form-input id="url-input" ref="urlInput" v-model="imageUrl" />
+ </gl-form-group>
+
+ <gl-form-group :label="descriptionLabel" label-for="description-input">
+ <gl-form-input id="description-input" ref="descriptionInput" v-model="altText" />
+ </gl-form-group>
+ </gl-modal>
+</template>
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/rich_content_editor.vue b/app/assets/javascripts/vue_shared/components/rich_content_editor/rich_content_editor.vue
index ba3696c8ad1..5c310fc059b 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/rich_content_editor.vue
+++ b/app/assets/javascripts/vue_shared/components/rich_content_editor/rich_content_editor.vue
@@ -2,7 +2,21 @@
import 'codemirror/lib/codemirror.css';
import '@toast-ui/editor/dist/toastui-editor.css';
-import { EDITOR_OPTIONS, EDITOR_TYPES, EDITOR_HEIGHT, EDITOR_PREVIEW_STYLE } from './constants';
+import AddImageModal from './modals/add_image_modal.vue';
+import {
+ EDITOR_OPTIONS,
+ EDITOR_TYPES,
+ EDITOR_HEIGHT,
+ EDITOR_PREVIEW_STYLE,
+ CUSTOM_EVENTS,
+} from './constants';
+
+import {
+ addCustomEventListener,
+ removeCustomEventListener,
+ addImage,
+ getMarkdown,
+} from './editor_service';
export default {
components: {
@@ -10,6 +24,7 @@ export default {
import(/* webpackChunkName: 'toast_editor' */ '@toast-ui/vue-editor').then(
toast => toast.Editor,
),
+ AddImageModal,
},
props: {
value: {
@@ -37,29 +52,85 @@ export default {
default: EDITOR_PREVIEW_STYLE,
},
},
+ data() {
+ return {
+ editorApi: null,
+ previousMode: null,
+ };
+ },
computed: {
editorOptions() {
return { ...EDITOR_OPTIONS, ...this.options };
},
+ editorInstance() {
+ return this.$refs.editor;
+ },
+ },
+ watch: {
+ value(newVal) {
+ const isSameMode = this.previousMode === this.editorApi.currentMode;
+ if (!isSameMode) {
+ /*
+ The ToastUI Editor consumes its content via the `initial-value` prop and then internally
+ manages changes. If we desire the `v-model` to work as expected, we need to manually call
+ `setMarkdown`. However, if we do this in each v-model change we'll continually prevent
+ the editor from internally managing changes. Thus we use the `previousMode` flag as
+ confirmation to actually update its internals. This is initially designed so that front
+ matter is excluded from editing in wysiwyg mode, but included in markdown mode.
+ */
+ this.editorInstance.invoke('setMarkdown', newVal);
+ this.previousMode = this.editorApi.currentMode;
+ }
+ },
+ },
+ beforeDestroy() {
+ removeCustomEventListener(
+ this.editorApi,
+ CUSTOM_EVENTS.openAddImageModal,
+ this.onOpenAddImageModal,
+ );
+
+ this.editorApi.eventManager.removeEventHandler('changeMode', this.onChangeMode);
},
methods: {
onContentChanged() {
- this.$emit('input', this.getMarkdown());
+ this.$emit('input', getMarkdown(this.editorInstance));
+ },
+ onLoad(editorApi) {
+ this.editorApi = editorApi;
+
+ addCustomEventListener(
+ this.editorApi,
+ CUSTOM_EVENTS.openAddImageModal,
+ this.onOpenAddImageModal,
+ );
+
+ this.editorApi.eventManager.listen('changeMode', this.onChangeMode);
+ },
+ onOpenAddImageModal() {
+ this.$refs.addImageModal.show();
+ },
+ onAddImage(image) {
+ addImage(this.editorInstance, image);
},
- getMarkdown() {
- return this.$refs.editor.invoke('getMarkdown');
+ onChangeMode(newMode) {
+ this.$emit('modeChange', newMode);
},
},
};
</script>
<template>
- <toast-editor
- ref="editor"
- :initial-value="value"
- :options="editorOptions"
- :preview-style="previewStyle"
- :initial-edit-type="initialEditType"
- :height="height"
- @change="onContentChanged"
- />
+ <div>
+ <toast-editor
+ ref="editor"
+ :initial-value="value"
+ :options="editorOptions"
+ :preview-style="previewStyle"
+ :initial-edit-type="initialEditType"
+ :height="height"
+ @change="onContentChanged"
+ @load="onLoad"
+ />
+ <add-image-modal ref="addImageModal" @addImage="onAddImage" />
+ </div>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/toolbar_item.vue b/app/assets/javascripts/vue_shared/components/rich_content_editor/toolbar_item.vue
index 58aaeef45f2..4271f6053ed 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/toolbar_item.vue
+++ b/app/assets/javascripts/vue_shared/components/rich_content_editor/toolbar_item.vue
@@ -1,20 +1,27 @@
<script>
-import { GlIcon } from '@gitlab/ui';
+import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
export default {
components: {
GlIcon,
},
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
props: {
icon: {
type: String,
required: true,
},
+ tooltip: {
+ type: String,
+ required: true,
+ },
},
};
</script>
<template>
- <button class="p-0 gl-display-flex toolbar-button">
- <gl-icon class="gl-mx-auto" :name="icon" />
+ <button v-gl-tooltip="{ title: tooltip }" class="p-0 gl-display-flex toolbar-button">
+ <gl-icon class="gl-mx-auto gl-align-self-center" :name="icon" />
</button>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/toolbar_service.js b/app/assets/javascripts/vue_shared/components/rich_content_editor/toolbar_service.js
deleted file mode 100644
index fff90f3e3fb..00000000000
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/toolbar_service.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import Vue from 'vue';
-import ToolbarItem from './toolbar_item.vue';
-
-const buildWrapper = propsData => {
- const instance = new Vue({
- render(createElement) {
- return createElement(ToolbarItem, propsData);
- },
- });
-
- instance.$mount();
- return instance.$el;
-};
-
-// eslint-disable-next-line import/prefer-default-export
-export const generateToolbarItem = config => {
- const { icon, classes, event, command, tooltip, isDivider } = config;
-
- if (isDivider) {
- return 'divider';
- }
-
- return {
- type: 'button',
- options: {
- el: buildWrapper({ props: { icon }, class: classes }),
- event,
- command,
- tooltip,
- },
- };
-};
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/constants.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/constants.js
index ab652c9356a..e94e7d46f85 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/constants.js
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/constants.js
@@ -1,5 +1,6 @@
-// eslint-disable-next-line import/prefer-default-export
export const DropdownVariant = {
Sidebar: 'sidebar',
Standalone: 'standalone',
};
+
+export const LIST_BUFFER_SIZE = 5;
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue
index 1ef2e8b3bed..af16088b6b9 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue
@@ -3,15 +3,20 @@ import { mapState, mapGetters, mapActions } from 'vuex';
import { GlLoadingIcon, GlButton, GlSearchBoxByType, GlLink } from '@gitlab/ui';
import { UP_KEY_CODE, DOWN_KEY_CODE, ENTER_KEY_CODE, ESC_KEY_CODE } from '~/lib/utils/keycodes';
+import SmartVirtualList from '~/vue_shared/components/smart_virtual_list.vue';
import LabelItem from './label_item.vue';
+import { LIST_BUFFER_SIZE } from './constants';
+
export default {
+ LIST_BUFFER_SIZE,
components: {
GlLoadingIcon,
GlButton,
GlSearchBoxByType,
GlLink,
+ SmartVirtualList,
LabelItem,
},
data() {
@@ -139,10 +144,18 @@ export default {
<gl-search-box-by-type v-model="searchKey" :autofocus="true" />
</div>
<div v-show="!labelsFetchInProgress" ref="labelsListContainer" class="dropdown-content">
- <ul class="list-unstyled mb-0">
+ <smart-virtual-list
+ :length="visibleLabels.length"
+ :remain="$options.LIST_BUFFER_SIZE"
+ :size="$options.LIST_BUFFER_SIZE"
+ wclass="list-unstyled mb-0"
+ wtag="ul"
+ class="h-100"
+ >
<li v-for="(label, index) in visibleLabels" :key="label.id" class="d-block text-left">
<label-item
:label="label"
+ :is-label-set="label.set"
:highlight="index === currentHighlightItem"
@clickLabel="handleLabelClick(label)"
/>
@@ -150,7 +163,7 @@ export default {
<li v-show="!visibleLabels.length" class="p-2 text-center">
{{ __('No matching results') }}
</li>
- </ul>
+ </smart-virtual-list>
</div>
<div v-if="isDropdownVariantSidebar" class="dropdown-footer">
<ul class="list-unstyled">
@@ -162,9 +175,9 @@ export default {
>
</li>
<li>
- <gl-link :href="labelsManagePath" class="d-flex flex-row text-break-word label-item">{{
- footerManageLabelTitle
- }}</gl-link>
+ <gl-link :href="labelsManagePath" class="d-flex flex-row text-break-word label-item">
+ {{ footerManageLabelTitle }}
+ </gl-link>
</li>
</ul>
</div>
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 c95221d71b5..002e741ab96 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
@@ -11,6 +11,10 @@ export default {
type: Object,
required: true,
},
+ isLabelSet: {
+ type: Boolean,
+ required: true,
+ },
highlight: {
type: Boolean,
required: false,
@@ -19,7 +23,7 @@ export default {
},
data() {
return {
- isSet: this.label.set,
+ isSet: this.isLabelSet,
};
},
computed: {
@@ -29,6 +33,16 @@ export default {
};
},
},
+ watch: {
+ /**
+ * This watcher assures that if user used
+ * `Enter` key to set/unset label, changes
+ * are reflected here too.
+ */
+ isLabelSet(value) {
+ this.isSet = value;
+ },
+ },
methods: {
handleClick() {
this.isSet = !this.isSet;
diff --git a/app/assets/javascripts/vue_shared/components/url_sync.vue b/app/assets/javascripts/vue_shared/components/url_sync.vue
new file mode 100644
index 00000000000..389d42f0829
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/url_sync.vue
@@ -0,0 +1,25 @@
+<script>
+import { historyPushState } from '~/lib/utils/common_utils';
+import { setUrlParams } from '~/lib/utils/url_utility';
+
+export default {
+ props: {
+ query: {
+ type: Object,
+ required: true,
+ },
+ },
+ watch: {
+ query: {
+ immediate: true,
+ deep: true,
+ handler(newQuery) {
+ historyPushState(setUrlParams(newQuery, window.location.href, true));
+ },
+ },
+ },
+ render() {
+ return this.$slots.default;
+ },
+};
+</script>
diff --git a/app/assets/javascripts/vue_shared/mixins/ci_pagination_api_mixin.js b/app/assets/javascripts/vue_shared/mixins/ci_pagination_api_mixin.js
index c93b3d37a63..a740a3fa6b9 100644
--- a/app/assets/javascripts/vue_shared/mixins/ci_pagination_api_mixin.js
+++ b/app/assets/javascripts/vue_shared/mixins/ci_pagination_api_mixin.js
@@ -5,6 +5,7 @@
* Components need to have `scope`, `page` and `requestData`
*/
import { historyPushState, buildUrlWithCurrentLocation } from '../../lib/utils/common_utils';
+import { validateParams } from '~/pipelines/utils';
export default {
methods: {
@@ -35,18 +36,7 @@ export default {
},
onChangeWithFilter(params) {
- const { username, ref } = this.requestData;
- const paramsData = params;
-
- if (username) {
- paramsData.username = username;
- }
-
- if (ref) {
- paramsData.ref = ref;
- }
-
- return paramsData;
+ return { ...params, ...validateParams(this.requestData) };
},
updateInternalState(parameters) {
diff --git a/app/assets/javascripts/vue_shared/mixins/related_issuable_mixin.js b/app/assets/javascripts/vue_shared/mixins/related_issuable_mixin.js
index 4fad34d22d8..c628a67f7f5 100644
--- a/app/assets/javascripts/vue_shared/mixins/related_issuable_mixin.js
+++ b/app/assets/javascripts/vue_shared/mixins/related_issuable_mixin.js
@@ -144,7 +144,9 @@ const mixins = {
return 'merge-request-status closed issue-token-state-icon-closed';
}
- return this.isOpen ? 'issue-token-state-icon-open' : 'issue-token-state-icon-closed';
+ return this.isOpen
+ ? 'issue-token-state-icon-open gl-text-green-500'
+ : 'issue-token-state-icon-closed gl-text-blue-500';
},
computedLinkElementType() {
return this.path.length > 0 ? 'a' : 'span';
diff --git a/app/assets/stylesheets/application_dark.scss b/app/assets/stylesheets/application_dark.scss
new file mode 100644
index 00000000000..72196d71969
--- /dev/null
+++ b/app/assets/stylesheets/application_dark.scss
@@ -0,0 +1,3 @@
+@import "./themes/dark";
+
+@import "./application";
diff --git a/app/assets/stylesheets/bootstrap_migration.scss b/app/assets/stylesheets/bootstrap_migration.scss
index 1c15400542a..a6d56819140 100644
--- a/app/assets/stylesheets/bootstrap_migration.scss
+++ b/app/assets/stylesheets/bootstrap_migration.scss
@@ -111,7 +111,7 @@ kbd {
code {
padding: 2px 4px;
color: $code-color;
- background-color: $gray-100;
+ background-color: $gray-50;
border-radius: $border-radius-default;
.code > & {
@@ -187,7 +187,7 @@ h3.popover-header {
// Add to .label so that old system notes that are saved to the db
// will still receive the correct styling
-.badge,
+.badge:not(.gl-badge),
.label {
padding: 4px 5px;
font-size: 12px;
diff --git a/app/assets/stylesheets/components/avatar.scss b/app/assets/stylesheets/components/avatar.scss
index 312123aeef9..6bb7e9d215e 100644
--- a/app/assets/stylesheets/components/avatar.scss
+++ b/app/assets/stylesheets/components/avatar.scss
@@ -70,7 +70,7 @@ $avatar-sizes: (
$identicon-backgrounds: $identicon-red, $identicon-purple, $identicon-indigo, $identicon-blue, $identicon-teal,
$identicon-orange, $gray-darker;
-.avatar-circle {
+%avatar-circle {
float: left;
margin-right: $gl-padding;
border-radius: $avatar-radius;
@@ -84,7 +84,7 @@ $identicon-backgrounds: $identicon-red, $identicon-purple, $identicon-indigo, $i
}
.avatar {
- @extend .avatar-circle;
+ @extend %avatar-circle;
transition-property: none;
width: 40px;
@@ -100,10 +100,7 @@ $identicon-backgrounds: $identicon-red, $identicon-purple, $identicon-indigo, $i
margin-left: 2px;
flex-shrink: 0;
- &.s16 {
- margin-right: 4px;
- }
-
+ &.s16,
&.s24 {
margin-right: 4px;
}
@@ -154,7 +151,7 @@ $identicon-backgrounds: $identicon-red, $identicon-purple, $identicon-indigo, $i
}
.avatar-container {
- @extend .avatar-circle;
+ @extend %avatar-circle;
overflow: hidden;
display: flex;
diff --git a/app/assets/stylesheets/components/dashboard_skeleton.scss b/app/assets/stylesheets/components/dashboard_skeleton.scss
index ce33aa94df3..64091201221 100644
--- a/app/assets/stylesheets/components/dashboard_skeleton.scss
+++ b/app/assets/stylesheets/components/dashboard_skeleton.scss
@@ -67,10 +67,10 @@
background-repeat: no-repeat;
background-size: cover;
background-image: linear-gradient(to right,
- $gray-100 0%,
+ $gray-50 0%,
$gray-10 20%,
- $gray-100 40%,
- $gray-100 100%);
+ $gray-50 40%,
+ $gray-50 100%);
border-radius: $gl-padding;
height: $gl-padding;
margin-top: -$gl-padding-8;
diff --git a/app/assets/stylesheets/components/design_management/design.scss b/app/assets/stylesheets/components/design_management/design.scss
index 1061aae2bbb..380b2280490 100644
--- a/app/assets/stylesheets/components/design_management/design.scss
+++ b/app/assets/stylesheets/components/design_management/design.scss
@@ -1,3 +1,7 @@
+.layout-page.design-detail-layout {
+ max-height: 100vh;
+}
+
.design-detail {
background-color: rgba($black, 0.9);
@@ -5,8 +9,30 @@
top: 35px;
}
- .inactive {
- opacity: 0.5;
+ .design-pin {
+ transition: opacity 0.5s ease;
+
+ &.inactive {
+ @include gl-opacity-5;
+
+ &:hover {
+ @include gl-opacity-10;
+ }
+ }
+ }
+
+ .badge.badge-pill {
+ display: flex;
+ height: 28px;
+ width: 28px;
+ background-color: $blue-400;
+ color: $white;
+ border: $white 1px solid;
+ border-radius: 50%;
+
+ &.resolved {
+ background-color: $gray-700;
+ }
}
}
@@ -40,14 +66,31 @@
min-width: 400px;
flex-basis: 28%;
+ .link-inherit-color {
+ &:hover,
+ &:active,
+ &:focus {
+ color: inherit;
+ text-decoration: none;
+ }
+ }
+
+ .toggle-comments {
+ line-height: 20px;
+ border-top: 1px solid $border-color;
+
+ &.expanded {
+ border-bottom: 1px solid $border-color;
+ }
+
+ .toggle-comments-button:focus {
+ text-decoration: none;
+ color: $blue-600;
+ }
+ }
+
.badge.badge-pill {
margin-left: $gl-padding;
- background-color: $blue-400;
- color: $white;
- border: $white 1px solid;
- min-height: 28px;
- padding: 7px 10px;
- border-radius: $gl-padding;
}
.design-discussion {
diff --git a/app/assets/stylesheets/components/popover.scss b/app/assets/stylesheets/components/popover.scss
index fcaa1b054ed..1e78781f4b8 100644
--- a/app/assets/stylesheets/components/popover.scss
+++ b/app/assets/stylesheets/components/popover.scss
@@ -1,7 +1,7 @@
.popover {
max-width: $popover-max-width;
border: 1px solid $gray-200;
- box-shadow: 0 2px 3px 1px $gray-200;
+ box-shadow: $popover-box-shadow;
font-size: $gl-font-size-small;
/**
diff --git a/app/assets/stylesheets/components/related_items_list.scss b/app/assets/stylesheets/components/related_items_list.scss
index 61f971a3185..956f34f7a8b 100644
--- a/app/assets/stylesheets/components/related_items_list.scss
+++ b/app/assets/stylesheets/components/related_items_list.scss
@@ -23,20 +23,17 @@ $item-remove-button-space: 42px;
.sortable-link {
white-space: normal;
}
+
+ .item-assignees .avatar {
+ height: $gl-padding;
+ width: $gl-padding;
+ }
}
.item-body {
position: relative;
line-height: $gl-line-height;
- .issue-token-state-icon-open {
- color: $green-500;
- }
-
- .issue-token-state-icon-closed {
- color: $blue-500;
- }
-
.merge-request-status.closed {
color: $red-500;
}
@@ -68,7 +65,6 @@ $item-remove-button-space: 42px;
.sortable-link {
color: $gray-900;
- font-weight: normal;
}
}
@@ -276,10 +272,6 @@ $item-remove-button-space: 42px;
/* Small devices (landscape phones, 768px and up) */
@include media-breakpoint-up(md) {
- .item-body .item-contents {
- max-width: 95%;
- }
-
.related-items-tree .item-contents,
.item-body .item-title {
max-width: 100%;
@@ -348,6 +340,11 @@ $item-remove-button-space: 42px;
}
.item-assignees {
+ .avatar {
+ height: $gl-padding-24;
+ width: $gl-padding-24;
+ }
+
.avatar-counter {
height: $gl-padding-24;
min-width: $gl-padding-24;
@@ -366,6 +363,10 @@ $item-remove-button-space: 42px;
.sortable-link {
line-height: 1.3;
}
+
+ .item-info-area {
+ flex-basis: auto;
+ }
}
@media only screen and (min-width: 1500px) {
diff --git a/app/assets/stylesheets/components/rich_content_editor.scss b/app/assets/stylesheets/components/rich_content_editor.scss
index eca0f1114af..bedd06ec9a1 100644
--- a/app/assets/stylesheets/components/rich_content_editor.scss
+++ b/app/assets/stylesheets/components/rich_content_editor.scss
@@ -1,4 +1,8 @@
-// Overrides styles from ToastUI editor
+/**
+* Overrides styles from ToastUI editor
+*/
+
+// Toolbar buttons
.tui-editor-defaultUI-toolbar .toolbar-button {
color: $gl-gray-600;
border: 0;
@@ -9,3 +13,19 @@
border: 0;
}
}
+
+// Contextual menu's & popups
+.tui-editor-defaultUI .tui-popup-wrapper {
+ @include gl-overflow-hidden;
+ @include gl-rounded-base;
+ @include gl-border-gray-400;
+
+ hr {
+ @include gl-m-0;
+ @include gl-bg-gray-400;
+ }
+
+ button {
+ @include gl-text-gray-800;
+ }
+}
diff --git a/app/assets/stylesheets/framework/animations.scss b/app/assets/stylesheets/framework/animations.scss
index 13174687e5d..136ff82e0f8 100644
--- a/app/assets/stylesheets/framework/animations.scss
+++ b/app/assets/stylesheets/framework/animations.scss
@@ -93,7 +93,6 @@
}
.dropdown-menu-toggle,
-.avatar-circle,
.header-user-avatar {
@include transition(border-color);
}
@@ -177,7 +176,7 @@ a {
[class^='skeleton-line-'] {
position: relative;
- background-color: $gray-100;
+ background-color: $gray-50;
height: 10px;
overflow: hidden;
@@ -192,10 +191,10 @@ a {
background-repeat: no-repeat;
background-size: cover;
background-image: linear-gradient(to right,
- $gray-100 0%,
+ $gray-50 0%,
$gray-10 20%,
- $gray-100 40%,
- $gray-100 100%);
+ $gray-50 40%,
+ $gray-50 100%);
height: 10px;
}
}
diff --git a/app/assets/stylesheets/framework/badges.scss b/app/assets/stylesheets/framework/badges.scss
index c036267a7c8..5b8a4bf964e 100644
--- a/app/assets/stylesheets/framework/badges.scss
+++ b/app/assets/stylesheets/framework/badges.scss
@@ -1,6 +1,14 @@
-.badge.badge-pill {
+.badge.badge-pill:not(.gl-badge) {
font-weight: $gl-font-weight-normal;
background-color: $badge-bg;
color: $gray-800;
vertical-align: baseline;
+
+ // Do not use this!
+ // This is a temporary workaround until the new GlBadge component
+ // is available: https://gitlab.com/gitlab-org/gitlab-ui/-/issues/481
+ &.badge-pill-success {
+ background-color: rgba($green-500, 0.2);
+ color: $green;
+ }
}
diff --git a/app/assets/stylesheets/framework/blank.scss b/app/assets/stylesheets/framework/blank.scss
index 7dd7ab339dd..a1e757afe56 100644
--- a/app/assets/stylesheets/framework/blank.scss
+++ b/app/assets/stylesheets/framework/blank.scss
@@ -116,3 +116,17 @@
}
}
}
+
+.experiment-new-project-page-blank-state {
+ @include media-breakpoint-down(md) {
+ flex-direction: column;
+ justify-content: center;
+ text-align: center;
+ }
+}
+
+$experiment-new-project-indigo-700: #41419f;
+
+.experiment-new-project-page-blank-state-title {
+ color: $experiment-new-project-indigo-700;
+}
diff --git a/app/assets/stylesheets/framework/broadcast_messages.scss b/app/assets/stylesheets/framework/broadcast_messages.scss
index 9903d10d27c..534ada08b85 100644
--- a/app/assets/stylesheets/framework/broadcast_messages.scss
+++ b/app/assets/stylesheets/framework/broadcast_messages.scss
@@ -14,8 +14,6 @@
}
.broadcast-banner-message {
- @extend .broadcast-message;
- @extend .alert-warning;
text-align: center;
.broadcast-message-dismiss {
@@ -24,8 +22,6 @@
}
.broadcast-notification-message {
- @extend .broadcast-message;
-
position: fixed;
bottom: $gl-padding;
right: $gl-padding;
@@ -42,7 +38,6 @@
}
.broadcast-message-dismiss {
- height: 100%;
color: $gray-800;
}
}
diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss
index 93361c21642..849ca4a79f8 100644
--- a/app/assets/stylesheets/framework/common.scss
+++ b/app/assets/stylesheets/framework/common.scss
@@ -111,7 +111,7 @@ pre {
hr {
margin: 24px 0;
- border-top: 1px solid darken($gray-normal, 8%);
+ border-top: 1px solid $gray-darker;
}
.str-truncated {
@@ -135,7 +135,7 @@ hr {
text-overflow: ellipsis;
white-space: nowrap;
- > div:not(.block),
+ > div:not(.block):not(.select2-display-none),
.str-truncated {
display: inline;
}
@@ -396,21 +396,13 @@ img.emoji {
🚨 Do not use these classes — they are deprecated and being removed. 🚨
See https://gitlab.com/gitlab-org/gitlab/-/issues/217418 for more details.
**/
-.prepend-top-0 { margin-top: 0; }
-.prepend-top-2 { margin-top: 2px; }
-.prepend-top-4 { margin-top: $gl-padding-4; }
.prepend-top-5 { margin-top: 5px; }
-.prepend-top-8 { margin-top: $grid-size; }
.prepend-top-10 { margin-top: 10px; }
.prepend-top-15 { margin-top: 15px; }
.prepend-top-default { margin-top: $gl-padding !important; }
.prepend-top-16 { margin-top: 16px; }
.prepend-top-20 { margin-top: 20px; }
-.prepend-top-32 { margin-top: 32px; }
-.prepend-left-2 { margin-left: 2px; }
-.prepend-left-4 { margin-left: 4px; }
.prepend-left-5 { margin-left: 5px; }
-.prepend-left-8 { margin-left: 8px; }
.prepend-left-10 { margin-left: 10px; }
.prepend-left-15 { margin-left: 15px; }
.prepend-left-default { margin-left: $gl-padding; }
@@ -420,7 +412,6 @@ img.emoji {
.append-right-2 { margin-right: 2px; }
.append-right-4 { margin-right: 4px; }
.append-right-5 { margin-right: 5px; }
-.append-right-8 { margin-right: 8px; }
.append-right-10 { margin-right: 10px; }
.append-right-15 { margin-right: 15px; }
.append-right-default { margin-right: $gl-padding; }
@@ -428,11 +419,7 @@ img.emoji {
.append-right-32 { margin-right: 32px; }
.append-right-48 { margin-right: 48px; }
.prepend-right-32 { margin-right: 32px; }
-.append-bottom-0 { margin-bottom: 0; }
-.append-bottom-2 { margin-bottom: 2px; }
-.append-bottom-4 { margin-bottom: $gl-padding-4; }
.append-bottom-5 { margin-bottom: 5px; }
-.append-bottom-8 { margin-bottom: $grid-size; }
.append-bottom-10 { margin-bottom: 10px; }
.append-bottom-15 { margin-bottom: 15px; }
.append-bottom-20 { margin-bottom: 20px; }
@@ -521,31 +508,6 @@ img.emoji {
}
/**
- The zero-indexed classes will not change and do not need to be updated.
- These can be removed when the Gitlab UI class include is merged.
-**/
-
-.gl-p-0 {
- padding: 0;
-}
-
-.gl-pl-0 {
- padding-left: 0;
-}
-
-.gl-pr-0 {
- padding-right: 0;
-}
-
-.gl-pt-0 {
- padding-top: 0;
-}
-
-.gl-pb-0 {
- padding-bottom: 0;
-}
-
-/**
* Removes browser specific clear icon from input fields in
* Internet Explorer 10, Internet Explorer 11, and Microsoft Edge.
* This is intended for elements which add a customized clear icon.
@@ -602,7 +564,7 @@ img.emoji {
bottom: 40px;
right: 40px;
font-size: $gl-font-size-small;
- background: $gray-100;
+ background: $gray-50;
width: 200px;
border-radius: 24px;
box-shadow: 0 2px 4px $issue-boards-card-shadow;
@@ -637,8 +599,6 @@ img.emoji {
.gl-font-lg { font-size: $gl-font-size-large; }
.gl-font-base { font-size: $gl-font-size-14; }
-.gl-line-height-24 { line-height: $gl-line-height-24; }
-
.gl-font-size-0 { font-size: 0; }
.gl-font-size-28 { font-size: $gl-font-size-28; }
.gl-font-size-42 { font-size: $gl-font-size-42; }
diff --git a/app/assets/stylesheets/framework/contextual_sidebar.scss b/app/assets/stylesheets/framework/contextual_sidebar.scss
index 11064f18418..e4bee01f61f 100644
--- a/app/assets/stylesheets/framework/contextual_sidebar.scss
+++ b/app/assets/stylesheets/framework/contextual_sidebar.scss
@@ -137,7 +137,7 @@
.badge.badge-pill:not(.fly-out-badge),
.sidebar-context-title,
.nav-item-name {
- display: none;
+ @include gl-sr-only;
}
.sidebar-top-level-items > li > a {
diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss
index 1df9818a877..485a4879c43 100644
--- a/app/assets/stylesheets/framework/dropdowns.scss
+++ b/app/assets/stylesheets/framework/dropdowns.scss
@@ -657,6 +657,7 @@
.dropdown-input-field,
.default-dropdown-input {
+ background-color: $input-bg;
display: block;
width: 100%;
min-height: 30px;
@@ -940,7 +941,7 @@ header.header-content .dropdown-menu.frequent-items-dropdown-menu {
position: absolute;
top: 13px;
right: 25px;
- color: $gray-100;
+ color: $gray-50;
}
}
@@ -979,7 +980,7 @@ header.header-content .dropdown-menu.frequent-items-dropdown-menu {
&:hover {
.frequent-items-item-avatar-container .avatar {
- border-color: $gray-100;
+ border-color: $gray-50;
}
}
diff --git a/app/assets/stylesheets/framework/files.scss b/app/assets/stylesheets/framework/files.scss
index 7ee3e68ceea..eef6d9031f8 100644
--- a/app/assets/stylesheets/framework/files.scss
+++ b/app/assets/stylesheets/framework/files.scss
@@ -480,7 +480,7 @@ span.idiff {
padding-bottom: $gl-padding;
.discussion-reply-holder {
- border-bottom: 1px solid $gray-100;
+ border-bottom: 1px solid $gray-50;
border-radius: 0;
}
}
diff --git a/app/assets/stylesheets/framework/filters.scss b/app/assets/stylesheets/framework/filters.scss
index 5f6a26d0a14..9bba5c0614a 100644
--- a/app/assets/stylesheets/framework/filters.scss
+++ b/app/assets/stylesheets/framework/filters.scss
@@ -96,7 +96,7 @@
}
.name {
- background-color: $white-normal;
+ background-color: $gray-50;
color: $gl-text-color-secondary;
border-radius: 2px 0 0 2px;
margin-right: 1px;
@@ -259,6 +259,7 @@
flex: 1;
position: relative;
min-width: 0;
+ background-color: $input-bg;
}
.filtered-search-input-dropdown-menu {
@@ -449,3 +450,17 @@
font-size: 13px;
}
}
+
+.vue-filtered-search-bar-container {
+ @include media-breakpoint-up(md) {
+ .sort-dropdown-container {
+ margin-left: 10px;
+ }
+ }
+
+ @include media-breakpoint-down(sm) {
+ .sort-dropdown-container {
+ margin-top: 10px;
+ }
+ }
+}
diff --git a/app/assets/stylesheets/framework/gitlab_theme.scss b/app/assets/stylesheets/framework/gitlab_theme.scss
index 6a2f36d2509..8d5afe1d312 100644
--- a/app/assets/stylesheets/framework/gitlab_theme.scss
+++ b/app/assets/stylesheets/framework/gitlab_theme.scss
@@ -314,12 +314,12 @@ body {
$gray-800,
$gray-700,
$gray-700,
- $gray-100,
+ $gray-50,
$gray-700
);
.navbar-gitlab {
- background-color: $gray-100;
+ background-color: $gray-50;
box-shadow: 0 1px 0 0 $border-color;
.logo-text svg {
@@ -388,4 +388,49 @@ body {
color: $gray-900;
}
}
+
+ &.gl-dark {
+ .logo-text svg {
+ fill: $gl-text-color;
+ }
+
+ .navbar-gitlab {
+ background-color: $gray-50;
+
+ .navbar-sub-nav,
+ .navbar-nav {
+ li {
+ > a:hover,
+ > a:focus,
+ > button:hover,
+ > button:focus {
+ color: $gl-text-color;
+ background-color: $gray-200;
+ }
+ }
+
+ li.active,
+ li.dropdown.show {
+ > a,
+ > button {
+ color: $gl-text-color;
+ background-color: $gray-200;
+ }
+ }
+ }
+
+ .search {
+ form {
+ background-color: $gray-100;
+ box-shadow: inset 0 0 0 1px $border-color;
+
+ &:active,
+ &:hover {
+ background-color: $gray-100;
+ box-shadow: inset 0 0 0 1px $blue-200;
+ }
+ }
+ }
+ }
+ }
}
diff --git a/app/assets/stylesheets/framework/markdown_area.scss b/app/assets/stylesheets/framework/markdown_area.scss
index 97698fefbee..2a97009e605 100644
--- a/app/assets/stylesheets/framework/markdown_area.scss
+++ b/app/assets/stylesheets/framework/markdown_area.scss
@@ -123,7 +123,7 @@
.markdown-area {
border-radius: 0;
background: $white;
- border: 1px solid $gray-100;
+ border: 1px solid $gray-50;
min-height: 140px;
max-height: 500px;
padding: 5px;
diff --git a/app/assets/stylesheets/framework/selects.scss b/app/assets/stylesheets/framework/selects.scss
index 3c428cc352f..c2ab6f5b8c5 100644
--- a/app/assets/stylesheets/framework/selects.scss
+++ b/app/assets/stylesheets/framework/selects.scss
@@ -12,6 +12,7 @@
.select2-container.select2-drop-above {
.select2-choice {
background: $white;
+ color: $gl-text-color;
border-color: $input-border;
height: 34px;
padding: $gl-vert-padding $gl-input-padding;
@@ -58,6 +59,42 @@
}
}
+ // Essentially we’re doing @include form-control-focus here (from
+ // bootstrap/scss/mixins/_forms.scss), except that the bootstrap mixin adds a
+ // `&:focus` selector and we’re never actually focusing the .select2-choice
+ // link nor the .select2-container, the Select2 library focuses an off-screen
+ // .select2-focusser element instead.
+ &.select2-container-active:not(.select2-dropdown-open) {
+ .select2-choice {
+ color: $input-focus-color;
+ background-color: $input-focus-bg;
+ border-color: $input-focus-border-color;
+ outline: 0;
+ }
+
+ // Reusable focus “glow†box-shadow
+ @mixin form-control-focus-glow {
+ @if $enable-shadows {
+ box-shadow: $input-box-shadow, $input-focus-box-shadow;
+ } @else {
+ box-shadow: $input-focus-box-shadow;
+ }
+ }
+
+ // Apply the focus “glow†shadow to the .select2-container if it also has
+ // the .block-truncated class as that applies an overflow: hidden, thereby
+ // hiding the glow of the nested .select2-choice element.
+ &.block-truncated {
+ @include form-control-focus-glow;
+ }
+
+ // Apply the glow directly to the .select2-choice link if we’re not
+ // block-truncating the container.
+ &:not(.block-truncated) .select2-choice {
+ @include form-control-focus-glow;
+ }
+ }
+
&.is-invalid {
~ .invalid-feedback {
display: block;
@@ -72,6 +109,7 @@
.select2-drop,
.select2-drop.select2-drop-above {
+ background: $white;
box-shadow: 0 2px 4px $dropdown-shadow-color;
border-radius: $border-radius-base;
border: 1px solid $border-color;
@@ -166,7 +204,8 @@
input {
padding: $grid-size;
- background: $white image-url('select2.png');
+ background: transparent image-url('select2.png');
+ color: $gl-text-color;
background-clip: content-box;
background-origin: content-box;
background-repeat: no-repeat;
diff --git a/app/assets/stylesheets/framework/system_messages.scss b/app/assets/stylesheets/framework/system_messages.scss
index 5c298d5a588..4f66d6bf354 100644
--- a/app/assets/stylesheets/framework/system_messages.scss
+++ b/app/assets/stylesheets/framework/system_messages.scss
@@ -83,12 +83,20 @@
// right sidebar eg: mr page
.nav-sidebar,
.right-sidebar,
- // navless pages' footer eg: login page
- // navless pages' footer border eg: login page
+ // navless pages' footer eg: login page
+ // navless pages' footer border eg: login page
&.devise-layout-html body .footer-container,
&.devise-layout-html body hr.footer-fixed {
bottom: $system-footer-height;
}
+
+ .content-wrapper {
+ margin-bottom: 16px;
+ }
+
+ .boards-list {
+ height: calc(100vh - #{$header-height + $breadcrumb-min-height + $performance-bar-height + $system-footer-height + $gl-padding-32});
+ }
}
.fullscreen-layout {
diff --git a/app/assets/stylesheets/framework/tables.scss b/app/assets/stylesheets/framework/tables.scss
index 5739f048e86..5bc2874ea05 100644
--- a/app/assets/stylesheets/framework/tables.scss
+++ b/app/assets/stylesheets/framework/tables.scss
@@ -47,7 +47,7 @@ table {
}
th {
- @include gl-bg-gray-100;
+ @include gl-bg-gray-50;
border-bottom: 0;
&.wide {
diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss
index 1afcbc6d514..6e07a2b5de1 100644
--- a/app/assets/stylesheets/framework/typography.scss
+++ b/app/assets/stylesheets/framework/typography.scss
@@ -545,6 +545,24 @@
}
}
}
+
+ /* AsciiDoc(tor) built-in alignment roles */
+
+ .text-left {
+ text-align: left !important;
+ }
+
+ .text-right {
+ text-align: right !important;
+ }
+
+ .text-center {
+ text-align: center !important;
+ }
+
+ .text-justify {
+ text-align: justify !important;
+ }
}
/**
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index ac4d431ea57..1536c5c3022 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -73,108 +73,106 @@ $size-scale: (
'xl': #{70 * $grid-size}
);
-/*
- * Color schema
- */
-$darken-normal-factor: 7%;
-$darken-dark-factor: 10%;
-$darken-border-factor: 5%;
-$darken-border-dashed-factor: 25%;
-
-$white: #fff;
-$white-normal: #f0f0f0;
-$white-dark: #eaeaea;
-$white-transparent: rgba(255, 255, 255, 0.8);
-
-$gray-lightest: #fdfdfd;
-$gray-light: #fafafa;
-$gray-lighter: #f9f9f9;
-$gray-normal: #f5f5f5;
-$gray-dark: darken($gray-light, $darken-dark-factor);
-$gray-darker: #eee;
-$gray-darkest: #c4c4c4;
-
-$purple: #6d49cb;
-$purple-light: #ede8fb;
-
-$black: #000;
-$black-transparent: rgba(0, 0, 0, 0.3);
-$almost-black: #242424;
-
-$t-gray-a-02: rgba($black, 0.02);
-$t-gray-a-04: rgba($black, 0.04);
-$t-gray-a-06: rgba($black, 0.06);
-$t-gray-a-08: rgba($black, 0.08);
-
-$gl-gray-100: #ddd;
-$gl-gray-200: #ccc;
-$gl-gray-350: #aaa;
-$gl-gray-400: #999;
-$gl-gray-500: #777;
-$gl-gray-600: #666;
-$gl-gray-700: #555;
-$gl-gray-800: #333;
-
-$green-50: #f1fdf6;
-$green-100: #dcf5e7;
-$green-200: #b3e6c8;
-$green-300: #75d09b;
-$green-400: #37b96d;
-$green-500: #1aaa55;
-$green-600: #168f48;
-$green-700: #12753a;
-$green-800: #0e5a2d;
-$green-900: #0a4020;
-$green-950: #072b15;
-
-$blue-50: #f6fafe;
-$blue-100: #e4f0fb;
-$blue-200: #b8d6f4;
-$blue-300: #73afea;
-$blue-400: #418cd8;
-$blue-500: #1f78d1;
-$blue-600: #1b69b6;
-$blue-700: #17599c;
-$blue-800: #134a81;
-$blue-900: #0f3b66;
-$blue-950: #0a2744;
-
-$orange-50: #fffaf4;
-$orange-100: #fff1de;
-$orange-200: #fed69f;
-$orange-300: #fdbc60;
-$orange-400: #fca429;
-$orange-500: #fc9403;
-$orange-600: #de7e00;
-$orange-700: #c26700;
-$orange-800: #a35200;
-$orange-900: #853c00;
-$orange-950: #592800;
-
-$red-50: #fef6f5;
-$red-100: #fbe5e1;
-$red-200: #f2b4a9;
-$red-300: #ea8271;
-$red-400: #e05842;
-$red-500: #db3b21;
-$red-600: #c0341d;
-$red-700: #a62d19;
-$red-800: #8b2615;
-$red-900: #711e11;
-$red-950: #4b140b;
-
-$gray-10: #fafafa;
-$gray-50: #f0f0f0;
-$gray-100: #f2f2f2;
-$gray-200: #dfdfdf;
-$gray-300: #ccc;
-$gray-400: #bababa;
-$gray-500: #a7a7a7;
-$gray-600: #919191;
-$gray-700: #707070;
-$gray-800: #4f4f4f;
-$gray-900: #2e2e2e;
-$gray-950: #1f1f1f;
+// Color schema
+$darken-normal-factor: 7% !default;
+$darken-dark-factor: 10% !default;
+$darken-border-factor: 5% !default;
+$darken-border-dashed-factor: 25% !default;
+
+$white: #fff !default;
+$white-normal: #f0f0f0 !default;
+$white-dark: #eaeaea !default;
+$white-transparent: rgba(255, 255, 255, 0.8) !default;
+
+$gray-lightest: #fdfdfd !default;
+$gray-light: #fafafa !default;
+$gray-lighter: #f9f9f9 !default;
+$gray-normal: #f5f5f5 !default;
+$gray-dark: darken($gray-light, $darken-dark-factor) !default;
+$gray-darker: #eee !default;
+$gray-darkest: #c4c4c4 !default;
+
+$purple: #6d49cb !default;
+$purple-light: #ede8fb !default;
+
+$black: #000 !default;
+$black-transparent: rgba(0, 0, 0, 0.3) !default;
+$almost-black: #242424 !default;
+
+$t-gray-a-02: rgba($black, 0.02) !default;
+$t-gray-a-04: rgba($black, 0.04) !default;
+$t-gray-a-06: rgba($black, 0.06) !default;
+$t-gray-a-08: rgba($black, 0.08) !default;
+
+$gl-gray-100: #ddd !default;
+$gl-gray-200: #ccc !default;
+$gl-gray-350: #aaa !default;
+$gl-gray-400: #999 !default;
+$gl-gray-500: #777 !default;
+$gl-gray-600: #666 !default;
+$gl-gray-700: #555 !default;
+$gl-gray-800: #333 !default;
+
+$green-50: #f1fdf6 !default;
+$green-100: #dcf5e7 !default;
+$green-200: #263a2e !default;
+$green-300: #75d09b !default;
+$green-400: #37b96d !default;
+$green-500: #1aaa55 !default;
+$green-600: #168f48 !default;
+$green-700: #12753a !default;
+$green-800: #0e5a2d !default;
+$green-900: #0a4020 !default;
+$green-950: #072b15 !default;
+
+$blue-50: #f6fafe !default;
+$blue-100: #e4f0fb !default;
+$blue-200: #b8d6f4 !default;
+$blue-300: #73afea !default;
+$blue-400: #418cd8 !default;
+$blue-500: #1f78d1 !default;
+$blue-600: #1b69b6 !default;
+$blue-700: #17599c !default;
+$blue-800: #134a81 !default;
+$blue-900: #0f3b66 !default;
+$blue-950: #0a2744 !default;
+
+$orange-50: #fffaf4 !default;
+$orange-100: #fff1de !default;
+$orange-200: #fed69f !default;
+$orange-300: #fdbc60 !default;
+$orange-400: #fca429 !default;
+$orange-500: #fc9403 !default;
+$orange-600: #de7e00 !default;
+$orange-700: #c26700 !default;
+$orange-800: #a35200 !default;
+$orange-900: #853c00 !default;
+$orange-950: #592800 !default;
+
+$red-50: #fcf1ef !default;
+$red-100: #fdd4cd !default;
+$red-200: #fcb5aa !default;
+$red-300: #f57f6c !default;
+$red-400: #ec5941 !default;
+$red-500: #dd2b0e !default;
+$red-600: #c91c00 !default;
+$red-700: #ae1800 !default;
+$red-800: #8d1300 !default;
+$red-900: #660e00 !default;
+$red-950: #4d0a00 !default;
+
+$gray-10: #fafafa !default;
+$gray-50: #f0f0f0 !default;
+$gray-100: #dbdbdb !default;
+$gray-200: #dfdfdf !default;
+$gray-300: #ccc !default;
+$gray-400: #bababa !default;
+$gray-500: #a7a7a7 !default;
+$gray-600: #919191 !default;
+$gray-700: #707070 !default;
+$gray-800: #4f4f4f !default;
+$gray-900: #2e2e2e !default;
+$gray-950: #1f1f1f !default;
$greens: (
'50': $green-50,
@@ -325,8 +323,8 @@ $theme-light-red-500: #c24b38;
$theme-light-red-600: #b03927;
$theme-light-red-700: #a62e21;
-$border-white-light: darken($white, $darken-border-factor);
-$border-white-normal: darken($white-normal, $darken-border-factor);
+$border-white-light: darken($white, $darken-border-factor) !default;
+$border-white-normal: darken($white-normal, $darken-border-factor) !default;
$border-gray-light: darken($gray-light, $darken-border-factor);
$border-gray-normal: darken($gray-normal, $darken-border-factor);
@@ -335,7 +333,7 @@ $border-gray-normal-dashed: darken($gray-normal, $darken-border-dashed-factor);
/*
* UI elements
*/
-$border-color: #e5e5e5;
+$border-color: $gray-200;
$shadow-color: $t-gray-a-08;
$well-expand-item: #e8f2f7;
$well-inner-border: #eef0f2;
@@ -356,7 +354,7 @@ $gl-text-color-secondary: $gray-700;
$gl-text-color-tertiary: $gray-600;
$gl-text-color-quaternary: #d6d6d6;
$gl-text-color-inverted: $white;
-$gl-text-color-secondary-inverted: rgba(255, 255, 255, 0.85);
+$gl-text-color-secondary-inverted: rgba($white, 0.85);
$gl-text-color-disabled: $gray-600;
$gl-grayish-blue: #7f8fa4;
$gl-gray-dark: #313236;
@@ -435,7 +433,6 @@ $layout-link-gray: #7e7c7c;
$btn-side-margin: 10px;
$btn-sm-side-margin: 7px;
$btn-margin-5: 5px;
-$sidebar-block-hover-color: #ebebeb;
$count-arrow-border: #dce0e5;
$general-hover-transition-duration: 100ms;
$general-hover-transition-curve: linear;
@@ -491,8 +488,8 @@ $line-number-select: #fbf2da;
$line-target-blue: $blue-50;
$line-select-yellow: #fcf8e7;
$line-select-yellow-dark: #f0e2bd;
-$dark-diff-match-bg: rgba(255, 255, 255, 0.3);
-$dark-diff-match-color: rgba(255, 255, 255, 0.1);
+$dark-diff-match-bg: rgba($white, 0.3);
+$dark-diff-match-color: rgba($white, 0.1);
$diff-image-info-color: #808080;
$diff-view-modes-color: #808080;
$diff-view-modes-border: #c1c1c1;
@@ -520,7 +517,7 @@ $dropdown-shadow-color: rgba(#000, 0.1);
$dropdown-title-btn-color: #bfbfbf;
$dropdown-input-fa-color: #c7c7c7;
$dropdown-input-focus-shadow: rgba($blue-300, 0.4);
-$dropdown-loading-bg: rgba(#fff, 0.6);
+$dropdown-loading-bg: rgba($white, 0.6);
$dropdown-chevron-size: 10px;
$dropdown-toggle-active-border-color: darken($border-color, 14%);
$dropdown-fade-mask-height: 32px;
@@ -534,9 +531,9 @@ $filtered-search-term-shadow-color: rgba(0, 0, 0, 0.09);
/*
* Contextual Sidebar
*/
-$link-active-background: rgba(0, 0, 0, 0.04);
-$link-hover-background: rgba(0, 0, 0, 0.06);
-$inactive-badge-background: rgba(0, 0, 0, 0.08);
+$link-active-background: rgba($black, 0.04);
+$link-hover-background: rgba($gray-900, 0.06);
+$inactive-badge-background: rgba($black, 0.08);
$sidebar-toggle-height: 60px;
$sidebar-toggle-width: 40px;
$sidebar-milestone-toggle-bottom-margin: 10px;
@@ -544,8 +541,8 @@ $sidebar-milestone-toggle-bottom-margin: 10px;
/*
* Buttons
*/
-$btn-active-gray: #ececec;
-$btn-active-gray-light: #e4e7ed;
+$btn-active-gray: $gray-50;
+$btn-active-gray-light: $gray-50;
$btn-white-active: #848484;
$gl-btn-padding: 10px;
$gl-btn-line-height: 16px;
@@ -602,12 +599,12 @@ $note-icon-gutter-width: 55px;
/*
* Identicon
*/
-$identicon-red: #ffebee;
-$identicon-purple: #f3e5f5;
-$identicon-indigo: #e8eaf6;
-$identicon-blue: #e3f2fd;
-$identicon-teal: #e0f2f1;
-$identicon-orange: #fbe9e7;
+$identicon-red: #ffebee !default;
+$identicon-purple: #f3e5f5 !default;
+$identicon-indigo: #e8eaf6 !default;
+$identicon-blue: #e3f2fd !default;
+$identicon-teal: #e0f2f1 !default;
+$identicon-orange: #fbe9e7 !default;
/*
* Calendar
@@ -719,8 +716,8 @@ $accepting-mr-label-color: #69d100;
/*
* Issues
*/
-$issues-today-bg: #f3fff2;
-$issues-today-border: #e1e8d5;
+$issues-today-bg: #f3fff2 !default;
+$issues-today-border: #e1e8d5 !default;
$compare-display-color: #888;
/*
@@ -871,6 +868,7 @@ $priority-label-empty-state-width: 114px;
Popovers
*/
$popover-max-width: 384px;
+$popover-box-shadow: 0 2px 3px 1px $gray-200;
/*
Issues Analytics
diff --git a/app/assets/stylesheets/framework/variables_overrides.scss b/app/assets/stylesheets/framework/variables_overrides.scss
index ef75dabbda4..c7a50bdb5a3 100644
--- a/app/assets/stylesheets/framework/variables_overrides.scss
+++ b/app/assets/stylesheets/framework/variables_overrides.scss
@@ -55,3 +55,26 @@ $tooltip-padding-y: 0.5rem;
$tooltip-padding-x: 0.75rem;
$tooltip-arrow-height: 0.5rem;
$tooltip-arrow-width: 1rem;
+$b-table-sort-icon-bg-descending: url('data:image/svg+xml, <svg \
+ xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="4 0 8 16"> \
+ <path style="fill: #666;" fill-rule="evenodd" d="M11.707085,11.7071 \
+ L7.999975,15.4142 L4.292875,11.7071 C3.902375,11.3166 3.902375, \
+ 10.6834 4.292875,10.2929 C4.683375,9.90237 \
+ 5.316575,9.90237 5.707075,10.2929 L6.999975, \
+ 11.5858 L6.999975,2 C6.999975,1.44771 \
+ 7.447695,1 7.999975,1 C8.552255,1 8.999975,1.44771 \
+ 8.999975,2 L8.999975,11.5858 L10.292865,10.2929 C10.683395 \
+ ,9.90237 11.316555,9.90237 11.707085,10.2929 \
+ C12.097605,10.6834 12.097605,11.3166 11.707085,11.7071 Z"/> \
+ </svg>') !default;
+$b-table-sort-icon-bg-ascending: url('data:image/svg+xml,<svg \
+ xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="4 0 8 16"> \
+ <path style="fill: #666;" fill-rule="evenodd" d="M4.29289,4.2971 L8,0.59 \
+ L11.7071,4.2971 C12.0976,4.6876 \
+ 12.0976,5.3208 11.7071,5.7113 C11.3166,6.10183 10.6834, \
+ 6.10183 10.2929,5.7113 L9,4.4184 L9,14.0042 C9,14.55649 \
+ 8.55228,15.0042 8,15.0042 C7.44772,15.0042 7,14.55649 \
+ 7,14.0042 L7,4.4184 L5.70711,5.7113 C5.31658,6.10183 4.68342,6.10183 4.29289,5.7113 \
+ C3.90237,5.3208 3.90237,4.6876 4.29289,4.2971 Z"/> \
+ </svg> ') !default;
+$b-table-sort-icon-bg-not-sorted: '';
diff --git a/app/assets/stylesheets/notify.scss b/app/assets/stylesheets/notify.scss
index 2bf823993d7..6320c10fb51 100644
--- a/app/assets/stylesheets/notify.scss
+++ b/app/assets/stylesheets/notify.scss
@@ -36,5 +36,5 @@ pre.commit-message {
}
.gl-label-text-dark {
- color: $gl-gray-800;
+ color: $gl-text-color;
}
diff --git a/app/assets/stylesheets/page_bundles/_ide_monaco_overrides.scss b/app/assets/stylesheets/page_bundles/_ide_monaco_overrides.scss
index 5675835a622..0b847902525 100644
--- a/app/assets/stylesheets/page_bundles/_ide_monaco_overrides.scss
+++ b/app/assets/stylesheets/page_bundles/_ide_monaco_overrides.scss
@@ -27,8 +27,7 @@
z-index: 2;
}
- .is-readonly,
- .editor.original {
+ .is-readonly .editor.original {
.view-lines {
cursor: default;
}
diff --git a/app/assets/stylesheets/page_bundles/_ide_theme_overrides.scss b/app/assets/stylesheets/page_bundles/_ide_theme_overrides.scss
index e4c01c2bd6c..2b82b2226c6 100644
--- a/app/assets/stylesheets/page_bundles/_ide_theme_overrides.scss
+++ b/app/assets/stylesheets/page_bundles/_ide_theme_overrides.scss
@@ -1,9 +1,15 @@
// -------
// Please see `app/assets/stylesheets/page_bundles/ide_themes/README.md` for a guide on contributing new themes
// -------
-.ide.theme-dark {
- a:not(.btn) {
- color: var(--ide-link-color);
+.ide {
+ $bs-input-focus-border: #80bdff;
+ $bs-input-focus-box-shadow: rgba(0, 123, 255, 0.25);
+
+ a:not(.btn),
+ .btn-link:hover,
+ .btn-link:focus,
+ .btn-link:active {
+ color: var(--ide-link-color, $blue-600);
}
h1,
@@ -19,156 +25,207 @@
.context-header > a,
input,
textarea,
- .md-area.is-focused,
.dropdown-menu li button,
.dropdown-menu-selectable li a.is-active,
.dropdown-menu-inner-title,
- .dropdown-menu-inner-content,
- .nav-links:not(.quick-links) li:not(.md-header-toolbar) a,
- .nav-links:not(.quick-links) li:not(.md-header-toolbar) a:hover,
- .nav-links:not(.quick-links) li:not(.md-header-toolbar) a.active .badge.badge-pill,
- .nav-links:not(.quick-links) li:not(.md-header-toolbar) a:hover .badge.badge-pill,
- .badge.badge-pill,
.bs-callout,
.ide-pipeline .top-bar,
- .ide-pipeline .top-bar .controllers .controllers-buttons {
- color: var(--ide-text-color);
+ .ide-pipeline .top-bar .controllers .controllers-buttons,
+ .controllers-buttons svg,
+ .nav-links li a.active,
+ .md-area.is-focused {
+ color: var(--ide-text-color, $gl-text-color);
}
- .drag-handle:hover,
- .card-header .badge.badge-pill {
- background-color: var(--ide-dropdown-hover-background);
+ .badge.badge-pill {
+ color: var(--ide-text-color, $gray-800);
+ background-color: var(--ide-background, $badge-bg);
}
+ .nav-links:not(.quick-links) li:not(.md-header-toolbar) a,
+ .dropdown-menu-inner-content,
.file-row .file-row-icon svg,
- .file-row:hover .file-row-icon svg,
- .controllers-buttons svg {
- color: var(--ide-text-color-secondary);
+ .file-row:hover .file-row-icon svg {
+ color: var(--ide-text-color-secondary, $gl-text-color-secondary);
+ }
+
+ .nav-links:not(.quick-links) li:not(.md-header-toolbar) {
+ &:hover a,
+ &.active a,
+ a:hover,
+ a.active {
+ &,
+ .badge.badge-pill {
+ color: var(--ide-text-color, $black);
+ border-color: var(--ide-input-border, $gray-darkest);
+ }
+ }
+ }
+
+ .drag-handle:hover {
+ background-color: var(--ide-dropdown-hover-background, $white-normal);
+ }
+
+ .card-header {
+ background-color: var(--ide-background, $white);
+
+ .badge.badge-pill {
+ background-color: var(--ide-dropdown-hover-background, $badge-bg);
+ }
}
.text-secondary {
- color: var(--ide-text-color-secondary) !important;
+ color: var(--ide-text-color-secondary, $gl-text-color-secondary) !important;
}
input[type='search']::placeholder,
input[type='text']::placeholder,
- textarea::placeholder,
+ textarea::placeholder {
+ color: var(--ide-input-border, $gl-text-color-tertiary);
+ }
+
.dropdown-input .fa {
- color: var(--ide-input-border);
+ color: var(--ide-input-border, $dropdown-input-fa-color);
}
.ide-nav-form .input-icon {
- color: var(--ide-input-border);
+ color: var(--ide-input-border, $dropdown-input-fa-color);
+ }
+
+ code {
+ background-color: var(--ide-background, $gray-100);
}
- code,
- .badge.badge-pill,
- .card-header,
.bs-callout,
.ide-pipeline .top-bar,
.ide-terminal .top-bar {
- background-color: var(--ide-background);
+ background-color: var(--ide-background, $gray-light);
}
.bs-callout {
- border-color: var(--ide-dropdown-background);
+ border-color: var(--ide-dropdown-background, $border-color);
code {
- background-color: var(--ide-dropdown-background);
+ background-color: var(--ide-dropdown-background, $gray-100);
}
}
- .nav-links:not(.quick-links) li:not(.md-header-toolbar) a:hover {
- border-color: var(--ide-dropdown-hover-background);
+ .common-note-form .md-area {
+ border-color: var(--ide-input-border, $border-color);
}
- .common-note-form .md-area {
- border-color: var(--ide-input-border);
+ .md table:not(.code) tr th {
+ background-color: var(--ide-highlight-background, $gray-100);
}
&,
- .md table:not(.code) tr th,
- .common-note-form .md-area,
- .card {
- background-color: var(--ide-highlight-background);
+ .card,
+ .common-note-form .md-area {
+ background-color: var(--ide-highlight-background, $white);
}
.card,
.card-header,
.ide-terminal .top-bar,
.ide-pipeline .top-bar {
- border-color: var(--ide-border-color);
+ border-color: var(--ide-border-color, $border-color);
+ }
+
+ hr {
+ border-color: var(--ide-border-color, darken($gray-normal, 8%));
}
- hr,
.md h1,
.md h2,
.md blockquote,
- pre,
.md table:not(.code) tbody td,
.md table:not(.code) tr th,
- .nav-links:not(.quick-links) {
- border-color: var(--ide-border-color-alt);
+ .nav-links:not(.quick-links),
+ .common-note-form .md-area.is-focused .nav-links {
+ border-color: var(--ide-border-color-alt, $white-dark);
}
- .ide-sidebar-link.active {
- color: var(--ide-highlight-accent);
- box-shadow: inset 3px 0 var(--ide-highlight-accent);
+ pre {
+ border-color: var(--ide-border-color-alt, $gray-200);
- &.is-right {
- box-shadow: inset -3px 0 var(--ide-highlight-accent);
+ code {
+ background-color: var(--ide-border-color, inherit);
}
}
- .nav-links li.active a,
- .nav-links li a.active {
- border-color: var(--ide-highlight-accent);
- color: var(--ide-text-color);
- }
+ // highlight accents (based on navigation theme) should only apply
+ // in the default white theme and "none" theme.
+ &:not(.theme-white):not(.theme-none) {
+ .ide-sidebar-link.active {
+ color: var(--ide-highlight-accent, $gl-text-color);
+ box-shadow: inset 3px 0 var(--ide-highlight-accent, $gl-text-color);
+
+ &.is-right {
+ box-shadow: inset -3px 0 var(--ide-highlight-accent, $gl-text-color);
+ }
+ }
+
+ .nav-links li.active a,
+ .nav-links li a.active {
+ border-color: var(--ide-highlight-accent, $gl-text-color);
+ }
- .avatar-container {
- &,
- .avatar {
- color: var(--ide-text-color);
- background-color: var(--ide-highlight-background);
- border-color: var(--ide-highlight-background);
+ .dropdown-menu .nav-links li a.active {
+ border-color: var(--ide-highlight-accent, $gl-text-color);
+ }
+
+ // for other themes, suppress different avatar default colors for simplicity
+ .avatar-container {
+ &,
+ .avatar {
+ color: var(--ide-text-color, $gl-text-color);
+ background-color: var(--ide-highlight-background, $white);
+ border-color: var(--ide-highlight-background, rgba($black, $gl-avatar-border-opacity));
+ }
}
}
input[type='text'],
input[type='search'],
.filtered-search-box {
- border-color: var(--ide-input-border);
- background: var(--ide-input-background) !important;
+ border-color: var(--ide-input-border, $border-color);
+ background: var(--ide-input-background, $white) !important;
+ }
+
+ input[type='text']:not([disabled]):not([readonly]):focus,
+ .md-area.is-focused {
+ border-color: var(--ide-input-border, $bs-input-focus-border);
+ box-shadow: 0 0 0 3px var(--ide-dropdown-background, $bs-input-focus-box-shadow);
}
input[type='text'],
input[type='search'],
.filtered-search-box,
textarea {
- color: var(--ide-input-color) !important;
+ color: var(--ide-input-color, $gl-text-color) !important;
}
.filtered-search-box input[type='search'] {
- border-color: transparent;
+ border-color: transparent !important;
+ box-shadow: none !important;
}
.filtered-search-token .value-container,
.filtered-search-term .value-container {
- background-color: var(--ide-dropdown-hover-background);
- color: var(--ide-text-color);
+ background-color: var(--ide-dropdown-hover-background, $white-normal);
+ color: var(--ide-text-color, $gl-text-color);
&:hover {
- background-color: var(--ide-input-border);
+ background-color: var(--ide-input-border, $gray-200);
}
}
@function calc-btn-hover-padding($original-padding, $original-border: 1px) {
- @return calc(#{$original-padding + $original-border} - var(--ide-btn-hover-border-width));
+ @return calc(#{$original-padding + $original-border} - var(--ide-btn-hover-border-width, #{$original-border}));
}
.btn:not(.btn-link):not([disabled]):hover {
- border-width: var(--ide-btn-hover-border-width);
+ border-width: var(--ide-btn-hover-border-width, 1px);
padding: calc-btn-hover-padding(6px) calc-btn-hover-padding(10px);
}
@@ -180,53 +237,71 @@
padding: calc-btn-hover-padding(6px) 0;
}
- .btn-inverted,
.btn-default,
.dropdown,
.dropdown-menu-toggle {
- background-color: var(--ide-input-background) !important;
- color: var(--ide-input-color) !important;
- border-color: var(--ide-btn-default-border);
+ background-color: var(--ide-input-background, $white) !important;
+ color: var(--ide-input-color, $gl-text-color) !important;
+ border-color: var(--ide-btn-default-border, $border-color);
}
- .btn-inverted,
- .btn-default {
+ .dropdown-menu-toggle {
+ border-color: var(--ide-btn-default-border, $gray-darkest);
+
&:hover,
&:focus {
- border-color: var(--ide-btn-default-hover-border) !important;
+ background-color: var(--ide-dropdown-btn-hover-background, $gray-darker) !important;
+ border-color: var(--ide-dropdown-btn-hover-border, $gray-darkest) !important;
}
}
- .dropdown,
- .dropdown-menu-toggle {
+ // In IDE, the only inverted buttons are `.btn-remove`
+ .btn-inverted.btn-remove {
+ color: var(--ide-input-color, $red-500) !important;
+ background-color: var(--ide-input-background, $white) !important;
+ border-color: var(--ide-btn-default-border, $red-500);
+
&:hover,
&:focus {
- background-color: var(--ide-dropdown-btn-hover-background) !important;
- border-color: var(--ide-dropdown-btn-hover-border) !important;
+ color: var(--ide-input-color, $red-700) !important;
+ background-color: var(--ide-input-background, $red-100) !important;
+ border-color: var(--ide-btn-default-hover-border, $red-500) !important;
}
- }
- .dropdown-menu {
- color: var(--ide-text-color);
- border-color: var(--ide-background);
- background-color: var(--ide-dropdown-background);
+ &:active {
+ color: var(--ide-input-color, $red-800) !important;
+ background-color: var(--ide-input-background, $red-200) !important;
+ border-color: var(--ide-btn-default-hover-border, $red-600) !important;
+ }
+ }
- .divider,
- .nav-links:not(.quick-links) {
- background-color: var(--ide-dropdown-hover-background);
- border-color: var(--ide-dropdown-hover-background);
+ .btn-default {
+ &:hover,
+ &:focus {
+ border-color: var(--ide-btn-default-hover-border, $border-white-normal) !important;
+ background-color: var(--ide-input-background, $white-normal) !important;
}
- .nav-links li a.active {
- border-color: var(--ide-highlight-accent);
+ &:active,
+ .active {
+ border-color: var(--ide-btn-default-hover-border, $border-white-normal) !important;
+ background-color: var(--ide-input-background, $white-dark) !important;
}
+ }
- .nav-links:not(.quick-links) li:not(.md-header-toolbar) a {
- color: var(--ide-text-color);
+ .dropdown-menu {
+ color: var(--ide-text-color, $gl-text-color);
+ border-color: var(--ide-background, $border-color);
+ background-color: var(--ide-dropdown-background, $white);
- &.active {
- color: var(--ide-text-color);
- }
+ .nav-links:not(.quick-links) {
+ background-color: var(--ide-dropdown-hover-background, $white);
+ border-color: var(--ide-dropdown-hover-background, $border-color);
+ }
+
+ .divider {
+ background-color: var(--ide-dropdown-hover-background, $gray-200);
+ border-color: var(--ide-dropdown-hover-background, $gray-200);
}
li > a:not(.disable-hover):hover,
@@ -234,75 +309,88 @@
li button:not(.disable-hover):hover,
li button:not(.disable-hover):focus,
li button.is-focused {
- background-color: var(--ide-dropdown-hover-background);
- color: var(--ide-text-color);
+ background-color: var(--ide-dropdown-hover-background, $gray-darker);
+ color: var(--ide-text-color, $gl-text-color);
}
}
.dropdown-title,
.dropdown-input {
- border-color: var(--ide-dropdown-hover-background) !important;
+ border-color: var(--ide-dropdown-hover-background, $gray-200) !important;
}
.btn-primary,
.btn-info {
- background-color: var(--ide-btn-primary-background);
- border-color: var(--ide-btn-primary-border) !important;
+ background-color: var(--ide-btn-primary-background, $blue-500);
+ border-color: var(--ide-btn-primary-border, $blue-600) !important;
&:hover,
&:focus {
- border-color: var(--ide-btn-primary-hover-border) !important;
+ background-color: var(--ide-btn-primary-background, $blue-600);
+ border-color: var(--ide-btn-primary-hover-border, $blue-700) !important;
+ }
+
+ &:active,
+ &.active {
+ background-color: var(--ide-btn-primary-background, $blue-700);
+ border-color: var(--ide-btn-primary-hover-border, $blue-800) !important;
}
}
.btn-success {
- background-color: var(--ide-btn-success-background);
- border-color: var(--ide-btn-success-border) !important;
+ background-color: var(--ide-btn-success-background, $green-500);
+ border-color: var(--ide-btn-success-border, $green-600) !important;
&:hover,
&:focus {
- border-color: var(--ide-btn-success-hover-border) !important;
+ background-color: var(--ide-btn-success-background, $green-600);
+ border-color: var(--ide-btn-success-hover-border, $green-700) !important;
+ }
+
+ &:active,
+ &.active {
+ background-color: var(--ide-btn-success-background, $green-700);
+ border-color: var(--ide-btn-success-hover-border, $green-800) !important;
}
}
.btn[disabled] {
- background: var(--ide-btn-default-background) !important;
- border: 1px solid var(--ide-btn-disabled-border) !important;
- color: var(--ide-btn-disabled-color) !important;
+ background-color: var(--ide-btn-default-background, $gray-light) !important;
+ border: 1px solid var(--ide-btn-disabled-border, $gray-200) !important;
+ color: var(--ide-btn-disabled-color, $gl-text-color-disabled) !important;
}
- pre code,
.md table:not(.code) tbody {
- background-color: var(--ide-border-color);
+ background-color: var(--ide-border-color, $white);
}
.animation-container {
[class^='skeleton-line-'] {
- background-color: var(--ide-animation-gradient-1);
+ background-color: var(--ide-animation-gradient-1, $gray-100);
&::after {
background-image: linear-gradient(to right,
- var(--ide-animation-gradient-1) 0%,
- var(--ide-animation-gradient-2) 20%,
- var(--ide-animation-gradient-1) 40%,
- var(--ide-animation-gradient-1) 100%);
+ var(--ide-animation-gradient-1, $gray-100) 0%,
+ var(--ide-animation-gradient-2, $gray-10) 20%,
+ var(--ide-animation-gradient-1, $gray-100) 40%,
+ var(--ide-animation-gradient-1, $gray-100) 100%);
}
}
}
.idiff.addition {
- background-color: var(--ide-diff-insert);
+ background-color: var(--ide-diff-insert, $line-added-dark);
}
.idiff.deletion {
- background-color: var(--ide-diff-remove);
+ background-color: var(--ide-diff-remove, $line-removed-dark);
}
-}
-.navbar.theme-dark {
- border-bottom-color: transparent;
+ ~ .popover {
+ box-shadow: none;
+ }
}
-.theme-dark ~ .popover {
- box-shadow: none;
+.navbar:not(.theme-white):not(.theme-none) {
+ border-bottom-color: transparent;
}
diff --git a/app/assets/stylesheets/page_bundles/ide.scss b/app/assets/stylesheets/page_bundles/ide.scss
index 61914740ac0..9c92f891834 100644
--- a/app/assets/stylesheets/page_bundles/ide.scss
+++ b/app/assets/stylesheets/page_bundles/ide.scss
@@ -5,6 +5,7 @@
@import './ide_theme_overrides';
@import './ide_themes/dark';
+@import './ide_themes/solarized-dark';
$search-list-icon-width: 18px;
$ide-activity-bar-width: 60px;
@@ -24,6 +25,13 @@ $ide-commit-header-height: 48px;
@include str-truncated(250px);
}
+.ide-layout {
+ // Fix for iOS 13+, the height of the page is actually less than
+ // 100vh because of the presence of the bottom bar
+ max-height: 100%;
+ position: fixed;
+}
+
.ide-view {
position: relative;
margin-top: 0;
@@ -65,6 +73,7 @@ $ide-commit-header-height: 48px;
flex-direction: column;
flex: 1;
border-left: 1px solid var(--ide-border-color, $white-dark);
+ border-right: 1px solid var(--ide-border-color, $white-dark);
overflow: hidden;
}
@@ -88,7 +97,7 @@ $ide-commit-header-height: 48px;
&.active {
background-color: var(--ide-highlight-background, $white);
- border-bottom-color: var(--ide-border-color, $white);
+ border-bottom-color: transparent;
}
&:not(.disabled) {
@@ -281,7 +290,6 @@ $ide-commit-header-height: 48px;
.multi-file-commit-panel {
display: flex;
position: relative;
- width: 340px;
padding: 0;
background-color: var(--ide-background, $gray-light);
@@ -386,7 +394,7 @@ $ide-commit-header-height: 48px;
&:hover,
&:focus {
- background: var(--ide-background, $gray-100);
+ background: var(--ide-background, $gray-50);
outline: 0;
}
@@ -558,7 +566,7 @@ $ide-commit-header-height: 48px;
&:hover {
color: var(--ide-text-color, $gl-text-color);
- background-color: var(--ide-background-hover, $gray-100);
+ background-color: var(--ide-background-hover, $gray-50);
}
&:focus {
@@ -584,14 +592,15 @@ $ide-commit-header-height: 48px;
background: var(--ide-highlight-background, $white);
}
- &.is-right {
- padding-right: $gl-padding;
- padding-left: $gl-padding + 1px;
+ }
- &::after {
- right: auto;
- left: -1px;
- }
+ &.is-right {
+ padding-right: $gl-padding;
+ padding-left: $gl-padding + 1px;
+
+ &::after {
+ right: auto;
+ left: -1px;
}
}
}
@@ -872,26 +881,21 @@ $ide-commit-header-height: 48px;
}
.ide-sidebar {
- width: auto;
min-width: 60px;
}
.ide-right-sidebar {
- .ide-activity-bar {
- border-left: 1px solid var(--ide-border-color, $white-dark);
- }
-
.multi-file-commit-panel-inner {
- width: 350px;
padding: $grid-size 0;
background-color: var(--ide-highlight-background, $white);
- border-left: 1px solid var(--ide-border-color, $white-dark);
+ border-right: 1px solid var(--ide-border-color, $white-dark);
}
.ide-right-sidebar-jobs-detail {
padding-bottom: 0;
}
+ .ide-right-sidebar-terminal,
.ide-right-sidebar-clientside {
padding: 0;
}
@@ -901,7 +905,7 @@ $ide-commit-header-height: 48px;
@include ide-trace-view();
svg {
- --svg-status-bg: var(--ide-background, $white);
+ --svg-status-bg: var(--ide-background, #{$white});
}
.empty-state {
@@ -1043,7 +1047,7 @@ $ide-commit-header-height: 48px;
.ide-entry-dropdown-toggle {
padding: $gl-padding-4;
color: var(--ide-text-color, $gl-text-color);
- background-color: var(--ide-background, $gray-100);
+ background-color: var(--ide-background, $gray-50);
&:hover {
background-color: var(--ide-file-row-btn-hover-background, $gray-200);
@@ -1144,12 +1148,12 @@ $ide-commit-header-height: 48px;
}
.file-row.is-active {
- background: var(--ide-background, $gray-100);
+ background: var(--ide-background, $gray-50);
}
.file-row:hover,
.file-row:focus {
- background: var(--ide-background, $gray-100);
+ background: var(--ide-background, $gray-50);
.ide-new-btn {
display: block;
@@ -1159,3 +1163,22 @@ $ide-commit-header-height: 48px;
fill: var(--ide-text-color-secondary, $gl-text-color-secondary);
}
}
+
+.ide-terminal {
+ @include ide-trace-view();
+
+ .terminal-wrapper {
+ background: $black;
+ color: $gray-darkest;
+ overflow: hidden;
+ }
+
+ .xterm {
+ height: 100%;
+ padding: $grid-size;
+ }
+
+ .xterm-viewport {
+ overflow-y: auto;
+ }
+}
diff --git a/app/assets/stylesheets/page_bundles/ide_themes/README.md b/app/assets/stylesheets/page_bundles/ide_themes/README.md
index 535179cc4c2..82e89aef49b 100644
--- a/app/assets/stylesheets/page_bundles/ide_themes/README.md
+++ b/app/assets/stylesheets/page_bundles/ide_themes/README.md
@@ -32,19 +32,7 @@ To add a new theme, follow the following steps:
3. Copy over all the CSS variables from `_dark.scss` to `_solarized_dark.scss` and assign them your own values.
Put them under the selector `.ide.theme-solarized-dark`.
4. Import this newly created SCSS file in `ide.scss` file in the parent directory.
-5. To make sure the variables apply to to your theme, add the selector `.ide.theme-solarized-dark` to the top
- of `_ide_theme_overrides.scss` file. The file should now look like this:
-
- ```scss
- .ide.theme-dark,
- .ide.theme-solarized-dark {
- /* file contents */
- }
- ```
-
- This step is temporary until all CSS variables in that file have their
- default values assigned.
-6. That's it! Raise a merge request with your newly added theme.
+5. That's it! Raise a merge request with your newly added theme.
## Modifying Monaco Themes
diff --git a/app/assets/stylesheets/page_bundles/ide_themes/_solarized-dark.scss b/app/assets/stylesheets/page_bundles/ide_themes/_solarized-dark.scss
new file mode 100644
index 00000000000..a58a0ed9475
--- /dev/null
+++ b/app/assets/stylesheets/page_bundles/ide_themes/_solarized-dark.scss
@@ -0,0 +1,50 @@
+// -------
+// Please see `app/assets/stylesheets/page_bundles/ide_themes/README.md` for a guide on contributing new themes
+// -------
+.ide.theme-solarized-dark {
+ --ide-border-color: #002c38;
+ --ide-border-color-alt: var(--ide-background);
+ --ide-highlight-accent: #fff;
+ --ide-text-color: #ddd;
+ --ide-text-color-secondary: #ddd;
+ --ide-background: #004152;
+ --ide-background-hover: #003b4d;
+ --ide-highlight-background: #003240;
+ --ide-link-color: #73b9ff;
+ --ide-footer-background: var(--ide-highlight-background);
+
+ --ide-input-border: #d8d8d8;
+ --ide-input-background: transparent;
+ --ide-input-color: #fff;
+
+ --ide-btn-default-background: transparent;
+ --ide-btn-default-border: var(--ide-input-border);
+ --ide-btn-default-hover-border: #d8d8d8;
+
+ --ide-btn-primary-background: #1068bf;
+ --ide-btn-primary-border: #428fdc;
+ --ide-btn-primary-hover-border: #63a6e9;
+
+ --ide-btn-success-background: #217645;
+ --ide-btn-success-border: #108548;
+ --ide-btn-success-hover-border: #2da160;
+
+ --ide-btn-disabled-border: rgba(223, 223, 223, 0.24);
+ --ide-btn-disabled-color: rgba(145, 145, 145, 0.48);
+
+ --ide-btn-hover-border-width: 2px;
+
+ --ide-dropdown-background: #004c61;
+ --ide-dropdown-hover-background: #00617a;
+
+ --ide-dropdown-btn-hover-border: #e9ecef;
+ --ide-dropdown-btn-hover-background: var(--ide-background-hover);
+
+ --ide-file-row-btn-hover-background: #005a73;
+
+ --ide-diff-insert: rgba(155, 185, 85, 0.2);
+ --ide-diff-remove: rgba(255, 0, 0, 0.2);
+
+ --ide-animation-gradient-1: var(--ide-file-row-btn-hover-background);
+ --ide-animation-gradient-2: var(--ide-dropdown-hover-background);
+ }
diff --git a/app/assets/stylesheets/pages/alert_management/details.scss b/app/assets/stylesheets/pages/alert_management/details.scss
index 89219e41644..591a26e5941 100644
--- a/app/assets/stylesheets/pages/alert_management/details.scss
+++ b/app/assets/stylesheets/pages/alert_management/details.scss
@@ -35,8 +35,39 @@
}
@include media-breakpoint-down(xs) {
- .alert-details-create-issue-button {
+ .alert-details-issue-button {
width: 100%;
}
}
+
+ .toggle-sidebar-mobile-button {
+ right: 0;
+ }
+
+ .dropdown-menu-toggle {
+ &:hover {
+ background-color: $white;
+ }
+ }
+
+ .assignee-dropdown-item {
+ .dropdown-item {
+ display: flex;
+ align-items: center;
+
+ &::before {
+ top: 50% !important;
+ }
+
+ &.is-active {
+ &:last-child {
+ border-bottom: 1px solid $gray-200;
+ }
+ }
+ }
+ }
+
+ .note-header-info {
+ margin-top: 1px;
+ }
}
diff --git a/app/assets/stylesheets/pages/alert_management/list.scss b/app/assets/stylesheets/pages/alert_management/list.scss
index dc181342def..c1ea9b7604a 100644
--- a/app/assets/stylesheets/pages/alert_management/list.scss
+++ b/app/assets/stylesheets/pages/alert_management/list.scss
@@ -1,22 +1,4 @@
.alert-management-list {
- // consider adding these stateful variants to @gitlab-ui
- // https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/1178
- .hover-bg-blue-50:hover {
- background-color: $blue-50;
- }
-
- .hover-gl-cursor-pointer:hover {
- cursor: pointer;
- }
-
- .hover-gl-border-b-solid:hover {
- @include gl-border-b-solid;
- }
-
- .hover-gl-border-blue-200:hover {
- border-color: $blue-200;
- }
-
// these styles need to be deleted once GlTable component looks in GitLab same as in @gitlab/ui
table {
color: $gray-700;
@@ -26,25 +8,52 @@
outline: none;
}
+ > :not([aria-sort='none']).b-table-sort-icon-left:hover::before {
+ content: '' !important;
+ }
+
td,
th {
- @include gl-p-5;
- border: 0; // Remove cell border styling so that we can set border styling per row
-
- &.event-count {
- @include gl-pr-9;
- }
+ // TODO: There is no gl-pl-9 utlity for this padding, to be done and then removed.
+ padding-left: 1.25rem;
+ @include gl-py-5;
+ @include gl-outline-none;
+ @include gl-relative;
}
th {
background-color: transparent;
font-weight: $gl-font-weight-bold;
color: $gl-gray-600;
+
+ &:hover::before {
+ left: 3%;
+ top: 34%;
+ @include gl-absolute;
+ content: url("data:image/svg+xml,%3Csvg \
+ xmlns='http://www.w3.org/2000/svg' \
+ width='14' height='14' viewBox='0 0 16 \
+ 16'%3E%3Cpath fill='%23BABABA' fill-rule='evenodd' \
+ d='M11.707085,11.7071 L7.999975,15.4142 L4.292875,11.7071 \
+ C3.902375,11.3166 3.902375,10.6834 \
+ 4.292875,10.2929 C4.683375,9.90237 \
+ 5.316575,9.90237 5.707075,10.2929 \
+ L6.999975,11.5858 L6.999975,2 C6.999975,1.44771 \
+ 7.447695,1 7.999975,1 C8.552255,1 8.999975,1.44771 \
+ 8.999975,2 L8.999975,11.5858 L10.292865,10.2929 \
+ C10.683395,9.90237 11.316555,9.90237 11.707085,10.2929 \
+ C12.097605,10.6834 12.097605,11.3166 11.707085,11.7071 \
+ Z'/%3E%3C/svg%3E%0A");
+ }
}
+ }
- &:last-child {
- td {
- @include gl-border-0;
+ @include media-breakpoint-up(md) {
+ tr {
+ &:last-child {
+ td {
+ @include gl-border-0;
+ }
}
}
}
@@ -52,21 +61,31 @@
@include media-breakpoint-down(sm) {
.alert-management-table {
- .table-col {
- min-height: 68px;
+ tr {
+ border-top: 0;
- &:last-child {
- background-color: $gray-10;
+ .table-col {
+ min-height: 68px;
- &::before {
- content: none !important;
- }
+ &:last-child {
+ background-color: $gray-10;
+
+ &::before {
+ content: none !important;
+ }
- div {
- width: 100% !important;
- padding: 0 !important;
+ div {
+ width: 100% !important;
+ padding: 0 !important;
+ }
}
}
+
+ &:hover {
+ background-color: $white;
+ border-color: $white;
+ border-bottom-style: none;
+ }
}
}
}
diff --git a/app/assets/stylesheets/pages/boards.scss b/app/assets/stylesheets/pages/boards.scss
index d755170fe1f..3e680c59910 100644
--- a/app/assets/stylesheets/pages/boards.scss
+++ b/app/assets/stylesheets/pages/boards.scss
@@ -84,17 +84,22 @@
.board-title-caret {
cursor: pointer;
border-radius: $border-radius-default;
- padding: 4px;
+ line-height: $gl-spacing-scale-5;
+ height: $gl-spacing-scale-5;
+
+ &.btn svg {
+ top: 0;
+ }
&:hover {
- background-color: $gray-dark;
+ background-color: $gray-50;
transition: background-color 0.1s linear;
}
}
&:not(.is-collapsed) {
.board-title-caret {
- margin: 0 $gl-padding-4 0 -10px;
+ margin-right: $gl-padding-4;
}
}
@@ -155,7 +160,7 @@
.board-inner {
font-size: $issue-boards-font-size;
background: $gray-light;
- border: 1px solid $border-color;
+ border: 1px solid $gray-100;
}
.board-header {
@@ -186,8 +191,8 @@
.board-title {
align-items: center;
font-size: 1em;
- border-bottom: 1px solid $border-color;
- padding: $gl-padding-8 $gl-padding;
+ border-bottom: 1px solid $gray-100;
+ padding: $gl-padding-8;
.js-max-issue-size::before {
content: '/';
@@ -199,13 +204,13 @@
}
.board-delete {
- margin-right: 10px;
color: $gray-darkest;
background-color: transparent;
outline: 0;
&:hover {
color: $blue-600;
+ box-shadow: none;
}
}
@@ -246,7 +251,7 @@
.board-card {
background: $white;
- border: 1px solid $gray-200;
+ border: 1px solid $gray-100;
box-shadow: 0 1px 2px $issue-boards-card-shadow;
line-height: $gl-padding;
list-style: none;
@@ -541,7 +546,8 @@
cursor: help;
}
-.board-labels-toggle-wrapper {
+.board-labels-toggle-wrapper,
+.board-swimlanes-toggle-wrapper {
/**
* Make the wrapper the same height as a button so it aligns properly when the
* filtered-search-box input element increases in size on Linux smaller breakpoints
@@ -572,3 +578,8 @@
top: 0;
}
}
+
+.board-epics-swimlanes {
+ overflow-x: auto;
+ min-height: 600px;
+}
diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss
index ddd1a373e2a..98d74a9aaa2 100644
--- a/app/assets/stylesheets/pages/diff.scss
+++ b/app/assets/stylesheets/pages/diff.scss
@@ -446,7 +446,7 @@ table.code {
vertical-align: top;
span {
- white-space: pre-wrap;
+ white-space: break-spaces;
&.context-cell {
display: inline-block;
diff --git a/app/assets/stylesheets/pages/experience_level.scss b/app/assets/stylesheets/pages/experience_level.scss
new file mode 100644
index 00000000000..e57ad6321a5
--- /dev/null
+++ b/app/assets/stylesheets/pages/experience_level.scss
@@ -0,0 +1,29 @@
+.signup-page[data-page^='registrations:experience_levels'] {
+ $card-shadow-color: rgba($black, 0.2);
+
+ .page-wrap {
+ background-color: $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;
+ }
+}
diff --git a/app/assets/stylesheets/pages/groups.scss b/app/assets/stylesheets/pages/groups.scss
index beb0ea27de0..c309c8d157a 100644
--- a/app/assets/stylesheets/pages/groups.scss
+++ b/app/assets/stylesheets/pages/groups.scss
@@ -14,17 +14,12 @@
flex-direction: column;
margin: 0;
- .group-row-contents .controls > .btn:last-child {
- margin: 0;
- }
-
li {
.title {
font-weight: 600;
}
a {
- color: $gray-900;
text-decoration: none;
&:hover {
@@ -42,8 +37,6 @@
}
.group-row {
- @include basic-list-stats;
-
.description p {
margin-bottom: 0;
color: $gl-text-color-secondary;
@@ -56,6 +49,12 @@
}
}
+.save-group-loader {
+ margin-top: $gl-padding-50;
+ margin-bottom: $gl-padding-50;
+ color: $gl-gray-700;
+}
+
.group-nav-container .nav-controls {
.group-filter-form {
flex: 1 1 auto;
@@ -454,29 +453,10 @@ table.pipeline-project-metrics tr td {
min-width: 30px;
}
- > span:last-child {
- margin-right: 0;
- }
-
.stat-value {
margin: 2px 0 0 5px;
}
}
-
- .controls {
- flex-basis: 90px;
-
- > .btn {
- margin: 0 $btn-side-margin 0 0;
- color: $gl-text-color-secondary;
- }
- }
-
- .metadata {
- @include media-breakpoint-up(md) {
- flex-basis: 240px;
- }
- }
}
.project-row-contents .stats {
diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss
index b241d0a2bdc..b1e849143b0 100644
--- a/app/assets/stylesheets/pages/issuable.scss
+++ b/app/assets/stylesheets/pages/issuable.scss
@@ -396,7 +396,7 @@
overflow: hidden;
&:hover {
- background-color: $sidebar-block-hover-color;
+ background-color: $gray-200;
}
&.issuable-sidebar-header {
@@ -754,7 +754,8 @@
margin-right: 10px;
min-width: 0;
- .issue-weight-icon {
+ .issue-weight-icon,
+ .issue-estimate-icon {
vertical-align: sub;
}
}
diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss
index 0dd25ec5360..0c349ab73a3 100644
--- a/app/assets/stylesheets/pages/issues.scss
+++ b/app/assets/stylesheets/pages/issues.scss
@@ -304,6 +304,72 @@ ul.related-merge-requests > li {
}
}
+.issue-sticky-header {
+ @include gl-left-0;
+ @include gl-w-full;
+ top: $header-height;
+
+ // collapsed right sidebar
+ @include media-breakpoint-up(sm) {
+ width: calc(100% - #{$gutter-collapsed-width});
+ }
+
+ .issue-sticky-header-text {
+ max-width: $limited-layout-width;
+ }
+}
+
+.with-performance-bar .issue-sticky-header {
+ top: $header-height + $performance-bar-height;
+}
+
+@include media-breakpoint-up(md) {
+ // collapsed left sidebar + collapsed right sidebar
+ .issue-sticky-header {
+ left: $contextual-sidebar-collapsed-width;
+ width: calc(100% - #{$contextual-sidebar-collapsed-width} - #{$gutter-collapsed-width});
+ }
+
+ // collapsed left sidebar + expanded right sidebar
+ .right-sidebar-expanded .issue-sticky-header {
+ width: calc(100% - #{$contextual-sidebar-collapsed-width} - #{$gutter-width});
+ }
+}
+
+@include media-breakpoint-up(xl) {
+ // expanded left sidebar + collapsed right sidebar
+ .issue-sticky-header {
+ left: $contextual-sidebar-width;
+ width: calc(100% - #{$contextual-sidebar-width} - #{$gutter-collapsed-width});
+ }
+
+ // collapsed left sidebar + collapsed right sidebar
+ .page-with-icon-sidebar .issue-sticky-header {
+ left: $contextual-sidebar-collapsed-width;
+ width: calc(100% - #{$contextual-sidebar-collapsed-width} - #{$gutter-collapsed-width});
+ }
+
+ // expanded left sidebar + expanded right sidebar
+ .right-sidebar-expanded .issue-sticky-header {
+ width: calc(100% - #{$contextual-sidebar-width} - #{$gutter-width});
+ }
+
+ // collapsed left sidebar + expanded right sidebar
+ .right-sidebar-expanded.page-with-icon-sidebar .issue-sticky-header {
+ width: calc(100% - #{$contextual-sidebar-collapsed-width} - #{$gutter-width});
+ }
+}
+
+.issuable-header-slide-enter-active,
+.issuable-header-slide-leave-active {
+ @include gl-transition-slow;
+}
+
+.issuable-header-slide-enter,
+.issuable-header-slide-leave-to {
+ transform: translateY(-100%);
+}
+
.issuable-list-root {
.gl-label-link {
text-decoration: none;
diff --git a/app/assets/stylesheets/pages/labels.scss b/app/assets/stylesheets/pages/labels.scss
index 22c1cb127cd..c3bac053a0a 100644
--- a/app/assets/stylesheets/pages/labels.scss
+++ b/app/assets/stylesheets/pages/labels.scss
@@ -86,7 +86,7 @@
justify-content: space-between;
padding: $gl-padding;
border-radius: $border-radius-default;
- border: 1px solid $gray-100;
+ border: 1px solid $gray-50;
&:last-child {
margin-bottom: 0;
@@ -276,7 +276,7 @@
}
.label-badge-gray {
- background-color: $gray-100;
+ background-color: $gray-50;
}
.label-links {
diff --git a/app/assets/stylesheets/pages/login.scss b/app/assets/stylesheets/pages/login.scss
index 67a8f689e9d..81a70470c65 100644
--- a/app/assets/stylesheets/pages/login.scss
+++ b/app/assets/stylesheets/pages/login.scss
@@ -96,14 +96,21 @@
margin: 0;
}
- .omniauth-btn {
- margin-bottom: $gl-padding;
+ form {
width: 48%;
- padding: $gl-padding-8;
+ padding: 0;
+ border: 0;
+ background: none;
+ margin-bottom: $gl-padding;
@include media-breakpoint-down(md) {
width: 100%;
}
+ }
+
+ .omniauth-btn {
+ width: 100%;
+ padding: $gl-padding-8;
img {
width: $default-icon-size;
diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss
index 57afe45a74b..c3f3dbc223b 100644
--- a/app/assets/stylesheets/pages/note_form.scss
+++ b/app/assets/stylesheets/pages/note_form.scss
@@ -253,11 +253,11 @@ table {
background-color: $gray-light;
border-radius: 0 0 3px 3px;
padding: $gl-padding;
- border-top: 1px solid $gray-100;
+ border-top: 1px solid $gray-50;
+ .new-note {
background-color: $gray-light;
- border-top: 1px solid $gray-100;
+ border-top: 1px solid $gray-50;
}
&.is-replying {
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index bed147aa3a7..e8cdfd717c0 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -5,7 +5,7 @@ $note-form-margin-left: 72px;
@mixin vertical-line($left) {
&::before {
content: '';
- border-left: 2px solid $gray-100;
+ border-left: 2px solid $gray-50;
position: absolute;
top: 0;
bottom: 0;
@@ -83,8 +83,8 @@ $note-form-margin-left: 72px;
.replies-toggle {
background-color: $gray-light;
padding: $gl-padding-8 $gl-padding;
- border-top: 1px solid $gray-100;
- border-bottom: 1px solid $gray-100;
+ border-top: 1px solid $gray-50;
+ border-bottom: 1px solid $gray-50;
.collapse-replies-btn:hover {
color: $blue-600;
diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss
index 154717f9776..43d766db9e0 100644
--- a/app/assets/stylesheets/pages/pipelines.scss
+++ b/app/assets/stylesheets/pages/pipelines.scss
@@ -669,7 +669,8 @@
.ci-action-icon-container {
position: absolute;
right: 5px;
- top: 5px;
+ top: 50%;
+ transform: translateY(-50%);
// Action Icons in big pipeline-graph nodes
&.ci-action-icon-wrapper {
@@ -920,7 +921,7 @@ button.mini-pipeline-graph-dropdown-toggle {
.ci-status-icon {
- @extend .append-right-8;
+ @include gl-mr-3;
position: relative;
diff --git a/app/assets/stylesheets/pages/profiles/preferences.scss b/app/assets/stylesheets/pages/profiles/preferences.scss
index 45e62913f37..3bab84af492 100644
--- a/app/assets/stylesheets/pages/profiles/preferences.scss
+++ b/app/assets/stylesheets/pages/profiles/preferences.scss
@@ -15,6 +15,10 @@
}
.application-theme {
+ $ui-dark-bg: #2e2e2e;
+ $ui-light-bg: #dfdfdf;
+ $ui-dark-mode-bg: #1f1f1f;
+
label {
margin: 0 $gl-padding-32 $gl-padding 0;
text-align: center;
@@ -60,11 +64,17 @@
}
&.ui-dark {
- background-color: $gray-900;
+ background-color: $ui-dark-bg;
+ border: solid 1px $border-color;
}
&.ui-light {
- background-color: $gray-200;
+ background-color: $ui-light-bg;
+ }
+
+ &.gl-dark {
+ background-color: $ui-dark-mode-bg;
+ border: solid 1px $border-color;
}
}
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index c0a1cf10fe4..438f6c2546e 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -396,7 +396,7 @@
margin-right: $gl-padding-4;
margin-bottom: $gl-padding-4;
color: $gl-text-color-secondary;
- background-color: $gray-100;
+ background-color: $gray-50;
line-height: $gl-btn-line-height;
&:hover {
diff --git a/app/assets/stylesheets/pages/prometheus.scss b/app/assets/stylesheets/pages/prometheus.scss
index 0f56b98a78d..26db1fb9f58 100644
--- a/app/assets/stylesheets/pages/prometheus.scss
+++ b/app/assets/stylesheets/pages/prometheus.scss
@@ -21,6 +21,14 @@
}
}
}
+
+ .links-section {
+ .gl-hover-text-blue-600-children:hover {
+ * {
+ @include gl-text-blue-600;
+ }
+ }
+ }
}
.draggable {
diff --git a/app/assets/stylesheets/pages/storage_quota.scss b/app/assets/stylesheets/pages/storage_quota.scss
new file mode 100644
index 00000000000..347bd1316c0
--- /dev/null
+++ b/app/assets/stylesheets/pages/storage_quota.scss
@@ -0,0 +1,17 @@
+.storage-type-usage {
+ &:first-child {
+ @include gl-rounded-top-left-base;
+ @include gl-rounded-bottom-left-base;
+ }
+
+ &:last-child {
+ @include gl-rounded-top-right-base;
+ @include gl-rounded-bottom-right-base;
+ }
+
+ &:not(:last-child) {
+ @include gl-border-r-2;
+ @include gl-border-r-solid;
+ @include gl-border-white;
+ }
+}
diff --git a/app/assets/stylesheets/themes/_dark.scss b/app/assets/stylesheets/themes/_dark.scss
new file mode 100644
index 00000000000..1f2a7645495
--- /dev/null
+++ b/app/assets/stylesheets/themes/_dark.scss
@@ -0,0 +1,134 @@
+$gray-10: #1f1f1f;
+$gray-50: #2e2e2e;
+$gray-100: #4f4f4f;
+$gray-200: #707070;
+$gray-300: #919191;
+$gray-400: #a7a7a7;
+$gray-500: #bababa;
+$gray-600: #ccc;
+$gray-700: #dfdfdf;
+$gray-800: #f2f2f2;
+$gray-900: #fafafa;
+$gray-950: #fff;
+
+$gl-gray-100: #333;
+$gl-gray-200: #555;
+$gl-gray-350: #666;
+$gl-gray-400: #777;
+$gl-gray-500: #999;
+$gl-gray-600: #aaa;
+$gl-gray-700: #ccc;
+$gl-gray-800: #ddd;
+
+$green-50: #072b15;
+$green-100: #0a4020;
+$green-200: #0e5a2d;
+$green-300: #12753a;
+$green-400: #168f48;
+$green-500: #1aaa55;
+$green-600: #37b96d;
+$green-700: #75d09b;
+$green-800: #b3e6c8;
+$green-900: #dcf5e7;
+$green-950: #f1fdf6;
+
+$blue-50: #0a2744;
+$blue-100: #0f3b66;
+$blue-200: #134a81;
+$blue-300: #17599c;
+$blue-400: #1b69b6;
+$blue-500: #1f78d1;
+$blue-600: #418cd8;
+$blue-700: #73afea;
+$blue-800: #b8d6f4;
+$blue-900: #e4f0fb;
+$blue-950: #f6fafe;
+
+$orange-50: #592800;
+$orange-100: #853c00;
+$orange-200: #a35200;
+$orange-300: #c26700;
+$orange-400: #de7e00;
+$orange-500: #fc9403;
+$orange-600: #fca429;
+$orange-700: #fdbc60;
+$orange-800: #fed69f;
+$orange-900: #fff1de;
+$orange-950: #fffaf4;
+
+$red-50: #4b140b;
+$red-100: #711e11;
+$red-200: #8b2615;
+$red-300: #a62d19;
+$red-400: #c0341d;
+$red-500: #db3b21;
+$red-600: #e05842;
+$red-700: #ea8271;
+$red-800: #f2b4a9;
+$red-900: #fbe5e1;
+$red-950: #fef6f5;
+
+$indigo-50: #1a1a40;
+$indigo-100: #292961;
+$indigo-200: #393982;
+$indigo-300: #4b4ba3;
+$indigo-400: #5b5bbd;
+$indigo-500: #6666c4;
+$indigo-600: #7c7ccc;
+$indigo-700: #a6a6de;
+$indigo-800: #d1d1f0;
+$indigo-900: #ebebfa;
+$indigo-950: #f7f7ff;
+
+$gray-lightest: #222;
+$gray-light: $gray-50;
+$gray-lighter: #303030;
+$gray-normal: #333;
+$gray-dark: $gray-100;
+$gray-darker: #4f4f4f;
+$gray-darkest: #c4c4c4;
+
+$black: #fff;
+$white: #333;
+$white-light: #2b2b2b;
+$white-normal: #333;
+$white-dark: #444;
+
+$border-white-light: $gray-900;
+$border-white-normal: $gray-900;
+
+$body-bg: $gray-50;
+$input-bg: $gray-100;
+$input-focus-bg: $gray-100;
+$input-color: $gray-900;
+$input-group-addon-bg: $gray-900;
+
+$tooltip-bg: $gray-800;
+$tooltip-color: $gray-10;
+
+$popover-color: $gray-950;
+$popover-box-shadow: 0 2px 3px 1px $gray-700;
+$popover-arrow-outer-color: $gray-800;
+
+$secondary: $gray-600;
+
+$issues-today-bg: #333838;
+$issues-today-border: #333a40;
+
+.gl-label {
+ filter: brightness(0.9) contrast(1.1);
+}
+
+// white-ish text for light labels
+// and for scoped label value (the right section)
+.gl-label-text-light.gl-label-text-light,
+.gl-label-text-dark + .gl-label-text-dark {
+ color: $gray-900;
+}
+
+// duplicated class as the original .atwho-view style is added later
+.atwho-view.atwho-view {
+ background-color: $white;
+ color: $gray-900;
+ border-color: $gray-800;
+}
diff --git a/app/assets/stylesheets/utilities.scss b/app/assets/stylesheets/utilities.scss
index 8cf5c533f1f..176d64272c2 100644
--- a/app/assets/stylesheets/utilities.scss
+++ b/app/assets/stylesheets/utilities.scss
@@ -81,68 +81,22 @@
.gl-h-32 { height: px-to-rem($grid-size * 4); }
.gl-h-64 { height: px-to-rem($grid-size * 8); }
-.gl-shim-h-2 {
- height: px-to-rem(4px);
-}
-
-.gl-shim-w-5 {
- width: px-to-rem(16px);
-}
-
-.gl-shim-pb-3 {
- padding-bottom: 8px;
-}
-
-.gl-shim-pt-5 {
- padding-top: 16px;
-}
-
-.gl-shim-mx-2 {
- margin-left: 4px;
- margin-right: 4px;
+.d-sm-table-column {
+ @include media-breakpoint-up(sm) {
+ display: table-column !important;
+ }
}
.gl-text-purple { color: $purple; }
-.gl-text-gray-800 { color: $gray-800; }
.gl-bg-purple-light { background-color: $purple-light; }
-// Classes using mixins coming from @gitlab-ui
-// can be removed once the mixins are added.
-// See https://gitlab.com/gitlab-org/gitlab/issues/36857 for more details.
-.gl-bg-blue-50 { @include gl-bg-blue-50; }
-.gl-bg-red-100 { @include gl-bg-red-100; }
-.gl-bg-orange-100 { @include gl-bg-orange-100; }
-.gl-bg-gray-50 { @include gl-bg-gray-50; }
-.gl-bg-gray-100 { @include gl-bg-gray-100; }
-.gl-bg-green-100 { @include gl-bg-green-100;}
-.gl-bg-blue-500 { @include gl-bg-blue-500; }
-.gl-bg-green-500 { @include gl-bg-green-500; }
-.gl-bg-theme-indigo-500 { @include gl-bg-theme-indigo-500; }
-.gl-bg-red-500 { @include gl-bg-red-500; }
-.gl-bg-orange-500 { @include gl-bg-orange-500; }
-
-.gl-text-blue-500 { @include gl-text-blue-500; }
-.gl-text-gray-500 { @include gl-text-gray-500; }
-.gl-text-gray-700 { @include gl-text-gray-700; }
-.gl-text-gray-900 { @include gl-text-gray-900; }
-.gl-text-red-700 { @include gl-text-red-700; }
-.gl-text-red-900 { @include gl-text-red-900; }
-.gl-text-orange-400 { @include gl-text-orange-400; }
-.gl-text-orange-500 { @include gl-text-orange-500; }
-.gl-text-orange-600 { @include gl-text-orange-600; }
-.gl-text-orange-700 { @include gl-text-orange-700; }
-.gl-text-green-500 { @include gl-text-green-500; }
-.gl-text-green-700 { @include gl-text-green-700; }
-
-.gl-align-items-center { @include gl-align-items-center; }
-
-.d-sm-table-column {
- @include media-breakpoint-up(sm) {
- display: table-column !important;
- }
+// move this to GitLab UI once onboarding experiment is considered a success
+.gl-py-8 {
+ padding-top: $gl-spacing-scale-8;
+ padding-bottom: $gl-spacing-scale-8;
}
-.gl-white-space-normal { @include gl-white-space-normal; }
-.gl-word-break-all { @include gl-word-break-all; }
-.gl-reset-line-height { @include gl-reset-line-height; }
-.gl-reset-text-align { @include gl-reset-text-align; }
+// move this to GitLab UI once onboarding experiment is considered a success
+.gl-pl-7 {
+ padding-left: $gl-spacing-scale-7;
+}
diff --git a/app/channels/application_cable/channel.rb b/app/channels/application_cable/channel.rb
index 9aec2305390..0de2b0185b5 100644
--- a/app/channels/application_cable/channel.rb
+++ b/app/channels/application_cable/channel.rb
@@ -2,5 +2,16 @@
module ApplicationCable
class Channel < ActionCable::Channel::Base
+ include Logging
+
+ private
+
+ def notification_payload(_)
+ super.merge!(params: params.except(:channel))
+ end
+
+ def request
+ connection.request
+ end
end
end
diff --git a/app/channels/application_cable/connection.rb b/app/channels/application_cable/connection.rb
index 87c833f3593..1361269f2a2 100644
--- a/app/channels/application_cable/connection.rb
+++ b/app/channels/application_cable/connection.rb
@@ -2,8 +2,12 @@
module ApplicationCable
class Connection < ActionCable::Connection::Base
+ include Logging
+
identified_by :current_user
+ public :request
+
def connect
self.current_user = find_user_from_session_store
end
@@ -18,5 +22,9 @@ module ApplicationCable
def session_id
Rack::Session::SessionId.new(cookies[Gitlab::Application.config.session_options[:key]])
end
+
+ def notification_payload(_)
+ super.merge!(params: request.params)
+ end
end
end
diff --git a/app/channels/application_cable/logging.rb b/app/channels/application_cable/logging.rb
new file mode 100644
index 00000000000..4152f8c779f
--- /dev/null
+++ b/app/channels/application_cable/logging.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module ApplicationCable
+ module Logging
+ private
+
+ def notification_payload(_)
+ super.merge!(
+ Labkit::Correlation::CorrelationId::LOG_KEY => request.request_id,
+ user_id: current_user&.id,
+ username: current_user&.username,
+ remote_ip: request.remote_ip,
+ ua: request.env['HTTP_USER_AGENT']
+ )
+ end
+ end
+end
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index 709834a2bec..94c82c25357 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -12,6 +12,10 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
before_action :whitelist_query_limiting, only: [:usage_data]
+ before_action only: [:ci_cd] do
+ push_frontend_feature_flag(:ci_instance_variables_ui, default_enabled: true)
+ end
+
VALID_SETTING_PANELS = %w(general integrations repository
ci_cd reporting metrics_and_profiling
network preferences).freeze
@@ -216,6 +220,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
[
*::ApplicationSettingsHelper.visible_attributes,
*::ApplicationSettingsHelper.external_authorization_service_attributes,
+ *ApplicationSetting.repository_storages_weighted_attributes,
:lets_encrypt_notification_email,
:lets_encrypt_terms_of_service_accepted,
:domain_blacklist_file,
diff --git a/app/controllers/admin/runners_controller.rb b/app/controllers/admin/runners_controller.rb
index 4639d8adfe0..2449fa3128c 100644
--- a/app/controllers/admin/runners_controller.rb
+++ b/app/controllers/admin/runners_controller.rb
@@ -4,7 +4,7 @@ class Admin::RunnersController < Admin::ApplicationController
before_action :runner, except: [:index, :tag_list]
def index
- finder = Admin::RunnersFinder.new(params: params)
+ finder = Ci::RunnersFinder.new(current_user: current_user, params: params)
@runners = finder.execute
@active_runners_count = Ci::Runner.online.count
@sort = finder.sort_key
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index ee42baa8326..fc0acd8f99a 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -241,7 +241,8 @@ class Admin::UsersController < Admin::ApplicationController
:theme_id,
:twitter,
:username,
- :website_url
+ :website_url,
+ :note
]
end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 54e3275662b..79a164a5574 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -12,6 +12,7 @@ class ApplicationController < ActionController::Base
include WorkhorseHelper
include EnforcesTwoFactorAuthentication
include WithPerformanceBar
+ include Gitlab::SearchContext::ControllerConcern
include SessionlessAuthentication
include SessionsHelper
include ConfirmEmailWarning
diff --git a/app/controllers/clusters/base_controller.rb b/app/controllers/clusters/base_controller.rb
index 8c13cc67be2..6b83400971d 100644
--- a/app/controllers/clusters/base_controller.rb
+++ b/app/controllers/clusters/base_controller.rb
@@ -7,7 +7,7 @@ class Clusters::BaseController < ApplicationController
before_action :authorize_read_cluster!
before_action do
- push_frontend_feature_flag(:managed_apps_local_tiller)
+ push_frontend_feature_flag(:managed_apps_local_tiller, clusterable)
end
helper_method :clusterable
diff --git a/app/controllers/clusters/clusters_controller.rb b/app/controllers/clusters/clusters_controller.rb
index aa39d430b24..46dec5f3287 100644
--- a/app/controllers/clusters/clusters_controller.rb
+++ b/app/controllers/clusters/clusters_controller.rb
@@ -23,6 +23,7 @@ class Clusters::ClustersController < Clusters::BaseController
respond_to do |format|
format.html
format.json do
+ Gitlab::PollingInterval.set_header(response, interval: STATUS_POLLING_INTERVAL)
serializer = ClusterSerializer.new(current_user: current_user)
render json: {
diff --git a/app/controllers/concerns/enforces_two_factor_authentication.rb b/app/controllers/concerns/enforces_two_factor_authentication.rb
index d486d734db8..6c443611a60 100644
--- a/app/controllers/concerns/enforces_two_factor_authentication.rb
+++ b/app/controllers/concerns/enforces_two_factor_authentication.rb
@@ -23,8 +23,7 @@ module EnforcesTwoFactorAuthentication
def two_factor_authentication_required?
Gitlab::CurrentSettings.require_two_factor_authentication? ||
- current_user.try(:require_two_factor_authentication_from_group?) ||
- current_user.try(:ultraauth_user?)
+ current_user.try(:require_two_factor_authentication_from_group?)
end
def current_user_requires_two_factor?
diff --git a/app/controllers/concerns/find_snippet.rb b/app/controllers/concerns/find_snippet.rb
new file mode 100644
index 00000000000..d51f1a1b3ad
--- /dev/null
+++ b/app/controllers/concerns/find_snippet.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module FindSnippet
+ extend ActiveSupport::Concern
+ include Gitlab::Utils::StrongMemoize
+
+ private
+
+ # rubocop:disable CodeReuse/ActiveRecord
+ def snippet
+ strong_memoize(:snippet) do
+ snippet_klass.inc_relations_for_view.find_by(id: snippet_id)
+ end
+ end
+ # rubocop:enable CodeReuse/ActiveRecord
+
+ def snippet_klass
+ raise NotImplementedError
+ end
+
+ def snippet_id
+ params[:id]
+ end
+end
diff --git a/app/controllers/concerns/integrations_actions.rb b/app/controllers/concerns/integrations_actions.rb
index ff283f9bb62..cc9db7936e8 100644
--- a/app/controllers/concerns/integrations_actions.rb
+++ b/app/controllers/concerns/integrations_actions.rb
@@ -16,10 +16,12 @@ module IntegrationsActions
def update
saved = integration.update(service_params[:service])
+ overwrite = Gitlab::Utils.to_boolean(params[:overwrite])
respond_to do |format|
format.html do
if saved
+ PropagateIntegrationWorker.perform_async(integration.id, overwrite)
redirect_to scoped_edit_integration_path(integration), notice: success_message
else
render 'shared/integrations/edit'
@@ -34,6 +36,10 @@ module IntegrationsActions
end
end
+ def custom_integration_projects
+ Project.with_custom_integration_compared_to(integration).page(params[:page]).per(20)
+ end
+
def test
render json: {}, status: :ok
end
diff --git a/app/controllers/concerns/issuable_actions.rb b/app/controllers/concerns/issuable_actions.rb
index 0b1b3f2bcba..98fa8202e25 100644
--- a/app/controllers/concerns/issuable_actions.rb
+++ b/app/controllers/concerns/issuable_actions.rb
@@ -16,19 +16,6 @@ module IssuableActions
end
end
- def permitted_keys
- [
- :issuable_ids,
- :assignee_id,
- :milestone_id,
- :state_event,
- :subscription_event,
- label_ids: [],
- add_label_ids: [],
- remove_label_ids: []
- ]
- end
-
def show
respond_to do |format|
format.html do
@@ -221,10 +208,20 @@ module IssuableActions
end
def bulk_update_params
- permitted_keys_array = permitted_keys.dup
- permitted_keys_array << { assignee_ids: [] }
+ params.require(:update).permit(bulk_update_permitted_keys)
+ end
- params.require(:update).permit(permitted_keys_array)
+ def bulk_update_permitted_keys
+ [
+ :issuable_ids,
+ :assignee_id,
+ :milestone_id,
+ :state_event,
+ :subscription_event,
+ assignee_ids: [],
+ add_label_ids: [],
+ remove_label_ids: []
+ ]
end
def resource_name
diff --git a/app/controllers/concerns/issuable_collections.rb b/app/controllers/concerns/issuable_collections.rb
index 5aa00af8910..9ef067e8797 100644
--- a/app/controllers/concerns/issuable_collections.rb
+++ b/app/controllers/concerns/issuable_collections.rb
@@ -5,7 +5,6 @@ module IssuableCollections
include PaginatedCollection
include SortingHelper
include SortingPreference
- include Gitlab::IssuableMetadata
include Gitlab::Utils::StrongMemoize
included do
@@ -44,7 +43,7 @@ module IssuableCollections
def set_pagination
@issuables = @issuables.page(params[:page])
@issuables = per_page_for_relative_position if params[:sort] == 'relative_position'
- @issuable_meta_data = issuable_meta_data(@issuables, collection_type, current_user)
+ @issuable_meta_data = Gitlab::IssuableMetadata.new(current_user, @issuables).data
@total_pages = issuable_page_count(@issuables)
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
diff --git a/app/controllers/concerns/issuable_collections_action.rb b/app/controllers/concerns/issuable_collections_action.rb
index 78b3c6771b3..e3ac117660b 100644
--- a/app/controllers/concerns/issuable_collections_action.rb
+++ b/app/controllers/concerns/issuable_collections_action.rb
@@ -11,7 +11,7 @@ module IssuableCollectionsAction
.non_archived
.page(params[:page])
- @issuable_meta_data = issuable_meta_data(@issues, collection_type, current_user)
+ @issuable_meta_data = Gitlab::IssuableMetadata.new(current_user, @issues).data
respond_to do |format|
format.html
@@ -22,7 +22,7 @@ module IssuableCollectionsAction
def merge_requests
@merge_requests = issuables_collection.page(params[:page])
- @issuable_meta_data = issuable_meta_data(@merge_requests, collection_type, current_user)
+ @issuable_meta_data = Gitlab::IssuableMetadata.new(current_user, @merge_requests).data
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
diff --git a/app/controllers/concerns/known_sign_in.rb b/app/controllers/concerns/known_sign_in.rb
index 97883d8d08c..c0b9605de58 100644
--- a/app/controllers/concerns/known_sign_in.rb
+++ b/app/controllers/concerns/known_sign_in.rb
@@ -26,6 +26,6 @@ module KnownSignIn
end
def notify_user
- current_user.notification_service.unknown_sign_in(current_user, request.remote_ip)
+ current_user.notification_service.unknown_sign_in(current_user, request.remote_ip, current_user.current_sign_in_at)
end
end
diff --git a/app/controllers/concerns/milestone_actions.rb b/app/controllers/concerns/milestone_actions.rb
index dbc575a1487..29138e7b014 100644
--- a/app/controllers/concerns/milestone_actions.rb
+++ b/app/controllers/concerns/milestone_actions.rb
@@ -51,13 +51,7 @@ module MilestoneActions
}
end
- # rubocop:disable Gitlab/ModuleWithInstanceVariables
def milestone_redirect_path
- if @milestone.global_milestone?
- url_for(action: :show, title: @milestone.title)
- else
- url_for(action: :show)
- end
+ url_for(action: :show)
end
- # rubocop:enable Gitlab/ModuleWithInstanceVariables
end
diff --git a/app/controllers/concerns/notes_actions.rb b/app/controllers/concerns/notes_actions.rb
index d4b0d3b2674..d3dfb1813e4 100644
--- a/app/controllers/concerns/notes_actions.rb
+++ b/app/controllers/concerns/notes_actions.rb
@@ -13,9 +13,7 @@ module NotesActions
end
def index
- current_fetched_at = Time.current.to_i
-
- notes_json = { notes: [], last_fetched_at: current_fetched_at }
+ notes_json = { notes: [], last_fetched_at: Time.current.to_i }
notes = notes_finder
.execute
@@ -24,7 +22,7 @@ module NotesActions
if notes_filter != UserPreference::NOTES_FILTERS[:only_comments]
notes =
ResourceEvents::MergeIntoNotesService
- .new(noteable, current_user, last_fetched_at: current_fetched_at)
+ .new(noteable, current_user, last_fetched_at: last_fetched_at)
.execute(notes)
end
diff --git a/app/controllers/concerns/preview_markdown.rb b/app/controllers/concerns/preview_markdown.rb
index ba15d611c0d..2916762e31f 100644
--- a/app/controllers/concerns/preview_markdown.rb
+++ b/app/controllers/concerns/preview_markdown.rb
@@ -32,7 +32,7 @@ module PreviewMarkdown
def markdown_context_params
case controller_name
- when 'wikis' then { pipeline: :wiki, project_wiki: @project_wiki, page_slug: params[:id] }
+ when 'wikis' then { pipeline: :wiki, wiki: wiki, page_slug: params[:id] }
when 'snippets' then { skip_project_check: true }
when 'groups' then { group: group }
when 'projects' then projects_filter_params
diff --git a/app/controllers/concerns/service_params.rb b/app/controllers/concerns/service_params.rb
index e2c83f9a069..e78fa8f8250 100644
--- a/app/controllers/concerns/service_params.rb
+++ b/app/controllers/concerns/service_params.rb
@@ -6,6 +6,7 @@ module ServiceParams
ALLOWED_PARAMS_CE = [
:active,
:add_pusher,
+ :alert_events,
:api_key,
:api_url,
:api_version,
@@ -28,6 +29,8 @@ module ServiceParams
:drone_url,
:enable_ssl_verification,
:external_wiki_url,
+ :google_iap_service_account_json,
+ :google_iap_audience_client_id,
# We're using `issues_events` and `merge_requests_events`
# in the view so we still need to explicitly state them
# here. `Service#event_names` would only give
diff --git a/app/controllers/concerns/snippet_authorizations.rb b/app/controllers/concerns/snippet_authorizations.rb
new file mode 100644
index 00000000000..9bbb0cc6faa
--- /dev/null
+++ b/app/controllers/concerns/snippet_authorizations.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module SnippetAuthorizations
+ extend ActiveSupport::Concern
+
+ private
+
+ def authorize_read_snippet!
+ return render_404 unless can?(current_user, :read_snippet, snippet)
+ end
+
+ def authorize_update_snippet!
+ return render_404 unless can?(current_user, :update_snippet, snippet)
+ end
+
+ def authorize_admin_snippet!
+ return render_404 unless can?(current_user, :admin_snippet, snippet)
+ end
+
+ def authorize_create_snippet!
+ return render_404 unless can?(current_user, :create_snippet)
+ end
+end
diff --git a/app/controllers/concerns/snippets_actions.rb b/app/controllers/concerns/snippets_actions.rb
index e78723bdda2..51fc12398d9 100644
--- a/app/controllers/concerns/snippets_actions.rb
+++ b/app/controllers/concerns/snippets_actions.rb
@@ -3,9 +3,18 @@
module SnippetsActions
extend ActiveSupport::Concern
include SendsBlob
+ include RendersNotes
+ include RendersBlob
+ include PaginatedCollection
+ include Gitlab::NoteableMetadata
included do
+ skip_before_action :verify_authenticity_token,
+ if: -> { action_name == 'show' && js_request? }
+
before_action :redirect_if_binary, only: [:edit, :update]
+
+ respond_to :html
end
def edit
@@ -43,6 +52,58 @@ module SnippetsActions
request.format.js?
end
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ def show
+ conditionally_expand_blob(blob)
+
+ respond_to do |format|
+ format.html do
+ @note = Note.new(noteable: @snippet, project: @snippet.project)
+ @noteable = @snippet
+
+ @discussions = @snippet.discussions
+ @notes = prepare_notes_for_rendering(@discussions.flat_map(&:notes), @noteable)
+ render 'show'
+ end
+
+ format.json do
+ render_blob_json(blob)
+ end
+
+ format.js do
+ if @snippet.embeddable?
+ render 'shared/snippets/show'
+ else
+ head :not_found
+ end
+ end
+ end
+ end
+
+ def update
+ update_params = snippet_params.merge(spammable_params)
+
+ service_response = Snippets::UpdateService.new(@snippet.project, current_user, update_params).execute(@snippet)
+ @snippet = service_response.payload[:snippet]
+
+ handle_repository_error(:edit)
+ end
+
+ def destroy
+ service_response = Snippets::DestroyService.new(current_user, @snippet).execute
+
+ if service_response.success?
+ redirect_to gitlab_dashboard_snippets_path(@snippet), status: :found
+ elsif service_response.http_status == 403
+ access_denied!
+ else
+ redirect_to gitlab_snippet_path(@snippet),
+ status: :found,
+ alert: service_response.message
+ end
+ end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
+
private
def content_disposition
diff --git a/app/controllers/concerns/wiki_actions.rb b/app/controllers/concerns/wiki_actions.rb
new file mode 100644
index 00000000000..b4b4fd84c37
--- /dev/null
+++ b/app/controllers/concerns/wiki_actions.rb
@@ -0,0 +1,232 @@
+# frozen_string_literal: true
+
+module WikiActions
+ include SendsBlob
+ include Gitlab::Utils::StrongMemoize
+ extend ActiveSupport::Concern
+
+ included do
+ before_action :authorize_read_wiki!
+ before_action :authorize_create_wiki!, only: [:edit, :create]
+ before_action :authorize_admin_wiki!, only: :destroy
+
+ before_action :wiki
+ before_action :page, only: [:show, :edit, :update, :history, :destroy]
+ before_action :load_sidebar, except: [:pages]
+
+ before_action only: [:show, :edit, :update] do
+ @valid_encoding = valid_encoding?
+ end
+
+ before_action only: [:edit, :update], unless: :valid_encoding? do
+ redirect_to wiki_page_path(wiki, page)
+ end
+ end
+
+ def new
+ redirect_to wiki_page_path(wiki, SecureRandom.uuid, random_title: true)
+ end
+
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ def pages
+ @wiki_pages = Kaminari.paginate_array(
+ wiki.list_pages(sort: params[:sort], direction: params[:direction])
+ ).page(params[:page])
+
+ @wiki_entries = WikiPage.group_by_directory(@wiki_pages)
+
+ render 'shared/wikis/pages'
+ end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
+
+ # `#show` handles a number of scenarios:
+ #
+ # - If `id` matches a WikiPage, then show the wiki page.
+ # - If `id` is a file in the wiki repository, then send the file.
+ # - If we know the user wants to create a new page with the given `id`,
+ # then display a create form.
+ # - Otherwise show the empty wiki page and invite the user to create a page.
+ #
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ def show
+ if page
+ set_encoding_error unless valid_encoding?
+
+ # Assign vars expected by MarkupHelper
+ @ref = params[:version_id]
+ @path = page.path
+
+ render 'shared/wikis/show'
+ elsif file_blob
+ send_blob(wiki.repository, file_blob, allow_caching: container.public?)
+ elsif show_create_form?
+ # Assign a title to the WikiPage unless `id` is a randomly generated slug from #new
+ title = params[:id] unless params[:random_title].present?
+
+ @page = build_page(title: title)
+
+ render 'shared/wikis/edit'
+ else
+ render 'shared/wikis/empty'
+ end
+ end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
+
+ def edit
+ render 'shared/wikis/edit'
+ end
+
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ def update
+ return render('shared/wikis/empty') unless can?(current_user, :create_wiki, container)
+
+ @page = WikiPages::UpdateService.new(container: container, current_user: current_user, params: wiki_params).execute(page)
+
+ if page.valid?
+ redirect_to(
+ wiki_page_path(wiki, page),
+ notice: _('Wiki was successfully updated.')
+ )
+ else
+ render 'shared/wikis/edit'
+ end
+ rescue WikiPage::PageChangedError, WikiPage::PageRenameError, Gitlab::Git::Wiki::OperationError => e
+ @error = e
+ render 'shared/wikis/edit'
+ end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
+
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ def create
+ @page = WikiPages::CreateService.new(container: container, current_user: current_user, params: wiki_params).execute
+
+ if page.persisted?
+ redirect_to(
+ wiki_page_path(wiki, page),
+ notice: _('Wiki was successfully updated.')
+ )
+ else
+ render 'shared/wikis/edit'
+ end
+ rescue Gitlab::Git::Wiki::OperationError => e
+ @page = build_page(wiki_params)
+ @error = e
+ render 'shared/wikis/edit'
+ end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
+
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ def history
+ if page
+ @page_versions = Kaminari.paginate_array(page.versions(page: params[:page].to_i),
+ total_count: page.count_versions)
+ .page(params[:page])
+
+ render 'shared/wikis/history'
+ else
+ redirect_to(
+ wiki_path(wiki),
+ notice: _("Page not found")
+ )
+ end
+ end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
+
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ def destroy
+ WikiPages::DestroyService.new(container: container, current_user: current_user).execute(page)
+
+ redirect_to wiki_path(wiki),
+ status: :found,
+ notice: _("Page was successfully deleted")
+ rescue Gitlab::Git::Wiki::OperationError => e
+ @error = e
+ render 'shared/wikis/edit'
+ end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
+
+ private
+
+ def container
+ raise NotImplementedError
+ end
+
+ def show_create_form?
+ can?(current_user, :create_wiki, container) &&
+ page.nil? &&
+ # Always show the create form when the wiki has had at least one page created.
+ # Otherwise, we only show the form when the user has navigated from
+ # the 'empty wiki' page
+ (wiki.exists? || params[:view] == 'create')
+ end
+
+ def wiki
+ strong_memoize(:wiki) do
+ wiki = Wiki.for_container(container, current_user)
+
+ # Call #wiki to make sure the Wiki Repo is initialized
+ wiki.wiki
+
+ wiki
+ end
+ rescue Wiki::CouldNotCreateWikiError
+ flash[:notice] = _("Could not create Wiki Repository at this time. Please try again later.")
+ redirect_to container
+ false
+ end
+
+ def page
+ strong_memoize(:page) do
+ wiki.find_page(*page_params)
+ end
+ end
+
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ def load_sidebar
+ @sidebar_page = wiki.find_sidebar(params[:version_id])
+
+ unless @sidebar_page # Fallback to default sidebar
+ @sidebar_wiki_entries, @sidebar_limited = wiki.sidebar_entries
+ end
+ end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
+
+ def wiki_params
+ params.require(:wiki).permit(:title, :content, :format, :message, :last_commit_sha)
+ end
+
+ def build_page(args = {})
+ WikiPage.new(wiki).tap do |page|
+ page.update_attributes(args) # rubocop:disable Rails/ActiveRecordAliases
+ end
+ end
+
+ def page_params
+ keys = [:id]
+ keys << :version_id if params[:action] == 'show'
+
+ params.values_at(*keys)
+ end
+
+ def valid_encoding?
+ page_encoding == Encoding::UTF_8
+ end
+
+ def page_encoding
+ strong_memoize(:page_encoding) { page&.content&.encoding }
+ end
+
+ def set_encoding_error
+ flash.now[:notice] = _("The content of this page is not encoded in UTF-8. Edits can only be made via the Git repository.")
+ end
+
+ def file_blob
+ strong_memoize(:file_blob) do
+ commit = wiki.repository.commit(wiki.default_branch)
+
+ next unless commit
+
+ wiki.repository.blob_at(commit.id, params[:id])
+ end
+ end
+end
diff --git a/app/controllers/concerns/workhorse_import_export_upload.rb b/app/controllers/concerns/workhorse_import_export_upload.rb
new file mode 100644
index 00000000000..3c52f4d7adf
--- /dev/null
+++ b/app/controllers/concerns/workhorse_import_export_upload.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module WorkhorseImportExportUpload
+ extend ActiveSupport::Concern
+ include WorkhorseRequest
+
+ included do
+ skip_before_action :verify_authenticity_token, only: %i[authorize]
+ before_action :verify_workhorse_api!, only: %i[authorize]
+ end
+
+ def authorize
+ set_workhorse_internal_api_content_type
+
+ authorized = ImportExportUploader.workhorse_authorize(
+ has_length: false,
+ maximum_size: Gitlab::CurrentSettings.max_import_size.megabytes
+ )
+
+ render json: authorized
+ rescue SocketError
+ render json: _("Error uploading file"), status: :internal_server_error
+ end
+
+ private
+
+ def file_is_valid?(file)
+ return false unless file.is_a?(::UploadedFile)
+
+ ImportExportUploader::EXTENSION_WHITELIST
+ .include?(File.extname(file.original_filename).delete('.'))
+ end
+end
diff --git a/app/controllers/dashboard/milestones_controller.rb b/app/controllers/dashboard/milestones_controller.rb
index d34a07324da..14f9a026688 100644
--- a/app/controllers/dashboard/milestones_controller.rb
+++ b/app/controllers/dashboard/milestones_controller.rb
@@ -1,48 +1,32 @@
# frozen_string_literal: true
class Dashboard::MilestonesController < Dashboard::ApplicationController
- include MilestoneActions
-
before_action :projects
before_action :groups, only: :index
- before_action :milestone, only: [:show, :merge_requests, :participants, :labels]
def index
respond_to do |format|
format.html do
- @milestone_states = Milestone.states_count(@projects.select(:id), @groups.select(:id))
- @milestones = Kaminari.paginate_array(milestones).page(params[:page])
+ @milestone_states = Milestone.states_count(@projects.select(:id), groups.select(:id))
+ @milestones = milestones.page(params[:page])
end
format.json do
- render json: milestones
+ render json: milestones.to_json(only: [:id, :title], methods: :name)
end
end
end
- def show
- end
-
private
- def group_milestones
- DashboardGroupMilestone.build_collection(groups, params)
- end
-
- # See [#39545](https://gitlab.com/gitlab-org/gitlab-foss/issues/39545) for info about the deprecation of dynamic milestones
- def dynamic_milestones
- DashboardMilestone.build_collection(@projects, params)
- end
-
def milestones
- @milestones = group_milestones + dynamic_milestones
- end
-
- def milestone
- @milestone = DashboardMilestone.build(@projects, params[:title])
- render_404 unless @milestone
+ MilestonesFinder.new(search_params).execute
end
def groups
@groups ||= GroupsFinder.new(current_user, all_available: false).execute
end
+
+ def search_params
+ params.permit(:state, :search_title).merge(group_ids: groups, project_ids: projects)
+ end
end
diff --git a/app/controllers/dashboard/todos_controller.rb b/app/controllers/dashboard/todos_controller.rb
index ebee8e9094e..8a8064b24c2 100644
--- a/app/controllers/dashboard/todos_controller.rb
+++ b/app/controllers/dashboard/todos_controller.rb
@@ -17,7 +17,9 @@ class Dashboard::TodosController < Dashboard::ApplicationController
end
def destroy
- TodoService.new.mark_todos_as_done_by_ids(params[:id], current_user)
+ todo = current_user.todos.find(params[:id])
+
+ TodoService.new.resolve_todo(todo, current_user, resolved_by_action: :mark_done)
respond_to do |format|
format.html do
@@ -31,7 +33,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController
end
def destroy_all
- updated_ids = TodoService.new.mark_todos_as_done(@todos, current_user)
+ updated_ids = TodoService.new.resolve_todos(@todos, current_user, resolved_by_action: :mark_all_done)
respond_to do |format|
format.html { redirect_to dashboard_todos_path, status: :found, notice: _('Everything on your to-do list is marked as done.') }
@@ -41,13 +43,13 @@ class Dashboard::TodosController < Dashboard::ApplicationController
end
def restore
- TodoService.new.mark_todos_as_pending_by_ids(params[:id], current_user)
+ TodoService.new.restore_todo(current_user.todos.find(params[:id]), current_user)
render json: todos_counts
end
def bulk_restore
- TodoService.new.mark_todos_as_pending_by_ids(params[:ids], current_user)
+ TodoService.new.restore_todos(current_user.todos.for_ids(params[:ids]), current_user)
render json: todos_counts
end
diff --git a/app/controllers/groups/boards_controller.rb b/app/controllers/groups/boards_controller.rb
index a9bd24890ee..c618ee8566a 100644
--- a/app/controllers/groups/boards_controller.rb
+++ b/app/controllers/groups/boards_controller.rb
@@ -9,6 +9,7 @@ class Groups::BoardsController < Groups::ApplicationController
before_action do
push_frontend_feature_flag(:multi_select_board, default_enabled: true)
push_frontend_feature_flag(:sfc_issue_boards, default_enabled: true)
+ push_frontend_feature_flag(:boards_with_swimlanes, group, default_enabled: false)
end
private
diff --git a/app/controllers/groups/group_links_controller.rb b/app/controllers/groups/group_links_controller.rb
index 52ee69edaa5..c395b93f4e7 100644
--- a/app/controllers/groups/group_links_controller.rb
+++ b/app/controllers/groups/group_links_controller.rb
@@ -27,7 +27,7 @@ class Groups::GroupLinksController < Groups::ApplicationController
end
def destroy
- Groups::GroupLinks::DestroyService.new(nil, nil).execute(@group_link)
+ Groups::GroupLinks::DestroyService.new(group, current_user).execute(@group_link)
respond_to do |format|
format.html do
diff --git a/app/controllers/groups/imports_controller.rb b/app/controllers/groups/imports_controller.rb
new file mode 100644
index 00000000000..b611685f9bc
--- /dev/null
+++ b/app/controllers/groups/imports_controller.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class Groups::ImportsController < Groups::ApplicationController
+ include ContinueParams
+
+ def show
+ if @group.import_state.nil? || @group.import_state.finished?
+ if continue_params[:to]
+ redirect_to continue_params[:to], notice: continue_params[:notice]
+ else
+ redirect_to group_path(@group), notice: s_('GroupImport|The group was successfully imported.')
+ end
+ elsif @group.import_state.failed?
+ redirect_to new_group_path(@group), alert: s_('GroupImport|Failed to import group.')
+ else
+ flash.now[:notice] = continue_params[:notice_now]
+ end
+ end
+end
diff --git a/app/controllers/groups/milestones_controller.rb b/app/controllers/groups/milestones_controller.rb
index 8cfbd293597..df3fb6b67c2 100644
--- a/app/controllers/groups/milestones_controller.rb
+++ b/app/controllers/groups/milestones_controller.rb
@@ -6,17 +6,17 @@ class Groups::MilestonesController < Groups::ApplicationController
before_action :milestone, only: [:edit, :show, :update, :merge_requests, :participants, :labels, :destroy]
before_action :authorize_admin_milestones!, only: [:edit, :new, :create, :update, :destroy]
before_action do
- push_frontend_feature_flag(:burnup_charts)
+ push_frontend_feature_flag(:burnup_charts, @group)
end
def index
respond_to do |format|
format.html do
- @milestone_states = Milestone.states_count(group_projects_with_access, [group])
- @milestones = Kaminari.paginate_array(milestones).page(params[:page])
+ @milestone_states = Milestone.states_count(group_projects_with_access.without_order, [group])
+ @milestones = milestones.page(params[:page])
end
format.json do
- render json: milestones.map { |m| m.for_display.slice(:id, :title, :name) }
+ render json: milestones.to_json(only: [:id, :title], methods: :name)
end
end
end
@@ -29,7 +29,7 @@ class Groups::MilestonesController < Groups::ApplicationController
@milestone = Milestones::CreateService.new(group, current_user, milestone_params).execute
if @milestone.persisted?
- redirect_to milestone_path
+ redirect_to milestone_path(@milestone)
else
render "new"
end
@@ -39,23 +39,15 @@ class Groups::MilestonesController < Groups::ApplicationController
end
def edit
- render_404 if @milestone.legacy_group_milestone?
end
def update
- # Keep this compatible with legacy group milestones where we have to update
- # all projects milestones states at once.
- milestones, update_params = get_milestones_for_update
- milestones.each do |milestone|
- Milestones::UpdateService.new(milestone.resource_parent, current_user, update_params).execute(milestone)
- end
+ Milestones::UpdateService.new(@milestone.parent, current_user, milestone_params).execute(@milestone)
- redirect_to milestone_path
+ redirect_to milestone_path(@milestone)
end
def destroy
- return render_404 if @milestone.legacy_group_milestone?
-
Milestones::DestroyService.new(group, current_user).execute(@milestone)
respond_to do |format|
@@ -66,14 +58,6 @@ class Groups::MilestonesController < Groups::ApplicationController
private
- def get_milestones_for_update
- if @milestone.legacy_group_milestone?
- [@milestone.milestones, legacy_milestone_params]
- else
- [[@milestone], milestone_params]
- end
- end
-
def authorize_admin_milestones!
return render_404 unless can?(current_user, :admin_milestone, group)
end
@@ -82,27 +66,21 @@ class Groups::MilestonesController < Groups::ApplicationController
params.require(:milestone).permit(:title, :description, :start_date, :due_date, :state_event)
end
- def legacy_milestone_params
- params.require(:milestone).permit(:state_event)
+ def milestones
+ MilestonesFinder.new(search_params).execute
end
- def milestone_path
- if @milestone.legacy_group_milestone?
- group_milestone_path(group, @milestone.safe_title, title: @milestone.title)
- else
- group_milestone_path(group, @milestone.iid)
- end
+ def milestone
+ @milestone = group.milestones.find_by_iid(params[:id])
+
+ render_404 unless @milestone
end
- def milestones
- milestones = MilestonesFinder.new(search_params).execute
+ def search_params
+ groups = request.format.json? ? group_ids(include_ancestors: true) : group_ids
@sort = params[:sort] || 'due_date_asc'
- MilestoneArray.sort(milestones + legacy_milestones, @sort)
- end
-
- def legacy_milestones
- GroupMilestone.build_collection(group, group_projects_with_access, params)
+ params.permit(:state, :search_title).merge(sort: @sort, group_ids: groups, project_ids: group_projects_with_access)
end
def group_projects_with_access
@@ -116,23 +94,6 @@ class Groups::MilestonesController < Groups::ApplicationController
group.self_and_descendants.public_or_visible_to_user(current_user).select(:id)
end
end
-
- def milestone
- @milestone =
- if params[:title]
- GroupMilestone.build(group, group_projects_with_access, params[:title])
- else
- group.milestones.find_by_iid(params[:id])
- end
-
- render_404 unless @milestone
- end
-
- def search_params
- groups = request.format.json? ? group_ids(include_ancestors: true) : group_ids
-
- params.permit(:state, :search_title).merge(group_ids: groups)
- end
end
Groups::MilestonesController.prepend_if_ee('EE::Groups::MilestonesController')
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index d5f2239b16a..fba374dbb44 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -57,6 +57,8 @@ class GroupsController < Groups::ApplicationController
@group = Groups::CreateService.new(current_user, group_params).execute
if @group.persisted?
+ track_experiment_event(:onboarding_issues, 'created_namespace')
+
notice = if @group.chat_team.present?
"Group '#{@group.name}' and its Mattermost team were successfully created."
else
@@ -72,7 +74,11 @@ class GroupsController < Groups::ApplicationController
def show
respond_to do |format|
format.html do
- render_show_html
+ if @group.import_state&.in_progress?
+ redirect_to group_import_path(@group)
+ else
+ render_show_html
+ end
end
format.atom do
@@ -264,11 +270,12 @@ class GroupsController < Groups::ApplicationController
def export_rate_limit
prefixed_action = "group_#{params[:action]}".to_sym
- if Gitlab::ApplicationRateLimiter.throttled?(prefixed_action, scope: [current_user, prefixed_action, @group])
+ scope = params[:action] == :download_export ? @group : nil
+
+ if Gitlab::ApplicationRateLimiter.throttled?(prefixed_action, scope: [current_user, scope].compact)
Gitlab::ApplicationRateLimiter.log_request(request, "#{prefixed_action}_request_limit".to_sym, current_user)
- flash[:alert] = _('This endpoint has been requested too many times. Try again later.')
- redirect_to edit_group_path(@group)
+ render plain: _('This endpoint has been requested too many times. Try again later.'), status: :too_many_requests
end
end
diff --git a/app/controllers/ide_controller.rb b/app/controllers/ide_controller.rb
index 8a838db04f9..2bf7bdd1ae0 100644
--- a/app/controllers/ide_controller.rb
+++ b/app/controllers/ide_controller.rb
@@ -6,9 +6,11 @@ class IdeController < ApplicationController
include ClientsidePreviewCSP
include StaticObjectExternalStorageCSP
+ before_action do
+ push_frontend_feature_flag(:build_service_proxy)
+ end
+
def index
Gitlab::UsageDataCounters::WebIdeCounter.increment_views_count
end
end
-
-IdeController.prepend_if_ee('EE::IdeController')
diff --git a/app/controllers/import/base_controller.rb b/app/controllers/import/base_controller.rb
index 04919a4b9d0..afdea4f7c9d 100644
--- a/app/controllers/import/base_controller.rb
+++ b/app/controllers/import/base_controller.rb
@@ -1,10 +1,86 @@
# frozen_string_literal: true
class Import::BaseController < ApplicationController
+ include ActionView::Helpers::SanitizeHelper
+
before_action :import_rate_limit, only: [:create]
+ def status
+ respond_to do |format|
+ format.json do
+ render json: { imported_projects: serialized_imported_projects,
+ provider_repos: serialized_provider_repos,
+ incompatible_repos: serialized_incompatible_repos,
+ namespaces: serialized_namespaces }
+ end
+ format.html
+ end
+ end
+
+ def realtime_changes
+ Gitlab::PollingInterval.set_header(response, interval: 3_000)
+
+ render json: already_added_projects.to_json(only: [:id], methods: [:import_status])
+ end
+
+ protected
+
+ def importable_repos
+ raise NotImplementedError
+ end
+
+ def incompatible_repos
+ []
+ end
+
+ def provider_name
+ raise NotImplementedError
+ end
+
+ def provider_url
+ raise NotImplementedError
+ end
+
private
+ def filter_attribute
+ :name
+ end
+
+ def sanitized_filter_param
+ @filter ||= sanitize(params[:filter])
+ end
+
+ def filtered(collection)
+ return collection unless sanitized_filter_param
+
+ collection.select { |item| item[filter_attribute].include?(sanitized_filter_param) }
+ end
+
+ def serialized_provider_repos
+ Import::ProviderRepoSerializer.new(current_user: current_user).represent(importable_repos, provider: provider_name, provider_url: provider_url)
+ end
+
+ def serialized_incompatible_repos
+ Import::ProviderRepoSerializer.new(current_user: current_user).represent(incompatible_repos, provider: provider_name, provider_url: provider_url)
+ end
+
+ def serialized_imported_projects
+ ProjectSerializer.new.represent(already_added_projects, serializer: :import, provider_url: provider_url)
+ end
+
+ def already_added_projects
+ @already_added_projects ||= filtered(find_already_added_projects(provider_name))
+ end
+
+ def serialized_namespaces
+ NamespaceSerializer.new.represent(namespaces)
+ end
+
+ def namespaces
+ current_user.manageable_groups_with_routes
+ end
+
# rubocop: disable CodeReuse/ActiveRecord
def find_already_added_projects(import_type)
current_user.created_projects.where(import_type: import_type).with_import_state
diff --git a/app/controllers/import/bitbucket_controller.rb b/app/controllers/import/bitbucket_controller.rb
index c37e799de62..4886aeb5e3f 100644
--- a/app/controllers/import/bitbucket_controller.rb
+++ b/app/controllers/import/bitbucket_controller.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: true
class Import::BitbucketController < Import::BaseController
+ extend ::Gitlab::Utils::Override
+
include ActionView::Helpers::SanitizeHelper
before_action :verify_bitbucket_import_enabled
@@ -10,7 +12,7 @@ class Import::BitbucketController < Import::BaseController
rescue_from Bitbucket::Error::Unauthorized, with: :bitbucket_unauthorized
def callback
- response = client.auth_code.get_token(params[:code], redirect_uri: users_import_bitbucket_callback_url)
+ response = oauth_client.auth_code.get_token(params[:code], redirect_uri: users_import_bitbucket_callback_url)
session[:bitbucket_token] = response.token
session[:bitbucket_expires_at] = response.expires_at
@@ -22,9 +24,10 @@ class Import::BitbucketController < Import::BaseController
# rubocop: disable CodeReuse/ActiveRecord
def status
+ return super if Feature.enabled?(:new_import_ui)
+
bitbucket_client = Bitbucket::Client.new(credentials)
repos = bitbucket_client.repos(filter: sanitized_filter_param)
-
@repos, @incompatible_repos = repos.partition { |repo| repo.valid? }
@already_added_projects = find_already_added_projects('bitbucket')
@@ -38,6 +41,10 @@ class Import::BitbucketController < Import::BaseController
render json: find_jobs('bitbucket')
end
+ def realtime_changes
+ super
+ end
+
def create
bitbucket_client = Bitbucket::Client.new(credentials)
@@ -59,7 +66,7 @@ class Import::BitbucketController < Import::BaseController
project = Gitlab::BitbucketImport::ProjectCreator.new(repo, project_name, target_namespace, current_user, credentials).execute
if project.persisted?
- render json: ProjectSerializer.new.represent(project)
+ render json: ProjectSerializer.new.represent(project, serializer: :import)
else
render json: { errors: project_save_error(project) }, status: :unprocessable_entity
end
@@ -68,16 +75,50 @@ class Import::BitbucketController < Import::BaseController
end
end
+ 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? }
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ override :incompatible_repos
+ def incompatible_repos
+ bitbucket_repos.reject { |repo| repo.valid? }
+ end
+
+ override :provider_name
+ def provider_name
+ :bitbucket
+ end
+
+ override :provider_url
+ def provider_url
+ provider.url
+ end
+
private
- def client
- @client ||= OAuth2::Client.new(provider.app_id, provider.app_secret, options)
+ def oauth_client
+ @oauth_client ||= OAuth2::Client.new(provider.app_id, provider.app_secret, options)
end
def provider
Gitlab::Auth::OAuth::Provider.config_for('bitbucket')
end
+ def client
+ @client ||= Bitbucket::Client.new(credentials)
+ end
+
+ def bitbucket_repos
+ @bitbucket_repos ||= client.repos(filter: sanitized_filter_param).to_a
+ end
+
def options
OmniAuth::Strategies::Bitbucket.default_options[:client_options].deep_symbolize_keys
end
@@ -91,7 +132,7 @@ class Import::BitbucketController < Import::BaseController
end
def go_to_bitbucket_for_permissions
- redirect_to client.auth_code.authorize_url(redirect_uri: users_import_bitbucket_callback_url)
+ redirect_to oauth_client.auth_code.authorize_url(redirect_uri: users_import_bitbucket_callback_url)
end
def bitbucket_unauthorized
diff --git a/app/controllers/import/bitbucket_server_controller.rb b/app/controllers/import/bitbucket_server_controller.rb
index 5fb7b5dccc5..9aa8110257d 100644
--- a/app/controllers/import/bitbucket_server_controller.rb
+++ b/app/controllers/import/bitbucket_server_controller.rb
@@ -1,12 +1,16 @@
# frozen_string_literal: true
class Import::BitbucketServerController < Import::BaseController
+ extend ::Gitlab::Utils::Override
+
include ActionView::Helpers::SanitizeHelper
before_action :verify_bitbucket_server_import_enabled
before_action :bitbucket_auth, except: [:new, :configure]
before_action :validate_import_params, only: [:create]
+ rescue_from BitbucketServer::Connection::ConnectionError, with: :bitbucket_connection_error
+
# As a basic sanity check to prevent URL injection, restrict project
# repository input and repository slugs to allowed characters. For Bitbucket:
#
@@ -24,7 +28,7 @@ class Import::BitbucketServerController < Import::BaseController
end
def create
- repo = bitbucket_client.repo(@project_key, @repo_slug)
+ repo = client.repo(@project_key, @repo_slug)
unless repo
return render json: { errors: _("Project %{project_repo} could not be found") % { project_repo: "#{@project_key}/#{@repo_slug}" } }, status: :unprocessable_entity
@@ -38,15 +42,13 @@ class Import::BitbucketServerController < Import::BaseController
project = Gitlab::BitbucketServerImport::ProjectCreator.new(@project_key, @repo_slug, repo, project_name, target_namespace, current_user, credentials).execute
if project.persisted?
- render json: ProjectSerializer.new.represent(project)
+ render json: ProjectSerializer.new.represent(project, serializer: :import)
else
render json: { errors: project_save_error(project) }, status: :unprocessable_entity
end
else
render json: { errors: _('This namespace has already been taken! Please choose another one.') }, status: :unprocessable_entity
end
- rescue BitbucketServer::Connection::ConnectionError => error
- render json: { errors: _("Unable to connect to server: %{error}") % { error: error } }, status: :unprocessable_entity
end
def configure
@@ -59,7 +61,9 @@ class Import::BitbucketServerController < Import::BaseController
# rubocop: disable CodeReuse/ActiveRecord
def status
- @collection = bitbucket_client.repos(page_offset: page_offset, limit: limit_per_page, filter: sanitized_filter_param)
+ return super if Feature.enabled?(:new_import_ui)
+
+ @collection = client.repos(page_offset: page_offset, limit: limit_per_page, filter: sanitized_filter_param)
@repos, @incompatible_repos = @collection.partition { |repo| repo.valid? }
# Use the import URL to filter beyond what BaseService#find_already_added_projects
@@ -67,10 +71,6 @@ class Import::BitbucketServerController < Import::BaseController
already_added_projects_names = @already_added_projects.pluck(:import_source)
@repos.reject! { |repo| already_added_projects_names.include?(repo.browse_url) }
- rescue BitbucketServer::Connection::ConnectionError => error
- flash[:alert] = _("Unable to connect to server: %{error}") % { error: error }
- clear_session_data
- redirect_to new_import_bitbucket_server_path
end
# rubocop: enable CodeReuse/ActiveRecord
@@ -78,6 +78,38 @@ class Import::BitbucketServerController < Import::BaseController
render json: find_jobs('bitbucket_server')
end
+ def realtime_changes
+ super
+ end
+
+ 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? }
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ override :incompatible_repos
+ def incompatible_repos
+ bitbucket_repos.reject { |repo| repo.valid? }
+ end
+
+ override :provider_name
+ def provider_name
+ :bitbucket_server
+ end
+
+ override :provider_url
+ def provider_url
+ session[bitbucket_server_url_key]
+ end
+
private
# rubocop: disable CodeReuse/ActiveRecord
@@ -86,8 +118,12 @@ class Import::BitbucketServerController < Import::BaseController
end
# rubocop: enable CodeReuse/ActiveRecord
- def bitbucket_client
- @bitbucket_client ||= BitbucketServer::Client.new(credentials)
+ def client
+ @client ||= BitbucketServer::Client.new(credentials)
+ end
+
+ def bitbucket_repos
+ @bitbucket_repos ||= client.repos(page_offset: page_offset, limit: limit_per_page, filter: sanitized_filter_param).to_a
end
def validate_import_params
@@ -153,4 +189,23 @@ class Import::BitbucketServerController < Import::BaseController
def sanitized_filter_param
sanitize(params[:filter])
end
+
+ def bitbucket_connection_error(error)
+ flash[:alert] = _("Unable to connect to server: %{error}") % { error: error }
+ clear_session_data
+
+ respond_to do |format|
+ format.json do
+ render json: {
+ error: {
+ message: _("Unable to connect to server: %{error}") % { error: error },
+ redirect: new_import_bitbucket_server_path
+ }
+ }, status: :unprocessable_entity
+ end
+ format.html do
+ redirect_to new_import_bitbucket_server_path
+ end
+ end
+ end
end
diff --git a/app/controllers/import/fogbugz_controller.rb b/app/controllers/import/fogbugz_controller.rb
index 4fb6efde7ff..91779a5d6cc 100644
--- a/app/controllers/import/fogbugz_controller.rb
+++ b/app/controllers/import/fogbugz_controller.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: true
class Import::FogbugzController < Import::BaseController
+ extend ::Gitlab::Utils::Override
+
before_action :verify_fogbugz_import_enabled
before_action :user_map, only: [:new_user_map, :create_user_map]
before_action :verify_blocked_uri, only: :callback
@@ -48,6 +50,8 @@ class Import::FogbugzController < Import::BaseController
return redirect_to new_import_fogbugz_path
end
+ return super if Feature.enabled?(:new_import_ui)
+
@repos = client.repos
@already_added_projects = find_already_added_projects('fogbugz')
@@ -57,6 +61,10 @@ class Import::FogbugzController < Import::BaseController
end
# rubocop: enable CodeReuse/ActiveRecord
+ def realtime_changes
+ super
+ end
+
def jobs
render json: find_jobs('fogbugz')
end
@@ -69,12 +77,35 @@ class Import::FogbugzController < Import::BaseController
project = Gitlab::FogbugzImport::ProjectCreator.new(repo, fb_session, current_user.namespace, current_user, umap).execute
if project.persisted?
- render json: ProjectSerializer.new.represent(project)
+ render json: ProjectSerializer.new.represent(project, serializer: :import)
else
render json: { errors: project_save_error(project) }, status: :unprocessable_entity
end
end
+ 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 }
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ override :provider_name
+ def provider_name
+ :fogbugz
+ end
+
+ override :provider_url
+ def provider_url
+ session[:fogbugz_uri]
+ end
+
private
def client
diff --git a/app/controllers/import/github_controller.rb b/app/controllers/import/github_controller.rb
index 4e8ceae75bd..097edcd6075 100644
--- a/app/controllers/import/github_controller.rb
+++ b/app/controllers/import/github_controller.rb
@@ -76,7 +76,7 @@ class Import::GithubController < Import::BaseController
def serialized_provider_repos
repos = client_repos.reject { |repo| already_added_project_names.include? repo.full_name }
- ProviderRepoSerializer.new(current_user: current_user).represent(repos, provider: provider, provider_url: provider_url)
+ Import::ProviderRepoSerializer.new(current_user: current_user).represent(repos, provider: provider, provider_url: provider_url)
end
def serialized_namespaces
diff --git a/app/controllers/import/gitlab_controller.rb b/app/controllers/import/gitlab_controller.rb
index 5ec8e9e6fc5..a95a67e208c 100644
--- a/app/controllers/import/gitlab_controller.rb
+++ b/app/controllers/import/gitlab_controller.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: true
class Import::GitlabController < Import::BaseController
+ extend ::Gitlab::Utils::Override
+
MAX_PROJECT_PAGES = 15
PER_PAGE_PROJECTS = 100
@@ -16,6 +18,8 @@ class Import::GitlabController < Import::BaseController
# rubocop: disable CodeReuse/ActiveRecord
def status
+ return super if Feature.enabled?(:new_import_ui)
+
@repos = client.projects(starting_page: 1, page_limit: MAX_PROJECT_PAGES, per_page: PER_PAGE_PROJECTS)
@already_added_projects = find_already_added_projects('gitlab')
@@ -37,7 +41,7 @@ class Import::GitlabController < Import::BaseController
project = Gitlab::GitlabImport::ProjectCreator.new(repo, target_namespace, current_user, access_params).execute
if project.persisted?
- render json: ProjectSerializer.new.represent(project)
+ render json: ProjectSerializer.new.represent(project, serializer: :import)
else
render json: { errors: project_save_error(project) }, status: :unprocessable_entity
end
@@ -46,6 +50,29 @@ class Import::GitlabController < Import::BaseController
end
end
+ 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"] }
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ override :provider_name
+ def provider_name
+ :gitlab
+ end
+
+ override :provider_url
+ def provider_url
+ 'https://gitlab.com'
+ end
+
private
def client
diff --git a/app/controllers/import/gitlab_groups_controller.rb b/app/controllers/import/gitlab_groups_controller.rb
new file mode 100644
index 00000000000..330af68385e
--- /dev/null
+++ b/app/controllers/import/gitlab_groups_controller.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+class Import::GitlabGroupsController < ApplicationController
+ include WorkhorseImportExportUpload
+
+ before_action :ensure_group_import_enabled
+ before_action :import_rate_limit, only: %i[create]
+
+ def create
+ unless file_is_valid?(group_params[:file])
+ return redirect_back_or_default(options: { alert: s_('GroupImport|Unable to process group import file') })
+ end
+
+ group_data = group_params.except(:file).merge(
+ visibility_level: closest_allowed_visibility_level,
+ import_export_upload: ImportExportUpload.new(import_file: group_params[:file])
+ )
+
+ group = ::Groups::CreateService.new(current_user, group_data).execute
+
+ if group.persisted?
+ if Groups::ImportExport::ImportService.new(group: group, user: current_user).async_execute
+ redirect_to(
+ group_path(group),
+ notice: s_("GroupImport|Group '%{group_name}' is being imported.") % { group_name: group.name }
+ )
+ else
+ redirect_to group_path(group), alert: _("Group import could not be scheduled")
+ end
+ else
+ redirect_back_or_default(
+ options: { alert: s_("GroupImport|Group could not be imported: %{errors}") % { errors: group.errors.full_messages.to_sentence } }
+ )
+ end
+ end
+
+ private
+
+ def group_params
+ params.permit(:path, :name, :parent_id, :file)
+ end
+
+ def closest_allowed_visibility_level
+ if group_params[:parent_id].present?
+ parent_group = Group.find(group_params[:parent_id])
+
+ Gitlab::VisibilityLevel.closest_allowed_level(parent_group.visibility_level)
+ else
+ Gitlab::VisibilityLevel::PRIVATE
+ end
+ end
+
+ def ensure_group_import_enabled
+ render_404 unless Feature.enabled?(:group_import_export, @group, default_enabled: true)
+ end
+
+ def import_rate_limit
+ if Gitlab::ApplicationRateLimiter.throttled?(:group_import, scope: current_user)
+ Gitlab::ApplicationRateLimiter.log_request(request, :group_import_request_limit, current_user)
+
+ flash[:alert] = _('This endpoint has been requested too many times. Try again later.')
+ redirect_to new_group_path
+ end
+ end
+end
diff --git a/app/controllers/import/gitlab_projects_controller.rb b/app/controllers/import/gitlab_projects_controller.rb
index 6a3715a4675..39d053347f0 100644
--- a/app/controllers/import/gitlab_projects_controller.rb
+++ b/app/controllers/import/gitlab_projects_controller.rb
@@ -1,14 +1,11 @@
# frozen_string_literal: true
class Import::GitlabProjectsController < Import::BaseController
- include WorkhorseRequest
+ include WorkhorseImportExportUpload
before_action :whitelist_query_limiting, only: [:create]
before_action :verify_gitlab_project_import_enabled
- skip_before_action :verify_authenticity_token, only: [:authorize]
- before_action :verify_workhorse_api!, only: [:authorize]
-
def new
@namespace = Namespace.find(project_params[:namespace_id])
return render_404 unless current_user.can?(:create_projects, @namespace)
@@ -17,7 +14,7 @@ class Import::GitlabProjectsController < Import::BaseController
end
def create
- unless file_is_valid?
+ unless file_is_valid?(project_params[:file])
return redirect_back_or_default(options: { alert: _("You need to upload a GitLab project export archive (ending in .gz).") })
end
@@ -33,28 +30,8 @@ class Import::GitlabProjectsController < Import::BaseController
end
end
- def authorize
- set_workhorse_internal_api_content_type
-
- authorized = ImportExportUploader.workhorse_authorize(
- has_length: false,
- maximum_size: Gitlab::CurrentSettings.max_attachment_size.megabytes.to_i)
-
- render json: authorized
- rescue SocketError
- render json: _("Error uploading file"), status: :internal_server_error
- end
-
private
- def file_is_valid?
- return false unless project_params[:file].is_a?(::UploadedFile)
-
- filename = project_params[:file].original_filename
-
- ImportExportUploader::EXTENSION_WHITELIST.include?(File.extname(filename).delete('.'))
- end
-
def verify_gitlab_project_import_enabled
render_404 unless gitlab_project_import_enabled?
end
diff --git a/app/controllers/projects/alert_management_controller.rb b/app/controllers/projects/alert_management_controller.rb
index 0c0a91e136f..054dc8e6a35 100644
--- a/app/controllers/projects/alert_management_controller.rb
+++ b/app/controllers/projects/alert_management_controller.rb
@@ -2,10 +2,6 @@
class Projects::AlertManagementController < Projects::ApplicationController
before_action :authorize_read_alert_management_alert!
- before_action do
- push_frontend_feature_flag(:alert_list_status_filtering_enabled)
- push_frontend_feature_flag(:create_issue_from_alert_enabled)
- end
def index
end
diff --git a/app/controllers/projects/alerting/notifications_controller.rb b/app/controllers/projects/alerting/notifications_controller.rb
index 358e7629958..fef8235628d 100644
--- a/app/controllers/projects/alerting/notifications_controller.rb
+++ b/app/controllers/projects/alerting/notifications_controller.rb
@@ -29,12 +29,22 @@ module Projects
end
def notify_service
- Projects::Alerting::NotifyService
- .new(project, current_user, notification_payload)
+ notify_service_class.new(project, current_user, notification_payload)
+ end
+
+ def notify_service_class
+ # We are tracking the consolidation of these services in
+ # https://gitlab.com/groups/gitlab-org/-/epics/3360
+ # to get rid of this workaround.
+ if Projects::Prometheus::Alerts::NotifyService.processable?(notification_payload)
+ Projects::Prometheus::Alerts::NotifyService
+ else
+ Projects::Alerting::NotifyService
+ end
end
def notification_payload
- params.permit![:notification]
+ @notification_payload ||= params.permit![:notification]
end
end
end
diff --git a/app/controllers/projects/badges_controller.rb b/app/controllers/projects/badges_controller.rb
index 66b51b17790..59a7dff680c 100644
--- a/app/controllers/projects/badges_controller.rb
+++ b/app/controllers/projects/badges_controller.rb
@@ -8,14 +8,21 @@ class Projects::BadgesController < Projects::ApplicationController
def pipeline
pipeline_status = Gitlab::Badge::Pipeline::Status
- .new(project, params[:ref])
+ .new(project, params[:ref], opts: {
+ key_text: params[:key_text],
+ key_width: params[:key_width]
+ })
render_badge pipeline_status
end
def coverage
coverage_report = Gitlab::Badge::Coverage::Report
- .new(project, params[:ref], params[:job])
+ .new(project, params[:ref], opts: {
+ job: params[:job],
+ key_text: params[:key_text],
+ key_width: params[:key_width]
+ })
render_badge coverage_report
end
diff --git a/app/controllers/projects/blame_controller.rb b/app/controllers/projects/blame_controller.rb
index b62ce940e9c..374b4921dbc 100644
--- a/app/controllers/projects/blame_controller.rb
+++ b/app/controllers/projects/blame_controller.rb
@@ -20,6 +20,7 @@ class Projects::BlameController < Projects::ApplicationController
environment_params[:find_latest] = true
@environment = EnvironmentsFinder.new(@project, current_user, environment_params).execute.last
- @blame_groups = Gitlab::Blame.new(@blob, @commit).groups
+ @blame = Gitlab::Blame.new(@blob, @commit)
+ @blame = Gitlab::View::Presenter::Factory.new(@blame, project: @project, path: @path).fabricate!
end
end
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index 584320a66de..abc1d58cbf1 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -71,6 +71,7 @@ class Projects::BlobController < Projects::ApplicationController
def update
@path = params[:file_path] if params[:file_path].present?
+
create_commit(Files::UpdateService, success_path: -> { after_edit_path },
failure_view: :edit,
failure_path: project_blob_path(@project, @id))
@@ -93,7 +94,6 @@ class Projects::BlobController < Projects::ApplicationController
def destroy
create_commit(Files::DeleteService, success_notice: _("The file has been successfully deleted."),
success_path: -> { after_delete_path },
- failure_view: :show,
failure_path: project_blob_path(@project, @id))
end
@@ -115,6 +115,8 @@ class Projects::BlobController < Projects::ApplicationController
private
+ attr_reader :branch_name
+
def blob
@blob ||= @repository.blob_at(@commit.id, @path)
@@ -254,3 +256,5 @@ class Projects::BlobController < Projects::ApplicationController
params.permit(:full, :since, :to, :bottom, :unfold, :offset, :indent)
end
end
+
+Projects::BlobController.prepend_if_ee('EE::Projects::BlobController')
diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb
index cc595740696..7cfb4a508da 100644
--- a/app/controllers/projects/branches_controller.rb
+++ b/app/controllers/projects/branches_controller.rb
@@ -25,8 +25,9 @@ class Projects::BranchesController < Projects::ApplicationController
@refs_pipelines = @project.ci_pipelines.latest_successful_for_refs(@branches.map(&:name))
@merged_branch_names = repository.merged_branch_names(@branches.map(&:name))
+ @branch_pipeline_statuses = branch_pipeline_statuses
- # https://gitlab.com/gitlab-org/gitlab-foss/issues/48097
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/22851
Gitlab::GitalyClient.allow_n_plus_1_calls do
render
end
@@ -194,4 +195,15 @@ class Projects::BranchesController < Projects::ApplicationController
confidential_issue_project
end
+
+ def branch_pipeline_statuses
+ latest_commits = @branches.map do |branch|
+ [branch.name, repository.commit(branch.dereferenced_target).sha]
+ end.to_h
+
+ latest_pipelines = project.ci_pipelines.latest_pipeline_per_commit(latest_commits.values)
+ latest_commits.transform_values do |commit_sha|
+ latest_pipelines[commit_sha]&.detailed_status(current_user)
+ end.compact
+ end
end
diff --git a/app/controllers/projects/ci/daily_build_group_report_results_controller.rb b/app/controllers/projects/ci/daily_build_group_report_results_controller.rb
index dfda5fca310..b36c5f1aea6 100644
--- a/app/controllers/projects/ci/daily_build_group_report_results_controller.rb
+++ b/app/controllers/projects/ci/daily_build_group_report_results_controller.rb
@@ -7,12 +7,13 @@ class Projects::Ci::DailyBuildGroupReportResultsController < Projects::Applicati
REPORT_WINDOW = 90.days
before_action :validate_feature_flag!
- before_action :authorize_download_code! # Share the same authorization rules as the graphs controller
+ before_action :authorize_read_build_report_results!
before_action :validate_param_type!
def index
respond_to do |format|
- format.csv { send_data(render_csv(results), type: 'text/csv; charset=utf-8') }
+ format.csv { send_data(render_csv(report_results), type: 'text/csv; charset=utf-8') }
+ format.json { render json: render_json(report_results) }
end
end
@@ -37,7 +38,11 @@ class Projects::Ci::DailyBuildGroupReportResultsController < Projects::Applicati
).render
end
- def results
+ def render_json(collection)
+ Ci::DailyBuildGroupReportResultSerializer.new.represent(collection, param_type: param_type)
+ end
+
+ def report_results
Ci::DailyBuildGroupReportResultsFinder.new(finder_params).execute
end
diff --git a/app/controllers/projects/discussions_controller.rb b/app/controllers/projects/discussions_controller.rb
index 028390c7e2a..06231607f73 100644
--- a/app/controllers/projects/discussions_controller.rb
+++ b/app/controllers/projects/discussions_controller.rb
@@ -10,7 +10,7 @@ class Projects::DiscussionsController < Projects::ApplicationController
before_action :authorize_resolve_discussion!, only: [:resolve, :unresolve]
def resolve
- Discussions::ResolveService.new(project, current_user, merge_request: merge_request).execute(discussion)
+ Discussions::ResolveService.new(project, current_user, one_or_more_discussions: discussion).execute
render_discussion
end
diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb
index 5f4d88c57e9..4d774123ef1 100644
--- a/app/controllers/projects/environments_controller.rb
+++ b/app/controllers/projects/environments_controller.rb
@@ -10,7 +10,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
push_frontend_feature_flag(:prometheus_computed_alerts)
end
- before_action :authorize_read_environment!
+ before_action :authorize_read_environment!, except: [:metrics, :additional_metrics, :metrics_dashboard, :metrics_redirect]
before_action :authorize_create_environment!, only: [:new, :create]
before_action :authorize_stop_environment!, only: [:stop]
before_action :authorize_update_environment!, only: [:edit, :update, :cancel_auto_stop]
diff --git a/app/controllers/projects/graphs_controller.rb b/app/controllers/projects/graphs_controller.rb
index 34246f27241..a8b90f8685f 100644
--- a/app/controllers/projects/graphs_controller.rb
+++ b/app/controllers/projects/graphs_controller.rb
@@ -6,7 +6,7 @@ class Projects::GraphsController < Projects::ApplicationController
# Authorize
before_action :require_non_empty_project
before_action :assign_ref_vars
- before_action :authorize_download_code!
+ before_action :authorize_read_repository_graphs!
def show
respond_to do |format|
@@ -54,7 +54,8 @@ class Projects::GraphsController < Projects::ApplicationController
end
def get_daily_coverage_options
- return unless Feature.enabled?(:ci_download_daily_code_coverage, default_enabled: true)
+ return unless Feature.enabled?(:ci_download_daily_code_coverage, @project, default_enabled: true)
+ return unless can?(current_user, :read_build_report_results, project)
date_today = Date.current
report_window = Projects::Ci::DailyBuildGroupReportResultsController::REPORT_WINDOW
@@ -70,6 +71,11 @@ class Projects::GraphsController < Projects::ApplicationController
namespace_id: @project.namespace,
project_id: @project,
format: :csv
+ ),
+ graph_api_path: namespace_project_ci_daily_build_group_report_results_path(
+ namespace_id: @project.namespace,
+ project_id: @project,
+ format: :json
)
}
end
diff --git a/app/controllers/projects/group_links_controller.rb b/app/controllers/projects/group_links_controller.rb
index d06e24ef39c..a30c455a7e4 100644
--- a/app/controllers/projects/group_links_controller.rb
+++ b/app/controllers/projects/group_links_controller.rb
@@ -5,10 +5,6 @@ class Projects::GroupLinksController < Projects::ApplicationController
before_action :authorize_admin_project!
before_action :authorize_admin_project_member!, only: [:update]
- def index
- redirect_to namespace_project_settings_members_path
- end
-
def create
group = Group.find(params[:link_group_id]) if params[:link_group_id].present?
@@ -26,8 +22,7 @@ class Projects::GroupLinksController < Projects::ApplicationController
def update
@group_link = @project.project_group_links.find(params[:id])
-
- @group_link.update(group_link_params)
+ Projects::GroupLinks::UpdateService.new(@group_link).execute(group_link_params)
end
def destroy
diff --git a/app/controllers/projects/import/jira_controller.rb b/app/controllers/projects/import/jira_controller.rb
index 711e23dc3ce..976ac7df976 100644
--- a/app/controllers/projects/import/jira_controller.rb
+++ b/app/controllers/projects/import/jira_controller.rb
@@ -4,59 +4,29 @@ module Projects
module Import
class JiraController < Projects::ApplicationController
before_action :authenticate_user!
- before_action :check_issues_available!
before_action :authorize_read_project!
- before_action :jira_import_enabled?
- before_action :jira_integration_configured?
- before_action :authorize_admin_project!, only: [:import]
+ before_action :validate_jira_import_settings!
def show
- jira_service = @project.jira_service
-
- if jira_service.present? && !@project.latest_jira_import&.in_progress? && current_user&.can?(:admin_project, @project)
- jira_client = jira_service.client
- jira_projects = jira_client.Project.all
-
- if jira_projects.present?
- @jira_projects = jira_projects.map { |p| ["#{p.name} (#{p.key})", p.key] }
- else
- flash[:alert] = 'No projects have been returned from Jira. Please check your Jira configuration.'
- end
- end
-
- unless Feature.enabled?(:jira_issue_import_vue, @project, default_enabled: true)
- flash[:notice] = _("Import %{status}") % { status: @project.jira_import_status } unless @project.latest_jira_import&.initial?
- end
- end
-
- def import
- jira_project_key = jira_import_params[:jira_project_key]
-
- if jira_project_key.present?
- response = ::JiraImport::StartImportService.new(current_user, @project, jira_project_key).execute
- flash[:notice] = response.message if response.message.present?
- else
- flash[:alert] = 'No Jira project key has been provided.'
- end
-
- redirect_to project_import_jira_path(@project)
end
private
- def jira_import_enabled?
- return if @project.jira_issues_import_feature_flag_enabled?
+ def validate_jira_import_settings!
+ Gitlab::JiraImport.validate_project_settings!(@project, user: current_user, configuration_check: false)
+ true
+ rescue Projects::ImportService::Error => e
+ flash[:notice] = e.message
redirect_to project_issues_path(@project)
- end
- def jira_integration_configured?
- return if Feature.enabled?(:jira_issue_import_vue, @project, default_enabled: true)
- return if @project.jira_service
+ false
+ end
- flash[:notice] = _("Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page." %
- { strong_start: '<strong>'.html_safe, strong_end: '</strong>'.html_safe })
- redirect_to project_issues_path(@project)
+ def jira_service
+ strong_memoize(:jira_service) do
+ @project.jira_service
+ end
end
def jira_import_params
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index 3e9d956f7b1..693329848de 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -46,7 +46,6 @@ class Projects::IssuesController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:vue_issuable_sidebar, project.group)
- push_frontend_feature_flag(:save_issuable_health_status, project.group, default_enabled: true)
end
before_action only: :show do
diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb
index e0457925b34..e1f6cbe3dca 100644
--- a/app/controllers/projects/jobs_controller.rb
+++ b/app/controllers/projects/jobs_controller.rb
@@ -14,6 +14,8 @@ class Projects::JobsController < Projects::ApplicationController
before_action only: [:show] do
push_frontend_feature_flag(:job_log_json, project, default_enabled: true)
end
+ before_action :authorize_create_proxy_build!, only: :proxy_websocket_authorize
+ before_action :verify_proxy_request!, only: :proxy_websocket_authorize
layout 'project'
@@ -151,6 +153,10 @@ class Projects::JobsController < Projects::ApplicationController
render json: Gitlab::Workhorse.channel_websocket(@build.terminal_specification)
end
+ def proxy_websocket_authorize
+ render json: proxy_websocket_service(build_service_specification)
+ end
+
private
def authorize_update_build!
@@ -165,10 +171,19 @@ class Projects::JobsController < Projects::ApplicationController
return access_denied! unless can?(current_user, :create_build_terminal, build)
end
+ def authorize_create_proxy_build!
+ return access_denied! unless can?(current_user, :create_build_service_proxy, build)
+ end
+
def verify_api_request!
Gitlab::Workhorse.verify_api_request!(request.headers)
end
+ def verify_proxy_request!
+ verify_api_request!
+ set_workhorse_internal_api_content_type
+ end
+
def raw_send_params
{ type: 'text/plain; charset=utf-8', disposition: 'inline' }
end
@@ -202,6 +217,27 @@ class Projects::JobsController < Projects::ApplicationController
'attachment'
end
-end
-Projects::JobsController.prepend_if_ee('EE::Projects::JobsController')
+ def build_service_specification
+ build.service_specification(service: params['service'],
+ port: params['port'],
+ path: params['path'],
+ subprotocols: proxy_subprotocol)
+ end
+
+ def proxy_subprotocol
+ # This will allow to reuse the same subprotocol set
+ # in the original websocket connection
+ request.headers['HTTP_SEC_WEBSOCKET_PROTOCOL'].presence || ::Ci::BuildRunnerSession::TERMINAL_SUBPROTOCOL
+ end
+
+ # This method provides the information to Workhorse
+ # about the service we want to proxy to.
+ # For security reasons, in case this operation is started by JS,
+ # it's important to use only sourced GitLab JS code
+ def proxy_websocket_service(service)
+ service[:url] = ::Gitlab::UrlHelpers.as_wss(service[:url])
+
+ ::Gitlab::Workhorse.channel_websocket(service)
+ end
+end
diff --git a/app/controllers/projects/merge_requests/diffs_controller.rb b/app/controllers/projects/merge_requests/diffs_controller.rb
index 2331674f42c..1bf143c9a91 100644
--- a/app/controllers/projects/merge_requests/diffs_controller.rb
+++ b/app/controllers/projects/merge_requests/diffs_controller.rb
@@ -162,8 +162,13 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
def renderable_notes
define_diff_comment_vars unless @notes
- @notes
+ draft_notes =
+ if current_user
+ merge_request.draft_notes.authored_by(current_user)
+ else
+ []
+ end
+
+ @notes.concat(draft_notes)
end
end
-
-Projects::MergeRequests::DiffsController.prepend_if_ee('EE::Projects::MergeRequests::DiffsController')
diff --git a/app/controllers/projects/merge_requests/drafts_controller.rb b/app/controllers/projects/merge_requests/drafts_controller.rb
new file mode 100644
index 00000000000..f4846b1aa81
--- /dev/null
+++ b/app/controllers/projects/merge_requests/drafts_controller.rb
@@ -0,0 +1,129 @@
+# frozen_string_literal: true
+
+class Projects::MergeRequests::DraftsController < Projects::MergeRequests::ApplicationController
+ include Gitlab::Utils::StrongMemoize
+
+ respond_to :json
+
+ before_action :authorize_create_note!, only: [:create, :publish]
+ before_action :authorize_admin_draft!, only: [:update, :destroy]
+ before_action :authorize_admin_draft!, if: -> { action_name == 'publish' && params[:id].present? }
+
+ def index
+ drafts = prepare_notes_for_rendering(draft_notes)
+ render json: DraftNoteSerializer.new(current_user: current_user).represent(drafts)
+ end
+
+ def create
+ create_params = draft_note_params.merge(in_reply_to_discussion_id: params[:in_reply_to_discussion_id])
+ create_service = DraftNotes::CreateService.new(merge_request, current_user, create_params)
+
+ draft_note = create_service.execute
+
+ prepare_notes_for_rendering(draft_note)
+
+ render json: DraftNoteSerializer.new(current_user: current_user).represent(draft_note)
+ end
+
+ def update
+ draft_note.update!(draft_note_params)
+
+ prepare_notes_for_rendering(draft_note)
+
+ render json: DraftNoteSerializer.new(current_user: current_user).represent(draft_note)
+ end
+
+ def destroy
+ DraftNotes::DestroyService.new(merge_request, current_user).execute(draft_note)
+
+ head :ok
+ end
+
+ def publish
+ result = DraftNotes::PublishService.new(merge_request, current_user).execute(draft_note(allow_nil: true))
+
+ if result[:status] == :success
+ head :ok
+ else
+ render json: { message: result[:message] }, status: result[:status]
+ end
+ end
+
+ def discard
+ DraftNotes::DestroyService.new(merge_request, current_user).execute
+
+ head :ok
+ end
+
+ private
+
+ def draft_note(allow_nil: false)
+ strong_memoize(:draft_note) do
+ draft_notes.find(params[:id])
+ end
+ rescue ActiveRecord::RecordNotFound => ex
+ # draft_note is allowed to be nil in #publish
+ raise ex unless allow_nil
+ end
+
+ def draft_notes
+ return unless current_user
+
+ strong_memoize(:draft_notes) do
+ merge_request.draft_notes.authored_by(current_user)
+ end
+ end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def merge_request
+ @merge_request ||= MergeRequestsFinder.new(current_user, project_id: @project.id).find_by!(iid: params[:merge_request_id])
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ def draft_note_params
+ params.require(:draft_note).permit(
+ :commit_id,
+ :note,
+ :position,
+ :resolve_discussion
+ ).tap do |h|
+ # Old FE version will still be sending `draft_note[commit_id]` as 'undefined'.
+ # That can result to having a note linked to a commit with 'undefined' ID
+ # which is non-existent.
+ h[:commit_id] = nil if h[:commit_id] == 'undefined'
+ end
+ end
+
+ def prepare_notes_for_rendering(notes)
+ return [] unless notes
+
+ notes = Array.wrap(notes)
+
+ # Preload author and access-level information
+ DraftNote.preload_author(notes)
+ user_ids = notes.map(&:author_id)
+ project.team.max_member_access_for_user_ids(user_ids)
+
+ notes.map(&method(:render_draft_note))
+ end
+
+ def render_draft_note(note)
+ params = { target_id: merge_request.id, target_type: 'MergeRequest', text: note.note }
+ result = PreviewMarkdownService.new(@project, current_user, params).execute
+ markdown_params = { markdown_engine: result[:markdown_engine], issuable_state_filter_enabled: true }
+
+ note.rendered_note = view_context.markdown(result[:text], markdown_params)
+ note.users_referenced = result[:users]
+ note.commands_changes = view_context.markdown(result[:commands])
+
+ note
+ end
+
+ def authorize_admin_draft!
+ access_denied! unless can?(current_user, :admin_note, draft_note)
+ end
+
+ def authorize_create_note!
+ access_denied! unless can?(current_user, :create_note, merge_request)
+ end
+end
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 5613b5b9589..55556ea7d31 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -33,6 +33,9 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag(:widget_visibility_polling, @project, default_enabled: true)
push_frontend_feature_flag(:merge_ref_head_comments, @project)
push_frontend_feature_flag(:mr_commit_neighbor_nav, @project, default_enabled: true)
+ push_frontend_feature_flag(:multiline_comments, @project)
+ push_frontend_feature_flag(:file_identifier_hash)
+ push_frontend_feature_flag(:batch_suggestions, @project)
end
before_action do
diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb
index 56f1f1a1019..16d63cc184f 100644
--- a/app/controllers/projects/milestones_controller.rb
+++ b/app/controllers/projects/milestones_controller.rb
@@ -7,7 +7,7 @@ class Projects::MilestonesController < Projects::ApplicationController
before_action :check_issuables_available!
before_action :milestone, only: [:edit, :update, :destroy, :show, :merge_requests, :participants, :labels, :promote]
before_action do
- push_frontend_feature_flag(:burnup_charts)
+ push_frontend_feature_flag(:burnup_charts, @project)
end
# Allow read any milestone
@@ -34,7 +34,7 @@ class Projects::MilestonesController < Projects::ApplicationController
@milestones = @milestones.page(params[:page])
end
format.json do
- render json: @milestones.to_json(methods: :name)
+ render json: @milestones.to_json(only: [:id, :title], methods: :name)
end
end
end
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index 678d0862f48..0b6c0db211e 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -12,8 +12,9 @@ class Projects::PipelinesController < Projects::ApplicationController
before_action :authorize_update_pipeline!, only: [:retry, :cancel]
before_action do
push_frontend_feature_flag(:junit_pipeline_view, project)
- push_frontend_feature_flag(:filter_pipelines_search, default_enabled: true)
- push_frontend_feature_flag(:dag_pipeline_tab)
+ push_frontend_feature_flag(:filter_pipelines_search, project, default_enabled: true)
+ push_frontend_feature_flag(:dag_pipeline_tab, project, default_enabled: false)
+ push_frontend_feature_flag(:pipelines_security_report_summary, project)
end
before_action :ensure_pipeline, only: [:show]
@@ -95,7 +96,14 @@ class Projects::PipelinesController < Projects::ApplicationController
end
def dag
- render_show
+ respond_to do |format|
+ format.html { render_show }
+ format.json do
+ render json: Ci::DagPipelineSerializer
+ .new(project: @project, current_user: @current_user)
+ .represent(@pipeline)
+ end
+ end
end
def failures
@@ -269,7 +277,7 @@ class Projects::PipelinesController < Projects::ApplicationController
end
def index_params
- params.permit(:scope, :username, :ref)
+ params.permit(:scope, :username, :ref, :status)
end
end
diff --git a/app/controllers/projects/refs_controller.rb b/app/controllers/projects/refs_controller.rb
index fcbeb5c840c..a2581e72257 100644
--- a/app/controllers/projects/refs_controller.rb
+++ b/app/controllers/projects/refs_controller.rb
@@ -53,7 +53,7 @@ class Projects::RefsController < Projects::ApplicationController
format.json do
logs, next_offset = tree_summary.fetch_logs
- response.headers["More-Logs-Offset"] = next_offset if next_offset
+ response.headers["More-Logs-Offset"] = next_offset.to_s if next_offset
render json: logs
end
diff --git a/app/controllers/projects/releases_controller.rb b/app/controllers/projects/releases_controller.rb
index 228b139d794..d3285b64dab 100644
--- a/app/controllers/projects/releases_controller.rb
+++ b/app/controllers/projects/releases_controller.rb
@@ -10,6 +10,7 @@ class Projects::ReleasesController < Projects::ApplicationController
push_frontend_feature_flag(:release_evidence_collection, project, default_enabled: true)
push_frontend_feature_flag(:release_show_page, project, default_enabled: true)
push_frontend_feature_flag(:release_asset_link_editing, project, default_enabled: true)
+ push_frontend_feature_flag(:release_asset_link_type, project, default_enabled: true)
end
before_action :authorize_update_release!, only: %i[edit update]
diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb
index 92c6ce324f7..710ad546e64 100644
--- a/app/controllers/projects/services_controller.rb
+++ b/app/controllers/projects/services_controller.rb
@@ -2,6 +2,7 @@
class Projects::ServicesController < Projects::ApplicationController
include ServiceParams
+ include InternalRedirect
# Authorize
before_action :authorize_admin_project!
@@ -10,6 +11,9 @@ class Projects::ServicesController < Projects::ApplicationController
before_action :web_hook_logs, only: [:edit, :update]
before_action :set_deprecation_notice_for_prometheus_service, only: [:edit, :update]
before_action :redirect_deprecated_prometheus_service, only: [:update]
+ before_action only: :edit do
+ push_frontend_feature_flag(:integration_form_refactor)
+ end
respond_to :html
@@ -26,8 +30,8 @@ class Projects::ServicesController < Projects::ApplicationController
respond_to do |format|
format.html do
if saved
- redirect_to project_settings_integrations_path(@project),
- notice: success_message
+ target_url = safe_redirect_path(params[:redirect_to]).presence || project_settings_integrations_path(@project)
+ redirect_to target_url, notice: success_message
else
render 'edit'
end
@@ -56,11 +60,10 @@ class Projects::ServicesController < Projects::ApplicationController
return { error: true, message: _('Validations failed.'), service_response: @service.errors.full_messages.join(','), test_failed: false }
end
- data = @service.test_data(project, current_user)
- outcome = @service.test(data)
+ result = Integrations::Test::ProjectService.new(@service, current_user, params[:event]).execute
- unless outcome[:success]
- return { error: true, message: _('Test failed.'), service_response: outcome[:result].to_s, test_failed: true }
+ unless result[:success]
+ return { error: true, message: _('Test failed.'), service_response: result[:message].to_s, test_failed: true }
end
{}
diff --git a/app/controllers/projects/settings/operations_controller.rb b/app/controllers/projects/settings/operations_controller.rb
index a9d1dc0759d..c2292511e0f 100644
--- a/app/controllers/projects/settings/operations_controller.rb
+++ b/app/controllers/projects/settings/operations_controller.rb
@@ -104,7 +104,7 @@ module Projects
project_params = {
incident_management_setting_attributes: ::Gitlab::Tracking::IncidentManagement.tracking_keys.keys,
- metrics_setting_attributes: [:external_dashboard_url],
+ metrics_setting_attributes: [:external_dashboard_url, :dashboard_timezone],
error_tracking_setting_attributes: [
:enabled,
diff --git a/app/controllers/projects/snippets/application_controller.rb b/app/controllers/projects/snippets/application_controller.rb
new file mode 100644
index 00000000000..3f488b07e96
--- /dev/null
+++ b/app/controllers/projects/snippets/application_controller.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class Projects::Snippets::ApplicationController < Projects::ApplicationController
+ include FindSnippet
+ include SnippetAuthorizations
+
+ private
+
+ # This overrides the default snippet create authorization
+ # because ProjectSnippets are checked against the project rather
+ # than the user
+ def authorize_create_snippet!
+ return render_404 unless can?(current_user, :create_snippet, project)
+ end
+
+ def snippet_klass
+ ProjectSnippet
+ end
+end
diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb
index 9233f063f55..5ee6abef804 100644
--- a/app/controllers/projects/snippets_controller.rb
+++ b/app/controllers/projects/snippets_controller.rb
@@ -1,34 +1,19 @@
# frozen_string_literal: true
-class Projects::SnippetsController < Projects::ApplicationController
- include RendersNotes
+class Projects::SnippetsController < Projects::Snippets::ApplicationController
+ include SnippetsActions
include ToggleAwardEmoji
include SpammableActions
- include SnippetsActions
- include RendersBlob
- include PaginatedCollection
- include Gitlab::NoteableMetadata
-
- skip_before_action :verify_authenticity_token,
- if: -> { action_name == 'show' && js_request? }
before_action :check_snippets_available!
+
before_action :snippet, only: [:show, :edit, :destroy, :update, :raw, :toggle_award_emoji, :mark_as_spam]
- # Allow create snippet
before_action :authorize_create_snippet!, only: [:new, :create]
-
- # Allow read any snippet
before_action :authorize_read_snippet!, except: [:new, :create, :index]
-
- # Allow modify snippet
before_action :authorize_update_snippet!, only: [:edit, :update]
-
- # Allow destroy snippet
before_action :authorize_admin_snippet!, only: [:destroy]
- respond_to :html
-
def index
@snippet_counts = Snippets::CountService
.new(current_user, project: @project)
@@ -56,61 +41,8 @@ class Projects::SnippetsController < Projects::ApplicationController
handle_repository_error(:new)
end
- def update
- update_params = snippet_params.merge(spammable_params)
-
- service_response = Snippets::UpdateService.new(project, current_user, update_params).execute(@snippet)
- @snippet = service_response.payload[:snippet]
-
- handle_repository_error(:edit)
- end
-
- def show
- conditionally_expand_blob(blob)
-
- respond_to do |format|
- format.html do
- @note = @project.notes.new(noteable: @snippet)
- @noteable = @snippet
-
- @discussions = @snippet.discussions
- @notes = prepare_notes_for_rendering(@discussions.flat_map(&:notes), @noteable)
- render 'show'
- end
-
- format.json do
- render_blob_json(blob)
- end
-
- format.js do
- if @snippet.embeddable?
- render 'shared/snippets/show'
- else
- head :not_found
- end
- end
- end
- end
-
- def destroy
- service_response = Snippets::DestroyService.new(current_user, @snippet).execute
-
- if service_response.success?
- redirect_to project_snippets_path(project), status: :found
- elsif service_response.http_status == 403
- access_denied!
- else
- redirect_to project_snippet_path(project, @snippet),
- status: :found,
- alert: service_response.message
- end
- end
-
protected
- def snippet
- @snippet ||= @project.snippets.inc_relations_for_view.find(params[:id])
- end
alias_method :awardable, :snippet
alias_method :spammable, :snippet
@@ -118,18 +50,6 @@ class Projects::SnippetsController < Projects::ApplicationController
project_snippet_path(@project, @snippet)
end
- def authorize_read_snippet!
- return render_404 unless can?(current_user, :read_snippet, @snippet)
- end
-
- def authorize_update_snippet!
- return render_404 unless can?(current_user, :update_snippet, @snippet)
- end
-
- def authorize_admin_snippet!
- return render_404 unless can?(current_user, :admin_snippet, @snippet)
- end
-
def snippet_params
params.require(:project_snippet).permit(:title, :content, :file_name, :private, :visibility_level, :description)
end
diff --git a/app/controllers/projects/tags_controller.rb b/app/controllers/projects/tags_controller.rb
index c89bfd110c4..df20daa8f7e 100644
--- a/app/controllers/projects/tags_controller.rb
+++ b/app/controllers/projects/tags_controller.rb
@@ -41,16 +41,20 @@ class Projects::TagsController < Projects::ApplicationController
# rubocop: enable CodeReuse/ActiveRecord
def create
+ # TODO: remove this with the release creation moved to it's own form https://gitlab.com/gitlab-org/gitlab/-/issues/214245
+ evidence_pipeline = find_evidence_pipeline
+
result = ::Tags::CreateService.new(@project, current_user)
.execute(params[:tag_name], params[:ref], params[:message])
if result[:status] == :success
- # Release creation with Tags was deprecated in GitLab 11.7
+ # TODO: remove this with the release creation moved to it's own form https://gitlab.com/gitlab-org/gitlab/-/issues/214245
if params[:release_description].present?
release_params = {
tag: params[:tag_name],
name: params[:tag_name],
- description: params[:release_description]
+ description: params[:release_description],
+ evidence_pipeline: evidence_pipeline
}
Releases::CreateService
@@ -93,4 +97,14 @@ class Projects::TagsController < Projects::ApplicationController
end
end
end
+
+ private
+
+ # TODO: remove this with the release creation moved to it's own form https://gitlab.com/gitlab-org/gitlab/-/issues/214245
+ def find_evidence_pipeline
+ evidence_pipeline_sha = @project.repository.commit(params[:ref])&.sha
+ return unless evidence_pipeline_sha
+
+ @project.ci_pipelines.for_sha(evidence_pipeline_sha).last
+ end
end
diff --git a/app/controllers/projects/web_ide_terminals_controller.rb b/app/controllers/projects/web_ide_terminals_controller.rb
new file mode 100644
index 00000000000..08ea5c4bca8
--- /dev/null
+++ b/app/controllers/projects/web_ide_terminals_controller.rb
@@ -0,0 +1,98 @@
+# frozen_string_literal: true
+
+class Projects::WebIdeTerminalsController < Projects::ApplicationController
+ before_action :authenticate_user!
+
+ before_action :build, except: [:check_config, :create]
+ before_action :authorize_create_web_ide_terminal!
+ before_action :authorize_read_web_ide_terminal!, except: [:check_config, :create]
+ before_action :authorize_update_web_ide_terminal!, only: [:cancel, :retry]
+
+ def check_config
+ return respond_422 unless branch_sha
+
+ result = ::Ci::WebIdeConfigService.new(project, current_user, sha: branch_sha).execute
+
+ if result[:status] == :success
+ head :ok
+ else
+ respond_422
+ end
+ end
+
+ def show
+ render_terminal(build)
+ end
+
+ def create
+ result = ::Ci::CreateWebIdeTerminalService.new(project,
+ current_user,
+ ref: params[:branch])
+ .execute
+
+ if result[:status] == :error
+ render status: :bad_request, json: result[:message]
+ else
+ pipeline = result[:pipeline]
+ current_build = pipeline.builds.last
+
+ if current_build
+ Gitlab::UsageDataCounters::WebIdeCounter.increment_terminals_count
+
+ render_terminal(current_build)
+ else
+ render status: :bad_request, json: pipeline.errors.full_messages
+ end
+ end
+ end
+
+ def cancel
+ return respond_422 unless build.cancelable?
+
+ build.cancel
+
+ head :ok
+ end
+
+ def retry
+ return respond_422 unless build.retryable?
+
+ new_build = Ci::Build.retry(build, current_user)
+
+ render_terminal(new_build)
+ end
+
+ private
+
+ def authorize_create_web_ide_terminal!
+ return access_denied! unless can?(current_user, :create_web_ide_terminal, project)
+ end
+
+ def authorize_read_web_ide_terminal!
+ authorize_build_ability!(:read_web_ide_terminal)
+ end
+
+ def authorize_update_web_ide_terminal!
+ authorize_build_ability!(:update_web_ide_terminal)
+ end
+
+ def authorize_build_ability!(ability)
+ return access_denied! unless can?(current_user, ability, build)
+ end
+
+ def build
+ @build ||= project.builds.find(params[:id])
+ end
+
+ def branch_sha
+ return unless params[:branch].present?
+
+ project.commit(params[:branch])&.id
+ end
+
+ def render_terminal(current_build)
+ render json: WebIdeTerminalSerializer
+ .new(project: project, current_user: current_user)
+ .represent(current_build)
+ end
+end
diff --git a/app/controllers/projects/wikis_controller.rb b/app/controllers/projects/wikis_controller.rb
index 508b1f5bd0a..85e643aa212 100644
--- a/app/controllers/projects/wikis_controller.rb
+++ b/app/controllers/projects/wikis_controller.rb
@@ -1,206 +1,11 @@
# frozen_string_literal: true
class Projects::WikisController < Projects::ApplicationController
+ include WikiActions
include PreviewMarkdown
- include SendsBlob
- include Gitlab::Utils::StrongMemoize
- before_action :authorize_read_wiki!
- before_action :authorize_create_wiki!, only: [:edit, :create]
- before_action :authorize_admin_wiki!, only: :destroy
- before_action :load_project_wiki
- before_action :load_page, only: [:show, :edit, :update, :history, :destroy]
- before_action only: [:show, :edit, :update] do
- @valid_encoding = valid_encoding?
- end
- before_action only: [:edit, :update], unless: :valid_encoding? do
- redirect_to(project_wiki_path(@project, @page))
- end
-
- def new
- redirect_to project_wiki_path(@project, SecureRandom.uuid, random_title: true)
- end
-
- def pages
- @wiki_pages = Kaminari.paginate_array(
- @project_wiki.list_pages(sort: params[:sort], direction: params[:direction])
- ).page(params[:page])
-
- @wiki_entries = WikiPage.group_by_directory(@wiki_pages)
- end
-
- # `#show` handles a number of scenarios:
- #
- # - If `id` matches a WikiPage, then show the wiki page.
- # - If `id` is a file in the wiki repository, then send the file.
- # - If we know the user wants to create a new page with the given `id`,
- # then display a create form.
- # - Otherwise show the empty wiki page and invite the user to create a page.
- def show
- if @page
- set_encoding_error unless valid_encoding?
-
- # Assign vars expected by MarkupHelper
- @ref = params[:version_id]
- @path = @page.path
-
- render 'show'
- elsif file_blob
- send_blob(@project_wiki.repository, file_blob, allow_caching: @project.public?)
- elsif show_create_form?
- # Assign a title to the WikiPage unless `id` is a randomly generated slug from #new
- title = params[:id] unless params[:random_title].present?
-
- @page = build_page(title: title)
-
- render 'edit'
- else
- render 'empty'
- end
- end
-
- def edit
- end
-
- def update
- return render('empty') unless can?(current_user, :create_wiki, @project)
-
- @page = WikiPages::UpdateService.new(container: @project, current_user: current_user, params: wiki_params).execute(@page)
-
- if @page.valid?
- redirect_to(
- project_wiki_path(@project, @page),
- notice: _('Wiki was successfully updated.')
- )
- else
- render 'edit'
- end
- rescue WikiPage::PageChangedError, WikiPage::PageRenameError, Gitlab::Git::Wiki::OperationError => e
- @error = e
- render 'edit'
- end
-
- def create
- @page = WikiPages::CreateService.new(container: @project, current_user: current_user, params: wiki_params).execute
-
- if @page.persisted?
- redirect_to(
- project_wiki_path(@project, @page),
- notice: _('Wiki was successfully updated.')
- )
- else
- render action: "edit"
- end
- rescue Gitlab::Git::Wiki::OperationError => e
- @page = build_page(wiki_params)
- @error = e
-
- render 'edit'
- end
-
- def history
- if @page
- @page_versions = Kaminari.paginate_array(@page.versions(page: params[:page].to_i),
- total_count: @page.count_versions)
- .page(params[:page])
- else
- redirect_to(
- project_wiki_path(@project, :home),
- notice: _("Page not found")
- )
- end
- end
-
- def destroy
- WikiPages::DestroyService.new(container: @project, current_user: current_user).execute(@page)
-
- redirect_to project_wiki_path(@project, :home),
- status: :found,
- notice: _("Page was successfully deleted")
- rescue Gitlab::Git::Wiki::OperationError => e
- @error = e
- render 'edit'
- end
+ alias_method :container, :project
def git_access
end
-
- private
-
- def show_create_form?
- can?(current_user, :create_wiki, @project) &&
- @page.nil? &&
- # Always show the create form when the wiki has had at least one page created.
- # Otherwise, we only show the form when the user has navigated from
- # the 'empty wiki' page
- (@project_wiki.exists? || params[:view] == 'create')
- end
-
- def load_project_wiki
- @project_wiki = load_wiki
-
- # Call #wiki to make sure the Wiki Repo is initialized
- @project_wiki.wiki
-
- @sidebar_page = @project_wiki.find_sidebar(params[:version_id])
-
- unless @sidebar_page # Fallback to default sidebar
- @sidebar_wiki_entries, @sidebar_limited = @project_wiki.sidebar_entries
- end
- rescue ProjectWiki::CouldNotCreateWikiError
- flash[:notice] = _("Could not create Wiki Repository at this time. Please try again later.")
- redirect_to project_path(@project)
- false
- end
-
- def load_wiki
- ProjectWiki.new(@project, current_user)
- end
-
- def wiki_params
- params.require(:wiki).permit(:title, :content, :format, :message, :last_commit_sha)
- end
-
- def build_page(args = {})
- WikiPage.new(@project_wiki).tap do |page|
- page.update_attributes(args) # rubocop:disable Rails/ActiveRecordAliases
- end
- end
-
- def load_page
- @page ||= find_page
- end
-
- def find_page
- @project_wiki.find_page(*page_params)
- end
-
- def page_params
- keys = [:id]
- keys << :version_id if params[:action] == 'show'
-
- params.values_at(*keys)
- end
-
- def valid_encoding?
- page_encoding == Encoding::UTF_8
- end
-
- def page_encoding
- strong_memoize(:page_encoding) { @page&.content&.encoding }
- end
-
- def set_encoding_error
- flash.now[:notice] = _("The content of this page is not encoded in UTF-8. Edits can only be made via the Git repository.")
- end
-
- def file_blob
- strong_memoize(:file_blob) do
- commit = @project_wiki.repository.commit(@project_wiki.default_branch)
-
- next unless commit
-
- @project_wiki.repository.blob_at(commit.id, params[:id])
- end
- end
end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 2f86b945b06..f0ddd62e996 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -34,6 +34,12 @@ class ProjectsController < Projects::ApplicationController
# Project Export Rate Limit
before_action :export_rate_limit, only: [:export, :download_export, :generate_new_export]
+ # Experiments
+ before_action only: [:new, :create] do
+ frontend_experimentation_tracking_data(:new_create_project_ui, 'click_tab')
+ push_frontend_feature_flag(:new_create_project_ui) if experiment_enabled?(:new_create_project_ui)
+ end
+
layout :determine_layout
def index
@@ -310,12 +316,11 @@ class ProjectsController < Projects::ApplicationController
render 'projects/empty' if @project.empty_repo?
else
if can?(current_user, :read_wiki, @project)
- @project_wiki = @project.wiki
- @wiki_home = @project_wiki.find_page('home', params[:version_id])
+ @wiki = @project.wiki
+ @wiki_home = @wiki.find_page('home', params[:version_id])
elsif @project.feature_available?(:issues, current_user)
@issues = issuables_collection.page(params[:page])
- @collection_type = 'Issue'
- @issuable_meta_data = issuable_meta_data(@issues, @collection_type, current_user)
+ @issuable_meta_data = Gitlab::IssuableMetadata.new(current_user, @issues).data
end
render :show
@@ -357,6 +362,7 @@ class ProjectsController < Projects::ApplicationController
def project_params_attributes
[
+ :allow_merge_on_skipped_pipeline,
:avatar,
:build_allow_git_fetch,
:build_coverage_regex,
@@ -483,11 +489,12 @@ class ProjectsController < Projects::ApplicationController
def export_rate_limit
prefixed_action = "project_#{params[:action]}".to_sym
- if rate_limiter.throttled?(prefixed_action, scope: [current_user, prefixed_action, @project])
+ project_scope = params[:action] == :download_export ? @project : nil
+
+ if rate_limiter.throttled?(prefixed_action, scope: [current_user, project_scope].compact)
rate_limiter.log_request(request, "#{prefixed_action}_request_limit".to_sym, current_user)
- flash[:alert] = _('This endpoint has been requested too many times. Try again later.')
- redirect_to edit_project_path(@project)
+ render plain: _('This endpoint has been requested too many times. Try again later.'), status: :too_many_requests
end
end
diff --git a/app/controllers/registrations/experience_levels_controller.rb b/app/controllers/registrations/experience_levels_controller.rb
new file mode 100644
index 00000000000..515d6b3f9aa
--- /dev/null
+++ b/app/controllers/registrations/experience_levels_controller.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+module Registrations
+ class ExperienceLevelsController < ApplicationController
+ # This will need to be changed to simply 'devise' as part of
+ # https://gitlab.com/gitlab-org/growth/engineering/issues/64
+ layout 'devise_experimental_separate_sign_up_flow'
+
+ before_action :check_experiment_enabled
+ before_action :ensure_namespace_path_param
+
+ def update
+ current_user.experience_level = params[:experience_level]
+
+ if current_user.save
+ hide_advanced_issues
+ flash[:message] = I18n.t('devise.registrations.signed_up')
+ redirect_to group_path(params[:namespace_path])
+ else
+ render :show
+ end
+ end
+
+ private
+
+ def check_experiment_enabled
+ access_denied! unless experiment_enabled?(:onboarding_issues)
+ end
+
+ 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?
+
+ settings = cookies[:onboarding_issues_settings]
+ return unless settings
+
+ modified_settings = Gitlab::Json.parse(settings).merge(hideAdvanced: true)
+ cookies[:onboarding_issues_settings] = modified_settings.to_json
+ end
+ end
+end
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
index ffbccbb01f2..6ab2924a8b5 100644
--- a/app/controllers/registrations_controller.rb
+++ b/app/controllers/registrations_controller.rb
@@ -63,6 +63,10 @@ class RegistrationsController < Devise::RegistrationsController
if result[:status] == :success
track_experiment_event(:signup_flow, 'end') # We want this event to be tracked when the user is _in_ the experimental group
+
+ track_experiment_event(:onboarding_issues, 'signed_up') if ::Gitlab.com? && !helpers.in_subscription_flow? && !helpers.in_invitation_flow?
+ return redirect_to new_users_sign_up_group_path if experiment_enabled?(:onboarding_issues) && !helpers.in_subscription_flow? && !helpers.in_invitation_flow?
+
set_flash_message! :notice, :signed_up
redirect_to path_for_signed_in_user(current_user)
else
diff --git a/app/controllers/repositories/git_http_controller.rb b/app/controllers/repositories/git_http_controller.rb
index e3dbe6fcbdf..6a27d63625e 100644
--- a/app/controllers/repositories/git_http_controller.rb
+++ b/app/controllers/repositories/git_http_controller.rb
@@ -9,7 +9,7 @@ module Repositories
rescue_from Gitlab::GitAccess::ForbiddenError, with: :render_403_with_exception
rescue_from Gitlab::GitAccess::NotFoundError, with: :render_404_with_exception
- rescue_from Gitlab::GitAccess::ProjectCreationError, with: :render_422_with_exception
+ rescue_from Gitlab::GitAccessProject::CreationError, with: :render_422_with_exception
rescue_from Gitlab::GitAccess::TimeoutError, with: :render_503_with_exception
# GET /foo/bar.git/info/refs?service=git-upload-pack (git pull)
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index 04d2b3068da..217f08dd648 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -5,6 +5,10 @@ class SearchController < ApplicationController
include SearchHelper
include RendersCommits
+ SCOPE_PRELOAD_METHOD = {
+ projects: :with_web_entity_associations
+ }.freeze
+
around_action :allow_gitaly_ref_name_caching
skip_before_action :authenticate_user!
@@ -28,12 +32,12 @@ class SearchController < ApplicationController
@scope = search_service.scope
@show_snippets = search_service.show_snippets?
@search_results = search_service.search_results
- @search_objects = search_service.search_objects
+ @search_objects = search_service.search_objects(preload_method)
render_commits if @scope == 'commits'
eager_load_user_status if @scope == 'users'
- increment_navbar_searches_counter
+ increment_search_counters
check_single_commit_result
end
@@ -47,22 +51,11 @@ class SearchController < ApplicationController
render json: { count: count }
end
- # rubocop: disable CodeReuse/ActiveRecord
- def autocomplete
- term = params[:term]
-
- if params[:project_id].present?
- @project = Project.find_by(id: params[:project_id])
- @project = nil unless can?(current_user, :read_project, @project)
- end
-
- @ref = params[:project_ref] if params[:project_ref].present?
+ private
- render json: search_autocomplete_opts(term).to_json
+ def preload_method
+ SCOPE_PRELOAD_METHOD[@scope.to_sym]
end
- # rubocop: enable CodeReuse/ActiveRecord
-
- private
def search_term_valid?
unless search_service.valid_query_length?
@@ -98,9 +91,11 @@ class SearchController < ApplicationController
end
end
- def increment_navbar_searches_counter
+ def increment_search_counters
+ Gitlab::UsageDataCounters::SearchCounter.count(:all_searches)
+
return if params[:nav_source] != 'navbar'
- Gitlab::UsageDataCounters::SearchCounter.increment_navbar_searches_count
+ Gitlab::UsageDataCounters::SearchCounter.count(:navbar_searches)
end
end
diff --git a/app/controllers/snippets/application_controller.rb b/app/controllers/snippets/application_controller.rb
new file mode 100644
index 00000000000..a533e46a75d
--- /dev/null
+++ b/app/controllers/snippets/application_controller.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class Snippets::ApplicationController < ApplicationController
+ include FindSnippet
+ include SnippetAuthorizations
+
+ private
+
+ def authorize_read_snippet!
+ return if can?(current_user, :read_snippet, snippet)
+
+ if current_user
+ render_404
+ else
+ authenticate_user!
+ end
+ end
+
+ def snippet_klass
+ PersonalSnippet
+ end
+end
diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb
index 425e0458b41..87d87390e57 100644
--- a/app/controllers/snippets_controller.rb
+++ b/app/controllers/snippets_controller.rb
@@ -1,19 +1,12 @@
# frozen_string_literal: true
-class SnippetsController < ApplicationController
- include RendersNotes
- include ToggleAwardEmoji
- include SpammableActions
+class SnippetsController < Snippets::ApplicationController
include SnippetsActions
- include RendersBlob
include PreviewMarkdown
- include PaginatedCollection
- include Gitlab::NoteableMetadata
-
- skip_before_action :verify_authenticity_token,
- if: -> { action_name == 'show' && js_request? }
+ include ToggleAwardEmoji
+ include SpammableActions
- before_action :snippet, only: [:show, :edit, :destroy, :update, :raw]
+ before_action :snippet, only: [:show, :edit, :destroy, :update, :raw, :toggle_award_emoji, :mark_as_spam]
before_action :authorize_create_snippet!, only: [:new, :create]
before_action :authorize_read_snippet!, only: [:show, :raw]
@@ -23,7 +16,6 @@ class SnippetsController < ApplicationController
skip_before_action :authenticate_user!, only: [:index, :show, :raw]
layout 'snippets'
- respond_to :html
def index
if params[:username].present?
@@ -60,62 +52,8 @@ class SnippetsController < ApplicationController
end
end
- def update
- service_response = Snippets::UpdateService.new(nil, current_user, snippet_params).execute(@snippet)
- @snippet = service_response.payload[:snippet]
-
- handle_repository_error(:edit)
- end
-
- def show
- conditionally_expand_blob(blob)
-
- respond_to do |format|
- format.html do
- @note = Note.new(noteable: @snippet)
- @noteable = @snippet
-
- @discussions = @snippet.discussions
- @notes = prepare_notes_for_rendering(@discussions.flat_map(&:notes), @noteable)
- render 'show'
- end
-
- format.json do
- render_blob_json(blob)
- end
-
- format.js do
- if @snippet.embeddable?
- render 'shared/snippets/show'
- else
- head :not_found
- end
- end
- end
- end
-
- def destroy
- service_response = Snippets::DestroyService.new(current_user, @snippet).execute
-
- if service_response.success?
- redirect_to dashboard_snippets_path, status: :found
- elsif service_response.http_status == 403
- access_denied!
- else
- redirect_to snippet_path(@snippet),
- status: :found,
- alert: service_response.message
- end
- end
-
protected
- # rubocop: disable CodeReuse/ActiveRecord
- def snippet
- @snippet ||= PersonalSnippet.inc_relations_for_view.find_by(id: params[:id])
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
alias_method :awardable, :snippet
alias_method :spammable, :snippet
@@ -123,28 +61,6 @@ class SnippetsController < ApplicationController
snippet_path(@snippet)
end
- def authorize_read_snippet!
- return if can?(current_user, :read_snippet, @snippet)
-
- if current_user
- render_404
- else
- authenticate_user!
- end
- end
-
- def authorize_update_snippet!
- return render_404 unless can?(current_user, :update_snippet, @snippet)
- end
-
- def authorize_admin_snippet!
- return render_404 unless can?(current_user, :admin_snippet, @snippet)
- end
-
- def authorize_create_snippet!
- return render_404 unless can?(current_user, :create_snippet)
- end
-
def snippet_params
params.require(:personal_snippet).permit(:title, :content, :file_name, :private, :visibility_level, :description).merge(spammable_params)
end
diff --git a/app/finders/admin/runners_finder.rb b/app/finders/admin/runners_finder.rb
deleted file mode 100644
index b2799565f57..00000000000
--- a/app/finders/admin/runners_finder.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-# frozen_string_literal: true
-
-class Admin::RunnersFinder < UnionFinder
- NUMBER_OF_RUNNERS_PER_PAGE = 30
-
- def initialize(params:)
- @params = params
- end
-
- def execute
- search!
- filter_by_status!
- filter_by_runner_type!
- filter_by_tag_list!
- sort!
- paginate!
-
- @runners.with_tags
- end
-
- def sort_key
- if @params[:sort] == 'contacted_asc'
- 'contacted_asc'
- else
- 'created_date'
- end
- end
-
- private
-
- def search!
- @runners =
- if @params[:search].present?
- Ci::Runner.search(@params[:search])
- else
- Ci::Runner.all
- end
- end
-
- def filter_by_status!
- filter_by!(:status_status, Ci::Runner::AVAILABLE_STATUSES)
- end
-
- def filter_by_runner_type!
- filter_by!(:type_type, Ci::Runner::AVAILABLE_TYPES)
- end
-
- def filter_by_tag_list!
- tag_list = @params[:tag_name].presence
-
- if tag_list
- @runners = @runners.tagged_with(tag_list)
- end
- end
-
- def sort!
- @runners = @runners.order_by(sort_key)
- end
-
- def paginate!
- @runners = @runners.page(@params[:page]).per(NUMBER_OF_RUNNERS_PER_PAGE)
- end
-
- def filter_by!(scope_name, available_scopes)
- scope = @params[scope_name]
-
- if scope.present? && available_scopes.include?(scope)
- @runners = @runners.public_send(scope) # rubocop:disable GitlabSecurity/PublicSend
- end
- end
-end
diff --git a/app/finders/ci/daily_build_group_report_results_finder.rb b/app/finders/ci/daily_build_group_report_results_finder.rb
index 3c3c24c1479..774f08d1ff2 100644
--- a/app/finders/ci/daily_build_group_report_results_finder.rb
+++ b/app/finders/ci/daily_build_group_report_results_finder.rb
@@ -14,21 +14,25 @@ module Ci
end
def execute
- return none unless can?(current_user, :download_code, project)
+ return none unless can?(current_user, :read_build_report_results, project)
Ci::DailyBuildGroupReportResult.recent_results(
- {
- project_id: project,
- ref_path: ref_path,
- date: start_date..end_date
- },
- limit: @limit
+ query_params,
+ limit: limit
)
end
private
- attr_reader :current_user, :project, :ref_path, :start_date, :end_date
+ attr_reader :current_user, :project, :ref_path, :start_date, :end_date, :limit
+
+ def query_params
+ {
+ project_id: project,
+ ref_path: ref_path,
+ date: start_date..end_date
+ }
+ end
def none
Ci::DailyBuildGroupReportResult.none
diff --git a/app/finders/ci/runners_finder.rb b/app/finders/ci/runners_finder.rb
new file mode 100644
index 00000000000..1b76211c524
--- /dev/null
+++ b/app/finders/ci/runners_finder.rb
@@ -0,0 +1,92 @@
+# frozen_string_literal: true
+
+module Ci
+ class RunnersFinder < UnionFinder
+ include Gitlab::Allowable
+
+ NUMBER_OF_RUNNERS_PER_PAGE = 30
+
+ def initialize(current_user:, group: nil, params:)
+ @params = params
+ @group = group
+ @current_user = current_user
+ end
+
+ def execute
+ search!
+ filter_by_status!
+ filter_by_runner_type!
+ filter_by_tag_list!
+ sort!
+ paginate!
+
+ @runners.with_tags
+
+ rescue Gitlab::Access::AccessDeniedError
+ Ci::Runner.none
+ end
+
+ def sort_key
+ if @params[:sort] == 'contacted_asc'
+ 'contacted_asc'
+ else
+ 'created_date'
+ end
+ end
+
+ private
+
+ def search!
+ @group ? group_runners : all_runners
+
+ @runners = @runners.search(@params[:search]) if @params[:search].present?
+ end
+
+ def all_runners
+ raise Gitlab::Access::AccessDeniedError unless @current_user&.admin?
+
+ @runners = Ci::Runner.all
+ end
+
+ 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)
+ end
+
+ def filter_by_status!
+ filter_by!(:status_status, Ci::Runner::AVAILABLE_STATUSES)
+ end
+
+ def filter_by_runner_type!
+ filter_by!(:type_type, Ci::Runner::AVAILABLE_TYPES)
+ end
+
+ def filter_by_tag_list!
+ tag_list = @params[:tag_name].presence
+
+ if tag_list
+ @runners = @runners.tagged_with(tag_list)
+ end
+ end
+
+ def sort!
+ @runners = @runners.order_by(sort_key)
+ end
+
+ def paginate!
+ @runners = @runners.page(@params[:page]).per(NUMBER_OF_RUNNERS_PER_PAGE)
+ end
+
+ def filter_by!(scope_name, available_scopes)
+ scope = @params[scope_name]
+
+ if scope.present? && available_scopes.include?(scope)
+ @runners = @runners.public_send(scope) # rubocop:disable GitlabSecurity/PublicSend
+ end
+ end
+ end
+end
diff --git a/app/finders/events_finder.rb b/app/finders/events_finder.rb
index 9c56451fd44..52612f1f8aa 100644
--- a/app/finders/events_finder.rb
+++ b/app/finders/events_finder.rb
@@ -72,9 +72,10 @@ class EventsFinder
# rubocop: disable CodeReuse/ActiveRecord
def by_action(events)
- return events unless Event::ACTIONS[params[:action]]
+ safe_action = Event.actions[params[:action]]
+ return events unless safe_action
- events.where(action: Event::ACTIONS[params[:action]])
+ events.where(action: safe_action)
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb
index 7014f2ec205..5cdc22fd873 100644
--- a/app/finders/issuable_finder.rb
+++ b/app/finders/issuable_finder.rb
@@ -451,7 +451,7 @@ class IssuableFinder
if params.filter_by_no_label?
items.without_label
elsif params.filter_by_any_label?
- items.any_label
+ items.any_label(params[:sort])
else
items.with_label(params.label_names, params[:sort])
end
diff --git a/app/finders/issuable_finder/params.rb b/app/finders/issuable_finder/params.rb
index adf9f1ca9d8..5b48d0817e3 100644
--- a/app/finders/issuable_finder/params.rb
+++ b/app/finders/issuable_finder/params.rb
@@ -105,7 +105,7 @@ class IssuableFinder
end
def project?
- params[:project_id].present?
+ project_id.present?
end
def group
@@ -132,15 +132,19 @@ class IssuableFinder
def project
strong_memoize(:project) do
- next nil unless params[:project_id].present?
+ next nil unless project?
- project = Project.find(params[:project_id])
+ project = project_id.is_a?(Project) ? project_id : Project.find(project_id)
project = nil unless Ability.allowed?(current_user, :"read_#{klass.to_ability_name}", project)
project
end
end
+ def project_id
+ params[:project_id]
+ end
+
def projects
strong_memoize(:projects) do
next [project] if project?
diff --git a/app/finders/labels_finder.rb b/app/finders/labels_finder.rb
index 027cdc4fc78..e726772fba4 100644
--- a/app/finders/labels_finder.rb
+++ b/app/finders/labels_finder.rb
@@ -46,7 +46,6 @@ class LabelsFinder < UnionFinder
end
else
if group?
- group = Group.find(params[:group_id])
label_ids << Label.where(group_id: group_ids_for(group))
end
@@ -123,7 +122,11 @@ class LabelsFinder < UnionFinder
end
def group?
- params[:group_id].present?
+ params[:group].present? || params[:group_id].present?
+ end
+
+ def group
+ strong_memoize(:group) { params[:group].presence || Group.find(params[:group_id]) }
end
def project?
@@ -169,7 +172,7 @@ class LabelsFinder < UnionFinder
ProjectsFinder.new(params: { non_archived: true }, current_user: current_user).execute # rubocop: disable CodeReuse/Finder
end
- @projects = @projects.in_namespace(params[:group_id]) if group?
+ @projects = @projects.in_namespace(group.id) if group?
@projects = @projects.where(id: params[:project_ids]) if projects?
@projects = @projects.reorder(nil)
diff --git a/app/finders/milestones_finder.rb b/app/finders/milestones_finder.rb
index cfe648d9f79..8f0cdf3b255 100644
--- a/app/finders/milestones_finder.rb
+++ b/app/finders/milestones_finder.rb
@@ -58,10 +58,8 @@ class MilestonesFinder
Milestone.filter_by_state(items, params[:state])
end
- # rubocop: disable CodeReuse/ActiveRecord
def order(items)
- order_statement = Gitlab::Database.nulls_last_order('due_date', 'ASC')
- items.reorder(order_statement).order('title ASC')
+ sort_by = params[:sort].presence || 'due_date_asc'
+ items.sort_by_attribute(sort_by)
end
- # rubocop: enable CodeReuse/ActiveRecord
end
diff --git a/app/finders/notes_finder.rb b/app/finders/notes_finder.rb
index e798db561bf..8e57014f66e 100644
--- a/app/finders/notes_finder.rb
+++ b/app/finders/notes_finder.rb
@@ -148,7 +148,7 @@ class NotesFinder
# Searches for notes matching the given query.
#
- # This method uses ILIKE on PostgreSQL and LIKE on MySQL.
+ # This method uses ILIKE on PostgreSQL.
#
def search(notes)
query = @params[:search]
diff --git a/app/finders/resource_label_event_finder.rb b/app/finders/resource_label_event_finder.rb
deleted file mode 100644
index 9aafd6e91b9..00000000000
--- a/app/finders/resource_label_event_finder.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-# frozen_string_literal: true
-
-class ResourceLabelEventFinder
- include FinderMethods
-
- MAX_PER_PAGE = 100
-
- attr_reader :params, :current_user, :eventable
-
- def initialize(current_user, eventable, params = {})
- @current_user = current_user
- @eventable = eventable
- @params = params
- end
-
- def execute
- events = eventable.resource_label_events.inc_relations
- events = events.page(page).per(per_page)
- events = visible_to_user(events)
-
- Kaminari.paginate_array(events)
- end
-
- private
-
- def visible_to_user(events)
- ResourceLabelEvent.preload_label_subjects(events)
-
- events.select do |event|
- Ability.allowed?(current_user, :read_label, event)
- end
- end
-
- def per_page
- [params[:per_page], MAX_PER_PAGE].compact.min
- end
-
- def page
- params[:page] || 1
- end
-end
diff --git a/app/finders/resource_milestone_event_finder.rb b/app/finders/resource_milestone_event_finder.rb
new file mode 100644
index 00000000000..7af34f0a4bc
--- /dev/null
+++ b/app/finders/resource_milestone_event_finder.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+class ResourceMilestoneEventFinder
+ include FinderMethods
+
+ MAX_PER_PAGE = 100
+
+ attr_reader :params, :current_user, :eventable
+
+ def initialize(current_user, eventable, params = {})
+ @current_user = current_user
+ @eventable = eventable
+ @params = params
+ end
+
+ def execute
+ Kaminari.paginate_array(visible_events)
+ end
+
+ private
+
+ def visible_events
+ @visible_events ||= visible_to_user(events)
+ end
+
+ def events
+ @events ||= eventable.resource_milestone_events.include_relations.page(page).per(per_page)
+ end
+
+ def visible_to_user(events)
+ events.select { |event| visible_for_user?(event) }
+ end
+
+ def visible_for_user?(event)
+ milestone = event_milestones[event.milestone_id]
+ return if milestone.blank?
+
+ parent = milestone.parent
+ parent_availabilities[key_for_parent(parent)]
+ end
+
+ def parent_availabilities
+ @parent_availabilities ||= relevant_parents.to_h do |parent|
+ [key_for_parent(parent), Ability.allowed?(current_user, :read_milestone, parent)]
+ end
+ end
+
+ def key_for_parent(parent)
+ "#{parent.class.name}_#{parent.id}"
+ end
+
+ def event_milestones
+ @milestones ||= events.map(&:milestone).uniq.to_h do |milestone|
+ [milestone.id, milestone]
+ end
+ end
+
+ def relevant_parents
+ @relevant_parents ||= event_milestones.map { |_id, milestone| milestone.parent }
+ end
+
+ def per_page
+ [params[:per_page], MAX_PER_PAGE].compact.min
+ end
+
+ def page
+ params[:page] || 1
+ end
+end
diff --git a/app/finders/uploader_finder.rb b/app/finders/uploader_finder.rb
new file mode 100644
index 00000000000..0d1de0d56fd
--- /dev/null
+++ b/app/finders/uploader_finder.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+class UploaderFinder
+ # Instantiates a a new FileUploader
+ # FileUploader can be opened via .open agnostic of storage type
+ # Arguments correspond to Upload.secret, Upload.model_type and Upload.file_path
+ # Returns a FileUploader with uploaded file retrieved into the object state
+ def initialize(project, secret, file_path)
+ @project = project
+ @secret = secret
+ @file_path = file_path
+ end
+
+ def execute
+ prevent_path_traversal_attack!
+ retrieve_file_state!
+
+ uploader
+ rescue ::Gitlab::Utils::PathTraversalAttackError
+ nil # no-op if for incorrect files
+ end
+
+ def prevent_path_traversal_attack!
+ Gitlab::Utils.check_path_traversal!(@file_path)
+ end
+
+ def retrieve_file_state!
+ uploader.retrieve_from_store!(@file_path)
+ end
+
+ def uploader
+ @uploader ||= FileUploader.new(@project, secret: @secret)
+ end
+end
diff --git a/app/finders/users_finder.rb b/app/finders/users_finder.rb
index ebb686c2aa7..f87e0c67604 100644
--- a/app/finders/users_finder.rb
+++ b/app/finders/users_finder.rb
@@ -15,6 +15,8 @@
# blocked: boolean
# external: boolean
# without_projects: boolean
+# sort: string
+# id: integer
#
class UsersFinder
include CreatedAtFilter
@@ -30,6 +32,7 @@ class UsersFinder
def execute
users = User.all.order_id_desc
users = by_username(users)
+ users = by_id(users)
users = by_search(users)
users = by_blocked(users)
users = by_active(users)
@@ -40,7 +43,7 @@ class UsersFinder
users = by_without_projects(users)
users = by_custom_attributes(users)
- users
+ order(users)
end
private
@@ -51,6 +54,12 @@ class UsersFinder
users.by_username(params[:username])
end
+ def by_id(users)
+ return users unless params[:id]
+
+ users.id_in(params[:id])
+ end
+
def by_search(users)
return users unless params[:search].present?
@@ -102,6 +111,14 @@ class UsersFinder
users.without_projects
end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def order(users)
+ return users unless params[:sort]
+
+ users.order_by(params[:sort])
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
end
UsersFinder.prepend_if_ee('EE::UsersFinder')
diff --git a/app/graphql/mutations/alert_management/alerts/set_assignees.rb b/app/graphql/mutations/alert_management/alerts/set_assignees.rb
new file mode 100644
index 00000000000..1e0c9fdeeaf
--- /dev/null
+++ b/app/graphql/mutations/alert_management/alerts/set_assignees.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+module Mutations
+ module AlertManagement
+ module Alerts
+ class SetAssignees < Base
+ graphql_name 'AlertSetAssignees'
+
+ argument :assignee_usernames,
+ [GraphQL::STRING_TYPE],
+ required: true,
+ description: 'The usernames to assign to the alert. Replaces existing assignees by default.'
+
+ argument :operation_mode,
+ Types::MutationOperationModeEnum,
+ required: false,
+ description: 'The operation to perform. Defaults to REPLACE.'
+
+ def resolve(args)
+ alert = authorized_find!(project_path: args[:project_path], iid: args[:iid])
+ result = set_assignees(alert, args[:assignee_usernames], args[:operation_mode])
+
+ prepare_response(result)
+ end
+
+ private
+
+ def set_assignees(alert, assignee_usernames, operation_mode)
+ operation_mode ||= Types::MutationOperationModeEnum.enum[:replace]
+
+ original_assignees = alert.assignees
+ target_users = find_target_users(assignee_usernames)
+
+ assignees = case Types::MutationOperationModeEnum.enum.key(operation_mode).to_sym
+ when :replace then target_users.uniq
+ when :append then (original_assignees + target_users).uniq
+ when :remove then (original_assignees - target_users)
+ end
+
+ ::AlertManagement::Alerts::UpdateService.new(alert, current_user, assignees: assignees).execute
+ end
+
+ def find_target_users(assignee_usernames)
+ UsersFinder.new(current_user, username: assignee_usernames).execute
+ end
+
+ def prepare_response(result)
+ {
+ alert: result.payload[:alert],
+ errors: result.error? ? [result.message] : []
+ }
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/alert_management/base.rb b/app/graphql/mutations/alert_management/base.rb
index ca2057d4845..7fcca63db51 100644
--- a/app/graphql/mutations/alert_management/base.rb
+++ b/app/graphql/mutations/alert_management/base.rb
@@ -3,7 +3,7 @@
module Mutations
module AlertManagement
class Base < BaseMutation
- include Mutations::ResolvesProject
+ include ResolvesProject
argument :project_path, GraphQL::ID_TYPE,
required: true,
@@ -32,7 +32,7 @@ module Mutations
return unless project
- resolver = Resolvers::AlertManagementAlertResolver.single.new(object: project, context: context, field: nil)
+ resolver = Resolvers::AlertManagement::AlertResolver.single.new(object: project, context: context, field: nil)
resolver.resolve(iid: iid)
end
end
diff --git a/app/graphql/mutations/alert_management/update_alert_status.rb b/app/graphql/mutations/alert_management/update_alert_status.rb
index e73a591378a..d820124d26f 100644
--- a/app/graphql/mutations/alert_management/update_alert_status.rb
+++ b/app/graphql/mutations/alert_management/update_alert_status.rb
@@ -27,7 +27,7 @@ module Mutations
def prepare_response(result)
{
alert: result.payload[:alert],
- errors: result.error? ? [result.message] : []
+ errors: result.errors
}
end
end
diff --git a/app/graphql/mutations/base_mutation.rb b/app/graphql/mutations/base_mutation.rb
index 30510cfab50..33f3f33a440 100644
--- a/app/graphql/mutations/base_mutation.rb
+++ b/app/graphql/mutations/base_mutation.rb
@@ -9,7 +9,7 @@ module Mutations
field :errors, [GraphQL::STRING_TYPE],
null: false,
- description: "Errors encountered during execution of the mutation."
+ description: 'Errors encountered during execution of the mutation.'
def current_user
context[:current_user]
diff --git a/app/graphql/mutations/branches/create.rb b/app/graphql/mutations/branches/create.rb
index 127d5447d0a..214fead2e80 100644
--- a/app/graphql/mutations/branches/create.rb
+++ b/app/graphql/mutations/branches/create.rb
@@ -3,7 +3,7 @@
module Mutations
module Branches
class Create < BaseMutation
- include Mutations::ResolvesProject
+ include ResolvesProject
graphql_name 'CreateBranch'
diff --git a/app/graphql/mutations/commits/create.rb b/app/graphql/mutations/commits/create.rb
new file mode 100644
index 00000000000..9ed1bb819c8
--- /dev/null
+++ b/app/graphql/mutations/commits/create.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Commits
+ class Create < BaseMutation
+ include ResolvesProject
+
+ graphql_name 'CommitCreate'
+
+ argument :project_path, GraphQL::ID_TYPE,
+ required: true,
+ description: 'Project full path the branch is associated with'
+
+ argument :branch, GraphQL::STRING_TYPE,
+ required: true,
+ description: 'Name of the branch'
+
+ argument :message,
+ GraphQL::STRING_TYPE,
+ required: true,
+ description: copy_field_description(Types::CommitType, :message)
+
+ argument :actions,
+ [Types::CommitActionType],
+ required: true,
+ description: 'Array of action hashes to commit as a batch'
+
+ field :commit,
+ Types::CommitType,
+ null: true,
+ description: 'The commit after mutation'
+
+ authorize :push_code
+
+ def resolve(project_path:, branch:, message:, actions:)
+ project = authorized_find!(full_path: project_path)
+
+ attributes = {
+ commit_message: message,
+ branch_name: branch,
+ start_branch: branch,
+ actions: actions.map { |action| action.to_h }
+ }
+
+ result = ::Files::MultiService.new(project, current_user, attributes).execute
+
+ {
+ commit: (project.repository.commit(result[:result]) if result[:status] == :success),
+ errors: Array.wrap(result[:message])
+ }
+ end
+
+ private
+
+ def find_object(full_path:)
+ resolve_project(full_path: full_path)
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/concerns/mutations/resolves_issuable.rb b/app/graphql/mutations/concerns/mutations/resolves_issuable.rb
index d63cc27a450..13a56f2e709 100644
--- a/app/graphql/mutations/concerns/mutations/resolves_issuable.rb
+++ b/app/graphql/mutations/concerns/mutations/resolves_issuable.rb
@@ -3,12 +3,22 @@
module Mutations
module ResolvesIssuable
extend ActiveSupport::Concern
- include Mutations::ResolvesProject
+
+ included do
+ include ResolvesProject
+ end
def resolve_issuable(type:, parent_path:, iid:)
parent = resolve_issuable_parent(type, parent_path)
+ key = type == :merge_request ? :iids : :iid
+ args = { key => iid.to_s }
+
+ resolver = issuable_resolver(type, parent, context)
+ ready, early_return = resolver.ready?(**args)
+
+ return early_return unless ready
- issuable_resolver(type, parent, context).resolve(iid: iid.to_s)
+ resolver.resolve(**args)
end
private
@@ -22,7 +32,7 @@ module Mutations
def resolve_issuable_parent(type, parent_path)
return unless type == :issue || type == :merge_request
- resolve_project(full_path: parent_path)
+ resolve_project(full_path: parent_path) if parent_path.present?
end
end
end
diff --git a/app/graphql/mutations/concerns/mutations/resolves_project.rb b/app/graphql/mutations/concerns/mutations/resolves_project.rb
deleted file mode 100644
index e223e3edd94..00000000000
--- a/app/graphql/mutations/concerns/mutations/resolves_project.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-module Mutations
- module ResolvesProject
- extend ActiveSupport::Concern
-
- def resolve_project(full_path:)
- project_resolver.resolve(full_path: full_path)
- end
-
- def project_resolver
- Resolvers::ProjectResolver.new(object: nil, context: context, field: nil)
- end
- end
-end
diff --git a/app/graphql/mutations/container_expiration_policies/update.rb b/app/graphql/mutations/container_expiration_policies/update.rb
new file mode 100644
index 00000000000..c210571c6ca
--- /dev/null
+++ b/app/graphql/mutations/container_expiration_policies/update.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+module Mutations
+ module ContainerExpirationPolicies
+ class Update < Mutations::BaseMutation
+ include ResolvesProject
+
+ graphql_name 'UpdateContainerExpirationPolicy'
+
+ authorize :destroy_container_image
+
+ argument :project_path,
+ GraphQL::ID_TYPE,
+ required: true,
+ description: 'The project path where the container expiration policy is located'
+
+ argument :enabled,
+ GraphQL::BOOLEAN_TYPE,
+ required: false,
+ description: copy_field_description(Types::ContainerExpirationPolicyType, :enabled)
+
+ argument :cadence,
+ Types::ContainerExpirationPolicyCadenceEnum,
+ required: false,
+ description: copy_field_description(Types::ContainerExpirationPolicyType, :cadence)
+
+ argument :older_than,
+ Types::ContainerExpirationPolicyOlderThanEnum,
+ required: false,
+ description: copy_field_description(Types::ContainerExpirationPolicyType, :older_than)
+
+ argument :keep_n,
+ Types::ContainerExpirationPolicyKeepEnum,
+ required: false,
+ description: copy_field_description(Types::ContainerExpirationPolicyType, :keep_n)
+
+ field :container_expiration_policy,
+ Types::ContainerExpirationPolicyType,
+ null: true,
+ description: 'The container expiration policy after mutation'
+
+ def resolve(project_path:, **args)
+ project = authorized_find!(full_path: project_path)
+
+ result = ::ContainerExpirationPolicies::UpdateService
+ .new(container: project, current_user: current_user, params: args)
+ .execute
+
+ {
+ container_expiration_policy: result.payload[:container_expiration_policy],
+ errors: result.errors
+ }
+ end
+
+ private
+
+ def find_object(full_path:)
+ resolve_project(full_path: full_path)
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/discussions/toggle_resolve.rb b/app/graphql/mutations/discussions/toggle_resolve.rb
new file mode 100644
index 00000000000..41fd22c6b55
--- /dev/null
+++ b/app/graphql/mutations/discussions/toggle_resolve.rb
@@ -0,0 +1,73 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Discussions
+ class ToggleResolve < BaseMutation
+ graphql_name 'DiscussionToggleResolve'
+
+ description 'Toggles the resolved state of a discussion'
+
+ argument :id,
+ GraphQL::ID_TYPE,
+ required: true,
+ description: 'The global id of the discussion'
+
+ argument :resolve,
+ GraphQL::BOOLEAN_TYPE,
+ required: true,
+ description: 'Will resolve the discussion when true, and unresolve the discussion when false'
+
+ field :discussion,
+ Types::Notes::DiscussionType,
+ null: true,
+ description: 'The discussion after mutation'
+
+ def resolve(id:, resolve:)
+ discussion = authorized_find_discussion!(id: id)
+ errors = []
+
+ begin
+ if resolve
+ resolve!(discussion)
+ else
+ unresolve!(discussion)
+ end
+ rescue ActiveRecord::RecordNotSaved
+ errors << "Discussion failed to be #{'un' unless resolve}resolved"
+ end
+
+ {
+ discussion: discussion,
+ errors: errors
+ }
+ end
+
+ private
+
+ # `Discussion` permissions are checked through `Discussion#can_resolve?`,
+ # so we use this method of checking permissions rather than by defining
+ # an `authorize` permission and calling `authorized_find!`.
+ def authorized_find_discussion!(id:)
+ find_object(id: id).tap do |discussion|
+ raise_resource_not_available_error! unless discussion&.can_resolve?(current_user)
+ end
+ end
+
+ def find_object(id:)
+ GitlabSchema.object_from_id(id, expected_type: ::Discussion)
+ end
+
+ def resolve!(discussion)
+ ::Discussions::ResolveService.new(
+ discussion.project,
+ current_user,
+ one_or_more_discussions: discussion
+ ).execute
+ end
+
+ def unresolve!(discussion)
+ discussion.unresolve!
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/issues/set_confidential.rb b/app/graphql/mutations/issues/set_confidential.rb
index 0fff5518665..75befddc261 100644
--- a/app/graphql/mutations/issues/set_confidential.rb
+++ b/app/graphql/mutations/issues/set_confidential.rb
@@ -19,7 +19,7 @@ module Mutations
{
issue: issue,
- errors: issue.errors.full_messages
+ errors: errors_on_object(issue)
}
end
end
diff --git a/app/graphql/mutations/issues/set_due_date.rb b/app/graphql/mutations/issues/set_due_date.rb
index 1855c6f053b..effd863c541 100644
--- a/app/graphql/mutations/issues/set_due_date.rb
+++ b/app/graphql/mutations/issues/set_due_date.rb
@@ -19,7 +19,7 @@ module Mutations
{
issue: issue,
- errors: issue.errors.full_messages
+ errors: errors_on_object(issue)
}
end
end
diff --git a/app/graphql/mutations/issues/update.rb b/app/graphql/mutations/issues/update.rb
index 3710144fff5..7f6d9b0f988 100644
--- a/app/graphql/mutations/issues/update.rb
+++ b/app/graphql/mutations/issues/update.rb
@@ -33,7 +33,7 @@ module Mutations
{
issue: issue,
- errors: issue.errors.full_messages
+ errors: errors_on_object(issue)
}
end
end
diff --git a/app/graphql/mutations/jira_import/import_users.rb b/app/graphql/mutations/jira_import/import_users.rb
new file mode 100644
index 00000000000..c7225e1a99c
--- /dev/null
+++ b/app/graphql/mutations/jira_import/import_users.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+module Mutations
+ module JiraImport
+ class ImportUsers < BaseMutation
+ include ResolvesProject
+
+ graphql_name 'JiraImportUsers'
+
+ field :jira_users,
+ [Types::JiraUserType],
+ null: true,
+ description: 'Users returned from Jira, matched by email and name if possible.'
+
+ argument :project_path, GraphQL::ID_TYPE,
+ required: true,
+ description: 'The project to import the Jira users into'
+ argument :start_at, GraphQL::INT_TYPE,
+ required: false,
+ description: 'The index of the record the import should started at, default 0 (50 records returned)'
+
+ def resolve(project_path:, start_at:)
+ project = authorized_find!(full_path: project_path)
+
+ service_response = ::JiraImport::UsersImporter.new(context[:current_user], project, start_at).execute
+
+ {
+ jira_users: service_response.payload,
+ errors: service_response.errors
+ }
+ end
+
+ private
+
+ def find_object(full_path:)
+ resolve_project(full_path: full_path)
+ end
+
+ def authorized_resource?(project)
+ Ability.allowed?(context[:current_user], :admin_project, project)
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/jira_import/start.rb b/app/graphql/mutations/jira_import/start.rb
index 6b80c9f8ca4..3df26d33711 100644
--- a/app/graphql/mutations/jira_import/start.rb
+++ b/app/graphql/mutations/jira_import/start.rb
@@ -3,7 +3,7 @@
module Mutations
module JiraImport
class Start < BaseMutation
- include Mutations::ResolvesProject
+ include ResolvesProject
graphql_name 'JiraImportStart'
@@ -23,29 +23,21 @@ module Mutations
description: 'Project name of the importer Jira project'
def resolve(project_path:, jira_project_key:)
- project = find_project!(project_path: project_path)
-
- raise_resource_not_available_error! unless project
+ project = authorized_find!(full_path: project_path)
service_response = ::JiraImport::StartImportService
.new(context[:current_user], project, jira_project_key)
.execute
jira_import = service_response.success? ? service_response.payload[:import_data] : nil
- errors = service_response.error? ? [service_response.message] : []
+
{
jira_import: jira_import,
- errors: errors
+ errors: service_response.errors
}
end
private
- def find_project!(project_path:)
- return unless project_path.present?
-
- authorized_find!(full_path: project_path)
- end
-
def find_object(full_path:)
resolve_project(full_path: full_path)
end
diff --git a/app/graphql/mutations/merge_requests/create.rb b/app/graphql/mutations/merge_requests/create.rb
new file mode 100644
index 00000000000..e210987f259
--- /dev/null
+++ b/app/graphql/mutations/merge_requests/create.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+module Mutations
+ module MergeRequests
+ class Create < BaseMutation
+ include ResolvesProject
+
+ graphql_name 'MergeRequestCreate'
+
+ argument :project_path, GraphQL::ID_TYPE,
+ required: true,
+ description: 'Project full path the merge request is associated with'
+
+ argument :title, GraphQL::STRING_TYPE,
+ required: true,
+ description: copy_field_description(Types::MergeRequestType, :title)
+
+ argument :source_branch, GraphQL::STRING_TYPE,
+ required: true,
+ description: copy_field_description(Types::MergeRequestType, :source_branch)
+
+ argument :target_branch, GraphQL::STRING_TYPE,
+ required: true,
+ description: copy_field_description(Types::MergeRequestType, :target_branch)
+
+ argument :description, GraphQL::STRING_TYPE,
+ required: false,
+ description: copy_field_description(Types::MergeRequestType, :description)
+
+ field :merge_request,
+ Types::MergeRequestType,
+ null: true,
+ description: 'The merge request after mutation'
+
+ authorize :create_merge_request_from
+
+ def resolve(project_path:, title:, source_branch:, target_branch:, description: nil)
+ project = authorized_find!(full_path: project_path)
+
+ attributes = {
+ title: title,
+ source_branch: source_branch,
+ target_branch: target_branch,
+ author_id: current_user.id,
+ description: description
+ }
+
+ merge_request = ::MergeRequests::CreateService.new(project, current_user, attributes).execute
+
+ {
+ merge_request: merge_request.valid? ? merge_request : nil,
+ errors: errors_on_object(merge_request)
+ }
+ end
+
+ private
+
+ def find_object(full_path:)
+ resolve_project(full_path: full_path)
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/merge_requests/set_assignees.rb b/app/graphql/mutations/merge_requests/set_assignees.rb
index 8f0025f0a58..de244b62d0f 100644
--- a/app/graphql/mutations/merge_requests/set_assignees.rb
+++ b/app/graphql/mutations/merge_requests/set_assignees.rb
@@ -40,7 +40,7 @@ module Mutations
{
merge_request: merge_request,
- errors: merge_request.errors.full_messages
+ errors: errors_on_object(merge_request)
}
end
end
diff --git a/app/graphql/mutations/merge_requests/set_labels.rb b/app/graphql/mutations/merge_requests/set_labels.rb
index 71f7a353bc9..c1e45808593 100644
--- a/app/graphql/mutations/merge_requests/set_labels.rb
+++ b/app/graphql/mutations/merge_requests/set_labels.rb
@@ -24,8 +24,9 @@ module Mutations
project = merge_request.project
label_ids = label_ids
+ .map { |gid| GlobalID.parse(gid) }
.select(&method(:label_descendant?))
- .map { |gid| GlobalID.parse(gid).model_id } # MergeRequests::UpdateService expects integers
+ .map(&:model_id) # MergeRequests::UpdateService expects integers
attribute_name = case operation_mode
when Types::MutationOperationModeEnum.enum[:append]
@@ -41,12 +42,12 @@ module Mutations
{
merge_request: merge_request,
- errors: merge_request.errors.full_messages
+ errors: errors_on_object(merge_request)
}
end
def label_descendant?(gid)
- GlobalID.parse(gid)&.model_class&.ancestors&.include?(Label)
+ gid&.model_class&.ancestors&.include?(Label)
end
end
end
diff --git a/app/graphql/mutations/merge_requests/set_locked.rb b/app/graphql/mutations/merge_requests/set_locked.rb
index 09aaa0b39aa..c49d5186a03 100644
--- a/app/graphql/mutations/merge_requests/set_locked.rb
+++ b/app/graphql/mutations/merge_requests/set_locked.rb
@@ -21,7 +21,7 @@ module Mutations
{
merge_request: merge_request,
- errors: merge_request.errors.full_messages
+ errors: errors_on_object(merge_request)
}
end
end
diff --git a/app/graphql/mutations/merge_requests/set_milestone.rb b/app/graphql/mutations/merge_requests/set_milestone.rb
index 707d6677952..b3412dd9ed2 100644
--- a/app/graphql/mutations/merge_requests/set_milestone.rb
+++ b/app/graphql/mutations/merge_requests/set_milestone.rb
@@ -22,7 +22,7 @@ module Mutations
{
merge_request: merge_request,
- errors: merge_request.errors.full_messages
+ errors: errors_on_object(merge_request)
}
end
end
diff --git a/app/graphql/mutations/merge_requests/set_subscription.rb b/app/graphql/mutations/merge_requests/set_subscription.rb
index 86750152775..1535481ab37 100644
--- a/app/graphql/mutations/merge_requests/set_subscription.rb
+++ b/app/graphql/mutations/merge_requests/set_subscription.rb
@@ -18,7 +18,7 @@ module Mutations
{
merge_request: merge_request,
- errors: merge_request.errors.full_messages
+ errors: errors_on_object(merge_request)
}
end
end
diff --git a/app/graphql/mutations/merge_requests/set_wip.rb b/app/graphql/mutations/merge_requests/set_wip.rb
index a2aa0c84ee4..5d2077c12f2 100644
--- a/app/graphql/mutations/merge_requests/set_wip.rb
+++ b/app/graphql/mutations/merge_requests/set_wip.rb
@@ -21,7 +21,7 @@ module Mutations
{
merge_request: merge_request,
- errors: merge_request.errors.full_messages
+ errors: errors_on_object(merge_request)
}
end
diff --git a/app/graphql/mutations/metrics/dashboard/annotations/base.rb b/app/graphql/mutations/metrics/dashboard/annotations/base.rb
new file mode 100644
index 00000000000..3126267da64
--- /dev/null
+++ b/app/graphql/mutations/metrics/dashboard/annotations/base.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Metrics
+ module Dashboard
+ module Annotations
+ class Base < BaseMutation
+ private
+
+ # This method is defined here in order to be used by `authorized_find!` in the subclasses.
+ def find_object(id:)
+ GitlabSchema.object_from_id(id)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/metrics/dashboard/annotations/delete.rb b/app/graphql/mutations/metrics/dashboard/annotations/delete.rb
new file mode 100644
index 00000000000..fb828ba0e2f
--- /dev/null
+++ b/app/graphql/mutations/metrics/dashboard/annotations/delete.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Metrics
+ module Dashboard
+ module Annotations
+ class Delete < Base
+ graphql_name 'DeleteAnnotation'
+
+ authorize :delete_metrics_dashboard_annotation
+
+ argument :id,
+ GraphQL::ID_TYPE,
+ required: true,
+ description: 'The global id of the annotation to delete'
+
+ def resolve(id:)
+ annotation = authorized_find!(id: id)
+
+ result = ::Metrics::Dashboard::Annotations::DeleteService.new(context[:current_user], annotation).execute
+
+ errors = Array.wrap(result[:message])
+
+ {
+ errors: errors
+ }
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/snippets/create.rb b/app/graphql/mutations/snippets/create.rb
index 6fc223fbee7..e1022358c09 100644
--- a/app/graphql/mutations/snippets/create.rb
+++ b/app/graphql/mutations/snippets/create.rb
@@ -3,7 +3,7 @@
module Mutations
module Snippets
class Create < BaseMutation
- include Mutations::ResolvesProject
+ include ResolvesProject
graphql_name 'CreateSnippet'
@@ -60,7 +60,7 @@ module Mutations
snippet = service_response.payload[:snippet]
{
- snippet: snippet.valid? ? snippet : nil,
+ snippet: service_response.success? ? snippet : nil,
errors: errors_on_object(snippet)
}
end
diff --git a/app/graphql/mutations/todos/mark_all_done.rb b/app/graphql/mutations/todos/mark_all_done.rb
index 5694985717c..d30d1bcbcf0 100644
--- a/app/graphql/mutations/todos/mark_all_done.rb
+++ b/app/graphql/mutations/todos/mark_all_done.rb
@@ -28,7 +28,9 @@ module Mutations
def mark_all_todos_done
return [] unless current_user
- TodoService.new.mark_all_todos_as_done_by_user(current_user)
+ todos = TodosFinder.new(current_user).execute
+
+ TodoService.new.resolve_todos(todos, current_user, resolved_by_action: :api_all_done)
end
end
end
diff --git a/app/graphql/mutations/todos/mark_done.rb b/app/graphql/mutations/todos/mark_done.rb
index d738e387c43..748e02d8782 100644
--- a/app/graphql/mutations/todos/mark_done.rb
+++ b/app/graphql/mutations/todos/mark_done.rb
@@ -30,7 +30,7 @@ module Mutations
private
def mark_done(todo)
- TodoService.new.mark_todo_as_done(todo, current_user)
+ TodoService.new.resolve_todo(todo, current_user, resolved_by_action: :api_done)
end
end
end
diff --git a/app/graphql/mutations/todos/restore.rb b/app/graphql/mutations/todos/restore.rb
index c4597bd84a2..a0a1772db0a 100644
--- a/app/graphql/mutations/todos/restore.rb
+++ b/app/graphql/mutations/todos/restore.rb
@@ -18,7 +18,7 @@ module Mutations
def resolve(id:)
todo = authorized_find!(id: id)
- restore(todo.id) if todo.done?
+ restore(todo)
{
todo: todo.reset,
@@ -28,8 +28,8 @@ module Mutations
private
- def restore(id)
- TodoService.new.mark_todos_as_pending_by_ids([id], current_user)
+ def restore(todo)
+ TodoService.new.restore_todo(todo, current_user)
end
end
end
diff --git a/app/graphql/mutations/todos/restore_many.rb b/app/graphql/mutations/todos/restore_many.rb
index 8a6265207cd..e95651b232f 100644
--- a/app/graphql/mutations/todos/restore_many.rb
+++ b/app/graphql/mutations/todos/restore_many.rb
@@ -68,7 +68,7 @@ module Mutations
end
def restore(todos)
- TodoService.new.mark_todos_as_pending(todos, current_user)
+ TodoService.new.restore_todos(todos, current_user)
end
end
end
diff --git a/app/graphql/resolvers/alert_management/alert_resolver.rb b/app/graphql/resolvers/alert_management/alert_resolver.rb
new file mode 100644
index 00000000000..71a7615685a
--- /dev/null
+++ b/app/graphql/resolvers/alert_management/alert_resolver.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+module Resolvers
+ module AlertManagement
+ class AlertResolver < BaseResolver
+ include LooksAhead
+
+ argument :iid, GraphQL::STRING_TYPE,
+ required: false,
+ description: 'IID of the alert. For example, "1"'
+
+ argument :statuses, [Types::AlertManagement::StatusEnum],
+ as: :status,
+ required: false,
+ description: 'Alerts with the specified statues. For example, [TRIGGERED]'
+
+ argument :sort, Types::AlertManagement::AlertSortEnum,
+ description: 'Sort alerts by this criteria',
+ required: false
+
+ argument :search, GraphQL::STRING_TYPE,
+ description: 'Search criteria for filtering alerts. This will search on title, description, service, monitoring_tool.',
+ required: false
+
+ type Types::AlertManagement::AlertType, null: true
+
+ def resolve_with_lookahead(**args)
+ parent = object.respond_to?(:sync) ? object.sync : object
+ return ::AlertManagement::Alert.none if parent.nil?
+
+ apply_lookahead(::AlertManagement::AlertsFinder.new(context[:current_user], parent, args).execute)
+ end
+
+ def preloads
+ {
+ assignees: [:assignees],
+ notes: [:ordered_notes, { ordered_notes: [:system_note_metadata, :project, :noteable] }]
+ }
+ end
+ end
+ end
+end
diff --git a/app/graphql/resolvers/alert_management/alert_status_counts_resolver.rb b/app/graphql/resolvers/alert_management/alert_status_counts_resolver.rb
index 7f4346632ca..a45de21002f 100644
--- a/app/graphql/resolvers/alert_management/alert_status_counts_resolver.rb
+++ b/app/graphql/resolvers/alert_management/alert_status_counts_resolver.rb
@@ -5,6 +5,10 @@ module Resolvers
class AlertStatusCountsResolver < BaseResolver
type Types::AlertManagement::AlertStatusCountsType, null: true
+ argument :search, GraphQL::STRING_TYPE,
+ description: 'Search criteria for filtering alerts. This will search on title, description, service, monitoring_tool.',
+ required: false
+
def resolve(**args)
::Gitlab::AlertManagement::AlertStatusCounts.new(context[:current_user], object, args)
end
diff --git a/app/graphql/resolvers/alert_management_alert_resolver.rb b/app/graphql/resolvers/alert_management_alert_resolver.rb
deleted file mode 100644
index 51ebbb96476..00000000000
--- a/app/graphql/resolvers/alert_management_alert_resolver.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-# frozen_string_literal: true
-
-module Resolvers
- class AlertManagementAlertResolver < BaseResolver
- argument :iid, GraphQL::STRING_TYPE,
- required: false,
- description: 'IID of the alert. For example, "1"'
-
- argument :statuses, [Types::AlertManagement::StatusEnum],
- as: :status,
- required: false,
- description: 'Alerts with the specified statues. For example, [TRIGGERED]'
-
- argument :sort, Types::AlertManagement::AlertSortEnum,
- description: 'Sort alerts by this criteria',
- required: false
-
- argument :search, GraphQL::STRING_TYPE,
- description: 'Search criteria for filtering alerts. This will search on title, description, service, monitoring_tool.',
- required: false
-
- type Types::AlertManagement::AlertType, null: true
-
- def resolve(**args)
- parent = object.respond_to?(:sync) ? object.sync : object
- return ::AlertManagement::Alert.none if parent.nil?
-
- ::AlertManagement::AlertsFinder.new(context[:current_user], parent, args).execute
- end
- end
-end
diff --git a/app/graphql/resolvers/assigned_merge_requests_resolver.rb b/app/graphql/resolvers/assigned_merge_requests_resolver.rb
new file mode 100644
index 00000000000..fa08b142a7e
--- /dev/null
+++ b/app/graphql/resolvers/assigned_merge_requests_resolver.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+module Resolvers
+ class AssignedMergeRequestsResolver < UserMergeRequestsResolver
+ def user_role
+ :assignee
+ end
+ end
+end
diff --git a/app/graphql/resolvers/authored_merge_requests_resolver.rb b/app/graphql/resolvers/authored_merge_requests_resolver.rb
new file mode 100644
index 00000000000..e19bc9e8715
--- /dev/null
+++ b/app/graphql/resolvers/authored_merge_requests_resolver.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+module Resolvers
+ class AuthoredMergeRequestsResolver < UserMergeRequestsResolver
+ def user_role
+ :author
+ end
+ end
+end
diff --git a/app/graphql/resolvers/base_resolver.rb b/app/graphql/resolvers/base_resolver.rb
index cf0642930ad..7daff68c069 100644
--- a/app/graphql/resolvers/base_resolver.rb
+++ b/app/graphql/resolvers/base_resolver.rb
@@ -3,27 +3,33 @@
module Resolvers
class BaseResolver < GraphQL::Schema::Resolver
extend ::Gitlab::Utils::Override
+ include ::Gitlab::Utils::StrongMemoize
def self.single
@single ||= Class.new(self) do
+ def ready?(**args)
+ ready, early_return = super
+ [ready, select_result(early_return)]
+ end
+
def resolve(**args)
- super.first
+ select_result(super)
end
def single?
true
end
+
+ def select_result(results)
+ results&.first
+ end
end
end
def self.last
- @last ||= Class.new(self) do
- def resolve(**args)
- super.last
- end
-
- def single?
- true
+ @last ||= Class.new(self.single) do
+ def select_result(results)
+ results&.last
end
end
end
@@ -59,6 +65,17 @@ module Resolvers
end
end
+ def synchronized_object
+ strong_memoize(:synchronized_object) do
+ case object
+ when BatchLoader::GraphQL
+ object.sync
+ else
+ object
+ end
+ end
+ end
+
def single?
false
end
diff --git a/app/graphql/resolvers/concerns/looks_ahead.rb b/app/graphql/resolvers/concerns/looks_ahead.rb
new file mode 100644
index 00000000000..becc6debd33
--- /dev/null
+++ b/app/graphql/resolvers/concerns/looks_ahead.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+module LooksAhead
+ extend ActiveSupport::Concern
+
+ FEATURE_FLAG = :graphql_lookahead_support
+
+ included do
+ attr_accessor :lookahead
+ end
+
+ def resolve(**args)
+ self.lookahead = args.delete(:lookahead)
+
+ resolve_with_lookahead(**args)
+ end
+
+ def apply_lookahead(query)
+ return query unless Feature.enabled?(FEATURE_FLAG)
+
+ selection = node_selection
+
+ includes = preloads.each.flat_map do |name, requirements|
+ selection&.selects?(name) ? requirements : []
+ end
+ preloads = (unconditional_includes + includes).uniq
+
+ return query if preloads.empty?
+
+ query.preload(*preloads) # rubocop: disable CodeReuse/ActiveRecord
+ end
+
+ private
+
+ def unconditional_includes
+ []
+ end
+
+ def preloads
+ {}
+ end
+
+ def node_selection
+ return unless lookahead
+
+ if lookahead.selects?(:nodes)
+ lookahead.selection(:nodes)
+ elsif lookahead.selects?(:edges)
+ lookahead.selection(:edges).selection(:nodes)
+ end
+ end
+end
diff --git a/app/graphql/resolvers/concerns/resolves_merge_requests.rb b/app/graphql/resolvers/concerns/resolves_merge_requests.rb
new file mode 100644
index 00000000000..a2140728a27
--- /dev/null
+++ b/app/graphql/resolvers/concerns/resolves_merge_requests.rb
@@ -0,0 +1,67 @@
+# frozen_string_literal: true
+
+# Mixin for resolving merge requests. All arguments must be in forms
+# that `MergeRequestsFinder` can handle, so you may need to use aliasing.
+module ResolvesMergeRequests
+ extend ActiveSupport::Concern
+ include LooksAhead
+
+ included do
+ type Types::MergeRequestType, null: true
+ end
+
+ def resolve_with_lookahead(**args)
+ args[:iids] = Array.wrap(args[:iids]) if args[:iids]
+ args.compact!
+
+ if project && args.keys == [:iids]
+ batch_load_merge_requests(args[:iids])
+ else
+ args[:project_id] ||= project
+
+ apply_lookahead(MergeRequestsFinder.new(current_user, args).execute)
+ end.then(&(single? ? :first : :itself))
+ end
+
+ def ready?(**args)
+ return early_return if no_results_possible?(args)
+
+ super
+ end
+
+ def early_return
+ [false, single? ? nil : MergeRequest.none]
+ end
+
+ private
+
+ def batch_load_merge_requests(iids)
+ iids.map { |iid| batch_load(iid) }.select(&:itself) # .compact doesn't work on BatchLoader
+ end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def batch_load(iid)
+ BatchLoader::GraphQL.for(iid.to_s).batch(key: project) do |iids, loader, args|
+ query = args[:key].merge_requests.where(iid: iids)
+
+ apply_lookahead(query).each do |mr|
+ loader.call(mr.iid.to_s, mr)
+ end
+ end
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ def unconditional_includes
+ [:target_project]
+ end
+
+ def preloads
+ {
+ assignees: [:assignees],
+ labels: [:labels],
+ author: [:author],
+ milestone: [:milestone],
+ head_pipeline: [:merge_request_diff, { head_pipeline: [:merge_request] }]
+ }
+ end
+end
diff --git a/app/graphql/resolvers/concerns/resolves_project.rb b/app/graphql/resolvers/concerns/resolves_project.rb
new file mode 100644
index 00000000000..3c5ce3dab01
--- /dev/null
+++ b/app/graphql/resolvers/concerns/resolves_project.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module ResolvesProject
+ def resolve_project(full_path: nil, project_id: nil)
+ unless full_path.present? ^ project_id.present?
+ raise ::Gitlab::Graphql::Errors::ArgumentError, 'Incompatible arguments: projectId, projectPath.'
+ end
+
+ if full_path.present?
+ ::Gitlab::Graphql::Loaders::FullPathModelLoader.new(Project, full_path).find
+ else
+ ::GitlabSchema.object_from_id(project_id, expected_type: Project)
+ end
+ end
+end
diff --git a/app/graphql/resolvers/full_path_resolver.rb b/app/graphql/resolvers/full_path_resolver.rb
index 46d3360baae..cbb0bf998a6 100644
--- a/app/graphql/resolvers/full_path_resolver.rb
+++ b/app/graphql/resolvers/full_path_resolver.rb
@@ -11,12 +11,7 @@ module Resolvers
end
def model_by_full_path(model, full_path)
- BatchLoader::GraphQL.for(full_path).batch(key: model) 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)
- end
- end
+ ::Gitlab::Graphql::Loaders::FullPathModelLoader.new(model, full_path).find
end
end
end
diff --git a/app/graphql/resolvers/merge_request_resolver.rb b/app/graphql/resolvers/merge_request_resolver.rb
new file mode 100644
index 00000000000..a47a128ea32
--- /dev/null
+++ b/app/graphql/resolvers/merge_request_resolver.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module Resolvers
+ class MergeRequestResolver < BaseResolver.single
+ include ResolvesMergeRequests
+
+ alias_method :project, :synchronized_object
+
+ argument :iid, GraphQL::STRING_TYPE,
+ required: true,
+ as: :iids,
+ description: 'IID of the merge request, for example `1`'
+
+ def no_results_possible?(args)
+ project.nil?
+ end
+ end
+end
diff --git a/app/graphql/resolvers/merge_requests_resolver.rb b/app/graphql/resolvers/merge_requests_resolver.rb
index 25121dce005..3aa52341eec 100644
--- a/app/graphql/resolvers/merge_requests_resolver.rb
+++ b/app/graphql/resolvers/merge_requests_resolver.rb
@@ -2,47 +2,43 @@
module Resolvers
class MergeRequestsResolver < BaseResolver
- argument :iid, GraphQL::STRING_TYPE,
- required: false,
- description: 'IID of the merge request, for example `1`'
+ include ResolvesMergeRequests
+
+ alias_method :project, :synchronized_object
argument :iids, [GraphQL::STRING_TYPE],
required: false,
description: 'Array of IIDs of merge requests, for example `[1, 2]`'
- type Types::MergeRequestType, null: true
+ argument :source_branches, [GraphQL::STRING_TYPE],
+ required: false,
+ as: :source_branch,
+ description: 'Array of source branch names. All resolved merge requests will have one of these branches as their source.'
- alias_method :project, :object
+ argument :target_branches, [GraphQL::STRING_TYPE],
+ required: false,
+ as: :target_branch,
+ description: 'Array of target branch names. All resolved merge requests will have one of these branches as their target.'
- def resolve(**args)
- project = object.respond_to?(:sync) ? object.sync : object
- return MergeRequest.none if project.nil?
+ argument :state, ::Types::MergeRequestStateEnum,
+ required: false,
+ description: 'A merge request state. If provided, all resolved merge requests will have this state.'
- args[:iids] ||= [args[:iid]].compact
+ argument :labels, [GraphQL::STRING_TYPE],
+ required: false,
+ as: :label_name,
+ description: 'Array of label names. All resolved merge requests will have all of these labels.'
- if args[:iids].any?
- batch_load_merge_requests(args[:iids])
- else
- args[:project_id] = project.id
-
- MergeRequestsFinder.new(context[:current_user], args).execute
- end
+ def self.single
+ ::Resolvers::MergeRequestResolver
end
- def batch_load_merge_requests(iids)
- iids.map { |iid| batch_load(iid) }.select(&:itself) # .compact doesn't work on BatchLoader
+ def no_results_possible?(args)
+ project.nil? || some_argument_is_empty?(args)
end
- # rubocop: disable CodeReuse/ActiveRecord
- def batch_load(iid)
- BatchLoader::GraphQL.for(iid.to_s).batch(key: project) do |iids, loader, args|
- arg_key = args[:key].respond_to?(:sync) ? args[:key].sync : args[:key]
-
- arg_key.merge_requests.where(iid: iids).each do |mr|
- loader.call(mr.iid.to_s, mr)
- end
- end
+ def some_argument_is_empty?(args)
+ args.values.any? { |v| v.is_a?(Array) && v.empty? }
end
- # rubocop: enable CodeReuse/ActiveRecord
end
end
diff --git a/app/graphql/resolvers/project_members_resolver.rb b/app/graphql/resolvers/project_members_resolver.rb
new file mode 100644
index 00000000000..3846531762e
--- /dev/null
+++ b/app/graphql/resolvers/project_members_resolver.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Resolvers
+ class ProjectMembersResolver < BaseResolver
+ argument :search, GraphQL::STRING_TYPE,
+ required: false,
+ description: 'Search query'
+
+ type Types::ProjectMemberType, null: true
+
+ alias_method :project, :object
+
+ def resolve(**args)
+ return Member.none unless project.present?
+
+ MembersFinder
+ .new(project, context[:current_user], params: args)
+ .execute
+ end
+ end
+end
diff --git a/app/graphql/resolvers/project_pipeline_resolver.rb b/app/graphql/resolvers/project_pipeline_resolver.rb
new file mode 100644
index 00000000000..5bafe3dd140
--- /dev/null
+++ b/app/graphql/resolvers/project_pipeline_resolver.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Resolvers
+ class ProjectPipelineResolver < BaseResolver
+ alias_method :project, :object
+
+ argument :iid, GraphQL::ID_TYPE,
+ required: true,
+ description: 'IID of the Pipeline, e.g., "1"'
+
+ def resolve(iid:)
+ BatchLoader::GraphQL.for(iid).batch(key: project) do |iids, loader, args|
+ args[:key].ci_pipelines.for_iid(iids).each { |pl| loader.call(pl.iid.to_s, pl) }
+ end
+ end
+ end
+end
diff --git a/app/graphql/resolvers/projects/jira_imports_resolver.rb b/app/graphql/resolvers/projects/jira_imports_resolver.rb
index 25361c068d9..aa9b7139f38 100644
--- a/app/graphql/resolvers/projects/jira_imports_resolver.rb
+++ b/app/graphql/resolvers/projects/jira_imports_resolver.rb
@@ -14,8 +14,6 @@ module Resolvers
end
def authorized_resource?(project)
- return false unless project.jira_issues_import_feature_flag_enabled?
-
context[:current_user].present? && Ability.allowed?(context[:current_user], :read_project, project)
end
end
diff --git a/app/graphql/resolvers/projects/jira_projects_resolver.rb b/app/graphql/resolvers/projects/jira_projects_resolver.rb
new file mode 100644
index 00000000000..a8c3768df41
--- /dev/null
+++ b/app/graphql/resolvers/projects/jira_projects_resolver.rb
@@ -0,0 +1,76 @@
+# frozen_string_literal: true
+
+module Resolvers
+ module Projects
+ class JiraProjectsResolver < BaseResolver
+ include Gitlab::Graphql::Authorize::AuthorizeResource
+
+ argument :name,
+ GraphQL::STRING_TYPE,
+ required: false,
+ description: 'Project name or key'
+
+ def resolve(name: nil, **args)
+ authorize!(project)
+
+ response, start_cursor, end_cursor = jira_projects(name: name, **compute_pagination_params(args))
+ end_cursor = nil if !!response.payload[:is_last]
+
+ if response.success?
+ Gitlab::Graphql::ExternallyPaginatedArray.new(start_cursor, end_cursor, *response.payload[:projects])
+ else
+ raise Gitlab::Graphql::Errors::BaseError, response.message
+ end
+ end
+
+ def authorized_resource?(project)
+ Ability.allowed?(context[:current_user], :admin_project, project)
+ end
+
+ private
+
+ alias_method :jira_service, :object
+
+ def project
+ jira_service&.project
+ end
+
+ def compute_pagination_params(params)
+ after_cursor = Base64.decode64(params[:after].to_s)
+ before_cursor = Base64.decode64(params[:before].to_s)
+
+ # differentiate between 0 cursor and nil or invalid cursor that decodes into zero.
+ after_index = after_cursor.to_i == 0 && after_cursor != "0" ? nil : after_cursor.to_i
+ before_index = before_cursor.to_i == 0 && before_cursor != "0" ? nil : before_cursor.to_i
+
+ if after_index.present? && before_index.present?
+ if after_index >= before_index
+ { start_at: 0, limit: 0 }
+ else
+ { start_at: after_index + 1, limit: before_index - after_index - 1 }
+ end
+ elsif after_index.present?
+ { start_at: after_index + 1, limit: nil }
+ elsif before_index.present?
+ { start_at: 0, limit: before_index - 1 }
+ else
+ { start_at: 0, limit: nil }
+ end
+ end
+
+ def jira_projects(name:, start_at:, limit:)
+ args = { query: name, start_at: start_at, limit: limit }.compact
+
+ response = Jira::Requests::Projects.new(project.jira_service, args).execute
+
+ return [response, nil, nil] if response.error?
+
+ projects = response.payload[:projects]
+ start_cursor = start_at == 0 ? nil : Base64.encode64((start_at - 1).to_s)
+ end_cursor = Base64.encode64((start_at + projects.size - 1).to_s)
+
+ [response, start_cursor, end_cursor]
+ end
+ end
+ end
+end
diff --git a/app/graphql/resolvers/user_merge_requests_resolver.rb b/app/graphql/resolvers/user_merge_requests_resolver.rb
new file mode 100644
index 00000000000..b0d6e159f73
--- /dev/null
+++ b/app/graphql/resolvers/user_merge_requests_resolver.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+module Resolvers
+ class UserMergeRequestsResolver < MergeRequestsResolver
+ include ResolvesProject
+
+ argument :project_path, GraphQL::STRING_TYPE,
+ required: false,
+ description: 'The full-path of the project the authored merge requests should be in. Incompatible with projectId.'
+
+ argument :project_id, GraphQL::ID_TYPE,
+ required: false,
+ description: 'The global ID of the project the authored merge requests should be in. Incompatible with projectPath.'
+
+ attr_reader :project
+ alias_method :user, :synchronized_object
+
+ def ready?(project_id: nil, project_path: nil, **args)
+ return early_return unless can_read_profile?
+
+ if project_id || project_path
+ load_project(project_path, project_id)
+ return early_return unless can_read_project?
+ elsif args[:iids].present?
+ raise ::Gitlab::Graphql::Errors::ArgumentError,
+ 'iids requires projectPath or projectId'
+ end
+
+ super(**args)
+ end
+
+ def resolve(**args)
+ prepare_args(args)
+ key = :"#{user_role}_id"
+ super(key => user.id, **args)
+ end
+
+ def user_role
+ raise NotImplementedError
+ end
+
+ private
+
+ def can_read_profile?
+ Ability.allowed?(current_user, :read_user_profile, user)
+ end
+
+ def can_read_project?
+ Ability.allowed?(current_user, :read_merge_request, project)
+ end
+
+ def load_project(project_path, project_id)
+ @project = resolve_project(full_path: project_path, project_id: project_id)
+ @project = @project.sync if @project.respond_to?(:sync)
+ end
+
+ def no_results_possible?(args)
+ some_argument_is_empty?(args)
+ end
+
+ # These arguments are handled in load_project, and should not be passed to
+ # the finder directly.
+ def prepare_args(args)
+ args.delete(:project_id)
+ args.delete(:project_path)
+ end
+ end
+end
diff --git a/app/graphql/resolvers/user_resolver.rb b/app/graphql/resolvers/user_resolver.rb
new file mode 100644
index 00000000000..a34cecba491
--- /dev/null
+++ b/app/graphql/resolvers/user_resolver.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+module Resolvers
+ class UserResolver < BaseResolver
+ description 'Retrieve a single user'
+
+ type Types::UserType, null: true
+
+ argument :id, GraphQL::ID_TYPE,
+ required: false,
+ description: 'ID of the User'
+
+ argument :username, GraphQL::STRING_TYPE,
+ required: false,
+ description: 'Username of the User'
+
+ def ready?(id: nil, username: nil)
+ unless id.present? ^ username.present?
+ raise Gitlab::Graphql::Errors::ArgumentError, 'Provide either a single username or id'
+ end
+
+ super
+ end
+
+ def resolve(id: nil, username: nil)
+ if id
+ GitlabSchema.object_from_id(id, expected_type: User)
+ else
+ batch_load(username)
+ end
+ end
+
+ private
+
+ def batch_load(username)
+ BatchLoader::GraphQL.for(username).batch do |usernames, loader|
+ User.by_username(usernames).each do |user|
+ loader.call(user.username, user)
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/resolvers/users_resolver.rb b/app/graphql/resolvers/users_resolver.rb
new file mode 100644
index 00000000000..110a283b42e
--- /dev/null
+++ b/app/graphql/resolvers/users_resolver.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+module Resolvers
+ class UsersResolver < BaseResolver
+ include Gitlab::Graphql::Authorize::AuthorizeResource
+
+ description 'Find Users'
+
+ argument :ids, [GraphQL::ID_TYPE],
+ required: false,
+ description: 'List of user Global IDs'
+
+ argument :usernames, [GraphQL::STRING_TYPE], required: false,
+ description: 'List of usernames'
+
+ argument :sort, Types::SortEnum,
+ description: 'Sort users by this criteria',
+ required: false,
+ default_value: 'created_desc'
+
+ def resolve(ids: nil, usernames: nil, sort: nil)
+ authorize!
+
+ ::UsersFinder.new(context[:current_user], finder_params(ids, usernames, sort)).execute
+ end
+
+ def ready?(**args)
+ args = { ids: nil, usernames: nil }.merge!(args)
+
+ return super if args.values.compact.blank?
+
+ if args.values.all?
+ raise Gitlab::Graphql::Errors::ArgumentError, 'Provide either a list of usernames or ids'
+ end
+
+ super
+ end
+
+ def authorize!
+ Ability.allowed?(context[:current_user], :read_users_list) || raise_resource_not_available_error!
+ end
+
+ private
+
+ def finder_params(ids, usernames, sort)
+ params = {}
+ params[:sort] = sort if sort
+ params[:username] = usernames if usernames
+ params[:id] = parse_gids(ids) if ids
+ params
+ end
+
+ def parse_gids(gids)
+ gids.map { |gid| GitlabSchema.parse_gid(gid, expected_type: ::User).model_id }
+ end
+ end
+end
diff --git a/app/graphql/types/access_level_enum.rb b/app/graphql/types/access_level_enum.rb
new file mode 100644
index 00000000000..6754d3d28ce
--- /dev/null
+++ b/app/graphql/types/access_level_enum.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Types
+ class AccessLevelEnum < BaseEnum
+ graphql_name 'AccessLevelEnum'
+ description 'Access level to a resource'
+
+ value 'NO_ACCESS', value: Gitlab::Access::NO_ACCESS
+ value 'GUEST', value: Gitlab::Access::GUEST
+ value 'REPORTER', value: Gitlab::Access::REPORTER
+ value 'DEVELOPER', value: Gitlab::Access::DEVELOPER
+ value 'MAINTAINER', value: Gitlab::Access::MAINTAINER
+ value 'OWNER', value: Gitlab::Access::OWNER
+ end
+end
diff --git a/app/graphql/types/access_level_type.rb b/app/graphql/types/access_level_type.rb
new file mode 100644
index 00000000000..c7f915f5038
--- /dev/null
+++ b/app/graphql/types/access_level_type.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+# rubocop:disable Graphql/AuthorizeTypes
+
+module Types
+ class AccessLevelType < Types::BaseObject
+ graphql_name 'AccessLevel'
+ description 'Represents the access level of a relationship between a User and object that it is related to'
+
+ field :integer_value, GraphQL::INT_TYPE, null: true,
+ description: 'Integer representation of access level',
+ method: :to_i
+
+ field :string_value, Types::AccessLevelEnum, null: true,
+ description: 'String representation of access level',
+ method: :to_i
+ end
+end
diff --git a/app/graphql/types/alert_management/alert_sort_enum.rb b/app/graphql/types/alert_management/alert_sort_enum.rb
index e6d38af8170..3faac9ce53c 100644
--- a/app/graphql/types/alert_management/alert_sort_enum.rb
+++ b/app/graphql/types/alert_management/alert_sort_enum.rb
@@ -6,16 +6,16 @@ module Types
graphql_name 'AlertManagementAlertSort'
description 'Values for sorting alerts'
- value 'START_TIME_ASC', 'Start time by ascending order', value: :start_time_asc
- value 'START_TIME_DESC', 'Start time by descending order', value: :start_time_desc
- value 'END_TIME_ASC', 'End time by ascending order', value: :end_time_asc
- value 'END_TIME_DESC', 'End time by descending order', value: :end_time_desc
+ value 'STARTED_AT_ASC', 'Start time by ascending order', value: :started_at_asc
+ value 'STARTED_AT_DESC', 'Start time by descending order', value: :started_at_desc
+ value 'ENDED_AT_ASC', 'End time by ascending order', value: :ended_at_asc
+ value 'ENDED_AT_DESC', 'End time by descending order', value: :ended_at_desc
value 'CREATED_TIME_ASC', 'Created time by ascending order', value: :created_at_asc
value 'CREATED_TIME_DESC', 'Created time by descending order', value: :created_at_desc
value 'UPDATED_TIME_ASC', 'Created time by ascending order', value: :updated_at_asc
value 'UPDATED_TIME_DESC', 'Created time by descending order', value: :updated_at_desc
- value 'EVENTS_COUNT_ASC', 'Events count by ascending order', value: :events_count_asc
- value 'EVENTS_COUNT_DESC', 'Events count by descending order', value: :events_count_desc
+ value 'EVENT_COUNT_ASC', 'Events count by ascending order', value: :event_count_asc
+ value 'EVENT_COUNT_DESC', 'Events count by descending order', value: :event_count_desc
value 'SEVERITY_ASC', 'Severity by ascending order', value: :severity_asc
value 'SEVERITY_DESC', 'Severity by descending order', value: :severity_desc
value 'STATUS_ASC', 'Status by ascending order', value: :status_asc
diff --git a/app/graphql/types/alert_management/alert_type.rb b/app/graphql/types/alert_management/alert_type.rb
index a766fb3236d..8215ccb152c 100644
--- a/app/graphql/types/alert_management/alert_type.rb
+++ b/app/graphql/types/alert_management/alert_type.rb
@@ -6,6 +6,8 @@ module Types
graphql_name 'AlertManagementAlert'
description "Describes an alert from the project's Alert Management"
+ implements(Types::Notes::NoteableType)
+
authorize :read_alert_management_alert
field :iid,
@@ -83,6 +85,15 @@ module Types
Types::TimeType,
null: true,
description: 'Timestamp the alert was last updated'
+
+ field :assignees,
+ Types::UserType.connection_type,
+ null: true,
+ description: 'Assignees of the alert'
+
+ def notes
+ object.ordered_notes
+ end
end
end
end
diff --git a/app/graphql/types/base_object.rb b/app/graphql/types/base_object.rb
index dad16898ba6..70e665f8fc3 100644
--- a/app/graphql/types/base_object.rb
+++ b/app/graphql/types/base_object.rb
@@ -12,5 +12,9 @@ module Types
def id
GitlabSchema.id_from_object(object)
end
+
+ def current_user
+ context[:current_user]
+ end
end
end
diff --git a/app/graphql/types/board_type.rb b/app/graphql/types/board_type.rb
index c0be782ed1e..f5dc9e08427 100644
--- a/app/graphql/types/board_type.rb
+++ b/app/graphql/types/board_type.rb
@@ -15,7 +15,7 @@ module Types
field :lists,
Types::BoardListType.connection_type,
null: true,
- description: 'Lists of the project board',
+ description: 'Lists of the board',
resolver: Resolvers::BoardListsResolver,
extras: [:lookahead]
end
diff --git a/app/graphql/types/ci/pipeline_type.rb b/app/graphql/types/ci/pipeline_type.rb
index d77b2a2ba32..32050766e5b 100644
--- a/app/graphql/types/ci/pipeline_type.rb
+++ b/app/graphql/types/ci/pipeline_type.rb
@@ -42,3 +42,5 @@ module Types
end
end
end
+
+Types::Ci::PipelineType.prepend_if_ee('::EE::Types::Ci::PipelineType')
diff --git a/app/graphql/types/commit_action_mode_enum.rb b/app/graphql/types/commit_action_mode_enum.rb
new file mode 100644
index 00000000000..77658a85b51
--- /dev/null
+++ b/app/graphql/types/commit_action_mode_enum.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+module Types
+ class CommitActionModeEnum < BaseEnum
+ graphql_name 'CommitActionMode'
+ description 'Mode of a commit action'
+
+ value 'CREATE', description: 'Create command', value: :create
+ value 'DELETE', description: 'Delete command', value: :delete
+ value 'MOVE', description: 'Move command', value: :move
+ value 'UPDATE', description: 'Update command', value: :update
+ value 'CHMOD', description: 'Chmod command', value: :chmod
+ end
+end
diff --git a/app/graphql/types/commit_action_type.rb b/app/graphql/types/commit_action_type.rb
new file mode 100644
index 00000000000..7674abb11eb
--- /dev/null
+++ b/app/graphql/types/commit_action_type.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module Types
+ # rubocop: disable Graphql/AuthorizeTypes
+ class CommitActionType < BaseInputObject
+ argument :action, type: Types::CommitActionModeEnum, required: true,
+ description: 'The action to perform, create, delete, move, update, chmod'
+ argument :file_path, type: GraphQL::STRING_TYPE, required: true,
+ description: 'Full path to the file'
+ argument :content, type: GraphQL::STRING_TYPE, required: false,
+ description: 'Content of the file'
+ argument :previous_path, type: GraphQL::STRING_TYPE, required: false,
+ description: 'Original full path to the file being moved'
+ argument :last_commit_id, type: GraphQL::STRING_TYPE, required: false,
+ description: 'Last known file commit ID'
+ argument :execute_filemode, type: GraphQL::BOOLEAN_TYPE, required: false,
+ description: 'Enables/disables the execute flag on the file'
+ argument :encoding, type: Types::CommitEncodingEnum, required: false,
+ description: 'Encoding of the file. Default is text'
+ end
+ # rubocop: enable Graphql/AuthorizeTypes
+end
diff --git a/app/graphql/types/commit_encoding_enum.rb b/app/graphql/types/commit_encoding_enum.rb
new file mode 100644
index 00000000000..0ea89b82db7
--- /dev/null
+++ b/app/graphql/types/commit_encoding_enum.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+module Types
+ class CommitEncodingEnum < BaseEnum
+ graphql_name 'CommitEncoding'
+
+ value 'TEXT', description: 'Text encoding', value: :text
+ value 'BASE64', description: 'Base64 encoding', value: :base64
+ end
+end
diff --git a/app/graphql/types/container_expiration_policy_cadence_enum.rb b/app/graphql/types/container_expiration_policy_cadence_enum.rb
new file mode 100644
index 00000000000..bb8bdf2197b
--- /dev/null
+++ b/app/graphql/types/container_expiration_policy_cadence_enum.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Types
+ class ContainerExpirationPolicyCadenceEnum < BaseEnum
+ OPTIONS_MAPPING = {
+ '1d': 'EVERY_DAY',
+ '7d': 'EVERY_WEEK',
+ '14d': 'EVERY_TWO_WEEKS',
+ '1month': 'EVERY_MONTH',
+ '3month': 'EVERY_THREE_MONTHS'
+ }.freeze
+
+ ::ContainerExpirationPolicy.cadence_options.each do |option, description|
+ value OPTIONS_MAPPING[option], description, value: option.to_s
+ end
+ end
+end
diff --git a/app/graphql/types/container_expiration_policy_keep_enum.rb b/app/graphql/types/container_expiration_policy_keep_enum.rb
new file mode 100644
index 00000000000..7632df61092
--- /dev/null
+++ b/app/graphql/types/container_expiration_policy_keep_enum.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module Types
+ class ContainerExpirationPolicyKeepEnum < BaseEnum
+ OPTIONS_MAPPING = {
+ 1 => 'ONE_TAG',
+ 5 => 'FIVE_TAGS',
+ 10 => 'TEN_TAGS',
+ 25 => 'TWENTY_FIVE_TAGS',
+ 50 => 'FIFTY_TAGS',
+ 100 => 'ONE_HUNDRED_TAGS'
+ }.freeze
+
+ ::ContainerExpirationPolicy.keep_n_options.each do |option, description|
+ value OPTIONS_MAPPING[option], description, value: option
+ end
+ end
+end
diff --git a/app/graphql/types/container_expiration_policy_older_than_enum.rb b/app/graphql/types/container_expiration_policy_older_than_enum.rb
new file mode 100644
index 00000000000..da70534b0d7
--- /dev/null
+++ b/app/graphql/types/container_expiration_policy_older_than_enum.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Types
+ class ContainerExpirationPolicyOlderThanEnum < BaseEnum
+ OPTIONS_MAPPING = {
+ '7d': 'SEVEN_DAYS',
+ '14d': 'FOURTEEN_DAYS',
+ '30d': 'THIRTY_DAYS',
+ '90d': 'NINETY_DAYS'
+ }.freeze
+
+ ::ContainerExpirationPolicy.older_than_options.each do |option, description|
+ value OPTIONS_MAPPING[option], description, value: option.to_s
+ end
+ end
+end
diff --git a/app/graphql/types/container_expiration_policy_type.rb b/app/graphql/types/container_expiration_policy_type.rb
new file mode 100644
index 00000000000..da53dbcbd39
--- /dev/null
+++ b/app/graphql/types/container_expiration_policy_type.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Types
+ class ContainerExpirationPolicyType < BaseObject
+ graphql_name 'ContainerExpirationPolicy'
+
+ description 'A tag expiration policy designed to keep only the images that matter most'
+
+ authorize :destroy_container_image
+
+ field :created_at, Types::TimeType, null: false, description: 'Timestamp of when the container expiration policy was created'
+ field :updated_at, Types::TimeType, null: false, description: 'Timestamp of when the container expiration policy was updated'
+ field :enabled, GraphQL::BOOLEAN_TYPE, null: false, description: 'Indicates whether this container expiration policy is enabled'
+ field :older_than, Types::ContainerExpirationPolicyOlderThanEnum, null: true, description: 'Tags older that this will expire'
+ field :cadence, Types::ContainerExpirationPolicyCadenceEnum, null: false, description: 'This container expiration policy schedule'
+ field :keep_n, Types::ContainerExpirationPolicyKeepEnum, null: true, description: 'Number of tags to retain'
+ field :name_regex, GraphQL::STRING_TYPE, null: true, description: 'Tags with names matching this regex pattern will expire'
+ field :name_regex_keep, GraphQL::STRING_TYPE, null: true, description: 'Tags with names matching this regex pattern will be preserved'
+ field :next_run_at, Types::TimeType, null: true, description: 'Next time that this container expiration policy will get executed'
+ end
+end
diff --git a/app/graphql/types/evidence_type.rb b/app/graphql/types/evidence_type.rb
new file mode 100644
index 00000000000..a2fc9953c67
--- /dev/null
+++ b/app/graphql/types/evidence_type.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Types
+ class EvidenceType < BaseObject
+ graphql_name 'ReleaseEvidence'
+ description 'Evidence for a release'
+
+ authorize :download_code
+
+ present_using Releases::EvidencePresenter
+
+ field :id, GraphQL::ID_TYPE, null: false,
+ description: 'ID of the evidence'
+ field :sha, GraphQL::STRING_TYPE, null: true,
+ description: 'SHA1 ID of the evidence hash'
+ field :filepath, GraphQL::STRING_TYPE, null: true,
+ description: 'URL from where the evidence can be downloaded'
+ field :collected_at, Types::TimeType, null: true,
+ description: 'Timestamp when the evidence was collected'
+ end
+end
diff --git a/app/graphql/types/group_member_type.rb b/app/graphql/types/group_member_type.rb
new file mode 100644
index 00000000000..ffffa3247db
--- /dev/null
+++ b/app/graphql/types/group_member_type.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Types
+ class GroupMemberType < BaseObject
+ expose_permissions Types::PermissionTypes::Group
+ authorize :read_group
+
+ implements MemberInterface
+
+ graphql_name 'GroupMember'
+ description 'Represents a Group Member'
+
+ field :group, Types::GroupType, null: true,
+ description: 'Group that a User is a member of',
+ resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, obj.source_id).find }
+ end
+end
diff --git a/app/graphql/types/group_type.rb b/app/graphql/types/group_type.rb
index 20b4c66ba95..fd7d9a9ba3d 100644
--- a/app/graphql/types/group_type.rb
+++ b/app/graphql/types/group_type.rb
@@ -65,6 +65,45 @@ module Types
null: true,
description: 'A single board of the group',
resolver: Resolvers::BoardsResolver.single
+
+ field :label,
+ Types::LabelType,
+ null: true,
+ description: 'A label available on this group' do
+ argument :title, GraphQL::STRING_TYPE,
+ required: true,
+ description: 'Title of the label'
+ end
+
+ def label(title:)
+ BatchLoader::GraphQL.for(title).batch(key: group) do |titles, loader, args|
+ LabelsFinder
+ .new(current_user, group: args[:key], title: titles)
+ .execute
+ .each { |label| loader.call(label.title, label) }
+ end
+ end
+
+ field :labels,
+ Types::LabelType.connection_type,
+ null: true,
+ description: 'Labels available on this group' do
+ argument :search_term, GraphQL::STRING_TYPE,
+ required: false,
+ description: 'A search term to find labels with'
+ end
+
+ def labels(search_term: nil)
+ LabelsFinder
+ .new(current_user, group: group, search: search_term)
+ .execute
+ end
+
+ private
+
+ def group
+ object.respond_to?(:sync) ? object.sync : object
+ end
end
end
diff --git a/app/graphql/types/jira_import_type.rb b/app/graphql/types/jira_import_type.rb
index 4a124566ffb..cf58a53b40d 100644
--- a/app/graphql/types/jira_import_type.rb
+++ b/app/graphql/types/jira_import_type.rb
@@ -15,6 +15,12 @@ module Types
description: 'User that started the Jira import'
field :jira_project_key, GraphQL::STRING_TYPE, null: false,
description: 'Project key for the imported Jira project'
+ field :imported_issues_count, GraphQL::INT_TYPE, null: false,
+ description: 'Count of issues that were successfully imported'
+ field :failed_to_import_count, GraphQL::INT_TYPE, null: false,
+ description: 'Count of issues that failed to import'
+ field :total_issue_count, GraphQL::INT_TYPE, null: false,
+ description: 'Total count of issues that were attempted to import'
end
# rubocop: enable Graphql/AuthorizeTypes
end
diff --git a/app/graphql/types/jira_user_type.rb b/app/graphql/types/jira_user_type.rb
new file mode 100644
index 00000000000..8aa21ce669b
--- /dev/null
+++ b/app/graphql/types/jira_user_type.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Types
+ # rubocop: disable Graphql/AuthorizeTypes
+ # Authorization is at project level for owners or admins on mutation level
+ class JiraUserType < BaseObject
+ graphql_name 'JiraUser'
+
+ field :jira_account_id, GraphQL::STRING_TYPE, null: false,
+ description: 'Account id of the Jira user'
+ field :jira_display_name, GraphQL::STRING_TYPE, null: false,
+ description: 'Display name of the Jira user'
+ field :jira_email, GraphQL::STRING_TYPE, null: true,
+ description: 'Email of the Jira user, returned only for users with public emails'
+ field :gitlab_id, GraphQL::INT_TYPE, null: true,
+ description: 'Id of the matched GitLab user'
+ end
+ # rubocop: enable Graphql/AuthorizeTypes
+end
diff --git a/app/graphql/types/member_interface.rb b/app/graphql/types/member_interface.rb
new file mode 100644
index 00000000000..976836221bc
--- /dev/null
+++ b/app/graphql/types/member_interface.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module Types
+ module MemberInterface
+ include BaseInterface
+
+ field :access_level, Types::AccessLevelType, null: true,
+ description: 'GitLab::Access level'
+
+ field :created_by, Types::UserType, null: true,
+ description: 'User that authorized membership'
+
+ field :created_at, Types::TimeType, null: true,
+ description: 'Date and time the membership was created'
+
+ field :updated_at, Types::TimeType, null: true,
+ description: 'Date and time the membership was last updated'
+
+ field :expires_at, Types::TimeType, null: true,
+ description: 'Date and time the membership expires'
+ end
+end
diff --git a/app/graphql/types/merge_request_type.rb b/app/graphql/types/merge_request_type.rb
index cd4c6b4d46a..cb4ff7ea0c5 100644
--- a/app/graphql/types/merge_request_type.rb
+++ b/app/graphql/types/merge_request_type.rb
@@ -28,6 +28,8 @@ module Types
description: 'Timestamp of when the merge request was created'
field :updated_at, Types::TimeType, null: false,
description: 'Timestamp of when the merge request was last updated'
+ field :merged_at, Types::TimeType, null: true, complexity: 5,
+ description: 'Timestamp of when the merge request was merged, null if not merged'
field :source_project, Types::ProjectType, null: true,
description: 'Source project of the merge request'
field :target_project, Types::ProjectType, null: false,
@@ -81,8 +83,14 @@ module Types
description: 'Default merge commit message of the merge request'
field :merge_ongoing, GraphQL::BOOLEAN_TYPE, method: :merge_ongoing?, null: false,
description: 'Indicates if a merge is currently occurring'
- field :source_branch_exists, GraphQL::BOOLEAN_TYPE, method: :source_branch_exists?, null: false,
+ field :source_branch_exists, GraphQL::BOOLEAN_TYPE,
+ null: false, calls_gitaly: true,
+ method: :source_branch_exists?,
description: 'Indicates if the source branch of the merge request exists'
+ field :target_branch_exists, GraphQL::BOOLEAN_TYPE,
+ null: false, calls_gitaly: true,
+ method: :target_branch_exists?,
+ description: 'Indicates if the target branch of the merge request exists'
field :mergeable_discussions_state, GraphQL::BOOLEAN_TYPE, null: true,
description: 'Indicates if all discussions in the merge request have been resolved, allowing the merge request to be merged'
field :web_url, GraphQL::STRING_TYPE, null: true,
@@ -103,6 +111,8 @@ module Types
resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Milestone, obj.milestone_id).find }
field :assignees, Types::UserType.connection_type, null: true, complexity: 5,
description: 'Assignees of the merge request'
+ field :author, Types::UserType, null: true,
+ description: 'User who created this merge request'
field :participants, Types::UserType.connection_type, null: true, complexity: 5,
description: 'Participants in the merge request'
field :subscribed, GraphQL::BOOLEAN_TYPE, method: :subscribed?, null: false, complexity: 5,
diff --git a/app/graphql/types/metrics/dashboard_type.rb b/app/graphql/types/metrics/dashboard_type.rb
index d684533ff94..bbcce2d9596 100644
--- a/app/graphql/types/metrics/dashboard_type.rb
+++ b/app/graphql/types/metrics/dashboard_type.rb
@@ -10,6 +10,9 @@ module Types
field :path, GraphQL::STRING_TYPE, null: true,
description: 'Path to a file with the dashboard definition'
+ field :schema_validation_warnings, [GraphQL::STRING_TYPE], null: true,
+ description: 'Dashboard schema validation warnings'
+
field :annotations, Types::Metrics::Dashboards::AnnotationType.connection_type, null: true,
description: 'Annotations added to the dashboard',
resolver: Resolvers::Metrics::Dashboards::AnnotationResolver
diff --git a/app/graphql/types/milestone_type.rb b/app/graphql/types/milestone_type.rb
index 900f8c6f01d..99bd6e819d6 100644
--- a/app/graphql/types/milestone_type.rb
+++ b/app/graphql/types/milestone_type.rb
@@ -35,5 +35,17 @@ module Types
field :updated_at, Types::TimeType, null: false,
description: 'Timestamp of last milestone update'
+
+ field :project_milestone, GraphQL::BOOLEAN_TYPE, null: false,
+ description: 'Indicates if milestone is at project level',
+ method: :project_milestone?
+
+ field :group_milestone, GraphQL::BOOLEAN_TYPE, null: false,
+ description: 'Indicates if milestone is at group level',
+ method: :group_milestone?
+
+ field :subgroup_milestone, GraphQL::BOOLEAN_TYPE, null: false,
+ description: 'Indicates if milestone is at subgroup level',
+ method: :subgroup_milestone?
end
end
diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb
index aeff84b83b8..8874c56dfdb 100644
--- a/app/graphql/types/mutation_type.rb
+++ b/app/graphql/types/mutation_type.rb
@@ -9,13 +9,17 @@ module Types
mount_mutation Mutations::Admin::SidekiqQueues::DeleteJobs
mount_mutation Mutations::AlertManagement::CreateAlertIssue
mount_mutation Mutations::AlertManagement::UpdateAlertStatus
+ mount_mutation Mutations::AlertManagement::Alerts::SetAssignees
mount_mutation Mutations::AwardEmojis::Add
mount_mutation Mutations::AwardEmojis::Remove
mount_mutation Mutations::AwardEmojis::Toggle
mount_mutation Mutations::Branches::Create, calls_gitaly: true
+ mount_mutation Mutations::Commits::Create, calls_gitaly: true
+ mount_mutation Mutations::Discussions::ToggleResolve
mount_mutation Mutations::Issues::SetConfidential
mount_mutation Mutations::Issues::SetDueDate
mount_mutation Mutations::Issues::Update
+ mount_mutation Mutations::MergeRequests::Create
mount_mutation Mutations::MergeRequests::SetLabels
mount_mutation Mutations::MergeRequests::SetLocked
mount_mutation Mutations::MergeRequests::SetMilestone
@@ -23,6 +27,7 @@ module Types
mount_mutation Mutations::MergeRequests::SetWip, calls_gitaly: true
mount_mutation Mutations::MergeRequests::SetAssignees
mount_mutation Mutations::Metrics::Dashboard::Annotations::Create
+ mount_mutation Mutations::Metrics::Dashboard::Annotations::Delete
mount_mutation Mutations::Notes::Create::Note, calls_gitaly: true
mount_mutation Mutations::Notes::Create::DiffNote, calls_gitaly: true
mount_mutation Mutations::Notes::Create::ImageDiffNote, calls_gitaly: true
@@ -44,8 +49,10 @@ module Types
mount_mutation Mutations::Snippets::Create
mount_mutation Mutations::Snippets::MarkAsSpam
mount_mutation Mutations::JiraImport::Start
+ mount_mutation Mutations::JiraImport::ImportUsers
mount_mutation Mutations::DesignManagement::Upload, calls_gitaly: true
mount_mutation Mutations::DesignManagement::Delete, calls_gitaly: true
+ mount_mutation Mutations::ContainerExpirationPolicies::Update
end
end
diff --git a/app/graphql/types/notes/discussion_type.rb b/app/graphql/types/notes/discussion_type.rb
index 74a233e9d26..a51d253097d 100644
--- a/app/graphql/types/notes/discussion_type.rb
+++ b/app/graphql/types/notes/discussion_type.rb
@@ -7,6 +7,8 @@ module Types
authorize :read_note
+ implements(Types::ResolvableInterface)
+
field :id, GraphQL::ID_TYPE, null: false,
description: "ID of this discussion"
field :reply_id, GraphQL::ID_TYPE, null: false,
diff --git a/app/graphql/types/notes/note_type.rb b/app/graphql/types/notes/note_type.rb
index d48cc868434..8755b4ccad5 100644
--- a/app/graphql/types/notes/note_type.rb
+++ b/app/graphql/types/notes/note_type.rb
@@ -9,6 +9,8 @@ module Types
expose_permissions Types::PermissionTypes::Note
+ implements(Types::ResolvableInterface)
+
field :id, GraphQL::ID_TYPE, null: false,
description: 'ID of the note'
@@ -22,11 +24,6 @@ module Types
description: 'User who wrote this note',
resolve: -> (note, args, context) { Gitlab::Graphql::Loaders::BatchModelLoader.new(User, note.author_id).find }
- field :resolved_by, Types::UserType,
- null: true,
- description: 'User that resolved the discussion',
- resolve: -> (note, _args, _context) { Gitlab::Graphql::Loaders::BatchModelLoader.new(User, note.resolved_by_id).find }
-
field :system, GraphQL::BOOLEAN_TYPE,
null: false,
description: 'Indicates whether this note was created by the system or by a user'
@@ -44,11 +41,6 @@ module Types
description: "Timestamp of the note's last activity"
field :discussion, Types::Notes::DiscussionType, null: true,
description: 'The discussion this note is a part of'
- field :resolvable, GraphQL::BOOLEAN_TYPE, null: false,
- description: 'Indicates if this note can be resolved. That is, if it is a resolvable discussion or simply a standalone note',
- method: :resolvable?
- field :resolved_at, Types::TimeType, null: true,
- description: "Timestamp of the note's resolution"
field :position, Types::Notes::DiffPositionType, null: true,
description: 'The position of this note on a diff'
field :confidential, GraphQL::BOOLEAN_TYPE, null: true,
diff --git a/app/graphql/types/notes/noteable_type.rb b/app/graphql/types/notes/noteable_type.rb
index 187c9109f8c..3a16d54f9cd 100644
--- a/app/graphql/types/notes/noteable_type.rb
+++ b/app/graphql/types/notes/noteable_type.rb
@@ -19,6 +19,8 @@ module Types
Types::SnippetType
when ::DesignManagement::Design
Types::DesignManagement::DesignType
+ when ::AlertManagement::Alert
+ Types::AlertManagement::AlertType
else
raise "Unknown GraphQL type for #{object}"
end
diff --git a/app/graphql/types/permission_types/ci/pipeline.rb b/app/graphql/types/permission_types/ci/pipeline.rb
index 73e44a33eba..cfd68380005 100644
--- a/app/graphql/types/permission_types/ci/pipeline.rb
+++ b/app/graphql/types/permission_types/ci/pipeline.rb
@@ -6,7 +6,8 @@ module Types
class Pipeline < BasePermissionType
graphql_name 'PipelinePermissions'
- abilities :update_pipeline, :admin_pipeline, :destroy_pipeline
+ abilities :admin_pipeline, :destroy_pipeline
+ ability_field :update_pipeline, calls_gitaly: true
end
end
end
diff --git a/app/graphql/types/permission_types/merge_request.rb b/app/graphql/types/permission_types/merge_request.rb
index d877fc177d2..28b7ebd2af6 100644
--- a/app/graphql/types/permission_types/merge_request.rb
+++ b/app/graphql/types/permission_types/merge_request.rb
@@ -3,6 +3,11 @@
module Types
module PermissionTypes
class MergeRequest < BasePermissionType
+ PERMISSION_FIELDS = %i[push_to_source_branch
+ remove_source_branch
+ cherry_pick_on_current_merge_request
+ revert_on_current_merge_request].freeze
+
present_using MergeRequestPresenter
description 'Check permissions for the current user on a merge request'
graphql_name 'MergeRequestPermissions'
@@ -10,10 +15,9 @@ module Types
abilities :read_merge_request, :admin_merge_request,
:update_merge_request, :create_note
- permission_field :push_to_source_branch, method: :can_push_to_source_branch?, calls_gitaly: true
- permission_field :remove_source_branch, method: :can_remove_source_branch?, calls_gitaly: true
- permission_field :cherry_pick_on_current_merge_request, method: :can_cherry_pick_on_current_merge_request?
- permission_field :revert_on_current_merge_request, method: :can_revert_on_current_merge_request?
+ PERMISSION_FIELDS.each do |field_name|
+ permission_field field_name, method: :"can_#{field_name}?", calls_gitaly: true
+ end
end
end
end
diff --git a/app/graphql/types/project_member_type.rb b/app/graphql/types/project_member_type.rb
new file mode 100644
index 00000000000..e9ccb51886b
--- /dev/null
+++ b/app/graphql/types/project_member_type.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Types
+ class ProjectMemberType < BaseObject
+ graphql_name 'ProjectMember'
+ description 'Represents a Project Member'
+
+ expose_permissions Types::PermissionTypes::Project
+
+ implements MemberInterface
+
+ authorize :read_project
+
+ field :id, GraphQL::ID_TYPE, null: false,
+ description: 'ID of the member'
+
+ field :user, Types::UserType, null: false,
+ description: 'User that is associated with the member object',
+ resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(User, obj.user_id).find }
+
+ field :project, Types::ProjectType, null: true,
+ description: 'Project that User is a member of',
+ resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, obj.source_id).find }
+ end
+end
diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb
index 4e438ed2576..bbfb7fc4f20 100644
--- a/app/graphql/types/project_type.rb
+++ b/app/graphql/types/project_type.rb
@@ -95,6 +95,8 @@ module Types
description: 'Status of Jira import background job of the project'
field :only_allow_merge_if_pipeline_succeeds, GraphQL::BOOLEAN_TYPE, null: true,
description: 'Indicates if merge requests of the project can only be merged with successful jobs'
+ field :allow_merge_on_skipped_pipeline, GraphQL::BOOLEAN_TYPE, null: true,
+ description: 'If `only_allow_merge_if_pipeline_succeeds` is true, indicates if merge requests of the project can also be merged with skipped jobs'
field :request_access_enabled, GraphQL::BOOLEAN_TYPE, null: true,
description: 'Indicates if users can request member access to the project'
field :only_allow_merge_if_all_discussions_are_resolved, GraphQL::BOOLEAN_TYPE, null: true,
@@ -125,6 +127,7 @@ module Types
Types::MergeRequestType.connection_type,
null: true,
description: 'Merge requests of the project',
+ extras: [:lookahead],
resolver: Resolvers::MergeRequestsResolver
field :merge_request,
@@ -139,6 +142,11 @@ module Types
description: 'Issues of the project',
resolver: Resolvers::IssuesResolver
+ field :project_members,
+ Types::ProjectMemberType.connection_type,
+ description: 'Members of the project',
+ resolver: Resolvers::ProjectMembersResolver
+
field :environments,
Types::EnvironmentType.connection_type,
null: true,
@@ -157,6 +165,12 @@ module Types
description: 'Build pipelines of the project',
resolver: Resolvers::ProjectPipelinesResolver
+ field :pipeline,
+ Types::Ci::PipelineType,
+ null: true,
+ description: 'Build pipeline of the project',
+ resolver: Resolvers::ProjectPipelineResolver
+
field :sentry_detailed_error,
Types::ErrorTracking::SentryDetailedErrorType,
null: true,
@@ -210,13 +224,14 @@ module Types
Types::AlertManagement::AlertType.connection_type,
null: true,
description: 'Alert Management alerts of the project',
- resolver: Resolvers::AlertManagementAlertResolver
+ extras: [:lookahead],
+ resolver: Resolvers::AlertManagement::AlertResolver
field :alert_management_alert,
Types::AlertManagement::AlertType,
null: true,
description: 'A single Alert Management alert of the project',
- resolver: Resolvers::AlertManagementAlertResolver.single
+ resolver: Resolvers::AlertManagement::AlertResolver.single
field :alert_management_alert_status_counts,
Types::AlertManagement::AlertStatusCountsType,
@@ -237,6 +252,50 @@ module Types
description: 'A single release of the project',
resolver: Resolvers::ReleasesResolver.single,
feature_flag: :graphql_release_data
+
+ field :container_expiration_policy,
+ Types::ContainerExpirationPolicyType,
+ null: true,
+ description: 'The container expiration policy of the project'
+
+ field :label,
+ Types::LabelType,
+ null: true,
+ description: 'A label available on this project' do
+ argument :title, GraphQL::STRING_TYPE,
+ required: true,
+ description: 'Title of the label'
+ end
+
+ def label(title:)
+ BatchLoader::GraphQL.for(title).batch(key: project) do |titles, loader, args|
+ LabelsFinder
+ .new(current_user, project: args[:key], title: titles)
+ .execute
+ .each { |label| loader.call(label.title, label) }
+ end
+ end
+
+ field :labels,
+ Types::LabelType.connection_type,
+ null: true,
+ description: 'Labels available on this project' do
+ argument :search_term, GraphQL::STRING_TYPE,
+ required: false,
+ description: 'A search term to find labels with'
+ end
+
+ def labels(search_term: nil)
+ LabelsFinder
+ .new(current_user, project: project, search: search_term)
+ .execute
+ end
+
+ private
+
+ def project
+ @project ||= object.respond_to?(:sync) ? object.sync : object
+ end
end
end
diff --git a/app/graphql/types/projects/service_type.rb b/app/graphql/types/projects/service_type.rb
index 55dd828d4b8..4ae7cb77904 100644
--- a/app/graphql/types/projects/service_type.rb
+++ b/app/graphql/types/projects/service_type.rb
@@ -6,7 +6,7 @@ module Types
include Types::BaseInterface
graphql_name 'Service'
- # TODO: Add all the fields that we want to expose for the project services intergrations
+ # TODO: Add all the fields that we want to expose for the project services integrations
# https://gitlab.com/gitlab-org/gitlab/-/issues/213088
field :type, GraphQL::STRING_TYPE, null: true,
description: 'Class name of the service'
diff --git a/app/graphql/types/projects/services/jira_project_type.rb b/app/graphql/types/projects/services/jira_project_type.rb
new file mode 100644
index 00000000000..ccf9107f398
--- /dev/null
+++ b/app/graphql/types/projects/services/jira_project_type.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Types
+ module Projects
+ module Services
+ # rubocop:disable Graphql/AuthorizeTypes
+ class JiraProjectType < BaseObject
+ graphql_name 'JiraProject'
+
+ field :key, GraphQL::STRING_TYPE, null: false,
+ description: 'Key of the Jira project'
+ field :project_id, GraphQL::INT_TYPE, null: false,
+ description: 'ID of the Jira project',
+ method: :id
+ field :name, GraphQL::STRING_TYPE, null: true,
+ description: 'Name of the Jira project'
+ end
+ # rubocop:enable Graphql/AuthorizeTypes
+ end
+ end
+end
diff --git a/app/graphql/types/projects/services/jira_service_type.rb b/app/graphql/types/projects/services/jira_service_type.rb
index 4fd9e61f5a4..e81963f752d 100644
--- a/app/graphql/types/projects/services/jira_service_type.rb
+++ b/app/graphql/types/projects/services/jira_service_type.rb
@@ -9,9 +9,14 @@ module Types
implements(Types::Projects::ServiceType)
authorize :admin_project
- # This is a placeholder for now for the actuall implementation of the JiraServiceType
- # Here we will want to expose a field with jira_projects fetched through Jira Rest API
- # MR implementing it https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28190
+
+ field :projects,
+ Types::Projects::Services::JiraProjectType.connection_type,
+ null: true,
+ connection: false,
+ extensions: [Gitlab::Graphql::Extensions::ExternallyPaginatedArrayExtension],
+ description: 'List of Jira projects fetched through Jira REST API',
+ resolver: Resolvers::Projects::JiraProjectsResolver
end
end
end
diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb
index 70cdcb62bc6..362e4004b73 100644
--- a/app/graphql/types/query_type.rb
+++ b/app/graphql/types/query_type.rb
@@ -47,10 +47,24 @@ module Types
null: false,
description: 'Fields related to design management'
+ field :user, Types::UserType,
+ null: true,
+ description: 'Find a user',
+ resolver: Resolvers::UserResolver
+
+ field :users, Types::UserType.connection_type,
+ null: true,
+ description: 'Find users',
+ resolver: Resolvers::UsersResolver
+
field :echo, GraphQL::STRING_TYPE, null: false,
description: 'Text to echo back',
resolver: Resolvers::EchoResolver
+ field :user, Types::UserType, null: true,
+ description: 'Find a user on this instance',
+ resolver: Resolvers::UserResolver
+
def design_management
DesignManagementObject.new(nil)
end
diff --git a/app/graphql/types/release_assets_type.rb b/app/graphql/types/release_assets_type.rb
new file mode 100644
index 00000000000..58ad05b5365
--- /dev/null
+++ b/app/graphql/types/release_assets_type.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module Types
+ class ReleaseAssetsType < BaseObject
+ graphql_name 'ReleaseAssets'
+
+ authorize :read_release
+
+ alias_method :release, :object
+
+ present_using ReleasePresenter
+
+ field :assets_count, GraphQL::INT_TYPE, null: true,
+ description: 'Number of assets of the release'
+ field :links, Types::ReleaseLinkType.connection_type, null: true,
+ description: 'Asset links of the release'
+ field :sources, Types::ReleaseSourceType.connection_type, null: true,
+ description: 'Sources of the release'
+ end
+end
diff --git a/app/graphql/types/release_link_type.rb b/app/graphql/types/release_link_type.rb
new file mode 100644
index 00000000000..070f14a90df
--- /dev/null
+++ b/app/graphql/types/release_link_type.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module Types
+ class ReleaseLinkType < BaseObject
+ graphql_name 'ReleaseLink'
+
+ authorize :read_release
+
+ field :id, GraphQL::ID_TYPE, null: false,
+ description: 'ID of the link'
+ field :name, GraphQL::STRING_TYPE, null: true,
+ description: 'Name of the link'
+ field :url, GraphQL::STRING_TYPE, null: true,
+ description: 'URL of the link'
+ field :link_type, Types::ReleaseLinkTypeEnum, null: true,
+ description: 'Type of the link: `other`, `runbook`, `image`, `package`; defaults to `other`'
+ field :external, GraphQL::BOOLEAN_TYPE, null: true, method: :external?,
+ description: 'Indicates the link points to an external resource'
+ end
+end
diff --git a/app/graphql/types/release_link_type_enum.rb b/app/graphql/types/release_link_type_enum.rb
new file mode 100644
index 00000000000..b364855833f
--- /dev/null
+++ b/app/graphql/types/release_link_type_enum.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Types
+ class ReleaseLinkTypeEnum < BaseEnum
+ graphql_name 'ReleaseLinkType'
+ description 'Type of the link: `other`, `runbook`, `image`, `package`; defaults to `other`'
+
+ ::Releases::Link.link_types.keys.each do |link_type|
+ value link_type.upcase, value: link_type, description: "#{link_type.titleize} link type"
+ end
+ end
+end
diff --git a/app/graphql/types/release_source_type.rb b/app/graphql/types/release_source_type.rb
new file mode 100644
index 00000000000..0ec1ad85a39
--- /dev/null
+++ b/app/graphql/types/release_source_type.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+module Types
+ class ReleaseSourceType < BaseObject
+ graphql_name 'ReleaseSource'
+
+ authorize :read_release_sources
+
+ field :format, GraphQL::STRING_TYPE, null: true,
+ description: 'Format of the source'
+ field :url, GraphQL::STRING_TYPE, null: true,
+ description: 'Download URL of the source'
+ end
+end
diff --git a/app/graphql/types/release_type.rb b/app/graphql/types/release_type.rb
index 632351be5d3..3d8e5a93c68 100644
--- a/app/graphql/types/release_type.rb
+++ b/app/graphql/types/release_type.rb
@@ -23,8 +23,12 @@ module Types
description: 'Timestamp of when the release was created'
field :released_at, Types::TimeType, null: true,
description: 'Timestamp of when the release was released'
+ field :assets, Types::ReleaseAssetsType, null: true, method: :itself,
+ description: 'Assets of the release'
field :milestones, Types::MilestoneType.connection_type, null: true,
description: 'Milestones associated to the release'
+ field :evidences, Types::EvidenceType.connection_type, null: true,
+ description: 'Evidence for the release'
field :author, Types::UserType, null: true,
description: 'User that created the release'
diff --git a/app/graphql/types/resolvable_interface.rb b/app/graphql/types/resolvable_interface.rb
new file mode 100644
index 00000000000..a39092c70ca
--- /dev/null
+++ b/app/graphql/types/resolvable_interface.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module Types
+ # This Interface contains fields that are shared between objects that include either
+ # the `ResolvableNote` or `ResolvableDiscussion` modules.
+ module ResolvableInterface
+ include Types::BaseInterface
+
+ field :resolved_by, Types::UserType,
+ null: true,
+ description: 'User who resolved the object'
+
+ def resolved_by
+ return unless object.resolved_by_id
+
+ Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.resolved_by_id).find
+ end
+
+ field :resolved, GraphQL::BOOLEAN_TYPE, null: false,
+ description: 'Indicates if the object is resolved',
+ method: :resolved?
+ field :resolvable, GraphQL::BOOLEAN_TYPE, null: false,
+ description: 'Indicates if the object can be resolved',
+ method: :resolvable?
+ field :resolved_at, Types::TimeType, null: true,
+ description: 'Timestamp of when the object was resolved'
+ end
+end
diff --git a/app/graphql/types/snippet_type.rb b/app/graphql/types/snippet_type.rb
index b23c4f71ffa..73ca3425ded 100644
--- a/app/graphql/types/snippet_type.rb
+++ b/app/graphql/types/snippet_type.rb
@@ -27,9 +27,12 @@ module Types
authorize: :read_project,
resolve: -> (snippet, args, context) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, snippet.project_id).find }
+ # Author can be nil in some scenarios. For example,
+ # when the admin setting restricted visibility
+ # level is set to public
field :author, Types::UserType,
description: 'The owner of the snippet',
- null: false,
+ null: true,
resolve: -> (snippet, args, context) { Gitlab::Graphql::Loaders::BatchModelLoader.new(User, snippet.author_id).find }
field :file_name, GraphQL::STRING_TYPE,
@@ -65,6 +68,11 @@ module Types
calls_gitaly: true,
null: false
+ field :blobs, type: [Types::Snippets::BlobType],
+ description: 'Snippet blobs',
+ calls_gitaly: true,
+ null: false
+
field :ssh_url_to_repo, type: GraphQL::STRING_TYPE,
description: 'SSH URL to the snippet repository',
calls_gitaly: true,
diff --git a/app/graphql/types/snippets/file_input_action_enum.rb b/app/graphql/types/snippets/file_input_action_enum.rb
new file mode 100644
index 00000000000..7785853f3a8
--- /dev/null
+++ b/app/graphql/types/snippets/file_input_action_enum.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Types
+ module Snippets
+ class FileInputActionEnum < BaseEnum
+ graphql_name 'SnippetFileInputActionEnum'
+ description 'Type of a snippet file input action'
+
+ value 'create', value: :create
+ value 'update', value: :update
+ value 'delete', value: :delete
+ value 'move', value: :move
+ end
+ end
+end
diff --git a/app/graphql/types/snippets/file_input_type.rb b/app/graphql/types/snippets/file_input_type.rb
new file mode 100644
index 00000000000..85a02c8f493
--- /dev/null
+++ b/app/graphql/types/snippets/file_input_type.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module Types
+ module Snippets
+ class FileInputType < BaseInputObject # rubocop:disable Graphql/AuthorizeTypes
+ graphql_name 'SnippetFileInputType'
+ description 'Represents an action to perform over a snippet file'
+
+ argument :action, Types::Snippets::FileInputActionEnum,
+ description: 'Type of input action',
+ required: true
+
+ argument :previous_path, GraphQL::STRING_TYPE,
+ description: 'Previous path of the snippet file',
+ required: false
+
+ argument :file_path, GraphQL::STRING_TYPE,
+ description: 'Path of the snippet file',
+ required: true
+
+ argument :content, GraphQL::STRING_TYPE,
+ description: 'Snippet file content',
+ required: false
+ end
+ end
+end
diff --git a/app/graphql/types/user_state_enum.rb b/app/graphql/types/user_state_enum.rb
new file mode 100644
index 00000000000..d34936b4c48
--- /dev/null
+++ b/app/graphql/types/user_state_enum.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Types
+ class UserStateEnum < BaseEnum
+ 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'
+ end
+end
diff --git a/app/graphql/types/user_type.rb b/app/graphql/types/user_type.rb
index 29a3f5d452f..ab3c84ea539 100644
--- a/app/graphql/types/user_type.rb
+++ b/app/graphql/types/user_type.rb
@@ -12,12 +12,12 @@ module Types
field :id, GraphQL::ID_TYPE, null: false,
description: 'ID of the user'
- field :name, GraphQL::STRING_TYPE, null: false,
- description: 'Human-readable name of the user'
- field :state, GraphQL::STRING_TYPE, null: false,
- description: 'State of the issue'
field :username, GraphQL::STRING_TYPE, null: false,
description: 'Username of the user. Unique within this instance of GitLab'
+ field :name, GraphQL::STRING_TYPE, null: false,
+ description: 'Human-readable name of the user'
+ field :state, Types::UserStateEnum, null: false,
+ description: 'State of the user'
field :avatar_url, GraphQL::STRING_TYPE, null: true,
description: "URL of the user's avatar"
field :web_url, GraphQL::STRING_TYPE, null: false,
@@ -25,6 +25,20 @@ module Types
field :todos, Types::TodoType.connection_type, null: false,
resolver: Resolvers::TodoResolver,
description: 'Todos of the user'
+ field :group_memberships, Types::GroupMemberType.connection_type, null: true,
+ description: 'Group memberships of the user',
+ method: :group_members
+ field :project_memberships, Types::ProjectMemberType.connection_type, null: true,
+ description: 'Project memberships of the user',
+ method: :project_members
+
+ # Merge request field: MRs can be either authored or assigned:
+ field :authored_merge_requests, Types::MergeRequestType.connection_type, null: true,
+ resolver: Resolvers::AuthoredMergeRequestsResolver,
+ description: 'Merge Requests authored by the user'
+ field :assigned_merge_requests, Types::MergeRequestType.connection_type, null: true,
+ resolver: Resolvers::AssignedMergeRequestsResolver,
+ description: 'Merge Requests assigned to the user'
field :snippets,
Types::SnippetType.connection_type,
diff --git a/app/helpers/active_sessions_helper.rb b/app/helpers/active_sessions_helper.rb
index 84aa1160f12..8fb23f99cb3 100644
--- a/app/helpers/active_sessions_helper.rb
+++ b/app/helpers/active_sessions_helper.rb
@@ -20,6 +20,6 @@ module ActiveSessionsHelper
'monitor-o'
end
- sprite_icon(icon_name, size: 16, css_class: 'prepend-top-2')
+ sprite_icon(icon_name, size: 16, css_class: 'gl-mt-2')
end
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 2df33073a89..bdfdf5a69b3 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -103,7 +103,7 @@ module ApplicationHelper
page: body_data_page,
page_type_id: controller.params[:id],
find_file: find_file_path,
- group: "#{@group&.path}"
+ group: @group&.path
}.merge(project_data)
end
@@ -113,6 +113,7 @@ module ApplicationHelper
{
project_id: @project.id,
project: @project.path,
+ group: @project.group&.path,
namespace_id: @project.namespace&.id
}
end
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index b9f0e3582df..e709d15a946 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -26,6 +26,17 @@ module ApplicationSettingsHelper
end
end
+ def storage_weights
+ ApplicationSetting.repository_storages_weighted_attributes.map do |attribute|
+ storage = attribute.to_s.delete_prefix('repository_storages_weighted_')
+ {
+ name: attribute,
+ label: storage,
+ value: @application_setting.repository_storages_weighted[storage] || 0
+ }
+ end
+ end
+
def all_protocols_enabled?
Gitlab::CurrentSettings.enabled_git_access_protocol.blank?
end
@@ -228,6 +239,7 @@ module ApplicationSettingsHelper
:import_sources,
:max_artifacts_size,
:max_attachment_size,
+ :max_import_size,
:max_pages_size,
:metrics_method_call_threshold,
:minimum_password_length,
@@ -261,6 +273,8 @@ module ApplicationSettingsHelper
:sourcegraph_enabled,
:sourcegraph_url,
:sourcegraph_public_only,
+ :spam_check_endpoint_enabled,
+ :spam_check_endpoint_url,
:terminal_max_session_time,
:terms,
:throttle_authenticated_api_enabled,
diff --git a/app/helpers/auto_devops_helper.rb b/app/helpers/auto_devops_helper.rb
index 0f0d5350df6..0f14680607e 100644
--- a/app/helpers/auto_devops_helper.rb
+++ b/app/helpers/auto_devops_helper.rb
@@ -2,7 +2,7 @@
module AutoDevopsHelper
def show_auto_devops_callout?(project)
- Feature.get(:auto_devops_banner_disabled).off? &&
+ Feature.disabled?(:auto_devops_banner_disabled) &&
show_callout?('auto_devops_settings_dismissed') &&
can?(current_user, :admin_pipeline, project) &&
project.has_auto_devops_implicitly_disabled? &&
diff --git a/app/helpers/clusters_helper.rb b/app/helpers/clusters_helper.rb
index 39aaf242231..1204f882707 100644
--- a/app/helpers/clusters_helper.rb
+++ b/app/helpers/clusters_helper.rb
@@ -17,15 +17,23 @@ module ClustersHelper
end
end
+ def js_clusters_list_data(path = nil)
+ {
+ endpoint: path,
+ img_tags: {
+ aws: { path: image_path('illustrations/logos/amazon_eks.svg'), text: s_('ClusterIntegration|Amazon EKS') },
+ default: { path: image_path('illustrations/logos/kubernetes.svg'), text: _('Kubernetes Cluster') },
+ gcp: { path: image_path('illustrations/logos/google_gke.svg'), text: s_('ClusterIntegration|Google GKE') }
+ }
+ }
+ end
+
+ # This method is depreciated and will be removed when associated HAML files are moved to JavaScript
def provider_icon(provider = nil)
- case provider
- when 'aws'
- image_tag 'illustrations/logos/amazon_eks.svg', alt: s_('ClusterIntegration|Amazon EKS'), class: 'gl-h-full'
- when 'gcp'
- image_tag 'illustrations/logos/google_gke.svg', alt: s_('ClusterIntegration|Google GKE'), class: 'gl-h-full'
- else
- image_tag 'illustrations/logos/kubernetes.svg', alt: _('Kubernetes Cluster'), class: 'gl-h-full'
- end
+ img_data = js_clusters_list_data.dig(:img_tags, provider&.to_sym) ||
+ js_clusters_list_data.dig(:img_tags, :default)
+
+ image_tag img_data[:path], alt: img_data[:text], class: 'gl-h-full'
end
def render_gcp_signup_offer
diff --git a/app/helpers/environments_helper.rb b/app/helpers/environments_helper.rb
index e7b561af3da..41a255434af 100644
--- a/app/helpers/environments_helper.rb
+++ b/app/helpers/environments_helper.rb
@@ -60,7 +60,8 @@ module EnvironmentsHelper
'custom-metrics-path' => project_prometheus_metrics_path(project),
'validate-query-path' => validate_query_project_prometheus_metrics_path(project),
'custom-metrics-available' => "#{custom_metrics_available?(project)}",
- 'prometheus-alerts-available' => "#{can?(current_user, :read_prometheus_alerts, project)}"
+ 'prometheus-alerts-available' => "#{can?(current_user, :read_prometheus_alerts, project)}",
+ 'dashboard-timezone' => project.metrics_setting_dashboard_timezone.to_s.upcase
}
end
@@ -68,10 +69,11 @@ module EnvironmentsHelper
return {} unless environment
{
- 'current-environment-name' => environment.name,
- 'has-metrics' => "#{environment.has_metrics?}",
- 'prometheus-status' => "#{environment.prometheus_status}",
- 'environment-state' => "#{environment.state}"
+ 'metrics-dashboard-base-path' => environment_metrics_path(environment),
+ 'current-environment-name' => environment.name,
+ 'has-metrics' => "#{environment.has_metrics?}",
+ 'prometheus-status' => "#{environment.prometheus_status}",
+ 'environment-state' => "#{environment.state}"
}
end
@@ -94,7 +96,8 @@ module EnvironmentsHelper
'empty-loading-svg-path' => image_path('illustrations/monitoring/loading.svg'),
'empty-no-data-svg-path' => image_path('illustrations/monitoring/no_data.svg'),
'empty-no-data-small-svg-path' => image_path('illustrations/chart-empty-state-small.svg'),
- 'empty-unable-to-connect-svg-path' => image_path('illustrations/monitoring/unable_to_connect.svg')
+ 'empty-unable-to-connect-svg-path' => image_path('illustrations/monitoring/unable_to_connect.svg'),
+ 'custom-dashboard-base-path' => Metrics::Dashboard::CustomDashboardService::DASHBOARD_ROOT
}
end
end
diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb
index e93aeba6dfd..c1f343edd10 100644
--- a/app/helpers/events_helper.rb
+++ b/app/helpers/events_helper.rb
@@ -188,7 +188,7 @@ module EventsHelper
end
def event_wiki_page_target_url(event)
- project_wiki_url(event.project, event.target.canonical_slug)
+ project_wiki_url(event.project, event.target&.canonical_slug || Wiki::HOMEPAGE)
end
def event_note_title_html(event)
diff --git a/app/helpers/gitlab_routing_helper.rb b/app/helpers/gitlab_routing_helper.rb
index 4474534045b..8a9380f4771 100644
--- a/app/helpers/gitlab_routing_helper.rb
+++ b/app/helpers/gitlab_routing_helper.rb
@@ -162,8 +162,8 @@ module GitlabRoutingHelper
# against the arguments. We can speed this up 10x by generating the strings directly.
# /*namespace_id/:project_id/-/jobs/:job_id/artifacts/download(.:format)
- def fast_download_project_job_artifacts_path(project, job)
- expose_fast_artifacts_path(project, job, :download)
+ def fast_download_project_job_artifacts_path(project, job, params = {})
+ expose_fast_artifacts_path(project, job, :download, params)
end
# /*namespace_id/:project_id/-/jobs/:job_id/artifacts/keep(.:format)
@@ -176,8 +176,13 @@ module GitlabRoutingHelper
expose_fast_artifacts_path(project, job, :browse)
end
- def expose_fast_artifacts_path(project, job, action)
+ def expose_fast_artifacts_path(project, job, action, params = {})
path = "#{project.full_path}/-/jobs/#{job.id}/artifacts/#{action}"
+
+ unless params.empty?
+ path += "?#{params.to_query}"
+ end
+
Gitlab::Utils.append_path(Gitlab.config.gitlab.relative_url_root, path)
end
@@ -240,6 +245,14 @@ module GitlabRoutingHelper
end
end
+ def gitlab_dashboard_snippets_path(snippet, *args)
+ if snippet.is_a?(ProjectSnippet)
+ project_snippets_path(snippet.project, *args)
+ else
+ dashboard_snippets_path
+ end
+ end
+
def gitlab_raw_snippet_path(snippet, *args)
if snippet.is_a?(ProjectSnippet)
raw_project_snippet_path(snippet.project, snippet, *args)
@@ -298,6 +311,16 @@ module GitlabRoutingHelper
toggle_award_emoji_snippet_url(snippet, *new_args)
end
+ # Wikis
+
+ def wiki_path(wiki, **options)
+ Gitlab::UrlBuilder.wiki_url(wiki, only_path: true, **options)
+ end
+
+ def wiki_page_path(wiki, page, **options)
+ Gitlab::UrlBuilder.wiki_page_url(wiki, page, only_path: true, **options)
+ end
+
private
def snippet_query_params(snippet, *args)
diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb
index 1ce99652463..a848c814742 100644
--- a/app/helpers/issuables_helper.rb
+++ b/app/helpers/issuables_helper.rb
@@ -205,9 +205,9 @@ module IssuablesHelper
author_output
end
- output << content_tag(:span, (issuable_first_contribution_icon if issuable.first_contribution?), class: 'has-tooltip prepend-left-4', title: _('1st contribution!'))
+ output << content_tag(:span, (issuable_first_contribution_icon if issuable.first_contribution?), class: 'has-tooltip gl-ml-2', title: _('1st contribution!'))
- output << content_tag(:span, (issuable.task_status if issuable.tasks?), id: "task_status", class: "d-none d-sm-none d-md-inline-block prepend-left-8")
+ output << content_tag(:span, (issuable.task_status if issuable.tasks?), id: "task_status", class: "d-none d-sm-none d-md-inline-block gl-ml-3")
output << content_tag(:span, (issuable.task_status_short if issuable.tasks?), id: "task_status_short", class: "d-md-none")
output.join.html_safe
@@ -276,6 +276,7 @@ module IssuablesHelper
canUpdate: can?(current_user, :"update_#{issuable.to_ability_name}", issuable),
canDestroy: can?(current_user, :"destroy_#{issuable.to_ability_name}", issuable),
issuableRef: issuable.to_reference,
+ issuableStatus: issuable.state,
markdownPreviewPath: preview_markdown_path(parent),
markdownDocsPath: help_page_path('user/markdown'),
lockVersion: issuable.lock_version,
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index 39edfeea81e..244b97c7196 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -9,40 +9,6 @@ module IssuesHelper
classes.join(' ')
end
- def url_for_issue(issue_iid, project = @project, options = {})
- return '' if project.nil?
-
- url =
- if options[:internal]
- url_for_internal_issue(issue_iid, project, options)
- else
- url_for_tracker_issue(issue_iid, project, options)
- end
-
- # Ensure we return a valid URL to prevent possible XSS.
- URI.parse(url).to_s
- rescue URI::InvalidURIError
- ''
- end
-
- def url_for_tracker_issue(issue_iid, project, options)
- if options[:only_path]
- project.issues_tracker.issue_path(issue_iid)
- else
- project.issues_tracker.issue_url(issue_iid)
- end
- end
-
- def url_for_internal_issue(issue_iid, project = @project, options = {})
- helpers = Gitlab::Routing.url_helpers
-
- if options[:only_path]
- helpers.namespace_project_issue_path(namespace_id: project.namespace, project_id: project, id: issue_iid)
- else
- helpers.namespace_project_issue_url(namespace_id: project.namespace, project_id: project, id: issue_iid)
- end
- end
-
def status_box_class(item)
if item.try(:expired?)
'status-box-expired'
@@ -168,11 +134,6 @@ module IssuesHelper
def show_moved_service_desk_issue_warning?(issue)
false
end
-
- # Required for Banzai::Filter::IssueReferenceFilter
- module_function :url_for_issue
- module_function :url_for_internal_issue
- module_function :url_for_tracker_issue
end
IssuesHelper.prepend_if_ee('EE::IssuesHelper')
diff --git a/app/helpers/markup_helper.rb b/app/helpers/markup_helper.rb
index 4f66356c27e..7ab2b33de8c 100644
--- a/app/helpers/markup_helper.rb
+++ b/app/helpers/markup_helper.rb
@@ -129,8 +129,8 @@ module MarkupHelper
context.merge!(
pipeline: :wiki,
project: @project,
- project_wiki: @project_wiki,
- repository: @project_wiki.repository,
+ wiki: @wiki,
+ repository: @wiki.repository,
page_slug: wiki_page.slug,
issuable_state_filter_enabled: true
)
@@ -300,7 +300,7 @@ module MarkupHelper
# RepositoryLinkFilter and UploadLinkFilter
commit: @commit,
- project_wiki: @project_wiki,
+ wiki: @wiki,
ref: @ref,
requested_path: @path
)
diff --git a/app/helpers/milestones_helper.rb b/app/helpers/milestones_helper.rb
deleted file mode 100644
index df1ee54c5ac..00000000000
--- a/app/helpers/milestones_helper.rb
+++ /dev/null
@@ -1,309 +0,0 @@
-# frozen_string_literal: true
-
-module MilestonesHelper
- include EntityDateHelper
- include Gitlab::Utils::StrongMemoize
-
- def milestone_status_string(milestone)
- if milestone.closed?
- _('Closed')
- elsif milestone.expired?
- _('Past due')
- elsif milestone.upcoming?
- _('Upcoming')
- else
- _('Open')
- end
- end
-
- def milestones_filter_path(opts = {})
- if @project
- project_milestones_path(@project, opts)
- elsif @group
- group_milestones_path(@group, opts)
- else
- dashboard_milestones_path(opts)
- end
- end
-
- def milestones_issues_path(opts = {})
- if @project
- project_issues_path(@project, opts)
- elsif @group
- issues_group_path(@group, opts)
- else
- issues_dashboard_path(opts)
- end
- end
-
- def milestones_browse_issuables_path(milestone, state: nil, type:)
- opts = { milestone_title: milestone.title, state: state }
-
- if @project
- polymorphic_path([@project.namespace.becomes(Namespace), @project, type], opts)
- elsif @group
- polymorphic_url([type, @group], opts)
- else
- polymorphic_url([type, :dashboard], opts)
- end
- end
-
- def milestone_issues_by_label_count(milestone, label, state:)
- issues = milestone.issues.with_label(label.title)
- issues =
- case state
- when :opened
- issues.opened
- when :closed
- issues.closed
- else
- raise ArgumentError, _("invalid milestone state `%{state}`") % { state: state }
- end
-
- issues.size
- end
-
- # Returns count of milestones for different states
- # Uses explicit hash keys as the 'opened' state URL params differs from the db value
- # and we need to add the total
- # rubocop: disable CodeReuse/ActiveRecord
- def milestone_counts(milestones)
- counts = milestones.reorder(nil).group(:state).count
-
- {
- opened: counts['active'] || 0,
- closed: counts['closed'] || 0,
- all: counts.values.sum || 0
- }
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
- # Show 'active' class if provided GET param matches check
- # `or_blank` allows the function to return 'active' when given an empty param
- # Could be refactored to be simpler but that may make it harder to read
- def milestone_class_for_state(param, check, match_blank_param = false)
- if match_blank_param
- 'active' if param.blank? || param == check
- elsif param == check
- 'active'
- else
- check
- end
- end
-
- def milestone_progress_tooltip_text(milestone)
- has_issues = milestone.total_issues_count > 0
-
- if has_issues
- [
- _('Progress'),
- _("%{percent}%% complete") % { percent: milestone.percent_complete }
- ].join('<br />')
- else
- _('Progress')
- end
- end
-
- def milestone_progress_bar(milestone)
- options = {
- class: 'progress-bar bg-success',
- style: "width: #{milestone.percent_complete}%;"
- }
-
- content_tag :div, class: 'progress' do
- content_tag :div, nil, options
- end
- end
-
- def milestones_filter_dropdown_path
- project = @target_project || @project
- if project
- project_milestones_path(project, :json)
- elsif @group
- group_milestones_path(@group, :json)
- else
- dashboard_milestones_path(:json)
- end
- end
-
- def milestone_time_for(date, date_type)
- title = date_type == :start ? "Start date" : "End date"
-
- if date
- time_ago = time_ago_in_words(date).sub("about ", "")
- state = if date.past?
- "ago"
- else
- "remaining"
- end
-
- content = [
- title,
- "<br />",
- date.to_s(:medium),
- "(#{time_ago} #{state})"
- ].join(" ")
-
- content.html_safe
- else
- title
- end
- end
-
- def milestone_issues_tooltip_text(milestone)
- total = milestone.total_issues_count
- opened = milestone.opened_issues_count
- closed = milestone.closed_issues_count
-
- return _("Issues") if total.zero?
-
- content = []
-
- if opened > 0
- content << n_("1 open issue", "%{issues} open issues", opened) % { issues: opened }
- end
-
- if closed > 0
- content << n_("1 closed issue", "%{issues} closed issues", closed) % { issues: closed }
- end
-
- content.join('<br />').html_safe
- end
-
- def milestone_merge_requests_tooltip_text(milestone)
- merge_requests = milestone.merge_requests
-
- return _("Merge requests") if merge_requests.empty?
-
- content = []
-
- content << n_("1 open merge request", "%{merge_requests} open merge requests", merge_requests.opened.count) % { merge_requests: merge_requests.opened.count } if merge_requests.opened.any?
- content << n_("1 closed merge request", "%{merge_requests} closed merge requests", merge_requests.closed.count) % { merge_requests: merge_requests.closed.count } if merge_requests.closed.any?
- content << n_("1 merged merge request", "%{merge_requests} merged merge requests", merge_requests.merged.count) % { merge_requests: merge_requests.merged.count } if merge_requests.merged.any?
-
- content.join('<br />').html_safe
- end
-
- def milestone_releases_tooltip_text(milestone)
- count = milestone.releases.count
-
- return _("Releases") if count.zero?
-
- n_("%{releases} release", "%{releases} releases", count) % { releases: count }
- end
-
- def recent_releases_with_counts(milestone)
- total_count = milestone.releases.size
- return [[], 0, 0] if total_count == 0
-
- recent_releases = milestone.releases.recent.to_a
- more_count = total_count - recent_releases.size
- [recent_releases, total_count, more_count]
- end
-
- def milestone_tooltip_due_date(milestone)
- if milestone.due_date
- "#{milestone.due_date.to_s(:medium)} (#{remaining_days_in_words(milestone.due_date, milestone.start_date)})"
- else
- _('Milestone')
- end
- end
-
- def milestone_date_range(milestone)
- if milestone.start_date && milestone.due_date
- "#{milestone.start_date.to_s(:medium)}–#{milestone.due_date.to_s(:medium)}"
- elsif milestone.due_date
- if milestone.due_date.past?
- _("expired on %{milestone_due_date}") % { milestone_due_date: milestone.due_date.strftime('%b %-d, %Y') }
- else
- _("expires on %{milestone_due_date}") % { milestone_due_date: milestone.due_date.strftime('%b %-d, %Y') }
- end
- elsif milestone.start_date
- if milestone.start_date.past?
- _("started on %{milestone_start_date}") % { milestone_start_date: milestone.start_date.strftime('%b %-d, %Y') }
- else
- _("starts on %{milestone_start_date}") % { milestone_start_date: milestone.start_date.strftime('%b %-d, %Y') }
- end
- end
- end
-
- def milestone_tab_path(milestone, tab)
- if milestone.global_milestone?
- url_for(action: tab, title: milestone.title, format: :json)
- else
- url_for(action: tab, format: :json)
- end
- end
-
- def update_milestone_path(milestone, params = {})
- if milestone.project_milestone?
- project_milestone_path(milestone.project, milestone, milestone: params)
- else
- group_milestone_route(milestone, params)
- end
- end
-
- def group_milestone_route(milestone, params = {})
- params = nil if params.empty?
-
- if milestone.legacy_group_milestone?
- group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: params)
- else
- group_milestone_path(milestone.group, milestone.iid, milestone: params)
- end
- end
-
- def group_or_project_milestone_path(milestone)
- params =
- if milestone.group_milestone?
- { milestone: { title: milestone.title } }
- else
- { title: milestone.title }
- end
-
- milestone_path(milestone.milestone, params)
- end
-
- def edit_milestone_path(milestone)
- if milestone.group_milestone?
- edit_group_milestone_path(milestone.group, milestone)
- elsif milestone.project_milestone?
- edit_project_milestone_path(milestone.project, milestone)
- end
- end
-
- def can_admin_project_milestones?
- strong_memoize(:can_admin_project_milestones) do
- can?(current_user, :admin_milestone, @project)
- end
- end
-
- def can_admin_group_milestones?
- strong_memoize(:can_admin_group_milestones) do
- can?(current_user, :admin_milestone, @project.group)
- end
- end
-
- def display_issues_count_warning?(milestone)
- milestone_visible_issues_count(milestone) > Milestone::DISPLAY_ISSUES_LIMIT
- end
-
- def milestone_issues_count_message(milestone)
- total_count = milestone_visible_issues_count(milestone)
- limit = Milestone::DISPLAY_ISSUES_LIMIT
- link_options = { milestone_title: @milestone.title }
-
- message = _('Showing %{limit} of %{total_count} issues. ') % { limit: limit, total_count: total_count }
- message += link_to(_('View all issues'), milestones_issues_path(link_options))
-
- message.html_safe
- end
-
- private
-
- def milestone_visible_issues_count(milestone)
- @milestone_visible_issues_count ||= milestone.issues_visible_to_user(current_user).size
- end
-end
-
-MilestonesHelper.prepend_if_ee('EE::MilestonesHelper')
diff --git a/app/helpers/milestones_routing_helper.rb b/app/helpers/milestones_routing_helper.rb
deleted file mode 100644
index a49b561533a..00000000000
--- a/app/helpers/milestones_routing_helper.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-module MilestonesRoutingHelper
- def milestone_path(milestone, *args)
- if milestone.group_milestone?
- group_milestone_path(milestone.group, milestone, *args)
- elsif milestone.project_milestone?
- project_milestone_path(milestone.project, milestone, *args)
- end
- end
-
- def milestone_url(milestone, *args)
- if milestone.group_milestone?
- group_milestone_url(milestone.group, milestone, *args)
- elsif milestone.project_milestone?
- project_milestone_url(milestone.project, milestone, *args)
- end
- end
-end
diff --git a/app/helpers/namespaces_helper.rb b/app/helpers/namespaces_helper.rb
index 228dc2cc27f..b9f8d81bc4e 100644
--- a/app/helpers/namespaces_helper.rb
+++ b/app/helpers/namespaces_helper.rb
@@ -56,6 +56,45 @@ module NamespacesHelper
namespaces_options(selected, options)
end
+ def namespace_storage_alert(namespace)
+ return {} if current_user.nil?
+
+ payload = Namespaces::CheckStorageSizeService.new(namespace, current_user).execute.payload
+
+ return {} if payload.empty?
+
+ alert_level = payload[:alert_level]
+ root_namespace = payload[:root_namespace]
+
+ return {} if cookies["hide_storage_limit_alert_#{root_namespace.id}_#{alert_level}"] == 'true'
+
+ payload
+ end
+
+ def namespace_storage_alert_style(alert_level)
+ if alert_level == :error || alert_level == :alert
+ 'danger'
+ else
+ alert_level.to_s
+ end
+ end
+
+ def namespace_storage_alert_icon(alert_level)
+ if alert_level == :error || alert_level == :alert
+ 'error'
+ elsif alert_level == :info
+ 'information-o'
+ else
+ alert_level.to_s
+ end
+ end
+
+ def namespace_storage_usage_link(namespace)
+ # The usage quota page is only available in EE. This will be changed in
+ # the future, see https://gitlab.com/gitlab-org/gitlab/-/issues/220042.
+ nil
+ end
+
private
# Many importers create a temporary Group, so use the real
@@ -89,4 +128,4 @@ module NamespacesHelper
end
end
-NamespacesHelper.include_if_ee('EE::NamespacesHelper')
+NamespacesHelper.prepend_if_ee('EE::NamespacesHelper')
diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb
index acf9f8c5b5b..782f1d3e759 100644
--- a/app/helpers/notes_helper.rb
+++ b/app/helpers/notes_helper.rb
@@ -3,6 +3,13 @@
module NotesHelper
MAX_PRERENDERED_NOTES = 10
+ def note_target_title(note)
+ # The design title is already present in `Event#note_target_reference`.
+ return if note.nil? || note.for_design?
+
+ note.title
+ end
+
def note_target_fields(note)
if note.noteable
hidden_field_tag(:target_type, note.noteable.class.name.underscore) +
@@ -54,8 +61,8 @@ module NotesHelper
class: 'add-diff-note js-add-diff-note-button',
type: 'submit', name: 'button',
data: diff_view_line_data(line_code, position, line_type),
- title: 'Add a comment to this line' do
- icon('comment-o')
+ title: _('Add a comment to this line') do
+ sprite_icon('comment', size: 12)
end
end
@@ -162,7 +169,7 @@ module NotesHelper
end
def notes_data(issuable)
- {
+ data = {
discussionsPath: discussions_path(issuable),
registerPath: new_session_path(:user, redirect_to_referer: 'yes', anchor: 'register-pane'),
newSessionPath: new_session_path(:user, redirect_to_referer: 'yes'),
@@ -174,6 +181,16 @@ module NotesHelper
prerenderedNotesCount: issuable.capped_notes_count(MAX_PRERENDERED_NOTES),
lastFetchedAt: Time.now.to_i
}
+
+ if issuable.is_a?(MergeRequest)
+ data.merge!(
+ draftsPath: project_merge_request_drafts_path(@project, issuable),
+ draftsPublishPath: publish_project_merge_request_drafts_path(@project, issuable),
+ draftsDiscardPath: discard_project_merge_request_drafts_path(@project, issuable)
+ )
+ end
+
+ data
end
def discussion_resolved_intro(discussion)
diff --git a/app/helpers/notifications_helper.rb b/app/helpers/notifications_helper.rb
index 8fd277564df..68dfd008921 100644
--- a/app/helpers/notifications_helper.rb
+++ b/app/helpers/notifications_helper.rb
@@ -122,6 +122,6 @@ module NotificationsHelper
end
def notification_event_disabled?(event)
- event == :fixed_pipeline && Feature.disabled?(:ci_pipeline_fixed_notifications)
+ event == :fixed_pipeline && !Gitlab::Ci::Features.pipeline_fixed_notifications?
end
end
diff --git a/app/helpers/numbers_helper.rb b/app/helpers/numbers_helper.rb
index 3c0b11c4d32..38d3f90dd55 100644
--- a/app/helpers/numbers_helper.rb
+++ b/app/helpers/numbers_helper.rb
@@ -1,15 +1,14 @@
# frozen_string_literal: true
module NumbersHelper
- # rubocop: disable CodeReuse/ActiveRecord
def limited_counter_with_delimiter(resource, **options)
limit = options.fetch(:limit, 1000).to_i
- count = resource.limit(limit + 1).count(:all)
+ count = resource.page.total_count_with_limit(:all, limit: limit)
+
if count > limit
number_with_delimiter(count - 1, options) + '+'
else
number_with_delimiter(count, options)
end
end
- # rubocop: enable CodeReuse/ActiveRecord
end
diff --git a/app/helpers/page_layout_helper.rb b/app/helpers/page_layout_helper.rb
index 46e2c9ce56e..a44760e85ca 100644
--- a/app/helpers/page_layout_helper.rb
+++ b/app/helpers/page_layout_helper.rb
@@ -104,6 +104,16 @@ module PageLayoutHelper
end
end
+ # This helper ensures there is always a default `Gitlab::SearchContext` available
+ # to all controller that use the application layout.
+ def search_context
+ strong_memoize(:search_context) do
+ next super if defined?(super)
+
+ Gitlab::SearchContext::Builder.new(controller.view_context).build!
+ end
+ end
+
def fluid_layout
current_user && current_user.layout == "fluid"
end
diff --git a/app/helpers/projects/alert_management_helper.rb b/app/helpers/projects/alert_management_helper.rb
index af86ef715c2..bc585899591 100644
--- a/app/helpers/projects/alert_management_helper.rb
+++ b/app/helpers/projects/alert_management_helper.rb
@@ -15,7 +15,7 @@ module Projects::AlertManagementHelper
{
'alert-id' => alert_id,
'project-path' => project.full_path,
- 'new-issue-path' => new_project_issue_path(project)
+ 'project-issues-path' => project_issues_path(project)
}
end
end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index d743ea6aeea..bda9a69d71f 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -284,8 +284,8 @@ module ProjectsHelper
"xcode://clone?repo=#{CGI.escape(default_url_to_repo(project))}"
end
- def link_to_bfg
- link_to 'BFG', 'https://rtyley.github.io/bfg-repo-cleaner/', target: '_blank', rel: 'noopener noreferrer'
+ def link_to_filter_repo
+ link_to 'git filter-repo', 'https://github.com/newren/git-filter-repo', target: '_blank', rel: 'noopener noreferrer'
end
def explore_projects_tab?
@@ -367,6 +367,10 @@ module ProjectsHelper
@project.metrics_setting_external_dashboard_url
end
+ def metrics_dashboard_timezone
+ @project.metrics_setting_dashboard_timezone
+ end
+
def grafana_integration_url
@project.grafana_integration&.grafana_url
end
@@ -410,7 +414,7 @@ module ProjectsHelper
nav_tabs << :pipelines
end
- if can?(current_user, :read_environment, project) || can?(current_user, :read_cluster, project)
+ if can_view_operations_tab?(current_user, project)
nav_tabs << :operations
end
@@ -438,22 +442,29 @@ module ProjectsHelper
def tab_ability_map
{
- environments: :read_environment,
- milestones: :read_milestone,
- snippets: :read_snippet,
- settings: :admin_project,
- builds: :read_build,
- clusters: :read_cluster,
- serverless: :read_cluster,
- error_tracking: :read_sentry_issue,
- alert_management: :read_alert_management_alert,
- labels: :read_label,
- issues: :read_issue,
- project_members: :read_project_member,
- wiki: :read_wiki
+ environments: :read_environment,
+ metrics_dashboards: :metrics_dashboard,
+ milestones: :read_milestone,
+ snippets: :read_snippet,
+ settings: :admin_project,
+ builds: :read_build,
+ clusters: :read_cluster,
+ serverless: :read_cluster,
+ error_tracking: :read_sentry_issue,
+ alert_management: :read_alert_management_alert,
+ labels: :read_label,
+ issues: :read_issue,
+ project_members: :read_project_member,
+ wiki: :read_wiki
}
end
+ def can_view_operations_tab?(current_user, project)
+ [:read_environment, :read_cluster, :metrics_dashboard].any? do |ability|
+ can?(current_user, ability, project)
+ end
+ end
+
def search_tab_ability_map
@search_tab_ability_map ||= tab_ability_map.merge(
blobs: :download_code,
@@ -533,11 +544,6 @@ module ProjectsHelper
end
end
- def project_wiki_path_with_version(proj, page, version, is_newest)
- url_params = is_newest ? {} : { version_id: version }
- project_wiki_path(proj, page, url_params)
- end
-
def project_status_css_class(status)
case status
when "started"
@@ -670,7 +676,6 @@ module ProjectsHelper
def sidebar_settings_paths
%w[
projects#edit
- project_members#index
integrations#show
services#edit
hooks#index
@@ -729,7 +734,7 @@ module ProjectsHelper
end
def native_code_navigation_enabled?(project)
- Feature.enabled?(:code_navigation, project)
+ Feature.enabled?(:code_navigation, project, default_enabled: true)
end
def show_visibility_confirm_modal?(project)
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index 5ad65c59a2e..4e3b6aad8cc 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -3,28 +3,6 @@
module SearchHelper
SEARCH_PERMITTED_PARAMS = [:search, :scope, :project_id, :group_id, :repository_ref, :snippets].freeze
- def search_autocomplete_opts(term)
- return unless current_user
-
- resources_results = [
- groups_autocomplete(term),
- projects_autocomplete(term)
- ].flatten
-
- search_pattern = Regexp.new(Regexp.escape(term), "i")
-
- generic_results = project_autocomplete + default_autocomplete + help_autocomplete
- generic_results.concat(default_autocomplete_admin) if current_user.admin?
- generic_results.select! { |result| result[:label] =~ search_pattern }
-
- [
- resources_results,
- generic_results
- ].flatten.uniq do |item|
- item[:label]
- end
- end
-
def search_entries_info(collection, scope, term)
return if collection.to_a.empty?
@@ -95,91 +73,6 @@ module SearchHelper
private
- # Autocomplete results for various settings pages
- def default_autocomplete
- [
- { category: "Settings", label: _("User settings"), url: profile_path },
- { category: "Settings", label: _("SSH Keys"), url: profile_keys_path },
- { category: "Settings", label: _("Dashboard"), url: root_path }
- ]
- end
-
- # Autocomplete results for settings pages, for admins
- def default_autocomplete_admin
- [
- { category: "Settings", label: _("Admin Section"), url: admin_root_path }
- ]
- end
-
- # Autocomplete results for internal help pages
- def help_autocomplete
- [
- { category: "Help", label: _("API Help"), url: help_page_path("api/README") },
- { category: "Help", label: _("Markdown Help"), url: help_page_path("user/markdown") },
- { category: "Help", label: _("Permissions Help"), url: help_page_path("user/permissions") },
- { category: "Help", label: _("Public Access Help"), url: help_page_path("public_access/public_access") },
- { category: "Help", label: _("Rake Tasks Help"), url: help_page_path("raketasks/README") },
- { category: "Help", label: _("SSH Keys Help"), url: help_page_path("ssh/README") },
- { category: "Help", label: _("System Hooks Help"), url: help_page_path("system_hooks/system_hooks") },
- { category: "Help", label: _("Webhooks Help"), url: help_page_path("user/project/integrations/webhooks") },
- { category: "Help", label: _("Workflow Help"), url: help_page_path("workflow/README") }
- ]
- end
-
- # Autocomplete results for the current project, if it's defined
- def project_autocomplete
- if @project && @project.repository.root_ref
- ref = @ref || @project.repository.root_ref
-
- [
- { category: "In this project", label: _("Files"), url: project_tree_path(@project, ref) },
- { category: "In this project", label: _("Commits"), url: project_commits_path(@project, ref) },
- { category: "In this project", label: _("Network"), url: project_network_path(@project, ref) },
- { category: "In this project", label: _("Graph"), url: project_graph_path(@project, ref) },
- { category: "In this project", label: _("Issues"), url: project_issues_path(@project) },
- { category: "In this project", label: _("Merge Requests"), url: project_merge_requests_path(@project) },
- { category: "In this project", label: _("Milestones"), url: project_milestones_path(@project) },
- { category: "In this project", label: _("Snippets"), url: project_snippets_path(@project) },
- { category: "In this project", label: _("Members"), url: project_project_members_path(@project) },
- { category: "In this project", label: _("Wiki"), url: project_wikis_path(@project) }
- ]
- else
- []
- end
- end
-
- # Autocomplete results for the current user's groups
- # rubocop: disable CodeReuse/ActiveRecord
- def groups_autocomplete(term, limit = 5)
- current_user.authorized_groups.order_id_desc.search(term).limit(limit).map do |group|
- {
- category: "Groups",
- id: group.id,
- label: "#{search_result_sanitize(group.full_name)}",
- url: group_path(group),
- avatar_url: group.avatar_url || ''
- }
- end
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
- # Autocomplete results for the current user's projects
- # rubocop: disable CodeReuse/ActiveRecord
- def projects_autocomplete(term, limit = 5)
- current_user.authorized_projects.order_id_desc.search_by_title(term)
- .sorted_by_stars_desc.non_archived.limit(limit).map do |p|
- {
- category: "Projects",
- id: p.id,
- value: "#{search_result_sanitize(p.name)}",
- label: "#{search_result_sanitize(p.full_name)}",
- url: project_path(p),
- avatar_url: p.avatar_url || ''
- }
- end
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
def search_result_sanitize(str)
Sanitize.clean(str)
end
diff --git a/app/helpers/services_helper.rb b/app/helpers/services_helper.rb
index b13cc93436f..fe839b92ba6 100644
--- a/app/helpers/services_helper.rb
+++ b/app/helpers/services_helper.rb
@@ -98,6 +98,28 @@ module ServicesHelper
end
end
+ def integration_form_refactor?
+ Feature.enabled?(:integration_form_refactor, @project)
+ end
+
+ def trigger_events_for_service
+ return [] unless integration_form_refactor?
+
+ ServiceEventSerializer.new(service: @service).represent(@service.configurable_events).to_json
+ end
+
+ def fields_for_service
+ return [] unless integration_form_refactor?
+
+ ServiceFieldSerializer.new(service: @service).represent(@service.global_fields).to_json
+ end
+
+ def show_service_trigger_events?
+ return false if @service.is_a?(JiraService) || integration_form_refactor?
+
+ @service.configurable_events.present?
+ end
+
extend self
end
diff --git a/app/helpers/subscribable_banner_helper.rb b/app/helpers/subscribable_banner_helper.rb
new file mode 100644
index 00000000000..c9d4370f8ad
--- /dev/null
+++ b/app/helpers/subscribable_banner_helper.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+module SubscribableBannerHelper
+ # Overridden in EE
+ def display_subscription_banner!
+ end
+end
+
+SubscribableBannerHelper.prepend_if_ee('EE::SubscribableBannerHelper')
diff --git a/app/helpers/timeboxes_helper.rb b/app/helpers/timeboxes_helper.rb
new file mode 100644
index 00000000000..0bffdba7349
--- /dev/null
+++ b/app/helpers/timeboxes_helper.rb
@@ -0,0 +1,302 @@
+# frozen_string_literal: true
+
+module TimeboxesHelper
+ include EntityDateHelper
+ include Gitlab::Utils::StrongMemoize
+
+ def milestone_status_string(milestone)
+ if milestone.closed?
+ _('Closed')
+ elsif milestone.expired?
+ _('Past due')
+ elsif milestone.upcoming?
+ _('Upcoming')
+ else
+ _('Open')
+ end
+ end
+
+ def milestones_filter_path(opts = {})
+ if @project
+ project_milestones_path(@project, opts)
+ elsif @group
+ group_milestones_path(@group, opts)
+ else
+ dashboard_milestones_path(opts)
+ end
+ end
+
+ def milestones_issues_path(opts = {})
+ if @project
+ project_issues_path(@project, opts)
+ elsif @group
+ issues_group_path(@group, opts)
+ else
+ issues_dashboard_path(opts)
+ end
+ end
+
+ def milestones_browse_issuables_path(milestone, state: nil, type:)
+ opts = { milestone_title: milestone.title, state: state }
+
+ if @project
+ polymorphic_path([@project.namespace.becomes(Namespace), @project, type], opts)
+ elsif @group
+ polymorphic_url([type, @group], opts)
+ else
+ polymorphic_url([type, :dashboard], opts)
+ end
+ end
+
+ def milestone_issues_by_label_count(milestone, label, state:)
+ issues = milestone.issues.with_label(label.title)
+ issues =
+ case state
+ when :opened
+ issues.opened
+ when :closed
+ issues.closed
+ else
+ raise ArgumentError, _("invalid milestone state `%{state}`") % { state: state }
+ end
+
+ issues.size
+ end
+
+ # Returns count of milestones for different states
+ # Uses explicit hash keys as the 'opened' state URL params differs from the db value
+ # and we need to add the total
+ # rubocop: disable CodeReuse/ActiveRecord
+ def milestone_counts(milestones)
+ counts = milestones.reorder(nil).group(:state).count
+
+ {
+ opened: counts['active'] || 0,
+ closed: counts['closed'] || 0,
+ all: counts.values.sum || 0
+ }
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ # Show 'active' class if provided GET param matches check
+ # `or_blank` allows the function to return 'active' when given an empty param
+ # Could be refactored to be simpler but that may make it harder to read
+ def milestone_class_for_state(param, check, match_blank_param = false)
+ if match_blank_param
+ 'active' if param.blank? || param == check
+ elsif param == check
+ 'active'
+ else
+ check
+ end
+ end
+
+ def milestone_progress_tooltip_text(milestone)
+ has_issues = milestone.total_issues_count > 0
+
+ if has_issues
+ [
+ _('Progress'),
+ _("%{percent}%% complete") % { percent: milestone.percent_complete }
+ ].join('<br />')
+ else
+ _('Progress')
+ end
+ end
+
+ def milestone_progress_bar(milestone)
+ options = {
+ class: 'progress-bar bg-success',
+ style: "width: #{milestone.percent_complete}%;"
+ }
+
+ content_tag :div, class: 'progress' do
+ content_tag :div, nil, options
+ end
+ end
+
+ def milestones_filter_dropdown_path
+ project = @target_project || @project
+ if project
+ project_milestones_path(project, :json)
+ elsif @group
+ group_milestones_path(@group, :json)
+ else
+ dashboard_milestones_path(:json)
+ end
+ end
+
+ def milestone_time_for(date, date_type)
+ title = date_type == :start ? "Start date" : "End date"
+
+ if date
+ time_ago = time_ago_in_words(date).sub("about ", "")
+ state = if date.past?
+ "ago"
+ else
+ "remaining"
+ end
+
+ content = [
+ title,
+ "<br />",
+ date.to_s(:medium),
+ "(#{time_ago} #{state})"
+ ].join(" ")
+
+ content.html_safe
+ else
+ title
+ end
+ end
+
+ def milestone_issues_tooltip_text(milestone)
+ total = milestone.total_issues_count
+ opened = milestone.opened_issues_count
+ closed = milestone.closed_issues_count
+
+ return _("Issues") if total.zero?
+
+ content = []
+
+ if opened > 0
+ content << n_("1 open issue", "%{issues} open issues", opened) % { issues: opened }
+ end
+
+ if closed > 0
+ content << n_("1 closed issue", "%{issues} closed issues", closed) % { issues: closed }
+ end
+
+ content.join('<br />').html_safe
+ end
+
+ def milestone_merge_requests_tooltip_text(milestone)
+ merge_requests = milestone.merge_requests
+
+ return _("Merge requests") if merge_requests.empty?
+
+ content = []
+
+ content << n_("1 open merge request", "%{merge_requests} open merge requests", merge_requests.opened.count) % { merge_requests: merge_requests.opened.count } if merge_requests.opened.any?
+ content << n_("1 closed merge request", "%{merge_requests} closed merge requests", merge_requests.closed.count) % { merge_requests: merge_requests.closed.count } if merge_requests.closed.any?
+ content << n_("1 merged merge request", "%{merge_requests} merged merge requests", merge_requests.merged.count) % { merge_requests: merge_requests.merged.count } if merge_requests.merged.any?
+
+ content.join('<br />').html_safe
+ end
+
+ def milestone_releases_tooltip_text(milestone)
+ count = milestone.releases.count
+
+ return _("Releases") if count.zero?
+
+ n_("%{releases} release", "%{releases} releases", count) % { releases: count }
+ end
+
+ def recent_releases_with_counts(milestone)
+ total_count = milestone.releases.size
+ return [[], 0, 0] if total_count == 0
+
+ recent_releases = milestone.releases.recent.to_a
+ more_count = total_count - recent_releases.size
+ [recent_releases, total_count, more_count]
+ end
+
+ def milestone_tooltip_due_date(milestone)
+ if milestone.due_date
+ "#{milestone.due_date.to_s(:medium)} (#{remaining_days_in_words(milestone.due_date, milestone.start_date)})"
+ else
+ _('Milestone')
+ end
+ end
+
+ def timebox_date_range(timebox)
+ if timebox.start_date && timebox.due_date
+ "#{timebox.start_date.to_s(:medium)}–#{timebox.due_date.to_s(:medium)}"
+ elsif timebox.due_date
+ if timebox.due_date.past?
+ _("expired on %{timebox_due_date}") % { timebox_due_date: timebox.due_date.to_s(:medium) }
+ else
+ _("expires on %{timebox_due_date}") % { timebox_due_date: timebox.due_date.to_s(:medium) }
+ end
+ elsif timebox.start_date
+ if timebox.start_date.past?
+ _("started on %{timebox_start_date}") % { timebox_start_date: timebox.start_date.to_s(:medium) }
+ else
+ _("starts on %{timebox_start_date}") % { timebox_start_date: timebox.start_date.to_s(:medium) }
+ end
+ end
+ end
+ alias_method :milestone_date_range, :timebox_date_range
+
+ def milestone_tab_path(milestone, tab)
+ url_for(action: tab, format: :json)
+ end
+
+ def update_milestone_path(milestone, params = {})
+ if milestone.project_milestone?
+ project_milestone_path(milestone.project, milestone, milestone: params)
+ else
+ group_milestone_route(milestone, params)
+ end
+ end
+
+ def group_milestone_route(milestone, params = {})
+ params = nil if params.empty?
+
+ group_milestone_path(milestone.group, milestone.iid, milestone: params)
+ end
+
+ def group_or_project_milestone_path(milestone)
+ params =
+ if milestone.group_milestone?
+ { milestone: { title: milestone.title } }
+ else
+ { title: milestone.title }
+ end
+
+ milestone_path(milestone.milestone, params)
+ end
+
+ def edit_milestone_path(milestone)
+ if milestone.group_milestone?
+ edit_group_milestone_path(milestone.group, milestone)
+ elsif milestone.project_milestone?
+ edit_project_milestone_path(milestone.project, milestone)
+ end
+ end
+
+ def can_admin_project_milestones?
+ strong_memoize(:can_admin_project_milestones) do
+ can?(current_user, :admin_milestone, @project)
+ end
+ end
+
+ def can_admin_group_milestones?
+ strong_memoize(:can_admin_group_milestones) do
+ can?(current_user, :admin_milestone, @project.group)
+ end
+ end
+
+ def display_issues_count_warning?(milestone)
+ milestone_visible_issues_count(milestone) > Milestone::DISPLAY_ISSUES_LIMIT
+ end
+
+ def milestone_issues_count_message(milestone)
+ total_count = milestone_visible_issues_count(milestone)
+ limit = Milestone::DISPLAY_ISSUES_LIMIT
+ link_options = { milestone_title: @milestone.title }
+
+ message = _('Showing %{limit} of %{total_count} issues. ') % { limit: limit, total_count: total_count }
+ message += link_to(_('View all issues'), milestones_issues_path(link_options))
+
+ message.html_safe
+ end
+
+ private
+
+ def milestone_visible_issues_count(milestone)
+ @milestone_visible_issues_count ||= milestone.issues_visible_to_user(current_user).size
+ end
+end
+
+TimeboxesHelper.prepend_if_ee('EE::TimeboxesHelper')
diff --git a/app/helpers/timeboxes_routing_helper.rb b/app/helpers/timeboxes_routing_helper.rb
new file mode 100644
index 00000000000..6fb5a1a3185
--- /dev/null
+++ b/app/helpers/timeboxes_routing_helper.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module TimeboxesRoutingHelper
+ def milestone_path(milestone, *args)
+ if milestone.group_milestone?
+ group_milestone_path(milestone.group, milestone, *args)
+ elsif milestone.project_milestone?
+ project_milestone_path(milestone.project, milestone, *args)
+ end
+ end
+
+ def milestone_url(milestone, *args)
+ if milestone.group_milestone?
+ group_milestone_url(milestone.group, milestone, *args)
+ elsif milestone.project_milestone?
+ project_milestone_url(milestone.project, milestone, *args)
+ end
+ end
+end
+
+TimeboxesRoutingHelper.prepend_if_ee('EE::TimeboxesRoutingHelper')
diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb
index 41f39c7e798..2b4f2f11d1e 100644
--- a/app/helpers/todos_helper.rb
+++ b/app/helpers/todos_helper.rb
@@ -37,11 +37,12 @@ module TodosHelper
end
def todo_target_title(todo)
- if todo.target
- "\"#{todo.target.title}\""
- else
- ""
- end
+ # Design To Dos' filenames are displayed in `#todo_target_link` (see `Design#to_reference`),
+ # so to avoid displaying duplicate filenames in the To Do list for designs,
+ # we return an empty string here.
+ return "" if todo.target.blank? || todo.for_design?
+
+ "\"#{todo.target.title}\""
end
def todo_parent_path(todo)
@@ -54,6 +55,7 @@ module TodosHelper
def todo_target_type_name(todo)
return _('design') if todo.for_design?
+ return _('alert') if todo.for_alert?
todo.target_type.titleize.downcase
end
@@ -67,6 +69,8 @@ module TodosHelper
project_commit_path(todo.project, todo.target, path_options)
elsif todo.for_design?
todos_design_path(todo, path_options)
+ elsif todo.for_alert?
+ details_project_alert_management_path(todo.project, todo.target)
else
path = [todo.resource_parent, todo.target]
diff --git a/app/helpers/visibility_level_helper.rb b/app/helpers/visibility_level_helper.rb
index d62839cf037..304b58d232a 100644
--- a/app/helpers/visibility_level_helper.rb
+++ b/app/helpers/visibility_level_helper.rb
@@ -167,6 +167,17 @@ module VisibilityLevelHelper
[requested_level, max_allowed_visibility_level(form_model)].min
end
+ def available_visibility_levels(form_model)
+ Gitlab::VisibilityLevel.values.reject do |level|
+ disallowed_visibility_level?(form_model, level) ||
+ restricted_visibility_levels.include?(level)
+ end
+ end
+
+ def snippets_selected_visibility_level(visibility_levels, selected)
+ visibility_levels.find { |level| level == selected } || visibility_levels.min
+ end
+
def multiple_visibility_levels_restricted?
restricted_visibility_levels.many? # rubocop: disable CodeReuse/ActiveRecord
end
diff --git a/app/helpers/wiki_helper.rb b/app/helpers/wiki_helper.rb
index dd8fde2a697..3c983606b73 100644
--- a/app/helpers/wiki_helper.rb
+++ b/app/helpers/wiki_helper.rb
@@ -22,7 +22,7 @@ module WikiHelper
page_slug_split
.map do |dir_or_page|
current_slug = "#{current_slug}#{dir_or_page}/"
- add_to_breadcrumb_dropdown link_to(WikiPage.unhyphenize(dir_or_page).capitalize, project_wiki_path(@project, current_slug)), location: :after
+ add_to_breadcrumb_dropdown link_to(WikiPage.unhyphenize(dir_or_page).capitalize, wiki_page_path(@wiki, current_slug)), location: :after
end
end
@@ -32,7 +32,7 @@ module WikiHelper
content_tag(:div, class: 'alert alert-danger') do
case error
when WikiPage::PageChangedError
- page_link = link_to s_("WikiPageConflictMessage|the page"), project_wiki_path(@project, @page), target: "_blank"
+ page_link = link_to s_("WikiPageConflictMessage|the page"), wiki_page_path(@wiki, @page), target: "_blank"
concat(
(s_("WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{page_link} and make sure your changes will not unintentionally remove theirs.") % { page_link: page_link }).html_safe
)
@@ -45,26 +45,63 @@ module WikiHelper
end
def wiki_attachment_upload_url
- expose_url(api_v4_projects_wikis_attachments_path(id: @project.id))
+ expose_url(api_v4_projects_wikis_attachments_path(id: @wiki.container.id))
end
- def wiki_sort_controls(project, sort, direction)
- sort ||= ProjectWiki::TITLE_ORDER
+ def wiki_sort_controls(wiki, sort, direction)
+ sort ||= Wiki::TITLE_ORDER
link_class = 'btn btn-default has-tooltip reverse-sort-btn qa-reverse-sort rspec-reverse-sort'
reversed_direction = direction == 'desc' ? 'asc' : 'desc'
icon_class = direction == 'desc' ? 'highest' : 'lowest'
- link_to(project_wikis_pages_path(project, sort: sort, direction: reversed_direction),
+ link_to(wiki_path(wiki, action: :pages, sort: sort, direction: reversed_direction),
type: 'button', class: link_class, title: _('Sort direction')) do
sprite_icon("sort-#{icon_class}", size: 16)
end
end
def wiki_sort_title(key)
- if key == ProjectWiki::CREATED_AT_ORDER
+ if key == Wiki::CREATED_AT_ORDER
s_("Wiki|Created date")
else
s_("Wiki|Title")
end
end
+
+ def wiki_empty_state_messages(wiki)
+ case wiki.container
+ when Project
+ {
+ writable: {
+ title: s_('WikiEmpty|The wiki lets you write documentation for your project'),
+ body: s_("WikiEmpty|A wiki is where you can store all the details about your project. This can include why you've created it, its principles, how to use it, and so on.")
+ },
+ issuable: {
+ title: s_('WikiEmpty|This project has no wiki pages'),
+ body: s_('WikiEmptyIssueMessage|You must be a project member in order to add wiki pages. If you have suggestions for how to improve the wiki for this project, consider opening an issue in the %{issues_link}.')
+ },
+ readonly: {
+ title: s_('WikiEmpty|This project has no wiki pages'),
+ body: s_('WikiEmpty|You must be a project member in order to add wiki pages.')
+ }
+ }
+ when Group
+ {
+ writable: {
+ title: s_('WikiEmpty|The wiki lets you write documentation for your group'),
+ body: s_("WikiEmpty|A wiki is where you can store all the details about your group. This can include why you've created it, its principles, how to use it, and so on.")
+ },
+ issuable: {
+ title: s_('WikiEmpty|This group has no wiki pages'),
+ body: s_('WikiEmptyIssueMessage|You must be a group member in order to add wiki pages. If you have suggestions for how to improve the wiki for this group, consider opening an issue in the %{issues_link}.')
+ },
+ readonly: {
+ title: s_('WikiEmpty|This group has no wiki pages'),
+ body: s_('WikiEmpty|You must be a group member in order to add wiki pages.')
+ }
+ }
+ else
+ raise NotImplementedError, "Unknown wiki container type #{wiki.container.class.name}"
+ end
+ end
end
diff --git a/app/mailers/emails/issues.rb b/app/mailers/emails/issues.rb
index d4d93ab9795..bcf60bea0e0 100644
--- a/app/mailers/emails/issues.rb
+++ b/app/mailers/emails/issues.rb
@@ -126,3 +126,5 @@ module Emails
end
end
end
+
+Emails::Issues.prepend_if_ee('EE::Emails::Issues')
diff --git a/app/mailers/emails/profile.rb b/app/mailers/emails/profile.rb
index 4b19149a833..c327a0bab43 100644
--- a/app/mailers/emails/profile.rb
+++ b/app/mailers/emails/profile.rb
@@ -45,13 +45,20 @@ module Emails
end
end
- def unknown_sign_in_email(user, ip)
+ def unknown_sign_in_email(user, ip, time)
@user = user
@ip = ip
+ @time = time
@target_url = edit_profile_password_url
Gitlab::I18n.with_locale(@user.preferred_language) do
- mail(to: @user.notification_email, subject: subject(_("Unknown sign-in from new location")))
+ mail(
+ to: @user.notification_email,
+ subject: subject(_("%{host} sign-in from new location") % { host: Gitlab.config.gitlab.host })
+ ) do |format|
+ format.html { render layout: 'mailer' }
+ format.text { render layout: 'mailer' }
+ end
end
end
end
diff --git a/app/mailers/emails/reviews.rb b/app/mailers/emails/reviews.rb
new file mode 100644
index 00000000000..ddb9e161a80
--- /dev/null
+++ b/app/mailers/emails/reviews.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module Emails
+ module Reviews
+ def new_review_email(recipient_id, review_id)
+ setup_review_email(review_id, recipient_id)
+
+ mail_answer_thread(@merge_request, review_thread_options(recipient_id))
+ end
+
+ private
+
+ def review_thread_options(recipient_id)
+ {
+ from: sender(@author.id),
+ to: User.find(recipient_id).notification_email_for(@merge_request.target_project.group),
+ subject: subject("#{@merge_request.title} (#{@merge_request.to_reference})")
+ }
+ end
+
+ def setup_review_email(review_id, recipient_id)
+ review = Review.find_by_id(review_id)
+
+ @notes = review.notes
+ @author = review.author
+ @author_name = review.author_name
+ @project = review.project
+ @merge_request = review.merge_request
+ @target_url = project_merge_request_url(@project, @merge_request)
+ @sent_notification = SentNotification.record(@merge_request, recipient_id, reply_key)
+ end
+ end
+end
diff --git a/app/mailers/notify.rb b/app/mailers/notify.rb
index d9483bab543..2cf72d40635 100644
--- a/app/mailers/notify.rb
+++ b/app/mailers/notify.rb
@@ -18,8 +18,9 @@ class Notify < ApplicationMailer
include Emails::RemoteMirrors
include Emails::Releases
include Emails::Groups
+ include Emails::Reviews
- helper MilestonesHelper
+ helper TimeboxesHelper
helper MergeRequestsHelper
helper DiffHelper
helper BlobHelper
diff --git a/app/mailers/previews/notify_preview.rb b/app/mailers/previews/notify_preview.rb
index c931b5a848f..cb7c6a36c27 100644
--- a/app/mailers/previews/notify_preview.rb
+++ b/app/mailers/previews/notify_preview.rb
@@ -162,7 +162,7 @@ class NotifyPreview < ActionMailer::Preview
end
def unknown_sign_in_email
- Notify.unknown_sign_in_email(user, '127.0.0.1').message
+ Notify.unknown_sign_in_email(user, '127.0.0.1', Time.current).message
end
private
diff --git a/app/models/active_session.rb b/app/models/active_session.rb
index 065bd5507be..a23190cc8b3 100644
--- a/app/models/active_session.rb
+++ b/app/models/active_session.rb
@@ -36,7 +36,7 @@ class ActiveSession
timestamp = Time.current
active_user_session = new(
- ip_address: request.ip,
+ ip_address: request.remote_ip,
browser: client.name,
os: client.os_name,
device_name: client.device_name,
diff --git a/app/models/alert_management.rb b/app/models/alert_management.rb
new file mode 100644
index 00000000000..0346b1f155f
--- /dev/null
+++ b/app/models/alert_management.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+module AlertManagement
+ def self.table_name_prefix
+ 'alert_management_'
+ end
+end
diff --git a/app/models/alert_management/alert.rb b/app/models/alert_management/alert.rb
index acaf474ecc2..af60ddd6f9a 100644
--- a/app/models/alert_management/alert.rb
+++ b/app/models/alert_management/alert.rb
@@ -1,10 +1,14 @@
# frozen_string_literal: true
+require_dependency 'alert_management'
+
module AlertManagement
class Alert < ApplicationRecord
+ include IidRoutes
include AtomicInternalId
include ShaAttribute
include Sortable
+ include Noteable
include Gitlab::SQL::Pattern
STATUSES = {
@@ -23,9 +27,15 @@ module AlertManagement
belongs_to :project
belongs_to :issue, optional: true
- has_internal_id :iid, scope: :project, init: ->(s) { s.project.alert_management_alerts.maximum(:iid) }
- self.table_name = 'alert_management_alerts'
+ has_many :alert_assignees, inverse_of: :alert
+ has_many :assignees, through: :alert_assignees
+
+ has_many :notes, as: :noteable, inverse_of: :noteable, dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
+ has_many :ordered_notes, -> { fresh }, as: :noteable, class_name: 'Note'
+ has_many :user_mentions, class_name: 'AlertManagement::AlertUserMention', foreign_key: :alert_management_alert_id
+
+ has_internal_id :iid, scope: :project, init: ->(s) { s.project.alert_management_alerts.maximum(:iid) }
sha_attribute :fingerprint
@@ -102,7 +112,7 @@ module AlertManagement
scope :order_start_time, -> (sort_order) { order(started_at: sort_order) }
scope :order_end_time, -> (sort_order) { order(ended_at: sort_order) }
- scope :order_events_count, -> (sort_order) { order(events: sort_order) }
+ scope :order_event_count, -> (sort_order) { order(events: sort_order) }
scope :order_severity, -> (sort_order) { order(severity: sort_order) }
scope :order_status, -> (sort_order) { order(status: sort_order) }
@@ -110,12 +120,12 @@ module AlertManagement
def self.sort_by_attribute(method)
case method.to_s
- when 'start_time_asc' then order_start_time(:asc)
- when 'start_time_desc' then order_start_time(:desc)
- when 'end_time_asc' then order_end_time(:asc)
- when 'end_time_desc' then order_end_time(:desc)
- when 'events_count_asc' then order_events_count(:asc)
- when 'events_count_desc' then order_events_count(:desc)
+ when 'started_at_asc' then order_start_time(:asc)
+ when 'started_at_desc' then order_start_time(:desc)
+ when 'ended_at_asc' then order_end_time(:asc)
+ when 'ended_at_desc' then order_end_time(:desc)
+ when 'event_count_asc' then order_event_count(:asc)
+ when 'event_count_desc' then order_event_count(:desc)
when 'severity_asc' then order_severity(:asc)
when 'severity_desc' then order_severity(:desc)
when 'status_asc' then order_status(:asc)
@@ -135,8 +145,28 @@ module AlertManagement
monitoring_tool == Gitlab::AlertManagement::AlertParams::MONITORING_TOOLS[:prometheus]
end
+ def register_new_event!
+ increment!(:events)
+ end
+
+ # required for todos (typically contains an identifier like issue iid)
+ # no-op; we could use iid, but we don't have a reference prefix
+ def to_reference(_from = nil, full: false)
+ ''
+ end
+
+ def execute_services
+ return unless project.has_active_services?(:alert_hooks)
+
+ project.execute_services(hook_data, :alert_hooks)
+ end
+
private
+ def hook_data
+ Gitlab::DataBuilder::Alert.build(self)
+ end
+
def hosts_length
return unless hosts
diff --git a/app/models/alert_management/alert_assignee.rb b/app/models/alert_management/alert_assignee.rb
new file mode 100644
index 00000000000..c74b2699182
--- /dev/null
+++ b/app/models/alert_management/alert_assignee.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module AlertManagement
+ class AlertAssignee < ApplicationRecord
+ belongs_to :alert, inverse_of: :alert_assignees
+ belongs_to :assignee, class_name: 'User', foreign_key: :user_id
+
+ validates :alert, presence: true
+ validates :assignee, presence: true, uniqueness: { scope: :alert_id }
+ end
+end
diff --git a/app/models/alert_management/alert_user_mention.rb b/app/models/alert_management/alert_user_mention.rb
new file mode 100644
index 00000000000..d36aa80ee05
--- /dev/null
+++ b/app/models/alert_management/alert_user_mention.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+module AlertManagement
+ class AlertUserMention < UserMention
+ belongs_to :alert_management_alert, class_name: '::AlertManagement::Alert'
+ belongs_to :note
+ end
+end
diff --git a/app/models/application_record.rb b/app/models/application_record.rb
index 0979d03f6e6..c7e4d64d3d5 100644
--- a/app/models/application_record.rb
+++ b/app/models/application_record.rb
@@ -5,6 +5,10 @@ class ApplicationRecord < ActiveRecord::Base
alias_method :reset, :reload
+ def self.without_order
+ reorder(nil)
+ end
+
def self.id_in(ids)
where(id: ids)
end
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index b29d6731b08..425a0e05c7d 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -19,6 +19,12 @@ class ApplicationSetting < ApplicationRecord
belongs_to :instance_administrators_group, class_name: "Group"
+ def self.repository_storages_weighted_attributes
+ @repository_storages_weighted_atributes ||= Gitlab.config.repositories.storages.keys.map { |k| "repository_storages_weighted_#{k}".to_sym }.freeze
+ end
+
+ store_accessor :repository_storages_weighted, *Gitlab.config.repositories.storages.keys, prefix: true
+
# Include here so it can override methods from
# `add_authentication_token_field`
# We don't prepend for now because otherwise we'll need to
@@ -39,6 +45,7 @@ class ApplicationSetting < ApplicationRecord
cache_markdown_field :after_sign_up_text
default_value_for :id, 1
+ default_value_for :repository_storages_weighted, {}
chronic_duration_attr_writer :archive_builds_in_human_readable, :archive_builds_in_seconds
@@ -136,6 +143,10 @@ class ApplicationSetting < ApplicationRecord
presence: true,
numericality: { only_integer: true, greater_than: 0 }
+ validates :max_import_size,
+ presence: true,
+ numericality: { only_integer: true, greater_than_or_equal_to: 0 }
+
validates :max_pages_size,
presence: true,
numericality: { only_integer: true, greater_than_or_equal_to: 0,
@@ -152,6 +163,7 @@ class ApplicationSetting < ApplicationRecord
validates :repository_storages, presence: true
validate :check_repository_storages
+ validate :check_repository_storages_weighted
validates :auto_devops_domain,
allow_blank: true,
@@ -271,6 +283,10 @@ class ApplicationSetting < ApplicationRecord
validates :allowed_key_types, presence: true
+ repository_storages_weighted_attributes.each do |attribute|
+ validates attribute, allow_nil: true, numericality: { only_integer: true, greater_than_or_equal_to: 0, less_than_or_equal_to: 100 }
+ end
+
validates_each :restricted_visibility_levels do |record, attr, value|
value&.each do |level|
unless Gitlab::VisibilityLevel.options.value?(level)
@@ -301,6 +317,13 @@ class ApplicationSetting < ApplicationRecord
numericality: { greater_than: 0, less_than_or_equal_to: 10 },
if: :external_authorization_service_enabled
+ validates :spam_check_endpoint_url,
+ addressable_url: true, allow_blank: true
+
+ validates :spam_check_endpoint_url,
+ presence: true,
+ if: :spam_check_endpoint_enabled
+
validates :external_auth_client_key,
presence: true,
if: -> (setting) { setting.external_auth_client_cert.present? }
@@ -427,6 +450,12 @@ class ApplicationSetting < ApplicationRecord
recaptcha_enabled || login_recaptcha_protection_enabled
end
+ repository_storages_weighted_attributes.each do |attribute|
+ define_method :"#{attribute}=" do |value|
+ super(value.to_i)
+ end
+ end
+
private
def parsed_grafana_url
diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb
index 221e4d5e0c6..d24136cc04a 100644
--- a/app/models/application_setting_implementation.rb
+++ b/app/models/application_setting_implementation.rb
@@ -86,6 +86,7 @@ module ApplicationSettingImplementation
local_markdown_version: 0,
max_artifacts_size: Settings.artifacts['max_size'],
max_attachment_size: Settings.gitlab['max_attachment_size'],
+ max_import_size: 50,
mirror_available: true,
outbound_local_requests_whitelist: [],
password_authentication_enabled_for_git: true,
@@ -104,6 +105,7 @@ module ApplicationSettingImplementation
login_recaptcha_protection_enabled: false,
repository_checks_enabled: true,
repository_storages: ['default'],
+ repository_storages_weighted: { default: 100 },
require_two_factor_authentication: false,
restricted_visibility_levels: Settings.gitlab['restricted_visibility_levels'],
session_expire_delay: Settings.gitlab['session_expire_delay'],
@@ -115,6 +117,8 @@ module ApplicationSettingImplementation
sourcegraph_enabled: false,
sourcegraph_url: nil,
sourcegraph_public_only: true,
+ spam_check_endpoint_enabled: false,
+ spam_check_endpoint_url: nil,
minimum_password_length: DEFAULT_MINIMUM_PASSWORD_LENGTH,
namespace_storage_size_limit: 0,
terminal_max_session_time: 0,
@@ -151,7 +155,7 @@ module ApplicationSettingImplementation
snowplow_app_id: nil,
snowplow_iglu_registry_url: nil,
custom_http_clone_url_root: nil,
- productivity_analytics_start_date: Time.now,
+ productivity_analytics_start_date: Time.current,
snippet_size_limit: 50.megabytes
}
end
@@ -260,6 +264,10 @@ module ApplicationSettingImplementation
Array(read_attribute(:repository_storages))
end
+ def repository_storages_weighted
+ read_attribute(:repository_storages_weighted)
+ end
+
def commit_email_hostname
super.presence || self.class.default_commit_email_hostname
end
@@ -289,10 +297,21 @@ module ApplicationSettingImplementation
performance_bar_allowed_group_id.present?
end
- # Choose one of the available repository storage options. Currently all have
- # equal weighting.
+ def normalized_repository_storage_weights
+ strong_memoize(:normalized_repository_storage_weights) do
+ weights_total = repository_storages_weighted.values.reduce(:+)
+
+ repository_storages_weighted.transform_values do |w|
+ next w if weights_total == 0
+
+ w.to_f / weights_total
+ end
+ end
+ end
+
+ # Choose one of the available repository storage options based on a normalized weighted probability.
def pick_repository_storage
- repository_storages.sample
+ normalized_repository_storage_weights.max_by { |_, weight| rand**(1.0 / weight) }.first
end
def runners_registration_token
@@ -420,6 +439,12 @@ module ApplicationSettingImplementation
invalid.empty?
end
+ def check_repository_storages_weighted
+ invalid = repository_storages_weighted.keys - Gitlab.config.repositories.storages.keys
+ errors.add(:repository_storages_weighted, "can't include: %{invalid_storages}" % { invalid_storages: invalid.join(", ") }) unless
+ invalid.empty?
+ end
+
def terms_exist
return unless enforce_terms?
diff --git a/app/models/audit_event.rb b/app/models/audit_event.rb
index 7ff0076c3e3..3bbd2e43a51 100644
--- a/app/models/audit_event.rb
+++ b/app/models/audit_event.rb
@@ -2,6 +2,9 @@
class AuditEvent < ApplicationRecord
include CreatedAtFilterable
+ include IgnorableColumns
+
+ ignore_column :updated_at, remove_with: '13.3', remove_after: '2020-08-22'
serialize :details, Hash # rubocop:disable Cop/ActiveRecordSerialize
diff --git a/app/models/badge.rb b/app/models/badge.rb
index 3400d6d407d..4339d419b48 100644
--- a/app/models/badge.rb
+++ b/app/models/badge.rb
@@ -18,7 +18,7 @@ class Badge < ApplicationRecord
# This regex will build the new PLACEHOLDER_REGEX with the new information
PLACEHOLDERS_REGEX = /(#{PLACEHOLDERS.keys.join('|')})/.freeze
- default_scope { order_created_at_asc }
+ default_scope { order_created_at_asc } # rubocop:disable Cop/DefaultScope
scope :order_created_at_asc, -> { reorder(created_at: :asc) }
diff --git a/app/models/blob.rb b/app/models/blob.rb
index c8df6c7732a..874bf58530e 100644
--- a/app/models/blob.rb
+++ b/app/models/blob.rb
@@ -50,6 +50,7 @@ class Blob < SimpleDelegator
BlobViewer::License,
BlobViewer::Contributing,
BlobViewer::Changelog,
+ BlobViewer::MetricsDashboardYml,
BlobViewer::CargoToml,
BlobViewer::Cartfile,
@@ -57,6 +58,7 @@ class Blob < SimpleDelegator
BlobViewer::Gemfile,
BlobViewer::Gemspec,
BlobViewer::GodepsJson,
+ BlobViewer::GoMod,
BlobViewer::PackageJson,
BlobViewer::Podfile,
BlobViewer::Podspec,
diff --git a/app/models/blob_viewer/go_mod.rb b/app/models/blob_viewer/go_mod.rb
new file mode 100644
index 00000000000..ae57e2c0526
--- /dev/null
+++ b/app/models/blob_viewer/go_mod.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+module BlobViewer
+ class GoMod < DependencyManager
+ include ServerSide
+ include Gitlab::Utils::StrongMemoize
+
+ MODULE_REGEX = /
+ \A (?# beginning of file)
+ module\s+ (?# module directive)
+ (?<name>.*?) (?# module name)
+ \s*(?:\/\/.*)? (?# comment)
+ (?:\n|\z) (?# newline or end of file)
+ /x.freeze
+
+ self.file_types = %i(go_mod go_sum)
+
+ def manager_name
+ 'Go Modules'
+ end
+
+ def manager_url
+ 'https://golang.org/ref/mod'
+ end
+
+ def package_type
+ 'go'
+ end
+
+ def package_name
+ strong_memoize(:package_name) do
+ next if blob.name != 'go.mod'
+ next unless match = MODULE_REGEX.match(blob.data)
+
+ match[:name]
+ end
+ end
+
+ def package_url
+ Gitlab::Golang.package_url(package_name)
+ end
+ end
+end
diff --git a/app/models/blob_viewer/metrics_dashboard_yml.rb b/app/models/blob_viewer/metrics_dashboard_yml.rb
new file mode 100644
index 00000000000..c05fb5d88d6
--- /dev/null
+++ b/app/models/blob_viewer/metrics_dashboard_yml.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+module BlobViewer
+ class MetricsDashboardYml < Base
+ include ServerSide
+ include Gitlab::Utils::StrongMemoize
+ include Auxiliary
+
+ self.partial_name = 'metrics_dashboard_yml'
+ self.loading_partial_name = 'metrics_dashboard_yml_loading'
+ self.file_types = %i(metrics_dashboard)
+ self.binary = false
+
+ def valid?
+ errors.blank?
+ end
+
+ def errors
+ strong_memoize(:errors) do
+ prepare!
+ parse_blob_data
+ end
+ end
+
+ private
+
+ def parse_blob_data
+ yaml = ::Gitlab::Config::Loader::Yaml.new(blob.data).load_raw!
+
+ ::PerformanceMonitoring::PrometheusDashboard.from_json(yaml)
+ nil
+ rescue Gitlab::Config::Loader::FormatError => error
+ wrap_yml_syntax_error(error)
+ rescue ActiveModel::ValidationError => invalid
+ invalid.model.errors
+ end
+
+ def wrap_yml_syntax_error(error)
+ ::PerformanceMonitoring::PrometheusDashboard.new.errors.tap do |errors|
+ errors.add(:'YAML syntax', error.message)
+ end
+ end
+ end
+end
diff --git a/app/models/board_group_recent_visit.rb b/app/models/board_group_recent_visit.rb
index 2f1cd830791..979f0e1ab92 100644
--- a/app/models/board_group_recent_visit.rb
+++ b/app/models/board_group_recent_visit.rb
@@ -14,7 +14,7 @@ class BoardGroupRecentVisit < ApplicationRecord
def self.visited!(user, board)
visit = find_or_create_by(user: user, group: board.group, board: board)
- visit.touch if visit.updated_at < Time.now
+ visit.touch if visit.updated_at < Time.current
rescue ActiveRecord::RecordNotUnique
retry
end
diff --git a/app/models/board_project_recent_visit.rb b/app/models/board_project_recent_visit.rb
index 236d88e909c..509c8f97b83 100644
--- a/app/models/board_project_recent_visit.rb
+++ b/app/models/board_project_recent_visit.rb
@@ -14,7 +14,7 @@ class BoardProjectRecentVisit < ApplicationRecord
def self.visited!(user, board)
visit = find_or_create_by(user: user, project: board.project, board: board)
- visit.touch if visit.updated_at < Time.now
+ visit.touch if visit.updated_at < Time.current
rescue ActiveRecord::RecordNotUnique
retry
end
diff --git a/app/models/chat_team.rb b/app/models/chat_team.rb
index 28aab279545..6e39d7e2204 100644
--- a/app/models/chat_team.rb
+++ b/app/models/chat_team.rb
@@ -12,6 +12,6 @@ class ChatTeam < ApplicationRecord
# Either the group is not found, or the user doesn't have the proper
# access on the mattermost instance. In the first case, we're done either way
# in the latter case, we can't recover by retrying, so we just log what happened
- Rails.logger.error("Mattermost team deletion failed: #{e}") # rubocop:disable Gitlab/RailsLogger
+ Gitlab::AppLogger.error("Mattermost team deletion failed: #{e}")
end
end
diff --git a/app/models/ci/bridge.rb b/app/models/ci/bridge.rb
index 1e92a47ab49..58c26e8c806 100644
--- a/app/models/ci/bridge.rb
+++ b/app/models/ci/bridge.rb
@@ -16,6 +16,9 @@ module Ci
has_many :sourced_pipelines, class_name: "::Ci::Sources::Pipeline",
foreign_key: :source_job_id
+ has_one :sourced_pipeline, class_name: "::Ci::Sources::Pipeline", foreign_key: :source_job_id
+ has_one :downstream_pipeline, through: :sourced_pipeline, source: :pipeline
+
validates :ref, presence: true
# rubocop:disable Cop/ActiveRecordSerialize
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 7f64ea7dd97..b5e68b55f72 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -26,7 +26,8 @@ module Ci
RUNNER_FEATURES = {
upload_multiple_artifacts: -> (build) { build.publishes_artifacts_reports? },
refspecs: -> (build) { build.merge_request_ref? },
- artifacts_exclude: -> (build) { build.supports_artifacts_exclude? }
+ artifacts_exclude: -> (build) { build.supports_artifacts_exclude? },
+ release_steps: -> (build) { build.release_steps? }
}.freeze
DEFAULT_RETRIES = {
@@ -39,6 +40,7 @@ module Ci
has_one :resource, class_name: 'Ci::Resource', inverse_of: :build
has_many :trace_sections, class_name: 'Ci::BuildTraceSection'
has_many :trace_chunks, class_name: 'Ci::BuildTraceChunk', foreign_key: :build_id
+ has_many :report_results, class_name: 'Ci::BuildReportResult', inverse_of: :build
has_many :job_artifacts, class_name: 'Ci::JobArtifact', foreign_key: :job_id, dependent: :destroy, inverse_of: :job # rubocop:disable Cop/ActiveRecordDependent
has_many :job_variables, class_name: 'Ci::JobVariable', foreign_key: :job_id
@@ -55,6 +57,7 @@ module Ci
delegate :url, to: :runner_session, prefix: true, allow_nil: true
delegate :terminal_specification, to: :runner_session, allow_nil: true
+ delegate :service_specification, to: :runner_session, allow_nil: true
delegate :gitlab_deploy_token, to: :project
delegate :trigger_short_token, to: :trigger_request, allow_nil: true
@@ -137,8 +140,8 @@ module Ci
.includes(:metadata, :job_artifacts_metadata)
end
- scope :with_artifacts_not_expired, ->() { with_downloadable_artifacts.where('artifacts_expire_at IS NULL OR artifacts_expire_at > ?', Time.now) }
- scope :with_expired_artifacts, ->() { with_downloadable_artifacts.where('artifacts_expire_at < ?', Time.now) }
+ scope :with_artifacts_not_expired, ->() { with_downloadable_artifacts.where('artifacts_expire_at IS NULL OR artifacts_expire_at > ?', Time.current) }
+ scope :with_expired_artifacts, ->() { with_downloadable_artifacts.where('artifacts_expire_at < ?', Time.current) }
scope :last_month, ->() { where('created_at > ?', Date.today - 1.month) }
scope :manual_actions, ->() { where(when: :manual, status: COMPLETED_STATUSES + %i[manual]) }
scope :scheduled_actions, ->() { where(when: :delayed, status: COMPLETED_STATUSES + %i[scheduled]) }
@@ -259,7 +262,7 @@ module Ci
end
before_transition any => :waiting_for_resource do |build|
- build.waiting_for_resource_at = Time.now
+ build.waiting_for_resource_at = Time.current
end
before_transition on: :enqueue_waiting_for_resource do |build|
@@ -352,7 +355,7 @@ module Ci
begin
Ci::Build.retry(build, build.user)
rescue Gitlab::Access::AccessDeniedError => ex
- Rails.logger.error "Unable to auto-retry job #{build.id}: #{ex}" # rubocop:disable Gitlab/RailsLogger
+ Gitlab::AppLogger.error "Unable to auto-retry job #{build.id}: #{ex}"
end
end
end
@@ -576,7 +579,7 @@ module Ci
def environment_changed_page_variables
Gitlab::Ci::Variables::Collection.new.tap do |variables|
- break variables unless environment_status
+ break variables unless environment_status && Feature.enabled?(:modifed_path_ci_variables, project)
variables.append(key: 'CI_MERGE_REQUEST_CHANGED_PAGE_PATHS', value: environment_status.changed_paths.join(','))
variables.append(key: 'CI_MERGE_REQUEST_CHANGED_PAGE_URLS', value: environment_status.changed_urls.join(','))
@@ -686,6 +689,10 @@ module Ci
job_artifacts.any?
end
+ def has_test_reports?
+ job_artifacts.test_reports.exists?
+ end
+
def has_old_trace?
old_trace.present?
end
@@ -713,7 +720,7 @@ module Ci
end
def needs_touch?
- Time.now - updated_at > 15.minutes.to_i
+ Time.current - updated_at > 15.minutes.to_i
end
def valid_token?(token)
@@ -756,13 +763,13 @@ module Ci
# and use that for `ExpireBuildInstanceArtifactsWorker`?
def erase_erasable_artifacts!
- job_artifacts.erasable.destroy_all # rubocop: disable DestroyAll
+ job_artifacts.erasable.destroy_all # rubocop: disable Cop/DestroyAll
end
def erase(opts = {})
return false unless erasable?
- job_artifacts.destroy_all # rubocop: disable DestroyAll
+ job_artifacts.destroy_all # rubocop: disable Cop/DestroyAll
erase_trace!
update_erased!(opts[:erased_by])
end
@@ -776,11 +783,11 @@ module Ci
end
def artifacts_expired?
- artifacts_expire_at && artifacts_expire_at < Time.now
+ artifacts_expire_at && artifacts_expire_at < Time.current
end
def artifacts_expire_in
- artifacts_expire_at - Time.now if artifacts_expire_at
+ artifacts_expire_at - Time.current if artifacts_expire_at
end
def artifacts_expire_in=(value)
@@ -809,6 +816,7 @@ module Ci
def steps
[Gitlab::Ci::Build::Step.from_commands(self),
+ Gitlab::Ci::Build::Step.from_release(self),
Gitlab::Ci::Build::Step.from_after_script(self)].compact
end
@@ -872,6 +880,16 @@ module Ci
options&.dig(:artifacts, :reports)&.any?
end
+ def supports_artifacts_exclude?
+ options&.dig(:artifacts, :exclude)&.any? &&
+ Gitlab::Ci::Features.artifacts_exclude_enabled?
+ end
+
+ def release_steps?
+ options.dig(:release)&.any? &&
+ Gitlab::Ci::Features.release_generation_enabled?
+ end
+
def hide_secrets(trace)
return unless trace
@@ -945,11 +963,6 @@ module Ci
failure_reason: :data_integrity_failure)
end
- def supports_artifacts_exclude?
- options&.dig(:artifacts, :exclude)&.any? &&
- Gitlab::Ci::Features.artifacts_exclude_enabled?
- end
-
def degradation_threshold
var = yaml_variables.find { |v| v[:key] == DEGRADATION_THRESHOLD_VARIABLE_NAME }
var[:value]&.to_i if var
@@ -993,7 +1006,7 @@ module Ci
end
def update_erased!(user = nil)
- self.update(erased_by: user, erased_at: Time.now, artifacts_expire_at: nil)
+ self.update(erased_by: user, erased_at: Time.current, artifacts_expire_at: nil)
end
def unscoped_project
@@ -1026,7 +1039,7 @@ module Ci
end
def has_expiring_artifacts?
- artifacts_expire_at.present? && artifacts_expire_at > Time.now
+ artifacts_expire_at.present? && artifacts_expire_at > Time.current
end
def job_jwt_variables
diff --git a/app/models/ci/build_dependencies.rb b/app/models/ci/build_dependencies.rb
index d3ff870e36a..2fcd1708cf4 100644
--- a/app/models/ci/build_dependencies.rb
+++ b/app/models/ci/build_dependencies.rb
@@ -45,7 +45,7 @@ module Ci
end
def valid_local?
- return true if Feature.enabled?('ci_disable_validates_dependencies')
+ return true if Feature.enabled?(:ci_disable_validates_dependencies)
local.all?(&:valid_dependency?)
end
diff --git a/app/models/ci/build_report_result.rb b/app/models/ci/build_report_result.rb
new file mode 100644
index 00000000000..530233ad5c0
--- /dev/null
+++ b/app/models/ci/build_report_result.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+module Ci
+ class BuildReportResult < ApplicationRecord
+ extend Gitlab::Ci::Model
+
+ self.primary_key = :build_id
+
+ belongs_to :build, class_name: "Ci::Build", inverse_of: :report_results
+ belongs_to :project, class_name: "Project", inverse_of: :build_report_results
+
+ validates :build, :project, presence: true
+ validates :data, json_schema: { filename: "build_report_result_data" }
+
+ store_accessor :data, :tests
+
+ def tests_name
+ tests.dig("name")
+ end
+
+ def tests_duration
+ tests.dig("duration")
+ end
+
+ def tests_success
+ tests.dig("success").to_i
+ end
+
+ def tests_failed
+ tests.dig("failed").to_i
+ end
+
+ def tests_errored
+ tests.dig("errored").to_i
+ end
+
+ def tests_skipped
+ tests.dig("skipped").to_i
+ end
+
+ def tests_total
+ [tests_success, tests_failed, tests_errored, tests_skipped].sum
+ end
+ end
+end
diff --git a/app/models/ci/build_runner_session.rb b/app/models/ci/build_runner_session.rb
index b46bbe69c7c..bc7f17f046c 100644
--- a/app/models/ci/build_runner_session.rb
+++ b/app/models/ci/build_runner_session.rb
@@ -7,6 +7,8 @@ module Ci
extend Gitlab::Ci::Model
TERMINAL_SUBPROTOCOL = 'terminal.gitlab.com'
+ DEFAULT_SERVICE_NAME = 'build'.freeze
+ DEFAULT_PORT_NAME = 'default_port'.freeze
self.table_name = 'ci_builds_runner_session'
@@ -23,6 +25,17 @@ module Ci
channel_specification(wss_url, TERMINAL_SUBPROTOCOL)
end
+ def service_specification(service: nil, path: nil, port: nil, subprotocols: nil)
+ return {} unless url.present?
+
+ port = port.presence || DEFAULT_PORT_NAME
+ service = service.presence || DEFAULT_SERVICE_NAME
+ url = "#{self.url}/proxy/#{service}/#{port}/#{path}"
+ subprotocols = subprotocols.presence || ::Ci::BuildRunnerSession::TERMINAL_SUBPROTOCOL
+
+ channel_specification(url, subprotocols)
+ end
+
private
def channel_specification(url, subprotocol)
@@ -37,5 +50,3 @@ module Ci
end
end
end
-
-Ci::BuildRunnerSession.prepend_if_ee('EE::Ci::BuildRunnerSession')
diff --git a/app/models/ci/daily_build_group_report_result.rb b/app/models/ci/daily_build_group_report_result.rb
index 3506b27e974..d6617b8c2eb 100644
--- a/app/models/ci/daily_build_group_report_result.rb
+++ b/app/models/ci/daily_build_group_report_result.rb
@@ -9,6 +9,8 @@ module Ci
belongs_to :last_pipeline, class_name: 'Ci::Pipeline', foreign_key: :last_pipeline_id
belongs_to :project
+ validates :data, json_schema: { filename: "daily_build_group_report_result_data" }
+
def self.upsert_reports(data)
upsert_all(data, unique_by: :index_daily_build_group_report_results_unique_columns) if data.any?
end
diff --git a/app/models/ci/freeze_period.rb b/app/models/ci/freeze_period.rb
index bf03b92259a..d215372bb45 100644
--- a/app/models/ci/freeze_period.rb
+++ b/app/models/ci/freeze_period.rb
@@ -5,7 +5,7 @@ module Ci
include StripAttribute
self.table_name = 'ci_freeze_periods'
- default_scope { order(created_at: :asc) }
+ default_scope { order(created_at: :asc) } # rubocop:disable Cop/DefaultScope
belongs_to :project, inverse_of: :freeze_periods
diff --git a/app/models/ci/group.rb b/app/models/ci/group.rb
index 4b2081f2977..779c6c0396f 100644
--- a/app/models/ci/group.rb
+++ b/app/models/ci/group.rb
@@ -24,7 +24,7 @@ module Ci
def status
strong_memoize(:status) do
- if Feature.enabled?(:ci_composite_status, project, default_enabled: false)
+ if ::Gitlab::Ci::Features.composite_status?(project)
Gitlab::Ci::Status::Composite
.new(@jobs)
.status
diff --git a/app/models/ci/instance_variable.rb b/app/models/ci/instance_variable.rb
index c674f76d229..8245729a884 100644
--- a/app/models/ci/instance_variable.rb
+++ b/app/models/ci/instance_variable.rb
@@ -3,8 +3,13 @@
module Ci
class InstanceVariable < ApplicationRecord
extend Gitlab::Ci::Model
+ extend Gitlab::ProcessMemoryCache::Helper
include Ci::NewHasVariable
include Ci::Maskable
+ include Limitable
+
+ self.limit_name = 'ci_instance_level_variables'
+ self.limit_scope = Limitable::GLOBAL_SCOPE
alias_attribute :secret_value, :value
@@ -12,8 +17,14 @@ module Ci
message: "(%{value}) has already been taken"
}
+ validates :encrypted_value, length: {
+ maximum: 1024,
+ too_long: 'The encrypted value of the provided variable exceeds %{count} bytes. Variables over 700 characters risk exceeding the limit.'
+ }
+
scope :unprotected, -> { where(protected: false) }
- after_commit { self.class.touch_redis_cache_timestamp }
+
+ after_commit { self.class.invalidate_memory_cache(:ci_instance_variable_data) }
class << self
def all_cached
@@ -24,10 +35,6 @@ module Ci
cached_data[:unprotected]
end
- def touch_redis_cache_timestamp(time = Time.current.to_f)
- shared_backend.write(:ci_instance_variable_changed_at, time)
- end
-
private
def cached_data
@@ -37,39 +44,13 @@ module Ci
{ all: all_records, unprotected: all_records.reject(&:protected?) }
end
end
+ end
- def fetch_memory_cache(key, &payload)
- cache = process_backend.read(key)
-
- if cache && !stale_cache?(cache)
- cache[:data]
- else
- store_cache(key, &payload)
- end
- end
-
- def stale_cache?(cache_info)
- shared_timestamp = shared_backend.read(:ci_instance_variable_changed_at)
- return true unless shared_timestamp
-
- shared_timestamp.to_f > cache_info[:cached_at].to_f
- end
-
- def store_cache(key)
- data = yield
- time = Time.current.to_f
-
- process_backend.write(key, data: data, cached_at: time)
- touch_redis_cache_timestamp(time)
- data
- end
-
- def shared_backend
- Rails.cache
- end
+ private
- def process_backend
- Gitlab::ProcessMemoryCache.cache_backend
+ def validate_plan_limit_not_exceeded
+ if Gitlab::Ci::Features.instance_level_variables_limit_enabled?
+ super
end
end
end
diff --git a/app/models/ci/job_artifact.rb b/app/models/ci/job_artifact.rb
index d931428dccd..8aba9356949 100644
--- a/app/models/ci/job_artifact.rb
+++ b/app/models/ci/job_artifact.rb
@@ -5,6 +5,7 @@ module Ci
include AfterCommitQueue
include ObjectStorage::BackgroundMove
include UpdateProjectStatistics
+ include UsageStatistics
include Sortable
extend Gitlab::Ci::Model
@@ -26,6 +27,7 @@ module Ci
accessibility: 'gl-accessibility.json',
codequality: 'gl-code-quality-report.json',
sast: 'gl-sast-report.json',
+ secret_detection: 'gl-secret-detection-report.json',
dependency_scanning: 'gl-dependency-scanning-report.json',
container_scanning: 'gl-container-scanning-report.json',
dast: 'gl-dast-report.json',
@@ -37,7 +39,8 @@ module Ci
dotenv: '.env',
cobertura: 'cobertura-coverage.xml',
terraform: 'tfplan.json',
- cluster_applications: 'gl-cluster-applications.json'
+ cluster_applications: 'gl-cluster-applications.json',
+ requirements: 'requirements.json'
}.freeze
INTERNAL_TYPES = {
@@ -62,13 +65,15 @@ module Ci
accessibility: :raw,
codequality: :raw,
sast: :raw,
+ secret_detection: :raw,
dependency_scanning: :raw,
container_scanning: :raw,
dast: :raw,
license_management: :raw,
license_scanning: :raw,
performance: :raw,
- terraform: :raw
+ terraform: :raw,
+ requirements: :raw
}.freeze
DOWNLOADABLE_TYPES = %w[
@@ -87,6 +92,8 @@ module Ci
metrics
performance
sast
+ secret_detection
+ requirements
].freeze
TYPE_AND_FORMAT_PAIRS = INTERNAL_TYPES.merge(REPORT_TYPES).freeze
@@ -109,6 +116,7 @@ module Ci
after_save :update_file_store, if: :saved_change_to_file?
+ scope :not_expired, -> { where('expire_at IS NULL OR expire_at > ?', Time.current) }
scope :with_files_stored_locally, -> { where(file_store: [nil, ::JobArtifactUploader::Store::LOCAL]) }
scope :with_files_stored_remotely, -> { where(file_store: ::JobArtifactUploader::Store::REMOTE) }
scope :for_sha, ->(sha, project_id) { joins(job: :pipeline).where(ci_pipelines: { sha: sha, project_id: project_id }) }
@@ -147,7 +155,8 @@ module Ci
where(file_type: types)
end
- scope :expired, -> (limit) { where('expire_at < ?', Time.now).limit(limit) }
+ scope :expired, -> (limit) { where('expire_at < ?', Time.current).limit(limit) }
+ scope :downloadable, -> { where(file_type: DOWNLOADABLE_TYPES) }
scope :locked, -> { where(locked: true) }
scope :unlocked, -> { where(locked: [false, nil]) }
@@ -176,7 +185,9 @@ module Ci
cobertura: 17,
terraform: 18, # Transformed json
accessibility: 19,
- cluster_applications: 20
+ cluster_applications: 20,
+ secret_detection: 21, ## EE-specific
+ requirements: 22 ## EE-specific
}
enum file_format: {
@@ -242,8 +253,16 @@ module Ci
super || self.file_location.nil?
end
+ def expired?
+ expire_at.present? && expire_at < Time.current
+ end
+
+ def expiring?
+ expire_at.present? && expire_at > Time.current
+ end
+
def expire_in
- expire_at - Time.now if expire_at
+ expire_at - Time.current if expire_at
end
def expire_in=(value)
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 5db1635f64d..497e1a4d74a 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -31,6 +31,7 @@ module Ci
belongs_to :pipeline_schedule, class_name: 'Ci::PipelineSchedule'
belongs_to :merge_request, class_name: 'MergeRequest'
belongs_to :external_pull_request
+ belongs_to :ci_ref, class_name: 'Ci::Ref', foreign_key: :ci_ref_id, inverse_of: :pipelines
has_internal_id :iid, scope: :project, presence: false, track_if: -> { !importing? }, ensure_if: -> { !importing? }, init: ->(s) do
s&.project&.all_pipelines&.maximum(:iid) || s&.project&.all_pipelines&.count
@@ -40,11 +41,15 @@ module Ci
has_many :statuses, class_name: 'CommitStatus', foreign_key: :commit_id, inverse_of: :pipeline
has_many :latest_statuses_ordered_by_stage, -> { latest.order(:stage_idx, :stage) }, class_name: 'CommitStatus', foreign_key: :commit_id, inverse_of: :pipeline
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 :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'
has_many :deployments, through: :builds
has_many :environments, -> { distinct }, through: :deployments
+ has_many :latest_builds, -> { latest }, foreign_key: :commit_id, inverse_of: :pipeline, class_name: 'Ci::Build'
+ has_many :downloadable_artifacts, -> { not_expired.downloadable }, through: :latest_builds, source: :job_artifacts
# Merge requests for which the current pipeline is running against
# the merge request's latest commit.
@@ -56,7 +61,6 @@ module Ci
has_many :cancelable_statuses, -> { cancelable }, foreign_key: :commit_id, class_name: 'CommitStatus'
has_many :manual_actions, -> { latest.manual_actions.includes(:project) }, foreign_key: :commit_id, class_name: 'Ci::Build'
has_many :scheduled_actions, -> { latest.scheduled_actions.includes(:project) }, foreign_key: :commit_id, class_name: 'Ci::Build'
- has_many :artifacts, -> { latest.with_artifacts_not_expired.includes(:project) }, foreign_key: :commit_id, class_name: 'Ci::Build'
has_many :auto_canceled_pipelines, class_name: 'Ci::Pipeline', foreign_key: 'auto_canceled_by_id'
has_many :auto_canceled_jobs, class_name: 'CommitStatus', foreign_key: 'auto_canceled_by_id'
@@ -64,13 +68,6 @@ module Ci
has_one :source_pipeline, class_name: 'Ci::Sources::Pipeline', inverse_of: :pipeline
- has_one :ref_status, ->(pipeline) {
- # We use .read_attribute to save 1 extra unneeded query to load the :project.
- unscope(:where)
- .where(project_id: pipeline.read_attribute(:project_id), ref: pipeline.ref, tag: pipeline.tag)
- # Sadly :inverse_of is not supported (yet) by Rails for composite PKs.
- }, class_name: 'Ci::Ref', inverse_of: :pipelines
-
has_one :chat_data, class_name: 'Ci::PipelineChatData'
has_many :triggered_pipelines, through: :sourced_pipelines, source: :pipeline
@@ -163,11 +160,11 @@ module Ci
# Create a separate worker for each new operation
before_transition [:created, :waiting_for_resource, :preparing, :pending] => :running do |pipeline|
- pipeline.started_at = Time.now
+ pipeline.started_at = Time.current
end
before_transition any => [:success, :failed, :canceled] do |pipeline|
- pipeline.finished_at = Time.now
+ pipeline.finished_at = Time.current
pipeline.update_duration
end
@@ -235,12 +232,10 @@ module Ci
end
after_transition any => [:success, :failed] do |pipeline|
+ ref_status = pipeline.ci_ref&.update_status_by!(pipeline)
+
pipeline.run_after_commit do
- if Feature.enabled?(:ci_pipeline_fixed_notifications)
- PipelineUpdateCiRefStatusWorker.perform_async(pipeline.id)
- else
- PipelineNotificationWorker.perform_async(pipeline.id)
- end
+ PipelineNotificationWorker.perform_async(pipeline.id, ref_status: ref_status)
end
end
@@ -260,6 +255,7 @@ module Ci
scope :for_sha_or_source_sha, -> (sha) { for_sha(sha).or(for_source_sha(sha)) }
scope :for_ref, -> (ref) { where(ref: ref) }
scope :for_id, -> (id) { where(id: id) }
+ scope :for_iid, -> (iid) { where(iid: iid) }
scope :created_after, -> (time) { where('ci_pipelines.created_at > ?', time) }
scope :with_reports, -> (reports_scope) do
@@ -397,11 +393,11 @@ module Ci
end
def ordered_stages
- if Feature.enabled?(:ci_atomic_processing, project, default_enabled: false)
+ if ::Gitlab::Ci::Features.atomic_processing?(project)
# The `Ci::Stage` contains all up-to date data
# as atomic processing updates all data in-bulk
stages
- elsif Feature.enabled?(:ci_pipeline_persisted_stages, default_enabled: true) && complete?
+ elsif complete?
# The `Ci::Stage` contains up-to date data only for `completed` pipelines
# this is due to asynchronous processing of pipeline, and stages possibly
# not updated inline with processing of pipeline
@@ -445,7 +441,7 @@ module Ci
end
def legacy_stages
- if Feature.enabled?(:ci_composite_status, project, default_enabled: false)
+ if ::Gitlab::Ci::Features.composite_status?(project)
legacy_stages_using_composite_status
else
legacy_stages_using_sql
@@ -798,13 +794,17 @@ module Ci
@latest_builds_with_artifacts ||= builds.latest.with_artifacts_not_expired.to_a
end
+ def latest_report_builds(reports_scope = ::Ci::JobArtifact.with_reports)
+ builds.latest.with_reports(reports_scope)
+ end
+
def has_reports?(reports_scope)
- complete? && builds.latest.with_reports(reports_scope).exists?
+ complete? && latest_report_builds(reports_scope).exists?
end
def test_reports
Gitlab::Ci::Reports::TestReports.new.tap do |test_reports|
- builds.latest.with_reports(Ci::JobArtifact.test_reports).preload(:project).find_each do |build|
+ latest_report_builds(Ci::JobArtifact.test_reports).preload(:project).find_each do |build|
build.collect_test_reports!(test_reports)
end
end
@@ -826,7 +826,7 @@ module Ci
def coverage_reports
Gitlab::Ci::Reports::CoverageReports.new.tap do |coverage_reports|
- builds.latest.with_reports(Ci::JobArtifact.coverage_reports).each do |build|
+ latest_report_builds(Ci::JobArtifact.coverage_reports).each do |build|
build.collect_coverage_reports!(coverage_reports)
end
end
@@ -834,7 +834,7 @@ module Ci
def terraform_reports
::Gitlab::Ci::Reports::TerraformReports.new.tap do |terraform_reports|
- builds.latest.with_reports(::Ci::JobArtifact.terraform_reports).each do |build|
+ latest_report_builds(::Ci::JobArtifact.terraform_reports).each do |build|
build.collect_terraform_reports!(terraform_reports)
end
end
@@ -969,6 +969,12 @@ module Ci
processables.populate_scheduling_type!
end
+ def ensure_ci_ref!
+ return unless Gitlab::Ci::Features.pipeline_fixed_notifications?
+
+ self.ci_ref = Ci::Ref.ensure_for(self)
+ end
+
private
def pipeline_data
diff --git a/app/models/ci/pipeline_enums.rb b/app/models/ci/pipeline_enums.rb
index 7e203cb67c4..2ccd8445aa8 100644
--- a/app/models/ci/pipeline_enums.rb
+++ b/app/models/ci/pipeline_enums.rb
@@ -27,9 +27,11 @@ module Ci
# https://gitlab.com/gitlab-org/gitlab/issues/195991
pipeline: 7,
chat: 8,
+ webide: 9,
merge_request_event: 10,
external_pull_request_event: 11,
- parent_pipeline: 12
+ parent_pipeline: 12,
+ ondemand_scan: 13
}
end
@@ -40,6 +42,7 @@ module Ci
unknown_source: nil,
repository_source: 1,
auto_devops_source: 2,
+ webide_source: 3,
remote_source: 4,
external_project_source: 5,
bridge_source: 6
diff --git a/app/models/ci/processable.rb b/app/models/ci/processable.rb
index cc00500662d..ac5785d9c91 100644
--- a/app/models/ci/processable.rb
+++ b/app/models/ci/processable.rb
@@ -4,12 +4,8 @@ module Ci
class Processable < ::CommitStatus
include Gitlab::Utils::StrongMemoize
- has_many :needs, class_name: 'Ci::BuildNeed', foreign_key: :build_id, inverse_of: :build
-
accepts_nested_attributes_for :needs
- enum scheduling_type: { stage: 0, dag: 1 }, _prefix: true
-
scope :preload_needs, -> { preload(:needs) }
scope :with_needs, -> (names = nil) do
diff --git a/app/models/ci/ref.rb b/app/models/ci/ref.rb
index a0782bc0444..be6062b6e6e 100644
--- a/app/models/ci/ref.rb
+++ b/app/models/ci/ref.rb
@@ -3,21 +3,62 @@
module Ci
class Ref < ApplicationRecord
extend Gitlab::Ci::Model
+ include Gitlab::OptimisticLocking
- STATUSES = %w[success failed fixed].freeze
-
- belongs_to :project
- belongs_to :last_updated_by_pipeline, foreign_key: :last_updated_by_pipeline_id, class_name: 'Ci::Pipeline'
- # ActiveRecord doesn't support composite FKs for this reason we have to do the 'unscope(:where)'
- # hack.
- has_many :pipelines, ->(ref) {
- # We use .read_attribute to save 1 extra unneeded query to load the :project.
- unscope(:where)
- .where(ref: ref.ref, project_id: ref.read_attribute(:project_id), tag: ref.tag)
- # Sadly :inverse_of is not supported (yet) by Rails for composite PKs.
- }, inverse_of: :ref_status
-
- validates :status, inclusion: { in: STATUSES }
- validates :last_updated_by_pipeline, presence: true
+ FAILING_STATUSES = %w[failed broken still_failing].freeze
+
+ belongs_to :project, inverse_of: :ci_refs
+ has_many :pipelines, class_name: 'Ci::Pipeline', foreign_key: :ci_ref_id, inverse_of: :ci_ref
+
+ state_machine :status, initial: :unknown do
+ event :succeed do
+ transition unknown: :success
+ transition fixed: :success
+ transition %i[failed broken still_failing] => :fixed
+ end
+
+ event :do_fail do
+ transition unknown: :failed
+ transition %i[failed broken] => :still_failing
+ transition %i[success fixed] => :broken
+ end
+
+ state :unknown, value: 0
+ state :success, value: 1
+ state :failed, value: 2
+ state :fixed, value: 3
+ state :broken, value: 4
+ state :still_failing, value: 5
+ end
+
+ class << self
+ def ensure_for(pipeline)
+ safe_find_or_create_by(project_id: pipeline.project_id,
+ ref_path: pipeline.source_ref_path)
+ end
+
+ def failing_state?(status_name)
+ FAILING_STATUSES.include?(status_name)
+ end
+ end
+
+ def last_finished_pipeline_id
+ Ci::Pipeline.where(ci_ref_id: self.id).finished.order(id: :desc).select(:id).take&.id
+ end
+
+ def update_status_by!(pipeline)
+ return unless Gitlab::Ci::Features.pipeline_fixed_notifications?
+
+ retry_lock(self) do
+ next unless last_finished_pipeline_id == pipeline.id
+
+ case pipeline.status
+ when 'success' then self.succeed
+ when 'failed' then self.do_fail
+ end
+
+ self.status_name
+ end
+ end
end
end
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb
index d4e9217ff9f..8fc273556f0 100644
--- a/app/models/ci/runner.rb
+++ b/app/models/ci/runner.rb
@@ -23,10 +23,17 @@ module Ci
project_type: 3
}
- ONLINE_CONTACT_TIMEOUT = 1.hour
+ # This `ONLINE_CONTACT_TIMEOUT` needs to be larger than
+ # `RUNNER_QUEUE_EXPIRY_TIME+UPDATE_CONTACT_COLUMN_EVERY`
+ #
+ ONLINE_CONTACT_TIMEOUT = 2.hours
+
+ # The `RUNNER_QUEUE_EXPIRY_TIME` indicates the longest interval that
+ # Runner request needs to be refreshed by Rails instead of being handled
+ # by Workhorse
RUNNER_QUEUE_EXPIRY_TIME = 1.hour
- # This needs to be less than `ONLINE_CONTACT_TIMEOUT`
+ # The `UPDATE_CONTACT_COLUMN_EVERY` defines how often the Runner DB entry can be updated
UPDATE_CONTACT_COLUMN_EVERY = (40.minutes..55.minutes).freeze
AVAILABLE_TYPES_LEGACY = %w[specific shared].freeze
@@ -81,6 +88,17 @@ module Ci
joins(:runner_namespaces).where(ci_runner_namespaces: { namespace_id: groups })
}
+ scope :belonging_to_group_or_project, -> (group_id, project_id) {
+ groups = ::Group.where(id: group_id)
+
+ group_runners = joins(:runner_namespaces).where(ci_runner_namespaces: { namespace_id: groups })
+ project_runners = joins(:runner_projects).where(ci_runner_projects: { project_id: project_id })
+
+ union_sql = ::Gitlab::SQL::Union.new([group_runners, project_runners]).to_sql
+
+ from("(#{union_sql}) #{table_name}")
+ }
+
scope :belonging_to_parent_group_of_project, -> (project_id) {
project_groups = ::Group.joins(:projects).where(projects: { id: project_id })
hierarchy_groups = Gitlab::ObjectHierarchy.new(project_groups).base_and_ancestors
@@ -145,14 +163,14 @@ module Ci
# Searches for runners matching the given query.
#
- # This method uses ILIKE on PostgreSQL and LIKE on MySQL.
+ # This method uses ILIKE on PostgreSQL.
#
# This method performs a *partial* match on tokens, thus a query for "a"
# will match any runner where the token contains the letter "a". As a result
# you should *not* use this method for non-admin purposes as otherwise users
# might be able to query a list of all runners.
#
- # query - The search query as a String
+ # query - The search query as a String.
#
# Returns an ActiveRecord::Relation.
def self.search(query)
@@ -271,9 +289,9 @@ module Ci
ensure_runner_queue_value == value if value.present?
end
- def update_cached_info(values)
+ def heartbeat(values)
values = values&.slice(:version, :revision, :platform, :architecture, :ip_address) || {}
- values[:contacted_at] = Time.now
+ values[:contacted_at] = Time.current
cache_attributes(values)
@@ -309,7 +327,7 @@ module Ci
real_contacted_at = read_attribute(:contacted_at)
real_contacted_at.nil? ||
- (Time.now - real_contacted_at) >= contacted_at_max_age
+ (Time.current - real_contacted_at) >= contacted_at_max_age
end
def tag_constraints
diff --git a/app/models/clusters/applications/cert_manager.rb b/app/models/clusters/applications/cert_manager.rb
index 1efa44c39c5..53c90fa56d5 100644
--- a/app/models/clusters/applications/cert_manager.rb
+++ b/app/models/clusters/applications/cert_manager.rb
@@ -38,7 +38,8 @@ module Clusters
chart: chart,
files: files.merge(cluster_issuer_file),
preinstall: pre_install_script,
- postinstall: post_install_script
+ postinstall: post_install_script,
+ local_tiller_enabled: cluster.local_tiller_enabled?
)
end
@@ -47,7 +48,8 @@ module Clusters
name: 'certmanager',
rbac: cluster.platform_kubernetes_rbac?,
files: files,
- postdelete: post_delete_script
+ postdelete: post_delete_script,
+ local_tiller_enabled: cluster.local_tiller_enabled?
)
end
diff --git a/app/models/clusters/applications/crossplane.rb b/app/models/clusters/applications/crossplane.rb
index 420e56c1742..2e5a8210b3c 100644
--- a/app/models/clusters/applications/crossplane.rb
+++ b/app/models/clusters/applications/crossplane.rb
@@ -35,7 +35,8 @@ module Clusters
version: VERSION,
rbac: cluster.platform_kubernetes_rbac?,
chart: chart,
- files: files
+ files: files,
+ local_tiller_enabled: cluster.local_tiller_enabled?
)
end
diff --git a/app/models/clusters/applications/elastic_stack.rb b/app/models/clusters/applications/elastic_stack.rb
index 0d029aabc3b..58ac0c1f188 100644
--- a/app/models/clusters/applications/elastic_stack.rb
+++ b/app/models/clusters/applications/elastic_stack.rb
@@ -34,7 +34,8 @@ module Clusters
repository: repository,
files: files,
preinstall: migrate_to_3_script,
- postinstall: post_install_script
+ postinstall: post_install_script,
+ local_tiller_enabled: cluster.local_tiller_enabled?
)
end
@@ -43,7 +44,8 @@ module Clusters
name: 'elastic-stack',
rbac: cluster.platform_kubernetes_rbac?,
files: files,
- postdelete: post_delete_script
+ postdelete: post_delete_script,
+ local_tiller_enabled: cluster.local_tiller_enabled?
)
end
@@ -51,7 +53,7 @@ module Clusters
super.merge('wait-for-elasticsearch.sh': File.read("#{Rails.root}/vendor/elastic_stack/wait-for-elasticsearch.sh"))
end
- def elasticsearch_client
+ def elasticsearch_client(timeout: nil)
strong_memoize(:elasticsearch_client) do
next unless kube_client
@@ -63,6 +65,7 @@ module Clusters
# ensure TLS certs are properly verified
faraday.ssl[:verify] = kube_client.ssl_options[:verify_ssl]
faraday.ssl[:cert_store] = kube_client.ssl_options[:cert_store]
+ faraday.options.timeout = timeout unless timeout.nil?
end
rescue Kubeclient::HttpError => error
@@ -118,7 +121,8 @@ module Clusters
Gitlab::Kubernetes::Helm::DeleteCommand.new(
name: 'elastic-stack',
rbac: cluster.platform_kubernetes_rbac?,
- files: files
+ files: files,
+ local_tiller_enabled: cluster.local_tiller_enabled?
).delete_command,
Gitlab::Kubernetes::KubectlCmd.delete("pvc", "--selector", "release=elastic-stack", "--namespace", Gitlab::Kubernetes::Helm::NAMESPACE)
]
diff --git a/app/models/clusters/applications/fluentd.rb b/app/models/clusters/applications/fluentd.rb
index 3fd6e870edc..1bcd39618f6 100644
--- a/app/models/clusters/applications/fluentd.rb
+++ b/app/models/clusters/applications/fluentd.rb
@@ -32,7 +32,8 @@ module Clusters
version: VERSION,
rbac: cluster.platform_kubernetes_rbac?,
chart: chart,
- files: files
+ files: files,
+ local_tiller_enabled: cluster.local_tiller_enabled?
)
end
diff --git a/app/models/clusters/applications/helm.rb b/app/models/clusters/applications/helm.rb
index 4a1bcac4bb7..226a9c26db0 100644
--- a/app/models/clusters/applications/helm.rb
+++ b/app/models/clusters/applications/helm.rb
@@ -52,7 +52,8 @@ module Clusters
Gitlab::Kubernetes::Helm::InitCommand.new(
name: name,
files: files,
- rbac: cluster.platform_kubernetes_rbac?
+ rbac: cluster.platform_kubernetes_rbac?,
+ local_tiller_enabled: cluster.local_tiller_enabled?
)
end
@@ -60,7 +61,8 @@ module Clusters
Gitlab::Kubernetes::Helm::ResetCommand.new(
name: name,
files: files,
- rbac: cluster.platform_kubernetes_rbac?
+ rbac: cluster.platform_kubernetes_rbac?,
+ local_tiller_enabled: cluster.local_tiller_enabled?
)
end
diff --git a/app/models/clusters/applications/ingress.rb b/app/models/clusters/applications/ingress.rb
index dd354198910..a44450ec7a9 100644
--- a/app/models/clusters/applications/ingress.rb
+++ b/app/models/clusters/applications/ingress.rb
@@ -63,7 +63,8 @@ module Clusters
version: VERSION,
rbac: cluster.platform_kubernetes_rbac?,
chart: chart,
- files: files
+ files: files,
+ local_tiller_enabled: cluster.local_tiller_enabled?
)
end
diff --git a/app/models/clusters/applications/jupyter.rb b/app/models/clusters/applications/jupyter.rb
index 056ea355de6..b737f0f962f 100644
--- a/app/models/clusters/applications/jupyter.rb
+++ b/app/models/clusters/applications/jupyter.rb
@@ -45,7 +45,8 @@ module Clusters
rbac: cluster.platform_kubernetes_rbac?,
chart: chart,
files: files,
- repository: repository
+ repository: repository,
+ local_tiller_enabled: cluster.local_tiller_enabled?
)
end
diff --git a/app/models/clusters/applications/knative.rb b/app/models/clusters/applications/knative.rb
index 3047da12dd9..b55fc3c45fc 100644
--- a/app/models/clusters/applications/knative.rb
+++ b/app/models/clusters/applications/knative.rb
@@ -77,7 +77,8 @@ module Clusters
chart: chart,
files: files,
repository: REPOSITORY,
- postinstall: install_knative_metrics
+ postinstall: install_knative_metrics,
+ local_tiller_enabled: cluster.local_tiller_enabled?
)
end
@@ -99,7 +100,8 @@ module Clusters
rbac: cluster.platform_kubernetes_rbac?,
files: files,
predelete: delete_knative_services_and_metrics,
- postdelete: delete_knative_istio_leftovers
+ postdelete: delete_knative_istio_leftovers,
+ local_tiller_enabled: cluster.local_tiller_enabled?
)
end
diff --git a/app/models/clusters/applications/prometheus.rb b/app/models/clusters/applications/prometheus.rb
index 3183318690c..24bb1df6d22 100644
--- a/app/models/clusters/applications/prometheus.rb
+++ b/app/models/clusters/applications/prometheus.rb
@@ -37,7 +37,7 @@ module Clusters
end
after_transition any => :updating do |application|
- application.update(last_update_started_at: Time.now)
+ application.update(last_update_started_at: Time.current)
end
end
@@ -66,7 +66,8 @@ module Clusters
rbac: cluster.platform_kubernetes_rbac?,
chart: chart,
files: files,
- postinstall: install_knative_metrics
+ postinstall: install_knative_metrics,
+ local_tiller_enabled: cluster.local_tiller_enabled?
)
end
@@ -76,7 +77,8 @@ module Clusters
version: version,
rbac: cluster.platform_kubernetes_rbac?,
chart: chart,
- files: files_with_replaced_values(values)
+ files: files_with_replaced_values(values),
+ local_tiller_enabled: cluster.local_tiller_enabled?
)
end
@@ -85,7 +87,8 @@ module Clusters
name: name,
rbac: cluster.platform_kubernetes_rbac?,
files: files,
- predelete: delete_knative_istio_metrics
+ predelete: delete_knative_istio_metrics,
+ local_tiller_enabled: cluster.local_tiller_enabled?
)
end
diff --git a/app/models/clusters/applications/runner.rb b/app/models/clusters/applications/runner.rb
index a861126908f..6d3b6c4ed8f 100644
--- a/app/models/clusters/applications/runner.rb
+++ b/app/models/clusters/applications/runner.rb
@@ -3,7 +3,7 @@
module Clusters
module Applications
class Runner < ApplicationRecord
- VERSION = '0.16.1'
+ VERSION = '0.17.1'
self.table_name = 'clusters_applications_runners'
@@ -36,7 +36,8 @@ module Clusters
rbac: cluster.platform_kubernetes_rbac?,
chart: chart,
files: files,
- repository: repository
+ repository: repository,
+ local_tiller_enabled: cluster.local_tiller_enabled?
)
end
diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb
index 83f558af1a1..bde7a2104ba 100644
--- a/app/models/clusters/cluster.rb
+++ b/app/models/clusters/cluster.rb
@@ -36,6 +36,8 @@ module Clusters
has_one :cluster_project, -> { order(id: :desc) }, class_name: 'Clusters::Project'
has_many :deployment_clusters
has_many :deployments, inverse_of: :cluster
+ has_many :successful_deployments, -> { success }, class_name: 'Deployment'
+ has_many :environments, -> { distinct }, through: :deployments
has_many :cluster_groups, class_name: 'Clusters::Group'
has_many :groups, through: :cluster_groups, class_name: '::Group'
@@ -125,12 +127,23 @@ module Clusters
scope :gcp_installed, -> { gcp_provided.joins(:provider_gcp).merge(Clusters::Providers::Gcp.with_status(:created)) }
scope :aws_installed, -> { aws_provided.joins(:provider_aws).merge(Clusters::Providers::Aws.with_status(:created)) }
+ scope :with_enabled_modsecurity, -> { joins(:application_ingress).merge(::Clusters::Applications::Ingress.modsecurity_enabled) }
+ scope :with_available_elasticstack, -> { joins(:application_elastic_stack).merge(::Clusters::Applications::ElasticStack.available) }
+ scope :distinct_with_deployed_environments, -> { joins(:environments).merge(::Deployment.success).distinct }
+ scope :preload_elasticstack, -> { preload(:application_elastic_stack) }
+ scope :preload_environments, -> { preload(:environments) }
+
scope :managed, -> { where(managed: true) }
scope :with_persisted_applications, -> { eager_load(*APPLICATIONS_ASSOCIATIONS) }
scope :default_environment, -> { where(environment_scope: DEFAULT_ENVIRONMENT) }
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_application_prometheus, -> { includes(:application_prometheus).joins(:application_prometheus) }
+ scope :with_project_alert_service_data, -> (project_ids) do
+ conditions = { projects: { alerts_service: [:data] } }
+ includes(conditions).joins(conditions).where(projects: { id: project_ids })
+ end
def self.ancestor_clusters_for_clusterable(clusterable, hierarchy_order: :asc)
return [] if clusterable.is_a?(Instance)
@@ -321,6 +334,10 @@ module Clusters
end
end
+ def local_tiller_enabled?
+ Feature.enabled?(:managed_apps_local_tiller, clusterable, default_enabled: false)
+ end
+
private
def unique_management_project_environment_scope
@@ -368,7 +385,10 @@ module Clusters
def retrieve_nodes
result = ::Gitlab::Kubernetes::KubeClient.graceful_request(id) { kubeclient.get_nodes }
- cluster_nodes = result[:response].to_a
+
+ return unless result[:response]
+
+ cluster_nodes = result[:response]
result = ::Gitlab::Kubernetes::KubeClient.graceful_request(id) { kubeclient.metrics_client.get_nodes }
nodes_metrics = result[:response].to_a
diff --git a/app/models/clusters/concerns/application_core.rb b/app/models/clusters/concerns/application_core.rb
index 297d00aa281..c1f63758906 100644
--- a/app/models/clusters/concerns/application_core.rb
+++ b/app/models/clusters/concerns/application_core.rb
@@ -15,7 +15,7 @@ module Clusters
def set_initial_status
return unless not_installable?
- self.status = status_states[:installable] if cluster&.application_helm_available? || ::Gitlab::Kubernetes::Helm.local_tiller_enabled?
+ self.status = status_states[:installable] if cluster&.application_helm_available? || cluster&.local_tiller_enabled?
end
def can_uninstall?
diff --git a/app/models/clusters/concerns/application_data.rb b/app/models/clusters/concerns/application_data.rb
index 77c606553d2..ade27e69642 100644
--- a/app/models/clusters/concerns/application_data.rb
+++ b/app/models/clusters/concerns/application_data.rb
@@ -7,7 +7,8 @@ module Clusters
Gitlab::Kubernetes::Helm::DeleteCommand.new(
name: name,
rbac: cluster.platform_kubernetes_rbac?,
- files: files
+ files: files,
+ local_tiller_enabled: cluster.local_tiller_enabled?
)
end
@@ -32,7 +33,7 @@ module Clusters
private
def use_tiller_ssl?
- return false if ::Gitlab::Kubernetes::Helm.local_tiller_enabled?
+ return false if cluster.local_tiller_enabled?
cluster.application_helm.has_ssl?
end
diff --git a/app/models/clusters/concerns/application_status.rb b/app/models/clusters/concerns/application_status.rb
index 0b915126f8a..86d74ed7b1c 100644
--- a/app/models/clusters/concerns/application_status.rb
+++ b/app/models/clusters/concerns/application_status.rb
@@ -97,13 +97,21 @@ module Clusters
application.status_reason = status_reason if status_reason
end
- before_transition any => [:installed, :updated] do |application, _|
- # When installing any application we are also performing an update
- # of tiller (see Gitlab::Kubernetes::Helm::ClientCommand) so
- # therefore we need to reflect that in the database.
-
- unless ::Gitlab::Kubernetes::Helm.local_tiller_enabled?
- application.cluster.application_helm.update!(version: Gitlab::Kubernetes::Helm::HELM_VERSION)
+ before_transition any => [:installed, :updated] do |application, transition|
+ unless application.cluster.local_tiller_enabled? || application.is_a?(Clusters::Applications::Helm)
+ if transition.event == :make_externally_installed
+ # If an application is externally installed
+ # We assume the helm application is externally installed too
+ helm = application.cluster.application_helm || application.cluster.build_application_helm
+
+ helm.make_externally_installed!
+ else
+ # When installing any application we are also performing an update
+ # of tiller (see Gitlab::Kubernetes::Helm::ClientCommand) so
+ # therefore we need to reflect that in the database.
+
+ application.cluster.application_helm.update!(version: Gitlab::Kubernetes::Helm::HELM_VERSION)
+ end
end
end
diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb
index 7e99f128dad..475f82f23ca 100644
--- a/app/models/commit_status.rb
+++ b/app/models/commit_status.rb
@@ -14,6 +14,10 @@ class CommitStatus < ApplicationRecord
belongs_to :pipeline, class_name: 'Ci::Pipeline', foreign_key: :commit_id
belongs_to :auto_canceled_by, class_name: 'Ci::Pipeline'
+ has_many :needs, class_name: 'Ci::BuildNeed', foreign_key: :build_id, inverse_of: :build
+
+ enum scheduling_type: { stage: 0, dag: 1 }, _prefix: true
+
delegate :commit, to: :pipeline
delegate :sha, :short_sha, :before_sha, to: :pipeline
@@ -90,7 +94,12 @@ class CommitStatus < ApplicationRecord
end
before_save if: :status_changed?, unless: :importing? do
- if Feature.disabled?(:ci_atomic_processing, project)
+ # we mark `processed` as always changed:
+ # another process might change its value and our object
+ # will not be refreshed to pick the change
+ self.processed_will_change!
+
+ if !::Gitlab::Ci::Features.atomic_processing?(project)
self.processed = nil
elsif latest?
self.processed = false # force refresh of all dependent ones
@@ -132,15 +141,15 @@ class CommitStatus < ApplicationRecord
end
before_transition [:created, :waiting_for_resource, :preparing, :skipped, :manual, :scheduled] => :pending do |commit_status|
- commit_status.queued_at = Time.now
+ commit_status.queued_at = Time.current
end
before_transition [:created, :preparing, :pending] => :running do |commit_status|
- commit_status.started_at = Time.now
+ commit_status.started_at = Time.current
end
before_transition any => [:success, :failed, :canceled] do |commit_status|
- commit_status.finished_at = Time.now
+ commit_status.finished_at = Time.current
end
before_transition any => :failed do |commit_status, transition|
@@ -185,8 +194,10 @@ class CommitStatus < ApplicationRecord
end
def self.update_as_processed!
- # Marks items as processed, and increases `lock_version` (Optimisitc Locking)
- update_all('processed=TRUE, lock_version=COALESCE(lock_version,0)+1')
+ # Marks items as processed
+ # we do not increase `lock_version`, as we are the one
+ # holding given lock_version (Optimisitc Locking)
+ update_all(processed: true)
end
def self.locking_enabled?
@@ -276,7 +287,7 @@ class CommitStatus < ApplicationRecord
end
def schedule_stage_and_pipeline_update
- if Feature.enabled?(:ci_atomic_processing, project)
+ if ::Gitlab::Ci::Features.atomic_processing?(project)
# Atomic Processing requires only single Worker
PipelineProcessWorker.perform_async(pipeline_id, [id])
else
diff --git a/app/models/concerns/cacheable_attributes.rb b/app/models/concerns/cacheable_attributes.rb
index d459af23a2f..de176ffde5c 100644
--- a/app/models/concerns/cacheable_attributes.rb
+++ b/app/models/concerns/cacheable_attributes.rb
@@ -55,7 +55,7 @@ module CacheableAttributes
current_without_cache.tap { |current_record| current_record&.cache! }
rescue => e
if Rails.env.production?
- Rails.logger.warn("Cached record for #{name} couldn't be loaded, falling back to uncached record: #{e}") # rubocop:disable Gitlab/RailsLogger
+ Gitlab::AppLogger.warn("Cached record for #{name} couldn't be loaded, falling back to uncached record: #{e}")
else
raise e
end
diff --git a/app/models/concerns/ci/contextable.rb b/app/models/concerns/ci/contextable.rb
index ccd90ea5900..7ea5382a4fa 100644
--- a/app/models/concerns/ci/contextable.rb
+++ b/app/models/concerns/ci/contextable.rb
@@ -18,7 +18,7 @@ module Ci
variables.concat(deployment_variables(environment: environment))
variables.concat(yaml_variables)
variables.concat(user_variables)
- variables.concat(dependency_variables) if Feature.enabled?(:ci_dependency_variables, project)
+ variables.concat(dependency_variables)
variables.concat(secret_instance_variables)
variables.concat(secret_group_variables)
variables.concat(secret_project_variables(environment: environment))
diff --git a/app/models/concerns/each_batch.rb b/app/models/concerns/each_batch.rb
index 6314b46a7e3..af5f4e30d06 100644
--- a/app/models/concerns/each_batch.rb
+++ b/app/models/concerns/each_batch.rb
@@ -17,7 +17,7 @@ module EachBatch
# Example:
#
# User.each_batch do |relation|
- # relation.update_all(updated_at: Time.now)
+ # relation.update_all(updated_at: Time.current)
# end
#
# The supplied block is also passed an optional batch index:
diff --git a/app/models/concerns/featurable.rb b/app/models/concerns/featurable.rb
new file mode 100644
index 00000000000..60aa46ce04c
--- /dev/null
+++ b/app/models/concerns/featurable.rb
@@ -0,0 +1,99 @@
+# frozen_string_literal: true
+
+# == Featurable concern
+#
+# This concern adds features (tools) functionality to Project and Group
+# To enable features you need to call `set_available_features`
+#
+# Example:
+#
+# class ProjectFeature
+# include Featurable
+# set_available_features %i(wiki merge_request)
+
+module Featurable
+ extend ActiveSupport::Concern
+
+ # Can be enabled only for members, everyone or disabled
+ # Access control is made only for non private containers.
+ #
+ # Permission levels:
+ #
+ # Disabled: not enabled for anyone
+ # Private: enabled only for team members
+ # Enabled: enabled for everyone able to access the project
+ # Public: enabled for everyone (only allowed for pages)
+ DISABLED = 0
+ PRIVATE = 10
+ ENABLED = 20
+ PUBLIC = 30
+
+ STRING_OPTIONS = HashWithIndifferentAccess.new({
+ 'disabled' => DISABLED,
+ 'private' => PRIVATE,
+ 'enabled' => ENABLED,
+ 'public' => PUBLIC
+ }).freeze
+
+ class_methods do
+ def set_available_features(available_features = [])
+ @available_features = available_features
+
+ class_eval do
+ available_features.each do |feature|
+ define_method("#{feature}_enabled?") do
+ public_send("#{feature}_access_level") > DISABLED # rubocop:disable GitlabSecurity/PublicSend
+ end
+ end
+ end
+ end
+
+ def available_features
+ @available_features
+ end
+
+ def access_level_attribute(feature)
+ feature = ensure_feature!(feature)
+
+ "#{feature}_access_level".to_sym
+ end
+
+ def quoted_access_level_column(feature)
+ attribute = connection.quote_column_name(access_level_attribute(feature))
+ table = connection.quote_table_name(table_name)
+
+ "#{table}.#{attribute}"
+ end
+
+ def access_level_from_str(level)
+ STRING_OPTIONS.fetch(level)
+ end
+
+ def str_from_access_level(level)
+ STRING_OPTIONS.key(level)
+ end
+
+ def ensure_feature!(feature)
+ feature = feature.model_name.plural if feature.respond_to?(:model_name)
+ feature = feature.to_sym
+ raise ArgumentError, "invalid feature: #{feature}" unless available_features.include?(feature)
+
+ feature
+ end
+ end
+
+ def access_level(feature)
+ public_send(self.class.access_level_attribute(feature)) # rubocop:disable GitlabSecurity/PublicSend
+ end
+
+ def feature_available?(feature, user)
+ # This feature might not be behind a feature flag at all, so default to true
+ return false unless ::Feature.enabled?(feature, user, default_enabled: true)
+
+ get_permission(user, feature)
+ end
+
+ def string_access_level(feature)
+ self.class.str_from_access_level(access_level(feature))
+ end
+end
diff --git a/app/models/concerns/has_status.rb b/app/models/concerns/has_status.rb
index b80f8c2bbb2..c885dea862f 100644
--- a/app/models/concerns/has_status.rb
+++ b/app/models/concerns/has_status.rb
@@ -66,7 +66,7 @@ module HasStatus
# 1. By plucking all related objects,
# 2. Or executes expensive SQL query
def slow_composite_status(project:)
- if Feature.enabled?(:ci_composite_status, project, default_enabled: false)
+ if ::Gitlab::Ci::Features.composite_status?(project)
Gitlab::Ci::Status::Composite
.new(all, with_allow_failure: columns_hash.key?('allow_failure'))
.status
@@ -160,7 +160,7 @@ module HasStatus
if started_at && finished_at
finished_at - started_at
elsif started_at
- Time.now - started_at
+ Time.current - started_at
end
end
end
diff --git a/app/models/concerns/import_state/sidekiq_job_tracker.rb b/app/models/concerns/import_state/sidekiq_job_tracker.rb
index 55f171d158d..b7d0ed0f51b 100644
--- a/app/models/concerns/import_state/sidekiq_job_tracker.rb
+++ b/app/models/concerns/import_state/sidekiq_job_tracker.rb
@@ -5,14 +5,17 @@ module ImportState
extend ActiveSupport::Concern
included do
+ scope :with_jid, -> { where.not(jid: nil) }
+ scope :without_jid, -> { where(jid: nil) }
+
# Refreshes the expiration time of the associated import job ID.
#
# This method can be used by asynchronous importers to refresh the status,
- # preventing the StuckImportJobsWorker from marking the import as failed.
+ # preventing the Gitlab::Import::StuckProjectImportJobsWorker from marking the import as failed.
def refresh_jid_expiration
return unless jid
- Gitlab::SidekiqStatus.set(jid, StuckImportJobsWorker::IMPORT_JOBS_EXPIRATION)
+ Gitlab::SidekiqStatus.set(jid, Gitlab::Import::StuckImportJob::IMPORT_JOBS_EXPIRATION)
end
def self.jid_by(project_id:, status:)
diff --git a/app/models/concerns/integration.rb b/app/models/concerns/integration.rb
new file mode 100644
index 00000000000..644a0ba1b5e
--- /dev/null
+++ b/app/models/concerns/integration.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Integration
+ extend ActiveSupport::Concern
+
+ class_methods do
+ def with_custom_integration_for(integration, page = nil, per = nil)
+ custom_integration_project_ids = Service
+ .where(type: integration.type)
+ .where(inherit_from_id: nil)
+ .distinct # Required until https://gitlab.com/gitlab-org/gitlab/-/issues/207385
+ .page(page)
+ .per(per)
+ .pluck(:project_id)
+
+ Project.where(id: custom_integration_project_ids)
+ end
+ end
+end
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index a1b14dca4ac..220af8ab7c7 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -39,15 +39,6 @@ module Issuable
locked: 4
}.with_indifferent_access.freeze
- # This object is used to gather issuable meta data for displaying
- # upvotes, downvotes, notes and closing merge requests count for issues and merge requests
- # lists avoiding n+1 queries and improving performance.
- IssuableMeta = Struct.new(:upvotes, :downvotes, :user_notes_count, :mrs_count) do
- def merge_requests_count(user = nil)
- mrs_count
- end
- end
-
included do
cache_markdown_field :title, pipeline: :single_line
cache_markdown_field :description, issuable_state_filter_enabled: true
@@ -139,7 +130,6 @@ module Issuable
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 :any_label, -> { joins(:label_links).distinct }
scope :join_project, -> { joins(:project) }
scope :inc_notes_with_associations, -> { includes(notes: [:project, :author, :award_emoji]) }
scope :references_project, -> { references(:project) }
@@ -185,6 +175,10 @@ module Issuable
assignees.count > 1
end
+ def supports_weight?
+ false
+ end
+
private
def description_max_length_for_new_records_is_valid
@@ -201,7 +195,7 @@ module Issuable
class_methods do
# Searches for records with a matching title.
#
- # This method uses ILIKE on PostgreSQL and LIKE on MySQL.
+ # This method uses ILIKE on PostgreSQL.
#
# query - The search query as a String
#
@@ -225,7 +219,7 @@ module Issuable
# Searches for records with a matching title or description.
#
- # This method uses ILIKE on PostgreSQL and LIKE on MySQL.
+ # This method uses ILIKE on PostgreSQL.
#
# query - The search query as a String
# matched_columns - Modify the scope of the query. 'title', 'description' or joining them with a comma.
@@ -316,6 +310,14 @@ module Issuable
end
end
+ def any_label(sort = nil)
+ if sort
+ joins(:label_links).group(*grouping_columns(sort))
+ else
+ joins(:label_links).distinct
+ end
+ end
+
# Includes table keys in group by clause when sorting
# preventing errors in postgres
#
@@ -401,6 +403,10 @@ module Issuable
participants(user).include?(user)
end
+ def can_assign_epic?(user)
+ false
+ end
+
def to_hook_data(user, old_associations: {})
changes = previous_changes
diff --git a/app/models/concerns/limitable.rb b/app/models/concerns/limitable.rb
index f320f54bb82..3cb0bd85936 100644
--- a/app/models/concerns/limitable.rb
+++ b/app/models/concerns/limitable.rb
@@ -2,6 +2,7 @@
module Limitable
extend ActiveSupport::Concern
+ GLOBAL_SCOPE = :limitable_global_scope
included do
class_attribute :limit_scope
@@ -14,14 +15,34 @@ module Limitable
private
def validate_plan_limit_not_exceeded
+ if GLOBAL_SCOPE == limit_scope
+ validate_global_plan_limit_not_exceeded
+ else
+ validate_scoped_plan_limit_not_exceeded
+ end
+ end
+
+ def validate_scoped_plan_limit_not_exceeded
scope_relation = self.public_send(limit_scope) # rubocop:disable GitlabSecurity/PublicSend
return unless scope_relation
relation = self.class.where(limit_scope => scope_relation)
+ limits = scope_relation.actual_limits
- if scope_relation.actual_limits.exceeded?(limit_name, relation)
- errors.add(:base, _("Maximum number of %{name} (%{count}) exceeded") %
- { name: limit_name.humanize(capitalize: false), count: scope_relation.actual_limits.public_send(limit_name) }) # rubocop:disable GitlabSecurity/PublicSend
- end
+ check_plan_limit_not_exceeded(limits, relation)
+ end
+
+ def validate_global_plan_limit_not_exceeded
+ relation = self.class.all
+ limits = Plan.default.actual_limits
+
+ check_plan_limit_not_exceeded(limits, relation)
+ end
+
+ def check_plan_limit_not_exceeded(limits, relation)
+ return unless limits.exceeded?(limit_name, relation)
+
+ errors.add(:base, _("Maximum number of %{name} (%{count}) exceeded") %
+ { name: limit_name.humanize(capitalize: false), count: limits.public_send(limit_name) }) # rubocop:disable GitlabSecurity/PublicSend
end
end
diff --git a/app/models/concerns/mentionable.rb b/app/models/concerns/mentionable.rb
index d157404f7bc..7b4485376d4 100644
--- a/app/models/concerns/mentionable.rb
+++ b/app/models/concerns/mentionable.rb
@@ -259,8 +259,8 @@ module Mentionable
# for the test period.
# During the test period the flag should be enabled at the group level.
def store_mentioned_users_to_db_enabled?
- return Feature.enabled?(:store_mentioned_users_to_db, self.project&.group) if self.respond_to?(:project)
- return Feature.enabled?(:store_mentioned_users_to_db, self.group) if self.respond_to?(:group)
+ return Feature.enabled?(:store_mentioned_users_to_db, self.project&.group, default_enabled: true) if self.respond_to?(:project)
+ return Feature.enabled?(:store_mentioned_users_to_db, self.group, default_enabled: true) if self.respond_to?(:group)
end
end
diff --git a/app/models/concerns/milestoneish.rb b/app/models/concerns/milestoneish.rb
index fa5a79cc12b..5f24564dc56 100644
--- a/app/models/concerns/milestoneish.rb
+++ b/app/models/concerns/milestoneish.rb
@@ -97,26 +97,6 @@ module Milestoneish
due_date && due_date.past?
end
- def group_milestone?
- false
- end
-
- def project_milestone?
- false
- end
-
- def legacy_group_milestone?
- false
- end
-
- def dashboard_milestone?
- false
- end
-
- def global_milestone?
- false
- end
-
def total_time_spent
@total_time_spent ||= issues.joins(:timelogs).sum(:time_spent) + merge_requests.joins(:timelogs).sum(:time_spent)
end
diff --git a/app/models/concerns/noteable.rb b/app/models/concerns/noteable.rb
index 933a0b167e2..183b902dd37 100644
--- a/app/models/concerns/noteable.rb
+++ b/app/models/concerns/noteable.rb
@@ -24,7 +24,7 @@ module Noteable
# The timestamp of the note (e.g. the :created_at or :updated_at attribute if provided via
# API call)
def system_note_timestamp
- @system_note_timestamp || Time.now # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ @system_note_timestamp || Time.current # rubocop:disable Gitlab/ModuleWithInstanceVariables
end
attr_writer :system_note_timestamp
diff --git a/app/models/concerns/prometheus_adapter.rb b/app/models/concerns/prometheus_adapter.rb
index 761a151a474..adb6a59e11c 100644
--- a/app/models/concerns/prometheus_adapter.rb
+++ b/app/models/concerns/prometheus_adapter.rb
@@ -44,7 +44,7 @@ module PrometheusAdapter
{
success: true,
data: data,
- last_update: Time.now.utc
+ last_update: Time.current.utc
}
rescue Gitlab::PrometheusClient::Error => err
{ success: false, result: err.message }
diff --git a/app/models/concerns/relative_positioning.rb b/app/models/concerns/relative_positioning.rb
index 1653ecdb305..1d89a4497d9 100644
--- a/app/models/concerns/relative_positioning.rb
+++ b/app/models/concerns/relative_positioning.rb
@@ -50,7 +50,7 @@ module RelativePositioning
# This method takes two integer values (positions) and
# calculates the position between them. The range is huge as
# the maximum integer value is 2147483647. We are incrementing position by IDEAL_DISTANCE * 2 every time
- # when we have enough space. If distance is less then IDEAL_DISTANCE we are calculating an average number
+ # when we have enough space. If distance is less than IDEAL_DISTANCE, we are calculating an average number.
def position_between(pos_before, pos_after)
pos_before ||= MIN_POSITION
pos_after ||= MAX_POSITION
diff --git a/app/models/concerns/resolvable_discussion.rb b/app/models/concerns/resolvable_discussion.rb
index 5d78eea7fca..5174ae05d15 100644
--- a/app/models/concerns/resolvable_discussion.rb
+++ b/app/models/concerns/resolvable_discussion.rb
@@ -23,7 +23,10 @@ module ResolvableDiscussion
:last_note
)
- delegate :potentially_resolvable?, to: :first_note
+ delegate :potentially_resolvable?,
+ :noteable_id,
+ :noteable_type,
+ to: :first_note
delegate :resolved_at,
:resolved_by,
@@ -79,7 +82,7 @@ module ResolvableDiscussion
return false unless current_user
return false unless resolvable?
- current_user == self.noteable.author ||
+ current_user == self.noteable.try(:author) ||
current_user.can?(:resolve_note, self.project)
end
diff --git a/app/models/concerns/resolvable_note.rb b/app/models/concerns/resolvable_note.rb
index 2d2d5fb7168..4e8a1bb643e 100644
--- a/app/models/concerns/resolvable_note.rb
+++ b/app/models/concerns/resolvable_note.rb
@@ -23,7 +23,7 @@ module ResolvableNote
class_methods do
# This method must be kept in sync with `#resolve!`
def resolve!(current_user)
- unresolved.update_all(resolved_at: Time.now, resolved_by_id: current_user.id)
+ unresolved.update_all(resolved_at: Time.current, resolved_by_id: current_user.id)
end
# This method must be kept in sync with `#unresolve!`
@@ -57,7 +57,7 @@ module ResolvableNote
return false unless resolvable?
return false if resolved?
- self.resolved_at = Time.now
+ self.resolved_at = Time.current
self.resolved_by = current_user
self.resolved_by_push = resolved_by_push
diff --git a/app/models/concerns/storage/legacy_namespace.rb b/app/models/concerns/storage/legacy_namespace.rb
index da4f2a79895..250889fdf8b 100644
--- a/app/models/concerns/storage/legacy_namespace.rb
+++ b/app/models/concerns/storage/legacy_namespace.rb
@@ -67,7 +67,7 @@ module Storage
unless gitlab_shell.mv_namespace(repository_storage, full_path_before_last_save, full_path)
- Rails.logger.error "Exception moving path #{repository_storage} from #{full_path_before_last_save} to #{full_path}" # rubocop:disable Gitlab/RailsLogger
+ Gitlab::AppLogger.error("Exception moving path #{repository_storage} from #{full_path_before_last_save} to #{full_path}")
# if we cannot move namespace directory we should rollback
# db changes in order to prevent out of sync between db and fs
diff --git a/app/models/concerns/timebox.rb b/app/models/concerns/timebox.rb
index d29e6a01c56..8927e42dd97 100644
--- a/app/models/concerns/timebox.rb
+++ b/app/models/concerns/timebox.rb
@@ -7,7 +7,9 @@ module Timebox
include CacheMarkdownField
include Gitlab::SQL::Pattern
include IidRoutes
+ include Referable
include StripAttribute
+ include FromUnion
TimeboxStruct = Struct.new(:title, :name, :id) do
# Ensure these models match the interface required for exporting
@@ -64,7 +66,11 @@ module Timebox
groups = groups.compact if groups.is_a? Array
groups = [] if groups.nil?
- where(project_id: projects).or(where(group_id: groups))
+ if Feature.enabled?(:optimized_timebox_queries, default_enabled: true)
+ from_union([where(project_id: projects), where(group_id: groups)], remove_duplicates: false)
+ else
+ where(project_id: projects).or(where(group_id: groups))
+ end
end
scope :within_timeframe, -> (start_date, end_date) do
@@ -122,6 +128,35 @@ module Timebox
end
end
+ ##
+ # Returns the String necessary to reference a Timebox in Markdown. Group
+ # timeboxes only support name references, and do not support cross-project
+ # references.
+ #
+ # format - Symbol format to use (default: :iid, optional: :name)
+ #
+ # Examples:
+ #
+ # Milestone.first.to_reference # => "%1"
+ # Iteration.first.to_reference(format: :name) # => "*iteration:\"goal\""
+ # Milestone.first.to_reference(cross_namespace_project) # => "gitlab-org/gitlab-foss%1"
+ # Iteration.first.to_reference(same_namespace_project) # => "gitlab-foss*iteration:1"
+ #
+ def to_reference(from = nil, format: :name, full: false)
+ format_reference = timebox_format_reference(format)
+ reference = "#{self.class.reference_prefix}#{format_reference}"
+
+ if project
+ "#{project.to_reference_base(from, full: full)}#{reference}"
+ else
+ reference
+ end
+ end
+
+ def reference_link_text(from = nil)
+ self.class.reference_prefix + self.title
+ end
+
def title=(value)
write_attribute(:title, sanitize_title(value)) if value.present?
end
@@ -162,6 +197,20 @@ module Timebox
private
+ def timebox_format_reference(format = :iid)
+ raise ArgumentError, _('Unknown format') unless [:iid, :name].include?(format)
+
+ if group_timebox? && format == :iid
+ raise ArgumentError, _('Cannot refer to a group %{timebox_type} by an internal id!') % { timebox_type: timebox_name }
+ end
+
+ if format == :name && !name.include?('"')
+ %("#{name}")
+ else
+ iid
+ end
+ end
+
# Timebox titles must be unique across project and group timeboxes
def uniqueness_of_title
if project
diff --git a/app/models/concerns/token_authenticatable.rb b/app/models/concerns/token_authenticatable.rb
index 4099039dd96..a1f83884f02 100644
--- a/app/models/concerns/token_authenticatable.rb
+++ b/app/models/concerns/token_authenticatable.rb
@@ -4,6 +4,10 @@ module TokenAuthenticatable
extend ActiveSupport::Concern
class_methods do
+ def encrypted_token_authenticatable_fields
+ @encrypted_token_authenticatable_fields ||= []
+ end
+
private
def add_authentication_token_field(token_field, options = {})
@@ -12,6 +16,7 @@ module TokenAuthenticatable
end
token_authenticatable_fields.push(token_field)
+ encrypted_token_authenticatable_fields.push(token_field) if options[:encrypted]
attr_accessor :cleartext_tokens
diff --git a/app/models/concerns/update_highest_role.rb b/app/models/concerns/update_highest_role.rb
index 7efc436c6c8..6432cc794a5 100644
--- a/app/models/concerns/update_highest_role.rb
+++ b/app/models/concerns/update_highest_role.rb
@@ -29,9 +29,7 @@ module UpdateHighestRole
UpdateHighestRoleWorker.perform_in(HIGHEST_ROLE_JOB_DELAY, update_highest_role_attribute)
else
# use same logging as ExclusiveLeaseGuard
- # rubocop:disable Gitlab/RailsLogger
- Rails.logger.error('Cannot obtain an exclusive lease. There must be another instance already in execution.')
- # rubocop:enable Gitlab/RailsLogger
+ Gitlab::AppLogger.error('Cannot obtain an exclusive lease. There must be another instance already in execution.')
end
end
end
diff --git a/app/models/container_expiration_policy.rb b/app/models/container_expiration_policy.rb
index 76bfbabf3b3..b1dd720d908 100644
--- a/app/models/container_expiration_policy.rb
+++ b/app/models/container_expiration_policy.rb
@@ -13,6 +13,8 @@ class ContainerExpirationPolicy < ApplicationRecord
validates :cadence, presence: true, inclusion: { in: ->(_) { self.cadence_options.stringify_keys } }
validates :older_than, inclusion: { in: ->(_) { self.older_than_options.stringify_keys } }, allow_nil: true
validates :keep_n, inclusion: { in: ->(_) { self.keep_n_options.keys } }, allow_nil: true
+ validates :name_regex, untrusted_regexp: true, if: :enabled?
+ validates :name_regex_keep, untrusted_regexp: true, if: :enabled?
scope :active, -> { where(enabled: true) }
scope :preloaded, -> { preload(project: [:route]) }
@@ -50,4 +52,8 @@ class ContainerExpirationPolicy < ApplicationRecord
def set_next_run_at
self.next_run_at = Time.zone.now + ChronicDuration.parse(cadence).seconds
end
+
+ def disable!
+ update_attribute(:enabled, false)
+ end
end
diff --git a/app/models/container_repository.rb b/app/models/container_repository.rb
index 455c672cea3..b0f7edac2f3 100644
--- a/app/models/container_repository.rb
+++ b/app/models/container_repository.rb
@@ -16,7 +16,13 @@ class ContainerRepository < ApplicationRecord
scope :ordered, -> { order(:name) }
scope :with_api_entity_associations, -> { preload(project: [:route, { namespace: :route }]) }
scope :for_group_and_its_subgroups, ->(group) do
- where(project_id: Project.for_group_and_its_subgroups(group).with_container_registry.select(:id))
+ project_scope = Project
+ .for_group_and_its_subgroups(group)
+ .with_container_registry
+ .select(:id)
+
+ ContainerRepository
+ .joins("INNER JOIN (#{project_scope.to_sql}) projects on projects.id=container_repositories.project_id")
end
scope :search_by_name, ->(query) { fuzzy_search(query, [:name], use_minimum_char_limit: false) }
@@ -67,6 +73,12 @@ class ContainerRepository < ApplicationRecord
end
end
+ def tags_count
+ return 0 unless manifest && manifest['tags']
+
+ manifest['tags'].size
+ end
+
def blob(config)
ContainerRegistry::Blob.new(self, config)
end
diff --git a/app/models/dashboard_group_milestone.rb b/app/models/dashboard_group_milestone.rb
deleted file mode 100644
index 48c09f4cd6b..00000000000
--- a/app/models/dashboard_group_milestone.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# frozen_string_literal: true
-# Dashboard Group Milestones are milestones that allow us to pull more info out for the UI that the Milestone object doesn't allow for
-class DashboardGroupMilestone < GlobalMilestone
- extend ::Gitlab::Utils::Override
-
- attr_reader :group_name
-
- def initialize(milestone)
- super
-
- @group_name = milestone.group.full_name
- end
-
- def self.build_collection(groups, params)
- milestones = Milestone.of_groups(groups.select(:id))
- .reorder_by_due_date_asc
- .order_by_name_asc
- milestones = milestones.search_title(params[:search_title]) if params[:search_title].present?
- Milestone.filter_by_state(milestones, params[:state]).map { |m| new(m) }
- end
-
- def dashboard_milestone?
- true
- end
-
- def merge_requests_enabled?
- true
- end
-end
diff --git a/app/models/dashboard_milestone.rb b/app/models/dashboard_milestone.rb
deleted file mode 100644
index fd59b94b737..00000000000
--- a/app/models/dashboard_milestone.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class DashboardMilestone < GlobalMilestone
- attr_reader :project_name
-
- def initialize(milestone)
- super
-
- @project_name = milestone.project.full_name
- end
-
- def project_milestone?
- true
- end
-
- def merge_requests_enabled?
- project.merge_requests_enabled?
- end
-end
diff --git a/app/models/data_list.rb b/app/models/data_list.rb
new file mode 100644
index 00000000000..12011cb17f7
--- /dev/null
+++ b/app/models/data_list.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+class DataList
+ def initialize(batch, data_fields_hash, klass)
+ @batch = batch
+ @data_fields_hash = data_fields_hash
+ @klass = klass
+ end
+
+ def to_array
+ [klass, columns, values]
+ end
+
+ private
+
+ attr_reader :batch, :data_fields_hash, :klass
+
+ def columns
+ data_fields_hash.keys << 'service_id'
+ end
+
+ def values
+ batch.map { |row| data_fields_hash.values << row['id'] }
+ end
+end
diff --git a/app/models/deployment.rb b/app/models/deployment.rb
index ba65acff7f3..aa3e3a8f66d 100644
--- a/app/models/deployment.rb
+++ b/app/models/deployment.rb
@@ -64,7 +64,7 @@ class Deployment < ApplicationRecord
end
before_transition any => [:success, :failed, :canceled] do |deployment|
- deployment.finished_at = Time.now
+ deployment.finished_at = Time.current
end
after_transition any => :success do |deployment|
diff --git a/app/models/design_management/design.rb b/app/models/design_management/design.rb
index e9b69eab7a7..0dca6333fa1 100644
--- a/app/models/design_management/design.rb
+++ b/app/models/design_management/design.rb
@@ -20,9 +20,11 @@ module DesignManagement
has_many :notes, as: :noteable, dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
has_many :user_mentions, class_name: 'DesignUserMention', dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
+ has_many :events, as: :target, dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
+
validates :project, :filename, presence: true
validates :issue, presence: true, unless: :importing?
- validates :filename, uniqueness: { scope: :issue_id }
+ validates :filename, uniqueness: { scope: :issue_id }, length: { maximum: 255 }
validate :validate_file_is_image
alias_attribute :title, :filename
@@ -126,68 +128,23 @@ module DesignManagement
# #12["filename with [] in it.jpg"]
def to_reference(from = nil, full: false)
infix = full ? '/designs' : ''
- totally_simple = %r{ \A #{self.class.simple_file_name} \z }x
- safe_name = if totally_simple.match?(filename)
- filename
- elsif filename =~ /[<>]/
- %Q{base64:#{Base64.strict_encode64(filename)}}
- else
- escaped = filename.gsub(%r{[\\"]}) { |x| "\\#{x}" }
- %Q{"#{escaped}"}
- end
+ safe_name = Sanitize.fragment(filename)
"#{issue.to_reference(from, full: full)}#{infix}[#{safe_name}]"
end
def self.reference_pattern
- @reference_pattern ||= begin
- # Filenames can be escaped with double quotes to name filenames
- # that include square brackets, or other special characters
- %r{
- #{Issue.reference_pattern}
- (\/designs)?
- \[
- (?<design> #{simple_file_name} | #{quoted_file_name} | #{base_64_encoded_name})
- \]
- }x
- end
- end
-
- def self.simple_file_name
- %r{
- (?<simple_file_name>
- ( \w | [_:,'-] | \. | \s )+
- \.
- \w+
- )
- }x
- end
-
- def self.base_64_encoded_name
- %r{
- base64:
- (?<base_64_encoded_name>
- [A-Za-z0-9+\n]+
- =?
- )
- }x
- end
-
- def self.quoted_file_name
- %r{
- "
- (?<escaped_filename>
- (\\ \\ | \\ " | [^"\\])+
- )
- "
- }x
+ # no-op: We only support link_reference_pattern parsing
end
def self.link_reference_pattern
@link_reference_pattern ||= begin
- exts = SAFE_IMAGE_EXT + DANGEROUS_IMAGE_EXT
path_segment = %r{issues/#{Gitlab::Regex.issue}/designs}
- filename_pattern = %r{(?<simple_file_name>[a-z0-9_=-]+\.(#{exts.join('|')}))}i
+ ext = Regexp.new(Regexp.union(SAFE_IMAGE_EXT + DANGEROUS_IMAGE_EXT).source, Regexp::IGNORECASE)
+ valid_char = %r{[^/\s]} # any char that is not a forward slash or whitespace
+ filename_pattern = %r{
+ (?<url_filename> #{valid_char}+ \. #{ext})
+ }x
super(path_segment, filename_pattern)
end
@@ -234,6 +191,11 @@ module DesignManagement
alias_method :after_note_created, :after_note_changed
alias_method :after_note_destroyed, :after_note_changed
+ # Part of the interface of objects we can create events about
+ def resource_parent
+ project
+ end
+
private
def head_version
diff --git a/app/models/design_management/version.rb b/app/models/design_management/version.rb
index 6be98fe3d44..55c9084caf2 100644
--- a/app/models/design_management/version.rb
+++ b/app/models/design_management/version.rb
@@ -88,7 +88,7 @@ module DesignManagement
rows = design_actions.map { |action| action.row_attrs(version) }
- Gitlab::Database.bulk_insert(::DesignManagement::Action.table_name, rows)
+ Gitlab::Database.bulk_insert(::DesignManagement::Action.table_name, rows) # rubocop:disable Gitlab/BulkInsert
version.designs.reset
version.validate!
design_actions.each(&:performed)
diff --git a/app/models/diff_note.rb b/app/models/diff_note.rb
index ff39dbb59f3..4b2e62bf761 100644
--- a/app/models/diff_note.rb
+++ b/app/models/diff_note.rb
@@ -136,7 +136,7 @@ class DiffNote < Note
# As an extra benefit, the returned `diff_file` already
# has `highlighted_diff_lines` data set from Redis on
# `Diff::FileCollection::MergeRequestDiff`.
- file = noteable.diffs(original_position.diff_options).diff_files.first
+ file = original_position.find_diff_file_from(noteable)
# if line is not found in persisted diffs, fallback and retrieve file from repository using gitaly
# This is required because of https://gitlab.com/gitlab-org/gitlab/issues/42676
file = nil if file&.line_for_position(original_position).nil? && importing?
diff --git a/app/models/discussion.rb b/app/models/discussion.rb
index c07078c03dd..e928bb0959a 100644
--- a/app/models/discussion.rb
+++ b/app/models/discussion.rb
@@ -20,6 +20,7 @@ class Discussion
:noteable_ability_name,
:to_ability_name,
:editable?,
+ :resolved_by_id,
:system_note_with_references_visible_for?,
:resource_parent,
diff --git a/app/models/draft_note.rb b/app/models/draft_note.rb
new file mode 100644
index 00000000000..febede9beba
--- /dev/null
+++ b/app/models/draft_note.rb
@@ -0,0 +1,122 @@
+# frozen_string_literal: true
+class DraftNote < ApplicationRecord
+ include DiffPositionableNote
+ include Gitlab::Utils::StrongMemoize
+ include Sortable
+ include ShaAttribute
+
+ PUBLISH_ATTRS = %i(noteable_id noteable_type type note).freeze
+ DIFF_ATTRS = %i(position original_position change_position commit_id).freeze
+
+ sha_attribute :commit_id
+
+ # Attribute used to store quick actions changes and users referenced.
+ attr_accessor :commands_changes
+ attr_accessor :users_referenced
+
+ # Text with quick actions filtered out
+ attr_accessor :rendered_note
+
+ attr_accessor :review
+
+ belongs_to :author, class_name: 'User'
+ belongs_to :merge_request
+
+ validates :merge_request_id, presence: true
+ validates :author_id, presence: true, uniqueness: { scope: [:merge_request_id, :discussion_id] }, if: :discussion_id?
+ validates :discussion_id, allow_nil: true, format: { with: /\A\h{40}\z/ }
+
+ scope :authored_by, ->(u) { where(author_id: u.id) }
+
+ delegate :file_path, :file_hash, :file_identifier_hash, to: :diff_file, allow_nil: true
+
+ def self.positions
+ where.not(position: nil)
+ .select(:position)
+ .map(&:position)
+ end
+
+ def project
+ merge_request.target_project
+ end
+
+ # noteable_id and noteable_type methods
+ # are used to generate discussion_id on Discussion.discussion_id
+ def noteable_id
+ merge_request_id
+ end
+
+ def noteable
+ merge_request
+ end
+
+ def noteable_type
+ "MergeRequest"
+ end
+
+ def for_commit?
+ commit_id.present?
+ end
+
+ def importing?
+ false
+ end
+
+ def resolvable?
+ false
+ end
+
+ def emoji_awardable?
+ false
+ end
+
+ def on_diff?
+ position&.complete?
+ end
+
+ def type
+ return 'DiffNote' if on_diff?
+ return 'DiscussionNote' if discussion_id.present?
+
+ 'Note'
+ end
+
+ def references
+ {
+ users: users_referenced,
+ commands: commands_changes
+ }
+ end
+
+ def line_code
+ @line_code ||= diff_file&.line_code_for_position(original_position)
+ end
+
+ def publish_params
+ attrs = PUBLISH_ATTRS.dup
+ attrs.concat(DIFF_ATTRS) if on_diff?
+ params = slice(*attrs)
+ params[:in_reply_to_discussion_id] = discussion_id if discussion_id.present?
+ params[:review_id] = review.id if review.present?
+
+ params
+ end
+
+ def self.preload_author(draft_notes)
+ ActiveRecord::Associations::Preloader.new.preload(draft_notes, { author: :status })
+ end
+
+ def diff_file
+ strong_memoize(:diff_file) do
+ file = original_position&.diff_file(project.repository)
+
+ file&.unfold_diff_lines(original_position)
+
+ file
+ end
+ end
+
+ def commit
+ @commit ||= project.commit(commit_id) if commit_id.present?
+ end
+end
diff --git a/app/models/environment.rb b/app/models/environment.rb
index 21044771bbb..8dae2d760f5 100644
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -339,7 +339,7 @@ class Environment < ApplicationRecord
end
def auto_stop_in
- auto_stop_at - Time.now if auto_stop_at
+ auto_stop_at - Time.current if auto_stop_at
end
def auto_stop_in=(value)
diff --git a/app/models/event.rb b/app/models/event.rb
index 12b85697690..9c0fcbb354b 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -7,36 +7,31 @@ class Event < ApplicationRecord
include DeleteWithLimit
include CreatedAtFilterable
include Gitlab::Utils::StrongMemoize
+ include UsageStatistics
- default_scope { reorder(nil) }
-
- CREATED = 1
- UPDATED = 2
- CLOSED = 3
- REOPENED = 4
- PUSHED = 5
- COMMENTED = 6
- MERGED = 7
- JOINED = 8 # User joined project
- LEFT = 9 # User left project
- DESTROYED = 10
- EXPIRED = 11 # User left project due to expiry
+ default_scope { reorder(nil) } # rubocop:disable Cop/DefaultScope
ACTIONS = HashWithIndifferentAccess.new(
- created: CREATED,
- updated: UPDATED,
- closed: CLOSED,
- reopened: REOPENED,
- pushed: PUSHED,
- commented: COMMENTED,
- merged: MERGED,
- joined: JOINED,
- left: LEFT,
- destroyed: DESTROYED,
- expired: EXPIRED
+ created: 1,
+ updated: 2,
+ closed: 3,
+ reopened: 4,
+ pushed: 5,
+ commented: 6,
+ merged: 7,
+ joined: 8, # User joined project
+ left: 9, # User left project
+ destroyed: 10,
+ expired: 11, # User left project due to expiry
+ approved: 12,
+ archived: 13 # Recoverable deletion
).freeze
- WIKI_ACTIONS = [CREATED, UPDATED, DESTROYED].freeze
+ private_constant :ACTIONS
+
+ WIKI_ACTIONS = [:created, :updated, :destroyed].freeze
+
+ DESIGN_ACTIONS = [:created, :updated, :destroyed, :archived].freeze
TARGET_TYPES = HashWithIndifferentAccess.new(
issue: Issue,
@@ -46,16 +41,20 @@ class Event < ApplicationRecord
project: Project,
snippet: Snippet,
user: User,
- wiki: WikiPage::Meta
+ wiki: WikiPage::Meta,
+ design: DesignManagement::Design
).freeze
RESET_PROJECT_ACTIVITY_INTERVAL = 1.hour
REPOSITORY_UPDATED_AT_INTERVAL = 5.minutes
+ enum action: ACTIONS, _suffix: true
+
delegate :name, :email, :public_email, :username, to: :author, prefix: true, allow_nil: true
delegate :title, to: :issue, prefix: true, allow_nil: true
delegate :title, to: :merge_request, prefix: true, allow_nil: true
delegate :title, to: :note, prefix: true, allow_nil: true
+ delegate :title, to: :design, prefix: true, allow_nil: true
belongs_to :author, class_name: "User"
belongs_to :project
@@ -77,16 +76,16 @@ class Event < ApplicationRecord
# Callbacks
after_create :reset_project_activity
after_create :set_last_repository_updated_at, if: :push_action?
- after_create :track_user_interacted_projects
+ after_create ->(event) { UserInteractedProject.track(event) }
# Scopes
scope :recent, -> { reorder(id: :desc) }
- scope :code_push, -> { where(action: PUSHED) }
- scope :merged, -> { where(action: MERGED) }
scope :for_wiki_page, -> { where(target_type: 'WikiPage::Meta') }
+ scope :for_design, -> { where(target_type: 'DesignManagement::Design') }
# Needed to implement feature flag: can be removed when feature flag is removed
scope :not_wiki_page, -> { where('target_type IS NULL or target_type <> ?', 'WikiPage::Meta') }
+ scope :not_design, -> { where('target_type IS NULL or target_type <> ?', 'DesignManagement::Design') }
scope :with_associations, -> do
# We're using preload for "push_event_payload" as otherwise the association
@@ -105,6 +104,13 @@ class Event < ApplicationRecord
# should ensure the ID points to a valid user.
validates :author_id, presence: true
+ validates :action_enum_value,
+ if: :design?,
+ inclusion: {
+ in: actions.values_at(*DESIGN_ACTIONS),
+ message: ->(event, _data) { "#{event.action} is not a valid design action" }
+ }
+
self.inheritance_column = 'action'
class << self
@@ -113,7 +119,7 @@ class Event < ApplicationRecord
end
def find_sti_class(action)
- if action.to_i == PUSHED
+ if actions.fetch(action, action) == actions[:pushed] # action can be integer or symbol
PushEvent
else
Event
@@ -123,19 +129,15 @@ class Event < ApplicationRecord
# Update Gitlab::ContributionsCalendar#activity_dates if this changes
def contributions
where("action = ? OR (target_type IN (?) AND action IN (?)) OR (target_type = ? AND action = ?)",
- Event::PUSHED,
- %w(MergeRequest Issue), [Event::CREATED, Event::CLOSED, Event::MERGED],
- "Note", Event::COMMENTED)
+ actions[:pushed],
+ %w(MergeRequest Issue), [actions[:created], actions[:closed], actions[:merged]],
+ "Note", actions[:commented])
end
def limit_recent(limit = 20, offset = nil)
recent.limit(limit).offset(offset)
end
- def actions
- ACTIONS.keys
- end
-
def target_types
TARGET_TYPES.keys
end
@@ -148,7 +150,9 @@ class Event < ApplicationRecord
def visible_to_user?(user = nil)
return false unless capability.present?
- Ability.allowed?(user, capability, permission_object)
+ capability.all? do |rule|
+ Ability.allowed?(user, rule, permission_object)
+ end
end
def resource_parent
@@ -159,46 +163,10 @@ class Event < ApplicationRecord
target.try(:title)
end
- def created_action?
- action == CREATED
- end
-
def push_action?
false
end
- def merged_action?
- action == MERGED
- end
-
- def closed_action?
- action == CLOSED
- end
-
- def reopened_action?
- action == REOPENED
- end
-
- def joined_action?
- action == JOINED
- end
-
- def left_action?
- action == LEFT
- end
-
- def expired_action?
- action == EXPIRED
- end
-
- def destroyed_action?
- action == DESTROYED
- end
-
- def commented_action?
- action == COMMENTED
- end
-
def membership_changed?
joined_action? || left_action? || expired_action?
end
@@ -208,11 +176,11 @@ class Event < ApplicationRecord
end
def created_wiki_page?
- wiki_page? && action == CREATED
+ wiki_page? && created_action?
end
def updated_wiki_page?
- wiki_page? && action == UPDATED
+ wiki_page? && updated_action?
end
def created_target?
@@ -239,6 +207,10 @@ class Event < ApplicationRecord
target_type == 'WikiPage::Meta'
end
+ def design?
+ target_type == 'DesignManagement::Design'
+ end
+
def milestone
target if milestone?
end
@@ -247,6 +219,10 @@ class Event < ApplicationRecord
target if issue?
end
+ def design
+ target if design?
+ end
+
def merge_request
target if merge_request?
end
@@ -266,6 +242,8 @@ class Event < ApplicationRecord
def action_name
if push_action?
push_action_name
+ elsif design?
+ design_action_names[action.to_sym]
elsif closed_action?
"closed"
elsif merged_action?
@@ -386,34 +364,30 @@ class Event < ApplicationRecord
protected
- # rubocop:disable Metrics/CyclomaticComplexity
- # rubocop:disable Metrics/PerceivedComplexity
- #
- # TODO Refactor this method so we no longer need to disable the above cops
- # https://gitlab.com/gitlab-org/gitlab/-/issues/216879.
def capability
@capability ||= begin
- if push_action? || commit_note?
- :download_code
- elsif membership_changed? || created_project_action?
- :read_project
- elsif issue? || issue_note?
- :read_issue
- elsif merge_request? || merge_request_note?
- :read_merge_request
- elsif personal_snippet_note? || project_snippet_note?
- :read_snippet
- elsif milestone?
- :read_milestone
- elsif wiki_page?
- :read_wiki
- elsif design_note?
- :read_design
- end
- end
- end
- # rubocop:enable Metrics/CyclomaticComplexity
- # rubocop:enable Metrics/PerceivedComplexity
+ capabilities.flat_map do |ability, syms|
+ if syms.any? { |sym| send(sym) } # rubocop: disable GitlabSecurity/PublicSend
+ [ability]
+ else
+ []
+ end
+ end
+ end
+ end
+
+ def capabilities
+ {
+ download_code: %i[push_action? commit_note?],
+ read_project: %i[membership_changed? created_project_action?],
+ read_issue: %i[issue? issue_note?],
+ read_merge_request: %i[merge_request? merge_request_note?],
+ read_snippet: %i[personal_snippet_note? project_snippet_note?],
+ read_milestone: %i[milestone?],
+ read_wiki: %i[wiki_page?],
+ read_design: %i[design_note? design?]
+ }
+ end
private
@@ -455,11 +429,17 @@ class Event < ApplicationRecord
.update_all(last_repository_updated_at: created_at)
end
- def track_user_interacted_projects
- # Note the call to .available? is due to earlier migrations
- # that would otherwise conflict with the call to .track
- # (because the table does not exist yet).
- UserInteractedProject.track(self) if UserInteractedProject.available?
+ def design_action_names
+ {
+ created: _('uploaded'),
+ updated: _('revised'),
+ destroyed: _('deleted'),
+ archived: _('archived')
+ }
+ end
+
+ def action_enum_value
+ self.class.actions[action]
end
end
diff --git a/app/models/global_milestone.rb b/app/models/global_milestone.rb
deleted file mode 100644
index 43de7454cb7..00000000000
--- a/app/models/global_milestone.rb
+++ /dev/null
@@ -1,108 +0,0 @@
-# frozen_string_literal: true
-# Global Milestones are milestones that can be shared across multiple projects
-class GlobalMilestone
- include Milestoneish
-
- STATE_COUNT_HASH = { opened: 0, closed: 0, all: 0 }.freeze
-
- attr_reader :milestone
- alias_attribute :name, :title
-
- delegate :title, :state, :due_date, :start_date, :participants, :project,
- :group, :expires_at, :closed?, :iid, :group_milestone?, :safe_title,
- :timebox_id, :milestoneish_id, :resource_parent, :releases, to: :milestone
-
- def to_hash
- {
- name: title,
- title: title,
- group_name: group&.full_name,
- project_name: project&.full_name
- }
- end
-
- def for_display
- @milestone
- end
-
- def self.build_collection(projects, params)
- items = Milestone.of_projects(projects)
- .reorder_by_due_date_asc
- .order_by_name_asc
- items = items.search_title(params[:search_title]) if params[:search_title].present?
-
- Milestone.filter_by_state(items, params[:state]).map { |m| new(m) }
- end
-
- # necessary for legacy milestones
- def self.build(projects, title)
- milestones = Milestone.of_projects(projects).where(title: title)
- return if milestones.blank?
-
- new(milestones.first)
- end
-
- def self.states_count(projects, group = nil)
- legacy_group_milestones_count = legacy_group_milestone_states_count(projects)
- group_milestones_count = group_milestones_states_count(group)
-
- legacy_group_milestones_count.merge(group_milestones_count) do |k, legacy_group_milestones_count, group_milestones_count|
- legacy_group_milestones_count + group_milestones_count
- end
- end
-
- def self.group_milestones_states_count(group)
- return STATE_COUNT_HASH unless group
-
- counts_by_state = Milestone.of_groups(group).count_by_state
-
- {
- opened: counts_by_state['active'] || 0,
- closed: counts_by_state['closed'] || 0,
- all: counts_by_state.values.sum
- }
- end
-
- def self.legacy_group_milestone_states_count(projects)
- return STATE_COUNT_HASH unless projects
-
- # We need to reorder(nil) on the projects, because the controller passes them in sorted.
- relation = Milestone.of_projects(projects.reorder(nil)).count_by_state
-
- {
- opened: relation['active'] || 0,
- closed: relation['closed'] || 0,
- all: relation.values.sum
- }
- end
-
- def initialize(milestone)
- @milestone = milestone
- end
-
- def active?
- state == 'active'
- end
-
- def closed?
- state == 'closed'
- end
-
- def issues
- @issues ||= Issue.of_milestones(milestone).includes(:project, :assignees, :labels)
- end
-
- def merge_requests
- @merge_requests ||= MergeRequest.of_milestones(milestone).includes(:target_project, :assignees, :labels)
- end
-
- def labels
- @labels ||= GlobalLabel.build_collection(milestone.labels).sort_by!(&:title)
- end
-
- def global_milestone?
- true
- end
-end
-
-GlobalMilestone.include_if_ee('::EE::GlobalMilestone')
diff --git a/app/models/group.rb b/app/models/group.rb
index 04cb6b8b4da..dd7624ab420 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -325,15 +325,17 @@ class Group < Namespace
def members_with_parents
# Avoids an unnecessary SELECT when the group has no parents
source_ids =
- if parent_id
+ if has_parent?
self_and_ancestors.reorder(nil).select(:id)
else
id
end
- GroupMember
- .active_without_invites_and_requests
- .where(source_id: source_ids)
+ group_hierarchy_members = GroupMember.active_without_invites_and_requests
+ .where(source_id: source_ids)
+
+ GroupMember.from_union([group_hierarchy_members,
+ members_from_self_and_ancestor_group_shares])
end
def members_from_self_and_ancestors_with_effective_access_level
@@ -398,7 +400,7 @@ class Group < Namespace
.first
&.access_level
- max_member_access || max_member_access_for_user_from_shared_groups(user) || GroupMember::NO_ACCESS
+ max_member_access || GroupMember::NO_ACCESS
end
def mattermost_team_params
@@ -494,6 +496,11 @@ class Group < Namespace
# TODO: group hooks https://gitlab.com/gitlab-org/gitlab/-/issues/216904
end
+ def preload_shared_group_links
+ preloader = ActiveRecord::Associations::Preloader.new
+ preloader.preload(self, shared_with_group_links: [shared_with_group: :route])
+ end
+
private
def update_two_factor_requirement
@@ -524,27 +531,39 @@ class Group < Namespace
errors.add(:visibility_level, "#{visibility} is not allowed since there are sub-groups with higher visibility.")
end
- def max_member_access_for_user_from_shared_groups(user)
+ def members_from_self_and_ancestor_group_shares
group_group_link_table = GroupGroupLink.arel_table
group_member_table = GroupMember.arel_table
- group_group_links_query = GroupGroupLink.where(shared_group_id: self_and_ancestors_ids)
+ source_ids =
+ if has_parent?
+ self_and_ancestors.reorder(nil).select(:id)
+ else
+ id
+ end
+
+ group_group_links_query = GroupGroupLink.where(shared_group_id: source_ids)
cte = Gitlab::SQL::CTE.new(:group_group_links_cte, group_group_links_query)
cte_alias = cte.table.alias(GroupGroupLink.table_name)
- link = GroupGroupLink
- .with(cte.to_arel)
- .select(smallest_value_arel([cte_alias[:group_access], group_member_table[:access_level]],
- 'group_access'))
- .from([group_member_table, cte.alias_to(group_group_link_table)])
- .where(group_member_table[:user_id].eq(user.id))
- .where(group_member_table[:requested_at].eq(nil))
- .where(group_member_table[:source_id].eq(group_group_link_table[:shared_with_group_id]))
- .where(group_member_table[:source_type].eq('Namespace'))
- .reorder(Arel::Nodes::Descending.new(group_group_link_table[:group_access]))
- .first
-
- link&.group_access
+ # Instead of members.access_level, we need to maximize that access_level at
+ # the respective group_group_links.group_access.
+ member_columns = GroupMember.attribute_names.map do |column_name|
+ if column_name == 'access_level'
+ smallest_value_arel([cte_alias[:group_access], group_member_table[:access_level]],
+ 'access_level')
+ else
+ group_member_table[column_name]
+ end
+ end
+
+ GroupMember
+ .with(cte.to_arel)
+ .select(*member_columns)
+ .from([group_member_table, cte.alias_to(group_group_link_table)])
+ .where(group_member_table[:requested_at].eq(nil))
+ .where(group_member_table[:source_id].eq(group_group_link_table[:shared_with_group_id]))
+ .where(group_member_table[:source_type].eq('Namespace'))
end
def smallest_value_arel(args, column_alias)
diff --git a/app/models/group_deploy_key.rb b/app/models/group_deploy_key.rb
new file mode 100644
index 00000000000..d1f1aa544cd
--- /dev/null
+++ b/app/models/group_deploy_key.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class GroupDeployKey < Key
+ self.table_name = 'group_deploy_keys'
+
+ validates :user, presence: true
+
+ def type
+ 'DeployKey'
+ end
+end
diff --git a/app/models/group_group_link.rb b/app/models/group_group_link.rb
index c233f59b1a6..fdc54ba33ab 100644
--- a/app/models/group_group_link.rb
+++ b/app/models/group_group_link.rb
@@ -14,6 +14,7 @@ class GroupGroupLink < ApplicationRecord
presence: true
scope :non_guests, -> { where('group_access > ?', Gitlab::Access::GUEST) }
+ scope :public_or_visible_to_user, ->(group, user) { where(shared_group: group, shared_with_group: Group.public_or_visible_to_user(user)) } # rubocop:disable Cop/GroupPublicOrVisibleToUser
def self.access_options
Gitlab::Access.options_with_owner
diff --git a/app/models/group_import_state.rb b/app/models/group_import_state.rb
index 7773b887249..d22c1ac5550 100644
--- a/app/models/group_import_state.rb
+++ b/app/models/group_import_state.rb
@@ -5,7 +5,8 @@ class GroupImportState < ApplicationRecord
belongs_to :group, inverse_of: :import_state
- validates :group, :status, :jid, presence: true
+ validates :group, :status, presence: true
+ validates :jid, presence: true, if: -> { started? || finished? }
state_machine :status, initial: :created do
state :created, value: 0
@@ -31,4 +32,8 @@ class GroupImportState < ApplicationRecord
state.update_column(:last_error, last_error) if last_error
end
end
+
+ def in_progress?
+ created? || started?
+ end
end
diff --git a/app/models/group_milestone.rb b/app/models/group_milestone.rb
deleted file mode 100644
index 60e97174e50..00000000000
--- a/app/models/group_milestone.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-# frozen_string_literal: true
-# Group Milestones are milestones that can be shared among many projects within the same group
-class GroupMilestone < GlobalMilestone
- attr_reader :group, :milestones
-
- def self.build_collection(group, projects, params)
- params =
- { state: params[:state], search_title: params[:search_title] }
-
- project_milestones = Milestone.of_projects(projects)
- project_milestones = project_milestones.search_title(params[:search_title]) if params[:search_title].present?
- child_milestones = Milestone.filter_by_state(project_milestones, params[:state])
- grouped_milestones = child_milestones.group_by(&:title)
-
- grouped_milestones.map do |title, grouped|
- new(title, grouped, group)
- end
- end
-
- def self.build(group, projects, title)
- child_milestones = Milestone.of_projects(projects).where(title: title)
- return if child_milestones.blank?
-
- new(title, child_milestones, group)
- end
-
- def initialize(title, milestones, group)
- @milestones = milestones
- @group = group
- end
-
- def milestone
- @milestone ||= milestones.find { |m| m.description.present? } || milestones.first
- end
-
- def issues_finder_params
- { group_id: group.id }
- end
-
- def legacy_group_milestone?
- true
- end
-
- def merge_requests_enabled?
- true
- end
-end
-
-GroupMilestone.include_if_ee('::EE::GroupMilestone')
diff --git a/app/models/internal_id.rb b/app/models/internal_id.rb
index b6882701e23..21cf6bfa414 100644
--- a/app/models/internal_id.rb
+++ b/app/models/internal_id.rb
@@ -25,8 +25,6 @@ class InternalId < ApplicationRecord
validates :usage, presence: true
- REQUIRED_SCHEMA_VERSION = 20180305095250
-
# Increments #last_value and saves the record
#
# The operation locks the record and gathers a `ROW SHARE` lock (in PostgreSQL).
@@ -63,24 +61,16 @@ class InternalId < ApplicationRecord
class << self
def track_greatest(subject, scope, usage, new_value, init)
- return new_value unless available?
-
InternalIdGenerator.new(subject, scope, usage)
.track_greatest(init, new_value)
end
def generate_next(subject, scope, usage, init)
- # Shortcut if `internal_ids` table is not available (yet)
- # This can be the case in other (unrelated) migration specs
- return (init.call(subject) || 0) + 1 unless available?
-
InternalIdGenerator.new(subject, scope, usage)
.generate(init)
end
def reset(subject, scope, usage, value)
- return false unless available?
-
InternalIdGenerator.new(subject, scope, usage)
.reset(value)
end
@@ -95,20 +85,6 @@ class InternalId < ApplicationRecord
where(filter).delete_all
end
-
- def available?
- return true unless Rails.env.test?
-
- Gitlab::SafeRequestStore.fetch(:internal_ids_available_flag) do
- ActiveRecord::Migrator.current_version >= REQUIRED_SCHEMA_VERSION
- end
- end
-
- # Flushes cached information about schema
- def reset_column_information
- Gitlab::SafeRequestStore[:internal_ids_available_flag] = nil
- super
- end
end
class InternalIdGenerator
diff --git a/app/models/issue.rb b/app/models/issue.rb
index a04ac412940..5c5190f88b1 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -59,6 +59,9 @@ class Issue < ApplicationRecord
has_one :sentry_issue
has_one :alert_management_alert, class_name: 'AlertManagement::Alert'
+ has_and_belongs_to_many :self_managed_prometheus_alert_events, join_table: :issues_self_managed_prometheus_alert_events # rubocop: disable Rails/HasAndBelongsToMany
+ has_and_belongs_to_many :prometheus_alert_events, join_table: :issues_prometheus_alert_events # rubocop: disable Rails/HasAndBelongsToMany
+ has_many :prometheus_alerts, through: :prometheus_alert_events
accepts_nested_attributes_for :sentry_issue
@@ -86,12 +89,14 @@ class Issue < ApplicationRecord
scope :preload_associated_models, -> { preload(:assignees, :labels, project: :namespace) }
scope :with_api_entity_associations, -> { preload(:timelogs, :assignees, :author, :notes, :labels, project: [:route, { namespace: :route }] ) }
scope :with_label_attributes, ->(label_attributes) { joins(:labels).where(labels: label_attributes) }
+ scope :with_alert_management_alerts, -> { joins(:alert_management_alert) }
+ scope :with_prometheus_alert_events, -> { joins(:issues_prometheus_alert_events) }
+ scope :with_self_managed_prometheus_alert_events, -> { joins(:issues_self_managed_prometheus_alert_events) }
scope :public_only, -> { where(confidential: false) }
scope :confidential_only, -> { where(confidential: true) }
scope :counts_by_state, -> { reorder(nil).group(:state_id).count }
- scope :with_alert_management_alerts, -> { joins(:alert_management_alert) }
# An issue can be uniquely identified by project_id and iid
# Takes one or more sets of composite IDs, expressed as hash-like records of
@@ -139,6 +144,10 @@ class Issue < ApplicationRecord
issue.closed_at = nil
issue.closed_by = nil
end
+
+ after_transition any => :closed do |issue|
+ issue.resolve_associated_alert_management_alert
+ end
end
# Alias to state machine .with_state_id method
@@ -344,10 +353,26 @@ class Issue < ApplicationRecord
previous_changes['updated_at']&.first || updated_at
end
+ def banzai_render_context(field)
+ super.merge(label_url_method: :project_issues_url)
+ end
+
def design_collection
@design_collection ||= ::DesignManagement::DesignCollection.new(self)
end
+ def resolve_associated_alert_management_alert
+ return unless alert_management_alert
+ return if alert_management_alert.resolve
+
+ Gitlab::AppLogger.warn(
+ message: 'Cannot resolve an associated Alert Management alert',
+ issue_id: id,
+ alert_id: alert_management_alert.id,
+ alert_errors: alert_management_alert.errors.messages
+ )
+ end
+
private
def ensure_metrics
diff --git a/app/models/issue/metrics.rb b/app/models/issue/metrics.rb
index d4e51dcfbca..a5e1957c096 100644
--- a/app/models/issue/metrics.rb
+++ b/app/models/issue/metrics.rb
@@ -11,11 +11,11 @@ class Issue::Metrics < ApplicationRecord
def record!
if issue.milestone_id.present? && self.first_associated_with_milestone_at.blank?
- self.first_associated_with_milestone_at = Time.now
+ self.first_associated_with_milestone_at = Time.current
end
if issue_assigned_to_list_label? && self.first_added_to_board_at.blank?
- self.first_added_to_board_at = Time.now
+ self.first_added_to_board_at = Time.current
end
self.save
diff --git a/app/models/iteration.rb b/app/models/iteration.rb
index 1acd08f2063..2bda0725471 100644
--- a/app/models/iteration.rb
+++ b/app/models/iteration.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true
class Iteration < ApplicationRecord
- include Timebox
-
self.table_name = 'sprints'
attr_accessor :skip_future_date_validation
@@ -15,9 +13,6 @@ class Iteration < ApplicationRecord
include AtomicInternalId
- has_many :issues, foreign_key: 'sprint_id'
- has_many :merge_requests, foreign_key: 'sprint_id'
-
belongs_to :project
belongs_to :group
@@ -33,6 +28,12 @@ class Iteration < ApplicationRecord
scope :upcoming, -> { with_state(:upcoming) }
scope :started, -> { with_state(:started) }
+ scope :within_timeframe, -> (start_date, end_date) do
+ where('start_date is not NULL or due_date is not NULL')
+ .where('start_date is NULL or start_date <= ?', end_date)
+ .where('due_date is NULL or due_date >= ?', start_date)
+ end
+
state_machine :state_enum, initial: :upcoming do
event :start do
transition upcoming: :started
@@ -62,6 +63,14 @@ class Iteration < ApplicationRecord
else iterations.upcoming
end
end
+
+ def reference_prefix
+ '*iteration:'
+ end
+
+ def reference_pattern
+ nil
+ end
end
def state
@@ -72,6 +81,10 @@ class Iteration < ApplicationRecord
self.state_enum = STATE_ENUM_MAP[value]
end
+ def resource_parent
+ group || project
+ end
+
private
def start_or_due_dates_changed?
@@ -98,3 +111,5 @@ class Iteration < ApplicationRecord
end
end
end
+
+Iteration.prepend_if_ee('EE::Iteration')
diff --git a/app/models/jira_import_state.rb b/app/models/jira_import_state.rb
index 92147794e88..2d952c552a8 100644
--- a/app/models/jira_import_state.rb
+++ b/app/models/jira_import_state.rb
@@ -7,6 +7,7 @@ class JiraImportState < ApplicationRecord
self.table_name = 'jira_imports'
+ ERROR_MESSAGE_SIZE = 1000 # 1000 characters limit
STATUSES = { initial: 0, scheduled: 1, started: 2, failed: 3, finished: 4 }.freeze
belongs_to :project
@@ -14,6 +15,7 @@ class JiraImportState < ApplicationRecord
belongs_to :label
scope :by_jira_project_key, -> (jira_project_key) { where(jira_project_key: jira_project_key) }
+ scope :with_status, ->(statuses) { where(status: statuses) }
validates :project, presence: true
validates :jira_project_key, presence: true
@@ -25,6 +27,8 @@ class JiraImportState < ApplicationRecord
message: _('Cannot have multiple Jira imports running at the same time')
}
+ before_save :ensure_error_message_size
+
alias_method :scheduled_by, :user
state_machine :status, initial: :initial do
@@ -47,7 +51,7 @@ class JiraImportState < ApplicationRecord
after_transition initial: :scheduled do |state, _|
state.run_after_commit do
job_id = Gitlab::JiraImport::Stage::StartImportWorker.perform_async(project.id)
- state.update(jid: job_id, scheduled_at: Time.now) if job_id
+ state.update(jid: job_id, scheduled_at: Time.current) if job_id
end
end
@@ -65,6 +69,13 @@ class JiraImportState < ApplicationRecord
end
end
+ after_transition any => :failed do |state, transition|
+ arguments_hash = transition.args.first
+ error_message = arguments_hash&.dig(:error_message)
+
+ state.update_column(:error_message, error_message) if error_message.present?
+ end
+
# Supress warning:
# both JiraImportState and its :status machine have defined a different default for "status".
# although both have same value but represented in 2 ways: integer(0) and symbol(:initial)
@@ -102,4 +113,18 @@ class JiraImportState < ApplicationRecord
def self.finished_imports_count
finished.sum(:imported_issues_count)
end
+
+ def mark_as_failed(error_message)
+ sanitized_message = Gitlab::UrlSanitizer.sanitize(error_message)
+
+ do_fail(error_message: error_message)
+ rescue ActiveRecord::ActiveRecordError => e
+ Gitlab::AppLogger.error("Error setting import status to failed: #{e.message}. Original error: #{sanitized_message}")
+ end
+
+ private
+
+ def ensure_error_message_size
+ self.error_message = error_message&.truncate(ERROR_MESSAGE_SIZE)
+ end
end
diff --git a/app/models/label.rb b/app/models/label.rb
index 652b5e23490..910cc0d68cd 100644
--- a/app/models/label.rb
+++ b/app/models/label.rb
@@ -31,7 +31,7 @@ class Label < ApplicationRecord
validates :title, uniqueness: { scope: [:group_id, :project_id] }
validates :title, length: { maximum: 255 }
- default_scope { order(title: :asc) }
+ default_scope { order(title: :asc) } # rubocop:disable Cop/DefaultScope
scope :templates, -> { where(template: true, type: [Label.name, nil]) }
scope :with_title, ->(title) { where(title: title) }
@@ -133,7 +133,7 @@ class Label < ApplicationRecord
# Searches for labels with a matching title or description.
#
- # This method uses ILIKE on PostgreSQL and LIKE on MySQL.
+ # This method uses ILIKE on PostgreSQL.
#
# query - The search query as a String.
#
diff --git a/app/models/lfs_object.rb b/app/models/lfs_object.rb
index 6a86aebae39..3761484b15d 100644
--- a/app/models/lfs_object.rb
+++ b/app/models/lfs_object.rb
@@ -44,13 +44,13 @@ class LfsObject < ApplicationRecord
file_store == LfsObjectUploader::Store::LOCAL
end
- # rubocop: disable DestroyAll
+ # rubocop: disable Cop/DestroyAll
def self.destroy_unreferenced
joins("LEFT JOIN lfs_objects_projects ON lfs_objects_projects.lfs_object_id = #{table_name}.id")
.where(lfs_objects_projects: { id: nil })
.destroy_all
end
- # rubocop: enable DestroyAll
+ # rubocop: enable Cop/DestroyAll
def self.calculate_oid(path)
self.hexdigest(path)
diff --git a/app/models/license_template.rb b/app/models/license_template.rb
index 73e403f98b4..bd24259984b 100644
--- a/app/models/license_template.rb
+++ b/app/models/license_template.rb
@@ -39,7 +39,7 @@ class LicenseTemplate
end
# Populate placeholders in the LicenseTemplate content
- def resolve!(project_name: nil, fullname: nil, year: Time.now.year.to_s)
+ def resolve!(project_name: nil, fullname: nil, year: Time.current.year.to_s)
# Ensure the string isn't shared with any other instance of LicenseTemplate
new_content = content.dup
new_content.gsub!(YEAR_TEMPLATE_REGEX, year) if year.present?
diff --git a/app/models/member.rb b/app/models/member.rb
index 791073da095..f2926d32d47 100644
--- a/app/models/member.rb
+++ b/app/models/member.rb
@@ -320,7 +320,7 @@ class Member < ApplicationRecord
return false unless invite?
self.invite_token = nil
- self.invite_accepted_at = Time.now.utc
+ self.invite_accepted_at = Time.current.utc
self.user = new_user
diff --git a/app/models/members/group_member.rb b/app/models/members/group_member.rb
index 431a2ccf416..9a916cd40ae 100644
--- a/app/models/members/group_member.rb
+++ b/app/models/members/group_member.rb
@@ -13,12 +13,19 @@ class GroupMember < Member
# Make sure group member points only to group as it source
default_value_for :source_type, SOURCE_TYPE
validates :source_type, format: { with: /\ANamespace\z/ }
- default_scope { where(source_type: SOURCE_TYPE) }
+ default_scope { where(source_type: SOURCE_TYPE) } # rubocop:disable Cop/DefaultScope
scope :of_groups, ->(groups) { where(source_id: groups.select(:id)) }
- scope :count_users_by_group_id, -> { joins(:user).group(:source_id).count }
scope :of_ldap_type, -> { where(ldap: true) }
+ scope :count_users_by_group_id, -> do
+ if Feature.enabled?(:optimized_count_users_by_group_id)
+ group(:source_id).count
+ else
+ joins(:user).group(:source_id).count
+ end
+ end
+
after_create :update_two_factor_requirement, unless: :invite?
after_destroy :update_two_factor_requirement, unless: :invite?
diff --git a/app/models/members/project_member.rb b/app/models/members/project_member.rb
index fa2e0cb8198..833b27756ab 100644
--- a/app/models/members/project_member.rb
+++ b/app/models/members/project_member.rb
@@ -9,7 +9,7 @@ class ProjectMember < Member
default_value_for :source_type, SOURCE_TYPE
validates :source_type, format: { with: /\AProject\z/ }
validates :access_level, inclusion: { in: Gitlab::Access.values }
- default_scope { where(source_type: SOURCE_TYPE) }
+ default_scope { where(source_type: SOURCE_TYPE) } # rubocop:disable Cop/DefaultScope
scope :in_project, ->(project) { where(source_id: project.id) }
scope :in_namespaces, ->(groups) do
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index b4d0b729454..caf7b554427 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -88,6 +88,9 @@ class MergeRequest < ApplicationRecord
has_many :deployments,
through: :deployment_merge_requests
+ has_many :draft_notes
+ has_many :reviews, inverse_of: :merge_request
+
KNOWN_MERGE_PARAMS = [
:auto_merge_strategy,
:should_remove_source_branch,
@@ -101,7 +104,7 @@ class MergeRequest < ApplicationRecord
after_create :ensure_merge_request_diff
after_update :clear_memoized_shas
after_update :reload_diff_if_branch_changed
- after_save :ensure_metrics, unless: :importing?
+ after_commit :ensure_metrics, on: [:create, :update], unless: :importing?
after_commit :expire_etag_cache, unless: :importing?
# When this attribute is true some MR validation is ignored
@@ -541,13 +544,21 @@ class MergeRequest < ApplicationRecord
merge_request_diffs.where.not(id: merge_request_diff.id)
end
- # Overwritten in EE
- def note_positions_for_paths(paths, _user = nil)
+ def note_positions_for_paths(paths, user = nil)
positions = notes.new_diff_notes.joins(:note_diff_file)
.where('note_diff_files.old_path IN (?) OR note_diff_files.new_path IN (?)', paths, paths)
.positions
- Gitlab::Diff::PositionCollection.new(positions, diff_head_sha)
+ collection = Gitlab::Diff::PositionCollection.new(positions, diff_head_sha)
+
+ return collection unless user
+
+ positions = draft_notes
+ .authored_by(user)
+ .positions
+ .select { |pos| paths.include?(pos.file_path) }
+
+ collection.concat(positions)
end
def preloads_discussion_diff_highlighting?
@@ -866,7 +877,7 @@ class MergeRequest < ApplicationRecord
check_service = MergeRequests::MergeabilityCheckService.new(self)
- if async && Feature.enabled?(:async_merge_request_check_mergeability, project, default_enabled: true)
+ if async
check_service.async_execute
else
check_service.execute(retry_lease: false)
@@ -885,11 +896,11 @@ class MergeRequest < ApplicationRecord
end
def merge_event
- @merge_event ||= target_project.events.where(target_id: self.id, target_type: "MergeRequest", action: Event::MERGED).last
+ @merge_event ||= target_project.events.where(target_id: self.id, target_type: "MergeRequest", action: :merged).last
end
def closed_event
- @closed_event ||= target_project.events.where(target_id: self.id, target_type: "MergeRequest", action: Event::CLOSED).last
+ @closed_event ||= target_project.events.where(target_id: self.id, target_type: "MergeRequest", action: :closed).last
end
def work_in_progress?
@@ -1158,6 +1169,7 @@ class MergeRequest < ApplicationRecord
def mergeable_ci_state?
return true unless project.only_allow_merge_if_pipeline_succeeds?
return false unless actual_head_pipeline
+ return true if project.allow_merge_on_skipped_pipeline? && actual_head_pipeline.skipped?
actual_head_pipeline.success?
end
@@ -1302,8 +1314,6 @@ class MergeRequest < ApplicationRecord
end
def has_accessibility_reports?
- return false unless Feature.enabled?(:accessibility_report_view, project)
-
actual_head_pipeline.present? && actual_head_pipeline.has_reports?(Ci::JobArtifact.accessibility_reports)
end
@@ -1568,6 +1578,10 @@ class MergeRequest < ApplicationRecord
deployments.visible.includes(:environment).order(id: :desc).limit(10)
end
+ def banzai_render_context(field)
+ super.merge(label_url_method: :project_merge_requests_url)
+ end
+
private
def with_rebase_lock
diff --git a/app/models/merge_request_context_commit.rb b/app/models/merge_request_context_commit.rb
index eecb10e6dbc..de97fc33f8d 100644
--- a/app/models/merge_request_context_commit.rb
+++ b/app/models/merge_request_context_commit.rb
@@ -20,7 +20,7 @@ class MergeRequestContextCommit < ApplicationRecord
# create MergeRequestContextCommit by given commit sha and it's diff file record
def self.bulk_insert(*args)
- Gitlab::Database.bulk_insert('merge_request_context_commits', *args)
+ Gitlab::Database.bulk_insert('merge_request_context_commits', *args) # rubocop:disable Gitlab/BulkInsert
end
def to_commit
diff --git a/app/models/merge_request_context_commit_diff_file.rb b/app/models/merge_request_context_commit_diff_file.rb
index 9dce7c53ab6..b89d1983ce3 100644
--- a/app/models/merge_request_context_commit_diff_file.rb
+++ b/app/models/merge_request_context_commit_diff_file.rb
@@ -12,6 +12,6 @@ class MergeRequestContextCommitDiffFile < ApplicationRecord
# create MergeRequestContextCommitDiffFile by given diff file record(s)
def self.bulk_insert(*args)
- Gitlab::Database.bulk_insert('merge_request_context_commit_diff_files', *args)
+ Gitlab::Database.bulk_insert('merge_request_context_commit_diff_files', *args) # rubocop:disable Gitlab/BulkInsert
end
end
diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb
index f793bd3d76f..66b27aeac91 100644
--- a/app/models/merge_request_diff.rb
+++ b/app/models/merge_request_diff.rb
@@ -437,7 +437,7 @@ class MergeRequestDiff < ApplicationRecord
transaction do
MergeRequestDiffFile.where(merge_request_diff_id: id).delete_all
- Gitlab::Database.bulk_insert('merge_request_diff_files', rows)
+ Gitlab::Database.bulk_insert('merge_request_diff_files', rows) # rubocop:disable Gitlab/BulkInsert
update!(stored_externally: false)
end
@@ -495,7 +495,7 @@ class MergeRequestDiff < ApplicationRecord
rows = build_external_merge_request_diff_files(rows) if use_external_diff?
# Faster inserts
- Gitlab::Database.bulk_insert('merge_request_diff_files', rows)
+ Gitlab::Database.bulk_insert('merge_request_diff_files', rows) # rubocop:disable Gitlab/BulkInsert
end
def build_external_diff_tempfile(rows)
diff --git a/app/models/merge_request_diff_commit.rb b/app/models/merge_request_diff_commit.rb
index 2819ea7ce1e..9f6933d0879 100644
--- a/app/models/merge_request_diff_commit.rb
+++ b/app/models/merge_request_diff_commit.rb
@@ -27,6 +27,6 @@ class MergeRequestDiffCommit < ApplicationRecord
)
end
- Gitlab::Database.bulk_insert(self.table_name, rows)
+ Gitlab::Database.bulk_insert(self.table_name, rows) # rubocop:disable Gitlab/BulkInsert
end
end
diff --git a/app/models/metrics/dashboard/annotation.rb b/app/models/metrics/dashboard/annotation.rb
index 8166880f0c9..3383dda20c9 100644
--- a/app/models/metrics/dashboard/annotation.rb
+++ b/app/models/metrics/dashboard/annotation.rb
@@ -3,6 +3,8 @@
module Metrics
module Dashboard
class Annotation < ApplicationRecord
+ include DeleteWithLimit
+
self.table_name = 'metrics_dashboard_annotations'
belongs_to :environment, inverse_of: :metrics_dashboard_annotations
@@ -14,14 +16,25 @@ module Metrics
validates :panel_xid, length: { maximum: 255 }
validate :single_ownership
validate :orphaned_annotation
+ validate :ending_at_after_starting_at
scope :after, ->(after) { where('starting_at >= ?', after) }
scope :before, ->(before) { where('starting_at <= ?', before) }
scope :for_dashboard, ->(dashboard_path) { where(dashboard_path: dashboard_path) }
+ scope :ending_before, ->(timestamp) { where('COALESCE(ending_at, starting_at) < ?', timestamp) }
private
+ # If annotation has NULL in ending_at column that indicates, that this annotation IS TIED TO SINGLE POINT
+ # IN TIME designated by starting_at timestamp. It does NOT mean that annotation is ever going starting from
+ # stating_at timestamp
+ def ending_at_after_starting_at
+ return if ending_at.blank? || starting_at.blank? || starting_at <= ending_at
+
+ errors.add(:ending_at, s_("Metrics::Dashboard::Annotation|can't be before starting_at time"))
+ end
+
def single_ownership
return if cluster.nil? ^ environment.nil?
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index b5e4f62792e..58adfd5f70b 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -2,7 +2,6 @@
class Milestone < ApplicationRecord
include Sortable
- include Referable
include Timebox
include Milestoneish
include FromUnion
@@ -29,6 +28,7 @@ class Milestone < ApplicationRecord
scope :order_by_name_asc, -> { order(Arel::Nodes::Ascending.new(arel_table[:title].lower)) }
scope :reorder_by_due_date_asc, -> { reorder(Gitlab::Database.nulls_last_order('due_date', 'ASC')) }
+ scope :with_api_entity_associations, -> { preload(project: [:project_feature, :route, namespace: :route]) }
validates_associated :milestone_releases, message: -> (_, obj) { obj[:value].map(&:errors).map(&:full_messages).join(",") }
@@ -122,35 +122,6 @@ class Milestone < ApplicationRecord
}
end
- ##
- # Returns the String necessary to reference a Milestone in Markdown. Group
- # milestones only support name references, and do not support cross-project
- # references.
- #
- # format - Symbol format to use (default: :iid, optional: :name)
- #
- # Examples:
- #
- # Milestone.first.to_reference # => "%1"
- # Milestone.first.to_reference(format: :name) # => "%\"goal\""
- # Milestone.first.to_reference(cross_namespace_project) # => "gitlab-org/gitlab-foss%1"
- # Milestone.first.to_reference(same_namespace_project) # => "gitlab-foss%1"
- #
- def to_reference(from = nil, format: :name, full: false)
- format_reference = milestone_format_reference(format)
- reference = "#{self.class.reference_prefix}#{format_reference}"
-
- if project
- "#{project.to_reference_base(from, full: full)}#{reference}"
- else
- reference
- end
- end
-
- def reference_link_text(from = nil)
- self.class.reference_prefix + self.title
- end
-
def for_display
self
end
@@ -179,22 +150,12 @@ class Milestone < ApplicationRecord
end
end
- private
-
- def milestone_format_reference(format = :iid)
- raise ArgumentError, _('Unknown format') unless [:iid, :name].include?(format)
-
- if group_milestone? && format == :iid
- raise ArgumentError, _('Cannot refer to a group milestone by an internal id!')
- end
-
- if format == :name && !name.include?('"')
- %("#{name}")
- else
- iid
- end
+ def subgroup_milestone?
+ group_milestone? && parent.subgroup?
end
+ private
+
def issues_finder_params
{ project_id: project_id, group_id: group_id, include_subgroups: group_id.present? }.compact
end
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index 8116f7a256f..90b4be7a674 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -100,11 +100,11 @@ class Namespace < ApplicationRecord
# Searches for namespaces matching the given query.
#
- # This method uses ILIKE on PostgreSQL and LIKE on MySQL.
+ # This method uses ILIKE on PostgreSQL.
#
- # query - The search query as a String
+ # query - The search query as a String.
#
- # Returns an ActiveRecord::Relation
+ # Returns an ActiveRecord::Relation.
def search(query)
fuzzy_search(query, [:name, :path])
end
@@ -277,7 +277,7 @@ class Namespace < ApplicationRecord
end
def has_parent?
- parent.present?
+ parent_id.present? || parent.present?
end
def root_ancestor
diff --git a/app/models/note.rb b/app/models/note.rb
index d174ba8fe83..6b6a7c50b00 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -72,6 +72,7 @@ class Note < ApplicationRecord
belongs_to :author, class_name: "User"
belongs_to :updated_by, class_name: "User"
belongs_to :last_edited_by, class_name: 'User'
+ belongs_to :review, inverse_of: :notes
has_many :todos
@@ -273,6 +274,10 @@ class Note < ApplicationRecord
noteable_type == "Snippet"
end
+ def for_alert_mangement_alert?
+ noteable_type == 'AlertManagement::Alert'
+ end
+
def for_personal_snippet?
noteable.is_a?(PersonalSnippet)
end
@@ -350,8 +355,10 @@ class Note < ApplicationRecord
self.special_role = Note::SpecialRole::FIRST_TIME_CONTRIBUTOR
end
- def confidential?
- confidential || noteable.try(:confidential?)
+ def confidential?(include_noteable: false)
+ return true if confidential
+
+ include_noteable && noteable.try(:confidential?)
end
def editable?
@@ -393,7 +400,13 @@ class Note < ApplicationRecord
end
def noteable_ability_name
- for_snippet? ? 'snippet' : noteable_type.demodulize.underscore
+ if for_snippet?
+ 'snippet'
+ elsif for_alert_mangement_alert?
+ 'alert_management_alert'
+ else
+ noteable_type.demodulize.underscore
+ end
end
def can_be_discussion_note?
@@ -520,7 +533,7 @@ class Note < ApplicationRecord
end
def banzai_render_context(field)
- super.merge(noteable: noteable, system_note: system?)
+ super.merge(noteable: noteable, system_note: system?, label_url_method: noteable_label_url_method)
end
def retrieve_upload(_identifier, paths)
@@ -603,6 +616,10 @@ class Note < ApplicationRecord
errors.add(:base, _('Maximum number of comments exceeded')) if noteable.notes.count >= Noteable::MAX_NOTES_LIMIT
end
+
+ def noteable_label_url_method
+ for_merge_request? ? :project_merge_requests_url : :project_issues_url
+ end
end
Note.prepend_if_ee('EE::Note')
diff --git a/app/models/pages_domain.rb b/app/models/pages_domain.rb
index da5e4012f05..856496f0941 100644
--- a/app/models/pages_domain.rb
+++ b/app/models/pages_domain.rb
@@ -49,11 +49,11 @@ class PagesDomain < ApplicationRecord
after_update :update_daemon, if: :saved_change_to_pages_config?
after_destroy :update_daemon
- scope :enabled, -> { where('enabled_until >= ?', Time.now ) }
+ scope :enabled, -> { where('enabled_until >= ?', Time.current ) }
scope :needs_verification, -> do
verified_at = arel_table[:verified_at]
enabled_until = arel_table[:enabled_until]
- threshold = Time.now + VERIFICATION_THRESHOLD
+ threshold = Time.current + VERIFICATION_THRESHOLD
where(verified_at.eq(nil).or(enabled_until.eq(nil).or(enabled_until.lt(threshold))))
end
@@ -69,7 +69,7 @@ class PagesDomain < ApplicationRecord
from_union([user_provided, certificate_not_valid, certificate_expiring])
end
- scope :for_removal, -> { where("remove_at < ?", Time.now) }
+ scope :for_removal, -> { where("remove_at < ?", Time.current) }
scope :with_logging_info, -> { includes(project: [:namespace, :route]) }
@@ -141,7 +141,7 @@ class PagesDomain < ApplicationRecord
def expired?
return false unless x509
- current = Time.new
+ current = Time.current
current < x509.not_before || x509.not_after < current
end
diff --git a/app/models/pages_domain_acme_order.rb b/app/models/pages_domain_acme_order.rb
index 63d7fbc8206..411456cc237 100644
--- a/app/models/pages_domain_acme_order.rb
+++ b/app/models/pages_domain_acme_order.rb
@@ -3,7 +3,7 @@
class PagesDomainAcmeOrder < ApplicationRecord
belongs_to :pages_domain
- scope :expired, -> { where("expires_at < ?", Time.now) }
+ scope :expired, -> { where("expires_at < ?", Time.current) }
validates :pages_domain, presence: true
validates :expires_at, presence: true
diff --git a/app/models/performance_monitoring/prometheus_dashboard.rb b/app/models/performance_monitoring/prometheus_dashboard.rb
index 57222c61b36..b04e7e689cd 100644
--- a/app/models/performance_monitoring/prometheus_dashboard.rb
+++ b/app/models/performance_monitoring/prometheus_dashboard.rb
@@ -4,30 +4,38 @@ module PerformanceMonitoring
class PrometheusDashboard
include ActiveModel::Model
- attr_accessor :dashboard, :panel_groups, :path, :environment, :priority, :templating
+ attr_accessor :dashboard, :panel_groups, :path, :environment, :priority, :templating, :links
validates :dashboard, presence: true
validates :panel_groups, presence: true
class << self
def from_json(json_content)
- dashboard = new(
- dashboard: json_content['dashboard'],
- panel_groups: json_content['panel_groups'].map { |group| PrometheusPanelGroup.from_json(group) }
- )
-
- dashboard.tap(&:validate!)
+ build_from_hash(json_content).tap(&:validate!)
end
def find_for(project:, user:, path:, options: {})
- dashboard_response = Gitlab::Metrics::Dashboard::Finder.find(project, user, options.merge(dashboard_path: path))
- return unless dashboard_response[:status] == :success
+ template = { path: path, environment: options[:environment] }
+ rsp = Gitlab::Metrics::Dashboard::Finder.find(project, user, options.merge(dashboard_path: path))
+
+ case rsp[:http_status] || rsp[:status]
+ when :success
+ new(template.merge(rsp[:dashboard] || {})) # when there is empty dashboard file returned rsp is still a success
+ when :unprocessable_entity
+ new(template) # validation error
+ else
+ nil # any other error
+ end
+ end
+
+ private
+
+ def build_from_hash(attributes)
+ return new unless attributes.is_a?(Hash)
new(
- {
- path: path,
- environment: options[:environment]
- }.merge(dashboard_response[:dashboard])
+ dashboard: attributes['dashboard'],
+ panel_groups: attributes['panel_groups']&.map { |group| PrometheusPanelGroup.from_json(group) }
)
end
end
@@ -36,6 +44,15 @@ module PerformanceMonitoring
self.as_json(only: yaml_valid_attributes).to_yaml
end
+ # This method is planned to be refactored as a part of https://gitlab.com/gitlab-org/gitlab/-/issues/219398
+ # implementation. For new existing logic was reused to faster deliver MVC
+ def schema_validation_warnings
+ self.class.from_json(self.as_json)
+ nil
+ rescue ActiveModel::ValidationError => exception
+ exception.model.errors.map { |attr, error| "#{attr}: #{error}" }
+ end
+
private
def yaml_valid_attributes
diff --git a/app/models/performance_monitoring/prometheus_metric.rb b/app/models/performance_monitoring/prometheus_metric.rb
index 7b8bef906fa..d67b1809d93 100644
--- a/app/models/performance_monitoring/prometheus_metric.rb
+++ b/app/models/performance_monitoring/prometheus_metric.rb
@@ -10,16 +10,24 @@ module PerformanceMonitoring
validates :query, presence: true, unless: :query_range
validates :query_range, presence: true, unless: :query
- def self.from_json(json_content)
- metric = PrometheusMetric.new(
- id: json_content['id'],
- unit: json_content['unit'],
- label: json_content['label'],
- query: json_content['query'],
- query_range: json_content['query_range']
- )
+ class << self
+ def from_json(json_content)
+ build_from_hash(json_content).tap(&:validate!)
+ end
- metric.tap(&:validate!)
+ private
+
+ def build_from_hash(attributes)
+ return new unless attributes.is_a?(Hash)
+
+ new(
+ id: attributes['id'],
+ unit: attributes['unit'],
+ label: attributes['label'],
+ query: attributes['query'],
+ query_range: attributes['query_range']
+ )
+ end
end
end
end
diff --git a/app/models/performance_monitoring/prometheus_panel.rb b/app/models/performance_monitoring/prometheus_panel.rb
index 3fe029abda0..a16a68ba832 100644
--- a/app/models/performance_monitoring/prometheus_panel.rb
+++ b/app/models/performance_monitoring/prometheus_panel.rb
@@ -8,17 +8,24 @@ module PerformanceMonitoring
validates :title, presence: true
validates :metrics, presence: true
+ class << self
+ def from_json(json_content)
+ build_from_hash(json_content).tap(&:validate!)
+ end
- def self.from_json(json_content)
- panel = new(
- type: json_content['type'],
- title: json_content['title'],
- y_label: json_content['y_label'],
- weight: json_content['weight'],
- metrics: json_content['metrics'].map { |metric| PrometheusMetric.from_json(metric) }
- )
+ private
- panel.tap(&:validate!)
+ def build_from_hash(attributes)
+ return new unless attributes.is_a?(Hash)
+
+ new(
+ type: attributes['type'],
+ title: attributes['title'],
+ y_label: attributes['y_label'],
+ weight: attributes['weight'],
+ metrics: attributes['metrics']&.map { |metric| PrometheusMetric.from_json(metric) }
+ )
+ end
end
def id(group_title)
diff --git a/app/models/performance_monitoring/prometheus_panel_group.rb b/app/models/performance_monitoring/prometheus_panel_group.rb
index e672545fce3..f88106f259b 100644
--- a/app/models/performance_monitoring/prometheus_panel_group.rb
+++ b/app/models/performance_monitoring/prometheus_panel_group.rb
@@ -8,15 +8,22 @@ module PerformanceMonitoring
validates :group, presence: true
validates :panels, presence: true
+ class << self
+ def from_json(json_content)
+ build_from_hash(json_content).tap(&:validate!)
+ end
- def self.from_json(json_content)
- panel_group = new(
- group: json_content['group'],
- priority: json_content['priority'],
- panels: json_content['panels'].map { |panel| PrometheusPanel.from_json(panel) }
- )
+ private
- panel_group.tap(&:validate!)
+ def build_from_hash(attributes)
+ return new unless attributes.is_a?(Hash)
+
+ new(
+ group: attributes['group'],
+ priority: attributes['priority'],
+ panels: attributes['panels']&.map { |panel| PrometheusPanel.from_json(panel) }
+ )
+ end
end
end
end
diff --git a/app/models/project.rb b/app/models/project.rb
index c0dd2eb8584..845e9e83e78 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -33,6 +33,7 @@ class Project < ApplicationRecord
include OptionallySearch
include FromUnion
include IgnorableColumns
+ include Integration
extend Gitlab::Cache::RequestCache
extend Gitlab::ConfigHelper
@@ -95,8 +96,7 @@ class Project < ApplicationRecord
after_create :create_project_feature, unless: :project_feature
after_create :create_ci_cd_settings,
- unless: :ci_cd_settings,
- if: proc { ProjectCiCdSetting.available? }
+ unless: :ci_cd_settings
after_create :create_container_expiration_policy,
unless: :container_expiration_policy
@@ -198,7 +198,7 @@ class Project < ApplicationRecord
has_one :error_tracking_setting, inverse_of: :project, class_name: 'ErrorTracking::ProjectErrorTrackingSetting'
has_one :metrics_setting, inverse_of: :project, class_name: 'ProjectMetricsSetting'
has_one :grafana_integration, inverse_of: :project
- has_one :project_setting, ->(project) { where_or_create_by(project: project) }, inverse_of: :project
+ has_one :project_setting, inverse_of: :project, autosave: true
has_one :alerting_setting, inverse_of: :project, class_name: 'Alerting::ProjectAlertingSetting'
# Merge Requests for target project should be removed with it
@@ -282,7 +282,7 @@ class Project < ApplicationRecord
class_name: 'Ci::Pipeline',
inverse_of: :project
has_many :stages, class_name: 'Ci::Stage', inverse_of: :project
- has_many :ci_refs, class_name: 'Ci::Ref'
+ has_many :ci_refs, class_name: 'Ci::Ref', inverse_of: :project
# Ci::Build objects store data on the file system such as artifact files and
# build traces. Currently there's no efficient way of removing this data in
@@ -291,6 +291,7 @@ class Project < ApplicationRecord
has_many :builds, class_name: 'Ci::Build', inverse_of: :project, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
has_many :build_trace_section_names, class_name: 'Ci::BuildTraceSectionName'
has_many :build_trace_chunks, class_name: 'Ci::BuildTraceChunk', through: :builds, source: :trace_chunks
+ has_many :build_report_results, class_name: 'Ci::BuildReportResult', inverse_of: :project
has_many :job_artifacts, class_name: 'Ci::JobArtifact'
has_many :runner_projects, class_name: 'Ci::RunnerProject', inverse_of: :project
has_many :runners, through: :runner_projects, source: :runner, class_name: 'Ci::Runner'
@@ -328,6 +329,9 @@ class Project < ApplicationRecord
has_many :repository_storage_moves, class_name: 'ProjectRepositoryStorageMove'
+ has_many :webide_pipelines, -> { webide_source }, class_name: 'Ci::Pipeline', inverse_of: :project
+ has_many :reviews, inverse_of: :project
+
accepts_nested_attributes_for :variables, allow_destroy: true
accepts_nested_attributes_for :project_feature, update_only: true
accepts_nested_attributes_for :project_setting, update_only: true
@@ -368,9 +372,11 @@ class Project < ApplicationRecord
delegate :root_ancestor, to: :namespace, allow_nil: true
delegate :last_pipeline, to: :commit, allow_nil: true
delegate :external_dashboard_url, to: :metrics_setting, allow_nil: true, prefix: true
+ delegate :dashboard_timezone, to: :metrics_setting, allow_nil: true, prefix: true
delegate :default_git_depth, :default_git_depth=, to: :ci_cd_settings, prefix: :ci
delegate :forward_deployment_enabled, :forward_deployment_enabled=, :forward_deployment_enabled?, to: :ci_cd_settings
delegate :actual_limits, :actual_plan_name, to: :namespace, allow_nil: true
+ delegate :allow_merge_on_skipped_pipeline, :allow_merge_on_skipped_pipeline?, :allow_merge_on_skipped_pipeline=, to: :project_setting
# Validations
validates :creator, presence: true, on: :create
@@ -442,7 +448,7 @@ class Project < ApplicationRecord
scope :archived, -> { where(archived: true) }
scope :non_archived, -> { where(archived: false) }
scope :for_milestones, ->(ids) { joins(:milestones).where('milestones.id' => ids).distinct }
- scope :with_push, -> { joins(:events).where('events.action = ?', Event::PUSHED) }
+ scope :with_push, -> { joins(:events).merge(Event.pushed_action) }
scope :with_project_feature, -> { joins('LEFT JOIN project_features ON projects.id = project_features.project_id') }
scope :inc_routes, -> { includes(:route, namespace: :route) }
scope :with_statistics, -> { includes(:statistics) }
@@ -507,6 +513,11 @@ class Project < ApplicationRecord
.where(project_pages_metadata: { project_id: nil })
end
+ scope :with_api_entity_associations, -> {
+ preload(:project_feature, :route, :tags,
+ group: :ip_restrictions, namespace: [:route, :owner])
+ }
+
enum auto_cancel_pending_pipelines: { disabled: 0, enabled: 1 }
chronic_duration_attr :build_timeout_human_readable, :build_timeout,
@@ -521,6 +532,10 @@ class Project < ApplicationRecord
# Used by Projects::CleanupService to hold a map of rewritten object IDs
mount_uploader :bfg_object_map, AttachmentUploader
+ def self.with_web_entity_associations
+ preload(:project_feature, :route, :creator, :group, namespace: [:route, :owner])
+ end
+
def self.eager_load_namespace_and_owner
includes(namespace: :owner)
end
@@ -602,8 +617,7 @@ class Project < ApplicationRecord
# Searches for a list of projects based on the query given in `query`.
#
# On PostgreSQL this method uses "ILIKE" to perform a case-insensitive
- # search. On MySQL a regular "LIKE" is used as it's already
- # case-insensitive.
+ # search.
#
# query - The search query as a String.
def search(query, include_namespace: false)
@@ -713,6 +727,10 @@ class Project < ApplicationRecord
super
end
+ def project_setting
+ super.presence || build_project_setting
+ end
+
def all_pipelines
if builds_enabled?
super
@@ -729,6 +747,10 @@ class Project < ApplicationRecord
end
end
+ def active_webide_pipelines(user:)
+ webide_pipelines.running_or_pending.for_user(user)
+ end
+
def autoclose_referenced_issues
return true if super.nil?
@@ -798,10 +820,6 @@ class Project < ApplicationRecord
Feature.enabled?(:context_commits, default_enabled: true)
end
- def jira_issues_import_feature_flag_enabled?
- Feature.enabled?(:jira_issue_import, self, default_enabled: true)
- end
-
# LFS and hashed repository storage are required for using Design Management.
def design_management_enabled?
lfs_enabled? && hashed_storage?(:repository)
@@ -889,18 +907,6 @@ class Project < ApplicationRecord
latest_jira_import&.status || 'initial'
end
- def validate_jira_import_settings!(user: nil)
- raise Projects::ImportService::Error, _('Jira import feature is disabled.') unless jira_issues_import_feature_flag_enabled?
- raise Projects::ImportService::Error, _('Jira integration not configured.') unless jira_service&.active?
-
- if user
- raise Projects::ImportService::Error, _('Cannot import because issues are not available in this project.') unless feature_available?(:issues, user)
- raise Projects::ImportService::Error, _('You do not have permissions to run the import.') unless user.can?(:admin_project, self)
- end
-
- raise Projects::ImportService::Error, _('Unable to connect to the Jira instance. Please check your Jira integration configuration.') unless jira_service.test(nil)[:success]
- end
-
def human_import_status_name
import_state&.human_status_name || 'none'
end
@@ -921,17 +927,15 @@ class Project < ApplicationRecord
job_id
end
- # rubocop:disable Gitlab/RailsLogger
def log_import_activity(job_id, type: :import)
job_type = type.to_s.capitalize
if job_id
- Rails.logger.info("#{job_type} job scheduled for #{full_path} with job ID #{job_id}.")
+ Gitlab::AppLogger.info("#{job_type} job scheduled for #{full_path} with job ID #{job_id}.")
else
- Rails.logger.error("#{job_type} job failed to create for #{full_path}.")
+ Gitlab::AppLogger.error("#{job_type} job failed to create for #{full_path}.")
end
end
- # rubocop:enable Gitlab/RailsLogger
def reset_cache_and_import_attrs
run_after_commit do
@@ -1007,7 +1011,7 @@ class Project < ApplicationRecord
end
def jira_import?
- import_type == 'jira' && latest_jira_import.present? && jira_issues_import_feature_flag_enabled?
+ import_type == 'jira' && latest_jira_import.present?
end
def gitlab_project_import?
@@ -1036,7 +1040,7 @@ class Project < ApplicationRecord
remote_mirrors.stuck.update_all(
update_status: :failed,
last_error: _('The remote mirror took to long to complete.'),
- last_update_at: Time.now
+ last_update_at: Time.current
)
end
@@ -1194,14 +1198,6 @@ class Project < ApplicationRecord
get_issue(issue_id)
end
- def default_issue_tracker
- gitlab_issue_tracker_service || create_gitlab_issue_tracker_service
- end
-
- def issues_tracker
- external_issue_tracker || default_issue_tracker
- end
-
def external_issue_reference_pattern
external_issue_tracker.class.reference_pattern(only_long: issues_enabled?)
end
@@ -1257,7 +1253,7 @@ class Project < ApplicationRecord
available_services_names.map do |service_name|
find_or_initialize_service(service_name)
- end
+ end.sort_by(&:title)
end
def disabled_services
@@ -1267,16 +1263,7 @@ class Project < ApplicationRecord
def find_or_initialize_service(name)
return if disabled_services.include?(name)
- service = find_service(services, name)
- return service if service
-
- template = find_service(services_templates, name)
-
- if template
- Service.build_from_template(id, template)
- else
- public_send("build_#{name}_service") # rubocop:disable GitlabSecurity/PublicSend
- end
+ find_service(services, name) || build_from_instance_or_template(name) || public_send("build_#{name}_service") # rubocop:disable GitlabSecurity/PublicSend
end
# rubocop: disable CodeReuse/ServiceClass
@@ -1781,17 +1768,15 @@ class Project < ApplicationRecord
ensure_pages_metadatum.update!(deployed: false)
end
- # rubocop:disable Gitlab/RailsLogger
def write_repository_config(gl_full_path: full_path)
# We'd need to keep track of project full path otherwise directory tree
# created with hashed storage enabled cannot be usefully imported using
# the import rake task.
repository.raw_repository.write_config(full_path: gl_full_path)
rescue Gitlab::Git::Repository::NoRepository => e
- Rails.logger.error("Error writing to .git/config for project #{full_path} (#{id}): #{e.message}.")
+ Gitlab::AppLogger.error("Error writing to .git/config for project #{full_path} (#{id}): #{e.message}.")
nil
end
- # rubocop:enable Gitlab/RailsLogger
def after_import
repository.expire_content_cache
@@ -1834,17 +1819,15 @@ class Project < ApplicationRecord
@pipeline_status ||= Gitlab::Cache::Ci::ProjectPipelineStatus.load_for_project(self)
end
- # rubocop:disable Gitlab/RailsLogger
def add_export_job(current_user:, after_export_strategy: nil, params: {})
job_id = ProjectExportWorker.perform_async(current_user.id, self.id, after_export_strategy, params)
if job_id
- Rails.logger.info "Export job started for project ID #{self.id} with job ID #{job_id}"
+ Gitlab::AppLogger.info "Export job started for project ID #{self.id} with job ID #{job_id}"
else
- Rails.logger.error "Export job failed to start for project ID #{self.id}"
+ Gitlab::AppLogger.error "Export job failed to start for project ID #{self.id}"
end
end
- # rubocop:enable Gitlab/RailsLogger
def import_export_shared
@import_export_shared ||= Gitlab::ImportExport::Shared.new(self)
@@ -2082,21 +2065,6 @@ class Project < ApplicationRecord
end
end
- def change_repository_storage(new_repository_storage_key)
- return if repository_read_only?
- return if repository_storage == new_repository_storage_key
-
- raise ArgumentError unless ::Gitlab.config.repositories.storages.key?(new_repository_storage_key)
-
- storage_move = repository_storage_moves.create!(
- source_storage_name: repository_storage,
- destination_storage_name: new_repository_storage_key
- )
- storage_move.schedule!
-
- self.repository_read_only = true
- end
-
def pushes_since_gc
Gitlab::Redis::SharedState.with { |redis| redis.get(pushes_since_gc_redis_shared_state_key).to_i }
end
@@ -2438,12 +2406,32 @@ class Project < ApplicationRecord
touch(:last_activity_at, :last_repository_updated_at)
end
+ def metrics_setting
+ super || build_metrics_setting
+ end
+
private
def find_service(services, name)
services.find { |service| service.to_param == name }
end
+ def build_from_instance_or_template(name)
+ instance = find_service(services_instances, name)
+ return Service.build_from_integration(id, instance) if instance
+
+ template = find_service(services_templates, name)
+ return Service.build_from_integration(id, template) if template
+ end
+
+ def services_templates
+ @services_templates ||= Service.templates
+ end
+
+ def services_instances
+ @services_instances ||= Service.instances
+ end
+
def closest_namespace_setting(name)
namespace.closest_setting(name)
end
@@ -2572,10 +2560,6 @@ class Project < ApplicationRecord
end
end
- def services_templates
- @services_templates ||= Service.where(template: true)
- end
-
def ensure_pages_metadatum
pages_metadatum || create_pages_metadatum!
rescue ActiveRecord::RecordNotUnique
diff --git a/app/models/project_ci_cd_setting.rb b/app/models/project_ci_cd_setting.rb
index c295837002a..e5fc481b035 100644
--- a/app/models/project_ci_cd_setting.rb
+++ b/app/models/project_ci_cd_setting.rb
@@ -3,9 +3,6 @@
class ProjectCiCdSetting < ApplicationRecord
belongs_to :project, inverse_of: :ci_cd_settings
- # The version of the schema that first introduced this model/table.
- MINIMUM_SCHEMA_VERSION = 20180403035759
-
DEFAULT_GIT_DEPTH = 50
before_create :set_default_git_depth
@@ -20,16 +17,6 @@ class ProjectCiCdSetting < ApplicationRecord
default_value_for :forward_deployment_enabled, true
- def self.available?
- @available ||=
- ActiveRecord::Migrator.current_version >= MINIMUM_SCHEMA_VERSION
- end
-
- def self.reset_column_information
- @available = nil
- super
- end
-
def forward_deployment_enabled?
super && ::Feature.enabled?(:forward_deployment_enabled, project, default_enabled: true)
end
diff --git a/app/models/project_feature.rb b/app/models/project_feature.rb
index 9201cd24d66..b3ebcbd4b17 100644
--- a/app/models/project_feature.rb
+++ b/app/models/project_feature.rb
@@ -1,51 +1,16 @@
# frozen_string_literal: true
class ProjectFeature < ApplicationRecord
- # == Project features permissions
- #
- # Grants access level to project tools
- #
- # Tools can be enabled only for users, everyone or disabled
- # Access control is made only for non private projects
- #
- # levels:
- #
- # Disabled: not enabled for anyone
- # Private: enabled only for team members
- # Enabled: enabled for everyone able to access the project
- # Public: enabled for everyone (only allowed for pages)
- #
-
- # Permission levels
- DISABLED = 0
- PRIVATE = 10
- ENABLED = 20
- PUBLIC = 30
+ include Featurable
FEATURES = %i(issues forking merge_requests wiki snippets builds repository pages metrics_dashboard).freeze
+
+ set_available_features(FEATURES)
+
PRIVATE_FEATURES_MIN_ACCESS_LEVEL = { merge_requests: Gitlab::Access::REPORTER, metrics_dashboard: Gitlab::Access::REPORTER }.freeze
PRIVATE_FEATURES_MIN_ACCESS_LEVEL_FOR_PRIVATE_PROJECT = { repository: Gitlab::Access::REPORTER }.freeze
- STRING_OPTIONS = HashWithIndifferentAccess.new({
- 'disabled' => DISABLED,
- 'private' => PRIVATE,
- 'enabled' => ENABLED,
- 'public' => PUBLIC
- }).freeze
class << self
- def access_level_attribute(feature)
- feature = ensure_feature!(feature)
-
- "#{feature}_access_level".to_sym
- end
-
- def quoted_access_level_column(feature)
- attribute = connection.quote_column_name(access_level_attribute(feature))
- table = connection.quote_table_name(table_name)
-
- "#{table}.#{attribute}"
- end
-
def required_minimum_access_level(feature)
feature = ensure_feature!(feature)
@@ -60,24 +25,6 @@ class ProjectFeature < ApplicationRecord
required_minimum_access_level(feature)
end
end
-
- def access_level_from_str(level)
- STRING_OPTIONS.fetch(level)
- end
-
- def str_from_access_level(level)
- STRING_OPTIONS.key(level)
- end
-
- private
-
- def ensure_feature!(feature)
- feature = feature.model_name.plural if feature.respond_to?(:model_name)
- feature = feature.to_sym
- raise ArgumentError, "invalid project feature: #{feature}" unless FEATURES.include?(feature)
-
- feature
- end
end
# Default scopes force us to unscope here since a service may need to check
@@ -107,45 +54,6 @@ class ProjectFeature < ApplicationRecord
end
end
- def feature_available?(feature, user)
- # This feature might not be behind a feature flag at all, so default to true
- return false unless ::Feature.enabled?(feature, user, default_enabled: true)
-
- get_permission(user, feature)
- end
-
- def access_level(feature)
- public_send(ProjectFeature.access_level_attribute(feature)) # rubocop:disable GitlabSecurity/PublicSend
- end
-
- def string_access_level(feature)
- ProjectFeature.str_from_access_level(access_level(feature))
- end
-
- def builds_enabled?
- builds_access_level > DISABLED
- end
-
- def wiki_enabled?
- wiki_access_level > DISABLED
- end
-
- def merge_requests_enabled?
- merge_requests_access_level > DISABLED
- end
-
- def forking_enabled?
- forking_access_level > DISABLED
- end
-
- def issues_enabled?
- issues_access_level > DISABLED
- end
-
- def pages_enabled?
- pages_access_level > DISABLED
- end
-
def public_pages?
return true unless Gitlab.config.pages.access_control
@@ -164,7 +72,7 @@ class ProjectFeature < ApplicationRecord
# which cannot be higher than repository access level
def repository_children_level
validator = lambda do |field|
- level = public_send(field) || ProjectFeature::ENABLED # rubocop:disable GitlabSecurity/PublicSend
+ level = public_send(field) || ENABLED # rubocop:disable GitlabSecurity/PublicSend
not_allowed = level > repository_access_level
self.errors.add(field, "cannot have higher visibility level than repository access level") if not_allowed
end
@@ -175,8 +83,8 @@ class ProjectFeature < ApplicationRecord
# Validates access level for other than pages cannot be PUBLIC
def allowed_access_levels
validator = lambda do |field|
- level = public_send(field) || ProjectFeature::ENABLED # rubocop:disable GitlabSecurity/PublicSend
- not_allowed = level > ProjectFeature::ENABLED
+ 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
diff --git a/app/models/project_group_link.rb b/app/models/project_group_link.rb
index f1c491d1a05..f065246e8af 100644
--- a/app/models/project_group_link.rb
+++ b/app/models/project_group_link.rb
@@ -15,8 +15,6 @@ class ProjectGroupLink < ApplicationRecord
scope :non_guests, -> { where('group_access > ?', Gitlab::Access::GUEST) }
- after_commit :refresh_group_members_authorized_projects
-
alias_method :shared_with_group, :group
def self.access_options
@@ -49,10 +47,6 @@ class ProjectGroupLink < ApplicationRecord
errors.add(:base, _("Project cannot be shared with the group it is in or one of its ancestors."))
end
end
-
- def refresh_group_members_authorized_projects
- group.refresh_members_authorized_projects
- end
end
ProjectGroupLink.prepend_if_ee('EE::ProjectGroupLink')
diff --git a/app/models/project_import_state.rb b/app/models/project_import_state.rb
index e434ea58729..4bd3ffbea2f 100644
--- a/app/models/project_import_state.rb
+++ b/app/models/project_import_state.rb
@@ -84,7 +84,11 @@ class ProjectImportState < ApplicationRecord
update_column(:last_error, sanitized_message)
rescue ActiveRecord::ActiveRecordError => e
- Rails.logger.error("Error setting import status to failed: #{e.message}. Original error: #{sanitized_message}") # rubocop:disable Gitlab/RailsLogger
+ Gitlab::Import::Logger.error(
+ message: 'Error setting import status to failed',
+ error: e.message,
+ original_error: sanitized_message
+ )
ensure
@errors = original_errors
end
diff --git a/app/models/project_metrics_setting.rb b/app/models/project_metrics_setting.rb
index a2a7dc571a4..c66d0f52f4c 100644
--- a/app/models/project_metrics_setting.rb
+++ b/app/models/project_metrics_setting.rb
@@ -4,6 +4,13 @@ class ProjectMetricsSetting < ApplicationRecord
belongs_to :project
validates :external_dashboard_url,
+ allow_nil: true,
length: { maximum: 255 },
addressable_url: { enforce_sanitization: true, ascii_only: true }
+
+ enum dashboard_timezone: { local: 0, utc: 1 }
+
+ def dashboard_timezone=(val)
+ super(val&.downcase)
+ end
end
diff --git a/app/models/project_repository_storage_move.rb b/app/models/project_repository_storage_move.rb
index e88cc5cfca6..b18d9765a57 100644
--- a/app/models/project_repository_storage_move.rb
+++ b/app/models/project_repository_storage_move.rb
@@ -18,6 +18,7 @@ class ProjectRepositoryStorageMove < ApplicationRecord
on: :create,
presence: true,
inclusion: { in: ->(_) { Gitlab.config.repositories.storages.keys } }
+ validate :project_repository_writable, on: :create
state_machine initial: :initial do
event :schedule do
@@ -36,7 +37,9 @@ class ProjectRepositoryStorageMove < ApplicationRecord
transition [:initial, :scheduled, :started] => :failed
end
- after_transition initial: :scheduled do |storage_move, _|
+ after_transition initial: :scheduled do |storage_move|
+ storage_move.project.update_column(:repository_read_only, true)
+
storage_move.run_after_commit do
ProjectUpdateRepositoryStorageWorker.perform_async(
storage_move.project_id,
@@ -46,6 +49,17 @@ class ProjectRepositoryStorageMove < ApplicationRecord
end
end
+ after_transition started: :finished do |storage_move|
+ storage_move.project.update_columns(
+ repository_read_only: false,
+ repository_storage: storage_move.destination_storage_name
+ )
+ end
+
+ after_transition started: :failed do |storage_move|
+ storage_move.project.update_column(:repository_read_only, false)
+ end
+
state :initial, value: 1
state :scheduled, value: 2
state :started, value: 3
@@ -55,4 +69,10 @@ class ProjectRepositoryStorageMove < ApplicationRecord
scope :order_created_at_desc, -> { order(created_at: :desc) }
scope :with_projects, -> { includes(project: :route) }
+
+ private
+
+ def project_repository_writable
+ errors.add(:project, _('is read only')) if project&.repository_read_only?
+ end
end
diff --git a/app/models/project_services/alerts_service.rb b/app/models/project_services/alerts_service.rb
index 16bf37fd189..58c47accfd1 100644
--- a/app/models/project_services/alerts_service.rb
+++ b/app/models/project_services/alerts_service.rb
@@ -41,7 +41,7 @@ class AlertsService < Service
end
def description
- _('Receive alerts on GitLab from any source')
+ _('Authorize external services to send alerts to GitLab')
end
def detailed_description
diff --git a/app/models/project_services/chat_message/alert_message.rb b/app/models/project_services/chat_message/alert_message.rb
new file mode 100644
index 00000000000..c8913775843
--- /dev/null
+++ b/app/models/project_services/chat_message/alert_message.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+module ChatMessage
+ class AlertMessage < BaseMessage
+ attr_reader :title
+ attr_reader :alert_url
+ attr_reader :severity
+ attr_reader :events
+ attr_reader :status
+ attr_reader :started_at
+
+ def initialize(params)
+ @project_name = params[:project_name] || params.dig(:project, :path_with_namespace)
+ @project_url = params.dig(:project, :web_url) || params[:project_url]
+ @title = params.dig(:object_attributes, :title)
+ @alert_url = params.dig(:object_attributes, :url)
+ @severity = params.dig(:object_attributes, :severity)
+ @events = params.dig(:object_attributes, :events)
+ @status = params.dig(:object_attributes, :status)
+ @started_at = params.dig(:object_attributes, :started_at)
+ end
+
+ def attachments
+ [{
+ title: title,
+ title_link: alert_url,
+ color: attachment_color,
+ fields: attachment_fields
+ }]
+ end
+
+ def message
+ "Alert firing in #{project_name}"
+ end
+
+ private
+
+ def attachment_color
+ "#C95823"
+ end
+
+ def attachment_fields
+ [
+ {
+ title: "Severity",
+ value: severity.to_s.humanize,
+ short: true
+ },
+ {
+ title: "Events",
+ value: events,
+ short: true
+ },
+ {
+ title: "Status",
+ value: status.to_s.humanize,
+ short: true
+ },
+ {
+ title: "Start time",
+ value: format_time(started_at),
+ short: true
+ }
+ ]
+ end
+
+ # This formats time into the following format
+ # April 23rd, 2020 1:06AM UTC
+ def format_time(time)
+ time = Time.zone.parse(time.to_s)
+ time.strftime("%B #{time.day.ordinalize}, %Y %l:%M%p %Z")
+ end
+ end
+end
diff --git a/app/models/project_services/chat_message/merge_message.rb b/app/models/project_services/chat_message/merge_message.rb
index 0a2d9120adc..c4fcdff8386 100644
--- a/app/models/project_services/chat_message/merge_message.rb
+++ b/app/models/project_services/chat_message/merge_message.rb
@@ -48,7 +48,7 @@ module ChatMessage
end
def merge_request_message
- "#{user_combined_name} #{state_or_action_text} #{merge_request_link} in #{project_link}"
+ "#{user_combined_name} #{state_or_action_text} merge request #{merge_request_link} in #{project_link}"
end
def merge_request_link
diff --git a/app/models/project_services/chat_message/pipeline_message.rb b/app/models/project_services/chat_message/pipeline_message.rb
index 1cd3837433f..f4c6938fa78 100644
--- a/app/models/project_services/chat_message/pipeline_message.rb
+++ b/app/models/project_services/chat_message/pipeline_message.rb
@@ -183,7 +183,7 @@ module ChatMessage
if ref_type == 'tag'
"#{project_url}/-/tags/#{ref}"
else
- "#{project_url}/commits/#{ref}"
+ "#{project_url}/-/commits/#{ref}"
end
end
@@ -200,14 +200,14 @@ module ChatMessage
end
def pipeline_failed_jobs_url
- "#{project_url}/pipelines/#{pipeline_id}/failures"
+ "#{project_url}/-/pipelines/#{pipeline_id}/failures"
end
def pipeline_url
if failed_jobs.any?
pipeline_failed_jobs_url
else
- "#{project_url}/pipelines/#{pipeline_id}"
+ "#{project_url}/-/pipelines/#{pipeline_id}"
end
end
diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb
index c92e8ecb31c..ad531412fb7 100644
--- a/app/models/project_services/hipchat_service.rb
+++ b/app/models/project_services/hipchat_service.rb
@@ -252,8 +252,8 @@ class HipchatService < Service
status = pipeline_attributes[:status]
duration = pipeline_attributes[:duration]
- branch_link = "<a href=\"#{project_url}/commits/#{CGI.escape(ref)}\">#{ref}</a>"
- pipeline_url = "<a href=\"#{project_url}/pipelines/#{pipeline_id}\">##{pipeline_id}</a>"
+ branch_link = "<a href=\"#{project_url}/-/commits/#{CGI.escape(ref)}\">#{ref}</a>"
+ pipeline_url = "<a href=\"#{project_url}/-/pipelines/#{pipeline_id}\">##{pipeline_id}</a>"
"#{project_link}: Pipeline #{pipeline_url} of #{branch_link} #{ref_type} by #{user_name} #{humanized_status(status)} in #{duration} second(s)"
end
diff --git a/app/models/project_services/jira_service.rb b/app/models/project_services/jira_service.rb
index 53da874ede8..bb4d35cad22 100644
--- a/app/models/project_services/jira_service.rb
+++ b/app/models/project_services/jira_service.rb
@@ -6,6 +6,8 @@ class JiraService < IssueTrackerService
include ApplicationHelper
include ActionView::Helpers::AssetUrlHelper
+ PROJECTS_PER_PAGE = 50
+
validates :url, public_url: true, presence: true, if: :activated?
validates :api_url, public_url: true, allow_blank: true
validates :username, presence: true, if: :activated?
@@ -201,6 +203,10 @@ class JiraService < IssueTrackerService
add_comment(data, jira_issue)
end
+ def valid_connection?
+ test(nil)[:success]
+ end
+
def test(_)
result = test_settings
success = result.present?
@@ -209,11 +215,6 @@ class JiraService < IssueTrackerService
{ success: success, result: result }
end
- # Jira does not need test data.
- def test_data(_, _)
- nil
- end
-
override :support_close_issue?
def support_close_issue?
true
@@ -413,17 +414,9 @@ class JiraService < IssueTrackerService
# Handle errors when doing Jira API calls
def jira_request
yield
- rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, Errno::ECONNREFUSED, URI::InvalidURIError, JIRA::HTTPError, OpenSSL::SSL::SSLError => error
+ rescue => error
@error = error
- log_error(
- "Error sending message",
- client_url: client_url,
- error: {
- exception_class: error.class.name,
- exception_message: error.message,
- exception_backtrace: Gitlab::BacktraceCleaner.clean_backtrace(error.backtrace)
- }
- )
+ log_error("Error sending message", client_url: client_url, error: @error.message)
nil
end
diff --git a/app/models/project_services/pipelines_email_service.rb b/app/models/project_services/pipelines_email_service.rb
index a58a264de5e..c11b2f7cc65 100644
--- a/app/models/project_services/pipelines_email_service.rb
+++ b/app/models/project_services/pipelines_email_service.rb
@@ -56,12 +56,6 @@ class PipelinesEmailService < Service
project&.ci_pipelines&.any?
end
- def test_data(project, user)
- data = Gitlab::DataBuilder::Pipeline.build(project.ci_pipelines.last)
- data[:user] = user.hook_attrs
- data
- end
-
def fields
[
{ type: 'textarea',
diff --git a/app/models/project_services/prometheus_service.rb b/app/models/project_services/prometheus_service.rb
index 4a28d1ff2b0..44a41969b1c 100644
--- a/app/models/project_services/prometheus_service.rb
+++ b/app/models/project_services/prometheus_service.rb
@@ -5,6 +5,8 @@ class PrometheusService < MonitoringService
# Access to prometheus is directly through the API
prop_accessor :api_url
+ prop_accessor :google_iap_service_account_json
+ prop_accessor :google_iap_audience_client_id
boolean_accessor :manual_configuration
# We need to allow the self-monitoring project to connect to the internal
@@ -49,7 +51,7 @@ class PrometheusService < MonitoringService
end
def fields
- [
+ result = [
{
type: 'checkbox',
name: 'manual_configuration',
@@ -64,6 +66,28 @@ class PrometheusService < MonitoringService
required: true
}
]
+
+ if Feature.enabled?(:prometheus_service_iap_auth)
+ result += [
+ {
+ type: 'text',
+ name: 'google_iap_audience_client_id',
+ title: 'Google IAP Audience Client ID',
+ placeholder: s_('PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)'),
+ autocomplete: 'off',
+ required: false
+ },
+ {
+ type: 'textarea',
+ name: 'google_iap_service_account_json',
+ title: 'Google IAP Service Account JSON',
+ placeholder: s_('PrometheusService|Contents of the credentials.json file of your service account, like: { "type": "service_account", "project_id": ... }'),
+ required: false
+ }
+ ]
+ end
+
+ result
end
# Check we can connect to the Prometheus API
@@ -77,7 +101,14 @@ class PrometheusService < MonitoringService
def prometheus_client
return unless should_return_client?
- Gitlab::PrometheusClient.new(api_url, allow_local_requests: allow_local_api_url?)
+ options = { allow_local_requests: allow_local_api_url? }
+
+ if Feature.enabled?(:prometheus_service_iap_auth) && behind_iap?
+ # Adds the Authorization header
+ options[:headers] = iap_client.apply({})
+ end
+
+ Gitlab::PrometheusClient.new(api_url, options)
end
def prometheus_available?
@@ -149,4 +180,12 @@ class PrometheusService < MonitoringService
Prometheus::CreateDefaultAlertsWorker.perform_async(project_id)
end
+
+ def behind_iap?
+ manual_configuration? && google_iap_audience_client_id.present? && google_iap_service_account_json.present?
+ end
+
+ def iap_client
+ @iap_client ||= Google::Auth::Credentials.new(Gitlab::Json.parse(google_iap_service_account_json), target_audience: google_iap_audience_client_id).client
+ end
end
diff --git a/app/models/project_services/slack_service.rb b/app/models/project_services/slack_service.rb
index 6d567bb1383..79245e84238 100644
--- a/app/models/project_services/slack_service.rb
+++ b/app/models/project_services/slack_service.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: true
class SlackService < ChatNotificationService
+ prop_accessor EVENT_CHANNEL['alert']
+
def title
'Slack notifications'
end
@@ -21,13 +23,25 @@ class SlackService < ChatNotificationService
'https://hooks.slack.com/services/…'
end
+ def supported_events
+ additional = []
+ additional << 'alert'
+
+ super + additional
+ end
+
+ def get_message(object_kind, data)
+ return ChatMessage::AlertMessage.new(data) if object_kind == 'alert'
+
+ super
+ end
+
module Notifier
private
def notify(message, opts)
# See https://gitlab.com/gitlab-org/slack-notifier/#custom-http-client
notifier = Slack::Messenger.new(webhook, opts.merge(http_client: HTTPClient))
-
notifier.ping(
message.pretext,
attachments: message.attachments,
diff --git a/app/models/project_setting.rb b/app/models/project_setting.rb
index 7c93faf3928..9022d3e879d 100644
--- a/app/models/project_setting.rb
+++ b/app/models/project_setting.rb
@@ -4,10 +4,6 @@ class ProjectSetting < ApplicationRecord
belongs_to :project, inverse_of: :project_setting
self.primary_key = :project_id
-
- def self.where_or_create_by(attrs)
- where(primary_key => safe_find_or_create_by(attrs))
- end
end
ProjectSetting.prepend_if_ee('EE::ProjectSetting')
diff --git a/app/models/prometheus_alert_event.rb b/app/models/prometheus_alert_event.rb
index 7e61f6d5e3c..25f58a0b9d5 100644
--- a/app/models/prometheus_alert_event.rb
+++ b/app/models/prometheus_alert_event.rb
@@ -34,10 +34,4 @@ class PrometheusAlertEvent < ApplicationRecord
def self.status_value_for(name)
state_machines[:status].states[name].value
end
-
- def self.payload_key_for(gitlab_alert_id, started_at)
- plain = [gitlab_alert_id, started_at].join('/')
-
- Digest::SHA1.hexdigest(plain)
- end
end
diff --git a/app/models/push_event.rb b/app/models/push_event.rb
index 5cab686f20b..0f626cb618e 100644
--- a/app/models/push_event.rb
+++ b/app/models/push_event.rb
@@ -68,7 +68,7 @@ class PushEvent < Event
end
def self.sti_name
- PUSHED
+ actions[:pushed]
end
def push_action?
@@ -111,7 +111,7 @@ class PushEvent < Event
end
def validate_push_action
- return if action == PUSHED
+ return if pushed_action?
errors.add(:action, "the action #{action.inspect} is not valid")
end
diff --git a/app/models/releases/evidence.rb b/app/models/releases/evidence.rb
index 1aac7e33e41..7c428f5ad03 100644
--- a/app/models/releases/evidence.rb
+++ b/app/models/releases/evidence.rb
@@ -1,44 +1,35 @@
# frozen_string_literal: true
-class Releases::Evidence < ApplicationRecord
- include ShaAttribute
- include Presentable
+module Releases
+ class Evidence < ApplicationRecord
+ include ShaAttribute
+ include Presentable
- belongs_to :release, inverse_of: :evidences
+ belongs_to :release, inverse_of: :evidences
- before_validation :generate_summary_and_sha
+ default_scope { order(created_at: :asc) } # rubocop:disable Cop/DefaultScope
- default_scope { order(created_at: :asc) }
+ sha_attribute :summary_sha
+ alias_attribute :collected_at, :created_at
+ alias_attribute :sha, :summary_sha
- sha_attribute :summary_sha
- alias_attribute :collected_at, :created_at
-
- def milestones
- @milestones ||= release.milestones.includes(:issues)
- end
-
- ##
- # Return `summary` without sensitive information.
- #
- # Removing issues from summary in order to prevent leaking confidential ones.
- # See more https://gitlab.com/gitlab-org/gitlab/issues/121930
- def summary
- safe_summary = read_attribute(:summary)
-
- safe_summary.dig('release', 'milestones')&.each do |milestone|
- milestone.delete('issues')
+ def milestones
+ @milestones ||= release.milestones.includes(:issues)
end
- safe_summary
- end
-
- private
+ ##
+ # Return `summary` without sensitive information.
+ #
+ # Removing issues from summary in order to prevent leaking confidential ones.
+ # See more https://gitlab.com/gitlab-org/gitlab/issues/121930
+ def summary
+ safe_summary = read_attribute(:summary)
- def generate_summary_and_sha
- summary = Evidences::EvidenceSerializer.new.represent(self) # rubocop: disable CodeReuse/Serializer
- return unless summary
+ safe_summary.dig('release', 'milestones')&.each do |milestone|
+ milestone.delete('issues')
+ end
- self.summary = summary
- self.summary_sha = Gitlab::CryptoHelper.sha256(summary)
+ safe_summary
+ end
end
end
diff --git a/app/models/releases/link.rb b/app/models/releases/link.rb
index 65be2a22958..dc7e78a85a9 100644
--- a/app/models/releases/link.rb
+++ b/app/models/releases/link.rb
@@ -14,6 +14,13 @@ module Releases
scope :sorted, -> { order(created_at: :desc) }
+ enum link_type: {
+ other: 0,
+ runbook: 1,
+ package: 2,
+ image: 3
+ }
+
def internal?
url.start_with?(release.project.web_url)
end
diff --git a/app/models/remote_mirror.rb b/app/models/remote_mirror.rb
index 8e7612e63c8..8b15d481c1b 100644
--- a/app/models/remote_mirror.rb
+++ b/app/models/remote_mirror.rb
@@ -68,13 +68,13 @@ class RemoteMirror < ApplicationRecord
after_transition any => :started do |remote_mirror, _|
Gitlab::Metrics.add_event(:remote_mirrors_running)
- remote_mirror.update(last_update_started_at: Time.now)
+ remote_mirror.update(last_update_started_at: Time.current)
end
after_transition started: :finished do |remote_mirror, _|
Gitlab::Metrics.add_event(:remote_mirrors_finished)
- timestamp = Time.now
+ timestamp = Time.current
remote_mirror.update!(
last_update_at: timestamp,
last_successful_update_at: timestamp,
@@ -86,7 +86,7 @@ class RemoteMirror < ApplicationRecord
after_transition started: :failed do |remote_mirror|
Gitlab::Metrics.add_event(:remote_mirrors_failed)
- remote_mirror.update(last_update_at: Time.now)
+ remote_mirror.update(last_update_at: Time.current)
remote_mirror.run_after_commit do
RemoteMirrorNotificationWorker.perform_async(remote_mirror.id)
@@ -144,9 +144,9 @@ class RemoteMirror < ApplicationRecord
return unless sync?
if recently_scheduled?
- RepositoryUpdateRemoteMirrorWorker.perform_in(backoff_delay, self.id, Time.now)
+ RepositoryUpdateRemoteMirrorWorker.perform_in(backoff_delay, self.id, Time.current)
else
- RepositoryUpdateRemoteMirrorWorker.perform_async(self.id, Time.now)
+ RepositoryUpdateRemoteMirrorWorker.perform_async(self.id, Time.current)
end
end
@@ -261,7 +261,7 @@ class RemoteMirror < ApplicationRecord
def recently_scheduled?
return false unless self.last_update_started_at
- self.last_update_started_at >= Time.now - backoff_delay
+ self.last_update_started_at >= Time.current - backoff_delay
end
def reset_fields
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 2673033ff1f..911cfc7db38 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -950,7 +950,6 @@ class Repository
async_remove_remote(remote_name) if tmp_remote_name
end
- # rubocop:disable Gitlab/RailsLogger
def async_remove_remote(remote_name)
return unless remote_name
return unless project
@@ -958,14 +957,13 @@ class Repository
job_id = RepositoryRemoveRemoteWorker.perform_async(project.id, remote_name)
if job_id
- Rails.logger.info("Remove remote job scheduled for #{project.id} with remote name: #{remote_name} job ID #{job_id}.")
+ Gitlab::AppLogger.info("Remove remote job scheduled for #{project.id} with remote name: #{remote_name} job ID #{job_id}.")
else
- Rails.logger.info("Remove remote job failed to create for #{project.id} with remote name #{remote_name}.")
+ Gitlab::AppLogger.info("Remove remote job failed to create for #{project.id} with remote name #{remote_name}.")
end
job_id
end
- # rubocop:enable Gitlab/RailsLogger
def fetch_source_branch!(source_repository, source_branch, local_ref)
raw_repository.fetch_source_branch!(source_repository.raw_repository, source_branch, local_ref)
@@ -1171,7 +1169,7 @@ class Repository
if target
target.committed_date
else
- Time.now
+ Time.current
end
end
end
diff --git a/app/models/repository_language.rb b/app/models/repository_language.rb
index e468d716239..6b1793a551f 100644
--- a/app/models/repository_language.rb
+++ b/app/models/repository_language.rb
@@ -4,7 +4,7 @@ class RepositoryLanguage < ApplicationRecord
belongs_to :project
belongs_to :programming_language
- default_scope { includes(:programming_language) }
+ default_scope { includes(:programming_language) } # rubocop:disable Cop/DefaultScope
validates :project, presence: true
validates :share, inclusion: { in: 0..100, message: "The share of a language is between 0 and 100" }
diff --git a/app/models/resource_label_event.rb b/app/models/resource_label_event.rb
index 845be408d5e..cc96698be09 100644
--- a/app/models/resource_label_event.rb
+++ b/app/models/resource_label_event.rb
@@ -71,6 +71,14 @@ class ResourceLabelEvent < ResourceEvent
end
end
+ def self.visible_to_user?(user, events)
+ ResourceLabelEvent.preload_label_subjects(events)
+
+ events.select do |event|
+ Ability.allowed?(user, :read_label, event)
+ end
+ end
+
private
def label_reference
diff --git a/app/models/resource_milestone_event.rb b/app/models/resource_milestone_event.rb
index 039f26d8e3f..36068cf508b 100644
--- a/app/models/resource_milestone_event.rb
+++ b/app/models/resource_milestone_event.rb
@@ -9,6 +9,8 @@ class ResourceMilestoneEvent < ResourceEvent
validate :exactly_one_issuable
+ scope :include_relations, -> { includes(:user, milestone: [:project, :group]) }
+
enum action: {
add: 1,
remove: 2
@@ -26,4 +28,12 @@ class ResourceMilestoneEvent < ResourceEvent
def milestone_title
milestone&.title
end
+
+ def milestone_parent
+ milestone&.parent
+ end
+
+ def issuable
+ issue || merge_request
+ end
end
diff --git a/app/models/review.rb b/app/models/review.rb
new file mode 100644
index 00000000000..5a30e2963c8
--- /dev/null
+++ b/app/models/review.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+class Review < ApplicationRecord
+ include Participable
+ include Mentionable
+
+ belongs_to :author, class_name: 'User', foreign_key: :author_id, inverse_of: :reviews
+ belongs_to :merge_request, inverse_of: :reviews
+ belongs_to :project, inverse_of: :reviews
+
+ has_many :notes, -> { order(:id) }, inverse_of: :review
+
+ delegate :name, to: :author, prefix: true
+
+ participant :author
+
+ def all_references(current_user = nil, extractor: nil)
+ ext = super
+
+ notes.each do |note|
+ note.all_references(current_user, extractor: ext)
+ end
+
+ ext
+ end
+
+ def user_mentions
+ merge_request.user_mentions.where.not(note_id: nil)
+ end
+end
diff --git a/app/models/route.rb b/app/models/route.rb
index 63a0461807b..706589e79b8 100644
--- a/app/models/route.rb
+++ b/app/models/route.rb
@@ -42,7 +42,7 @@ class Route < ApplicationRecord
old_path = route.path
# Callbacks must be run manually
- route.update_columns(attributes.merge(updated_at: Time.now))
+ route.update_columns(attributes.merge(updated_at: Time.current))
# We are not calling route.delete_conflicting_redirects here, in hopes
# of avoiding deadlocks. The parent (self, in this method) already
diff --git a/app/models/self_managed_prometheus_alert_event.rb b/app/models/self_managed_prometheus_alert_event.rb
index d2d4a5c37d4..cf26563e92d 100644
--- a/app/models/self_managed_prometheus_alert_event.rb
+++ b/app/models/self_managed_prometheus_alert_event.rb
@@ -15,10 +15,4 @@ class SelfManagedPrometheusAlertEvent < ApplicationRecord
yield event if block_given?
end
end
-
- def self.payload_key_for(started_at, alert_name, query_expression)
- plain = [started_at, alert_name, query_expression].join('/')
-
- Digest::SHA1.hexdigest(plain)
- end
end
diff --git a/app/models/service.rb b/app/models/service.rb
index fb4d9a77077..2880526c9de 100644
--- a/app/models/service.rb
+++ b/app/models/service.rb
@@ -22,6 +22,7 @@ class Service < ApplicationRecord
serialize :properties, JSON # rubocop:disable Cop/ActiveRecordSerialize
default_value_for :active, false
+ default_value_for :alert_events, true
default_value_for :push_events, true
default_value_for :issues_events, true
default_value_for :confidential_issues_events, true
@@ -72,6 +73,7 @@ class Service < ApplicationRecord
scope :pipeline_hooks, -> { where(pipeline_events: true, active: true) }
scope :wiki_page_hooks, -> { where(wiki_page_events: true, active: true) }
scope :deployment_hooks, -> { where(deployment_events: true, active: true) }
+ scope :alert_hooks, -> { where(alert_events: true, active: true) }
scope :external_issue_trackers, -> { issue_trackers.active.without_defaults }
scope :deployment, -> { where(category: 'deployment') }
@@ -134,8 +136,12 @@ class Service < ApplicationRecord
%w(active)
end
- def test_data(project, user)
- Gitlab::DataBuilder::Push.build_sample(project, user)
+ def to_service_hash
+ as_json(methods: :type, except: %w[id template instance project_id])
+ end
+
+ def to_data_fields_hash
+ data_fields.as_json(only: data_fields.class.column_names).except('id', 'service_id')
end
def event_channel_names
@@ -164,7 +170,7 @@ class Service < ApplicationRecord
end
def configurable_events
- events = self.class.supported_events
+ events = supported_events
# No need to disable individual triggers when there is only one
if events.count == 1
@@ -335,17 +341,19 @@ class Service < ApplicationRecord
services_names.map { |service_name| "#{service_name}_service".camelize }
end
- def self.build_from_template(project_id, template)
- service = template.dup
+ def self.build_from_integration(project_id, integration)
+ service = integration.dup
- if template.supports_data_fields?
- data_fields = template.data_fields.dup
+ if integration.supports_data_fields?
+ data_fields = integration.data_fields.dup
data_fields.service = service
end
service.template = false
+ service.instance = false
+ service.inherit_from_id = integration.id if integration.instance?
service.project_id = project_id
- service.active = false if service.active? && service.invalid?
+ service.active = false if service.invalid?
service
end
@@ -394,6 +402,8 @@ class Service < ApplicationRecord
"Event will be triggered when a commit is created/updated"
when "deployment"
"Event will be triggered when a deployment finishes"
+ when "alert"
+ "Event will be triggered when a new, unique alert is recorded"
end
end
diff --git a/app/models/service_list.rb b/app/models/service_list.rb
new file mode 100644
index 00000000000..fa3760f0c56
--- /dev/null
+++ b/app/models/service_list.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class ServiceList
+ def initialize(batch, service_hash, extra_hash = {})
+ @batch = batch
+ @service_hash = service_hash
+ @extra_hash = extra_hash
+ end
+
+ def to_array
+ [Service, columns, values]
+ end
+
+ private
+
+ attr_reader :batch, :service_hash, :extra_hash
+
+ def columns
+ (service_hash.keys << 'project_id') + extra_hash.keys
+ end
+
+ def values
+ batch.map do |project_id|
+ (service_hash.values << project_id) + extra_hash.values
+ end
+ end
+end
diff --git a/app/models/snippet.rb b/app/models/snippet.rb
index 72ebdf61787..b63ab003711 100644
--- a/app/models/snippet.rb
+++ b/app/models/snippet.rb
@@ -337,7 +337,7 @@ class Snippet < ApplicationRecord
class << self
# Searches for snippets with a matching title, description or file name.
#
- # This method uses ILIKE on PostgreSQL and LIKE on MySQL.
+ # This method uses ILIKE on PostgreSQL.
#
# query - The search query as a String.
#
diff --git a/app/models/snippet_input_action.rb b/app/models/snippet_input_action.rb
new file mode 100644
index 00000000000..7f4ab775ab0
--- /dev/null
+++ b/app/models/snippet_input_action.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+class SnippetInputAction
+ include ActiveModel::Validations
+
+ ACTIONS = %i[create update delete move].freeze
+
+ ACTIONS.each do |action_const|
+ define_method "#{action_const}_action?" do
+ action == action_const
+ end
+ end
+
+ attr_reader :action, :previous_path, :file_path, :content
+
+ validates :action, inclusion: { in: ACTIONS, message: "%{value} is not a valid action" }
+ validates :previous_path, presence: true, if: :move_action?
+ validates :file_path, presence: true
+ validates :content, presence: true, if: -> (action) { action.create_action? || action.update_action? }
+ validate :ensure_same_file_path_and_previous_path, if: :update_action?
+ validate :ensure_allowed_action
+
+ def initialize(action: nil, previous_path: nil, file_path: nil, content: nil, allowed_actions: nil)
+ @action = action&.to_sym
+ @previous_path = previous_path
+ @file_path = file_path
+ @content = content
+ @allowed_actions = Array(allowed_actions).map(&:to_sym)
+ end
+
+ def to_commit_action
+ {
+ action: action,
+ previous_path: build_previous_path,
+ file_path: file_path,
+ content: content
+ }
+ end
+
+ private
+
+ def build_previous_path
+ return previous_path unless update_action?
+
+ previous_path.presence || file_path
+ end
+
+ def ensure_same_file_path_and_previous_path
+ return if previous_path.blank? || file_path.blank?
+ return if previous_path == file_path
+
+ errors.add(:file_path, "can't be different from the previous_path attribute")
+ end
+
+ def ensure_allowed_action
+ return if @allowed_actions.empty?
+
+ unless @allowed_actions.include?(action)
+ errors.add(:action, 'is not allowed')
+ end
+ end
+end
diff --git a/app/models/snippet_input_action_collection.rb b/app/models/snippet_input_action_collection.rb
new file mode 100644
index 00000000000..38313e3a980
--- /dev/null
+++ b/app/models/snippet_input_action_collection.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+class SnippetInputActionCollection
+ include Gitlab::Utils::StrongMemoize
+
+ attr_reader :actions
+
+ delegate :empty?, :any?, :[], to: :actions
+
+ def initialize(actions = [], allowed_actions: nil)
+ @actions = actions.map { |action| SnippetInputAction.new(action.merge(allowed_actions: allowed_actions)) }
+ end
+
+ def to_commit_actions
+ strong_memoize(:commit_actions) do
+ actions.map { |action| action.to_commit_action }
+ end
+ end
+
+ def valid?
+ strong_memoize(:valid) do
+ actions.all?(&:valid?)
+ end
+ end
+end
diff --git a/app/models/ssh_host_key.rb b/app/models/ssh_host_key.rb
index 72690ad7d04..7e34988c7a0 100644
--- a/app/models/ssh_host_key.rb
+++ b/app/models/ssh_host_key.rb
@@ -107,7 +107,7 @@ class SshHostKey
if status.success? && !errors.present?
{ known_hosts: known_hosts }
else
- Rails.logger.debug("Failed to detect SSH host keys for #{id}: #{errors}") # rubocop:disable Gitlab/RailsLogger
+ Gitlab::AppLogger.debug("Failed to detect SSH host keys for #{id}: #{errors}")
{ error: 'Failed to detect SSH host keys' }
end
diff --git a/app/models/storage/legacy_project.rb b/app/models/storage/legacy_project.rb
index 345172cca76..f643d52587e 100644
--- a/app/models/storage/legacy_project.rb
+++ b/app/models/storage/legacy_project.rb
@@ -35,7 +35,7 @@ module Storage
gitlab_shell.mv_repository(repository_storage, "#{old_full_path}.wiki", "#{new_full_path}.wiki")
return true
rescue => e
- Rails.logger.error "Exception renaming #{old_full_path} -> #{new_full_path}: #{e}" # rubocop:disable Gitlab/RailsLogger
+ Gitlab::AppLogger.error("Exception renaming #{old_full_path} -> #{new_full_path}: #{e}")
# Returning false does not rollback after_* transaction but gives
# us information about failing some of tasks
return false
diff --git a/app/models/terraform/state.rb b/app/models/terraform/state.rb
index c4e047ff9d1..6ed074b2190 100644
--- a/app/models/terraform/state.rb
+++ b/app/models/terraform/state.rb
@@ -2,6 +2,8 @@
module Terraform
class State < ApplicationRecord
+ include UsageStatistics
+
DEFAULT = '{"version":1}'.freeze
HEX_REGEXP = %r{\A\h+\z}.freeze
UUID_LENGTH = 32
diff --git a/app/models/todo.rb b/app/models/todo.rb
index dc42551f0ab..102f36a991e 100644
--- a/app/models/todo.rb
+++ b/app/models/todo.rb
@@ -66,6 +66,8 @@ class Todo < ApplicationRecord
scope :with_entity_associations, -> { preload(:target, :author, :note, group: :route, project: [:route, { namespace: :route }]) }
scope :joins_issue_and_assignees, -> { left_joins(issue: :assignees) }
+ enum resolved_by_action: { system_done: 0, api_all_done: 1, api_done: 2, mark_all_done: 3, mark_done: 4 }, _prefix: :resolved_by
+
state_machine :state, initial: :pending do
event :done do
transition [:pending] => :done
@@ -100,17 +102,17 @@ class Todo < ApplicationRecord
state.nil? ? exists?(target: target) : exists?(target: target, state: state)
end
- # Updates the state of a relation of todos to the new state.
+ # Updates attributes of a relation of todos to the new state.
#
- # new_state - The new state of the todos.
+ # new_attributes - The new attributes of the todos.
#
# Returns an `Array` containing the IDs of the updated todos.
- def update_state(new_state)
- # Only update those that are not really on that state
- base = where.not(state: new_state).except(:order)
+ def batch_update(**new_attributes)
+ # Only update those that have different state
+ base = where.not(state: new_attributes[:state]).except(:order)
ids = base.pluck(:id)
- base.update_all(state: new_state, updated_at: Time.now)
+ base.update_all(new_attributes.merge(updated_at: Time.current))
ids
end
@@ -187,6 +189,10 @@ class Todo < ApplicationRecord
target_type == DesignManagement::Design.name
end
+ def for_alert?
+ target_type == AlertManagement::Alert.name
+ end
+
# override to return commits, which are not active record
def target
if for_commit?
diff --git a/app/models/uploads/base.rb b/app/models/uploads/base.rb
index 442ed733566..7555c72e101 100644
--- a/app/models/uploads/base.rb
+++ b/app/models/uploads/base.rb
@@ -7,7 +7,7 @@ module Uploads
attr_reader :logger
def initialize(logger: nil)
- @logger = Rails.logger # rubocop:disable Gitlab/RailsLogger
+ @logger = Gitlab::AppLogger
end
def delete_keys_async(keys_to_delete)
diff --git a/app/models/user.rb b/app/models/user.rb
index 927ffa4d12b..431a5b3a5b7 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -69,7 +69,6 @@ class User < ApplicationRecord
MINIMUM_INACTIVE_DAYS = 180
- ignore_column :bot_type, remove_with: '13.1', remove_after: '2020-05-22'
ignore_column :ghost, remove_with: '13.2', remove_after: '2020-06-22'
# Override Devise::Models::Trackable#update_tracked_fields!
@@ -181,6 +180,8 @@ class User < ApplicationRecord
has_one :user_highest_role
has_one :user_canonical_email
+ has_many :reviews, foreign_key: :author_id, inverse_of: :author
+
#
# Validations
#
@@ -264,18 +265,21 @@ class User < ApplicationRecord
# User's role
enum role: { software_developer: 0, development_team_lead: 1, devops_engineer: 2, systems_administrator: 3, security_analyst: 4, data_analyst: 5, product_manager: 6, product_designer: 7, other: 8 }, _suffix: true
+ delegate :notes_filter_for,
+ :set_notes_filter,
+ :first_day_of_week, :first_day_of_week=,
+ :timezone, :timezone=,
+ :time_display_relative, :time_display_relative=,
+ :time_format_in_24h, :time_format_in_24h=,
+ :show_whitespace_in_diffs, :show_whitespace_in_diffs=,
+ :tab_width, :tab_width=,
+ :sourcegraph_enabled, :sourcegraph_enabled=,
+ :setup_for_company, :setup_for_company=,
+ :render_whitespace_in_code, :render_whitespace_in_code=,
+ :experience_level, :experience_level=,
+ to: :user_preference
+
delegate :path, to: :namespace, allow_nil: true, prefix: true
- delegate :notes_filter_for, to: :user_preference
- delegate :set_notes_filter, to: :user_preference
- delegate :first_day_of_week, :first_day_of_week=, to: :user_preference
- delegate :timezone, :timezone=, to: :user_preference
- delegate :time_display_relative, :time_display_relative=, to: :user_preference
- delegate :time_format_in_24h, :time_format_in_24h=, to: :user_preference
- delegate :show_whitespace_in_diffs, :show_whitespace_in_diffs=, to: :user_preference
- delegate :tab_width, :tab_width=, to: :user_preference
- delegate :sourcegraph_enabled, :sourcegraph_enabled=, to: :user_preference
- delegate :setup_for_company, :setup_for_company=, to: :user_preference
- delegate :render_whitespace_in_code, :render_whitespace_in_code=, to: :user_preference
delegate :job_title, :job_title=, to: :user_detail, allow_nil: true
accepts_nested_attributes_for :user_preference, update_only: true
@@ -342,6 +346,7 @@ class User < ApplicationRecord
where('EXISTS (?)',
::PersonalAccessToken
.where('personal_access_tokens.user_id = users.id')
+ .without_impersonation
.expiring_and_not_notified(at).select(1))
end
scope :order_recent_sign_in, -> { reorder(Gitlab::Database.nulls_last_order('current_sign_in_at', 'DESC')) }
@@ -517,7 +522,7 @@ class User < ApplicationRecord
# Searches users matching the given query.
#
- # This method uses ILIKE on PostgreSQL and LIKE on MySQL.
+ # This method uses ILIKE on PostgreSQL.
#
# query - The search query as a String
#
@@ -560,7 +565,7 @@ class User < ApplicationRecord
# searches user by given pattern
# it compares name, email, username fields and user's secondary emails with given pattern
- # This method uses ILIKE on PostgreSQL and LIKE on MySQL.
+ # This method uses ILIKE on PostgreSQL.
def search_with_secondary_emails(query)
return none if query.blank?
@@ -689,7 +694,7 @@ class User < ApplicationRecord
@reset_token, enc = Devise.token_generator.generate(self.class, :reset_password_token)
self.reset_password_token = enc
- self.reset_password_sent_at = Time.now.utc
+ self.reset_password_sent_at = Time.current.utc
@reset_token
end
@@ -716,7 +721,7 @@ class User < ApplicationRecord
otp_grace_period_started_at: nil,
otp_backup_codes: nil
)
- self.u2f_registrations.destroy_all # rubocop: disable DestroyAll
+ self.u2f_registrations.destroy_all # rubocop: disable Cop/DestroyAll
end
end
@@ -957,11 +962,11 @@ class User < ApplicationRecord
end
def allow_password_authentication_for_web?
- Gitlab::CurrentSettings.password_authentication_enabled_for_web? && !ldap_user? && !ultraauth_user?
+ Gitlab::CurrentSettings.password_authentication_enabled_for_web? && !ldap_user?
end
def allow_password_authentication_for_git?
- Gitlab::CurrentSettings.password_authentication_enabled_for_git? && !ldap_user? && !ultraauth_user?
+ Gitlab::CurrentSettings.password_authentication_enabled_for_git? && !ldap_user?
end
def can_change_username?
@@ -1049,14 +1054,6 @@ class User < ApplicationRecord
end
end
- def ultraauth_user?
- if identities.loaded?
- identities.find { |identity| Gitlab::Auth::OAuth::Provider.ultraauth_provider?(identity.provider) && !identity.extern_uid.nil? }
- else
- identities.exists?(["provider = ? AND extern_uid IS NOT NULL", "ultraauth"])
- end
- end
-
def ldap_identity
@ldap_identity ||= identities.find_by(["provider LIKE ?", "ldap%"])
end
@@ -1129,7 +1126,7 @@ class User < ApplicationRecord
if !Gitlab.config.ldap.enabled
false
elsif ldap_user?
- !last_credential_check_at || (last_credential_check_at + ldap_sync_time) < Time.now
+ !last_credential_check_at || (last_credential_check_at + ldap_sync_time) < Time.current
else
false
end
@@ -1378,7 +1375,7 @@ class User < ApplicationRecord
def contributed_projects
events = Event.select(:project_id)
.contributions.where(author_id: self)
- .where("created_at > ?", Time.now - 1.year)
+ .where("created_at > ?", Time.current - 1.year)
.distinct
.reorder(nil)
@@ -1642,16 +1639,12 @@ class User < ApplicationRecord
super.presence || build_user_detail
end
- def todos_limited_to(ids)
- todos.where(id: ids)
- end
-
def pending_todo_for(target)
todos.find_by(target: target, state: :pending)
end
def password_expired?
- !!(password_expires_at && password_expires_at < Time.now)
+ !!(password_expires_at && password_expires_at < Time.current)
end
def can_be_deactivated?
@@ -1832,7 +1825,7 @@ class User < ApplicationRecord
def update_highest_role?
return false unless persisted?
- (previous_changes.keys & %w(state user_type ghost)).any?
+ (previous_changes.keys & %w(state user_type)).any?
end
def update_highest_role_attribute
diff --git a/app/models/user_interacted_project.rb b/app/models/user_interacted_project.rb
index f6f72f4b77a..1c615777018 100644
--- a/app/models/user_interacted_project.rb
+++ b/app/models/user_interacted_project.rb
@@ -9,9 +9,6 @@ class UserInteractedProject < ApplicationRecord
CACHE_EXPIRY_TIME = 1.day
- # Schema version required for this model
- REQUIRED_SCHEMA_VERSION = 20180223120443
-
class << self
def track(event)
# For events without a project, we simply don't care.
@@ -38,17 +35,6 @@ class UserInteractedProject < ApplicationRecord
end
end
- # Check if we can safely call .track (table exists)
- def available?
- @available_flag ||= ActiveRecord::Migrator.current_version >= REQUIRED_SCHEMA_VERSION # rubocop:disable Gitlab/PredicateMemoization
- end
-
- # Flushes cached information about schema
- def reset_column_information
- @available_flag = nil
- super
- end
-
private
def cached_exists?(project_id:, user_id:, &block)
diff --git a/app/models/user_preference.rb b/app/models/user_preference.rb
index 48a56cded0e..d3b3a46bf74 100644
--- a/app/models/user_preference.rb
+++ b/app/models/user_preference.rb
@@ -15,6 +15,8 @@ class UserPreference < ApplicationRecord
less_than_or_equal_to: Gitlab::TabWidth::MAX
}
+ enum experience_level: { novice: 0, experienced: 1 }
+
default_value_for :tab_width, value: Gitlab::TabWidth::DEFAULT, allows_nil: false
default_value_for :timezone, value: Time.zone.tzinfo.name, allows_nil: false
default_value_for :time_display_relative, value: true, allows_nil: false
diff --git a/app/models/web_ide_terminal.rb b/app/models/web_ide_terminal.rb
new file mode 100644
index 00000000000..ef70df2405f
--- /dev/null
+++ b/app/models/web_ide_terminal.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+class WebIdeTerminal
+ include ::Gitlab::Routing
+
+ attr_reader :build, :project
+
+ delegate :id, :status, to: :build
+
+ def initialize(build)
+ @build = build
+ @project = build.project
+ end
+
+ def show_path
+ web_ide_terminal_route_generator(:show)
+ end
+
+ def retry_path
+ web_ide_terminal_route_generator(:retry)
+ end
+
+ def cancel_path
+ web_ide_terminal_route_generator(:cancel)
+ end
+
+ def terminal_path
+ terminal_project_job_path(project, build, format: :ws)
+ end
+
+ def proxy_websocket_path
+ proxy_project_job_path(project, build, format: :ws)
+ end
+
+ def services
+ build.services.map(&:alias).compact + Array(build.image&.alias)
+ end
+
+ private
+
+ def web_ide_terminal_route_generator(action, options = {})
+ options.reverse_merge!(action: action,
+ controller: 'projects/web_ide_terminals',
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ id: build.id,
+ only_path: true)
+
+ url_for(options)
+ end
+end
diff --git a/app/models/wiki.rb b/app/models/wiki.rb
index 54bcec32095..4c497cc304c 100644
--- a/app/models/wiki.rb
+++ b/app/models/wiki.rb
@@ -205,7 +205,7 @@ class Wiki
end
def wiki_base_path
- Gitlab.config.gitlab.relative_url_root + web_url(only_path: true).sub(%r{/#{Wiki::HOMEPAGE}\z}, '')
+ web_url(only_path: true).sub(%r{/#{Wiki::HOMEPAGE}\z}, '')
end
private
diff --git a/app/models/wiki_directory.rb b/app/models/wiki_directory.rb
index 712ba79bbd2..df2fe25b08b 100644
--- a/app/models/wiki_directory.rb
+++ b/app/models/wiki_directory.rb
@@ -15,6 +15,6 @@ class WikiDirectory
# Relative path to the partial to be used when rendering collections
# of this object.
def to_partial_path
- 'projects/wikis/wiki_directory'
+ '../shared/wikis/wiki_directory'
end
end
diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb
index 319cdd38d93..9e4e2f68d38 100644
--- a/app/models/wiki_page.rb
+++ b/app/models/wiki_page.rb
@@ -261,8 +261,7 @@ class WikiPage
# Relative path to the partial to be used when rendering collections
# of this object.
def to_partial_path
- # TODO: Move into shared/ with https://gitlab.com/gitlab-org/gitlab/-/issues/196054
- 'projects/wikis/wiki_page'
+ '../shared/wikis/wiki_page'
end
def id
@@ -271,7 +270,10 @@ class WikiPage
def title_changed?
if persisted?
- old_title, old_dir = wiki.page_title_and_dir(self.class.unhyphenize(page.url_path))
+ # A page's `title` will be returned from Gollum/Gitaly with any +<>
+ # characters changed to -, whereas the `path` preserves these characters.
+ path_without_extension = Pathname(page.path).sub_ext('').to_s
+ old_title, old_dir = wiki.page_title_and_dir(self.class.unhyphenize(path_without_extension))
new_title, new_dir = wiki.page_title_and_dir(self.class.unhyphenize(title))
new_title != old_title || (title.include?('/') && new_dir != old_dir)
diff --git a/app/models/wiki_page/meta.rb b/app/models/wiki_page/meta.rb
index 474968122b1..215d84dc463 100644
--- a/app/models/wiki_page/meta.rb
+++ b/app/models/wiki_page/meta.rb
@@ -120,7 +120,7 @@ class WikiPage
end
def insert_slugs(strings, is_new, canonical_slug)
- creation = Time.now.utc
+ creation = Time.current.utc
slug_attrs = strings.map do |slug|
{
diff --git a/app/models/wiki_page/slug.rb b/app/models/wiki_page/slug.rb
index 246fa8d6442..c1725d34921 100644
--- a/app/models/wiki_page/slug.rb
+++ b/app/models/wiki_page/slug.rb
@@ -16,11 +16,11 @@ class WikiPage
scope :canonical, -> { where(canonical: true) }
def update_columns(attrs = {})
- super(attrs.reverse_merge(updated_at: Time.now.utc))
+ super(attrs.reverse_merge(updated_at: Time.current.utc))
end
def self.update_all(attrs = {})
- super(attrs.reverse_merge(updated_at: Time.now.utc))
+ super(attrs.reverse_merge(updated_at: Time.current.utc))
end
end
end
diff --git a/app/policies/ci/build_policy.rb b/app/policies/ci/build_policy.rb
index 12892a69257..0879a740f8a 100644
--- a/app/policies/ci/build_policy.rb
+++ b/app/policies/ci/build_policy.rb
@@ -36,6 +36,10 @@ module Ci
@subject.has_terminal?
end
+ condition(:is_web_ide_terminal, scope: :subject) do
+ @subject.pipeline.webide?
+ end
+
rule { protected_ref | archived }.policy do
prevent :update_build
prevent :update_commit_status
@@ -50,6 +54,24 @@ module Ci
end
rule { can?(:update_build) & terminal }.enable :create_build_terminal
+
+ rule { is_web_ide_terminal & can?(:create_web_ide_terminal) & (admin | owner_of_job) }.policy do
+ enable :read_web_ide_terminal
+ enable :update_web_ide_terminal
+ end
+
+ rule { is_web_ide_terminal & ~can?(:update_web_ide_terminal) }.policy do
+ prevent :create_build_terminal
+ end
+
+ rule { can?(:update_web_ide_terminal) & terminal }.policy do
+ enable :create_build_terminal
+ enable :create_build_service_proxy
+ end
+
+ rule { ~can?(:build_service_proxy_enabled) }.policy do
+ prevent :create_build_service_proxy
+ end
end
end
diff --git a/app/policies/container_expiration_policy_policy.rb b/app/policies/container_expiration_policy_policy.rb
new file mode 100644
index 00000000000..709435f47d3
--- /dev/null
+++ b/app/policies/container_expiration_policy_policy.rb
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+
+class ContainerExpirationPolicyPolicy < BasePolicy
+ delegate { @subject.project }
+end
diff --git a/app/policies/draft_note_policy.rb b/app/policies/draft_note_policy.rb
new file mode 100644
index 00000000000..be99d12c5f8
--- /dev/null
+++ b/app/policies/draft_note_policy.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class DraftNotePolicy < BasePolicy
+ delegate { @subject.merge_request }
+
+ condition(:is_author) { @user && @subject.author == @user }
+
+ rule { is_author }.policy do
+ enable :read_note
+ enable :admin_note
+ enable :resolve_note
+ end
+end
diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb
index 8df4fc5e88c..f87c72007ec 100644
--- a/app/policies/project_policy.rb
+++ b/app/policies/project_policy.rb
@@ -147,6 +147,10 @@ class ProjectPolicy < BasePolicy
@user && @user.confirmed?
end
+ condition(:build_service_proxy_enabled) do
+ ::Feature.enabled?(:build_service_proxy, @subject)
+ end
+
features = %w[
merge_requests
issues
@@ -278,7 +282,6 @@ class ProjectPolicy < BasePolicy
rule { can?(:metrics_dashboard) }.policy do
enable :read_prometheus
- enable :read_environment
enable :read_deployment
end
@@ -429,27 +432,11 @@ class ProjectPolicy < BasePolicy
rule { builds_disabled | repository_disabled }.policy do
prevent(*create_read_update_admin_destroy(:build))
prevent(*create_read_update_admin_destroy(:pipeline_schedule))
+ prevent(*create_read_update_admin_destroy(:environment))
prevent(*create_read_update_admin_destroy(:cluster))
prevent(*create_read_update_admin_destroy(:deployment))
end
- # Enabling `read_environment` specifically for the condition of `metrics_dashboard_allowed` is
- # necessary due to the route for metrics dashboard requiring an environment id.
- # This will be addressed in https://gitlab.com/gitlab-org/gitlab/-/issues/213833 when
- # environments and metrics are decoupled and these rules will be removed.
-
- rule { (builds_disabled | repository_disabled) & ~metrics_dashboard_allowed}.policy do
- prevent(*create_read_update_admin_destroy(:environment))
- end
-
- rule { (builds_disabled | repository_disabled) & metrics_dashboard_allowed}.policy do
- prevent :create_environment
- prevent :update_environment
- prevent :admin_environment
- prevent :destroy_environment
- enable :read_environment
- end
-
# There's two separate cases when builds_disabled is true:
# 1. When internal CI is disabled - builds_disabled && internal_builds_disabled
# - We do not prevent the user from accessing Pipelines to allow them to access external CI
@@ -577,6 +564,18 @@ class ProjectPolicy < BasePolicy
enable :read_project
end
+ rule { can?(:create_pipeline) & can?(:maintainer_access) }.enable :create_web_ide_terminal
+
+ rule { build_service_proxy_enabled }.enable :build_service_proxy_enabled
+
+ rule { can?(:download_code) }.policy do
+ enable :read_repository_graphs
+ end
+
+ rule { can?(:read_build) & can?(:read_pipeline) }.policy do
+ enable :read_build_report_results
+ end
+
private
def team_member?
diff --git a/app/policies/releases/link_policy.rb b/app/policies/releases/link_policy.rb
new file mode 100644
index 00000000000..4a662fafb2f
--- /dev/null
+++ b/app/policies/releases/link_policy.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+module Releases
+ class LinkPolicy < BasePolicy
+ delegate { @subject.release.project }
+ end
+end
diff --git a/app/policies/releases/source_policy.rb b/app/policies/releases/source_policy.rb
new file mode 100644
index 00000000000..8b86b925589
--- /dev/null
+++ b/app/policies/releases/source_policy.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Releases
+ class SourcePolicy < BasePolicy
+ delegate { @subject.project }
+
+ rule { can?(:public_access) | can?(:reporter_access) }.policy do
+ enable :read_release_sources
+ end
+
+ rule { ~can?(:read_release) }.prevent :read_release_sources
+ end
+end
diff --git a/app/presenters/gitlab/blame_presenter.rb b/app/presenters/gitlab/blame_presenter.rb
new file mode 100644
index 00000000000..db2fc52a88b
--- /dev/null
+++ b/app/presenters/gitlab/blame_presenter.rb
@@ -0,0 +1,82 @@
+# frozen_string_literal: true
+
+module Gitlab
+ class BlamePresenter < Gitlab::View::Presenter::Simple
+ include ActionView::Helpers::UrlHelper
+ include ActionView::Helpers::TranslationHelper
+ include ActionView::Context
+ include AvatarsHelper
+ include BlameHelper
+ include CommitsHelper
+ include ApplicationHelper
+ include TreeHelper
+ include IconsHelper
+
+ presents :blame
+
+ CommitData = Struct.new(
+ :author_avatar,
+ :age_map_class,
+ :commit_link,
+ :commit_author_link,
+ :project_blame_link,
+ :time_ago_tooltip)
+
+ def initialize(subject, **attributes)
+ super
+
+ @commits = {}
+ precalculate_data_by_commit!
+ end
+
+ def groups
+ @groups ||= blame.groups
+ end
+
+ def commit_data(commit)
+ @commits[commit.id] ||= get_commit_data(commit)
+ end
+
+ private
+
+ # Huge source files with a high churn rate (e.g. 'locale/gitlab.pot') could have
+ # 10x times more blame groups than unique commits across all the groups.
+ # That means we could cache per-commit data we need
+ # to avoid recalculating it multiple times.
+ # For such files, it could significantly improve the performance of the Blame.
+ def precalculate_data_by_commit!
+ groups.each { |group| commit_data(group[:commit]) }
+ end
+
+ def get_commit_data(commit)
+ CommitData.new.tap do |data|
+ data.author_avatar = author_avatar(commit, size: 36, has_tooltip: false)
+ data.age_map_class = age_map_class(commit.committed_date, project_duration)
+ data.commit_link = link_to commit.title, project_commit_path(project, commit.id), class: "cdark", title: commit.title
+ data.commit_author_link = commit_author_link(commit, avatar: false)
+ data.project_blame_link = project_blame_link(commit)
+ data.time_ago_tooltip = time_ago_with_tooltip(commit.committed_date)
+ end
+ end
+
+ def project_blame_link(commit)
+ previous_commit_id = commit.parent_id
+ return unless previous_commit_id
+
+ link_to project_blame_path(project, tree_join(previous_commit_id, path)),
+ title: _('View blame prior to this change'),
+ aria: { label: _('View blame prior to this change') },
+ data: { toggle: 'tooltip', placement: 'right', container: 'body' } do
+ versions_sprite_icon
+ end
+ end
+
+ def project_duration
+ @project_duration ||= age_map_duration(groups, project)
+ end
+
+ def versions_sprite_icon
+ @versions_sprite_icon ||= sprite_icon('doc-versions', size: 16, css_class: 'doc-versions align-text-bottom')
+ end
+ end
+end
diff --git a/app/presenters/projects/prometheus/alert_presenter.rb b/app/presenters/projects/prometheus/alert_presenter.rb
index 2114e06a8c5..6009ee4c7be 100644
--- a/app/presenters/projects/prometheus/alert_presenter.rb
+++ b/app/presenters/projects/prometheus/alert_presenter.rb
@@ -45,8 +45,8 @@ module Projects
project_issues_url(project, label_name: INCIDENT_LABEL_NAME)
end
- def starts_at
- super&.rfc3339
+ def start_time
+ starts_at&.strftime('%d %B %Y, %-l:%M%p (%Z)')
end
def issue_summary_markdown
@@ -73,7 +73,7 @@ module Projects
def metadata_list
metadata = []
- metadata << list_item('Start time', starts_at) if starts_at
+ metadata << list_item('Start time', start_time) if start_time
metadata << list_item('full_query', backtick(full_query)) if full_query
metadata << list_item(service.label.humanize, service.value) if service
metadata << list_item(monitoring_tool.label.humanize, monitoring_tool.value) if monitoring_tool
@@ -149,7 +149,7 @@ module Projects
end
def embed_time
- starts_at ? Time.rfc3339(starts_at) : Time.current
+ starts_at || Time.current
end
def alert_embed_window_params(time)
diff --git a/app/presenters/release_presenter.rb b/app/presenters/release_presenter.rb
index ea46f0a234b..7b0a3d1e7b9 100644
--- a/app/presenters/release_presenter.rb
+++ b/app/presenters/release_presenter.rb
@@ -5,7 +5,7 @@ class ReleasePresenter < Gitlab::View::Presenter::Delegated
presents :release
- delegate :project, :tag, to: :release
+ delegate :project, :tag, :assets_count, to: :release
def commit_path
return unless release.commit && can_download_code?
diff --git a/app/presenters/snippet_presenter.rb b/app/presenters/snippet_presenter.rb
index faaf7568c72..62a90025ce1 100644
--- a/app/presenters/snippet_presenter.rb
+++ b/app/presenters/snippet_presenter.rb
@@ -36,10 +36,14 @@ class SnippetPresenter < Gitlab::View::Presenter::Delegated
end
def blob
+ blobs.first
+ end
+
+ def blobs
if snippet.empty_repo?
- snippet.blob
+ [snippet.blob]
else
- snippet.blobs.first
+ snippet.blobs
end
end
diff --git a/app/serializers/build_artifact_entity.rb b/app/serializers/build_artifact_entity.rb
index fac0fbd14b9..7a030372591 100644
--- a/app/serializers/build_artifact_entity.rb
+++ b/app/serializers/build_artifact_entity.rb
@@ -4,30 +4,28 @@ class BuildArtifactEntity < Grape::Entity
include RequestAwareEntity
include GitlabRoutingHelper
- expose :name do |job|
- job.name
- end
-
- expose :artifacts_expired?, as: :expired
- expose :artifacts_expire_at, as: :expire_at
+ alias_method :artifact, :object
- expose :path do |job|
- fast_download_project_job_artifacts_path(project, job)
+ expose :name do |artifact|
+ "#{artifact.job.name}:#{artifact.file_type}"
end
- expose :keep_path, if: -> (*) { job.has_expiring_archive_artifacts? } do |job|
- fast_keep_project_job_artifacts_path(project, job)
- end
+ expose :expire_at
+ expose :expired?, as: :expired
- expose :browse_path do |job|
- fast_browse_project_job_artifacts_path(project, job)
+ expose :path do |artifact|
+ fast_download_project_job_artifacts_path(
+ artifact.project,
+ artifact.job,
+ file_type: artifact.file_type
+ )
end
- private
-
- alias_method :job, :object
+ expose :keep_path, if: -> (*) { artifact.expiring? } do |artifact|
+ fast_keep_project_job_artifacts_path(artifact.project, artifact.job)
+ end
- def project
- job.project
+ expose :browse_path do |artifact|
+ fast_browse_project_job_artifacts_path(artifact.project, artifact.job)
end
end
diff --git a/app/serializers/ci/dag_job_entity.rb b/app/serializers/ci/dag_job_entity.rb
index b4947319ed1..ed4d4505152 100644
--- a/app/serializers/ci/dag_job_entity.rb
+++ b/app/serializers/ci/dag_job_entity.rb
@@ -3,6 +3,7 @@
module Ci
class DagJobEntity < Grape::Entity
expose :name
+ expose :scheduling_type
expose :needs, if: -> (job, _) { job.scheduling_type_dag? } do |job|
job.needs.pluck(:name) # rubocop: disable CodeReuse/ActiveRecord
diff --git a/app/serializers/ci/dag_pipeline_entity.rb b/app/serializers/ci/dag_pipeline_entity.rb
index b615dd2b194..51aa487ec29 100644
--- a/app/serializers/ci/dag_pipeline_entity.rb
+++ b/app/serializers/ci/dag_pipeline_entity.rb
@@ -2,12 +2,12 @@
module Ci
class DagPipelineEntity < Grape::Entity
- expose :ordered_stages_with_preloads, as: :stages, using: Ci::DagStageEntity
+ expose :stages_with_preloads, as: :stages, using: Ci::DagStageEntity
private
- def ordered_stages_with_preloads
- object.ordered_stages.preload(preloaded_relations) # rubocop: disable CodeReuse/ActiveRecord
+ def stages_with_preloads
+ object.stages.preload(preloaded_relations) # rubocop: disable CodeReuse/ActiveRecord
end
def preloaded_relations
diff --git a/app/serializers/ci/daily_build_group_report_result_entity.rb b/app/serializers/ci/daily_build_group_report_result_entity.rb
new file mode 100644
index 00000000000..e4118db9b1f
--- /dev/null
+++ b/app/serializers/ci/daily_build_group_report_result_entity.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Ci
+ class DailyBuildGroupReportResultEntity < Grape::Entity
+ expose :date
+
+ ::Ci::DailyBuildGroupReportResult::PARAM_TYPES.each do |type|
+ expose type, if: lambda { |report_result, options| options[:param_type] == type } do |report_result, options|
+ report_result.data[options[:param_type]]
+ end
+ end
+ end
+end
diff --git a/app/serializers/ci/daily_build_group_report_result_serializer.rb b/app/serializers/ci/daily_build_group_report_result_serializer.rb
new file mode 100644
index 00000000000..fdc693d01b2
--- /dev/null
+++ b/app/serializers/ci/daily_build_group_report_result_serializer.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module Ci
+ class DailyBuildGroupReportResultSerializer < BaseSerializer
+ entity ::Ci::DailyBuildGroupReportResultEntity
+
+ def represent(resource, opts = {})
+ group(resource).map do |group_name, data|
+ {
+ group_name: group_name,
+ data: super(data, opts)
+ }
+ end
+ end
+
+ private
+
+ def group(resource)
+ collect(resource).group_by(&:group_name)
+ end
+
+ def collect(resource)
+ return resource if resource.respond_to?(:group_by)
+
+ [resource]
+ end
+ end
+end
diff --git a/app/serializers/cluster_entity.rb b/app/serializers/cluster_entity.rb
index 4f53ea30544..8a1d41dbd96 100644
--- a/app/serializers/cluster_entity.rb
+++ b/app/serializers/cluster_entity.rb
@@ -8,6 +8,7 @@ class ClusterEntity < Grape::Entity
expose :environment_scope
expose :name
expose :nodes
+ expose :provider_type
expose :status_name, as: :status
expose :status_reason
expose :applications, using: ClusterApplicationEntity
diff --git a/app/serializers/cluster_serializer.rb b/app/serializers/cluster_serializer.rb
index f59b6a35a29..27156d3178f 100644
--- a/app/serializers/cluster_serializer.rb
+++ b/app/serializers/cluster_serializer.rb
@@ -13,6 +13,7 @@ class ClusterSerializer < BaseSerializer
:name,
:nodes,
:path,
+ :provider_type,
:status
]
})
diff --git a/app/serializers/container_repository_entity.rb b/app/serializers/container_repository_entity.rb
index 46aa0adc5a0..4c87d1438b0 100644
--- a/app/serializers/container_repository_entity.rb
+++ b/app/serializers/container_repository_entity.rb
@@ -3,7 +3,7 @@
class ContainerRepositoryEntity < Grape::Entity
include RequestAwareEntity
- expose :id, :name, :path, :location, :created_at, :status
+ expose :id, :name, :path, :location, :created_at, :status, :tags_count
expose :tags_path do |repository|
project_registry_repository_tags_path(project, repository, format: :json)
diff --git a/app/serializers/diff_file_base_entity.rb b/app/serializers/diff_file_base_entity.rb
index 8c2b3a65d57..33eb33d314b 100644
--- a/app/serializers/diff_file_base_entity.rb
+++ b/app/serializers/diff_file_base_entity.rb
@@ -67,10 +67,8 @@ class DiffFileBaseEntity < Grape::Entity
end
end
- expose :file_hash do |diff_file|
- Digest::SHA1.hexdigest(diff_file.file_path)
- end
-
+ expose :file_identifier_hash
+ expose :file_hash
expose :file_path
expose :old_path
expose :new_path
diff --git a/app/serializers/diff_file_metadata_entity.rb b/app/serializers/diff_file_metadata_entity.rb
index 05280518f39..460f4967e99 100644
--- a/app/serializers/diff_file_metadata_entity.rb
+++ b/app/serializers/diff_file_metadata_entity.rb
@@ -7,7 +7,6 @@ class DiffFileMetadataEntity < Grape::Entity
expose :old_path
expose :new_file?, as: :new_file
expose :deleted_file?, as: :deleted_file
- expose :file_hash do |diff_file|
- Digest::SHA1.hexdigest(diff_file.file_path)
- end
+ expose :file_identifier_hash
+ expose :file_hash
end
diff --git a/app/serializers/diffs_entity.rb b/app/serializers/diffs_entity.rb
index fb4fbe57130..6ef524b5bec 100644
--- a/app/serializers/diffs_entity.rb
+++ b/app/serializers/diffs_entity.rb
@@ -69,19 +69,17 @@ class DiffsEntity < Grape::Entity
expose :diff_files do |diffs, options|
submodule_links = Gitlab::SubmoduleLinks.new(merge_request.project.repository)
- code_navigation_path =
- Gitlab::CodeNavigationPath.new(merge_request.project, diffs.diff_refs.head_sha)
DiffFileEntity.represent(diffs.diff_files,
- options.merge(submodule_links: submodule_links, code_navigation_path: code_navigation_path))
+ options.merge(submodule_links: submodule_links, code_navigation_path: code_navigation_path(diffs)))
end
expose :merge_request_diffs, using: MergeRequestDiffEntity, if: -> (_, options) { options[:merge_request_diffs]&.any? } do |diffs|
options[:merge_request_diffs]
end
- expose :definition_path_prefix, if: -> (diff_file) { Feature.enabled?(:code_navigation, merge_request.project) } do |diffs|
- project_blob_path(merge_request.project, diffs.diff_refs.head_sha)
+ expose :definition_path_prefix, if: -> (diff_file) { Feature.enabled?(:code_navigation, merge_request.project, default_enabled: true) } do |diffs|
+ project_blob_path(merge_request.project, diffs.diff_refs&.head_sha)
end
def merge_request
@@ -90,6 +88,12 @@ class DiffsEntity < Grape::Entity
private
+ def code_navigation_path(diffs)
+ return unless Feature.enabled?(:code_navigation, merge_request.project, default_enabled: true)
+
+ Gitlab::CodeNavigationPath.new(merge_request.project, diffs.diff_refs&.head_sha)
+ end
+
def commit_ids
@commit_ids ||= merge_request.recent_commits.map(&:id)
end
diff --git a/app/serializers/draft_note_entity.rb b/app/serializers/draft_note_entity.rb
new file mode 100644
index 00000000000..cab4849ebc9
--- /dev/null
+++ b/app/serializers/draft_note_entity.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+class DraftNoteEntity < Grape::Entity
+ include RequestAwareEntity
+
+ expose :id
+ expose :author, using: NoteUserEntity
+ expose :merge_request_id
+ expose :position, if: -> (note, _) { note.on_diff? }
+ expose :line_code
+ expose :file_identifier_hash
+ expose :file_hash
+ expose :file_path
+ expose :note
+ expose :rendered_note, as: :note_html
+ expose :references
+ expose :discussion_id
+ expose :resolve_discussion
+ expose :noteable_type
+
+ expose :current_user do
+ expose :can_edit do |note|
+ can?(current_user, :admin_note, note)
+ end
+
+ expose :can_award_emoji do |note|
+ note.emoji_awardable?
+ end
+
+ expose :can_resolve do |note|
+ note.resolvable? && can?(current_user, :resolve_note, note)
+ end
+ end
+
+ private
+
+ def current_user
+ request.current_user
+ end
+end
diff --git a/app/serializers/draft_note_serializer.rb b/app/serializers/draft_note_serializer.rb
new file mode 100644
index 00000000000..282d7f9bdda
--- /dev/null
+++ b/app/serializers/draft_note_serializer.rb
@@ -0,0 +1,4 @@
+# frozen_string_literal: true
+class DraftNoteSerializer < BaseSerializer
+ entity DraftNoteEntity
+end
diff --git a/app/serializers/import/base_provider_repo_entity.rb b/app/serializers/import/base_provider_repo_entity.rb
new file mode 100644
index 00000000000..88a831a1686
--- /dev/null
+++ b/app/serializers/import/base_provider_repo_entity.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+class Import::BaseProviderRepoEntity < Grape::Entity
+ expose :id
+ expose :full_name
+ expose :sanitized_name
+ expose :provider_link
+end
diff --git a/app/serializers/import/bitbucket_provider_repo_entity.rb b/app/serializers/import/bitbucket_provider_repo_entity.rb
new file mode 100644
index 00000000000..e8c647d407e
--- /dev/null
+++ b/app/serializers/import/bitbucket_provider_repo_entity.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class Import::BitbucketProviderRepoEntity < Import::BaseProviderRepoEntity
+ expose :id, override: true do |repo|
+ repo.full_name
+ end
+
+ expose :sanitized_name, override: true do |repo|
+ repo.name.gsub(/[^\s\w.-]/, '')
+ end
+
+ expose :provider_link, override: true do |repo, options|
+ repo.clone_url
+ end
+end
diff --git a/app/serializers/import/bitbucket_server_provider_repo_entity.rb b/app/serializers/import/bitbucket_server_provider_repo_entity.rb
new file mode 100644
index 00000000000..d818cac46cd
--- /dev/null
+++ b/app/serializers/import/bitbucket_server_provider_repo_entity.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class Import::BitbucketServerProviderRepoEntity < Import::BitbucketProviderRepoEntity
+ expose :provider_link, override: true do |repo, options|
+ repo.browse_url
+ end
+end
diff --git a/app/serializers/import/fogbugz_provider_repo_entity.rb b/app/serializers/import/fogbugz_provider_repo_entity.rb
new file mode 100644
index 00000000000..d420de141e1
--- /dev/null
+++ b/app/serializers/import/fogbugz_provider_repo_entity.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class Import::FogbugzProviderRepoEntity < Import::BaseProviderRepoEntity
+ include ImportHelper
+
+ expose :full_name, override: true do |repo|
+ repo.name
+ end
+
+ expose :sanitized_name, override: true do |repo|
+ repo.safe_name
+ end
+
+ expose :provider_link, override: true do |repo, options|
+ provider_project_link_url(options[:provider_url], repo.path)
+ end
+end
diff --git a/app/serializers/import/githubish_provider_repo_entity.rb b/app/serializers/import/githubish_provider_repo_entity.rb
new file mode 100644
index 00000000000..d3e323053f9
--- /dev/null
+++ b/app/serializers/import/githubish_provider_repo_entity.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class Import::GithubishProviderRepoEntity < Import::BaseProviderRepoEntity
+ include ImportHelper
+
+ expose :sanitized_name, override: true do |provider_repo|
+ sanitize_project_name(provider_repo[:name])
+ end
+
+ expose :provider_link, override: true do |provider_repo, options|
+ provider_project_link_url(options[:provider_url], provider_repo[:full_name])
+ end
+
+ private
+
+ def owner_name(provider_repo, provider)
+ provider_repo.dig(:owner, :login) if provider == :github
+ end
+end
diff --git a/app/serializers/import/gitlab_provider_repo_entity.rb b/app/serializers/import/gitlab_provider_repo_entity.rb
new file mode 100644
index 00000000000..5fecd0a1cd3
--- /dev/null
+++ b/app/serializers/import/gitlab_provider_repo_entity.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class Import::GitlabProviderRepoEntity < Import::BaseProviderRepoEntity
+ expose :id, override: true do |repo|
+ repo["id"]
+ end
+
+ expose :full_name, override: true do |repo|
+ repo["path_with_namespace"]
+ end
+
+ expose :sanitized_name, override: true do |repo|
+ repo["path"]
+ end
+
+ expose :provider_link, override: true do |repo|
+ repo["web_url"]
+ end
+end
diff --git a/app/serializers/import/provider_repo_serializer.rb b/app/serializers/import/provider_repo_serializer.rb
new file mode 100644
index 00000000000..5a9549d79aa
--- /dev/null
+++ b/app/serializers/import/provider_repo_serializer.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class Import::ProviderRepoSerializer < BaseSerializer
+ def represent(repo, opts = {})
+ entity =
+ case opts[:provider]
+ when :fogbugz
+ Import::FogbugzProviderRepoEntity
+ when :github, :gitea
+ Import::GithubishProviderRepoEntity
+ when :bitbucket
+ Import::BitbucketProviderRepoEntity
+ when :bitbucket_server
+ Import::BitbucketServerProviderRepoEntity
+ when :gitlab
+ Import::GitlabProviderRepoEntity
+ else
+ raise NotImplementedError
+ end
+
+ super(repo, opts, entity)
+ end
+end
diff --git a/app/serializers/merge_request_noteable_entity.rb b/app/serializers/merge_request_noteable_entity.rb
index 8e7456ce059..a356b5b5cd4 100644
--- a/app/serializers/merge_request_noteable_entity.rb
+++ b/app/serializers/merge_request_noteable_entity.rb
@@ -50,6 +50,8 @@ class MergeRequestNoteableEntity < IssuableEntity
merge_request.project.archived?
end
+ expose :project_id
+
expose :archived_project_docs_path, if: -> (merge_request) { merge_request.project.archived? } do |merge_request|
help_page_path('user/project/settings/index.md', anchor: 'archiving-a-project')
end
diff --git a/app/serializers/paginated_diff_entity.rb b/app/serializers/paginated_diff_entity.rb
index a31c9d70d4b..37c48338e55 100644
--- a/app/serializers/paginated_diff_entity.rb
+++ b/app/serializers/paginated_diff_entity.rb
@@ -10,11 +10,9 @@ class PaginatedDiffEntity < Grape::Entity
expose :diff_files do |diffs, options|
submodule_links = Gitlab::SubmoduleLinks.new(merge_request.project.repository)
- code_navigation_path =
- Gitlab::CodeNavigationPath.new(merge_request.project, diffs.diff_refs.head_sha)
DiffFileEntity.represent(diffs.diff_files,
- options.merge(submodule_links: submodule_links, code_navigation_path: code_navigation_path))
+ options.merge(submodule_links: submodule_links, code_navigation_path: code_navigation_path(diffs)))
end
expose :pagination do
@@ -38,6 +36,12 @@ class PaginatedDiffEntity < Grape::Entity
private
+ def code_navigation_path(diffs)
+ return unless Feature.enabled?(:code_navigation, merge_request.project, default_enabled: true)
+
+ Gitlab::CodeNavigationPath.new(merge_request.project, diffs.diff_refs&.head_sha)
+ end
+
%i[current_page next_page total_pages].each do |method|
define_method method do
pagination_data[method]
diff --git a/app/serializers/pipeline_details_entity.rb b/app/serializers/pipeline_details_entity.rb
index a58278cf4ef..50efa9ea15d 100644
--- a/app/serializers/pipeline_details_entity.rb
+++ b/app/serializers/pipeline_details_entity.rb
@@ -9,8 +9,7 @@ class PipelineDetailsEntity < PipelineEntity
expose :details do
expose :artifacts do |pipeline, options|
- rel = pipeline.artifacts
- rel = rel.eager_load_job_artifacts_archive if options.fetch(:preload_job_artifacts_archive, true)
+ rel = pipeline.downloadable_artifacts
BuildArtifactEntity.represent(rel, options)
end
diff --git a/app/serializers/pipeline_serializer.rb b/app/serializers/pipeline_serializer.rb
index b2c0ceb640b..21d49c6c292 100644
--- a/app/serializers/pipeline_serializer.rb
+++ b/app/serializers/pipeline_serializer.rb
@@ -7,10 +7,6 @@ class PipelineSerializer < BaseSerializer
# rubocop: disable CodeReuse/ActiveRecord
def represent(resource, opts = {})
if resource.is_a?(ActiveRecord::Relation)
- # We don't want PipelineDetailsEntity to preload the job_artifacts_archive
- # because we do it with preloaded_relations in a more optimal way
- # if the given resource is a collection of multiple pipelines.
- opts[:preload_job_artifacts_archive] = false
resource = resource.preload(preloaded_relations)
end
@@ -44,35 +40,29 @@ class PipelineSerializer < BaseSerializer
def preloaded_relations
[
- :latest_statuses_ordered_by_stage,
- :project,
- :stages,
- {
- failed_builds: %i(project metadata)
- },
- :retryable_builds,
:cancelable_statuses,
- :trigger_requests,
+ :latest_statuses_ordered_by_stage,
:manual_actions,
+ :retryable_builds,
:scheduled_actions,
- :artifacts,
+ :stages,
+ :trigger_requests,
:user,
{
+ downloadable_artifacts: {
+ project: [:route, { namespace: :route }],
+ job: []
+ },
+ failed_builds: %i(project metadata),
merge_request: {
source_project: [:route, { namespace: :route }],
target_project: [:route, { namespace: :route }]
- }
- },
- {
+ },
pending_builds: :project,
project: [:route, { namespace: :route }],
- artifacts: {
- project: [:route, { namespace: :route }],
- job_artifacts_archive: []
- }
- },
- { triggered_by_pipeline: [:project, :user] },
- { triggered_pipelines: [:project, :user] }
+ triggered_by_pipeline: [:project, :user],
+ triggered_pipelines: [:project, :user]
+ }
]
end
end
diff --git a/app/serializers/provider_repo_entity.rb b/app/serializers/provider_repo_entity.rb
deleted file mode 100644
index d70aaa91324..00000000000
--- a/app/serializers/provider_repo_entity.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# frozen_string_literal: true
-
-class ProviderRepoEntity < Grape::Entity
- include ImportHelper
-
- expose :id
- expose :full_name
- expose :owner_name do |provider_repo, options|
- owner_name(provider_repo, options[:provider])
- end
-
- expose :sanitized_name do |provider_repo|
- sanitize_project_name(provider_repo[:name])
- end
-
- expose :provider_link do |provider_repo, options|
- provider_project_link_url(options[:provider_url], provider_repo[:full_name])
- end
-
- private
-
- def owner_name(provider_repo, provider)
- provider_repo.dig(:owner, :login) if provider == :github
- end
-end
diff --git a/app/serializers/provider_repo_serializer.rb b/app/serializers/provider_repo_serializer.rb
deleted file mode 100644
index 8a73f6fe6df..00000000000
--- a/app/serializers/provider_repo_serializer.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-# frozen_string_literal: true
-
-class ProviderRepoSerializer < BaseSerializer
- entity ProviderRepoEntity
-end
diff --git a/app/serializers/service_field_entity.rb b/app/serializers/service_field_entity.rb
new file mode 100644
index 00000000000..9929d7e2e5a
--- /dev/null
+++ b/app/serializers/service_field_entity.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+class ServiceFieldEntity < Grape::Entity
+ include RequestAwareEntity
+
+ expose :type, :name, :title, :placeholder, :required, :choices, :help
+
+ expose :value do |field|
+ # field[:name] is not user input and so can assume is safe
+ value = service.public_send(field[:name]) # rubocop:disable GitlabSecurity/PublicSend
+
+ if field[:type] == 'password' && value.present?
+ 'true'
+ else
+ value
+ end
+ end
+
+ private
+
+ def service
+ request.service
+ end
+end
diff --git a/app/serializers/service_field_serializer.rb b/app/serializers/service_field_serializer.rb
new file mode 100644
index 00000000000..120d0f5820e
--- /dev/null
+++ b/app/serializers/service_field_serializer.rb
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+
+class ServiceFieldSerializer < BaseSerializer
+ entity ServiceFieldEntity
+end
diff --git a/app/serializers/web_ide_terminal_entity.rb b/app/serializers/web_ide_terminal_entity.rb
new file mode 100644
index 00000000000..e2e90e824e7
--- /dev/null
+++ b/app/serializers/web_ide_terminal_entity.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+class WebIdeTerminalEntity < Grape::Entity
+ expose :id
+ expose :status
+ expose :show_path
+ expose :cancel_path
+ expose :retry_path
+ expose :terminal_path
+ expose :services
+ expose :proxy_websocket_path, if: ->(_) { Feature.enabled?(:build_service_proxy) }
+end
diff --git a/app/serializers/web_ide_terminal_serializer.rb b/app/serializers/web_ide_terminal_serializer.rb
new file mode 100644
index 00000000000..5a9c4b99e0a
--- /dev/null
+++ b/app/serializers/web_ide_terminal_serializer.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class WebIdeTerminalSerializer < BaseSerializer
+ entity WebIdeTerminalEntity
+
+ def represent(resource, opts = {})
+ resource = WebIdeTerminal.new(resource) if resource.is_a?(Ci::Build)
+
+ super
+ end
+end
diff --git a/app/services/admin/propagate_integration_service.rb b/app/services/admin/propagate_integration_service.rb
new file mode 100644
index 00000000000..084b103ee3b
--- /dev/null
+++ b/app/services/admin/propagate_integration_service.rb
@@ -0,0 +1,142 @@
+# frozen_string_literal: true
+
+module Admin
+ class PropagateIntegrationService
+ BATCH_SIZE = 100
+
+ delegate :data_fields_present?, to: :integration
+
+ def self.propagate(integration:, overwrite:)
+ new(integration, overwrite).propagate
+ end
+
+ def initialize(integration, overwrite)
+ @integration = integration
+ @overwrite = overwrite
+ end
+
+ def propagate
+ if overwrite
+ update_integration_for_all_projects
+ else
+ update_integration_for_inherited_projects
+ end
+
+ create_integration_for_projects_without_integration
+ end
+
+ private
+
+ attr_reader :integration, :overwrite
+
+ # rubocop: disable Cop/InBatches
+ # rubocop: disable CodeReuse/ActiveRecord
+ def update_integration_for_inherited_projects
+ Service.where(type: integration.type, inherit_from_id: integration.id).in_batches(of: BATCH_SIZE) do |batch|
+ bulk_update_from_integration(batch)
+ end
+ end
+
+ def update_integration_for_all_projects
+ Service.where(type: integration.type).in_batches(of: BATCH_SIZE) do |batch|
+ bulk_update_from_integration(batch)
+ end
+ end
+ # rubocop: enable Cop/InBatches
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def bulk_update_from_integration(batch)
+ # Retrieving the IDs instantiates the ActiveRecord relation (batch)
+ # into concrete models, otherwise update_all will clear the relation.
+ # https://stackoverflow.com/q/34811646/462015
+ batch_ids = batch.pluck(:id)
+
+ Service.transaction do
+ batch.update_all(service_hash)
+
+ if data_fields_present?
+ integration.data_fields.class.where(service_id: batch_ids).update_all(data_fields_hash)
+ end
+ end
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ def create_integration_for_projects_without_integration
+ loop do
+ batch = Project.uncached { project_ids_without_integration }
+
+ bulk_create_from_integration(batch) unless batch.empty?
+
+ break if batch.size < BATCH_SIZE
+ end
+ end
+
+ def bulk_create_from_integration(batch)
+ service_list = ServiceList.new(batch, service_hash, { 'inherit_from_id' => integration.id }).to_array
+
+ Project.transaction do
+ results = bulk_insert(*service_list)
+
+ if data_fields_present?
+ data_list = DataList.new(results, data_fields_hash, integration.data_fields.class).to_array
+
+ bulk_insert(*data_list)
+ end
+
+ run_callbacks(batch)
+ end
+ end
+
+ def bulk_insert(klass, columns, values_array)
+ items_to_insert = values_array.map { |array| Hash[columns.zip(array)] }
+
+ klass.insert_all(items_to_insert, returning: [:id])
+ end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def run_callbacks(batch)
+ if active_external_issue_tracker?
+ Project.where(id: batch).update_all(has_external_issue_tracker: true)
+ end
+
+ if active_external_wiki?
+ Project.where(id: batch).update_all(has_external_wiki: true)
+ end
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ def active_external_issue_tracker?
+ integration.issue_tracker? && !integration.default
+ end
+
+ def active_external_wiki?
+ integration.type == 'ExternalWikiService'
+ end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def project_ids_without_integration
+ services = Service
+ .select('1')
+ .where('services.project_id = projects.id')
+ .where(type: integration.type)
+
+ Project
+ .where('NOT EXISTS (?)', services)
+ .where(pending_delete: false)
+ .where(archived: false)
+ .limit(BATCH_SIZE)
+ .pluck(:id)
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ def service_hash
+ @service_hash ||= integration.to_service_hash
+ .tap { |json| json['inherit_from_id'] = integration.id }
+ end
+
+ def data_fields_hash
+ @data_fields_hash ||= integration.to_data_fields_hash
+ end
+ end
+end
diff --git a/app/services/alert_management/alerts/update_service.rb b/app/services/alert_management/alerts/update_service.rb
new file mode 100644
index 00000000000..ffabbb37289
--- /dev/null
+++ b/app/services/alert_management/alerts/update_service.rb
@@ -0,0 +1,98 @@
+# frozen_string_literal: true
+
+module AlertManagement
+ module Alerts
+ class UpdateService
+ include Gitlab::Utils::StrongMemoize
+
+ # @param alert [AlertManagement::Alert]
+ # @param current_user [User]
+ # @param params [Hash] Attributes of the alert
+ def initialize(alert, current_user, params)
+ @alert = alert
+ @current_user = current_user
+ @params = params
+ end
+
+ def execute
+ return error_no_permissions unless allowed?
+ return error_no_updates if params.empty?
+
+ filter_assignees
+ old_assignees = alert.assignees.to_a
+
+ if alert.update(params)
+ process_assignement(old_assignees)
+
+ success
+ else
+ error(alert.errors.full_messages.to_sentence)
+ end
+ end
+
+ private
+
+ attr_reader :alert, :current_user, :params
+
+ def allowed?
+ current_user&.can?(:update_alert_management_alert, alert)
+ end
+
+ def assignee_todo_allowed?
+ assignee&.can?(:read_alert_management_alert, alert)
+ end
+
+ def todo_service
+ strong_memoize(:todo_service) do
+ TodoService.new
+ end
+ end
+
+ def success
+ ServiceResponse.success(payload: { alert: alert })
+ end
+
+ def error(message)
+ ServiceResponse.error(payload: { alert: alert }, message: message)
+ end
+
+ def error_no_permissions
+ error(_('You have no permissions'))
+ end
+
+ def error_no_updates
+ error(_('Please provide attributes to update'))
+ end
+
+ # ----- Assignee-related behavior ------
+ def filter_assignees
+ return if params[:assignees].nil?
+
+ params[:assignees] = Array(assignee)
+ end
+
+ def assignee
+ strong_memoize(:assignee) do
+ # Take first assignee while multiple are not currently supported
+ params[:assignees]&.first
+ end
+ end
+
+ def process_assignement(old_assignees)
+ assign_todo
+ add_assignee_system_note(old_assignees)
+ end
+
+ def assign_todo
+ # Remove check in follow-up issue https://gitlab.com/gitlab-org/gitlab/-/issues/222672
+ return unless assignee_todo_allowed?
+
+ todo_service.assign_alert(alert, current_user)
+ end
+
+ def add_assignee_system_note(old_assignees)
+ SystemNoteService.change_issuable_assignees(alert, alert.project, current_user, old_assignees)
+ end
+ end
+ end
+end
diff --git a/app/services/alert_management/create_alert_issue_service.rb b/app/services/alert_management/create_alert_issue_service.rb
index 0197f29145d..beacd240b08 100644
--- a/app/services/alert_management/create_alert_issue_service.rb
+++ b/app/services/alert_management/create_alert_issue_service.rb
@@ -29,8 +29,7 @@ module AlertManagement
delegate :project, to: :alert
def allowed?
- Feature.enabled?(:alert_management_create_alert_issue, project) &&
- user.can?(:create_issue, project)
+ user.can?(:create_issue, project)
end
def create_issue(alert, user, alert_payload)
diff --git a/app/services/alert_management/process_prometheus_alert_service.rb b/app/services/alert_management/process_prometheus_alert_service.rb
index af28f1354b3..90fcbd95e4b 100644
--- a/app/services/alert_management/process_prometheus_alert_service.rb
+++ b/app/services/alert_management/process_prometheus_alert_service.rb
@@ -29,6 +29,7 @@ module AlertManagement
def process_firing_alert_management_alert
if am_alert.present?
+ am_alert.register_new_event!
reset_alert_management_alert_status
else
create_alert_management_alert
@@ -47,7 +48,10 @@ module AlertManagement
def create_alert_management_alert
am_alert = AlertManagement::Alert.new(am_alert_params.merge(ended_at: nil))
- return if am_alert.save
+ if am_alert.save
+ am_alert.execute_services
+ return
+ end
logger.warn(
message: 'Unable to create AlertManagement::Alert',
diff --git a/app/services/auto_merge/base_service.rb b/app/services/auto_merge/base_service.rb
index 1de2f31f87c..c4109765a1c 100644
--- a/app/services/auto_merge/base_service.rb
+++ b/app/services/auto_merge/base_service.rb
@@ -6,19 +6,18 @@ module AutoMerge
include MergeRequests::AssignsMergeParams
def execute(merge_request)
- assign_allowed_merge_params(merge_request, params.merge(auto_merge_strategy: strategy))
-
- merge_request.auto_merge_enabled = true
- merge_request.merge_user = current_user
-
- return :failed unless merge_request.save
-
- yield if block_given?
+ ActiveRecord::Base.transaction do
+ register_auto_merge_parameters!(merge_request)
+ yield if block_given?
+ end
# Notify the event that auto merge is enabled or merge param is updated
AutoMergeProcessWorker.perform_async(merge_request.id)
strategy.to_sym
+ rescue => e
+ track_exception(e, merge_request)
+ :failed
end
def update(merge_request)
@@ -30,23 +29,27 @@ module AutoMerge
end
def cancel(merge_request)
- if clear_auto_merge_parameters(merge_request)
+ ActiveRecord::Base.transaction do
+ clear_auto_merge_parameters!(merge_request)
yield if block_given?
-
- success
- else
- error("Can't cancel the automatic merge", 406)
end
+
+ success
+ rescue => e
+ track_exception(e, merge_request)
+ error("Can't cancel the automatic merge", 406)
end
def abort(merge_request, reason)
- if clear_auto_merge_parameters(merge_request)
+ ActiveRecord::Base.transaction do
+ clear_auto_merge_parameters!(merge_request)
yield if block_given?
-
- success
- else
- error("Can't abort the automatic merge", 406)
end
+
+ success
+ rescue => e
+ track_exception(e, merge_request)
+ error("Can't abort the automatic merge", 406)
end
def available_for?(merge_request)
@@ -65,7 +68,14 @@ module AutoMerge
end
end
- def clear_auto_merge_parameters(merge_request)
+ def register_auto_merge_parameters!(merge_request)
+ assign_allowed_merge_params(merge_request, params.merge(auto_merge_strategy: strategy))
+ merge_request.auto_merge_enabled = true
+ merge_request.merge_user = current_user
+ merge_request.save!
+ end
+
+ def clear_auto_merge_parameters!(merge_request)
merge_request.auto_merge_enabled = false
merge_request.merge_user = nil
@@ -76,7 +86,11 @@ module AutoMerge
'auto_merge_strategy'
)
- merge_request.save
+ merge_request.save!
+ end
+
+ def track_exception(error, merge_request)
+ Gitlab::ErrorTracking.track_exception(error, merge_request_id: merge_request&.id)
end
end
end
diff --git a/app/services/award_emojis/destroy_service.rb b/app/services/award_emojis/destroy_service.rb
index a61a7911a9d..cfd194262f9 100644
--- a/app/services/award_emojis/destroy_service.rb
+++ b/app/services/award_emojis/destroy_service.rb
@@ -13,7 +13,7 @@ module AwardEmojis
return error("User has not awarded emoji of type #{name} on the awardable", status: :forbidden)
end
- award = awards.destroy_all.first # rubocop: disable DestroyAll
+ award = awards.destroy_all.first # rubocop: disable Cop/DestroyAll
after_destroy(award)
success(award: award)
diff --git a/app/services/ci/authorize_job_artifact_service.rb b/app/services/ci/authorize_job_artifact_service.rb
new file mode 100644
index 00000000000..893e92d427c
--- /dev/null
+++ b/app/services/ci/authorize_job_artifact_service.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+module Ci
+ class AuthorizeJobArtifactService
+ include Gitlab::Utils::StrongMemoize
+
+ # Max size of the zipped LSIF artifact
+ LSIF_ARTIFACT_MAX_SIZE = 20.megabytes
+ LSIF_ARTIFACT_TYPE = 'lsif'
+
+ def initialize(job, params, max_size:)
+ @job = job
+ @max_size = max_size
+ @size = params[:filesize]
+ @type = params[:artifact_type].to_s
+ end
+
+ def forbidden?
+ lsif? && !code_navigation_enabled?
+ end
+
+ def too_large?
+ size && max_size <= size.to_i
+ end
+
+ def headers
+ default_headers = JobArtifactUploader.workhorse_authorize(has_length: false, maximum_size: max_size)
+ default_headers.tap do |h|
+ h[:ProcessLsif] = true if lsif? && code_navigation_enabled?
+ end
+ end
+
+ private
+
+ attr_reader :job, :size, :type
+
+ def code_navigation_enabled?
+ strong_memoize(:code_navigation_enabled) do
+ Feature.enabled?(:code_navigation, job.project, default_enabled: true)
+ end
+ end
+
+ def lsif?
+ strong_memoize(:lsif) do
+ type == LSIF_ARTIFACT_TYPE
+ end
+ end
+
+ def max_size
+ lsif? ? LSIF_ARTIFACT_MAX_SIZE : @max_size.to_i
+ end
+ end
+end
diff --git a/app/services/ci/build_report_result_service.rb b/app/services/ci/build_report_result_service.rb
new file mode 100644
index 00000000000..758ba1c73bf
--- /dev/null
+++ b/app/services/ci/build_report_result_service.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module Ci
+ class BuildReportResultService
+ def execute(build)
+ return unless Feature.enabled?(:build_report_summary, build.project)
+ return unless build.has_test_reports?
+
+ build.report_results.create!(
+ project_id: build.project_id,
+ data: tests_params(build)
+ )
+ end
+
+ private
+
+ def generate_test_suite_report(build)
+ build.collect_test_reports!(Gitlab::Ci::Reports::TestReports.new)
+ end
+
+ def tests_params(build)
+ test_suite = generate_test_suite_report(build)
+
+ {
+ tests: {
+ name: test_suite.name,
+ duration: test_suite.total_time,
+ failed: test_suite.failed_count,
+ errored: test_suite.error_count,
+ skipped: test_suite.skipped_count,
+ success: test_suite.success_count
+ }
+ }
+ end
+ end
+end
diff --git a/app/services/ci/create_cross_project_pipeline_service.rb b/app/services/ci/create_cross_project_pipeline_service.rb
index a73a2e2b471..1700312b941 100644
--- a/app/services/ci/create_cross_project_pipeline_service.rb
+++ b/app/services/ci/create_cross_project_pipeline_service.rb
@@ -47,6 +47,7 @@ module Ci
# and update the status when the downstream pipeline completes.
subject.success! unless subject.dependent?
else
+ subject.options[:downstream_errors] = pipeline.errors.full_messages
subject.drop!(:downstream_pipeline_creation_failed)
end
end
diff --git a/app/services/ci/create_web_ide_terminal_service.rb b/app/services/ci/create_web_ide_terminal_service.rb
new file mode 100644
index 00000000000..29d40756ab4
--- /dev/null
+++ b/app/services/ci/create_web_ide_terminal_service.rb
@@ -0,0 +1,123 @@
+# frozen_string_literal: true
+
+module Ci
+ class CreateWebIdeTerminalService < ::BaseService
+ include ::Gitlab::Utils::StrongMemoize
+
+ TerminalCreationError = Class.new(StandardError)
+
+ TERMINAL_NAME = 'terminal'.freeze
+
+ attr_reader :terminal
+
+ def execute
+ check_access!
+ validate_params!
+ load_terminal_config!
+
+ pipeline = create_pipeline!
+ success(pipeline: pipeline)
+ rescue TerminalCreationError => e
+ error(e.message)
+ rescue ActiveRecord::RecordInvalid => e
+ error("Failed to persist the pipeline: #{e.message}")
+ end
+
+ private
+
+ def create_pipeline!
+ build_pipeline.tap do |pipeline|
+ pipeline.stages << terminal_stage_seed(pipeline).to_resource
+ pipeline.save!
+
+ Ci::ProcessPipelineService
+ .new(pipeline)
+ .execute(nil, initial_process: true)
+
+ pipeline_created_counter.increment(source: :webide)
+ end
+ end
+
+ def build_pipeline
+ Ci::Pipeline.new(
+ project: project,
+ user: current_user,
+ source: :webide,
+ config_source: :webide_source,
+ ref: ref,
+ sha: sha,
+ tag: false,
+ before_sha: Gitlab::Git::BLANK_SHA
+ )
+ end
+
+ def terminal_stage_seed(pipeline)
+ attributes = {
+ name: TERMINAL_NAME,
+ index: 0,
+ builds: [terminal_build_seed]
+ }
+
+ Gitlab::Ci::Pipeline::Seed::Stage.new(pipeline, attributes, [])
+ end
+
+ def terminal_build_seed
+ terminal.merge(
+ name: TERMINAL_NAME,
+ stage: TERMINAL_NAME,
+ user: current_user,
+ scheduling_type: :stage)
+ end
+
+ def load_terminal_config!
+ result = ::Ci::WebIdeConfigService.new(project, current_user, sha: sha).execute
+ raise TerminalCreationError, result[:message] if result[:status] != :success
+
+ @terminal = result[:terminal]
+ raise TerminalCreationError, 'Terminal is not configured' unless terminal
+ end
+
+ def validate_params!
+ unless sha
+ raise TerminalCreationError, 'Ref does not exist'
+ end
+
+ unless branch_exists?
+ raise TerminalCreationError, 'Ref needs to be a branch'
+ end
+ end
+
+ def check_access!
+ unless can?(current_user, :create_web_ide_terminal, project)
+ raise TerminalCreationError, 'Insufficient permissions to create a terminal'
+ end
+
+ if terminal_active?
+ raise TerminalCreationError, 'There is already a terminal running'
+ end
+ end
+
+ def pipeline_created_counter
+ @pipeline_created_counter ||= Gitlab::Metrics
+ .counter(:pipelines_created_total, "Counter of pipelines created")
+ end
+
+ def terminal_active?
+ project.active_webide_pipelines(user: current_user).exists?
+ end
+
+ def ref
+ strong_memoize(:ref) do
+ Gitlab::Git.ref_name(params[:ref])
+ end
+ end
+
+ def branch_exists?
+ project.repository.branch_exists?(ref)
+ end
+
+ def sha
+ project.commit(params[:ref]).try(:id)
+ end
+ end
+end
diff --git a/app/services/ci/extract_sections_from_build_trace_service.rb b/app/services/ci/extract_sections_from_build_trace_service.rb
index 97f9918fdb7..c756e376901 100644
--- a/app/services/ci/extract_sections_from_build_trace_service.rb
+++ b/app/services/ci/extract_sections_from_build_trace_service.rb
@@ -5,7 +5,7 @@ module Ci
def execute(build)
return false unless build.trace_sections.empty?
- Gitlab::Database.bulk_insert(BuildTraceSection.table_name, extract_sections(build))
+ Gitlab::Database.bulk_insert(BuildTraceSection.table_name, extract_sections(build)) # rubocop:disable Gitlab/BulkInsert
true
end
diff --git a/app/services/ci/process_pipeline_service.rb b/app/services/ci/process_pipeline_service.rb
index 3f23e81dcdd..80ebe5f5eb6 100644
--- a/app/services/ci/process_pipeline_service.rb
+++ b/app/services/ci/process_pipeline_service.rb
@@ -11,7 +11,7 @@ module Ci
def execute(trigger_build_ids = nil, initial_process: false)
update_retried
- if Feature.enabled?(:ci_atomic_processing, pipeline.project)
+ if ::Gitlab::Ci::Features.atomic_processing?(pipeline.project)
Ci::PipelineProcessing::AtomicProcessingService
.new(pipeline)
.execute
diff --git a/app/services/ci/update_ci_ref_status_service.rb b/app/services/ci/update_ci_ref_status_service.rb
index 4f7ac4d11b0..22cc43232cc 100644
--- a/app/services/ci/update_ci_ref_status_service.rb
+++ b/app/services/ci/update_ci_ref_status_service.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
+# NOTE: This class is unused and to be removed in 13.1~
module Ci
class UpdateCiRefStatusService
include Gitlab::OptimisticLocking
diff --git a/app/services/ci/web_ide_config_service.rb b/app/services/ci/web_ide_config_service.rb
new file mode 100644
index 00000000000..ade9132f419
--- /dev/null
+++ b/app/services/ci/web_ide_config_service.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+module Ci
+ class WebIdeConfigService < ::BaseService
+ include ::Gitlab::Utils::StrongMemoize
+
+ ValidationError = Class.new(StandardError)
+
+ WEBIDE_CONFIG_FILE = '.gitlab/.gitlab-webide.yml'.freeze
+
+ attr_reader :config, :config_content
+
+ def execute
+ check_access!
+ load_config_content!
+ load_config!
+
+ success(terminal: config.terminal_value)
+ rescue ValidationError => e
+ error(e.message)
+ end
+
+ private
+
+ def check_access!
+ unless can?(current_user, :download_code, project)
+ raise ValidationError, 'Insufficient permissions to read configuration'
+ end
+ end
+
+ def load_config_content!
+ @config_content = webide_yaml_from_repo
+
+ unless config_content
+ raise ValidationError, "Failed to load Web IDE config file '#{WEBIDE_CONFIG_FILE}' for #{params[:sha]}"
+ end
+ end
+
+ def load_config!
+ @config = Gitlab::WebIde::Config.new(config_content)
+
+ unless @config.valid?
+ raise ValidationError, @config.errors.first
+ end
+ rescue Gitlab::WebIde::Config::ConfigError => e
+ raise ValidationError, e.message
+ end
+
+ def webide_yaml_from_repo
+ gitlab_webide_yml_for(params[:sha])
+ rescue GRPC::NotFound, GRPC::Internal
+ nil
+ end
+
+ def gitlab_webide_yml_for(sha)
+ project.repository.blob_data_at(sha, WEBIDE_CONFIG_FILE)
+ end
+ end
+end
diff --git a/app/services/clusters/applications/prometheus_config_service.rb b/app/services/clusters/applications/prometheus_config_service.rb
index 34d44ab881e..50c4e26b0d0 100644
--- a/app/services/clusters/applications/prometheus_config_service.rb
+++ b/app/services/clusters/applications/prometheus_config_service.rb
@@ -132,19 +132,21 @@ module Clusters
end
def alerts(environment)
- variables = Gitlab::Prometheus::QueryVariables.call(environment)
alerts = Projects::Prometheus::AlertsFinder
.new(environment: environment)
.execute
alerts.map do |alert|
- substitute_query_variables(alert.to_param, variables)
+ hash = alert.to_param
+ hash['expr'] = substitute_query_variables(hash['expr'], environment)
+ hash
end
end
- def substitute_query_variables(hash, variables)
- hash['expr'] %= variables
- hash
+ def substitute_query_variables(query, environment)
+ result = ::Prometheus::ProxyVariableSubstitutionService.new(environment, query: query).execute
+
+ result[:params][:query]
end
def environments
diff --git a/app/services/clusters/parse_cluster_applications_artifact_service.rb b/app/services/clusters/parse_cluster_applications_artifact_service.rb
index b8e1c80cfe7..35fba5f47c7 100644
--- a/app/services/clusters/parse_cluster_applications_artifact_service.rb
+++ b/app/services/clusters/parse_cluster_applications_artifact_service.rb
@@ -18,13 +18,9 @@ module Clusters
raise ArgumentError, 'Artifact is not cluster_applications file type' unless artifact&.cluster_applications?
- unless artifact.file.size < MAX_ACCEPTABLE_ARTIFACT_SIZE
- return error(too_big_error_message, :bad_request)
- end
-
- unless cluster
- return error(s_('ClusterIntegration|No deployment cluster found for this job'))
- end
+ return error(too_big_error_message, :bad_request) unless artifact.file.size < MAX_ACCEPTABLE_ARTIFACT_SIZE
+ return error(no_deployment_message, :bad_request) unless job.deployment
+ return error(no_deployment_cluster_message, :bad_request) unless cluster
parse!(artifact)
@@ -61,7 +57,8 @@ module Clusters
Clusters::Cluster.transaction do
RELEASE_NAMES.each do |release_name|
- application = find_or_build_application(release_name)
+ application_class = Clusters::Cluster::APPLICATIONS[release_name]
+ application = cluster.find_or_build_application(application_class)
release = release_by_name[release_name]
@@ -80,16 +77,18 @@ module Clusters
end
end
- def find_or_build_application(application_name)
- application_class = Clusters::Cluster::APPLICATIONS[application_name]
-
- cluster.find_or_build_application(application_class)
- end
-
def too_big_error_message
human_size = ActiveSupport::NumberHelper.number_to_human_size(MAX_ACCEPTABLE_ARTIFACT_SIZE)
s_('ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}') % { human_size: human_size }
end
+
+ def no_deployment_message
+ s_('ClusterIntegration|No deployment found for this job')
+ end
+
+ def no_deployment_cluster_message
+ s_('ClusterIntegration|No deployment cluster found for this job')
+ end
end
end
diff --git a/app/services/commits/create_service.rb b/app/services/commits/create_service.rb
index bd238605ac1..d80d9bebe9c 100644
--- a/app/services/commits/create_service.rb
+++ b/app/services/commits/create_service.rb
@@ -30,12 +30,14 @@ module Commits
success(result: new_commit)
rescue ChangeError => ex
+ Gitlab::ErrorTracking.log_exception(ex)
error(ex.message, pass_back: { error_code: ex.error_code })
rescue ValidationError,
Gitlab::Git::Index::IndexError,
Gitlab::Git::CommitError,
Gitlab::Git::PreReceiveError,
Gitlab::Git::CommandError => ex
+ Gitlab::ErrorTracking.log_exception(ex)
error(ex.message)
end
diff --git a/app/services/concerns/exclusive_lease_guard.rb b/app/services/concerns/exclusive_lease_guard.rb
index 0c5ecca3a50..4678d051d29 100644
--- a/app/services/concerns/exclusive_lease_guard.rb
+++ b/app/services/concerns/exclusive_lease_guard.rb
@@ -58,6 +58,6 @@ module ExclusiveLeaseGuard
end
def log_error(message, extra_args = {})
- Rails.logger.error(message) # rubocop:disable Gitlab/RailsLogger
+ Gitlab::AppLogger.error(message)
end
end
diff --git a/app/services/concerns/integrations/project_test_data.rb b/app/services/concerns/integrations/project_test_data.rb
new file mode 100644
index 00000000000..4d551430315
--- /dev/null
+++ b/app/services/concerns/integrations/project_test_data.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+module Integrations
+ module ProjectTestData
+ private
+
+ def push_events_data
+ Gitlab::DataBuilder::Push.build_sample(project, current_user)
+ end
+
+ def note_events_data
+ note = project.notes.first
+ return { error: s_('TestHooks|Ensure the project has notes.') } unless note.present?
+
+ Gitlab::DataBuilder::Note.build(note, current_user)
+ end
+
+ def issues_events_data
+ issue = project.issues.first
+ return { error: s_('TestHooks|Ensure the project has issues.') } unless issue.present?
+
+ issue.to_hook_data(current_user)
+ end
+
+ def merge_requests_events_data
+ merge_request = project.merge_requests.first
+ return { error: s_('TestHooks|Ensure the project has merge requests.') } unless merge_request.present?
+
+ merge_request.to_hook_data(current_user)
+ end
+
+ def job_events_data
+ build = project.builds.first
+ return { error: s_('TestHooks|Ensure the project has CI jobs.') } unless build.present?
+
+ Gitlab::DataBuilder::Build.build(build)
+ end
+
+ def pipeline_events_data
+ pipeline = project.ci_pipelines.newest_first.first
+ return { error: s_('TestHooks|Ensure the project has CI pipelines.') } unless pipeline.present?
+
+ Gitlab::DataBuilder::Pipeline.build(pipeline)
+ end
+
+ def wiki_page_events_data
+ page = project.wiki.list_pages(limit: 1).first
+ if !project.wiki_enabled? || page.blank?
+ return { error: s_('TestHooks|Ensure the wiki is enabled and has pages.') }
+ end
+
+ Gitlab::DataBuilder::WikiPage.build(page, current_user, 'create')
+ end
+
+ def deployment_events_data
+ deployment = project.deployments.first
+ return { error: s_('TestHooks|Ensure the project has deployments.') } unless deployment.present?
+
+ Gitlab::DataBuilder::Deployment.build(deployment)
+ end
+ end
+end
diff --git a/app/services/concerns/measurable.rb b/app/services/concerns/measurable.rb
index 5a74f15506e..b099a58a9ae 100644
--- a/app/services/concerns/measurable.rb
+++ b/app/services/concerns/measurable.rb
@@ -4,8 +4,6 @@
# Example:
# ```
# class DummyService
-# prepend Measurable
-#
# def execute
# # ...
# end
diff --git a/app/services/concerns/spam_check_methods.rb b/app/services/concerns/spam_check_methods.rb
index 53e9e001463..939f8f183ab 100644
--- a/app/services/concerns/spam_check_methods.rb
+++ b/app/services/concerns/spam_check_methods.rb
@@ -22,15 +22,18 @@ module SpamCheckMethods
# a dirty instance, which means it should be already assigned with the new
# attribute values.
# rubocop:disable Gitlab/ModuleWithInstanceVariables
- def spam_check(spammable, user)
+ def spam_check(spammable, user, action:)
+ raise ArgumentError.new('Please provide an action, such as :create') unless action
+
Spam::SpamActionService.new(
spammable: spammable,
- request: @request
+ request: @request,
+ user: user,
+ context: { action: action }
).execute(
api: @api,
recaptcha_verified: @recaptcha_verified,
- spam_log_id: @spam_log_id,
- user: user)
+ spam_log_id: @spam_log_id)
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
end
diff --git a/app/services/container_expiration_policies/update_service.rb b/app/services/container_expiration_policies/update_service.rb
new file mode 100644
index 00000000000..2f34941d692
--- /dev/null
+++ b/app/services/container_expiration_policies/update_service.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+module ContainerExpirationPolicies
+ class UpdateService < BaseContainerService
+ include Gitlab::Utils::StrongMemoize
+
+ ALLOWED_ATTRIBUTES = %i[enabled cadence older_than keep_n name_regex name_regex_keep].freeze
+
+ def execute
+ return ServiceResponse.error(message: 'Access Denied', http_status: 403) unless allowed?
+
+ if container_expiration_policy.update(container_expiration_policy_params)
+ ServiceResponse.success(payload: { container_expiration_policy: container_expiration_policy })
+ else
+ ServiceResponse.error(
+ message: container_expiration_policy.errors.full_messages.to_sentence || 'Bad request',
+ http_status: 400
+ )
+ end
+ end
+
+ private
+
+ def container_expiration_policy
+ strong_memoize(:container_expiration_policy) do
+ @container.container_expiration_policy || @container.build_container_expiration_policy
+ end
+ end
+
+ def allowed?
+ Ability.allowed?(current_user, :destroy_container_image, @container)
+ end
+
+ def container_expiration_policy_params
+ @params.slice(*ALLOWED_ATTRIBUTES)
+ end
+ end
+end
diff --git a/app/services/container_expiration_policy_service.rb b/app/services/container_expiration_policy_service.rb
index 82274fd8668..80f32298323 100644
--- a/app/services/container_expiration_policy_service.rb
+++ b/app/services/container_expiration_policy_service.rb
@@ -1,7 +1,14 @@
# frozen_string_literal: true
class ContainerExpirationPolicyService < BaseService
+ InvalidPolicyError = Class.new(StandardError)
+
def execute(container_expiration_policy)
+ unless container_expiration_policy.valid?
+ container_expiration_policy.disable!
+ raise InvalidPolicyError
+ end
+
container_expiration_policy.schedule_next_run!
container_expiration_policy.container_repositories.find_each do |container_repository|
diff --git a/app/services/design_management/delete_designs_service.rb b/app/services/design_management/delete_designs_service.rb
index e69f07db5bf..5d875c630a0 100644
--- a/app/services/design_management/delete_designs_service.rb
+++ b/app/services/design_management/delete_designs_service.rb
@@ -15,6 +15,7 @@ module DesignManagement
return error('Forbidden!') unless can_delete_designs?
version = delete_designs!
+ EventCreateService.new.destroy_designs(designs, current_user)
success(version: version)
end
@@ -48,7 +49,9 @@ module DesignManagement
end
def design_action(design)
- on_success { counter.count(:delete) }
+ on_success do
+ counter.count(:delete)
+ end
DesignManagement::DesignAction.new(design, :delete)
end
diff --git a/app/services/design_management/save_designs_service.rb b/app/services/design_management/save_designs_service.rb
index a09c19bc885..0446d2f1ee8 100644
--- a/app/services/design_management/save_designs_service.rb
+++ b/app/services/design_management/save_designs_service.rb
@@ -20,6 +20,7 @@ module DesignManagement
uploaded_designs, version = upload_designs!
skipped_designs = designs - uploaded_designs
+ create_events
success({ designs: uploaded_designs, version: version, skipped_designs: skipped_designs })
rescue ::ActiveRecord::RecordInvalid => e
error(e.message)
@@ -47,7 +48,7 @@ module DesignManagement
end
def build_actions
- files.zip(designs).flat_map do |(file, design)|
+ @actions ||= files.zip(designs).flat_map do |(file, design)|
Array.wrap(build_design_action(file, design))
end
end
@@ -57,7 +58,9 @@ module DesignManagement
return if design_unchanged?(design, content)
action = new_file?(design) ? :create : :update
- on_success { ::Gitlab::UsageDataCounters::DesignsCounter.count(action) }
+ on_success do
+ ::Gitlab::UsageDataCounters::DesignsCounter.count(action)
+ end
DesignManagement::DesignAction.new(design, action, content)
end
@@ -67,6 +70,16 @@ module DesignManagement
content == existing_blobs[design]&.data
end
+ def create_events
+ by_action = @actions.group_by(&:action).transform_values { |grp| grp.map(&:design) }
+
+ event_create_service.save_designs(current_user, **by_action)
+ end
+
+ def event_create_service
+ @event_create_service ||= EventCreateService.new
+ end
+
def commit_message
<<~MSG
Updated #{files.size} #{'designs'.pluralize(files.size)}
diff --git a/app/services/discussions/resolve_service.rb b/app/services/discussions/resolve_service.rb
index 816cd45b07a..946fb5f1372 100644
--- a/app/services/discussions/resolve_service.rb
+++ b/app/services/discussions/resolve_service.rb
@@ -2,25 +2,68 @@
module Discussions
class ResolveService < Discussions::BaseService
- def execute(one_or_more_discussions)
- Array(one_or_more_discussions).each { |discussion| resolve_discussion(discussion) }
+ include Gitlab::Utils::StrongMemoize
+
+ def initialize(project, user = nil, params = {})
+ @discussions = Array.wrap(params.fetch(:one_or_more_discussions))
+ @follow_up_issue = params[:follow_up_issue]
+ @resolved_count = 0
+
+ raise ArgumentError, 'Discussions must be all for the same noteable' \
+ unless noteable_is_same?
+
+ super
+ end
+
+ def execute
+ discussions.each(&method(:resolve_discussion))
+ process_auto_merge
+ end
+
+ private
+
+ attr_accessor :discussions, :follow_up_issue
+
+ def noteable_is_same?
+ return true unless discussions.size > 1
+
+ # Perform this check without fetching extra records
+ discussions.all? do |discussion|
+ discussion.noteable_type == first_discussion.noteable_type &&
+ discussion.noteable_id == first_discussion.noteable_id
+ end
end
def resolve_discussion(discussion)
return unless discussion.can_resolve?(current_user)
discussion.resolve!(current_user)
+ @resolved_count += 1
- MergeRequests::ResolvedDiscussionNotificationService.new(project, current_user).execute(merge_request)
+ MergeRequests::ResolvedDiscussionNotificationService.new(project, current_user).execute(merge_request) if merge_request
SystemNoteService.discussion_continued_in_issue(discussion, project, current_user, follow_up_issue) if follow_up_issue
end
+ def first_discussion
+ @first_discussion ||= discussions.first
+ end
+
def merge_request
- params[:merge_request]
+ strong_memoize(:merge_request) do
+ first_discussion.noteable if first_discussion.for_merge_request?
+ end
+ end
+
+ def process_auto_merge
+ return unless merge_request
+ return unless @resolved_count.positive?
+ return unless discussions_ready_to_merge?
+
+ AutoMergeProcessWorker.perform_async(merge_request.id)
end
- def follow_up_issue
- params[:follow_up_issue]
+ def discussions_ready_to_merge?
+ merge_request.auto_merge_enabled? && merge_request.mergeable_discussions_state?
end
end
end
diff --git a/app/services/draft_notes/base_service.rb b/app/services/draft_notes/base_service.rb
new file mode 100644
index 00000000000..89daae0e8f4
--- /dev/null
+++ b/app/services/draft_notes/base_service.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module DraftNotes
+ class BaseService < ::BaseService
+ attr_accessor :merge_request, :current_user, :params
+
+ def initialize(merge_request, current_user, params = nil)
+ @merge_request, @current_user, @params = merge_request, current_user, params.dup
+ end
+
+ private
+
+ def draft_notes
+ @draft_notes ||= merge_request.draft_notes.order_id_asc.authored_by(current_user)
+ end
+
+ def project
+ merge_request.target_project
+ end
+ end
+end
diff --git a/app/services/draft_notes/create_service.rb b/app/services/draft_notes/create_service.rb
new file mode 100644
index 00000000000..501778b7d5f
--- /dev/null
+++ b/app/services/draft_notes/create_service.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+module DraftNotes
+ class CreateService < DraftNotes::BaseService
+ attr_accessor :in_draft_mode, :in_reply_to_discussion_id
+
+ def initialize(merge_request, current_user, params = nil)
+ @in_reply_to_discussion_id = params.delete(:in_reply_to_discussion_id)
+ super
+ end
+
+ def execute
+ if in_reply_to_discussion_id.present?
+ unless discussion
+ return base_error(_('Thread to reply to cannot be found'))
+ end
+
+ params[:discussion_id] = discussion.reply_id
+ end
+
+ if params[:resolve_discussion] && !can_resolve_discussion?
+ return base_error(_('User is not allowed to resolve thread'))
+ end
+
+ draft_note = DraftNote.new(params)
+ draft_note.merge_request = merge_request
+ draft_note.author = current_user
+ draft_note.save
+
+ if in_reply_to_discussion_id.blank? && draft_note.diff_file&.unfolded?
+ merge_request.diffs.clear_cache
+ end
+
+ draft_note
+ end
+
+ private
+
+ def base_error(text)
+ DraftNote.new.tap do |draft|
+ draft.errors.add(:base, text)
+ end
+ end
+
+ def discussion
+ @discussion ||= merge_request.notes.find_discussion(in_reply_to_discussion_id)
+ end
+
+ def can_resolve_discussion?
+ note = discussion&.notes&.first
+ return false unless note
+
+ current_user && Ability.allowed?(current_user, :resolve_note, note)
+ end
+ end
+end
diff --git a/app/services/draft_notes/destroy_service.rb b/app/services/draft_notes/destroy_service.rb
new file mode 100644
index 00000000000..ddca0debb03
--- /dev/null
+++ b/app/services/draft_notes/destroy_service.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module DraftNotes
+ class DestroyService < DraftNotes::BaseService
+ # If no `draft` is given it fallsback to all
+ # draft notes of the given merge request and user.
+ def execute(draft = nil)
+ drafts = draft || draft_notes
+
+ clear_highlight_diffs_cache(Array.wrap(drafts))
+
+ drafts.is_a?(DraftNote) ? drafts.destroy! : drafts.delete_all
+ end
+
+ private
+
+ def clear_highlight_diffs_cache(drafts)
+ if drafts.any? { |draft| draft.diff_file&.unfolded? }
+ merge_request.diffs.clear_cache
+ end
+ end
+ end
+end
diff --git a/app/services/draft_notes/publish_service.rb b/app/services/draft_notes/publish_service.rb
new file mode 100644
index 00000000000..a9a7304e5ed
--- /dev/null
+++ b/app/services/draft_notes/publish_service.rb
@@ -0,0 +1,67 @@
+# frozen_string_literal: true
+
+module DraftNotes
+ class PublishService < DraftNotes::BaseService
+ def execute(draft = nil)
+ return error('Not allowed to create notes') unless can?(current_user, :create_note, merge_request)
+
+ if draft
+ publish_draft_note(draft)
+ else
+ publish_draft_notes
+ end
+
+ success
+ rescue ActiveRecord::RecordInvalid => e
+ message = "Unable to save #{e.record.class.name}: #{e.record.errors.full_messages.join(", ")} "
+ error(message)
+ end
+
+ private
+
+ def publish_draft_note(draft)
+ create_note_from_draft(draft)
+ draft.delete
+
+ MergeRequests::ResolvedDiscussionNotificationService.new(project, current_user).execute(merge_request)
+ end
+
+ def publish_draft_notes
+ return if draft_notes.empty?
+
+ review = Review.create!(author: current_user, merge_request: merge_request, project: project)
+
+ draft_notes.map do |draft_note|
+ draft_note.review = review
+ create_note_from_draft(draft_note)
+ end
+ draft_notes.delete_all
+
+ notification_service.async.new_review(review)
+ MergeRequests::ResolvedDiscussionNotificationService.new(project, current_user).execute(merge_request)
+ end
+
+ def create_note_from_draft(draft)
+ # 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
+ set_discussion_resolve_status(note, draft)
+
+ note
+ end
+
+ def set_discussion_resolve_status(note, draft_note)
+ return unless draft_note.discussion_id.present?
+
+ discussion = note.discussion
+
+ if draft_note.resolve_discussion && discussion.can_resolve?(current_user)
+ discussion.resolve!(current_user)
+ else
+ discussion.unresolve!
+ end
+ end
+ end
+end
diff --git a/app/services/event_create_service.rb b/app/services/event_create_service.rb
index 522f36cda46..89c3225dbcd 100644
--- a/app/services/event_create_service.rb
+++ b/app/services/event_create_service.rb
@@ -11,67 +11,81 @@ class EventCreateService
IllegalActionError = Class.new(StandardError)
def open_issue(issue, current_user)
- create_record_event(issue, current_user, Event::CREATED)
+ create_resource_event(issue, current_user, :opened)
+
+ create_record_event(issue, current_user, :created)
end
def close_issue(issue, current_user)
- create_record_event(issue, current_user, Event::CLOSED)
+ create_resource_event(issue, current_user, :closed)
+
+ create_record_event(issue, current_user, :closed)
end
def reopen_issue(issue, current_user)
- create_record_event(issue, current_user, Event::REOPENED)
+ create_resource_event(issue, current_user, :reopened)
+
+ create_record_event(issue, current_user, :reopened)
end
def open_mr(merge_request, current_user)
- create_record_event(merge_request, current_user, Event::CREATED)
+ create_resource_event(merge_request, current_user, :opened)
+
+ create_record_event(merge_request, current_user, :created)
end
def close_mr(merge_request, current_user)
- create_record_event(merge_request, current_user, Event::CLOSED)
+ create_resource_event(merge_request, current_user, :closed)
+
+ create_record_event(merge_request, current_user, :closed)
end
def reopen_mr(merge_request, current_user)
- create_record_event(merge_request, current_user, Event::REOPENED)
+ create_resource_event(merge_request, current_user, :reopened)
+
+ create_record_event(merge_request, current_user, :reopened)
end
def merge_mr(merge_request, current_user)
- create_record_event(merge_request, current_user, Event::MERGED)
+ create_resource_event(merge_request, current_user, :merged)
+
+ create_record_event(merge_request, current_user, :merged)
end
def open_milestone(milestone, current_user)
- create_record_event(milestone, current_user, Event::CREATED)
+ create_record_event(milestone, current_user, :created)
end
def close_milestone(milestone, current_user)
- create_record_event(milestone, current_user, Event::CLOSED)
+ create_record_event(milestone, current_user, :closed)
end
def reopen_milestone(milestone, current_user)
- create_record_event(milestone, current_user, Event::REOPENED)
+ create_record_event(milestone, current_user, :reopened)
end
def destroy_milestone(milestone, current_user)
- create_record_event(milestone, current_user, Event::DESTROYED)
+ create_record_event(milestone, current_user, :destroyed)
end
def leave_note(note, current_user)
- create_record_event(note, current_user, Event::COMMENTED)
+ create_record_event(note, current_user, :commented)
end
def join_project(project, current_user)
- create_event(project, current_user, Event::JOINED)
+ create_event(project, current_user, :joined)
end
def leave_project(project, current_user)
- create_event(project, current_user, Event::LEFT)
+ create_event(project, current_user, :left)
end
def expired_leave_project(project, current_user)
- create_event(project, current_user, Event::EXPIRED)
+ create_event(project, current_user, :expired)
end
def create_project(project, current_user)
- create_event(project, current_user, Event::CREATED)
+ create_event(project, current_user, :created)
end
def push(project, current_user, push_data)
@@ -82,11 +96,34 @@ class EventCreateService
create_push_event(BulkPushEventPayloadService, project, current_user, push_data)
end
+ def save_designs(current_user, create: [], update: [])
+ created = create.group_by(&:project).flat_map do |project, designs|
+ Feature.enabled?(:design_activity_events, project) ? designs : []
+ end.to_set
+ updated = update.group_by(&:project).flat_map do |project, designs|
+ Feature.enabled?(:design_activity_events, project) ? designs : []
+ end.to_set
+ return [] if created.empty? && updated.empty?
+
+ records = created.zip([:created].cycle) + updated.zip([:updated].cycle)
+
+ create_record_events(records, current_user)
+ end
+
+ def destroy_designs(designs, current_user)
+ designs = designs.select do |design|
+ Feature.enabled?(:design_activity_events, design.project)
+ end
+ return [] unless designs.present?
+
+ create_record_events(designs.zip([:destroyed].cycle), current_user)
+ end
+
# Create a new wiki page event
#
# @param [WikiPage::Meta] wiki_page_meta The event target
# @param [User] author The event author
- # @param [Integer] action One of the Event::WIKI_ACTIONS
+ # @param [Symbol] action One of the Event::WIKI_ACTIONS
#
# @return a tuple of event and either :found or :created
def wiki_event(wiki_page_meta, author, action)
@@ -100,7 +137,7 @@ class EventCreateService
event = create_record_event(wiki_page_meta, author, action)
# Ensure that the event is linked in time to the metadata, for non-deletes
- unless action == Event::DESTROYED
+ unless event.destroyed_action?
time_stamp = wiki_page_meta.updated_at
event.update_columns(updated_at: time_stamp, created_at: time_stamp)
end
@@ -111,16 +148,41 @@ class EventCreateService
private
def existing_wiki_event(wiki_page_meta, action)
- if action == Event::DESTROYED
+ if Event.actions.fetch(action) == Event.actions[:destroyed]
most_recent = Event.for_wiki_meta(wiki_page_meta).recent.first
- return most_recent if most_recent.present? && most_recent.action == action
+ return most_recent if most_recent.present? && Event.actions[most_recent.action] == Event.actions[action]
else
Event.for_wiki_meta(wiki_page_meta).created_at(wiki_page_meta.updated_at).first
end
end
def create_record_event(record, current_user, status)
- create_event(record.resource_parent, current_user, status, target_id: record.id, target_type: record.class.name)
+ create_event(record.resource_parent, current_user, status,
+ target_id: record.id, target_type: record.class.name)
+ end
+
+ # If creating several events, this method will insert them all in a single
+ # statement
+ #
+ # @param [[Eventable, Symbol]] a list of pairs of records and a valid status
+ # @param [User] the author of the event
+ def create_record_events(pairs, current_user)
+ base_attrs = {
+ created_at: Time.now.utc,
+ updated_at: Time.now.utc,
+ author_id: current_user.id
+ }
+
+ attribute_sets = pairs.map do |record, status|
+ action = Event.actions[status]
+ raise IllegalActionError, "#{status} is not a valid status" if action.nil?
+
+ parent_attrs(record.resource_parent)
+ .merge(base_attrs)
+ .merge(action: action, target_id: record.id, target_type: record.class.name)
+ end
+
+ Event.insert_all(attribute_sets, returning: %w[id])
end
def create_push_event(service_class, project, current_user, push_data)
@@ -128,7 +190,7 @@ class EventCreateService
# when creating push payload data will result in the event creation being
# rolled back as well.
event = Event.transaction do
- new_event = create_event(project, current_user, Event::PUSHED)
+ new_event = create_event(project, current_user, :pushed)
service_class.new(new_event, push_data).execute
@@ -146,16 +208,34 @@ class EventCreateService
action: status,
author_id: current_user.id
)
+ attributes.merge!(parent_attrs(resource_parent))
+
+ Event.create!(attributes)
+ end
+ def parent_attrs(resource_parent)
resource_parent_attr = case resource_parent
when Project
- :project
+ :project_id
when Group
- :group
+ :group_id
end
- attributes[resource_parent_attr] = resource_parent if resource_parent_attr
- Event.create!(attributes)
+ return {} unless resource_parent_attr
+
+ { resource_parent_attr => resource_parent.id }
+ end
+
+ def create_resource_event(issuable, current_user, status)
+ return unless state_change_tracking_enabled?(issuable)
+
+ ResourceEvents::ChangeStateService.new(resource: issuable, user: current_user)
+ .execute(status)
+ end
+
+ def state_change_tracking_enabled?(issuable)
+ issuable&.respond_to?(:resource_state_events) &&
+ ::Feature.enabled?(:track_resource_state_change_events, issuable&.project)
end
end
diff --git a/app/services/git/wiki_push_service/change.rb b/app/services/git/wiki_push_service/change.rb
index 8685850165a..14e622dd147 100644
--- a/app/services/git/wiki_push_service/change.rb
+++ b/app/services/git/wiki_push_service/change.rb
@@ -21,11 +21,11 @@ module Git
def event_action
case raw_change.operation
when :added
- Event::CREATED
+ :created
when :deleted
- Event::DESTROYED
+ :destroyed
else
- Event::UPDATED
+ :updated
end
end
diff --git a/app/services/groups/destroy_service.rb b/app/services/groups/destroy_service.rb
index 9437eb9eede..1bff70e6c2e 100644
--- a/app/services/groups/destroy_service.rb
+++ b/app/services/groups/destroy_service.rb
@@ -6,7 +6,7 @@ module Groups
def async_execute
job_id = GroupDestroyWorker.perform_async(group.id, current_user.id)
- Rails.logger.info("User #{current_user.id} scheduled a deletion of group ID #{group.id} with job ID #{job_id}") # rubocop:disable Gitlab/RailsLogger
+ Gitlab::AppLogger.info("User #{current_user.id} scheduled a deletion of group ID #{group.id} with job ID #{job_id}")
end
# rubocop: disable CodeReuse/ActiveRecord
diff --git a/app/services/groups/group_links/create_service.rb b/app/services/groups/group_links/create_service.rb
index 2ce53fcfe4a..589ac7ccde7 100644
--- a/app/services/groups/group_links/create_service.rb
+++ b/app/services/groups/group_links/create_service.rb
@@ -5,7 +5,7 @@ module Groups
class CreateService < BaseService
def execute(shared_group)
unless group && shared_group &&
- can?(current_user, :admin_group, shared_group) &&
+ can?(current_user, :admin_group_member, shared_group) &&
can?(current_user, :read_group, group)
return error('Not Found', 404)
end
diff --git a/app/services/groups/group_links/destroy_service.rb b/app/services/groups/group_links/destroy_service.rb
index 6835b6c4637..b0d496ae78c 100644
--- a/app/services/groups/group_links/destroy_service.rb
+++ b/app/services/groups/group_links/destroy_service.rb
@@ -3,7 +3,11 @@
module Groups
module GroupLinks
class DestroyService < BaseService
- def execute(one_or_more_links)
+ def execute(one_or_more_links, skip_authorization: false)
+ unless skip_authorization || group && can?(current_user, :admin_group_member, group)
+ return error('Not Found', 404)
+ end
+
links = Array(one_or_more_links)
if GroupGroupLink.delete(links)
diff --git a/app/services/groups/import_export/export_service.rb b/app/services/groups/import_export/export_service.rb
index 0f2e3bb65f9..abac0ffc5d9 100644
--- a/app/services/groups/import_export/export_service.rb
+++ b/app/services/groups/import_export/export_service.rb
@@ -4,10 +4,11 @@ module Groups
module ImportExport
class ExportService
def initialize(group:, user:, params: {})
- @group = group
+ @group = group
@current_user = user
- @params = params
- @shared = @params[:shared] || Gitlab::ImportExport::Shared.new(@group)
+ @params = params
+ @shared = @params[:shared] || Gitlab::ImportExport::Shared.new(@group)
+ @logger = Gitlab::Export::Logger.build
end
def async_execute
@@ -21,7 +22,7 @@ module Groups
save!
ensure
- cleanup
+ remove_base_tmp_dir
end
private
@@ -80,8 +81,8 @@ module Groups
Gitlab::ImportExport::Saver.new(exportable: @group, shared: @shared)
end
- def cleanup
- FileUtils.rm_rf(shared.archive_path) if shared&.archive_path
+ def remove_base_tmp_dir
+ FileUtils.rm_rf(shared.base_path) if shared&.base_path
end
def notify_error!
@@ -91,21 +92,21 @@ module Groups
end
def notify_success
- @shared.logger.info(
- group_id: @group.id,
- group_name: @group.name,
- message: 'Group Import/Export: Export succeeded'
+ @logger.info(
+ message: 'Group Export succeeded',
+ group_id: @group.id,
+ group_name: @group.name
)
notification_service.group_was_exported(@group, @current_user)
end
def notify_error
- @shared.logger.error(
- group_id: @group.id,
+ @logger.error(
+ message: 'Group Export failed',
+ group_id: @group.id,
group_name: @group.name,
- error: @shared.errors.join(', '),
- message: 'Group Import/Export: Export failed'
+ errors: @shared.errors.join(', ')
)
notification_service.group_was_not_exported(@group, @current_user, @shared.errors)
diff --git a/app/services/groups/import_export/import_service.rb b/app/services/groups/import_export/import_service.rb
index 6f692c98c38..a5c776f8fc2 100644
--- a/app/services/groups/import_export/import_service.rb
+++ b/app/services/groups/import_export/import_service.rb
@@ -9,6 +9,20 @@ module Groups
@group = group
@current_user = user
@shared = Gitlab::ImportExport::Shared.new(@group)
+ @logger = Gitlab::Import::Logger.build
+ end
+
+ def async_execute
+ group_import_state = GroupImportState.safe_find_or_create_by!(group: group)
+ jid = GroupImportWorker.perform_async(current_user.id, group.id)
+
+ if jid.present?
+ group_import_state.update!(jid: jid)
+ else
+ group_import_state.fail_op('Failed to schedule import job')
+
+ false
+ end
end
def execute
@@ -21,6 +35,7 @@ module Groups
end
ensure
+ remove_base_tmp_dir
remove_import_file
end
@@ -77,7 +92,7 @@ module Groups
end
def notify_success
- @shared.logger.info(
+ @logger.info(
group_id: @group.id,
group_name: @group.name,
message: 'Group Import/Export: Import succeeded'
@@ -85,7 +100,7 @@ module Groups
end
def notify_error
- @shared.logger.error(
+ @logger.error(
group_id: @group.id,
group_name: @group.name,
message: "Group Import/Export: Errors occurred, see '#{Gitlab::ErrorTracking::Logger.file_name}' for details"
@@ -97,6 +112,10 @@ module Groups
raise Gitlab::ImportExport::Error.new(@shared.errors.to_sentence)
end
+
+ def remove_base_tmp_dir
+ FileUtils.rm_rf(@shared.base_path)
+ end
end
end
end
diff --git a/app/services/groups/transfer_service.rb b/app/services/groups/transfer_service.rb
index fe3ab884302..fbbf4ce8baf 100644
--- a/app/services/groups/transfer_service.rb
+++ b/app/services/groups/transfer_service.rb
@@ -45,6 +45,7 @@ module Groups
raise_transfer_error(:invalid_policies) unless valid_policies?
raise_transfer_error(:namespace_with_same_path) if namespace_with_same_path?
raise_transfer_error(:group_contains_images) if group_projects_contain_registry_images?
+ raise_transfer_error(:cannot_transfer_to_subgroup) if transfer_to_subgroup?
end
def group_is_already_root?
@@ -55,6 +56,11 @@ module Groups
@new_parent_group && @new_parent_group.id == @group.parent_id
end
+ def transfer_to_subgroup?
+ @new_parent_group && \
+ @group.self_and_descendants.pluck_primary_key.include?(@new_parent_group.id)
+ end
+
def valid_policies?
return false unless can?(current_user, :admin_group, @group)
@@ -82,6 +88,7 @@ module Groups
end
@group.parent = @new_parent_group
+ @group.clear_memoization(:self_and_ancestors_ids)
@group.save!
end
@@ -125,7 +132,8 @@ module Groups
group_is_already_root: s_('TransferGroup|Group is already a root group.'),
same_parent_as_current: s_('TransferGroup|Group is already associated to the parent group.'),
invalid_policies: s_("TransferGroup|You don't have enough permissions."),
- group_contains_images: s_('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.')
+ group_contains_images: s_('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.'),
+ cannot_transfer_to_subgroup: s_('TransferGroup|Cannot transfer group to one of its subgroup.')
}.freeze
end
end
diff --git a/app/services/import/github_service.rb b/app/services/import/github_service.rb
index 3c57fada677..0cf17568c78 100644
--- a/app/services/import/github_service.rb
+++ b/app/services/import/github_service.rb
@@ -10,15 +10,26 @@ module Import
return error(_('This namespace has already been taken! Please choose another one.'), :unprocessable_entity)
end
- project = Gitlab::LegacyGithubImport::ProjectCreator
- .new(repo, project_name, target_namespace, current_user, access_params, type: provider)
- .execute(extra_project_attrs)
+ project = create_project(access_params, provider)
if project.persisted?
success(project)
else
error(project_save_error(project), :unprocessable_entity)
end
+ rescue Octokit::Error => e
+ log_error(e)
+ end
+
+ def create_project(access_params, provider)
+ Gitlab::LegacyGithubImport::ProjectCreator.new(
+ repo,
+ project_name,
+ target_namespace,
+ current_user,
+ access_params,
+ type: provider
+ ).execute(extra_project_attrs)
end
def repo
@@ -44,6 +55,18 @@ module Import
def authorized?
can?(current_user, :create_projects, target_namespace)
end
+
+ private
+
+ def log_error(exception)
+ Gitlab::Import::Logger.error(
+ message: 'Import failed due to a GitHub error',
+ status: exception.response_status,
+ error: exception.response_body
+ )
+
+ error(_('Import failed due to a GitHub error: %{original}') % { original: exception.response_body }, :unprocessable_entity)
+ end
end
end
diff --git a/app/services/integrations/test/base_service.rb b/app/services/integrations/test/base_service.rb
new file mode 100644
index 00000000000..a8a027092d5
--- /dev/null
+++ b/app/services/integrations/test/base_service.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module Integrations
+ module Test
+ class BaseService
+ include BaseServiceUtility
+
+ attr_accessor :integration, :current_user, :event
+
+ # @param integration [Service] The external service that will be called
+ # @param current_user [User] The user calling the service
+ # @param event [String/nil] The event that triggered this
+ def initialize(integration, current_user, event = nil)
+ @integration = integration
+ @current_user = current_user
+ @event = event
+ end
+
+ def execute
+ if event && (integration.supported_events.exclude?(event) || data.blank?)
+ return error('Testing not available for this event')
+ end
+
+ return error(data[:error]) if data[:error].present?
+
+ integration.test(data)
+ end
+
+ private
+
+ def data
+ raise NotImplementedError
+ end
+ end
+ end
+end
diff --git a/app/services/integrations/test/project_service.rb b/app/services/integrations/test/project_service.rb
new file mode 100644
index 00000000000..941d70c2cc4
--- /dev/null
+++ b/app/services/integrations/test/project_service.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+module Integrations
+ module Test
+ class ProjectService < Integrations::Test::BaseService
+ include Integrations::ProjectTestData
+ include Gitlab::Utils::StrongMemoize
+
+ def project
+ strong_memoize(:project) do
+ integration.project
+ end
+ end
+
+ private
+
+ def data
+ strong_memoize(:data) do
+ next pipeline_events_data if integration.is_a?(::PipelinesEmailService)
+
+ case event
+ when 'push', 'tag_push'
+ push_events_data
+ when 'note', 'confidential_note'
+ note_events_data
+ when 'issue', 'confidential_issue'
+ issues_events_data
+ when 'merge_request'
+ merge_requests_events_data
+ when 'job'
+ job_events_data
+ when 'pipeline'
+ pipeline_events_data
+ when 'wiki_page'
+ wiki_page_events_data
+ when 'deployment'
+ deployment_events_data
+ else
+ push_events_data
+ end
+ end
+ end
+ end
+ end
+end
+
+Integrations::Test::ProjectService.prepend_if_ee('::EE::Integrations::Test::ProjectService')
diff --git a/app/services/issuable/bulk_update_service.rb b/app/services/issuable/bulk_update_service.rb
index 2cd0e1e992d..2902385da4a 100644
--- a/app/services/issuable/bulk_update_service.rb
+++ b/app/services/issuable/bulk_update_service.rb
@@ -17,9 +17,8 @@ module Issuable
ids = params.delete(:issuable_ids).split(",")
items = find_issuables(parent, model_class, ids)
- permitted_attrs(type).each do |key|
- params.delete(key) unless params[key].present?
- end
+ params.slice!(*permitted_attrs(type))
+ params.delete_if { |k, v| v.blank? }
if params[:assignee_ids] == [IssuableFinder::Params::NONE.to_s]
params[:assignee_ids] = []
@@ -40,9 +39,13 @@ module Issuable
private
def permitted_attrs(type)
- attrs = %i(state_event milestone_id assignee_id assignee_ids add_label_ids remove_label_ids subscription_event)
+ attrs = %i(state_event milestone_id add_label_ids remove_label_ids subscription_event)
+
+ issuable_specific_attrs(type, attrs)
+ end
- if type == 'issue'
+ def issuable_specific_attrs(type, attrs)
+ if type == 'issue' || type == 'merge_request'
attrs.push(:assignee_ids)
else
attrs.push(:assignee_id)
diff --git a/app/services/issuable/clone/attributes_rewriter.rb b/app/services/issuable/clone/attributes_rewriter.rb
index a78e191c85f..b185ab592ff 100644
--- a/app/services/issuable/clone/attributes_rewriter.rb
+++ b/app/services/issuable/clone/attributes_rewriter.rb
@@ -105,7 +105,7 @@ module Issuable
yield(event)
end.compact
- Gitlab::Database.bulk_insert(table_name, events)
+ Gitlab::Database.bulk_insert(table_name, events) # rubocop:disable Gitlab/BulkInsert
end
end
diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb
index 18062bd60da..38b10996f44 100644
--- a/app/services/issuable_base_service.rb
+++ b/app/services/issuable_base_service.rb
@@ -129,15 +129,11 @@ class IssuableBaseService < BaseService
add_label_ids = attributes.delete(:add_label_ids)
remove_label_ids = attributes.delete(:remove_label_ids)
- new_label_ids = existing_label_ids || label_ids || []
+ new_label_ids = label_ids || existing_label_ids || []
new_label_ids |= extra_label_ids
- if add_label_ids.blank? && remove_label_ids.blank?
- new_label_ids = label_ids if label_ids
- else
- new_label_ids |= add_label_ids if add_label_ids
- new_label_ids -= remove_label_ids if remove_label_ids
- end
+ new_label_ids |= add_label_ids if add_label_ids
+ new_label_ids -= remove_label_ids if remove_label_ids
new_label_ids.uniq
end
@@ -350,7 +346,7 @@ class IssuableBaseService < BaseService
todo_service.mark_todo(issuable, current_user)
when 'done'
todo = TodosFinder.new(current_user).find_by(target: issuable)
- todo_service.mark_todos_as_done_by_ids(todo, current_user) if todo
+ todo_service.resolve_todo(todo, current_user) if todo
end
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/services/issues/create_service.rb b/app/services/issues/create_service.rb
index 7869509aa9c..c0194f5b847 100644
--- a/app/services/issues/create_service.rb
+++ b/app/services/issues/create_service.rb
@@ -15,7 +15,7 @@ module Issues
end
def before_create(issue)
- spam_check(issue, current_user)
+ spam_check(issue, current_user, action: :create)
issue.move_to_end
# current_user (defined in BaseService) is not available within run_after_commit block
@@ -38,9 +38,8 @@ module Issues
return if discussions_to_resolve.empty?
Discussions::ResolveService.new(project, current_user,
- merge_request: merge_request_to_resolve_discussions_of,
- follow_up_issue: issue)
- .execute(discussions_to_resolve)
+ one_or_more_discussions: discussions_to_resolve,
+ follow_up_issue: issue).execute
end
private
diff --git a/app/services/issues/import_csv_service.rb b/app/services/issues/import_csv_service.rb
index c01db5fcfe6..60790ba3547 100644
--- a/app/services/issues/import_csv_service.rb
+++ b/app/services/issues/import_csv_service.rb
@@ -46,7 +46,7 @@ module Issues
end
def email_results_to_user
- Notify.import_issues_csv_email(@user.id, @project.id, @results).deliver_now
+ Notify.import_issues_csv_email(@user.id, @project.id, @results).deliver_later
end
def detect_col_sep(header)
diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb
index ee1a22634af..8d22f0edcdd 100644
--- a/app/services/issues/update_service.rb
+++ b/app/services/issues/update_service.rb
@@ -18,7 +18,7 @@ module Issues
end
def before_update(issue, skip_spam_check: false)
- spam_check(issue, current_user) unless skip_spam_check
+ spam_check(issue, current_user, action: :update) unless skip_spam_check
end
def after_update(issue)
@@ -32,7 +32,7 @@ module Issues
old_assignees = old_associations.fetch(:assignees, [])
if has_changes?(issue, old_labels: old_labels, old_assignees: old_assignees)
- todo_service.mark_pending_todos_as_done(issue, current_user)
+ todo_service.resolve_todos_for_target(issue, current_user)
end
if issue.previous_changes.include?('title') ||
@@ -68,7 +68,7 @@ module Issues
end
def handle_task_changes(issuable)
- todo_service.mark_pending_todos_as_done(issuable, current_user)
+ todo_service.resolve_todos_for_target(issuable, current_user)
todo_service.update_issue(issuable, current_user)
end
diff --git a/app/services/jira/requests/base.rb b/app/services/jira/requests/base.rb
new file mode 100644
index 00000000000..7521c7610cb
--- /dev/null
+++ b/app/services/jira/requests/base.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+module Jira
+ module Requests
+ class Base
+ include ProjectServicesLoggable
+
+ PER_PAGE = 50
+
+ attr_reader :jira_service, :project, :limit, :start_at, :query
+
+ def initialize(jira_service, limit: PER_PAGE, start_at: 0, query: nil)
+ @project = jira_service&.project
+ @jira_service = jira_service
+
+ @limit = limit
+ @start_at = start_at
+ @query = query
+ end
+
+ def execute
+ return ServiceResponse.error(message: _('Jira service not configured.')) unless jira_service&.active?
+ return ServiceResponse.success(payload: empty_payload) if limit.to_i <= 0
+
+ request
+ end
+
+ private
+
+ def client
+ @client ||= jira_service.client
+ end
+
+ def request
+ response = client.get(url)
+ build_service_response(response)
+ rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, Errno::ECONNREFUSED, URI::InvalidURIError, JIRA::HTTPError, OpenSSL::SSL::SSLError => error
+ error_message = "Jira request error: #{error.message}"
+ log_error("Error sending message", client_url: client.options[:site], error: error_message)
+ ServiceResponse.error(message: error_message)
+ end
+
+ def url
+ raise NotImplementedError
+ end
+
+ def build_service_response(response)
+ raise NotImplementedError
+ end
+ end
+ end
+end
diff --git a/app/services/jira/requests/projects.rb b/app/services/jira/requests/projects.rb
new file mode 100644
index 00000000000..da464503211
--- /dev/null
+++ b/app/services/jira/requests/projects.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module Jira
+ module Requests
+ class Projects < Base
+ extend ::Gitlab::Utils::Override
+
+ private
+
+ override :url
+ def url
+ '/rest/api/2/project/search?query=%{query}&maxResults=%{limit}&startAt=%{start_at}' %
+ { query: CGI.escape(query.to_s), limit: limit.to_i, start_at: start_at.to_i }
+ end
+
+ override :build_service_response
+ def build_service_response(response)
+ return ServiceResponse.success(payload: empty_payload) unless response['values'].present?
+
+ ServiceResponse.success(payload: { projects: map_projects(response), is_last: response['isLast'] })
+ end
+
+ def map_projects(response)
+ response['values'].map { |v| JIRA::Resource::Project.build(client, v) }
+ end
+
+ def empty_payload
+ { projects: [], is_last: true }
+ end
+ end
+ end
+end
diff --git a/app/services/jira_import/start_import_service.rb b/app/services/jira_import/start_import_service.rb
index 59fd463022f..a06cc6df719 100644
--- a/app/services/jira_import/start_import_service.rb
+++ b/app/services/jira_import/start_import_service.rb
@@ -28,8 +28,8 @@ module JiraImport
rescue => ex
# in case project.save! raises an erorr
Gitlab::ErrorTracking.track_exception(ex, project_id: project.id)
+ jira_import&.do_fail!(error_message: ex.message)
build_error_response(ex.message)
- jira_import.do_fail!
end
def build_jira_import
@@ -62,7 +62,7 @@ module JiraImport
end
def validate
- project.validate_jira_import_settings!(user: user)
+ Gitlab::JiraImport.validate_project_settings!(project, user: user)
return build_error_response(_('Unable to find Jira project to import data from.')) if jira_project_key.blank?
return build_error_response(_('Jira import is already running.')) if import_in_progress?
diff --git a/app/services/jira_import/users_importer.rb b/app/services/jira_import/users_importer.rb
new file mode 100644
index 00000000000..579d3675073
--- /dev/null
+++ b/app/services/jira_import/users_importer.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+module JiraImport
+ class UsersImporter
+ attr_reader :user, :project, :start_at, :result
+
+ MAX_USERS = 50
+
+ def initialize(user, project, start_at)
+ @project = project
+ @start_at = start_at
+ @user = user
+ end
+
+ def execute
+ Gitlab::JiraImport.validate_project_settings!(project, user: user)
+
+ return ServiceResponse.success(payload: nil) if users.blank?
+
+ result = UsersMapper.new(project, users).execute
+ ServiceResponse.success(payload: result)
+ rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, Errno::ECONNREFUSED, URI::InvalidURIError, JIRA::HTTPError, OpenSSL::SSL::SSLError => error
+ Gitlab::ErrorTracking.track_exception(error, project_id: project.id, request: url)
+ ServiceResponse.error(message: "There was an error when communicating to Jira: #{error.message}")
+ rescue Projects::ImportService::Error => error
+ ServiceResponse.error(message: error.message)
+ end
+
+ private
+
+ def users
+ @users ||= client.get(url)
+ end
+
+ def url
+ "/rest/api/2/users?maxResults=#{MAX_USERS}&startAt=#{start_at.to_i}"
+ end
+
+ def client
+ @client ||= project.jira_service.client
+ end
+ end
+end
diff --git a/app/services/jira_import/users_mapper.rb b/app/services/jira_import/users_mapper.rb
new file mode 100644
index 00000000000..31a3f721556
--- /dev/null
+++ b/app/services/jira_import/users_mapper.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module JiraImport
+ class UsersMapper
+ attr_reader :project, :jira_users
+
+ def initialize(project, jira_users)
+ @project = project
+ @jira_users = jira_users
+ end
+
+ def execute
+ jira_users.to_a.map do |jira_user|
+ {
+ jira_account_id: jira_user['accountId'],
+ jira_display_name: jira_user['displayName'],
+ jira_email: jira_user['emailAddress'],
+ gitlab_id: match_user(jira_user)
+ }
+ end
+ end
+
+ private
+
+ # TODO: Matching user by email and displayName will be done as the part
+ # of follow-up issue: https://gitlab.com/gitlab-org/gitlab/-/issues/219023
+ def match_user(jira_user)
+ nil
+ end
+ end
+end
diff --git a/app/services/keys/create_service.rb b/app/services/keys/create_service.rb
index 32c4ab645df..c256de7b35d 100644
--- a/app/services/keys/create_service.rb
+++ b/app/services/keys/create_service.rb
@@ -2,6 +2,14 @@
module Keys
class CreateService < ::Keys::BaseService
+ attr_accessor :current_user
+
+ def initialize(current_user, params = {})
+ @current_user, @params = current_user, params
+ @ip_address = @params.delete(:ip_address)
+ @user = params.delete(:user) || current_user
+ end
+
def execute
key = user.keys.create(params)
notification_service.new_key(key) if key.persisted?
diff --git a/app/services/labels/available_labels_service.rb b/app/services/labels/available_labels_service.rb
index 8886e58d6ef..979964e09fd 100644
--- a/app/services/labels/available_labels_service.rb
+++ b/app/services/labels/available_labels_service.rb
@@ -30,11 +30,13 @@ module Labels
end
def filter_labels_ids_in_param(key)
- return [] if params[key].to_a.empty?
+ ids = params[key].to_a
+ return [] if ids.empty?
# rubocop:disable CodeReuse/ActiveRecord
- available_labels.by_ids(params[key]).pluck(:id)
+ existing_ids = available_labels.by_ids(ids).pluck(:id)
# rubocop:enable CodeReuse/ActiveRecord
+ ids.map(&:to_i) & existing_ids
end
private
diff --git a/app/services/labels/create_service.rb b/app/services/labels/create_service.rb
index c032985be42..a5b30e29e55 100644
--- a/app/services/labels/create_service.rb
+++ b/app/services/labels/create_service.rb
@@ -20,7 +20,7 @@ module Labels
label.save
label
else
- Rails.logger.warn("target_params should contain :project or :group or :template, actual value: #{target_params}") # rubocop:disable Gitlab/RailsLogger
+ Gitlab::AppLogger.warn("target_params should contain :project or :group or :template, actual value: #{target_params}")
end
end
end
diff --git a/app/services/labels/promote_service.rb b/app/services/labels/promote_service.rb
index cc91fd4b4d2..9ed10f6a11b 100644
--- a/app/services/labels/promote_service.rb
+++ b/app/services/labels/promote_service.rb
@@ -90,7 +90,7 @@ module Labels
# rubocop: disable CodeReuse/ActiveRecord
def destroy_project_labels(label_ids)
- Label.where(id: label_ids).destroy_all # rubocop: disable DestroyAll
+ Label.where(id: label_ids).destroy_all # rubocop: disable Cop/DestroyAll
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb
index 31097b9151a..8d57a76f7d0 100644
--- a/app/services/merge_requests/merge_service.rb
+++ b/app/services/merge_requests/merge_service.rb
@@ -121,12 +121,12 @@ module MergeRequests
end
def handle_merge_error(log_message:, save_message_on_model: false)
- Rails.logger.error("MergeService ERROR: #{merge_request_info} - #{log_message}") # rubocop:disable Gitlab/RailsLogger
+ Gitlab::AppLogger.error("MergeService ERROR: #{merge_request_info} - #{log_message}")
@merge_request.update(merge_error: log_message) if save_message_on_model
end
def log_info(message)
- @logger ||= Rails.logger # rubocop:disable Gitlab/RailsLogger
+ @logger ||= Gitlab::AppLogger
@logger.info("#{merge_request_info} - #{message}")
end
diff --git a/app/services/merge_requests/update_service.rb b/app/services/merge_requests/update_service.rb
index 2d33e87bf4b..561695baeab 100644
--- a/app/services/merge_requests/update_service.rb
+++ b/app/services/merge_requests/update_service.rb
@@ -27,7 +27,7 @@ module MergeRequests
old_assignees = old_associations.fetch(:assignees, [])
if has_changes?(merge_request, old_labels: old_labels, old_assignees: old_assignees)
- todo_service.mark_pending_todos_as_done(merge_request, current_user)
+ todo_service.resolve_todos_for_target(merge_request, current_user)
end
if merge_request.previous_changes.include?('title') ||
@@ -73,7 +73,7 @@ module MergeRequests
end
def handle_task_changes(merge_request)
- todo_service.mark_pending_todos_as_done(merge_request, current_user)
+ todo_service.resolve_todos_for_target(merge_request, current_user)
todo_service.update_merge_request(merge_request, current_user)
end
diff --git a/app/services/metrics/dashboard/base_service.rb b/app/services/metrics/dashboard/base_service.rb
index 514793694ba..c2a0f22e73e 100644
--- a/app/services/metrics/dashboard/base_service.rb
+++ b/app/services/metrics/dashboard/base_service.rb
@@ -13,7 +13,8 @@ module Metrics
STAGES::EndpointInserter,
STAGES::PanelIdsInserter,
STAGES::Sorter,
- STAGES::AlertsInserter
+ STAGES::AlertsInserter,
+ STAGES::UrlValidator
].freeze
def get_dashboard
diff --git a/app/services/metrics/dashboard/self_monitoring_dashboard_service.rb b/app/services/metrics/dashboard/self_monitoring_dashboard_service.rb
index d97668d1c7c..8599c23c206 100644
--- a/app/services/metrics/dashboard/self_monitoring_dashboard_service.rb
+++ b/app/services/metrics/dashboard/self_monitoring_dashboard_service.rb
@@ -6,7 +6,7 @@ module Metrics
module Dashboard
class SelfMonitoringDashboardService < ::Metrics::Dashboard::PredefinedDashboardService
DASHBOARD_PATH = 'config/prometheus/self_monitoring_default.yml'
- DASHBOARD_NAME = 'Default'
+ DASHBOARD_NAME = N_('Default dashboard')
SEQUENCE = [
STAGES::CustomMetricsInserter,
@@ -23,7 +23,7 @@ module Metrics
def all_dashboard_paths(_project)
[{
path: DASHBOARD_PATH,
- display_name: DASHBOARD_NAME,
+ display_name: _(DASHBOARD_NAME),
default: true,
system_dashboard: false
}]
diff --git a/app/services/metrics/dashboard/system_dashboard_service.rb b/app/services/metrics/dashboard/system_dashboard_service.rb
index ed4b78ba159..db5599b4def 100644
--- a/app/services/metrics/dashboard/system_dashboard_service.rb
+++ b/app/services/metrics/dashboard/system_dashboard_service.rb
@@ -6,7 +6,7 @@ module Metrics
module Dashboard
class SystemDashboardService < ::Metrics::Dashboard::PredefinedDashboardService
DASHBOARD_PATH = 'config/prometheus/common_metrics.yml'
- DASHBOARD_NAME = 'Default'
+ DASHBOARD_NAME = N_('Default dashboard')
SEQUENCE = [
STAGES::CommonMetricsInserter,
@@ -22,7 +22,7 @@ module Metrics
def all_dashboard_paths(_project)
[{
path: DASHBOARD_PATH,
- display_name: DASHBOARD_NAME,
+ display_name: _(DASHBOARD_NAME),
default: true,
system_dashboard: true
}]
diff --git a/app/services/milestones/promote_service.rb b/app/services/milestones/promote_service.rb
index 80e6456f729..2431318cbb2 100644
--- a/app/services/milestones/promote_service.rb
+++ b/app/services/milestones/promote_service.rb
@@ -76,7 +76,7 @@ module Milestones
# rubocop: disable CodeReuse/ActiveRecord
def destroy_old_milestones(milestone)
- Milestone.where(id: milestone_ids_for_merge(milestone)).destroy_all # rubocop: disable DestroyAll
+ Milestone.where(id: milestone_ids_for_merge(milestone)).destroy_all # rubocop: disable Cop/DestroyAll
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/services/namespaces/check_storage_size_service.rb b/app/services/namespaces/check_storage_size_service.rb
index b3cf17681ee..57d2645a0c8 100644
--- a/app/services/namespaces/check_storage_size_service.rb
+++ b/app/services/namespaces/check_storage_size_service.rb
@@ -41,7 +41,8 @@ module Namespaces
{
explanation_message: explanation_message,
usage_message: usage_message,
- alert_level: alert_level
+ alert_level: alert_level,
+ root_namespace: root_namespace
}
end
@@ -50,7 +51,7 @@ module Namespaces
end
def usage_message
- s_("You reached %{usage_in_percent} of %{namespace_name}'s capacity (%{used_storage} of %{storage_limit})" % current_usage_params)
+ s_("You reached %{usage_in_percent} of %{namespace_name}'s storage capacity (%{used_storage} of %{storage_limit})" % current_usage_params)
end
def alert_level
diff --git a/app/services/notes/create_service.rb b/app/services/notes/create_service.rb
index 6c1f52ec866..935dbfb72dd 100644
--- a/app/services/notes/create_service.rb
+++ b/app/services/notes/create_service.rb
@@ -88,9 +88,11 @@ module Notes
end
end
- # EE::Notes::CreateService would override this method
def quick_action_options
- { merge_request_diff_head_sha: params[:merge_request_diff_head_sha] }
+ {
+ merge_request_diff_head_sha: params[:merge_request_diff_head_sha],
+ review_id: params[:review_id]
+ }
end
def tracking_data_for(note)
@@ -103,5 +105,3 @@ module Notes
end
end
end
-
-Notes::CreateService.prepend_if_ee('EE::Notes::CreateService')
diff --git a/app/services/notes/post_process_service.rb b/app/services/notes/post_process_service.rb
index bc86118a150..0e455c641ce 100644
--- a/app/services/notes/post_process_service.rb
+++ b/app/services/notes/post_process_service.rb
@@ -36,7 +36,7 @@ module Notes
return unless @note.project
note_data = hook_data
- hooks_scope = @note.confidential? ? :confidential_note_hooks : :note_hooks
+ hooks_scope = @note.confidential?(include_noteable: true) ? :confidential_note_hooks : :note_hooks
@note.project.execute_hooks(note_data, hooks_scope)
@note.project.execute_services(note_data, hooks_scope)
diff --git a/app/services/notification_recipients/build_service.rb b/app/services/notification_recipients/build_service.rb
index df807f11e1b..0fe0d26d7b2 100644
--- a/app/services/notification_recipients/build_service.rb
+++ b/app/services/notification_recipients/build_service.rb
@@ -32,7 +32,9 @@ module NotificationRecipients
def self.build_new_release_recipients(*args)
::NotificationRecipients::Builder::NewRelease.new(*args).notification_recipients
end
+
+ def self.build_new_review_recipients(*args)
+ ::NotificationRecipients::Builder::NewReview.new(*args).notification_recipients
+ end
end
end
-
-NotificationRecipients::BuildService.prepend_if_ee('EE::NotificationRecipients::BuildService')
diff --git a/app/services/notification_recipients/builder/new_review.rb b/app/services/notification_recipients/builder/new_review.rb
new file mode 100644
index 00000000000..3b1296f6967
--- /dev/null
+++ b/app/services/notification_recipients/builder/new_review.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+module NotificationRecipients
+ module Builder
+ class NewReview < Base
+ attr_reader :review
+ def initialize(review)
+ @review = review
+ end
+
+ def target
+ review.merge_request
+ end
+
+ def project
+ review.project
+ end
+
+ def group
+ project.group
+ end
+
+ def build!
+ add_participants(review.author)
+ add_mentions(review.author, target: review)
+ add_project_watchers
+ add_custom_notifications
+ add_subscribed_users
+ end
+
+ # A new review is a batch of new notes
+ # therefore new_note subscribers should also
+ # receive incoming new reviews
+ def custom_action
+ :new_note
+ end
+
+ def acting_user
+ review.author
+ end
+ end
+ end
+end
diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb
index 4c1db03fab8..73e60ac8420 100644
--- a/app/services/notification_service.rb
+++ b/app/services/notification_service.rb
@@ -68,10 +68,10 @@ class NotificationService
# Notify a user when a previously unknown IP or device is used to
# sign in to their account
- def unknown_sign_in(user, ip)
+ def unknown_sign_in(user, ip, time)
return unless user.can?(:receive_notifications)
- mailer.unknown_sign_in_email(user, ip).deliver_later
+ mailer.unknown_sign_in_email(user, ip, time).deliver_later
end
# When create an issue we should send an email to:
@@ -447,14 +447,14 @@ class NotificationService
# from the PipelinesEmailService integration.
return if pipeline.project.emails_disabled?
- ref_status ||= pipeline.status
- email_template = "pipeline_#{ref_status}_email"
+ status = pipeline_notification_status(ref_status, pipeline)
+ email_template = "pipeline_#{status}_email"
return unless mailer.respond_to?(email_template)
recipients ||= notifiable_users(
[pipeline.user], :watch,
- custom_action: :"#{ref_status}_pipeline",
+ custom_action: :"#{status}_pipeline",
target: pipeline
).map do |user|
user.notification_email_for(pipeline.project.group)
@@ -557,6 +557,15 @@ class NotificationService
mailer.group_was_not_exported_email(current_user, group, errors).deliver_later
end
+ # Notify users on new review in system
+ def new_review(review)
+ recipients = NotificationRecipients::BuildService.build_new_review_recipients(review)
+
+ recipients.each do |recipient|
+ mailer.new_review_email(recipient.user.id, review.id).deliver_later
+ end
+ end
+
protected
def new_resource_email(target, method)
@@ -652,6 +661,16 @@ class NotificationService
private
+ def pipeline_notification_status(ref_status, pipeline)
+ if Ci::Ref.failing_state?(ref_status)
+ 'failed'
+ elsif ref_status
+ ref_status
+ else
+ pipeline.status
+ end
+ end
+
def owners_and_maintainers_without_invites(project)
recipients = project.members.active_without_invites_and_requests.owners_and_maintainers
diff --git a/app/services/pages/delete_service.rb b/app/services/pages/delete_service.rb
index d4de6bb750d..7408943e78c 100644
--- a/app/services/pages/delete_service.rb
+++ b/app/services/pages/delete_service.rb
@@ -4,7 +4,7 @@ module Pages
class DeleteService < BaseService
def execute
project.remove_pages
- project.pages_domains.destroy_all # rubocop: disable DestroyAll
+ project.pages_domains.destroy_all # rubocop: disable Cop/DestroyAll
end
end
end
diff --git a/app/services/projects/after_import_service.rb b/app/services/projects/after_import_service.rb
index ee2dde8aa7f..fad2290a47b 100644
--- a/app/services/projects/after_import_service.rb
+++ b/app/services/projects/after_import_service.rb
@@ -22,8 +22,12 @@ module Projects
# causing GC to run every time.
service.increment!
rescue Projects::HousekeepingService::LeaseTaken => e
- Rails.logger.info( # rubocop:disable Gitlab/RailsLogger
- "Could not perform housekeeping for project #{@project.full_path} (#{@project.id}): #{e}")
+ Gitlab::Import::Logger.info(
+ message: 'Project housekeeping failed',
+ project_full_path: @project.full_path,
+ project_id: @project.id,
+ error: e.message
+ )
end
private
diff --git a/app/services/projects/alerting/notify_service.rb b/app/services/projects/alerting/notify_service.rb
index 76c89e85f17..86c408aeec8 100644
--- a/app/services/projects/alerting/notify_service.rb
+++ b/app/services/projects/alerting/notify_service.rb
@@ -10,7 +10,7 @@ module Projects
return forbidden unless alerts_service_activated?
return unauthorized unless valid_token?(token)
- alert = create_alert
+ alert = process_alert
return bad_request unless alert.persisted?
process_incident_issues(alert) if process_issues?
@@ -26,11 +26,36 @@ module Projects
delegate :alerts_service, :alerts_service_activated?, to: :project
def am_alert_params
- Gitlab::AlertManagement::AlertParams.from_generic_alert(project: project, payload: params.to_h)
+ strong_memoize(:am_alert_params) do
+ Gitlab::AlertManagement::AlertParams.from_generic_alert(project: project, payload: params.to_h)
+ end
+ end
+
+ def process_alert
+ existing_alert = find_alert_by_fingerprint(am_alert_params[:fingerprint])
+
+ if existing_alert
+ process_existing_alert(existing_alert)
+ else
+ create_alert
+ end
+ end
+
+ def process_existing_alert(alert)
+ alert.register_new_event!
end
def create_alert
- AlertManagement::Alert.create(am_alert_params)
+ alert = AlertManagement::Alert.create(am_alert_params)
+ alert.execute_services if alert.persisted?
+
+ alert
+ end
+
+ def find_alert_by_fingerprint(fingerprint)
+ return unless fingerprint
+
+ AlertManagement::Alert.for_fingerprint(project, fingerprint).first
end
def send_email?
@@ -38,6 +63,8 @@ module Projects
end
def process_incident_issues(alert)
+ return if alert.issue
+
IncidentManagement::ProcessAlertWorker
.perform_async(project.id, parsed_payload, alert.id)
end
diff --git a/app/services/projects/container_repository/cleanup_tags_service.rb b/app/services/projects/container_repository/cleanup_tags_service.rb
index b53a9c1561e..c5809c11ea9 100644
--- a/app/services/projects/container_repository/cleanup_tags_service.rb
+++ b/app/services/projects/container_repository/cleanup_tags_service.rb
@@ -6,6 +6,7 @@ module Projects
def execute(container_repository)
return error('feature disabled') unless can_use?
return error('access denied') unless can_destroy?
+ return error('invalid regex') unless valid_regex?
tags = container_repository.tags
tags = without_latest(tags)
@@ -76,6 +77,17 @@ module Projects
def can_use?
Feature.enabled?(:container_registry_cleanup, project, default_enabled: true)
end
+
+ def valid_regex?
+ %w(name_regex_delete name_regex name_regex_keep).each do |param_name|
+ regex = params[param_name]
+ Gitlab::UntrustedRegexp.new(regex) unless regex.blank?
+ end
+ true
+ rescue RegexpError => e
+ Gitlab::ErrorTracking.log_exception(e, project_id: project.id)
+ false
+ end
end
end
end
diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb
index 3233d1799b8..bffd443c49f 100644
--- a/app/services/projects/create_service.rb
+++ b/app/services/projects/create_service.rb
@@ -150,7 +150,7 @@ module Projects
if @project.save
unless @project.gitlab_project_import?
- create_services_from_active_templates(@project)
+ create_services_from_active_instances_or_templates(@project)
@project.create_labels
end
@@ -166,7 +166,7 @@ module Projects
log_message = message.dup
log_message << " Project ID: #{@project.id}" if @project&.id
- Rails.logger.error(log_message) # rubocop:disable Gitlab/RailsLogger
+ Gitlab::AppLogger.error(log_message)
if @project && @project.persisted? && @project.import_state
@project.import_state.mark_as_failed(message)
@@ -175,15 +175,6 @@ module Projects
@project
end
- # rubocop: disable CodeReuse/ActiveRecord
- def create_services_from_active_templates(project)
- Service.where(template: true, active: true).each do |template|
- service = Service.build_from_template(project.id, template)
- service.save!
- end
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
def create_prometheus_service
service = @project.find_or_initialize_service(::PrometheusService.to_param)
@@ -225,6 +216,15 @@ module Projects
private
+ # rubocop: disable CodeReuse/ActiveRecord
+ def create_services_from_active_instances_or_templates(project)
+ Service.active.where(instance: true).or(Service.active.where(template: true)).group_by(&:type).each do |type, records|
+ service = records.find(&:instance?) || records.find(&:template?)
+ Service.build_from_integration(project.id, service).save!
+ end
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
def project_namespace
@project_namespace ||= Namespace.find_by_id(@params[:namespace_id]) || current_user.namespace
end
@@ -249,9 +249,7 @@ module Projects
end
end
-# rubocop: disable Cop/InjectEnterpriseEditionModule
Projects::CreateService.prepend_if_ee('EE::Projects::CreateService')
-# rubocop: enable Cop/InjectEnterpriseEditionModule
# Measurable should be at the bottom of the ancestor chain, so it will measure execution of EE::Projects::CreateService as well
Projects::CreateService.prepend(Measurable)
diff --git a/app/services/projects/destroy_service.rb b/app/services/projects/destroy_service.rb
index fd1366d2c4a..2e949f2fc55 100644
--- a/app/services/projects/destroy_service.rb
+++ b/app/services/projects/destroy_service.rb
@@ -64,7 +64,7 @@ module Projects
end
def remove_snippets
- response = Snippets::BulkDestroyService.new(current_user, project.snippets).execute
+ response = ::Snippets::BulkDestroyService.new(current_user, project.snippets).execute
response.success?
end
diff --git a/app/services/projects/detect_repository_languages_service.rb b/app/services/projects/detect_repository_languages_service.rb
index 942cd8162e4..c57773c3302 100644
--- a/app/services/projects/detect_repository_languages_service.rb
+++ b/app/services/projects/detect_repository_languages_service.rb
@@ -21,7 +21,7 @@ module Projects
.update_all(share: update[:share])
end
- Gitlab::Database.bulk_insert(
+ Gitlab::Database.bulk_insert( # rubocop:disable Gitlab/BulkInsert
RepositoryLanguage.table_name,
detection.insertions(matching_programming_languages)
)
diff --git a/app/services/projects/group_links/create_service.rb b/app/services/projects/group_links/create_service.rb
index 241948b335b..2ba3cd6694f 100644
--- a/app/services/projects/group_links/create_service.rb
+++ b/app/services/projects/group_links/create_service.rb
@@ -13,6 +13,7 @@ module Projects
)
if link.save
+ group.refresh_members_authorized_projects
success(link: link)
else
error(link.errors.full_messages.to_sentence, 409)
diff --git a/app/services/projects/group_links/destroy_service.rb b/app/services/projects/group_links/destroy_service.rb
index ea7d05551fd..229191e41f6 100644
--- a/app/services/projects/group_links/destroy_service.rb
+++ b/app/services/projects/group_links/destroy_service.rb
@@ -12,7 +12,9 @@ module Projects
TodosDestroyer::ConfidentialIssueWorker.perform_in(Todo::WAIT_FOR_DELETE, nil, project.id)
end
- group_link.destroy
+ group_link.destroy.tap do |link|
+ link.group.refresh_members_authorized_projects
+ end
end
end
end
diff --git a/app/services/projects/group_links/update_service.rb b/app/services/projects/group_links/update_service.rb
new file mode 100644
index 00000000000..7de4b7a211d
--- /dev/null
+++ b/app/services/projects/group_links/update_service.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module Projects
+ module GroupLinks
+ class UpdateService < BaseService
+ def initialize(group_link, user = nil)
+ super(group_link.project, user)
+
+ @group_link = group_link
+ end
+
+ def execute(group_link_params)
+ group_link.update!(group_link_params)
+
+ if requires_authorization_refresh?(group_link_params)
+ group_link.group.refresh_members_authorized_projects
+ end
+ end
+
+ private
+
+ attr_reader :group_link
+
+ def requires_authorization_refresh?(params)
+ params.include?(:group_access)
+ end
+ end
+ end
+end
diff --git a/app/services/projects/hashed_storage/base_attachment_service.rb b/app/services/projects/hashed_storage/base_attachment_service.rb
index a2a7895ba17..d61a2af6c1c 100644
--- a/app/services/projects/hashed_storage/base_attachment_service.rb
+++ b/app/services/projects/hashed_storage/base_attachment_service.rb
@@ -19,7 +19,7 @@ module Projects
def initialize(project:, old_disk_path:, logger: nil)
@project = project
@old_disk_path = old_disk_path
- @logger = logger || Rails.logger # rubocop:disable Gitlab/RailsLogger
+ @logger = logger || Gitlab::AppLogger
end
# Return whether this operation was skipped or not
diff --git a/app/services/projects/import_export/export_service.rb b/app/services/projects/import_export/export_service.rb
index 86cb4f35206..031b99753c3 100644
--- a/app/services/projects/import_export/export_service.rb
+++ b/app/services/projects/import_export/export_service.rb
@@ -9,6 +9,7 @@ module Projects
super
@shared = project.import_export_shared
+ @logger = Gitlab::Export::Logger.build
end
def execute(after_export_strategy = nil)
@@ -115,11 +116,20 @@ module Projects
end
def notify_success
- Rails.logger.info("Import/Export - Project #{project.name} with ID: #{project.id} successfully exported") # rubocop:disable Gitlab/RailsLogger
+ @logger.info(
+ message: 'Project successfully exported',
+ project_name: project.name,
+ project_id: project.id
+ )
end
def notify_error
- Rails.logger.error("Import/Export - Project #{project.name} with ID: #{project.id} export error - #{shared.errors.join(', ')}") # rubocop:disable Gitlab/RailsLogger
+ @logger.error(
+ message: 'Project export error',
+ export_errors: shared.errors.join(', '),
+ project_name: project.name,
+ project_id: project.id
+ )
notification_service.project_not_exported(project, current_user, shared.errors)
end
diff --git a/app/services/projects/import_service.rb b/app/services/projects/import_service.rb
index 449c4c3de6b..b4abb5b6df7 100644
--- a/app/services/projects/import_service.rb
+++ b/app/services/projects/import_service.rb
@@ -149,9 +149,7 @@ module Projects
end
end
-# rubocop: disable Cop/InjectEnterpriseEditionModule
Projects::ImportService.prepend_if_ee('EE::Projects::ImportService')
-# rubocop: enable Cop/InjectEnterpriseEditionModule
# Measurable should be at the bottom of the ancestor chain, so it will measure execution of EE::Projects::ImportService as well
Projects::ImportService.prepend(Measurable)
diff --git a/app/services/projects/lfs_pointers/lfs_link_service.rb b/app/services/projects/lfs_pointers/lfs_link_service.rb
index 39cd553261f..e86106f0a09 100644
--- a/app/services/projects/lfs_pointers/lfs_link_service.rb
+++ b/app/services/projects/lfs_pointers/lfs_link_service.rb
@@ -38,7 +38,7 @@ module Projects
rows = existent_lfs_objects
.not_linked_to_project(project)
.map { |existing_lfs_object| { project_id: project.id, lfs_object_id: existing_lfs_object.id } }
- Gitlab::Database.bulk_insert(:lfs_objects_projects, rows)
+ Gitlab::Database.bulk_insert(:lfs_objects_projects, rows) # rubocop:disable Gitlab/BulkInsert
iterations += 1
linked_existing_objects += existent_lfs_objects.map(&:oid)
diff --git a/app/services/projects/lsif_data_service.rb b/app/services/projects/lsif_data_service.rb
deleted file mode 100644
index 5e7055b3309..00000000000
--- a/app/services/projects/lsif_data_service.rb
+++ /dev/null
@@ -1,101 +0,0 @@
-# frozen_string_literal: true
-
-module Projects
- class LsifDataService
- attr_reader :file, :project, :commit_id, :docs,
- :doc_ranges, :ranges, :def_refs, :hover_refs
-
- CACHE_EXPIRE_IN = 1.hour
-
- def initialize(file, project, commit_id)
- @file = file
- @project = project
- @commit_id = commit_id
-
- fetch_data!
- end
-
- def execute(path)
- doc_id = find_doc_id(docs, path)
- dir_absolute_path = docs[doc_id]&.delete_suffix(path)
-
- doc_ranges[doc_id]&.map do |range_id|
- location, ref_id = ranges[range_id].values_at('loc', 'ref_id')
- line_data, column_data = location
-
- {
- start_line: line_data.first,
- end_line: line_data.last,
- start_char: column_data.first,
- end_char: column_data.last,
- definition_url: definition_url_for(def_refs[ref_id], dir_absolute_path),
- hover: highlighted_hover(hover_refs[ref_id])
- }
- end
- end
-
- private
-
- def fetch_data
- Rails.cache.fetch("project:#{project.id}:lsif:#{commit_id}", expires_in: CACHE_EXPIRE_IN) do
- data = nil
-
- file.open do |stream|
- Zlib::GzipReader.wrap(stream) do |gz_stream|
- data = Gitlab::Json.parse(gz_stream.read)
- end
- end
-
- data
- end
- end
-
- def fetch_data!
- data = fetch_data
-
- @docs = data['docs']
- @doc_ranges = data['doc_ranges']
- @ranges = data['ranges']
- @def_refs = data['def_refs']
- @hover_refs = data['hover_refs']
- end
-
- def find_doc_id(docs, path)
- docs.reduce(nil) do |doc_id, (id, doc_path)|
- next doc_id unless doc_path =~ /#{path}$/
-
- if doc_id.nil? || docs[doc_id].size > doc_path.size
- doc_id = id
- end
-
- doc_id
- end
- end
-
- def definition_url_for(ref_id, dir_absolute_path)
- return unless range = ranges[ref_id]
-
- def_doc_id, location = range.values_at('doc_id', 'loc')
- localized_doc_url = docs[def_doc_id].delete_prefix(dir_absolute_path)
-
- # location is stored as [[start_line, end_line], [start_char, end_char]]
- start_line = location.first.first
-
- line_anchor = "L#{start_line + 1}"
- definition_ref_path = [commit_id, localized_doc_url].join('/')
-
- Gitlab::Routing.url_helpers.project_blob_path(project, definition_ref_path, anchor: line_anchor)
- end
-
- def highlighted_hover(hovers)
- hovers&.map do |hover|
- # Documentation for a method which is added as comments on top of the method
- # is stored as a raw string value in LSIF file
- next { value: hover } unless hover.is_a?(Hash)
-
- value = Gitlab::Highlight.highlight(nil, hover['value'], language: hover['language'])
- { language: hover['language'], value: value }
- end
- end
- 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 01419563538..51d84af249e 100644
--- a/app/services/projects/move_deploy_keys_projects_service.rb
+++ b/app/services/projects/move_deploy_keys_projects_service.rb
@@ -28,7 +28,7 @@ module Projects
# rubocop: enable CodeReuse/ActiveRecord
def remove_remaining_deploy_keys_projects
- source_project.deploy_keys_projects.destroy_all # rubocop: disable DestroyAll
+ source_project.deploy_keys_projects.destroy_all # rubocop: disable Cop/DestroyAll
end
end
end
diff --git a/app/services/projects/move_lfs_objects_projects_service.rb b/app/services/projects/move_lfs_objects_projects_service.rb
index 8cc420d7ba7..57a8d3d69c6 100644
--- a/app/services/projects/move_lfs_objects_projects_service.rb
+++ b/app/services/projects/move_lfs_objects_projects_service.rb
@@ -20,7 +20,7 @@ module Projects
end
def remove_remaining_lfs_objects_project
- source_project.lfs_objects_projects.destroy_all # rubocop: disable DestroyAll
+ source_project.lfs_objects_projects.destroy_all # rubocop: disable Cop/DestroyAll
end
# rubocop: disable CodeReuse/ActiveRecord
diff --git a/app/services/projects/move_notification_settings_service.rb b/app/services/projects/move_notification_settings_service.rb
index 65a888fe26b..efe06f158cc 100644
--- a/app/services/projects/move_notification_settings_service.rb
+++ b/app/services/projects/move_notification_settings_service.rb
@@ -21,7 +21,7 @@ module Projects
# Remove remaining notification settings from source_project
def remove_remaining_notification_settings
- source_project.notification_settings.destroy_all # rubocop: disable DestroyAll
+ source_project.notification_settings.destroy_all # rubocop: disable Cop/DestroyAll
end
# Get users of current notification_settings
diff --git a/app/services/projects/move_project_group_links_service.rb b/app/services/projects/move_project_group_links_service.rb
index d1aa9af2bcb..349953ff973 100644
--- a/app/services/projects/move_project_group_links_service.rb
+++ b/app/services/projects/move_project_group_links_service.rb
@@ -25,7 +25,7 @@ module Projects
# Remove remaining project group links from source_project
def remove_remaining_project_group_links
- source_project.reset.project_group_links.destroy_all # rubocop: disable DestroyAll
+ source_project.reset.project_group_links.destroy_all # rubocop: disable Cop/DestroyAll
end
def group_links_in_target_project
diff --git a/app/services/projects/move_project_members_service.rb b/app/services/projects/move_project_members_service.rb
index de4e7e5a1e3..9a1b7c6d1b6 100644
--- a/app/services/projects/move_project_members_service.rb
+++ b/app/services/projects/move_project_members_service.rb
@@ -25,7 +25,7 @@ module Projects
def remove_remaining_members
# Remove remaining members and authorizations from source_project
- source_project.project_members.destroy_all # rubocop: disable DestroyAll
+ source_project.project_members.destroy_all # rubocop: disable Cop/DestroyAll
end
def project_members_in_target_project
diff --git a/app/services/projects/operations/update_service.rb b/app/services/projects/operations/update_service.rb
index c06f572b52f..7aa7ea73639 100644
--- a/app/services/projects/operations/update_service.rb
+++ b/app/services/projects/operations/update_service.rb
@@ -41,9 +41,9 @@ module Projects
attribs = params[:metrics_setting_attributes]
return {} unless attribs
- destroy = attribs[:external_dashboard_url].blank?
+ attribs[:external_dashboard_url] = attribs[:external_dashboard_url].presence
- { metrics_setting_attributes: attribs.merge(_destroy: destroy) }
+ { metrics_setting_attributes: attribs }
end
def error_tracking_params
diff --git a/app/services/projects/prometheus/alerts/create_events_service.rb b/app/services/projects/prometheus/alerts/create_events_service.rb
index a29240947ff..4fcf841314b 100644
--- a/app/services/projects/prometheus/alerts/create_events_service.rb
+++ b/app/services/projects/prometheus/alerts/create_events_service.rb
@@ -40,17 +40,13 @@ module Projects
def create_managed_prometheus_alert_event(parsed_alert)
alert = find_alert(parsed_alert.metric_id)
- payload_key = PrometheusAlertEvent.payload_key_for(parsed_alert.metric_id, parsed_alert.starts_at_raw)
-
- event = PrometheusAlertEvent.find_or_initialize_by_payload_key(parsed_alert.project, alert, payload_key)
+ event = PrometheusAlertEvent.find_or_initialize_by_payload_key(parsed_alert.project, alert, parsed_alert.gitlab_fingerprint)
set_status(parsed_alert, event)
end
def create_self_managed_prometheus_alert_event(parsed_alert)
- payload_key = SelfManagedPrometheusAlertEvent.payload_key_for(parsed_alert.starts_at_raw, parsed_alert.title, parsed_alert.full_query)
-
- event = SelfManagedPrometheusAlertEvent.find_or_initialize_by_payload_key(parsed_alert.project, payload_key) do |event|
+ event = SelfManagedPrometheusAlertEvent.find_or_initialize_by_payload_key(parsed_alert.project, parsed_alert.gitlab_fingerprint) do |event|
event.environment = parsed_alert.environment
event.title = parsed_alert.title
event.query_expression = parsed_alert.full_query
diff --git a/app/services/projects/prometheus/alerts/notify_service.rb b/app/services/projects/prometheus/alerts/notify_service.rb
index 2583a6cae9f..877a4f99a94 100644
--- a/app/services/projects/prometheus/alerts/notify_service.rb
+++ b/app/services/projects/prometheus/alerts/notify_service.rb
@@ -7,9 +7,19 @@ module Projects
include Gitlab::Utils::StrongMemoize
include IncidentManagement::Settings
+ # This set of keys identifies a payload as a valid Prometheus
+ # payload and thus processable by this service. See also
+ # https://prometheus.io/docs/alerting/configuration/#webhook_config
+ REQUIRED_PAYLOAD_KEYS = %w[
+ version groupKey status receiver groupLabels commonLabels
+ commonAnnotations externalURL alerts
+ ].to_set.freeze
+
+ SUPPORTED_VERSION = '4'
+
def execute(token)
return bad_request unless valid_payload_size?
- return unprocessable_entity unless valid_version?
+ return unprocessable_entity unless self.class.processable?(params)
return unauthorized unless valid_alert_manager_token?(token)
process_prometheus_alerts
@@ -20,6 +30,14 @@ module Projects
ServiceResponse.success
end
+ def self.processable?(params)
+ # Workaround for https://gitlab.com/gitlab-org/gitlab/-/issues/220496
+ return false unless params
+
+ REQUIRED_PAYLOAD_KEYS.subset?(params.keys.to_set) &&
+ params['version'] == SUPPORTED_VERSION
+ end
+
private
def valid_payload_size?
@@ -42,12 +60,10 @@ module Projects
params['alerts']
end
- def valid_version?
- params['version'] == '4'
- end
-
def valid_alert_manager_token?(token)
- valid_for_manual?(token) || valid_for_managed?(token)
+ valid_for_manual?(token) ||
+ valid_for_alerts_endpoint?(token) ||
+ valid_for_managed?(token)
end
def valid_for_manual?(token)
@@ -61,6 +77,13 @@ module Projects
end
end
+ def valid_for_alerts_endpoint?(token)
+ return false unless project.alerts_service_activated?
+
+ # Here we are enforcing the existence of the token
+ compare_token(token, project.alerts_service.token)
+ end
+
def valid_for_managed?(token)
prometheus_application = available_prometheus_application(project)
return false unless prometheus_application
diff --git a/app/services/projects/propagate_service_template.rb b/app/services/projects/propagate_service_template.rb
index 0483c951f1e..4adcda042d1 100644
--- a/app/services/projects/propagate_service_template.rb
+++ b/app/services/projects/propagate_service_template.rb
@@ -26,7 +26,7 @@ module Projects
def propagate_projects_with_template
loop do
- batch = Project.uncached { project_ids_batch }
+ batch = Project.uncached { project_ids_without_integration }
bulk_create_from_template(batch) unless batch.empty?
@@ -35,40 +35,36 @@ module Projects
end
def bulk_create_from_template(batch)
- service_list = batch.map do |project_id|
- service_hash.values << project_id
- end
+ service_list = ServiceList.new(batch, service_hash).to_array
Project.transaction do
- results = bulk_insert(Service, service_hash.keys << 'project_id', service_list)
+ results = bulk_insert(*service_list)
if data_fields_present?
- data_list = results.map { |row| data_hash.values << row['id'] }
+ data_list = DataList.new(results, data_fields_hash, template.data_fields.class).to_array
- bulk_insert(template.data_fields.class, data_hash.keys << 'service_id', data_list)
+ bulk_insert(*data_list)
end
run_callbacks(batch)
end
end
- def project_ids_batch
- Project.connection.select_values(
- <<-SQL
- SELECT id
- FROM projects
- WHERE NOT EXISTS (
- SELECT true
- FROM services
- WHERE services.project_id = projects.id
- AND services.type = #{ActiveRecord::Base.connection.quote(template.type)}
- )
- AND projects.pending_delete = false
- AND projects.archived = false
- LIMIT #{BATCH_SIZE}
- SQL
- )
+ # rubocop: disable CodeReuse/ActiveRecord
+ def project_ids_without_integration
+ services = Service
+ .select('1')
+ .where('services.project_id = projects.id')
+ .where(type: template.type)
+
+ Project
+ .where('NOT EXISTS (?)', services)
+ .where(pending_delete: false)
+ .where(archived: false)
+ .limit(BATCH_SIZE)
+ .pluck(:id)
end
+ # rubocop: enable CodeReuse/ActiveRecord
def bulk_insert(klass, columns, values_array)
items_to_insert = values_array.map { |array| Hash[columns.zip(array)] }
@@ -77,11 +73,11 @@ module Projects
end
def service_hash
- @service_hash ||= template.as_json(methods: :type, except: %w[id template project_id])
+ @service_hash ||= template.to_service_hash
end
- def data_hash
- @data_hash ||= template.data_fields.as_json(only: template.data_fields.class.column_names).except('id', 'service_id')
+ def data_fields_hash
+ @data_fields_hash ||= template.to_data_fields_hash
end
# rubocop: disable CodeReuse/ActiveRecord
diff --git a/app/services/projects/update_remote_mirror_service.rb b/app/services/projects/update_remote_mirror_service.rb
index e554bed6819..5f8ef75a8d7 100644
--- a/app/services/projects/update_remote_mirror_service.rb
+++ b/app/services/projects/update_remote_mirror_service.rb
@@ -27,7 +27,11 @@ module Projects
remote_mirror.update_start!
remote_mirror.ensure_remote!
- repository.fetch_remote(remote_mirror.remote_name, ssh_auth: remote_mirror, no_tags: true)
+
+ # https://gitlab.com/gitlab-org/gitaly/-/issues/2670
+ if Feature.disabled?(:gitaly_ruby_remote_branches_ls_remote)
+ repository.fetch_remote(remote_mirror.remote_name, ssh_auth: remote_mirror, no_tags: true)
+ end
response = remote_mirror.update_repository
diff --git a/app/services/projects/update_repository_storage_service.rb b/app/services/projects/update_repository_storage_service.rb
index 0632df6f6d7..fa8d4c5aa5f 100644
--- a/app/services/projects/update_repository_storage_service.rb
+++ b/app/services/projects/update_repository_storage_service.rb
@@ -24,7 +24,7 @@ module Projects
mark_old_paths_for_archive
repository_storage_move.finish!
- project.update!(repository_storage: destination_storage_name, repository_read_only: false)
+
project.leave_pool_repository
project.track_project_repository
end
@@ -34,10 +34,7 @@ module Projects
ServiceResponse.success
rescue StandardError => e
- project.transaction do
- repository_storage_move.do_fail!
- project.update!(repository_read_only: false)
- end
+ repository_storage_move.do_fail!
Gitlab::ErrorTracking.track_exception(e, project_path: project.full_path)
diff --git a/app/services/projects/update_service.rb b/app/services/projects/update_service.rb
index e10dede632a..58c9bce963b 100644
--- a/app/services/projects/update_service.rb
+++ b/app/services/projects/update_service.rb
@@ -13,8 +13,12 @@ module Projects
ensure_wiki_exists if enabling_wiki?
- if changing_storage_size?
- project.change_repository_storage(params.delete(:repository_storage))
+ if changing_repository_storage?
+ storage_move = project.repository_storage_moves.build(
+ source_storage_name: project.repository_storage,
+ destination_storage_name: params.delete(:repository_storage)
+ )
+ storage_move.schedule
end
yield if block_given?
@@ -132,7 +136,7 @@ module Projects
def ensure_wiki_exists
ProjectWiki.new(project, project.owner).wiki
- rescue ProjectWiki::CouldNotCreateWikiError
+ rescue Wiki::CouldNotCreateWikiError
log_error("Could not create wiki for #{project.full_name}")
Gitlab::Metrics.counter(:wiki_can_not_be_created_total, 'Counts the times we failed to create a wiki').increment
end
@@ -145,10 +149,11 @@ module Projects
project.previous_changes.include?(:pages_https_only)
end
- def changing_storage_size?
+ def changing_repository_storage?
new_repository_storage = params[:repository_storage]
new_repository_storage && project.repository.exists? &&
+ project.repository_storage != new_repository_storage &&
can?(current_user, :change_repository_storage, project)
end
end
diff --git a/app/services/projects/update_statistics_service.rb b/app/services/projects/update_statistics_service.rb
index cc6ffa9eafc..a0793cff2df 100644
--- a/app/services/projects/update_statistics_service.rb
+++ b/app/services/projects/update_statistics_service.rb
@@ -5,7 +5,7 @@ module Projects
def execute
return unless project
- Rails.logger.info("Updating statistics for project #{project.id}") # rubocop:disable Gitlab/RailsLogger
+ Gitlab::AppLogger.info("Updating statistics for project #{project.id}")
project.statistics.refresh!(only: statistics.map(&:to_sym))
end
diff --git a/app/services/prometheus/create_default_alerts_service.rb b/app/services/prometheus/create_default_alerts_service.rb
index c87cbbbe3cf..53baf6a650e 100644
--- a/app/services/prometheus/create_default_alerts_service.rb
+++ b/app/services/prometheus/create_default_alerts_service.rb
@@ -33,6 +33,7 @@ module Prometheus
return ServiceResponse.error(message: 'Invalid environment') unless environment
create_alerts
+ schedule_prometheus_update
ServiceResponse.success
end
@@ -51,6 +52,16 @@ module Prometheus
end
end
+ def schedule_prometheus_update
+ return unless prometheus_application
+
+ ::Clusters::Applications::ScheduleUpdateService.new(prometheus_application, project).execute
+ end
+
+ def prometheus_application
+ environment.cluster_prometheus_adapter
+ end
+
def metrics_by_identifier
strong_memoize(:metrics_by_identifier) do
metric_identifiers = DEFAULT_ALERTS.map { |alert| alert[:identifier] }
diff --git a/app/services/prometheus/proxy_service.rb b/app/services/prometheus/proxy_service.rb
index 085cfc76196..e0bc5518d30 100644
--- a/app/services/prometheus/proxy_service.rb
+++ b/app/services/prometheus/proxy_service.rb
@@ -30,6 +30,10 @@ module Prometheus
'query_range' => {
method: ['GET'],
params: %w(query start end step timeout)
+ },
+ 'series' => {
+ method: %w(GET),
+ params: %w(match start end)
}
}.freeze
diff --git a/app/services/prometheus/proxy_variable_substitution_service.rb b/app/services/prometheus/proxy_variable_substitution_service.rb
index 7b98cfc592a..10fb3a8c1b5 100644
--- a/app/services/prometheus/proxy_variable_substitution_service.rb
+++ b/app/services/prometheus/proxy_variable_substitution_service.rb
@@ -58,7 +58,7 @@ module Prometheus
def substitute_variables(result)
return success(result) unless query(result)
- result[:params][:query] = gsub(query(result), full_context)
+ result[:params][:query] = gsub(query(result), full_context(result))
success(result)
end
@@ -75,12 +75,16 @@ module Prometheus
end
end
- def predefined_context
- Gitlab::Prometheus::QueryVariables.call(@environment).stringify_keys
+ def predefined_context(result)
+ Gitlab::Prometheus::QueryVariables.call(
+ @environment,
+ start_time: start_timestamp(result),
+ end_time: end_timestamp(result)
+ ).stringify_keys
end
- def full_context
- @full_context ||= predefined_context.reverse_merge(variables_hash)
+ def full_context(result)
+ @full_context ||= predefined_context(result).reverse_merge(variables_hash)
end
def variables
@@ -91,6 +95,16 @@ module Prometheus
variables.to_h
end
+ def start_timestamp(result)
+ Time.rfc3339(result[:params][:start])
+ rescue ArgumentError
+ end
+
+ def end_timestamp(result)
+ Time.rfc3339(result[:params][:end])
+ rescue ArgumentError
+ end
+
def query(result)
result[:params][:query]
end
diff --git a/app/services/protected_branches/legacy_api_update_service.rb b/app/services/protected_branches/legacy_api_update_service.rb
index 65dc3297ae8..0cad23f20f7 100644
--- a/app/services/protected_branches/legacy_api_update_service.rb
+++ b/app/services/protected_branches/legacy_api_update_service.rb
@@ -39,11 +39,11 @@ module ProtectedBranches
def delete_redundant_access_levels
unless developers_can_merge.nil?
- protected_branch.merge_access_levels.destroy_all # rubocop: disable DestroyAll
+ protected_branch.merge_access_levels.destroy_all # rubocop: disable Cop/DestroyAll
end
unless developers_can_push.nil?
- protected_branch.push_access_levels.destroy_all # rubocop: disable DestroyAll
+ protected_branch.push_access_levels.destroy_all # rubocop: disable Cop/DestroyAll
end
end
end
diff --git a/app/services/releases/create_evidence_service.rb b/app/services/releases/create_evidence_service.rb
new file mode 100644
index 00000000000..ac13dce1729
--- /dev/null
+++ b/app/services/releases/create_evidence_service.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Releases
+ class CreateEvidenceService
+ def initialize(release, pipeline: nil)
+ @release = release
+ @pipeline = pipeline
+ end
+
+ def execute
+ evidence = release.evidences.build
+
+ summary = Evidences::EvidenceSerializer.new.represent(evidence) # rubocop: disable CodeReuse/Serializer
+ evidence.summary = summary
+ # TODO: fix the sha generating https://gitlab.com/gitlab-org/gitlab/-/issues/209000
+ evidence.summary_sha = Gitlab::CryptoHelper.sha256(summary)
+
+ evidence.save!
+ end
+
+ private
+
+ attr_reader :release
+ end
+end
diff --git a/app/services/releases/create_service.rb b/app/services/releases/create_service.rb
index 81ca9d6d123..92a0b875dd4 100644
--- a/app/services/releases/create_service.rb
+++ b/app/services/releases/create_service.rb
@@ -9,11 +9,16 @@ module Releases
return error('Release already exists', 409) if release
return error("Milestone(s) not found: #{inexistent_milestones.join(', ')}", 400) if inexistent_milestones.any?
+ # should be found before the creation of new tag
+ # because tag creation can spawn new pipeline
+ # which won't have any data for evidence yet
+ evidence_pipeline = find_evidence_pipeline
+
tag = ensure_tag
return tag unless tag.is_a?(Gitlab::Git::Tag)
- create_release(tag)
+ create_release(tag, evidence_pipeline)
end
def find_or_build_release
@@ -42,13 +47,15 @@ module Releases
Ability.allowed?(current_user, :create_release, project)
end
- def create_release(tag)
+ def create_release(tag, evidence_pipeline)
release = build_release(tag)
release.save!
notify_create_release(release)
+ create_evidence!(release, evidence_pipeline)
+
success(tag: tag, release: release)
rescue => e
error(e.message, 400)
@@ -70,5 +77,27 @@ module Releases
milestones: milestones
)
end
+
+ def find_evidence_pipeline
+ # TODO: remove this with the release creation moved to it's own form https://gitlab.com/gitlab-org/gitlab/-/issues/214245
+ return params[:evidence_pipeline] if params[:evidence_pipeline]
+
+ sha = existing_tag&.dereferenced_target&.sha
+ sha ||= repository.commit(ref)&.sha
+
+ return unless sha
+
+ project.ci_pipelines.for_sha(sha).last
+ end
+
+ def create_evidence!(release, pipeline)
+ return if release.historical_release?
+
+ if release.upcoming_release?
+ CreateEvidenceWorker.perform_at(release.released_at, release.id, pipeline&.id)
+ else
+ CreateEvidenceWorker.perform_async(release.id, pipeline&.id)
+ end
+ end
end
end
diff --git a/app/services/resource_events/change_labels_service.rb b/app/services/resource_events/change_labels_service.rb
index e0d019f54be..dc23f727079 100644
--- a/app/services/resource_events/change_labels_service.rb
+++ b/app/services/resource_events/change_labels_service.rb
@@ -22,7 +22,7 @@ module ResourceEvents
label_hash.merge(label_id: label.id, action: ResourceLabelEvent.actions['remove'])
end
- Gitlab::Database.bulk_insert(ResourceLabelEvent.table_name, labels)
+ Gitlab::Database.bulk_insert(ResourceLabelEvent.table_name, labels) # rubocop:disable Gitlab/BulkInsert
resource.expire_note_etag_cache
end
diff --git a/app/services/resource_events/change_state_service.rb b/app/services/resource_events/change_state_service.rb
new file mode 100644
index 00000000000..8beb76d8aee
--- /dev/null
+++ b/app/services/resource_events/change_state_service.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module ResourceEvents
+ class ChangeStateService
+ attr_reader :resource, :user
+
+ def initialize(user:, resource:)
+ @user, @resource = user, resource
+ end
+
+ def execute(state)
+ ResourceStateEvent.create(
+ user: user,
+ issue: issue,
+ merge_request: merge_request,
+ state: ResourceStateEvent.states[state],
+ created_at: Time.zone.now)
+
+ resource.expire_note_etag_cache
+ end
+
+ private
+
+ def issue
+ return unless resource.is_a?(Issue)
+
+ resource
+ end
+
+ def merge_request
+ return unless resource.is_a?(MergeRequest)
+
+ resource
+ end
+ end
+end
diff --git a/app/services/resource_events/merge_into_notes_service.rb b/app/services/resource_events/merge_into_notes_service.rb
index 4aa9bb80229..122bcb8550f 100644
--- a/app/services/resource_events/merge_into_notes_service.rb
+++ b/app/services/resource_events/merge_into_notes_service.rb
@@ -11,7 +11,8 @@ module ResourceEvents
SYNTHETIC_NOTE_BUILDER_SERVICES = [
SyntheticLabelNotesBuilderService,
- SyntheticMilestoneNotesBuilderService
+ SyntheticMilestoneNotesBuilderService,
+ SyntheticStateNotesBuilderService
].freeze
attr_reader :resource, :current_user, :params
@@ -23,7 +24,7 @@ module ResourceEvents
end
def execute(notes = [])
- (notes + synthetic_notes).sort_by { |n| n.created_at }
+ (notes + synthetic_notes).sort_by(&:created_at)
end
private
diff --git a/app/services/resource_events/synthetic_state_notes_builder_service.rb b/app/services/resource_events/synthetic_state_notes_builder_service.rb
new file mode 100644
index 00000000000..763134d98d8
--- /dev/null
+++ b/app/services/resource_events/synthetic_state_notes_builder_service.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module ResourceEvents
+ class SyntheticStateNotesBuilderService < BaseSyntheticNotesBuilderService
+ private
+
+ def synthetic_notes
+ state_change_events.map do |event|
+ StateNote.from_event(event, resource: resource, resource_parent: resource_parent)
+ end
+ end
+
+ def state_change_events
+ return [] unless resource.respond_to?(:resource_state_events)
+
+ events = resource.resource_state_events.includes(user: :status) # rubocop: disable CodeReuse/ActiveRecord
+ since_fetch_at(events)
+ end
+ end
+end
diff --git a/app/services/search_service.rb b/app/services/search_service.rb
index bf21eba28f7..650dc197f8c 100644
--- a/app/services/search_service.rb
+++ b/app/services/search_service.rb
@@ -5,7 +5,6 @@ class SearchService
SEARCH_TERM_LIMIT = 64
SEARCH_CHAR_LIMIT = 4096
-
DEFAULT_PER_PAGE = Gitlab::SearchResults::DEFAULT_PER_PAGE
MAX_PER_PAGE = 200
@@ -62,8 +61,8 @@ class SearchService
@search_results ||= search_service.execute
end
- def search_objects
- @search_objects ||= redact_unauthorized_results(search_results.objects(scope, page: params[:page], per_page: per_page))
+ def search_objects(preload_method = nil)
+ @search_objects ||= redact_unauthorized_results(search_results.objects(scope, page: params[:page], per_page: per_page, preload_method: preload_method))
end
private
@@ -83,16 +82,21 @@ class SearchService
end
def redact_unauthorized_results(results_collection)
- results = results_collection.to_a
- permitted_results = results.select { |object| visible_result?(object) }
+ redacted_results = results_collection.reject { |object| visible_result?(object) }
+
+ if redacted_results.any?
+ redacted_log = redacted_results.each_with_object({}) do |object, memo|
+ memo[object.id] = { ability: :"read_#{object.to_ability_name}", id: object.id, class_name: object.class.name }
+ end
+
+ log_redacted_search_results(redacted_log.values)
- redacted_results = (results - permitted_results).each_with_object({}) do |object, memo|
- memo[object.id] = { ability: :"read_#{object.to_ability_name}", id: object.id, class_name: object.class.name }
+ return results_collection.id_not_in(redacted_log.keys) if results_collection.is_a?(ActiveRecord::Relation)
end
- log_redacted_search_results(redacted_results.values) if redacted_results.any?
+ return results_collection if results_collection.is_a?(ActiveRecord::Relation)
- return results_collection.id_not_in(redacted_results.keys) if results_collection.is_a?(ActiveRecord::Relation)
+ permitted_results = results_collection - redacted_results
Kaminari.paginate_array(
permitted_results,
diff --git a/app/services/service_response.rb b/app/services/service_response.rb
index 08b7e9d0831..74c0be22d46 100644
--- a/app/services/service_response.rb
+++ b/app/services/service_response.rb
@@ -26,6 +26,12 @@ class ServiceResponse
status == :error
end
+ def errors
+ return [] unless error?
+
+ Array.wrap(message)
+ end
+
private
attr_writer :status, :message, :http_status, :payload
diff --git a/app/services/snippets/base_service.rb b/app/services/snippets/base_service.rb
index 81d12997335..5d1fe815d83 100644
--- a/app/services/snippets/base_service.rb
+++ b/app/services/snippets/base_service.rb
@@ -6,12 +6,13 @@ module Snippets
CreateRepositoryError = Class.new(StandardError)
- attr_reader :uploaded_files
+ attr_reader :uploaded_assets, :snippet_files
def initialize(project, user = nil, params = {})
super
- @uploaded_files = Array(@params.delete(:files).presence)
+ @uploaded_assets = Array(@params.delete(:files).presence)
+ @snippet_files = SnippetInputActionCollection.new(Array(@params.delete(:snippet_files).presence))
filter_spam_check_params
end
@@ -22,12 +23,30 @@ module Snippets
Gitlab::VisibilityLevel.allowed_for?(current_user, visibility_level)
end
- def error_forbidden_visibility(snippet)
+ def forbidden_visibility_error(snippet)
deny_visibility_level(snippet)
snippet_error_response(snippet, 403)
end
+ def valid_params?
+ return true if snippet_files.empty?
+
+ (params.keys & [:content, :file_name]).none? && snippet_files.valid?
+ end
+
+ def invalid_params_error(snippet)
+ if snippet_files.valid?
+ [:content, :file_name].each do |key|
+ snippet.errors.add(key, 'and snippet files cannot be used together') if params.key?(key)
+ end
+ else
+ snippet.errors.add(:snippet_files, 'have invalid data')
+ end
+
+ snippet_error_response(snippet, 403)
+ end
+
def snippet_error_response(snippet, http_status)
ServiceResponse.error(
message: snippet.errors.full_messages.to_sentence,
@@ -52,5 +71,13 @@ module Snippets
message
end
+
+ def files_to_commit(snippet)
+ snippet_files.to_commit_actions.presence || build_actions_from_params(snippet)
+ end
+
+ def build_actions_from_params(snippet)
+ raise NotImplementedError
+ end
end
end
diff --git a/app/services/snippets/bulk_destroy_service.rb b/app/services/snippets/bulk_destroy_service.rb
index d9cc383a5a6..a612d8f8dfc 100644
--- a/app/services/snippets/bulk_destroy_service.rb
+++ b/app/services/snippets/bulk_destroy_service.rb
@@ -14,12 +14,12 @@ module Snippets
@snippets = snippets
end
- def execute
+ def execute(options = {})
return ServiceResponse.success(message: 'No snippets found.') if snippets.empty?
- user_can_delete_snippets!
+ user_can_delete_snippets! unless options[:hard_delete]
attempt_delete_repositories!
- snippets.destroy_all # rubocop: disable DestroyAll
+ snippets.destroy_all # rubocop: disable Cop/DestroyAll
ServiceResponse.success(message: 'Snippets were deleted.')
rescue SnippetAccessError
diff --git a/app/services/snippets/create_service.rb b/app/services/snippets/create_service.rb
index ed6da3a0ad0..7b477621da3 100644
--- a/app/services/snippets/create_service.rb
+++ b/app/services/snippets/create_service.rb
@@ -5,13 +5,15 @@ module Snippets
def execute
@snippet = build_from_params
+ return invalid_params_error(@snippet) unless valid_params?
+
unless visibility_allowed?(@snippet, @snippet.visibility_level)
- return error_forbidden_visibility(@snippet)
+ return forbidden_visibility_error(@snippet)
end
@snippet.author = current_user
- spam_check(@snippet, current_user)
+ spam_check(@snippet, current_user, action: :create)
if save_and_commit
UserAgentDetailService.new(@snippet, @request).create
@@ -29,12 +31,21 @@ module Snippets
def build_from_params
if project
- project.snippets.build(params)
+ project.snippets.build(create_params)
else
- PersonalSnippet.new(params)
+ PersonalSnippet.new(create_params)
end
end
+ # If the snippet_files param is present
+ # we need to fill content and file_name from
+ # the model
+ def create_params
+ return params if snippet_files.empty?
+
+ params.merge(content: snippet_files[0].content, file_name: snippet_files[0].file_path)
+ end
+
def save_and_commit
snippet_saved = @snippet.save
@@ -75,19 +86,19 @@ module Snippets
message: 'Initial commit'
}
- @snippet.snippet_repository.multi_files_action(current_user, snippet_files, commit_attrs)
- end
-
- def snippet_files
- [{ file_path: params[:file_name], content: params[:content] }]
+ @snippet.snippet_repository.multi_files_action(current_user, files_to_commit(@snippet), commit_attrs)
end
def move_temporary_files
return unless @snippet.is_a?(PersonalSnippet)
- uploaded_files.each do |file|
+ uploaded_assets.each do |file|
FileMover.new(file, from_model: current_user, to_model: @snippet).execute
end
end
+
+ def build_actions_from_params(_snippet)
+ [{ file_path: params[:file_name], content: params[:content] }]
+ end
end
end
diff --git a/app/services/snippets/update_service.rb b/app/services/snippets/update_service.rb
index 250120c1c19..6cdc2c374da 100644
--- a/app/services/snippets/update_service.rb
+++ b/app/services/snippets/update_service.rb
@@ -7,12 +7,14 @@ module Snippets
UpdateError = Class.new(StandardError)
def execute(snippet)
+ return invalid_params_error(snippet) unless valid_params?
+
if visibility_changed?(snippet) && !visibility_allowed?(snippet, visibility_level)
- return error_forbidden_visibility(snippet)
+ return forbidden_visibility_error(snippet)
end
- snippet.assign_attributes(params)
- spam_check(snippet, current_user)
+ update_snippet_attributes(snippet)
+ spam_check(snippet, current_user, action: :update)
if save_and_commit(snippet)
Gitlab::UsageDataCounters::SnippetCounter.count(:update)
@@ -29,6 +31,19 @@ module Snippets
visibility_level && visibility_level.to_i != snippet.visibility_level
end
+ def update_snippet_attributes(snippet)
+ # We can remove the following condition once
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/217801
+ # is implemented.
+ # Once we can perform different operations through this service
+ # we won't need to keep track of the `content` and `file_name` fields
+ if snippet_files.any?
+ params.merge!(content: snippet_files[0].content, file_name: snippet_files[0].file_path)
+ end
+
+ snippet.assign_attributes(params)
+ end
+
def save_and_commit(snippet)
return false unless snippet.save
@@ -81,15 +96,7 @@ module Snippets
message: 'Update snippet'
}
- snippet.snippet_repository.multi_files_action(current_user, snippet_files(snippet), commit_attrs)
- end
-
- def snippet_files(snippet)
- file_name_on_repo = snippet.file_name_on_repo
-
- [{ previous_path: file_name_on_repo,
- file_path: params[:file_name] || file_name_on_repo,
- content: params[:content] }]
+ snippet.snippet_repository.multi_files_action(current_user, files_to_commit(snippet), commit_attrs)
end
# Because we are removing repositories we don't want to remove
@@ -101,7 +108,15 @@ module Snippets
end
def committable_attributes?
- (params.stringify_keys.keys & COMMITTABLE_ATTRIBUTES).present?
+ (params.stringify_keys.keys & COMMITTABLE_ATTRIBUTES).present? || snippet_files.any?
+ end
+
+ def build_actions_from_params(snippet)
+ file_name_on_repo = snippet.file_name_on_repo
+
+ [{ previous_path: file_name_on_repo,
+ file_path: params[:file_name] || file_name_on_repo,
+ content: params[:content] }]
end
end
end
diff --git a/app/services/spam/akismet_service.rb b/app/services/spam/akismet_service.rb
index ab35fb8700f..e11a1dbdd96 100644
--- a/app/services/spam/akismet_service.rb
+++ b/app/services/spam/akismet_service.rb
@@ -27,7 +27,7 @@ module Spam
is_spam, is_blatant = akismet_client.check(options[:ip_address], options[:user_agent], params)
is_spam || is_blatant
rescue => e
- Rails.logger.error("Unable to connect to Akismet: #{e}, skipping check") # rubocop:disable Gitlab/RailsLogger
+ Gitlab::AppLogger.error("Unable to connect to Akismet: #{e}, skipping check")
false
end
end
@@ -67,7 +67,7 @@ module Spam
akismet_client.public_send(type, options[:ip_address], options[:user_agent], params) # rubocop:disable GitlabSecurity/PublicSend
true
rescue => e
- Rails.logger.error("Unable to connect to Akismet: #{e}, skipping!") # rubocop:disable Gitlab/RailsLogger
+ Gitlab::AppLogger.error("Unable to connect to Akismet: #{e}, skipping!")
false
end
end
diff --git a/app/services/spam/spam_action_service.rb b/app/services/spam/spam_action_service.rb
index f0a4aff4443..b745b67f566 100644
--- a/app/services/spam/spam_action_service.rb
+++ b/app/services/spam/spam_action_service.rb
@@ -7,9 +7,11 @@ module Spam
attr_accessor :target, :request, :options
attr_reader :spam_log
- def initialize(spammable:, request:)
+ def initialize(spammable:, request:, user:, context: {})
@target = spammable
@request = request
+ @user = user
+ @context = context
@options = {}
if @request
@@ -22,7 +24,7 @@ module Spam
end
end
- def execute(api: false, recaptcha_verified:, spam_log_id:, user:)
+ def execute(api: false, recaptcha_verified:, spam_log_id:)
if recaptcha_verified
# If it's a request which is already verified through reCAPTCHA,
# update the spam log accordingly.
@@ -40,6 +42,8 @@ module Spam
private
+ attr_reader :user, :context
+
def allowlisted?(user)
user.respond_to?(:gitlab_employee) && user.gitlab_employee?
end
@@ -49,7 +53,8 @@ module Spam
# ask the SpamVerdictService what to do with the target.
spam_verdict_service.execute.tap do |result|
case result
- when REQUIRE_RECAPTCHA
+ when CONDITIONAL_ALLOW
+ # at the moment, this means "ask for reCAPTCHA"
create_spam_log(api)
break if target.allow_possible_spam?
@@ -74,7 +79,7 @@ module Spam
description: target.spam_description,
source_ip: options[:ip_address],
user_agent: options[:user_agent],
- noteable_type: target.class.to_s,
+ noteable_type: notable_type,
via_api: api
}
)
@@ -84,8 +89,14 @@ module Spam
def spam_verdict_service
SpamVerdictService.new(target: target,
+ user: user,
request: @request,
- options: options)
+ options: options,
+ context: context.merge(target_type: notable_type))
+ end
+
+ def notable_type
+ @notable_type ||= target.class.to_s
end
end
end
diff --git a/app/services/spam/spam_constants.rb b/app/services/spam/spam_constants.rb
index 085bac684c4..2a16cfae78b 100644
--- a/app/services/spam/spam_constants.rb
+++ b/app/services/spam/spam_constants.rb
@@ -2,8 +2,24 @@
module Spam
module SpamConstants
- REQUIRE_RECAPTCHA = :recaptcha
- DISALLOW = :disallow
- ALLOW = :allow
+ CONDITIONAL_ALLOW = "conditional_allow"
+ DISALLOW = "disallow"
+ ALLOW = "allow"
+ BLOCK_USER = "block"
+
+ SUPPORTED_VERDICTS = {
+ BLOCK_USER => {
+ priority: 1
+ },
+ DISALLOW => {
+ priority: 2
+ },
+ CONDITIONAL_ALLOW => {
+ priority: 3
+ },
+ ALLOW => {
+ priority: 4
+ }
+ }.freeze
end
end
diff --git a/app/services/spam/spam_verdict_service.rb b/app/services/spam/spam_verdict_service.rb
index 2b4d5f4a984..68f1135ae28 100644
--- a/app/services/spam/spam_verdict_service.rb
+++ b/app/services/spam/spam_verdict_service.rb
@@ -5,22 +5,90 @@ module Spam
include AkismetMethods
include SpamConstants
- def initialize(target:, request:, options:)
+ def initialize(user:, target:, request:, options:, context: {})
@target = target
@request = request
+ @user = user
@options = options
+ @verdict_params = assemble_verdict_params(context)
end
def execute
+ external_spam_check_result = spam_verdict
+ akismet_result = akismet_verdict
+
+ # filter out anything we don't recognise, including nils.
+ valid_results = [external_spam_check_result, akismet_result].compact.select { |r| SUPPORTED_VERDICTS.key?(r) }
+ # Treat nils - such as service unavailable - as ALLOW
+ return ALLOW unless valid_results.any?
+
+ # Favour the most restrictive result.
+ valid_results.min_by { |v| SUPPORTED_VERDICTS[v][:priority] }
+ end
+
+ private
+
+ attr_reader :user, :target, :request, :options, :verdict_params
+
+ def akismet_verdict
if akismet.spam?
- Gitlab::Recaptcha.enabled? ? REQUIRE_RECAPTCHA : DISALLOW
+ Gitlab::Recaptcha.enabled? ? CONDITIONAL_ALLOW : DISALLOW
else
ALLOW
end
end
- private
+ def spam_verdict
+ return unless Gitlab::CurrentSettings.spam_check_endpoint_enabled
+ return if endpoint_url.blank?
+
+ begin
+ result = Gitlab::HTTP.post(endpoint_url, body: verdict_params.to_json, headers: { 'Content-Type' => 'application/json' })
+ return unless result
+
+ json_result = Gitlab::Json.parse(result).with_indifferent_access
+ # @TODO metrics/logging
+ # Expecting:
+ # error: (string or nil)
+ # result: (string or nil)
+ verdict = json_result[:verdict]
+ return unless SUPPORTED_VERDICTS.include?(verdict)
- attr_reader :target, :request, :options
+ # @TODO log if json_result[:error]
+
+ json_result[:verdict]
+ rescue *Gitlab::HTTP::HTTP_ERRORS => e
+ # @TODO: log error via try_post https://gitlab.com/gitlab-org/gitlab/-/issues/219223
+ Gitlab::ErrorTracking.log_exception(e)
+ return
+ rescue
+ # @TODO log
+ ALLOW
+ end
+ end
+
+ def assemble_verdict_params(context)
+ return {} unless endpoint_url.present?
+
+ project = target.try(:project)
+
+ context.merge({
+ target: {
+ title: target.spam_title,
+ description: target.spam_description,
+ type: target.class.to_s
+ },
+ user: {
+ created_at: user.created_at,
+ email: user.email,
+ username: user.username
+ },
+ user_in_project: user.authorized_project?(project)
+ })
+ end
+
+ def endpoint_url
+ @endpoint_url ||= Gitlab::CurrentSettings.current_application_settings.spam_check_endpoint_url
+ end
end
end
diff --git a/app/services/submit_usage_ping_service.rb b/app/services/submit_usage_ping_service.rb
index 3265eb106eb..4bbde3a9648 100644
--- a/app/services/submit_usage_ping_service.rb
+++ b/app/services/submit_usage_ping_service.rb
@@ -28,7 +28,7 @@ class SubmitUsagePingService
true
rescue Gitlab::HTTP::Error => e
- Rails.logger.info "Unable to contact GitLab, Inc.: #{e}" # rubocop:disable Gitlab/RailsLogger
+ Gitlab::AppLogger.info("Unable to contact GitLab, Inc.: #{e}")
false
end
diff --git a/app/services/suggestions/apply_service.rb b/app/services/suggestions/apply_service.rb
index 479eed3ce57..ab80b23a37b 100644
--- a/app/services/suggestions/apply_service.rb
+++ b/app/services/suggestions/apply_service.rb
@@ -2,109 +2,49 @@
module Suggestions
class ApplyService < ::BaseService
- DEFAULT_SUGGESTION_COMMIT_MESSAGE = 'Apply suggestion to %{file_path}'
-
- PLACEHOLDERS = {
- 'project_path' => ->(suggestion, user) { suggestion.project.path },
- 'project_name' => ->(suggestion, user) { suggestion.project.name },
- 'file_path' => ->(suggestion, user) { suggestion.file_path },
- 'branch_name' => ->(suggestion, user) { suggestion.branch },
- 'username' => ->(suggestion, user) { user.username },
- 'user_full_name' => ->(suggestion, user) { user.name }
- }.freeze
-
- # This regex is built dynamically using the keys from the PLACEHOLDER struct.
- # So, we can easily add new placeholder just by modifying the PLACEHOLDER hash.
- # This regex will build the new PLACEHOLDER_REGEX with the new information
- PLACEHOLDERS_REGEX = Regexp.union(PLACEHOLDERS.keys.map { |key| Regexp.new(Regexp.escape(key)) }).freeze
-
- attr_reader :current_user
-
- def initialize(current_user)
+ def initialize(current_user, *suggestions)
@current_user = current_user
+ @suggestion_set = Gitlab::Suggestions::SuggestionSet.new(suggestions)
end
- def execute(suggestion)
- unless suggestion.appliable?(cached: false)
- return error('Suggestion is not appliable')
- end
-
- unless latest_source_head?(suggestion)
- return error('The file has been changed')
+ def execute
+ if suggestion_set.valid?
+ result
+ else
+ error(suggestion_set.error_message)
end
+ end
- diff_file = suggestion.diff_file
-
- unless diff_file
- return error('The file was not found')
- end
+ private
- params = file_update_params(suggestion, diff_file)
- result = ::Files::UpdateService.new(suggestion.project, current_user, params).execute
+ attr_reader :current_user, :suggestion_set
- if result[:status] == :success
- suggestion.update(commit_id: result[:result], applied: true)
+ def result
+ multi_service.execute.tap do |result|
+ update_suggestions(result)
end
-
- result
- rescue Files::UpdateService::FileChangedError
- error('The file has been changed')
end
- private
+ def update_suggestions(result)
+ return unless result[:status] == :success
- # Checks whether the latest source branch HEAD matches with
- # the position HEAD we're using to update the file content. Since
- # the persisted HEAD is updated async (for MergeRequest),
- # it's more consistent to fetch this data directly from the
- # repository.
- def latest_source_head?(suggestion)
- suggestion.position.head_sha == suggestion.noteable.source_branch_sha
+ Suggestion.id_in(suggestion_set.suggestions)
+ .update_all(commit_id: result[:result], applied: true)
end
- def file_update_params(suggestion, diff_file)
- blob = diff_file.new_blob
- project = suggestion.project
- file_path = suggestion.file_path
- branch_name = suggestion.branch
- file_content = new_file_content(suggestion, blob)
- commit_message = processed_suggestion_commit_message(suggestion)
-
- file_last_commit =
- Gitlab::Git::Commit.last_for_path(project.repository,
- blob.commit_id,
- blob.path)
-
- {
- file_path: file_path,
- branch_name: branch_name,
- start_branch: branch_name,
+ def multi_service
+ params = {
commit_message: commit_message,
- file_content: file_content,
- last_commit_sha: file_last_commit&.id
+ branch_name: suggestion_set.branch,
+ start_branch: suggestion_set.branch,
+ actions: suggestion_set.actions
}
- end
-
- def new_file_content(suggestion, blob)
- range = suggestion.from_line_index..suggestion.to_line_index
- blob.load_all_data!
- content = blob.data.lines
- content[range] = suggestion.to_content
-
- content.join
- end
-
- def suggestion_commit_message(project)
- project.suggestion_commit_message.presence || DEFAULT_SUGGESTION_COMMIT_MESSAGE
+ ::Files::MultiService.new(suggestion_set.project, current_user, params)
end
- def processed_suggestion_commit_message(suggestion)
- message = suggestion_commit_message(suggestion.project)
-
- Gitlab::StringPlaceholderReplacer.replace_string_placeholders(message, PLACEHOLDERS_REGEX) do |key|
- PLACEHOLDERS[key].call(suggestion, current_user)
- end
+ def commit_message
+ Gitlab::Suggestions::CommitMessage.new(current_user, suggestion_set).message
end
end
end
diff --git a/app/services/suggestions/create_service.rb b/app/services/suggestions/create_service.rb
index 1d3338c1b45..93d2bd11426 100644
--- a/app/services/suggestions/create_service.rb
+++ b/app/services/suggestions/create_service.rb
@@ -25,7 +25,7 @@ module Suggestions
end
rows.in_groups_of(100, false) do |rows|
- Gitlab::Database.bulk_insert('suggestions', rows)
+ Gitlab::Database.bulk_insert('suggestions', rows) # rubocop:disable Gitlab/BulkInsert
end
end
end
diff --git a/app/services/system_notes/issuables_service.rb b/app/services/system_notes/issuables_service.rb
index 275c64bea89..7d7ee8d829e 100644
--- a/app/services/system_notes/issuables_service.rb
+++ b/app/services/system_notes/issuables_service.rb
@@ -128,7 +128,7 @@ module SystemNotes
body = cross_reference_note_content(gfm_reference)
if noteable.is_a?(ExternalIssue)
- noteable.project.issues_tracker.create_cross_reference_note(noteable, mentioner, author)
+ noteable.project.external_issue_tracker.create_cross_reference_note(noteable, mentioner, author)
else
create_note(NoteSummary.new(noteable, noteable.project, author, body, action: 'cross_reference'))
end
@@ -225,7 +225,12 @@ module SystemNotes
action = status == 'reopened' ? 'opened' : status
- create_note(NoteSummary.new(noteable, project, author, body, action: action))
+ # A state event which results in a synthetic note will be
+ # created by EventCreateService if change event tracking
+ # is enabled.
+ unless state_change_tracking_enabled?
+ create_note(NoteSummary.new(noteable, project, author, body, action: action))
+ end
end
# Check if a cross reference to a noteable from a mentioner already exists
@@ -318,6 +323,11 @@ module SystemNotes
def self.cross_reference?(note_text)
note_text =~ /\A#{cross_reference_note_prefix}/i
end
+
+ def state_change_tracking_enabled?
+ noteable.respond_to?(:resource_state_events) &&
+ ::Feature.enabled?(:track_resource_state_change_events, noteable.project)
+ end
end
end
diff --git a/app/services/test_hooks/base_service.rb b/app/services/test_hooks/base_service.rb
index ebebf29c28b..0fda6fb1ed0 100644
--- a/app/services/test_hooks/base_service.rb
+++ b/app/services/test_hooks/base_service.rb
@@ -2,6 +2,8 @@
module TestHooks
class BaseService
+ include BaseServiceUtility
+
attr_accessor :hook, :current_user, :trigger
def initialize(hook, current_user, trigger)
@@ -12,31 +14,11 @@ module TestHooks
def execute
trigger_key = hook.class.triggers.key(trigger.to_sym)
- trigger_data_method = "#{trigger}_data"
-
- if trigger_key.nil? || !self.respond_to?(trigger_data_method, true)
- return error('Testing not available for this hook')
- end
-
- error_message = catch(:validation_error) do # rubocop:disable Cop/BanCatchThrow
- sample_data = self.__send__(trigger_data_method) # rubocop:disable GitlabSecurity/PublicSend
-
- return hook.execute(sample_data, trigger_key) # rubocop:disable Cop/AvoidReturnFromBlocks
- end
-
- error(error_message)
- end
-
- private
- def error(message, http_status = nil)
- result = {
- message: message,
- status: :error
- }
+ return error('Testing not available for this hook') if trigger_key.nil? || data.blank?
+ return error(data[:error]) if data[:error].present?
- result[:http_status] = http_status if http_status
- result
+ hook.execute(data, trigger_key)
end
end
end
diff --git a/app/services/test_hooks/project_service.rb b/app/services/test_hooks/project_service.rb
index aa80cc928b9..4e554dce357 100644
--- a/app/services/test_hooks/project_service.rb
+++ b/app/services/test_hooks/project_service.rb
@@ -2,6 +2,9 @@
module TestHooks
class ProjectService < TestHooks::BaseService
+ include Integrations::ProjectTestData
+ include Gitlab::Utils::StrongMemoize
+
attr_writer :project
def project
@@ -10,58 +13,25 @@ module TestHooks
private
- def push_events_data
- throw(:validation_error, s_('TestHooks|Ensure the project has at least one commit.')) if project.empty_repo? # rubocop:disable Cop/BanCatchThrow
-
- Gitlab::DataBuilder::Push.build_sample(project, current_user)
- end
-
- alias_method :tag_push_events_data, :push_events_data
-
- def note_events_data
- note = project.notes.first
- throw(:validation_error, s_('TestHooks|Ensure the project has notes.')) unless note.present? # rubocop:disable Cop/BanCatchThrow
-
- Gitlab::DataBuilder::Note.build(note, current_user)
- end
-
- def issues_events_data
- issue = project.issues.first
- throw(:validation_error, s_('TestHooks|Ensure the project has issues.')) unless issue.present? # rubocop:disable Cop/BanCatchThrow
-
- issue.to_hook_data(current_user)
- end
-
- alias_method :confidential_issues_events_data, :issues_events_data
-
- def merge_requests_events_data
- merge_request = project.merge_requests.first
- throw(:validation_error, s_('TestHooks|Ensure the project has merge requests.')) unless merge_request.present? # rubocop:disable Cop/BanCatchThrow
-
- merge_request.to_hook_data(current_user)
- end
-
- def job_events_data
- build = project.builds.first
- throw(:validation_error, s_('TestHooks|Ensure the project has CI jobs.')) unless build.present? # rubocop:disable Cop/BanCatchThrow
-
- Gitlab::DataBuilder::Build.build(build)
- end
-
- def pipeline_events_data
- pipeline = project.ci_pipelines.first
- throw(:validation_error, s_('TestHooks|Ensure the project has CI pipelines.')) unless pipeline.present? # rubocop:disable Cop/BanCatchThrow
-
- Gitlab::DataBuilder::Pipeline.build(pipeline)
- end
-
- def wiki_page_events_data
- page = project.wiki.list_pages(limit: 1).first
- if !project.wiki_enabled? || page.blank?
- throw(:validation_error, s_('TestHooks|Ensure the wiki is enabled and has pages.')) # rubocop:disable Cop/BanCatchThrow
+ def data
+ strong_memoize(:data) do
+ case trigger
+ when 'push_events', 'tag_push_events'
+ push_events_data
+ when 'note_events'
+ note_events_data
+ when 'issues_events', 'confidential_issues_events'
+ issues_events_data
+ when 'merge_requests_events'
+ merge_requests_events_data
+ when 'job_events'
+ job_events_data
+ when 'pipeline_events'
+ pipeline_events_data
+ when 'wiki_page_events'
+ wiki_page_events_data
+ end
end
-
- Gitlab::DataBuilder::WikiPage.build(page, current_user, 'create')
end
end
end
diff --git a/app/services/test_hooks/system_service.rb b/app/services/test_hooks/system_service.rb
index 5c7961f417d..66d78bfc578 100644
--- a/app/services/test_hooks/system_service.rb
+++ b/app/services/test_hooks/system_service.rb
@@ -2,23 +2,26 @@
module TestHooks
class SystemService < TestHooks::BaseService
- private
-
- def push_events_data
- Gitlab::DataBuilder::Push.sample_data
- end
+ include Gitlab::Utils::StrongMemoize
- def tag_push_events_data
- Gitlab::DataBuilder::Push.sample_data
- end
+ private
- def repository_update_events_data
- Gitlab::DataBuilder::Repository.sample_data
+ def data
+ strong_memoize(:data) do
+ case trigger
+ when 'push_events', 'tag_push_events'
+ Gitlab::DataBuilder::Push.sample_data
+ when 'repository_update_events'
+ Gitlab::DataBuilder::Repository.sample_data
+ when 'merge_requests_events'
+ merge_requests_events_data
+ end
+ end
end
def merge_requests_events_data
merge_request = MergeRequest.of_projects(current_user.projects.select(:id)).first
- throw(:validation_error, s_('TestHooks|Ensure one of your projects has merge requests.')) unless merge_request.present? # rubocop:disable Cop/BanCatchThrow
+ return { error: s_('TestHooks|Ensure one of your projects has merge requests.') } unless merge_request.present?
merge_request.to_hook_data(current_user)
end
diff --git a/app/services/todo_service.rb b/app/services/todo_service.rb
index 55f888d5664..e6fb0d3c72e 100644
--- a/app/services/todo_service.rb
+++ b/app/services/todo_service.rb
@@ -30,7 +30,7 @@ class TodoService
# * mark all pending todos related to the target for the current user as done
#
def close_issue(issue, current_user)
- mark_pending_todos_as_done(issue, current_user)
+ resolve_todos_for_target(issue, current_user)
end
# When we destroy a todo target we should:
@@ -79,7 +79,7 @@ class TodoService
# * mark all pending todos related to the target for the current user as done
#
def close_merge_request(merge_request, current_user)
- mark_pending_todos_as_done(merge_request, current_user)
+ resolve_todos_for_target(merge_request, current_user)
end
# When merge a merge request we should:
@@ -87,7 +87,7 @@ class TodoService
# * mark all pending todos related to the target for the current user as done
#
def merge_merge_request(merge_request, current_user)
- mark_pending_todos_as_done(merge_request, current_user)
+ resolve_todos_for_target(merge_request, current_user)
end
# When a build fails on the HEAD of a merge request we should:
@@ -105,7 +105,7 @@ class TodoService
# * mark all pending todos related to the merge request for that user as done
#
def merge_request_push(merge_request, current_user)
- mark_pending_todos_as_done(merge_request, current_user)
+ resolve_todos_for_target(merge_request, current_user)
end
# When a build is retried to a merge request we should:
@@ -114,7 +114,7 @@ class TodoService
#
def merge_request_build_retried(merge_request)
merge_request.merge_participants.each do |user|
- mark_pending_todos_as_done(merge_request, user)
+ resolve_todos_for_target(merge_request, user)
end
end
@@ -151,76 +151,68 @@ class TodoService
# * mark all pending todos related to the awardable for the current user as done
#
def new_award_emoji(awardable, current_user)
- mark_pending_todos_as_done(awardable, current_user)
+ resolve_todos_for_target(awardable, current_user)
end
- # When marking pending todos as done we should:
+ # When assigning an alert we should:
#
- # * mark all pending todos related to the target for the current user as done
+ # * create a pending todo for new assignee if alert is assigned
#
- def mark_pending_todos_as_done(target, user)
- attributes = attributes_for_target(target)
- pending_todos(user, attributes).update_all(state: :done)
- user.update_todos_count_cache
+ def assign_alert(alert, current_user)
+ create_assignment_todo(alert, current_user, [])
end
- # When user marks some todos as done
- def mark_todos_as_done(todos, current_user)
- update_todos_state(todos, current_user, :done)
+ # When user marks an issue as todo
+ def mark_todo(issuable, current_user)
+ attributes = attributes_for_todo(issuable.project, issuable, current_user, Todo::MARKED)
+ create_todos(current_user, attributes)
end
- def mark_todos_as_done_by_ids(ids, current_user)
- todos = todos_by_ids(ids, current_user)
- mark_todos_as_done(todos, current_user)
+ def todo_exist?(issuable, current_user)
+ TodosFinder.new(current_user).any_for_target?(issuable, :pending)
end
- def mark_all_todos_as_done_by_user(current_user)
- todos = TodosFinder.new(current_user).execute
- mark_todos_as_done(todos, current_user)
- end
+ # Resolves all todos related to target
+ def resolve_todos_for_target(target, current_user)
+ attributes = attributes_for_target(target)
- def mark_todo_as_done(todo, current_user)
- return if todo.done?
+ resolve_todos(pending_todos(current_user, attributes), current_user)
+ end
- todo.update(state: :done)
+ def resolve_todos(todos, current_user, resolution: :done, resolved_by_action: :system_done)
+ todos_ids = todos.batch_update(state: resolution, resolved_by_action: resolved_by_action)
current_user.update_todos_count_cache
- end
- # When user marks some todos as pending
- def mark_todos_as_pending(todos, current_user)
- update_todos_state(todos, current_user, :pending)
+ todos_ids
end
- def mark_todos_as_pending_by_ids(ids, current_user)
- todos = todos_by_ids(ids, current_user)
- mark_todos_as_pending(todos, current_user)
- end
+ def resolve_todo(todo, current_user, resolution: :done, resolved_by_action: :system_done)
+ return if todo.done?
- # When user marks an issue as todo
- def mark_todo(issuable, current_user)
- attributes = attributes_for_todo(issuable.project, issuable, current_user, Todo::MARKED)
- create_todos(current_user, attributes)
- end
+ todo.update(state: resolution, resolved_by_action: resolved_by_action)
- def todo_exist?(issuable, current_user)
- TodosFinder.new(current_user).any_for_target?(issuable, :pending)
+ current_user.update_todos_count_cache
end
- private
+ def restore_todos(todos, current_user)
+ todos_ids = todos.batch_update(state: :pending)
- def todos_by_ids(ids, current_user)
- current_user.todos_limited_to(Array(ids))
+ current_user.update_todos_count_cache
+
+ todos_ids
end
- def update_todos_state(todos, current_user, state)
- todos_ids = todos.update_state(state)
+ def restore_todo(todo, current_user)
+ return if todo.pending?
- current_user.update_todos_count_cache
+ todo.update(state: :pending)
- todos_ids
+ current_user.update_todos_count_cache
end
+ private
+
def create_todos(users, attributes)
Array(users).map do |user|
next if pending_todos(user, attributes).exists?
@@ -252,16 +244,16 @@ class TodoService
return unless note.can_create_todo?
project = note.project
- target = note.noteable
+ target = note.noteable
- mark_pending_todos_as_done(target, author)
+ resolve_todos_for_target(target, author)
create_mention_todos(project, target, author, note, skip_users)
end
- def create_assignment_todo(issuable, author, old_assignees = [])
- if issuable.assignees.any?
- assignees = issuable.assignees - old_assignees
- attributes = attributes_for_todo(issuable.project, issuable, author, Todo::ASSIGNED)
+ def create_assignment_todo(target, author, old_assignees = [])
+ if target.assignees.any?
+ assignees = target.assignees - old_assignees
+ attributes = attributes_for_todo(target.project, target, author, Todo::ASSIGNED)
create_todos(assignees, attributes)
end
end
diff --git a/app/services/user_project_access_changed_service.rb b/app/services/user_project_access_changed_service.rb
index 66f1ccfab70..11727f05f35 100644
--- a/app/services/user_project_access_changed_service.rb
+++ b/app/services/user_project_access_changed_service.rb
@@ -19,7 +19,8 @@ class UserProjectAccessChangedService
if priority == HIGH_PRIORITY
AuthorizedProjectsWorker.bulk_perform_async(bulk_args) # rubocop:disable Scalability/BulkPerformWithContext
else
- AuthorizedProjectUpdate::UserRefreshWithLowUrgencyWorker.bulk_perform_in(DELAY, bulk_args) # rubocop:disable Scalability/BulkPerformWithContext
+ AuthorizedProjectUpdate::UserRefreshWithLowUrgencyWorker.bulk_perform_in( # rubocop:disable Scalability/BulkPerformWithContext
+ DELAY, bulk_args, batch_size: 100, batch_delay: 30.seconds)
end
end
end
diff --git a/app/services/users/build_service.rb b/app/services/users/build_service.rb
index 3938d675596..f06f00a5c3f 100644
--- a/app/services/users/build_service.rb
+++ b/app/services/users/build_service.rb
@@ -82,7 +82,8 @@ module Users
:organization,
:location,
:public_email,
- :user_type
+ :user_type,
+ :note
]
end
diff --git a/app/services/users/destroy_service.rb b/app/services/users/destroy_service.rb
index 587a8516394..436d4fb3985 100644
--- a/app/services/users/destroy_service.rb
+++ b/app/services/users/destroy_service.rb
@@ -56,7 +56,7 @@ module Users
MigrateToGhostUserService.new(user).execute unless options[:hard_delete]
- response = Snippets::BulkDestroyService.new(current_user, user.snippets).execute
+ response = Snippets::BulkDestroyService.new(current_user, user.snippets).execute(options)
raise DestroyError, response.message if response.error?
# Rails attempts to load all related records into memory before
diff --git a/app/services/users/migrate_to_ghost_user_service.rb b/app/services/users/migrate_to_ghost_user_service.rb
index 5ca9ed67e56..1b46edd4d7d 100644
--- a/app/services/users/migrate_to_ghost_user_service.rb
+++ b/app/services/users/migrate_to_ghost_user_service.rb
@@ -53,6 +53,7 @@ module Users
migrate_abuse_reports
migrate_award_emoji
migrate_snippets
+ migrate_reviews
end
# rubocop: disable CodeReuse/ActiveRecord
@@ -85,6 +86,10 @@ module Users
snippets = user.snippets.only_project_snippets
snippets.update_all(author_id: ghost_user.id)
end
+
+ def migrate_reviews
+ user.reviews.update_all(author_id: ghost_user.id)
+ end
end
end
diff --git a/app/services/web_hook_service.rb b/app/services/web_hook_service.rb
index 178a321e20c..91a26ff45b1 100644
--- a/app/services/web_hook_service.rb
+++ b/app/services/web_hook_service.rb
@@ -63,7 +63,7 @@ class WebHookService
error_message: e.to_s
)
- Rails.logger.error("WebHook Error => #{e}") # rubocop:disable Gitlab/RailsLogger
+ Gitlab::AppLogger.error("WebHook Error => #{e}")
{
status: :error,
diff --git a/app/services/wiki_pages/create_service.rb b/app/services/wiki_pages/create_service.rb
index 4ef19676d82..63107445782 100644
--- a/app/services/wiki_pages/create_service.rb
+++ b/app/services/wiki_pages/create_service.rb
@@ -22,7 +22,7 @@ module WikiPages
end
def event_action
- Event::CREATED
+ :created
end
end
end
diff --git a/app/services/wiki_pages/destroy_service.rb b/app/services/wiki_pages/destroy_service.rb
index eb162223723..d59c27bb92a 100644
--- a/app/services/wiki_pages/destroy_service.rb
+++ b/app/services/wiki_pages/destroy_service.rb
@@ -19,7 +19,7 @@ module WikiPages
end
def event_action
- Event::DESTROYED
+ :destroyed
end
end
end
diff --git a/app/services/wiki_pages/update_service.rb b/app/services/wiki_pages/update_service.rb
index 0a056f1ec33..5ac6902e0b0 100644
--- a/app/services/wiki_pages/update_service.rb
+++ b/app/services/wiki_pages/update_service.rb
@@ -22,7 +22,7 @@ module WikiPages
end
def event_action
- Event::UPDATED
+ :updated
end
def slug_for_page(page)
diff --git a/app/uploaders/file_mover.rb b/app/uploaders/file_mover.rb
index 7c7953c8a0e..887cb702acf 100644
--- a/app/uploaders/file_mover.rb
+++ b/app/uploaders/file_mover.rb
@@ -98,7 +98,7 @@ class FileMover
end
def revert
- Rails.logger.warn("Markdown not updated, file move reverted for #{to_model}") # rubocop:disable Gitlab/RailsLogger
+ Gitlab::AppLogger.warn("Markdown not updated, file move reverted for #{to_model}")
if temp_file_uploader.file_storage?
FileUtils.move(file_path, temp_file_path)
diff --git a/app/validators/json_schema_validator.rb b/app/validators/json_schema_validator.rb
new file mode 100644
index 00000000000..f8c1727035c
--- /dev/null
+++ b/app/validators/json_schema_validator.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+#
+# JsonSchemaValidator
+#
+# Custom validator for json schema.
+# Create a json schema within the json_schemas directory
+#
+# class Project < ActiveRecord::Base
+# validates :data, json_schema: { filename: "file" }
+# end
+#
+class JsonSchemaValidator < ActiveModel::EachValidator
+ FILENAME_ALLOWED = /\A[a-z0-9_-]*\Z/.freeze
+ FilenameError = Class.new(StandardError)
+
+ def initialize(options)
+ raise ArgumentError, "Expected 'filename' as an argument" unless options[:filename]
+ raise FilenameError, "Must be a valid 'filename'" unless options[:filename].match?(FILENAME_ALLOWED)
+
+ super(options)
+ end
+
+ def validate_each(record, attribute, value)
+ unless valid_schema?(value)
+ record.errors.add(attribute, "must be a valid json schema")
+ end
+ end
+
+ private
+
+ def valid_schema?(value)
+ JSON::Validator.validate(schema_path, value)
+ end
+
+ def schema_path
+ Rails.root.join('app', 'validators', 'json_schemas', "#{options[:filename]}.json").to_s
+ end
+end
diff --git a/app/validators/json_schemas/build_report_result_data.json b/app/validators/json_schemas/build_report_result_data.json
new file mode 100644
index 00000000000..0fb4fd6d0b7
--- /dev/null
+++ b/app/validators/json_schemas/build_report_result_data.json
@@ -0,0 +1,12 @@
+{
+ "description": "Build report result data",
+ "type": "object",
+ "properties": {
+ "coverage": { "type": "float" },
+ "tests": {
+ "type": "object",
+ "items": { "$ref": "./build_report_result_data_tests.json" }
+ }
+ },
+ "additionalProperties": false
+}
diff --git a/app/validators/json_schemas/build_report_result_data_tests.json b/app/validators/json_schemas/build_report_result_data_tests.json
new file mode 100644
index 00000000000..b38559e727f
--- /dev/null
+++ b/app/validators/json_schemas/build_report_result_data_tests.json
@@ -0,0 +1,13 @@
+{
+ "description": "Build report result data tests",
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "duration": { "type": "string" },
+ "failed": { "type": "integer" },
+ "errored": { "type": "integer" },
+ "skipped": { "type": "integer" },
+ "success": { "type": "integer" }
+ },
+ "additionalProperties": false
+}
diff --git a/app/validators/json_schemas/daily_build_group_report_result_data.json b/app/validators/json_schemas/daily_build_group_report_result_data.json
new file mode 100644
index 00000000000..2524ac63050
--- /dev/null
+++ b/app/validators/json_schemas/daily_build_group_report_result_data.json
@@ -0,0 +1,8 @@
+{
+ "description": "Daily build group report result data",
+ "type": "object",
+ "properties": {
+ "coverage": { "type": "float" }
+ },
+ "additionalProperties": false
+}
diff --git a/app/views/admin/appearances/_form.html.haml b/app/views/admin/appearances/_form.html.haml
index 5bb05bcba26..aa47daf4a57 100644
--- a/app/views/admin/appearances/_form.html.haml
+++ b/app/views/admin/appearances/_form.html.haml
@@ -6,7 +6,7 @@
.row
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0 Navigation bar
+ %h4.gl-mt-0 Navigation bar
.col-lg-8
.form-group
@@ -25,7 +25,7 @@
%hr
.row
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0 Favicon
+ %h4.gl-mt-0 Favicon
.col-lg-8
.form-group
@@ -49,7 +49,7 @@
%hr
.row
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0 Sign in/Sign up pages
+ %h4.gl-mt-0 Sign in/Sign up pages
.col-lg-8
.form-group
@@ -77,7 +77,7 @@
%hr
.row
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0 New project pages
+ %h4.gl-mt-0 New project pages
.col-lg-8
.form-group
@@ -90,7 +90,7 @@
%hr
.row
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0 Profile image guideline
+ %h4.gl-mt-0 Profile image guideline
.col-lg-8
.form-group
diff --git a/app/views/admin/appearances/_system_header_footer_form.html.haml b/app/views/admin/appearances/_system_header_footer_form.html.haml
index 4301ebd05af..7f53b2baa32 100644
--- a/app/views/admin/appearances/_system_header_footer_form.html.haml
+++ b/app/views/admin/appearances/_system_header_footer_form.html.haml
@@ -3,7 +3,7 @@
%hr
.row
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
+ %h4.gl-mt-0
= _('System header and footer')
.col-lg-8
diff --git a/app/views/admin/application_settings/_account_and_limit.html.haml b/app/views/admin/application_settings/_account_and_limit.html.haml
index 94a7a1be455..ceec8901951 100644
--- a/app/views/admin/application_settings/_account_and_limit.html.haml
+++ b/app/views/admin/application_settings/_account_and_limit.html.haml
@@ -29,11 +29,16 @@
= f.label :receive_max_input_size, _('Maximum push size (MB)'), class: 'label-light'
= f.number_field :receive_max_input_size, class: 'form-control qa-receive-max-input-size-field', title: _('Maximum size limit for a single commit.'), data: { toggle: 'tooltip', container: 'body' }
.form-group
+ = f.label :max_import_size, _('Maximum import size (MB)'), class: 'label-light'
+ = f.number_field :max_import_size, class: 'form-control qa-receive-max-import-size-field', title: _('Maximum size of import files.'), data: { toggle: 'tooltip', container: 'body' }
+ %span.form-text.text-muted= _('0 for unlimited, only effective with remote storage enabled.')
+ .form-group
= f.label :session_expire_delay, _('Session duration (minutes)'), class: 'label-light'
= f.number_field :session_expire_delay, class: 'form-control', title: _('Maximum duration of a session.'), data: { toggle: 'tooltip', container: 'body' }
%span.form-text.text-muted#session_expire_delay_help_block= _('GitLab restart is required to apply changes.')
= render_if_exists 'admin/application_settings/personal_access_token_expiration_policy', form: f
+ = render_if_exists 'admin/application_settings/enforce_pat_expiration', form: f
.form-group
= f.label :user_oauth_applications, _('User OAuth applications'), class: 'label-bold'
diff --git a/app/views/admin/application_settings/_issue_limits.html.haml b/app/views/admin/application_settings/_issue_limits.html.haml
index 5906358fbb1..b0bdc204f64 100644
--- a/app/views/admin/application_settings/_issue_limits.html.haml
+++ b/app/views/admin/application_settings/_issue_limits.html.haml
@@ -3,7 +3,7 @@
%fieldset
.form-group
- = f.label :issues_create_limit, 'Max requests per second per user', class: 'label-bold'
+ = f.label :issues_create_limit, 'Max requests per minute per user', class: 'label-bold'
= f.number_field :issues_create_limit, class: 'form-control'
= f.submit 'Save changes', class: "btn btn-success", 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 42528f40123..b0593b3bfa2 100644
--- a/app/views/admin/application_settings/_outbound.html.haml
+++ b/app/views/admin/application_settings/_outbound.html.haml
@@ -14,10 +14,10 @@
.form-group
= f.label :outbound_local_requests_whitelist_raw, class: 'label-bold' do
- = _('Whitelist to allow requests to the local network from hooks and services')
+ = _('Local IP addresses and domain names that hooks and services may access.')
= f.text_area :outbound_local_requests_whitelist_raw, placeholder: "example.com, 192.168.1.1", class: 'form-control', rows: 8
%span.form-text.text-muted
- = _('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 whitelist 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.')
+ = _('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.')
.form-group
.form-check
diff --git a/app/views/admin/application_settings/_repository_storage.html.haml b/app/views/admin/application_settings/_repository_storage.html.haml
index 6fabafe3fc1..ed276da08f2 100644
--- a/app/views/admin/application_settings/_repository_storage.html.haml
+++ b/app/views/admin/application_settings/_repository_storage.html.haml
@@ -15,12 +15,12 @@
.form-group
.form-text
%p.text-secondary
- = _('Select the configured storage available for new repositories to be placed on.')
+ = _('Select a weight for the storage new repositories will be placed on.')
= link_to icon('question-circle'), help_page_path('administration/repository_storage_paths')
.form-check
- = f.collection_check_boxes :repository_storages, Gitlab.config.repositories.storages, :first, :first, include_hidden: false do |b|
- = b.check_box class: 'form-check-input'
- = b.label class: 'label-bold form-check-label'
+ - storage_weights.each do |attribute|
+ = f.text_field attribute[:name], class: 'form-text-input', value: attribute[:value]
+ = f.label attribute[:label], attribute[:label], class: 'label-bold form-check-label'
%br
= f.submit _('Save changes'), class: "btn btn-success qa-save-changes-button"
diff --git a/app/views/admin/application_settings/_spam.html.haml b/app/views/admin/application_settings/_spam.html.haml
index f0a19075115..ab9368e723e 100644
--- a/app/views/admin/application_settings/_spam.html.haml
+++ b/app/views/admin/application_settings/_spam.html.haml
@@ -62,4 +62,13 @@
.form-text.text-muted
How many seconds an IP will be counted towards the limit
+ .form-group
+ .form-check
+ = f.check_box :spam_check_endpoint_enabled, class: 'form-check-input'
+ = f.label :spam_check_endpoint_enabled, _('Enable Spam Check via external API endpoint'), class: 'form-check-label'
+ .form-text.text-muted= _('Define custom rules for what constitutes spam, independent of Akismet')
+ .form-group
+ = f.label :spam_check_endpoint_url, _('URL of the external Spam Check endpoint'), class: 'label-bold'
+ = f.text_field :spam_check_endpoint_url, class: 'form-control'
+
= f.submit 'Save changes', class: "btn btn-success"
diff --git a/app/views/admin/application_settings/ci/_header.html.haml b/app/views/admin/application_settings/ci/_header.html.haml
new file mode 100644
index 00000000000..9f03936f64a
--- /dev/null
+++ b/app/views/admin/application_settings/ci/_header.html.haml
@@ -0,0 +1,20 @@
+- expanded = local_assigns.fetch(:expanded)
+
+%h4
+ = _('Variables')
+ = link_to icon('question-circle'), help_page_path('ci/variables/README', anchor: 'variables'), target: '_blank', rel: 'noopener noreferrer'
+
+%button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded ? _('Collapse') : _('Expand')
+
+%p
+ = _('Environment variables are applied to all project environments in this instance via the Runner. You can use environment variables for passwords, secret keys, etc. Make variables available to the running application by prepending the variable key with <code>K8S_SECRET_</code>. You can set variables to be:').html_safe
+
+%ul
+ %li
+ = _('<code>Protected</code> to expose them to protected branches or tags only.').html_safe
+ %li
+ = _('<code>Masked</code> to prevent the values from being displayed in job logs (must match certain regexp requirements).').html_safe
+
+%p
+ = link_to _('More information'), help_page_path('ci/variables/README', anchor: 'instance-level-cicd-environment-variables')
diff --git a/app/views/admin/application_settings/ci_cd.html.haml b/app/views/admin/application_settings/ci_cd.html.haml
index 81f06926188..2452ab794fc 100644
--- a/app/views/admin/application_settings/ci_cd.html.haml
+++ b/app/views/admin/application_settings/ci_cd.html.haml
@@ -2,6 +2,17 @@
- page_title _("CI/CD")
- @content_class = "limit-container-width" unless fluid_layout
+- if ::Gitlab::Ci::Features.instance_variables_ui_enabled?
+ %section.settings.no-animate#js-ci-cd-variables{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ = render 'admin/application_settings/ci/header', expanded: expanded_by_default?
+ .settings-content
+ - if ci_variable_protected_by_default?
+ %p.settings-message.text-center
+ - link_start = '<a href="%{url}">'.html_safe % { url: help_page_path('ci/variables/README', anchor: 'protected-variables') }
+ = s_('Environment variables on this GitLab instance are configured to be %{link_start}protected%{link_end} by default').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
+ #js-instance-variables{ data: { endpoint: admin_ci_variables_path, group: 'true', maskable_regex: ci_variable_maskable_regex, protected_by_default: ci_variable_protected_by_default?.to_s} }
+
%section.settings.as-ci-cd.no-animate#js-ci-cd-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
diff --git a/app/views/admin/broadcast_messages/_form.html.haml b/app/views/admin/broadcast_messages/_form.html.haml
index 8b86a024a6e..79d758cf10b 100644
--- a/app/views/admin/broadcast_messages/_form.html.haml
+++ b/app/views/admin/broadcast_messages/_form.html.haml
@@ -1,4 +1,4 @@
-.broadcast-banner-message.js-broadcast-banner-message-preview.mt-2{ style: broadcast_message_style(@broadcast_message), class: ('hidden' unless @broadcast_message.banner? ) }
+.broadcast-message.broadcast-banner-message.alert-warning.js-broadcast-banner-message-preview.mt-2{ style: broadcast_message_style(@broadcast_message), class: ('hidden' unless @broadcast_message.banner? ) }
= sprite_icon('bullhorn', size: 16, css_class:'vertical-align-text-top')
.js-broadcast-message-preview
- if @broadcast_message.message.present?
@@ -6,7 +6,7 @@
- else
Your message here
.d-flex.justify-content-center
- .broadcast-notification-message.preview.js-broadcast-notification-message-preview.mt-2{ class: ('hidden' unless @broadcast_message.notification? ) }
+ .broadcast-message.broadcast-notification-message.preview.js-broadcast-notification-message-preview.mt-2{ class: ('hidden' unless @broadcast_message.notification? ) }
= sprite_icon('bullhorn', size: 16, css_class:'vertical-align-text-top')
.js-broadcast-message-preview
- if @broadcast_message.message.present?
diff --git a/app/views/admin/broadcast_messages/index.html.haml b/app/views/admin/broadcast_messages/index.html.haml
index 6f2433e3306..e7a7ee96508 100644
--- a/app/views/admin/broadcast_messages/index.html.haml
+++ b/app/views/admin/broadcast_messages/index.html.haml
@@ -12,7 +12,7 @@
%br.clearfix
- if @broadcast_messages.any?
- %table.table
+ %table.table.table-responsive
%thead
%tr
%th Status
@@ -37,7 +37,7 @@
= message.target_path
%td
= message.broadcast_type.capitalize
- %td
+ %td.gl-white-space-nowrap
= link_to sprite_icon('pencil-square'), edit_admin_broadcast_message_path(message), title: 'Edit', class: 'btn'
= link_to sprite_icon('remove'), admin_broadcast_message_path(message), method: :delete, remote: true, title: 'Remove', class: 'js-remove-tr btn btn-danger'
diff --git a/app/views/admin/groups/_group.html.haml b/app/views/admin/groups/_group.html.haml
index 5fe8f9b4bbc..bbeeb1be929 100644
--- a/app/views/admin/groups/_group.html.haml
+++ b/app/views/admin/groups/_group.html.haml
@@ -1,34 +1,37 @@
- group = local_assigns.fetch(:group)
-- css_class = 'no-description' if group.description.blank?
+- css_class = "gl-display-flex!#{' no-description' if group.description.blank?}"
-%li.group-row.py-3{ class: css_class, data: { qa_selector: 'group_row_content' } }
- .controls
- = link_to _('Edit'), admin_group_edit_path(group), id: "edit_#{dom_id(group)}", class: 'btn'
- = link_to _('Delete'), [:admin, group], data: { confirm: _("Are you sure you want to remove %{group_name}?") % { group_name: group.name } }, method: :delete, class: 'btn btn-remove'
- .stats
+%li.group-row.gl-py-3.gl-align-items-center{ class: css_class, data: { qa_selector: 'group_row_content' } }
+ .avatar-container.rect-avatar.s40.gl-flex-shrink-0
+ = group_icon(group, class: "avatar s40")
+
+ .gl-min-w-0.gl-flex-grow-1
+ .title
+ = link_to [:admin, group], class: 'group-name', data: { qa_selector: 'group_name_link' } do
+ = group.full_name
+
+ - if group.description.present?
+ .description
+ = markdown_field(group, :description)
+
+ .stats.gl-text-gray-700.gl-flex-shrink-0.gl-display-none.gl-display-sm-flex
%span.badge.badge-pill
= storage_counter(group.storage_size)
- = render_if_exists 'admin/namespace_plan_badge', namespace: group
- = render_if_exists 'admin/groups/marked_for_deletion_badge', group: group
+ = render_if_exists 'admin/namespace_plan_badge', namespace: group, css_class: 'gl-ml-5 gl-mr-0'
+ = render_if_exists 'admin/groups/marked_for_deletion_badge', group: group, css_class: 'gl-ml-5'
- %span
+ %span.gl-ml-5
= icon('bookmark')
= number_with_delimiter(group.projects.count)
- %span
+ %span.gl-ml-5
= icon('users')
= number_with_delimiter(group.users.count)
- %span.visibility-icon.has-tooltip{ data: { container: 'body', placement: 'left' }, title: visibility_icon_description(group) }
+ %span.gl-ml-5.visibility-icon.has-tooltip{ data: { container: 'body', placement: 'left' }, title: visibility_icon_description(group) }
= visibility_level_icon(group.visibility_level, fw: false)
- .avatar-container.rect-avatar.s40
- = group_icon(group, class: "avatar s40 d-none d-sm-block")
- .title
- = link_to [:admin, group], class: 'group-name', data: { qa_selector: 'group_name_link' } do
- = group.full_name
-
- - if group.description.present?
- .description
- = markdown_field(group, :description)
+ .controls.gl-flex-shrink-0.gl-ml-5
+ = link_to _('Edit'), admin_group_edit_path(group), id: "edit_#{dom_id(group)}", class: 'btn'
+ = link_to _('Delete'), [:admin, group], data: { confirm: _("Are you sure you want to remove %{group_name}?") % { group_name: group.name } }, method: :delete, class: 'btn btn-remove'
diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml
index ebed558f11b..e105091e773 100644
--- a/app/views/admin/groups/show.html.haml
+++ b/app/views/admin/groups/show.html.haml
@@ -59,6 +59,8 @@
= render_if_exists 'namespaces/shared_runner_status', namespace: @group
+ = render 'shared/custom_attributes', custom_attributes: @group.custom_attributes
+
= render_if_exists 'ldap_group_links/ldap_group_links_show', group: @group
.card
diff --git a/app/views/admin/hook_logs/_index.html.haml b/app/views/admin/hook_logs/_index.html.haml
index 1d7c9930b6a..841640efad2 100644
--- a/app/views/admin/hook_logs/_index.html.haml
+++ b/app/views/admin/hook_logs/_index.html.haml
@@ -1,6 +1,6 @@
.row.prepend-top-default.append-bottom-default
.col-lg-3
- %h4.prepend-top-0
+ %h4.gl-mt-0
Recent Deliveries
%p When an event in GitLab triggers a webhook, you can use the request details to figure out if something went wrong.
.col-lg-9
diff --git a/app/views/admin/hooks/edit.html.haml b/app/views/admin/hooks/edit.html.haml
index 9ce0fa8d401..636dd6bdfc1 100644
--- a/app/views/admin/hooks/edit.html.haml
+++ b/app/views/admin/hooks/edit.html.haml
@@ -9,7 +9,7 @@
= form_for @hook, as: :hook, url: admin_hook_path do |f|
= render partial: 'form', locals: { form: f, hook: @hook }
.form-actions
- %span>= f.submit _('Save changes'), class: 'btn btn-success append-right-8'
+ %span>= f.submit _('Save changes'), class: 'btn btn-success gl-mr-3'
= render 'shared/web_hooks/test_button', hook: @hook
= link_to _('Delete'), admin_hook_path(@hook), method: :delete, class: 'btn btn-remove float-right', data: { confirm: _('Are you sure?') }
diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml
index 8abc4c37e70..f9d42d3f53b 100644
--- a/app/views/admin/projects/show.html.haml
+++ b/app/views/admin/projects/show.html.haml
@@ -108,6 +108,8 @@
= visibility_level_icon(@project.visibility_level)
= visibility_level_label(@project.visibility_level)
+ = render 'shared/custom_attributes', custom_attributes: @project.custom_attributes
+
= render_if_exists 'admin/projects/geo_status_widget', locals: { project: @project }
.card
diff --git a/app/views/admin/sessions/_two_factor_u2f.html.haml b/app/views/admin/sessions/_two_factor_u2f.html.haml
deleted file mode 100644
index 09b91d76295..00000000000
--- a/app/views/admin/sessions/_two_factor_u2f.html.haml
+++ /dev/null
@@ -1,17 +0,0 @@
-#js-authenticate-u2f
-%a.btn.btn-block.btn-info#js-login-2fa-device{ href: '#' }= _("Sign in via 2FA code")
-
-%script#js-authenticate-u2f-in-progress{ type: "text/template" }
- %p= _("Trying to communicate with your device. Plug it in (if you haven't already) and press the button on the device now.")
-
--# haml-lint:disable NoPlainNodes
-%script#js-authenticate-u2f-error{ type: "text/template" }
- %div
- %p <%= error_message %> (#{_("error code:")} <%= error_code %>)
- %a.btn.btn-block.btn-warning#js-u2f-try-again= _("Try again?")
-
-%script#js-authenticate-u2f-authenticated{ type: "text/template" }
- %div
- %p= _("We heard back from your U2F device. You have been authenticated.")
- = form_tag(admin_session_path, method: :post, id: 'js-login-u2f-form') do |f|
- = hidden_field_tag 'user[device_response]', nil, class: 'form-control', required: true, id: "js-device-response"
diff --git a/app/views/admin/sessions/two_factor.html.haml b/app/views/admin/sessions/two_factor.html.haml
index 57a3452cf35..746d57dbad1 100644
--- a/app/views/admin/sessions/two_factor.html.haml
+++ b/app/views/admin/sessions/two_factor.html.haml
@@ -12,4 +12,4 @@
- if current_user.two_factor_otp_enabled?
= render 'admin/sessions/two_factor_otp'
- if current_user.two_factor_u2f_enabled?
- = render 'admin/sessions/two_factor_u2f'
+ = render 'u2f/authenticate', render_remember_me: false, target_path: admin_session_path
diff --git a/app/views/admin/users/_admin_notes.html.haml b/app/views/admin/users/_admin_notes.html.haml
new file mode 100644
index 00000000000..5d91ba1a1ca
--- /dev/null
+++ b/app/views/admin/users/_admin_notes.html.haml
@@ -0,0 +1,7 @@
+%fieldset
+ %legend= _('Admin notes')
+ .form-group.row
+ .col-sm-2.col-form-label.text-right
+ = f.label :note, s_('AdminNote|Note')
+ .col-sm-10
+ = f.text_area :note, class: 'form-control'
diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml
index 3281718071c..38c6c8b2a62 100644
--- a/app/views/admin/users/_form.html.haml
+++ b/app/views/admin/users/_form.html.haml
@@ -83,7 +83,7 @@
.col-sm-10
= f.text_field :website_url, class: 'form-control'
- = render_if_exists 'admin/users/admin_notes', f: f
+ = render 'admin/users/admin_notes', f: f
.form-actions
- if @user.new_record?
diff --git a/app/views/admin/users/_user_detail.html.haml b/app/views/admin/users/_user_detail.html.haml
index 3cc3fc6fa92..3839231cb95 100644
--- a/app/views/admin/users/_user_detail.html.haml
+++ b/app/views/admin/users/_user_detail.html.haml
@@ -3,10 +3,10 @@
= image_tag avatar_icon_for_user(user), class: 'avatar s32 d-none d-md-flex', alt: _('Avatar for %{name}') % { name: sanitize_name(user.name) }
.row-main-content
.row-title.str-truncated-100
- = image_tag avatar_icon_for_user(user), class: 'avatar s16 d-xs-flex d-md-none mr-1 prepend-top-2', alt: _('Avatar for %{name}') % { name: sanitize_name(user.name) }
+ = image_tag avatar_icon_for_user(user), class: 'avatar s16 d-xs-flex d-md-none mr-1 gl-mt-2', alt: _('Avatar for %{name}') % { name: sanitize_name(user.name) }
= link_to user.name, admin_user_path(user), class: 'text-plain js-user-link', data: { user_id: user.id, qa_selector: 'username_link' }
- = render_if_exists 'admin/users/user_listing_note', user: user
+ = render 'admin/users/user_listing_note', user: user
- user_badges_in_admin_section(user).each do |badge|
- css_badge = "badge badge-#{badge[:variant]}" if badge[:variant].present?
diff --git a/app/views/admin/users/_user_detail_note.html.haml b/app/views/admin/users/_user_detail_note.html.haml
new file mode 100644
index 00000000000..4f2a682c5ca
--- /dev/null
+++ b/app/views/admin/users/_user_detail_note.html.haml
@@ -0,0 +1,7 @@
+- if @user.note.present?
+ - text = @user.note
+ .card.border-info
+ .card-header.bg-info.text-white
+ = _('Admin Note')
+ .card-body
+ %p= text
diff --git a/app/views/admin/users/_user_listing_note.html.haml b/app/views/admin/users/_user_listing_note.html.haml
new file mode 100644
index 00000000000..df4af009c5c
--- /dev/null
+++ b/app/views/admin/users/_user_listing_note.html.haml
@@ -0,0 +1,3 @@
+- if user.note.present?
+ %span.has-tooltip.user-note{ title: user.note }
+ = icon("sticky-note-o cgrey")
diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml
index cd07fee8e59..e76f1f6444c 100644
--- a/app/views/admin/users/show.html.haml
+++ b/app/views/admin/users/show.html.haml
@@ -86,7 +86,7 @@
%li
%span.light Current sign-in IP:
%strong
- - if @user.current_sign_in_ip
+ - if @user.current_sign_in_ip # rubocop:disable Style/RedundantCondition
= @user.current_sign_in_ip
- else
never
@@ -102,7 +102,7 @@
%li
%span.light Last sign-in IP:
%strong
- - if @user.last_sign_in_ip
+ - if @user.last_sign_in_ip # rubocop:disable Style/RedundantCondition
= @user.last_sign_in_ip
- else
never
@@ -141,6 +141,8 @@
= render_if_exists 'namespaces/shared_runner_status', namespace: @user.namespace
+ = render 'shared/custom_attributes', custom_attributes: @user.custom_attributes
+
.col-md-6
- unless @user == current_user
- unless @user.confirmed?
@@ -154,7 +156,7 @@
%br
= link_to 'Confirm user', confirm_admin_user_path(@user), method: :put, class: "btn btn-info", data: { confirm: 'Are you sure?', qa_selector: 'confirm_user_button' }
- = render_if_exists 'admin/users/user_detail_note'
+ = render 'admin/users/user_detail_note'
- if @user.deactivated?
.card.border-info
diff --git a/app/views/ci/variables/_index.html.haml b/app/views/ci/variables/_index.html.haml
index 26051261715..fa5f2c514ae 100644
--- a/app/views/ci/variables/_index.html.haml
+++ b/app/views/ci/variables/_index.html.haml
@@ -8,7 +8,18 @@
- if Feature.enabled?(:new_variables_ui, @project || @group, default_enabled: true)
- is_group = !@group.nil?
- #js-ci-project-variables{ data: { endpoint: save_endpoint, project_id: @project&.id || '', group: is_group.to_s, maskable_regex: ci_variable_maskable_regex, protected_by_default: ci_variable_protected_by_default?.to_s} }
+ #js-ci-project-variables{ data: { endpoint: save_endpoint,
+ project_id: @project&.id || '',
+ group: is_group.to_s,
+ maskable_regex: ci_variable_maskable_regex,
+ protected_by_default: ci_variable_protected_by_default?.to_s,
+ aws_logo_svg_path: image_path('aws_logo.svg'),
+ 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'),
+ protected_environment_variables_link: help_page_path('ci/variables/README', anchor: 'protect-a-custom-variable'),
+ masked_environment_variables_link: help_page_path('ci/variables/README', anchor: 'mask-a-custom-variable'),
+ } }
- else
.row
diff --git a/app/views/clusters/clusters/_banner.html.haml b/app/views/clusters/clusters/_banner.html.haml
index 82057fd0463..e9ad0c6a4e0 100644
--- a/app/views/clusters/clusters/_banner.html.haml
+++ b/app/views/clusters/clusters/_banner.html.haml
@@ -4,7 +4,7 @@
.hidden.js-cluster-creating.bs-callout.bs-callout-info{ role: 'alert' }
%span.spinner.spinner-dark.spinner-sm{ 'aria-label': 'Loading' }
- %span.prepend-left-4= s_('ClusterIntegration|Kubernetes cluster is being created...')
+ %span.gl-ml-2= s_('ClusterIntegration|Kubernetes cluster is being created...')
.hidden.row.js-cluster-api-unreachable.gl-alert.gl-alert-warning{ role: 'alert' }
= sprite_icon('warning', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
diff --git a/app/views/clusters/clusters/_gcp_signup_offer_banner.html.haml b/app/views/clusters/clusters/_gcp_signup_offer_banner.html.haml
index 617e5d1d5d3..486625c790b 100644
--- a/app/views/clusters/clusters/_gcp_signup_offer_banner.html.haml
+++ b/app/views/clusters/clusters/_gcp_signup_offer_banner.html.haml
@@ -2,7 +2,7 @@
.bs-callout.gcp-signup-offer.alert.alert-block.alert-dismissable.prepend-top-default.append-bottom-default{ role: 'alert', data: { feature_id: UserCalloutsHelper::GCP_SIGNUP_OFFER, dismiss_endpoint: user_callouts_path } }
%button.close.js-close{ type: "button" } &times;
.gcp-signup-offer--content
- .gcp-signup-offer--icon.append-right-8
+ .gcp-signup-offer--icon.gl-mr-3
= sprite_icon("information", size: 16)
.gcp-signup-offer--copy
%h4= s_('ClusterIntegration|Did you know?')
diff --git a/app/views/clusters/clusters/_gitlab_integration_form.html.haml b/app/views/clusters/clusters/_gitlab_integration_form.html.haml
index 2489f78b403..c5b54997407 100644
--- a/app/views/clusters/clusters/_gitlab_integration_form.html.haml
+++ b/app/views/clusters/clusters/_gitlab_integration_form.html.haml
@@ -4,7 +4,7 @@
.d-flex.align-items-center
%h4.pr-2.m-0
= s_('ClusterIntegration|GitLab Integration')
- %label.append-bottom-0.js-cluster-enable-toggle-area{ title: s_('ClusterIntegration|Enable or disable GitLab\'s connection to your Kubernetes cluster.'), data: { toggle: 'tooltip', container: 'body' } }
+ %label.gl-mb-0.js-cluster-enable-toggle-area{ title: s_('ClusterIntegration|Enable or disable GitLab\'s connection to your Kubernetes cluster.'), data: { toggle: 'tooltip', container: 'body' } }
= render "shared/buttons/project_feature_toggle", is_checked: @cluster.enabled?, label: s_("ClusterIntegration|Toggle Kubernetes cluster"), disabled: !can?(current_user, :update_cluster, @cluster), data: { qa_selector: 'integration_status_toggle' } do
= field.hidden_field :enabled, { class: 'js-project-feature-toggle-input'}
diff --git a/app/views/clusters/clusters/_sidebar.html.haml b/app/views/clusters/clusters/_sidebar.html.haml
index 60ccad5b943..24a74c59b97 100644
--- a/app/views/clusters/clusters/_sidebar.html.haml
+++ b/app/views/clusters/clusters/_sidebar.html.haml
@@ -1,4 +1,4 @@
-%h4.prepend-top-0
+%h4.gl-mt-0
= s_('ClusterIntegration|Add a Kubernetes cluster integration')
%p
= clusterable.sidebar_text
diff --git a/app/views/clusters/clusters/index.html.haml b/app/views/clusters/clusters/index.html.haml
index 86194842664..a654a8741a4 100644
--- a/app/views/clusters/clusters/index.html.haml
+++ b/app/views/clusters/clusters/index.html.haml
@@ -19,7 +19,7 @@
= link_to _('More information'), help_page_path('user/group/clusters/index', anchor: 'cluster-precedence')
- if Feature.enabled?(:clusters_list_redesign)
- #js-clusters-list-app{ data: { endpoint: clusterable.index_path(format: :json) } }
+ #js-clusters-list-app{ data: js_clusters_list_data(clusterable.index_path(format: :json)) }
- else
.clusters-table.js-clusters-list
.gl-responsive-table-row.table-row-header{ role: "row" }
diff --git a/app/views/clusters/clusters/show.html.haml b/app/views/clusters/clusters/show.html.haml
index 1cc68d927bd..83b8092fb48 100644
--- a/app/views/clusters/clusters/show.html.haml
+++ b/app/views/clusters/clusters/show.html.haml
@@ -30,7 +30,7 @@
ingress_help_path: help_page_path('user/project/clusters/index.md', anchor: 'getting-the-external-endpoint'),
ingress_dns_help_path: help_page_path('user/clusters/applications.md', anchor: 'pointing-your-dns-at-the-external-endpoint'),
ingress_mod_security_help_path: help_page_path('user/clusters/applications.md', anchor: 'web-application-firewall-modsecurity'),
- environments_help_path: help_page_path('ci/environments', anchor: 'defining-environments'),
+ environments_help_path: help_page_path('ci/environments/index.md', anchor: 'defining-environments'),
clusters_help_path: help_page_path('user/project/clusters/index.md', anchor: 'deploying-to-a-kubernetes-cluster'),
deploy_boards_help_path: help_page_path('user/project/deploy_boards.html', anchor: 'enabling-deploy-boards'),
cloud_run_help_path: help_page_path('user/project/clusters/add_remove_clusters.md', anchor: 'cloud-run-for-anthos'),
diff --git a/app/views/dashboard/milestones/_milestone.html.haml b/app/views/dashboard/milestones/_milestone.html.haml
index 89212eb6bf9..4921de32f65 100644
--- a/app/views/dashboard/milestones/_milestone.html.haml
+++ b/app/views/dashboard/milestones/_milestone.html.haml
@@ -1,5 +1,4 @@
= render 'shared/milestones/milestone',
- milestone_path: group_or_project_milestone_path(milestone),
issues_path: issues_dashboard_path(milestone_title: milestone.title),
merge_requests_path: merge_requests_dashboard_path(milestone_title: milestone.title),
milestone: milestone,
diff --git a/app/views/dashboard/milestones/show.html.haml b/app/views/dashboard/milestones/show.html.haml
deleted file mode 100644
index 2129920afd2..00000000000
--- a/app/views/dashboard/milestones/show.html.haml
+++ /dev/null
@@ -1,5 +0,0 @@
-- header_title "Milestones", dashboard_milestones_path
-
-= render 'shared/milestones/top', milestone: @milestone
-= render 'shared/milestones/tabs', milestone: @milestone, show_full_project_name: true
-= render 'shared/milestones/sidebar', milestone: @milestone, affix_offset: 51
diff --git a/app/views/devise/confirmations/almost_there.haml b/app/views/devise/confirmations/almost_there.haml
index 79826a364db..a1fcbea5bf2 100644
--- a/app/views/devise/confirmations/almost_there.haml
+++ b/app/views/devise/confirmations/almost_there.haml
@@ -1,5 +1,5 @@
.well-confirmation.text-center.append-bottom-20
- %h1.prepend-top-0
+ %h1.gl-mt-0
Almost there...
%p.lead.append-bottom-20
Please check your email to confirm your account
diff --git a/app/views/devise/sessions/two_factor.html.haml b/app/views/devise/sessions/two_factor.html.haml
index f49cdfbf8da..126d8450568 100644
--- a/app/views/devise/sessions/two_factor.html.haml
+++ b/app/views/devise/sessions/two_factor.html.haml
@@ -14,4 +14,4 @@
= f.submit "Verify code", class: "btn btn-success"
- if @user.two_factor_u2f_enabled?
- = render "u2f/authenticate", locals: { params: params, resource: resource, resource_name: resource_name }
+ = render "u2f/authenticate", params: params, resource: resource, resource_name: resource_name, render_remember_me: true, target_path: new_user_session_path
diff --git a/app/views/devise/shared/_omniauth_box.html.haml b/app/views/devise/shared/_omniauth_box.html.haml
index 5c3e4ccbfe5..e99d0ac1105 100644
--- a/app/views/devise/shared/_omniauth_box.html.haml
+++ b/app/views/devise/shared/_omniauth_box.html.haml
@@ -7,7 +7,7 @@
.d-flex.justify-content-between.flex-wrap
- providers.each do |provider|
- has_icon = provider_has_icon?(provider)
- = link_to omniauth_authorize_path(:user, provider), method: :post, class: "btn d-flex align-items-center omniauth-btn text-left oauth-login #{qa_class_for_provider(provider)}", id: "oauth-login-#{provider}" do
+ = button_to omniauth_authorize_path(:user, provider), id: "oauth-login-#{provider}", class: "btn d-flex align-items-center omniauth-btn text-left oauth-login #{qa_class_for_provider(provider)}" do
- if has_icon
= provider_image_tag(provider)
%span
diff --git a/app/views/doorkeeper/applications/index.html.haml b/app/views/doorkeeper/applications/index.html.haml
index 5d85d9e431f..9aab1556373 100644
--- a/app/views/doorkeeper/applications/index.html.haml
+++ b/app/views/doorkeeper/applications/index.html.haml
@@ -3,7 +3,7 @@
.row.prepend-top-default
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
+ %h4.gl-mt-0
= page_title
%p
- if user_oauth_applications?
@@ -12,7 +12,7 @@
= _("Manage applications that you've authorized to use your account.")
.col-lg-8
- if user_oauth_applications?
- %h5.prepend-top-0
+ %h5.gl-mt-0
= _('Add new application')
= render 'form', application: @application
%hr
diff --git a/app/views/events/event/_note.html.haml b/app/views/events/event/_note.html.haml
index 7e2103287f7..21e8b1401ca 100644
--- a/app/views/events/event/_note.html.haml
+++ b/app/views/events/event/_note.html.haml
@@ -7,8 +7,10 @@
%span.event-type.d-inline-block.append-right-4{ class: event.action_name }
= event.action_name
= event_note_title_html(event)
- %span.event-target-title.append-right-4{ dir: "auto" }
- = "&quot;".html_safe + event.target.title + "&quot".html_safe
+ - title = note_target_title(event.target)
+ - if title.present?
+ %span.event-target-title.append-right-4{ dir: "auto" }
+ = "&quot;".html_safe + title + "&quot".html_safe
= render "events/event_scope", event: event
diff --git a/app/views/groups/_flash_messages.html.haml b/app/views/groups/_flash_messages.html.haml
index fa1a9d2cca4..ca951f28fcf 100644
--- a/app/views/groups/_flash_messages.html.haml
+++ b/app/views/groups/_flash_messages.html.haml
@@ -1,2 +1,3 @@
= content_for :flash_message do
= render_if_exists 'shared/shared_runners_minutes_limit', namespace: @group, classes: [container_class, ("limit-container-width" unless fluid_layout)]
+ = render 'shared/namespace_storage_limit_alert', namespace: @group, classes: [container_class, ("limit-container-width" unless fluid_layout)]
diff --git a/app/views/groups/_home_panel.html.haml b/app/views/groups/_home_panel.html.haml
index d083288edc8..9bf7ad228d9 100644
--- a/app/views/groups/_home_panel.html.haml
+++ b/app/views/groups/_home_panel.html.haml
@@ -9,15 +9,15 @@
= group_icon(@group, class: 'avatar avatar-tile s64', width: 64, height: 64)
.d-flex.flex-column.flex-wrap.align-items-baseline
.d-inline-flex.align-items-baseline
- %h1.home-panel-title.prepend-top-8.append-bottom-5
+ %h1.home-panel-title.gl-mt-3.append-bottom-5
= @group.name
- %span.visibility-icon.text-secondary.prepend-left-4.has-tooltip{ data: { container: 'body' }, title: visibility_icon_description(@group) }
+ %span.visibility-icon.text-secondary.gl-ml-2.has-tooltip{ data: { container: 'body' }, title: visibility_icon_description(@group) }
= visibility_level_icon(@group.visibility_level, fw: false, options: {class: 'icon'})
.home-panel-metadata.d-flex.align-items-center.text-secondary
%span
= _("Group ID: %{group_id}") % { group_id: @group.id }
- if current_user
- %span.access-request-links.prepend-left-8
+ %span.access-request-links.gl-ml-3
= render 'shared/members/access_request_links', source: @group
.home-panel-buttons.col-md-12.col-lg-6.d-inline-flex.flex-wrap.justify-content-lg-end
diff --git a/app/views/groups/_import_group_pane.html.haml b/app/views/groups/_import_group_pane.html.haml
new file mode 100644
index 00000000000..adfac7d59a5
--- /dev/null
+++ b/app/views/groups/_import_group_pane.html.haml
@@ -0,0 +1,52 @@
+- parent = @group.parent
+- group_path = root_url
+- group_path << parent.full_path + '/' if parent
+
+= form_with url: import_gitlab_group_path, class: 'group-form gl-show-field-errors', multipart: true do |f|
+ = form_errors(@group)
+
+ .row
+ .form-group.group-name.col-sm-12
+ = f.label :name, _('Group name'), class: 'label-bold'
+ = f.text_field :name, placeholder: s_('GroupsNew|My Awesome Group'), class: 'js-autofill-group-name form-control input-lg',
+ required: true,
+ title: _('Please fill in a descriptive name for your group.'),
+ autofocus: true
+
+ .row
+ .form-group.col-xs-12.col-sm-8
+ = f.label :path, _('Group URL'), class: 'label-bold'
+ .input-group.gl-field-error-anchor
+ .group-root-path.input-group-prepend.has-tooltip{ title: group_path, :'data-placement' => 'bottom' }
+ .input-group-text
+ %span
+ = root_url
+ - if parent
+ %strong= parent.full_path + '/'
+ = f.hidden_field :parent_id, value: parent&.id
+ = f.text_field :path, placeholder: 'my-awesome-group', class: 'form-control js-validate-group-path js-autofill-group-path',
+ id: 'import_group_path',
+ required: true,
+ pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS,
+ title: _('Please choose a group URL with no special characters.'),
+ "data-bind-in" => "#{'create_chat_team' if Gitlab.config.mattermost.enabled}"
+ %p.validation-error.gl-field-error.field-validation.hide
+ = _('Group path is already taken. Suggestions: ')
+ %span.gl-path-suggestions
+ %p.validation-success.gl-field-success.field-validation.hide= _('Group path is available.')
+ %p.validation-pending.gl-field-error-ignore.field-validation.hide= _('Checking group path availability...')
+
+ .row
+ .form-group.col-md-12
+ = s_('GroupsNew|To copy a GitLab group between installations, navigate to the group settings page for the original installation, generate an export file, and upload it here.')
+ .row
+ .form-group.col-sm-12
+ = f.label :file, s_('GroupsNew|GitLab group export'), class: 'label-bold'
+ %div
+ = render 'shared/file_picker_button', f: f, field: :file, help_text: nil
+
+ .row
+ .form-actions.col-sm-12
+ = f.submit s_('GroupsNew|Import group'), class: 'btn btn-success'
+ = link_to _('Cancel'), new_group_path, class: 'btn btn-cancel'
+
diff --git a/app/views/groups/_new_group_fields.html.haml b/app/views/groups/_new_group_fields.html.haml
new file mode 100644
index 00000000000..d9706556e79
--- /dev/null
+++ b/app/views/groups/_new_group_fields.html.haml
@@ -0,0 +1,22 @@
+= form_errors(@group)
+= render 'shared/group_form', f: f, autofocus: true
+
+.row
+ .form-group.group-description-holder.col-sm-12
+ = f.label :avatar, _("Group avatar"), class: 'label-bold'
+ %div
+ = render 'shared/choose_avatar_button', f: f
+
+ .form-group.col-sm-12
+ %label.label-bold
+ = _('Visibility level')
+ %p
+ = _('Who will be able to see this group?')
+ = link_to _('View the documentation'), help_page_path("public_access/public_access"), target: '_blank'
+ = render 'shared/visibility_level', f: f, visibility_level: default_group_visibility, can_change_visibility_level: true, form_model: @group, with_label: false
+
+ = render 'create_chat_team', f: f if Gitlab.config.mattermost.enabled
+
+ .form-actions.col-sm-12
+ = f.submit _('Create group'), class: "btn btn-success"
+ = link_to _('Cancel'), dashboard_groups_path, class: 'btn btn-cancel'
diff --git a/app/views/groups/imports/show.html.haml b/app/views/groups/imports/show.html.haml
new file mode 100644
index 00000000000..ac8ca8797fe
--- /dev/null
+++ b/app/views/groups/imports/show.html.haml
@@ -0,0 +1,10 @@
+- page_title _('Import in progress')
+- @content_class = "limit-container-width" unless fluid_layout
+
+.save-group-loader
+ .center
+ %h2
+ %i.loading.spinner.spinner-sm
+ = page_title
+ %p
+ = s_('GroupImport|Please wait while we import the group for you. Refresh at will.')
diff --git a/app/views/groups/milestones/_form.html.haml b/app/views/groups/milestones/_form.html.haml
index b0ba846f204..7a35bc12eee 100644
--- a/app/views/groups/milestones/_form.html.haml
+++ b/app/views/groups/milestones/_form.html.haml
@@ -11,8 +11,8 @@
.col-form-label.col-sm-2
= f.label :description, "Description"
.col-sm-10
- = render layout: 'projects/md_preview', locals: { url: group_preview_markdown_path } do
- = render 'projects/zen', f: f, attr: :description, classes: 'note-textarea', placeholder: 'Write milestone description...', supports_autocomplete: false
+ = render layout: 'shared/md_preview', locals: { url: group_preview_markdown_path } do
+ = render 'shared/zen', f: f, attr: :description, classes: 'note-textarea', placeholder: 'Write milestone description...', supports_autocomplete: false
.clearfix
.error-alert
= render "shared/milestones/form_dates", f: f
diff --git a/app/views/groups/milestones/_milestone.html.haml b/app/views/groups/milestones/_milestone.html.haml
index bae8997e24c..b73626dab81 100644
--- a/app/views/groups/milestones/_milestone.html.haml
+++ b/app/views/groups/milestones/_milestone.html.haml
@@ -1,6 +1,4 @@
-
= render 'shared/milestones/milestone',
- milestone_path: group_milestone_route(milestone),
issues_path: issues_group_path(@group, milestone_title: milestone.title),
merge_requests_path: merge_requests_group_path(@group, milestone_title: milestone.title),
milestone: milestone
diff --git a/app/views/groups/milestones/index.html.haml b/app/views/groups/milestones/index.html.haml
index b6fb908c8f6..03407adb57d 100644
--- a/app/views/groups/milestones/index.html.haml
+++ b/app/views/groups/milestones/index.html.haml
@@ -16,5 +16,8 @@
.nothing-here-block No milestones to show
- else
- @milestones.each do |milestone|
- = render 'milestone', milestone: milestone
+ - if milestone.project_milestone?
+ = render 'projects/milestones/milestone', milestone: milestone
+ - else
+ = render 'milestone', milestone: milestone
= paginate @milestones, theme: "gitlab"
diff --git a/app/views/groups/new.html.haml b/app/views/groups/new.html.haml
index 376624f4786..ed016206310 100644
--- a/app/views/groups/new.html.haml
+++ b/app/views/groups/new.html.haml
@@ -2,43 +2,44 @@
- @hide_top_links = true
- page_title _('New Group')
- header_title _("Groups"), dashboard_groups_path
+- active_tab = local_assigns.fetch(:active_tab, 'create')
-.page-title-holder.d-flex.align-items-center
- %h1.page-title= _('New group')
-.row.prepend-top-default
- .col-lg-3.profile-settings-sidebar
- %p
- - group_docs_path = help_page_path('user/group/index')
- - group_docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: group_docs_path }
- = s_('%{group_docs_link_start}Groups%{group_docs_link_end} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects.').html_safe % { group_docs_link_start: group_docs_link_start, group_docs_link_end: '</a>'.html_safe }
- %p
- - subgroup_docs_path = help_page_path('user/group/subgroups/index')
- - subgroup_docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: subgroup_docs_path }
- = s_('Groups can also be nested by creating %{subgroup_docs_link_start}subgroups%{subgroup_docs_link_end}.').html_safe % { subgroup_docs_link_start: subgroup_docs_link_start, subgroup_docs_link_end: '</a>'.html_safe }
- %p
- = _('Projects that belong to a group are prefixed with the group namespace. Existing projects may be moved into a group.')
+.group-edit-container.prepend-top-default
+ .row
+ .col-lg-3.group-settings-sidebar
+ %h4.prepend-top-0
+ = _('New group')
+ %p
+ - group_docs_path = help_page_path('user/group/index')
+ - group_docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: group_docs_path }
+ = s_('%{group_docs_link_start}Groups%{group_docs_link_end} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects.').html_safe % { group_docs_link_start: group_docs_link_start, group_docs_link_end: '</a>'.html_safe }
+ %p
+ - subgroup_docs_path = help_page_path('user/group/subgroups/index')
+ - subgroup_docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: subgroup_docs_path }
+ = s_('Groups can also be nested by creating %{subgroup_docs_link_start}subgroups%{subgroup_docs_link_end}.').html_safe % { subgroup_docs_link_start: subgroup_docs_link_start, subgroup_docs_link_end: '</a>'.html_safe }
+ %p
+ = _('Projects that belong to a group are prefixed with the group namespace. Existing projects may be moved into a group.')
- .col-lg-9
- = form_for @group, html: { class: 'group-form gl-show-field-errors' } do |f|
- = form_errors(@group)
- = render 'shared/group_form', f: f, autofocus: true
+ .col-lg-9.js-toggle-container
+ %ul.nav.nav-tabs.nav-links.gitlab-tabs{ role: 'tablist' }
+ %li.nav-item{ role: 'presentation' }
+ %a.nav-link.active{ href: '#create-group-pane', id: 'create-group-tab', role: 'tab', data: { toggle: 'tab', track_label: 'create_group', track_event: 'click_tab', track_value: '' } }
+ %span.d-none.d-sm-block= s_('GroupsNew|Create group')
+ %span.d-block.d-sm-none= s_('GroupsNew|Create')
+ %li.nav-item{ role: 'presentation' }
+ %a.nav-link{ href: '#import-group-pane', id: 'import-group-tab', role: 'tab', data: { toggle: 'tab', track_label: 'import_group', track_event: 'click_tab', track_value: '' } }
+ %span.d-none.d-sm-block= s_('GroupsNew|Import group')
+ %span.d-block.d-sm-none= s_('GroupsNew|Import')
- .row
- .form-group.group-description-holder.col-sm-12
- = f.label :avatar, _("Group avatar"), class: 'label-bold'
- %div
- = render 'shared/choose_avatar_button', f: f
+ .tab-content.gitlab-tab-content
+ .tab-pane.js-toggle-container{ id: 'create-group-pane', class: active_when(active_tab == 'create'), role: 'tabpanel' }
+ = form_for @group, html: { class: 'group-form gl-show-field-errors' } do |f|
+ = render 'new_group_fields', f: f, group_name_id: 'create-group-name'
- .form-group.col-sm-12
- %label.label-bold
- = _('Visibility level')
- %p
- = _('Who will be able to see this group?')
- = link_to _('View the documentation'), help_page_path("public_access/public_access"), target: '_blank'
- = render 'shared/visibility_level', f: f, visibility_level: default_group_visibility, can_change_visibility_level: true, form_model: @group, with_label: false
-
- = render 'create_chat_team', f: f if Gitlab.config.mattermost.enabled
-
- .form-actions
- = f.submit _('Create group'), class: "btn btn-success"
- = link_to _('Cancel'), dashboard_groups_path, class: 'btn btn-cancel'
+ .tab-pane.js-toggle-container{ id: 'import-group-pane', class: active_when(active_tab) == 'import', role: 'tabpanel' }
+ - if import_sources_enabled?
+ = render 'import_group_pane', active_tab: active_tab, autofocus: true
+ - else
+ .nothing-here-block
+ %h4= s_('GroupsNew|No import options available')
+ %p= s_('GroupsNew|Contact an administrator to enable options for importing your group.')
diff --git a/app/views/groups/registry/repositories/index.html.haml b/app/views/groups/registry/repositories/index.html.haml
index 41cb073686a..2cac8e653e5 100644
--- a/app/views/groups/registry/repositories/index.html.haml
+++ b/app/views/groups/registry/repositories/index.html.haml
@@ -12,6 +12,6 @@
"containers_error_image" => image_path('illustrations/docker-error-state.svg'),
"registry_host_url_with_port" => escape_once(registry_config.host_port),
"garbage_collection_help_page_path" => help_page_path('administration/packages/container_registry', anchor: 'container-registry-garbage-collection'),
- "is_admin": current_user&.admin,
- is_group_page: true,
+ "is_admin": current_user&.admin.to_s,
+ is_group_page: "true",
character_error: @character_error.to_s } }
diff --git a/app/views/groups/settings/_export.html.haml b/app/views/groups/settings/_export.html.haml
index ef7bf562c69..94466b76ac8 100644
--- a/app/views/groups/settings/_export.html.haml
+++ b/app/views/groups/settings/_export.html.haml
@@ -7,7 +7,7 @@
%p= _('Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the "New Group" page.')
.bs-callout.bs-callout-info
- %p.append-bottom-0
+ %p.gl-mb-0
%p= _('The following items will be exported:')
%ul
- group_export_descriptions.each do |description|
diff --git a/app/views/groups/settings/_general.html.haml b/app/views/groups/settings/_general.html.haml
index 73a0c8ff02b..742bf50fb89 100644
--- a/app/views/groups/settings/_general.html.haml
+++ b/app/views/groups/settings/_general.html.haml
@@ -12,7 +12,7 @@
= f.label :id, _('Group ID'), class: 'label-bold'
= f.text_field :id, class: 'form-control w-auto', readonly: true
- .row.prepend-top-8
+ .row.gl-mt-3
.form-group.col-md-9
= f.label :description, _('Group description (optional)'), class: 'label-bold'
= f.text_area :description, class: 'form-control', rows: 3, maxlength: 250
diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml
index 032766327ca..7e5bf6ddde1 100644
--- a/app/views/groups/show.html.haml
+++ b/app/views/groups/show.html.haml
@@ -1,10 +1,6 @@
- breadcrumb_title _("Details")
- @content_class = "limit-container-width" unless fluid_layout
-= content_for :flash_message do
- - if Feature.enabled?(:subscribable_banner_subscription)
- = render_if_exists "layouts/header/ee_subscribable_banner", subscription: true
-
= content_for :meta_tags do
= auto_discovery_link_tag(:atom, group_url(@group, rss_url_options), title: "#{@group.name} activity")
diff --git a/app/views/groups/sidebar/_packages.html.haml b/app/views/groups/sidebar/_packages.html.haml
index 67e759a4d63..59061a048b3 100644
--- a/app/views/groups/sidebar/_packages.html.haml
+++ b/app/views/groups/sidebar/_packages.html.haml
@@ -1,16 +1,16 @@
- if group_container_registry_nav?
- = nav_link(path: group_packages_nav_link_paths) do
+ = nav_link(controller: 'groups/registry/repositories') do
= link_to group_container_registries_path(@group), title: _('Container Registry') do
.nav-icon-container
= sprite_icon('package')
%span.nav-item-name
= _('Packages & Registries')
%ul.sidebar-sub-level-items
- = nav_link(controller: [:packages, :repositories], html_options: { class: "fly-out-top-item" } ) do
+ = nav_link(controller: 'groups/registry/repositories', html_options: { class: "fly-out-top-item" } ) do
= link_to group_container_registries_path(@group), title: _('Container Registry') do
%strong.fly-out-top-item-name
= _('Packages & Registries')
%li.divider.fly-out-top-item
- = nav_link(controller: 'groups/container_registries') do
+ = nav_link(controller: 'groups/registry/repositories') do
= link_to group_container_registries_path(@group), title: _('Container Registry') do
%span= _('Container Registry')
diff --git a/app/views/import/_githubish_status.html.haml b/app/views/import/_githubish_status.html.haml
index b05c039c85c..9bf1f0c61bb 100644
--- a/app/views/import/_githubish_status.html.haml
+++ b/app/views/import/_githubish_status.html.haml
@@ -1,4 +1,6 @@
- provider = local_assigns.fetch(:provider)
+- extra_data = local_assigns.fetch(:extra_data, {})
+- filterable = local_assigns.fetch(:filterable, true)
- provider_title = Gitlab::ImportSources.title(provider)
#import-projects-mount-element{ data: { provider: provider, provider_title: provider_title,
@@ -6,4 +8,5 @@
ci_cd_only: has_ci_cd_only_params?.to_s,
repos_path: url_for([:status, :import, provider, format: :json]),
jobs_path: url_for([:realtime_changes, :import, provider, format: :json]),
- import_path: url_for([:import, provider, format: :json]) } }
+ import_path: url_for([:import, provider, format: :json]),
+ filterable: filterable.to_s }.merge(extra_data) }
diff --git a/app/views/import/bitbucket/status.html.haml b/app/views/import/bitbucket/status.html.haml
index 7399ff937ce..d405acef75c 100644
--- a/app/views/import/bitbucket/status.html.haml
+++ b/app/views/import/bitbucket/status.html.haml
@@ -5,90 +5,93 @@
%i.fa.fa-bitbucket
= _('Import projects from Bitbucket')
-- if @repos.any?
- %p.light
- = _('Select projects you want to import.')
- %p
- - if @incompatible_repos.any?
- = button_tag class: 'btn btn-import btn-success js-import-all' do
- = _('Import all compatible projects')
- = icon('spinner spin', class: 'loading-icon')
- - else
- = button_tag class: 'btn btn-import btn-success js-import-all' do
- = _('Import all projects')
- = icon('spinner spin', class: 'loading-icon')
+- if Feature.enabled?(:new_import_ui)
+ = render 'import/githubish_status', provider: 'bitbucket'
+- else
+ - if @repos.any?
+ %p.light
+ = _('Select projects you want to import.')
+ %p
+ - if @incompatible_repos.any?
+ = button_tag class: 'btn btn-import btn-success js-import-all' do
+ = _('Import all compatible projects')
+ = icon('spinner spin', class: 'loading-icon')
+ - else
+ = button_tag class: 'btn btn-import btn-success js-import-all' do
+ = _('Import all projects')
+ = icon('spinner spin', class: 'loading-icon')
-.position-relative.ms-no-clear.d-flex.flex-fill.float-right.append-bottom-10
- = form_tag status_import_bitbucket_path, method: 'get' do
- = text_field_tag :filter, @filter, class: 'form-control pr-5', placeholder: _('Filter projects'), size: 40, autofocus: true, 'aria-label': _('Search')
- .position-absolute.position-top-0.d-flex.align-items-center.text-muted.position-right-0.h-100
- .border-left
- %button{ class: 'btn btn-transparent btn-secondary', 'aria-label': _('Search Button'), type: 'submit' }
- %i{ class: 'fa fa-search', 'aria-hidden': true }
+ .position-relative.ms-no-clear.d-flex.flex-fill.float-right.append-bottom-10
+ = form_tag status_import_bitbucket_path, method: 'get' do
+ = text_field_tag :filter, @filter, class: 'form-control pr-5', placeholder: _('Filter projects'), size: 40, autofocus: true, 'aria-label': _('Search')
+ .position-absolute.position-top-0.d-flex.align-items-center.text-muted.position-right-0.h-100
+ .border-left
+ %button{ class: 'btn btn-transparent btn-secondary', 'aria-label': _('Search Button'), type: 'submit' }
+ %i{ class: 'fa fa-search', 'aria-hidden': true }
-.table-responsive
- %table.table.import-jobs
- %colgroup.import-jobs-from-col
- %colgroup.import-jobs-to-col
- %colgroup.import-jobs-status-col
- %thead
- %tr
- %th= _('From Bitbucket')
- %th= _('To GitLab')
- %th= _('Status')
- %tbody
- - @already_added_projects.each do |project|
- %tr{ id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}" }
- %td
- = link_to project.import_source, "https://bitbucket.org/#{project.import_source}", target: '_blank', rel: 'noopener noreferrer'
- %td
- = link_to project.full_path, [project.namespace.becomes(Namespace), project]
- %td.job-status
- - case project.import_status
- - when 'finished'
- %span
- %i.fa.fa-check
- = _('done')
- - when 'started'
- %i.fa.fa-spinner.fa-spin
- = _('started')
- - else
- = project.human_import_status_name
+ .table-responsive
+ %table.table.import-jobs
+ %colgroup.import-jobs-from-col
+ %colgroup.import-jobs-to-col
+ %colgroup.import-jobs-status-col
+ %thead
+ %tr
+ %th= _('From Bitbucket')
+ %th= _('To GitLab')
+ %th= _('Status')
+ %tbody
+ - @already_added_projects.each do |project|
+ %tr{ id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}" }
+ %td
+ = link_to project.import_source, "https://bitbucket.org/#{project.import_source}", target: '_blank', rel: 'noopener noreferrer'
+ %td
+ = link_to project.full_path, [project.namespace.becomes(Namespace), project]
+ %td.job-status
+ - case project.import_status
+ - when 'finished'
+ %span
+ %i.fa.fa-check
+ = _('done')
+ - when 'started'
+ %i.fa.fa-spinner.fa-spin
+ = _('started')
+ - else
+ = project.human_import_status_name
- - @repos.each do |repo|
- %tr{ id: "repo_#{repo.owner}___#{repo.slug}" }
- %td
- = link_to repo.full_name, "https://bitbucket.org/#{repo.full_name}", target: '_blank', rel: 'noopener noreferrer'
- %td.import-target
- %fieldset.row
- .input-group
- .project-path.input-group-prepend
- - if current_user.can_select_namespace?
- - selected = params[:namespace_id] || :current_user
- - opts = current_user.can_create_group? ? { extra_group: Group.new(name: repo.owner, path: repo.owner) } : {}
- = select_tag :namespace_id, namespaces_options(selected, opts.merge({ display_path: true })), { class: 'select2 js-select-namespace', tabindex: 1 }
- - else
- = text_field_tag :path, current_user.namespace_path, class: "input-group-text input-large form-control", tabindex: 1, disabled: true
- %span.input-group-prepend
- .input-group-text /
- = text_field_tag :path, sanitize_project_name(repo.slug), class: "input-mini form-control", tabindex: 2, autofocus: true, required: true
- %td.import-actions.job-status
- = button_tag class: 'btn btn-import js-add-to-import' do
- = _('Import')
- = icon('spinner spin', class: 'loading-icon')
- - @incompatible_repos.each do |repo|
- %tr{ id: "repo_#{repo.owner}___#{repo.slug}" }
- %td
- = link_to repo.full_name, "https://bitbucket.org/#{repo.full_name}", target: '_blank', rel: 'noopener noreferrer'
- %td.import-target
- %td.import-actions-job-status
- = label_tag _('Incompatible Project'), nil, class: 'label badge-danger'
+ - @repos.each do |repo|
+ %tr{ id: "repo_#{repo.owner}___#{repo.slug}" }
+ %td
+ = link_to repo.full_name, "https://bitbucket.org/#{repo.full_name}", target: '_blank', rel: 'noopener noreferrer'
+ %td.import-target
+ %fieldset.row
+ .input-group
+ .project-path.input-group-prepend
+ - if current_user.can_select_namespace?
+ - selected = params[:namespace_id] || :current_user
+ - opts = current_user.can_create_group? ? { extra_group: Group.new(name: repo.owner, path: repo.owner) } : {}
+ = select_tag :namespace_id, namespaces_options(selected, opts.merge({ display_path: true })), { class: 'select2 js-select-namespace', tabindex: 1 }
+ - else
+ = text_field_tag :path, current_user.namespace_path, class: "input-group-text input-large form-control", tabindex: 1, disabled: true
+ %span.input-group-prepend
+ .input-group-text /
+ = text_field_tag :path, sanitize_project_name(repo.slug), class: "input-mini form-control", tabindex: 2, autofocus: true, required: true
+ %td.import-actions.job-status
+ = button_tag class: 'btn btn-import js-add-to-import' do
+ = _('Import')
+ = icon('spinner spin', class: 'loading-icon')
+ - @incompatible_repos.each do |repo|
+ %tr{ id: "repo_#{repo.owner}___#{repo.slug}" }
+ %td
+ = link_to repo.full_name, "https://bitbucket.org/#{repo.full_name}", target: '_blank', rel: 'noopener noreferrer'
+ %td.import-target
+ %td.import-actions-job-status
+ = label_tag _('Incompatible Project'), nil, class: 'label badge-danger'
-- if @incompatible_repos.any?
- %p
- = _("One or more of your Bitbucket projects cannot be imported into GitLab directly because they use Subversion or Mercurial for version control, rather than Git.")
- - link_to_git = link_to(_('Git'), 'https://www.atlassian.com/git/tutorials/migrating-overview')
- - link_to_import_flow = link_to(_('import flow'), status_import_bitbucket_path)
- = _("Please convert them to %{link_to_git}, and go through the %{link_to_import_flow} again.").html_safe % { link_to_git: link_to_git, link_to_import_flow: link_to_import_flow }
+ - if @incompatible_repos.any?
+ %p
+ = _("One or more of your Bitbucket projects cannot be imported into GitLab directly because they use Subversion or Mercurial for version control, rather than Git.")
+ - link_to_git = link_to(_('Git'), 'https://www.atlassian.com/git/tutorials/migrating-overview')
+ - link_to_import_flow = link_to(_('import flow'), status_import_bitbucket_path)
+ = _("Please convert them to %{link_to_git}, and go through the %{link_to_import_flow} again.").html_safe % { link_to_git: link_to_git, link_to_import_flow: link_to_import_flow }
-.js-importer-status{ data: { jobs_import_path: "#{jobs_import_bitbucket_path}", import_path: "#{import_bitbucket_path}" } }
+ .js-importer-status{ data: { jobs_import_path: "#{jobs_import_bitbucket_path}", import_path: "#{import_bitbucket_path}" } }
diff --git a/app/views/import/bitbucket_server/new.html.haml b/app/views/import/bitbucket_server/new.html.haml
index ac86be8fa7a..2eac8d0c5a1 100644
--- a/app/views/import/bitbucket_server/new.html.haml
+++ b/app/views/import/bitbucket_server/new.html.haml
@@ -13,14 +13,14 @@
.form-group.row
= label_tag :bitbucket_server_url, 'Bitbucket Server URL', class: 'col-form-label col-md-2'
.col-md-4
- = text_field_tag :bitbucket_server_url, '', class: 'form-control append-right-8', placeholder: _('https://your-bitbucket-server'), size: 40
+ = text_field_tag :bitbucket_server_url, '', class: 'form-control gl-mr-3', placeholder: _('https://your-bitbucket-server'), size: 40
.form-group.row
= label_tag :bitbucket_server_url, 'Username', class: 'col-form-label col-md-2'
.col-md-4
- = text_field_tag :bitbucket_username, '', class: 'form-control append-right-8', placeholder: _('username'), size: 40
+ = text_field_tag :bitbucket_username, '', class: 'form-control gl-mr-3', placeholder: _('username'), size: 40
.form-group.row
= label_tag :personal_access_token, 'Password/Personal Access Token', class: 'col-form-label col-md-2'
.col-md-4
- = password_field_tag :personal_access_token, '', class: 'form-control append-right-8', placeholder: _('Personal Access Token'), size: 40
+ = password_field_tag :personal_access_token, '', class: 'form-control gl-mr-3', placeholder: _('Personal Access Token'), size: 40
.form-actions
= submit_tag _('List your Bitbucket Server repositories'), class: 'btn btn-success'
diff --git a/app/views/import/bitbucket_server/status.html.haml b/app/views/import/bitbucket_server/status.html.haml
index 1aaf5883bf4..7523b8f7b1c 100644
--- a/app/views/import/bitbucket_server/status.html.haml
+++ b/app/views/import/bitbucket_server/status.html.haml
@@ -5,91 +5,94 @@
%i.fa.fa-bitbucket-square
= _('Import projects from Bitbucket Server')
-- if @repos.any?
- %p.light
- = _('Select projects you want to import.')
- .btn-group
- - if @incompatible_repos.any?
- = button_tag class: 'btn btn-import btn-success js-import-all' do
- = _('Import all compatible projects')
- = icon('spinner spin', class: 'loading-icon')
- - else
- = button_tag class: 'btn btn-import btn-success js-import-all' do
- = _('Import all projects')
- = icon('spinner spin', class: 'loading-icon')
+- if Feature.enabled?(:new_import_ui)
+ = render 'import/githubish_status', provider: 'bitbucket_server', extra_data: { reconfigure_path: configure_import_bitbucket_server_path }
+- else
+ - if @repos.any?
+ %p.light
+ = _('Select projects you want to import.')
+ .btn-group
+ - if @incompatible_repos.any?
+ = button_tag class: 'btn btn-import btn-success js-import-all' do
+ = _('Import all compatible projects')
+ = icon('spinner spin', class: 'loading-icon')
+ - else
+ = button_tag class: 'btn btn-import btn-success js-import-all' do
+ = _('Import all projects')
+ = icon('spinner spin', class: 'loading-icon')
-.btn-group
- = link_to('Reconfigure', configure_import_bitbucket_server_path, class: 'btn btn-primary', method: :post)
+ .btn-group
+ = link_to('Reconfigure', configure_import_bitbucket_server_path, class: 'btn btn-primary', method: :post)
-.input-btn-group.float-right
- = form_tag status_import_bitbucket_server_path, :method => 'get' do
- = text_field_tag :filter, sanitize(params[:filter]), class: 'form-control append-bottom-10', placeholder: _('Filter your projects by name'), size: 40, autoFocus: true
+ .input-btn-group.float-right
+ = form_tag status_import_bitbucket_server_path, :method => 'get' do
+ = text_field_tag :filter, sanitize(params[:filter]), class: 'form-control append-bottom-10', placeholder: _('Filter your projects by name'), size: 40, autoFocus: true
-.table-responsive.prepend-top-10
- %table.table.import-jobs
- %colgroup.import-jobs-from-col
- %colgroup.import-jobs-to-col
- %colgroup.import-jobs-status-col
- %thead
- %tr
- %th= _('From Bitbucket Server')
- %th= _('To GitLab')
- %th= _('Status')
- %tbody
- - @already_added_projects.each do |project|
- %tr{ id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}" }
- %td
- = link_to project.import_source, project.import_source, target: '_blank', rel: 'noopener noreferrer'
- %td
- = link_to project.full_path, [project.namespace.becomes(Namespace), project]
- %td.job-status
- - case project.import_status
- - when 'finished'
- = icon('check', text: 'Done')
- - when 'started'
- = icon('spin', text: 'started')
- - else
- = project.human_import_status_name
+ .table-responsive.prepend-top-10
+ %table.table.import-jobs
+ %colgroup.import-jobs-from-col
+ %colgroup.import-jobs-to-col
+ %colgroup.import-jobs-status-col
+ %thead
+ %tr
+ %th= _('From Bitbucket Server')
+ %th= _('To GitLab')
+ %th= _('Status')
+ %tbody
+ - @already_added_projects.each do |project|
+ %tr{ id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}" }
+ %td
+ = link_to project.import_source, project.import_source, target: '_blank', rel: 'noopener noreferrer'
+ %td
+ = link_to project.full_path, [project.namespace.becomes(Namespace), project]
+ %td.job-status
+ - case project.import_status
+ - when 'finished'
+ = icon('check', text: 'Done')
+ - when 'started'
+ = icon('spin', text: 'started')
+ - else
+ = project.human_import_status_name
- - @repos.each do |repo|
- %tr{ id: "repo_#{repo.project_key}___#{repo.slug}", data: { project: repo.project_key, repository: repo.slug } }
- %td
- = link_to repo.browse_url, repo.browse_url, target: '_blank', rel: 'noopener noreferrer'
- %td.import-target
- %fieldset.row
- .input-group
- .project-path.input-group-prepend
- - if current_user.can_select_namespace?
- - selected = params[:namespace_id] || :extra_group
- - opts = current_user.can_create_group? ? { extra_group: Group.new(name: sanitize_project_name(repo.project_key), path: sanitize_project_name(repo.project_key)) } : {}
- = select_tag :namespace_id, namespaces_options(selected, opts.merge({ display_path: true })), { class: 'select2 js-select-namespace', tabindex: 1 }
- - else
- = text_field_tag :path, current_user.namespace_path, class: "input-group-text input-large form-control", tabindex: 1, disabled: true
- %span.input-group-prepend
- .input-group-text /
- = text_field_tag :path, sanitize_project_name(repo.slug), class: "input-mini form-control", tabindex: 2, required: true
- %td.import-actions.job-status
- = button_tag class: 'btn btn-import js-add-to-import' do
- Import
- = icon('spinner spin', class: 'loading-icon')
- - @incompatible_repos.each do |repo|
- %tr{ id: "repo_#{repo.project_key}___#{repo.slug}" }
- %td
- = link_to repo.browse_url, repo.browse_url, target: '_blank', rel: 'noopener noreferrer'
- %td.import-target
- %td.import-actions-job-status
- = label_tag 'Incompatible Project', nil, class: 'label badge-danger'
+ - @repos.each do |repo|
+ %tr{ id: "repo_#{repo.project_key}___#{repo.slug}", data: { project: repo.project_key, repository: repo.slug } }
+ %td
+ = link_to repo.browse_url, repo.browse_url, target: '_blank', rel: 'noopener noreferrer'
+ %td.import-target
+ %fieldset.row
+ .input-group
+ .project-path.input-group-prepend
+ - if current_user.can_select_namespace?
+ - selected = params[:namespace_id] || :extra_group
+ - opts = current_user.can_create_group? ? { extra_group: Group.new(name: sanitize_project_name(repo.project_key), path: sanitize_project_name(repo.project_key)) } : {}
+ = select_tag :namespace_id, namespaces_options(selected, opts.merge({ display_path: true })), { class: 'select2 js-select-namespace', tabindex: 1 }
+ - else
+ = text_field_tag :path, current_user.namespace_path, class: "input-group-text input-large form-control", tabindex: 1, disabled: true
+ %span.input-group-prepend
+ .input-group-text /
+ = text_field_tag :path, sanitize_project_name(repo.slug), class: "input-mini form-control", tabindex: 2, required: true
+ %td.import-actions.job-status
+ = button_tag class: 'btn btn-import js-add-to-import' do
+ Import
+ = icon('spinner spin', class: 'loading-icon')
+ - @incompatible_repos.each do |repo|
+ %tr{ id: "repo_#{repo.project_key}___#{repo.slug}" }
+ %td
+ = link_to repo.browse_url, repo.browse_url, target: '_blank', rel: 'noopener noreferrer'
+ %td.import-target
+ %td.import-actions-job-status
+ = label_tag 'Incompatible Project', nil, class: 'label badge-danger'
-- if @incompatible_repos.any?
- %p
- One or more of your Bitbucket Server projects cannot be imported into GitLab
- directly because they use Subversion or Mercurial for version control,
- rather than Git. Please convert
- = link_to 'them to Git,', 'https://www.atlassian.com/git/tutorials/migrating-overview'
- and go through the
- = link_to 'import flow', status_import_bitbucket_server_path
- again.
+ - if @incompatible_repos.any?
+ %p
+ One or more of your Bitbucket Server projects cannot be imported into GitLab
+ directly because they use Subversion or Mercurial for version control,
+ rather than Git. Please convert
+ = link_to 'them to Git,', 'https://www.atlassian.com/git/tutorials/migrating-overview'
+ and go through the
+ = link_to 'import flow', status_import_bitbucket_server_path
+ again.
-= paginate_without_count(@collection)
+ = paginate_without_count(@collection)
-.js-importer-status{ data: { jobs_import_path: "#{jobs_import_bitbucket_server_path}", import_path: "#{import_bitbucket_server_path}" } }
+ .js-importer-status{ data: { jobs_import_path: "#{jobs_import_bitbucket_server_path}", import_path: "#{import_bitbucket_server_path}" } }
diff --git a/app/views/import/fogbugz/status.html.haml b/app/views/import/fogbugz/status.html.haml
index eca67582d6f..75529487aa4 100644
--- a/app/views/import/fogbugz/status.html.haml
+++ b/app/views/import/fogbugz/status.html.haml
@@ -4,56 +4,63 @@
%i.fa.fa-bug
= _('Import projects from FogBugz')
-- if @repos.any?
- %p.light
- = _('Select projects you want to import.')
+- if Feature.enabled?(:new_import_ui)
%p.light
- link_to_customize = link_to('customize', new_user_map_import_fogbugz_path)
= _('Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab.').html_safe % { link_to_customize: link_to_customize }
%hr
- %p
- = button_tag class: 'btn btn-import btn-success js-import-all' do
- = _('Import all projects')
- = icon("spinner spin", class: "loading-icon")
+ = render 'import/githubish_status', provider: 'fogbugz', filterable: false
+- else
+ - if @repos.any?
+ %p.light
+ = _('Select projects you want to import.')
+ %p.light
+ - link_to_customize = link_to('customize', new_user_map_import_fogbugz_path)
+ = _('Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab.').html_safe % { link_to_customize: link_to_customize }
+ %hr
+ %p
+ = button_tag class: 'btn btn-import btn-success js-import-all' do
+ = _('Import all projects')
+ = icon("spinner spin", class: "loading-icon")
-.table-responsive
- %table.table.import-jobs
- %colgroup.import-jobs-from-col
- %colgroup.import-jobs-to-col
- %colgroup.import-jobs-status-col
- %thead
- %tr
- %th= _("From FogBugz")
- %th= _("To GitLab")
- %th= _("Status")
- %tbody
- - @already_added_projects.each do |project|
- %tr{ id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}" }
- %td
- = project.import_source
- %td
- = link_to project.full_path, [project.namespace.becomes(Namespace), project]
- %td.job-status
- - case project.import_status
- - when 'finished'
- %span
- %i.fa.fa-check
- = _("done")
- - when 'started'
- %i.fa.fa-spinner.fa-spin
- = _("started")
- - else
- = project.human_import_status_name
+ .table-responsive
+ %table.table.import-jobs
+ %colgroup.import-jobs-from-col
+ %colgroup.import-jobs-to-col
+ %colgroup.import-jobs-status-col
+ %thead
+ %tr
+ %th= _("From FogBugz")
+ %th= _("To GitLab")
+ %th= _("Status")
+ %tbody
+ - @already_added_projects.each do |project|
+ %tr{ id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}" }
+ %td
+ = project.import_source
+ %td
+ = link_to project.full_path, [project.namespace.becomes(Namespace), project]
+ %td.job-status
+ - case project.import_status
+ - when 'finished'
+ %span
+ %i.fa.fa-check
+ = _("done")
+ - when 'started'
+ %i.fa.fa-spinner.fa-spin
+ = _("started")
+ - else
+ = project.human_import_status_name
- - @repos.each do |repo|
- %tr{ id: "repo_#{repo.id}" }
- %td
- = repo.name
- %td.import-target
- #{current_user.username}/#{repo.name}
- %td.import-actions.job-status
- = button_tag class: "btn btn-import js-add-to-import" do
- = _("Import")
- = icon("spinner spin", class: "loading-icon")
+ - @repos.each do |repo|
+ %tr{ id: "repo_#{repo.id}" }
+ %td
+ = repo.name
+ %td.import-target
+ #{current_user.username}/#{repo.name}
+ %td.import-actions.job-status
+ = button_tag class: "btn btn-import js-add-to-import" do
+ = _("Import")
+ = icon("spinner spin", class: "loading-icon")
-.js-importer-status{ data: { jobs_import_path: "#{jobs_import_fogbugz_path}", import_path: "#{import_fogbugz_path}" } }
+ .js-importer-status{ data: { jobs_import_path: "#{jobs_import_fogbugz_path}", import_path: "#{import_fogbugz_path}" } }
diff --git a/app/views/import/gitlab/status.html.haml b/app/views/import/gitlab/status.html.haml
index a5fa12fe7df..a12b69ae5f9 100644
--- a/app/views/import/gitlab/status.html.haml
+++ b/app/views/import/gitlab/status.html.haml
@@ -4,52 +4,55 @@
%i.fa.fa-heart
= _('Import projects from GitLab.com')
-%p.light
- = _('Select projects you want to import.')
-%hr
-%p
- = button_tag class: "btn btn-import btn-success js-import-all" do
- = _('Import all projects')
- = icon("spinner spin", class: "loading-icon")
+- if Feature.enabled?(:new_import_ui)
+ = render 'import/githubish_status', provider: 'gitlab', filterable: false
+- else
+ %p.light
+ = _('Select projects you want to import.')
+ %hr
+ %p
+ = button_tag class: "btn btn-import btn-success js-import-all" do
+ = _('Import all projects')
+ = icon("spinner spin", class: "loading-icon")
-.table-responsive
- %table.table.import-jobs
- %colgroup.import-jobs-from-col
- %colgroup.import-jobs-to-col
- %colgroup.import-jobs-status-col
- %thead
- %tr
- %th= _('From GitLab.com')
- %th= _('To this GitLab instance')
- %th= _('Status')
- %tbody
- - @already_added_projects.each do |project|
- %tr{ id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}" }
- %td
- = link_to project.import_source, "https://gitlab.com/#{project.import_source}", target: "_blank"
- %td
- = link_to project.full_path, [project.namespace.becomes(Namespace), project]
- %td.job-status
- - case project.import_status
- - when 'finished'
- %span
- %i.fa.fa-check
- = _('done')
- - when 'started'
- %i.fa.fa-spinner.fa-spin
- = _('started')
- - else
- = project.human_import_status_name
+ .table-responsive
+ %table.table.import-jobs
+ %colgroup.import-jobs-from-col
+ %colgroup.import-jobs-to-col
+ %colgroup.import-jobs-status-col
+ %thead
+ %tr
+ %th= _('From GitLab.com')
+ %th= _('To this GitLab instance')
+ %th= _('Status')
+ %tbody
+ - @already_added_projects.each do |project|
+ %tr{ id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}" }
+ %td
+ = link_to project.import_source, "https://gitlab.com/#{project.import_source}", target: "_blank"
+ %td
+ = link_to project.full_path, [project.namespace.becomes(Namespace), project]
+ %td.job-status
+ - case project.import_status
+ - when 'finished'
+ %span
+ %i.fa.fa-check
+ = _('done')
+ - when 'started'
+ %i.fa.fa-spinner.fa-spin
+ = _('started')
+ - else
+ = project.human_import_status_name
- - @repos.each do |repo|
- %tr{ id: "repo_#{repo["id"]}" }
- %td
- = link_to repo["path_with_namespace"], "https://gitlab.com/#{repo["path_with_namespace"]}", target: "_blank", rel: 'noopener noreferrer'
- %td.import-target
- = import_project_target(repo['namespace']['path'], repo['name'])
- %td.import-actions.job-status
- = button_tag class: "btn btn-import js-add-to-import" do
- = _('Import')
- = icon("spinner spin", class: "loading-icon")
+ - @repos.each do |repo|
+ %tr{ id: "repo_#{repo["id"]}" }
+ %td
+ = link_to repo["path_with_namespace"], "https://gitlab.com/#{repo["path_with_namespace"]}", target: "_blank", rel: 'noopener noreferrer'
+ %td.import-target
+ = import_project_target(repo['namespace']['path'], repo['name'])
+ %td.import-actions.job-status
+ = button_tag class: "btn btn-import js-add-to-import" do
+ = _('Import')
+ = icon("spinner spin", class: "loading-icon")
-.js-importer-status{ data: { jobs_import_path: "#{jobs_import_gitlab_path}", import_path: "#{import_gitlab_path}" } }
+ .js-importer-status{ data: { jobs_import_path: "#{jobs_import_gitlab_path}", import_path: "#{import_gitlab_path}" } }
diff --git a/app/views/import/phabricator/new.html.haml b/app/views/import/phabricator/new.html.haml
index 811e126579e..3dfc7c37d98 100644
--- a/app/views/import/phabricator/new.html.haml
+++ b/app/views/import/phabricator/new.html.haml
@@ -11,15 +11,15 @@
= form_tag import_phabricator_path, class: 'new_project', method: :post do
= render 'import/shared/new_project_form'
- %h4.prepend-top-0= _('Enter in your Phabricator Server URL and personal access token below')
+ %h4.gl-mt-0= _('Enter in your Phabricator Server URL and personal access token below')
.form-group.row
= label_tag :phabricator_server_url, _('Phabricator Server URL'), class: 'col-form-label col-md-2'
.col-md-4
- = text_field_tag :phabricator_server_url, params[:phabricator_server_url], class: 'form-control append-right-8', placeholder: 'https://your-phabricator-server', size: 40
+ = text_field_tag :phabricator_server_url, params[:phabricator_server_url], class: 'form-control gl-mr-3', placeholder: 'https://your-phabricator-server', size: 40
.form-group.row
= label_tag :api_token, _('API Token'), class: 'col-form-label col-md-2'
.col-md-4
- = password_field_tag :api_token, params[:api_token], class: 'form-control append-right-8', placeholder: _('Personal Access Token'), size: 40
+ = password_field_tag :api_token, params[:api_token], class: 'form-control gl-mr-3', placeholder: _('Personal Access Token'), size: 40
.form-actions
= submit_tag _('Import tasks'), class: 'btn btn-success'
diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml
index 99c4fc0d1b6..886d4109ff5 100644
--- a/app/views/layouts/_head.html.haml
+++ b/app/views/layouts/_head.html.haml
@@ -18,7 +18,10 @@
- if ActionController::Base.asset_host
%link{ rel: 'dns-prefetch', href: ActionController::Base.asset_host }
- %link{ rel: 'preconnnect', href: ActionController::Base.asset_host, crossorigin: '' }
+ %link{ rel: 'preconnect', href: ActionController::Base.asset_host, crossorigin: '' }
+
+ - if Gitlab::CurrentSettings.snowplow_enabled? && Gitlab::CurrentSettings.snowplow_collector_hostname
+ %link{ rel: 'preconnect', href: Gitlab::CurrentSettings.snowplow_collector_hostname, crossorigin: '' }
%meta{ 'http-equiv' => 'X-UA-Compatible', content: 'IE=edge' }
@@ -44,7 +47,10 @@
= favicon_link_tag favicon, id: 'favicon', data: { original_href: favicon }, type: 'image/png'
- = stylesheet_link_tag "application", media: "all"
+ - if user_application_theme == 'gl-dark'
+ = stylesheet_link_tag "application_dark", media: "all"
+ - else
+ = stylesheet_link_tag "application", media: "all"
= stylesheet_link_tag "print", media: "print"
= stylesheet_link_tag "disable_animations", media: "all" if Rails.env.test? || Gitlab.config.gitlab['disable_animations']
= stylesheet_link_tag 'performance_bar' if performance_bar_enabled?
diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml
index 3885fa311ba..d1cf83b2a9f 100644
--- a/app/views/layouts/_page.html.haml
+++ b/app/views/layouts/_page.html.haml
@@ -6,14 +6,14 @@
.alert-wrapper
= render 'shared/outdated_browser'
= render_if_exists 'layouts/header/users_over_license_banner'
- - if Feature.enabled?(:subscribable_banner_license, default_enabled: true)
- = render_if_exists "layouts/header/ee_subscribable_banner"
+ = render_if_exists "layouts/header/licensed_user_count_threshold"
= render "layouts/broadcast"
= render "layouts/header/read_only_banner"
= render "layouts/nav/classification_level_banner"
= yield :flash_message
= render "shared/ping_consent"
= render_account_recovery_regular_check
+ = render_if_exists "layouts/header/ee_subscribable_banner"
- unless @hide_breadcrumbs
= render "layouts/nav/breadcrumbs"
.d-flex
diff --git a/app/views/layouts/_search.html.haml b/app/views/layouts/_search.html.haml
index ba5cd0fdd41..97d00bce11b 100644
--- a/app/views/layouts/_search.html.haml
+++ b/app/views/layouts/_search.html.haml
@@ -1,12 +1,8 @@
-- if @group && @group.persisted? && @group.path
- - group_data_attrs = { group_path: j(@group.path), name: j(@group.name), issues_path: issues_group_path(@group), mr_path: merge_requests_group_path(@group) }
-- if @project && @project.persisted?
- - project_data_attrs = { project_path: j(@project.path), name: j(@project.name), issues_path: project_issues_path(@project), mr_path: project_merge_requests_path(@project), issues_disabled: !@project.issues_enabled? }
.search.search-form{ data: { track_label: "navbar_search", track_event: "activate_form_input", track_value: "" } }
= form_tag search_path, method: :get, class: 'form-inline' do |f|
.search-input-container
.search-input-wrap
- .dropdown{ data: { url: search_autocomplete_path } }
+ .dropdown
= search_field_tag 'search', nil, placeholder: _('Search or jump to…'),
class: 'search-input dropdown-menu-toggle no-outline js-search-dashboard-options',
spellcheck: false,
@@ -27,27 +23,17 @@
= sprite_icon('search', size: 16, css_class: 'search-icon')
= sprite_icon('close', size: 16, css_class: 'clear-icon js-clear-input')
- = hidden_field_tag :group_id, @group.try(:id), class: 'js-search-group-options', data: group_data_attrs
+ = hidden_field_tag :group_id, search_context.for_group? ? search_context.group.id : '', class: 'js-search-group-options', data: search_context.group_metadata
+ = hidden_field_tag :project_id, search_context.for_project? ? search_context.project.id : '', id: 'search_project_id', class: 'js-search-project-options', data: search_context.project_metadata
- = hidden_field_tag :project_id, @project && @project.persisted? ? @project.id : '', id: 'search_project_id', class: 'js-search-project-options', data: project_data_attrs
+ - if search_context.for_project?
+ = hidden_field_tag :scope, search_context.scope
+ = hidden_field_tag :search_code, search_context.code_search?
- - if @project && @project.persisted?
- - if current_controller?(:issues)
- = hidden_field_tag :scope, 'issues'
- - elsif current_controller?(:merge_requests)
- = hidden_field_tag :scope, 'merge_requests'
- - elsif current_controller?(:wikis)
- = hidden_field_tag :scope, 'wiki_blobs'
- - elsif current_controller?(:commits)
- = hidden_field_tag :scope, 'commits'
- - else
- = hidden_field_tag :search_code, true
-
- - if @snippet || @snippets
- = hidden_field_tag :snippets, true
- = hidden_field_tag :repository_ref, @ref
+ = hidden_field_tag :snippets, search_context.for_snippets?
+ = hidden_field_tag :repository_ref, search_context.ref
= hidden_field_tag :nav_source, 'navbar'
+
-# workaround for non-JS feature specs, see spec/support/helpers/search_helpers.rb
- if ENV['RAILS_ENV'] == 'test'
%noscript= button_tag 'Search'
- .search-autocomplete-opts.hide{ :'data-autocomplete-path' => search_autocomplete_path, :'data-autocomplete-project-id' => @project.try(:id), :'data-autocomplete-project-ref' => @ref }
diff --git a/app/views/layouts/group.html.haml b/app/views/layouts/group.html.haml
index 49de821f1c2..36b664e5888 100644
--- a/app/views/layouts/group.html.haml
+++ b/app/views/layouts/group.html.haml
@@ -2,6 +2,7 @@
- page_description @group.description unless page_description
- header_title group_title(@group) unless header_title
- nav "group"
+- display_subscription_banner!
- @left_sidebar = true
- content_for :page_specific_javascripts do
diff --git a/app/views/layouts/header/_current_user_dropdown.html.haml b/app/views/layouts/header/_current_user_dropdown.html.haml
index 7d9924719a2..d568086f4a4 100644
--- a/app/views/layouts/header/_current_user_dropdown.html.haml
+++ b/app/views/layouts/header/_current_user_dropdown.html.haml
@@ -6,7 +6,7 @@
= current_user.name
= current_user.to_reference
- if current_user.status
- .user-status.d-flex.align-items-center.prepend-top-2.has-tooltip{ title: current_user.status.message_html, data: { html: 'true', placement: 'bottom' } }
+ .user-status.d-flex.align-items-center.gl-mt-2.has-tooltip{ title: current_user.status.message_html, data: { html: 'true', placement: 'bottom' } }
%span.user-status-emoji.d-flex.align-items-center
= emoji_icon current_user.status.emoji
%span.user-status-message.str-truncated
@@ -26,7 +26,7 @@
- if current_user_menu?(:settings)
%li
= link_to s_("CurrentUser|Settings"), profile_path, data: { qa_selector: 'settings_link' }
- = render_if_exists 'layouts/header/buy_ci_minutes', project: @project, namespace: @group
+ = render_if_exists 'layouts/header/buy_pipeline_minutes', project: @project, namespace: @group
= render_if_exists 'layouts/header/upgrade'
- if current_user_menu?(:help)
diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml
index f6255dac7cf..b4e25956f16 100644
--- a/app/views/layouts/header/_default.html.haml
+++ b/app/views/layouts/header/_default.html.haml
@@ -1,9 +1,3 @@
-- if project
- - search_path_url = search_path(project_id: project.id)
-- elsif group
- - search_path_url = search_path(group_id: group.id)
-- else
- - search_path_url = search_path
- has_impersonation_link = header_link?(:admin_impersonation)
%header.navbar.navbar-gitlab.navbar-expand-sm.js-navbar{ data: { qa_selector: 'navbar' } }
@@ -12,11 +6,12 @@
.header-content
.title-container
%h1.title
+ %span.gl-sr-only GitLab
= link_to root_path, title: _('Dashboard'), id: 'logo' do
= brand_header_logo
- logo_text = brand_header_logo_type
- if logo_text.present?
- %span.logo-text.d-none.d-lg-block.prepend-left-8
+ %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: 'label-link canary-badge bg-transparent', target: :_blank do
@@ -36,7 +31,7 @@
%li.nav-item.d-none.d-lg-block.m-auto
= render 'layouts/search' unless current_controller?(:search)
%li.nav-item.d-inline-block.d-lg-none
- = link_to search_path_url, title: _('Search'), aria: { label: _('Search') }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
+ = link_to search_context.search_url, title: _('Search'), aria: { label: _('Search') }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= sprite_icon('search', size: 16)
- if header_link?(:issues)
= nav_link(path: 'dashboard#issues', html_options: { class: "user-counter" }) do
@@ -60,6 +55,8 @@
= todos_count_format(todos_pending_count)
%li.nav-item.header-help.dropdown.d-none.d-md-block
= link_to help_path, class: 'header-help-dropdown-toggle', data: { toggle: "dropdown" } do
+ %span.gl-sr-only
+ = s_('Nav|Help')
= sprite_icon('question', size: 16)
= sprite_icon('angle-down', css_class: 'caret-down')
.dropdown-menu.dropdown-menu-right
@@ -67,7 +64,7 @@
- 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) }
= 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"
+ = 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
= sprite_icon('angle-down', css_class: 'caret-down')
.dropdown-menu.dropdown-menu-right
diff --git a/app/views/layouts/header/_logo_with_title.html.haml b/app/views/layouts/header/_logo_with_title.html.haml
index 1ea6168fc9a..9b5a47306d2 100644
--- a/app/views/layouts/header/_logo_with_title.html.haml
+++ b/app/views/layouts/header/_logo_with_title.html.haml
@@ -1,4 +1,4 @@
%header.navbar.fixed-top.navbar-gitlab.justify-content-center
= render 'shared/logo.svg'
- %span.logo-text.d-none.d-lg-block.prepend-left-8.pt-1
+ %span.logo-text.d-none.d-lg-block.gl-ml-3.pt-1
= render 'shared/logo_type.svg'
diff --git a/app/views/layouts/nav/breadcrumbs/_collapsed_dropdown.html.haml b/app/views/layouts/nav/breadcrumbs/_collapsed_dropdown.html.haml
index ad0d51d28f9..8ea75087fed 100644
--- a/app/views/layouts/nav/breadcrumbs/_collapsed_dropdown.html.haml
+++ b/app/views/layouts/nav/breadcrumbs/_collapsed_dropdown.html.haml
@@ -3,7 +3,7 @@
- if defined?(@breadcrumb_dropdown_links) && @breadcrumb_dropdown_links.key?(dropdown_location)
%li.dropdown
%button.text-expander.has-tooltip.js-breadcrumbs-collapsed-expander{ type: "button", data: { toggle: "dropdown", container: "body" }, "aria-label": button_tooltip, title: button_tooltip }
- = icon("ellipsis-h")
+ = sprite_icon("ellipsis_h", size: 12)
= sprite_icon("angle-right", size: 8, css_class: "breadcrumbs-list-angle")
.dropdown-menu
%ul
diff --git a/app/views/layouts/nav/sidebar/_group.html.haml b/app/views/layouts/nav/sidebar/_group.html.haml
index 92b6174795b..cd9765289a4 100644
--- a/app/views/layouts/nav/sidebar/_group.html.haml
+++ b/app/views/layouts/nav/sidebar/_group.html.haml
@@ -55,7 +55,7 @@
%span.badge.badge-pill.count= number_with_delimiter(issues_count)
%ul.sidebar-sub-level-items{ data: { qa_selector: 'group_issues_sidebar_submenu'} }
- = nav_link(path: ['groups#issues', 'labels#index', 'milestones#index'], html_options: { class: "fly-out-top-item" } ) do
+ = nav_link(path: ['groups#issues', 'labels#index', 'milestones#index', 'iterations#index'], html_options: { class: "fly-out-top-item" } ) do
= link_to issues_group_path(@group) do
%strong.fly-out-top-item-name
= _('Issues')
@@ -85,6 +85,8 @@
%span
= _('Milestones')
+ = render_if_exists 'layouts/nav/sidebar/iterations_link'
+
- if group_sidebar_link?(:merge_requests)
= nav_link(path: 'groups#merge_requests') do
= link_to merge_requests_group_path(@group) do
diff --git a/app/views/layouts/nav/sidebar/_project.html.haml b/app/views/layouts/nav/sidebar/_project.html.haml
index a67860e8e2e..16902ebe1d4 100644
--- a/app/views/layouts/nav/sidebar/_project.html.haml
+++ b/app/views/layouts/nav/sidebar/_project.html.haml
@@ -216,7 +216,7 @@
= _('Operations')
%li.divider.fly-out-top-item
- - if project_nav_tab? :environments
+ - if project_nav_tab? :metrics_dashboards
= nav_link(controller: :environments, action: [:metrics, :metrics_redirect]) do
= link_to metrics_project_environments_path(@project), title: _('Metrics'), class: 'shortcuts-metrics', data: { qa_selector: 'operations_metrics_link' } do
%span
@@ -290,7 +290,7 @@
= render 'layouts/nav/sidebar/analytics_links', links: project_analytics_navbar_links(@project, current_user)
- if project_nav_tab? :wiki
- - wiki_url = project_wiki_path(@project, :home)
+ - wiki_url = wiki_path(@project.wiki)
= nav_link(controller: :wikis) do
= link_to wiki_url, class: 'shortcuts-wiki', data: { qa_selector: 'wiki_link' } do
.nav-icon-container
@@ -319,7 +319,7 @@
- if project_nav_tab? :snippets
= nav_link(controller: :snippets) do
- = link_to project_snippets_path(@project), class: 'shortcuts-snippets' do
+ = link_to project_snippets_path(@project), class: 'shortcuts-snippets', data: { qa_selector: 'snippets_link' } do
.nav-icon-container
= sprite_icon('snippet')
%span.nav-item-name
@@ -330,6 +330,18 @@
%strong.fly-out-top-item-name
= _('Snippets')
+ = nav_link(controller: :project_members) do
+ = link_to project_project_members_path(@project), title: _('Members'), class: 'qa-members-link', id: 'js-onboarding-members-link' do
+ .nav-icon-container
+ = sprite_icon('users')
+ %span.nav-item-name
+ = _('Members')
+ %ul.sidebar-sub-level-items.is-fly-out-only
+ = nav_link(path: %w[members#show], html_options: { class: "fly-out-top-item" } ) do
+ = link_to project_project_members_path(@project) do
+ %strong.fly-out-top-item-name
+ = _('Members')
+
- if project_nav_tab? :settings
= nav_link(path: sidebar_settings_paths) do
= link_to edit_project_path(@project), class: 'shortcuts-tree' do
@@ -350,10 +362,6 @@
= link_to edit_project_path(@project), title: _('General'), class: 'qa-general-settings-link' do
%span
= _('General')
- = nav_link(controller: :project_members) do
- = link_to project_project_members_path(@project), title: _('Members'), class: 'qa-link-members-settings', id: 'js-onboarding-settings-members-link' do
- %span
- = _('Members')
- if can_edit
= nav_link(controller: [:integrations, :services]) do
= link_to project_settings_integrations_path(@project), title: _('Integrations'), data: { qa_selector: 'integrations_settings_link' } do
@@ -389,19 +397,6 @@
= render_if_exists 'projects/sidebar/settings_audit_events'
- - else
- = nav_link(controller: :project_members) do
- = link_to project_settings_members_path(@project), title: _('Members'), class: 'shortcuts-tree' do
- .nav-icon-container
- = sprite_icon('users')
- %span.nav-item-name
- = _('Members')
- %ul.sidebar-sub-level-items.is-fly-out-only
- = nav_link(path: %w[members#show], html_options: { class: "fly-out-top-item" } ) do
- = link_to project_project_members_path(@project) do
- %strong.fly-out-top-item-name
- = _('Members')
-
= render 'shared/sidebar_toggle_button'
-# Shortcut to Project > Activity
diff --git a/app/views/layouts/project.html.haml b/app/views/layouts/project.html.haml
index b8ef38272fc..820cb9eea47 100644
--- a/app/views/layouts/project.html.haml
+++ b/app/views/layouts/project.html.haml
@@ -2,7 +2,8 @@
- page_description @project.description unless page_description
- header_title project_title(@project) unless header_title
- nav "project"
-- @left_sidebar = true
+- display_subscription_banner!
+- @left_sidebar = true
- content_for :project_javascripts do
- project = @target_project || @project
diff --git a/app/views/layouts/terms.html.haml b/app/views/layouts/terms.html.haml
index 1f7cf486b2c..e39cb5ee0a2 100644
--- a/app/views/layouts/terms.html.haml
+++ b/app/views/layouts/terms.html.haml
@@ -5,7 +5,7 @@
%body{ data: { page: body_data_page } }
.layout-page.terms{ class: page_class }
- .content-wrapper.prepend-top-0
+ .content-wrapper.gl-mt-0
.mobile-overlay
.alert-wrapper
= render "layouts/broadcast"
@@ -19,7 +19,7 @@
= brand_header_logo
- logo_text = brand_header_logo_type
- if logo_text.present?
- %span.logo-text.prepend-left-8
+ %span.logo-text.gl-ml-3
= logo_text
- if header_link?(:user_dropdown)
.navbar-collapse
diff --git a/app/views/notify/merged_merge_request_email.html.haml b/app/views/notify/merged_merge_request_email.html.haml
index 0fe54e73313..341aa6f8103 100644
--- a/app/views/notify/merged_merge_request_email.html.haml
+++ b/app/views/notify/merged_merge_request_email.html.haml
@@ -1,2 +1,2 @@
%p
- Merge Request #{@merge_request.to_reference} was merged
+ Merge Request #{link_to @merge_request.to_reference, project_merge_request_url(@merge_request.target_project, @merge_request)} was merged
diff --git a/app/views/notify/merged_merge_request_email.text.haml b/app/views/notify/merged_merge_request_email.text.haml
index d623e701a30..74e6f86f603 100644
--- a/app/views/notify/merged_merge_request_email.text.haml
+++ b/app/views/notify/merged_merge_request_email.text.haml
@@ -1,6 +1,6 @@
Merge Request #{@merge_request.to_reference} was merged
-Merge Request url: #{project_merge_request_url(@merge_request.target_project, @merge_request)}
+Merge Request URL: #{project_merge_request_url(@merge_request.target_project, @merge_request)}
= merge_path_description(@merge_request, 'to')
diff --git a/app/views/notify/new_issue_email.html.haml b/app/views/notify/new_issue_email.html.haml
index 78afb42c9cf..52e110a98f6 100644
--- a/app/views/notify/new_issue_email.html.haml
+++ b/app/views/notify/new_issue_email.html.haml
@@ -1,5 +1,5 @@
%p.details
- #{link_to @issue.author_name, user_url(@issue.author)} created an issue:
+ #{link_to @issue.author_name, user_url(@issue.author)} created an issue #{link_to @issue.to_reference(full: false), issue_url(@issue)}:
- if @issue.assignees.any?
%p
diff --git a/app/views/notify/new_review_email.html.haml b/app/views/notify/new_review_email.html.haml
new file mode 100644
index 00000000000..ad870473681
--- /dev/null
+++ b/app/views/notify/new_review_email.html.haml
@@ -0,0 +1,16 @@
+%table{ border: "0", cellpadding:"0", cellspacing: "0", style: "width:100%;margin:0 auto;border-collapse:separate;border-spacing:0;" }
+ %tbody
+ %tr
+ %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;background-color:#ffffff;text-align:left;overflow:hidden;" }
+ %table{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:100%;border-collapse:separate;border-spacing:0;" }
+ %tbody
+ %tr
+ %td{ style: "color:#333333;border-bottom:1px solid #ededed;font-size:15px;font-weight:bold;line-height:1.4;padding: 20px 0;" }
+ - mr_link = link_to(@merge_request.to_reference(@project), project_merge_request_url(@project, @merge_request))
+ - mr_author_link = link_to(@author_name, user_url(@author))
+ = _('Merge request %{mr_link} was reviewed by %{mr_author}').html_safe % { mr_link: mr_link, mr_author: mr_author_link }
+ %tr
+ %td{ style: "overflow:hidden;font-size:14px;line-height:1.4;display:grid;" }
+ - @notes.each do |note|
+ - target_url = project_merge_request_url(@project, @merge_request, anchor: "note_#{note.id}")
+ = render 'note_email', note: note, diff_limit: 3, target_url: target_url, note_style: "border-bottom:1px solid #ededed;"
diff --git a/app/views/notify/new_review_email.text.erb b/app/views/notify/new_review_email.text.erb
new file mode 100644
index 00000000000..164735abad0
--- /dev/null
+++ b/app/views/notify/new_review_email.text.erb
@@ -0,0 +1,13 @@
+<% mr_url = merge_request_url(@merge_request) %>
+<% mr_author_name = sanitize_name(@author_name) %>
+<%= _('Merge request %{mr_link} was reviewed by %{mr_author}') % { mr_link: mr_url, mr_author: mr_author_name } %>
+
+--
+<% @notes.each_with_index do |note, index| %>
+ <% target_url = project_merge_request_url(@project, @merge_request, anchor: "note_#{note.id}") %>
+ <%= render 'note_email', note: note, diff_limit: 3, target_url: target_url %>
+
+ <% if index != @notes.length-1 %>
+--
+ <% end %>
+<% end %>
diff --git a/app/views/notify/unknown_sign_in_email.html.haml b/app/views/notify/unknown_sign_in_email.html.haml
index a4123fada1b..914242da5c6 100644
--- a/app/views/notify/unknown_sign_in_email.html.haml
+++ b/app/views/notify/unknown_sign_in_email.html.haml
@@ -1,14 +1,54 @@
-%p
- = _('Hi %{username}!') % { username: sanitize_name(@user.name) }
-%p
- = _('A sign-in to your account has been made from the following IP address: %{ip}.') % { ip: @ip }
-%p
- - password_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: 'https://docs.gitlab.com/ee/user/profile/#changing-your-password' }
- = _('If you recently signed in and recognize the IP address, you may disregard this email.')
- = _('If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}.').html_safe % { password_link_start: password_link_start, password_link_end: '</a>'.html_safe }
- = _('Passwords should be unique and not used for any other sites or services.')
+- default_font = "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;"
+- default_style = "#{default_font}font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;"
+- spacer_style = "#{default_font};height:18px;font-size:18px;line-height:18px;"
-- unless @user.two_factor_enabled?
- %p
- - mfa_link_start = '<a href="https://docs.gitlab.com/ee/user/profile/account/two_factor_authentication.html" target="_blank">'.html_safe
- = _('To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method.').html_safe % { mfa_link_start: mfa_link_start, mfa_link_end: '</a>'.html_safe }
+%tr.alert
+ %td{ style: "#{default_font}padding:10px;border-radius:3px;font-size:14px;line-height:1.3;text-align:center;overflow:hidden;color:#ffffff;background-color:#FC6D26;" }
+ %table.img{ border: "0", cellpadding: "0", cellspacing: "0", style: "border-collapse:collapse;margin:0 auto;" }
+ %tbody
+ %tr
+ %td{ style: "#{default_font}vertical-align:middle;color:#ffffff;text-align:center;" }
+ %span
+ = _("Your %{host} account was signed in to from a new location") % { host: Gitlab.config.gitlab.host }
+%tr.spacer
+ %td{ style: spacer_style }
+ &nbsp;
+%tr.section
+ %td{ style: "#{default_font};padding:0 15px;border:1px solid #ededed;border-radius:3px;overflow:hidden;" }
+ %table.info{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:100%;" }
+ %tbody
+ %tr
+ %td{ style: default_style }
+ = _('Hostname')
+ %td{ style: "#{default_style}color:#333333;font-weight:400;width:75%;padding-left:5px;" }
+ = Gitlab.config.gitlab.host
+ %tr
+ %td{ style: "#{default_style}border-top:1px solid #ededed;" }
+ = _('IP Address')
+ %td{ style: "#{default_style}color:#333333;font-weight:400;width:75%;padding-left:5px;border-top:1px solid #ededed;" }
+ %span.muted{ style: "color:#333333;text-decoration:none;" }
+ = @ip
+ %tr
+ %td{ style: "#{default_style}border-top:1px solid #ededed;" }
+ = _('Time')
+ %td{ style: "#{default_style}color:#333333;font-weight:400;width:75%;padding-left:5px;border-top:1px solid #ededed;" }
+ = @time.strftime('%Y-%m-%d %l:%M:%S %p %Z')
+%tr.spacer
+ %td{ style: spacer_style }
+ &nbsp;
+%tr.section
+ %td{ style: "#{default_font};line-height:1.4;text-align:center;padding:0 15px;overflow:hidden;" }
+ %table.img{ border: "0", cellpadding: "0", cellspacing: "0", style: "border-collapse:collapse;width:100%;" }
+ %tbody
+ %tr{ style: 'width:100%;' }
+ %td{ style: "#{default_style}text-align:center;" }
+ - password_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: 'https://docs.gitlab.com/ee/user/profile/#changing-your-password' }
+ = _('If you recently signed in and recognize the IP address, you may disregard this email.')
+ %p
+ = _('If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}.').html_safe % { password_link_start: password_link_start, password_link_end: '</a>'.html_safe }
+ = _('Passwords should be unique and not used for any other sites or services.')
+
+ - unless @user.two_factor_enabled?
+ %p
+ - mfa_link_start = '<a href="https://docs.gitlab.com/ee/user/profile/account/two_factor_authentication.html" target="_blank">'.html_safe
+ = _('To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method.').html_safe % { mfa_link_start: mfa_link_start, mfa_link_end: '</a>'.html_safe }
diff --git a/app/views/profiles/_event_table.html.haml b/app/views/profiles/_event_table.html.haml
index 977ff30d5a6..c65c4fd0d81 100644
--- a/app/views/profiles/_event_table.html.haml
+++ b/app/views/profiles/_event_table.html.haml
@@ -1,4 +1,4 @@
-%h5.prepend-top-0
+%h5.gl-mt-0
= _('History of authentications')
%ul.content-list
diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml
index e6380817c8f..f4a97206a19 100644
--- a/app/views/profiles/accounts/show.html.haml
+++ b/app/views/profiles/accounts/show.html.haml
@@ -7,7 +7,7 @@
.row.prepend-top-default
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
+ %h4.gl-mt-0
= s_('Profiles|Two-Factor Authentication')
%p
= s_("Profiles|Increase your account's security by enabling Two-Factor Authentication (2FA)")
@@ -24,7 +24,7 @@
- if display_providers_on_profile?
.row.prepend-top-default
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
+ %h4.gl-mt-0
= s_('Profiles|Social sign-in')
%p
= s_('Profiles|Activate signin with one of the following services')
@@ -34,7 +34,7 @@
- if current_user.can_change_username?
.row.prepend-top-default
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0.warning-title
+ %h4.gl-mt-0.warning-title
= s_('Profiles|Change username')
%p
= s_('Profiles|Changing your username can have unintended side effects.')
@@ -47,7 +47,7 @@
.row.prepend-top-default
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0.danger-title
+ %h4.gl-mt-0.danger-title
= s_('Profiles|Delete account')
.col-lg-8
- if current_user.can_be_removed? && can?(current_user, :destroy_user, current_user)
diff --git a/app/views/profiles/active_sessions/index.html.haml b/app/views/profiles/active_sessions/index.html.haml
index d651319fc3f..6d01d055f0c 100644
--- a/app/views/profiles/active_sessions/index.html.haml
+++ b/app/views/profiles/active_sessions/index.html.haml
@@ -3,7 +3,7 @@
.row.prepend-top-default
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
+ %h4.gl-mt-0
= page_title
%p
= _('This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize.')
diff --git a/app/views/profiles/audit_log.html.haml b/app/views/profiles/audit_log.html.haml
index 275c0428d34..02aadcc5c8b 100644
--- a/app/views/profiles/audit_log.html.haml
+++ b/app/views/profiles/audit_log.html.haml
@@ -3,7 +3,7 @@
.row.prepend-top-default
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
+ %h4.gl-mt-0
= page_title
%p
= _('This is a security log of important events involving your account.')
diff --git a/app/views/profiles/chat_names/index.html.haml b/app/views/profiles/chat_names/index.html.haml
index 0c8098a97d5..05870e0e221 100644
--- a/app/views/profiles/chat_names/index.html.haml
+++ b/app/views/profiles/chat_names/index.html.haml
@@ -3,7 +3,7 @@
.row.prepend-top-default
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
+ %h4.gl-mt-0
= page_title
%p
= _('You can see your chat accounts.')
diff --git a/app/views/profiles/emails/index.html.haml b/app/views/profiles/emails/index.html.haml
index e28c74dd650..e90bda0e187 100644
--- a/app/views/profiles/emails/index.html.haml
+++ b/app/views/profiles/emails/index.html.haml
@@ -3,12 +3,12 @@
.row.prepend-top-default
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
+ %h4.gl-mt-0
= page_title
%p
= _('Control emails linked to your account')
.col-lg-8
- %h4.prepend-top-0
+ %h4.gl-mt-0
= _('Add email address')
= form_for 'email', url: profile_emails_path do |f|
.form-group
@@ -17,7 +17,7 @@
.prepend-top-default
= f.submit _('Add email address'), class: 'btn btn-success', data: { qa_selector: 'add_email_address_button' }
%hr
- %h4.prepend-top-0
+ %h4.gl-mt-0
= _('Linked emails (%{email_count})') % { email_count: @emails.load.size + 1 }
.account-well.append-bottom-default
%ul
diff --git a/app/views/profiles/gpg_keys/index.html.haml b/app/views/profiles/gpg_keys/index.html.haml
index f9f898a9225..31610e7505b 100644
--- a/app/views/profiles/gpg_keys/index.html.haml
+++ b/app/views/profiles/gpg_keys/index.html.haml
@@ -3,12 +3,12 @@
.row.prepend-top-default
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
+ %h4.gl-mt-0
= page_title
%p
= _('GPG keys allow you to verify signed commits.')
.col-lg-8
- %h5.prepend-top-0
+ %h5.gl-mt-0
= _('Add a GPG key')
%p.profile-settings-content
- help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/project/repository/gpg_signed_commits/index.md') }
diff --git a/app/views/profiles/keys/index.html.haml b/app/views/profiles/keys/index.html.haml
index da6aa0fce3a..788c67b3704 100644
--- a/app/views/profiles/keys/index.html.haml
+++ b/app/views/profiles/keys/index.html.haml
@@ -3,12 +3,12 @@
.row.prepend-top-default
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
+ %h4.gl-mt-0
= page_title
%p
= _('SSH keys allow you to establish a secure connection between your computer and GitLab.')
.col-lg-8
- %h5.prepend-top-0
+ %h5.gl-mt-0
= _('Add an SSH key')
%p.profile-settings-content
- generate_link_url = help_page_path("ssh/README", anchor: 'generating-a-new-ssh-key-pair')
diff --git a/app/views/profiles/notifications/show.html.haml b/app/views/profiles/notifications/show.html.haml
index 73f6a821b51..498f80aed2b 100644
--- a/app/views/profiles/notifications/show.html.haml
+++ b/app/views/profiles/notifications/show.html.haml
@@ -11,14 +11,14 @@
= hidden_field_tag :notification_type, 'global'
.row.prepend-top-default
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
+ %h4.gl-mt-0
= page_title
%p
= _('You can specify notification level per group or per project.')
%p
= _('By default, all projects and groups will use the global notifications setting.')
.col-lg-8
- %h5.prepend-top-0
+ %h5.gl-mt-0
= _('Global notification settings')
= form_for @user, url: profile_notifications_path, method: :put, html: { class: 'update-notifications prepend-top-default' } do |f|
diff --git a/app/views/profiles/passwords/edit.html.haml b/app/views/profiles/passwords/edit.html.haml
index af6fa6b1b61..9deaf7f84be 100644
--- a/app/views/profiles/passwords/edit.html.haml
+++ b/app/views/profiles/passwords/edit.html.haml
@@ -4,12 +4,12 @@
.row.prepend-top-default
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
+ %h4.gl-mt-0
= page_title
%p
= _('After a successful password update, you will be redirected to the login page where you can log in with your new password.')
.col-lg-8
- %h5.prepend-top-0
+ %h5.gl-mt-0
- if @user.password_automatically_set
= _('Change your password')
- else
diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml
index 81b22d964a5..769502e0026 100644
--- a/app/views/profiles/personal_access_tokens/index.html.haml
+++ b/app/views/profiles/personal_access_tokens/index.html.haml
@@ -6,7 +6,7 @@
.row.prepend-top-default
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
+ %h4.gl-mt-0
= page_title
%p
= s_('AccessTokens|You can generate a personal access token for each application you use that needs access to the GitLab API.')
@@ -35,7 +35,7 @@
%hr
.row.prepend-top-default
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
+ %h4.gl-mt-0
= s_('AccessTokens|Feed token')
%p
= s_('AccessTokens|Your feed token is used to authenticate you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar, and is included in those feed URLs.')
@@ -53,7 +53,7 @@
%hr
.row.prepend-top-default
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
+ %h4.gl-mt-0
= s_('AccessTokens|Incoming email token')
%p
= s_('AccessTokens|Your incoming email token is used to authenticate you when you create a new issue by email, and is included in your personal project-specific email addresses.')
@@ -71,7 +71,7 @@
%hr
.row.prepend-top-default
.col-lg-4
- %h4.prepend-top-0
+ %h4.gl-mt-0
= s_('AccessTokens|Static object token')
%p
= s_('AccessTokens|Your static object token is used to authenticate you when repository static objects (e.g. archives, blobs, ...) are being served from an external storage.')
diff --git a/app/views/profiles/preferences/_sourcegraph.html.haml b/app/views/profiles/preferences/_sourcegraph.html.haml
index 20a904694ca..7328d36b0fb 100644
--- a/app/views/profiles/preferences/_sourcegraph.html.haml
+++ b/app/views/profiles/preferences/_sourcegraph.html.haml
@@ -5,7 +5,7 @@
%hr
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
+ %h4.gl-mt-0
= s_('Preferences|Integrations')
%p
= s_('Preferences|Customize integrations with third party services.')
diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml
index 12d42ce9892..cc44d137848 100644
--- a/app/views/profiles/preferences/show.html.haml
+++ b/app/views/profiles/preferences/show.html.haml
@@ -3,7 +3,7 @@
= form_for @user, url: profile_preferences_path, remote: true, method: :put, html: { class: 'row prepend-top-default js-preferences-form' } do |f|
.col-lg-4.application-theme
- %h4.prepend-top-0
+ %h4.gl-mt-0
= s_('Preferences|Navigation theme')
%p
= s_('Preferences|Customize the appearance of the application header and navigation sidebar.')
@@ -18,7 +18,7 @@
%hr
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
+ %h4.gl-mt-0
= s_('Preferences|Syntax highlighting theme')
%p
= s_('Preferences|This setting allows you to customize the appearance of the syntax.')
@@ -35,7 +35,7 @@
%hr
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
+ %h4.gl-mt-0
= s_('Preferences|Behavior')
%p
= s_('Preferences|This setting allows you to customize the behavior of the system layout and default views.')
@@ -83,7 +83,7 @@
%hr
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
+ %h4.gl-mt-0
= _('Localization')
%p
= _('Customize language and region related settings.')
@@ -104,7 +104,7 @@
.col-sm-12
%hr
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0= s_('Preferences|Time preferences')
+ %h4.gl-mt-0= s_('Preferences|Time preferences')
%p= s_('Preferences|These settings will update how dates and times are displayed for you.')
.col-lg-8
.form-group
diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml
index 43fc9150e99..78fdcdef3c4 100644
--- a/app/views/profiles/show.html.haml
+++ b/app/views/profiles/show.html.haml
@@ -7,7 +7,7 @@
.row
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
+ %h4.gl-mt-0
= s_("Profiles|Public Avatar")
%p
- if @user.avatar?
@@ -27,7 +27,7 @@
.clearfix.avatar-image.append-bottom-default
= link_to avatar_icon_for_user(@user, 400), target: '_blank', rel: 'noopener noreferrer' do
= image_tag avatar_icon_for_user(@user, 160), alt: '', class: 'avatar s160'
- %h5.prepend-top-0= s_("Profiles|Upload new avatar")
+ %h5.gl-mt-0= s_("Profiles|Upload new avatar")
.prepend-top-5.append-bottom-10
%button.btn.js-choose-user-avatar-button{ type: 'button' }= s_("Profiles|Choose file...")
%span.avatar-file-name.prepend-left-default.js-avatar-filename= s_("Profiles|No file chosen")
@@ -40,7 +40,7 @@
%hr
.row
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0= s_("Profiles|Current status")
+ %h4.gl-mt-0= s_("Profiles|Current status")
%p= s_("Profiles|This emoji and message will appear on your profile and throughout the interface.")
.col-lg-8
= f.fields_for :status, @user.status do |status_form|
@@ -71,7 +71,7 @@
%hr
.row.user-time-preferences
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0= s_("Profiles|Time settings")
+ %h4.gl-mt-0= s_("Profiles|Time settings")
%p= s_("Profiles|You can set your current timezone here")
.col-lg-8
-# TODO: might need an entry in user/profile.md to describe some of these settings
@@ -83,7 +83,7 @@
%hr
.row
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
+ %h4.gl-mt-0
= s_("Profiles|Main settings")
%p
= s_("Profiles|This information will appear on your profile")
diff --git a/app/views/profiles/two_factor_auths/show.html.haml b/app/views/profiles/two_factor_auths/show.html.haml
index 4a2d0a4f8ce..7e566361848 100644
--- a/app/views/profiles/two_factor_auths/show.html.haml
+++ b/app/views/profiles/two_factor_auths/show.html.haml
@@ -5,7 +5,7 @@
.js-two-factor-auth{ 'data-two-factor-skippable' => "#{two_factor_skippable?}", 'data-two_factor_skip_url' => skip_profile_two_factor_auth_path }
.row.prepend-top-default
.col-lg-4
- %h4.prepend-top-0
+ %h4.gl-mt-0
= _('Register Two-Factor Authenticator')
%p
= _('Use an one time password authenticator on your mobile device or computer to enable two-factor authentication (2FA).')
@@ -33,13 +33,13 @@
= raw @qr_code
.col-md-8
.account-well
- %p.prepend-top-0.append-bottom-0
+ %p.gl-mt-0.gl-mb-0
= _("Can't scan the code?")
- %p.prepend-top-0.append-bottom-0
+ %p.gl-mt-0.gl-mb-0
= _('To add the entry manually, provide the following details to the application on your phone.')
- %p.prepend-top-0.append-bottom-0
+ %p.gl-mt-0.gl-mb-0
= _('Account: %{account}') % { account: @account_string }
- %p.prepend-top-0.append-bottom-0
+ %p.gl-mt-0.gl-mb-0
= _('Key: %{key}') %{ key: current_user.otp_secret.scan(/.{4}/).join(' ') }
%p.two-factor-new-manual-content
= _('Time based: Yes')
@@ -57,7 +57,7 @@
.row.prepend-top-default
.col-lg-4
- %h4.prepend-top-0
+ %h4.gl-mt-0
= _('Register Universal Two-Factor (U2F) Device')
%p
= _('Use a hardware device to add the second factor of authentication.')
diff --git a/app/views/projects/_export.html.haml b/app/views/projects/_export.html.haml
index 2e00632892b..7da15e0d8a5 100644
--- a/app/views/projects/_export.html.haml
+++ b/app/views/projects/_export.html.haml
@@ -7,7 +7,7 @@
%p= _('Export this project with all its related data in order to move your project to a new GitLab instance. Once the export is finished, you can import the file from the "New Project" page.')
.bs-callout.bs-callout-info
- %p.append-bottom-0
+ %p.gl-mb-0
%p= _('The following items will be exported:')
%ul
- project_export_descriptions.each do |desc|
diff --git a/app/views/projects/_find_file_link.html.haml b/app/views/projects/_find_file_link.html.haml
index da1b2d7f9b6..74cdb0f7409 100644
--- a/app/views/projects/_find_file_link.html.haml
+++ b/app/views/projects/_find_file_link.html.haml
@@ -1,3 +1,2 @@
= link_to project_find_file_path(@project, @ref), class: 'btn shortcuts-find-file', rel: 'nofollow' do
- = icon('search')
- %span= _('Find file')
+ = _('Find file')
diff --git a/app/views/projects/_flash_messages.html.haml b/app/views/projects/_flash_messages.html.haml
index 8217608db4e..4739689b419 100644
--- a/app/views/projects/_flash_messages.html.haml
+++ b/app/views/projects/_flash_messages.html.haml
@@ -8,6 +8,5 @@
- unless project.empty_repo?
= render 'shared/auto_devops_implicitly_enabled_banner', project: project
= render_if_exists 'projects/above_size_limit_warning', project: project
- - if Feature.enabled?(:subscribable_banner_subscription)
- = render_if_exists "layouts/header/ee_subscribable_banner", subscription: true
= render_if_exists 'shared/shared_runners_minutes_limit', project: project, classes: [container_class, ("limit-container-width" unless fluid_layout)]
+ = render 'shared/namespace_storage_limit_alert', namespace: project.namespace, classes: [container_class, ("limit-container-width" unless fluid_layout)]
diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml
index be58ecb3572..6f8375f80be 100644
--- a/app/views/projects/_home_panel.html.haml
+++ b/app/views/projects/_home_panel.html.haml
@@ -4,15 +4,15 @@
- emails_disabled = @project.emails_disabled?
.project-home-panel{ class: [("empty-project" if empty_repo), ("js-show-on-project-root" if vue_file_list_enabled?)] }
- .row.append-bottom-8
+ .row.gl-mb-3
.home-panel-title-row.col-md-12.col-lg-6.d-flex
.avatar-container.rect-avatar.s64.home-panel-avatar.append-right-default.float-none
= project_icon(@project, alt: @project.name, class: 'avatar avatar-tile s64', width: 64, height: 64)
.d-flex.flex-column.flex-wrap.align-items-baseline
.d-inline-flex.align-items-baseline
- %h1.home-panel-title.prepend-top-8.append-bottom-5{ data: { qa_selector: 'project_name_content' } }
+ %h1.home-panel-title.gl-mt-3.append-bottom-5{ data: { qa_selector: 'project_name_content' } }
= @project.name
- %span.visibility-icon.text-secondary.prepend-left-4.has-tooltip{ data: { container: 'body' }, title: visibility_icon_description(@project) }
+ %span.visibility-icon.text-secondary.gl-ml-2.has-tooltip{ data: { container: 'body' }, title: visibility_icon_description(@project) }
= visibility_level_icon(@project.visibility_level, fw: false, options: {class: 'icon'})
= render_if_exists 'compliance_management/compliance_framework/compliance_framework_badge', project: @project
.home-panel-metadata.d-flex.flex-wrap.text-secondary
@@ -20,7 +20,7 @@
%span.text-secondary
= s_('ProjectPage|Project ID: %{project_id}') % { project_id: @project.id }
- if current_user
- %span.access-request-links.prepend-left-8
+ %span.access-request-links.gl-ml-3
= render 'shared/members/access_request_links', source: @project
- if @project.tag_list.present?
%span.home-panel-topic-list.mt-2.w-100.d-inline-flex
@@ -80,7 +80,7 @@
- if @project.badges.present?
.project-badges.mb-2
- @project.badges.each do |badge|
- %a.append-right-8{ href: badge.rendered_link_url(@project),
+ %a.gl-mr-3{ href: badge.rendered_link_url(@project),
target: '_blank',
rel: 'noopener noreferrer' }>
%img.project-badge{ src: badge.rendered_image_url(@project),
diff --git a/app/views/projects/_import_project_pane.html.haml b/app/views/projects/_import_project_pane.html.haml
index 28d4f8eb201..3ae37254e39 100644
--- a/app/views/projects/_import_project_pane.html.haml
+++ b/app/views/projects/_import_project_pane.html.haml
@@ -22,7 +22,7 @@
**tracking_attrs(track_label, 'click_button', 'bitbucket_cloud') do
= icon('bitbucket', text: 'Bitbucket Cloud')
- unless bitbucket_import_configured?
- = render 'bitbucket_import_modal'
+ = render 'projects/bitbucket_import_modal'
- if bitbucket_server_import_enabled?
%div
= link_to status_import_bitbucket_server_path, class: "btn import_bitbucket", **tracking_attrs(track_label, 'click_button', 'bitbucket_server') do
@@ -34,7 +34,7 @@
**tracking_attrs(track_label, 'click_button', 'gitlab_com') do
= icon('gitlab', text: 'GitLab.com')
- unless gitlab_import_configured?
- = render 'gitlab_import_modal'
+ = render 'projects/gitlab_import_modal'
- if google_code_import_enabled?
%div
@@ -73,4 +73,4 @@
= form_for @project, html: { class: 'new_project' } do |f|
%hr
= render "shared/import_form", f: f
- = render 'new_project_fields', f: f, project_name_id: "import-url-name", hide_init_with_readme: true, track_label: track_label
+ = render 'projects/new_project_fields', f: f, project_name_id: "import-url-name", hide_init_with_readme: true, track_label: track_label
diff --git a/app/views/projects/_md_preview.html.haml b/app/views/projects/_md_preview.html.haml
deleted file mode 100644
index 10575aa68b1..00000000000
--- a/app/views/projects/_md_preview.html.haml
+++ /dev/null
@@ -1,36 +0,0 @@
-- referenced_users = local_assigns.fetch(:referenced_users, nil)
-
-- if defined?(@merge_request) && @merge_request.discussion_locked?
- .issuable-note-warning
- = sprite_icon('lock', size: 16, css_class: 'icon')
- %span
- = _('This merge request is locked.')
- = _('Only project members can comment.')
-
-.md-area.position-relative
- .md-header
- %ul.nav.nav-tabs.nav-links.clearfix
- %li.md-header-tab.active
- %button.js-md-write-button{ tabindex: -1 }
- = _("Write")
- %li.md-header-tab
- %button.js-md-preview-button{ tabindex: -1 }
- = _("Preview")
-
- %li.md-header-toolbar.active
- = render 'projects/blob/markdown_buttons', show_fullscreen_button: true
-
- .md-write-holder
- = yield
- .md.md-preview-holder.js-md-preview.hide{ data: { url: url } }
- .referenced-commands.hide
-
- - if referenced_users
- .referenced-users.hide
- %span
- = icon("exclamation-triangle")
- You are about to add
- %strong
- %span.js-referenced-users-count 0
- people
- to the discussion. Proceed with caution.
diff --git a/app/views/projects/_merge_request_merge_checks_settings.html.haml b/app/views/projects/_merge_request_merge_checks_settings.html.haml
index d3fcb52422b..9cebb191346 100644
--- a/app/views/projects/_merge_request_merge_checks_settings.html.haml
+++ b/app/views/projects/_merge_request_merge_checks_settings.html.haml
@@ -14,6 +14,13 @@
anchor: 'pipelines-for-merge-requests'),
target: '_blank'
.form-check.mb-2
+ .gl-pl-6
+ = form.check_box :allow_merge_on_skipped_pipeline, class: 'form-check-input'
+ = form.label :allow_merge_on_skipped_pipeline, class: 'form-check-label' do
+ = s_('ProjectSettings|Skipped pipelines are considered successful')
+ .text-secondary
+ = s_('ProjectSettings|This introduces the risk of merging changes that will not pass the pipeline.')
+ .form-check.mb-2
= form.check_box :only_allow_merge_if_all_discussions_are_resolved, class: 'form-check-input'
= form.label :only_allow_merge_if_all_discussions_are_resolved, class: 'form-check-label' do
= s_('ProjectSettings|All discussions must be resolved')
diff --git a/app/views/projects/_merge_request_merge_suggestions_settings.html.haml b/app/views/projects/_merge_request_merge_suggestions_settings.html.haml
index 06bb9056e61..12f26a7e315 100644
--- a/app/views/projects/_merge_request_merge_suggestions_settings.html.haml
+++ b/app/views/projects/_merge_request_merge_suggestions_settings.html.haml
@@ -9,9 +9,9 @@
anchor: 'configure-the-commit-message-for-applied-suggestions'),
target: '_blank'
.mb-2
- = form.text_field :suggestion_commit_message, class: 'form-control mb-2', placeholder: Suggestions::ApplyService::DEFAULT_SUGGESTION_COMMIT_MESSAGE
+ = form.text_field :suggestion_commit_message, class: 'form-control mb-2', placeholder: Gitlab::Suggestions::CommitMessage::DEFAULT_SUGGESTION_COMMIT_MESSAGE
%p.form-text.text-muted
= s_('ProjectSettings|The variables GitLab supports:')
- - Suggestions::ApplyService::PLACEHOLDERS.keys.each do |placeholder|
+ - Gitlab::Suggestions::CommitMessage::PLACEHOLDERS.keys.each do |placeholder|
%code
= "%{#{placeholder}}".html_safe
diff --git a/app/views/projects/_new_project_fields.html.haml b/app/views/projects/_new_project_fields.html.haml
index 5d88be0925e..e0a426607d4 100644
--- a/app/views/projects/_new_project_fields.html.haml
+++ b/app/views/projects/_new_project_fields.html.haml
@@ -23,7 +23,7 @@
display_path: true,
extra_group: namespace_id),
{},
- { class: 'select2 js-select-namespace qa-project-namespace-select block-truncated', tabindex: 1, data: { track_label: "#{track_label}", track_event: "activate_form_input", track_property: "project_path", track_value: "" }})
+ { 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: "" }})
- else
.input-group-prepend.static-namespace.flex-shrink-0.has-tooltip{ title: user_url(current_user.username) + '/' }
diff --git a/app/views/projects/_wiki.html.haml b/app/views/projects/_wiki.html.haml
index 57a5d3e2e83..6f90bf50b91 100644
--- a/app/views/projects/_wiki.html.haml
+++ b/app/views/projects/_wiki.html.haml
@@ -14,4 +14,4 @@
- if can_create_wiki
%p
= _("Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message.")
- = link_to _("Create your first page"), project_wiki_path(@project, :home) + '?view=create', class: "btn btn-primary"
+ = link_to _("Create your first page"), wiki_path(@project.wiki) + '?view=create', class: "btn btn-primary"
diff --git a/app/views/projects/_zen.html.haml b/app/views/projects/_zen.html.haml
deleted file mode 100644
index 744aef3cad4..00000000000
--- a/app/views/projects/_zen.html.haml
+++ /dev/null
@@ -1,19 +0,0 @@
-- @gfm_form = true
-- current_text ||= nil
-- supports_autocomplete = local_assigns.fetch(:supports_autocomplete, true)
-- supports_quick_actions = local_assigns.fetch(:supports_quick_actions, false)
-- qa_selector = local_assigns.fetch(:qa_selector, '')
-.zen-backdrop
- - classes << ' js-gfm-input js-autosize markdown-area'
- - if defined?(f) && f
- = f.text_area attr,
- class: classes,
- placeholder: placeholder,
- dir: 'auto',
- data: { supports_quick_actions: supports_quick_actions,
- supports_autocomplete: supports_autocomplete,
- qa_selector: qa_selector }
- - else
- = text_area_tag attr, current_text, class: classes, placeholder: placeholder
- %a.zen-control.zen-control-leave.js-zen-leave{ href: "#" }
- = icon('compress')
diff --git a/app/views/projects/blame/_blame_group.html.haml b/app/views/projects/blame/_blame_group.html.haml
new file mode 100644
index 00000000000..e9967814833
--- /dev/null
+++ b/app/views/projects/blame/_blame_group.html.haml
@@ -0,0 +1,26 @@
+%tr
+ %td.blame-commit{ class: commit_data.age_map_class }
+ .commit
+ = commit_data.author_avatar
+ .commit-row-title
+ %span.item-title.str-truncated-100
+ = commit_data.commit_link
+ %span
+ = commit_data.project_blame_link
+ &nbsp;
+ .light
+ = commit_data.commit_author_link
+ = _('committed')
+ #{commit_data.time_ago_tooltip}
+ %td.line-numbers
+ - line_count = blame_group[:lines].count
+ - (current_line...(current_line + line_count)).each do |i|
+ %a.diff-line-num{ href: "#L#{i}", id: "L#{i}", 'data-line-number' => i }
+ = link_icon
+ = i
+ \
+ %td.lines
+ %pre.code.highlight
+ %code
+ - blame_group[:lines].each do |line|
+ #{line}
diff --git a/app/views/projects/blame/show.html.haml b/app/views/projects/blame/show.html.haml
index b17207c0da6..0591c3180ea 100644
--- a/app/views/projects/blame/show.html.haml
+++ b/app/views/projects/blame/show.html.haml
@@ -1,5 +1,5 @@
-- project_duration = age_map_duration(@blame_groups, @project)
- page_title "Blame", @blob.path, @ref
+- link_icon = icon("link")
#blob-content-holder.tree-holder
= render "projects/blob/breadcrumb", blob: @blob, blame: true
@@ -11,38 +11,13 @@
.table-responsive.file-content.blame.code.js-syntax-highlight
%table
- current_line = 1
- - @blame_groups.each do |blame_group|
- %tr
- - commit = blame_group[:commit]
- %td.blame-commit{ class: age_map_class(commit.committed_date, project_duration) }
- .commit
- = author_avatar(commit, size: 36, has_tooltip: false)
- .commit-row-title
- %span.item-title.str-truncated-100
- = link_to commit.title, project_commit_path(@project, commit.id), class: "cdark", title: commit.title
- %span
- - previous_commit_id = commit.parent_id
- - if previous_commit_id
- = link_to project_blame_path(@project, tree_join(previous_commit_id, @path)),
- title: _('View blame prior to this change'),
- aria: { label: _('View blame prior to this change') },
- data: { toggle: 'tooltip', placement: 'right', container: 'body' } do
- = sprite_icon('doc-versions', size: 16, css_class: 'doc-versions align-text-bottom')
- &nbsp;
- .light
- = commit_author_link(commit, avatar: false)
- committed
- #{time_ago_with_tooltip(commit.committed_date)}
- %td.line-numbers
- - line_count = blame_group[:lines].count
- - (current_line...(current_line + line_count)).each do |i|
- %a.diff-line-num{ href: "#L#{i}", id: "L#{i}", 'data-line-number' => i }
- = icon("link")
- = i
- \
- - current_line += line_count
- %td.lines
- %pre.code.highlight
- %code
- - blame_group[:lines].each do |line|
- #{line}
+ - @blame.groups.each do |blame_group|
+ - commit_data = @blame.commit_data(blame_group[:commit])
+
+ = render 'blame_group',
+ blame_group: blame_group,
+ current_line: current_line,
+ link_icon: link_icon,
+ commit_data: commit_data
+
+ - current_line += blame_group[:lines].count
diff --git a/app/views/projects/blob/_editor.html.haml b/app/views/projects/blob/_editor.html.haml
index b67f9d0cd08..032df24a603 100644
--- a/app/views/projects/blob/_editor.html.haml
+++ b/app/views/projects/blob/_editor.html.haml
@@ -28,7 +28,7 @@
.file-buttons
- if is_markdown
- = render 'projects/blob/markdown_buttons', show_fullscreen_button: false
+ = render 'shared/blob/markdown_buttons', show_fullscreen_button: false
= button_tag class: 'soft-wrap-toggle btn', type: 'button', tabindex: '-1' do
%span.no-wrap
= custom_icon('icon_no_wrap')
diff --git a/app/views/projects/blob/_header_content.html.haml b/app/views/projects/blob/_header_content.html.haml
index 7ed71a7d43c..6527c6021a0 100644
--- a/app/views/projects/blob/_header_content.html.haml
+++ b/app/views/projects/blob/_header_content.html.haml
@@ -1,7 +1,7 @@
.file-header-content
= blob_icon blob.mode, blob.name
- %strong.file-title-name.qa-file-title-name
+ %strong.file-title-name
= blob.name
= copy_file_path_button(blob.path)
diff --git a/app/views/projects/blob/_markdown_buttons.html.haml b/app/views/projects/blob/_markdown_buttons.html.haml
deleted file mode 100644
index 44ec2fa69cb..00000000000
--- a/app/views/projects/blob/_markdown_buttons.html.haml
+++ /dev/null
@@ -1,13 +0,0 @@
-.md-header-toolbar.active
- = markdown_toolbar_button({ icon: "bold", data: { "md-tag" => "**" }, title: _("Add bold text") })
- = markdown_toolbar_button({ icon: "italic", data: { "md-tag" => "*" }, title: _("Add italic text") })
- = markdown_toolbar_button({ icon: "quote", data: { "md-tag" => "> ", "md-prepend" => true }, title: _("Insert a quote") })
- = markdown_toolbar_button({ icon: "code", data: { "md-tag" => "`", "md-block" => "```" }, title: _("Insert code") })
- = markdown_toolbar_button({ icon: "link", data: { "md-tag" => "[{text}](url)", "md-select" => "url" }, title: _("Add a link") })
- = markdown_toolbar_button({ icon: "list-bulleted", data: { "md-tag" => "* ", "md-prepend" => true }, title: _("Add a bullet list") })
- = markdown_toolbar_button({ icon: "list-numbered", data: { "md-tag" => "1. ", "md-prepend" => true }, title: _("Add a numbered list") })
- = markdown_toolbar_button({ icon: "list-task", data: { "md-tag" => "* [ ] ", "md-prepend" => true }, title: _("Add a task list") })
- = markdown_toolbar_button({ icon: "table", data: { "md-tag" => "| header | header |\n| ------ | ------ |\n| cell | cell |\n| cell | cell |", "md-prepend" => true }, title: _("Add a table") })
- - if show_fullscreen_button
- %button.toolbar-btn.toolbar-fullscreen-btn.js-zen-enter.has-tooltip{ type: "button", tabindex: -1, "aria-label": "Go full screen", title: _("Go full screen"), data: { container: "body" } }
- = sprite_icon("screen-full")
diff --git a/app/views/projects/blob/viewers/_metrics_dashboard_yml.html.haml b/app/views/projects/blob/viewers/_metrics_dashboard_yml.html.haml
new file mode 100644
index 00000000000..fc8683e1d19
--- /dev/null
+++ b/app/views/projects/blob/viewers/_metrics_dashboard_yml.html.haml
@@ -0,0 +1,11 @@
+- if viewer.valid?
+ = icon('check fw')
+ = _('Metrics Dashboard YAML definition is valid.')
+- else
+ = icon('warning fw')
+ = _('Metrics Dashboard YAML definition is invalid:')
+ %ul
+ - viewer.errors.messages.each do |error|
+ %li= error.join(': ')
+
+= link_to _('Learn more'), help_page_path('user/project/integrations/prometheus.md', anchor: 'defining-custom-dashboards-per-project')
diff --git a/app/views/projects/blob/viewers/_metrics_dashboard_yml_loading.html.haml b/app/views/projects/blob/viewers/_metrics_dashboard_yml_loading.html.haml
new file mode 100644
index 00000000000..31a0d514444
--- /dev/null
+++ b/app/views/projects/blob/viewers/_metrics_dashboard_yml_loading.html.haml
@@ -0,0 +1,4 @@
+= icon('spinner spin fw')
+= _('Metrics Dashboard YAML definition') + '…'
+
+= link_to _('Learn more'), help_page_path('user/project/integrations/prometheus.md')
diff --git a/app/views/projects/blob/viewers/_readme.html.haml b/app/views/projects/blob/viewers/_readme.html.haml
index c2329a7aa66..6cbd26e2271 100644
--- a/app/views/projects/blob/viewers/_readme.html.haml
+++ b/app/views/projects/blob/viewers/_readme.html.haml
@@ -1,4 +1,4 @@
= icon('info-circle fw')
= succeed '.' do
To learn more about this project, read
- = link_to "the wiki", project_wiki_path(viewer.project, :home)
+ = link_to "the wiki", wiki_path(viewer.project.wiki)
diff --git a/app/views/projects/blob/viewers/_route_map.html.haml b/app/views/projects/blob/viewers/_route_map.html.haml
index 07b9378ba97..024e9b4ddb2 100644
--- a/app/views/projects/blob/viewers/_route_map.html.haml
+++ b/app/views/projects/blob/viewers/_route_map.html.haml
@@ -6,4 +6,4 @@
This Route Map is invalid:
= viewer.validation_message
-= link_to 'Learn more', help_page_path('ci/environments', anchor: 'going-from-source-files-to-public-pages')
+= link_to 'Learn more', help_page_path('ci/environments/index.md', anchor: 'going-from-source-files-to-public-pages')
diff --git a/app/views/projects/blob/viewers/_route_map_loading.html.haml b/app/views/projects/blob/viewers/_route_map_loading.html.haml
index f11c047e85a..1d768bd1ca4 100644
--- a/app/views/projects/blob/viewers/_route_map_loading.html.haml
+++ b/app/views/projects/blob/viewers/_route_map_loading.html.haml
@@ -1,4 +1,4 @@
= icon('spinner spin fw')
Validating Route Map…
-= link_to 'Learn more', help_page_path('ci/environments', anchor: 'going-from-source-files-to-public-pages')
+= link_to 'Learn more', help_page_path('ci/environments/index.md', anchor: 'going-from-source-files-to-public-pages')
diff --git a/app/views/projects/branches/_branch.html.haml b/app/views/projects/branches/_branch.html.haml
index 3e53cb510b0..2e9be28df86 100644
--- a/app/views/projects/branches/_branch.html.haml
+++ b/app/views/projects/branches/_branch.html.haml
@@ -5,7 +5,7 @@
.branch-info
.branch-title
= sprite_icon('fork', size: 12)
- = link_to project_tree_path(@project, branch.name), class: 'item-title str-truncated-100 ref-name prepend-left-8 qa-branch-name' do
+ = link_to project_tree_path(@project, branch.name), class: 'item-title str-truncated-100 ref-name gl-ml-3 qa-branch-name' do
= branch.name
- if branch.name == @repository.root_ref
%span.badge.badge-primary.prepend-left-5 default
@@ -29,6 +29,12 @@
.js-branch-divergence-graph
.controls.d-none.d-md-block<
+ - if commit_status
+ = render 'ci/status/icon', size: 24, status: commit_status, option_css_classes: 'gl-display-inline-flex gl-vertical-align-middle gl-mr-5'
+ - elsif show_commit_status
+ .gl-display-inline-flex.gl-vertical-align-middle.gl-mr-5
+ %svg.s24
+
- if merge_project && create_mr_button?(@repository.root_ref, branch.name)
= link_to create_mr_path(@repository.root_ref, branch.name), class: 'btn btn-default' do
= _('Merge request')
diff --git a/app/views/projects/branches/_panel.html.haml b/app/views/projects/branches/_panel.html.haml
index 93061452e12..828371e9656 100644
--- a/app/views/projects/branches/_panel.html.haml
+++ b/app/views/projects/branches/_panel.html.haml
@@ -12,7 +12,7 @@
= panel_title
%ul.content-list.all-branches.qa-all-branches
- branches.first(overview_max_branches).each do |branch|
- = render "projects/branches/branch", branch: branch, merged: project.repository.merged_to_root_ref?(branch)
+ = render "projects/branches/branch", branch: branch, merged: project.repository.merged_to_root_ref?(branch), commit_status: @branch_pipeline_statuses[branch.name], show_commit_status: @branch_pipeline_statuses.any?
- if branches.size > overview_max_branches
.card-footer.text-center
= link_to show_more_text, project_branches_filtered_path(project, state: state), id: "state-#{state}", data: { state: state }
diff --git a/app/views/projects/branches/index.html.haml b/app/views/projects/branches/index.html.haml
index 6bdc6f716fe..ba42f43088f 100644
--- a/app/views/projects/branches/index.html.haml
+++ b/app/views/projects/branches/index.html.haml
@@ -59,7 +59,7 @@
- elsif @branches.any?
%ul.content-list.all-branches
- @branches.each do |branch|
- = render "projects/branches/branch", branch: branch, merged: @merged_branch_names.include?(branch.name)
+ = render "projects/branches/branch", branch: branch, merged: @merged_branch_names.include?(branch.name), commit_status: @branch_pipeline_statuses[branch.name], show_commit_status: @branch_pipeline_statuses.any?
= paginate @branches, theme: 'gitlab'
- else
.nothing-here-block
diff --git a/app/views/projects/buttons/_fork.html.haml b/app/views/projects/buttons/_fork.html.haml
index 4b82eb2c5ef..2d9c7f9848f 100644
--- a/app/views/projects/buttons/_fork.html.haml
+++ b/app/views/projects/buttons/_fork.html.haml
@@ -1,6 +1,6 @@
- unless @project.empty_repo?
- if current_user && can?(current_user, :fork_project, @project)
- .count-badge.d-inline-flex.align-item-stretch.append-right-8
+ .count-badge.d-inline-flex.align-item-stretch.gl-mr-3
- if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2
= link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: s_('ProjectOverview|Go to your fork'), class: 'btn btn-default has-tooltip count-badge-button d-flex align-items-center fork-btn' do
= sprite_icon('fork', { css_class: 'icon' })
diff --git a/app/views/projects/buttons/_star.html.haml b/app/views/projects/buttons/_star.html.haml
index 02e5297528b..3dac38d1356 100644
--- a/app/views/projects/buttons/_star.html.haml
+++ b/app/views/projects/buttons/_star.html.haml
@@ -1,5 +1,5 @@
- if current_user
- .count-badge.d-inline-flex.align-item-stretch.append-right-8
+ .count-badge.d-inline-flex.align-item-stretch.gl-mr-3
%button.count-badge-button.btn.btn-default.btn-xs.d-flex.align-items-center.star-btn.toggle-star{ type: "button", data: { endpoint: toggle_star_project_path(@project, :json) } }
- if current_user.starred?(@project)
= sprite_icon('star', { css_class: 'icon' })
@@ -12,7 +12,7 @@
= @project.star_count
- else
- .count-badge.d-inline-flex.align-item-stretch.append-right-8
+ .count-badge.d-inline-flex.align-item-stretch.gl-mr-3
= link_to new_user_session_path, class: 'btn btn-default btn-xs has-tooltip count-badge-button d-flex align-items-center star-btn', title: s_('ProjectOverview|You must sign in to star a project') do
= sprite_icon('star-o', { css_class: 'icon' })
%span= s_('ProjectOverview|Star')
diff --git a/app/views/projects/cleanup/_show.html.haml b/app/views/projects/cleanup/_show.html.haml
index ed3c9890efd..02e8bad69b9 100644
--- a/app/views/projects/cleanup/_show.html.haml
+++ b/app/views/projects/cleanup/_show.html.haml
@@ -6,7 +6,7 @@
%button.btn.js-settings-toggle
= expanded ? _('Collapse') : _('Expand')
%p
- = _("Clean up after running %{bfg} on the repository" % { bfg: link_to_bfg }).html_safe
+ = _("Clean up after running %{filter_repo} on the repository" % { filter_repo: link_to_filter_repo }).html_safe
= link_to icon('question-circle'),
help_page_path('user/project/repository/reducing_the_repo_size_using_git.md'),
target: '_blank', rel: 'noopener noreferrer'
@@ -14,15 +14,15 @@
.settings-content
- url = cleanup_namespace_project_settings_repository_path(@project.namespace, @project)
= form_for @project, url: url, method: :post, authenticity_token: true, html: { class: 'js-requires-input' } do |f|
- %fieldset.prepend-top-0.append-bottom-10
+ %fieldset.gl-mt-0.append-bottom-10
.append-bottom-10
- %h5.prepend-top-0
+ %h5.gl-mt-0
= _("Upload object map")
%button.btn.btn-default.js-choose-file{ type: "button" }
= _("Choose a file")
%span.prepend-left-default.js-filename
= _("No file selected")
- = f.file_field :bfg_object_map, accept: 'text/plain', class: "hidden js-object-map-input", required: true
+ = f.file_field :bfg_object_map, class: "hidden js-object-map-input", required: true
.form-text.text-muted
= _("The maximum file size allowed is %{size}.") % { size: number_to_human_size(Gitlab::CurrentSettings.max_attachment_size.megabytes) }
= f.submit _('Start cleanup'), class: 'btn btn-success'
diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml
index 88d1ec54cb0..4442bdcdf1d 100644
--- a/app/views/projects/commit/_commit_box.html.haml
+++ b/app/views/projects/commit/_commit_box.html.haml
@@ -22,8 +22,8 @@
.header-action-buttons
- if defined?(@notes_count) && @notes_count > 0
- %span.btn.disabled.btn-grouped.d-none.d-sm-block.append-right-10
- = icon('comment')
+ %span.btn.disabled.btn-grouped.d-none.d-sm-block.append-right-10.has-tooltip{ title: n_("%d comment on this commit", "%d comments on this commit", @notes_count) % @notes_count }
+ = sprite_icon('comment')
= @notes_count
= link_to project_tree_path(@project, @commit), class: "btn btn-default append-right-10 d-none d-sm-none d-md-inline" do
#{ _('Browse files') }
diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml
index b42eef32a76..ab1d855a6e0 100644
--- a/app/views/projects/commits/_commit.html.haml
+++ b/app/views/projects/commits/_commit.html.haml
@@ -41,7 +41,7 @@
= render_if_exists 'projects/commits/project_namespace', show_project_name: show_project_name, project: project
- if commit.description?
- %pre.commit-row-description.js-toggle-content.append-bottom-8
+ %pre.commit-row-description.js-toggle-content.gl-mb-3
= preserve(markdown_field(commit, :description))
.commit-actions.flex-row
diff --git a/app/views/projects/diffs/_file.html.haml b/app/views/projects/diffs/_file.html.haml
index 855b719dc45..7395c16c38b 100644
--- a/app/views/projects/diffs/_file.html.haml
+++ b/app/views/projects/diffs/_file.html.haml
@@ -14,7 +14,7 @@
.file-actions.d-none.d-sm-block
- if blob&.readable_text?
= link_to '#', class: 'js-toggle-diff-comments btn active has-tooltip', title: _("Toggle comments for this file"), disabled: @diff_notes_disabled do
- = icon('comment')
+ = sprite_icon('comment', size: 16)
\
- if editable_diff?(diff_file)
- link_opts = @merge_request.persisted? ? { from_merge_request_iid: @merge_request.iid } : {}
diff --git a/app/views/projects/diffs/_stats.html.haml b/app/views/projects/diffs/_stats.html.haml
index 86e6e732610..17c1764e8a4 100644
--- a/app/views/projects/diffs/_stats.html.haml
+++ b/app/views/projects/diffs/_stats.html.haml
@@ -22,8 +22,8 @@
- 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), size: 16, css_class: "#{diff_file_changed_icon_color(diff_file)} diff-file-changed-icon append-right-8")
- %span.diff-changed-file-content.append-right-8
+ = sprite_icon(diff_file_changed_icon(diff_file), size: 16, 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
diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml
index 9e06358beba..6b1455acd08 100644
--- a/app/views/projects/empty.html.haml
+++ b/app/views/projects/empty.html.haml
@@ -6,11 +6,11 @@
%div{ class: [("limit-container-width" unless fluid_layout)] }
= render "home_panel"
- %h4.prepend-top-0.append-bottom-8
+ %h4.gl-mt-0.gl-mb-3
= _('The repository for this project is empty')
- if @project.can_current_user_push_code?
- %p.append-bottom-0
+ %p.gl-mb-0
= _('You can get started by cloning the repository or start adding files to it with one of the following options.')
.project-buttons.qa-quick-actions
@@ -22,7 +22,7 @@
= render 'stat_anchor_list', anchors: @project.empty_repo_statistics_buttons
- if can?(current_user, :push_code, @project)
- .empty-wrapper.prepend-top-32
+ .empty-wrapper.gl-mt-7
%h3#repo-command-line-instructions.page-title-empty
= _('Command line instructions')
%p
diff --git a/app/views/projects/environments/_form.html.haml b/app/views/projects/environments/_form.html.haml
index 1fbe34cfff3..efe80a4877c 100644
--- a/app/views/projects/environments/_form.html.haml
+++ b/app/views/projects/environments/_form.html.haml
@@ -1,9 +1,9 @@
.row.prepend-top-default.append-bottom-default
.col-lg-3
- %h4.prepend-top-0
+ %h4.gl-mt-0
= _("Environments")
%p
- - link_to_read_more = link_to(_("Read more about environments"), help_page_path("ci/environments"))
+ - link_to_read_more = link_to(_("Read more about environments"), help_page_path("ci/environments/index.md"))
= _("Environments allow you to track deployments of your application %{link_to_read_more}.").html_safe % { link_to_read_more: link_to_read_more }
= form_for [@project.namespace.becomes(Namespace), @project, @environment], html: { class: 'col-lg-9' } do |f|
diff --git a/app/views/projects/environments/empty_metrics.html.haml b/app/views/projects/environments/empty_metrics.html.haml
index dad93290fbd..5642fb34da9 100644
--- a/app/views/projects/environments/empty_metrics.html.haml
+++ b/app/views/projects/environments/empty_metrics.html.haml
@@ -11,4 +11,4 @@
%p.state-description
= s_('Metrics|Check out the CI/CD documentation on deploying to an environment')
.text-center
- = link_to s_("Environments|Learn about environments"), help_page_path('ci/environments'), class: 'btn btn-success'
+ = link_to s_("Environments|Learn about environments"), help_page_path('ci/environments/index.md'), class: 'btn btn-success'
diff --git a/app/views/projects/environments/index.html.haml b/app/views/projects/environments/index.html.haml
index 2ba88da3375..445196ed449 100644
--- a/app/views/projects/environments/index.html.haml
+++ b/app/views/projects/environments/index.html.haml
@@ -4,5 +4,5 @@
"can-read-environment" => can?(current_user, :read_environment, @project).to_s,
"can-create-environment" => can?(current_user, :create_environment, @project).to_s,
"new-environment-path" => new_project_environment_path(@project),
- "help-page-path" => help_page_path("ci/environments"),
+ "help-page-path" => help_page_path("ci/environments/index.md"),
"deploy-boards-help-path" => help_page_path("user/project/deploy_boards", anchor: "enabling-deploy-boards") } }
diff --git a/app/views/projects/environments/metrics.html.haml b/app/views/projects/environments/metrics.html.haml
index aab30af5ed4..cd7339edd1a 100644
--- a/app/views/projects/environments/metrics.html.haml
+++ b/app/views/projects/environments/metrics.html.haml
@@ -1,4 +1,4 @@
-- page_title _("Metrics for environment"), @environment.name
+- page_title _("Metrics Dashboard"), @environment.name
.prometheus-container
#prometheus-graphs{ data: metrics_data(@project, @environment) }
diff --git a/app/views/projects/environments/show.html.haml b/app/views/projects/environments/show.html.haml
index 3a7a93dc4e6..d5249662dde 100644
--- a/app/views/projects/environments/show.html.haml
+++ b/app/views/projects/environments/show.html.haml
@@ -23,7 +23,7 @@
emphasis_end: '</strong>'.html_safe,
ci_config_link_start: '<a href="https://docs.gitlab.com/ee/ci/yaml/" target="_blank" rel="noopener noreferrer">'.html_safe,
ci_config_link_end: '</a>'.html_safe }
- %a{ href: 'https://docs.gitlab.com/ee/ci/environments.html#stopping-an-environment',
+ %a{ href: 'https://docs.gitlab.com/ee/ci/environments/index.html#stopping-an-environment',
target: '_blank',
rel: 'noopener noreferrer' }
= s_('Environments|Learn more about stopping environments')
@@ -39,7 +39,7 @@
.d-flex
%h3.page-title= @environment.name
- if @environment.auto_stop_at?
- %p.align-self-end.prepend-left-8
+ %p.align-self-end.gl-ml-3
= s_('Environments|Auto stops %{auto_stop_time}').html_safe % {auto_stop_time: time_ago_with_tooltip(@environment.auto_stop_at)}
.nav-controls.my-2
= render 'projects/environments/pin_button', environment: @environment
diff --git a/app/views/projects/forks/_fork_button.html.haml b/app/views/projects/forks/_fork_button.html.haml
index c7ed6a5094d..70064722832 100644
--- a/app/views/projects/forks/_fork_button.html.haml
+++ b/app/views/projects/forks/_fork_button.html.haml
@@ -22,5 +22,5 @@
- else
.avatar-container.s100.mx-auto
= image_tag(avatar, class: "avatar s100")
- %h5.prepend-top-default
+ %h5.prepend-top-default{ data: { qa_selector: 'fork_namespace_content', qa_name: namespace.human_name } }
= namespace.human_name
diff --git a/app/views/projects/forks/new.html.haml b/app/views/projects/forks/new.html.haml
index 8a5b08a19c8..763e31c4a8b 100644
--- a/app/views/projects/forks/new.html.haml
+++ b/app/views/projects/forks/new.html.haml
@@ -2,14 +2,14 @@
.row.prepend-top-default
.col-lg-3
- %h4.prepend-top-0
+ %h4.gl-mt-0
= _("Fork project")
%p
= _("A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project.").html_safe
.col-lg-9
- if @namespaces.present?
.fork-thumbnail-container.js-fork-content
- %h5.prepend-top-0.append-bottom-0.prepend-left-default.append-right-default
+ %h5.gl-mt-0.gl-mb-0.prepend-left-default.append-right-default
= _("Select a namespace to fork the project")
- @namespaces.each do |namespace|
= render 'fork_button', namespace: namespace
diff --git a/app/views/projects/graphs/charts.html.haml b/app/views/projects/graphs/charts.html.haml
index 7257dacf680..24d92e947bc 100644
--- a/app/views/projects/graphs/charts.html.haml
+++ b/app/views/projects/graphs/charts.html.haml
@@ -28,7 +28,7 @@
%a.btn.btn-sm{ href: "#{download_path}?#{@daily_coverage_options[:base_params].to_query}" }
%small
= _("Download raw data (.csv)")
- #js-code-coverage-chart{ data: { daily_coverage_options: @daily_coverage_options.to_json.html_safe } }
+ #js-code-coverage-chart{ data: { graph_endpoint: "#{@daily_coverage_options[:graph_api_path]}?#{@daily_coverage_options[:base_params].to_query}" } }
.repo-charts
.sub-header-block.border-top
diff --git a/app/views/projects/hook_logs/_index.html.haml b/app/views/projects/hook_logs/_index.html.haml
index f3cea6bea68..e7b924c65bf 100644
--- a/app/views/projects/hook_logs/_index.html.haml
+++ b/app/views/projects/hook_logs/_index.html.haml
@@ -1,6 +1,6 @@
-.row.prepend-top-32.append-bottom-default
+.row.gl-mt-7.append-bottom-default
.col-lg-3
- %h4.prepend-top-0
+ %h4.gl-mt-0
Recent Deliveries
%p When an event in GitLab triggers a webhook, you can use the request details to figure out if something went wrong.
.col-lg-9
diff --git a/app/views/projects/hook_logs/show.html.haml b/app/views/projects/hook_logs/show.html.haml
index 873fb4d47b7..a6a3f56c28c 100644
--- a/app/views/projects/hook_logs/show.html.haml
+++ b/app/views/projects/hook_logs/show.html.haml
@@ -4,7 +4,7 @@
.row.prepend-top-default.append-bottom-default
.col-lg-3
- %h4.prepend-top-0
+ %h4.gl-mt-0
Request details
.col-lg-9
= link_to 'Resend Request', @hook_log.present.retry_path, method: :post, class: "btn btn-default float-right prepend-left-10"
diff --git a/app/views/projects/hooks/edit.html.haml b/app/views/projects/hooks/edit.html.haml
index f7eae802dac..15100840c0a 100644
--- a/app/views/projects/hooks/edit.html.haml
+++ b/app/views/projects/hooks/edit.html.haml
@@ -10,7 +10,7 @@
= form_for [@project.namespace.becomes(Namespace), @project, @hook], as: :hook, url: project_hook_path(@project, @hook) do |f|
= render partial: 'shared/web_hooks/form', locals: { form: f, hook: @hook }
- %span>= f.submit 'Save changes', class: 'btn btn-success append-right-8'
+ %span>= f.submit 'Save changes', class: 'btn btn-success gl-mr-3'
= render 'shared/web_hooks/test_button', hook: @hook
= link_to _('Delete'), project_hook_path(@project, @hook), method: :delete, class: 'btn btn-remove float-right', data: { confirm: _('Are you sure?') }
diff --git a/app/views/projects/import/jira/show.html.haml b/app/views/projects/import/jira/show.html.haml
index cddd97cbc84..fe6cc6fa828 100644
--- a/app/views/projects/import/jira/show.html.haml
+++ b/app/views/projects/import/jira/show.html.haml
@@ -1,33 +1,6 @@
-- if Feature.enabled?(:jira_issue_import_vue, @project, default_enabled: true)
- .js-jira-import-root{ data: { project_path: @project.full_path,
- issues_path: project_issues_path(@project),
- jira_integration_path: edit_project_service_path(@project, :jira),
- is_jira_configured: @project.jira_service.present?.to_s,
- jira_projects: @jira_projects.to_json,
- in_progress_illustration: image_path('illustrations/export-import.svg'),
- setup_illustration: image_path('illustrations/manual_action.svg') } }
-- else
- - title = _('Jira Issue Import')
- - page_title title
- - breadcrumb_title title
- - header_title _("Projects"), root_path
-
- = render 'import/shared/errors'
-
- - if @project.import_state&.in_progress?
- %h3.page-title.d-flex.align-items-center
- = sprite_icon('issues', size: 16, css_class: 'mr-1')
- = _('Import in progress')
- - elsif @jira_projects.present?
- %h3.page-title.d-flex.align-items-center
- = sprite_icon('issues', size: 16, css_class: 'mr-1')
- = _('Import issues from Jira')
-
- = form_tag import_project_import_jira_path(@project), method: :post do
- .form-group.row
- = label_tag :jira_project_key, _('From project'), class: 'col-form-label col-md-2'
- .col-md-4
- = select_tag :jira_project_key, options_for_select(@jira_projects, ''), { class: 'select2' }
- .form-actions
- = submit_tag _('Import issues'), class: 'btn btn-success'
- = link_to _('Cancel'), project_issues_path(@project), class: 'btn btn-cancel'
+.js-jira-import-root{ data: { project_path: @project.full_path,
+ issues_path: project_issues_path(@project),
+ jira_integration_path: edit_project_service_path(@project, :jira),
+ is_jira_configured: @project.jira_service&.active? && @project.jira_service&.valid_connection?.to_s,
+ in_progress_illustration: image_path('illustrations/export-import.svg'),
+ setup_illustration: image_path('illustrations/manual_action.svg') } }
diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml
index 1bf0c8eb031..e325d585d0c 100644
--- a/app/views/projects/issues/_issue.html.haml
+++ b/app/views/projects/issues/_issue.html.haml
@@ -43,6 +43,7 @@
= link_to_label(label, small: true)
= render_if_exists "projects/issues/issue_weight", issue: issue
+ = render "projects/issues/issue_estimate", issue: issue
.issuable-meta
%ul.controls
diff --git a/app/views/projects/issues/_issue_estimate.html.haml b/app/views/projects/issues/_issue_estimate.html.haml
new file mode 100644
index 00000000000..46797d0f1a0
--- /dev/null
+++ b/app/views/projects/issues/_issue_estimate.html.haml
@@ -0,0 +1,7 @@
+- issue = local_assigns.fetch(:issue)
+
+- if issue.time_estimate > 0
+ %span.issuable-estimate.d-none.d-sm-inline-block.has-tooltip{ data: { container: 'body', qa_selector: 'issuable_estimate' }, title: _('Estimate') }
+ &nbsp;
+ = sprite_icon('timer', size: 16, css_class: 'issue-estimate-icon')
+ = Gitlab::TimeTrackingFormatter.output(issue.time_estimate)
diff --git a/app/views/projects/issues/_new_branch.html.haml b/app/views/projects/issues/_new_branch.html.haml
index f3a1edd2571..73904354a12 100644
--- a/app/views/projects/issues/_new_branch.html.haml
+++ b/app/views/projects/issues/_new_branch.html.haml
@@ -41,7 +41,7 @@
= _('Create branch')
%li.divider.droplab-item-ignore
- %li.droplab-item-ignore.prepend-left-8.append-right-8.prepend-top-16
+ %li.droplab-item-ignore.gl-ml-3.gl-mr-3.prepend-top-16
- if can_create_confidential_merge_request?
#js-forked-project{ data: { namespace_path: @project.namespace.full_path, project_path: @project.full_path, new_fork_path: new_project_fork_path(@project), help_page_path: help_page_path('user/project/merge_requests') } }
.form-group
diff --git a/app/views/projects/issues/import_csv/_button.html.haml b/app/views/projects/issues/import_csv/_button.html.haml
index 07c34b51037..7119b22daef 100644
--- a/app/views/projects/issues/import_csv/_button.html.haml
+++ b/app/views/projects/issues/import_csv/_button.html.haml
@@ -1,22 +1,16 @@
- type = local_assigns.fetch(:type, :icon)
+- can_edit = can?(current_user, :admin_project, @project)
-- if @project.jira_issues_import_feature_flag_enabled?
- .dropdown.btn-group
- %button.btn.rounded-right.text-center{ class: ('has-tooltip' if type == :icon), title: (_('Import issues') if type == :icon),
- data: { toggle: 'dropdown' }, 'aria-label' => _('Import issues'), 'aria-haspopup' => 'true', 'aria-expanded' => 'false' }
- - if type == :icon
- = sprite_icon('import')
- - else
- = _('Import issues')
- %ul.dropdown-menu
- %li
- %button.btn{ data: { toggle: 'modal', target: '.issues-import-modal' } }
- = _('Import CSV')
- %li= link_to _('Import from Jira'), project_import_jira_path(@project)
-- else
- %button.csv-import-button.btn{ title: _('Import CSV'), class: ('has-tooltip' if type == :icon),
- data: { toggle: 'modal', target: '.issues-import-modal' } }
+.dropdown.btn-group
+ %button.btn.rounded-right.text-center{ class: ('has-tooltip' if type == :icon), title: (_('Import issues') if type == :icon),
+ data: { toggle: 'dropdown' }, 'aria-label' => _('Import issues'), 'aria-haspopup' => 'true', 'aria-expanded' => 'false' }
- if type == :icon
= sprite_icon('import')
- else
- = _('Import CSV')
+ = _('Import issues')
+ %ul.dropdown-menu
+ %li
+ %button{ data: { toggle: 'modal', target: '.issues-import-modal' } }
+ = _('Import CSV')
+ - if can_edit
+ %li= link_to _('Import from Jira'), project_import_jira_path(@project)
diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml
index 0aef4e39466..826a62e39d3 100644
--- a/app/views/projects/issues/index.html.haml
+++ b/app/views/projects/issues/index.html.haml
@@ -6,11 +6,10 @@
= content_for :meta_tags do
= auto_discovery_link_tag(:atom, safe_params.merge(rss_url_options).to_h, title: "#{@project.name} issues")
-- if @project.jira_issues_import_feature_flag_enabled?
- .js-projects-issues-root{ data: { can_edit: can?(current_user, :admin_project, @project).to_s,
- is_jira_configured: @project.jira_service.present?.to_s,
- issues_path: project_issues_path(@project),
- project_path: @project.full_path } }
+.js-projects-issues-root{ data: { can_edit: can?(current_user, :admin_project, @project).to_s,
+ is_jira_configured: @project.jira_service.present?.to_s,
+ issues_path: project_issues_path(@project),
+ project_path: @project.full_path } }
- if project_issues(@project).exists?
.top-area
diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml
index 525eb4b90c1..4d24b510267 100644
--- a/app/views/projects/issues/show.html.haml
+++ b/app/views/projects/issues/show.html.haml
@@ -11,6 +11,7 @@
- can_create_issue = show_new_issue_link?(@project)
= render_if_exists "projects/issues/alert_blocked", issue: @issue, current_user: current_user
+= render_if_exists "projects/issues/alert_moved_from_service_desk", issue: @issue
.detail-page-header
.detail-page-header-body
diff --git a/app/views/projects/logs/empty_logs.html.haml b/app/views/projects/logs/empty_logs.html.haml
index 52598e0be8d..afae2d30f6e 100644
--- a/app/views/projects/logs/empty_logs.html.haml
+++ b/app/views/projects/logs/empty_logs.html.haml
@@ -11,4 +11,4 @@
%p.state-description.text-center
= s_('Logs|To see the logs, deploy your code to an environment.')
.text-center
- = link_to s_('Environments|Learn about environments'), help_page_path('ci/environments'), class: 'btn btn-success'
+ = link_to s_('Environments|Learn about environments'), help_page_path('ci/environments/index.md'), class: 'btn btn-success'
diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml
index 7e146a36d84..90bc2504cb4 100644
--- a/app/views/projects/merge_requests/show.html.haml
+++ b/app/views/projects/merge_requests/show.html.haml
@@ -100,3 +100,5 @@
= render "projects/commit/change", type: 'revert', commit: @merge_request.merge_commit, title: @merge_request.title
- if @merge_request.can_be_cherry_picked?
= render "projects/commit/change", type: 'cherry-pick', commit: @merge_request.merge_commit, title: @merge_request.title
+
+#js-review-bar
diff --git a/app/views/projects/milestones/_form.html.haml b/app/views/projects/milestones/_form.html.haml
index e1797e6db2a..a3083fa2081 100644
--- a/app/views/projects/milestones/_form.html.haml
+++ b/app/views/projects/milestones/_form.html.haml
@@ -12,8 +12,8 @@
.col-form-label.col-sm-2
= f.label :description, _('Description')
.col-sm-10
- = render layout: 'projects/md_preview', locals: { url: preview_markdown_path(@project) } do
- = render 'projects/zen', f: f, attr: :description, classes: 'qa-milestone-description note-textarea', placeholder: _('Write milestone description...')
+ = render layout: 'shared/md_preview', locals: { url: preview_markdown_path(@project) } do
+ = render 'shared/zen', f: f, attr: :description, classes: 'qa-milestone-description note-textarea', placeholder: _('Write milestone description...')
= render 'shared/notes/hints'
.clearfix
.error-alert
diff --git a/app/views/projects/milestones/_milestone.html.haml b/app/views/projects/milestones/_milestone.html.haml
index bc82b45f902..00937c5bf73 100644
--- a/app/views/projects/milestones/_milestone.html.haml
+++ b/app/views/projects/milestones/_milestone.html.haml
@@ -1,5 +1,4 @@
= render 'shared/milestones/milestone',
- milestone_path: project_milestone_path(milestone.project, milestone),
issues_path: project_issues_path(milestone.project, milestone_title: milestone.title),
merge_requests_path: project_merge_requests_path(milestone.project, milestone_title: milestone.title),
milestone: milestone
diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml
index c18af6a267b..81a778f76f4 100644
--- a/app/views/projects/new.html.haml
+++ b/app/views/projects/new.html.haml
@@ -7,9 +7,13 @@
.project-edit-container.prepend-top-default
.project-edit-errors
= render 'projects/errors'
- .row
+
+ - if experiment_enabled?(:new_create_project_ui)
+ .js-experiment-new-project-creation{ data: { is_ci_cd_available: ci_cd_projects_available?, has_errors: @project.errors.any? } }
+
+ .row{ 'v-cloak': experiment_enabled?(:new_create_project_ui) }
.col-lg-3.profile-settings-sidebar
- %h4.prepend-top-0
+ %h4.gl-mt-0
= _('New project')
%p
- among_other_things_link = link_to _('among other things'), help_page_path("user/project/index.md", anchor: "projects-features"), target: '_blank'
@@ -32,15 +36,15 @@
.col-lg-9.js-toggle-container
%ul.nav.nav-tabs.nav-links.gitlab-tabs{ role: 'tablist' }
%li.nav-item{ role: 'presentation' }
- %a.nav-link.active{ href: '#blank-project-pane', id: 'blank-project-tab', data: { toggle: 'tab', track_label: 'blank_project', track_event: "click_tab", track_value: "" }, role: 'tab' }
+ %a.nav-link.active{ href: '#blank-project-pane', id: 'blank-project-tab', data: { toggle: 'tab', experiment_track_label: 'blank_project' }, role: 'tab' }
%span.d-none.d-sm-block= s_('ProjectsNew|Blank project')
%span.d-block.d-sm-none= s_('ProjectsNew|Blank')
%li.nav-item{ role: 'presentation' }
- %a.nav-link{ href: '#create-from-template-pane', id: 'create-from-template-tab', data: { toggle: 'tab', track_label: 'create_from_template', track_event: "click_tab", track_value: "" }, role: 'tab' }
+ %a.nav-link{ href: '#create-from-template-pane', id: 'create-from-template-tab', data: { toggle: 'tab', experiment_track_label: 'create_from_template' }, role: 'tab' }
%span.d-none.d-sm-block.qa-project-create-from-template-tab= s_('ProjectsNew|Create from template')
%span.d-block.d-sm-none= s_('ProjectsNew|Template')
%li.nav-item{ role: 'presentation' }
- %a.nav-link{ href: '#import-project-pane', id: 'import-project-tab', data: { toggle: 'tab', track_label: 'import_project', track_event: "click_tab", track_value: "" }, role: 'tab' }
+ %a.nav-link{ href: '#import-project-pane', id: 'import-project-tab', data: { toggle: 'tab', experiment_track_label: 'import_project' }, role: 'tab' }
%span.d-none.d-sm-block= s_('ProjectsNew|Import project')
%span.d-block.d-sm-none= s_('ProjectsNew|Import')
= render_if_exists 'projects/new_ci_cd_only_project_tab', active_tab: active_tab
diff --git a/app/views/projects/pipeline_schedules/_form.html.haml b/app/views/projects/pipeline_schedules/_form.html.haml
index 396e5da87bc..20cf2ed63b5 100644
--- a/app/views/projects/pipeline_schedules/_form.html.haml
+++ b/app/views/projects/pipeline_schedules/_form.html.haml
@@ -37,7 +37,7 @@
= f.label :active, s_('PipelineSchedules|Activated'), class: 'label-bold'
%div
= f.check_box :active, required: false, value: @schedule.active?
- = _('Active')
+ = f.label :active, _('Active'), class: 'gl-font-weight-normal'
.footer-block.row-content-block
= f.submit _('Save pipeline schedule'), class: 'btn btn-success', tabindex: 3
= link_to _('Cancel'), pipeline_schedules_path(@project), class: 'btn btn-cancel'
diff --git a/app/views/projects/pipelines/_with_tabs.html.haml b/app/views/projects/pipelines/_with_tabs.html.haml
index e39f543d42e..92edde034a6 100644
--- a/app/views/projects/pipelines/_with_tabs.html.haml
+++ b/app/views/projects/pipelines/_with_tabs.html.haml
@@ -1,19 +1,20 @@
- test_reports_enabled = Feature.enabled?(:junit_pipeline_view, @project)
-- dag_pipeline_tab_enabled = Feature.enabled?(:dag_pipeline_tab)
+- dag_pipeline_tab_enabled = Feature.enabled?(:dag_pipeline_tab, @project, default_enabled: false)
.tabs-holder
%ul.pipelines-tabs.nav-links.no-top.no-bottom.mobile-separator.nav.nav-tabs
%li.js-pipeline-tab-link
= link_to project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-pipeline', action: 'pipelines', toggle: 'tab' }, class: 'pipeline-tab' do
= _('Pipeline')
- %li.js-builds-tab-link
- = link_to builds_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-builds', action: 'builds', toggle: 'tab' }, class: 'builds-tab' do
- = _('Jobs')
- %span.badge.badge-pill.js-builds-counter= pipeline.total_size
- if dag_pipeline_tab_enabled
%li.js-dag-tab-link
= link_to dag_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-dag', action: 'dag', toggle: 'tab' }, class: 'dag-tab' do
= _('DAG')
+ %span.badge-pill.gl-badge.sm.gl-bg-blue-500.gl-text-white.gl-ml-2= _('Beta')
+ %li.js-builds-tab-link
+ = link_to builds_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-builds', action: 'builds', toggle: 'tab' }, class: 'builds-tab' do
+ = _('Jobs')
+ %span.badge.badge-pill.js-builds-counter= pipeline.total_size
- if @pipeline.failed_builds.present?
%li.js-failures-tab-link
= link_to failures_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-failures', action: 'failures', toggle: 'tab' }, class: 'failures-tab' do
@@ -82,6 +83,7 @@
- if dag_pipeline_tab_enabled
#js-tab-dag.tab-pane
+ #js-pipeline-dag-vue{ data: { pipeline_data_path: dag_project_pipeline_path(@project, @pipeline) } }
#js-tab-tests.tab-pane
#js-pipeline-tests-detail
diff --git a/app/views/projects/pipelines/charts.html.haml b/app/views/projects/pipelines/charts.html.haml
index 7496ca97d56..55f1b9098c3 100644
--- a/app/views/projects/pipelines/charts.html.haml
+++ b/app/views/projects/pipelines/charts.html.haml
@@ -1,4 +1,4 @@
-- page_title _('CI / CD Charts')
+- page_title _('CI / CD Analytics')
#js-project-pipelines-charts-app{ data: { counts: @counts, success_ratio: success_ratio(@counts),
times_chart: { labels: @charts[:pipeline_times].labels, values: @charts[:pipeline_times].pipeline_times },
diff --git a/app/views/projects/pipelines/index.html.haml b/app/views/projects/pipelines/index.html.haml
index 64789c7c263..fa4a77a692a 100644
--- a/app/views/projects/pipelines/index.html.haml
+++ b/app/views/projects/pipelines/index.html.haml
@@ -4,6 +4,7 @@
#pipelines-list-vue{ data: { endpoint: project_pipelines_path(@project, format: :json),
project_id: @project.id,
+ params: params.to_json,
"help-page-path" => help_page_path('ci/quick_start/README'),
"help-auto-devops-path" => help_page_path('topics/autodevops/index.md'),
"empty-state-svg-path" => image_path('illustrations/pipelines_empty.svg'),
diff --git a/app/views/projects/project_templates/_built_in_templates.html.haml b/app/views/projects/project_templates/_built_in_templates.html.haml
index a583eb39eb3..eb41a3e0785 100644
--- a/app/views/projects/project_templates/_built_in_templates.html.haml
+++ b/app/views/projects/project_templates/_built_in_templates.html.haml
@@ -11,7 +11,7 @@
.controls.d-flex.align-items-center
%a.btn.btn-default.append-right-10{ href: template.preview, rel: 'noopener noreferrer', target: '_blank', data: { track_label: "template_preview", track_property: template.name, track_event: "click_button", track_value: "" } }
= _("Preview")
- %label.btn.btn-success.template-button.choose-template.append-bottom-0{ for: template.name }
+ %label.btn.btn-success.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: "" } }
%span{ data: { qa_selector: 'use_template_button' } }
= _("Use template")
diff --git a/app/views/projects/protected_branches/show.html.haml b/app/views/projects/protected_branches/show.html.haml
index 1012ceefe93..ffaf118a5e3 100644
--- a/app/views/projects/protected_branches/show.html.haml
+++ b/app/views/projects/protected_branches/show.html.haml
@@ -2,7 +2,7 @@
.row.prepend-top-default.append-bottom-default
.col-lg-3
- %h4.prepend-top-0.ref-name
+ %h4.gl-mt-0.ref-name
= @protected_ref.name
.col-lg-9
diff --git a/app/views/projects/protected_tags/show.html.haml b/app/views/projects/protected_tags/show.html.haml
index 86629f1753b..6f4535a0b3f 100644
--- a/app/views/projects/protected_tags/show.html.haml
+++ b/app/views/projects/protected_tags/show.html.haml
@@ -2,7 +2,7 @@
.row.prepend-top-default.append-bottom-default
.col-lg-3
- %h4.prepend-top-0.ref-name
+ %h4.gl-mt-0.ref-name
= @protected_ref.name
.col-lg-9.edit_protected_tag
diff --git a/app/views/projects/registry/repositories/_tag.html.haml b/app/views/projects/registry/repositories/_tag.html.haml
deleted file mode 100644
index 9594c9184a2..00000000000
--- a/app/views/projects/registry/repositories/_tag.html.haml
+++ /dev/null
@@ -1,33 +0,0 @@
-%tr.tag
- %td
- = escape_once(tag.name)
- = clipboard_button(text: "#{tag.location}")
- %td
- - if tag.revision
- %span.has-tooltip{ title: "#{tag.revision}" }
- = tag.short_revision
- - else
- \-
- %td
- - if tag.total_size
- = number_to_human_size(tag.total_size)
- &middot;
- = pluralize(tag.layers.size, "layer")
- - else
- .light
- \-
- %td
- - if tag.created_at
- = time_ago_with_tooltip tag.created_at
- - else
- .light
- \-
- - if can?(current_user, :update_container_image, @project)
- %td.content
- .controls.d-none.d-sm-block.float-right
- = link_to project_registry_repository_tag_path(@project, tag.repository, tag.name),
- method: :delete,
- class: 'btn btn-remove has-tooltip',
- title: 'Remove tag',
- data: { confirm: 'Are you sure you want to delete this tag?' } do
- = icon('trash cred')
diff --git a/app/views/projects/registry/repositories/index.html.haml b/app/views/projects/registry/repositories/index.html.haml
index 650e63eb406..8540ce30060 100644
--- a/app/views/projects/registry/repositories/index.html.haml
+++ b/app/views/projects/registry/repositories/index.html.haml
@@ -5,7 +5,6 @@
.row.registry-placeholder.prepend-bottom-10
.col-12
#js-container-registry{ data: { endpoint: project_container_registry_index_path(@project),
- settings_path: project_settings_ci_cd_path(@project),
expiration_policy: @project.container_expiration_policy.to_json,
"help_page_path" => help_page_path('user/packages/container_registry/index'),
"two_factor_auth_help_link" => help_page_path('user/profile/account/two_factor_authentication'),
@@ -16,5 +15,5 @@
"registry_host_url_with_port" => escape_once(registry_config.host_port),
"expiration_policy_help_page_path" => help_page_path('user/packages/container_registry/index', anchor: 'expiration-policy'),
"garbage_collection_help_page_path" => help_page_path('administration/packages/container_registry', anchor: 'container-registry-garbage-collection'),
- "is_admin": current_user&.admin,
+ "is_admin": current_user&.admin.to_s,
character_error: @character_error.to_s } }
diff --git a/app/views/projects/services/_form.html.haml b/app/views/projects/services/_form.html.haml
index 3f91bdc4266..e6761807409 100644
--- a/app/views/projects/services/_form.html.haml
+++ b/app/views/projects/services/_form.html.haml
@@ -1,6 +1,6 @@
.row.prepend-top-default.append-bottom-default
.col-lg-4
- %h4.prepend-top-0
+ %h4.gl-mt-0
= @service.title
- [true, false].each do |value|
- hide_class = 'd-none' if @service.operating? != value
@@ -13,6 +13,7 @@
= form_for(@service, as: :service, url: scoped_integration_path(@service), method: :put, html: { class: 'gl-show-field-errors integration-settings-form js-integration-settings-form', data: { 'can-test' => @service.can_test?, 'test-url' => test_project_service_path(@project, @service) } }) do |form|
= render 'shared/service_settings', form: form, service: @service
.footer-block.row-content-block
+ %input{ id: 'services_redirect_to', type: 'hidden', name: 'redirect_to', value: request.referrer }
= service_save_button
&nbsp;
= link_to _('Cancel'), project_settings_integrations_path(@project), class: 'btn btn-cancel'
diff --git a/app/views/projects/services/alerts/_help.html.haml b/app/views/projects/services/alerts/_help.html.haml
index ef3ab8d8d04..4b09d1d9d0e 100644
--- a/app/views/projects/services/alerts/_help.html.haml
+++ b/app/views/projects/services/alerts/_help.html.haml
@@ -1,3 +1,6 @@
.js-alerts-service-settings{ data: { activated: @service.activated?.to_s,
form_path: scoped_integration_path(@service),
- authorization_key: @service.token, url: @service.url || _('<namespace / project>'), learn_more_url: 'https://docs.gitlab.com/ee/user/project/integrations/generic_alerts.html' } }
+ authorization_key: @service.token,
+ url: @service.url || _('<namespace / project>'),
+ alerts_setup_url: help_page_path('user/project/integrations/generic_alerts.html', anchor: 'setting-up-generic-alerts'),
+ alerts_usage_url: help_page_path('user/project/operations/alert_management.html') } }
diff --git a/app/views/projects/services/prometheus/_show.html.haml b/app/views/projects/services/prometheus/_show.html.haml
index 926671845c7..728a52f024f 100644
--- a/app/views/projects/services/prometheus/_show.html.haml
+++ b/app/views/projects/services/prometheus/_show.html.haml
@@ -1,6 +1,6 @@
.row
.col-lg-3
- %h4.prepend-top-0
+ %h4.gl-mt-0
= s_('PrometheusService|Metrics')
.row.append-bottom-default.prometheus-metrics-monitoring.js-prometheus-metrics-monitoring
diff --git a/app/views/projects/settings/access_tokens/index.html.haml b/app/views/projects/settings/access_tokens/index.html.haml
index 07784dce677..092f9c2333c 100644
--- a/app/views/projects/settings/access_tokens/index.html.haml
+++ b/app/views/projects/settings/access_tokens/index.html.haml
@@ -6,7 +6,7 @@
.row.prepend-top-default
.col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
+ %h4.gl-mt-0
= page_title
%p
= _('You can generate an access token scoped to this project for each application to use the GitLab API.')
diff --git a/app/views/projects/settings/ci_cd/_form.html.haml b/app/views/projects/settings/ci_cd/_form.html.haml
index b50f712922f..a1809cecafb 100644
--- a/app/views/projects/settings/ci_cd/_form.html.haml
+++ b/app/views/projects/settings/ci_cd/_form.html.haml
@@ -4,7 +4,7 @@
= form_errors(@project)
%fieldset.builds-feature
.form-group
- %h5.prepend-top-0
+ %h5.gl-mt-0
= _("Git strategy for pipelines")
%p
= _("Choose between <code>clone</code> or <code>fetch</code> to get the recent application code").html_safe
diff --git a/app/views/projects/settings/integrations/show.html.haml b/app/views/projects/settings/integrations/show.html.haml
index 4372763fcf7..e7a509abc8b 100644
--- a/app/views/projects/settings/integrations/show.html.haml
+++ b/app/views/projects/settings/integrations/show.html.haml
@@ -12,6 +12,8 @@
.gl-alert-actions
= link_to _('Go to Webhooks'), project_hooks_path(@project), class: 'btn gl-alert-action btn-info new-gl-button'
-%h4= s_('Integrations')
-%p= s_('Integrations allow you to integrate GitLab with other applications')
+%h4= _('Integrations')
+- integrations_link_start = '<a href="%{url}">'.html_safe % { url: help_page_url('user/project/integrations/overview') }
+- webhooks_link_start = '<a href="%{url}">'.html_safe % { url: project_hooks_path(@project) }
+%p= _("%{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}.").html_safe % { integrations_link_start: integrations_link_start, webhooks_link_start: webhooks_link_start, link_end: '</a>'.html_safe }
= render 'shared/integrations/index', integrations: @services
diff --git a/app/views/projects/settings/operations/_external_dashboard.html.haml b/app/views/projects/settings/operations/_external_dashboard.html.haml
deleted file mode 100644
index 08d50a336fd..00000000000
--- a/app/views/projects/settings/operations/_external_dashboard.html.haml
+++ /dev/null
@@ -1,3 +0,0 @@
-.js-operation-settings{ data: { operations_settings_endpoint: project_settings_operations_path(@project),
- external_dashboard: { url: metrics_external_dashboard_url,
- help_page_path: help_page_path('user/project/operations/linking_to_an_external_dashboard') } } }
diff --git a/app/views/projects/settings/operations/_incidents.html.haml b/app/views/projects/settings/operations/_incidents.html.haml
index 92fffa42b73..3b1b0a00380 100644
--- a/app/views/projects/settings/operations/_incidents.html.haml
+++ b/app/views/projects/settings/operations/_incidents.html.haml
@@ -9,7 +9,7 @@
= _('Expand')
%p
= _('Action to take when receiving an alert.')
- = link_to help_page_path('user/project/integrations/prometheus', anchor: 'taking-action-on-an-alert-ultimate') do
+ = link_to help_page_path('user/project/integrations/prometheus', anchor: 'taking-action-on-incidents-ultimate') do
= _('More information')
.settings-content
= form_for @project, url: project_settings_operations_path(@project), method: :patch do |f|
diff --git a/app/views/projects/settings/operations/_metrics_dashboard.html.haml b/app/views/projects/settings/operations/_metrics_dashboard.html.haml
new file mode 100644
index 00000000000..edbada8444a
--- /dev/null
+++ b/app/views/projects/settings/operations/_metrics_dashboard.html.haml
@@ -0,0 +1,5 @@
+.js-operation-settings{ data: { operations_settings_endpoint: project_settings_operations_path(@project),
+ help_page: help_page_path('user/project/operations/dashboard_settings'),
+ external_dashboard: { url: metrics_external_dashboard_url,
+ help_page: help_page_path('user/project/operations/linking_to_an_external_dashboard') },
+ dashboard_timezone: { setting: metrics_dashboard_timezone.upcase } } }
diff --git a/app/views/projects/settings/operations/show.html.haml b/app/views/projects/settings/operations/show.html.haml
index ee47d70171b..9e4fbf81ca4 100644
--- a/app/views/projects/settings/operations/show.html.haml
+++ b/app/views/projects/settings/operations/show.html.haml
@@ -5,7 +5,7 @@
= render 'projects/settings/operations/incidents'
= render 'projects/settings/operations/error_tracking'
= render 'projects/settings/operations/prometheus', service: prometheus_service if Feature.enabled?(:settings_operations_prometheus_service)
-= render 'projects/settings/operations/external_dashboard'
+= render 'projects/settings/operations/metrics_dashboard'
= render 'projects/settings/operations/grafana_integration'
= render_if_exists 'projects/settings/operations/tracing'
= render_if_exists 'projects/settings/operations/status_page'
diff --git a/app/views/projects/snippets/_actions.html.haml b/app/views/projects/snippets/_actions.html.haml
index 41c9bac0102..6aedab36e1b 100644
--- a/app/views/projects/snippets/_actions.html.haml
+++ b/app/views/projects/snippets/_actions.html.haml
@@ -14,7 +14,7 @@
= link_to _('Submit as spam'), mark_as_spam_project_snippet_path(@project, @snippet), method: :post, class: 'btn btn-grouped btn-spam', title: _('Submit as spam')
- if can?(current_user, :create_snippet, @project) || can?(current_user, :update_snippet, @snippet)
.d-block.d-sm-none.dropdown
- %button.btn.btn-default.btn-block.append-bottom-0.prepend-top-5{ data: { toggle: "dropdown" } }
+ %button.btn.btn-default.btn-block.gl-mb-0.prepend-top-5{ data: { toggle: "dropdown" } }
= _('Options')
= icon('caret-down')
.dropdown-menu.dropdown-menu-full-width
diff --git a/app/views/projects/tags/_tag.html.haml b/app/views/projects/tags/_tag.html.haml
index da693a15ec2..79a00b00fa6 100644
--- a/app/views/projects/tags/_tag.html.haml
+++ b/app/views/projects/tags/_tag.html.haml
@@ -3,10 +3,10 @@
%li.flex-row.allow-wrap
.row-main-content
= icon('tag')
- = link_to tag.name, project_tag_path(@project, tag.name), class: 'item-title ref-name prepend-left-4'
+ = link_to tag.name, project_tag_path(@project, tag.name), class: 'item-title ref-name gl-ml-2'
- if protected_tag?(@project, tag)
- %span.badge.badge-success.prepend-left-4
+ %span.badge.badge-success.gl-ml-2
= s_('TagsPage|protected')
- if tag.message.present?
@@ -22,7 +22,7 @@
- if release
.text-secondary
- = icon('rocket')
+ = sprite_icon("rocket", size: 12)
= _("Release")
= link_to release.name, project_releases_path(@project, anchor: release.tag), class: 'tag-release-link'
- if release.description.present?
diff --git a/app/views/projects/tags/new.html.haml b/app/views/projects/tags/new.html.haml
index 1b3b0972744..5aabfdd022a 100644
--- a/app/views/projects/tags/new.html.haml
+++ b/app/views/projects/tags/new.html.haml
@@ -46,8 +46,8 @@
- replacements = { releases_page_link_start: releases_page_link_start, docs_link_start: docs_link_start, link_end: link_end }
= s_('TagsPage|Optionally, create a public Release of your project, based on this tag. Release notes are displayed on the %{releases_page_link_start}Releases%{link_end} page. %{docs_link_start}More information%{link_end}').html_safe % replacements
- = render layout: 'projects/md_preview', locals: { url: preview_markdown_path(@project), referenced_users: true } do
- = render 'projects/zen', attr: :release_description, classes: 'note-textarea', placeholder: s_('TagsPage|Write your release notes or drag files here…'), current_text: @release_description
+ = render layout: 'shared/md_preview', locals: { url: preview_markdown_path(@project), referenced_users: true } do
+ = render 'shared/zen', attr: :release_description, classes: 'note-textarea', placeholder: s_('TagsPage|Write your release notes or drag files here…'), current_text: @release_description
= render 'shared/notes/hints'
.form-actions
= button_tag s_('TagsPage|Create tag'), class: 'btn btn-success'
diff --git a/app/views/projects/tags/releases/edit.html.haml b/app/views/projects/tags/releases/edit.html.haml
index 40d886ff1af..a3746808440 100644
--- a/app/views/projects/tags/releases/edit.html.haml
+++ b/app/views/projects/tags/releases/edit.html.haml
@@ -10,8 +10,8 @@
= form_for(@release, method: :put, url: project_tag_release_path(@project, @tag.name),
html: { class: 'common-note-form release-form js-quick-submit' }) do |f|
- = render layout: 'projects/md_preview', locals: { url: preview_markdown_path(@project), referenced_users: true } do
- = render 'projects/zen', f: f, attr: :description, classes: 'note-textarea', placeholder: "Write your release notes or drag files here…"
+ = render layout: 'shared/md_preview', locals: { url: preview_markdown_path(@project), referenced_users: true } do
+ = render 'shared/zen', f: f, attr: :description, classes: 'note-textarea', placeholder: "Write your release notes or drag files here…"
= render 'shared/notes/hints'
.error-alert
.prepend-top-default
diff --git a/app/views/projects/triggers/_index.html.haml b/app/views/projects/triggers/_index.html.haml
index 55a9234f01a..4ca070cb162 100644
--- a/app/views/projects/triggers/_index.html.haml
+++ b/app/views/projects/triggers/_index.html.haml
@@ -96,6 +96,6 @@
%p.light
With webhook:
- %pre.append-bottom-0
+ %pre.gl-mb-0
:plain
#{builds_trigger_url(@project.id, ref: 'REF_NAME')}?token=TOKEN&variables[RUN_NIGHTLY_BUILD]=true
diff --git a/app/views/projects/triggers/edit.html.haml b/app/views/projects/triggers/edit.html.haml
index 0f74d733c06..e287f05fe6a 100644
--- a/app/views/projects/triggers/edit.html.haml
+++ b/app/views/projects/triggers/edit.html.haml
@@ -2,6 +2,6 @@
.row.prepend-top-default.append-bottom-default
.col-lg-12
- %h4.prepend-top-0
+ %h4.gl-mt-0
Update trigger
= render "form", btn_text: "Save trigger"
diff --git a/app/views/projects/wikis/_form.html.haml b/app/views/projects/wikis/_form.html.haml
deleted file mode 100644
index d29abfa937d..00000000000
--- a/app/views/projects/wikis/_form.html.haml
+++ /dev/null
@@ -1,72 +0,0 @@
-- form_classes = 'wiki-form common-note-form prepend-top-default js-quick-submit'
-- form_classes += ' js-new-wiki-page' unless @page.persisted?
-
-= form_for [@project.namespace.becomes(Namespace), @project, @page], method: @page.persisted? ? :put : :post,
- html: { class: form_classes },
- data: { uploads_path: uploads_path } do |f|
- = form_errors(@page, truncate: :title)
-
- - if @page.persisted?
- = f.hidden_field :last_commit_sha, value: @page.last_commit_sha
-
- .form-group.row
- .col-sm-12= f.label :title, class: 'control-label-full-width'
- .col-sm-12
- = f.text_field :title, class: 'form-control qa-wiki-title-textbox', value: @page.title, required: true, autofocus: !@page.persisted?, placeholder: s_('Wiki|Page title')
- %span.d-inline-block.mw-100.prepend-top-5
- = icon('lightbulb-o')
- - if @page.persisted?
- = s_("WikiEditPageTip|Tip: You can move this page by adding the path to the beginning of the title.")
- = link_to icon('question-circle'), help_page_path('user/project/wiki/index', anchor: 'moving-a-wiki-page'),
- target: '_blank', rel: 'noopener noreferrer'
- - else
- = s_("WikiNewPageTip|Tip: You can specify the full path for the new file. We will automatically create any missing directories.")
- = succeed '.' do
- = link_to _('Learn more'), help_page_path('user/project/wiki/index', anchor: 'creating-a-new-wiki-page'),
- target: '_blank', rel: 'noopener noreferrer'
- .form-group.row
- .col-sm-12= f.label :format, class: 'control-label-full-width'
- .col-sm-12
- .select-wrapper
- = f.select :format, options_for_select(ProjectWiki::MARKUPS, {selected: @page.format}), {}, class: 'form-control select-control'
- = icon('chevron-down')
-
- .form-group.row
- .col-sm-12= f.label :content, class: 'control-label-full-width'
- .col-sm-12
- = render layout: 'projects/md_preview', locals: { url: project_wiki_preview_markdown_path(@project, @page.slug) } do
- = render 'projects/zen', f: f, attr: :content, classes: 'note-textarea qa-wiki-content-textarea', placeholder: s_("WikiPage|Write your content or drag files here…")
- = render 'shared/notes/hints'
-
- .clearfix
- .error-alert
-
- .form-text.text-muted
- = succeed '.' do
- - case @page.format.to_s
- - when 'rdoc'
- - link_example = '{Link title}[link:page-slug]'
- - when 'asciidoc'
- - link_example = 'link:page-slug[Link title]'
- - when 'org'
- - link_example = '[[page-slug]]'
- - else
- - link_example = '[Link Title](page-slug)'
- = (s_('WikiMarkdownTip|To link to a (new) page, simply type <code class="js-markup-link-example">%{link_example}</code>') % { link_example: link_example }).html_safe
- = succeed '.' do
- - markdown_link = link_to s_("WikiMarkdownDocs|documentation"), help_page_path('user/markdown', anchor: 'wiki-specific-markdown')
- = (s_("WikiMarkdownDocs|More examples are in the %{docs_link}") % { docs_link: markdown_link }).html_safe
-
- .form-group.row
- .col-sm-12= f.label :commit_message, class: 'control-label-full-width'
- .col-sm-12= f.text_field :message, class: 'form-control qa-wiki-message-textbox', rows: 18, value: nil
-
- .form-actions
- - if @page && @page.persisted?
- = f.submit _("Save changes"), class: 'btn-success btn qa-save-changes-button'
- .float-right
- = link_to _("Cancel"), project_wiki_path(@project, @page), class: 'btn btn-cancel btn-grouped'
- - else
- = f.submit s_("Wiki|Create page"), class: 'btn-success btn qa-create-page-button rspec-create-page-button'
- .float-right
- = link_to _("Cancel"), project_wiki_path(@project, :home), class: 'btn btn-cancel'
diff --git a/app/views/projects/wikis/_main_links.html.haml b/app/views/projects/wikis/_main_links.html.haml
deleted file mode 100644
index 2e1e176c42a..00000000000
--- a/app/views/projects/wikis/_main_links.html.haml
+++ /dev/null
@@ -1,9 +0,0 @@
-- if (@page && @page.persisted?)
- - if can?(current_user, :create_wiki, @project)
- = link_to project_wikis_new_path(@project), class: "add-new-wiki btn btn-success", role: "button" do
- = s_("Wiki|New page")
- = link_to project_wiki_history_path(@project, @page), class: "btn", role: "button" do
- = s_("Wiki|Page history")
- - if can?(current_user, :create_wiki, @project) && @page.latest? && @valid_encoding
- = link_to project_wiki_edit_path(@project, @page), class: "btn js-wiki-edit", role: "button" do
- = _("Edit")
diff --git a/app/views/projects/wikis/_pages_wiki_page.html.haml b/app/views/projects/wikis/_pages_wiki_page.html.haml
deleted file mode 100644
index c156f8cbf50..00000000000
--- a/app/views/projects/wikis/_pages_wiki_page.html.haml
+++ /dev/null
@@ -1,6 +0,0 @@
-%li
- = link_to wiki_page.title, project_wiki_path(@project, wiki_page)
- %small (#{wiki_page.format})
- .float-right
- - if wiki_page.last_version
- %small= (s_("Last edited %{date}") % { date: time_ago_with_tooltip(wiki_page.last_version.authored_date) }).html_safe
diff --git a/app/views/projects/wikis/_sidebar.html.haml b/app/views/projects/wikis/_sidebar.html.haml
deleted file mode 100644
index 2b8da83b126..00000000000
--- a/app/views/projects/wikis/_sidebar.html.haml
+++ /dev/null
@@ -1,22 +0,0 @@
-%aside.right-sidebar.right-sidebar-expanded.wiki-sidebar.js-wiki-sidebar.js-right-sidebar{ data: { "offset-top" => "50", "spy" => "affix" } }
- .sidebar-container
- .block.wiki-sidebar-header.append-bottom-default.w-100
- %a.gutter-toggle.float-right.d-block.d-sm-block.d-md-none.js-sidebar-wiki-toggle{ href: "#" }
- = icon('angle-double-right')
-
- - git_access_url = project_wikis_git_access_path(@project)
- = link_to git_access_url, class: active_nav_link?(path: 'wikis#git_access') ? 'active' : '' do
- = icon('cloud-download', class: 'append-right-5')
- %span= _("Clone repository")
-
- .blocks-container
- .block.block-first.w-100
- - if @sidebar_page
- = render_wiki_content(@sidebar_page)
- - else
- %ul.wiki-pages
- = render @sidebar_wiki_entries, context: 'sidebar'
- .block.w-100
- - if @sidebar_limited
- = link_to project_wikis_pages_path(@project), class: 'btn btn-block' do
- = s_("Wiki|View All Pages")
diff --git a/app/views/projects/wikis/_sidebar_wiki_page.html.haml b/app/views/projects/wikis/_sidebar_wiki_page.html.haml
deleted file mode 100644
index 769d869bd53..00000000000
--- a/app/views/projects/wikis/_sidebar_wiki_page.html.haml
+++ /dev/null
@@ -1,3 +0,0 @@
-%li{ class: active_when(params[:id] == wiki_page.slug) }
- = link_to project_wiki_path(@project, wiki_page) do
- = wiki_page.human_title
diff --git a/app/views/projects/wikis/_wiki_page.html.haml b/app/views/projects/wikis/_wiki_page.html.haml
deleted file mode 100644
index c84d06dad02..00000000000
--- a/app/views/projects/wikis/_wiki_page.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-= render "#{context}_wiki_page", wiki_page: wiki_page
diff --git a/app/views/projects/wikis/edit.html.haml b/app/views/projects/wikis/edit.html.haml
deleted file mode 100644
index 9ccf5acfefc..00000000000
--- a/app/views/projects/wikis/edit.html.haml
+++ /dev/null
@@ -1,31 +0,0 @@
-- @content_class = "limit-container-width" unless fluid_layout
-- add_to_breadcrumbs _("Wiki"), project_wiki_path(@project, @page)
-- breadcrumb_title @page.persisted? ? _("Edit") : _("New")
-- page_title @page.persisted? ? _("Edit") : _("New"), @page.human_title, _("Wiki")
-
-= wiki_page_errors(@error)
-
-.wiki-page-header.top-area.has-sidebar-toggle.flex-column.flex-lg-row
- %button.btn.btn-default.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" }
- = icon('angle-double-left')
-
- .nav-text
- %h2.wiki-page-title
- - if @page.persisted?
- = link_to @page.human_title, project_wiki_path(@project, @page)
- %span.light
- &middot;
- = s_("Wiki|Edit Page")
- - else
- = s_("Wiki|Create New Page")
-
- .nav-controls.pb-md-3.pb-lg-0
- - if @page.persisted?
- = link_to project_wiki_history_path(@project, @page), class: "btn" do
- = s_("Wiki|Page history")
- - if can?(current_user, :admin_wiki, @project)
- #delete-wiki-modal-wrapper{ data: { delete_wiki_url: project_wiki_path(@project, @page), page_title: @page.human_title } }
-
-= render 'form', uploads_path: wiki_attachment_upload_url
-
-= render 'sidebar'
diff --git a/app/views/projects/wikis/git_access.html.haml b/app/views/projects/wikis/git_access.html.haml
index 72c9f45779a..208dedc988b 100644
--- a/app/views/projects/wikis/git_access.html.haml
+++ b/app/views/projects/wikis/git_access.html.haml
@@ -8,10 +8,10 @@
.git-access-header.w-100.d-flex.flex-column.justify-content-center
%span
= _("Clone repository")
- %strong= @project_wiki.full_path
+ %strong= @wiki.full_path
.pt-3.pt-lg-0.w-100
- = render "shared/clone_panel", project: @project_wiki
+ = render "shared/clone_panel", project: @wiki
.wiki-git-access
%h3= s_("WikiClone|Install Gollum")
@@ -22,8 +22,8 @@
%h3= s_("WikiClone|Clone your wiki")
%pre.dark
:preserve
- git clone #{ content_tag(:span, h(default_url_to_repo(@project_wiki)), class: 'clone')}
- cd #{h @project_wiki.path}
+ git clone #{ content_tag(:span, h(default_url_to_repo(@wiki)), class: 'clone')}
+ cd #{h @wiki.path}
%h3= s_("WikiClone|Start Gollum and edit locally")
%pre.dark
@@ -34,4 +34,4 @@
>> Maximum connections set to 1024
>> Listening on 0.0.0.0:4567, CTRL+C to stop
-= render 'sidebar'
+= render 'shared/wikis/sidebar'
diff --git a/app/views/projects/wikis/history.html.haml b/app/views/projects/wikis/history.html.haml
deleted file mode 100644
index d3a55c53649..00000000000
--- a/app/views/projects/wikis/history.html.haml
+++ /dev/null
@@ -1,42 +0,0 @@
-- page_title _("History"), @page.human_title, _("Wiki")
-
-.wiki-page-header.top-area.has-sidebar-toggle.flex-column.flex-lg-row
- %button.btn.btn-default.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" }
- = icon('angle-double-left')
-
- .nav-text
- %h2.wiki-page-title
- = link_to @page.human_title, project_wiki_path(@project, @page)
- %span.light
- &middot;
- = _("History")
-
-.table-holder
- %table.table
- %thead
- %tr
- %th= s_("Wiki|Page version")
- %th= _("Author")
- %th= _("Commit Message")
- %th= _("Last updated")
- %th= _("Format")
- %tbody
- - @page_versions.each_with_index do |version, index|
- - commit = version
- %tr
- %td
- = link_to project_wiki_path_with_version(@project, @page,
- commit.id, index == 0) do
- = truncate_sha(commit.id)
- %td
- = commit.author_name
- %td
- = commit.message
- %td
- #{time_ago_with_tooltip(version.authored_date)}
- %td
- %strong
- = version.format
-= paginate @page_versions, theme: 'gitlab'
-
-= render 'sidebar'
diff --git a/app/views/projects/wikis/pages.html.haml b/app/views/projects/wikis/pages.html.haml
deleted file mode 100644
index d9dcd8f9acd..00000000000
--- a/app/views/projects/wikis/pages.html.haml
+++ /dev/null
@@ -1,32 +0,0 @@
-- add_to_breadcrumbs "Wiki", project_wiki_path(@project, :home)
-- breadcrumb_title s_("Wiki|Pages")
-- page_title s_("Wiki|Pages"), _("Wiki")
-- sort_title = wiki_sort_title(params[:sort])
-
-.wiki-page-header.top-area.flex-column.flex-lg-row
-
- .nav-text.flex-fill
- %h2.wiki-page-title
- = s_("Wiki|Wiki Pages")
-
- .nav-controls.pb-md-3.pb-lg-0
- = link_to project_wikis_git_access_path(@project), class: 'btn' do
- = icon('cloud-download')
- = _("Clone repository")
-
- .dropdown.inline.wiki-sort-dropdown
- .btn-group{ role: 'group' }
- .btn-group{ role: 'group' }
- %button.dropdown-toggle{ type: 'button', data: { toggle: 'dropdown', display: 'static' }, class: 'btn btn-default' }
- = sort_title
- = icon('chevron-down')
- %ul.dropdown-menu.dropdown-menu-right.dropdown-menu-selectable.dropdown-menu-sort
- %li
- = sortable_item(s_("Wiki|Title"), project_wikis_pages_path(@project, sort: ProjectWiki::TITLE_ORDER), sort_title)
- = sortable_item(s_("Wiki|Created date"), project_wikis_pages_path(@project, sort: ProjectWiki::CREATED_AT_ORDER), sort_title)
- = wiki_sort_controls(@project, params[:sort], params[:direction])
-
-%ul.wiki-pages-list.content-list
- = render @wiki_entries, context: 'pages'
-
-= paginate @wiki_pages, theme: 'gitlab'
diff --git a/app/views/projects/wikis/show.html.haml b/app/views/projects/wikis/show.html.haml
deleted file mode 100644
index 74798311c2e..00000000000
--- a/app/views/projects/wikis/show.html.haml
+++ /dev/null
@@ -1,32 +0,0 @@
-- @content_class = "limit-container-width" unless fluid_layout
-- breadcrumb_title @page.human_title
-- wiki_breadcrumb_dropdown_links(@page.slug)
-- page_title @page.human_title, _("Wiki")
-- add_to_breadcrumbs _("Wiki"), project_wiki_path(@project, :home)
-
-.wiki-page-header.top-area.has-sidebar-toggle.flex-column.flex-lg-row
- %button.btn.btn-default.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" }
- = icon('angle-double-left')
-
- .nav-text.flex-fill
- %h2.wiki-page-title= @page.human_title
- %span.wiki-last-edit-by
- - if @page.last_version
- = (_("Last edited by %{name}") % { name: "<strong>#{@page.last_version.author_name}</strong>" }).html_safe
- #{time_ago_with_tooltip(@page.last_version.authored_date)}
-
- .nav-controls.pb-md-3.pb-lg-0
- = render 'main_links'
-
-- if @page.historical?
- .warning_message
- = s_("WikiHistoricalPage|This is an old version of this page.")
- - most_recent_link = link_to s_("WikiHistoricalPage|most recent version"), project_wiki_path(@project, @page)
- - history_link = link_to s_("WikiHistoricalPage|history"), project_wiki_history_path(@project, @page)
- = (s_("WikiHistoricalPage|You can view the %{most_recent_link} or browse the %{history_link}.") % { most_recent_link: most_recent_link, history_link: history_link }).html_safe
-
-.prepend-top-default.append-bottom-default
- .md{ data: { qa_selector: 'wiki_page_content' } }
- = render_wiki_content(@page)
-
-= render 'sidebar'
diff --git a/app/views/registrations/experience_levels/show.html.haml b/app/views/registrations/experience_levels/show.html.haml
new file mode 100644
index 00000000000..24b87790e18
--- /dev/null
+++ b/app/views/registrations/experience_levels/show.html.haml
@@ -0,0 +1,28 @@
+- page_title _('What’s your experience level?')
+
+.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 very familiar with the basics of project management and DevOps.')
+ = link_to _('Show me everything'), 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 project management and DevOps.')
+ = link_to _('Show me more advanced stuff'), users_sign_up_experience_level_path(experience_level: :experienced, namespace_path: params[:namespace_path]), method: :patch, class: 'stretched-link'
diff --git a/app/views/shared/_broadcast_message.html.haml b/app/views/shared/_broadcast_message.html.haml
index b809696cccb..3e889900981 100644
--- a/app/views/shared/_broadcast_message.html.haml
+++ b/app/views/shared/_broadcast_message.html.haml
@@ -1,4 +1,6 @@
-%div{ class: "broadcast-#{message.broadcast_type}-message #{opts[:preview] && 'preview'} js-broadcast-notification-#{message.id} d-flex",
+- is_banner = message.broadcast_type == 'banner'
+
+%div{ class: "broadcast-message #{'alert-warning' if is_banner} broadcast-#{message.broadcast_type}-message #{opts[:preview] && 'preview'} js-broadcast-notification-#{message.id} gl-display-flex",
style: broadcast_message_style(message), dir: 'auto' }
.flex-grow-1.text-right.pr-2
= sprite_icon('bullhorn', size: 16, css_class: 'vertical-align-text-top')
diff --git a/app/views/shared/_choose_avatar_button.html.haml b/app/views/shared/_choose_avatar_button.html.haml
index 0d46d047134..caf2bdce899 100644
--- a/app/views/shared/_choose_avatar_button.html.haml
+++ b/app/views/shared/_choose_avatar_button.html.haml
@@ -1,4 +1 @@
-%button.btn.js-choose-avatar-button{ type: 'button' }= _("Choose file…")
-%span.file_name.js-avatar-filename= _("No file chosen")
-= f.file_field :avatar, class: "js-avatar-input hidden"
-.form-text.text-muted= _("The maximum file size allowed is 200KB.")
+= render 'shared/file_picker_button', f: f, field: :avatar, help_text: _("The maximum file size allowed is 200KB.")
diff --git a/app/views/shared/_custom_attributes.html.haml b/app/views/shared/_custom_attributes.html.haml
new file mode 100644
index 00000000000..966ab8e3cb1
--- /dev/null
+++ b/app/views/shared/_custom_attributes.html.haml
@@ -0,0 +1,12 @@
+- return unless custom_attributes.present?
+
+.card
+ .card-header
+ = link_to(_('Custom Attributes'), help_page_path('api/custom_attributes.md'))
+ %ul.content-list
+ - custom_attributes.each do |custom_attribute|
+ %li
+ %span.light
+ = custom_attribute.key
+ %strong
+ = custom_attribute.value
diff --git a/app/views/shared/_field.html.haml b/app/views/shared/_field.html.haml
index 4f416c483f2..2480014ea42 100644
--- a/app/views/shared/_field.html.haml
+++ b/app/views/shared/_field.html.haml
@@ -3,6 +3,7 @@
- value = @service.send(name)
- type = field[:type]
- placeholder = field[:placeholder]
+- autocomplete = field[:autocomplete]
- required = field[:required]
- choices = field[:choices]
- default_choice = field[:default_choice]
@@ -15,13 +16,13 @@
= form.label name, title, class: "col-form-label col-sm-2"
.col-sm-10
- if type == 'text'
- = form.text_field name, class: "form-control", placeholder: placeholder, required: required, data: { qa_selector: "#{name.downcase.gsub('\s', '')}_field" }
+ = form.text_field name, class: "form-control", autocomplete: autocomplete, placeholder: placeholder, required: required, data: { qa_selector: "#{name.downcase.gsub('\s', '')}_field" }
- elsif type == 'textarea'
= form.text_area name, rows: 5, class: "form-control", placeholder: placeholder, required: required
- elsif type == 'checkbox'
= form.check_box name
- elsif type == 'select'
- = form.select name, options_for_select(choices, value ? value : default_choice), {}, { class: "form-control"}
+ = form.select name, options_for_select(choices, value ? value : default_choice), {}, { class: "form-control"} # rubocop:disable Style/RedundantCondition
- elsif type == 'password'
= form.password_field name, autocomplete: "new-password", placeholder: placeholder, class: "form-control", required: value.blank? && required, data: { qa_selector: "#{name.downcase.gsub('\s', '')}_field" }
- if help
diff --git a/app/views/shared/_file_highlight.html.haml b/app/views/shared/_file_highlight.html.haml
index 18f51f0c0c8..b9952d6832f 100644
--- a/app/views/shared/_file_highlight.html.haml
+++ b/app/views/shared/_file_highlight.html.haml
@@ -1,4 +1,4 @@
-.file-content.code.js-syntax-highlight.qa-file-content
+.file-content.code.js-syntax-highlight
.line-numbers
- if blob.data.present?
- link_icon = icon('link')
diff --git a/app/views/shared/_file_picker_button.html.haml b/app/views/shared/_file_picker_button.html.haml
new file mode 100644
index 00000000000..7c9a3bd3d31
--- /dev/null
+++ b/app/views/shared/_file_picker_button.html.haml
@@ -0,0 +1,6 @@
+%span.js-filepicker
+ %button.btn.js-filepicker-button{ type: 'button' }= _("Choose file…")
+ %span.file_name.js-filepicker-filename= _("No file chosen")
+ = f.file_field field, class: "js-filepicker-input hidden"
+ - if help_text.present?
+ .form-text.text-muted= help_text
diff --git a/app/views/shared/_group_form.html.haml b/app/views/shared/_group_form.html.haml
index 019b2ef89a4..09b9cd448bb 100644
--- a/app/views/shared/_group_form.html.haml
+++ b/app/views/shared/_group_form.html.haml
@@ -6,7 +6,7 @@
.form-group.group-name-holder.col-sm-12
= f.label :name, class: 'label-bold' do
= _("Group name")
- = f.text_field :name, placeholder: _('My Awesome Group'), class: 'form-control input-lg',
+ = f.text_field :name, placeholder: _('My Awesome Group'), class: 'js-autofill-group-name form-control input-lg',
required: true,
title: _('Please fill in a descriptive name for your group.'),
autofocus: true
@@ -22,7 +22,7 @@
- if parent
%strong= parent.full_path + '/'
= f.hidden_field :parent_id
- = f.text_field :path, placeholder: _('my-awesome-group'), class: 'form-control js-validate-group-path',
+ = f.text_field :path, placeholder: _('my-awesome-group'), class: 'form-control js-validate-group-path js-autofill-group-path',
autofocus: local_assigns[:autofocus] || false, required: true,
pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS,
title: _('Please choose a group URL with no special characters.'),
diff --git a/app/views/shared/_md_preview.html.haml b/app/views/shared/_md_preview.html.haml
new file mode 100644
index 00000000000..f5f24b2f0ce
--- /dev/null
+++ b/app/views/shared/_md_preview.html.haml
@@ -0,0 +1,36 @@
+- referenced_users = local_assigns.fetch(:referenced_users, nil)
+
+- if defined?(@merge_request) && @merge_request.discussion_locked?
+ .issuable-note-warning
+ = sprite_icon('lock', size: 16, css_class: 'icon')
+ %span
+ = _('This merge request is locked.')
+ = _('Only project members can comment.')
+
+.md-area.position-relative
+ .md-header
+ %ul.nav.nav-tabs.nav-links.clearfix
+ %li.md-header-tab.active
+ %button.js-md-write-button{ tabindex: -1 }
+ = _("Write")
+ %li.md-header-tab
+ %button.js-md-preview-button{ tabindex: -1 }
+ = _("Preview")
+
+ %li.md-header-toolbar.active
+ = render 'shared/blob/markdown_buttons', show_fullscreen_button: true
+
+ .md-write-holder
+ = yield
+ .md.md-preview-holder.js-md-preview.hide{ data: { url: url } }
+ .referenced-commands.hide
+
+ - if referenced_users
+ .referenced-users.hide
+ %span
+ = icon("exclamation-triangle")
+ You are about to add
+ %strong
+ %span.js-referenced-users-count 0
+ people
+ to the discussion. Proceed with caution.
diff --git a/app/views/shared/_namespace_storage_limit_alert.html.haml b/app/views/shared/_namespace_storage_limit_alert.html.haml
new file mode 100644
index 00000000000..95f27cde15b
--- /dev/null
+++ b/app/views/shared/_namespace_storage_limit_alert.html.haml
@@ -0,0 +1,26 @@
+- return unless current_user
+
+- payload = namespace_storage_alert(namespace)
+- return if payload.empty?
+
+- alert_level = payload[:alert_level]
+- root_namespace = payload[:root_namespace]
+
+- style = namespace_storage_alert_style(alert_level)
+- icon = namespace_storage_alert_icon(alert_level)
+- link = namespace_storage_usage_link(root_namespace)
+
+%div{ class: [classes, 'js-namespace-storage-alert'] }
+ .gl-pt-5.gl-pb-3
+ .gl-alert{ class: "gl-alert-#{style}", role: 'alert' }
+ = sprite_icon(icon, css_class: "gl-icon gl-alert-icon")
+ .gl-alert-title
+ %h4.gl-alert-title= payload[:usage_message]
+ - if alert_level != :error
+ %button.js-namespace-storage-alert-dismiss.gl-alert-dismiss.gl-cursor-pointer{ type: 'button', 'aria-label' => _('Dismiss'), data: { id: root_namespace.id, level: alert_level } }
+ = sprite_icon('close', size: 16, css_class: 'gl-icon')
+ .gl-alert-body
+ = payload[:explanation_message]
+ - if link
+ .gl-alert-actions
+ = link_to(_('Manage storage usage'), link, class: "btn gl-alert-action btn-md gl-button btn-#{style}")
diff --git a/app/views/shared/_new_merge_request_checkbox.html.haml b/app/views/shared/_new_merge_request_checkbox.html.haml
index 24c0dfe247f..6bc6d0943c9 100644
--- a/app/views/shared/_new_merge_request_checkbox.html.haml
+++ b/app/views/shared/_new_merge_request_checkbox.html.haml
@@ -1,4 +1,4 @@
-.form-check.prepend-top-8
+.form-check.gl-mt-3
- nonce = SecureRandom.hex
= check_box_tag 'create_merge_request', 1, true, class: 'js-create-merge-request form-check-input', id: "create_merge_request-#{nonce}"
= label_tag "create_merge_request-#{nonce}", class: 'form-check-label' do
diff --git a/app/views/shared/_promo.html.haml b/app/views/shared/_promo.html.haml
index 0f31b60d8d3..855f6b9c1f4 100644
--- a/app/views/shared/_promo.html.haml
+++ b/app/views/shared/_promo.html.haml
@@ -1,5 +1,5 @@
.gitlab-promo
- = link_to 'Homepage', promo_url
- = link_to 'Blog', promo_url + '/blog/'
+ = link_to _('Homepage'), promo_url
+ = link_to _('Blog'), promo_url + '/blog/'
= link_to '@gitlab', 'https://twitter.com/gitlab'
- = link_to 'Requests', 'https://gitlab.com/gitlab-org/gitlab-foss/blob/master/CONTRIBUTING.md#feature-proposals'
+ = link_to _('Requests'), 'https://gitlab.com/gitlab-org/gitlab-foss/blob/master/CONTRIBUTING.md#feature-proposals'
diff --git a/app/views/shared/_service_settings.html.haml b/app/views/shared/_service_settings.html.haml
index a9203459914..92b86c6fec1 100644
--- a/app/views/shared/_service_settings.html.haml
+++ b/app/views/shared/_service_settings.html.haml
@@ -1,5 +1,4 @@
= form_errors(@service)
-- trigger_events = Feature.enabled?(:integration_form_refactor) ? ServiceEventSerializer.new(service: @service).represent(@service.configurable_events).to_json : []
- if lookup_context.template_exists?('help', "projects/services/#{@service.to_param}", true)
= render "projects/services/#{@service.to_param}/help", subject: @service
@@ -10,9 +9,9 @@
.service-settings
.js-vue-integration-settings{ data: { show_active: @service.show_active_box?.to_s, activated: (@service.active || @service.new_record?).to_s, type: @service.to_param, merge_request_events: @service.merge_requests_events.to_s,
-commit_events: @service.commit_events.to_s, enable_comments: @service.comment_on_event_enabled.to_s, comment_detail: @service.comment_detail, trigger_events: trigger_events } }
+commit_events: @service.commit_events.to_s, enable_comments: @service.comment_on_event_enabled.to_s, comment_detail: @service.comment_detail, trigger_events: trigger_events_for_service, fields: fields_for_service } }
- - if @service.configurable_events.present? && !@service.is_a?(JiraService) && Feature.disabled?(:integration_form_refactor)
+ - if show_service_trigger_events?
.form-group.row
%label.col-form-label.col-sm-2= _('Trigger')
@@ -33,5 +32,6 @@ commit_events: @service.commit_events.to_s, enable_comments: @service.comment_on
%p.text-muted
= @service.class.event_description(event)
- - @service.global_fields.each do |field|
- = render 'shared/field', form: form, field: field
+ - unless integration_form_refactor?
+ - @service.global_fields.each do |field|
+ = render 'shared/field', form: form, field: field
diff --git a/app/views/shared/_visibility_level.html.haml b/app/views/shared/_visibility_level.html.haml
index 2f42a877beb..84ce40e240c 100644
--- a/app/views/shared/_visibility_level.html.haml
+++ b/app/views/shared/_visibility_level.html.haml
@@ -2,7 +2,7 @@
.form-group.visibility-level-setting
- if with_label
- = f.label :visibility_level, _('Visibility level'), class: 'label-bold append-bottom-0'
+ = f.label :visibility_level, _('Visibility level'), class: 'label-bold gl-mb-0'
%p
= _('Who can see this group?')
- visibility_docs_path = help_page_path('public_access/public_access')
diff --git a/app/views/shared/_visibility_radios.html.haml b/app/views/shared/_visibility_radios.html.haml
index 80532c9187b..90b12557bc8 100644
--- a/app/views/shared/_visibility_radios.html.haml
+++ b/app/views/shared/_visibility_radios.html.haml
@@ -1,8 +1,7 @@
-- Gitlab::VisibilityLevel.values.each do |level|
- - disallowed = disallowed_visibility_level?(form_model, level)
- - restricted = restricted_visibility_levels.include?(level)
- - next if disallowed || restricted
+- available_visibility_levels = available_visibility_levels(form_model)
+- selected_level = snippets_selected_visibility_level(available_visibility_levels, selected_level)
+- 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.label "#{model_method}_#{level}", class: 'form-check-label' do
diff --git a/app/views/shared/_zen.html.haml b/app/views/shared/_zen.html.haml
new file mode 100644
index 00000000000..8dd0e5a92a7
--- /dev/null
+++ b/app/views/shared/_zen.html.haml
@@ -0,0 +1,19 @@
+- @gfm_form = true
+- current_text ||= nil
+- supports_autocomplete = local_assigns.fetch(:supports_autocomplete, true)
+- supports_quick_actions = local_assigns.fetch(:supports_quick_actions, false)
+- qa_selector = local_assigns.fetch(:qa_selector, '')
+.zen-backdrop
+ - classes << ' js-gfm-input js-autosize markdown-area'
+ - if defined?(f) && f
+ = f.text_area attr,
+ class: classes,
+ placeholder: placeholder,
+ dir: 'auto',
+ data: { supports_quick_actions: supports_quick_actions,
+ supports_autocomplete: supports_autocomplete,
+ qa_selector: qa_selector }
+ - else
+ = text_area_tag attr, current_text, class: classes, placeholder: placeholder
+ %a.zen-control.zen-control-leave.js-zen-leave.gl-text-gray-700{ href: "#" }
+ = sprite_icon('compress', size: 16)
diff --git a/app/views/shared/access_tokens/_created_container.html.haml b/app/views/shared/access_tokens/_created_container.html.haml
index f11ef1e01de..c5a18d98b89 100644
--- a/app/views/shared/access_tokens/_created_container.html.haml
+++ b/app/views/shared/access_tokens/_created_container.html.haml
@@ -1,5 +1,5 @@
.created-personal-access-token-container
- %h5.prepend-top-0
+ %h5.gl-mt-0
= _('Your new %{type}') % { type: type }
.form-group
.input-group
diff --git a/app/views/shared/access_tokens/_form.html.haml b/app/views/shared/access_tokens/_form.html.haml
index cb7f907308f..680626f7880 100644
--- a/app/views/shared/access_tokens/_form.html.haml
+++ b/app/views/shared/access_tokens/_form.html.haml
@@ -1,7 +1,7 @@
- title = local_assigns.fetch(:title, _('Add a %{type}') % { type: type })
- prefix = local_assigns.fetch(:prefix, :personal_access_token)
-%h5.prepend-top-0
+%h5.gl-mt-0
= title
%p.profile-settings-content
= _("Enter the name of your application, and we'll return a unique %{type}.") % { type: type }
diff --git a/app/views/shared/blob/_markdown_buttons.html.haml b/app/views/shared/blob/_markdown_buttons.html.haml
new file mode 100644
index 00000000000..c1ffdc7184a
--- /dev/null
+++ b/app/views/shared/blob/_markdown_buttons.html.haml
@@ -0,0 +1,13 @@
+.md-header-toolbar.active
+ = markdown_toolbar_button({ icon: "bold", data: { "md-tag" => "**" }, title: _("Add bold text") })
+ = markdown_toolbar_button({ icon: "italic", data: { "md-tag" => "*" }, title: _("Add italic text") })
+ = markdown_toolbar_button({ icon: "quote", data: { "md-tag" => "> ", "md-prepend" => true }, title: _("Insert a quote") })
+ = markdown_toolbar_button({ icon: "code", data: { "md-tag" => "`", "md-block" => "```" }, title: _("Insert code") })
+ = markdown_toolbar_button({ icon: "link", data: { "md-tag" => "[{text}](url)", "md-select" => "url" }, title: _("Add a link") })
+ = markdown_toolbar_button({ icon: "list-bulleted", data: { "md-tag" => "- ", "md-prepend" => true }, title: _("Add a bullet list") })
+ = markdown_toolbar_button({ icon: "list-numbered", data: { "md-tag" => "1. ", "md-prepend" => true }, title: _("Add a numbered list") })
+ = markdown_toolbar_button({ icon: "list-task", data: { "md-tag" => "- [ ] ", "md-prepend" => true }, title: _("Add a task list") })
+ = markdown_toolbar_button({ icon: "table", data: { "md-tag" => "| header | header |\n| ------ | ------ |\n| cell | cell |\n| cell | cell |", "md-prepend" => true }, title: _("Add a table") })
+ - if show_fullscreen_button
+ %button.toolbar-btn.toolbar-fullscreen-btn.js-zen-enter.has-tooltip{ type: "button", tabindex: -1, "aria-label": "Go full screen", title: _("Go full screen"), data: { container: "body" } }
+ = sprite_icon("screen-full")
diff --git a/app/views/shared/boards/_show.html.haml b/app/views/shared/boards/_show.html.haml
index cf42ac3dd37..902b6d19f82 100644
--- a/app/views/shared/boards/_show.html.haml
+++ b/app/views/shared/boards/_show.html.haml
@@ -20,20 +20,31 @@
#board-app.boards-app.position-relative{ "v-cloak" => "true", data: board_data, ":class" => "{ 'is-compact': detailIssueVisible }" }
= render 'shared/issuable/search_bar', type: :boards, board: board
- .boards-list.w-100.py-3.px-2.text-nowrap{ data: { qa_selector: "boards_list" } }
- .boards-app-loading.w-100.text-center{ "v-if" => "loading" }
- = icon("spinner spin 2x")
- %board{ "v-cloak" => "true",
- "v-for" => "list in state.lists",
- "ref" => "board",
+ - if Feature.enabled?(:boards_with_swimlanes, current_board_parent)
+ %board-content{ "v-cloak" => "true",
+ "ref" => "board_content",
+ ":lists" => "state.lists",
":can-admin-list" => can_admin_list,
":group-id" => group_id,
- ":list" => "list",
":disabled" => "disabled",
":issue-link-base" => "issueLinkBase",
":root-path" => "rootPath",
- ":board-id" => "boardId",
- ":key" => "list.id" }
+ ":board-id" => "boardId" }
+ - else
+ .boards-list.w-100.py-3.px-2.text-nowrap{ data: { qa_selector: "boards_list" } }
+ .boards-app-loading.w-100.text-center{ "v-if" => "loading" }
+ = icon("spinner spin 2x")
+ %board{ "v-cloak" => "true",
+ "v-for" => "list in state.lists",
+ "ref" => "board",
+ ":can-admin-list" => can_admin_list,
+ ":group-id" => group_id,
+ ":list" => "list",
+ ":disabled" => "disabled",
+ ":issue-link-base" => "issueLinkBase",
+ ":root-path" => "rootPath",
+ ":board-id" => "boardId",
+ ":key" => "list.id" }
= render "shared/boards/components/sidebar", group: group
= render_if_exists 'shared/boards/components/board_settings_sidebar'
- if @project
diff --git a/app/views/shared/deploy_keys/_form.html.haml b/app/views/shared/deploy_keys/_form.html.haml
index 1944c293be1..94742d96af7 100644
--- a/app/views/shared/deploy_keys/_form.html.haml
+++ b/app/views/shared/deploy_keys/_form.html.haml
@@ -30,5 +30,5 @@
= deploy_keys_project_form.label :can_push do
= deploy_keys_project_form.check_box :can_push
%strong= _('Write access allowed')
- %p.light.append-bottom-0
+ %p.light.gl-mb-0
= _('Allow this key to push to repository as well? (Default only allows pull access.)')
diff --git a/app/views/shared/deploy_keys/_index.html.haml b/app/views/shared/deploy_keys/_index.html.haml
index f28e745f4c5..358075b9e44 100644
--- a/app/views/shared/deploy_keys/_index.html.haml
+++ b/app/views/shared/deploy_keys/_index.html.haml
@@ -7,7 +7,7 @@
%p
= _('Deploy keys allow read-only or read-write (if enabled) access to your repository. Deploy keys can be used for CI, staging or production servers. You can create a deploy key or add an existing one.')
.settings-content
- %h5.prepend-top-0
+ %h5.gl-mt-0
= _('Create a new deploy key for this project')
= render @deploy_keys.form_partial_path
%hr
diff --git a/app/views/shared/deploy_keys/_project_group_form.html.haml b/app/views/shared/deploy_keys/_project_group_form.html.haml
index 8edd1d9deb8..4e569050827 100644
--- a/app/views/shared/deploy_keys/_project_group_form.html.haml
+++ b/app/views/shared/deploy_keys/_project_group_form.html.haml
@@ -7,7 +7,7 @@
= f.label :key, class: "label-bold"
= f.text_area :key, class: "form-control", rows: 5, required: true
.form-group.row
- %p.light.append-bottom-0
+ %p.light.gl-mb-0
= _('Paste a machine public key here. Read more about how to generate it')
= link_to "here", help_page_path("ssh/README")
@@ -17,7 +17,7 @@
= deploy_keys_project_form.check_box :can_push
%strong= _('Write access allowed')
.form-group.row
- %p.light.append-bottom-0
+ %p.light.gl-mb-0
= _('Allow this key to push to repository as well? (Default only allows pull access.)')
.form-group.row
diff --git a/app/views/shared/deploy_tokens/_index.html.haml b/app/views/shared/deploy_tokens/_index.html.haml
index b0c9c72dfaa..8203b378297 100644
--- a/app/views/shared/deploy_tokens/_index.html.haml
+++ b/app/views/shared/deploy_tokens/_index.html.haml
@@ -10,7 +10,7 @@
.settings-content
- if @new_deploy_token.persisted?
= render 'shared/deploy_tokens/new_deploy_token', deploy_token: @new_deploy_token
- %h5.prepend-top-0
+ %h5.gl-mt-0
= s_('DeployTokens|Add a deploy token')
= render 'shared/deploy_tokens/form', group_or_project: group_or_project, token: @new_deploy_token, presenter: @deploy_tokens
%hr
diff --git a/app/views/shared/deploy_tokens/_new_deploy_token.html.haml b/app/views/shared/deploy_tokens/_new_deploy_token.html.haml
index f295fa82192..a9728dc841f 100644
--- a/app/views/shared/deploy_tokens/_new_deploy_token.html.haml
+++ b/app/views/shared/deploy_tokens/_new_deploy_token.html.haml
@@ -1,6 +1,6 @@
.qa-created-deploy-token-section.created-deploy-token-container.info-well
.well-segment
- %h5.prepend-top-0
+ %h5.gl-mt-0
= s_('DeployTokens|Your New Deploy Token')
.form-group
diff --git a/app/views/shared/empty_states/_snippets.html.haml b/app/views/shared/empty_states/_snippets.html.haml
index efd9bceedc5..db8da50d868 100644
--- a/app/views/shared/empty_states/_snippets.html.haml
+++ b/app/views/shared/empty_states/_snippets.html.haml
@@ -3,7 +3,7 @@
.row.empty-state.mt-0
.col-12
.svg-content
- = image_tag 'illustrations/snippets_empty.svg'
+ = image_tag 'illustrations/snippets_empty.svg', data: { qa_selector: 'svg_content' }
.text-content.text-center.pt-0
- if current_user
%h4
@@ -12,7 +12,7 @@
= s_('SnippetsEmptyState|Store, share, and embed small pieces of code and text.')
.mt-2<
- if button_path
- = link_to s_('SnippetsEmptyState|New snippet'), button_path, class: 'btn btn-success', title: s_('SnippetsEmptyState|New snippet'), id: 'new_snippet_link'
+ = link_to s_('SnippetsEmptyState|New snippet'), button_path, class: 'btn btn-success', title: s_('SnippetsEmptyState|New snippet'), id: 'new_snippet_link', data: { qa_selector: 'create_first_snippet_link' }
= link_to s_('SnippetsEmptyState|Documentation'), help_page_path('user/snippets.md'), class: 'btn btn-default', title: s_('SnippetsEmptyState|Documentation')
- else
%h4.text-center= s_('SnippetsEmptyState|There are no snippets to show.')
diff --git a/app/views/shared/empty_states/_wikis.html.haml b/app/views/shared/empty_states/_wikis.html.haml
index 73eedcc1dc9..ff5ee801969 100644
--- a/app/views/shared/empty_states/_wikis.html.haml
+++ b/app/views/shared/empty_states/_wikis.html.haml
@@ -1,30 +1,31 @@
- layout_path = 'shared/empty_states/wikis_layout'
+- messages = wiki_empty_state_messages(@wiki)
-- if can?(current_user, :create_wiki, @project)
- - create_path = project_wiki_path(@project, params[:id], { view: 'create' })
+- if can?(current_user, :create_wiki, @wiki.container)
+ - create_path = wiki_page_path(@wiki, params[:id], view: 'create')
- create_link = link_to s_('WikiEmpty|Create your first page'), create_path, class: 'btn btn-success qa-create-first-page-link', title: s_('WikiEmpty|Create your first page')
= render layout: layout_path, locals: { image_path: 'illustrations/wiki_login_empty.svg' } do
%h4.text-left
- = s_('WikiEmpty|The wiki lets you write documentation for your project')
+ = messages.dig(:writable, :title)
%p.text-left
- = s_("WikiEmpty|A wiki is where you can store all the details about your project. This can include why you've created it, its principles, how to use it, and so on.")
+ = messages.dig(:writable, :body)
= create_link
-- elsif can?(current_user, :read_issue, @project)
+- elsif @project && can?(current_user, :read_issue, @project)
- issues_link = link_to s_('WikiEmptyIssueMessage|issue tracker'), project_issues_path(@project)
- new_issue_link = link_to s_('WikiEmpty|Suggest wiki improvement'), new_project_issue_path(@project), class: 'btn btn-success', title: s_('WikiEmptyIssueMessage|Suggest wiki improvement')
= render layout: layout_path, locals: { image_path: 'illustrations/wiki_logout_empty.svg' } do
%h4
- = s_('WikiEmpty|This project has no wiki pages')
+ = messages.dig(:issuable, :title)
%p.text-left
- = s_('WikiEmptyIssueMessage|You must be a project member in order to add wiki pages. If you have suggestions for how to improve the wiki for this project, consider opening an issue in the %{issues_link}.').html_safe % { issues_link: issues_link }
+ = messages.dig(:issuable, :body).html_safe % { issues_link: issues_link }
= new_issue_link
- else
= render layout: layout_path, locals: { image_path: 'illustrations/wiki_logout_empty.svg' } do
%h4
- = s_('WikiEmpty|This project has no wiki pages')
+ = messages.dig(:readonly, :title)
%p
- = s_('WikiEmpty|You must be a project member in order to add wiki pages.')
+ = messages.dig(:readonly, :body)
diff --git a/app/views/shared/file_hooks/_index.html.haml b/app/views/shared/file_hooks/_index.html.haml
index 0e1f41bbbf6..436bd305df1 100644
--- a/app/views/shared/file_hooks/_index.html.haml
+++ b/app/views/shared/file_hooks/_index.html.haml
@@ -2,7 +2,7 @@
.row.prepend-top-default
.col-lg-4
- %h4.prepend-top-0
+ %h4.gl-mt-0
= _('File Hooks')
%p
= _('File hooks are similar to system hooks but are executed as files instead of sending data to a URL.')
diff --git a/app/views/shared/form_elements/_description.html.haml b/app/views/shared/form_elements/_description.html.haml
index 2f2e6d83f9f..77af4f09408 100644
--- a/app/views/shared/form_elements/_description.html.haml
+++ b/app/views/shared/form_elements/_description.html.haml
@@ -18,8 +18,8 @@
- if model.is_a?(Issuable)
= render 'shared/issuable/form/template_selector', issuable: model
- = render layout: 'projects/md_preview', locals: { url: preview_url, referenced_users: true } do
- = render 'projects/zen', f: form, attr: :description,
+ = render layout: 'shared/md_preview', locals: { url: preview_url, referenced_users: true } do
+ = render 'shared/zen', f: form, attr: :description,
classes: 'note-textarea qa-issuable-form-description rspec-issuable-form-description',
placeholder: placeholder,
supports_quick_actions: supports_quick_actions
diff --git a/app/views/shared/groups/_group.html.haml b/app/views/shared/groups/_group.html.haml
index 60c9c076a70..5dac400bd5e 100644
--- a/app/views/shared/groups/_group.html.haml
+++ b/app/views/shared/groups/_group.html.haml
@@ -1,28 +1,29 @@
- user = local_assigns.fetch(:user, current_user)
- access = user&.max_member_access_for_group(group.id)
-%li.group-row.py-3{ class: ('no-description' if group.description.blank?) }
- .stats
- %span
+%li.group-row.py-3.gl-align-items-center{ class: "gl-display-flex!#{' no-description' if group.description.blank?}" }
+ .avatar-container.rect-avatar.s40.gl-flex-shrink-0
+ = link_to group do
+ = group_icon(group, class: "avatar s40")
+ .gl-min-w-0.gl-flex-grow-1
+ .title
+ = link_to group.full_name, group, class: 'group-name'
+
+ - if access&.nonzero?
+ %span.user-access-role= Gitlab::Access.human_access(access)
+
+ - if group.description.present?
+ .description
+ = markdown_field(group, :description)
+
+ .stats.gl-text-gray-700.gl-flex-shrink-0
+ %span.gl-ml-5
= icon('bookmark')
= number_with_delimiter(group.projects.non_archived.count)
- %span
+ %span.gl-ml-5
= icon('users')
= number_with_delimiter(group.users.count)
- %span.visibility-icon.has-tooltip{ data: { container: 'body', placement: 'left' }, title: visibility_icon_description(group) }
+ %span.gl-ml-5.visibility-icon.has-tooltip{ data: { container: 'body', placement: 'left' }, title: visibility_icon_description(group) }
= visibility_level_icon(group.visibility_level, fw: false)
-
- .avatar-container.rect-avatar.s40
- = link_to group do
- = group_icon(group, class: "avatar s40")
- .title
- = link_to group.full_name, group, class: 'group-name'
-
- - if access&.nonzero?
- %span.user-access-role= Gitlab::Access.human_access(access)
-
- - if group.description.present?
- .description
- = markdown_field(group, :description)
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index a020a04e366..1b3ad484bcc 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -31,7 +31,7 @@
= 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.
-= render 'shared/issuable/form/metadata', issuable: issuable, form: form
+= render 'shared/issuable/form/metadata', issuable: issuable, form: form, project: project
= render_if_exists 'shared/issuable/approvals', issuable: issuable, presenter: presenter, form: form
diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml
index 34be9291f1f..d53ec4d4eeb 100644
--- a/app/views/shared/issuable/_search_bar.html.haml
+++ b/app/views/shared/issuable/_search_bar.html.haml
@@ -173,6 +173,8 @@
= render 'shared/issuable/board_create_list_dropdown', board: board
- if @project
#js-add-issues-btn.prepend-left-10{ data: { can_admin_list: can?(current_user, :admin_list, @project) } }
+ - if Feature.enabled?(:boards_with_swimlanes, @group)
+ #js-board-epics-swimlanes-toggle
#js-toggle-focus-btn
- elsif is_not_boards_modal_or_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 a1c56cdb64f..ab4bd88cfe5 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -53,7 +53,8 @@
.selectbox.hide-collapsed
= f.hidden_field 'milestone_id', value: milestone[:id], id: nil
= dropdown_tag('Milestone', options: { title: _('Assign milestone'), toggle_class: 'js-milestone-select js-extra-options', filter: true, dropdown_class: 'dropdown-menu-selectable', placeholder: _('Search milestones'), data: { show_no: true, field_name: "#{issuable_type}[milestone_id]", project_id: issuable_sidebar[:project_id], issuable_id: issuable_sidebar[:id], milestones: issuable_sidebar[:project_milestones_path], ability_name: issuable_type, issue_update: issuable_sidebar[:issuable_json_path], use_id: true, default_no: true, selected: milestone[:title], null_default: true, display: 'static' }})
-
+ - if @project.group.present?
+ = render_if_exists 'shared/issuable/iteration_select', { can_edit: can_edit_issuable, group_path: @project.group.full_path, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid], issuable_type: issuable_type }
#issuable-time-tracker.block
// Fallback while content is loading
.title.hide-collapsed
diff --git a/app/views/shared/issuable/_sidebar_assignees.html.haml b/app/views/shared/issuable/_sidebar_assignees.html.haml
index 4192ecd2238..cf239a5d04c 100644
--- a/app/views/shared/issuable/_sidebar_assignees.html.haml
+++ b/app/views/shared/issuable/_sidebar_assignees.html.haml
@@ -40,4 +40,17 @@
- data['max-select'] = dropdown_options[:data][:'max-select'] if dropdown_options[:data][:'max-select']
- options[:data].merge!(data)
- = dropdown_tag(title, options: options)
+ - if experiment_enabled?(:invite_members_version_a) && can_import_members?
+ - options[:dropdown_class] += ' dropdown-extended-height'
+ - options[:footer_content] = true
+ - options[:wrapper_class] = 'js-sidebar-assignee-dropdown'
+
+ = dropdown_tag(title, options: options) do
+ %ul.dropdown-footer-list
+ %li
+ = link_to _('Invite Members'),
+ project_project_members_path(@project),
+ title: _('Invite Members'),
+ data: { 'is-link': true, 'track-event': 'click_invite_members', 'track-label': 'edit_assignee' }
+ - else
+ = dropdown_tag(title, options: options)
diff --git a/app/views/shared/issuable/form/_metadata.html.haml b/app/views/shared/issuable/form/_metadata.html.haml
index 90a6a98235d..1389bc2ab4d 100644
--- a/app/views/shared/issuable/form/_metadata.html.haml
+++ b/app/views/shared/issuable/form/_metadata.html.haml
@@ -1,3 +1,4 @@
+- project = local_assigns.fetch(:project)
- issuable = local_assigns.fetch(:issuable)
- return unless can?(current_user, :"admin_#{issuable.to_ability_name}", issuable.project)
@@ -10,6 +11,9 @@
%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
+
.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) }
@@ -22,11 +26,11 @@
.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/weight", issuable: issuable, form: form
= render_if_exists "shared/issuable/form/merge_request_blocks", issuable: issuable, form: form
- - if has_due_date
+ - if has_due_date || issuable.supports_weight?
.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
diff --git a/app/views/shared/milestones/_deprecation_message.html.haml b/app/views/shared/milestones/_deprecation_message.html.haml
index acd90fa9178..ba5eb54f017 100644
--- a/app/views/shared/milestones/_deprecation_message.html.haml
+++ b/app/views/shared/milestones/_deprecation_message.html.haml
@@ -1,14 +1,14 @@
.banner-callout.compact.milestone-deprecation-message.js-milestone-deprecation-message.prepend-top-20
.banner-graphic= image_tag 'illustrations/milestone_removing-page.svg'
.banner-body.prepend-left-10.append-right-10
- %h5.banner-title.prepend-top-0= _('This page will be removed in a future release.')
+ %h5.banner-title.gl-mt-0= _('This page will be removed in a future release.')
%p.milestone-banner-text= _('Use group milestones to manage issues from multiple projects in the same milestone.')
= button_tag _('Promote these project milestones into a group milestone.'), class: 'btn btn-link js-popover-link text-align-left milestone-banner-link'
.milestone-banner-buttons.prepend-top-20= link_to _('Learn more'), help_page_url('user/project/milestones/index', anchor: 'promoting-project-milestones-to-group-milestones'), class: 'btn btn-default', target: '_blank'
%template.js-milestone-deprecation-message-template
.milestone-popover-body
- %ol.milestone-popover-instructions-list.append-bottom-0
+ %ol.milestone-popover-instructions-list.gl-mb-0
%li= _('Click any <strong>project name</strong> in the project list below to navigate to the project milestone.').html_safe
%li= _('Click the <strong>Promote</strong> button in the top right corner to promote it to a group milestone.').html_safe
%hr.popover-hr
diff --git a/app/views/shared/milestones/_form_dates.html.haml b/app/views/shared/milestones/_form_dates.html.haml
index 4de89d7c7a0..6dbc460d9bf 100644
--- a/app/views/shared/milestones/_form_dates.html.haml
+++ b/app/views/shared/milestones/_form_dates.html.haml
@@ -1,13 +1,13 @@
.col-md-6
.form-group.row
.col-form-label.col-sm-2
- = f.label :start_date, "Start Date"
+ = f.label :start_date, _('Start Date')
.col-sm-10
- = f.text_field :start_date, class: "datepicker form-control", placeholder: "Select start date", autocomplete: 'off'
- %a.inline.float-right.prepend-top-5.js-clear-start-date{ href: "#" } Clear start date
+ = f.text_field :start_date, class: "datepicker form-control", placeholder: _('Select start date'), autocomplete: 'off'
+ %a.inline.float-right.prepend-top-5.js-clear-start-date{ href: "#" }= _('Clear start date')
.form-group.row
.col-form-label.col-sm-2
- = f.label :due_date, "Due Date"
+ = f.label :due_date, _('Due Date')
.col-sm-10
- = f.text_field :due_date, class: "datepicker form-control", placeholder: "Select due date", autocomplete: 'off'
- %a.inline.float-right.prepend-top-5.js-clear-due-date{ href: "#" } Clear due date
+ = f.text_field :due_date, class: "datepicker form-control", placeholder: _('Select due date'), autocomplete: 'off'
+ %a.inline.float-right.prepend-top-5.js-clear-due-date{ href: "#" }= _('Clear due date')
diff --git a/app/views/shared/milestones/_header.html.haml b/app/views/shared/milestones/_header.html.haml
index 2da857261d1..99a46f1fb85 100644
--- a/app/views/shared/milestones/_header.html.haml
+++ b/app/views/shared/milestones/_header.html.haml
@@ -11,8 +11,7 @@
.milestone-buttons
- if can?(current_user, :admin_milestone, @group || @project)
- - unless milestone.legacy_group_milestone?
- = link_to _('Edit'), edit_milestone_path(milestone), class: 'btn btn-grouped'
+ = link_to _('Edit'), edit_milestone_path(milestone), class: 'btn btn-grouped'
- if milestone.project_milestone? && milestone.project.group
%button.js-promote-project-milestone-button.btn.btn-grouped{ data: { toggle: 'modal',
@@ -31,8 +30,7 @@
- else
= link_to _('Reopen milestone'), update_milestone_path(milestone, { state_event: :activate }), method: :put, class: 'btn btn-grouped btn-reopen'
- - unless milestone.legacy_group_milestone?
- = render 'shared/milestones/delete_button'
+ = render 'shared/milestones/delete_button'
%button.btn.btn-default.btn-grouped.float-right.d-block.d-sm-none.js-sidebar-toggle{ type: 'button' }
= icon('angle-double-left')
diff --git a/app/views/shared/milestones/_milestone.html.haml b/app/views/shared/milestones/_milestone.html.haml
index 9f61082d605..31505d2d9fb 100644
--- a/app/views/shared/milestones/_milestone.html.haml
+++ b/app/views/shared/milestones/_milestone.html.haml
@@ -6,39 +6,33 @@
.row
.col-sm-6
.append-bottom-5
- %strong= link_to truncate(milestone.title, length: 100), milestone_path
+ %strong= link_to truncate(milestone.title, length: 100), milestone_path(milestone)
- if @group
= " - #{milestone_type}"
- - if @project || milestone.is_a?(GlobalMilestone) || milestone.group_milestone?
- - if milestone.due_date || milestone.start_date
- .text-tertiary.append-bottom-5
- = milestone_date_range(milestone)
- - recent_releases, total_count, more_count = recent_releases_with_counts(milestone)
- - unless total_count.zero?
- .text-tertiary.append-bottom-5.milestone-release-links
- = icon('rocket')
- = n_('Release', 'Releases', total_count)
- - recent_releases.each do |release|
- = link_to release.name, project_releases_path(release.project, anchor: release.tag)
- - unless release == recent_releases.last
- &bull;
- - if total_count > recent_releases.count
+ - if milestone.due_date || milestone.start_date
+ .text-tertiary.append-bottom-5
+ = milestone_date_range(milestone)
+ - recent_releases, total_count, more_count = recent_releases_with_counts(milestone)
+ - unless total_count.zero?
+ .text-tertiary.append-bottom-5.milestone-release-links
+ = sprite_icon("rocket", size: 12)
+ = n_('Release', 'Releases', total_count)
+ - recent_releases.each do |release|
+ = link_to release.name, project_releases_path(release.project, anchor: release.tag)
+ - unless release == recent_releases.last
&bull;
- = link_to n_('%{count} more release', '%{count} more releases', more_count) % { count: more_count }, project_releases_path(milestone.project)
- %div
- = render('shared/milestone_expired', milestone: milestone)
- - if milestone.group_milestone?
- .label-badge.label-badge-blue.d-inline-block
- = milestone.group.full_name
- - if milestone.legacy_group_milestone?
- .projects
- - link_to milestone_path(milestone.milestone) do
- %span.label-badge.label-badge-blue.d-inline-block.append-bottom-5
- = dashboard ? milestone.project.full_name : milestone.project.name
- - if milestone.project
- .label-badge.label-badge-gray.d-inline-block
- = milestone.project.full_name
+ - if total_count > recent_releases.count
+ &bull;
+ = link_to n_('%{count} more release', '%{count} more releases', more_count) % { count: more_count }, project_releases_path(milestone.project)
+ %div
+ = render('shared/milestone_expired', milestone: milestone)
+ - if milestone.group_milestone?
+ .label-badge.label-badge-blue.d-inline-block
+ = milestone.group.full_name
+ - if milestone.project_milestone?
+ .label-badge.label-badge-gray.d-inline-block
+ = milestone.project.full_name
.col-sm-4.milestone-progress
= milestone_progress_bar(milestone)
@@ -49,29 +43,25 @@
.float-lg-right.light #{milestone.percent_complete}% complete
.col-sm-2
.milestone-actions.d-flex.justify-content-sm-start.justify-content-md-end
- - if @project
- - if can_admin_project_milestones? and milestone.active?
- - if can_admin_group_milestones?
- %button.js-promote-project-milestone-button.btn.btn-blank.btn-sm.btn-grouped.has-tooltip{ title: s_('Milestones|Promote to Group Milestone'),
- disabled: true,
- type: 'button',
- data: { url: promote_project_milestone_path(milestone.project, milestone),
- milestone_title: milestone.title,
- group_name: @project.group.name,
- target: '#promote-milestone-modal',
- container: 'body',
- toggle: 'modal' } }
- = sprite_icon('level-up', size: 14)
+ - if @project # if in milestones list on project level
+ - if can_admin_group_milestones?
+ %button.js-promote-project-milestone-button.btn.btn-blank.btn-sm.btn-grouped.has-tooltip{ title: s_('Milestones|Promote to Group Milestone'),
+ disabled: true,
+ type: 'button',
+ data: { url: promote_project_milestone_path(milestone.project, milestone),
+ milestone_title: milestone.title,
+ group_name: @project.group.name,
+ target: '#promote-milestone-modal',
+ container: 'body',
+ toggle: 'modal' } }
+ = sprite_icon('level-up', size: 14)
+
+ - if can?(current_user, :admin_milestone, milestone)
+ - if milestone.closed?
+ = link_to s_('Milestones|Reopen Milestone'), milestone_path(milestone, milestone: { state_event: :activate }), method: :put, class: "btn btn-sm btn-grouped btn-reopen"
+ - else
+ = link_to s_('Milestones|Close Milestone'), milestone_path(milestone, milestone: { state_event: :close }), method: :put, class: "btn btn-sm btn-grouped btn-close"
- = link_to s_('Milestones|Close Milestone'), project_milestone_path(@project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-sm btn-close btn-grouped"
- - unless milestone.active?
- = link_to s_('Milestones|Reopen Milestone'), project_milestone_path(@project, milestone, milestone: {state_event: :activate }), method: :put, class: "btn btn-grouped btn-reopen"
- - if @group
- - if can?(current_user, :admin_milestone, @group)
- - if milestone.closed?
- = link_to s_('Milestones|Reopen Milestone'), group_milestone_route(milestone, {state_event: :activate }), method: :put, class: "btn btn-sm btn-grouped btn-reopen"
- - else
- = link_to s_('Milestones|Close Milestone'), group_milestone_route(milestone, {state_event: :close }), method: :put, class: "btn btn-sm btn-grouped btn-close"
- if dashboard
.label-badge.label-badge-gray
= milestone_type
diff --git a/app/views/shared/milestones/_sidebar.html.haml b/app/views/shared/milestones/_sidebar.html.haml
index ba1629bd99a..160f6487439 100644
--- a/app/views/shared/milestones/_sidebar.html.haml
+++ b/app/views/shared/milestones/_sidebar.html.haml
@@ -4,12 +4,12 @@
%aside.right-sidebar.js-right-sidebar{ data: { "offset-top" => affix_offset, "spy" => "affix", "always-show-toggle" => true }, class: sidebar_gutter_collapsed_class, 'aria-live' => 'polite' }
.issuable-sidebar.milestone-sidebar
.block.milestone-progress.issuable-sidebar-header
- %a.gutter-toggle.float-right.js-sidebar-toggle.has-tooltip{ role: "button", href: "#", "aria-label" => "Toggle sidebar", title: sidebar_gutter_tooltip_text, data: { container: 'body', placement: 'left', boundary: 'viewport' } }
+ %a.gutter-toggle.float-right.js-sidebar-toggle.has-tooltip{ role: "button", href: "#", "aria-label" => s_('MilestoneSidebar|Toggle sidebar'), title: sidebar_gutter_tooltip_text, data: { container: 'body', placement: 'left', boundary: 'viewport' } }
= sidebar_gutter_toggle_icon
.title.hide-collapsed
%strong.bold== #{milestone.percent_complete}%
%span.hide-collapsed
- complete
+ = s_('MilestoneSidebar|complete')
.value.hide-collapsed
= milestone_progress_bar(milestone)
@@ -20,15 +20,15 @@
.block.start_date.hide-collapsed
.title
- Start date
+ = s_('MilestoneSidebar|Start date')
- if @project && can?(current_user, :admin_milestone, @project)
- = link_to 'Edit', edit_project_milestone_path(@project, @milestone), class: 'js-sidebar-dropdown-toggle edit-link float-right'
+ = link_to s_('MilestoneSidebar|Edit'), edit_project_milestone_path(@project, @milestone), class: 'js-sidebar-dropdown-toggle edit-link float-right'
.value
%span.value-content
- if milestone.start_date
%span.bold= milestone.start_date.to_s(:medium)
- else
- %span.no-value No start date
+ %span.no-value= s_('MilestoneSidebar|No start date')
.block.due_date
.sidebar-collapsed-icon
@@ -45,26 +45,26 @@
.due_date.has-tooltip{ title: milestone_time_for(milestone.due_date, :end), data: { container: 'body', html: 'true', placement: 'left', boundary: 'viewport' } }
= milestone.due_date.strftime('%b %-d %Y')
- elsif milestone.start_date
- From
+ = s_('MilestoneSidebar|From')
.milestone-date.has-tooltip{ title: milestone_time_for(milestone.start_date, :start), data: { container: 'body', html: 'true', placement: 'left', boundary: 'viewport' } }
= milestone.start_date.strftime('%b %-d %Y')
- elsif milestone.due_date
- Until
+ = s_('MilestoneSidebar|Until')
.milestone-date.has-tooltip{ title: milestone_time_for(milestone.due_date, :end), data: { container: 'body', html: 'true', placement: 'left', boundary: 'viewport' } }
= milestone.due_date.strftime('%b %-d %Y')
- else
.has-tooltip{ title: milestone_time_for(milestone.start_date, :start), data: { container: 'body', html: 'true', placement: 'left', boundary: 'viewport' } }
- None
+ = s_('MilestoneSidebar|None')
.title.hide-collapsed
- Due date
+ = s_('MilestoneSidebar|Due date')
- if @project && can?(current_user, :admin_milestone, @project)
- = link_to 'Edit', edit_project_milestone_path(@project, @milestone), class: 'js-sidebar-dropdown-toggle edit-link float-right'
+ = link_to s_('MilestoneSidebar|Edit'), edit_project_milestone_path(@project, @milestone), class: 'js-sidebar-dropdown-toggle edit-link float-right'
.value.hide-collapsed
%span.value-content
- if milestone.due_date
%span.bold= milestone.due_date.to_s(:medium)
- else
- %span.no-value No due date
+ %span.no-value= s_('MilestoneSidebar|No due date')
- remaining_days = remaining_days_in_words(milestone.due_date, milestone.start_date)
- if remaining_days.present?
= surround '(', ')' do
@@ -77,19 +77,19 @@
= custom_icon('issues')
%span= milestone.issues_visible_to_user(current_user).count
.title.hide-collapsed
- Issues
+ = s_('MilestoneSidebar|Issues')
%span.badge.badge-pill= milestone.issues_visible_to_user(current_user).count
- if show_new_issue_link?(project)
- = link_to new_project_issue_path(project, issue: { milestone_id: milestone.id }), class: "float-right", title: "New Issue" do
- New issue
+ = link_to new_project_issue_path(project, issue: { milestone_id: milestone.id }), class: "float-right", title: s_('MilestoneSidebar|New Issue') do
+ = s_('MilestoneSidebar|New issue')
.value.hide-collapsed.bold
%span.milestone-stat
= link_to milestones_browse_issuables_path(milestone, type: :issues) do
- Open:
+ = s_('MilestoneSidebar|Open:')
= milestone.issues_visible_to_user(current_user).opened.count
%span.milestone-stat
= link_to milestones_browse_issuables_path(milestone, type: :issues, state: 'closed') do
- Closed:
+ = s_('MilestoneSidebar|Closed:')
= milestone.issues_visible_to_user(current_user).closed.count
.block
@@ -108,31 +108,31 @@
= custom_icon('mr_bold')
%span= milestone.merge_requests.count
.title.hide-collapsed
- Merge requests
+ = s_('MilestoneSidebar|Merge requests')
%span.badge.badge-pill= milestone.merge_requests.count
.value.hide-collapsed.bold
- if !project || can?(current_user, :read_merge_request, project)
%span.milestone-stat
= link_to milestones_browse_issuables_path(milestone, type: :merge_requests) do
- Open:
+ = s_('MilestoneSidebar|Open:')
= milestone.merge_requests.opened.count
%span.milestone-stat
= link_to milestones_browse_issuables_path(milestone, type: :merge_requests, state: 'closed') do
- Closed:
+ = s_('MilestoneSidebar|Closed:')
= milestone.merge_requests.closed.count
%span.milestone-stat
= link_to milestones_browse_issuables_path(milestone, type: :merge_requests, state: 'merged') do
- Merged:
+ = s_('MilestoneSidebar|Merged:')
= milestone.merge_requests.merged.count
- else
%span.milestone-stat
- Open:
+ = s_('MilestoneSidebar|Open:')
= milestone.merge_requests.opened.count
%span.milestone-stat
- Closed:
+ = s_('MilestoneSidebar|Closed:')
= milestone.merge_requests.closed.count
%span.milestone-stat
- Merged:
+ = s_('MilestoneSidebar|Merged:')
= milestone.merge_requests.merged.count
- if project
@@ -140,12 +140,12 @@
.block.releases
.sidebar-collapsed-icon.has-tooltip{ title: milestone_releases_tooltip_text(milestone), data: { container: 'body', placement: 'left', boundary: 'viewport' } }
%strong
- = icon('rocket')
+ = sprite_icon("rocket", size: 16)
%span= total_count
.title.hide-collapsed= n_('Release', 'Releases', total_count)
.hide-collapsed
- if total_count.zero?
- .no-value= _('None')
+ .no-value= s_('MilestoneSidebar|None')
- else
.font-weight-bold
- recent_releases.each do |release|
@@ -160,10 +160,10 @@
- if milestone_ref.present?
.block.reference
.sidebar-collapsed-icon.dont-change-state
- = clipboard_button(text: milestone_ref, title: _("Copy reference"), placement: "left", boundary: 'viewport')
+ = clipboard_button(text: milestone_ref, title: s_('MilestoneSidebar|Copy reference'), placement: "left", boundary: 'viewport')
.cross-project-reference.hide-collapsed
%span
- Reference:
+ = s_('MilestoneSidebar|Reference:')
%cite{ title: milestone_ref }
= milestone_ref
- = clipboard_button(text: milestone_ref, title: _("Copy reference"), placement: "left", boundary: 'viewport')
+ = clipboard_button(text: milestone_ref, title: s_('MilestoneSidebar|Copy reference'), placement: "left", boundary: 'viewport')
diff --git a/app/views/shared/milestones/_top.html.haml b/app/views/shared/milestones/_top.html.haml
index 5f53e6316af..49df00940b7 100644
--- a/app/views/shared/milestones/_top.html.haml
+++ b/app/views/shared/milestones/_top.html.haml
@@ -1,11 +1,9 @@
- page_title milestone.title
-- @breadcrumb_link = dashboard_milestone_path(milestone.safe_title, title: milestone.title)
+- @breadcrumb_link = milestone_path(milestone)
- group = local_assigns[:group]
-- is_dynamic_milestone = milestone.legacy_group_milestone? || milestone.dashboard_milestone?
= render 'shared/milestones/header', milestone: milestone
-= render 'shared/milestones/deprecation_message' if is_dynamic_milestone
= render 'shared/milestones/description', milestone: milestone
- if milestone.complete? && milestone.active?
@@ -15,26 +13,3 @@
= group ? _('You may close the milestone now.') : _('Navigate to the project to close the milestone.')
= render_if_exists 'shared/milestones/burndown', milestone: milestone, project: @project
-
-- if is_dynamic_milestone
- .table-holder
- %table.table
- %thead
- %tr
- %th= _('Project')
- %th= _('Open issues')
- %th= _('State')
- %th= _('Due date')
- %tr
- %td
- - project_name = group ? milestone.project.name : milestone.project.full_name
- = link_to project_name, milestone_path(milestone.milestone)
- %td
- = milestone.milestone.issues_visible_to_user(current_user).opened.count
- %td
- - if milestone.closed?
- = _('Closed')
- - else
- = _('Open')
- %td
- = milestone.expires_at
diff --git a/app/views/shared/notes/_edit_form.html.haml b/app/views/shared/notes/_edit_form.html.haml
index 6fe511c2999..244c191af12 100644
--- a/app/views/shared/notes/_edit_form.html.haml
+++ b/app/views/shared/notes/_edit_form.html.haml
@@ -2,8 +2,8 @@
= form_tag '#', method: :put, class: 'edit-note common-note-form js-quick-submit' do
= hidden_field_tag :target_id, '', class: 'js-form-target-id'
= hidden_field_tag :target_type, '', class: 'js-form-target-type'
- = render layout: 'projects/md_preview', locals: { url: preview_markdown_path(project), referenced_users: true } do
- = render 'projects/zen', attr: 'note[note]', classes: 'note-textarea js-note-text js-task-list-field', placeholder: _("Write a comment or drag your files here…")
+ = render layout: 'shared/md_preview', locals: { url: preview_markdown_path(project), referenced_users: true } do
+ = render 'shared/zen', attr: 'note[note]', classes: 'note-textarea js-note-text js-task-list-field', placeholder: _("Write a comment or drag your files here…")
= render 'shared/notes/hints'
.note-form-actions.clearfix
diff --git a/app/views/shared/notes/_form.html.haml b/app/views/shared/notes/_form.html.haml
index 327745e4f4d..40e36728642 100644
--- a/app/views/shared/notes/_form.html.haml
+++ b/app/views/shared/notes/_form.html.haml
@@ -25,8 +25,8 @@
= f.hidden_field :position
.discussion-form-container.discussion-with-resolve-btn.flex-column.p-0
- = render layout: 'projects/md_preview', locals: { url: preview_url, referenced_users: true } do
- = render 'projects/zen', f: f,
+ = render layout: 'shared/md_preview', locals: { url: preview_url, referenced_users: true } do
+ = render 'shared/zen', f: f,
attr: :note,
classes: 'note-textarea js-note-text',
placeholder: _("Write a comment or drag your files here…"),
diff --git a/app/views/shared/notifications/_custom_notifications.html.haml b/app/views/shared/notifications/_custom_notifications.html.haml
index 0142deb47f8..9bd08c2296f 100644
--- a/app/views/shared/notifications/_custom_notifications.html.haml
+++ b/app/views/shared/notifications/_custom_notifications.html.haml
@@ -16,7 +16,7 @@
= hidden_field_tag("hide_label", true) if hide_label
.row
.col-lg-4
- %h4.prepend-top-0= _('Notification events')
+ %h4.gl-mt-0= _('Notification events')
%p
- notification_link = link_to _('notification emails'), help_page_path('user/profile/notifications'), target: '_blank'
- paragraph = _('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 %{notification_link}.') % { notification_link: notification_link.html_safe }
@@ -26,7 +26,7 @@
- next if notification_event_disabled?(event)
- field_id = "#{notifications_menu_identifier("modal", notification_setting)}_notification_setting[#{event}]"
.form-group
- .form-check{ class: ("prepend-top-0" if index == 0) }
+ .form-check{ class: ("gl-mt-0" if index == 0) }
= check_box("notification_setting", event, id: field_id, class: "js-custom-notification-event form-check-input", checked: notification_setting.public_send(event))
%label.form-check-label{ for: field_id }
%strong
diff --git a/app/views/shared/notifications/_new_button.html.haml b/app/views/shared/notifications/_new_button.html.haml
index 566f08b94ce..796ff095eea 100644
--- a/app/views/shared/notifications/_new_button.html.haml
+++ b/app/views/shared/notifications/_new_button.html.haml
@@ -8,7 +8,7 @@
- else
- button_title = _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) }
- .js-notification-dropdown.notification-dropdown.home-panel-action-button.prepend-top-default.append-right-8.dropdown.inline
+ .js-notification-dropdown.notification-dropdown.home-panel-action-button.prepend-top-default.gl-mr-3.dropdown.inline
= form_for notification_setting, remote: true, html: { class: "inline notification-form no-label" } do |f|
= hidden_setting_source_input(notification_setting)
= hidden_field_tag "hide_label", true
diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml
index 3d61943193f..fc3f1a8d1c1 100644
--- a/app/views/shared/projects/_project.html.haml
+++ b/app/views/shared/projects/_project.html.haml
@@ -30,9 +30,9 @@
.project-details.d-sm-flex.flex-sm-fill.align-items-center{ data: { qa_selector: 'project', qa_project_name: project.name } }
.flex-wrapper
.d-flex.align-items-center.flex-wrap.project-title
- %h2.d-flex.prepend-top-8
+ %h2.d-flex.gl-mt-3
= link_to project_path(project), class: 'text-plain' do
- %span.project-full-name.append-right-8><
+ %span.project-full-name.gl-mr-3><
%span.namespace-name
- if project.namespace && !skip_namespace
= project.namespace.human_name
@@ -40,22 +40,22 @@
%span.project-name<
= project.name
- %span.metadata-info.visibility-icon.append-right-10.prepend-top-8.text-secondary.has-tooltip{ data: { container: 'body', placement: 'top' }, title: visibility_icon_description(project) }
+ %span.metadata-info.visibility-icon.append-right-10.gl-mt-3.text-secondary.has-tooltip{ data: { container: 'body', placement: 'top' }, title: visibility_icon_description(project) }
= visibility_level_icon(project.visibility_level, fw: true)
- if explore_projects_tab? && license_name
- %span.metadata-info.d-inline-flex.align-items-center.append-right-10.prepend-top-8
+ %span.metadata-info.d-inline-flex.align-items-center.append-right-10.gl-mt-3
= sprite_icon('scale', size: 14, css_class: 'append-right-4')
= license_name
- if !explore_projects_tab? && access&.nonzero?
-# haml-lint:disable UnnecessaryStringOutput
= ' ' # prevent haml from eating the space between elements
- .metadata-info.prepend-top-8
+ .metadata-info.gl-mt-3
%span.user-access-role.d-block= Gitlab::Access.human_access(access)
- if !explore_projects_tab?
- .metadata-info.prepend-top-8
+ .metadata-info.gl-mt-3
= render_if_exists 'compliance_management/compliance_framework/compliance_framework_badge', project: project
- if show_last_commit_as_description
diff --git a/app/views/shared/snippets/_form.html.haml b/app/views/shared/snippets/_form.html.haml
index 4695692fb53..7f307f33b51 100644
--- a/app/views/shared/snippets/_form.html.haml
+++ b/app/views/shared/snippets/_form.html.haml
@@ -9,7 +9,7 @@
.form-group
= f.label :title, class: 'label-bold'
- = f.text_field :title, class: 'form-control qa-snippet-title', required: true, autofocus: true
+ = f.text_field :title, class: 'form-control', required: true, autofocus: true, data: { qa_selector: 'snippet_title_field' }
.form-group.js-description-input
- description_placeholder = s_('Snippets|Optionally add a description about what your snippet does or how to use it...')
@@ -19,15 +19,15 @@
.js-collapsed{ class: ('d-none' if is_expanded) }
= text_field_tag nil, nil, class: 'form-control', placeholder: description_placeholder, data: { qa_selector: 'description_placeholder' }
.js-expanded{ class: ('d-none' if !is_expanded) }
- = render layout: 'projects/md_preview', locals: { url: preview_markdown_path(@project), referenced_users: true } do
- = render 'projects/zen', f: f, attr: :description, classes: 'note-textarea', placeholder: description_placeholder, qa_selector: 'snippet_description_field'
+ = render layout: 'shared/md_preview', locals: { url: preview_markdown_path(@project), referenced_users: true } do
+ = render 'shared/zen', f: f, attr: :description, classes: 'note-textarea', placeholder: description_placeholder, qa_selector: 'snippet_description_field'
= render 'shared/notes/hints'
.form-group.file-editor
= f.label :file_name, s_('Snippets|File')
.file-holder.snippet
.js-file-title.file-title-flex-parent
- = f.text_field :file_name, placeholder: s_("Snippets|Give your file a name to add code highlighting, e.g. example.rb for Ruby"), class: 'form-control js-snippet-file-name qa-snippet-file-name'
+ = f.text_field :file_name, placeholder: s_("Snippets|Give your file a name to add code highlighting, e.g. example.rb for Ruby"), class: 'form-control js-snippet-file-name', data: { qa_selector: 'file_name_field' }
.file-content.code
%pre#editor{ data: { 'editor-loading': true } }= @snippet.content
= f.hidden_field :content, class: 'snippet-file-content'
diff --git a/app/views/shared/snippets/_header.html.haml b/app/views/shared/snippets/_header.html.haml
index e663d57ae6a..7f213c50de2 100644
--- a/app/views/shared/snippets/_header.html.haml
+++ b/app/views/shared/snippets/_header.html.haml
@@ -1,6 +1,6 @@
.detail-page-header
.detail-page-header-body
- .snippet-box.qa-snippet-box.has-tooltip.inline.append-right-5{ title: snippet_visibility_level_description(@snippet.visibility_level, @snippet), data: { container: "body" } }
+ .snippet-box.has-tooltip.inline.append-right-5{ title: snippet_visibility_level_description(@snippet.visibility_level, @snippet), data: { container: "body" } }
%span.sr-only
= visibility_level_label(@snippet.visibility_level)
= visibility_level_icon(@snippet.visibility_level, fw: false)
@@ -17,11 +17,11 @@
= render "snippets/actions"
.snippet-header.limited-header-width
- %h2.snippet-title.prepend-top-0.mb-3{ data: { qa_selector: 'snippet_title' } }
+ %h2.snippet-title.gl-mt-0.mb-3
= markdown_field(@snippet, :title)
- if @snippet.description.present?
- .description{ data: { qa_selector: 'snippet_description_field' } }
+ .description
.md
= markdown_field(@snippet, :description)
%textarea.hidden.js-task-list-field
diff --git a/app/views/shared/tokens/_scopes_list.html.haml b/app/views/shared/tokens/_scopes_list.html.haml
index 913392be510..558cf67f201 100644
--- a/app/views/shared/tokens/_scopes_list.html.haml
+++ b/app/views/shared/tokens/_scopes_list.html.haml
@@ -6,7 +6,7 @@
%td
= _('Scopes')
%td
- %ul.scopes-list.append-bottom-0
+ %ul.scopes-list.gl-mb-0
- token.scopes.each do |scope|
%li
%span.bold= scope
diff --git a/app/views/shared/web_hooks/_hook.html.haml b/app/views/shared/web_hooks/_hook.html.haml
index 34a62340966..470e2f6b904 100644
--- a/app/views/shared/web_hooks/_hook.html.haml
+++ b/app/views/shared/web_hooks/_hook.html.haml
@@ -11,6 +11,6 @@
= hook.enable_ssl_verification ? _('enabled') : _('disabled')
.col-md-4.col-lg-5.text-right-md.prepend-top-5
- %span>= render 'shared/web_hooks/test_button', hook: hook, button_class: 'btn-sm append-right-8'
- %span>= link_to _('Edit'), edit_hook_path(hook), class: 'btn btn-sm append-right-8'
+ %span>= render 'shared/web_hooks/test_button', hook: hook, button_class: 'btn-sm gl-mr-3'
+ %span>= link_to _('Edit'), edit_hook_path(hook), class: 'btn btn-sm gl-mr-3'
= link_to _('Delete'), destroy_hook_path(hook), data: { confirm: _('Are you sure?') }, method: :delete, class: 'btn btn-sm'
diff --git a/app/views/shared/web_hooks/_title_and_docs.html.haml b/app/views/shared/web_hooks/_title_and_docs.html.haml
index 359f5f34f5b..f00f3473efa 100644
--- a/app/views/shared/web_hooks/_title_and_docs.html.haml
+++ b/app/views/shared/web_hooks/_title_and_docs.html.haml
@@ -1,5 +1,10 @@
-%h4.prepend-top-0
+- webhooks_link_start = '<a href="%{url}">'.html_safe % { url: help_page_path(hook.help_path) }
+
+%h4.gl-mt-0
= page_title
-%p
- - link = link_to(hook.pluralized_name, help_page_path(hook.help_path))
- = _('%{link} can be used for binding events when something is happening within the project.').html_safe % { link: link }
+
+- if @project
+ - integrations_link_start = '<a href="%{url}">'.html_safe % { url: scoped_integrations_path }
+ %p= _("%{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.").html_safe % { webhooks_link_start: webhooks_link_start, webhook_type: hook.pluralized_name, integrations_link_start: integrations_link_start, link_end: '</a>'.html_safe }
+- else
+ %p= _("%{webhooks_link_start}%{webhook_type}%{link_end} enable you to send notifications to web applications in response to events in a group or project.").html_safe % { webhooks_link_start: webhooks_link_start, webhook_type: hook.pluralized_name, link_end: '</a>'.html_safe }
diff --git a/app/views/shared/wikis/_form.html.haml b/app/views/shared/wikis/_form.html.haml
new file mode 100644
index 00000000000..8ea06d4d6c3
--- /dev/null
+++ b/app/views/shared/wikis/_form.html.haml
@@ -0,0 +1,79 @@
+- form_classes = %w[wiki-form common-note-form prepend-top-default js-quick-submit]
+
+- if @page.persisted?
+ - form_action = wiki_page_path(@wiki, @page)
+ - form_method = :put
+- else
+ - form_action = wiki_path(@wiki, action: :create)
+ - form_method = :post
+ - form_classes << 'js-new-wiki-page'
+
+= form_for @page, url: form_action, method: form_method,
+ html: { class: form_classes },
+ data: { uploads_path: uploads_path } do |f|
+ = form_errors(@page, truncate: :title)
+
+ - if @page.persisted?
+ = f.hidden_field :last_commit_sha, value: @page.last_commit_sha
+
+ .form-group.row
+ .col-sm-12= f.label :title, class: 'control-label-full-width'
+ .col-sm-12
+ = f.text_field :title, class: 'form-control qa-wiki-title-textbox', value: @page.title, required: true, autofocus: !@page.persisted?, placeholder: s_('Wiki|Page title')
+ %span.d-inline-block.mw-100.prepend-top-5
+ = icon('lightbulb-o')
+ - if @page.persisted?
+ = s_("WikiEditPageTip|Tip: You can move this page by adding the path to the beginning of the title.")
+ = link_to icon('question-circle'), help_page_path('user/project/wiki/index', anchor: 'moving-a-wiki-page'),
+ target: '_blank', rel: 'noopener noreferrer'
+ - else
+ = s_("WikiNewPageTip|Tip: You can specify the full path for the new file. We will automatically create any missing directories.")
+ = succeed '.' do
+ = link_to _('Learn more'), help_page_path('user/project/wiki/index', anchor: 'creating-a-new-wiki-page'),
+ target: '_blank', rel: 'noopener noreferrer'
+ .form-group.row
+ .col-sm-12= f.label :format, class: 'control-label-full-width'
+ .col-sm-12
+ .select-wrapper
+ = f.select :format, options_for_select(Wiki::MARKUPS, {selected: @page.format}), {}, class: 'form-control select-control'
+ = icon('chevron-down')
+
+ .form-group.row
+ .col-sm-12= f.label :content, class: 'control-label-full-width'
+ .col-sm-12
+ = render layout: 'shared/md_preview', locals: { url: wiki_page_path(@wiki, @page, action: :preview_markdown) } do
+ = render 'shared/zen', f: f, attr: :content, classes: 'note-textarea qa-wiki-content-textarea', placeholder: s_("WikiPage|Write your content or drag files here…")
+ = render 'shared/notes/hints'
+
+ .clearfix
+ .error-alert
+
+ .form-text.text-muted
+ = succeed '.' do
+ - case @page.format.to_s
+ - when 'rdoc'
+ - link_example = '{Link title}[link:page-slug]'
+ - when 'asciidoc'
+ - link_example = 'link:page-slug[Link title]'
+ - when 'org'
+ - link_example = '[[page-slug]]'
+ - else
+ - link_example = '[Link Title](page-slug)'
+ = (s_('WikiMarkdownTip|To link to a (new) page, simply type <code class="js-markup-link-example">%{link_example}</code>') % { link_example: link_example }).html_safe
+ = succeed '.' do
+ - markdown_link = link_to s_("WikiMarkdownDocs|documentation"), help_page_path('user/markdown', anchor: 'wiki-specific-markdown')
+ = (s_("WikiMarkdownDocs|More examples are in the %{docs_link}") % { docs_link: markdown_link }).html_safe
+
+ .form-group.row
+ .col-sm-12= f.label :commit_message, class: 'control-label-full-width'
+ .col-sm-12= f.text_field :message, class: 'form-control qa-wiki-message-textbox', rows: 18, value: nil
+
+ .form-actions
+ - if @page && @page.persisted?
+ = f.submit _("Save changes"), class: 'btn-success btn qa-save-changes-button'
+ .float-right
+ = link_to _("Cancel"), wiki_page_path(@wiki, @page), class: 'btn btn-cancel btn-grouped'
+ - else
+ = f.submit s_("Wiki|Create page"), class: 'btn-success btn qa-create-page-button rspec-create-page-button'
+ .float-right
+ = link_to _("Cancel"), wiki_path(@wiki), class: 'btn btn-cancel'
diff --git a/app/views/shared/wikis/_main_links.html.haml b/app/views/shared/wikis/_main_links.html.haml
new file mode 100644
index 00000000000..e173ef72d11
--- /dev/null
+++ b/app/views/shared/wikis/_main_links.html.haml
@@ -0,0 +1,9 @@
+- if @page&.persisted?
+ - if can?(current_user, :create_wiki, @wiki.container)
+ = link_to wiki_path(@wiki, action: :new), class: "btn btn-success", role: "button", data: { qa_selector: 'new_page_button' } do
+ = s_("Wiki|New page")
+ = link_to wiki_page_path(@wiki, @page, action: :history), class: "btn", role: "button", data: { qa_selector: 'page_history_button' } do
+ = s_("Wiki|Page history")
+ - if can?(current_user, :create_wiki, @wiki.container) && @page.latest? && @valid_encoding
+ = link_to wiki_page_path(@wiki, @page, action: :edit), class: "btn js-wiki-edit", role: "button", data: { qa_selector: 'edit_page_button' } do
+ = _("Edit")
diff --git a/app/views/shared/wikis/_pages_wiki_page.html.haml b/app/views/shared/wikis/_pages_wiki_page.html.haml
new file mode 100644
index 00000000000..534884eb848
--- /dev/null
+++ b/app/views/shared/wikis/_pages_wiki_page.html.haml
@@ -0,0 +1,6 @@
+%li
+ = link_to wiki_page.title, wiki_page_path(@wiki, wiki_page)
+ %small (#{wiki_page.format})
+ .float-right
+ - if wiki_page.last_version
+ %small= (s_("Last edited %{date}") % { date: time_ago_with_tooltip(wiki_page.last_version.authored_date) }).html_safe
diff --git a/app/views/shared/wikis/_sidebar.html.haml b/app/views/shared/wikis/_sidebar.html.haml
new file mode 100644
index 00000000000..8cfb95cdcf5
--- /dev/null
+++ b/app/views/shared/wikis/_sidebar.html.haml
@@ -0,0 +1,22 @@
+%aside.right-sidebar.right-sidebar-expanded.wiki-sidebar.js-wiki-sidebar.js-right-sidebar{ data: { "offset-top" => "50", "spy" => "affix" } }
+ .sidebar-container
+ .block.wiki-sidebar-header.append-bottom-default.w-100
+ %a.gutter-toggle.float-right.d-block.d-sm-block.d-md-none.js-sidebar-wiki-toggle{ href: "#" }
+ = icon('angle-double-right')
+
+ - git_access_url = wiki_path(@wiki, action: :git_access)
+ = link_to git_access_url, class: active_nav_link?(path: 'wikis#git_access') ? 'active' : '', data: { qa_selector: 'clone_repository_link' } do
+ = icon('cloud-download', class: 'append-right-5')
+ %span= _("Clone repository")
+
+ .blocks-container
+ .block.block-first.w-100
+ - if @sidebar_page
+ = render_wiki_content(@sidebar_page)
+ - else
+ %ul.wiki-pages
+ = render @sidebar_wiki_entries, context: 'sidebar'
+ .block.w-100
+ - if @sidebar_limited
+ = link_to wiki_path(@wiki, action: :pages), class: 'btn btn-block' do
+ = s_("Wiki|View All Pages")
diff --git a/app/views/shared/wikis/_sidebar_wiki_page.html.haml b/app/views/shared/wikis/_sidebar_wiki_page.html.haml
new file mode 100644
index 00000000000..2573471f9f9
--- /dev/null
+++ b/app/views/shared/wikis/_sidebar_wiki_page.html.haml
@@ -0,0 +1,3 @@
+%li{ class: active_when(params[:id] == wiki_page.slug) }
+ = link_to wiki_page_path(@wiki, wiki_page) do
+ = wiki_page.human_title
diff --git a/app/views/projects/wikis/_wiki_directory.html.haml b/app/views/shared/wikis/_wiki_directory.html.haml
index 0e5f32ed859..0e5f32ed859 100644
--- a/app/views/projects/wikis/_wiki_directory.html.haml
+++ b/app/views/shared/wikis/_wiki_directory.html.haml
diff --git a/app/views/shared/wikis/_wiki_page.html.haml b/app/views/shared/wikis/_wiki_page.html.haml
new file mode 100644
index 00000000000..b27feac86cc
--- /dev/null
+++ b/app/views/shared/wikis/_wiki_page.html.haml
@@ -0,0 +1 @@
+= render "shared/wikis/#{context}_wiki_page", wiki_page: wiki_page
diff --git a/app/views/shared/wikis/edit.html.haml b/app/views/shared/wikis/edit.html.haml
new file mode 100644
index 00000000000..5bda8d85627
--- /dev/null
+++ b/app/views/shared/wikis/edit.html.haml
@@ -0,0 +1,31 @@
+- @content_class = "limit-container-width" unless fluid_layout
+- add_to_breadcrumbs _("Wiki"), wiki_page_path(@wiki, @page)
+- breadcrumb_title @page.persisted? ? _("Edit") : _("New")
+- page_title @page.persisted? ? _("Edit") : _("New"), @page.human_title, _("Wiki")
+
+= wiki_page_errors(@error)
+
+.wiki-page-header.top-area.has-sidebar-toggle.flex-column.flex-lg-row
+ %button.btn.btn-default.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" }
+ = icon('angle-double-left')
+
+ .nav-text
+ %h2.wiki-page-title
+ - if @page.persisted?
+ = link_to @page.human_title, wiki_page_path(@wiki, @page)
+ %span.light
+ &middot;
+ = s_("Wiki|Edit Page")
+ - else
+ = s_("Wiki|Create New Page")
+
+ .nav-controls.pb-md-3.pb-lg-0
+ - if @page.persisted?
+ = link_to wiki_page_path(@wiki, @page, action: :history), class: "btn" do
+ = s_("Wiki|Page history")
+ - if can?(current_user, :admin_wiki, @wiki.container)
+ #delete-wiki-modal-wrapper{ data: { delete_wiki_url: wiki_page_path(@wiki, @page), page_title: @page.human_title } }
+
+= render 'shared/wikis/form', uploads_path: wiki_attachment_upload_url
+
+= render 'shared/wikis/sidebar'
diff --git a/app/views/projects/wikis/empty.html.haml b/app/views/shared/wikis/empty.html.haml
index 62fa6e1907b..62fa6e1907b 100644
--- a/app/views/projects/wikis/empty.html.haml
+++ b/app/views/shared/wikis/empty.html.haml
diff --git a/app/views/shared/wikis/history.html.haml b/app/views/shared/wikis/history.html.haml
new file mode 100644
index 00000000000..ec07082bd02
--- /dev/null
+++ b/app/views/shared/wikis/history.html.haml
@@ -0,0 +1,41 @@
+- page_title _("History"), @page.human_title, _("Wiki")
+
+.wiki-page-header.top-area.has-sidebar-toggle.flex-column.flex-lg-row
+ %button.btn.btn-default.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" }
+ = icon('angle-double-left')
+
+ .nav-text
+ %h2.wiki-page-title
+ = link_to @page.human_title, wiki_page_path(@wiki, @page)
+ %span.light
+ &middot;
+ = _("History")
+
+.table-holder
+ %table.table
+ %thead
+ %tr
+ %th= s_("Wiki|Page version")
+ %th= _("Author")
+ %th= _("Commit Message")
+ %th= _("Last updated")
+ %th= _("Format")
+ %tbody
+ - @page_versions.each_with_index do |version, index|
+ - commit = version
+ %tr
+ %td
+ = link_to wiki_page_path(@wiki, @page, version_id: index == 0 ? nil : commit.id) do
+ = truncate_sha(commit.id)
+ %td
+ = commit.author_name
+ %td
+ = commit.message
+ %td
+ #{time_ago_with_tooltip(version.authored_date)}
+ %td
+ %strong
+ = version.format
+= paginate @page_versions, theme: 'gitlab'
+
+= render 'shared/wikis/sidebar'
diff --git a/app/views/shared/wikis/pages.html.haml b/app/views/shared/wikis/pages.html.haml
new file mode 100644
index 00000000000..987c696cdfe
--- /dev/null
+++ b/app/views/shared/wikis/pages.html.haml
@@ -0,0 +1,32 @@
+- 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])
+
+.wiki-page-header.top-area.flex-column.flex-lg-row
+
+ .nav-text.flex-fill
+ %h2.wiki-page-title
+ = s_("Wiki|Wiki Pages")
+
+ .nav-controls.pb-md-3.pb-lg-0
+ = link_to wiki_path(@wiki, action: :git_access), class: 'btn' do
+ = icon('cloud-download')
+ = _("Clone repository")
+
+ .dropdown.inline.wiki-sort-dropdown
+ .btn-group{ role: 'group' }
+ .btn-group{ role: 'group' }
+ %button.dropdown-toggle{ type: 'button', data: { toggle: 'dropdown', display: 'static' }, class: 'btn btn-default' }
+ = sort_title
+ = icon('chevron-down')
+ %ul.dropdown-menu.dropdown-menu-right.dropdown-menu-selectable.dropdown-menu-sort
+ %li
+ = sortable_item(s_("Wiki|Title"), wiki_path(@wiki, action: :pages, sort: Wiki::TITLE_ORDER), sort_title)
+ = sortable_item(s_("Wiki|Created date"), wiki_path(@wiki, action: :pages, sort: Wiki::CREATED_AT_ORDER), sort_title)
+ = wiki_sort_controls(@wiki, params[:sort], params[:direction])
+
+%ul.wiki-pages-list.content-list
+ = render @wiki_entries, context: 'pages'
+
+= paginate @wiki_pages, theme: 'gitlab'
diff --git a/app/views/shared/wikis/show.html.haml b/app/views/shared/wikis/show.html.haml
new file mode 100644
index 00000000000..a4f3996e5de
--- /dev/null
+++ b/app/views/shared/wikis/show.html.haml
@@ -0,0 +1,32 @@
+- @content_class = "limit-container-width" unless fluid_layout
+- breadcrumb_title @page.human_title
+- wiki_breadcrumb_dropdown_links(@page.slug)
+- page_title @page.human_title, _("Wiki")
+- add_to_breadcrumbs _("Wiki"), wiki_path(@wiki)
+
+.wiki-page-header.top-area.has-sidebar-toggle.flex-column.flex-lg-row
+ %button.btn.btn-default.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" }
+ = icon('angle-double-left')
+
+ .nav-text.flex-fill
+ %h2.wiki-page-title{ data: { qa_selector: 'wiki_page_title' } }= @page.human_title
+ %span.wiki-last-edit-by
+ - if @page.last_version
+ = (_("Last edited by %{name}") % { name: "<strong>#{@page.last_version.author_name}</strong>" }).html_safe
+ #{time_ago_with_tooltip(@page.last_version.authored_date)}
+
+ .nav-controls.pb-md-3.pb-lg-0
+ = render 'shared/wikis/main_links'
+
+- if @page.historical?
+ .warning_message
+ = s_("WikiHistoricalPage|This is an old version of this page.")
+ - most_recent_link = link_to s_("WikiHistoricalPage|most recent version"), wiki_page_path(@wiki, @page)
+ - history_link = link_to s_("WikiHistoricalPage|history"), wiki_page_path(@wiki, @page, action: :history)
+ = (s_("WikiHistoricalPage|You can view the %{most_recent_link} or browse the %{history_link}.") % { most_recent_link: most_recent_link, history_link: history_link }).html_safe
+
+.prepend-top-default.append-bottom-default
+ .md{ data: { qa_selector: 'wiki_page_content' } }
+ = render_wiki_content(@page)
+
+= render 'shared/wikis/sidebar'
diff --git a/app/views/snippets/_actions.html.haml b/app/views/snippets/_actions.html.haml
index 979821a3846..2ff174971cc 100644
--- a/app/views/snippets/_actions.html.haml
+++ b/app/views/snippets/_actions.html.haml
@@ -13,7 +13,7 @@
- if @snippet.submittable_as_spam_by?(current_user)
= link_to _('Submit as spam'), mark_as_spam_snippet_path(@snippet), method: :post, class: 'btn btn-grouped btn-spam', title: _('Submit as spam')
.d-block.d-sm-none.dropdown
- %button.btn.btn-default.btn-block.append-bottom-0.prepend-top-5{ data: { toggle: "dropdown" } }
+ %button.btn.btn-default.btn-block.gl-mb-0.prepend-top-5{ data: { toggle: "dropdown" } }
= _("Options")
= icon('caret-down')
.dropdown-menu.dropdown-menu-full-width
diff --git a/app/views/u2f/_authenticate.html.haml b/app/views/u2f/_authenticate.html.haml
index 51018428b1b..6658d70df8d 100644
--- a/app/views/u2f/_authenticate.html.haml
+++ b/app/views/u2f/_authenticate.html.haml
@@ -1,18 +1,19 @@
-#js-authenticate-u2f
+#js-authenticate-token-2fa
%a.btn.btn-block.btn-info#js-login-2fa-device{ href: '#' }= _("Sign in via 2FA code")
-%script#js-authenticate-u2f-in-progress{ type: "text/template" }
+%script#js-authenticate-token-2fa-in-progress{ type: "text/template" }
%p= _("Trying to communicate with your device. Plug it in (if you haven't already) and press the button on the device now.")
-%script#js-authenticate-u2f-error{ type: "text/template" }
+%script#js-authenticate-token-2fa-error{ type: "text/template" }
%div
%p <%= error_message %> (#{_("error code:")} <%= error_code %>)
- %a.btn.btn-block.btn-warning#js-u2f-try-again= _("Try again?")
+ %a.btn.btn-block.btn-warning#js-token-2fa-try-again= _("Try again?")
-%script#js-authenticate-u2f-authenticated{ type: "text/template" }
+%script#js-authenticate-token-2fa-authenticated{ type: "text/template" }
%div
- %p= _("We heard back from your U2F device. You have been authenticated.")
- = form_tag(new_user_session_path, method: :post, id: 'js-login-u2f-form') do |f|
- - resource_params = params[resource_name].presence || params
- = hidden_field_tag 'user[remember_me]', resource_params.fetch(:remember_me, 0)
+ %p= _("We heard back from your device. You have been authenticated.")
+ = form_tag(target_path, method: :post, id: 'js-login-token-2fa-form') do |f|
+ - if render_remember_me
+ - resource_params = params[resource_name].presence || params
+ = hidden_field_tag 'user[remember_me]', resource_params.fetch(:remember_me, 0)
= hidden_field_tag 'user[device_response]', nil, class: 'form-control', required: true, id: "js-device-response"
diff --git a/app/views/u2f/_register.html.haml b/app/views/u2f/_register.html.haml
index ef3835332a7..6f3f4c4981c 100644
--- a/app/views/u2f/_register.html.haml
+++ b/app/views/u2f/_register.html.haml
@@ -25,7 +25,7 @@
%div
%p
%span <%= error_message %> (#{_("error code:")} <%= error_code %>)
- %a.btn.btn-warning#js-u2f-try-again= _("Try again?")
+ %a.btn.btn-warning#js-token-2fa-try-again= _("Try again?")
%script#js-register-u2f-registered{ type: "text/template" }
.row.append-bottom-10
diff --git a/app/views/users/_deletion_guidance.html.haml b/app/views/users/_deletion_guidance.html.haml
index 7169aebea74..0024801dbf6 100644
--- a/app/views/users/_deletion_guidance.html.haml
+++ b/app/views/users/_deletion_guidance.html.haml
@@ -8,4 +8,4 @@
- personal_projects_count = user.personal_projects.count
- unless personal_projects_count.zero?
%li
- = n_('personal project will be removed and cannot be restored', '%d personal projects will be removed and cannot be restored', personal_projects_count)
+ = n_('%d personal project will be removed and cannot be restored.', '%d personal projects will be removed and cannot be restored.', personal_projects_count) % personal_projects_count
diff --git a/app/views/users/terms/index.html.haml b/app/views/users/terms/index.html.haml
index 4fa04402a1c..bc4861d6ae8 100644
--- a/app/views/users/terms/index.html.haml
+++ b/app/views/users/terms/index.html.haml
@@ -6,13 +6,13 @@
.card-footer.footer-block.clearfix
- if can?(current_user, :accept_terms, @term)
.float-right
- = button_to accept_term_path(@term, redirect_params), class: 'btn btn-success prepend-left-8', data: { qa_selector: 'accept_terms_button' } do
+ = button_to accept_term_path(@term, redirect_params), class: 'btn btn-success gl-ml-3', data: { qa_selector: 'accept_terms_button' } do
= _('Accept terms')
- else
.pull-right
- = link_to root_path, class: 'btn btn-success prepend-left-8' do
+ = link_to root_path, class: 'btn btn-success gl-ml-3' do
= _('Continue')
- if can?(current_user, :decline_terms, @term)
.float-right
- = button_to decline_term_path(@term, redirect_params), class: 'btn btn-default prepend-left-8' do
+ = button_to decline_term_path(@term, redirect_params), class: 'btn btn-default gl-ml-3' do
= _('Decline and sign out')
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index 1f9a53d64d9..0699be0f4cb 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -10,6 +10,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
+ :tags: []
- :name: authorized_project_update:authorized_project_update_user_refresh_with_low_urgency
:feature_category: :authentication_and_authorization
:has_external_dependencies:
@@ -17,6 +18,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
+ :tags: []
- :name: auto_devops:auto_devops_disable
:feature_category: :auto_devops
:has_external_dependencies:
@@ -24,6 +26,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
+ :tags: []
- :name: auto_merge:auto_merge_process
:feature_category: :continuous_delivery
:has_external_dependencies:
@@ -31,6 +34,7 @@
:resource_boundary: :cpu
:weight: 3
:idempotent:
+ :tags: []
- :name: chaos:chaos_cpu_spin
:feature_category: :not_owned
:has_external_dependencies:
@@ -38,6 +42,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
+ :tags: []
- :name: chaos:chaos_db_spin
:feature_category: :not_owned
:has_external_dependencies:
@@ -45,6 +50,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
+ :tags: []
- :name: chaos:chaos_kill
:feature_category: :not_owned
:has_external_dependencies:
@@ -52,6 +58,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
+ :tags: []
- :name: chaos:chaos_leak_mem
:feature_category: :not_owned
:has_external_dependencies:
@@ -59,6 +66,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
+ :tags: []
- :name: chaos:chaos_sleep
:feature_category: :not_owned
:has_external_dependencies:
@@ -66,6 +74,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
+ :tags: []
- :name: container_repository:cleanup_container_repository
:feature_category: :container_registry
:has_external_dependencies:
@@ -73,6 +82,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: container_repository:delete_container_repository
:feature_category: :container_registry
:has_external_dependencies:
@@ -80,6 +90,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:admin_email
:feature_category: :source_code_management
:has_external_dependencies:
@@ -87,6 +98,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:ci_archive_traces_cron
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -94,6 +106,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:container_expiration_policy
:feature_category: :container_registry
:has_external_dependencies:
@@ -101,6 +114,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:environments_auto_stop_cron
:feature_category: :continuous_delivery
:has_external_dependencies:
@@ -108,6 +122,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:expire_build_artifacts
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -115,6 +130,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:gitlab_usage_ping
:feature_category: :collection
:has_external_dependencies:
@@ -122,6 +138,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:import_export_project_cleanup
:feature_category: :importers
:has_external_dependencies:
@@ -129,6 +146,15 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
+- :name: cronjob:import_stuck_project_import_jobs
+ :feature_category: :importers
+ :has_external_dependencies:
+ :urgency: :low
+ :resource_boundary: :cpu
+ :weight: 1
+ :idempotent:
+ :tags: []
- :name: cronjob:issue_due_scheduler
:feature_category: :issue_tracking
:has_external_dependencies:
@@ -136,6 +162,23 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
+- :name: cronjob:jira_import_stuck_jira_import_jobs
+ :feature_category: :importers
+ :has_external_dependencies:
+ :urgency: :low
+ :resource_boundary: :cpu
+ :weight: 1
+ :idempotent:
+ :tags: []
+- :name: cronjob:metrics_dashboard_schedule_annotations_prune
+ :feature_category: :metrics
+ :has_external_dependencies:
+ :urgency: :low
+ :resource_boundary: :unknown
+ :weight: 1
+ :idempotent: true
+ :tags: []
- :name: cronjob:namespaces_prune_aggregation_schedules
:feature_category: :source_code_management
:has_external_dependencies:
@@ -143,6 +186,7 @@
:resource_boundary: :cpu
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:pages_domain_removal_cron
:feature_category: :pages
:has_external_dependencies:
@@ -150,6 +194,7 @@
:resource_boundary: :cpu
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:pages_domain_ssl_renewal_cron
:feature_category: :pages
:has_external_dependencies:
@@ -157,6 +202,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:pages_domain_verification_cron
:feature_category: :pages
:has_external_dependencies:
@@ -164,6 +210,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:personal_access_tokens_expiring
:feature_category: :authentication_and_authorization
:has_external_dependencies:
@@ -171,6 +218,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:pipeline_schedule
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -178,6 +226,7 @@
:resource_boundary: :cpu
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:prune_old_events
:feature_category: :users
:has_external_dependencies:
@@ -185,6 +234,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:prune_web_hook_logs
:feature_category: :integrations
:has_external_dependencies:
@@ -192,6 +242,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:remove_expired_group_links
:feature_category: :authentication_and_authorization
:has_external_dependencies:
@@ -199,6 +250,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:remove_expired_members
:feature_category: :authentication_and_authorization
:has_external_dependencies:
@@ -206,6 +258,7 @@
:resource_boundary: :cpu
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:remove_unreferenced_lfs_objects
:feature_category: :git_lfs
:has_external_dependencies:
@@ -213,6 +266,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:repository_archive_cache
:feature_category: :source_code_management
:has_external_dependencies:
@@ -220,6 +274,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:repository_check_dispatch
:feature_category: :source_code_management
:has_external_dependencies:
@@ -227,6 +282,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:requests_profiles
:feature_category: :source_code_management
:has_external_dependencies:
@@ -234,6 +290,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:schedule_migrate_external_diffs
:feature_category: :source_code_management
:has_external_dependencies:
@@ -241,6 +298,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:stuck_ci_jobs
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -248,6 +306,7 @@
:resource_boundary: :cpu
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:stuck_export_jobs
:feature_category: :importers
:has_external_dependencies:
@@ -255,6 +314,7 @@
:resource_boundary: :cpu
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:stuck_import_jobs
:feature_category: :importers
:has_external_dependencies:
@@ -262,6 +322,7 @@
:resource_boundary: :cpu
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:stuck_merge_jobs
:feature_category: :source_code_management
:has_external_dependencies:
@@ -269,6 +330,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:trending_projects
:feature_category: :source_code_management
:has_external_dependencies:
@@ -276,6 +338,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:users_create_statistics
:feature_category: :users
:has_external_dependencies:
@@ -283,6 +346,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: cronjob:x509_issuer_crl_check
:feature_category: :source_code_management
:has_external_dependencies: true
@@ -290,6 +354,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
+ :tags: []
- :name: deployment:deployments_finished
:feature_category: :continuous_delivery
:has_external_dependencies:
@@ -297,6 +362,7 @@
:resource_boundary: :cpu
:weight: 3
:idempotent:
+ :tags: []
- :name: deployment:deployments_forward_deployment
:feature_category: :continuous_delivery
:has_external_dependencies:
@@ -304,6 +370,7 @@
:resource_boundary: :unknown
:weight: 3
:idempotent:
+ :tags: []
- :name: deployment:deployments_success
:feature_category: :continuous_delivery
:has_external_dependencies:
@@ -311,6 +378,7 @@
:resource_boundary: :cpu
:weight: 3
:idempotent:
+ :tags: []
- :name: gcp_cluster:cluster_configure_istio
:feature_category: :kubernetes_management
:has_external_dependencies: true
@@ -318,6 +386,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: gcp_cluster:cluster_install_app
:feature_category: :kubernetes_management
:has_external_dependencies: true
@@ -325,6 +394,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: gcp_cluster:cluster_patch_app
:feature_category: :kubernetes_management
:has_external_dependencies: true
@@ -332,6 +402,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: gcp_cluster:cluster_provision
:feature_category: :kubernetes_management
:has_external_dependencies: true
@@ -339,6 +410,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: gcp_cluster:cluster_update_app
:feature_category: :kubernetes_management
:has_external_dependencies:
@@ -346,6 +418,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: gcp_cluster:cluster_upgrade_app
:feature_category: :kubernetes_management
:has_external_dependencies: true
@@ -353,6 +426,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: gcp_cluster:cluster_wait_for_app_installation
:feature_category: :kubernetes_management
:has_external_dependencies: true
@@ -360,6 +434,7 @@
:resource_boundary: :cpu
:weight: 1
:idempotent:
+ :tags: []
- :name: gcp_cluster:cluster_wait_for_app_update
:feature_category: :kubernetes_management
:has_external_dependencies:
@@ -367,6 +442,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: gcp_cluster:cluster_wait_for_ingress_ip_address
:feature_category: :kubernetes_management
:has_external_dependencies: true
@@ -374,6 +450,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: gcp_cluster:clusters_applications_activate_service
:feature_category: :kubernetes_management
:has_external_dependencies:
@@ -381,6 +458,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: gcp_cluster:clusters_applications_deactivate_service
:feature_category: :kubernetes_management
:has_external_dependencies:
@@ -388,6 +466,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: gcp_cluster:clusters_applications_uninstall
:feature_category: :kubernetes_management
:has_external_dependencies: true
@@ -395,6 +474,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: gcp_cluster:clusters_applications_wait_for_uninstall_app
:feature_category: :kubernetes_management
:has_external_dependencies: true
@@ -402,6 +482,7 @@
:resource_boundary: :cpu
:weight: 1
:idempotent:
+ :tags: []
- :name: gcp_cluster:clusters_cleanup_app
:feature_category: :kubernetes_management
:has_external_dependencies: true
@@ -409,6 +490,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: gcp_cluster:clusters_cleanup_project_namespace
:feature_category: :kubernetes_management
:has_external_dependencies: true
@@ -416,6 +498,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: gcp_cluster:clusters_cleanup_service_account
:feature_category: :kubernetes_management
:has_external_dependencies: true
@@ -423,6 +506,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: gcp_cluster:wait_for_cluster_creation
:feature_category: :kubernetes_management
:has_external_dependencies: true
@@ -430,6 +514,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: github_importer:github_import_import_diff_note
:feature_category: :importers
:has_external_dependencies: true
@@ -437,6 +522,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: github_importer:github_import_import_issue
:feature_category: :importers
:has_external_dependencies: true
@@ -444,6 +530,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: github_importer:github_import_import_lfs_object
:feature_category: :importers
:has_external_dependencies: true
@@ -451,6 +538,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: github_importer:github_import_import_note
:feature_category: :importers
:has_external_dependencies: true
@@ -458,6 +546,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: github_importer:github_import_import_pull_request
:feature_category: :importers
:has_external_dependencies: true
@@ -465,6 +554,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: github_importer:github_import_refresh_import_jid
:feature_category: :importers
:has_external_dependencies:
@@ -472,6 +562,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: github_importer:github_import_stage_finish_import
:feature_category: :importers
:has_external_dependencies:
@@ -479,6 +570,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: github_importer:github_import_stage_import_base_data
:feature_category: :importers
:has_external_dependencies:
@@ -486,6 +578,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: github_importer:github_import_stage_import_issues_and_diff_notes
:feature_category: :importers
:has_external_dependencies:
@@ -493,6 +586,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: github_importer:github_import_stage_import_lfs_objects
:feature_category: :importers
:has_external_dependencies:
@@ -500,6 +594,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: github_importer:github_import_stage_import_notes
:feature_category: :importers
:has_external_dependencies:
@@ -507,6 +602,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: github_importer:github_import_stage_import_pull_requests
:feature_category: :importers
:has_external_dependencies:
@@ -514,6 +610,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: github_importer:github_import_stage_import_repository
:feature_category: :importers
:has_external_dependencies:
@@ -521,6 +618,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: hashed_storage:hashed_storage_migrator
:feature_category: :source_code_management
:has_external_dependencies:
@@ -528,6 +626,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: hashed_storage:hashed_storage_project_migrate
:feature_category: :source_code_management
:has_external_dependencies:
@@ -535,6 +634,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: hashed_storage:hashed_storage_project_rollback
:feature_category: :source_code_management
:has_external_dependencies:
@@ -542,6 +642,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: hashed_storage:hashed_storage_rollbacker
:feature_category: :source_code_management
:has_external_dependencies:
@@ -549,6 +650,15 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
+- :name: incident_management:clusters_applications_check_prometheus_health
+ :feature_category: :incident_management
+ :has_external_dependencies: true
+ :urgency: :low
+ :resource_boundary: :unknown
+ :weight: 2
+ :idempotent: true
+ :tags: []
- :name: incident_management:incident_management_process_alert
:feature_category: :incident_management
:has_external_dependencies:
@@ -556,6 +666,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
+ :tags: []
- :name: incident_management:incident_management_process_prometheus_alert
:feature_category: :incident_management
:has_external_dependencies:
@@ -563,6 +674,7 @@
:resource_boundary: :cpu
:weight: 2
:idempotent:
+ :tags: []
- :name: jira_importer:jira_import_advance_stage
:feature_category: :importers
:has_external_dependencies:
@@ -570,6 +682,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: jira_importer:jira_import_import_issue
:feature_category: :importers
:has_external_dependencies:
@@ -577,6 +690,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: jira_importer:jira_import_stage_finish_import
:feature_category: :importers
:has_external_dependencies:
@@ -584,6 +698,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: jira_importer:jira_import_stage_import_attachments
:feature_category: :importers
:has_external_dependencies:
@@ -591,6 +706,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: jira_importer:jira_import_stage_import_issues
:feature_category: :importers
:has_external_dependencies:
@@ -598,6 +714,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: jira_importer:jira_import_stage_import_labels
:feature_category: :importers
:has_external_dependencies:
@@ -605,6 +722,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: jira_importer:jira_import_stage_import_notes
:feature_category: :importers
:has_external_dependencies:
@@ -612,6 +730,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: jira_importer:jira_import_stage_start_import
:feature_category: :importers
:has_external_dependencies:
@@ -619,6 +738,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: mail_scheduler:mail_scheduler_issue_due
:feature_category: :issue_tracking
:has_external_dependencies:
@@ -626,6 +746,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
+ :tags: []
- :name: mail_scheduler:mail_scheduler_notification_service
:feature_category: :issue_tracking
:has_external_dependencies:
@@ -633,6 +754,7 @@
:resource_boundary: :cpu
:weight: 2
:idempotent:
+ :tags: []
- :name: notifications:new_release
:feature_category: :release_orchestration
:has_external_dependencies:
@@ -640,6 +762,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
+ :tags: []
- :name: object_pool:object_pool_create
:feature_category: :gitaly
:has_external_dependencies:
@@ -647,6 +770,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: object_pool:object_pool_destroy
:feature_category: :gitaly
:has_external_dependencies:
@@ -654,6 +778,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: object_pool:object_pool_join
:feature_category: :gitaly
:has_external_dependencies:
@@ -661,6 +786,7 @@
:resource_boundary: :cpu
:weight: 1
:idempotent:
+ :tags: []
- :name: object_pool:object_pool_schedule_join
:feature_category: :gitaly
:has_external_dependencies:
@@ -668,6 +794,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: object_storage:object_storage_background_move
:feature_category: :not_owned
:has_external_dependencies:
@@ -675,6 +802,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: object_storage:object_storage_migrate_uploads
:feature_category: :not_owned
:has_external_dependencies:
@@ -682,6 +810,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: pipeline_background:archive_trace
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -689,6 +818,15 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
+- :name: pipeline_background:ci_build_report_result
+ :feature_category: :continuous_integration
+ :has_external_dependencies:
+ :urgency: :low
+ :resource_boundary: :unknown
+ :weight: 1
+ :idempotent: true
+ :tags: []
- :name: pipeline_background:ci_build_trace_chunk_flush
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -696,6 +834,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: pipeline_background:ci_daily_build_group_report_results
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -703,6 +842,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
+ :tags: []
- :name: pipeline_cache:expire_job_cache
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -710,6 +850,7 @@
:resource_boundary: :unknown
:weight: 3
:idempotent: true
+ :tags: []
- :name: pipeline_cache:expire_pipeline_cache
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -717,6 +858,7 @@
:resource_boundary: :cpu
:weight: 3
:idempotent: true
+ :tags: []
- :name: pipeline_creation:create_pipeline
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -724,6 +866,7 @@
:resource_boundary: :cpu
:weight: 4
:idempotent:
+ :tags: []
- :name: pipeline_creation:run_pipeline_schedule
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -731,6 +874,7 @@
:resource_boundary: :unknown
:weight: 4
:idempotent:
+ :tags: []
- :name: pipeline_default:build_coverage
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -738,6 +882,7 @@
:resource_boundary: :unknown
:weight: 3
:idempotent:
+ :tags: []
- :name: pipeline_default:build_trace_sections
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -745,6 +890,7 @@
:resource_boundary: :unknown
:weight: 3
:idempotent:
+ :tags: []
- :name: pipeline_default:ci_create_cross_project_pipeline
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -752,6 +898,7 @@
:resource_boundary: :cpu
:weight: 3
:idempotent:
+ :tags: []
- :name: pipeline_default:ci_pipeline_bridge_status
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -759,6 +906,7 @@
:resource_boundary: :cpu
:weight: 3
:idempotent:
+ :tags: []
- :name: pipeline_default:pipeline_metrics
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -766,6 +914,7 @@
:resource_boundary: :unknown
:weight: 3
:idempotent:
+ :tags: []
- :name: pipeline_default:pipeline_notification
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -773,6 +922,7 @@
:resource_boundary: :cpu
:weight: 3
:idempotent:
+ :tags: []
- :name: pipeline_default:pipeline_update_ci_ref_status
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -780,6 +930,7 @@
:resource_boundary: :cpu
:weight: 3
:idempotent:
+ :tags: []
- :name: pipeline_hooks:build_hooks
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -787,6 +938,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
+ :tags: []
- :name: pipeline_hooks:pipeline_hooks
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -794,6 +946,7 @@
:resource_boundary: :cpu
:weight: 2
:idempotent:
+ :tags: []
- :name: pipeline_processing:build_finished
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -801,6 +954,7 @@
:resource_boundary: :cpu
:weight: 5
:idempotent:
+ :tags: []
- :name: pipeline_processing:build_queue
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -808,6 +962,7 @@
:resource_boundary: :cpu
:weight: 5
:idempotent:
+ :tags: []
- :name: pipeline_processing:build_success
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -815,6 +970,7 @@
:resource_boundary: :unknown
:weight: 5
:idempotent:
+ :tags: []
- :name: pipeline_processing:ci_build_prepare
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -822,6 +978,7 @@
:resource_boundary: :unknown
:weight: 5
:idempotent:
+ :tags: []
- :name: pipeline_processing:ci_build_schedule
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -829,6 +986,7 @@
:resource_boundary: :cpu
:weight: 5
:idempotent:
+ :tags: []
- :name: pipeline_processing:ci_resource_groups_assign_resource_from_resource_group
:feature_category: :continuous_delivery
:has_external_dependencies:
@@ -836,6 +994,7 @@
:resource_boundary: :unknown
:weight: 5
:idempotent:
+ :tags: []
- :name: pipeline_processing:pipeline_process
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -843,6 +1002,7 @@
:resource_boundary: :unknown
:weight: 5
:idempotent:
+ :tags: []
- :name: pipeline_processing:pipeline_update
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -850,6 +1010,7 @@
:resource_boundary: :unknown
:weight: 5
:idempotent:
+ :tags: []
- :name: pipeline_processing:stage_update
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -857,6 +1018,7 @@
:resource_boundary: :unknown
:weight: 5
:idempotent: true
+ :tags: []
- :name: pipeline_processing:update_head_pipeline_for_merge_request
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -864,6 +1026,7 @@
:resource_boundary: :cpu
:weight: 5
:idempotent: true
+ :tags: []
- :name: repository_check:repository_check_batch
:feature_category: :source_code_management
:has_external_dependencies:
@@ -871,6 +1034,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: repository_check:repository_check_clear
:feature_category: :source_code_management
:has_external_dependencies:
@@ -878,6 +1042,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: repository_check:repository_check_single_repository
:feature_category: :source_code_management
:has_external_dependencies:
@@ -885,6 +1050,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: todos_destroyer:todos_destroyer_confidential_issue
:feature_category: :issue_tracking
:has_external_dependencies:
@@ -892,6 +1058,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: todos_destroyer:todos_destroyer_entity_leave
:feature_category: :issue_tracking
:has_external_dependencies:
@@ -899,6 +1066,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: todos_destroyer:todos_destroyer_group_private
:feature_category: :issue_tracking
:has_external_dependencies:
@@ -906,6 +1074,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: todos_destroyer:todos_destroyer_private_features
:feature_category: :issue_tracking
:has_external_dependencies:
@@ -913,6 +1082,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: todos_destroyer:todos_destroyer_project_private
:feature_category: :issue_tracking
:has_external_dependencies:
@@ -920,6 +1090,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: update_namespace_statistics:namespaces_root_statistics
:feature_category: :source_code_management
:has_external_dependencies:
@@ -927,6 +1098,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
+ :tags: []
- :name: update_namespace_statistics:namespaces_schedule_aggregation
:feature_category: :source_code_management
:has_external_dependencies:
@@ -934,6 +1106,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
+ :tags: []
- :name: authorized_keys
:feature_category: :source_code_management
:has_external_dependencies:
@@ -941,6 +1114,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent: true
+ :tags: []
- :name: authorized_projects
:feature_category: :authentication_and_authorization
:has_external_dependencies:
@@ -948,6 +1122,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent: true
+ :tags: []
- :name: background_migration
:feature_category: :database
:has_external_dependencies:
@@ -955,6 +1130,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: chat_notification
:feature_category: :chatops
:has_external_dependencies: true
@@ -962,6 +1138,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
+ :tags: []
- :name: create_commit_signature
:feature_category: :source_code_management
:has_external_dependencies:
@@ -969,6 +1146,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent: true
+ :tags: []
- :name: create_evidence
:feature_category: :release_evidence
:has_external_dependencies:
@@ -976,6 +1154,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
+ :tags: []
- :name: create_note_diff_file
:feature_category: :source_code_management
:has_external_dependencies:
@@ -983,6 +1162,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: default
:feature_category:
:has_external_dependencies:
@@ -990,6 +1170,7 @@
:resource_boundary:
:weight: 1
:idempotent:
+ :tags: []
- :name: delete_diff_files
:feature_category: :source_code_management
:has_external_dependencies:
@@ -997,6 +1178,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: delete_merged_branches
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1004,6 +1186,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: delete_stored_files
:feature_category: :not_owned
:has_external_dependencies:
@@ -1011,6 +1194,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: delete_user
:feature_category: :authentication_and_authorization
:has_external_dependencies:
@@ -1018,6 +1202,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: design_management_new_version
:feature_category: :design_management
:has_external_dependencies:
@@ -1025,6 +1210,7 @@
:resource_boundary: :memory
:weight: 1
:idempotent:
+ :tags: []
- :name: detect_repository_languages
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1032,6 +1218,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: email_receiver
:feature_category: :issue_tracking
:has_external_dependencies:
@@ -1039,6 +1226,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
+ :tags: []
- :name: emails_on_push
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1046,6 +1234,7 @@
:resource_boundary: :cpu
:weight: 2
:idempotent:
+ :tags: []
- :name: error_tracking_issue_link
:feature_category: :error_tracking
:has_external_dependencies: true
@@ -1053,6 +1242,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: expire_build_instance_artifacts
:feature_category: :continuous_integration
:has_external_dependencies:
@@ -1060,6 +1250,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: export_csv
:feature_category: :issue_tracking
:has_external_dependencies:
@@ -1067,6 +1258,7 @@
:resource_boundary: :cpu
:weight: 1
:idempotent:
+ :tags: []
- :name: external_service_reactive_caching
:feature_category: :not_owned
:has_external_dependencies: true
@@ -1074,6 +1266,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: file_hook
:feature_category: :integrations
:has_external_dependencies:
@@ -1081,6 +1274,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: git_garbage_collect
:feature_category: :gitaly
:has_external_dependencies:
@@ -1088,6 +1282,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: github_import_advance_stage
:feature_category: :importers
:has_external_dependencies:
@@ -1095,6 +1290,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: gitlab_shell
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1102,6 +1298,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
+ :tags: []
- :name: group_destroy
:feature_category: :subgroups
:has_external_dependencies:
@@ -1109,6 +1306,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: group_export
:feature_category: :importers
:has_external_dependencies:
@@ -1116,6 +1314,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: group_import
:feature_category: :importers
:has_external_dependencies:
@@ -1123,6 +1322,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: import_issues_csv
:feature_category: :issue_tracking
:has_external_dependencies:
@@ -1130,6 +1330,7 @@
:resource_boundary: :cpu
:weight: 2
:idempotent:
+ :tags: []
- :name: invalid_gpg_signature_update
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1137,6 +1338,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
+ :tags: []
- :name: irker
:feature_category: :integrations
:has_external_dependencies:
@@ -1144,6 +1346,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: mailers
:feature_category:
:has_external_dependencies:
@@ -1151,6 +1354,7 @@
:resource_boundary:
:weight: 2
:idempotent:
+ :tags: []
- :name: merge
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1158,6 +1362,7 @@
:resource_boundary: :unknown
:weight: 5
:idempotent:
+ :tags: []
- :name: merge_request_mergeability_check
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1165,6 +1370,15 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
+ :tags: []
+- :name: metrics_dashboard_prune_old_annotations
+ :feature_category: :metrics
+ :has_external_dependencies:
+ :urgency: :low
+ :resource_boundary: :unknown
+ :weight: 1
+ :idempotent: true
+ :tags: []
- :name: migrate_external_diffs
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1172,6 +1386,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: namespaceless_project_destroy
:feature_category: :authentication_and_authorization
:has_external_dependencies:
@@ -1179,6 +1394,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: new_issue
:feature_category: :issue_tracking
:has_external_dependencies:
@@ -1186,6 +1402,7 @@
:resource_boundary: :cpu
:weight: 2
:idempotent:
+ :tags: []
- :name: new_merge_request
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1193,6 +1410,7 @@
:resource_boundary: :cpu
:weight: 2
:idempotent:
+ :tags: []
- :name: new_note
:feature_category: :issue_tracking
:has_external_dependencies:
@@ -1200,6 +1418,7 @@
:resource_boundary: :cpu
:weight: 2
:idempotent:
+ :tags: []
- :name: pages
:feature_category: :pages
:has_external_dependencies:
@@ -1207,6 +1426,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: pages_domain_ssl_renewal
:feature_category: :pages
:has_external_dependencies:
@@ -1214,6 +1434,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: pages_domain_verification
:feature_category: :pages
:has_external_dependencies:
@@ -1221,6 +1442,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: phabricator_import_import_tasks
:feature_category: :importers
:has_external_dependencies:
@@ -1228,6 +1450,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: post_receive
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1235,6 +1458,7 @@
:resource_boundary: :cpu
:weight: 5
:idempotent:
+ :tags: []
- :name: process_commit
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1242,6 +1466,7 @@
:resource_boundary: :unknown
:weight: 3
:idempotent: true
+ :tags: []
- :name: project_cache
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1249,6 +1474,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: project_daily_statistics
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1256,6 +1482,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: project_destroy
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1263,6 +1490,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: project_export
:feature_category: :importers
:has_external_dependencies:
@@ -1270,6 +1498,7 @@
:resource_boundary: :memory
:weight: 1
:idempotent:
+ :tags: []
- :name: project_service
:feature_category: :integrations
:has_external_dependencies: true
@@ -1277,6 +1506,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: project_update_repository_storage
:feature_category: :gitaly
:has_external_dependencies:
@@ -1284,6 +1514,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: prometheus_create_default_alerts
:feature_category: :incident_management
:has_external_dependencies:
@@ -1291,6 +1522,15 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
+ :tags: []
+- :name: propagate_integration
+ :feature_category: :integrations
+ :has_external_dependencies:
+ :urgency: :low
+ :resource_boundary: :unknown
+ :weight: 1
+ :idempotent: true
+ :tags: []
- :name: propagate_service_template
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1298,6 +1538,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: reactive_caching
:feature_category: :not_owned
:has_external_dependencies:
@@ -1305,6 +1546,7 @@
:resource_boundary: :cpu
:weight: 1
:idempotent:
+ :tags: []
- :name: rebase
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1312,6 +1554,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
+ :tags: []
- :name: remote_mirror_notification
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1319,6 +1562,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
+ :tags: []
- :name: repository_cleanup
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1326,6 +1570,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: repository_fork
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1333,6 +1578,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: repository_import
:feature_category: :importers
:has_external_dependencies: true
@@ -1340,6 +1586,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: repository_remove_remote
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1347,6 +1594,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: repository_update_remote_mirror
:feature_category: :source_code_management
:has_external_dependencies: true
@@ -1354,6 +1602,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: self_monitoring_project_create
:feature_category: :metrics
:has_external_dependencies:
@@ -1361,6 +1610,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
+ :tags: []
- :name: self_monitoring_project_delete
:feature_category: :metrics
:has_external_dependencies:
@@ -1368,6 +1618,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
+ :tags: []
- :name: system_hook_push
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1375,6 +1626,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: update_external_pull_requests
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1382,6 +1634,7 @@
:resource_boundary: :unknown
:weight: 3
:idempotent:
+ :tags: []
- :name: update_highest_role
:feature_category: :authentication_and_authorization
:has_external_dependencies:
@@ -1389,6 +1642,7 @@
:resource_boundary: :unknown
:weight: 2
:idempotent: true
+ :tags: []
- :name: update_merge_requests
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1396,6 +1650,7 @@
:resource_boundary: :cpu
:weight: 3
:idempotent:
+ :tags: []
- :name: update_project_statistics
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1403,6 +1658,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: upload_checksum
:feature_category: :geo_replication
:has_external_dependencies:
@@ -1410,6 +1666,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: web_hook
:feature_category: :integrations
:has_external_dependencies: true
@@ -1417,6 +1674,7 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
+ :tags: []
- :name: x509_certificate_revoke
:feature_category: :source_code_management
:has_external_dependencies:
@@ -1424,3 +1682,4 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
+ :tags: []
diff --git a/app/workers/authorized_keys_worker.rb b/app/workers/authorized_keys_worker.rb
index eabfd89ba60..ab0e7fc4921 100644
--- a/app/workers/authorized_keys_worker.rb
+++ b/app/workers/authorized_keys_worker.rb
@@ -9,6 +9,7 @@ class AuthorizedKeysWorker
urgency :high
weight 2
idempotent!
+ loggable_arguments 0
def perform(action, *args)
return unless Gitlab::CurrentSettings.authorized_keys_enabled?
diff --git a/app/workers/authorized_project_update/user_refresh_with_low_urgency_worker.rb b/app/workers/authorized_project_update/user_refresh_with_low_urgency_worker.rb
index 19038cb8900..7ca59a72adf 100644
--- a/app/workers/authorized_project_update/user_refresh_with_low_urgency_worker.rb
+++ b/app/workers/authorized_project_update/user_refresh_with_low_urgency_worker.rb
@@ -5,6 +5,7 @@ module AuthorizedProjectUpdate
feature_category :authentication_and_authorization
urgency :low
queue_namespace :authorized_project_update
+ deduplicate :until_executing, including_scheduled: true
idempotent!
end
diff --git a/app/workers/authorized_projects_worker.rb b/app/workers/authorized_projects_worker.rb
index a35e0320553..62eea8e0462 100644
--- a/app/workers/authorized_projects_worker.rb
+++ b/app/workers/authorized_projects_worker.rb
@@ -7,8 +7,8 @@ class AuthorizedProjectsWorker
feature_category :authentication_and_authorization
urgency :high
weight 2
-
idempotent!
+ loggable_arguments 1 # For the job waiter key
# This is a workaround for a Ruby 2.3.7 bug. rspec-mocks cannot restore the
# visibility of prepended modules. See https://github.com/rspec/rspec-mocks/issues/1231
diff --git a/app/workers/background_migration_worker.rb b/app/workers/background_migration_worker.rb
index 6a64afe47de..bff864ba420 100644
--- a/app/workers/background_migration_worker.rb
+++ b/app/workers/background_migration_worker.rb
@@ -5,6 +5,7 @@ class BackgroundMigrationWorker # rubocop:disable Scalability/IdempotentWorker
feature_category :database
urgency :throttled
+ loggable_arguments 0, 1
# The minimum amount of time between processing two jobs of the same migration
# class.
diff --git a/app/workers/build_finished_worker.rb b/app/workers/build_finished_worker.rb
index b6ef9ab4710..d38780dd08d 100644
--- a/app/workers/build_finished_worker.rb
+++ b/app/workers/build_finished_worker.rb
@@ -28,6 +28,7 @@ class BuildFinishedWorker # rubocop:disable Scalability/IdempotentWorker
# We execute these in sync to reduce IO.
BuildTraceSectionsWorker.new.perform(build.id)
BuildCoverageWorker.new.perform(build.id)
+ Ci::BuildReportResultWorker.new.perform(build.id)
# We execute these async as these are independent operations.
BuildHooksWorker.perform_async(build.id)
diff --git a/app/workers/ci/build_report_result_worker.rb b/app/workers/ci/build_report_result_worker.rb
new file mode 100644
index 00000000000..60387936d0b
--- /dev/null
+++ b/app/workers/ci/build_report_result_worker.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Ci
+ class BuildReportResultWorker
+ include ApplicationWorker
+ include PipelineBackgroundQueue
+
+ idempotent!
+
+ def perform(build_id)
+ Ci::Build.find_by_id(build_id).try do |build|
+ Ci::BuildReportResultService.new.execute(build)
+ end
+ end
+ end
+end
diff --git a/app/workers/cleanup_container_repository_worker.rb b/app/workers/cleanup_container_repository_worker.rb
index c3fac453e73..4469ea8cff9 100644
--- a/app/workers/cleanup_container_repository_worker.rb
+++ b/app/workers/cleanup_container_repository_worker.rb
@@ -5,6 +5,7 @@ class CleanupContainerRepositoryWorker # rubocop:disable Scalability/IdempotentW
queue_namespace :container_repository
feature_category :container_registry
+ loggable_arguments 2
attr_reader :container_repository, :current_user
diff --git a/app/workers/cluster_install_app_worker.rb b/app/workers/cluster_install_app_worker.rb
index 002932a0fa5..f3da4d5c4bb 100644
--- a/app/workers/cluster_install_app_worker.rb
+++ b/app/workers/cluster_install_app_worker.rb
@@ -6,6 +6,7 @@ class ClusterInstallAppWorker # rubocop:disable Scalability/IdempotentWorker
include ClusterApplications
worker_has_external_dependencies!
+ loggable_arguments 0
def perform(app_name, app_id)
find_application(app_name, app_id) do |app|
diff --git a/app/workers/cluster_patch_app_worker.rb b/app/workers/cluster_patch_app_worker.rb
index f75004aa3e5..b0393809802 100644
--- a/app/workers/cluster_patch_app_worker.rb
+++ b/app/workers/cluster_patch_app_worker.rb
@@ -6,6 +6,7 @@ class ClusterPatchAppWorker # rubocop:disable Scalability/IdempotentWorker
include ClusterApplications
worker_has_external_dependencies!
+ loggable_arguments 0
def perform(app_name, app_id)
find_application(app_name, app_id) do |app|
diff --git a/app/workers/cluster_update_app_worker.rb b/app/workers/cluster_update_app_worker.rb
index 7ceeb167b33..29feb813043 100644
--- a/app/workers/cluster_update_app_worker.rb
+++ b/app/workers/cluster_update_app_worker.rb
@@ -9,6 +9,7 @@ class ClusterUpdateAppWorker # rubocop:disable Scalability/IdempotentWorker
include ExclusiveLeaseGuard
sidekiq_options retry: 3, dead: false
+ loggable_arguments 0, 3
LEASE_TIMEOUT = 10.minutes.to_i
diff --git a/app/workers/cluster_upgrade_app_worker.rb b/app/workers/cluster_upgrade_app_worker.rb
index 99f48415f08..d4650ab3a85 100644
--- a/app/workers/cluster_upgrade_app_worker.rb
+++ b/app/workers/cluster_upgrade_app_worker.rb
@@ -6,6 +6,7 @@ class ClusterUpgradeAppWorker # rubocop:disable Scalability/IdempotentWorker
include ClusterApplications
worker_has_external_dependencies!
+ loggable_arguments 0
def perform(app_name, app_id)
find_application(app_name, app_id) do |app|
diff --git a/app/workers/cluster_wait_for_app_installation_worker.rb b/app/workers/cluster_wait_for_app_installation_worker.rb
index e098c3b86b5..4bc29807ea4 100644
--- a/app/workers/cluster_wait_for_app_installation_worker.rb
+++ b/app/workers/cluster_wait_for_app_installation_worker.rb
@@ -10,6 +10,7 @@ class ClusterWaitForAppInstallationWorker # rubocop:disable Scalability/Idempote
worker_has_external_dependencies!
worker_resource_boundary :cpu
+ loggable_arguments 0
def perform(app_name, app_id)
find_application(app_name, app_id) do |app|
diff --git a/app/workers/cluster_wait_for_app_update_worker.rb b/app/workers/cluster_wait_for_app_update_worker.rb
index 9f1d83c2c7b..c0a11eb93a7 100644
--- a/app/workers/cluster_wait_for_app_update_worker.rb
+++ b/app/workers/cluster_wait_for_app_update_worker.rb
@@ -8,6 +8,8 @@ class ClusterWaitForAppUpdateWorker # rubocop:disable Scalability/IdempotentWork
INTERVAL = 10.seconds
TIMEOUT = 20.minutes
+ loggable_arguments 0
+
def perform(app_name, app_id)
find_application(app_name, app_id) do |app|
::Clusters::Applications::CheckUpgradeProgressService.new(app).execute
diff --git a/app/workers/cluster_wait_for_ingress_ip_address_worker.rb b/app/workers/cluster_wait_for_ingress_ip_address_worker.rb
index c7336ee515d..fa46135d279 100644
--- a/app/workers/cluster_wait_for_ingress_ip_address_worker.rb
+++ b/app/workers/cluster_wait_for_ingress_ip_address_worker.rb
@@ -6,6 +6,7 @@ class ClusterWaitForIngressIpAddressWorker # rubocop:disable Scalability/Idempot
include ClusterApplications
worker_has_external_dependencies!
+ loggable_arguments 0
def perform(app_name, app_id)
find_application(app_name, app_id) do |app|
diff --git a/app/workers/clusters/applications/activate_service_worker.rb b/app/workers/clusters/applications/activate_service_worker.rb
index abd7f8eaea4..c92f978a7d2 100644
--- a/app/workers/clusters/applications/activate_service_worker.rb
+++ b/app/workers/clusters/applications/activate_service_worker.rb
@@ -6,6 +6,8 @@ module Clusters
include ApplicationWorker
include ClusterQueue
+ loggable_arguments 1
+
def perform(cluster_id, service_name)
cluster = Clusters::Cluster.find_by_id(cluster_id)
return unless cluster
diff --git a/app/workers/clusters/applications/check_prometheus_health_worker.rb b/app/workers/clusters/applications/check_prometheus_health_worker.rb
new file mode 100644
index 00000000000..2e8ee739946
--- /dev/null
+++ b/app/workers/clusters/applications/check_prometheus_health_worker.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+module Clusters
+ module Applications
+ class CheckPrometheusHealthWorker
+ include ApplicationWorker
+ # rubocop:disable Scalability/CronWorkerContext
+ # This worker does not perform work scoped to a context
+ include CronjobQueue
+ # rubocop:enable Scalability/CronWorkerContext
+
+ queue_namespace :incident_management
+ feature_category :incident_management
+ urgency :low
+
+ idempotent!
+ worker_has_external_dependencies!
+
+ def perform
+ demo_project_ids = Gitlab::Monitor::DemoProjects.primary_keys
+
+ clusters = Clusters::Cluster.with_application_prometheus
+ .with_project_alert_service_data(demo_project_ids)
+
+ # Move to a seperate worker with scoped context if expanded to do work on customer projects
+ clusters.each { |cluster| Clusters::Applications::PrometheusHealthCheckService.new(cluster).execute }
+ end
+ end
+ end
+end
diff --git a/app/workers/clusters/applications/deactivate_service_worker.rb b/app/workers/clusters/applications/deactivate_service_worker.rb
index fecbb6dde45..4d103bb0edc 100644
--- a/app/workers/clusters/applications/deactivate_service_worker.rb
+++ b/app/workers/clusters/applications/deactivate_service_worker.rb
@@ -6,6 +6,8 @@ module Clusters
include ApplicationWorker
include ClusterQueue
+ loggable_arguments 1
+
def perform(cluster_id, service_name)
cluster = Clusters::Cluster.find_by_id(cluster_id)
raise cluster_missing_error(service_name) unless cluster
diff --git a/app/workers/clusters/applications/uninstall_worker.rb b/app/workers/clusters/applications/uninstall_worker.rb
index 977a25e8442..a9307931b59 100644
--- a/app/workers/clusters/applications/uninstall_worker.rb
+++ b/app/workers/clusters/applications/uninstall_worker.rb
@@ -8,6 +8,7 @@ module Clusters
include ClusterApplications
worker_has_external_dependencies!
+ loggable_arguments 0
def perform(app_name, app_id)
find_application(app_name, app_id) do |app|
diff --git a/app/workers/clusters/applications/wait_for_uninstall_app_worker.rb b/app/workers/clusters/applications/wait_for_uninstall_app_worker.rb
index a486cfa90b7..dc842788374 100644
--- a/app/workers/clusters/applications/wait_for_uninstall_app_worker.rb
+++ b/app/workers/clusters/applications/wait_for_uninstall_app_worker.rb
@@ -12,6 +12,7 @@ module Clusters
worker_has_external_dependencies!
worker_resource_boundary :cpu
+ loggable_arguments 0
def perform(app_name, app_id)
find_application(app_name, app_id) do |app|
diff --git a/app/workers/concerns/application_worker.rb b/app/workers/concerns/application_worker.rb
index 7ab9a0c2a02..9c942228111 100644
--- a/app/workers/concerns/application_worker.rb
+++ b/app/workers/concerns/application_worker.rb
@@ -76,6 +76,22 @@ module ApplicationWorker
get_sidekiq_options['queue'].to_s
end
+ # Set/get which arguments can be logged and sent to Sentry.
+ #
+ # Numeric arguments are logged by default, so there is no need to
+ # list those.
+ #
+ # Non-numeric arguments must be listed by position, as Sidekiq
+ # cannot see argument names.
+ #
+ def loggable_arguments(*args)
+ if args.any?
+ @loggable_arguments = args
+ else
+ @loggable_arguments || []
+ end
+ end
+
def queue_size
Sidekiq::Queue.new(queue).size
end
@@ -84,7 +100,7 @@ module ApplicationWorker
Sidekiq::Client.push_bulk('class' => self, 'args' => args_list)
end
- def bulk_perform_in(delay, args_list)
+ def bulk_perform_in(delay, args_list, batch_size: nil, batch_delay: nil)
now = Time.now.to_i
schedule = now + delay.to_i
@@ -92,7 +108,14 @@ module ApplicationWorker
raise ArgumentError, _('The schedule time must be in the future!')
end
- Sidekiq::Client.push_bulk('class' => self, 'args' => args_list, 'at' => schedule)
+ if batch_size && batch_delay
+ args_list.each_slice(batch_size.to_i).with_index do |args_batch, idx|
+ batch_schedule = schedule + idx * batch_delay.to_i
+ Sidekiq::Client.push_bulk('class' => self, 'args' => args_batch, 'at' => batch_schedule)
+ end
+ else
+ Sidekiq::Client.push_bulk('class' => self, 'args' => args_list, 'at' => schedule)
+ end
end
end
end
diff --git a/app/workers/concerns/gitlab/github_import/queue.rb b/app/workers/concerns/gitlab/github_import/queue.rb
index 7cc23dd7c0b..05eb7fbc2cb 100644
--- a/app/workers/concerns/gitlab/github_import/queue.rb
+++ b/app/workers/concerns/gitlab/github_import/queue.rb
@@ -15,6 +15,17 @@ module Gitlab
# this is better than a project being stuck in the "import" state
# forever.
sidekiq_options dead: false, retry: 5
+
+ sidekiq_retries_exhausted do |msg, e|
+ Gitlab::Import::Logger.error(
+ event: :github_importer_exhausted,
+ message: msg['error_message'],
+ class: msg['class'],
+ args: msg['args'],
+ exception_message: e.message,
+ exception_backtrace: e.backtrace
+ )
+ end
end
end
end
diff --git a/app/workers/concerns/gitlab/jira_import/import_worker.rb b/app/workers/concerns/gitlab/jira_import/import_worker.rb
index 537300e6eba..fdc6e64bbaa 100644
--- a/app/workers/concerns/gitlab/jira_import/import_worker.rb
+++ b/app/workers/concerns/gitlab/jira_import/import_worker.rb
@@ -7,6 +7,7 @@ module Gitlab
included do
include ApplicationWorker
+ include ProjectImportOptions
include Gitlab::JiraImport::QueueOptions
end
@@ -26,7 +27,6 @@ module Gitlab
def can_import?(project)
return false unless project
- return false unless project.jira_issues_import_feature_flag_enabled?
project.latest_jira_import&.started?
end
diff --git a/app/workers/concerns/project_import_options.rb b/app/workers/concerns/project_import_options.rb
index c8ee5539441..4df209da29d 100644
--- a/app/workers/concerns/project_import_options.rb
+++ b/app/workers/concerns/project_import_options.rb
@@ -6,7 +6,7 @@ module ProjectImportOptions
IMPORT_RETRY_COUNT = 5
included do
- sidekiq_options retry: IMPORT_RETRY_COUNT, status_expiration: StuckImportJobsWorker::IMPORT_JOBS_EXPIRATION
+ sidekiq_options retry: IMPORT_RETRY_COUNT, status_expiration: Gitlab::Import::StuckImportJob::IMPORT_JOBS_EXPIRATION
# We only want to mark the project as failed once we exhausted all retries
sidekiq_retries_exhausted do |job|
diff --git a/app/workers/concerns/reactive_cacheable_worker.rb b/app/workers/concerns/reactive_cacheable_worker.rb
index e73707c2b43..189b0607605 100644
--- a/app/workers/concerns/reactive_cacheable_worker.rb
+++ b/app/workers/concerns/reactive_cacheable_worker.rb
@@ -7,6 +7,7 @@ module ReactiveCacheableWorker
include ApplicationWorker
feature_category_not_owned!
+ loggable_arguments 0
def self.context_for_arguments(arguments)
class_name, *_other_args = arguments
diff --git a/app/workers/concerns/worker_attributes.rb b/app/workers/concerns/worker_attributes.rb
index b60179531af..b19217b15de 100644
--- a/app/workers/concerns/worker_attributes.rb
+++ b/app/workers/concerns/worker_attributes.rb
@@ -111,6 +111,28 @@ module WorkerAttributes
1
end
+ def tags(*values)
+ worker_attributes[:tags] = values
+ end
+
+ def get_tags
+ Array(worker_attributes[:tags])
+ end
+
+ def deduplicate(strategy, options = {})
+ worker_attributes[:deduplication_strategy] = strategy
+ worker_attributes[:deduplication_options] = options
+ end
+
+ def get_deduplicate_strategy
+ worker_attributes[:deduplication_strategy] ||
+ Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob::DEFAULT_STRATEGY
+ end
+
+ def get_deduplication_options
+ worker_attributes[:deduplication_options] || {}
+ end
+
protected
# Returns a worker attribute declared on this class or its parent class.
diff --git a/app/workers/container_expiration_policy_worker.rb b/app/workers/container_expiration_policy_worker.rb
index e1544be5aed..96590e165ae 100644
--- a/app/workers/container_expiration_policy_worker.rb
+++ b/app/workers/container_expiration_policy_worker.rb
@@ -12,6 +12,8 @@ class ContainerExpirationPolicyWorker # rubocop:disable Scalability/IdempotentWo
user: container_expiration_policy.project.owner) do |project:, user:|
ContainerExpirationPolicyService.new(project, user)
.execute(container_expiration_policy)
+ rescue ContainerExpirationPolicyService::InvalidPolicyError => e
+ Gitlab::ErrorTracking.log_exception(e, container_expiration_policy_id: container_expiration_policy.id)
end
end
end
diff --git a/app/workers/create_commit_signature_worker.rb b/app/workers/create_commit_signature_worker.rb
index a88d2bf7d15..f81baf20d19 100644
--- a/app/workers/create_commit_signature_worker.rb
+++ b/app/workers/create_commit_signature_worker.rb
@@ -5,8 +5,8 @@ class CreateCommitSignatureWorker
feature_category :source_code_management
weight 2
-
idempotent!
+ loggable_arguments 0
# rubocop: disable CodeReuse/ActiveRecord
def perform(commit_shas, project_id)
@@ -37,7 +37,7 @@ class CreateCommitSignatureWorker
commits.each do |commit|
commit&.signature
rescue => e
- Rails.logger.error("Failed to create signature for commit #{commit.id}. Error: #{e.message}") # rubocop:disable Gitlab/RailsLogger
+ Gitlab::AppLogger.error("Failed to create signature for commit #{commit.id}. Error: #{e.message}")
end
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/workers/create_evidence_worker.rb b/app/workers/create_evidence_worker.rb
index 135e2ac38b4..b18028e4114 100644
--- a/app/workers/create_evidence_worker.rb
+++ b/app/workers/create_evidence_worker.rb
@@ -6,10 +6,15 @@ class CreateEvidenceWorker # rubocop:disable Scalability/IdempotentWorker
feature_category :release_evidence
weight 2
- def perform(release_id)
+ # pipeline_id is optional for backward compatibility with existing jobs
+ # caller should always try to provide the pipeline and pass nil only
+ # if pipeline is absent
+ def perform(release_id, pipeline_id = nil)
release = Release.find_by_id(release_id)
return unless release
- Releases::Evidence.create!(release: release)
+ pipeline = Ci::Pipeline.find_by_id(pipeline_id)
+
+ ::Releases::CreateEvidenceService.new(release, pipeline: pipeline).execute
end
end
diff --git a/app/workers/create_pipeline_worker.rb b/app/workers/create_pipeline_worker.rb
index 54698518e4f..68fe44d01ce 100644
--- a/app/workers/create_pipeline_worker.rb
+++ b/app/workers/create_pipeline_worker.rb
@@ -8,6 +8,7 @@ class CreatePipelineWorker # rubocop:disable Scalability/IdempotentWorker
feature_category :continuous_integration
urgency :high
worker_resource_boundary :cpu
+ loggable_arguments 2, 3, 4
def perform(project_id, user_id, ref, source, params = {})
project = Project.find(project_id)
diff --git a/app/workers/delete_stored_files_worker.rb b/app/workers/delete_stored_files_worker.rb
index 463f26fdd5a..9cf5631b7d8 100644
--- a/app/workers/delete_stored_files_worker.rb
+++ b/app/workers/delete_stored_files_worker.rb
@@ -4,6 +4,7 @@ class DeleteStoredFilesWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category_not_owned!
+ loggable_arguments 0
def perform(class_name, keys)
klass = begin
diff --git a/app/workers/delete_user_worker.rb b/app/workers/delete_user_worker.rb
index d3b87c133d3..ed2e00f1241 100644
--- a/app/workers/delete_user_worker.rb
+++ b/app/workers/delete_user_worker.rb
@@ -4,6 +4,7 @@ class DeleteUserWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :authentication_and_authorization
+ loggable_arguments 2
def perform(current_user_id, delete_user_id, options = {})
delete_user = User.find(delete_user_id)
@@ -11,6 +12,6 @@ class DeleteUserWorker # rubocop:disable Scalability/IdempotentWorker
Users::DestroyService.new(current_user).execute(delete_user, options.symbolize_keys)
rescue Gitlab::Access::AccessDeniedError => e
- Rails.logger.warn("User could not be destroyed: #{e}") # rubocop:disable Gitlab/RailsLogger
+ Gitlab::AppLogger.warn("User could not be destroyed: #{e}")
end
end
diff --git a/app/workers/email_receiver_worker.rb b/app/workers/email_receiver_worker.rb
index fcb88982c0b..9ceab9bb878 100644
--- a/app/workers/email_receiver_worker.rb
+++ b/app/workers/email_receiver_worker.rb
@@ -20,7 +20,7 @@ class EmailReceiverWorker # rubocop:disable Scalability/IdempotentWorker
private
def handle_failure(raw, error)
- Rails.logger.warn("Email can not be processed: #{error}\n\n#{raw}") # rubocop:disable Gitlab/RailsLogger
+ Gitlab::AppLogger.warn("Email can not be processed: #{error}\n\n#{raw}")
return unless raw.present?
diff --git a/app/workers/expire_build_instance_artifacts_worker.rb b/app/workers/expire_build_instance_artifacts_worker.rb
index 48fd086f88f..e6cd60a3e47 100644
--- a/app/workers/expire_build_instance_artifacts_worker.rb
+++ b/app/workers/expire_build_instance_artifacts_worker.rb
@@ -14,7 +14,7 @@ class ExpireBuildInstanceArtifactsWorker # rubocop:disable Scalability/Idempoten
return unless build&.project && !build.project.pending_delete
- Rails.logger.info "Removing artifacts for build #{build.id}..." # rubocop:disable Gitlab/RailsLogger
+ Gitlab::AppLogger.info("Removing artifacts for build #{build.id}...")
build.erase_erasable_artifacts!
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/workers/export_csv_worker.rb b/app/workers/export_csv_worker.rb
index 9e2b3ad9bb4..e7baaf40a41 100644
--- a/app/workers/export_csv_worker.rb
+++ b/app/workers/export_csv_worker.rb
@@ -5,6 +5,7 @@ class ExportCsvWorker # rubocop:disable Scalability/IdempotentWorker
feature_category :issue_tracking
worker_resource_boundary :cpu
+ loggable_arguments 2
def perform(current_user_id, project_id, params)
@current_user = User.find(current_user_id)
diff --git a/app/workers/file_hook_worker.rb b/app/workers/file_hook_worker.rb
index f8cdea54a17..b1422cd8795 100644
--- a/app/workers/file_hook_worker.rb
+++ b/app/workers/file_hook_worker.rb
@@ -5,6 +5,7 @@ class FileHookWorker # rubocop:disable Scalability/IdempotentWorker
sidekiq_options retry: false
feature_category :integrations
+ loggable_arguments 0
def perform(file_name, data)
success, message = Gitlab::FileHook.execute(file_name, data)
diff --git a/app/workers/git_garbage_collect_worker.rb b/app/workers/git_garbage_collect_worker.rb
index 37ca3af517f..f2222c7be5e 100644
--- a/app/workers/git_garbage_collect_worker.rb
+++ b/app/workers/git_garbage_collect_worker.rb
@@ -5,6 +5,7 @@ class GitGarbageCollectWorker # rubocop:disable Scalability/IdempotentWorker
sidekiq_options retry: false
feature_category :gitaly
+ loggable_arguments 1, 2, 3
# Timeout set to 24h
LEASE_TIMEOUT = 86400
diff --git a/app/workers/gitlab/github_import/advance_stage_worker.rb b/app/workers/gitlab/github_import/advance_stage_worker.rb
index 21e478f935b..834c2f7791c 100644
--- a/app/workers/gitlab/github_import/advance_stage_worker.rb
+++ b/app/workers/gitlab/github_import/advance_stage_worker.rb
@@ -12,6 +12,7 @@ module Gitlab
sidekiq_options dead: false
feature_category :importers
+ loggable_arguments 1, 2
# The known importer stages and their corresponding Sidekiq workers.
STAGES = {
diff --git a/app/workers/gitlab/import/stuck_import_job.rb b/app/workers/gitlab/import/stuck_import_job.rb
new file mode 100644
index 00000000000..16be7a77ab1
--- /dev/null
+++ b/app/workers/gitlab/import/stuck_import_job.rb
@@ -0,0 +1,82 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Import
+ module StuckImportJob
+ extend ActiveSupport::Concern
+
+ IMPORT_JOBS_EXPIRATION = 15.hours.seconds.to_i
+
+ included do
+ include ApplicationWorker
+ # rubocop:disable Scalability/CronWorkerContext
+ # This worker updates several import states inline and does not schedule
+ # other jobs. So no context needed
+ include CronjobQueue
+ # rubocop:enable Scalability/CronWorkerContext
+
+ feature_category :importers
+ worker_resource_boundary :cpu
+ end
+
+ def perform
+ stuck_imports_without_jid_count = mark_imports_without_jid_as_failed!
+ stuck_imports_with_jid_count = mark_imports_with_jid_as_failed!
+
+ track_metrics(stuck_imports_with_jid_count, stuck_imports_without_jid_count)
+ end
+
+ private
+
+ def track_metrics(with_jid_count, without_jid_count)
+ raise NotImplementedError
+ end
+
+ def mark_imports_without_jid_as_failed!
+ enqueued_import_states_without_jid.each do |import_state|
+ import_state.mark_as_failed(error_message)
+ end.size
+ end
+
+ def mark_imports_with_jid_as_failed!
+ jids_and_ids = enqueued_import_states_with_jid.pluck(:jid, :id).to_h # rubocop: disable CodeReuse/ActiveRecord
+
+ # Find the jobs that aren't currently running or that exceeded the threshold.
+ completed_jids = Gitlab::SidekiqStatus.completed_jids(jids_and_ids.keys)
+ return 0 unless completed_jids.any?
+
+ completed_import_state_ids = jids_and_ids.values_at(*completed_jids)
+
+ # We select the import states again, because they may have transitioned from
+ # scheduled/started to finished/failed while we were looking up their Sidekiq status.
+ completed_import_states = enqueued_import_states_with_jid.id_in(completed_import_state_ids)
+ completed_import_state_jids = completed_import_states.map { |import_state| import_state.jid }.join(', ')
+
+ Gitlab::Import::Logger.info(
+ message: 'Marked stuck import jobs as failed',
+ job_ids: completed_import_state_jids
+ )
+
+ completed_import_states.each do |import_state|
+ import_state.mark_as_failed(error_message)
+ end.size
+ end
+
+ def enqueued_import_states
+ raise NotImplementedError
+ end
+
+ def enqueued_import_states_with_jid
+ enqueued_import_states.with_jid
+ end
+
+ def enqueued_import_states_without_jid
+ enqueued_import_states.without_jid
+ end
+
+ def error_message
+ _("Import timed out. Import took longer than %{import_jobs_expiration} seconds") % { import_jobs_expiration: IMPORT_JOBS_EXPIRATION }
+ end
+ end
+ end
+end
diff --git a/app/workers/gitlab/import/stuck_project_import_jobs_worker.rb b/app/workers/gitlab/import/stuck_project_import_jobs_worker.rb
new file mode 100644
index 00000000000..01979b2029f
--- /dev/null
+++ b/app/workers/gitlab/import/stuck_project_import_jobs_worker.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+module Gitlab
+ module Import
+ class StuckProjectImportJobsWorker # rubocop:disable Scalability/IdempotentWorker
+ include Gitlab::Import::StuckImportJob
+
+ private
+
+ def track_metrics(with_jid_count, without_jid_count)
+ Gitlab::Metrics.add_event(
+ :stuck_import_jobs,
+ projects_without_jid_count: without_jid_count,
+ projects_with_jid_count: with_jid_count
+ )
+ end
+
+ def enqueued_import_states
+ ProjectImportState.with_status([:scheduled, :started])
+ end
+ end
+ end
+end
diff --git a/app/workers/gitlab/jira_import/import_issue_worker.rb b/app/workers/gitlab/jira_import/import_issue_worker.rb
index 78de5cf1307..7709d2ec31b 100644
--- a/app/workers/gitlab/jira_import/import_issue_worker.rb
+++ b/app/workers/gitlab/jira_import/import_issue_worker.rb
@@ -8,6 +8,8 @@ module Gitlab
include Gitlab::JiraImport::QueueOptions
include Gitlab::Import::DatabaseHelpers
+ loggable_arguments 3
+
def perform(project_id, jira_issue_id, issue_attributes, waiter_key)
issue_id = create_issue(issue_attributes, project_id)
JiraImport.cache_issue_mapping(issue_id, jira_issue_id, project_id)
@@ -48,7 +50,7 @@ module Gitlab
label_link_attrs << build_label_attrs(issue_id, import_label_id.to_i)
- Gitlab::Database.bulk_insert(LabelLink.table_name, label_link_attrs)
+ Gitlab::Database.bulk_insert(LabelLink.table_name, label_link_attrs) # rubocop:disable Gitlab/BulkInsert
end
def assign_issue(project_id, issue_id, assignee_ids)
@@ -56,7 +58,7 @@ module Gitlab
assignee_attrs = assignee_ids.map { |user_id| { issue_id: issue_id, user_id: user_id } }
- Gitlab::Database.bulk_insert(IssueAssignee.table_name, assignee_attrs)
+ Gitlab::Database.bulk_insert(IssueAssignee.table_name, assignee_attrs) # rubocop:disable Gitlab/BulkInsert
end
def build_label_attrs(issue_id, label_id)
diff --git a/app/workers/gitlab/jira_import/stage/start_import_worker.rb b/app/workers/gitlab/jira_import/stage/start_import_worker.rb
index 5b36feadbd1..bfc02224ee4 100644
--- a/app/workers/gitlab/jira_import/stage/start_import_worker.rb
+++ b/app/workers/gitlab/jira_import/stage/start_import_worker.rb
@@ -25,7 +25,6 @@ module Gitlab
def start_import
return false unless project
- return false unless project.jira_issues_import_feature_flag_enabled?
return true if start(project.latest_jira_import)
Gitlab::Import::Logger.info(
diff --git a/app/workers/gitlab/jira_import/stuck_jira_import_jobs_worker.rb b/app/workers/gitlab/jira_import/stuck_jira_import_jobs_worker.rb
new file mode 100644
index 00000000000..5e675193a8c
--- /dev/null
+++ b/app/workers/gitlab/jira_import/stuck_jira_import_jobs_worker.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module JiraImport
+ class StuckJiraImportJobsWorker # rubocop:disable Scalability/IdempotentWorker
+ include Gitlab::Import::StuckImportJob
+
+ private
+
+ def track_metrics(with_jid_count, without_jid_count)
+ Gitlab::Metrics.add_event(:stuck_jira_import_jobs,
+ jira_imports_without_jid_count: with_jid_count,
+ jira_imports_with_jid_count: without_jid_count)
+ end
+
+ def enqueued_import_states
+ JiraImportState.with_status([:scheduled, :started])
+ end
+ end
+ end
+end
diff --git a/app/workers/gitlab/phabricator_import/base_worker.rb b/app/workers/gitlab/phabricator_import/base_worker.rb
index 82ef9e825f9..2dc4855f854 100644
--- a/app/workers/gitlab/phabricator_import/base_worker.rb
+++ b/app/workers/gitlab/phabricator_import/base_worker.rb
@@ -13,7 +13,7 @@
# - It keeps track of the jobs so we know how many jobs are running for the
# project
# - It refreshes the import jid, so it doesn't get cleaned up by the
-# `StuckImportJobsWorker`
+# `Gitlab::Import::StuckProjectImportJobsWorker`
# - It marks the import as failed if a job failed to many times
# - It marks the import as finished when all remaining jobs are done
module Gitlab
diff --git a/app/workers/gitlab_shell_worker.rb b/app/workers/gitlab_shell_worker.rb
index b104d3c681e..b8e1e3d8fc4 100644
--- a/app/workers/gitlab_shell_worker.rb
+++ b/app/workers/gitlab_shell_worker.rb
@@ -7,6 +7,7 @@ class GitlabShellWorker # rubocop:disable Scalability/IdempotentWorker
feature_category :source_code_management
urgency :high
weight 2
+ loggable_arguments 0
def perform(action, *arg)
# Gitlab::Shell is being removed but we need to continue to process jobs
diff --git a/app/workers/group_export_worker.rb b/app/workers/group_export_worker.rb
index 3e0390429d6..6fd977e43d8 100644
--- a/app/workers/group_export_worker.rb
+++ b/app/workers/group_export_worker.rb
@@ -5,6 +5,7 @@ class GroupExportWorker # rubocop:disable Scalability/IdempotentWorker
include ExceptionBacktrace
feature_category :importers
+ loggable_arguments 2
def perform(current_user_id, group_id, params = {})
current_user = User.find(current_user_id)
diff --git a/app/workers/group_import_worker.rb b/app/workers/group_import_worker.rb
index d8f236013bf..36d81468d55 100644
--- a/app/workers/group_import_worker.rb
+++ b/app/workers/group_import_worker.rb
@@ -9,15 +9,16 @@ class GroupImportWorker # rubocop:disable Scalability/IdempotentWorker
def perform(user_id, group_id)
current_user = User.find(user_id)
group = Group.find(group_id)
- group_import = group.build_import_state(jid: self.jid)
+ group_import_state = group.import_state || group.build_import_state
- group_import.start!
+ group_import_state.jid = self.jid
+ group_import_state.start!
::Groups::ImportExport::ImportService.new(group: group, user: current_user).execute
- group_import.finish!
+ group_import_state.finish!
rescue StandardError => e
- group_import&.fail_op(e.message)
+ group_import_state&.fail_op(e.message)
raise e
end
diff --git a/app/workers/hashed_storage/project_migrate_worker.rb b/app/workers/hashed_storage/project_migrate_worker.rb
index 3ce60ce7eb6..03e53058dbb 100644
--- a/app/workers/hashed_storage/project_migrate_worker.rb
+++ b/app/workers/hashed_storage/project_migrate_worker.rb
@@ -5,6 +5,7 @@ module HashedStorage
include ApplicationWorker
queue_namespace :hashed_storage
+ loggable_arguments 1
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 17b3cca83e1..d4a5e474323 100644
--- a/app/workers/hashed_storage/project_rollback_worker.rb
+++ b/app/workers/hashed_storage/project_rollback_worker.rb
@@ -5,6 +5,7 @@ module HashedStorage
include ApplicationWorker
queue_namespace :hashed_storage
+ loggable_arguments 1
attr_reader :project_id
diff --git a/app/workers/incident_management/process_prometheus_alert_worker.rb b/app/workers/incident_management/process_prometheus_alert_worker.rb
index 768e049c60e..e405bc2c2d2 100644
--- a/app/workers/incident_management/process_prometheus_alert_worker.rb
+++ b/app/workers/incident_management/process_prometheus_alert_worker.rb
@@ -41,23 +41,11 @@ module IncidentManagement
end
def find_gitlab_managed_event(alert)
- payload_key = payload_key_for_alert(alert)
-
- PrometheusAlertEvent.find_by_payload_key(payload_key)
+ PrometheusAlertEvent.find_by_payload_key(alert.gitlab_fingerprint)
end
def find_self_managed_event(alert)
- payload_key = payload_key_for_alert(alert)
-
- SelfManagedPrometheusAlertEvent.find_by_payload_key(payload_key)
- end
-
- def payload_key_for_alert(alert)
- if alert.gitlab_managed?
- PrometheusAlertEvent.payload_key_for(alert.metric_id, alert.starts_at_raw)
- else
- SelfManagedPrometheusAlertEvent.payload_key_for(alert.starts_at_raw, alert.title, alert.full_query)
- end
+ SelfManagedPrometheusAlertEvent.find_by_payload_key(alert.gitlab_fingerprint)
end
def create_issue(project, alert)
diff --git a/app/workers/irker_worker.rb b/app/workers/irker_worker.rb
index 09f53681e7f..687fb1cd02a 100644
--- a/app/workers/irker_worker.rb
+++ b/app/workers/irker_worker.rb
@@ -8,26 +8,30 @@ class IrkerWorker # rubocop:disable Scalability/IdempotentWorker
feature_category :integrations
- def perform(project_id, chans, colors, push_data, settings)
- project = Project.find(project_id)
+ def perform(project_id, channels, colors, push_data, settings)
+ # Establish connection to irker server
+ return false unless start_connection(settings['server_host'],
+ settings['server_port'])
- # Get config parameters
- return false unless init_perform settings, chans, colors
+ @project = Project.find(project_id)
+ @colors = colors
+ @channels = channels
- repo_name = push_data['repository']['name']
- committer = push_data['user_name']
- branch = push_data['ref'].gsub(%r'refs/[^/]*/', '')
+ @repo_path = @project.full_path
+ @repo_name = push_data['repository']['name']
+ @committer = push_data['user_name']
+ @branch = push_data['ref'].gsub(%r'refs/[^/]*/', '')
if @colors
- repo_name = "\x0304#{repo_name}\x0f"
- branch = "\x0305#{branch}\x0f"
+ @repo_name = "\x0304#{@repo_name}\x0f"
+ @branch = "\x0305#{@branch}\x0f"
end
# First messages are for branch creation/deletion
- send_branch_updates push_data, project, repo_name, committer, branch
+ send_branch_updates(push_data)
# Next messages are for commits
- send_commits push_data, project, repo_name, committer, branch
+ send_commits(push_data)
close_connection
true
@@ -35,12 +39,6 @@ class IrkerWorker # rubocop:disable Scalability/IdempotentWorker
private
- def init_perform(set, chans, colors)
- @colors = colors
- @channels = chans
- start_connection set['server_host'], set['server_port']
- end
-
def start_connection(irker_server, irker_port)
begin
@socket = TCPSocket.new irker_server, irker_port
@@ -48,11 +46,13 @@ class IrkerWorker # rubocop:disable Scalability/IdempotentWorker
logger.fatal "Can't connect to Irker daemon: #{e}"
return false
end
+
true
end
- def sendtoirker(privmsg)
+ def send_to_irker(privmsg)
to_send = { to: @channels, privmsg: privmsg }
+
@socket.puts Gitlab::Json.dump(to_send)
end
@@ -60,51 +60,51 @@ class IrkerWorker # rubocop:disable Scalability/IdempotentWorker
@socket.close
end
- def send_branch_updates(push_data, project, repo_name, committer, branch)
- if Gitlab::Git.blank_ref?(push_data['before'])
- send_new_branch project, repo_name, committer, branch
- elsif Gitlab::Git.blank_ref?(push_data['after'])
- send_del_branch repo_name, committer, branch
- end
+ def send_branch_updates(push_data)
+ message =
+ if Gitlab::Git.blank_ref?(push_data['before'])
+ new_branch_message
+ elsif Gitlab::Git.blank_ref?(push_data['after'])
+ delete_branch_message
+ end
+
+ send_to_irker(message)
end
- def send_new_branch(project, repo_name, committer, branch)
- repo_path = project.full_path
- newbranch = "#{Gitlab.config.gitlab.url}/#{repo_path}/-/branches"
+ def new_branch_message
+ newbranch = "#{Gitlab.config.gitlab.url}/#{@repo_path}/-/branches"
newbranch = "\x0302\x1f#{newbranch}\x0f" if @colors
- privmsg = "[#{repo_name}] #{committer} has created a new branch " \
- "#{branch}: #{newbranch}"
- sendtoirker privmsg
+ "[#{@repo_name}] #{@committer} has created a new branch #{@branch}: #{newbranch}"
end
- def send_del_branch(repo_name, committer, branch)
- privmsg = "[#{repo_name}] #{committer} has deleted the branch #{branch}"
- sendtoirker privmsg
+ def delete_branch_message
+ "[#{@repo_name}] #{@committer} has deleted the branch #{@branch}"
end
- def send_commits(push_data, project, repo_name, committer, branch)
+ def send_commits(push_data)
return if push_data['total_commits_count'] == 0
# Next message is for number of commit pushed, if any
if Gitlab::Git.blank_ref?(push_data['before'])
# Tweak on push_data["before"] in order to have a nice compare URL
- push_data['before'] = before_on_new_branch push_data, project
+ push_data['before'] = before_on_new_branch(push_data)
end
- send_commits_count(push_data, project, repo_name, committer, branch)
+ send_commits_count(push_data)
# One message per commit, limited by 3 messages (same limit as the
# github irc hook)
commits = push_data['commits'].first(3)
- commits.each do |hook_attrs|
- send_one_commit project, hook_attrs, repo_name, branch
+ commits.each do |commit_attrs|
+ send_one_commit(commit_attrs)
end
end
- def before_on_new_branch(push_data, project)
- commit = commit_from_id project, push_data['commits'][0]['id']
+ def before_on_new_branch(push_data)
+ commit = commit_from_id(push_data['commits'][0]['id'])
parents = commit.parents
+
# Return old value if there's no new one
return push_data['before'] if parents.empty?
@@ -112,35 +112,36 @@ class IrkerWorker # rubocop:disable Scalability/IdempotentWorker
parents[0].id
end
- def send_commits_count(data, project, repo, committer, branch)
- url = compare_url data, project.full_path
- commits = colorize_commits data['total_commits_count']
+ def send_commits_count(push_data)
+ url = compare_url(push_data['before'], push_data['after'])
+ commits = colorize_commits(push_data['total_commits_count'])
+ new_commits = 'new commit'.pluralize(push_data['total_commits_count'])
- new_commits = 'new commit'.pluralize(data['total_commits_count'])
- sendtoirker "[#{repo}] #{committer} pushed #{commits} #{new_commits} " \
- "to #{branch}: #{url}"
+ send_to_irker("[#{@repo_name}] #{@committer} pushed #{commits} #{new_commits} " \
+ "to #{@branch}: #{url}")
end
- def compare_url(data, repo_path)
- sha1 = Commit.truncate_sha(data['before'])
- sha2 = Commit.truncate_sha(data['after'])
- compare_url = "#{Gitlab.config.gitlab.url}/#{repo_path}/-/compare" \
+ def compare_url(sha_before, sha_after)
+ sha1 = Commit.truncate_sha(sha_before)
+ sha2 = Commit.truncate_sha(sha_after)
+ compare_url = "#{Gitlab.config.gitlab.url}/#{@repo_path}/-/compare" \
"/#{sha1}...#{sha2}"
- colorize_url compare_url
+
+ colorize_url(compare_url)
end
- def send_one_commit(project, hook_attrs, repo_name, branch)
- commit = commit_from_id project, hook_attrs['id']
- sha = colorize_sha Commit.truncate_sha(hook_attrs['id'])
- author = hook_attrs['author']['name']
+ def send_one_commit(commit_attrs)
+ commit = commit_from_id(commit_attrs['id'])
+ sha = colorize_sha(Commit.truncate_sha(commit_attrs['id']))
+ author = commit_attrs['author']['name']
files = colorize_nb_files(files_count(commit))
title = commit.title
- sendtoirker "#{repo_name}/#{branch} #{sha} #{author} (#{files}): #{title}"
+ send_to_irker("#{@repo_name}/#{@branch} #{sha} #{author} (#{files}): #{title}")
end
- def commit_from_id(project, id)
- project.commit(id)
+ def commit_from_id(id)
+ @project.commit(id)
end
def files_count(commit)
diff --git a/app/workers/mail_scheduler/notification_service_worker.rb b/app/workers/mail_scheduler/notification_service_worker.rb
index 691af2a724d..309f23c8708 100644
--- a/app/workers/mail_scheduler/notification_service_worker.rb
+++ b/app/workers/mail_scheduler/notification_service_worker.rb
@@ -9,6 +9,7 @@ module MailScheduler
feature_category :issue_tracking
worker_resource_boundary :cpu
+ loggable_arguments 0
def perform(meth, *args)
check_arguments!(args)
diff --git a/app/workers/merge_worker.rb b/app/workers/merge_worker.rb
index cc5fe884aec..270bd831f96 100644
--- a/app/workers/merge_worker.rb
+++ b/app/workers/merge_worker.rb
@@ -6,6 +6,7 @@ class MergeWorker # rubocop:disable Scalability/IdempotentWorker
feature_category :source_code_management
urgency :high
weight 5
+ loggable_arguments 2
def perform(merge_request_id, current_user_id, params)
params = params.with_indifferent_access
diff --git a/app/workers/metrics/dashboard/prune_old_annotations_worker.rb b/app/workers/metrics/dashboard/prune_old_annotations_worker.rb
new file mode 100644
index 00000000000..2a9ce3bb8e6
--- /dev/null
+++ b/app/workers/metrics/dashboard/prune_old_annotations_worker.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Metrics
+ module Dashboard
+ class PruneOldAnnotationsWorker
+ include ApplicationWorker
+
+ DELETE_LIMIT = 10_000
+ DEFAULT_CUT_OFF_PERIOD = 2.weeks
+
+ feature_category :metrics
+
+ idempotent! # in the scope of 24 hours
+
+ def perform
+ stale_annotations = ::Metrics::Dashboard::Annotation.ending_before(DEFAULT_CUT_OFF_PERIOD.ago.beginning_of_day)
+ stale_annotations.delete_with_limit(DELETE_LIMIT)
+
+ self.class.perform_async if stale_annotations.exists?
+ end
+ end
+ end
+end
diff --git a/app/workers/metrics/dashboard/schedule_annotations_prune_worker.rb b/app/workers/metrics/dashboard/schedule_annotations_prune_worker.rb
new file mode 100644
index 00000000000..cbdd69c6e8c
--- /dev/null
+++ b/app/workers/metrics/dashboard/schedule_annotations_prune_worker.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Metrics
+ module Dashboard
+ class ScheduleAnnotationsPruneWorker
+ include ApplicationWorker
+ # rubocop:disable Scalability/CronWorkerContext
+ # This worker does not perform work scoped to a context
+ include CronjobQueue
+ # rubocop:enable Scalability/CronWorkerContext
+
+ feature_category :metrics
+
+ idempotent! # PruneOldAnnotationsWorker worker is idempotent in the scope of 24 hours
+
+ def perform
+ # Process is split into two jobs to avoid long running jobs, which are more prone to be disrupted
+ # mid work, which may cause some data not be delete, especially because cronjobs has retry option disabled
+ PruneOldAnnotationsWorker.perform_async
+ end
+ end
+ end
+end
diff --git a/app/workers/new_note_worker.rb b/app/workers/new_note_worker.rb
index 8ead87a9230..b31311b0e44 100644
--- a/app/workers/new_note_worker.rb
+++ b/app/workers/new_note_worker.rb
@@ -16,17 +16,14 @@ class NewNoteWorker # rubocop:disable Scalability/IdempotentWorker
NotificationService.new.new_note(note) unless skip_notification?(note)
Notes::PostProcessService.new(note).execute
else
- Rails.logger.error("NewNoteWorker: couldn't find note with ID=#{note_id}, skipping job") # rubocop:disable Gitlab/RailsLogger
+ Gitlab::AppLogger.error("NewNoteWorker: couldn't find note with ID=#{note_id}, skipping job")
end
end
+ # rubocop: enable CodeReuse/ActiveRecord
private
- # EE-only method
def skip_notification?(note)
- false
+ note.review.present?
end
- # rubocop: enable CodeReuse/ActiveRecord
end
-
-NewNoteWorker.prepend_if_ee('EE::NewNoteWorker')
diff --git a/app/workers/object_storage/background_move_worker.rb b/app/workers/object_storage/background_move_worker.rb
index 7b0a7c7ec58..fba91e49e43 100644
--- a/app/workers/object_storage/background_move_worker.rb
+++ b/app/workers/object_storage/background_move_worker.rb
@@ -7,6 +7,7 @@ module ObjectStorage
sidekiq_options retry: 5
feature_category_not_owned!
+ loggable_arguments 0, 1, 2, 3
def perform(uploader_class_name, subject_class_name, file_field, subject_id)
uploader_class = uploader_class_name.constantize
diff --git a/app/workers/object_storage/migrate_uploads_worker.rb b/app/workers/object_storage/migrate_uploads_worker.rb
index d9d21f2cb7e..33a0e0f5f88 100644
--- a/app/workers/object_storage/migrate_uploads_worker.rb
+++ b/app/workers/object_storage/migrate_uploads_worker.rb
@@ -7,6 +7,7 @@ module ObjectStorage
include ObjectStorageQueue
feature_category_not_owned!
+ loggable_arguments 0, 1, 2, 3
SanityCheckError = Class.new(StandardError)
diff --git a/app/workers/pages_worker.rb b/app/workers/pages_worker.rb
index 875f17282f9..d699e32c1a0 100644
--- a/app/workers/pages_worker.rb
+++ b/app/workers/pages_worker.rb
@@ -5,6 +5,7 @@ class PagesWorker # rubocop:disable Scalability/IdempotentWorker
sidekiq_options retry: 3
feature_category :pages
+ loggable_arguments 0, 1
def perform(action, *arg)
send(action, *arg) # rubocop:disable GitlabSecurity/PublicSend
diff --git a/app/workers/personal_access_tokens/expiring_worker.rb b/app/workers/personal_access_tokens/expiring_worker.rb
index 86240f827fc..f9940d9d014 100644
--- a/app/workers/personal_access_tokens/expiring_worker.rb
+++ b/app/workers/personal_access_tokens/expiring_worker.rb
@@ -15,9 +15,9 @@ module PersonalAccessTokens
with_context(user: user) do
notification_service.access_token_about_to_expire(user)
- Rails.logger.info "#{self.class}: Notifying User #{user.id} about expiring tokens" # rubocop:disable Gitlab/RailsLogger
+ Gitlab::AppLogger.info "#{self.class}: Notifying User #{user.id} about expiring tokens"
- user.personal_access_tokens.expiring_and_not_notified(limit_date).update_all(expire_notification_delivered: true)
+ user.personal_access_tokens.without_impersonation.expiring_and_not_notified(limit_date).update_all(expire_notification_delivered: true)
end
end
end
diff --git a/app/workers/pipeline_notification_worker.rb b/app/workers/pipeline_notification_worker.rb
index 3336383adf7..f4b43106bf2 100644
--- a/app/workers/pipeline_notification_worker.rb
+++ b/app/workers/pipeline_notification_worker.rb
@@ -7,10 +7,10 @@ class PipelineNotificationWorker # rubocop:disable Scalability/IdempotentWorker
urgency :high
worker_resource_boundary :cpu
- # rubocop: disable CodeReuse/ActiveRecord
def perform(pipeline_id, args = {})
case args
when Hash
+ args = args.with_indifferent_access
ref_status = args[:ref_status]
recipients = args[:recipients]
else # TODO: backward compatible interface, can be removed in 12.10
@@ -18,10 +18,9 @@ class PipelineNotificationWorker # rubocop:disable Scalability/IdempotentWorker
ref_status = nil
end
- pipeline = Ci::Pipeline.find_by(id: pipeline_id)
+ pipeline = Ci::Pipeline.find_by_id(pipeline_id)
return unless pipeline
NotificationService.new.pipeline_finished(pipeline, ref_status: ref_status, recipients: recipients)
end
- # rubocop: enable CodeReuse/ActiveRecord
end
diff --git a/app/workers/pipeline_process_worker.rb b/app/workers/pipeline_process_worker.rb
index 66a661dde71..cd7c82d3117 100644
--- a/app/workers/pipeline_process_worker.rb
+++ b/app/workers/pipeline_process_worker.rb
@@ -7,6 +7,7 @@ class PipelineProcessWorker # rubocop:disable Scalability/IdempotentWorker
queue_namespace :pipeline_processing
feature_category :continuous_integration
urgency :high
+ loggable_arguments 1
# rubocop: disable CodeReuse/ActiveRecord
def perform(pipeline_id, build_ids = nil)
diff --git a/app/workers/pipeline_update_ci_ref_status_worker.rb b/app/workers/pipeline_update_ci_ref_status_worker.rb
index 96e14e126de..9b1a5d8e7cf 100644
--- a/app/workers/pipeline_update_ci_ref_status_worker.rb
+++ b/app/workers/pipeline_update_ci_ref_status_worker.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
+# NOTE: This class is unused and to be removed in 13.1~
class PipelineUpdateCiRefStatusWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include PipelineQueue
diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb
index ddf112e648c..62d76294bc0 100644
--- a/app/workers/post_receive.rb
+++ b/app/workers/post_receive.rb
@@ -7,6 +7,7 @@ class PostReceive # rubocop:disable Scalability/IdempotentWorker
urgency :high
worker_resource_boundary :cpu
weight 5
+ loggable_arguments 0, 1, 2, 3
def perform(gl_repository, identifier, changes, push_options = {})
container, project, repo_type = Gitlab::GlRepository.parse(gl_repository)
diff --git a/app/workers/process_commit_worker.rb b/app/workers/process_commit_worker.rb
index bdfabea8938..5756ebb8358 100644
--- a/app/workers/process_commit_worker.rb
+++ b/app/workers/process_commit_worker.rb
@@ -13,8 +13,8 @@ class ProcessCommitWorker
feature_category :source_code_management
urgency :high
weight 3
-
idempotent!
+ loggable_arguments 2, 3
# project_id - The ID of the project this commit belongs to.
# user_id - The ID of the user that pushed the commit.
diff --git a/app/workers/project_cache_worker.rb b/app/workers/project_cache_worker.rb
index 573f903f4e0..b114c67de47 100644
--- a/app/workers/project_cache_worker.rb
+++ b/app/workers/project_cache_worker.rb
@@ -4,11 +4,11 @@
class ProjectCacheWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
- urgency :high
-
LEASE_TIMEOUT = 15.minutes.to_i
feature_category :source_code_management
+ urgency :high
+ loggable_arguments 1, 2, 3
# project_id - The ID of the project for which to flush the cache.
# files - An Array containing extra types of files to refresh such as
diff --git a/app/workers/project_export_worker.rb b/app/workers/project_export_worker.rb
index a287c511a65..d29348e85bc 100644
--- a/app/workers/project_export_worker.rb
+++ b/app/workers/project_export_worker.rb
@@ -8,6 +8,7 @@ class ProjectExportWorker # rubocop:disable Scalability/IdempotentWorker
feature_category :importers
worker_resource_boundary :memory
urgency :throttled
+ loggable_arguments 2, 3
def perform(current_user_id, project_id, after_export_strategy = {}, params = {})
current_user = User.find(current_user_id)
diff --git a/app/workers/propagate_integration_worker.rb b/app/workers/propagate_integration_worker.rb
new file mode 100644
index 00000000000..15c0e761a0a
--- /dev/null
+++ b/app/workers/propagate_integration_worker.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class PropagateIntegrationWorker
+ include ApplicationWorker
+
+ feature_category :integrations
+ idempotent!
+ loggable_arguments 1
+
+ def perform(integration_id, overwrite)
+ Admin::PropagateIntegrationService.propagate(
+ integration: Service.find(integration_id),
+ overwrite: overwrite
+ )
+ end
+end
diff --git a/app/workers/rebase_worker.rb b/app/workers/rebase_worker.rb
index 2e13af5e0aa..ee9ae827bb6 100644
--- a/app/workers/rebase_worker.rb
+++ b/app/workers/rebase_worker.rb
@@ -7,6 +7,7 @@ class RebaseWorker # rubocop:disable Scalability/IdempotentWorker
feature_category :source_code_management
weight 2
+ loggable_arguments 2
def perform(merge_request_id, current_user_id, skip_ci = false)
current_user = User.find(current_user_id)
diff --git a/app/workers/remove_expired_group_links_worker.rb b/app/workers/remove_expired_group_links_worker.rb
index 8226f22837c..3f1a484f384 100644
--- a/app/workers/remove_expired_group_links_worker.rb
+++ b/app/workers/remove_expired_group_links_worker.rb
@@ -7,10 +7,12 @@ class RemoveExpiredGroupLinksWorker # rubocop:disable Scalability/IdempotentWork
feature_category :authentication_and_authorization
def perform
- ProjectGroupLink.expired.destroy_all # rubocop: disable DestroyAll
+ ProjectGroupLink.expired.find_each do |link|
+ Projects::GroupLinks::DestroyService.new(link.project, nil).execute(link)
+ end
GroupGroupLink.expired.find_in_batches do |link_batch|
- Groups::GroupLinks::DestroyService.new(nil, nil).execute(link_batch)
+ Groups::GroupLinks::DestroyService.new(nil, nil).execute(link_batch, skip_authorization: true)
end
end
end
diff --git a/app/workers/repository_check/batch_worker.rb b/app/workers/repository_check/batch_worker.rb
index 9e762860ec6..1e2cb912598 100644
--- a/app/workers/repository_check/batch_worker.rb
+++ b/app/workers/repository_check/batch_worker.rb
@@ -12,6 +12,8 @@ module RepositoryCheck
attr_reader :shard_name
+ loggable_arguments 0
+
def perform(shard_name)
@shard_name = shard_name
diff --git a/app/workers/repository_import_worker.rb b/app/workers/repository_import_worker.rb
index 9f17ef467e3..30570a2227e 100644
--- a/app/workers/repository_import_worker.rb
+++ b/app/workers/repository_import_worker.rb
@@ -43,7 +43,12 @@ class RepositoryImportWorker # rubocop:disable Scalability/IdempotentWorker
def start_import
return true if start(project.import_state)
- Rails.logger.info("Project #{project.full_path} was in inconsistent state (#{project.import_status}) while importing.") # rubocop:disable Gitlab/RailsLogger
+ Gitlab::Import::Logger.info(
+ message: 'Project was in inconsistent state while importing',
+ project_full_path: project.full_path,
+ project_import_status: project.import_status
+ )
+
false
end
diff --git a/app/workers/repository_remove_remote_worker.rb b/app/workers/repository_remove_remote_worker.rb
index 23a9ec1e202..5e632b1b1ca 100644
--- a/app/workers/repository_remove_remote_worker.rb
+++ b/app/workers/repository_remove_remote_worker.rb
@@ -5,6 +5,7 @@ class RepositoryRemoveRemoteWorker # rubocop:disable Scalability/IdempotentWorke
include ExclusiveLeaseGuard
feature_category :source_code_management
+ loggable_arguments 1
LEASE_TIMEOUT = 1.hour
diff --git a/app/workers/repository_update_remote_mirror_worker.rb b/app/workers/repository_update_remote_mirror_worker.rb
index cfff2382f04..21b5916f459 100644
--- a/app/workers/repository_update_remote_mirror_worker.rb
+++ b/app/workers/repository_update_remote_mirror_worker.rb
@@ -10,6 +10,7 @@ class RepositoryUpdateRemoteMirrorWorker # rubocop:disable Scalability/Idempoten
sidekiq_options retry: 3, dead: false
feature_category :source_code_management
+ loggable_arguments 1
LOCK_WAIT_TIME = 30.seconds
MAX_TRIES = 3
diff --git a/app/workers/stuck_import_jobs_worker.rb b/app/workers/stuck_import_jobs_worker.rb
index 6a48b78b22c..ce8d5bf0219 100644
--- a/app/workers/stuck_import_jobs_worker.rb
+++ b/app/workers/stuck_import_jobs_worker.rb
@@ -1,75 +1,19 @@
# frozen_string_literal: true
class StuckImportJobsWorker # rubocop:disable Scalability/IdempotentWorker
- include ApplicationWorker
- # rubocop:disable Scalability/CronWorkerContext
- # This worker updates several import states inline and does not schedule
- # other jobs. So no context needed
- include CronjobQueue
- # rubocop:enable Scalability/CronWorkerContext
-
- feature_category :importers
- worker_resource_boundary :cpu
-
- IMPORT_JOBS_EXPIRATION = 15.hours.to_i
-
- def perform
- import_state_without_jid_count = mark_import_states_without_jid_as_failed!
- import_state_with_jid_count = mark_import_states_with_jid_as_failed!
-
- Gitlab::Metrics.add_event(:stuck_import_jobs,
- projects_without_jid_count: import_state_without_jid_count,
- projects_with_jid_count: import_state_with_jid_count)
- end
+ include Gitlab::Import::StuckImportJob
private
- def mark_import_states_without_jid_as_failed!
- enqueued_import_states_without_jid.each do |import_state|
- import_state.mark_as_failed(error_message)
- end.count
- end
-
- # rubocop: disable CodeReuse/ActiveRecord
- def mark_import_states_with_jid_as_failed!
- jids_and_ids = enqueued_import_states_with_jid.pluck(:jid, :id).to_h
-
- # Find the jobs that aren't currently running or that exceeded the threshold.
- completed_jids = Gitlab::SidekiqStatus.completed_jids(jids_and_ids.keys)
- return unless completed_jids.any?
-
- completed_import_state_ids = jids_and_ids.values_at(*completed_jids)
-
- # We select the import states again, because they may have transitioned from
- # scheduled/started to finished/failed while we were looking up their Sidekiq status.
- completed_import_states = enqueued_import_states_with_jid.where(id: completed_import_state_ids)
-
- completed_import_state_jids = completed_import_states.map { |import_state| import_state.jid }.join(', ')
- Rails.logger.info("Marked stuck import jobs as failed. JIDs: #{completed_import_state_jids}") # rubocop:disable Gitlab/RailsLogger
-
- completed_import_states.each do |import_state|
- import_state.mark_as_failed(error_message)
- end.count
+ def track_metrics(with_jid_count, without_jid_count)
+ Gitlab::Metrics.add_event(
+ :stuck_import_jobs,
+ projects_without_jid_count: without_jid_count,
+ projects_with_jid_count: with_jid_count
+ )
end
- # rubocop: enable CodeReuse/ActiveRecord
def enqueued_import_states
ProjectImportState.with_status([:scheduled, :started])
end
-
- # rubocop: disable CodeReuse/ActiveRecord
- def enqueued_import_states_with_jid
- enqueued_import_states.where.not(jid: nil)
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
- # rubocop: disable CodeReuse/ActiveRecord
- def enqueued_import_states_without_jid
- enqueued_import_states.where(jid: nil)
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
- def error_message
- _("Import timed out. Import took longer than %{import_jobs_expiration} seconds") % { import_jobs_expiration: IMPORT_JOBS_EXPIRATION }
- end
end
diff --git a/app/workers/todos_destroyer/entity_leave_worker.rb b/app/workers/todos_destroyer/entity_leave_worker.rb
index 558cc32d158..4996456dc91 100644
--- a/app/workers/todos_destroyer/entity_leave_worker.rb
+++ b/app/workers/todos_destroyer/entity_leave_worker.rb
@@ -5,6 +5,8 @@ module TodosDestroyer
include ApplicationWorker
include TodosDestroyerQueue
+ loggable_arguments 2
+
def perform(user_id, entity_id, entity_type)
::Todos::Destroy::EntityLeaveService.new(user_id, entity_id, entity_type).execute
end
diff --git a/app/workers/update_external_pull_requests_worker.rb b/app/workers/update_external_pull_requests_worker.rb
index 0d48877e1b0..e916331ae82 100644
--- a/app/workers/update_external_pull_requests_worker.rb
+++ b/app/workers/update_external_pull_requests_worker.rb
@@ -5,6 +5,7 @@ class UpdateExternalPullRequestsWorker # rubocop:disable Scalability/IdempotentW
feature_category :source_code_management
weight 3
+ loggable_arguments 2
def perform(project_id, user_id, ref)
project = Project.find_by_id(project_id)
diff --git a/app/workers/update_merge_requests_worker.rb b/app/workers/update_merge_requests_worker.rb
index 63bb6171b9c..98534b258a7 100644
--- a/app/workers/update_merge_requests_worker.rb
+++ b/app/workers/update_merge_requests_worker.rb
@@ -7,6 +7,7 @@ class UpdateMergeRequestsWorker # rubocop:disable Scalability/IdempotentWorker
urgency :high
worker_resource_boundary :cpu
weight 3
+ loggable_arguments 2, 3, 4
LOG_TIME_THRESHOLD = 90 # seconds
diff --git a/app/workers/web_hook_worker.rb b/app/workers/web_hook_worker.rb
index 6e1e7e7d62e..5230f3bfa1f 100644
--- a/app/workers/web_hook_worker.rb
+++ b/app/workers/web_hook_worker.rb
@@ -5,6 +5,7 @@ class WebHookWorker # rubocop:disable Scalability/IdempotentWorker
feature_category :integrations
worker_has_external_dependencies!
+ loggable_arguments 2
sidekiq_options retry: 4, dead: false
diff --git a/babel.config.js b/babel.config.js
index 9c419b93b33..6d377305e46 100644
--- a/babel.config.js
+++ b/babel.config.js
@@ -2,7 +2,7 @@
const BABEL_ENV = process.env.BABEL_ENV || process.env.NODE_ENV || null;
-const presets = [
+let presets = [
[
'@babel/preset-env',
{
@@ -49,6 +49,17 @@ if (isJest) {
https://gitlab.com/gitlab-org/gitlab-foss/issues/58390
*/
plugins.push('babel-plugin-dynamic-import-node');
+
+ presets = [
+ [
+ '@babel/preset-env',
+ {
+ targets: {
+ node: 'current',
+ },
+ },
+ ],
+ ];
}
module.exports = { presets, plugins, sourceType: 'unambiguous' };
diff --git a/bin/background_jobs_sk b/bin/background_jobs_sk
index fb7de0a6180..0aab69126b2 100755
--- a/bin/background_jobs_sk
+++ b/bin/background_jobs_sk
@@ -36,7 +36,7 @@ start_silent()
start_sidekiq()
{
cmd="exec"
- chpst=$(which chpst)
+ chpst=$(command -v chpst)
if [ -n "$chpst" ]; then
cmd="${cmd} ${chpst} -P"
diff --git a/bin/background_jobs_sk_cluster b/bin/background_jobs_sk_cluster
index b1d5fce204e..6188ec51420 100755
--- a/bin/background_jobs_sk_cluster
+++ b/bin/background_jobs_sk_cluster
@@ -43,7 +43,7 @@ restart()
start_sidekiq()
{
cmd="exec"
- chpst=$(which chpst)
+ chpst=$(command -v chpst)
if [ -n "$chpst" ]; then
cmd="${cmd} ${chpst} -P"
diff --git a/bin/secpick b/bin/secpick
index a68dabc8c47..517465d3f5d 100755
--- a/bin/secpick
+++ b/bin/secpick
@@ -21,28 +21,18 @@ module Secpick
@options = self.class.options
end
- def ee?
- File.exist?(File.expand_path('../ee/app/models/license.rb', __dir__))
- end
-
def dry_run?
@options[:try] == true
end
- def original_branch
- @options[:branch].strip
- end
-
def source_branch
- branch = "#{original_branch}-#{@options[:version]}"
+ branch = "#{@options[:branch]}-#{@options[:version]}"
branch.prepend("#{BRANCH_PREFIX}-") unless branch.start_with?("#{BRANCH_PREFIX}-")
branch.freeze
end
def stable_branch
- "#{@options[:version]}-#{STABLE_SUFFIX}".tap do |name|
- name << "-ee" if ee?
- end.freeze
+ "#{@options[:version]}-#{STABLE_SUFFIX}-ee".freeze
end
def git_commands
@@ -50,7 +40,7 @@ module Secpick
"git checkout -B #{source_branch} #{@options[:remote]}/#{stable_branch} --no-track",
"git cherry-pick #{@options[:sha]}",
"git push #{@options[:remote]} #{source_branch}",
- "git checkout #{original_branch}"]
+ "git checkout #{@options[:branch]}"]
end
def gitlab_params
@@ -64,11 +54,7 @@ module Secpick
end
def new_mr_url
- if ee?
- SECURITY_MR_URL
- else
- SECURITY_MR_URL.sub('/gitlab/', '/gitlab-foss/')
- end
+ SECURITY_MR_URL
end
def create!
@@ -131,8 +117,8 @@ module Secpick
parser.parse!
- options[:sha] ||= `git rev-parse HEAD`
- options[:branch] ||= `git rev-parse --abbrev-ref HEAD`
+ options[:sha] ||= `git rev-parse HEAD`.strip
+ options[:branch] ||= `git rev-parse --abbrev-ref HEAD`.strip
options[:remote] ||= DEFAULT_REMOTE
nil_options = options.select {|_, v| v.nil? }
diff --git a/bin/web b/bin/web
index f640abf0fbc..b714ad1e1bb 100755
--- a/bin/web
+++ b/bin/web
@@ -3,19 +3,18 @@
set -e
cd $(dirname $0)/..
-app_root=$(pwd)
case "$USE_WEB_SERVER" in
- puma|"") # and the "" defines default
- exec bin/web_puma "$@"
- ;;
+ puma|"") # and the "" defines default
+ exec bin/web_puma "$@"
+ ;;
- unicorn)
- exec bin/web_unicorn "$@"
- ;;
+ unicorn)
+ exec bin/web_unicorn "$@"
+ ;;
- *)
- echo "Unkown web server used by USE_WEB_SERVER: $USE_WEB_SERVER."
- exit 1
- ;;
+ *)
+ echo "Unkown web server used by USE_WEB_SERVER: $USE_WEB_SERVER."
+ exit 1
+ ;;
esac
diff --git a/cable/config.ru b/cable/config.ru
index a528672ce25..c50bc41511d 100644
--- a/cable/config.ru
+++ b/cable/config.ru
@@ -5,4 +5,6 @@ Rails.application.eager_load!
ACTION_CABLE_SERVER = true
+use ActionDispatch::RequestId
+
run ActionCable.server
diff --git a/changelogs/unreleased/11805-support-first-name-and-last-name-attributes-in-ldap-user-sync.yml b/changelogs/unreleased/11805-support-first-name-and-last-name-attributes-in-ldap-user-sync.yml
new file mode 100644
index 00000000000..4878eeb26e7
--- /dev/null
+++ b/changelogs/unreleased/11805-support-first-name-and-last-name-attributes-in-ldap-user-sync.yml
@@ -0,0 +1,5 @@
+---
+title: Support first_name and last_name attributes in LDAP user sync
+merge_request: 29542
+author:
+type: added
diff --git a/changelogs/unreleased/118613-spam-api-call.yml b/changelogs/unreleased/118613-spam-api-call.yml
new file mode 100644
index 00000000000..68d4aa27071
--- /dev/null
+++ b/changelogs/unreleased/118613-spam-api-call.yml
@@ -0,0 +1,5 @@
+---
+title: SpamVerdictService can call external spam check endpoint
+merge_request: 31449
+author:
+type: added
diff --git a/changelogs/unreleased/13049-design-view-allow-comment-pins-on-designs-to-be-resolvable.yml b/changelogs/unreleased/13049-design-view-allow-comment-pins-on-designs-to-be-resolvable.yml
new file mode 100644
index 00000000000..579485e7488
--- /dev/null
+++ b/changelogs/unreleased/13049-design-view-allow-comment-pins-on-designs-to-be-resolvable.yml
@@ -0,0 +1,5 @@
+---
+title: "[Frontend] Resolvable design discussions"
+merge_request: 32399
+author:
+type: added
diff --git a/changelogs/unreleased/13049-graphql-resolve-discussion.yml b/changelogs/unreleased/13049-graphql-resolve-discussion.yml
new file mode 100644
index 00000000000..850d5b5aac4
--- /dev/null
+++ b/changelogs/unreleased/13049-graphql-resolve-discussion.yml
@@ -0,0 +1,5 @@
+---
+title: Add a GraphQL mutation for toggling the resolved state of a Discussion
+merge_request: 32934
+author:
+type: added
diff --git a/changelogs/unreleased/17555-custom-text-for-badges.yml b/changelogs/unreleased/17555-custom-text-for-badges.yml
new file mode 100644
index 00000000000..61132efa264
--- /dev/null
+++ b/changelogs/unreleased/17555-custom-text-for-badges.yml
@@ -0,0 +1,5 @@
+---
+title: Allow customization of badge key_text and key_width
+merge_request: 29381
+author: Fabian Schneider @fabsrc
+type: added
diff --git a/changelogs/unreleased/191455-add-a-button-to-assign-users-who-have-commented-on-an-issue.yml b/changelogs/unreleased/191455-add-a-button-to-assign-users-who-have-commented-on-an-issue.yml
new file mode 100644
index 00000000000..370d8f8ceb3
--- /dev/null
+++ b/changelogs/unreleased/191455-add-a-button-to-assign-users-who-have-commented-on-an-issue.yml
@@ -0,0 +1,5 @@
+---
+title: Resolve Add a button to assign users who have commented on an issue
+merge_request: 23883
+author:
+type: added
diff --git a/changelogs/unreleased/191455-add-a-button-to-quickly-assign-users-who-have-commented-on-an-issu.yml b/changelogs/unreleased/191455-add-a-button-to-quickly-assign-users-who-have-commented-on-an-issu.yml
new file mode 100644
index 00000000000..df303695865
--- /dev/null
+++ b/changelogs/unreleased/191455-add-a-button-to-quickly-assign-users-who-have-commented-on-an-issu.yml
@@ -0,0 +1,5 @@
+---
+title: Add api.js methods to update issues and merge requests
+merge_request: 32893
+author:
+type: added
diff --git a/changelogs/unreleased/195692-too-much-x-axis-padding-on-the-environments-dashboard-content.yml b/changelogs/unreleased/195692-too-much-x-axis-padding-on-the-environments-dashboard-content.yml
new file mode 100644
index 00000000000..0ee3d01d030
--- /dev/null
+++ b/changelogs/unreleased/195692-too-much-x-axis-padding-on-the-environments-dashboard-content.yml
@@ -0,0 +1,5 @@
+---
+title: Resolve incorrect x-axis padding on the Environments Dashboard
+merge_request: 32533
+author:
+type: fixed
diff --git a/changelogs/unreleased/196544-nodemetrics-size.yml b/changelogs/unreleased/196544-nodemetrics-size.yml
new file mode 100644
index 00000000000..1319ef2f624
--- /dev/null
+++ b/changelogs/unreleased/196544-nodemetrics-size.yml
@@ -0,0 +1,5 @@
+---
+title: Added node size to cluster index
+merge_request: 32435
+author:
+type: changed
diff --git a/changelogs/unreleased/196630-commit-tab.yml b/changelogs/unreleased/196630-commit-tab.yml
new file mode 100644
index 00000000000..38b158d1520
--- /dev/null
+++ b/changelogs/unreleased/196630-commit-tab.yml
@@ -0,0 +1,5 @@
+---
+title: Don't hide Commit tab in Web IDE when there are no changes yet
+merge_request: 32979
+author:
+type: added
diff --git a/changelogs/unreleased/196784-add-container-expiration-policy-to-graphql-project.yml b/changelogs/unreleased/196784-add-container-expiration-policy-to-graphql-project.yml
new file mode 100644
index 00000000000..dfd80b80241
--- /dev/null
+++ b/changelogs/unreleased/196784-add-container-expiration-policy-to-graphql-project.yml
@@ -0,0 +1,5 @@
+---
+title: Add the container expiration policy attribute to the project GraphQL type
+merge_request: 32100
+author:
+type: added
diff --git a/changelogs/unreleased/196784-graphql-mutations-for-container-expiration-policies.yml b/changelogs/unreleased/196784-graphql-mutations-for-container-expiration-policies.yml
new file mode 100644
index 00000000000..3205401f5db
--- /dev/null
+++ b/changelogs/unreleased/196784-graphql-mutations-for-container-expiration-policies.yml
@@ -0,0 +1,5 @@
+---
+title: Add container expiration policy objects to the GraphQL API
+merge_request: 32944
+author:
+type: added
diff --git a/changelogs/unreleased/197426-error-details-timeago-tooltip.yml b/changelogs/unreleased/197426-error-details-timeago-tooltip.yml
new file mode 100644
index 00000000000..926f22bfa68
--- /dev/null
+++ b/changelogs/unreleased/197426-error-details-timeago-tooltip.yml
@@ -0,0 +1,5 @@
+---
+title: Show tooltip on error detail page when hovering over dates
+merge_request: 34506
+author:
+type: added
diff --git a/changelogs/unreleased/199245-search-api-seems-to-ignore-ref-returns-spurious-results-from-maste.yml b/changelogs/unreleased/199245-search-api-seems-to-ignore-ref-returns-spurious-results-from-maste.yml
new file mode 100644
index 00000000000..8e9f49ad14f
--- /dev/null
+++ b/changelogs/unreleased/199245-search-api-seems-to-ignore-ref-returns-spurious-results-from-maste.yml
@@ -0,0 +1,5 @@
+---
+title: Fix incorrect commit search results returned when searching with ref
+merge_request: 33216
+author:
+type: fixed
diff --git a/changelogs/unreleased/199250-expose-release-yaml-as-steps-via-api-2.yml b/changelogs/unreleased/199250-expose-release-yaml-as-steps-via-api-2.yml
new file mode 100644
index 00000000000..58d02d65b71
--- /dev/null
+++ b/changelogs/unreleased/199250-expose-release-yaml-as-steps-via-api-2.yml
@@ -0,0 +1,5 @@
+---
+title: Convert `:release` yaml to `release-cli` commands
+merge_request: 34261
+author:
+type: added
diff --git a/changelogs/unreleased/199732-show-more-context-to-jump-unresolved-button.yml b/changelogs/unreleased/199732-show-more-context-to-jump-unresolved-button.yml
new file mode 100644
index 00000000000..0a654b11442
--- /dev/null
+++ b/changelogs/unreleased/199732-show-more-context-to-jump-unresolved-button.yml
@@ -0,0 +1,5 @@
+---
+title: Show more context in unresolved jump button
+merge_request: 32737
+author:
+type: changed
diff --git a/changelogs/unreleased/200016-display-downstream-pipeline-errors.yml b/changelogs/unreleased/200016-display-downstream-pipeline-errors.yml
new file mode 100644
index 00000000000..4457947639f
--- /dev/null
+++ b/changelogs/unreleased/200016-display-downstream-pipeline-errors.yml
@@ -0,0 +1,5 @@
+---
+title: Implement displaying downstream pipeline error details
+merge_request: 32844
+author:
+type: fixed
diff --git a/changelogs/unreleased/20069-ci-secrets-rake-task.yml b/changelogs/unreleased/20069-ci-secrets-rake-task.yml
new file mode 100644
index 00000000000..6c75d8945e5
--- /dev/null
+++ b/changelogs/unreleased/20069-ci-secrets-rake-task.yml
@@ -0,0 +1,5 @@
+---
+title: Add rake task to verify encrypted data through secrets
+merge_request: 21851
+author:
+type: added
diff --git a/changelogs/unreleased/205424-add-api-for-share-groups-with-groups.yml b/changelogs/unreleased/205424-add-api-for-share-groups-with-groups.yml
new file mode 100644
index 00000000000..a8d892db2ff
--- /dev/null
+++ b/changelogs/unreleased/205424-add-api-for-share-groups-with-groups.yml
@@ -0,0 +1,5 @@
+---
+title: Add API support for sharing groups with groups
+merge_request: 32008
+author:
+type: added
diff --git a/changelogs/unreleased/207257-specify-asset-types-in-releases-2.yml b/changelogs/unreleased/207257-specify-asset-types-in-releases-2.yml
new file mode 100644
index 00000000000..f897faeeaa2
--- /dev/null
+++ b/changelogs/unreleased/207257-specify-asset-types-in-releases-2.yml
@@ -0,0 +1,5 @@
+---
+title: Expose `release_links.type` via API
+merge_request: 33154
+author:
+type: changed
diff --git a/changelogs/unreleased/207257-specify-asset-types-in-releases-3.yml b/changelogs/unreleased/207257-specify-asset-types-in-releases-3.yml
new file mode 100644
index 00000000000..bf5de47e7ff
--- /dev/null
+++ b/changelogs/unreleased/207257-specify-asset-types-in-releases-3.yml
@@ -0,0 +1,5 @@
+---
+title: Add `link_type` to `ReleaseLink` GraphQL type
+merge_request: 33386
+author:
+type: added
diff --git a/changelogs/unreleased/207257-specify-asset-types-in-releases.yml b/changelogs/unreleased/207257-specify-asset-types-in-releases.yml
new file mode 100644
index 00000000000..ee11eb72389
--- /dev/null
+++ b/changelogs/unreleased/207257-specify-asset-types-in-releases.yml
@@ -0,0 +1,5 @@
+---
+title: Add link_type column to release_links table
+merge_request: 33156
+author:
+type: changed
diff --git a/changelogs/unreleased/207990-secret-detection-ci-template.yml b/changelogs/unreleased/207990-secret-detection-ci-template.yml
new file mode 100644
index 00000000000..246ac1c096a
--- /dev/null
+++ b/changelogs/unreleased/207990-secret-detection-ci-template.yml
@@ -0,0 +1,5 @@
+---
+title: Add secret detection template
+merge_request: 33869
+author:
+type: added
diff --git a/changelogs/unreleased/208412-featurable.yml b/changelogs/unreleased/208412-featurable.yml
new file mode 100644
index 00000000000..02adcccec0b
--- /dev/null
+++ b/changelogs/unreleased/208412-featurable.yml
@@ -0,0 +1,5 @@
+---
+title: Extract featurable concern from ProjectFeature
+merge_request: 31700
+author: Alexander Randa
+type: other
diff --git a/changelogs/unreleased/208970-group_auth_update_to_consider_shared_groups.yml b/changelogs/unreleased/208970-group_auth_update_to_consider_shared_groups.yml
new file mode 100644
index 00000000000..2947e9d261c
--- /dev/null
+++ b/changelogs/unreleased/208970-group_auth_update_to_consider_shared_groups.yml
@@ -0,0 +1,5 @@
+---
+title: Group authorization refresh to consider shared groups
+merge_request: 31204
+author:
+type: fixed
diff --git a/changelogs/unreleased/209025-design-filename-limit-migrations.yml b/changelogs/unreleased/209025-design-filename-limit-migrations.yml
new file mode 100644
index 00000000000..92379b29e34
--- /dev/null
+++ b/changelogs/unreleased/209025-design-filename-limit-migrations.yml
@@ -0,0 +1,6 @@
+---
+title: Add database migrations to design_management_designs.filename to enforce
+ a 255 character limit, and modify any filenames that exceed that limit
+merge_request: 33565
+author:
+type: changed
diff --git a/changelogs/unreleased/209345-add-ds-detect-kotlin-build-file.yml b/changelogs/unreleased/209345-add-ds-detect-kotlin-build-file.yml
new file mode 100644
index 00000000000..a6eca5f5ad6
--- /dev/null
+++ b/changelogs/unreleased/209345-add-ds-detect-kotlin-build-file.yml
@@ -0,0 +1,5 @@
+---
+title: Add DS detection of build.gradle.kts
+merge_request: !32727
+author:
+type: fixed
diff --git a/changelogs/unreleased/21002-slack-opened-merge-request-webhook-message-is-malformed.yml b/changelogs/unreleased/21002-slack-opened-merge-request-webhook-message-is-malformed.yml
new file mode 100644
index 00000000000..840f72be481
--- /dev/null
+++ b/changelogs/unreleased/21002-slack-opened-merge-request-webhook-message-is-malformed.yml
@@ -0,0 +1,5 @@
+---
+title: Add explicit mention of Merge request in Slack message
+merge_request: 33152
+author:
+type: changed
diff --git a/changelogs/unreleased/210281-label-for-pipeline-schedule-active.yml b/changelogs/unreleased/210281-label-for-pipeline-schedule-active.yml
new file mode 100644
index 00000000000..7b3ad814382
--- /dev/null
+++ b/changelogs/unreleased/210281-label-for-pipeline-schedule-active.yml
@@ -0,0 +1,5 @@
+---
+title: Fix 'Active' checkbox text in Pipeline Schedule form to be a label
+merge_request: 27054
+author: Jonston Chan
+type: fixed
diff --git a/changelogs/unreleased/210482-update-descriptions-on-the-integrations-and-webhooks-pages-at-the-.yml b/changelogs/unreleased/210482-update-descriptions-on-the-integrations-and-webhooks-pages-at-the-.yml
new file mode 100644
index 00000000000..4e8aa0d7ca5
--- /dev/null
+++ b/changelogs/unreleased/210482-update-descriptions-on-the-integrations-and-webhooks-pages-at-the-.yml
@@ -0,0 +1,5 @@
+---
+title: Change copy of webhooks / integration help text
+merge_request: 34301
+author:
+type: changed
diff --git a/changelogs/unreleased/210550-conan-export-tgz.yml b/changelogs/unreleased/210550-conan-export-tgz.yml
new file mode 100644
index 00000000000..bffd0b8b644
--- /dev/null
+++ b/changelogs/unreleased/210550-conan-export-tgz.yml
@@ -0,0 +1,5 @@
+---
+title: Conan package registry support for the conan_export.tgz file
+merge_request: 32866
+author:
+type: fixed
diff --git a/changelogs/unreleased/211340-change-chart-legend-format-to-tabular-format.yml b/changelogs/unreleased/211340-change-chart-legend-format-to-tabular-format.yml
new file mode 100644
index 00000000000..9db7b230ded
--- /dev/null
+++ b/changelogs/unreleased/211340-change-chart-legend-format-to-tabular-format.yml
@@ -0,0 +1,5 @@
+---
+title: Change legends in monitor dashboards to tabular layout
+merge_request: 30131
+author:
+type: changed
diff --git a/changelogs/unreleased/211461-destroy-annotations-graphql-endpoint.yml b/changelogs/unreleased/211461-destroy-annotations-graphql-endpoint.yml
new file mode 100644
index 00000000000..7e9edaad64b
--- /dev/null
+++ b/changelogs/unreleased/211461-destroy-annotations-graphql-endpoint.yml
@@ -0,0 +1,5 @@
+---
+title: Added delete action for Dashboard Annotations in GraphQL
+merge_request: 33468
+author:
+type: added
diff --git a/changelogs/unreleased/211828-placement-of-add-designs-button-could-be-confusing-with-the-additi.yml b/changelogs/unreleased/211828-placement-of-add-designs-button-could-be-confusing-with-the-additi.yml
new file mode 100644
index 00000000000..cb172caf997
--- /dev/null
+++ b/changelogs/unreleased/211828-placement-of-add-designs-button-could-be-confusing-with-the-additi.yml
@@ -0,0 +1,5 @@
+---
+title: Rename Add Designs button
+merge_request: 33491
+author:
+type: changed
diff --git a/changelogs/unreleased/212063-images-overflow-at-releases-list-panel.yml b/changelogs/unreleased/212063-images-overflow-at-releases-list-panel.yml
new file mode 100644
index 00000000000..dcfe1e56491
--- /dev/null
+++ b/changelogs/unreleased/212063-images-overflow-at-releases-list-panel.yml
@@ -0,0 +1,5 @@
+---
+title: Resolve image overflow at releases list panel
+merge_request: 32307
+author:
+type: fixed
diff --git a/changelogs/unreleased/212848.yml b/changelogs/unreleased/212848.yml
new file mode 100644
index 00000000000..c4a33866d62
--- /dev/null
+++ b/changelogs/unreleased/212848.yml
@@ -0,0 +1,5 @@
+---
+title: Removed UltraAuth integration for OmniAuth
+merge_request: 29330
+author: Kartikey Tanna
+type: removed
diff --git a/changelogs/unreleased/212882-add-cpu-mem-charts.yml b/changelogs/unreleased/212882-add-cpu-mem-charts.yml
new file mode 100644
index 00000000000..52e645cead7
--- /dev/null
+++ b/changelogs/unreleased/212882-add-cpu-mem-charts.yml
@@ -0,0 +1,5 @@
+---
+title: Add CPU, memory usage charts to self monitoring default dashboard
+merge_request: 33532
+author:
+type: changed
diff --git a/changelogs/unreleased/212882-add-instance-variable.yml b/changelogs/unreleased/212882-add-instance-variable.yml
new file mode 100644
index 00000000000..19131ff7ab9
--- /dev/null
+++ b/changelogs/unreleased/212882-add-instance-variable.yml
@@ -0,0 +1,5 @@
+---
+title: Add ability to filter self monitoring resource usage charts by instance name
+merge_request: 34084
+author:
+type: changed
diff --git a/changelogs/unreleased/213009-when-filtering-by-groups-icons-are-misaligned.yml b/changelogs/unreleased/213009-when-filtering-by-groups-icons-are-misaligned.yml
new file mode 100644
index 00000000000..e0674b167a2
--- /dev/null
+++ b/changelogs/unreleased/213009-when-filtering-by-groups-icons-are-misaligned.yml
@@ -0,0 +1,6 @@
+---
+title: Improve spacing and wrapping of group actions buttons and stats in group list
+ view
+merge_request: 32786
+author:
+type: fixed
diff --git a/changelogs/unreleased/213587-ide-ipad-scroll-issue.yml b/changelogs/unreleased/213587-ide-ipad-scroll-issue.yml
new file mode 100644
index 00000000000..b542581f0f8
--- /dev/null
+++ b/changelogs/unreleased/213587-ide-ipad-scroll-issue.yml
@@ -0,0 +1,5 @@
+---
+title: Fix issues with scroll on iOS / iPad OS
+merge_request: 34486
+author:
+type: fixed
diff --git a/changelogs/unreleased/213597-add-in-this-group-option-to-search-dropdown-where-not-present.yml b/changelogs/unreleased/213597-add-in-this-group-option-to-search-dropdown-where-not-present.yml
new file mode 100644
index 00000000000..c8d405afc01
--- /dev/null
+++ b/changelogs/unreleased/213597-add-in-this-group-option-to-search-dropdown-where-not-present.yml
@@ -0,0 +1,5 @@
+---
+title: Enable the `in this group` action in the Search dropdown
+merge_request: 31939
+author:
+type: changed
diff --git a/changelogs/unreleased/213699-remove-search-results-autocomplete.yml b/changelogs/unreleased/213699-remove-search-results-autocomplete.yml
new file mode 100644
index 00000000000..539d4695658
--- /dev/null
+++ b/changelogs/unreleased/213699-remove-search-results-autocomplete.yml
@@ -0,0 +1,5 @@
+---
+title: Remove all search autocomplete for groups/projects/other
+merge_request: 31187
+author:
+type: removed
diff --git a/changelogs/unreleased/213824-update-red-variables-in-gitlab-scss-to-match-gitlab-ui.yml b/changelogs/unreleased/213824-update-red-variables-in-gitlab-scss-to-match-gitlab-ui.yml
new file mode 100644
index 00000000000..7c446d40128
--- /dev/null
+++ b/changelogs/unreleased/213824-update-red-variables-in-gitlab-scss-to-match-gitlab-ui.yml
@@ -0,0 +1,5 @@
+---
+title: Update red hex values to match GitLab UI
+merge_request: 34544
+author:
+type: other
diff --git a/changelogs/unreleased/213881-alerts-list-pagination.yml b/changelogs/unreleased/213881-alerts-list-pagination.yml
new file mode 100644
index 00000000000..310152722ed
--- /dev/null
+++ b/changelogs/unreleased/213881-alerts-list-pagination.yml
@@ -0,0 +1,5 @@
+---
+title: Alerts list pagination
+merge_request: 33073
+author:
+type: added
diff --git a/changelogs/unreleased/213923-add-range-var.yml b/changelogs/unreleased/213923-add-range-var.yml
new file mode 100644
index 00000000000..71a1bc5e381
--- /dev/null
+++ b/changelogs/unreleased/213923-add-range-var.yml
@@ -0,0 +1,5 @@
+---
+title: Provide `__range` variable for Prometheus queries
+merge_request: 33521
+author:
+type: added
diff --git a/changelogs/unreleased/214102-move-the-members-section-from-settings-to-the-side-nav-for-project.yml b/changelogs/unreleased/214102-move-the-members-section-from-settings-to-the-side-nav-for-project.yml
new file mode 100644
index 00000000000..2cb3569a38e
--- /dev/null
+++ b/changelogs/unreleased/214102-move-the-members-section-from-settings-to-the-side-nav-for-project.yml
@@ -0,0 +1,5 @@
+---
+title: Move the Members section from settings to the side nav for projects
+merge_request: 32667
+author:
+type: changed
diff --git a/changelogs/unreleased/214109-date-time-format-should-be-consistent-in-the-incident.yml b/changelogs/unreleased/214109-date-time-format-should-be-consistent-in-the-incident.yml
new file mode 100644
index 00000000000..762c8dc1992
--- /dev/null
+++ b/changelogs/unreleased/214109-date-time-format-should-be-consistent-in-the-incident.yml
@@ -0,0 +1,5 @@
+---
+title: Add timezone display to alert based issue start time
+merge_request: 32702
+author:
+type: added
diff --git a/changelogs/unreleased/214250-usage-ping-counts-for-all-search.yml b/changelogs/unreleased/214250-usage-ping-counts-for-all-search.yml
new file mode 100644
index 00000000000..b313bfc9dcb
--- /dev/null
+++ b/changelogs/unreleased/214250-usage-ping-counts-for-all-search.yml
@@ -0,0 +1,5 @@
+---
+title: Add Usage Ping count for all searches
+merge_request: 32111
+author:
+type: changed
diff --git a/changelogs/unreleased/214281-modify-dashboard-title.yml b/changelogs/unreleased/214281-modify-dashboard-title.yml
new file mode 100644
index 00000000000..19919dd664b
--- /dev/null
+++ b/changelogs/unreleased/214281-modify-dashboard-title.yml
@@ -0,0 +1,5 @@
+---
+title: Add metrics dashboard name to document title
+merge_request: 30392
+author:
+type: added
diff --git a/changelogs/unreleased/214370-add-timezone-setting.yml b/changelogs/unreleased/214370-add-timezone-setting.yml
new file mode 100644
index 00000000000..03c564da54c
--- /dev/null
+++ b/changelogs/unreleased/214370-add-timezone-setting.yml
@@ -0,0 +1,5 @@
+---
+title: Display dates on metrics dashboards in UTC time zone
+merge_request: 32746
+author:
+type: added
diff --git a/changelogs/unreleased/214370-extend-metrics-settings.yml b/changelogs/unreleased/214370-extend-metrics-settings.yml
new file mode 100644
index 00000000000..56045e3cb5d
--- /dev/null
+++ b/changelogs/unreleased/214370-extend-metrics-settings.yml
@@ -0,0 +1,5 @@
+---
+title: Update operations metrics settings title and description to make them general
+merge_request: 32494
+author:
+type: changed
diff --git a/changelogs/unreleased/214493-invaid-uri.yml b/changelogs/unreleased/214493-invaid-uri.yml
new file mode 100644
index 00000000000..13d6e261804
--- /dev/null
+++ b/changelogs/unreleased/214493-invaid-uri.yml
@@ -0,0 +1,5 @@
+---
+title: Return 404 response when redirecting request with invalid url.
+merge_request: 33492
+author:
+type: fixed
diff --git a/changelogs/unreleased/214556-user-defined-alert-identification.yml b/changelogs/unreleased/214556-user-defined-alert-identification.yml
new file mode 100644
index 00000000000..d65f76e97c0
--- /dev/null
+++ b/changelogs/unreleased/214556-user-defined-alert-identification.yml
@@ -0,0 +1,5 @@
+---
+title: Set fingerprints and increment events count for Alert Management alerts
+merge_request: 32613
+author:
+type: added
diff --git a/changelogs/unreleased/214921-improve-tabbing-behavior-when-creating-new-projects.yml b/changelogs/unreleased/214921-improve-tabbing-behavior-when-creating-new-projects.yml
new file mode 100644
index 00000000000..e7d56cf3189
--- /dev/null
+++ b/changelogs/unreleased/214921-improve-tabbing-behavior-when-creating-new-projects.yml
@@ -0,0 +1,5 @@
+---
+title: Fix tabbing through form fields in projects/new flow
+merge_request: 33209
+author:
+type: fixed
diff --git a/changelogs/unreleased/215497-add-custom-links-to-panel.yml b/changelogs/unreleased/215497-add-custom-links-to-panel.yml
new file mode 100644
index 00000000000..e542a4dfffc
--- /dev/null
+++ b/changelogs/unreleased/215497-add-custom-links-to-panel.yml
@@ -0,0 +1,5 @@
+---
+title: Allow user to add custom links to their metrics dashboard panels
+merge_request: 32646
+author:
+type: added
diff --git a/changelogs/unreleased/215517-tab-docs-ff.yml b/changelogs/unreleased/215517-tab-docs-ff.yml
new file mode 100644
index 00000000000..9ff5f4802ae
--- /dev/null
+++ b/changelogs/unreleased/215517-tab-docs-ff.yml
@@ -0,0 +1,5 @@
+---
+title: Add DAG visualization MVC
+merge_request: 33958
+author:
+type: added
diff --git a/changelogs/unreleased/215618_mutation_to_create_a_commit.yml b/changelogs/unreleased/215618_mutation_to_create_a_commit.yml
new file mode 100644
index 00000000000..9850681d1ef
--- /dev/null
+++ b/changelogs/unreleased/215618_mutation_to_create_a_commit.yml
@@ -0,0 +1,5 @@
+---
+title: Add mutation to create commits in GraphQL
+merge_request: 31102
+author:
+type: added
diff --git a/changelogs/unreleased/215619_add_mutation_to_create_mr.yml b/changelogs/unreleased/215619_add_mutation_to_create_mr.yml
new file mode 100644
index 00000000000..477f8b60d5e
--- /dev/null
+++ b/changelogs/unreleased/215619_add_mutation_to_create_mr.yml
@@ -0,0 +1,5 @@
+---
+title: Add mutation to create a merge request in GraphQL
+merge_request: 31867
+author:
+type: added
diff --git a/changelogs/unreleased/215658-add-users-graphql.yml b/changelogs/unreleased/215658-add-users-graphql.yml
new file mode 100644
index 00000000000..a28ae9f1a12
--- /dev/null
+++ b/changelogs/unreleased/215658-add-users-graphql.yml
@@ -0,0 +1,5 @@
+---
+title: Add user root query to GraphQL API
+merge_request: 33041
+author:
+type: added
diff --git a/changelogs/unreleased/215658-graphql-memberships.yml b/changelogs/unreleased/215658-graphql-memberships.yml
new file mode 100644
index 00000000000..1dd970dbfe6
--- /dev/null
+++ b/changelogs/unreleased/215658-graphql-memberships.yml
@@ -0,0 +1,5 @@
+---
+title: Adds groupMembership and projectMembership to GraphQL API
+merge_request: 33049
+author:
+type: added
diff --git a/changelogs/unreleased/215658-root-users-query.yml b/changelogs/unreleased/215658-root-users-query.yml
new file mode 100644
index 00000000000..24c388ba826
--- /dev/null
+++ b/changelogs/unreleased/215658-root-users-query.yml
@@ -0,0 +1,5 @@
+---
+title: Add root users query to GraphQL API
+merge_request: 33195
+author:
+type: added
diff --git a/changelogs/unreleased/215668-settings-auto-fix.yml b/changelogs/unreleased/215668-settings-auto-fix.yml
new file mode 100644
index 00000000000..b0ac2c15fcf
--- /dev/null
+++ b/changelogs/unreleased/215668-settings-auto-fix.yml
@@ -0,0 +1,5 @@
+---
+title: Add model for project level security auto-fix settings
+merge_request: 32577
+author:
+type: added
diff --git a/changelogs/unreleased/215711-improve-performance-of-search-api-advanced-users-scope.yml b/changelogs/unreleased/215711-improve-performance-of-search-api-advanced-users-scope.yml
new file mode 100644
index 00000000000..e401c881223
--- /dev/null
+++ b/changelogs/unreleased/215711-improve-performance-of-search-api-advanced-users-scope.yml
@@ -0,0 +1,5 @@
+---
+title: Reduce redundant queries for Search API users scope.
+merge_request: 33795
+author:
+type: performance
diff --git a/changelogs/unreleased/215946-add-gitlab-to-do-for-user-when-they-are-assigned-to-an-alert.yml b/changelogs/unreleased/215946-add-gitlab-to-do-for-user-when-they-are-assigned-to-an-alert.yml
new file mode 100644
index 00000000000..5191aca5caf
--- /dev/null
+++ b/changelogs/unreleased/215946-add-gitlab-to-do-for-user-when-they-are-assigned-to-an-alert.yml
@@ -0,0 +1,5 @@
+---
+title: Add todo when alert is assigned to a user
+merge_request: 34104
+author:
+type: added
diff --git a/changelogs/unreleased/216045-capture-todo-resolution.yml b/changelogs/unreleased/216045-capture-todo-resolution.yml
new file mode 100644
index 00000000000..cc43635a120
--- /dev/null
+++ b/changelogs/unreleased/216045-capture-todo-resolution.yml
@@ -0,0 +1,5 @@
+---
+title: Store Todo resolution method
+merge_request: 32753
+author:
+type: added
diff --git a/changelogs/unreleased/216088-disable-container-expiration-policy-when-invalid-regex-is-present.yml b/changelogs/unreleased/216088-disable-container-expiration-policy-when-invalid-regex-is-present.yml
new file mode 100644
index 00000000000..0a8df78d0c7
--- /dev/null
+++ b/changelogs/unreleased/216088-disable-container-expiration-policy-when-invalid-regex-is-present.yml
@@ -0,0 +1,5 @@
+---
+title: Validate regex before sending them to CleanupContainerRepositoryWorker
+merge_request: 34282
+author:
+type: added
diff --git a/changelogs/unreleased/216088-regex-validation-on-container-expiration-policy.yml b/changelogs/unreleased/216088-regex-validation-on-container-expiration-policy.yml
new file mode 100644
index 00000000000..c6df3112d90
--- /dev/null
+++ b/changelogs/unreleased/216088-regex-validation-on-container-expiration-policy.yml
@@ -0,0 +1,5 @@
+---
+title: Container expiration policy regular expressions are now validated
+merge_request: 34063
+author:
+type: added
diff --git a/changelogs/unreleased/216097-add-application-limits-to-ci-instancevariable.yml b/changelogs/unreleased/216097-add-application-limits-to-ci-instancevariable.yml
new file mode 100644
index 00000000000..becb89455fd
--- /dev/null
+++ b/changelogs/unreleased/216097-add-application-limits-to-ci-instancevariable.yml
@@ -0,0 +1,5 @@
+---
+title: Add application limits to instance level CI/CD variables
+merge_request: 32575
+author:
+type: added
diff --git a/changelogs/unreleased/216103-personal-access-token-pat-expiry-is-notifying-a-for-impersonation-.yml b/changelogs/unreleased/216103-personal-access-token-pat-expiry-is-notifying-a-for-impersonation-.yml
new file mode 100644
index 00000000000..16884a14a1e
--- /dev/null
+++ b/changelogs/unreleased/216103-personal-access-token-pat-expiry-is-notifying-a-for-impersonation-.yml
@@ -0,0 +1,5 @@
+---
+title: Prevent emails to user on expiry of impersonation token
+merge_request: 32140
+author:
+type: fixed
diff --git a/changelogs/unreleased/216142-resolve-alert-when-associated-issue-closes.yml b/changelogs/unreleased/216142-resolve-alert-when-associated-issue-closes.yml
new file mode 100644
index 00000000000..834fef6f01b
--- /dev/null
+++ b/changelogs/unreleased/216142-resolve-alert-when-associated-issue-closes.yml
@@ -0,0 +1,5 @@
+---
+title: Automatically resolve alert when associated issue closes
+merge_request: 33278
+author:
+type: added
diff --git a/changelogs/unreleased/216145-jira-users-import-endpoint.yml b/changelogs/unreleased/216145-jira-users-import-endpoint.yml
new file mode 100644
index 00000000000..54c3a130b07
--- /dev/null
+++ b/changelogs/unreleased/216145-jira-users-import-endpoint.yml
@@ -0,0 +1,5 @@
+---
+title: Create graphQL endpoint for Jira users import
+merge_request: 33501
+author:
+type: added
diff --git a/changelogs/unreleased/216145-project-members-graphql.yml b/changelogs/unreleased/216145-project-members-graphql.yml
new file mode 100644
index 00000000000..b64407b8b35
--- /dev/null
+++ b/changelogs/unreleased/216145-project-members-graphql.yml
@@ -0,0 +1,5 @@
+---
+title: Add members to project graphQL endpoint
+merge_request: 33418
+author:
+type: added
diff --git a/changelogs/unreleased/216160-fix-label-any-with-custom-sorting.yml b/changelogs/unreleased/216160-fix-label-any-with-custom-sorting.yml
new file mode 100644
index 00000000000..25b0c302cf2
--- /dev/null
+++ b/changelogs/unreleased/216160-fix-label-any-with-custom-sorting.yml
@@ -0,0 +1,5 @@
+---
+title: Fix issuable listings with any label filter
+merge_request: 31729
+author:
+type: fixed
diff --git a/changelogs/unreleased/216174-track-mr-usage.yml b/changelogs/unreleased/216174-track-mr-usage.yml
new file mode 100644
index 00000000000..90374fa85f7
--- /dev/null
+++ b/changelogs/unreleased/216174-track-mr-usage.yml
@@ -0,0 +1,5 @@
+---
+title: Track merge_requests_users usage data
+merge_request: 32562
+author:
+type: changed
diff --git a/changelogs/unreleased/216326-send-alerts-to-slack-db-settings.yml b/changelogs/unreleased/216326-send-alerts-to-slack-db-settings.yml
new file mode 100644
index 00000000000..ab77ed18444
--- /dev/null
+++ b/changelogs/unreleased/216326-send-alerts-to-slack-db-settings.yml
@@ -0,0 +1,5 @@
+---
+title: Add column for alert slack notifications
+merge_request: 33017
+author:
+type: added
diff --git a/changelogs/unreleased/216385-add-related-dashboard-links-in-metrics-dashboard-mvc1.yml b/changelogs/unreleased/216385-add-related-dashboard-links-in-metrics-dashboard-mvc1.yml
new file mode 100644
index 00000000000..1d211732e04
--- /dev/null
+++ b/changelogs/unreleased/216385-add-related-dashboard-links-in-metrics-dashboard-mvc1.yml
@@ -0,0 +1,5 @@
+---
+title: Render user-defined links in dashboard yml file on metrics dashboard
+merge_request: 32895
+author:
+type: added
diff --git a/changelogs/unreleased/216640-insert-image-modal.yml b/changelogs/unreleased/216640-insert-image-modal.yml
new file mode 100644
index 00000000000..46d43736921
--- /dev/null
+++ b/changelogs/unreleased/216640-insert-image-modal.yml
@@ -0,0 +1,5 @@
+---
+title: Add ability to insert an image via SSE
+merge_request: 33029
+author:
+type: added
diff --git a/changelogs/unreleased/216677-track-static-site-editor-initializations.yml b/changelogs/unreleased/216677-track-static-site-editor-initializations.yml
new file mode 100644
index 00000000000..e8d87d70250
--- /dev/null
+++ b/changelogs/unreleased/216677-track-static-site-editor-initializations.yml
@@ -0,0 +1,5 @@
+---
+title: Track when Static Site Editor is initialized
+merge_request: 34215
+author:
+type: added
diff --git a/changelogs/unreleased/216678-sse-track-merge-requests.yml b/changelogs/unreleased/216678-sse-track-merge-requests.yml
new file mode 100644
index 00000000000..30d3f722b50
--- /dev/null
+++ b/changelogs/unreleased/216678-sse-track-merge-requests.yml
@@ -0,0 +1,5 @@
+---
+title: Track merge requests submitted by Static Site Editor
+merge_request: 34105
+author:
+type: added
diff --git a/changelogs/unreleased/216735-fix-prometheus-alerts-not-being-created.yml b/changelogs/unreleased/216735-fix-prometheus-alerts-not-being-created.yml
new file mode 100644
index 00000000000..cfcd401f6ca
--- /dev/null
+++ b/changelogs/unreleased/216735-fix-prometheus-alerts-not-being-created.yml
@@ -0,0 +1,5 @@
+---
+title: Fix prometheus alerts not being automatically created
+merge_request: 33806
+author:
+type: fixed
diff --git a/changelogs/unreleased/216749-improve-the-container-registry-ui-header-section-with-relevant-met.yml b/changelogs/unreleased/216749-improve-the-container-registry-ui-header-section-with-relevant-met.yml
new file mode 100644
index 00000000000..286453d9575
--- /dev/null
+++ b/changelogs/unreleased/216749-improve-the-container-registry-ui-header-section-with-relevant-met.yml
@@ -0,0 +1,5 @@
+---
+title: Improve Container Registry UI header
+merge_request: 32424
+author:
+type: changed
diff --git a/changelogs/unreleased/216757-add-tags-count.yml b/changelogs/unreleased/216757-add-tags-count.yml
new file mode 100644
index 00000000000..22737f7a914
--- /dev/null
+++ b/changelogs/unreleased/216757-add-tags-count.yml
@@ -0,0 +1,5 @@
+---
+title: Add tags_count to container registry api and controller
+merge_request: 32141
+author:
+type: changed
diff --git a/changelogs/unreleased/216757-include-tag-count-in-the-image-repository-list-view-of-the-contain.yml b/changelogs/unreleased/216757-include-tag-count-in-the-image-repository-list-view-of-the-contain.yml
new file mode 100644
index 00000000000..c9b7a195002
--- /dev/null
+++ b/changelogs/unreleased/216757-include-tag-count-in-the-image-repository-list-view-of-the-contain.yml
@@ -0,0 +1,5 @@
+---
+title: Include tag count in the image repository list
+merge_request: 33027
+author:
+type: changed
diff --git a/changelogs/unreleased/216785-use-ci-job-token-for-terraform-state-auth.yml b/changelogs/unreleased/216785-use-ci-job-token-for-terraform-state-auth.yml
new file mode 100644
index 00000000000..c7fec94b9fb
--- /dev/null
+++ b/changelogs/unreleased/216785-use-ci-job-token-for-terraform-state-auth.yml
@@ -0,0 +1,5 @@
+---
+title: Allow CI_JOB_TOKEN for authenticating to the Terraform state API
+merge_request: 34618
+author:
+type: added
diff --git a/changelogs/unreleased/216797-style-toastui-menus.yml b/changelogs/unreleased/216797-style-toastui-menus.yml
new file mode 100644
index 00000000000..0f87d9cef1e
--- /dev/null
+++ b/changelogs/unreleased/216797-style-toastui-menus.yml
@@ -0,0 +1,5 @@
+---
+title: Style ToastUI contextual menus
+merge_request: 33719
+author:
+type: changed
diff --git a/changelogs/unreleased/216834-frontmatter-wysiwyg-removal.yml b/changelogs/unreleased/216834-frontmatter-wysiwyg-removal.yml
new file mode 100644
index 00000000000..2885d9d5e26
--- /dev/null
+++ b/changelogs/unreleased/216834-frontmatter-wysiwyg-removal.yml
@@ -0,0 +1,5 @@
+---
+title: Update Static Site Editor WYSIWYG mode to hide front matter
+merge_request: 33441
+author:
+type: added
diff --git a/changelogs/unreleased/216835-instrument-db-calls.yml b/changelogs/unreleased/216835-instrument-db-calls.yml
new file mode 100644
index 00000000000..6e1af13b4c7
--- /dev/null
+++ b/changelogs/unreleased/216835-instrument-db-calls.yml
@@ -0,0 +1,6 @@
+---
+title: Add number of database calls to Prometheus metrics and logs for sidekiq and
+ request
+merge_request: 32131
+author:
+type: added
diff --git a/changelogs/unreleased/216865-confirm-leave-site.yml b/changelogs/unreleased/216865-confirm-leave-site.yml
new file mode 100644
index 00000000000..3d6b47db91f
--- /dev/null
+++ b/changelogs/unreleased/216865-confirm-leave-site.yml
@@ -0,0 +1,5 @@
+---
+title: Display confirmation modal when user exits SSE and there are unsaved changes
+merge_request: 33103
+author:
+type: added
diff --git a/changelogs/unreleased/216871-snippets-author-can-t-be-blank-error.yml b/changelogs/unreleased/216871-snippets-author-can-t-be-blank-error.yml
new file mode 100644
index 00000000000..f4a06320e47
--- /dev/null
+++ b/changelogs/unreleased/216871-snippets-author-can-t-be-blank-error.yml
@@ -0,0 +1,5 @@
+---
+title: Fallback to lowest visibility level in snippet visibility radio
+merge_request: 31847
+author: Jacopo Beschi @jacopo-beschi
+type: fixed
diff --git a/changelogs/unreleased/216880-frontend-add-sticky-issue-titles.yml b/changelogs/unreleased/216880-frontend-add-sticky-issue-titles.yml
new file mode 100644
index 00000000000..1194adab7a3
--- /dev/null
+++ b/changelogs/unreleased/216880-frontend-add-sticky-issue-titles.yml
@@ -0,0 +1,5 @@
+---
+title: Add sticky title on Issue pages
+merge_request: 33983
+author:
+type: added
diff --git a/changelogs/unreleased/216908-pass-limit-and-offset-when-searching-for-commits.yml b/changelogs/unreleased/216908-pass-limit-and-offset-when-searching-for-commits.yml
new file mode 100644
index 00000000000..4b2b857cb85
--- /dev/null
+++ b/changelogs/unreleased/216908-pass-limit-and-offset-when-searching-for-commits.yml
@@ -0,0 +1,5 @@
+---
+title: Improve performance of commit search by limiting the number of results requested
+merge_request: 32260
+author:
+type: performance
diff --git a/changelogs/unreleased/216939-remove-async-mr-check-ff.yml b/changelogs/unreleased/216939-remove-async-mr-check-ff.yml
new file mode 100644
index 00000000000..b66cb44de4b
--- /dev/null
+++ b/changelogs/unreleased/216939-remove-async-mr-check-ff.yml
@@ -0,0 +1,5 @@
+---
+title: Remove async_merge_request_check_mergeability feature flag
+merge_request: 33917
+author:
+type: changed
diff --git a/changelogs/unreleased/217034-auto-creation-of-issues-for-alerts-off-by-default.yml b/changelogs/unreleased/217034-auto-creation-of-issues-for-alerts-off-by-default.yml
new file mode 100644
index 00000000000..c109a644871
--- /dev/null
+++ b/changelogs/unreleased/217034-auto-creation-of-issues-for-alerts-off-by-default.yml
@@ -0,0 +1,5 @@
+---
+title: Turn off alert issue creation by default
+merge_request: 34107
+author:
+type: added
diff --git a/changelogs/unreleased/217105-remove-FF-hide_token_from_runners_api.yml b/changelogs/unreleased/217105-remove-FF-hide_token_from_runners_api.yml
new file mode 100644
index 00000000000..45aea72ae24
--- /dev/null
+++ b/changelogs/unreleased/217105-remove-FF-hide_token_from_runners_api.yml
@@ -0,0 +1,5 @@
+---
+title: Remove FF hide_token_from_runners_api
+merge_request: 33947
+author:
+type: other
diff --git a/changelogs/unreleased/217168-close-open-reply-input-fields-in-the-design-view-sidebar-when-leav.yml b/changelogs/unreleased/217168-close-open-reply-input-fields-in-the-design-view-sidebar-when-leav.yml
new file mode 100644
index 00000000000..b3f61c924fa
--- /dev/null
+++ b/changelogs/unreleased/217168-close-open-reply-input-fields-in-the-design-view-sidebar-when-leav.yml
@@ -0,0 +1,6 @@
+---
+title: Close open reply input fields in the design view sidebar when leaving a new
+ comment
+merge_request: 33587
+author:
+type: added
diff --git a/changelogs/unreleased/217366-expose-jira-successfully-imported-issues-count-in-graphql.yml b/changelogs/unreleased/217366-expose-jira-successfully-imported-issues-count-in-graphql.yml
new file mode 100644
index 00000000000..da139df5643
--- /dev/null
+++ b/changelogs/unreleased/217366-expose-jira-successfully-imported-issues-count-in-graphql.yml
@@ -0,0 +1,5 @@
+---
+title: Expose Jira imported issues count in GraphQL
+merge_request: 32580
+author:
+type: added
diff --git a/changelogs/unreleased/217566-add-warning-of-potential-data-loss-on-elastic-stack-upgrade-2.yml b/changelogs/unreleased/217566-add-warning-of-potential-data-loss-on-elastic-stack-upgrade-2.yml
new file mode 100644
index 00000000000..9306f5a9144
--- /dev/null
+++ b/changelogs/unreleased/217566-add-warning-of-potential-data-loss-on-elastic-stack-upgrade-2.yml
@@ -0,0 +1,5 @@
+---
+title: Add warning popup for Elastic Stack update
+merge_request: 31972
+author:
+type: added
diff --git a/changelogs/unreleased/217570-improve-performance-for-blame-api.yml b/changelogs/unreleased/217570-improve-performance-for-blame-api.yml
new file mode 100644
index 00000000000..390e19dc333
--- /dev/null
+++ b/changelogs/unreleased/217570-improve-performance-for-blame-api.yml
@@ -0,0 +1,5 @@
+---
+title: Lazy load commit_date and authored_date on Commit
+merge_request: 34181
+author:
+type: performance
diff --git a/changelogs/unreleased/217616-fix-note-confidential.yml b/changelogs/unreleased/217616-fix-note-confidential.yml
new file mode 100644
index 00000000000..d9e1f8a9b26
--- /dev/null
+++ b/changelogs/unreleased/217616-fix-note-confidential.yml
@@ -0,0 +1,5 @@
+---
+title: Don't display confidential note icon on confidential issue public notes
+merge_request: 32571
+author:
+type: fixed
diff --git a/changelogs/unreleased/217666-prometheus-api-client.yml b/changelogs/unreleased/217666-prometheus-api-client.yml
new file mode 100644
index 00000000000..cb1f4eb193b
--- /dev/null
+++ b/changelogs/unreleased/217666-prometheus-api-client.yml
@@ -0,0 +1,5 @@
+---
+title: Include available instance memory in usage ping
+merge_request: 32315
+author:
+type: other
diff --git a/changelogs/unreleased/217670-alerts-count.yml b/changelogs/unreleased/217670-alerts-count.yml
new file mode 100644
index 00000000000..5a3995be0ce
--- /dev/null
+++ b/changelogs/unreleased/217670-alerts-count.yml
@@ -0,0 +1,5 @@
+---
+title: Organize alerts by status tabs
+merge_request: 32582
+author:
+type: added
diff --git a/changelogs/unreleased/217680-health-metric-instrumentation.yml b/changelogs/unreleased/217680-health-metric-instrumentation.yml
new file mode 100644
index 00000000000..b1f55701c08
--- /dev/null
+++ b/changelogs/unreleased/217680-health-metric-instrumentation.yml
@@ -0,0 +1,5 @@
+---
+title: Track Sentry error status updates with dedicated actions
+merge_request: 33623
+author:
+type: changed
diff --git a/changelogs/unreleased/217680-health-metrics-instrumentation.yml b/changelogs/unreleased/217680-health-metrics-instrumentation.yml
new file mode 100644
index 00000000000..77ae44aaf38
--- /dev/null
+++ b/changelogs/unreleased/217680-health-metrics-instrumentation.yml
@@ -0,0 +1,5 @@
+---
+title: Monitor:Health metrics instrumenation
+merge_request: 32846
+author:
+type: added
diff --git a/changelogs/unreleased/217692-design-view-highlight-focused-design-pins-follow-up.yml b/changelogs/unreleased/217692-design-view-highlight-focused-design-pins-follow-up.yml
new file mode 100644
index 00000000000..27b6d0dd58c
--- /dev/null
+++ b/changelogs/unreleased/217692-design-view-highlight-focused-design-pins-follow-up.yml
@@ -0,0 +1,5 @@
+---
+title: Add opacity transition to active design discussion pins
+merge_request: 33493
+author:
+type: other
diff --git a/changelogs/unreleased/217736-add-related-dashboard-links-in-metrics-dashboard-mvc2.yml b/changelogs/unreleased/217736-add-related-dashboard-links-in-metrics-dashboard-mvc2.yml
new file mode 100644
index 00000000000..8369dbc3def
--- /dev/null
+++ b/changelogs/unreleased/217736-add-related-dashboard-links-in-metrics-dashboard-mvc2.yml
@@ -0,0 +1,5 @@
+---
+title: Add time range to user-defined links in metrics dashboard
+merge_request: 33663
+author:
+type: added
diff --git a/changelogs/unreleased/217743-match-commits-filter-author-button-to-spec.yml b/changelogs/unreleased/217743-match-commits-filter-author-button-to-spec.yml
new file mode 100644
index 00000000000..c90ceb3190b
--- /dev/null
+++ b/changelogs/unreleased/217743-match-commits-filter-author-button-to-spec.yml
@@ -0,0 +1,5 @@
+---
+title: Make commits author button confirm to Pajamas specs
+merge_request: 32821
+author:
+type: fixed
diff --git a/changelogs/unreleased/217748-pipeline-index-endpoint-performance.yml b/changelogs/unreleased/217748-pipeline-index-endpoint-performance.yml
new file mode 100644
index 00000000000..d9a68248010
--- /dev/null
+++ b/changelogs/unreleased/217748-pipeline-index-endpoint-performance.yml
@@ -0,0 +1,5 @@
+---
+title: Add project_id, user_id, status, ref index to ci_pipelines
+merge_request: 33290
+author:
+type: performance
diff --git a/changelogs/unreleased/217816-add-evidence-to-releases-graphql-endpoint.yml b/changelogs/unreleased/217816-add-evidence-to-releases-graphql-endpoint.yml
new file mode 100644
index 00000000000..79ffa011f63
--- /dev/null
+++ b/changelogs/unreleased/217816-add-evidence-to-releases-graphql-endpoint.yml
@@ -0,0 +1,5 @@
+---
+title: Add Evidence to Releases GraphQL endpoint
+merge_request: 33254
+author:
+type: added
diff --git a/changelogs/unreleased/217834-remove-FF-ci_dependency_variables.yml b/changelogs/unreleased/217834-remove-FF-ci_dependency_variables.yml
new file mode 100644
index 00000000000..d237974389a
--- /dev/null
+++ b/changelogs/unreleased/217834-remove-FF-ci_dependency_variables.yml
@@ -0,0 +1,5 @@
+---
+title: Enable CI Inheriting Env Variables feature
+merge_request: 34495
+author:
+type: added
diff --git a/changelogs/unreleased/217934-snippet-description-files.yml b/changelogs/unreleased/217934-snippet-description-files.yml
new file mode 100644
index 00000000000..193188beeb8
--- /dev/null
+++ b/changelogs/unreleased/217934-snippet-description-files.yml
@@ -0,0 +1,5 @@
+---
+title: Send information about attached files to the GraphQL mutation
+merge_request: 34221
+author:
+type: fixed
diff --git a/changelogs/unreleased/217936-validate-the-size-of-the-value-for-instance-level-variables.yml b/changelogs/unreleased/217936-validate-the-size-of-the-value-for-instance-level-variables.yml
new file mode 100644
index 00000000000..b62aa0a8c20
--- /dev/null
+++ b/changelogs/unreleased/217936-validate-the-size-of-the-value-for-instance-level-variables.yml
@@ -0,0 +1,5 @@
+---
+title: Add value length validations for instance level variable
+merge_request: 32303
+author:
+type: fixed
diff --git a/changelogs/unreleased/217985-use-glinfinitescroll-s-default-slot-in-the-project-selector-vue-co.yml b/changelogs/unreleased/217985-use-glinfinitescroll-s-default-slot-in-the-project-selector-vue-co.yml
new file mode 100644
index 00000000000..2d06af04985
--- /dev/null
+++ b/changelogs/unreleased/217985-use-glinfinitescroll-s-default-slot-in-the-project-selector-vue-co.yml
@@ -0,0 +1,5 @@
+---
+title: Make project selector in various dashboard more translatable
+merge_request: 33771
+author:
+type: other
diff --git a/changelogs/unreleased/218007-fix-incomplete-kubernetes-cluster-status-list.yml b/changelogs/unreleased/218007-fix-incomplete-kubernetes-cluster-status-list.yml
new file mode 100644
index 00000000000..bdb87ceee3b
--- /dev/null
+++ b/changelogs/unreleased/218007-fix-incomplete-kubernetes-cluster-status-list.yml
@@ -0,0 +1,5 @@
+---
+title: Resolve Fix Incomplete Kubernetes Cluster Status List
+merge_request: 33344
+author:
+type: fixed
diff --git a/changelogs/unreleased/218025-xff-is-a-400-error.yml b/changelogs/unreleased/218025-xff-is-a-400-error.yml
new file mode 100644
index 00000000000..737fc01315e
--- /dev/null
+++ b/changelogs/unreleased/218025-xff-is-a-400-error.yml
@@ -0,0 +1,5 @@
+---
+title: Convert IP spoofing errors into client errors
+merge_request: 33280
+author:
+type: other
diff --git a/changelogs/unreleased/218036-cannot-delete-account-on-gitlab-com.yml b/changelogs/unreleased/218036-cannot-delete-account-on-gitlab-com.yml
new file mode 100644
index 00000000000..fa95f5e36c5
--- /dev/null
+++ b/changelogs/unreleased/218036-cannot-delete-account-on-gitlab-com.yml
@@ -0,0 +1,5 @@
+---
+title: Add index to issues and epics on last_edited_by_id
+merge_request: 33075
+author:
+type: performance
diff --git a/changelogs/unreleased/218045-feature-flag-remove-feature-flag-for-create-issue-from-alert-detai.yml b/changelogs/unreleased/218045-feature-flag-remove-feature-flag-for-create-issue-from-alert-detai.yml
new file mode 100644
index 00000000000..65b51037ce6
--- /dev/null
+++ b/changelogs/unreleased/218045-feature-flag-remove-feature-flag-for-create-issue-from-alert-detai.yml
@@ -0,0 +1,5 @@
+---
+title: Add button to create an issue from an alert management alert
+merge_request: 33221
+author:
+type: added
diff --git a/changelogs/unreleased/218045-remove-create-issue-feature-flag-FE.yml b/changelogs/unreleased/218045-remove-create-issue-feature-flag-FE.yml
new file mode 100644
index 00000000000..db500c26f45
--- /dev/null
+++ b/changelogs/unreleased/218045-remove-create-issue-feature-flag-FE.yml
@@ -0,0 +1,5 @@
+---
+title: Create issue from alert
+merge_request: 33213
+author:
+type: added
diff --git a/changelogs/unreleased/218165-add-note-no-extend-ecs.yml b/changelogs/unreleased/218165-add-note-no-extend-ecs.yml
new file mode 100644
index 00000000000..7952028f97e
--- /dev/null
+++ b/changelogs/unreleased/218165-add-note-no-extend-ecs.yml
@@ -0,0 +1,5 @@
+---
+title: Add note to ECS CI template
+merge_request: 32597
+author:
+type: added
diff --git a/changelogs/unreleased/218230-bugfix-save-wiki-page-modifications-with-certain-characters.yml b/changelogs/unreleased/218230-bugfix-save-wiki-page-modifications-with-certain-characters.yml
new file mode 100644
index 00000000000..5be7a069ece
--- /dev/null
+++ b/changelogs/unreleased/218230-bugfix-save-wiki-page-modifications-with-certain-characters.yml
@@ -0,0 +1,5 @@
+---
+title: Allow wiki pages with +<> characters in their title to be saved
+merge_request: 33803
+author:
+type: fixed
diff --git a/changelogs/unreleased/218287-release-evidence-is-not-being-collected-if-release-is-created-via-.yml b/changelogs/unreleased/218287-release-evidence-is-not-being-collected-if-release-is-created-via-.yml
new file mode 100644
index 00000000000..101b8c60287
--- /dev/null
+++ b/changelogs/unreleased/218287-release-evidence-is-not-being-collected-if-release-is-created-via-.yml
@@ -0,0 +1,5 @@
+---
+title: Fix creating release evidence if release is created via UI
+merge_request: 32441
+author:
+type: fixed
diff --git a/changelogs/unreleased/218340-graphql-haspreviouspage-and-hasnextpage.yml b/changelogs/unreleased/218340-graphql-haspreviouspage-and-hasnextpage.yml
new file mode 100644
index 00000000000..075caecc1c7
--- /dev/null
+++ b/changelogs/unreleased/218340-graphql-haspreviouspage-and-hasnextpage.yml
@@ -0,0 +1,5 @@
+---
+title: GraphQL hasNextPage and hasPreviousPage return correct values
+merge_request: 32476
+author:
+type: fixed
diff --git a/changelogs/unreleased/218414-refine-sast-analyzer-language-detection.yml b/changelogs/unreleased/218414-refine-sast-analyzer-language-detection.yml
new file mode 100644
index 00000000000..b385ee3a25c
--- /dev/null
+++ b/changelogs/unreleased/218414-refine-sast-analyzer-language-detection.yml
@@ -0,0 +1,5 @@
+---
+title: Refine SAST language detection by frameworks
+merge_request: 33226
+author:
+type: changed
diff --git a/changelogs/unreleased/218464-expiration-policy-defaults.yml b/changelogs/unreleased/218464-expiration-policy-defaults.yml
new file mode 100644
index 00000000000..ac25d58b034
--- /dev/null
+++ b/changelogs/unreleased/218464-expiration-policy-defaults.yml
@@ -0,0 +1,5 @@
+---
+title: Update container expiration policy database defaults
+merge_request: 32600
+author:
+type: fixed
diff --git a/changelogs/unreleased/218510-hide-copy-btn-for-rendering-error.yml b/changelogs/unreleased/218510-hide-copy-btn-for-rendering-error.yml
new file mode 100644
index 00000000000..fa212bf2121
--- /dev/null
+++ b/changelogs/unreleased/218510-hide-copy-btn-for-rendering-error.yml
@@ -0,0 +1,5 @@
+---
+title: Hid copy contents button when blob has rendering error
+merge_request: 32632
+author:
+type: fixed
diff --git a/changelogs/unreleased/218560-allow-generic-endpoint-to-receive-alerts-from-external-prometheus.yml b/changelogs/unreleased/218560-allow-generic-endpoint-to-receive-alerts-from-external-prometheus.yml
new file mode 100644
index 00000000000..0713e96b714
--- /dev/null
+++ b/changelogs/unreleased/218560-allow-generic-endpoint-to-receive-alerts-from-external-prometheus.yml
@@ -0,0 +1,5 @@
+---
+title: Allow generic endpoint to receive alerts from external Prometheus
+merge_request: 32676
+author:
+type: added
diff --git a/changelogs/unreleased/218569-dont-show-import-from-jira-button-for-non-entitled-users.yml b/changelogs/unreleased/218569-dont-show-import-from-jira-button-for-non-entitled-users.yml
new file mode 100644
index 00000000000..da712f0aa59
--- /dev/null
+++ b/changelogs/unreleased/218569-dont-show-import-from-jira-button-for-non-entitled-users.yml
@@ -0,0 +1,5 @@
+---
+title: Hide "Import from Jira" option from non-entitled users
+merge_request: 32685
+author:
+type: fixed
diff --git a/changelogs/unreleased/218582-fix-artifact-downloads-without-new-route.yml b/changelogs/unreleased/218582-fix-artifact-downloads-without-new-route.yml
new file mode 100644
index 00000000000..758b08c3a42
--- /dev/null
+++ b/changelogs/unreleased/218582-fix-artifact-downloads-without-new-route.yml
@@ -0,0 +1,5 @@
+---
+title: Fix 404 when downloading a non-archive artifact
+merge_request: 32811
+author:
+type: fixed
diff --git a/changelogs/unreleased/218648-remove-jira-httperror-non-actionable-exceptions.yml b/changelogs/unreleased/218648-remove-jira-httperror-non-actionable-exceptions.yml
new file mode 100644
index 00000000000..5ac63075c1f
--- /dev/null
+++ b/changelogs/unreleased/218648-remove-jira-httperror-non-actionable-exceptions.yml
@@ -0,0 +1,5 @@
+---
+title: Less verbose JiraService error logs
+merge_request: 32847
+author:
+type: other
diff --git a/changelogs/unreleased/218707-search-criteria-for-alert-status-counts.yml b/changelogs/unreleased/218707-search-criteria-for-alert-status-counts.yml
new file mode 100644
index 00000000000..a556ae4b924
--- /dev/null
+++ b/changelogs/unreleased/218707-search-criteria-for-alert-status-counts.yml
@@ -0,0 +1,5 @@
+---
+title: Add search argument for AlertStatusCountsResolver
+merge_request: 34596
+author:
+type: added
diff --git a/changelogs/unreleased/218716-iterate-on-epic-tree-card-spacing.yml b/changelogs/unreleased/218716-iterate-on-epic-tree-card-spacing.yml
new file mode 100644
index 00000000000..843d27d1cea
--- /dev/null
+++ b/changelogs/unreleased/218716-iterate-on-epic-tree-card-spacing.yml
@@ -0,0 +1,5 @@
+---
+title: Reduced padding and increased emphasis of titles within the epic tree
+merge_request: 32873
+author:
+type: other
diff --git a/changelogs/unreleased/218733-add-manual-rollout-resource-group.yml b/changelogs/unreleased/218733-add-manual-rollout-resource-group.yml
new file mode 100644
index 00000000000..926db344ade
--- /dev/null
+++ b/changelogs/unreleased/218733-add-manual-rollout-resource-group.yml
@@ -0,0 +1,6 @@
+---
+title: Prevent multiple Auto DevOps deployment jobs running concurrently when using
+ manual rollout
+merge_request: 32824
+author:
+type: fixed
diff --git a/changelogs/unreleased/218757-fix-polling-for-events.yml b/changelogs/unreleased/218757-fix-polling-for-events.yml
new file mode 100644
index 00000000000..10accb9ba4d
--- /dev/null
+++ b/changelogs/unreleased/218757-fix-polling-for-events.yml
@@ -0,0 +1,5 @@
+---
+title: Fix polling for resource events
+merge_request: 33025
+author:
+type: fixed
diff --git a/changelogs/unreleased/218823-wiki-base-path-relative-url-root.yml b/changelogs/unreleased/218823-wiki-base-path-relative-url-root.yml
new file mode 100644
index 00000000000..f48f7d11cca
--- /dev/null
+++ b/changelogs/unreleased/218823-wiki-base-path-relative-url-root.yml
@@ -0,0 +1,5 @@
+---
+title: Fix relative URL root in wiki_base_path
+merge_request: 33841
+author:
+type: fixed
diff --git a/changelogs/unreleased/219002-remove-ghost-column.yml b/changelogs/unreleased/219002-remove-ghost-column.yml
new file mode 100644
index 00000000000..0af12a67b20
--- /dev/null
+++ b/changelogs/unreleased/219002-remove-ghost-column.yml
@@ -0,0 +1,5 @@
+---
+title: Remove obsolete users.ghost column
+merge_request: 32957
+author:
+type: other
diff --git a/changelogs/unreleased/219022-fix-pipelines-apps-not-loading.yml b/changelogs/unreleased/219022-fix-pipelines-apps-not-loading.yml
new file mode 100644
index 00000000000..a56c63353ad
--- /dev/null
+++ b/changelogs/unreleased/219022-fix-pipelines-apps-not-loading.yml
@@ -0,0 +1,5 @@
+---
+title: Fix a bug where some Vue apps would be unable to load when DAG tab is disabled
+merge_request: 32966
+author:
+type: fixed
diff --git a/changelogs/unreleased/219074-safe-link-validation.yml b/changelogs/unreleased/219074-safe-link-validation.yml
new file mode 100644
index 00000000000..afce591505a
--- /dev/null
+++ b/changelogs/unreleased/219074-safe-link-validation.yml
@@ -0,0 +1,5 @@
+---
+title: Add validation step on backend for metrics dashboard links
+merge_request: 34204
+author:
+type: added
diff --git a/changelogs/unreleased/219145-comment-button-does-not-show-up-on-mr-when-comments-are-set-to-new.yml b/changelogs/unreleased/219145-comment-button-does-not-show-up-on-mr-when-comments-are-set-to-new.yml
new file mode 100644
index 00000000000..232842c3c5a
--- /dev/null
+++ b/changelogs/unreleased/219145-comment-button-does-not-show-up-on-mr-when-comments-are-set-to-new.yml
@@ -0,0 +1,5 @@
+---
+title: Fix overflow issue in MR and Issue comments
+merge_request: 33100
+author:
+type: fixed
diff --git a/changelogs/unreleased/219151-follow-up-from-fallback-to-lowest-visibility-level-in-snippet-visi.yml b/changelogs/unreleased/219151-follow-up-from-fallback-to-lowest-visibility-level-in-snippet-visi.yml
new file mode 100644
index 00000000000..b9f98664dff
--- /dev/null
+++ b/changelogs/unreleased/219151-follow-up-from-fallback-to-lowest-visibility-level-in-snippet-visi.yml
@@ -0,0 +1,5 @@
+---
+title: Add snippet DB visibility check in spec
+merge_request: 33388
+author: Jacopo Beschi @jacopo-beschi
+type: changed
diff --git a/changelogs/unreleased/219210-column-date-format.yml b/changelogs/unreleased/219210-column-date-format.yml
new file mode 100644
index 00000000000..6b71df17130
--- /dev/null
+++ b/changelogs/unreleased/219210-column-date-format.yml
@@ -0,0 +1,5 @@
+---
+title: Format metrics column chart x axis dates
+merge_request: 33681
+author:
+type: changed
diff --git a/changelogs/unreleased/219210-stacked-column-date-format.yml b/changelogs/unreleased/219210-stacked-column-date-format.yml
new file mode 100644
index 00000000000..86ce1103c97
--- /dev/null
+++ b/changelogs/unreleased/219210-stacked-column-date-format.yml
@@ -0,0 +1,5 @@
+---
+title: Add date time format to the monitor stacked-column chart
+merge_request: 33814
+author:
+type: changed
diff --git a/changelogs/unreleased/219228-add-web-ide-solarized-dark-theme-support.yml b/changelogs/unreleased/219228-add-web-ide-solarized-dark-theme-support.yml
new file mode 100644
index 00000000000..469a372e78e
--- /dev/null
+++ b/changelogs/unreleased/219228-add-web-ide-solarized-dark-theme-support.yml
@@ -0,0 +1,5 @@
+---
+title: Add solarized dark for Web IDE
+merge_request: 33148
+author:
+type: added
diff --git a/changelogs/unreleased/219391-follow-up-from-add-type-field-to-asset-links-on-edit-release-page.yml b/changelogs/unreleased/219391-follow-up-from-add-type-field-to-asset-links-on-edit-release-page.yml
new file mode 100644
index 00000000000..fc732222a6f
--- /dev/null
+++ b/changelogs/unreleased/219391-follow-up-from-add-type-field-to-asset-links-on-edit-release-page.yml
@@ -0,0 +1,5 @@
+---
+title: Resolve spacing ux debt on Release assets form field
+merge_request: 33684
+author:
+type: fixed
diff --git a/changelogs/unreleased/219395-metrics-dashboard-validation-fix-500-for-empty-.yml b/changelogs/unreleased/219395-metrics-dashboard-validation-fix-500-for-empty-.yml
new file mode 100644
index 00000000000..4581e4d0566
--- /dev/null
+++ b/changelogs/unreleased/219395-metrics-dashboard-validation-fix-500-for-empty-.yml
@@ -0,0 +1,6 @@
+---
+title: Fixed dashboard YAML file validaiton for files which do not contain object
+ as root element
+merge_request: 33935
+author:
+type: fixed
diff --git a/changelogs/unreleased/219582-fix-ambiguous_string_concat_on_cleanup_projects_with_missing_names.yml b/changelogs/unreleased/219582-fix-ambiguous_string_concat_on_cleanup_projects_with_missing_names.yml
new file mode 100644
index 00000000000..4a4e268171e
--- /dev/null
+++ b/changelogs/unreleased/219582-fix-ambiguous_string_concat_on_cleanup_projects_with_missing_names.yml
@@ -0,0 +1,5 @@
+---
+title: Fix ambiguous string concatenation on CleanupProjectsWithMissingNamespace
+merge_request: 33497
+author:
+type: fixed
diff --git a/changelogs/unreleased/219658-add-route-to-ghost-lost-and-found-group.yml b/changelogs/unreleased/219658-add-route-to-ghost-lost-and-found-group.yml
new file mode 100644
index 00000000000..d60ab67bee9
--- /dev/null
+++ b/changelogs/unreleased/219658-add-route-to-ghost-lost-and-found-group.yml
@@ -0,0 +1,5 @@
+---
+title: Add route for the lost-and-found group and update the route of orphaned projects
+merge_request: 34285
+author:
+type: fixed
diff --git a/changelogs/unreleased/220014-default-for-SAST_EXCLUDED_PATHS-DS_EXCLUDED_PATHS.yml b/changelogs/unreleased/220014-default-for-SAST_EXCLUDED_PATHS-DS_EXCLUDED_PATHS.yml
new file mode 100644
index 00000000000..9a3557f0673
--- /dev/null
+++ b/changelogs/unreleased/220014-default-for-SAST_EXCLUDED_PATHS-DS_EXCLUDED_PATHS.yml
@@ -0,0 +1,5 @@
+---
+title: Set default values for SAST_EXCLUDED_PATHS and DS_EXCLUDED_PATHS
+merge_request: 34076
+author:
+type: changed
diff --git a/changelogs/unreleased/220051-duplicate-issues-created-when-importing-from-csv.yml b/changelogs/unreleased/220051-duplicate-issues-created-when-importing-from-csv.yml
new file mode 100644
index 00000000000..1c58bf63840
--- /dev/null
+++ b/changelogs/unreleased/220051-duplicate-issues-created-when-importing-from-csv.yml
@@ -0,0 +1,5 @@
+---
+title: Prevent duplicate issues when importing from CSV
+merge_request: 33626
+author:
+type: fixed
diff --git a/changelogs/unreleased/220058.yml b/changelogs/unreleased/220058.yml
new file mode 100644
index 00000000000..4327732eef7
--- /dev/null
+++ b/changelogs/unreleased/220058.yml
@@ -0,0 +1,5 @@
+---
+title: Fix sidebar spacing for alert details
+merge_request: 33630
+author:
+type: fixed
diff --git a/changelogs/unreleased/220144-substitute-variables-in-alerts.yml b/changelogs/unreleased/220144-substitute-variables-in-alerts.yml
new file mode 100644
index 00000000000..b270feee3eb
--- /dev/null
+++ b/changelogs/unreleased/220144-substitute-variables-in-alerts.yml
@@ -0,0 +1,5 @@
+---
+title: Fix bug with variable substitution in alerts
+merge_request: 33772
+author:
+type: fixed
diff --git a/changelogs/unreleased/220148-fix-vsa-issue-summary-title.yml b/changelogs/unreleased/220148-fix-vsa-issue-summary-title.yml
new file mode 100644
index 00000000000..e6c409337ef
--- /dev/null
+++ b/changelogs/unreleased/220148-fix-vsa-issue-summary-title.yml
@@ -0,0 +1,5 @@
+---
+title: Fix Value Stream Analytics summary when using non-english locale
+merge_request: 33717
+author:
+type: fixed
diff --git a/changelogs/unreleased/220185-mask-key-comments-when-exposing-ssh-deploy-keys-via-the-api.yml b/changelogs/unreleased/220185-mask-key-comments-when-exposing-ssh-deploy-keys-via-the-api.yml
new file mode 100644
index 00000000000..7d319fb4f91
--- /dev/null
+++ b/changelogs/unreleased/220185-mask-key-comments-when-exposing-ssh-deploy-keys-via-the-api.yml
@@ -0,0 +1,5 @@
+---
+title: Mask key comments when exposing SSH/Deploy Keys via the API
+merge_request: 34255
+author:
+type: added
diff --git a/changelogs/unreleased/220192-fix-pagination-pd.yml b/changelogs/unreleased/220192-fix-pagination-pd.yml
new file mode 100644
index 00000000000..e0785d09008
--- /dev/null
+++ b/changelogs/unreleased/220192-fix-pagination-pd.yml
@@ -0,0 +1,5 @@
+---
+title: Fix pagination for resource label events
+merge_request: 33821
+author:
+type: fixed
diff --git a/changelogs/unreleased/220195-display-epics-on-swimlanes.yml b/changelogs/unreleased/220195-display-epics-on-swimlanes.yml
new file mode 100644
index 00000000000..46880ee8b8d
--- /dev/null
+++ b/changelogs/unreleased/220195-display-epics-on-swimlanes.yml
@@ -0,0 +1,5 @@
+---
+title: Update board header icons
+merge_request: 34366
+author:
+type: changed
diff --git a/changelogs/unreleased/220209-optimize-container-repository-query.yml b/changelogs/unreleased/220209-optimize-container-repository-query.yml
new file mode 100644
index 00000000000..6376d06cb53
--- /dev/null
+++ b/changelogs/unreleased/220209-optimize-container-repository-query.yml
@@ -0,0 +1,5 @@
+---
+title: Optimize container repository for groups query
+merge_request: 34364
+author:
+type: performance
diff --git a/changelogs/unreleased/220300-do-not-create-duplicate-alert-issues.yml b/changelogs/unreleased/220300-do-not-create-duplicate-alert-issues.yml
new file mode 100644
index 00000000000..e6a8a952561
--- /dev/null
+++ b/changelogs/unreleased/220300-do-not-create-duplicate-alert-issues.yml
@@ -0,0 +1,5 @@
+---
+title: Do not create duplicate issues for exising Alert Management alerts
+merge_request: 33860
+author:
+type: fixed
diff --git a/changelogs/unreleased/220415-feature-flag-enable-alert-slack-notifications.yml b/changelogs/unreleased/220415-feature-flag-enable-alert-slack-notifications.yml
new file mode 100644
index 00000000000..fc1198d8344
--- /dev/null
+++ b/changelogs/unreleased/220415-feature-flag-enable-alert-slack-notifications.yml
@@ -0,0 +1,5 @@
+---
+title: Enable Slack notifications for alerts
+merge_request: 34038
+author:
+type: added
diff --git a/changelogs/unreleased/220477-harden-ci-pipelines-usage-data-queries.yml b/changelogs/unreleased/220477-harden-ci-pipelines-usage-data-queries.yml
new file mode 100644
index 00000000000..39231901fae
--- /dev/null
+++ b/changelogs/unreleased/220477-harden-ci-pipelines-usage-data-queries.yml
@@ -0,0 +1,5 @@
+---
+title: Harden CI pipelines usage data queries with an index
+merge_request: 34045
+author:
+type: performance
diff --git a/changelogs/unreleased/220616-group-code-icons-in-toolbar.yml b/changelogs/unreleased/220616-group-code-icons-in-toolbar.yml
new file mode 100644
index 00000000000..15e671bad56
--- /dev/null
+++ b/changelogs/unreleased/220616-group-code-icons-in-toolbar.yml
@@ -0,0 +1,5 @@
+---
+title: Update Static Site Editor toolbar to group inline-code and code-block buttons together
+merge_request: 34006
+author:
+type: changed
diff --git a/changelogs/unreleased/220954-replace-fa-file-image-o-with-gitlab-media-icon.yml b/changelogs/unreleased/220954-replace-fa-file-image-o-with-gitlab-media-icon.yml
new file mode 100644
index 00000000000..9f01694f06a
--- /dev/null
+++ b/changelogs/unreleased/220954-replace-fa-file-image-o-with-gitlab-media-icon.yml
@@ -0,0 +1,5 @@
+---
+title: Use GitLab SVG icon for file attacher action
+merge_request: 34196
+author:
+type: other
diff --git a/changelogs/unreleased/221052-fix-custom-slashcommand-receiving-500.yml b/changelogs/unreleased/221052-fix-custom-slashcommand-receiving-500.yml
new file mode 100644
index 00000000000..58d594fe4f8
--- /dev/null
+++ b/changelogs/unreleased/221052-fix-custom-slashcommand-receiving-500.yml
@@ -0,0 +1,5 @@
+---
+title: Fix undefined method error
+merge_request: 34522
+author:
+type: fixed
diff --git a/changelogs/unreleased/221136-docs-product-feedback-slack-notifications-service-doc-outdated.yml b/changelogs/unreleased/221136-docs-product-feedback-slack-notifications-service-doc-outdated.yml
new file mode 100644
index 00000000000..7fca5a43e6c
--- /dev/null
+++ b/changelogs/unreleased/221136-docs-product-feedback-slack-notifications-service-doc-outdated.yml
@@ -0,0 +1,5 @@
+---
+title: Fix order of integrations to be sorted alphabetically
+merge_request: 34501
+author:
+type: fixed
diff --git a/changelogs/unreleased/221174-graphql-pagination-bug.yml b/changelogs/unreleased/221174-graphql-pagination-bug.yml
new file mode 100644
index 00000000000..70765ae708b
--- /dev/null
+++ b/changelogs/unreleased/221174-graphql-pagination-bug.yml
@@ -0,0 +1,5 @@
+---
+title: GraphQL - properly handle pagination of millisecond-precision timestamps
+merge_request: 34352
+author:
+type: fixed
diff --git a/changelogs/unreleased/22691-externalize-i18n-strings-from---app-views-shared-milestones-_form_d.yml b/changelogs/unreleased/22691-externalize-i18n-strings-from---app-views-shared-milestones-_form_d.yml
new file mode 100644
index 00000000000..f6f54617e1a
--- /dev/null
+++ b/changelogs/unreleased/22691-externalize-i18n-strings-from---app-views-shared-milestones-_form_d.yml
@@ -0,0 +1,5 @@
+---
+title: Externalize i18n strings from ./app/views/shared/milestones/_form_dates.html.haml
+merge_request: 32162
+author: Gilang Gumilar
+type: changed
diff --git a/changelogs/unreleased/22691-externalize-i18n-strings-from---app-views-shared-milestones-_sideba.yml b/changelogs/unreleased/22691-externalize-i18n-strings-from---app-views-shared-milestones-_sideba.yml
new file mode 100644
index 00000000000..54168b42538
--- /dev/null
+++ b/changelogs/unreleased/22691-externalize-i18n-strings-from---app-views-shared-milestones-_sideba.yml
@@ -0,0 +1,5 @@
+---
+title: Externalize i18n strings from ./app/views/shared/milestones/_sidebar.html.haml
+merge_request: 32150
+author: Gilang Gumilar
+type: changed
diff --git a/changelogs/unreleased/22691-externelize-i18n-strings-from---app-views-shared-_promo-html-haml.yml b/changelogs/unreleased/22691-externelize-i18n-strings-from---app-views-shared-_promo-html-haml.yml
new file mode 100644
index 00000000000..fb2b87754da
--- /dev/null
+++ b/changelogs/unreleased/22691-externelize-i18n-strings-from---app-views-shared-_promo-html-haml.yml
@@ -0,0 +1,5 @@
+---
+title: Externalize i18n strings from ./app/views/shared/_promo.html.haml
+merge_request: 32109
+author: Gilang Gumilar
+type: changed
diff --git a/changelogs/unreleased/22822-ide-paste-images.yml b/changelogs/unreleased/22822-ide-paste-images.yml
new file mode 100644
index 00000000000..26a3adf70a6
--- /dev/null
+++ b/changelogs/unreleased/22822-ide-paste-images.yml
@@ -0,0 +1,5 @@
+---
+title: Add support for pasting images in the Web IDE
+merge_request: 33256
+author:
+type: added
diff --git a/changelogs/unreleased/22834-ff-merge-msg.yml b/changelogs/unreleased/22834-ff-merge-msg.yml
new file mode 100644
index 00000000000..6e2e09bd654
--- /dev/null
+++ b/changelogs/unreleased/22834-ff-merge-msg.yml
@@ -0,0 +1,5 @@
+---
+title: Improve fast-forward merge is not possible message
+merge_request: 22834
+author: Ben Bodenmiller
+type: other
diff --git a/changelogs/unreleased/22868-fix-remove-button-alignment.yml b/changelogs/unreleased/22868-fix-remove-button-alignment.yml
new file mode 100644
index 00000000000..63c755d2479
--- /dev/null
+++ b/changelogs/unreleased/22868-fix-remove-button-alignment.yml
@@ -0,0 +1,5 @@
+---
+title: Fix "Broadcast Messages" table overflow and button alignment
+merge_request: 32801
+author:
+type: fixed
diff --git a/changelogs/unreleased/23352-editorconfig.yml b/changelogs/unreleased/23352-editorconfig.yml
new file mode 100644
index 00000000000..a80fb3556c8
--- /dev/null
+++ b/changelogs/unreleased/23352-editorconfig.yml
@@ -0,0 +1,5 @@
+---
+title: Support reading .editorconfig files inside of the Web IDE
+merge_request: 32378
+author:
+type: added
diff --git a/changelogs/unreleased/25486-batch-suggestions.yml b/changelogs/unreleased/25486-batch-suggestions.yml
new file mode 100644
index 00000000000..157e50c2a15
--- /dev/null
+++ b/changelogs/unreleased/25486-batch-suggestions.yml
@@ -0,0 +1,5 @@
+---
+title: User can apply multiple suggestions at the same time.
+merge_request: 22439
+author: Jesse Hall
+type: added
diff --git a/changelogs/unreleased/25830-find-file-button.yml b/changelogs/unreleased/25830-find-file-button.yml
new file mode 100644
index 00000000000..cd0b2104ac2
--- /dev/null
+++ b/changelogs/unreleased/25830-find-file-button.yml
@@ -0,0 +1,5 @@
+---
+title: Remove search icon from Project find file button
+merge_request: 33198
+author:
+type: changed
diff --git a/changelogs/unreleased/28154-move-controllers-outside-ee.yml b/changelogs/unreleased/28154-move-controllers-outside-ee.yml
new file mode 100644
index 00000000000..3fa60392c65
--- /dev/null
+++ b/changelogs/unreleased/28154-move-controllers-outside-ee.yml
@@ -0,0 +1,5 @@
+---
+title: Move review related controllers/workers outside EE
+merge_request: 32663
+author:
+type: changed
diff --git a/changelogs/unreleased/28589-emoji-status-popover-doesn-t-show-emoji-when-it-s-in-the-message.yml b/changelogs/unreleased/28589-emoji-status-popover-doesn-t-show-emoji-when-it-s-in-the-message.yml
new file mode 100644
index 00000000000..85f6aa53840
--- /dev/null
+++ b/changelogs/unreleased/28589-emoji-status-popover-doesn-t-show-emoji-when-it-s-in-the-message.yml
@@ -0,0 +1,5 @@
+---
+title: Fix rendering of emojis in status tooltips
+merge_request: 32604
+author:
+type: fixed
diff --git a/changelogs/unreleased/30707-show-outdated-status-of-suggestions.yml b/changelogs/unreleased/30707-show-outdated-status-of-suggestions.yml
new file mode 100644
index 00000000000..bec0d8d3c95
--- /dev/null
+++ b/changelogs/unreleased/30707-show-outdated-status-of-suggestions.yml
@@ -0,0 +1,5 @@
+---
+title: Show disabled suggestion button with tooltip message
+merge_request: 33357
+author:
+type: changed
diff --git a/changelogs/unreleased/30853-footer-system-message-covers-horizontal-scrollbar.yml b/changelogs/unreleased/30853-footer-system-message-covers-horizontal-scrollbar.yml
new file mode 100644
index 00000000000..565fed3508e
--- /dev/null
+++ b/changelogs/unreleased/30853-footer-system-message-covers-horizontal-scrollbar.yml
@@ -0,0 +1,5 @@
+---
+title: Footer system message fix
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/32230-reorder-diffs-compare-versions-dropdowns.yml b/changelogs/unreleased/32230-reorder-diffs-compare-versions-dropdowns.yml
new file mode 100644
index 00000000000..34bc383ec38
--- /dev/null
+++ b/changelogs/unreleased/32230-reorder-diffs-compare-versions-dropdowns.yml
@@ -0,0 +1,5 @@
+---
+title: Reorder diffs compare versions dropdowns.
+merge_request: 31770
+author: Gilang Gumilar
+type: changed
diff --git a/changelogs/unreleased/33040-doc-cicd-yaml-clarify-rules-if-when-behaviour.yml b/changelogs/unreleased/33040-doc-cicd-yaml-clarify-rules-if-when-behaviour.yml
new file mode 100644
index 00000000000..6ed24768729
--- /dev/null
+++ b/changelogs/unreleased/33040-doc-cicd-yaml-clarify-rules-if-when-behaviour.yml
@@ -0,0 +1,5 @@
+---
+doc: "cicd: yaml: clarify rules:if when behaviour"
+merge_request: 33040
+author: Melvin Vermeeren
+type: changed
diff --git a/changelogs/unreleased/33185-add-missing-install-instruction.yml b/changelogs/unreleased/33185-add-missing-install-instruction.yml
new file mode 100644
index 00000000000..db82588bd04
--- /dev/null
+++ b/changelogs/unreleased/33185-add-missing-install-instruction.yml
@@ -0,0 +1,5 @@
+---
+doc: "doc: install: add missing exiftool dependency"
+merge_request: 33185
+author: Stefan Schrijvers
+type: fixed
diff --git a/changelogs/unreleased/33743-graph-code-coverage-changes-over-time-for-a-project.yml b/changelogs/unreleased/33743-graph-code-coverage-changes-over-time-for-a-project.yml
new file mode 100644
index 00000000000..d2ee2c50d00
--- /dev/null
+++ b/changelogs/unreleased/33743-graph-code-coverage-changes-over-time-for-a-project.yml
@@ -0,0 +1,5 @@
+---
+title: Resolve Graph code coverage changes over time for a project
+merge_request: 26174
+author:
+type: added
diff --git a/changelogs/unreleased/37412-update-error-tracking-list-message.yml b/changelogs/unreleased/37412-update-error-tracking-list-message.yml
new file mode 100644
index 00000000000..5c6ece8dd51
--- /dev/null
+++ b/changelogs/unreleased/37412-update-error-tracking-list-message.yml
@@ -0,0 +1,5 @@
+---
+title: Update text in error tracking list error message
+merge_request: 33872
+author:
+type: fixed
diff --git a/changelogs/unreleased/39545-cleanup-dynamic-milestone-pages.yml b/changelogs/unreleased/39545-cleanup-dynamic-milestone-pages.yml
new file mode 100644
index 00000000000..e2ab210a333
--- /dev/null
+++ b/changelogs/unreleased/39545-cleanup-dynamic-milestone-pages.yml
@@ -0,0 +1,5 @@
+---
+title: Remove deprecated dashboard & group milestone pages
+merge_request: 13237
+author:
+type: removed
diff --git a/changelogs/unreleased/500-metrics-creation.yml b/changelogs/unreleased/500-metrics-creation.yml
new file mode 100644
index 00000000000..83a93e2ff04
--- /dev/null
+++ b/changelogs/unreleased/500-metrics-creation.yml
@@ -0,0 +1,5 @@
+---
+title: Fix for metrics creation when saving MR
+merge_request: 32668
+author:
+type: fixed
diff --git a/changelogs/unreleased/Fix-spelling-error.yml b/changelogs/unreleased/Fix-spelling-error.yml
new file mode 100644
index 00000000000..c851da131fe
--- /dev/null
+++ b/changelogs/unreleased/Fix-spelling-error.yml
@@ -0,0 +1,5 @@
+---
+title: Fix spelling error on Ci::RunnersFinder
+merge_request: 32985
+author: Arthur de Lapertosa Lisboa
+type: fixed
diff --git a/changelogs/unreleased/Remove-addAssignee-logic-from-issues-model.yml b/changelogs/unreleased/Remove-addAssignee-logic-from-issues-model.yml
new file mode 100644
index 00000000000..27c9dbaf3b6
--- /dev/null
+++ b/changelogs/unreleased/Remove-addAssignee-logic-from-issues-model.yml
@@ -0,0 +1,5 @@
+---
+title: Remove addAssignee logic from issue model
+merge_request: 32231
+author: nuwe1
+type: other
diff --git a/changelogs/unreleased/Remove-addLabel-function-logic-from-issue-models.yml b/changelogs/unreleased/Remove-addLabel-function-logic-from-issue-models.yml
new file mode 100644
index 00000000000..df0e490e1ca
--- /dev/null
+++ b/changelogs/unreleased/Remove-addLabel-function-logic-from-issue-models.yml
@@ -0,0 +1,5 @@
+---
+title: Remove addLabel Logic from issue models
+merge_request: 32233
+author: nuwe1
+type: other
diff --git a/changelogs/unreleased/Remove-addMilestone-logic-from-issue-models.yml b/changelogs/unreleased/Remove-addMilestone-logic-from-issue-models.yml
new file mode 100644
index 00000000000..7c537b04d84
--- /dev/null
+++ b/changelogs/unreleased/Remove-addMilestone-logic-from-issue-models.yml
@@ -0,0 +1,5 @@
+---
+title: Remove addMilestone logic from issue model
+merge_request: 32235
+author: nuwe1
+type: other
diff --git a/changelogs/unreleased/Remove-clickable-styling-from-loading-row.yml b/changelogs/unreleased/Remove-clickable-styling-from-loading-row.yml
new file mode 100644
index 00000000000..a32c3d5f847
--- /dev/null
+++ b/changelogs/unreleased/Remove-clickable-styling-from-loading-row.yml
@@ -0,0 +1,5 @@
+---
+title: Fix loading and empty state styling for alerts list
+merge_request: 32531
+author:
+type: fixed
diff --git a/changelogs/unreleased/Remove-destroy-function-logic-from-list-model.yml b/changelogs/unreleased/Remove-destroy-function-logic-from-list-model.yml
new file mode 100644
index 00000000000..2832db23bed
--- /dev/null
+++ b/changelogs/unreleased/Remove-destroy-function-logic-from-list-model.yml
@@ -0,0 +1,5 @@
+---
+title: Remove destroy function logic from list model
+merge_request: 32237
+author: nuwe1
+type: other
diff --git a/changelogs/unreleased/Remove-findAssignee-logic-from-issues-model.yml b/changelogs/unreleased/Remove-findAssignee-logic-from-issues-model.yml
new file mode 100644
index 00000000000..7e4bfe78cf6
--- /dev/null
+++ b/changelogs/unreleased/Remove-findAssignee-logic-from-issues-model.yml
@@ -0,0 +1,5 @@
+---
+title: Remove findAssignee logic from issue model
+merge_request: 32238
+author: nuwe1
+type: other
diff --git a/changelogs/unreleased/Remove-findLabel-logic-from-issues-model.yml b/changelogs/unreleased/Remove-findLabel-logic-from-issues-model.yml
new file mode 100644
index 00000000000..97fa19ca080
--- /dev/null
+++ b/changelogs/unreleased/Remove-findLabel-logic-from-issues-model.yml
@@ -0,0 +1,5 @@
+---
+title: Remove findLabel logic from issue model
+merge_request: 32239
+author: nuwe1
+type: other
diff --git a/changelogs/unreleased/Remove-findissue-logic-from-list-model.yml b/changelogs/unreleased/Remove-findissue-logic-from-list-model.yml
new file mode 100644
index 00000000000..74d57ff4f14
--- /dev/null
+++ b/changelogs/unreleased/Remove-findissue-logic-from-list-model.yml
@@ -0,0 +1,5 @@
+---
+title: Remove findIssue logic from list model
+merge_request: 32241
+author: nuwe1
+type: other
diff --git a/changelogs/unreleased/Remove-moveIssue-logic-from-list-model.yml b/changelogs/unreleased/Remove-moveIssue-logic-from-list-model.yml
new file mode 100644
index 00000000000..9323405a02c
--- /dev/null
+++ b/changelogs/unreleased/Remove-moveIssue-logic-from-list-model.yml
@@ -0,0 +1,5 @@
+---
+title: Remove moveIssue logic from list model
+merge_request: 32242
+author: nuwe1
+type: other
diff --git a/changelogs/unreleased/Remove-newIssue-logic-from-list-model.yml b/changelogs/unreleased/Remove-newIssue-logic-from-list-model.yml
new file mode 100644
index 00000000000..978533e9285
--- /dev/null
+++ b/changelogs/unreleased/Remove-newIssue-logic-from-list-model.yml
@@ -0,0 +1,5 @@
+---
+title: Remove newIssue logic from list model
+merge_request: 32244
+author: nuwe1
+type: other
diff --git a/changelogs/unreleased/Remove-nextPage-function-logic-from-listmodel.yml b/changelogs/unreleased/Remove-nextPage-function-logic-from-listmodel.yml
new file mode 100644
index 00000000000..d548c912513
--- /dev/null
+++ b/changelogs/unreleased/Remove-nextPage-function-logic-from-listmodel.yml
@@ -0,0 +1,5 @@
+---
+title: Remove nextpage function logic from list model
+merge_request: 31904
+author: nuwe1
+type: other
diff --git a/changelogs/unreleased/Remove-removeAllAssignees-logic-from-issue-model.yml b/changelogs/unreleased/Remove-removeAllAssignees-logic-from-issue-model.yml
new file mode 100644
index 00000000000..df0488a3882
--- /dev/null
+++ b/changelogs/unreleased/Remove-removeAllAssignees-logic-from-issue-model.yml
@@ -0,0 +1,5 @@
+---
+title: Remove removeAllAssignees logic from issue model
+merge_request: 32247
+author: nuwe1
+type: other
diff --git a/changelogs/unreleased/Remove-removeAssignee-logic-from-issue-model.yml b/changelogs/unreleased/Remove-removeAssignee-logic-from-issue-model.yml
new file mode 100644
index 00000000000..257f95de712
--- /dev/null
+++ b/changelogs/unreleased/Remove-removeAssignee-logic-from-issue-model.yml
@@ -0,0 +1,5 @@
+---
+title: Remove removeAssignee logic from issue model
+merge_request: 32248
+author: nuwe1
+type: other
diff --git a/changelogs/unreleased/Remove-removeIssue-function-logic-from-list-model.yml b/changelogs/unreleased/Remove-removeIssue-function-logic-from-list-model.yml
new file mode 100644
index 00000000000..8d929b1a448
--- /dev/null
+++ b/changelogs/unreleased/Remove-removeIssue-function-logic-from-list-model.yml
@@ -0,0 +1,5 @@
+---
+title: Remove removeIssue logic from list model
+merge_request:
+author: nuwe1
+type: other
diff --git a/changelogs/unreleased/Remove-removeLabel-logic-from-issues-model.yml b/changelogs/unreleased/Remove-removeLabel-logic-from-issues-model.yml
new file mode 100644
index 00000000000..a04939f68f4
--- /dev/null
+++ b/changelogs/unreleased/Remove-removeLabel-logic-from-issues-model.yml
@@ -0,0 +1,5 @@
+---
+title: Remove removeLabel logic from issue model
+merge_request: 32251
+author: nuwe1
+type: other
diff --git a/changelogs/unreleased/Remove-removeLabels-logic-from-issues-model.yml b/changelogs/unreleased/Remove-removeLabels-logic-from-issues-model.yml
new file mode 100644
index 00000000000..18398999113
--- /dev/null
+++ b/changelogs/unreleased/Remove-removeLabels-logic-from-issues-model.yml
@@ -0,0 +1,5 @@
+---
+title: Remove removeLabels logic from issue model
+merge_request: 32252
+author: nuwe1
+type: other
diff --git a/changelogs/unreleased/Remove-removeMilestone-logic-from-issue-model.yml b/changelogs/unreleased/Remove-removeMilestone-logic-from-issue-model.yml
new file mode 100644
index 00000000000..ff000f33c53
--- /dev/null
+++ b/changelogs/unreleased/Remove-removeMilestone-logic-from-issue-model.yml
@@ -0,0 +1,5 @@
+---
+title: Remove removeMilestone logic from issue model
+merge_request: 32253
+author: nuwe1
+type: other
diff --git a/changelogs/unreleased/Remove-removeMultipleIssues-logic-from-list-model.yml b/changelogs/unreleased/Remove-removeMultipleIssues-logic-from-list-model.yml
new file mode 100644
index 00000000000..ba525900849
--- /dev/null
+++ b/changelogs/unreleased/Remove-removeMultipleIssues-logic-from-list-model.yml
@@ -0,0 +1,5 @@
+---
+title: Remove removeMultipleIssues logic from list model
+merge_request: 32254
+author: nuwe1
+type: other
diff --git a/changelogs/unreleased/Remove-setFetchingState-logic-from-issue-model.yml b/changelogs/unreleased/Remove-setFetchingState-logic-from-issue-model.yml
new file mode 100644
index 00000000000..5295fed6e98
--- /dev/null
+++ b/changelogs/unreleased/Remove-setFetchingState-logic-from-issue-model.yml
@@ -0,0 +1,5 @@
+---
+title: Remove setFetchingState logic from issue model
+merge_request: 32255
+author: nuwe1
+type: other
diff --git a/changelogs/unreleased/Remove-setLoadingState-logic-From-issue-model.yml b/changelogs/unreleased/Remove-setLoadingState-logic-From-issue-model.yml
new file mode 100644
index 00000000000..38c2b29d18f
--- /dev/null
+++ b/changelogs/unreleased/Remove-setLoadingState-logic-From-issue-model.yml
@@ -0,0 +1,5 @@
+---
+title: Remove setLoadingState logic from issue model
+merge_request: 32226
+author: nuwe1
+type: other
diff --git a/changelogs/unreleased/Remove-update-fuction-logic-from-list-model.yml b/changelogs/unreleased/Remove-update-fuction-logic-from-list-model.yml
new file mode 100644
index 00000000000..6b13103b332
--- /dev/null
+++ b/changelogs/unreleased/Remove-update-fuction-logic-from-list-model.yml
@@ -0,0 +1,5 @@
+---
+title: Remove update function logic from list model
+merge_request: 31900
+author: nuwe1
+type: other
diff --git a/changelogs/unreleased/Remove-updateData-logic-from-issue-model.yml b/changelogs/unreleased/Remove-updateData-logic-from-issue-model.yml
new file mode 100644
index 00000000000..27af15c3cc5
--- /dev/null
+++ b/changelogs/unreleased/Remove-updateData-logic-from-issue-model.yml
@@ -0,0 +1,5 @@
+---
+title: Remove updateData logic from issue model
+merge_request: 32256
+author: nuwe1
+type: other
diff --git a/changelogs/unreleased/aalakkad-fix-time-tracking-help-link.yml b/changelogs/unreleased/aalakkad-fix-time-tracking-help-link.yml
new file mode 100644
index 00000000000..48a48e34c69
--- /dev/null
+++ b/changelogs/unreleased/aalakkad-fix-time-tracking-help-link.yml
@@ -0,0 +1,5 @@
+---
+title: Fix time_tracking help link
+merge_request: 32552
+author:
+type: fixed
diff --git a/changelogs/unreleased/ab-alert-usage-ping.yml b/changelogs/unreleased/ab-alert-usage-ping.yml
new file mode 100644
index 00000000000..408e511cd36
--- /dev/null
+++ b/changelogs/unreleased/ab-alert-usage-ping.yml
@@ -0,0 +1,5 @@
+---
+title: Add count of alerts from all sources to usage ping
+merge_request: 33220
+author:
+type: added
diff --git a/changelogs/unreleased/ab-cleanup-migrations.yml b/changelogs/unreleased/ab-cleanup-migrations.yml
new file mode 100644
index 00000000000..803040ab69b
--- /dev/null
+++ b/changelogs/unreleased/ab-cleanup-migrations.yml
@@ -0,0 +1,5 @@
+---
+title: Squash database migrations prior to 2019 into one
+merge_request: 31936
+author:
+type: other
diff --git a/changelogs/unreleased/ab-monitor-demo-environments-2.yml b/changelogs/unreleased/ab-monitor-demo-environments-2.yml
new file mode 100644
index 00000000000..19bb53079d8
--- /dev/null
+++ b/changelogs/unreleased/ab-monitor-demo-environments-2.yml
@@ -0,0 +1,5 @@
+---
+title: Add Scheduled Job for Monitoring Monitor Group Demo Environments
+merge_request: 27360
+author:
+type: added
diff --git a/changelogs/unreleased/ab-services-partial-indexes.yml b/changelogs/unreleased/ab-services-partial-indexes.yml
new file mode 100644
index 00000000000..15dad096f7b
--- /dev/null
+++ b/changelogs/unreleased/ab-services-partial-indexes.yml
@@ -0,0 +1,5 @@
+---
+title: Adjust condition for partial indexes on services table
+merge_request: 33044
+author:
+type: performance
diff --git a/changelogs/unreleased/add-api-endpoint-for-resource-milestone-events-pd.yml b/changelogs/unreleased/add-api-endpoint-for-resource-milestone-events-pd.yml
new file mode 100644
index 00000000000..8f5ef68ba5b
--- /dev/null
+++ b/changelogs/unreleased/add-api-endpoint-for-resource-milestone-events-pd.yml
@@ -0,0 +1,5 @@
+---
+title: Add API endpoint for resource milestone events
+merge_request: 31720
+author:
+type: added
diff --git a/changelogs/unreleased/add-doc-custom-validators.yml b/changelogs/unreleased/add-doc-custom-validators.yml
new file mode 100644
index 00000000000..86e32801bdc
--- /dev/null
+++ b/changelogs/unreleased/add-doc-custom-validators.yml
@@ -0,0 +1,5 @@
+---
+title: Add doc for custom validators in api styleguide
+merge_request: 26734
+author: Rajendra Kadam
+type: added
diff --git a/changelogs/unreleased/add-experience-level-to-user-preferences.yml b/changelogs/unreleased/add-experience-level-to-user-preferences.yml
new file mode 100644
index 00000000000..2029ebc90d5
--- /dev/null
+++ b/changelogs/unreleased/add-experience-level-to-user-preferences.yml
@@ -0,0 +1,5 @@
+---
+title: Add experience_level to user_preferences
+merge_request: 32784
+author:
+type: added
diff --git a/changelogs/unreleased/add-global-plans.yml b/changelogs/unreleased/add-global-plans.yml
new file mode 100644
index 00000000000..cafd6cfc227
--- /dev/null
+++ b/changelogs/unreleased/add-global-plans.yml
@@ -0,0 +1,5 @@
+---
+title: Adapt Limitable for system-wide features
+merge_request: 32574
+author:
+type: added
diff --git a/changelogs/unreleased/add-group-runners-finder.yml b/changelogs/unreleased/add-group-runners-finder.yml
new file mode 100644
index 00000000000..a90eb2c2e42
--- /dev/null
+++ b/changelogs/unreleased/add-group-runners-finder.yml
@@ -0,0 +1,5 @@
+---
+title: Add finder for group-level runners
+merge_request: 29283
+author: Arthur de Lapertosa Lisboa
+type: added
diff --git a/changelogs/unreleased/add-tags-to-queue-attributes.yml b/changelogs/unreleased/add-tags-to-queue-attributes.yml
new file mode 100644
index 00000000000..fd609109a67
--- /dev/null
+++ b/changelogs/unreleased/add-tags-to-queue-attributes.yml
@@ -0,0 +1,5 @@
+---
+title: Add tags to experimental queue selector attributes
+merge_request: 32651
+author:
+type: added
diff --git a/changelogs/unreleased/add_build_reference.yml b/changelogs/unreleased/add_build_reference.yml
new file mode 100644
index 00000000000..70db43c810d
--- /dev/null
+++ b/changelogs/unreleased/add_build_reference.yml
@@ -0,0 +1,5 @@
+---
+title: Added build_id column to requirements_management_test_reports table
+merge_request: 33184
+author:
+type: other
diff --git a/changelogs/unreleased/ajk-GQL-user-mrs.yml b/changelogs/unreleased/ajk-GQL-user-mrs.yml
new file mode 100644
index 00000000000..103ae1d33dd
--- /dev/null
+++ b/changelogs/unreleased/ajk-GQL-user-mrs.yml
@@ -0,0 +1,5 @@
+---
+title: Add GraphQL support for authored and assigned Merge Requests
+merge_request: 31227
+author:
+type: added
diff --git a/changelogs/unreleased/ajk-design-ref-filter.yml b/changelogs/unreleased/ajk-design-ref-filter.yml
new file mode 100644
index 00000000000..0f77e344d65
--- /dev/null
+++ b/changelogs/unreleased/ajk-design-ref-filter.yml
@@ -0,0 +1,5 @@
+---
+title: Enable GitLab-Flavored Markdown processing for design links
+merge_request: 32446
+author:
+type: added
diff --git a/changelogs/unreleased/ajk-gql-add-mr-author.yml b/changelogs/unreleased/ajk-gql-add-mr-author.yml
new file mode 100644
index 00000000000..f4d8048f54b
--- /dev/null
+++ b/changelogs/unreleased/ajk-gql-add-mr-author.yml
@@ -0,0 +1,5 @@
+---
+title: Add missing Merge Request fields
+merge_request: 30935
+author:
+type: added
diff --git a/changelogs/unreleased/ajk-gql-labels.yml b/changelogs/unreleased/ajk-gql-labels.yml
new file mode 100644
index 00000000000..8716e536492
--- /dev/null
+++ b/changelogs/unreleased/ajk-gql-labels.yml
@@ -0,0 +1,5 @@
+---
+title: Add GraphQL support for project and group labels
+merge_request: 32113
+author:
+type: added
diff --git a/changelogs/unreleased/ajk-gql-lookahead.yml b/changelogs/unreleased/ajk-gql-lookahead.yml
new file mode 100644
index 00000000000..e1d920ba57a
--- /dev/null
+++ b/changelogs/unreleased/ajk-gql-lookahead.yml
@@ -0,0 +1,5 @@
+---
+title: Add GraphQL lookahead support
+merge_request: 32373
+author:
+type: performance
diff --git a/changelogs/unreleased/ajk-gql-mr-resolvers-split.yml b/changelogs/unreleased/ajk-gql-mr-resolvers-split.yml
new file mode 100644
index 00000000000..02c84076fc3
--- /dev/null
+++ b/changelogs/unreleased/ajk-gql-mr-resolvers-split.yml
@@ -0,0 +1,5 @@
+---
+title: Add filters to merge request fields
+merge_request: 32328
+author:
+type: added
diff --git a/changelogs/unreleased/ajk-safe-wiki-event-url.yml b/changelogs/unreleased/ajk-safe-wiki-event-url.yml
new file mode 100644
index 00000000000..4e25186e024
--- /dev/null
+++ b/changelogs/unreleased/ajk-safe-wiki-event-url.yml
@@ -0,0 +1,5 @@
+---
+title: Ensure we always generate a valid wiki event URL
+merge_request: 34191
+author:
+type: fixed
diff --git a/changelogs/unreleased/ak-update-google-auth.yml b/changelogs/unreleased/ak-update-google-auth.yml
new file mode 100644
index 00000000000..cb91b9ebe93
--- /dev/null
+++ b/changelogs/unreleased/ak-update-google-auth.yml
@@ -0,0 +1,5 @@
+---
+title: Support IAP protected prometheus installations
+merge_request: 33508
+author:
+type: added
diff --git a/changelogs/unreleased/al-214420-pass-hard-delete-on-snippets-destroy.yml b/changelogs/unreleased/al-214420-pass-hard-delete-on-snippets-destroy.yml
new file mode 100644
index 00000000000..3d4e35b7322
--- /dev/null
+++ b/changelogs/unreleased/al-214420-pass-hard-delete-on-snippets-destroy.yml
@@ -0,0 +1,5 @@
+---
+title: Pass hard delete option to snippets bulk destroy
+merge_request: 33520
+author:
+type: fixed
diff --git a/changelogs/unreleased/al-215200-snippets-by-type-usage-counter.yml b/changelogs/unreleased/al-215200-snippets-by-type-usage-counter.yml
new file mode 100644
index 00000000000..de49e91fe13
--- /dev/null
+++ b/changelogs/unreleased/al-215200-snippets-by-type-usage-counter.yml
@@ -0,0 +1,5 @@
+---
+title: Add index on id and type for Snippets
+merge_request: 32885
+author:
+type: performance
diff --git a/changelogs/unreleased/al-217784-add-blobs-field-to-snippets-in-graphql.yml b/changelogs/unreleased/al-217784-add-blobs-field-to-snippets-in-graphql.yml
new file mode 100644
index 00000000000..89a3d978487
--- /dev/null
+++ b/changelogs/unreleased/al-217784-add-blobs-field-to-snippets-in-graphql.yml
@@ -0,0 +1,5 @@
+---
+title: Add blobs field to SnippetType in GraphQL
+merge_request: 33657
+author:
+type: changed
diff --git a/changelogs/unreleased/alert-assignee-dropdown.yml b/changelogs/unreleased/alert-assignee-dropdown.yml
new file mode 100644
index 00000000000..3ad54932780
--- /dev/null
+++ b/changelogs/unreleased/alert-assignee-dropdown.yml
@@ -0,0 +1,5 @@
+---
+title: Allow the assignment of alerts to users from the alert detail view
+merge_request: 33122
+author:
+type: added
diff --git a/changelogs/unreleased/alert-assignee-list-view.yml b/changelogs/unreleased/alert-assignee-list-view.yml
new file mode 100644
index 00000000000..cb942b87c0b
--- /dev/null
+++ b/changelogs/unreleased/alert-assignee-list-view.yml
@@ -0,0 +1,5 @@
+---
+title: Add database and GraphQL support for alert assignees
+merge_request: 32609
+author:
+type: added
diff --git a/changelogs/unreleased/alert-management-mobile-alignment.yml b/changelogs/unreleased/alert-management-mobile-alignment.yml
new file mode 100644
index 00000000000..04f2c3224ff
--- /dev/null
+++ b/changelogs/unreleased/alert-management-mobile-alignment.yml
@@ -0,0 +1,5 @@
+---
+title: Update alert management mobile table alignment
+merge_request: 32295
+author:
+type: other
diff --git a/changelogs/unreleased/alert-system-notes-tool-tip.yml b/changelogs/unreleased/alert-system-notes-tool-tip.yml
new file mode 100644
index 00000000000..3129a4ff521
--- /dev/null
+++ b/changelogs/unreleased/alert-system-notes-tool-tip.yml
@@ -0,0 +1,5 @@
+---
+title: Enable ability to assign alerts to users with corresponding system notes and todos
+merge_request: 34360
+author:
+type: added
diff --git a/changelogs/unreleased/alert-system-notes.yml b/changelogs/unreleased/alert-system-notes.yml
new file mode 100644
index 00000000000..2cff9e8b2a4
--- /dev/null
+++ b/changelogs/unreleased/alert-system-notes.yml
@@ -0,0 +1,5 @@
+---
+title: Add system note when assigning user to alert
+merge_request: 33217
+author:
+type: added
diff --git a/changelogs/unreleased/alert-table-classes-hotfix.yml b/changelogs/unreleased/alert-table-classes-hotfix.yml
new file mode 100644
index 00000000000..46d4ae10cbb
--- /dev/null
+++ b/changelogs/unreleased/alert-table-classes-hotfix.yml
@@ -0,0 +1,5 @@
+---
+title: Fix broken CSS classes inside alert management list
+merge_request: 33038
+author:
+type: fixed
diff --git a/changelogs/unreleased/allow_skipped.yml b/changelogs/unreleased/allow_skipped.yml
new file mode 100644
index 00000000000..b920298f42e
--- /dev/null
+++ b/changelogs/unreleased/allow_skipped.yml
@@ -0,0 +1,5 @@
+---
+title: Add setting to allow merge on skipped pipeline
+merge_request: 27490
+author: Mathieu Parent
+type: added
diff --git a/changelogs/unreleased/andr3-218471-code-review-diff-overlaps-sidebar.yml b/changelogs/unreleased/andr3-218471-code-review-diff-overlaps-sidebar.yml
new file mode 100644
index 00000000000..799e32d1578
--- /dev/null
+++ b/changelogs/unreleased/andr3-218471-code-review-diff-overlaps-sidebar.yml
@@ -0,0 +1,5 @@
+---
+title: Fix whitespace changes overgrowing the diff container
+merge_request: 32774
+author:
+type: fixed
diff --git a/changelogs/unreleased/asciidoc-alignment-roles.yml b/changelogs/unreleased/asciidoc-alignment-roles.yml
new file mode 100644
index 00000000000..d53d3705243
--- /dev/null
+++ b/changelogs/unreleased/asciidoc-alignment-roles.yml
@@ -0,0 +1,5 @@
+---
+title: 'AsciiDoc: Add support for built-in alignment roles.'
+merge_request: 32928
+author: mnrvwl
+type: fixed
diff --git a/changelogs/unreleased/assign-alerts-sidebar-base.yml b/changelogs/unreleased/assign-alerts-sidebar-base.yml
new file mode 100644
index 00000000000..3785df5e8e0
--- /dev/null
+++ b/changelogs/unreleased/assign-alerts-sidebar-base.yml
@@ -0,0 +1,5 @@
+---
+title: Assign alerts sidebar base
+merge_request 32642:
+author:
+type: changed
diff --git a/changelogs/unreleased/assign-alerts-sidebar-container-fix.yml b/changelogs/unreleased/assign-alerts-sidebar-container-fix.yml
new file mode 100644
index 00000000000..cdf9bb479ce
--- /dev/null
+++ b/changelogs/unreleased/assign-alerts-sidebar-container-fix.yml
@@ -0,0 +1,5 @@
+---
+title: Assign alerts sidebar container fix
+merge_request: 32743
+author:
+type: other
diff --git a/changelogs/unreleased/autodevops-secrets.yml b/changelogs/unreleased/autodevops-secrets.yml
new file mode 100644
index 00000000000..dd1df110620
--- /dev/null
+++ b/changelogs/unreleased/autodevops-secrets.yml
@@ -0,0 +1,5 @@
+---
+title: Add secret detection template to Auto DevOps
+merge_request: 34467
+author:
+type: changed
diff --git a/changelogs/unreleased/aws-guidance.yml b/changelogs/unreleased/aws-guidance.yml
new file mode 100644
index 00000000000..ab3725c1397
--- /dev/null
+++ b/changelogs/unreleased/aws-guidance.yml
@@ -0,0 +1,5 @@
+---
+title: Adds AWS guidance to CI/CD > Add Variable modal
+merge_request: 34009
+author:
+type: added
diff --git a/changelogs/unreleased/browse-locked-artifact.yml b/changelogs/unreleased/browse-locked-artifact.yml
new file mode 100644
index 00000000000..d89739a3de6
--- /dev/null
+++ b/changelogs/unreleased/browse-locked-artifact.yml
@@ -0,0 +1,5 @@
+---
+title: Update artifacts section to show when an artifact is locked
+merge_request: 32992
+author:
+type: changed
diff --git a/changelogs/unreleased/bump_ci_auto_deploy_0_16.yml b/changelogs/unreleased/bump_ci_auto_deploy_0_16.yml
new file mode 100644
index 00000000000..b222b69f295
--- /dev/null
+++ b/changelogs/unreleased/bump_ci_auto_deploy_0_16.yml
@@ -0,0 +1,5 @@
+---
+title: Update Auto deploy image to v0.16.1, introducing support for AUTO_DEVOPS_DEPLOY_DEBUG
+merge_request: 33799
+author:
+type: changed
diff --git a/changelogs/unreleased/bump_cluster_applications_version.yml b/changelogs/unreleased/bump_cluster_applications_version.yml
new file mode 100644
index 00000000000..7ea7407350d
--- /dev/null
+++ b/changelogs/unreleased/bump_cluster_applications_version.yml
@@ -0,0 +1,5 @@
+---
+title: Bump cluster-applications version to v0.20.0
+merge_request: 34569
+author:
+type: added
diff --git a/changelogs/unreleased/cablett-email-link.yml b/changelogs/unreleased/cablett-email-link.yml
new file mode 100644
index 00000000000..405bcb649c5
--- /dev/null
+++ b/changelogs/unreleased/cablett-email-link.yml
@@ -0,0 +1,5 @@
+---
+title: Add new issue link to email notification header
+merge_request: 32833
+author:
+type: changed
diff --git a/changelogs/unreleased/cablett-merge-request-merged-email-ref.yml b/changelogs/unreleased/cablett-merge-request-merged-email-ref.yml
new file mode 100644
index 00000000000..4d2128c5910
--- /dev/null
+++ b/changelogs/unreleased/cablett-merge-request-merged-email-ref.yml
@@ -0,0 +1,5 @@
+---
+title: Render Merge request reference as link
+merge_request: 33248
+author:
+type: changed
diff --git a/changelogs/unreleased/calebw-update-stuck-runner-message.yml b/changelogs/unreleased/calebw-update-stuck-runner-message.yml
new file mode 100644
index 00000000000..57c48377ae5
--- /dev/null
+++ b/changelogs/unreleased/calebw-update-stuck-runner-message.yml
@@ -0,0 +1,5 @@
+---
+title: Clarify verbiage for stuck job messages.
+merge_request: 32250
+author:
+type: other
diff --git a/changelogs/unreleased/change_from_vendor_specific_to_gitlab.yml b/changelogs/unreleased/change_from_vendor_specific_to_gitlab.yml
new file mode 100644
index 00000000000..f32424612b9
--- /dev/null
+++ b/changelogs/unreleased/change_from_vendor_specific_to_gitlab.yml
@@ -0,0 +1,5 @@
+---
+title: Change from vendor specific to Gitlab
+merge_request: 34576
+author:
+type: changed
diff --git a/changelogs/unreleased/chore-bump-omniauth_openid_connect.yml b/changelogs/unreleased/chore-bump-omniauth_openid_connect.yml
new file mode 100644
index 00000000000..a9415ef2def
--- /dev/null
+++ b/changelogs/unreleased/chore-bump-omniauth_openid_connect.yml
@@ -0,0 +1,5 @@
+---
+title: Bump omniauth_openid_connect to 0.3.5
+merge_request: 34030
+author: Roger Meier
+type: other
diff --git a/changelogs/unreleased/chore-styles-removal.yml b/changelogs/unreleased/chore-styles-removal.yml
new file mode 100644
index 00000000000..b395ad5cf20
--- /dev/null
+++ b/changelogs/unreleased/chore-styles-removal.yml
@@ -0,0 +1,5 @@
+---
+title: Remove temporary datepicker position fix as it is no longer required
+merge_request: 31836
+author: Arun Kumar Mohan
+type: removed
diff --git a/changelogs/unreleased/ci-rust-cargo-test-workspace-option.yml b/changelogs/unreleased/ci-rust-cargo-test-workspace-option.yml
new file mode 100644
index 00000000000..91e3117bffa
--- /dev/null
+++ b/changelogs/unreleased/ci-rust-cargo-test-workspace-option.yml
@@ -0,0 +1,5 @@
+---
+title: "Rust CI template: Replace --all with --workspace on cargo test."
+merge_request: 33517
+author: Markus Becker
+type: fixed
diff --git a/changelogs/unreleased/clean-up-install-from-source-gitlab-shell.yml b/changelogs/unreleased/clean-up-install-from-source-gitlab-shell.yml
new file mode 100644
index 00000000000..d14cf0f9382
--- /dev/null
+++ b/changelogs/unreleased/clean-up-install-from-source-gitlab-shell.yml
@@ -0,0 +1,5 @@
+---
+title: Clean up gitlab-shell install-from-source path
+merge_request: 33057
+author:
+type: changed
diff --git a/changelogs/unreleased/cngo-add-link-text-to-collapsed-left-sidebar.yml b/changelogs/unreleased/cngo-add-link-text-to-collapsed-left-sidebar.yml
new file mode 100644
index 00000000000..0d7f75d24b8
--- /dev/null
+++ b/changelogs/unreleased/cngo-add-link-text-to-collapsed-left-sidebar.yml
@@ -0,0 +1,5 @@
+---
+title: Add link text to collapsed left sidebar links for screen readers
+merge_request: 33866
+author:
+type: fixed
diff --git a/changelogs/unreleased/cngo-improve-header-accessibility.yml b/changelogs/unreleased/cngo-improve-header-accessibility.yml
new file mode 100644
index 00000000000..384db4602b2
--- /dev/null
+++ b/changelogs/unreleased/cngo-improve-header-accessibility.yml
@@ -0,0 +1,5 @@
+---
+title: Improve header acccessibility
+merge_request: 33603
+author:
+type: fixed
diff --git a/changelogs/unreleased/cngo-make-markdown-textarea-links-tab-accessible.yml b/changelogs/unreleased/cngo-make-markdown-textarea-links-tab-accessible.yml
new file mode 100644
index 00000000000..5da2079f9b4
--- /dev/null
+++ b/changelogs/unreleased/cngo-make-markdown-textarea-links-tab-accessible.yml
@@ -0,0 +1,5 @@
+---
+title: Make markdown textarea links tab-accessible
+merge_request: 33518
+author:
+type: fixed
diff --git a/changelogs/unreleased/create-branch-url.yml b/changelogs/unreleased/create-branch-url.yml
new file mode 100644
index 00000000000..84f89bba805
--- /dev/null
+++ b/changelogs/unreleased/create-branch-url.yml
@@ -0,0 +1,5 @@
+---
+title: Add anchor for creating a branch
+merge_request: 32745
+author:
+type: other
diff --git a/changelogs/unreleased/create-ops-ff-issues-table.yml b/changelogs/unreleased/create-ops-ff-issues-table.yml
new file mode 100644
index 00000000000..9d6395d26cc
--- /dev/null
+++ b/changelogs/unreleased/create-ops-ff-issues-table.yml
@@ -0,0 +1,5 @@
+---
+title: Create operations_feature_flags_issues table
+merge_request: 32876
+author:
+type: added
diff --git a/changelogs/unreleased/curd-auto-merge-in-transaction.yml b/changelogs/unreleased/curd-auto-merge-in-transaction.yml
new file mode 100644
index 00000000000..9a9cfbea1c7
--- /dev/null
+++ b/changelogs/unreleased/curd-auto-merge-in-transaction.yml
@@ -0,0 +1,5 @@
+---
+title: Wrap auto merge parameters update in database transaction
+merge_request: 33471
+author:
+type: fixed
diff --git a/changelogs/unreleased/data-endpoint-for-dag-visualization-2.yml b/changelogs/unreleased/data-endpoint-for-dag-visualization-2.yml
new file mode 100644
index 00000000000..d4b91718861
--- /dev/null
+++ b/changelogs/unreleased/data-endpoint-for-dag-visualization-2.yml
@@ -0,0 +1,5 @@
+---
+title: Add DAG serializer for pipelines controller
+merge_request: 31583
+author:
+type: added
diff --git a/changelogs/unreleased/dblessing-new-sign-in-email-beautification.yml b/changelogs/unreleased/dblessing-new-sign-in-email-beautification.yml
new file mode 100644
index 00000000000..96ad1bc440d
--- /dev/null
+++ b/changelogs/unreleased/dblessing-new-sign-in-email-beautification.yml
@@ -0,0 +1,5 @@
+---
+title: Improve new/unknown sign-in email styling
+merge_request: 32808
+author:
+type: changed
diff --git a/changelogs/unreleased/dennis-project-templates-add-gitbook-logo.yml b/changelogs/unreleased/dennis-project-templates-add-gitbook-logo.yml
new file mode 100644
index 00000000000..ebe823442f0
--- /dev/null
+++ b/changelogs/unreleased/dennis-project-templates-add-gitbook-logo.yml
@@ -0,0 +1,5 @@
+---
+title: Add GitBook logo to project templates
+merge_request: 33403
+author:
+type: changed
diff --git a/changelogs/unreleased/dennis-project-templates-add-gomicro-logo.yml b/changelogs/unreleased/dennis-project-templates-add-gomicro-logo.yml
new file mode 100644
index 00000000000..19bce8e3c28
--- /dev/null
+++ b/changelogs/unreleased/dennis-project-templates-add-gomicro-logo.yml
@@ -0,0 +1,5 @@
+---
+title: Add GoMicro logo to project templates
+merge_request: 33404
+author:
+type: changed
diff --git a/changelogs/unreleased/dennis-project-templates-add-hexo-logo.yml b/changelogs/unreleased/dennis-project-templates-add-hexo-logo.yml
new file mode 100644
index 00000000000..59ae2a3a99a
--- /dev/null
+++ b/changelogs/unreleased/dennis-project-templates-add-hexo-logo.yml
@@ -0,0 +1,5 @@
+---
+title: Add Hexo logo to project templates
+merge_request: 33406
+author:
+type: changed
diff --git a/changelogs/unreleased/dennis-project-templates-add-hugo-logo.yml b/changelogs/unreleased/dennis-project-templates-add-hugo-logo.yml
new file mode 100644
index 00000000000..df2305c1406
--- /dev/null
+++ b/changelogs/unreleased/dennis-project-templates-add-hugo-logo.yml
@@ -0,0 +1,5 @@
+---
+title: Add Hugo logo to project templates
+merge_request: 33402
+author:
+type: changed
diff --git a/changelogs/unreleased/dennis-project-templates-add-jekyll-logo.yml b/changelogs/unreleased/dennis-project-templates-add-jekyll-logo.yml
new file mode 100644
index 00000000000..1cb28444cbc
--- /dev/null
+++ b/changelogs/unreleased/dennis-project-templates-add-jekyll-logo.yml
@@ -0,0 +1,5 @@
+---
+title: Add Jekyll logo to project templates
+merge_request: 33405
+author:
+type: changed
diff --git a/changelogs/unreleased/dennis-update-webhooks-page-from-whitelist-to-allowlist.yml b/changelogs/unreleased/dennis-update-webhooks-page-from-whitelist-to-allowlist.yml
new file mode 100644
index 00000000000..80d2ec6d7ba
--- /dev/null
+++ b/changelogs/unreleased/dennis-update-webhooks-page-from-whitelist-to-allowlist.yml
@@ -0,0 +1,5 @@
+---
+title: Update local IP address and domain name allow list input label
+merge_request: 33812
+author:
+type: changed
diff --git a/changelogs/unreleased/design-view-scrolling-issue-bug.yml b/changelogs/unreleased/design-view-scrolling-issue-bug.yml
new file mode 100644
index 00000000000..d47ecfa848a
--- /dev/null
+++ b/changelogs/unreleased/design-view-scrolling-issue-bug.yml
@@ -0,0 +1,5 @@
+---
+title: Remove ability to scroll Issue while in Design View
+merge_request: 29881
+author:
+type: fixed
diff --git a/changelogs/unreleased/docs-auto-build-cnb-custom-builder.yml b/changelogs/unreleased/docs-auto-build-cnb-custom-builder.yml
new file mode 100644
index 00000000000..8e96cf2d53a
--- /dev/null
+++ b/changelogs/unreleased/docs-auto-build-cnb-custom-builder.yml
@@ -0,0 +1,5 @@
+---
+title: Customize the Cloud Native Buildpack builder used with Auto Build
+merge_request: 32691
+author:
+type: added
diff --git a/changelogs/unreleased/docs-firefox-u2f-api.yml b/changelogs/unreleased/docs-firefox-u2f-api.yml
new file mode 100644
index 00000000000..c15a81694f5
--- /dev/null
+++ b/changelogs/unreleased/docs-firefox-u2f-api.yml
@@ -0,0 +1,5 @@
+---
+title: Update U2F docs for Firefox 67+
+merge_request: 32289
+author: Takuya Noguchi
+type: other
diff --git a/changelogs/unreleased/docs-fj-update-web-ide-terminal-doc-core.yml b/changelogs/unreleased/docs-fj-update-web-ide-terminal-doc-core.yml
new file mode 100644
index 00000000000..a48e6e235f9
--- /dev/null
+++ b/changelogs/unreleased/docs-fj-update-web-ide-terminal-doc-core.yml
@@ -0,0 +1,5 @@
+---
+title: Update docs to reflect move web IDE Terminal and file sync to Core
+merge_request: 33419
+author:
+type: other
diff --git a/changelogs/unreleased/docs-saml-sso-from-core-at-self-hosted.yml b/changelogs/unreleased/docs-saml-sso-from-core-at-self-hosted.yml
new file mode 100644
index 00000000000..9ad183db112
--- /dev/null
+++ b/changelogs/unreleased/docs-saml-sso-from-core-at-self-hosted.yml
@@ -0,0 +1,5 @@
+---
+title: Specify tiers for SAML SSO at self-hosted plans
+merge_request: 34040
+author: Takuya Noguchi
+type: other
diff --git a/changelogs/unreleased/docs-u2f-version-history.yml b/changelogs/unreleased/docs-u2f-version-history.yml
new file mode 100644
index 00000000000..e847faa317e
--- /dev/null
+++ b/changelogs/unreleased/docs-u2f-version-history.yml
@@ -0,0 +1,5 @@
+---
+title: Add version history information on U2F support
+merge_request: 33229
+author: Takuya Noguchi
+type: other
diff --git a/changelogs/unreleased/downloadable_reports.yml b/changelogs/unreleased/downloadable_reports.yml
new file mode 100644
index 00000000000..58f2c6d5ee1
--- /dev/null
+++ b/changelogs/unreleased/downloadable_reports.yml
@@ -0,0 +1,5 @@
+---
+title: Add secret_detection to DOWNLOADABLE_TYPES
+merge_request: 34313
+author:
+type: added
diff --git a/changelogs/unreleased/dz-redirect-unscoped-pipelines-routes.yml b/changelogs/unreleased/dz-redirect-unscoped-pipelines-routes.yml
new file mode 100644
index 00000000000..dbe7c17f61d
--- /dev/null
+++ b/changelogs/unreleased/dz-redirect-unscoped-pipelines-routes.yml
@@ -0,0 +1,5 @@
+---
+title: Move pipelines routing under /-/ scope
+merge_request: 30730
+author:
+type: changed
diff --git a/changelogs/unreleased/ee-app-services-1.yml b/changelogs/unreleased/ee-app-services-1.yml
new file mode 100644
index 00000000000..bbd916a9d2c
--- /dev/null
+++ b/changelogs/unreleased/ee-app-services-1.yml
@@ -0,0 +1,5 @@
+---
+title: Move prepend to last in ee-app-services
+merge_request: 31838
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/emilyring-cluster-list-refactor-provider-icon.yml b/changelogs/unreleased/emilyring-cluster-list-refactor-provider-icon.yml
new file mode 100644
index 00000000000..b16051b7303
--- /dev/null
+++ b/changelogs/unreleased/emilyring-cluster-list-refactor-provider-icon.yml
@@ -0,0 +1,5 @@
+---
+title: Added provider type icon to cluster list
+merge_request: 33196
+author:
+type: changed
diff --git a/changelogs/unreleased/emilyring-remove-tf-plan-name.yml b/changelogs/unreleased/emilyring-remove-tf-plan-name.yml
new file mode 100644
index 00000000000..c7bbb46c82f
--- /dev/null
+++ b/changelogs/unreleased/emilyring-remove-tf-plan-name.yml
@@ -0,0 +1,5 @@
+---
+title: Removed default artifact name for Terraform template
+merge_request: 34557
+author:
+type: fixed
diff --git a/changelogs/unreleased/emilyring-tf-widget-multiple.yml b/changelogs/unreleased/emilyring-tf-widget-multiple.yml
new file mode 100644
index 00000000000..1bd7a002ede
--- /dev/null
+++ b/changelogs/unreleased/emilyring-tf-widget-multiple.yml
@@ -0,0 +1,5 @@
+---
+title: Allow Tf Plan to genrate multiple reports
+merge_request: 33867
+author:
+type: changed
diff --git a/changelogs/unreleased/enable-atomic-processing-by-default.yml b/changelogs/unreleased/enable-atomic-processing-by-default.yml
new file mode 100644
index 00000000000..691728b4ae4
--- /dev/null
+++ b/changelogs/unreleased/enable-atomic-processing-by-default.yml
@@ -0,0 +1,5 @@
+---
+title: Enable CI Atomic Processing by default
+merge_request:
+author:
+type: performance
diff --git a/changelogs/unreleased/exclude-server-fields-from-exceptions-log.yml b/changelogs/unreleased/exclude-server-fields-from-exceptions-log.yml
new file mode 100644
index 00000000000..2fac0330b5c
--- /dev/null
+++ b/changelogs/unreleased/exclude-server-fields-from-exceptions-log.yml
@@ -0,0 +1,5 @@
+---
+title: Exclude extra.server fields from exceptions_json.log
+merge_request: 32770
+author:
+type: changed
diff --git a/changelogs/unreleased/experimentation-cookie-domain.yml b/changelogs/unreleased/experimentation-cookie-domain.yml
new file mode 100644
index 00000000000..94e102305fe
--- /dev/null
+++ b/changelogs/unreleased/experimentation-cookie-domain.yml
@@ -0,0 +1,5 @@
+---
+title: Set experiementation cookie for GitLab domain only
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/feat-admin-pages-show-custom-attributes.yml b/changelogs/unreleased/feat-admin-pages-show-custom-attributes.yml
new file mode 100644
index 00000000000..6a9efcff172
--- /dev/null
+++ b/changelogs/unreleased/feat-admin-pages-show-custom-attributes.yml
@@ -0,0 +1,5 @@
+---
+title: Show custom attributes within Admin Pages
+merge_request: 34017
+author: Roger Meier
+type: added
diff --git a/changelogs/unreleased/feature-api-add-bridge-api-endpoint.yml b/changelogs/unreleased/feature-api-add-bridge-api-endpoint.yml
new file mode 100644
index 00000000000..02298d74233
--- /dev/null
+++ b/changelogs/unreleased/feature-api-add-bridge-api-endpoint.yml
@@ -0,0 +1,5 @@
+---
+title: Add API endpoint for listing bridge jobs.
+merge_request: 31370
+author: Abhijith Sivarajan
+type: added
diff --git a/changelogs/unreleased/feature-bump-cluster-applications-to-0-16-0.yml b/changelogs/unreleased/feature-bump-cluster-applications-to-0-16-0.yml
new file mode 100644
index 00000000000..f548d243a05
--- /dev/null
+++ b/changelogs/unreleased/feature-bump-cluster-applications-to-0-16-0.yml
@@ -0,0 +1,5 @@
+---
+title: Adds PostHog as a CI/CD Managed Application
+merge_request: 32856
+author:
+type: added
diff --git a/changelogs/unreleased/feature-gb-artifacts-exclude-feature-flag.yml b/changelogs/unreleased/feature-gb-artifacts-exclude-feature-flag.yml
new file mode 100644
index 00000000000..1bb65ee2127
--- /dev/null
+++ b/changelogs/unreleased/feature-gb-artifacts-exclude-feature-flag.yml
@@ -0,0 +1,5 @@
+---
+title: Add support for artifacts/exclude configuration
+merge_request: 33170
+author:
+type: added
diff --git a/changelogs/unreleased/feature-show-memory-cpu-on-cluster-list.yml b/changelogs/unreleased/feature-show-memory-cpu-on-cluster-list.yml
new file mode 100644
index 00000000000..e3375d85821
--- /dev/null
+++ b/changelogs/unreleased/feature-show-memory-cpu-on-cluster-list.yml
@@ -0,0 +1,5 @@
+---
+title: Adds cluster CPU and Memory to cluster index
+merge_request: 32601
+author:
+type: changed
diff --git a/changelogs/unreleased/filter-from-url-query-params-pipeline.yml b/changelogs/unreleased/filter-from-url-query-params-pipeline.yml
new file mode 100644
index 00000000000..e1de53cb4ef
--- /dev/null
+++ b/changelogs/unreleased/filter-from-url-query-params-pipeline.yml
@@ -0,0 +1,5 @@
+---
+title: Filter pipelines based on url query params
+merge_request: 32230
+author:
+type: added
diff --git a/changelogs/unreleased/filter-pipelines-by-status.yml b/changelogs/unreleased/filter-pipelines-by-status.yml
new file mode 100644
index 00000000000..e768fb3e112
--- /dev/null
+++ b/changelogs/unreleased/filter-pipelines-by-status.yml
@@ -0,0 +1,5 @@
+---
+title: Filter pipelines by status
+merge_request: 32151
+author:
+type: added
diff --git a/changelogs/unreleased/filter-pipelines-by-tag-name.yml b/changelogs/unreleased/filter-pipelines-by-tag-name.yml
new file mode 100644
index 00000000000..259fd8e9808
--- /dev/null
+++ b/changelogs/unreleased/filter-pipelines-by-tag-name.yml
@@ -0,0 +1,5 @@
+---
+title: Filter Pipelines by Tag Name
+merge_request: 32470
+author:
+type: added
diff --git a/changelogs/unreleased/fix-atomic-processing-lock-version.yml b/changelogs/unreleased/fix-atomic-processing-lock-version.yml
new file mode 100644
index 00000000000..9db891d651f
--- /dev/null
+++ b/changelogs/unreleased/fix-atomic-processing-lock-version.yml
@@ -0,0 +1,5 @@
+---
+title: Fix atomic processing bumping a lock_version
+merge_request: 32914
+author:
+type: fixed
diff --git a/changelogs/unreleased/fix-design-notes-filename-duplication.yml b/changelogs/unreleased/fix-design-notes-filename-duplication.yml
new file mode 100644
index 00000000000..5d82323f6f2
--- /dev/null
+++ b/changelogs/unreleased/fix-design-notes-filename-duplication.yml
@@ -0,0 +1,5 @@
+---
+title: Fix filename duplication in design notes in activity feeds
+merge_request: 32823
+author: Arun Kumar Mohan
+type: fixed
diff --git a/changelogs/unreleased/fix-design-todos-filename-duplication.yml b/changelogs/unreleased/fix-design-todos-filename-duplication.yml
new file mode 100644
index 00000000000..901e8bbc8e3
--- /dev/null
+++ b/changelogs/unreleased/fix-design-todos-filename-duplication.yml
@@ -0,0 +1,5 @@
+---
+title: Fix duplicate filename displayed in design todos
+merge_request: 32274
+author: Arun Kumar Mohan
+type: fixed
diff --git a/changelogs/unreleased/fix-ecs-detached-branch-pipeline.yml b/changelogs/unreleased/fix-ecs-detached-branch-pipeline.yml
new file mode 100644
index 00000000000..cca6bb4eac3
--- /dev/null
+++ b/changelogs/unreleased/fix-ecs-detached-branch-pipeline.yml
@@ -0,0 +1,5 @@
+---
+title: Fix CI rules for ECS related jobs
+merge_request: 33527
+author:
+type: fixed
diff --git a/changelogs/unreleased/fix-group-transfer-to-subgroup.yml b/changelogs/unreleased/fix-group-transfer-to-subgroup.yml
new file mode 100644
index 00000000000..41294ceca36
--- /dev/null
+++ b/changelogs/unreleased/fix-group-transfer-to-subgroup.yml
@@ -0,0 +1,5 @@
+---
+title: Fix group transfer service to deny moving group to its subgroup
+merge_request: 31495
+author: Abhisek Datta
+type: fixed
diff --git a/changelogs/unreleased/fix-invalid-error-tracking-method.yml b/changelogs/unreleased/fix-invalid-error-tracking-method.yml
new file mode 100644
index 00000000000..90a49dcd8bd
--- /dev/null
+++ b/changelogs/unreleased/fix-invalid-error-tracking-method.yml
@@ -0,0 +1,5 @@
+---
+title: Fix NoMethodError by using the correct method to report exceptions to Sentry
+merge_request: 33260
+author:
+type: fixed
diff --git a/changelogs/unreleased/fix-max_import_size.yml b/changelogs/unreleased/fix-max_import_size.yml
new file mode 100644
index 00000000000..0cd9ceaa4d9
--- /dev/null
+++ b/changelogs/unreleased/fix-max_import_size.yml
@@ -0,0 +1,5 @@
+---
+title: Add max import file size option
+merge_request: 33215
+author: Roger Meier
+type: added
diff --git a/changelogs/unreleased/fix-omniauth-buttons-js.yml b/changelogs/unreleased/fix-omniauth-buttons-js.yml
new file mode 100644
index 00000000000..9350af2cdd0
--- /dev/null
+++ b/changelogs/unreleased/fix-omniauth-buttons-js.yml
@@ -0,0 +1,5 @@
+---
+title: Avoid javascript for omniauth logins
+merge_request: 33459
+author: Diego Louzán
+type: other
diff --git a/changelogs/unreleased/fix-pagination-link.yml b/changelogs/unreleased/fix-pagination-link.yml
new file mode 100644
index 00000000000..d2c1fc1eb94
--- /dev/null
+++ b/changelogs/unreleased/fix-pagination-link.yml
@@ -0,0 +1,5 @@
+---
+title: Fix pagination link header
+merge_request: 33714
+author: Max Wittig
+type: fixed
diff --git a/changelogs/unreleased/fix-runner-hearbeat.yml b/changelogs/unreleased/fix-runner-hearbeat.yml
new file mode 100644
index 00000000000..8125bad48ab
--- /dev/null
+++ b/changelogs/unreleased/fix-runner-hearbeat.yml
@@ -0,0 +1,5 @@
+---
+title: Fix Runner heartbeats that results in considering them offline
+merge_request: 32851
+author:
+type: fixed
diff --git a/changelogs/unreleased/fix-selecting-status-emoji-twice.yml b/changelogs/unreleased/fix-selecting-status-emoji-twice.yml
new file mode 100644
index 00000000000..b4da2f096b6
--- /dev/null
+++ b/changelogs/unreleased/fix-selecting-status-emoji-twice.yml
@@ -0,0 +1,5 @@
+---
+title: Fix invisible emoji modal on Set Status form when clicked the second time
+merge_request: 33398
+author:
+type: fixed
diff --git a/changelogs/unreleased/fix-typo-issues-limit-settings-template.yml b/changelogs/unreleased/fix-typo-issues-limit-settings-template.yml
new file mode 100644
index 00000000000..c0fd8b45692
--- /dev/null
+++ b/changelogs/unreleased/fix-typo-issues-limit-settings-template.yml
@@ -0,0 +1,5 @@
+---
+title: Update issue limits template to use minutes
+merge_request: 34254
+author:
+type: fixed
diff --git a/changelogs/unreleased/fix-vertically-center-action-icon.yml b/changelogs/unreleased/fix-vertically-center-action-icon.yml
new file mode 100644
index 00000000000..40c97bbc73b
--- /dev/null
+++ b/changelogs/unreleased/fix-vertically-center-action-icon.yml
@@ -0,0 +1,5 @@
+---
+title: vertically center action icon in the CI pipeline
+merge_request: 33427
+author: Nathanael Weber
+type: fixed
diff --git a/changelogs/unreleased/fix_back_button_when_switching_mr_tabs.yml b/changelogs/unreleased/fix_back_button_when_switching_mr_tabs.yml
new file mode 100644
index 00000000000..bb9904faa50
--- /dev/null
+++ b/changelogs/unreleased/fix_back_button_when_switching_mr_tabs.yml
@@ -0,0 +1,5 @@
+---
+title: Fix back button when switching MR tabs
+merge_request: 29862
+author: Lee Tickett
+type: fixed
diff --git a/changelogs/unreleased/fix_default_path_when_creating_project_from_group_template.yml b/changelogs/unreleased/fix_default_path_when_creating_project_from_group_template.yml
new file mode 100644
index 00000000000..500b688f13f
--- /dev/null
+++ b/changelogs/unreleased/fix_default_path_when_creating_project_from_group_template.yml
@@ -0,0 +1,5 @@
+---
+title: Fix default path when creating project from group template
+merge_request: 30597
+author: Lee Tickett
+type: fixed
diff --git a/changelogs/unreleased/fix_deleting_user_psql_error_on_events_table_v2.yml b/changelogs/unreleased/fix_deleting_user_psql_error_on_events_table_v2.yml
new file mode 100644
index 00000000000..33572c95188
--- /dev/null
+++ b/changelogs/unreleased/fix_deleting_user_psql_error_on_events_table_v2.yml
@@ -0,0 +1,5 @@
+---
+title: Remove not null constraint from events tables
+merge_request: 34190
+author:
+type: fixed
diff --git a/changelogs/unreleased/fix_mr_note_label_urls.yml b/changelogs/unreleased/fix_mr_note_label_urls.yml
new file mode 100644
index 00000000000..5558fe22804
--- /dev/null
+++ b/changelogs/unreleased/fix_mr_note_label_urls.yml
@@ -0,0 +1,5 @@
+---
+title: Fix merge request note label URLs
+merge_request: 30428
+author: Lee Tickett
+type: fixed
diff --git a/changelogs/unreleased/fix_nil_class_for_bytesize_error.yml b/changelogs/unreleased/fix_nil_class_for_bytesize_error.yml
new file mode 100644
index 00000000000..7db554864c9
--- /dev/null
+++ b/changelogs/unreleased/fix_nil_class_for_bytesize_error.yml
@@ -0,0 +1,5 @@
+---
+title: Fix undefined error in Gitlab::Git::Diff
+merge_request: 32967
+author:
+type: fixed
diff --git a/changelogs/unreleased/fix_preconnect_typo.yml b/changelogs/unreleased/fix_preconnect_typo.yml
new file mode 100644
index 00000000000..433bab8ec9d
--- /dev/null
+++ b/changelogs/unreleased/fix_preconnect_typo.yml
@@ -0,0 +1,5 @@
+---
+title: Fix preconnect typo in rel link
+merge_request: 33255
+author:
+type: performance
diff --git a/changelogs/unreleased/fj-add-allowed-actions-to-snippet-input-action.yml b/changelogs/unreleased/fj-add-allowed-actions-to-snippet-input-action.yml
new file mode 100644
index 00000000000..ac25131bd1f
--- /dev/null
+++ b/changelogs/unreleased/fj-add-allowed-actions-to-snippet-input-action.yml
@@ -0,0 +1,5 @@
+---
+title: Add allowed actions to snippet input action
+merge_request: 34499
+author:
+type: changed
diff --git a/changelogs/unreleased/fj-add-snippet-file-input-action.yml b/changelogs/unreleased/fj-add-snippet-file-input-action.yml
new file mode 100644
index 00000000000..583e5038633
--- /dev/null
+++ b/changelogs/unreleased/fj-add-snippet-file-input-action.yml
@@ -0,0 +1,5 @@
+---
+title: Add GraphQL snippet FileInputType
+merge_request: 34442
+author:
+type: other
diff --git a/changelogs/unreleased/fj-add-snippet-files-param-to-snippet-create-service.yml b/changelogs/unreleased/fj-add-snippet-files-param-to-snippet-create-service.yml
new file mode 100644
index 00000000000..cd3a5ead9e6
--- /dev/null
+++ b/changelogs/unreleased/fj-add-snippet-files-param-to-snippet-create-service.yml
@@ -0,0 +1,5 @@
+---
+title: Allow the snippet create service to accept an array of files
+merge_request: 32649
+author:
+type: changed
diff --git a/changelogs/unreleased/fj-add-snippet-files-param-to-snippet-update-service.yml b/changelogs/unreleased/fj-add-snippet-files-param-to-snippet-update-service.yml
new file mode 100644
index 00000000000..8892a5166ea
--- /dev/null
+++ b/changelogs/unreleased/fj-add-snippet-files-param-to-snippet-update-service.yml
@@ -0,0 +1,5 @@
+---
+title: Allow the snippet update service to accept an array of files
+merge_request: 32832
+author:
+type: changed
diff --git a/changelogs/unreleased/fj-add-validations-snippet-input-action.yml b/changelogs/unreleased/fj-add-validations-snippet-input-action.yml
new file mode 100644
index 00000000000..005ec4ccf9d
--- /dev/null
+++ b/changelogs/unreleased/fj-add-validations-snippet-input-action.yml
@@ -0,0 +1,5 @@
+---
+title: Add update validations to SnippetInputAction
+merge_request: 33379
+author:
+type: changed
diff --git a/changelogs/unreleased/fj-backfill-imported-snippet-repositories.yml b/changelogs/unreleased/fj-backfill-imported-snippet-repositories.yml
new file mode 100644
index 00000000000..d2ea7fe1be1
--- /dev/null
+++ b/changelogs/unreleased/fj-backfill-imported-snippet-repositories.yml
@@ -0,0 +1,5 @@
+---
+title: Backfill failed imported snippet repositories
+merge_request: 34052
+author:
+type: other
diff --git a/changelogs/unreleased/fj-bump-lfs-token-default-expiration-time.yml b/changelogs/unreleased/fj-bump-lfs-token-default-expiration-time.yml
new file mode 100644
index 00000000000..c0dc036f79f
--- /dev/null
+++ b/changelogs/unreleased/fj-bump-lfs-token-default-expiration-time.yml
@@ -0,0 +1,5 @@
+---
+title: Increase LFS token default time to 2 hours
+merge_request: 33140
+author:
+type: changed
diff --git a/changelogs/unreleased/fj-change-snippet-author-nullable-graphql-type.yml b/changelogs/unreleased/fj-change-snippet-author-nullable-graphql-type.yml
new file mode 100644
index 00000000000..925f7ff9a25
--- /dev/null
+++ b/changelogs/unreleased/fj-change-snippet-author-nullable-graphql-type.yml
@@ -0,0 +1,5 @@
+---
+title: Set author as nullable in snippet GraphQL Type
+merge_request: 34135
+author:
+type: fixed
diff --git a/changelogs/unreleased/fj-fix-import-from-different-types-exports.yml b/changelogs/unreleased/fj-fix-import-from-different-types-exports.yml
new file mode 100644
index 00000000000..5a6fd312ee4
--- /dev/null
+++ b/changelogs/unreleased/fj-fix-import-from-different-types-exports.yml
@@ -0,0 +1,5 @@
+---
+title: Fix snippet repository import fail with older export files
+merge_request: 33584
+author:
+type: fixed
diff --git a/changelogs/unreleased/fj-fix-single-param-update.yml b/changelogs/unreleased/fj-fix-single-param-update.yml
new file mode 100644
index 00000000000..8d5f9dd80d4
--- /dev/null
+++ b/changelogs/unreleased/fj-fix-single-param-update.yml
@@ -0,0 +1,5 @@
+---
+title: Fix bug in snippets updating only file_name or content
+merge_request: 33375
+author:
+type: fixed
diff --git a/changelogs/unreleased/fj-fix-snippet-create-mutation-non-activerecord-errors.yml b/changelogs/unreleased/fj-fix-snippet-create-mutation-non-activerecord-errors.yml
new file mode 100644
index 00000000000..4d5bbceb870
--- /dev/null
+++ b/changelogs/unreleased/fj-fix-snippet-create-mutation-non-activerecord-errors.yml
@@ -0,0 +1,5 @@
+---
+title: Fix bug in snippet create mutation with non ActiveRecord errors
+merge_request: 33085
+author:
+type: fixed
diff --git a/changelogs/unreleased/fj-fix-snippet-import-from-database.yml b/changelogs/unreleased/fj-fix-snippet-import-from-database.yml
new file mode 100644
index 00000000000..a8c9678405b
--- /dev/null
+++ b/changelogs/unreleased/fj-fix-snippet-import-from-database.yml
@@ -0,0 +1,5 @@
+---
+title: Fix snippet repository import edge cases
+merge_request: 33506
+author:
+type: fixed
diff --git a/changelogs/unreleased/fj-fix-snippet-import-when-fails.yml b/changelogs/unreleased/fj-fix-snippet-import-when-fails.yml
new file mode 100644
index 00000000000..d040ee3fccd
--- /dev/null
+++ b/changelogs/unreleased/fj-fix-snippet-import-when-fails.yml
@@ -0,0 +1,5 @@
+---
+title: Remove non migrated snippets from failed imports
+merge_request: 33621
+author:
+type: fixed
diff --git a/changelogs/unreleased/followup-leakyconst-master-check.yml b/changelogs/unreleased/followup-leakyconst-master-check.yml
new file mode 100644
index 00000000000..3c0e00510f1
--- /dev/null
+++ b/changelogs/unreleased/followup-leakyconst-master-check.yml
@@ -0,0 +1,5 @@
+---
+title: Move NoPrimary table def to last context in spec
+merge_request: 33015
+author: Rajendra Kadam
+type: other
diff --git a/changelogs/unreleased/fox-comment-icons-commits.yml b/changelogs/unreleased/fox-comment-icons-commits.yml
new file mode 100644
index 00000000000..9eb198629ae
--- /dev/null
+++ b/changelogs/unreleased/fox-comment-icons-commits.yml
@@ -0,0 +1,5 @@
+---
+title: Use sprites for comment icons on Commits
+merge_request: 31696
+author:
+type: changed
diff --git a/changelogs/unreleased/georgekoltsov-import-export-tmp-folder-cleanup.yml b/changelogs/unreleased/georgekoltsov-import-export-tmp-folder-cleanup.yml
new file mode 100644
index 00000000000..d79f751a48f
--- /dev/null
+++ b/changelogs/unreleased/georgekoltsov-import-export-tmp-folder-cleanup.yml
@@ -0,0 +1,5 @@
+---
+title: Clean up shared/tmp folder after Import/Export
+merge_request: 32326
+author:
+type: fixed
diff --git a/changelogs/unreleased/gitaly-version-v13.1.0-rc1.yml b/changelogs/unreleased/gitaly-version-v13.1.0-rc1.yml
new file mode 100644
index 00000000000..8c2ea5800a5
--- /dev/null
+++ b/changelogs/unreleased/gitaly-version-v13.1.0-rc1.yml
@@ -0,0 +1,5 @@
+---
+title: Upgrade to Gitaly v13.1.0-rc1
+merge_request: 33302
+author:
+type: changed
diff --git a/changelogs/unreleased/gitlab-ui-badge-integration-2.yml b/changelogs/unreleased/gitlab-ui-badge-integration-2.yml
new file mode 100644
index 00000000000..fef025138d5
--- /dev/null
+++ b/changelogs/unreleased/gitlab-ui-badge-integration-2.yml
@@ -0,0 +1,5 @@
+---
+title: Update the visual design of badges in some areas
+merge_request: 31646
+author:
+type: other
diff --git a/changelogs/unreleased/gl-cluster-applications-json.yml b/changelogs/unreleased/gl-cluster-applications-json.yml
new file mode 100644
index 00000000000..d27029eb769
--- /dev/null
+++ b/changelogs/unreleased/gl-cluster-applications-json.yml
@@ -0,0 +1,6 @@
+---
+title: Bump cluster-applications to 0.17.0, which updates Runner to 0.17.0 and Cilium
+ to 1.7.4
+merge_request: 32931
+author:
+type: changed
diff --git a/changelogs/unreleased/id-code-nav-500-error.yml b/changelogs/unreleased/id-code-nav-500-error.yml
new file mode 100644
index 00000000000..e88980602c3
--- /dev/null
+++ b/changelogs/unreleased/id-code-nav-500-error.yml
@@ -0,0 +1,5 @@
+---
+title: Return code navigation path for nil diff_refs
+merge_request: 33850
+author:
+type: fixed
diff --git a/changelogs/unreleased/id-code-navigation-enable-feature.yml b/changelogs/unreleased/id-code-navigation-enable-feature.yml
new file mode 100644
index 00000000000..e1f9a9c1978
--- /dev/null
+++ b/changelogs/unreleased/id-code-navigation-enable-feature.yml
@@ -0,0 +1,5 @@
+---
+title: Add native code intelligence
+merge_request: 34542
+author:
+type: added
diff --git a/changelogs/unreleased/improve_issue_labels_api.yml b/changelogs/unreleased/improve_issue_labels_api.yml
new file mode 100644
index 00000000000..e57aba6ab59
--- /dev/null
+++ b/changelogs/unreleased/improve_issue_labels_api.yml
@@ -0,0 +1,5 @@
+---
+title: Improve Add/Remove Issue Labels API
+merge_request: 31864
+author: Lee Tickett
+type: added
diff --git a/changelogs/unreleased/improve_storage_move_workflow.yml b/changelogs/unreleased/improve_storage_move_workflow.yml
new file mode 100644
index 00000000000..c5e74e07267
--- /dev/null
+++ b/changelogs/unreleased/improve_storage_move_workflow.yml
@@ -0,0 +1,5 @@
+---
+title: Add project specific repository storage API
+merge_request: 32493
+author:
+type: added
diff --git a/changelogs/unreleased/increase-events-count-for-prometheus-alerts.yml b/changelogs/unreleased/increase-events-count-for-prometheus-alerts.yml
new file mode 100644
index 00000000000..29ccc347d09
--- /dev/null
+++ b/changelogs/unreleased/increase-events-count-for-prometheus-alerts.yml
@@ -0,0 +1,5 @@
+---
+title: Increase events count for Prometheus alerts
+merge_request: 33706
+author:
+type: added
diff --git a/changelogs/unreleased/instance-variables-ui.yml b/changelogs/unreleased/instance-variables-ui.yml
new file mode 100644
index 00000000000..26d59c0fafd
--- /dev/null
+++ b/changelogs/unreleased/instance-variables-ui.yml
@@ -0,0 +1,5 @@
+---
+title: New instance-level variables UI
+merge_request: 33510
+author:
+type: added
diff --git a/changelogs/unreleased/instance_auto_devops_enabled_usage_ping.yml b/changelogs/unreleased/instance_auto_devops_enabled_usage_ping.yml
new file mode 100644
index 00000000000..22e72c5bb8f
--- /dev/null
+++ b/changelogs/unreleased/instance_auto_devops_enabled_usage_ping.yml
@@ -0,0 +1,5 @@
+---
+title: Add whether instance has Auto DevOps enabled to usage ping
+merge_request: 33811
+author:
+type: changed
diff --git a/changelogs/unreleased/issue-bulk-update.yml b/changelogs/unreleased/issue-bulk-update.yml
new file mode 100644
index 00000000000..968c16f4d25
--- /dev/null
+++ b/changelogs/unreleased/issue-bulk-update.yml
@@ -0,0 +1,5 @@
+---
+title: Allow different in bulk editing issues
+merge_request: 32734
+author:
+type: fixed
diff --git a/changelogs/unreleased/jc-pick-weighted-repository.yml b/changelogs/unreleased/jc-pick-weighted-repository.yml
new file mode 100644
index 00000000000..803741e00cc
--- /dev/null
+++ b/changelogs/unreleased/jc-pick-weighted-repository.yml
@@ -0,0 +1,5 @@
+---
+title: Pick repository storage based on weight
+merge_request: 34095
+author:
+type: changed
diff --git a/changelogs/unreleased/jc-show-all-storages.yml b/changelogs/unreleased/jc-show-all-storages.yml
new file mode 100644
index 00000000000..fac5d5bb813
--- /dev/null
+++ b/changelogs/unreleased/jc-show-all-storages.yml
@@ -0,0 +1,5 @@
+---
+title: Show all storages in settings
+merge_request: 34093
+author:
+type: fixed
diff --git a/changelogs/unreleased/jc-ui-repository-storages-weighted.yml b/changelogs/unreleased/jc-ui-repository-storages-weighted.yml
new file mode 100644
index 00000000000..eefe0012310
--- /dev/null
+++ b/changelogs/unreleased/jc-ui-repository-storages-weighted.yml
@@ -0,0 +1,5 @@
+---
+title: Add ApplicationSetting ui changes for repository_storages_weighted
+merge_request: 33096
+author:
+type: added
diff --git a/changelogs/unreleased/jc-weighted-repository-storages.yml b/changelogs/unreleased/jc-weighted-repository-storages.yml
new file mode 100644
index 00000000000..060c1a26494
--- /dev/null
+++ b/changelogs/unreleased/jc-weighted-repository-storages.yml
@@ -0,0 +1,5 @@
+---
+title: Save repository storages in application settings with weights
+merge_request: 31645
+author:
+type: added
diff --git a/changelogs/unreleased/jcunha-bump-deploy-image-to-0-17-0.yml b/changelogs/unreleased/jcunha-bump-deploy-image-to-0-17-0.yml
new file mode 100644
index 00000000000..21c60bc9871
--- /dev/null
+++ b/changelogs/unreleased/jcunha-bump-deploy-image-to-0-17-0.yml
@@ -0,0 +1,6 @@
+---
+title: Updated Auto DevOps with a fix to delete PostgreSQL PVC on environment cleanup,
+ a fix for multiline K8S_SECRET variables, updated Helm to 2.16.7 and glibc to 2.31
+merge_request: 34399
+author: verenion
+type: fixed
diff --git a/changelogs/unreleased/jdb-mutliline-comment-fe.yml b/changelogs/unreleased/jdb-mutliline-comment-fe.yml
new file mode 100644
index 00000000000..da4b6e28dd5
--- /dev/null
+++ b/changelogs/unreleased/jdb-mutliline-comment-fe.yml
@@ -0,0 +1,5 @@
+---
+title: Add frontend support for multiline comments
+merge_request: 29516
+author:
+type: added
diff --git a/changelogs/unreleased/jej-api-for-root-groups.yml b/changelogs/unreleased/jej-api-for-root-groups.yml
new file mode 100644
index 00000000000..d859273f912
--- /dev/null
+++ b/changelogs/unreleased/jej-api-for-root-groups.yml
@@ -0,0 +1,5 @@
+---
+title: Groups API has top_level_only option to exclude subgroups
+merge_request: 32870
+author:
+type: added
diff --git a/changelogs/unreleased/jh-drop_jid_null_constraint.yml b/changelogs/unreleased/jh-drop_jid_null_constraint.yml
new file mode 100644
index 00000000000..ef1637c814e
--- /dev/null
+++ b/changelogs/unreleased/jh-drop_jid_null_constraint.yml
@@ -0,0 +1,5 @@
+---
+title: Remove null constraint for JID in GroupImportState
+merge_request: 33181
+author:
+type: changed
diff --git a/changelogs/unreleased/jh-group_import_status.yml b/changelogs/unreleased/jh-group_import_status.yml
new file mode 100644
index 00000000000..9441ad39216
--- /dev/null
+++ b/changelogs/unreleased/jh-group_import_status.yml
@@ -0,0 +1,5 @@
+---
+title: Show import in progress screen for group imports
+merge_request: 31731
+author:
+type: added
diff --git a/changelogs/unreleased/jh-group_import_ui_frontend.yml b/changelogs/unreleased/jh-group_import_ui_frontend.yml
new file mode 100644
index 00000000000..e820607cc76
--- /dev/null
+++ b/changelogs/unreleased/jh-group_import_ui_frontend.yml
@@ -0,0 +1,5 @@
+---
+title: Create Group import UI for creating new Groups
+merge_request: 29271
+author:
+type: added
diff --git a/changelogs/unreleased/jh-rate_limit_project_export.yml b/changelogs/unreleased/jh-rate_limit_project_export.yml
new file mode 100644
index 00000000000..743755b1c49
--- /dev/null
+++ b/changelogs/unreleased/jh-rate_limit_project_export.yml
@@ -0,0 +1,5 @@
+---
+title: Rate limit project export by user
+merge_request: 31719
+author:
+type: changed
diff --git a/changelogs/unreleased/jira-projects-api-wrapper.yml b/changelogs/unreleased/jira-projects-api-wrapper.yml
new file mode 100644
index 00000000000..4fe86aa3f4c
--- /dev/null
+++ b/changelogs/unreleased/jira-projects-api-wrapper.yml
@@ -0,0 +1,5 @@
+---
+title: Add a GraphQL endpoint to fetch Jira projects through its REST API
+merge_request: 28190
+author:
+type: changed
diff --git a/changelogs/unreleased/jivanvl-add-snowplow-logs.yml b/changelogs/unreleased/jivanvl-add-snowplow-logs.yml
new file mode 100644
index 00000000000..bc0d3592e74
--- /dev/null
+++ b/changelogs/unreleased/jivanvl-add-snowplow-logs.yml
@@ -0,0 +1,5 @@
+---
+title: Add snowplow tracking for logs page
+merge_request: 32704
+author:
+type: other
diff --git a/changelogs/unreleased/jivanvl-make-chart-panels-focusable-keyboard.yml b/changelogs/unreleased/jivanvl-make-chart-panels-focusable-keyboard.yml
new file mode 100644
index 00000000000..99798f4c58a
--- /dev/null
+++ b/changelogs/unreleased/jivanvl-make-chart-panels-focusable-keyboard.yml
@@ -0,0 +1,5 @@
+---
+title: Focus and toggle metrics dashboard panels via keyboard
+merge_request: 28603
+author:
+type: added
diff --git a/changelogs/unreleased/kborges-github-import-rake-add-rate-limit-doc.yml b/changelogs/unreleased/kborges-github-import-rake-add-rate-limit-doc.yml
new file mode 100644
index 00000000000..5d797b0f7a1
--- /dev/null
+++ b/changelogs/unreleased/kborges-github-import-rake-add-rate-limit-doc.yml
@@ -0,0 +1,5 @@
+---
+title: Document github rate limit behavior
+merge_request: 33090
+author:
+type: other
diff --git a/changelogs/unreleased/leaky-constant-fix-11.yml b/changelogs/unreleased/leaky-constant-fix-11.yml
new file mode 100644
index 00000000000..b373491e61c
--- /dev/null
+++ b/changelogs/unreleased/leaky-constant-fix-11.yml
@@ -0,0 +1,5 @@
+---
+title: Fix leaky constant issue in commit entity spec
+merge_request: 32039
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/leaky-constant-fix-14.yml b/changelogs/unreleased/leaky-constant-fix-14.yml
new file mode 100644
index 00000000000..b124371e415
--- /dev/null
+++ b/changelogs/unreleased/leaky-constant-fix-14.yml
@@ -0,0 +1,5 @@
+---
+title: Fix leaky constant issue in task completion status spec
+merge_request: 32043
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/leaky-constant-fix-22.yml b/changelogs/unreleased/leaky-constant-fix-22.yml
new file mode 100644
index 00000000000..ebeaceee09f
--- /dev/null
+++ b/changelogs/unreleased/leaky-constant-fix-22.yml
@@ -0,0 +1,5 @@
+---
+title: Fix leaky constant issue in admin mode migration spec
+merge_request: 32074
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/leaky-constant-fix-28.yml b/changelogs/unreleased/leaky-constant-fix-28.yml
new file mode 100644
index 00000000000..d1a04a25caa
--- /dev/null
+++ b/changelogs/unreleased/leaky-constant-fix-28.yml
@@ -0,0 +1,5 @@
+---
+title: Fix leaky constant issue in sidekiq middleware server metric spec
+merge_request: 32104
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/leaky-constant-fix-29.yml b/changelogs/unreleased/leaky-constant-fix-29.yml
new file mode 100644
index 00000000000..eafa7e599c6
--- /dev/null
+++ b/changelogs/unreleased/leaky-constant-fix-29.yml
@@ -0,0 +1,5 @@
+---
+title: Fix leaky constant issue in sidekiq middleware client metric spec
+merge_request: 32108
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/leaky-constant-fix-3.yml b/changelogs/unreleased/leaky-constant-fix-3.yml
new file mode 100644
index 00000000000..3ad8fd7a15f
--- /dev/null
+++ b/changelogs/unreleased/leaky-constant-fix-3.yml
@@ -0,0 +1,5 @@
+---
+title: Add class stubs and fix leaky constant alert in query limit helper spec
+merge_request: 31949
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/leaky-constant-fix-30.yml b/changelogs/unreleased/leaky-constant-fix-30.yml
new file mode 100644
index 00000000000..f4f957d5b08
--- /dev/null
+++ b/changelogs/unreleased/leaky-constant-fix-30.yml
@@ -0,0 +1,5 @@
+---
+title: Fix leaky constant issue in path regex spec
+merge_request: 32115
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/leaky-constant-fix-32.yml b/changelogs/unreleased/leaky-constant-fix-32.yml
new file mode 100644
index 00000000000..a5c5674d5da
--- /dev/null
+++ b/changelogs/unreleased/leaky-constant-fix-32.yml
@@ -0,0 +1,5 @@
+---
+title: Fix leaky constant issue importer and cache headers spec
+merge_request: 32122
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/leaky-constant-fix-33.yml b/changelogs/unreleased/leaky-constant-fix-33.yml
new file mode 100644
index 00000000000..f53da019813
--- /dev/null
+++ b/changelogs/unreleased/leaky-constant-fix-33.yml
@@ -0,0 +1,5 @@
+---
+title: Fix leaky constant issue in relation factory spec
+merge_request: 32129
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/leaky-constant-fix-34.yml b/changelogs/unreleased/leaky-constant-fix-34.yml
new file mode 100644
index 00000000000..822b9ed0471
--- /dev/null
+++ b/changelogs/unreleased/leaky-constant-fix-34.yml
@@ -0,0 +1,5 @@
+---
+title: Fix leaky constant issue in test coverage spec
+merge_request: 32134
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/leaky-constant-fix-36.yml b/changelogs/unreleased/leaky-constant-fix-36.yml
new file mode 100644
index 00000000000..1c487a8329e
--- /dev/null
+++ b/changelogs/unreleased/leaky-constant-fix-36.yml
@@ -0,0 +1,5 @@
+---
+title: Fix leaky constant issue in diff collection spec
+merge_request: 32163
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/leaky-constant-fix-37.yml b/changelogs/unreleased/leaky-constant-fix-37.yml
new file mode 100644
index 00000000000..af986b7bb13
--- /dev/null
+++ b/changelogs/unreleased/leaky-constant-fix-37.yml
@@ -0,0 +1,5 @@
+---
+title: Fix leaky constant issue in migration helpers, with lock retries and ignored cols spec
+merge_request: 32170
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/leaky-constant-fix-38.yml b/changelogs/unreleased/leaky-constant-fix-38.yml
new file mode 100644
index 00000000000..7ed7fc71da6
--- /dev/null
+++ b/changelogs/unreleased/leaky-constant-fix-38.yml
@@ -0,0 +1,5 @@
+---
+title: Fix leaky constant issue in factory spec
+merge_request: 32174
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/leaky-constant-fix-39.yml b/changelogs/unreleased/leaky-constant-fix-39.yml
new file mode 100644
index 00000000000..13ea6ac7cb4
--- /dev/null
+++ b/changelogs/unreleased/leaky-constant-fix-39.yml
@@ -0,0 +1,5 @@
+---
+title: Fix leaky constant issue in creds factory spec
+merge_request: 32176
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/leaky-constant-fix-5.yml b/changelogs/unreleased/leaky-constant-fix-5.yml
new file mode 100644
index 00000000000..b67057fe237
--- /dev/null
+++ b/changelogs/unreleased/leaky-constant-fix-5.yml
@@ -0,0 +1,5 @@
+---
+title: Remove usage of spam constants in spec
+merge_request: 31959
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/leaky-constant-fix-9.yml b/changelogs/unreleased/leaky-constant-fix-9.yml
new file mode 100644
index 00000000000..e361c58c746
--- /dev/null
+++ b/changelogs/unreleased/leaky-constant-fix-9.yml
@@ -0,0 +1,5 @@
+---
+title: Fix leaky constant issue in uninstall progress service check
+merge_request: 32036
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/lm-change-sorting.yml b/changelogs/unreleased/lm-change-sorting.yml
new file mode 100644
index 00000000000..d061995cb48
--- /dev/null
+++ b/changelogs/unreleased/lm-change-sorting.yml
@@ -0,0 +1,5 @@
+---
+title: 'Alert Managament: Change sorting order to have newest alerts first'
+merge_request: 33642
+author:
+type: changed
diff --git a/changelogs/unreleased/lm-hover-state-sort.yml b/changelogs/unreleased/lm-hover-state-sort.yml
new file mode 100644
index 00000000000..4a701511787
--- /dev/null
+++ b/changelogs/unreleased/lm-hover-state-sort.yml
@@ -0,0 +1,5 @@
+---
+title: Add hovering icon for sorting columns on alert management list
+merge_request: 33429
+author:
+type: other
diff --git a/changelogs/unreleased/lm-sorting-list.yml b/changelogs/unreleased/lm-sorting-list.yml
new file mode 100644
index 00000000000..e1a9dceec5c
--- /dev/null
+++ b/changelogs/unreleased/lm-sorting-list.yml
@@ -0,0 +1,5 @@
+---
+title: Adds sorting by column to alert management list
+merge_request: 32478
+author:
+type: added
diff --git a/changelogs/unreleased/long-path-mr-bug.yml b/changelogs/unreleased/long-path-mr-bug.yml
new file mode 100644
index 00000000000..ab171f3da5d
--- /dev/null
+++ b/changelogs/unreleased/long-path-mr-bug.yml
@@ -0,0 +1,5 @@
+---
+title: Fix rendering of very long paths in merge request file tree
+merge_request: 34153
+author:
+type: fixed
diff --git a/changelogs/unreleased/markdown-toolbar-list-style.yml b/changelogs/unreleased/markdown-toolbar-list-style.yml
new file mode 100644
index 00000000000..4121af3e744
--- /dev/null
+++ b/changelogs/unreleased/markdown-toolbar-list-style.yml
@@ -0,0 +1,5 @@
+---
+title: Set markdown toolbar to use hyphens for lists
+merge_request: 31426
+author:
+type: changed
diff --git a/changelogs/unreleased/mattkasa-207510-terraform-state-usage-ping.yml b/changelogs/unreleased/mattkasa-207510-terraform-state-usage-ping.yml
new file mode 100644
index 00000000000..9d047e66b4b
--- /dev/null
+++ b/changelogs/unreleased/mattkasa-207510-terraform-state-usage-ping.yml
@@ -0,0 +1,5 @@
+---
+title: Add usage data metrics for terraform states
+merge_request: 31280
+author:
+type: added
diff --git a/changelogs/unreleased/mattkasa-207532-add-usage-ping-for-terraform-reports.yml b/changelogs/unreleased/mattkasa-207532-add-usage-ping-for-terraform-reports.yml
new file mode 100644
index 00000000000..8656f398610
--- /dev/null
+++ b/changelogs/unreleased/mattkasa-207532-add-usage-ping-for-terraform-reports.yml
@@ -0,0 +1,5 @@
+---
+title: Add usage data metrics for terraform reports
+merge_request: 31281
+author:
+type: added
diff --git a/changelogs/unreleased/mg-fix-katex-fonts.yml b/changelogs/unreleased/mg-fix-katex-fonts.yml
new file mode 100644
index 00000000000..71acf5ca351
--- /dev/null
+++ b/changelogs/unreleased/mg-fix-katex-fonts.yml
@@ -0,0 +1,5 @@
+---
+title: Fix KaTeX font paths
+merge_request: 33338
+author:
+type: fixed
diff --git a/changelogs/unreleased/mo-add-build-report-result.yml b/changelogs/unreleased/mo-add-build-report-result.yml
new file mode 100644
index 00000000000..4b24a194500
--- /dev/null
+++ b/changelogs/unreleased/mo-add-build-report-result.yml
@@ -0,0 +1,5 @@
+---
+title: Add build report results data model
+merge_request: 32991
+author:
+type: performance
diff --git a/changelogs/unreleased/move_migration_to_post_deployment.yml b/changelogs/unreleased/move_migration_to_post_deployment.yml
new file mode 100644
index 00000000000..d70ab5249c4
--- /dev/null
+++ b/changelogs/unreleased/move_migration_to_post_deployment.yml
@@ -0,0 +1,5 @@
+---
+title: Move migration related to ci_builds to post_deployment
+merge_request: 33416
+author:
+type: performance
diff --git a/changelogs/unreleased/mwaw-210289-add-metrics-dashboard-validation-to-grapql.yml b/changelogs/unreleased/mwaw-210289-add-metrics-dashboard-validation-to-grapql.yml
new file mode 100644
index 00000000000..675f08ffe27
--- /dev/null
+++ b/changelogs/unreleased/mwaw-210289-add-metrics-dashboard-validation-to-grapql.yml
@@ -0,0 +1,5 @@
+---
+title: Add dashboard schema validation warnings as metrics dashboard GraphQL field
+merge_request: 33592
+author:
+type: added
diff --git a/changelogs/unreleased/mwaw-210289-metrics-dashboard-file-validation-mvc-1.yml b/changelogs/unreleased/mwaw-210289-metrics-dashboard-file-validation-mvc-1.yml
new file mode 100644
index 00000000000..7c07e780906
--- /dev/null
+++ b/changelogs/unreleased/mwaw-210289-metrics-dashboard-file-validation-mvc-1.yml
@@ -0,0 +1,5 @@
+---
+title: Added validation for YAML files with metrics dashboard definitions.
+merge_request: 33202
+author:
+type: added
diff --git a/changelogs/unreleased/mwaw-211433-metrics-dashboard-annotations-reaper-job-database-layer.yml b/changelogs/unreleased/mwaw-211433-metrics-dashboard-annotations-reaper-job-database-layer.yml
new file mode 100644
index 00000000000..454f6aab8e9
--- /dev/null
+++ b/changelogs/unreleased/mwaw-211433-metrics-dashboard-annotations-reaper-job-database-layer.yml
@@ -0,0 +1,6 @@
+---
+title: Table index added to `metrics_dashboard_annotations` for future pruning of stale metrics
+ Annotations for metrics dashboards are now checked for valid start and end dates.
+merge_request: 32433
+author:
+type: added
diff --git a/changelogs/unreleased/mwaw-211433-metrics-dashboard-annotations-reaper-job-worker.yml b/changelogs/unreleased/mwaw-211433-metrics-dashboard-annotations-reaper-job-worker.yml
new file mode 100644
index 00000000000..4dfeb792c5a
--- /dev/null
+++ b/changelogs/unreleased/mwaw-211433-metrics-dashboard-annotations-reaper-job-worker.yml
@@ -0,0 +1,5 @@
+---
+title: Remove metrics dashboard annotations attached to time periods older than two weeks.
+merge_request: 32838
+author:
+type: added
diff --git a/changelogs/unreleased/nfriend-enable-release_asset_link_type-f.yml b/changelogs/unreleased/nfriend-enable-release_asset_link_type-f.yml
new file mode 100644
index 00000000000..dc24c002774
--- /dev/null
+++ b/changelogs/unreleased/nfriend-enable-release_asset_link_type-f.yml
@@ -0,0 +1,5 @@
+---
+title: Allow Release asset links to be associated with a type
+merge_request: 33998
+author:
+type: added
diff --git a/changelogs/unreleased/nfriend-fix-release-button-alignment.yml b/changelogs/unreleased/nfriend-fix-release-button-alignment.yml
new file mode 100644
index 00000000000..79c6087fc54
--- /dev/null
+++ b/changelogs/unreleased/nfriend-fix-release-button-alignment.yml
@@ -0,0 +1,5 @@
+---
+title: Fix alignment of button text on the Edit Release page
+merge_request: 33104
+author:
+type: fixed
diff --git a/changelogs/unreleased/nicolasdular-broadcast-notification-close-btn.yml b/changelogs/unreleased/nicolasdular-broadcast-notification-close-btn.yml
new file mode 100644
index 00000000000..f7eb40584af
--- /dev/null
+++ b/changelogs/unreleased/nicolasdular-broadcast-notification-close-btn.yml
@@ -0,0 +1,5 @@
+---
+title: Move broadcast notification dismiss button to the top
+merge_request: 33174
+author:
+type: changed
diff --git a/changelogs/unreleased/notes-ee-feature.yml b/changelogs/unreleased/notes-ee-feature.yml
new file mode 100644
index 00000000000..38d9471ce39
--- /dev/null
+++ b/changelogs/unreleased/notes-ee-feature.yml
@@ -0,0 +1,5 @@
+---
+title: Move Admin note feature to GitLab Core
+merge_request: 31457
+author: Rajendra
+type: added
diff --git a/changelogs/unreleased/ntepluhina-fix-note-scrolling.yml b/changelogs/unreleased/ntepluhina-fix-note-scrolling.yml
new file mode 100644
index 00000000000..8bd0a746504
--- /dev/null
+++ b/changelogs/unreleased/ntepluhina-fix-note-scrolling.yml
@@ -0,0 +1,5 @@
+---
+title: Fix design note scrolling
+merge_request: 33939
+author:
+type: fixed
diff --git a/changelogs/unreleased/optimize-milestones-page.yml b/changelogs/unreleased/optimize-milestones-page.yml
new file mode 100644
index 00000000000..dd067c08faf
--- /dev/null
+++ b/changelogs/unreleased/optimize-milestones-page.yml
@@ -0,0 +1,5 @@
+---
+title: Optimize SQL queries on Milestone index page
+merge_request: 32953
+author:
+type: performance
diff --git a/changelogs/unreleased/osw-add-redis-metrics-to-sidekiq-job-run.yml b/changelogs/unreleased/osw-add-redis-metrics-to-sidekiq-job-run.yml
new file mode 100644
index 00000000000..88efab2233c
--- /dev/null
+++ b/changelogs/unreleased/osw-add-redis-metrics-to-sidekiq-job-run.yml
@@ -0,0 +1,5 @@
+---
+title: Add metrics for Redis usage during Sidekiq job execution
+merge_request: 32265
+author:
+type: added
diff --git a/changelogs/unreleased/osw-add-redis-metrics-to-web-requests.yml b/changelogs/unreleased/osw-add-redis-metrics-to-web-requests.yml
new file mode 100644
index 00000000000..77602f9a31c
--- /dev/null
+++ b/changelogs/unreleased/osw-add-redis-metrics-to-web-requests.yml
@@ -0,0 +1,5 @@
+---
+title: Add metrics for Redis usage during web requests
+merge_request: 32605
+author:
+type: added
diff --git a/changelogs/unreleased/osw-pass-state-id-instead-state-to-background-migration.yml b/changelogs/unreleased/osw-pass-state-id-instead-state-to-background-migration.yml
new file mode 100644
index 00000000000..27e673437e7
--- /dev/null
+++ b/changelogs/unreleased/osw-pass-state-id-instead-state-to-background-migration.yml
@@ -0,0 +1,5 @@
+---
+title: Adjust wrong column reference for ResetMergeStatus (background job)
+merge_request: 33899
+author:
+type: fixed
diff --git a/changelogs/unreleased/osw-separate-redis-logs.yml b/changelogs/unreleased/osw-separate-redis-logs.yml
new file mode 100644
index 00000000000..dbef2557df7
--- /dev/null
+++ b/changelogs/unreleased/osw-separate-redis-logs.yml
@@ -0,0 +1,6 @@
+---
+title: Add detailed logs of each Redis instance usage during job execution and web
+ requests
+merge_request: 34110
+author:
+type: added
diff --git a/changelogs/unreleased/perf-use-build-stubbed.yml b/changelogs/unreleased/perf-use-build-stubbed.yml
new file mode 100644
index 00000000000..0f78d8649df
--- /dev/null
+++ b/changelogs/unreleased/perf-use-build-stubbed.yml
@@ -0,0 +1,5 @@
+---
+title: Use build_stubbed to avoid interacting with the DB in todos helper specs
+merge_request: 32906
+author: Arun Kumar Mohan
+type: performance
diff --git a/changelogs/unreleased/ph-28154-moveFrontendBatchCommentsFiles.yml b/changelogs/unreleased/ph-28154-moveFrontendBatchCommentsFiles.yml
new file mode 100644
index 00000000000..9deb3e23517
--- /dev/null
+++ b/changelogs/unreleased/ph-28154-moveFrontendBatchCommentsFiles.yml
@@ -0,0 +1,5 @@
+---
+title: Moves merge request reviews into Core
+merge_request: 32558
+author:
+type: other
diff --git a/changelogs/unreleased/pl-alert-management-fix-multiple-issue-creation.yml b/changelogs/unreleased/pl-alert-management-fix-multiple-issue-creation.yml
new file mode 100644
index 00000000000..a4837dd7df8
--- /dev/null
+++ b/changelogs/unreleased/pl-alert-management-fix-multiple-issue-creation.yml
@@ -0,0 +1,5 @@
+---
+title: Fix linking alerts to created issues for the Generic alerts intergration
+merge_request: 33647
+author:
+type: fixed
diff --git a/changelogs/unreleased/psi-dark-theme.yml b/changelogs/unreleased/psi-dark-theme.yml
new file mode 100644
index 00000000000..21257280afb
--- /dev/null
+++ b/changelogs/unreleased/psi-dark-theme.yml
@@ -0,0 +1,5 @@
+---
+title: Add dark theme (alpha)
+merge_request: 28252
+author:
+type: added
diff --git a/changelogs/unreleased/rails-logger-cop-1.yml b/changelogs/unreleased/rails-logger-cop-1.yml
new file mode 100644
index 00000000000..c9b37eb9244
--- /dev/null
+++ b/changelogs/unreleased/rails-logger-cop-1.yml
@@ -0,0 +1,5 @@
+---
+title: Use applogger in project import state file
+merge_request: 32182
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/rails-logger-cop-10.yml b/changelogs/unreleased/rails-logger-cop-10.yml
new file mode 100644
index 00000000000..c81a504350c
--- /dev/null
+++ b/changelogs/unreleased/rails-logger-cop-10.yml
@@ -0,0 +1,5 @@
+---
+title: Use applogger in exclusive_lease_guard
+merge_request: 32194
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/rails-logger-cop-11.yml b/changelogs/unreleased/rails-logger-cop-11.yml
new file mode 100644
index 00000000000..fa337bf4658
--- /dev/null
+++ b/changelogs/unreleased/rails-logger-cop-11.yml
@@ -0,0 +1,5 @@
+---
+title: Use applogger in groups destroy service and label create service
+merge_request: 32195
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/rails-logger-cop-12.yml b/changelogs/unreleased/rails-logger-cop-12.yml
new file mode 100644
index 00000000000..c08f8d5426a
--- /dev/null
+++ b/changelogs/unreleased/rails-logger-cop-12.yml
@@ -0,0 +1,5 @@
+---
+title: Use applogger in merge_service.rb
+merge_request: 32196
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/rails-logger-cop-13.yml b/changelogs/unreleased/rails-logger-cop-13.yml
new file mode 100644
index 00000000000..ab0414f0ae3
--- /dev/null
+++ b/changelogs/unreleased/rails-logger-cop-13.yml
@@ -0,0 +1,5 @@
+---
+title: Use applogger in project create service and after import service
+merge_request: 32198
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/rails-logger-cop-14.yml b/changelogs/unreleased/rails-logger-cop-14.yml
new file mode 100644
index 00000000000..07f332d9d35
--- /dev/null
+++ b/changelogs/unreleased/rails-logger-cop-14.yml
@@ -0,0 +1,5 @@
+---
+title: Use applogger in update stats service
+merge_request: 32200
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/rails-logger-cop-15.yml b/changelogs/unreleased/rails-logger-cop-15.yml
new file mode 100644
index 00000000000..1c9ccafe5cb
--- /dev/null
+++ b/changelogs/unreleased/rails-logger-cop-15.yml
@@ -0,0 +1,5 @@
+---
+title: Use applogger in base attachment service
+merge_request: 32201
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/rails-logger-cop-16.yml b/changelogs/unreleased/rails-logger-cop-16.yml
new file mode 100644
index 00000000000..be60fdce4d0
--- /dev/null
+++ b/changelogs/unreleased/rails-logger-cop-16.yml
@@ -0,0 +1,5 @@
+---
+title: Use applogger in export service
+merge_request: 32203
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/rails-logger-cop-17.yml b/changelogs/unreleased/rails-logger-cop-17.yml
new file mode 100644
index 00000000000..013457961cf
--- /dev/null
+++ b/changelogs/unreleased/rails-logger-cop-17.yml
@@ -0,0 +1,5 @@
+---
+title: Use applogger in akismet service
+merge_request: 32205
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/rails-logger-cop-18.yml b/changelogs/unreleased/rails-logger-cop-18.yml
new file mode 100644
index 00000000000..d5ebd1b4a11
--- /dev/null
+++ b/changelogs/unreleased/rails-logger-cop-18.yml
@@ -0,0 +1,5 @@
+---
+title: Use applogger in file mover file
+merge_request: 32206
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/rails-logger-cop-19.yml b/changelogs/unreleased/rails-logger-cop-19.yml
new file mode 100644
index 00000000000..b56f06caf73
--- /dev/null
+++ b/changelogs/unreleased/rails-logger-cop-19.yml
@@ -0,0 +1,5 @@
+---
+title: Use applogger in commit signature worker
+merge_request: 32207
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/rails-logger-cop-2.yml b/changelogs/unreleased/rails-logger-cop-2.yml
new file mode 100644
index 00000000000..0685f503e44
--- /dev/null
+++ b/changelogs/unreleased/rails-logger-cop-2.yml
@@ -0,0 +1,5 @@
+---
+title: Use applogger in project.rb
+merge_request: 32183
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/rails-logger-cop-20.yml b/changelogs/unreleased/rails-logger-cop-20.yml
new file mode 100644
index 00000000000..1128b8022e3
--- /dev/null
+++ b/changelogs/unreleased/rails-logger-cop-20.yml
@@ -0,0 +1,5 @@
+---
+title: Use applogger in delete user worker
+merge_request: 32209
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/rails-logger-cop-21.yml b/changelogs/unreleased/rails-logger-cop-21.yml
new file mode 100644
index 00000000000..099142ff482
--- /dev/null
+++ b/changelogs/unreleased/rails-logger-cop-21.yml
@@ -0,0 +1,5 @@
+---
+title: Use applogger in email receiver worker
+merge_request: 32211
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/rails-logger-cop-22.yml b/changelogs/unreleased/rails-logger-cop-22.yml
new file mode 100644
index 00000000000..df22074b16a
--- /dev/null
+++ b/changelogs/unreleased/rails-logger-cop-22.yml
@@ -0,0 +1,5 @@
+---
+title: Use applogger in artifact worker
+merge_request: 32212
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/rails-logger-cop-23.yml b/changelogs/unreleased/rails-logger-cop-23.yml
new file mode 100644
index 00000000000..4e7513570e9
--- /dev/null
+++ b/changelogs/unreleased/rails-logger-cop-23.yml
@@ -0,0 +1,5 @@
+---
+title: Use applogger in new note worker
+merge_request: 32213
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/rails-logger-cop-3.yml b/changelogs/unreleased/rails-logger-cop-3.yml
new file mode 100644
index 00000000000..b7de674cdb6
--- /dev/null
+++ b/changelogs/unreleased/rails-logger-cop-3.yml
@@ -0,0 +1,5 @@
+---
+title: Use applogger in chat_team.rb
+merge_request: 32184
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/rails-logger-cop-4.yml b/changelogs/unreleased/rails-logger-cop-4.yml
new file mode 100644
index 00000000000..a7f76711de7
--- /dev/null
+++ b/changelogs/unreleased/rails-logger-cop-4.yml
@@ -0,0 +1,5 @@
+---
+title: Use applogger in repository model
+merge_request: 32185
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/rails-logger-cop-5.yml b/changelogs/unreleased/rails-logger-cop-5.yml
new file mode 100644
index 00000000000..4e758bde275
--- /dev/null
+++ b/changelogs/unreleased/rails-logger-cop-5.yml
@@ -0,0 +1,5 @@
+---
+title: Use applogger in build and ssh host key
+merge_request: 32187
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/rails-logger-cop-6.yml b/changelogs/unreleased/rails-logger-cop-6.yml
new file mode 100644
index 00000000000..a5fea225b08
--- /dev/null
+++ b/changelogs/unreleased/rails-logger-cop-6.yml
@@ -0,0 +1,5 @@
+---
+title: Use applogger in cache attrs and highest role ruby files
+merge_request: 32189
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/rails-logger-cop-7.yml b/changelogs/unreleased/rails-logger-cop-7.yml
new file mode 100644
index 00000000000..b8482ccef54
--- /dev/null
+++ b/changelogs/unreleased/rails-logger-cop-7.yml
@@ -0,0 +1,5 @@
+---
+title: Use applogger in legacy project and namespace
+merge_request: 32190
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/rails-logger-cop-8.yml b/changelogs/unreleased/rails-logger-cop-8.yml
new file mode 100644
index 00000000000..4765c087bb7
--- /dev/null
+++ b/changelogs/unreleased/rails-logger-cop-8.yml
@@ -0,0 +1,5 @@
+---
+title: Use applogger in base.rb
+merge_request: 32191
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/rails-logger-cop-9.yml b/changelogs/unreleased/rails-logger-cop-9.yml
new file mode 100644
index 00000000000..8e740f6f1bd
--- /dev/null
+++ b/changelogs/unreleased/rails-logger-cop-9.yml
@@ -0,0 +1,5 @@
+---
+title: Use applogger in usage ping and webhook service
+merge_request: 32192
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/rc-add_dashboard_timezone.yml b/changelogs/unreleased/rc-add_dashboard_timezone.yml
new file mode 100644
index 00000000000..190d3faadec
--- /dev/null
+++ b/changelogs/unreleased/rc-add_dashboard_timezone.yml
@@ -0,0 +1,5 @@
+---
+title: Add column dashboard_timezone to project_metrics_setting
+merge_request: 33120
+author:
+type: added
diff --git a/changelogs/unreleased/rearchitect-fixed-pipelines-notification-v2.yml b/changelogs/unreleased/rearchitect-fixed-pipelines-notification-v2.yml
new file mode 100644
index 00000000000..6f65d844a7a
--- /dev/null
+++ b/changelogs/unreleased/rearchitect-fixed-pipelines-notification-v2.yml
@@ -0,0 +1,5 @@
+---
+title: Make Fixed Email Notification Generally Available
+merge_request: 28338
+author: jacopo-beschi
+type: added
diff --git a/changelogs/unreleased/reduce-repo-size.yml b/changelogs/unreleased/reduce-repo-size.yml
new file mode 100644
index 00000000000..8483cc0a705
--- /dev/null
+++ b/changelogs/unreleased/reduce-repo-size.yml
@@ -0,0 +1,5 @@
+---
+title: Add support for `git filter-repo` to repository cleanup
+merge_request: 33576
+author:
+type: added
diff --git a/changelogs/unreleased/refactor-stuck-imports-jobs-worker.yml b/changelogs/unreleased/refactor-stuck-imports-jobs-worker.yml
new file mode 100644
index 00000000000..72508bd724c
--- /dev/null
+++ b/changelogs/unreleased/refactor-stuck-imports-jobs-worker.yml
@@ -0,0 +1,5 @@
+---
+title: Process stuck jira import jobs
+merge_request: 32643
+author:
+type: added
diff --git a/changelogs/unreleased/remove-a11y-widget-ff.yml b/changelogs/unreleased/remove-a11y-widget-ff.yml
new file mode 100644
index 00000000000..0f99d7a1e93
--- /dev/null
+++ b/changelogs/unreleased/remove-a11y-widget-ff.yml
@@ -0,0 +1,5 @@
+---
+title: Add accessibility report MR widget
+merge_request: 32902
+author:
+type: added
diff --git a/changelogs/unreleased/remove-redundant-modsecurity-indexes.yml b/changelogs/unreleased/remove-redundant-modsecurity-indexes.yml
new file mode 100644
index 00000000000..41a1759281d
--- /dev/null
+++ b/changelogs/unreleased/remove-redundant-modsecurity-indexes.yml
@@ -0,0 +1,5 @@
+---
+title: Remove unused WAF indexes from CI variables
+merge_request: 30021
+author:
+type: other
diff --git a/changelogs/unreleased/remove_scoped_approval_rules_feature_flag.yml b/changelogs/unreleased/remove_scoped_approval_rules_feature_flag.yml
new file mode 100644
index 00000000000..f577053d074
--- /dev/null
+++ b/changelogs/unreleased/remove_scoped_approval_rules_feature_flag.yml
@@ -0,0 +1,5 @@
+---
+title: Remove `scoped_approval_rules` feature flag
+merge_request: 28864
+author: Lee Tickett
+type: added
diff --git a/changelogs/unreleased/replace-slot-for-vue-3-migration.yml b/changelogs/unreleased/replace-slot-for-vue-3-migration.yml
new file mode 100644
index 00000000000..c2f1e2a4697
--- /dev/null
+++ b/changelogs/unreleased/replace-slot-for-vue-3-migration.yml
@@ -0,0 +1,5 @@
+---
+title: Replace slot syntax for Vue 3 migration
+merge_request: 31987
+author: gaslan
+type: other
diff --git a/changelogs/unreleased/reword-addMultipleToDiscussionWarning.yml b/changelogs/unreleased/reword-addMultipleToDiscussionWarning.yml
new file mode 100644
index 00000000000..47e984576c5
--- /dev/null
+++ b/changelogs/unreleased/reword-addMultipleToDiscussionWarning.yml
@@ -0,0 +1,5 @@
+---
+title: Update wording of addMultipleToDiscussionWarning
+merge_request: 34088
+author:
+type: fixed
diff --git a/changelogs/unreleased/rf-brakeman-to-core.yml b/changelogs/unreleased/rf-brakeman-to-core.yml
new file mode 100644
index 00000000000..3f2d4536815
--- /dev/null
+++ b/changelogs/unreleased/rf-brakeman-to-core.yml
@@ -0,0 +1,5 @@
+---
+title: Bring SAST to Core - brakeman
+merge_request: 34217
+author:
+type: added
diff --git a/changelogs/unreleased/rp-use-gitlab-yaml-loader-blob-viewer.yml b/changelogs/unreleased/rp-use-gitlab-yaml-loader-blob-viewer.yml
new file mode 100644
index 00000000000..e9ecbc0cd66
--- /dev/null
+++ b/changelogs/unreleased/rp-use-gitlab-yaml-loader-blob-viewer.yml
@@ -0,0 +1,5 @@
+---
+title: Display error for YAML files that are too large
+merge_request: 34199
+author:
+type: changed
diff --git a/changelogs/unreleased/rspec-rails-fast-failure-template.yml b/changelogs/unreleased/rspec-rails-fast-failure-template.yml
new file mode 100644
index 00000000000..c466c68075a
--- /dev/null
+++ b/changelogs/unreleased/rspec-rails-fast-failure-template.yml
@@ -0,0 +1,5 @@
+---
+title: Add Verify/FailFast CI template
+merge_request: 31812
+author:
+type: added
diff --git a/changelogs/unreleased/sav-1566-pat-for-projects-db-changes.yml b/changelogs/unreleased/sav-1566-pat-for-projects-db-changes.yml
new file mode 100644
index 00000000000..50a32041395
--- /dev/null
+++ b/changelogs/unreleased/sav-1566-pat-for-projects-db-changes.yml
@@ -0,0 +1,5 @@
+---
+title: Add ProjectAccessToken table
+merge_request: 33272
+author:
+type: added
diff --git a/changelogs/unreleased/schedule_storage_move_api.yml b/changelogs/unreleased/schedule_storage_move_api.yml
new file mode 100644
index 00000000000..8c205aade84
--- /dev/null
+++ b/changelogs/unreleased/schedule_storage_move_api.yml
@@ -0,0 +1,5 @@
+---
+title: Add API to schedule project repository storage moves
+merge_request: 34119
+author:
+type: added
diff --git a/changelogs/unreleased/services-usage-1.yml b/changelogs/unreleased/services-usage-1.yml
new file mode 100644
index 00000000000..d202273ca8c
--- /dev/null
+++ b/changelogs/unreleased/services-usage-1.yml
@@ -0,0 +1,5 @@
+---
+title: Record audit event when an admin creates a new SSH Key for a user via the API
+merge_request: 33859
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/services-usage-2.yml b/changelogs/unreleased/services-usage-2.yml
new file mode 100644
index 00000000000..8cc4e96d520
--- /dev/null
+++ b/changelogs/unreleased/services-usage-2.yml
@@ -0,0 +1,5 @@
+---
+title: Use Keys::DestroyService for deleting an SSH key when an admin deletes a key via the API
+merge_request: 34535
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/sh-add-partial-index-locked-merge-requests.yml b/changelogs/unreleased/sh-add-partial-index-locked-merge-requests.yml
new file mode 100644
index 00000000000..bfeadcfded5
--- /dev/null
+++ b/changelogs/unreleased/sh-add-partial-index-locked-merge-requests.yml
@@ -0,0 +1,5 @@
+---
+title: Add partial index on locked merge requets
+merge_request: 34127
+author:
+type: performance
diff --git a/changelogs/unreleased/sh-avoid-extra-route-reload.yml b/changelogs/unreleased/sh-avoid-extra-route-reload.yml
new file mode 100644
index 00000000000..7c363ac92d8
--- /dev/null
+++ b/changelogs/unreleased/sh-avoid-extra-route-reload.yml
@@ -0,0 +1,5 @@
+---
+title: Speed up boot time in production
+merge_request: 33929
+author:
+type: performance
diff --git a/changelogs/unreleased/sh-extend-remember-me-token.yml b/changelogs/unreleased/sh-extend-remember-me-token.yml
new file mode 100644
index 00000000000..ddee3f8be7e
--- /dev/null
+++ b/changelogs/unreleased/sh-extend-remember-me-token.yml
@@ -0,0 +1,5 @@
+---
+title: Extend "Remember me" token after each login
+merge_request: 32730
+author:
+type: other
diff --git a/changelogs/unreleased/sh-fix-auto-merge-after-resolve-discussions.yml b/changelogs/unreleased/sh-fix-auto-merge-after-resolve-discussions.yml
new file mode 100644
index 00000000000..c4aa8d22ca3
--- /dev/null
+++ b/changelogs/unreleased/sh-fix-auto-merge-after-resolve-discussions.yml
@@ -0,0 +1,5 @@
+---
+title: Fix auto-merge not running after discussions resolved
+merge_request: 33371
+author:
+type: fixed
diff --git a/changelogs/unreleased/sh-fix-delete-blob-failure.yml b/changelogs/unreleased/sh-fix-delete-blob-failure.yml
new file mode 100644
index 00000000000..ec3a48a09f2
--- /dev/null
+++ b/changelogs/unreleased/sh-fix-delete-blob-failure.yml
@@ -0,0 +1,5 @@
+---
+title: Fix 500 error in BlobController#delete
+merge_request: 34367
+author:
+type: fixed
diff --git a/changelogs/unreleased/sh-fix-issue-219991.yml b/changelogs/unreleased/sh-fix-issue-219991.yml
new file mode 100644
index 00000000000..f09cb34b761
--- /dev/null
+++ b/changelogs/unreleased/sh-fix-issue-219991.yml
@@ -0,0 +1,5 @@
+---
+title: Fix force_remove_source_branch not working in API
+merge_request: 33804
+author:
+type: fixed
diff --git a/changelogs/unreleased/sh-update-workhorse-8-34-0.yml b/changelogs/unreleased/sh-update-workhorse-8-34-0.yml
new file mode 100644
index 00000000000..5ecb3840463
--- /dev/null
+++ b/changelogs/unreleased/sh-update-workhorse-8-34-0.yml
@@ -0,0 +1,5 @@
+---
+title: Update GitLab Workhorse to v8.34.0
+merge_request: 33543
+author:
+type: fixed
diff --git a/changelogs/unreleased/sh-workhorse-direct-access-upload.yml b/changelogs/unreleased/sh-workhorse-direct-access-upload.yml
new file mode 100644
index 00000000000..41aee482891
--- /dev/null
+++ b/changelogs/unreleased/sh-workhorse-direct-access-upload.yml
@@ -0,0 +1,5 @@
+---
+title: Support Workhorse directly uploading files to S3
+merge_request: 29389
+author:
+type: added
diff --git a/changelogs/unreleased/show-redis-instance-in-performance-bar.yml b/changelogs/unreleased/show-redis-instance-in-performance-bar.yml
new file mode 100644
index 00000000000..80dbd33f110
--- /dev/null
+++ b/changelogs/unreleased/show-redis-instance-in-performance-bar.yml
@@ -0,0 +1,5 @@
+---
+title: Show Redis instance in performance bar
+merge_request: 34377
+author:
+type: changed
diff --git a/changelogs/unreleased/show_build_status_in_branch_list.yml b/changelogs/unreleased/show_build_status_in_branch_list.yml
new file mode 100644
index 00000000000..259b916af10
--- /dev/null
+++ b/changelogs/unreleased/show_build_status_in_branch_list.yml
@@ -0,0 +1,5 @@
+---
+title: Show build status on branch list
+merge_request: 30948
+author: Lee Tickett
+type: added
diff --git a/changelogs/unreleased/show_estimate_on_issues_list.yml b/changelogs/unreleased/show_estimate_on_issues_list.yml
new file mode 100644
index 00000000000..9845fcc2f57
--- /dev/null
+++ b/changelogs/unreleased/show_estimate_on_issues_list.yml
@@ -0,0 +1,5 @@
+---
+title: Show estimate on issues list
+merge_request: 28271
+author: Lee Tickett
+type: added
diff --git a/changelogs/unreleased/sidekiq-arguments-logging-tokens.yml b/changelogs/unreleased/sidekiq-arguments-logging-tokens.yml
new file mode 100644
index 00000000000..143a85b2986
--- /dev/null
+++ b/changelogs/unreleased/sidekiq-arguments-logging-tokens.yml
@@ -0,0 +1,5 @@
+---
+title: Filter potentially-sensitive Sidekiq arguments from logs and Sentry
+merge_request: 33967
+author:
+type: changed
diff --git a/changelogs/unreleased/skip-importing-failed-jira-issue-instead-of-entrire-batch.yml b/changelogs/unreleased/skip-importing-failed-jira-issue-instead-of-entrire-batch.yml
new file mode 100644
index 00000000000..89e4261c40d
--- /dev/null
+++ b/changelogs/unreleased/skip-importing-failed-jira-issue-instead-of-entrire-batch.yml
@@ -0,0 +1,5 @@
+---
+title: Skip the individual JIRA issues if failed to import vs failing the whole batch
+merge_request: 32673
+author:
+type: fixed
diff --git a/changelogs/unreleased/support-grafana-links-in-metrics-dashboard.yml b/changelogs/unreleased/support-grafana-links-in-metrics-dashboard.yml
new file mode 100644
index 00000000000..cbbce1b2b34
--- /dev/null
+++ b/changelogs/unreleased/support-grafana-links-in-metrics-dashboard.yml
@@ -0,0 +1,5 @@
+---
+title: Support user-defined Grafana links in metrics dashboard
+merge_request: 34003
+author:
+type: added
diff --git a/changelogs/unreleased/switch-diff-view-fix.yml b/changelogs/unreleased/switch-diff-view-fix.yml
new file mode 100644
index 00000000000..ff3e1e11e49
--- /dev/null
+++ b/changelogs/unreleased/switch-diff-view-fix.yml
@@ -0,0 +1,6 @@
+---
+title: Deduplicate URL parameters when requesting merge request diffs which causes
+ diffs load to fail
+merge_request: 33117
+author:
+type: fixed
diff --git a/changelogs/unreleased/sy-publish-command.yml b/changelogs/unreleased/sy-publish-command.yml
new file mode 100644
index 00000000000..cfc46e8f1c1
--- /dev/null
+++ b/changelogs/unreleased/sy-publish-command.yml
@@ -0,0 +1,6 @@
+---
+title: Backfill StatusPage::Published incidents and enable a publish quick action
+ for EE
+merge_request: 30906
+author:
+type: added
diff --git a/changelogs/unreleased/sy-publish-status-ui-fe.yml b/changelogs/unreleased/sy-publish-status-ui-fe.yml
new file mode 100644
index 00000000000..f0de124efb1
--- /dev/null
+++ b/changelogs/unreleased/sy-publish-status-ui-fe.yml
@@ -0,0 +1,5 @@
+---
+title: Add link to status page detail view for status page published issues
+merge_request: 30249
+author:
+type: added
diff --git a/changelogs/unreleased/templates-current-folder-fix.yml b/changelogs/unreleased/templates-current-folder-fix.yml
new file mode 100644
index 00000000000..9b4999c9d54
--- /dev/null
+++ b/changelogs/unreleased/templates-current-folder-fix.yml
@@ -0,0 +1,5 @@
+---
+title: "Web IDE: Create template files in the folder from which new file request was made"
+merge_request: 33585
+author: Ashesh Vidyut
+type: fixed
diff --git a/changelogs/unreleased/tidy_put_projects_issues_spec.yml b/changelogs/unreleased/tidy_put_projects_issues_spec.yml
new file mode 100644
index 00000000000..ef0d8d1745d
--- /dev/null
+++ b/changelogs/unreleased/tidy_put_projects_issues_spec.yml
@@ -0,0 +1,5 @@
+---
+title: Tidy
+merge_request: 32759
+author: Lee Tickett
+type: other
diff --git a/changelogs/unreleased/tr-avoid-alert-refetch.yml b/changelogs/unreleased/tr-avoid-alert-refetch.yml
new file mode 100644
index 00000000000..3dafc79a366
--- /dev/null
+++ b/changelogs/unreleased/tr-avoid-alert-refetch.yml
@@ -0,0 +1,5 @@
+---
+title: Avoid refresh to show endedAt after mutation
+merge_request: 32636
+author:
+type: fixed
diff --git a/changelogs/unreleased/tr-fix-broken-incident-link.yml b/changelogs/unreleased/tr-fix-broken-incident-link.yml
new file mode 100644
index 00000000000..bea818796d0
--- /dev/null
+++ b/changelogs/unreleased/tr-fix-broken-incident-link.yml
@@ -0,0 +1,5 @@
+---
+title: Fix broken help link on operations settings page
+merge_request: 32722
+author:
+type: fixed
diff --git a/changelogs/unreleased/tr-reword-alert-service.yml b/changelogs/unreleased/tr-reword-alert-service.yml
new file mode 100644
index 00000000000..e7665822e72
--- /dev/null
+++ b/changelogs/unreleased/tr-reword-alert-service.yml
@@ -0,0 +1,5 @@
+---
+title: Add more detail to alert integration settings description
+merge_request: 33244
+author:
+type: added
diff --git a/changelogs/unreleased/track-pod-logs-refresh-action.yml b/changelogs/unreleased/track-pod-logs-refresh-action.yml
new file mode 100644
index 00000000000..a7d9021a90e
--- /dev/null
+++ b/changelogs/unreleased/track-pod-logs-refresh-action.yml
@@ -0,0 +1,5 @@
+---
+title: Track pod logs refresh action
+merge_request: 33802
+author:
+type: added
diff --git a/changelogs/unreleased/update-deprecated-slot-syntax-in---app-assets-javascripts-pages-admin-pro.yml b/changelogs/unreleased/update-deprecated-slot-syntax-in---app-assets-javascripts-pages-admin-pro.yml
new file mode 100644
index 00000000000..f4775f7db5c
--- /dev/null
+++ b/changelogs/unreleased/update-deprecated-slot-syntax-in---app-assets-javascripts-pages-admin-pro.yml
@@ -0,0 +1,5 @@
+---
+title: Update deprecated slot syntax in ./app/assets/javascripts/pages/admin/projects/index/components/delete_project_modal.vue
+merge_request: 31994
+author: Gilang Gumilar
+type: other
diff --git a/changelogs/unreleased/update-deprecated-slot-syntax-in---app-assets-javascripts-pages-projects-.yml b/changelogs/unreleased/update-deprecated-slot-syntax-in---app-assets-javascripts-pages-projects-.yml
new file mode 100644
index 00000000000..8ee3646bcd1
--- /dev/null
+++ b/changelogs/unreleased/update-deprecated-slot-syntax-in---app-assets-javascripts-pages-projects-.yml
@@ -0,0 +1,5 @@
+---
+title: Update deprecated slot syntax in ./app/assets/javascripts/pages/projects/labels/components/promote_label_modal.vue
+merge_request: 31995
+author: Gilang Gumilar
+type: other
diff --git a/changelogs/unreleased/update-deprecated-slot-syntax-in---clusters-applications-vue.yml b/changelogs/unreleased/update-deprecated-slot-syntax-in---clusters-applications-vue.yml
new file mode 100644
index 00000000000..a18b4990414
--- /dev/null
+++ b/changelogs/unreleased/update-deprecated-slot-syntax-in---clusters-applications-vue.yml
@@ -0,0 +1,5 @@
+---
+title: Update deprecated slot syntax in ./app/assets/javascripts/clusters/components/remove_cluster_confirmation.vue
+merge_request: 32010
+author: Gilang Gumilar
+type: other
diff --git a/changelogs/unreleased/update-deprecated-slot-syntax-in---javascripts-environments_app-vue.yml b/changelogs/unreleased/update-deprecated-slot-syntax-in---javascripts-environments_app-vue.yml
new file mode 100644
index 00000000000..a4f77b53937
--- /dev/null
+++ b/changelogs/unreleased/update-deprecated-slot-syntax-in---javascripts-environments_app-vue.yml
@@ -0,0 +1,5 @@
+---
+title: Update deprecated slot syntax in ./app/assets/javascripts/environments/components/environments_app.vue
+merge_request: 32011
+author: Gilang Gumilar
+type: other
diff --git a/changelogs/unreleased/update-deprecated-slot-syntax-in-app-assets-javascripts-reports-component.yml b/changelogs/unreleased/update-deprecated-slot-syntax-in-app-assets-javascripts-reports-component.yml
new file mode 100644
index 00000000000..b880020aa7f
--- /dev/null
+++ b/changelogs/unreleased/update-deprecated-slot-syntax-in-app-assets-javascripts-reports-component.yml
@@ -0,0 +1,5 @@
+---
+title: Update deprecated slot syntax in app/assets/javascripts/reports/components/grouped_test_reports_app.vue
+merge_request: 31975
+author: Gilang Gumilar
+type: other
diff --git a/changelogs/unreleased/update-gitlab-runner-helm-chart-to-0-17-0.yml b/changelogs/unreleased/update-gitlab-runner-helm-chart-to-0-17-0.yml
new file mode 100644
index 00000000000..98f8ec0c03b
--- /dev/null
+++ b/changelogs/unreleased/update-gitlab-runner-helm-chart-to-0-17-0.yml
@@ -0,0 +1,5 @@
+---
+title: Update GitLab Runner Helm Chart to 0.17.0
+merge_request: 32634
+author:
+type: other
diff --git a/changelogs/unreleased/update-gitlab-runner-helm-chart-to-0-17-1.yml b/changelogs/unreleased/update-gitlab-runner-helm-chart-to-0-17-1.yml
new file mode 100644
index 00000000000..74cf7405268
--- /dev/null
+++ b/changelogs/unreleased/update-gitlab-runner-helm-chart-to-0-17-1.yml
@@ -0,0 +1,5 @@
+---
+title: Update GitLab Runner Helm Chart to 0.17.1
+merge_request: 33504
+author:
+type: other
diff --git a/changelogs/unreleased/update-index-artifacts-expire.yml b/changelogs/unreleased/update-index-artifacts-expire.yml
new file mode 100644
index 00000000000..9eaed111aa8
--- /dev/null
+++ b/changelogs/unreleased/update-index-artifacts-expire.yml
@@ -0,0 +1,6 @@
+---
+title: Update index_ci_builds_on_commit_id_and_artifacts_expireatandidpartial index
+ for secret_detection
+merge_request: 32584
+author:
+type: performance
diff --git a/changelogs/unreleased/update-validates-hostname-gem.yml b/changelogs/unreleased/update-validates-hostname-gem.yml
new file mode 100644
index 00000000000..4665ebe2724
--- /dev/null
+++ b/changelogs/unreleased/update-validates-hostname-gem.yml
@@ -0,0 +1,5 @@
+---
+title: Update validates_hostname gem with support for more TLDs
+merge_request: 34010
+author:
+type: fixed
diff --git a/changelogs/unreleased/update-workhorse-version-master.yml b/changelogs/unreleased/update-workhorse-version-master.yml
new file mode 100644
index 00000000000..3a8aa981668
--- /dev/null
+++ b/changelogs/unreleased/update-workhorse-version-master.yml
@@ -0,0 +1,5 @@
+---
+title: Update Workhorse to v8.35.0
+merge_request: 33817
+author:
+type: other
diff --git a/changelogs/unreleased/upgrade-renamed-diff-show-full-diff-for-renamed-files.yml b/changelogs/unreleased/upgrade-renamed-diff-show-full-diff-for-renamed-files.yml
new file mode 100644
index 00000000000..3a9cc4c383a
--- /dev/null
+++ b/changelogs/unreleased/upgrade-renamed-diff-show-full-diff-for-renamed-files.yml
@@ -0,0 +1,5 @@
+---
+title: Add a link to the `renamed` viewer to fully expand the renamed file (if it's text)
+merge_request: 28448
+author:
+type: added
diff --git a/changelogs/unreleased/vs-fix-account-delete-plural-msg.yml b/changelogs/unreleased/vs-fix-account-delete-plural-msg.yml
new file mode 100644
index 00000000000..39dccc2fbde
--- /dev/null
+++ b/changelogs/unreleased/vs-fix-account-delete-plural-msg.yml
@@ -0,0 +1,5 @@
+---
+title: Fix plural message in account deletion section
+merge_request: 32868
+author:
+type: fixed
diff --git a/changelogs/unreleased/xanf-use-new-import-ui-templates.yml b/changelogs/unreleased/xanf-use-new-import-ui-templates.yml
new file mode 100644
index 00000000000..32546178546
--- /dev/null
+++ b/changelogs/unreleased/xanf-use-new-import-ui-templates.yml
@@ -0,0 +1,5 @@
+---
+title: Introduce a feature flag for Vue-based UI for all import providers
+merge_request: 33980
+author:
+type: added
diff --git a/config/application.rb b/config/application.rb
index d8f02277527..524827226e7 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -25,6 +25,7 @@ module Gitlab
require_dependency Rails.root.join('lib/gitlab/middleware/read_only')
require_dependency Rails.root.join('lib/gitlab/middleware/basic_health_check')
require_dependency Rails.root.join('lib/gitlab/middleware/same_site_cookies')
+ require_dependency Rails.root.join('lib/gitlab/middleware/handle_ip_spoof_attack_error')
require_dependency Rails.root.join('lib/gitlab/runtime')
# Settings in config/environments/* take precedence over those specified here.
@@ -163,6 +164,8 @@ module Gitlab
config.assets.paths << Gemojione.images_path
config.assets.paths << "#{config.root}/vendor/assets/fonts"
+ config.assets.precompile << "application_dark.css"
+
config.assets.precompile << "print.css"
config.assets.precompile << "mailer.css"
config.assets.precompile << "mailer_client_specific.css"
@@ -235,6 +238,8 @@ module Gitlab
config.middleware.insert_before ActionDispatch::Cookies, ::Gitlab::Middleware::SameSiteCookies
+ config.middleware.insert_before ActionDispatch::RemoteIp, ::Gitlab::Middleware::HandleIpSpoofAttackError
+
# Allow access to GitLab API from other domains
config.middleware.insert_before Warden::Manager, Rack::Cors do
headers_to_expose = %w[Link X-Total X-Total-Pages X-Per-Page X-Page X-Next-Page X-Prev-Page X-Gitlab-Blob-Id X-Gitlab-Commit-Id X-Gitlab-Content-Sha256 X-Gitlab-Encoding X-Gitlab-File-Name X-Gitlab-File-Path X-Gitlab-Last-Commit-Id X-Gitlab-Ref X-Gitlab-Size]
@@ -298,7 +303,10 @@ module Gitlab
end
config.after_initialize do
- Rails.application.reload_routes!
+ # Devise (see initializers/8_devise.rb) already reloads routes if
+ # eager loading is enabled, so don't do this twice since it's
+ # expensive.
+ Rails.application.reload_routes! unless config.eager_load
project_url_helpers = Module.new do
extend ActiveSupport::Concern
@@ -316,7 +324,7 @@ module Gitlab
# conflict with the methods defined in `project_url_helpers`, and we want
# these methods available in the same places.
Gitlab::Routing.add_helpers(project_url_helpers)
- Gitlab::Routing.add_helpers(MilestonesRoutingHelper)
+ Gitlab::Routing.add_helpers(TimeboxesRoutingHelper)
end
end
end
diff --git a/config/dependency_decisions.yml b/config/dependency_decisions.yml
index 84db15d6535..ff5ccbb3c1b 100644
--- a/config/dependency_decisions.yml
+++ b/config/dependency_decisions.yml
@@ -626,3 +626,9 @@
:why:
:versions: []
:when: 2019-11-08 10:03:31.787226000 Z
+- - :whitelist
+ - CC0-1.0
+ - :who: Thomas Randolph
+ :why: This license is public domain
+ :versions: []
+ :when: 2020-06-03 05:04:44.632875345 Z
diff --git a/config/feature_categories.yml b/config/feature_categories.yml
index 010d3d14fcb..7cbc90497a4 100644
--- a/config/feature_categories.yml
+++ b/config/feature_categories.yml
@@ -43,6 +43,7 @@
- digital_experience_management
- disaster_recovery
- dynamic_application_security_testing
+- editor_extension
- epics
- error_tracking
- feature_flags
@@ -52,6 +53,7 @@
- geo_replication
- git_lfs
- gitaly
+- gitlab_docs
- gitlab_handbook
- gitter
- global_search
@@ -82,6 +84,7 @@
- pages
- pki_management
- planning_analytics
+- product_analytics
- quality_management
- release_evidence
- release_orchestration
@@ -100,7 +103,6 @@
- source_code_management
- static_application_security_testing
- static_site_editor
-- status_page
- subgroups
- templates
- time_tracking
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index 9a2e470f852..bd328d9919a 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -469,6 +469,11 @@ production: &base
geo_file_download_dispatch_worker:
cron: "*/1 * * * *"
+ # GitLab Geo registry sync worker (for backfilling)
+ # NOTE: This will only take effect if Geo is enabled (secondary nodes only)
+ geo_registry_sync_worker:
+ cron: "*/1 * * * *"
+
# GitLab Geo migrated local files clean up worker
# NOTE: This will only take effect if Geo is enabled (secondary nodes only)
geo_migrated_local_files_clean_up_worker:
@@ -482,6 +487,11 @@ production: &base
# NOTE: This will only take effect if elasticsearch is enabled.
elastic_index_bulk_cron_worker:
cron: "*/1 * * * *"
+
+ # Elasticsearch bulk updater for initial updates.
+ # NOTE: This will only take effect if elasticsearch is enabled.
+ elastic_index_initial_bulk_cron_worker:
+ cron: "*/1 * * * *"
registry:
# enabled: true
@@ -1078,8 +1088,6 @@ production: &base
monitoring:
# Time between sampling of unicorn socket metrics, in seconds
# unicorn_sampler_interval: 10
- # Time between sampling of Puma metrics, in seconds
- # puma_sampler_interval: 5
# IP whitelist to access monitoring endpoints
ip_whitelist:
- 127.0.0.0/8
diff --git a/config/initializers/01_secret_token.rb b/config/initializers/01_secret_token.rb
index e3fefeab81c..8b96727a2a1 100644
--- a/config/initializers/01_secret_token.rb
+++ b/config/initializers/01_secret_token.rb
@@ -61,6 +61,8 @@ def generate_new_rsa_private_key
end
def warn_missing_secret(secret)
+ return if Rails.env.test?
+
warn "Missing Rails.application.secrets.#{secret} for #{Rails.env} environment. The secret will be generated and stored in config/secrets.yml."
end
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index c0cd491547a..9d9f24183d5 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -451,9 +451,12 @@ Settings.cron_jobs['trending_projects_worker']['job_class'] = 'TrendingProjectsW
Settings.cron_jobs['remove_unreferenced_lfs_objects_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['remove_unreferenced_lfs_objects_worker']['cron'] ||= '20 0 * * *'
Settings.cron_jobs['remove_unreferenced_lfs_objects_worker']['job_class'] = 'RemoveUnreferencedLfsObjectsWorker'
-Settings.cron_jobs['stuck_import_jobs_worker'] ||= Settingslogic.new({})
-Settings.cron_jobs['stuck_import_jobs_worker']['cron'] ||= '15 * * * *'
-Settings.cron_jobs['stuck_import_jobs_worker']['job_class'] = 'StuckImportJobsWorker'
+Settings.cron_jobs['import_stuck_project_import_jobs'] ||= Settingslogic.new({})
+Settings.cron_jobs['import_stuck_project_import_jobs']['cron'] ||= '15 * * * *'
+Settings.cron_jobs['import_stuck_project_import_jobs']['job_class'] = 'Gitlab::Import::StuckProjectImportJobsWorker'
+Settings.cron_jobs['jira_import_stuck_jira_import_jobs'] ||= Settingslogic.new({})
+Settings.cron_jobs['jira_import_stuck_jira_import_jobs']['cron'] ||= '* 0/15 * * *'
+Settings.cron_jobs['jira_import_stuck_jira_import_jobs']['job_class'] = 'Gitlab::JiraImport::StuckJiraImportJobsWorker'
Settings.cron_jobs['stuck_export_jobs_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['stuck_export_jobs_worker']['cron'] ||= '30 * * * *'
Settings.cron_jobs['stuck_export_jobs_worker']['job_class'] = 'StuckExportJobsWorker'
@@ -478,6 +481,9 @@ Settings.cron_jobs['issue_due_scheduler_worker']['job_class'] = 'IssueDueSchedul
Settings.cron_jobs['prune_web_hook_logs_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['prune_web_hook_logs_worker']['cron'] ||= '0 */1 * * *'
Settings.cron_jobs['prune_web_hook_logs_worker']['job_class'] = 'PruneWebHookLogsWorker'
+Settings.cron_jobs['metrics_dashboard_schedule_annotations_prune_worker'] ||= Settingslogic.new({})
+Settings.cron_jobs['metrics_dashboard_schedule_annotations_prune_worker']['cron'] ||= '0 1 * * *'
+Settings.cron_jobs['metrics_dashboard_schedule_annotations_prune_worker']['job_class'] = 'Metrics::Dashboard::ScheduleAnnotationsPruneWorker'
Settings.cron_jobs['schedule_migrate_external_diffs_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['schedule_migrate_external_diffs_worker']['cron'] ||= '15 * * * *'
Settings.cron_jobs['schedule_migrate_external_diffs_worker']['job_class'] = 'ScheduleMigrateExternalDiffsWorker'
@@ -507,6 +513,9 @@ Gitlab.ee do
Settings.cron_jobs['geo_file_download_dispatch_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['geo_file_download_dispatch_worker']['cron'] ||= '*/1 * * * *'
Settings.cron_jobs['geo_file_download_dispatch_worker']['job_class'] ||= 'Geo::FileDownloadDispatchWorker'
+ Settings.cron_jobs['geo_registry_sync_worker'] ||= Settingslogic.new({})
+ Settings.cron_jobs['geo_registry_sync_worker']['cron'] ||= '*/1 * * * *'
+ Settings.cron_jobs['geo_registry_sync_worker']['job_class'] ||= 'Geo::RegistrySyncWorker'
Settings.cron_jobs['geo_metrics_update_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['geo_metrics_update_worker']['cron'] ||= '*/1 * * * *'
Settings.cron_jobs['geo_metrics_update_worker']['job_class'] ||= 'Geo::MetricsUpdateWorker'
@@ -552,9 +561,15 @@ Gitlab.ee do
Settings.cron_jobs['elastic_index_bulk_cron_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['elastic_index_bulk_cron_worker']['cron'] ||= '*/1 * * * *'
Settings.cron_jobs['elastic_index_bulk_cron_worker']['job_class'] ||= 'ElasticIndexBulkCronWorker'
+ Settings.cron_jobs['elastic_index_initial_bulk_cron_worker'] ||= Settingslogic.new({})
+ Settings.cron_jobs['elastic_index_initial_bulk_cron_worker']['cron'] ||= '*/1 * * * *'
+ Settings.cron_jobs['elastic_index_initial_bulk_cron_worker']['job_class'] ||= 'ElasticIndexInitialBulkCronWorker'
Settings.cron_jobs['sync_seat_link_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['sync_seat_link_worker']['cron'] ||= "#{rand(60)} 0 * * *"
Settings.cron_jobs['sync_seat_link_worker']['job_class'] = 'SyncSeatLinkWorker'
+ Settings.cron_jobs['web_application_firewall_metrics_worker'] ||= Settingslogic.new({})
+ Settings.cron_jobs['web_application_firewall_metrics_worker']['cron'] ||= '0 1 * * 0'
+ Settings.cron_jobs['web_application_firewall_metrics_worker']['job_class'] = 'IngressModsecurityCounterMetricsWorker'
end
#
@@ -728,9 +743,6 @@ Settings.action_cable['worker_pool_size'] ||= 4
Settings['monitoring'] ||= Settingslogic.new({})
Settings.monitoring['ip_whitelist'] ||= ['127.0.0.1/8']
Settings.monitoring['unicorn_sampler_interval'] ||= 10
-Settings.monitoring['puma_sampler_interval'] ||= 5
-Settings.monitoring['ruby_sampler_interval'] ||= 60
-Settings.monitoring['global_search_sampler_interval'] ||= 60
Settings.monitoring['sidekiq_exporter'] ||= Settingslogic.new({})
Settings.monitoring.sidekiq_exporter['enabled'] ||= false
Settings.monitoring.sidekiq_exporter['address'] ||= 'localhost'
diff --git a/config/initializers/7_prometheus_metrics.rb b/config/initializers/7_prometheus_metrics.rb
index 267a1f0b1a5..bb89850892e 100644
--- a/config/initializers/7_prometheus_metrics.rb
+++ b/config/initializers/7_prometheus_metrics.rb
@@ -42,14 +42,11 @@ if !Rails.env.test? && Gitlab::Metrics.prometheus_metrics_enabled?
Gitlab::Cluster::LifecycleEvents.on_worker_start do
defined?(::Prometheus::Client.reinitialize_on_pid_change) && Prometheus::Client.reinitialize_on_pid_change
- Gitlab::Metrics::Samplers::RubySampler.initialize_instance(Settings.monitoring.ruby_sampler_interval).start
-
- if Gitlab::Utils.to_boolean(ENV['ENABLE_DATABASE_CONNECTION_POOL_METRICS'])
- Gitlab::Metrics::Samplers::DatabaseSampler.initialize_instance(Gitlab::Metrics::Samplers::DatabaseSampler::SAMPLING_INTERVAL_SECONDS).start
- end
+ Gitlab::Metrics::Samplers::RubySampler.initialize_instance.start
+ Gitlab::Metrics::Samplers::DatabaseSampler.initialize_instance.start
if Gitlab.ee? && Gitlab::Runtime.sidekiq?
- Gitlab::Metrics::Samplers::GlobalSearchSampler.instance(Settings.monitoring.global_search_sampler_interval).start
+ Gitlab::Metrics::Samplers::GlobalSearchSampler.instance.start
end
rescue IOError => e
Gitlab::ErrorTracking.track_exception(e)
@@ -62,7 +59,7 @@ if !Rails.env.test? && Gitlab::Metrics.prometheus_metrics_enabled?
if Gitlab::Runtime.unicorn?
Gitlab::Metrics::Samplers::UnicornSampler.instance(Settings.monitoring.unicorn_sampler_interval).start
elsif Gitlab::Runtime.puma?
- Gitlab::Metrics::Samplers::PumaSampler.instance(Settings.monitoring.puma_sampler_interval).start
+ Gitlab::Metrics::Samplers::PumaSampler.instance.start
end
Gitlab::Metrics.gauge(:deployments, 'GitLab Version', {}, :max).set({ version: Gitlab::VERSION }, 1)
diff --git a/config/initializers/8_devise.rb b/config/initializers/8_devise.rb
index 3daddb10b29..2be6e535fee 100644
--- a/config/initializers/8_devise.rb
+++ b/config/initializers/8_devise.rb
@@ -6,6 +6,11 @@ Devise.setup do |config|
manager.default_strategies(scope: :user).unshift :two_factor_backupable
end
+ # This is the default. This makes it explicit that Devise loads routes
+ # before eager loading. Disabling this seems to cause an error loading
+ # grape-entity `expose` for some reason.
+ config.reload_routes = true
+
# ==> Mailer Configuration
# Configure the class responsible to send e-mails.
config.mailer = "DeviseMailer"
@@ -102,7 +107,7 @@ Devise.setup do |config|
# config.remember_across_browsers = true
# If true, extends the user's remember period when remembered via cookie.
- # config.extend_remember_period = false
+ config.extend_remember_period = true
# Options to be passed to the created cookie. For instance, you can set
# secure: true in order to force SSL only cookies.
diff --git a/config/initializers/action_cable.rb b/config/initializers/action_cable.rb
index eb44ff00d09..c549dd45ad9 100644
--- a/config/initializers/action_cable.rb
+++ b/config/initializers/action_cable.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require 'action_cable/subscription_adapter/redis'
+
Rails.application.configure do
# We only mount the ActionCable engine in tests where we run it in-app
# For other environments, we run it on a standalone Puma server
@@ -7,3 +9,11 @@ Rails.application.configure do
config.action_cable.url = Gitlab::Utils.append_path(Gitlab.config.gitlab.relative_url_root, '/-/cable')
config.action_cable.worker_pool_size = Gitlab.config.action_cable.worker_pool_size
end
+
+# https://github.com/rails/rails/blob/bb5ac1623e8de08c1b7b62b1368758f0d3bb6379/actioncable/lib/action_cable/subscription_adapter/redis.rb#L18
+ActionCable::SubscriptionAdapter::Redis.redis_connector = lambda do |config|
+ args = config.except(:adapter, :channel_prefix)
+ .merge(instrumentation_class: ::Gitlab::Instrumentation::Redis::ActionCable)
+
+ ::Redis.new(args)
+end
diff --git a/config/initializers/actionpack_generate_old_csrf_token.rb b/config/initializers/actionpack_generate_old_csrf_token.rb
new file mode 100644
index 00000000000..6367a1d4d59
--- /dev/null
+++ b/config/initializers/actionpack_generate_old_csrf_token.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module RequestForgeryProtectionPatch
+ private
+
+ # Patch to generate 6.0.3 tokens so that we do not have CSRF errors while
+ # rolling out 6.0.3.1. This enables GitLab to have a mix of 6.0.3 and
+ # 6.0.3.1 Rails servers
+ #
+ # 1. Deploy this patch with :global_csrf_token FF disabled.
+ # 2. Once all Rails servers are on 6.0.3.1, enable :global_csrf_token FF.
+ # 3. On GitLab 13.2, remove this patch
+ def masked_authenticity_token(session, form_options: {})
+ action, method = form_options.values_at(:action, :method)
+
+ raw_token = if per_form_csrf_tokens && action && method
+ action_path = normalize_action_path(action)
+ per_form_csrf_token(session, action_path, method)
+ else
+ if Feature.enabled?(:global_csrf_token)
+ global_csrf_token(session)
+ else
+ real_csrf_token(session)
+ end
+ end
+
+ mask_token(raw_token)
+ end
+ end
+end
+
+ActionController::Base.include Gitlab::RequestForgeryProtectionPatch
diff --git a/config/initializers/bullet.rb b/config/initializers/bullet.rb
index 0ade7109420..d1f72ca3ce7 100644
--- a/config/initializers/bullet.rb
+++ b/config/initializers/bullet.rb
@@ -1,10 +1,15 @@
-if defined?(Bullet) && ENV['ENABLE_BULLET']
+def bullet_enabled?
+ Gitlab::Utils.to_boolean(ENV['ENABLE_BULLET'].to_s)
+end
+
+if defined?(Bullet) && (bullet_enabled? || Rails.env.development?)
Rails.application.configure do
config.after_initialize do
Bullet.enable = true
- Bullet.bullet_logger = true
- Bullet.console = true
+ Bullet.bullet_logger = bullet_enabled?
+ Bullet.console = bullet_enabled?
+
Bullet.raise = Rails.env.test?
end
end
diff --git a/config/initializers/database_config.rb b/config/initializers/database_config.rb
index 52897ad549d..ce732677c74 100644
--- a/config/initializers/database_config.rb
+++ b/config/initializers/database_config.rb
@@ -30,7 +30,7 @@ if Gitlab::Runtime.multi_threaded?
Rails.application.config.database_configuration[Rails.env]
previous_db_pool_size = db_config['pool']
- db_config['pool'] = [db_config['pool'].to_i, max_threads].max
+ db_config['pool'] = [db_config['pool'].to_i, max_threads].max + ENV["DB_POOL_HEADROOM"].to_i
ActiveRecord::Base.establish_connection(db_config)
diff --git a/config/initializers/doorkeeper.rb b/config/initializers/doorkeeper.rb
index 4158bfec216..76e29fb6c02 100644
--- a/config/initializers/doorkeeper.rb
+++ b/config/initializers/doorkeeper.rb
@@ -106,10 +106,5 @@ Doorkeeper.configure do
# WWW-Authenticate Realm (default "Doorkeeper").
# realm "Doorkeeper"
- # Allow dynamic query parameters (disabled by default)
- # Some applications require dynamic query parameters on their request_uri
- # set to true if you want this to be allowed
- # wildcard_redirect_uri false
-
base_controller '::Gitlab::BaseDoorkeeperController'
end
diff --git a/config/initializers/fill_shards.rb b/config/initializers/fill_shards.rb
index 40a9a271953..90c0d63e4fe 100644
--- a/config/initializers/fill_shards.rb
+++ b/config/initializers/fill_shards.rb
@@ -1,8 +1,7 @@
-# The `table_exists?` check is needed because during our migration rollback testing,
+# The explicit schema version check is needed because during our migration rollback testing,
# `Shard.connected?` could be cached and return true even though the table doesn't exist
return unless Shard.connected?
-return unless Shard.table_exists?
-return unless Shard.connection.index_exists?(:shards, :name, unique: true)
+return unless ActiveRecord::Migrator.current_version >= 20190402150158
return if Gitlab::Database.read_only?
Shard.populate!
diff --git a/config/initializers/google_api_client.rb b/config/initializers/google_api_client.rb
index 443bb29fb52..49a35e5bd7c 100644
--- a/config/initializers/google_api_client.rb
+++ b/config/initializers/google_api_client.rb
@@ -1,23 +1,12 @@
# frozen_string_literal: true
-#
-# google-api-client >= 0.26.0 supports enabling CloudRun and Istio during
-# cluster creation, but fog-google currently hard deps on '~> 0.23.0', which
-# prevents us from upgrading. We are injecting these options as hashes below
-# as a workaround until this is resolved.
-#
-# This can be removed once fog-google and google-api-client can be upgraded.
-# See https://gitlab.com/gitlab-org/gitlab/issues/31280 for more details.
-#
-require 'google/apis/container_v1beta1'
require 'google/apis/options'
+# these require solve load order issues (undefined constant Google::Apis::ServerError and Signet::RemoteServerError, rescued in multiple places)
+require 'google/apis/errors'
+require 'signet/errors'
+
# As stated in https://github.com/googleapis/google-api-ruby-client#errors--retries,
# enabling retries is strongly encouraged but disabled by default. Large uploads
# that may hit timeouts will mainly benefit from this.
Google::Apis::RequestOptions.default.retries = 3 if Gitlab::Utils.to_boolean(ENV.fetch('ENABLE_GOOGLE_API_RETRIES', true))
-
-Google::Apis::ContainerV1beta1::AddonsConfig::Representation.tap do |representation|
- representation.hash :cloud_run_config, as: 'cloudRunConfig'
- representation.hash :istio_config, as: 'istioConfig'
-end
diff --git a/config/initializers/grape_validators.rb b/config/initializers/grape_validators.rb
index 9d2b6dc9bd1..22f2c9ecf92 100644
--- a/config/initializers/grape_validators.rb
+++ b/config/initializers/grape_validators.rb
@@ -7,3 +7,4 @@ Grape::Validations.register_validator(:git_sha, ::API::Validations::Validators::
Grape::Validations.register_validator(:integer_none_any, ::API::Validations::Validators::IntegerNoneAny)
Grape::Validations.register_validator(:array_none_any, ::API::Validations::Validators::ArrayNoneAny)
Grape::Validations.register_validator(:check_assignees_count, ::API::Validations::Validators::CheckAssigneesCount)
+Grape::Validations.register_validator(:untrusted_regexp, ::API::Validations::Validators::UntrustedRegexp)
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 cc20b83b234..55b98cda520 100644
--- a/config/initializers/kaminari_active_record_relation_methods_with_limit.rb
+++ b/config/initializers/kaminari_active_record_relation_methods_with_limit.rb
@@ -5,9 +5,10 @@ module Kaminari
# 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
- # that limit the COUNT query to 10,000 to avoid query timeouts.
+ # that limit the COUNT query to a configurable value to avoid query timeouts.
+ # The default limit value is 10,000 records
# rubocop: disable Gitlab/ModuleWithInstanceVariables
- def total_count_with_limit(column_name = :all, _options = nil) #:nodoc:
+ def total_count_with_limit(column_name = :all, options = {}) #:nodoc:
return @total_count if defined?(@total_count) && @total_count
# There are some cases that total count can be deduced from loaded records
@@ -18,13 +19,14 @@ 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
# #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
c = c.except(:includes) unless references_eager_loaded_tables?
# .group returns an OrderedHash that responds to #count
# The following line was modified from `c = c.count(:all)`
- c = c.limit(MAX_COUNT_LIMIT + 1).count(column_name)
+ c = c.limit(limit + 1).count(column_name)
@total_count =
if c.is_a?(Hash) || c.is_a?(ActiveSupport::OrderedHash)
c.count
diff --git a/config/initializers/lograge.rb b/config/initializers/lograge.rb
index e1e15d1870c..01353ad4ec1 100644
--- a/config/initializers/lograge.rb
+++ b/config/initializers/lograge.rb
@@ -12,9 +12,9 @@ unless Gitlab::Runtime.sidekiq?
config.lograge.logger = ActiveSupport::Logger.new(filename)
config.lograge.before_format = lambda do |data, payload|
data.delete(:error)
- data[:db_duration_s] = Gitlab::Utils.ms_to_round_sec(data.delete(:db))
- data[:view_duration_s] = Gitlab::Utils.ms_to_round_sec(data.delete(:view))
- data[:duration_s] = Gitlab::Utils.ms_to_round_sec(data.delete(:duration))
+ data[:db_duration_s] = Gitlab::Utils.ms_to_round_sec(data.delete(:db)) if data[:db]
+ data[:view_duration_s] = Gitlab::Utils.ms_to_round_sec(data.delete(:view)) if data[:view]
+ data[:duration_s] = Gitlab::Utils.ms_to_round_sec(data.delete(:duration)) if data[:duration]
data
end
diff --git a/config/initializers/peek.rb b/config/initializers/peek.rb
index a3810be70b2..deac938c80b 100644
--- a/config/initializers/peek.rb
+++ b/config/initializers/peek.rb
@@ -9,6 +9,8 @@ Peek.into Peek::Views::Host
Peek.into Peek::Views::ActiveRecord
Peek.into Peek::Views::Gitaly
Peek.into Peek::Views::RedisDetailed
+Peek.into Peek::Views::Elasticsearch
Peek.into Peek::Views::Rugged
+Peek.into Peek::Views::BulletDetailed if defined?(Bullet)
Peek.into Peek::Views::Tracing if Labkit::Tracing.tracing_url_enabled?
diff --git a/config/initializers/rack_attack_new.rb b/config/initializers/rack_attack.rb
index 51b49bec864..51b49bec864 100644
--- a/config/initializers/rack_attack_new.rb
+++ b/config/initializers/rack_attack.rb
diff --git a/config/initializers/zz_metrics.rb b/config/initializers/zz_metrics.rb
index 26f6743f480..7e675e478cf 100644
--- a/config/initializers/zz_metrics.rb
+++ b/config/initializers/zz_metrics.rb
@@ -147,6 +147,8 @@ if Gitlab::Metrics.enabled? && !Rails.env.test? && !(Rails.env.development? && d
Gitlab::Application.configure do |config|
config.middleware.use(Gitlab::Metrics::RackMiddleware)
config.middleware.use(Gitlab::Middleware::RailsQueueDuration)
+ config.middleware.use(Gitlab::Metrics::RedisRackMiddleware)
+ config.middleware.use(Gitlab::Metrics::ElasticsearchRackMiddleware)
end
Sidekiq.configure_server do |config|
diff --git a/config/locales/doorkeeper.en.yml b/config/locales/doorkeeper.en.yml
index 7c8dc2d0a32..8469b72c312 100644
--- a/config/locales/doorkeeper.en.yml
+++ b/config/locales/doorkeeper.en.yml
@@ -81,6 +81,8 @@ en:
Grants read-write access to repositories on private projects using Git-over-HTTP (not using the API).
read_registry:
Grants read-only access to container registry images on private projects.
+ write_registry:
+ Grants write access to container registry images on private projects.
openid:
Grants permission to authenticate with GitLab using OpenID Connect. Also gives read-only access to the user's profile and group memberships.
sudo:
diff --git a/config/locales/en.yml b/config/locales/en.yml
index c95232ae540..ed0552ab452 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -272,4 +272,5 @@ en:
long: "%B %d, %Y %H:%M"
short: "%d %b %H:%M"
timeago_tooltip: "%b %-d, %Y %-l:%M%P"
+ with_timezone: "%Y-%m-%d %H:%M:%S %z"
pm: pm
diff --git a/config/prometheus/self_monitoring_default.yml b/config/prometheus/self_monitoring_default.yml
index dc2361fb3bc..50e6f4585e4 100644
--- a/config/prometheus/self_monitoring_default.yml
+++ b/config/prometheus/self_monitoring_default.yml
@@ -1,6 +1,36 @@
dashboard: 'Default dashboard'
priority: 1
+
+templating:
+ variables:
+ instance:
+ type: 'text'
+ label: 'Instance label regex'
+ options:
+ default_value: '.+'
+
panel_groups:
+
+- group: 'Resource usage'
+ panels:
+ - title: "Memory usage"
+ type: "line-chart"
+ y_label: "% memory used"
+ metrics:
+ - id: node_memory_usage_percentage
+ query_range: '(1 - (node_memory_MemAvailable_bytes{instance=~"{{instance}}"} or (node_memory_MemFree_bytes{instance=~"{{instance}}"} + node_memory_Buffers_bytes{instance=~"{{instance}}"} + node_memory_Cached_bytes{instance=~"{{instance}}"} + node_memory_Slab_bytes{instance=~"{{instance}}"})) / node_memory_MemTotal_bytes{instance=~"{{instance}}"}) * 100'
+ unit: "%"
+ label: instance
+
+ - title: "CPU usage"
+ type: "line-chart"
+ y_label: "% CPU used"
+ metrics:
+ - id: node_cpu_usage_percentage
+ query_range: '(avg without (mode,cpu) (1 - irate(node_cpu_seconds_total{mode="idle",instance=~"{{instance}}"}[5m]))) * 100'
+ unit: "%"
+ label: instance
+
- group: Web Service
panels:
- title: Web Service - Error Ratio
diff --git a/config/pseudonymizer.yml b/config/pseudonymizer.yml
index e9d5fd5623f..532fbe3b70f 100644
--- a/config/pseudonymizer.yml
+++ b/config/pseudonymizer.yml
@@ -465,7 +465,6 @@ tables:
- auditor
- require_two_factor_authentication_from_group
- two_factor_grace_period
- - ghost
- last_activity_on
- notified_of_own_activity
- user_type
diff --git a/config/routes.rb b/config/routes.rb
index 86f42822299..598a52cddb3 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -45,12 +45,19 @@ Rails.application.routes.draw do
use_doorkeeper_openid_connect
# Sign up
- get 'users/sign_up/welcome' => 'registrations#welcome'
- patch 'users/sign_up/update_registration' => 'registrations#update_registration'
+ scope path: '/users/sign_up', module: :registrations, as: :users_sign_up do
+ get :welcome
+ patch :update_registration
+ resource :experience_level, only: [:show, :update]
+
+ Gitlab.ee do
+ resources :groups, only: [:new, :create]
+ resources :projects, only: [:new, :create]
+ end
+ end
# Search
get 'search' => 'search#show'
- get 'search/autocomplete' => 'search#autocomplete', as: :search_autocomplete
get 'search/count' => 'search#count', as: :search_count
# JSON Web Token
diff --git a/config/routes/dashboard.rb b/config/routes/dashboard.rb
index f1e8c2b9d82..7e29a36f020 100644
--- a/config/routes/dashboard.rb
+++ b/config/routes/dashboard.rb
@@ -5,13 +5,7 @@ resource :dashboard, controller: 'dashboard', only: [] do
get :activity
scope module: :dashboard do
- resources :milestones, only: [:index, :show] do
- member do
- get :merge_requests
- get :participants
- get :labels
- end
- end
+ resources :milestones, only: [:index]
resources :labels, only: [:index]
resources :groups, only: [:index]
diff --git a/config/routes/group.rb b/config/routes/group.rb
index 9571d70d103..408c57eaa94 100644
--- a/config/routes/group.rb
+++ b/config/routes/group.rb
@@ -70,6 +70,7 @@ constraints(::Constraints::GroupUrlConstrainer.new) do
end
resource :avatar, only: [:destroy]
+ resource :import, only: [:show]
concerns :clusterable
@@ -78,7 +79,7 @@ constraints(::Constraints::GroupUrlConstrainer.new) do
delete :leave, on: :collection
end
- resources :group_links, only: [:index, :create, :update, :destroy], constraints: { id: /\d+/ }
+ resources :group_links, only: [:create, :update, :destroy], constraints: { id: /\d+/ }
resources :uploads, only: [:create] do
collection do
diff --git a/config/routes/import.rb b/config/routes/import.rb
index 57a1fab48e9..cd8278f6fd0 100644
--- a/config/routes/import.rb
+++ b/config/routes/import.rb
@@ -25,12 +25,14 @@ namespace :import do
get :status
get :callback
get :jobs
+ get :realtime_changes
end
resource :bitbucket, only: [:create], controller: :bitbucket do
get :status
get :callback
get :jobs
+ get :realtime_changes
end
resource :bitbucket_server, only: [:create, :new], controller: :bitbucket_server do
@@ -38,6 +40,7 @@ namespace :import do
get :status
get :callback
get :jobs
+ get :realtime_changes
end
resource :google_code, only: [:create, :new], controller: :google_code do
@@ -53,6 +56,7 @@ namespace :import do
get :status
post :callback
get :jobs
+ get :realtime_changes
get :new_user_map, path: :user_map
post :create_user_map, path: :user_map
@@ -63,6 +67,10 @@ namespace :import do
post :authorize
end
+ resource :gitlab_group, only: [:create] do
+ post :authorize
+ end
+
resource :manifest, only: [:create, :new], controller: :manifest do
get :status
get :jobs
diff --git a/config/routes/merge_requests.rb b/config/routes/merge_requests.rb
index f6c45081ce0..b2635a7fa74 100644
--- a/config/routes/merge_requests.rb
+++ b/config/routes/merge_requests.rb
@@ -55,6 +55,15 @@ resources :merge_requests, concerns: :awardable, except: [:new, :create, :show],
delete :resolve, action: :unresolve
end
end
+
+ scope module: :merge_requests do
+ resources :drafts, only: [:index, :update, :create, :destroy] do
+ collection do
+ post :publish
+ delete :discard
+ end
+ end
+ end
end
scope path: 'merge_requests', controller: 'merge_requests/creations' do
diff --git a/config/routes/project.rb b/config/routes/project.rb
index 020bfa7687d..78dcc189d5b 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -49,9 +49,11 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
get :trace, defaults: { format: 'json' }
get :raw
get :terminal
+ get :proxy
- # This route is also defined in gitlab-workhorse. Make sure to update accordingly.
+ # These routes are also defined in gitlab-workhorse. Make sure to update accordingly.
get '/terminal.ws/authorize', to: 'jobs#terminal_websocket_authorize', format: false
+ get '/proxy.ws/authorize', to: 'jobs#proxy_websocket_authorize', format: false
end
resource :artifacts, only: [] do
@@ -65,12 +67,10 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
namespace :ci do
resource :lint, only: [:show, :create]
- resources :daily_build_group_report_results, only: [:index], constraints: { format: 'csv' }
+ resources :daily_build_group_report_results, only: [:index], constraints: { format: /(csv|json)/ }
end
namespace :settings do
- get :members, to: redirect("%{namespace_id}/%{project_id}/-/project_members")
-
resource :ci_cd, only: [:show, :update], controller: 'ci_cd' do
post :reset_cache
put :reset_registration_token
@@ -199,7 +199,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
resources :starrers, only: [:index]
resources :forks, only: [:index, :new, :create]
- resources :group_links, only: [:index, :create, :update, :destroy], constraints: { id: /\d+/ }
+ resources :group_links, only: [:create, :update, :destroy], constraints: { id: /\d+/ }
resource :import, only: [:new, :create, :show]
resource :avatar, only: [:show, :destroy]
@@ -315,6 +315,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
draw :issues
draw :merge_requests
+ draw :pipelines
# The wiki and repository routing contains wildcard characters so
# its preferable to keep it below all other project routes
@@ -323,9 +324,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
draw :wiki
namespace :import do
- resource :jira, only: [:show], controller: :jira do
- post :import
- end
+ resource :jira, only: [:show], controller: :jira
end
end
# End of the /-/ scope.
@@ -380,17 +379,6 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
post 'alerts/notify', to: 'alerting/notifications#create'
- # Unscoped route. It will be replaced with redirect to /-/pipelines/
- # Issue https://gitlab.com/gitlab-org/gitlab/issues/118849
- draw :pipelines
-
- # To ensure an old unscoped routing is used for the UI we need to
- # add prefix 'as' to the scope routing and place it below original routing.
- # Issue https://gitlab.com/gitlab-org/gitlab/issues/118849
- scope '-', as: 'scoped' do
- draw :pipelines
- end
-
draw :legacy_builds
resources :hooks, only: [:index, :create, :edit, :update, :destroy], constraints: { id: /\d+/ } do # rubocop: disable Cop/PutProjectRoutesUnderScope
@@ -472,9 +460,21 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
post :web_ide_pipelines_count
end
+ resources :web_ide_terminals, path: :ide_terminals, only: [:create, :show], constraints: { id: /\d+/, format: :json } do # rubocop: disable Cop/PutProjectRoutesUnderScope
+ member do
+ post :cancel
+ post :retry
+ end
+
+ collection do
+ post :check_config
+ end
+ end
+
# Deprecated unscoped routing.
# Issue https://gitlab.com/gitlab-org/gitlab/issues/118849
scope as: 'deprecated' do
+ draw :pipelines
draw :repository
end
diff --git a/config/settings.rb b/config/settings.rb
index 144a068ef2a..99f1b85202e 100644
--- a/config/settings.rb
+++ b/config/settings.rb
@@ -66,6 +66,12 @@ class Settings < Settingslogic
(base_url(gitlab) + [gitlab.relative_url_root]).join('')
end
+ def build_gitlab_go_url
+ # "Go package paths are not URLs, and do not include port numbers"
+ # https://github.com/golang/go/issues/38213#issuecomment-607851460
+ "#{gitlab.host}#{gitlab.relative_url_root}"
+ end
+
def kerberos_protocol
kerberos.https ? "https" : "http"
end
diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml
index e6e0b4b4409..0052910b56e 100644
--- a/config/sidekiq_queues.yml
+++ b/config/sidekiq_queues.yml
@@ -82,10 +82,14 @@
- 1
- - elastic_commit_indexer
- 1
+- - elastic_delete_project
+ - 1
- - elastic_full_index
- 1
- - elastic_indexer
- 1
+- - elastic_indexing_control
+ - 1
- - elastic_namespace_indexer
- 1
- - elastic_namespace_rollout
@@ -148,6 +152,8 @@
- 5
- - merge_request_mergeability_check
- 1
+- - metrics_dashboard_prune_old_annotations
+ - 1
- - migrate_external_diffs
- 1
- - namespaceless_project_destroy
@@ -210,6 +216,8 @@
- 1
- - prometheus_create_default_alerts
- 1
+- - propagate_integration
+ - 1
- - propagate_service_template
- 1
- - reactive_caching
@@ -236,6 +244,8 @@
- 1
- - repository_update_remote_mirror
- 1
+- - requirements_management_process_requirements_reports
+ - 1
- - security_scans
- 2
- - self_monitoring_project_create
diff --git a/config/webpack.config.js b/config/webpack.config.js
index 7c130b010b6..557db58b1b9 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -19,10 +19,11 @@ const IS_EE = require('./helpers/is_ee_env');
const DEV_SERVER_HOST = process.env.DEV_SERVER_HOST || 'localhost';
const DEV_SERVER_PORT = parseInt(process.env.DEV_SERVER_PORT, 10) || 3808;
const DEV_SERVER_LIVERELOAD = IS_DEV_SERVER && process.env.DEV_SERVER_LIVERELOAD !== 'false';
-const WEBPACK_REPORT = process.env.WEBPACK_REPORT;
-const WEBPACK_MEMORY_TEST = process.env.WEBPACK_MEMORY_TEST;
-const NO_COMPRESSION = process.env.NO_COMPRESSION;
-const NO_SOURCEMAPS = process.env.NO_SOURCEMAPS;
+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';
+const NO_COMPRESSION = process.env.NO_COMPRESSION && process.env.NO_COMPRESSION !== 'false';
+const NO_SOURCEMAPS = process.env.NO_SOURCEMAPS && process.env.NO_SOURCEMAPS !== 'false';
const VUE_VERSION = require('vue/package.json').version;
const VUE_LOADER_VERSION = require('vue-loader/package.json').version;
@@ -244,6 +245,7 @@ module.exports = {
loader: 'file-loader',
options: {
name: '[name].[contenthash:8].[ext]',
+ esModule: false,
},
},
],
@@ -254,7 +256,7 @@ module.exports = {
moduleIds: 'hashed',
runtimeChunk: 'single',
splitChunks: {
- maxInitialRequests: 4,
+ maxInitialRequests: 20,
cacheGroups: {
default: false,
common: () => ({
@@ -329,9 +331,6 @@ module.exports = {
// automatically configure monaco editor web workers
new MonacoWebpackPlugin(),
- // prevent pikaday from including moment.js
- new webpack.IgnorePlugin(/moment/, /pikaday/),
-
// fix legacy jQuery plugins which depend on globals
new webpack.ProvidePlugin({
$: 'jquery',
@@ -516,6 +515,14 @@ module.exports = {
// This one is used to check against "EE" properly in application code
IS_EE: IS_EE ? 'window.gon && window.gon.ee' : JSON.stringify(false),
}),
+
+ /* Pikaday has a optional dependency to moment.
+ We are currently not utilizing moment.
+ Ignoring this import removes warning from our development build.
+ Upstream reference:
+ https://github.com/Pikaday/Pikaday/blob/5c1a7559be/pikaday.js#L14
+ */
+ new webpack.IgnorePlugin(/moment/, /pikaday/),
].filter(Boolean),
devServer: {
diff --git a/config/webpack.vendor.config.js b/config/webpack.vendor.config.js
index bebd1d656b5..548eca4200f 100644
--- a/config/webpack.vendor.config.js
+++ b/config/webpack.vendor.config.js
@@ -38,7 +38,7 @@ module.exports = {
'katex',
'three',
'select2',
- 'moment',
+ 'moment-mini',
'aws-sdk',
'sanitize-html',
'bootstrap/dist/js/bootstrap.js',
@@ -65,7 +65,23 @@ module.exports = {
}),
new YarnCheck({
rootDirectory: ROOT_PATH,
- exclude: /ts-jest/,
+ exclude: new RegExp(
+ [
+ /*
+ chokidar has a newer version which do not depend on fsevents,
+ is faster and only compatible with newer node versions (>=8)
+
+ Their actual interface remains the same and we can safely _force_
+ newer versions to get performance and security benefits.
+
+ This can be removed once all dependencies are up to date:
+ https://gitlab.com/gitlab-org/gitlab/-/issues/219353
+ */
+ 'chokidar',
+ // We are ignoring ts-jest, because we force a newer version, compatible with our current jest version
+ 'ts-jest',
+ ].join('|'),
+ ),
forceKill: true,
}),
],
diff --git a/danger/bundle_size/Dangerfile b/danger/bundle_size/Dangerfile
new file mode 100644
index 00000000000..a7102cd0e38
--- /dev/null
+++ b/danger/bundle_size/Dangerfile
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+analysis_result = "./bundle-size-review/analysis.json"
+markdown_result = "./bundle-size-review/comparison.md"
+
+# Executing the webpack-entry-point-analyser
+# We would like to do that in the CI file directly,
+# but unfortunately the head_commit SHA is not available
+# as a CI variable due to our merge into master simulation
+analyze_cmd = [
+ "webpack-entry-point-analyser",
+ "--from-file ./webpack-report/stats.json",
+ "--json #{analysis_result}",
+ " --sha #{gitlab&.head_commit}"
+].join(" ")
+
+# execute analysis
+`#{analyze_cmd}`
+
+# We are executing the comparison by comparing the start_sha
+# to the current pipeline result. The start_sha is the commit
+# from master that was merged into for the merged pipeline.
+comparison_cmd = [
+ "webpack-compare-reports",
+ "--job #{ENV["CI_JOB_ID"]}",
+ "--to-file #{analysis_result}",
+ "--html ./bundle-size-review/comparison.html",
+ "--markdown #{markdown_result}"
+].join(" ")
+
+# execute comparison
+`#{comparison_cmd}`
+
+comment = `cat #{markdown_result}`
+
+markdown(<<~MARKDOWN)
+ #{comment}
+MARKDOWN
diff --git a/danger/changelog/Dangerfile b/danger/changelog/Dangerfile
index 7b8a096639d..aa7a81555a3 100644
--- a/danger/changelog/Dangerfile
+++ b/danger/changelog/Dangerfile
@@ -3,7 +3,7 @@
require 'yaml'
-SEE_DOC = "See [the documentation](https://docs.gitlab.com/ee/development/changelog.html)."
+SEE_DOC = "See the [changelog documentation](https://docs.gitlab.com/ee/development/changelog.html)."
CREATE_CHANGELOG_MESSAGE = <<~MSG
If you want to create a changelog entry for GitLab FOSS, run the following:
@@ -20,14 +20,29 @@ bin/changelog --ee -m %<mr_iid>s "%<mr_title>s"
If this merge request [doesn't need a CHANGELOG entry](https://docs.gitlab.com/ee/development/changelog.html#what-warrants-a-changelog-entry), feel free to ignore this message.
MSG
+SUGGEST_MR_COMMENT = <<~SUGGEST_COMMENT
+```suggestion
+merge_request: %<mr_iid>s
+```
+
+#{SEE_DOC}
+SUGGEST_COMMENT
+
def check_changelog_yaml(path)
- yaml = YAML.safe_load(File.read(path))
+ raw_file = File.read(path)
+ yaml = YAML.safe_load(raw_file)
fail "`title` should be set, in #{gitlab.html_link(path)}! #{SEE_DOC}" if yaml["title"].nil?
fail "`type` should be set, in #{gitlab.html_link(path)}! #{SEE_DOC}" if yaml["type"].nil?
if yaml["merge_request"].nil? && !helper.security_mr?
- message "Consider setting `merge_request` to #{gitlab.mr_json["iid"]} in #{gitlab.html_link(path)}. #{SEE_DOC}"
+ mr_line = raw_file.lines.find_index("merge_request:\n")
+
+ if mr_line
+ markdown(format(SUGGEST_MR_COMMENT, mr_iid: gitlab.mr_json["iid"]), file: path, line: mr_line.succ)
+ else
+ message "Consider setting `merge_request` to #{gitlab.mr_json["iid"]} in #{gitlab.html_link(path)}. #{SEE_DOC}"
+ end
elsif yaml["merge_request"] != gitlab.mr_json["iid"] && !helper.security_mr?
fail "Merge request ID was not set to #{gitlab.mr_json["iid"]}! #{SEE_DOC}"
end
diff --git a/danger/commit_messages/Dangerfile b/danger/commit_messages/Dangerfile
index 59d42082de9..174fc10eef3 100644
--- a/danger/commit_messages/Dangerfile
+++ b/danger/commit_messages/Dangerfile
@@ -6,6 +6,16 @@ COMMIT_MESSAGE_GUIDELINES = "https://docs.gitlab.com/ee/development/contributing
MORE_INFO = "For more information, take a look at our [Commit message guidelines](#{COMMIT_MESSAGE_GUIDELINES})."
THE_DANGER_JOB_TEXT = "the `danger-review` job"
MAX_COMMITS_COUNT = 10
+MAX_COMMITS_COUNT_EXCEEDED_MESSAGE = <<~MSG
+This merge request includes more than %<max_commits_count>d commits. Each commit should meet the following criteria:
+
+1. Have a well-written commit message.
+1. Has all tests passing when used on its own (e.g. when using git checkout SHA).
+1. Can be reverted on its own without also requiring the revert of commit that came before it.
+1. Is small enough that it can be reviewed in isolation in under 30 minutes or so.
+
+If this merge request contains commits that do not meet this criteria and/or contains intermediate work, please rebase these commits into a smaller number of commits or split this merge request into multiple smaller merge requests.
+MSG
def gitlab_danger
@gitlab_danger ||= GitlabDanger.new(helper.gitlab_helper)
@@ -94,11 +104,7 @@ def lint_commits(commits)
warn_or_fail_commits(failed_commit_linters, default_to_fail: !squash_mr?)
if count_non_fixup_commits(commit_linters) > MAX_COMMITS_COUNT
- level = squash_mr? ? :warn : :fail
- self.__send__(level, # rubocop:disable GitlabSecurity/PublicSend
- "This merge request includes more than #{MAX_COMMITS_COUNT} commits. " \
- 'Please rebase these commits into a smaller number of commits or split ' \
- 'this merge request into multiple smaller merge requests.')
+ self.warn(format(MAX_COMMITS_COUNT_EXCEEDED_MESSAGE, max_commits_count: MAX_COMMITS_COUNT))
end
if squash_mr?
diff --git a/danger/roulette/Dangerfile b/danger/roulette/Dangerfile
index d73f6bf4f10..54559af4066 100644
--- a/danger/roulette/Dangerfile
+++ b/danger/roulette/Dangerfile
@@ -36,36 +36,22 @@ Please consider creating a merge request to
for them.
MARKDOWN
-NO_REVIEWER = 'No reviewer available'.freeze
-NO_MAINTAINER = 'No maintainer available'.freeze
+OPTIONAL_REVIEW_TEMPLATE = "%{role} review is optional for %{category}".freeze
+NOT_AVAILABLE_TEMPLATE = 'No %{role} available'.freeze
-Spin = Struct.new(:reviewer, :maintainer)
-
-def spin_role_for_category(team, role, project, category)
- team.select do |member|
- member.public_send("#{role}?", project, category, gitlab.mr_labels) # rubocop:disable GitlabSecurity/PublicSend
+def note_for_category_role(spin, role)
+ if spin.optional_role == role
+ return OPTIONAL_REVIEW_TEMPLATE % { role: role.capitalize, category: helper.label_for_category(spin.category) }
end
-end
-
-def spin_for_category(team, project, category, branch_name)
- reviewers, traintainers, maintainers =
- %i[reviewer traintainer maintainer].map do |role|
- spin_role_for_category(team, role, project, category)
- end
- # TODO: take CODEOWNERS into account?
- # https://gitlab.com/gitlab-org/gitlab/issues/26723
-
- # Make traintainers have triple the chance to be picked as a reviewer
- random = roulette.new_random(branch_name)
- reviewer = roulette.spin_for_person(reviewers + traintainers + traintainers, random: random)
- maintainer = roulette.spin_for_person(maintainers, random: random)
-
- Spin.new(reviewer, maintainer)
+ spin.public_send(role)&.markdown_name || NOT_AVAILABLE_TEMPLATE % { role: role } # rubocop:disable GitlabSecurity/PublicSend
end
-def markdown_row_for_category(category, reviewer, maintainer)
- "| #{helper.label_for_category(category)} | #{reviewer&.markdown_name || NO_REVIEWER} | #{maintainer&.markdown_name || NO_MAINTAINER} |"
+def markdown_row_for_spin(spin)
+ reviewer_note = note_for_category_role(spin, :reviewer)
+ maintainer_note = note_for_category_role(spin, :maintainer)
+
+ "| #{helper.label_for_category(spin.category)} | #{reviewer_note} | #{maintainer_note} |"
end
changes = helper.changes_by_category
@@ -78,43 +64,13 @@ categories = changes.keys - [:unknown]
categories << :database if gitlab.mr_labels.include?('database') && !categories.include?(:database)
if changes.any?
- # Strip leading and trailing CE/EE markers
- canonical_branch_name =
- roulette.canonical_branch_name(gitlab.mr_json['source_branch'])
-
- team =
- begin
- roulette.project_team(helper.project_name)
- rescue => err
- warn("Reviewer roulette failed to load team data: #{err.message}")
- []
- end
-
project = helper.project_name
- unknown = changes.fetch(:unknown, [])
- spin_per_category = categories.each_with_object({}) do |category, memo|
- memo[category] = spin_for_category(team, project, category, canonical_branch_name)
- end
+ branch_name = gitlab.mr_json['source_branch']
- rows = spin_per_category.map do |category, spin|
- reviewer = spin.reviewer
- maintainer = spin.maintainer
-
- case category
- when :test
- if reviewer.nil?
- # Fetch an already picked backend reviewer, or pick one otherwise
- reviewer = spin_per_category[:backend]&.reviewer || spin_for_category(team, project, :backend, canonical_branch_name).reviewer
- end
- when :engineering_productivity
- if maintainer.nil?
- # Fetch an already picked backend maintainer, or pick one otherwise
- maintainer = spin_per_category[:backend]&.maintainer || spin_for_category(team, project, :backend, canonical_branch_name).maintainer
- end
- end
-
- markdown_row_for_category(category, reviewer, maintainer)
- end
+ roulette_spins = roulette.spin(project, categories, branch_name)
+ rows = roulette_spins.map { |spin| markdown_row_for_spin(spin) }
+
+ unknown = changes.fetch(:unknown, [])
markdown(MESSAGE)
markdown(CATEGORY_TABLE_HEADER + rows.join("\n")) unless rows.empty?
diff --git a/danger/specs/Dangerfile b/danger/specs/Dangerfile
index 7803fad8472..784ce75fef8 100644
--- a/danger/specs/Dangerfile
+++ b/danger/specs/Dangerfile
@@ -1,16 +1,35 @@
# frozen_string_literal: true
NO_SPECS_LABELS = %w[backstage documentation QA].freeze
-NO_NEW_SPEC_MESSAGE = <<~MSG.freeze
+NO_NEW_SPEC_MESSAGE = <<~MSG
You've made some app changes, but didn't add any tests.
That's OK as long as you're refactoring existing code,
but please consider adding any of the %<labels>s labels.
MSG
+EE_CHANGE_WITH_FOSS_SPEC_CHANGE_MESSAGE = <<~MSG
+You've made some EE-specific changes, but only made changes to FOSS tests.
+This could be a sign that you're testing an EE-specific behavior in a FOSS test.
-has_app_changes = !helper.all_changed_files.grep(%r{\A(ee/)?(app|lib|db/(geo/)?(post_)?migrate)/}).empty?
-has_spec_changes = !helper.all_changed_files.grep(%r{\A(ee/)?spec/}).empty?
+Please make sure the spec files pass in AS-IF-FOSS mode either:
+
+1. Locally with `FOSS_ONLY=1 bin/rspec -- %<spec_files>s`.
+1. In the MR pipeline by verifying that the `rspec foss-impact` job has passed.
+1. In the MR pipelines by including `RUN AS-IF-FOSS` in the MR title (you can do it with the ``/title %<mr_title>s [RUN AS-IF-FOSS]`` quick action) and start a new MR pipeline.
+
+MSG
+
+has_app_changes = helper.all_changed_files.grep(%r{\A(app|lib|db/(geo/)?(post_)?migrate)/}).any?
+has_ee_app_changes = helper.all_changed_files.grep(%r{\Aee/(app|lib|db/(geo/)?(post_)?migrate)/}).any?
+spec_changes = helper.all_changed_files.grep(%r{\Aspec/})
+has_spec_changes = spec_changes.any?
+has_ee_spec_changes = helper.all_changed_files.grep(%r{\Aee/spec/}).any?
new_specs_needed = (gitlab.mr_labels & NO_SPECS_LABELS).empty?
-if has_app_changes && !has_spec_changes && new_specs_needed
+if (has_app_changes || has_ee_app_changes) && !(has_spec_changes || has_ee_spec_changes) && new_specs_needed
warn format(NO_NEW_SPEC_MESSAGE, labels: helper.labels_list(NO_SPECS_LABELS)), sticky: false
end
+
+# The only changes outside `ee/` are in `spec/`
+if has_ee_app_changes && has_spec_changes && !(has_app_changes || has_ee_spec_changes)
+ warn format(EE_CHANGE_WITH_FOSS_SPEC_CHANGE_MESSAGE, spec_files: spec_changes.join(" "), mr_title: gitlab.mr_json['title']), sticky: false
+end
diff --git a/danger/telemetry/Dangerfile b/danger/telemetry/Dangerfile
index c18a15fcb03..b749bd3b80b 100644
--- a/danger/telemetry/Dangerfile
+++ b/danger/telemetry/Dangerfile
@@ -1,12 +1,11 @@
# frozen_string_literal: true
TELEMETRY_CHANGED_FILES_MESSAGE = <<~MSG
-This merge request includes changes for which a review from the Data team and Telemetry team is recommended.
-Please reach out to @gitlab-org/growth/telemetry/engineers group for a review.
-MSG
+For the following files, a review from the [Data team and Telemetry team](https://gitlab.com/groups/gitlab-org/growth/telemetry/engineers/-/group_members?with_inherited_permissions=exclude) is recommended
+Please check the ~telemetry [guide](https://docs.gitlab.com/ee/development/telemetry/usage_ping.html) and reach out to @gitlab-org/growth/telemetry/engineers group for a review.
+
+%<changed_files>s
-USAGE_DATA_FILES_MESSAGE = <<~MSG
-For the following files, a review from the [Data team and Telemetry team](https://gitlab.com/groups/gitlab-org/growth/telemetry/engineers/-/group_members?with_inherited_permissions=exclude) is recommended:
MSG
tracking_files = [
@@ -16,7 +15,7 @@ tracking_files = [
'spec/helpers/tracking_helper_spec.rb',
'app/assets/javascripts/tracking.js',
'spec/frontend/tracking_spec.js'
- ]
+]
usage_data_changed_files = git.modified_files.grep(%r{usage_data})
snowplow_events_changed_files = git.modified_files & tracking_files
@@ -24,9 +23,7 @@ snowplow_events_changed_files = git.modified_files & tracking_files
changed_files = (usage_data_changed_files + snowplow_events_changed_files)
if changed_files.any?
- warn format(TELEMETRY_CHANGED_FILES_MESSAGE)
-
- markdown(USAGE_DATA_FILES_MESSAGE + helper.markdown_list(changed_files))
+ warn format(TELEMETRY_CHANGED_FILES_MESSAGE, changed_files: helper.markdown_list(changed_files))
telemetry_labels = ['telemetry']
telemetry_labels << 'telemetry::review pending' unless helper.mr_has_labels?('telemetry::reviewed')
diff --git a/db/fixtures/development/10_merge_requests.rb b/db/fixtures/development/10_merge_requests.rb
index 9157045a7fd..8cda3eb51be 100644
--- a/db/fixtures/development/10_merge_requests.rb
+++ b/db/fixtures/development/10_merge_requests.rb
@@ -19,7 +19,7 @@ Gitlab::Seeder.quiet do
target_branch = branches.pop
label_ids = project.labels.pluck(:id).sample(3)
- label_ids += project.group.labels.sample(3) if project.group
+ label_ids += project.group.labels.sample(3).pluck(:id) if project.group
params = {
source_branch: source_branch,
diff --git a/db/fixtures/development/17_cycle_analytics.rb b/db/fixtures/development/17_cycle_analytics.rb
index f5dc2b558d4..57993061c58 100644
--- a/db/fixtures/development/17_cycle_analytics.rb
+++ b/db/fixtures/development/17_cycle_analytics.rb
@@ -107,6 +107,10 @@ class Gitlab::Seeder::CycleAnalytics
pipeline = FactoryBot.create(:ci_pipeline, :success, project: project)
build = FactoryBot.create(:ci_build, pipeline: pipeline, project: project, user: developers.sample)
+ # Required because seeds run in a transaction and these are now
+ # created in an `after_commit` hook.
+ merge_request.ensure_metrics
+
merge_request.metrics.update!(
latest_build_started_at: merge_request.created_at,
latest_build_finished_at: within_end_time(merge_request.created_at + TEST_STAGE_MAX_DURATION_IN_HOURS.hours),
diff --git a/db/gitlab_structure.sql b/db/gitlab_structure.sql
new file mode 100644
index 00000000000..35c7a2eb14e
--- /dev/null
+++ b/db/gitlab_structure.sql
@@ -0,0 +1,4 @@
+-- this file tracks custom GitLab data, such as foreign keys referencing partitioned tables
+-- more details can be found in the issue: https://gitlab.com/gitlab-org/gitlab/-/issues/201872
+SET search_path=public;
+
diff --git a/db/migrate/20171230123729_init_schema.rb b/db/migrate/20171230123729_init_schema.rb
deleted file mode 100644
index 99ff85ff01f..00000000000
--- a/db/migrate/20171230123729_init_schema.rb
+++ /dev/null
@@ -1,1859 +0,0 @@
-# frozen_string_literal: true
-
-# rubocop:disable Layout/SpaceInsideHashLiteralBraces
-# rubocop:disable Layout/SpaceAroundOperators
-# rubocop:disable Metrics/AbcSize
-# rubocop:disable Migration/AddConcurrentForeignKey
-# rubocop:disable Style/WordArray
-# rubocop:disable Migration/PreventStrings
-# rubocop:disable Migration/AddLimitToTextColumns
-# rubocop:disable Migration/Datetime
-
-class InitSchema < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- def up
- # These are extensions that must be enabled in order to support this database
- enable_extension "plpgsql"
- enable_extension "pg_trgm"
- create_table "abuse_reports", id: :serial do |t|
- t.integer "reporter_id"
- t.integer "user_id"
- t.text "message"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.text "message_html"
- t.integer "cached_markdown_version"
- end
- create_table "appearances", id: :serial do |t|
- t.string "title", null: false
- t.text "description", null: false
- t.string "header_logo"
- t.string "logo"
- t.datetime_with_timezone "created_at", null: false
- t.datetime_with_timezone "updated_at", null: false
- t.text "description_html"
- t.integer "cached_markdown_version"
- t.string "favicon"
- t.text "new_project_guidelines"
- t.text "new_project_guidelines_html"
- end
- create_table "application_settings", id: :serial do |t|
- t.integer "default_projects_limit"
- t.boolean "signup_enabled"
- t.boolean "gravatar_enabled"
- t.text "sign_in_text"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.string "home_page_url"
- t.integer "default_branch_protection", default: 2
- t.text "restricted_visibility_levels"
- t.boolean "version_check_enabled", default: true
- t.integer "max_attachment_size", default: 10, null: false
- t.integer "default_project_visibility"
- t.integer "default_snippet_visibility"
- t.text "domain_whitelist"
- t.boolean "user_oauth_applications", default: true
- t.string "after_sign_out_path"
- t.integer "session_expire_delay", default: 10080, null: false
- t.text "import_sources"
- t.text "help_page_text"
- t.string "admin_notification_email"
- t.boolean "shared_runners_enabled", default: true, null: false
- t.integer "max_artifacts_size", default: 100, null: false
- t.string "runners_registration_token"
- t.integer "max_pages_size", default: 100, null: false
- t.boolean "require_two_factor_authentication", default: false
- t.integer "two_factor_grace_period", default: 48
- t.boolean "metrics_enabled", default: false
- t.string "metrics_host", default: "localhost"
- t.integer "metrics_pool_size", default: 16
- t.integer "metrics_timeout", default: 10
- t.integer "metrics_method_call_threshold", default: 10
- t.boolean "recaptcha_enabled", default: false
- t.string "recaptcha_site_key"
- t.string "recaptcha_private_key"
- t.integer "metrics_port", default: 8089
- t.boolean "akismet_enabled", default: false
- t.string "akismet_api_key"
- t.integer "metrics_sample_interval", default: 15
- t.boolean "sentry_enabled", default: false
- t.string "sentry_dsn"
- t.boolean "email_author_in_body", default: false
- t.integer "default_group_visibility"
- t.boolean "repository_checks_enabled", default: false
- t.text "shared_runners_text"
- t.integer "metrics_packet_size", default: 1
- t.text "disabled_oauth_sign_in_sources"
- t.string "health_check_access_token"
- t.boolean "send_user_confirmation_email", default: false
- t.integer "container_registry_token_expire_delay", default: 5
- t.text "after_sign_up_text"
- t.boolean "user_default_external", default: false, null: false
- t.string "repository_storages", default: "default"
- t.string "enabled_git_access_protocol"
- t.boolean "domain_blacklist_enabled", default: false
- t.text "domain_blacklist"
- t.boolean "usage_ping_enabled", default: true, null: false
- t.boolean "koding_enabled"
- t.string "koding_url"
- t.text "sign_in_text_html"
- t.text "help_page_text_html"
- t.text "shared_runners_text_html"
- t.text "after_sign_up_text_html"
- t.integer "rsa_key_restriction", default: 0, null: false
- t.integer "dsa_key_restriction", default: 0, null: false
- t.integer "ecdsa_key_restriction", default: 0, null: false
- t.integer "ed25519_key_restriction", default: 0, null: false
- t.boolean "housekeeping_enabled", default: true, null: false
- t.boolean "housekeeping_bitmaps_enabled", default: true, null: false
- t.integer "housekeeping_incremental_repack_period", default: 10, null: false
- t.integer "housekeeping_full_repack_period", default: 50, null: false
- t.integer "housekeeping_gc_period", default: 200, null: false
- t.boolean "sidekiq_throttling_enabled", default: false
- t.string "sidekiq_throttling_queues"
- t.decimal "sidekiq_throttling_factor"
- t.boolean "html_emails_enabled", default: true
- t.string "plantuml_url"
- t.boolean "plantuml_enabled"
- t.integer "terminal_max_session_time", default: 0, null: false
- t.integer "unique_ips_limit_per_user"
- t.integer "unique_ips_limit_time_window"
- t.boolean "unique_ips_limit_enabled", default: false, null: false
- t.string "default_artifacts_expire_in", default: "0", null: false
- t.string "uuid"
- t.decimal "polling_interval_multiplier", default: "1.0", null: false
- t.integer "cached_markdown_version"
- t.boolean "clientside_sentry_enabled", default: false, null: false
- t.string "clientside_sentry_dsn"
- t.boolean "prometheus_metrics_enabled", default: false, null: false
- t.boolean "authorized_keys_enabled", default: true, null: false
- t.boolean "help_page_hide_commercial_content", default: false
- t.string "help_page_support_url"
- t.integer "performance_bar_allowed_group_id"
- t.boolean "hashed_storage_enabled", default: false, null: false
- t.boolean "project_export_enabled", default: true, null: false
- t.boolean "auto_devops_enabled", default: false, null: false
- t.boolean "throttle_unauthenticated_enabled", default: false, null: false
- t.integer "throttle_unauthenticated_requests_per_period", default: 3600, null: false
- t.integer "throttle_unauthenticated_period_in_seconds", default: 3600, null: false
- t.boolean "throttle_authenticated_api_enabled", default: false, null: false
- t.integer "throttle_authenticated_api_requests_per_period", default: 7200, null: false
- t.integer "throttle_authenticated_api_period_in_seconds", default: 3600, null: false
- t.boolean "throttle_authenticated_web_enabled", default: false, null: false
- t.integer "throttle_authenticated_web_requests_per_period", default: 7200, null: false
- t.integer "throttle_authenticated_web_period_in_seconds", default: 3600, null: false
- t.integer "circuitbreaker_failure_count_threshold", default: 3
- t.integer "circuitbreaker_failure_reset_time", default: 1800
- t.integer "circuitbreaker_storage_timeout", default: 15
- t.integer "circuitbreaker_access_retries", default: 3
- t.integer "gitaly_timeout_default", default: 55, null: false
- t.integer "gitaly_timeout_medium", default: 30, null: false
- t.integer "gitaly_timeout_fast", default: 10, null: false
- t.boolean "password_authentication_enabled_for_web"
- t.boolean "password_authentication_enabled_for_git", default: true, null: false
- t.integer "circuitbreaker_check_interval", default: 1, null: false
- t.boolean "external_authorization_service_enabled", default: false, null: false
- t.string "external_authorization_service_url"
- t.string "external_authorization_service_default_label"
- end
- create_table "audit_events", id: :serial do |t|
- t.integer "author_id", null: false
- t.string "type", null: false
- t.integer "entity_id", null: false
- t.string "entity_type", null: false
- t.text "details"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.index ["entity_id", "entity_type"], name: "index_audit_events_on_entity_id_and_entity_type", using: :btree
- end
- create_table "award_emoji", id: :serial do |t|
- t.string "name"
- t.integer "user_id"
- t.string "awardable_type"
- t.integer "awardable_id"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.index ["awardable_type", "awardable_id"], name: "index_award_emoji_on_awardable_type_and_awardable_id", using: :btree
- t.index ["user_id", "name"], name: "index_award_emoji_on_user_id_and_name", using: :btree
- end
- create_table "boards", id: :serial do |t|
- t.integer "project_id", null: false
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.index ["project_id"], name: "index_boards_on_project_id", using: :btree
- end
- create_table "broadcast_messages", id: :serial do |t|
- t.text "message", null: false
- t.datetime "starts_at", null: false
- t.datetime "ends_at", null: false
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.string "color"
- t.string "font"
- t.text "message_html", null: false
- t.integer "cached_markdown_version"
- t.index ["starts_at", "ends_at", "id"], name: "index_broadcast_messages_on_starts_at_and_ends_at_and_id", using: :btree
- end
- create_table "chat_names", id: :serial do |t|
- t.integer "user_id", null: false
- t.integer "service_id", null: false
- t.string "team_id", null: false
- t.string "team_domain"
- t.string "chat_id", null: false
- t.string "chat_name"
- t.datetime "last_used_at"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.index ["service_id", "team_id", "chat_id"], name: "index_chat_names_on_service_id_and_team_id_and_chat_id", unique: true, using: :btree
- t.index ["user_id", "service_id"], name: "index_chat_names_on_user_id_and_service_id", unique: true, using: :btree
- end
- create_table "chat_teams", id: :serial do |t|
- t.integer "namespace_id", null: false
- t.string "team_id"
- t.string "name"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.index ["namespace_id"], name: "index_chat_teams_on_namespace_id", unique: true, using: :btree
- end
- create_table "ci_build_trace_section_names", id: :serial do |t|
- t.integer "project_id", null: false
- t.string "name", null: false
- t.index ["project_id", "name"], name: "index_ci_build_trace_section_names_on_project_id_and_name", unique: true, using: :btree
- end
- create_table "ci_build_trace_sections", id: :serial do |t|
- t.integer "project_id", null: false
- t.datetime_with_timezone "date_start", null: false
- t.datetime_with_timezone "date_end", null: false
- t.bigint "byte_start", null: false
- t.bigint "byte_end", null: false
- t.integer "build_id", null: false
- t.integer "section_name_id", null: false
- t.index ["build_id", "section_name_id"], name: "index_ci_build_trace_sections_on_build_id_and_section_name_id", unique: true, using: :btree
- t.index ["project_id"], name: "index_ci_build_trace_sections_on_project_id", using: :btree
- end
- create_table "ci_builds", id: :serial do |t|
- t.string "status"
- t.datetime "finished_at"
- t.text "trace"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.datetime "started_at"
- t.integer "runner_id"
- t.float "coverage"
- t.integer "commit_id"
- t.text "commands"
- t.string "name"
- t.text "options"
- t.boolean "allow_failure", default: false, null: false
- t.string "stage"
- t.integer "trigger_request_id"
- t.integer "stage_idx"
- t.boolean "tag"
- t.string "ref"
- t.integer "user_id"
- t.string "type"
- t.string "target_url"
- t.string "description"
- t.text "artifacts_file"
- t.integer "project_id"
- t.text "artifacts_metadata"
- t.integer "erased_by_id"
- t.datetime "erased_at"
- t.datetime "artifacts_expire_at"
- t.string "environment"
- t.bigint "artifacts_size"
- t.string "when"
- t.text "yaml_variables"
- t.datetime "queued_at"
- t.string "token"
- t.integer "lock_version"
- t.string "coverage_regex"
- t.integer "auto_canceled_by_id"
- t.boolean "retried"
- t.integer "stage_id"
- t.integer "artifacts_file_store"
- t.integer "artifacts_metadata_store"
- t.boolean "protected"
- t.integer "failure_reason"
- t.index ["auto_canceled_by_id"], name: "index_ci_builds_on_auto_canceled_by_id", using: :btree
- t.index ["commit_id", "stage_idx", "created_at"], name: "index_ci_builds_on_commit_id_and_stage_idx_and_created_at", using: :btree
- t.index ["commit_id", "status", "type"], name: "index_ci_builds_on_commit_id_and_status_and_type", using: :btree
- t.index ["commit_id", "type", "name", "ref"], name: "index_ci_builds_on_commit_id_and_type_and_name_and_ref", using: :btree
- t.index ["commit_id", "type", "ref"], name: "index_ci_builds_on_commit_id_and_type_and_ref", using: :btree
- t.index ["project_id", "id"], name: "index_ci_builds_on_project_id_and_id", using: :btree
- t.index ["protected"], name: "index_ci_builds_on_protected", using: :btree
- t.index ["runner_id"], name: "index_ci_builds_on_runner_id", using: :btree
- t.index ["stage_id"], name: "index_ci_builds_on_stage_id", using: :btree
- t.index ["status", "type", "runner_id"], name: "index_ci_builds_on_status_and_type_and_runner_id", using: :btree
- t.index ["status"], name: "index_ci_builds_on_status", using: :btree
- t.index ["token"], name: "index_ci_builds_on_token", unique: true, using: :btree
- t.index ["updated_at"], name: "index_ci_builds_on_updated_at", using: :btree
- t.index ["user_id"], name: "index_ci_builds_on_user_id", using: :btree
- end
- create_table "ci_group_variables", id: :serial do |t|
- t.string "key", null: false
- t.text "value"
- t.text "encrypted_value"
- t.string "encrypted_value_salt"
- t.string "encrypted_value_iv"
- t.integer "group_id", null: false
- t.boolean "protected", default: false, null: false
- t.datetime_with_timezone "created_at", null: false
- t.datetime_with_timezone "updated_at", null: false
- t.index ["group_id", "key"], name: "index_ci_group_variables_on_group_id_and_key", unique: true, using: :btree
- end
- create_table "ci_job_artifacts", id: :serial do |t|
- t.integer "project_id", null: false
- t.integer "job_id", null: false
- t.integer "file_type", null: false
- t.bigint "size"
- t.datetime_with_timezone "created_at", null: false
- t.datetime_with_timezone "updated_at", null: false
- t.datetime_with_timezone "expire_at"
- t.string "file"
- t.integer "file_store"
- t.index ["job_id", "file_type"], name: "index_ci_job_artifacts_on_job_id_and_file_type", unique: true, using: :btree
- t.index ["project_id"], name: "index_ci_job_artifacts_on_project_id", using: :btree
- end
- create_table "ci_pipeline_schedule_variables", id: :serial do |t|
- t.string "key", null: false
- t.text "value"
- t.text "encrypted_value"
- t.string "encrypted_value_salt"
- t.string "encrypted_value_iv"
- t.integer "pipeline_schedule_id", null: false
- t.datetime_with_timezone "created_at"
- t.datetime_with_timezone "updated_at"
- t.index ["pipeline_schedule_id", "key"], name: "index_ci_pipeline_schedule_variables_on_schedule_id_and_key", unique: true, using: :btree
- end
- create_table "ci_pipeline_schedules", id: :serial do |t|
- t.string "description"
- t.string "ref"
- t.string "cron"
- t.string "cron_timezone"
- t.datetime "next_run_at"
- t.integer "project_id"
- t.integer "owner_id"
- t.boolean "active", default: true
- t.datetime "created_at"
- t.datetime "updated_at"
- t.index ["next_run_at", "active"], name: "index_ci_pipeline_schedules_on_next_run_at_and_active", using: :btree
- t.index ["project_id"], name: "index_ci_pipeline_schedules_on_project_id", using: :btree
- end
- create_table "ci_pipeline_variables", id: :serial do |t|
- t.string "key", null: false
- t.text "value"
- t.text "encrypted_value"
- t.string "encrypted_value_salt"
- t.string "encrypted_value_iv"
- t.integer "pipeline_id", null: false
- t.index ["pipeline_id", "key"], name: "index_ci_pipeline_variables_on_pipeline_id_and_key", unique: true, using: :btree
- end
- create_table "ci_pipelines", id: :serial do |t|
- t.string "ref"
- t.string "sha"
- t.string "before_sha"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.boolean "tag", default: false
- t.text "yaml_errors"
- t.datetime "committed_at"
- t.integer "project_id"
- t.string "status"
- t.datetime "started_at"
- t.datetime "finished_at"
- t.integer "duration"
- t.integer "user_id"
- t.integer "lock_version"
- t.integer "auto_canceled_by_id"
- t.integer "pipeline_schedule_id"
- t.integer "source"
- t.boolean "protected"
- t.integer "config_source"
- t.integer "failure_reason"
- t.index ["auto_canceled_by_id"], name: "index_ci_pipelines_on_auto_canceled_by_id", using: :btree
- t.index ["pipeline_schedule_id"], name: "index_ci_pipelines_on_pipeline_schedule_id", using: :btree
- t.index ["project_id", "ref", "status", "id"], name: "index_ci_pipelines_on_project_id_and_ref_and_status_and_id", using: :btree
- t.index ["project_id", "sha"], name: "index_ci_pipelines_on_project_id_and_sha", using: :btree
- t.index ["project_id"], name: "index_ci_pipelines_on_project_id", using: :btree
- t.index ["status"], name: "index_ci_pipelines_on_status", using: :btree
- t.index ["user_id"], name: "index_ci_pipelines_on_user_id", using: :btree
- end
- create_table "ci_runner_namespaces", id: :serial do |t|
- t.integer "runner_id"
- t.integer "namespace_id"
- t.index ["namespace_id"], name: "index_ci_runner_namespaces_on_namespace_id", using: :btree
- t.index ["runner_id", "namespace_id"], name: "index_ci_runner_namespaces_on_runner_id_and_namespace_id", unique: true, using: :btree
- end
- create_table "ci_runner_projects", id: :serial do |t|
- t.integer "runner_id", null: false
- t.datetime "created_at"
- t.datetime "updated_at"
- t.integer "project_id"
- t.index ["project_id"], name: "index_ci_runner_projects_on_project_id", using: :btree
- t.index ["runner_id"], name: "index_ci_runner_projects_on_runner_id", using: :btree
- end
- create_table "ci_runners", id: :serial do |t|
- t.string "token"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.string "description"
- t.datetime "contacted_at"
- t.boolean "active", default: true, null: false
- t.boolean "is_shared", default: false
- t.string "name"
- t.string "version"
- t.string "revision"
- t.string "platform"
- t.string "architecture"
- t.boolean "run_untagged", default: true, null: false
- t.boolean "locked", default: false, null: false
- t.integer "access_level", default: 0, null: false
- t.index ["contacted_at"], name: "index_ci_runners_on_contacted_at", using: :btree
- t.index ["is_shared"], name: "index_ci_runners_on_is_shared", using: :btree
- t.index ["locked"], name: "index_ci_runners_on_locked", using: :btree
- t.index ["token"], name: "index_ci_runners_on_token", using: :btree
- end
- create_table "ci_stages", id: :serial do |t|
- t.integer "project_id"
- t.integer "pipeline_id"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.string "name"
- t.integer "status"
- t.integer "lock_version"
- t.index ["pipeline_id", "name"], name: "index_ci_stages_on_pipeline_id_and_name", using: :btree
- t.index ["pipeline_id"], name: "index_ci_stages_on_pipeline_id", using: :btree
- t.index ["project_id"], name: "index_ci_stages_on_project_id", using: :btree
- end
- create_table "ci_trigger_requests", id: :serial do |t|
- t.integer "trigger_id", null: false
- t.text "variables"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.integer "commit_id"
- t.index ["commit_id"], name: "index_ci_trigger_requests_on_commit_id", using: :btree
- end
- create_table "ci_triggers", id: :serial do |t|
- t.string "token"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.integer "project_id"
- t.integer "owner_id"
- t.string "description"
- t.string "ref"
- t.index ["project_id"], name: "index_ci_triggers_on_project_id", using: :btree
- end
- create_table "ci_variables", id: :serial do |t|
- t.string "key", null: false
- t.text "value"
- t.text "encrypted_value"
- t.string "encrypted_value_salt"
- t.string "encrypted_value_iv"
- t.integer "project_id", null: false
- t.boolean "protected", default: false, null: false
- t.string "environment_scope", default: "*", null: false
- t.index ["project_id", "key", "environment_scope"], name: "index_ci_variables_on_project_id_and_key_and_environment_scope", unique: true, using: :btree
- end
- create_table "cluster_platforms_kubernetes", id: :serial do |t|
- t.integer "cluster_id", null: false
- t.datetime_with_timezone "created_at", null: false
- t.datetime_with_timezone "updated_at", null: false
- t.text "api_url"
- t.text "ca_cert"
- t.string "namespace"
- t.string "username"
- t.text "encrypted_password"
- t.string "encrypted_password_iv"
- t.text "encrypted_token"
- t.string "encrypted_token_iv"
- t.index ["cluster_id"], name: "index_cluster_platforms_kubernetes_on_cluster_id", unique: true, using: :btree
- end
- create_table "cluster_projects", id: :serial do |t|
- t.integer "project_id", null: false
- t.integer "cluster_id", null: false
- t.datetime_with_timezone "created_at", null: false
- t.datetime_with_timezone "updated_at", null: false
- t.index ["cluster_id"], name: "index_cluster_projects_on_cluster_id", using: :btree
- t.index ["project_id"], name: "index_cluster_projects_on_project_id", using: :btree
- end
- create_table "cluster_providers_gcp", id: :serial do |t|
- t.integer "cluster_id", null: false
- t.integer "status"
- t.integer "num_nodes", null: false
- t.datetime_with_timezone "created_at", null: false
- t.datetime_with_timezone "updated_at", null: false
- t.text "status_reason"
- t.string "gcp_project_id", null: false
- t.string "zone", null: false
- t.string "machine_type"
- t.string "operation_id"
- t.string "endpoint"
- t.text "encrypted_access_token"
- t.string "encrypted_access_token_iv"
- t.index ["cluster_id"], name: "index_cluster_providers_gcp_on_cluster_id", unique: true, using: :btree
- end
- create_table "clusters", id: :serial do |t|
- t.integer "user_id"
- t.integer "provider_type"
- t.integer "platform_type"
- t.datetime_with_timezone "created_at", null: false
- t.datetime_with_timezone "updated_at", null: false
- t.boolean "enabled", default: true
- t.string "name", null: false
- t.string "environment_scope", default: "*", null: false
- t.index ["enabled"], name: "index_clusters_on_enabled", using: :btree
- t.index ["user_id"], name: "index_clusters_on_user_id", using: :btree
- end
- create_table "clusters_applications_helm", id: :serial do |t|
- t.integer "cluster_id", null: false
- t.datetime_with_timezone "created_at", null: false
- t.datetime_with_timezone "updated_at", null: false
- t.integer "status", null: false
- t.string "version", null: false
- t.text "status_reason"
- end
- create_table "clusters_applications_ingress", id: :serial do |t|
- t.integer "cluster_id", null: false
- t.datetime_with_timezone "created_at", null: false
- t.datetime_with_timezone "updated_at", null: false
- t.integer "status", null: false
- t.integer "ingress_type", null: false
- t.string "version", null: false
- t.string "cluster_ip"
- t.text "status_reason"
- end
- create_table "clusters_applications_prometheus", id: :serial do |t|
- t.integer "cluster_id", null: false
- t.integer "status", null: false
- t.string "version", null: false
- t.text "status_reason"
- t.datetime_with_timezone "created_at", null: false
- t.datetime_with_timezone "updated_at", null: false
- end
- create_table "container_repositories", id: :serial do |t|
- t.integer "project_id", null: false
- t.string "name", null: false
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.index ["project_id", "name"], name: "index_container_repositories_on_project_id_and_name", unique: true, using: :btree
- t.index ["project_id"], name: "index_container_repositories_on_project_id", using: :btree
- end
- create_table "conversational_development_index_metrics", id: :serial do |t|
- t.float "leader_issues", null: false
- t.float "instance_issues", null: false
- t.float "leader_notes", null: false
- t.float "instance_notes", null: false
- t.float "leader_milestones", null: false
- t.float "instance_milestones", null: false
- t.float "leader_boards", null: false
- t.float "instance_boards", null: false
- t.float "leader_merge_requests", null: false
- t.float "instance_merge_requests", null: false
- t.float "leader_ci_pipelines", null: false
- t.float "instance_ci_pipelines", null: false
- t.float "leader_environments", null: false
- t.float "instance_environments", null: false
- t.float "leader_deployments", null: false
- t.float "instance_deployments", null: false
- t.float "leader_projects_prometheus_active", null: false
- t.float "instance_projects_prometheus_active", null: false
- t.float "leader_service_desk_issues", null: false
- t.float "instance_service_desk_issues", null: false
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.float "percentage_boards", default: 0.0, null: false
- t.float "percentage_ci_pipelines", default: 0.0, null: false
- t.float "percentage_deployments", default: 0.0, null: false
- t.float "percentage_environments", default: 0.0, null: false
- t.float "percentage_issues", default: 0.0, null: false
- t.float "percentage_merge_requests", default: 0.0, null: false
- t.float "percentage_milestones", default: 0.0, null: false
- t.float "percentage_notes", default: 0.0, null: false
- t.float "percentage_projects_prometheus_active", default: 0.0, null: false
- t.float "percentage_service_desk_issues", default: 0.0, null: false
- end
- create_table "deploy_keys_projects", id: :serial do |t|
- t.integer "deploy_key_id", null: false
- t.integer "project_id", null: false
- t.datetime "created_at"
- t.datetime "updated_at"
- t.boolean "can_push", default: false, null: false
- t.index ["project_id"], name: "index_deploy_keys_projects_on_project_id", using: :btree
- end
- create_table "deployments", id: :serial do |t|
- t.integer "iid", null: false
- t.integer "project_id", null: false
- t.integer "environment_id", null: false
- t.string "ref", null: false
- t.boolean "tag", null: false
- t.string "sha", null: false
- t.integer "user_id"
- t.integer "deployable_id"
- t.string "deployable_type"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.string "on_stop"
- t.index ["created_at"], name: "index_deployments_on_created_at", using: :btree
- t.index ["environment_id", "id"], name: "index_deployments_on_environment_id_and_id", using: :btree
- t.index ["environment_id", "iid", "project_id"], name: "index_deployments_on_environment_id_and_iid_and_project_id", using: :btree
- t.index ["project_id", "iid"], name: "index_deployments_on_project_id_and_iid", unique: true, using: :btree
- end
- create_table "emails", id: :serial do |t|
- t.integer "user_id", null: false
- t.string "email", null: false
- t.datetime "created_at"
- t.datetime "updated_at"
- t.string "confirmation_token"
- t.datetime_with_timezone "confirmed_at"
- t.datetime_with_timezone "confirmation_sent_at"
- t.index ["confirmation_token"], name: "index_emails_on_confirmation_token", unique: true, using: :btree
- t.index ["email"], name: "index_emails_on_email", unique: true, using: :btree
- t.index ["user_id"], name: "index_emails_on_user_id", using: :btree
- end
- create_table "environments", id: :serial do |t|
- t.integer "project_id", null: false
- t.string "name", null: false
- t.datetime "created_at"
- t.datetime "updated_at"
- t.string "external_url"
- t.string "environment_type"
- t.string "state", default: "available", null: false
- t.string "slug", null: false
- t.index ["project_id", "name"], name: "index_environments_on_project_id_and_name", unique: true, using: :btree
- t.index ["project_id", "slug"], name: "index_environments_on_project_id_and_slug", unique: true, using: :btree
- end
- create_table "events", id: :serial do |t|
- t.integer "project_id"
- t.integer "author_id", null: false
- t.integer "target_id"
- t.datetime_with_timezone "created_at", null: false
- t.datetime_with_timezone "updated_at", null: false
- t.integer "action", limit: 2, null: false
- t.string "target_type"
- t.index ["action"], name: "index_events_on_action", using: :btree
- t.index ["author_id"], name: "index_events_on_author_id", using: :btree
- t.index ["project_id", "id"], name: "index_events_on_project_id_and_id", using: :btree
- t.index ["target_type", "target_id"], name: "index_events_on_target_type_and_target_id", using: :btree
- end
- create_table "feature_gates", id: :serial do |t|
- t.string "feature_key", null: false
- t.string "key", null: false
- t.string "value"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.index ["feature_key", "key", "value"], name: "index_feature_gates_on_feature_key_and_key_and_value", unique: true, using: :btree
- end
- create_table "features", id: :serial do |t|
- t.string "key", null: false
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.index ["key"], name: "index_features_on_key", unique: true, using: :btree
- end
- create_table "fork_network_members", id: :serial do |t|
- t.integer "fork_network_id", null: false
- t.integer "project_id", null: false
- t.integer "forked_from_project_id"
- t.index ["fork_network_id"], name: "index_fork_network_members_on_fork_network_id", using: :btree
- t.index ["project_id"], name: "index_fork_network_members_on_project_id", unique: true, using: :btree
- end
- create_table "fork_networks", id: :serial do |t|
- t.integer "root_project_id"
- t.string "deleted_root_project_name"
- t.index ["root_project_id"], name: "index_fork_networks_on_root_project_id", unique: true, using: :btree
- end
- create_table "forked_project_links", id: :serial do |t|
- t.integer "forked_to_project_id", null: false
- t.integer "forked_from_project_id", null: false
- t.datetime "created_at"
- t.datetime "updated_at"
- t.index ["forked_to_project_id"], name: "index_forked_project_links_on_forked_to_project_id", unique: true, using: :btree
- end
- create_table "gcp_clusters", id: :serial do |t|
- t.integer "project_id", null: false
- t.integer "user_id"
- t.integer "service_id"
- t.integer "status"
- t.integer "gcp_cluster_size", null: false
- t.datetime_with_timezone "created_at", null: false
- t.datetime_with_timezone "updated_at", null: false
- t.boolean "enabled", default: true
- t.text "status_reason"
- t.string "project_namespace"
- t.string "endpoint"
- t.text "ca_cert"
- t.text "encrypted_kubernetes_token"
- t.string "encrypted_kubernetes_token_iv"
- t.string "username"
- t.text "encrypted_password"
- t.string "encrypted_password_iv"
- t.string "gcp_project_id", null: false
- t.string "gcp_cluster_zone", null: false
- t.string "gcp_cluster_name", null: false
- t.string "gcp_machine_type"
- t.string "gcp_operation_id"
- t.text "encrypted_gcp_token"
- t.string "encrypted_gcp_token_iv"
- t.index ["project_id"], name: "index_gcp_clusters_on_project_id", unique: true, using: :btree
- end
- create_table "gpg_key_subkeys", id: :serial do |t|
- t.integer "gpg_key_id", null: false
- t.binary "keyid"
- t.binary "fingerprint"
- t.index ["fingerprint"], name: "index_gpg_key_subkeys_on_fingerprint", unique: true, using: :btree
- t.index ["gpg_key_id"], name: "index_gpg_key_subkeys_on_gpg_key_id", using: :btree
- t.index ["keyid"], name: "index_gpg_key_subkeys_on_keyid", unique: true, using: :btree
- end
- create_table "gpg_keys", id: :serial do |t|
- t.datetime_with_timezone "created_at", null: false
- t.datetime_with_timezone "updated_at", null: false
- t.integer "user_id"
- t.binary "primary_keyid"
- t.binary "fingerprint"
- t.text "key"
- t.index ["fingerprint"], name: "index_gpg_keys_on_fingerprint", unique: true, using: :btree
- t.index ["primary_keyid"], name: "index_gpg_keys_on_primary_keyid", unique: true, using: :btree
- t.index ["user_id"], name: "index_gpg_keys_on_user_id", using: :btree
- end
- create_table "gpg_signatures", id: :serial do |t|
- t.datetime_with_timezone "created_at", null: false
- t.datetime_with_timezone "updated_at", null: false
- t.integer "project_id"
- t.integer "gpg_key_id"
- t.binary "commit_sha"
- t.binary "gpg_key_primary_keyid"
- t.text "gpg_key_user_name"
- t.text "gpg_key_user_email"
- t.integer "verification_status", limit: 2, default: 0, null: false
- t.integer "gpg_key_subkey_id"
- t.index ["commit_sha"], name: "index_gpg_signatures_on_commit_sha", unique: true, using: :btree
- t.index ["gpg_key_id"], name: "index_gpg_signatures_on_gpg_key_id", using: :btree
- t.index ["gpg_key_primary_keyid"], name: "index_gpg_signatures_on_gpg_key_primary_keyid", using: :btree
- t.index ["gpg_key_subkey_id"], name: "index_gpg_signatures_on_gpg_key_subkey_id", using: :btree
- t.index ["project_id"], name: "index_gpg_signatures_on_project_id", using: :btree
- end
- create_table "group_custom_attributes", id: :serial do |t|
- t.datetime_with_timezone "created_at", null: false
- t.datetime_with_timezone "updated_at", null: false
- t.integer "group_id", null: false
- t.string "key", null: false
- t.string "value", null: false
- t.index ["group_id", "key"], name: "index_group_custom_attributes_on_group_id_and_key", unique: true, using: :btree
- t.index ["key", "value"], name: "index_group_custom_attributes_on_key_and_value", using: :btree
- end
- create_table "identities", id: :serial do |t|
- t.string "extern_uid"
- t.string "provider"
- t.integer "user_id"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.index ["user_id"], name: "index_identities_on_user_id", using: :btree
- end
- create_table "issue_assignees", id: false do |t|
- t.integer "user_id", null: false
- t.integer "issue_id", null: false
- t.index ["issue_id", "user_id"], name: "index_issue_assignees_on_issue_id_and_user_id", unique: true, using: :btree
- t.index ["user_id"], name: "index_issue_assignees_on_user_id", using: :btree
- end
- create_table "issue_metrics", id: :serial do |t|
- t.integer "issue_id", null: false
- t.datetime "first_mentioned_in_commit_at"
- t.datetime "first_associated_with_milestone_at"
- t.datetime "first_added_to_board_at"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.index ["issue_id"], name: "index_issue_metrics", using: :btree
- end
- create_table "issues", id: :serial do |t|
- t.string "title"
- t.integer "author_id"
- t.integer "project_id"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.text "description"
- t.integer "milestone_id"
- t.string "state"
- t.integer "iid"
- t.integer "updated_by_id"
- t.boolean "confidential", default: false, null: false
- t.date "due_date"
- t.integer "moved_to_id"
- t.integer "lock_version"
- t.text "title_html"
- t.text "description_html"
- t.integer "time_estimate"
- t.integer "relative_position"
- t.integer "cached_markdown_version"
- t.datetime "last_edited_at"
- t.integer "last_edited_by_id"
- t.boolean "discussion_locked"
- t.datetime_with_timezone "closed_at"
- t.index ["author_id"], name: "index_issues_on_author_id", using: :btree
- t.index ["confidential"], name: "index_issues_on_confidential", using: :btree
- t.index ["description"], name: "index_issues_on_description_trigram", using: :gin, opclass: {"description"=>"gin_trgm_ops"}
- t.index ["milestone_id"], name: "index_issues_on_milestone_id", using: :btree
- t.index ["moved_to_id"], name: "index_issues_on_moved_to_id", where: "(moved_to_id IS NOT NULL)", using: :btree
- t.index ["project_id", "created_at", "id", "state"], name: "index_issues_on_project_id_and_created_at_and_id_and_state", using: :btree
- t.index ["project_id", "due_date", "id", "state"], name: "idx_issues_on_project_id_and_due_date_and_id_and_state_partial", where: "(due_date IS NOT NULL)", using: :btree
- t.index ["project_id", "iid"], name: "index_issues_on_project_id_and_iid", unique: true, using: :btree
- t.index ["project_id", "updated_at", "id", "state"], name: "index_issues_on_project_id_and_updated_at_and_id_and_state", using: :btree
- t.index ["relative_position"], name: "index_issues_on_relative_position", using: :btree
- t.index ["state"], name: "index_issues_on_state", using: :btree
- t.index ["title"], name: "index_issues_on_title_trigram", using: :gin, opclass: {"title"=>"gin_trgm_ops"}
- t.index ["updated_by_id"], name: "index_issues_on_updated_by_id", where: "(updated_by_id IS NOT NULL)", using: :btree
- end
- create_table "keys", id: :serial do |t|
- t.integer "user_id"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.text "key"
- t.string "title"
- t.string "type"
- t.string "fingerprint"
- t.boolean "public", default: false, null: false
- t.datetime "last_used_at"
- t.index ["fingerprint"], name: "index_keys_on_fingerprint", unique: true, using: :btree
- t.index ["user_id"], name: "index_keys_on_user_id", using: :btree
- end
- create_table "label_links", id: :serial do |t|
- t.integer "label_id"
- t.integer "target_id"
- t.string "target_type"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.index ["label_id"], name: "index_label_links_on_label_id", using: :btree
- t.index ["target_id", "target_type"], name: "index_label_links_on_target_id_and_target_type", using: :btree
- end
- create_table "label_priorities", id: :serial do |t|
- t.integer "project_id", null: false
- t.integer "label_id", null: false
- t.integer "priority", null: false
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.index ["priority"], name: "index_label_priorities_on_priority", using: :btree
- t.index ["project_id", "label_id"], name: "index_label_priorities_on_project_id_and_label_id", unique: true, using: :btree
- end
- create_table "labels", id: :serial do |t|
- t.string "title"
- t.string "color"
- t.integer "project_id"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.boolean "template", default: false
- t.string "description"
- t.text "description_html"
- t.string "type"
- t.integer "group_id"
- t.integer "cached_markdown_version"
- t.index ["group_id", "project_id", "title"], name: "index_labels_on_group_id_and_project_id_and_title", unique: true, using: :btree
- t.index ["project_id"], name: "index_labels_on_project_id", using: :btree
- t.index ["template"], name: "index_labels_on_template", where: "template", using: :btree
- t.index ["title"], name: "index_labels_on_title", using: :btree
- t.index ["type", "project_id"], name: "index_labels_on_type_and_project_id", using: :btree
- end
- create_table "lfs_objects", id: :serial do |t|
- t.string "oid", null: false
- t.bigint "size", null: false
- t.datetime "created_at"
- t.datetime "updated_at"
- t.string "file"
- t.integer "file_store"
- t.index ["oid"], name: "index_lfs_objects_on_oid", unique: true, using: :btree
- end
- create_table "lfs_objects_projects", id: :serial do |t|
- t.integer "lfs_object_id", null: false
- t.integer "project_id", null: false
- t.datetime "created_at"
- t.datetime "updated_at"
- t.index ["project_id"], name: "index_lfs_objects_projects_on_project_id", using: :btree
- end
- create_table "lists", id: :serial do |t|
- t.integer "board_id", null: false
- t.integer "label_id"
- t.integer "list_type", default: 1, null: false
- t.integer "position"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.index ["board_id", "label_id"], name: "index_lists_on_board_id_and_label_id", unique: true, using: :btree
- t.index ["label_id"], name: "index_lists_on_label_id", using: :btree
- end
- create_table "members", id: :serial do |t|
- t.integer "access_level", null: false
- t.integer "source_id", null: false
- t.string "source_type", null: false
- t.integer "user_id"
- t.integer "notification_level", null: false
- t.string "type"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.integer "created_by_id"
- t.string "invite_email"
- t.string "invite_token"
- t.datetime "invite_accepted_at"
- t.datetime "requested_at"
- t.date "expires_at"
- t.index ["access_level"], name: "index_members_on_access_level", using: :btree
- t.index ["invite_token"], name: "index_members_on_invite_token", unique: true, using: :btree
- t.index ["requested_at"], name: "index_members_on_requested_at", using: :btree
- t.index ["source_id", "source_type"], name: "index_members_on_source_id_and_source_type", using: :btree
- t.index ["user_id"], name: "index_members_on_user_id", using: :btree
- end
- create_table "merge_request_diff_commits", id: false do |t|
- t.datetime_with_timezone "authored_date"
- t.datetime_with_timezone "committed_date"
- t.integer "merge_request_diff_id", null: false
- t.integer "relative_order", null: false
- t.binary "sha", null: false
- t.text "author_name"
- t.text "author_email"
- t.text "committer_name"
- t.text "committer_email"
- t.text "message"
- t.index ["merge_request_diff_id", "relative_order"], name: "index_merge_request_diff_commits_on_mr_diff_id_and_order", unique: true, using: :btree
- t.index ["sha"], name: "index_merge_request_diff_commits_on_sha", using: :btree
- end
- create_table "merge_request_diff_files", id: false do |t|
- t.integer "merge_request_diff_id", null: false
- t.integer "relative_order", null: false
- t.boolean "new_file", null: false
- t.boolean "renamed_file", null: false
- t.boolean "deleted_file", null: false
- t.boolean "too_large", null: false
- t.string "a_mode", null: false
- t.string "b_mode", null: false
- t.text "new_path", null: false
- t.text "old_path", null: false
- t.text "diff", null: false
- t.boolean "binary"
- t.index ["merge_request_diff_id", "relative_order"], name: "index_merge_request_diff_files_on_mr_diff_id_and_order", unique: true, using: :btree
- end
- create_table "merge_request_diffs", id: :serial do |t|
- t.string "state"
- t.integer "merge_request_id", null: false
- t.datetime "created_at"
- t.datetime "updated_at"
- t.string "base_commit_sha"
- t.string "real_size"
- t.string "head_commit_sha"
- t.string "start_commit_sha"
- t.index ["merge_request_id", "id"], name: "index_merge_request_diffs_on_merge_request_id_and_id", using: :btree
- end
- create_table "merge_request_metrics", id: :serial do |t|
- t.integer "merge_request_id", null: false
- t.datetime "latest_build_started_at"
- t.datetime "latest_build_finished_at"
- t.datetime "first_deployed_to_production_at"
- t.datetime "merged_at"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.integer "pipeline_id"
- t.integer "merged_by_id"
- t.integer "latest_closed_by_id"
- t.datetime_with_timezone "latest_closed_at"
- t.index ["first_deployed_to_production_at"], name: "index_merge_request_metrics_on_first_deployed_to_production_at", using: :btree
- t.index ["merge_request_id"], name: "index_merge_request_metrics", using: :btree
- t.index ["pipeline_id"], name: "index_merge_request_metrics_on_pipeline_id", using: :btree
- end
- create_table "merge_requests", id: :serial do |t|
- t.string "target_branch", null: false
- t.string "source_branch", null: false
- t.integer "source_project_id"
- t.integer "author_id"
- t.integer "assignee_id"
- t.string "title"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.integer "milestone_id"
- t.string "state", default: "opened", null: false
- t.string "merge_status", default: "unchecked", null: false
- t.integer "target_project_id", null: false
- t.integer "iid"
- t.text "description"
- t.integer "updated_by_id"
- t.text "merge_error"
- t.text "merge_params"
- t.boolean "merge_when_pipeline_succeeds", default: false, null: false
- t.integer "merge_user_id"
- t.string "merge_commit_sha"
- t.string "rebase_commit_sha"
- t.string "in_progress_merge_commit_sha"
- t.integer "lock_version"
- t.text "title_html"
- t.text "description_html"
- t.integer "time_estimate"
- t.integer "cached_markdown_version"
- t.datetime "last_edited_at"
- t.integer "last_edited_by_id"
- t.integer "head_pipeline_id"
- t.string "merge_jid"
- t.boolean "discussion_locked"
- t.integer "latest_merge_request_diff_id"
- t.index ["assignee_id"], name: "index_merge_requests_on_assignee_id", using: :btree
- t.index ["author_id"], name: "index_merge_requests_on_author_id", using: :btree
- t.index ["created_at"], name: "index_merge_requests_on_created_at", using: :btree
- t.index ["description"], name: "index_merge_requests_on_description_trigram", using: :gin, opclass: {"description"=>"gin_trgm_ops"}
- t.index ["head_pipeline_id"], name: "index_merge_requests_on_head_pipeline_id", using: :btree
- t.index ["latest_merge_request_diff_id"], name: "index_merge_requests_on_latest_merge_request_diff_id", using: :btree
- t.index ["merge_user_id"], name: "index_merge_requests_on_merge_user_id", where: "(merge_user_id IS NOT NULL)", using: :btree
- t.index ["milestone_id"], name: "index_merge_requests_on_milestone_id", using: :btree
- t.index ["source_branch"], name: "index_merge_requests_on_source_branch", using: :btree
- t.index ["source_project_id", "source_branch"], name: "index_merge_requests_on_source_project_and_branch_state_opened", where: "((state)::text = 'opened'::text)", using: :btree
- t.index ["source_project_id", "source_branch"], name: "index_merge_requests_on_source_project_id_and_source_branch", using: :btree
- t.index ["target_branch"], name: "index_merge_requests_on_target_branch", using: :btree
- t.index ["target_project_id", "iid"], name: "index_merge_requests_on_target_project_id_and_iid", unique: true, using: :btree
- t.index ["target_project_id", "merge_commit_sha", "id"], name: "index_merge_requests_on_tp_id_and_merge_commit_sha_and_id", using: :btree
- t.index ["title"], name: "index_merge_requests_on_title", using: :btree
- t.index ["title"], name: "index_merge_requests_on_title_trigram", using: :gin, opclass: {"title"=>"gin_trgm_ops"}
- t.index ["updated_by_id"], name: "index_merge_requests_on_updated_by_id", where: "(updated_by_id IS NOT NULL)", using: :btree
- end
- create_table "merge_requests_closing_issues", id: :serial do |t|
- t.integer "merge_request_id", null: false
- t.integer "issue_id", null: false
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.index ["issue_id"], name: "index_merge_requests_closing_issues_on_issue_id", using: :btree
- t.index ["merge_request_id"], name: "index_merge_requests_closing_issues_on_merge_request_id", using: :btree
- end
- create_table "milestones", id: :serial do |t|
- t.string "title", null: false
- t.integer "project_id"
- t.text "description"
- t.date "due_date"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.string "state"
- t.integer "iid"
- t.text "title_html"
- t.text "description_html"
- t.date "start_date"
- t.integer "cached_markdown_version"
- t.integer "group_id"
- t.index ["description"], name: "index_milestones_on_description_trigram", using: :gin, opclass: {"description"=>"gin_trgm_ops"}
- t.index ["due_date"], name: "index_milestones_on_due_date", using: :btree
- t.index ["group_id"], name: "index_milestones_on_group_id", using: :btree
- t.index ["project_id", "iid"], name: "index_milestones_on_project_id_and_iid", unique: true, using: :btree
- t.index ["title"], name: "index_milestones_on_title", using: :btree
- t.index ["title"], name: "index_milestones_on_title_trigram", using: :gin, opclass: {"title"=>"gin_trgm_ops"}
- end
- create_table "namespaces", id: :serial do |t|
- t.string "name", null: false
- t.string "path", null: false
- t.integer "owner_id"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.string "type"
- t.string "description", default: "", null: false
- t.string "avatar"
- t.boolean "share_with_group_lock", default: false
- t.integer "visibility_level", default: 20, null: false
- t.boolean "request_access_enabled", default: false, null: false
- t.text "description_html"
- t.boolean "lfs_enabled"
- t.integer "parent_id"
- t.boolean "require_two_factor_authentication", default: false, null: false
- t.integer "two_factor_grace_period", default: 48, null: false
- t.integer "cached_markdown_version"
- t.string "runners_token"
- t.index ["created_at"], name: "index_namespaces_on_created_at", using: :btree
- t.index ["name", "parent_id"], name: "index_namespaces_on_name_and_parent_id", unique: true, using: :btree
- t.index ["name"], name: "index_namespaces_on_name_trigram", using: :gin, opclass: {"name"=>"gin_trgm_ops"}
- t.index ["owner_id"], name: "index_namespaces_on_owner_id", using: :btree
- t.index ["parent_id", "id"], name: "index_namespaces_on_parent_id_and_id", unique: true, using: :btree
- t.index ["path"], name: "index_namespaces_on_path", using: :btree
- t.index ["path"], name: "index_namespaces_on_path_trigram", using: :gin, opclass: {"path"=>"gin_trgm_ops"}
- t.index ["require_two_factor_authentication"], name: "index_namespaces_on_require_two_factor_authentication", using: :btree
- t.index ["type"], name: "index_namespaces_on_type", using: :btree
- end
- create_table "notes", id: :serial do |t|
- t.text "note"
- t.string "noteable_type"
- t.integer "author_id"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.integer "project_id"
- t.string "attachment"
- t.string "line_code"
- t.string "commit_id"
- t.integer "noteable_id"
- t.boolean "system", default: false, null: false
- t.text "st_diff"
- t.integer "updated_by_id"
- t.string "type"
- t.text "position"
- t.text "original_position"
- t.datetime "resolved_at"
- t.integer "resolved_by_id"
- t.string "discussion_id"
- t.text "note_html"
- t.integer "cached_markdown_version"
- t.text "change_position"
- t.boolean "resolved_by_push"
- t.index ["author_id"], name: "index_notes_on_author_id", using: :btree
- t.index ["commit_id"], name: "index_notes_on_commit_id", using: :btree
- t.index ["created_at"], name: "index_notes_on_created_at", using: :btree
- t.index ["discussion_id"], name: "index_notes_on_discussion_id", using: :btree
- t.index ["line_code"], name: "index_notes_on_line_code", using: :btree
- t.index ["note"], name: "index_notes_on_note_trigram", using: :gin, opclass: {"note"=>"gin_trgm_ops"}
- t.index ["noteable_id", "noteable_type"], name: "index_notes_on_noteable_id_and_noteable_type", using: :btree
- t.index ["noteable_type"], name: "index_notes_on_noteable_type", using: :btree
- t.index ["project_id", "noteable_type"], name: "index_notes_on_project_id_and_noteable_type", using: :btree
- t.index ["updated_at"], name: "index_notes_on_updated_at", using: :btree
- end
- create_table "notification_settings", id: :serial do |t|
- t.integer "user_id", null: false
- t.string "source_type"
- t.integer "source_id"
- t.integer "level", default: 0, null: false
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.boolean "new_note"
- t.boolean "new_issue"
- t.boolean "reopen_issue"
- t.boolean "close_issue"
- t.boolean "reassign_issue"
- t.boolean "new_merge_request"
- t.boolean "reopen_merge_request"
- t.boolean "close_merge_request"
- t.boolean "reassign_merge_request"
- t.boolean "merge_merge_request"
- t.boolean "failed_pipeline"
- t.boolean "success_pipeline"
- t.index ["source_id", "source_type"], name: "index_notification_settings_on_source_id_and_source_type", using: :btree
- t.index ["user_id", "source_id", "source_type"], name: "index_notifications_on_user_id_and_source_id_and_source_type", unique: true, using: :btree
- t.index ["user_id"], name: "index_notification_settings_on_user_id", using: :btree
- end
- create_table "oauth_access_grants", id: :serial do |t|
- t.integer "resource_owner_id", null: false
- t.integer "application_id", null: false
- t.string "token", null: false
- t.integer "expires_in", null: false
- t.text "redirect_uri", null: false
- t.datetime "created_at", null: false
- t.datetime "revoked_at"
- t.string "scopes"
- t.index ["token"], name: "index_oauth_access_grants_on_token", unique: true, using: :btree
- end
- create_table "oauth_access_tokens", id: :serial do |t|
- t.integer "resource_owner_id"
- t.integer "application_id"
- t.string "token", null: false
- t.string "refresh_token"
- t.integer "expires_in"
- t.datetime "revoked_at"
- t.datetime "created_at", null: false
- t.string "scopes"
- t.index ["refresh_token"], name: "index_oauth_access_tokens_on_refresh_token", unique: true, using: :btree
- t.index ["resource_owner_id"], name: "index_oauth_access_tokens_on_resource_owner_id", using: :btree
- t.index ["token"], name: "index_oauth_access_tokens_on_token", unique: true, using: :btree
- end
- create_table "oauth_applications", id: :serial do |t|
- t.string "name", null: false
- t.string "uid", null: false
- t.string "secret", null: false
- t.text "redirect_uri", null: false
- t.string "scopes", default: "", null: false
- t.datetime "created_at"
- t.datetime "updated_at"
- t.integer "owner_id"
- t.string "owner_type"
- t.boolean "trusted", default: false, null: false
- t.index ["owner_id", "owner_type"], name: "index_oauth_applications_on_owner_id_and_owner_type", using: :btree
- t.index ["uid"], name: "index_oauth_applications_on_uid", unique: true, using: :btree
- end
- create_table "oauth_openid_requests", id: :serial do |t|
- t.integer "access_grant_id", null: false
- t.string "nonce", null: false
- end
- create_table "pages_domains", id: :serial do |t|
- t.integer "project_id"
- t.text "certificate"
- t.text "encrypted_key"
- t.string "encrypted_key_iv"
- t.string "encrypted_key_salt"
- t.string "domain"
- t.index ["domain"], name: "index_pages_domains_on_domain", unique: true, using: :btree
- t.index ["project_id"], name: "index_pages_domains_on_project_id", using: :btree
- end
- create_table "personal_access_tokens", id: :serial do |t|
- t.integer "user_id", null: false
- t.string "token", null: false
- t.string "name", null: false
- t.boolean "revoked", default: false
- t.date "expires_at"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.string "scopes", default: "--- []\n", null: false
- t.boolean "impersonation", default: false, null: false
- t.index ["token"], name: "index_personal_access_tokens_on_token", unique: true, using: :btree
- t.index ["user_id"], name: "index_personal_access_tokens_on_user_id", using: :btree
- end
- create_table "project_authorizations", id: false do |t|
- t.integer "user_id"
- t.integer "project_id"
- t.integer "access_level"
- t.index ["project_id"], name: "index_project_authorizations_on_project_id", using: :btree
- t.index ["user_id", "project_id", "access_level"], name: "index_project_authorizations_on_user_id_project_id_access_level", unique: true, using: :btree
- end
- create_table "project_auto_devops", id: :serial do |t|
- t.integer "project_id", null: false
- t.datetime_with_timezone "created_at", null: false
- t.datetime_with_timezone "updated_at", null: false
- t.boolean "enabled"
- t.string "domain"
- t.index ["project_id"], name: "index_project_auto_devops_on_project_id", unique: true, using: :btree
- end
- create_table "project_custom_attributes", id: :serial do |t|
- t.datetime_with_timezone "created_at", null: false
- t.datetime_with_timezone "updated_at", null: false
- t.integer "project_id", null: false
- t.string "key", null: false
- t.string "value", null: false
- t.index ["key", "value"], name: "index_project_custom_attributes_on_key_and_value", using: :btree
- t.index ["project_id", "key"], name: "index_project_custom_attributes_on_project_id_and_key", unique: true, using: :btree
- end
- create_table "project_features", id: :serial do |t|
- t.integer "project_id"
- t.integer "merge_requests_access_level"
- t.integer "issues_access_level"
- t.integer "wiki_access_level"
- t.integer "snippets_access_level"
- t.integer "builds_access_level"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.integer "repository_access_level", default: 20, null: false
- t.index ["project_id"], name: "index_project_features_on_project_id", using: :btree
- end
- create_table "project_group_links", id: :serial do |t|
- t.integer "project_id", null: false
- t.integer "group_id", null: false
- t.datetime "created_at"
- t.datetime "updated_at"
- t.integer "group_access", default: 30, null: false
- t.date "expires_at"
- t.index ["group_id"], name: "index_project_group_links_on_group_id", using: :btree
- t.index ["project_id"], name: "index_project_group_links_on_project_id", using: :btree
- end
- create_table "project_import_data", id: :serial do |t|
- t.integer "project_id"
- t.text "data"
- t.text "encrypted_credentials"
- t.string "encrypted_credentials_iv"
- t.string "encrypted_credentials_salt"
- t.index ["project_id"], name: "index_project_import_data_on_project_id", using: :btree
- end
- create_table "project_statistics", id: :serial do |t|
- t.integer "project_id", null: false
- t.integer "namespace_id", null: false
- t.bigint "commit_count", default: 0, null: false
- t.bigint "storage_size", default: 0, null: false
- t.bigint "repository_size", default: 0, null: false
- t.bigint "lfs_objects_size", default: 0, null: false
- t.bigint "build_artifacts_size", default: 0, null: false
- t.index ["namespace_id"], name: "index_project_statistics_on_namespace_id", using: :btree
- t.index ["project_id"], name: "index_project_statistics_on_project_id", unique: true, using: :btree
- end
- create_table "projects", id: :serial do |t|
- t.string "name"
- t.string "path"
- t.text "description"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.integer "creator_id"
- t.integer "namespace_id"
- t.datetime "last_activity_at"
- t.string "import_url"
- t.integer "visibility_level", default: 0, null: false
- t.boolean "archived", default: false, null: false
- t.string "avatar"
- t.string "import_status"
- t.integer "star_count", default: 0, null: false
- t.boolean "merge_requests_rebase_enabled", default: false, null: false
- t.string "import_type"
- t.string "import_source"
- t.boolean "merge_requests_ff_only_enabled", default: false, null: false
- t.text "import_error"
- t.integer "ci_id"
- t.boolean "shared_runners_enabled", default: true, null: false
- t.string "runners_token"
- t.string "build_coverage_regex"
- t.boolean "build_allow_git_fetch", default: true, null: false
- t.integer "build_timeout", default: 3600, null: false
- t.boolean "pending_delete", default: false
- t.boolean "public_builds", default: true, null: false
- t.boolean "last_repository_check_failed"
- t.datetime "last_repository_check_at"
- t.boolean "container_registry_enabled"
- t.boolean "only_allow_merge_if_pipeline_succeeds", default: false, null: false
- t.boolean "has_external_issue_tracker"
- t.string "repository_storage", default: "default", null: false
- t.boolean "repository_read_only"
- t.boolean "request_access_enabled", default: false, null: false
- t.boolean "has_external_wiki"
- t.string "ci_config_path"
- t.boolean "lfs_enabled"
- t.text "description_html"
- t.boolean "only_allow_merge_if_all_discussions_are_resolved"
- t.boolean "printing_merge_request_link_enabled", default: true, null: false
- t.integer "auto_cancel_pending_pipelines", default: 1, null: false
- t.string "import_jid"
- t.integer "cached_markdown_version"
- t.text "delete_error"
- t.datetime "last_repository_updated_at"
- t.integer "storage_version", limit: 2
- t.boolean "resolve_outdated_diff_discussions"
- t.string "external_authorization_classification_label"
- t.integer "jobs_cache_index"
- t.index ["ci_id"], name: "index_projects_on_ci_id", using: :btree
- t.index ["created_at"], name: "index_projects_on_created_at", using: :btree
- t.index ["creator_id"], name: "index_projects_on_creator_id", using: :btree
- t.index ["description"], name: "index_projects_on_description_trigram", using: :gin, opclass: {"description"=>"gin_trgm_ops"}
- t.index ["last_activity_at"], name: "index_projects_on_last_activity_at", using: :btree
- t.index ["last_repository_check_failed"], name: "index_projects_on_last_repository_check_failed", using: :btree
- t.index ["last_repository_updated_at"], name: "index_projects_on_last_repository_updated_at", using: :btree
- t.index ["name"], name: "index_projects_on_name_trigram", using: :gin, opclass: {"name"=>"gin_trgm_ops"}
- t.index ["namespace_id"], name: "index_projects_on_namespace_id", using: :btree
- t.index ["path"], name: "index_projects_on_path", using: :btree
- t.index ["path"], name: "index_projects_on_path_trigram", using: :gin, opclass: {"path"=>"gin_trgm_ops"}
- t.index ["pending_delete"], name: "index_projects_on_pending_delete", using: :btree
- t.index ["repository_storage"], name: "index_projects_on_repository_storage", using: :btree
- t.index ["runners_token"], name: "index_projects_on_runners_token", using: :btree
- t.index ["star_count"], name: "index_projects_on_star_count", using: :btree
- t.index ["visibility_level"], name: "index_projects_on_visibility_level", using: :btree
- end
- create_table "protected_branch_merge_access_levels", id: :serial do |t|
- t.integer "protected_branch_id", null: false
- t.integer "access_level", default: 40, null: false
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.index ["protected_branch_id"], name: "index_protected_branch_merge_access", using: :btree
- end
- create_table "protected_branch_push_access_levels", id: :serial do |t|
- t.integer "protected_branch_id", null: false
- t.integer "access_level", default: 40, null: false
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.index ["protected_branch_id"], name: "index_protected_branch_push_access", using: :btree
- end
- create_table "protected_branches", id: :serial do |t|
- t.integer "project_id", null: false
- t.string "name", null: false
- t.datetime "created_at"
- t.datetime "updated_at"
- t.index ["project_id"], name: "index_protected_branches_on_project_id", using: :btree
- end
- create_table "protected_tag_create_access_levels", id: :serial do |t|
- t.integer "protected_tag_id", null: false
- t.integer "access_level", default: 40
- t.integer "user_id"
- t.integer "group_id"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.index ["protected_tag_id"], name: "index_protected_tag_create_access", using: :btree
- t.index ["user_id"], name: "index_protected_tag_create_access_levels_on_user_id", using: :btree
- end
- create_table "protected_tags", id: :serial do |t|
- t.integer "project_id", null: false
- t.string "name", null: false
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.index ["project_id"], name: "index_protected_tags_on_project_id", using: :btree
- end
- create_table "push_event_payloads", id: false do |t|
- t.bigint "commit_count", null: false
- t.integer "event_id", null: false
- t.integer "action", limit: 2, null: false
- t.integer "ref_type", limit: 2, null: false
- t.binary "commit_from"
- t.binary "commit_to"
- t.text "ref"
- t.string "commit_title", limit: 70
- t.index ["event_id"], name: "index_push_event_payloads_on_event_id", unique: true, using: :btree
- end
- create_table "redirect_routes", id: :serial do |t|
- t.integer "source_id", null: false
- t.string "source_type", null: false
- t.string "path", null: false
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.boolean "permanent"
- t.index ["path"], name: "index_redirect_routes_on_path", unique: true, using: :btree
- t.index ["path"], name: "index_redirect_routes_on_path_text_pattern_ops", using: :btree, opclass: {"path"=>"varchar_pattern_ops"}
- t.index ["permanent"], name: "index_redirect_routes_on_permanent", using: :btree
- t.index ["source_type", "source_id"], name: "index_redirect_routes_on_source_type_and_source_id", using: :btree
- end
- create_table "releases", id: :serial do |t|
- t.string "tag"
- t.text "description"
- t.integer "project_id"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.text "description_html"
- t.integer "cached_markdown_version"
- t.index ["project_id", "tag"], name: "index_releases_on_project_id_and_tag", using: :btree
- t.index ["project_id"], name: "index_releases_on_project_id", using: :btree
- end
- create_table "routes", id: :serial do |t|
- t.integer "source_id", null: false
- t.string "source_type", null: false
- t.string "path", null: false
- t.datetime "created_at"
- t.datetime "updated_at"
- t.string "name"
- t.index ["path"], name: "index_routes_on_path", unique: true, using: :btree
- t.index ["path"], name: "index_routes_on_path_text_pattern_ops", using: :btree, opclass: {"path"=>"varchar_pattern_ops"}
- t.index ["source_type", "source_id"], name: "index_routes_on_source_type_and_source_id", unique: true, using: :btree
- end
- create_table "sent_notifications", id: :serial do |t|
- t.integer "project_id"
- t.string "noteable_type"
- t.integer "noteable_id"
- t.integer "recipient_id"
- t.string "commit_id"
- t.string "reply_key", null: false
- t.string "line_code"
- t.string "note_type"
- t.text "position"
- t.string "in_reply_to_discussion_id"
- t.index ["reply_key"], name: "index_sent_notifications_on_reply_key", unique: true, using: :btree
- end
- create_table "services", id: :serial do |t|
- t.string "type"
- t.string "title"
- t.integer "project_id"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.boolean "active", default: false, null: false
- t.text "properties"
- t.boolean "template", default: false
- t.boolean "push_events", default: true
- t.boolean "issues_events", default: true
- t.boolean "merge_requests_events", default: true
- t.boolean "tag_push_events", default: true
- t.boolean "note_events", default: true, null: false
- t.string "category", default: "common", null: false
- t.boolean "default", default: false
- t.boolean "wiki_page_events", default: true
- t.boolean "pipeline_events", default: false, null: false
- t.boolean "confidential_issues_events", default: true, null: false
- t.boolean "commit_events", default: true, null: false
- t.boolean "job_events", default: false, null: false
- t.index ["project_id"], name: "index_services_on_project_id", using: :btree
- t.index ["template"], name: "index_services_on_template", using: :btree
- end
- create_table "snippets", id: :serial do |t|
- t.string "title"
- t.text "content"
- t.integer "author_id", null: false
- t.integer "project_id"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.string "file_name"
- t.string "type"
- t.integer "visibility_level", default: 0, null: false
- t.text "title_html"
- t.text "content_html"
- t.integer "cached_markdown_version"
- t.text "description"
- t.text "description_html"
- t.index ["author_id"], name: "index_snippets_on_author_id", using: :btree
- t.index ["file_name"], name: "index_snippets_on_file_name_trigram", using: :gin, opclass: {"file_name"=>"gin_trgm_ops"}
- t.index ["project_id"], name: "index_snippets_on_project_id", using: :btree
- t.index ["title"], name: "index_snippets_on_title_trigram", using: :gin, opclass: {"title"=>"gin_trgm_ops"}
- t.index ["updated_at"], name: "index_snippets_on_updated_at", using: :btree
- t.index ["visibility_level"], name: "index_snippets_on_visibility_level", using: :btree
- end
- create_table "spam_logs", id: :serial do |t|
- t.integer "user_id"
- t.string "source_ip"
- t.string "user_agent"
- t.boolean "via_api"
- t.string "noteable_type"
- t.string "title"
- t.text "description"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.boolean "submitted_as_ham", default: false, null: false
- t.boolean "recaptcha_verified", default: false, null: false
- end
- create_table "subscriptions", id: :serial do |t|
- t.integer "user_id"
- t.string "subscribable_type"
- t.integer "subscribable_id"
- t.boolean "subscribed"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.integer "project_id"
- t.index ["subscribable_id", "subscribable_type", "user_id", "project_id"], name: "index_subscriptions_on_subscribable_and_user_id_and_project_id", unique: true, using: :btree
- end
- create_table "system_note_metadata", id: :serial do |t|
- t.integer "note_id", null: false
- t.integer "commit_count"
- t.string "action"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.index ["note_id"], name: "index_system_note_metadata_on_note_id", unique: true, using: :btree
- end
- create_table "taggings", id: :serial do |t|
- t.integer "tag_id"
- t.integer "taggable_id"
- t.string "taggable_type"
- t.integer "tagger_id"
- t.string "tagger_type"
- t.string "context"
- t.datetime "created_at"
- t.index ["tag_id", "taggable_id", "taggable_type", "context", "tagger_id", "tagger_type"], name: "taggings_idx", unique: true, using: :btree
- t.index ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context", using: :btree
- end
- create_table "tags", id: :serial do |t|
- t.string "name"
- t.integer "taggings_count", default: 0
- t.index ["name"], name: "index_tags_on_name", unique: true, using: :btree
- end
- create_table "timelogs", id: :serial do |t|
- t.integer "time_spent", null: false
- t.integer "user_id"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.integer "issue_id"
- t.integer "merge_request_id"
- t.datetime_with_timezone "spent_at"
- t.index ["issue_id"], name: "index_timelogs_on_issue_id", using: :btree
- t.index ["merge_request_id"], name: "index_timelogs_on_merge_request_id", using: :btree
- t.index ["user_id"], name: "index_timelogs_on_user_id", using: :btree
- end
- create_table "todos", id: :serial do |t|
- t.integer "user_id", null: false
- t.integer "project_id", null: false
- t.string "target_type", null: false
- t.integer "target_id"
- t.integer "author_id"
- t.integer "action", null: false
- t.string "state", null: false
- t.datetime "created_at"
- t.datetime "updated_at"
- t.integer "note_id"
- t.string "commit_id"
- t.index ["author_id"], name: "index_todos_on_author_id", using: :btree
- t.index ["commit_id"], name: "index_todos_on_commit_id", using: :btree
- t.index ["note_id"], name: "index_todos_on_note_id", using: :btree
- t.index ["project_id"], name: "index_todos_on_project_id", using: :btree
- t.index ["target_type", "target_id"], name: "index_todos_on_target_type_and_target_id", using: :btree
- t.index ["user_id"], name: "index_todos_on_user_id", using: :btree
- end
- create_table "trending_projects", id: :serial do |t|
- t.integer "project_id", null: false
- t.index ["project_id"], name: "index_trending_projects_on_project_id", using: :btree
- end
- create_table "u2f_registrations", id: :serial do |t|
- t.text "certificate"
- t.string "key_handle"
- t.string "public_key"
- t.integer "counter"
- t.integer "user_id"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.string "name"
- t.index ["key_handle"], name: "index_u2f_registrations_on_key_handle", using: :btree
- t.index ["user_id"], name: "index_u2f_registrations_on_user_id", using: :btree
- end
- create_table "uploads", id: :serial do |t|
- t.bigint "size", null: false
- t.string "path", limit: 511, null: false
- t.string "checksum", limit: 64
- t.string "model_type"
- t.integer "model_id"
- t.string "uploader", null: false
- t.datetime "created_at", null: false
- t.integer "store"
- t.index ["checksum"], name: "index_uploads_on_checksum", using: :btree
- t.index ["model_id", "model_type"], name: "index_uploads_on_model_id_and_model_type", using: :btree
- t.index ["path"], name: "index_uploads_on_path", using: :btree
- end
- create_table "user_agent_details", id: :serial do |t|
- t.string "user_agent", null: false
- t.string "ip_address", null: false
- t.integer "subject_id", null: false
- t.string "subject_type", null: false
- t.boolean "submitted", default: false, null: false
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.index ["subject_id", "subject_type"], name: "index_user_agent_details_on_subject_id_and_subject_type", using: :btree
- end
- create_table "user_custom_attributes", id: :serial do |t|
- t.datetime_with_timezone "created_at", null: false
- t.datetime_with_timezone "updated_at", null: false
- t.integer "user_id", null: false
- t.string "key", null: false
- t.string "value", null: false
- t.index ["key", "value"], name: "index_user_custom_attributes_on_key_and_value", using: :btree
- t.index ["user_id", "key"], name: "index_user_custom_attributes_on_user_id_and_key", unique: true, using: :btree
- end
- create_table "user_synced_attributes_metadata", id: :serial do |t|
- t.boolean "name_synced", default: false
- t.boolean "email_synced", default: false
- t.boolean "location_synced", default: false
- t.integer "user_id", null: false
- t.string "provider"
- t.index ["user_id"], name: "index_user_synced_attributes_metadata_on_user_id", unique: true, using: :btree
- end
- create_table "users", id: :serial do |t|
- t.string "email", default: "", null: false
- t.string "encrypted_password", default: "", null: false
- t.string "reset_password_token"
- t.datetime "reset_password_sent_at"
- t.datetime "remember_created_at"
- t.integer "sign_in_count", default: 0
- t.datetime "current_sign_in_at"
- t.datetime "last_sign_in_at"
- t.string "current_sign_in_ip"
- t.string "last_sign_in_ip"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.string "name"
- t.boolean "admin", default: false, null: false
- t.integer "projects_limit", null: false
- t.string "skype", default: "", null: false
- t.string "linkedin", default: "", null: false
- t.string "twitter", default: "", null: false
- t.string "bio"
- t.integer "failed_attempts", default: 0
- t.datetime "locked_at"
- t.string "username"
- t.boolean "can_create_group", default: true, null: false
- t.boolean "can_create_team", default: true, null: false
- t.string "state"
- t.integer "color_scheme_id", default: 1, null: false
- t.datetime "password_expires_at"
- t.integer "created_by_id"
- t.datetime "last_credential_check_at"
- t.string "avatar"
- t.string "confirmation_token"
- t.datetime "confirmed_at"
- t.datetime "confirmation_sent_at"
- t.string "unconfirmed_email"
- t.boolean "hide_no_ssh_key", default: false
- t.string "website_url", default: "", null: false
- t.string "notification_email"
- t.boolean "hide_no_password", default: false
- t.boolean "password_automatically_set", default: false
- t.string "location"
- t.string "encrypted_otp_secret"
- t.string "encrypted_otp_secret_iv"
- t.string "encrypted_otp_secret_salt"
- t.boolean "otp_required_for_login", default: false, null: false
- t.text "otp_backup_codes"
- t.string "public_email", default: "", null: false
- t.integer "dashboard", default: 0
- t.integer "project_view", default: 0
- t.integer "consumed_timestep"
- t.integer "layout", default: 0
- t.boolean "hide_project_limit", default: false
- t.string "unlock_token"
- t.datetime "otp_grace_period_started_at"
- t.boolean "external", default: false
- t.string "incoming_email_token"
- t.string "organization"
- t.boolean "require_two_factor_authentication_from_group", default: false, null: false
- t.integer "two_factor_grace_period", default: 48, null: false
- t.boolean "ghost"
- t.date "last_activity_on"
- t.boolean "notified_of_own_activity"
- t.string "preferred_language"
- t.string "rss_token"
- t.integer "theme_id", limit: 2
- t.index ["admin"], name: "index_users_on_admin", using: :btree
- t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree
- t.index ["created_at"], name: "index_users_on_created_at", using: :btree
- t.index ["email"], name: "index_users_on_email", unique: true, using: :btree
- t.index ["email"], name: "index_users_on_email_trigram", using: :gin, opclass: {"email"=>"gin_trgm_ops"}
- t.index ["ghost"], name: "index_users_on_ghost", using: :btree
- t.index ["incoming_email_token"], name: "index_users_on_incoming_email_token", using: :btree
- t.index ["name"], name: "index_users_on_name", using: :btree
- t.index ["name"], name: "index_users_on_name_trigram", using: :gin, opclass: {"name"=>"gin_trgm_ops"}
- t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
- t.index ["rss_token"], name: "index_users_on_rss_token", using: :btree
- t.index ["state"], name: "index_users_on_state", using: :btree
- t.index ["username"], name: "index_users_on_username", using: :btree
- t.index ["username"], name: "index_users_on_username_trigram", using: :gin, opclass: {"username"=>"gin_trgm_ops"}
- end
- create_table "users_star_projects", id: :serial do |t|
- t.integer "project_id", null: false
- t.integer "user_id", null: false
- t.datetime "created_at"
- t.datetime "updated_at"
- t.index ["project_id"], name: "index_users_star_projects_on_project_id", using: :btree
- t.index ["user_id", "project_id"], name: "index_users_star_projects_on_user_id_and_project_id", unique: true, using: :btree
- end
- create_table "web_hook_logs", id: :serial do |t|
- t.integer "web_hook_id", null: false
- t.string "trigger"
- t.string "url"
- t.text "request_headers"
- t.text "request_data"
- t.text "response_headers"
- t.text "response_body"
- t.string "response_status"
- t.float "execution_duration"
- t.string "internal_error_message"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.index ["web_hook_id"], name: "index_web_hook_logs_on_web_hook_id", using: :btree
- end
- create_table "web_hooks", id: :serial do |t|
- t.string "url", limit: 2000
- t.integer "project_id"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.string "type", default: "ProjectHook"
- t.integer "service_id"
- t.boolean "push_events", default: true, null: false
- t.boolean "issues_events", default: false, null: false
- t.boolean "merge_requests_events", default: false, null: false
- t.boolean "tag_push_events", default: false
- t.boolean "note_events", default: false, null: false
- t.boolean "enable_ssl_verification", default: true
- t.boolean "wiki_page_events", default: false, null: false
- t.string "token"
- t.boolean "pipeline_events", default: false, null: false
- t.boolean "confidential_issues_events", default: false, null: false
- t.boolean "repository_update_events", default: false, null: false
- t.boolean "job_events", default: false, null: false
- t.boolean "confidential_note_events"
- t.index ["project_id"], name: "index_web_hooks_on_project_id", using: :btree
- t.index ["type"], name: "index_web_hooks_on_type", using: :btree
- end
- add_foreign_key "boards", "projects", name: "fk_f15266b5f9", on_delete: :cascade
- add_foreign_key "chat_teams", "namespaces", on_delete: :cascade
- add_foreign_key "ci_build_trace_section_names", "projects", on_delete: :cascade
- add_foreign_key "ci_build_trace_sections", "ci_build_trace_section_names", column: "section_name_id", name: "fk_264e112c66", on_delete: :cascade
- add_foreign_key "ci_build_trace_sections", "ci_builds", column: "build_id", name: "fk_4ebe41f502", on_delete: :cascade
- add_foreign_key "ci_build_trace_sections", "projects", on_delete: :cascade
- add_foreign_key "ci_builds", "ci_pipelines", column: "auto_canceled_by_id", name: "fk_a2141b1522", on_delete: :nullify
- add_foreign_key "ci_builds", "ci_stages", column: "stage_id", name: "fk_3a9eaa254d", on_delete: :cascade
- add_foreign_key "ci_builds", "projects", name: "fk_befce0568a", on_delete: :cascade
- add_foreign_key "ci_group_variables", "namespaces", column: "group_id", name: "fk_33ae4d58d8", on_delete: :cascade
- add_foreign_key "ci_job_artifacts", "ci_builds", column: "job_id", on_delete: :cascade
- add_foreign_key "ci_job_artifacts", "projects", on_delete: :cascade
- add_foreign_key "ci_pipeline_schedule_variables", "ci_pipeline_schedules", column: "pipeline_schedule_id", name: "fk_41c35fda51", on_delete: :cascade
- add_foreign_key "ci_pipeline_schedules", "projects", name: "fk_8ead60fcc4", on_delete: :cascade
- add_foreign_key "ci_pipeline_schedules", "users", column: "owner_id", name: "fk_9ea99f58d2", on_delete: :nullify
- add_foreign_key "ci_pipeline_variables", "ci_pipelines", column: "pipeline_id", name: "fk_f29c5f4380", on_delete: :cascade
- add_foreign_key "ci_pipelines", "ci_pipeline_schedules", column: "pipeline_schedule_id", name: "fk_3d34ab2e06", on_delete: :nullify
- add_foreign_key "ci_pipelines", "ci_pipelines", column: "auto_canceled_by_id", name: "fk_262d4c2d19", on_delete: :nullify
- add_foreign_key "ci_pipelines", "projects", name: "fk_86635dbd80", on_delete: :cascade
- add_foreign_key "ci_runner_namespaces", "ci_runners", column: "runner_id", on_delete: :cascade
- add_foreign_key "ci_runner_namespaces", "namespaces", on_delete: :cascade
- add_foreign_key "ci_runner_projects", "projects", name: "fk_4478a6f1e4", on_delete: :cascade
- add_foreign_key "ci_stages", "ci_pipelines", column: "pipeline_id", name: "fk_fb57e6cc56", on_delete: :cascade
- add_foreign_key "ci_stages", "projects", name: "fk_2360681d1d", on_delete: :cascade
- add_foreign_key "ci_trigger_requests", "ci_triggers", column: "trigger_id", name: "fk_b8ec8b7245", on_delete: :cascade
- add_foreign_key "ci_triggers", "projects", name: "fk_e3e63f966e", on_delete: :cascade
- add_foreign_key "ci_triggers", "users", column: "owner_id", name: "fk_e8e10d1964", on_delete: :cascade
- add_foreign_key "ci_variables", "projects", name: "fk_ada5eb64b3", on_delete: :cascade
- add_foreign_key "cluster_platforms_kubernetes", "clusters", on_delete: :cascade
- add_foreign_key "cluster_projects", "clusters", on_delete: :cascade
- add_foreign_key "cluster_projects", "projects", on_delete: :cascade
- add_foreign_key "cluster_providers_gcp", "clusters", on_delete: :cascade
- add_foreign_key "clusters", "users", on_delete: :nullify
- add_foreign_key "clusters_applications_helm", "clusters", on_delete: :cascade
- add_foreign_key "clusters_applications_ingress", "clusters", on_delete: :cascade
- add_foreign_key "clusters_applications_prometheus", "clusters", on_delete: :cascade
- add_foreign_key "container_repositories", "projects"
- add_foreign_key "deploy_keys_projects", "projects", name: "fk_58a901ca7e", on_delete: :cascade
- add_foreign_key "deployments", "projects", name: "fk_b9a3851b82", on_delete: :cascade
- add_foreign_key "environments", "projects", name: "fk_d1c8c1da6a", on_delete: :cascade
- add_foreign_key "events", "projects", on_delete: :cascade
- add_foreign_key "events", "users", column: "author_id", name: "fk_edfd187b6f", on_delete: :cascade
- add_foreign_key "fork_network_members", "fork_networks", on_delete: :cascade
- add_foreign_key "fork_network_members", "projects", column: "forked_from_project_id", name: "fk_b01280dae4", on_delete: :nullify
- add_foreign_key "fork_network_members", "projects", on_delete: :cascade
- add_foreign_key "fork_networks", "projects", column: "root_project_id", name: "fk_e7b436b2b5", on_delete: :nullify
- add_foreign_key "forked_project_links", "projects", column: "forked_to_project_id", name: "fk_434510edb0", on_delete: :cascade
- add_foreign_key "gcp_clusters", "projects", on_delete: :cascade
- add_foreign_key "gcp_clusters", "services", on_delete: :nullify
- add_foreign_key "gcp_clusters", "users", on_delete: :nullify
- add_foreign_key "gpg_key_subkeys", "gpg_keys", on_delete: :cascade
- add_foreign_key "gpg_keys", "users", on_delete: :cascade
- add_foreign_key "gpg_signatures", "gpg_key_subkeys", on_delete: :nullify
- add_foreign_key "gpg_signatures", "gpg_keys", on_delete: :nullify
- add_foreign_key "gpg_signatures", "projects", on_delete: :cascade
- add_foreign_key "group_custom_attributes", "namespaces", column: "group_id", on_delete: :cascade
- add_foreign_key "issue_assignees", "issues", name: "fk_b7d881734a", on_delete: :cascade
- add_foreign_key "issue_assignees", "users", name: "fk_5e0c8d9154", on_delete: :cascade
- add_foreign_key "issue_metrics", "issues", on_delete: :cascade
- add_foreign_key "issues", "issues", column: "moved_to_id", name: "fk_a194299be1", on_delete: :nullify
- add_foreign_key "issues", "milestones", name: "fk_96b1dd429c", on_delete: :nullify
- add_foreign_key "issues", "projects", name: "fk_899c8f3231", on_delete: :cascade
- add_foreign_key "issues", "users", column: "author_id", name: "fk_05f1e72feb", on_delete: :nullify
- add_foreign_key "issues", "users", column: "updated_by_id", name: "fk_ffed080f01", on_delete: :nullify
- add_foreign_key "label_priorities", "labels", on_delete: :cascade
- add_foreign_key "label_priorities", "projects", on_delete: :cascade
- add_foreign_key "labels", "namespaces", column: "group_id", on_delete: :cascade
- add_foreign_key "labels", "projects", name: "fk_7de4989a69", on_delete: :cascade
- add_foreign_key "lists", "boards", name: "fk_0d3f677137", on_delete: :cascade
- add_foreign_key "lists", "labels", name: "fk_7a5553d60f", on_delete: :cascade
- add_foreign_key "members", "users", name: "fk_2e88fb7ce9", on_delete: :cascade
- add_foreign_key "merge_request_diff_commits", "merge_request_diffs", on_delete: :cascade
- add_foreign_key "merge_request_diff_files", "merge_request_diffs", on_delete: :cascade
- add_foreign_key "merge_request_diffs", "merge_requests", name: "fk_8483f3258f", on_delete: :cascade
- add_foreign_key "merge_request_metrics", "ci_pipelines", column: "pipeline_id", on_delete: :cascade
- add_foreign_key "merge_request_metrics", "merge_requests", on_delete: :cascade
- add_foreign_key "merge_request_metrics", "users", column: "latest_closed_by_id", name: "fk_ae440388cc", on_delete: :nullify
- add_foreign_key "merge_request_metrics", "users", column: "merged_by_id", name: "fk_7f28d925f3", on_delete: :nullify
- add_foreign_key "merge_requests", "ci_pipelines", column: "head_pipeline_id", name: "fk_fd82eae0b9", on_delete: :nullify
- add_foreign_key "merge_requests", "merge_request_diffs", column: "latest_merge_request_diff_id", name: "fk_06067f5644", on_delete: :nullify
- add_foreign_key "merge_requests", "milestones", name: "fk_6a5165a692", on_delete: :nullify
- add_foreign_key "merge_requests", "projects", column: "source_project_id", name: "fk_3308fe130c", on_delete: :nullify
- add_foreign_key "merge_requests", "projects", column: "target_project_id", name: "fk_a6963e8447", on_delete: :cascade
- add_foreign_key "merge_requests", "users", column: "assignee_id", name: "fk_6149611a04", on_delete: :nullify
- add_foreign_key "merge_requests", "users", column: "author_id", name: "fk_e719a85f8a", on_delete: :nullify
- add_foreign_key "merge_requests", "users", column: "merge_user_id", name: "fk_ad525e1f87", on_delete: :nullify
- add_foreign_key "merge_requests", "users", column: "updated_by_id", name: "fk_641731faff", on_delete: :nullify
- add_foreign_key "merge_requests_closing_issues", "issues", on_delete: :cascade
- add_foreign_key "merge_requests_closing_issues", "merge_requests", on_delete: :cascade
- add_foreign_key "milestones", "namespaces", column: "group_id", name: "fk_95650a40d4", on_delete: :cascade
- add_foreign_key "milestones", "projects", name: "fk_9bd0a0c791", on_delete: :cascade
- add_foreign_key "notes", "projects", name: "fk_99e097b079", on_delete: :cascade
- add_foreign_key "oauth_openid_requests", "oauth_access_grants", column: "access_grant_id", name: "fk_oauth_openid_requests_oauth_access_grants_access_grant_id"
- add_foreign_key "pages_domains", "projects", name: "fk_ea2f6dfc6f", on_delete: :cascade
- add_foreign_key "personal_access_tokens", "users"
- add_foreign_key "project_authorizations", "projects", on_delete: :cascade
- add_foreign_key "project_authorizations", "users", on_delete: :cascade
- add_foreign_key "project_auto_devops", "projects", on_delete: :cascade
- add_foreign_key "project_custom_attributes", "projects", on_delete: :cascade
- add_foreign_key "project_features", "projects", name: "fk_18513d9b92", on_delete: :cascade
- add_foreign_key "project_group_links", "projects", name: "fk_daa8cee94c", on_delete: :cascade
- add_foreign_key "project_import_data", "projects", name: "fk_ffb9ee3a10", on_delete: :cascade
- add_foreign_key "project_statistics", "projects", on_delete: :cascade
- add_foreign_key "protected_branch_merge_access_levels", "protected_branches", name: "fk_8a3072ccb3", on_delete: :cascade
- add_foreign_key "protected_branch_push_access_levels", "protected_branches", name: "fk_9ffc86a3d9", on_delete: :cascade
- add_foreign_key "protected_branches", "projects", name: "fk_7a9c6d93e7", on_delete: :cascade
- add_foreign_key "protected_tag_create_access_levels", "namespaces", column: "group_id"
- add_foreign_key "protected_tag_create_access_levels", "protected_tags", name: "fk_f7dfda8c51", on_delete: :cascade
- add_foreign_key "protected_tag_create_access_levels", "users"
- add_foreign_key "protected_tags", "projects", name: "fk_8e4af87648", on_delete: :cascade
- add_foreign_key "push_event_payloads", "events", name: "fk_36c74129da", on_delete: :cascade
- add_foreign_key "releases", "projects", name: "fk_47fe2a0596", on_delete: :cascade
- add_foreign_key "services", "projects", name: "fk_71cce407f9", on_delete: :cascade
- add_foreign_key "snippets", "projects", name: "fk_be41fd4bb7", on_delete: :cascade
- add_foreign_key "subscriptions", "projects", on_delete: :cascade
- add_foreign_key "system_note_metadata", "notes", name: "fk_d83a918cb1", on_delete: :cascade
- add_foreign_key "timelogs", "issues", name: "fk_timelogs_issues_issue_id", on_delete: :cascade
- add_foreign_key "timelogs", "merge_requests", name: "fk_timelogs_merge_requests_merge_request_id", on_delete: :cascade
- add_foreign_key "todos", "projects", name: "fk_45054f9c45", on_delete: :cascade
- add_foreign_key "trending_projects", "projects", on_delete: :cascade
- add_foreign_key "u2f_registrations", "users"
- add_foreign_key "user_custom_attributes", "users", on_delete: :cascade
- add_foreign_key "user_synced_attributes_metadata", "users", on_delete: :cascade
- add_foreign_key "users_star_projects", "projects", name: "fk_22cd27ddfc", on_delete: :cascade
- add_foreign_key "web_hook_logs", "web_hooks", on_delete: :cascade
- add_foreign_key "web_hooks", "projects", name: "fk_0c8ca6d9d1", on_delete: :cascade
- end
-
- def down
- raise ActiveRecord::IrreversibleMigration, "The initial migration is not revertable"
- end
-end
-# rubocop:enable Migration/AddLimitToTextColumns
-# rubocop:enable Migration/PreventStrings
diff --git a/db/migrate/20180101160629_create_prometheus_metrics.rb b/db/migrate/20180101160629_create_prometheus_metrics.rb
deleted file mode 100644
index f94abd0e76e..00000000000
--- a/db/migrate/20180101160629_create_prometheus_metrics.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-class CreatePrometheusMetrics < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- def change
- create_table :prometheus_metrics do |t|
- t.references :project, index: true, foreign_key: { on_delete: :cascade }, null: false
- t.string :title, null: false
- t.string :query, null: false
- t.string :y_label
- t.string :unit
- t.string :legend
- t.integer :group, null: false, index: true
- t.timestamps_with_timezone null: false
- end
- end
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/migrate/20180101160630_change_project_id_for_prometheus_metrics.rb b/db/migrate/20180101160630_change_project_id_for_prometheus_metrics.rb
deleted file mode 100644
index d225899af18..00000000000
--- a/db/migrate/20180101160630_change_project_id_for_prometheus_metrics.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-class ChangeProjectIdForPrometheusMetrics < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- change_column_null :prometheus_metrics, :project_id, true
- end
-end
diff --git a/db/migrate/20180102220145_add_pages_https_only_to_projects.rb b/db/migrate/20180102220145_add_pages_https_only_to_projects.rb
deleted file mode 100644
index 7bd646cd5fd..00000000000
--- a/db/migrate/20180102220145_add_pages_https_only_to_projects.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class AddPagesHttpsOnlyToProjects < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- add_column :projects, :pages_https_only, :boolean # rubocop:disable Migration/AddColumnsToWideTables
- end
-end
diff --git a/db/migrate/20180103123548_add_confidential_note_events_to_services.rb b/db/migrate/20180103123548_add_confidential_note_events_to_services.rb
deleted file mode 100644
index 02724575e6c..00000000000
--- a/db/migrate/20180103123548_add_confidential_note_events_to_services.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-class AddConfidentialNoteEventsToServices < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_column :services, :confidential_note_events, :boolean
- change_column_default :services, :confidential_note_events, true
- end
-
- def down
- remove_column :services, :confidential_note_events
- end
-end
diff --git a/db/migrate/20180105212544_add_commits_count_to_merge_request_diff.rb b/db/migrate/20180105212544_add_commits_count_to_merge_request_diff.rb
deleted file mode 100644
index e27eecde906..00000000000
--- a/db/migrate/20180105212544_add_commits_count_to_merge_request_diff.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-class AddCommitsCountToMergeRequestDiff < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- MIGRATION = 'AddMergeRequestDiffCommitsCount'.freeze
- BATCH_SIZE = 5000
- DELAY_INTERVAL = 5.minutes.to_i
-
- class MergeRequestDiff < ActiveRecord::Base
- self.table_name = 'merge_request_diffs'
-
- include ::EachBatch
- end
-
- disable_ddl_transaction!
-
- def up
- add_column :merge_request_diffs, :commits_count, :integer
-
- say 'Populating the MergeRequestDiff `commits_count`'
-
- queue_background_migration_jobs_by_range_at_intervals(MergeRequestDiff, MIGRATION, DELAY_INTERVAL, batch_size: BATCH_SIZE)
- end
-
- def down
- remove_column :merge_request_diffs, :commits_count
- end
-end
diff --git a/db/migrate/20180109183319_change_default_value_for_pages_https_only.rb b/db/migrate/20180109183319_change_default_value_for_pages_https_only.rb
deleted file mode 100644
index 558eb60ac3f..00000000000
--- a/db/migrate/20180109183319_change_default_value_for_pages_https_only.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-class ChangeDefaultValueForPagesHttpsOnly < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- change_column_default :projects, :pages_https_only, true
- end
-
- def down
- change_column_default :projects, :pages_https_only, nil
- end
-end
diff --git a/db/migrate/20180113220114_rework_redirect_routes_indexes.rb b/db/migrate/20180113220114_rework_redirect_routes_indexes.rb
deleted file mode 100644
index ca7ce6286dc..00000000000
--- a/db/migrate/20180113220114_rework_redirect_routes_indexes.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class ReworkRedirectRoutesIndexes < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- INDEX_NAME_UNIQUE = "index_redirect_routes_on_path_unique_text_pattern_ops"
-
- INDEX_NAME_PERM = "index_redirect_routes_on_path_text_pattern_ops_where_permanent"
- INDEX_NAME_TEMP = "index_redirect_routes_on_path_text_pattern_ops_where_temporary"
-
- OLD_INDEX_NAME_PATH_TPOPS = "index_redirect_routes_on_path_text_pattern_ops"
- OLD_INDEX_NAME_PATH_LOWER = "index_on_redirect_routes_lower_path"
-
- def up
- disable_statement_timeout do
- # this is a plain btree on a single boolean column. It'll never be
- # selective enough to be valuable.
- if index_exists?(:redirect_routes, :permanent)
- remove_concurrent_index(:redirect_routes, :permanent)
- end
-
- if_not_exists = Gitlab::Database.version.to_f >= 9.5 ? "IF NOT EXISTS" : ""
-
- # Unique index on lower(path) across both types of redirect_routes:
- execute("CREATE UNIQUE INDEX CONCURRENTLY #{if_not_exists} #{INDEX_NAME_UNIQUE} ON redirect_routes (lower(path) varchar_pattern_ops);")
-
- # Make two indexes on path -- one for permanent and one for temporary routes:
- execute("CREATE INDEX CONCURRENTLY #{if_not_exists} #{INDEX_NAME_PERM} ON redirect_routes (lower(path) varchar_pattern_ops) where (permanent);")
- execute("CREATE INDEX CONCURRENTLY #{if_not_exists} #{INDEX_NAME_TEMP} ON redirect_routes (lower(path) varchar_pattern_ops) where (not permanent or permanent is null) ;")
-
- # Remove the old indexes:
-
- # This one needed to be on lower(path) but wasn't so it's replaced with the two above
- execute "DROP INDEX CONCURRENTLY IF EXISTS #{OLD_INDEX_NAME_PATH_TPOPS};"
-
- # This one isn't needed because we only ever do = and LIKE on this
- # column so the varchar_pattern_ops index is sufficient
- execute "DROP INDEX CONCURRENTLY IF EXISTS #{OLD_INDEX_NAME_PATH_LOWER};"
- end
- end
-
- def down
- disable_statement_timeout do
- add_concurrent_index(:redirect_routes, :permanent)
-
- execute("CREATE INDEX CONCURRENTLY #{OLD_INDEX_NAME_PATH_TPOPS} ON redirect_routes (path varchar_pattern_ops);")
- execute("CREATE INDEX CONCURRENTLY #{OLD_INDEX_NAME_PATH_LOWER} ON redirect_routes (LOWER(path));")
-
- execute("DROP INDEX CONCURRENTLY IF EXISTS #{INDEX_NAME_UNIQUE};")
- execute("DROP INDEX CONCURRENTLY IF EXISTS #{INDEX_NAME_PERM};")
- execute("DROP INDEX CONCURRENTLY IF EXISTS #{INDEX_NAME_TEMP};")
- end
- end
-end
diff --git a/db/migrate/20180115094742_add_default_project_creation_setting.rb b/db/migrate/20180115094742_add_default_project_creation_setting.rb
deleted file mode 100644
index b19e588ece3..00000000000
--- a/db/migrate/20180115094742_add_default_project_creation_setting.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-class AddDefaultProjectCreationSetting < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- unless column_exists?(:application_settings, :default_project_creation)
- add_column_with_default(:application_settings, :default_project_creation, :integer, default: 2) # rubocop:disable Migration/AddColumnWithDefault
- end
- end
-
- def down
- if column_exists?(:application_settings, :default_project_creation)
- remove_column(:application_settings, :default_project_creation)
- end
- end
-end
diff --git a/db/migrate/20180115113902_add_project_creation_level_to_groups.rb b/db/migrate/20180115113902_add_project_creation_level_to_groups.rb
deleted file mode 100644
index a10ce54087c..00000000000
--- a/db/migrate/20180115113902_add_project_creation_level_to_groups.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-class AddProjectCreationLevelToGroups < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- unless column_exists?(:namespaces, :project_creation_level)
- add_column(:namespaces, :project_creation_level, :integer)
- end
- end
-
- def down
- if column_exists?(:namespaces, :project_creation_level)
- remove_column(:namespaces, :project_creation_level, :integer)
- end
- end
-end
diff --git a/db/migrate/20180115201419_add_index_updated_at_to_issues.rb b/db/migrate/20180115201419_add_index_updated_at_to_issues.rb
deleted file mode 100644
index 8707307eed0..00000000000
--- a/db/migrate/20180115201419_add_index_updated_at_to_issues.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class AddIndexUpdatedAtToIssues < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :issues, :updated_at
- end
-
- def down
- remove_concurrent_index :issues, :updated_at
- end
-end
diff --git a/db/migrate/20180116193854_create_lfs_file_locks.rb b/db/migrate/20180116193854_create_lfs_file_locks.rb
deleted file mode 100644
index 6d49281dca2..00000000000
--- a/db/migrate/20180116193854_create_lfs_file_locks.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-class CreateLfsFileLocks < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- create_table :lfs_file_locks do |t|
- t.references :project, null: false, foreign_key: { on_delete: :cascade }
- t.references :user, null: false, index: true, foreign_key: { on_delete: :cascade }
- t.datetime :created_at, null: false # rubocop:disable Migration/Datetime
- t.string :path, limit: 511 # rubocop:disable Migration/PreventStrings
- end
-
- add_index :lfs_file_locks, [:project_id, :path], unique: true
- end
-
- def down
- if foreign_keys_for(:lfs_file_locks, :project_id).any?
- remove_foreign_key :lfs_file_locks, column: :project_id
- end
-
- if index_exists?(:lfs_file_locks, [:project_id, :path])
- remove_concurrent_index :lfs_file_locks, [:project_id, :path]
- end
-
- drop_table :lfs_file_locks
- end
-end
diff --git a/db/migrate/20180119135717_add_uploader_index_to_uploads.rb b/db/migrate/20180119135717_add_uploader_index_to_uploads.rb
deleted file mode 100644
index 7dd0a06e3bf..00000000000
--- a/db/migrate/20180119135717_add_uploader_index_to_uploads.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddUploaderIndexToUploads < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- remove_concurrent_index :uploads, :path
- add_concurrent_index :uploads, [:uploader, :path], using: :btree
- end
-
- def down
- remove_concurrent_index :uploads, [:uploader, :path]
- add_concurrent_index :uploads, :path, using: :btree
- end
-end
diff --git a/db/migrate/20180119160751_optimize_ci_job_artifacts.rb b/db/migrate/20180119160751_optimize_ci_job_artifacts.rb
deleted file mode 100644
index 3598689d78c..00000000000
--- a/db/migrate/20180119160751_optimize_ci_job_artifacts.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class OptimizeCiJobArtifacts < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- # job_id is just here to be a covering index for index only scans
- # since we'll almost always be joining against ci_builds on job_id
- add_concurrent_index(:ci_job_artifacts, [:expire_at, :job_id])
- add_concurrent_index(:ci_builds, [:artifacts_expire_at], where: "artifacts_file <> ''")
- end
-
- def down
- remove_concurrent_index(:ci_job_artifacts, [:expire_at, :job_id])
- remove_concurrent_index(:ci_builds, [:artifacts_expire_at], where: "artifacts_file <> ''")
- end
-end
diff --git a/db/migrate/20180122162010_add_auto_devops_domain_to_application_settings.rb b/db/migrate/20180122162010_add_auto_devops_domain_to_application_settings.rb
deleted file mode 100644
index 603f4eb13db..00000000000
--- a/db/migrate/20180122162010_add_auto_devops_domain_to_application_settings.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddAutoDevopsDomainToApplicationSettings < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- def change
- add_column :application_settings, :auto_devops_domain, :string
- end
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/migrate/20180125214301_create_user_callouts.rb b/db/migrate/20180125214301_create_user_callouts.rb
deleted file mode 100644
index 6eb2f932ccc..00000000000
--- a/db/migrate/20180125214301_create_user_callouts.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class CreateUserCallouts < ActiveRecord::Migration[4.2]
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- def change
- create_table :user_callouts do |t|
- t.integer :feature_name, null: false
- t.references :user, index: true, foreign_key: { on_delete: :cascade }, null: false
- end
-
- add_index :user_callouts, [:user_id, :feature_name], unique: true
- end
-end
diff --git a/db/migrate/20180129193323_add_uploads_builder_context.rb b/db/migrate/20180129193323_add_uploads_builder_context.rb
deleted file mode 100644
index 308b732dca4..00000000000
--- a/db/migrate/20180129193323_add_uploads_builder_context.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddUploadsBuilderContext < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- def change
- add_column :uploads, :mount_point, :string
- add_column :uploads, :secret, :string
- end
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/migrate/20180201102129_add_unique_constraint_to_trending_projects_project_id.rb b/db/migrate/20180201102129_add_unique_constraint_to_trending_projects_project_id.rb
deleted file mode 100644
index 1f2a79d36a5..00000000000
--- a/db/migrate/20180201102129_add_unique_constraint_to_trending_projects_project_id.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-class AddUniqueConstraintToTrendingProjectsProjectId < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :trending_projects, :project_id, unique: true, name: 'index_trending_projects_on_project_id_unique'
- remove_concurrent_index_by_name :trending_projects, 'index_trending_projects_on_project_id'
- rename_index :trending_projects, 'index_trending_projects_on_project_id_unique', 'index_trending_projects_on_project_id'
- end
-
- def down
- rename_index :trending_projects, 'index_trending_projects_on_project_id', 'index_trending_projects_on_project_id_old'
- add_concurrent_index :trending_projects, :project_id
- remove_concurrent_index_by_name :trending_projects, 'index_trending_projects_on_project_id_old'
- end
-end
diff --git a/db/migrate/20180201110056_add_foreign_keys_to_todos.rb b/db/migrate/20180201110056_add_foreign_keys_to_todos.rb
deleted file mode 100644
index 6b217632a52..00000000000
--- a/db/migrate/20180201110056_add_foreign_keys_to_todos.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-class AddForeignKeysToTodos < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- class Todo < ActiveRecord::Base
- self.table_name = 'todos'
- include EachBatch
- end
-
- BATCH_SIZE = 1000
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- Todo.where('NOT EXISTS ( SELECT true FROM users WHERE id=todos.user_id )').each_batch(of: BATCH_SIZE) do |batch|
- batch.delete_all
- end
-
- Todo.where('NOT EXISTS ( SELECT true FROM users WHERE id=todos.author_id )').each_batch(of: BATCH_SIZE) do |batch|
- batch.delete_all
- end
-
- Todo.where('note_id IS NOT NULL AND NOT EXISTS ( SELECT true FROM notes WHERE id=todos.note_id )').each_batch(of: BATCH_SIZE) do |batch|
- batch.delete_all
- end
-
- add_concurrent_foreign_key :todos, :users, column: :user_id, on_delete: :cascade
- add_concurrent_foreign_key :todos, :users, column: :author_id, on_delete: :cascade
- add_concurrent_foreign_key :todos, :notes, column: :note_id, on_delete: :cascade
- end
-
- def down
- remove_foreign_key :todos, column: :user_id
- remove_foreign_key :todos, column: :author_id
- remove_foreign_key :todos, :notes
- end
-end
diff --git a/db/migrate/20180201145907_migrate_remaining_issues_closed_at.rb b/db/migrate/20180201145907_migrate_remaining_issues_closed_at.rb
deleted file mode 100644
index d398909f25b..00000000000
--- a/db/migrate/20180201145907_migrate_remaining_issues_closed_at.rb
+++ /dev/null
@@ -1,56 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class MigrateRemainingIssuesClosedAt < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- class Issue < ActiveRecord::Base
- self.table_name = 'issues'
- include EachBatch
- end
-
- def up
- Gitlab::BackgroundMigration.steal('CopyColumn')
- Gitlab::BackgroundMigration.steal('CleanupConcurrentTypeChange')
-
- if migrate_column_type?
- if closed_at_for_type_change_exists?
- migrate_remaining_rows
- else
- # Due to some EE merge problems some environments may not have the
- # "closed_at_for_type_change" column. If this is the case we have no
- # other option than to migrate the data _right now_.
- # rubocop:disable Migration/UpdateLargeTable
- change_column_type_concurrently(:issues, :closed_at, :datetime_with_timezone)
- cleanup_concurrent_column_type_change(:issues, :closed_at)
- end
- end
- end
-
- def down
- # Previous migrations already revert the changes made here.
- end
-
- def migrate_remaining_rows
- Issue.where('closed_at_for_type_change IS NULL AND closed_at IS NOT NULL').each_batch do |batch|
- batch.update_all('closed_at_for_type_change = closed_at')
- end
-
- cleanup_concurrent_column_type_change(:issues, :closed_at)
- end
-
- def migrate_column_type?
- # Some environments may have already executed the previous version of this
- # migration, thus we don't need to migrate those environments again.
- column_for('issues', 'closed_at').type == :datetime # rubocop:disable Migration/Datetime
- end
-
- def closed_at_for_type_change_exists?
- columns('issues').any? { |col| col.name == 'closed_at_for_type_change' }
- end
-end
diff --git a/db/migrate/20180206200543_reset_events_primary_key_sequence.rb b/db/migrate/20180206200543_reset_events_primary_key_sequence.rb
deleted file mode 100644
index e7a18e68395..00000000000
--- a/db/migrate/20180206200543_reset_events_primary_key_sequence.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class ResetEventsPrimaryKeySequence < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- class Event < ActiveRecord::Base
- self.table_name = 'events'
- end
-
- def up
- reset_pk_sequence!(Event.table_name)
- end
-
- def down
- # No-op
- end
-end
diff --git a/db/migrate/20180208183958_schedule_populate_untracked_uploads_if_needed.rb b/db/migrate/20180208183958_schedule_populate_untracked_uploads_if_needed.rb
deleted file mode 100644
index b69ac8f94c1..00000000000
--- a/db/migrate/20180208183958_schedule_populate_untracked_uploads_if_needed.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class SchedulePopulateUntrackedUploadsIfNeeded < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- FOLLOW_UP_MIGRATION = 'PopulateUntrackedUploads'.freeze
-
- class UntrackedFile < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'untracked_files_for_uploads'
- end
-
- def up
- if table_exists?(:untracked_files_for_uploads)
- process_or_remove_table
- end
- end
-
- def down
- # nothing
- end
-
- private
-
- def process_or_remove_table
- if UntrackedFile.all.empty?
- drop_temp_table
- else
- schedule_populate_untracked_uploads_jobs
- end
- end
-
- def drop_temp_table
- drop_table(:untracked_files_for_uploads, if_exists: true)
- end
-
- def schedule_populate_untracked_uploads_jobs
- say "Scheduling #{FOLLOW_UP_MIGRATION} background migration jobs since there are rows in untracked_files_for_uploads."
-
- bulk_queue_background_migration_jobs_by_range(
- UntrackedFile, FOLLOW_UP_MIGRATION)
- end
-end
diff --git a/db/migrate/20180209115333_create_chatops_tables.rb b/db/migrate/20180209115333_create_chatops_tables.rb
deleted file mode 100644
index 9e11dfde7a3..00000000000
--- a/db/migrate/20180209115333_create_chatops_tables.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-# frozen_string_literal: true
-
-class CreateChatopsTables < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- create_table :ci_pipeline_chat_data, id: :bigserial do |t|
- t.integer :pipeline_id, null: false
- t.references :chat_name, foreign_key: { on_delete: :cascade }, null: false
- t.text :response_url, null: false # rubocop:disable Migration/AddLimitToTextColumns
-
- # A pipeline can only contain one row in this table, hence this index is
- # unique.
- t.index :pipeline_id, unique: true
-
- t.index :chat_name_id
- end
-
- # rubocop:disable Migration/AddConcurrentForeignKey
- add_foreign_key :ci_pipeline_chat_data, :ci_pipelines,
- column: :pipeline_id,
- on_delete: :cascade
- end
-end
diff --git a/db/migrate/20180209165249_add_closed_by_to_issues.rb b/db/migrate/20180209165249_add_closed_by_to_issues.rb
deleted file mode 100644
index 91a1e021ab9..00000000000
--- a/db/migrate/20180209165249_add_closed_by_to_issues.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddClosedByToIssues < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- disable_ddl_transaction!
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- def up
- add_column :issues, :closed_by_id, :integer
- add_concurrent_foreign_key :issues, :users, column: :closed_by_id, on_delete: :nullify
- end
-
- def down
- remove_foreign_key :issues, column: :closed_by_id
- remove_column :issues, :closed_by_id
- end
-end
diff --git a/db/migrate/20180212030105_add_external_ip_to_clusters_applications_ingress.rb b/db/migrate/20180212030105_add_external_ip_to_clusters_applications_ingress.rb
deleted file mode 100644
index 78bb49b8b84..00000000000
--- a/db/migrate/20180212030105_add_external_ip_to_clusters_applications_ingress.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-class AddExternalIpToClustersApplicationsIngress < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- def change
- add_column :clusters_applications_ingress, :external_ip, :string
- end
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/migrate/20180213131630_add_partial_index_to_projects_for_index_only_scans.rb b/db/migrate/20180213131630_add_partial_index_to_projects_for_index_only_scans.rb
deleted file mode 100644
index 905915d9239..00000000000
--- a/db/migrate/20180213131630_add_partial_index_to_projects_for_index_only_scans.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-class AddPartialIndexToProjectsForIndexOnlyScans < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- INDEX_NAME = 'index_projects_on_id_partial_for_visibility'
-
- disable_ddl_transaction!
-
- # Adds a partial index to leverage index-only scans when looking up project ids
- def up
- unless index_exists?(:projects, :id, name: INDEX_NAME)
- add_concurrent_index :projects, :id, name: INDEX_NAME, unique: true, where: 'visibility_level IN (10,20)'
- end
- end
-
- def down
- if index_exists?(:projects, :id, name: INDEX_NAME)
- remove_concurrent_index_by_name :projects, INDEX_NAME
- end
- end
-end
diff --git a/db/migrate/20180214093516_create_badges.rb b/db/migrate/20180214093516_create_badges.rb
deleted file mode 100644
index 7a0d82d2d81..00000000000
--- a/db/migrate/20180214093516_create_badges.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-class CreateBadges < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- def change
- create_table :badges do |t|
- t.string :link_url, null: false
- t.string :image_url, null: false
- t.references :project, index: true, foreign_key: { on_delete: :cascade }, null: true
- t.integer :group_id, index: true, null: true
- t.string :type, null: false
-
- t.timestamps_with_timezone null: false
- end
-
- # rubocop:disable Migration/AddConcurrentForeignKey
- add_foreign_key :badges, :namespaces, column: :group_id, on_delete: :cascade
- # rubocop:enable Migration/AddConcurrentForeignKey
- end
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/migrate/20180214155405_create_clusters_applications_runners.rb b/db/migrate/20180214155405_create_clusters_applications_runners.rb
deleted file mode 100644
index e6025007507..00000000000
--- a/db/migrate/20180214155405_create_clusters_applications_runners.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-class CreateClustersApplicationsRunners < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- create_table :clusters_applications_runners do |t|
- t.references :cluster, null: false, foreign_key: { on_delete: :cascade }
- t.references :runner, references: :ci_runners
- t.index :runner_id
- t.index :cluster_id, unique: true
- t.integer :status, null: false
- t.timestamps_with_timezone null: false
- t.string :version, null: false # rubocop:disable Migration/PreventStrings
- t.text :status_reason # rubocop:disable Migration/AddLimitToTextColumns
- end
-
- add_concurrent_foreign_key :clusters_applications_runners, :ci_runners,
- column: :runner_id,
- on_delete: :nullify
- end
-
- def down
- if foreign_keys_for(:clusters_applications_runners, :runner_id).any?
- remove_foreign_key :clusters_applications_runners, column: :runner_id
- end
-
- drop_table :clusters_applications_runners
- end
-end
diff --git a/db/migrate/20180215181245_users_name_lower_index.rb b/db/migrate/20180215181245_users_name_lower_index.rb
deleted file mode 100644
index 46f02885c3f..00000000000
--- a/db/migrate/20180215181245_users_name_lower_index.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class UsersNameLowerIndex < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
- INDEX_NAME = 'index_on_users_name_lower'
-
- disable_ddl_transaction!
-
- def up
- # On GitLab.com this produces an index with a size of roughly 60 MB.
- execute "CREATE INDEX CONCURRENTLY #{INDEX_NAME} ON users (LOWER(name))"
- end
-
- def down
- execute "DROP INDEX CONCURRENTLY IF EXISTS #{INDEX_NAME}"
- end
-end
diff --git a/db/migrate/20180216120000_add_pages_domain_verification.rb b/db/migrate/20180216120000_add_pages_domain_verification.rb
deleted file mode 100644
index 0600fe633a7..00000000000
--- a/db/migrate/20180216120000_add_pages_domain_verification.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-class AddPagesDomainVerification < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- def change
- add_column :pages_domains, :verified_at, :datetime_with_timezone
- add_column :pages_domains, :verification_code, :string # rubocop:disable Migration/PreventStrings
- end
-end
diff --git a/db/migrate/20180216120010_add_pages_domain_verified_at_index.rb b/db/migrate/20180216120010_add_pages_domain_verified_at_index.rb
deleted file mode 100644
index 6e7cb89c765..00000000000
--- a/db/migrate/20180216120010_add_pages_domain_verified_at_index.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class AddPagesDomainVerifiedAtIndex < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :pages_domains, :verified_at
- end
-
- def down
- remove_concurrent_index :pages_domains, :verified_at
- end
-end
diff --git a/db/migrate/20180216120020_allow_domain_verification_to_be_disabled.rb b/db/migrate/20180216120020_allow_domain_verification_to_be_disabled.rb
deleted file mode 100644
index 18e4f534105..00000000000
--- a/db/migrate/20180216120020_allow_domain_verification_to_be_disabled.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class AllowDomainVerificationToBeDisabled < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- def change
- add_column :application_settings, :pages_domain_verification_enabled, :boolean, default: true, null: false
- end
-end
diff --git a/db/migrate/20180216120030_add_pages_domain_enabled_until.rb b/db/migrate/20180216120030_add_pages_domain_enabled_until.rb
deleted file mode 100644
index 3347bb6deaa..00000000000
--- a/db/migrate/20180216120030_add_pages_domain_enabled_until.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class AddPagesDomainEnabledUntil < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- def change
- add_column :pages_domains, :enabled_until, :datetime_with_timezone
- end
-end
diff --git a/db/migrate/20180216120040_add_pages_domain_enabled_until_index.rb b/db/migrate/20180216120040_add_pages_domain_enabled_until_index.rb
deleted file mode 100644
index 3880a8ea139..00000000000
--- a/db/migrate/20180216120040_add_pages_domain_enabled_until_index.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-class AddPagesDomainEnabledUntilIndex < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :pages_domains, [:project_id, :enabled_until]
- add_concurrent_index :pages_domains, [:verified_at, :enabled_until]
- end
-
- def down
- remove_concurrent_index :pages_domains, [:verified_at, :enabled_until]
- remove_concurrent_index :pages_domains, [:project_id, :enabled_until]
- end
-end
diff --git a/db/migrate/20180216120050_pages_domains_verification_grace_period.rb b/db/migrate/20180216120050_pages_domains_verification_grace_period.rb
deleted file mode 100644
index e51cff68b50..00000000000
--- a/db/migrate/20180216120050_pages_domains_verification_grace_period.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-class PagesDomainsVerificationGracePeriod < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- class PagesDomain < ActiveRecord::Base
- include EachBatch
- end
-
- # Allow this migration to resume if it fails partway through
- disable_ddl_transaction!
-
- def up
- now = Time.now
- grace = now + 30.days
-
- PagesDomain.each_batch do |relation|
- relation.update_all(verified_at: now, enabled_until: grace)
-
- # Sleep 2 minutes between batches to not overload the DB with dead tuples
- sleep(2.minutes) unless relation.reorder(:id).last == PagesDomain.reorder(:id).last
- end
- end
-
- def down
- # no-op
- end
-end
diff --git a/db/migrate/20180219153455_add_maximum_timeout_to_ci_runners.rb b/db/migrate/20180219153455_add_maximum_timeout_to_ci_runners.rb
deleted file mode 100644
index 68578c23207..00000000000
--- a/db/migrate/20180219153455_add_maximum_timeout_to_ci_runners.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class AddMaximumTimeoutToCiRunners < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- add_column :ci_runners, :maximum_timeout, :integer
- end
-end
diff --git a/db/migrate/20180221151752_add_allow_maintainer_to_push_to_merge_requests.rb b/db/migrate/20180221151752_add_allow_maintainer_to_push_to_merge_requests.rb
deleted file mode 100644
index 71f6bc46a88..00000000000
--- a/db/migrate/20180221151752_add_allow_maintainer_to_push_to_merge_requests.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddAllowMaintainerToPushToMergeRequests < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_column :merge_requests, :allow_maintainer_to_push, :boolean
- end
-
- def down
- remove_column :merge_requests, :allow_maintainer_to_push
- end
-end
diff --git a/db/migrate/20180222043024_add_ip_address_to_runner.rb b/db/migrate/20180222043024_add_ip_address_to_runner.rb
deleted file mode 100644
index cc183112f6f..00000000000
--- a/db/migrate/20180222043024_add_ip_address_to_runner.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class AddIpAddressToRunner < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- add_column :ci_runners, :ip_address, :string # rubocop:disable Migration/PreventStrings
- end
-end
diff --git a/db/migrate/20180223120443_create_user_interacted_projects_table.rb b/db/migrate/20180223120443_create_user_interacted_projects_table.rb
deleted file mode 100644
index 185a690ad3d..00000000000
--- a/db/migrate/20180223120443_create_user_interacted_projects_table.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-class CreateUserInteractedProjectsTable < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- INDEX_NAME = 'user_interacted_projects_non_unique_index'
-
- def up
- create_table :user_interacted_projects, id: false do |t|
- t.references :user, null: false
- t.references :project, null: false
- end
-
- add_index :user_interacted_projects, [:project_id, :user_id], name: INDEX_NAME
- end
-
- def down
- drop_table :user_interacted_projects
- end
-end
diff --git a/db/migrate/20180223144945_add_allow_local_requests_from_hooks_and_services_to_application_settings.rb b/db/migrate/20180223144945_add_allow_local_requests_from_hooks_and_services_to_application_settings.rb
deleted file mode 100644
index 3171ff56299..00000000000
--- a/db/migrate/20180223144945_add_allow_local_requests_from_hooks_and_services_to_application_settings.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-class AddAllowLocalRequestsFromHooksAndServicesToApplicationSettings < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_column_with_default(:application_settings, :allow_local_requests_from_hooks_and_services, # rubocop:disable Migration/AddColumnWithDefault
- :boolean,
- default: false,
- allow_null: false)
- end
-
- def down
- remove_column(:application_settings, :allow_local_requests_from_hooks_and_services)
- end
-end
diff --git a/db/migrate/20180226050030_add_checksum_to_ci_job_artifacts.rb b/db/migrate/20180226050030_add_checksum_to_ci_job_artifacts.rb
deleted file mode 100644
index bccb7ac26ec..00000000000
--- a/db/migrate/20180226050030_add_checksum_to_ci_job_artifacts.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class AddChecksumToCiJobArtifacts < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- def change
- add_column :ci_job_artifacts, :file_sha256, :binary
- end
-end
diff --git a/db/migrate/20180227182112_add_group_id_to_boards_ce.rb b/db/migrate/20180227182112_add_group_id_to_boards_ce.rb
deleted file mode 100644
index b887be0cc55..00000000000
--- a/db/migrate/20180227182112_add_group_id_to_boards_ce.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-class AddGroupIdToBoardsCe < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- disable_ddl_transaction!
-
- DOWNTIME = false
-
- def up
- return if group_id_exists?
-
- # rubocop:disable Migration/AddConcurrentForeignKey
- add_column :boards, :group_id, :integer
- add_foreign_key :boards, :namespaces, column: :group_id, on_delete: :cascade
- add_concurrent_index :boards, :group_id
-
- change_column_null :boards, :project_id, true
- end
-
- def down
- return unless group_id_exists?
-
- # rubocop:disable Migration/RemoveIndex
- remove_foreign_key :boards, column: :group_id
- remove_index :boards, :group_id if index_exists? :boards, :group_id
- remove_column :boards, :group_id
-
- execute "DELETE from boards WHERE project_id IS NULL"
- change_column_null :boards, :project_id, false
- end
-
- private
-
- def group_id_exists?
- column_exists?(:boards, :group_id)
- end
-end
diff --git a/db/migrate/20180228172924_add_include_private_contributions_to_users.rb b/db/migrate/20180228172924_add_include_private_contributions_to_users.rb
deleted file mode 100644
index 58e50b2ee74..00000000000
--- a/db/migrate/20180228172924_add_include_private_contributions_to_users.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class AddIncludePrivateContributionsToUsers < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- def change
- add_column :users, :include_private_contributions, :boolean # rubocop:disable Migration/AddColumnsToWideTables
- end
-end
diff --git a/db/migrate/20180301010859_create_ci_builds_metadata_table.rb b/db/migrate/20180301010859_create_ci_builds_metadata_table.rb
deleted file mode 100644
index 29652c675e1..00000000000
--- a/db/migrate/20180301010859_create_ci_builds_metadata_table.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-class CreateCiBuildsMetadataTable < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- create_table :ci_builds_metadata do |t|
- t.integer :build_id, null: false
- t.integer :project_id, null: false
- t.integer :timeout
- t.integer :timeout_source, null: false, default: 1
-
- t.foreign_key :ci_builds, column: :build_id, on_delete: :cascade
- t.foreign_key :projects, column: :project_id, on_delete: :cascade
-
- t.index :build_id, unique: true
- t.index :project_id
- end
- end
-end
diff --git a/db/migrate/20180302152117_ensure_foreign_keys_on_clusters_applications.rb b/db/migrate/20180302152117_ensure_foreign_keys_on_clusters_applications.rb
deleted file mode 100644
index d660c7cfd2d..00000000000
--- a/db/migrate/20180302152117_ensure_foreign_keys_on_clusters_applications.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class EnsureForeignKeysOnClustersApplications < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- # rubocop:disable Cop/InBatches
- def up
- existing = Clusters::Cluster
- .joins(:application_ingress)
- .where('clusters.id = clusters_applications_ingress.cluster_id')
-
- Clusters::Applications::Ingress.where('NOT EXISTS (?)', existing).in_batches do |batch|
- batch.delete_all
- end
-
- unless foreign_keys_for(:clusters_applications_ingress, :cluster_id).any?
- add_concurrent_foreign_key :clusters_applications_ingress, :clusters,
- column: :cluster_id,
- on_delete: :cascade
- end
-
- existing = Clusters::Cluster
- .joins(:application_prometheus)
- .where('clusters.id = clusters_applications_prometheus.cluster_id')
-
- Clusters::Applications::Ingress.where('NOT EXISTS (?)', existing).in_batches do |batch|
- batch.delete_all
- end
-
- unless foreign_keys_for(:clusters_applications_prometheus, :cluster_id).any?
- add_concurrent_foreign_key :clusters_applications_prometheus, :clusters,
- column: :cluster_id,
- on_delete: :cascade
- end
- end
-
- def down
- if foreign_keys_for(:clusters_applications_ingress, :cluster_id).any?
- remove_foreign_key :clusters_applications_ingress, column: :cluster_id
- end
-
- if foreign_keys_for(:clusters_applications_prometheus, :cluster_id).any?
- remove_foreign_key :clusters_applications_prometheus, column: :cluster_id
- end
- end
-end
diff --git a/db/migrate/20180305095250_create_internal_ids_table.rb b/db/migrate/20180305095250_create_internal_ids_table.rb
deleted file mode 100644
index 8565f5d848b..00000000000
--- a/db/migrate/20180305095250_create_internal_ids_table.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class CreateInternalIdsTable < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- create_table :internal_ids, id: :bigserial do |t|
- t.references :project, null: false, foreign_key: { on_delete: :cascade }
- t.integer :usage, null: false
- t.integer :last_value, null: false
-
- t.index [:usage, :project_id], unique: true
- end
- end
-end
diff --git a/db/migrate/20180305144721_add_privileged_to_runner.rb b/db/migrate/20180305144721_add_privileged_to_runner.rb
deleted file mode 100644
index 1ad3c045d60..00000000000
--- a/db/migrate/20180305144721_add_privileged_to_runner.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddPrivilegedToRunner < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_column_with_default :clusters_applications_runners, :privileged, :boolean, default: true, allow_null: false # rubocop:disable Migration/AddColumnWithDefault
- end
-
- def down
- remove_column :clusters_applications_runners, :privileged
- end
-end
diff --git a/db/migrate/20180306134842_add_missing_indexes_acts_as_taggable_on_engine.rb b/db/migrate/20180306134842_add_missing_indexes_acts_as_taggable_on_engine.rb
deleted file mode 100644
index b400ff94dbe..00000000000
--- a/db/migrate/20180306134842_add_missing_indexes_acts_as_taggable_on_engine.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# This migration comes from acts_as_taggable_on_engine (originally 6)
-#
-# It has been modified to handle no-downtime GitLab migrations. Several
-# indexes have been removed since they are not needed for GitLab.
-class AddMissingIndexesActsAsTaggableOnEngine < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :taggings, :tag_id unless index_exists? :taggings, :tag_id
- add_concurrent_index :taggings, [:taggable_id, :taggable_type] unless index_exists? :taggings, [:taggable_id, :taggable_type]
- end
-
- def down
- remove_concurrent_index :taggings, :tag_id
- remove_concurrent_index :taggings, [:taggable_id, :taggable_type]
- end
-end
diff --git a/db/migrate/20180308052825_add_section_name_id_index_on_ci_build_trace_sections.rb b/db/migrate/20180308052825_add_section_name_id_index_on_ci_build_trace_sections.rb
deleted file mode 100644
index 58a1d2b12d5..00000000000
--- a/db/migrate/20180308052825_add_section_name_id_index_on_ci_build_trace_sections.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-class AddSectionNameIdIndexOnCiBuildTraceSections < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
- INDEX_NAME = 'index_ci_build_trace_sections_on_section_name_id'
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :ci_build_trace_sections, :section_name_id, name: INDEX_NAME
- end
-
- def down
- remove_concurrent_index :ci_build_trace_sections, :section_name_id, name: INDEX_NAME
- end
-end
diff --git a/db/migrate/20180308125206_add_user_internal_regex_to_application_setting.rb b/db/migrate/20180308125206_add_user_internal_regex_to_application_setting.rb
deleted file mode 100644
index d97d2953677..00000000000
--- a/db/migrate/20180308125206_add_user_internal_regex_to_application_setting.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class AddUserInternalRegexToApplicationSetting < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- def up
- add_column :application_settings, :user_default_internal_regex, :string, null: true
- end
- # rubocop:enable Migration/PreventStrings
-
- def down
- remove_column :application_settings, :user_default_internal_regex
- end
-end
diff --git a/db/migrate/20180309121820_reschedule_commits_count_for_merge_request_diff.rb b/db/migrate/20180309121820_reschedule_commits_count_for_merge_request_diff.rb
deleted file mode 100644
index 3d85a19b82f..00000000000
--- a/db/migrate/20180309121820_reschedule_commits_count_for_merge_request_diff.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-class RescheduleCommitsCountForMergeRequestDiff < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- MIGRATION = 'AddMergeRequestDiffCommitsCount'.freeze
- BATCH_SIZE = 5000
- DELAY_INTERVAL = 5.minutes.to_i
-
- class MergeRequestDiff < ActiveRecord::Base
- self.table_name = 'merge_request_diffs'
-
- include ::EachBatch
- end
-
- disable_ddl_transaction!
-
- def up
- say 'Populating the MergeRequestDiff `commits_count` (reschedule)'
-
- execute("SET statement_timeout TO '60s'")
-
- MergeRequestDiff.where(commits_count: nil).each_batch(of: BATCH_SIZE) do |relation, index|
- start_id, end_id = relation.pluck('MIN(id), MAX(id)').first
- delay = index * DELAY_INTERVAL
-
- BackgroundMigrationWorker.perform_in(delay, MIGRATION, [start_id, end_id])
- end
- end
-end
diff --git a/db/migrate/20180309160427_add_partial_indexes_on_todos.rb b/db/migrate/20180309160427_add_partial_indexes_on_todos.rb
deleted file mode 100644
index c22ed0a5177..00000000000
--- a/db/migrate/20180309160427_add_partial_indexes_on_todos.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddPartialIndexesOnTodos < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- INDEX_NAME_PENDING = "index_todos_on_user_id_and_id_pending"
- INDEX_NAME_DONE = "index_todos_on_user_id_and_id_done"
-
- def up
- unless index_exists?(:todos, [:user_id, :id], name: INDEX_NAME_PENDING)
- add_concurrent_index(:todos, [:user_id, :id], where: "state='pending'", name: INDEX_NAME_PENDING)
- end
-
- unless index_exists?(:todos, [:user_id, :id], name: INDEX_NAME_DONE)
- add_concurrent_index(:todos, [:user_id, :id], where: "state='done'", name: INDEX_NAME_DONE)
- end
- end
-
- def down
- remove_concurrent_index(:todos, [:user_id, :id], where: "state='pending'", name: INDEX_NAME_PENDING)
- remove_concurrent_index(:todos, [:user_id, :id], where: "state='done'", name: INDEX_NAME_DONE)
- end
-end
diff --git a/db/migrate/20180314100728_add_external_authorization_service_timeout_to_application_settings.rb b/db/migrate/20180314100728_add_external_authorization_service_timeout_to_application_settings.rb
deleted file mode 100644
index c3c6aa0ddf8..00000000000
--- a/db/migrate/20180314100728_add_external_authorization_service_timeout_to_application_settings.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-class AddExternalAuthorizationServiceTimeoutToApplicationSettings < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- # We can use the regular `add_column` with a default since `application_settings`
- # is a small table.
- add_column :application_settings,
- :external_authorization_service_timeout,
- :float,
- default: 0.5
- end
-
- def down
- remove_column :application_settings, :external_authorization_service_timeout
- end
-end
diff --git a/db/migrate/20180314145917_add_header_and_footer_banners_to_appearances_table.rb b/db/migrate/20180314145917_add_header_and_footer_banners_to_appearances_table.rb
deleted file mode 100644
index a6f2605c906..00000000000
--- a/db/migrate/20180314145917_add_header_and_footer_banners_to_appearances_table.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-class AddHeaderAndFooterBannersToAppearancesTable < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- # rubocop:disable Migration/AddLimitToTextColumns
- add_column :appearances, :header_message, :text
- add_column :appearances, :header_message_html, :text
-
- add_column :appearances, :footer_message, :text
- add_column :appearances, :footer_message_html, :text
-
- add_column :appearances, :message_background_color, :text
- add_column :appearances, :message_font_color, :text
- # rubocop:enable Migration/AddLimitToTextColumns
- end
-end
diff --git a/db/migrate/20180315160435_add_external_auth_mutual_tls_fields_to_project_settings.rb b/db/migrate/20180315160435_add_external_auth_mutual_tls_fields_to_project_settings.rb
deleted file mode 100644
index dd40c5fdf4d..00000000000
--- a/db/migrate/20180315160435_add_external_auth_mutual_tls_fields_to_project_settings.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-class AddExternalAuthMutualTlsFieldsToProjectSettings < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- # rubocop:disable Migration/AddLimitToTextColumns
- def change
- add_column :application_settings,
- :external_auth_client_cert, :text
- add_column :application_settings,
- :encrypted_external_auth_client_key, :text
- add_column :application_settings,
- :encrypted_external_auth_client_key_iv, :string
- add_column :application_settings,
- :encrypted_external_auth_client_key_pass, :string
- add_column :application_settings,
- :encrypted_external_auth_client_key_pass_iv, :string
- end
- # rubocop:enable Migration/AddLimitToTextColumns
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/migrate/20180319190020_create_deploy_tokens.rb b/db/migrate/20180319190020_create_deploy_tokens.rb
deleted file mode 100644
index 019543cb2f1..00000000000
--- a/db/migrate/20180319190020_create_deploy_tokens.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-class CreateDeployTokens < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- def change
- create_table :deploy_tokens do |t|
- t.boolean :revoked, default: false
- t.boolean :read_repository, null: false, default: false
- t.boolean :read_registry, null: false, default: false
-
- t.datetime_with_timezone :expires_at, null: false
- t.datetime_with_timezone :created_at, null: false
-
- t.string :name, null: false
- t.string :token, index: { unique: true }, null: false
-
- t.index [:token, :expires_at, :id], where: "(revoked IS FALSE)"
- end
- end
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/migrate/20180320182229_add_indexes_for_user_activity_queries.rb b/db/migrate/20180320182229_add_indexes_for_user_activity_queries.rb
deleted file mode 100644
index ba8ad1b7495..00000000000
--- a/db/migrate/20180320182229_add_indexes_for_user_activity_queries.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-class AddIndexesForUserActivityQueries < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :events, [:author_id, :project_id] unless index_exists?(:events, [:author_id, :project_id])
- add_concurrent_index :user_interacted_projects, :user_id unless index_exists?(:user_interacted_projects, :user_id)
- end
-
- def down
- remove_concurrent_index :events, [:author_id, :project_id] if index_exists?(:events, [:author_id, :project_id])
-
- remove_concurrent_index :user_interacted_projects, :user_id if index_exists?(:user_interacted_projects, :user_id)
- end
-end
diff --git a/db/migrate/20180323150945_add_push_to_merge_request_to_notification_settings.rb b/db/migrate/20180323150945_add_push_to_merge_request_to_notification_settings.rb
deleted file mode 100644
index 3b38d21a8aa..00000000000
--- a/db/migrate/20180323150945_add_push_to_merge_request_to_notification_settings.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class AddPushToMergeRequestToNotificationSettings < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- add_column :notification_settings, :push_to_merge_request, :boolean
- end
-end
diff --git a/db/migrate/20180326202229_create_ci_build_trace_chunks.rb b/db/migrate/20180326202229_create_ci_build_trace_chunks.rb
deleted file mode 100644
index 45a64ec23d1..00000000000
--- a/db/migrate/20180326202229_create_ci_build_trace_chunks.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-class CreateCiBuildTraceChunks < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- create_table :ci_build_trace_chunks, id: :bigserial do |t|
- t.integer :build_id, null: false
- t.integer :chunk_index, null: false
- t.integer :data_store, null: false
- t.binary :raw_data
-
- t.foreign_key :ci_builds, column: :build_id, on_delete: :cascade
- t.index [:build_id, :chunk_index], unique: true
- end
- end
-end
diff --git a/db/migrate/20180327101207_remove_index_from_events_table.rb b/db/migrate/20180327101207_remove_index_from_events_table.rb
deleted file mode 100644
index 0583a2641ec..00000000000
--- a/db/migrate/20180327101207_remove_index_from_events_table.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class RemoveIndexFromEventsTable < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- remove_concurrent_index :events, :author_id
- end
-
- def down
- add_concurrent_index :events, :author_id
- end
-end
diff --git a/db/migrate/20180330121048_add_issue_due_to_notification_settings.rb b/db/migrate/20180330121048_add_issue_due_to_notification_settings.rb
deleted file mode 100644
index 2d9ca002872..00000000000
--- a/db/migrate/20180330121048_add_issue_due_to_notification_settings.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class AddIssueDueToNotificationSettings < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- add_column :notification_settings, :issue_due, :boolean
- end
-end
diff --git a/db/migrate/20180403035759_create_project_ci_cd_settings.rb b/db/migrate/20180403035759_create_project_ci_cd_settings.rb
deleted file mode 100644
index c630dd3c942..00000000000
--- a/db/migrate/20180403035759_create_project_ci_cd_settings.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-class CreateProjectCiCdSettings < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- unless table_exists?(:project_ci_cd_settings)
- create_table(:project_ci_cd_settings) do |t|
- t.integer(:project_id, null: false)
- t.boolean(:group_runners_enabled, default: true, null: false)
- end
- end
-
- disable_statement_timeout do
- # This particular INSERT will take between 10 and 20 seconds.
- execute 'INSERT INTO project_ci_cd_settings (project_id) SELECT id FROM projects'
-
- # We add the index and foreign key separately so the above INSERT statement
- # takes as little time as possible.
- add_concurrent_index(:project_ci_cd_settings, :project_id, unique: true)
-
- add_foreign_key_with_retry
- end
- end
-
- def down
- drop_table :project_ci_cd_settings
- end
-
- def add_foreign_key_with_retry
- # Between the initial INSERT and the addition of the foreign key some
- # projects may have been removed, leaving orphaned rows in our new settings
- # table.
- loop do
- remove_orphaned_settings
-
- begin
- add_project_id_foreign_key
- break
- rescue ActiveRecord::InvalidForeignKey
- say 'project_ci_cd_settings contains some orphaned rows, retrying...'
- end
- end
- end
-
- def add_project_id_foreign_key
- add_concurrent_foreign_key(:project_ci_cd_settings, :projects, column: :project_id)
- end
-
- def remove_orphaned_settings
- execute <<~SQL
- DELETE FROM project_ci_cd_settings
- WHERE NOT EXISTS (
- SELECT 1
- FROM projects
- WHERE projects.id = project_ci_cd_settings.project_id
- )
- SQL
- end
-end
diff --git a/db/migrate/20180405142733_create_project_deploy_tokens.rb b/db/migrate/20180405142733_create_project_deploy_tokens.rb
deleted file mode 100644
index ba000492247..00000000000
--- a/db/migrate/20180405142733_create_project_deploy_tokens.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-class CreateProjectDeployTokens < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- def change
- create_table :project_deploy_tokens do |t|
- t.integer :project_id, null: false
- t.integer :deploy_token_id, null: false
- t.datetime_with_timezone :created_at, null: false
-
- t.foreign_key :deploy_tokens, column: :deploy_token_id, on_delete: :cascade
- t.foreign_key :projects, column: :project_id, on_delete: :cascade
-
- t.index [:project_id, :deploy_token_id], unique: true
- end
- end
-end
diff --git a/db/migrate/20180408143354_rename_users_rss_token_to_feed_token.rb b/db/migrate/20180408143354_rename_users_rss_token_to_feed_token.rb
deleted file mode 100644
index 4b8844a134d..00000000000
--- a/db/migrate/20180408143354_rename_users_rss_token_to_feed_token.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-class RenameUsersRssTokenToFeedToken < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- # rubocop:disable Migration/UpdateLargeTable
- rename_column_concurrently :users, :rss_token, :feed_token
- end
-
- def down
- cleanup_concurrent_column_rename :users, :feed_token, :rss_token
- end
-end
diff --git a/db/migrate/20180413022611_create_missing_namespace_for_internal_users.rb b/db/migrate/20180413022611_create_missing_namespace_for_internal_users.rb
deleted file mode 100644
index 21d7f50ee83..00000000000
--- a/db/migrate/20180413022611_create_missing_namespace_for_internal_users.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-class CreateMissingNamespaceForInternalUsers < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- def up
- connection.exec_query(users_query.to_sql).rows.each do |id, username|
- create_namespace(id, username)
- # When testing locally I've noticed that these internal users are missing
- # the notification email, for more details visit the below link:
- # https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/18357#note_68327560
- set_notification_email(id)
- end
- end
-
- def down
- # no-op
- end
-
- private
-
- def users
- @users ||= Arel::Table.new(:users)
- end
-
- def namespaces
- @namespaces ||= Arel::Table.new(:namespaces)
- end
-
- def users_query
- condition = users[:ghost].eq(true)
-
- if column_exists?(:users, :support_bot)
- condition = condition.or(users[:support_bot].eq(true))
- end
-
- users.join(namespaces, Arel::Nodes::OuterJoin)
- .on(namespaces[:type].eq(nil).and(namespaces[:owner_id].eq(users[:id])))
- .where(namespaces[:owner_id].eq(nil))
- .where(condition)
- .project(users[:id], users[:username])
- end
-
- def create_namespace(user_id, username)
- path = Uniquify.new.string(username) do |str|
- query = "SELECT id FROM namespaces WHERE parent_id IS NULL AND path='#{str}' LIMIT 1"
- connection.exec_query(query).present?
- end
-
- insert_query = "INSERT INTO namespaces(owner_id, path, name, created_at, updated_at) VALUES(#{user_id}, '#{path}', '#{path}', NOW(), NOW())"
- namespace_id = connection.insert(insert_query)
-
- create_route(namespace_id)
- end
-
- def create_route(namespace_id)
- return unless namespace_id
-
- row = connection.exec_query("SELECT id, path FROM namespaces WHERE id=#{namespace_id}").first
- id, path = row.values_at('id', 'path')
-
- execute("INSERT INTO routes(source_id, source_type, path, name, created_at, updated_at) VALUES(#{id}, 'Namespace', '#{path}', '#{path}', NOW(), NOW())")
- end
-
- def set_notification_email(user_id)
- execute "UPDATE users SET notification_email = email WHERE notification_email IS NULL AND id = #{user_id}"
- end
-end
diff --git a/db/migrate/20180416155103_add_further_scope_columns_to_internal_id_table.rb b/db/migrate/20180416155103_add_further_scope_columns_to_internal_id_table.rb
deleted file mode 100644
index 7c28cbb6795..00000000000
--- a/db/migrate/20180416155103_add_further_scope_columns_to_internal_id_table.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class AddFurtherScopeColumnsToInternalIdTable < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- change_column_null :internal_ids, :project_id, true
- add_column :internal_ids, :namespace_id, :integer, null: true
- end
-
- def down
- change_column_null :internal_ids, :project_id, false
- remove_column :internal_ids, :namespace_id
- end
-end
diff --git a/db/migrate/20180417090132_add_index_constraints_to_internal_id_table.rb b/db/migrate/20180417090132_add_index_constraints_to_internal_id_table.rb
deleted file mode 100644
index ac6bb1a8cab..00000000000
--- a/db/migrate/20180417090132_add_index_constraints_to_internal_id_table.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-class AddIndexConstraintsToInternalIdTable < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :internal_ids, [:usage, :namespace_id], unique: true, where: 'namespace_id IS NOT NULL'
-
- replace_index(:internal_ids, [:usage, :project_id], name: 'index_internal_ids_on_usage_and_project_id') do
- add_concurrent_index :internal_ids, [:usage, :project_id], unique: true, where: 'project_id IS NOT NULL'
- end
-
- add_concurrent_foreign_key :internal_ids, :namespaces, column: :namespace_id, on_delete: :cascade
- end
-
- def down
- remove_concurrent_index :internal_ids, [:usage, :namespace_id]
-
- replace_index(:internal_ids, [:usage, :project_id], name: 'index_internal_ids_on_usage_and_project_id') do
- add_concurrent_index :internal_ids, [:usage, :project_id], unique: true
- end
-
- remove_foreign_key :internal_ids, column: :namespace_id
- end
-
- private
-
- def replace_index(table, columns, name:)
- temporary_name = "#{name}_old"
-
- if index_exists?(table, columns, name: name)
- rename_index table, name, temporary_name
- end
-
- yield
-
- remove_concurrent_index_by_name table, temporary_name
- end
-end
diff --git a/db/migrate/20180417101040_add_tmp_stage_priority_index_to_ci_builds.rb b/db/migrate/20180417101040_add_tmp_stage_priority_index_to_ci_builds.rb
deleted file mode 100644
index ce470884999..00000000000
--- a/db/migrate/20180417101040_add_tmp_stage_priority_index_to_ci_builds.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-class AddTmpStagePriorityIndexToCiBuilds < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index(:ci_builds, [:stage_id, :stage_idx],
- where: 'stage_idx IS NOT NULL', name: 'tmp_build_stage_position_index')
- end
-
- def down
- remove_concurrent_index_by_name(:ci_builds, 'tmp_build_stage_position_index')
- end
-end
diff --git a/db/migrate/20180417101940_add_index_to_ci_stage.rb b/db/migrate/20180417101940_add_index_to_ci_stage.rb
deleted file mode 100644
index 97a8f5efce0..00000000000
--- a/db/migrate/20180417101940_add_index_to_ci_stage.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class AddIndexToCiStage < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- add_column :ci_stages, :position, :integer
- end
-end
diff --git a/db/migrate/20180418053107_add_index_to_ci_job_artifacts_file_store.rb b/db/migrate/20180418053107_add_index_to_ci_job_artifacts_file_store.rb
deleted file mode 100644
index 4b574923483..00000000000
--- a/db/migrate/20180418053107_add_index_to_ci_job_artifacts_file_store.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-class AddIndexToCiJobArtifactsFileStore < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :ci_job_artifacts, :file_store
- end
-
- def down
- # rubocop:disable Migration/RemoveIndex
- remove_index :ci_job_artifacts, :file_store if index_exists?(:ci_job_artifacts, :file_store)
- end
-end
diff --git a/db/migrate/20180420010016_add_pipeline_build_foreign_key.rb b/db/migrate/20180420010016_add_pipeline_build_foreign_key.rb
deleted file mode 100644
index 90a908feaee..00000000000
--- a/db/migrate/20180420010016_add_pipeline_build_foreign_key.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-class AddPipelineBuildForeignKey < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- execute <<~SQL
- DELETE FROM ci_builds WHERE project_id IS NULL OR commit_id IS NULL
- SQL
-
- execute <<~SQL
- DELETE FROM ci_builds WHERE NOT EXISTS
- (SELECT true FROM ci_pipelines WHERE ci_pipelines.id = ci_builds.commit_id)
- AND stage_id IS NULL
- SQL
-
- add_concurrent_foreign_key(:ci_builds, :ci_pipelines, column: :commit_id)
- end
-
- def down
- return unless foreign_key_exists?(:ci_builds, :ci_pipelines, column: :commit_id)
-
- remove_foreign_key(:ci_builds, column: :commit_id)
- end
-end
diff --git a/db/migrate/20180420010616_cleanup_build_stage_migration.rb b/db/migrate/20180420010616_cleanup_build_stage_migration.rb
deleted file mode 100644
index 30c0d97781d..00000000000
--- a/db/migrate/20180420010616_cleanup_build_stage_migration.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-class CleanupBuildStageMigration < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- TMP_INDEX = 'tmp_id_stage_partial_null_index'.freeze
-
- disable_ddl_transaction!
-
- class Build < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'ci_builds'
- self.inheritance_column = :_type_disabled
- end
-
- def up
- disable_statement_timeout do
- ##
- # We steal from the background migrations queue to catch up with the
- # scheduled migrations set.
- #
- Gitlab::BackgroundMigration.steal('MigrateBuildStage')
-
- ##
- # We add temporary index, to make iteration over batches more performant.
- # Conditional here is to avoid the need of doing that in a separate
- # migration file to make this operation idempotent.
- #
- unless index_exists_by_name?(:ci_builds, TMP_INDEX)
- add_concurrent_index(:ci_builds, :id, where: 'stage_id IS NULL', name: TMP_INDEX)
- end
-
- ##
- # We check if there are remaining rows that should be migrated (for example
- # if Sidekiq / Redis fails / is restarted, what could result in not all
- # background migrations being executed correctly.
- #
- # We migrate remaining rows synchronously in a blocking way, to make sure
- # that when this migration is done we are confident that all rows are
- # already migrated.
- #
- Build.where('stage_id IS NULL').each_batch(of: 50) do |batch|
- range = batch.pluck('MIN(id)', 'MAX(id)').first
-
- Gitlab::BackgroundMigration::MigrateBuildStage.new.perform(*range)
- end
-
- ##
- # We remove temporary index, because it is not required during standard
- # operations and runtime.
- #
- remove_concurrent_index_by_name(:ci_builds, TMP_INDEX)
- end
- end
-
- def down
- if index_exists_by_name?(:ci_builds, TMP_INDEX)
- disable_statement_timeout do
- remove_concurrent_index_by_name(:ci_builds, TMP_INDEX)
- end
- end
- end
-end
diff --git a/db/migrate/20180423204600_add_pages_access_level_to_project_feature.rb b/db/migrate/20180423204600_add_pages_access_level_to_project_feature.rb
deleted file mode 100644
index acb6d04126e..00000000000
--- a/db/migrate/20180423204600_add_pages_access_level_to_project_feature.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-class AddPagesAccessLevelToProjectFeature < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
- disable_ddl_transaction!
-
- DOWNTIME = false
-
- # rubocop: disable Migration/UpdateLargeTable
- # rubocop: disable Migration/AddColumnWithDefault
- def up
- add_column_with_default(:project_features, :pages_access_level, :integer, default: ProjectFeature::PUBLIC, allow_null: false)
-
- change_column_default(:project_features, :pages_access_level, ProjectFeature::ENABLED)
- end
- # rubocop: enable Migration/UpdateLargeTable
- # rubocop: enable Migration/AddColumnWithDefault
-
- def down
- remove_column :project_features, :pages_access_level
- end
-end
diff --git a/db/migrate/20180424090541_add_enforce_terms_to_application_settings.rb b/db/migrate/20180424090541_add_enforce_terms_to_application_settings.rb
deleted file mode 100644
index b8fd71002a1..00000000000
--- a/db/migrate/20180424090541_add_enforce_terms_to_application_settings.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-class AddEnforceTermsToApplicationSettings < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- # rubocop:disable Migration/SaferBooleanColumn
- add_column :application_settings, :enforce_terms, :boolean, default: false
- end
-end
diff --git a/db/migrate/20180424134533_create_application_setting_terms.rb b/db/migrate/20180424134533_create_application_setting_terms.rb
deleted file mode 100644
index 41edb8a9559..00000000000
--- a/db/migrate/20180424134533_create_application_setting_terms.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class CreateApplicationSettingTerms < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- # rubocop:disable Migration/AddLimitToTextColumns
- def change
- create_table :application_setting_terms do |t|
- t.integer :cached_markdown_version
- t.text :terms, null: false
- t.text :terms_html
- end
- end
- # rubocop:enable Migration/AddLimitToTextColumns
-end
diff --git a/db/migrate/20180424160449_add_pipeline_iid_to_ci_pipelines.rb b/db/migrate/20180424160449_add_pipeline_iid_to_ci_pipelines.rb
deleted file mode 100644
index 550b5a2c149..00000000000
--- a/db/migrate/20180424160449_add_pipeline_iid_to_ci_pipelines.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-class AddPipelineIidToCiPipelines < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- add_column :ci_pipelines, :iid, :integer
- end
-
- def down
- remove_column :ci_pipelines, :iid, :integer
- end
-end
diff --git a/db/migrate/20180425075446_create_term_agreements.rb b/db/migrate/20180425075446_create_term_agreements.rb
deleted file mode 100644
index 25182215841..00000000000
--- a/db/migrate/20180425075446_create_term_agreements.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-class CreateTermAgreements < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- create_table :term_agreements do |t|
- t.references :term, index: true, null: false
- t.foreign_key :application_setting_terms, column: :term_id
- t.references :user, index: true, null: false, foreign_key: { on_delete: :cascade }
- t.boolean :accepted, default: false, null: false
-
- t.timestamps_with_timezone null: false
- end
-
- add_index :term_agreements, [:user_id, :term_id],
- unique: true,
- name: 'term_agreements_unique_index'
- end
-
- def down
- # rubocop:disable Migration/RemoveIndex
- remove_index :term_agreements, name: 'term_agreements_unique_index'
-
- drop_table :term_agreements
- end
-end
diff --git a/db/migrate/20180425131009_assure_commits_count_for_merge_request_diff.rb b/db/migrate/20180425131009_assure_commits_count_for_merge_request_diff.rb
deleted file mode 100644
index 7d38a15b850..00000000000
--- a/db/migrate/20180425131009_assure_commits_count_for_merge_request_diff.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-class AssureCommitsCountForMergeRequestDiff < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- class MergeRequestDiff < ActiveRecord::Base
- self.table_name = 'merge_request_diffs'
-
- include ::EachBatch
- end
-
- def up
- Gitlab::BackgroundMigration.steal('AddMergeRequestDiffCommitsCount')
-
- MergeRequestDiff.where(commits_count: nil).each_batch(of: 50) do |batch|
- range = batch.pluck('MIN(id)', 'MAX(id)').first
-
- Gitlab::BackgroundMigration::AddMergeRequestDiffCommitsCount.new.perform(*range)
- end
- end
-
- def down
- # noop
- end
-end
diff --git a/db/migrate/20180425205249_add_index_constraints_to_pipeline_iid.rb b/db/migrate/20180425205249_add_index_constraints_to_pipeline_iid.rb
deleted file mode 100644
index 8a0cb7ae4e4..00000000000
--- a/db/migrate/20180425205249_add_index_constraints_to_pipeline_iid.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class AddIndexConstraintsToPipelineIid < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :ci_pipelines, [:project_id, :iid], unique: true, where: 'iid IS NOT NULL'
- end
-
- def down
- remove_concurrent_index :ci_pipelines, [:project_id, :iid]
- end
-end
diff --git a/db/migrate/20180426102016_add_accepted_term_to_users.rb b/db/migrate/20180426102016_add_accepted_term_to_users.rb
deleted file mode 100644
index 3c6665b4264..00000000000
--- a/db/migrate/20180426102016_add_accepted_term_to_users.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddAcceptedTermToUsers < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- change_table :users do |t|
- t.references :accepted_term,
- null: true
- end
- add_concurrent_foreign_key :users, :application_setting_terms, column: :accepted_term_id
- end
-
- def down
- remove_foreign_key :users, column: :accepted_term_id
- remove_column :users, :accepted_term_id
- end
-end
diff --git a/db/migrate/20180430101916_add_runner_type_to_ci_runners.rb b/db/migrate/20180430101916_add_runner_type_to_ci_runners.rb
deleted file mode 100644
index a74231e0f44..00000000000
--- a/db/migrate/20180430101916_add_runner_type_to_ci_runners.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class AddRunnerTypeToCiRunners < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- add_column :ci_runners, :runner_type, :smallint
- end
-end
diff --git a/db/migrate/20180502122856_create_project_mirror_data.rb b/db/migrate/20180502122856_create_project_mirror_data.rb
deleted file mode 100644
index 1ecfd8926fb..00000000000
--- a/db/migrate/20180502122856_create_project_mirror_data.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-class CreateProjectMirrorData < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- # rubocop:disable Migration/AddLimitToTextColumns
- def up
- if table_exists?(:project_mirror_data)
- add_column :project_mirror_data, :status, :string unless column_exists?(:project_mirror_data, :status)
- add_column :project_mirror_data, :jid, :string unless column_exists?(:project_mirror_data, :jid)
- add_column :project_mirror_data, :last_error, :text unless column_exists?(:project_mirror_data, :last_error)
- else
- create_table :project_mirror_data do |t|
- t.references :project, index: true, foreign_key: { on_delete: :cascade }
- t.string :status
- t.string :jid
- t.text :last_error
- end
- end
- end
- # rubocop:enable Migration/AddLimitToTextColumns
- # rubocop:enable Migration/PreventStrings
-
- def down
- remove_column :project_mirror_data, :status
- remove_column :project_mirror_data, :jid
- remove_column :project_mirror_data, :last_error
-
- # ee/db/migrate/20170509153720_create_project_mirror_data_ee.rb will remove the table.
- end
-end
diff --git a/db/migrate/20180503131624_create_remote_mirrors.rb b/db/migrate/20180503131624_create_remote_mirrors.rb
deleted file mode 100644
index 330a0d8f62d..00000000000
--- a/db/migrate/20180503131624_create_remote_mirrors.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-class CreateRemoteMirrors < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- # rubocop:disable Migration/PreventStrings
- def up
- return if table_exists?(:remote_mirrors)
-
- create_table :remote_mirrors do |t|
- t.references :project, index: true, foreign_key: { on_delete: :cascade }
- t.string :url
- t.boolean :enabled, default: true
- t.string :update_status
- t.datetime :last_update_at # rubocop:disable Migration/Datetime
- t.datetime :last_successful_update_at # rubocop:disable Migration/Datetime
- t.datetime :last_update_started_at # rubocop:disable Migration/Datetime
- t.string :last_error
- t.boolean :only_protected_branches, default: false, null: false
- t.string :remote_name
- t.text :encrypted_credentials # rubocop:disable Migration/AddLimitToTextColumns
- t.string :encrypted_credentials_iv
- t.string :encrypted_credentials_salt
-
- # rubocop:disable Migration/Timestamps
- t.timestamps null: false
- end
- end
- # rubocop:enable Migration/PreventStrings
-
- def down
- # ee/db/migrate/20160321161032_create_remote_mirrors_ee.rb will remove the table
- end
-end
diff --git a/db/migrate/20180503141722_add_remote_mirror_available_overridden_to_projects.rb b/db/migrate/20180503141722_add_remote_mirror_available_overridden_to_projects.rb
deleted file mode 100644
index aa3d9a804ab..00000000000
--- a/db/migrate/20180503141722_add_remote_mirror_available_overridden_to_projects.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class AddRemoteMirrorAvailableOverriddenToProjects < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_column(:projects, :remote_mirror_available_overridden, :boolean) unless column_exists?(:projects, :remote_mirror_available_overridden) # rubocop:disable Migration/AddColumnsToWideTables
- end
-
- def down
- # ee/db/migrate/20171017130239_add_remote_mirror_available_overridden_to_projects_ee.rb will remove the column.
- end
-end
diff --git a/db/migrate/20180503150427_add_index_to_namespaces_runners_token.rb b/db/migrate/20180503150427_add_index_to_namespaces_runners_token.rb
deleted file mode 100644
index 899e4a05cbd..00000000000
--- a/db/migrate/20180503150427_add_index_to_namespaces_runners_token.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddIndexToNamespacesRunnersToken < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :namespaces, :runners_token, unique: true
- end
-
- def down
- if index_exists?(:namespaces, :runners_token, unique: true)
- # rubocop:disable Migration/RemoveIndex
- remove_index :namespaces, :runners_token
- end
- end
-end
diff --git a/db/migrate/20180503175053_ensure_missing_columns_to_project_mirror_data.rb b/db/migrate/20180503175053_ensure_missing_columns_to_project_mirror_data.rb
deleted file mode 100644
index 12ebac47850..00000000000
--- a/db/migrate/20180503175053_ensure_missing_columns_to_project_mirror_data.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-class EnsureMissingColumnsToProjectMirrorData < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- # rubocop:disable Migration/AddLimitToTextColumns
- # rubocop:disable Migration/PreventStrings
- def up
- add_column :project_mirror_data, :status, :string unless column_exists?(:project_mirror_data, :status)
- add_column :project_mirror_data, :jid, :string unless column_exists?(:project_mirror_data, :jid)
- add_column :project_mirror_data, :last_error, :text unless column_exists?(:project_mirror_data, :last_error)
- end
- # rubocop:enable Migration/PreventStrings
- # rubocop:enable Migration/AddLimitToTextColumns
-
- def down
- # db/migrate/20180502122856_create_project_mirror_data.rb will remove the table
- end
-end
diff --git a/db/migrate/20180503175054_add_indexes_to_project_mirror_data.rb b/db/migrate/20180503175054_add_indexes_to_project_mirror_data.rb
deleted file mode 100644
index 15a188594b0..00000000000
--- a/db/migrate/20180503175054_add_indexes_to_project_mirror_data.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-class AddIndexesToProjectMirrorData < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :project_mirror_data, :jid
- add_concurrent_index :project_mirror_data, :status
- end
-
- def down
- # rubocop:disable Migration/RemoveIndex
- remove_index :project_mirror_data, :jid if index_exists? :project_mirror_data, :jid
- remove_index :project_mirror_data, :status if index_exists? :project_mirror_data, :status
- end
-end
diff --git a/db/migrate/20180503193542_add_indexes_to_remote_mirror.rb b/db/migrate/20180503193542_add_indexes_to_remote_mirror.rb
deleted file mode 100644
index 19bed8d0500..00000000000
--- a/db/migrate/20180503193542_add_indexes_to_remote_mirror.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-class AddIndexesToRemoteMirror < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :remote_mirrors, :last_successful_update_at unless index_exists?(:remote_mirrors, :last_successful_update_at)
- end
-
- def down
- # ee/db/migrate/20170208144550_add_index_to_mirrors_last_update_at_fields.rb will remove the index.
- # rubocop:disable Migration/RemoveIndex
- remove_index :remote_mirrors, :last_successful_update_at if index_exists? :remote_mirrors, :last_successful_update_at
- end
-end
diff --git a/db/migrate/20180503193953_add_mirror_available_to_application_settings.rb b/db/migrate/20180503193953_add_mirror_available_to_application_settings.rb
deleted file mode 100644
index 117887a8bc2..00000000000
--- a/db/migrate/20180503193953_add_mirror_available_to_application_settings.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-class AddMirrorAvailableToApplicationSettings < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- # rubocop:disable Migration/AddColumnWithDefault
- add_column_with_default(:application_settings, :mirror_available, :boolean, default: true, allow_null: false) unless column_exists?(:application_settings, :mirror_available)
- # rubocop:enable Migration/AddColumnWithDefault
- end
-
- def down
- # ee/db/migrate/20171017125928_add_remote_mirror_available_to_application_settings.rb will remove the column.
- end
-end
diff --git a/db/migrate/20180503200320_enable_prometheus_metrics_by_default.rb b/db/migrate/20180503200320_enable_prometheus_metrics_by_default.rb
deleted file mode 100644
index bab3b178713..00000000000
--- a/db/migrate/20180503200320_enable_prometheus_metrics_by_default.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-class EnablePrometheusMetricsByDefault < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- def up
- change_column_default :application_settings, :prometheus_metrics_enabled, true
- end
-
- def down
- change_column_default :application_settings, :prometheus_metrics_enabled, false
- end
-end
diff --git a/db/migrate/20180504195842_project_name_lower_index.rb b/db/migrate/20180504195842_project_name_lower_index.rb
deleted file mode 100644
index e789837193f..00000000000
--- a/db/migrate/20180504195842_project_name_lower_index.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class ProjectNameLowerIndex < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
- INDEX_NAME = 'index_projects_on_lower_name'
-
- disable_ddl_transaction!
-
- def up
- disable_statement_timeout do
- execute "CREATE INDEX CONCURRENTLY #{INDEX_NAME} ON projects (LOWER(name))"
- end
- end
-
- def down
- disable_statement_timeout do
- execute "DROP INDEX CONCURRENTLY IF EXISTS #{INDEX_NAME}"
- end
- end
-end
diff --git a/db/migrate/20180508055821_make_remote_mirrors_disabled_by_default.rb b/db/migrate/20180508055821_make_remote_mirrors_disabled_by_default.rb
deleted file mode 100644
index 81aa18c8b86..00000000000
--- a/db/migrate/20180508055821_make_remote_mirrors_disabled_by_default.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-class MakeRemoteMirrorsDisabledByDefault < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- def up
- change_column_default :remote_mirrors, :enabled, false
- end
-
- def down
- change_column_default :remote_mirrors, :enabled, true
- end
-end
diff --git a/db/migrate/20180508100222_add_not_null_constraint_to_project_mirror_data_foreign_key.rb b/db/migrate/20180508100222_add_not_null_constraint_to_project_mirror_data_foreign_key.rb
deleted file mode 100644
index dba5d20f276..00000000000
--- a/db/migrate/20180508100222_add_not_null_constraint_to_project_mirror_data_foreign_key.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-class AddNotNullConstraintToProjectMirrorDataForeignKey < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- class ProjectImportState < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'project_mirror_data'
- end
-
- def up
- ProjectImportState.where(project_id: nil).delete_all
-
- change_column_null :project_mirror_data, :project_id, false
- end
-
- def down
- change_column_null :project_mirror_data, :project_id, true
- end
-end
diff --git a/db/migrate/20180508102840_add_unique_constraint_to_project_mirror_data_project_id_index.rb b/db/migrate/20180508102840_add_unique_constraint_to_project_mirror_data_project_id_index.rb
deleted file mode 100644
index b225354ca43..00000000000
--- a/db/migrate/20180508102840_add_unique_constraint_to_project_mirror_data_project_id_index.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-class AddUniqueConstraintToProjectMirrorDataProjectIdIndex < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index(:project_mirror_data,
- :project_id,
- unique: true,
- name: 'index_project_mirror_data_on_project_id_unique')
-
- remove_concurrent_index_by_name(:project_mirror_data, 'index_project_mirror_data_on_project_id')
-
- rename_index(:project_mirror_data,
- 'index_project_mirror_data_on_project_id_unique',
- 'index_project_mirror_data_on_project_id')
- end
-
- def down
- rename_index(:project_mirror_data,
- 'index_project_mirror_data_on_project_id',
- 'index_project_mirror_data_on_project_id_old')
-
- add_concurrent_index(:project_mirror_data, :project_id)
-
- remove_concurrent_index_by_name(:project_mirror_data,
- 'index_project_mirror_data_on_project_id_old')
- end
-end
diff --git a/db/migrate/20180508135515_set_runner_type_not_null.rb b/db/migrate/20180508135515_set_runner_type_not_null.rb
deleted file mode 100644
index 00c546c8f47..00000000000
--- a/db/migrate/20180508135515_set_runner_type_not_null.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class SetRunnerTypeNotNull < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- change_column_null(:ci_runners, :runner_type, false)
- end
-end
diff --git a/db/migrate/20180511090724_add_index_on_ci_runners_runner_type.rb b/db/migrate/20180511090724_add_index_on_ci_runners_runner_type.rb
deleted file mode 100644
index 4913b8602c9..00000000000
--- a/db/migrate/20180511090724_add_index_on_ci_runners_runner_type.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-class AddIndexOnCiRunnersRunnerType < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :ci_runners, :runner_type
- end
-
- def down
- # rubocop:disable Migration/RemoveIndex
- remove_index :ci_runners, :runner_type
- end
-end
diff --git a/db/migrate/20180511131058_create_clusters_applications_jupyter.rb b/db/migrate/20180511131058_create_clusters_applications_jupyter.rb
deleted file mode 100644
index 908a6113f98..00000000000
--- a/db/migrate/20180511131058_create_clusters_applications_jupyter.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class CreateClustersApplicationsJupyter < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- def change
- create_table :clusters_applications_jupyter do |t|
- t.references :cluster, null: false, unique: true, foreign_key: { on_delete: :cascade }
- t.references :oauth_application, foreign_key: { on_delete: :nullify }
-
- t.integer :status, null: false
- t.string :version, null: false
- t.string :hostname
-
- t.timestamps_with_timezone null: false
-
- t.text :status_reason # rubocop:disable Migration/AddLimitToTextColumns
- end
- end
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/migrate/20180515005612_add_squash_to_merge_requests.rb b/db/migrate/20180515005612_add_squash_to_merge_requests.rb
deleted file mode 100644
index dd301d22614..00000000000
--- a/db/migrate/20180515005612_add_squash_to_merge_requests.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddSquashToMergeRequests < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
- disable_ddl_transaction!
-
- DOWNTIME = false
-
- def up
- unless column_exists?(:merge_requests, :squash)
- # rubocop:disable Migration/UpdateLargeTable
- add_column_with_default :merge_requests, :squash, :boolean, default: false, allow_null: false # rubocop:disable Migration/AddColumnWithDefault
- end
- end
-
- def down
- remove_column :merge_requests, :squash if column_exists?(:merge_requests, :squash)
- end
-end
diff --git a/db/migrate/20180515121227_create_notes_diff_files.rb b/db/migrate/20180515121227_create_notes_diff_files.rb
deleted file mode 100644
index 1797a86c679..00000000000
--- a/db/migrate/20180515121227_create_notes_diff_files.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-class CreateNotesDiffFiles < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- # rubocop:disable Migration/AddLimitToTextColumns
- # rubocop:disable Migration/PreventStrings
- def change
- create_table :note_diff_files do |t|
- t.references :diff_note, references: :notes, null: false, index: { unique: true }
- t.text :diff, null: false
- t.boolean :new_file, null: false
- t.boolean :renamed_file, null: false
- t.boolean :deleted_file, null: false
- t.string :a_mode, null: false
- t.string :b_mode, null: false
- t.text :new_path, null: false
- t.text :old_path, null: false
- end
-
- # rubocop:disable Migration/AddConcurrentForeignKey
- add_foreign_key :note_diff_files, :notes, column: :diff_note_id, on_delete: :cascade
- # rubocop:enable Migration/AddConcurrentForeignKey
- end
- # rubocop:enable Migration/PreventStrings
- # rubocop:enable Migration/AddLimitToTextColumns
-end
diff --git a/db/migrate/20180517082340_add_not_null_constraints_to_project_authorizations.rb b/db/migrate/20180517082340_add_not_null_constraints_to_project_authorizations.rb
deleted file mode 100644
index 859e341d04b..00000000000
--- a/db/migrate/20180517082340_add_not_null_constraints_to_project_authorizations.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-class AddNotNullConstraintsToProjectAuthorizations < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- def up
- execute <<~SQL
- ALTER TABLE project_authorizations
- ALTER COLUMN user_id SET NOT NULL,
- ALTER COLUMN project_id SET NOT NULL,
- ALTER COLUMN access_level SET NOT NULL
- SQL
- end
-
- def down
- execute <<~SQL
- ALTER TABLE project_authorizations
- ALTER COLUMN user_id DROP NOT NULL,
- ALTER COLUMN project_id DROP NOT NULL,
- ALTER COLUMN access_level DROP NOT NULL
- SQL
- end
-end
diff --git a/db/migrate/20180523042841_rename_merge_requests_allow_maintainer_to_push.rb b/db/migrate/20180523042841_rename_merge_requests_allow_maintainer_to_push.rb
deleted file mode 100644
index 131dca1fbc2..00000000000
--- a/db/migrate/20180523042841_rename_merge_requests_allow_maintainer_to_push.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-class RenameMergeRequestsAllowMaintainerToPush < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- # NOOP
- end
-
- def down
- if column_exists?(:merge_requests, :allow_collaboration)
- cleanup_concurrent_column_rename :merge_requests, :allow_collaboration, :allow_maintainer_to_push
- end
- end
-end
diff --git a/db/migrate/20180524132016_merge_requests_target_id_iid_state_partial_index.rb b/db/migrate/20180524132016_merge_requests_target_id_iid_state_partial_index.rb
deleted file mode 100644
index bff4690427e..00000000000
--- a/db/migrate/20180524132016_merge_requests_target_id_iid_state_partial_index.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class MergeRequestsTargetIdIidStatePartialIndex < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- INDEX_NAME = 'index_merge_requests_on_target_project_id_and_iid_opened'
-
- disable_ddl_transaction!
-
- def up
- # On GitLab.com this index will take up roughly 5 MB of space.
- add_concurrent_index(
- :merge_requests,
- [:target_project_id, :iid],
- where: "state = 'opened'",
- name: INDEX_NAME
- )
- end
-
- def down
- remove_concurrent_index_by_name(:merge_requests, INDEX_NAME)
- end
-end
diff --git a/db/migrate/20180529093006_ensure_remote_mirror_columns.rb b/db/migrate/20180529093006_ensure_remote_mirror_columns.rb
deleted file mode 100644
index 8cf636e1da6..00000000000
--- a/db/migrate/20180529093006_ensure_remote_mirror_columns.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-class EnsureRemoteMirrorColumns < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- # rubocop:disable Migration/Datetime
- # rubocop:disable Migration/PreventStrings
- def up
- add_column :remote_mirrors, :last_update_started_at, :datetime unless column_exists?(:remote_mirrors, :last_update_started_at)
- add_column :remote_mirrors, :remote_name, :string unless column_exists?(:remote_mirrors, :remote_name)
-
- unless column_exists?(:remote_mirrors, :only_protected_branches)
- add_column_with_default(:remote_mirrors, # rubocop:disable Migration/AddColumnWithDefault
- :only_protected_branches,
- :boolean,
- default: false,
- allow_null: false)
- end
- end
- # rubocop:enable Migration/PreventStrings
- # rubocop:enable Migration/Datetime
-
- def down
- # db/migrate/20180503131624_create_remote_mirrors.rb will remove the table
- end
-end
diff --git a/db/migrate/20180530135500_add_index_to_stages_position.rb b/db/migrate/20180530135500_add_index_to_stages_position.rb
deleted file mode 100644
index eabf94ab8ec..00000000000
--- a/db/migrate/20180530135500_add_index_to_stages_position.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class AddIndexToStagesPosition < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :ci_stages, [:pipeline_id, :position]
- end
-
- def down
- remove_concurrent_index :ci_stages, [:pipeline_id, :position]
- end
-end
diff --git a/db/migrate/20180531185349_add_repository_languages.rb b/db/migrate/20180531185349_add_repository_languages.rb
deleted file mode 100644
index 08871e8b6f0..00000000000
--- a/db/migrate/20180531185349_add_repository_languages.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-class AddRepositoryLanguages < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- def up
- create_table(:programming_languages) do |t|
- t.string :name, null: false
- t.string :color, null: false
- t.datetime_with_timezone :created_at, null: false
- end
-
- create_table(:repository_languages, id: false) do |t|
- t.references :project, null: false, foreign_key: { on_delete: :cascade }
- t.references :programming_language, null: false
- t.float :share, null: false
- end
-
- add_index :programming_languages, :name, unique: true
- add_index :repository_languages, [:project_id, :programming_language_id],
- unique: true, name: "index_repository_languages_on_project_and_languages_id"
- end
- # rubocop:enable Migration/PreventStrings
-
- def down
- drop_table :repository_languages
- drop_table :programming_languages
- end
-end
diff --git a/db/migrate/20180531220618_change_default_value_for_dsa_key_restriction.rb b/db/migrate/20180531220618_change_default_value_for_dsa_key_restriction.rb
deleted file mode 100644
index cf621c46f2b..00000000000
--- a/db/migrate/20180531220618_change_default_value_for_dsa_key_restriction.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-class ChangeDefaultValueForDsaKeyRestriction < ActiveRecord::Migration[4.2]
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- def up
- change_column :application_settings, :dsa_key_restriction, :integer, null: false,
- default: -1
-
- execute("UPDATE application_settings SET dsa_key_restriction = -1")
- end
-
- def down
- change_column :application_settings, :dsa_key_restriction, :integer, null: false,
- default: 0
- end
-end
diff --git a/db/migrate/20180601213245_add_deploy_strategy_to_project_auto_devops.rb b/db/migrate/20180601213245_add_deploy_strategy_to_project_auto_devops.rb
deleted file mode 100644
index 67d20b949d9..00000000000
--- a/db/migrate/20180601213245_add_deploy_strategy_to_project_auto_devops.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddDeployStrategyToProjectAutoDevops < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_column_with_default :project_auto_devops, :deploy_strategy, :integer, default: 0, allow_null: false # rubocop:disable Migration/AddColumnWithDefault
- end
-
- def down
- remove_column :project_auto_devops, :deploy_strategy
- end
-end
diff --git a/db/migrate/20180607071808_add_push_events_branch_filter_to_web_hooks.rb b/db/migrate/20180607071808_add_push_events_branch_filter_to_web_hooks.rb
deleted file mode 100644
index 42bb0a784bb..00000000000
--- a/db/migrate/20180607071808_add_push_events_branch_filter_to_web_hooks.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddPushEventsBranchFilterToWebHooks < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- add_column :web_hooks, :push_events_branch_filter, :text # rubocop:disable Migration/AddLimitToTextColumns
- end
-end
diff --git a/db/migrate/20180608091413_add_group_to_todos.rb b/db/migrate/20180608091413_add_group_to_todos.rb
deleted file mode 100644
index 7f8efd78c59..00000000000
--- a/db/migrate/20180608091413_add_group_to_todos.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-class AddGroupToTodos < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- class Todo < ActiveRecord::Base
- self.table_name = 'todos'
-
- include ::EachBatch
- end
-
- def up
- add_column(:todos, :group_id, :integer) unless group_id_exists?
- add_concurrent_foreign_key :todos, :namespaces, column: :group_id, on_delete: :cascade
- add_concurrent_index :todos, :group_id
-
- change_column_null :todos, :project_id, true
- end
-
- def down
- remove_foreign_key_without_error(:todos, column: :group_id)
- remove_concurrent_index(:todos, :group_id)
- remove_column(:todos, :group_id) if group_id_exists?
-
- Todo.where(project_id: nil).each_batch { |batch| batch.delete_all }
- change_column_null :todos, :project_id, false
- end
-
- private
-
- def group_id_exists?
- column_exists?(:todos, :group_id)
- end
-end
diff --git a/db/migrate/20180608110058_rename_merge_requests_allow_collaboration.rb b/db/migrate/20180608110058_rename_merge_requests_allow_collaboration.rb
deleted file mode 100644
index 0f2d5ba3a5e..00000000000
--- a/db/migrate/20180608110058_rename_merge_requests_allow_collaboration.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class RenameMergeRequestsAllowCollaboration < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- if column_exists?(:merge_requests, :allow_collaboration)
- # rubocop:disable Migration/UpdateLargeTable
- rename_column_concurrently :merge_requests, :allow_collaboration, :allow_maintainer_to_push
- end
- end
-
- def down
- # NOOP
- end
-end
diff --git a/db/migrate/20180612103626_add_columns_for_helm_tiller_certificates.rb b/db/migrate/20180612103626_add_columns_for_helm_tiller_certificates.rb
deleted file mode 100644
index 515aab45145..00000000000
--- a/db/migrate/20180612103626_add_columns_for_helm_tiller_certificates.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# frozen_string_literal: true
-class AddColumnsForHelmTillerCertificates < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- # rubocop:disable Migration/AddLimitToTextColumns
- def change
- add_column :clusters_applications_helm, :encrypted_ca_key, :text
- add_column :clusters_applications_helm, :encrypted_ca_key_iv, :text
- add_column :clusters_applications_helm, :ca_cert, :text
- end
- # rubocop:enable Migration/AddLimitToTextColumns
-end
diff --git a/db/migrate/20180613081317_create_ci_builds_runner_session.rb b/db/migrate/20180613081317_create_ci_builds_runner_session.rb
deleted file mode 100644
index 29e133de1b7..00000000000
--- a/db/migrate/20180613081317_create_ci_builds_runner_session.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class CreateCiBuildsRunnerSession < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- def change
- create_table :ci_builds_runner_session, id: :bigserial do |t|
- t.integer :build_id, null: false
- t.string :url, null: false
- t.string :certificate
- t.string :authorization
-
- t.foreign_key :ci_builds, column: :build_id, on_delete: :cascade
- t.index :build_id, unique: true
- end
- end
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/migrate/20180625113853_create_import_export_uploads.rb b/db/migrate/20180625113853_create_import_export_uploads.rb
deleted file mode 100644
index 2fe5a1e7f6b..00000000000
--- a/db/migrate/20180625113853_create_import_export_uploads.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-class CreateImportExportUploads < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- # rubocop:disable Migration/AddLimitToTextColumns
- def change
- create_table :import_export_uploads do |t|
- t.datetime_with_timezone :updated_at, null: false
-
- t.references :project, index: true, foreign_key: { on_delete: :cascade }, unique: true
-
- t.text :import_file
- t.text :export_file
- end
-
- add_index :import_export_uploads, :updated_at
- end
- # rubocop:enable Migration/AddLimitToTextColumns
-end
diff --git a/db/migrate/20180626125654_add_index_on_deployable_for_deployments.rb b/db/migrate/20180626125654_add_index_on_deployable_for_deployments.rb
deleted file mode 100644
index 0fc14b43fae..00000000000
--- a/db/migrate/20180626125654_add_index_on_deployable_for_deployments.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddIndexOnDeployableForDeployments < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :deployments, [:deployable_type, :deployable_id]
- end
-
- def down
- remove_concurrent_index :deployments, [:deployable_type, :deployable_id]
- end
-end
diff --git a/db/migrate/20180628124813_alter_web_hook_logs_indexes.rb b/db/migrate/20180628124813_alter_web_hook_logs_indexes.rb
deleted file mode 100644
index 64ef165c5e6..00000000000
--- a/db/migrate/20180628124813_alter_web_hook_logs_indexes.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# frozen_string_literal: true
-
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AlterWebHookLogsIndexes < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- # "created_at" comes first so the Sidekiq worker pruning old webhook logs can
- # use a composite index.
- #
- # We leave the old standalone index on "web_hook_id" in place so future code
- # that doesn't care about "created_at" can still use that index.
- COLUMNS_TO_INDEX = %i[created_at web_hook_id]
-
- def up
- add_concurrent_index(:web_hook_logs, COLUMNS_TO_INDEX)
- end
-
- def down
- remove_concurrent_index(:web_hook_logs, COLUMNS_TO_INDEX)
- end
-end
diff --git a/db/migrate/20180629153018_create_site_statistics.rb b/db/migrate/20180629153018_create_site_statistics.rb
deleted file mode 100644
index 60a32b3b2a7..00000000000
--- a/db/migrate/20180629153018_create_site_statistics.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-class CreateSiteStatistics < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- create_table :site_statistics do |t|
- t.integer :repositories_count, default: 0, null: false
- t.integer :wikis_count, default: 0, null: false
- end
-
- execute('INSERT INTO site_statistics (id) VALUES(1)')
- end
-
- def down
- drop_table :site_statistics
- end
-end
diff --git a/db/migrate/20180702124358_remove_orphaned_routes.rb b/db/migrate/20180702124358_remove_orphaned_routes.rb
deleted file mode 100644
index 62c15f9cd00..00000000000
--- a/db/migrate/20180702124358_remove_orphaned_routes.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class RemoveOrphanedRoutes < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- class Route < ActiveRecord::Base
- self.table_name = 'routes'
- include EachBatch
-
- def self.orphaned_namespace_routes
- where(source_type: 'Namespace')
- .where('NOT EXISTS ( SELECT 1 FROM namespaces WHERE namespaces.id = routes.source_id )')
- end
-
- def self.orphaned_project_routes
- where(source_type: 'Project')
- .where('NOT EXISTS ( SELECT 1 FROM projects WHERE projects.id = routes.source_id )')
- end
- end
-
- def up
- # Some of these queries can take up to 10 seconds to run on GitLab.com,
- # which is pretty close to our 15 second statement timeout. To ensure a
- # smooth deployment procedure we disable the statement timeouts for this
- # migration, just in case.
- disable_statement_timeout do
- # On GitLab.com there are around 4000 orphaned project routes, and around
- # 150 orphaned namespace routes.
- [
- Route.orphaned_project_routes,
- Route.orphaned_namespace_routes
- ].each do |relation|
- relation.each_batch(of: 1_000) do |batch|
- batch.delete_all
- end
- end
- end
- end
-
- def down
- # There is no way to restore orphaned routes, and this doesn't make any
- # sense anyway.
- end
-end
diff --git a/db/migrate/20180702134423_generate_missing_routes.rb b/db/migrate/20180702134423_generate_missing_routes.rb
deleted file mode 100644
index dd1106c9e6a..00000000000
--- a/db/migrate/20180702134423_generate_missing_routes.rb
+++ /dev/null
@@ -1,144 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-# This migration generates missing routes for any projects and namespaces that
-# don't already have a route.
-#
-# On GitLab.com this would insert 611 project routes, and 0 namespace routes.
-# The exact number could vary per instance, so we take care of both just in
-# case.
-class GenerateMissingRoutes < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- class User < ActiveRecord::Base
- self.table_name = 'users'
- end
-
- class Route < ActiveRecord::Base
- self.table_name = 'routes'
- end
-
- module Routable
- def build_full_path
- if parent && path
- parent.build_full_path + '/' + path
- else
- path
- end
- end
-
- def build_full_name
- if parent && name
- parent.human_name + ' / ' + name
- else
- name
- end
- end
-
- def human_name
- build_full_name
- end
-
- def attributes_for_insert
- time = Time.zone.now
-
- {
- # We can't use "self.class.name" here as that would include the
- # migration namespace.
- source_type: source_type_for_route,
- source_id: id,
- created_at: time,
- updated_at: time,
- name: build_full_name,
-
- # The route path might already be taken. Instead of trying to generate a
- # new unique name on every conflict, we just append the row ID to the
- # route path.
- path: "#{build_full_path}-#{id}"
- }
- end
- end
-
- class Project < ActiveRecord::Base
- self.table_name = 'projects'
-
- include EachBatch
- include GenerateMissingRoutes::Routable
-
- belongs_to :namespace, class_name: 'GenerateMissingRoutes::Namespace'
-
- has_one :route,
- as: :source,
- inverse_of: :source,
- class_name: 'GenerateMissingRoutes::Route'
-
- alias_method :parent, :namespace
- alias_attribute :parent_id, :namespace_id
-
- def self.without_routes
- where(
- 'NOT EXISTS (
- SELECT 1
- FROM routes
- WHERE source_type = ?
- AND source_id = projects.id
- )',
- 'Project'
- )
- end
-
- def source_type_for_route
- 'Project'
- end
- end
-
- class Namespace < ActiveRecord::Base
- self.table_name = 'namespaces'
- self.inheritance_column = :_type_disabled
-
- include EachBatch
- include GenerateMissingRoutes::Routable
-
- belongs_to :parent, class_name: 'GenerateMissingRoutes::Namespace'
- belongs_to :owner, class_name: 'GenerateMissingRoutes::User'
-
- has_one :route,
- as: :source,
- inverse_of: :source,
- class_name: 'GenerateMissingRoutes::Route'
-
- def self.without_routes
- where(
- 'NOT EXISTS (
- SELECT 1
- FROM routes
- WHERE source_type = ?
- AND source_id = namespaces.id
- )',
- 'Namespace'
- )
- end
-
- def source_type_for_route
- 'Namespace'
- end
- end
-
- def up
- [Namespace, Project].each do |model|
- model.without_routes.each_batch(of: 100) do |batch|
- rows = batch.map(&:attributes_for_insert)
-
- Gitlab::Database.bulk_insert(:routes, rows)
- end
- end
- end
-
- def down
- # Removing routes we previously generated makes no sense.
- end
-end
diff --git a/db/migrate/20180704204006_add_hide_third_party_offers_to_application_settings.rb b/db/migrate/20180704204006_add_hide_third_party_offers_to_application_settings.rb
deleted file mode 100644
index b037f72a964..00000000000
--- a/db/migrate/20180704204006_add_hide_third_party_offers_to_application_settings.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-class AddHideThirdPartyOffersToApplicationSettings < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_column_with_default(:application_settings, :hide_third_party_offers, # rubocop:disable Migration/AddColumnWithDefault
- :boolean,
- default: false,
- allow_null: false)
- end
-
- def down
- remove_column(:application_settings, :hide_third_party_offers)
- end
-end
diff --git a/db/migrate/20180705160945_add_file_format_to_ci_job_artifacts.rb b/db/migrate/20180705160945_add_file_format_to_ci_job_artifacts.rb
deleted file mode 100644
index 938438841a5..00000000000
--- a/db/migrate/20180705160945_add_file_format_to_ci_job_artifacts.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class AddFileFormatToCiJobArtifacts < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- def change
- add_column :ci_job_artifacts, :file_format, :integer, limit: 2
- end
-end
diff --git a/db/migrate/20180710162338_add_foreign_key_from_notification_settings_to_users.rb b/db/migrate/20180710162338_add_foreign_key_from_notification_settings_to_users.rb
deleted file mode 100644
index 79691f2b24c..00000000000
--- a/db/migrate/20180710162338_add_foreign_key_from_notification_settings_to_users.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-class AddForeignKeyFromNotificationSettingsToUsers < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- class NotificationSetting < ActiveRecord::Base
- self.table_name = 'notification_settings'
-
- include EachBatch
- end
-
- class User < ActiveRecord::Base
- self.table_name = 'users'
- end
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- NotificationSetting.each_batch(of: 1000) do |batch|
- batch.where('NOT EXISTS (?)', User.select(1).where('users.id = notification_settings.user_id'))
- .delete_all
- end
-
- add_concurrent_foreign_key(:notification_settings, :users, column: :user_id, on_delete: :cascade)
- end
-
- def down
- remove_foreign_key(:notification_settings, column: :user_id)
- end
-end
diff --git a/db/migrate/20180711103851_drop_duplicate_protected_tags.rb b/db/migrate/20180711103851_drop_duplicate_protected_tags.rb
deleted file mode 100644
index 94f72aa162d..00000000000
--- a/db/migrate/20180711103851_drop_duplicate_protected_tags.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class DropDuplicateProtectedTags < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- BATCH_SIZE = 1000
-
- class Project < ActiveRecord::Base
- self.table_name = 'projects'
-
- include ::EachBatch
- end
-
- class ProtectedTag < ActiveRecord::Base
- self.table_name = 'protected_tags'
- end
-
- def up
- Project.each_batch(of: BATCH_SIZE) do |projects|
- ids = ProtectedTag
- .where(project_id: projects)
- .group(:name, :project_id)
- .select('max(id)')
-
- tags = ProtectedTag
- .where(project_id: projects)
- .where.not(id: ids)
-
- tags.delete_all
- end
- end
-
- def down
- end
-end
diff --git a/db/migrate/20180711103922_add_protected_tags_index.rb b/db/migrate/20180711103922_add_protected_tags_index.rb
deleted file mode 100644
index ef81ca633c3..00000000000
--- a/db/migrate/20180711103922_add_protected_tags_index.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddProtectedTagsIndex < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :protected_tags, [:project_id, :name], unique: true
- end
-
- def down
- remove_concurrent_index :protected_tags, [:project_id, :name]
- end
-end
diff --git a/db/migrate/20180713092803_create_user_statuses.rb b/db/migrate/20180713092803_create_user_statuses.rb
deleted file mode 100644
index 79a12c9b8ee..00000000000
--- a/db/migrate/20180713092803_create_user_statuses.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-class CreateUserStatuses < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- def change
- create_table :user_statuses, id: false, primary_key: :user_id do |t|
- t.references :user,
- foreign_key: { on_delete: :cascade },
- null: false,
- primary_key: true
- t.integer :cached_markdown_version, limit: 4
- t.string :emoji, null: false, default: 'speech_balloon'
- t.string :message, limit: 100
- t.string :message_html
- end
- end
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/migrate/20180717125853_remove_restricted_todos.rb b/db/migrate/20180717125853_remove_restricted_todos.rb
deleted file mode 100644
index 1d4bbf6571e..00000000000
--- a/db/migrate/20180717125853_remove_restricted_todos.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-# frozen_string_literal: true
-
-class RemoveRestrictedTodos < ActiveRecord::Migration[4.2]
- DOWNTIME = false
- disable_ddl_transaction!
-
- MIGRATION = 'RemoveRestrictedTodos'.freeze
- BATCH_SIZE = 1000
- DELAY_INTERVAL = 5.minutes.to_i
-
- class Project < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'projects'
- end
-
- def up
- Project.where('EXISTS (SELECT 1 FROM todos WHERE todos.project_id = projects.id)')
- .each_batch(of: BATCH_SIZE) do |batch, index|
- range = batch.pluck('MIN(id)', 'MAX(id)').first
-
- BackgroundMigrationWorker.perform_in(index * DELAY_INTERVAL, MIGRATION, range)
- end
- end
-
- def down
- # nothing to do
- end
-end
diff --git a/db/migrate/20180718005113_add_instance_statistics_visibility_to_application_setting.rb b/db/migrate/20180718005113_add_instance_statistics_visibility_to_application_setting.rb
deleted file mode 100644
index 9e453be8c57..00000000000
--- a/db/migrate/20180718005113_add_instance_statistics_visibility_to_application_setting.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-class AddInstanceStatisticsVisibilityToApplicationSetting < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_column_with_default(:application_settings, :instance_statistics_visibility_private, # rubocop:disable Migration/AddColumnWithDefault
- :boolean,
- default: false,
- allow_null: false)
- end
-
- def down
- remove_column(:application_settings, :instance_statistics_visibility_private)
- end
-end
diff --git a/db/migrate/20180720023512_add_receive_max_input_size_to_application_settings.rb b/db/migrate/20180720023512_add_receive_max_input_size_to_application_settings.rb
deleted file mode 100644
index 0cf3c78507e..00000000000
--- a/db/migrate/20180720023512_add_receive_max_input_size_to_application_settings.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddReceiveMaxInputSizeToApplicationSettings < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- def change
- add_column :application_settings, :receive_max_input_size, :integer
- end
-end
diff --git a/db/migrate/20180722103201_add_private_profile_to_users.rb b/db/migrate/20180722103201_add_private_profile_to_users.rb
deleted file mode 100644
index 63b7a631fc8..00000000000
--- a/db/migrate/20180722103201_add_private_profile_to_users.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddPrivateProfileToUsers < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- def change
- add_column :users, :private_profile, :boolean # rubocop:disable Migration/AddColumnsToWideTables
- end
-end
diff --git a/db/migrate/20180723135214_add_web_ide_client_side_preview_enabled_to_application_settings.rb b/db/migrate/20180723135214_add_web_ide_client_side_preview_enabled_to_application_settings.rb
deleted file mode 100644
index 96b5c43d0a3..00000000000
--- a/db/migrate/20180723135214_add_web_ide_client_side_preview_enabled_to_application_settings.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-class AddWebIdeClientSidePreviewEnabledToApplicationSettings < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_column_with_default(:application_settings, :web_ide_clientside_preview_enabled, # rubocop:disable Migration/AddColumnWithDefault
- :boolean,
- default: false,
- allow_null: false)
- end
-
- def down
- remove_column(:application_settings, :web_ide_clientside_preview_enabled)
- end
-end
diff --git a/db/migrate/20180726172057_create_resource_label_events.rb b/db/migrate/20180726172057_create_resource_label_events.rb
deleted file mode 100644
index 550e35d6f90..00000000000
--- a/db/migrate/20180726172057_create_resource_label_events.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-class CreateResourceLabelEvents < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- create_table :resource_label_events, id: :bigserial do |t|
- t.integer :action, null: false
- t.references :issue, null: true, index: true, foreign_key: { on_delete: :cascade }
- t.references :merge_request, null: true, index: true, foreign_key: { on_delete: :cascade }
- t.references :label, index: true, foreign_key: { on_delete: :nullify }
- t.references :user, index: true, foreign_key: { on_delete: :nullify }
- t.datetime_with_timezone :created_at, null: false
- end
- end
-end
diff --git a/db/migrate/20180807153545_remove_redundant_status_index_on_ci_builds.rb b/db/migrate/20180807153545_remove_redundant_status_index_on_ci_builds.rb
deleted file mode 100644
index c957fc2f6fc..00000000000
--- a/db/migrate/20180807153545_remove_redundant_status_index_on_ci_builds.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class RemoveRedundantStatusIndexOnCiBuilds < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- remove_concurrent_index :ci_builds, :status
- end
-
- def down
- add_concurrent_index :ci_builds, :status
- end
-end
diff --git a/db/migrate/20180808162000_add_user_show_add_ssh_key_message_to_application_settings.rb b/db/migrate/20180808162000_add_user_show_add_ssh_key_message_to_application_settings.rb
deleted file mode 100644
index 6bf54f79644..00000000000
--- a/db/migrate/20180808162000_add_user_show_add_ssh_key_message_to_application_settings.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddUserShowAddSshKeyMessageToApplicationSettings < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- # rubocop:disable Migration/AddColumnWithDefault
- add_column_with_default :application_settings, :user_show_add_ssh_key_message, :boolean, default: true, allow_null: false
- # rubocop:enable Migration/AddColumnWithDefault
- end
-
- def down
- remove_column :application_settings, :user_show_add_ssh_key_message
- end
-end
diff --git a/db/migrate/20180813101999_change_default_of_auto_devops_instance_wide.rb b/db/migrate/20180813101999_change_default_of_auto_devops_instance_wide.rb
deleted file mode 100644
index da101bc76e3..00000000000
--- a/db/migrate/20180813101999_change_default_of_auto_devops_instance_wide.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-class ChangeDefaultOfAutoDevopsInstanceWide < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- change_column_default :application_settings, :auto_devops_enabled, true
- end
-
- def down
- change_column_default :application_settings, :auto_devops_enabled, false
- end
-end
diff --git a/db/migrate/20180813102000_enable_auto_devops_instance_wide_for_everyone.rb b/db/migrate/20180813102000_enable_auto_devops_instance_wide_for_everyone.rb
deleted file mode 100644
index 1531fad2c6c..00000000000
--- a/db/migrate/20180813102000_enable_auto_devops_instance_wide_for_everyone.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-class EnableAutoDevopsInstanceWideForEveryone < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- execute "UPDATE application_settings SET auto_devops_enabled = true"
- end
-
- def down
- # No way to know here what their previous setting was...
- end
-end
diff --git a/db/migrate/20180814153625_add_commit_email_to_users.rb b/db/migrate/20180814153625_add_commit_email_to_users.rb
deleted file mode 100644
index c94ee9512de..00000000000
--- a/db/migrate/20180814153625_add_commit_email_to_users.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-# frozen_string_literal: true
-
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddCommitEmailToUsers < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- # When a migration requires downtime you **must** uncomment the following
- # constant and define a short and easy to understand explanation as to why the
- # migration requires downtime.
- # DOWNTIME_REASON = ''
-
- # When using the methods "add_concurrent_index", "remove_concurrent_index" or
- # "add_column_with_default" you must disable the use of transactions
- # as these methods can not run in an existing transaction.
- # When using "add_concurrent_index" or "remove_concurrent_index" methods make sure
- # that either of them is the _only_ method called in the migration,
- # any other changes should go in a separate migration.
- # This ensures that upon failure _only_ the index creation or removing fails
- # and can be retried or reverted easily.
- #
- # To disable transactions uncomment the following line and remove these
- # comments:
- # disable_ddl_transaction!
-
- # rubocop:disable Migration/PreventStrings
- # rubocop:disable Migration/AddColumnsToWideTables
- def change
- add_column :users, :commit_email, :string
- end
- # rubocop:enable Migration/AddColumnsToWideTables
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/migrate/20180815040323_add_authorization_type_to_cluster_platforms_kubernetes.rb b/db/migrate/20180815040323_add_authorization_type_to_cluster_platforms_kubernetes.rb
deleted file mode 100644
index 44125b4696a..00000000000
--- a/db/migrate/20180815040323_add_authorization_type_to_cluster_platforms_kubernetes.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-class AddAuthorizationTypeToClusterPlatformsKubernetes < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- add_column :cluster_platforms_kubernetes, :authorization_type, :integer, limit: 2
- end
-end
diff --git a/db/migrate/20180815160409_add_file_location_to_ci_job_artifacts.rb b/db/migrate/20180815160409_add_file_location_to_ci_job_artifacts.rb
deleted file mode 100644
index 389101902d0..00000000000
--- a/db/migrate/20180815160409_add_file_location_to_ci_job_artifacts.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class AddFileLocationToCiJobArtifacts < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- add_column :ci_job_artifacts, :file_location, :integer, limit: 2
- end
-end
diff --git a/db/migrate/20180815170510_add_partial_index_to_ci_builds_artifacts_file.rb b/db/migrate/20180815170510_add_partial_index_to_ci_builds_artifacts_file.rb
deleted file mode 100644
index 237e6ba4559..00000000000
--- a/db/migrate/20180815170510_add_partial_index_to_ci_builds_artifacts_file.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-class AddPartialIndexToCiBuildsArtifactsFile < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- INDEX_NAME = 'partial_index_ci_builds_on_id_with_legacy_artifacts'.freeze
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index(:ci_builds, :id, where: "artifacts_file <> ''", name: INDEX_NAME)
- end
-
- def down
- remove_concurrent_index_by_name(:ci_builds, INDEX_NAME)
- end
-end
diff --git a/db/migrate/20180815175440_add_index_on_list_type.rb b/db/migrate/20180815175440_add_index_on_list_type.rb
deleted file mode 100644
index 3fe0f6b8de5..00000000000
--- a/db/migrate/20180815175440_add_index_on_list_type.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: true
-class AddIndexOnListType < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :lists, :list_type
- end
-
- def down
- remove_concurrent_index :lists, :list_type
- end
-end
diff --git a/db/migrate/20180824202952_add_outbound_requests_whitelist_to_application_settings.rb b/db/migrate/20180824202952_add_outbound_requests_whitelist_to_application_settings.rb
deleted file mode 100644
index 7b87b04bc9d..00000000000
--- a/db/migrate/20180824202952_add_outbound_requests_whitelist_to_application_settings.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-class AddOutboundRequestsWhitelistToApplicationSettings < ActiveRecord::Migration[5.1]
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- def change
- add_column :application_settings, :outbound_local_requests_whitelist, :string, array: true, limit: 255
- end
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/migrate/20180831164905_add_common_to_prometheus_metrics.rb b/db/migrate/20180831164905_add_common_to_prometheus_metrics.rb
deleted file mode 100644
index 6654e6d1957..00000000000
--- a/db/migrate/20180831164905_add_common_to_prometheus_metrics.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class AddCommonToPrometheusMetrics < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_column_with_default(:prometheus_metrics, :common, :boolean, default: false) # rubocop:disable Migration/AddColumnWithDefault
- end
-
- def down
- remove_column(:prometheus_metrics, :common)
- end
-end
diff --git a/db/migrate/20180831164907_add_index_on_common_for_prometheus_metrics.rb b/db/migrate/20180831164907_add_index_on_common_for_prometheus_metrics.rb
deleted file mode 100644
index 5758321891a..00000000000
--- a/db/migrate/20180831164907_add_index_on_common_for_prometheus_metrics.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class AddIndexOnCommonForPrometheusMetrics < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :prometheus_metrics, :common
- end
-
- def down
- remove_concurrent_index :prometheus_metrics, :common
- end
-end
diff --git a/db/migrate/20180831164908_add_identifier_to_prometheus_metric.rb b/db/migrate/20180831164908_add_identifier_to_prometheus_metric.rb
deleted file mode 100644
index efdcab53920..00000000000
--- a/db/migrate/20180831164908_add_identifier_to_prometheus_metric.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-class AddIdentifierToPrometheusMetric < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- add_column :prometheus_metrics, :identifier, :string # rubocop:disable Migration/PreventStrings
- end
-end
diff --git a/db/migrate/20180831164909_add_index_for_identifier_to_prometheus_metric.rb b/db/migrate/20180831164909_add_index_for_identifier_to_prometheus_metric.rb
deleted file mode 100644
index 1f6cfc181f4..00000000000
--- a/db/migrate/20180831164909_add_index_for_identifier_to_prometheus_metric.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class AddIndexForIdentifierToPrometheusMetric < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :prometheus_metrics, :identifier, unique: true
- end
-
- def down
- remove_concurrent_index :prometheus_metrics, :identifier, unique: true
- end
-end
diff --git a/db/migrate/20180831164910_import_common_metrics.rb b/db/migrate/20180831164910_import_common_metrics.rb
deleted file mode 100644
index 4e61a25c1ad..00000000000
--- a/db/migrate/20180831164910_import_common_metrics.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-class ImportCommonMetrics < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- ::Gitlab::DatabaseImporters::CommonMetrics::Importer.new.execute
- end
-
- def down
- # no-op
- end
-end
diff --git a/db/migrate/20180901171833_add_project_config_source_status_index_to_pipeline.rb b/db/migrate/20180901171833_add_project_config_source_status_index_to_pipeline.rb
deleted file mode 100644
index f2136657d95..00000000000
--- a/db/migrate/20180901171833_add_project_config_source_status_index_to_pipeline.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class AddProjectConfigSourceStatusIndexToPipeline < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :ci_pipelines, [:project_id, :status, :config_source]
- end
-
- def down
- remove_concurrent_index :ci_pipelines, [:project_id, :status, :config_source]
- end
-end
diff --git a/db/migrate/20180901200537_add_resource_label_event_reference_fields.rb b/db/migrate/20180901200537_add_resource_label_event_reference_fields.rb
deleted file mode 100644
index 2dc86e1ac9a..00000000000
--- a/db/migrate/20180901200537_add_resource_label_event_reference_fields.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-# frozen_string_literal: true
-
-class AddResourceLabelEventReferenceFields < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- # rubocop:disable Migration/AddLimitToTextColumns
- def change
- add_column :resource_label_events, :cached_markdown_version, :integer
- add_column :resource_label_events, :reference, :text
- add_column :resource_label_events, :reference_html, :text
- end
- # rubocop:enable Migration/AddLimitToTextColumns
-end
diff --git a/db/migrate/20180902070406_create_group_group_links.rb b/db/migrate/20180902070406_create_group_group_links.rb
deleted file mode 100644
index 95fed0ebf96..00000000000
--- a/db/migrate/20180902070406_create_group_group_links.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-class CreateGroupGroupLinks < ActiveRecord::Migration[5.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- create_table :group_group_links do |t|
- t.timestamps_with_timezone null: false
-
- t.references :shared_group, null: false,
- index: false,
- foreign_key: { on_delete: :cascade,
- to_table: :namespaces }
- t.references :shared_with_group, null: false,
- foreign_key: { on_delete: :cascade,
- to_table: :namespaces }
- t.date :expires_at
- t.index [:shared_group_id, :shared_with_group_id],
- { unique: true,
- name: 'index_group_group_links_on_shared_group_and_shared_with_group' }
- t.integer :group_access, { limit: 2,
- default: 30, # Gitlab::Access::DEVELOPER
- null: false }
- end
- end
-
- def down
- drop_table :group_group_links
- end
-end
diff --git a/db/migrate/20180906101639_add_user_ping_consent_to_application_settings.rb b/db/migrate/20180906101639_add_user_ping_consent_to_application_settings.rb
deleted file mode 100644
index 334efa12e7b..00000000000
--- a/db/migrate/20180906101639_add_user_ping_consent_to_application_settings.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class AddUserPingConsentToApplicationSettings < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_column :application_settings, :usage_stats_set_by_user_id, :integer
- add_concurrent_foreign_key :application_settings, :users, column: :usage_stats_set_by_user_id, on_delete: :nullify
- end
-
- def down
- remove_foreign_key :application_settings, column: :usage_stats_set_by_user_id
- remove_column :application_settings, :usage_stats_set_by_user_id
- end
-end
diff --git a/db/migrate/20180907015926_add_legacy_abac_to_cluster_providers_gcp.rb b/db/migrate/20180907015926_add_legacy_abac_to_cluster_providers_gcp.rb
deleted file mode 100644
index 8bfb0c5612a..00000000000
--- a/db/migrate/20180907015926_add_legacy_abac_to_cluster_providers_gcp.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class AddLegacyAbacToClusterProvidersGcp < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_column_with_default(:cluster_providers_gcp, :legacy_abac, :boolean, default: true) # rubocop:disable Migration/AddColumnWithDefault
- end
-
- def down
- remove_column(:cluster_providers_gcp, :legacy_abac)
- end
-end
diff --git a/db/migrate/20180910115836_add_attr_encrypted_columns_to_web_hook.rb b/db/migrate/20180910115836_add_attr_encrypted_columns_to_web_hook.rb
deleted file mode 100644
index 3341fd5c593..00000000000
--- a/db/migrate/20180910115836_add_attr_encrypted_columns_to_web_hook.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class AddAttrEncryptedColumnsToWebHook < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- def change
- add_column :web_hooks, :encrypted_token, :string
- add_column :web_hooks, :encrypted_token_iv, :string
-
- add_column :web_hooks, :encrypted_url, :string
- add_column :web_hooks, :encrypted_url_iv, :string
- end
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/migrate/20180910153412_add_token_digest_to_personal_access_tokens.rb b/db/migrate/20180910153412_add_token_digest_to_personal_access_tokens.rb
deleted file mode 100644
index 4ed31bf7f39..00000000000
--- a/db/migrate/20180910153412_add_token_digest_to_personal_access_tokens.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class AddTokenDigestToPersonalAccessTokens < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- change_column :personal_access_tokens, :token, :string, null: true
-
- add_column :personal_access_tokens, :token_digest, :string # rubocop:disable Migration/PreventStrings
- end
-
- def down
- remove_column :personal_access_tokens, :token_digest
-
- change_column :personal_access_tokens, :token, :string, null: false
- end
-end
diff --git a/db/migrate/20180910153413_add_index_to_token_digest_on_personal_access_tokens.rb b/db/migrate/20180910153413_add_index_to_token_digest_on_personal_access_tokens.rb
deleted file mode 100644
index d501b07614a..00000000000
--- a/db/migrate/20180910153413_add_index_to_token_digest_on_personal_access_tokens.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class AddIndexToTokenDigestOnPersonalAccessTokens < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :personal_access_tokens, :token_digest, unique: true
- end
-
- def down
- remove_concurrent_index :personal_access_tokens, :token_digest if index_exists?(:personal_access_tokens, :token_digest)
- end
-end
diff --git a/db/migrate/20180912111628_add_knative_application.rb b/db/migrate/20180912111628_add_knative_application.rb
deleted file mode 100644
index cd2512cc17a..00000000000
--- a/db/migrate/20180912111628_add_knative_application.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-class AddKnativeApplication < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- def change
- create_table "clusters_applications_knative" do |t|
- t.references :cluster, null: false, unique: true, foreign_key: { on_delete: :cascade }
-
- t.datetime_with_timezone "created_at", null: false
- t.datetime_with_timezone "updated_at", null: false
- t.integer "status", null: false
- t.string "version", null: false
- t.string "hostname"
- t.text "status_reason" # rubocop:disable Migration/AddLimitToTextColumns
- end
- end
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/migrate/20180916011959_add_index_pipelines_project_id_source.rb b/db/migrate/20180916011959_add_index_pipelines_project_id_source.rb
deleted file mode 100644
index 5b71c79ac86..00000000000
--- a/db/migrate/20180916011959_add_index_pipelines_project_id_source.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddIndexPipelinesProjectIdSource < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :ci_pipelines, [:project_id, :source]
- end
-
- def down
- remove_concurrent_index :ci_pipelines, [:project_id, :source]
- end
-end
diff --git a/db/migrate/20180924141949_add_diff_max_patch_bytes_to_application_settings.rb b/db/migrate/20180924141949_add_diff_max_patch_bytes_to_application_settings.rb
deleted file mode 100644
index 69166f8d1a4..00000000000
--- a/db/migrate/20180924141949_add_diff_max_patch_bytes_to_application_settings.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# frozen_string_literal: true
-
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddDiffMaxPatchBytesToApplicationSettings < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_column_with_default(:application_settings, # rubocop:disable Migration/AddColumnWithDefault
- :diff_max_patch_bytes,
- :integer,
- default: 100.kilobytes,
- allow_null: false)
- end
-
- def down
- remove_column(:application_settings, :diff_max_patch_bytes)
- end
-end
diff --git a/db/migrate/20180924190739_add_scheduled_at_to_ci_builds.rb b/db/migrate/20180924190739_add_scheduled_at_to_ci_builds.rb
deleted file mode 100644
index 04a784a0c90..00000000000
--- a/db/migrate/20180924190739_add_scheduled_at_to_ci_builds.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class AddScheduledAtToCiBuilds < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- def change
- add_column :ci_builds, :scheduled_at, :datetime_with_timezone # rubocop:disable Migration/AddColumnsToWideTables
- end
-end
diff --git a/db/migrate/20180924201039_add_partial_index_to_scheduled_at.rb b/db/migrate/20180924201039_add_partial_index_to_scheduled_at.rb
deleted file mode 100644
index 378fc4e5fea..00000000000
--- a/db/migrate/20180924201039_add_partial_index_to_scheduled_at.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-class AddPartialIndexToScheduledAt < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- INDEX_NAME = 'partial_index_ci_builds_on_scheduled_at_with_scheduled_jobs'.freeze
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index(:ci_builds, :scheduled_at, where: "scheduled_at IS NOT NULL AND type = 'Ci::Build' AND status = 'scheduled'", name: INDEX_NAME)
- end
-
- def down
- remove_concurrent_index_by_name(:ci_builds, INDEX_NAME)
- end
-end
diff --git a/db/migrate/20180925200829_create_user_preferences.rb b/db/migrate/20180925200829_create_user_preferences.rb
deleted file mode 100644
index b46df8157a6..00000000000
--- a/db/migrate/20180925200829_create_user_preferences.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-# frozen_string_literal: true
-
-class CreateUserPreferences < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- class UserPreference < ActiveRecord::Base
- self.table_name = 'user_preferences'
-
- NOTES_FILTERS = { all_notes: 0, comments: 1 }.freeze
- end
-
- def change
- create_table :user_preferences do |t|
- t.references :user,
- null: false,
- index: { unique: true },
- foreign_key: { on_delete: :cascade }
-
- t.integer :issue_notes_filter,
- default: UserPreference::NOTES_FILTERS[:all_notes],
- null: false, limit: 2
-
- t.integer :merge_request_notes_filter,
- default: UserPreference::NOTES_FILTERS[:all_notes],
- null: false,
- limit: 2
-
- t.timestamps_with_timezone null: false
- end
- end
-end
diff --git a/db/migrate/20180927073410_add_index_to_project_deploy_tokens_deploy_token_id.rb b/db/migrate/20180927073410_add_index_to_project_deploy_tokens_deploy_token_id.rb
deleted file mode 100644
index edfcad81202..00000000000
--- a/db/migrate/20180927073410_add_index_to_project_deploy_tokens_deploy_token_id.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class AddIndexToProjectDeployTokensDeployTokenId < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :project_deploy_tokens, :deploy_token_id
- end
-
- def down
- remove_concurrent_index(:project_deploy_tokens, :deploy_token_id)
- end
-end
diff --git a/db/migrate/20181002172433_remove_restricted_todos_with_cte.rb b/db/migrate/20181002172433_remove_restricted_todos_with_cte.rb
deleted file mode 100644
index 7826c8d802e..00000000000
--- a/db/migrate/20181002172433_remove_restricted_todos_with_cte.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-# rescheduling of the revised RemoveRestrictedTodos background migration
-class RemoveRestrictedTodosWithCte < ActiveRecord::Migration[4.2]
- DOWNTIME = false
- disable_ddl_transaction!
-
- MIGRATION = 'RemoveRestrictedTodos'.freeze
- BATCH_SIZE = 1000
- DELAY_INTERVAL = 5.minutes.to_i
-
- class Project < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'projects'
- end
-
- def up
- Project.where('EXISTS (SELECT 1 FROM todos WHERE todos.project_id = projects.id)')
- .each_batch(of: BATCH_SIZE) do |batch, index|
- range = batch.pluck('MIN(id)', 'MAX(id)').first
-
- BackgroundMigrationWorker.perform_in(index * DELAY_INTERVAL, MIGRATION, range)
- end
- end
-
- def down
- # nothing to do
- end
-end
diff --git a/db/migrate/20181005110927_add_index_to_lfs_objects_file_store.rb b/db/migrate/20181005110927_add_index_to_lfs_objects_file_store.rb
deleted file mode 100644
index ff17a0a567d..00000000000
--- a/db/migrate/20181005110927_add_index_to_lfs_objects_file_store.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class AddIndexToLfsObjectsFileStore < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :lfs_objects, :file_store
- end
-
- def down
- remove_concurrent_index :lfs_objects, :file_store
- end
-end
diff --git a/db/migrate/20181005125926_add_index_to_uploads_store.rb b/db/migrate/20181005125926_add_index_to_uploads_store.rb
deleted file mode 100644
index d9e31225b6f..00000000000
--- a/db/migrate/20181005125926_add_index_to_uploads_store.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class AddIndexToUploadsStore < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :uploads, :store
- end
-
- def down
- remove_concurrent_index :uploads, :store
- end
-end
diff --git a/db/migrate/20181006004100_import_common_metrics_nginx_vts.rb b/db/migrate/20181006004100_import_common_metrics_nginx_vts.rb
deleted file mode 100644
index 2b238774dca..00000000000
--- a/db/migrate/20181006004100_import_common_metrics_nginx_vts.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-class ImportCommonMetricsNginxVts < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- ::Gitlab::DatabaseImporters::CommonMetrics::Importer.new.execute
- end
-
- def down
- # no-op
- end
-end
diff --git a/db/migrate/20181009190428_create_clusters_kubernetes_namespaces.rb b/db/migrate/20181009190428_create_clusters_kubernetes_namespaces.rb
deleted file mode 100644
index 42d0899fe31..00000000000
--- a/db/migrate/20181009190428_create_clusters_kubernetes_namespaces.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-# frozen_string_literal: true
-
-class CreateClustersKubernetesNamespaces < ActiveRecord::Migration[4.2]
- DOWNTIME = false
- INDEX_NAME = 'kubernetes_namespaces_cluster_and_namespace'
-
- # rubocop:disable Migration/PreventStrings
- def change
- create_table :clusters_kubernetes_namespaces, id: :bigserial do |t|
- t.references :cluster, null: false, index: true, foreign_key: { on_delete: :cascade }
- t.references :project, index: true, foreign_key: { on_delete: :nullify }
- t.references :cluster_project, index: true, foreign_key: { on_delete: :nullify }
-
- t.timestamps_with_timezone null: false
-
- t.string :encrypted_service_account_token_iv
- t.string :namespace, null: false
- t.string :service_account_name
-
- t.text :encrypted_service_account_token # rubocop:disable Migration/AddLimitToTextColumns
-
- t.index [:cluster_id, :namespace], name: INDEX_NAME, unique: true
- end
- end
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/migrate/20181010235606_create_board_project_recent_visits.rb b/db/migrate/20181010235606_create_board_project_recent_visits.rb
deleted file mode 100644
index 07bfbdda26b..00000000000
--- a/db/migrate/20181010235606_create_board_project_recent_visits.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class CreateBoardProjectRecentVisits < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- create_table :board_project_recent_visits, id: :bigserial do |t|
- t.timestamps_with_timezone null: false
-
- t.references :user, index: true, foreign_key: { on_delete: :cascade }
- t.references :project, index: true, foreign_key: { on_delete: :cascade }
- t.references :board, index: true, foreign_key: { on_delete: :cascade }
- end
-
- add_index :board_project_recent_visits, [:user_id, :project_id, :board_id], unique: true, name: 'index_board_project_recent_visits_on_user_project_and_board'
- end
-end
diff --git a/db/migrate/20181014203236_create_cluster_groups.rb b/db/migrate/20181014203236_create_cluster_groups.rb
deleted file mode 100644
index 33ae9a4a478..00000000000
--- a/db/migrate/20181014203236_create_cluster_groups.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class CreateClusterGroups < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- create_table :cluster_groups do |t|
- t.references :cluster, null: false, foreign_key: { on_delete: :cascade }
- t.references :group, null: false, index: true
-
- t.index [:cluster_id, :group_id], unique: true
- t.foreign_key :namespaces, column: :group_id, on_delete: :cascade
- end
- end
-end
diff --git a/db/migrate/20181015155839_add_finished_at_to_deployments.rb b/db/migrate/20181015155839_add_finished_at_to_deployments.rb
deleted file mode 100644
index bb8d6cdcf2c..00000000000
--- a/db/migrate/20181015155839_add_finished_at_to_deployments.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-class AddFinishedAtToDeployments < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- add_column :deployments, :finished_at, :datetime_with_timezone
- end
-
- def down
- remove_column :deployments, :finished_at, :datetime_with_timezone
- end
-end
diff --git a/db/migrate/20181016141739_add_status_to_deployments.rb b/db/migrate/20181016141739_add_status_to_deployments.rb
deleted file mode 100644
index 103bd9cc56d..00000000000
--- a/db/migrate/20181016141739_add_status_to_deployments.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-# frozen_string_literal: true
-
-class AddStatusToDeployments < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DEPLOYMENT_STATUS_SUCCESS = 2 # Equivalent to Deployment.state_machine.states['success'].value
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- ##
- # NOTE:
- # Ideally, `status` column should not have default value because it should be leveraged by state machine (i.e. application level).
- # However, we have to use the default value for avoiding `NOT NULL` violation during the transition period.
- # The default value should be removed in the future release.
- # rubocop:disable Migration/AddColumnWithDefault
- # rubocop:disable Migration/UpdateLargeTable
- def up
- add_column_with_default(:deployments,
- :status,
- :integer,
- limit: 2,
- default: DEPLOYMENT_STATUS_SUCCESS,
- allow_null: false)
- end
- # rubocop:enable Migration/AddColumnWithDefault
- # rubocop:enable Migration/UpdateLargeTable
-
- def down
- remove_column(:deployments, :status)
- end
-end
diff --git a/db/migrate/20181016152238_create_board_group_recent_visits.rb b/db/migrate/20181016152238_create_board_group_recent_visits.rb
deleted file mode 100644
index 9e240a5f97f..00000000000
--- a/db/migrate/20181016152238_create_board_group_recent_visits.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-class CreateBoardGroupRecentVisits < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- create_table :board_group_recent_visits, id: :bigserial do |t|
- t.timestamps_with_timezone null: false
-
- t.references :user, index: true, foreign_key: { on_delete: :cascade }
- t.references :board, index: true, foreign_key: { on_delete: :cascade }
- t.references :group, references: :namespace, column: :group_id, index: true
- t.foreign_key :namespaces, column: :group_id, on_delete: :cascade
- end
-
- add_index :board_group_recent_visits, [:user_id, :group_id, :board_id], unique: true, name: 'index_board_group_recent_visits_on_user_group_and_board'
- end
-end
diff --git a/db/migrate/20181017001059_add_cluster_type_to_clusters.rb b/db/migrate/20181017001059_add_cluster_type_to_clusters.rb
deleted file mode 100644
index 75abcfedfc9..00000000000
--- a/db/migrate/20181017001059_add_cluster_type_to_clusters.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-class AddClusterTypeToClusters < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- PROJECT_CLUSTER_TYPE = 3
-
- disable_ddl_transaction!
-
- def up
- add_column_with_default(:clusters, :cluster_type, :smallint, default: PROJECT_CLUSTER_TYPE) # rubocop:disable Migration/AddColumnWithDefault
- end
-
- def down
- remove_column(:clusters, :cluster_type)
- end
-end
diff --git a/db/migrate/20181019032400_add_shards_table.rb b/db/migrate/20181019032400_add_shards_table.rb
deleted file mode 100644
index 713039c1a15..00000000000
--- a/db/migrate/20181019032400_add_shards_table.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-class AddShardsTable < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- def change
- create_table :shards do |t|
- t.string :name, null: false, index: { unique: true } # rubocop:disable Migration/PreventStrings
- end
- end
-end
diff --git a/db/migrate/20181019032408_add_repositories_table.rb b/db/migrate/20181019032408_add_repositories_table.rb
deleted file mode 100644
index d4d3acf7029..00000000000
--- a/db/migrate/20181019032408_add_repositories_table.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-class AddRepositoriesTable < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- def change
- create_table :repositories, id: :bigserial do |t|
- t.references :shard, null: false, index: true, foreign_key: { on_delete: :restrict }
- t.string :disk_path, null: false, index: { unique: true } # rubocop:disable Migration/PreventStrings
- end
-
- add_column :projects, :pool_repository_id, :bigint # rubocop:disable Migration/AddColumnsToWideTables
- add_index :projects, :pool_repository_id, where: 'pool_repository_id IS NOT NULL'
- end
-end
diff --git a/db/migrate/20181019105553_add_projects_pool_repository_id_foreign_key.rb b/db/migrate/20181019105553_add_projects_pool_repository_id_foreign_key.rb
deleted file mode 100644
index dddf44ce488..00000000000
--- a/db/migrate/20181019105553_add_projects_pool_repository_id_foreign_key.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-class AddProjectsPoolRepositoryIdForeignKey < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_foreign_key(
- :projects,
- :repositories,
- column: :pool_repository_id,
- on_delete: :nullify
- )
- end
-
- def down
- remove_foreign_key(:projects, column: :pool_repository_id)
- end
-end
diff --git a/db/migrate/20181022135539_add_index_on_status_to_deployments.rb b/db/migrate/20181022135539_add_index_on_status_to_deployments.rb
deleted file mode 100644
index 9c7a722c626..00000000000
--- a/db/migrate/20181022135539_add_index_on_status_to_deployments.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class AddIndexOnStatusToDeployments < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :deployments, [:project_id, :status]
- add_concurrent_index :deployments, [:environment_id, :status]
- end
-
- def down
- remove_concurrent_index :deployments, [:project_id, :status]
- remove_concurrent_index :deployments, [:environment_id, :status]
- end
-end
diff --git a/db/migrate/20181023104858_add_archive_builds_duration_to_application_settings.rb b/db/migrate/20181023104858_add_archive_builds_duration_to_application_settings.rb
deleted file mode 100644
index 5d7a21fc5b5..00000000000
--- a/db/migrate/20181023104858_add_archive_builds_duration_to_application_settings.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-class AddArchiveBuildsDurationToApplicationSettings < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- add_column(:application_settings, :archive_builds_in_seconds, :integer, allow_null: true)
- end
-end
diff --git a/db/migrate/20181023144439_add_partial_index_for_legacy_successful_deployments.rb b/db/migrate/20181023144439_add_partial_index_for_legacy_successful_deployments.rb
deleted file mode 100644
index e90e59b57a9..00000000000
--- a/db/migrate/20181023144439_add_partial_index_for_legacy_successful_deployments.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-class AddPartialIndexForLegacySuccessfulDeployments < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- INDEX_NAME = 'partial_index_deployments_for_legacy_successful_deployments'.freeze
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index(:deployments, :id, where: "finished_at IS NULL AND status = 2", name: INDEX_NAME)
- end
-
- def down
- remove_concurrent_index_by_name(:deployments, INDEX_NAME)
- end
-end
diff --git a/db/migrate/20181025115728_add_private_commit_email_hostname_to_application_settings.rb b/db/migrate/20181025115728_add_private_commit_email_hostname_to_application_settings.rb
deleted file mode 100644
index 0923975f43a..00000000000
--- a/db/migrate/20181025115728_add_private_commit_email_hostname_to_application_settings.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-# frozen_string_literal: true
-
-class AddPrivateCommitEmailHostnameToApplicationSettings < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- def change
- add_column(:application_settings, :commit_email_hostname, :string, null: true)
- end
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/migrate/20181026143227_migrate_snippets_access_level_default_value.rb b/db/migrate/20181026143227_migrate_snippets_access_level_default_value.rb
deleted file mode 100644
index 2f4ef33b253..00000000000
--- a/db/migrate/20181026143227_migrate_snippets_access_level_default_value.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-# frozen_string_literal: true
-
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class MigrateSnippetsAccessLevelDefaultValue < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- ENABLED = 20
-
- disable_ddl_transaction!
-
- class ProjectFeature < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'project_features'
- end
-
- def up
- change_column_default :project_features, :snippets_access_level, ENABLED
-
- # On GitLab.com this will update about 28 000 rows. Since our updates are
- # very small and this column is not indexed, these updates should be very
- # lightweight.
- ProjectFeature.where(snippets_access_level: nil).each_batch do |batch|
- batch.update_all(snippets_access_level: ENABLED)
- end
-
- # We do not need to perform this in a post-deployment migration as the
- # ProjectFeature model already enforces a default value for all new rows.
- change_column_null :project_features, :snippets_access_level, false
- end
-
- def down
- change_column_null :project_features, :snippets_access_level, true
- change_column_default :project_features, :snippets_access_level, nil
-
- # We can't migrate from 20 -> NULL, as some projects may have explicitly set
- # the access level to 20.
- end
-end
diff --git a/db/migrate/20181027114222_add_first_day_of_week_to_user_preferences.rb b/db/migrate/20181027114222_add_first_day_of_week_to_user_preferences.rb
deleted file mode 100644
index 96ba5fbd816..00000000000
--- a/db/migrate/20181027114222_add_first_day_of_week_to_user_preferences.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class AddFirstDayOfWeekToUserPreferences < ActiveRecord::Migration[5.0]
- DOWNTIME = false
-
- def change
- add_column :user_preferences, :first_day_of_week, :integer
- end
-end
diff --git a/db/migrate/20181028120717_add_first_day_of_week_to_application_settings.rb b/db/migrate/20181028120717_add_first_day_of_week_to_application_settings.rb
deleted file mode 100644
index c4c25d08754..00000000000
--- a/db/migrate/20181028120717_add_first_day_of_week_to_application_settings.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: true
-
-class AddFirstDayOfWeekToApplicationSettings < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
- disable_ddl_transaction!
-
- DOWNTIME = false
-
- def up
- add_column_with_default(:application_settings, :first_day_of_week, :integer, default: 0) # rubocop:disable Migration/AddColumnWithDefault
- end
-
- def down
- remove_column(:application_settings, :first_day_of_week)
- end
-end
diff --git a/db/migrate/20181030154446_add_missing_indexes_for_foreign_keys.rb b/db/migrate/20181030154446_add_missing_indexes_for_foreign_keys.rb
deleted file mode 100644
index e21eb291282..00000000000
--- a/db/migrate/20181030154446_add_missing_indexes_for_foreign_keys.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-# frozen_string_literal: true
-
-class AddMissingIndexesForForeignKeys < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index(:application_settings, :usage_stats_set_by_user_id)
- add_concurrent_index(:ci_pipeline_schedules, :owner_id)
- add_concurrent_index(:ci_trigger_requests, :trigger_id)
- add_concurrent_index(:ci_triggers, :owner_id)
- add_concurrent_index(:clusters_applications_helm, :cluster_id, unique: true)
- add_concurrent_index(:clusters_applications_ingress, :cluster_id, unique: true)
- add_concurrent_index(:clusters_applications_jupyter, :cluster_id, unique: true)
- add_concurrent_index(:clusters_applications_jupyter, :oauth_application_id)
- add_concurrent_index(:clusters_applications_knative, :cluster_id, unique: true)
- add_concurrent_index(:clusters_applications_prometheus, :cluster_id, unique: true)
- add_concurrent_index(:fork_network_members, :forked_from_project_id)
- add_concurrent_index(:internal_ids, :namespace_id)
- add_concurrent_index(:internal_ids, :project_id)
- add_concurrent_index(:issues, :closed_by_id)
- add_concurrent_index(:label_priorities, :label_id)
- add_concurrent_index(:merge_request_metrics, :merged_by_id)
- add_concurrent_index(:merge_request_metrics, :latest_closed_by_id)
- add_concurrent_index(:oauth_openid_requests, :access_grant_id)
- add_concurrent_index(:project_deploy_tokens, :deploy_token_id)
- add_concurrent_index(:protected_tag_create_access_levels, :group_id)
- add_concurrent_index(:subscriptions, :project_id)
- add_concurrent_index(:user_statuses, :user_id)
- add_concurrent_index(:users, :accepted_term_id)
- end
-
- def down
- remove_concurrent_index(:application_settings, :usage_stats_set_by_user_id)
- remove_concurrent_index(:ci_pipeline_schedules, :owner_id)
- remove_concurrent_index(:ci_trigger_requests, :trigger_id)
- remove_concurrent_index(:ci_triggers, :owner_id)
- remove_concurrent_index(:clusters_applications_helm, :cluster_id, unique: true)
- remove_concurrent_index(:clusters_applications_ingress, :cluster_id, unique: true)
- remove_concurrent_index(:clusters_applications_jupyter, :cluster_id, unique: true)
- remove_concurrent_index(:clusters_applications_jupyter, :oauth_application_id)
- remove_concurrent_index(:clusters_applications_knative, :cluster_id, unique: true)
- remove_concurrent_index(:clusters_applications_prometheus, :cluster_id, unique: true)
- remove_concurrent_index(:fork_network_members, :forked_from_project_id)
- remove_concurrent_index(:internal_ids, :namespace_id)
- remove_concurrent_index(:internal_ids, :project_id)
- remove_concurrent_index(:issues, :closed_by_id)
- remove_concurrent_index(:label_priorities, :label_id)
- remove_concurrent_index(:merge_request_metrics, :merged_by_id)
- remove_concurrent_index(:merge_request_metrics, :latest_closed_by_id)
- remove_concurrent_index(:oauth_openid_requests, :access_grant_id)
- remove_concurrent_index(:project_deploy_tokens, :deploy_token_id)
- remove_concurrent_index(:protected_tag_create_access_levels, :group_id)
- remove_concurrent_index(:subscriptions, :project_id)
- remove_concurrent_index(:user_statuses, :user_id)
- remove_concurrent_index(:users, :accepted_term_id)
- end
-end
diff --git a/db/migrate/20181031145139_add_protected_ci_variables_to_application_settings.rb b/db/migrate/20181031145139_add_protected_ci_variables_to_application_settings.rb
deleted file mode 100644
index 1817677c58d..00000000000
--- a/db/migrate/20181031145139_add_protected_ci_variables_to_application_settings.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class AddProtectedCiVariablesToApplicationSettings < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_column_with_default(:application_settings, :protected_ci_variables, :boolean, default: false, allow_null: false) # rubocop:disable Migration/AddColumnWithDefault
- end
-
- def down
- remove_column(:application_settings, :protected_ci_variables)
- end
-end
diff --git a/db/migrate/20181031190558_drop_fk_gcp_clusters_table.rb b/db/migrate/20181031190558_drop_fk_gcp_clusters_table.rb
deleted file mode 100644
index 2c1dea05808..00000000000
--- a/db/migrate/20181031190558_drop_fk_gcp_clusters_table.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-# frozen_string_literal: true
-
-class DropFkGcpClustersTable < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- remove_foreign_key_if_exists :gcp_clusters, column: :project_id
- remove_foreign_key_if_exists :gcp_clusters, column: :user_id
- remove_foreign_key_if_exists :gcp_clusters, column: :service_id
- end
-
- def down
- add_foreign_key_if_not_exists :gcp_clusters, :projects, column: :project_id, on_delete: :cascade
- add_foreign_key_if_not_exists :gcp_clusters, :users, column: :user_id, on_delete: :nullify
- add_foreign_key_if_not_exists :gcp_clusters, :services, column: :service_id, on_delete: :nullify
- end
-
- private
-
- def add_foreign_key_if_not_exists(source, target, column:, on_delete:)
- return unless table_exists?(source)
- return if foreign_key_exists?(source, target, column: column)
-
- add_concurrent_foreign_key(source, target, column: column, on_delete: on_delete)
- end
-
- def remove_foreign_key_if_exists(table, column:)
- return unless table_exists?(table)
- return unless foreign_key_exists?(table, column: column)
-
- remove_foreign_key(table, column: column)
- end
-end
diff --git a/db/migrate/20181031190559_drop_gcp_clusters_table.rb b/db/migrate/20181031190559_drop_gcp_clusters_table.rb
deleted file mode 100644
index 597fe49f4c8..00000000000
--- a/db/migrate/20181031190559_drop_gcp_clusters_table.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-# frozen_string_literal: true
-
-class DropGcpClustersTable < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- drop_table :gcp_clusters
- end
-
- def down
- create_table :gcp_clusters do |t|
- # Order columns by best align scheme
- t.references :project, null: false, index: { unique: true }, foreign_key: { on_delete: :cascade }
- t.references :user, foreign_key: { on_delete: :nullify }
- t.references :service, foreign_key: { on_delete: :nullify }
- t.integer :status
- t.integer :gcp_cluster_size, null: false
-
- # Timestamps
- t.datetime_with_timezone :created_at, null: false
- t.datetime_with_timezone :updated_at, null: false
-
- # Enable/disable
- t.boolean :enabled, default: true
-
- # General
- t.text :status_reason
-
- # k8s integration specific
- t.string :project_namespace
-
- # Cluster details
- t.string :endpoint
- t.text :ca_cert
- t.text :encrypted_kubernetes_token
- t.string :encrypted_kubernetes_token_iv
- t.string :username
- t.text :encrypted_password
- t.string :encrypted_password_iv
-
- # GKE
- t.string :gcp_project_id, null: false
- t.string :gcp_cluster_zone, null: false
- t.string :gcp_cluster_name, null: false
- t.string :gcp_machine_type
- t.string :gcp_operation_id
- t.text :encrypted_gcp_token
- t.string :encrypted_gcp_token_iv
- end
- end
-end
diff --git a/db/migrate/20181101144347_add_index_for_stuck_mr_query.rb b/db/migrate/20181101144347_add_index_for_stuck_mr_query.rb
deleted file mode 100644
index 569eaa8b22c..00000000000
--- a/db/migrate/20181101144347_add_index_for_stuck_mr_query.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: true
-class AddIndexForStuckMrQuery < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :merge_requests, [:id, :merge_jid], where: "merge_jid IS NOT NULL and state = 'locked'"
- end
-
- def down
- remove_concurrent_index :merge_requests, [:id, :merge_jid], where: "merge_jid IS NOT NULL and state = 'locked'"
- end
-end
diff --git a/db/migrate/20181101191341_create_clusters_applications_cert_manager.rb b/db/migrate/20181101191341_create_clusters_applications_cert_manager.rb
deleted file mode 100644
index 95996531669..00000000000
--- a/db/migrate/20181101191341_create_clusters_applications_cert_manager.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-class CreateClustersApplicationsCertManager < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- def change
- create_table :clusters_applications_cert_managers do |t|
- t.references :cluster, null: false, index: false, foreign_key: { on_delete: :cascade }
- t.integer :status, null: false
- t.string :version, null: false
- t.string :email, null: false
- t.timestamps_with_timezone null: false
- t.text :status_reason # rubocop:disable Migration/AddLimitToTextColumns
- t.index :cluster_id, unique: true
- end
- end
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/migrate/20181106135939_add_index_to_deployments.rb b/db/migrate/20181106135939_add_index_to_deployments.rb
deleted file mode 100644
index e8181e61d22..00000000000
--- a/db/migrate/20181106135939_add_index_to_deployments.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class AddIndexToDeployments < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :deployments, [:project_id, :status, :created_at]
- end
-
- def down
- remove_concurrent_index :deployments, [:project_id, :status, :created_at]
- end
-end
diff --git a/db/migrate/20181108091549_cleanup_environments_external_url.rb b/db/migrate/20181108091549_cleanup_environments_external_url.rb
deleted file mode 100644
index 8439f6e55e6..00000000000
--- a/db/migrate/20181108091549_cleanup_environments_external_url.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-class CleanupEnvironmentsExternalUrl < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- update_column_in_batches(:environments, :external_url, nil) do |table, query|
- query.where(table[:external_url].matches('javascript://%'))
- end
- end
-
- def down
- end
-end
diff --git a/db/migrate/20181112103239_drop_default_value_on_status_deployments.rb b/db/migrate/20181112103239_drop_default_value_on_status_deployments.rb
deleted file mode 100644
index 59d6d2f29ff..00000000000
--- a/db/migrate/20181112103239_drop_default_value_on_status_deployments.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# frozen_string_literal: true
-
-class DropDefaultValueOnStatusDeployments < ActiveRecord::Migration[4.2]
- DOWNTIME = false
- DEPLOYMENT_STATUS_SUCCESS = 2 # Equivalent to Deployment.state_machine.states['success'].value
-
- def up
- change_column_default :deployments, :status, nil
- end
-
- def down
- change_column_default :deployments, :status, DEPLOYMENT_STATUS_SUCCESS
- end
-end
diff --git a/db/migrate/20181115140140_add_encrypted_runners_token_to_settings.rb b/db/migrate/20181115140140_add_encrypted_runners_token_to_settings.rb
deleted file mode 100644
index abb720dafb2..00000000000
--- a/db/migrate/20181115140140_add_encrypted_runners_token_to_settings.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-# frozen_string_literal: true
-
-class AddEncryptedRunnersTokenToSettings < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- def change
- add_column :application_settings, :runners_registration_token_encrypted, :string
- end
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/migrate/20181116050532_knative_external_ip.rb b/db/migrate/20181116050532_knative_external_ip.rb
deleted file mode 100644
index 4179e13c1b8..00000000000
--- a/db/migrate/20181116050532_knative_external_ip.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: true
-
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class KnativeExternalIp < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- def change
- add_column :clusters_applications_knative, :external_ip, :string
- end
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/migrate/20181116141415_add_encrypted_runners_token_to_namespaces.rb b/db/migrate/20181116141415_add_encrypted_runners_token_to_namespaces.rb
deleted file mode 100644
index 00c88140b52..00000000000
--- a/db/migrate/20181116141415_add_encrypted_runners_token_to_namespaces.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-# frozen_string_literal: true
-
-class AddEncryptedRunnersTokenToNamespaces < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- def change
- add_column :namespaces, :runners_token_encrypted, :string
- end
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/migrate/20181116141504_add_encrypted_runners_token_to_projects.rb b/db/migrate/20181116141504_add_encrypted_runners_token_to_projects.rb
deleted file mode 100644
index f42239475f7..00000000000
--- a/db/migrate/20181116141504_add_encrypted_runners_token_to_projects.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-class AddEncryptedRunnersTokenToProjects < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- # rubocop:disable Migration/AddColumnsToWideTables
- # rubocop:disable Migration/PreventStrings
- def change
- add_column :projects, :runners_token_encrypted, :string
- end
- # rubocop:enable Migration/PreventStrings
- # rubocop:enable Migration/AddColumnsToWideTables
-end
diff --git a/db/migrate/20181119081539_add_merge_request_id_to_ci_pipelines.rb b/db/migrate/20181119081539_add_merge_request_id_to_ci_pipelines.rb
deleted file mode 100644
index f96d80787f9..00000000000
--- a/db/migrate/20181119081539_add_merge_request_id_to_ci_pipelines.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-# frozen_string_literal: true
-
-class AddMergeRequestIdToCiPipelines < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- def up
- add_column :ci_pipelines, :merge_request_id, :integer
- end
-
- def down
- remove_column :ci_pipelines, :merge_request_id, :integer
- end
-end
diff --git a/db/migrate/20181119132520_add_indexes_to_ci_builds_and_pipelines.rb b/db/migrate/20181119132520_add_indexes_to_ci_builds_and_pipelines.rb
deleted file mode 100644
index cb01fa113eb..00000000000
--- a/db/migrate/20181119132520_add_indexes_to_ci_builds_and_pipelines.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-# frozen_string_literal: true
-
-class AddIndexesToCiBuildsAndPipelines < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- indexes.each do |index|
- add_concurrent_index(*index)
- end
- end
-
- def down
- indexes.each do |index|
- remove_concurrent_index(*index)
- end
- end
-
- private
-
- def indexes
- [
- [
- :ci_pipelines,
- [:project_id, :ref, :id],
- {
- order: { id: :desc },
- name: 'index_ci_pipelines_on_project_idandrefandiddesc'
- }
- ],
- [
- :ci_builds,
- [:commit_id, :artifacts_expire_at, :id],
- {
- where: "type::text = 'Ci::Build'::text AND (retried = false OR retried IS NULL) AND (name::text = ANY (ARRAY['sast'::character varying, 'dependency_scanning'::character varying, 'sast:container'::character varying, 'container_scanning'::character varying, 'dast'::character varying]::text[]))",
- name: 'index_ci_builds_on_commit_id_and_artifacts_expireatandidpartial'
- }
- ]
- ]
- end
-end
diff --git a/db/migrate/20181120082911_rename_repositories_pool_repositories.rb b/db/migrate/20181120082911_rename_repositories_pool_repositories.rb
deleted file mode 100644
index 165771c4775..00000000000
--- a/db/migrate/20181120082911_rename_repositories_pool_repositories.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-class RenameRepositoriesPoolRepositories < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
-
- # This change doesn't require downtime as the table is not in use, so we're
- # free to change an empty table
- DOWNTIME = false
-
- def change
- rename_table :repositories, :pool_repositories
- end
-end
diff --git a/db/migrate/20181120091639_add_foreign_key_to_ci_pipelines_merge_requests.rb b/db/migrate/20181120091639_add_foreign_key_to_ci_pipelines_merge_requests.rb
deleted file mode 100644
index f8b46395941..00000000000
--- a/db/migrate/20181120091639_add_foreign_key_to_ci_pipelines_merge_requests.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-class AddForeignKeyToCiPipelinesMergeRequests < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :ci_pipelines, :merge_request_id, where: 'merge_request_id IS NOT NULL'
- add_concurrent_foreign_key :ci_pipelines, :merge_requests, column: :merge_request_id, on_delete: :cascade
- end
-
- def down
- if foreign_key_exists?(:ci_pipelines, :merge_requests, column: :merge_request_id)
- remove_foreign_key :ci_pipelines, :merge_requests
- end
-
- remove_concurrent_index :ci_pipelines, :merge_request_id, where: 'merge_request_id IS NOT NULL'
- end
-end
diff --git a/db/migrate/20181120151656_add_token_encrypted_to_ci_runners.rb b/db/migrate/20181120151656_add_token_encrypted_to_ci_runners.rb
deleted file mode 100644
index 2b78d390907..00000000000
--- a/db/migrate/20181120151656_add_token_encrypted_to_ci_runners.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-class AddTokenEncryptedToCiRunners < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- add_column :ci_runners, :token_encrypted, :string # rubocop:disable Migration/PreventStrings
- end
-end
diff --git a/db/migrate/20181121101842_add_ci_builds_partial_index_on_project_id_and_status.rb b/db/migrate/20181121101842_add_ci_builds_partial_index_on_project_id_and_status.rb
deleted file mode 100644
index a524709faf8..00000000000
--- a/db/migrate/20181121101842_add_ci_builds_partial_index_on_project_id_and_status.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-# frozen_string_literal: true
-
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddCiBuildsPartialIndexOnProjectIdAndStatus < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index(*index_arguments)
- end
-
- def down
- remove_concurrent_index(*index_arguments)
- end
-
- private
-
- def index_arguments
- [
- :ci_builds,
- [:project_id, :status],
- {
- name: 'index_ci_builds_project_id_and_status_for_live_jobs_partial2',
- where: "(((type)::text = 'Ci::Build'::text) AND ((status)::text = ANY (ARRAY[('running'::character varying)::text, ('pending'::character varying)::text, ('created'::character varying)::text])))"
- }
- ]
- end
-end
diff --git a/db/migrate/20181121101843_remove_redundant_ci_builds_partial_index.rb b/db/migrate/20181121101843_remove_redundant_ci_builds_partial_index.rb
deleted file mode 100644
index e4fb703e887..00000000000
--- a/db/migrate/20181121101843_remove_redundant_ci_builds_partial_index.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-# frozen_string_literal: true
-
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class RemoveRedundantCiBuildsPartialIndex < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- remove_concurrent_index(*index_arguments)
- end
-
- def down
- add_concurrent_index(*index_arguments)
- end
-
- private
-
- def index_arguments
- [
- :ci_builds,
- [:project_id, :status],
- {
- name: 'index_ci_builds_project_id_and_status_for_live_jobs_partial',
- where: "((status)::text = ANY (ARRAY[('running'::character varying)::text, ('pending'::character varying)::text, ('created'::character varying)::text]))"
- }
- ]
- end
-end
diff --git a/db/migrate/20181122160027_create_project_repositories.rb b/db/migrate/20181122160027_create_project_repositories.rb
deleted file mode 100644
index 9148cde2fb4..00000000000
--- a/db/migrate/20181122160027_create_project_repositories.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class CreateProjectRepositories < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- create_table :project_repositories, id: :bigserial do |t|
- t.references :shard, null: false, index: true, foreign_key: { on_delete: :restrict }
- t.string :disk_path, null: false, index: { unique: true } # rubocop:disable Migration/PreventStrings
- t.references :project, null: false, index: { unique: true }, foreign_key: { on_delete: :cascade }
- end
- end
-end
diff --git a/db/migrate/20181123135036_drop_not_null_constraint_pool_repository_disk_path.rb b/db/migrate/20181123135036_drop_not_null_constraint_pool_repository_disk_path.rb
deleted file mode 100644
index bcd969e91c5..00000000000
--- a/db/migrate/20181123135036_drop_not_null_constraint_pool_repository_disk_path.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class DropNotNullConstraintPoolRepositoryDiskPath < ActiveRecord::Migration[5.0]
- DOWNTIME = false
-
- def change
- change_column_null :pool_repositories, :disk_path, true
- end
-end
diff --git a/db/migrate/20181123144235_create_suggestions.rb b/db/migrate/20181123144235_create_suggestions.rb
deleted file mode 100644
index b92e8ac8027..00000000000
--- a/db/migrate/20181123144235_create_suggestions.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-# frozen_string_literal: true
-
-class CreateSuggestions < ActiveRecord::Migration[5.0]
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- # rubocop:disable Migration/AddLimitToTextColumns
- def change
- create_table :suggestions, id: :bigserial do |t|
- t.references :note, foreign_key: { on_delete: :cascade }, null: false
- t.integer :relative_order, null: false, limit: 2
- t.boolean :applied, null: false, default: false
- t.string :commit_id
- t.text :from_content, null: false
- t.text :to_content, null: false
-
- t.index [:note_id, :relative_order],
- name: 'index_suggestions_on_note_id_and_relative_order',
- unique: true
- end
- end
- # rubocop:enable Migration/AddLimitToTextColumns
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/migrate/20181126150622_add_events_index_on_project_id_and_created_at.rb b/db/migrate/20181126150622_add_events_index_on_project_id_and_created_at.rb
deleted file mode 100644
index 7e9c56957d5..00000000000
--- a/db/migrate/20181126150622_add_events_index_on_project_id_and_created_at.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddEventsIndexOnProjectIdAndCreatedAt < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index(*index_arguments)
- end
-
- def down
- remove_concurrent_index(*index_arguments)
- end
-
- private
-
- def index_arguments
- [
- :events,
- [:project_id, :created_at],
- {
- name: 'index_events_on_project_id_and_created_at'
- }
- ]
- end
-end
diff --git a/db/migrate/20181126153547_remove_notes_index_on_updated_at.rb b/db/migrate/20181126153547_remove_notes_index_on_updated_at.rb
deleted file mode 100644
index d7ca46b50e4..00000000000
--- a/db/migrate/20181126153547_remove_notes_index_on_updated_at.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class RemoveNotesIndexOnUpdatedAt < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- remove_concurrent_index(*index_arguments)
- end
-
- def down
- add_concurrent_index(*index_arguments)
- end
-
- private
-
- def index_arguments
- [
- :notes,
- [:updated_at],
- {
- name: 'index_notes_on_updated_at'
- }
- ]
- end
-end
diff --git a/db/migrate/20181128123704_add_state_to_pool_repository.rb b/db/migrate/20181128123704_add_state_to_pool_repository.rb
deleted file mode 100644
index 4d4e56390df..00000000000
--- a/db/migrate/20181128123704_add_state_to_pool_repository.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-class AddStateToPoolRepository < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- # Given the table is empty, and the non concurrent methods are chosen so
- # the transactions don't have to be disabled
- # rubocop:disable Migration/AddConcurrentForeignKey
- # rubocop:disable Migration/AddIndex
- # rubocop:disable Migration/PreventStrings
- def change
- add_column(:pool_repositories, :state, :string, null: true)
-
- add_column :pool_repositories, :source_project_id, :integer
- add_index :pool_repositories, :source_project_id, unique: true
- add_foreign_key :pool_repositories, :projects, column: :source_project_id, on_delete: :nullify
- end
- # rubocop:enable Migration/PreventStrings
- # rubocop:enable Migration/AddIndex
- # rubocop:enable Migration/AddConcurrentForeignKey
-end
diff --git a/db/migrate/20181129104854_add_token_encrypted_to_ci_builds.rb b/db/migrate/20181129104854_add_token_encrypted_to_ci_builds.rb
deleted file mode 100644
index b83cabd6b75..00000000000
--- a/db/migrate/20181129104854_add_token_encrypted_to_ci_builds.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-class AddTokenEncryptedToCiBuilds < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- # rubocop:disable Migration/AddColumnsToWideTables
- # rubocop:disable Migration/PreventStrings
- def change
- add_column :ci_builds, :token_encrypted, :string
- end
- # rubocop:enable Migration/PreventStrings
- # rubocop:enable Migration/AddColumnsToWideTables
-end
diff --git a/db/migrate/20181129104944_add_index_to_ci_builds_token_encrypted.rb b/db/migrate/20181129104944_add_index_to_ci_builds_token_encrypted.rb
deleted file mode 100644
index f90aca008e5..00000000000
--- a/db/migrate/20181129104944_add_index_to_ci_builds_token_encrypted.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class AddIndexToCiBuildsTokenEncrypted < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :ci_builds, :token_encrypted, unique: true, where: 'token_encrypted IS NOT NULL'
- end
-
- def down
- remove_concurrent_index :ci_builds, :token_encrypted
- end
-end
diff --git a/db/migrate/20181203002526_add_project_bfg_object_map_column.rb b/db/migrate/20181203002526_add_project_bfg_object_map_column.rb
deleted file mode 100644
index 7850f314ca8..00000000000
--- a/db/migrate/20181203002526_add_project_bfg_object_map_column.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-# frozen_string_literal: true
-
-class AddProjectBfgObjectMapColumn < ActiveRecord::Migration[5.0]
- DOWNTIME = false
-
- # rubocop:disable Migration/AddColumnsToWideTables
- # rubocop:disable Migration/PreventStrings
- def change
- add_column :projects, :bfg_object_map, :string
- end
- # rubocop:enable Migration/PreventStrings
- # rubocop:enable Migration/AddColumnsToWideTables
-end
diff --git a/db/migrate/20181205171941_create_project_daily_statistics.rb b/db/migrate/20181205171941_create_project_daily_statistics.rb
deleted file mode 100644
index c9e2a1e1aa7..00000000000
--- a/db/migrate/20181205171941_create_project_daily_statistics.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-class CreateProjectDailyStatistics < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- create_table :project_daily_statistics, id: :bigserial do |t|
- t.integer :project_id, null: false
- t.integer :fetch_count, null: false
- t.date :date
-
- t.index [:project_id, :date], unique: true, order: { date: :desc }
- t.foreign_key :projects, on_delete: :cascade
- end
- end
-end
diff --git a/db/migrate/20181211092510_add_name_author_id_and_sha_to_releases.rb b/db/migrate/20181211092510_add_name_author_id_and_sha_to_releases.rb
deleted file mode 100644
index 79711d13cfe..00000000000
--- a/db/migrate/20181211092510_add_name_author_id_and_sha_to_releases.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-class AddNameAuthorIdAndShaToReleases < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- def change
- add_column :releases, :author_id, :integer
- add_column :releases, :name, :string
- add_column :releases, :sha, :string
- end
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/migrate/20181211092514_add_author_id_index_and_fk_to_releases.rb b/db/migrate/20181211092514_add_author_id_index_and_fk_to_releases.rb
deleted file mode 100644
index f6350a49944..00000000000
--- a/db/migrate/20181211092514_add_author_id_index_and_fk_to_releases.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-class AddAuthorIdIndexAndFkToReleases < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index :releases, :author_id
-
- add_concurrent_foreign_key :releases, :users, column: :author_id, on_delete: :nullify
- end
-
- def down
- remove_foreign_key :releases, column: :author_id
-
- remove_concurrent_index :releases, column: :author_id
- end
-end
diff --git a/db/migrate/20181212104941_backfill_releases_name_with_tag_name.rb b/db/migrate/20181212104941_backfill_releases_name_with_tag_name.rb
deleted file mode 100644
index e152dc87bc1..00000000000
--- a/db/migrate/20181212104941_backfill_releases_name_with_tag_name.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class BackfillReleasesNameWithTagName < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- update_column_in_batches(:releases, :name, Release.arel_table[:tag])
- end
-
- def down
- # no-op
- end
-end
diff --git a/db/migrate/20181212171634_create_error_tracking_settings.rb b/db/migrate/20181212171634_create_error_tracking_settings.rb
deleted file mode 100644
index 567abe6f45f..00000000000
--- a/db/migrate/20181212171634_create_error_tracking_settings.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class CreateErrorTrackingSettings < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- def change
- create_table :project_error_tracking_settings, id: :int, primary_key: :project_id, default: nil do |t|
- t.boolean :enabled, null: false, default: true
- t.string :api_url, null: false
- t.string :encrypted_token
- t.string :encrypted_token_iv
- t.foreign_key :projects, column: :project_id, on_delete: :cascade
- end
- end
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/migrate/20181219145521_add_options_to_build_metadata.rb b/db/migrate/20181219145521_add_options_to_build_metadata.rb
deleted file mode 100644
index dc9569babc2..00000000000
--- a/db/migrate/20181219145521_add_options_to_build_metadata.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddOptionsToBuildMetadata < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- add_column :ci_builds_metadata, :config_options, :jsonb
- add_column :ci_builds_metadata, :config_variables, :jsonb
- end
-end
diff --git a/db/migrate/20181228175414_create_releases_link_table.rb b/db/migrate/20181228175414_create_releases_link_table.rb
deleted file mode 100644
index 9d770d0dc2f..00000000000
--- a/db/migrate/20181228175414_create_releases_link_table.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-class CreateReleasesLinkTable < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- # rubocop:disable Migration/PreventStrings
- def change
- create_table :release_links, id: :bigserial do |t|
- t.references :release, null: false, index: false, foreign_key: { on_delete: :cascade }
- t.string :url, null: false
- t.string :name, null: false
- t.timestamps_with_timezone null: false
-
- t.index [:release_id, :url], unique: true
- t.index [:release_id, :name], unique: true
- end
- end
- # rubocop:enable Migration/PreventStrings
-end
diff --git a/db/migrate/20181228175414_init_schema.rb b/db/migrate/20181228175414_init_schema.rb
new file mode 100644
index 00000000000..d4212f405d9
--- /dev/null
+++ b/db/migrate/20181228175414_init_schema.rb
@@ -0,0 +1,2562 @@
+# frozen_string_literal: true
+
+# rubocop:disable Metrics/AbcSize
+# rubocop:disable Migration/AddConcurrentForeignKey
+# rubocop:disable Style/WordArray
+# rubocop:disable Migration/PreventStrings
+# rubocop:disable Migration/AddLimitToTextColumns
+# rubocop:disable Migration/Datetime
+
+class InitSchema < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def up
+ # These are extensions that must be enabled in order to support this database
+ enable_extension "pg_trgm"
+ enable_extension "plpgsql"
+
+ create_table "abuse_reports", id: :serial, force: :cascade do |t|
+ t.integer "reporter_id"
+ t.integer "user_id"
+ t.text "message"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.text "message_html"
+ t.integer "cached_markdown_version"
+ end
+
+ create_table "appearances", id: :serial, force: :cascade do |t|
+ t.string "title", null: false
+ t.text "description", null: false
+ t.string "header_logo"
+ t.string "logo"
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.text "description_html"
+ t.integer "cached_markdown_version"
+ t.string "favicon"
+ t.text "new_project_guidelines"
+ t.text "new_project_guidelines_html"
+ t.text "header_message"
+ t.text "header_message_html"
+ t.text "footer_message"
+ t.text "footer_message_html"
+ t.text "message_background_color"
+ t.text "message_font_color"
+ end
+
+ create_table "application_setting_terms", id: :serial, force: :cascade do |t|
+ t.integer "cached_markdown_version"
+ t.text "terms", null: false
+ t.text "terms_html"
+ end
+
+ create_table "application_settings", id: :serial, force: :cascade do |t|
+ t.integer "default_projects_limit"
+ t.boolean "signup_enabled"
+ t.boolean "gravatar_enabled"
+ t.text "sign_in_text"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.string "home_page_url"
+ t.integer "default_branch_protection", default: 2
+ t.text "restricted_visibility_levels"
+ t.boolean "version_check_enabled", default: true
+ t.integer "max_attachment_size", default: 10, null: false
+ t.integer "default_project_visibility"
+ t.integer "default_snippet_visibility"
+ t.text "domain_whitelist"
+ t.boolean "user_oauth_applications", default: true
+ t.string "after_sign_out_path"
+ t.integer "session_expire_delay", default: 10080, null: false
+ t.text "import_sources"
+ t.text "help_page_text"
+ t.string "admin_notification_email"
+ t.boolean "shared_runners_enabled", default: true, null: false
+ t.integer "max_artifacts_size", default: 100, null: false
+ t.string "runners_registration_token"
+ t.integer "max_pages_size", default: 100, null: false
+ t.boolean "require_two_factor_authentication", default: false
+ t.integer "two_factor_grace_period", default: 48
+ t.boolean "metrics_enabled", default: false
+ t.string "metrics_host", default: "localhost"
+ t.integer "metrics_pool_size", default: 16
+ t.integer "metrics_timeout", default: 10
+ t.integer "metrics_method_call_threshold", default: 10
+ t.boolean "recaptcha_enabled", default: false
+ t.string "recaptcha_site_key"
+ t.string "recaptcha_private_key"
+ t.integer "metrics_port", default: 8089
+ t.boolean "akismet_enabled", default: false
+ t.string "akismet_api_key"
+ t.integer "metrics_sample_interval", default: 15
+ t.boolean "sentry_enabled", default: false
+ t.string "sentry_dsn"
+ t.boolean "email_author_in_body", default: false
+ t.integer "default_group_visibility"
+ t.boolean "repository_checks_enabled", default: false
+ t.text "shared_runners_text"
+ t.integer "metrics_packet_size", default: 1
+ t.text "disabled_oauth_sign_in_sources"
+ t.string "health_check_access_token"
+ t.boolean "send_user_confirmation_email", default: false
+ t.integer "container_registry_token_expire_delay", default: 5
+ t.text "after_sign_up_text"
+ t.boolean "user_default_external", default: false, null: false
+ t.string "repository_storages", default: "default"
+ t.string "enabled_git_access_protocol"
+ t.boolean "domain_blacklist_enabled", default: false
+ t.text "domain_blacklist"
+ t.boolean "usage_ping_enabled", default: true, null: false
+ t.text "sign_in_text_html"
+ t.text "help_page_text_html"
+ t.text "shared_runners_text_html"
+ t.text "after_sign_up_text_html"
+ t.integer "rsa_key_restriction", default: 0, null: false
+ t.integer "dsa_key_restriction", default: -1, null: false
+ t.integer "ecdsa_key_restriction", default: 0, null: false
+ t.integer "ed25519_key_restriction", default: 0, null: false
+ t.boolean "housekeeping_enabled", default: true, null: false
+ t.boolean "housekeeping_bitmaps_enabled", default: true, null: false
+ t.integer "housekeeping_incremental_repack_period", default: 10, null: false
+ t.integer "housekeeping_full_repack_period", default: 50, null: false
+ t.integer "housekeeping_gc_period", default: 200, null: false
+ t.boolean "html_emails_enabled", default: true
+ t.string "plantuml_url"
+ t.boolean "plantuml_enabled"
+ t.integer "terminal_max_session_time", default: 0, null: false
+ t.integer "unique_ips_limit_per_user"
+ t.integer "unique_ips_limit_time_window"
+ t.boolean "unique_ips_limit_enabled", default: false, null: false
+ t.string "default_artifacts_expire_in", default: "0", null: false
+ t.string "uuid"
+ t.decimal "polling_interval_multiplier", default: "1.0", null: false
+ t.integer "cached_markdown_version"
+ t.boolean "clientside_sentry_enabled", default: false, null: false
+ t.string "clientside_sentry_dsn"
+ t.boolean "prometheus_metrics_enabled", default: true, null: false
+ t.boolean "authorized_keys_enabled", default: true, null: false
+ t.boolean "help_page_hide_commercial_content", default: false
+ t.string "help_page_support_url"
+ t.integer "performance_bar_allowed_group_id"
+ t.boolean "hashed_storage_enabled", default: false, null: false
+ t.boolean "project_export_enabled", default: true, null: false
+ t.boolean "auto_devops_enabled", default: true, null: false
+ t.boolean "throttle_unauthenticated_enabled", default: false, null: false
+ t.integer "throttle_unauthenticated_requests_per_period", default: 3600, null: false
+ t.integer "throttle_unauthenticated_period_in_seconds", default: 3600, null: false
+ t.boolean "throttle_authenticated_api_enabled", default: false, null: false
+ t.integer "throttle_authenticated_api_requests_per_period", default: 7200, null: false
+ t.integer "throttle_authenticated_api_period_in_seconds", default: 3600, null: false
+ t.boolean "throttle_authenticated_web_enabled", default: false, null: false
+ t.integer "throttle_authenticated_web_requests_per_period", default: 7200, null: false
+ t.integer "throttle_authenticated_web_period_in_seconds", default: 3600, null: false
+ t.integer "gitaly_timeout_default", default: 55, null: false
+ t.integer "gitaly_timeout_medium", default: 30, null: false
+ t.integer "gitaly_timeout_fast", default: 10, null: false
+ t.boolean "password_authentication_enabled_for_web"
+ t.boolean "password_authentication_enabled_for_git", default: true, null: false
+ t.boolean "external_authorization_service_enabled", default: false, null: false
+ t.string "external_authorization_service_url"
+ t.string "external_authorization_service_default_label"
+ t.integer "default_project_creation", default: 2, null: false
+ t.string "auto_devops_domain"
+ t.boolean "pages_domain_verification_enabled", default: true, null: false
+ t.boolean "allow_local_requests_from_hooks_and_services", default: false, null: false
+ t.string "user_default_internal_regex"
+ t.float "external_authorization_service_timeout", default: 0.5
+ t.text "external_auth_client_cert"
+ t.text "encrypted_external_auth_client_key"
+ t.string "encrypted_external_auth_client_key_iv"
+ t.string "encrypted_external_auth_client_key_pass"
+ t.string "encrypted_external_auth_client_key_pass_iv"
+ t.boolean "enforce_terms", default: false
+ t.boolean "mirror_available", default: true, null: false
+ t.boolean "hide_third_party_offers", default: false, null: false
+ t.boolean "instance_statistics_visibility_private", default: false, null: false
+ t.integer "receive_max_input_size"
+ t.boolean "web_ide_clientside_preview_enabled", default: false, null: false
+ t.boolean "user_show_add_ssh_key_message", default: true, null: false
+ t.string "outbound_local_requests_whitelist", limit: 255, array: true
+ t.integer "usage_stats_set_by_user_id"
+ t.integer "diff_max_patch_bytes", default: 102400, null: false
+ t.integer "archive_builds_in_seconds"
+ t.string "commit_email_hostname"
+ t.integer "first_day_of_week", default: 0, null: false
+ t.boolean "protected_ci_variables", default: false, null: false
+ t.string "runners_registration_token_encrypted"
+ t.index ["usage_stats_set_by_user_id"], name: "index_application_settings_on_usage_stats_set_by_user_id"
+ end
+
+ create_table "audit_events", id: :serial, force: :cascade do |t|
+ t.integer "author_id", null: false
+ t.string "type", null: false
+ t.integer "entity_id", null: false
+ t.string "entity_type", null: false
+ t.text "details"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.index ["entity_id", "entity_type"], name: "index_audit_events_on_entity_id_and_entity_type"
+ end
+
+ create_table "award_emoji", id: :serial, force: :cascade do |t|
+ t.string "name"
+ t.integer "user_id"
+ t.string "awardable_type"
+ t.integer "awardable_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.index ["awardable_type", "awardable_id"], name: "index_award_emoji_on_awardable_type_and_awardable_id"
+ t.index ["user_id", "name"], name: "index_award_emoji_on_user_id_and_name"
+ end
+
+ create_table "badges", id: :serial, force: :cascade do |t|
+ t.string "link_url", null: false
+ t.string "image_url", null: false
+ t.integer "project_id"
+ t.integer "group_id"
+ t.string "type", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.index ["group_id"], name: "index_badges_on_group_id"
+ t.index ["project_id"], name: "index_badges_on_project_id"
+ end
+
+ create_table "board_group_recent_visits", force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "user_id"
+ t.integer "board_id"
+ t.integer "group_id"
+ t.index ["board_id"], name: "index_board_group_recent_visits_on_board_id"
+ t.index ["group_id"], name: "index_board_group_recent_visits_on_group_id"
+ t.index ["user_id", "group_id", "board_id"], name: "index_board_group_recent_visits_on_user_group_and_board", unique: true
+ t.index ["user_id"], name: "index_board_group_recent_visits_on_user_id"
+ end
+
+ create_table "board_project_recent_visits", force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "user_id"
+ t.integer "project_id"
+ t.integer "board_id"
+ t.index ["board_id"], name: "index_board_project_recent_visits_on_board_id"
+ t.index ["project_id"], name: "index_board_project_recent_visits_on_project_id"
+ t.index ["user_id", "project_id", "board_id"], name: "index_board_project_recent_visits_on_user_project_and_board", unique: true
+ t.index ["user_id"], name: "index_board_project_recent_visits_on_user_id"
+ end
+
+ create_table "boards", id: :serial, force: :cascade do |t|
+ t.integer "project_id"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.integer "group_id"
+ t.index ["group_id"], name: "index_boards_on_group_id"
+ t.index ["project_id"], name: "index_boards_on_project_id"
+ end
+
+ create_table "broadcast_messages", id: :serial, force: :cascade do |t|
+ t.text "message", null: false
+ t.datetime "starts_at", null: false
+ t.datetime "ends_at", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.string "color"
+ t.string "font"
+ t.text "message_html", null: false
+ t.integer "cached_markdown_version"
+ t.index ["starts_at", "ends_at", "id"], name: "index_broadcast_messages_on_starts_at_and_ends_at_and_id"
+ end
+
+ create_table "chat_names", id: :serial, force: :cascade do |t|
+ t.integer "user_id", null: false
+ t.integer "service_id", null: false
+ t.string "team_id", null: false
+ t.string "team_domain"
+ t.string "chat_id", null: false
+ t.string "chat_name"
+ t.datetime "last_used_at"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["service_id", "team_id", "chat_id"], name: "index_chat_names_on_service_id_and_team_id_and_chat_id", unique: true
+ t.index ["user_id", "service_id"], name: "index_chat_names_on_user_id_and_service_id", unique: true
+ end
+
+ create_table "chat_teams", id: :serial, force: :cascade do |t|
+ t.integer "namespace_id", null: false
+ t.string "team_id"
+ t.string "name"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["namespace_id"], name: "index_chat_teams_on_namespace_id", unique: true
+ end
+
+ create_table "ci_build_trace_chunks", force: :cascade do |t|
+ t.integer "build_id", null: false
+ t.integer "chunk_index", null: false
+ t.integer "data_store", null: false
+ t.binary "raw_data"
+ t.index ["build_id", "chunk_index"], name: "index_ci_build_trace_chunks_on_build_id_and_chunk_index", unique: true
+ end
+
+ create_table "ci_build_trace_section_names", id: :serial, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.string "name", null: false
+ t.index ["project_id", "name"], name: "index_ci_build_trace_section_names_on_project_id_and_name", unique: true
+ end
+
+ create_table "ci_build_trace_sections", id: :serial, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.datetime_with_timezone "date_start", null: false
+ t.datetime_with_timezone "date_end", null: false
+ t.bigint "byte_start", null: false
+ t.bigint "byte_end", null: false
+ t.integer "build_id", null: false
+ t.integer "section_name_id", null: false
+ t.index ["build_id", "section_name_id"], name: "index_ci_build_trace_sections_on_build_id_and_section_name_id", unique: true
+ t.index ["project_id"], name: "index_ci_build_trace_sections_on_project_id"
+ t.index ["section_name_id"], name: "index_ci_build_trace_sections_on_section_name_id"
+ end
+
+ create_table "ci_builds", id: :serial, force: :cascade do |t|
+ t.string "status"
+ t.datetime "finished_at"
+ t.text "trace"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.datetime "started_at"
+ t.integer "runner_id"
+ t.float "coverage"
+ t.integer "commit_id"
+ t.text "commands"
+ t.string "name"
+ t.text "options"
+ t.boolean "allow_failure", default: false, null: false
+ t.string "stage"
+ t.integer "trigger_request_id"
+ t.integer "stage_idx"
+ t.boolean "tag"
+ t.string "ref"
+ t.integer "user_id"
+ t.string "type"
+ t.string "target_url"
+ t.string "description"
+ t.text "artifacts_file"
+ t.integer "project_id"
+ t.text "artifacts_metadata"
+ t.integer "erased_by_id"
+ t.datetime "erased_at"
+ t.datetime "artifacts_expire_at"
+ t.string "environment"
+ t.bigint "artifacts_size"
+ t.string "when"
+ t.text "yaml_variables"
+ t.datetime "queued_at"
+ t.string "token"
+ t.integer "lock_version"
+ t.string "coverage_regex"
+ t.integer "auto_canceled_by_id"
+ t.boolean "retried"
+ t.integer "stage_id"
+ t.integer "artifacts_file_store"
+ t.integer "artifacts_metadata_store"
+ t.boolean "protected"
+ t.integer "failure_reason"
+ t.datetime_with_timezone "scheduled_at"
+ t.string "token_encrypted"
+ t.index ["artifacts_expire_at"], name: "index_ci_builds_on_artifacts_expire_at", where: "(artifacts_file <> ''::text)"
+ t.index ["auto_canceled_by_id"], name: "index_ci_builds_on_auto_canceled_by_id"
+ t.index ["commit_id", "artifacts_expire_at", "id"], name: "index_ci_builds_on_commit_id_and_artifacts_expireatandidpartial", where: "(((type)::text = 'Ci::Build'::text) AND ((retried = false) OR (retried IS NULL)) AND ((name)::text = ANY (ARRAY[('sast'::character varying)::text, ('dependency_scanning'::character varying)::text, ('sast:container'::character varying)::text, ('container_scanning'::character varying)::text, ('dast'::character varying)::text])))"
+ t.index ["commit_id", "stage_idx", "created_at"], name: "index_ci_builds_on_commit_id_and_stage_idx_and_created_at"
+ t.index ["commit_id", "status", "type"], name: "index_ci_builds_on_commit_id_and_status_and_type"
+ t.index ["commit_id", "type", "name", "ref"], name: "index_ci_builds_on_commit_id_and_type_and_name_and_ref"
+ t.index ["commit_id", "type", "ref"], name: "index_ci_builds_on_commit_id_and_type_and_ref"
+ t.index ["id"], name: "partial_index_ci_builds_on_id_with_legacy_artifacts", where: "(artifacts_file <> ''::text)"
+ t.index ["project_id", "id"], name: "index_ci_builds_on_project_id_and_id"
+ t.index ["project_id", "status"], name: "index_ci_builds_project_id_and_status_for_live_jobs_partial2", where: "(((type)::text = 'Ci::Build'::text) AND ((status)::text = ANY (ARRAY[('running'::character varying)::text, ('pending'::character varying)::text, ('created'::character varying)::text])))"
+ t.index ["protected"], name: "index_ci_builds_on_protected"
+ t.index ["runner_id"], name: "index_ci_builds_on_runner_id"
+ t.index ["scheduled_at"], name: "partial_index_ci_builds_on_scheduled_at_with_scheduled_jobs", where: "((scheduled_at IS NOT NULL) AND ((type)::text = 'Ci::Build'::text) AND ((status)::text = 'scheduled'::text))"
+ t.index ["stage_id", "stage_idx"], name: "tmp_build_stage_position_index", where: "(stage_idx IS NOT NULL)"
+ t.index ["stage_id"], name: "index_ci_builds_on_stage_id"
+ t.index ["status", "type", "runner_id"], name: "index_ci_builds_on_status_and_type_and_runner_id"
+ t.index ["token"], name: "index_ci_builds_on_token", unique: true
+ t.index ["token_encrypted"], name: "index_ci_builds_on_token_encrypted", unique: true, where: "(token_encrypted IS NOT NULL)"
+ t.index ["updated_at"], name: "index_ci_builds_on_updated_at"
+ t.index ["user_id"], name: "index_ci_builds_on_user_id"
+ end
+
+ create_table "ci_builds_metadata", id: :serial, force: :cascade do |t|
+ t.integer "build_id", null: false
+ t.integer "project_id", null: false
+ t.integer "timeout"
+ t.integer "timeout_source", default: 1, null: false
+ t.jsonb "config_options"
+ t.jsonb "config_variables"
+ t.index ["build_id"], name: "index_ci_builds_metadata_on_build_id", unique: true
+ t.index ["project_id"], name: "index_ci_builds_metadata_on_project_id"
+ end
+
+ create_table "ci_builds_runner_session", force: :cascade do |t|
+ t.integer "build_id", null: false
+ t.string "url", null: false
+ t.string "certificate"
+ t.string "authorization"
+ t.index ["build_id"], name: "index_ci_builds_runner_session_on_build_id", unique: true
+ end
+
+ create_table "ci_group_variables", id: :serial, force: :cascade do |t|
+ t.string "key", null: false
+ t.text "value"
+ t.text "encrypted_value"
+ t.string "encrypted_value_salt"
+ t.string "encrypted_value_iv"
+ t.integer "group_id", null: false
+ t.boolean "protected", default: false, null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.index ["group_id", "key"], name: "index_ci_group_variables_on_group_id_and_key", unique: true
+ end
+
+ create_table "ci_job_artifacts", id: :serial, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.integer "job_id", null: false
+ t.integer "file_type", null: false
+ t.bigint "size"
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.datetime_with_timezone "expire_at"
+ t.string "file"
+ t.integer "file_store"
+ t.binary "file_sha256"
+ t.integer "file_format", limit: 2
+ t.integer "file_location", limit: 2
+ t.index ["expire_at", "job_id"], name: "index_ci_job_artifacts_on_expire_at_and_job_id"
+ t.index ["file_store"], name: "index_ci_job_artifacts_on_file_store"
+ t.index ["job_id", "file_type"], name: "index_ci_job_artifacts_on_job_id_and_file_type", unique: true
+ t.index ["project_id"], name: "index_ci_job_artifacts_on_project_id"
+ end
+
+ create_table "ci_pipeline_chat_data", force: :cascade do |t|
+ t.integer "pipeline_id", null: false
+ t.integer "chat_name_id", null: false
+ t.text "response_url", null: false
+ t.index ["chat_name_id"], name: "index_ci_pipeline_chat_data_on_chat_name_id"
+ t.index ["pipeline_id"], name: "index_ci_pipeline_chat_data_on_pipeline_id", unique: true
+ end
+
+ create_table "ci_pipeline_schedule_variables", id: :serial, force: :cascade do |t|
+ t.string "key", null: false
+ t.text "value"
+ t.text "encrypted_value"
+ t.string "encrypted_value_salt"
+ t.string "encrypted_value_iv"
+ t.integer "pipeline_schedule_id", null: false
+ t.datetime_with_timezone "created_at"
+ t.datetime_with_timezone "updated_at"
+ t.index ["pipeline_schedule_id", "key"], name: "index_ci_pipeline_schedule_variables_on_schedule_id_and_key", unique: true
+ end
+
+ create_table "ci_pipeline_schedules", id: :serial, force: :cascade do |t|
+ t.string "description"
+ t.string "ref"
+ t.string "cron"
+ t.string "cron_timezone"
+ t.datetime "next_run_at"
+ t.integer "project_id"
+ t.integer "owner_id"
+ t.boolean "active", default: true
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.index ["next_run_at", "active"], name: "index_ci_pipeline_schedules_on_next_run_at_and_active"
+ t.index ["owner_id"], name: "index_ci_pipeline_schedules_on_owner_id"
+ t.index ["project_id"], name: "index_ci_pipeline_schedules_on_project_id"
+ end
+
+ create_table "ci_pipeline_variables", id: :serial, force: :cascade do |t|
+ t.string "key", null: false
+ t.text "value"
+ t.text "encrypted_value"
+ t.string "encrypted_value_salt"
+ t.string "encrypted_value_iv"
+ t.integer "pipeline_id", null: false
+ t.index ["pipeline_id", "key"], name: "index_ci_pipeline_variables_on_pipeline_id_and_key", unique: true
+ end
+
+ create_table "ci_pipelines", id: :serial, force: :cascade do |t|
+ t.string "ref"
+ t.string "sha"
+ t.string "before_sha"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.boolean "tag", default: false
+ t.text "yaml_errors"
+ t.datetime "committed_at"
+ t.integer "project_id"
+ t.string "status"
+ t.datetime "started_at"
+ t.datetime "finished_at"
+ t.integer "duration"
+ t.integer "user_id"
+ t.integer "lock_version"
+ t.integer "auto_canceled_by_id"
+ t.integer "pipeline_schedule_id"
+ t.integer "source"
+ t.boolean "protected"
+ t.integer "config_source"
+ t.integer "failure_reason"
+ t.integer "iid"
+ t.integer "merge_request_id"
+ t.index ["auto_canceled_by_id"], name: "index_ci_pipelines_on_auto_canceled_by_id"
+ t.index ["merge_request_id"], name: "index_ci_pipelines_on_merge_request_id", where: "(merge_request_id IS NOT NULL)"
+ t.index ["pipeline_schedule_id"], name: "index_ci_pipelines_on_pipeline_schedule_id"
+ t.index ["project_id", "iid"], name: "index_ci_pipelines_on_project_id_and_iid", unique: true, where: "(iid IS NOT NULL)"
+ t.index ["project_id", "ref", "id"], name: "index_ci_pipelines_on_project_idandrefandiddesc", order: { id: :desc }
+ t.index ["project_id", "ref", "status", "id"], name: "index_ci_pipelines_on_project_id_and_ref_and_status_and_id"
+ t.index ["project_id", "sha"], name: "index_ci_pipelines_on_project_id_and_sha"
+ t.index ["project_id", "source"], name: "index_ci_pipelines_on_project_id_and_source"
+ t.index ["project_id", "status", "config_source"], name: "index_ci_pipelines_on_project_id_and_status_and_config_source"
+ t.index ["project_id"], name: "index_ci_pipelines_on_project_id"
+ t.index ["status"], name: "index_ci_pipelines_on_status"
+ t.index ["user_id"], name: "index_ci_pipelines_on_user_id"
+ end
+
+ create_table "ci_runner_namespaces", id: :serial, force: :cascade do |t|
+ t.integer "runner_id"
+ t.integer "namespace_id"
+ t.index ["namespace_id"], name: "index_ci_runner_namespaces_on_namespace_id"
+ t.index ["runner_id", "namespace_id"], name: "index_ci_runner_namespaces_on_runner_id_and_namespace_id", unique: true
+ end
+
+ create_table "ci_runner_projects", id: :serial, force: :cascade do |t|
+ t.integer "runner_id", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.integer "project_id"
+ t.index ["project_id"], name: "index_ci_runner_projects_on_project_id"
+ t.index ["runner_id"], name: "index_ci_runner_projects_on_runner_id"
+ end
+
+ create_table "ci_runners", id: :serial, force: :cascade do |t|
+ t.string "token"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.string "description"
+ t.datetime "contacted_at"
+ t.boolean "active", default: true, null: false
+ t.boolean "is_shared", default: false
+ t.string "name"
+ t.string "version"
+ t.string "revision"
+ t.string "platform"
+ t.string "architecture"
+ t.boolean "run_untagged", default: true, null: false
+ t.boolean "locked", default: false, null: false
+ t.integer "access_level", default: 0, null: false
+ t.integer "maximum_timeout"
+ t.string "ip_address"
+ t.integer "runner_type", limit: 2, null: false
+ t.string "token_encrypted"
+ t.index ["contacted_at"], name: "index_ci_runners_on_contacted_at"
+ t.index ["is_shared"], name: "index_ci_runners_on_is_shared"
+ t.index ["locked"], name: "index_ci_runners_on_locked"
+ t.index ["runner_type"], name: "index_ci_runners_on_runner_type"
+ t.index ["token"], name: "index_ci_runners_on_token"
+ end
+
+ create_table "ci_stages", id: :serial, force: :cascade do |t|
+ t.integer "project_id"
+ t.integer "pipeline_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.string "name"
+ t.integer "status"
+ t.integer "lock_version"
+ t.integer "position"
+ t.index ["pipeline_id", "name"], name: "index_ci_stages_on_pipeline_id_and_name", unique: true
+ t.index ["pipeline_id", "position"], name: "index_ci_stages_on_pipeline_id_and_position"
+ t.index ["pipeline_id"], name: "index_ci_stages_on_pipeline_id"
+ t.index ["project_id"], name: "index_ci_stages_on_project_id"
+ end
+
+ create_table "ci_trigger_requests", id: :serial, force: :cascade do |t|
+ t.integer "trigger_id", null: false
+ t.text "variables"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.integer "commit_id"
+ t.index ["commit_id"], name: "index_ci_trigger_requests_on_commit_id"
+ t.index ["trigger_id"], name: "index_ci_trigger_requests_on_trigger_id"
+ end
+
+ create_table "ci_triggers", id: :serial, force: :cascade do |t|
+ t.string "token"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.integer "project_id"
+ t.integer "owner_id"
+ t.string "description"
+ t.string "ref"
+ t.index ["owner_id"], name: "index_ci_triggers_on_owner_id"
+ t.index ["project_id"], name: "index_ci_triggers_on_project_id"
+ end
+
+ create_table "ci_variables", id: :serial, force: :cascade do |t|
+ t.string "key", null: false
+ t.text "value"
+ t.text "encrypted_value"
+ t.string "encrypted_value_salt"
+ t.string "encrypted_value_iv"
+ t.integer "project_id", null: false
+ t.boolean "protected", default: false, null: false
+ t.string "environment_scope", default: "*", null: false
+ t.index ["project_id", "key", "environment_scope"], name: "index_ci_variables_on_project_id_and_key_and_environment_scope", unique: true
+ end
+
+ create_table "cluster_groups", id: :serial, force: :cascade do |t|
+ t.integer "cluster_id", null: false
+ t.integer "group_id", null: false
+ t.index ["cluster_id", "group_id"], name: "index_cluster_groups_on_cluster_id_and_group_id", unique: true
+ t.index ["group_id"], name: "index_cluster_groups_on_group_id"
+ end
+
+ create_table "cluster_platforms_kubernetes", id: :serial, force: :cascade do |t|
+ t.integer "cluster_id", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.text "api_url"
+ t.text "ca_cert"
+ t.string "namespace"
+ t.string "username"
+ t.text "encrypted_password"
+ t.string "encrypted_password_iv"
+ t.text "encrypted_token"
+ t.string "encrypted_token_iv"
+ t.integer "authorization_type", limit: 2
+ t.index ["cluster_id"], name: "index_cluster_platforms_kubernetes_on_cluster_id", unique: true
+ end
+
+ create_table "cluster_projects", id: :serial, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.integer "cluster_id", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.index ["cluster_id"], name: "index_cluster_projects_on_cluster_id"
+ t.index ["project_id"], name: "index_cluster_projects_on_project_id"
+ end
+
+ create_table "cluster_providers_gcp", id: :serial, force: :cascade do |t|
+ t.integer "cluster_id", null: false
+ t.integer "status"
+ t.integer "num_nodes", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.text "status_reason"
+ t.string "gcp_project_id", null: false
+ t.string "zone", null: false
+ t.string "machine_type"
+ t.string "operation_id"
+ t.string "endpoint"
+ t.text "encrypted_access_token"
+ t.string "encrypted_access_token_iv"
+ t.boolean "legacy_abac", default: true, null: false
+ t.index ["cluster_id"], name: "index_cluster_providers_gcp_on_cluster_id", unique: true
+ end
+
+ create_table "clusters", id: :serial, force: :cascade do |t|
+ t.integer "user_id"
+ t.integer "provider_type"
+ t.integer "platform_type"
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.boolean "enabled", default: true
+ t.string "name", null: false
+ t.string "environment_scope", default: "*", null: false
+ t.integer "cluster_type", limit: 2, default: 3, null: false
+ t.index ["enabled"], name: "index_clusters_on_enabled"
+ t.index ["user_id"], name: "index_clusters_on_user_id"
+ end
+
+ create_table "clusters_applications_cert_managers", id: :serial, force: :cascade do |t|
+ t.integer "cluster_id", null: false
+ t.integer "status", null: false
+ t.string "version", null: false
+ t.string "email", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.text "status_reason"
+ t.index ["cluster_id"], name: "index_clusters_applications_cert_managers_on_cluster_id", unique: true
+ end
+
+ create_table "clusters_applications_helm", id: :serial, force: :cascade do |t|
+ t.integer "cluster_id", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "status", null: false
+ t.string "version", null: false
+ t.text "status_reason"
+ t.text "encrypted_ca_key"
+ t.text "encrypted_ca_key_iv"
+ t.text "ca_cert"
+ t.index ["cluster_id"], name: "index_clusters_applications_helm_on_cluster_id", unique: true
+ end
+
+ create_table "clusters_applications_ingress", id: :serial, force: :cascade do |t|
+ t.integer "cluster_id", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "status", null: false
+ t.integer "ingress_type", null: false
+ t.string "version", null: false
+ t.string "cluster_ip"
+ t.text "status_reason"
+ t.string "external_ip"
+ t.index ["cluster_id"], name: "index_clusters_applications_ingress_on_cluster_id", unique: true
+ end
+
+ create_table "clusters_applications_jupyter", id: :serial, force: :cascade do |t|
+ t.integer "cluster_id", null: false
+ t.integer "oauth_application_id"
+ t.integer "status", null: false
+ t.string "version", null: false
+ t.string "hostname"
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.text "status_reason"
+ t.index ["cluster_id"], name: "index_clusters_applications_jupyter_on_cluster_id", unique: true
+ t.index ["oauth_application_id"], name: "index_clusters_applications_jupyter_on_oauth_application_id"
+ end
+
+ create_table "clusters_applications_knative", id: :serial, force: :cascade do |t|
+ t.integer "cluster_id", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "status", null: false
+ t.string "version", null: false
+ t.string "hostname"
+ t.text "status_reason"
+ t.string "external_ip"
+ t.index ["cluster_id"], name: "index_clusters_applications_knative_on_cluster_id", unique: true
+ end
+
+ create_table "clusters_applications_prometheus", id: :serial, force: :cascade do |t|
+ t.integer "cluster_id", null: false
+ t.integer "status", null: false
+ t.string "version", null: false
+ t.text "status_reason"
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.index ["cluster_id"], name: "index_clusters_applications_prometheus_on_cluster_id", unique: true
+ end
+
+ create_table "clusters_applications_runners", id: :serial, force: :cascade do |t|
+ t.integer "cluster_id", null: false
+ t.integer "runner_id"
+ t.integer "status", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.string "version", null: false
+ t.text "status_reason"
+ t.boolean "privileged", default: true, null: false
+ t.index ["cluster_id"], name: "index_clusters_applications_runners_on_cluster_id", unique: true
+ t.index ["runner_id"], name: "index_clusters_applications_runners_on_runner_id"
+ end
+
+ create_table "clusters_kubernetes_namespaces", force: :cascade do |t|
+ t.integer "cluster_id", null: false
+ t.integer "project_id"
+ t.integer "cluster_project_id"
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.string "encrypted_service_account_token_iv"
+ t.string "namespace", null: false
+ t.string "service_account_name"
+ t.text "encrypted_service_account_token"
+ t.index ["cluster_id", "namespace"], name: "kubernetes_namespaces_cluster_and_namespace", unique: true
+ t.index ["cluster_id"], name: "index_clusters_kubernetes_namespaces_on_cluster_id"
+ t.index ["cluster_project_id"], name: "index_clusters_kubernetes_namespaces_on_cluster_project_id"
+ t.index ["project_id"], name: "index_clusters_kubernetes_namespaces_on_project_id"
+ end
+
+ create_table "container_repositories", id: :serial, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.string "name", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["project_id", "name"], name: "index_container_repositories_on_project_id_and_name", unique: true
+ t.index ["project_id"], name: "index_container_repositories_on_project_id"
+ end
+
+ create_table "conversational_development_index_metrics", id: :serial, force: :cascade do |t|
+ t.float "leader_issues", null: false
+ t.float "instance_issues", null: false
+ t.float "leader_notes", null: false
+ t.float "instance_notes", null: false
+ t.float "leader_milestones", null: false
+ t.float "instance_milestones", null: false
+ t.float "leader_boards", null: false
+ t.float "instance_boards", null: false
+ t.float "leader_merge_requests", null: false
+ t.float "instance_merge_requests", null: false
+ t.float "leader_ci_pipelines", null: false
+ t.float "instance_ci_pipelines", null: false
+ t.float "leader_environments", null: false
+ t.float "instance_environments", null: false
+ t.float "leader_deployments", null: false
+ t.float "instance_deployments", null: false
+ t.float "leader_projects_prometheus_active", null: false
+ t.float "instance_projects_prometheus_active", null: false
+ t.float "leader_service_desk_issues", null: false
+ t.float "instance_service_desk_issues", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.float "percentage_boards", default: 0.0, null: false
+ t.float "percentage_ci_pipelines", default: 0.0, null: false
+ t.float "percentage_deployments", default: 0.0, null: false
+ t.float "percentage_environments", default: 0.0, null: false
+ t.float "percentage_issues", default: 0.0, null: false
+ t.float "percentage_merge_requests", default: 0.0, null: false
+ t.float "percentage_milestones", default: 0.0, null: false
+ t.float "percentage_notes", default: 0.0, null: false
+ t.float "percentage_projects_prometheus_active", default: 0.0, null: false
+ t.float "percentage_service_desk_issues", default: 0.0, null: false
+ end
+
+ create_table "deploy_keys_projects", id: :serial, force: :cascade do |t|
+ t.integer "deploy_key_id", null: false
+ t.integer "project_id", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.boolean "can_push", default: false, null: false
+ t.index ["project_id"], name: "index_deploy_keys_projects_on_project_id"
+ end
+
+ create_table "deploy_tokens", id: :serial, force: :cascade do |t|
+ t.boolean "revoked", default: false
+ t.boolean "read_repository", default: false, null: false
+ t.boolean "read_registry", default: false, null: false
+ t.datetime_with_timezone "expires_at", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.string "name", null: false
+ t.string "token", null: false
+ t.index ["token", "expires_at", "id"], name: "index_deploy_tokens_on_token_and_expires_at_and_id", where: "(revoked IS FALSE)"
+ t.index ["token"], name: "index_deploy_tokens_on_token", unique: true
+ end
+
+ create_table "deployments", id: :serial, force: :cascade do |t|
+ t.integer "iid", null: false
+ t.integer "project_id", null: false
+ t.integer "environment_id", null: false
+ t.string "ref", null: false
+ t.boolean "tag", null: false
+ t.string "sha", null: false
+ t.integer "user_id"
+ t.integer "deployable_id"
+ t.string "deployable_type"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.string "on_stop"
+ t.datetime_with_timezone "finished_at"
+ t.integer "status", limit: 2, null: false
+ t.index ["created_at"], name: "index_deployments_on_created_at"
+ t.index ["deployable_type", "deployable_id"], name: "index_deployments_on_deployable_type_and_deployable_id"
+ t.index ["environment_id", "id"], name: "index_deployments_on_environment_id_and_id"
+ t.index ["environment_id", "iid", "project_id"], name: "index_deployments_on_environment_id_and_iid_and_project_id"
+ t.index ["environment_id", "status"], name: "index_deployments_on_environment_id_and_status"
+ t.index ["id"], name: "partial_index_deployments_for_legacy_successful_deployments", where: "((finished_at IS NULL) AND (status = 2))"
+ t.index ["project_id", "iid"], name: "index_deployments_on_project_id_and_iid", unique: true
+ t.index ["project_id", "status", "created_at"], name: "index_deployments_on_project_id_and_status_and_created_at"
+ t.index ["project_id", "status"], name: "index_deployments_on_project_id_and_status"
+ end
+
+ create_table "emails", id: :serial, force: :cascade do |t|
+ t.integer "user_id", null: false
+ t.string "email", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.string "confirmation_token"
+ t.datetime_with_timezone "confirmed_at"
+ t.datetime_with_timezone "confirmation_sent_at"
+ t.index ["confirmation_token"], name: "index_emails_on_confirmation_token", unique: true
+ t.index ["email"], name: "index_emails_on_email", unique: true
+ t.index ["user_id"], name: "index_emails_on_user_id"
+ end
+
+ create_table "environments", id: :serial, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.string "name", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.string "external_url"
+ t.string "environment_type"
+ t.string "state", default: "available", null: false
+ t.string "slug", null: false
+ t.index ["project_id", "name"], name: "index_environments_on_project_id_and_name", unique: true
+ t.index ["project_id", "slug"], name: "index_environments_on_project_id_and_slug", unique: true
+ end
+
+ create_table "events", id: :serial, force: :cascade do |t|
+ t.integer "project_id"
+ t.integer "author_id", null: false
+ t.integer "target_id"
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "action", limit: 2, null: false
+ t.string "target_type"
+ t.index ["action"], name: "index_events_on_action"
+ t.index ["author_id", "project_id"], name: "index_events_on_author_id_and_project_id"
+ t.index ["project_id", "created_at"], name: "index_events_on_project_id_and_created_at"
+ t.index ["project_id", "id"], name: "index_events_on_project_id_and_id"
+ t.index ["target_type", "target_id"], name: "index_events_on_target_type_and_target_id"
+ end
+
+ create_table "feature_gates", id: :serial, force: :cascade do |t|
+ t.string "feature_key", null: false
+ t.string "key", null: false
+ t.string "value"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["feature_key", "key", "value"], name: "index_feature_gates_on_feature_key_and_key_and_value", unique: true
+ end
+
+ create_table "features", id: :serial, force: :cascade do |t|
+ t.string "key", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["key"], name: "index_features_on_key", unique: true
+ end
+
+ create_table "fork_network_members", id: :serial, force: :cascade do |t|
+ t.integer "fork_network_id", null: false
+ t.integer "project_id", null: false
+ t.integer "forked_from_project_id"
+ t.index ["fork_network_id"], name: "index_fork_network_members_on_fork_network_id"
+ t.index ["forked_from_project_id"], name: "index_fork_network_members_on_forked_from_project_id"
+ t.index ["project_id"], name: "index_fork_network_members_on_project_id", unique: true
+ end
+
+ create_table "fork_networks", id: :serial, force: :cascade do |t|
+ t.integer "root_project_id"
+ t.string "deleted_root_project_name"
+ t.index ["root_project_id"], name: "index_fork_networks_on_root_project_id", unique: true
+ end
+
+ create_table "forked_project_links", id: :serial, force: :cascade do |t|
+ t.integer "forked_to_project_id", null: false
+ t.integer "forked_from_project_id", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.index ["forked_to_project_id"], name: "index_forked_project_links_on_forked_to_project_id", unique: true
+ end
+
+ create_table "gpg_key_subkeys", id: :serial, force: :cascade do |t|
+ t.integer "gpg_key_id", null: false
+ t.binary "keyid"
+ t.binary "fingerprint"
+ t.index ["fingerprint"], name: "index_gpg_key_subkeys_on_fingerprint", unique: true
+ t.index ["gpg_key_id"], name: "index_gpg_key_subkeys_on_gpg_key_id"
+ t.index ["keyid"], name: "index_gpg_key_subkeys_on_keyid", unique: true
+ end
+
+ create_table "gpg_keys", id: :serial, force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "user_id"
+ t.binary "primary_keyid"
+ t.binary "fingerprint"
+ t.text "key"
+ t.index ["fingerprint"], name: "index_gpg_keys_on_fingerprint", unique: true
+ t.index ["primary_keyid"], name: "index_gpg_keys_on_primary_keyid", unique: true
+ t.index ["user_id"], name: "index_gpg_keys_on_user_id"
+ end
+
+ create_table "gpg_signatures", id: :serial, force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "project_id"
+ t.integer "gpg_key_id"
+ t.binary "commit_sha"
+ t.binary "gpg_key_primary_keyid"
+ t.text "gpg_key_user_name"
+ t.text "gpg_key_user_email"
+ t.integer "verification_status", limit: 2, default: 0, null: false
+ t.integer "gpg_key_subkey_id"
+ t.index ["commit_sha"], name: "index_gpg_signatures_on_commit_sha", unique: true
+ t.index ["gpg_key_id"], name: "index_gpg_signatures_on_gpg_key_id"
+ t.index ["gpg_key_primary_keyid"], name: "index_gpg_signatures_on_gpg_key_primary_keyid"
+ t.index ["gpg_key_subkey_id"], name: "index_gpg_signatures_on_gpg_key_subkey_id"
+ t.index ["project_id"], name: "index_gpg_signatures_on_project_id"
+ end
+
+ create_table "group_custom_attributes", id: :serial, force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "group_id", null: false
+ t.string "key", null: false
+ t.string "value", null: false
+ t.index ["group_id", "key"], name: "index_group_custom_attributes_on_group_id_and_key", unique: true
+ t.index ["key", "value"], name: "index_group_custom_attributes_on_key_and_value"
+ end
+
+ create_table "group_group_links", force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.bigint "shared_group_id", null: false
+ t.bigint "shared_with_group_id", null: false
+ t.date "expires_at"
+ t.integer "group_access", limit: 2, default: 30, null: false
+ t.index ["shared_group_id", "shared_with_group_id"], name: "index_group_group_links_on_shared_group_and_shared_with_group", unique: true
+ t.index ["shared_with_group_id"], name: "index_group_group_links_on_shared_with_group_id"
+ end
+
+ create_table "identities", id: :serial, force: :cascade do |t|
+ t.string "extern_uid"
+ t.string "provider"
+ t.integer "user_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.index ["user_id"], name: "index_identities_on_user_id"
+ end
+
+ create_table "import_export_uploads", id: :serial, force: :cascade do |t|
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "project_id"
+ t.text "import_file"
+ t.text "export_file"
+ t.index ["project_id"], name: "index_import_export_uploads_on_project_id"
+ t.index ["updated_at"], name: "index_import_export_uploads_on_updated_at"
+ end
+
+ create_table "internal_ids", force: :cascade do |t|
+ t.integer "project_id"
+ t.integer "usage", null: false
+ t.integer "last_value", null: false
+ t.integer "namespace_id"
+ t.index ["namespace_id"], name: "index_internal_ids_on_namespace_id"
+ t.index ["project_id"], name: "index_internal_ids_on_project_id"
+ t.index ["usage", "namespace_id"], name: "index_internal_ids_on_usage_and_namespace_id", unique: true, where: "(namespace_id IS NOT NULL)"
+ t.index ["usage", "project_id"], name: "index_internal_ids_on_usage_and_project_id", unique: true, where: "(project_id IS NOT NULL)"
+ end
+
+ create_table "issue_assignees", id: false, force: :cascade do |t|
+ t.integer "user_id", null: false
+ t.integer "issue_id", null: false
+ t.index ["issue_id", "user_id"], name: "index_issue_assignees_on_issue_id_and_user_id", unique: true
+ t.index ["user_id"], name: "index_issue_assignees_on_user_id"
+ end
+
+ create_table "issue_metrics", id: :serial, force: :cascade do |t|
+ t.integer "issue_id", null: false
+ t.datetime "first_mentioned_in_commit_at"
+ t.datetime "first_associated_with_milestone_at"
+ t.datetime "first_added_to_board_at"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["issue_id"], name: "index_issue_metrics"
+ end
+
+ create_table "issues", id: :serial, force: :cascade do |t|
+ t.string "title"
+ t.integer "author_id"
+ t.integer "project_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.text "description"
+ t.integer "milestone_id"
+ t.string "state"
+ t.integer "iid"
+ t.integer "updated_by_id"
+ t.boolean "confidential", default: false, null: false
+ t.date "due_date"
+ t.integer "moved_to_id"
+ t.integer "lock_version"
+ t.text "title_html"
+ t.text "description_html"
+ t.integer "time_estimate"
+ t.integer "relative_position"
+ t.integer "cached_markdown_version"
+ t.datetime "last_edited_at"
+ t.integer "last_edited_by_id"
+ t.boolean "discussion_locked"
+ t.datetime_with_timezone "closed_at"
+ t.integer "closed_by_id"
+ t.index ["author_id"], name: "index_issues_on_author_id"
+ t.index ["closed_by_id"], name: "index_issues_on_closed_by_id"
+ t.index ["confidential"], name: "index_issues_on_confidential"
+ t.index ["description"], name: "index_issues_on_description_trigram", opclass: :gin_trgm_ops, using: :gin
+ t.index ["milestone_id"], name: "index_issues_on_milestone_id"
+ t.index ["moved_to_id"], name: "index_issues_on_moved_to_id", where: "(moved_to_id IS NOT NULL)"
+ t.index ["project_id", "created_at", "id", "state"], name: "index_issues_on_project_id_and_created_at_and_id_and_state"
+ t.index ["project_id", "due_date", "id", "state"], name: "idx_issues_on_project_id_and_due_date_and_id_and_state_partial", where: "(due_date IS NOT NULL)"
+ t.index ["project_id", "iid"], name: "index_issues_on_project_id_and_iid", unique: true
+ t.index ["project_id", "updated_at", "id", "state"], name: "index_issues_on_project_id_and_updated_at_and_id_and_state"
+ t.index ["relative_position"], name: "index_issues_on_relative_position"
+ t.index ["state"], name: "index_issues_on_state"
+ t.index ["title"], name: "index_issues_on_title_trigram", opclass: :gin_trgm_ops, using: :gin
+ t.index ["updated_at"], name: "index_issues_on_updated_at"
+ t.index ["updated_by_id"], name: "index_issues_on_updated_by_id", where: "(updated_by_id IS NOT NULL)"
+ end
+
+ create_table "keys", id: :serial, force: :cascade do |t|
+ t.integer "user_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.text "key"
+ t.string "title"
+ t.string "type"
+ t.string "fingerprint"
+ t.boolean "public", default: false, null: false
+ t.datetime "last_used_at"
+ t.index ["fingerprint"], name: "index_keys_on_fingerprint", unique: true
+ t.index ["user_id"], name: "index_keys_on_user_id"
+ end
+
+ create_table "label_links", id: :serial, force: :cascade do |t|
+ t.integer "label_id"
+ t.integer "target_id"
+ t.string "target_type"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.index ["label_id"], name: "index_label_links_on_label_id"
+ t.index ["target_id", "target_type"], name: "index_label_links_on_target_id_and_target_type"
+ end
+
+ create_table "label_priorities", id: :serial, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.integer "label_id", null: false
+ t.integer "priority", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["label_id"], name: "index_label_priorities_on_label_id"
+ t.index ["priority"], name: "index_label_priorities_on_priority"
+ t.index ["project_id", "label_id"], name: "index_label_priorities_on_project_id_and_label_id", unique: true
+ end
+
+ create_table "labels", id: :serial, force: :cascade do |t|
+ t.string "title"
+ t.string "color"
+ t.integer "project_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.boolean "template", default: false
+ t.string "description"
+ t.text "description_html"
+ t.string "type"
+ t.integer "group_id"
+ t.integer "cached_markdown_version"
+ t.index ["group_id", "project_id", "title"], name: "index_labels_on_group_id_and_project_id_and_title", unique: true
+ t.index ["project_id"], name: "index_labels_on_project_id"
+ t.index ["template"], name: "index_labels_on_template", where: "template"
+ t.index ["title"], name: "index_labels_on_title"
+ t.index ["type", "project_id"], name: "index_labels_on_type_and_project_id"
+ end
+
+ create_table "lfs_file_locks", id: :serial, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.integer "user_id", null: false
+ t.datetime "created_at", null: false
+ t.string "path", limit: 511
+ t.index ["project_id", "path"], name: "index_lfs_file_locks_on_project_id_and_path", unique: true
+ t.index ["user_id"], name: "index_lfs_file_locks_on_user_id"
+ end
+
+ create_table "lfs_objects", id: :serial, force: :cascade do |t|
+ t.string "oid", null: false
+ t.bigint "size", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.string "file"
+ t.integer "file_store"
+ t.index ["file_store"], name: "index_lfs_objects_on_file_store"
+ t.index ["oid"], name: "index_lfs_objects_on_oid", unique: true
+ end
+
+ create_table "lfs_objects_projects", id: :serial, force: :cascade do |t|
+ t.integer "lfs_object_id", null: false
+ t.integer "project_id", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.index ["project_id"], name: "index_lfs_objects_projects_on_project_id"
+ end
+
+ create_table "lists", id: :serial, force: :cascade do |t|
+ t.integer "board_id", null: false
+ t.integer "label_id"
+ t.integer "list_type", default: 1, null: false
+ t.integer "position"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["board_id", "label_id"], name: "index_lists_on_board_id_and_label_id", unique: true
+ t.index ["label_id"], name: "index_lists_on_label_id"
+ t.index ["list_type"], name: "index_lists_on_list_type"
+ end
+
+ create_table "members", id: :serial, force: :cascade do |t|
+ t.integer "access_level", null: false
+ t.integer "source_id", null: false
+ t.string "source_type", null: false
+ t.integer "user_id"
+ t.integer "notification_level", null: false
+ t.string "type"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.integer "created_by_id"
+ t.string "invite_email"
+ t.string "invite_token"
+ t.datetime "invite_accepted_at"
+ t.datetime "requested_at"
+ t.date "expires_at"
+ t.index ["access_level"], name: "index_members_on_access_level"
+ t.index ["invite_token"], name: "index_members_on_invite_token", unique: true
+ t.index ["requested_at"], name: "index_members_on_requested_at"
+ t.index ["source_id", "source_type"], name: "index_members_on_source_id_and_source_type"
+ t.index ["user_id"], name: "index_members_on_user_id"
+ end
+
+ create_table "merge_request_diff_commits", id: false, force: :cascade do |t|
+ t.datetime_with_timezone "authored_date"
+ t.datetime_with_timezone "committed_date"
+ t.integer "merge_request_diff_id", null: false
+ t.integer "relative_order", null: false
+ t.binary "sha", null: false
+ t.text "author_name"
+ t.text "author_email"
+ t.text "committer_name"
+ t.text "committer_email"
+ t.text "message"
+ t.index ["merge_request_diff_id", "relative_order"], name: "index_merge_request_diff_commits_on_mr_diff_id_and_order", unique: true
+ t.index ["sha"], name: "index_merge_request_diff_commits_on_sha"
+ end
+
+ create_table "merge_request_diff_files", id: false, force: :cascade do |t|
+ t.integer "merge_request_diff_id", null: false
+ t.integer "relative_order", null: false
+ t.boolean "new_file", null: false
+ t.boolean "renamed_file", null: false
+ t.boolean "deleted_file", null: false
+ t.boolean "too_large", null: false
+ t.string "a_mode", null: false
+ t.string "b_mode", null: false
+ t.text "new_path", null: false
+ t.text "old_path", null: false
+ t.text "diff", null: false
+ t.boolean "binary"
+ t.index ["merge_request_diff_id", "relative_order"], name: "index_merge_request_diff_files_on_mr_diff_id_and_order", unique: true
+ end
+
+ create_table "merge_request_diffs", id: :serial, force: :cascade do |t|
+ t.string "state"
+ t.integer "merge_request_id", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.string "base_commit_sha"
+ t.string "real_size"
+ t.string "head_commit_sha"
+ t.string "start_commit_sha"
+ t.integer "commits_count"
+ t.index ["merge_request_id", "id"], name: "index_merge_request_diffs_on_merge_request_id_and_id"
+ end
+
+ create_table "merge_request_metrics", id: :serial, force: :cascade do |t|
+ t.integer "merge_request_id", null: false
+ t.datetime "latest_build_started_at"
+ t.datetime "latest_build_finished_at"
+ t.datetime "first_deployed_to_production_at"
+ t.datetime "merged_at"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.integer "pipeline_id"
+ t.integer "merged_by_id"
+ t.integer "latest_closed_by_id"
+ t.datetime_with_timezone "latest_closed_at"
+ t.index ["first_deployed_to_production_at"], name: "index_merge_request_metrics_on_first_deployed_to_production_at"
+ t.index ["latest_closed_by_id"], name: "index_merge_request_metrics_on_latest_closed_by_id"
+ t.index ["merge_request_id"], name: "index_merge_request_metrics"
+ t.index ["merged_by_id"], name: "index_merge_request_metrics_on_merged_by_id"
+ t.index ["pipeline_id"], name: "index_merge_request_metrics_on_pipeline_id"
+ end
+
+ create_table "merge_requests", id: :serial, force: :cascade do |t|
+ t.string "target_branch", null: false
+ t.string "source_branch", null: false
+ t.integer "source_project_id"
+ t.integer "author_id"
+ t.integer "assignee_id"
+ t.string "title"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.integer "milestone_id"
+ t.string "state", default: "opened", null: false
+ t.string "merge_status", default: "unchecked", null: false
+ t.integer "target_project_id", null: false
+ t.integer "iid"
+ t.text "description"
+ t.integer "updated_by_id"
+ t.text "merge_error"
+ t.text "merge_params"
+ t.boolean "merge_when_pipeline_succeeds", default: false, null: false
+ t.integer "merge_user_id"
+ t.string "merge_commit_sha"
+ t.string "rebase_commit_sha"
+ t.string "in_progress_merge_commit_sha"
+ t.integer "lock_version"
+ t.text "title_html"
+ t.text "description_html"
+ t.integer "time_estimate"
+ t.integer "cached_markdown_version"
+ t.datetime "last_edited_at"
+ t.integer "last_edited_by_id"
+ t.integer "head_pipeline_id"
+ t.string "merge_jid"
+ t.boolean "discussion_locked"
+ t.integer "latest_merge_request_diff_id"
+ t.boolean "allow_maintainer_to_push"
+ t.boolean "squash", default: false, null: false
+ t.index ["assignee_id"], name: "index_merge_requests_on_assignee_id"
+ t.index ["author_id"], name: "index_merge_requests_on_author_id"
+ t.index ["created_at"], name: "index_merge_requests_on_created_at"
+ t.index ["description"], name: "index_merge_requests_on_description_trigram", opclass: :gin_trgm_ops, using: :gin
+ t.index ["head_pipeline_id"], name: "index_merge_requests_on_head_pipeline_id"
+ t.index ["id", "merge_jid"], name: "index_merge_requests_on_id_and_merge_jid", where: "((merge_jid IS NOT NULL) AND ((state)::text = 'locked'::text))"
+ t.index ["latest_merge_request_diff_id"], name: "index_merge_requests_on_latest_merge_request_diff_id"
+ t.index ["merge_user_id"], name: "index_merge_requests_on_merge_user_id", where: "(merge_user_id IS NOT NULL)"
+ t.index ["milestone_id"], name: "index_merge_requests_on_milestone_id"
+ t.index ["source_branch"], name: "index_merge_requests_on_source_branch"
+ t.index ["source_project_id", "source_branch"], name: "index_merge_requests_on_source_project_and_branch_state_opened", where: "((state)::text = 'opened'::text)"
+ t.index ["source_project_id", "source_branch"], name: "index_merge_requests_on_source_project_id_and_source_branch"
+ t.index ["target_branch"], name: "index_merge_requests_on_target_branch"
+ t.index ["target_project_id", "iid"], name: "index_merge_requests_on_target_project_id_and_iid", unique: true
+ t.index ["target_project_id", "iid"], name: "index_merge_requests_on_target_project_id_and_iid_opened", where: "((state)::text = 'opened'::text)"
+ t.index ["target_project_id", "merge_commit_sha", "id"], name: "index_merge_requests_on_tp_id_and_merge_commit_sha_and_id"
+ t.index ["title"], name: "index_merge_requests_on_title"
+ t.index ["title"], name: "index_merge_requests_on_title_trigram", opclass: :gin_trgm_ops, using: :gin
+ t.index ["updated_by_id"], name: "index_merge_requests_on_updated_by_id", where: "(updated_by_id IS NOT NULL)"
+ end
+
+ create_table "merge_requests_closing_issues", id: :serial, force: :cascade do |t|
+ t.integer "merge_request_id", null: false
+ t.integer "issue_id", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["issue_id"], name: "index_merge_requests_closing_issues_on_issue_id"
+ t.index ["merge_request_id"], name: "index_merge_requests_closing_issues_on_merge_request_id"
+ end
+
+ create_table "milestones", id: :serial, force: :cascade do |t|
+ t.string "title", null: false
+ t.integer "project_id"
+ t.text "description"
+ t.date "due_date"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.string "state"
+ t.integer "iid"
+ t.text "title_html"
+ t.text "description_html"
+ t.date "start_date"
+ t.integer "cached_markdown_version"
+ t.integer "group_id"
+ t.index ["description"], name: "index_milestones_on_description_trigram", opclass: :gin_trgm_ops, using: :gin
+ t.index ["due_date"], name: "index_milestones_on_due_date"
+ t.index ["group_id"], name: "index_milestones_on_group_id"
+ t.index ["project_id", "iid"], name: "index_milestones_on_project_id_and_iid", unique: true
+ t.index ["title"], name: "index_milestones_on_title"
+ t.index ["title"], name: "index_milestones_on_title_trigram", opclass: :gin_trgm_ops, using: :gin
+ end
+
+ create_table "namespaces", id: :serial, force: :cascade do |t|
+ t.string "name", null: false
+ t.string "path", null: false
+ t.integer "owner_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.string "type"
+ t.string "description", default: "", null: false
+ t.string "avatar"
+ t.boolean "share_with_group_lock", default: false
+ t.integer "visibility_level", default: 20, null: false
+ t.boolean "request_access_enabled", default: false, null: false
+ t.text "description_html"
+ t.boolean "lfs_enabled"
+ t.integer "parent_id"
+ t.boolean "require_two_factor_authentication", default: false, null: false
+ t.integer "two_factor_grace_period", default: 48, null: false
+ t.integer "cached_markdown_version"
+ t.string "runners_token"
+ t.integer "project_creation_level"
+ t.string "runners_token_encrypted"
+ t.index ["created_at"], name: "index_namespaces_on_created_at"
+ t.index ["name", "parent_id"], name: "index_namespaces_on_name_and_parent_id", unique: true
+ t.index ["name"], name: "index_namespaces_on_name_trigram", opclass: :gin_trgm_ops, using: :gin
+ t.index ["owner_id"], name: "index_namespaces_on_owner_id"
+ t.index ["parent_id", "id"], name: "index_namespaces_on_parent_id_and_id", unique: true
+ t.index ["path"], name: "index_namespaces_on_path"
+ t.index ["path"], name: "index_namespaces_on_path_trigram", opclass: :gin_trgm_ops, using: :gin
+ t.index ["require_two_factor_authentication"], name: "index_namespaces_on_require_two_factor_authentication"
+ t.index ["runners_token"], name: "index_namespaces_on_runners_token", unique: true
+ t.index ["type"], name: "index_namespaces_on_type"
+ end
+
+ create_table "note_diff_files", id: :serial, force: :cascade do |t|
+ t.integer "diff_note_id", null: false
+ t.text "diff", null: false
+ t.boolean "new_file", null: false
+ t.boolean "renamed_file", null: false
+ t.boolean "deleted_file", null: false
+ t.string "a_mode", null: false
+ t.string "b_mode", null: false
+ t.text "new_path", null: false
+ t.text "old_path", null: false
+ t.index ["diff_note_id"], name: "index_note_diff_files_on_diff_note_id", unique: true
+ end
+
+ create_table "notes", id: :serial, force: :cascade do |t|
+ t.text "note"
+ t.string "noteable_type"
+ t.integer "author_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.integer "project_id"
+ t.string "attachment"
+ t.string "line_code"
+ t.string "commit_id"
+ t.integer "noteable_id"
+ t.boolean "system", default: false, null: false
+ t.text "st_diff"
+ t.integer "updated_by_id"
+ t.string "type"
+ t.text "position"
+ t.text "original_position"
+ t.datetime "resolved_at"
+ t.integer "resolved_by_id"
+ t.string "discussion_id"
+ t.text "note_html"
+ t.integer "cached_markdown_version"
+ t.text "change_position"
+ t.boolean "resolved_by_push"
+ t.index ["author_id"], name: "index_notes_on_author_id"
+ t.index ["commit_id"], name: "index_notes_on_commit_id"
+ t.index ["created_at"], name: "index_notes_on_created_at"
+ t.index ["discussion_id"], name: "index_notes_on_discussion_id"
+ t.index ["line_code"], name: "index_notes_on_line_code"
+ t.index ["note"], name: "index_notes_on_note_trigram", opclass: :gin_trgm_ops, using: :gin
+ t.index ["noteable_id", "noteable_type"], name: "index_notes_on_noteable_id_and_noteable_type"
+ t.index ["noteable_type"], name: "index_notes_on_noteable_type"
+ t.index ["project_id", "noteable_type"], name: "index_notes_on_project_id_and_noteable_type"
+ end
+
+ create_table "notification_settings", id: :serial, force: :cascade do |t|
+ t.integer "user_id", null: false
+ t.string "source_type"
+ t.integer "source_id"
+ t.integer "level", default: 0, null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.boolean "new_note"
+ t.boolean "new_issue"
+ t.boolean "reopen_issue"
+ t.boolean "close_issue"
+ t.boolean "reassign_issue"
+ t.boolean "new_merge_request"
+ t.boolean "reopen_merge_request"
+ t.boolean "close_merge_request"
+ t.boolean "reassign_merge_request"
+ t.boolean "merge_merge_request"
+ t.boolean "failed_pipeline"
+ t.boolean "success_pipeline"
+ t.boolean "push_to_merge_request"
+ t.boolean "issue_due"
+ t.index ["source_id", "source_type"], name: "index_notification_settings_on_source_id_and_source_type"
+ t.index ["user_id", "source_id", "source_type"], name: "index_notifications_on_user_id_and_source_id_and_source_type", unique: true
+ t.index ["user_id"], name: "index_notification_settings_on_user_id"
+ end
+
+ create_table "oauth_access_grants", id: :serial, force: :cascade do |t|
+ t.integer "resource_owner_id", null: false
+ t.integer "application_id", null: false
+ t.string "token", null: false
+ t.integer "expires_in", null: false
+ t.text "redirect_uri", null: false
+ t.datetime "created_at", null: false
+ t.datetime "revoked_at"
+ t.string "scopes"
+ t.index ["token"], name: "index_oauth_access_grants_on_token", unique: true
+ end
+
+ create_table "oauth_access_tokens", id: :serial, force: :cascade do |t|
+ t.integer "resource_owner_id"
+ t.integer "application_id"
+ t.string "token", null: false
+ t.string "refresh_token"
+ t.integer "expires_in"
+ t.datetime "revoked_at"
+ t.datetime "created_at", null: false
+ t.string "scopes"
+ t.index ["refresh_token"], name: "index_oauth_access_tokens_on_refresh_token", unique: true
+ t.index ["resource_owner_id"], name: "index_oauth_access_tokens_on_resource_owner_id"
+ t.index ["token"], name: "index_oauth_access_tokens_on_token", unique: true
+ end
+
+ create_table "oauth_applications", id: :serial, force: :cascade do |t|
+ t.string "name", null: false
+ t.string "uid", null: false
+ t.string "secret", null: false
+ t.text "redirect_uri", null: false
+ t.string "scopes", default: "", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.integer "owner_id"
+ t.string "owner_type"
+ t.boolean "trusted", default: false, null: false
+ t.index ["owner_id", "owner_type"], name: "index_oauth_applications_on_owner_id_and_owner_type"
+ t.index ["uid"], name: "index_oauth_applications_on_uid", unique: true
+ end
+
+ create_table "oauth_openid_requests", id: :serial, force: :cascade do |t|
+ t.integer "access_grant_id", null: false
+ t.string "nonce", null: false
+ t.index ["access_grant_id"], name: "index_oauth_openid_requests_on_access_grant_id"
+ end
+
+ create_table "pages_domains", id: :serial, force: :cascade do |t|
+ t.integer "project_id"
+ t.text "certificate"
+ t.text "encrypted_key"
+ t.string "encrypted_key_iv"
+ t.string "encrypted_key_salt"
+ t.string "domain"
+ t.datetime_with_timezone "verified_at"
+ t.string "verification_code", null: false
+ t.datetime_with_timezone "enabled_until"
+ t.index ["domain"], name: "index_pages_domains_on_domain", unique: true
+ t.index ["project_id", "enabled_until"], name: "index_pages_domains_on_project_id_and_enabled_until"
+ t.index ["project_id"], name: "index_pages_domains_on_project_id"
+ t.index ["verified_at", "enabled_until"], name: "index_pages_domains_on_verified_at_and_enabled_until"
+ t.index ["verified_at"], name: "index_pages_domains_on_verified_at"
+ end
+
+ create_table "personal_access_tokens", id: :serial, force: :cascade do |t|
+ t.integer "user_id", null: false
+ t.string "name", null: false
+ t.boolean "revoked", default: false
+ t.date "expires_at"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.string "scopes", default: "--- []\n", null: false
+ t.boolean "impersonation", default: false, null: false
+ t.string "token_digest"
+ t.index ["token_digest"], name: "index_personal_access_tokens_on_token_digest", unique: true
+ t.index ["user_id"], name: "index_personal_access_tokens_on_user_id"
+ end
+
+ create_table "pool_repositories", force: :cascade do |t|
+ t.integer "shard_id", null: false
+ t.string "disk_path"
+ t.string "state"
+ t.integer "source_project_id"
+ t.index ["disk_path"], name: "index_pool_repositories_on_disk_path", unique: true
+ t.index ["shard_id"], name: "index_pool_repositories_on_shard_id"
+ t.index ["source_project_id"], name: "index_pool_repositories_on_source_project_id", unique: true
+ end
+
+ create_table "programming_languages", id: :serial, force: :cascade do |t|
+ t.string "name", null: false
+ t.string "color", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.index ["name"], name: "index_programming_languages_on_name", unique: true
+ end
+
+ create_table "project_authorizations", id: false, force: :cascade do |t|
+ t.integer "user_id", null: false
+ t.integer "project_id", null: false
+ t.integer "access_level", null: false
+ t.index ["project_id"], name: "index_project_authorizations_on_project_id"
+ t.index ["user_id", "project_id", "access_level"], name: "index_project_authorizations_on_user_id_project_id_access_level", unique: true
+ end
+
+ create_table "project_auto_devops", id: :serial, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.boolean "enabled"
+ t.string "domain"
+ t.integer "deploy_strategy", default: 0, null: false
+ t.index ["project_id"], name: "index_project_auto_devops_on_project_id", unique: true
+ end
+
+ create_table "project_ci_cd_settings", id: :serial, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.boolean "group_runners_enabled", default: true, null: false
+ t.index ["project_id"], name: "index_project_ci_cd_settings_on_project_id", unique: true
+ end
+
+ create_table "project_custom_attributes", id: :serial, force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "project_id", null: false
+ t.string "key", null: false
+ t.string "value", null: false
+ t.index ["key", "value"], name: "index_project_custom_attributes_on_key_and_value"
+ t.index ["project_id", "key"], name: "index_project_custom_attributes_on_project_id_and_key", unique: true
+ end
+
+ create_table "project_daily_statistics", force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.integer "fetch_count", null: false
+ t.date "date"
+ t.index ["project_id", "date"], name: "index_project_daily_statistics_on_project_id_and_date", unique: true, order: { date: :desc }
+ end
+
+ create_table "project_deploy_tokens", id: :serial, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.integer "deploy_token_id", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.index ["deploy_token_id"], name: "index_project_deploy_tokens_on_deploy_token_id"
+ t.index ["project_id", "deploy_token_id"], name: "index_project_deploy_tokens_on_project_id_and_deploy_token_id", unique: true
+ end
+
+ create_table "project_error_tracking_settings", primary_key: "project_id", id: :integer, default: nil, force: :cascade do |t|
+ t.boolean "enabled", default: true, null: false
+ t.string "api_url", null: false
+ t.string "encrypted_token"
+ t.string "encrypted_token_iv"
+ end
+
+ create_table "project_features", id: :serial, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.integer "merge_requests_access_level"
+ t.integer "issues_access_level"
+ t.integer "wiki_access_level"
+ t.integer "snippets_access_level", default: 20, null: false
+ t.integer "builds_access_level"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.integer "repository_access_level", default: 20, null: false
+ t.integer "pages_access_level", default: 20, null: false
+ t.index ["project_id"], name: "index_project_features_on_project_id", unique: true
+ end
+
+ create_table "project_group_links", id: :serial, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.integer "group_id", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.integer "group_access", default: 30, null: false
+ t.date "expires_at"
+ t.index ["group_id"], name: "index_project_group_links_on_group_id"
+ t.index ["project_id"], name: "index_project_group_links_on_project_id"
+ end
+
+ create_table "project_import_data", id: :serial, force: :cascade do |t|
+ t.integer "project_id"
+ t.text "data"
+ t.text "encrypted_credentials"
+ t.string "encrypted_credentials_iv"
+ t.string "encrypted_credentials_salt"
+ t.index ["project_id"], name: "index_project_import_data_on_project_id"
+ end
+
+ create_table "project_mirror_data", id: :serial, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.string "status"
+ t.string "jid"
+ t.text "last_error"
+ t.index ["jid"], name: "index_project_mirror_data_on_jid"
+ t.index ["project_id"], name: "index_project_mirror_data_on_project_id", unique: true
+ t.index ["status"], name: "index_project_mirror_data_on_status"
+ end
+
+ create_table "project_repositories", force: :cascade do |t|
+ t.integer "shard_id", null: false
+ t.string "disk_path", null: false
+ t.integer "project_id", null: false
+ t.index ["disk_path"], name: "index_project_repositories_on_disk_path", unique: true
+ t.index ["project_id"], name: "index_project_repositories_on_project_id", unique: true
+ t.index ["shard_id"], name: "index_project_repositories_on_shard_id"
+ end
+
+ create_table "project_statistics", id: :serial, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.integer "namespace_id", null: false
+ t.bigint "commit_count", default: 0, null: false
+ t.bigint "storage_size", default: 0, null: false
+ t.bigint "repository_size", default: 0, null: false
+ t.bigint "lfs_objects_size", default: 0, null: false
+ t.bigint "build_artifacts_size", default: 0, null: false
+ t.index ["namespace_id"], name: "index_project_statistics_on_namespace_id"
+ t.index ["project_id"], name: "index_project_statistics_on_project_id", unique: true
+ end
+
+ create_table "projects", id: :serial, force: :cascade do |t|
+ t.string "name"
+ t.string "path"
+ t.text "description"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.integer "creator_id"
+ t.integer "namespace_id", null: false
+ t.datetime "last_activity_at"
+ t.string "import_url"
+ t.integer "visibility_level", default: 0, null: false
+ t.boolean "archived", default: false, null: false
+ t.string "avatar"
+ t.string "import_status"
+ t.integer "star_count", default: 0, null: false
+ t.boolean "merge_requests_rebase_enabled", default: false, null: false
+ t.string "import_type"
+ t.string "import_source"
+ t.boolean "merge_requests_ff_only_enabled", default: false, null: false
+ t.text "import_error"
+ t.integer "ci_id"
+ t.boolean "shared_runners_enabled", default: true, null: false
+ t.string "runners_token"
+ t.string "build_coverage_regex"
+ t.boolean "build_allow_git_fetch", default: true, null: false
+ t.integer "build_timeout", default: 3600, null: false
+ t.boolean "pending_delete", default: false
+ t.boolean "public_builds", default: true, null: false
+ t.boolean "last_repository_check_failed"
+ t.datetime "last_repository_check_at"
+ t.boolean "container_registry_enabled"
+ t.boolean "only_allow_merge_if_pipeline_succeeds", default: false, null: false
+ t.boolean "has_external_issue_tracker"
+ t.string "repository_storage", default: "default", null: false
+ t.boolean "repository_read_only"
+ t.boolean "request_access_enabled", default: false, null: false
+ t.boolean "has_external_wiki"
+ t.string "ci_config_path"
+ t.boolean "lfs_enabled"
+ t.text "description_html"
+ t.boolean "only_allow_merge_if_all_discussions_are_resolved"
+ t.boolean "printing_merge_request_link_enabled", default: true, null: false
+ t.integer "auto_cancel_pending_pipelines", default: 1, null: false
+ t.string "import_jid"
+ t.integer "cached_markdown_version"
+ t.text "delete_error"
+ t.datetime "last_repository_updated_at"
+ t.integer "storage_version", limit: 2
+ t.boolean "resolve_outdated_diff_discussions"
+ t.string "external_authorization_classification_label"
+ t.integer "jobs_cache_index"
+ t.boolean "pages_https_only", default: true
+ t.boolean "remote_mirror_available_overridden"
+ t.bigint "pool_repository_id"
+ t.string "runners_token_encrypted"
+ t.string "bfg_object_map"
+ t.index "lower((name)::text)", name: "index_projects_on_lower_name"
+ t.index ["ci_id"], name: "index_projects_on_ci_id"
+ t.index ["created_at"], name: "index_projects_on_created_at"
+ t.index ["creator_id"], name: "index_projects_on_creator_id"
+ t.index ["description"], name: "index_projects_on_description_trigram", opclass: :gin_trgm_ops, using: :gin
+ t.index ["id"], name: "index_projects_on_id_partial_for_visibility", unique: true, where: "(visibility_level = ANY (ARRAY[10, 20]))"
+ t.index ["last_activity_at"], name: "index_projects_on_last_activity_at"
+ t.index ["last_repository_check_at"], name: "index_projects_on_last_repository_check_at", where: "(last_repository_check_at IS NOT NULL)"
+ t.index ["last_repository_check_failed"], name: "index_projects_on_last_repository_check_failed"
+ t.index ["last_repository_updated_at"], name: "index_projects_on_last_repository_updated_at"
+ t.index ["name"], name: "index_projects_on_name_trigram", opclass: :gin_trgm_ops, using: :gin
+ t.index ["namespace_id"], name: "index_projects_on_namespace_id"
+ t.index ["path"], name: "index_projects_on_path"
+ t.index ["path"], name: "index_projects_on_path_trigram", opclass: :gin_trgm_ops, using: :gin
+ t.index ["pending_delete"], name: "index_projects_on_pending_delete"
+ t.index ["pool_repository_id"], name: "index_projects_on_pool_repository_id", where: "(pool_repository_id IS NOT NULL)"
+ t.index ["repository_storage", "created_at"], name: "idx_project_repository_check_partial", where: "(last_repository_check_at IS NULL)"
+ t.index ["repository_storage"], name: "index_projects_on_repository_storage"
+ t.index ["runners_token"], name: "index_projects_on_runners_token"
+ t.index ["star_count"], name: "index_projects_on_star_count"
+ t.index ["visibility_level"], name: "index_projects_on_visibility_level"
+ end
+
+ create_table "prometheus_metrics", id: :serial, force: :cascade do |t|
+ t.integer "project_id"
+ t.string "title", null: false
+ t.string "query", null: false
+ t.string "y_label"
+ t.string "unit"
+ t.string "legend"
+ t.integer "group", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.boolean "common", default: false, null: false
+ t.string "identifier"
+ t.index ["common"], name: "index_prometheus_metrics_on_common"
+ t.index ["group"], name: "index_prometheus_metrics_on_group"
+ t.index ["identifier"], name: "index_prometheus_metrics_on_identifier", unique: true
+ t.index ["project_id"], name: "index_prometheus_metrics_on_project_id"
+ end
+
+ create_table "protected_branch_merge_access_levels", id: :serial, force: :cascade do |t|
+ t.integer "protected_branch_id", null: false
+ t.integer "access_level", default: 40, null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["protected_branch_id"], name: "index_protected_branch_merge_access"
+ end
+
+ create_table "protected_branch_push_access_levels", id: :serial, force: :cascade do |t|
+ t.integer "protected_branch_id", null: false
+ t.integer "access_level", default: 40, null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["protected_branch_id"], name: "index_protected_branch_push_access"
+ end
+
+ create_table "protected_branches", id: :serial, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.string "name", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.index ["project_id"], name: "index_protected_branches_on_project_id"
+ end
+
+ create_table "protected_tag_create_access_levels", id: :serial, force: :cascade do |t|
+ t.integer "protected_tag_id", null: false
+ t.integer "access_level", default: 40
+ t.integer "user_id"
+ t.integer "group_id"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["group_id"], name: "index_protected_tag_create_access_levels_on_group_id"
+ t.index ["protected_tag_id"], name: "index_protected_tag_create_access"
+ t.index ["user_id"], name: "index_protected_tag_create_access_levels_on_user_id"
+ end
+
+ create_table "protected_tags", id: :serial, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.string "name", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["project_id", "name"], name: "index_protected_tags_on_project_id_and_name", unique: true
+ t.index ["project_id"], name: "index_protected_tags_on_project_id"
+ end
+
+ create_table "push_event_payloads", id: false, force: :cascade do |t|
+ t.bigint "commit_count", null: false
+ t.integer "event_id", null: false
+ t.integer "action", limit: 2, null: false
+ t.integer "ref_type", limit: 2, null: false
+ t.binary "commit_from"
+ t.binary "commit_to"
+ t.text "ref"
+ t.string "commit_title", limit: 70
+ t.index ["event_id"], name: "index_push_event_payloads_on_event_id", unique: true
+ end
+
+ create_table "redirect_routes", id: :serial, force: :cascade do |t|
+ t.integer "source_id", null: false
+ t.string "source_type", null: false
+ t.string "path", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index "lower((path)::text) varchar_pattern_ops", name: "index_redirect_routes_on_path_unique_text_pattern_ops", unique: true
+ t.index ["path"], name: "index_redirect_routes_on_path", unique: true
+ t.index ["source_type", "source_id"], name: "index_redirect_routes_on_source_type_and_source_id"
+ end
+
+ create_table "release_links", force: :cascade do |t|
+ t.integer "release_id", null: false
+ t.string "url", null: false
+ t.string "name", null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.index ["release_id", "name"], name: "index_release_links_on_release_id_and_name", unique: true
+ t.index ["release_id", "url"], name: "index_release_links_on_release_id_and_url", unique: true
+ end
+
+ create_table "releases", id: :serial, force: :cascade do |t|
+ t.string "tag"
+ t.text "description"
+ t.integer "project_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.text "description_html"
+ t.integer "cached_markdown_version"
+ t.integer "author_id"
+ t.string "name"
+ t.string "sha"
+ t.index ["author_id"], name: "index_releases_on_author_id"
+ t.index ["project_id", "tag"], name: "index_releases_on_project_id_and_tag"
+ t.index ["project_id"], name: "index_releases_on_project_id"
+ end
+
+ create_table "remote_mirrors", id: :serial, force: :cascade do |t|
+ t.integer "project_id"
+ t.string "url"
+ t.boolean "enabled", default: false
+ t.string "update_status"
+ t.datetime "last_update_at"
+ t.datetime "last_successful_update_at"
+ t.datetime "last_update_started_at"
+ t.string "last_error"
+ t.boolean "only_protected_branches", default: false, null: false
+ t.string "remote_name"
+ t.text "encrypted_credentials"
+ t.string "encrypted_credentials_iv"
+ t.string "encrypted_credentials_salt"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["last_successful_update_at"], name: "index_remote_mirrors_on_last_successful_update_at"
+ t.index ["project_id"], name: "index_remote_mirrors_on_project_id"
+ end
+
+ create_table "repository_languages", id: false, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.integer "programming_language_id", null: false
+ t.float "share", null: false
+ t.index ["project_id", "programming_language_id"], name: "index_repository_languages_on_project_and_languages_id", unique: true
+ end
+
+ create_table "resource_label_events", force: :cascade do |t|
+ t.integer "action", null: false
+ t.integer "issue_id"
+ t.integer "merge_request_id"
+ t.integer "label_id"
+ t.integer "user_id"
+ t.datetime_with_timezone "created_at", null: false
+ t.integer "cached_markdown_version"
+ t.text "reference"
+ t.text "reference_html"
+ t.index ["issue_id"], name: "index_resource_label_events_on_issue_id"
+ t.index ["label_id"], name: "index_resource_label_events_on_label_id"
+ t.index ["merge_request_id"], name: "index_resource_label_events_on_merge_request_id"
+ t.index ["user_id"], name: "index_resource_label_events_on_user_id"
+ end
+
+ create_table "routes", id: :serial, force: :cascade do |t|
+ t.integer "source_id", null: false
+ t.string "source_type", null: false
+ t.string "path", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.string "name"
+ t.index ["path"], name: "index_routes_on_path", unique: true
+ t.index ["path"], name: "index_routes_on_path_text_pattern_ops", opclass: :varchar_pattern_ops
+ t.index ["source_type", "source_id"], name: "index_routes_on_source_type_and_source_id", unique: true
+ end
+
+ create_table "sent_notifications", id: :serial, force: :cascade do |t|
+ t.integer "project_id"
+ t.string "noteable_type"
+ t.integer "noteable_id"
+ t.integer "recipient_id"
+ t.string "commit_id"
+ t.string "reply_key", null: false
+ t.string "line_code"
+ t.string "note_type"
+ t.text "position"
+ t.string "in_reply_to_discussion_id"
+ t.index ["reply_key"], name: "index_sent_notifications_on_reply_key", unique: true
+ end
+
+ create_table "services", id: :serial, force: :cascade do |t|
+ t.string "type"
+ t.string "title"
+ t.integer "project_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.boolean "active", default: false, null: false
+ t.text "properties"
+ t.boolean "template", default: false
+ t.boolean "push_events", default: true
+ t.boolean "issues_events", default: true
+ t.boolean "merge_requests_events", default: true
+ t.boolean "tag_push_events", default: true
+ t.boolean "note_events", default: true, null: false
+ t.string "category", default: "common", null: false
+ t.boolean "default", default: false
+ t.boolean "wiki_page_events", default: true
+ t.boolean "pipeline_events", default: false, null: false
+ t.boolean "confidential_issues_events", default: true, null: false
+ t.boolean "commit_events", default: true, null: false
+ t.boolean "job_events", default: false, null: false
+ t.boolean "confidential_note_events", default: true
+ t.index ["project_id"], name: "index_services_on_project_id"
+ t.index ["template"], name: "index_services_on_template"
+ end
+
+ create_table "shards", id: :serial, force: :cascade do |t|
+ t.string "name", null: false
+ t.index ["name"], name: "index_shards_on_name", unique: true
+ end
+
+ create_table "snippets", id: :serial, force: :cascade do |t|
+ t.string "title"
+ t.text "content"
+ t.integer "author_id", null: false
+ t.integer "project_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.string "file_name"
+ t.string "type"
+ t.integer "visibility_level", default: 0, null: false
+ t.text "title_html"
+ t.text "content_html"
+ t.integer "cached_markdown_version"
+ t.text "description"
+ t.text "description_html"
+ t.index ["author_id"], name: "index_snippets_on_author_id"
+ t.index ["file_name"], name: "index_snippets_on_file_name_trigram", opclass: :gin_trgm_ops, using: :gin
+ t.index ["project_id"], name: "index_snippets_on_project_id"
+ t.index ["title"], name: "index_snippets_on_title_trigram", opclass: :gin_trgm_ops, using: :gin
+ t.index ["updated_at"], name: "index_snippets_on_updated_at"
+ t.index ["visibility_level"], name: "index_snippets_on_visibility_level"
+ end
+
+ create_table "spam_logs", id: :serial, force: :cascade do |t|
+ t.integer "user_id"
+ t.string "source_ip"
+ t.string "user_agent"
+ t.boolean "via_api"
+ t.string "noteable_type"
+ t.string "title"
+ t.text "description"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.boolean "submitted_as_ham", default: false, null: false
+ t.boolean "recaptcha_verified", default: false, null: false
+ end
+
+ create_table "subscriptions", id: :serial, force: :cascade do |t|
+ t.integer "user_id"
+ t.string "subscribable_type"
+ t.integer "subscribable_id"
+ t.boolean "subscribed"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.integer "project_id"
+ t.index ["project_id"], name: "index_subscriptions_on_project_id"
+ t.index ["subscribable_id", "subscribable_type", "user_id", "project_id"], name: "index_subscriptions_on_subscribable_and_user_id_and_project_id", unique: true
+ end
+
+ create_table "suggestions", force: :cascade do |t|
+ t.integer "note_id", null: false
+ t.integer "relative_order", limit: 2, null: false
+ t.boolean "applied", default: false, null: false
+ t.string "commit_id"
+ t.text "from_content", null: false
+ t.text "to_content", null: false
+ t.index ["note_id", "relative_order"], name: "index_suggestions_on_note_id_and_relative_order", unique: true
+ t.index ["note_id"], name: "index_suggestions_on_note_id"
+ end
+
+ create_table "system_note_metadata", id: :serial, force: :cascade do |t|
+ t.integer "note_id", null: false
+ t.integer "commit_count"
+ t.string "action"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["note_id"], name: "index_system_note_metadata_on_note_id", unique: true
+ end
+
+ create_table "taggings", id: :serial, force: :cascade do |t|
+ t.integer "tag_id"
+ t.integer "taggable_id"
+ t.string "taggable_type"
+ t.integer "tagger_id"
+ t.string "tagger_type"
+ t.string "context"
+ t.datetime "created_at"
+ t.index ["tag_id", "taggable_id", "taggable_type", "context", "tagger_id", "tagger_type"], name: "taggings_idx", unique: true
+ t.index ["tag_id"], name: "index_taggings_on_tag_id"
+ t.index ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context"
+ t.index ["taggable_id", "taggable_type"], name: "index_taggings_on_taggable_id_and_taggable_type"
+ end
+
+ create_table "tags", id: :serial, force: :cascade do |t|
+ t.string "name"
+ t.integer "taggings_count", default: 0
+ t.index ["name"], name: "index_tags_on_name", unique: true
+ end
+
+ create_table "term_agreements", id: :serial, force: :cascade do |t|
+ t.integer "term_id", null: false
+ t.integer "user_id", null: false
+ t.boolean "accepted", default: false, null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.index ["term_id"], name: "index_term_agreements_on_term_id"
+ t.index ["user_id", "term_id"], name: "term_agreements_unique_index", unique: true
+ t.index ["user_id"], name: "index_term_agreements_on_user_id"
+ end
+
+ create_table "timelogs", id: :serial, force: :cascade do |t|
+ t.integer "time_spent", null: false
+ t.integer "user_id"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.integer "issue_id"
+ t.integer "merge_request_id"
+ t.datetime_with_timezone "spent_at"
+ t.index ["issue_id"], name: "index_timelogs_on_issue_id"
+ t.index ["merge_request_id"], name: "index_timelogs_on_merge_request_id"
+ t.index ["user_id"], name: "index_timelogs_on_user_id"
+ end
+
+ create_table "todos", id: :serial, force: :cascade do |t|
+ t.integer "user_id", null: false
+ t.integer "project_id"
+ t.string "target_type", null: false
+ t.integer "target_id"
+ t.integer "author_id", null: false
+ t.integer "action", null: false
+ t.string "state", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.integer "note_id"
+ t.string "commit_id"
+ t.integer "group_id"
+ t.index ["author_id"], name: "index_todos_on_author_id"
+ t.index ["commit_id"], name: "index_todos_on_commit_id"
+ t.index ["group_id"], name: "index_todos_on_group_id"
+ t.index ["note_id"], name: "index_todos_on_note_id"
+ t.index ["project_id"], name: "index_todos_on_project_id"
+ t.index ["target_type", "target_id"], name: "index_todos_on_target_type_and_target_id"
+ t.index ["user_id", "id"], name: "index_todos_on_user_id_and_id_done", where: "((state)::text = 'done'::text)"
+ t.index ["user_id", "id"], name: "index_todos_on_user_id_and_id_pending", where: "((state)::text = 'pending'::text)"
+ t.index ["user_id"], name: "index_todos_on_user_id"
+ end
+
+ create_table "trending_projects", id: :serial, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.index ["project_id"], name: "index_trending_projects_on_project_id", unique: true
+ end
+
+ create_table "u2f_registrations", id: :serial, force: :cascade do |t|
+ t.text "certificate"
+ t.string "key_handle"
+ t.string "public_key"
+ t.integer "counter"
+ t.integer "user_id"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.string "name"
+ t.index ["key_handle"], name: "index_u2f_registrations_on_key_handle"
+ t.index ["user_id"], name: "index_u2f_registrations_on_user_id"
+ end
+
+ create_table "uploads", id: :serial, force: :cascade do |t|
+ t.bigint "size", null: false
+ t.string "path", limit: 511, null: false
+ t.string "checksum", limit: 64
+ t.string "model_type"
+ t.integer "model_id"
+ t.string "uploader", null: false
+ t.datetime "created_at", null: false
+ t.integer "store"
+ t.string "mount_point"
+ t.string "secret"
+ t.index ["checksum"], name: "index_uploads_on_checksum"
+ t.index ["model_id", "model_type"], name: "index_uploads_on_model_id_and_model_type"
+ t.index ["store"], name: "index_uploads_on_store"
+ t.index ["uploader", "path"], name: "index_uploads_on_uploader_and_path"
+ end
+
+ create_table "user_agent_details", id: :serial, force: :cascade do |t|
+ t.string "user_agent", null: false
+ t.string "ip_address", null: false
+ t.integer "subject_id", null: false
+ t.string "subject_type", null: false
+ t.boolean "submitted", default: false, null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["subject_id", "subject_type"], name: "index_user_agent_details_on_subject_id_and_subject_type"
+ end
+
+ create_table "user_callouts", id: :serial, force: :cascade do |t|
+ t.integer "feature_name", null: false
+ t.integer "user_id", null: false
+ t.index ["user_id", "feature_name"], name: "index_user_callouts_on_user_id_and_feature_name", unique: true
+ t.index ["user_id"], name: "index_user_callouts_on_user_id"
+ end
+
+ create_table "user_custom_attributes", id: :serial, force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "user_id", null: false
+ t.string "key", null: false
+ t.string "value", null: false
+ t.index ["key", "value"], name: "index_user_custom_attributes_on_key_and_value"
+ t.index ["user_id", "key"], name: "index_user_custom_attributes_on_user_id_and_key", unique: true
+ end
+
+ create_table "user_interacted_projects", id: false, force: :cascade do |t|
+ t.integer "user_id", null: false
+ t.integer "project_id", null: false
+ t.index ["project_id", "user_id"], name: "index_user_interacted_projects_on_project_id_and_user_id", unique: true
+ t.index ["user_id"], name: "index_user_interacted_projects_on_user_id"
+ end
+
+ create_table "user_preferences", id: :serial, force: :cascade do |t|
+ t.integer "user_id", null: false
+ t.integer "issue_notes_filter", limit: 2, default: 0, null: false
+ t.integer "merge_request_notes_filter", limit: 2, default: 0, null: false
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "first_day_of_week"
+ t.index ["user_id"], name: "index_user_preferences_on_user_id", unique: true
+ end
+
+ create_table "user_statuses", primary_key: "user_id", id: :serial, force: :cascade do |t|
+ t.integer "cached_markdown_version"
+ t.string "emoji", default: "speech_balloon", null: false
+ t.string "message", limit: 100
+ t.string "message_html"
+ t.index ["user_id"], name: "index_user_statuses_on_user_id"
+ end
+
+ create_table "user_synced_attributes_metadata", id: :serial, force: :cascade do |t|
+ t.boolean "name_synced", default: false
+ t.boolean "email_synced", default: false
+ t.boolean "location_synced", default: false
+ t.integer "user_id", null: false
+ t.string "provider"
+ t.index ["user_id"], name: "index_user_synced_attributes_metadata_on_user_id", unique: true
+ end
+
+ create_table "users", id: :serial, force: :cascade do |t|
+ t.string "email", default: "", null: false
+ t.string "encrypted_password", default: "", null: false
+ t.string "reset_password_token"
+ t.datetime "reset_password_sent_at"
+ t.datetime "remember_created_at"
+ t.integer "sign_in_count", default: 0
+ t.datetime "current_sign_in_at"
+ t.datetime "last_sign_in_at"
+ t.string "current_sign_in_ip"
+ t.string "last_sign_in_ip"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.string "name"
+ t.boolean "admin", default: false, null: false
+ t.integer "projects_limit", null: false
+ t.string "skype", default: "", null: false
+ t.string "linkedin", default: "", null: false
+ t.string "twitter", default: "", null: false
+ t.string "bio"
+ t.integer "failed_attempts", default: 0
+ t.datetime "locked_at"
+ t.string "username"
+ t.boolean "can_create_group", default: true, null: false
+ t.boolean "can_create_team", default: true, null: false
+ t.string "state"
+ t.integer "color_scheme_id", default: 1, null: false
+ t.datetime "password_expires_at"
+ t.integer "created_by_id"
+ t.datetime "last_credential_check_at"
+ t.string "avatar"
+ t.string "confirmation_token"
+ t.datetime "confirmed_at"
+ t.datetime "confirmation_sent_at"
+ t.string "unconfirmed_email"
+ t.boolean "hide_no_ssh_key", default: false
+ t.string "website_url", default: "", null: false
+ t.string "notification_email"
+ t.boolean "hide_no_password", default: false
+ t.boolean "password_automatically_set", default: false
+ t.string "location"
+ t.string "encrypted_otp_secret"
+ t.string "encrypted_otp_secret_iv"
+ t.string "encrypted_otp_secret_salt"
+ t.boolean "otp_required_for_login", default: false, null: false
+ t.text "otp_backup_codes"
+ t.string "public_email", default: "", null: false
+ t.integer "dashboard", default: 0
+ t.integer "project_view", default: 0
+ t.integer "consumed_timestep"
+ t.integer "layout", default: 0
+ t.boolean "hide_project_limit", default: false
+ t.string "unlock_token"
+ t.datetime "otp_grace_period_started_at"
+ t.boolean "external", default: false
+ t.string "incoming_email_token"
+ t.string "organization"
+ t.boolean "require_two_factor_authentication_from_group", default: false, null: false
+ t.integer "two_factor_grace_period", default: 48, null: false
+ t.boolean "ghost"
+ t.date "last_activity_on"
+ t.boolean "notified_of_own_activity"
+ t.string "preferred_language"
+ t.integer "theme_id", limit: 2
+ t.boolean "include_private_contributions"
+ t.string "feed_token"
+ t.integer "accepted_term_id"
+ t.boolean "private_profile"
+ t.string "commit_email"
+ t.index "lower((name)::text)", name: "index_on_users_name_lower"
+ t.index ["accepted_term_id"], name: "index_users_on_accepted_term_id"
+ t.index ["admin"], name: "index_users_on_admin"
+ t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
+ t.index ["created_at"], name: "index_users_on_created_at"
+ t.index ["email"], name: "index_users_on_email", unique: true
+ t.index ["email"], name: "index_users_on_email_trigram", opclass: :gin_trgm_ops, using: :gin
+ t.index ["feed_token"], name: "index_users_on_feed_token"
+ t.index ["ghost"], name: "index_users_on_ghost"
+ t.index ["incoming_email_token"], name: "index_users_on_incoming_email_token"
+ t.index ["name"], name: "index_users_on_name"
+ t.index ["name"], name: "index_users_on_name_trigram", opclass: :gin_trgm_ops, using: :gin
+ t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
+ t.index ["state"], name: "index_users_on_state"
+ t.index ["username"], name: "index_users_on_username"
+ t.index ["username"], name: "index_users_on_username_trigram", opclass: :gin_trgm_ops, using: :gin
+ end
+
+ create_table "users_star_projects", id: :serial, force: :cascade do |t|
+ t.integer "project_id", null: false
+ t.integer "user_id", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.index ["project_id"], name: "index_users_star_projects_on_project_id"
+ t.index ["user_id", "project_id"], name: "index_users_star_projects_on_user_id_and_project_id", unique: true
+ end
+
+ create_table "web_hook_logs", id: :serial, force: :cascade do |t|
+ t.integer "web_hook_id", null: false
+ t.string "trigger"
+ t.string "url"
+ t.text "request_headers"
+ t.text "request_data"
+ t.text "response_headers"
+ t.text "response_body"
+ t.string "response_status"
+ t.float "execution_duration"
+ t.string "internal_error_message"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["created_at", "web_hook_id"], name: "index_web_hook_logs_on_created_at_and_web_hook_id"
+ t.index ["web_hook_id"], name: "index_web_hook_logs_on_web_hook_id"
+ end
+
+ create_table "web_hooks", id: :serial, force: :cascade do |t|
+ t.integer "project_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.string "type", default: "ProjectHook"
+ t.integer "service_id"
+ t.boolean "push_events", default: true, null: false
+ t.boolean "issues_events", default: false, null: false
+ t.boolean "merge_requests_events", default: false, null: false
+ t.boolean "tag_push_events", default: false
+ t.boolean "note_events", default: false, null: false
+ t.boolean "enable_ssl_verification", default: true
+ t.boolean "wiki_page_events", default: false, null: false
+ t.boolean "pipeline_events", default: false, null: false
+ t.boolean "confidential_issues_events", default: false, null: false
+ t.boolean "repository_update_events", default: false, null: false
+ t.boolean "job_events", default: false, null: false
+ t.boolean "confidential_note_events"
+ t.text "push_events_branch_filter"
+ t.string "encrypted_token"
+ t.string "encrypted_token_iv"
+ t.string "encrypted_url"
+ t.string "encrypted_url_iv"
+ t.index ["project_id"], name: "index_web_hooks_on_project_id"
+ t.index ["type"], name: "index_web_hooks_on_type"
+ end
+
+ add_foreign_key "application_settings", "users", column: "usage_stats_set_by_user_id", name: "fk_964370041d", on_delete: :nullify
+ add_foreign_key "badges", "namespaces", column: "group_id", on_delete: :cascade
+ add_foreign_key "badges", "projects", on_delete: :cascade
+ add_foreign_key "board_group_recent_visits", "boards", on_delete: :cascade
+ add_foreign_key "board_group_recent_visits", "namespaces", column: "group_id", on_delete: :cascade
+ add_foreign_key "board_group_recent_visits", "users", on_delete: :cascade
+ add_foreign_key "board_project_recent_visits", "boards", on_delete: :cascade
+ add_foreign_key "board_project_recent_visits", "projects", on_delete: :cascade
+ add_foreign_key "board_project_recent_visits", "users", on_delete: :cascade
+ add_foreign_key "boards", "namespaces", column: "group_id", on_delete: :cascade
+ add_foreign_key "boards", "projects", name: "fk_f15266b5f9", on_delete: :cascade
+ add_foreign_key "chat_teams", "namespaces", on_delete: :cascade
+ add_foreign_key "ci_build_trace_chunks", "ci_builds", column: "build_id", on_delete: :cascade
+ add_foreign_key "ci_build_trace_section_names", "projects", on_delete: :cascade
+ add_foreign_key "ci_build_trace_sections", "ci_build_trace_section_names", column: "section_name_id", name: "fk_264e112c66", on_delete: :cascade
+ add_foreign_key "ci_build_trace_sections", "ci_builds", column: "build_id", name: "fk_4ebe41f502", on_delete: :cascade
+ add_foreign_key "ci_build_trace_sections", "projects", on_delete: :cascade
+ add_foreign_key "ci_builds", "ci_pipelines", column: "auto_canceled_by_id", name: "fk_a2141b1522", on_delete: :nullify
+ add_foreign_key "ci_builds", "ci_pipelines", column: "commit_id", name: "fk_d3130c9a7f", on_delete: :cascade
+ add_foreign_key "ci_builds", "ci_stages", column: "stage_id", name: "fk_3a9eaa254d", on_delete: :cascade
+ add_foreign_key "ci_builds", "projects", name: "fk_befce0568a", on_delete: :cascade
+ add_foreign_key "ci_builds_metadata", "ci_builds", column: "build_id", on_delete: :cascade
+ add_foreign_key "ci_builds_metadata", "projects", on_delete: :cascade
+ add_foreign_key "ci_builds_runner_session", "ci_builds", column: "build_id", on_delete: :cascade
+ add_foreign_key "ci_group_variables", "namespaces", column: "group_id", name: "fk_33ae4d58d8", on_delete: :cascade
+ add_foreign_key "ci_job_artifacts", "ci_builds", column: "job_id", on_delete: :cascade
+ add_foreign_key "ci_job_artifacts", "projects", on_delete: :cascade
+ add_foreign_key "ci_pipeline_chat_data", "chat_names", on_delete: :cascade
+ add_foreign_key "ci_pipeline_chat_data", "ci_pipelines", column: "pipeline_id", on_delete: :cascade
+ add_foreign_key "ci_pipeline_schedule_variables", "ci_pipeline_schedules", column: "pipeline_schedule_id", name: "fk_41c35fda51", on_delete: :cascade
+ add_foreign_key "ci_pipeline_schedules", "projects", name: "fk_8ead60fcc4", on_delete: :cascade
+ add_foreign_key "ci_pipeline_schedules", "users", column: "owner_id", name: "fk_9ea99f58d2", on_delete: :nullify
+ add_foreign_key "ci_pipeline_variables", "ci_pipelines", column: "pipeline_id", name: "fk_f29c5f4380", on_delete: :cascade
+ add_foreign_key "ci_pipelines", "ci_pipeline_schedules", column: "pipeline_schedule_id", name: "fk_3d34ab2e06", on_delete: :nullify
+ add_foreign_key "ci_pipelines", "ci_pipelines", column: "auto_canceled_by_id", name: "fk_262d4c2d19", on_delete: :nullify
+ add_foreign_key "ci_pipelines", "merge_requests", name: "fk_a23be95014", on_delete: :cascade
+ add_foreign_key "ci_pipelines", "projects", name: "fk_86635dbd80", on_delete: :cascade
+ add_foreign_key "ci_runner_namespaces", "ci_runners", column: "runner_id", on_delete: :cascade
+ add_foreign_key "ci_runner_namespaces", "namespaces", on_delete: :cascade
+ add_foreign_key "ci_runner_projects", "projects", name: "fk_4478a6f1e4", on_delete: :cascade
+ add_foreign_key "ci_stages", "ci_pipelines", column: "pipeline_id", name: "fk_fb57e6cc56", on_delete: :cascade
+ add_foreign_key "ci_stages", "projects", name: "fk_2360681d1d", on_delete: :cascade
+ add_foreign_key "ci_trigger_requests", "ci_triggers", column: "trigger_id", name: "fk_b8ec8b7245", on_delete: :cascade
+ add_foreign_key "ci_triggers", "projects", name: "fk_e3e63f966e", on_delete: :cascade
+ add_foreign_key "ci_triggers", "users", column: "owner_id", name: "fk_e8e10d1964", on_delete: :cascade
+ add_foreign_key "ci_variables", "projects", name: "fk_ada5eb64b3", on_delete: :cascade
+ add_foreign_key "cluster_groups", "clusters", on_delete: :cascade
+ add_foreign_key "cluster_groups", "namespaces", column: "group_id", on_delete: :cascade
+ add_foreign_key "cluster_platforms_kubernetes", "clusters", on_delete: :cascade
+ add_foreign_key "cluster_projects", "clusters", on_delete: :cascade
+ add_foreign_key "cluster_projects", "projects", on_delete: :cascade
+ add_foreign_key "cluster_providers_gcp", "clusters", on_delete: :cascade
+ add_foreign_key "clusters", "users", on_delete: :nullify
+ add_foreign_key "clusters_applications_cert_managers", "clusters", on_delete: :cascade
+ add_foreign_key "clusters_applications_helm", "clusters", on_delete: :cascade
+ add_foreign_key "clusters_applications_ingress", "clusters", on_delete: :cascade
+ add_foreign_key "clusters_applications_jupyter", "clusters", on_delete: :cascade
+ add_foreign_key "clusters_applications_jupyter", "oauth_applications", on_delete: :nullify
+ add_foreign_key "clusters_applications_knative", "clusters", on_delete: :cascade
+ add_foreign_key "clusters_applications_prometheus", "clusters", on_delete: :cascade
+ add_foreign_key "clusters_applications_runners", "ci_runners", column: "runner_id", name: "fk_02de2ded36", on_delete: :nullify
+ add_foreign_key "clusters_applications_runners", "clusters", on_delete: :cascade
+ add_foreign_key "clusters_kubernetes_namespaces", "cluster_projects", on_delete: :nullify
+ add_foreign_key "clusters_kubernetes_namespaces", "clusters", on_delete: :cascade
+ add_foreign_key "clusters_kubernetes_namespaces", "projects", on_delete: :nullify
+ add_foreign_key "container_repositories", "projects"
+ add_foreign_key "deploy_keys_projects", "projects", name: "fk_58a901ca7e", on_delete: :cascade
+ add_foreign_key "deployments", "projects", name: "fk_b9a3851b82", on_delete: :cascade
+ add_foreign_key "environments", "projects", name: "fk_d1c8c1da6a", on_delete: :cascade
+ add_foreign_key "events", "projects", on_delete: :cascade
+ add_foreign_key "events", "users", column: "author_id", name: "fk_edfd187b6f", on_delete: :cascade
+ add_foreign_key "fork_network_members", "fork_networks", on_delete: :cascade
+ add_foreign_key "fork_network_members", "projects", column: "forked_from_project_id", name: "fk_b01280dae4", on_delete: :nullify
+ add_foreign_key "fork_network_members", "projects", on_delete: :cascade
+ add_foreign_key "fork_networks", "projects", column: "root_project_id", name: "fk_e7b436b2b5", on_delete: :nullify
+ add_foreign_key "forked_project_links", "projects", column: "forked_to_project_id", name: "fk_434510edb0", on_delete: :cascade
+ add_foreign_key "gpg_key_subkeys", "gpg_keys", on_delete: :cascade
+ add_foreign_key "gpg_keys", "users", on_delete: :cascade
+ add_foreign_key "gpg_signatures", "gpg_key_subkeys", on_delete: :nullify
+ add_foreign_key "gpg_signatures", "gpg_keys", on_delete: :nullify
+ add_foreign_key "gpg_signatures", "projects", on_delete: :cascade
+ add_foreign_key "group_custom_attributes", "namespaces", column: "group_id", on_delete: :cascade
+ add_foreign_key "group_group_links", "namespaces", column: "shared_group_id", on_delete: :cascade
+ add_foreign_key "group_group_links", "namespaces", column: "shared_with_group_id", on_delete: :cascade
+ add_foreign_key "import_export_uploads", "projects", on_delete: :cascade
+ add_foreign_key "internal_ids", "namespaces", name: "fk_162941d509", on_delete: :cascade
+ add_foreign_key "internal_ids", "projects", on_delete: :cascade
+ add_foreign_key "issue_assignees", "issues", name: "fk_b7d881734a", on_delete: :cascade
+ add_foreign_key "issue_assignees", "users", name: "fk_5e0c8d9154", on_delete: :cascade
+ add_foreign_key "issue_metrics", "issues", on_delete: :cascade
+ add_foreign_key "issues", "issues", column: "moved_to_id", name: "fk_a194299be1", on_delete: :nullify
+ add_foreign_key "issues", "milestones", name: "fk_96b1dd429c", on_delete: :nullify
+ add_foreign_key "issues", "projects", name: "fk_899c8f3231", on_delete: :cascade
+ add_foreign_key "issues", "users", column: "author_id", name: "fk_05f1e72feb", on_delete: :nullify
+ add_foreign_key "issues", "users", column: "closed_by_id", name: "fk_c63cbf6c25", on_delete: :nullify
+ add_foreign_key "issues", "users", column: "updated_by_id", name: "fk_ffed080f01", on_delete: :nullify
+ add_foreign_key "label_priorities", "labels", on_delete: :cascade
+ add_foreign_key "label_priorities", "projects", on_delete: :cascade
+ add_foreign_key "labels", "namespaces", column: "group_id", on_delete: :cascade
+ add_foreign_key "labels", "projects", name: "fk_7de4989a69", on_delete: :cascade
+ add_foreign_key "lfs_file_locks", "projects", on_delete: :cascade
+ add_foreign_key "lfs_file_locks", "users", on_delete: :cascade
+ add_foreign_key "lists", "boards", name: "fk_0d3f677137", on_delete: :cascade
+ add_foreign_key "lists", "labels", name: "fk_7a5553d60f", on_delete: :cascade
+ add_foreign_key "members", "users", name: "fk_2e88fb7ce9", on_delete: :cascade
+ add_foreign_key "merge_request_diff_commits", "merge_request_diffs", on_delete: :cascade
+ add_foreign_key "merge_request_diff_files", "merge_request_diffs", on_delete: :cascade
+ add_foreign_key "merge_request_diffs", "merge_requests", name: "fk_8483f3258f", on_delete: :cascade
+ add_foreign_key "merge_request_metrics", "ci_pipelines", column: "pipeline_id", on_delete: :cascade
+ add_foreign_key "merge_request_metrics", "merge_requests", on_delete: :cascade
+ add_foreign_key "merge_request_metrics", "users", column: "latest_closed_by_id", name: "fk_ae440388cc", on_delete: :nullify
+ add_foreign_key "merge_request_metrics", "users", column: "merged_by_id", name: "fk_7f28d925f3", on_delete: :nullify
+ add_foreign_key "merge_requests", "ci_pipelines", column: "head_pipeline_id", name: "fk_fd82eae0b9", on_delete: :nullify
+ add_foreign_key "merge_requests", "merge_request_diffs", column: "latest_merge_request_diff_id", name: "fk_06067f5644", on_delete: :nullify
+ add_foreign_key "merge_requests", "milestones", name: "fk_6a5165a692", on_delete: :nullify
+ add_foreign_key "merge_requests", "projects", column: "source_project_id", name: "fk_3308fe130c", on_delete: :nullify
+ add_foreign_key "merge_requests", "projects", column: "target_project_id", name: "fk_a6963e8447", on_delete: :cascade
+ add_foreign_key "merge_requests", "users", column: "assignee_id", name: "fk_6149611a04", on_delete: :nullify
+ add_foreign_key "merge_requests", "users", column: "author_id", name: "fk_e719a85f8a", on_delete: :nullify
+ add_foreign_key "merge_requests", "users", column: "merge_user_id", name: "fk_ad525e1f87", on_delete: :nullify
+ add_foreign_key "merge_requests", "users", column: "updated_by_id", name: "fk_641731faff", on_delete: :nullify
+ add_foreign_key "merge_requests_closing_issues", "issues", on_delete: :cascade
+ add_foreign_key "merge_requests_closing_issues", "merge_requests", on_delete: :cascade
+ add_foreign_key "milestones", "namespaces", column: "group_id", name: "fk_95650a40d4", on_delete: :cascade
+ add_foreign_key "milestones", "projects", name: "fk_9bd0a0c791", on_delete: :cascade
+ add_foreign_key "note_diff_files", "notes", column: "diff_note_id", on_delete: :cascade
+ add_foreign_key "notes", "projects", name: "fk_99e097b079", on_delete: :cascade
+ add_foreign_key "notification_settings", "users", name: "fk_0c95e91db7", on_delete: :cascade
+ add_foreign_key "oauth_openid_requests", "oauth_access_grants", column: "access_grant_id", name: "fk_oauth_openid_requests_oauth_access_grants_access_grant_id"
+ add_foreign_key "pages_domains", "projects", name: "fk_ea2f6dfc6f", on_delete: :cascade
+ add_foreign_key "personal_access_tokens", "users"
+ add_foreign_key "pool_repositories", "projects", column: "source_project_id", on_delete: :nullify
+ add_foreign_key "pool_repositories", "shards", on_delete: :restrict
+ add_foreign_key "project_authorizations", "projects", on_delete: :cascade
+ add_foreign_key "project_authorizations", "users", on_delete: :cascade
+ add_foreign_key "project_auto_devops", "projects", on_delete: :cascade
+ add_foreign_key "project_ci_cd_settings", "projects", name: "fk_24c15d2f2e", on_delete: :cascade
+ add_foreign_key "project_custom_attributes", "projects", on_delete: :cascade
+ add_foreign_key "project_daily_statistics", "projects", on_delete: :cascade
+ add_foreign_key "project_deploy_tokens", "deploy_tokens", on_delete: :cascade
+ add_foreign_key "project_deploy_tokens", "projects", on_delete: :cascade
+ add_foreign_key "project_error_tracking_settings", "projects", on_delete: :cascade
+ add_foreign_key "project_features", "projects", name: "fk_18513d9b92", on_delete: :cascade
+ add_foreign_key "project_group_links", "projects", name: "fk_daa8cee94c", on_delete: :cascade
+ add_foreign_key "project_import_data", "projects", name: "fk_ffb9ee3a10", on_delete: :cascade
+ add_foreign_key "project_mirror_data", "projects", on_delete: :cascade
+ add_foreign_key "project_repositories", "projects", on_delete: :cascade
+ add_foreign_key "project_repositories", "shards", on_delete: :restrict
+ add_foreign_key "project_statistics", "projects", on_delete: :cascade
+ add_foreign_key "projects", "pool_repositories", name: "fk_6e5c14658a", on_delete: :nullify
+ add_foreign_key "prometheus_metrics", "projects", on_delete: :cascade
+ add_foreign_key "protected_branch_merge_access_levels", "protected_branches", name: "fk_8a3072ccb3", on_delete: :cascade
+ add_foreign_key "protected_branch_push_access_levels", "protected_branches", name: "fk_9ffc86a3d9", on_delete: :cascade
+ add_foreign_key "protected_branches", "projects", name: "fk_7a9c6d93e7", on_delete: :cascade
+ add_foreign_key "protected_tag_create_access_levels", "namespaces", column: "group_id"
+ add_foreign_key "protected_tag_create_access_levels", "protected_tags", name: "fk_f7dfda8c51", on_delete: :cascade
+ add_foreign_key "protected_tag_create_access_levels", "users"
+ add_foreign_key "protected_tags", "projects", name: "fk_8e4af87648", on_delete: :cascade
+ add_foreign_key "push_event_payloads", "events", name: "fk_36c74129da", on_delete: :cascade
+ add_foreign_key "release_links", "releases", on_delete: :cascade
+ add_foreign_key "releases", "projects", name: "fk_47fe2a0596", on_delete: :cascade
+ add_foreign_key "releases", "users", column: "author_id", name: "fk_8e4456f90f", on_delete: :nullify
+ add_foreign_key "remote_mirrors", "projects", on_delete: :cascade
+ add_foreign_key "repository_languages", "projects", on_delete: :cascade
+ add_foreign_key "resource_label_events", "issues", on_delete: :cascade
+ add_foreign_key "resource_label_events", "labels", on_delete: :nullify
+ add_foreign_key "resource_label_events", "merge_requests", on_delete: :cascade
+ add_foreign_key "resource_label_events", "users", on_delete: :nullify
+ add_foreign_key "services", "projects", name: "fk_71cce407f9", on_delete: :cascade
+ add_foreign_key "snippets", "projects", name: "fk_be41fd4bb7", on_delete: :cascade
+ add_foreign_key "subscriptions", "projects", on_delete: :cascade
+ add_foreign_key "suggestions", "notes", on_delete: :cascade
+ add_foreign_key "system_note_metadata", "notes", name: "fk_d83a918cb1", on_delete: :cascade
+ add_foreign_key "term_agreements", "application_setting_terms", column: "term_id"
+ add_foreign_key "term_agreements", "users", on_delete: :cascade
+ add_foreign_key "timelogs", "issues", name: "fk_timelogs_issues_issue_id", on_delete: :cascade
+ add_foreign_key "timelogs", "merge_requests", name: "fk_timelogs_merge_requests_merge_request_id", on_delete: :cascade
+ add_foreign_key "todos", "namespaces", column: "group_id", name: "fk_a27c483435", on_delete: :cascade
+ add_foreign_key "todos", "notes", name: "fk_91d1f47b13", on_delete: :cascade
+ add_foreign_key "todos", "projects", name: "fk_45054f9c45", on_delete: :cascade
+ add_foreign_key "todos", "users", column: "author_id", name: "fk_ccf0373936", on_delete: :cascade
+ add_foreign_key "todos", "users", name: "fk_d94154aa95", on_delete: :cascade
+ add_foreign_key "trending_projects", "projects", on_delete: :cascade
+ add_foreign_key "u2f_registrations", "users"
+ add_foreign_key "user_callouts", "users", on_delete: :cascade
+ add_foreign_key "user_custom_attributes", "users", on_delete: :cascade
+ add_foreign_key "user_interacted_projects", "projects", on_delete: :cascade
+ add_foreign_key "user_interacted_projects", "users", on_delete: :cascade
+ add_foreign_key "user_preferences", "users", on_delete: :cascade
+ add_foreign_key "user_statuses", "users", on_delete: :cascade
+ add_foreign_key "user_synced_attributes_metadata", "users", on_delete: :cascade
+ add_foreign_key "users", "application_setting_terms", column: "accepted_term_id", name: "fk_789cd90b35", on_delete: :cascade
+ add_foreign_key "users_star_projects", "projects", name: "fk_22cd27ddfc", on_delete: :cascade
+ add_foreign_key "web_hook_logs", "web_hooks", on_delete: :cascade
+ add_foreign_key "web_hooks", "projects", name: "fk_0c8ca6d9d1", on_delete: :cascade
+ end
+
+ def down
+ raise ActiveRecord::IrreversibleMigration, "The initial migration is not revertable"
+ end
+end
+
+# rubocop:enable Metrics/AbcSize
+# rubocop:enable Migration/AddConcurrentForeignKey
+# rubocop:enable Style/WordArray
+# rubocop:enable Migration/PreventStrings
+# rubocop:enable Migration/AddLimitToTextColumns
+# rubocop:enable Migration/Datetime
diff --git a/db/migrate/20190315191339_create_merge_request_assignees_table.rb b/db/migrate/20190315191339_create_merge_request_assignees_table.rb
index 6fc4463f281..dbd9ea3e35b 100644
--- a/db/migrate/20190315191339_create_merge_request_assignees_table.rb
+++ b/db/migrate/20190315191339_create_merge_request_assignees_table.rb
@@ -17,6 +17,8 @@ class CreateMergeRequestAssigneesTable < ActiveRecord::Migration[5.0]
end
def down
+ # rubocop:disable Migration/DropTable
drop_table :merge_request_assignees
+ # rubocop:enable Migration/DropTable
end
end
diff --git a/db/migrate/20190402150158_backport_enterprise_schema.rb b/db/migrate/20190402150158_backport_enterprise_schema.rb
index 694c0feba0a..912da09af9d 100644
--- a/db/migrate/20190402150158_backport_enterprise_schema.rb
+++ b/db/migrate/20190402150158_backport_enterprise_schema.rb
@@ -193,7 +193,9 @@ class BackportEnterpriseSchema < ActiveRecord::Migration[5.0]
end
def drop_table_if_exists(table)
+ # rubocop:disable Migration/DropTable
drop_table(table) if table_exists?(table)
+ # rubocop:enable Migration/DropTable
end
def add_column_with_default_if_not_exists(table, name, *args)
diff --git a/db/migrate/20190722144316_create_milestone_releases_table.rb b/db/migrate/20190722144316_create_milestone_releases_table.rb
index 55878bcec41..911ca941a56 100644
--- a/db/migrate/20190722144316_create_milestone_releases_table.rb
+++ b/db/migrate/20190722144316_create_milestone_releases_table.rb
@@ -15,6 +15,8 @@ class CreateMilestoneReleasesTable < ActiveRecord::Migration[5.2]
end
def down
+ # rubocop:disable Migration/DropTable
drop_table :milestone_releases
+ # rubocop:enable Migration/DropTable
end
end
diff --git a/db/migrate/20190927055500_create_description_versions.rb b/db/migrate/20190927055500_create_description_versions.rb
index b3082533a6f..9046ebbc499 100644
--- a/db/migrate/20190927055500_create_description_versions.rb
+++ b/db/migrate/20190927055500_create_description_versions.rb
@@ -24,6 +24,8 @@ class CreateDescriptionVersions < ActiveRecord::Migration[5.2]
def down
remove_column :system_note_metadata, :description_version_id
+ # rubocop:disable Migration/DropTable
drop_table :description_versions
+ # rubocop:enable Migration/DropTable
end
end
diff --git a/db/migrate/20191118053631_add_group_deletion_schedules.rb b/db/migrate/20191118053631_add_group_deletion_schedules.rb
index 6f3ed27e156..bc18480e5b9 100644
--- a/db/migrate/20191118053631_add_group_deletion_schedules.rb
+++ b/db/migrate/20191118053631_add_group_deletion_schedules.rb
@@ -23,6 +23,8 @@ class AddGroupDeletionSchedules < ActiveRecord::Migration[5.2]
end
def down
+ # rubocop:disable Migration/DropTable
drop_table :group_deletion_schedules
+ # rubocop:enable Migration/DropTable
end
end
diff --git a/db/migrate/20191127151619_create_gitlab_subscription_histories.rb b/db/migrate/20191127151619_create_gitlab_subscription_histories.rb
index 718f2c1b313..db2617112a3 100644
--- a/db/migrate/20191127151619_create_gitlab_subscription_histories.rb
+++ b/db/migrate/20191127151619_create_gitlab_subscription_histories.rb
@@ -23,6 +23,8 @@ class CreateGitlabSubscriptionHistories < ActiveRecord::Migration[5.2]
end
def down
+ # rubocop:disable Migration/DropTable
drop_table :gitlab_subscription_histories
+ # rubocop:enable Migration/DropTable
end
end
diff --git a/db/migrate/20200123091622_drop_analytics_repository_files_table.rb b/db/migrate/20200123091622_drop_analytics_repository_files_table.rb
index aa31d23920a..ed6746165a8 100644
--- a/db/migrate/20200123091622_drop_analytics_repository_files_table.rb
+++ b/db/migrate/20200123091622_drop_analytics_repository_files_table.rb
@@ -7,7 +7,9 @@ class DropAnalyticsRepositoryFilesTable < ActiveRecord::Migration[5.2]
def up
# Requires ExclusiveLock on the table. Not in use, no records, no FKs.
+ # rubocop:disable Migration/DropTable
drop_table :analytics_repository_files
+ # rubocop:enable Migration/DropTable
end
def down
diff --git a/db/migrate/20200123091734_drop_analytics_repository_file_commits_table.rb b/db/migrate/20200123091734_drop_analytics_repository_file_commits_table.rb
index 2d3c1c9a817..2eb10a9056d 100644
--- a/db/migrate/20200123091734_drop_analytics_repository_file_commits_table.rb
+++ b/db/migrate/20200123091734_drop_analytics_repository_file_commits_table.rb
@@ -7,7 +7,9 @@ class DropAnalyticsRepositoryFileCommitsTable < ActiveRecord::Migration[5.2]
def up
# Requires ExclusiveLock on the table. Not in use, no records, no FKs.
+ # rubocop:disable Migration/DropTable
drop_table :analytics_repository_file_commits
+ # rubocop:enable Migration/DropTable
end
def down
diff --git a/db/migrate/20200123091854_drop_analytics_repository_file_edits_table.rb b/db/migrate/20200123091854_drop_analytics_repository_file_edits_table.rb
index 59bf2dbdca3..e4bdb6f6ec2 100644
--- a/db/migrate/20200123091854_drop_analytics_repository_file_edits_table.rb
+++ b/db/migrate/20200123091854_drop_analytics_repository_file_edits_table.rb
@@ -7,7 +7,9 @@ class DropAnalyticsRepositoryFileEditsTable < ActiveRecord::Migration[5.2]
def up
# Requires ExclusiveLock on the table. Not in use, no records, no FKs.
+ # rubocop:disable Migration/DropTable
drop_table :analytics_repository_file_edits if table_exists?(:analytics_repository_file_edits) # this table might be already dropped on development environment
+ # rubocop:enable Migration/DropTable
end
def down
diff --git a/db/migrate/20200214025454_add_canonical_emails.rb b/db/migrate/20200214025454_add_canonical_emails.rb
index 0732d39169d..70ab7208ade 100644
--- a/db/migrate/20200214025454_add_canonical_emails.rb
+++ b/db/migrate/20200214025454_add_canonical_emails.rb
@@ -20,7 +20,9 @@ class AddCanonicalEmails < ActiveRecord::Migration[6.0]
def down
with_lock_retries do
+ # rubocop:disable Migration/DropTable
drop_table(:user_canonical_emails)
+ # rubocop:enable Migration/DropTable
end
end
end
diff --git a/db/migrate/20200215225103_drop_forked_project_links_table.rb b/db/migrate/20200215225103_drop_forked_project_links_table.rb
index 9c028d23dbc..6acced2c734 100644
--- a/db/migrate/20200215225103_drop_forked_project_links_table.rb
+++ b/db/migrate/20200215225103_drop_forked_project_links_table.rb
@@ -8,6 +8,7 @@ class DropForkedProjectLinksTable < ActiveRecord::Migration[6.0]
DOWNTIME = false
def change
+ # rubocop:disable Migration/DropTable
drop_table "forked_project_links", id: :serial do |t|
t.integer "forked_to_project_id", null: false
t.integer "forked_from_project_id", null: false
@@ -15,5 +16,6 @@ class DropForkedProjectLinksTable < ActiveRecord::Migration[6.0]
t.datetime "updated_at"
t.index ["forked_to_project_id"], name: "index_forked_project_links_on_forked_to_project_id", unique: true
end
+ # rubocop:enable Migration/DropTable
end
end
diff --git a/db/migrate/20200227165129_create_user_details.rb b/db/migrate/20200227165129_create_user_details.rb
index 89258eadb9f..474dc357266 100644
--- a/db/migrate/20200227165129_create_user_details.rb
+++ b/db/migrate/20200227165129_create_user_details.rb
@@ -20,7 +20,9 @@ class CreateUserDetails < ActiveRecord::Migration[6.0]
def down
with_lock_retries do
+ # rubocop:disable Migration/DropTable
drop_table :user_details
+ # rubocop:enable Migration/DropTable
end
end
end
diff --git a/db/migrate/20200306160521_add_index_on_author_id_and_created_at_to_events.rb b/db/migrate/20200306160521_add_index_on_author_id_and_created_at_to_events.rb
index 3328a14bb65..2f7c16b3f20 100644
--- a/db/migrate/20200306160521_add_index_on_author_id_and_created_at_to_events.rb
+++ b/db/migrate/20200306160521_add_index_on_author_id_and_created_at_to_events.rb
@@ -4,14 +4,15 @@ class AddIndexOnAuthorIdAndCreatedAtToEvents < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
+ INDEX_NAME = 'index_events_on_author_id_and_created_at'
disable_ddl_transaction!
def up
- add_concurrent_index :events, [:author_id, :created_at]
+ add_concurrent_index :events, [:author_id, :created_at], name: INDEX_NAME
end
def down
- remove_concurrent_index :events, [:author_id, :created_at]
+ remove_concurrent_index :events, INDEX_NAME
end
end
diff --git a/db/migrate/20200311093210_create_user_highest_roles.rb b/db/migrate/20200311093210_create_user_highest_roles.rb
index 36007f196d1..df2b02b7d91 100644
--- a/db/migrate/20200311093210_create_user_highest_roles.rb
+++ b/db/migrate/20200311093210_create_user_highest_roles.rb
@@ -19,7 +19,9 @@ class CreateUserHighestRoles < ActiveRecord::Migration[6.0]
def down
with_lock_retries do
+ # rubocop:disable Migration/DropTable
drop_table :user_highest_roles
+ # rubocop:enable Migration/DropTable
end
end
end
diff --git a/db/migrate/20200325094612_add_allow_merge_on_skipped_pipeline_to_project_settings.rb b/db/migrate/20200325094612_add_allow_merge_on_skipped_pipeline_to_project_settings.rb
new file mode 100644
index 00000000000..8575dd2f080
--- /dev/null
+++ b/db/migrate/20200325094612_add_allow_merge_on_skipped_pipeline_to_project_settings.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddAllowMergeOnSkippedPipelineToProjectSettings < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def change
+ add_column :project_settings, :allow_merge_on_skipped_pipeline, :boolean
+ end
+end
diff --git a/db/migrate/20200326122700_create_diff_note_positions.rb b/db/migrate/20200326122700_create_diff_note_positions.rb
index d37f7fef078..6c558516471 100644
--- a/db/migrate/20200326122700_create_diff_note_positions.rb
+++ b/db/migrate/20200326122700_create_diff_note_positions.rb
@@ -30,6 +30,8 @@ class CreateDiffNotePositions < ActiveRecord::Migration[6.0]
# rubocop:enable Migration/AddLimitToTextColumns
def down
+ # rubocop:disable Migration/DropTable
drop_table :diff_note_positions
+ # rubocop:enable Migration/DropTable
end
end
diff --git a/db/migrate/20200330203826_drop_fk_in_ci_ref.rb b/db/migrate/20200330203826_drop_fk_in_ci_ref.rb
new file mode 100644
index 00000000000..08cb4aaddab
--- /dev/null
+++ b/db/migrate/20200330203826_drop_fk_in_ci_ref.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+class DropFkInCiRef < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ remove_foreign_key_if_exists :ci_refs, column: :project_id
+ end
+ with_lock_retries do
+ remove_foreign_key_if_exists :ci_refs, column: :last_updated_by_pipeline_id
+ end
+ end
+
+ def down
+ add_foreign_key_if_not_exists :ci_refs, :projects, column: :project_id, on_delete: :cascade
+ add_foreign_key_if_not_exists :ci_refs, :ci_pipelines, column: :last_updated_by_pipeline_id, on_delete: :nullify
+ end
+
+ private
+
+ def add_foreign_key_if_not_exists(source, target, column:, on_delete:)
+ return unless table_exists?(source)
+ return if foreign_key_exists?(source, target, column: column)
+
+ add_concurrent_foreign_key(source, target, column: column, on_delete: on_delete)
+ end
+end
diff --git a/db/migrate/20200330203837_recreate_ci_ref.rb b/db/migrate/20200330203837_recreate_ci_ref.rb
new file mode 100644
index 00000000000..5a7bede4dc8
--- /dev/null
+++ b/db/migrate/20200330203837_recreate_ci_ref.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+class RecreateCiRef < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ UNKNOWN_STATUS = 0
+
+ def up
+ with_lock_retries do
+ # rubocop:disable Migration/DropTable
+ drop_table :ci_refs
+ # rubocop:enable Migration/DropTable
+
+ create_table :ci_refs do |t|
+ t.references :project, null: false, index: false, foreign_key: { on_delete: :cascade }, type: :bigint
+ t.integer :lock_version, null: false, default: 0
+ t.integer :status, null: false, limit: 2, default: UNKNOWN_STATUS
+ t.text :ref_path, null: false # rubocop: disable Migration/AddLimitToTextColumns
+ t.index [:project_id, :ref_path], unique: true
+ end
+ end
+ end
+
+ def down
+ with_lock_retries do
+ # rubocop:disable Migration/DropTable
+ drop_table :ci_refs
+ # rubocop:enable Migration/DropTable
+
+ create_table :ci_refs do |t|
+ t.references :project, null: false, index: false, foreign_key: { on_delete: :cascade }, type: :integer
+ t.integer :lock_version, default: 0
+ t.integer :last_updated_by_pipeline_id
+ t.boolean :tag, default: false, null: false
+ t.string :ref, null: false, limit: 255
+ t.string :status, null: false, limit: 255
+ t.foreign_key :ci_pipelines, column: :last_updated_by_pipeline_id, on_delete: :nullify
+ t.index [:project_id, :ref, :tag], unique: true
+ t.index [:last_updated_by_pipeline_id]
+ end
+ end
+ end
+end
diff --git a/db/migrate/20200331103637_add_ci_ref_id_to_ci_pipelines.rb b/db/migrate/20200331103637_add_ci_ref_id_to_ci_pipelines.rb
new file mode 100644
index 00000000000..9f2780670dc
--- /dev/null
+++ b/db/migrate/20200331103637_add_ci_ref_id_to_ci_pipelines.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddCiRefIdToCiPipelines < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ with_lock_retries do
+ add_column :ci_pipelines, :ci_ref_id, :bigint
+ end
+ end
+
+ def down
+ with_lock_retries do
+ remove_column :ci_pipelines, :ci_ref_id, :bigint
+ end
+ end
+end
diff --git a/db/migrate/20200331113728_add_index_to_ci_ref_id.rb b/db/migrate/20200331113728_add_index_to_ci_ref_id.rb
new file mode 100644
index 00000000000..d3495fd4fa1
--- /dev/null
+++ b/db/migrate/20200331113728_add_index_to_ci_ref_id.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class AddIndexToCiRefId < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :ci_pipelines, [:ci_ref_id], where: 'ci_ref_id IS NOT NULL'
+ end
+
+ def down
+ remove_concurrent_index :ci_pipelines, [:ci_ref_id], where: 'ci_ref_id IS NOT NULL'
+ end
+end
diff --git a/db/migrate/20200331113738_add_fk_to_ci_ref_id.rb b/db/migrate/20200331113738_add_fk_to_ci_ref_id.rb
new file mode 100644
index 00000000000..1a7a76904b1
--- /dev/null
+++ b/db/migrate/20200331113738_add_fk_to_ci_ref_id.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class AddFkToCiRefId < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_foreign_key :ci_pipelines, :ci_refs, column: :ci_ref_id, on_delete: :nullify
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key_if_exists :ci_pipelines, column: :ci_ref_id
+ end
+ end
+end
diff --git a/db/migrate/20200331132103_add_project_compliance_framework_settings_table.rb b/db/migrate/20200331132103_add_project_compliance_framework_settings_table.rb
index 6af8c6db939..169c8602cab 100644
--- a/db/migrate/20200331132103_add_project_compliance_framework_settings_table.rb
+++ b/db/migrate/20200331132103_add_project_compliance_framework_settings_table.rb
@@ -16,7 +16,9 @@ class AddProjectComplianceFrameworkSettingsTable < ActiveRecord::Migration[6.0]
def down
with_lock_retries do
+ # rubocop:disable Migration/DropTable
drop_table :project_compliance_framework_settings
+ # rubocop:enable Migration/DropTable
end
end
end
diff --git a/db/migrate/20200407182205_create_partitioned_foreign_keys.rb b/db/migrate/20200407182205_create_partitioned_foreign_keys.rb
index aca8116d2dd..59e7d88b238 100644
--- a/db/migrate/20200407182205_create_partitioned_foreign_keys.rb
+++ b/db/migrate/20200407182205_create_partitioned_foreign_keys.rb
@@ -26,6 +26,8 @@ class CreatePartitionedForeignKeys < ActiveRecord::Migration[6.0]
end
def down
+ # rubocop:disable Migration/DropTable
drop_table :partitioned_foreign_keys
+ # rubocop:enable Migration/DropTable
end
end
diff --git a/db/migrate/20200407222647_create_project_repository_storage_moves.rb b/db/migrate/20200407222647_create_project_repository_storage_moves.rb
index 402a1cdd4a6..98e44aa2fc6 100644
--- a/db/migrate/20200407222647_create_project_repository_storage_moves.rb
+++ b/db/migrate/20200407222647_create_project_repository_storage_moves.rb
@@ -26,6 +26,8 @@ class CreateProjectRepositoryStorageMoves < ActiveRecord::Migration[6.0]
remove_check_constraint(:project_repository_storage_moves, 'project_repository_storage_moves_source_storage_name')
remove_check_constraint(:project_repository_storage_moves, 'project_repository_storage_moves_destination_storage_name')
+ # rubocop:disable Migration/DropTable
drop_table :project_repository_storage_moves
+ # rubocop:enable Migration/DropTable
end
end
diff --git a/db/migrate/20200408125046_create_ci_freeze_periods.rb b/db/migrate/20200408125046_create_ci_freeze_periods.rb
index 42a385150b8..98f0e20b11b 100644
--- a/db/migrate/20200408125046_create_ci_freeze_periods.rb
+++ b/db/migrate/20200408125046_create_ci_freeze_periods.rb
@@ -25,6 +25,8 @@ class CreateCiFreezePeriods < ActiveRecord::Migration[6.0]
end
def down
+ # rubocop:disable Migration/DropTable
drop_table :ci_freeze_periods
+ # rubocop:enable Migration/DropTable
end
end
diff --git a/db/migrate/20200416005331_create_status_page_published_incidents.rb b/db/migrate/20200416005331_create_status_page_published_incidents.rb
index 75889cd5bb6..ea2ddcde925 100644
--- a/db/migrate/20200416005331_create_status_page_published_incidents.rb
+++ b/db/migrate/20200416005331_create_status_page_published_incidents.rb
@@ -15,6 +15,8 @@ class CreateStatusPagePublishedIncidents < ActiveRecord::Migration[6.0]
end
def down
+ # rubocop:disable Migration/DropTable
drop_table :status_page_published_incidents
+ # rubocop:enable Migration/DropTable
end
end
diff --git a/db/migrate/20200417044453_create_alert_management_alerts.rb b/db/migrate/20200417044453_create_alert_management_alerts.rb
index 6221eeeb24b..3509f4946a7 100644
--- a/db/migrate/20200417044453_create_alert_management_alerts.rb
+++ b/db/migrate/20200417044453_create_alert_management_alerts.rb
@@ -39,6 +39,8 @@ class CreateAlertManagementAlerts < ActiveRecord::Migration[6.0]
end
def down
+ # rubocop:disable Migration/DropTable
drop_table :alert_management_alerts
+ # rubocop:enable Migration/DropTable
end
end
diff --git a/db/migrate/20200420104303_add_group_import_states_table.rb b/db/migrate/20200420104303_add_group_import_states_table.rb
index a44a2ea75f3..10b8cd4aa49 100644
--- a/db/migrate/20200420104303_add_group_import_states_table.rb
+++ b/db/migrate/20200420104303_add_group_import_states_table.rb
@@ -20,6 +20,8 @@ class AddGroupImportStatesTable < ActiveRecord::Migration[6.0]
# rubocop:enable Migration/AddLimitToTextColumns
def down
+ # rubocop:disable Migration/DropTable
drop_table :group_import_states
+ # rubocop:enable Migration/DropTable
end
end
diff --git a/db/migrate/20200420115948_create_metrics_users_starred_dashboard.rb b/db/migrate/20200420115948_create_metrics_users_starred_dashboard.rb
index 27130136e9d..8e9495f3a83 100644
--- a/db/migrate/20200420115948_create_metrics_users_starred_dashboard.rb
+++ b/db/migrate/20200420115948_create_metrics_users_starred_dashboard.rb
@@ -20,6 +20,8 @@ class CreateMetricsUsersStarredDashboard < ActiveRecord::Migration[6.0]
# rubocop: enable Migration/AddLimitToTextColumns
def down
+ # rubocop:disable Migration/DropTable
drop_table :metrics_users_starred_dashboards
+ # rubocop:enable Migration/DropTable
end
end
diff --git a/db/migrate/20200421054930_remove_index_on_pipeline_id_from_ci_pipeline_variables.rb b/db/migrate/20200421054930_remove_index_on_pipeline_id_from_ci_pipeline_variables.rb
new file mode 100644
index 00000000000..1a904188fc6
--- /dev/null
+++ b/db/migrate/20200421054930_remove_index_on_pipeline_id_from_ci_pipeline_variables.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class RemoveIndexOnPipelineIdFromCiPipelineVariables < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ INDEX_NAME = 'index_ci_pipeline_variables_on_pipeline_id'
+
+ disable_ddl_transaction!
+
+ def up
+ remove_concurrent_index_by_name :ci_pipeline_variables, INDEX_NAME
+ end
+
+ def down
+ add_concurrent_index :ci_pipeline_variables, :pipeline_id, name: INDEX_NAME, where: "key = 'AUTO_DEVOPS_MODSECURITY_SEC_RULE_ENGINE'"
+ end
+end
diff --git a/db/migrate/20200421054948_remove_index_on_pipeline_id_from_ci_variables.rb b/db/migrate/20200421054948_remove_index_on_pipeline_id_from_ci_variables.rb
new file mode 100644
index 00000000000..f7e6d10e8a3
--- /dev/null
+++ b/db/migrate/20200421054948_remove_index_on_pipeline_id_from_ci_variables.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class RemoveIndexOnPipelineIdFromCiVariables < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ INDEX_NAME = 'index_ci_variables_on_project_id'
+
+ disable_ddl_transaction!
+
+ def up
+ remove_concurrent_index_by_name :ci_variables, INDEX_NAME
+ end
+
+ def down
+ add_concurrent_index :ci_variables, :project_id, name: INDEX_NAME, where: "key = 'AUTO_DEVOPS_MODSECURITY_SEC_RULE_ENGINE'"
+ end
+end
diff --git a/db/migrate/20200422091541_create_ci_instance_variables.rb b/db/migrate/20200422091541_create_ci_instance_variables.rb
index ab2a4722f89..d1c954b4020 100644
--- a/db/migrate/20200422091541_create_ci_instance_variables.rb
+++ b/db/migrate/20200422091541_create_ci_instance_variables.rb
@@ -26,6 +26,8 @@ class CreateCiInstanceVariables < ActiveRecord::Migration[6.0]
end
def down
+ # rubocop:disable Migration/DropTable
drop_table :ci_instance_variables
+ # rubocop:enable Migration/DropTable
end
end
diff --git a/db/migrate/20200424135319_create_nuget_dependency_link_metadata.rb b/db/migrate/20200424135319_create_nuget_dependency_link_metadata.rb
index 8aa3d98aa80..79adf41f973 100644
--- a/db/migrate/20200424135319_create_nuget_dependency_link_metadata.rb
+++ b/db/migrate/20200424135319_create_nuget_dependency_link_metadata.rb
@@ -7,7 +7,7 @@ class CreateNugetDependencyLinkMetadata < ActiveRecord::Migration[6.0]
disable_ddl_transaction!
- CONSTRAINT_NAME = 'packages_nuget_dependency_link_metadata_target_framework_constraint'
+ CONSTRAINT_NAME = 'packages_nuget_dependency_link_metadata_target_framework_constr'
def up
unless table_exists?(:packages_nuget_dependency_link_metadata)
@@ -21,6 +21,8 @@ class CreateNugetDependencyLinkMetadata < ActiveRecord::Migration[6.0]
end
def down
+ # rubocop:disable Migration/DropTable
drop_table :packages_nuget_dependency_link_metadata
+ # rubocop:enable Migration/DropTable
end
end
diff --git a/db/migrate/20200429023324_add_composer_metadata.rb b/db/migrate/20200429023324_add_composer_metadata.rb
new file mode 100644
index 00000000000..738b630bec1
--- /dev/null
+++ b/db/migrate/20200429023324_add_composer_metadata.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+class AddComposerMetadata < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def change
+ create_table :packages_composer_metadata, id: false do |t|
+ t.references :package, primary_key: true, index: false, default: nil, foreign_key: { to_table: :packages_packages, on_delete: :cascade }, type: :bigint
+ t.binary :target_sha, null: false
+ end
+ end
+end
diff --git a/db/migrate/20200430123614_create_project_access_tokens.rb b/db/migrate/20200430123614_create_project_access_tokens.rb
new file mode 100644
index 00000000000..f07b1875ce0
--- /dev/null
+++ b/db/migrate/20200430123614_create_project_access_tokens.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class CreateProjectAccessTokens < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def change
+ create_table :project_access_tokens, primary_key: [:personal_access_token_id, :project_id] do |t|
+ t.column :personal_access_token_id, :bigint, null: false
+ t.column :project_id, :bigint, null: false
+ end
+
+ add_index :project_access_tokens, :project_id
+ end
+end
diff --git a/db/migrate/20200430130048_create_packages_nuget_metadata.rb b/db/migrate/20200430130048_create_packages_nuget_metadata.rb
index 0f0d490c93d..3c89a143932 100644
--- a/db/migrate/20200430130048_create_packages_nuget_metadata.rb
+++ b/db/migrate/20200430130048_create_packages_nuget_metadata.rb
@@ -29,6 +29,8 @@ class CreatePackagesNugetMetadata < ActiveRecord::Migration[6.0]
end
def down
+ # rubocop:disable Migration/DropTable
drop_table :packages_nuget_metadata
+ # rubocop:enable Migration/DropTable
end
end
diff --git a/db/migrate/20200430174637_create_group_deploy_keys.rb b/db/migrate/20200430174637_create_group_deploy_keys.rb
new file mode 100644
index 00000000000..283c8769a80
--- /dev/null
+++ b/db/migrate/20200430174637_create_group_deploy_keys.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+class CreateGroupDeployKeys < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ unless table_exists?(:group_deploy_keys)
+ with_lock_retries do
+ create_table :group_deploy_keys do |t|
+ t.references :user, foreign_key: { on_delete: :restrict }, index: true
+ t.timestamps_with_timezone
+ t.datetime_with_timezone :last_used_at
+ t.datetime_with_timezone :expires_at
+ t.text :key, null: false, unique: true
+ t.text :title
+ t.text :fingerprint, null: false, unique: true
+ t.binary :fingerprint_sha256
+
+ t.index :fingerprint, unique: true
+ t.index :fingerprint_sha256
+ end
+ end
+ end
+
+ add_text_limit(:group_deploy_keys, :key, 4096)
+ add_text_limit(:group_deploy_keys, :title, 255)
+ add_text_limit(:group_deploy_keys, :fingerprint, 255)
+ end
+
+ def down
+ # rubocop:disable Migration/DropTable
+ drop_table :group_deploy_keys
+ # rubocop:enable Migration/DropTable
+ end
+end
diff --git a/db/migrate/20200507221434_add_container_registry_features_to_application_settings.rb b/db/migrate/20200507221434_add_container_registry_features_to_application_settings.rb
index b333db56eee..fbbf2306f81 100644
--- a/db/migrate/20200507221434_add_container_registry_features_to_application_settings.rb
+++ b/db/migrate/20200507221434_add_container_registry_features_to_application_settings.rb
@@ -4,7 +4,7 @@ class AddContainerRegistryFeaturesToApplicationSettings < ActiveRecord::Migratio
DOWNTIME = false
def up
- add_column :application_settings, :container_registry_features, :text, array: true, default: [], null: false # rubocop:disable Migration/AddLimitToTextColumns
+ add_column :application_settings, :container_registry_features, :text, array: true, default: [], null: false
end
def down
diff --git a/db/migrate/20200508021128_remove_ultraauth_provider_from_identities.rb b/db/migrate/20200508021128_remove_ultraauth_provider_from_identities.rb
new file mode 100644
index 00000000000..dd3f1dbcc0e
--- /dev/null
+++ b/db/migrate/20200508021128_remove_ultraauth_provider_from_identities.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class RemoveUltraauthProviderFromIdentities < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :identities, :provider
+ execute "DELETE FROM identities WHERE provider = 'ultraauth'"
+ remove_concurrent_index :identities, :provider
+ end
+
+ def down
+ end
+end
diff --git a/db/migrate/20200508050301_add_spam_check_endpoint_to_application_settings.rb b/db/migrate/20200508050301_add_spam_check_endpoint_to_application_settings.rb
new file mode 100644
index 00000000000..d30b8abbbc3
--- /dev/null
+++ b/db/migrate/20200508050301_add_spam_check_endpoint_to_application_settings.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+class AddSpamCheckEndpointToApplicationSettings < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ unless column_exists?(:application_settings, :spam_check_endpoint_url)
+ add_column :application_settings, :spam_check_endpoint_url, :text
+ end
+
+ add_text_limit :application_settings, :spam_check_endpoint_url, 255
+
+ unless column_exists?(:application_settings, :spam_check_endpoint_enabled)
+ add_column :application_settings, :spam_check_endpoint_enabled, :boolean, null: false, default: false
+ end
+ end
+
+ def down
+ remove_column_if_exists :spam_check_endpoint_url
+ remove_column_if_exists :spam_check_endpoint_enabled
+ end
+
+ private
+
+ def remove_column_if_exists(column)
+ return unless column_exists?(:application_settings, column)
+
+ remove_column :application_settings, column
+ end
+end
diff --git a/db/migrate/20200508140959_add_elasticsearch_pause_indexing_to_application_settings.rb b/db/migrate/20200508140959_add_elasticsearch_pause_indexing_to_application_settings.rb
new file mode 100644
index 00000000000..5828db973ed
--- /dev/null
+++ b/db/migrate/20200508140959_add_elasticsearch_pause_indexing_to_application_settings.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddElasticsearchPauseIndexingToApplicationSettings < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ add_column :application_settings, :elasticsearch_pause_indexing, :boolean, default: false, null: false
+ end
+ end
+
+ def down
+ remove_column :application_settings, :elasticsearch_pause_indexing
+ end
+end
diff --git a/db/migrate/20200508203901_add_repository_storages_weighted_to_application_settings.rb b/db/migrate/20200508203901_add_repository_storages_weighted_to_application_settings.rb
new file mode 100644
index 00000000000..b9d4f65989a
--- /dev/null
+++ b/db/migrate/20200508203901_add_repository_storages_weighted_to_application_settings.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddRepositoryStoragesWeightedToApplicationSettings < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def up
+ add_column :application_settings, :repository_storages_weighted, :jsonb, default: {}, null: false
+ end
+
+ def down
+ remove_column :application_settings, :repository_storages_weighted
+ end
+end
diff --git a/db/migrate/20200511181027_create_test_reports.rb b/db/migrate/20200511181027_create_test_reports.rb
new file mode 100644
index 00000000000..a08e208441d
--- /dev/null
+++ b/db/migrate/20200511181027_create_test_reports.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class CreateTestReports < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def change
+ create_table :requirements_management_test_reports do |t|
+ t.datetime_with_timezone :created_at, null: false
+ t.references :requirement, null: false, foreign_key: { on_delete: :cascade }
+ t.bigint :pipeline_id
+ t.bigint :author_id
+ t.integer :state, null: false, limit: 2
+
+ t.index :pipeline_id
+ t.index :author_id
+ end
+ end
+end
diff --git a/db/migrate/20200511191027_add_author_foreign_key_to_test_reports.rb b/db/migrate/20200511191027_add_author_foreign_key_to_test_reports.rb
new file mode 100644
index 00000000000..a9fbee388c5
--- /dev/null
+++ b/db/migrate/20200511191027_add_author_foreign_key_to_test_reports.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddAuthorForeignKeyToTestReports < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ with_lock_retries do
+ add_foreign_key :requirements_management_test_reports, :users, column: :author_id, on_delete: :nullify # rubocop:disable Migration/AddConcurrentForeignKey
+ end
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key :requirements_management_test_reports, column: :author_id
+ end
+ end
+end
diff --git a/db/migrate/20200511208012_add_pipeline_foreign_key_to_test_reports.rb b/db/migrate/20200511208012_add_pipeline_foreign_key_to_test_reports.rb
new file mode 100644
index 00000000000..2b9b3464580
--- /dev/null
+++ b/db/migrate/20200511208012_add_pipeline_foreign_key_to_test_reports.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddPipelineForeignKeyToTestReports < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ with_lock_retries do
+ add_foreign_key :requirements_management_test_reports, :ci_pipelines, column: :pipeline_id, on_delete: :nullify # rubocop:disable Migration/AddConcurrentForeignKey
+ end
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key :requirements_management_test_reports, column: :pipeline_id
+ end
+ end
+end
diff --git a/db/migrate/20200512160004_add_index_to_ci_job_artifacts_for_terraform_reports.rb b/db/migrate/20200512160004_add_index_to_ci_job_artifacts_for_terraform_reports.rb
new file mode 100644
index 00000000000..20eaa549ee5
--- /dev/null
+++ b/db/migrate/20200512160004_add_index_to_ci_job_artifacts_for_terraform_reports.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class AddIndexToCiJobArtifactsForTerraformReports < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ INDEX_NAME = 'index_ci_job_artifacts_for_terraform_reports'
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :ci_job_artifacts, [:project_id, :id], where: 'file_type = 18', name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :ci_job_artifacts, INDEX_NAME
+ end
+end
diff --git a/db/migrate/20200512195442_update_index_on_name_type_eq_ci_build_to_ci_builds.rb b/db/migrate/20200512195442_update_index_on_name_type_eq_ci_build_to_ci_builds.rb
new file mode 100644
index 00000000000..f1334afb89d
--- /dev/null
+++ b/db/migrate/20200512195442_update_index_on_name_type_eq_ci_build_to_ci_builds.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+class UpdateIndexOnNameTypeEqCiBuildToCiBuilds < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ disable_ddl_transaction!
+
+ OLD_INDEX_NAME = 'index_ci_builds_on_name_and_security_type_eq_ci_build'
+ NEW_INDEX_NAME = 'index_security_ci_builds_on_name_and_id'
+
+ OLD_CLAUSE = "((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,
+ ('license_scanning'::character varying)::text])) AND ((type)::text = 'Ci::Build'::text)"
+
+ NEW_CLAUSE = "((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,
+ ('license_scanning'::character varying)::text])) AND ((type)::text = 'Ci::Build'::text)"
+
+ def up
+ add_concurrent_index :ci_builds, [:name, :id], name: NEW_INDEX_NAME, where: NEW_CLAUSE
+ remove_concurrent_index_by_name :ci_builds, OLD_INDEX_NAME
+ end
+
+ def down
+ add_concurrent_index :ci_builds, [:name, :id], name: OLD_INDEX_NAME, where: OLD_CLAUSE
+ remove_concurrent_index_by_name :ci_builds, NEW_INDEX_NAME
+ end
+end
diff --git a/db/migrate/20200518091745_add_index_to_personal_access_token_impersonation.rb b/db/migrate/20200518091745_add_index_to_personal_access_token_impersonation.rb
new file mode 100644
index 00000000000..f9681f1a976
--- /dev/null
+++ b/db/migrate/20200518091745_add_index_to_personal_access_token_impersonation.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+class AddIndexToPersonalAccessTokenImpersonation < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ INDEX_NAME = 'index_expired_and_not_notified_personal_access_tokens'
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index(
+ :personal_access_tokens,
+ [:id, :expires_at],
+ where: "impersonation = FALSE AND revoked = FALSE AND expire_notification_delivered = FALSE",
+ name: INDEX_NAME
+ )
+ end
+
+ def down
+ remove_concurrent_index_by_name(
+ :personal_access_tokens,
+ name: INDEX_NAME
+ )
+ end
+end
diff --git a/db/migrate/20200519074709_update_resource_state_events_constraint_to_support_epic_id.rb b/db/migrate/20200519074709_update_resource_state_events_constraint_to_support_epic_id.rb
new file mode 100644
index 00000000000..ff60e3bdac1
--- /dev/null
+++ b/db/migrate/20200519074709_update_resource_state_events_constraint_to_support_epic_id.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+class UpdateResourceStateEventsConstraintToSupportEpicId < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ OLD_CONSTRAINT = 'resource_state_events_must_belong_to_issue_or_merge_request'
+ CONSTRAINT_NAME = 'resource_state_events_must_belong_to_issue_or_merge_request_or_'
+
+ def up
+ remove_check_constraint :resource_state_events, OLD_CONSTRAINT
+ add_check_constraint :resource_state_events, "(issue_id != NULL AND merge_request_id IS NULL AND epic_id IS NULL) OR " \
+ "(issue_id IS NULL AND merge_request_id != NULL AND epic_id IS NULL) OR" \
+ "(issue_id IS NULL AND merge_request_id IS NULL AND epic_id != NULL)", CONSTRAINT_NAME
+ end
+
+ def down
+ remove_check_constraint :resource_state_events, CONSTRAINT_NAME
+ add_check_constraint :resource_state_events, '(issue_id != NULL AND merge_request_id IS NULL) OR (merge_request_id != NULL AND issue_id IS NULL)', OLD_CONSTRAINT
+ end
+end
diff --git a/db/migrate/20200519101002_add_error_message_column_to_jira_imports.rb b/db/migrate/20200519101002_add_error_message_column_to_jira_imports.rb
new file mode 100644
index 00000000000..478b5358056
--- /dev/null
+++ b/db/migrate/20200519101002_add_error_message_column_to_jira_imports.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class AddErrorMessageColumnToJiraImports < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ disable_ddl_transaction!
+
+ def up
+ unless column_exists?(:jira_imports, :error_message)
+ add_column :jira_imports, :error_message, :text
+ end
+
+ add_text_limit :jira_imports, :error_message, 1000
+ end
+
+ def down
+ return unless column_exists?(:jira_imports, :error_message)
+
+ remove_column :jira_imports, :error_message
+ end
+end
diff --git a/db/migrate/20200519115908_add_epics_confidential_index.rb b/db/migrate/20200519115908_add_epics_confidential_index.rb
new file mode 100644
index 00000000000..68a1715acb4
--- /dev/null
+++ b/db/migrate/20200519115908_add_epics_confidential_index.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddEpicsConfidentialIndex < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :epics, :confidential
+ end
+
+ def down
+ remove_concurrent_index :epics, :confidential
+ end
+end
diff --git a/db/migrate/20200519141534_add_instance_level_variables_column_to_plan_limits.rb b/db/migrate/20200519141534_add_instance_level_variables_column_to_plan_limits.rb
new file mode 100644
index 00000000000..bf36e74a746
--- /dev/null
+++ b/db/migrate/20200519141534_add_instance_level_variables_column_to_plan_limits.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddInstanceLevelVariablesColumnToPlanLimits < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def change
+ add_column :plan_limits, :ci_instance_level_variables, :integer, default: 25, null: false
+ end
+end
diff --git a/db/migrate/20200519194042_update_container_expiration_policies_defaults.rb b/db/migrate/20200519194042_update_container_expiration_policies_defaults.rb
new file mode 100644
index 00000000000..071f50d16a0
--- /dev/null
+++ b/db/migrate/20200519194042_update_container_expiration_policies_defaults.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class UpdateContainerExpirationPoliciesDefaults < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ with_lock_retries do
+ change_column_default :container_expiration_policies, :cadence, '1d'
+ change_column_default :container_expiration_policies, :keep_n, 10
+ change_column_default :container_expiration_policies, :older_than, '90d'
+ end
+ end
+
+ def down
+ with_lock_retries do
+ change_column_default :container_expiration_policies, :cadence, '7d'
+ change_column_default :container_expiration_policies, :keep_n, nil
+ change_column_default :container_expiration_policies, :older_than, nil
+ end
+ end
+end
diff --git a/db/migrate/20200520103514_add_todo_resolved_by_action.rb b/db/migrate/20200520103514_add_todo_resolved_by_action.rb
new file mode 100644
index 00000000000..0aa91091451
--- /dev/null
+++ b/db/migrate/20200520103514_add_todo_resolved_by_action.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddTodoResolvedByAction < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ with_lock_retries do
+ add_column :todos, :resolved_by_action, :integer, limit: 2
+ end
+ end
+
+ def down
+ with_lock_retries do
+ remove_column :todos, :resolved_by_action
+ end
+ end
+end
diff --git a/db/migrate/20200521022725_add_experience_level_to_user_preferences.rb b/db/migrate/20200521022725_add_experience_level_to_user_preferences.rb
new file mode 100644
index 00000000000..e70a13599c3
--- /dev/null
+++ b/db/migrate/20200521022725_add_experience_level_to_user_preferences.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddExperienceLevelToUserPreferences < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def change
+ add_column :user_preferences, :experience_level, :integer, limit: 2
+ end
+end
diff --git a/db/migrate/20200521225327_create_alert_management_alert_assignees.rb b/db/migrate/20200521225327_create_alert_management_alert_assignees.rb
new file mode 100644
index 00000000000..095b2fdfeee
--- /dev/null
+++ b/db/migrate/20200521225327_create_alert_management_alert_assignees.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+class CreateAlertManagementAlertAssignees < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ ALERT_INDEX_NAME = 'index_alert_assignees_on_alert_id'
+ UNIQUE_INDEX_NAME = 'index_alert_assignees_on_user_id_and_alert_id'
+
+ def up
+ create_table :alert_management_alert_assignees do |t|
+ t.bigint :user_id, null: false
+ t.bigint :alert_id, null: false
+
+ t.index :alert_id, name: ALERT_INDEX_NAME
+ t.index [:user_id, :alert_id], unique: true, name: UNIQUE_INDEX_NAME
+ end
+ end
+
+ def down
+ # rubocop:disable Migration/DropTable
+ drop_table :alert_management_alert_assignees
+ # rubocop:enable Migration/DropTable
+ end
+end
diff --git a/db/migrate/20200521225337_add_foreign_key_to_user_id_on_alert_management_alert_assignees.rb b/db/migrate/20200521225337_add_foreign_key_to_user_id_on_alert_management_alert_assignees.rb
new file mode 100644
index 00000000000..9d97c68f78f
--- /dev/null
+++ b/db/migrate/20200521225337_add_foreign_key_to_user_id_on_alert_management_alert_assignees.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddForeignKeyToUserIdOnAlertManagementAlertAssignees < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ with_lock_retries do
+ add_foreign_key :alert_management_alert_assignees, :users, column: :user_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey
+ end
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key :alert_management_alert_assignees, column: :user_id
+ end
+ end
+end
diff --git a/db/migrate/20200521225346_add_foreign_key_to_alert_id_on_alert_mangagement_alert_assignees.rb b/db/migrate/20200521225346_add_foreign_key_to_alert_id_on_alert_mangagement_alert_assignees.rb
new file mode 100644
index 00000000000..1d6197edef9
--- /dev/null
+++ b/db/migrate/20200521225346_add_foreign_key_to_alert_id_on_alert_mangagement_alert_assignees.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddForeignKeyToAlertIdOnAlertMangagementAlertAssignees < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ with_lock_retries do
+ add_foreign_key :alert_management_alert_assignees, :alert_management_alerts, column: :alert_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey
+ end
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key :alert_management_alert_assignees, column: :alert_id
+ end
+ end
+end
diff --git a/db/migrate/20200522235146_add_index_on_snippet_type_and_id.rb b/db/migrate/20200522235146_add_index_on_snippet_type_and_id.rb
new file mode 100644
index 00000000000..0949e8049d1
--- /dev/null
+++ b/db/migrate/20200522235146_add_index_on_snippet_type_and_id.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddIndexOnSnippetTypeAndId < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :snippets, [:id, :type]
+ end
+
+ def down
+ remove_concurrent_index :snippets, [:id, :type]
+ end
+end
diff --git a/db/migrate/20200525114553_rename_user_type_index.rb b/db/migrate/20200525114553_rename_user_type_index.rb
new file mode 100644
index 00000000000..44ce142ffcb
--- /dev/null
+++ b/db/migrate/20200525114553_rename_user_type_index.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RenameUserTypeIndex < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :users, [:state, :user_type], name: 'index_users_on_state_and_user_type'
+ remove_concurrent_index_by_name :users, 'index_users_on_state_and_user_type_internal'
+ end
+
+ def down
+ add_concurrent_index :users, [:state, :user_type], where: 'ghost IS NOT TRUE', name: 'index_users_on_state_and_user_type_internal'
+ remove_concurrent_index_by_name :users, 'index_users_on_state_and_user_type'
+ end
+end
diff --git a/db/migrate/20200526013844_add_alert_events_to_services.rb b/db/migrate/20200526013844_add_alert_events_to_services.rb
new file mode 100644
index 00000000000..1dba7fcaad4
--- /dev/null
+++ b/db/migrate/20200526013844_add_alert_events_to_services.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddAlertEventsToServices < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ with_lock_retries do
+ add_column :services, :alert_events, :boolean
+ end
+ end
+
+ def down
+ with_lock_retries do
+ remove_column :services, :alert_events
+ end
+ end
+end
diff --git a/db/migrate/20200526120714_change_partial_indexes_on_services.rb b/db/migrate/20200526120714_change_partial_indexes_on_services.rb
new file mode 100644
index 00000000000..a4d58cda105
--- /dev/null
+++ b/db/migrate/20200526120714_change_partial_indexes_on_services.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+class ChangePartialIndexesOnServices < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ # Set this constant to true if this migration requires downtime.
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :services, [:type, :instance], unique: true, where: 'instance = true', name: 'index_services_on_type_and_instance_partial'
+ remove_concurrent_index_by_name :services, 'index_services_on_type_and_instance'
+
+ add_concurrent_index :services, [:type, :template], unique: true, where: 'template = true', name: 'index_services_on_type_and_template_partial'
+ remove_concurrent_index_by_name :services, 'index_services_on_type_and_template'
+ end
+
+ def down
+ add_concurrent_index :services, [:type, :instance], unique: true, where: 'instance IS TRUE', name: 'index_services_on_type_and_instance'
+ remove_concurrent_index_by_name :services, 'index_services_on_type_and_instance_partial'
+
+ add_concurrent_index :services, [:type, :template], unique: true, where: 'template IS TRUE', name: 'index_services_on_type_and_template'
+ remove_concurrent_index_by_name :services, 'index_services_on_type_and_template_partial'
+ end
+end
diff --git a/db/migrate/20200526142550_drop_null_constraint_on_group_import_state_jid.rb b/db/migrate/20200526142550_drop_null_constraint_on_group_import_state_jid.rb
new file mode 100644
index 00000000000..d0dfa126455
--- /dev/null
+++ b/db/migrate/20200526142550_drop_null_constraint_on_group_import_state_jid.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class DropNullConstraintOnGroupImportStateJid < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def up
+ change_column_null :group_import_states, :jid, true
+ end
+
+ def down
+ # No-op -- null values could have been added after this this constraint was removed.
+ end
+end
diff --git a/db/migrate/20200526153844_add_issues_last_edited_by_id_index.rb b/db/migrate/20200526153844_add_issues_last_edited_by_id_index.rb
new file mode 100644
index 00000000000..85f121a4c02
--- /dev/null
+++ b/db/migrate/20200526153844_add_issues_last_edited_by_id_index.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddIssuesLastEditedByIdIndex < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :issues, :last_edited_by_id
+ add_concurrent_index :epics, :last_edited_by_id
+ end
+
+ def down
+ remove_concurrent_index :issues, :last_edited_by_id
+ remove_concurrent_index :epics, :last_edited_by_id
+ end
+end
diff --git a/db/migrate/20200526164946_create_operations_feature_flags_issues.rb b/db/migrate/20200526164946_create_operations_feature_flags_issues.rb
new file mode 100644
index 00000000000..24876997cfd
--- /dev/null
+++ b/db/migrate/20200526164946_create_operations_feature_flags_issues.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class CreateOperationsFeatureFlagsIssues < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def change
+ create_table :operations_feature_flags_issues do |t|
+ t.references :feature_flag, index: false, foreign_key: { on_delete: :cascade, to_table: :operations_feature_flags }, null: false
+ t.bigint :issue_id, null: false
+
+ t.index [:feature_flag_id, :issue_id], unique: true, name: :index_ops_feature_flags_issues_on_feature_flag_id_and_issue_id
+ t.index :issue_id
+ end
+ end
+end
diff --git a/db/migrate/20200526164947_add_foreign_key_to_ops_feature_flags_issues.rb b/db/migrate/20200526164947_add_foreign_key_to_ops_feature_flags_issues.rb
new file mode 100644
index 00000000000..1cad53cb371
--- /dev/null
+++ b/db/migrate/20200526164947_add_foreign_key_to_ops_feature_flags_issues.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddForeignKeyToOpsFeatureFlagsIssues < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ with_lock_retries do
+ add_foreign_key :operations_feature_flags_issues, :issues, column: :issue_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey
+ end
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key :operations_feature_flags_issues, column: :issue_id
+ end
+ end
+end
diff --git a/db/migrate/20200527092027_add_link_type_to_release_links.rb b/db/migrate/20200527092027_add_link_type_to_release_links.rb
new file mode 100644
index 00000000000..5088775f665
--- /dev/null
+++ b/db/migrate/20200527092027_add_link_type_to_release_links.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddLinkTypeToReleaseLinks < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ with_lock_retries do
+ add_column :release_links, :link_type, :integer, limit: 2, default: 0
+ end
+ end
+
+ def down
+ with_lock_retries do
+ remove_column :release_links, :link_type
+ end
+ end
+end
diff --git a/db/migrate/20200527135313_add_requirements_build_reference.rb b/db/migrate/20200527135313_add_requirements_build_reference.rb
new file mode 100644
index 00000000000..3385243fbdd
--- /dev/null
+++ b/db/migrate/20200527135313_add_requirements_build_reference.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class AddRequirementsBuildReference < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ INDEX_NAME = 'index_requirements_management_test_reports_on_build_id'
+
+ def up
+ add_column :requirements_management_test_reports, :build_id, :bigint
+ add_index :requirements_management_test_reports, :build_id, name: INDEX_NAME # rubocop:disable Migration/AddIndex
+
+ with_lock_retries do
+ add_foreign_key :requirements_management_test_reports, :ci_builds, column: :build_id, on_delete: :nullify # rubocop:disable Migration/AddConcurrentForeignKey
+ end
+ end
+
+ def down
+ with_lock_retries do
+ remove_column :requirements_management_test_reports, :build_id
+ end
+ end
+end
diff --git a/db/migrate/20200527151413_create_ci_build_report_results_table.rb b/db/migrate/20200527151413_create_ci_build_report_results_table.rb
new file mode 100644
index 00000000000..7f854dd4891
--- /dev/null
+++ b/db/migrate/20200527151413_create_ci_build_report_results_table.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class CreateCiBuildReportResultsTable < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def change
+ create_table :ci_build_report_results, id: false do |t|
+ t.bigint :build_id, null: false, index: false, primary_key: true
+ t.bigint :project_id, null: false, index: true
+ t.jsonb :data, null: false, default: {}
+ end
+ end
+end
diff --git a/db/migrate/20200527152116_add_foreign_key_to_build_id_on_build_report_results.rb b/db/migrate/20200527152116_add_foreign_key_to_build_id_on_build_report_results.rb
new file mode 100644
index 00000000000..1c41389b15b
--- /dev/null
+++ b/db/migrate/20200527152116_add_foreign_key_to_build_id_on_build_report_results.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddForeignKeyToBuildIdOnBuildReportResults < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ with_lock_retries do
+ add_foreign_key :ci_build_report_results, :ci_builds, column: :build_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey
+ end
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key :ci_build_report_results, column: :build_id
+ end
+ end
+end
diff --git a/db/migrate/20200527152657_add_foreign_key_to_project_id_on_build_report_results.rb b/db/migrate/20200527152657_add_foreign_key_to_project_id_on_build_report_results.rb
new file mode 100644
index 00000000000..da870722bc3
--- /dev/null
+++ b/db/migrate/20200527152657_add_foreign_key_to_project_id_on_build_report_results.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddForeignKeyToProjectIdOnBuildReportResults < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ with_lock_retries do
+ add_foreign_key :ci_build_report_results, :projects, column: :project_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey
+ end
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key :ci_build_report_results, column: :project_id
+ end
+ end
+end
diff --git a/db/migrate/20200527170649_create_alert_management_alert_user_mentions.rb b/db/migrate/20200527170649_create_alert_management_alert_user_mentions.rb
new file mode 100644
index 00000000000..15e4ab2a357
--- /dev/null
+++ b/db/migrate/20200527170649_create_alert_management_alert_user_mentions.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class CreateAlertManagementAlertUserMentions < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def change
+ create_table :alert_management_alert_user_mentions do |t|
+ t.references :alert_management_alert, type: :bigint, index: false, null: false, foreign_key: { on_delete: :cascade }
+ t.bigint :note_id, null: true
+
+ t.integer :mentioned_users_ids, array: true
+ t.integer :mentioned_projects_ids, array: true
+ t.integer :mentioned_groups_ids, array: true
+ end
+
+ add_index :alert_management_alert_user_mentions, [:note_id], where: 'note_id IS NOT NULL', unique: true, name: 'index_alert_user_mentions_on_note_id'
+ add_index :alert_management_alert_user_mentions, [:alert_management_alert_id], where: 'note_id IS NULL', unique: true, name: 'index_alert_user_mentions_on_alert_id'
+ add_index :alert_management_alert_user_mentions, [:alert_management_alert_id, :note_id], unique: true, name: 'index_alert_user_mentions_on_alert_id_and_note_id'
+ end
+end
diff --git a/db/migrate/20200527211000_add_max_import_size.rb b/db/migrate/20200527211000_add_max_import_size.rb
new file mode 100644
index 00000000000..2779997dbb2
--- /dev/null
+++ b/db/migrate/20200527211000_add_max_import_size.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddMaxImportSize < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ add_column(:application_settings, :max_import_size, :integer, default: 50, null: false)
+ end
+
+ def down
+ remove_column(:application_settings, :max_import_size)
+ end
+end
diff --git a/db/migrate/20200528054112_add_index_to_package_name.rb b/db/migrate/20200528054112_add_index_to_package_name.rb
new file mode 100644
index 00000000000..4629c32ab3d
--- /dev/null
+++ b/db/migrate/20200528054112_add_index_to_package_name.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddIndexToPackageName < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'package_name_index'.freeze
+
+ def up
+ add_concurrent_index(:packages_packages, :name, name: INDEX_NAME)
+ end
+
+ def down
+ remove_concurrent_index(:packages_packages, :name, name: INDEX_NAME)
+ end
+end
diff --git a/db/migrate/20200528125905_add_project_id_user_id_status_ref_index_to_ci_pipelines.rb b/db/migrate/20200528125905_add_project_id_user_id_status_ref_index_to_ci_pipelines.rb
new file mode 100644
index 00000000000..7211490e337
--- /dev/null
+++ b/db/migrate/20200528125905_add_project_id_user_id_status_ref_index_to_ci_pipelines.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class AddProjectIdUserIdStatusRefIndexToCiPipelines < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ SOURCE_PARENT_PIPELINE = 12
+
+ def up
+ add_concurrent_index(
+ :ci_pipelines,
+ [:project_id, :user_id, :status, :ref],
+ where: "source != #{SOURCE_PARENT_PIPELINE}"
+ )
+ end
+
+ def down
+ remove_concurrent_index(
+ :ci_pipelines,
+ [:project_id, :user_id, :status, :ref],
+ where: "source != #{SOURCE_PARENT_PIPELINE}"
+ )
+ end
+end
diff --git a/db/migrate/20200528171933_remove_not_null_from_external_dashboard_url.rb b/db/migrate/20200528171933_remove_not_null_from_external_dashboard_url.rb
new file mode 100644
index 00000000000..d146c8b487b
--- /dev/null
+++ b/db/migrate/20200528171933_remove_not_null_from_external_dashboard_url.rb
@@ -0,0 +1,12 @@
+# 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 RemoveNotNullFromExternalDashboardUrl < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def change
+ change_column_null :project_metrics_settings, :external_dashboard_url, true
+ end
+end
diff --git a/db/migrate/20200601210148_add_dashboard_timezone_to_project_metrics_setting.rb b/db/migrate/20200601210148_add_dashboard_timezone_to_project_metrics_setting.rb
new file mode 100644
index 00000000000..3f74ef28621
--- /dev/null
+++ b/db/migrate/20200601210148_add_dashboard_timezone_to_project_metrics_setting.rb
@@ -0,0 +1,12 @@
+# 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 AddDashboardTimezoneToProjectMetricsSetting < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def change
+ add_column :project_metrics_settings, :dashboard_timezone, :integer, limit: 2, null: false, default: 0
+ end
+end
diff --git a/db/migrate/20200603073101_change_constraint_name_on_resource_state_events.rb b/db/migrate/20200603073101_change_constraint_name_on_resource_state_events.rb
new file mode 100644
index 00000000000..d37027bf2fb
--- /dev/null
+++ b/db/migrate/20200603073101_change_constraint_name_on_resource_state_events.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class ChangeConstraintNameOnResourceStateEvents < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ NEW_CONSTRAINT_NAME = 'state_events_must_belong_to_issue_or_merge_request_or_epic'
+ OLD_CONSTRAINT_NAME = 'resource_state_events_must_belong_to_issue_or_merge_request_or_'
+
+ def up
+ execute "ALTER TABLE resource_state_events RENAME CONSTRAINT #{OLD_CONSTRAINT_NAME} TO #{NEW_CONSTRAINT_NAME};"
+ end
+
+ def down
+ execute "ALTER TABLE resource_state_events RENAME CONSTRAINT #{NEW_CONSTRAINT_NAME} TO #{OLD_CONSTRAINT_NAME};"
+ end
+end
diff --git a/db/migrate/20200603180338_add_enforce_pat_expiration_to_application_settings.rb b/db/migrate/20200603180338_add_enforce_pat_expiration_to_application_settings.rb
new file mode 100644
index 00000000000..ca0abc70b64
--- /dev/null
+++ b/db/migrate/20200603180338_add_enforce_pat_expiration_to_application_settings.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddEnforcePatExpirationToApplicationSettings < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def change
+ add_column :application_settings, :enforce_pat_expiration, :boolean, default: true, null: false
+ end
+end
diff --git a/db/migrate/20200604143628_create_project_security_settings.rb b/db/migrate/20200604143628_create_project_security_settings.rb
new file mode 100644
index 00000000000..b1a08cf8781
--- /dev/null
+++ b/db/migrate/20200604143628_create_project_security_settings.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+class CreateProjectSecuritySettings < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ with_lock_retries do
+ create_table :project_security_settings, id: false do |t|
+ t.references :project, primary_key: true, index: false, foreign_key: { on_delete: :cascade }
+ t.timestamps_with_timezone
+
+ t.boolean :auto_fix_container_scanning, default: true, null: false
+ t.boolean :auto_fix_dast, default: true, null: false
+ t.boolean :auto_fix_dependency_scanning, default: true, null: false
+ t.boolean :auto_fix_sast, default: true, null: false
+ end
+ end
+ end
+
+ def down
+ with_lock_retries do
+ # rubocop:disable Migration/DropTable
+ drop_table :project_security_settings
+ # rubocop:enable Migration/DropTable
+ end
+ end
+end
diff --git a/db/migrate/20200604145731_create_board_user_preferences.rb b/db/migrate/20200604145731_create_board_user_preferences.rb
new file mode 100644
index 00000000000..36e5014fdbe
--- /dev/null
+++ b/db/migrate/20200604145731_create_board_user_preferences.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class CreateBoardUserPreferences < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def up
+ create_table :board_user_preferences do |t|
+ t.bigint :user_id, null: false, index: true
+ t.bigint :board_id, null: false, index: true
+ t.boolean :hide_labels
+ t.timestamps_with_timezone null: false
+ end
+
+ add_index :board_user_preferences, [:user_id, :board_id], unique: true
+ end
+
+ def down
+ # rubocop:disable Migration/DropTable
+ drop_table :board_user_preferences
+ # rubocop:enable Migration/DropTable
+ end
+end
diff --git a/db/migrate/20200604174544_add_users_foreign_key_to_board_user_preferences.rb b/db/migrate/20200604174544_add_users_foreign_key_to_board_user_preferences.rb
new file mode 100644
index 00000000000..8f60c41a9c7
--- /dev/null
+++ b/db/migrate/20200604174544_add_users_foreign_key_to_board_user_preferences.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddUsersForeignKeyToBoardUserPreferences < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ with_lock_retries do
+ add_foreign_key :board_user_preferences, :users, column: :user_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey
+ end
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key :board_user_preferences, column: :user_id
+ end
+ end
+end
diff --git a/db/migrate/20200604174558_add_boards_foreign_key_to_board_user_preferences.rb b/db/migrate/20200604174558_add_boards_foreign_key_to_board_user_preferences.rb
new file mode 100644
index 00000000000..a18f0eac505
--- /dev/null
+++ b/db/migrate/20200604174558_add_boards_foreign_key_to_board_user_preferences.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddBoardsForeignKeyToBoardUserPreferences < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ with_lock_retries do
+ add_foreign_key :board_user_preferences, :boards, column: :board_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey
+ end
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key :board_user_preferences, column: :board_id
+ end
+ end
+end
diff --git a/db/migrate/20200605003204_add_foreign_key_to_alert_management_alert_user_mentions.rb b/db/migrate/20200605003204_add_foreign_key_to_alert_management_alert_user_mentions.rb
new file mode 100644
index 00000000000..35a250521a6
--- /dev/null
+++ b/db/migrate/20200605003204_add_foreign_key_to_alert_management_alert_user_mentions.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddForeignKeyToAlertManagementAlertUserMentions < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ with_lock_retries do
+ add_foreign_key :alert_management_alert_user_mentions, :notes, column: :note_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey
+ end
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key :alert_management_alert_user_mentions, column: :note_id
+ end
+ end
+end
diff --git a/db/migrate/20200605093113_add_ip_address_to_audit_events.rb b/db/migrate/20200605093113_add_ip_address_to_audit_events.rb
new file mode 100644
index 00000000000..9f5694ddce2
--- /dev/null
+++ b/db/migrate/20200605093113_add_ip_address_to_audit_events.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddIpAddressToAuditEvents < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def change
+ add_column :audit_events, :ip_address, :inet
+ end
+end
diff --git a/db/migrate/20200608214008_change_column_default_project_incident_management_settings.rb b/db/migrate/20200608214008_change_column_default_project_incident_management_settings.rb
new file mode 100644
index 00000000000..1bfafb410c0
--- /dev/null
+++ b/db/migrate/20200608214008_change_column_default_project_incident_management_settings.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class ChangeColumnDefaultProjectIncidentManagementSettings < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def up
+ change_column_default(:project_incident_management_settings, :create_issue, from: true, to: false)
+ end
+
+ def down
+ change_column_default(:project_incident_management_settings, :create_issue, from: false, to: true)
+ end
+end
diff --git a/db/migrate/20200609142506_remove_not_null_constraint_from_weight_events_table.rb b/db/migrate/20200609142506_remove_not_null_constraint_from_weight_events_table.rb
new file mode 100644
index 00000000000..af4d4dbbf42
--- /dev/null
+++ b/db/migrate/20200609142506_remove_not_null_constraint_from_weight_events_table.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class RemoveNotNullConstraintFromWeightEventsTable < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def change
+ change_column_null :resource_weight_events, :user_id, true
+ end
+end
diff --git a/db/migrate/20200609142507_remove_not_null_constraint_from_milestone_events_table.rb b/db/migrate/20200609142507_remove_not_null_constraint_from_milestone_events_table.rb
new file mode 100644
index 00000000000..41204afb014
--- /dev/null
+++ b/db/migrate/20200609142507_remove_not_null_constraint_from_milestone_events_table.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class RemoveNotNullConstraintFromMilestoneEventsTable < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def change
+ change_column_null :resource_milestone_events, :user_id, true
+ end
+end
diff --git a/db/migrate/20200609142508_remove_not_null_constraint_from_state_events_table.rb b/db/migrate/20200609142508_remove_not_null_constraint_from_state_events_table.rb
new file mode 100644
index 00000000000..ffa047a78f9
--- /dev/null
+++ b/db/migrate/20200609142508_remove_not_null_constraint_from_state_events_table.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class RemoveNotNullConstraintFromStateEventsTable < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def change
+ change_column_null :resource_state_events, :user_id, true
+ end
+end
diff --git a/db/migrate/20200609212701_add_incident_settings_to_all_existing_projects.rb b/db/migrate/20200609212701_add_incident_settings_to_all_existing_projects.rb
new file mode 100644
index 00000000000..60286e0dca6
--- /dev/null
+++ b/db/migrate/20200609212701_add_incident_settings_to_all_existing_projects.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+class AddIncidentSettingsToAllExistingProjects < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def up
+ # Add records to projects project_incident_management_settings
+ # to preserve behavior for existing projects that
+ # are using the create issue functionality with the default setting of true
+ query = <<-SQL
+ WITH project_ids AS (
+ SELECT DISTINCT issues.project_id AS id
+ FROM issues
+ LEFT OUTER JOIN project_incident_management_settings
+ ON project_incident_management_settings.project_id = issues.project_id
+ INNER JOIN label_links
+ ON label_links.target_type = 'Issue'
+ AND label_links.target_id = issues.id
+ INNER JOIN labels
+ ON labels.id = label_links.label_id
+ WHERE ( project_incident_management_settings.project_id IS NULL )
+ -- Use incident labels even though they could be manually added by users who
+ -- are not using alert funtionality.
+ AND labels.title = 'incident'
+ AND labels.color = '#CC0033'
+ AND labels.description = 'Denotes a disruption to IT services and the associated issues require immediate attention'
+ )
+ INSERT INTO project_incident_management_settings (project_id, create_issue, send_email, issue_template_key)
+ SELECT project_ids.id, TRUE, FALSE, NULL
+ FROM project_ids
+ ON CONFLICT (project_id) DO NOTHING;
+ SQL
+
+ execute(query)
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/migrate/20200615083635_add_composer_json_to_metadata.rb b/db/migrate/20200615083635_add_composer_json_to_metadata.rb
new file mode 100644
index 00000000000..0240d298d34
--- /dev/null
+++ b/db/migrate/20200615083635_add_composer_json_to_metadata.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddComposerJsonToMetadata < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def change
+ add_column :packages_composer_metadata, :composer_json, :jsonb, default: {}, null: false
+ end
+end
diff --git a/db/migrate/20200615121217_add_projects_foreign_key_to_project_access_tokens.rb b/db/migrate/20200615121217_add_projects_foreign_key_to_project_access_tokens.rb
new file mode 100644
index 00000000000..bc8956ff6df
--- /dev/null
+++ b/db/migrate/20200615121217_add_projects_foreign_key_to_project_access_tokens.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddProjectsForeignKeyToProjectAccessTokens < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_foreign_key :project_access_tokens, :projects, column: :project_id
+ end
+
+ def down
+ remove_foreign_key_if_exists :project_access_tokens, column: :project_id
+ end
+end
diff --git a/db/migrate/20200615123055_add_personal_access_token_foreign_key_to_project_access_tokens.rb b/db/migrate/20200615123055_add_personal_access_token_foreign_key_to_project_access_tokens.rb
new file mode 100644
index 00000000000..efe3fe13bab
--- /dev/null
+++ b/db/migrate/20200615123055_add_personal_access_token_foreign_key_to_project_access_tokens.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddPersonalAccessTokenForeignKeyToProjectAccessTokens < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_foreign_key :project_access_tokens, :personal_access_tokens, column: :personal_access_token_id
+ end
+
+ def down
+ remove_foreign_key_if_exists :project_access_tokens, column: :personal_access_token_id
+ end
+end
diff --git a/db/migrate/20200615232735_add_index_to_composer_metadata.rb b/db/migrate/20200615232735_add_index_to_composer_metadata.rb
new file mode 100644
index 00000000000..72a490c55d8
--- /dev/null
+++ b/db/migrate/20200615232735_add_index_to_composer_metadata.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddIndexToComposerMetadata < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index(:packages_composer_metadata, [:package_id, :target_sha], unique: true)
+ end
+
+ def down
+ remove_concurrent_index(:packages_composer_metadata, [:package_id, :target_sha])
+ end
+end
diff --git a/db/post_migrate/20180104131052_schedule_set_confidential_note_events_on_webhooks.rb b/db/post_migrate/20180104131052_schedule_set_confidential_note_events_on_webhooks.rb
deleted file mode 100644
index 0822aebc2c6..00000000000
--- a/db/post_migrate/20180104131052_schedule_set_confidential_note_events_on_webhooks.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-class ScheduleSetConfidentialNoteEventsOnWebhooks < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- BATCH_SIZE = 1_000
- INTERVAL = 5.minutes
-
- disable_ddl_transaction!
-
- def up
- migration = Gitlab::BackgroundMigration::SetConfidentialNoteEventsOnWebhooks
- migration_name = migration.to_s.demodulize
- relation = migration::WebHook.hooks_to_update
-
- queue_background_migration_jobs_by_range_at_intervals(relation,
- migration_name,
- INTERVAL,
- batch_size: BATCH_SIZE)
- end
-
- def down
- end
-end
diff --git a/db/post_migrate/20180119121225_remove_redundant_pipeline_stages.rb b/db/post_migrate/20180119121225_remove_redundant_pipeline_stages.rb
deleted file mode 100644
index 66ad0a89539..00000000000
--- a/db/post_migrate/20180119121225_remove_redundant_pipeline_stages.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-class RemoveRedundantPipelineStages < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up(attempts: 100)
- remove_redundant_pipeline_stages!
- remove_outdated_index!
- add_unique_index!
- rescue ActiveRecord::RecordNotUnique
- retry if (attempts -= 1) > 0
-
- raise StandardError, <<~EOS
- Failed to add an unique index to ci_stages, despite retrying the
- migration 100 times.
-
- See https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/16580.
- EOS
- end
-
- def down
- remove_concurrent_index :ci_stages, [:pipeline_id, :name], unique: true
- add_concurrent_index :ci_stages, [:pipeline_id, :name]
- end
-
- private
-
- def remove_outdated_index!
- return unless index_exists?(:ci_stages, [:pipeline_id, :name])
-
- remove_concurrent_index :ci_stages, [:pipeline_id, :name]
- end
-
- def add_unique_index!
- add_concurrent_index :ci_stages, [:pipeline_id, :name], unique: true
- end
-
- def remove_redundant_pipeline_stages!
- disable_statement_timeout do
- redundant_stages_ids = <<~SQL
- SELECT id FROM ci_stages WHERE (pipeline_id, name) IN (
- SELECT pipeline_id, name FROM ci_stages
- GROUP BY pipeline_id, name HAVING COUNT(*) > 1
- )
- SQL
-
- execute <<~SQL
- UPDATE ci_builds SET stage_id = NULL WHERE stage_id IN (#{redundant_stages_ids})
- SQL
-
- execute <<~SQL
- DELETE FROM ci_stages WHERE id IN (#{redundant_stages_ids})
- SQL
- end
- end
-end
diff --git a/db/post_migrate/20180122154930_schedule_set_confidential_note_events_on_services.rb b/db/post_migrate/20180122154930_schedule_set_confidential_note_events_on_services.rb
deleted file mode 100644
index 98bbb34dda1..00000000000
--- a/db/post_migrate/20180122154930_schedule_set_confidential_note_events_on_services.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-class ScheduleSetConfidentialNoteEventsOnServices < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- BATCH_SIZE = 1_000
- INTERVAL = 20.minutes
-
- disable_ddl_transaction!
-
- def up
- migration = Gitlab::BackgroundMigration::SetConfidentialNoteEventsOnServices
- migration_name = migration.to_s.demodulize
- relation = migration::Service.services_to_update
-
- queue_background_migration_jobs_by_range_at_intervals(relation,
- migration_name,
- INTERVAL,
- batch_size: BATCH_SIZE)
- end
-
- def down
- end
-end
diff --git a/db/post_migrate/20180204200836_change_author_id_to_not_null_in_todos.rb b/db/post_migrate/20180204200836_change_author_id_to_not_null_in_todos.rb
deleted file mode 100644
index 54b8a91fa47..00000000000
--- a/db/post_migrate/20180204200836_change_author_id_to_not_null_in_todos.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-class ChangeAuthorIdToNotNullInTodos < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- class Todo < ActiveRecord::Base
- self.table_name = 'todos'
- include EachBatch
- end
-
- BATCH_SIZE = 1000
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- Todo.where(author_id: nil).each_batch(of: BATCH_SIZE) do |batch|
- batch.delete_all
- end
-
- change_column_null :todos, :author_id, false
- end
-
- def down
- change_column_null :todos, :author_id, true
- end
-end
diff --git a/db/post_migrate/20180212101828_add_tmp_partial_null_index_to_builds.rb b/db/post_migrate/20180212101828_add_tmp_partial_null_index_to_builds.rb
deleted file mode 100644
index f8badcac990..00000000000
--- a/db/post_migrate/20180212101828_add_tmp_partial_null_index_to_builds.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-class AddTmpPartialNullIndexToBuilds < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index(:ci_builds, :id, where: 'stage_id IS NULL',
- name: 'tmp_id_partial_null_index')
- end
-
- def down
- remove_concurrent_index_by_name(:ci_builds, 'tmp_id_partial_null_index')
- end
-end
diff --git a/db/post_migrate/20180212101928_schedule_build_stage_migration.rb b/db/post_migrate/20180212101928_schedule_build_stage_migration.rb
deleted file mode 100644
index 2445ab1a130..00000000000
--- a/db/post_migrate/20180212101928_schedule_build_stage_migration.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-class ScheduleBuildStageMigration < ActiveRecord::Migration[4.2]
- ##
- # This migration has been rescheduled to run again, see
- # `20180405101928_reschedule_builds_stages_migration.rb`
- #
-
- def up
- # noop
- end
-
- def down
- # noop
- end
-end
diff --git a/db/post_migrate/20180212102028_remove_tmp_partial_null_index_from_builds.rb b/db/post_migrate/20180212102028_remove_tmp_partial_null_index_from_builds.rb
deleted file mode 100644
index 2444df881b8..00000000000
--- a/db/post_migrate/20180212102028_remove_tmp_partial_null_index_from_builds.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-class RemoveTmpPartialNullIndexFromBuilds < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- disable_ddl_transaction!
-
- def up
- remove_concurrent_index_by_name(:ci_builds, 'tmp_id_partial_null_index')
- end
-
- def down
- add_concurrent_index(:ci_builds, :id, where: 'stage_id IS NULL',
- name: 'tmp_id_partial_null_index')
- end
-end
diff --git a/db/post_migrate/20180216121020_fill_pages_domain_verification_code.rb b/db/post_migrate/20180216121020_fill_pages_domain_verification_code.rb
deleted file mode 100644
index dae43ee14df..00000000000
--- a/db/post_migrate/20180216121020_fill_pages_domain_verification_code.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-class FillPagesDomainVerificationCode < ActiveRecord::Migration[4.2]
- DOWNTIME = false
-
- class PagesDomain < ActiveRecord::Base
- include EachBatch
- end
-
- # Allow this migration to resume if it fails partway through
- disable_ddl_transaction!
-
- def up
- PagesDomain.where(verification_code: [nil, '']).each_batch do |relation|
- connection.execute(set_codes_sql(relation))
-
- # Sleep 2 minutes between batches to not overload the DB with dead tuples
- sleep(2.minutes) unless relation.reorder(:id).last == PagesDomain.reorder(:id).last
- end
-
- change_column_null(:pages_domains, :verification_code, false)
- end
-
- def down
- change_column_null(:pages_domains, :verification_code, true)
- end
-
- private
-
- def set_codes_sql(relation)
- ids = relation.pluck(:id)
- whens = ids.map { |id| "WHEN #{id} THEN '#{SecureRandom.hex(16)}'" }
-
- <<~SQL
- UPDATE pages_domains
- SET verification_code =
- CASE id
- #{whens.join("\n")}
- END
- WHERE id IN(#{ids.join(',')})
- SQL
- end
-end
diff --git a/db/post_migrate/20180216121030_enqueue_verify_pages_domain_workers.rb b/db/post_migrate/20180216121030_enqueue_verify_pages_domain_workers.rb
deleted file mode 100644
index d776fb85f00..00000000000
--- a/db/post_migrate/20180216121030_enqueue_verify_pages_domain_workers.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-class EnqueueVerifyPagesDomainWorkers < ActiveRecord::Migration[4.2]
- class PagesDomain < ActiveRecord::Base
- include EachBatch
- end
-
- def up
- PagesDomain.each_batch do |relation|
- ids = relation.pluck(:id).map { |id| [id] }
- PagesDomainVerificationWorker.bulk_perform_async(ids)
- end
- end
-
- def down
- # no-op
- end
-end
diff --git a/db/post_migrate/20180220150310_remove_empty_extern_uid_auth0_identities.rb b/db/post_migrate/20180220150310_remove_empty_extern_uid_auth0_identities.rb
deleted file mode 100644
index 86ef333685e..00000000000
--- a/db/post_migrate/20180220150310_remove_empty_extern_uid_auth0_identities.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-class RemoveEmptyExternUidAuth0Identities < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- class Identity < ActiveRecord::Base
- self.table_name = 'identities'
- include EachBatch
- end
-
- def up
- broken_auth0_identities.each_batch do |identity|
- identity.delete_all
- end
- end
-
- def broken_auth0_identities
- Identity.where(provider: 'auth0', extern_uid: [nil, ''])
- end
-
- def down
- end
-end
diff --git a/db/post_migrate/20180223124427_build_user_interacted_projects_table.rb b/db/post_migrate/20180223124427_build_user_interacted_projects_table.rb
deleted file mode 100644
index 1eb49d60da5..00000000000
--- a/db/post_migrate/20180223124427_build_user_interacted_projects_table.rb
+++ /dev/null
@@ -1,139 +0,0 @@
-require_relative '../migrate/20180223120443_create_user_interacted_projects_table.rb'
-# rubocop:disable AddIndex
-# rubocop:disable AddConcurrentForeignKey
-class BuildUserInteractedProjectsTable < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- UNIQUE_INDEX_NAME = 'index_user_interacted_projects_on_project_id_and_user_id'
-
- disable_ddl_transaction!
-
- def up
- PostgresStrategy.new.up
-
- if index_exists_by_name?(:user_interacted_projects, CreateUserInteractedProjectsTable::INDEX_NAME)
- remove_concurrent_index_by_name :user_interacted_projects, CreateUserInteractedProjectsTable::INDEX_NAME
- end
- end
-
- def down
- execute "TRUNCATE user_interacted_projects"
-
- if foreign_key_exists?(:user_interacted_projects, :users)
- remove_foreign_key :user_interacted_projects, :users
- end
-
- if foreign_key_exists?(:user_interacted_projects, :projects)
- remove_foreign_key :user_interacted_projects, :projects
- end
-
- if index_exists_by_name?(:user_interacted_projects, UNIQUE_INDEX_NAME)
- remove_concurrent_index_by_name :user_interacted_projects, UNIQUE_INDEX_NAME
- end
-
- unless index_exists_by_name?(:user_interacted_projects, CreateUserInteractedProjectsTable::INDEX_NAME)
- add_concurrent_index :user_interacted_projects, [:project_id, :user_id], name: CreateUserInteractedProjectsTable::INDEX_NAME
- end
- end
-
- class PostgresStrategy < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- BATCH_SIZE = 100_000
- SLEEP_TIME = 5
-
- def up
- with_index(:events, [:author_id, :project_id], name: 'events_user_interactions_temp', where: 'project_id IS NOT NULL') do
- insert_missing_records
-
- # Do this once without lock to speed up the second invocation
- remove_duplicates
- with_table_lock(:user_interacted_projects) do
- remove_duplicates
- create_unique_index
- end
-
- remove_without_project
- with_table_lock(:user_interacted_projects, :projects) do
- remove_without_project
- create_fk :user_interacted_projects, :projects, :project_id
- end
-
- remove_without_user
- with_table_lock(:user_interacted_projects, :users) do
- remove_without_user
- create_fk :user_interacted_projects, :users, :user_id
- end
- end
-
- execute "ANALYZE user_interacted_projects"
- end
-
- private
-
- def insert_missing_records
- iteration = 0
- records = 0
- begin
- Rails.logger.info "Building user_interacted_projects table, batch ##{iteration}" # rubocop:disable Gitlab/RailsLogger
- result = execute <<~SQL
- INSERT INTO user_interacted_projects (user_id, project_id)
- SELECT e.user_id, e.project_id
- FROM (SELECT DISTINCT author_id AS user_id, project_id FROM events WHERE project_id IS NOT NULL) AS e
- LEFT JOIN user_interacted_projects ucp USING (user_id, project_id)
- WHERE ucp.user_id IS NULL
- LIMIT #{BATCH_SIZE}
- SQL
- iteration += 1
- records += result.cmd_tuples
- Rails.logger.info "Building user_interacted_projects table, batch ##{iteration} complete, created #{records} overall" # rubocop:disable Gitlab/RailsLogger
- Kernel.sleep(SLEEP_TIME) if result.cmd_tuples > 0
- end while result.cmd_tuples > 0
- end
-
- def remove_duplicates
- execute <<~SQL
- WITH numbered AS (select ctid, ROW_NUMBER() OVER (PARTITION BY (user_id, project_id)) as row_number, user_id, project_id from user_interacted_projects)
- DELETE FROM user_interacted_projects WHERE ctid IN (SELECT ctid FROM numbered WHERE row_number > 1);
- SQL
- end
-
- def remove_without_project
- execute "DELETE FROM user_interacted_projects WHERE NOT EXISTS (SELECT 1 FROM projects WHERE id = user_interacted_projects.project_id)"
- end
-
- def remove_without_user
- execute "DELETE FROM user_interacted_projects WHERE NOT EXISTS (SELECT 1 FROM users WHERE id = user_interacted_projects.user_id)"
- end
-
- def create_fk(table, target, column)
- return if foreign_key_exists?(table, target, column: column)
-
- add_foreign_key table, target, column: column, on_delete: :cascade
- end
-
- def create_unique_index
- return if index_exists_by_name?(:user_interacted_projects, UNIQUE_INDEX_NAME)
-
- add_index :user_interacted_projects, [:project_id, :user_id], unique: true, name: UNIQUE_INDEX_NAME
- end
-
- # Protect table against concurrent data changes while still allowing reads
- def with_table_lock(*tables)
- ActiveRecord::Base.connection.transaction do
- execute "LOCK TABLE #{tables.join(", ")} IN SHARE MODE"
- yield
- end
- end
-
- def with_index(*args)
- add_concurrent_index(*args) unless index_exists?(*args)
- yield
- ensure
- remove_concurrent_index(*args) if index_exists?(*args)
- end
- end
-end
diff --git a/db/post_migrate/20180301084653_change_project_namespace_id_not_null.rb b/db/post_migrate/20180301084653_change_project_namespace_id_not_null.rb
deleted file mode 100644
index 62a239b0e7c..00000000000
--- a/db/post_migrate/20180301084653_change_project_namespace_id_not_null.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class ChangeProjectNamespaceIdNotNull < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- class Project < ActiveRecord::Base
- self.table_name = 'projects'
- include EachBatch
- end
-
- BATCH_SIZE = 1000
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- Project.where(namespace_id: nil).each_batch(of: BATCH_SIZE) do |batch|
- batch.delete_all
- end
-
- change_column_null :projects, :namespace_id, false
- end
-
- def down
- change_column_null :projects, :namespace_id, true
- end
-end
diff --git a/db/post_migrate/20180305100050_remove_permanent_from_redirect_routes.rb b/db/post_migrate/20180305100050_remove_permanent_from_redirect_routes.rb
deleted file mode 100644
index e363642b2ac..00000000000
--- a/db/post_migrate/20180305100050_remove_permanent_from_redirect_routes.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class RemovePermanentFromRedirectRoutes < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- disable_ddl_transaction!
-
- INDEX_NAME_PERM = "index_redirect_routes_on_path_text_pattern_ops_where_permanent"
- INDEX_NAME_TEMP = "index_redirect_routes_on_path_text_pattern_ops_where_temporary"
-
- def up
- # These indexes were created on Postgres only in:
- # ReworkRedirectRoutesIndexes:
- # https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/16211
- disable_statement_timeout do
- execute "DROP INDEX CONCURRENTLY IF EXISTS #{INDEX_NAME_PERM};"
- execute "DROP INDEX CONCURRENTLY IF EXISTS #{INDEX_NAME_TEMP};"
- end
-
- remove_column(:redirect_routes, :permanent)
- end
-
- def down
- add_column(:redirect_routes, :permanent, :boolean)
-
- disable_statement_timeout do
- execute("CREATE INDEX CONCURRENTLY #{INDEX_NAME_PERM} ON redirect_routes (lower(path) varchar_pattern_ops) where (permanent);")
- execute("CREATE INDEX CONCURRENTLY #{INDEX_NAME_TEMP} ON redirect_routes (lower(path) varchar_pattern_ops) where (not permanent or permanent is null) ;")
- end
- end
-end
diff --git a/db/post_migrate/20180306074045_migrate_create_trace_artifact_sidekiq_queue.rb b/db/post_migrate/20180306074045_migrate_create_trace_artifact_sidekiq_queue.rb
deleted file mode 100644
index fc74f6f1712..00000000000
--- a/db/post_migrate/20180306074045_migrate_create_trace_artifact_sidekiq_queue.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-class MigrateCreateTraceArtifactSidekiqQueue < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- sidekiq_queue_migrate 'pipeline_default:create_trace_artifact', to: 'pipeline_background:archive_trace'
- end
-
- def down
- sidekiq_queue_migrate 'pipeline_background:archive_trace', to: 'pipeline_default:create_trace_artifact'
- end
-end
diff --git a/db/post_migrate/20180306164012_add_path_index_to_redirect_routes.rb b/db/post_migrate/20180306164012_add_path_index_to_redirect_routes.rb
deleted file mode 100644
index f0257e303f7..00000000000
--- a/db/post_migrate/20180306164012_add_path_index_to_redirect_routes.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddPathIndexToRedirectRoutes < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
- disable_ddl_transaction!
-
- INDEX_NAME = 'index_redirect_routes_on_path_unique_text_pattern_ops'
-
- # Indexing on LOWER(path) varchar_pattern_ops speeds up the LIKE query in
- # RedirectRoute.matching_path_and_descendants
- #
- # This same index is also added in the `ReworkRedirectRoutesIndexes` so this
- # is a no-op in most cases.
- def up
- disable_statement_timeout do
- unless index_exists_by_name?(:redirect_routes, INDEX_NAME)
- execute("CREATE UNIQUE INDEX CONCURRENTLY #{INDEX_NAME} ON redirect_routes (lower(path) varchar_pattern_ops);")
- end
- end
- end
-
- def down
- # Do nothing in the DOWN. Since the index above is originally created in the
- # `ReworkRedirectRoutesIndexes`. This migration wouldn't have actually
- # created any new index.
- end
-end
diff --git a/db/post_migrate/20180307012445_migrate_update_head_pipeline_for_merge_request_sidekiq_queue.rb b/db/post_migrate/20180307012445_migrate_update_head_pipeline_for_merge_request_sidekiq_queue.rb
deleted file mode 100644
index 372c04429c7..00000000000
--- a/db/post_migrate/20180307012445_migrate_update_head_pipeline_for_merge_request_sidekiq_queue.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class MigrateUpdateHeadPipelineForMergeRequestSidekiqQueue < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- sidekiq_queue_migrate 'pipeline_default:update_head_pipeline_for_merge_request',
- to: 'pipeline_processing:update_head_pipeline_for_merge_request'
- end
-
- def down
- sidekiq_queue_migrate 'pipeline_processing:update_head_pipeline_for_merge_request',
- to: 'pipeline_default:update_head_pipeline_for_merge_request'
- end
-end
diff --git a/db/post_migrate/20180405101928_reschedule_builds_stages_migration.rb b/db/post_migrate/20180405101928_reschedule_builds_stages_migration.rb
deleted file mode 100644
index 213d97b71f7..00000000000
--- a/db/post_migrate/20180405101928_reschedule_builds_stages_migration.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-class RescheduleBuildsStagesMigration < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- ##
- # Rescheduled `20180212101928_schedule_build_stage_migration.rb`
- #
-
- DOWNTIME = false
- MIGRATION = 'MigrateBuildStage'.freeze
- BATCH_SIZE = 500
-
- disable_ddl_transaction!
-
- class Build < ActiveRecord::Base
- include EachBatch
- self.table_name = 'ci_builds'
- end
-
- def up
- disable_statement_timeout do
- Build.where('stage_id IS NULL').tap do |relation|
- queue_background_migration_jobs_by_range_at_intervals(relation,
- MIGRATION,
- 5.minutes,
- batch_size: BATCH_SIZE)
- end
- end
- end
-
- def down
- # noop
- end
-end
diff --git a/db/post_migrate/20180408143355_cleanup_users_rss_token_rename.rb b/db/post_migrate/20180408143355_cleanup_users_rss_token_rename.rb
deleted file mode 100644
index 813603cb3ad..00000000000
--- a/db/post_migrate/20180408143355_cleanup_users_rss_token_rename.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-class CleanupUsersRssTokenRename < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- disable_ddl_transaction!
-
- def up
- cleanup_concurrent_column_rename :users, :rss_token, :feed_token
- end
-
- def down
- # rubocop:disable Migration/UpdateLargeTable
- rename_column_concurrently :users, :feed_token, :rss_token
- end
-end
diff --git a/db/post_migrate/20180409170809_populate_missing_project_ci_cd_settings.rb b/db/post_migrate/20180409170809_populate_missing_project_ci_cd_settings.rb
deleted file mode 100644
index a400a071e07..00000000000
--- a/db/post_migrate/20180409170809_populate_missing_project_ci_cd_settings.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class PopulateMissingProjectCiCdSettings < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- # Projects created after the initial migration but before the code started
- # using ProjectCiCdSetting won't have a corresponding row in
- # project_ci_cd_settings, so let's fix that.
- execute <<~SQL
- INSERT INTO project_ci_cd_settings (project_id)
- SELECT id
- FROM projects
- WHERE NOT EXISTS (
- SELECT 1
- FROM project_ci_cd_settings
- WHERE project_ci_cd_settings.project_id = projects.id
- )
- SQL
- end
-
- def down
- # There's nothing to revert for this migration.
- end
-end
diff --git a/db/post_migrate/20180420080616_schedule_stages_index_migration.rb b/db/post_migrate/20180420080616_schedule_stages_index_migration.rb
deleted file mode 100644
index 2d72e75393f..00000000000
--- a/db/post_migrate/20180420080616_schedule_stages_index_migration.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-class ScheduleStagesIndexMigration < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- MIGRATION = 'MigrateStageIndex'.freeze
- BATCH_SIZE = 10000
-
- disable_ddl_transaction!
-
- class Stage < ActiveRecord::Base
- include EachBatch
- self.table_name = 'ci_stages'
- end
-
- def up
- disable_statement_timeout do
- Stage.all.tap do |relation|
- queue_background_migration_jobs_by_range_at_intervals(relation,
- MIGRATION,
- 5.minutes,
- batch_size: BATCH_SIZE)
- end
- end
- end
-
- def down
- # noop
- end
-end
diff --git a/db/post_migrate/20180424151928_fill_file_store.rb b/db/post_migrate/20180424151928_fill_file_store.rb
deleted file mode 100644
index 45fa10c9550..00000000000
--- a/db/post_migrate/20180424151928_fill_file_store.rb
+++ /dev/null
@@ -1,72 +0,0 @@
-class FillFileStore < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- class JobArtifact < ActiveRecord::Base
- include EachBatch
- self.table_name = 'ci_job_artifacts'
- BATCH_SIZE = 10_000
-
- def self.params_for_background_migration
- yield self.where(file_store: nil), 'FillFileStoreJobArtifact', 5.minutes, BATCH_SIZE
- end
- end
-
- class LfsObject < ActiveRecord::Base
- include EachBatch
- self.table_name = 'lfs_objects'
- BATCH_SIZE = 10_000
-
- def self.params_for_background_migration
- yield self.where(file_store: nil), 'FillFileStoreLfsObject', 5.minutes, BATCH_SIZE
- end
- end
-
- class Upload < ActiveRecord::Base
- include EachBatch
- self.table_name = 'uploads'
- self.inheritance_column = :_type_disabled # Disable STI
- BATCH_SIZE = 10_000
-
- def self.params_for_background_migration
- yield self.where(store: nil), 'FillStoreUpload', 5.minutes, BATCH_SIZE
- end
- end
-
- def up
- # NOTE: Schedule background migrations that fill 'NULL' value by '1'(ObjectStorage::Store::LOCAL) on `file_store`, `store` columns
- #
- # Here are the target columns
- # - ci_job_artifacts.file_store
- # - lfs_objects.file_store
- # - uploads.store
-
- FillFileStore::JobArtifact.params_for_background_migration do |relation, class_name, delay_interval, batch_size|
- queue_background_migration_jobs_by_range_at_intervals(relation,
- class_name,
- delay_interval,
- batch_size: batch_size)
- end
-
- FillFileStore::LfsObject.params_for_background_migration do |relation, class_name, delay_interval, batch_size|
- queue_background_migration_jobs_by_range_at_intervals(relation,
- class_name,
- delay_interval,
- batch_size: batch_size)
- end
-
- FillFileStore::Upload.params_for_background_migration do |relation, class_name, delay_interval, batch_size|
- queue_background_migration_jobs_by_range_at_intervals(relation,
- class_name,
- delay_interval,
- batch_size: batch_size)
- end
- end
-
- def down
- # noop
- end
-end
diff --git a/db/post_migrate/20180430143705_backfill_runner_type_for_ci_runners_post_migrate.rb b/db/post_migrate/20180430143705_backfill_runner_type_for_ci_runners_post_migrate.rb
deleted file mode 100644
index ba1023866c5..00000000000
--- a/db/post_migrate/20180430143705_backfill_runner_type_for_ci_runners_post_migrate.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-class BackfillRunnerTypeForCiRunnersPostMigrate < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- INSTANCE_RUNNER_TYPE = 1
- PROJECT_RUNNER_TYPE = 3
-
- disable_ddl_transaction!
-
- def up
- # rubocop:disable Migration/UpdateColumnInBatches
- update_column_in_batches(:ci_runners, :runner_type, INSTANCE_RUNNER_TYPE) do |table, query|
- query.where(table[:is_shared].eq(true)).where(table[:runner_type].eq(nil))
- end
-
- update_column_in_batches(:ci_runners, :runner_type, PROJECT_RUNNER_TYPE) do |table, query|
- query.where(table[:is_shared].eq(false)).where(table[:runner_type].eq(nil))
- end
- end
-
- def down
- end
-end
diff --git a/db/post_migrate/20180507083701_set_minimal_project_build_timeout.rb b/db/post_migrate/20180507083701_set_minimal_project_build_timeout.rb
deleted file mode 100644
index 34edbb08bcf..00000000000
--- a/db/post_migrate/20180507083701_set_minimal_project_build_timeout.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-class SetMinimalProjectBuildTimeout < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- MINIMUM_TIMEOUT = 600
-
- # Allow this migration to resume if it fails partway through
- disable_ddl_transaction!
-
- def up
- # rubocop:disable Migration/UpdateLargeTable
- # rubocop:disable Migration/UpdateColumnInBatches
- update_column_in_batches(:projects, :build_timeout, MINIMUM_TIMEOUT) do |table, query|
- query.where(table[:build_timeout].lt(MINIMUM_TIMEOUT))
- end
- end
-
- def down
- # no-op
- end
-end
diff --git a/db/post_migrate/20180511174224_add_unique_constraint_to_project_features_project_id.rb b/db/post_migrate/20180511174224_add_unique_constraint_to_project_features_project_id.rb
deleted file mode 100644
index a526001a91e..00000000000
--- a/db/post_migrate/20180511174224_add_unique_constraint_to_project_features_project_id.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-class AddUniqueConstraintToProjectFeaturesProjectId < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- class ProjectFeature < ActiveRecord::Base
- self.table_name = 'project_features'
-
- include EachBatch
- end
-
- def up
- remove_duplicates
-
- add_concurrent_index :project_features, :project_id, unique: true, name: 'index_project_features_on_project_id_unique'
- remove_concurrent_index_by_name :project_features, 'index_project_features_on_project_id'
- rename_index :project_features, 'index_project_features_on_project_id_unique', 'index_project_features_on_project_id'
- end
-
- def down
- rename_index :project_features, 'index_project_features_on_project_id', 'index_project_features_on_project_id_old'
- add_concurrent_index :project_features, :project_id
- remove_concurrent_index_by_name :project_features, 'index_project_features_on_project_id_old'
- end
-
- private
-
- def remove_duplicates
- features = ProjectFeature
- .select('MAX(id) AS max, COUNT(id), project_id')
- .group(:project_id)
- .having('COUNT(id) > 1')
-
- features.each do |feature|
- ProjectFeature
- .where(project_id: feature['project_id'])
- .where('id <> ?', feature['max'])
- .each_batch { |batch| batch.delete_all }
- end
- end
-end
diff --git a/db/post_migrate/20180512061621_add_not_null_constraint_to_project_features_project_id.rb b/db/post_migrate/20180512061621_add_not_null_constraint_to_project_features_project_id.rb
deleted file mode 100644
index e3abbc039e8..00000000000
--- a/db/post_migrate/20180512061621_add_not_null_constraint_to_project_features_project_id.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-class AddNotNullConstraintToProjectFeaturesProjectId < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- class ProjectFeature < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'project_features'
- end
-
- def up
- ProjectFeature.where(project_id: nil).delete_all
-
- change_column_null :project_features, :project_id, false
- end
-
- def down
- change_column_null :project_features, :project_id, true
- end
-end
diff --git a/db/post_migrate/20180514161336_remove_gemnasium_service.rb b/db/post_migrate/20180514161336_remove_gemnasium_service.rb
deleted file mode 100644
index 5842bde474c..00000000000
--- a/db/post_migrate/20180514161336_remove_gemnasium_service.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class RemoveGemnasiumService < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- disable_statement_timeout
-
- execute("DELETE FROM services WHERE type='GemnasiumService';")
- end
-
- def down
- # noop
- end
-end
diff --git a/db/post_migrate/20180523125103_cleanup_merge_requests_allow_maintainer_to_push_rename.rb b/db/post_migrate/20180523125103_cleanup_merge_requests_allow_maintainer_to_push_rename.rb
deleted file mode 100644
index b3b539fd156..00000000000
--- a/db/post_migrate/20180523125103_cleanup_merge_requests_allow_maintainer_to_push_rename.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-class CleanupMergeRequestsAllowMaintainerToPushRename < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- # NOOP
- end
-
- def down
- if column_exists?(:merge_requests, :allow_collaboration)
- # rubocop:disable Migration/UpdateLargeTable
- rename_column_concurrently :merge_requests, :allow_collaboration, :allow_maintainer_to_push
- end
- end
-end
diff --git a/db/post_migrate/20180529152628_schedule_to_archive_legacy_traces.rb b/db/post_migrate/20180529152628_schedule_to_archive_legacy_traces.rb
deleted file mode 100644
index 6246f6afab0..00000000000
--- a/db/post_migrate/20180529152628_schedule_to_archive_legacy_traces.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-class ScheduleToArchiveLegacyTraces < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- BATCH_SIZE = 5000
- BACKGROUND_MIGRATION_CLASS = 'ArchiveLegacyTraces'
-
- disable_ddl_transaction!
-
- class Build < ActiveRecord::Base
- include EachBatch
- self.table_name = 'ci_builds'
- self.inheritance_column = :_type_disabled # Disable STI
-
- scope :type_build, -> { where(type: 'Ci::Build') }
-
- scope :finished, -> { where(status: [:success, :failed, :canceled]) }
-
- scope :without_archived_trace, -> do
- where('NOT EXISTS (SELECT 1 FROM ci_job_artifacts WHERE ci_builds.id = ci_job_artifacts.job_id AND ci_job_artifacts.file_type = 3)')
- end
- end
-
- def up
- queue_background_migration_jobs_by_range_at_intervals(
- ::ScheduleToArchiveLegacyTraces::Build.type_build.finished.without_archived_trace,
- BACKGROUND_MIGRATION_CLASS,
- 5.minutes,
- batch_size: BATCH_SIZE)
- end
-
- def down
- # noop
- end
-end
diff --git a/db/post_migrate/20180603190921_migrate_object_storage_upload_sidekiq_queue.rb b/db/post_migrate/20180603190921_migrate_object_storage_upload_sidekiq_queue.rb
deleted file mode 100644
index bc7c3eb5385..00000000000
--- a/db/post_migrate/20180603190921_migrate_object_storage_upload_sidekiq_queue.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-class MigrateObjectStorageUploadSidekiqQueue < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- sidekiq_queue_migrate 'object_storage_upload', to: 'object_storage:object_storage_background_move'
- end
-
- def down
- # do not migrate any jobs back because we would migrate also
- # jobs which were not part of the 'object_storage_upload'
- end
-end
diff --git a/db/post_migrate/20180604123514_cleanup_stages_position_migration.rb b/db/post_migrate/20180604123514_cleanup_stages_position_migration.rb
deleted file mode 100644
index 326cdfa27c3..00000000000
--- a/db/post_migrate/20180604123514_cleanup_stages_position_migration.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-class CleanupStagesPositionMigration < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- TMP_INDEX_NAME = 'tmp_id_stage_position_partial_null_index'.freeze
-
- disable_ddl_transaction!
-
- class Stages < ActiveRecord::Base
- include EachBatch
- self.table_name = 'ci_stages'
- end
-
- def up
- disable_statement_timeout do
- Gitlab::BackgroundMigration.steal('MigrateStageIndex')
-
- unless index_exists_by_name?(:ci_stages, TMP_INDEX_NAME)
- add_concurrent_index(:ci_stages, :id, where: 'position IS NULL', name: TMP_INDEX_NAME)
- end
-
- migratable = <<~SQL
- position IS NULL AND EXISTS (
- SELECT 1 FROM ci_builds WHERE stage_id = ci_stages.id AND stage_idx IS NOT NULL
- )
- SQL
-
- Stages.where(migratable).each_batch(of: 1000) do |batch|
- batch.pluck(:id).each do |stage|
- Gitlab::BackgroundMigration::MigrateStageIndex.new.perform(stage, stage)
- end
- end
-
- remove_concurrent_index_by_name(:ci_stages, TMP_INDEX_NAME)
- end
- end
-
- def down
- if index_exists_by_name?(:ci_stages, TMP_INDEX_NAME)
- disable_statement_timeout do
- remove_concurrent_index_by_name(:ci_stages, TMP_INDEX_NAME)
- end
- end
- end
-end
diff --git a/db/post_migrate/20180608201435_cleanup_merge_requests_allow_collaboration_rename.rb b/db/post_migrate/20180608201435_cleanup_merge_requests_allow_collaboration_rename.rb
deleted file mode 100644
index 5e892f8bace..00000000000
--- a/db/post_migrate/20180608201435_cleanup_merge_requests_allow_collaboration_rename.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class CleanupMergeRequestsAllowCollaborationRename < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- if column_exists?(:merge_requests, :allow_collaboration)
- cleanup_concurrent_column_rename :merge_requests, :allow_collaboration, :allow_maintainer_to_push
- end
- end
-
- def down
- # NOOP
- end
-end
diff --git a/db/post_migrate/20180629191052_add_partial_index_to_projects_for_last_repository_check_at.rb b/db/post_migrate/20180629191052_add_partial_index_to_projects_for_last_repository_check_at.rb
deleted file mode 100644
index 15c02cd77b8..00000000000
--- a/db/post_migrate/20180629191052_add_partial_index_to_projects_for_last_repository_check_at.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-class AddPartialIndexToProjectsForLastRepositoryCheckAt < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- INDEX_NAME = "index_projects_on_last_repository_check_at"
-
- def up
- add_concurrent_index(:projects, :last_repository_check_at, where: "last_repository_check_at IS NOT NULL", name: INDEX_NAME)
- end
-
- def down
- remove_concurrent_index(:projects, :last_repository_check_at, where: "last_repository_check_at IS NOT NULL", name: INDEX_NAME)
- end
-end
diff --git a/db/post_migrate/20180702120647_enqueue_fix_cross_project_label_links.rb b/db/post_migrate/20180702120647_enqueue_fix_cross_project_label_links.rb
deleted file mode 100644
index 3d3d49e7564..00000000000
--- a/db/post_migrate/20180702120647_enqueue_fix_cross_project_label_links.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-class EnqueueFixCrossProjectLabelLinks < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- BATCH_SIZE = 100
- MIGRATION = 'FixCrossProjectLabelLinks'
- DELAY_INTERVAL = 5.minutes
-
- disable_ddl_transaction!
-
- class Label < ActiveRecord::Base
- self.table_name = 'labels'
- end
-
- class Namespace < ActiveRecord::Base
- self.table_name = 'namespaces'
-
- include ::EachBatch
-
- default_scope { where(type: 'Group', id: Label.where(type: 'GroupLabel').select('distinct group_id')) }
- end
-
- def up
- queue_background_migration_jobs_by_range_at_intervals(Namespace, MIGRATION, DELAY_INTERVAL, batch_size: BATCH_SIZE)
- end
-
- def down
- # noop
- end
-end
diff --git a/db/post_migrate/20180704145007_update_project_indexes.rb b/db/post_migrate/20180704145007_update_project_indexes.rb
deleted file mode 100644
index 0a82f4535a0..00000000000
--- a/db/post_migrate/20180704145007_update_project_indexes.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class UpdateProjectIndexes < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- NEW_INDEX_NAME = 'idx_project_repository_check_partial'
-
- disable_ddl_transaction!
-
- def up
- add_concurrent_index(:projects,
- [:repository_storage, :created_at],
- name: NEW_INDEX_NAME,
- where: 'last_repository_check_at IS NULL'
- )
- end
-
- def down
- remove_concurrent_index_by_name(:projects, NEW_INDEX_NAME)
- end
-end
diff --git a/db/post_migrate/20180706223200_populate_site_statistics.rb b/db/post_migrate/20180706223200_populate_site_statistics.rb
deleted file mode 100644
index 6f887a0c18f..00000000000
--- a/db/post_migrate/20180706223200_populate_site_statistics.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-class PopulateSiteStatistics < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- transaction do
- execute('SET LOCAL statement_timeout TO 0') # see https://gitlab.com/gitlab-org/gitlab-foss/issues/48967
-
- execute("UPDATE site_statistics SET repositories_count = (SELECT COUNT(*) FROM projects)")
- end
-
- transaction do
- execute('SET LOCAL statement_timeout TO 0') # see https://gitlab.com/gitlab-org/gitlab-foss/issues/48967
-
- execute("UPDATE site_statistics SET wikis_count = (SELECT COUNT(*) FROM project_features WHERE wiki_access_level != 0)")
- end
- end
-
- def down
- # No downside in keeping the counter up-to-date
- end
-end
diff --git a/db/post_migrate/20180809195358_migrate_null_wiki_access_levels.rb b/db/post_migrate/20180809195358_migrate_null_wiki_access_levels.rb
deleted file mode 100644
index b272bad7f92..00000000000
--- a/db/post_migrate/20180809195358_migrate_null_wiki_access_levels.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-class MigrateNullWikiAccessLevels < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- class ProjectFeature < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'project_features'
- end
-
- def up
- ProjectFeature.where(wiki_access_level: nil).each_batch do |relation|
- relation.update_all(wiki_access_level: 20)
- end
-
- # We need to re-count wikis as previous attempt was not considering the NULLs.
- transaction do
- execute('SET LOCAL statement_timeout TO 0') # see https://gitlab.com/gitlab-org/gitlab-foss/issues/48967
-
- execute("UPDATE site_statistics SET wikis_count = (SELECT COUNT(*) FROM project_features WHERE wiki_access_level != 0)")
- end
- end
-
- def down
- # there is no way to rollback this change, there are no downsides in keeping migrated data.
- end
-end
diff --git a/db/post_migrate/20180816161409_migrate_legacy_artifacts_to_job_artifacts.rb b/db/post_migrate/20180816161409_migrate_legacy_artifacts_to_job_artifacts.rb
deleted file mode 100644
index 6b0d1ef0d0c..00000000000
--- a/db/post_migrate/20180816161409_migrate_legacy_artifacts_to_job_artifacts.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-class MigrateLegacyArtifactsToJobArtifacts < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- MIGRATION = 'MigrateLegacyArtifacts'.freeze
- BATCH_SIZE = 100
-
- disable_ddl_transaction!
-
- class Build < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'ci_builds'
- self.inheritance_column = :_type_disabled
-
- scope :with_legacy_artifacts, -> { where("artifacts_file <> ''") }
- end
-
- def up
- MigrateLegacyArtifactsToJobArtifacts::Build
- .with_legacy_artifacts.tap do |relation|
- queue_background_migration_jobs_by_range_at_intervals(relation,
- MIGRATION,
- 5.minutes,
- batch_size: BATCH_SIZE)
- end
- end
-
- def down
- # no-op
- end
-end
diff --git a/db/post_migrate/20180816193530_rename_login_root_namespaces.rb b/db/post_migrate/20180816193530_rename_login_root_namespaces.rb
deleted file mode 100644
index 70db8f46d05..00000000000
--- a/db/post_migrate/20180816193530_rename_login_root_namespaces.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-class RenameLoginRootNamespaces < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
- include Gitlab::Database::RenameReservedPathsMigration::V1
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- # We're taking over the /login namespace as part of a fix for the Jira integration
- def up
- disable_statement_timeout do
- rename_root_paths 'login'
- end
- end
-
- def down
- disable_statement_timeout do
- revert_renames
- end
- end
-end
diff --git a/db/post_migrate/20180826111825_recalculate_site_statistics.rb b/db/post_migrate/20180826111825_recalculate_site_statistics.rb
deleted file mode 100644
index 938707c9ba4..00000000000
--- a/db/post_migrate/20180826111825_recalculate_site_statistics.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-# frozen_string_literal: true
-
-class RecalculateSiteStatistics < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- transaction do
- execute('SET LOCAL statement_timeout TO 0') # see https://gitlab.com/gitlab-org/gitlab-foss/issues/48967
-
- execute("UPDATE site_statistics SET repositories_count = (SELECT COUNT(*) FROM projects)")
- end
-
- transaction do
- execute('SET LOCAL statement_timeout TO 0') # see https://gitlab.com/gitlab-org/gitlab-foss/issues/48967
-
- execute("UPDATE site_statistics SET wikis_count = (SELECT COUNT(*) FROM project_features WHERE wiki_access_level != 0)")
- end
- end
-
- def down
- # No downside in keeping the counter up-to-date
- end
-end
diff --git a/db/post_migrate/20180913142237_schedule_digest_personal_access_tokens.rb b/db/post_migrate/20180913142237_schedule_digest_personal_access_tokens.rb
deleted file mode 100644
index 951cb3b088c..00000000000
--- a/db/post_migrate/20180913142237_schedule_digest_personal_access_tokens.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-class ScheduleDigestPersonalAccessTokens < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- BATCH_SIZE = 10_000
- MIGRATION = 'DigestColumn'
- DELAY_INTERVAL = 5.minutes.to_i
-
- disable_ddl_transaction!
-
- class PersonalAccessToken < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'personal_access_tokens'
- end
-
- def up
- PersonalAccessToken.where('token is NOT NULL').each_batch(of: BATCH_SIZE) do |batch, index|
- range = batch.pluck('MIN(id)', 'MAX(id)').first
- BackgroundMigrationWorker.perform_in(index * DELAY_INTERVAL, MIGRATION, ['PersonalAccessToken', :token, :token_digest, *range])
- end
- end
-
- def down
- # raise ActiveRecord::IrreversibleMigration
- end
-end
diff --git a/db/post_migrate/20180914162043_encrypt_web_hooks_columns.rb b/db/post_migrate/20180914162043_encrypt_web_hooks_columns.rb
deleted file mode 100644
index ef864f490bb..00000000000
--- a/db/post_migrate/20180914162043_encrypt_web_hooks_columns.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-# frozen_string_literal: true
-
-class EncryptWebHooksColumns < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- BATCH_SIZE = 10000
- RANGE_SIZE = 100
- MIGRATION = 'EncryptColumns'
- COLUMNS = [:token, :url]
-
- WebHook = ::Gitlab::BackgroundMigration::Models::EncryptColumns::WebHook
-
- disable_ddl_transaction!
-
- def up
- WebHook.each_batch(of: BATCH_SIZE) do |relation, index|
- delay = index * 2.minutes
-
- relation.each_batch(of: RANGE_SIZE) do |relation|
- range = relation.pluck('MIN(id)', 'MAX(id)').first
- args = [WebHook, COLUMNS, *range]
-
- BackgroundMigrationWorker.perform_in(delay, MIGRATION, args)
- end
- end
- end
-
- def down
- # noop
- end
-end
diff --git a/db/post_migrate/20180914201132_remove_sidekiq_throttling_from_application_settings.rb b/db/post_migrate/20180914201132_remove_sidekiq_throttling_from_application_settings.rb
deleted file mode 100644
index 2c007ec395d..00000000000
--- a/db/post_migrate/20180914201132_remove_sidekiq_throttling_from_application_settings.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class RemoveSidekiqThrottlingFromApplicationSettings < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- remove_column :application_settings, :sidekiq_throttling_enabled, :boolean, default: false
- remove_column :application_settings, :sidekiq_throttling_queues, :string
- remove_column :application_settings, :sidekiq_throttling_factor, :decimal
-
- Rails.cache.delete("ApplicationSetting:#{Gitlab::VERSION}:#{Rails.version}")
- end
-end
diff --git a/db/post_migrate/20180917172041_remove_wikis_count_from_site_statistics.rb b/db/post_migrate/20180917172041_remove_wikis_count_from_site_statistics.rb
deleted file mode 100644
index 3b8300dabeb..00000000000
--- a/db/post_migrate/20180917172041_remove_wikis_count_from_site_statistics.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-# frozen_string_literal: true
-class RemoveWikisCountFromSiteStatistics < ActiveRecord::Migration[4.2]
- def change
- remove_column :site_statistics, :wikis_count, :integer
- end
-end
diff --git a/db/post_migrate/20181008145341_steal_encrypt_columns.rb b/db/post_migrate/20181008145341_steal_encrypt_columns.rb
deleted file mode 100644
index 4102643ba13..00000000000
--- a/db/post_migrate/20181008145341_steal_encrypt_columns.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class StealEncryptColumns < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- Gitlab::BackgroundMigration.steal('EncryptColumns')
- end
-
- def down
- # no-op
- end
-end
diff --git a/db/post_migrate/20181008145359_remove_web_hooks_token_and_url.rb b/db/post_migrate/20181008145359_remove_web_hooks_token_and_url.rb
deleted file mode 100644
index 93e4458b795..00000000000
--- a/db/post_migrate/20181008145359_remove_web_hooks_token_and_url.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-class RemoveWebHooksTokenAndUrl < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- remove_column :web_hooks, :token, :string
- remove_column :web_hooks, :url, :string, limit: 2000
- end
-end
diff --git a/db/post_migrate/20181008200441_remove_circuit_breaker.rb b/db/post_migrate/20181008200441_remove_circuit_breaker.rb
deleted file mode 100644
index 09491038e50..00000000000
--- a/db/post_migrate/20181008200441_remove_circuit_breaker.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-class RemoveCircuitBreaker < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- # Set this constant to true if this migration requires downtime.
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- CIRCUIT_BREAKER_COLUMS_WITH_DEFAULT = {
- circuitbreaker_failure_count_threshold: 3,
- circuitbreaker_failure_reset_time: 1800,
- circuitbreaker_storage_timeout: 15,
- circuitbreaker_access_retries: 3,
- circuitbreaker_check_interval: 1
- }.freeze
-
- def up
- CIRCUIT_BREAKER_COLUMS_WITH_DEFAULT.keys.each do |column|
- remove_column(:application_settings, column) if column_exists?(:application_settings, column)
- end
- end
-
- def down
- CIRCUIT_BREAKER_COLUMS_WITH_DEFAULT.each do |column, default|
- # rubocop:disable Migration/AddColumnWithDefault
- add_column_with_default(:application_settings, column, :integer, default: default) unless column_exists?(:application_settings, column)
- # rubocop:enable Migration/AddColumnWithDefault
- end
- end
-end
diff --git a/db/post_migrate/20181010133639_backfill_store_project_full_path_in_repo.rb b/db/post_migrate/20181010133639_backfill_store_project_full_path_in_repo.rb
deleted file mode 100644
index 247f5980f7e..00000000000
--- a/db/post_migrate/20181010133639_backfill_store_project_full_path_in_repo.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-# frozen_string_literal: true
-
-class BackfillStoreProjectFullPathInRepo < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- BATCH_SIZE = 1_000
- DELAY_INTERVAL = 5.minutes
- UP_MIGRATION = 'BackfillProjectFullpathInRepoConfig::Up'
- DOWN_MIGRATION = 'BackfillProjectFullpathInRepoConfig::Down'
-
- disable_ddl_transaction!
-
- class Project < ActiveRecord::Base
- self.table_name = 'projects'
-
- include EachBatch
- end
-
- def up
- queue_background_migration_jobs_by_range_at_intervals(Project, UP_MIGRATION, DELAY_INTERVAL)
- end
-
- def down
- queue_background_migration_jobs_by_range_at_intervals(Project, DOWN_MIGRATION, DELAY_INTERVAL)
- end
-end
diff --git a/db/post_migrate/20181013005024_remove_koding_from_application_settings.rb b/db/post_migrate/20181013005024_remove_koding_from_application_settings.rb
deleted file mode 100644
index 550ad94f4ab..00000000000
--- a/db/post_migrate/20181013005024_remove_koding_from_application_settings.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class RemoveKodingFromApplicationSettings < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- remove_column :application_settings, :koding_enabled
- remove_column :application_settings, :koding_url
- end
-
- def down
- add_column :application_settings, :koding_enabled, :boolean # rubocop:disable Migration/SaferBooleanColumn
- add_column :application_settings, :koding_url, :string
- end
-end
diff --git a/db/post_migrate/20181022173835_enqueue_populate_cluster_kubernetes_namespace.rb b/db/post_migrate/20181022173835_enqueue_populate_cluster_kubernetes_namespace.rb
deleted file mode 100644
index 94a4574abff..00000000000
--- a/db/post_migrate/20181022173835_enqueue_populate_cluster_kubernetes_namespace.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-class EnqueuePopulateClusterKubernetesNamespace < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- MIGRATION = 'PopulateClusterKubernetesNamespaceTable'.freeze
-
- disable_ddl_transaction!
-
- def up
- BackgroundMigrationWorker.perform_async(MIGRATION)
- end
-
- def down
- Clusters::KubernetesNamespace.delete_all
- end
-end
diff --git a/db/post_migrate/20181026091631_migrate_forbidden_redirect_uris.rb b/db/post_migrate/20181026091631_migrate_forbidden_redirect_uris.rb
deleted file mode 100644
index 7c2df832882..00000000000
--- a/db/post_migrate/20181026091631_migrate_forbidden_redirect_uris.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-class MigrateForbiddenRedirectUris < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- FORBIDDEN_SCHEMES = %w[data:// vbscript:// javascript://]
- NEW_URI = 'http://forbidden-scheme-has-been-overwritten'
-
- disable_ddl_transaction!
-
- def up
- update_forbidden_uris(:oauth_applications)
- update_forbidden_uris(:oauth_access_grants)
- end
-
- def down
- # noop
- end
-
- private
-
- def update_forbidden_uris(table_name)
- update_column_in_batches(table_name, :redirect_uri, NEW_URI) do |table, query|
- where_clause = FORBIDDEN_SCHEMES.map do |scheme|
- table[:redirect_uri].matches("#{scheme}%")
- end.inject(&:or)
-
- query.where(where_clause)
- end
- end
-end
diff --git a/db/post_migrate/20181030135124_fill_empty_finished_at_in_deployments.rb b/db/post_migrate/20181030135124_fill_empty_finished_at_in_deployments.rb
deleted file mode 100644
index 228841a14a0..00000000000
--- a/db/post_migrate/20181030135124_fill_empty_finished_at_in_deployments.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-# frozen_string_literal: true
-
-class FillEmptyFinishedAtInDeployments < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- DEPLOYMENT_STATUS_SUCCESS = 2 # Equivalent to Deployment.statuses[:success]
-
- class Deployments < ActiveRecord::Base
- self.table_name = 'deployments'
-
- include EachBatch
- end
-
- def up
- FillEmptyFinishedAtInDeployments::Deployments
- .where('finished_at IS NULL')
- .where('status = ?', DEPLOYMENT_STATUS_SUCCESS)
- .each_batch(of: 10_000) do |relation|
- relation.update_all('finished_at=created_at')
- end
- end
-
- def down
- # no-op
- end
-end
diff --git a/db/post_migrate/20181101091005_steal_digest_column.rb b/db/post_migrate/20181101091005_steal_digest_column.rb
deleted file mode 100644
index 58ea710c18a..00000000000
--- a/db/post_migrate/20181101091005_steal_digest_column.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class StealDigestColumn < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- disable_ddl_transaction!
-
- def up
- Gitlab::BackgroundMigration.steal('DigestColumn')
- end
-
- def down
- # raise ActiveRecord::IrreversibleMigration
- end
-end
diff --git a/db/post_migrate/20181101091124_remove_token_from_personal_access_tokens.rb b/db/post_migrate/20181101091124_remove_token_from_personal_access_tokens.rb
deleted file mode 100644
index 415373068d5..00000000000
--- a/db/post_migrate/20181101091124_remove_token_from_personal_access_tokens.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-class RemoveTokenFromPersonalAccessTokens < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def change
- remove_column :personal_access_tokens, :token, :string
- end
-end
diff --git a/db/post_migrate/20181105201455_steal_fill_store_upload.rb b/db/post_migrate/20181105201455_steal_fill_store_upload.rb
deleted file mode 100644
index a31a4eab472..00000000000
--- a/db/post_migrate/20181105201455_steal_fill_store_upload.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-# frozen_string_literal: true
-
-class StealFillStoreUpload < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- BATCH_SIZE = 10_000
-
- disable_ddl_transaction!
-
- class Upload < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'uploads'
- self.inheritance_column = :_type_disabled # Disable STI
- end
-
- def up
- Gitlab::BackgroundMigration.steal('FillStoreUpload')
-
- Upload.where(store: nil).each_batch(of: BATCH_SIZE) do |batch|
- range = batch.pluck('MIN(id)', 'MAX(id)').first
-
- Gitlab::BackgroundMigration::FillStoreUpload.new.perform(*range)
- end
- end
-
- def down
- # noop
- end
-end
diff --git a/db/post_migrate/20181107054254_remove_restricted_todos_again.rb b/db/post_migrate/20181107054254_remove_restricted_todos_again.rb
deleted file mode 100644
index bbeb4e8a1de..00000000000
--- a/db/post_migrate/20181107054254_remove_restricted_todos_again.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-# rescheduling of the revised RemoveRestrictedTodosWithCte background migration
-class RemoveRestrictedTodosAgain < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- disable_ddl_transaction!
-
- MIGRATION = 'RemoveRestrictedTodos'.freeze
- BATCH_SIZE = 1000
- DELAY_INTERVAL = 5.minutes.to_i
-
- class Project < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'projects'
- end
-
- def up
- Project.where('EXISTS (SELECT 1 FROM todos WHERE todos.project_id = projects.id)')
- .each_batch(of: BATCH_SIZE) do |batch, index|
- range = batch.pluck('MIN(id)', 'MAX(id)').first
-
- BackgroundMigrationWorker.perform_in(index * DELAY_INTERVAL, MIGRATION, range)
- end
- end
-
- def down
- # nothing to do
- end
-end
diff --git a/db/post_migrate/20181121111200_schedule_runners_token_encryption.rb b/db/post_migrate/20181121111200_schedule_runners_token_encryption.rb
deleted file mode 100644
index ba82072fc98..00000000000
--- a/db/post_migrate/20181121111200_schedule_runners_token_encryption.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-# frozen_string_literal: true
-
-class ScheduleRunnersTokenEncryption < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- BATCH_SIZE = 10000
- RANGE_SIZE = 2000
- MIGRATION = 'EncryptRunnersTokens'
-
- MODELS = [
- ::Gitlab::BackgroundMigration::Models::EncryptColumns::Settings,
- ::Gitlab::BackgroundMigration::Models::EncryptColumns::Namespace,
- ::Gitlab::BackgroundMigration::Models::EncryptColumns::Project,
- ::Gitlab::BackgroundMigration::Models::EncryptColumns::Runner
- ].freeze
-
- disable_ddl_transaction!
-
- def up
- MODELS.each do |model|
- model.each_batch(of: BATCH_SIZE) do |relation, index|
- delay = index * 4.minutes
-
- relation.each_batch(of: RANGE_SIZE) do |relation|
- range = relation.pluck('MIN(id)', 'MAX(id)').first
- args = [model.name.demodulize.downcase, *range]
-
- BackgroundMigrationWorker.perform_in(delay, MIGRATION, args)
- end
- end
- end
- end
-
- def down
- # no-op
- end
-end
diff --git a/db/post_migrate/20181123042307_drop_site_statistics.rb b/db/post_migrate/20181123042307_drop_site_statistics.rb
deleted file mode 100644
index 8986374ef65..00000000000
--- a/db/post_migrate/20181123042307_drop_site_statistics.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class DropSiteStatistics < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- drop_table :site_statistics
- end
-
- def down
- create_table :site_statistics do |t|
- t.integer :repositories_count, default: 0, null: false
- end
-
- execute('INSERT INTO site_statistics (id) VALUES(1)')
- end
-end
diff --git a/db/post_migrate/20181130102132_backfill_hashed_project_repositories.rb b/db/post_migrate/20181130102132_backfill_hashed_project_repositories.rb
deleted file mode 100644
index 7814cdba58a..00000000000
--- a/db/post_migrate/20181130102132_backfill_hashed_project_repositories.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-# frozen_string_literal: true
-
-class BackfillHashedProjectRepositories < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
- BATCH_SIZE = 1_000
- DELAY_INTERVAL = 5.minutes
- MIGRATION = 'BackfillHashedProjectRepositories'
-
- disable_ddl_transaction!
-
- class Project < ActiveRecord::Base
- include EachBatch
-
- self.table_name = 'projects'
- end
-
- def up
- queue_background_migration_jobs_by_range_at_intervals(Project, MIGRATION, DELAY_INTERVAL)
- end
-
- def down
- # no-op: since there could have been existing rows before the migration do not remove anything
- end
-end
diff --git a/db/post_migrate/20181219130552_update_project_import_visibility_level.rb b/db/post_migrate/20181219130552_update_project_import_visibility_level.rb
deleted file mode 100644
index bfa452578a3..00000000000
--- a/db/post_migrate/20181219130552_update_project_import_visibility_level.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-# frozen_string_literal: true
-
-class UpdateProjectImportVisibilityLevel < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- BATCH_SIZE = 100
-
- PRIVATE = 0
- INTERNAL = 10
-
- disable_ddl_transaction!
-
- class Namespace < ActiveRecord::Base
- self.table_name = 'namespaces'
- end
-
- class Project < ActiveRecord::Base
- include EachBatch
-
- belongs_to :namespace
-
- IMPORT_TYPE = 'gitlab_project'
-
- scope :with_group_visibility, ->(visibility) do
- joins(:namespace)
- .where(namespaces: { type: 'Group', visibility_level: visibility })
- .where(import_type: IMPORT_TYPE)
- .where('projects.visibility_level > namespaces.visibility_level')
- end
-
- self.table_name = 'projects'
- end
-
- def up
- # Update project's visibility to be the same as the group
- # if it is more restrictive than `PUBLIC`.
- update_projects_visibility(PRIVATE)
- update_projects_visibility(INTERNAL)
- end
-
- def down
- # no-op: unrecoverable data migration
- end
-
- private
-
- def update_projects_visibility(visibility)
- say_with_time("Updating project visibility to #{visibility} on #{Project::IMPORT_TYPE} imports.") do
- Project.with_group_visibility(visibility).select(:id).each_batch(of: BATCH_SIZE) do |batch, _index|
- batch_sql = batch.select(:id).to_sql
-
- say("Updating #{batch.size} items.", true)
-
- execute("UPDATE projects SET visibility_level = '#{visibility}' WHERE id IN (#{batch_sql})")
- end
- end
- end
-end
diff --git a/db/post_migrate/20181219145520_migrate_cluster_configure_worker_sidekiq_queue.rb b/db/post_migrate/20181219145520_migrate_cluster_configure_worker_sidekiq_queue.rb
deleted file mode 100644
index c37f8c039c0..00000000000
--- a/db/post_migrate/20181219145520_migrate_cluster_configure_worker_sidekiq_queue.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-class MigrateClusterConfigureWorkerSidekiqQueue < ActiveRecord::Migration[5.0]
- include Gitlab::Database::MigrationHelpers
-
- DOWNTIME = false
-
- def up
- sidekiq_queue_migrate 'gcp_cluster:cluster_platform_configure', to: 'gcp_cluster:cluster_configure'
- end
-
- def down
- sidekiq_queue_migrate 'gcp_cluster:cluster_configure', to: 'gcp_cluster:cluster_platform_configure'
- end
-end
diff --git a/db/post_migrate/20200310215714_migrate_saml_identities_to_scim_identities.rb b/db/post_migrate/20200310215714_migrate_saml_identities_to_scim_identities.rb
index e2ec7b62d31..b41c55ce622 100644
--- a/db/post_migrate/20200310215714_migrate_saml_identities_to_scim_identities.rb
+++ b/db/post_migrate/20200310215714_migrate_saml_identities_to_scim_identities.rb
@@ -20,7 +20,7 @@ class MigrateSamlIdentitiesToScimIdentities < ActiveRecord::Migration[6.0]
record.attributes.extract!("extern_uid", "user_id", "group_id", "active", "created_at", "updated_at")
end
- Gitlab::Database.bulk_insert(:scim_identities, data_to_insert, on_conflict: :do_nothing)
+ Gitlab::Database.bulk_insert(:scim_identities, data_to_insert, on_conflict: :do_nothing) # rubocop:disable Gitlab/BulkInsert
end
end
diff --git a/db/post_migrate/20200406102120_backfill_deployment_clusters_from_deployments.rb b/db/post_migrate/20200406102120_backfill_deployment_clusters_from_deployments.rb
index 2db270d303c..76b00796d1a 100644
--- a/db/post_migrate/20200406102120_backfill_deployment_clusters_from_deployments.rb
+++ b/db/post_migrate/20200406102120_backfill_deployment_clusters_from_deployments.rb
@@ -17,7 +17,7 @@ class BackfillDeploymentClustersFromDeployments < ActiveRecord::Migration[6.0]
class Deployment < ActiveRecord::Base
include EachBatch
- default_scope { where('cluster_id IS NOT NULL') }
+ default_scope { where('cluster_id IS NOT NULL') } # rubocop:disable Cop/DefaultScope
self.table_name = 'deployments'
end
diff --git a/db/post_migrate/20200408132152_remove_namespaces_trial_ends_on.rb b/db/post_migrate/20200408132152_remove_namespaces_trial_ends_on.rb
new file mode 100644
index 00000000000..cfe0daaf50f
--- /dev/null
+++ b/db/post_migrate/20200408132152_remove_namespaces_trial_ends_on.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class RemoveNamespacesTrialEndsOn < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ remove_concurrent_index_by_name :namespaces, 'index_namespaces_on_trial_ends_on'
+
+ with_lock_retries do
+ remove_column :namespaces, :trial_ends_on
+ end
+ end
+
+ def down
+ unless column_exists?(:namespaces, :trial_ends_on)
+ with_lock_retries do
+ add_column :namespaces, :trial_ends_on, :datetime_with_timezone
+ end
+ end
+
+ add_concurrent_index :namespaces, :trial_ends_on, using: 'btree', where: 'trial_ends_on IS NOT NULL'
+ end
+end
diff --git a/db/post_migrate/20200421195234_backfill_status_page_published_incidents.rb b/db/post_migrate/20200421195234_backfill_status_page_published_incidents.rb
new file mode 100644
index 00000000000..fa7a5a9d924
--- /dev/null
+++ b/db/post_migrate/20200421195234_backfill_status_page_published_incidents.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+class BackfillStatusPagePublishedIncidents < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ class Incident < ActiveRecord::Base
+ self.table_name = 'status_page_published_incidents'
+ end
+
+ class StatusPageIssue < ActiveRecord::Base
+ include ::EachBatch
+
+ self.table_name = 'issues'
+
+ scope :published_only, -> do
+ joins('INNER JOIN status_page_settings ON status_page_settings.project_id = issues.project_id')
+ .where('status_page_settings.enabled = true')
+ .where(confidential: false)
+ end
+ end
+
+ def up
+ current_time = Time.current
+
+ StatusPageIssue.published_only.each_batch do |batch|
+ incidents = batch.map do |status_page_issue|
+ {
+ issue_id: status_page_issue.id,
+ created_at: current_time,
+ updated_at: current_time
+ }
+ end
+
+ Incident.insert_all(incidents, unique_by: :issue_id)
+ end
+ end
+
+ def down
+ # no op
+
+ # While we expect this table to be empty at the point of
+ # the up migration, there is no reliable way to determine
+ # whether records were added as a part of the migration
+ # or after it has run.
+ end
+end
diff --git a/db/post_migrate/20200518114540_schedule_fix_ruby_object_in_audit_events.rb b/db/post_migrate/20200518114540_schedule_fix_ruby_object_in_audit_events.rb
new file mode 100644
index 00000000000..e4335089540
--- /dev/null
+++ b/db/post_migrate/20200518114540_schedule_fix_ruby_object_in_audit_events.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+class ScheduleFixRubyObjectInAuditEvents < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ INDEX_NAME = 'index_audit_events_on_ruby_object_in_details'
+ INTERVAL = 2.minutes.to_i
+ BATCH_SIZE = 1_000
+ MIGRATION = 'FixRubyObjectInAuditEvents'
+
+ disable_ddl_transaction!
+
+ class AuditEvent < ActiveRecord::Base
+ self.table_name = 'audit_events'
+
+ include ::EachBatch
+ end
+
+ def up
+ return unless Gitlab.ee?
+
+ # create temporary index for audit_events with ruby/object in details field, may take well over 1h
+ add_concurrent_index(:audit_events, :id, where: "details ~~ '%ruby/object%'", name: INDEX_NAME)
+
+ relation = AuditEvent.where("details ~~ '%ruby/object%'")
+
+ queue_background_migration_jobs_by_range_at_intervals(
+ relation,
+ MIGRATION,
+ INTERVAL,
+ batch_size: BATCH_SIZE
+ )
+ end
+
+ def down
+ # temporary index is to be dropped in a different migration in an upcoming release
+ # https://gitlab.com/gitlab-org/gitlab/issues/196842
+ remove_concurrent_index_by_name(:audit_events, INDEX_NAME)
+ end
+end
diff --git a/db/post_migrate/20200518133123_add_index_on_starting_ending_at_to_metrics_dashboard_annotations.rb b/db/post_migrate/20200518133123_add_index_on_starting_ending_at_to_metrics_dashboard_annotations.rb
new file mode 100644
index 00000000000..3094fff0d1d
--- /dev/null
+++ b/db/post_migrate/20200518133123_add_index_on_starting_ending_at_to_metrics_dashboard_annotations.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class AddIndexOnStartingEndingAtToMetricsDashboardAnnotations < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ INDEX_NAME = 'index_metrics_dashboard_annotations_on_timespan_end'
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :metrics_dashboard_annotations, 'COALESCE(ending_at, starting_at)', name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index :metrics_dashboard_annotations, 'COALESCE(ending_at, starting_at)', name: INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20200519171058_update_index_ci_builds_on_commit_id_and_artifacts_expireatandidpartial.rb b/db/post_migrate/20200519171058_update_index_ci_builds_on_commit_id_and_artifacts_expireatandidpartial.rb
new file mode 100644
index 00000000000..e09ad4bdadf
--- /dev/null
+++ b/db/post_migrate/20200519171058_update_index_ci_builds_on_commit_id_and_artifacts_expireatandidpartial.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+class UpdateIndexCiBuildsOnCommitIdAndArtifactsExpireatandidpartial < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ disable_ddl_transaction!
+
+ OLD_INDEX_NAME = 'index_ci_builds_on_commit_id_and_artifacts_expireatandidpartial'
+ NEW_INDEX_NAME = 'index_ci_builds_on_commit_id_artifacts_expired_at_and_id'
+
+ OLD_CLAUSE = "type::text = 'Ci::Build'::text AND (retried = false OR retried IS NULL) AND
+ (name::text = ANY (ARRAY['sast'::character varying,
+ 'dependency_scanning'::character varying,
+ 'sast:container'::character varying,
+ 'container_scanning'::character varying,
+ 'dast'::character varying]::text[]))"
+
+ NEW_CLAUSE = "type::text = 'Ci::Build'::text AND (retried = false OR retried IS NULL) AND
+ (name::text = ANY (ARRAY['sast'::character varying,
+ 'secret_detection'::character varying,
+ 'dependency_scanning'::character varying,
+ 'container_scanning'::character varying,
+ 'dast'::character varying]::text[]))"
+
+ def up
+ add_concurrent_index :ci_builds, [:commit_id, :artifacts_expire_at, :id], name: NEW_INDEX_NAME, where: NEW_CLAUSE
+ remove_concurrent_index_by_name :ci_builds, OLD_INDEX_NAME
+ end
+
+ def down
+ add_concurrent_index :ci_builds, [:commit_id, :artifacts_expire_at, :id], name: OLD_INDEX_NAME, where: OLD_CLAUSE
+ remove_concurrent_index_by_name :ci_builds, NEW_INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20200525121014_drop_users_ghost_column.rb b/db/post_migrate/20200525121014_drop_users_ghost_column.rb
new file mode 100644
index 00000000000..1f80bc74b9d
--- /dev/null
+++ b/db/post_migrate/20200525121014_drop_users_ghost_column.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+class DropUsersGhostColumn < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ remove_concurrent_index_by_name :users, 'index_users_on_ghost'
+
+ with_lock_retries do
+ remove_column :users, :ghost
+ end
+ end
+
+ def down
+ unless column_exists?(:users, :ghost)
+ with_lock_retries do
+ add_column :users, :ghost, :boolean # rubocop:disable Migration/AddColumnsToWideTables
+ end
+ end
+
+ execute 'UPDATE users set ghost = TRUE WHERE user_type = 5'
+
+ add_concurrent_index :users, :ghost
+ end
+end
diff --git a/db/post_migrate/20200525144525_migrate_stuck_import_jobs_queue_to_stuck_project_import_jobs.rb b/db/post_migrate/20200525144525_migrate_stuck_import_jobs_queue_to_stuck_project_import_jobs.rb
new file mode 100644
index 00000000000..57e25c928f1
--- /dev/null
+++ b/db/post_migrate/20200525144525_migrate_stuck_import_jobs_queue_to_stuck_project_import_jobs.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class MigrateStuckImportJobsQueueToStuckProjectImportJobs < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ sidekiq_queue_migrate 'cronjob:stuck_import_jobs', to: 'cronjob:import_stuck_project_import_jobs'
+ end
+
+ def down
+ sidekiq_queue_migrate 'cronjob:import_stuck_project_import_jobs', to: 'cronjob:stuck_import_jobs'
+ end
+end
diff --git a/db/post_migrate/20200526000407_seed_repository_storages_weighted.rb b/db/post_migrate/20200526000407_seed_repository_storages_weighted.rb
new file mode 100644
index 00000000000..e5a0acb9cd8
--- /dev/null
+++ b/db/post_migrate/20200526000407_seed_repository_storages_weighted.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class SeedRepositoryStoragesWeighted < ActiveRecord::Migration[6.0]
+ class ApplicationSetting < ActiveRecord::Base
+ serialize :repository_storages
+ self.table_name = 'application_settings'
+ end
+
+ def up
+ ApplicationSetting.all.each do |settings|
+ storages = Gitlab.config.repositories.storages.keys.collect do |storage|
+ weight = settings.repository_storages.include?(storage) ? 100 : 0
+ [storage, weight]
+ end
+
+ settings.repository_storages_weighted = Hash[storages]
+ settings.save!
+ end
+ end
+
+ def down
+ end
+end
diff --git a/db/post_migrate/20200527094322_drop_vulnerability_confidence_index.rb b/db/post_migrate/20200527094322_drop_vulnerability_confidence_index.rb
new file mode 100644
index 00000000000..e9a9dd5eff8
--- /dev/null
+++ b/db/post_migrate/20200527094322_drop_vulnerability_confidence_index.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class DropVulnerabilityConfidenceIndex < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ DOWNTIME = false
+ INDEX_NAME = 'index_vulnerability_on_id_and_confidence_eq_zero'
+
+ def up
+ Gitlab::BackgroundMigration.steal('RemoveUndefinedVulnerabilityConfidenceLevel')
+
+ remove_concurrent_index_by_name :vulnerabilities, INDEX_NAME
+ end
+
+ def down
+ add_concurrent_index(:vulnerabilities, :id, where: 'confidence = 0', name: INDEX_NAME)
+ end
+end
diff --git a/db/post_migrate/20200527095401_drop_vulnerability_occurrence_confidence_index.rb b/db/post_migrate/20200527095401_drop_vulnerability_occurrence_confidence_index.rb
new file mode 100644
index 00000000000..99fe4da7686
--- /dev/null
+++ b/db/post_migrate/20200527095401_drop_vulnerability_occurrence_confidence_index.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class DropVulnerabilityOccurrenceConfidenceIndex < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ DOWNTIME = false
+ INDEX_NAME = 'index_vulnerability_occurrences_on_id_and_confidence_eq_zero'
+
+ def up
+ Gitlab::BackgroundMigration.steal('RemoveUndefinedOccurrenceConfidenceLevel')
+
+ remove_concurrent_index_by_name :vulnerability_occurrences, INDEX_NAME
+ end
+
+ def down
+ add_concurrent_index(:vulnerability_occurrences, :id, where: 'confidence = 0', name: INDEX_NAME)
+ end
+end
diff --git a/db/post_migrate/20200528123703_add_merge_request_partial_index_to_events.rb b/db/post_migrate/20200528123703_add_merge_request_partial_index_to_events.rb
new file mode 100644
index 00000000000..bf2269e77ab
--- /dev/null
+++ b/db/post_migrate/20200528123703_add_merge_request_partial_index_to_events.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+class AddMergeRequestPartialIndexToEvents < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_events_on_author_id_and_created_at_merge_requests'
+
+ def up
+ add_concurrent_index(
+ :events,
+ [:author_id, :created_at],
+ name: INDEX_NAME,
+ where: "(target_type = 'MergeRequest')"
+ )
+ end
+
+ def down
+ remove_concurrent_index :events, INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20200602013900_add_limit_to_designs_filename.rb b/db/post_migrate/20200602013900_add_limit_to_designs_filename.rb
new file mode 100644
index 00000000000..88732648965
--- /dev/null
+++ b/db/post_migrate/20200602013900_add_limit_to_designs_filename.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddLimitToDesignsFilename < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_text_limit(:design_management_designs, :filename, 255, validate: false)
+ end
+
+ def down
+ remove_text_limit(:design_management_designs, :filename)
+ end
+end
diff --git a/db/post_migrate/20200602013901_cap_designs_filename_length_to_new_limit.rb b/db/post_migrate/20200602013901_cap_designs_filename_length_to_new_limit.rb
new file mode 100644
index 00000000000..0458481c6bd
--- /dev/null
+++ b/db/post_migrate/20200602013901_cap_designs_filename_length_to_new_limit.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+class CapDesignsFilenameLengthToNewLimit < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ CHAR_LENGTH = 255
+ MODIFIED_NAME = 'gitlab-modified-'
+ MODIFIED_EXTENSION = '.jpg'
+
+ def up
+ arel_table = Arel::Table.new(:design_management_designs)
+
+ # Design filenames larger than the limit will be renamed to "gitlab-modified-{id}.jpg",
+ # which will be valid and unique. The design file itself will appear broken, as it is
+ # understood that no designs with filenames that exceed this limit will be legitimate.
+ # See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33565/diffs#note_355789080
+ new_value_clause = Arel::Nodes::NamedFunction.new(
+ 'CONCAT',
+ [
+ Arel::Nodes.build_quoted(MODIFIED_NAME),
+ arel_table[:id],
+ Arel::Nodes.build_quoted(MODIFIED_EXTENSION)
+ ]
+ )
+ where_clause = Arel::Nodes::NamedFunction.new(
+ 'CHAR_LENGTH',
+ [arel_table[:filename]]
+ ).gt(CHAR_LENGTH)
+
+ update_arel = Arel::UpdateManager.new.table(arel_table)
+ .set([[arel_table[:filename], new_value_clause]])
+ .where(where_clause)
+
+ ActiveRecord::Base.connection.execute(update_arel.to_sql)
+ end
+
+ def down
+ # no-op : the original filename is lost forever
+ end
+end
diff --git a/db/post_migrate/20200602143020_update_routes_for_lost_and_found_group_and_orphaned_projects.rb b/db/post_migrate/20200602143020_update_routes_for_lost_and_found_group_and_orphaned_projects.rb
new file mode 100644
index 00000000000..1935eaa1237
--- /dev/null
+++ b/db/post_migrate/20200602143020_update_routes_for_lost_and_found_group_and_orphaned_projects.rb
@@ -0,0 +1,178 @@
+# frozen_string_literal: true
+
+# This migration adds or updates the routes for all the entities affected by
+# post-migration '20200511083541_cleanup_projects_with_missing_namespace'
+# - A route is added for the 'lost-and-found' group
+# - A route is added for the Ghost user (if not already defined)
+# - The routes for all the orphaned projects that were moved under the 'lost-and-found'
+# group are updated to reflect the new path
+class UpdateRoutesForLostAndFoundGroupAndOrphanedProjects < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ class User < ActiveRecord::Base
+ self.table_name = 'users'
+
+ LOST_AND_FOUND_GROUP = 'lost-and-found'
+ USER_TYPE_GHOST = 5
+ ACCESS_LEVEL_OWNER = 50
+
+ has_one :namespace, -> { where(type: nil) },
+ foreign_key: :owner_id, inverse_of: :owner, autosave: true,
+ class_name: 'UpdateRoutesForLostAndFoundGroupAndOrphanedProjects::Namespace'
+
+ def lost_and_found_group
+ # Find the 'lost-and-found' group
+ # There should only be one Group owned by the Ghost user starting with 'lost-and-found'
+ Group
+ .joins('INNER JOIN members ON namespaces.id = members.source_id')
+ .where('namespaces.type = ?', 'Group')
+ .where('members.type = ?', 'GroupMember')
+ .where('members.source_type = ?', 'Namespace')
+ .where('members.user_id = ?', self.id)
+ .where('members.access_level = ?', ACCESS_LEVEL_OWNER)
+ .find_by(Group.arel_table[:name].matches("#{LOST_AND_FOUND_GROUP}%"))
+ end
+
+ class << self
+ # Return the ghost user
+ def ghost
+ User.find_by(user_type: USER_TYPE_GHOST)
+ end
+ end
+ end
+
+ # Temporary Concern to not repeat the same methods twice
+ module HasPath
+ extend ActiveSupport::Concern
+
+ def full_path
+ if parent && path
+ parent.full_path + '/' + path
+ else
+ path
+ end
+ end
+
+ def full_name
+ if parent && name
+ parent.full_name + ' / ' + name
+ else
+ name
+ end
+ end
+ end
+
+ class Namespace < ActiveRecord::Base
+ include HasPath
+
+ self.table_name = 'namespaces'
+
+ belongs_to :owner, class_name: 'UpdateRoutesForLostAndFoundGroupAndOrphanedProjects::User'
+ belongs_to :parent, class_name: "UpdateRoutesForLostAndFoundGroupAndOrphanedProjects::Namespace"
+ has_many :children, foreign_key: :parent_id,
+ class_name: "UpdateRoutesForLostAndFoundGroupAndOrphanedProjects::Namespace"
+ has_many :projects, class_name: "UpdateRoutesForLostAndFoundGroupAndOrphanedProjects::Project"
+
+ def ensure_route!
+ unless Route.for_source('Namespace', self.id)
+ Route.create!(
+ source_id: self.id,
+ source_type: 'Namespace',
+ path: self.full_path,
+ name: self.full_name
+ )
+ end
+ end
+
+ def generate_unique_path
+ # Generate a unique path if there is no route for the namespace
+ # (an existing route guarantees that the path is already unique)
+ unless Route.for_source('Namespace', self.id)
+ self.path = Uniquify.new.string(self.path) do |str|
+ Route.where(path: str).exists?
+ end
+ end
+ end
+ end
+
+ class Group < Namespace
+ # Disable STI to allow us to manually set "type = 'Group'"
+ # Otherwise rails forces "type = CleanupProjectsWithMissingNamespace::Group"
+ self.inheritance_column = :_type_disabled
+ end
+
+ class Route < ActiveRecord::Base
+ self.table_name = 'routes'
+
+ def self.for_source(source_type, source_id)
+ Route.find_by(source_type: source_type, source_id: source_id)
+ end
+ end
+
+ class Project < ActiveRecord::Base
+ include HasPath
+
+ self.table_name = 'projects'
+
+ belongs_to :group, -> { where(type: 'Group') }, foreign_key: 'namespace_id',
+ class_name: "UpdateRoutesForLostAndFoundGroupAndOrphanedProjects::Group"
+ belongs_to :namespace,
+ class_name: "UpdateRoutesForLostAndFoundGroupAndOrphanedProjects::Namespace"
+
+ alias_method :parent, :namespace
+ alias_attribute :parent_id, :namespace_id
+
+ def ensure_route!
+ Route.find_or_initialize_by(source_type: 'Project', source_id: self.id).tap do |record|
+ record.path = self.full_path
+ record.name = self.full_name
+ record.save!
+ end
+ end
+ end
+
+ def up
+ # Reset the column information of all the models that update the database
+ # to ensure the Active Record's knowledge of the table structure is current
+ Namespace.reset_column_information
+ Route.reset_column_information
+
+ # Find the ghost user, its namespace and the "lost and found" group
+ ghost_user = User.ghost
+ return unless ghost_user # No reason to continue if there is no Ghost user
+
+ ghost_namespace = ghost_user.namespace
+ lost_and_found_group = ghost_user.lost_and_found_group
+
+ # No reason to continue if there is no 'lost-and-found' group
+ # 1. No orphaned projects were found in this instance, or
+ # 2. The 'lost-and-found' group and the orphaned projects have been already deleted
+ return unless lost_and_found_group
+
+ # Update the 'lost-and-found' group description to be more self-explanatory
+ lost_and_found_group.generate_unique_path
+ lost_and_found_group.description =
+ 'Group for storing projects that were not properly deleted. '\
+ 'It should be considered as a system level Group with non-working '\
+ 'projects inside it. The contents may be deleted with a future update. '\
+ 'More info: gitlab.com/gitlab-org/gitlab/-/issues/198603'
+ lost_and_found_group.save!
+
+ # Update the routes for the Ghost user, the "lost and found" group
+ # and all the orphaned projects
+ ghost_namespace.ensure_route!
+ lost_and_found_group.ensure_route!
+
+ # The following does a fast index scan by namespace_id
+ # No reason to process in batches:
+ # - 66 projects in GitLab.com, less than 1ms execution time to fetch them
+ # with a constant update time for each
+ lost_and_found_group.projects.each do |project|
+ project.ensure_route!
+ end
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/post_migrate/20200608072931_backfill_imported_snippet_repositories.rb b/db/post_migrate/20200608072931_backfill_imported_snippet_repositories.rb
new file mode 100644
index 00000000000..0566524fa90
--- /dev/null
+++ b/db/post_migrate/20200608072931_backfill_imported_snippet_repositories.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+class BackfillImportedSnippetRepositories < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ DELAY_INTERVAL = 2.minutes.to_i
+ BATCH_SIZE = 200
+ MIGRATION = 'BackfillSnippetRepositories'
+
+ disable_ddl_transaction!
+
+ class Snippet < ActiveRecord::Base
+ include EachBatch
+
+ self.table_name = 'snippets'
+ self.inheritance_column = :_type_disabled
+ end
+
+ class SnippetRepository < ActiveRecord::Base
+ self.table_name = 'snippet_repositories'
+ end
+
+ def up
+ index = 1
+
+ Snippet.select(:id).where.not(id: SnippetRepository.select(:snippet_id)).each_batch(of: BATCH_SIZE, column: 'id') do |batch|
+ split_in_consecutive_batches(batch).each do |ids_batch|
+ migrate_in(index * DELAY_INTERVAL, MIGRATION, [ids_batch.first, ids_batch.last])
+
+ index += 1
+ end
+ end
+ end
+
+ def down
+ # no-op
+ end
+
+ private
+
+ def split_in_consecutive_batches(relation)
+ ids = relation.pluck(:id)
+
+ (ids.first..ids.last).to_a.split {|i| !ids.include?(i) }.select(&:present?)
+ end
+end
diff --git a/db/post_migrate/20200608075553_add_index_on_user_id_and_created_at_and_source_to_ci_pipelines.rb b/db/post_migrate/20200608075553_add_index_on_user_id_and_created_at_and_source_to_ci_pipelines.rb
new file mode 100644
index 00000000000..5df9cacdff6
--- /dev/null
+++ b/db/post_migrate/20200608075553_add_index_on_user_id_and_created_at_and_source_to_ci_pipelines.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddIndexOnUserIdAndCreatedAtAndSourceToCiPipelines < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :ci_pipelines, [:user_id, :created_at, :source]
+ remove_concurrent_index :ci_pipelines, [:user_id, :created_at]
+ end
+
+ def down
+ add_concurrent_index :ci_pipelines, [:user_id, :created_at]
+ remove_concurrent_index :ci_pipelines, [:user_id, :created_at, :source]
+ end
+end
diff --git a/db/post_migrate/20200609002841_add_partial_index_on_locked_state_id_to_merge_requests.rb b/db/post_migrate/20200609002841_add_partial_index_on_locked_state_id_to_merge_requests.rb
new file mode 100644
index 00000000000..076c8fd8715
--- /dev/null
+++ b/db/post_migrate/20200609002841_add_partial_index_on_locked_state_id_to_merge_requests.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddPartialIndexOnLockedStateIdToMergeRequests < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ INDEX_NAME = "idx_merge_requests_on_target_project_id_and_locked_state"
+ LOCKED_STATE_ID = 4
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :merge_requests, :target_project_id, where: "(state_id = #{LOCKED_STATE_ID})", name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :merge_requests, name: INDEX_NAME
+ end
+end
diff --git a/db/structure.sql b/db/structure.sql
index 38a8f98a1f3..7cd30c15c33 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -1,7 +1,5 @@
SET search_path=public;
-CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
-
CREATE EXTENSION IF NOT EXISTS pg_trgm WITH SCHEMA public;
CREATE TABLE public.abuse_reports (
@@ -24,6 +22,39 @@ CREATE SEQUENCE public.abuse_reports_id_seq
ALTER SEQUENCE public.abuse_reports_id_seq OWNED BY public.abuse_reports.id;
+CREATE TABLE public.alert_management_alert_assignees (
+ id bigint NOT NULL,
+ user_id bigint NOT NULL,
+ alert_id bigint NOT NULL
+);
+
+CREATE SEQUENCE public.alert_management_alert_assignees_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE public.alert_management_alert_assignees_id_seq OWNED BY public.alert_management_alert_assignees.id;
+
+CREATE TABLE public.alert_management_alert_user_mentions (
+ id bigint NOT NULL,
+ alert_management_alert_id bigint NOT NULL,
+ note_id bigint,
+ mentioned_users_ids integer[],
+ mentioned_projects_ids integer[],
+ mentioned_groups_ids integer[]
+);
+
+CREATE SEQUENCE public.alert_management_alert_user_mentions_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE public.alert_management_alert_user_mentions_id_seq OWNED BY public.alert_management_alert_user_mentions.id;
+
CREATE TABLE public.alert_management_alerts (
id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
@@ -441,7 +472,14 @@ CREATE TABLE public.application_settings (
container_registry_vendor text DEFAULT ''::text NOT NULL,
container_registry_version text DEFAULT ''::text NOT NULL,
container_registry_features text[] DEFAULT '{}'::text[] NOT NULL,
+ spam_check_endpoint_url text,
+ spam_check_endpoint_enabled boolean DEFAULT false NOT NULL,
+ elasticsearch_pause_indexing boolean DEFAULT false NOT NULL,
+ repository_storages_weighted jsonb DEFAULT '{}'::jsonb NOT NULL,
+ max_import_size integer DEFAULT 50 NOT NULL,
+ enforce_pat_expiration boolean DEFAULT true NOT NULL,
CONSTRAINT check_d03919528d CHECK ((char_length(container_registry_vendor) <= 255)),
+ CONSTRAINT check_d820146492 CHECK ((char_length(spam_check_endpoint_url) <= 255)),
CONSTRAINT check_e5aba18f02 CHECK ((char_length(container_registry_version) <= 255))
);
@@ -659,7 +697,8 @@ CREATE TABLE public.audit_events (
entity_type character varying NOT NULL,
details text,
created_at timestamp without time zone,
- updated_at timestamp without time zone
+ updated_at timestamp without time zone,
+ ip_address inet
);
CREATE SEQUENCE public.audit_events_id_seq
@@ -785,6 +824,24 @@ CREATE SEQUENCE public.board_project_recent_visits_id_seq
ALTER SEQUENCE public.board_project_recent_visits_id_seq OWNED BY public.board_project_recent_visits.id;
+CREATE TABLE public.board_user_preferences (
+ id bigint NOT NULL,
+ user_id bigint NOT NULL,
+ board_id bigint NOT NULL,
+ hide_labels boolean,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL
+);
+
+CREATE SEQUENCE public.board_user_preferences_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE public.board_user_preferences_id_seq OWNED BY public.board_user_preferences.id;
+
CREATE TABLE public.boards (
id integer NOT NULL,
project_id integer,
@@ -886,6 +943,21 @@ CREATE SEQUENCE public.ci_build_needs_id_seq
ALTER SEQUENCE public.ci_build_needs_id_seq OWNED BY public.ci_build_needs.id;
+CREATE TABLE public.ci_build_report_results (
+ build_id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ data jsonb DEFAULT '{}'::jsonb NOT NULL
+);
+
+CREATE SEQUENCE public.ci_build_report_results_build_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE public.ci_build_report_results_build_id_seq OWNED BY public.ci_build_report_results.build_id;
+
CREATE TABLE public.ci_build_trace_chunks (
id bigint NOT NULL,
build_id integer NOT NULL,
@@ -1288,7 +1360,8 @@ CREATE TABLE public.ci_pipelines (
merge_request_id integer,
source_sha bytea,
target_sha bytea,
- external_pull_request_id bigint
+ external_pull_request_id bigint,
+ ci_ref_id bigint
);
CREATE TABLE public.ci_pipelines_config (
@@ -1316,12 +1389,10 @@ ALTER SEQUENCE public.ci_pipelines_id_seq OWNED BY public.ci_pipelines.id;
CREATE TABLE public.ci_refs (
id bigint NOT NULL,
- project_id integer NOT NULL,
- lock_version integer DEFAULT 0,
- last_updated_by_pipeline_id integer,
- tag boolean DEFAULT false NOT NULL,
- ref character varying(255) NOT NULL,
- status character varying(255) NOT NULL
+ project_id bigint NOT NULL,
+ lock_version integer DEFAULT 0 NOT NULL,
+ status smallint DEFAULT 0 NOT NULL,
+ ref_path text NOT NULL
);
CREATE SEQUENCE public.ci_refs_id_seq
@@ -1971,9 +2042,9 @@ CREATE TABLE public.container_expiration_policies (
updated_at timestamp with time zone NOT NULL,
next_run_at timestamp with time zone,
name_regex character varying(255),
- cadence character varying(12) DEFAULT '7d'::character varying NOT NULL,
- older_than character varying(12),
- keep_n integer,
+ cadence character varying(12) DEFAULT '1d'::character varying NOT NULL,
+ older_than character varying(12) DEFAULT '90d'::character varying,
+ keep_n integer DEFAULT 10,
enabled boolean DEFAULT true NOT NULL,
name_regex_keep text,
CONSTRAINT container_expiration_policies_name_regex_keep CHECK ((char_length(name_regex_keep) <= 255))
@@ -3112,6 +3183,31 @@ CREATE TABLE public.group_deletion_schedules (
marked_for_deletion_on date NOT NULL
);
+CREATE TABLE public.group_deploy_keys (
+ id bigint NOT NULL,
+ user_id bigint,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ last_used_at timestamp with time zone,
+ expires_at timestamp with time zone,
+ key text NOT NULL,
+ title text,
+ fingerprint text NOT NULL,
+ fingerprint_sha256 bytea,
+ CONSTRAINT check_cc0365908d CHECK ((char_length(title) <= 255)),
+ CONSTRAINT check_e4526dcf91 CHECK ((char_length(fingerprint) <= 255)),
+ CONSTRAINT check_f58fa0a0f7 CHECK ((char_length(key) <= 4096))
+);
+
+CREATE SEQUENCE public.group_deploy_keys_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE public.group_deploy_keys_id_seq OWNED BY public.group_deploy_keys.id;
+
CREATE TABLE public.group_deploy_tokens (
id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
@@ -3153,7 +3249,7 @@ CREATE TABLE public.group_import_states (
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
status smallint DEFAULT 0 NOT NULL,
- jid text NOT NULL,
+ jid text,
last_error text,
CONSTRAINT check_87b58f6b30 CHECK ((char_length(last_error) <= 255)),
CONSTRAINT check_96558fff96 CHECK ((char_length(jid) <= 100))
@@ -3511,7 +3607,9 @@ CREATE TABLE public.jira_imports (
jid character varying(255),
jira_project_key character varying(255) NOT NULL,
jira_project_name character varying(255) NOT NULL,
- scheduled_at timestamp with time zone
+ scheduled_at timestamp with time zone,
+ error_message text,
+ CONSTRAINT check_9ed451c5b1 CHECK ((char_length(error_message) <= 1000))
);
CREATE SEQUENCE public.jira_imports_id_seq
@@ -4194,7 +4292,6 @@ CREATE TABLE public.namespaces (
cached_markdown_version integer,
project_creation_level integer,
runners_token character varying,
- trial_ends_on timestamp with time zone,
file_template_project_id integer,
saml_discovery_token character varying,
runners_token_encrypted character varying,
@@ -4480,6 +4577,21 @@ CREATE SEQUENCE public.operations_feature_flags_id_seq
ALTER SEQUENCE public.operations_feature_flags_id_seq OWNED BY public.operations_feature_flags.id;
+CREATE TABLE public.operations_feature_flags_issues (
+ id bigint NOT NULL,
+ feature_flag_id bigint NOT NULL,
+ issue_id bigint NOT NULL
+);
+
+CREATE SEQUENCE public.operations_feature_flags_issues_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE public.operations_feature_flags_issues_id_seq OWNED BY public.operations_feature_flags_issues.id;
+
CREATE TABLE public.operations_scopes (
id bigint NOT NULL,
strategy_id bigint NOT NULL,
@@ -4560,6 +4672,12 @@ CREATE SEQUENCE public.packages_build_infos_id_seq
ALTER SEQUENCE public.packages_build_infos_id_seq OWNED BY public.packages_build_infos.id;
+CREATE TABLE public.packages_composer_metadata (
+ package_id bigint NOT NULL,
+ target_sha bytea NOT NULL,
+ composer_json jsonb DEFAULT '{}'::jsonb NOT NULL
+);
+
CREATE TABLE public.packages_conan_file_metadata (
id bigint NOT NULL,
package_file_id bigint NOT NULL,
@@ -4861,7 +4979,8 @@ CREATE TABLE public.plan_limits (
group_hooks integer DEFAULT 50 NOT NULL,
ci_project_subscriptions integer DEFAULT 2 NOT NULL,
ci_pipeline_schedules integer DEFAULT 10 NOT NULL,
- offset_pagination_limit integer DEFAULT 50000 NOT NULL
+ offset_pagination_limit integer DEFAULT 50000 NOT NULL,
+ ci_instance_level_variables integer DEFAULT 25 NOT NULL
);
CREATE SEQUENCE public.plan_limits_id_seq
@@ -4923,6 +5042,11 @@ CREATE SEQUENCE public.programming_languages_id_seq
ALTER SEQUENCE public.programming_languages_id_seq OWNED BY public.programming_languages.id;
+CREATE TABLE public.project_access_tokens (
+ personal_access_token_id bigint NOT NULL,
+ project_id bigint NOT NULL
+);
+
CREATE TABLE public.project_alerting_settings (
project_id integer NOT NULL,
encrypted_token character varying NOT NULL,
@@ -5150,7 +5274,7 @@ ALTER SEQUENCE public.project_import_data_id_seq OWNED BY public.project_import_
CREATE TABLE public.project_incident_management_settings (
project_id integer NOT NULL,
- create_issue boolean DEFAULT true NOT NULL,
+ create_issue boolean DEFAULT false NOT NULL,
send_email boolean DEFAULT false NOT NULL,
issue_template_key text
);
@@ -5166,7 +5290,8 @@ ALTER SEQUENCE public.project_incident_management_settings_project_id_seq OWNED
CREATE TABLE public.project_metrics_settings (
project_id integer NOT NULL,
- external_dashboard_url character varying NOT NULL
+ external_dashboard_url character varying,
+ dashboard_timezone smallint DEFAULT 0 NOT NULL
);
CREATE TABLE public.project_mirror_data (
@@ -5259,12 +5384,32 @@ CREATE SEQUENCE public.project_repository_storage_moves_id_seq
ALTER SEQUENCE public.project_repository_storage_moves_id_seq OWNED BY public.project_repository_storage_moves.id;
+CREATE TABLE public.project_security_settings (
+ project_id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ auto_fix_container_scanning boolean DEFAULT true NOT NULL,
+ auto_fix_dast boolean DEFAULT true NOT NULL,
+ auto_fix_dependency_scanning boolean DEFAULT true NOT NULL,
+ auto_fix_sast boolean DEFAULT true NOT NULL
+);
+
+CREATE SEQUENCE public.project_security_settings_project_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE public.project_security_settings_project_id_seq OWNED BY public.project_security_settings.project_id;
+
CREATE TABLE public.project_settings (
project_id integer NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
push_rule_id bigint,
show_default_award_emojis boolean DEFAULT true,
+ allow_merge_on_skipped_pipeline boolean,
CONSTRAINT check_bde223416c CHECK ((show_default_award_emojis IS NOT NULL))
);
@@ -5679,7 +5824,8 @@ CREATE TABLE public.release_links (
name character varying NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
- filepath character varying(128)
+ filepath character varying(128),
+ link_type smallint DEFAULT 0
);
CREATE SEQUENCE public.release_links_id_seq
@@ -5773,6 +5919,25 @@ CREATE SEQUENCE public.requirements_id_seq
ALTER SEQUENCE public.requirements_id_seq OWNED BY public.requirements.id;
+CREATE TABLE public.requirements_management_test_reports (
+ id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ requirement_id bigint NOT NULL,
+ pipeline_id bigint,
+ author_id bigint,
+ state smallint NOT NULL,
+ build_id bigint
+);
+
+CREATE SEQUENCE public.requirements_management_test_reports_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE public.requirements_management_test_reports_id_seq OWNED BY public.requirements_management_test_reports.id;
+
CREATE TABLE public.resource_label_events (
id bigint NOT NULL,
action integer NOT NULL,
@@ -5798,7 +5963,7 @@ ALTER SEQUENCE public.resource_label_events_id_seq OWNED BY public.resource_labe
CREATE TABLE public.resource_milestone_events (
id bigint NOT NULL,
- user_id bigint NOT NULL,
+ user_id bigint,
issue_id bigint,
merge_request_id bigint,
milestone_id bigint,
@@ -5818,13 +5983,13 @@ ALTER SEQUENCE public.resource_milestone_events_id_seq OWNED BY public.resource_
CREATE TABLE public.resource_state_events (
id bigint NOT NULL,
- user_id bigint NOT NULL,
+ user_id bigint,
issue_id bigint,
merge_request_id bigint,
created_at timestamp with time zone NOT NULL,
state smallint NOT NULL,
epic_id integer,
- CONSTRAINT resource_state_events_must_belong_to_issue_or_merge_request CHECK ((((issue_id <> NULL::bigint) AND (merge_request_id IS NULL)) OR ((merge_request_id <> NULL::bigint) AND (issue_id IS NULL))))
+ CONSTRAINT state_events_must_belong_to_issue_or_merge_request_or_epic CHECK ((((issue_id <> NULL::bigint) AND (merge_request_id IS NULL) AND (epic_id IS NULL)) OR ((issue_id IS NULL) AND (merge_request_id <> NULL::bigint) AND (epic_id IS NULL)) OR ((issue_id IS NULL) AND (merge_request_id IS NULL) AND (epic_id <> NULL::integer))))
);
CREATE SEQUENCE public.resource_state_events_id_seq
@@ -5838,7 +6003,7 @@ ALTER SEQUENCE public.resource_state_events_id_seq OWNED BY public.resource_stat
CREATE TABLE public.resource_weight_events (
id bigint NOT NULL,
- user_id bigint NOT NULL,
+ user_id bigint,
issue_id bigint NOT NULL,
weight integer,
created_at timestamp with time zone NOT NULL
@@ -6073,7 +6238,8 @@ CREATE TABLE public.services (
template boolean DEFAULT false,
instance boolean DEFAULT false NOT NULL,
comment_detail smallint,
- inherit_from_id bigint
+ inherit_from_id bigint,
+ alert_events boolean
);
CREATE SEQUENCE public.services_id_seq
@@ -6483,7 +6649,8 @@ CREATE TABLE public.todos (
updated_at timestamp without time zone,
note_id integer,
commit_id character varying,
- group_id integer
+ group_id integer,
+ resolved_by_action smallint
);
CREATE SEQUENCE public.todos_id_seq
@@ -6673,7 +6840,8 @@ CREATE TABLE public.user_preferences (
setup_for_company boolean,
render_whitespace_in_code boolean,
tab_width smallint,
- feature_filter_type bigint
+ feature_filter_type bigint,
+ experience_level smallint
);
CREATE SEQUENCE public.user_preferences_id_seq
@@ -6783,7 +6951,6 @@ CREATE TABLE public.users (
auditor boolean DEFAULT false NOT NULL,
require_two_factor_authentication_from_group boolean DEFAULT false NOT NULL,
two_factor_grace_period integer DEFAULT 48 NOT NULL,
- ghost boolean,
last_activity_on date,
notified_of_own_activity boolean,
preferred_language character varying,
@@ -7283,6 +7450,10 @@ ALTER SEQUENCE public.zoom_meetings_id_seq OWNED BY public.zoom_meetings.id;
ALTER TABLE ONLY public.abuse_reports ALTER COLUMN id SET DEFAULT nextval('public.abuse_reports_id_seq'::regclass);
+ALTER TABLE ONLY public.alert_management_alert_assignees ALTER COLUMN id SET DEFAULT nextval('public.alert_management_alert_assignees_id_seq'::regclass);
+
+ALTER TABLE ONLY public.alert_management_alert_user_mentions ALTER COLUMN id SET DEFAULT nextval('public.alert_management_alert_user_mentions_id_seq'::regclass);
+
ALTER TABLE ONLY public.alert_management_alerts ALTER COLUMN id SET DEFAULT nextval('public.alert_management_alerts_id_seq'::regclass);
ALTER TABLE ONLY public.alerts_service_data ALTER COLUMN id SET DEFAULT nextval('public.alerts_service_data_id_seq'::regclass);
@@ -7335,6 +7506,8 @@ ALTER TABLE ONLY public.board_labels ALTER COLUMN id SET DEFAULT nextval('public
ALTER TABLE ONLY public.board_project_recent_visits ALTER COLUMN id SET DEFAULT nextval('public.board_project_recent_visits_id_seq'::regclass);
+ALTER TABLE ONLY public.board_user_preferences ALTER COLUMN id SET DEFAULT nextval('public.board_user_preferences_id_seq'::regclass);
+
ALTER TABLE ONLY public.boards ALTER COLUMN id SET DEFAULT nextval('public.boards_id_seq'::regclass);
ALTER TABLE ONLY public.broadcast_messages ALTER COLUMN id SET DEFAULT nextval('public.broadcast_messages_id_seq'::regclass);
@@ -7345,6 +7518,8 @@ ALTER TABLE ONLY public.chat_teams ALTER COLUMN id SET DEFAULT nextval('public.c
ALTER TABLE ONLY public.ci_build_needs ALTER COLUMN id SET DEFAULT nextval('public.ci_build_needs_id_seq'::regclass);
+ALTER TABLE ONLY public.ci_build_report_results ALTER COLUMN build_id SET DEFAULT nextval('public.ci_build_report_results_build_id_seq'::regclass);
+
ALTER TABLE ONLY public.ci_build_trace_chunks ALTER COLUMN id SET DEFAULT nextval('public.ci_build_trace_chunks_id_seq'::regclass);
ALTER TABLE ONLY public.ci_build_trace_section_names ALTER COLUMN id SET DEFAULT nextval('public.ci_build_trace_section_names_id_seq'::regclass);
@@ -7547,6 +7722,8 @@ ALTER TABLE ONLY public.grafana_integrations ALTER COLUMN id SET DEFAULT nextval
ALTER TABLE ONLY public.group_custom_attributes ALTER COLUMN id SET DEFAULT nextval('public.group_custom_attributes_id_seq'::regclass);
+ALTER TABLE ONLY public.group_deploy_keys ALTER COLUMN id SET DEFAULT nextval('public.group_deploy_keys_id_seq'::regclass);
+
ALTER TABLE ONLY public.group_deploy_tokens ALTER COLUMN id SET DEFAULT nextval('public.group_deploy_tokens_id_seq'::regclass);
ALTER TABLE ONLY public.group_group_links ALTER COLUMN id SET DEFAULT nextval('public.group_group_links_id_seq'::regclass);
@@ -7661,6 +7838,8 @@ ALTER TABLE ONLY public.operations_feature_flags ALTER COLUMN id SET DEFAULT nex
ALTER TABLE ONLY public.operations_feature_flags_clients ALTER COLUMN id SET DEFAULT nextval('public.operations_feature_flags_clients_id_seq'::regclass);
+ALTER TABLE ONLY public.operations_feature_flags_issues ALTER COLUMN id SET DEFAULT nextval('public.operations_feature_flags_issues_id_seq'::regclass);
+
ALTER TABLE ONLY public.operations_scopes ALTER COLUMN id SET DEFAULT nextval('public.operations_scopes_id_seq'::regclass);
ALTER TABLE ONLY public.operations_strategies ALTER COLUMN id SET DEFAULT nextval('public.operations_strategies_id_seq'::regclass);
@@ -7737,6 +7916,8 @@ ALTER TABLE ONLY public.project_repository_states ALTER COLUMN id SET DEFAULT ne
ALTER TABLE ONLY public.project_repository_storage_moves ALTER COLUMN id SET DEFAULT nextval('public.project_repository_storage_moves_id_seq'::regclass);
+ALTER TABLE ONLY public.project_security_settings ALTER COLUMN project_id SET DEFAULT nextval('public.project_security_settings_project_id_seq'::regclass);
+
ALTER TABLE ONLY public.project_statistics ALTER COLUMN id SET DEFAULT nextval('public.project_statistics_id_seq'::regclass);
ALTER TABLE ONLY public.project_tracing_settings ALTER COLUMN id SET DEFAULT nextval('public.project_tracing_settings_id_seq'::regclass);
@@ -7777,6 +7958,8 @@ ALTER TABLE ONLY public.remote_mirrors ALTER COLUMN id SET DEFAULT nextval('publ
ALTER TABLE ONLY public.requirements ALTER COLUMN id SET DEFAULT nextval('public.requirements_id_seq'::regclass);
+ALTER TABLE ONLY public.requirements_management_test_reports ALTER COLUMN id SET DEFAULT nextval('public.requirements_management_test_reports_id_seq'::regclass);
+
ALTER TABLE ONLY public.resource_label_events ALTER COLUMN id SET DEFAULT nextval('public.resource_label_events_id_seq'::regclass);
ALTER TABLE ONLY public.resource_milestone_events ALTER COLUMN id SET DEFAULT nextval('public.resource_milestone_events_id_seq'::regclass);
@@ -7914,6 +8097,12 @@ ALTER TABLE ONLY public.zoom_meetings ALTER COLUMN id SET DEFAULT nextval('publi
ALTER TABLE ONLY public.abuse_reports
ADD CONSTRAINT abuse_reports_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY public.alert_management_alert_assignees
+ ADD CONSTRAINT alert_management_alert_assignees_pkey PRIMARY KEY (id);
+
+ALTER TABLE ONLY public.alert_management_alert_user_mentions
+ ADD CONSTRAINT alert_management_alert_user_mentions_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY public.alert_management_alerts
ADD CONSTRAINT alert_management_alerts_pkey PRIMARY KEY (id);
@@ -7998,6 +8187,9 @@ ALTER TABLE ONLY public.board_labels
ALTER TABLE ONLY public.board_project_recent_visits
ADD CONSTRAINT board_project_recent_visits_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY public.board_user_preferences
+ ADD CONSTRAINT board_user_preferences_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY public.boards
ADD CONSTRAINT boards_pkey PRIMARY KEY (id);
@@ -8010,6 +8202,9 @@ ALTER TABLE ONLY public.chat_names
ALTER TABLE ONLY public.chat_teams
ADD CONSTRAINT chat_teams_pkey PRIMARY KEY (id);
+ALTER TABLE public.design_management_designs
+ ADD CONSTRAINT check_07155e2715 CHECK ((char_length((filename)::text) <= 255)) NOT VALID;
+
ALTER TABLE public.ci_job_artifacts
ADD CONSTRAINT check_27f0f6dbab CHECK ((file_store IS NOT NULL)) NOT VALID;
@@ -8022,6 +8217,9 @@ ALTER TABLE public.lfs_objects
ALTER TABLE ONLY public.ci_build_needs
ADD CONSTRAINT ci_build_needs_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY public.ci_build_report_results
+ ADD CONSTRAINT ci_build_report_results_pkey PRIMARY KEY (build_id);
+
ALTER TABLE ONLY public.ci_build_trace_chunks
ADD CONSTRAINT ci_build_trace_chunks_pkey PRIMARY KEY (id);
@@ -8334,6 +8532,9 @@ ALTER TABLE ONLY public.group_custom_attributes
ALTER TABLE ONLY public.group_deletion_schedules
ADD CONSTRAINT group_deletion_schedules_pkey PRIMARY KEY (group_id);
+ALTER TABLE ONLY public.group_deploy_keys
+ ADD CONSTRAINT group_deploy_keys_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY public.group_deploy_tokens
ADD CONSTRAINT group_deploy_tokens_pkey PRIMARY KEY (id);
@@ -8511,6 +8712,9 @@ ALTER TABLE ONLY public.operations_feature_flag_scopes
ALTER TABLE ONLY public.operations_feature_flags_clients
ADD CONSTRAINT operations_feature_flags_clients_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY public.operations_feature_flags_issues
+ ADD CONSTRAINT operations_feature_flags_issues_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY public.operations_feature_flags
ADD CONSTRAINT operations_feature_flags_pkey PRIMARY KEY (id);
@@ -8529,6 +8733,9 @@ ALTER TABLE ONLY public.operations_user_lists
ALTER TABLE ONLY public.packages_build_infos
ADD CONSTRAINT packages_build_infos_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY public.packages_composer_metadata
+ ADD CONSTRAINT packages_composer_metadata_pkey PRIMARY KEY (package_id);
+
ALTER TABLE ONLY public.packages_conan_file_metadata
ADD CONSTRAINT packages_conan_file_metadata_pkey PRIMARY KEY (id);
@@ -8589,6 +8796,9 @@ ALTER TABLE ONLY public.pool_repositories
ALTER TABLE ONLY public.programming_languages
ADD CONSTRAINT programming_languages_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY public.project_access_tokens
+ ADD CONSTRAINT project_access_tokens_pkey PRIMARY KEY (personal_access_token_id, project_id);
+
ALTER TABLE ONLY public.project_alerting_settings
ADD CONSTRAINT project_alerting_settings_pkey PRIMARY KEY (project_id);
@@ -8649,6 +8859,9 @@ ALTER TABLE ONLY public.project_repository_states
ALTER TABLE ONLY public.project_repository_storage_moves
ADD CONSTRAINT project_repository_storage_moves_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY public.project_security_settings
+ ADD CONSTRAINT project_security_settings_pkey PRIMARY KEY (project_id);
+
ALTER TABLE ONLY public.project_settings
ADD CONSTRAINT project_settings_pkey PRIMARY KEY (project_id);
@@ -8709,6 +8922,9 @@ ALTER TABLE ONLY public.releases
ALTER TABLE ONLY public.remote_mirrors
ADD CONSTRAINT remote_mirrors_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY public.requirements_management_test_reports
+ ADD CONSTRAINT requirements_management_test_reports_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY public.requirements
ADD CONSTRAINT requirements_pkey PRIMARY KEY (id);
@@ -8952,8 +9168,6 @@ CREATE UNIQUE INDEX design_management_designs_versions_uniqueness ON public.desi
CREATE INDEX design_user_mentions_on_design_id_and_note_id_index ON public.design_user_mentions USING btree (design_id, note_id);
-CREATE INDEX dev_index_route_on_path_trigram ON public.routes USING gin (path public.gin_trgm_ops);
-
CREATE UNIQUE INDEX epic_user_mentions_on_epic_id_and_note_id_index ON public.epic_user_mentions USING btree (epic_id, note_id);
CREATE UNIQUE INDEX epic_user_mentions_on_epic_id_index ON public.epic_user_mentions USING btree (epic_id) WHERE (note_id IS NULL);
@@ -8990,6 +9204,8 @@ CREATE INDEX idx_merge_requests_on_state_id_and_merge_status ON public.merge_req
CREATE INDEX idx_merge_requests_on_target_project_id_and_iid_opened ON public.merge_requests USING btree (target_project_id, iid) WHERE (state_id = 1);
+CREATE INDEX idx_merge_requests_on_target_project_id_and_locked_state ON public.merge_requests USING btree (target_project_id) WHERE (state_id = 4);
+
CREATE UNIQUE INDEX idx_metrics_users_starred_dashboard_on_user_project_dashboard ON public.metrics_users_starred_dashboards USING btree (user_id, project_id, dashboard_path);
CREATE INDEX idx_mr_cc_diff_files_on_mr_cc_id_and_sha ON public.merge_request_context_commit_diff_files USING btree (merge_request_context_commit_id, sha);
@@ -9030,12 +9246,22 @@ CREATE UNIQUE INDEX idx_vulnerability_issue_links_on_vulnerability_id_and_link_t
CREATE INDEX index_abuse_reports_on_user_id ON public.abuse_reports USING btree (user_id);
+CREATE INDEX index_alert_assignees_on_alert_id ON public.alert_management_alert_assignees USING btree (alert_id);
+
+CREATE UNIQUE INDEX index_alert_assignees_on_user_id_and_alert_id ON public.alert_management_alert_assignees USING btree (user_id, alert_id);
+
CREATE INDEX index_alert_management_alerts_on_issue_id ON public.alert_management_alerts USING btree (issue_id);
CREATE UNIQUE INDEX index_alert_management_alerts_on_project_id_and_fingerprint ON public.alert_management_alerts USING btree (project_id, fingerprint);
CREATE UNIQUE INDEX index_alert_management_alerts_on_project_id_and_iid ON public.alert_management_alerts USING btree (project_id, iid);
+CREATE UNIQUE INDEX index_alert_user_mentions_on_alert_id ON public.alert_management_alert_user_mentions USING btree (alert_management_alert_id) WHERE (note_id IS NULL);
+
+CREATE UNIQUE INDEX index_alert_user_mentions_on_alert_id_and_note_id ON public.alert_management_alert_user_mentions USING btree (alert_management_alert_id, note_id);
+
+CREATE UNIQUE INDEX index_alert_user_mentions_on_note_id ON public.alert_management_alert_user_mentions USING btree (note_id) WHERE (note_id IS NOT NULL);
+
CREATE INDEX index_alerts_service_data_on_service_id ON public.alerts_service_data USING btree (service_id);
CREATE INDEX index_allowed_email_domains_on_group_id ON public.allowed_email_domains USING btree (group_id);
@@ -9126,6 +9352,8 @@ CREATE INDEX index_approvers_on_user_id ON public.approvers USING btree (user_id
CREATE INDEX index_audit_events_on_entity_id_and_entity_type_and_id_desc ON public.audit_events USING btree (entity_id, entity_type, id DESC);
+CREATE INDEX index_audit_events_on_ruby_object_in_details ON public.audit_events USING btree (id) WHERE (details ~~ '%ruby/object%'::text);
+
CREATE INDEX index_award_emoji_on_awardable_type_and_awardable_id ON public.award_emoji USING btree (awardable_type, awardable_id);
CREATE INDEX index_award_emoji_on_user_id_and_name ON public.award_emoji USING btree (user_id, name);
@@ -9162,6 +9390,12 @@ CREATE INDEX index_board_project_recent_visits_on_user_id ON public.board_projec
CREATE UNIQUE INDEX index_board_project_recent_visits_on_user_project_and_board ON public.board_project_recent_visits USING btree (user_id, project_id, board_id);
+CREATE INDEX index_board_user_preferences_on_board_id ON public.board_user_preferences USING btree (board_id);
+
+CREATE INDEX index_board_user_preferences_on_user_id ON public.board_user_preferences USING btree (user_id);
+
+CREATE UNIQUE INDEX index_board_user_preferences_on_user_id_and_board_id ON public.board_user_preferences USING btree (user_id, board_id);
+
CREATE INDEX index_boards_on_group_id ON public.boards USING btree (group_id);
CREATE INDEX index_boards_on_milestone_id ON public.boards USING btree (milestone_id);
@@ -9180,6 +9414,8 @@ CREATE UNIQUE INDEX index_chat_teams_on_namespace_id ON public.chat_teams USING
CREATE UNIQUE INDEX index_ci_build_needs_on_build_id_and_name ON public.ci_build_needs USING btree (build_id, name);
+CREATE INDEX index_ci_build_report_results_on_project_id ON public.ci_build_report_results USING btree (project_id);
+
CREATE UNIQUE INDEX index_ci_build_trace_chunks_on_build_id_and_chunk_index ON public.ci_build_trace_chunks USING btree (build_id, chunk_index);
CREATE UNIQUE INDEX index_ci_build_trace_section_names_on_project_id_and_name ON public.ci_build_trace_section_names USING btree (project_id, name);
@@ -9202,8 +9438,6 @@ CREATE INDEX index_ci_builds_on_artifacts_expire_at ON public.ci_builds USING bt
CREATE INDEX index_ci_builds_on_auto_canceled_by_id ON public.ci_builds USING btree (auto_canceled_by_id);
-CREATE INDEX index_ci_builds_on_commit_id_and_artifacts_expireatandidpartial ON public.ci_builds USING btree (commit_id, artifacts_expire_at, id) WHERE (((type)::text = 'Ci::Build'::text) AND ((retried = false) OR (retried IS NULL)) AND ((name)::text = ANY (ARRAY[('sast'::character varying)::text, ('dependency_scanning'::character varying)::text, ('sast:container'::character varying)::text, ('container_scanning'::character varying)::text, ('dast'::character varying)::text])));
-
CREATE INDEX index_ci_builds_on_commit_id_and_stage_idx_and_created_at ON public.ci_builds USING btree (commit_id, stage_idx, created_at);
CREATE INDEX index_ci_builds_on_commit_id_and_status_and_type ON public.ci_builds USING btree (commit_id, status, type);
@@ -9212,7 +9446,7 @@ CREATE INDEX index_ci_builds_on_commit_id_and_type_and_name_and_ref ON public.ci
CREATE INDEX index_ci_builds_on_commit_id_and_type_and_ref ON public.ci_builds USING btree (commit_id, type, ref);
-CREATE INDEX index_ci_builds_on_name_and_security_type_eq_ci_build ON public.ci_builds USING btree (name, id) 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, ('license_scanning'::character varying)::text])) AND ((type)::text = 'Ci::Build'::text));
+CREATE INDEX index_ci_builds_on_commit_id_artifacts_expired_at_and_id ON public.ci_builds USING btree (commit_id, artifacts_expire_at, id) 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])));
CREATE INDEX index_ci_builds_on_project_id_and_id ON public.ci_builds USING btree (project_id, id);
@@ -9258,6 +9492,8 @@ CREATE UNIQUE INDEX index_ci_instance_variables_on_key ON public.ci_instance_var
CREATE INDEX index_ci_job_artifacts_file_store_is_null ON public.ci_job_artifacts USING btree (id) WHERE (file_store IS NULL);
+CREATE INDEX index_ci_job_artifacts_for_terraform_reports ON public.ci_job_artifacts USING btree (project_id, id) WHERE (file_type = 18);
+
CREATE INDEX index_ci_job_artifacts_on_expire_at_and_job_id ON public.ci_job_artifacts USING btree (expire_at, job_id);
CREATE INDEX index_ci_job_artifacts_on_file_store ON public.ci_job_artifacts USING btree (file_store);
@@ -9284,14 +9520,14 @@ CREATE INDEX index_ci_pipeline_schedules_on_owner_id ON public.ci_pipeline_sched
CREATE INDEX index_ci_pipeline_schedules_on_project_id ON public.ci_pipeline_schedules USING btree (project_id);
-CREATE INDEX index_ci_pipeline_variables_on_pipeline_id ON public.ci_pipeline_variables USING btree (pipeline_id) WHERE ((key)::text = 'AUTO_DEVOPS_MODSECURITY_SEC_RULE_ENGINE'::text);
-
CREATE UNIQUE INDEX index_ci_pipeline_variables_on_pipeline_id_and_key ON public.ci_pipeline_variables USING btree (pipeline_id, key);
CREATE INDEX index_ci_pipelines_config_on_pipeline_id ON public.ci_pipelines_config USING btree (pipeline_id);
CREATE INDEX index_ci_pipelines_on_auto_canceled_by_id ON public.ci_pipelines USING btree (auto_canceled_by_id);
+CREATE INDEX index_ci_pipelines_on_ci_ref_id ON public.ci_pipelines USING btree (ci_ref_id) WHERE (ci_ref_id IS NOT NULL);
+
CREATE INDEX index_ci_pipelines_on_external_pull_request_id ON public.ci_pipelines USING btree (external_pull_request_id) WHERE (external_pull_request_id IS NOT NULL);
CREATE INDEX index_ci_pipelines_on_merge_request_id ON public.ci_pipelines USING btree (merge_request_id) WHERE (merge_request_id IS NOT NULL);
@@ -9312,15 +9548,15 @@ CREATE INDEX index_ci_pipelines_on_project_id_and_status_and_config_source ON pu
CREATE INDEX index_ci_pipelines_on_project_id_and_status_and_updated_at ON public.ci_pipelines USING btree (project_id, status, updated_at);
+CREATE INDEX index_ci_pipelines_on_project_id_and_user_id_and_status_and_ref ON public.ci_pipelines USING btree (project_id, user_id, status, ref) WHERE (source <> 12);
+
CREATE INDEX index_ci_pipelines_on_project_idandrefandiddesc ON public.ci_pipelines USING btree (project_id, ref, id DESC);
CREATE INDEX index_ci_pipelines_on_status ON public.ci_pipelines USING btree (status);
-CREATE INDEX index_ci_pipelines_on_user_id_and_created_at ON public.ci_pipelines USING btree (user_id, created_at);
+CREATE INDEX index_ci_pipelines_on_user_id_and_created_at_and_source ON public.ci_pipelines USING btree (user_id, created_at, source);
-CREATE INDEX index_ci_refs_on_last_updated_by_pipeline_id ON public.ci_refs USING btree (last_updated_by_pipeline_id);
-
-CREATE UNIQUE INDEX index_ci_refs_on_project_id_and_ref_and_tag ON public.ci_refs USING btree (project_id, ref, tag);
+CREATE UNIQUE INDEX index_ci_refs_on_project_id_and_ref_path ON public.ci_refs USING btree (project_id, ref_path);
CREATE UNIQUE INDEX index_ci_resource_groups_on_project_id_and_key ON public.ci_resource_groups USING btree (project_id, key);
@@ -9382,8 +9618,6 @@ CREATE INDEX index_ci_triggers_on_owner_id ON public.ci_triggers USING btree (ow
CREATE INDEX index_ci_triggers_on_project_id ON public.ci_triggers USING btree (project_id);
-CREATE INDEX index_ci_variables_on_project_id ON public.ci_variables USING btree (project_id) WHERE ((key)::text = 'AUTO_DEVOPS_MODSECURITY_SEC_RULE_ENGINE'::text);
-
CREATE UNIQUE INDEX index_ci_variables_on_project_id_and_key_and_environment_scope ON public.ci_variables USING btree (project_id, key, environment_scope);
CREATE UNIQUE INDEX index_cluster_groups_on_cluster_id_and_group_id ON public.cluster_groups USING btree (cluster_id, group_id);
@@ -9582,6 +9816,8 @@ CREATE INDEX index_epics_on_author_id ON public.epics USING btree (author_id);
CREATE INDEX index_epics_on_closed_by_id ON public.epics USING btree (closed_by_id);
+CREATE INDEX index_epics_on_confidential ON public.epics USING btree (confidential);
+
CREATE INDEX index_epics_on_due_date_sourcing_epic_id ON public.epics USING btree (due_date_sourcing_epic_id) WHERE (due_date_sourcing_epic_id IS NOT NULL);
CREATE INDEX index_epics_on_due_date_sourcing_milestone_id ON public.epics USING btree (due_date_sourcing_milestone_id);
@@ -9596,6 +9832,8 @@ CREATE INDEX index_epics_on_group_id_and_iid_varchar_pattern ON public.epics USI
CREATE INDEX index_epics_on_iid ON public.epics USING btree (iid);
+CREATE INDEX index_epics_on_last_edited_by_id ON public.epics USING btree (last_edited_by_id);
+
CREATE INDEX index_epics_on_lock_version ON public.epics USING btree (lock_version) WHERE (lock_version IS NULL);
CREATE INDEX index_epics_on_parent_id ON public.epics USING btree (parent_id);
@@ -9610,6 +9848,8 @@ CREATE INDEX index_events_on_action ON public.events USING btree (action);
CREATE INDEX index_events_on_author_id_and_created_at ON public.events USING btree (author_id, created_at);
+CREATE INDEX index_events_on_author_id_and_created_at_merge_requests ON public.events USING btree (author_id, created_at) WHERE ((target_type)::text = 'MergeRequest'::text);
+
CREATE INDEX index_events_on_author_id_and_project_id ON public.events USING btree (author_id, project_id);
CREATE INDEX index_events_on_group_id_partial ON public.events USING btree (group_id) WHERE (group_id IS NOT NULL);
@@ -9622,6 +9862,8 @@ CREATE INDEX index_events_on_target_type_and_target_id ON public.events USING bt
CREATE INDEX index_evidences_on_release_id ON public.evidences USING btree (release_id);
+CREATE INDEX index_expired_and_not_notified_personal_access_tokens ON public.personal_access_tokens USING btree (id, expires_at) WHERE ((impersonation = false) AND (revoked = false) AND (expire_notification_delivered = false));
+
CREATE UNIQUE INDEX index_external_pull_requests_on_project_and_branches ON public.external_pull_requests USING btree (project_id, source_branch, target_branch);
CREATE UNIQUE INDEX index_feature_flag_scopes_on_flag_id_and_environment_scope ON public.operations_feature_flag_scopes USING btree (feature_flag_id, environment_scope);
@@ -9750,6 +9992,12 @@ CREATE INDEX index_group_deletion_schedules_on_marked_for_deletion_on ON public.
CREATE INDEX index_group_deletion_schedules_on_user_id ON public.group_deletion_schedules USING btree (user_id);
+CREATE UNIQUE INDEX index_group_deploy_keys_on_fingerprint ON public.group_deploy_keys USING btree (fingerprint);
+
+CREATE INDEX index_group_deploy_keys_on_fingerprint_sha256 ON public.group_deploy_keys USING btree (fingerprint_sha256);
+
+CREATE INDEX index_group_deploy_keys_on_user_id ON public.group_deploy_keys USING btree (user_id);
+
CREATE INDEX index_group_deploy_tokens_on_deploy_token_id ON public.group_deploy_tokens USING btree (deploy_token_id);
CREATE UNIQUE INDEX index_group_deploy_tokens_on_group_and_deploy_token_ids ON public.group_deploy_tokens USING btree (group_id, deploy_token_id);
@@ -9828,6 +10076,8 @@ CREATE INDEX index_issues_on_description_trigram ON public.issues USING gin (des
CREATE INDEX index_issues_on_duplicated_to_id ON public.issues USING btree (duplicated_to_id) WHERE (duplicated_to_id IS NOT NULL);
+CREATE INDEX index_issues_on_last_edited_by_id ON public.issues USING btree (last_edited_by_id);
+
CREATE INDEX index_issues_on_lock_version ON public.issues USING btree (lock_version) WHERE (lock_version IS NULL);
CREATE INDEX index_issues_on_milestone_id ON public.issues USING btree (milestone_id);
@@ -10034,6 +10284,8 @@ CREATE INDEX index_metrics_dashboard_annotations_on_cluster_id_and_3_columns ON
CREATE INDEX index_metrics_dashboard_annotations_on_environment_id_and_3_col ON public.metrics_dashboard_annotations USING btree (environment_id, dashboard_path, starting_at, ending_at) WHERE (environment_id IS NOT NULL);
+CREATE INDEX index_metrics_dashboard_annotations_on_timespan_end ON public.metrics_dashboard_annotations USING btree (COALESCE(ending_at, starting_at));
+
CREATE INDEX index_metrics_users_starred_dashboards_on_project_id ON public.metrics_users_starred_dashboards USING btree (project_id);
CREATE INDEX index_milestone_releases_on_release_id ON public.milestone_releases USING btree (release_id);
@@ -10096,8 +10348,6 @@ CREATE UNIQUE INDEX index_namespaces_on_runners_token_encrypted ON public.namesp
CREATE INDEX index_namespaces_on_shared_and_extra_runners_minutes_limit ON public.namespaces USING btree (shared_runners_minutes_limit, extra_shared_runners_minutes_limit);
-CREATE INDEX index_namespaces_on_trial_ends_on ON public.namespaces USING btree (trial_ends_on) WHERE (trial_ends_on IS NOT NULL);
-
CREATE INDEX index_namespaces_on_type_partial ON public.namespaces USING btree (type) WHERE (type IS NOT NULL);
CREATE INDEX index_non_requested_project_members_on_source_id_and_type ON public.members USING btree (source_id, source_type) WHERE ((requested_at IS NULL) AND ((type)::text = 'ProjectMember'::text));
@@ -10156,6 +10406,8 @@ CREATE INDEX index_on_users_name_lower ON public.users USING btree (lower((name)
CREATE INDEX index_open_project_tracker_data_on_service_id ON public.open_project_tracker_data USING btree (service_id);
+CREATE INDEX index_operations_feature_flags_issues_on_issue_id ON public.operations_feature_flags_issues USING btree (issue_id);
+
CREATE UNIQUE INDEX index_operations_feature_flags_on_project_id_and_iid ON public.operations_feature_flags USING btree (project_id, iid);
CREATE UNIQUE INDEX index_operations_feature_flags_on_project_id_and_name ON public.operations_feature_flags USING btree (project_id, name);
@@ -10170,12 +10422,16 @@ CREATE UNIQUE INDEX index_operations_user_lists_on_project_id_and_iid ON public.
CREATE UNIQUE INDEX index_operations_user_lists_on_project_id_and_name ON public.operations_user_lists USING btree (project_id, name);
+CREATE UNIQUE INDEX index_ops_feature_flags_issues_on_feature_flag_id_and_issue_id ON public.operations_feature_flags_issues USING btree (feature_flag_id, issue_id);
+
CREATE UNIQUE INDEX index_ops_strategies_user_lists_on_strategy_id_and_user_list_id ON public.operations_strategies_user_lists USING btree (strategy_id, user_list_id);
CREATE UNIQUE INDEX index_packages_build_infos_on_package_id ON public.packages_build_infos USING btree (package_id);
CREATE INDEX index_packages_build_infos_on_pipeline_id ON public.packages_build_infos USING btree (pipeline_id);
+CREATE UNIQUE INDEX index_packages_composer_metadata_on_package_id_and_target_sha ON public.packages_composer_metadata USING btree (package_id, target_sha);
+
CREATE UNIQUE INDEX index_packages_conan_file_metadata_on_package_file_id ON public.packages_conan_file_metadata USING btree (package_file_id);
CREATE UNIQUE INDEX index_packages_conan_metadata_on_package_id_username_channel ON public.packages_conan_metadata USING btree (package_id, package_username, package_channel);
@@ -10258,6 +10514,8 @@ CREATE UNIQUE INDEX index_pool_repositories_on_source_project_id_and_shard_id ON
CREATE UNIQUE INDEX index_programming_languages_on_name ON public.programming_languages USING btree (name);
+CREATE INDEX index_project_access_tokens_on_project_id ON public.project_access_tokens USING btree (project_id);
+
CREATE UNIQUE INDEX index_project_aliases_on_name ON public.project_aliases USING btree (name);
CREATE INDEX index_project_aliases_on_project_id ON public.project_aliases USING btree (project_id);
@@ -10504,6 +10762,14 @@ CREATE INDEX index_remote_mirrors_on_project_id ON public.remote_mirrors USING b
CREATE UNIQUE INDEX index_repository_languages_on_project_and_languages_id ON public.repository_languages USING btree (project_id, programming_language_id);
+CREATE INDEX index_requirements_management_test_reports_on_author_id ON public.requirements_management_test_reports USING btree (author_id);
+
+CREATE INDEX index_requirements_management_test_reports_on_build_id ON public.requirements_management_test_reports USING btree (build_id);
+
+CREATE INDEX index_requirements_management_test_reports_on_pipeline_id ON public.requirements_management_test_reports USING btree (pipeline_id);
+
+CREATE INDEX index_requirements_management_test_reports_on_requirement_id ON public.requirements_management_test_reports USING btree (requirement_id);
+
CREATE INDEX index_requirements_on_author_id ON public.requirements USING btree (author_id);
CREATE INDEX index_requirements_on_created_at ON public.requirements USING btree (created_at);
@@ -10576,6 +10842,8 @@ CREATE UNIQUE INDEX index_scim_identities_on_user_id_and_group_id ON public.scim
CREATE UNIQUE INDEX index_scim_oauth_access_tokens_on_group_id_and_token_encrypted ON public.scim_oauth_access_tokens USING btree (group_id, token_encrypted);
+CREATE INDEX index_security_ci_builds_on_name_and_id ON public.ci_builds USING btree (name, id) 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, ('license_scanning'::character varying)::text])) AND ((type)::text = 'Ci::Build'::text));
+
CREATE INDEX index_self_managed_prometheus_alert_events_on_environment_id ON public.self_managed_prometheus_alert_events USING btree (environment_id);
CREATE INDEX index_sent_notifications_on_noteable_type_noteable_id ON public.sent_notifications USING btree (noteable_id) WHERE ((noteable_type)::text = 'Issue'::text);
@@ -10602,9 +10870,9 @@ CREATE INDEX index_services_on_type ON public.services USING btree (type);
CREATE INDEX index_services_on_type_and_id_and_template_when_active ON public.services USING btree (type, id, template) WHERE (active = true);
-CREATE UNIQUE INDEX index_services_on_type_and_instance ON public.services USING btree (type, instance) WHERE (instance IS TRUE);
+CREATE UNIQUE INDEX index_services_on_type_and_instance_partial ON public.services USING btree (type, instance) WHERE (instance = true);
-CREATE UNIQUE INDEX index_services_on_type_and_template ON public.services USING btree (type, template) WHERE (template IS TRUE);
+CREATE UNIQUE INDEX index_services_on_type_and_template_partial ON public.services USING btree (type, template) WHERE (template = true);
CREATE UNIQUE INDEX index_shards_on_name ON public.shards USING btree (name);
@@ -10632,6 +10900,8 @@ CREATE INDEX index_snippets_on_description_trigram ON public.snippets USING gin
CREATE INDEX index_snippets_on_file_name_trigram ON public.snippets USING gin (file_name public.gin_trgm_ops);
+CREATE INDEX index_snippets_on_id_and_type ON public.snippets USING btree (id, type);
+
CREATE INDEX index_snippets_on_project_id_and_visibility_level ON public.snippets USING btree (project_id, visibility_level);
CREATE INDEX index_snippets_on_title_trigram ON public.snippets USING gin (title public.gin_trgm_ops);
@@ -10788,8 +11058,6 @@ CREATE INDEX index_users_on_email_trigram ON public.users USING gin (email publi
CREATE INDEX index_users_on_feed_token ON public.users USING btree (feed_token);
-CREATE INDEX index_users_on_ghost ON public.users USING btree (ghost);
-
CREATE INDEX index_users_on_group_view ON public.users USING btree (group_view);
CREATE INDEX index_users_on_incoming_email_token ON public.users USING btree (incoming_email_token);
@@ -10806,7 +11074,7 @@ CREATE UNIQUE INDEX index_users_on_reset_password_token ON public.users USING bt
CREATE INDEX index_users_on_state ON public.users USING btree (state);
-CREATE INDEX index_users_on_state_and_user_type_internal ON public.users USING btree (state, user_type) WHERE (ghost IS NOT TRUE);
+CREATE INDEX index_users_on_state_and_user_type ON public.users USING btree (state, user_type);
CREATE UNIQUE INDEX index_users_on_static_object_token ON public.users USING btree (static_object_token);
@@ -10878,8 +11146,6 @@ CREATE UNIQUE INDEX index_vulnerability_occurrence_identifiers_on_unique_keys ON
CREATE INDEX index_vulnerability_occurrence_pipelines_on_pipeline_id ON public.vulnerability_occurrence_pipelines USING btree (pipeline_id);
-CREATE INDEX index_vulnerability_occurrences_on_id_and_confidence_eq_zero ON public.vulnerability_occurrences USING btree (id) WHERE (confidence = 0);
-
CREATE INDEX index_vulnerability_occurrences_on_primary_identifier_id ON public.vulnerability_occurrences USING btree (primary_identifier_id);
CREATE INDEX index_vulnerability_occurrences_on_scanner_id ON public.vulnerability_occurrences USING btree (scanner_id);
@@ -10890,8 +11156,6 @@ CREATE UNIQUE INDEX index_vulnerability_occurrences_on_uuid ON public.vulnerabil
CREATE INDEX index_vulnerability_occurrences_on_vulnerability_id ON public.vulnerability_occurrences USING btree (vulnerability_id);
-CREATE INDEX index_vulnerability_on_id_and_confidence_eq_zero ON public.vulnerabilities USING btree (id) WHERE (confidence = 0);
-
CREATE UNIQUE INDEX index_vulnerability_scanners_on_project_id_and_external_id ON public.vulnerability_scanners USING btree (project_id, external_id);
CREATE UNIQUE INDEX index_vulnerability_user_mentions_on_note_id ON public.vulnerability_user_mentions USING btree (note_id) WHERE (note_id IS NOT NULL);
@@ -10960,6 +11224,8 @@ CREATE INDEX note_mentions_temp_index ON public.notes USING btree (id, noteable_
CREATE UNIQUE INDEX one_canonical_wiki_page_slug_per_metadata ON public.wiki_page_slugs USING btree (wiki_page_meta_id) WHERE (canonical = true);
+CREATE INDEX package_name_index ON public.packages_packages USING btree (name);
+
CREATE INDEX packages_packages_verification_checksum_partial ON public.packages_package_files USING btree (verification_checksum) WHERE (verification_checksum IS NOT NULL);
CREATE INDEX packages_packages_verification_failure_partial ON public.packages_package_files USING btree (verification_failure) WHERE (verification_failure IS NOT NULL);
@@ -11171,6 +11437,9 @@ ALTER TABLE ONLY public.deploy_keys_projects
ALTER TABLE ONLY public.issue_assignees
ADD CONSTRAINT fk_5e0c8d9154 FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;
+ALTER TABLE ONLY public.project_access_tokens
+ ADD CONSTRAINT fk_5f7e8450e1 FOREIGN KEY (personal_access_token_id) REFERENCES public.personal_access_tokens(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY public.merge_requests
ADD CONSTRAINT fk_6149611a04 FOREIGN KEY (assignee_id) REFERENCES public.users(id) ON DELETE SET NULL;
@@ -11381,6 +11650,9 @@ ALTER TABLE ONLY public.fork_network_members
ALTER TABLE ONLY public.vulnerabilities
ADD CONSTRAINT fk_b1de915a15 FOREIGN KEY (author_id) REFERENCES public.users(id) ON DELETE SET NULL;
+ALTER TABLE ONLY public.project_access_tokens
+ ADD CONSTRAINT fk_b27801bfbf FOREIGN KEY (project_id) REFERENCES public.projects(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY public.protected_tag_create_access_levels
ADD CONSTRAINT fk_b4eb82fe3c FOREIGN KEY (group_id) REFERENCES public.namespaces(id) ON DELETE CASCADE;
@@ -11456,6 +11728,9 @@ ALTER TABLE ONLY public.lists
ALTER TABLE ONLY public.metrics_users_starred_dashboards
ADD CONSTRAINT fk_d76a2b9a8c FOREIGN KEY (project_id) REFERENCES public.projects(id) ON DELETE CASCADE;
+ALTER TABLE ONLY public.ci_pipelines
+ ADD CONSTRAINT fk_d80e161c54 FOREIGN KEY (ci_ref_id) REFERENCES public.ci_refs(id) ON DELETE SET NULL;
+
ALTER TABLE ONLY public.system_note_metadata
ADD CONSTRAINT fk_d83a918cb1 FOREIGN KEY (note_id) REFERENCES public.notes(id) ON DELETE CASCADE;
@@ -11591,6 +11866,9 @@ ALTER TABLE ONLY public.events
ALTER TABLE ONLY public.ip_restrictions
ADD CONSTRAINT fk_rails_04a93778d5 FOREIGN KEY (group_id) REFERENCES public.namespaces(id) ON DELETE CASCADE;
+ALTER TABLE ONLY public.ci_build_report_results
+ ADD CONSTRAINT fk_rails_056d298d48 FOREIGN KEY (project_id) REFERENCES public.projects(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY public.ci_daily_build_group_report_results
ADD CONSTRAINT fk_rails_0667f7608c FOREIGN KEY (project_id) REFERENCES public.projects(id) ON DELETE CASCADE;
@@ -11660,6 +11938,9 @@ ALTER TABLE ONLY public.diff_note_positions
ALTER TABLE ONLY public.users_security_dashboard_projects
ADD CONSTRAINT fk_rails_150cd5682c FOREIGN KEY (project_id) REFERENCES public.projects(id) ON DELETE CASCADE;
+ALTER TABLE ONLY public.ci_build_report_results
+ ADD CONSTRAINT fk_rails_16cb1ff064 FOREIGN KEY (build_id) REFERENCES public.ci_builds(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY public.project_deploy_tokens
ADD CONSTRAINT fk_rails_170e03cbaf FOREIGN KEY (project_id) REFERENCES public.projects(id) ON DELETE CASCADE;
@@ -11699,9 +11980,6 @@ ALTER TABLE ONLY public.epic_user_mentions
ALTER TABLE ONLY public.approver_groups
ADD CONSTRAINT fk_rails_1cdcbd7723 FOREIGN KEY (group_id) REFERENCES public.namespaces(id) ON DELETE CASCADE;
-ALTER TABLE ONLY public.ci_refs
- ADD CONSTRAINT fk_rails_1da48d19ce FOREIGN KEY (last_updated_by_pipeline_id) REFERENCES public.ci_pipelines(id) ON DELETE SET NULL;
-
ALTER TABLE ONLY public.packages_tags
ADD CONSTRAINT fk_rails_1dfc868911 FOREIGN KEY (package_id) REFERENCES public.packages_packages(id) ON DELETE CASCADE;
@@ -11729,6 +12007,9 @@ ALTER TABLE ONLY public.service_desk_settings
ALTER TABLE ONLY public.group_custom_attributes
ADD CONSTRAINT fk_rails_246e0db83a FOREIGN KEY (group_id) REFERENCES public.namespaces(id) ON DELETE CASCADE;
+ALTER TABLE ONLY public.requirements_management_test_reports
+ ADD CONSTRAINT fk_rails_24cecc1e68 FOREIGN KEY (pipeline_id) REFERENCES public.ci_pipelines(id) ON DELETE SET NULL;
+
ALTER TABLE ONLY public.group_wiki_repositories
ADD CONSTRAINT fk_rails_26f867598c FOREIGN KEY (group_id) REFERENCES public.namespaces(id) ON DELETE CASCADE;
@@ -11951,6 +12232,9 @@ ALTER TABLE ONLY public.clusters_applications_knative
ALTER TABLE ONLY public.terraform_states
ADD CONSTRAINT fk_rails_558901b030 FOREIGN KEY (locked_by_user_id) REFERENCES public.users(id);
+ALTER TABLE ONLY public.group_deploy_keys
+ ADD CONSTRAINT fk_rails_5682fc07f8 FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE RESTRICT;
+
ALTER TABLE ONLY public.issue_user_mentions
ADD CONSTRAINT fk_rails_57581fda73 FOREIGN KEY (issue_id) REFERENCES public.issues(id) ON DELETE CASCADE;
@@ -12065,6 +12349,9 @@ ALTER TABLE ONLY public.geo_hashed_storage_migrated_events
ALTER TABLE ONLY public.plan_limits
ADD CONSTRAINT fk_rails_69f8b6184f FOREIGN KEY (plan_id) REFERENCES public.plans(id) ON DELETE CASCADE;
+ALTER TABLE ONLY public.operations_feature_flags_issues
+ ADD CONSTRAINT fk_rails_6a8856ca4f FOREIGN KEY (feature_flag_id) REFERENCES public.operations_feature_flags(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY public.prometheus_alerts
ADD CONSTRAINT fk_rails_6d9b283465 FOREIGN KEY (environment_id) REFERENCES public.environments(id) ON DELETE CASCADE;
@@ -12164,6 +12451,9 @@ ALTER TABLE ONLY public.snippet_repositories
ALTER TABLE ONLY public.gpg_key_subkeys
ADD CONSTRAINT fk_rails_8b2c90b046 FOREIGN KEY (gpg_key_id) REFERENCES public.gpg_keys(id) ON DELETE CASCADE;
+ALTER TABLE ONLY public.board_user_preferences
+ ADD CONSTRAINT fk_rails_8b3b23ce82 FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY public.allowed_email_domains
ADD CONSTRAINT fk_rails_8b5da859f9 FOREIGN KEY (group_id) REFERENCES public.namespaces(id) ON DELETE CASCADE;
@@ -12188,6 +12478,9 @@ ALTER TABLE ONLY public.design_user_mentions
ALTER TABLE ONLY public.clusters_kubernetes_namespaces
ADD CONSTRAINT fk_rails_8df789f3ab FOREIGN KEY (environment_id) REFERENCES public.environments(id) ON DELETE SET NULL;
+ALTER TABLE ONLY public.alert_management_alert_user_mentions
+ ADD CONSTRAINT fk_rails_8e48eca0fe FOREIGN KEY (alert_management_alert_id) REFERENCES public.alert_management_alerts(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY public.project_daily_statistics
ADD CONSTRAINT fk_rails_8e549b272d FOREIGN KEY (project_id) REFERENCES public.projects(id) ON DELETE CASCADE;
@@ -12212,6 +12505,9 @@ ALTER TABLE ONLY public.list_user_preferences
ALTER TABLE ONLY public.board_labels
ADD CONSTRAINT fk_rails_9374a16edd FOREIGN KEY (board_id) REFERENCES public.boards(id) ON DELETE CASCADE;
+ALTER TABLE ONLY public.alert_management_alert_assignees
+ ADD CONSTRAINT fk_rails_93c0f6703b FOREIGN KEY (alert_id) REFERENCES public.alert_management_alerts(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY public.scim_identities
ADD CONSTRAINT fk_rails_9421a0bffb FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;
@@ -12320,6 +12616,9 @@ ALTER TABLE ONLY public.ci_build_trace_sections
ALTER TABLE ONLY public.clusters
ADD CONSTRAINT fk_rails_ac3a663d79 FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE SET NULL;
+ALTER TABLE ONLY public.packages_composer_metadata
+ ADD CONSTRAINT fk_rails_ad48c2e5bb FOREIGN KEY (package_id) REFERENCES public.packages_packages(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY public.analytics_cycle_analytics_group_stages
ADD CONSTRAINT fk_rails_ae5da3409b FOREIGN KEY (group_id) REFERENCES public.namespaces(id) ON DELETE CASCADE;
@@ -12470,6 +12769,9 @@ ALTER TABLE ONLY public.subscriptions
ALTER TABLE ONLY public.operations_strategies
ADD CONSTRAINT fk_rails_d183b6e6dd FOREIGN KEY (feature_flag_id) REFERENCES public.operations_feature_flags(id) ON DELETE CASCADE;
+ALTER TABLE ONLY public.requirements_management_test_reports
+ ADD CONSTRAINT fk_rails_d1e8b498bf FOREIGN KEY (author_id) REFERENCES public.users(id) ON DELETE SET NULL;
+
ALTER TABLE ONLY public.pool_repositories
ADD CONSTRAINT fk_rails_d2711daad4 FOREIGN KEY (source_project_id) REFERENCES public.projects(id) ON DELETE SET NULL;
@@ -12479,6 +12781,9 @@ ALTER TABLE ONLY public.group_group_links
ALTER TABLE ONLY public.vulnerability_issue_links
ADD CONSTRAINT fk_rails_d459c19036 FOREIGN KEY (vulnerability_id) REFERENCES public.vulnerabilities(id) ON DELETE CASCADE;
+ALTER TABLE ONLY public.alert_management_alert_assignees
+ ADD CONSTRAINT fk_rails_d47570ac62 FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY public.geo_hashed_storage_attachments_events
ADD CONSTRAINT fk_rails_d496b088e9 FOREIGN KEY (project_id) REFERENCES public.projects(id) ON DELETE CASCADE;
@@ -12491,6 +12796,9 @@ ALTER TABLE ONLY public.dependency_proxy_blobs
ALTER TABLE ONLY public.issues_prometheus_alert_events
ADD CONSTRAINT fk_rails_db5b756534 FOREIGN KEY (issue_id) REFERENCES public.issues(id) ON DELETE CASCADE;
+ALTER TABLE ONLY public.board_user_preferences
+ ADD CONSTRAINT fk_rails_dbebdaa8fe FOREIGN KEY (board_id) REFERENCES public.boards(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY public.vulnerability_occurrence_pipelines
ADD CONSTRAINT fk_rails_dc3ae04693 FOREIGN KEY (occurrence_id) REFERENCES public.vulnerability_occurrences(id) ON DELETE CASCADE;
@@ -12530,6 +12838,9 @@ ALTER TABLE ONLY public.approval_merge_request_rule_sources
ALTER TABLE ONLY public.prometheus_alerts
ADD CONSTRAINT fk_rails_e6351447ec FOREIGN KEY (prometheus_metric_id) REFERENCES public.prometheus_metrics(id) ON DELETE CASCADE;
+ALTER TABLE ONLY public.requirements_management_test_reports
+ ADD CONSTRAINT fk_rails_e67d085910 FOREIGN KEY (build_id) REFERENCES public.ci_builds(id) ON DELETE SET NULL;
+
ALTER TABLE ONLY public.merge_request_metrics
ADD CONSTRAINT fk_rails_e6d7c24d1b FOREIGN KEY (merge_request_id) REFERENCES public.merge_requests(id) ON DELETE CASCADE;
@@ -12548,12 +12859,18 @@ ALTER TABLE ONLY public.merge_request_blocks
ALTER TABLE ONLY public.protected_branch_unprotect_access_levels
ADD CONSTRAINT fk_rails_e9eb8dc025 FOREIGN KEY (protected_branch_id) REFERENCES public.protected_branches(id) ON DELETE CASCADE;
+ALTER TABLE ONLY public.alert_management_alert_user_mentions
+ ADD CONSTRAINT fk_rails_eb2de0cdef FOREIGN KEY (note_id) REFERENCES public.notes(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY public.ci_daily_report_results
ADD CONSTRAINT fk_rails_ebc2931b90 FOREIGN KEY (project_id) REFERENCES public.projects(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.cluster_providers_aws
ADD CONSTRAINT fk_rails_ed1fdfaeb2 FOREIGN KEY (created_by_user_id) REFERENCES public.users(id) ON DELETE SET NULL;
+ALTER TABLE ONLY public.project_security_settings
+ ADD CONSTRAINT fk_rails_ed4abe1338 FOREIGN KEY (project_id) REFERENCES public.projects(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY public.ci_daily_build_group_report_results
ADD CONSTRAINT fk_rails_ee072d13b3 FOREIGN KEY (last_pipeline_id) REFERENCES public.ci_pipelines(id) ON DELETE CASCADE;
@@ -12614,6 +12931,12 @@ ALTER TABLE ONLY public.merge_trains
ALTER TABLE ONLY public.ci_runner_namespaces
ADD CONSTRAINT fk_rails_f9d9ed3308 FOREIGN KEY (namespace_id) REFERENCES public.namespaces(id) ON DELETE CASCADE;
+ALTER TABLE ONLY public.requirements_management_test_reports
+ ADD CONSTRAINT fk_rails_fb3308ad55 FOREIGN KEY (requirement_id) REFERENCES public.requirements(id) ON DELETE CASCADE;
+
+ALTER TABLE ONLY public.operations_feature_flags_issues
+ ADD CONSTRAINT fk_rails_fb4d2a7cb1 FOREIGN KEY (issue_id) REFERENCES public.issues(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY public.board_project_recent_visits
ADD CONSTRAINT fk_rails_fb6fc419cb FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;
@@ -12648,282 +12971,6 @@ ALTER TABLE ONLY public.u2f_registrations
ADD CONSTRAINT fk_u2f_registrations_user_id FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;
COPY "schema_migrations" (version) FROM STDIN;
-20171230123729
-20180101160629
-20180101160630
-20180102220145
-20180103123548
-20180104131052
-20180105212544
-20180109183319
-20180113220114
-20180115094742
-20180115113902
-20180115201419
-20180116193854
-20180119121225
-20180119135717
-20180119160751
-20180122154930
-20180122162010
-20180125214301
-20180129193323
-20180201102129
-20180201110056
-20180201145907
-20180204200836
-20180206200543
-20180208183958
-20180209115333
-20180209165249
-20180212030105
-20180212101828
-20180212101928
-20180212102028
-20180213131630
-20180214093516
-20180214155405
-20180215181245
-20180216120000
-20180216120010
-20180216120020
-20180216120030
-20180216120040
-20180216120050
-20180216121020
-20180216121030
-20180219153455
-20180220150310
-20180221151752
-20180222043024
-20180223120443
-20180223124427
-20180223144945
-20180226050030
-20180227182112
-20180228172924
-20180301010859
-20180301084653
-20180302152117
-20180305095250
-20180305100050
-20180305144721
-20180306074045
-20180306134842
-20180306164012
-20180307012445
-20180308052825
-20180308125206
-20180309121820
-20180309160427
-20180314100728
-20180314145917
-20180315160435
-20180319190020
-20180320182229
-20180323150945
-20180326202229
-20180327101207
-20180330121048
-20180403035759
-20180405101928
-20180405142733
-20180408143354
-20180408143355
-20180409170809
-20180413022611
-20180416155103
-20180417090132
-20180417101040
-20180417101940
-20180418053107
-20180420010016
-20180420010616
-20180420080616
-20180423204600
-20180424090541
-20180424134533
-20180424151928
-20180424160449
-20180425075446
-20180425131009
-20180425205249
-20180426102016
-20180430101916
-20180430143705
-20180502122856
-20180503131624
-20180503141722
-20180503150427
-20180503175053
-20180503175054
-20180503193542
-20180503193953
-20180503200320
-20180504195842
-20180507083701
-20180508055821
-20180508100222
-20180508102840
-20180508135515
-20180511090724
-20180511131058
-20180511174224
-20180512061621
-20180514161336
-20180515005612
-20180515121227
-20180517082340
-20180523042841
-20180523125103
-20180524132016
-20180529093006
-20180529152628
-20180530135500
-20180531185349
-20180531220618
-20180601213245
-20180603190921
-20180604123514
-20180607071808
-20180608091413
-20180608110058
-20180608201435
-20180612103626
-20180613081317
-20180625113853
-20180626125654
-20180628124813
-20180629153018
-20180629191052
-20180702120647
-20180702124358
-20180702134423
-20180704145007
-20180704204006
-20180705160945
-20180706223200
-20180710162338
-20180711103851
-20180711103922
-20180713092803
-20180717125853
-20180718005113
-20180720023512
-20180722103201
-20180723135214
-20180726172057
-20180807153545
-20180808162000
-20180809195358
-20180813101999
-20180813102000
-20180814153625
-20180815040323
-20180815160409
-20180815170510
-20180815175440
-20180816161409
-20180816193530
-20180824202952
-20180826111825
-20180831164905
-20180831164907
-20180831164908
-20180831164909
-20180831164910
-20180901171833
-20180901200537
-20180902070406
-20180906101639
-20180907015926
-20180910115836
-20180910153412
-20180910153413
-20180912111628
-20180913142237
-20180914162043
-20180914201132
-20180916011959
-20180917172041
-20180924141949
-20180924190739
-20180924201039
-20180925200829
-20180927073410
-20181002172433
-20181005110927
-20181005125926
-20181006004100
-20181008145341
-20181008145359
-20181008200441
-20181009190428
-20181010133639
-20181010235606
-20181013005024
-20181014203236
-20181015155839
-20181016141739
-20181016152238
-20181017001059
-20181019032400
-20181019032408
-20181019105553
-20181022135539
-20181022173835
-20181023104858
-20181023144439
-20181025115728
-20181026091631
-20181026143227
-20181027114222
-20181028120717
-20181030135124
-20181030154446
-20181031145139
-20181031190558
-20181031190559
-20181101091005
-20181101091124
-20181101144347
-20181101191341
-20181105201455
-20181106135939
-20181107054254
-20181108091549
-20181112103239
-20181115140140
-20181116050532
-20181116141415
-20181116141504
-20181119081539
-20181119132520
-20181120082911
-20181120091639
-20181120151656
-20181121101842
-20181121101843
-20181121111200
-20181122160027
-20181123042307
-20181123135036
-20181123144235
-20181126150622
-20181126153547
-20181128123704
-20181129104854
-20181129104944
-20181130102132
-20181203002526
-20181205171941
-20181211092510
-20181211092514
-20181212104941
-20181212171634
-20181219130552
-20181219145520
-20181219145521
20181228175414
20190102152410
20190103140724
@@ -13700,6 +13747,7 @@ COPY "schema_migrations" (version) FROM STDIN;
20200323134519
20200324093258
20200324115359
+20200325094612
20200325104755
20200325104756
20200325104833
@@ -13720,6 +13768,11 @@ COPY "schema_migrations" (version) FROM STDIN;
20200330121000
20200330123739
20200330132913
+20200330203826
+20200330203837
+20200331103637
+20200331113728
+20200331113738
20200331132103
20200331195952
20200331220930
@@ -13756,6 +13809,7 @@ COPY "schema_migrations" (version) FROM STDIN;
20200407222647
20200408110856
20200408125046
+20200408132152
20200408133211
20200408153842
20200408154331
@@ -13805,8 +13859,11 @@ COPY "schema_migrations" (version) FROM STDIN;
20200420172752
20200420172927
20200420201933
+20200421054930
+20200421054948
20200421092907
20200421111005
+20200421195234
20200421233150
20200422091541
20200422213749
@@ -13826,11 +13883,14 @@ COPY "schema_migrations" (version) FROM STDIN;
20200429001827
20200429002150
20200429015603
+20200429023324
20200429181335
20200429181955
20200429182245
20200430103158
+20200430123614
20200430130048
+20200430174637
20200505164958
20200505171834
20200505172405
@@ -13838,7 +13898,11 @@ COPY "schema_migrations" (version) FROM STDIN;
20200506125731
20200506154421
20200507221434
+20200508021128
+20200508050301
20200508091106
+20200508140959
+20200508203901
20200511080113
20200511083541
20200511092246
@@ -13854,9 +13918,14 @@ COPY "schema_migrations" (version) FROM STDIN;
20200511145545
20200511162057
20200511162115
+20200511181027
+20200511191027
+20200511208012
20200511220023
20200512085150
+20200512160004
20200512164334
+20200512195442
20200513160930
20200513171959
20200513224143
@@ -13867,5 +13936,67 @@ COPY "schema_migrations" (version) FROM STDIN;
20200514000132
20200514000340
20200515155620
+20200518091745
+20200518114540
+20200518133123
+20200519074709
+20200519101002
+20200519115908
+20200519141534
+20200519171058
+20200519194042
+20200520103514
+20200521022725
+20200521225327
+20200521225337
+20200521225346
+20200522235146
+20200525114553
+20200525121014
+20200525144525
+20200526000407
+20200526013844
+20200526120714
+20200526142550
+20200526153844
+20200526164946
+20200526164947
+20200527092027
+20200527094322
+20200527095401
+20200527135313
+20200527151413
+20200527152116
+20200527152657
+20200527170649
+20200527211000
+20200528054112
+20200528123703
+20200528125905
+20200528171933
+20200601210148
+20200602013900
+20200602013901
+20200602143020
+20200603073101
+20200603180338
+20200604143628
+20200604145731
+20200604174544
+20200604174558
+20200605003204
+20200605093113
+20200608072931
+20200608075553
+20200608214008
+20200609002841
+20200609142506
+20200609142507
+20200609142508
+20200609212701
+20200615083635
+20200615121217
+20200615123055
+20200615232735
\.
diff --git a/doc/.vale/gitlab/Acronyms.yml b/doc/.vale/gitlab/Acronyms.yml
new file mode 100644
index 00000000000..5176a18e2b6
--- /dev/null
+++ b/doc/.vale/gitlab/Acronyms.yml
@@ -0,0 +1,71 @@
+---
+# Warning: gitlab.Acronyms
+#
+# Checks for unexpanded acronyms.
+#
+# For a list of all options, see https://errata-ai.github.io/vale/styles/
+extends: conditional
+message: '"%s" has no definition.'
+link: https://about.gitlab.com/handbook/marketing/growth-marketing/content/editorial-team/#acronyms
+level: warning
+ignorecase: false
+# Ensures that the existence of 'first' implies the existence of 'second'.
+first: '\b([A-Z]{3,5})\b'
+second: '(?:\b[A-Z][a-z]+ )+\(([A-Z]{3,5})\)'
+# ... with the exception of these:
+exceptions:
+ - API
+ - ARN
+ - ASCII
+ - AWS
+ - CNAME
+ - CPU
+ - CSS
+ - CSV
+ - DNS
+ - EKS
+ - GDK
+ - GET
+ - GNU
+ - GPG
+ - GPL
+ - HTML
+ - HTTP
+ - HTTPS
+ - IAM
+ - IDE
+ - JSON
+ - LDAP
+ - LDAPS
+ - LESS
+ - LFS
+ - NFS
+ - NGINX
+ - NOTE
+ - ONLY
+ - PGP
+ - PHP
+ - POST
+ - PUT
+ - RPC
+ - RSA
+ - RSS
+ - SAML
+ - SCP
+ - SCSS
+ - SHA
+ - SQL
+ - SSH
+ - SSL
+ - SSO
+ - TIP
+ - TLS
+ - TODO
+ - TOML
+ - UNIX
+ - URI
+ - URL
+ - VPC
+ - WIP
+ - XML
+ - YAML
diff --git a/doc/.vale/gitlab/BadgeCapitalization.yml b/doc/.vale/gitlab/BadgeCapitalization.yml
index 7e68a06b4d5..c9e9da3b6ce 100644
--- a/doc/.vale/gitlab/BadgeCapitalization.yml
+++ b/doc/.vale/gitlab/BadgeCapitalization.yml
@@ -1,5 +1,7 @@
---
-# Verifies that badges are not lower case, which won't render properly.
+# Error: gitlab.BadgeCapitalization
+#
+# Verifies that badges are not mixed case, which won't render properly.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
extends: existence
diff --git a/doc/.vale/gitlab/British.yml b/doc/.vale/gitlab/British.yml
index 943e85beba1..1e5841d3648 100644
--- a/doc/.vale/gitlab/British.yml
+++ b/doc/.vale/gitlab/British.yml
@@ -1,9 +1,11 @@
---
-# Checks for use of some of the top misused terms at GitLab.
+# Error: gitlab.British
+#
+# Checks that US spelling is used over British spelling.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
extends: substitution
-message: 'Use the American spelling "%s" instead of the British "%s".'
+message: 'Use the US spelling "%s" instead of the British "%s".'
link: https://about.gitlab.com/handbook/communication/#top-misused-terms
level: error
ignorecase: true
diff --git a/doc/.vale/gitlab/CodeblockFences.yml b/doc/.vale/gitlab/CodeblockFences.yml
new file mode 100644
index 00000000000..8b61a1a3c16
--- /dev/null
+++ b/doc/.vale/gitlab/CodeblockFences.yml
@@ -0,0 +1,13 @@
+---
+# Error: gitlab.CodeblockFences
+#
+# Ensures all codeblock language tags use the full name, not aliases.
+#
+# For a list of all options, see https://errata-ai.github.io/vale/styles/
+extends: existence
+message: 'Syntax highlighting hint "%s" must be one of: yaml, ruby, plaintext, markdown, javascript, shell, golang, python, dockerfile, or typescript.'
+link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#code-blocks
+level: error
+scope: raw
+raw:
+ - '\`\`\`(yml|rb|text|md|bash|sh\n|js\n|go\n|py\n|docker\n|ts)'
diff --git a/doc/.vale/gitlab/Contractions.yml b/doc/.vale/gitlab/Contractions.yml
index f4ec24742da..45212945c53 100644
--- a/doc/.vale/gitlab/Contractions.yml
+++ b/doc/.vale/gitlab/Contractions.yml
@@ -1,9 +1,11 @@
---
+# Suggestion: gitlab.Contractions
+#
# Checks for use of common and uncommon contractions.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
extends: substitution
-message: Use "%s" instead of "%s", for a friendly, informal tone.
+message: 'Use "%s" instead of "%s", for a friendly, informal tone.'
link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#language
level: suggestion
nonword: false
diff --git a/doc/.vale/gitlab/CurlStringsQuoted.yml b/doc/.vale/gitlab/CurlStringsQuoted.yml
new file mode 100644
index 00000000000..4fcb0069423
--- /dev/null
+++ b/doc/.vale/gitlab/CurlStringsQuoted.yml
@@ -0,0 +1,13 @@
+---
+# Warning: gitlab.CurlStringsQuoted
+#
+# Ensures all codeblocks using curl quote any URL strings.
+#
+# For a list of all options, see https://errata-ai.github.io/vale/styles/
+extends: existence
+message: 'Curl commands must wrap URLs in double quotes ("): %s'
+link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#curl-commands
+level: warning
+scope: code
+raw:
+ - 'curl.*[^"=]https?://.*'
diff --git a/doc/.vale/gitlab/FirstPerson.yml b/doc/.vale/gitlab/FirstPerson.yml
index 18c5265b0a6..6db89dd4758 100644
--- a/doc/.vale/gitlab/FirstPerson.yml
+++ b/doc/.vale/gitlab/FirstPerson.yml
@@ -1,8 +1,11 @@
+---
+# Warning: gitlab.FirstPerson
+#
# Checks for use of first person pronouns.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
extends: existence
-message: '`%s` is a first-person pronoun. Use second- or third-person pronouns (like we, you, us, one) instead.'
+message: '"%s" is a first-person pronoun. Use second- or third-person pronouns (like we, you, us, one) instead.'
level: warning
ignorecase: true
link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#language
diff --git a/doc/.vale/gitlab/InternalLinkExtension.yml b/doc/.vale/gitlab/InternalLinkExtension.yml
index d07a2600798..94a935196a7 100644
--- a/doc/.vale/gitlab/InternalLinkExtension.yml
+++ b/doc/.vale/gitlab/InternalLinkExtension.yml
@@ -1,9 +1,11 @@
---
+# Error: gitlab.InternalLinkExtension
+#
# Checks that internal links have .md extenstion and not .html extension.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
extends: existence
-message: Link %s must use the .md file extension.
+message: 'Link "%s" must use the .md file extension.'
link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#links-to-internal-documentation
level: error
scope: raw
diff --git a/doc/.vale/gitlab/LatinTerms.yml b/doc/.vale/gitlab/LatinTerms.yml
index 8412631f8fe..a2d024fb1ec 100644
--- a/doc/.vale/gitlab/LatinTerms.yml
+++ b/doc/.vale/gitlab/LatinTerms.yml
@@ -1,9 +1,11 @@
---
-# Checks for use of latin terms..
+# Warning: gitlab.LatinTerms
+#
+# Checks for use of latin terms.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
extends: substitution
-message: Use "%s" instead of "%s," but consider rewriting the sentence.
+message: 'Use "%s" instead of "%s", but consider rewriting the sentence.'
link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#language
level: warning
nonword: true
diff --git a/doc/.vale/gitlab/MeaningfulLinkWords.yml b/doc/.vale/gitlab/MeaningfulLinkWords.yml
new file mode 100644
index 00000000000..1931112ab3e
--- /dev/null
+++ b/doc/.vale/gitlab/MeaningfulLinkWords.yml
@@ -0,0 +1,15 @@
+---
+# Warning: gitlab.MeaningfulLinkWords
+#
+# Checks for the presence of semantically unhelpful words in link text.
+#
+# For a list of all options, see https://errata-ai.github.io/vale/styles/
+extends: existence
+message: 'Improve SEO and accessibility by rewriting "%s" in the link text.'
+level: warning
+scope: link
+ignorecase: true
+link: https://about.gitlab.com/handbook/communication/#writing-style-guidelines
+tokens:
+ - here
+ - this page
diff --git a/doc/.vale/gitlab/MergeConflictMarkers.yml b/doc/.vale/gitlab/MergeConflictMarkers.yml
new file mode 100644
index 00000000000..4d733c856e5
--- /dev/null
+++ b/doc/.vale/gitlab/MergeConflictMarkers.yml
@@ -0,0 +1,13 @@
+---
+# Error: gitlab.MergeConflictMarkers
+#
+# Checks for the presence of merge conflict markers.
+#
+# For a list of all options, see https://errata-ai.github.io/vale/styles/
+extends: existence
+message: 'Merge conflict marker "%s" found.'
+link: https://docs.gitlab.com/ee/development/code_review.html#merging-a-merge-request
+level: error
+scope: raw
+raw:
+ - '\n<<<<<<< .+\n|\n=======\n|\n>>>>>>> .+\n'
diff --git a/doc/.vale/gitlab/OxfordComma.yml b/doc/.vale/gitlab/OxfordComma.yml
index 4b37ba8c2b9..e04d209d960 100644
--- a/doc/.vale/gitlab/OxfordComma.yml
+++ b/doc/.vale/gitlab/OxfordComma.yml
@@ -1,10 +1,12 @@
---
+# Warning: gitlab.OxfordComma
+#
# Checks for the lack of an Oxford comma. In some cases, will catch overly
# complex sentence structures with lots of commas.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
extends: existence
-message: Use a comma before the last "and" or "or" in a list of four or more items.
+message: 'Use a comma before the last "and" or "or" in a list of four or more items.'
link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#punctuation
level: warning
raw:
diff --git a/doc/.vale/gitlab/Profanity.yml b/doc/.vale/gitlab/Profanity.yml
deleted file mode 100644
index c386b23e52c..00000000000
--- a/doc/.vale/gitlab/Profanity.yml
+++ /dev/null
@@ -1,30 +0,0 @@
----
-extends: existence
-message: "Remove profanity: '%s'"
-ignorecase: true
-level: error
-tokens:
- - 'arse(hole)?'
- - 'ass(hole)?'
- - 'bastard'
- - 'bitch'
- - 'bloody'
- - 'bollocks'
- - 'bugger'
- - 'cocksucker'
- - 'crap'
- - 'cunt'
- - 'damn'
- - 'eff(ing)?'
- - 'fart'
- - 'fuck(er|ing)?'
- - 'goddamn(it?|ed)'
- - 'hell'
- - 'horseshit'
- - 'motherfuck(ers?|ing)'
- - 'piss(ing)?'
- - 'shit'
- - 'tits'
- - 'turd'
- - 'twat'
- - 'wank(er|ing)?'
diff --git a/doc/.vale/gitlab/ReferenceLinks.yml b/doc/.vale/gitlab/ReferenceLinks.yml
index 35a657710de..8a3b6940187 100644
--- a/doc/.vale/gitlab/ReferenceLinks.yml
+++ b/doc/.vale/gitlab/ReferenceLinks.yml
@@ -1,3 +1,6 @@
+---
+# Error: gitlab.ReferenceLinks
+#
# Checks for the presence of reference-style links that must be inline.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
diff --git a/doc/.vale/gitlab/RelativeLinks.yml b/doc/.vale/gitlab/RelativeLinks.yml
index 95bd60dd6e4..de24d0608e7 100644
--- a/doc/.vale/gitlab/RelativeLinks.yml
+++ b/doc/.vale/gitlab/RelativeLinks.yml
@@ -1,9 +1,11 @@
---
+# Error: gitlab.RelativeLinks
+#
# Checks for the presence of absolute hyperlinks that should be relative.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
extends: existence
-message: Link %s must be relative.
+message: 'Link "%s" must be relative.'
link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#links-to-internal-documentation
level: error
scope: raw
diff --git a/doc/.vale/gitlab/Repetition.yml b/doc/.vale/gitlab/Repetition.yml
index 8477a4feb58..76afb7bb5ab 100644
--- a/doc/.vale/gitlab/Repetition.yml
+++ b/doc/.vale/gitlab/Repetition.yml
@@ -1,3 +1,6 @@
+---
+# Error: gitlab.Repetition
+#
# Checks for duplicate words, like `the the` or `and and`.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
diff --git a/doc/.vale/gitlab/SentenceLength.yml b/doc/.vale/gitlab/SentenceLength.yml
new file mode 100644
index 00000000000..b19b76723a6
--- /dev/null
+++ b/doc/.vale/gitlab/SentenceLength.yml
@@ -0,0 +1,13 @@
+---
+# Warning: gitlab.SentenceLength
+#
+# Counts words in a sentence and alerts if a sentence exceeds 25 words.
+#
+# For a list of all options, see https://errata-ai.github.io/vale/styles/
+extends: occurrence
+message: 'Shorter sentences improve readability (max 25 words).'
+scope: sentence
+link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#language
+level: warning
+max: 25
+token: \b(\w+)\b
diff --git a/doc/.vale/gitlab/SentenceSpacing.yml b/doc/.vale/gitlab/SentenceSpacing.yml
index b061f7f6f9e..c460ef3ae65 100644
--- a/doc/.vale/gitlab/SentenceSpacing.yml
+++ b/doc/.vale/gitlab/SentenceSpacing.yml
@@ -1,4 +1,6 @@
---
+# Error: gitlab.SentenceSpacing
+#
# Check for the following in common content scenarios:
#
# - No spaces.
diff --git a/doc/.vale/gitlab/Spelling.yml b/doc/.vale/gitlab/Spelling.yml
index 9b9b1ef10c2..7bf0f085f5c 100644
--- a/doc/.vale/gitlab/Spelling.yml
+++ b/doc/.vale/gitlab/Spelling.yml
@@ -1,3 +1,6 @@
+---
+# Warning: gitlab.Spelling
+#
# Checks for possible spelling mistakes in content, not code. May find false positives
# due to links using angle brackets: <https://example.com>. These can be ignored.
#
diff --git a/doc/.vale/gitlab/SubstitutionWarning.yml b/doc/.vale/gitlab/SubstitutionWarning.yml
index fe690d708ed..8c5f7705417 100644
--- a/doc/.vale/gitlab/SubstitutionWarning.yml
+++ b/doc/.vale/gitlab/SubstitutionWarning.yml
@@ -1,4 +1,6 @@
---
+# Warning: gitlab.SubstitutionWarning
+#
# Warns against using common shorthand for terms.
# For substitutions flagged as errors, see Substitutions.yml
#
@@ -10,7 +12,9 @@ level: warning
ignorecase: true
swap:
admin: administrator
+ blacklist(ed|ing)?: denylist
config: configuration
distro: distribution
info: information
repo: repository
+ whitelist(ed|ing)?: allowlist
diff --git a/doc/.vale/gitlab/Substitutions.yml b/doc/.vale/gitlab/Substitutions.yml
index b9c0dbecf31..156ff3a53f0 100644
--- a/doc/.vale/gitlab/Substitutions.yml
+++ b/doc/.vale/gitlab/Substitutions.yml
@@ -1,4 +1,6 @@
---
+# Error: gitlab.Substitutions
+#
# Checks for use of some of the top misused terms at GitLab.
# For substitutions only flagged as warnings, see SubstitutionWarning.yml
#
@@ -9,6 +11,7 @@ link: https://about.gitlab.com/handbook/communication/#top-misused-terms
level: error
ignorecase: true
swap:
+ frontmatter: front matter
GitLabber: GitLab team member
gitlab omnibus: Omnibus GitLab
param: parameter
diff --git a/doc/.vale/gitlab/VersionText.yml b/doc/.vale/gitlab/VersionText.yml
index c572a1a926c..9a05103cc39 100644
--- a/doc/.vale/gitlab/VersionText.yml
+++ b/doc/.vale/gitlab/VersionText.yml
@@ -1,4 +1,6 @@
---
+# Error: gitlab.VersionText
+#
# Checks that version text is formatted correctly.
#
# Specifically looks for either of the following that is immediately followed on the next line
diff --git a/doc/.vale/gitlab/spelling-exceptions.txt b/doc/.vale/gitlab/spelling-exceptions.txt
index c5e89f72043..b56fa2861ca 100644
--- a/doc/.vale/gitlab/spelling-exceptions.txt
+++ b/doc/.vale/gitlab/spelling-exceptions.txt
@@ -1,13 +1,20 @@
Akismet
Alertmanager
Algolia
+Alibaba
+allowlist
+allowlisting
+allowlists
+anonymized
Ansible
Anthos
API
approvers
+architected
Artifactory
Asana
Asciidoctor
+Assembla
Atlassian
Auth0
Authentiq
@@ -25,7 +32,10 @@ autoscaler
autoscales
autoscaling
awardable
+Axios
Azure
+B-tree
+backfilling
backport
backported
backporting
@@ -34,6 +44,7 @@ backtrace
backtraced
backtraces
backtracing
+badging
Bamboo
Bitbucket
blockquote
@@ -41,6 +52,7 @@ blockquoted
blockquotes
blockquoting
boolean
+Bootsnap
browsable
Bugzilla
Buildkite
@@ -52,8 +64,16 @@ burndown
cacheable
CAS
CentOS
-Chatops
+Certbot
+chai
+chatbot
+chatbots
+ChatOps
+checksummed
+checksumming
Citrix
+Citus
+clonable
Cloudwatch
Cobertura
Cognito
@@ -63,6 +83,7 @@ compilable
composable
Conda
Consul
+Corosync
cron
crons
crontab
@@ -72,41 +93,67 @@ crosslinking
crosslinks
Crossplane
CrowdIn
+Dangerfile
+datetime
Debian
deduplicate
deduplicated
deduplicates
deduplicating
deduplication
+deliverables
+denylist
+denylisting
+denylists
+deployer
+deployers
deprovision
deprovisioned
deprovisioning
deprovisions
+dequarantine
+dequarantined
+dequarantining
+DevOps
discoverability
Disqus
Dockerfile
Dockerfiles
+dogfood
+dogfoods
+dogfooding
dotenv
downvoted
downvotes
Dpl
Dreamweaver
+Ecto
Elasticsearch
enablement
enqueued
+enum
+enums
+ETag
+Excon
expirable
Facebook
failover
failovers
failsafe
+fastlane
favicon
+Filebeat
+Fio
firewalled
Flawfinder
Flowdock
Fluentd
Forgerock
+Fugit
Gantt
Gemnasium
+Gemojione
+gettext
Git
Gitaly
Gitea
@@ -115,6 +162,7 @@ GitLab
gitlabsos
Gitleaks
Gitter
+globals
Gmail
Google
Gosec
@@ -122,6 +170,7 @@ Gradle
Grafana
gravatar
Gzip
+Haml
hardcode
hardcoded
hardcodes
@@ -140,6 +189,7 @@ hotfixing
http
https
idempotence
+idmapper
Ingress
initializer
initializers
@@ -152,39 +202,56 @@ jasmine-jquery
JavaScript
Jaeger
Jenkins
+Jenkinsfile
Jira
jQuery
+jsdom
JupyterHub
kanban
kanbans
+Kaniko
Karma
Kerberos
Kibana
+Kinesis
Knative
Kramdown
+kubectl
Kubernetes
Kubesec
Laravel
LDAP
+ldapsearch
+Leiningen
Libravatar
Lograge
+Logstash
lookahead
lookaheads
lookbehind
lookbehinds
lookups
+loopback
Lucene
Maildir
+Mailgun
Makefile
Makefiles
Markdown
markdownlint
+matcher
+matchers
Mattermost
mbox
+memoization
+memoize
+memoized
+memoizing
mergeable
Microsoft
middleware
middlewares
+migratus
Minikube
MinIO
mitmproxy
@@ -195,16 +262,24 @@ misconfiguration
misconfigurations
misconfiguring
mitigations
+mixin
+mixins
mockup
mockups
ModSecurity
+monorepo
+monorepos
+mutex
nameserver
nameservers
namespace
namespaced
namespaces
+namespacing
+namespacings
Nanoc
NGINX
+Nokogiri
npm
Nurtch
OAuth
@@ -213,17 +288,24 @@ offboarded
offboarding
offboards
OmniAuth
+onboarding
OpenID
OpenShift
Packagist
parallelization
parallelizations
+passwordless
+Patroni
performant
+phaser
+phasers
Pipfile
Pipfiles
Piwik
PgBouncer
plaintext
+Poedit
+pooler
PostgreSQL
precompile
preconfigure
@@ -233,8 +315,12 @@ prefill
prefilled
prefilling
prefills
+preload
+preloading
+preloads
prepend
prepended
+prepending
prepends
Pritaly
profiler
@@ -242,8 +328,8 @@ Prometheus
proxied
proxies
proxying
-Pseudonymized
-Pseudonymizer
+pseudonymized
+pseudonymizer
Puma
Python
Qualys
@@ -259,20 +345,27 @@ Redcarpet
Redis
Redmine
reCAPTCHA
+redirection
+redirections
+refactorings
referer
referers
+reflog
+reflogs
reindex
reindexed
reindexes
reindexing
relicensing
remediations
-Repmgr
-Repmgrd
+repmgr
+repmgrd
+repurposing
requeue
requeued
requeues
reusability
+Restlet
resynced
resyncing
resyncs
@@ -287,6 +380,8 @@ reverified
reverifies
reverify
Rubix
+Rubocop
+Rubular
runbook
runbooks
runit
@@ -294,11 +389,15 @@ runtime
runtimes
Salesforce
SAML
+sandboxing
sbt
+scatterplot
+scatterplots
Sendmail
Sentry
serverless
Sidekiq
+Sisense
sharding
shfmt
Shibboleth
@@ -309,13 +408,18 @@ serializing
Sitespeed
Slack
Slony
+smartcard
+smartcards
SMTP
Sobelow
+Sourcegraph
spidering
Splunk
SpotBugs
SSH
+Stackdriver
storable
+storages
strace
strikethrough
strikethroughs
@@ -340,7 +444,9 @@ subquerying
substring
substrings
syslog
+tcpdump
Tiller
+timecop
todos
tokenizer
Tokenizers
@@ -352,13 +458,15 @@ tooltips
Trello
triaging
TypeScript
+Twilio
Twitter
Ubuntu
unarchive
unarchived
unarchives
-Unassign
-Unassigns
+unarchiving
+unassign
+unassigns
uncheck
unchecked
unchecking
@@ -380,6 +488,7 @@ unmergeable
unmerged
unmerges
unmerging
+unmocked
unoptimize
unoptimized
unoptimizes
@@ -393,14 +502,20 @@ unpublished
unpublishes
unpublishing
unreferenced
+unregister
+unregistered
+unregisters
+unreplicated
unresolve
unresolved
unresolving
unschedule
+unscoped
unstage
unstaged
unstages
unstaging
+unstarted
unstash
unstashed
unstashing
@@ -418,6 +533,9 @@ upvotes
validator
validators
vendored
+versionless
+viewport
+viewports
virtualized
virtualizing
Vue
@@ -425,14 +543,22 @@ Vuex
walkthrough
walkthroughs
WebdriverIO
+Webex
webpack
webserver
whitepaper
whitepapers
+wireframe
+wireframes
+wireframed
+wireframing
Wireshark
Wordpress
+worktree
+worktrees
Xcode
Xeon
YouTrack
Zeitwerk
Zendesk
+zsh
diff --git a/doc/README.md b/doc/README.md
index c9511b22f8f..fe38b6cb419 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -289,7 +289,7 @@ The following documentation relates to the DevOps **Release** stage:
| [Environment-specific variables](ci/variables/README.md#limit-the-environment-scopes-of-environment-variables) | Limit the scope of variables to specific environments. |
| [GitLab CI/CD](ci/README.md) | Explore the features and capabilities of Continuous Deployment and Delivery with GitLab. |
| [GitLab Pages](user/project/pages/index.md) | Build, test, and deploy a static site directly from GitLab. |
-| [Protected Runners](ci/runners/README.md#protected-runners) | Select Runners to only pick jobs for protected branches and tags. |
+| [Protected Runners](ci/runners/README.md#prevent-runners-from-revealing-sensitive-information) | Select Runners to only pick jobs for protected branches and tags. |
| [Scheduled Pipelines](ci/pipelines/schedules.md) | Execute pipelines on a schedule. |
<div align="right">
@@ -363,7 +363,7 @@ The following documentation relates to the DevOps **Secure** stage:
| Secure Topics | Description |
|:------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------|
| [Compliance Dashboard](user/compliance/compliance_dashboard/index.md) **(ULTIMATE)** | View the most recent Merge Request activity in a group. |
-| [Container Scanning](user/application_security/container_scanning/index.md) **(ULTIMATE)** | Use Clair to scan docker images for known vulnerabilities. |
+| [Container Scanning](user/application_security/container_scanning/index.md) **(ULTIMATE)** | Use Clair to scan Docker images for known vulnerabilities. |
| [Dependency List](user/application_security/dependency_list/index.md) **(ULTIMATE)** | View your project's dependencies and their known vulnerabilities. |
| [Dependency Scanning](user/application_security/dependency_scanning/index.md) **(ULTIMATE)** | Analyze your dependencies for known vulnerabilities. |
| [Dynamic Application Security Testing (DAST)](user/application_security/dast/index.md) **(ULTIMATE)** | Analyze running web applications for known vulnerabilities. |
diff --git a/doc/administration/audit_events.md b/doc/administration/audit_events.md
index e42982e6524..cc94d756f99 100644
--- a/doc/administration/audit_events.md
+++ b/doc/administration/audit_events.md
@@ -1,6 +1,6 @@
---
-stage: Monitor
-group: APM
+stage: Manage
+group: Analytics
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
---
@@ -36,7 +36,7 @@ There are two kinds of events logged:
### Impersonation data **(PREMIUM)**
-> [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 Premium](https://about.gitlab.com/pricing/) 13.0.
Impersonation is where an administrator uses credentials to perform an action as a different user.
@@ -93,13 +93,15 @@ From there, you can see the following actions:
- Release was added to a project
- Release was updated
- Release milestone associations changed
-- Permission to approve merge requests by committers was updated ([introduced](https://gitlab.com/gitlab-org/gitlab/issues/7531) in GitLab 12.9)
-- Permission to approve merge requests by authors was updated ([introduced](https://gitlab.com/gitlab-org/gitlab/issues/7531) in GitLab 12.9)
-- Number of required approvals was updated ([introduced](https://gitlab.com/gitlab-org/gitlab/issues/7531) in GitLab 12.9)
+- Permission to approve merge requests by committers was updated ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7531) in GitLab 12.9)
+- Permission to approve merge requests by authors was updated ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7531) in GitLab 12.9)
+- Number of required approvals was updated ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7531) in GitLab 12.9)
+
+Project events can also be accessed via the [Project Audit Events API](../api/audit_events.md#project-audit-events-starter)
### Instance events **(PREMIUM ONLY)**
-> [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 Premium](https://about.gitlab.com/pricing/) 9.3.
Server-wide audit logging introduces the ability to observe user actions across
the entire instance of your GitLab server, making it easy to understand who
@@ -118,10 +120,10 @@ recorded:
- Ask for password reset
- Grant OAuth access
- Started or stopped user impersonation
-- Changed username ([introduced](https://gitlab.com/gitlab-org/gitlab/issues/7797) in GitLab 12.8)
-- User was deleted ([introduced](https://gitlab.com/gitlab-org/gitlab/issues/251) in GitLab 12.8)
-- User was added ([introduced](https://gitlab.com/gitlab-org/gitlab/issues/251) in GitLab 12.8)
-- User was blocked via Admin Area ([introduced](https://gitlab.com/gitlab-org/gitlab/issues/251) in GitLab 12.8)
+- Changed username ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7797) in GitLab 12.8)
+- User was deleted ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/251) in GitLab 12.8)
+- User was added ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/251) in GitLab 12.8)
+- User was blocked via Admin Area ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/251) in GitLab 12.8)
- User was blocked via API ([introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25872) in GitLab 12.9)
It's possible to filter particular actions by choosing an audit data type from
@@ -152,7 +154,7 @@ It may make the user interface for your project or audit logs very busy, and the
to prevent performance degradations on GitLab instances with very high Git write traffic.
In an upcoming release, Audit Logs for Git push events will be enabled
-by default. Follow [#7865](https://gitlab.com/gitlab-org/gitlab/issues/7865) for updates.
+by default. Follow [#7865](https://gitlab.com/gitlab-org/gitlab/-/issues/7865) for updates.
If you still wish to enable **Repository push** events in your instance, follow
the steps bellow.
diff --git a/doc/administration/auth/README.md b/doc/administration/auth/README.md
index f30d6be1775..60e1dfb4637 100644
--- a/doc/administration/auth/README.md
+++ b/doc/administration/auth/README.md
@@ -1,6 +1,9 @@
---
comments: false
type: index
+stage: Manage
+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 authentication and authorization
@@ -21,10 +24,9 @@ providers:
- [Google](../../integration/google.md)
- [JWT](jwt.md)
- [Kerberos](../../integration/kerberos.md)
-- [LDAP](ldap.md): Includes Active Directory, Apple Open Directory, Open LDAP,
+- [LDAP](ldap/index.md): Includes Active Directory, Apple Open Directory, Open LDAP,
and 389 Server.
- - [LDAP for GitLab EE](ldap-ee.md): LDAP additions to GitLab Enterprise Editions **(STARTER ONLY)**
- - [Google Secure LDAP](google_secure_ldap.md)
+ - [Google Secure LDAP](ldap/google_secure_ldap.md)
- [Okta](okta.md)
- [Salesforce](../../integration/salesforce.md)
- [SAML](../../integration/saml.md)
@@ -32,4 +34,6 @@ providers:
- [Shibboleth](../../integration/shibboleth.md)
- [Smartcard](smartcard.md) **(PREMIUM ONLY)**
- [Twitter](../../integration/twitter.md)
-- [UltraAuth](../../integration/ultra_auth.md)
+
+NOTE: **Note:**
+UltraAuth has removed their software which supports OmniAuth integration. We have therefore removed all references to UltraAuth integration.
diff --git a/doc/administration/auth/authentiq.md b/doc/administration/auth/authentiq.md
index e9b32b64160..56f6fddc1af 100644
--- a/doc/administration/auth/authentiq.md
+++ b/doc/administration/auth/authentiq.md
@@ -1,5 +1,8 @@
---
type: reference
+stage: Manage
+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
---
# Authentiq OmniAuth Provider
diff --git a/doc/administration/auth/cognito.md b/doc/administration/auth/cognito.md
index 8d5580ccb6c..b4df6446835 100644
--- a/doc/administration/auth/cognito.md
+++ b/doc/administration/auth/cognito.md
@@ -1,3 +1,10 @@
+---
+type: concepts, howto
+stage: Manage
+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
+---
+
# Amazon Web Services Cognito
Amazon Cognito lets you add user sign-up, sign-in, and access control to your GitLab instance.
@@ -51,6 +58,8 @@ Include the code block in the `/etc/gitlab/gitlab.rb` file:
gitlab_rails['omniauth_providers'] = [
{
"name" => "cognito",
+ # "label" => "Cognito",
+ # "icon" => nil, # Optional icon URL
"app_id" => "CLIENT ID",
"app_secret" => "CLIENT SECRET",
"args" => {
@@ -79,3 +88,5 @@ Include the code block in the `/etc/gitlab/gitlab.rb` file:
Your sign-in page should now display a Cognito button below the regular sign-in form.
To begin the authentication process, click the icon, and AWS Cognito will ask the user to sign in and authorize the GitLab application.
If successful, the user will be redirected and signed in to your GitLab instance.
+
+For more information, see the [Initial OmniAuth Configuration](../../integration/omniauth.md#initial-omniauth-configuration).
diff --git a/doc/administration/auth/crowd.md b/doc/administration/auth/crowd.md
index 71938d4fd2b..254bd259344 100644
--- a/doc/administration/auth/crowd.md
+++ b/doc/administration/auth/crowd.md
@@ -1,5 +1,8 @@
---
type: reference
+stage: Manage
+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
---
# Atlassian Crowd OmniAuth Provider
diff --git a/doc/administration/auth/google_secure_ldap.md b/doc/administration/auth/google_secure_ldap.md
index b643dd2f7b9..d30efc6d3cc 100644
--- a/doc/administration/auth/google_secure_ldap.md
+++ b/doc/administration/auth/google_secure_ldap.md
@@ -1,219 +1,5 @@
---
-type: reference
+redirect_to: 'ldap/google_secure_ldap.md'
---
-# Google Secure LDAP **(CORE ONLY)**
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/46391) in GitLab 11.9.
-
-[Google Cloud Identity](https://cloud.google.com/identity/) provides a Secure
-LDAP service that can be configured with GitLab for authentication and group sync.
-
-Secure LDAP requires a slightly different configuration than standard LDAP servers.
-The steps below cover:
-
-- Configuring the Secure LDAP Client in the Google Admin console.
-- Required GitLab configuration.
-
-## Configuring Google LDAP client
-
-1. Navigate to <https://admin.google.com/Dashboard> and sign in as a GSuite domain administrator.
-
-1. Go to **Apps > LDAP > Add Client**.
-
-1. Provide an `LDAP client name` and an optional `Description`. Any descriptive
- values are acceptable. For example, the name could be 'GitLab' and the
- description could be 'GitLab LDAP Client'. Click the **Continue** button.
-
- ![Add LDAP Client Step 1](img/google_secure_ldap_add_step_1.png)
-
-1. Set **Access Permission** according to your needs. You must choose either
- 'Entire domain (GitLab)' or 'Selected organizational units' for both 'Verify user
- credentials' and 'Read user information'. Select 'Add LDAP Client'
-
- TIP: **Tip:** If you plan to use GitLab [LDAP Group Sync](ldap-ee.md#group-sync)
- , turn on 'Read group information'.
-
- ![Add LDAP Client Step 2](img/google_secure_ldap_add_step_2.png)
-
-1. Download the generated certificate. This is required for GitLab to
- communicate with the Google Secure LDAP service. Save the downloaded certificates
- for later use. After downloading, click the **Continue to Client Details** button.
-
-1. Expand the **Service Status** section and turn the LDAP client 'ON for everyone'.
- After selecting 'Save', click on the 'Service Status' bar again to collapse
- and return to the rest of the settings.
-
-1. Expand the **Authentication** section and choose 'Generate New Credentials'.
- Copy/note these credentials for later use. After selecting 'Close', click
- on the 'Authentication' bar again to collapse and return to the rest of the settings.
-
-Now the Google Secure LDAP Client configuration is finished. The screenshot below
-shows an example of the final settings. Continue on to configure GitLab.
-
-![LDAP Client Settings](img/google_secure_ldap_client_settings.png)
-
-## Configuring GitLab
-
-Edit GitLab configuration, inserting the access credentials and certificate
-obtained earlier.
-
-The following are the configuration keys that need to be modified using the
-values obtained during the LDAP client configuration earlier:
-
-- `bind_dn`: The access credentials username
-- `password`: The access credentials password
-- `cert`: The `.crt` file text from the downloaded certificate bundle
-- `key`: The `.key` file text from the downloaded certificate bundle
-
-**For Omnibus installations**
-
-1. Edit `/etc/gitlab/gitlab.rb`:
-
- ```ruby
- gitlab_rails['ldap_enabled'] = true
- gitlab_rails['ldap_servers'] = YAML.load <<-EOS # remember to close this block with 'EOS' below
- main: # 'main' is the GitLab 'provider ID' of this LDAP server
- label: 'Google Secure LDAP'
-
- host: 'ldap.google.com'
- port: 636
- uid: 'uid'
- bind_dn: 'DizzyHorse'
- password: 'd6V5H8nhMUW9AuDP25abXeLd'
- encryption: 'simple_tls'
- verify_certificates: true
-
- tls_options:
- cert: |
- -----BEGIN CERTIFICATE-----
- MIIDbDCCAlSgAwIBAgIGAWlzxiIfMA0GCSqGSIb3DQEBCwUAMHcxFDASBgNVBAoTC0dvb2dsZSBJ
- bmMuMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQDEwtMREFQIENsaWVudDEPMA0GA1UE
- CxMGR1N1aXRlMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTAeFw0xOTAzMTIyMTE5
- MThaFw0yMjAzMTEyMTE5MThaMHcxFDASBgNVBAoTC0dvb2dsZSBJbmMuMRYwFAYDVQQHEw1Nb3Vu
- dGFpbiBWaWV3MRQwEgYDVQQDEwtMREFQIENsaWVudDEPMA0GA1UECxMGR1N1aXRlMQswCQYDVQQG
- EwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
- ALOTy4aC38dyjESk6N8fRsKk8DN23ZX/GaNFL5OUmmA1KWzrvVC881OzNdtGm3vNOIxr9clteEG/
- tQwsmsJvQT5U+GkBt+tGKF/zm7zueHUYqTP7Pg5pxAnAei90qkIRFi17ulObyRHPYv1BbCt8pxNB
- 4fG/gAXkFbCNxwh1eiQXXRTfruasCZ4/mHfX7MVm8JmWU9uAVIOLW+DSWOFhrDQduJdGBXJOyC2r
- Gqoeg9+tkBmNH/jjxpnEkFW8q7io9DdOUqqNgoidA1h9vpKTs3084sy2DOgUvKN9uXWx14uxIyYU
- Y1DnDy0wczcsuRt7l+EgtCEgpsLiLJQbKW+JS1UCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAf60J
- yazhbHkDKIH2gFxfm7QLhhnqsmafvl4WP7JqZt0u0KdnvbDPfokdkM87yfbKJU1MTI86M36wEC+1
- P6bzklKz7kXbzAD4GggksAzxsEE64OWHC+Y64Tkxq2NiZTw/76POkcg9StiIXjG0ZcebHub9+Ux/
- rTncip92nDuvgEM7lbPFKRIS/YMhLCk09B/U0F6XLsf1yYjyf5miUTDikPkov23b/YGfpc8kh6hq
- 1kqdi6a1cYPP34eAhtRhMqcZU9qezpJF6s9EeN/3YFfKzLODFSsVToBRAdZgGHzj//SAtLyQTD4n
- KCSvK1UmaMxNaZyTHg8JnMf0ZuRpv26iSg==
- -----END CERTIFICATE-----
-
- key: |
- -----BEGIN PRIVATE KEY-----
- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCzk8uGgt/HcoxEpOjfH0bCpPAz
- dt2V/xmjRS+TlJpgNSls671QvPNTszXbRpt7zTiMa/XJbXhBv7UMLJrCb0E+VPhpAbfrRihf85u8
- 7nh1GKkz+z4OacQJwHovdKpCERYte7pTm8kRz2L9QWwrfKcTQeHxv4AF5BWwjccIdXokF10U367m
- rAmeP5h31+zFZvCZllPbgFSDi1vg0ljhYaw0HbiXRgVyTsgtqxqqHoPfrZAZjR/448aZxJBVvKu4
- qPQ3TlKqjYKInQNYfb6Sk7N9POLMtgzoFLyjfbl1sdeLsSMmFGNQ5w8tMHM3LLkbe5fhILQhIKbC
- 4iyUGylviUtVAgMBAAECggEAIPb0CQy0RJoX+q/lGbRVmnyJpYDf+115WNnl+mrwjdGkeZyqw4v0
- BPzkWYzUFP1esJRO6buBNFybQRFdFW0z5lvVv/zzRKq71aVUBPInxaMRyHuJ8D5lIL8nDtgVOwyE
- 7DOGyDtURUMzMjdUwoTe7K+O6QBU4X/1pVPZYgmissYSMmt68LiP8k0p601F4+r5xOi/QEy44aVp
- aOJZBUOisKB8BmUXZqmQ4Cy05vU9Xi1rLyzkn9s7fxnZ+JO6Sd1r0Thm1mE0yuPgxkDBh/b4f3/2
- GsQNKKKCiij/6TfkjnBi8ZvWR44LnKpu760g/K7psVNrKwqJG6C/8RAcgISWQQKBgQDop7BaKGhK
- 1QMJJ/vnlyYFTucfGLn6bM//pzTys5Gop0tpcfX/Hf6a6Dd+zBhmC3tBmhr80XOX/PiyAIbc0lOI
- 31rafZuD/oVx5mlIySWX35EqS14LXmdVs/5vOhsInNgNiE+EPFf1L9YZgG/zA7OUBmqtTeYIPDVC
- 7ViJcydItQKBgQDFmK0H0IA6W4opGQo+zQKhefooqZ+RDk9IIZMPOAtnvOM7y3rSVrfsSjzYVuMS
- w/RP/vs7rwhaZejnCZ8/7uIqwg4sdUBRzZYR3PRNFeheW+BPZvb+2keRCGzOs7xkbF1mu54qtYTa
- HZGZj1OsD83AoMwVLcdLDgO1kw32dkS8IQKBgFRdgoifAHqqVah7VFB9se7Y1tyi5cXWsXI+Wufr
- j9U9nQ4GojK52LqpnH4hWnOelDqMvF6TQTyLIk/B+yWWK26Ft/dk9wDdSdystd8L+dLh4k0Y+Whb
- +lLMq2YABw+PeJUnqdYE38xsZVHoDjBsVjFGRmbDybeQxauYT7PACy3FAoGBAK2+k9bdNQMbXp7I
- j8OszHVkJdz/WXlY1cmdDAxDwXOUGVKIlxTAf7TbiijILZ5gg0Cb+hj+zR9/oI0WXtr+mAv02jWp
- W8cSOLS4TnBBpTLjIpdu+BwbnvYeLF6MmEjNKEufCXKQbaLEgTQ/XNlchBSuzwSIXkbWqdhM1+gx
- EjtBAoGARAdMIiDMPWIIZg3nNnFebbmtBP0qiBsYohQZ+6i/8s/vautEHBEN6Q0brIU/goo+nTHc
- t9VaOkzjCmAJSLPUanuBC8pdYgLu5J20NXUZLD9AE/2bBT3OpezKcdYeI2jqoc1qlWHlNtVtdqQ2
- AcZSFJQjdg5BTyvdEDhaYUKGdRw=
- -----END PRIVATE KEY-----
- EOS
- ```
-
-1. Save the file and [reconfigure](../restart_gitlab.md#omnibus-gitlab-reconfigure) GitLab for the changes to take effect.
-
----
-
-**For installations from source**
-
-1. Edit `config/gitlab.yml`:
-
- ```yaml
- ldap:
- enabled: true
- servers:
- main: # 'main' is the GitLab 'provider ID' of this LDAP server
- label: 'Google Secure LDAP'
-
- host: 'ldap.google.com'
- port: 636
- uid: 'uid'
- bind_dn: 'DizzyHorse'
- password: 'd6V5H8nhMUW9AuDP25abXeLd'
- encryption: 'simple_tls'
- verify_certificates: true
-
- tls_options:
- cert: |
- -----BEGIN CERTIFICATE-----
- MIIDbDCCAlSgAwIBAgIGAWlzxiIfMA0GCSqGSIb3DQEBCwUAMHcxFDASBgNVBAoTC0dvb2dsZSBJ
- bmMuMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQDEwtMREFQIENsaWVudDEPMA0GA1UE
- CxMGR1N1aXRlMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTAeFw0xOTAzMTIyMTE5
- MThaFw0yMjAzMTEyMTE5MThaMHcxFDASBgNVBAoTC0dvb2dsZSBJbmMuMRYwFAYDVQQHEw1Nb3Vu
- dGFpbiBWaWV3MRQwEgYDVQQDEwtMREFQIENsaWVudDEPMA0GA1UECxMGR1N1aXRlMQswCQYDVQQG
- EwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
- ALOTy4aC38dyjESk6N8fRsKk8DN23ZX/GaNFL5OUmmA1KWzrvVC881OzNdtGm3vNOIxr9clteEG/
- tQwsmsJvQT5U+GkBt+tGKF/zm7zueHUYqTP7Pg5pxAnAei90qkIRFi17ulObyRHPYv1BbCt8pxNB
- 4fG/gAXkFbCNxwh1eiQXXRTfruasCZ4/mHfX7MVm8JmWU9uAVIOLW+DSWOFhrDQduJdGBXJOyC2r
- Gqoeg9+tkBmNH/jjxpnEkFW8q7io9DdOUqqNgoidA1h9vpKTs3084sy2DOgUvKN9uXWx14uxIyYU
- Y1DnDy0wczcsuRt7l+EgtCEgpsLiLJQbKW+JS1UCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAf60J
- yazhbHkDKIH2gFxfm7QLhhnqsmafvl4WP7JqZt0u0KdnvbDPfokdkM87yfbKJU1MTI86M36wEC+1
- P6bzklKz7kXbzAD4GggksAzxsEE64OWHC+Y64Tkxq2NiZTw/76POkcg9StiIXjG0ZcebHub9+Ux/
- rTncip92nDuvgEM7lbPFKRIS/YMhLCk09B/U0F6XLsf1yYjyf5miUTDikPkov23b/YGfpc8kh6hq
- 1kqdi6a1cYPP34eAhtRhMqcZU9qezpJF6s9EeN/3YFfKzLODFSsVToBRAdZgGHzj//SAtLyQTD4n
- KCSvK1UmaMxNaZyTHg8JnMf0ZuRpv26iSg==
- -----END CERTIFICATE-----
-
- key: |
- -----BEGIN PRIVATE KEY-----
- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCzk8uGgt/HcoxEpOjfH0bCpPAz
- dt2V/xmjRS+TlJpgNSls671QvPNTszXbRpt7zTiMa/XJbXhBv7UMLJrCb0E+VPhpAbfrRihf85u8
- 7nh1GKkz+z4OacQJwHovdKpCERYte7pTm8kRz2L9QWwrfKcTQeHxv4AF5BWwjccIdXokF10U367m
- rAmeP5h31+zFZvCZllPbgFSDi1vg0ljhYaw0HbiXRgVyTsgtqxqqHoPfrZAZjR/448aZxJBVvKu4
- qPQ3TlKqjYKInQNYfb6Sk7N9POLMtgzoFLyjfbl1sdeLsSMmFGNQ5w8tMHM3LLkbe5fhILQhIKbC
- 4iyUGylviUtVAgMBAAECggEAIPb0CQy0RJoX+q/lGbRVmnyJpYDf+115WNnl+mrwjdGkeZyqw4v0
- BPzkWYzUFP1esJRO6buBNFybQRFdFW0z5lvVv/zzRKq71aVUBPInxaMRyHuJ8D5lIL8nDtgVOwyE
- 7DOGyDtURUMzMjdUwoTe7K+O6QBU4X/1pVPZYgmissYSMmt68LiP8k0p601F4+r5xOi/QEy44aVp
- aOJZBUOisKB8BmUXZqmQ4Cy05vU9Xi1rLyzkn9s7fxnZ+JO6Sd1r0Thm1mE0yuPgxkDBh/b4f3/2
- GsQNKKKCiij/6TfkjnBi8ZvWR44LnKpu760g/K7psVNrKwqJG6C/8RAcgISWQQKBgQDop7BaKGhK
- 1QMJJ/vnlyYFTucfGLn6bM//pzTys5Gop0tpcfX/Hf6a6Dd+zBhmC3tBmhr80XOX/PiyAIbc0lOI
- 31rafZuD/oVx5mlIySWX35EqS14LXmdVs/5vOhsInNgNiE+EPFf1L9YZgG/zA7OUBmqtTeYIPDVC
- 7ViJcydItQKBgQDFmK0H0IA6W4opGQo+zQKhefooqZ+RDk9IIZMPOAtnvOM7y3rSVrfsSjzYVuMS
- w/RP/vs7rwhaZejnCZ8/7uIqwg4sdUBRzZYR3PRNFeheW+BPZvb+2keRCGzOs7xkbF1mu54qtYTa
- HZGZj1OsD83AoMwVLcdLDgO1kw32dkS8IQKBgFRdgoifAHqqVah7VFB9se7Y1tyi5cXWsXI+Wufr
- j9U9nQ4GojK52LqpnH4hWnOelDqMvF6TQTyLIk/B+yWWK26Ft/dk9wDdSdystd8L+dLh4k0Y+Whb
- +lLMq2YABw+PeJUnqdYE38xsZVHoDjBsVjFGRmbDybeQxauYT7PACy3FAoGBAK2+k9bdNQMbXp7I
- j8OszHVkJdz/WXlY1cmdDAxDwXOUGVKIlxTAf7TbiijILZ5gg0Cb+hj+zR9/oI0WXtr+mAv02jWp
- W8cSOLS4TnBBpTLjIpdu+BwbnvYeLF6MmEjNKEufCXKQbaLEgTQ/XNlchBSuzwSIXkbWqdhM1+gx
- EjtBAoGARAdMIiDMPWIIZg3nNnFebbmtBP0qiBsYohQZ+6i/8s/vautEHBEN6Q0brIU/goo+nTHc
- t9VaOkzjCmAJSLPUanuBC8pdYgLu5J20NXUZLD9AE/2bBT3OpezKcdYeI2jqoc1qlWHlNtVtdqQ2
- AcZSFJQjdg5BTyvdEDhaYUKGdRw=
- -----END PRIVATE KEY-----
- ```
-
-1. Save the file and [restart](../restart_gitlab.md#installations-from-source) GitLab for the changes to take effect.
-
-<!-- ## 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. -->
+This document was moved to [another location](ldap/google_secure_ldap.md).
diff --git a/doc/administration/auth/how_to_configure_ldap_gitlab_ce/img/gitlab_ou.png b/doc/administration/auth/how_to_configure_ldap_gitlab_ce/img/gitlab_ou.png
deleted file mode 100644
index 223fd0ac401..00000000000
--- a/doc/administration/auth/how_to_configure_ldap_gitlab_ce/img/gitlab_ou.png
+++ /dev/null
Binary files differ
diff --git a/doc/administration/auth/how_to_configure_ldap_gitlab_ce/img/ldap_ou.gif b/doc/administration/auth/how_to_configure_ldap_gitlab_ce/img/ldap_ou.gif
deleted file mode 100644
index a6727a3d85f..00000000000
--- a/doc/administration/auth/how_to_configure_ldap_gitlab_ce/img/ldap_ou.gif
+++ /dev/null
Binary files differ
diff --git a/doc/administration/auth/how_to_configure_ldap_gitlab_ce/img/user_auth.gif b/doc/administration/auth/how_to_configure_ldap_gitlab_ce/img/user_auth.gif
deleted file mode 100644
index 36e6085259f..00000000000
--- a/doc/administration/auth/how_to_configure_ldap_gitlab_ce/img/user_auth.gif
+++ /dev/null
Binary files differ
diff --git a/doc/administration/auth/how_to_configure_ldap_gitlab_ce/index.md b/doc/administration/auth/how_to_configure_ldap_gitlab_ce/index.md
index 01da4528eab..40d021e180c 100644
--- a/doc/administration/auth/how_to_configure_ldap_gitlab_ce/index.md
+++ b/doc/administration/auth/how_to_configure_ldap_gitlab_ce/index.md
@@ -1,273 +1,5 @@
---
-type: howto
+redirect_to: '../ldap/index.md'
---
-# How to configure LDAP with GitLab CE
-
-Managing a large number of users in GitLab can become a burden for system administrators. As an organization grows so do user accounts. Keeping these user accounts in sync across multiple enterprise applications often becomes a time consuming task.
-
-In this guide we will focus on configuring GitLab with Active Directory. [Active Directory](https://en.wikipedia.org/wiki/Active_Directory) is a popular LDAP compatible directory service provided by Microsoft, included in all modern Windows Server operating systems.
-
-GitLab has supported LDAP integration since [version 2.2](https://about.gitlab.com/releases/2012/02/22/gitlab-version-2-2/). With GitLab LDAP [group syncing](../how_to_configure_ldap_gitlab_ee/index.md#group-sync) being added to GitLab Enterprise Edition in [version 6.0](https://about.gitlab.com/releases/2013/08/20/gitlab-6-dot-0-released/). LDAP integration has become one of the most popular features in GitLab.
-
-## Getting started
-
-### Choosing an LDAP Server
-
-The main reason organizations choose to utilize a LDAP server is to keep the entire organization's user base consolidated into a central repository. Users can access multiple applications and systems across the IT environment using a single login. Because LDAP is an open, vendor-neutral, industry standard application protocol, the number of applications using LDAP authentication continues to increase.
-
-There are many commercial and open source [directory servers](https://en.wikipedia.org/wiki/Directory_service#LDAP_implementations) that support the LDAP protocol. Deciding on the right directory server highly depends on the existing IT environment in which the server will be integrated with.
-
-For example, [Active Directory](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/hh831484(v=ws.11)) is generally favored in a primarily Windows environment, as this allows quick integration with existing services. Other popular directory services include:
-
-- [Oracle Internet Directory](https://www.oracle.com/middleware/technologies/internet-directory.html)
-- [OpenLDAP](https://www.openldap.org/)
-- [389 Directory](http://directory.fedoraproject.org/)
-- [OpenDJ (Renamed to Forgerock Directory Services)](https://www.forgerock.com/platform/directory-services)
-- [ApacheDS](https://directory.apache.org/)
-
-> GitLab uses the [Net::LDAP](https://rubygems.org/gems/net-ldap) library under the hood. This means it supports all [IETF](https://tools.ietf.org/html/rfc2251) compliant LDAPv3 servers.
-
-### Active Directory (AD)
-
-We won't cover the installation and configuration of Windows Server or Active Directory Domain Services in this tutorial. There are a number of resources online to guide you through this process:
-
-- Install Windows Server 2012 - (`technet.microsoft.com`) - [Installing Windows Server 2012](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/jj134246(v=ws.11))
-
-- Install Active Directory Domain Services (AD DS) (`technet.microsoft.com`) - [Install Active Directory Domain Services](https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/deploy/install-active-directory-domain-services--level-100-#BKMK_PS)
-
-> **Shortcut:** You can quickly install AD DS via PowerShell using
-`Install-WindowsFeature AD-Domain-Services -IncludeManagementTools`
-
-### Creating an AD **OU** structure
-
-Configuring organizational units (**OU**s) is an important part of setting up Active Directory. **OU**s form the base for an entire organizational structure. Using GitLab as an example we have designed the **OU** structure below using the geographic **OU** model. In the Geographic Model we separate **OU**s for different geographic regions.
-
-| GitLab **OU** Design | GitLab AD Structure |
-| :----------------------------: | :------------------------------: |
-| ![GitLab OU Design](img/gitlab_ou.png) | ![GitLab AD Structure](img/ldap_ou.gif) |
-
-Using PowerShell you can output the **OU** structure as a table (_all names are examples only_):
-
-```ps
-Get-ADObject -LDAPFilter "(objectClass=*)" -SearchBase 'OU=GitLab INT,DC=GitLab,DC=org' -Properties CanonicalName | Format-Table Name,CanonicalName -A
-```
-
-```plaintext
-OU CanonicalName
----- -------------
-GitLab INT GitLab.org/GitLab INT
-United States GitLab.org/GitLab INT/United States
-Developers GitLab.org/GitLab INT/United States/Developers
-Gary Johnson GitLab.org/GitLab INT/United States/Developers/Gary Johnson
-Ellis Matthews GitLab.org/GitLab INT/United States/Developers/Ellis Matthews
-William Collins GitLab.org/GitLab INT/United States/Developers/William Collins
-People Ops GitLab.org/GitLab INT/United States/People Ops
-Margaret Baker GitLab.org/GitLab INT/United States/People Ops/Margaret Baker
-Libby Hartzler GitLab.org/GitLab INT/United States/People Ops/Libby Hartzler
-Victoria Ryles GitLab.org/GitLab INT/United States/People Ops/Victoria Ryles
-The Netherlands GitLab.org/GitLab INT/The Netherlands
-Developers GitLab.org/GitLab INT/The Netherlands/Developers
-John Doe GitLab.org/GitLab INT/The Netherlands/Developers/John Doe
-Jon Mealy GitLab.org/GitLab INT/The Netherlands/Developers/Jon Mealy
-Jane Weingarten GitLab.org/GitLab INT/The Netherlands/Developers/Jane Weingarten
-Production GitLab.org/GitLab INT/The Netherlands/Production
-Sarah Konopka GitLab.org/GitLab INT/The Netherlands/Production/Sarah Konopka
-Cynthia Bruno GitLab.org/GitLab INT/The Netherlands/Production/Cynthia Bruno
-David George GitLab.org/GitLab INT/The Netherlands/Production/David George
-United Kingdom GitLab.org/GitLab INT/United Kingdom
-Developers GitLab.org/GitLab INT/United Kingdom/Developers
-Leroy Fox GitLab.org/GitLab INT/United Kingdom/Developers/Leroy Fox
-Christopher Alley GitLab.org/GitLab INT/United Kingdom/Developers/Christopher Alley
-Norris Morita GitLab.org/GitLab INT/United Kingdom/Developers/Norris Morita
-Support GitLab.org/GitLab INT/United Kingdom/Support
-Laura Stanley GitLab.org/GitLab INT/United Kingdom/Support/Laura Stanley
-Nikki Schuman GitLab.org/GitLab INT/United Kingdom/Support/Nikki Schuman
-Harriet Butcher GitLab.org/GitLab INT/United Kingdom/Support/Harriet Butcher
-Global Groups GitLab.org/GitLab INT/Global Groups
-DevelopersNL GitLab.org/GitLab INT/Global Groups/DevelopersNL
-DevelopersUK GitLab.org/GitLab INT/Global Groups/DevelopersUK
-DevelopersUS GitLab.org/GitLab INT/Global Groups/DevelopersUS
-ProductionNL GitLab.org/GitLab INT/Global Groups/ProductionNL
-SupportUK GitLab.org/GitLab INT/Global Groups/SupportUK
-People Ops US GitLab.org/GitLab INT/Global Groups/People Ops US
-Global Admins GitLab.org/GitLab INT/Global Groups/Global Admins
-```
-
-> See [more information](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-powershell-1.0/ff730967(v=technet.10)) on searching Active Directory with Windows PowerShell from [The Scripting Guys](https://devblogs.microsoft.com/scripting/)
-
-## GitLab LDAP configuration
-
-The initial configuration of LDAP in GitLab requires changes to the `gitlab.rb` configuration file (`/etc/gitlab/gitlab.rb`). Below is an example of a complete configuration using an Active Directory.
-
-The two Active Directory specific values are `active_directory: true` and `uid: 'sAMAccountName'`. `sAMAccountName` is an attribute returned by Active Directory used for GitLab usernames. See the example output from `ldapsearch` for a full list of attributes a "person" object (user) has in **AD** - [`ldapsearch` example](#using-ldapsearch-unix)
-
-> Both group_base and admin_group configuration options are only available in GitLab Enterprise Edition. See [GitLab EE - LDAP Features](../how_to_configure_ldap_gitlab_ee/index.md#gitlab-enterprise-edition---ldap-features) **(STARTER ONLY)**
-
-### Example `gitlab.rb` LDAP
-
-```ruby
-gitlab_rails['ldap_enabled'] = true
-gitlab_rails['ldap_servers'] = {
-'main' => {
- 'label' => 'GitLab AD',
- 'host' => 'ad.example.org',
- 'port' => 636,
- 'uid' => 'sAMAccountName',
- 'encryption' => 'simple_tls',
- 'verify_certificates' => true,
- 'bind_dn' => 'CN=GitLabSRV,CN=Users,DC=GitLab,DC=org',
- 'password' => 'Password1',
- 'active_directory' => true,
- 'base' => 'OU=GitLab INT,DC=GitLab,DC=org',
- 'group_base' => 'OU=Global Groups,OU=GitLab INT,DC=GitLab,DC=org',
- 'admin_group' => 'Global Admins'
- }
-}
-```
-
-> **Note:** Remember to run `gitlab-ctl reconfigure` after modifying `gitlab.rb`
-
-## Security improvements (LDAPS)
-
-Security is an important aspect when deploying an LDAP server. By default, LDAP traffic is transmitted unsecured. LDAP can be secured using SSL/TLS called LDAPS, or commonly "LDAP over SSL".
-
-Securing LDAP (enabling LDAPS) on Windows Server 2012 involves installing a valid SSL certificate. For full details see Microsoft's guide [How to enable LDAP over SSL with a third-party certification authority](https://support.microsoft.com/en-us/help/321051/how-to-enable-ldap-over-ssl-with-a-third-party-certification-authority)
-
-> By default a LDAP service listens for connections on TCP and UDP port 389. LDAPS (LDAP over SSL) listens on port 636
-
-### Testing your AD server
-
-#### Using **AdFind** (Windows)
-
-You can use the [`AdFind`](https://social.technet.microsoft.com/wiki/contents/articles/7535.adfind-command-examples.aspx) utility (on Windows based systems) to test that your LDAP server is accessible and authentication is working correctly. This is a freeware utility built by [Joe Richards](http://www.joeware.net/freetools/tools/adfind/index.htm).
-
-**Return all objects**
-
-You can use the filter `objectclass=*` to return all directory objects.
-
-```shell
-adfind -h ad.example.org:636 -ssl -u "CN=GitLabSRV,CN=Users,DC=GitLab,DC=org" -up Password1 -b "OU=GitLab INT,DC=GitLab,DC=org" -f (objectClass=*)
-```
-
-**Return single object using filter**
-
-You can also retrieve a single object by **specifying** the object name or full **DN**. In this example we specify the object name only `CN=Leroy Fox`.
-
-```shell
-adfind -h ad.example.org:636 -ssl -u "CN=GitLabSRV,CN=Users,DC=GitLab,DC=org" -up Password1 -b "OU=GitLab INT,DC=GitLab,DC=org" -f (&(objectcategory=person)(CN=Leroy Fox))â€
-```
-
-#### Using **ldapsearch** (Unix)
-
-You can use the `ldapsearch` utility (on Unix based systems) to test that your LDAP server is accessible and authentication is working correctly. This utility is included in the [`ldap-utils`](https://wiki.debian.org/LDAP/LDAPUtils) package.
-
-**Return all objects**
-
-You can use the filter `objectclass=*` to return all directory objects.
-
-```shell
-ldapsearch -D "CN=GitLabSRV,CN=Users,DC=GitLab,DC=org" \
--w Password1 -p 636 -h ad.example.org \
--b "OU=GitLab INT,DC=GitLab,DC=org" -Z \
--s sub "(objectclass=*)"
-```
-
-**Return single object using filter**
-
-You can also retrieve a single object by **specifying** the object name or full **DN**. In this example we specify the object name only `CN=Leroy Fox`.
-
-```shell
-ldapsearch -D "CN=GitLabSRV,CN=Users,DC=GitLab,DC=org" -w Password1 -p 389 -h ad.example.org -b "OU=GitLab INT,DC=GitLab,DC=org" -Z -s sub "CN=Leroy Fox"
-```
-
-**Full output of `ldapsearch` command:** - Filtering for _CN=Leroy Fox_
-
-```plaintext
-# LDAPv3
-# base <OU=GitLab INT,DC=GitLab,DC=org> with scope subtree
-# filter: CN=Leroy Fox
-# requesting: ALL
-#
-
-# Leroy Fox, Developers, United Kingdom, GitLab INT, GitLab.org
-dn: CN=Leroy Fox,OU=Developers,OU=United Kingdom,OU=GitLab INT,DC=GitLab,DC=or
- g
-objectClass: top
-objectClass: person
-objectClass: organizationalPerson
-objectClass: user
-cn: Leroy Fox
-sn: Fox
-givenName: Leroy
-distinguishedName: CN=Leroy Fox,OU=Developers,OU=United Kingdom,OU=GitLab INT,
- DC=GitLab,DC=org
-instanceType: 4
-whenCreated: 20170210030500.0Z
-whenChanged: 20170213050128.0Z
-displayName: Leroy Fox
-uSNCreated: 16790
-memberOf: CN=DevelopersUK,OU=Global Groups,OU=GitLab INT,DC=GitLab,DC=org
-uSNChanged: 20812
-name: Leroy Fox
-objectGUID:: rBCAo6NR6E6vfSKgzcUILg==
-userAccountControl: 512
-badPwdCount: 0
-codePage: 0
-countryCode: 0
-badPasswordTime: 0
-lastLogoff: 0
-lastLogon: 0
-pwdLastSet: 131311695009850084
-primaryGroupID: 513
-objectSid:: AQUAAAAAAAUVAAAA9GMAb7tdJZvsATf7ZwQAAA==
-accountExpires: 9223372036854775807
-logonCount: 0
-sAMAccountName: Leroyf
-sAMAccountType: 805306368
-userPrincipalName: Leroyf@GitLab.org
-objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=GitLab,DC=org
-dSCorePropagationData: 16010101000000.0Z
-lastLogonTimestamp: 131314356887754250
-
-# search result
-search: 2
-result: 0 Success
-
-# numResponses: 2
-# numEntries: 1
-```
-
-## Basic user authentication
-
-After configuring LDAP, basic authentication will be available. Users can then login using their directory credentials. An extra tab is added to the GitLab login screen for the configured LDAP server (e.g "**GitLab AD**").
-
-![GitLab OU Structure](img/user_auth.gif)
-
-Users that are removed from the LDAP base group (e.g `OU=GitLab INT,DC=GitLab,DC=org`) will be **blocked** in GitLab. [More information](../ldap.md#security) on LDAP security.
-
-If `allow_username_or_email_login` is enabled in the LDAP configuration, GitLab will ignore everything after the first '@' in the LDAP username used on login. Example: The username `jon.doe@example.com` is converted to `jon.doe` when authenticating with the LDAP server. Disable this setting if you use `userPrincipalName` as the `uid`.
-
-## LDAP extended features on GitLab EE
-
-With [GitLab Enterprise Edition (EE)](https://about.gitlab.com/pricing/), besides everything we just described, you'll
-have extended functionalities with LDAP, such as:
-
-- Group sync
-- Group permissions
-- Updating user permissions
-- Multiple LDAP servers
-
-Read through the article on [LDAP for GitLab EE](../how_to_configure_ldap_gitlab_ee/index.md) **(STARTER ONLY)** for an overview.
-
-<!-- ## 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. -->
+This document was moved to [another location](../ldap/index.md).
diff --git a/doc/administration/auth/how_to_configure_ldap_gitlab_ee/img/admin_group.png b/doc/administration/auth/how_to_configure_ldap_gitlab_ee/img/admin_group.png
deleted file mode 100644
index 9896379d669..00000000000
--- a/doc/administration/auth/how_to_configure_ldap_gitlab_ee/img/admin_group.png
+++ /dev/null
Binary files differ
diff --git a/doc/administration/auth/how_to_configure_ldap_gitlab_ee/img/group_link_final.png b/doc/administration/auth/how_to_configure_ldap_gitlab_ee/img/group_link_final.png
deleted file mode 100644
index 21fb5a7d0ce..00000000000
--- a/doc/administration/auth/how_to_configure_ldap_gitlab_ee/img/group_link_final.png
+++ /dev/null
Binary files differ
diff --git a/doc/administration/auth/how_to_configure_ldap_gitlab_ee/img/group_linking.gif b/doc/administration/auth/how_to_configure_ldap_gitlab_ee/img/group_linking.gif
deleted file mode 100644
index a0ec2d4f10a..00000000000
--- a/doc/administration/auth/how_to_configure_ldap_gitlab_ee/img/group_linking.gif
+++ /dev/null
Binary files differ
diff --git a/doc/administration/auth/how_to_configure_ldap_gitlab_ee/img/manual_permissions.gif b/doc/administration/auth/how_to_configure_ldap_gitlab_ee/img/manual_permissions.gif
deleted file mode 100644
index a9d5dd7e73e..00000000000
--- a/doc/administration/auth/how_to_configure_ldap_gitlab_ee/img/manual_permissions.gif
+++ /dev/null
Binary files differ
diff --git a/doc/administration/auth/how_to_configure_ldap_gitlab_ee/img/multi_login.gif b/doc/administration/auth/how_to_configure_ldap_gitlab_ee/img/multi_login.gif
deleted file mode 100644
index d317add9837..00000000000
--- a/doc/administration/auth/how_to_configure_ldap_gitlab_ee/img/multi_login.gif
+++ /dev/null
Binary files differ
diff --git a/doc/administration/auth/how_to_configure_ldap_gitlab_ee/index.md b/doc/administration/auth/how_to_configure_ldap_gitlab_ee/index.md
index d7b32c8a92a..40d021e180c 100644
--- a/doc/administration/auth/how_to_configure_ldap_gitlab_ee/index.md
+++ b/doc/administration/auth/how_to_configure_ldap_gitlab_ee/index.md
@@ -1,125 +1,5 @@
---
-type: howto
+redirect_to: '../ldap/index.md'
---
-# How to configure LDAP with GitLab EE **(STARTER ONLY)**
-
-This article expands on [How to Configure LDAP with GitLab CE](../how_to_configure_ldap_gitlab_ce/index.md). Make sure to read through it before moving forward.
-
-## GitLab Enterprise Edition - LDAP features
-
-[GitLab Enterprise Edition (EE)](https://about.gitlab.com/pricing/) has several advantages when it comes to integrating with Active Directory (LDAP):
-
-- [Administrator Sync](../ldap-ee.md#administrator-sync): As an extension of group sync, you can automatically manage your global GitLab administrators. Specify a group CN for `admin_group` and all members of the LDAP group will be given administrator privileges.
-- [Group Sync](#group-sync): This allows GitLab group membership to be automatically updated based on LDAP group members.
-- [Multiple LDAP servers](#multiple-ldap-servers): The ability to configure multiple LDAP servers. This is useful if an organization has different LDAP servers within departments. This is not designed for failover. We're working on [supporting LDAP failover](https://gitlab.com/gitlab-org/gitlab/issues/139) in GitLab.
-
-- Daily user synchronization: Once a day, GitLab will run a synchronization to check and update GitLab users against LDAP. This process updates all user details automatically.
-
-In the following section, you'll find a description of each of these features. Read through [LDAP GitLab EE docs](../ldap-ee.md) for complementary information.
-
-![GitLab OU Structure](img/admin_group.png)
-
-All members of the group `Global Admins` will be given **administrator** access to GitLab, allowing them to view the `/admin` dashboard.
-
-### Group Sync
-
-Group syncing allows AD (LDAP) groups to be mapped to GitLab groups. This provides more control over per-group user management. To configure group syncing edit the `group_base` **DN** (`'OU=Global Groups,OU=GitLab INT,DC=GitLab,DC=org'`). This **OU** contains all groups that will be associated with [GitLab groups](../../../user/group/index.md).
-
-#### Creating group links - example
-
-As an example, let's suppose we have a "UKGov" GitLab group, which deals with confidential government information. Therefore, users of this group must be given the correct permissions to projects contained within the group. Granular group permissions can be applied based on the AD group.
-
-**UK Developers** of our "UKGov" group are given **"developer"** permissions.
-
-_The developer permission allows the development staff to effectively manage all project code, issues, and merge requests._
-
-**UK Support** staff of our "UKGov" group are given **"reporter"** permissions.
-
-_The reporter permission allows support staff to manage issues, labels, and review project code._
-
-**US People Ops** of our "UKGov" group are given **"guest"** permissions.
-
-![Creating group links](img/group_linking.gif)
-
-> Guest permissions allows people ops staff to review and lodge new issues while allowing no read or write access to project code or [confidential issues](../../../user/project/issues/confidential_issues.md#permissions-and-access-to-confidential-issues) created by other users.
-
-See the [permission list](../../../user/permissions.md) for complementary information.
-
-#### Group permissions - example
-
-Considering the previous example, our staff will have
-access to our GitLab instance with the following structure:
-
-![GitLab OU Structure](img/group_link_final.png)
-
-Using this permission structure in our example allows only UK staff access to sensitive information stored in the projects code, while still allowing other teams to work effectively. As all permissions are controlled via AD groups new users can be quickly added to existing groups. New group members will then automatically inherit the required permissions.
-
-> [More information](../ldap-ee.md#group-sync) on group syncing.
-
-### Updating user permissions - new feature
-
-Since GitLab [v8.15](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/822) LDAP user permissions can now be manually overridden by an admin user. To override a user's permissions visit the groups **Members** page and select **Edit permissions**.
-
-![Setting manual permissions](img/manual_permissions.gif)
-
-### Multiple LDAP servers
-
-GitLab EE can support multiple LDAP servers. Simply configure another server in the `gitlab.rb` file within the `ldap_servers` block. In the example below we configure a new secondary server with the label **GitLab Secondary AD**. This is shown on the GitLab login screen. Large enterprises often utilize multiple LDAP servers for segregating organizational departments.
-
-![Multiple LDAP Servers Login](img/multi_login.gif)
-
-Considering the example illustrated on the image above,
-our `gitlab.rb` configuration would look like:
-
-```ruby
-gitlab_rails['ldap_enabled'] = true
-gitlab_rails['ldap_servers'] = {
-'main' => {
- 'label' => 'GitLab AD',
- 'host' => 'ad.example.org',
- 'port' => 636,
- 'uid' => 'sAMAccountName',
- 'method' => 'ssl',
- 'bind_dn' => 'CN=GitLabSRV,CN=Users,DC=GitLab,DC=org',
- 'password' => 'Password1',
- 'active_directory' => true,
- 'base' => 'OU=GitLab INT,DC=GitLab,DC=org',
- 'group_base' => 'OU=Global Groups,OU=GitLab INT,DC=GitLab,DC=org',
- 'admin_group' => 'Global Admins'
- },
-
-'secondary' => {
- 'label' => 'GitLab Secondary AD',
- 'host' => 'ad-secondary.example.net',
- 'port' => 636,
- 'uid' => 'sAMAccountName',
- 'method' => 'ssl',
- 'bind_dn' => 'CN=GitLabSRV,CN=Users,DC=GitLab,DC=com',
- 'password' => 'Password1',
- 'active_directory' => true,
- 'base' => 'OU=GitLab Secondary,DC=GitLab,DC=com',
- 'group_base' => 'OU=Global Groups,OU=GitLab INT,DC=GitLab,DC=com',
- 'admin_group' => 'Global Admins'
- }
-}
-```
-
-## Conclusion
-
-Integration of GitLab with Active Directory (LDAP) reduces the complexity of user management.
-It has the advantage of improving user permission controls, while easing the deployment of GitLab into an existing [IT environment](https://www.techopedia.com/definition/29199/it-infrastructure). GitLab EE offers advanced group management and multiple LDAP servers.
-
-With the assistance of the [GitLab Support](https://about.gitlab.com/support/) team, setting up GitLab with an existing AD/LDAP solution will be a smooth and painless process.
-
-<!-- ## 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. -->
+This document was moved to [another location](../ldap/index.md).
diff --git a/doc/administration/auth/jwt.md b/doc/administration/auth/jwt.md
index 5a773485842..29b192a4845 100644
--- a/doc/administration/auth/jwt.md
+++ b/doc/administration/auth/jwt.md
@@ -1,5 +1,8 @@
---
type: reference
+stage: Manage
+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
---
# JWT OmniAuth provider
diff --git a/doc/administration/auth/ldap-ee.md b/doc/administration/auth/ldap-ee.md
index 9e193dba08c..f5565628af1 100644
--- a/doc/administration/auth/ldap-ee.md
+++ b/doc/administration/auth/ldap-ee.md
@@ -1,417 +1,5 @@
---
-type: reference
+redirect_to: 'ldap/index.md'
---
-# LDAP Additions in GitLab EE **(STARTER ONLY)**
-
-This section documents LDAP features specific to GitLab Enterprise Edition
-[Starter](https://about.gitlab.com/pricing/#self-managed) and above.
-
-For documentation relevant to both Community Edition and Enterprise Edition,
-see the main [LDAP documentation](ldap.md).
-
-NOTE: **Note:**
-[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
-
-## Use cases
-
-- User sync: Once a day, GitLab will update users against LDAP.
-- Group sync: Once an hour, GitLab will update group membership
- based on LDAP group members.
-
-## Multiple LDAP servers
-
-With GitLab Enterprise Edition Starter, you can configure multiple LDAP servers
-that your GitLab instance will connect to.
-
-To add another LDAP server:
-
-1. Duplicating the settings under [the main configuration](ldap.md#configuration).
-1. Edit them to match the additional LDAP server.
-
-Be sure to choose a different provider ID made of letters a-z and numbers 0-9.
-This ID will be stored in the database so that GitLab can remember which LDAP
-server a user belongs to.
-
-## User sync
-
-Once per day, GitLab will run a worker to check and update GitLab
-users against LDAP.
-
-The process will execute the following access checks:
-
-- Ensure the user is still present in LDAP.
-- If the LDAP server is Active Directory, ensure the user is active (not
- blocked/disabled state). This will only be checked if
- `active_directory: true` is set in the LDAP configuration.
-
-NOTE: **Note:**
-In Active Directory, a user is marked as disabled/blocked if the user
-account control attribute (`userAccountControl:1.2.840.113556.1.4.803`)
-has bit 2 set. See <https://ctovswild.com/2009/09/03/bitmask-searches-in-ldap/>
-for more information.
-
-The user will be set to `ldap_blocked` state in GitLab if the above conditions
-fail. This means the user will not be able to login or push/pull code.
-
-The process will also update the following user information:
-
-- Email address.
-- If `sync_ssh_keys` is set, SSH public keys.
-- If Kerberos is enabled, Kerberos identity.
-
-NOTE: **Note:**
-The LDAP sync process updates existing users while new users will
-be created on first sign in.
-
-## Group Sync
-
-If your LDAP supports the `memberof` property, when the user signs in for the
-first time GitLab will trigger 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
-access to their groups and projects.
-
-A group sync process will run every hour on the hour, and `group_base` must be set
-in LDAP configuration for LDAP synchronizations based on group CN to work. This allows
-GitLab group membership to be automatically updated based on LDAP group members.
-
-The `group_base` configuration should be a base LDAP 'container', such as an
-'organization' or 'organizational unit', that contains LDAP groups that should
-be available to GitLab. For example, `group_base` could be
-`ou=groups,dc=example,dc=com`. In the config file it will look like the
-following.
-
-**Omnibus configuration**
-
-1. Edit `/etc/gitlab/gitlab.rb`:
-
- ```ruby
- gitlab_rails['ldap_servers'] = YAML.load <<-EOS
- main:
- ## snip...
- ##
- ## Base where we can search for groups
- ##
- ## Ex. ou=groups,dc=gitlab,dc=example
- ##
- ##
- group_base: ou=groups,dc=example,dc=com
- EOS
- ```
-
-1. [Apply your changes to GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
-
-**Source configuration**
-
-1. Edit `/home/git/gitlab/config/gitlab.yml`:
-
- ```yaml
- production:
- ldap:
- servers:
- main:
- # snip...
- group_base: ou=groups,dc=example,dc=com
- ```
-
-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 will need to [create one
-or more LDAP group links](#adding-group-links).
-
-NOTE: **Note:**
-If an LDAP user is a group member when LDAP Synchronization is added, and they are not part of the LDAP group, they will be removed from the group.
-
-### Adding group links
-
-Once [group sync has been configured](#group-sync) on the instance, one or more LDAP
-groups can be linked to a GitLab group to grant their members access to its
-contents.
-
-Group owners or maintainers can add and use LDAP group links by:
-
-1. Navigating to the group's **Settings > LDAP Synchronization** page. Here, one or more
- LDAP groups and [filters](#filters-premium-only) can be linked to this GitLab group,
- each one with a configured [permission level](../../user/permissions.md#group-members-permissions)
- for its members.
-1. Updating the group's membership by navigating to the group's **Settings > Members**
- page and clicking **Sync now**.
-
-### Filters **(PREMIUM ONLY)**
-
-In GitLab Premium, you can add an LDAP user filter for group synchronization.
-Filters allow for complex logic without creating a special LDAP group.
-
-To sync GitLab group membership based on an LDAP filter:
-
-1. Open the **LDAP Synchronization** page for the GitLab group.
-1. Select **LDAP user filter** as the **Sync method**.
-1. Enter an LDAP user filter in the **LDAP user filter** field.
-
-The filter must comply with the
-syntax defined in [RFC 2254](https://tools.ietf.org/search/rfc2254).
-
-## Administrator sync
-
-As an extension of group sync, you can automatically manage your global GitLab
-administrators. Specify a group CN for `admin_group` and all members of the
-LDAP group will be given administrator privileges. The configuration will look
-like the following.
-
-NOTE: **Note:**
-Administrators will not be synced unless `group_base` is also
-specified alongside `admin_group`. Also, only specify the CN of the admin
-group, as opposed to the full DN.
-
-**Omnibus configuration**
-
-1. Edit `/etc/gitlab/gitlab.rb`:
-
- ```ruby
- gitlab_rails['ldap_servers'] = YAML.load <<-EOS
- main:
- ## snip...
- ##
- ## Base where we can search for groups
- ##
- ## Ex. ou=groups,dc=gitlab,dc=example
- ##
- ##
- group_base: ou=groups,dc=example,dc=com
-
- ##
- ## The CN of a group containing GitLab administrators
- ##
- ## Ex. administrators
- ##
- ## Note: Not `cn=administrators` or the full DN
- ##
- ##
- admin_group: my_admin_group
-
- EOS
- ```
-
-1. [Apply your changes to GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
-
-**Source configuration**
-
-1. Edit `/home/git/gitlab/config/gitlab.yml`:
-
- ```yaml
- production:
- ldap:
- servers:
- main:
- # snip...
- group_base: ou=groups,dc=example,dc=com
- admin_group: my_admin_group
- ```
-
-1. [Restart GitLab](../restart_gitlab.md#installations-from-source) for the changes to take effect.
-
-## Global group memberships lock
-
-"Lock memberships to LDAP synchronization" setting allows instance administrators
-to lock down user abilities to invite new members to a group.
-
-When enabled, the following applies:
-
-- Only administrator can manage memberships of any group including access levels.
-- Users are not allowed to share project with other groups or invite members to
- a project created in a group.
-
-## Adjusting LDAP user sync schedule
-
-> Introduced in GitLab Enterprise Edition Starter.
-
-NOTE: **Note:**
-These are cron formatted values. You can use a crontab generator to create
-these values, for example <http://www.crontabgenerator.com/>.
-
-By default, GitLab will run a worker once per day at 01:30 a.m. server time to
-check and update GitLab users against LDAP.
-
-You can manually configure LDAP user sync times by setting the
-following configuration values. The example below shows how to set LDAP user
-sync to run once every 12 hours at the top of the hour.
-
-**Omnibus installations**
-
-1. Edit `/etc/gitlab/gitlab.rb`:
-
- ```ruby
- gitlab_rails['ldap_sync_worker_cron'] = "0 */12 * * *"
- ```
-
-1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
-
-**Source installations**
-
-1. Edit `config/gitlab.yaml`:
-
- ```yaml
- cron_jobs:
- ldap_sync_worker_cron:
- "0 */12 * * *"
- ```
-
-1. [Restart GitLab](../restart_gitlab.md#installations-from-source) for the changes to take effect.
-
-## Adjusting LDAP group sync schedule
-
-NOTE: **Note:**
-These are cron formatted values. You can use a crontab generator to create
-these values, for example <http://www.crontabgenerator.com/>.
-
-By default, GitLab will run a group sync process every hour, on the hour.
-
-CAUTION: **Important:**
-It's recommended that you do not run too short intervals as this
-could lead to multiple syncs running concurrently. This is primarily a concern
-for installations with a large number of LDAP users. Please review the
-[LDAP group sync benchmark metrics](#benchmarks) to see how
-your installation compares before proceeding.
-
-You can manually configure LDAP group sync times by setting the
-following configuration values. The example below shows how to set group
-sync to run once every 2 hours at the top of the hour.
-
-**Omnibus installations**
-
-1. Edit `/etc/gitlab/gitlab.rb`:
-
- ```ruby
- gitlab_rails['ldap_group_sync_worker_cron'] = "0 */2 * * * *"
- ```
-
-1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
-
-**Source installations**
-
-1. Edit `config/gitlab.yaml`:
-
- ```yaml
- cron_jobs:
- ldap_group_sync_worker_cron:
- "*/30 * * * *"
- ```
-
-1. [Restart GitLab](../restart_gitlab.md#installations-from-source) for the changes to take effect.
-
-## External groups
-
-> Introduced in GitLab Enterprise Edition Starter 8.9.
-
-Using the `external_groups` setting will allow you to mark all users belonging
-to these groups as [external users](../../user/permissions.md#external-users-core-only).
-Group membership is checked periodically through the `LdapGroupSync` background
-task.
-
-**Omnibus configuration**
-
-1. Edit `/etc/gitlab/gitlab.rb`:
-
- ```ruby
- gitlab_rails['ldap_servers'] = YAML.load <<-EOS
- main:
- ## snip...
- ##
- ## An array of CNs of groups containing users that should be considered external
- ##
- ## Ex. ['interns', 'contractors']
- ##
- ## Note: Not `cn=interns` or the full DN
- ##
- external_groups: ['interns', 'contractors']
- EOS
- ```
-
-1. [Apply your changes to GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
-
-**Source configuration**
-
-1. Edit `config/gitlab.yaml`:
-
- ```yaml
- production:
- ldap:
- servers:
- main:
- # snip...
- external_groups: ['interns', 'contractors']
- ```
-
-1. [Restart GitLab](../restart_gitlab.md#installations-from-source) for the changes to take effect.
-
-## Group sync technical details
-
-There is a lot going on with group sync 'under the hood'. This section
-outlines what LDAP queries are executed and what behavior you can expect
-from group sync.
-
-Group member access will be downgraded from a higher level if their LDAP group
-membership changes. For example, if a user has 'Owner' rights in a group and the
-next group sync reveals they should only have 'Developer' privileges, their
-access will be adjusted accordingly. The only exception is if the user is the
-*last* owner in a group. Groups need at least one owner to fulfill
-administrative duties.
-
-### Supported LDAP group types/attributes
-
-GitLab supports LDAP groups that use member attributes:
-
-- `member`
-- `submember`
-- `uniquemember`
-- `memberof`
-- `memberuid`.
-
-This means group sync supports, at least, LDAP groups with object class:
-`groupOfNames`, `posixGroup`, and `groupOfUniqueNames`.
-
-Other object classes should work fine as long as members
-are defined as one of the mentioned attributes. This also means GitLab supports
-Microsoft Active Directory, Apple Open Directory, Open LDAP, and 389 Server.
-Other LDAP servers should work, too.
-
-Active Directory also supports nested groups. Group sync will recursively
-resolve membership if `active_directory: true` is set in the configuration file.
-
-NOTE: **Note:**
-Nested group membership will only be resolved if the nested group
-also falls within the configured `group_base`. For example, if GitLab sees a
-nested group with DN `cn=nested_group,ou=special_groups,dc=example,dc=com` but
-the configured `group_base` is `ou=groups,dc=example,dc=com`, `cn=nested_group`
-will be ignored.
-
-### Queries
-
-- Each LDAP group is queried a maximum of one time with base `group_base` and
- filter `(cn=<cn_from_group_link>)`.
-- If the LDAP group has the `memberuid` attribute, GitLab will execute another
- LDAP query per member to obtain each user's full DN. These queries are
- executed with base `base`, scope 'base object', and a filter depending on
- whether `user_filter` is set. Filter may be `(uid=<uid_from_group>)` or a
- joining of `user_filter`.
-
-### Benchmarks
-
-Group sync was written to be as performant as possible. Data is cached, database
-queries are optimized, and LDAP queries are minimized. The last benchmark run
-revealed the following metrics:
-
-For 20000 LDAP users, 11000 LDAP groups and 1000 GitLab groups with 10
-LDAP group links each:
-
-- Initial sync (no existing members assigned in GitLab) took 1.8 hours
-- Subsequent syncs (checking membership, no writes) took 15 minutes
-
-These metrics are meant to provide a baseline and performance may vary based on
-any number of factors. This was a pretty extreme benchmark and most instances will
-not have near this many users or groups. Disk speed, database performance,
-network and LDAP server response time will affect these metrics.
-
-## Troubleshooting
-
-Please see our [administrator guide to troubleshooting LDAP](ldap-troubleshooting.md).
+This document was moved to [another location](ldap/index.md).
diff --git a/doc/administration/auth/ldap-troubleshooting.md b/doc/administration/auth/ldap-troubleshooting.md
index 77c9c30d140..a553f449abb 100644
--- a/doc/administration/auth/ldap-troubleshooting.md
+++ b/doc/administration/auth/ldap-troubleshooting.md
@@ -1,651 +1,5 @@
-# LDAP Troubleshooting for Administrators
+---
+redirect_to: 'ldap/ldap-troubleshooting.md'
+---
-## Common Problems & Workflows
-
-### Connection
-
-#### Connection refused
-
-If you are getting `Connection Refused` errors when trying to connect to the
-LDAP server please double-check the LDAP `port` and `encryption` settings used by
-GitLab. Common combinations are `encryption: 'plain'` and `port: 389`, OR
-`encryption: 'simple_tls'` and `port: 636`.
-
-#### Connection times out
-
-If GitLab cannot reach your LDAP endpoint, you will see a message like this:
-
-```plaintext
-Could not authenticate you from Ldapmain because "Connection timed out - user specified timeout".
-```
-
-If your configured LDAP provider and/or endpoint is offline or otherwise
-unreachable by GitLab, no LDAP user will be able to authenticate and log in.
-GitLab does not cache or store credentials for LDAP users to provide authentication
-during an LDAP outage.
-
-Contact your LDAP provider or administrator if you are seeing this error.
-
-#### Referral error
-
-If you see `LDAP search error: Referral` in the logs, or when troubleshooting
-LDAP Group Sync, this error may indicate a configuration problem. The LDAP
-configuration `/etc/gitlab/gitlab.rb` (Omnibus) or `config/gitlab.yml` (source)
-is in YAML format and is sensitive to indentation. Check that `group_base` and
-`admin_group` configuration keys are indented 2 spaces past the server
-identifier. The default identifier is `main` and an example snippet looks like
-the following:
-
-```yaml
-main: # 'main' is the GitLab 'provider ID' of this LDAP server
- label: 'LDAP'
- host: 'ldap.example.com'
- ...
- group_base: 'cn=my_group,ou=groups,dc=example,dc=com'
- admin_group: 'my_admin_group'
-```
-
-#### Query LDAP **(STARTER ONLY)**
-
-The following allows you to perform a search in LDAP using the rails console.
-Depending on what you're trying to do, it may make more sense to query [a
-user](#query-a-user-in-ldap) or [a group](#query-a-group-in-ldap-starter-only) directly, or
-even [use `ldapsearch`](#ldapsearch) instead.
-
-```ruby
-adapter = Gitlab::Auth::Ldap::Adapter.new('ldapmain')
-options = {
- # :base is required
- # use .base or .group_base
- base: adapter.config.group_base,
-
- # :filter is optional
- # 'cn' looks for all "cn"s under :base
- # '*' is the search string - here, it's a wildcard
- filter: Net::Ldap::Filter.eq('cn', '*'),
-
- # :attributes is optional
- # the attributes we want to get returned
- attributes: %w(dn cn memberuid member submember uniquemember memberof)
-}
-adapter.ldap_search(options)
-```
-
-For examples of how this is run,
-[review the `Adapter` module](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/lib/ee/gitlab/auth/ldap/adapter.rb).
-
-### User logins
-
-#### No users are found
-
-If [you've confirmed](#ldap-check) that a connection to LDAP can be
-established but GitLab doesn't show you LDAP users in the output, one of the
-following is most likely true:
-
-- The `bind_dn` user doesn't have enough permissions to traverse the user tree.
-- The user(s) don't fall under the [configured `base`](ldap.md#configuration).
-- The [configured `user_filter`](ldap.md#using-an-ldap-filter-to-limit-access-to-your-gitlab-server) blocks access to the user(s).
-
-In this case, you con confirm which of the above is true using
-[ldapsearch](#ldapsearch) with the existing LDAP configuration in your
-`/etc/gitlab/gitlab.rb`.
-
-#### User(s) cannot login
-
-A user can have trouble logging in for any number of reasons. To get started,
-here are some questions to ask yourself:
-
-- Does the user fall under the [configured `base`](ldap.md#configuration) in
- LDAP? The user must fall under this `base` to login.
-- Does the user pass through the [configured `user_filter`](ldap.md#using-an-ldap-filter-to-limit-access-to-your-gitlab-server)?
- If one is not configured, this question can be ignored. If it is, then the
- user must also pass through this filter to be allowed to login.
- - Refer to our docs on [debugging the `user_filter`](#debug-ldap-user-filter).
-
-If the above are both okay, the next place to look for the problem is
-the logs themselves while reproducing the issue.
-
-- Ask the user to login and let it fail.
-- [Look through the output](#gitlab-logs) for any errors or other
- messages about the login. You may see one of the other error messages on
- this page, in which case that section can help resolve the issue.
-
-If the logs don't lead to the root of the problem, use the
-[rails console](#rails-console) to [query this user](#query-a-user-in-ldap)
-to see if GitLab can read this user on the LDAP server.
-
-It can also be helpful to
-[debug a user sync](#sync-all-users-starter-only) to
-investigate further.
-
-#### Invalid credentials on login
-
-If that the login credentials used are accurate on LDAP, ensure the following
-are true for the user in question:
-
-- Make sure the user you are binding with has enough permissions to read the user's
- tree and traverse it.
-- Check that the `user_filter` is not blocking otherwise valid users.
-- Run [an LDAP check command](#ldap-check) to make sure that the LDAP settings
- are correct and [GitLab can see your users](#no-users-are-found).
-
-#### Email has already been taken
-
-A user tries to login with the correct LDAP credentials, is denied access,
-and the [production.log](../logs.md#productionlog) shows an error that looks like this:
-
-```plaintext
-(LDAP) Error saving user <USER DN> (email@example.com): ["Email has already been taken"]
-```
-
-This error is referring to the email address in LDAP, `email@example.com`. Email
-addresses must be unique in GitLab and LDAP links to a user's primary email (as opposed
-to any of their possibly-numerous secondary emails). Another user (or even the
-same user) has the email `email@example.com` set as a secondary email, which
-is throwing this error.
-
-We can check where this conflicting email address is coming from using the
-[rails console](#rails-console). Once in the console, run the following:
-
-```ruby
-# This searches for an email among the primary AND secondary emails
-user = User.find_by_any_email('email@example.com')
-user.username
-```
-
-This will show you which user has this email address. One of two steps will
-have to be taken here:
-
-- To create a new GitLab user/username for this user when logging in with LDAP,
- remove the secondary email to remove the conflict.
-- To use an existing GitLab user/username for this user to use with LDAP,
- remove this email as a secondary email and make it a primary one so GitLab
- will associate this profile to the LDAP identity.
-
-The user can do either of these steps [in their
-profile](../../user/profile/index.md#user-profile) or an admin can do it.
-
-#### Debug LDAP user filter
-
-[`ldapsearch`](#ldapsearch) allows you to test your configured
-[user filter](ldap.md#using-an-ldap-filter-to-limit-access-to-your-gitlab-server)
-to confirm that it returns the users you expect it to return.
-
-```shell
-ldapsearch -H ldaps://$host:$port -D "$bind_dn" -y bind_dn_password.txt -b "$base" "$user_filter" sAMAccountName
-```
-
-- Variables beginning with a `$` refer to a variable from the LDAP section of
- your configuration file.
-- Replace `ldaps://` with `ldap://` if you are using the plain authentication method.
- Port `389` is the default `ldap://` port and `636` is the default `ldaps://`
- port.
-- We are assuming the password for the `bind_dn` user is in `bind_dn_password.txt`.
-
-#### Sync all users **(STARTER ONLY)**
-
-The output from a manual [user sync](ldap-ee.md#user-sync) can show you what happens when
-GitLab tries to sync its users against LDAP. Enter the [rails console](#rails-console)
-and then run:
-
-```ruby
-Rails.logger.level = Logger::DEBUG
-
-LdapSyncWorker.new.perform
-```
-
-Next, [learn how to read the
-output](#example-console-output-after-a-user-sync-starter-only).
-
-##### Example console output after a user sync **(STARTER ONLY)**
-
-The output from a [manual user sync](#sync-all-users-starter-only) will be very verbose, and a
-single user's successful sync can look like this:
-
-```shell
-Syncing user John, email@example.com
- Identity Load (0.9ms) SELECT "identities".* FROM "identities" WHERE "identities"."user_id" = 20 AND (provider LIKE 'ldap%') LIMIT 1
-Instantiating Gitlab::Auth::Ldap::Person with LDIF:
-dn: cn=John Smith,ou=people,dc=example,dc=com
-cn: John Smith
-mail: email@example.com
-memberof: cn=admin_staff,ou=people,dc=example,dc=com
-uid: John
-
- UserSyncedAttributesMetadata Load (0.9ms) SELECT "user_synced_attributes_metadata".* FROM "user_synced_attributes_metadata" WHERE "user_synced_attributes_metadata"."user_id" = 20 LIMIT 1
- (0.3ms) BEGIN
- Namespace Load (1.0ms) SELECT "namespaces".* FROM "namespaces" WHERE "namespaces"."owner_id" = 20 AND "namespaces"."type" IS NULL LIMIT 1
- Route Load (0.8ms) SELECT "routes".* FROM "routes" WHERE "routes"."source_id" = 27 AND "routes"."source_type" = 'Namespace' LIMIT 1
- Ci::Runner Load (1.1ms) SELECT "ci_runners".* FROM "ci_runners" INNER JOIN "ci_runner_namespaces" ON "ci_runners"."id" = "ci_runner_namespaces"."runner_id" WHERE "ci_runner_namespaces"."namespace_id" = 27
- (0.7ms) COMMIT
- (0.4ms) BEGIN
- Route Load (0.8ms) SELECT "routes".* FROM "routes" WHERE (LOWER("routes"."path") = LOWER('John'))
- Namespace Load (1.0ms) SELECT "namespaces".* FROM "namespaces" WHERE "namespaces"."id" = 27 LIMIT 1
- Route Exists (0.9ms) SELECT 1 AS one FROM "routes" WHERE LOWER("routes"."path") = LOWER('John') AND "routes"."id" != 50 LIMIT 1
- User Update (1.1ms) UPDATE "users" SET "updated_at" = '2019-10-17 14:40:59.751685', "last_credential_check_at" = '2019-10-17 14:40:59.738714' WHERE "users"."id" = 20
-```
-
-There's a lot here, so let's go over what could be helpful when debugging.
-
-First, GitLab will look for all users that have previously
-logged in with LDAP and iterate on them. Each user's sync will start with
-the following line that contains the user's username and email, as they
-exist in GitLab now:
-
-```shell
-Syncing user John, email@example.com
-```
-
-If you don't find a particular user's GitLab email in the output, then that
-user hasn't logged in with LDAP yet.
-
-Next, GitLab searches its `identities` table for the existing
-link between this user and the configured LDAP provider(s):
-
-```sql
- Identity Load (0.9ms) SELECT "identities".* FROM "identities" WHERE "identities"."user_id" = 20 AND (provider LIKE 'ldap%') LIMIT 1
-```
-
-The identity object will have the DN that GitLab will use to look for the user
-in LDAP. If the DN isn't found, the email is used instead. We can see that
-this user is found in LDAP:
-
-```shell
-Instantiating Gitlab::Auth::Ldap::Person with LDIF:
-dn: cn=John Smith,ou=people,dc=example,dc=com
-cn: John Smith
-mail: email@example.com
-memberof: cn=admin_staff,ou=people,dc=example,dc=com
-uid: John
-```
-
-If the user wasn't found in LDAP with either the DN or email, you may see the
-following message instead:
-
-```shell
-LDAP search error: No Such Object
-```
-
-...in which case the user will be blocked:
-
-```shell
- User Update (0.4ms) UPDATE "users" SET "state" = $1, "updated_at" = $2 WHERE "users"."id" = $3 [["state", "ldap_blocked"], ["updated_at", "2019-10-18 15:46:22.902177"], ["id", 20]]
-```
-
-Once the user is found in LDAP the rest of the output will update the GitLab
-database with any changes.
-
-#### Query a user in LDAP
-
-This will test that GitLab can reach out to LDAP and read a particular user.
-It can expose potential errors connecting to and/or querying LDAP
-that may seem to fail silently in the GitLab UI.
-
-```ruby
-Rails.logger.level = Logger::DEBUG
-
-adapter = Gitlab::Auth::Ldap::Adapter.new('ldapmain') # If `main` is the LDAP provider
-Gitlab::Auth::Ldap::Person.find_by_uid('<uid>', adapter)
-```
-
-### Group memberships **(STARTER ONLY)**
-
-#### Membership(s) not granted **(STARTER ONLY)**
-
-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
-things to check to debug the situation.
-
-- Ensure LDAP configuration has a `group_base` specified.
- [This configuration](ldap-ee.md#group-sync) is required for group sync to work properly.
-- Ensure the correct [LDAP group link is added to the GitLab
- group](ldap-ee.md#adding-group-links).
-- Check that the user has an LDAP identity:
- 1. Sign in to GitLab as an administrator user.
- 1. Navigate to **Admin area -> Users**.
- 1. Search for the user
- 1. Open the user, by clicking on their name. Do not click 'Edit'.
- 1. Navigate to the **Identities** tab. There should be an LDAP identity with
- an LDAP DN as the 'Identifier'. If not, this user hasn't logged in with
- LDAP yet and must do so first.
-- You've waited an hour or [the configured
- interval](ldap-ee.md#adjusting-ldap-group-sync-schedule) for the group to
- sync. To speed up the process, either go to the GitLab group **Settings ->
- Members** and press **Sync now** (sync one group) or [run the group sync Rake
- task](../raketasks/ldap.md#run-a-group-sync-starter-only) (sync all groups).
-
-If all of the above looks good, jump in to a little more advanced debugging in
-the rails console.
-
-1. Enter the [rails console](#rails-console).
-1. Choose a GitLab group to test with. This group should have an LDAP group link
- already configured.
-1. [Enable debug logging, find the above GitLab group, and sync it with LDAP](#sync-one-group-starter-only).
-1. Look through the output of the sync. See [example log
- output](#example-console-output-after-a-group-sync-starter-only)
- for how to read the output.
-1. If you still aren't able to see why the user isn't being added, [query the
- LDAP group directly](#query-a-group-in-ldap-starter-only) to see what members are listed.
-1. Is the user's DN or UID in one of the lists from the above output? One of the DNs or
- UIDs here should match the 'Identifier' from the LDAP identity checked earlier. If it doesn't,
- the user does not appear to be in the LDAP group.
-
-#### Admin privileges not granted
-
-When [Administrator sync](ldap-ee.md#administrator-sync) has been configured
-but the configured users aren't granted the correct admin privileges, confirm
-the following are true:
-
-- A [`group_base` is also configured](ldap-ee.md#group-sync).
-- The configured `admin_group` in the `gitlab.rb` is a CN, rather than a DN or an array.
-- This CN falls under the scope of the configured `group_base`.
-- The members of the `admin_group` have already logged into GitLab with their LDAP
- credentials. GitLab will only grant this admin access to the users whose
- accounts are already connected to LDAP.
-
-If all the above are true and the users are still not getting access, [run a manual
-group sync](#sync-all-groups-starter-only) in the rails console and [look through the
-output](#example-console-output-after-a-group-sync-starter-only) to see what happens when
-GitLab syncs the `admin_group`.
-
-#### Sync all groups **(STARTER ONLY)**
-
-NOTE: **NOTE:**
-To sync all groups manually when debugging is unnecessary, [use the Rake
-task](../raketasks/ldap.md#run-a-group-sync-starter-only) instead.
-
-The output from a manual [group sync](ldap-ee.md#group-sync) can show you what happens
-when GitLab syncs its LDAP group memberships against LDAP.
-
-```ruby
-Rails.logger.level = Logger::DEBUG
-
-LdapAllGroupsSyncWorker.new.perform
-```
-
-Next, [learn how to read the
-output](#example-console-output-after-a-group-sync-starter-only).
-
-##### Example console output after a group sync **(STARTER ONLY)**
-
-Like the output from the user sync, the output from the [manual group
-sync](#sync-all-groups-starter-only) will also be very verbose. However, it contains lots
-of helpful information.
-
-Indicates the point where syncing actually begins:
-
-```shell
-Started syncing 'ldapmain' provider for 'my_group' group
-```
-
-The following entry shows an array of all user DNs GitLab sees in the LDAP server.
-Note that these are the users for a single LDAP group, not a GitLab group. If
-you have multiple LDAP groups linked to this GitLab group, you will see multiple
-log entries like this - one for each LDAP group. If you don't see an LDAP user
-DN in this log entry, LDAP is not returning the user when we do the lookup.
-Verify the user is actually in the LDAP group.
-
-```shell
-Members in 'ldap_group_1' LDAP group: ["uid=john0,ou=people,dc=example,dc=com",
-"uid=mary0,ou=people,dc=example,dc=com", "uid=john1,ou=people,dc=example,dc=com",
-"uid=mary1,ou=people,dc=example,dc=com", "uid=john2,ou=people,dc=example,dc=com",
-"uid=mary2,ou=people,dc=example,dc=com", "uid=john3,ou=people,dc=example,dc=com",
-"uid=mary3,ou=people,dc=example,dc=com", "uid=john4,ou=people,dc=example,dc=com",
-"uid=mary4,ou=people,dc=example,dc=com"]
-```
-
-Shortly after each of the above entries, you will see a hash of resolved member
-access levels. This hash represents all user DNs GitLab thinks should have
-access to this group, and at which access level (role). This hash is additive,
-and more DNs may be added, or existing entries modified, based on additional
-LDAP group lookups. The very last occurrence of this entry should indicate
-exactly which users GitLab believes should be added to the group.
-
-NOTE: **Note:**
-10 is 'Guest', 20 is 'Reporter', 30 is 'Developer', 40 is 'Maintainer'
-and 50 is 'Owner'.
-
-```shell
-Resolved 'my_group' group member access: {"uid=john0,ou=people,dc=example,dc=com"=>30,
-"uid=mary0,ou=people,dc=example,dc=com"=>30, "uid=john1,ou=people,dc=example,dc=com"=>30,
-"uid=mary1,ou=people,dc=example,dc=com"=>30, "uid=john2,ou=people,dc=example,dc=com"=>30,
-"uid=mary2,ou=people,dc=example,dc=com"=>30, "uid=john3,ou=people,dc=example,dc=com"=>30,
-"uid=mary3,ou=people,dc=example,dc=com"=>30, "uid=john4,ou=people,dc=example,dc=com"=>30,
-"uid=mary4,ou=people,dc=example,dc=com"=>30}
-```
-
-It's not uncommon to see warnings like the following. These indicate that GitLab
-would have added the user to a group, but the user could not be found in GitLab.
-Usually this is not a cause for concern.
-
-If you think a particular user should already exist in GitLab, but you're seeing
-this entry, it could be due to a mismatched DN stored in GitLab. See
-[User DN and/or email have changed](#user-dn-orand-email-have-changed) to update the user's LDAP identity.
-
-```shell
-User with DN `uid=john0,ou=people,dc=example,dc=com` should have access
-to 'my_group' group but there is no user in GitLab with that
-identity. Membership will be updated once the user signs in for
-the first time.
-```
-
-Finally, the following entry says syncing has finished for this group:
-
-```shell
-Finished syncing all providers for 'my_group' group
-```
-
-Once all the configured group links have been synchronized, GitLab will look
-for any Administrators or External users to sync:
-
-```shell
-Syncing admin users for 'ldapmain' provider
-```
-
-The output will look similar to what happens with a single group, and then
-this line will indicate the sync is finished:
-
-```shell
-Finished syncing admin users for 'ldapmain' provider
-```
-
-If [admin sync](ldap-ee.md#administrator-sync) is not configured, you'll see a message
-stating as such:
-
-```shell
-No `admin_group` configured for 'ldapmain' provider. Skipping
-```
-
-#### Sync one group **(STARTER ONLY)**
-
-[Syncing all groups](#sync-all-groups-starter-only) can produce a lot of noise in the output, which can be
-distracting when you're only interested in troubleshooting the memberships of
-a single GitLab group. In that case, here's how you can just sync this group
-and see its debug output:
-
-```ruby
-Rails.logger.level = Logger::DEBUG
-
-# Find the GitLab group.
-# If the output is `nil`, the group could not be found.
-# If a bunch of group attributes are in the output, your group was found successfully.
-group = Group.find_by(name: 'my_gitlab_group')
-
-# Sync this group against LDAP
-EE::Gitlab::Auth::Ldap::Sync::Group.execute_all_providers(group)
-```
-
-The output will be similar to
-[that you'd get from syncing all groups](#example-console-output-after-a-group-sync-starter-only).
-
-#### Query a group in LDAP **(STARTER ONLY)**
-
-When you'd like to confirm that GitLab can read a LDAP group and see all its members,
-you can run the following:
-
-```ruby
-# Find the adapter and the group itself
-adapter = Gitlab::Auth::Ldap::Adapter.new('ldapmain') # If `main` is the LDAP provider
-ldap_group = EE::Gitlab::Auth::Ldap::Group.find_by_cn('group_cn_here', adapter)
-
-# Find the members of the LDAP group
-ldap_group.member_dns
-ldap_group.member_uids
-```
-
-### User DN or/and email have changed
-
-When an LDAP user is created in GitLab, their LDAP DN is stored for later reference.
-
-If GitLab cannot find a user by their DN, it will fall back
-to finding the user by their email. If the lookup is successful, GitLab will
-update the stored DN to the new value so both values will now match what's in
-LDAP.
-
-If the email has changed and the DN has not, GitLab will find the user with
-the DN and update its own record of the user's email to match the one in LDAP.
-
-However, if the primary email _and_ the DN change in LDAP, then GitLab will
-have no way of identifying the correct LDAP record of the user and, as a
-result, the user will be blocked. To rectify this, the user's existing
-profile will have to be updated with at least one of the new values (primary
-email or DN) so the LDAP record can be found.
-
-The following script will update the emails for all provided users so they
-won't be blocked or unable to access their accounts.
-
->**NOTE**: The following script will require that any new accounts with the new
-email address are removed first. This is because emails have to be unique in GitLab.
-
-Go to the [rails console](#rails-console) and then run:
-
-```ruby
-# Each entry will have to include the old username and the new email
-emails = {
- 'ORIGINAL_USERNAME' => 'NEW_EMAIL_ADDRESS',
- ...
-}
-
-emails.each do |username, email|
- user = User.find_by_username(username)
- user.email = email
- user.skip_reconfirmation!
- user.save!
-end
-```
-
-You can then [run a UserSync](#sync-all-users-starter-only) **(STARTER ONLY)** to sync the latest DN
-for each of these users.
-
-## Debugging Tools
-
-### LDAP check
-
-The [Rake task to check LDAP](../raketasks/ldap.md#check) is a valuable tool
-to help determine whether GitLab can successfully establish a connection to
-LDAP and can get so far as to even read users.
-
-If a connection can't be established, it is likely either because of a problem
-with your configuration or a firewall blocking the connection.
-
-- Ensure you don't have a firewall blocking the
-connection, and that the LDAP server is accessible to the GitLab host.
-- Look for an error message in the Rake check output, which may lead to your LDAP configuration to
-confirm that the configuration values (specifically `host`, `port`, `bind_dn`, and
-`password`) are correct.
-- Look for [errors](#connection) in [the logs](#gitlab-logs) to further debug connection failures.
-
-If GitLab can successfully connect to LDAP but doesn't return any
-users, [see what to do when no users are found](#no-users-are-found).
-
-### GitLab logs
-
-If a user account is blocked or unblocked due to the LDAP configuration, a
-message will be [logged to `application.log`](../logs.md#applicationlog).
-
-If there is an unexpected error during an LDAP lookup (configuration error,
-timeout), the login is rejected and a message will be [logged to
-`production.log`](../logs.md#productionlog).
-
-### ldapsearch
-
-`ldapsearch` is a utility that will allow you to query your LDAP server. You can
-use it to test your LDAP settings and ensure that the settings you're using
-will get you the results you expect.
-
-When using `ldapsearch`, be sure to use the same settings you've already
-specified in your `gitlab.rb` configuration so you can confirm what happens
-when those exact settings are used.
-
-Running this command on the GitLab host will also help confirm that there's no
-obstruction between the GitLab host and LDAP.
-
-For example, consider the following GitLab configuration:
-
-```shell
-gitlab_rails['ldap_servers'] = YAML.load <<-'EOS' # remember to close this block with 'EOS' below
- main: # 'main' is the GitLab 'provider ID' of this LDAP server
- label: 'LDAP'
- host: '127.0.0.1'
- port: 389
- uid: 'uid'
- encryption: 'plain'
- bind_dn: 'cn=admin,dc=ldap-testing,dc=example,dc=com'
- password: 'Password1'
- active_directory: true
- allow_username_or_email_login: false
- block_auto_created_users: false
- base: 'dc=ldap-testing,dc=example,dc=com'
- user_filter: ''
- attributes:
- username: ['uid', 'userid', 'sAMAccountName']
- email: ['mail', 'email', 'userPrincipalName']
- name: 'cn'
- first_name: 'givenName'
- last_name: 'sn'
- group_base: 'ou=groups,dc=ldap-testing,dc=example,dc=com'
- admin_group: 'gitlab_admin'
-EOS
-```
-
-You would run the following `ldapsearch` to find the `bind_dn` user:
-
-```shell
-ldapsearch -D "cn=admin,dc=ldap-testing,dc=example,dc=com" \
- -w Password1 \
- -p 389 \
- -h 127.0.0.1 \
- -b "dc=ldap-testing,dc=example,dc=com"
-```
-
-Note that the `bind_dn`, `password`, `port`, `host`, and `base` are all
-identical to what's configured in the `gitlab.rb`.
-
-Please see [the official
-`ldapsearch` documentation](https://linux.die.net/man/1/ldapsearch) for more.
-
-### Rails console
-
-CAUTION: **CAUTION:**
-Please note that it is very easy to create, read, modify, and destroy data on the
-rails console, so please be sure to run commands exactly as listed.
-
-The rails console is a valuable tool to help debug LDAP problems. It allows you to
-directly interact with the application by running commands and seeing how GitLab
-responds to them.
-
-Please refer to [this guide](../troubleshooting/debug.md#starting-a-rails-console-session)
-for instructions on how to use the rails console.
-
-#### Enable debug output
-
-This will provide debug output that will be useful to see
-what GitLab is doing and with what. This value is not persisted, and will only
-be enabled for this session in the rails console.
-
-To enable debug output in the rails console, [enter the rails
-console](#rails-console) and run:
-
-```ruby
-Rails.logger.level = Logger::DEBUG
-```
+This document was moved to [another location](ldap/ldap-troubleshooting.md).
diff --git a/doc/administration/auth/ldap.md b/doc/administration/auth/ldap.md
index 1e91b539db5..f5565628af1 100644
--- a/doc/administration/auth/ldap.md
+++ b/doc/administration/auth/ldap.md
@@ -1,555 +1,5 @@
---
-type: reference
+redirect_to: 'ldap/index.md'
---
-<!-- If the change is EE-specific, put it in `ldap-ee.md`, NOT here. -->
-
-# LDAP
-
-GitLab integrates with LDAP to support user authentication.
-
-This integration works with most LDAP-compliant directory servers, including:
-
-- Microsoft Active Directory
-- Apple Open Directory
-- Open LDAP
-- 389 Server.
-
-GitLab Enterprise Editions (EE) include enhanced integration,
-including group membership syncing as well as multiple LDAP servers support.
-
-For more details about EE-specific LDAP features, see the
-[LDAP Enterprise Edition documentation](ldap-ee.md).
-
-NOTE: **Note:**
-The information on this page is relevant for both GitLab CE and EE.
-
-## Overview
-
-[LDAP](https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol)
-stands for **Lightweight Directory Access Protocol**, which is a standard
-application protocol for accessing and maintaining distributed directory
-information services over an Internet Protocol (IP) network.
-
-## Security
-
-GitLab assumes that LDAP users:
-
-- Are not able to change their LDAP `mail`, `email`, or `userPrincipalName` attribute.
- An LDAP user who is allowed to change their email on the LDAP server can potentially
- [take over any account](#enabling-ldap-sign-in-for-existing-gitlab-users)
- on your GitLab server.
-- Have unique email addresses, otherwise it is possible for LDAP users with the same
- email address to share the same GitLab account.
-
-We recommend against using LDAP integration if your LDAP users are
-allowed to change their 'mail', 'email' or 'userPrincipalName' attribute on
-the LDAP server or share email addresses.
-
-### User deletion
-
-If a user is deleted from the LDAP server, they will be blocked in GitLab as
-well. Users will be immediately blocked from logging in. However, there is an
-LDAP check cache time of one hour (see note) which means users that
-are already logged in or are using Git over SSH will still be able to access
-GitLab for up to one hour. Manually block the user in the GitLab Admin Area to
-immediately block all access.
-
-NOTE: **Note**:
-GitLab Enterprise Edition Starter supports a
-[configurable sync time](ldap-ee.md#adjusting-ldap-user-sync-schedule),
-with a default of one hour.
-
-## Git password authentication
-
-LDAP-enabled users can always authenticate with Git using their GitLab username
-or email and LDAP password, even if password authentication for Git is disabled
-in the application settings.
-
-## Google Secure LDAP **(CORE ONLY)**
-
-> Introduced in GitLab 11.9.
-
-[Google Cloud Identity](https://cloud.google.com/identity/) provides a Secure
-LDAP service that can be configured with GitLab for authentication and group sync.
-See [Google Secure LDAP](google_secure_ldap.md) for detailed configuration instructions.
-
-## Configuration
-
-NOTE: **Note**:
-In GitLab Enterprise Edition Starter, you can configure multiple LDAP servers
-to connect to one GitLab server.
-
-For a complete guide on configuring LDAP with:
-
-- GitLab Community Edition, see
- [How to configure LDAP with GitLab CE](how_to_configure_ldap_gitlab_ce/index.md).
-- Enterprise Editions, see
- [How to configure LDAP with GitLab EE](how_to_configure_ldap_gitlab_ee/index.md). **(STARTER ONLY)**
-
-To enable LDAP integration you need to 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.
-
-There is a Rake task to check LDAP configuration. After configuring LDAP
-using the documentation below, see [LDAP check Rake task](../raketasks/check.md#ldap-check)
-for information on the LDAP check Rake task.
-
-Prior to version 7.4, GitLab used a different syntax for configuring
-LDAP integration. The old LDAP integration syntax still works but may be
-removed in a future version. If your `gitlab.rb` or `gitlab.yml` file contains
-LDAP settings in both the old syntax and the new syntax, only the __old__
-syntax will be used by GitLab.
-
-The configuration inside `gitlab_rails['ldap_servers']` below is sensitive to
-incorrect indentation. Be sure to retain the indentation given in the example.
-Copy/paste can sometimes cause problems.
-
-NOTE: **Note:**
-The `encryption` value `ssl` corresponds to 'Simple TLS' in the LDAP
-library. `tls` corresponds to StartTLS, not to be confused with regular TLS.
-Normally, if you specify `ssl` it will be on port 636, while `tls` (StartTLS)
-would be on port 389. `plain` also operates on port 389.
-
-NOTE: **Note:**
-LDAP users must have an email address set, regardless of whether it is used to log in.
-
-**Omnibus configuration**
-
-```ruby
-gitlab_rails['ldap_enabled'] = true
-gitlab_rails['prevent_ldap_sign_in'] = false
-gitlab_rails['ldap_servers'] = YAML.load <<-EOS # remember to close this block with 'EOS' below
-##
-## 'main' is the GitLab 'provider ID' of this LDAP server
-##
-main:
- ##
- ## A human-friendly name for your LDAP server. It is OK to change the label later,
- ## for instance if you find out it is too large to fit on the web page.
- ##
- ## Example: 'Paris' or 'Acme, Ltd.'
- ##
- label: 'LDAP'
-
- ##
- ## Example: 'ldap.mydomain.com'
- ##
- host: '_your_ldap_server'
-
- ##
- ## This port is an example, it is sometimes different but it is always an
- ## integer and not a string.
- ##
- port: 389 # usually 636 for SSL
- uid: 'sAMAccountName' # This should be the attribute, not the value that maps to uid.
-
- ##
- ## Examples: 'america\momo' or 'CN=Gitlab Git,CN=Users,DC=mydomain,DC=com'
- ##
- bind_dn: '_the_full_dn_of_the_user_you_will_bind_with'
- password: '_the_password_of_the_bind_user'
-
- ##
- ## Encryption method. The "method" key is deprecated in favor of
- ## "encryption".
- ##
- ## Examples: "start_tls" or "simple_tls" or "plain"
- ##
- ## Deprecated values: "tls" was replaced with "start_tls" and "ssl" was
- ## replaced with "simple_tls".
- ##
- ##
- encryption: 'plain'
-
- ##
- ## Enables SSL certificate verification if encryption method is
- ## "start_tls" or "simple_tls". Defaults to true since GitLab 10.0 for
- ## security. This may break installations upon upgrade to 10.0, that did
- ## not know their LDAP SSL certificates were not set up properly.
- ##
- verify_certificates: true
-
- # OpenSSL::SSL::SSLContext options.
- tls_options:
- # Specifies the path to a file containing a PEM-format CA certificate,
- # e.g. if you need to use an internal CA.
- #
- # Example: '/etc/ca.pem'
- #
- ca_file: ''
-
- # Specifies the SSL version for OpenSSL to use, if the OpenSSL default
- # is not appropriate.
- #
- # Example: 'TLSv1_1'
- #
- ssl_version: ''
-
- # Specific SSL ciphers to use in communication with LDAP servers.
- #
- # Example: 'ALL:!EXPORT:!LOW:!aNULL:!eNULL:!SSLv2'
- ciphers: ''
-
- # Client certificate
- #
- # Example:
- # cert: |
- # -----BEGIN CERTIFICATE-----
- # MIIDbDCCAlSgAwIBAgIGAWkJxLmKMA0GCSqGSIb3DQEBCwUAMHcxFDASBgNVBAoTC0dvb2dsZSBJ
- # bmMuMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQDEwtMREFQIENsaWVudDEPMA0GA1UE
- # CxMGR1N1aXRlMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTAeFw0xOTAyMjAwNzE4
- # rntnF4d+0dd7zP3jrWkbdtoqjLDT/5D7NYRmVCD5vizV98FJ5//PIHbD1gL3a9b2MPAc6k7NV8tl
- # ...
- # 4SbuJPAiJxC1LQ0t39dR6oMCAMab3hXQqhL56LrR6cRBp6Mtlphv7alu9xb/x51y2x+g2zWtsf80
- # Jrv/vKMsIh/sAyuogb7hqMtp55ecnKxceg==
- # -----END CERTIFICATE -----
- cert: ''
-
- # Client private key
- # key: |
- # -----BEGIN PRIVATE KEY-----
- # MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC3DmJtLRmJGY4xU1QtI3yjvxO6
- # bNuyE4z1NF6Xn7VSbcAaQtavWQ6GZi5uukMo+W5DHVtEkgDwh92ySZMuJdJogFbNvJvHAayheCdN
- # 7mCQ2UUT9jGXIbmksUn9QMeJVXTZjgJWJzPXToeUdinx9G7+lpVa62UATEd1gaI3oyL72WmpDy/C
- # rntnF4d+0dd7zP3jrWkbdtoqjLDT/5D7NYRmVCD5vizV98FJ5//PIHbD1gL3a9b2MPAc6k7NV8tl
- # ...
- # +9IhSYX+XIg7BZOVDeYqlPfxRvQh8vy3qjt/KUihmEPioAjLaGiihs1Fk5ctLk9A2hIUyP+sEQv9
- # l6RG+a/mW+0rCWn8JAd464Ps9hE=
- # -----END PRIVATE KEY-----
- key: ''
-
- ##
- ## 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.
- ##
- timeout: 10
-
- ##
- ## 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.
- ##
- active_directory: true
-
- ##
- ## If allow_username_or_email_login is enabled, GitLab will ignore everything
- ## after the first '@' in the LDAP username submitted by the user on login.
- ##
- ## Example:
- ## - the user enters 'jane.doe@example.com' and 'p@ssw0rd' as LDAP credentials;
- ## - GitLab queries the LDAP server with 'jane.doe' and 'p@ssw0rd'.
- ##
- ## If you are using "uid: 'userPrincipalName'" on ActiveDirectory you need to
- ## disable this setting, because the userPrincipalName contains an '@'.
- ##
- allow_username_or_email_login: false
-
- ##
- ## To maintain tight control over the number of active users on your GitLab installation,
- ## enable this setting to keep new users blocked until they have been cleared by the admin
- ## (default: false).
- ##
- block_auto_created_users: false
-
- ##
- ## Base where we can search for users
- ##
- ## Ex. 'ou=People,dc=gitlab,dc=example' or 'DC=mydomain,DC=com'
- ##
- ##
- base: ''
-
- ##
- ## Filter LDAP users
- ##
- ## Format: RFC 4515 https://tools.ietf.org/search/rfc4515
- ## Ex. (employeeType=developer)
- ##
- ## Note: GitLab does not support omniauth-ldap's custom filter syntax.
- ##
- ## Example for getting only specific users:
- ## '(&(objectclass=user)(|(samaccountname=momo)(samaccountname=toto)))'
- ##
- user_filter: ''
-
- ##
- ## LDAP attributes that GitLab will use to create an account for the LDAP user.
- ## The specified attribute can either be the attribute name as a string (e.g. 'mail'),
- ## or an array of attribute names to try in order (e.g. ['mail', 'email']).
- ## Note that the user's LDAP login will always be the attribute specified as `uid` above.
- ##
- attributes:
- ##
- ## The username will be used in paths for the user's own projects
- ## (like `gitlab.example.com/username/project`) and when mentioning
- ## them in issues, merge request and comments (like `@username`).
- ## If the attribute specified for `username` contains an email address,
- ## the GitLab username will be the part of the email address before the '@'.
- ##
- username: ['uid', 'userid', 'sAMAccountName']
- email: ['mail', 'email', 'userPrincipalName']
-
- ##
- ## If no full name could be found at the attribute specified for `name`,
- ## the full name is determined using the attributes specified for
- ## `first_name` and `last_name`.
- ##
- name: 'cn'
- first_name: 'givenName'
- last_name: 'sn'
-
- ##
- ## If lowercase_usernames is enabled, GitLab will lower case the username.
- ##
- lowercase_usernames: false
-
- ##
- ## EE only
- ##
-
- ## Base where we can search for groups
- ##
- ## Ex. ou=groups,dc=gitlab,dc=example
- ##
- group_base: ''
-
- ## The CN of a group containing GitLab administrators
- ##
- ## Ex. administrators
- ##
- ## Note: Not `cn=administrators` or the full DN
- ##
- admin_group: ''
-
- ## An array of CNs of groups containing users that should be considered external
- ##
- ## Ex. ['interns', 'contractors']
- ##
- ## Note: Not `cn=interns` or the full DN
- ##
- external_groups: []
-
- ##
- ## The LDAP attribute containing a user's public SSH key
- ##
- ## Example: sshPublicKey
- ##
- sync_ssh_keys: false
-
-## GitLab EE only: add more LDAP servers
-## Choose an ID made of a-z and 0-9 . This ID will be stored in the database
-## so that GitLab can remember which LDAP server a user belongs to.
-#uswest2:
-# label:
-# host:
-# ....
-EOS
-```
-
-**Source configuration**
-
-Use the same format as `gitlab_rails['ldap_servers']` for the contents under
-`servers:` in the example below:
-
-```yaml
-production:
- # snip...
- ldap:
- enabled: false
- prevent_ldap_sign_in: false
- servers:
- ##
- ## 'main' is the GitLab 'provider ID' of this LDAP server
- ##
- main:
- ##
- ## A human-friendly name for your LDAP server. It is OK to change the label later,
- ## for instance if you find out it is too large to fit on the web page.
- ##
- ## Example: 'Paris' or 'Acme, Ltd.'
- label: 'LDAP'
- ## snip...
-```
-
-## Using an LDAP filter to limit access to your GitLab server
-
-If you want to limit all GitLab access to a subset of the LDAP users on your
-LDAP server, the first step should be to narrow the configured `base`. However,
-it is sometimes necessary to filter users further. In this case, you can set up
-an LDAP user filter. The filter must comply with
-[RFC 4515](https://tools.ietf.org/search/rfc4515).
-
-**Omnibus configuration**
-
-```ruby
-gitlab_rails['ldap_servers'] = YAML.load <<-EOS
-main:
- # snip...
- user_filter: '(employeeType=developer)'
-EOS
-```
-
-**Source configuration**
-
-```yaml
-production:
- ldap:
- servers:
- main:
- # snip...
- user_filter: '(employeeType=developer)'
-```
-
-Tip: If you want to limit access to the nested members of an Active Directory
-group, you can use the following syntax:
-
-```plaintext
-(memberOf:1.2.840.113556.1.4.1941:=CN=My Group,DC=Example,DC=com)
-```
-
-Find more information about this "LDAP_MATCHING_RULE_IN_CHAIN" filter at
-<https://docs.microsoft.com/en-us/windows/win32/adsi/search-filter-syntax>. Support for
-nested members in the user filter should not be confused with
-[group sync nested groups support](ldap-ee.md#supported-ldap-group-typesattributes). **(STARTER ONLY)**
-
-Please note that GitLab does not support the custom filter syntax used by
-OmniAuth LDAP.
-
-### Escaping special characters
-
-The `user_filter` DN can contain special characters. For example:
-
-- A comma:
-
- ```plaintext
- OU=GitLab, Inc,DC=gitlab,DC=com
- ```
-
-- Open and close brackets:
-
- ```plaintext
- OU=Gitlab (Inc),DC=gitlab,DC=com
- ```
-
- These characters must be escaped as documented in
- [RFC 4515](https://tools.ietf.org/search/rfc4515).
-
-- Escape commas with `\2C`. For example:
-
- ```plaintext
- OU=GitLab\2C Inc,DC=gitlab,DC=com
- ```
-
-- Escape open and close brackets with `\28` and `\29`, respectively. For example:
-
- ```plaintext
- OU=Gitlab \28Inc\29,DC=gitlab,DC=com
- ```
-
-## Enabling 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, then
-the LDAP DN will be associated with the existing user. If the LDAP email
-attribute is not found in GitLab's database, a new user is created.
-
-In other words, if an existing GitLab user wants to enable LDAP sign-in for
-themselves, they should check that their GitLab email address matches their
-LDAP email address, and then sign into GitLab via their LDAP credentials.
-
-## Enabling 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.
-
-GitLab can automatically lowercase usernames provided by the LDAP server by enabling
-the configuration option `lowercase_usernames`. By default, this configuration option is `false`.
-
-**Omnibus configuration**
-
-1. Edit `/etc/gitlab/gitlab.rb`:
-
- ```ruby
- gitlab_rails['ldap_servers'] = YAML.load <<-EOS
- main:
- # snip...
- lowercase_usernames: true
- EOS
- ```
-
-1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
-
-**Source configuration**
-
-1. Edit `config/gitlab.yaml`:
-
- ```yaml
- production:
- ldap:
- servers:
- main:
- # snip...
- lowercase_usernames: true
- ```
-
-1. [Restart GitLab](../restart_gitlab.md#installations-from-source) for the changes to take effect.
-
-## Disable LDAP web sign in
-
-It can be useful to prevent using LDAP credentials through the web UI when
-an alternative such as SAML is preferred. This allows LDAP to be used for group
-sync, while also allowing your SAML identity provider to handle additional
-checks like custom 2FA.
-
-When LDAP web sign in is disabled, users will not see a **LDAP** tab on the sign in page.
-This does not disable [using LDAP credentials for Git access](#git-password-authentication).
-
-**Omnibus configuration**
-
-1. Edit `/etc/gitlab/gitlab.rb`:
-
- ```ruby
- gitlab_rails['prevent_ldap_sign_in'] = true
- ```
-
-1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
-
-**Source configuration**
-
-1. Edit `config/gitlab.yaml`:
-
- ```yaml
- production:
- ldap:
- prevent_ldap_sign_in: true
- ```
-
-1. [Restart GitLab](../restart_gitlab.md#installations-from-source) for the changes to take effect.
-
-## Encryption
-
-### TLS Server Authentication
-
-There are two encryption methods, `simple_tls` and `start_tls`.
-
-For either encryption method, if setting `verify_certificates: false`, TLS
-encryption is established with the LDAP server before any LDAP-protocol data is
-exchanged but no validation of the LDAP server's SSL certificate is performed.
-
->**Note**: Before GitLab 9.5, `verify_certificates: false` is the default if
-unspecified.
-
-## Limitations
-
-### TLS Client Authentication
-
-Not implemented by `Net::LDAP`.
-You should disable anonymous LDAP authentication and enable simple or SASL
-authentication. The TLS client authentication setting in your LDAP server cannot
-be mandatory and clients cannot be authenticated with the TLS protocol.
-
-## Troubleshooting
-
-Please see our [administrator guide to troubleshooting LDAP](ldap-troubleshooting.md).
+This document was moved to [another location](ldap/index.md).
diff --git a/doc/administration/auth/ldap/google_secure_ldap.md b/doc/administration/auth/ldap/google_secure_ldap.md
new file mode 100644
index 00000000000..2271ce93b6f
--- /dev/null
+++ b/doc/administration/auth/ldap/google_secure_ldap.md
@@ -0,0 +1,222 @@
+---
+type: reference
+stage: Manage
+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
+---
+
+# Google Secure LDAP **(CORE ONLY)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/46391) in GitLab 11.9.
+
+[Google Cloud Identity](https://cloud.google.com/identity/) provides a Secure
+LDAP service that can be configured with GitLab for authentication and group sync.
+
+Secure LDAP requires a slightly different configuration than standard LDAP servers.
+The steps below cover:
+
+- Configuring the Secure LDAP Client in the Google Admin console.
+- Required GitLab configuration.
+
+## Configuring Google LDAP client
+
+1. Navigate to <https://admin.google.com/Dashboard> and sign in as a GSuite domain administrator.
+
+1. Go to **Apps > LDAP > Add Client**.
+
+1. Provide an `LDAP client name` and an optional `Description`. Any descriptive
+ values are acceptable. For example, the name could be 'GitLab' and the
+ description could be 'GitLab LDAP Client'. Click the **Continue** button.
+
+ ![Add LDAP Client Step 1](img/google_secure_ldap_add_step_1.png)
+
+1. Set **Access Permission** according to your needs. You must choose either
+ 'Entire domain (GitLab)' or 'Selected organizational units' for both 'Verify user
+ credentials' and 'Read user information'. Select 'Add LDAP Client'
+
+ TIP: **Tip:** If you plan to use GitLab [LDAP Group Sync](index.md#group-sync-starter-only)
+ , turn on 'Read group information'.
+
+ ![Add LDAP Client Step 2](img/google_secure_ldap_add_step_2.png)
+
+1. Download the generated certificate. This is required for GitLab to
+ communicate with the Google Secure LDAP service. Save the downloaded certificates
+ for later use. After downloading, click the **Continue to Client Details** button.
+
+1. Expand the **Service Status** section and turn the LDAP client 'ON for everyone'.
+ After selecting 'Save', click on the 'Service Status' bar again to collapse
+ and return to the rest of the settings.
+
+1. Expand the **Authentication** section and choose 'Generate New Credentials'.
+ Copy/note these credentials for later use. After selecting 'Close', click
+ on the 'Authentication' bar again to collapse and return to the rest of the settings.
+
+Now the Google Secure LDAP Client configuration is finished. The screenshot below
+shows an example of the final settings. Continue on to configure GitLab.
+
+![LDAP Client Settings](img/google_secure_ldap_client_settings.png)
+
+## Configuring GitLab
+
+Edit GitLab configuration, inserting the access credentials and certificate
+obtained earlier.
+
+The following are the configuration keys that need to be modified using the
+values obtained during the LDAP client configuration earlier:
+
+- `bind_dn`: The access credentials username
+- `password`: The access credentials password
+- `cert`: The `.crt` file text from the downloaded certificate bundle
+- `key`: The `.key` file text from the downloaded certificate bundle
+
+**For Omnibus installations**
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['ldap_enabled'] = true
+ gitlab_rails['ldap_servers'] = YAML.load <<-EOS # remember to close this block with 'EOS' below
+ main: # 'main' is the GitLab 'provider ID' of this LDAP server
+ label: 'Google Secure LDAP'
+
+ host: 'ldap.google.com'
+ port: 636
+ uid: 'uid'
+ bind_dn: 'DizzyHorse'
+ password: 'd6V5H8nhMUW9AuDP25abXeLd'
+ encryption: 'simple_tls'
+ verify_certificates: true
+
+ tls_options:
+ cert: |
+ -----BEGIN CERTIFICATE-----
+ MIIDbDCCAlSgAwIBAgIGAWlzxiIfMA0GCSqGSIb3DQEBCwUAMHcxFDASBgNVBAoTC0dvb2dsZSBJ
+ bmMuMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQDEwtMREFQIENsaWVudDEPMA0GA1UE
+ CxMGR1N1aXRlMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTAeFw0xOTAzMTIyMTE5
+ MThaFw0yMjAzMTEyMTE5MThaMHcxFDASBgNVBAoTC0dvb2dsZSBJbmMuMRYwFAYDVQQHEw1Nb3Vu
+ dGFpbiBWaWV3MRQwEgYDVQQDEwtMREFQIENsaWVudDEPMA0GA1UECxMGR1N1aXRlMQswCQYDVQQG
+ EwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+ ALOTy4aC38dyjESk6N8fRsKk8DN23ZX/GaNFL5OUmmA1KWzrvVC881OzNdtGm3vNOIxr9clteEG/
+ tQwsmsJvQT5U+GkBt+tGKF/zm7zueHUYqTP7Pg5pxAnAei90qkIRFi17ulObyRHPYv1BbCt8pxNB
+ 4fG/gAXkFbCNxwh1eiQXXRTfruasCZ4/mHfX7MVm8JmWU9uAVIOLW+DSWOFhrDQduJdGBXJOyC2r
+ Gqoeg9+tkBmNH/jjxpnEkFW8q7io9DdOUqqNgoidA1h9vpKTs3084sy2DOgUvKN9uXWx14uxIyYU
+ Y1DnDy0wczcsuRt7l+EgtCEgpsLiLJQbKW+JS1UCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAf60J
+ yazhbHkDKIH2gFxfm7QLhhnqsmafvl4WP7JqZt0u0KdnvbDPfokdkM87yfbKJU1MTI86M36wEC+1
+ P6bzklKz7kXbzAD4GggksAzxsEE64OWHC+Y64Tkxq2NiZTw/76POkcg9StiIXjG0ZcebHub9+Ux/
+ rTncip92nDuvgEM7lbPFKRIS/YMhLCk09B/U0F6XLsf1yYjyf5miUTDikPkov23b/YGfpc8kh6hq
+ 1kqdi6a1cYPP34eAhtRhMqcZU9qezpJF6s9EeN/3YFfKzLODFSsVToBRAdZgGHzj//SAtLyQTD4n
+ KCSvK1UmaMxNaZyTHg8JnMf0ZuRpv26iSg==
+ -----END CERTIFICATE-----
+
+ key: |
+ -----BEGIN PRIVATE KEY-----
+ MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCzk8uGgt/HcoxEpOjfH0bCpPAz
+ dt2V/xmjRS+TlJpgNSls671QvPNTszXbRpt7zTiMa/XJbXhBv7UMLJrCb0E+VPhpAbfrRihf85u8
+ 7nh1GKkz+z4OacQJwHovdKpCERYte7pTm8kRz2L9QWwrfKcTQeHxv4AF5BWwjccIdXokF10U367m
+ rAmeP5h31+zFZvCZllPbgFSDi1vg0ljhYaw0HbiXRgVyTsgtqxqqHoPfrZAZjR/448aZxJBVvKu4
+ qPQ3TlKqjYKInQNYfb6Sk7N9POLMtgzoFLyjfbl1sdeLsSMmFGNQ5w8tMHM3LLkbe5fhILQhIKbC
+ 4iyUGylviUtVAgMBAAECggEAIPb0CQy0RJoX+q/lGbRVmnyJpYDf+115WNnl+mrwjdGkeZyqw4v0
+ BPzkWYzUFP1esJRO6buBNFybQRFdFW0z5lvVv/zzRKq71aVUBPInxaMRyHuJ8D5lIL8nDtgVOwyE
+ 7DOGyDtURUMzMjdUwoTe7K+O6QBU4X/1pVPZYgmissYSMmt68LiP8k0p601F4+r5xOi/QEy44aVp
+ aOJZBUOisKB8BmUXZqmQ4Cy05vU9Xi1rLyzkn9s7fxnZ+JO6Sd1r0Thm1mE0yuPgxkDBh/b4f3/2
+ GsQNKKKCiij/6TfkjnBi8ZvWR44LnKpu760g/K7psVNrKwqJG6C/8RAcgISWQQKBgQDop7BaKGhK
+ 1QMJJ/vnlyYFTucfGLn6bM//pzTys5Gop0tpcfX/Hf6a6Dd+zBhmC3tBmhr80XOX/PiyAIbc0lOI
+ 31rafZuD/oVx5mlIySWX35EqS14LXmdVs/5vOhsInNgNiE+EPFf1L9YZgG/zA7OUBmqtTeYIPDVC
+ 7ViJcydItQKBgQDFmK0H0IA6W4opGQo+zQKhefooqZ+RDk9IIZMPOAtnvOM7y3rSVrfsSjzYVuMS
+ w/RP/vs7rwhaZejnCZ8/7uIqwg4sdUBRzZYR3PRNFeheW+BPZvb+2keRCGzOs7xkbF1mu54qtYTa
+ HZGZj1OsD83AoMwVLcdLDgO1kw32dkS8IQKBgFRdgoifAHqqVah7VFB9se7Y1tyi5cXWsXI+Wufr
+ j9U9nQ4GojK52LqpnH4hWnOelDqMvF6TQTyLIk/B+yWWK26Ft/dk9wDdSdystd8L+dLh4k0Y+Whb
+ +lLMq2YABw+PeJUnqdYE38xsZVHoDjBsVjFGRmbDybeQxauYT7PACy3FAoGBAK2+k9bdNQMbXp7I
+ j8OszHVkJdz/WXlY1cmdDAxDwXOUGVKIlxTAf7TbiijILZ5gg0Cb+hj+zR9/oI0WXtr+mAv02jWp
+ W8cSOLS4TnBBpTLjIpdu+BwbnvYeLF6MmEjNKEufCXKQbaLEgTQ/XNlchBSuzwSIXkbWqdhM1+gx
+ EjtBAoGARAdMIiDMPWIIZg3nNnFebbmtBP0qiBsYohQZ+6i/8s/vautEHBEN6Q0brIU/goo+nTHc
+ t9VaOkzjCmAJSLPUanuBC8pdYgLu5J20NXUZLD9AE/2bBT3OpezKcdYeI2jqoc1qlWHlNtVtdqQ2
+ AcZSFJQjdg5BTyvdEDhaYUKGdRw=
+ -----END PRIVATE KEY-----
+ EOS
+ ```
+
+1. Save the file and [reconfigure](../../restart_gitlab.md#omnibus-gitlab-reconfigure) GitLab for the changes to take effect.
+
+---
+
+**For installations from source**
+
+1. Edit `config/gitlab.yml`:
+
+ ```yaml
+ ldap:
+ enabled: true
+ servers:
+ main: # 'main' is the GitLab 'provider ID' of this LDAP server
+ label: 'Google Secure LDAP'
+
+ host: 'ldap.google.com'
+ port: 636
+ uid: 'uid'
+ bind_dn: 'DizzyHorse'
+ password: 'd6V5H8nhMUW9AuDP25abXeLd'
+ encryption: 'simple_tls'
+ verify_certificates: true
+
+ tls_options:
+ cert: |
+ -----BEGIN CERTIFICATE-----
+ MIIDbDCCAlSgAwIBAgIGAWlzxiIfMA0GCSqGSIb3DQEBCwUAMHcxFDASBgNVBAoTC0dvb2dsZSBJ
+ bmMuMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQDEwtMREFQIENsaWVudDEPMA0GA1UE
+ CxMGR1N1aXRlMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTAeFw0xOTAzMTIyMTE5
+ MThaFw0yMjAzMTEyMTE5MThaMHcxFDASBgNVBAoTC0dvb2dsZSBJbmMuMRYwFAYDVQQHEw1Nb3Vu
+ dGFpbiBWaWV3MRQwEgYDVQQDEwtMREFQIENsaWVudDEPMA0GA1UECxMGR1N1aXRlMQswCQYDVQQG
+ EwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+ ALOTy4aC38dyjESk6N8fRsKk8DN23ZX/GaNFL5OUmmA1KWzrvVC881OzNdtGm3vNOIxr9clteEG/
+ tQwsmsJvQT5U+GkBt+tGKF/zm7zueHUYqTP7Pg5pxAnAei90qkIRFi17ulObyRHPYv1BbCt8pxNB
+ 4fG/gAXkFbCNxwh1eiQXXRTfruasCZ4/mHfX7MVm8JmWU9uAVIOLW+DSWOFhrDQduJdGBXJOyC2r
+ Gqoeg9+tkBmNH/jjxpnEkFW8q7io9DdOUqqNgoidA1h9vpKTs3084sy2DOgUvKN9uXWx14uxIyYU
+ Y1DnDy0wczcsuRt7l+EgtCEgpsLiLJQbKW+JS1UCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAf60J
+ yazhbHkDKIH2gFxfm7QLhhnqsmafvl4WP7JqZt0u0KdnvbDPfokdkM87yfbKJU1MTI86M36wEC+1
+ P6bzklKz7kXbzAD4GggksAzxsEE64OWHC+Y64Tkxq2NiZTw/76POkcg9StiIXjG0ZcebHub9+Ux/
+ rTncip92nDuvgEM7lbPFKRIS/YMhLCk09B/U0F6XLsf1yYjyf5miUTDikPkov23b/YGfpc8kh6hq
+ 1kqdi6a1cYPP34eAhtRhMqcZU9qezpJF6s9EeN/3YFfKzLODFSsVToBRAdZgGHzj//SAtLyQTD4n
+ KCSvK1UmaMxNaZyTHg8JnMf0ZuRpv26iSg==
+ -----END CERTIFICATE-----
+
+ key: |
+ -----BEGIN PRIVATE KEY-----
+ MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCzk8uGgt/HcoxEpOjfH0bCpPAz
+ dt2V/xmjRS+TlJpgNSls671QvPNTszXbRpt7zTiMa/XJbXhBv7UMLJrCb0E+VPhpAbfrRihf85u8
+ 7nh1GKkz+z4OacQJwHovdKpCERYte7pTm8kRz2L9QWwrfKcTQeHxv4AF5BWwjccIdXokF10U367m
+ rAmeP5h31+zFZvCZllPbgFSDi1vg0ljhYaw0HbiXRgVyTsgtqxqqHoPfrZAZjR/448aZxJBVvKu4
+ qPQ3TlKqjYKInQNYfb6Sk7N9POLMtgzoFLyjfbl1sdeLsSMmFGNQ5w8tMHM3LLkbe5fhILQhIKbC
+ 4iyUGylviUtVAgMBAAECggEAIPb0CQy0RJoX+q/lGbRVmnyJpYDf+115WNnl+mrwjdGkeZyqw4v0
+ BPzkWYzUFP1esJRO6buBNFybQRFdFW0z5lvVv/zzRKq71aVUBPInxaMRyHuJ8D5lIL8nDtgVOwyE
+ 7DOGyDtURUMzMjdUwoTe7K+O6QBU4X/1pVPZYgmissYSMmt68LiP8k0p601F4+r5xOi/QEy44aVp
+ aOJZBUOisKB8BmUXZqmQ4Cy05vU9Xi1rLyzkn9s7fxnZ+JO6Sd1r0Thm1mE0yuPgxkDBh/b4f3/2
+ GsQNKKKCiij/6TfkjnBi8ZvWR44LnKpu760g/K7psVNrKwqJG6C/8RAcgISWQQKBgQDop7BaKGhK
+ 1QMJJ/vnlyYFTucfGLn6bM//pzTys5Gop0tpcfX/Hf6a6Dd+zBhmC3tBmhr80XOX/PiyAIbc0lOI
+ 31rafZuD/oVx5mlIySWX35EqS14LXmdVs/5vOhsInNgNiE+EPFf1L9YZgG/zA7OUBmqtTeYIPDVC
+ 7ViJcydItQKBgQDFmK0H0IA6W4opGQo+zQKhefooqZ+RDk9IIZMPOAtnvOM7y3rSVrfsSjzYVuMS
+ w/RP/vs7rwhaZejnCZ8/7uIqwg4sdUBRzZYR3PRNFeheW+BPZvb+2keRCGzOs7xkbF1mu54qtYTa
+ HZGZj1OsD83AoMwVLcdLDgO1kw32dkS8IQKBgFRdgoifAHqqVah7VFB9se7Y1tyi5cXWsXI+Wufr
+ j9U9nQ4GojK52LqpnH4hWnOelDqMvF6TQTyLIk/B+yWWK26Ft/dk9wDdSdystd8L+dLh4k0Y+Whb
+ +lLMq2YABw+PeJUnqdYE38xsZVHoDjBsVjFGRmbDybeQxauYT7PACy3FAoGBAK2+k9bdNQMbXp7I
+ j8OszHVkJdz/WXlY1cmdDAxDwXOUGVKIlxTAf7TbiijILZ5gg0Cb+hj+zR9/oI0WXtr+mAv02jWp
+ W8cSOLS4TnBBpTLjIpdu+BwbnvYeLF6MmEjNKEufCXKQbaLEgTQ/XNlchBSuzwSIXkbWqdhM1+gx
+ EjtBAoGARAdMIiDMPWIIZg3nNnFebbmtBP0qiBsYohQZ+6i/8s/vautEHBEN6Q0brIU/goo+nTHc
+ t9VaOkzjCmAJSLPUanuBC8pdYgLu5J20NXUZLD9AE/2bBT3OpezKcdYeI2jqoc1qlWHlNtVtdqQ2
+ AcZSFJQjdg5BTyvdEDhaYUKGdRw=
+ -----END PRIVATE KEY-----
+ ```
+
+1. Save the file and [restart](../../restart_gitlab.md#installations-from-source) GitLab for the changes to take effect.
+
+<!-- ## 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/auth/img/google_secure_ldap_add_step_1.png b/doc/administration/auth/ldap/img/google_secure_ldap_add_step_1.png
index bee9c602a14..bee9c602a14 100644
--- a/doc/administration/auth/img/google_secure_ldap_add_step_1.png
+++ b/doc/administration/auth/ldap/img/google_secure_ldap_add_step_1.png
Binary files differ
diff --git a/doc/administration/auth/img/google_secure_ldap_add_step_2.png b/doc/administration/auth/ldap/img/google_secure_ldap_add_step_2.png
index b127410cb8c..b127410cb8c 100644
--- a/doc/administration/auth/img/google_secure_ldap_add_step_2.png
+++ b/doc/administration/auth/ldap/img/google_secure_ldap_add_step_2.png
Binary files differ
diff --git a/doc/administration/auth/img/google_secure_ldap_client_settings.png b/doc/administration/auth/ldap/img/google_secure_ldap_client_settings.png
index 868e6645f56..868e6645f56 100644
--- a/doc/administration/auth/img/google_secure_ldap_client_settings.png
+++ b/doc/administration/auth/ldap/img/google_secure_ldap_client_settings.png
Binary files differ
diff --git a/doc/administration/auth/ldap/img/multi_login.gif b/doc/administration/auth/ldap/img/multi_login.gif
new file mode 100644
index 00000000000..5aee6090793
--- /dev/null
+++ b/doc/administration/auth/ldap/img/multi_login.gif
Binary files differ
diff --git a/doc/administration/auth/ldap/index.md b/doc/administration/auth/ldap/index.md
new file mode 100644
index 00000000000..4a7a972596f
--- /dev/null
+++ b/doc/administration/auth/ldap/index.md
@@ -0,0 +1,756 @@
+---
+type: reference
+stage: Manage
+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
+---
+
+# General LDAP Setup
+
+GitLab integrates with LDAP to support user authentication.
+
+This integration works with most LDAP-compliant directory servers, including:
+
+- Microsoft Active Directory
+- Apple Open Directory
+- Open LDAP
+- 389 Server
+
+GitLab Enterprise Editions (EE) include enhanced integration,
+including group membership syncing as well as multiple LDAP servers support.
+
+NOTE: **Note:**
+[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.
+
+## Overview
+
+[LDAP](https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol)
+stands for **Lightweight Directory Access Protocol**, which is a standard
+application protocol for accessing and maintaining distributed directory
+information services over an Internet Protocol (IP) network.
+
+## Security **(CORE ONLY)**
+
+GitLab assumes that LDAP users:
+
+- Are not able to change their LDAP `mail`, `email`, or `userPrincipalName` attributes.
+ An LDAP user who is allowed to change their email on the LDAP server can potentially
+ [take over any account](#enabling-ldap-sign-in-for-existing-gitlab-users-core-only)
+ on your GitLab server.
+- Have unique email addresses, otherwise it is possible for LDAP users with the same
+ email address to share the same GitLab account.
+
+We recommend against using LDAP integration if your LDAP users are
+allowed to change their 'mail', 'email' or 'userPrincipalName' attribute on
+the LDAP server or share email addresses.
+
+### User deletion **(CORE ONLY)**
+
+If a user is deleted from the LDAP server, they will be blocked in GitLab as
+well. Users will be immediately blocked from logging in. However, there is an
+LDAP check cache time of one hour (see note) which means users that
+are already logged in or are using Git over SSH will still be able to access
+GitLab for up to one hour. Manually block the user in the GitLab Admin Area to
+immediately block all access.
+
+NOTE: **Note**:
+GitLab Enterprise Edition Starter supports a
+[configurable sync time](#adjusting-ldap-user-sync-schedule-starter-only).
+
+## Git password authentication **(CORE ONLY)**
+
+LDAP-enabled users can always 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 **(CORE ONLY)**
+
+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, then
+the LDAP DN will be associated with the existing user. If the LDAP email
+attribute is not found in GitLab's database, a new user is created.
+
+In other words, if an existing GitLab user wants to enable LDAP sign-in for
+themselves, they should check that their GitLab email address matches their
+LDAP email address, and then sign into GitLab via their LDAP credentials.
+
+## Google Secure LDAP **(CORE ONLY)**
+
+> Introduced in GitLab 11.9.
+
+[Google Cloud Identity](https://cloud.google.com/identity/) provides a Secure
+LDAP service that can be configured with GitLab for authentication and group sync.
+See [Google Secure LDAP](google_secure_ldap.md) for detailed configuration instructions.
+
+## Configuration **(CORE ONLY)**
+
+To enable LDAP integration you need to 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.
+
+There is a Rake task to check LDAP configuration. After configuring LDAP
+using the documentation below, see [LDAP check Rake task](../../raketasks/check.md#ldap-check)
+for information on the LDAP check Rake task.
+
+NOTE: **Note:**
+The `encryption` value `simple_tls` corresponds to 'Simple TLS' in the LDAP
+library. `start_tls` corresponds to StartTLS, not to be confused with regular TLS.
+Normally, if you specify `simple_tls` it will be on port 636, while `start_tls` (StartTLS)
+would be on port 389. `plain` also operates on port 389. Removed values: `tls` was replaced with `start_tls` and `ssl` was replaced with `simple_tls`.
+
+NOTE: **Note:**
+LDAP users must have an email address set, regardless of whether it is used to log in.
+
+### Example Configurations **(CORE ONLY)**
+
+**Omnibus Configuration**
+
+```ruby
+gitlab_rails['ldap_enabled'] = true
+gitlab_rails['prevent_ldap_sign_in'] = false
+gitlab_rails['ldap_servers'] = {
+'main' => {
+ 'label' => 'LDAP',
+ 'host' => 'ldap.mydomain.com',
+ 'port' => 389,
+ 'uid' => 'sAMAccountName',
+ 'encryption' => 'simple_tls',
+ 'verify_certificates' => true,
+ 'bind_dn' => '_the_full_dn_of_the_user_you_will_bind_with',
+ 'password' => '_the_password_of_the_bind_user',
+ 'encryption' => 'plain',
+ 'verify_certificates' => true,
+ 'tls_options' => {
+ 'ca_file' => '',
+ 'ssl_version' => '',
+ 'ciphers' => '',
+ 'cert' => '',
+ 'key' => ''
+ },
+ 'timeout' => 10,
+ 'active_directory' => true,
+ 'allow_username_or_email_login' => false,
+ 'block_auto_created_users' => false,
+ 'base' => 'dc=example,dc=com',
+ 'user_filter' => '',
+ 'attributes' => {
+ 'username' => ['uid', 'userid', 'sAMAccountName'],
+ 'email' => ['mail', 'email', 'userPrincipalName'],
+ 'name' => 'cn',
+ 'first_name' => 'givenName',
+ 'last_name' => 'sn'
+ },
+ 'lowercase_usernames' => false,
+
+ # EE Only
+ 'group_base' => '',
+ 'admin_group' => '',
+ 'external_groups' => [],
+ 'sync_ssh_keys' => false
+ }
+}
+```
+
+**Source Configuration**
+
+```yaml
+production:
+ # snip...
+ ldap:
+ enabled: false
+ prevent_ldap_sign_in: false
+ servers:
+ main:
+ label: 'LDAP'
+ ...
+```
+
+### Basic Configuration Settings **(CORE ONLY)**
+
+| Setting | Description | Required | Examples |
+| ------- | ----------- | -------- | -------- |
+| `label` | A human-friendly name for your LDAP server. It will be displayed on your login page. | yes | `'Paris'` or `'Acme, Ltd.'` |
+| `host` | IP address or domain name of your LDAP server. | yes | `'ldap.mydomain.com'` |
+| `port` | The port to connect with on your LDAP server. Always an integer, not a string. | yes | `389` or `636` (for SSL) |
+| `uid` | LDAP attribute for username. Should be the attribute, not the value that maps to the `uid`. | yes | `'sAMAccountName'`, `'uid'`, `'userPrincipalName'` |
+| `bind_dn` | The full DN of the user you will bind with. | no | `'america\momo'` or `'CN=Gitlab,OU=Users,DC=domain,DC=com'` |
+| `password` | The password of the bind user. | no | `'your_great_password'` |
+| `encryption` | Encryption method. The `method` key is deprecated in favor of `encryption`. | yes | `'start_tls'` or `'simple_tls'` or `'plain'` |
+| `verify_certificates` | Enables SSL certificate verification if encryption method is `start_tls` or `simple_tls`. Defaults to true. | 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. | 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. | no | boolean |
+| `allow_username_or_email_login` | If enabled, GitLab will ignore everything after the first `@` in the LDAP username submitted by the user on login. If you are using `uid: 'userPrincipalName'` on ActiveDirectory you need to disable this setting, because the userPrincipalName contains an `@`. | no | boolean |
+| `block_auto_created_users` | To maintain tight control over the number of active users on your GitLab installation, enable this setting to keep new users blocked until they have been cleared by the admin (default: false). | no | boolean |
+| `base` | Base where we can search for users. | 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. | no | `'(employeeType=developer)'` or `'(&(objectclass=user)(|(samaccountname=momo)(samaccountname=toto)))'` |
+| `lowercase_usernames` | If lowercase_usernames is enabled, GitLab will lower case the username. | no | boolean |
+
+### SSL Configuration Settings **(CORE ONLY)**
+
+| Setting | Description | Required | Examples |
+| ------- | ----------- | -------- | -------- |
+| `ca_file` | Specifies the path to a file containing a PEM-format CA certificate, e.g. if you need to use an internal CA. | no | `'/etc/ca.pem'` |
+| `ssl_version` | Specifies the SSL version for OpenSSL to use, if the OpenSSL default is not appropriate. | no | `'TLSv1_1'` |
+| `ciphers` | Specific SSL ciphers to use in communication with LDAP servers. | no | `'ALL:!EXPORT:!LOW:!aNULL:!eNULL:!SSLv2'` |
+| `cert` | Client certificate | no | `'-----BEGIN CERTIFICATE----- <REDACTED> -----END CERTIFICATE -----'` |
+| `key` | Client private key | no | `'-----BEGIN PRIVATE KEY----- <REDACTED> -----END PRIVATE KEY -----'` |
+
+### Attribute Configuration Settings **(CORE ONLY)**
+
+LDAP attributes that GitLab will use to create an account for the LDAP user. The specified attribute can either be the attribute name as a string (e.g. `'mail'`), or an array of attribute names to try in order (e.g. `['mail', 'email']`). Note that the user's LDAP login will always be the attribute specified as `uid` above.
+
+| Setting | Description | Required | Examples |
+| ------- | ----------- | -------- | -------- |
+| `username` | The username will be used in paths for the user's own projects (like `gitlab.example.com/username/project`) and when mentioning them in issues, merge request and comments (like `@username`). If the attribute specified for `username` contains an email address, the GitLab username will be the part of the email address before the `@`. | no | `['uid', 'userid', 'sAMAccountName']` |
+| `email` | LDAP attribute for user email. | no | `['mail', 'email', 'userPrincipalName']` |
+| `name` | LDAP attribute for user display name. If no full name could be found at the attribute specified for `name`, the full name is determined using the attributes specified for `first_name` and `last_name`. | no | `'cn'` or `'displayName'` |
+| `first_name` | LDAP attribute for user first name. | no | `'givenName'` |
+| `last_name` | LDAP attribute for user last name. | no | `'sn'` |
+
+### LDAP Sync Configuration Settings **(STARTER ONLY)**
+
+| Setting | Description | Required | Examples |
+| ------- | ----------- | -------- | -------- |
+| `group_base` | Base used to search for groups. | no | `'ou=groups,dc=gitlab,dc=example'` |
+| `admin_group` | The CN of a group containing GitLab administrators. Note: Not `cn=administrators` or the full DN. | no | `'administrators'` |
+| `external_groups` | An array of CNs of groups containing users that should be considered external. Note: Not `cn=interns` or the full DN. | no | `['interns', 'contractors']` |
+| `sync_ssh_keys` | The LDAP attribute containing a user's public SSH key. | no | `'sshPublicKey'` or false if not set |
+
+### Set up LDAP user filter **(CORE ONLY)**
+
+If you want to limit all GitLab access to a subset of the LDAP users on your
+LDAP server, the first step should be to narrow the configured `base`. However,
+it is sometimes necessary to filter users further. In this case, you can set up
+an LDAP user filter. The filter must comply with
+[RFC 4515](https://tools.ietf.org/search/rfc4515).
+
+**Omnibus configuration**
+
+```ruby
+gitlab_rails['ldap_servers'] = {
+'main' => {
+ # snip...
+ 'user_filter' => '(employeeType=developer)'
+ }
+}
+```
+
+**Source configuration**
+
+```yaml
+production:
+ ldap:
+ servers:
+ main:
+ # snip...
+ user_filter: '(employeeType=developer)'
+```
+
+If you want to limit access to the nested members of an Active Directory
+group, you can use the following syntax:
+
+```plaintext
+(memberOf:1.2.840.113556.1.4.1941:=CN=My Group,DC=Example,DC=com)
+```
+
+For more information about this "LDAP_MATCHING_RULE_IN_CHAIN" filter, see the following
+[Microsoft Search Filter Syntax](https://docs.microsoft.com/en-us/windows/win32/adsi/search-filter-syntax) document.
+Support for nested members in the user filter should not be confused with
+[group sync nested groups support](#supported-ldap-group-typesattributes). **(STARTER ONLY)**
+
+Please note that GitLab does not support the custom filter syntax used by
+OmniAuth LDAP.
+
+#### Escaping special characters **(CORE ONLY)**
+
+The `user_filter` DN can contain special characters. For example:
+
+- A comma:
+
+ ```plaintext
+ OU=GitLab, Inc,DC=gitlab,DC=com
+ ```
+
+- Open and close brackets:
+
+ ```plaintext
+ OU=Gitlab (Inc),DC=gitlab,DC=com
+ ```
+
+ These characters must be escaped as documented in
+ [RFC 4515](https://tools.ietf.org/search/rfc4515).
+
+- Escape commas with `\2C`. For example:
+
+ ```plaintext
+ OU=GitLab\2C Inc,DC=gitlab,DC=com
+ ```
+
+- Escape open and close brackets with `\28` and `\29`, respectively. For example:
+
+ ```plaintext
+ OU=Gitlab \28Inc\29,DC=gitlab,DC=com
+ ```
+
+### Enabling LDAP username lowercase **(CORE ONLY)**
+
+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.
+
+GitLab can automatically lowercase usernames provided by the LDAP server by enabling
+the configuration option `lowercase_usernames`. By default, this configuration option is `false`.
+
+**Omnibus configuration**
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['ldap_servers'] = {
+ 'main' => {
+ # snip...
+ 'lowercase_usernames' => true
+ }
+ }
+ ```
+
+1. [Reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+
+**Source configuration**
+
+1. Edit `config/gitlab.yaml`:
+
+ ```yaml
+ production:
+ ldap:
+ servers:
+ main:
+ # snip...
+ lowercase_usernames: true
+ ```
+
+1. [Restart GitLab](../../restart_gitlab.md#installations-from-source) for the changes to take effect.
+
+### Disable LDAP web sign in **(CORE ONLY)**
+
+It can be useful to prevent using LDAP credentials through the web UI when
+an alternative such as SAML is preferred. This allows LDAP to be used for group
+sync, while also allowing your SAML identity provider to handle additional
+checks like custom 2FA.
+
+When LDAP web sign in is disabled, users will not see a **LDAP** tab on the sign in page.
+This does not disable [using LDAP credentials for Git access](#git-password-authentication-core-only).
+
+**Omnibus configuration**
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['prevent_ldap_sign_in'] = true
+ ```
+
+1. [Reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+
+**Source configuration**
+
+1. Edit `config/gitlab.yaml`:
+
+ ```yaml
+ production:
+ ldap:
+ prevent_ldap_sign_in: true
+ ```
+
+1. [Restart GitLab](../../restart_gitlab.md#installations-from-source) for the changes to take effect.
+
+## Encryption **(CORE ONLY)**
+
+### TLS Server Authentication
+
+There are two encryption methods, `simple_tls` and `start_tls`.
+
+For either encryption method, if setting `verify_certificates: false`, TLS
+encryption is established with the LDAP server before any LDAP-protocol data is
+exchanged but no validation of the LDAP server's SSL certificate is performed.
+
+### Limitations
+
+#### TLS Client Authentication
+
+Not implemented by `Net::LDAP`.
+
+You should disable anonymous LDAP authentication and enable simple or SASL
+authentication. The TLS client authentication setting in your LDAP server cannot
+be mandatory and clients cannot be authenticated with the TLS protocol.
+
+## Multiple LDAP servers **(STARTER ONLY)**
+
+With GitLab Enterprise Edition Starter, you can configure multiple LDAP servers
+that your GitLab instance will connect to.
+
+To add another LDAP server:
+
+1. Duplicate the settings under [the main configuration](#configuration-core-only).
+1. Edit them to match the additional LDAP server.
+
+Be sure to choose a different provider ID made of letters a-z and numbers 0-9.
+This ID will be stored in the database so that GitLab can remember which LDAP
+server a user belongs to.
+
+![Multiple LDAP Servers Login](img/multi_login.gif)
+
+Based on the example illustrated on the image above,
+our `gitlab.rb` configuration would look like:
+
+```ruby
+gitlab_rails['ldap_enabled'] = true
+gitlab_rails['ldap_servers'] = {
+'main' => {
+ 'label' => 'GitLab AD',
+ 'host' => 'ad.example.org',
+ 'port' => 636,
+ ...
+ },
+
+'secondary' => {
+ 'label' => 'GitLab Secondary AD',
+ 'host' => 'ad-secondary.example.net',
+ 'port' => 636,
+ ...
+ },
+
+'tertiary' => {
+ 'label' => 'GitLab Tertiary AD',
+ 'host' => 'ad-tertiary.example.net',
+ 'port' => 636,
+ ...
+ }
+
+}
+```
+
+NOTE: **Note:**
+Any number of LDAP servers can be configured. However, make sure to use a unique naming convention for the `label` section of each entry as this will be the display name of the tab shown on the sign-in page.
+
+## User sync **(STARTER ONLY)**
+
+Once per day, GitLab runs a worker to check and update GitLab
+users against LDAP.
+
+The process executes the following access checks:
+
+- Ensure the user is still present in LDAP.
+- If the LDAP server is Active Directory, ensure the user is active (not
+ blocked/disabled state). This will only be checked if
+ `active_directory: true` is set in the LDAP configuration.
+
+NOTE: **Note:**
+In Active Directory, a user is marked as disabled/blocked if the user
+account control attribute (`userAccountControl:1.2.840.113556.1.4.803`)
+has bit 2 set. See <https://ctovswild.com/2009/09/03/bitmask-searches-in-ldap/>
+for more information.
+
+The user will be set to `ldap_blocked` state in GitLab if the above conditions
+fail. This means the user will not be able to login or push/pull code.
+
+The process will also update the following user information:
+
+- Email address.
+- If `sync_ssh_keys` is set, SSH public keys.
+- If Kerberos is enabled, Kerberos identity.
+
+NOTE: **Note:**
+The LDAP sync process updates existing users while new users are created on first sign in.
+
+### Adjusting LDAP user sync schedule **(STARTER ONLY)**
+
+NOTE: **Note:**
+These are cron formatted values. You can use a crontab generator to create
+these values, for example <http://www.crontabgenerator.com/>.
+
+By default, GitLab will run a worker once per day at 01:30 a.m. server time to
+check and update GitLab users against LDAP.
+
+You can manually configure LDAP user sync times by setting the
+following configuration values. The example below shows how to set LDAP user
+sync to run once every 12 hours at the top of the hour.
+
+**Omnibus installations**
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['ldap_sync_worker_cron'] = "0 */12 * * *"
+ ```
+
+1. [Reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+
+**Source installations**
+
+1. Edit `config/gitlab.yaml`:
+
+ ```yaml
+ cron_jobs:
+ ldap_sync_worker_cron:
+ "0 */12 * * *"
+ ```
+
+1. [Restart GitLab](../../restart_gitlab.md#installations-from-source) for the changes to take effect.
+
+## Group Sync **(STARTER ONLY)**
+
+If your LDAP supports the `memberof` property, when the user signs in for the
+first time GitLab will trigger 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
+access to their groups and projects.
+
+A group sync process will run every hour on the hour, and `group_base` must be set
+in LDAP configuration for LDAP synchronizations based on group CN to work. This allows
+GitLab group membership to be automatically updated based on LDAP group members.
+
+The `group_base` configuration should be a base LDAP 'container', such as an
+'organization' or 'organizational unit', that contains LDAP groups that should
+be available to GitLab. For example, `group_base` could be
+`ou=groups,dc=example,dc=com`. In the config file it will look like the
+following.
+
+**Omnibus configuration**
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['ldap_servers'] = {
+ 'main' => {
+ # snip...
+ 'group_base' => 'ou=groups,dc=example,dc=com',
+ }
+ }
+ ```
+
+1. [Apply your changes to GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure).
+
+**Source configuration**
+
+1. Edit `/home/git/gitlab/config/gitlab.yml`:
+
+ ```yaml
+ production:
+ ldap:
+ servers:
+ main:
+ # snip...
+ group_base: ou=groups,dc=example,dc=com
+ ```
+
+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 will need to [create one
+or more LDAP group links](#adding-group-links-starter-only).
+
+### Adding group links **(STARTER ONLY)**
+
+For information on adding group links via CNs and filters, refer to [the GitLab groups documentation](../../../user/group/index.md#manage-group-memberships-via-ldap).
+
+### Administrator sync **(STARTER ONLY)**
+
+As an extension of group sync, you can automatically manage your global GitLab
+administrators. Specify a group CN for `admin_group` and all members of the
+LDAP group will be given administrator privileges. The configuration will look
+like the following.
+
+NOTE: **Note:**
+Administrators will not be synced unless `group_base` is also
+specified alongside `admin_group`. Also, only specify the CN of the admin
+group, as opposed to the full DN.
+
+**Omnibus configuration**
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['ldap_servers'] = {
+ 'main' => {
+ # snip...
+ 'group_base' => 'ou=groups,dc=example,dc=com',
+ 'admin_group' => 'my_admin_group',
+ }
+ }
+ ```
+
+1. [Apply your changes to GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure).
+
+**Source configuration**
+
+1. Edit `/home/git/gitlab/config/gitlab.yml`:
+
+ ```yaml
+ production:
+ ldap:
+ servers:
+ main:
+ # snip...
+ group_base: ou=groups,dc=example,dc=com
+ admin_group: my_admin_group
+ ```
+
+1. [Restart GitLab](../../restart_gitlab.md#installations-from-source) for the changes to take effect.
+
+### Global group memberships lock **(STARTER ONLY)**
+
+"Lock memberships to LDAP synchronization" setting allows instance administrators
+to lock down user abilities to invite new members to a group.
+
+When enabled, the following applies:
+
+- Only administrator can manage memberships of any group including access levels.
+- Users are not allowed to share project with other groups or invite members to
+ a project created in a group.
+
+### Adjusting LDAP group sync schedule **(STARTER ONLY)**
+
+NOTE: **Note:**
+These are cron formatted values. You can use a crontab generator to create
+these values, for example [Crontab Generator](http://www.crontabgenerator.com/).
+
+By default, GitLab runs a group sync process every hour, on the hour.
+
+CAUTION: **Important:**
+It's recommended that you do not start the sync process too frequently as this
+could lead to multiple syncs running concurrently. This is primarily a concern
+for installations with a large number of LDAP users. Please review the
+[LDAP group sync benchmark metrics](#benchmarks) to see how
+your installation compares before proceeding.
+
+You can manually configure LDAP group sync times by setting the
+following configuration values. The example below shows how to set group
+sync to run once every 2 hours at the top of the hour.
+
+**Omnibus installations**
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['ldap_group_sync_worker_cron'] = "0 */2 * * * *"
+ ```
+
+1. [Reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+
+**Source installations**
+
+1. Edit `config/gitlab.yaml`:
+
+ ```yaml
+ cron_jobs:
+ ldap_group_sync_worker_cron:
+ "*/30 * * * *"
+ ```
+
+1. [Restart GitLab](../../restart_gitlab.md#installations-from-source) for the changes to take effect.
+
+### External groups **(STARTER ONLY)**
+
+Using the `external_groups` setting will allow you to mark all users belonging
+to these groups as [external users](../../../user/permissions.md#external-users-core-only).
+Group membership is checked periodically through the `LdapGroupSync` background
+task.
+
+**Omnibus configuration**
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['ldap_servers'] = {
+ 'main' => {
+ # snip...
+ 'external_groups' => ['interns', 'contractors'],
+ }
+ }
+ ```
+
+1. [Apply your changes to GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure).
+
+**Source configuration**
+
+1. Edit `config/gitlab.yaml`:
+
+ ```yaml
+ production:
+ ldap:
+ servers:
+ main:
+ # snip...
+ external_groups: ['interns', 'contractors']
+ ```
+
+1. [Restart GitLab](../../restart_gitlab.md#installations-from-source) for the changes to take effect.
+
+### Group sync technical details
+
+There is a lot going on with group sync 'under the hood'. This section
+outlines what LDAP queries are executed and what behavior you can expect
+from group sync.
+
+Group member access will be downgraded from a higher level if their LDAP group
+membership changes. For example, if a user has 'Owner' rights in a group and the
+next group sync reveals they should only have 'Developer' privileges, their
+access will be adjusted accordingly. The only exception is if the user is the
+*last* owner in a group. Groups need at least one owner to fulfill
+administrative duties.
+
+#### Supported LDAP group types/attributes
+
+GitLab supports LDAP groups that use member attributes:
+
+- `member`
+- `submember`
+- `uniquemember`
+- `memberof`
+- `memberuid`.
+
+This means group sync supports, at least, LDAP groups with the following object classes:
+`groupOfNames`, `posixGroup`, and `groupOfUniqueNames`.
+
+Other object classes should work fine as long as members
+are defined as one of the mentioned attributes. This also means GitLab supports
+Microsoft Active Directory, Apple Open Directory, Open LDAP, and 389 Server.
+Other LDAP servers should work, too.
+
+Active Directory also supports nested groups. Group sync will recursively
+resolve membership if `active_directory: true` is set in the configuration file.
+
+NOTE: **Note:**
+Nested group memberships are resolved only if the nested group
+is found within the configured `group_base`. For example, if GitLab sees a
+nested group with DN `cn=nested_group,ou=special_groups,dc=example,dc=com` but
+the configured `group_base` is `ou=groups,dc=example,dc=com`, `cn=nested_group`
+is ignored.
+
+#### Queries
+
+- Each LDAP group is queried a maximum of one time with base `group_base` and
+ filter `(cn=<cn_from_group_link>)`.
+- If the LDAP group has the `memberuid` attribute, GitLab will execute another
+ LDAP query per member to obtain each user's full DN. These queries are
+ executed with base `base`, scope 'base object', and a filter depending on
+ whether `user_filter` is set. Filter may be `(uid=<uid_from_group>)` or a
+ joining of `user_filter`.
+
+#### Benchmarks
+
+Group sync was written to be as performant as possible. Data is cached, database
+queries are optimized, and LDAP queries are minimized. The last benchmark run
+revealed the following metrics:
+
+For 20000 LDAP users, 11000 LDAP groups and 1000 GitLab groups with 10
+LDAP group links each:
+
+- Initial sync (no existing members assigned in GitLab) took 1.8 hours
+- Subsequent syncs (checking membership, no writes) took 15 minutes
+
+These metrics are meant to provide a baseline and performance may vary based on
+any number of factors. This was a pretty extreme benchmark and most instances will
+not have near this many users or groups. Disk speed, database performance,
+network and LDAP server response time will affect these metrics.
+
+## Troubleshooting
+
+Please see our [administrator guide to troubleshooting LDAP](ldap-troubleshooting.md).
diff --git a/doc/administration/auth/ldap/ldap-troubleshooting.md b/doc/administration/auth/ldap/ldap-troubleshooting.md
new file mode 100644
index 00000000000..909802b5dec
--- /dev/null
+++ b/doc/administration/auth/ldap/ldap-troubleshooting.md
@@ -0,0 +1,678 @@
+---
+type: reference
+stage: Manage
+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
+---
+
+# LDAP Troubleshooting for Administrators
+
+## Common Problems & Workflows
+
+### Connection
+
+#### Connection refused
+
+If you are getting `Connection Refused` errors when trying to connect to the
+LDAP server please double-check the LDAP `port` and `encryption` settings used by
+GitLab. Common combinations are `encryption: 'plain'` and `port: 389`, OR
+`encryption: 'simple_tls'` and `port: 636`.
+
+#### Connection times out
+
+If GitLab cannot reach your LDAP endpoint, you will see a message like this:
+
+```plaintext
+Could not authenticate you from Ldapmain because "Connection timed out - user specified timeout".
+```
+
+If your configured LDAP provider and/or endpoint is offline or otherwise
+unreachable by GitLab, no LDAP user will be able to authenticate and log in.
+GitLab does not cache or store credentials for LDAP users to provide authentication
+during an LDAP outage.
+
+Contact your LDAP provider or administrator if you are seeing this error.
+
+#### Referral error
+
+If you see `LDAP search error: Referral` in the logs, or when troubleshooting
+LDAP Group Sync, this error may indicate a configuration problem. The LDAP
+configuration `/etc/gitlab/gitlab.rb` (Omnibus) or `config/gitlab.yml` (source)
+is in YAML format and is sensitive to indentation. Check that `group_base` and
+`admin_group` configuration keys are indented 2 spaces past the server
+identifier. The default identifier is `main` and an example snippet looks like
+the following:
+
+```yaml
+main: # 'main' is the GitLab 'provider ID' of this LDAP server
+ label: 'LDAP'
+ host: 'ldap.example.com'
+ ...
+ group_base: 'cn=my_group,ou=groups,dc=example,dc=com'
+ admin_group: 'my_admin_group'
+```
+
+#### Query LDAP **(STARTER ONLY)**
+
+The following allows you to perform a search in LDAP using the rails console.
+Depending on what you're trying to do, it may make more sense to query [a
+user](#query-a-user-in-ldap) or [a group](#query-a-group-in-ldap-starter-only) directly, or
+even [use `ldapsearch`](#ldapsearch) instead.
+
+```ruby
+adapter = Gitlab::Auth::Ldap::Adapter.new('ldapmain')
+options = {
+ # :base is required
+ # use .base or .group_base
+ base: adapter.config.group_base,
+
+ # :filter is optional
+ # 'cn' looks for all "cn"s under :base
+ # '*' is the search string - here, it's a wildcard
+ filter: Net::Ldap::Filter.eq('cn', '*'),
+
+ # :attributes is optional
+ # the attributes we want to get returned
+ attributes: %w(dn cn memberuid member submember uniquemember memberof)
+}
+adapter.ldap_search(options)
+```
+
+For examples of how this is run,
+[review the `Adapter` module](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/lib/ee/gitlab/auth/ldap/adapter.rb).
+
+### User logins
+
+#### No users are found
+
+If [you've confirmed](#ldap-check) that a connection to LDAP can be
+established but GitLab doesn't show you LDAP users in the output, one of the
+following is most likely true:
+
+- The `bind_dn` user doesn't have enough permissions to traverse the user tree.
+- The user(s) don't fall under the [configured `base`](index.md#configuration-core-only).
+- The [configured `user_filter`](index.md#set-up-ldap-user-filter-core-only) blocks access to the user(s).
+
+In this case, you con confirm which of the above is true using
+[ldapsearch](#ldapsearch) with the existing LDAP configuration in your
+`/etc/gitlab/gitlab.rb`.
+
+#### User(s) cannot login
+
+A user can have trouble logging in for any number of reasons. To get started,
+here are some questions to ask yourself:
+
+- Does the user fall under the [configured `base`](index.md#configuration-core-only) in
+ LDAP? The user must fall under this `base` to login.
+- Does the user pass through the [configured `user_filter`](index.md#set-up-ldap-user-filter-core-only)?
+ If one is not configured, this question can be ignored. If it is, then the
+ user must also pass through this filter to be allowed to login.
+ - Refer to our docs on [debugging the `user_filter`](#debug-ldap-user-filter).
+
+If the above are both okay, the next place to look for the problem is
+the logs themselves while reproducing the issue.
+
+- Ask the user to login and let it fail.
+- [Look through the output](#gitlab-logs) for any errors or other
+ messages about the login. You may see one of the other error messages on
+ this page, in which case that section can help resolve the issue.
+
+If the logs don't lead to the root of the problem, use the
+[rails console](#rails-console) to [query this user](#query-a-user-in-ldap)
+to see if GitLab can read this user on the LDAP server.
+
+It can also be helpful to
+[debug a user sync](#sync-all-users-starter-only) to
+investigate further.
+
+#### Invalid credentials on login
+
+If that the login credentials used are accurate on LDAP, ensure the following
+are true for the user in question:
+
+- Make sure the user you are binding with has enough permissions to read the user's
+ tree and traverse it.
+- Check that the `user_filter` is not blocking otherwise valid users.
+- Run [an LDAP check command](#ldap-check) to make sure that the LDAP settings
+ are correct and [GitLab can see your users](#no-users-are-found).
+
+#### Email has already been taken
+
+A user tries to login with the correct LDAP credentials, is denied access,
+and the [production.log](../../logs.md#productionlog) shows an error that looks like this:
+
+```plaintext
+(LDAP) Error saving user <USER DN> (email@example.com): ["Email has already been taken"]
+```
+
+This error is referring to the email address in LDAP, `email@example.com`. Email
+addresses must be unique in GitLab and LDAP links to a user's primary email (as opposed
+to any of their possibly-numerous secondary emails). Another user (or even the
+same user) has the email `email@example.com` set as a secondary email, which
+is throwing this error.
+
+We can check where this conflicting email address is coming from using the
+[rails console](#rails-console). Once in the console, run the following:
+
+```ruby
+# This searches for an email among the primary AND secondary emails
+user = User.find_by_any_email('email@example.com')
+user.username
+```
+
+This will show you which user has this email address. One of two steps will
+have to be taken here:
+
+- To create a new GitLab user/username for this user when logging in with LDAP,
+ remove the secondary email to remove the conflict.
+- To use an existing GitLab user/username for this user to use with LDAP,
+ remove this email as a secondary email and make it a primary one so GitLab
+ will associate this profile to the LDAP identity.
+
+The user can do either of these steps [in their
+profile](../../../user/profile/index.md#user-profile) or an admin can do it.
+
+#### Debug LDAP user filter
+
+[`ldapsearch`](#ldapsearch) allows you to test your configured
+[user filter](index.md#set-up-ldap-user-filter-core-only)
+to confirm that it returns the users you expect it to return.
+
+```shell
+ldapsearch -H ldaps://$host:$port -D "$bind_dn" -y bind_dn_password.txt -b "$base" "$user_filter" sAMAccountName
+```
+
+- Variables beginning with a `$` refer to a variable from the LDAP section of
+ your configuration file.
+- Replace `ldaps://` with `ldap://` if you are using the plain authentication method.
+ Port `389` is the default `ldap://` port and `636` is the default `ldaps://`
+ port.
+- We are assuming the password for the `bind_dn` user is in `bind_dn_password.txt`.
+
+#### Sync all users **(STARTER ONLY)**
+
+The output from a manual [user sync](index.md#user-sync-starter-only) can show you what happens when
+GitLab tries to sync its users against LDAP. Enter the [rails console](#rails-console)
+and then run:
+
+```ruby
+Rails.logger.level = Logger::DEBUG
+
+LdapSyncWorker.new.perform
+```
+
+Next, [learn how to read the
+output](#example-console-output-after-a-user-sync-starter-only).
+
+##### Example console output after a user sync **(STARTER ONLY)**
+
+The output from a [manual user sync](#sync-all-users-starter-only) will be very verbose, and a
+single user's successful sync can look like this:
+
+```shell
+Syncing user John, email@example.com
+ Identity Load (0.9ms) SELECT "identities".* FROM "identities" WHERE "identities"."user_id" = 20 AND (provider LIKE 'ldap%') LIMIT 1
+Instantiating Gitlab::Auth::Ldap::Person with LDIF:
+dn: cn=John Smith,ou=people,dc=example,dc=com
+cn: John Smith
+mail: email@example.com
+memberof: cn=admin_staff,ou=people,dc=example,dc=com
+uid: John
+
+ UserSyncedAttributesMetadata Load (0.9ms) SELECT "user_synced_attributes_metadata".* FROM "user_synced_attributes_metadata" WHERE "user_synced_attributes_metadata"."user_id" = 20 LIMIT 1
+ (0.3ms) BEGIN
+ Namespace Load (1.0ms) SELECT "namespaces".* FROM "namespaces" WHERE "namespaces"."owner_id" = 20 AND "namespaces"."type" IS NULL LIMIT 1
+ Route Load (0.8ms) SELECT "routes".* FROM "routes" WHERE "routes"."source_id" = 27 AND "routes"."source_type" = 'Namespace' LIMIT 1
+ Ci::Runner Load (1.1ms) SELECT "ci_runners".* FROM "ci_runners" INNER JOIN "ci_runner_namespaces" ON "ci_runners"."id" = "ci_runner_namespaces"."runner_id" WHERE "ci_runner_namespaces"."namespace_id" = 27
+ (0.7ms) COMMIT
+ (0.4ms) BEGIN
+ Route Load (0.8ms) SELECT "routes".* FROM "routes" WHERE (LOWER("routes"."path") = LOWER('John'))
+ Namespace Load (1.0ms) SELECT "namespaces".* FROM "namespaces" WHERE "namespaces"."id" = 27 LIMIT 1
+ Route Exists (0.9ms) SELECT 1 AS one FROM "routes" WHERE LOWER("routes"."path") = LOWER('John') AND "routes"."id" != 50 LIMIT 1
+ User Update (1.1ms) UPDATE "users" SET "updated_at" = '2019-10-17 14:40:59.751685', "last_credential_check_at" = '2019-10-17 14:40:59.738714' WHERE "users"."id" = 20
+```
+
+There's a lot here, so let's go over what could be helpful when debugging.
+
+First, GitLab will look for all users that have previously
+logged in with LDAP and iterate on them. Each user's sync will start with
+the following line that contains the user's username and email, as they
+exist in GitLab now:
+
+```shell
+Syncing user John, email@example.com
+```
+
+If you don't find a particular user's GitLab email in the output, then that
+user hasn't logged in with LDAP yet.
+
+Next, GitLab searches its `identities` table for the existing
+link between this user and the configured LDAP provider(s):
+
+```sql
+ Identity Load (0.9ms) SELECT "identities".* FROM "identities" WHERE "identities"."user_id" = 20 AND (provider LIKE 'ldap%') LIMIT 1
+```
+
+The identity object will have the DN that GitLab will use to look for the user
+in LDAP. If the DN isn't found, the email is used instead. We can see that
+this user is found in LDAP:
+
+```shell
+Instantiating Gitlab::Auth::Ldap::Person with LDIF:
+dn: cn=John Smith,ou=people,dc=example,dc=com
+cn: John Smith
+mail: email@example.com
+memberof: cn=admin_staff,ou=people,dc=example,dc=com
+uid: John
+```
+
+If the user wasn't found in LDAP with either the DN or email, you may see the
+following message instead:
+
+```shell
+LDAP search error: No Such Object
+```
+
+...in which case the user will be blocked:
+
+```shell
+ User Update (0.4ms) UPDATE "users" SET "state" = $1, "updated_at" = $2 WHERE "users"."id" = $3 [["state", "ldap_blocked"], ["updated_at", "2019-10-18 15:46:22.902177"], ["id", 20]]
+```
+
+Once the user is found in LDAP the rest of the output will update the GitLab
+database with any changes.
+
+#### Query a user in LDAP
+
+This will test that GitLab can reach out to LDAP and read a particular user.
+It can expose potential errors connecting to and/or querying LDAP
+that may seem to fail silently in the GitLab UI.
+
+```ruby
+Rails.logger.level = Logger::DEBUG
+
+adapter = Gitlab::Auth::Ldap::Adapter.new('ldapmain') # If `main` is the LDAP provider
+Gitlab::Auth::Ldap::Person.find_by_uid('<uid>', adapter)
+```
+
+### Group memberships **(STARTER ONLY)**
+
+#### Membership(s) not granted **(STARTER ONLY)**
+
+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
+things to check to debug the situation.
+
+- Ensure LDAP configuration has a `group_base` specified.
+ [This configuration](index.md#group-sync-starter-only) 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-starter-only).
+- Check that the user has an LDAP identity:
+ 1. Sign in to GitLab as an administrator user.
+ 1. Navigate to **Admin area -> Users**.
+ 1. Search for the user
+ 1. Open the user, by clicking on their name. Do not click 'Edit'.
+ 1. Navigate to the **Identities** tab. There should be an LDAP identity with
+ an LDAP DN as the 'Identifier'. If not, this user hasn't logged 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-starter-only) for the group to
+ sync. To speed up the process, either go to the GitLab group **Settings ->
+ Members** and press **Sync now** (sync one group) or [run the group sync Rake
+ task](../../raketasks/ldap.md#run-a-group-sync-starter-only) (sync all groups).
+
+If all of the above looks good, jump in to a little more advanced debugging in
+the rails console.
+
+1. Enter the [rails console](#rails-console).
+1. Choose a GitLab group to test with. This group should have an LDAP group link
+ already configured.
+1. [Enable debug logging, find the above GitLab group, and sync it with LDAP](#sync-one-group-starter-only).
+1. Look through the output of the sync. See [example log
+ output](#example-console-output-after-a-group-sync-starter-only)
+ for how to read the output.
+1. If you still aren't able to see why the user isn't being added, [query the
+ LDAP group directly](#query-a-group-in-ldap-starter-only) to see what members are listed.
+1. Is the user's DN or UID in one of the lists from the above output? One of the DNs or
+ UIDs here should match the 'Identifier' from the LDAP identity checked earlier. If it doesn't,
+ the user does not appear to be in the LDAP group.
+
+#### Admin privileges not granted
+
+When [Administrator sync](index.md#administrator-sync-starter-only) has been configured
+but the configured users aren't granted the correct admin privileges, confirm
+the following are true:
+
+- A [`group_base` is also configured](index.md#group-sync-starter-only).
+- The configured `admin_group` in the `gitlab.rb` is a CN, rather than a DN or an array.
+- This CN falls under the scope of the configured `group_base`.
+- The members of the `admin_group` have already logged into GitLab with their LDAP
+ credentials. GitLab will only grant this admin access to the users whose
+ accounts are already connected to LDAP.
+
+If all the above are true and the users are still not getting access, [run a manual
+group sync](#sync-all-groups-starter-only) in the rails console and [look through the
+output](#example-console-output-after-a-group-sync-starter-only) to see what happens when
+GitLab syncs the `admin_group`.
+
+#### Sync all groups **(STARTER ONLY)**
+
+NOTE: **NOTE:**
+To sync all groups manually when debugging is unnecessary, [use the Rake
+task](../../raketasks/ldap.md#run-a-group-sync-starter-only) instead.
+
+The output from a manual [group sync](index.md#group-sync-starter-only) can show you what happens
+when GitLab syncs its LDAP group memberships against LDAP.
+
+```ruby
+Rails.logger.level = Logger::DEBUG
+
+LdapAllGroupsSyncWorker.new.perform
+```
+
+Next, [learn how to read the
+output](#example-console-output-after-a-group-sync-starter-only).
+
+##### Example console output after a group sync **(STARTER ONLY)**
+
+Like the output from the user sync, the output from the [manual group
+sync](#sync-all-groups-starter-only) will also be very verbose. However, it contains lots
+of helpful information.
+
+Indicates the point where syncing actually begins:
+
+```shell
+Started syncing 'ldapmain' provider for 'my_group' group
+```
+
+The following entry shows an array of all user DNs GitLab sees in the LDAP server.
+Note that these are the users for a single LDAP group, not a GitLab group. If
+you have multiple LDAP groups linked to this GitLab group, you will see multiple
+log entries like this - one for each LDAP group. If you don't see an LDAP user
+DN in this log entry, LDAP is not returning the user when we do the lookup.
+Verify the user is actually in the LDAP group.
+
+```shell
+Members in 'ldap_group_1' LDAP group: ["uid=john0,ou=people,dc=example,dc=com",
+"uid=mary0,ou=people,dc=example,dc=com", "uid=john1,ou=people,dc=example,dc=com",
+"uid=mary1,ou=people,dc=example,dc=com", "uid=john2,ou=people,dc=example,dc=com",
+"uid=mary2,ou=people,dc=example,dc=com", "uid=john3,ou=people,dc=example,dc=com",
+"uid=mary3,ou=people,dc=example,dc=com", "uid=john4,ou=people,dc=example,dc=com",
+"uid=mary4,ou=people,dc=example,dc=com"]
+```
+
+Shortly after each of the above entries, you will see a hash of resolved member
+access levels. This hash represents all user DNs GitLab thinks should have
+access to this group, and at which access level (role). This hash is additive,
+and more DNs may be added, or existing entries modified, based on additional
+LDAP group lookups. The very last occurrence of this entry should indicate
+exactly which users GitLab believes should be added to the group.
+
+NOTE: **Note:**
+10 is 'Guest', 20 is 'Reporter', 30 is 'Developer', 40 is 'Maintainer'
+and 50 is 'Owner'.
+
+```shell
+Resolved 'my_group' group member access: {"uid=john0,ou=people,dc=example,dc=com"=>30,
+"uid=mary0,ou=people,dc=example,dc=com"=>30, "uid=john1,ou=people,dc=example,dc=com"=>30,
+"uid=mary1,ou=people,dc=example,dc=com"=>30, "uid=john2,ou=people,dc=example,dc=com"=>30,
+"uid=mary2,ou=people,dc=example,dc=com"=>30, "uid=john3,ou=people,dc=example,dc=com"=>30,
+"uid=mary3,ou=people,dc=example,dc=com"=>30, "uid=john4,ou=people,dc=example,dc=com"=>30,
+"uid=mary4,ou=people,dc=example,dc=com"=>30}
+```
+
+It's not uncommon to see warnings like the following. These indicate that GitLab
+would have added the user to a group, but the user could not be found in GitLab.
+Usually this is not a cause for concern.
+
+If you think a particular user should already exist in GitLab, but you're seeing
+this entry, it could be due to a mismatched DN stored in GitLab. See
+[User DN and/or email have changed](#user-dn-orand-email-have-changed) to update the user's LDAP identity.
+
+```shell
+User with DN `uid=john0,ou=people,dc=example,dc=com` should have access
+to 'my_group' group but there is no user in GitLab with that
+identity. Membership will be updated once the user signs in for
+the first time.
+```
+
+Finally, the following entry says syncing has finished for this group:
+
+```shell
+Finished syncing all providers for 'my_group' group
+```
+
+Once all the configured group links have been synchronized, GitLab will look
+for any Administrators or External users to sync:
+
+```shell
+Syncing admin users for 'ldapmain' provider
+```
+
+The output will look similar to what happens with a single group, and then
+this line will indicate the sync is finished:
+
+```shell
+Finished syncing admin users for 'ldapmain' provider
+```
+
+If [admin sync](index.md#administrator-sync-starter-only) is not configured, you'll see a message
+stating as such:
+
+```shell
+No `admin_group` configured for 'ldapmain' provider. Skipping
+```
+
+#### Sync one group **(STARTER ONLY)**
+
+[Syncing all groups](#sync-all-groups-starter-only) can produce a lot of noise in the output, which can be
+distracting when you're only interested in troubleshooting the memberships of
+a single GitLab group. In that case, here's how you can just sync this group
+and see its debug output:
+
+```ruby
+Rails.logger.level = Logger::DEBUG
+
+# Find the GitLab group.
+# If the output is `nil`, the group could not be found.
+# If a bunch of group attributes are in the output, your group was found successfully.
+group = Group.find_by(name: 'my_gitlab_group')
+
+# Sync this group against LDAP
+EE::Gitlab::Auth::Ldap::Sync::Group.execute_all_providers(group)
+```
+
+The output will be similar to
+[that you'd get from syncing all groups](#example-console-output-after-a-group-sync-starter-only).
+
+#### Query a group in LDAP **(STARTER ONLY)**
+
+When you'd like to confirm that GitLab can read a LDAP group and see all its members,
+you can run the following:
+
+```ruby
+# Find the adapter and the group itself
+adapter = Gitlab::Auth::Ldap::Adapter.new('ldapmain') # If `main` is the LDAP provider
+ldap_group = EE::Gitlab::Auth::Ldap::Group.find_by_cn('group_cn_here', adapter)
+
+# Find the members of the LDAP group
+ldap_group.member_dns
+ldap_group.member_uids
+```
+
+### User DN or/and email have changed
+
+When an LDAP user is created in GitLab, their LDAP DN is stored for later reference.
+
+If GitLab cannot find a user by their DN, it will fall back
+to finding the user by their email. If the lookup is successful, GitLab will
+update the stored DN to the new value so both values will now match what's in
+LDAP.
+
+If the email has changed and the DN has not, GitLab will find the user with
+the DN and update its own record of the user's email to match the one in LDAP.
+
+However, if the primary email _and_ the DN change in LDAP, then GitLab will
+have no way of identifying the correct LDAP record of the user and, as a
+result, the user will be blocked. To rectify this, the user's existing
+profile will have to be updated with at least one of the new values (primary
+email or DN) so the LDAP record can be found.
+
+The following script will update the emails for all provided users so they
+won't be blocked or unable to access their accounts.
+
+>**NOTE**: The following script will require that any new accounts with the new
+email address are removed first. This is because emails have to be unique in GitLab.
+
+Go to the [rails console](#rails-console) and then run:
+
+```ruby
+# Each entry will have to include the old username and the new email
+emails = {
+ 'ORIGINAL_USERNAME' => 'NEW_EMAIL_ADDRESS',
+ ...
+}
+
+emails.each do |username, email|
+ user = User.find_by_username(username)
+ user.email = email
+ user.skip_reconfirmation!
+ user.save!
+end
+```
+
+You can then [run a UserSync](#sync-all-users-starter-only) **(STARTER ONLY)** to sync the latest DN
+for each of these users.
+
+## Debugging Tools
+
+### LDAP check
+
+The [Rake task to check LDAP](../../raketasks/ldap.md#check) is a valuable tool
+to help determine whether GitLab can successfully establish a connection to
+LDAP and can get so far as to even read users.
+
+If a connection can't be established, it is likely either because of a problem
+with your configuration or a firewall blocking the connection.
+
+- Ensure you don't have a firewall blocking the
+connection, and that the LDAP server is accessible to the GitLab host.
+- Look for an error message in the Rake check output, which may lead to your LDAP configuration to
+confirm that the configuration values (specifically `host`, `port`, `bind_dn`, and
+`password`) are correct.
+- Look for [errors](#connection) in [the logs](#gitlab-logs) to further debug connection failures.
+
+If GitLab can successfully connect to LDAP but doesn't return any
+users, [see what to do when no users are found](#no-users-are-found).
+
+### GitLab logs
+
+If a user account is blocked or unblocked due to the LDAP configuration, a
+message will be [logged to `application.log`](../../logs.md#applicationlog).
+
+If there is an unexpected error during an LDAP lookup (configuration error,
+timeout), the login is rejected and a message will be [logged to
+`production.log`](../../logs.md#productionlog).
+
+### ldapsearch
+
+`ldapsearch` is a utility that will allow you to query your LDAP server. You can
+use it to test your LDAP settings and ensure that the settings you're using
+will get you the results you expect.
+
+When using `ldapsearch`, be sure to use the same settings you've already
+specified in your `gitlab.rb` configuration so you can confirm what happens
+when those exact settings are used.
+
+Running this command on the GitLab host will also help confirm that there's no
+obstruction between the GitLab host and LDAP.
+
+For example, consider the following GitLab configuration:
+
+```shell
+gitlab_rails['ldap_servers'] = YAML.load <<-'EOS' # remember to close this block with 'EOS' below
+ main: # 'main' is the GitLab 'provider ID' of this LDAP server
+ label: 'LDAP'
+ host: '127.0.0.1'
+ port: 389
+ uid: 'uid'
+ encryption: 'plain'
+ bind_dn: 'cn=admin,dc=ldap-testing,dc=example,dc=com'
+ password: 'Password1'
+ active_directory: true
+ allow_username_or_email_login: false
+ block_auto_created_users: false
+ base: 'dc=ldap-testing,dc=example,dc=com'
+ user_filter: ''
+ attributes:
+ username: ['uid', 'userid', 'sAMAccountName']
+ email: ['mail', 'email', 'userPrincipalName']
+ name: 'cn'
+ first_name: 'givenName'
+ last_name: 'sn'
+ group_base: 'ou=groups,dc=ldap-testing,dc=example,dc=com'
+ admin_group: 'gitlab_admin'
+EOS
+```
+
+You would run the following `ldapsearch` to find the `bind_dn` user:
+
+```shell
+ldapsearch -D "cn=admin,dc=ldap-testing,dc=example,dc=com" \
+ -w Password1 \
+ -p 389 \
+ -h 127.0.0.1 \
+ -b "dc=ldap-testing,dc=example,dc=com"
+```
+
+Note that the `bind_dn`, `password`, `port`, `host`, and `base` are all
+identical to what's configured in the `gitlab.rb`.
+
+Please see [the official
+`ldapsearch` documentation](https://linux.die.net/man/1/ldapsearch) for more.
+
+### Using **AdFind** (Windows)
+
+You can use the [`AdFind`](https://social.technet.microsoft.com/wiki/contents/articles/7535.adfind-command-examples.aspx) utility (on Windows based systems) to test that your LDAP server is accessible and authentication is working correctly. This is a freeware utility built by [Joe Richards](http://www.joeware.net/freetools/tools/adfind/index.htm).
+
+**Return all objects**
+
+You can use the filter `objectclass=*` to return all directory objects.
+
+```shell
+adfind -h ad.example.org:636 -ssl -u "CN=GitLabSRV,CN=Users,DC=GitLab,DC=org" -up Password1 -b "OU=GitLab INT,DC=GitLab,DC=org" -f (objectClass=*)
+```
+
+**Return single object using filter**
+
+You can also retrieve a single object by **specifying** the object name or full **DN**. In this example we specify the object name only `CN=Leroy Fox`.
+
+```shell
+adfind -h ad.example.org:636 -ssl -u "CN=GitLabSRV,CN=Users,DC=GitLab,DC=org" -up Password1 -b "OU=GitLab INT,DC=GitLab,DC=org" -f (&(objectcategory=person)(CN=Leroy Fox))â€
+```
+
+### Rails console
+
+CAUTION: **CAUTION:**
+Please note that it is very easy to create, read, modify, and destroy data on the
+rails console, so please be sure to run commands exactly as listed.
+
+The rails console is a valuable tool to help debug LDAP problems. It allows you to
+directly interact with the application by running commands and seeing how GitLab
+responds to them.
+
+Please refer to [this guide](../../troubleshooting/debug.md#starting-a-rails-console-session)
+for instructions on how to use the rails console.
+
+#### Enable debug output
+
+This will provide debug output that will be useful to see
+what GitLab is doing and with what. This value is not persisted, and will only
+be enabled for this session in the rails console.
+
+To enable debug output in the rails console, [enter the rails
+console](#rails-console) and run:
+
+```ruby
+Rails.logger.level = Logger::DEBUG
+```
diff --git a/doc/administration/auth/oidc.md b/doc/administration/auth/oidc.md
index 7a808636e94..794733f860c 100644
--- a/doc/administration/auth/oidc.md
+++ b/doc/administration/auth/oidc.md
@@ -1,5 +1,8 @@
---
type: reference
+stage: Manage
+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
---
# OpenID Connect OmniAuth provider
@@ -96,8 +99,8 @@ The OpenID Connect will provide you with a client details and secret for you to
- `mtls` - Mutual TLS or X.509 certificate validation
- Any other value will POST the client ID and secret in the request body
- If not specified, defaults to `basic`.
- - `<uid_field>` (optional) is the field name from the `user_info` details that will be used as `uid` value. For example, `preferred_username`.
- If this value is not provided or the field with the configured value is missing from the `user_info` details, the `uid` will use the `sub` field.
+ - `<uid_field>` (optional) is the field name from the `user_info.raw_attributes` details that will be used as `uid` value. For example, `preferred_username`.
+ If this value is not provided or the field with the configured value is missing from the `user_info.raw_attributes` details, the `uid` will use the `sub` field.
- `send_scope_to_token_endpoint` is `true` by default. In other words, the `scope` parameter is normally included in requests to the token endpoint.
However, if your OpenID Connect provider does not accept the `scope` parameter in such requests, set this to `false`.
- `client_options` are the OpenID Connect client-specific options. Specifically:
diff --git a/doc/administration/auth/okta.md b/doc/administration/auth/okta.md
index 4fd37b51f24..f7ab60ab56b 100644
--- a/doc/administration/auth/okta.md
+++ b/doc/administration/auth/okta.md
@@ -1,5 +1,8 @@
---
type: reference
+stage: Manage
+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
---
# Okta SSO provider
@@ -17,7 +20,7 @@ The following documentation enables Okta as a SAML provider.
1. Now, very important, add a logo
(you can choose it from <https://about.gitlab.com/press/>). You'll have to
crop and resize it.
-1. Next, you'll need the to fill in the SAML general config. Here's an example
+1. Next, you'll need the to fill in the SAML general configuration. Here's an example
image.
![Okta admin panel view](img/okta_admin_panel.png)
@@ -25,14 +28,14 @@ The following documentation enables Okta as a SAML provider.
1. The last part of the configuration is the feedback section where you can
just say you're a customer and creating an app for internal use.
1. When you have your app you'll have a few tabs on the top of the app's
- profile. Click on the SAML 2.0 config instructions button which should
+ profile. Click on the SAML 2.0 configuration instructions button which should
look like the following:
![Okta SAML settings](img/okta_saml_settings.png)
1. On the screen that comes up take note of the
**Identity Provider Single Sign-On URL** which you'll use for the
- `idp_sso_target_url` on your GitLab config file.
+ `idp_sso_target_url` on your GitLab configuration file.
1. **Before you leave Okta make sure you add your user and groups if any.**
diff --git a/doc/administration/auth/smartcard.md b/doc/administration/auth/smartcard.md
index 7131fd7571f..9ad1e0641f6 100644
--- a/doc/administration/auth/smartcard.md
+++ b/doc/administration/auth/smartcard.md
@@ -8,7 +8,7 @@ GitLab supports authentication using smartcards.
## Existing password authentication
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/33669) in GitLab 12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/33669) in GitLab 12.6.
By default, existing users can continue to log in with a username and password when smartcard
authentication is enabled.
@@ -25,7 +25,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 Premium](https://about.gitlab.com/pricing/) 11.6 as an experimental feature.
CAUTION: **Caution:**
Smartcard authentication against local databases may change or be removed completely in future
@@ -52,7 +52,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 Premium](https://about.gitlab.com/pricing/) 12.3.
Smartcards with X.509 certificates using SAN extensions can be used to authenticate
with GitLab.
@@ -67,7 +67,7 @@ database with GitLab, in:
- GitLab 12.4 and later, at least one of the `subjectAltName` (SAN) extensions
need to define the user identity (`email`) within the GitLab instance (`URI`).
`URI`: needs to match `Gitlab.config.host.gitlab`.
-- From [GitLab 12.5](https://gitlab.com/gitlab-org/gitlab/issues/33907),
+- From [GitLab 12.5](https://gitlab.com/gitlab-org/gitlab/-/issues/33907),
if your certificate contains only **one** SAN email entry, you don't need to
add or modify it to match the `email` with the `URI`.
@@ -95,7 +95,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 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.
GitLab implements a standard way of certificate matching following
[RFC4523](https://tools.ietf.org/html/rfc4523). It uses the
@@ -159,7 +159,7 @@ attribute. As a prerequisite, you must use an LDAP server that:
```
For example, the following is an example server context in an NGINX
- configuration file (eg. in `/etc/nginx/sites-available/gitlab-ssl`):
+ configuration file (such as in `/etc/nginx/sites-available/gitlab-ssl`):
```plaintext
server {
diff --git a/doc/administration/compliance.md b/doc/administration/compliance.md
index 8cd10f5ea4e..47e4b6c068c 100644
--- a/doc/administration/compliance.md
+++ b/doc/administration/compliance.md
@@ -12,8 +12,8 @@ GitLab’s [security features](../security/README.md) may also help you meet rel
|**[Email all users of a project, group, or entire server](../user/admin_area/settings/terms.md)**<br>An admin can email groups of users based on project or group membership, or email everyone using the GitLab instance. This is great for scheduled maintenance or upgrades.|Starter+||
|**[Omnibus package supports log forwarding](https://docs.gitlab.com/omnibus/settings/logs.html#udp-log-forwarding)**<br>Forward your logs to a central system.|Starter+||
|**[Lock project membership to group](../user/group/index.md#member-lock-starter)**<br>Group owners can prevent new members from being added to projects within a group.|Starter+|✓|
-|**[LDAP group sync](auth/ldap-ee.md#group-sync)**<br>GitLab Enterprise Edition gives admins the ability to automatically sync groups and manage SSH keys, permissions, and authentication, so you can focus on building your product, not configuring your tools.|Starter+||
-|**[LDAP group sync filters](auth/ldap-ee.md#group-sync)**<br>GitLab Enterprise Edition Premium gives more flexibility to synchronize with LDAP based on filters, meaning you can leverage LDAP attributes to map GitLab permissions.|Premium+||
+|**[LDAP group sync](auth/ldap/index.md#group-sync-starter-only)**<br>GitLab Enterprise Edition gives admins the ability to automatically sync groups and manage SSH keys, permissions, and authentication, so you can focus on building your product, not configuring your tools.|Starter+||
+|**[LDAP group sync filters](auth/ldap/index.md#group-sync-starter-only)**<br>GitLab Enterprise Edition Premium gives more flexibility to synchronize with LDAP based on filters, meaning you can leverage LDAP attributes to map GitLab permissions.|Premium+||
|**[Audit logs](audit_events.md)**<br>To maintain the integrity of your code, GitLab Enterprise Edition Premium gives admins the ability to view any modifications made within the GitLab server in an advanced audit log system, so you can control, analyze, and track every change.|Premium+||
|**[Auditor users](auditor_users.md)**<br>Auditor users are users who are given read-only access to all projects, groups, and other resources on the GitLab instance.|Premium+||
|**[Credentials inventory](../user/admin_area/credentials_inventory.md)**<br>With a credentials inventory, GitLab administrators can keep track of the credentials used by all of the users in their GitLab instance. |Ultimate||
diff --git a/doc/administration/environment_variables.md b/doc/administration/environment_variables.md
index 37d7194af53..ecf9464eb91 100644
--- a/doc/administration/environment_variables.md
+++ b/doc/administration/environment_variables.md
@@ -1,3 +1,10 @@
+---
+stage: Verify
+group: Continuous Integration
+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
+---
+
# Environment Variables
GitLab exposes certain environment variables which can be used to override
@@ -63,6 +70,7 @@ to the naming scheme `GITLAB_#{name in 1_settings.rb in upper case}`.
To set environment variables, follow [these
instructions](https://docs.gitlab.com/omnibus/settings/environment-variables.html).
-It's possible to preconfigure the GitLab docker image by adding the environment
+It's possible to preconfigure the GitLab Docker image by adding the environment
variable `GITLAB_OMNIBUS_CONFIG` to the `docker run` command.
-For more information see the ['preconfigure-docker-container' section in the Omnibus documentation](https://docs.gitlab.com/omnibus/docker/#preconfigure-docker-container).
+For more information see the [Pre-configure Docker container](https://docs.gitlab.com/omnibus/docker/#pre-configure-docker-container)
+section in the Omnibus documentation.
diff --git a/doc/administration/external_database.md b/doc/administration/external_database.md
index 47509828c20..7424b4e1e83 100644
--- a/doc/administration/external_database.md
+++ b/doc/administration/external_database.md
@@ -1,41 +1,7 @@
-# Configure GitLab using an external PostgreSQL service
-
-If you're hosting GitLab on a cloud provider, you can optionally use a
-managed service for PostgreSQL. For example, AWS offers a managed Relational
-Database Service (RDS) that runs PostgreSQL.
-
-Alternatively, you may opt to manage your own PostgreSQL instance or cluster
-separate from the Omnibus GitLab package.
-
-If you use a cloud-managed service, or provide your own PostgreSQL instance:
-
-1. Set up PostgreSQL according to the
- [database requirements document](../install/requirements.md#database).
-1. Set up a `gitlab` username with a password of your choice. The `gitlab` user
- needs privileges to create the `gitlabhq_production` database.
-1. If you are using a cloud-managed service, you may need to grant additional
- roles to your `gitlab` user:
- - Amazon RDS requires the [`rds_superuser`](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.html#Appendix.PostgreSQL.CommonDBATasks.Roles) role.
- - Azure Database for PostgreSQL requires the [`azure_pg_admin`](https://docs.microsoft.com/en-us/azure/postgresql/howto-create-users#how-to-create-additional-admin-users-in-azure-database-for-postgresql) role.
+---
+redirect_to: 'postgresql/external.md'
+---
-1. Configure the GitLab application servers with the appropriate connection details
- for your external PostgreSQL service in your `/etc/gitlab/gitlab.rb` file:
-
- ```ruby
- # Disable the bundled Omnibus provided PostgreSQL
- postgresql['enable'] = false
-
- # PostgreSQL connection details
- gitlab_rails['db_adapter'] = 'postgresql'
- gitlab_rails['db_encoding'] = 'unicode'
- gitlab_rails['db_host'] = '10.1.0.5' # IP/hostname of database server
- gitlab_rails['db_password'] = 'DB password'
- ```
-
- For more information on GitLab HA setups, refer to [configuring GitLab for HA](high_availability/gitlab.md).
-
-1. Reconfigure for the changes to take effect:
+# Configure GitLab using an external PostgreSQL service
- ```shell
- sudo gitlab-ctl reconfigure
- ```
+This content has been moved to a [new location](postgresql/external.md).
diff --git a/doc/administration/external_pipeline_validation.md b/doc/administration/external_pipeline_validation.md
index 489d1924803..cb1d35f24d5 100644
--- a/doc/administration/external_pipeline_validation.md
+++ b/doc/administration/external_pipeline_validation.md
@@ -1,3 +1,10 @@
+---
+stage: Verify
+group: Continuous Integration
+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, howto
+---
+
# External Pipeline Validation
You can use an external service for validating a pipeline before it's created.
diff --git a/doc/administration/feature_flags.md b/doc/administration/feature_flags.md
index 59cd5497032..9e87eed4508 100644
--- a/doc/administration/feature_flags.md
+++ b/doc/administration/feature_flags.md
@@ -1,4 +1,7 @@
---
+stage: Release
+group: Progressive Delivery
+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
description: "GitLab administrator: enable and disable GitLab features deployed behind feature flags"
---
@@ -29,7 +32,7 @@ them. It can be done by GitLab administrators with access to GitLab Rails
console.
If you used a certain feature and identified a bug, a misbehavior, or an
-error, it's very important that you [**provide feedback**](https://gitlab.com/gitlab-org/gitlab/issues/new?issue[title]=Docs%20-%20feature%20flag%20feedback%3A%20Feature%20Name&issue[description]=Describe%20the%20problem%20you%27ve%20encountered.%0A%0A%3C!--%20Don%27t%20edit%20below%20this%20line%20--%3E%0A%0A%2Flabel%20~%22docs%5C-comments%22%20) to GitLab as soon
+error, it's very important that you [**provide feedback**](https://gitlab.com/gitlab-org/gitlab/-/issues/new?issue[title]=Docs%20-%20feature%20flag%20feedback%3A%20Feature%20Name&issue[description]=Describe%20the%20problem%20you%27ve%20encountered.%0A%0A%3C!--%20Don%27t%20edit%20below%20this%20line%20--%3E%0A%0A%2Flabel%20~%22docs%5C-comments%22%20) to GitLab as soon
as possible so we can improve or fix it while behind a flag. When you upgrade
GitLab to an earlier version, the feature flag status may change.
@@ -94,6 +97,18 @@ Example, to disable Evidence Collection:
Feature.disable(:release_evidence_collection)
```
+Some feature flags can be enabled or disabled on a per project basis:
+
+```ruby
+Feature.enable(:<feature flag>, Project.find(<project id>))
+```
+
+For example, to enable the [`:release_evidence_collection`](../ci/junit_test_reports.md#enabling-the-feature) feature flag for project `1234`:
+
+```ruby
+Feature.enable(:release_evidence_collection, Project.find(1234))
+```
+
When the feature is ready, GitLab will remove the feature flag, the option for
enabling and disabling it will no longer exist, and the feature will become
available in all instances.
diff --git a/doc/administration/geo/disaster_recovery/background_verification.md b/doc/administration/geo/disaster_recovery/background_verification.md
index 5b24c222f06..88218d24b2f 100644
--- a/doc/administration/geo/disaster_recovery/background_verification.md
+++ b/doc/administration/geo/disaster_recovery/background_verification.md
@@ -1,3 +1,10 @@
+---
+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/#designated-technical-writers
+type: howto
+---
+
# Automatic background verification **(PREMIUM ONLY)**
NOTE: **Note:**
diff --git a/doc/administration/geo/disaster_recovery/bring_primary_back.md b/doc/administration/geo/disaster_recovery/bring_primary_back.md
index 43089237a75..b19e55595e7 100644
--- a/doc/administration/geo/disaster_recovery/bring_primary_back.md
+++ b/doc/administration/geo/disaster_recovery/bring_primary_back.md
@@ -1,3 +1,10 @@
+---
+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/#designated-technical-writers
+type: howto
+---
+
# Bring a demoted primary node back online **(PREMIUM ONLY)**
After a failover, it is possible to fail back to the demoted **primary** node to
diff --git a/doc/administration/geo/disaster_recovery/index.md b/doc/administration/geo/disaster_recovery/index.md
index 9f7afad353b..f690ec63cf9 100644
--- a/doc/administration/geo/disaster_recovery/index.md
+++ b/doc/administration/geo/disaster_recovery/index.md
@@ -1,3 +1,10 @@
+---
+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/#designated-technical-writers
+type: howto
+---
+
# Disaster Recovery (Geo) **(PREMIUM ONLY)**
Geo replicates your database, your Git repositories, and few other assets.
@@ -51,7 +58,7 @@ must disable the **primary** node.
NOTE: **Note:**
(**CentOS only**) In CentOS 6 or older, there is no easy way to prevent GitLab from being
- started if the machine reboots isn't available (see [Omnibus GitLab issue #3058](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/3058)).
+ started if the machine reboots isn't available (see [Omnibus GitLab issue #3058](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/3058)).
It may be safest to uninstall the GitLab package completely:
```shell
@@ -60,7 +67,7 @@ must disable the **primary** node.
NOTE: **Note:**
(**Ubuntu 14.04 LTS**) If you are using an older version of Ubuntu
- or any other distro based on the Upstart init system, you can prevent GitLab
+ or any other distribution based on the Upstart init system, you can prevent GitLab
from starting if the machine reboots by doing the following:
```shell
@@ -121,14 +128,20 @@ Note the following when promoting a secondary:
gitlab-ctl promote-to-primary-node
```
+ If you have already run the [preflight checks](planned_failover.md#preflight-checks), you can skip them with:
+
+ ```shell
+ gitlab-ctl promote-to-primary-node --skip-preflight-check
+ ```
+
1. Verify you can connect to the newly promoted **primary** node using the URL used
previously for the **secondary** node.
1. If successful, the **secondary** node has now been promoted to the **primary** node.
-#### Promoting a **secondary** node with HA
+#### Promoting a **secondary** node with multiple servers
The `gitlab-ctl promote-to-primary-node` command cannot be used yet in
-conjunction with High Availability or with multiple machines, as it can only
+conjunction with multiple servers, as it can only
perform changes on a **secondary** with only a single machine. Instead, you must
do this manually.
@@ -178,6 +191,27 @@ required:
set the database to read-write:
- Amazon RDS - [Promoting a Read Replica to Be a Standalone DB Instance](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_ReadRepl.html#USER_ReadRepl.Promote)
- Azure Database for PostgreSQL - [Stop replication](https://docs.microsoft.com/en-us/azure/postgresql/howto-read-replicas-portal#stop-replication)
+ - Other external PostgreSQL databases - save the script below in you secondary node, for example
+ `/tmp/geo_promote.sh`, and modify the connection parameters to match your
+ environment. Then, execute it to promote the replica:
+
+ ```shell
+ #!/bin/bash
+
+ PG_SUPERUSER=postgres
+
+ # The path to your pg_ctl binary. You may need to adjust this path to match
+ # your PostgreSQL installation
+ PG_CTL_BINARY=/usr/lib/postgresql/10/bin/pg_ctl
+
+ # The path to your PostgreSQL data directory. You may need to adjust this
+ # path to match your PostgreSQL installation. You can also run
+ # `SHOW data_directory;` from PostgreSQL to find your data directory
+ PG_DATA_DIRECTORY=/etc/postgresql/10/main
+
+ # Promote the PostgreSQL database and allow read/write operations
+ sudo -u $PG_SUPERUSER $PG_CTL_BINARY -D $PG_DATA_DIRECTORY promote
+ ```
1. Edit `/etc/gitlab/gitlab.rb` on every node in the **secondary** site to
reflect its new status as **primary** by removing any lines that enabled the
diff --git a/doc/administration/geo/disaster_recovery/planned_failover.md b/doc/administration/geo/disaster_recovery/planned_failover.md
index 00ca1e4b8b0..0ce1325a537 100644
--- a/doc/administration/geo/disaster_recovery/planned_failover.md
+++ b/doc/administration/geo/disaster_recovery/planned_failover.md
@@ -1,3 +1,10 @@
+---
+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/#designated-technical-writers
+type: howto
+---
+
# Disaster recovery for planned failover **(PREMIUM ONLY)**
The primary use-case of Disaster Recovery is to ensure business continuity in
@@ -126,7 +133,7 @@ will take to finish syncing. An example message would be:
## Prevent updates to the **primary** node
-Until a [read-only mode](https://gitlab.com/gitlab-org/gitlab-foss/issues/19739) is implemented, updates must be prevented
+Until a [read-only mode](https://gitlab.com/gitlab-org/gitlab/-/issues/14609) is implemented, updates must be prevented
from happening manually. Note that your **secondary** node still needs read-only
access to the **primary** node during the maintenance window.
diff --git a/doc/administration/geo/replication/configuration.md b/doc/administration/geo/replication/configuration.md
index 86a8e5b28d1..3d08ed81700 100644
--- a/doc/administration/geo/replication/configuration.md
+++ b/doc/administration/geo/replication/configuration.md
@@ -1,3 +1,10 @@
+---
+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/#designated-technical-writers
+type: howto
+---
+
# Geo configuration **(PREMIUM ONLY)**
## Configuring a new **secondary** node
@@ -25,7 +32,7 @@ Any change that requires access to the **Admin Area** needs to be done in the
GitLab stores a number of secret values in the `/etc/gitlab/gitlab-secrets.json`
file which *must* be the same on all nodes. Until there is
-a means of automatically replicating these between nodes (see [issue #3789](https://gitlab.com/gitlab-org/gitlab/issues/3789)),
+a means of automatically replicating these between nodes (see [issue #3789](https://gitlab.com/gitlab-org/gitlab/-/issues/3789)),
they must be manually replicated to the **secondary** node.
1. SSH into the **primary** node, and execute the command below:
diff --git a/doc/administration/geo/replication/database.md b/doc/administration/geo/replication/database.md
index 62bd0e6ac19..3f2d46ba457 100644
--- a/doc/administration/geo/replication/database.md
+++ b/doc/administration/geo/replication/database.md
@@ -1,3 +1,10 @@
+---
+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/#designated-technical-writers
+type: howto
+---
+
# Geo database replication **(PREMIUM ONLY)**
NOTE: **Note:**
@@ -23,10 +30,6 @@ The GitLab **primary** node where the write operations happen will connect to
the **primary** database server, and **secondary** nodes will
connect to their own database servers (which are also read-only).
-NOTE: **Note:**
-In database documentation, you may see "**primary**" being referenced as "master"
-and "**secondary**" as either "slave" or "standby" server (read-only).
-
We recommend using [PostgreSQL replication slots](https://medium.com/@tk512/replication-slots-in-postgresql-b4b03d277c75)
to ensure that the **primary** node retains all the data necessary for the **secondary** nodes to
recover. See below for more details.
@@ -43,7 +46,7 @@ The following guide assumes that:
CAUTION: **Warning:**
Geo works with streaming replication. Logical replication is not supported at this time.
-There is an [issue where support is being discussed](https://gitlab.com/gitlab-org/gitlab/issues/7420).
+There is an [issue where support is being discussed](https://gitlab.com/gitlab-org/gitlab/-/issues/7420).
### Step 1. Configure the **primary** server
@@ -317,7 +320,7 @@ There is an [issue where support is being discussed](https://gitlab.com/gitlab-o
to the private key, which is **only** present on the **primary** node.
1. Test that the `gitlab-psql` user can connect to the **primary** node's database
- (the default Omnibus database name is gitlabhq_production):
+ (the default Omnibus database name is `gitlabhq_production`):
```shell
sudo \
@@ -461,7 +464,7 @@ The replication process is now complete.
PostgreSQL connections. We recommend using PgBouncer if you use GitLab in a
high-availability configuration with a cluster of nodes supporting a Geo
**primary** node and another cluster of nodes supporting a Geo **secondary** node. For more
-information, see [High Availability with Omnibus GitLab](../../high_availability/database.md#high-availability-with-omnibus-gitlab-premium-only).
+information, see [High Availability with Omnibus GitLab](../../postgresql/replication_and_failover.md).
For a Geo **secondary** node to work properly with PgBouncer in front of the database,
it will need a separate read-only user to make [PostgreSQL FDW queries](https://www.postgresql.org/docs/11/postgres-fdw.html)
diff --git a/doc/administration/geo/replication/datatypes.md b/doc/administration/geo/replication/datatypes.md
index 17031b11f51..f50da27d82f 100644
--- a/doc/administration/geo/replication/datatypes.md
+++ b/doc/administration/geo/replication/datatypes.md
@@ -1,3 +1,10 @@
+---
+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/#designated-technical-writers
+type: howto
+---
+
# Geo data types support
A Geo data type is a specific class of data that is required by one or more GitLab features to
@@ -129,11 +136,11 @@ successfully, you must replicate their data using some other means.
| Application data in PostgreSQL | **Yes** | **Yes** | |
| Project repository | **Yes** | **Yes** | |
| Project wiki repository | **Yes** | **Yes** | |
-| Project designs repository | **Yes** | [No](https://gitlab.com/gitlab-org/gitlab/issues/32467) | |
+| Project designs repository | **Yes** | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/32467) | |
| Uploads | **Yes** | [No](https://gitlab.com/groups/gitlab-org/-/epics/1817) | Verified only on transfer, or manually (*1*) |
-| LFS objects | **Yes** | [No](https://gitlab.com/gitlab-org/gitlab/issues/8922) | Verified only on transfer, or manually (*1*). Unavailable for new LFS objects in 11.11.x and 12.0.x (*2*). |
-| CI job artifacts (other than traces) | **Yes** | [No](https://gitlab.com/gitlab-org/gitlab/issues/8923) | Verified only manually (*1*) |
-| Archived traces | **Yes** | [No](https://gitlab.com/gitlab-org/gitlab/issues/8923) | Verified only on transfer, or manually (*1*) |
+| LFS objects | **Yes** | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/8922) | Verified only on transfer, or manually (*1*). Unavailable for new LFS objects in 11.11.x and 12.0.x (*2*). |
+| CI job artifacts (other than traces) | **Yes** | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/8923) | Verified only manually (*1*) |
+| Archived traces | **Yes** | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/8923) | Verified only on transfer, or manually (*1*) |
| Personal snippets | **Yes** | **Yes** | |
| [Versioned snippets](../../../user/snippets.md#versioned-snippets) | [No](https://gitlab.com/groups/gitlab-org/-/epics/2809) | [No](https://gitlab.com/groups/gitlab-org/-/epics/2810) | |
| Project snippets | **Yes** | **Yes** | |
@@ -147,11 +154,16 @@ successfully, you must replicate their data using some other means.
| [Conan Repository](../../../user/packages/conan_repository/index.md) | [No](https://gitlab.com/groups/gitlab-org/-/epics/2346) | No | |
| [NuGet Repository](../../../user/packages/nuget_repository/index.md) | [No](https://gitlab.com/groups/gitlab-org/-/epics/2346) | No | |
| [PyPi Repository](../../../user/packages/pypi_repository/index.md) | [No](https://gitlab.com/groups/gitlab-org/-/epics/2554) | No | |
-| [External merge request diffs](../../merge_request_diffs.md) | [No](https://gitlab.com/gitlab-org/gitlab/issues/33817) | No | |
+| [Composer Repository](../../../user/packages/composer_repository/index.md) | [No](https://gitlab.com/groups/gitlab-org/-/epics/3096) | No | |
+| [External merge request diffs](../../merge_request_diffs.md) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/33817) | No | |
+| [Terraform State](../../terraform_state.md) | [No](https://gitlab.com/groups/gitlab-org/-/epics/3112)(*3*) | No | |
+| [Vulnerability Export](../../../user/application_security/security_dashboard/#export-vulnerabilities-1) | [No](https://gitlab.com/groups/gitlab-org/-/epics/3111)(*3*) | No | | |
| Content in object storage | **Yes** | No | |
- (*1*): The integrity can be verified manually using
[Integrity Check Rake Task](../../raketasks/check.md) on both nodes and comparing
the output between them.
- (*2*): GitLab versions 11.11.x and 12.0.x are affected by [a bug that prevents any new
- LFS objects from replicating](https://gitlab.com/gitlab-org/gitlab/issues/32696).
+ LFS objects from replicating](https://gitlab.com/gitlab-org/gitlab/-/issues/32696).
+- (*3*): If you are using Object Storage, the replication can be performed by the
+ Object Storage provider if supported. Please see [Geo with Object Storage](object_storage.md)
diff --git a/doc/administration/geo/replication/docker_registry.md b/doc/administration/geo/replication/docker_registry.md
index e9c69dd32e4..bea6528dc9b 100644
--- a/doc/administration/geo/replication/docker_registry.md
+++ b/doc/administration/geo/replication/docker_registry.md
@@ -1,3 +1,10 @@
+---
+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/#designated-technical-writers
+type: howto
+---
+
# Docker Registry for a secondary node **(PREMIUM ONLY)**
You can set up a [Docker Registry](https://docs.docker.com/registry/) on your
@@ -5,7 +12,7 @@ You can set up a [Docker Registry](https://docs.docker.com/registry/) on your
## Storage support
-Docker Registry currently supports a few types of storages. If you choose a
+Docker Registry currently supports a few types of storage. If you choose a
distributed storage (`azure`, `gcs`, `s3`, `swift`, or `oss`) for your Docker
Registry on the **primary** node, you can use the same storage for a **secondary**
Docker Registry as well. For more information, read the
@@ -16,7 +23,7 @@ integrated [Container Registry](../../packages/container_registry.md#container-r
## Replicating Docker Registry
You can enable a storage-agnostic replication so it
-can be used for cloud or local storages. Whenever a new image is pushed to the
+can be used for cloud or local storage. Whenever a new image is pushed to the
**primary** node, each **secondary** node will pull it to its own container
repository.
@@ -104,7 +111,7 @@ generate a short-lived JWT that is pull-only-capable to access the
```ruby
gitlab_rails['geo_registry_replication_enabled'] = true
- gitlab_rails['geo_registry_replication_primary_api_url'] = 'http://primary.example.com:4567/' # Primary registry address, it will be used by the secondary node to directly communicate to primary registry
+ gitlab_rails['geo_registry_replication_primary_api_url'] = 'https://primary.example.com:5050/' # Primary registry address, it will be used by the secondary node to directly communicate to primary registry
```
1. Reconfigure the **secondary** node for the change to take effect:
diff --git a/doc/administration/geo/replication/external_database.md b/doc/administration/geo/replication/external_database.md
index ae3069a0e40..491b3278ead 100644
--- a/doc/administration/geo/replication/external_database.md
+++ b/doc/administration/geo/replication/external_database.md
@@ -1,3 +1,10 @@
+---
+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/#designated-technical-writers
+type: howto
+---
+
# Geo with external PostgreSQL instances **(PREMIUM ONLY)**
This document is relevant if you are using a PostgreSQL instance that is *not
@@ -62,7 +69,7 @@ Once your read-only replica is set up, you can skip to [configure you secondary
#### Manually configure the primary database for replication
-The [geo_primary_role](https://docs.gitlab.com/omnibus/roles/#gitlab-geo-roles)
+The [`geo_primary_role`](https://docs.gitlab.com/omnibus/roles/#gitlab-geo-roles)
configures the **primary** node's database to be replicated by making changes to
`pg_hba.conf` and `postgresql.conf`. Make the following configuration changes
manually to your external database configuration and ensure that you restart PostgreSQL
@@ -123,7 +130,7 @@ hot_standby = on
### Configure **secondary** application nodes to use the external read-replica
With Omnibus, the
-[geo_secondary_role](https://docs.gitlab.com/omnibus/roles/#gitlab-geo-roles)
+[`geo_secondary_role`](https://docs.gitlab.com/omnibus/roles/#gitlab-geo-roles)
has three main functions:
1. Configure the replica database.
diff --git a/doc/administration/geo/replication/faq.md b/doc/administration/geo/replication/faq.md
index 2405e2cbfd2..522ad32c352 100644
--- a/doc/administration/geo/replication/faq.md
+++ b/doc/administration/geo/replication/faq.md
@@ -1,3 +1,10 @@
+---
+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/#designated-technical-writers
+type: howto
+---
+
# Geo Frequently Asked Questions **(PREMIUM ONLY)**
## What are the minimum requirements to run Geo?
diff --git a/doc/administration/geo/replication/geo_validation_tests.md b/doc/administration/geo/replication/geo_validation_tests.md
index a8b0bdeb7da..7b186d15fae 100644
--- a/doc/administration/geo/replication/geo_validation_tests.md
+++ b/doc/administration/geo/replication/geo_validation_tests.md
@@ -1,3 +1,10 @@
+---
+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/#designated-technical-writers
+type: howto
+---
+
# Geo validation tests
The Geo team performs manual testing and validation on common deployment configurations to ensure
@@ -26,8 +33,8 @@ The following are GitLab upgrade validation tests we performed.
configuration.
- Outcome: Upgrade test was successful.
- Follow up issues:
- - [Investigate Geo end-to-end test failures](https://gitlab.com/gitlab-org/gitlab/issues/201823).
- - [Add more logging to Geo end-to-end tests](https://gitlab.com/gitlab-org/gitlab/issues/201830).
+ - [Investigate Geo end-to-end test failures](https://gitlab.com/gitlab-org/gitlab/-/issues/201823).
+ - [Add more logging to Geo end-to-end tests](https://gitlab.com/gitlab-org/gitlab/-/issues/201830).
- [Excess service restarts during zero-downtime upgrade](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/5047).
[Upgrade Geo multi-server installation](https://gitlab.com/gitlab-org/gitlab/-/issues/199836):
@@ -43,7 +50,7 @@ The following are GitLab upgrade validation tests we performed.
configuration.
- Outcome: Upgrade test was successful.
- Follow up issues:
- - [Investigate why HTTP push spec failed on primary node](https://gitlab.com/gitlab-org/gitlab/issues/199825).
+ - [Investigate why HTTP push spec failed on primary node](https://gitlab.com/gitlab-org/gitlab/-/issues/199825).
- [Investigate if documentation should be modified to include refresh foreign tables task](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/5041).
### October 2019
@@ -89,7 +96,7 @@ The following are PostgreSQL upgrade validation tests we performed.
### September 2019
-[Test and validate PostgreSQL 10.0 upgrade for Geo](https://gitlab.com/gitlab-org/gitlab/issues/12092):
+[Test and validate PostgreSQL 10.0 upgrade for Geo](https://gitlab.com/gitlab-org/gitlab/-/issues/12092):
- Description: With the 12.0 release, GitLab required an upgrade to PostgreSQL 10.0. We tested
various upgrade scenarios from GitLab 11.11.5 through to GitLab 12.1.8.
diff --git a/doc/administration/geo/replication/index.md b/doc/administration/geo/replication/index.md
index 87bd7b69515..5b4b476bfa8 100644
--- a/doc/administration/geo/replication/index.md
+++ b/doc/administration/geo/replication/index.md
@@ -1,3 +1,10 @@
+---
+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/#designated-technical-writers
+type: howto
+---
+
# Replication (Geo) **(PREMIUM ONLY)**
> - Introduced in GitLab Enterprise Edition 8.9.
@@ -191,7 +198,7 @@ If you installed GitLab using the Omnibus packages (highly recommended):
1. [Set up the database replication](database.md) (`primary (read-write) <-> secondary (read-only)` topology).
1. [Configure fast lookup of authorized SSH keys in the database](../../operations/fast_ssh_key_lookup.md). This step is required and needs to be done on **both** the **primary** and **secondary** nodes.
1. [Configure GitLab](configuration.md) to set the **primary** and **secondary** nodes.
-1. Optional: [Configure a secondary LDAP server](../../auth/ldap.md) for the **secondary** node. See [notes on LDAP](#ldap).
+1. Optional: [Configure a secondary LDAP server](../../auth/ldap/index.md) for the **secondary** node. See [notes on LDAP](#ldap).
1. [Follow the "Using a Geo Server" guide](using_a_geo_server.md).
## Post-installation documentation
@@ -243,15 +250,15 @@ For more information on removing a Geo node, see [Removing **secondary** Geo nod
CAUTION: **Caution:**
This list of limitations only reflects the latest version of GitLab. If you are using an older version, extra limitations may be in place.
-- Pushing directly to a **secondary** node redirects (for HTTP) or proxies (for SSH) the request to the **primary** node instead of [handling it directly](https://gitlab.com/gitlab-org/gitlab/issues/1381), except when using Git over HTTP with credentials embedded within the URI. For example, `https://user:password@secondary.tld`.
+- Pushing directly to a **secondary** node redirects (for HTTP) or proxies (for SSH) the request to the **primary** node instead of [handling it directly](https://gitlab.com/gitlab-org/gitlab/-/issues/1381), except when using Git over HTTP with credentials embedded within the URI. For example, `https://user:password@secondary.tld`.
- Cloning, pulling, or pushing repositories that exist on the **primary** node but not on the **secondary** nodes where [selective synchronization](configuration.md#selective-synchronization) does not include the project is not supported over SSH [but support is planned](https://gitlab.com/groups/gitlab-org/-/epics/2562). HTTP(S) is supported.
-- The **primary** node has to be online for OAuth login to happen. Existing sessions and Git are not affected. Support for the **secondary** node to use an OAuth provider independent from the primary is [being planned](https://gitlab.com/gitlab-org/gitlab/issues/208465).
-- The installation takes multiple manual steps that together can take about an hour depending on circumstances. We are working on improving this experience. See [Omnibus GitLab issue #2978](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/2978) for details.
+- The **primary** node has to be online for OAuth login to happen. Existing sessions and Git are not affected. Support for the **secondary** node to use an OAuth provider independent from the primary is [being planned](https://gitlab.com/gitlab-org/gitlab/-/issues/208465).
+- The installation takes multiple manual steps that together can take about an hour depending on circumstances. We are working on improving this experience. See [Omnibus GitLab issue #2978](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/2978) for details.
- Real-time updates of issues/merge requests (for example, via long polling) doesn't work on the **secondary** node.
- [Selective synchronization](configuration.md#selective-synchronization) applies only to files and repositories. Other datasets are replicated to the **secondary** node in full, making it inappropriate for use as an access control mechanism.
- Object pools for forked project deduplication work only on the **primary** node, and are duplicated on the **secondary** node.
- [External merge request diffs](../../merge_request_diffs.md) will not be replicated if they are on-disk, and viewing merge requests will fail. However, external MR diffs in object storage **are** supported. The default configuration (in-database) does work.
-- GitLab Runners cannot register with a **secondary** node. Support for this is [planned for the future](https://gitlab.com/gitlab-org/gitlab/issues/3294).
+- GitLab Runners cannot register with a **secondary** node. Support for this is [planned for the future](https://gitlab.com/gitlab-org/gitlab/-/issues/3294).
### Limitations on replication/verification
diff --git a/doc/administration/geo/replication/location_aware_git_url.md b/doc/administration/geo/replication/location_aware_git_url.md
index f1f1edd4a9b..49c83ee1718 100644
--- a/doc/administration/geo/replication/location_aware_git_url.md
+++ b/doc/administration/geo/replication/location_aware_git_url.md
@@ -1,3 +1,10 @@
+---
+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/#designated-technical-writers
+type: howto
+---
+
# Location-aware Git remote URL with AWS Route53 **(PREMIUM ONLY)**
You can provide GitLab users with a single remote URL that automatically uses
@@ -15,7 +22,7 @@ NOTE: **Note**
You can also use a load balancer to distribute web UI or API traffic to
[multiple Geo **secondary** nodes](../../../user/admin_area/geo_nodes.md#multiple-secondary-nodes-behind-a-load-balancer).
Importantly, the **primary** node cannot yet be included. See the feature request
-[Support putting the **primary** behind a Geo node load balancer](https://gitlab.com/gitlab-org/gitlab/issues/10888).
+[Support putting the **primary** behind a Geo node load balancer](https://gitlab.com/gitlab-org/gitlab/-/issues/10888).
## Prerequisites
diff --git a/doc/administration/geo/replication/multiple_servers.md b/doc/administration/geo/replication/multiple_servers.md
index 9322c4cc417..2747aaeb105 100644
--- a/doc/administration/geo/replication/multiple_servers.md
+++ b/doc/administration/geo/replication/multiple_servers.md
@@ -1,3 +1,10 @@
+---
+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/#designated-technical-writers
+type: howto
+---
+
# Geo for multiple servers **(PREMIUM ONLY)**
This document describes a minimal reference architecture for running Geo
@@ -38,7 +45,7 @@ Because of the additional complexity involved in setting up this configuration
for PostgreSQL and Redis, it is not covered by this Geo multi-server documentation.
For more information about setting up a multi-server PostgreSQL cluster and Redis cluster using the omnibus package see the multi-server documentation for
-[PostgreSQL](../../high_availability/database.md) and
+[PostgreSQL](../../postgresql/replication_and_failover.md) and
[Redis](../../high_availability/redis.md), respectively.
NOTE: **Note:**
@@ -87,7 +94,7 @@ NOTE: **Note:** PostgreSQL and Redis should have already been disabled on the
application servers, and connections from the application servers to those
services on the backend servers configured, during normal GitLab multi-server set up. See
multi-server configuration documentation for
-[PostgreSQL](../../high_availability/database.md#configuring-the-application-nodes)
+[PostgreSQL](../../postgresql/replication_and_failover.md#configuring-the-application-nodes)
and [Redis](../../high_availability/redis.md#example-configuration-for-the-gitlab-application).
### Step 2: Configure the **primary** database
diff --git a/doc/administration/geo/replication/object_storage.md b/doc/administration/geo/replication/object_storage.md
index ffd44282b23..3cc0ade414e 100644
--- a/doc/administration/geo/replication/object_storage.md
+++ b/doc/administration/geo/replication/object_storage.md
@@ -1,3 +1,10 @@
+---
+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/#designated-technical-writers
+type: howto
+---
+
# Geo with Object storage **(PREMIUM ONLY)**
Geo can be used in combination with Object Storage (AWS S3, or other compatible object storage).
@@ -16,7 +23,7 @@ To have:
## Enabling GitLab managed object storage replication
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/10586) in GitLab 12.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10586) in GitLab 12.4.
CAUTION: **Caution:**
This is a [**beta** feature](https://about.gitlab.com/handbook/product/#beta) and is not ready yet for production use at any scale.
diff --git a/doc/administration/geo/replication/remove_geo_node.md b/doc/administration/geo/replication/remove_geo_node.md
index c04c7aec858..539132776b3 100644
--- a/doc/administration/geo/replication/remove_geo_node.md
+++ b/doc/administration/geo/replication/remove_geo_node.md
@@ -1,3 +1,10 @@
+---
+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/#designated-technical-writers
+type: howto
+---
+
# Removing secondary Geo nodes **(PREMIUM ONLY)**
**Secondary** nodes can be removed from the Geo cluster using the Geo admin page of the **primary** node. To remove a **secondary** node:
diff --git a/doc/administration/geo/replication/security_review.md b/doc/administration/geo/replication/security_review.md
index 0ac8157220a..f5edf79c6e4 100644
--- a/doc/administration/geo/replication/security_review.md
+++ b/doc/administration/geo/replication/security_review.md
@@ -1,3 +1,10 @@
+---
+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/#designated-technical-writers
+type: howto
+---
+
# Geo security review (Q&A) **(PREMIUM ONLY)**
The following security review of the Geo feature set focuses on security aspects of
@@ -22,7 +29,7 @@ from [owasp.org](https://owasp.org/).
etc) and repository + wiki data. In a typical configuration, this will
happen across the public Internet, and be TLS-encrypted.
- PostgreSQL replication is TLS-encrypted.
-- See also: [only TLSv1.2 should be supported](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/2948)
+- See also: [only TLSv1.2 should be supported](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/2948)
### How can the data be classified into categories according to its sensitivity?
@@ -72,7 +79,7 @@ from [owasp.org](https://owasp.org/).
- Nothing Geo-specific. Any user where `admin: true` is set in the database is
considered an admin with super-user privileges.
-- See also: [more granular access control](https://gitlab.com/gitlab-org/gitlab-foss/issues/32730)
+- See also: [more granular access control](https://gitlab.com/gitlab-org/gitlab/-/issues/18242)
(not Geo-specific).
- Much of Geo’s integration (database replication, for instance) must be
configured with the application, typically by system administrators.
diff --git a/doc/administration/geo/replication/troubleshooting.md b/doc/administration/geo/replication/troubleshooting.md
index 293414a6e5e..b03a2dae971 100644
--- a/doc/administration/geo/replication/troubleshooting.md
+++ b/doc/administration/geo/replication/troubleshooting.md
@@ -1,3 +1,10 @@
+---
+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/#designated-technical-writers
+type: howto
+---
+
# Geo Troubleshooting **(PREMIUM ONLY)**
Setting up Geo requires careful attention to details and sometimes it's easy to
@@ -332,7 +339,7 @@ some of these queries will never be able to complete due to being canceled
every time.
These long-running queries are
-[planned to be removed in the future](https://gitlab.com/gitlab-org/gitlab/issues/34269),
+[planned to be removed in the future](https://gitlab.com/gitlab-org/gitlab/-/issues/34269),
but as a workaround, we recommend enabling
[hot_standby_feedback](https://www.postgresql.org/docs/10/hot-standby.html#HOT-STANDBY-CONFLICT).
This increases the likelihood of bloat on the **primary** node as it prevents
@@ -353,7 +360,7 @@ sudo gitlab-ctl reconfigure
```
To help us resolve this problem, consider commenting on
-[the issue](https://gitlab.com/gitlab-org/gitlab/issues/4489).
+[the issue](https://gitlab.com/gitlab-org/gitlab/-/issues/4489).
### Message: `LOG: invalid CIDR mask in address`
@@ -405,7 +412,7 @@ long enough to accommodate a full clone of your largest repositories.
If new LFS objects are never replicated to secondary Geo nodes, check the version of
GitLab you are running. GitLab versions 11.11.x or 12.0.x are affected by
-[a bug that results in new LFS objects not being replicated to Geo secondary nodes](https://gitlab.com/gitlab-org/gitlab/issues/32696).
+[a bug that results in new LFS objects not being replicated to Geo secondary nodes](https://gitlab.com/gitlab-org/gitlab/-/issues/32696).
To resolve the issue, upgrade to GitLab 12.1 or newer.
@@ -535,7 +542,7 @@ or `gitlab-ctl promote-to-primary-node`, either:
```ruby
Rails.application.load_tasks; nil
- Gitlab::Geo.expire_cache_keys!([:primary_node, :current_node])
+ Gitlab::Geo.expire_cache!
Rake::Task['geo:set_secondary_as_primary'].invoke
```
@@ -568,7 +575,7 @@ is displayed if you attempt to run this command on a primary node.
### Message: `sudo: gitlab-pg-ctl: command not found`
When
-[promoting a **secondary** node with HA](../disaster_recovery/index.md#promoting-a-secondary-node-with-ha),
+[promoting a **secondary** node with multiple servers](../disaster_recovery/index.md#promoting-a-secondary-node-with-multiple-servers),
you need to run the `gitlab-pg-ctl` command to promote the PostgreSQL
read-replica database.
diff --git a/doc/administration/geo/replication/tuning.md b/doc/administration/geo/replication/tuning.md
index 972bf002935..63a8f81eecb 100644
--- a/doc/administration/geo/replication/tuning.md
+++ b/doc/administration/geo/replication/tuning.md
@@ -1,3 +1,10 @@
+---
+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/#designated-technical-writers
+type: howto
+---
+
# Tuning Geo **(PREMIUM ONLY)**
## Changing the sync capacity values
diff --git a/doc/administration/geo/replication/updating_the_geo_nodes.md b/doc/administration/geo/replication/updating_the_geo_nodes.md
index fa1576e19eb..6c2778ad0fe 100644
--- a/doc/administration/geo/replication/updating_the_geo_nodes.md
+++ b/doc/administration/geo/replication/updating_the_geo_nodes.md
@@ -1,3 +1,10 @@
+---
+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/#designated-technical-writers
+type: howto
+---
+
# Updating the Geo nodes **(PREMIUM ONLY)**
Updating Geo nodes involves performing:
diff --git a/doc/administration/geo/replication/using_a_geo_server.md b/doc/administration/geo/replication/using_a_geo_server.md
index 2fec2b2b59c..3f2895f1c71 100644
--- a/doc/administration/geo/replication/using_a_geo_server.md
+++ b/doc/administration/geo/replication/using_a_geo_server.md
@@ -1,3 +1,10 @@
+---
+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/#designated-technical-writers
+type: howto
+---
+
<!-- Please update EE::GitLab::GeoGitAccess::GEO_SERVER_DOCS_URL if this file is moved) -->
# Using a Geo Server **(PREMIUM ONLY)**
diff --git a/doc/administration/geo/replication/version_specific_updates.md b/doc/administration/geo/replication/version_specific_updates.md
index db8bbddec3b..777de715a8c 100644
--- a/doc/administration/geo/replication/version_specific_updates.md
+++ b/doc/administration/geo/replication/version_specific_updates.md
@@ -1,3 +1,10 @@
+---
+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/#designated-technical-writers
+type: howto
+---
+
# Version specific update instructions
Check this document if it includes instructions for the version you are updating.
@@ -16,7 +23,7 @@ The issue is fixed in GitLab 12.9.4. Please upgrade to GitLab 12.9.4 or later.
DANGER: **Danger:**
Only upgrade to GitLab 12.7.5 or later. Do not upgrade to versions 12.7.0
through 12.7.4 because there is [an initialization order
-bug](https://gitlab.com/gitlab-org/gitlab/issues/199672) that causes Geo
+bug](https://gitlab.com/gitlab-org/gitlab/-/issues/199672) that causes Geo
**secondaries** to set the incorrect database connection pool size. [The
fix](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/24021) was
shipped in 12.7.5.
@@ -56,14 +63,14 @@ sudo touch /etc/gitlab/disable-postgresql-upgrade
CAUTION: **Warning:**
This version is affected by [a bug that results in new LFS objects not being replicated to
-Geo secondary nodes](https://gitlab.com/gitlab-org/gitlab/issues/32696). The issue is fixed
+Geo secondary nodes](https://gitlab.com/gitlab-org/gitlab/-/issues/32696). The issue is fixed
in GitLab 12.1. Please upgrade to GitLab 12.1 or later.
## Updating to GitLab 11.11
CAUTION: **Warning:**
This version is affected by [a bug that results in new LFS objects not being replicated to
-Geo secondary nodes](https://gitlab.com/gitlab-org/gitlab/issues/32696). The issue is fixed
+Geo secondary nodes](https://gitlab.com/gitlab-org/gitlab/-/issues/32696). The issue is fixed
in GitLab 12.1. Please upgrade to GitLab 12.1 or later.
## Updating to GitLab 10.8
diff --git a/doc/administration/git_annex.md b/doc/administration/git_annex.md
index 0d44ed9312c..c4c38f8e683 100644
--- a/doc/administration/git_annex.md
+++ b/doc/administration/git_annex.md
@@ -5,7 +5,7 @@ disqus_identifier: 'https://docs.gitlab.com/ee/workflow/git_annex.html'
# Git annex
> **Warning:** GitLab has [completely
-removed](https://gitlab.com/gitlab-org/gitlab/issues/1648) in GitLab 9.0 (2017/03/22).
+removed](https://gitlab.com/gitlab-org/gitlab/-/issues/1648) in GitLab 9.0 (2017/03/22).
Read through the [migration guide from git-annex to Git LFS](../topics/git/lfs/migrate_from_git_annex_to_git_lfs.md).
The biggest limitation of Git, compared to some older centralized version
diff --git a/doc/administration/git_protocol.md b/doc/administration/git_protocol.md
index a8e785f9344..e1600d972bd 100644
--- a/doc/administration/git_protocol.md
+++ b/doc/administration/git_protocol.md
@@ -4,9 +4,9 @@ description: "Set and configure Git protocol v2"
# Configuring Git Protocol v2
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/46555) in GitLab 11.4.
-> - [Temporarily disabled](https://gitlab.com/gitlab-org/gitlab-foss/issues/55769) in GitLab 11.5.8, 11.6.6, 11.7.1, and 11.8+.
-> - [Re-enabled](https://gitlab.com/gitlab-org/gitlab/issues/27828) in GitLab 12.8.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/46555) in GitLab 11.4.
+> - [Temporarily disabled](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/55769) in GitLab 11.5.8, 11.6.6, 11.7.1, and 11.8+.
+> - [Re-enabled](https://gitlab.com/gitlab-org/gitlab/-/issues/27828) in GitLab 12.8.
Git protocol v2 improves the v1 wire protocol in several ways and is
enabled by default in GitLab for HTTP requests. In order to enable SSH,
@@ -24,7 +24,7 @@ From the server side, if we want to configure SSH we need to set the `sshd`
server to accept the `GIT_PROTOCOL` environment.
In installations using [GitLab Helm Charts](https://docs.gitlab.com/charts/)
-and [All-in-one docker image](https://docs.gitlab.com/omnibus/docker/), the SSH
+and [All-in-one Docker image](https://docs.gitlab.com/omnibus/docker/), the SSH
service is already configured to accept the `GIT_PROTOCOL` environment and users
need not do anything more.
diff --git a/doc/administration/gitaly/index.md b/doc/administration/gitaly/index.md
index 14b0a6bd450..1469ed64004 100644
--- a/doc/administration/gitaly/index.md
+++ b/doc/administration/gitaly/index.md
@@ -1,14 +1,25 @@
+---
+stage: Create
+group: Gitaly
+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
+---
+
# Gitaly
-[Gitaly](https://gitlab.com/gitlab-org/gitaly) is the service that
-provides high-level RPC access to Git repositories. Without it, no other
-components can read or write Git data. GitLab components that access Git
-repositories (GitLab Rails, GitLab Shell, GitLab Workhorse, etc.) act as clients
-to Gitaly. End users do not have direct access to Gitaly.
+[Gitaly](https://gitlab.com/gitlab-org/gitaly) is the service that provides high-level RPC access to
+Git repositories. Without it, no GitLab components can read or write Git data.
+
+In the Gitaly documentation:
-On this page, *Gitaly server* refers to a standalone node that only runs Gitaly
-and *Gitaly client* is a GitLab Rails app node that runs all other processes
-except Gitaly.
+- **Gitaly server** refers to any node that runs Gitaly itself.
+- **Gitaly client** refers to any node that runs a process that makes requests of the
+ Gitaly server. Processes include, but are not limited to:
+ - [GitLab Rails application](https://gitlab.com/gitlab-org/gitlab).
+ - [GitLab Shell](https://gitlab.com/gitlab-org/gitlab-shell).
+ - [GitLab Workhorse](https://gitlab.com/gitlab-org/gitlab-workhorse).
+
+GitLab end users do not have direct access to Gitaly.
CAUTION: **Caution:**
From GitLab 13.0, using NFS for Git repositories is deprecated. In GitLab 14.0,
@@ -17,19 +28,20 @@ support for NFS for Git repositories is scheduled to be removed. Upgrade to
## Architecture
-Here's a high-level architecture overview of how Gitaly is used.
+The following is a high-level architecture overview of how Gitaly is used.
![Gitaly architecture diagram](img/architecture_v12_4.png)
-## Configuring Gitaly
+## Configure Gitaly
The Gitaly service itself is configured via a [TOML configuration file](reference.md).
-If you want to change any of its settings:
+To change Gitaly settings:
**For Omnibus GitLab**
-1. Edit `/etc/gitlab/gitlab.rb` and add or change the [Gitaly settings](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/1dd07197c7e5ae23626aad5a4a070a800b670380/files/gitlab-config-template/gitlab.rb.template#L1622-1676).
+1. Edit `/etc/gitlab/gitlab.rb` and add or change the
+ [Gitaly settings](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/1dd07197c7e5ae23626aad5a4a070a800b670380/files/gitlab-config-template/gitlab.rb.template#L1622-1676).
1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
**For installations from source**
@@ -37,92 +49,121 @@ If you want to change any of its settings:
1. Edit `/home/git/gitaly/config.toml` and add or change the [Gitaly settings](https://gitlab.com/gitlab-org/gitaly/blob/master/config.toml.example).
1. Save the file and [restart GitLab](../restart_gitlab.md#installations-from-source).
-## Running Gitaly on its own server
+## Run Gitaly on its own server
+
+By default, Gitaly is run on the same server as Gitaly clients and is
+[configured as above](#configure-gitaly). Single-server installations are best served by
+this default configuration used by:
-This is an optional way to deploy Gitaly which can benefit GitLab
-installations that are larger than a single machine. Most
-installations will be better served with the default configuration
-used by Omnibus and the GitLab source installation guide.
-Follow transition to Gitaly on its own server, [Gitaly servers will need to be upgraded before other servers in your cluster](https://docs.gitlab.com/omnibus/update/#upgrading-gitaly-servers).
+- [Omnibus GitLab](https://docs.gitlab.com/omnibus/).
+- The GitLab [source installation guide](../../install/installation.md).
-Starting with GitLab 11.4, Gitaly is able to serve all Git requests without
-requiring a shared NFS mount for Git repository data.
-Between 11.4 and 11.8 the exception was the
-[Elasticsearch indexer](https://gitlab.com/gitlab-org/gitlab-elasticsearch-indexer).
-But since 11.8 the indexer uses Gitaly for data access as well. NFS can still
-be leveraged for redundancy on block level of the Git data. But only has to
-be mounted on the Gitaly server.
+However, Gitaly can be deployed to its own server, which can benefit GitLab installations that span
+multiple machines.
-From GitLab v11.8 to v12.2, it is possible to use Elasticsearch in conjunction with
-a Gitaly setup that isn't utilising NFS. In order to use Elasticsearch in this
-scenario, the [new repository indexer](../../integration/elasticsearch.md#elasticsearch-repository-indexer)
-needs to be enabled in your GitLab configuration. [Since GitLab v12.3](https://gitlab.com/gitlab-org/gitlab/issues/6481),
-the new indexer becomes the default and no configuration is required.
+NOTE: **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.
+
+The process for setting up Gitaly on its own server is:
+
+1. [Install Gitaly](#install-gitaly).
+1. [Configure authentication](#configure-authentication).
+1. [Configure Gitaly servers](#configure-gitaly-servers).
+1. [Configure Gitaly clients](#configure-gitaly-clients).
+
+When running Gitaly on its own server, note the following regarding GitLab versions:
+
+- From GitLab 11.4, Gitaly was able to serve all Git requests without requiring a shared NFS mount
+ for Git repository data, except for the
+ [Elasticsearch indexer](https://gitlab.com/gitlab-org/gitlab-elasticsearch-indexer).
+- From GitLab 11.8, the Elasticsearch indexer uses Gitaly for data access as well. NFS can still be
+ leveraged for redundancy on block-level Git data, but only has to be mounted on the Gitaly
+ servers.
+- From GitLab 11.8 to 12.2, it is possible to use Elasticsearch in a Gitaly setup that doesn't use
+ NFS. In order to use Elasticsearch in these versions, the
+ [repository indexer](../../integration/elasticsearch.md#elasticsearch-repository-indexer)
+ must be enabled in your GitLab configuration.
+- [Since GitLab 12.3](https://gitlab.com/gitlab-org/gitlab/-/issues/6481), the new indexer is
+ the default and no configuration is required.
### Network architecture
-The following list depicts what the network architecture of Gitaly is:
+The following list depicts the network architecture of Gitaly:
- GitLab Rails shards repositories into [repository storages](../repository_storage_paths.md).
-- `/config/gitlab.yml` contains a map from storage names to
- `(Gitaly address, Gitaly token)` pairs.
-- the `storage name` -\> `(Gitaly address, Gitaly token)` map in
- `/config/gitlab.yml` is the single source of truth for the Gitaly network
- topology.
+- `/config/gitlab.yml` contains a map from storage names to `(Gitaly address, Gitaly token)` pairs.
+- The `storage name` -\> `(Gitaly address, Gitaly token)` map in `/config/gitlab.yml` is the single
+ source of truth for the Gitaly network topology.
- A `(Gitaly address, Gitaly token)` corresponds to a Gitaly server.
- A Gitaly server hosts one or more storages.
-- A GitLab server can use one or more Gitaly servers.
-- Gitaly addresses must be specified in such a way that they resolve
- correctly for ALL Gitaly clients.
-- Gitaly clients are: Puma/Unicorn, Sidekiq, GitLab Workhorse,
- GitLab Shell, Elasticsearch Indexer, and Gitaly itself.
+- A Gitaly client can use one or more Gitaly servers.
+- Gitaly addresses must be specified in such a way that they resolve correctly for **all** Gitaly
+ clients.
+- Gitaly clients are:
+ - Puma or Unicorn.
+ - Sidekiq.
+ - GitLab Workhorse.
+ - GitLab Shell.
+ - Elasticsearch indexer.
+ - Gitaly itself.
- A Gitaly server must be able to make RPC calls **to itself** via its own
`(Gitaly address, Gitaly token)` pair as specified in `/config/gitlab.yml`.
-- Gitaly servers must not be exposed to the public internet as Gitaly's network
- traffic is unencrypted by default. The use of firewall is highly recommended
- to restrict access to the Gitaly server. Another option is to
- [use TLS](#tls-support).
-- Authentication is done through a static token which is shared among the Gitaly
- and GitLab Rails nodes.
+- Authentication is done through a static token which is shared among the Gitaly and GitLab Rails
+ nodes.
+
+DANGER: **Danger:**
+Gitaly servers must not be exposed to the public internet as Gitaly's network traffic is unencrypted
+by default. The use of firewall is highly recommended to restrict access to the Gitaly server.
+Another option is to [use TLS](#tls-support).
+
+In the following sections, we describe how to configure two Gitaly servers with secret token
+`abc123secret`:
-Below we describe how to configure two Gitaly servers one at
-`gitaly1.internal` and the other at `gitaly2.internal`
-with secret token `abc123secret`. We assume
-your GitLab installation has three repository storages: `default`,
-`storage1` and `storage2`. You can use as little as just one server with one
-repository storage if desired.
+- `gitaly1.internal`.
+- `gitaly2.internal`.
-Note: **Note:** The token referred to throughout the Gitaly documentation is
-just an arbitrary password selected by the administrator. It is unrelated to
-tokens created for the GitLab API or other similar web API tokens.
+We assume your GitLab installation has three repository storages:
-### 1. Installation
+- `default`.
+- `storage1`.
+- `storage2`.
-First install Gitaly on each Gitaly server using either
-Omnibus GitLab or install it from source:
+You can use as few as one server with one repository storage if desired.
-- For Omnibus GitLab: [Download/install](https://about.gitlab.com/install/) the Omnibus GitLab
- package you want using **steps 1 and 2** from the GitLab downloads page but
- **_do not_** provide the `EXTERNAL_URL=` value.
-- From source: [Install Gitaly](../../install/installation.md#install-gitaly).
+NOTE: **Note:**
+The token referred to throughout the Gitaly documentation is just an arbitrary password selected by
+the administrator. It is unrelated to tokens created for the GitLab API or other similar web API
+tokens.
+
+### Install Gitaly
+
+Install Gitaly on each Gitaly server using either Omnibus GitLab or install it from source:
+
+- For Omnibus GitLab, [download and install](https://about.gitlab.com/install/) the Omnibus GitLab
+ package you want but **do not** provide the `EXTERNAL_URL=` value.
+- To install from source, follow the steps at
+ [Install Gitaly](../../install/installation.md#install-gitaly).
-### 2. Authentication
+### Configure authentication
-Gitaly and GitLab use two shared secrets for authentication, one to authenticate gRPC requests
-to Gitaly, and a second for authentication callbacks from GitLab-Shell to the GitLab internal API.
+Gitaly and GitLab use two shared secrets for authentication:
+
+- One to authenticate gRPC requests to Gitaly.
+- A second for authentication callbacks from GitLab Shell to the GitLab internal API.
**For Omnibus GitLab**
To configure the Gitaly token:
-1. On the client server, edit `/etc/gitlab/gitlab.rb`:
+1. On the Gitaly clients, edit `/etc/gitlab/gitlab.rb`:
```ruby
gitlab_rails['gitaly_token'] = 'abc123secret'
```
1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
-
1. On the Gitaly server, edit `/etc/gitlab/gitlab.rb`:
```ruby
@@ -131,22 +172,24 @@ To configure the Gitaly token:
1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
-There are two ways to configure the GitLab-Shell token:
+There are two ways to configure the GitLab Shell token.
-1. Copy `/etc/gitlab/gitlab-secrets.json` from the client server to same path on the Gitaly server.
-1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+Method 1:
+
+1. Copy `/etc/gitlab/gitlab-secrets.json` from the Gitaly client to same path on the Gitaly servers
+ (and any other Gitaly clients).
+1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) on Gitaly servers.
-**OR**
+Method 2:
-1. On the client server, edit `/etc/gitlab/gitlab.rb`:
+1. On the Gitaly clients, edit `/etc/gitlab/gitlab.rb`:
```ruby
gitlab_shell['secret_token'] = 'shellsecret'
```
1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
-
-1. On the Gitaly server, edit `/etc/gitlab/gitlab.rb`:
+1. On the Gitaly servers, edit `/etc/gitlab/gitlab.rb`:
```ruby
gitlab_shell['secret_token'] = 'shellsecret'
@@ -156,9 +199,9 @@ There are two ways to configure the GitLab-Shell token:
**For installations from source**
-1. Copy `/home/git/gitlab/.gitlab_shell_secret` from the client server to the same path on the Gitaly
-server.
-1. On the client server, edit `/home/git/gitlab/config/gitlab.yml`:
+1. Copy `/home/git/gitlab/.gitlab_shell_secret` from the Gitaly client to the same path on the
+ Gitaly servers (and any other Gitaly clients).
+1. On the Gitaly clients, edit `/home/git/gitlab/config/gitlab.yml`:
```yaml
gitlab:
@@ -167,17 +210,22 @@ server.
```
1. Save the file and [restart GitLab](../restart_gitlab.md#installations-from-source).
+1. On the Gitaly servers, edit `/home/git/gitaly/config.toml`:
+
+ ```toml
+ [auth]
+ token = 'abc123secret'
+ ```
-### 3. Gitaly server configuration
+1. Save the file and [restart GitLab](../restart_gitlab.md#installations-from-source).
-Next, on the Gitaly servers, you need to configure storage paths, enable
-the network listener and configure the token.
+### Configure Gitaly servers
-NOTE: **Note:** If you want to reduce the risk of downtime when you enable
-authentication you can temporarily disable enforcement, see [the
-documentation on configuring Gitaly
-authentication](https://gitlab.com/gitlab-org/gitaly/blob/master/doc/configuration/README.md#authentication)
-.
+On the Gitaly servers, you must configure storage paths and enable the network listener.
+
+If you want to reduce the risk of downtime when you enable authentication, you can temporarily
+disable enforcement. For more information, see the documentation on configuring
+[Gitaly authentication](https://gitlab.com/gitlab-org/gitaly/blob/master/doc/configuration/README.md#authentication).
**For Omnibus GitLab**
@@ -199,6 +247,7 @@ authentication](https://gitlab.com/gitlab-org/gitaly/blob/master/doc/configurati
sidekiq['enable'] = false
gitlab_workhorse['enable'] = false
grafana['enable'] = false
+ gitlab_exporter['enable'] = false
# If you run a separate monitoring node you can disable these services
alertmanager['enable'] = false
@@ -211,7 +260,6 @@ authentication](https://gitlab.com/gitlab-org/gitaly/blob/master/doc/configurati
# prometheus['monitor_kubernetes'] = false
# If you don't want to run monitoring services uncomment the following (not recommended)
- # gitlab_exporter['enable'] = false
# node_exporter['enable'] = false
# Prevent database connections during 'gitlab-ctl reconfigure'
@@ -221,7 +269,7 @@ authentication](https://gitlab.com/gitlab-org/gitaly/blob/master/doc/configurati
# Configure the gitlab-shell API callback URL. Without this, `git push` will
# fail. This can be your 'front door' GitLab URL or an internal load
# balancer.
- # Don't forget to copy `/etc/gitlab/gitlab-secrets.json` from web server to Gitaly server.
+ # Don't forget to copy `/etc/gitlab/gitlab-secrets.json` from Gitaly client to Gitaly server.
gitlab_rails['internal_api_url'] = 'https://gitlab.example.com'
# Make Gitaly accept connections on all network interfaces. You must use
@@ -230,7 +278,7 @@ authentication](https://gitlab.com/gitlab-org/gitaly/blob/master/doc/configurati
gitaly['listen_addr'] = "0.0.0.0:8075"
```
-1. Append the following to `/etc/gitlab/gitlab.rb` for each respective server:
+1. Append the following to `/etc/gitlab/gitlab.rb` for each respective Gitaly server:
<!--
updates to following example must also be made at
@@ -262,27 +310,24 @@ authentication](https://gitlab.com/gitlab-org/gitaly/blob/master/doc/configurati
1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
1. Run `sudo /opt/gitlab/embedded/service/gitlab-shell/bin/check -config /opt/gitlab/embedded/service/gitlab-shell/config.yml`
-to confirm that Gitaly can perform callbacks to the internal API.
+ to confirm that Gitaly can perform callbacks to the GitLab internal API.
**For installations from source**
-1. On the client node(s), edit `/home/git/gitaly/config.toml`:
+1. Edit `/home/git/gitaly/config.toml`:
```toml
listen_addr = '0.0.0.0:8075'
internal_socket_dir = '/var/opt/gitlab/gitaly'
- [auth]
- token = 'abc123secret'
-
[logging]
format = 'json'
level = 'info'
dir = '/var/log/gitaly'
```
-1. Append the following to `/home/git/gitaly/config.toml` for each respective server:
+1. Append the following to `/home/git/gitaly/config.toml` for each respective Gitaly server:
On `gitaly1.internal`:
@@ -304,34 +349,51 @@ to confirm that Gitaly can perform callbacks to the internal API.
path = '/srv/gitlab/git-data/repositories'
```
-1. On each Gitaly server, edit `/home/git/gitlab-shell/config.yml`:
+1. Edit `/home/git/gitlab-shell/config.yml`:
```yaml
gitlab_url: https://gitlab.example.com
```
-1. Save the file and [restart GitLab](../restart_gitlab.md#installations-from-source).
+1. Save the files and [restart GitLab](../restart_gitlab.md#installations-from-source).
1. Run `sudo -u git /home/git/gitlab-shell/bin/check -config /home/git/gitlab-shell/config.yml`
-to confirm that Gitaly can perform callbacks to the internal API.
+ to confirm that Gitaly can perform callbacks to the GitLab internal API.
+
+### Configure Gitaly clients
-### 4. Converting clients to use the Gitaly server
+As the final step, you must update Gitaly clients to switch from using local Gitaly service to use
+the Gitaly servers you just configured.
-As the final step, you need to update the client machines to switch from using
-their local Gitaly service to the new Gitaly server you just configured. This
-is a risky step because if there is any sort of network, firewall, or name
-resolution problem preventing your GitLab server from reaching the Gitaly server,
-then all Gitaly requests will fail.
+This can be risky because anything that prevents your Gitaly clients from reaching the Gitaly
+servers will cause all Gitaly requests to fail. For example, any sort of network, firewall, or name
+resolution problems.
-Additionally, you need to
-[disable Rugged if previously manually enabled](../high_availability/nfs.md#improving-nfs-performance-with-gitlab).
+Additionally, you must [disable Rugged](../high_availability/nfs.md#improving-nfs-performance-with-gitlab)
+if previously enabled manually.
-We assume that your `gitaly1.internal` Gitaly server can be reached at
-`gitaly1.internal:8075` from your GitLab server, and that Gitaly server
-can read and write to `/mnt/gitlab/default` and `/mnt/gitlab/storage1`.
+Gitaly makes the following assumptions:
-We assume also that your `gitaly2.internal` Gitaly server can be reached at
-`gitaly2.internal:8075` from your GitLab server, and that Gitaly server
-can read and write to `/mnt/gitlab/storage2`.
+- Your `gitaly1.internal` Gitaly server can be reached at `gitaly1.internal:8075` from your Gitaly
+ clients, and that Gitaly server can read and write to `/mnt/gitlab/default` and
+ `/mnt/gitlab/storage1`.
+- Your `gitaly2.internal` Gitaly server can be reached at `gitaly2.internal:8075` from your Gitaly
+ clients, and that Gitaly server can read and write to `/mnt/gitlab/storage2`.
+- Your `gitaly1.internal` and `gitaly2.internal` Gitaly servers can reach each other.
+
+Note you can't a use mixed setup, with at least one of your Gitaly servers configured as a local
+server with the `path` setting provided. This is because other Gitaly instances can't communicate
+with it. The following setup is _incorrect_, because:
+
+- You must replace `path` with `gitaly_address` containing a proper value.
+- The address must be reachable from the other two addresses provided.
+
+```ruby
+git_data_dirs({
+ 'default' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
+ 'storage1' => { 'path' => '/var/opt/gitlab/git-data' },
+ 'storage2' => { 'gitaly_address' => 'tcp://gitaly2.internal:8075' },
+})
+```
**For Omnibus GitLab**
@@ -346,7 +408,8 @@ can read and write to `/mnt/gitlab/storage2`.
```
1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
-1. Run `sudo gitlab-rake gitlab:gitaly:check` to confirm the client can connect to Gitaly.
+1. Run `sudo gitlab-rake gitlab:gitaly:check` to confirm the Gitaly client can connect to Gitaly
+ servers.
1. Tail the logs to see the requests:
```shell
@@ -373,39 +436,38 @@ can read and write to `/mnt/gitlab/storage2`.
```
NOTE: **Note:**
- `/some/dummy/path` should be set to a local folder that exists, however no
- data will be stored in this folder. This will no longer be necessary after
- [this issue](https://gitlab.com/gitlab-org/gitaly/issues/1282) is resolved.
+ `/some/dummy/path` should be set to a local folder that exists, however no data will be stored in
+ this folder. This will no longer be necessary after
+ [this issue](https://gitlab.com/gitlab-org/gitaly/-/issues/1282) is resolved.
1. Save the file and [restart GitLab](../restart_gitlab.md#installations-from-source).
-1. Run `sudo -u git -H bundle exec rake gitlab:gitaly:check RAILS_ENV=production` to
-confirm the client can connect to Gitaly.
+1. Run `sudo -u git -H bundle exec rake gitlab:gitaly:check RAILS_ENV=production` to confirm the
+ Gitaly client can connect to Gitaly servers.
1. Tail the logs to see the requests:
```shell
tail -f /home/git/gitlab/log/gitaly.log
```
-When you tail the Gitaly logs on your Gitaly server you should see requests
-coming in. One sure way to trigger a Gitaly request is to clone a repository
-from your GitLab server over HTTP.
+When you tail the Gitaly logs on your Gitaly server, you should see requests coming in. One sure way
+to trigger a Gitaly request is to clone a repository from GitLab over HTTP or HTTPS.
DANGER: **Danger:**
-If you have [Server hooks](../server_hooks.md) configured,
-either per repository or globally, you must move these to the Gitaly node.
-If you have multiple Gitaly nodes, copy your server hook(s) to all nodes.
+If you have [server hooks](../server_hooks.md) configured, either per repository or globally, you
+must move these to the Gitaly servers. If you have multiple Gitaly servers, copy your server hooks
+to all Gitaly servers.
### Disabling the Gitaly service in a cluster environment
If you are running Gitaly [as a remote
-service](#running-gitaly-on-its-own-server) you may want to disable
+service](#run-gitaly-on-its-own-server) you may want to disable
the local Gitaly service that runs on your GitLab server by default.
Disabling Gitaly only makes sense when you run GitLab in a custom
cluster configuration, where different services run on different
machines. Disabling Gitaly on all machines in the cluster is not a
valid configuration.
-To disable Gitaly on a client node:
+To disable Gitaly on a GitLab server:
**For Omnibus GitLab**
@@ -436,13 +498,16 @@ with a Gitaly instance that listens for secure connections you will need to use
scheme in the `gitaly_address` of the corresponding storage entry in the GitLab configuration.
You will need to bring your own certificates as this isn't provided automatically.
-The certificate, or its certificate authority, must be installed on all Gitaly
-nodes (including the Gitaly node using the certificate) and on all client nodes
+The certificate corresponding to each Gitaly server will need to be installed
+on that Gitaly server.
+
+Additionally the certificate, or its certificate authority, must be installed on all Gitaly servers
+(including the Gitaly server using the certificate) and on all Gitaly clients
that communicate with it following the procedure described in
-[GitLab custom certificate configuration](https://docs.gitlab.com/omnibus/settings/ssl.html#install-custom-public-certificates).
+[GitLab custom certificate configuration](https://docs.gitlab.com/omnibus/settings/ssl.html#install-custom-public-certificates) (and repeated below).
NOTE: **Note**
-The self-signed certificate must specify the address you use to access the
+The certificate must specify the address you use to access the
Gitaly server. If you are addressing the Gitaly server by a hostname, you can
either use the Common Name field for this, or add it as a Subject Alternative
Name. If you are addressing the Gitaly server by its IP address, you must add it
@@ -459,7 +524,14 @@ To configure Gitaly with TLS:
**For Omnibus GitLab**
-1. On the client node(s), edit `/etc/gitlab/gitlab.rb` as follows:
+1. Create certificates for Gitaly servers.
+1. On the Gitaly clients, copy the certificates, or their certificate authority, into the `/etc/gitlab/trusted-certs`:
+
+ ```shell
+ sudo cp cert.pem /etc/gitlab/trusted-certs/
+ ```
+
+1. On the Gitaly clients, edit `git_data_dirs` in `/etc/gitlab/gitlab.rb` as follows:
```ruby
git_data_dirs({
@@ -467,19 +539,10 @@ To configure Gitaly with TLS:
'storage1' => { 'gitaly_address' => 'tls://gitaly1.internal:9999' },
'storage2' => { 'gitaly_address' => 'tls://gitaly2.internal:9999' },
})
-
- gitlab_rails['gitaly_token'] = 'abc123secret'
- gitlab_shell['secret_token'] = 'shellsecret'
```
-1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) on client node(s).
-1. On the client node(s), copy the cert into the `/etc/gitlab/trusted-certs`:
-
- ```shell
- sudo cp cert.pem /etc/gitlab/trusted-certs/
- ```
-
-1. On the Gitaly server, create the `/etc/gitlab/ssl` directory and copy your key and certificate there:
+1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+1. On the Gitaly servers, create the `/etc/gitlab/ssl` directory and copy your key and certificate there:
```shell
sudo mkdir -p /etc/gitlab/ssl
@@ -488,14 +551,14 @@ To configure Gitaly with TLS:
sudo chmod 644 key.pem cert.pem
```
-1. Copy the cert to `/etc/gitlab/trusted-certs` so Gitaly will trust the cert when
-calling into itself:
+1. Copy all Gitaly server certificates, or their certificate authority, to `/etc/gitlab/trusted-certs` so Gitaly server will trust the certificate when
+calling into itself or other Gitaly servers:
- ```shell
- sudo cp /etc/gitlab/ssl/cert.pem /etc/gitlab/trusted-certs/
- ```
+ ```shell
+ sudo cp cert1.pem cert2.pem /etc/gitlab/trusted-certs/
+ ```
-1. On the Gitaly server node(s), edit `/etc/gitlab/gitlab.rb` and add:
+1. Edit `/etc/gitlab/gitlab.rb` and add:
<!--
updates to following example must also be made at
@@ -508,23 +571,23 @@ calling into itself:
gitaly['key_path'] = "/etc/gitlab/ssl/key.pem"
```
-1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) on Gitaly server node(s).
+1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
1. (Optional) After [verifying that all Gitaly traffic is being served over TLS](#observe-type-of-gitaly-connections),
you can improve security by disabling non-TLS connections by commenting out
or deleting `gitaly['listen_addr']` in `/etc/gitlab/gitlab.rb`, saving the file,
- and [reconfiguring GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure)
- on Gitaly server node(s).
+ and [reconfiguring GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
**For installations from source**
-1. On the client node(s), add the cert to the system trusted certs:
+1. Create certificates for Gitaly servers.
+1. On the Gitaly clients, copy the certificates into the system trusted certificates:
```shell
sudo cp cert.pem /usr/local/share/ca-certificates/gitaly.crt
sudo update-ca-certificates
```
-1. On the client node(s), edit `/home/git/gitlab/config/gitlab.yml` as follows:
+1. On the Gitaly clients, edit `storages` in `/home/git/gitlab/config/gitlab.yml` as follows:
```yaml
gitlab:
@@ -539,28 +602,21 @@ calling into itself:
storage2:
gitaly_address: tls://gitaly2.internal:9999
path: /some/dummy/path
-
- gitaly:
- token: 'abc123secret'
```
NOTE: **Note:**
`/some/dummy/path` should be set to a local folder that exists, however no
data will be stored in this folder. This will no longer be necessary after
- [this issue](https://gitlab.com/gitlab-org/gitaly/issues/1282) is resolved.
+ [this issue](https://gitlab.com/gitlab-org/gitaly/-/issues/1282) is resolved.
-1. Save the file and[restart GitLab](../restart_gitlab.md#installations-from-source)
-on client node(s).
-1. Copy `/home/git/gitlab/.gitlab_shell_secret` from the client server to the same
-path on the Gitaly server.
-1. On the Gitaly server, create or edit `/etc/default/gitlab` and add:
+1. Save the file and [restart GitLab](../restart_gitlab.md#installations-from-source).
+1. On the Gitaly servers, create or edit `/etc/default/gitlab` and add:
```shell
export SSL_CERT_DIR=/etc/gitlab/ssl
```
-1. Save the file.
-1. Create the `/etc/gitlab/ssl` directory and copy your key and certificate there:
+1. On the Gitaly servers, create the `/etc/gitlab/ssl` directory and copy your key and certificate there:
```shell
sudo mkdir -p /etc/gitlab/ssl
@@ -569,15 +625,14 @@ path on the Gitaly server.
sudo chmod 644 key.pem cert.pem
```
-1. On the Gitaly server, add the cert to the system trusted certs so Gitaly will trust it
-when calling into itself:
+1. Copy all Gitaly server certificates, or their certificate authority, to the system trusted certificates so Gitaly server will trust the certificate when calling into itself or other Gitaly servers.
```shell
sudo cp cert.pem /usr/local/share/ca-certificates/gitaly.crt
sudo update-ca-certificates
```
-1. On the Gitaly server node(s), edit `/home/git/gitaly/config.toml` and add:
+1. Edit `/home/git/gitaly/config.toml` and add:
```toml
tls_listen_addr = '0.0.0.0:9999'
@@ -587,12 +642,11 @@ when calling into itself:
key_path = '/etc/gitlab/ssl/key.pem'
```
-1. Save the file and [restart GitLab](../restart_gitlab.md#installations-from-source) on Gitaly server node(s).
+1. Save the file and [restart GitLab](../restart_gitlab.md#installations-from-source).
1. (Optional) After [verifying that all Gitaly traffic is being served over TLS](#observe-type-of-gitaly-connections),
you can improve security by disabling non-TLS connections by commenting out
or deleting `listen_addr` in `/home/git/gitaly/config.toml`, saving the file,
- and [restarting GitLab](../restart_gitlab.md#installations-from-source)
- on Gitaly server node(s).
+ and [restarting GitLab](../restart_gitlab.md#installations-from-source).
### Observe type of Gitaly connections
@@ -673,8 +727,8 @@ gitaly['concurrency'] = [
This will limit the number of in-flight RPC calls for the given RPC's.
The limit is applied per repository. In the example above, each on the
-Gitaly server can have at most 20 simultaneous PostUploadPack calls in
-flight, and the same for SSHUploadPack. If another request comes in for
+Gitaly server can have at most 20 simultaneous `PostUploadPack` calls in
+flight, and the same for `SSHUploadPack`. If another request comes in for
a repository that has used up its 20 slots, that request will get
queued.
@@ -686,7 +740,7 @@ reporting about the concurrency limiter. In Prometheus, look for the
`gitaly_rate_limiting_seconds` metrics.
The name of the Prometheus metric is not quite right because this is a
-concurrency limiter, not a rate limiter. If a client makes 1000 requests
+concurrency limiter, not a rate limiter. If a Gitaly client makes 1000 requests
in a row in a very short timespan, the concurrency will not exceed 1,
and this mechanism (the concurrency limiter) will do nothing.
@@ -697,7 +751,7 @@ downtime, or causes outages, or both. If you are careful, though, you
*can* rotate Gitaly credentials without a service interruption.
This procedure also works if you are running GitLab on a single server.
-In that case, "Gitaly servers" and "Gitaly clients" refers to the same
+In that case, "Gitaly server" and "Gitaly client" refers to the same
machine.
### 1. Monitor current authentication behavior
@@ -723,7 +777,7 @@ The only non-zero number should have `enforced="true",status="ok"`. If
you have other non-zero numbers, something is wrong in your
configuration.
-The 'status="ok"' number reflects your current request rate. In the example
+The `status="ok"` number reflects your current request rate. In the example
above, Gitaly is handling about 4000 requests per second.
Now you have established that you can monitor the Gitaly authentication
@@ -894,9 +948,9 @@ which is still under development as of December 2019.
## Troubleshooting Gitaly
-### Checking versions when using standalone Gitaly nodes
+### Checking versions when using standalone Gitaly servers
-When using standalone Gitaly nodes, you must make sure they are the same version
+When using standalone Gitaly servers, you must make sure they are the same version
as GitLab to ensure full compatibility. Check **Admin Area > Gitaly Servers** on
your GitLab instance and confirm all Gitaly Servers are `Up to date`.
@@ -931,8 +985,8 @@ gitaly-debug -h
remote: GitLab: 401 Unauthorized
```
-You will need to sync your `gitlab-secrets.json` file with your GitLab
-app nodes.
+You will need to sync your `gitlab-secrets.json` file with your Gitaly clients (GitLab
+app nodes).
### Client side gRPC logs
@@ -975,11 +1029,11 @@ If you're running Gitaly on its own server and notice that users can
successfully clone and fetch repositories (via both SSH and HTTPS), but can't
push to them or make changes to the repository in the web UI without getting a
`401 Unauthorized` message, then it's possible Gitaly is failing to authenticate
-with the other nodes due to having the [wrong secrets file](#3-gitaly-server-configuration).
+with the Gitaly client due to having the [wrong secrets file](#configure-gitaly-servers).
Confirm the following are all true:
-- When any user performs a `git push` to any repository on this Gitaly node, it
+- When any user performs a `git push` to any repository on this Gitaly server, it
fails with the following error (note the `401 Unauthorized`):
```shell
@@ -993,7 +1047,8 @@ Confirm the following are all true:
UI, it immediately fails with a red `401 Unauthorized` banner.
- Creating a new project and [initializing it with a README](../../gitlab-basics/create-project.md#blank-projects)
successfully creates the project but doesn't create the README.
-- When [tailing the logs](https://docs.gitlab.com/omnibus/settings/logs.html#tail-logs-in-a-console-on-the-server) on an app node and reproducing the error, you get `401` errors
+- When [tailing the logs](https://docs.gitlab.com/omnibus/settings/logs.html#tail-logs-in-a-console-on-the-server)
+ on a Gitaly client and reproducing the error, you get `401` errors
when reaching the `/api/v4/internal/allowed` endpoint:
```shell
@@ -1055,14 +1110,16 @@ Confirm the following are all true:
[IP] - - [18/Jul/2019:00:30:14 +0000] "POST /api/v4/internal/allowed HTTP/1.1" 401 30 "" "Ruby"
```
-To fix this problem, confirm that your [`gitlab-secrets.json` file](#3-gitaly-server-configuration)
-on the Gitaly node matches the one on all other nodes. If it doesn't match,
-update the secrets file on the Gitaly node to match the others, then
-[reconfigure the node](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+To fix this problem, confirm that your [`gitlab-secrets.json` file](#configure-gitaly-servers)
+on the Gitaly server matches the one on Gitaly client. If it doesn't match,
+update the secrets file on the Gitaly server to match the Gitaly client, then
+[reconfigure](../restart_gitlab.md#omnibus-gitlab-reconfigure).
### Command line tools cannot connect to Gitaly
-If you are having trouble connecting to a Gitaly node with command line (CLI) tools, and certain actions result in a `14: Connect Failed` error message, it means that gRPC cannot reach your Gitaly node.
+If you are having trouble connecting to a Gitaly server with command line (CLI) tools,
+and certain actions result in a `14: Connect Failed` error message,
+it means that gRPC cannot reach your Gitaly server.
Verify that you can reach Gitaly via TCP:
@@ -1070,18 +1127,22 @@ Verify that you can reach Gitaly via TCP:
sudo gitlab-rake gitlab:tcp_check[GITALY_SERVER_IP,GITALY_LISTEN_PORT]
```
-If the TCP connection fails, check your network settings and your firewall rules. If the TCP connection succeeds, your networking and firewall rules are correct.
+If the TCP connection fails, check your network settings and your firewall rules.
+If the TCP connection succeeds, your networking and firewall rules are correct.
-If you use proxy servers in your command line environment, such as Bash, these can interfere with your gRPC traffic.
+If you use proxy servers in your command line environment, such as Bash, these
+can interfere with your gRPC traffic.
-If you use Bash or a compatible command line environment, run the following commands to determine whether you have proxy servers configured:
+If you use Bash or a compatible command line environment, run the following commands
+to determine whether you have proxy servers configured:
```shell
echo $http_proxy
echo $https_proxy
```
-If either of these variables have a value, your Gitaly CLI connections may be getting routed through a proxy which cannot connect to Gitaly.
+If either of these variables have a value, your Gitaly CLI connections may be
+getting routed through a proxy which cannot connect to Gitaly.
To remove the proxy setting, run the following commands (depending on which variables had values):
@@ -1092,20 +1153,21 @@ unset https_proxy
### Gitaly not listening on new address after reconfiguring
-When updating the `gitaly['listen_addr']` or `gitaly['prometheus_listen_addr']` values, Gitaly may continue to listen on the old address after a `sudo gitlab-ctl reconfigure`.
+When updating the `gitaly['listen_addr']` or `gitaly['prometheus_listen_addr']`
+values, Gitaly may continue to listen on the old address after a `sudo gitlab-ctl reconfigure`.
-When this occurs, performing a `sudo gitlab-ctl restart` will resolve the issue. This will no longer be necessary after [this issue](https://gitlab.com/gitlab-org/gitaly/issues/2521) is resolved.
+When this occurs, performing a `sudo gitlab-ctl restart` will resolve the issue. This will no longer be necessary after [this issue](https://gitlab.com/gitlab-org/gitaly/-/issues/2521) is resolved.
-### Permission denied errors appearing in Gitaly logs when accessing repositories from a standalone Gitaly node
+### Permission denied errors appearing in Gitaly logs when accessing repositories from a standalone Gitaly server
If this error occurs even though file permissions are correct, it's likely that
-the Gitaly node is experiencing
+the Gitaly server is experiencing
[clock drift](https://en.wikipedia.org/wiki/Clock_drift).
-Please ensure that the GitLab and Gitaly nodes are synchronized and use an NTP time
+Please ensure that the Gitaly clients and servers are synchronized and use an NTP time
server to keep them synchronized if possible.
### Praefect
-Praefect is an experimental daemon that allows for replication of the Git data.
-It can be setup with omnibus, [as explained here](./praefect.md).
+Praefect is a router and transaction manager for Gitaly, and a required
+component for running a Gitaly Cluster. For more information see [Gitaly Cluster](praefect.md).
diff --git a/doc/administration/gitaly/praefect.md b/doc/administration/gitaly/praefect.md
index 0ea83f0e090..3d4e606205e 100644
--- a/doc/administration/gitaly/praefect.md
+++ b/doc/administration/gitaly/praefect.md
@@ -1,4 +1,7 @@
---
+stage: Create
+group: Gitaly
+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
---
@@ -89,7 +92,7 @@ to install GitLab](https://about.gitlab.com/install/).
Provision a PostgreSQL server (PostgreSQL 11 or newer). Configuration through
the Omnibus GitLab distribution is not yet supported. Follow this
-[issue](https://gitlab.com/gitlab-org/gitaly/issues/2476) for updates.
+[issue](https://gitlab.com/gitlab-org/gitaly/-/issues/2476) for updates.
Prepare all your new nodes by [installing
GitLab](https://about.gitlab.com/install/).
@@ -319,37 +322,6 @@ application server, or a Gitaly node.
}
```
-1. Enable the database replication queue:
-
- ```ruby
- praefect['postgres_queue_enabled'] = true
- ```
-
- In the next release, database replication queue will be enabled by default.
- See [issue #2615](https://gitlab.com/gitlab-org/gitaly/-/issues/2615).
-
-1. Enable automatic failover by editing `/etc/gitlab/gitlab.rb`:
-
- ```ruby
- praefect['failover_enabled'] = true
- praefect['failover_election_strategy'] = 'sql'
- ```
-
- When automatic failover is enabled, Praefect checks the health of internal
- Gitaly nodes. If the primary has a certain amount of health checks fail, it
- will promote one of the secondaries to be primary, and demote the primary to
- be a secondary.
-
- NOTE: **Note:** Database leader election will be [enabled by default in the
- future](https://gitlab.com/gitlab-org/gitaly/-/issues/2682).
-
- Caution, **automatic failover** favors availability over consistency and will
- cause data loss if changes have not been replicated to the newly elected
- primary. In the next release, leader election will [prefer to promote up to
- date replicas](https://gitlab.com/gitlab-org/gitaly/-/issues/2642), and it
- will be an option to favor consistency by marking [out-of-date repositories
- read-only](https://gitlab.com/gitlab-org/gitaly/-/issues/2630).
-
1. Save the changes to `/etc/gitlab/gitlab.rb` and [reconfigure
Praefect](../restart_gitlab.md#omnibus-gitlab-reconfigure):
@@ -409,7 +381,7 @@ Particular attention should be shown to:
`gitaly-2`, and `gitaly-3` as Gitaly storage names.
For more information on Gitaly server configuration, see our [Gitaly
-documentation](index.md#3-gitaly-server-configuration).
+documentation](index.md#configure-gitaly-servers).
1. SSH into the **Gitaly** node and login as root:
@@ -424,16 +396,18 @@ documentation](index.md#3-gitaly-server-configuration).
postgresql['enable'] = false
redis['enable'] = false
nginx['enable'] = false
- prometheus['enable'] = false
grafana['enable'] = false
puma['enable'] = false
sidekiq['enable'] = false
gitlab_workhorse['enable'] = false
prometheus_monitoring['enable'] = false
- # Enable only the Praefect service
+ # Enable only the Gitaly service
gitaly['enable'] = true
+ # Enable Prometheus if needed
+ prometheus['enable'] = true
+
# Prevent database connections during 'gitlab-ctl reconfigure'
gitlab_rails['rake_cache_clear'] = false
gitlab_rails['auto_migrate'] = false
@@ -682,8 +656,8 @@ Particular attention should be shown to:
Repository > Repository storage** to make the newly configured Praefect
cluster the storage location for new Git repositories.
- - Deselect the **default** storage location
- - Select the **praefect** storage location
+ - The default option is unchecked.
+ - The Praefect option is checked.
![Update repository storage](img/praefect_storage_v12_10.png)
@@ -744,7 +718,7 @@ Praefect regularly checks the health of each backend Gitaly node. This
information can be used to automatically failover to a new primary node if the
current primary node is found to be unhealthy.
-- **PostgreSQL (recommended):** Enabled by setting
+- **PostgreSQL (recommended):** Enabled by default, and equivalent to:
`praefect['failover_election_strategy'] = sql`. This configuration
option will allow multiple Praefect nodes to coordinate via the
PostgreSQL database to elect a primary Gitaly node. This configuration
@@ -755,24 +729,21 @@ current primary node is found to be unhealthy.
reconfigured in `/etc/gitlab/gitlab.rb` on the Praefect node. Modify the
`praefect['virtual_storages']` field by moving the `primary = true` to promote
a different Gitaly node to primary. In the steps above, `gitaly-1` was set to
- the primary.
-- **Memory:** Enabled by setting `praefect['failover_enabled'] = true` in
- `/etc/gitlab/gitlab.rb` on the Praefect node. If a sufficient number of health
+ the primary. Requires `praefect['failover_enabled'] = false` in the configuration.
+- **Memory:** Enabled by setting `praefect['failover_election_strategy'] = 'local'`
+ in `/etc/gitlab/gitlab.rb` on the Praefect node. If a sufficient number of health
checks fail for the current primary backend Gitaly node, and new primary will
be elected. **Do not use with multiple Praefect nodes!** Using with multiple
Praefect nodes is likely to result in a split brain.
-NOTE: **Note:**: Praefect does not yet account for replication lag on
-the secondaries during the election process, so data loss can occur
-during a failover. Follow issue
-[#2642](https://gitlab.com/gitlab-org/gitaly/-/issues/2642) for updates.
-
It is likely that we will implement support for Consul, and a cloud native
strategy in the future.
## Identifying Impact of a Primary Node Failure
-When a primary Gitaly node fails, there is a chance of data loss. Data loss can occur if there were outstanding replication jobs the secondaries did not manage to process before the failure. The Praefect `dataloss` sub-command helps identify these cases by counting the number of dead replication jobs for each repository within a given time frame.
+When a primary Gitaly node fails, there is a chance of data loss. Data loss can occur if there were outstanding replication jobs the secondaries did not manage to process before the failure. The `dataloss` Praefect sub-command helps identify these cases by counting the number of dead replication jobs for each repository. This command must be executed on a Praefect node.
+
+A time frame to search can be specified with `-from` and `-to`:
```shell
sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml dataloss -from <rfc3339-time> -to <rfc3339-time>
@@ -784,9 +755,7 @@ If the time frame is not specified, dead replication jobs from the last six hour
sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml dataloss
Failed replication jobs between [2020-01-02 00:00:00 +0000 UTC, 2020-01-02 06:00:00 +0000 UTC):
-example/repository-1: 1 jobs
-example/repository-2: 4 jobs
-example/repository-3: 2 jobs
+@hashed/fa/53/fa539965395b8382145f8370b34eab249cf610d2d6f2943c95b9b9d08a63d4a3.git: 2 jobs
```
To specify a time frame in UTC, run:
@@ -797,7 +766,8 @@ sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.t
### Checking repository checksums
-To check a project's checksums across all nodes, the Praefect replicas Rake task can be used:
+To check a project's repository checksums across on all Gitaly nodes, the
+replicas Rake task can be run on the main GitLab node:
```shell
sudo gitlab-rake "gitlab:praefect:replicas[project_id]"
diff --git a/doc/administration/gitaly/reference.md b/doc/administration/gitaly/reference.md
index e718d8953ca..52fd6fa6900 100644
--- a/doc/administration/gitaly/reference.md
+++ b/doc/administration/gitaly/reference.md
@@ -1,4 +1,7 @@
---
+stage: Create
+group: Gitaly
+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
---
@@ -12,7 +15,7 @@ The configuration file is passed as an argument to the `gitaly`
executable. This is usually done by either Omnibus GitLab or your
[init](https://en.wikipedia.org/wiki/Init) script.
-An [example config file](https://gitlab.com/gitlab-org/gitaly/blob/master/config.toml.example)
+An [example configuration file](https://gitlab.com/gitlab-org/gitaly/blob/master/config.toml.example)
can be found in the Gitaly project.
## Format
@@ -157,7 +160,7 @@ sum(rate(gitaly_catfile_cache_total{type="hit"}[5m])) / sum(rate(gitaly_catfile_
A Gitaly process uses one or more `gitaly-ruby` helper processes to
execute RPC's implemented in Ruby instead of Go. The `[gitaly-ruby]`
-section of the config file contains settings for these helper processes.
+section of the configuration file contains settings for these helper processes.
These processes are known to occasionally suffer from memory leaks.
Gitaly restarts its `gitaly-ruby` helpers when their memory exceeds the
@@ -190,7 +193,7 @@ For historical reasons
the Git hooks that allow GitLab to validate and react to Git pushes.
Because Gitaly "owns" Git pushes, GitLab Shell must therefore be
installed alongside Gitaly. This will be [simplified in the
-future](https://gitlab.com/gitlab-org/gitaly/issues/1226).
+future](https://gitlab.com/gitlab-org/gitaly/-/issues/1226).
| Name | Type | Required | Description |
| ---- | ---- | -------- | ----------- |
diff --git a/doc/administration/high_availability/consul.md b/doc/administration/high_availability/consul.md
index 1f22c46a0ad..a87c1f1027f 100644
--- a/doc/administration/high_availability/consul.md
+++ b/doc/administration/high_availability/consul.md
@@ -7,7 +7,7 @@ type: reference
As part of its High Availability stack, GitLab Premium includes a bundled version of [Consul](https://www.consul.io/) that can be managed through `/etc/gitlab/gitlab.rb`. Consul is a service networking solution. When it comes to [GitLab Architecture](../../development/architecture.md), Consul utilization is supported for configuring:
1. [Monitoring in Scaled and Highly Available environments](monitoring_node.md)
-1. [PostgreSQL High Availability with Omnibus](database.md#high-availability-with-omnibus-gitlab-premium-only)
+1. [PostgreSQL High Availability with Omnibus](../postgresql/replication_and_failover.md)
A Consul cluster consists of multiple server agents, as well as client agents that run on other nodes which need to talk to the Consul cluster.
@@ -27,7 +27,7 @@ When installing the GitLab package, do not supply `EXTERNAL_URL` value.
On each Consul node perform the following:
-1. Make sure you collect [`CONSUL_SERVER_NODES`](database.md#consul-information), which are the IP addresses or DNS records of the Consul server nodes, for the next step, before executing the next step.
+1. Make sure you collect [`CONSUL_SERVER_NODES`](../postgresql/replication_and_failover.md#consul-information), which are the IP addresses or DNS records of the Consul server nodes, for the next step, before executing the next step.
1. Edit `/etc/gitlab/gitlab.rb` replacing values noted in the `# START user configuration` section:
diff --git a/doc/administration/high_availability/database.md b/doc/administration/high_availability/database.md
index 6f1873af993..75183436046 100644
--- a/doc/administration/high_availability/database.md
+++ b/doc/administration/high_availability/database.md
@@ -4,1100 +4,17 @@ type: reference
# Configuring PostgreSQL for Scaling and High Availability
-In this section, you'll be guided through configuring a PostgreSQL database
-to be used with GitLab in a highly available environment.
+In this section, you'll be guided through configuring a PostgreSQL database to
+be used with GitLab in one of our [Scalable and Highly Available Setups](../reference_architectures/index.md).
## Provide your own PostgreSQL instance **(CORE ONLY)**
-If you're hosting GitLab on a cloud provider, you can optionally use a
-managed service for PostgreSQL. For example, AWS offers a managed Relational
-Database Service (RDS) that runs PostgreSQL.
+This content has been moved to a [new location](../postgresql/external.md).
-If you use a cloud-managed service, or provide your own PostgreSQL:
+## Standalone PostgreSQL using Omnibus GitLab **(CORE ONLY)**
-1. Set up PostgreSQL according to the
- [database requirements document](../../install/requirements.md#database).
-1. Set up a `gitlab` username with a password of your choice. The `gitlab` user
- needs privileges to create the `gitlabhq_production` database.
-1. Configure the GitLab application servers with the appropriate details.
- This step is covered in [Configuring GitLab for HA](gitlab.md).
+This content has been moved to a [new location](../postgresql/standalone.md).
-## PostgreSQL in a Scaled and Highly Available Environment
+## PostgreSQL replication and failover with Omnibus GitLab **(PREMIUM ONLY)**
-This section is relevant for [Scalable and Highly Available Setups](../reference_architectures/index.md).
-
-### Provide your own PostgreSQL instance **(CORE ONLY)**
-
-If you want to use your own deployed PostgreSQL instance(s),
-see [Provide your own PostgreSQL instance](#provide-your-own-postgresql-instance-core-only)
-for more details. However, you can use the Omnibus GitLab package to easily
-deploy the bundled PostgreSQL.
-
-### Standalone PostgreSQL using Omnibus GitLab **(CORE ONLY)**
-
-1. SSH into the PostgreSQL server.
-1. [Download/install](https://about.gitlab.com/install/) the Omnibus GitLab
- package you want using **steps 1 and 2** from the GitLab downloads page.
- - Do not complete any other steps on the download page.
-1. Generate a password hash for PostgreSQL. This assumes you will use the default
- username of `gitlab` (recommended). The command will request a password
- and confirmation. Use the value that is output by this command in the next
- step as the value of `POSTGRESQL_PASSWORD_HASH`.
-
- ```shell
- sudo gitlab-ctl pg-password-md5 gitlab
- ```
-
-1. Edit `/etc/gitlab/gitlab.rb` and add the contents below, updating placeholder
- values appropriately.
-
- - `POSTGRESQL_PASSWORD_HASH` - The value output from the previous step
- - `APPLICATION_SERVER_IP_BLOCKS` - A space delimited list of IP subnets or IP
- addresses of the GitLab application servers that will connect to the
- database. Example: `%w(123.123.123.123/32 123.123.123.234/32)`
-
- ```ruby
- # Disable all components except PostgreSQL
- roles ['postgres_role']
- repmgr['enable'] = false
- consul['enable'] = false
- prometheus['enable'] = false
- alertmanager['enable'] = false
- pgbouncer_exporter['enable'] = false
- redis_exporter['enable'] = false
- gitlab_exporter['enable'] = false
-
- postgresql['listen_address'] = '0.0.0.0'
- postgresql['port'] = 5432
-
- # Replace POSTGRESQL_PASSWORD_HASH with a generated md5 value
- postgresql['sql_user_password'] = 'POSTGRESQL_PASSWORD_HASH'
-
- # Replace XXX.XXX.XXX.XXX/YY with Network Address
- # ????
- postgresql['trust_auth_cidr_addresses'] = %w(APPLICATION_SERVER_IP_BLOCKS)
-
- # Disable automatic database migrations
- gitlab_rails['auto_migrate'] = false
- ```
-
- NOTE: **Note:** The role `postgres_role` was introduced with GitLab 10.3
-
-1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
-1. Note the PostgreSQL node's IP address or hostname, port, and
- plain text password. These will be necessary when configuring the GitLab
- application servers later.
-1. [Enable monitoring](#enable-monitoring)
-
-Advanced configuration options are supported and can be added if
-needed.
-
-### High Availability with Omnibus GitLab **(PREMIUM ONLY)**
-
-> Important notes:
->
-> - This document will focus only on configuration supported with [GitLab Premium](https://about.gitlab.com/pricing/), using the Omnibus GitLab package.
-> - If you are a Community Edition or Starter user, consider using a cloud hosted solution.
-> - This document will not cover installations from source.
->
-> - If HA setup is not what you were looking for, see the [database configuration document](https://docs.gitlab.com/omnibus/settings/database.html)
-> for the Omnibus GitLab packages.
->
-> Please read this document fully before attempting to configure PostgreSQL HA
-> for GitLab.
->
-> This configuration is GA in EE 10.2.
-
-The recommended configuration for a PostgreSQL HA requires:
-
-- A minimum of three database nodes
- - Each node will run the following services:
- - `PostgreSQL` - The database itself
- - `repmgrd` - A service to monitor, and handle failover in case of a failure
- - `Consul` agent - Used for service discovery, to alert other nodes when failover occurs
-- A minimum of three `Consul` server nodes
-- A minimum of one `pgbouncer` service 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 node
-
-You also need to take into consideration the underlying network topology,
-making sure you have redundant connectivity between all Database and GitLab instances,
-otherwise the networks will become a single point of failure.
-
-#### Architecture
-
-![PostgreSQL HA Architecture](img/pg_ha_architecture.png)
-
-Database nodes run two services with PostgreSQL:
-
-- Repmgrd. Monitors the cluster and handles failover when issues with the master occur. The failover consists of:
- - Selecting a new master for the cluster.
- - Promoting the new node to master.
- - Instructing remaining servers to follow the new master node.
-
- On failure, the old master node is automatically evicted from the cluster, and should be rejoined manually once recovered.
-- Consul. Monitors the status of each node in the database cluster and tracks its health in a service definition on the Consul cluster.
-
-Alongside each PgBouncer, there is a Consul agent that watches the status of the PostgreSQL service. If that status changes, Consul runs a script which updates the configuration and reloads PgBouncer
-
-##### 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:
-
-- 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)
-- Repmgr connects to the database servers [PostgreSQL default port](https://docs.gitlab.com/omnibus/package-information/defaults.html#postgresql)
-- 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)
-
-#### Required information
-
-Before proceeding with configuration, you will need to collect all the necessary
-information.
-
-##### Network information
-
-PostgreSQL does not listen on any network interface by default. It needs to know
-which IP address to listen on in order to be accessible to other services.
-Similarly, PostgreSQL access is controlled based on the network source.
-
-This is why you will need:
-
-- IP address of each nodes network interface. This can be set to `0.0.0.0` to
- listen on all interfaces. It cannot be set to the loopback address `127.0.0.1`.
-- Network Address. This can be in subnet (i.e. `192.168.0.0/255.255.255.0`)
- or CIDR (i.e. `192.168.0.0/24`) form.
-
-##### User information
-
-Various services require different configuration to secure
-the communication as well as information required for running the service.
-Bellow you will find details on each service and the minimum required
-information you need to provide.
-
-##### Consul information
-
-When using default setup, minimum configuration requires:
-
-- `CONSUL_USERNAME`. Defaults to `gitlab-consul`
-- `CONSUL_DATABASE_PASSWORD`. Password for the database user.
-- `CONSUL_PASSWORD_HASH`. This is a hash generated out of Consul username/password pair.
- Can be generated with:
-
- ```shell
- sudo gitlab-ctl pg-password-md5 CONSUL_USERNAME
- ```
-
-- `CONSUL_SERVER_NODES`. The IP addresses or DNS records of the Consul server nodes.
-
-Few notes on the service itself:
-
-- The service runs under a system account, by default `gitlab-consul`.
- - If you are using a different username, you will have to specify it. We
- will refer to it with `CONSUL_USERNAME`,
-- There will be a database user created with read only access to the repmgr
- database
-- Passwords will be stored in the following locations:
- - `/etc/gitlab/gitlab.rb`: hashed
- - `/var/opt/gitlab/pgbouncer/pg_auth`: hashed
- - `/var/opt/gitlab/consul/.pgpass`: plaintext
-
-##### PostgreSQL information
-
-When configuring PostgreSQL, we will set `max_wal_senders` to one more than
-the number of database nodes in the cluster.
-This is used to prevent replication from using up all of the
-available database connections.
-
-In this document we are assuming 3 database nodes, which makes this configuration:
-
-```ruby
-postgresql['max_wal_senders'] = 4
-```
-
-As previously mentioned, you'll have to prepare the network subnets that will
-be allowed to authenticate with the database.
-You'll also need to supply the IP addresses or DNS records of Consul
-server nodes.
-
-We will need the following password information for the application's database user:
-
-- `POSTGRESQL_USERNAME`. Defaults to `gitlab`
-- `POSTGRESQL_USER_PASSWORD`. The password for the database user
-- `POSTGRESQL_PASSWORD_HASH`. This is a hash generated out of the username/password pair.
- Can be generated with:
-
- ```shell
- sudo gitlab-ctl pg-password-md5 POSTGRESQL_USERNAME
- ```
-
-##### PgBouncer information
-
-When using default setup, minimum configuration requires:
-
-- `PGBOUNCER_USERNAME`. Defaults to `pgbouncer`
-- `PGBOUNCER_PASSWORD`. This is a password for PgBouncer service.
-- `PGBOUNCER_PASSWORD_HASH`. This is a hash generated out of PgBouncer username/password pair.
- Can be generated with:
-
- ```shell
- sudo gitlab-ctl pg-password-md5 PGBOUNCER_USERNAME
- ```
-
-- `PGBOUNCER_NODE`, is the IP address or a FQDN of the node running PgBouncer.
-
-Few notes on 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 will have to specify this username. We will refer to this requirement with `PGBOUNCER_USERNAME`.
-- The service will have a regular database user account generated for it
- - This defaults to `repmgr`
-- Passwords will be stored in the following locations:
- - `/etc/gitlab/gitlab.rb`: hashed, and in plain text
- - `/var/opt/gitlab/pgbouncer/pg_auth`: hashed
-
-##### Repmgr information
-
-When using default setup, you will only have to prepare the network subnets that will
-be allowed to authenticate with the service.
-
-Few notes on the service itself:
-
-- The service runs under the same system account as the database
- - In the package, this is by default `gitlab-psql`
-- The service will have a superuser database user account generated for it
- - This defaults to `gitlab_repmgr`
-
-#### Installing Omnibus GitLab
-
-First, make sure to [download/install](https://about.gitlab.com/install/)
-Omnibus GitLab **on each node**.
-
-Make sure you install the necessary dependencies from step 1,
-add GitLab package repository from step 2.
-When installing the GitLab package, do not supply `EXTERNAL_URL` value.
-
-#### Configuring the Database nodes
-
-1. Make sure to [configure the Consul nodes](consul.md).
-1. Make sure you collect [`CONSUL_SERVER_NODES`](#consul-information), [`PGBOUNCER_PASSWORD_HASH`](#pgbouncer-information), [`POSTGRESQL_PASSWORD_HASH`](#postgresql-information), the [number of db nodes](#postgresql-information), and the [network address](#network-information) before executing the next step.
-
-1. On the master database node, edit `/etc/gitlab/gitlab.rb` replacing values noted in the `# START user configuration` section:
-
- ```ruby
- # Disable all components except PostgreSQL and Repmgr and Consul
- roles ['postgres_role']
-
- # PostgreSQL configuration
- postgresql['listen_address'] = '0.0.0.0'
- postgresql['hot_standby'] = 'on'
- postgresql['wal_level'] = 'replica'
- postgresql['shared_preload_libraries'] = 'repmgr_funcs'
-
- # Disable automatic database migrations
- gitlab_rails['auto_migrate'] = false
-
- # Configure the Consul agent
- consul['services'] = %w(postgresql)
-
- # START user configuration
- # Please set the real values as explained in Required Information section
- #
- # Replace PGBOUNCER_PASSWORD_HASH with a generated md5 value
- postgresql['pgbouncer_user_password'] = 'PGBOUNCER_PASSWORD_HASH'
- # Replace POSTGRESQL_PASSWORD_HASH with a generated md5 value
- postgresql['sql_user_password'] = 'POSTGRESQL_PASSWORD_HASH'
- # Replace X with value of number of db nodes + 1
- postgresql['max_wal_senders'] = X
- postgresql['max_replication_slots'] = X
-
- # Replace XXX.XXX.XXX.XXX/YY with Network Address
- postgresql['trust_auth_cidr_addresses'] = %w(XXX.XXX.XXX.XXX/YY)
- repmgr['trust_auth_cidr_addresses'] = %w(127.0.0.1/32 XXX.XXX.XXX.XXX/YY)
-
- # Replace placeholders:
- #
- # Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z
- # with the addresses gathered for CONSUL_SERVER_NODES
- consul['configuration'] = {
- retry_join: %w(Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z)
- }
- #
- # END user configuration
- ```
-
- > `postgres_role` was introduced with GitLab 10.3
-
-1. On secondary nodes, add all the configuration specified above for primary node
- to `/etc/gitlab/gitlab.rb`. In addition, append the following configuration
- to inform `gitlab-ctl` that they are standby nodes initially and it need not
- attempt to register them as primary node
-
- ```ruby
- # HA setting to specify if a node should attempt to be master on initialization
- repmgr['master_on_initialization'] = false
- ```
-
-1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
-1. [Enable Monitoring](#enable-monitoring)
-
-> Please note:
->
-> - If you want your database to listen on a specific interface, change the config:
-> `postgresql['listen_address'] = '0.0.0.0'`.
-> - If your PgBouncer service runs under a different user account,
-> you also need to specify: `postgresql['pgbouncer_user'] = PGBOUNCER_USERNAME` in
-> your configuration.
-
-##### Database nodes post-configuration
-
-###### Primary node
-
-Select one node as a primary node.
-
-1. Open a database prompt:
-
- ```shell
- gitlab-psql -d gitlabhq_production
- ```
-
-1. Enable the `pg_trgm` extension:
-
- ```shell
- CREATE EXTENSION pg_trgm;
- ```
-
-1. Exit the database prompt by typing `\q` and Enter.
-
-1. Verify the cluster is initialized with one node:
-
- ```shell
- gitlab-ctl repmgr cluster show
- ```
-
- The output should be similar to the following:
-
- ```plaintext
- Role | Name | Upstream | Connection String
- ----------+----------|----------|----------------------------------------
- * master | HOSTNAME | | host=HOSTNAME user=gitlab_repmgr dbname=gitlab_repmgr
- ```
-
-1. Note down the hostname or IP address in the connection string: `host=HOSTNAME`. We will
- refer to the hostname in the next section as `MASTER_NODE_NAME`. If the value
- is not an IP address, it will need to be a resolvable name (via DNS or
- `/etc/hosts`)
-
-###### Secondary nodes
-
-1. Set up the repmgr standby:
-
- ```shell
- gitlab-ctl repmgr standby setup MASTER_NODE_NAME
- ```
-
- Do note that this will remove the existing data on the node. The command
- has a wait time.
-
- The output should be similar to the following:
-
- ```console
- # gitlab-ctl repmgr standby setup MASTER_NODE_NAME
- Doing this will delete the entire contents of /var/opt/gitlab/postgresql/data
- If this is not what you want, hit Ctrl-C now to exit
- To skip waiting, rerun with the -w option
- Sleeping for 30 seconds
- Stopping the database
- Removing the data
- Cloning the data
- Starting the database
- Registering the node with the cluster
- ok: run: repmgrd: (pid 19068) 0s
- ```
-
-1. Verify the node now appears in the cluster:
-
- ```shell
- gitlab-ctl repmgr cluster show
- ```
-
- The output should be similar to the following:
-
- ```plaintext
- Role | Name | Upstream | Connection String
- ----------+---------|-----------|------------------------------------------------
- * master | MASTER | | host=MASTER_NODE_NAME user=gitlab_repmgr dbname=gitlab_repmgr
- standby | STANDBY | MASTER | host=STANDBY_HOSTNAME user=gitlab_repmgr dbname=gitlab_repmgr
- ```
-
-Repeat the above steps on all secondary nodes.
-
-##### Database checkpoint
-
-Before moving on, make sure the databases are configured correctly. Run the
-following command on the **primary** node to verify that replication is working
-properly:
-
-```shell
-gitlab-ctl repmgr cluster show
-```
-
-The output should be similar to:
-
-```plaintext
-Role | Name | Upstream | Connection String
-----------+--------------|--------------|--------------------------------------------------------------------
-* master | MASTER | | host=MASTER port=5432 user=gitlab_repmgr dbname=gitlab_repmgr
- standby | STANDBY | MASTER | host=STANDBY port=5432 user=gitlab_repmgr dbname=gitlab_repmgr
-```
-
-If the 'Role' column for any node says "FAILED", check the
-[Troubleshooting section](#troubleshooting) before proceeding.
-
-Also, check that the check master command works successfully on each node:
-
-```shell
-su - gitlab-consul
-gitlab-ctl repmgr-check-master || echo 'This node is a standby repmgr node'
-```
-
-This command relies on exit codes to tell Consul whether a particular node is a master
-or secondary. The most important thing here is that this command does not produce errors.
-If there are errors it's most likely due to incorrect `gitlab-consul` database user permissions.
-Check the [Troubleshooting section](#troubleshooting) before proceeding.
-
-#### Configuring the PgBouncer node
-
-See our [documentation for PgBouncer](pgbouncer.md) for information on running PgBouncer as part of an HA setup.
-
-#### Configuring the Application nodes
-
-These will be the nodes running the `gitlab-rails` service. You may have other
-attributes set, but the following need to be set.
-
-1. Edit `/etc/gitlab/gitlab.rb`:
-
- ```ruby
- # Disable PostgreSQL on the application node
- postgresql['enable'] = false
-
- gitlab_rails['db_host'] = 'PGBOUNCER_NODE' or 'INTERNAL_LOAD_BALANCER'
- gitlab_rails['db_port'] = 6432
- gitlab_rails['db_password'] = 'POSTGRESQL_USER_PASSWORD'
- gitlab_rails['auto_migrate'] = false
- ```
-
-1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
-
-##### Application node post-configuration
-
-Ensure that all migrations ran:
-
-```shell
-gitlab-rake gitlab:db:configure
-```
-
-> **Note**: If you encounter a `rake aborted!` error stating that PgBouncer is failing to connect to
-PostgreSQL it may be that your PgBouncer node's IP address is missing from
-PostgreSQL's `trust_auth_cidr_addresses` in `gitlab.rb` on your database nodes. See
-[PgBouncer error `ERROR: pgbouncer cannot connect to server`](#pgbouncer-error-error-pgbouncer-cannot-connect-to-server)
-in the Troubleshooting section before proceeding.
-
-##### Ensure GitLab is running
-
-At this point, your GitLab instance should be up and running. Verify you are
-able to login, and create issues and merge requests. If you have troubles check
-the [Troubleshooting section](#troubleshooting).
-
-#### Example configuration
-
-Here we'll show you some fully expanded example configurations.
-
-##### Example recommended setup
-
-This example uses 3 Consul servers, 3 PgBouncer servers (with associated internal load balancer),
-3 PostgreSQL servers, and 1 application node.
-
-We start with all servers on the same 10.6.0.0/16 private network range, they
-can connect to each freely other on those addresses.
-
-Here is a list and description of each machine and the assigned IP:
-
-- `10.6.0.11`: Consul 1
-- `10.6.0.12`: Consul 2
-- `10.6.0.13`: Consul 3
-- `10.6.0.20`: Internal Load Balancer
-- `10.6.0.21`: PgBouncer 1
-- `10.6.0.22`: PgBouncer 2
-- `10.6.0.23`: PgBouncer 3
-- `10.6.0.31`: PostgreSQL master
-- `10.6.0.32`: PostgreSQL secondary
-- `10.6.0.33`: PostgreSQL secondary
-- `10.6.0.41`: GitLab application
-
-All passwords are set to `toomanysecrets`, please do not use this password or derived hashes and the `external_url` for GitLab is `http://gitlab.example.com`.
-
-Please note that after the initial configuration, if a failover occurs, the PostgresSQL master will change to one of the available secondaries until it is failed back.
-
-##### Example recommended setup for Consul servers
-
-On each server edit `/etc/gitlab/gitlab.rb`:
-
-```ruby
-# Disable all components except Consul
-roles ['consul_role']
-
-consul['configuration'] = {
- server: true,
- retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13)
-}
-consul['monitoring_service_discovery'] = true
-```
-
-[Reconfigure Omnibus GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
-
-##### Example recommended setup for PgBouncer servers
-
-On each server edit `/etc/gitlab/gitlab.rb`:
-
-```ruby
-# Disable all components except Pgbouncer and Consul agent
-roles ['pgbouncer_role']
-
-# Configure PgBouncer
-pgbouncer['admin_users'] = %w(pgbouncer gitlab-consul)
-
-pgbouncer['users'] = {
- 'gitlab-consul': {
- password: '5e0e3263571e3704ad655076301d6ebe'
- },
- 'pgbouncer': {
- password: '771a8625958a529132abe6f1a4acb19c'
- }
-}
-
-consul['watchers'] = %w(postgresql)
-consul['enable'] = true
-consul['configuration'] = {
- retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13)
-}
-consul['monitoring_service_discovery'] = true
-```
-
-[Reconfigure Omnibus GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
-
-##### Internal load balancer setup
-
-An internal load balancer (TCP) is then required to be setup to serve each PgBouncer node (in this example on the IP of `10.6.0.20`). An example of how to do this can be found in the [PgBouncer Configure Internal Load Balancer](pgbouncer.md#configure-the-internal-load-balancer) section.
-
-##### Example recommended setup for PostgreSQL servers
-
-###### Primary node
-
-On primary node edit `/etc/gitlab/gitlab.rb`:
-
-```ruby
-# Disable all components except PostgreSQL and Repmgr and Consul
-roles ['postgres_role']
-
-# PostgreSQL configuration
-postgresql['listen_address'] = '0.0.0.0'
-postgresql['hot_standby'] = 'on'
-postgresql['wal_level'] = 'replica'
-postgresql['shared_preload_libraries'] = 'repmgr_funcs'
-
-# Disable automatic database migrations
-gitlab_rails['auto_migrate'] = false
-
-postgresql['pgbouncer_user_password'] = '771a8625958a529132abe6f1a4acb19c'
-postgresql['sql_user_password'] = '450409b85a0223a214b5fb1484f34d0f'
-postgresql['max_wal_senders'] = 4
-
-postgresql['trust_auth_cidr_addresses'] = %w(10.6.0.0/16)
-repmgr['trust_auth_cidr_addresses'] = %w(10.6.0.0/16)
-
-# Configure the Consul agent
-consul['services'] = %w(postgresql)
-consul['enable'] = true
-consul['configuration'] = {
- retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13)
-}
-consul['monitoring_service_discovery'] = true
-```
-
-[Reconfigure Omnibus GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
-
-###### Secondary nodes
-
-On secondary nodes, edit `/etc/gitlab/gitlab.rb` and add all the configuration
-added to primary node, noted above. In addition, append the following
-configuration:
-
-```ruby
-# HA setting to specify if a node should attempt to be master on initialization
-repmgr['master_on_initialization'] = false
-```
-
-[Reconfigure Omnibus GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
-
-##### Example recommended setup for application server
-
-On the server edit `/etc/gitlab/gitlab.rb`:
-
-```ruby
-external_url 'http://gitlab.example.com'
-
-gitlab_rails['db_host'] = '10.6.0.20' # Internal Load Balancer for PgBouncer nodes
-gitlab_rails['db_port'] = 6432
-gitlab_rails['db_password'] = 'toomanysecrets'
-gitlab_rails['auto_migrate'] = false
-
-postgresql['enable'] = false
-pgbouncer['enable'] = false
-consul['enable'] = true
-
-# Configure Consul agent
-consul['watchers'] = %w(postgresql)
-
-pgbouncer['users'] = {
- 'gitlab-consul': {
- password: '5e0e3263571e3704ad655076301d6ebe'
- },
- 'pgbouncer': {
- password: '771a8625958a529132abe6f1a4acb19c'
- }
-}
-
-consul['configuration'] = {
- retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13)
-}
-```
-
-[Reconfigure Omnibus GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
-
-##### Example recommended setup manual steps
-
-After deploying the configuration follow these steps:
-
-1. On `10.6.0.31`, our primary database
-
- Enable the `pg_trgm` extension
-
- ```shell
- gitlab-psql -d gitlabhq_production
- ```
-
- ```shell
- CREATE EXTENSION pg_trgm;
- ```
-
-1. On `10.6.0.32`, our first standby database
-
- Make this node a standby of the primary
-
- ```shell
- gitlab-ctl repmgr standby setup 10.6.0.21
- ```
-
-1. On `10.6.0.33`, our second standby database
-
- Make this node a standby of the primary
-
- ```shell
- gitlab-ctl repmgr standby setup 10.6.0.21
- ```
-
-1. On `10.6.0.41`, our application server
-
- Set `gitlab-consul` user's PgBouncer password to `toomanysecrets`
-
- ```shell
- gitlab-ctl write-pgpass --host 127.0.0.1 --database pgbouncer --user pgbouncer --hostuser gitlab-consul
- ```
-
- Run database migrations
-
- ```shell
- gitlab-rake gitlab:db:configure
- ```
-
-#### Example minimal setup
-
-This example uses 3 PostgreSQL servers, and 1 application node (with PgBouncer setup alongside).
-
-It differs from the [recommended setup](#example-recommended-setup) by moving the Consul servers into the same servers we use for PostgreSQL.
-The trade-off is between reducing server counts, against the increased operational complexity of needing to deal with PostgreSQL [failover](#failover-procedure) and [restore](#restore-procedure) procedures in addition to [Consul outage recovery](consul.md#outage-recovery) on the same set of machines.
-
-In this example we start with all servers on the same 10.6.0.0/16 private network range, they can connect to each freely other on those addresses.
-
-Here is a list and description of each machine and the assigned IP:
-
-- `10.6.0.21`: PostgreSQL master
-- `10.6.0.22`: PostgreSQL secondary
-- `10.6.0.23`: PostgreSQL secondary
-- `10.6.0.31`: GitLab application
-
-All passwords are set to `toomanysecrets`, please do not use this password or derived hashes.
-
-The `external_url` for GitLab is `http://gitlab.example.com`
-
-Please note that after the initial configuration, if a failover occurs, the PostgresSQL master will change to one of the available secondaries until it is failed back.
-
-##### Example minimal configuration for database servers
-
-##### Primary node
-
-On primary database node edit `/etc/gitlab/gitlab.rb`:
-
-```ruby
-# Disable all components except PostgreSQL, Repmgr, and Consul
-roles ['postgres_role']
-
-# PostgreSQL configuration
-postgresql['listen_address'] = '0.0.0.0'
-postgresql['hot_standby'] = 'on'
-postgresql['wal_level'] = 'replica'
-postgresql['shared_preload_libraries'] = 'repmgr_funcs'
-
-# Disable automatic database migrations
-gitlab_rails['auto_migrate'] = false
-
-# Configure the Consul agent
-consul['services'] = %w(postgresql)
-
-postgresql['pgbouncer_user_password'] = '771a8625958a529132abe6f1a4acb19c'
-postgresql['sql_user_password'] = '450409b85a0223a214b5fb1484f34d0f'
-postgresql['max_wal_senders'] = 4
-
-postgresql['trust_auth_cidr_addresses'] = %w(10.6.0.0/16)
-repmgr['trust_auth_cidr_addresses'] = %w(10.6.0.0/16)
-
-consul['configuration'] = {
- server: true,
- retry_join: %w(10.6.0.21 10.6.0.22 10.6.0.23)
-}
-```
-
-[Reconfigure Omnibus GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
-
-###### Secondary nodes
-
-On secondary nodes, edit `/etc/gitlab/gitlab.rb` and add all the information added
-to primary node, noted above. In addition, append the following configuration
-
-```ruby
-# HA setting to specify if a node should attempt to be master on initialization
-repmgr['master_on_initialization'] = false
-```
-
-##### Example minimal configuration for application server
-
-On the server edit `/etc/gitlab/gitlab.rb`:
-
-```ruby
-external_url 'http://gitlab.example.com'
-
-gitlab_rails['db_host'] = '127.0.0.1'
-gitlab_rails['db_port'] = 6432
-gitlab_rails['db_password'] = 'toomanysecrets'
-gitlab_rails['auto_migrate'] = false
-
-postgresql['enable'] = false
-pgbouncer['enable'] = true
-consul['enable'] = true
-
-# Configure PgBouncer
-pgbouncer['admin_users'] = %w(pgbouncer gitlab-consul)
-
-# Configure Consul agent
-consul['watchers'] = %w(postgresql)
-
-pgbouncer['users'] = {
- 'gitlab-consul': {
- password: '5e0e3263571e3704ad655076301d6ebe'
- },
- 'pgbouncer': {
- password: '771a8625958a529132abe6f1a4acb19c'
- }
-}
-
-consul['configuration'] = {
- retry_join: %w(10.6.0.21 10.6.0.22 10.6.0.23)
-}
-```
-
-[Reconfigure Omnibus GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
-
-##### Example minimal setup manual steps
-
-The manual steps for this configuration are the same as for the [example recommended setup](#example-recommended-setup-manual-steps).
-
-#### Failover procedure
-
-By default, if the master database fails, `repmgrd` should promote one of the
-standby nodes to master automatically, and Consul will update PgBouncer with
-the new master.
-
-If you need to failover manually, you have two options:
-
-**Shutdown the current master database**
-
-Run:
-
-```shell
-gitlab-ctl stop postgresql
-```
-
-The automated failover process will see this and failover to one of the
-standby nodes.
-
-**Or perform a manual failover**
-
-1. Ensure the old master node is not still active.
-1. Login to the server that should become the new master and run:
-
- ```shell
- gitlab-ctl repmgr standby promote
- ```
-
-1. If there are any other standby servers in the cluster, have them follow
- the new master server:
-
- ```shell
- gitlab-ctl repmgr standby follow NEW_MASTER
- ```
-
-#### Restore procedure
-
-If a node fails, it can be removed from the cluster, or added back as a standby
-after it has been restored to service.
-
-##### Remove a standby from the cluster
-
- From any other node in the cluster, run:
-
- ```shell
- gitlab-ctl repmgr standby unregister --node=X
- ```
-
- where X is the value of node in `repmgr.conf` on the old server.
-
- To find this, you can use:
-
- ```shell
- awk -F = '$1 == "node" { print $2 }' /var/opt/gitlab/postgresql/repmgr.conf
- ```
-
- It will output something like:
-
- ```plaintext
- 959789412
- ```
-
- Then you will use this ID to unregister the node:
-
- ```shell
- gitlab-ctl repmgr standby unregister --node=959789412
- ```
-
-##### Add a node as a standby server
-
- From the stnadby node, run:
-
- ```shell
- gitlab-ctl repmgr standby follow NEW_MASTER
- gitlab-ctl restart repmgrd
- ```
-
- CAUTION: **Warning:** When the server is brought back online, and before
- you switch it to a standby node, repmgr will report that there are two masters.
- If there are any clients that are still attempting to write to the old master,
- this will cause a split, and the old master will need to be resynced from
- scratch by performing a `gitlab-ctl repmgr standby setup NEW_MASTER`.
-
-##### Add a failed master back into the cluster as a standby node
-
- Once `repmgrd` and PostgreSQL are runnning, the node will need to follow the new
- as a standby node.
-
- ```shell
- gitlab-ctl repmgr standby follow NEW_MASTER
- ```
-
- Once the node is following the new master as a standby, the node needs to be
- [unregistered from the cluster on the new master node](#remove-a-standby-from-the-cluster).
-
- Once the old master node has been unregistered from the cluster, it will need
- to be setup as a new standby:
-
- ```shell
- gitlab-ctl repmgr standby setup NEW_MASTER
- ```
-
- Failure to unregister and readd the old master node can lead to subsequent failovers
- not working.
-
-#### Alternate configurations
-
-##### Database authorization
-
-By default, we give any host on the database network the permission to perform
-repmgr operations using PostgreSQL's `trust` method. If you do not want this
-level of trust, there are alternatives.
-
-You can trust only the specific nodes that will be database clusters, or you
-can require md5 authentication.
-
-##### Trust specific addresses
-
-If you know the IP address, or FQDN of all database and PgBouncer nodes in the
-cluster, you can trust only those nodes.
-
-In `/etc/gitlab/gitlab.rb` on all of the database nodes, set
-`repmgr['trust_auth_cidr_addresses']` to an array of strings containing all of
-the addresses.
-
-If setting to a node's FQDN, they must have a corresponding PTR record in DNS.
-If setting to a node's IP address, specify it as `XXX.XXX.XXX.XXX/32`.
-
-For example:
-
-```ruby
-repmgr['trust_auth_cidr_addresses'] = %w(192.168.1.44/32 db2.example.com)
-```
-
-##### MD5 Authentication
-
-If you are running on an untrusted network, repmgr can use md5 authentication
-with a [`.pgpass` file](https://www.postgresql.org/docs/11/libpq-pgpass.html)
-to authenticate.
-
-You can specify by IP address, FQDN, or by subnet, using the same format as in
-the previous section:
-
-1. On the current master node, create a password for the `gitlab` and
- `gitlab_repmgr` user:
-
- ```shell
- gitlab-psql -d template1
- template1=# \password gitlab_repmgr
- Enter password: ****
- Confirm password: ****
- template1=# \password gitlab
- ```
-
-1. On each database node:
-
- 1. Edit `/etc/gitlab/gitlab.rb`:
- 1. Ensure `repmgr['trust_auth_cidr_addresses']` is **not** set
- 1. Set `postgresql['md5_auth_cidr_addresses']` to the desired value
- 1. Set `postgresql['sql_replication_user'] = 'gitlab_repmgr'`
- 1. Reconfigure with `gitlab-ctl reconfigure`
- 1. Restart PostgreSQL with `gitlab-ctl restart postgresql`
-
- 1. Create a `.pgpass` file. Enter the `gitlab_repmgr` password twice to
- when asked:
-
- ```shell
- gitlab-ctl write-pgpass --user gitlab_repmgr --hostuser gitlab-psql --database '*'
- ```
-
-1. On each PgBouncer node, edit `/etc/gitlab/gitlab.rb`:
- 1. Ensure `gitlab_rails['db_password']` is set to the plaintext password for
- the `gitlab` database user
- 1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect
-
-## Enable Monitoring
-
-> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/3786) in GitLab 12.0.
-
-If you enable Monitoring, it must be enabled on **all** database servers.
-
-1. Create/edit `/etc/gitlab/gitlab.rb` and add the following configuration:
-
- ```ruby
- # Enable service discovery for Prometheus
- consul['monitoring_service_discovery'] = true
-
- # Set the network addresses that the exporters will listen on
- node_exporter['listen_address'] = '0.0.0.0:9100'
- postgres_exporter['listen_address'] = '0.0.0.0:9187'
- ```
-
-1. Run `sudo gitlab-ctl reconfigure` to compile the configuration.
-
-## Troubleshooting
-
-### Consul and PostgreSQL changes not taking effect
-
-Due to the potential impacts, `gitlab-ctl reconfigure` only reloads Consul and PostgreSQL, it will not restart the services. However, not all changes can be activated by reloading.
-
-To restart either service, run `gitlab-ctl restart SERVICE`
-
-For PostgreSQL, it is usually safe to restart the master node by default. Automatic failover defaults to a 1 minute timeout. Provided the database returns before then, nothing else needs to be done. To be safe, you can stop `repmgrd` on the standby nodes first with `gitlab-ctl stop repmgrd`, then start afterwards with `gitlab-ctl start repmgrd`.
-
-On the Consul server nodes, it is important to restart the Consul service in a controlled fashion. Read our [Consul documentation](consul.md#restarting-the-server-cluster) for instructions on how to restart the service.
-
-### `gitlab-ctl repmgr-check-master` command produces errors
-
-If this command displays errors about database permissions it is likely that something failed during
-install, resulting in the `gitlab-consul` database user getting incorrect permissions. Follow these
-steps to fix the problem:
-
-1. On the master database node, connect to the database prompt - `gitlab-psql -d template1`
-1. Delete the `gitlab-consul` user - `DROP USER "gitlab-consul";`
-1. Exit the database prompt - `\q`
-1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) and the user will be re-added with the proper permissions.
-1. Change to the `gitlab-consul` user - `su - gitlab-consul`
-1. Try the check command again - `gitlab-ctl repmgr-check-master`.
-
-Now there should not be errors. If errors still occur then there is another problem.
-
-### PgBouncer error `ERROR: pgbouncer cannot connect to server`
-
-You may get this error when running `gitlab-rake gitlab:db:configure` or you
-may see the error in the PgBouncer log file.
-
-```plaintext
-PG::ConnectionBad: ERROR: pgbouncer cannot connect to server
-```
-
-The problem may be that your PgBouncer node's IP address is not included in the
-`trust_auth_cidr_addresses` setting in `/etc/gitlab/gitlab.rb` on the database nodes.
-
-You can confirm that this is the issue by checking the PostgreSQL log on the master
-database node. If you see the following error then `trust_auth_cidr_addresses`
-is the problem.
-
-```plaintext
-2018-03-29_13:59:12.11776 FATAL: no pg_hba.conf entry for host "123.123.123.123", user "pgbouncer", database "gitlabhq_production", SSL off
-```
-
-To fix the problem, add the IP address to `/etc/gitlab/gitlab.rb`.
-
-```ruby
-postgresql['trust_auth_cidr_addresses'] = %w(123.123.123.123/32 <other_cidrs>)
-```
-
-[Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
-
-### Issues with other components
-
-If you're running into an issue with a component not outlined here, be sure to check the troubleshooting section of their specific documentation page.
-
-- [Consul](consul.md#troubleshooting)
-- [PostgreSQL](https://docs.gitlab.com/omnibus/settings/database.html#troubleshooting)
-- [GitLab application](gitlab.md#troubleshooting)
-
-## Configure using Omnibus
-
-**Note**: We recommend that you follow the instructions here for a full [PostgreSQL cluster](#high-availability-with-omnibus-gitlab-premium-only).
-If you are reading this section due to an old bookmark, you can find that old documentation [in the repository](https://gitlab.com/gitlab-org/gitlab/blob/v10.1.4/doc/administration/high_availability/database.md#configure-using-omnibus).
-
-Read more on high-availability configuration:
-
-1. [Configure Redis](redis.md)
-1. [Configure NFS](nfs.md)
-1. [Configure the GitLab application servers](gitlab.md)
-1. [Configure the load balancers](load_balancer.md)
-1. [Manage the bundled Consul cluster](consul.md)
+This content has been moved to a [new location](../postgresql/replication_and_failover.md).
diff --git a/doc/administration/high_availability/gitaly.md b/doc/administration/high_availability/gitaly.md
index 2e6bcabeb06..230f5baf33a 100644
--- a/doc/administration/high_availability/gitaly.md
+++ b/doc/administration/high_availability/gitaly.md
@@ -1,4 +1,7 @@
---
+stage: Create
+group: Gitaly
+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
---
@@ -11,7 +14,7 @@ This document is relevant for [scalable and highly available setups](../referenc
## Running Gitaly on its own server
-See [Running Gitaly on its own server](../gitaly/index.md#running-gitaly-on-its-own-server)
+See [Run Gitaly on its own server](../gitaly/index.md#run-gitaly-on-its-own-server)
in Gitaly documentation.
Continue configuration of other components by going back to the
@@ -19,9 +22,9 @@ Continue configuration of other components by going back to the
## Enable Monitoring
-> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/3786) in GitLab 12.0.
+> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/3786) in GitLab 12.0.
-1. Make sure to collect [`CONSUL_SERVER_NODES`](database.md#consul-information), which are the IP addresses or DNS records of the Consul server nodes, for the next step. Note they are presented as `Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z`
+1. Make sure to collect [`CONSUL_SERVER_NODES`](../postgresql/replication_and_failover.md#consul-information), which are the IP addresses or DNS records of the Consul server nodes, for the next step. Note they are presented as `Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z`
1. Create/edit `/etc/gitlab/gitlab.rb` and add the following configuration:
diff --git a/doc/administration/high_availability/gitlab.md b/doc/administration/high_availability/gitlab.md
index cdafdbc4954..67a84f99bea 100644
--- a/doc/administration/high_availability/gitlab.md
+++ b/doc/administration/high_availability/gitlab.md
@@ -138,11 +138,11 @@ migrations performed.
## Enable Monitoring
-> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/3786) in GitLab 12.0.
+> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/3786) in GitLab 12.0.
If you enable Monitoring, it must be enabled on **all** GitLab servers.
-1. Make sure to collect [`CONSUL_SERVER_NODES`](database.md#consul-information), which are the IP addresses or DNS records of the Consul server nodes, for the next step. Note they are presented as `Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z`
+1. Make sure to collect [`CONSUL_SERVER_NODES`](../postgresql/replication_and_failover.md#consul-information), which are the IP addresses or DNS records of the Consul server nodes, for the next step. Note they are presented as `Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z`
1. Create/edit `/etc/gitlab/gitlab.rb` and add the following configuration:
@@ -178,7 +178,7 @@ If you enable Monitoring, it must be enabled on **all** GitLab servers.
running `sudo gitlab-ctl reconfigure`, it can take an extended period of time
for Unicorn to complete reloading after receiving a `HUP`. For more
information, see the
- [issue](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/4401).
+ [issue](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/4401).
## Troubleshooting
@@ -203,7 +203,7 @@ for more details.
Read more on high-availability configuration:
-1. [Configure the database](database.md)
+1. [Configure the database](../postgresql/replication_and_failover.md)
1. [Configure Redis](redis.md)
1. [Configure NFS](nfs.md)
1. [Configure the load balancers](load_balancer.md)
diff --git a/doc/administration/high_availability/load_balancer.md b/doc/administration/high_availability/load_balancer.md
index beeb57a0e32..75703327140 100644
--- a/doc/administration/high_availability/load_balancer.md
+++ b/doc/administration/high_availability/load_balancer.md
@@ -2,9 +2,9 @@
type: reference
---
-# Load Balancer for GitLab HA
+# Load Balancer for multi-node GitLab
-In an active/active GitLab configuration, you will need a load balancer to route
+In an multi-node GitLab configuration, you will need a load balancer to route
traffic to the application servers. The specifics on which load balancer to use
or the exact configuration is beyond the scope of GitLab documentation. We hope
that if you're managing HA systems like GitLab you have a load balancer of
@@ -14,7 +14,7 @@ you need to use with GitLab.
## SSL
-How will you handle SSL in your HA environment? There are several different
+How will you handle SSL in your multi-node environment? There are several different
options:
- Each application node terminates SSL
@@ -109,11 +109,15 @@ Configure DNS for an alternate SSH hostname such as `altssh.gitlab.example.com`.
| ------- | ------------ | -------- |
| 443 | 22 | TCP |
+## Readiness check
+
+It is strongly recommend that multi-node deployments configure load balancers to utilize the [readiness check](../../user/admin_area/monitoring/health_check.md#readiness) to ensure a node is ready to accept traffic, before routing traffic to it. This is especially important when utilizing Puma, as there is a brief period during a restart where Puma will not accept requests.
+
---
Read more on high-availability configuration:
-1. [Configure the database](database.md)
+1. [Configure the database](../postgresql/replication_and_failover.md)
1. [Configure Redis](redis.md)
1. [Configure NFS](nfs.md)
1. [Configure the GitLab application servers](gitlab.md)
diff --git a/doc/administration/high_availability/monitoring_node.md b/doc/administration/high_availability/monitoring_node.md
index 409a4dfecb9..653a0b32ad7 100644
--- a/doc/administration/high_availability/monitoring_node.md
+++ b/doc/administration/high_availability/monitoring_node.md
@@ -4,7 +4,7 @@ type: reference
# Configuring a Monitoring node for Scaling and High Availability
-> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/3786) in GitLab 12.0.
+> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/3786) in GitLab 12.0.
You can configure a Prometheus node to monitor GitLab.
@@ -22,7 +22,7 @@ Omnibus:
package you want using **steps 1 and 2** from the GitLab downloads page.
- Do not complete any other steps on the download page.
-1. Make sure to collect [`CONSUL_SERVER_NODES`](database.md#consul-information), which are the IP addresses or DNS records of the Consul server nodes, for the next step. Note they are presented as `Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z`
+1. Make sure to collect [`CONSUL_SERVER_NODES`](../postgresql/replication_and_failover.md#consul-information), which are the IP addresses or DNS records of the Consul server nodes, for the next step. Note they are presented as `Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z`
1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
diff --git a/doc/administration/high_availability/nfs.md b/doc/administration/high_availability/nfs.md
index d2b8cf65b35..6511f9bd85d 100644
--- a/doc/administration/high_availability/nfs.md
+++ b/doc/administration/high_availability/nfs.md
@@ -59,7 +59,7 @@ management between systems:
We recommend that all NFS users disable the NFS server delegation feature. This
is to avoid a [Linux kernel bug](https://bugzilla.redhat.com/show_bug.cgi?id=1552203)
which causes NFS clients to slow precipitously due to
-[excessive network traffic from numerous `TEST_STATEID` NFS messages](https://gitlab.com/gitlab-org/gitlab-foss/issues/52017).
+[excessive network traffic from numerous `TEST_STATEID` NFS messages](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/52017).
To disable NFS server delegation, do the following:
@@ -146,7 +146,7 @@ Additionally, this configuration is specifically warned against in the
>to the NFS server can cause data corruption problems.
For supported database architecture, please see our documentation on
-[Configuring a Database for GitLab HA](database.md).
+[Configuring a Database for GitLab HA](../postgresql/replication_and_failover.md).
## NFS Client mount options
@@ -164,7 +164,7 @@ Note there are several options that you should consider using:
| Setting | Description |
| ------- | ----------- |
-| `vers=4.1` |NFS v4.1 should be used instead of v4.0 because there is a Linux [NFS client bug in v4.0](https://gitlab.com/gitlab-org/gitaly/issues/1339) that can cause significant problems due to stale data.
+| `vers=4.1` |NFS v4.1 should be used instead of v4.0 because there is a Linux [NFS client bug in v4.0](https://gitlab.com/gitlab-org/gitaly/-/issues/1339) that can cause significant problems due to stale data.
| `nofail` | Don't halt boot process waiting for this mount to become available
| `lookupcache=positive` | Tells the NFS client to honor `positive` cache results but invalidates any `negative` cache results. Negative cache results cause problems with Git. Specifically, a `git push` can fail to register uniformly across all NFS clients. The negative cache causes the clients to 'remember' that the files did not exist previously.
| `hard` | Instead of `soft`. [Further details](#soft-mount-option).
@@ -194,7 +194,7 @@ use the `hard` option, because (from the man page):
Other vendors make similar recommendations, including
[SAP](http://wiki.scn.sap.com/wiki/x/PARnFQ) and NetApp's
-[knowledge base](https://kb.netapp.com/app/answers/answer_view/a_id/1004893/~/hard-mount-vs-soft-mount-),
+[knowledge base](https://kb.netapp.com/Advice_and_Troubleshooting/Data_Storage_Software/ONTAP_OS/What_are_the_differences_between_hard_mount_and_soft_mount),
they highlight that if the NFS client driver caches data, `soft` means there is no certainty if
writes by GitLab are actually on disk.
@@ -284,7 +284,7 @@ are empty before attempting a restore. Read more about the
Read more on high-availability configuration:
-1. [Configure the database](database.md)
+1. [Configure the database](../postgresql/replication_and_failover.md)
1. [Configure Redis](redis.md)
1. [Configure the GitLab application servers](gitlab.md)
1. [Configure the load balancers](load_balancer.md)
diff --git a/doc/administration/high_availability/pgbouncer.md b/doc/administration/high_availability/pgbouncer.md
index 4c672f49e26..15e4da5b1f7 100644
--- a/doc/administration/high_availability/pgbouncer.md
+++ b/doc/administration/high_availability/pgbouncer.md
@@ -12,124 +12,7 @@ In a HA setup, it's recommended to run a PgBouncer node separately for each data
### Running PgBouncer as part of an HA GitLab installation
-1. Make sure you collect [`CONSUL_SERVER_NODES`](database.md#consul-information), [`CONSUL_PASSWORD_HASH`](database.md#consul-information), and [`PGBOUNCER_PASSWORD_HASH`](database.md#pgbouncer-information) before executing the next step.
-
-1. One each node, edit the `/etc/gitlab/gitlab.rb` config file and replace values noted in the `# START user configuration` section as below:
-
- ```ruby
- # Disable all components except PgBouncer and Consul agent
- roles ['pgbouncer_role']
-
- # Configure PgBouncer
- pgbouncer['admin_users'] = %w(pgbouncer gitlab-consul)
-
- # Configure Consul agent
- consul['watchers'] = %w(postgresql)
-
- # START user configuration
- # Please set the real values as explained in Required Information section
- # Replace CONSUL_PASSWORD_HASH with with a generated md5 value
- # Replace PGBOUNCER_PASSWORD_HASH with with a generated md5 value
- pgbouncer['users'] = {
- 'gitlab-consul': {
- password: 'CONSUL_PASSWORD_HASH'
- },
- 'pgbouncer': {
- password: 'PGBOUNCER_PASSWORD_HASH'
- }
- }
- # Replace placeholders:
- #
- # Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z
- # with the addresses gathered for CONSUL_SERVER_NODES
- consul['configuration'] = {
- retry_join: %w(Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z)
- }
- #
- # END user configuration
- ```
-
- NOTE: **Note:**
- `pgbouncer_role` was introduced with GitLab 10.3.
-
-1. Run `gitlab-ctl reconfigure`
-
-1. Create a `.pgpass` file so Consul is able to
- reload PgBouncer. Enter the `PGBOUNCER_PASSWORD` twice when asked:
-
- ```shell
- gitlab-ctl write-pgpass --host 127.0.0.1 --database pgbouncer --user pgbouncer --hostuser gitlab-consul
- ```
-
-#### PgBouncer Checkpoint
-
-1. Ensure each node is talking to the current master:
-
- ```shell
- gitlab-ctl pgb-console # You will be prompted for PGBOUNCER_PASSWORD
- ```
-
- If there is an error `psql: ERROR: Auth failed` after typing in the
- password, ensure you previously generated the MD5 password hashes with the correct
- format. The correct format is to concatenate the password and the username:
- `PASSWORDUSERNAME`. For example, `Sup3rS3cr3tpgbouncer` would be the text
- needed to generate an MD5 password hash for the `pgbouncer` user.
-
-1. Once the console prompt is available, run the following queries:
-
- ```shell
- show databases ; show clients ;
- ```
-
- The output should be similar to the following:
-
- ```plaintext
- name | host | port | database | force_user | pool_size | reserve_pool | pool_mode | max_connections | current_connections
- ---------------------+-------------+------+---------------------+------------+-----------+--------------+-----------+-----------------+---------------------
- gitlabhq_production | MASTER_HOST | 5432 | gitlabhq_production | | 20 | 0 | | 0 | 0
- pgbouncer | | 6432 | pgbouncer | pgbouncer | 2 | 0 | statement | 0 | 0
- (2 rows)
-
- type | user | database | state | addr | port | local_addr | local_port | connect_time | request_time | ptr | link | remote_pid | tls
- ------+-----------+---------------------+---------+----------------+-------+------------+------------+---------------------+---------------------+-----------+------+------------+-----
- C | pgbouncer | pgbouncer | active | 127.0.0.1 | 56846 | 127.0.0.1 | 6432 | 2017-08-21 18:09:59 | 2017-08-21 18:10:48 | 0x22b3880 | | 0 |
- (2 rows)
- ```
-
-#### Configure the internal load balancer
-
-If you're running more than one PgBouncer node as recommended, then at this time you'll need to set up a TCP internal load balancer to serve each correctly. This can be done with any reputable TCP load balancer.
-
-As an example here's how you could do it with [HAProxy](https://www.haproxy.org/):
-
-```plaintext
-global
- log /dev/log local0
- log localhost local1 notice
- log stdout format raw local0
-
-defaults
- log global
- default-server inter 10s fall 3 rise 2
- balance leastconn
-
-frontend internal-pgbouncer-tcp-in
- bind *:6432
- mode tcp
- option tcplog
-
- default_backend pgbouncer
-
-backend pgbouncer
- mode tcp
- option tcp-check
-
- server pgbouncer1 <ip>:6432 check
- server pgbouncer2 <ip>:6432 check
- server pgbouncer3 <ip>:6432 check
-```
-
-Refer to your preferred Load Balancer's documentation for further guidance.
+This content has been moved to a [new location](../postgresql/replication_and_failover.md#configuring-the-pgbouncer-node).
### Running PgBouncer as part of a non-HA GitLab installation
@@ -179,7 +62,7 @@ Refer to your preferred Load Balancer's documentation for further guidance.
## Enable Monitoring
-> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/3786) in GitLab 12.0.
+> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/3786) in GitLab 12.0.
If you enable Monitoring, it must be enabled on **all** PgBouncer servers.
diff --git a/doc/administration/high_availability/redis.md b/doc/administration/high_availability/redis.md
index d52c80aec0d..bad50f7ca74 100644
--- a/doc/administration/high_availability/redis.md
+++ b/doc/administration/high_availability/redis.md
@@ -746,11 +746,11 @@ gitlab_rails['redis_sentinels'] = [
## Enable Monitoring
-> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/3786) in GitLab 12.0.
+> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/3786) in GitLab 12.0.
If you enable Monitoring, it must be enabled on **all** Redis servers.
-1. Make sure to collect [`CONSUL_SERVER_NODES`](database.md#consul-information), which are the IP addresses or DNS records of the Consul server nodes, for the next step. Note they are presented as `Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z`
+1. Make sure to collect [`CONSUL_SERVER_NODES`](../postgresql/replication_and_failover.md#consul-information), which are the IP addresses or DNS records of the Consul server nodes, for the next step. Note they are presented as `Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z`
1. Create/edit `/etc/gitlab/gitlab.rb` and add the following configuration:
@@ -1002,7 +1002,7 @@ Changes to Redis HA over time.
Read more on High Availability:
1. [High Availability Overview](README.md)
-1. [Configure the database](database.md)
+1. [Configure the database](../postgresql/replication_and_failover.md)
1. [Configure NFS](nfs.md)
1. [Configure the GitLab application servers](gitlab.md)
1. [Configure the load balancers](load_balancer.md)
diff --git a/doc/administration/housekeeping.md b/doc/administration/housekeeping.md
index 4a2e2b9aac9..4110f8b7646 100644
--- a/doc/administration/housekeeping.md
+++ b/doc/administration/housekeeping.md
@@ -1,6 +1,6 @@
# Housekeeping
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/3041) in GitLab 8.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/3041) in GitLab 8.4.
## Automatic housekeeping
diff --git a/doc/administration/incoming_email.md b/doc/administration/incoming_email.md
index fcd69464b13..e078a7c1098 100644
--- a/doc/administration/incoming_email.md
+++ b/doc/administration/incoming_email.md
@@ -1,3 +1,9 @@
+---
+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/#designated-technical-writers
+---
+
# Incoming email
GitLab has several features based on receiving incoming emails:
@@ -92,13 +98,13 @@ authenticate solely based on access to an email domain such as `*.hooli.com.`
Alternatively, use a dedicated domain for GitLab email communications such as
`hooli-gitlab.com`.
-See GitLab issue [#30366](https://gitlab.com/gitlab-org/gitlab-foss/issues/30366)
+See GitLab issue [#30366](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/30366)
for a real-world example of this exploit.
### Omnibus package installations
1. Find the `incoming_email` section in `/etc/gitlab/gitlab.rb`, enable the feature
- and fill in the details for your specific IMAP server and email account (see [examples](#config-examples) below).
+ and fill in the details for your specific IMAP server and email account (see [examples](#configuration-examples) below).
1. Reconfigure GitLab for the changes to take effect:
@@ -124,7 +130,7 @@ Reply by email should now be working.
```
1. Find the `incoming_email` section in `config/gitlab.yml`, enable the feature
- and fill in the details for your specific IMAP server and email account (see [examples](#config-examples) below).
+ and fill in the details for your specific IMAP server and email account (see [examples](#configuration-examples) below).
1. Enable `mail_room` in the init script at `/etc/default/gitlab`:
@@ -147,7 +153,7 @@ Reply by email should now be working.
Reply by email should now be working.
-### Config examples
+### Configuration examples
#### Postfix
diff --git a/doc/administration/index.md b/doc/administration/index.md
index fb827ae8573..fa415e5f78d 100644
--- a/doc/administration/index.md
+++ b/doc/administration/index.md
@@ -109,7 +109,7 @@ Learn how to install, configure, update, and maintain your GitLab instance.
- [Sign-up restrictions](../user/admin_area/settings/sign_up_restrictions.md): block email addresses of specific domains, or whitelist only specific domains.
- [Access restrictions](../user/admin_area/settings/visibility_and_access_controls.md#enabled-git-access-protocols): Define which Git access protocols can be used to talk to GitLab (SSH, HTTP, HTTPS).
- [Authentication and Authorization](auth/README.md): Configure external authentication with LDAP, SAML, CAS, and additional providers.
- - [Sync LDAP](auth/ldap-ee.md) **(STARTER ONLY)**
+ - [Sync LDAP](auth/ldap/index.md) **(STARTER ONLY)**
- [Kerberos authentication](../integration/kerberos.md) **(STARTER ONLY)**
- See also other [authentication](../topics/authentication/index.md#gitlab-administrators) topics (for example, enforcing 2FA).
- [Email users](../tools/email.md): Email GitLab users from within GitLab. **(STARTER ONLY)**
@@ -157,7 +157,7 @@ Learn how to install, configure, update, and maintain your GitLab instance.
- [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 Shared and specific Runners](../ci/runners/README.md#registering-a-shared-runner): Learn how to register and configure Shared and specific Runners to your own instance.
+- [Register Runners](../ci/runners/README.md#types-of-runners): Learn how to register and configure Runners.
- [Shared Runners pipelines quota](../user/admin_area/settings/continuous_integration.md#shared-runners-pipeline-minutes-quota-starter-only): Limit the usage of pipeline minutes for Shared Runners. **(STARTER ONLY)**
- [Enable/disable Auto DevOps](../topics/autodevops/index.md#enablingdisabling-auto-devops): Enable or disable Auto DevOps for your instance.
diff --git a/doc/administration/instance_limits.md b/doc/administration/instance_limits.md
index d0e8f079cb2..3d2f7380494 100644
--- a/doc/administration/instance_limits.md
+++ b/doc/administration/instance_limits.md
@@ -10,7 +10,7 @@ performance, data, or could even exhaust the allocated resources for the applica
## Number of comments per issue, merge request or commit
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/22388) in GitLab 12.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22388) in GitLab 12.4.
There's a limit to the number of comments that can be submitted on an issue,
merge request, or commit. When the limit is reached, system notes can still be
@@ -21,7 +21,7 @@ will fail.
## Size of comments and descriptions of issues, merge requests, and epics
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/61974) in GitLab 12.2.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/61974) in GitLab 12.2.
There is a limit to the size of comments and descriptions of issues, merge requests, and epics.
Attempting to add a body of text larger than the limit will result in an error, and the
@@ -43,7 +43,7 @@ When the number exceeds the limit the page displays an alert and links to a pagi
## Number of pipelines per Git push
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/51401) in GitLab 11.10.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/51401) in GitLab 11.10.
The number of pipelines that can be created in a single push is 4.
This is to prevent the accidental creation of pipelines when `git push --all`
@@ -53,9 +53,9 @@ Read more in the [CI documentation](../ci/yaml/README.md#processing-git-pushes).
## Retention of activity history
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/21164) in GitLab 8.12.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/21164) in GitLab 8.12.
-Activity history for projects and individuals' profiles was limited to one year until [GitLab 11.4](https://gitlab.com/gitlab-org/gitlab-foss/issues/52246) when it was extended to two years, and in [GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/issues/33840) to three years.
+Activity history for projects and individuals' profiles was limited to one year until [GitLab 11.4](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/52246) when it was extended to two years, and in [GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/-/issues/33840) to three years.
## Number of embedded metrics
@@ -87,7 +87,7 @@ NOTE: **Note:** Set the limit to `0` to disable it.
## Incoming emails from auto-responders
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/30327) in GitLab 12.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30327) in GitLab 12.4.
GitLab ignores all incoming emails sent from auto-responders by looking for the `X-Autoreply`
header. Such emails don't create comments on issues or merge requests.
@@ -126,7 +126,7 @@ NOTE: **Note:** Set the limit to `0` to disable it.
### Number of jobs in active pipelines
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/32823) in GitLab 12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32823) in GitLab 12.6.
The total number of jobs in active pipelines can be limited per project. This limit is checked
each time a new pipeline is created. An active pipeline is any pipeline in one of the following states:
@@ -156,7 +156,7 @@ NOTE: **Note:** Set the limit to `0` to disable it.
### Number of CI/CD subscriptions to a project
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/9045) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9045) in GitLab 12.9.
The total number of subscriptions can be limited per project. This limit is
checked each time a new subscription is created.
@@ -199,6 +199,24 @@ To set this limit on a self-managed installation, run the following in the
Plan.default.limits.update!(ci_pipeline_schedules: 100)
```
+### Number of instance level variables
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216097) in GitLab 13.1.
+
+The total number of instance level CI/CD variables is limited at the instance level.
+This limit is checked each time a new instance level variable is created. If a new variable
+would cause the total number of variables to exceed the limit, the new variable will not be created.
+
+On self-managed instances this limit is defined for the `default` plan. By default,
+this limit is set to `25`.
+
+To update this limit to a new value on a self-managed installation, run the following in the
+[GitLab Rails console](troubleshooting/debug.md#starting-a-rails-console-session):
+
+```ruby
+Plan.default.limits.update!(ci_instance_level_variables: 30)
+```
+
## Instance monitoring and metrics
### Incident Management inbound alert limits
@@ -235,7 +253,7 @@ Kubernetes won't be shown.
Reports that go over the 20 MB limit won't be loaded. Affected reports:
-- [Merge Request security reports](../user/project/merge_requests/index.md#security-reports-ultimate)
+- [Merge Request security reports](../user/project/merge_requests/testing_and_reports_in_merge_requests.md#security-reports-ultimate)
- [CI/CD parameter `artifacts:expose_as`](../ci/yaml/README.md#artifactsexpose_as)
- [JUnit test reports](../ci/junit_test_reports.md)
@@ -243,7 +261,7 @@ Reports that go over the 20 MB limit won't be loaded. Affected reports:
### Maximum field length
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/201826) in GitLab 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/201826) in GitLab 12.8.
You can set a limit on the content of text fields indexed for Global Search.
Setting a maximum helps to reduce the load of the indexing processes. If any
@@ -270,7 +288,7 @@ See the [documentation on Snippets settings](snippets/index.md).
### Webhooks and Project Services
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/31009) in GitLab 12.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/31009) in GitLab 12.4.
Total number of changes (branches or tags) in a single push. If changes are more
than the specified limit, hooks won't be executed.
@@ -282,7 +300,7 @@ More information can be found in these docs:
### Activities
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/31007) in GitLab 12.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/31007) in GitLab 12.4.
Total number of changes (branches or tags) in a single push to determine whether
individual push events or bulk push event will be created.
diff --git a/doc/administration/integration/plantuml.md b/doc/administration/integration/plantuml.md
index 3372d05bd6b..cd25fbf351b 100644
--- a/doc/administration/integration/plantuml.md
+++ b/doc/administration/integration/plantuml.md
@@ -105,6 +105,21 @@ To activate the changes, run the following command:
sudo gitlab-ctl reconfigure
```
+### Security
+
+PlantUML has features that allows fetching network resources.
+
+```plaintext
+@startuml
+start
+ ' ...
+ !include http://localhost/
+stop;
+@enduml
+```
+
+**If you self-host the PlantUML server, network controls should be put in place to isolate it.**
+
## GitLab
You need to enable PlantUML integration from Settings under Admin Area. To do
diff --git a/doc/administration/job_artifacts.md b/doc/administration/job_artifacts.md
index fbfad46ef65..0dbda67d39b 100644
--- a/doc/administration/job_artifacts.md
+++ b/doc/administration/job_artifacts.md
@@ -1,3 +1,10 @@
+---
+stage: Verify
+group: Continuous Integration
+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, howto
+---
+
# Jobs artifacts administration
> - Introduced in GitLab 8.2 and GitLab Runner 0.7.0.
@@ -40,6 +47,9 @@ GitLab Runner can upload an archive containing the job artifacts to GitLab. By d
this is done when the job succeeds, but can also be done on failure, or always, via the
[`artifacts:when`](../ci/yaml/README.md#artifactswhen) parameter.
+Most artifacts are compressed by GitLab Runner before being sent to the coordinator. The exception to this is
+[reports artifacts](../ci/pipelines/job_artifacts.md#artifactsreports), which are compressed after uploading.
+
### Using local storage
To change the location where the artifacts are stored locally, follow the steps
@@ -119,7 +129,7 @@ The connection settings match those provided by [Fog](https://github.com/fog), a
| `aws_signature_version` | AWS signature version to use. 2 or 4 are valid options. Digital Ocean Spaces and other providers may need 2. | 4 |
| `enable_signature_v4_streaming` | Set to true to enable HTTP chunked transfers with [AWS v4 signatures](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-streaming.html). Oracle Cloud S3 needs this to be false | true |
| `region` | AWS region | us-east-1 |
-| `host` | S3 compatible host for when not using AWS, e.g. `localhost` or `storage.example.com` | s3.amazonaws.com |
+| `host` | S3 compatible host for when not using AWS, for example `localhost` or `storage.example.com` | s3.amazonaws.com |
| `endpoint` | Can be used when configuring an S3 compatible service such as [MinIO](https://min.io), by entering a URL such as `http://127.0.0.1:9000` | (optional) |
| `path_style` | Set to true to use `host/bucket_name/object` style paths instead of `bucket_name.host/object`. Leave as false for AWS S3 | false |
| `use_iam_profile` | Set to true to use IAM profile instead of access keys | false
@@ -129,7 +139,7 @@ The connection settings match those provided by [Fog](https://github.com/fog), a
_The artifacts are stored by default in
`/var/opt/gitlab/gitlab-rails/shared/artifacts`._
-1. Edit `/etc/gitlab/gitlab.rb` and add the following lines by replacing with
+1. Edit `/etc/gitlab/gitlab.rb` and add the following lines, substituting
the values you want:
```ruby
@@ -144,7 +154,7 @@ _The artifacts are stored by default in
}
```
- NOTE: For GitLab 9.4+, if you are using AWS IAM profiles, be sure to omit the
+ NOTE: For GitLab 9.4+, if you're using AWS IAM profiles, be sure to omit the
AWS access key and secret access key/value pairs. For example:
```ruby
@@ -164,7 +174,7 @@ _The artifacts are stored by default in
CAUTION: **CAUTION:**
JUnit test report artifact (`junit.xml.gz`) migration
-[is not supported](https://gitlab.com/gitlab-org/gitlab/issues/27698)
+[is not supported](https://gitlab.com/gitlab-org/gitlab/-/issues/27698)
by the `gitlab:artifacts:migrate` script.
**In installations from source:**
@@ -197,7 +207,7 @@ _The artifacts are stored by default in
CAUTION: **CAUTION:**
JUnit test report artifact (`junit.xml.gz`) migration
-[is not supported](https://gitlab.com/gitlab-org/gitlab/issues/27698)
+[is not supported](https://gitlab.com/gitlab-org/gitlab/-/issues/27698)
by the `gitlab:artifacts:migrate` script.
### OpenStack compatible connection settings
@@ -209,8 +219,8 @@ The connection settings match those provided by [Fog](https://github.com/fog), a
| `provider` | Always `OpenStack` for compatible hosts | OpenStack |
| `openstack_username` | OpenStack username | |
| `openstack_api_key` | OpenStack API key | |
-| `openstack_temp_url_key` | OpenStack key for generating temporary urls | |
-| `openstack_auth_url` | OpenStack authentication endpont | |
+| `openstack_temp_url_key` | OpenStack key for generating temporary URLs | |
+| `openstack_auth_url` | OpenStack authentication endpoint | |
| `openstack_region` | OpenStack region | |
| `openstack_tenant_id` | OpenStack tenant ID |
@@ -219,7 +229,7 @@ The connection settings match those provided by [Fog](https://github.com/fog), a
_The uploads are stored by default in
`/var/opt/gitlab/gitlab-rails/shared/artifacts`._
-1. Edit `/etc/gitlab/gitlab.rb` and add the following lines by replacing with
+1. Edit `/etc/gitlab/gitlab.rb` and add the following lines, substituting
the values you want:
```ruby
@@ -296,17 +306,20 @@ In order to migrate back to local storage:
## Expiring artifacts
-If an expiry date is used for the artifacts, they are marked for deletion
-right after that date passes. Artifacts are cleaned up by the
-`expire_build_artifacts_worker` cron job which is run by Sidekiq every hour at
-50 minutes (`50 * * * *`).
+If [`artifacts:expire_in`](../ci/yaml/README.md#artifactsexpire_in) is used to set
+an expiry for the artifacts, they are marked for deletion right after that date passes.
+Otherwise, they will expire per the [default artifacts expiration setting](../user/admin_area/settings/continuous_integration.md).
+
+Artifacts are cleaned up by the `expire_build_artifacts_worker` cron job which Sidekiq
+runs every hour at 50 minutes (`50 * * * *`).
To change the default schedule on which the artifacts are expired, follow the
steps below.
**In Omnibus installations:**
-1. Edit `/etc/gitlab/gitlab.rb` and comment out or add the following line
+1. Edit `/etc/gitlab/gitlab.rb` and add the following line (or uncomment it if it already exists and is commented out), substituting
+ your schedule in cron syntax:
```ruby
gitlab_rails['expire_build_artifacts_worker_cron'] = "50 * * * *"
@@ -326,12 +339,15 @@ steps below.
1. Save the file and [restart GitLab](restart_gitlab.md#installations-from-source) for the changes to take effect.
+If the `expire` directive is not set explicitly in your pipeline, artifacts will expire per the
+default artifacts expiration setting, which you can find in the [CI/CD Admin settings](../user/admin_area/settings/continuous_integration.md).
+
## Validation for dependencies
> Introduced in GitLab 10.3.
To disable [the dependencies validation](../ci/yaml/README.md#when-a-dependent-job-will-fail),
-you can flip the feature flag from a Rails console.
+you can enable the `ci_disable_validates_dependencies` feature flag from a Rails console.
**In Omnibus installations:**
@@ -341,10 +357,10 @@ you can flip the feature flag from a Rails console.
sudo gitlab-rails console
```
-1. Flip the switch and disable it:
+1. Enable the feature flag to disable the validation:
```ruby
- Feature.enable('ci_disable_validates_dependencies')
+ Feature.enable(:ci_disable_validates_dependencies)
```
**In installations from source:**
@@ -356,15 +372,15 @@ you can flip the feature flag from a Rails console.
sudo -u git -H bundle exec rails console -e production
```
-1. Flip the switch and disable it:
+1. Enable the feature flag to disable the validation:
```ruby
- Feature.enable('ci_disable_validates_dependencies')
+ Feature.enable(:ci_disable_validates_dependencies)
```
## Set the maximum file size of the artifacts
-Provided the artifacts are enabled, you can change the maximum file size of the
+If artifacts are enabled, you can change the maximum file size of the
artifacts through the [Admin Area settings](../user/admin_area/settings/continuous_integration.md#maximum-artifacts-size-core-only).
## Storage statistics
@@ -404,6 +420,8 @@ In these and other cases, you'll need to identify the projects most responsible
for disk space usage, figure out what types of artifacts are using the most
space, and in some cases, manually delete job artifacts to reclaim disk space.
+One possible first step is to [clean up _orphaned_ artifact files](../raketasks/cleanup.md#remove-orphan-artifact-files).
+
#### List projects by total size of job artifacts stored
List the top 20 projects, sorted by the total size of job artifacts stored, by
@@ -488,7 +506,7 @@ highly recommend running them only under the guidance of a Support Engineer, or
running them in a test environment with a backup of the instance ready to be
restored, just in case.
-If you need to manually remove ALL job artifacts associated with multiple jobs,
+If you need to manually remove **all** job artifacts associated with multiple jobs,
**including job logs**, this can be done from the Rails console (`sudo gitlab-rails console`):
1. Select jobs to be deleted:
diff --git a/doc/administration/job_logs.md b/doc/administration/job_logs.md
index 5c03ff1f4b2..d3484536a76 100644
--- a/doc/administration/job_logs.md
+++ b/doc/administration/job_logs.md
@@ -1,6 +1,13 @@
+---
+stage: Verify
+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/#designated-technical-writers
+type: reference
+---
+
# Job logs
-> [Renamed from job traces to job logs](https://gitlab.com/gitlab-org/gitlab/issues/29121) in GitLab 12.5.
+> [Renamed from job traces to job logs](https://gitlab.com/gitlab-org/gitlab/-/issues/29121) in GitLab 12.5.
Job logs are sent by GitLab Runner while it's processing a job. You can see
logs in job pages, pipelines, email notifications, etc.
@@ -64,10 +71,19 @@ There isn't a way to automatically expire old job logs, but it's safe to remove
them if they're taking up too much space. If you remove the logs manually, the
job output in the UI will be empty.
+For example, to delete all job logs older than 60 days, run the following from a shell in your GitLab instance:
+
+DANGER: **Warning:**
+This command will permanently delete the log files and is irreversible.
+
+```shell
+find /var/opt/gitlab/gitlab-rails/shared/artifacts -name "job.log" -mtime +60 -delete
+```
+
## New incremental logging architecture
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/18169) in GitLab 10.4.
-> - [Announced as generally available](https://gitlab.com/gitlab-org/gitlab-foss/issues/46097) in GitLab 11.0.
+> - [Announced as generally available](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/46097) in GitLab 11.0.
NOTE: **Note:**
This feature is off by default. See below for how to [enable or disable](#enabling-incremental-logging) it.
@@ -112,13 +128,13 @@ sudo -u git -H bin/rails console -e production
**To check if incremental logging (trace) is enabled:**
```ruby
-Feature.enabled?('ci_enable_live_trace')
+Feature.enabled?(:ci_enable_live_trace)
```
**To enable incremental logging (trace):**
```ruby
-Feature.enable('ci_enable_live_trace')
+Feature.enable(:ci_enable_live_trace)
```
NOTE: **Note:**
diff --git a/doc/administration/lfs/index.md b/doc/administration/lfs/index.md
index e2b982448ef..dd0e25b05f1 100644
--- a/doc/administration/lfs/index.md
+++ b/doc/administration/lfs/index.md
@@ -110,7 +110,7 @@ Here is a configuration example with GCS.
| `provider` | The provider name | `Google` |
| `google_project` | GCP project name | `gcp-project-12345` |
| `google_client_email` | The email address of the service account | `foo@gcp-project-12345.iam.gserviceaccount.com` |
-| `google_json_key_location` | The json key path | `/path/to/gcp-project-12345-abcde.json` |
+| `google_json_key_location` | The JSON key path | `/path/to/gcp-project-12345-abcde.json` |
NOTE: **Note:**
The service account must have permission to access the bucket.
diff --git a/doc/administration/libravatar.md b/doc/administration/libravatar.md
index e1c38b3409f..beecd9e4783 100644
--- a/doc/administration/libravatar.md
+++ b/doc/administration/libravatar.md
@@ -37,7 +37,7 @@ the configuration options as follows:
### Your own Libravatar server
-If you are [running your own libravatar service](https://wiki.libravatar.org/running_your_own/),
+If you are [running your own Libravatar service](https://wiki.libravatar.org/running_your_own/),
the URL will be different in the configuration, but you must provide the same
placeholders so GitLab can parse the URL correctly.
diff --git a/doc/administration/logs.md b/doc/administration/logs.md
index 57b12897979..7d7053a26db 100644
--- a/doc/administration/logs.md
+++ b/doc/administration/logs.md
@@ -46,6 +46,8 @@ Line breaks have been added to this example for legibility:
"gitaly_duration_s":0.16,
"redis_calls":115,
"redis_duration_s":0.13,
+ "redis_read_bytes":1507378,
+ "redis_write_bytes":2920,
"correlation_id":"O1SdybnnIq7",
"cpu_s":17.50,
"db_duration_s":0.08,
@@ -56,23 +58,60 @@ Line breaks have been added to this example for legibility:
This example was a GET request for a specific
issue. Each line also contains performance data, with times in
-milliseconds:
+seconds:
1. `duration_s`: total time taken to retrieve the request
1. `queue_duration_s`: total time that the request was queued inside GitLab Workhorse
1. `view_duration_s`: total time taken inside the Rails views
1. `db_duration_s`: total time to retrieve data from PostgreSQL
-1. `redis_duration_s`: total time to retrieve data from Redis
1. `cpu_s`: total time spent on CPU
1. `gitaly_duration_s`: total time taken by Gitaly calls
1. `gitaly_calls`: total number of calls made to Gitaly
1. `redis_calls`: total number of calls made to Redis
+1. `redis_duration_s`: total time to retrieve data from Redis
+1. `redis_read_bytes`: total bytes read from Redis
+1. `redis_write_bytes`: total bytes written to Redis
+1. `redis_<instance>_calls`: total number of calls made to a Redis instance
+1. `redis_<instance>_duration_s`: total time to retrieve data from a Redis instance
+1. `redis_<instance>_read_bytes`: total bytes read from a Redis instance
+1. `redis_<instance>_write_bytes`: total bytes written to a Redis instance
User clone and fetch activity using HTTP transport appears in this log as `action: git_upload_pack`.
In addition, the log contains the originating IP address,
(`remote_ip`),the user's ID (`user_id`), and username (`username`).
+Some endpoints such as `/search` may make requests to Elasticsearch if using
+[Advanced Global Search](../user/search/advanced_global_search.md). These will
+additionally log `elasticsearch_calls` and `elasticsearch_call_duration_s`,
+which correspond to:
+
+1. `elasticsearch_calls`: total number of calls to Elasticsearch
+1. `elasticsearch_duration_s`: total time taken by Elasticsearch calls
+
+ActionCable connection and subscription events are also logged to this file and they follow the same
+format above. The `method`, `path`, and `format` fields are not applicable, and are always empty.
+The ActionCable connection or channel class is used as the `controller`.
+
+```json
+{
+ "method":{},
+ "path":{},
+ "format":{},
+ "controller":"IssuesChannel",
+ "action":"subscribe",
+ "status":200,
+ "time":"2020-05-14T19:46:22.008Z",
+ "params":[{"key":"project_path","value":"gitlab/gitlab-foss"},{"key":"iid","value":"1"}],
+ "remote_ip":"127.0.0.1",
+ "user_id":1,
+ "username":"admin",
+ "ua":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:76.0) Gecko/20100101 Firefox/76.0",
+ "correlation_id":"jSOIEynHCUa",
+ "duration_s":0.32566
+}
+```
+
NOTE: **Note:** Starting with GitLab 12.5, if an error occurs, an
`exception` field is included with `class`, `message`, and
`backtrace`. Previous versions included an `error` field instead of
@@ -218,7 +257,7 @@ October 07, 2014 11:25: Project "project133" was removed
## `application_json.log`
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/22812) in GitLab 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22812) in GitLab 12.7.
This file lives in `/var/log/gitlab/gitlab-rails/application_json.log` for
Omnibus GitLab packages or in `/home/git/gitlab/log/application_json.log` for
@@ -340,7 +379,7 @@ only. For example:
## `audit_json.log`
NOTE: **Note:**
-Most log entries only exist in [GitLab Starter](https://about.gitlab.com/pricing), however a few exist in GitLab Core.
+Most log entries only exist in [GitLab Starter](https://about.gitlab.com/pricing/), however a few exist in GitLab Core.
This file lives in `/var/log/gitlab/gitlab-rails/audit_json.log` for
Omnibus GitLab packages or in `/home/git/gitlab/log/audit_json.log` for
@@ -593,6 +632,16 @@ installations from source.
It logs the progress of the import process.
+## `exporter.log`
+
+> Introduced in GitLab 13.1.
+
+This file lives in `/var/log/gitlab/gitlab-rails/exporter.log` for
+Omnibus GitLab packages or in `/home/git/gitlab/log/exporter.log` for
+installations from source.
+
+It logs the progress of the export process.
+
## `auth.log`
> Introduced in GitLab 12.0.
@@ -608,12 +657,12 @@ This log records:
- [Protected paths](../user/admin_area/settings/protected_paths.md) abusive requests.
NOTE: **Note:**
-From [%12.1](https://gitlab.com/gitlab-org/gitlab-foss/issues/62756), user ID and username are also
+From [%12.3](https://gitlab.com/gitlab-org/gitlab/-/issues/29239), user ID and username are also
recorded on this log, if available.
## `graphql_json.log`
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/59587) in GitLab 12.0.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/59587) in GitLab 12.0.
This file lives in `/var/log/gitlab/gitlab-rails/graphql_json.log` for
Omnibus GitLab packages or in `/home/git/gitlab/log/graphql_json.log` for
@@ -724,17 +773,6 @@ Each line contains a JSON line that can be ingested by Elasticsearch. For exampl
"severity": "ERROR",
"time": "2019-12-17T11:49:29.485Z",
"correlation_id": "AbDVUrrTvM1",
- "extra.server": {
- "os": {
- "name": "Darwin",
- "version": "Darwin Kernel Version 19.2.0",
- "build": "19.2.0",
- },
- "runtime": {
- "name": "ruby",
- "version": "ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-darwin18]"
- }
- },
"extra.project_id": 55,
"extra.relation_key": "milestones",
"extra.relation_index": 1,
@@ -756,7 +794,7 @@ Omnibus GitLab packages or in `/home/git/gitlab/log/service_measurement.log` for
installations from source.
It contain only a single structured log with measurements for each service execution.
-It will contain measurement such as: number of sql calls, execution_time, gc_stats, memory usage, etc...
+It will contain measurement such as: number of SQL calls, `execution_time`, `gc_stats`, memory usage, etc...
For example:
diff --git a/doc/administration/merge_request_diffs.md b/doc/administration/merge_request_diffs.md
index 795933e2772..da9ca42ed9e 100644
--- a/doc/administration/merge_request_diffs.md
+++ b/doc/administration/merge_request_diffs.md
@@ -1,6 +1,6 @@
# Merge request diffs storage **(CORE ONLY)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/52568) in GitLab 11.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/52568) in GitLab 11.8.
Merge request diffs are size-limited copies of diffs associated with merge
requests. When viewing a merge request, diffs are sourced from these copies
diff --git a/doc/administration/monitoring/github_imports.md b/doc/administration/monitoring/github_imports.md
index 6d5915930b2..21cc4c708a8 100644
--- a/doc/administration/monitoring/github_imports.md
+++ b/doc/administration/monitoring/github_imports.md
@@ -1,3 +1,9 @@
+---
+stage: Monitor
+group: APM
+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
+---
+
# Monitoring GitHub imports
>**Note:**
diff --git a/doc/administration/monitoring/gitlab_self_monitoring_project/index.md b/doc/administration/monitoring/gitlab_self_monitoring_project/index.md
index 091da46f316..d05fb803c5c 100644
--- a/doc/administration/monitoring/gitlab_self_monitoring_project/index.md
+++ b/doc/administration/monitoring/gitlab_self_monitoring_project/index.md
@@ -1,7 +1,13 @@
+---
+stage: Monitor
+group: APM
+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 self monitoring project
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/32351) in GitLab 12.7, behind a disabled feature flag (`self_monitoring_project`).
-> - The feature flag was removed and the Self Monitoring Project was [made generally available](https://gitlab.com/gitlab-org/gitlab/issues/198511) in GitLab 12.8.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32351) in GitLab 12.7, behind a disabled feature flag (`self_monitoring_project`).
+> - The feature flag was removed and the Self Monitoring Project was [made generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/198511) in GitLab 12.8.
GitLab has been adding the ability for administrators to see insights into the health of
their GitLab instance. In order to surface this experience in a native way, similar to how
@@ -15,10 +21,12 @@ All administrators at the time of creation of the project and group will be adde
as maintainers of the group and project, and as an admin, you'll be able to add new
members to the group in order to give them maintainer access to the project.
-This project is used to self monitor your GitLab instance. Metrics are not yet
-fully integrated, and the dashboard does not aggregate any data on Omnibus installations. GitLab plans
-to provide integrated self-monitoring metrics in a future release. You can
-currently use the project to configure your own [custom metrics](../../../user/project/integrations/prometheus.md#adding-custom-metrics) using
+This project is used to self monitor your GitLab instance. The metrics dashboard
+of the project shows some basic resource usage charts, such as CPU and memory usage
+of each server in [Omnibus GitLab](https://docs.gitlab.com/omnibus/) installations.
+
+You can also use the project to configure your own
+[custom metrics](../../../user/project/integrations/prometheus.md#adding-custom-metrics) using
metrics exposed by the [GitLab exporter](../prometheus/gitlab_metrics.md#metrics-available).
## Creating the self monitoring project
@@ -53,7 +61,7 @@ you should
## Taking action on Prometheus alerts **(ULTIMATE)**
You can [add a webhook](../../../user/project/integrations/prometheus.md#external-prometheus-instances)
-to the Prometheus config in order for GitLab to receive notifications of any alerts.
+to the Prometheus configuration in order for GitLab to receive notifications of any alerts.
Once the webhook is setup, you can
[take action on incoming alerts](../../../user/project/integrations/prometheus.md#taking-action-on-incidents-ultimate).
@@ -69,7 +77,7 @@ You can add custom metrics in the self monitoring project by:
### Getting error message in logs: `Could not create instance administrators group. Errors: ["You don’t have permission to create groups."]`
-There is [a bug](https://gitlab.com/gitlab-org/gitlab/issues/208676) which causes
+There is [a bug](https://gitlab.com/gitlab-org/gitlab/-/issues/208676) which causes
project creation to fail with the following error (which appears in the log file)
when the first admin user is an
[external user](../../../user/permissions.md#external-users-core-only):
diff --git a/doc/administration/monitoring/index.md b/doc/administration/monitoring/index.md
index 1d7c52a198f..a54c25450c6 100644
--- a/doc/administration/monitoring/index.md
+++ b/doc/administration/monitoring/index.md
@@ -1,3 +1,9 @@
+---
+stage: Monitor
+group: APM
+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
+---
+
# Monitoring GitLab
Explore our features to monitor your GitLab instance:
diff --git a/doc/administration/monitoring/ip_whitelist.md b/doc/administration/monitoring/ip_whitelist.md
index 1b0ea1744d9..862a9368be8 100644
--- a/doc/administration/monitoring/ip_whitelist.md
+++ b/doc/administration/monitoring/ip_whitelist.md
@@ -1,3 +1,9 @@
+---
+stage: Monitor
+group: APM
+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
+---
+
# IP whitelist
> Introduced in GitLab 9.4.
diff --git a/doc/administration/monitoring/performance/gitlab_configuration.md b/doc/administration/monitoring/performance/gitlab_configuration.md
index 14119a5d8f3..d09dabab40d 100644
--- a/doc/administration/monitoring/performance/gitlab_configuration.md
+++ b/doc/administration/monitoring/performance/gitlab_configuration.md
@@ -1,3 +1,9 @@
+---
+stage: Monitor
+group: APM
+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 Configuration
GitLab Performance Monitoring is disabled by default. To enable it and change any of its
diff --git a/doc/administration/monitoring/performance/grafana_configuration.md b/doc/administration/monitoring/performance/grafana_configuration.md
index 3438a564d2f..4dbe3aed84e 100644
--- a/doc/administration/monitoring/performance/grafana_configuration.md
+++ b/doc/administration/monitoring/performance/grafana_configuration.md
@@ -1,3 +1,9 @@
+---
+stage: Monitor
+group: APM
+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
+---
+
# Grafana Configuration
[Grafana](https://grafana.com/) is a tool that allows you to visualize time
@@ -57,7 +63,7 @@ repository for more information on this process.
## Integration with GitLab UI
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/61005) in GitLab 12.1.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/61005) in GitLab 12.1.
If you have set up Grafana, you can enable a link to access it easily from the sidebar:
diff --git a/doc/administration/monitoring/performance/img/request_profiling_token.png b/doc/administration/monitoring/performance/img/request_profiling_token.png
deleted file mode 100644
index ee819fcb437..00000000000
--- a/doc/administration/monitoring/performance/img/request_profiling_token.png
+++ /dev/null
Binary files differ
diff --git a/doc/administration/monitoring/performance/index.md b/doc/administration/monitoring/performance/index.md
index 02070287611..6f22327e499 100644
--- a/doc/administration/monitoring/performance/index.md
+++ b/doc/administration/monitoring/performance/index.md
@@ -1,3 +1,9 @@
+---
+stage: Monitor
+group: APM
+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 Performance Monitoring
GitLab comes with its own application performance measuring system as of GitLab
diff --git a/doc/administration/monitoring/performance/performance_bar.md b/doc/administration/monitoring/performance/performance_bar.md
index 89246bc9782..c681dedbca8 100644
--- a/doc/administration/monitoring/performance/performance_bar.md
+++ b/doc/administration/monitoring/performance/performance_bar.md
@@ -1,3 +1,9 @@
+---
+stage: Monitor
+group: APM
+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
+---
+
# Performance Bar
A Performance Bar can be displayed, to dig into the performance of a page. When
@@ -18,7 +24,7 @@ It allows you to see (from left to right):
![Redis profiling using the Performance Bar](img/performance_bar_redis_calls.png)
- total load timings of the page; click through for details of these calls. Values in the following order:
- Backend - Time that the actual base page took to load
- - [First Contentful Paint](https://developers.google.com/web/tools/lighthouse/audits/first-contentful-paint) - Time until something was visible to the user
+ - [First Contentful Paint](hhttps://web.dev/first-contentful-paint/) - Time until something was visible to the user
- [DomContentLoaded](https://developers.google.com/web/fundamentals/performance/critical-rendering-path/measure-crp) Event
- Number of Requests that the page loaded
![Frontend requests using the Performance Bar](img/performance_bar_frontend.png)
diff --git a/doc/administration/monitoring/performance/request_profiling.md b/doc/administration/monitoring/performance/request_profiling.md
index c32edb60f9d..a3b29493d84 100644
--- a/doc/administration/monitoring/performance/request_profiling.md
+++ b/doc/administration/monitoring/performance/request_profiling.md
@@ -1,17 +1,39 @@
+---
+stage: Monitor
+group: APM
+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
+---
+
# Request Profiling
-## Procedure
+To profile a request:
+
+1. Sign in to GitLab as a user with Administrator or Maintainer [permissions](../../../user/permissions.md).
+1. In the navigation bar, click **{admin}** **Admin area**.
+1. Navigate to **{monitor}** **Monitoring > Requests Profiles**.
+1. In the **Requests Profiles** section, copy the token.
+1. Pass the headers `X-Profile-Token: <token>` and `X-Profile-Mode: <mode>`(where
+ `<mode>` can be `execution` or `memory`) to the request you want to profile. When
+ passing headers, you can use:
+
+ - Browser extensions such as the
+ [ModHeader](https://chrome.google.com/webstore/detail/modheader/idgpnmonknjnojddfkpgkljpfnnfcklj)
+ Chrome extension.
+ - `curl`. For example:
+
+ ```shell
+ curl --header 'X-Profile-Token: <token>' --header 'X-Profile-Mode: <mode>' "https://gitlab.example.com/group/project"
+ ```
+
+ NOTE: **Note:**
+ Profiled requests can take longer than usual.
+
+After the request completes, you can view the profiling output from the
+**{monitor}** **Monitoring > Requests Profiles** administration page:
-1. Grab the profiling token from **Monitoring > Requests Profiles** admin page
- (highlighted in a blue in the image below).
- ![Profile token](img/request_profiling_token.png)
-1. Pass the header `X-Profile-Token: <token>` and `X-Profile-Mode: <mode>`(where `<mode>` can be `execution` or `memory`) to the request you want to profile. You can use:
- - Browser extensions. For example, [ModHeader](https://chrome.google.com/webstore/detail/modheader/idgpnmonknjnojddfkpgkljpfnnfcklj) Chrome extension.
- - `curl`. For example, `curl --header 'X-Profile-Token: <token>' --header 'X-Profile-Mode: <mode>' https://gitlab.example.com/group/project`.
-1. Once request is finished (which will take a little longer than usual), you can
- view the profiling output from **Monitoring > Requests Profiles** admin page.
- ![Profiling output](img/request_profile_result.png)
+![Profiling output](img/request_profile_result.png)
-## Cleaning up
+## Cleaning up profiled requests
-Profiling output will be cleared out every day via a Sidekiq worker.
+The output from profiled requests is cleared out once each day through a
+Sidekiq worker.
diff --git a/doc/administration/monitoring/prometheus/gitlab_metrics.md b/doc/administration/monitoring/prometheus/gitlab_metrics.md
index f725db9a039..f3084b1732e 100644
--- a/doc/administration/monitoring/prometheus/gitlab_metrics.md
+++ b/doc/administration/monitoring/prometheus/gitlab_metrics.md
@@ -6,30 +6,29 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# GitLab Prometheus metrics
->**Note:**
-Available since [Omnibus GitLab 9.3](https://gitlab.com/gitlab-org/gitlab-foss/issues/29118). For
-installations from source you'll have to configure it yourself.
-
To enable the GitLab Prometheus metrics:
-1. Log into GitLab as an administrator.
-1. Navigate to **Admin Area > Settings > Metrics and profiling**.
+1. Log into GitLab as a user with [administrator permissions](../../../user/permissions.md).
+1. Navigate to **{admin}** **Admin Area > Settings > Metrics and profiling**.
1. Find the **Metrics - Prometheus** section, and click **Enable Prometheus Metrics**.
1. [Restart GitLab](../../restart_gitlab.md#omnibus-gitlab-restart) for the changes to take effect.
+NOTE: **Note:**
+For installations from source you'll have to configure it yourself.
+
## Collecting the metrics
GitLab monitors its own internal service metrics, and makes them available at the
-`/-/metrics` endpoint. Unlike other [Prometheus](https://prometheus.io) exporters, in order to access
-it, the client IP needs to be [included in a whitelist](../ip_whitelist.md).
+`/-/metrics` endpoint. Unlike other [Prometheus](https://prometheus.io) exporters, to access
+it, the client IP address needs to be [explicitly allowed](../ip_whitelist.md).
-For Omnibus and Chart installations, these metrics are automatically enabled
-and collected as of [GitLab
-9.4](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/1702). For
-source installations or earlier versions, these metrics will need to be enabled
+For [Omnibus GitLab](https://docs.gitlab.com/omnibus/) and Chart installations,
+these metrics are enabled and collected as of
+[GitLab 9.4](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/1702).
+For source installations or earlier versions, these metrics must be enabled
manually and collected by a Prometheus server.
-See also [Sidekiq metrics](#sidekiq-metrics) for how to enable and view metrics from Sidekiq nodes.
+For enabling and viewing metrics from Sidekiq nodes, see [Sidekiq metrics](#sidekiq-metrics).
## Metrics available
@@ -43,32 +42,33 @@ The following metrics are available:
| `gitlab_cache_operation_duration_seconds` | Histogram | 10.2 | Cache access time | |
| `gitlab_cache_operations_total` | Counter | 12.2 | Cache operations by controller/action | `controller`, `action`, `operation` |
| `gitlab_ci_pipeline_creation_duration_seconds` | Histogram | 13.0 | Time in seconds it takes to create a CI/CD pipeline | |
+| `gitlab_ci_pipeline_size_builds` | Histogram | 13.1 | Total number of builds within a pipeline grouped by a pipeline source | `source` |
| `job_waiter_started_total` | Counter | 12.9 | Number of batches of jobs started where a web request is waiting for the jobs to complete | `worker` |
| `job_waiter_timeouts_total` | Counter | 12.9 | Number of batches of jobs that timed out where a web request is waiting for the jobs to complete | `worker` |
| `gitlab_database_transaction_seconds` | Histogram | 12.1 | Time spent in database transactions, in seconds | |
| `gitlab_method_call_duration_seconds` | Histogram | 10.2 | Method calls real duration | `controller`, `action`, `module`, `method` |
| `gitlab_page_out_of_bounds` | Counter | 12.8 | Counter for the PageLimiter pagination limit being hit | `controller`, `action`, `bot` |
| `gitlab_rails_queue_duration_seconds` | Histogram | 9.4 | Measures latency between GitLab Workhorse forwarding a request to Rails | |
-| `gitlab_sql_duration_seconds` | Histogram | 10.2 | SQL execution time, excluding SCHEMA operations and BEGIN / COMMIT | |
-| `gitlab_transaction_allocated_memory_bytes` | Histogram | 10.2 | Allocated memory for all transactions (gitlab_transaction_* metrics) | |
+| `gitlab_sql_duration_seconds` | Histogram | 10.2 | SQL execution time, excluding `SCHEMA` operations and `BEGIN` / `COMMIT` | |
+| `gitlab_transaction_allocated_memory_bytes` | Histogram | 10.2 | Allocated memory for all transactions (`gitlab_transaction_*` metrics) | |
| `gitlab_transaction_cache_<key>_count_total` | Counter | 10.2 | Counter for total Rails cache calls (per key) | |
| `gitlab_transaction_cache_<key>_duration_total` | Counter | 10.2 | Counter for total time (seconds) spent in Rails cache calls (per key) | |
| `gitlab_transaction_cache_count_total` | Counter | 10.2 | Counter for total Rails cache calls (aggregate) | |
| `gitlab_transaction_cache_duration_total` | Counter | 10.2 | Counter for total time (seconds) spent in Rails cache calls (aggregate) | |
| `gitlab_transaction_cache_read_hit_count_total` | Counter | 10.2 | Counter for cache hits for Rails cache calls | `controller`, `action` |
| `gitlab_transaction_cache_read_miss_count_total` | Counter | 10.2 | Counter for cache misses for Rails cache calls | `controller`, `action` |
-| `gitlab_transaction_duration_seconds` | Histogram | 10.2 | Duration for all transactions (gitlab_transaction_* metrics) | `controller`, `action` |
+| `gitlab_transaction_duration_seconds` | Histogram | 10.2 | Duration for all transactions (`gitlab_transaction_*` metrics) | `controller`, `action` |
| `gitlab_transaction_event_build_found_total` | Counter | 9.4 | Counter for build found for API /jobs/request | |
| `gitlab_transaction_event_build_invalid_total` | Counter | 9.4 | Counter for build invalid due to concurrency conflict for API /jobs/request | |
| `gitlab_transaction_event_build_not_found_cached_total` | Counter | 9.4 | Counter for cached response of build not found for API /jobs/request | |
| `gitlab_transaction_event_build_not_found_total` | Counter | 9.4 | Counter for build not found for API /jobs/request | |
| `gitlab_transaction_event_change_default_branch_total` | Counter | 9.4 | Counter when default branch is changed for any repository | |
| `gitlab_transaction_event_create_repository_total` | Counter | 9.4 | Counter when any repository is created | |
-| `gitlab_transaction_event_etag_caching_cache_hit_total` | Counter | 9.4 | Counter for etag cache hit. | `endpoint` |
-| `gitlab_transaction_event_etag_caching_header_missing_total` | Counter | 9.4 | Counter for etag cache miss - header missing | `endpoint` |
-| `gitlab_transaction_event_etag_caching_key_not_found_total` | Counter | 9.4 | Counter for etag cache miss - key not found | `endpoint` |
-| `gitlab_transaction_event_etag_caching_middleware_used_total` | Counter | 9.4 | Counter for etag middleware accessed | `endpoint` |
-| `gitlab_transaction_event_etag_caching_resource_changed_total` | Counter | 9.4 | Counter for etag cache miss - resource changed | `endpoint` |
+| `gitlab_transaction_event_etag_caching_cache_hit_total` | Counter | 9.4 | Counter for ETag cache hit. | `endpoint` |
+| `gitlab_transaction_event_etag_caching_header_missing_total` | Counter | 9.4 | Counter for ETag cache miss - header missing | `endpoint` |
+| `gitlab_transaction_event_etag_caching_key_not_found_total` | Counter | 9.4 | Counter for ETag cache miss - key not found | `endpoint` |
+| `gitlab_transaction_event_etag_caching_middleware_used_total` | Counter | 9.4 | Counter for ETag middleware accessed | `endpoint` |
+| `gitlab_transaction_event_etag_caching_resource_changed_total` | Counter | 9.4 | Counter for ETag cache miss - resource changed | `endpoint` |
| `gitlab_transaction_event_fork_repository_total` | Counter | 9.4 | Counter for repository forks (RepositoryForkWorker). Only incremented when source repository exists | |
| `gitlab_transaction_event_import_repository_total` | Counter | 9.4 | Counter for repository imports (RepositoryImportWorker) | |
| `gitlab_transaction_event_push_branch_total` | Counter | 9.4 | Counter for all branch pushes | |
@@ -92,6 +92,13 @@ The following metrics are available:
| `gitlab_view_rendering_duration_seconds` | Histogram | 10.2 | Duration for views (histogram) | `controller`, `action`, `view` |
| `http_requests_total` | Counter | 9.4 | Rack request count | `method` |
| `http_request_duration_seconds` | Histogram | 9.4 | HTTP response time from rack middleware | `method`, `status` |
+| `gitlab_transaction_db_count_total` | Counter | 13.1 | Counter for total number of sql calls | `controller`, `action` |
+| `gitlab_transaction_db_write_count_total` | Counter | 13.1 | Counter for total number of write sql calls | `controller`, `action` |
+| `gitlab_transaction_db_cached_count_total` | Counter | 13.1 | Counter for total number of cached sql calls | `controller`, `action` |
+| `http_redis_requests_duration_seconds` | Histogram | 13.1 | Redis requests duration during web transactions | `controller`, `action` |
+| `http_redis_requests_total` | Counter | 13.1 | Redis requests count during web transactions | `controller`, `action` |
+| `http_elasticsearch_requests_duration_seconds` **(STARTER)** | Histogram | 13.1 | Elasticsearch requests duration during web transactions | `controller`, `action` |
+| `http_elasticsearch_requests_total` **(STARTER)** | Counter | 13.1 | Elasticsearch requests count during web transactions | `controller`, `action` |
| `pipelines_created_total` | Counter | 9.4 | Counter of pipelines created | |
| `rack_uncaught_errors_total` | Counter | 9.4 | Rack connections handling uncaught errors count | |
| `user_session_logins_total` | Counter | 9.4 | Counter of how many users have logged in | |
@@ -99,7 +106,7 @@ The following metrics are available:
| `failed_login_captcha_total` | Gauge | 11.0 | Counter of failed CAPTCHA attempts during login | |
| `successful_login_captcha_total` | Gauge | 11.0 | Counter of successful CAPTCHA attempts during login | |
| `auto_devops_pipelines_completed_total` | Counter | 12.7 | Counter of completed Auto DevOps pipelines, labeled by status | |
-| `gitlab_metrics_dashboard_processing_time_ms` | Summary | 12.10 | Metrics dashboard processing time in milliseconds | service, stages |
+| `gitlab_metrics_dashboard_processing_time_ms` | Summary | 12.10 | Metrics dashboard processing time in milliseconds | service, stages |
## Metrics controlled by a feature flag
@@ -119,13 +126,17 @@ configuration option in `gitlab.yml`. These metrics are served from the
| Metric | Type | Since | Description | Labels |
|:---------------------------------------------- |:------- |:----- |:----------- |:------ |
-| `sidekiq_jobs_cpu_seconds` | Histogram | 12.4 | Seconds of cpu time to run Sidekiq job | `queue`, `boundary`, `external_dependencies`, `feature_category`, `job_status`, `urgency` |
+| `sidekiq_jobs_cpu_seconds` | Histogram | 12.4 | Seconds of CPU time to run Sidekiq job | `queue`, `boundary`, `external_dependencies`, `feature_category`, `job_status`, `urgency` |
| `sidekiq_jobs_completion_seconds` | Histogram | 12.2 | Seconds to complete Sidekiq job | `queue`, `boundary`, `external_dependencies`, `feature_category`, `job_status`, `urgency` |
| `sidekiq_jobs_db_seconds` | Histogram | 12.9 | Seconds of DB time to run Sidekiq job | `queue`, `boundary`, `external_dependencies`, `feature_category`, `job_status`, `urgency` |
| `sidekiq_jobs_gitaly_seconds` | Histogram | 12.9 | Seconds of Gitaly time to run Sidekiq job | `queue`, `boundary`, `external_dependencies`, `feature_category`, `job_status`, `urgency` |
+| `sidekiq_redis_requests_duration_seconds` | Histogram | 13.1 | Duration in seconds that a Sidekiq job spent querying a Redis server | `queue`, `boundary`, `external_dependencies`, `feature_category`, `job_status`, `urgency` |
+| `sidekiq_elasticsearch_requests_duration_seconds` | Histogram | 13.1 | Duration in seconds that a Sidekiq job spent in requests to an Elasticsearch server | `queue`, `boundary`, `external_dependencies`, `feature_category`, `job_status`, `urgency` |
| `sidekiq_jobs_queue_duration_seconds` | Histogram | 12.5 | Duration in seconds that a Sidekiq job was queued before being executed | `queue`, `boundary`, `external_dependencies`, `feature_category`, `urgency` |
| `sidekiq_jobs_failed_total` | Counter | 12.2 | Sidekiq jobs failed | `queue`, `boundary`, `external_dependencies`, `feature_category`, `urgency` |
| `sidekiq_jobs_retried_total` | Counter | 12.2 | Sidekiq jobs retried | `queue`, `boundary`, `external_dependencies`, `feature_category`, `urgency` |
+| `sidekiq_redis_requests_total` | Counter | 13.1 | Redis requests during a Sidekiq job execution | `queue`, `boundary`, `external_dependencies`, `feature_category`, `job_status`, `urgency` |
+| `sidekiq_elasticsearch_requests_total` | Counter | 13.1 | Elasticsearch requests during a Sidekiq job execution | `queue`, `boundary`, `external_dependencies`, `feature_category`, `job_status`, `urgency` |
| `sidekiq_running_jobs` | Gauge | 12.2 | Number of Sidekiq jobs running | `queue`, `boundary`, `external_dependencies`, `feature_category`, `urgency` |
| `sidekiq_concurrency` | Gauge | 12.5 | Maximum number of Sidekiq jobs | |
| `geo_db_replication_lag_seconds` | Gauge | 10.2 | Database replication lag (seconds) | `url` |
@@ -172,7 +183,29 @@ The following metrics are available:
| Metric | Type | Since | Description |
|:--------------------------------- |:--------- |:------------------------------------------------------------- |:-------------------------------------- |
-| `db_load_balancing_hosts` | Gauge | [12.3](https://gitlab.com/gitlab-org/gitlab/issues/13630) | Current number of load balancing hosts |
+| `db_load_balancing_hosts` | Gauge | [12.3](https://gitlab.com/gitlab-org/gitlab/-/issues/13630) | Current number of load balancing hosts |
+
+## Connection pool metrics
+
+These metrics record the status of the database [connection pools](https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html).
+
+They all have these labels:
+
+1. `class` - the Ruby class being recorded.
+ 1. `ActiveRecord::Base` is the main database connection.
+ 1. `Geo::TrackingBase` is the connection to the Geo tracking database, if
+ enabled.
+1. `host` - the host name used to connect to the database.
+1. `port` - the port used to connect to the database.
+
+| Metric | Type | Since | Description |
+|:----------------------------------------------|:------|:------|:--------------------------------------------------|
+| `gitlab_database_connection_pool_size` | Gauge | 13.0 | Total connection pool capacity |
+| `gitlab_database_connection_pool_connections` | Gauge | 13.0 | Current connections in the pool |
+| `gitlab_database_connection_pool_busy` | Gauge | 13.0 | Connections in use where the owner is still alive |
+| `gitlab_database_connection_pool_dead` | Gauge | 13.0 | Connections in use where the owner is not alive |
+| `gitlab_database_connection_pool_idle` | Gauge | 13.0 | Connections not in use |
+| `gitlab_database_connection_pool_waiting` | Gauge | 13.0 | Threads currently waiting on this queue |
## Ruby metrics
@@ -205,31 +238,28 @@ Unicorn specific metrics, when Unicorn is used.
When Puma is used instead of Unicorn, the following metrics are available:
-| Metric | Type | Since | Description |
-|:---------------------------------------------- |:------- |:----- |:----------- |
-| `puma_workers` | Gauge | 12.0 | Total number of workers |
-| `puma_running_workers` | Gauge | 12.0 | Number of booted workers |
-| `puma_stale_workers` | Gauge | 12.0 | Number of old workers |
-| `puma_running` | Gauge | 12.0 | Number of running threads |
-| `puma_queued_connections` | Gauge | 12.0 | Number of connections in that worker's "to do" set waiting for a worker thread |
-| `puma_active_connections` | Gauge | 12.0 | Number of threads processing a request |
-| `puma_pool_capacity` | Gauge | 12.0 | Number of requests the worker is capable of taking right now |
-| `puma_max_threads` | Gauge | 12.0 | Maximum number of worker threads |
-| `puma_idle_threads` | Gauge | 12.0 | Number of spawned threads which are not processing a request |
-| `puma_killer_terminations_total` | Gauge | 12.0 | Number of workers terminated by PumaWorkerKiller |
+| Metric | Type | Since | Description |
+|:--------------------------------- |:------- |:----- |:----------- |
+| `puma_workers` | Gauge | 12.0 | Total number of workers |
+| `puma_running_workers` | Gauge | 12.0 | Number of booted workers |
+| `puma_stale_workers` | Gauge | 12.0 | Number of old workers |
+| `puma_running` | Gauge | 12.0 | Number of running threads |
+| `puma_queued_connections` | Gauge | 12.0 | Number of connections in that worker's "to do" set waiting for a worker thread |
+| `puma_active_connections` | Gauge | 12.0 | Number of threads processing a request |
+| `puma_pool_capacity` | Gauge | 12.0 | Number of requests the worker is capable of taking right now |
+| `puma_max_threads` | Gauge | 12.0 | Maximum number of worker threads |
+| `puma_idle_threads` | Gauge | 12.0 | Number of spawned threads which are not processing a request |
+| `puma_killer_terminations_total` | Gauge | 12.0 | Number of workers terminated by PumaWorkerKiller |
## Metrics shared directory
GitLab's Prometheus client requires a directory to store metrics data shared between multi-process services.
Those files are shared among all instances running under Unicorn server.
-The directory needs to be accessible to all running Unicorn's processes otherwise
-metrics will not function correctly.
-
-For best performance its advisable that this directory will be located in `tmpfs`.
-
-Its location is configured using environment variable `prometheus_multiproc_dir`.
+The directory must be accessible to all running Unicorn's processes, or
+metrics won't function correctly.
-If GitLab is installed using Omnibus and `tmpfs` is available then metrics
-directory will be automatically configured.
+This directory's location is configured using environment variable `prometheus_multiproc_dir`.
+For best performance, create this directory in `tmpfs`.
-[↠Back to the main Prometheus page](index.md)
+If GitLab is installed using [Omnibus GitLab](https://docs.gitlab.com/omnibus/)
+and `tmpfs` is available, then the metrics directory will be configured for you.
diff --git a/doc/administration/monitoring/prometheus/index.md b/doc/administration/monitoring/prometheus/index.md
index cb93aca6e4e..1e233b890a2 100644
--- a/doc/administration/monitoring/prometheus/index.md
+++ b/doc/administration/monitoring/prometheus/index.md
@@ -84,7 +84,7 @@ To change the address/port that Prometheus listens on:
1. Save the file and [reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to
take effect
-### Adding custom scrape configs
+### Adding custom scrape configurations
You can configure additional scrape targets for the Omnibus GitLab-bundled
Prometheus by editing `prometheus['scrape_configs']` in `/etc/gitlab/gitlab.rb`
diff --git a/doc/administration/monitoring/prometheus/node_exporter.md b/doc/administration/monitoring/prometheus/node_exporter.md
index 357303ee4e1..07f6b8b8e1e 100644
--- a/doc/administration/monitoring/prometheus/node_exporter.md
+++ b/doc/administration/monitoring/prometheus/node_exporter.md
@@ -6,27 +6,24 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Node exporter
->**Note:**
-Available since Omnibus GitLab 8.16. For installations from source you'll
-have to install and configure it yourself.
-
-The [node exporter](https://github.com/prometheus/node_exporter) allows you to measure
+The [node exporter](https://github.com/prometheus/node_exporter) enables you to measure
various machine resources such as memory, disk and CPU utilization.
+NOTE: **Note:**
+For installations from source you'll have to install and configure it yourself.
+
To enable the node exporter:
-1. [Enable Prometheus](index.md#configuring-prometheus)
-1. Edit `/etc/gitlab/gitlab.rb`
-1. Add or find and uncomment the following line, making sure it's set to `true`:
+1. [Enable Prometheus](index.md#configuring-prometheus).
+1. Edit `/etc/gitlab/gitlab.rb`.
+1. Add (or find and uncomment) the following line, making sure it's set to `true`:
```ruby
node_exporter['enable'] = true
```
-1. Save the file and [reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure)
- for the changes to take effect
-
-Prometheus will now automatically begin collecting performance data from
-the node exporter exposed under `localhost:9100`.
+1. Save the file, and [reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure)
+ for the changes to take effect.
-[↠Back to the main Prometheus page](index.md)
+Prometheus will now begin collecting performance data from the node exporter
+exposed at `localhost:9100`.
diff --git a/doc/administration/monitoring/prometheus/pgbouncer_exporter.md b/doc/administration/monitoring/prometheus/pgbouncer_exporter.md
index 92ba2d9bb52..62d0bf684b6 100644
--- a/doc/administration/monitoring/prometheus/pgbouncer_exporter.md
+++ b/doc/administration/monitoring/prometheus/pgbouncer_exporter.md
@@ -6,29 +6,30 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# PgBouncer exporter
->**Note:**
-Available since [Omnibus GitLab 11.0](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/2493).
-For installations from source you'll have to install and configure it yourself.
+> Introduced in [Omnibus GitLab 11.0](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/2493).
+
+The [PgBouncer exporter](https://github.com/prometheus-community/pgbouncer_exporter) enables
+you to measure various [PgBouncer](https://www.pgbouncer.org/) metrics.
-The [PgBouncer exporter](https://github.com/stanhu/pgbouncer_exporter) allows you to measure various PgBouncer metrics.
+NOTE: **Note:**
+For installations from source you'll have to install and configure it yourself.
To enable the PgBouncer exporter:
-1. [Enable Prometheus](index.md#configuring-prometheus)
-1. Edit `/etc/gitlab/gitlab.rb`
-1. Add or find and uncomment the following line, making sure it's set to `true`:
+1. [Enable Prometheus](index.md#configuring-prometheus).
+1. Edit `/etc/gitlab/gitlab.rb`.
+1. Add (or find and uncomment) the following line, making sure it's set to `true`:
```ruby
pgbouncer_exporter['enable'] = true
```
-1. Save the file and [reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to
- take effect.
+1. Save the file and [reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure)
+ for the changes to take effect.
-Prometheus will now automatically begin collecting performance data from
-the PgBouncer exporter exposed under `localhost:9188`.
+Prometheus will now begin collecting performance data from the PgBouncer exporter
+exposed at `localhost:9188`.
-The PgBouncer exporter will also be enabled by default if the [`pgbouncer_role`](https://docs.gitlab.com/omnibus/roles/#postgres-roles)
+The PgBouncer exporter will also be enabled by default if the
+[`pgbouncer_role`](https://docs.gitlab.com/omnibus/roles/#postgresql-roles)
role is enabled.
-
-[↠Back to the main Prometheus page](index.md)
diff --git a/doc/administration/monitoring/prometheus/postgres_exporter.md b/doc/administration/monitoring/prometheus/postgres_exporter.md
index 77ca502b21d..e3fff45fce3 100644
--- a/doc/administration/monitoring/prometheus/postgres_exporter.md
+++ b/doc/administration/monitoring/prometheus/postgres_exporter.md
@@ -6,12 +6,11 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# PostgreSQL Server Exporter
->**Note:**
-Available since [Omnibus GitLab 8.17](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/1131).
-For installations from source you will have to install and configure it yourself.
-
The [PostgreSQL Server Exporter](https://github.com/wrouesnel/postgres_exporter) allows you to export various PostgreSQL metrics.
+NOTE: **Note:**
+For installations from source you will have to install and configure it yourself.
+
To enable the PostgreSQL Server Exporter:
1. [Enable Prometheus](index.md#configuring-prometheus).
@@ -21,10 +20,10 @@ To enable the PostgreSQL Server Exporter:
postgres_exporter['enable'] = true
```
-NOTE: **Note:**
-If PostgreSQL Server Exporter is configured on a separate node, make sure that the local
-address is [listed in `trust_auth_cidr_addresses`](../../high_availability/database.md#network-information) or the
-exporter will not be able to connect to the database.
+ NOTE: **Note:**
+ If PostgreSQL Server Exporter is configured on a separate node, make sure that the local
+ address is [listed in `trust_auth_cidr_addresses`](../../postgresql/replication_and_failover.md#network-information) or the
+ exporter will not be able to connect to the database.
1. Save the file and [reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to
take effect.
@@ -34,31 +33,44 @@ the PostgreSQL Server Exporter exposed under `localhost:9187`.
## Advanced configuration
-In most cases, PostgreSQL Server Exporter will work with the defaults and you should not
-need to change anything.
-
-To further customize the PostgreSQL Server Exporter, use the following configuration options:
+In most cases, PostgreSQL Server Exporter works with the defaults and you should not
+need to change anything. To further customize the PostgreSQL Server Exporter,
+use the following configuration options:
1. Edit `/etc/gitlab/gitlab.rb`:
```ruby
- postgres_exporter['dbname'] = 'pgbouncer' # The name of the database to connect to.
- postgres_exporter['user'] = 'gitlab-psql' # The user to sign in as.
- postgres_exporter['password'] = '' # The user's password.
- postgres_exporter['host'] = 'localhost' # The host to connect to. Values that start with '/' are for unix domain sockets (default is 'localhost').
- postgres_exporter['port'] = 5432 # The port to bind to (default is '5432').
- postgres_exporter['sslmode'] = 'require' # Whether or not to use SSL. Valid options are:
- # 'disable' (no SSL),
- # 'require' (always use SSL and skip verification, this is the default value),
- # 'verify-ca' (always use SSL and verify that the certificate presented by the server was signed by a trusted CA),
- # 'verify-full' (always use SSL and verify that the certification presented by the server was signed by a trusted CA and the server host name matches the one in the certificate).
- postgres_exporter['fallback_application_name'] = '' # An application_name to fall back to if one isn't provided.
- postgres_exporter['connect_timeout'] = '' # Maximum wait for connection, in seconds. Zero or not specified means wait indefinitely.
- postgres_exporter['sslcert'] = 'ssl.crt' # Cert file location. The file must contain PEM encoded data.
- postgres_exporter['sslkey'] = 'ssl.key' # Key file location. The file must contain PEM encoded data.
- postgres_exporter['sslrootcert'] = 'ssl-root.crt' # The location of the root certificate file. The file must contain PEM encoded data.
+ # The name of the database to connect to.
+ postgres_exporter['dbname'] = 'pgbouncer'
+ # The user to sign in as.
+ postgres_exporter['user'] = 'gitlab-psql'
+ # The user's password.
+ postgres_exporter['password'] = ''
+ # The host to connect to. Values that start with '/' are for unix domain sockets
+ # (default is 'localhost').
+ postgres_exporter['host'] = 'localhost'
+ # The port to bind to (default is '5432').
+ postgres_exporter['port'] = 5432
+ # Whether or not to use SSL. Valid options are:
+ # 'disable' (no SSL),
+ # 'require' (always use SSL and skip verification, this is the default value),
+ # 'verify-ca' (always use SSL and verify that the certificate presented by
+ # the server was signed by a trusted CA),
+ # 'verify-full' (always use SSL and verify that the certification presented
+ # by the server was signed by a trusted CA and the server host name matches
+ # the one in the certificate).
+ postgres_exporter['sslmode'] = 'require'
+ # An application_name to fall back to if one isn't provided.
+ postgres_exporter['fallback_application_name'] = ''
+ # Maximum wait for connection, in seconds. Zero or not specified means wait indefinitely.
+ postgres_exporter['connect_timeout'] = ''
+ # Cert file location. The file must contain PEM encoded data.
+ postgres_exporter['sslcert'] = 'ssl.crt'
+ # Key file location. The file must contain PEM encoded data.
+ postgres_exporter['sslkey'] = 'ssl.key'
+ # The location of the root certificate file. The file must contain PEM encoded data.
+ postgres_exporter['sslrootcert'] = 'ssl-root.crt'
```
-1. Save the file and [reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
-
-[↠Back to the main Prometheus page](index.md)
+1. Save the file and [reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure)
+ for the changes to take effect.
diff --git a/doc/administration/monitoring/prometheus/redis_exporter.md b/doc/administration/monitoring/prometheus/redis_exporter.md
index bef87400f5a..b7c66959349 100644
--- a/doc/administration/monitoring/prometheus/redis_exporter.md
+++ b/doc/administration/monitoring/prometheus/redis_exporter.md
@@ -6,19 +6,18 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Redis exporter
->**Note:**
-Available since [Omnibus GitLab 8.17](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/1118).
-For installations from source you'll have to install and configure it yourself.
-
-The [Redis exporter](https://github.com/oliver006/redis_exporter) allows you to measure
-various [Redis](https://redis.io) metrics. For more information on what's exported,
+The [Redis exporter](https://github.com/oliver006/redis_exporter) enables you to measure
+various [Redis](https://redis.io) metrics. For more information on what is exported,
[read the upstream documentation](https://github.com/oliver006/redis_exporter/blob/master/README.md#whats-exported).
+NOTE: **Note:**
+For installations from source you'll have to install and configure it yourself.
+
To enable the Redis exporter:
-1. [Enable Prometheus](index.md#configuring-prometheus)
-1. Edit `/etc/gitlab/gitlab.rb`
-1. Add or find and uncomment the following line, making sure it's set to `true`:
+1. [Enable Prometheus](index.md#configuring-prometheus).
+1. Edit `/etc/gitlab/gitlab.rb`.
+1. Add (or find and uncomment) the following line, making sure it's set to `true`:
```ruby
redis_exporter['enable'] = true
@@ -27,7 +26,5 @@ To enable the Redis exporter:
1. Save the file and [reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure)
for the changes to take effect.
-Prometheus will now automatically begin collecting performance data from
-the Redis exporter exposed under `localhost:9121`.
-
-[↠Back to the main Prometheus page](index.md)
+Prometheus will now begin collecting performance data from
+the Redis exporter exposed at `localhost:9121`.
diff --git a/doc/administration/object_storage.md b/doc/administration/object_storage.md
index c4f9b672923..1dea2de73f6 100644
--- a/doc/administration/object_storage.md
+++ b/doc/administration/object_storage.md
@@ -66,7 +66,7 @@ One risk of using a single bucket would be that if your organisation decided to
migrate GitLab to the Helm deployment in the future. GitLab would run, but the situation with
backups might not be realised until the organisation had a critical requirement for the backups to work.
-### S3 API compatability issues
+### S3 API compatibility issues
Not all S3 providers [are fully compatible](../raketasks/backup_restore.md#other-s3-providers)
with the Fog library that GitLab uses. Symptoms include:
@@ -79,7 +79,7 @@ with the Fog library that GitLab uses. Symptoms include:
If you're working to add more GitLab servers for [scaling or fault tolerance](reference_architectures/index.md)
and one of your requirements is [GitLab Pages](../user/project/pages/index.md) this currently requires
-NFS. There is [work in progress](https://gitlab.com/gitlab-org/gitlab-pages/issues/196)
+NFS. There is [work in progress](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/196)
to remove this dependency. In the future, GitLab Pages may use
[object storage](https://gitlab.com/gitlab-org/gitlab/-/issues/208135).
@@ -141,10 +141,88 @@ Using the default GitLab settings, some object storage back-ends such as
and [Alibaba](https://gitlab.com/gitlab-org/charts/gitlab/-/issues/1564)
might generate `ETag mismatch` errors.
+If you are seeing this ETag mismatch error with Amazon Web Services S3,
+it's likely this is due to [encryption settings on your bucket](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTCommonResponseHeaders.html).
+See the section on [using Amazon instance profiles](#using-amazon-instance-profiles) on how to fix this issue.
+
When using GitLab direct upload, the
[workaround for MinIO](https://gitlab.com/gitlab-org/charts/gitlab/-/issues/1564#note_244497658)
is to use the `--compat` parameter on the server.
-We are working on a fix to GitLab component Workhorse, and also
-a workaround, in the mean time, to
-[allow ETag verification to be disabled](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/18175).
+We are working on a fix to the [GitLab Workhorse
+component](https://gitlab.com/gitlab-org/gitlab-workhorse/-/issues/222).
+
+### Using Amazon instance profiles
+
+Instead of supplying AWS access and secret keys in object storage
+configuration, GitLab can be configured to use IAM roles to set up an
+[Amazon instance profile](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2.html).
+When this is used, GitLab will fetch temporary credentials each time an
+S3 bucket is accessed, so no hard-coded values are needed in the
+configuration.
+
+#### Encrypted S3 buckets
+
+> Introduced in [GitLab 13.1](https://gitlab.com/gitlab-org/gitlab-workhorse/-/merge_requests/466) only for instance profiles.
+
+When configured to use an instance profile, GitLab Workhorse
+will properly upload files to S3 buckets that have [SSE-S3 or SSE-KMS
+encryption enabled by default](https://docs.aws.amazon.com/kms/latest/developerguide/services-s3.html).
+Note that customer master keys (CMKs) and SSE-C encryption are not yet
+supported since this requires supplying keys to the GitLab
+configuration.
+
+Without instance profiles enabled (or prior to GitLab 13.1), GitLab
+Workhorse will upload files to S3 using pre-signed URLs that do not have
+a `Content-MD5` HTTP header computed for them. To ensure data is not
+corrupted, Workhorse checks that the MD5 hash of the data sent equals
+the ETag header returned from the S3 server. When encryption is enabled,
+this is not the case, which causes Workhorse to report an `ETag
+mismatch` error during an upload.
+
+With instance profiles enabled, GitLab Workhorse uses an AWS S3 client
+that properly computes and sends the `Content-MD5` header to the server,
+which eliminates the need for comparing ETag headers. If the data is
+corrupted in transit, the S3 server will reject the file.
+
+#### IAM Permissions
+
+To set up an instance profile, create an Amazon Identity Access and
+Management (IAM) role with the necessary permissions. The following
+example is a role for an S3 bucket named `test-bucket`:
+
+```json
+{
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Sid": "VisualEditor0",
+ "Effect": "Allow",
+ "Action": [
+ "s3:PutObject",
+ "s3:GetObject",
+ "s3:AbortMultipartUpload",
+ "s3:DeleteObject"
+ ],
+ "Resource": "arn:aws:s3:::test-bucket/*"
+ }
+ ]
+}
+```
+
+Associate this role with your GitLab instance, and then configure GitLab
+to use it via the `use_iam_profile` configuration option. For example,
+when configuring uploads to use object storage, see the `AWS IAM profiles`
+section in [S3 compatible connection settings](uploads.md#s3-compatible-connection-settings).
+
+#### Disabling the feature
+
+The Workhorse S3 client is only enabled when the `use_iam_profile`
+configuration flag is `true`.
+
+To disable this feature, ask a GitLab administrator with [Rails console access](feature_flags.md#how-to-enable-and-disable-features-behind-flags) to run the
+following command:
+
+```ruby
+Feature.disable(:use_workhorse_s3_client)
+```
diff --git a/doc/administration/operations/extra_sidekiq_processes.md b/doc/administration/operations/extra_sidekiq_processes.md
index 8f54b82c325..155680354da 100644
--- a/doc/administration/operations/extra_sidekiq_processes.md
+++ b/doc/administration/operations/extra_sidekiq_processes.md
@@ -106,14 +106,14 @@ you list:
## Queue selector (experimental)
-> [Introduced](https://gitlab.com/gitlab-com/gl-infra/scalability/issues/45) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.8.
+> [Introduced](https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/45) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.8.
CAUTION: **Caution:**
As this is marked as **experimental**, it is subject to change at any
time, including **breaking backwards compatibility**. This is so that we
can react to changes we need for our GitLab.com deployment. We have a
tracking issue open to [remove the experimental
-designation](https://gitlab.com/gitlab-com/gl-infra/scalability/issues/147)
+designation](https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/147)
from this feature; please comment there if you are interested in using
this in your own deployment.
@@ -126,6 +126,8 @@ in a more general way using the following components:
### Available attributes
+- [Introduced](https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/261) in GitLab 13.1, `tags`.
+
From the [list of all available
attributes](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/workers/all_queues.yml),
`experimental_queue_selector` allows selecting of queues by the
@@ -144,14 +146,21 @@ following attributes:
- `name` - the queue name. The other attributes are typically more useful as
they are more general, but this is available in case a particular queue needs
to be selected.
-- `resource_boundary` - if the worker is bound by `cpu`, `memory`, or
+- `resource_boundary` - if the queue is bound by `cpu`, `memory`, or
`unknown`. For example, the `project_export` queue is memory bound as it has
to load data in memory before saving it for export.
+- `tags` - short-lived annotations for queues. These are expected to frequently
+ change from release to release, and may be removed entirely.
`has_external_dependencies` is a boolean attribute: only the exact
string `true` is considered true, and everything else is considered
false.
+`tags` is a set, which means that `=` checks for intersecting sets, and
+`!=` checks for disjoint sets. For example, `tags=a,b` selects queues
+that have tags `a`, `b`, or both. `tags!=a,b` selects queues that have
+neither of those tags.
+
### Available operators
`experimental_queue_selector` supports the following operators, listed
diff --git a/doc/administration/operations/fast_ssh_key_lookup.md b/doc/administration/operations/fast_ssh_key_lookup.md
index 6759c3f265d..9f67c927128 100644
--- a/doc/administration/operations/fast_ssh_key_lookup.md
+++ b/doc/administration/operations/fast_ssh_key_lookup.md
@@ -1,7 +1,7 @@
# Fast lookup of authorized SSH keys in the database
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/1631) in [GitLab Starter](https://about.gitlab.com/pricing/) 9.3.
-> - [Available in](https://gitlab.com/gitlab-org/gitlab/issues/3953) GitLab Community Edition 10.4.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/1631) in [GitLab Starter](https://about.gitlab.com/pricing/) 9.3.
+> - [Available in](https://gitlab.com/gitlab-org/gitlab/-/issues/3953) GitLab Community Edition 10.4.
NOTE: **Note:** This document describes a drop-in replacement for the
`authorized_keys` file. For normal (non-deploy key) users, consider using
@@ -125,7 +125,7 @@ the database. The following instructions can be used to build OpenSSH 7.5:
```shell
sudo su -
cd /tmp
- curl --remote-name https://mirrors.evowise.com/pub/OpenBSD/OpenSSH/portable/openssh-7.5p1.tar.gz
+ curl --remote-name https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-7.5p1.tar.gz
tar xzvf openssh-7.5p1.tar.gz
yum install rpm-build gcc make wget openssl-devel krb5-devel pam-devel libX11-devel xmkmf libXt-devel
```
diff --git a/doc/administration/operations/filesystem_benchmarking.md b/doc/administration/operations/filesystem_benchmarking.md
index 019909e2e89..c5c5a8b4313 100644
--- a/doc/administration/operations/filesystem_benchmarking.md
+++ b/doc/administration/operations/filesystem_benchmarking.md
@@ -14,7 +14,7 @@ I/O. The information on this page can be used for either scenario.
### Benchmarking with `fio`
We recommend using
-[fio](https://fio.readthedocs.io/en/latest/fio_doc.html) to test I/O
+[Fio](https://fio.readthedocs.io/en/latest/fio_doc.html) to test I/O
performance. This test should be run both on the NFS server and on the
application nodes that talk to the NFS server.
diff --git a/doc/administration/operations/puma.md b/doc/administration/operations/puma.md
index af559cf00e9..af28335ef91 100644
--- a/doc/administration/operations/puma.md
+++ b/doc/administration/operations/puma.md
@@ -10,7 +10,8 @@ Unicorn unless explicitly specified not to.
## Why switch to Puma?
Puma has a multi-thread architecture which uses less memory than a multi-process
-application server like Unicorn.
+application server like Unicorn. On GitLab.com, we saw a 40% reduction in memory
+consumption.
Most Rails applications requests normally include a proportion of I/O wait time.
During I/O wait time MRI Ruby will release the GVL (Global VM Lock) to other threads.
@@ -18,9 +19,15 @@ Multi-threaded Puma can therefore still serve more requests than a single proces
## Configuring Puma to replace Unicorn
-If you are currently running Unicorn and would like to switch to Puma, server configuration
-will _not_ carry over automatically. For details on matching Unicorn configuration settings with
-the Puma equivalent, where applicable, see [Converting Unicorn settings to Puma](https://docs.gitlab.com/omnibus/settings/puma.html#converting-unicorn-settings-to-puma).
+Beginning with GitLab 13.0, Puma is the default application server. We plan to remove support for
+Unicorn in GitLab 14.0.
+
+When switching to Puma, Unicorn server configuration
+will _not_ carry over automatically, due to differences between the two application servers. For Omnibus-based
+deployments, see [Configuring Puma Settings](https://docs.gitlab.com/omnibus/settings/puma.html#configuring-puma-settings).
+For Helm based deployments, see the [Webservice Chart documentation](https://docs.gitlab.com/charts/charts/gitlab/webservice/index.html).
+
+Additionally we strongly recommend that multi-node deployments [configure their load balancers to utilize the readiness check](../high_availability/load_balancer.md#readiness-check) due to a difference between Unicorn and Puma in how they handle connections during a restart of the service.
## Performance caveat when using Puma with Rugged
diff --git a/doc/administration/operations/ssh_certificates.md b/doc/administration/operations/ssh_certificates.md
index b652f282b7b..c81eb15955d 100644
--- a/doc/administration/operations/ssh_certificates.md
+++ b/doc/administration/operations/ssh_certificates.md
@@ -158,7 +158,7 @@ Users can still bypass SSH certificate authentication by manually
uploading an SSH public key to their profile, relying on the
`~/.ssh/authorized_keys` fallback to authenticate it. There's
currently no feature to prevent this, [but there's an open request for
-adding it](https://gitlab.com/gitlab-org/gitlab-foss/issues/49218).
+adding it](https://gitlab.com/gitlab-org/gitlab/-/issues/23260).
Such a restriction can currently be hacked in by e.g. providing a
custom `AuthorizedKeysCommand` which checks if the discovered key-ID
diff --git a/doc/administration/operations/unicorn.md b/doc/administration/operations/unicorn.md
index 50481482f4c..eabf99eb08c 100644
--- a/doc/administration/operations/unicorn.md
+++ b/doc/administration/operations/unicorn.md
@@ -40,9 +40,9 @@ master process has PID 56227 below.
[2015-06-05T10:58:08.708824 #62538] INFO -- : worker=10 ready
```
-### Tunables
+### Tunable options
-The main tunables for Unicorn are the number of worker processes and the
+The main tunable options for Unicorn are the number of worker processes and the
request timeout after which the Unicorn master terminates a worker process.
See the [Omnibus GitLab Unicorn settings
documentation](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/unicorn.md)
diff --git a/doc/administration/packages/container_registry.md b/doc/administration/packages/container_registry.md
index 503e5fb4a2a..8f55345a9a8 100644
--- a/doc/administration/packages/container_registry.md
+++ b/doc/administration/packages/container_registry.md
@@ -1,3 +1,9 @@
+---
+stage: Package
+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/#designated-technical-writers
+---
+
# GitLab Container Registry administration
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/4040) in GitLab 8.8.
@@ -92,7 +98,7 @@ auth:
```
CAUTION: **Caution:**
-If `auth` is not set up, users will be able to pull docker images without authentication.
+If `auth` is not set up, users will be able to pull Docker images without authentication.
## Container Registry domain configuration
@@ -116,7 +122,7 @@ expose the Registry on a port so that you can reuse the existing GitLab TLS
certificate.
Assuming that the GitLab domain is `https://gitlab.example.com` and the port the
-Registry is exposed to the outside world is `4567`, here is what you need to set
+Registry is exposed to the outside world is `5050`, here is what you need to set
in `gitlab.rb` or `gitlab.yml` if you are using Omnibus GitLab or installed
GitLab from source respectively.
@@ -130,7 +136,7 @@ otherwise you will run into conflicts.
path to the existing TLS certificate and key used by GitLab:
```ruby
- registry_external_url 'https://gitlab.example.com:4567'
+ registry_external_url 'https://gitlab.example.com:5050'
```
Note how the `registry_external_url` is listening on HTTPS under the
@@ -151,7 +157,7 @@ otherwise you will run into conflicts.
1. Validate using:
```shell
- openssl s_client -showcerts -servername gitlab.example.com -connect gitlab.example.com:443 > cacert.pem
+ openssl s_client -showcerts -servername gitlab.example.com -connect gitlab.example.com:5050 > cacert.pem
```
NOTE: **Note:**
@@ -166,7 +172,7 @@ If your certificate provider provides the CA Bundle certificates, append them to
registry:
enabled: true
host: gitlab.example.com
- port: 4567
+ port: 5050
```
1. Save the file and [restart GitLab](../restart_gitlab.md#installations-from-source) for the changes to take effect.
@@ -176,7 +182,7 @@ Users should now be able to login to the Container Registry with their GitLab
credentials using:
```shell
-docker login gitlab.example.com:4567
+docker login gitlab.example.com:5050
```
### Configure Container Registry under its own domain
@@ -370,7 +376,7 @@ The different supported drivers are:
| swift | OpenStack Swift Object Storage |
| oss | Aliyun OSS |
-Read more about the individual driver's config options in the
+Read more about the individual driver's configuration options in the
[Docker Registry docs](https://docs.docker.com/registry/configuration/#storage).
[Read more about using object storage with GitLab](../object_storage.md).
@@ -407,8 +413,8 @@ NOTE: **Note:**
**Installations from source**
-Configuring the storage driver is done in your registry config YML file created
-when you [deployed your docker registry](https://docs.docker.com/registry/deploying/).
+Configuring the storage driver is done in your registry configuration YML file created
+when you [deployed your Docker registry](https://docs.docker.com/registry/deploying/).
`s3` storage driver example:
@@ -429,6 +435,16 @@ storage:
NOTE: **Note:**
`your-s3-bucket` should only be the name of a bucket that exists, and can't include subdirectories.
+**Migrate without downtime**
+
+To migrate the data to AWS S3 without downtime:
+
+1. To reduce the amount of data to be migrated, run the [garbage collection tool without downtime](#performing-garbage-collection-without-downtime). Part of this process sets the registry to `read-only`.
+1. Copy the data to your AWS S3 bucket, for example with [AWS CLI's `cp`](https://docs.aws.amazon.com/cli/latest/reference/s3/cp.html) command.
+1. Configure your registry to use the S3 bucket for storage.
+1. Put the registry back to `read-write`.
+1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+
### Disable redirect for storage driver
By default, users accessing a registry configured with a remote backend are redirected to the default backend for the storage driver. For example, registries can be configured using the `s3` storage driver, which redirects requests to a remote S3 bucket to alleviate load on the GitLab server.
@@ -604,7 +620,7 @@ You can use GitLab as an auth endpoint with an external container registry.
You can configure the Container Registry to send webhook notifications in
response to events happening within the registry.
-Read more about the Container Registry notifications config options in the
+Read more about the Container Registry notifications configuration options in the
[Docker Registry notifications documentation](https://docs.docker.com/registry/notifications/).
NOTE: **Note:**
@@ -635,8 +651,8 @@ To configure a notification endpoint in Omnibus:
**Installations from source**
-Configuring the notification endpoint is done in your registry config YML file created
-when you [deployed your docker registry](https://docs.docker.com/registry/deploying/).
+Configuring the notification endpoint is done in your registry configuration YML file created
+when you [deployed your Docker registry](https://docs.docker.com/registry/deploying/).
Example:
@@ -704,6 +720,8 @@ no longer directly accessible via the `:latest` tag.
### Recycling unused tags
+> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/987) in Omnibus GitLab 8.12.
+
There are a couple of considerations you need to note before running the
built-in command:
@@ -759,6 +777,8 @@ that you have backed up all registry data.
### Performing garbage collection without downtime
+> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/764) in GitLab 8.8.
+
You can perform a garbage collection without stopping the Container Registry by setting
it into a read-only mode and by not using the built-in command. During this time,
you will be able to pull from the Container Registry, but you will not be able to
@@ -873,9 +893,9 @@ thus the error above.
While GitLab doesn't support using self-signed certificates with Container
Registry out of the box, it is possible to make it work by
-[instructing the docker-daemon to trust the self-signed certificates](https://docs.docker.com/registry/insecure/#use-self-signed-certificates),
-mounting the docker-daemon and setting `privileged = false` in the Runner's
-`config.toml`. Setting `privileged = true` takes precedence over the docker-daemon:
+[instructing the Docker daemon to trust the self-signed certificates](https://docs.docker.com/registry/insecure/#use-self-signed-certificates),
+mounting the Docker daemon and setting `privileged = false` in the Runner's
+`config.toml`. Setting `privileged = true` takes precedence over the Docker daemon:
```toml
[runners.docker]
@@ -884,7 +904,7 @@ mounting the docker-daemon and setting `privileged = false` in the Runner's
volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
```
-Additional information about this: [issue 18239](https://gitlab.com/gitlab-org/gitlab-foss/issues/18239).
+Additional information about this: [issue 18239](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/18239).
### `unauthorized: authentication required` when pushing large images
@@ -955,7 +975,7 @@ Start with a value between `25000000` (25MB) and `50000000` (50MB).
### Supporting older Docker clients
-As of GitLab 11.9, we began shipping version 2.7.1 of the Docker container registry, which disables the schema1 manifest by default. If you are still using older Docker clients (1.9 or older), you may experience an error pushing images. See [omnibus-4145](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/4145) for more details.
+As of GitLab 11.9, we began shipping version 2.7.1 of the Docker container registry, which disables the schema1 manifest by default. If you are still using older Docker clients (1.9 or older), you may experience an error pushing images. See [omnibus-4145](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/4145) for more details.
You can add a configuration option for backwards compatibility.
@@ -1002,7 +1022,7 @@ there is likely an issue with the headers forwarded to the registry by NGINX. Th
NGINX configurations should handle this, but it might occur in custom setups where the SSL is
offloaded to a third party reverse proxy.
-This problem was discussed in a [docker project issue](https://github.com/docker/distribution/issues/970)
+This problem was discussed in a [Docker project issue](https://github.com/docker/distribution/issues/970)
and a simple solution would be to enable relative URLs in the Registry.
**For Omnibus installations**
@@ -1062,7 +1082,7 @@ A user attempted to enable an S3-backed Registry. The `docker login` step went
fine. However, when pushing an image, the output showed:
```plaintext
-The push refers to a repository [s3-testing.myregistry.com:4567/root/docker-test/docker-image]
+The push refers to a repository [s3-testing.myregistry.com:5050/root/docker-test/docker-image]
dc5e59c14160: Pushing [==================================================>] 14.85 kB
03c20c1a019a: Pushing [==================================================>] 2.048 kB
a08f14ef632e: Pushing [==================================================>] 2.048 kB
@@ -1154,8 +1174,8 @@ Now that we have mitmproxy and Docker running, we can attempt to login and push
a container image. You may need to run as root to do this. For example:
```shell
-docker login s3-testing.myregistry.com:4567
-docker push s3-testing.myregistry.com:4567/root/docker-test/docker-image
+docker login s3-testing.myregistry.com:5050
+docker push s3-testing.myregistry.com:5050/root/docker-test/docker-image
```
In the example above, we see the following trace on the mitmproxy window:
diff --git a/doc/administration/packages/dependency_proxy.md b/doc/administration/packages/dependency_proxy.md
index ec2020c26de..565a4521c2a 100644
--- a/doc/administration/packages/dependency_proxy.md
+++ b/doc/administration/packages/dependency_proxy.md
@@ -1,6 +1,12 @@
+---
+stage: Package
+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/#designated-technical-writers
+---
+
# GitLab Dependency Proxy administration **(PREMIUM ONLY)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/7934) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.11.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7934) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.11.
GitLab can be utilized as a dependency proxy for a variety of common package managers.
diff --git a/doc/administration/packages/index.md b/doc/administration/packages/index.md
index f826741d66f..5088dd86a86 100644
--- a/doc/administration/packages/index.md
+++ b/doc/administration/packages/index.md
@@ -1,3 +1,9 @@
+---
+stage: Package
+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/#designated-technical-writers
+---
+
# GitLab Package Registry administration **(PREMIUM ONLY)**
GitLab Packages allows organizations to utilize GitLab as a private repository
@@ -9,10 +15,12 @@ The Packages feature allows GitLab to act as a repository for the following:
| Software repository | Description | Available in GitLab version |
| ------------------- | ----------- | --------------------------- |
| [PyPi Repository](../../user/packages/pypi_repository/index.md) | The GitLab PyPi Repository enables every project in GitLab to have its own space to store [PyPi](https://pypi.org/) packages. | 12.10+ |
+| [Composer Repository](../../user/packages/composer_repository/index.md) | The GitLab Composer Repository enables every project in GitLab to have its own space to store [Composer](https://getcomposer.org/) packages. | 13.1+ |
| [NuGet Repository](../../user/packages/nuget_repository/index.md) | The GitLab NuGet Repository enables every project in GitLab to have its own space to store [NuGet](https://www.nuget.org/) packages. | 12.8+ |
| [Conan Repository](../../user/packages/conan_repository/index.md) | The GitLab Conan Repository enables every project in GitLab to have its own space to store [Conan](https://conan.io/) packages. | 12.4+ |
| [Maven Repository](../../user/packages/maven_repository/index.md) | The GitLab Maven Repository enables every project in GitLab to have its own space to store [Maven](https://maven.apache.org/) packages. | 11.3+ |
| [NPM Registry](../../user/packages/npm_registry/index.md) | The GitLab NPM Registry enables every project in GitLab to have its own space to store [NPM](https://www.npmjs.com/) packages. | 11.7+ |
+| [Go Proxy](../../user/packages/go_proxy/index.md) | The Go proxy for GitLab enables every project in GitLab to be fetched with the [Go proxy protocol](https://proxy.golang.org/). | 13.1+ |
Don't you see your package management system supported yet?
Please consider contributing
diff --git a/doc/administration/pages/index.md b/doc/administration/pages/index.md
index 21d13be47bd..a7a3a86de8e 100644
--- a/doc/administration/pages/index.md
+++ b/doc/administration/pages/index.md
@@ -1,4 +1,7 @@
---
+stage: Release
+group: Release 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/#designated-technical-writers
description: 'Learn how to administer GitLab Pages.'
---
@@ -6,9 +9,9 @@ description: 'Learn how to administer GitLab Pages.'
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80) in GitLab EE 8.3.
> - Custom CNAMEs with TLS support were [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/173) in GitLab EE 8.5.
-> - GitLab Pages [was ported](https://gitlab.com/gitlab-org/gitlab-foss/issues/14605) to Community Edition in GitLab 8.17.
+> - GitLab Pages [was ported](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/14605) to Community Edition in GitLab 8.17.
> - Support for subgroup project's websites was
-> [introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/30548) in GitLab 11.8.
+> [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/30548) in GitLab 11.8.
GitLab Pages allows for hosting of static sites. It must be configured by an
administrator. Separate [user documentation](../../user/project/pages/index.md) is available.
@@ -75,7 +78,7 @@ among other things.
Follow [these instructions](https://publicsuffix.org/submit/) to submit your
GitLab Pages subdomain. For instance, if your domain is `example.io`, you should
request that `example.io` is added to the Public Suffix List. GitLab.com
-added `gitlab.io` [in 2016](https://gitlab.com/gitlab-com/infrastructure/issues/230).
+added `gitlab.io` [in 2016](https://gitlab.com/gitlab-com/infrastructure/-/issues/230).
### DNS configuration
@@ -98,7 +101,8 @@ You should not use the GitLab domain to serve user pages. For more information s
## Configuration
Depending on your needs, you can set up GitLab Pages in 4 different ways.
-The following options are listed from the easiest setup to the most
+
+The following examples are listed from the easiest setup to the most
advanced one. The absolute minimum requirement is to set up the wildcard DNS
since that is needed in all configurations.
@@ -175,6 +179,64 @@ NOTE: **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.
+### Global settings
+
+Below is a table of all configuration settings known to Pages in Omnibus GitLab,
+and what they do. These options can be adjusted in `/etc/gitlab/gitlab.rb`,
+and will take effect after you [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+Most of these settings don't need to be configured manually unless you need more granular
+control over how the Pages daemon runs and serves content in your environment.
+
+| Setting | Description |
+| ------- | ----------- |
+| `pages_external_url` | The URL where GitLab Pages is accessible, including protocol (HTTP / HTTPS). If `https://` is used, you must also set `gitlab_pages['ssl_certificate']` and `gitlab_pages['ssl_certificate_key']`.
+| **gitlab_pages[]** | |
+| `access_control` | Whether to enable [access control](index.md#access-control).
+| `api_secret_key` | Full path to file with secret key used to authenticate with the GitLab API. Auto-generated when left unset.
+| `artifacts_server` | Enable viewing [artifacts](../job_artifacts.md) in GitLab Pages.
+| `artifacts_server_timeout` | Timeout (in seconds) for a proxied request to the artifacts server.
+| `artifacts_server_url` | API URL to proxy artifact requests to. Defaults to GitLab `external URL` + `/api/v4`, for example `https://gitlab.com/api/v4`.
+| `auth_redirect_uri` | Callback URL for authenticating with GitLab. Defaults to project's subdomain of `pages_external_url` + `/auth`.
+| `auth_secret` | Secret key for signing authentication requests. Leave blank to pull automatically from GitLab during OAuth registration.
+| `dir` | Working directory for config and secrets files.
+| `enable` | Enable or disable GitLab Pages on the current system.
+| `external_http` | Configure Pages to bind to one or more secondary IP addresses, serving HTTP requests. Multiple addresses can be given as an array, along with exact ports, for example `['1.2.3.4', '1.2.3.5:8063']`. Sets value for `listen_http`.
+| `external_https` | Configure Pages to bind to one or more secondary IP addresses, serving HTTPS requests. Multiple addresses can be given as an array, along with exact ports, for example `['1.2.3.4', '1.2.3.5:8063']`. Sets value for `listen_https`.
+| `gitlab_client_http_timeout` | GitLab API HTTP client connection timeout in seconds (default: 10s).
+| `gitlab_client_jwt_expiry` | JWT Token expiry time in seconds (default: 30s).
+| `gitlab_id` | The OAuth application public ID. Leave blank to automatically fill when Pages authenticates with GitLab.
+| `gitlab_secret` | The OAuth application secret. Leave blank to automatically fill when Pages authenticates with GitLab.
+| `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.
+| `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 inplace chroot; refer to the GitLab Pages [README](https://gitlab.com/gitlab-org/gitlab-pages/blob/master/README.md#caveats) for more information.
+| `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`.
+| `listen_proxy` | The addresses to listen on for reverse-proxy requests. Pages will bind to these addresses' network socket and receives incoming requests from it. Sets the value of `proxy_pass` in `$nginx-dir/conf/gitlab-pages.conf`.
+| `log_directory` | Absolute path to a log directory.
+| `log_format` | The log output format: 'text' or 'json'.
+| `log_verbose` | Verbose logging, true/false.
+| `max_connections` | Limit on the number of concurrent connections to the HTTP, HTTPS or proxy listeners.
+| `metrics_address` | The address to listen on for metrics requests.
+| `redirect_http` | Redirect pages from HTTP to HTTPS, true/false.
+| `sentry_dsn` | The address for sending Sentry crash reporting to.
+| `sentry_enabled` | Enable reporting and logging with Sentry, true/false.
+| `sentry_environment` | The environment for Sentry crash reporting.
+| `status_uri` | The URL path for a status page, for example, `/@status`.
+| `tls_max_version` | Specifies the maximum SSL/TLS version ("ssl3", "tls1.0", "tls1.1" or "tls1.2").
+| `tls_min_version` | Specifies the minimum SSL/TLS version ("ssl3", "tls1.0", "tls1.1" or "tls1.2").
+| `use_http2` | Enable HTTP2 support.
+| **gitlab_pages['env'][]** | |
+| `http_proxy` | Configure GitLab Pages to use an HTTP Proxy to mediate traffic between Pages and GitLab. Sets an environment variable `http_proxy` when starting Pages daemon.
+| **gitlab_rails[]** | |
+| `pages_domain_verification_cron_worker` | Schedule for verifying custom GitLab Pages domains.
+| `pages_domain_ssl_renewal_cron_worker` | Schedule for obtaining and renewing SSL certificates through Let's Encrypt for GitLab Pages domains.
+| `pages_domain_removal_cron_worker` | Schedule for removing unverified custom GitLab Pages domains.
+| `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).
+
+---
+
## Advanced configuration
In addition to the wildcard domains, you can also have the option to configure
@@ -261,7 +323,7 @@ This setting is enabled by default.
### Let's Encrypt integration
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/28996) in GitLab 12.1.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/28996) in GitLab 12.1.
[GitLab Pages' Let's Encrypt integration](../../user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration.md)
allows users to add Let's Encrypt SSL certificates for GitLab Pages
@@ -278,7 +340,7 @@ To enable it, you'll need to:
### Access control
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/33422) in GitLab 11.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/33422) in GitLab 11.5.
GitLab Pages access control can be configured per-project, and allows access to a Pages
site to be controlled based on a user's membership to that project.
@@ -305,9 +367,13 @@ Pages access control is disabled by default. To enable it:
1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
1. Users can now configure it in their [projects' settings](../../user/project/pages/pages_access_control.md).
+NOTE: **Important:**
+For multi-node setups, in order for this setting to be effective, it has to be applied
+to all the App nodes as well as the Sidekiq nodes.
+
#### Disabling public access to all Pages websites
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/32095) in GitLab 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32095) in GitLab 12.7.
You can enforce [Access Control](#access-control) for all GitLab Pages websites hosted
on your GitLab instance. By doing so, only logged-in users will have access to them.
@@ -324,7 +390,7 @@ To do that:
CAUTION: **Warning:**
This action will not make all currently public web-sites private until they redeployed.
This issue among others will be resolved by
-[changing GitLab Pages configuration mechanism](https://gitlab.com/gitlab-org/gitlab-pages/issues/282).
+[changing GitLab Pages configuration mechanism](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/282).
### Running behind a proxy
@@ -335,7 +401,7 @@ pages:
1. Configure in `/etc/gitlab/gitlab.rb`:
```ruby
- gitlab_pages['http_proxy'] = 'http://example:8080'
+ gitlab_pages['env']['http_proxy'] = 'http://example:8080'
```
1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
@@ -353,7 +419,7 @@ For installation from source this can be fixed by installing the custom Certific
Authority (CA) in the system certificate store.
For Omnibus, normally this would be fixed by [installing a custom CA in Omnibus GitLab](https://docs.gitlab.com/omnibus/settings/ssl.html#install-custom-public-certificates)
-but a [bug](https://gitlab.com/gitlab-org/gitlab/issues/25411) is currently preventing
+but a [bug](https://gitlab.com/gitlab-org/gitlab/-/issues/25411) is currently preventing
that method from working. Use the following workaround:
1. Append your GitLab server TLS/SSL certificate to `/opt/gitlab/embedded/ssl/certs/cacert.pem` where `gitlab-domain-example.com` is your GitLab application URL
@@ -435,7 +501,7 @@ The default is 100MB.
### Override maximum pages size per project or group **(PREMIUM ONLY)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/16610) in GitLab 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/16610) in GitLab 12.7.
To override the global maximum pages size for a specific project:
diff --git a/doc/administration/pages/source.md b/doc/administration/pages/source.md
index 1bb3b86b419..d5b49bdf839 100644
--- a/doc/administration/pages/source.md
+++ b/doc/administration/pages/source.md
@@ -1,3 +1,9 @@
+---
+stage: Release
+group: Release 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/#designated-technical-writers
+---
+
# GitLab Pages administration for source installations
>**Note:**
@@ -266,7 +272,7 @@ world. Custom domains are supported, but no TLS.
sudo ln -sf /etc/nginx/sites-{available,enabled}/gitlab-pages.conf
```
-1. Edit all GitLab related configs in `/etc/nginx/site-available/` and replace
+1. Edit all GitLab related configurations in `/etc/nginx/site-available/` and replace
`0.0.0.0` with `192.0.2.1`, where `192.0.2.1` the primary IP where GitLab
listens to.
1. Restart NGINX
@@ -335,7 +341,7 @@ world. Custom domains and TLS are supported.
sudo ln -sf /etc/nginx/sites-{available,enabled}/gitlab-pages-ssl.conf
```
-1. Edit all GitLab related configs in `/etc/nginx/site-available/` and replace
+1. Edit all GitLab related configurations in `/etc/nginx/site-available/` and replace
`0.0.0.0` with `192.0.2.1`, where `192.0.2.1` the primary IP where GitLab
listens to.
1. Restart NGINX
@@ -346,7 +352,7 @@ world. Custom domains and TLS are supported.
>**Note:**
The following information applies only for installations from source.
-Be extra careful when setting up the domain name in the NGINX config. You must
+Be extra careful when setting up the domain name in the NGINX configuration. You must
not remove the backslashes.
If your GitLab Pages domain is `example.io`, replace:
@@ -370,7 +376,7 @@ server_name ~^.*\.pages\.example\.io$;
## Access control
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/33422) in GitLab 11.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/33422) in GitLab 11.5.
GitLab Pages access control can be configured per-project, and allows access to a Pages
site to be controlled based on a user's membership to that project.
diff --git a/doc/administration/postgresql/external.md b/doc/administration/postgresql/external.md
new file mode 100644
index 00000000000..6e2bbc0aae1
--- /dev/null
+++ b/doc/administration/postgresql/external.md
@@ -0,0 +1,41 @@
+# Configure GitLab using an external PostgreSQL service
+
+If you're hosting GitLab on a cloud provider, you can optionally use a
+managed service for PostgreSQL. For example, AWS offers a managed Relational
+Database Service (RDS) that runs PostgreSQL.
+
+Alternatively, you may opt to manage your own PostgreSQL instance or cluster
+separate from the Omnibus GitLab package.
+
+If you use a cloud-managed service, or provide your own PostgreSQL instance:
+
+1. Set up PostgreSQL according to the
+ [database requirements document](../../install/requirements.md#database).
+1. Set up a `gitlab` username with a password of your choice. The `gitlab` user
+ needs privileges to create the `gitlabhq_production` database.
+1. If you are using a cloud-managed service, you may need to grant additional
+ roles to your `gitlab` user:
+ - Amazon RDS requires the [`rds_superuser`](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.html#Appendix.PostgreSQL.CommonDBATasks.Roles) role.
+ - Azure Database for PostgreSQL requires the [`azure_pg_admin`](https://docs.microsoft.com/en-us/azure/postgresql/howto-create-users#how-to-create-additional-admin-users-in-azure-database-for-postgresql) role.
+
+1. Configure the GitLab application servers with the appropriate connection details
+ for your external PostgreSQL service in your `/etc/gitlab/gitlab.rb` file:
+
+ ```ruby
+ # Disable the bundled Omnibus provided PostgreSQL
+ postgresql['enable'] = false
+
+ # PostgreSQL connection details
+ gitlab_rails['db_adapter'] = 'postgresql'
+ gitlab_rails['db_encoding'] = 'unicode'
+ gitlab_rails['db_host'] = '10.1.0.5' # IP/hostname of database server
+ gitlab_rails['db_password'] = 'DB password'
+ ```
+
+ For more information on GitLab HA setups, refer to [configuring GitLab for HA](../high_availability/gitlab.md).
+
+1. Reconfigure for the changes to take effect:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
diff --git a/doc/administration/high_availability/img/pg_ha_architecture.png b/doc/administration/postgresql/img/pg_ha_architecture.png
index ef870f652ae..ef870f652ae 100644
--- a/doc/administration/high_availability/img/pg_ha_architecture.png
+++ b/doc/administration/postgresql/img/pg_ha_architecture.png
Binary files differ
diff --git a/doc/administration/postgresql/replication_and_failover.md b/doc/administration/postgresql/replication_and_failover.md
new file mode 100644
index 00000000000..aa95b983d20
--- /dev/null
+++ b/doc/administration/postgresql/replication_and_failover.md
@@ -0,0 +1,1129 @@
+# PostgreSQL replication and failover with Omnibus GitLab **(PREMIUM ONLY)**
+
+> Important notes:
+>
+> - This document will focus only on configuration supported with [GitLab Premium](https://about.gitlab.com/pricing/), using the Omnibus GitLab package.
+> - If you are a Community Edition or Starter user, consider using a cloud hosted solution.
+> - This document will not cover installations from source.
+>
+> - If a setup with replication and failover is not what you were looking for, see the [database configuration document](https://docs.gitlab.com/omnibus/settings/database.html)
+> for the Omnibus GitLab packages.
+>
+> Please read this document fully before attempting to configure PostgreSQL with
+> replication and failover for GitLab.
+
+## Architecture
+
+The Omnibus GitLab recommended configuration for a PostgreSQL cluster with
+replication and failover requires:
+
+- A minimum of three database nodes.
+- A minimum of three `Consul` server nodes.
+- A minimum of one `pgbouncer` service 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 node.
+
+![PostgreSQL HA Architecture](img/pg_ha_architecture.png)
+
+You also need to take into consideration the underlying network topology, making
+sure you have redundant connectivity between all Database and GitLab instances
+to avoid the network becoming a single point of failure.
+
+### Database node
+
+Each database node runs three services:
+
+`PostgreSQL` - The database itself.
+
+`repmgrd` - Communicates with other repmgrd services in the cluster and handles
+failover when issues with the master server occurs. The failover procedure
+consists of:
+
+- Selecting a new master for the cluster.
+- Promoting the new node to master.
+- Instructing remaining servers to follow the new master node.
+- The old master node is automatically evicted from the cluster and should be
+ rejoined manually once recovered.
+
+`Consul` agent - Monitors the status of each node in the database cluster and
+tracks its health in a service definition on the Consul cluster.
+
+### Consul server node
+
+The Consul server node runs the Consul server service.
+
+### PgBouncer node
+
+Each PgBouncer node runs two services:
+
+`PgBouncer` - The database connection pooler itself.
+
+`Consul` agent - Watches the status of the PostgreSQL service definition on the
+Consul cluster. If that status changes, Consul runs a script which updates the
+PgBouncer configuration to point to the new PostgreSQL master node and reloads
+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:
+
+- 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)
+- Repmgr connects to the database servers [PostgreSQL default port](https://docs.gitlab.com/omnibus/package-information/defaults.html#postgresql)
+- 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)
+
+## Setting it up
+
+### Required information
+
+Before proceeding with configuration, you will need to collect all the necessary
+information.
+
+#### Network information
+
+PostgreSQL does not listen on any network interface by default. It needs to know
+which IP address to listen on in order to be accessible to other services.
+Similarly, PostgreSQL access is controlled based on the network source.
+
+This is why you will need:
+
+- IP address of each nodes network interface. This can be set to `0.0.0.0` to
+ listen on all interfaces. It cannot be set to the loopback address `127.0.0.1`.
+- Network Address. This can be in subnet (i.e. `192.168.0.0/255.255.255.0`)
+ or CIDR (i.e. `192.168.0.0/24`) form.
+
+#### Consul information
+
+When using default setup, minimum configuration requires:
+
+- `CONSUL_USERNAME`. Defaults to `gitlab-consul`
+- `CONSUL_DATABASE_PASSWORD`. Password for the database user.
+- `CONSUL_PASSWORD_HASH`. This is a hash generated out of Consul username/password pair.
+ Can be generated with:
+
+ ```shell
+ sudo gitlab-ctl pg-password-md5 CONSUL_USERNAME
+ ```
+
+- `CONSUL_SERVER_NODES`. The IP addresses or DNS records of the Consul server nodes.
+
+Few notes on the service itself:
+
+- The service runs under a system account, by default `gitlab-consul`.
+ - If you are using a different username, you will have to specify it. We
+ will refer to it with `CONSUL_USERNAME`,
+- There will be a database user created with read only access to the repmgr
+ database
+- Passwords will be stored in the following locations:
+ - `/etc/gitlab/gitlab.rb`: hashed
+ - `/var/opt/gitlab/pgbouncer/pg_auth`: hashed
+ - `/var/opt/gitlab/consul/.pgpass`: plaintext
+
+#### PostgreSQL information
+
+When configuring PostgreSQL, we will set `max_wal_senders` to one more than
+the number of database nodes in the cluster.
+This is used to prevent replication from using up all of the
+available database connections.
+
+In this document we are assuming 3 database nodes, which makes this configuration:
+
+```ruby
+postgresql['max_wal_senders'] = 4
+```
+
+As previously mentioned, you'll have to prepare the network subnets that will
+be allowed to authenticate with the database.
+You'll also need to supply the IP addresses or DNS records of Consul
+server nodes.
+
+We will need the following password information for the application's database user:
+
+- `POSTGRESQL_USERNAME`. Defaults to `gitlab`
+- `POSTGRESQL_USER_PASSWORD`. The password for the database user
+- `POSTGRESQL_PASSWORD_HASH`. This is a hash generated out of the username/password pair.
+ Can be generated with:
+
+ ```shell
+ sudo gitlab-ctl pg-password-md5 POSTGRESQL_USERNAME
+ ```
+
+#### PgBouncer information
+
+When using default setup, minimum configuration requires:
+
+- `PGBOUNCER_USERNAME`. Defaults to `pgbouncer`
+- `PGBOUNCER_PASSWORD`. This is a password for PgBouncer service.
+- `PGBOUNCER_PASSWORD_HASH`. This is a hash generated out of PgBouncer username/password pair.
+ Can be generated with:
+
+ ```shell
+ sudo gitlab-ctl pg-password-md5 PGBOUNCER_USERNAME
+ ```
+
+- `PGBOUNCER_NODE`, is the IP address or a FQDN of the node running PgBouncer.
+
+Few notes on 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 will have to specify this username. We will refer to this requirement with `PGBOUNCER_USERNAME`.
+- The service will have a regular database user account generated for it
+ - This defaults to `repmgr`
+- Passwords will be stored in the following locations:
+ - `/etc/gitlab/gitlab.rb`: hashed, and in plain text
+ - `/var/opt/gitlab/pgbouncer/pg_auth`: hashed
+
+#### Repmgr information
+
+When using default setup, you will only have to prepare the network subnets that will
+be allowed to authenticate with the service.
+
+Few notes on the service itself:
+
+- The service runs under the same system account as the database
+ - In the package, this is by default `gitlab-psql`
+- The service will have a superuser database user account generated for it
+ - This defaults to `gitlab_repmgr`
+
+### Installing Omnibus GitLab
+
+First, make sure to [download/install](https://about.gitlab.com/install/)
+Omnibus GitLab **on each node**.
+
+Make sure you install the necessary dependencies from step 1,
+add GitLab package repository from step 2.
+When installing the GitLab package, do not supply `EXTERNAL_URL` value.
+
+### Configuring the Database nodes
+
+1. Make sure to [configure the Consul nodes](../high_availability/consul.md).
+1. Make sure you collect [`CONSUL_SERVER_NODES`](#consul-information), [`PGBOUNCER_PASSWORD_HASH`](#pgbouncer-information), [`POSTGRESQL_PASSWORD_HASH`](#postgresql-information), the [number of db nodes](#postgresql-information), and the [network address](#network-information) before executing the next step.
+
+1. On the master database node, edit `/etc/gitlab/gitlab.rb` replacing values noted in the `# START user configuration` section:
+
+ ```ruby
+ # Disable all components except PostgreSQL and Repmgr and Consul
+ roles ['postgres_role']
+
+ # PostgreSQL configuration
+ postgresql['listen_address'] = '0.0.0.0'
+ postgresql['hot_standby'] = 'on'
+ postgresql['wal_level'] = 'replica'
+ postgresql['shared_preload_libraries'] = 'repmgr_funcs'
+
+ # Disable automatic database migrations
+ gitlab_rails['auto_migrate'] = false
+
+ # Configure the Consul agent
+ consul['services'] = %w(postgresql)
+
+ # START user configuration
+ # Please set the real values as explained in Required Information section
+ #
+ # Replace PGBOUNCER_PASSWORD_HASH with a generated md5 value
+ postgresql['pgbouncer_user_password'] = 'PGBOUNCER_PASSWORD_HASH'
+ # Replace POSTGRESQL_PASSWORD_HASH with a generated md5 value
+ postgresql['sql_user_password'] = 'POSTGRESQL_PASSWORD_HASH'
+ # Replace X with value of number of db nodes + 1
+ postgresql['max_wal_senders'] = X
+ postgresql['max_replication_slots'] = X
+
+ # Replace XXX.XXX.XXX.XXX/YY with Network Address
+ postgresql['trust_auth_cidr_addresses'] = %w(XXX.XXX.XXX.XXX/YY)
+ repmgr['trust_auth_cidr_addresses'] = %w(127.0.0.1/32 XXX.XXX.XXX.XXX/YY)
+
+ # Replace placeholders:
+ #
+ # Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z
+ # with the addresses gathered for CONSUL_SERVER_NODES
+ consul['configuration'] = {
+ retry_join: %w(Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z)
+ }
+ #
+ # END user configuration
+ ```
+
+ > `postgres_role` was introduced with GitLab 10.3
+
+1. On secondary nodes, add all the configuration specified above for primary node
+ to `/etc/gitlab/gitlab.rb`. In addition, append the following configuration
+ to inform `gitlab-ctl` that they are standby nodes initially and it need not
+ attempt to register them as primary node
+
+ ```ruby
+ # Specify if a node should attempt to be master on initialization
+ repmgr['master_on_initialization'] = false
+ ```
+
+1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+1. [Enable Monitoring](#enable-monitoring)
+
+> Please note:
+>
+> - If you want your database to listen on a specific interface, change the configuration:
+> `postgresql['listen_address'] = '0.0.0.0'`.
+> - If your PgBouncer service runs under a different user account,
+> you also need to specify: `postgresql['pgbouncer_user'] = PGBOUNCER_USERNAME` in
+> your configuration.
+
+#### Enable Monitoring
+
+> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/3786) in GitLab 12.0.
+
+If you enable Monitoring, it must be enabled on **all** database servers.
+
+1. Create/edit `/etc/gitlab/gitlab.rb` and add the following configuration:
+
+ ```ruby
+ # Enable service discovery for Prometheus
+ consul['monitoring_service_discovery'] = true
+
+ # Set the network addresses that the exporters will listen on
+ node_exporter['listen_address'] = '0.0.0.0:9100'
+ postgres_exporter['listen_address'] = '0.0.0.0:9187'
+ ```
+
+1. Run `sudo gitlab-ctl reconfigure` to compile the configuration.
+
+#### Database nodes post-configuration
+
+##### Primary node
+
+Select one node as a primary node.
+
+1. Open a database prompt:
+
+ ```shell
+ gitlab-psql -d gitlabhq_production
+ ```
+
+1. Enable the `pg_trgm` extension:
+
+ ```shell
+ CREATE EXTENSION pg_trgm;
+ ```
+
+1. Exit the database prompt by typing `\q` and Enter.
+
+1. Verify the cluster is initialized with one node:
+
+ ```shell
+ gitlab-ctl repmgr cluster show
+ ```
+
+ The output should be similar to the following:
+
+ ```plaintext
+ Role | Name | Upstream | Connection String
+ ----------+----------|----------|----------------------------------------
+ * master | HOSTNAME | | host=HOSTNAME user=gitlab_repmgr dbname=gitlab_repmgr
+ ```
+
+1. Note down the hostname or IP address in the connection string: `host=HOSTNAME`. We will
+ refer to the hostname in the next section as `MASTER_NODE_NAME`. If the value
+ is not an IP address, it will need to be a resolvable name (via DNS or
+ `/etc/hosts`)
+
+##### Secondary nodes
+
+1. Set up the repmgr standby:
+
+ ```shell
+ gitlab-ctl repmgr standby setup MASTER_NODE_NAME
+ ```
+
+ Do note that this will remove the existing data on the node. The command
+ has a wait time.
+
+ The output should be similar to the following:
+
+ ```console
+ # gitlab-ctl repmgr standby setup MASTER_NODE_NAME
+ Doing this will delete the entire contents of /var/opt/gitlab/postgresql/data
+ If this is not what you want, hit Ctrl-C now to exit
+ To skip waiting, rerun with the -w option
+ Sleeping for 30 seconds
+ Stopping the database
+ Removing the data
+ Cloning the data
+ Starting the database
+ Registering the node with the cluster
+ ok: run: repmgrd: (pid 19068) 0s
+ ```
+
+1. Verify the node now appears in the cluster:
+
+ ```shell
+ gitlab-ctl repmgr cluster show
+ ```
+
+ The output should be similar to the following:
+
+ ```plaintext
+ Role | Name | Upstream | Connection String
+ ----------+---------|-----------|------------------------------------------------
+ * master | MASTER | | host=MASTER_NODE_NAME user=gitlab_repmgr dbname=gitlab_repmgr
+ standby | STANDBY | MASTER | host=STANDBY_HOSTNAME user=gitlab_repmgr dbname=gitlab_repmgr
+ ```
+
+Repeat the above steps on all secondary nodes.
+
+#### Database checkpoint
+
+Before moving on, make sure the databases are configured correctly. Run the
+following command on the **primary** node to verify that replication is working
+properly:
+
+```shell
+gitlab-ctl repmgr cluster show
+```
+
+The output should be similar to:
+
+```plaintext
+Role | Name | Upstream | Connection String
+----------+--------------|--------------|--------------------------------------------------------------------
+* master | MASTER | | host=MASTER port=5432 user=gitlab_repmgr dbname=gitlab_repmgr
+ standby | STANDBY | MASTER | host=STANDBY port=5432 user=gitlab_repmgr dbname=gitlab_repmgr
+```
+
+If the 'Role' column for any node says "FAILED", check the
+[Troubleshooting section](#troubleshooting) before proceeding.
+
+Also, check that the check master command works successfully on each node:
+
+```shell
+su - gitlab-consul
+gitlab-ctl repmgr-check-master || echo 'This node is a standby repmgr node'
+```
+
+This command relies on exit codes to tell Consul whether a particular node is a master
+or secondary. The most important thing here is that this command does not produce errors.
+If there are errors it's most likely due to incorrect `gitlab-consul` database user permissions.
+Check the [Troubleshooting section](#troubleshooting) before proceeding.
+
+### Configuring the PgBouncer node
+
+1. Make sure you collect [`CONSUL_SERVER_NODES`](#consul-information), [`CONSUL_PASSWORD_HASH`](#consul-information), and [`PGBOUNCER_PASSWORD_HASH`](#pgbouncer-information) before executing the next step.
+
+1. One each node, edit the `/etc/gitlab/gitlab.rb` config file and replace values noted in the `# START user configuration` section as below:
+
+ ```ruby
+ # Disable all components except PgBouncer and Consul agent
+ roles ['pgbouncer_role']
+
+ # Configure PgBouncer
+ pgbouncer['admin_users'] = %w(pgbouncer gitlab-consul)
+
+ # Configure Consul agent
+ consul['watchers'] = %w(postgresql)
+
+ # START user configuration
+ # Please set the real values as explained in Required Information section
+ # Replace CONSUL_PASSWORD_HASH with with a generated md5 value
+ # Replace PGBOUNCER_PASSWORD_HASH with with a generated md5 value
+ pgbouncer['users'] = {
+ 'gitlab-consul': {
+ password: 'CONSUL_PASSWORD_HASH'
+ },
+ 'pgbouncer': {
+ password: 'PGBOUNCER_PASSWORD_HASH'
+ }
+ }
+ # Replace placeholders:
+ #
+ # Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z
+ # with the addresses gathered for CONSUL_SERVER_NODES
+ consul['configuration'] = {
+ retry_join: %w(Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z)
+ }
+ #
+ # END user configuration
+ ```
+
+ NOTE: **Note:**
+ `pgbouncer_role` was introduced with GitLab 10.3.
+
+1. Run `gitlab-ctl reconfigure`
+
+1. Create a `.pgpass` file so Consul is able to
+ reload PgBouncer. Enter the `PGBOUNCER_PASSWORD` twice when asked:
+
+ ```shell
+ gitlab-ctl write-pgpass --host 127.0.0.1 --database pgbouncer --user pgbouncer --hostuser gitlab-consul
+ ```
+
+1. [Enable monitoring](../high_availability/pgbouncer.md#enable-monitoring)
+
+#### PgBouncer Checkpoint
+
+1. Ensure each node is talking to the current master:
+
+ ```shell
+ gitlab-ctl pgb-console # You will be prompted for PGBOUNCER_PASSWORD
+ ```
+
+ If there is an error `psql: ERROR: Auth failed` after typing in the
+ password, ensure you previously generated the MD5 password hashes with the correct
+ format. The correct format is to concatenate the password and the username:
+ `PASSWORDUSERNAME`. For example, `Sup3rS3cr3tpgbouncer` would be the text
+ needed to generate an MD5 password hash for the `pgbouncer` user.
+
+1. Once the console prompt is available, run the following queries:
+
+ ```shell
+ show databases ; show clients ;
+ ```
+
+ The output should be similar to the following:
+
+ ```plaintext
+ name | host | port | database | force_user | pool_size | reserve_pool | pool_mode | max_connections | current_connections
+ ---------------------+-------------+------+---------------------+------------+-----------+--------------+-----------+-----------------+---------------------
+ gitlabhq_production | MASTER_HOST | 5432 | gitlabhq_production | | 20 | 0 | | 0 | 0
+ pgbouncer | | 6432 | pgbouncer | pgbouncer | 2 | 0 | statement | 0 | 0
+ (2 rows)
+
+ type | user | database | state | addr | port | local_addr | local_port | connect_time | request_time | ptr | link | remote_pid | tls
+ ------+-----------+---------------------+---------+----------------+-------+------------+------------+---------------------+---------------------+-----------+------+------------+-----
+ C | pgbouncer | pgbouncer | active | 127.0.0.1 | 56846 | 127.0.0.1 | 6432 | 2017-08-21 18:09:59 | 2017-08-21 18:10:48 | 0x22b3880 | | 0 |
+ (2 rows)
+ ```
+
+#### Configure the internal load balancer
+
+If you're running more than one PgBouncer node as recommended, then at this time you'll need to set up a TCP internal load balancer to serve each correctly. This can be done with any reputable TCP load balancer.
+
+As an example here's how you could do it with [HAProxy](https://www.haproxy.org/):
+
+```plaintext
+global
+ log /dev/log local0
+ log localhost local1 notice
+ log stdout format raw local0
+
+defaults
+ log global
+ default-server inter 10s fall 3 rise 2
+ balance leastconn
+
+frontend internal-pgbouncer-tcp-in
+ bind *:6432
+ mode tcp
+ option tcplog
+
+ default_backend pgbouncer
+
+backend pgbouncer
+ mode tcp
+ option tcp-check
+
+ server pgbouncer1 <ip>:6432 check
+ server pgbouncer2 <ip>:6432 check
+ server pgbouncer3 <ip>:6432 check
+```
+
+Refer to your preferred Load Balancer's documentation for further guidance.
+
+### Configuring the Application nodes
+
+These will be the nodes running the `gitlab-rails` service. You may have other
+attributes set, but the following need to be set.
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ # Disable PostgreSQL on the application node
+ postgresql['enable'] = false
+
+ gitlab_rails['db_host'] = 'PGBOUNCER_NODE' or 'INTERNAL_LOAD_BALANCER'
+ gitlab_rails['db_port'] = 6432
+ gitlab_rails['db_password'] = 'POSTGRESQL_USER_PASSWORD'
+ gitlab_rails['auto_migrate'] = false
+ ```
+
+1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+
+#### Application node post-configuration
+
+Ensure that all migrations ran:
+
+```shell
+gitlab-rake gitlab:db:configure
+```
+
+> **Note**: If you encounter a `rake aborted!` error stating that PgBouncer is failing to connect to
+PostgreSQL it may be that your PgBouncer node's IP address is missing from
+PostgreSQL's `trust_auth_cidr_addresses` in `gitlab.rb` on your database nodes. See
+[PgBouncer error `ERROR: pgbouncer cannot connect to server`](#pgbouncer-error-error-pgbouncer-cannot-connect-to-server)
+in the Troubleshooting section before proceeding.
+
+### Ensure GitLab is running
+
+At this point, your GitLab instance should be up and running. Verify you are
+able to login, and create issues and merge requests. If you have troubles check
+the [Troubleshooting section](#troubleshooting).
+
+## Example configuration
+
+Here we'll show you some fully expanded example configurations.
+
+### Example recommended setup
+
+This example uses 3 Consul servers, 3 PgBouncer servers (with associated internal load balancer),
+3 PostgreSQL servers, and 1 application node.
+
+We start with all servers on the same 10.6.0.0/16 private network range, they
+can connect to each freely other on those addresses.
+
+Here is a list and description of each machine and the assigned IP:
+
+- `10.6.0.11`: Consul 1
+- `10.6.0.12`: Consul 2
+- `10.6.0.13`: Consul 3
+- `10.6.0.20`: Internal Load Balancer
+- `10.6.0.21`: PgBouncer 1
+- `10.6.0.22`: PgBouncer 2
+- `10.6.0.23`: PgBouncer 3
+- `10.6.0.31`: PostgreSQL master
+- `10.6.0.32`: PostgreSQL secondary
+- `10.6.0.33`: PostgreSQL secondary
+- `10.6.0.41`: GitLab application
+
+All passwords are set to `toomanysecrets`, please do not use this password or derived hashes and the `external_url` for GitLab is `http://gitlab.example.com`.
+
+Please note that after the initial configuration, if a failover occurs, the PostgresSQL master will change to one of the available secondaries until it is failed back.
+
+#### Example recommended setup for Consul servers
+
+On each server edit `/etc/gitlab/gitlab.rb`:
+
+```ruby
+# Disable all components except Consul
+roles ['consul_role']
+
+consul['configuration'] = {
+ server: true,
+ retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13)
+}
+consul['monitoring_service_discovery'] = true
+```
+
+[Reconfigure Omnibus GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+
+#### Example recommended setup for PgBouncer servers
+
+On each server edit `/etc/gitlab/gitlab.rb`:
+
+```ruby
+# Disable all components except Pgbouncer and Consul agent
+roles ['pgbouncer_role']
+
+# Configure PgBouncer
+pgbouncer['admin_users'] = %w(pgbouncer gitlab-consul)
+
+pgbouncer['users'] = {
+ 'gitlab-consul': {
+ password: '5e0e3263571e3704ad655076301d6ebe'
+ },
+ 'pgbouncer': {
+ password: '771a8625958a529132abe6f1a4acb19c'
+ }
+}
+
+consul['watchers'] = %w(postgresql)
+consul['enable'] = true
+consul['configuration'] = {
+ retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13)
+}
+consul['monitoring_service_discovery'] = true
+```
+
+[Reconfigure Omnibus GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+
+#### Internal load balancer setup
+
+An internal load balancer (TCP) is then required to be setup to serve each PgBouncer node (in this example on the IP of `10.6.0.20`). An example of how to do this can be found in the [PgBouncer Configure Internal Load Balancer](#configure-the-internal-load-balancer) section.
+
+#### Example recommended setup for PostgreSQL servers
+
+##### Primary node
+
+On primary node edit `/etc/gitlab/gitlab.rb`:
+
+```ruby
+# Disable all components except PostgreSQL and Repmgr and Consul
+roles ['postgres_role']
+
+# PostgreSQL configuration
+postgresql['listen_address'] = '0.0.0.0'
+postgresql['hot_standby'] = 'on'
+postgresql['wal_level'] = 'replica'
+postgresql['shared_preload_libraries'] = 'repmgr_funcs'
+
+# Disable automatic database migrations
+gitlab_rails['auto_migrate'] = false
+
+postgresql['pgbouncer_user_password'] = '771a8625958a529132abe6f1a4acb19c'
+postgresql['sql_user_password'] = '450409b85a0223a214b5fb1484f34d0f'
+postgresql['max_wal_senders'] = 4
+
+postgresql['trust_auth_cidr_addresses'] = %w(10.6.0.0/16)
+repmgr['trust_auth_cidr_addresses'] = %w(10.6.0.0/16)
+
+# Configure the Consul agent
+consul['services'] = %w(postgresql)
+consul['enable'] = true
+consul['configuration'] = {
+ retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13)
+}
+consul['monitoring_service_discovery'] = true
+```
+
+[Reconfigure Omnibus GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+
+##### Secondary nodes
+
+On secondary nodes, edit `/etc/gitlab/gitlab.rb` and add all the configuration
+added to primary node, noted above. In addition, append the following
+configuration:
+
+```ruby
+# Specify if a node should attempt to be master on initialization
+repmgr['master_on_initialization'] = false
+```
+
+[Reconfigure Omnibus GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+
+###### Example recommended setup for application server
+
+On the server edit `/etc/gitlab/gitlab.rb`:
+
+```ruby
+external_url 'http://gitlab.example.com'
+
+gitlab_rails['db_host'] = '10.6.0.20' # Internal Load Balancer for PgBouncer nodes
+gitlab_rails['db_port'] = 6432
+gitlab_rails['db_password'] = 'toomanysecrets'
+gitlab_rails['auto_migrate'] = false
+
+postgresql['enable'] = false
+pgbouncer['enable'] = false
+consul['enable'] = true
+
+# Configure Consul agent
+consul['watchers'] = %w(postgresql)
+
+pgbouncer['users'] = {
+ 'gitlab-consul': {
+ password: '5e0e3263571e3704ad655076301d6ebe'
+ },
+ 'pgbouncer': {
+ password: '771a8625958a529132abe6f1a4acb19c'
+ }
+}
+
+consul['configuration'] = {
+ retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13)
+}
+```
+
+[Reconfigure Omnibus GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+
+#### Example recommended setup manual steps
+
+After deploying the configuration follow these steps:
+
+1. On `10.6.0.31`, our primary database
+
+ Enable the `pg_trgm` extension
+
+ ```shell
+ gitlab-psql -d gitlabhq_production
+ ```
+
+ ```shell
+ CREATE EXTENSION pg_trgm;
+ ```
+
+1. On `10.6.0.32`, our first standby database
+
+ Make this node a standby of the primary
+
+ ```shell
+ gitlab-ctl repmgr standby setup 10.6.0.21
+ ```
+
+1. On `10.6.0.33`, our second standby database
+
+ Make this node a standby of the primary
+
+ ```shell
+ gitlab-ctl repmgr standby setup 10.6.0.21
+ ```
+
+1. On `10.6.0.41`, our application server
+
+ Set `gitlab-consul` user's PgBouncer password to `toomanysecrets`
+
+ ```shell
+ gitlab-ctl write-pgpass --host 127.0.0.1 --database pgbouncer --user pgbouncer --hostuser gitlab-consul
+ ```
+
+ Run database migrations
+
+ ```shell
+ gitlab-rake gitlab:db:configure
+ ```
+
+### Example minimal setup
+
+This example uses 3 PostgreSQL servers, and 1 application node (with PgBouncer setup alongside).
+
+It differs from the [recommended setup](#example-recommended-setup) by moving the Consul servers into the same servers we use for PostgreSQL.
+The trade-off is between reducing server counts, against the increased operational complexity of needing to deal with PostgreSQL [failover](#failover-procedure) and [restore](#restore-procedure) procedures in addition to [Consul outage recovery](../high_availability/consul.md#outage-recovery) on the same set of machines.
+
+In this example we start with all servers on the same 10.6.0.0/16 private network range, they can connect to each freely other on those addresses.
+
+Here is a list and description of each machine and the assigned IP:
+
+- `10.6.0.21`: PostgreSQL master
+- `10.6.0.22`: PostgreSQL secondary
+- `10.6.0.23`: PostgreSQL secondary
+- `10.6.0.31`: GitLab application
+
+All passwords are set to `toomanysecrets`, please do not use this password or derived hashes.
+
+The `external_url` for GitLab is `http://gitlab.example.com`
+
+Please note that after the initial configuration, if a failover occurs, the PostgresSQL master will change to one of the available secondaries until it is failed back.
+
+#### Example minimal configuration for database servers
+
+##### Primary node
+
+On primary database node edit `/etc/gitlab/gitlab.rb`:
+
+```ruby
+# Disable all components except PostgreSQL, Repmgr, and Consul
+roles ['postgres_role']
+
+# PostgreSQL configuration
+postgresql['listen_address'] = '0.0.0.0'
+postgresql['hot_standby'] = 'on'
+postgresql['wal_level'] = 'replica'
+postgresql['shared_preload_libraries'] = 'repmgr_funcs'
+
+# Disable automatic database migrations
+gitlab_rails['auto_migrate'] = false
+
+# Configure the Consul agent
+consul['services'] = %w(postgresql)
+
+postgresql['pgbouncer_user_password'] = '771a8625958a529132abe6f1a4acb19c'
+postgresql['sql_user_password'] = '450409b85a0223a214b5fb1484f34d0f'
+postgresql['max_wal_senders'] = 4
+
+postgresql['trust_auth_cidr_addresses'] = %w(10.6.0.0/16)
+repmgr['trust_auth_cidr_addresses'] = %w(10.6.0.0/16)
+
+consul['configuration'] = {
+ server: true,
+ retry_join: %w(10.6.0.21 10.6.0.22 10.6.0.23)
+}
+```
+
+[Reconfigure Omnibus GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+
+##### Secondary nodes
+
+On secondary nodes, edit `/etc/gitlab/gitlab.rb` and add all the information added
+to primary node, noted above. In addition, append the following configuration
+
+```ruby
+# Specify if a node should attempt to be master on initialization
+repmgr['master_on_initialization'] = false
+```
+
+#### Example minimal configuration for application server
+
+On the server edit `/etc/gitlab/gitlab.rb`:
+
+```ruby
+external_url 'http://gitlab.example.com'
+
+gitlab_rails['db_host'] = '127.0.0.1'
+gitlab_rails['db_port'] = 6432
+gitlab_rails['db_password'] = 'toomanysecrets'
+gitlab_rails['auto_migrate'] = false
+
+postgresql['enable'] = false
+pgbouncer['enable'] = true
+consul['enable'] = true
+
+# Configure PgBouncer
+pgbouncer['admin_users'] = %w(pgbouncer gitlab-consul)
+
+# Configure Consul agent
+consul['watchers'] = %w(postgresql)
+
+pgbouncer['users'] = {
+ 'gitlab-consul': {
+ password: '5e0e3263571e3704ad655076301d6ebe'
+ },
+ 'pgbouncer': {
+ password: '771a8625958a529132abe6f1a4acb19c'
+ }
+}
+
+consul['configuration'] = {
+ retry_join: %w(10.6.0.21 10.6.0.22 10.6.0.23)
+}
+```
+
+[Reconfigure Omnibus GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+
+#### Example minimal setup manual steps
+
+The manual steps for this configuration are the same as for the [example recommended setup](#example-recommended-setup-manual-steps).
+
+### Failover procedure
+
+By default, if the master database fails, `repmgrd` should promote one of the
+standby nodes to master automatically, and Consul will update PgBouncer with
+the new master.
+
+If you need to failover manually, you have two options:
+
+**Shutdown the current master database**
+
+Run:
+
+```shell
+gitlab-ctl stop postgresql
+```
+
+The automated failover process will see this and failover to one of the
+standby nodes.
+
+**Or perform a manual failover**
+
+1. Ensure the old master node is not still active.
+1. Login to the server that should become the new master and run:
+
+ ```shell
+ gitlab-ctl repmgr standby promote
+ ```
+
+1. If there are any other standby servers in the cluster, have them follow
+ the new master server:
+
+ ```shell
+ gitlab-ctl repmgr standby follow NEW_MASTER
+ ```
+
+### Restore procedure
+
+If a node fails, it can be removed from the cluster, or added back as a standby
+after it has been restored to service.
+
+#### Remove a standby from the cluster
+
+ From any other node in the cluster, run:
+
+ ```shell
+ gitlab-ctl repmgr standby unregister --node=X
+ ```
+
+ where X is the value of node in `repmgr.conf` on the old server.
+
+ To find this, you can use:
+
+ ```shell
+ awk -F = '$1 == "node" { print $2 }' /var/opt/gitlab/postgresql/repmgr.conf
+ ```
+
+ It will output something like:
+
+ ```plaintext
+ 959789412
+ ```
+
+ Then you will use this ID to unregister the node:
+
+ ```shell
+ gitlab-ctl repmgr standby unregister --node=959789412
+ ```
+
+#### Add a node as a standby server
+
+ From the standby node, run:
+
+ ```shell
+ gitlab-ctl repmgr standby follow NEW_MASTER
+ gitlab-ctl restart repmgrd
+ ```
+
+ CAUTION: **Warning:** When the server is brought back online, and before
+ you switch it to a standby node, repmgr will report that there are two masters.
+ If there are any clients that are still attempting to write to the old master,
+ this will cause a split, and the old master will need to be resynced from
+ scratch by performing a `gitlab-ctl repmgr standby setup NEW_MASTER`.
+
+#### Add a failed master back into the cluster as a standby node
+
+ Once `repmgrd` and PostgreSQL are running, the node will need to follow the new
+ as a standby node.
+
+ ```shell
+ gitlab-ctl repmgr standby follow NEW_MASTER
+ ```
+
+ Once the node is following the new master as a standby, the node needs to be
+ [unregistered from the cluster on the new master node](#remove-a-standby-from-the-cluster).
+
+ Once the old master node has been unregistered from the cluster, it will need
+ to be setup as a new standby:
+
+ ```shell
+ gitlab-ctl repmgr standby setup NEW_MASTER
+ ```
+
+ Failure to unregister and read the old master node can lead to subsequent failovers
+ not working.
+
+### Alternate configurations
+
+#### Database authorization
+
+By default, we give any host on the database network the permission to perform
+repmgr operations using PostgreSQL's `trust` method. If you do not want this
+level of trust, there are alternatives.
+
+You can trust only the specific nodes that will be database clusters, or you
+can require md5 authentication.
+
+#### Trust specific addresses
+
+If you know the IP address, or FQDN of all database and PgBouncer nodes in the
+cluster, you can trust only those nodes.
+
+In `/etc/gitlab/gitlab.rb` on all of the database nodes, set
+`repmgr['trust_auth_cidr_addresses']` to an array of strings containing all of
+the addresses.
+
+If setting to a node's FQDN, they must have a corresponding PTR record in DNS.
+If setting to a node's IP address, specify it as `XXX.XXX.XXX.XXX/32`.
+
+For example:
+
+```ruby
+repmgr['trust_auth_cidr_addresses'] = %w(192.168.1.44/32 db2.example.com)
+```
+
+#### MD5 Authentication
+
+If you are running on an untrusted network, repmgr can use md5 authentication
+with a [`.pgpass` file](https://www.postgresql.org/docs/11/libpq-pgpass.html)
+to authenticate.
+
+You can specify by IP address, FQDN, or by subnet, using the same format as in
+the previous section:
+
+1. On the current master node, create a password for the `gitlab` and
+ `gitlab_repmgr` user:
+
+ ```shell
+ gitlab-psql -d template1
+ template1=# \password gitlab_repmgr
+ Enter password: ****
+ Confirm password: ****
+ template1=# \password gitlab
+ ```
+
+1. On each database node:
+
+ 1. Edit `/etc/gitlab/gitlab.rb`:
+ 1. Ensure `repmgr['trust_auth_cidr_addresses']` is **not** set
+ 1. Set `postgresql['md5_auth_cidr_addresses']` to the desired value
+ 1. Set `postgresql['sql_replication_user'] = 'gitlab_repmgr'`
+ 1. Reconfigure with `gitlab-ctl reconfigure`
+ 1. Restart PostgreSQL with `gitlab-ctl restart postgresql`
+
+ 1. Create a `.pgpass` file. Enter the `gitlab_repmgr` password twice to
+ when asked:
+
+ ```shell
+ gitlab-ctl write-pgpass --user gitlab_repmgr --hostuser gitlab-psql --database '*'
+ ```
+
+1. On each PgBouncer node, edit `/etc/gitlab/gitlab.rb`:
+ 1. Ensure `gitlab_rails['db_password']` is set to the plaintext password for
+ the `gitlab` database user
+ 1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect
+
+## Troubleshooting
+
+### Consul and PostgreSQL changes not taking effect
+
+Due to the potential impacts, `gitlab-ctl reconfigure` only reloads Consul and PostgreSQL, it will not restart the services. However, not all changes can be activated by reloading.
+
+To restart either service, run `gitlab-ctl restart SERVICE`
+
+For PostgreSQL, it is usually safe to restart the master node by default. Automatic failover defaults to a 1 minute timeout. Provided the database returns before then, nothing else needs to be done. To be safe, you can stop `repmgrd` on the standby nodes first with `gitlab-ctl stop repmgrd`, then start afterwards with `gitlab-ctl start repmgrd`.
+
+On the Consul server nodes, it is important to restart the Consul service in a controlled fashion. Read our [Consul documentation](../high_availability/consul.md#restarting-the-server-cluster) for instructions on how to restart the service.
+
+### `gitlab-ctl repmgr-check-master` command produces errors
+
+If this command displays errors about database permissions it is likely that something failed during
+install, resulting in the `gitlab-consul` database user getting incorrect permissions. Follow these
+steps to fix the problem:
+
+1. On the master database node, connect to the database prompt - `gitlab-psql -d template1`
+1. Delete the `gitlab-consul` user - `DROP USER "gitlab-consul";`
+1. Exit the database prompt - `\q`
+1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) and the user will be re-added with the proper permissions.
+1. Change to the `gitlab-consul` user - `su - gitlab-consul`
+1. Try the check command again - `gitlab-ctl repmgr-check-master`.
+
+Now there should not be errors. If errors still occur then there is another problem.
+
+### PgBouncer error `ERROR: pgbouncer cannot connect to server`
+
+You may get this error when running `gitlab-rake gitlab:db:configure` or you
+may see the error in the PgBouncer log file.
+
+```plaintext
+PG::ConnectionBad: ERROR: pgbouncer cannot connect to server
+```
+
+The problem may be that your PgBouncer node's IP address is not included in the
+`trust_auth_cidr_addresses` setting in `/etc/gitlab/gitlab.rb` on the database nodes.
+
+You can confirm that this is the issue by checking the PostgreSQL log on the master
+database node. If you see the following error then `trust_auth_cidr_addresses`
+is the problem.
+
+```plaintext
+2018-03-29_13:59:12.11776 FATAL: no pg_hba.conf entry for host "123.123.123.123", user "pgbouncer", database "gitlabhq_production", SSL off
+```
+
+To fix the problem, add the IP address to `/etc/gitlab/gitlab.rb`.
+
+```ruby
+postgresql['trust_auth_cidr_addresses'] = %w(123.123.123.123/32 <other_cidrs>)
+```
+
+[Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+
+### Issues with other components
+
+If you're running into an issue with a component not outlined here, be sure to check the troubleshooting section of their specific documentation page.
+
+- [Consul](../high_availability/consul.md#troubleshooting)
+- [PostgreSQL](https://docs.gitlab.com/omnibus/settings/database.html#troubleshooting)
+- [GitLab application](../high_availability/gitlab.md#troubleshooting)
diff --git a/doc/administration/postgresql/standalone.md b/doc/administration/postgresql/standalone.md
new file mode 100644
index 00000000000..3e7826ce009
--- /dev/null
+++ b/doc/administration/postgresql/standalone.md
@@ -0,0 +1,65 @@
+# Standalone PostgreSQL using Omnibus GitLab **(CORE ONLY)**
+
+If you wish to have your database service hosted separately from your GitLab
+application server(s), you can do this using the PostgreSQL binaries packaged
+together with Omnibus GitLab. This is recommended as part of our
+[reference architecture for up to 2,000 users](../reference_architectures/2k_users.md).
+
+## Setting it up
+
+1. SSH into the PostgreSQL server.
+1. [Download/install](https://about.gitlab.com/install/) the Omnibus GitLab
+ package you want using **steps 1 and 2** from the GitLab downloads page.
+ - Do not complete any other steps on the download page.
+1. Generate a password hash for PostgreSQL. This assumes you will use the default
+ username of `gitlab` (recommended). The command will request a password
+ and confirmation. Use the value that is output by this command in the next
+ step as the value of `POSTGRESQL_PASSWORD_HASH`.
+
+ ```shell
+ sudo gitlab-ctl pg-password-md5 gitlab
+ ```
+
+1. Edit `/etc/gitlab/gitlab.rb` and add the contents below, updating placeholder
+ values appropriately.
+
+ - `POSTGRESQL_PASSWORD_HASH` - The value output from the previous step
+ - `APPLICATION_SERVER_IP_BLOCKS` - A space delimited list of IP subnets or IP
+ addresses of the GitLab application servers that will connect to the
+ database. Example: `%w(123.123.123.123/32 123.123.123.234/32)`
+
+ ```ruby
+ # Disable all components except PostgreSQL
+ roles ['postgres_role']
+ repmgr['enable'] = false
+ consul['enable'] = false
+ prometheus['enable'] = false
+ alertmanager['enable'] = false
+ pgbouncer_exporter['enable'] = false
+ redis_exporter['enable'] = false
+ gitlab_exporter['enable'] = false
+
+ postgresql['listen_address'] = '0.0.0.0'
+ postgresql['port'] = 5432
+
+ # Replace POSTGRESQL_PASSWORD_HASH with a generated md5 value
+ postgresql['sql_user_password'] = 'POSTGRESQL_PASSWORD_HASH'
+
+ # Replace XXX.XXX.XXX.XXX/YY with Network Address
+ # ????
+ postgresql['trust_auth_cidr_addresses'] = %w(APPLICATION_SERVER_IP_BLOCKS)
+
+ # Disable automatic database migrations
+ gitlab_rails['auto_migrate'] = false
+ ```
+
+ NOTE: **Note:** The role `postgres_role` was introduced with GitLab 10.3
+
+1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+1. Note the PostgreSQL node's IP address or hostname, port, and
+ plain text password. These will be necessary when configuring the GitLab
+ application servers later.
+1. [Enable monitoring](replication_and_failover.md#enable-monitoring)
+
+Advanced configuration options are supported and can be added if
+needed.
diff --git a/doc/administration/raketasks/github_import.md b/doc/administration/raketasks/github_import.md
index 83a3d2c8884..a46a2b34687 100644
--- a/doc/administration/raketasks/github_import.md
+++ b/doc/administration/raketasks/github_import.md
@@ -12,6 +12,11 @@ Bear in mind that the syntax is very specific. Remove any spaces within the argu
before/after the brackets. Also, some shells (for example, `zsh`) can interpret the open/close brackets
(`[]`) separately. You may need to either escape the brackets or use double quotes.
+## Caveats
+
+If the GitHub [rate limit](https://developer.github.com/v3/#rate-limiting) is reached while importing,
+the importing process will wait (`sleep()`) until it can continue importing.
+
## Importing multiple projects
To import a project from the list of your GitHub projects available:
diff --git a/doc/administration/raketasks/ldap.md b/doc/administration/raketasks/ldap.md
index 2871a9235a3..d168e3d568c 100644
--- a/doc/administration/raketasks/ldap.md
+++ b/doc/administration/raketasks/ldap.md
@@ -32,13 +32,13 @@ rake gitlab:ldap:check[50]
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/14735) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.2.
-The following task will run a [group sync](../auth/ldap-ee.md#group-sync) immediately. This is valuable
+The following task will run a [group sync](../auth/ldap/index.md#group-sync-starter-only) immediately. This is valuable
when you'd like to update all configured group memberships against LDAP without
waiting for the next scheduled group sync to be run.
NOTE: **NOTE:**
If you'd like to change the frequency at which a group sync is performed,
-[adjust the cron schedule](../auth/ldap-ee.md#adjusting-ldap-group-sync-schedule)
+[adjust the cron schedule](../auth/ldap/index.md#adjusting-ldap-group-sync-schedule-starter-only)
instead.
**Omnibus Installation**
diff --git a/doc/administration/raketasks/maintenance.md b/doc/administration/raketasks/maintenance.md
index eee68c0da0a..78094f00a43 100644
--- a/doc/administration/raketasks/maintenance.md
+++ b/doc/administration/raketasks/maintenance.md
@@ -51,6 +51,40 @@ Hooks: /home/git/gitlab-shell/hooks/
Git: /usr/bin/git
```
+## Show GitLab license information **(STARTER ONLY)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20501) in GitLab Starter 12.6.
+
+This command shows information about your [GitLab license](../../user/admin_area/license.md) and
+how many seats are used. It is only available on GitLab Enterprise
+installations: a license cannot be installed into GitLab Community Edition.
+
+These may be useful when raising tickets with Support, or for programmatically
+checking your license parameters.
+
+**Omnibus Installation**
+
+```shell
+sudo gitlab-rake gitlab:license:info
+```
+
+**Source Installation**
+
+```shell
+bundle exec rake gitlab:license:info RAILS_ENV=production
+```
+
+Example output:
+
+```plaintext
+Today's Date: 2020-02-29
+Current User Count: 30
+Max Historical Count: 30
+Max Users in License: 40
+License valid from: 2019-11-29 to 2020-11-28
+Email associated with license: user@example.com
+```
+
## Check GitLab configuration
The `gitlab:check` Rake task runs the following Rake tasks:
@@ -62,7 +96,7 @@ The `gitlab:check` Rake task runs the following Rake tasks:
It will check that each component was set up according to the installation guide and suggest fixes
for issues found. This command must be run from your application server and will not work correctly on
-component servers like [Gitaly](../gitaly/index.md#running-gitaly-on-its-own-server).
+component servers like [Gitaly](../gitaly/index.md#run-gitaly-on-its-own-server).
You may also have a look at our troubleshooting guides for:
@@ -265,6 +299,20 @@ database: gitlabhq_production
up migration_id migration_name
```
+## Run incomplete database migrations
+
+Database migrations can be stuck in an incomplete state. That is, they'll have a `down`
+status in the output of the `sudo gitlab-rake db:migrate:status` command.
+
+To complete these migrations, use the following Rake task:
+
+```shell
+sudo gitlab-rake db:migrate
+```
+
+After the command completes, run `sudo gitlab-rake db:migrate:status` to check if all
+migrations are completed (have an `up` status).
+
## Import common metrics
Sometimes you may need to re-import the common metrics that power the Metrics dashboards.
diff --git a/doc/administration/raketasks/praefect.md b/doc/administration/raketasks/praefect.md
index c3dadb6bc30..c48e23df77a 100644
--- a/doc/administration/raketasks/praefect.md
+++ b/doc/administration/raketasks/praefect.md
@@ -7,7 +7,7 @@
Prints out checksums of the repository of a given project_id on the primary as well as secondary internal Gitaly nodes.
NOTE: **Note:**
-This only is relevant and works for projects that have been created on a praefect storage. See the [Praefect Documentation](../gitaly/praefect.md) for configuring Praefect.
+This only is relevant and works for projects that have been created on a Praefect storage. See the [Praefect Documentation](../gitaly/praefect.md) for configuring Praefect.
**Omnibus Installation**
diff --git a/doc/administration/raketasks/project_import_export.md b/doc/administration/raketasks/project_import_export.md
index 2ab8b13e29e..2e65e889c90 100644
--- a/doc/administration/raketasks/project_import_export.md
+++ b/doc/administration/raketasks/project_import_export.md
@@ -1,6 +1,6 @@
# Project import/export administration **(CORE ONLY)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/3050) in GitLab 8.9.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/3050) in GitLab 8.9.
> - From GitLab 11.3, import/export can use object storage automatically.
GitLab provides Rake tasks relating to project import and export. For more information, see:
diff --git a/doc/administration/raketasks/storage.md b/doc/administration/raketasks/storage.md
index 30f50c24138..74fd2c2ebb6 100644
--- a/doc/administration/raketasks/storage.md
+++ b/doc/administration/raketasks/storage.md
@@ -104,7 +104,7 @@ You can monitor the progress in the **{admin}** **Admin Area > Monitoring > Back
There is a specific queue you can watch to see how long it will take to finish:
`hashed_storage:hashed_storage_project_migrate`.
-After it reaches zero, you can confirm every project has been migrated by running the commands bellow.
+After it reaches zero, you can confirm every project has been migrated by running the commands below.
If you find it necessary, you can run this migration script again to schedule missing projects.
Any error or warning will be logged in Sidekiq's log file.
diff --git a/doc/administration/raketasks/uploads/migrate.md b/doc/administration/raketasks/uploads/migrate.md
index d58b802b024..b164c4e744d 100644
--- a/doc/administration/raketasks/uploads/migrate.md
+++ b/doc/administration/raketasks/uploads/migrate.md
@@ -128,7 +128,7 @@ CAUTION: **Warning:**
**Extended downtime is required** so no new files are created in object storage during
the migration. A configuration setting will be added soon to allow migrating
from object storage to local files with only a brief moment of downtime for configuration changes.
-To follow progress, see the [relevant issue](https://gitlab.com/gitlab-org/gitlab/issues/30979).
+To follow progress, see the [relevant issue](https://gitlab.com/gitlab-org/gitlab/-/issues/30979).
### All-in-one Rake task
diff --git a/doc/administration/raketasks/uploads/sanitize.md b/doc/administration/raketasks/uploads/sanitize.md
index 7c760b95c33..9586ab2c6f4 100644
--- a/doc/administration/raketasks/uploads/sanitize.md
+++ b/doc/administration/raketasks/uploads/sanitize.md
@@ -65,5 +65,5 @@ The output is written into an `exif.log` file because it will probably be long.
If sanitization fails for an upload, an error message should be in the output of the Rake task.
Typical reasons include that the file is missing in the storage or it's not a valid image.
-[Report](https://gitlab.com/gitlab-org/gitlab/issues/new) any issues and use the prefix 'EXIF' in
+[Report](https://gitlab.com/gitlab-org/gitlab/-/issues/new) any issues and use the prefix 'EXIF' in
the issue title with the error output and (if possible) the image.
diff --git a/doc/administration/reference_architectures/10k_users.md b/doc/administration/reference_architectures/10k_users.md
index 7f31f336251..a15fcf722a5 100644
--- a/doc/administration/reference_architectures/10k_users.md
+++ b/doc/administration/reference_architectures/10k_users.md
@@ -8,8 +8,8 @@ For a full list of reference architectures, see
> - **High Availability:** True
> - **Test RPS rates:** API: 200 RPS, Web: 20 RPS, Git: 20 RPS
-| Service | Nodes | Configuration ([8](#footnotes)) | GCP | AWS ([9](#footnotes)) | Azure([9](#footnotes)) |
-|--------------------------------------------------------------|-------|---------------------------------|----------------|-----------------------|------------------------|
+| Service | Nodes | Configuration ([8](#footnotes)) | GCP | AWS | Azure |
+|--------------------------------------------------------------|-------|---------------------------------|----------------|-----------------------|----------------|
| GitLab Rails ([1](#footnotes)) | 3 | 32 vCPU, 28.8GB Memory | n1-highcpu-32 | c5.9xlarge | F32s v2 |
| PostgreSQL | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | D4s v3 |
| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
@@ -56,7 +56,7 @@ For a full list of reference architectures, see
1. NFS can be used as an alternative for both repository data (replacing Gitaly) and
object storage but this isn't typically recommended for performance reasons. Note however it is required for
- [GitLab Pages](https://gitlab.com/gitlab-org/gitlab-pages/issues/196).
+ [GitLab Pages](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/196).
1. Our architectures have been tested and validated with [HAProxy](https://www.haproxy.org/)
as the load balancer. Although other load balancers with similar feature sets
@@ -74,6 +74,3 @@ For a full list of reference architectures, see
or higher, are required for your CPU or Node counts accordingly. For more information, a
[Sysbench](https://github.com/akopytov/sysbench) benchmark of the CPU can be found
[here](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Reference-Architectures/GCP-CPU-Benchmarks).
-
-1. AWS-equivalent and Azure-equivalent configurations are rough suggestions
- and may change in the future. They have not yet been tested and validated.
diff --git a/doc/administration/reference_architectures/1k_users.md b/doc/administration/reference_architectures/1k_users.md
index b6aaffa9488..34805a8ac68 100644
--- a/doc/administration/reference_architectures/1k_users.md
+++ b/doc/administration/reference_architectures/1k_users.md
@@ -7,11 +7,18 @@ For a full list of reference architectures, see
> - **Supported users (approximate):** 1,000
> - **High Availability:** False
-| Users | Configuration([8](#footnotes)) | GCP | AWS([9](#footnotes)) | Azure([9](#footnotes)) |
-|-------|--------------------------------|---------------|----------------------|------------------------|
-| 100 | 2 vCPU, 7.2GB Memory | n1-standard-2 | m5.large | D2s v3 |
-| 500 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | D4s v3 |
-| 1000 | 8 vCPU, 30GB Memory | n1-standard-8 | m5.2xlarge | D8s v3 |
+| Users | Configuration([8](#footnotes)) | GCP | AWS | Azure |
+|-------|------------------------------------|----------------|---------------------|------------------------|
+| 500 | 4 vCPU, 3.6GB Memory | `n1-highcpu-4` | `c5.xlarge` | F4s v2 |
+| 1000 | 8 vCPU, 7.2GB Memory | `n1-highcpu-8` | `c5.2xlarge` | F8s v2 |
+
+In addition to the above, we recommend having at least
+2GB of swap on your server, even if you currently have
+enough available RAM. Having swap will help reduce the chance of errors occurring
+if your available memory changes. We also recommend
+configuring the kernel's swappiness setting
+to a low value like `10` to make the most of your RAM while still having the swap
+available when needed.
For situations where you need to serve up to 1,000 users, a single-node
solution with [frequent backups](index.md#automated-backups-core-only) is appropriate
@@ -25,7 +32,7 @@ requirements, this is the ideal solution.
NOTE: **Note:**
You can also optionally configure GitLab to use an
-[external PostgreSQL service](../external_database.md) or an
+[external PostgreSQL service](../postgresql/external.md) or an
[external object storage service](../high_availability/object_storage.md) for
added performance and reliability at a reduced complexity cost.
@@ -59,7 +66,7 @@ added performance and reliability at a reduced complexity cost.
1. NFS can be used as an alternative for both repository data (replacing Gitaly) and
object storage but this isn't typically recommended for performance reasons. Note however it is required for
- [GitLab Pages](https://gitlab.com/gitlab-org/gitlab-pages/issues/196).
+ [GitLab Pages](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/196).
1. Our architectures have been tested and validated with [HAProxy](https://www.haproxy.org/)
as the load balancer. Although other load balancers with similar feature sets
@@ -77,6 +84,3 @@ added performance and reliability at a reduced complexity cost.
or higher, are required for your CPU or Node counts accordingly. For more information, a
[Sysbench](https://github.com/akopytov/sysbench) benchmark of the CPU can be found
[here](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Reference-Architectures/GCP-CPU-Benchmarks).
-
-1. AWS-equivalent and Azure-equivalent configurations are rough suggestions
- and may change in the future. They have not yet been tested and validated.
diff --git a/doc/administration/reference_architectures/25k_users.md b/doc/administration/reference_architectures/25k_users.md
index 2ee692d635c..d851fa124c6 100644
--- a/doc/administration/reference_architectures/25k_users.md
+++ b/doc/administration/reference_architectures/25k_users.md
@@ -8,23 +8,23 @@ For a full list of reference architectures, see
> - **High Availability:** True
> - **Test RPS rates:** API: 500 RPS, Web: 50 RPS, Git: 50 RPS
-| Service | Nodes | Configuration ([8](#footnotes)) | GCP | AWS ([9](#footnotes)) | Azure([9](#footnotes)) |
-|--------------------------------------------------------------|-------|---------------------------------|----------------|-----------------------|------------------------|
-| GitLab Rails ([1](#footnotes)) | 5 | 32 vCPU, 28.8GB Memory | n1-highcpu-32 | c5.9xlarge | F32s v2 |
-| PostgreSQL | 3 | 8 vCPU, 30GB Memory | n1-standard-8 | m5.2xlarge | D8s v3 |
-| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
-| Gitaly ([2](#footnotes)) ([5](#footnotes)) ([7](#footnotes)) | X | 32 vCPU, 120GB Memory | n1-standard-32 | m5.8xlarge | D32s v3 |
-| Redis ([3](#footnotes)) - Cache | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | D4s v3 |
-| Redis ([3](#footnotes)) - Queues / Shared State | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | D4s v3 |
-| Redis Sentinel ([3](#footnotes)) - Cache | 3 | 1 vCPU, 1.7GB Memory | g1-small | t2.small | B1MS |
-| Redis Sentinel ([3](#footnotes)) - Queues / Shared State | 3 | 1 vCPU, 1.7GB Memory | g1-small | t2.small | B1MS |
-| Consul | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
-| Sidekiq | 4 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | D4s v3 |
+| Service | Nodes | Configuration ([8](#footnotes)) | GCP | AWS | Azure |
+|--------------------------------------------------------------|-------|---------------------------------|------------------|-----------------------|----------------|
+| GitLab Rails ([1](#footnotes)) | 5 | 32 vCPU, 28.8GB Memory | `n1-highcpu-32` | `c5.9xlarge` | F32s v2 |
+| PostgreSQL | 3 | 8 vCPU, 30GB Memory | `n1-standard-8` | `m5.2xlarge` | D8s v3 |
+| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | `n1-highcpu-2` | `c5.large` | F2s v2 |
+| Gitaly ([2](#footnotes)) ([5](#footnotes)) ([7](#footnotes)) | X | 32 vCPU, 120GB Memory | `n1-standard-32` | `m5.8xlarge` | D32s v3 |
+| Redis ([3](#footnotes)) - Cache | 3 | 4 vCPU, 15GB Memory | `n1-standard-4` | `m5.xlarge` | D4s v3 |
+| Redis ([3](#footnotes)) - Queues / Shared State | 3 | 4 vCPU, 15GB Memory | `n1-standard-4` | `m5.xlarge` | D4s v3 |
+| Redis Sentinel ([3](#footnotes)) - Cache | 3 | 1 vCPU, 1.7GB Memory | `g1-small` | `t2.small` | B1MS |
+| Redis Sentinel ([3](#footnotes)) - Queues / Shared State | 3 | 1 vCPU, 1.7GB Memory | `g1-small` | `t2.small` | B1MS |
+| Consul | 3 | 2 vCPU, 1.8GB Memory | `n1-highcpu-2` | `c5.large` | F2s v2 |
+| Sidekiq | 4 | 4 vCPU, 15GB Memory | `n1-standard-4` | `m5.xlarge` | D4s v3 |
| Object Storage ([4](#footnotes)) | - | - | - | - | - |
-| NFS Server ([5](#footnotes)) ([7](#footnotes)) | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | F4s v2 |
-| Monitoring node | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | F4s v2 |
-| External load balancing node ([6](#footnotes)) | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
-| Internal load balancing node ([6](#footnotes)) | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | F4s v2 |
+| NFS Server ([5](#footnotes)) ([7](#footnotes)) | 1 | 4 vCPU, 3.6GB Memory | `n1-highcpu-4` | `c5.xlarge` | F4s v2 |
+| Monitoring node | 1 | 4 vCPU, 3.6GB Memory | `n1-highcpu-4` | `c5.xlarge` | F4s v2 |
+| External load balancing node ([6](#footnotes)) | 1 | 4 vCPU, 3.6GB Memory | `n1-highcpu-4` | `c5.xlarge` | F4s v2 |
+| Internal load balancing node ([6](#footnotes)) | 1 | 4 vCPU, 3.6GB Memory | `n1-highcpu-4` | `c5.xlarge` | F4s v2 |
## Footnotes
@@ -56,7 +56,7 @@ For a full list of reference architectures, see
1. NFS can be used as an alternative for both repository data (replacing Gitaly) and
object storage but this isn't typically recommended for performance reasons. Note however it is required for
- [GitLab Pages](https://gitlab.com/gitlab-org/gitlab-pages/issues/196).
+ [GitLab Pages](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/196).
1. Our architectures have been tested and validated with [HAProxy](https://www.haproxy.org/)
as the load balancer. Although other load balancers with similar feature sets
@@ -74,6 +74,3 @@ For a full list of reference architectures, see
or higher, are required for your CPU or Node counts accordingly. For more information, a
[Sysbench](https://github.com/akopytov/sysbench) benchmark of the CPU can be found
[here](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Reference-Architectures/GCP-CPU-Benchmarks).
-
-1. AWS-equivalent and Azure-equivalent configurations are rough suggestions
- and may change in the future. They have not yet been tested and validated.
diff --git a/doc/administration/reference_architectures/2k_users.md b/doc/administration/reference_architectures/2k_users.md
index 874e00e6722..0a3ade1acf1 100644
--- a/doc/administration/reference_architectures/2k_users.md
+++ b/doc/administration/reference_architectures/2k_users.md
@@ -1,3 +1,7 @@
+---
+reading_time: true
+---
+
# Reference architecture: up to 2,000 users
This page describes GitLab reference architecture for up to 2,000 users.
@@ -6,85 +10,864 @@ For a full list of reference architectures, see
> - **Supported users (approximate):** 2,000
> - **High Availability:** False
-> - **Test RPS rates:** API: 40 RPS, Web: 4 RPS, Git: 4 RPS
-
-| Service | Nodes | Configuration ([8](#footnotes)) | GCP | AWS ([9](#footnotes)) | Azure([9](#footnotes)) |
-|--------------------------------------------------------------|-------|---------------------------------|---------------|-----------------------|----------------|
-| External load balancing node ([6](#footnotes)) | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
-| Object Storage ([4](#footnotes)) | - | - | - | - | - |
-| NFS Server ([5](#footnotes)) ([7](#footnotes)) | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | F4s v2 |
-| PostgreSQL | 1 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large | D2s v3 |
-| Redis ([3](#footnotes)) | 1 | 1 vCPU, 3.75GB Memory | n1-standard-1 | m5.large | D2s v3 |
-| Gitaly ([5](#footnotes)) ([7](#footnotes)) | X ([2](#footnotes)) | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | D4s v3 |
-| GitLab Rails ([1](#footnotes)) | 2 | 8 vCPU, 7.2GB Memory | n1-highcpu-8 | c5.2xlarge | F8s v2 |
-| Monitoring node | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
-
-## Setup instructions
-
-1. [Configure the external load balancing node](../high_availability/load_balancer.md)
- that will handle the load balancing of the two GitLab application services nodes.
-1. [Configure the Object Storage](../object_storage.md) ([4](#footnotes)) used for shared data objects.
-1. (Optional) [Configure NFS](../high_availability/nfs.md) to have
- shared disk storage service as an alternative to Gitaly and/or
- [Object Storage](../object_storage.md) (although not recommended).
- NFS is required for GitLab Pages, you can skip this step if you're not using that feature.
-1. [Configure PostgreSQL](../high_availability/load_balancer.md), the database for GitLab.
-1. [Configure Redis](../high_availability/redis.md).
-1. [Configure Gitaly](../gitaly/index.md#running-gitaly-on-its-own-server),
- which is used to provide access to the Git repositories.
-1. [Configure the main GitLab Rails application](../high_availability/gitlab.md)
- to run Puma/Unicorn, Workhorse, GitLab Shell, and to serve all
- frontend requests (UI, API, Git over HTTP/SSH).
-1. [Configure Prometheus](../high_availability/monitoring_node.md) to monitor your GitLab environment.
-
-## Footnotes
-
-1. In our architectures we run each GitLab Rails node using the Puma webserver
- and have its number of workers set to 90% of available CPUs along with four threads. For
- nodes that are running Rails with other components the worker value should be reduced
- accordingly where we've found 50% achieves a good balance but this is dependent
- on workload.
-
-1. Gitaly node requirements are dependent on customer data, specifically the number of
- projects and their sizes. We recommend two nodes as an absolute minimum for HA environments
- and at least four nodes should be used when supporting 50,000 or more users.
- We also recommend that each Gitaly node should store no more than 5TB of data
- and have the number of [`gitaly-ruby` workers](../gitaly/index.md#gitaly-ruby)
- set to 20% of available CPUs. Additional nodes should be considered in conjunction
- with a review of expected data size and spread based on the recommendations above.
-
-1. Recommended Redis setup differs depending on the size of the architecture.
- For smaller architectures (less than 3,000 users) a single instance should suffice.
- For medium sized installs (3,000 - 5,000) we suggest one Redis cluster for all
- classes and that Redis Sentinel is hosted alongside Consul.
- For larger architectures (10,000 users or more) we suggest running a separate
- [Redis Cluster](../high_availability/redis.md#running-multiple-redis-clusters) for the Cache class
- and another for the Queues and Shared State classes respectively. We also recommend
- that you run the Redis Sentinel clusters separately for each Redis Cluster.
-
-1. For data objects such as LFS, Uploads, Artifacts, etc. We recommend an [Object Storage service](../object_storage.md)
- over NFS where possible, due to better performance and availability.
-
-1. NFS can be used as an alternative for both repository data (replacing Gitaly) and
- object storage but this isn't typically recommended for performance reasons. Note however it is required for
- [GitLab Pages](https://gitlab.com/gitlab-org/gitlab-pages/issues/196).
-
-1. Our architectures have been tested and validated with [HAProxy](https://www.haproxy.org/)
- as the load balancer. Although other load balancers with similar feature sets
- could also be used, those load balancers have not been validated.
-
-1. We strongly recommend that any Gitaly or NFS nodes be set up with SSD disks over
- HDD with a throughput of at least 8,000 IOPS for read operations and 2,000 IOPS for write
- as these components have heavy I/O. These IOPS values are recommended only as a starter
- as with time they may be adjusted higher or lower depending on the scale of your
- environment's workload. If you're running the environment on a Cloud provider
- you may need to refer to their documentation on how configure IOPS correctly.
-
-1. The architectures were built and tested with the [Intel Xeon E5 v3 (Haswell)](https://cloud.google.com/compute/docs/cpu-platforms)
- CPU platform on GCP. On different hardware you may find that adjustments, either lower
- or higher, are required for your CPU or Node counts accordingly. For more information, a
- [Sysbench](https://github.com/akopytov/sysbench) benchmark of the CPU can be found
- [here](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Reference-Architectures/GCP-CPU-Benchmarks).
-
-1. AWS-equivalent and Azure-equivalent configurations are rough suggestions
- and may change in the future. They have not yet been tested and validated.
+> - **Test requests per second (RPS) rates:** API: 40 RPS, Web: 4 RPS, Git: 4 RPS
+
+| Service | Nodes | Configuration | GCP | AWS | Azure |
+|--------------------------------------------------------------|-----------|---------------------------------|---------------|-----------------------|----------------|
+| Load balancer | 1 | 2 vCPU, 1.8GB memory | n1-highcpu-2 | c5.large | F2s v2 |
+| Object storage | n/a | n/a | n/a | n/a | n/a |
+| NFS server (optional, not recommended) | 1 | 4 vCPU, 3.6GB memory | n1-highcpu-4 | c5.xlarge | F4s v2 |
+| PostgreSQL | 1 | 2 vCPU, 7.5GB memory | n1-standard-2 | m5.large | D2s v3 |
+| Redis | 1 | 1 vCPU, 3.75GB memory | n1-standard-1 | m5.large | D2s v3 |
+| Gitaly | 1 | 4 vCPU, 15GB memory | n1-standard-4 | m5.xlarge | D4s v3 |
+| GitLab Rails | 2 | 8 vCPU, 7.2GB memory | n1-highcpu-8 | c5.2xlarge | F8s v2 |
+| Monitoring node | 1 | 2 vCPU, 1.8GB memory | n1-highcpu-2 | c5.large | F2s v2 |
+
+The Google Cloud Platform (GCP) architectures were built and tested using the
+[Intel Xeon E5 v3 (Haswell)](https://cloud.google.com/compute/docs/cpu-platforms)
+CPU platform. On different hardware you may find that adjustments, either lower
+or higher, are required for your CPU or node counts. For more information, see
+our [Sysbench](https://github.com/akopytov/sysbench)-based
+[CPU benchmark](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Reference-Architectures/GCP-CPU-Benchmarks).
+
+AWS-equivalent and Azure-equivalent configurations are rough suggestions that
+may change in the future, and haven't been tested or validated.
+
+Due to better performance and availability, for data objects (such as LFS,
+uploads, or artifacts), using an [object storage service](#configure-the-object-storage)
+is recommended instead of using NFS. Using an object storage service also
+doesn't require you to provision and maintain a node.
+
+## Setup components
+
+To set up GitLab and its components to accommodate up to 2,000 users:
+
+1. [Configure the external load balancing node](#configure-the-load-balancer)
+ to handle the load balancing of the two GitLab application services nodes.
+1. [Configure the object storage](#configure-the-object-storage) used for
+ shared data objects.
+1. [Configure NFS](#configure-nfs-optional) (optional, and not recommended)
+ to have shared disk storage service as an alternative to Gitaly or object
+ storage. You can skip this step if you're not using GitLab Pages (which
+ requires NFS).
+1. [Configure PostgreSQL](#configure-postgresql), the database for GitLab.
+1. [Configure Redis](#configure-redis).
+1. [Configure Gitaly](#configure-gitaly), which provides access to the Git
+ repositories.
+1. [Configure the main GitLab Rails application](#configure-gitlab-rails)
+ to run Puma/Unicorn, Workhorse, GitLab Shell, and to serve all frontend
+ requests (which include UI, API, and Git over HTTP/SSH).
+1. [Configure Prometheus](#configure-prometheus) to monitor your GitLab
+ environment.
+
+## Configure the load balancer
+
+NOTE: **Note:**
+This architecture has been tested and validated with [HAProxy](https://www.haproxy.org/).
+Although you can use a load balancer with a similar set of features, GitLab
+hasn't validated other load balancers.
+
+In an active/active GitLab configuration, you'll need a load balancer to route
+traffic to the application servers. The specifics for which load balancer to
+use or its exact configuration is out of scope for the GitLab documentation.
+If you're managing multi-node systems (including GitLab) you'll probably
+already have a load balancer of choice. Some examples including HAProxy
+(open-source), F5 Big-IP LTM, and Citrix Net Scaler. This documentation
+includes the ports and protocols for use with GitLab.
+
+The next question is how you will handle SSL in your environment. There are
+several different options:
+
+- [The application node terminates SSL](#application-node-terminates-ssl).
+- [The load balancer terminates SSL without backend SSL](#load-balancer-terminates-ssl-without-backend-ssl)
+ and communication is not secure between the load balancer and the application node.
+- [The load balancer terminates SSL with backend SSL](#load-balancer-terminates-ssl-with-backend-ssl)
+ and communication is *secure* between the load balancer and the application node.
+
+### Application node terminates SSL
+
+Configure your load balancer to pass connections on port 443 as `TCP` instead
+of `HTTP(S)`. This will pass the connection unaltered to the application node's
+NGINX service, which has the SSL certificate and listens to port 443.
+
+For details about managing SSL certificates and configuring NGINX, see the
+[NGINX HTTPS documentation](https://docs.gitlab.com/omnibus/settings/nginx.html#enable-https).
+
+### Load balancer terminates SSL without backend SSL
+
+Configure your load balancer to use the `HTTP(S)` protocol instead of `TCP`.
+The load balancer will be responsible for both managing SSL certificates and
+terminating SSL.
+
+Due to communication between the load balancer and GitLab not being secure,
+you'll need to complete some additional configuration. For details, see the
+[NGINX proxied SSL documentation](https://docs.gitlab.com/omnibus/settings/nginx.html#supporting-proxied-ssl).
+
+### Load balancer terminates SSL with backend SSL
+
+Configure your load balancers (or single balancer, if you have only one) to use
+the `HTTP(S)` protocol rather than `TCP`. The load balancers will be
+responsible for the managing SSL certificates for end users.
+
+Traffic will be secure between the load balancers and NGINX in this scenario,
+and there's no need to add a configuration for proxied SSL. However, you'll
+need to add a configuration to GitLab to configure SSL certificates. For
+details about managing SSL certificates and configuring NGINX, see the
+[NGINX HTTPS documentation](https://docs.gitlab.com/omnibus/settings/nginx.html#enable-https).
+
+### Ports
+
+The basic load balancer ports you should use are described in the following
+table:
+
+| Port | Backend Port | Protocol |
+| ------- | ------------ | ------------------------ |
+| 80 | 80 | HTTP (*1*) |
+| 443 | 443 | TCP or HTTPS (*1*) (*2*) |
+| 22 | 22 | TCP |
+
+- (*1*): [Web terminal](../../ci/environments/index.md#web-terminals) support
+ requires your load balancer to correctly handle WebSocket connections.
+ When using HTTP or HTTPS proxying, your load balancer must be configured
+ to pass through the `Connection` and `Upgrade` hop-by-hop headers. For
+ details, see the [web terminal](../integration/terminal.md) integration guide.
+- (*2*): When using the HTTPS protocol for port 443, you'll need to add an SSL
+ certificate to the load balancers. If you need to terminate SSL at the
+ GitLab application server, use the TCP protocol.
+
+If you're using GitLab Pages with custom domain support you will need some
+additional port configurations. GitLab Pages requires a separate virtual IP
+address. Configure DNS to point the `pages_external_url` from
+`/etc/gitlab/gitlab.rb` to the new virtual IP address. For more information,
+see the [GitLab Pages documentation](../pages/index.md).
+
+| Port | Backend Port | Protocol |
+| ------- | ------------- | --------- |
+| 80 | Varies (*1*) | HTTP |
+| 443 | Varies (*1*) | TCP (*2*) |
+
+- (*1*): The backend port for GitLab Pages depends on the
+ `gitlab_pages['external_http']` and `gitlab_pages['external_https']`
+ settings. For details, see the [GitLab Pages documentation](../pages/index.md).
+- (*2*): Port 443 for GitLab Pages must use the TCP protocol. Users can
+ configure custom domains with custom SSL, which wouldn't be possible if SSL
+ was terminated at the load balancer.
+
+#### Alternate SSH Port
+
+Some organizations have policies against opening SSH port 22. In this case,
+it may be helpful to configure an alternate SSH hostname that instead allows
+users to use SSH over port 443. An alternate SSH hostname requires a new
+virtual IP address compared to the previously described GitLab HTTP
+configuration.
+
+Configure DNS for an alternate SSH hostname, such as `altssh.gitlab.example.com`:
+
+| LB Port | Backend Port | Protocol |
+| ------- | ------------ | -------- |
+| 443 | 22 | TCP |
+
+<div align="right">
+ <a type="button" class="btn btn-default" href="#setup-components">
+ Back to setup components <i class="fa fa-angle-double-up" aria-hidden="true"></i>
+ </a>
+</div>
+
+## Configure the object storage
+
+GitLab supports using an object storage service for holding several types of
+data, and is recommended over [NFS](#configure-nfs-optional). In general,
+object storage services are better for larger environments, as object storage
+is typically much more performant, reliable, and scalable.
+
+Object storage options that GitLab has either tested or is aware of customers
+using, includes:
+
+- SaaS/Cloud solutions (such as [Amazon S3](https://aws.amazon.com/s3/) or
+ [Google Cloud Storage](https://cloud.google.com/storage)).
+- On-premises hardware and appliances, from various storage vendors.
+- MinIO ([Deployment guide](https://docs.gitlab.com/charts/advanced/external-object-storage/minio.html)).
+
+To configure GitLab to use object storage, refer to the following guides based
+on the features you intend to use:
+
+1. [Object storage for backups](../../raketasks/backup_restore.md#uploading-backups-to-a-remote-cloud-storage).
+1. [Object storage for job artifacts](../job_artifacts.md#using-object-storage)
+ including [incremental logging](../job_logs.md#new-incremental-logging-architecture).
+1. [Object storage for LFS objects](../lfs/index.md#storing-lfs-objects-in-remote-object-storage).
+1. [Object storage for uploads](../uploads.md#using-object-storage-core-only).
+1. [Object storage for merge request diffs](../merge_request_diffs.md#using-object-storage).
+1. [Object storage for Container Registry](../packages/container_registry.md#container-registry-storage-driver) (optional feature).
+1. [Object storage for Mattermost](https://docs.mattermost.com/administration/config-settings.html#file-storage) (optional feature).
+1. [Object storage for packages](../packages/index.md#using-object-storage) (optional feature). **(PREMIUM ONLY)**
+1. [Object storage for Dependency Proxy](../packages/dependency_proxy.md#using-object-storage) (optional feature). **(PREMIUM ONLY)**
+1. [Object storage for Pseudonymizer](../pseudonymizer.md#configuration) (optional feature). **(ULTIMATE ONLY)**
+1. [Object storage for autoscale Runner caching](https://docs.gitlab.com/runner/configuration/autoscale.html#distributed-runners-caching) (optional, for improved performance).
+1. [Object storage for Terraform state files](../terraform_state.md#using-object-storage-core-only).
+
+Using separate buckets for each data type is the recommended approach for GitLab.
+
+A limitation of our configuration is that each use of object storage is
+separately configured. We have an [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/23345)
+for improving this, which would allow for one bucket with separate folders.
+
+Using a single bucket when GitLab is deployed with the Helm chart causes
+restoring from a backup to
+[not function properly](https://docs.gitlab.com/charts/advanced/external-object-storage/#lfs-artifacts-uploads-packages-external-diffs-pseudonymizer).
+Although you may not be using a Helm deployment right now, if you migrate
+GitLab to a Helm deployment later, GitLab would still work, but you may not
+realize backups aren't working correctly until a critical requirement for
+functioning backups is encountered.
+
+<div align="right">
+ <a type="button" class="btn btn-default" href="#setup-components">
+ Back to setup components <i class="fa fa-angle-double-up" aria-hidden="true"></i>
+ </a>
+</div>
+
+## Configure NFS (optional)
+
+For improved performance, [object storage](#configure-the-object-storage),
+along with [Gitaly](#configure-gitaly), are recommended over using NFS whenever
+possible. However, if you intend to use GitLab Pages,
+[you must use NFS](troubleshooting.md#gitlab-pages-requires-nfs).
+
+For information about configuring NFS, see the [NFS documentation page](../high_availability/nfs.md).
+
+<div align="right">
+ <a type="button" class="btn btn-default" href="#setup-components">
+ Back to setup components <i class="fa fa-angle-double-up" aria-hidden="true"></i>
+ </a>
+</div>
+
+## Configure PostgreSQL
+
+In this section, you'll be guided through configuring an external PostgreSQL database
+to be used with GitLab.
+
+### Provide your own PostgreSQL instance
+
+If you're hosting GitLab on a cloud provider, you can optionally use a
+managed service for PostgreSQL. For example, AWS offers a managed relational
+database service (RDS) that runs PostgreSQL.
+
+If you use a cloud-managed service, or provide your own PostgreSQL:
+
+1. Set up PostgreSQL according to the
+ [database requirements document](../../install/requirements.md#database).
+1. Create a `gitlab` username with a password of your choice. The `gitlab` user
+ needs privileges to create the `gitlabhq_production` database.
+1. Configure the GitLab application servers with the appropriate details.
+ This step is covered in [Configuring the GitLab Rails application](#configure-gitlab-rails).
+
+### Standalone PostgreSQL using Omnibus GitLab
+
+1. SSH into the PostgreSQL server.
+1. [Download/install](https://about.gitlab.com/install/) the Omnibus GitLab
+ package you want using **steps 1 and 2** from the GitLab downloads page.
+ - Do not complete any other steps on the download page.
+1. Generate a password hash for PostgreSQL. This assumes you will use the default
+ username of `gitlab` (recommended). The command will request a password
+ and confirmation. Use the value that is output by this command in the next
+ step as the value of `POSTGRESQL_PASSWORD_HASH`.
+
+ ```shell
+ sudo gitlab-ctl pg-password-md5 gitlab
+ ```
+
+1. Edit `/etc/gitlab/gitlab.rb` and add the contents below, updating placeholder
+ values appropriately.
+
+ - `POSTGRESQL_PASSWORD_HASH` - The value output from the previous step
+ - `APPLICATION_SERVER_IP_BLOCKS` - A space delimited list of IP subnets or IP
+ addresses of the GitLab application servers that will connect to the
+ database. Example: `%w(123.123.123.123/32 123.123.123.234/32)`
+
+ ```ruby
+ # Disable all components except PostgreSQL
+ roles ['postgres_role']
+ repmgr['enable'] = false
+ consul['enable'] = false
+ prometheus['enable'] = false
+ alertmanager['enable'] = false
+ pgbouncer_exporter['enable'] = false
+ redis_exporter['enable'] = false
+ gitlab_exporter['enable'] = false
+
+ # Set the network addresses that the exporters used for monitoring will listen on
+ node_exporter['listen_address'] = '0.0.0.0:9100'
+ postgres_exporter['listen_address'] = '0.0.0.0:9187'
+ postgres_exporter['dbname'] = 'gitlabhq_production'
+ postgres_exporter['password'] = 'POSTGRESQL_PASSWORD_HASH'
+
+ # Set the PostgreSQL address and port
+ postgresql['listen_address'] = '0.0.0.0'
+ postgresql['port'] = 5432
+
+ # Replace POSTGRESQL_PASSWORD_HASH with a generated md5 value
+ postgresql['sql_user_password'] = 'POSTGRESQL_PASSWORD_HASH'
+
+ # Replace APPLICATION_SERVER_IP_BLOCK with the CIDR address of the application node
+ postgresql['trust_auth_cidr_addresses'] = %w(127.0.0.1/32 APPLICATION_SERVER_IP_BLOCK)
+
+ # Disable automatic database migrations
+ gitlab_rails['auto_migrate'] = false
+ ```
+
+1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+1. Note the PostgreSQL node's IP address or hostname, port, and
+ plain text password. These will be necessary when configuring the [GitLab
+ application server](#configure-gitlab-rails) later.
+
+Advanced [configuration options](https://docs.gitlab.com/omnibus/settings/database.html)
+are supported and can be added if needed.
+
+<div align="right">
+ <a type="button" class="btn btn-default" href="#setup-components">
+ Back to setup components <i class="fa fa-angle-double-up" aria-hidden="true"></i>
+ </a>
+</div>
+
+## Configure Redis
+
+In this section, you'll be guided through configuring an external Redis instance
+to be used with GitLab.
+
+### Provide your own Redis instance
+
+Redis version 5.0 or higher is required, as this is what ships with
+Omnibus GitLab packages starting with GitLab 13.0. Older Redis versions
+do not support an optional count argument to SPOP which is now required for
+[Merge Trains](../../ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.md).
+
+In addition, GitLab makes use of certain commands like `UNLINK` and `USAGE` which
+were introduced only in Redis 4.
+
+Managed Redis from cloud providers such as AWS ElastiCache will work. If these
+services support high availability, be sure it is not the Redis Cluster type.
+
+Note the Redis node's IP address or hostname, port, and password (if required).
+These will be necessary when configuring the
+[GitLab application servers](#configure-gitlab-rails) later.
+
+### Standalone Redis using Omnibus GitLab
+
+The Omnibus GitLab package can be used to configure a standalone Redis server.
+The steps below are the minimum necessary to configure a Redis server with
+Omnibus:
+
+1. SSH into the Redis server.
+1. [Download/install](https://about.gitlab.com/install/) the Omnibus GitLab
+ package you want using **steps 1 and 2** from the GitLab downloads page.
+ - Do not complete any other steps on the download page.
+
+1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
+
+ ```ruby
+ ## Enable Redis
+ redis['enable'] = true
+
+ ## Disable all other services
+ sidekiq['enable'] = false
+ gitlab_workhorse['enable'] = false
+ puma['enable'] = false
+ unicorn['enable'] = false
+ postgresql['enable'] = false
+ nginx['enable'] = false
+ prometheus['enable'] = false
+ alertmanager['enable'] = false
+ pgbouncer_exporter['enable'] = false
+ gitlab_exporter['enable'] = false
+ gitaly['enable'] = false
+ grafana['enable'] = false
+
+ redis['bind'] = '0.0.0.0'
+ redis['port'] = 6379
+ redis['password'] = 'SECRET_PASSWORD_HERE'
+
+ gitlab_rails['enable'] = false
+
+ # Set the network addresses that the exporters used for monitoring will listen on
+ node_exporter['listen_address'] = '0.0.0.0:9100'
+ redis_exporter['listen_address'] = '0.0.0.0:9121'
+ redis_exporter['flags'] = {
+ 'redis.addr' => 'redis://0.0.0.0:6379',
+ 'redis.password' => 'SECRET_PASSWORD_HERE',
+ }
+ ```
+
+1. [Reconfigure Omnibus GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+1. Note the Redis node's IP address or hostname, port, and
+ Redis password. These will be necessary when [configuring the GitLab
+ application servers](#configure-gitlab-rails) later.
+
+Advanced [configuration options](https://docs.gitlab.com/omnibus/settings/redis.html)
+are supported and can be added if needed.
+
+<div align="right">
+ <a type="button" class="btn btn-default" href="#setup-components">
+ Back to setup components <i class="fa fa-angle-double-up" aria-hidden="true"></i>
+ </a>
+</div>
+
+## Configure Gitaly
+
+Deploying Gitaly in its own server can benefit GitLab installations that are
+larger than a single machine. Gitaly node requirements are dependent on data,
+specifically the number of projects and their sizes. It's recommended that each
+Gitaly node store no more than 5TB of data. Your 2K setup may require one or more
+nodes depending on your repository storage requirements.
+
+We strongly recommend that all Gitaly nodes should be set up with SSD disks with a throughput of at least
+8,000 IOPS for read operations and 2,000 IOPS for write, as Gitaly has heavy I/O.
+These IOPS values are recommended only as a starter as with time they may be
+adjusted higher or lower depending on the scale of your environment's workload.
+If you're running the environment on a Cloud provider
+you may need to refer to their documentation on how configure IOPS correctly.
+
+Some things to note:
+
+- The GitLab Rails application shards repositories into [repository storages](../repository_storage_paths.md).
+- A Gitaly server can host one or more storages.
+- A GitLab server can use one or more Gitaly servers.
+- Gitaly addresses must be specified in such a way that they resolve
+ correctly for ALL Gitaly clients.
+- Gitaly servers must not be exposed to the public internet, as Gitaly's network
+ traffic is unencrypted by default. The use of a firewall is highly recommended
+ to restrict access to the Gitaly server. Another option is to
+ [use TLS](#gitaly-tls-support).
+
+TIP: **Tip:**
+For more information about Gitaly's history and network architecture see the
+[standalone Gitaly documentation](../gitaly/index.md).
+
+Note: **Note:** The token referred to throughout the Gitaly documentation is
+just an arbitrary password selected by the administrator. It is unrelated to
+tokens created for the GitLab API or other similar web API tokens.
+
+Below we describe how to configure one Gitaly server `gitaly1.internal` with
+secret token `gitalysecret`. We assume your GitLab installation has two
+repository storages: `default` and `storage1`.
+
+To configure the Gitaly server:
+
+1. [Download/Install](https://about.gitlab.com/install/) the Omnibus GitLab
+ package you want using **steps 1 and 2** from the GitLab downloads page but
+ **without** providing the `EXTERNAL_URL` value.
+1. Edit `/etc/gitlab/gitlab.rb` to configure storage paths, enable
+ the network listener and configure the token:
+
+ <!--
+ updates to following example must also be made at
+ https://gitlab.com/gitlab-org/charts/gitlab/blob/master/doc/advanced/external-gitaly/external-omnibus-gitaly.md#configure-omnibus-gitlab
+ -->
+
+ ```ruby
+ # /etc/gitlab/gitlab.rb
+
+ # Gitaly and GitLab use two shared secrets for authentication, one to authenticate gRPC requests
+ # to Gitaly, and a second for authentication callbacks from GitLab-Shell to the GitLab internal API.
+ # The following two values must be the same as their respective values
+ # of the GitLab Rails application setup
+ gitaly['auth_token'] = 'gitlaysecret'
+ gitlab_shell['secret_token'] = 'shellsecret'
+
+ # Avoid running unnecessary services on the Gitaly server
+ postgresql['enable'] = false
+ redis['enable'] = false
+ nginx['enable'] = false
+ puma['enable'] = false
+ unicorn['enable'] = false
+ sidekiq['enable'] = false
+ gitlab_workhorse['enable'] = false
+ grafana['enable'] = false
+
+ # If you run a seperate monitoring node you can disable these services
+ alertmanager['enable'] = false
+ prometheus['enable'] = false
+
+ # Prevent database connections during 'gitlab-ctl reconfigure'
+ gitlab_rails['rake_cache_clear'] = false
+ gitlab_rails['auto_migrate'] = false
+
+ # Configure the gitlab-shell API callback URL. Without this, `git push` will
+ # fail. This can be your 'front door' GitLab URL or an internal load
+ # balancer.
+ # Don't forget to copy `/etc/gitlab/gitlab-secrets.json` from web server to Gitaly server.
+ gitlab_rails['internal_api_url'] = 'https://gitlab.example.com'
+
+ # Make Gitaly accept connections on all network interfaces. You must use
+ # firewalls to restrict access to this address/port.
+ # Comment out following line if you only want to support TLS connections
+ gitaly['listen_addr'] = "0.0.0.0:8075"
+ gitaly['prometheus_listen_addr'] = "0.0.0.0:9236"
+
+ # Set the network addresses that the exporters used for monitoring will listen on
+ node_exporter['listen_address'] = '0.0.0.0:9100'
+ ```
+
+1. Append the following to `/etc/gitlab/gitlab.rb` on `gitaly1.internal`:
+
+ ```ruby
+ git_data_dirs({
+ 'default' => {
+ 'path' => '/var/opt/gitlab/git-data'
+ },
+ 'storage1' => {
+ 'path' => '/mnt/gitlab/git-data'
+ },
+ })
+ ```
+
+ <!--
+ updates to following example must also be made at
+ https://gitlab.com/gitlab-org/charts/gitlab/blob/master/doc/advanced/external-gitaly/external-omnibus-gitaly.md#configure-omnibus-gitlab
+ -->
+
+1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+1. Confirm that Gitaly can perform callbacks to the internal API:
+
+ ```shell
+ sudo /opt/gitlab/embedded/service/gitlab-shell/bin/check -config /opt/gitlab/embedded/service/gitlab-shell/config.yml
+ ```
+
+### Gitaly TLS support
+
+Gitaly supports TLS encryption. To be able to communicate
+with a Gitaly instance that listens for secure connections you will need to use `tls://` URL
+scheme in the `gitaly_address` of the corresponding storage entry in the GitLab configuration.
+
+You will need to bring your own certificates as this isn't provided automatically.
+The certificate, or its certificate authority, must be installed on all Gitaly
+nodes (including the Gitaly node using the certificate) and on all client nodes
+that communicate with it following the procedure described in
+[GitLab custom certificate configuration](https://docs.gitlab.com/omnibus/settings/ssl.html#install-custom-public-certificates).
+
+NOTE: **Note**
+The self-signed certificate must specify the address you use to access the
+Gitaly server. If you are addressing the Gitaly server by a hostname, you can
+either use the Common Name field for this, or add it as a Subject Alternative
+Name. If you are addressing the Gitaly server by its IP address, you must add it
+as a Subject Alternative Name to the certificate.
+[gRPC does not support using an IP address as Common Name in a certificate](https://github.com/grpc/grpc/issues/2691).
+
+NOTE: **Note:**
+It is possible to configure Gitaly servers with both an
+unencrypted listening address `listen_addr` and an encrypted listening
+address `tls_listen_addr` at the same time. This allows you to do a
+gradual transition from unencrypted to encrypted traffic, if necessary.
+
+To configure Gitaly with TLS:
+
+1. Create the `/etc/gitlab/ssl` directory and copy your key and certificate there:
+
+ ```shell
+ sudo mkdir -p /etc/gitlab/ssl
+ sudo chmod 755 /etc/gitlab/ssl
+ sudo cp key.pem cert.pem /etc/gitlab/ssl/
+ sudo chmod 644 key.pem cert.pem
+ ```
+
+1. Copy the cert to `/etc/gitlab/trusted-certs` so Gitaly will trust the cert when
+ calling into itself:
+
+ ```shell
+ sudo cp /etc/gitlab/ssl/cert.pem /etc/gitlab/trusted-certs/
+ ```
+
+1. Edit `/etc/gitlab/gitlab.rb` and add:
+
+ <!--
+ updates to following example must also be made at
+ https://gitlab.com/gitlab-org/charts/gitlab/blob/master/doc/advanced/external-gitaly/external-omnibus-gitaly.md#configure-omnibus-gitlab
+ -->
+
+ ```ruby
+ gitaly['tls_listen_addr'] = "0.0.0.0:9999"
+ gitaly['certificate_path'] = "/etc/gitlab/ssl/cert.pem"
+ gitaly['key_path'] = "/etc/gitlab/ssl/key.pem"
+ ```
+
+1. Delete `gitaly['listen_addr']` to allow only encrypted connections.
+1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+
+<div align="right">
+ <a type="button" class="btn btn-default" href="#setup-components">
+ Back to setup components <i class="fa fa-angle-double-up" aria-hidden="true"></i>
+ </a>
+</div>
+
+## Configure GitLab Rails
+
+NOTE: **Note:**
+In our architectures we run each GitLab Rails node using the Puma webserver
+and have its number of workers set to 90% of available CPUs along with four threads. For
+nodes that are running Rails with other components the worker value should be reduced
+accordingly where we've found 50% achieves a good balance but this is dependent
+on workload.
+
+This section describes how to configure the GitLab application (Rails) component.
+On each node perform the following:
+
+1. If you're [using NFS](#configure-nfs-optional):
+
+ 1. If necessary, install the NFS client utility packages using the following
+ commands:
+
+ ```shell
+ # Ubuntu/Debian
+ apt-get install nfs-common
+
+ # CentOS/Red Hat
+ yum install nfs-utils nfs-utils-lib
+ ```
+
+ 1. Specify the necessary NFS mounts in `/etc/fstab`.
+ The exact contents of `/etc/fstab` will depend on how you chose
+ to configure your NFS server. See the [NFS documentation](../high_availability/nfs.md)
+ for examples and the various options.
+
+ 1. Create the shared directories. These may be different depending on your NFS
+ mount locations.
+
+ ```shell
+ mkdir -p /var/opt/gitlab/.ssh /var/opt/gitlab/gitlab-rails/uploads /var/opt/gitlab/gitlab-rails/shared /var/opt/gitlab/gitlab-ci/builds /var/opt/gitlab/git-data
+ ```
+
+1. Download/install Omnibus GitLab using **steps 1 and 2** from
+ [GitLab downloads](https://about.gitlab.com/install/). Do not complete other
+ steps on the download page.
+1. Create/edit `/etc/gitlab/gitlab.rb` and use the following configuration.
+ To maintain uniformity of links across nodes, the `external_url`
+ on the application server should point to the external URL that users will use
+ to access GitLab. This would be the URL of the [load balancer](#configure-the-load-balancer)
+ which will route traffic to the GitLab application server:
+
+ ```ruby
+ external_url 'https://gitlab.example.com'
+
+ # Gitaly and GitLab use two shared secrets for authentication, one to authenticate gRPC requests
+ # to Gitaly, and a second for authentication callbacks from GitLab-Shell to the GitLab internal API.
+ # The following two values must be the same as their respective values
+ # of the Gitaly setup
+ gitlab_rails['gitaly_token'] = 'gitalyecret'
+ gitlab_shell['secret_token'] = 'shellsecret'
+
+ git_data_dirs({
+ 'default' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
+ 'storage1' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
+ 'storage2' => { 'gitaly_address' => 'tcp://gitaly2.internal:8075' },
+ })
+
+ ## Disable components that will not be on the GitLab application server
+ roles ['application_role']
+ gitaly['enable'] = false
+ nginx['enable'] = true
+
+ ## PostgreSQL connection details
+ gitlab_rails['db_adapter'] = 'postgresql'
+ gitlab_rails['db_encoding'] = 'unicode'
+ gitlab_rails['db_host'] = '10.1.0.5' # IP/hostname of database server
+ gitlab_rails['db_password'] = 'DB password'
+
+ ## Redis connection details
+ gitlab_rails['redis_port'] = '6379'
+ gitlab_rails['redis_host'] = '10.1.0.6' # IP/hostname of Redis server
+ gitlab_rails['redis_password'] = 'Redis Password'
+
+ # Set the network addresses that the exporters used for monitoring will listen on
+ node_exporter['listen_address'] = '0.0.0.0:9100'
+ gitlab_workhorse['prometheus_listen_addr'] = '0.0.0.0:9229'
+ sidekiq['listen_address'] = "0.0.0.0"
+ puma['listen'] = '0.0.0.0'
+
+ # Add the monitoring node's IP address to the monitoring whitelist and allow it to
+ # scrape the NGINX metrics. Replace placeholder `monitoring.gitlab.example.com` with
+ # the address and/or subnets gathered from the monitoring node
+ gitlab_rails['monitoring_whitelist'] = ['<MONITOR NODE IP>/32', '127.0.0.0/8']
+ nginx['status']['options']['allow'] = ['<MONITOR NODE IP>/32', '127.0.0.0/8']
+
+ ## Uncomment and edit the following options if you have set up NFS
+ ##
+ ## Prevent GitLab from starting if NFS data mounts are not available
+ ##
+ #high_availability['mountpoint'] = '/var/opt/gitlab/git-data'
+ ##
+ ## Ensure UIDs and GIDs match between servers for permissions via NFS
+ ##
+ #user['uid'] = 9000
+ #user['gid'] = 9000
+ #web_server['uid'] = 9001
+ #web_server['gid'] = 9001
+ #registry['uid'] = 9002
+ #registry['gid'] = 9002
+ ```
+
+1. If you're using [Gitaly with TLS support](#gitaly-tls-support), make sure the
+ `git_data_dirs` entry is configured with `tls` instead of `tcp`:
+
+ ```ruby
+ git_data_dirs({
+ 'default' => { 'gitaly_address' => 'tls://gitaly1.internal:9999' },
+ 'storage1' => { 'gitaly_address' => 'tls://gitaly1.internal:9999' },
+ 'storage2' => { 'gitaly_address' => 'tls://gitaly2.internal:9999' },
+ })
+ ```
+
+ 1. Copy the cert into `/etc/gitlab/trusted-certs`:
+
+ ```shell
+ sudo cp cert.pem /etc/gitlab/trusted-certs/
+ ```
+
+1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+1. Run `sudo gitlab-rake gitlab:gitaly:check` to confirm the node can connect to Gitaly.
+1. Tail the logs to see the requests:
+
+ ```shell
+ sudo gitlab-ctl tail gitaly
+ ```
+
+NOTE: **Note:** When you specify `https` in the `external_url`, as in the example
+above, GitLab assumes you have SSL certificates in `/etc/gitlab/ssl/`. If
+certificates are not present, NGINX will fail to start. See the
+[NGINX documentation](https://docs.gitlab.com/omnibus/settings/nginx.html#enable-https)
+for more information.
+
+<div align="right">
+ <a type="button" class="btn btn-default" href="#setup-components">
+ Back to setup components <i class="fa fa-angle-double-up" aria-hidden="true"></i>
+ </a>
+</div>
+
+## Configure Prometheus
+
+The Omnibus GitLab package can be used to configure a standalone Monitoring node
+running [Prometheus](../monitoring/prometheus/index.md) and
+[Grafana](../monitoring/performance/grafana_configuration.md):
+
+1. SSH into the Monitoring node.
+1. [Download/install](https://about.gitlab.com/install/) the Omnibus GitLab
+ package you want using **steps 1 and 2** from the GitLab downloads page.
+ Do not complete any other steps on the download page.
+1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
+
+ ```ruby
+ external_url 'http://gitlab.example.com'
+
+ # Enable Prometheus
+ prometheus['enable'] = true
+ prometheus['listen_address'] = '0.0.0.0:9090'
+ prometheus['monitor_kubernetes'] = false
+
+ # Enable Login form
+ grafana['disable_login_form'] = false
+
+ # Enable Grafana
+ grafana['enable'] = true
+ grafana['admin_password'] = 'toomanysecrets'
+
+ # Disable all other services
+ gitlab_rails['auto_migrate'] = false
+ alertmanager['enable'] = false
+ gitaly['enable'] = false
+ gitlab_exporter['enable'] = false
+ gitlab_workhorse['enable'] = false
+ nginx['enable'] = true
+ postgres_exporter['enable'] = false
+ postgresql['enable'] = false
+ redis['enable'] = false
+ redis_exporter['enable'] = false
+ sidekiq['enable'] = false
+ puma['enable'] = false
+ unicorn['enable'] = false
+ node_exporter['enable'] = false
+ gitlab_exporter['enable'] = false
+ ```
+
+1. Prometheus also needs some scrape configs to pull all the data from the various
+ nodes where we configured exporters. Assuming that your nodes' IPs are:
+
+ ```plaintext
+ 1.1.1.1: postgres
+ 1.1.1.2: redis
+ 1.1.1.3: gitaly1
+ 1.1.1.4: rails1
+ 1.1.1.5: rails2
+ ```
+
+ Add the following to `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ prometheus['scrape_configs'] = [
+ {
+ 'job_name': 'postgres',
+ 'static_configs' => [
+ 'targets' => ['1.1.1.1:9187'],
+ ],
+ },
+ {
+ 'job_name': 'redis',
+ 'static_configs' => [
+ 'targets' => ['1.1.1.2:9121'],
+ ],
+ },
+ {
+ 'job_name': 'gitaly',
+ 'static_configs' => [
+ 'targets' => ['1.1.1.3:9236'],
+ ],
+ },
+ {
+ 'job_name': 'gitlab-nginx',
+ 'static_configs' => [
+ 'targets' => ['1.1.1.4:8060', '1.1.1.5:8060'],
+ ],
+ },
+ {
+ 'job_name': 'gitlab-workhorse',
+ 'static_configs' => [
+ 'targets' => ['1.1.1.4:9229', '1.1.1.5:9229'],
+ ],
+ },
+ {
+ 'job_name': 'gitlab-rails',
+ 'metrics_path': '/-/metrics',
+ 'static_configs' => [
+ 'targets' => ['1.1.1.4:8080', '1.1.1.5:8080'],
+ ],
+ },
+ {
+ 'job_name': 'gitlab-sidekiq',
+ 'static_configs' => [
+ 'targets' => ['1.1.1.4:8082', '1.1.1.5:8082'],
+ ],
+ },
+ {
+ 'job_name': 'node',
+ 'static_configs' => [
+ 'targets' => ['1.1.1.1:9100', '1.1.1.2:9100', '1.1.1.3:9100', '1.1.1.4:9100', '1.1.1.5:9100'],
+ ],
+ },
+ ]
+ ```
+
+1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+1. In the GitLab UI, set `admin/application_settings/metrics_and_profiling` > Metrics - Grafana to `/-/grafana` to
+`http[s]://<MONITOR NODE>/-/grafana`
+
+<div align="right">
+ <a type="button" class="btn btn-default" href="#setup-components">
+ Back to setup components <i class="fa fa-angle-double-up" aria-hidden="true"></i>
+ </a>
+</div>
+
+## Troubleshooting
+
+See the [troubleshooting documentation](troubleshooting.md).
+
+<div align="right">
+ <a type="button" class="btn btn-default" href="#setup-components">
+ Back to setup components <i class="fa fa-angle-double-up" aria-hidden="true"></i>
+ </a>
+</div>
diff --git a/doc/administration/reference_architectures/3k_users.md b/doc/administration/reference_architectures/3k_users.md
index bd429fbc4b4..efeed3e9ffd 100644
--- a/doc/administration/reference_architectures/3k_users.md
+++ b/doc/administration/reference_architectures/3k_users.md
@@ -14,20 +14,20 @@ following the [2,000-user reference architecture](2k_users.md).
> - **High Availability:** True
> - **Test RPS rates:** API: 60 RPS, Web: 6 RPS, Git: 6 RPS
-| Service | Nodes | Configuration ([8](#footnotes)) | GCP | AWS ([9](#footnotes)) | Azure([9](#footnotes)) |
-|--------------------------------------------------------------|-------|---------------------------------|---------------|-----------------------|------------------------|
-| GitLab Rails ([1](#footnotes)) | 3 | 8 vCPU, 7.2GB Memory | n1-highcpu-8 | c5.2xlarge | F8s v2 |
-| PostgreSQL | 3 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large | D2s v3 |
-| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
-| Gitaly ([2](#footnotes)) ([5](#footnotes)) ([7](#footnotes)) | X | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | D4s v3 |
-| Redis ([3](#footnotes)) | 3 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large | D2s v3 |
-| Consul + Sentinel ([3](#footnotes)) | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
-| Sidekiq | 4 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large | D2s v3 |
+| Service | Nodes | Configuration ([8](#footnotes)) | GCP | AWS | Azure |
+|--------------------------------------------------------------|-------|---------------------------------|---------------|-----------------------|----------------|
+| GitLab Rails ([1](#footnotes)) | 3 | 8 vCPU, 7.2GB Memory | `n1-highcpu-8` | `c5.2xlarge` | F8s v2 |
+| PostgreSQL | 3 | 2 vCPU, 7.5GB Memory | `n1-standard-2` | `m5.large` | D2s v3 |
+| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | `n1-highcpu-2` | `c5.large` | F2s v2 |
+| Gitaly ([2](#footnotes)) ([5](#footnotes)) ([7](#footnotes)) | X | 4 vCPU, 15GB Memory | `n1-standard-4` | `m5.xlarge` | D4s v3 |
+| Redis ([3](#footnotes)) | 3 | 2 vCPU, 7.5GB Memory | `n1-standard-2` | `m5.large` | D2s v3 |
+| Consul + Sentinel ([3](#footnotes)) | 3 | 2 vCPU, 1.8GB Memory | `n1-highcpu-2` | `c5.large` | F2s v2 |
+| Sidekiq | 4 | 2 vCPU, 7.5GB Memory | `n1-standard-2` | `m5.large` | D2s v3 |
| Object Storage ([4](#footnotes)) | - | - | - | - | - |
-| NFS Server ([5](#footnotes)) ([7](#footnotes)) | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | F4s v2 |
-| Monitoring node | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
-| External load balancing node ([6](#footnotes)) | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
-| Internal load balancing node ([6](#footnotes)) | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
+| NFS Server ([5](#footnotes)) ([7](#footnotes)) | 1 | 4 vCPU, 3.6GB Memory | `n1-highcpu-4` | `c5.xlarge` | F4s v2 |
+| Monitoring node | 1 | 2 vCPU, 1.8GB Memory | `n1-highcpu-2` | `c5.large` | F2s v2 |
+| External load balancing node ([6](#footnotes)) | 1 | 2 vCPU, 1.8GB Memory | `n1-highcpu-2` | `c5.large` | F2s v2 |
+| Internal load balancing node ([6](#footnotes)) | 1 | 2 vCPU, 1.8GB Memory | `n1-highcpu-2` | `c5.large` | F2s v2 |
## Footnotes
@@ -59,7 +59,7 @@ following the [2,000-user reference architecture](2k_users.md).
1. NFS can be used as an alternative for both repository data (replacing Gitaly) and
object storage but this isn't typically recommended for performance reasons. Note however it is required for
- [GitLab Pages](https://gitlab.com/gitlab-org/gitlab-pages/issues/196).
+ [GitLab Pages](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/196).
1. Our architectures have been tested and validated with [HAProxy](https://www.haproxy.org/)
as the load balancer. Although other load balancers with similar feature sets
@@ -77,6 +77,3 @@ following the [2,000-user reference architecture](2k_users.md).
or higher, are required for your CPU or Node counts accordingly. For more information, a
[Sysbench](https://github.com/akopytov/sysbench) benchmark of the CPU can be found
[here](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Reference-Architectures/GCP-CPU-Benchmarks).
-
-1. AWS-equivalent and Azure-equivalent configurations are rough suggestions
- and may change in the future. They have not yet been tested and validated.
diff --git a/doc/administration/reference_architectures/50k_users.md b/doc/administration/reference_architectures/50k_users.md
index 67f773a021f..dd94f5470b4 100644
--- a/doc/administration/reference_architectures/50k_users.md
+++ b/doc/administration/reference_architectures/50k_users.md
@@ -8,23 +8,23 @@ For a full list of reference architectures, see
> - **High Availability:** True
> - **Test RPS rates:** API: 1000 RPS, Web: 100 RPS, Git: 100 RPS
-| Service | Nodes | Configuration ([8](#footnotes)) | GCP | AWS ([9](#footnotes)) | Azure([9](#footnotes)) |
-|--------------------------------------------------------------|-------|---------------------------------|----------------|-----------------------|------------------------|
-| GitLab Rails ([1](#footnotes)) | 12 | 32 vCPU, 28.8GB Memory | n1-highcpu-32 | c5.9xlarge | F32s v2 |
-| PostgreSQL | 3 | 16 vCPU, 60GB Memory | n1-standard-16 | m5.4xlarge | D16s v3 |
-| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
-| Gitaly ([2](#footnotes)) ([5](#footnotes)) ([7](#footnotes)) | X | 64 vCPU, 240GB Memory | n1-standard-64 | m5.16xlarge | D64s v3 |
-| Redis ([3](#footnotes)) - Cache | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | D4s v3 |
-| Redis ([3](#footnotes)) - Queues / Shared State | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | D4s v3 |
-| Redis Sentinel ([3](#footnotes)) - Cache | 3 | 1 vCPU, 1.7GB Memory | g1-small | t2.small | B1MS |
-| Redis Sentinel ([3](#footnotes)) - Queues / Shared State | 3 | 1 vCPU, 1.7GB Memory | g1-small | t2.small | B1MS |
-| Consul | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
-| Sidekiq | 4 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | D4s v3 |
-| NFS Server ([5](#footnotes)) ([7](#footnotes)) | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | F4s v2 |
+| Service | Nodes | Configuration ([8](#footnotes)) | GCP | AWS | Azure |
+|--------------------------------------------------------------|-------|---------------------------------|----------------|-----------------------|----------------|
+| GitLab Rails ([1](#footnotes)) | 12 | 32 vCPU, 28.8GB Memory | `n1-highcpu-32` | `c5.9xlarge` | F32s v2 |
+| PostgreSQL | 3 | 16 vCPU, 60GB Memory | `n1-standard-16` | `m5.4xlarge` | D16s v3 |
+| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | `n1-highcpu-2` | `c5.large` | F2s v2 |
+| Gitaly ([2](#footnotes)) ([5](#footnotes)) ([7](#footnotes)) | X | 64 vCPU, 240GB Memory | `n1-standard-64` | `m5.16xlarge` | D64s v3 |
+| Redis ([3](#footnotes)) - Cache | 3 | 4 vCPU, 15GB Memory | `n1-standard-4` | `m5.xlarge` | D4s v3 |
+| Redis ([3](#footnotes)) - Queues / Shared State | 3 | 4 vCPU, 15GB Memory | `n1-standard-4` | `m5.xlarge` | D4s v3 |
+| Redis Sentinel ([3](#footnotes)) - Cache | 3 | 1 vCPU, 1.7GB Memory | `g1-small` | `t2.small` | B1MS |
+| Redis Sentinel ([3](#footnotes)) - Queues / Shared State | 3 | 1 vCPU, 1.7GB Memory | `g1-small` | `t2.small` | B1MS |
+| Consul | 3 | 2 vCPU, 1.8GB Memory | `n1-highcpu-2` | `c5.large` | F2s v2 |
+| Sidekiq | 4 | 4 vCPU, 15GB Memory | `n1-standard-4` | `m5.xlarge` | D4s v3 |
+| NFS Server ([5](#footnotes)) ([7](#footnotes)) | 1 | 4 vCPU, 3.6GB Memory | `n1-highcpu-4` | `c5.xlarge` | F4s v2 |
| Object Storage ([4](#footnotes)) | - | - | - | - | - |
-| Monitoring node | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | F4s v2 |
-| External load balancing node ([6](#footnotes)) | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
-| Internal load balancing node ([6](#footnotes)) | 1 | 8 vCPU, 7.2GB Memory | n1-highcpu-8 | c5.2xlarge | F8s v2 |
+| Monitoring node | 1 | 4 vCPU, 3.6GB Memory | `n1-highcpu-4` | `c5.xlarge` | F4s v2 |
+| External load balancing node ([6](#footnotes)) | 1 | 8 vCPU, 7.2GB Memory | `n1-highcpu-8` | `c5.2xlarge` | F8s v2 |
+| Internal load balancing node ([6](#footnotes)) | 1 | 8 vCPU, 7.2GB Memory | `n1-highcpu-8` | `c5.2xlarge` | F8s v2 |
## Footnotes
@@ -56,7 +56,7 @@ For a full list of reference architectures, see
1. NFS can be used as an alternative for both repository data (replacing Gitaly) and
object storage but this isn't typically recommended for performance reasons. Note however it is required for
- [GitLab Pages](https://gitlab.com/gitlab-org/gitlab-pages/issues/196).
+ [GitLab Pages](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/196).
1. Our architectures have been tested and validated with [HAProxy](https://www.haproxy.org/)
as the load balancer. Although other load balancers with similar feature sets
@@ -74,6 +74,3 @@ For a full list of reference architectures, see
or higher, are required for your CPU or Node counts accordingly. For more information, a
[Sysbench](https://github.com/akopytov/sysbench) benchmark of the CPU can be found
[here](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Reference-Architectures/GCP-CPU-Benchmarks).
-
-1. AWS-equivalent and Azure-equivalent configurations are rough suggestions
- and may change in the future. They have not yet been tested and validated.
diff --git a/doc/administration/reference_architectures/5k_users.md b/doc/administration/reference_architectures/5k_users.md
index 41ef6f369c2..604572b083e 100644
--- a/doc/administration/reference_architectures/5k_users.md
+++ b/doc/administration/reference_architectures/5k_users.md
@@ -8,20 +8,20 @@ For a full list of reference architectures, see
> - **High Availability:** True
> - **Test RPS rates:** API: 100 RPS, Web: 10 RPS, Git: 10 RPS
-| Service | Nodes | Configuration ([8](#footnotes)) | GCP | AWS ([9](#footnotes)) | Azure([9](#footnotes)) |
-|--------------------------------------------------------------|-------|---------------------------------|---------------|-----------------------|------------------------|
-| GitLab Rails ([1](#footnotes)) | 3 | 16 vCPU, 14.4GB Memory | n1-highcpu-16 | c5.4xlarge | F16s v2 |
-| PostgreSQL | 3 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large | D2s v3 |
-| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
-| Gitaly ([2](#footnotes)) ([5](#footnotes)) ([7](#footnotes)) | X | 8 vCPU, 30GB Memory | n1-standard-8 | m5.2xlarge | D8s v3 |
-| Redis ([3](#footnotes)) | 3 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large | D2s v3 |
-| Consul + Sentinel ([3](#footnotes)) | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
-| Sidekiq | 4 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large | D2s v3 |
+| Service | Nodes | Configuration ([8](#footnotes)) | GCP | AWS | Azure |
+|--------------------------------------------------------------|-------|---------------------------------|---------------|-----------------------|----------------|
+| GitLab Rails ([1](#footnotes)) | 3 | 16 vCPU, 14.4GB Memory | `n1-highcpu-16` | `c5.4xlarge` | F16s v2 |
+| PostgreSQL | 3 | 2 vCPU, 7.5GB Memory | `n1-standard-2` | `m5.large` | D2s v3 |
+| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | `n1-highcpu-2` | `c5.large` | F2s v2 |
+| Gitaly ([2](#footnotes)) ([5](#footnotes)) ([7](#footnotes)) | X | 8 vCPU, 30GB Memory | `n1-standard-8` | `m5.2xlarge` | D8s v3 |
+| Redis ([3](#footnotes)) | 3 | 2 vCPU, 7.5GB Memory | `n1-standard-2` | `m5.large` | D2s v3 |
+| Consul + Sentinel ([3](#footnotes)) | 3 | 2 vCPU, 1.8GB Memory | `n1-highcpu-2` | `c5.large` | F2s v2 |
+| Sidekiq | 4 | 2 vCPU, 7.5GB Memory | `n1-standard-2` | `m5.large` | D2s v3 |
| Object Storage ([4](#footnotes)) | - | - | - | - | - |
-| NFS Server ([5](#footnotes)) ([7](#footnotes)) | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | F4s v2 |
-| Monitoring node | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
-| External load balancing node ([6](#footnotes)) | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
-| Internal load balancing node ([6](#footnotes)) | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
+| NFS Server ([5](#footnotes)) ([7](#footnotes)) | 1 | 4 vCPU, 3.6GB Memory | `n1-highcpu-4` | `c5.xlarge` | F4s v2 |
+| Monitoring node | 1 | 2 vCPU, 1.8GB Memory | `n1-highcpu-2` | `c5.large` | F2s v2 |
+| External load balancing node ([6](#footnotes)) | 1 | 2 vCPU, 1.8GB Memory | `n1-highcpu-2` | `c5.large` | F2s v2 |
+| Internal load balancing node ([6](#footnotes)) | 1 | 2 vCPU, 1.8GB Memory | `n1-highcpu-2` | `c5.large` | F2s v2 |
## Footnotes
@@ -53,7 +53,7 @@ For a full list of reference architectures, see
1. NFS can be used as an alternative for both repository data (replacing Gitaly) and
object storage but this isn't typically recommended for performance reasons. Note however it is required for
- [GitLab Pages](https://gitlab.com/gitlab-org/gitlab-pages/issues/196).
+ [GitLab Pages](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/196).
1. Our architectures have been tested and validated with [HAProxy](https://www.haproxy.org/)
as the load balancer. Although other load balancers with similar feature sets
@@ -71,6 +71,3 @@ For a full list of reference architectures, see
or higher, are required for your CPU or Node counts accordingly. For more information, a
[Sysbench](https://github.com/akopytov/sysbench) benchmark of the CPU can be found
[here](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Reference-Architectures/GCP-CPU-Benchmarks).
-
-1. AWS-equivalent and Azure-equivalent configurations are rough suggestions
- and may change in the future. They have not yet been tested and validated.
diff --git a/doc/administration/reference_architectures/index.md b/doc/administration/reference_architectures/index.md
index 26244368234..623d7f3f776 100644
--- a/doc/administration/reference_architectures/index.md
+++ b/doc/administration/reference_architectures/index.md
@@ -126,8 +126,8 @@ As long as at least one of each component is online and capable of handling the
By adding automatic failover for database systems, you can enable higher uptime
with additional database nodes. This extends the default database with
cluster management and failover policies.
-[PgBouncer](../../development/architecture.md#pgbouncer) in conjunction with
-[Repmgr](../high_availability/database.md) is recommended.
+[PgBouncer in conjunction with Repmgr](../postgresql/replication_and_failover.md)
+is recommended.
### Instance level replication with GitLab Geo **(PREMIUM ONLY)**
@@ -141,6 +141,9 @@ that can also be promoted in case of disaster.
## Configure GitLab to scale
+NOTE: **Note:**
+From GitLab 13.0, using NFS for Git repositories is deprecated. In GitLab 14.0, support for NFS for Git repositories is scheduled to be removed. Upgrade to [Gitaly Cluster](../gitaly/praefect.md) as soon as possible.
+
The following components are the ones you need to configure in order to scale
GitLab. They are listed in the order you'll typically configure them if they are
required by your [reference architecture](#reference-architectures) of choice.
@@ -160,14 +163,33 @@ column.
| [Consul](../../development/architecture.md#consul) ([3](#footnotes)) | Service discovery and health checks/failover | [Consul configuration](../high_availability/consul.md) **(PREMIUM ONLY)** | Yes |
| [PostgreSQL](../../development/architecture.md#postgresql) | Database | [PostgreSQL configuration](https://docs.gitlab.com/omnibus/settings/database.html) | Yes |
| [PgBouncer](../../development/architecture.md#pgbouncer) | Database connection pooler | [PgBouncer configuration](../high_availability/pgbouncer.md#running-pgbouncer-as-part-of-a-non-ha-gitlab-installation) **(PREMIUM ONLY)** | Yes |
-| Repmgr | PostgreSQL cluster management and failover | [PostgreSQL and Repmgr configuration](../high_availability/database.md) | Yes |
+| Repmgr | PostgreSQL cluster management and failover | [PostgreSQL and Repmgr configuration](../postgresql/replication_and_failover.md) | Yes |
| [Redis](../../development/architecture.md#redis) ([3](#footnotes)) | Key/value store for fast data lookup and caching | [Redis configuration](../high_availability/redis.md) | Yes |
| Redis Sentinel | Redis | [Redis Sentinel configuration](../high_availability/redis.md) | Yes |
-| [Gitaly](../../development/architecture.md#gitaly) ([2](#footnotes)) ([7](#footnotes)) ([10](#footnotes)) | Provides access to Git repositories | [Gitaly configuration](../gitaly/index.md#running-gitaly-on-its-own-server) | Yes |
+| [Gitaly](../../development/architecture.md#gitaly) ([2](#footnotes)) ([7](#footnotes)) | Provides access to Git repositories | [Gitaly configuration](../gitaly/index.md#run-gitaly-on-its-own-server) | Yes |
| [Sidekiq](../../development/architecture.md#sidekiq) | Asynchronous/background jobs | [Sidekiq configuration](../high_availability/sidekiq.md) | Yes |
| [GitLab application services](../../development/architecture.md#unicorn)([1](#footnotes)) | Puma/Unicorn, Workhorse, GitLab Shell - serves front-end requests (UI, API, Git over HTTP/SSH) | [GitLab app scaling configuration](../high_availability/gitlab.md) | Yes |
| [Prometheus](../../development/architecture.md#prometheus) and [Grafana](../../development/architecture.md#grafana) | GitLab environment monitoring | [Monitoring node for scaling](../high_availability/monitoring_node.md) | Yes |
+### Configuring select components with Cloud Native Helm
+
+We also provide [Helm charts](https://docs.gitlab.com/charts/) as a Cloud Native installation
+method for GitLab. For the reference architectures, select components can be set up in this
+way as an alternative if so desired.
+
+For these kind of setups we support using the charts in an [advanced configuration](https://docs.gitlab.com/charts/#advanced-configuration)
+where stateful backend components, such as the database or Gitaly, are run externally - either
+via Omnibus or reputable third party services. Note that we don't currently support running the
+stateful components via Helm _at large scales_.
+
+When designing these environments you should refer to the respective [Reference Architecture](#available-reference-architectures)
+above for guidance on sizing. Components run via Helm would be similarly scaled to their Omnibus
+specs, only translated into Kubernetes resources.
+
+For example, if you were to set up a 50k installation with the Rails nodes being run in Helm,
+then the same amount of resources as given for Omnibus should be given to the Kubernetes
+cluster with the Rails nodes broken down into a number of smaller Pods across that cluster.
+
## Footnotes
1. In our architectures we run each GitLab Rails node using the Puma webserver
@@ -177,9 +199,7 @@ column.
on workload.
1. Gitaly node requirements are dependent on customer data, specifically the number of
- projects and their sizes. We recommend two nodes as an absolute minimum,
- and at least four nodes should be used when supporting 50,000 or more users.
- We also recommend that each Gitaly node should store no more than 5TB of data
+ projects and their sizes. We recommend that each Gitaly node should store no more than 5TB of data
and have the number of [`gitaly-ruby` workers](../gitaly/index.md#gitaly-ruby)
set to 20% of available CPUs. Additional nodes should be considered in conjunction
with a review of expected data size and spread based on the recommendations above.
@@ -198,7 +218,7 @@ column.
1. NFS can be used as an alternative for object storage but this isn't typically
recommended for performance reasons. Note however it is required for [GitLab
- Pages](https://gitlab.com/gitlab-org/gitlab-pages/issues/196).
+ Pages](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/196).
1. Our architectures have been tested and validated with [HAProxy](https://www.haproxy.org/)
as the load balancer. Although other load balancers with similar feature sets
@@ -216,10 +236,3 @@ column.
or higher, are required for your CPU or Node counts accordingly. For more information, a
[Sysbench](https://github.com/akopytov/sysbench) benchmark of the CPU can be found
[here](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Reference-Architectures/GCP-CPU-Benchmarks).
-
-1. AWS-equivalent and Azure-equivalent configurations are rough suggestions
- and may change in the future. They have not yet been tested and validated.
-
-1. From GitLab 13.0, using NFS for Git repositories is deprecated. In GitLab
- 14.0, support for NFS for Git repositories is scheduled to be removed.
- Upgrade to [Gitaly Cluster](../gitaly/praefect.md) as soon as possible.
diff --git a/doc/administration/reference_architectures/troubleshooting.md b/doc/administration/reference_architectures/troubleshooting.md
new file mode 100644
index 00000000000..15e377fe183
--- /dev/null
+++ b/doc/administration/reference_architectures/troubleshooting.md
@@ -0,0 +1,329 @@
+# Troubleshooting a reference architecture set up
+
+This page serves as the troubleshooting documentation if you followed one of
+the [reference architectures](index.md#reference-architectures).
+
+## Troubleshooting object storage
+
+### S3 API compatibility issues
+
+Not all S3 providers [are fully compatible](../../raketasks/backup_restore.md#other-s3-providers)
+with the Fog library that GitLab uses. Symptoms include:
+
+```plaintext
+411 Length Required
+```
+
+### GitLab Pages requires NFS
+
+If you intend to use [GitLab Pages](../../user/project/pages/index.md), this currently requires
+[NFS](../high_availability/nfs.md). There is [work in progress](https://gitlab.com/gitlab-org/gitlab-pages/issues/196)
+to remove this dependency. In the future, GitLab Pages may use
+[object storage](https://gitlab.com/gitlab-org/gitlab/-/issues/208135).
+
+The dependency on disk storage also prevents Pages being deployed using the
+[GitLab Helm chart](https://gitlab.com/gitlab-org/charts/gitlab/-/issues/37).
+
+### Incremental logging is required for CI to use object storage
+
+If you configure GitLab to use object storage for CI logs and artifacts,
+[you must also enable incremental logging](../job_logs.md#new-incremental-logging-architecture).
+
+### Proxy Download
+
+A number of the use cases for object storage allow client traffic to be redirected to the
+object storage back end, like when Git clients request large files via LFS or when
+downloading CI artifacts and logs.
+
+When the files are stored on local block storage or NFS, GitLab has to act as a proxy.
+With object storage, the default behavior is for GitLab to redirect to the object
+storage device rather than proxy the request.
+
+The `proxy_download` setting controls this behavior: the default is generally `false`.
+Verify this in the documentation for each use case. Set it to `true` to make
+GitLab proxy the files rather than redirect.
+
+When not proxying files, GitLab returns an
+[HTTP 302 redirect with a pre-signed, time-limited object storage URL](https://gitlab.com/gitlab-org/gitlab/-/issues/32117#note_218532298).
+This can result in some of the following problems:
+
+- If GitLab is using non-secure HTTP to access the object storage, clients may generate
+`https->http` downgrade errors and refuse to process the redirect. The solution to this
+is for GitLab to use HTTPS. LFS, for example, will generate this error:
+
+ ```plaintext
+ LFS: lfsapi/client: refusing insecure redirect, https->http
+ ```
+
+- Clients will need to trust the certificate authority that issued the object storage
+certificate, or may return common TLS errors such as:
+
+ ```plaintext
+ x509: certificate signed by unknown authority
+ ```
+
+- Clients will need network access to the object storage. Errors that might result
+if this access is not in place include:
+
+ ```plaintext
+ Received status code 403 from server: Forbidden
+ ```
+
+### ETag mismatch
+
+Using the default GitLab settings, some object storage back-ends such as
+[MinIO](https://gitlab.com/gitlab-org/gitlab/-/issues/23188)
+and [Alibaba](https://gitlab.com/gitlab-org/charts/gitlab/-/issues/1564)
+might generate `ETag mismatch` errors.
+
+When using GitLab direct upload, the
+[workaround for MinIO](https://gitlab.com/gitlab-org/charts/gitlab/-/issues/1564#note_244497658)
+is to use the `--compat` parameter on the server.
+
+We are working on a fix to GitLab component Workhorse, and also
+a workaround, in the mean time, to
+[allow ETag verification to be disabled](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/18175).
+
+## Troubleshooting Redis
+
+If the application node cannot connect to the Redis node, check your firewall rules and
+make sure Redis can accept TCP connections under port `6379`.
+
+## Troubleshooting Gitaly
+
+### Checking versions when using standalone Gitaly nodes
+
+When using standalone Gitaly nodes, you must make sure they are the same version
+as GitLab to ensure full compatibility. Check **Admin Area > Gitaly Servers** on
+your GitLab instance and confirm all Gitaly Servers are `Up to date`.
+
+![Gitaly standalone software versions diagram](../gitaly/img/gitlab_gitaly_version_mismatch_v12_4.png)
+
+### `gitaly-debug`
+
+The `gitaly-debug` command provides "production debugging" tools for Gitaly and Git
+performance. It is intended to help production engineers and support
+engineers investigate Gitaly performance problems.
+
+If you're using GitLab 11.6 or newer, this tool should be installed on
+your GitLab / Gitaly server already at `/opt/gitlab/embedded/bin/gitaly-debug`.
+If you're investigating an older GitLab version you can compile this
+tool offline and copy the executable to your server:
+
+```shell
+git clone https://gitlab.com/gitlab-org/gitaly.git
+cd cmd/gitaly-debug
+GOOS=linux GOARCH=amd64 go build -o gitaly-debug
+```
+
+To see the help page of `gitaly-debug` for a list of supported sub-commands, run:
+
+```shell
+gitaly-debug -h
+```
+
+### Commits, pushes, and clones return a 401
+
+```plaintext
+remote: GitLab: 401 Unauthorized
+```
+
+You will need to sync your `gitlab-secrets.json` file with your GitLab
+app nodes.
+
+### Client side gRPC logs
+
+Gitaly uses the [gRPC](https://grpc.io/) RPC framework. The Ruby gRPC
+client has its own log file which may contain useful information when
+you are seeing Gitaly errors. You can control the log level of the
+gRPC client with the `GRPC_LOG_LEVEL` environment variable. The
+default level is `WARN`.
+
+You can run a gRPC trace with:
+
+```shell
+sudo GRPC_TRACE=all GRPC_VERBOSITY=DEBUG gitlab-rake gitlab:gitaly:check
+```
+
+### Observing `gitaly-ruby` traffic
+
+[`gitaly-ruby`](../gitaly/index.md#gitaly-ruby) is an internal implementation detail of Gitaly,
+so, there's not that much visibility into what goes on inside
+`gitaly-ruby` processes.
+
+If you have Prometheus set up to scrape your Gitaly process, you can see
+request rates and error codes for individual RPCs in `gitaly-ruby` by
+querying `grpc_client_handled_total`. Strictly speaking, this metric does
+not differentiate between `gitaly-ruby` and other RPCs, but in practice
+(as of GitLab 11.9), all gRPC calls made by Gitaly itself are internal
+calls from the main Gitaly process to one of its `gitaly-ruby` sidecars.
+
+Assuming your `grpc_client_handled_total` counter only observes Gitaly,
+the following query shows you RPCs are (most likely) internally
+implemented as calls to `gitaly-ruby`:
+
+```prometheus
+sum(rate(grpc_client_handled_total[5m])) by (grpc_method) > 0
+```
+
+### Repository changes fail with a `401 Unauthorized` error
+
+If you're running Gitaly on its own server and notice that users can
+successfully clone and fetch repositories (via both SSH and HTTPS), but can't
+push to them or make changes to the repository in the web UI without getting a
+`401 Unauthorized` message, then it's possible Gitaly is failing to authenticate
+with the other nodes due to having the wrong secrets file.
+
+Confirm the following are all true:
+
+- When any user performs a `git push` to any repository on this Gitaly node, it
+ fails with the following error (note the `401 Unauthorized`):
+
+ ```shell
+ remote: GitLab: 401 Unauthorized
+ To <REMOTE_URL>
+ ! [remote rejected] branch-name -> branch-name (pre-receive hook declined)
+ error: failed to push some refs to '<REMOTE_URL>'
+ ```
+
+- When any user adds or modifies a file from the repository using the GitLab
+ UI, it immediately fails with a red `401 Unauthorized` banner.
+- Creating a new project and [initializing it with a README](../../gitlab-basics/create-project.md#blank-projects)
+ successfully creates the project but doesn't create the README.
+- When [tailing the logs](https://docs.gitlab.com/omnibus/settings/logs.html#tail-logs-in-a-console-on-the-server) on an app node and reproducing the error, you get `401` errors
+ when reaching the `/api/v4/internal/allowed` endpoint:
+
+ ```shell
+ # api_json.log
+ {
+ "time": "2019-07-18T00:30:14.967Z",
+ "severity": "INFO",
+ "duration": 0.57,
+ "db": 0,
+ "view": 0.57,
+ "status": 401,
+ "method": "POST",
+ "path": "\/api\/v4\/internal\/allowed",
+ "params": [
+ {
+ "key": "action",
+ "value": "git-receive-pack"
+ },
+ {
+ "key": "changes",
+ "value": "REDACTED"
+ },
+ {
+ "key": "gl_repository",
+ "value": "REDACTED"
+ },
+ {
+ "key": "project",
+ "value": "\/path\/to\/project.git"
+ },
+ {
+ "key": "protocol",
+ "value": "web"
+ },
+ {
+ "key": "env",
+ "value": "{\"GIT_ALTERNATE_OBJECT_DIRECTORIES\":[],\"GIT_ALTERNATE_OBJECT_DIRECTORIES_RELATIVE\":[],\"GIT_OBJECT_DIRECTORY\":null,\"GIT_OBJECT_DIRECTORY_RELATIVE\":null}"
+ },
+ {
+ "key": "user_id",
+ "value": "2"
+ },
+ {
+ "key": "secret_token",
+ "value": "[FILTERED]"
+ }
+ ],
+ "host": "gitlab.example.com",
+ "ip": "REDACTED",
+ "ua": "Ruby",
+ "route": "\/api\/:version\/internal\/allowed",
+ "queue_duration": 4.24,
+ "gitaly_calls": 0,
+ "gitaly_duration": 0,
+ "correlation_id": "XPUZqTukaP3"
+ }
+
+ # nginx_access.log
+ [IP] - - [18/Jul/2019:00:30:14 +0000] "POST /api/v4/internal/allowed HTTP/1.1" 401 30 "" "Ruby"
+ ```
+
+To fix this problem, confirm that your `gitlab-secrets.json` file
+on the Gitaly node matches the one on all other nodes. If it doesn't match,
+update the secrets file on the Gitaly node to match the others, then
+[reconfigure the node](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+
+### Command line tools cannot connect to Gitaly
+
+If you are having trouble connecting to a Gitaly node with command line (CLI) tools, and certain actions result in a `14: Connect Failed` error message, it means that gRPC cannot reach your Gitaly node.
+
+Verify that you can reach Gitaly via TCP:
+
+```shell
+sudo gitlab-rake gitlab:tcp_check[GITALY_SERVER_IP,GITALY_LISTEN_PORT]
+```
+
+If the TCP connection fails, check your network settings and your firewall rules. If the TCP connection succeeds, your networking and firewall rules are correct.
+
+If you use proxy servers in your command line environment, such as Bash, these can interfere with your gRPC traffic.
+
+If you use Bash or a compatible command line environment, run the following commands to determine whether you have proxy servers configured:
+
+```shell
+echo $http_proxy
+echo $https_proxy
+```
+
+If either of these variables have a value, your Gitaly CLI connections may be getting routed through a proxy which cannot connect to Gitaly.
+
+To remove the proxy setting, run the following commands (depending on which variables had values):
+
+```shell
+unset http_proxy
+unset https_proxy
+```
+
+### Gitaly not listening on new address after reconfiguring
+
+When updating the `gitaly['listen_addr']` or `gitaly['prometheus_listen_addr']` values, Gitaly may continue to listen on the old address after a `sudo gitlab-ctl reconfigure`.
+
+When this occurs, performing a `sudo gitlab-ctl restart` will resolve the issue. This will no longer be necessary after [this issue](https://gitlab.com/gitlab-org/gitaly/issues/2521) is resolved.
+
+### Permission denied errors appearing in Gitaly logs when accessing repositories from a standalone Gitaly node
+
+If this error occurs even though file permissions are correct, it's likely that
+the Gitaly node is experiencing
+[clock drift](https://en.wikipedia.org/wiki/Clock_drift).
+
+Please ensure that the GitLab and Gitaly nodes are synchronized and use an NTP time
+server to keep them synchronized if possible.
+
+## Troubleshooting the GitLab Rails application
+
+- `mount: wrong fs type, bad option, bad superblock on`
+
+You have not installed the necessary NFS client utilities. See step 1 above.
+
+- `mount: mount point /var/opt/gitlab/... does not exist`
+
+This particular directory does not exist on the NFS server. Ensure
+the share is exported and exists on the NFS server and try to remount.
+
+## Troubleshooting Monitoring
+
+If the monitoring node is not receiving any data, check that the exporters are
+capturing data.
+
+```shell
+curl http[s]://localhost:<EXPORTER LISTENING PORT>/metric
+```
+
+or
+
+```shell
+curl http[s]://localhost:<EXPORTER LISTENING PORT>/-/metric
+```
diff --git a/doc/administration/repository_storage_paths.md b/doc/administration/repository_storage_paths.md
index 283401dafff..87f901becf5 100644
--- a/doc/administration/repository_storage_paths.md
+++ b/doc/administration/repository_storage_paths.md
@@ -10,7 +10,7 @@ storage shards) to distribute the storage load between several mount points.
> - You must have at least one storage path called `default`.
> - The paths are defined in key-value pairs. The key is an arbitrary name you
> can pick to name the file path.
-> - The target directories and any of its subpaths must not be a symlink.
+> - The target directories and any of its sub-paths must not be a symlink.
> - No target directory may be a sub-directory of another; no nesting.
Example: this is OK:
@@ -57,7 +57,7 @@ storage2:
Now that you've read that big fat warning above, let's edit the configuration
files and add the full paths of the alternative repository storage paths. In
-the example below, we add two more mountpoints that are named `nfs_1` and `nfs_2`
+the example below, we add two more mount points that are named `nfs_1` and `nfs_2`
respectively.
NOTE: **Note:** This example uses NFS. We do not recommend using EFS for storage as it may impact GitLab's performance. See the [relevant documentation](high_availability/nfs.md#avoid-using-awss-elastic-file-system-efs) for more details.
diff --git a/doc/administration/repository_storage_types.md b/doc/administration/repository_storage_types.md
index a95178c01e2..825da08b66e 100644
--- a/doc/administration/repository_storage_types.md
+++ b/doc/administration/repository_storage_types.md
@@ -1,6 +1,6 @@
# Repository storage types **(CORE ONLY)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/28283) in GitLab 10.0.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/28283) in GitLab 10.0.
> - Hashed storage became the default for new installations in GitLab 12.0
> - Hashed storage is enabled by default for new and renamed projects in GitLab 13.0.
@@ -108,7 +108,7 @@ The output includes the project ID and the project name:
### Hashed object pools
-> [Introduced](https://gitlab.com/gitlab-org/gitaly/issues/1606) in GitLab 12.1.
+> [Introduced](https://gitlab.com/gitlab-org/gitaly/-/issues/1606) in GitLab 12.1.
DANGER: **Danger:**
Do not run `git prune` or `git gc` in pool repositories! This can
diff --git a/doc/administration/server_hooks.md b/doc/administration/server_hooks.md
index 0b8c66805ae..6df0f187a42 100644
--- a/doc/administration/server_hooks.md
+++ b/doc/administration/server_hooks.md
@@ -1,4 +1,7 @@
---
+stage: Create
+group: Gitaly
+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, howto
disqus_identifier: 'https://docs.gitlab.com/ee/administration/custom_hooks.html'
---
@@ -7,7 +10,7 @@ disqus_identifier: 'https://docs.gitlab.com/ee/administration/custom_hooks.html'
> **Notes:**
>
-> - Server hooks were [introduced](https://gitlab.com/gitlab-org/gitlab/issues/196051) in GitLab 12.8 replacing Custom Hooks.
+> - Server hooks were [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196051) in GitLab 12.8 replacing Custom Hooks.
> - Server hooks must be configured on the filesystem of the GitLab server. Only GitLab server administrators will be able to complete these tasks. Please explore [webhooks](../user/project/integrations/webhooks.md) and [GitLab CI/CD](../ci/README.md) as an option if you do not have filesystem access. For a user-configurable Git hook interface, see [Push Rules](../push_rules/push_rules.md), available in GitLab Starter **(STARTER)**.
> - Server hooks won't be replicated to secondary nodes if you use [GitLab Geo](geo/replication/index.md).
@@ -65,9 +68,18 @@ Follow the steps below to properly set up a server hook for all repositories:
`/home/git/gitlab-shell/hooks`. For Omnibus installs the path is usually
`/opt/gitlab/embedded/service/gitlab-shell/hooks`.
To look in a different directory for the global custom hooks,
- set `custom_hooks_dir` in the GitLab Shell config. For
- Omnibus installations, this can be set in `gitlab.rb`; and in source
- installations, this can be set in `gitlab-shell/config.yml`.
+ set `custom_hooks_dir` in the Gitaly config. For Omnibus installations, this is set
+ in `gitlab.rb`. For source installations, the configuration location depends on the
+ GitLab version. For:
+
+ - GitLab 13.0 and earlier, this is set in `gitlab-shell/config.yml`.
+ - GitLab 13.1 and later, this is set in `gitaly/config.toml` under the `[hooks]`
+ section.
+
+ NOTE: **Note:**
+ The `custom_hooks_dir` value in `gitlab-shell/config.yml` is still honored in GitLab
+ 13.1 and later if the value in `gitaly/config.toml` is blank or non-existent.
+
1. Create a new directory in this location. Depending on your hook, it will be
either a `pre-receive.d`, `post-receive.d`, or `update.d` directory.
1. Inside this new directory, add your hook. Hooks can be
diff --git a/doc/administration/snippets/index.md b/doc/administration/snippets/index.md
index e6bbfa8cf00..cf3d8bec1a6 100644
--- a/doc/administration/snippets/index.md
+++ b/doc/administration/snippets/index.md
@@ -8,7 +8,7 @@ Adjust the snippets' settings of your GitLab instance.
## Snippets content size limit
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/31133) in GitLab 12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/31133) in GitLab 12.6.
You can set a content size max limit in snippets. This limit can prevent
abuses of the feature. The default content size limit is **52428800 Bytes** (50MB).
diff --git a/doc/administration/timezone.md b/doc/administration/timezone.md
index d6112c45141..3cfee8630b7 100644
--- a/doc/administration/timezone.md
+++ b/doc/administration/timezone.md
@@ -15,7 +15,7 @@ To see all available time zones, run `bundle exec rake time:zones:all`.
For Omnibus installations, run `gitlab-rake time:zones:all`.
NOTE: **Note:**
-Currently, this Rake task does not list timezones in TZInfo format required by Omnibus GitLab during a reconfigure: [#58672](https://gitlab.com/gitlab-org/gitlab-foss/issues/58672).
+Currently, this Rake task does not list timezones in TZInfo format required by Omnibus GitLab during a reconfigure: [#27209](https://gitlab.com/gitlab-org/gitlab/-/issues/27209).
## Changing time zone in Omnibus installations
diff --git a/doc/administration/troubleshooting/debug.md b/doc/administration/troubleshooting/debug.md
index 1e1b2ad8378..55fd6462bc3 100644
--- a/doc/administration/troubleshooting/debug.md
+++ b/doc/administration/troubleshooting/debug.md
@@ -244,7 +244,7 @@ separate Rails process to debug the issue:
For example:
```ruby
- app.get 'https://gitlab.com/gitlab-org/gitlab-foss/issues/1?private_token=123456'
+ app.get 'https://gitlab.com/gitlab-org/gitlab-foss/-/issues/1?private_token=123456'
```
1. In a new window, run `top`. It should show this Ruby process using 100% CPU. Write down the PID.
diff --git a/doc/administration/troubleshooting/elasticsearch.md b/doc/administration/troubleshooting/elasticsearch.md
index a39fe4ba8c3..12b82e4bc48 100644
--- a/doc/administration/troubleshooting/elasticsearch.md
+++ b/doc/administration/troubleshooting/elasticsearch.md
@@ -189,7 +189,7 @@ Moving past that, it is best to attempt the same search using the [Elasticsearch
If the results:
-- Sync up, then there is not a technical "issue" per se. Instead, it might be a problem
+- Sync up, then there is not a technical "issue." Instead, it might be a problem
with the Elasticsearch filters we are using. This can be complicated, so it is best to
escalate to GitLab support to check these and guide you on the potential on whether or
not a feature request is needed.
@@ -330,10 +330,10 @@ feel free to update that page with issues you encounter and solutions.
Setting up Elasticsearch isn't too bad, but it can be a bit finicky and time consuming.
-The easiest method is to spin up a docker container with the required version and
+The easiest method is to spin up a Docker container with the required version and
bind ports 9200/9300 so it can be used.
-The following is an example of running a docker container of Elasticsearch v7.2.0:
+The following is an example of running a Docker container of Elasticsearch v7.2.0:
```shell
docker pull docker.elastic.co/elasticsearch/elasticsearch:7.2.0
@@ -342,7 +342,7 @@ docker run -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" docker.elas
From here, you can:
-- Grab the IP of the docker container (use `docker inspect <container_id>`)
+- Grab the IP of the Docker container (use `docker inspect <container_id>`)
- Use `<IP.add.re.ss:9200>` to communicate with it.
This is a quick method to test out Elasticsearch, but by no means is this a
diff --git a/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md b/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
index 2cbc994fb4c..33af356b37d 100644
--- a/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
+++ b/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
@@ -263,7 +263,7 @@ p.import_state.mark_as_failed("Failed manually through console.")
In a specific situation, an imported repository needed to be renamed. The Support
Team was informed of a backup restore that failed on a single repository, which created
-the project with an empty repository. The project was successfully restored to a dev
+the project with an empty repository. The project was successfully restored to a development
instance, then exported, and imported into a new project under a different name.
The Support Team was able to transfer the incorrectly named imported project into the
@@ -302,7 +302,7 @@ you will see two pushes with the same "from" SHA:
```ruby
p = Project.find_with_namespace('u/p')
-p.events.code_push.last(100).each do |e|
+p.events.pushed_action.last(100).each do |e|
printf "%-20.20s %8s...%8s (%s)\n", e.data[:ref], e.data[:before], e.data[:after], e.author.try(:username)
end
```
@@ -311,7 +311,7 @@ GitLab 9.5 and above:
```ruby
p = Project.find_by_full_path('u/p')
-p.events.code_push.last(100).each do |e|
+p.events.pushed_action.last(100).each do |e|
printf "%-20.20s %8s...%8s (%s)\n", e.push_event_payload[:ref], e.push_event_payload[:commit_from], e.push_event_payload[:commit_to], e.author.try(:username)
end
```
@@ -380,39 +380,6 @@ user = User.find_by_username ''
user.skip_reconfirmation!
```
-### Get an admin token
-
-```ruby
-# Get the first admin's first access token (no longer works on 11.9+. see: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/22743)
-User.where(admin:true).first.personal_access_tokens.first.token
-
-# Get the first admin's private token (no longer works on 10.2+)
-User.where(admin:true).private_token
-```
-
-### Create personal access token
-
-```ruby
-personal_access_token = User.find(123).personal_access_tokens.create(
- name: 'apitoken',
- impersonation: false,
- scopes: [:api]
-)
-
-puts personal_access_token.token
-```
-
-You might also want to manually set the token string:
-
-```ruby
-User.find(123).personal_access_tokens.create(
- name: 'apitoken',
- token_digest: Gitlab::CryptoHelper.sha256('some-token-string-here'),
- impersonation: false,
- scopes: [:api]
-)
-```
-
### Active users & Historical users
```ruby
@@ -518,7 +485,7 @@ group.project_creation_level=0
### Remove redirecting routes
-See <https://gitlab.com/gitlab-org/gitlab-foss/issues/41758#note_54828133>.
+See <https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41758#note_54828133>.
```ruby
path = 'foo'
@@ -576,7 +543,7 @@ This section has been moved to the [job artifacts troubleshooting documentation]
### Find reason failure (for when build trace is empty) (Introduced in 10.3.0)
-See <https://gitlab.com/gitlab-org/gitlab-foss/issues/41111>.
+See <https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41111>.
```ruby
build = Ci::Build.find(78420)
@@ -620,10 +587,26 @@ Gitlab::CurrentSettings.current_application_settings.runners_registration_token
## License
-### See license plan name (since v9.3.0-ee)
+### See current license information
```ruby
+# License information (name, company, email address)
+License.current.licensee
+
+# Plan:
License.current.plan
+
+# Uploaded:
+License.current.created_at
+
+# Started:
+License.current.starts_at
+
+# Expires at:
+License.current.expires_at
+
+# Is this a trial license?
+License.current.trial?
```
### Check if a project feature is available on the instance
@@ -636,7 +619,7 @@ License.current.feature_available?(:jira_dev_panel_integration)
### Check if a project feature is available in a project
-Features listed in <https://gitlab.com/gitlab-org/gitlab/blob/master/ee/app/models/license.rb>.
+Features listed in [`license.rb`](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/app/models/license.rb).
```ruby
p = Project.find_by_full_path('<group>/<project>')
diff --git a/doc/administration/troubleshooting/index.md b/doc/administration/troubleshooting/index.md
new file mode 100644
index 00000000000..50f192b1983
--- /dev/null
+++ b/doc/administration/troubleshooting/index.md
@@ -0,0 +1,20 @@
+# Troubleshooting a GitLab installation
+
+Below are some resources to help you troubleshoot a GitLab installation
+in case something goes wrong:
+
+- [Debugging tips](debug.md)
+- [Diagnostics tools](diagnostics_tools.md)
+- [Elasticsearch](elasticsearch.md)
+- [GitLab Rails console cheat sheet](gitlab_rails_cheat_sheet.md)
+- [Group SAML and SCIM troubleshooting](group_saml_scim.md) **(SILVER ONLY)**
+- [Kubernetes cheat sheet](kubernetes_cheat_sheet.md)
+- [Linux cheat sheet](linux_cheat_sheet.md)
+- [Parsing GitLab logs with `jq`](log_parsing.md)
+- [Navigating GitLab via Rails console](navigating_gitlab_via_rails_console.md)
+- [PostgreSQL](postgresql.md)
+- [Sidekiq](sidekiq.md)
+- [SSL](ssl.md)
+
+If you need a testing environment to troubleshoot, see the
+[apps for a testing environment](test_environments.md).
diff --git a/doc/administration/troubleshooting/kubernetes_cheat_sheet.md b/doc/administration/troubleshooting/kubernetes_cheat_sheet.md
index cab073b9924..01532032b49 100644
--- a/doc/administration/troubleshooting/kubernetes_cheat_sheet.md
+++ b/doc/administration/troubleshooting/kubernetes_cheat_sheet.md
@@ -85,7 +85,7 @@ and they will assist you with any issues you are having.
## GitLab-specific Kubernetes information
- Minimal config that can be used to test a Kubernetes Helm chart can be found
- [here](https://gitlab.com/gitlab-org/charts/gitlab/issues/620).
+ [here](https://gitlab.com/gitlab-org/charts/gitlab/-/issues/620).
- Tailing logs of a separate pod. An example for a Webservice pod:
@@ -186,7 +186,7 @@ and they will assist you with any issues you are having.
helm upgrade <release name> <chart path> -f gitlab.yaml
```
- After <https://gitlab.com/gitlab-org/charts/gitlab/issues/780> is fixed, it should
+ After <https://gitlab.com/gitlab-org/charts/gitlab/-/issues/780> is fixed, it should
be possible to use [Updating GitLab using the Helm Chart](https://docs.gitlab.com/charts/index.html#updating-gitlab-using-the-helm-chart)
for upgrades.
diff --git a/doc/administration/troubleshooting/postgresql.md b/doc/administration/troubleshooting/postgresql.md
index 65a6bffca44..e5a4dffb3cc 100644
--- a/doc/administration/troubleshooting/postgresql.md
+++ b/doc/administration/troubleshooting/postgresql.md
@@ -31,7 +31,7 @@ This section is for links to information elsewhere in the GitLab documentation.
- Destructively reseeding the GitLab database.
- Guidance around updating packaged PostgreSQL, including how to stop it happening automatically.
-- [More about external PostgreSQL](../external_database.md)
+- [More about external PostgreSQL](../postgresql/external.md)
- [Running Geo with external PostgreSQL](../geo/replication/external_database.md)
@@ -45,8 +45,8 @@ This section is for links to information elsewhere in the GitLab documentation.
- Managing Omnibus PostgreSQL versions [from the development docs](https://docs.gitlab.com/omnibus/development/managing-postgresql-versions.html)
-- [PostgreSQL scaling](../high_availability/database.md)
- - including [troubleshooting](../high_availability/database.md#troubleshooting) `gitlab-ctl repmgr-check-master` and PgBouncer errors
+- [PostgreSQL scaling](../postgresql/replication_and_failover.md)
+ - including [troubleshooting](../postgresql/replication_and_failover.md#troubleshooting) `gitlab-ctl repmgr-check-master` and PgBouncer errors
- [Developer database documentation](../../development/README.md#database-guides) - some of which is absolutely not for production use. Including:
- understanding EXPLAIN plans
@@ -55,8 +55,8 @@ This section is for links to information elsewhere in the GitLab documentation.
- [GitLab database requirements](../../install/requirements.md#database) including
- Support for MySQL was removed in GitLab 12.1; [migrate to PostgreSQL](../../update/mysql_to_postgresql.md)
- - required extension pg_trgm
- - required extension postgres_fdw for Geo
+ - required extension `pg_trgm`
+ - required extension `postgres_fdw` for Geo
- Errors like this in the `production/sidekiq` log; see: [Set default_transaction_isolation into read committed](https://docs.gitlab.com/omnibus/settings/database.html#set-default_transaction_isolation-into-read-committed):
@@ -95,15 +95,15 @@ This section is for links to information elsewhere in the GitLab documentation.
References:
-- [Issue #1 Deadlocks with GitLab 12.1, PostgreSQL 10.7](https://gitlab.com/gitlab-org/gitlab/issues/30528)
+- [Issue #1 Deadlocks with GitLab 12.1, PostgreSQL 10.7](https://gitlab.com/gitlab-org/gitlab/-/issues/30528)
- [Customer ticket (internal) GitLab 12.1.6](https://gitlab.zendesk.com/agent/tickets/134307) and [Google doc (internal)](https://docs.google.com/document/d/19xw2d_D1ChLiU-MO1QzWab-4-QXgsIUcN5e_04WTKy4)
-- [Issue #2 deadlocks can occur if an instance is flooded with pushes](https://gitlab.com/gitlab-org/gitlab/issues/33650). Provided for context about how GitLab code can have this sort of unanticipated effect in unusual situations.
+- [Issue #2 deadlocks can occur if an instance is flooded with pushes](https://gitlab.com/gitlab-org/gitlab/-/issues/33650). Provided for context about how GitLab code can have this sort of unanticipated effect in unusual situations.
```plaintext
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 [#1](https://gitlab.com/gitlab-org/gitlab/-/issues/30528); our recommended settings are as follows:
```ini
deadlock_timeout = 5s
@@ -111,20 +111,20 @@ statement_timeout = 15s
idle_in_transaction_session_timeout = 60s
```
-Quoting from issue [#1](https://gitlab.com/gitlab-org/gitlab/issues/30528):
+Quoting from issue [#1](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."
TIP: **Tip:** In support, our general approach to reconfiguring timeouts (applies also to the HTTP stack as well) is that it's acceptable to do it temporarily as a workaround. If it makes GitLab usable for the customer, then it buys time to understand the problem more completely, implement a hot fix, or make some other change that addresses the root cause. Generally, the timeouts should be put back to reasonable defaults once the root cause is resolved.
-In this case, the guidance we had from development was to drop deadlock_timeout and/or statement_timeout but to leave the third setting at 60s. Setting idle_in_transaction protects the database from sessions potentially hanging for days. There's more discussion in [the issue relating to introducing this timeout on GitLab.com](https://gitlab.com/gitlab-com/gl-infra/production/issues/1053).
+In this case, the guidance we had from development was to drop deadlock_timeout and/or statement_timeout but to leave the third setting at 60s. Setting idle_in_transaction protects the database from sessions potentially hanging for days. There's more discussion in [the issue relating to introducing this timeout on GitLab.com](https://gitlab.com/gitlab-com/gl-infra/production/-/issues/1053).
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) indicate that these should both be set to at least a number of minutes for all Omnibus installations (so they don't hang indefinitely). However, 15s for statement_timeout is very short, and will only be effective if the underlying infrastructure is very performant.
+Comments in issue [#1](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 installations (so they don't hang indefinitely). However, 15s for statement_timeout is very short, and will only be effective if the underlying infrastructure is very performant.
See current settings with:
diff --git a/doc/administration/troubleshooting/sidekiq.md b/doc/administration/troubleshooting/sidekiq.md
index ca21c038267..5109a3baff2 100644
--- a/doc/administration/troubleshooting/sidekiq.md
+++ b/doc/administration/troubleshooting/sidekiq.md
@@ -29,9 +29,18 @@ Example:
gitlab_rails['env'] = {"SIDEKIQ_LOG_ARGUMENTS" => "1"}
```
-Please note: It is not recommend to enable this setting in production because some
-Sidekiq jobs (such as sending a password reset email) take secret arguments (for
-example the password reset token).
+This does not log all job arguments. To avoid logging sensitive
+information (for instance, password reset tokens), it logs numeric
+arguments for all workers, with overrides for some specific workers
+where their arguments are not sensitive.
+
+Example log output:
+
+```json
+{"severity":"INFO","time":"2020-06-08T14:37:37.892Z","class":"AdminEmailsWorker","args":["[FILTERED]","[FILTERED]","[FILTERED]"],"retry":3,"queue":"admin_emails","backtrace":true,"jid":"9e35e2674ac7b12d123e13cc","created_at":"2020-06-08T14:37:37.373Z","meta.user":"root","meta.caller_id":"Admin::EmailsController#create","correlation_id":"37D3lArJmT1","uber-trace-id":"2d942cc98cc1b561:6dc94409cfdd4d77:9fbe19bdee865293:1","enqueued_at":"2020-06-08T14:37:37.410Z","pid":65011,"message":"AdminEmailsWorker JID-9e35e2674ac7b12d123e13cc: done: 0.48085 sec","job_status":"done","scheduling_latency_s":0.001012,"redis_calls":9,"redis_duration_s":0.004608,"redis_read_bytes":696,"redis_write_bytes":6141,"duration_s":0.48085,"cpu_s":0.308849,"completed_at":"2020-06-08T14:37:37.892Z","db_duration_s":0.010742}
+{"severity":"INFO","time":"2020-06-08T14:37:37.894Z","class":"ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper","wrapped":"ActionMailer::DeliveryJob","queue":"mailers","args":["[FILTERED]"],"retry":3,"backtrace":true,"jid":"e47a4f6793d475378432e3c8","created_at":"2020-06-08T14:37:37.884Z","meta.user":"root","meta.caller_id":"AdminEmailsWorker","correlation_id":"37D3lArJmT1","uber-trace-id":"2d942cc98cc1b561:29344de0f966446d:5c3b0e0e1bef987b:1","enqueued_at":"2020-06-08T14:37:37.885Z","pid":65011,"message":"ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper JID-e47a4f6793d475378432e3c8: start","job_status":"start","scheduling_latency_s":0.009473}
+{"severity":"INFO","time":"2020-06-08T14:39:50.648Z","class":"NewIssueWorker","args":["455","1"],"retry":3,"queue":"new_issue","backtrace":true,"jid":"a24af71f96fd129ec47f5d1e","created_at":"2020-06-08T14:39:50.643Z","meta.user":"root","meta.project":"h5bp/html5-boilerplate","meta.root_namespace":"h5bp","meta.caller_id":"Projects::IssuesController#create","correlation_id":"f9UCZHqhuP7","uber-trace-id":"28f65730f99f55a3:a5d2b62dec38dffc:48ddd092707fa1b7:1","enqueued_at":"2020-06-08T14:39:50.646Z","pid":65011,"message":"NewIssueWorker JID-a24af71f96fd129ec47f5d1e: start","job_status":"start","scheduling_latency_s":0.001144}
+```
When using [Sidekiq JSON logging](../logs.md#sidekiqlog),
arguments logs are limited to a maximum size of 10 kilobytes of text;
@@ -86,13 +95,13 @@ sudo apt-get install linux-tools-common linux-tools-generic linux-tools-`uname -
sudo yum install perf
```
-Run perf against the Sidekiq PID:
+Run `perf` against the Sidekiq PID:
```shell
sudo perf record -p <sidekiq_pid>
```
-Let this run for 30-60 seconds and then press Ctrl-C. Then view the perf report:
+Let this run for 30-60 seconds and then press Ctrl-C. Then view the `perf` report:
```shell
$ sudo perf report
@@ -105,13 +114,13 @@ Samples: 348K of event 'cycles', Event count (approx.): 280908431073
0.10% ruby libc-2.12.so [.] _int_free
```
-Above you see sample output from a perf report. It shows that 97% of the CPU is
+Above you see sample output from a `perf` report. It shows that 97% of the CPU is
being spent inside Nokogiri and `xmlXPathNodeSetMergeAndClear`. For something
this obvious you should then go investigate what job in GitLab would use
Nokogiri and XPath. Combine with `TTIN` or `gdb` output to show the
corresponding Ruby code where this is happening.
-## The GNU Project Debugger (gdb)
+## The GNU Project Debugger (`gdb`)
`gdb` can be another effective tool for debugging Sidekiq. It gives you a little
more interactive way to look at each thread and see what's causing problems.
diff --git a/doc/administration/troubleshooting/test_environments.md b/doc/administration/troubleshooting/test_environments.md
index e9db5f64446..80ccd15aa22 100644
--- a/doc/administration/troubleshooting/test_environments.md
+++ b/doc/administration/troubleshooting/test_environments.md
@@ -16,7 +16,7 @@ are only available internally at GitLab.
## Docker
-The following were tested on docker containers running in the cloud. Support Engineers,
+The following were tested on Docker containers running in the cloud. Support Engineers,
please see [these docs](https://gitlab.com/gitlab-com/dev-resources/tree/master/dev-resources#running-docker-containers)
on how to run Docker containers on `dev-resources`. Other setups haven't been tested,
but contributions are welcome.
diff --git a/doc/administration/uploads.md b/doc/administration/uploads.md
index 0a300084342..620f349912c 100644
--- a/doc/administration/uploads.md
+++ b/doc/administration/uploads.md
@@ -168,8 +168,8 @@ The connection settings match those provided by [Fog](https://github.com/fog), a
| `provider` | Always `OpenStack` for compatible hosts | `OpenStack` |
| `openstack_username` | OpenStack username | |
| `openstack_api_key` | OpenStack API key | |
-| `openstack_temp_url_key` | OpenStack key for generating temporary urls | |
-| `openstack_auth_url` | OpenStack authentication endpont | |
+| `openstack_temp_url_key` | OpenStack key for generating temporary URLs | |
+| `openstack_auth_url` | OpenStack authentication endpoint | |
| `openstack_region` | OpenStack region | |
| `openstack_tenant` | OpenStack tenant ID |
diff --git a/doc/api/README.md b/doc/api/README.md
index 34d496a37fe..6cbb99a76cb 100644
--- a/doc/api/README.md
+++ b/doc/api/README.md
@@ -53,12 +53,12 @@ between v3 and v4; please read the [v3 to v4 documentation](v3_to_v4.md)
### Current status
Currently only API version v4 is available. Version v3 was removed in
-[GitLab 11.0](https://gitlab.com/gitlab-org/gitlab-foss/issues/36819).
+[GitLab 11.0](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/36819).
## Basic usage
API requests should be prefixed with `api` and the API version. The API version
-is defined in [`lib/api.rb`](https://gitlab.com/gitlab-org/gitlab-foss/tree/master/lib/api/api.rb). For example, the root of the v4 API
+is defined in [`lib/api.rb`](https://gitlab.com/gitlab-org/gitlab/tree/master/lib/api/api.rb). For example, the root of the v4 API
is at `/api/v4`.
Example of a valid API request using cURL:
@@ -107,13 +107,13 @@ You can use an [OAuth2 token](oauth2.md) to authenticate with the API by passing
Example of using the OAuth2 token in a parameter:
```shell
-curl https://gitlab.example.com/api/v4/projects?access_token=OAUTH-TOKEN
+curl "https://gitlab.example.com/api/v4/projects?access_token=OAUTH-TOKEN"
```
Example of using the OAuth2 token in a header:
```shell
-curl --header "Authorization: Bearer OAUTH-TOKEN" https://gitlab.example.com/api/v4/projects
+curl --header "Authorization: Bearer OAUTH-TOKEN" "https://gitlab.example.com/api/v4/projects"
```
Read more about [GitLab as an OAuth2 provider](oauth2.md).
@@ -126,19 +126,19 @@ or the `Private-Token` header.
Example of using the personal/project access token in a parameter:
```shell
-curl https://gitlab.example.com/api/v4/projects?private_token=<your_access_token>
+curl "https://gitlab.example.com/api/v4/projects?private_token=<your_access_token>"
```
Example of using the personal/project access token in a header:
```shell
-curl --header "Private-Token: <your_access_token>" https://gitlab.example.com/api/v4/projects
+curl --header "Private-Token: <your_access_token>" "https://gitlab.example.com/api/v4/projects"
```
You can also use personal/project access tokens with OAuth-compliant headers:
```shell
-curl --header "Authorization: Bearer <your_access_token>" https://gitlab.example.com/api/v4/projects
+curl --header "Authorization: Bearer <your_access_token>" "https://gitlab.example.com/api/v4/projects"
```
### Session cookie
@@ -180,7 +180,7 @@ Impersonation tokens are used exactly like regular personal access tokens, and c
#### Disable impersonation
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/40385) in GitLab 11.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/40385) in GitLab 11.6.
By default, impersonation is enabled. To disable impersonation:
@@ -348,7 +348,7 @@ and we request the second page (`page=2`) of [comments](notes.md) of the issue
with ID `8` which belongs to the project with ID `8`:
```shell
-curl --head --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/8/issues/8/notes?per_page=3&page=2
+curl --head --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/8/issues/8/notes?per_page=3&page=2"
```
The response will then be:
@@ -417,10 +417,14 @@ The response header includes a link to the next page. For example:
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
...
```
+CAUTION: **Deprecation:**
+The `Links` Header will be removed in GitLab 14.0 to be aligned with the [W3C specification](https://www.w3.org/wiki/LinkHeader)
+
The link to the next page contains an additional filter `id_after=42` which excludes records we have retrieved already.
Note the type of filter depends on the `order_by` option used and we may have more than one additional filter.
@@ -450,7 +454,7 @@ The `:id` path parameter needs to be replaced with the project ID, and the `:gro
The resulting cURL call for a project with ID `5` and a group ID of `17` is then:
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/share/17
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/share/17"
```
NOTE: **Note:**
@@ -521,10 +525,10 @@ https://gitlab.example.com/api/v4/projects/import
`variables` is a parameter of type `array` containing hash key/value pairs `[{ 'key' => 'UPLOAD_TO_S3', 'value' => 'true' }]`:
```shell
-curl --globoff --request POST --header "PRIVATE-TOKEN: ********************" \
+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"
-curl --request POST --header "PRIVATE-TOKEN: ********************" \
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
--header "Content-Type: application/json" \
--data '{ "ref": "master", "variables": [ {"key": "VAR1", "value": "hello"}, {"key": "VAR2", "value": "world"} ] }' \
"https://gitlab.example.com/api/v4/projects/169/pipeline"
diff --git a/doc/api/access_requests.md b/doc/api/access_requests.md
index fd667073680..53198d05b46 100644
--- a/doc/api/access_requests.md
+++ b/doc/api/access_requests.md
@@ -6,14 +6,12 @@
The access levels are defined in the `Gitlab::Access` module. Currently, these levels are recognized:
-```plaintext
-0 => No access
-10 => Guest access
-20 => Reporter access
-30 => Developer access
-40 => Maintainer access
-50 => Owner access # Only valid for groups
-```
+- No access (`0`)
+- Guest (`10`)
+- Reporter (`20`)
+- Developer (`30`)
+- Maintainer (`40`)
+- Owner (`50`) - Only valid to set for groups
## List access requests for a group or project
@@ -31,8 +29,8 @@ GET /projects/:id/access_requests
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/:id/access_requests
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:id/access_requests
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/access_requests"
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/access_requests"
```
Example response:
@@ -74,8 +72,8 @@ POST /projects/:id/access_requests
Example request:
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/:id/access_requests
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:id/access_requests
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/access_requests"
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/access_requests"
```
Example response:
@@ -109,8 +107,8 @@ PUT /projects/:id/access_requests/:user_id/approve
Example request:
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/:id/access_requests/:user_id/approve?access_level=20
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:id/access_requests/:user_id/approve?access_level=20
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/access_requests/:user_id/approve?access_level=20"
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/access_requests/:user_id/approve?access_level=20"
```
Example response:
@@ -143,6 +141,6 @@ DELETE /projects/:id/access_requests/:user_id
Example request:
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/:id/access_requests/:user_id
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:id/access_requests/:user_id
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/access_requests/:user_id"
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/access_requests/:user_id"
```
diff --git a/doc/api/admin_sidekiq_queues.md b/doc/api/admin_sidekiq_queues.md
index 9d053714b54..32d336e79fe 100644
--- a/doc/api/admin_sidekiq_queues.md
+++ b/doc/api/admin_sidekiq_queues.md
@@ -33,7 +33,7 @@ DELETE /admin/sidekiq/queues/:queue_name
At least one attribute, other than `queue_name`, is required.
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/admin/sidekiq/queues/authorized_projects?user=root
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/admin/sidekiq/queues/authorized_projects?user=root"
```
Example response:
diff --git a/doc/api/appearance.md b/doc/api/appearance.md
index 733d71ee222..47a9d48a4ae 100644
--- a/doc/api/appearance.md
+++ b/doc/api/appearance.md
@@ -1,6 +1,6 @@
# Appearance API **(CORE ONLY)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/16647) in GitLab 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/16647) in GitLab 12.7.
Appearance API allows you to maintain GitLab's appearance as if using the GitLab UI at
`/admin/appearance`. The API requires administrator privileges.
@@ -14,7 +14,7 @@ GET /application/appearance
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/application/appearance
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/application/appearance"
```
Example response:
@@ -50,7 +50,7 @@ PUT /application/appearance
| `description` | string | no | Markdown text shown on the sign in / sign up page
| `logo` | mixed | no | Instance image used on the sign in / sign up page
| `header_logo` | mixed | no | Instance image used for the main navigation bar
-| `favicon` | mixed | no | Instance favicon in .ico/.png format
+| `favicon` | mixed | no | Instance favicon in `.ico` or `.png` format
| `new_project_guidelines` | string | no | Markdown text shown on the new project page
| `profile_image_guidelines` | string | no | Markdown text shown on the profile page below Public Avatar
| `header_message` | string | no | Message within the system header bar
@@ -60,7 +60,7 @@ PUT /application/appearance
| `email_header_and_footer_enabled` | boolean | no | Add header and footer to all outgoing emails if enabled
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/application/appearance?email_header_and_footer_enabled=true&header_message=test
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/application/appearance?email_header_and_footer_enabled=true&header_message=test"
```
Example response:
diff --git a/doc/api/applications.md b/doc/api/applications.md
index 5d4a8b3a99f..379f346c019 100644
--- a/doc/api/applications.md
+++ b/doc/api/applications.md
@@ -32,7 +32,7 @@ Parameters:
Example request:
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --data "name=MyApplication&redirect_uri=http://redirect.uri&scopes=" https://gitlab.example.com/api/v4/applications
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --data "name=MyApplication&redirect_uri=http://redirect.uri&scopes=" "https://gitlab.example.com/api/v4/applications"
```
Example response:
@@ -59,7 +59,7 @@ GET /applications
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/applications
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/applications"
```
Example response:
@@ -98,5 +98,5 @@ Parameters:
Example request:
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/applications/:id
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/applications/:id"
```
diff --git a/doc/api/audit_events.md b/doc/api/audit_events.md
index 7754f431110..ce2a9afd53c 100644
--- a/doc/api/audit_events.md
+++ b/doc/api/audit_events.md
@@ -25,7 +25,7 @@ are paginated.
Read more on [pagination](README.md#pagination).
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://primary.example.com/api/v4/audit_events
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://primary.example.com/api/v4/audit_events"
```
Example response:
@@ -96,7 +96,7 @@ GET /audit_events/:id
| `id` | integer | yes | The ID of the audit event |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://primary.example.com/api/v4/audit_events/1
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://primary.example.com/api/v4/audit_events/1"
```
Example response:
@@ -122,7 +122,7 @@ Example response:
## Group Audit Events **(STARTER)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/34078) in GitLab 12.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34078) in GitLab 12.5.
The Group Audit Events API allows you to retrieve [group audit events](../administration/audit_events.md#group-events-starter).
@@ -146,7 +146,7 @@ are paginated.
Read more on [pagination](README.md#pagination).
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://primary.example.com/api/v4/groups/60/audit_events
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://primary.example.com/api/v4/groups/60/audit_events"
```
Example response:
@@ -202,7 +202,7 @@ GET /groups/:id/audit_events/:audit_event_id
| `audit_event_id` | integer | yes | The ID of the audit event |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://primary.example.com/api/v4/groups/60/audit_events/2
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://primary.example.com/api/v4/groups/60/audit_events/2"
```
Example response:
@@ -225,3 +225,115 @@ Example response:
"created_at": "2019-08-28T19:36:44.162Z"
}
```
+
+## Project Audit Events **(STARTER)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/219238) in GitLab 13.1.
+
+The Project Audit Events API allows you to retrieve [project audit events](../administration/audit_events.md#project-events-starter).
+
+To retrieve project audit events using the API, you must [authenticate yourself](README.md#authentication) as a Maintainer or an Owner of the project.
+
+### Retrieve all project audit events
+
+```plaintext
+GET /projects/:id/audit_events
+```
+
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) |
+| `created_after` | string | no | Return project audit events created on or after the given time. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ |
+| `created_before` | string | no | Return project audit events created on or before the given time. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ |
+
+By default, `GET` requests return 20 results at a time because the API results
+are paginated.
+
+Read more on [pagination](README.md#pagination).
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" https://primary.example.com/api/v4/projects/7/audit_events
+```
+
+Example response:
+
+```json
+[
+ {
+ "id": 5,
+ "author_id": 1,
+ "entity_id": 7,
+ "entity_type": "Project",
+ "details": {
+ "change": "prevent merge request approval from reviewers",
+ "from": "",
+ "to": "true",
+ "author_name": "Administrator",
+ "target_id": 7,
+ "target_type": "Project",
+ "target_details": "twitter/typeahead-js",
+ "ip_address": "127.0.0.1",
+ "entity_path": "twitter/typeahead-js"
+ },
+ "created_at": "2020-05-26T22:55:04.230Z"
+ },
+ {
+ "id": 4,
+ "author_id": 1,
+ "entity_id": 7,
+ "entity_type": "Project",
+ "details": {
+ "change": "prevent merge request approval from authors",
+ "from": "false",
+ "to": "true",
+ "author_name": "Administrator",
+ "target_id": 7,
+ "target_type": "Project",
+ "target_details": "twitter/typeahead-js",
+ "ip_address": "127.0.0.1",
+ "entity_path": "twitter/typeahead-js"
+ },
+ "created_at": "2020-05-26T22:55:04.218Z"
+ }
+]
+```
+
+### Retrieve a specific project audit event
+
+Only available to project maintainers or owners.
+
+```plaintext
+GET /projects/:id/audit_events/:audit_event_id
+```
+
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) |
+| `audit_event_id` | integer | yes | The ID of the audit event |
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" https://primary.example.com/api/v4/projects/7/audit_events/5
+```
+
+Example response:
+
+```json
+{
+ "id": 5,
+ "author_id": 1,
+ "entity_id": 7,
+ "entity_type": "Project",
+ "details": {
+ "change": "prevent merge request approval from reviewers",
+ "from": "",
+ "to": "true",
+ "author_name": "Administrator",
+ "target_id": 7,
+ "target_type": "Project",
+ "target_details": "twitter/typeahead-js",
+ "ip_address": "127.0.0.1",
+ "entity_path": "twitter/typeahead-js"
+ },
+ "created_at": "2020-05-26T22:55:04.230Z"
+}
+```
diff --git a/doc/api/avatar.md b/doc/api/avatar.md
index 308c0de25f4..223704d3e6c 100644
--- a/doc/api/avatar.md
+++ b/doc/api/avatar.md
@@ -29,7 +29,7 @@ Parameters:
Example request:
```shell
-curl https://gitlab.example.com/api/v4/avatar?email=admin@example.com&size=32
+curl "https://gitlab.example.com/api/v4/avatar?email=admin@example.com&size=32"
```
Example response:
diff --git a/doc/api/award_emoji.md b/doc/api/award_emoji.md
index 37b3cd32f89..6e8739df13c 100644
--- a/doc/api/award_emoji.md
+++ b/doc/api/award_emoji.md
@@ -1,3 +1,9 @@
+---
+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/#designated-technical-writers
+---
+
# Award Emoji API
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/4575) in GitLab 8.9. Snippet support added in 8.12.
@@ -36,7 +42,7 @@ Parameters:
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/issues/80/award_emoji
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/80/award_emoji"
```
Example response:
@@ -99,7 +105,7 @@ Parameters:
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/issues/80/award_emoji/1
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/80/award_emoji/1"
```
Example response:
@@ -142,7 +148,7 @@ Parameters:
| `name` | string | yes | Name of the emoji without colons. |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/issues/80/award_emoji?name=blowfish
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/80/award_emoji?name=blowfish"
```
Example Response:
@@ -188,7 +194,7 @@ Parameters:
| `award_id` | integer | yes | ID of an award emoji. |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/issues/80/award_emoji/344
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/80/award_emoji/344"
```
## Award Emoji on Comments
@@ -219,7 +225,7 @@ Parameters:
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/issues/80/notes/1/award_emoji
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/80/notes/1/award_emoji"
```
Example response:
@@ -265,7 +271,7 @@ Parameters:
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/issues/80/notes/1/award_emoji/2
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/80/notes/1/award_emoji/2"
```
Example response:
@@ -309,7 +315,7 @@ Parameters:
Example request:
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/issues/80/notes/1/award_emoji?name=rocket
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/80/notes/1/award_emoji?name=rocket"
```
Example response:
@@ -356,5 +362,5 @@ Parameters:
Example request:
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/issues/80/award_emoji/345
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/80/award_emoji/345"
```
diff --git a/doc/api/boards.md b/doc/api/boards.md
index 8af23527931..155a876e76a 100644
--- a/doc/api/boards.md
+++ b/doc/api/boards.md
@@ -1,3 +1,9 @@
+---
+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/#designated-technical-writers
+---
+
# Issue Boards API
Every API call to boards must be authenticated.
@@ -18,7 +24,7 @@ GET /projects/:id/boards
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.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/boards
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/boards"
```
Example response:
@@ -50,7 +56,8 @@ Example response:
},
"position" : 1,
"max_issue_count": 0,
- "max_issue_weight": 0
+ "max_issue_weight": 0,
+ "limit_metric": null
},
{
"id" : 2,
@@ -61,7 +68,8 @@ Example response:
},
"position" : 2,
"max_issue_count": 0,
- "max_issue_weight": 0
+ "max_issue_weight": 0,
+ "limit_metric": null
},
{
"id" : 3,
@@ -72,7 +80,8 @@ Example response:
},
"position" : 3,
"max_issue_count": 0,
- "max_issue_weight": 0
+ "max_issue_weight": 0,
+ "limit_metric": null
}
]
}
@@ -93,7 +102,7 @@ GET /projects/:id/boards/:board_id
| `board_id` | integer | yes | The ID of a board |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/boards/1
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/boards/1"
```
Example response:
@@ -125,7 +134,8 @@ Example response:
},
"position" : 1,
"max_issue_count": 0,
- "max_issue_weight": 0
+ "max_issue_weight": 0,
+ "limit_metric": null
},
{
"id" : 2,
@@ -136,7 +146,8 @@ Example response:
},
"position" : 2,
"max_issue_count": 0,
- "max_issue_weight": 0
+ "max_issue_weight": 0,
+ "limit_metric": null
},
{
"id" : 3,
@@ -147,7 +158,8 @@ Example response:
},
"position" : 3,
"max_issue_count": 0,
- "max_issue_weight": 0
+ "max_issue_weight": 0,
+ "limit_metric": null
}
]
}
@@ -167,7 +179,7 @@ POST /projects/:id/boards
| `name` | string | yes | The name of the new board |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/boards?name=newboard
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/boards?name=newboard"
```
Example response:
@@ -199,7 +211,8 @@ Example response:
},
"position" : 1,
"max_issue_count": 0,
- "max_issue_weight": 0
+ "max_issue_weight": 0,
+ "limit_metric": null
},
{
"id" : 2,
@@ -210,7 +223,8 @@ Example response:
},
"position" : 2,
"max_issue_count": 0,
- "max_issue_weight": 0
+ "max_issue_weight": 0,
+ "limit_metric": null
},
{
"id" : 3,
@@ -221,7 +235,8 @@ Example response:
},
"position" : 3,
"max_issue_count": 0,
- "max_issue_weight": 0
+ "max_issue_weight": 0,
+ "limit_metric": null
}
]
}
@@ -248,7 +263,7 @@ PUT /projects/:id/boards/:board_id
| `weight` | integer | no | The weight range from 0 to 9, to which the board should be scoped to |
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/boards/1?name=new_name&milestone_id=43&assignee_id=1&labels=Doing&weight=4
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/boards/1?name=new_name&milestone_id=43&assignee_id=1&labels=Doing&weight=4"
```
Example response:
@@ -322,7 +337,7 @@ DELETE /projects/:id/boards/:board_id
| `board_id` | integer | yes | The ID of a board |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/boards/1
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/boards/1"
```
## List board lists
@@ -340,7 +355,7 @@ GET /projects/:id/boards/:board_id/lists
| `board_id` | integer | yes | The ID of a board |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/boards/1/lists
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/boards/1/lists"
```
Example response:
@@ -356,7 +371,8 @@ Example response:
},
"position" : 1,
"max_issue_count": 0,
- "max_issue_weight": 0
+ "max_issue_weight": 0,
+ "limit_metric": null
},
{
"id" : 2,
@@ -367,7 +383,8 @@ Example response:
},
"position" : 2,
"max_issue_count": 0,
- "max_issue_weight": 0
+ "max_issue_weight": 0,
+ "limit_metric": null
},
{
"id" : 3,
@@ -378,7 +395,8 @@ Example response:
},
"position" : 3,
"max_issue_count": 0,
- "max_issue_weight": 0
+ "max_issue_weight": 0,
+ "limit_metric": null
}
]
```
@@ -398,7 +416,7 @@ GET /projects/:id/boards/:board_id/lists/:list_id
| `list_id`| integer | yes | The ID of a board's list |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/boards/1/lists/1
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/boards/1/lists/1"
```
Example response:
@@ -413,7 +431,8 @@ Example response:
},
"position" : 1,
"max_issue_count": 0,
- "max_issue_weight": 0
+ "max_issue_weight": 0,
+ "limit_metric": null
}
```
@@ -440,7 +459,7 @@ Check the [Issue Board docs](../user/project/issue_board.md#summary-of-features-
for more information regarding the required license for each list type.
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/boards/1/lists?label_id=5
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/boards/1/lists?label_id=5"
```
Example response:
@@ -455,7 +474,8 @@ Example response:
},
"position" : 1,
"max_issue_count": 0,
- "max_issue_weight": 0
+ "max_issue_weight": 0,
+ "limit_metric": null
}
```
@@ -475,7 +495,7 @@ PUT /projects/:id/boards/:board_id/lists/:list_id
| `position` | integer | yes | The position of the list |
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/boards/1/lists/1?position=2
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/boards/1/lists/1?position=2"
```
Example response:
@@ -490,7 +510,8 @@ Example response:
},
"position" : 1,
"max_issue_count": 0,
- "max_issue_weight": 0
+ "max_issue_weight": 0,
+ "limit_metric": null
}
```
@@ -509,5 +530,5 @@ DELETE /projects/:id/boards/:board_id/lists/:list_id
| `list_id` | integer | yes | The ID of a board's list |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/boards/1/lists/1
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/boards/1/lists/1"
```
diff --git a/doc/api/branches.md b/doc/api/branches.md
index 7d14a3d54b9..7a64f62189e 100644
--- a/doc/api/branches.md
+++ b/doc/api/branches.md
@@ -26,7 +26,7 @@ Parameters:
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/repository/branches
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/repository/branches"
```
Example response:
@@ -83,7 +83,7 @@ Parameters:
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/repository/branches/master
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/repository/branches/master"
```
Example response:
@@ -145,7 +145,7 @@ Parameters:
Example request:
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/repository/branches?branch=newbranch&ref=master
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/repository/branches?branch=newbranch&ref=master"
```
Example response:
@@ -199,7 +199,7 @@ Parameters:
Example request:
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/repository/branches/newbranch
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/repository/branches/newbranch"
```
## Delete merged branches
@@ -222,5 +222,5 @@ Parameters:
Example request:
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/repository/merged_branches
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/repository/merged_branches"
```
diff --git a/doc/api/broadcast_messages.md b/doc/api/broadcast_messages.md
index db2198dc162..37156186d03 100644
--- a/doc/api/broadcast_messages.md
+++ b/doc/api/broadcast_messages.md
@@ -20,7 +20,7 @@ GET /broadcast_messages
Example request:
```shell
-curl https://gitlab.example.com/api/v4/broadcast_messages
+curl "https://gitlab.example.com/api/v4/broadcast_messages"
```
Example response:
@@ -59,7 +59,7 @@ Parameters:
Example request:
```shell
-curl https://gitlab.example.com/api/v4/broadcast_messages/1
+curl "https://gitlab.example.com/api/v4/broadcast_messages/1"
```
Example response:
@@ -103,7 +103,7 @@ Parameters:
Example request:
```shell
-curl --data "message=Deploy in progress&color=#cecece" --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/broadcast_messages
+curl --data "message=Deploy in progress&color=#cecece" --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/broadcast_messages"
```
Example response:
@@ -148,7 +148,7 @@ Parameters:
Example request:
```shell
-curl --request PUT --data "message=Update message&color=#000" --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/broadcast_messages/1
+curl --request PUT --data "message=Update message&color=#000" --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/broadcast_messages/1"
```
Example response:
@@ -185,5 +185,5 @@ Parameters:
Example request:
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/broadcast_messages/1
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/broadcast_messages/1"
```
diff --git a/doc/api/commits.md b/doc/api/commits.md
index 98a8e4ea2ce..9be4ce4fcdb 100644
--- a/doc/api/commits.md
+++ b/doc/api/commits.md
@@ -132,7 +132,7 @@ PAYLOAD=$(cat << 'JSON'
}
JSON
)
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --header "Content-Type: application/json" --data "$PAYLOAD" https://gitlab.example.com/api/v4/projects/1/repository/commits
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --header "Content-Type: application/json" --data "$PAYLOAD" "https://gitlab.example.com/api/v4/projects/1/repository/commits"
```
Example response:
@@ -206,7 +206,7 @@ Parameters:
| `stats` | boolean | no | Include commit stats. Default is true |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/repository/commits/master
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/repository/commits/master"
```
Example response:
@@ -498,7 +498,7 @@ POST /projects/:id/repository/commits/:sha/comments
| `line_type` | string | no | The line type. Takes `new` or `old` as arguments |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form "note=Nice picture man\!" --form "path=dudeism.md" --form "line=11" --form "line_type=new" https://gitlab.example.com/api/v4/projects/17/repository/commits/18f3e63d05582537db6d183d9d557be09e1f90c8/comments
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form "note=Nice picture man\!" --form "path=dudeism.md" --form "line=11" --form "line_type=new" "https://gitlab.example.com/api/v4/projects/17/repository/commits/18f3e63d05582537db6d183d9d557be09e1f90c8/comments"
```
Example response:
diff --git a/doc/api/container_registry.md b/doc/api/container_registry.md
index 9ec4373c92c..d4a4fc1a733 100644
--- a/doc/api/container_registry.md
+++ b/doc/api/container_registry.md
@@ -1,6 +1,6 @@
# Container Registry API
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/55978) in GitLab 11.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/55978) in GitLab 11.8.
This is the API docs of the [GitLab Container Registry](../user/packages/container_registry/index.md).
@@ -19,6 +19,7 @@ GET /projects/:id/registry/repositories
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) accessible by the authenticated user. |
| `tags` | boolean | no | If the parameter is included as true, each repository will include an array of `"tags"` in the response. |
| `name` | string | no | Returns a list of repositories with a name that matches the value. ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29763) in GitLab 13.0). |
+| `tags_count` | boolean | no | If the parameter is included as true, each repository will include `"tags_count"` in the response ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/32141) in GitLab 13.1). |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/registry/repositories"
@@ -60,9 +61,10 @@ GET /groups/:id/registry/repositories
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) accessible by the authenticated user. |
| `tags` | boolean | no | If the parameter is included as true, each repository will include an array of `"tags"` in the response. |
| `name` | string | no | Returns a list of repositories with a name that matches the value. ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29763) in GitLab 13.0). |
+| `tags_count` | boolean | no | If the parameter is included as true, each repository will include `"tags_count"` in the response ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/32141) in GitLab 13.1). |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/2/registry/repositories?tags=1"
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/2/registry/repositories?tags=1&tags_count=true"
```
Example response:
@@ -76,6 +78,7 @@ Example response:
"project_id": 9,
"location": "gitlab.example.com:5000/group/project",
"created_at": "2019-01-10T13:38:57.391Z",
+ "tags_count": 1,
"tags": [
{
"name": "0.0.1",
@@ -91,6 +94,7 @@ Example response:
"project_id": 11,
"location": "gitlab.example.com:5000/group/other_project",
"created_at": "2019-01-10T13:39:08.229Z",
+ "tags_count": 3,
"tags": [
{
"name": "0.0.1",
@@ -236,9 +240,9 @@ DELETE /projects/:id/registry/repositories/:repository_id/tags
| --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user. |
| `repository_id` | integer | yes | The ID of registry repository. |
-| `name_regex` | string | no | The [re2](https://github.com/google/re2/wiki/Syntax) regex of the name to delete. To delete all tags specify `.*`. **Note:** `name_regex` is deprecated in favor of `name_regex_delete`.|
-| `name_regex_delete` | string | yes | The [re2](https://github.com/google/re2/wiki/Syntax) regex of the name to delete. To delete all tags specify `.*`.|
-| `name_regex_keep` | string | no | The [re2](https://github.com/google/re2/wiki/Syntax) regex of the name to keep. This value will override any matches from `name_regex_delete`. Note: setting to `.*` will result in a no-op. |
+| `name_regex` | string | no | The [re2](https://github.com/google/re2/wiki/Syntax) regex of the name to delete. To delete all tags specify `.*`. **Note:** `name_regex` is deprecated in favor of `name_regex_delete`. This field is validated. |
+| `name_regex_delete` | string | yes | The [re2](https://github.com/google/re2/wiki/Syntax) regex of the name to delete. To delete all tags specify `.*`. This field is validated. |
+| `name_regex_keep` | string | no | The [re2](https://github.com/google/re2/wiki/Syntax) regex of the name to keep. This value will override any matches from `name_regex_delete`. This field is validated. Note: setting to `.*` will result in a no-op. |
| `keep_n` | integer | no | The amount of latest tags of given name to keep. |
| `older_than` | string | no | Tags to delete that are older than the given time, written in human readable form `1h`, `1d`, `1month`. |
@@ -260,7 +264,7 @@ This action does not delete blobs. In order to delete them and recycle disk spac
NOTE: **Note:**
Since GitLab 12.4, individual tags are deleted.
-For more details, see the [discussion](https://gitlab.com/gitlab-org/gitlab/issues/15737).
+For more details, see the [discussion](https://gitlab.com/gitlab-org/gitlab/-/issues/15737).
Examples:
diff --git a/doc/api/custom_attributes.md b/doc/api/custom_attributes.md
index 20b364993ae..07ece99f9b1 100644
--- a/doc/api/custom_attributes.md
+++ b/doc/api/custom_attributes.md
@@ -20,7 +20,7 @@ GET /projects/:id/custom_attributes
| `id` | integer | yes | The ID of a resource |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/users/42/custom_attributes
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/users/42/custom_attributes"
```
Example response:
@@ -54,7 +54,7 @@ GET /projects/:id/custom_attributes/:key
| `key` | string | yes | The key of the custom attribute |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/users/42/custom_attributes/location
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/users/42/custom_attributes/location"
```
Example response:
@@ -84,7 +84,7 @@ PUT /projects/:id/custom_attributes/:key
| `value` | string | yes | The value of the custom attribute |
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" --data "value=Greenland" https://gitlab.example.com/api/v4/users/42/custom_attributes/location
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" --data "value=Greenland" "https://gitlab.example.com/api/v4/users/42/custom_attributes/location"
```
Example response:
@@ -112,5 +112,5 @@ DELETE /projects/:id/custom_attributes/:key
| `key` | string | yes | The key of the custom attribute |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/users/42/custom_attributes/location
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/users/42/custom_attributes/location"
```
diff --git a/doc/api/dependencies.md b/doc/api/dependencies.md
index bb7e5ae238d..56d33bf151a 100644
--- a/doc/api/dependencies.md
+++ b/doc/api/dependencies.md
@@ -28,7 +28,7 @@ GET /projects/:id/dependencies?package_manager=yarn,bundler
| `package_manager` | string array | no | Returns dependencies belonging to specified package manager. Valid values: `bundler`, `composer`, `maven`, `npm`, `pip` or `yarn`. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/4/dependencies
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/4/dependencies"
```
Example response:
diff --git a/doc/api/deploy_keys.md b/doc/api/deploy_keys.md
index a7acc0c2b55..1634d07768a 100644
--- a/doc/api/deploy_keys.md
+++ b/doc/api/deploy_keys.md
@@ -185,7 +185,7 @@ curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://git
Enables a deploy key for a project so this can be used. Returns the enabled key, with a status code 201 when successful.
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/deploy_keys/13/enable
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/deploy_keys/13/enable"
```
| Attribute | Type | Required | Description |
@@ -213,19 +213,19 @@ First, find the ID of the projects you're interested in, by either listing all
projects:
```shell
-curl --header 'PRIVATE-TOKEN: <your_access_token>' https://gitlab.example.com/api/v4/projects
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects"
```
Or finding the ID of a group:
```shell
-curl --header 'PRIVATE-TOKEN: <your_access_token>' https://gitlab.example.com/api/v4/groups
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups"
```
Then listing all projects in that group (for example, group 1234):
```shell
-curl --header 'PRIVATE-TOKEN: <your_access_token>' https://gitlab.example.com/api/v4/groups/1234
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1234"
```
With those IDs, add the same deploy key to all:
@@ -233,6 +233,6 @@ With those IDs, add the same deploy key to all:
```shell
for project_id in 321 456 987; do
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --header "Content-Type: application/json" \
- --data '{"title": "my key", "key": "ssh-rsa AAAA..."}' https://gitlab.example.com/api/v4/projects/${project_id}/deploy_keys
+ --data '{"title": "my key", "key": "ssh-rsa AAAA..."}' "https://gitlab.example.com/api/v4/projects/${project_id}/deploy_keys"
done
```
diff --git a/doc/api/deploy_tokens.md b/doc/api/deploy_tokens.md
index 6e732a43da0..bfef61dbda8 100644
--- a/doc/api/deploy_tokens.md
+++ b/doc/api/deploy_tokens.md
@@ -2,7 +2,7 @@
## List all deploy tokens
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/21811) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/21811) in GitLab 12.9.
Get a list of all deploy tokens across the GitLab instance. This endpoint requires admin access.
@@ -39,7 +39,7 @@ Project deploy token API endpoints require project maintainer access or higher.
### List project deploy tokens
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/21811) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/21811) in GitLab 12.9.
Get a list of a project's deploy tokens.
@@ -78,7 +78,7 @@ Example response:
### Create a project deploy token
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/21811) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/21811) in GitLab 12.9.
Creates a new deploy token for a project.
@@ -115,7 +115,7 @@ Example response:
### Delete a project deploy token
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/21811) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/21811) in GitLab 12.9.
Removes a deploy token from the project.
@@ -140,7 +140,7 @@ These endpoints require group maintainer access or higher.
### List group deploy tokens
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/21811) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/21811) in GitLab 12.9.
Get a list of a group's deploy tokens
@@ -179,7 +179,7 @@ Example response:
### Create a group deploy token
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/21811) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/21811) in GitLab 12.9.
Creates a new deploy token for a group.
@@ -218,7 +218,7 @@ Example response:
### Delete a group deploy token
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/21811) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/21811) in GitLab 12.9.
Removes a deploy token from the group.
diff --git a/doc/api/deployments.md b/doc/api/deployments.md
index 250c63a8520..8c952ba07b1 100644
--- a/doc/api/deployments.md
+++ b/doc/api/deployments.md
@@ -364,7 +364,7 @@ Example of a response:
## List of merge requests associated with a deployment
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/35739) in GitLab 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35739) in GitLab 12.7.
This API retrieves the list of merge requests shipped with a given deployment:
diff --git a/doc/api/discussions.md b/doc/api/discussions.md
index 572e174201d..1f509a7aadc 100644
--- a/doc/api/discussions.md
+++ b/doc/api/discussions.md
@@ -1,3 +1,9 @@
+---
+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/#designated-technical-writers
+---
+
# Discussions API
Discussions are a set of related notes on:
@@ -111,7 +117,7 @@ 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
@@ -131,7 +137,7 @@ 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/6a9c1750b37d513a43987b574953fceb50b03ce7"
```
### Create new issue thread
@@ -152,7 +158,7 @@ Parameters:
| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin 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
@@ -178,7 +184,7 @@ Parameters:
| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin 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/6a9c1750b37d513a43987b574953fceb50b03ce7/notes?body=comment"
```
### Modify existing issue thread note
@@ -200,7 +206,7 @@ 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/6a9c1750b37d513a43987b574953fceb50b03ce7/notes/1108?body=comment"
```
### Delete an issue thread note
@@ -221,7 +227,7 @@ 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
@@ -319,7 +325,7 @@ 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
@@ -339,7 +345,7 @@ 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/6a9c1750b37d513a43987b574953fceb50b03ce7"
```
### Create new snippet thread
@@ -361,7 +367,7 @@ Parameters:
| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin 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
@@ -384,7 +390,7 @@ Parameters:
| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin 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/6a9c1750b37d513a43987b574953fceb50b03ce7/notes?body=comment"
```
### Modify existing snippet thread note
@@ -406,7 +412,7 @@ 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/6a9c1750b37d513a43987b574953fceb50b03ce7/notes/1108?body=comment"
```
### Delete a snippet thread note
@@ -427,7 +433,7 @@ 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)**
@@ -526,7 +532,7 @@ 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
@@ -546,7 +552,7 @@ 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/6a9c1750b37d513a43987b574953fceb50b03ce7"
```
### Create new epic thread
@@ -568,7 +574,7 @@ Parameters:
| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin 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
@@ -592,7 +598,7 @@ Parameters:
| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin 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/6a9c1750b37d513a43987b574953fceb50b03ce7/notes?body=comment"
```
### Modify existing epic thread note
@@ -614,7 +620,7 @@ 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/6a9c1750b37d513a43987b574953fceb50b03ce7/notes/1108?body=comment"
```
### Delete an epic thread note
@@ -635,7 +641,7 @@ 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
@@ -777,7 +783,9 @@ Diff comments also contain position:
"new_line": 27,
"line_range": {
"start_line_code": "588440f66559714280628a4f9799f0c4eb880a4a_10_10",
- "end_line_code": "588440f66559714280628a4f9799f0c4eb880a4a_11_11"
+ "start_line_type": "new",
+ "end_line_code": "588440f66559714280628a4f9799f0c4eb880a4a_11_11",
+ "end_line_type": "old"
}
},
"resolved": false,
@@ -790,7 +798,7 @@ 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
@@ -810,7 +818,7 @@ 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/6a9c1750b37d513a43987b574953fceb50b03ce7
```
### Create new merge request thread
@@ -842,13 +850,15 @@ Parameters:
| `position[line_range]` | hash | no | Line range for a multi-line diff note |
| `position[line_range][start_line_code]` | string | yes | Line code for the start line |
| `position[line_range][end_line_code]` | string | yes | Line code for the end line |
+| `position[line_range][start_line_type]` | string | yes | Line type for the start line |
+| `position[line_range][end_line_type]` | string | yes | Line type for the end line |
| `position[width]` | integer | no | Width of the image (for 'image' diff notes) |
| `position[height]` | integer | no | Height of the image (for 'image' diff notes) |
| `position[x]` | integer | no | X coordinate (for 'image' diff notes) |
| `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/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"
```
### Resolve a merge request thread
@@ -869,7 +879,7 @@ 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/6a9c1750b37d513a43987b574953fceb50b03ce7?resolved=true"
```
### Add note to existing merge request thread
@@ -893,7 +903,7 @@ Parameters:
| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin 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/6a9c1750b37d513a43987b574953fceb50b03ce7/notes?body=comment"
```
### Modify an existing merge request thread note
@@ -916,13 +926,13 @@ 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/6a9c1750b37d513a43987b574953fceb50b03ce7/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/6a9c1750b37d513a43987b574953fceb50b03ce7/notes/1108?resolved=true"
```
### Delete a merge request thread note
@@ -943,7 +953,7 @@ 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
@@ -1086,7 +1096,7 @@ 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
@@ -1106,7 +1116,7 @@ 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/6a9c1750b37d513a43987b574953fceb50b03ce7"
```
### Create new commit thread
@@ -1141,7 +1151,7 @@ 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"
```
### Add note to existing commit thread
@@ -1164,7 +1174,7 @@ Parameters:
| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin 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/6a9c1750b37d513a43987b574953fceb50b03ce7/notes?body=comment
```
### Modify an existing commit thread note
@@ -1186,13 +1196,13 @@ 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/6a9c1750b37d513a43987b574953fceb50b03ce7/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/6a9c1750b37d513a43987b574953fceb50b03ce7/notes/1108?resolved=true"
```
### Delete a commit thread note
@@ -1213,5 +1223,5 @@ 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/environments.md b/doc/api/environments.md
index ffaff5f4f1e..5f6bdc251ba 100644
--- a/doc/api/environments.md
+++ b/doc/api/environments.md
@@ -15,7 +15,7 @@ GET /projects/:id/environments
| `search` | string | no | Return list of environments matching the search criteria. Mutually exclusive with `name` |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/environments?name=review%2Ffix-foo
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/environments?name=review%2Ffix-foo"
```
Example response:
@@ -141,7 +141,7 @@ Example of response
## Create a new environment
-Creates a new environment with the given name and external_url.
+Creates a new environment with the given name and `external_url`.
It returns `201` if the environment was successfully created, `400` for wrong parameters.
@@ -173,7 +173,7 @@ Example response:
## Edit an existing environment
-Updates an existing environment's name and/or external_url.
+Updates an existing environment's name and/or `external_url`.
It returns `200` if the environment was successfully updated. In case of an error, a status code `400` is returned.
@@ -186,7 +186,7 @@ PUT /projects/:id/environments/:environments_id
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.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 |
-| `external_url` | string | no | The new external_url |
+| `external_url` | string | no | The new `external_url` |
```shell
curl --request PUT --data "name=staging&external_url=https://staging.example.gitlab.com" --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/environments/1"
diff --git a/doc/api/epic_issues.md b/doc/api/epic_issues.md
index b001749ff5b..86f88b0322f 100644
--- a/doc/api/epic_issues.md
+++ b/doc/api/epic_issues.md
@@ -1,3 +1,9 @@
+---
+stage: Plan
+group: Portfolio 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/#designated-technical-writers
+---
+
# Epic Issues API **(ULTIMATE)**
Every API call to epic_issues must be authenticated.
@@ -20,7 +26,7 @@ GET /groups/:id/epics/:epic_iid/issues
| `epic_iid` | integer/string | yes | The internal ID of the epic. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/1/epics/5/issues/
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/epics/5/issues/"
```
Example response:
@@ -117,7 +123,7 @@ POST /groups/:id/epics/:epic_iid/issues/:issue_id
| `issue_id` | integer/string | yes | The ID of the issue. |
```shell
-curl --header POST "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/1/epics/5/issues/55
+curl --header POST "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/epics/5/issues/55"
```
Example response:
@@ -223,7 +229,7 @@ DELETE /groups/:id/epics/:epic_iid/issues/:epic_issue_id
| `epic_issue_id` | integer/string | yes | The ID of the issue - epic association. |
```shell
-curl --header DELETE "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/1/epics/5/issues/11
+curl --header DELETE "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/epics/5/issues/11"
```
Example response:
@@ -331,7 +337,7 @@ PUT /groups/:id/epics/:epic_iid/issues/:epic_issue_id
| `move_after_id` | integer/string | no | The ID of the issue - epic association that should be placed after the link in the question. |
```shell
-curl --header PUT "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/1/epics/5/issues/11?move_before_id=20
+curl --header PUT "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/epics/5/issues/11?move_before_id=20"
```
Example response:
diff --git a/doc/api/epic_links.md b/doc/api/epic_links.md
index 4f45fbde9e7..756a41a0680 100644
--- a/doc/api/epic_links.md
+++ b/doc/api/epic_links.md
@@ -25,7 +25,7 @@ GET /groups/:id/epics/:epic_iid/epics
| `epic_iid` | integer | yes | The internal ID of the epic. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/1/epics/5/epics/
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/epics/5/epics/"
```
Example response:
@@ -80,7 +80,7 @@ POST /groups/:id/epics/:epic_iid/epics
| `child_epic_id` | integer | yes | The global ID of the child epic. Internal ID can't be used because they can conflict with epics from other groups. |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/1/epics/5/epics/6
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/epics/5/epics/6"
```
Example response:
@@ -133,7 +133,7 @@ POST /groups/:id/epics/:epic_iid/epics
| `title` | string | yes | The title of a newly created epic. |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/1/epics/5/epics?title=Newpic
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/epics/5/epics?title=Newpic"
```
Example response:
@@ -168,7 +168,7 @@ PUT /groups/:id/epics/:epic_iid/epics/:child_epic_id
| `move_after_id` | integer | no | The global ID of a sibling epic that should be placed after the child epic. |
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/1/epics/4/epics/5
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/epics/4/epics/5"
```
Example response:
@@ -223,7 +223,7 @@ DELETE /groups/:id/epics/:epic_iid/epics/:child_epic_id
| `child_epic_id` | integer | yes | The global ID of the child epic. Internal ID can't be used because they can conflict with epics from other groups. |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/1/epics/4/epics/5
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/epics/4/epics/5"
```
Example response:
diff --git a/doc/api/epics.md b/doc/api/epics.md
index 6ca6f04b741..a420ef4cd15 100644
--- a/doc/api/epics.md
+++ b/doc/api/epics.md
@@ -1,7 +1,13 @@
+---
+stage: Plan
+group: Portfolio 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/#designated-technical-writers
+---
+
# Epics API **(PREMIUM)**
> - Introduced in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.2.
-> - Single-level Epics [were moved](https://gitlab.com/gitlab-org/gitlab/issues/37081) to [GitLab Premium](https://about.gitlab.com/pricing/) in 12.8.
+> - Single-level Epics [were moved](https://gitlab.com/gitlab-org/gitlab/-/issues/37081) to [GitLab Premium](https://about.gitlab.com/pricing/) in 12.8.
Every API call to epic must be authenticated.
@@ -70,7 +76,7 @@ GET /groups/:id/epics?state=opened
| `my_reaction_emoji` | string | no | Return epics reacted by the authenticated user by the given emoji. `None` returns epics not given a reaction. `Any` returns epics given at least one reaction. Introduced in [GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31479)|
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/1/epics
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/epics"
```
Example response:
@@ -177,7 +183,7 @@ GET /groups/:id/epics/:epic_iid
| `epic_iid` | integer/string | yes | The internal ID of the epic. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/1/epics/5
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/epics/5"
```
Example response:
@@ -253,7 +259,7 @@ POST /groups/:id/epics
| `parent_id` | integer/string | no | The ID of a parent epic (since 11.11) |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/1/epics?title=Epic&description=Epic%20description
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/epics?title=Epic&description=Epic%20description"
```
Example response:
@@ -330,7 +336,7 @@ PUT /groups/:id/epics/:epic_iid
| `state_event` | string | no | State event for an epic. Set `close` to close the epic and `reopen` to reopen it (since 11.4) |
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/1/epics/5?title=New%20Title
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/epics/5?title=New%20Title"
```
Example response:
@@ -393,7 +399,7 @@ DELETE /groups/:id/epics/:epic_iid
| `epic_iid` | integer/string | yes | The internal ID of the epic. |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/1/epics/5
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/epics/5"
```
## Create a todo
@@ -412,7 +418,7 @@ POST /groups/:id/epics/:epic_iid/todo
| `epic_iid` | integer | yes | The internal ID of a group's epic |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/1/epics/5/todo
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/epics/5/todo"
```
Example response:
diff --git a/doc/api/error_tracking.md b/doc/api/error_tracking.md
index f44266aa552..e18fbaf25c3 100644
--- a/doc/api/error_tracking.md
+++ b/doc/api/error_tracking.md
@@ -1,6 +1,6 @@
# Error Tracking settings API
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/34940) in GitLab 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34940) in GitLab 12.7.
## Error Tracking project settings
@@ -17,7 +17,7 @@ GET /projects/:id/error_tracking/settings
| `id` | integer | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/error_tracking/settings
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/error_tracking/settings"
```
Example response:
@@ -45,7 +45,7 @@ PATCH /projects/:id/error_tracking/settings
| `active` | boolean | yes | Pass `true` to enable the already configured error tracking settings or `false` to disable it. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/error_tracking/settings?active=true
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/error_tracking/settings?active=true"
```
Example response:
diff --git a/doc/api/events.md b/doc/api/events.md
index e6cb56f1339..99bb6d5af2b 100644
--- a/doc/api/events.md
+++ b/doc/api/events.md
@@ -72,7 +72,7 @@ Parameters:
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/events?target_type=issue&action=created&after=2017-01-31&before=2017-03-01&scope=all
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/events?target_type=issue&action=created&after=2017-01-31&before=2017-03-01&scope=all"
```
Example response:
@@ -144,7 +144,7 @@ Parameters:
| `sort` | string | no | Sort events in `asc` or `desc` order by `created_at`. Default is `desc` |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/users/:id/events
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/users/:id/events"
```
Example response:
@@ -277,7 +277,7 @@ Parameters:
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:project_id/events?target_type=issue&action=created&after=2017-01-31&before=2017-03-01
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:project_id/events?target_type=issue&action=created&after=2017-01-31&before=2017-03-01"
```
Example response:
diff --git a/doc/api/feature_flag_specs.md b/doc/api/feature_flag_specs.md
index fbe99826b27..52a4864fdc5 100644
--- a/doc/api/feature_flag_specs.md
+++ b/doc/api/feature_flag_specs.md
@@ -1,8 +1,17 @@
+---
+stage: Release
+group: Progressive Delivery
+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
+---
+
# 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 Premium](https://about.gitlab.com/pricing/) 12.5.
+
+CAUTION: **Deprecation**
+This API is deprecated and [scheduled for removal in GitLab 14.0](https://gitlab.com/gitlab-org/gitlab/-/issues/213369).
-The API for creating, updating, reading and deleting [Feature Flag Specs](../user/project/operations/feature_flags.md#define-environment-specs).
+The API for creating, updating, reading and deleting Feature Flag Specs.
Automation engineers benefit from this API by being able to modify Feature Flag Specs without accessing user interface.
To manage the [Feature Flag](../user/project/operations/feature_flags.md) resources via public API, please refer to the [Feature Flags API](feature_flags.md) document.
@@ -26,7 +35,7 @@ GET /projects/:id/feature_flag_scopes
| `environment` | string | yes | The [environment](../ci/environments/index.md) name |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/feature_flag_scopes?environment=production
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/feature_flag_scopes?environment=production"
```
Example response:
@@ -94,7 +103,7 @@ GET /projects/:id/feature_flags/:name/scopes
| `name` | string | yes | The name of the feature flag. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/feature_flags/new_live_trace/scopes
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/feature_flags/new_live_trace/scopes"
```
Example response:
@@ -160,7 +169,7 @@ POST /projects/:id/feature_flags/:name/scopes
| `strategies` | json | yes | The [strategies](../user/project/operations/feature_flags.md#feature-flag-strategies) of the feature flag spec. |
```shell
-curl https://gitlab.example.com/api/v4/projects/1/feature_flags/new_live_trace/scopes \
+curl "https://gitlab.example.com/api/v4/projects/1/feature_flags/new_live_trace/scopes" \
--header "PRIVATE-TOKEN: <your_access_token>" \
--header "Content-type: application/json" \
--data @- << EOF
@@ -205,7 +214,7 @@ GET /projects/:id/feature_flags/:name/scopes/:environment_scope
| `environment_scope` | string | yes | The URL-encoded [environment spec](../ci/environments/index.md#scoping-environments-with-specs) of the feature flag. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:id/feature_flags/new_live_trace/scopes/production
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/feature_flags/new_live_trace/scopes/production"
```
Example response:
@@ -243,7 +252,7 @@ PUT /projects/:id/feature_flags/:name/scopes/:environment_scope
| `strategies` | json | yes | The [strategies](../user/project/operations/feature_flags.md#feature-flag-strategies) of the feature flag spec. |
```shell
-curl https://gitlab.example.com/api/v4/projects/1/feature_flags/new_live_trace/scopes/production \
+curl "https://gitlab.example.com/api/v4/projects/1/feature_flags/new_live_trace/scopes/production" \
--header "PRIVATE-TOKEN: <your_access_token>" \
--header "Content-type: application/json" \
--data @- << EOF
@@ -287,5 +296,5 @@ DELETE /projects/:id/feature_flags/:name/scopes/:environment_scope
| `environment_scope` | string | yes | The URL-encoded [environment spec](../ci/environments/index.md#scoping-environments-with-specs) of the feature flag. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" --request DELETE https://gitlab.example.com/api/v4/projects/1/feature_flags/new_live_trace/scopes/production
+curl --header "PRIVATE-TOKEN: <your_access_token>" --request DELETE "https://gitlab.example.com/api/v4/projects/1/feature_flags/new_live_trace/scopes/production"
```
diff --git a/doc/api/feature_flag_user_lists.md b/doc/api/feature_flag_user_lists.md
index 04cad8f2d1d..460f3727819 100644
--- a/doc/api/feature_flag_user_lists.md
+++ b/doc/api/feature_flag_user_lists.md
@@ -1,3 +1,9 @@
+---
+stage: Release
+group: Progressive Delivery
+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
+---
+
# Feature flag user lists API **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/205409) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.10.
@@ -23,7 +29,7 @@ GET /projects/:id/feature_flags_user_lists
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/feature_flags_user_lists
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/feature_flags_user_lists"
```
Example response:
@@ -66,7 +72,7 @@ POST /projects/:id/feature_flags_user_lists
| `user_xids` | string | yes | A comma separated list of user IDs. |
```shell
-curl https://gitlab.example.com/api/v4/projects/1/feature_flags_user_lists \
+curl "https://gitlab.example.com/api/v4/projects/1/feature_flags_user_lists" \
--header "PRIVATE-TOKEN: <your_access_token>" \
--header "Content-type: application/json" \
--data @- << EOF
@@ -105,7 +111,7 @@ GET /projects/:id/feature_flags_user_lists/:iid
| `iid` | integer/string | yes | The internal ID of the project's feature flag user list. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/feature_flags_user_lists/1
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/feature_flags_user_lists/1"
```
Example response:
@@ -138,7 +144,7 @@ PUT /projects/:id/feature_flags_user_lists/:iid
| `user_xids` | string | no | A comma separated list of user IDs. |
```shell
-curl https://gitlab.example.com/api/v4/projects/1/feature_flags_user_lists/1 \
+curl "https://gitlab.example.com/api/v4/projects/1/feature_flags_user_lists/1" \
--header "PRIVATE-TOKEN: <your_access_token>" \
--header "Content-type: application/json" \
--request PUT \
@@ -177,5 +183,5 @@ DELETE /projects/:id/feature_flags_user_lists/:iid
| `iid` | integer/string | yes | The internal ID of the project's feature flag user list |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" --request DELETE https://gitlab.example.com/api/v4/projects/1/feature_flags_user_lists/1
+curl --header "PRIVATE-TOKEN: <your_access_token>" --request DELETE "https://gitlab.example.com/api/v4/projects/1/feature_flags_user_lists/1"
```
diff --git a/doc/api/feature_flags.md b/doc/api/feature_flags.md
index 3e1b0e05298..f3af662c972 100644
--- a/doc/api/feature_flags.md
+++ b/doc/api/feature_flags.md
@@ -1,6 +1,15 @@
+---
+stage: Release
+group: Progressive Delivery
+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
+---
+
# Feature Flags 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 Premium](https://about.gitlab.com/pricing/) 12.5.
+
+NOTE: **Note**
+This API is behind a [feature flag](../user/project/operations/feature_flags.md#feature-flag-behavior-change-in-130). If this flag is not enabled in your environment, you can use the [legacy feature flags API](feature_flags_legacy.md).
API for accessing resources of [GitLab Feature Flags](../user/project/operations/feature_flags.md).
@@ -25,7 +34,7 @@ GET /projects/:id/feature_flags
| `scope` | string | no | The condition of feature flags, one of: `enabled`, `disabled`. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/feature_flags
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/feature_flags"
```
Example response:
@@ -35,113 +44,94 @@ Example response:
{
"name":"merge_train",
"description":"This feature is about merge train",
+ "version": "new_version_flag",
"created_at":"2019-11-04T08:13:51.423Z",
"updated_at":"2019-11-04T08:13:51.423Z",
- "scopes":[
- {
- "id":82,
- "active":false,
- "environment_scope":"*",
- "strategies":[
- {
- "name":"default",
- "parameters":{
-
- }
- }
- ],
- "created_at":"2019-11-04T08:13:51.425Z",
- "updated_at":"2019-11-04T08:13:51.425Z"
- },
- {
- "id":83,
- "active":true,
- "environment_scope":"review/*",
- "strategies":[
- {
- "name":"default",
- "parameters":{
-
- }
- }
- ],
- "created_at":"2019-11-04T08:13:51.427Z",
- "updated_at":"2019-11-04T08:13:51.427Z"
- },
- {
- "id":84,
- "active":false,
- "environment_scope":"production",
- "strategies":[
- {
- "name":"default",
- "parameters":{
-
- }
- }
- ],
- "created_at":"2019-11-04T08:13:51.428Z",
- "updated_at":"2019-11-04T08:13:51.428Z"
- }
+ "scopes":[],
+ "strategies": [
+ {
+ "id": 1,
+ "name": "userWithId",
+ "parameters": {
+ "userIds": "user1"
+ },
+ "scopes": [
+ {
+ "id": 1,
+ "environment_scope": "production"
+ }
+ ]
+ }
]
},
{
"name":"new_live_trace",
"description":"This is a new live trace feature",
+ "version": "new_version_flag",
"created_at":"2019-11-04T08:13:10.507Z",
"updated_at":"2019-11-04T08:13:10.507Z",
- "scopes":[
- {
- "id":79,
- "active":false,
- "environment_scope":"*",
- "strategies":[
- {
- "name":"default",
- "parameters":{
-
- }
- }
- ],
- "created_at":"2019-11-04T08:13:10.516Z",
- "updated_at":"2019-11-04T08:13:10.516Z"
- },
- {
- "id":80,
- "active":true,
- "environment_scope":"staging",
- "strategies":[
- {
- "name":"default",
- "parameters":{
-
- }
- }
- ],
- "created_at":"2019-11-04T08:13:10.525Z",
- "updated_at":"2019-11-04T08:13:10.525Z"
- },
- {
- "id":81,
- "active":false,
- "environment_scope":"production",
- "strategies":[
- {
- "name":"default",
- "parameters":{
-
- }
- }
- ],
- "created_at":"2019-11-04T08:13:10.527Z",
- "updated_at":"2019-11-04T08:13:10.527Z"
- }
+ "scopes":[]
+ "strategies": [
+ {
+ "id": 2,
+ "name": "default",
+ "parameters": {},
+ "scopes": [
+ {
+ "id": 2,
+ "environment_scope": "staging"
+ }
+ ]
+ }
]
}
]
```
-## New feature flag
+## Get a single feature flag
+
+Gets a single feature flag.
+
+```plaintext
+GET /projects/:id/feature_flags/:name
+```
+
+| Attribute | Type | Required | Description |
+| ------------------- | ---------------- | ---------- | ---------------------------------------------------------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). |
+| `name` | string | yes | The name of the feature flag. |
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/feature_flags/awesome_feature
+```
+
+Example response:
+
+```json
+{
+ "name": "awesome_feature",
+ "description": null,
+ "version": "new_version_flag",
+ "created_at": "2020-05-13T19:56:33.119Z",
+ "updated_at": "2020-05-13T19:56:33.119Z",
+ "scopes": [],
+ "strategies": [
+ {
+ "id": 36,
+ "name": "default",
+ "parameters": {},
+ "scopes": [
+ {
+ "id": 37,
+ "environment_scope": "production"
+ }
+ ]
+ }
+ ]
+}
+```
+
+## Create a feature flag
Creates a new feature flag.
@@ -152,22 +142,24 @@ POST /projects/:id/feature_flags
| Attribute | Type | Required | Description |
| ------------------- | ---------------- | ---------- | ---------------------------------------------------------------------------------------|
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). |
-| `name` | string | yes | The name of the feature flag. |
-| `description` | string | no | The description of the feature flag. |
-| `scopes` | JSON | no | The [feature flag specs](../user/project/operations/feature_flags.md#define-environment-specs) of the feature flag. |
-| `scopes:environment_scope` | string | no | The [environment spec](../ci/environments/index.md#scoping-environments-with-specs). |
-| `scopes:active` | boolean | no | Whether the spec is active. |
-| `scopes:strategies` | JSON | no | The [strategies](../user/project/operations/feature_flags.md#feature-flag-strategies) of the feature flag spec. |
+| `name` | string | yes | The name of the feature flag. |
+| `version` | string | yes | The version of the feature flag. Must be `new_version_flag`. Omit or set to `legacy_flag` to create a [Legacy Feature Flag](feature_flags_legacy.md). |
+| `description` | string | no | The description of the feature flag. |
+| `strategies` | JSON | no | The feature flag [strategies](../user/project/operations/feature_flags.md#feature-flag-strategies). |
+| `strategies:name` | JSON | no | The strategy name. |
+| `strategies:parameters` | JSON | no | The strategy parameters. |
+| `strategies:scopes` | JSON | no | The scopes for the strategy. |
+| `strategies:scopes:environment_scope` | string | no | The environment spec for the scope. |
```shell
-curl https://gitlab.example.com/api/v4/projects/1/feature_flags \
+curl "https://gitlab.example.com/api/v4/projects/1/feature_flags" \
--header "PRIVATE-TOKEN: <your_access_token>" \
--header "Content-type: application/json" \
--data @- << EOF
{
- "name": "awesome_feature",
- "scopes": [{ "environment_scope": "*", "active": false, "strategies": [{ "name": "default", "parameters": {} }] },
- { "environment_scope": "production", "active": true, "strategies": [{ "name": "userWithId", "parameters": { "userIds": "1,2,3" } }] }]
+ "name": "awesome_feature",
+ "version": "new_version_flag",
+ "strategies": [{ "name": "default", "parameters": {}, "scopes": [{ "environment_scope": "production" }] }]
}
EOF
```
@@ -176,121 +168,101 @@ Example response:
```json
{
- "name":"awesome_feature",
- "description":null,
- "created_at":"2019-11-04T08:32:27.288Z",
- "updated_at":"2019-11-04T08:32:27.288Z",
- "scopes":[
- {
- "id":85,
- "active":false,
- "environment_scope":"*",
- "strategies":[
- {
- "name":"default",
- "parameters":{
-
- }
- }
- ],
- "created_at":"2019-11-04T08:32:29.324Z",
- "updated_at":"2019-11-04T08:32:29.324Z"
- },
- {
- "id":86,
- "active":true,
- "environment_scope":"production",
- "strategies":[
- {
- "name":"userWithId",
- "parameters":{
- "userIds":"1,2,3"
- }
- }
- ],
- "created_at":"2019-11-04T08:32:29.328Z",
- "updated_at":"2019-11-04T08:32:29.328Z"
- }
- ]
+ "name": "awesome_feature",
+ "description": null,
+ "version": "new_version_flag",
+ "created_at": "2020-05-13T19:56:33.119Z",
+ "updated_at": "2020-05-13T19:56:33.119Z",
+ "scopes": [],
+ "strategies": [
+ {
+ "id": 36,
+ "name": "default",
+ "parameters": {},
+ "scopes": [
+ {
+ "id": 37,
+ "environment_scope": "production"
+ }
+ ]
+ }
+ ]
}
```
-## Single feature flag
+## Update a feature flag
-Gets a single feature flag.
+Updates a feature flag.
```plaintext
-GET /projects/:id/feature_flags/:name
+PUT /projects/:id/feature_flags/:name
```
| Attribute | Type | Required | Description |
| ------------------- | ---------------- | ---------- | ---------------------------------------------------------------------------------------|
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). |
-| `name` | string | yes | The name of the feature flag. |
+| `name` | string | yes | The name of the feature flag. |
+| `description` | string | no | The description of the feature flag. |
+| `strategies` | JSON | no | The feature flag [strategies](../user/project/operations/feature_flags.md#feature-flag-strategies). |
+| `strategies:id` | JSON | no | The feature flag strategy id. |
+| `strategies:name` | JSON | no | The strategy name. |
+| `strategies:parameters` | JSON | no | The strategy parameters. |
+| `strategies:scopes` | JSON | no | The scopes for the strategy. |
+| `strategies:scopes:id` | JSON | no | The scopes id. |
+| `strategies:scopes:environment_scope` | string | no | The environment spec for the scope. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/feature_flags/new_live_trace
+curl "https://gitlab.example.com/api/v4/projects/1/feature_flags/awesome_feature" \
+ --header "PRIVATE-TOKEN: <your_access_token>" \
+ --header "Content-type: application/json" \
+ --data @- << EOF
+{
+ "strategies": [{ "name": "gradualRolloutUserId", "parameters": { "groupId": "default", "percentage": "25" }, "scopes": [{ "environment_scope": "staging" }] }]
+}
+EOF
```
Example response:
```json
{
- "name":"new_live_trace",
- "description":"This is a new live trace feature",
- "created_at":"2019-11-04T08:13:10.507Z",
- "updated_at":"2019-11-04T08:13:10.507Z",
- "scopes":[
- {
- "id":79,
- "active":false,
- "environment_scope":"*",
- "strategies":[
- {
- "name":"default",
- "parameters":{
-
- }
- }
- ],
- "created_at":"2019-11-04T08:13:10.516Z",
- "updated_at":"2019-11-04T08:13:10.516Z"
- },
- {
- "id":80,
- "active":true,
- "environment_scope":"staging",
- "strategies":[
- {
- "name":"default",
- "parameters":{
-
- }
- }
- ],
- "created_at":"2019-11-04T08:13:10.525Z",
- "updated_at":"2019-11-04T08:13:10.525Z"
+ "name": "awesome_feature",
+ "description": null,
+ "version": "new_version_flag",
+ "created_at": "2020-05-13T20:10:32.891Z",
+ "updated_at": "2020-05-13T20:10:32.891Z",
+ "scopes": [],
+ "strategies": [
+ {
+ "id": 38,
+ "name": "gradualRolloutUserId",
+ "parameters": {
+ "groupId": "default",
+ "percentage": "25"
},
- {
- "id":81,
- "active":false,
- "environment_scope":"production",
- "strategies":[
- {
- "name":"default",
- "parameters":{
-
- }
- }
- ],
- "created_at":"2019-11-04T08:13:10.527Z",
- "updated_at":"2019-11-04T08:13:10.527Z"
- }
- ]
+ "scopes": [
+ {
+ "id": 40,
+ "environment_scope": "staging"
+ }
+ ]
+ },
+ {
+ "id": 37,
+ "name": "default",
+ "parameters": {},
+ "scopes": [
+ {
+ "id": 39,
+ "environment_scope": "production"
+ }
+ ]
+ }
+ ]
}
```
-## Delete feature flag
+## Delete a feature flag
Deletes a feature flag.
@@ -304,5 +276,5 @@ DELETE /projects/:id/feature_flags/:name
| `name` | string | yes | The name of the feature flag. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" --request DELETE https://gitlab.example.com/api/v4/projects/1/feature_flags/awesome_feature
+curl --header "PRIVATE-TOKEN: <your_access_token>" --request DELETE "https://gitlab.example.com/api/v4/projects/1/feature_flags/awesome_feature"
```
diff --git a/doc/api/feature_flags_legacy.md b/doc/api/feature_flags_legacy.md
new file mode 100644
index 00000000000..30bae9c5eeb
--- /dev/null
+++ b/doc/api/feature_flags_legacy.md
@@ -0,0 +1,317 @@
+---
+stage: Release
+group: Progressive Delivery
+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
+---
+
+# Legacy Feature Flags API **(PREMIUM)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9566) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.5.
+
+CAUTION: **Deprecation**
+This API is deprecated and [scheduled for removal in GitLab 14.0](https://gitlab.com/gitlab-org/gitlab/-/issues/213369). Use [this API](feature_flags.md) instead.
+
+API for accessing resources of [GitLab Feature Flags](../user/project/operations/feature_flags.md).
+
+Users with Developer or higher [permissions](../user/permissions.md) can access Feature Flag API.
+
+## Feature Flags pagination
+
+By default, `GET` requests return 20 results at a time because the API results
+are [paginated](README.md#pagination).
+
+## List feature flags for a project
+
+Gets all feature flags of the requested project.
+
+```plaintext
+GET /projects/:id/feature_flags
+```
+
+| Attribute | Type | Required | Description |
+| ------------------- | ---------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). |
+| `scope` | string | no | The condition of feature flags, one of: `enabled`, `disabled`. |
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/feature_flags
+```
+
+Example response:
+
+```json
+[
+ {
+ "name":"merge_train",
+ "description":"This feature is about merge train",
+ "created_at":"2019-11-04T08:13:51.423Z",
+ "updated_at":"2019-11-04T08:13:51.423Z",
+ "scopes":[
+ {
+ "id":82,
+ "active":false,
+ "environment_scope":"*",
+ "strategies":[
+ {
+ "name":"default",
+ "parameters":{
+
+ }
+ }
+ ],
+ "created_at":"2019-11-04T08:13:51.425Z",
+ "updated_at":"2019-11-04T08:13:51.425Z"
+ },
+ {
+ "id":83,
+ "active":true,
+ "environment_scope":"review/*",
+ "strategies":[
+ {
+ "name":"default",
+ "parameters":{
+
+ }
+ }
+ ],
+ "created_at":"2019-11-04T08:13:51.427Z",
+ "updated_at":"2019-11-04T08:13:51.427Z"
+ },
+ {
+ "id":84,
+ "active":false,
+ "environment_scope":"production",
+ "strategies":[
+ {
+ "name":"default",
+ "parameters":{
+
+ }
+ }
+ ],
+ "created_at":"2019-11-04T08:13:51.428Z",
+ "updated_at":"2019-11-04T08:13:51.428Z"
+ }
+ ]
+ },
+ {
+ "name":"new_live_trace",
+ "description":"This is a new live trace feature",
+ "created_at":"2019-11-04T08:13:10.507Z",
+ "updated_at":"2019-11-04T08:13:10.507Z",
+ "scopes":[
+ {
+ "id":79,
+ "active":false,
+ "environment_scope":"*",
+ "strategies":[
+ {
+ "name":"default",
+ "parameters":{
+
+ }
+ }
+ ],
+ "created_at":"2019-11-04T08:13:10.516Z",
+ "updated_at":"2019-11-04T08:13:10.516Z"
+ },
+ {
+ "id":80,
+ "active":true,
+ "environment_scope":"staging",
+ "strategies":[
+ {
+ "name":"default",
+ "parameters":{
+
+ }
+ }
+ ],
+ "created_at":"2019-11-04T08:13:10.525Z",
+ "updated_at":"2019-11-04T08:13:10.525Z"
+ },
+ {
+ "id":81,
+ "active":false,
+ "environment_scope":"production",
+ "strategies":[
+ {
+ "name":"default",
+ "parameters":{
+
+ }
+ }
+ ],
+ "created_at":"2019-11-04T08:13:10.527Z",
+ "updated_at":"2019-11-04T08:13:10.527Z"
+ }
+ ]
+ }
+]
+```
+
+## New feature flag
+
+Creates a new feature flag.
+
+```plaintext
+POST /projects/:id/feature_flags
+```
+
+| Attribute | Type | Required | Description |
+| ------------------- | ---------------- | ---------- | ---------------------------------------------------------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). |
+| `name` | string | yes | The name of the feature flag. |
+| `description` | string | no | The description of the feature flag. |
+| `scopes` | JSON | no | The feature flag specs of the feature flag. |
+| `scopes:environment_scope` | string | no | The environment spec. |
+| `scopes:active` | boolean | no | Whether the spec is active. |
+| `scopes:strategies` | JSON | no | The [strategies](../user/project/operations/feature_flags.md#feature-flag-strategies) of the feature flag spec. |
+
+```shell
+curl https://gitlab.example.com/api/v4/projects/1/feature_flags \
+ --header "PRIVATE-TOKEN: <your_access_token>" \
+ --header "Content-type: application/json" \
+ --data @- << EOF
+{
+ "name": "awesome_feature",
+ "scopes": [{ "environment_scope": "*", "active": false, "strategies": [{ "name": "default", "parameters": {} }] },
+ { "environment_scope": "production", "active": true, "strategies": [{ "name": "userWithId", "parameters": { "userIds": "1,2,3" } }] }]
+}
+EOF
+```
+
+Example response:
+
+```json
+{
+ "name":"awesome_feature",
+ "description":null,
+ "created_at":"2019-11-04T08:32:27.288Z",
+ "updated_at":"2019-11-04T08:32:27.288Z",
+ "scopes":[
+ {
+ "id":85,
+ "active":false,
+ "environment_scope":"*",
+ "strategies":[
+ {
+ "name":"default",
+ "parameters":{
+
+ }
+ }
+ ],
+ "created_at":"2019-11-04T08:32:29.324Z",
+ "updated_at":"2019-11-04T08:32:29.324Z"
+ },
+ {
+ "id":86,
+ "active":true,
+ "environment_scope":"production",
+ "strategies":[
+ {
+ "name":"userWithId",
+ "parameters":{
+ "userIds":"1,2,3"
+ }
+ }
+ ],
+ "created_at":"2019-11-04T08:32:29.328Z",
+ "updated_at":"2019-11-04T08:32:29.328Z"
+ }
+ ]
+}
+```
+
+## Single feature flag
+
+Gets a single feature flag.
+
+```plaintext
+GET /projects/:id/feature_flags/:name
+```
+
+| Attribute | Type | Required | Description |
+| ------------------- | ---------------- | ---------- | ---------------------------------------------------------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). |
+| `name` | string | yes | The name of the feature flag. |
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/feature_flags/new_live_trace
+```
+
+Example response:
+
+```json
+{
+ "name":"new_live_trace",
+ "description":"This is a new live trace feature",
+ "created_at":"2019-11-04T08:13:10.507Z",
+ "updated_at":"2019-11-04T08:13:10.507Z",
+ "scopes":[
+ {
+ "id":79,
+ "active":false,
+ "environment_scope":"*",
+ "strategies":[
+ {
+ "name":"default",
+ "parameters":{
+
+ }
+ }
+ ],
+ "created_at":"2019-11-04T08:13:10.516Z",
+ "updated_at":"2019-11-04T08:13:10.516Z"
+ },
+ {
+ "id":80,
+ "active":true,
+ "environment_scope":"staging",
+ "strategies":[
+ {
+ "name":"default",
+ "parameters":{
+
+ }
+ }
+ ],
+ "created_at":"2019-11-04T08:13:10.525Z",
+ "updated_at":"2019-11-04T08:13:10.525Z"
+ },
+ {
+ "id":81,
+ "active":false,
+ "environment_scope":"production",
+ "strategies":[
+ {
+ "name":"default",
+ "parameters":{
+
+ }
+ }
+ ],
+ "created_at":"2019-11-04T08:13:10.527Z",
+ "updated_at":"2019-11-04T08:13:10.527Z"
+ }
+ ]
+}
+```
+
+## Delete feature flag
+
+Deletes a feature flag.
+
+```plaintext
+DELETE /projects/:id/feature_flags/:name
+```
+
+| Attribute | Type | Required | Description |
+| ------------------- | ---------------- | ---------- | ---------------------------------------------------------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). |
+| `name` | string | yes | The name of the feature flag. |
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" --request DELETE https://gitlab.example.com/api/v4/projects/1/feature_flags/awesome_feature
+```
diff --git a/doc/api/features.md b/doc/api/features.md
index 03f1663b987..bbf86eca490 100644
--- a/doc/api/features.md
+++ b/doc/api/features.md
@@ -1,3 +1,9 @@
+---
+stage: Release
+group: Progressive Delivery
+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
+---
+
# Features flags API
This API is for managing Flipper-based [feature flags used in development of GitLab](../development/feature_flags/index.md).
@@ -16,7 +22,7 @@ GET /features
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/features
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/features"
```
Example response:
@@ -80,7 +86,7 @@ Note that you can enable or disable a feature for a `feature_group`, a `user`,
a `group`, and a `project` in a single API call.
```shell
-curl --data "value=30" --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/features/new_library
+curl --data "value=30" --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/features/new_library"
```
Example response:
diff --git a/doc/api/geo_nodes.md b/doc/api/geo_nodes.md
index 820f78853d0..12f785a3e3d 100644
--- a/doc/api/geo_nodes.md
+++ b/doc/api/geo_nodes.md
@@ -12,7 +12,7 @@ POST /geo_nodes
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://primary.example.com/api/v4/geo_nodes \
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://primary.example.com/api/v4/geo_nodes" \
--request POST \
-d "name=himynameissomething" \
-d "url=https://another-node.example.com/"
@@ -73,7 +73,7 @@ GET /geo_nodes
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://primary.example.com/api/v4/geo_nodes
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://primary.example.com/api/v4/geo_nodes"
```
Example response:
@@ -140,7 +140,7 @@ GET /geo_nodes/:id
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://primary.example.com/api/v4/geo_nodes/1
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://primary.example.com/api/v4/geo_nodes/1"
```
Example response:
@@ -287,7 +287,7 @@ GET /geo_nodes/status
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://primary.example.com/api/v4/geo_nodes/status
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://primary.example.com/api/v4/geo_nodes/status"
```
Example response:
@@ -366,7 +366,9 @@ Example response:
"revision": "33d33a096a",
"package_files_count": 10,
"package_files_checksummed_count": 10,
- "package_files_checksum_failed_count": 0
+ "package_files_checksum_failed_count": 0,
+ "package_files_synced_count": 10,
+ "package_files_failed_count": 5
},
{
"geo_node_id": 2,
@@ -437,7 +439,9 @@ Example response:
"revision": "33d33a096a",
"package_files_count": 10,
"package_files_checksummed_count": 10,
- "package_files_checksum_failed_count": 0
+ "package_files_checksum_failed_count": 0,
+ "package_files_synced_count": 10,
+ "package_files_failed_count": 5
}
]
```
@@ -452,7 +456,7 @@ GET /geo_nodes/:id/status
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://primary.example.com/api/v4/geo_nodes/2/status
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://primary.example.com/api/v4/geo_nodes/2/status"
```
Example response:
@@ -530,7 +534,7 @@ GET /geo_nodes/current/failures
This endpoint uses [Pagination](README.md#pagination).
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://primary.example.com/api/v4/geo_nodes/current/failures
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://primary.example.com/api/v4/geo_nodes/current/failures"
```
Example response:
diff --git a/doc/api/graphql/index.md b/doc/api/graphql/index.md
index 044c3500bf4..d653c4e0f47 100644
--- a/doc/api/graphql/index.md
+++ b/doc/api/graphql/index.md
@@ -29,11 +29,11 @@ allows clients to request exactly the data they need, making it
possible to get all required data in a limited number of requests.
The GraphQL data (fields) can be described in the form of types,
-allowing clients to use [clientside GraphQL
+allowing clients to use [client-side GraphQL
libraries](https://graphql.org/code/#graphql-clients) to consume the
API and avoid manual parsing.
-Since there's no fixed endpoints and datamodel, new abilities can be
+Since there's no fixed endpoints and data model, new abilities can be
added to the API without creating breaking changes. This allows us to
have a versionless API as described in [the GraphQL
documentation](https://graphql.org/learn/best-practices/#versioning).
@@ -57,8 +57,10 @@ The GraphQL API includes the following queries at the root level:
1. `project` : Project information, with many of its associations such as issues and merge requests.
1. `group` : Basic group information and epics **(ULTIMATE)** are currently supported.
+1. `user` : Information about a particular user.
1. `namespace` : Within a namespace it is also possible to fetch `projects`.
1. `currentUser`: Information about the currently logged in user.
+1. `users`: Information about a collection of users.
1. `metaData`: Metadata about GitLab and the GraphQL API.
1. `snippets`: Snippets visible to the currently logged in user.
diff --git a/doc/api/graphql/reference/gitlab_schema.graphql b/doc/api/graphql/reference/gitlab_schema.graphql
index 91f1413943c..c4bbe7d969d 100644
--- a/doc/api/graphql/reference/gitlab_schema.graphql
+++ b/doc/api/graphql/reference/gitlab_schema.graphql
@@ -1,4 +1,31 @@
"""
+Represents the access level of a relationship between a User and object that it is related to
+"""
+type AccessLevel {
+ """
+ Integer representation of access level
+ """
+ integerValue: Int
+
+ """
+ String representation of access level
+ """
+ stringValue: AccessLevelEnum
+}
+
+"""
+Access level to a resource
+"""
+enum AccessLevelEnum {
+ DEVELOPER
+ GUEST
+ MAINTAINER
+ NO_ACCESS
+ OWNER
+ REPORTER
+}
+
+"""
Autogenerated input type of AddAwardEmoji
"""
input AddAwardEmojiInput {
@@ -141,7 +168,32 @@ type AdminSidekiqQueuesDeleteJobsPayload {
"""
Describes an alert from the project's Alert Management
"""
-type AlertManagementAlert {
+type AlertManagementAlert implements Noteable {
+ """
+ Assignees of the alert
+ """
+ assignees(
+ """
+ Returns the elements in the list that come after the specified cursor.
+ """
+ after: String
+
+ """
+ Returns the elements in the list that come before the specified cursor.
+ """
+ before: String
+
+ """
+ Returns the first _n_ elements from the list.
+ """
+ first: Int
+
+ """
+ Returns the last _n_ elements from the list.
+ """
+ last: Int
+ ): UserConnection
+
"""
Timestamp the alert was created
"""
@@ -158,6 +210,31 @@ type AlertManagementAlert {
details: JSON
"""
+ All discussions on this noteable
+ """
+ discussions(
+ """
+ Returns the elements in the list that come after the specified cursor.
+ """
+ after: String
+
+ """
+ Returns the elements in the list that come before the specified cursor.
+ """
+ before: String
+
+ """
+ Returns the first _n_ elements from the list.
+ """
+ first: Int
+
+ """
+ Returns the last _n_ elements from the list.
+ """
+ last: Int
+ ): DiscussionConnection!
+
+ """
Timestamp the alert ended
"""
endedAt: Time
@@ -188,6 +265,31 @@ type AlertManagementAlert {
monitoringTool: String
"""
+ All notes on this noteable
+ """
+ notes(
+ """
+ Returns the elements in the list that come after the specified cursor.
+ """
+ after: String
+
+ """
+ Returns the elements in the list that come before the specified cursor.
+ """
+ before: String
+
+ """
+ Returns the first _n_ elements from the list.
+ """
+ first: Int
+
+ """
+ Returns the last _n_ elements from the list.
+ """
+ last: Int
+ ): NoteConnection!
+
+ """
Service the alert came from
"""
service: String
@@ -270,22 +372,22 @@ enum AlertManagementAlertSort {
"""
End time by ascending order
"""
- END_TIME_ASC
+ ENDED_AT_ASC
"""
End time by descending order
"""
- END_TIME_DESC
+ ENDED_AT_DESC
"""
Events count by ascending order
"""
- EVENTS_COUNT_ASC
+ EVENT_COUNT_ASC
"""
Events count by descending order
"""
- EVENTS_COUNT_DESC
+ EVENT_COUNT_DESC
"""
Severity by ascending order
@@ -300,12 +402,12 @@ enum AlertManagementAlertSort {
"""
Start time by ascending order
"""
- START_TIME_ASC
+ STARTED_AT_ASC
"""
Start time by descending order
"""
- START_TIME_DESC
+ STARTED_AT_DESC
"""
Status by ascending order
@@ -444,6 +546,61 @@ enum AlertManagementStatus {
}
"""
+Autogenerated input type of AlertSetAssignees
+"""
+input AlertSetAssigneesInput {
+ """
+ The usernames to assign to the alert. Replaces existing assignees by default.
+ """
+ assigneeUsernames: [String!]!
+
+ """
+ A unique identifier for the client performing the mutation.
+ """
+ clientMutationId: String
+
+ """
+ The iid of the alert to mutate
+ """
+ iid: String!
+
+ """
+ The operation to perform. Defaults to REPLACE.
+ """
+ operationMode: MutationOperationMode
+
+ """
+ The project the alert to mutate is in
+ """
+ projectPath: ID!
+}
+
+"""
+Autogenerated return type of AlertSetAssignees
+"""
+type AlertSetAssigneesPayload {
+ """
+ The alert after mutation
+ """
+ alert: AlertManagementAlert
+
+ """
+ A unique identifier for the client performing the mutation.
+ """
+ clientMutationId: String
+
+ """
+ Errors encountered during execution of the mutation.
+ """
+ errors: [String!]!
+
+ """
+ The issue created after mutation
+ """
+ issue: Issue
+}
+
+"""
An emoji awarded by a user.
"""
type AwardEmoji {
@@ -586,7 +743,7 @@ type Board {
id: ID!
"""
- Lists of the project board
+ Lists of the board
"""
lists(
"""
@@ -935,6 +1092,266 @@ type Commit {
webUrl: String!
}
+input CommitAction {
+ """
+ The action to perform, create, delete, move, update, chmod
+ """
+ action: CommitActionMode!
+
+ """
+ Content of the file
+ """
+ content: String
+
+ """
+ Encoding of the file. Default is text
+ """
+ encoding: CommitEncoding
+
+ """
+ Enables/disables the execute flag on the file
+ """
+ executeFilemode: Boolean
+
+ """
+ Full path to the file
+ """
+ filePath: String!
+
+ """
+ Last known file commit ID
+ """
+ lastCommitId: String
+
+ """
+ Original full path to the file being moved
+ """
+ previousPath: String
+}
+
+"""
+Mode of a commit action
+"""
+enum CommitActionMode {
+ """
+ Chmod command
+ """
+ CHMOD
+
+ """
+ Create command
+ """
+ CREATE
+
+ """
+ Delete command
+ """
+ DELETE
+
+ """
+ Move command
+ """
+ MOVE
+
+ """
+ Update command
+ """
+ UPDATE
+}
+
+"""
+Autogenerated input type of CommitCreate
+"""
+input CommitCreateInput {
+ """
+ Array of action hashes to commit as a batch
+ """
+ actions: [CommitAction!]!
+
+ """
+ Name of the branch
+ """
+ branch: String!
+
+ """
+ A unique identifier for the client performing the mutation.
+ """
+ clientMutationId: String
+
+ """
+ Raw commit message
+ """
+ message: String!
+
+ """
+ Project full path the branch is associated with
+ """
+ projectPath: ID!
+}
+
+"""
+Autogenerated return type of CommitCreate
+"""
+type CommitCreatePayload {
+ """
+ A unique identifier for the client performing the mutation.
+ """
+ clientMutationId: String
+
+ """
+ The commit after mutation
+ """
+ commit: Commit
+
+ """
+ Errors encountered during execution of the mutation.
+ """
+ errors: [String!]!
+}
+
+enum CommitEncoding {
+ """
+ Base64 encoding
+ """
+ BASE64
+
+ """
+ Text encoding
+ """
+ TEXT
+}
+
+"""
+A tag expiration policy designed to keep only the images that matter most
+"""
+type ContainerExpirationPolicy {
+ """
+ This container expiration policy schedule
+ """
+ cadence: ContainerExpirationPolicyCadenceEnum!
+
+ """
+ Timestamp of when the container expiration policy was created
+ """
+ createdAt: Time!
+
+ """
+ Indicates whether this container expiration policy is enabled
+ """
+ enabled: Boolean!
+
+ """
+ Number of tags to retain
+ """
+ keepN: ContainerExpirationPolicyKeepEnum
+
+ """
+ Tags with names matching this regex pattern will expire
+ """
+ nameRegex: String
+
+ """
+ Tags with names matching this regex pattern will be preserved
+ """
+ nameRegexKeep: String
+
+ """
+ Next time that this container expiration policy will get executed
+ """
+ nextRunAt: Time
+
+ """
+ Tags older that this will expire
+ """
+ olderThan: ContainerExpirationPolicyOlderThanEnum
+
+ """
+ Timestamp of when the container expiration policy was updated
+ """
+ updatedAt: Time!
+}
+
+enum ContainerExpirationPolicyCadenceEnum {
+ """
+ Every day
+ """
+ EVERY_DAY
+
+ """
+ Every month
+ """
+ EVERY_MONTH
+
+ """
+ Every three months
+ """
+ EVERY_THREE_MONTHS
+
+ """
+ Every two weeks
+ """
+ EVERY_TWO_WEEKS
+
+ """
+ Every week
+ """
+ EVERY_WEEK
+}
+
+enum ContainerExpirationPolicyKeepEnum {
+ """
+ 50 tags per image name
+ """
+ FIFTY_TAGS
+
+ """
+ 5 tags per image name
+ """
+ FIVE_TAGS
+
+ """
+ 100 tags per image name
+ """
+ ONE_HUNDRED_TAGS
+
+ """
+ 1 tag per image name
+ """
+ ONE_TAG
+
+ """
+ 10 tags per image name
+ """
+ TEN_TAGS
+
+ """
+ 25 tags per image name
+ """
+ TWENTY_FIVE_TAGS
+}
+
+enum ContainerExpirationPolicyOlderThanEnum {
+ """
+ 14 days until tags are automatically removed
+ """
+ FOURTEEN_DAYS
+
+ """
+ 90 days until tags are automatically removed
+ """
+ NINETY_DAYS
+
+ """
+ 7 days until tags are automatically removed
+ """
+ SEVEN_DAYS
+
+ """
+ 30 days until tags are automatically removed
+ """
+ THIRTY_DAYS
+}
+
"""
Autogenerated input type of CreateAlertIssue
"""
@@ -1460,6 +1877,43 @@ type CreateSnippetPayload {
snippet: Snippet
}
+enum DastScanTypeEnum {
+ """
+ Passive DAST scan. This scan will not make active attacks against the target site.
+ """
+ PASSIVE
+}
+
+"""
+Autogenerated input type of DeleteAnnotation
+"""
+input DeleteAnnotationInput {
+ """
+ A unique identifier for the client performing the mutation.
+ """
+ clientMutationId: String
+
+ """
+ The global id of the annotation to delete
+ """
+ id: ID!
+}
+
+"""
+Autogenerated return type of DeleteAnnotation
+"""
+type DeleteAnnotationPayload {
+ """
+ A unique identifier for the client performing the mutation.
+ """
+ clientMutationId: String
+
+ """
+ Errors encountered during execution of the mutation.
+ """
+ errors: [String!]!
+}
+
"""
The response from the AdminSidekiqQueuesDeleteJobs mutation.
"""
@@ -2492,7 +2946,7 @@ type DiffRefs {
startSha: String!
}
-type Discussion {
+type Discussion implements ResolvableInterface {
"""
Timestamp of the discussion's creation
"""
@@ -2532,6 +2986,26 @@ type Discussion {
ID used to reply to this discussion
"""
replyId: ID!
+
+ """
+ Indicates if the object can be resolved
+ """
+ resolvable: Boolean!
+
+ """
+ Indicates if the object is resolved
+ """
+ resolved: Boolean!
+
+ """
+ Timestamp of when the object was resolved
+ """
+ resolvedAt: Time
+
+ """
+ User who resolved the object
+ """
+ resolvedBy: User
}
"""
@@ -2570,6 +3044,46 @@ type DiscussionEdge {
}
"""
+Autogenerated input type of DiscussionToggleResolve
+"""
+input DiscussionToggleResolveInput {
+ """
+ A unique identifier for the client performing the mutation.
+ """
+ clientMutationId: String
+
+ """
+ The global id of the discussion
+ """
+ id: ID!
+
+ """
+ Will resolve the discussion when true, and unresolve the discussion when false
+ """
+ resolve: Boolean!
+}
+
+"""
+Autogenerated return type of DiscussionToggleResolve
+"""
+type DiscussionToggleResolvePayload {
+ """
+ A unique identifier for the client performing the mutation.
+ """
+ clientMutationId: String
+
+ """
+ The discussion after mutation
+ """
+ discussion: Discussion
+
+ """
+ Errors encountered during execution of the mutation.
+ """
+ errors: [String!]!
+}
+
+"""
Autogenerated input type of DismissVulnerability
"""
input DismissVulnerabilityInput {
@@ -4328,6 +4842,46 @@ type Group {
): IterationConnection
"""
+ A label available on this group
+ """
+ label(
+ """
+ Title of the label
+ """
+ title: String!
+ ): Label
+
+ """
+ Labels available on this group
+ """
+ labels(
+ """
+ Returns the elements in the list that come after the specified cursor.
+ """
+ after: String
+
+ """
+ Returns the elements in the list that come before the specified cursor.
+ """
+ before: String
+
+ """
+ Returns the first _n_ elements from the list.
+ """
+ first: Int
+
+ """
+ Returns the last _n_ elements from the list.
+ """
+ last: Int
+
+ """
+ A search term to find labels with
+ """
+ searchTerm: String
+ ): LabelConnection
+
+ """
Indicates if Large File Storage (LFS) is enabled for namespace
"""
lfsEnabled: Boolean
@@ -4610,6 +5164,81 @@ type Group {
webUrl: String!
}
+"""
+Represents a Group Member
+"""
+type GroupMember implements MemberInterface {
+ """
+ GitLab::Access level
+ """
+ accessLevel: AccessLevel
+
+ """
+ Date and time the membership was created
+ """
+ createdAt: Time
+
+ """
+ User that authorized membership
+ """
+ createdBy: User
+
+ """
+ Date and time the membership expires
+ """
+ expiresAt: Time
+
+ """
+ Group that a User is a member of
+ """
+ group: Group
+
+ """
+ Date and time the membership was last updated
+ """
+ updatedAt: Time
+
+ """
+ Permissions for the current user on the resource
+ """
+ userPermissions: GroupPermissions!
+}
+
+"""
+The connection type for GroupMember.
+"""
+type GroupMemberConnection {
+ """
+ A list of edges.
+ """
+ edges: [GroupMemberEdge]
+
+ """
+ A list of nodes.
+ """
+ nodes: [GroupMember]
+
+ """
+ Information to aid in pagination.
+ """
+ pageInfo: PageInfo!
+}
+
+"""
+An edge in a connection.
+"""
+type GroupMemberEdge {
+ """
+ A cursor for use in pagination.
+ """
+ cursor: String!
+
+ """
+ The item at the end of the edge.
+ """
+ node: GroupMember
+}
+
type GroupPermissions {
"""
Indicates the user can perform `read_group` on this resource
@@ -5421,6 +6050,16 @@ type JiraImport {
createdAt: Time
"""
+ Count of issues that failed to import
+ """
+ failedToImportCount: Int!
+
+ """
+ Count of issues that were successfully imported
+ """
+ importedIssuesCount: Int!
+
+ """
Project key for the imported Jira project
"""
jiraProjectKey: String!
@@ -5434,6 +6073,11 @@ type JiraImport {
User that started the Jira import
"""
scheduledBy: User
+
+ """
+ Total count of issues that were attempted to import
+ """
+ totalIssueCount: Int!
}
"""
@@ -5516,6 +6160,98 @@ type JiraImportStartPayload {
jiraImport: JiraImport
}
+"""
+Autogenerated input type of JiraImportUsers
+"""
+input JiraImportUsersInput {
+ """
+ A unique identifier for the client performing the mutation.
+ """
+ clientMutationId: String
+
+ """
+ The project to import the Jira users into
+ """
+ projectPath: ID!
+
+ """
+ The index of the record the import should started at, default 0 (50 records returned)
+ """
+ startAt: Int
+}
+
+"""
+Autogenerated return type of JiraImportUsers
+"""
+type JiraImportUsersPayload {
+ """
+ A unique identifier for the client performing the mutation.
+ """
+ clientMutationId: String
+
+ """
+ Errors encountered during execution of the mutation.
+ """
+ errors: [String!]!
+
+ """
+ Users returned from Jira, matched by email and name if possible.
+ """
+ jiraUsers: [JiraUser!]
+}
+
+type JiraProject {
+ """
+ Key of the Jira project
+ """
+ key: String!
+
+ """
+ Name of the Jira project
+ """
+ name: String
+
+ """
+ ID of the Jira project
+ """
+ projectId: Int!
+}
+
+"""
+The connection type for JiraProject.
+"""
+type JiraProjectConnection {
+ """
+ A list of edges.
+ """
+ edges: [JiraProjectEdge]
+
+ """
+ A list of nodes.
+ """
+ nodes: [JiraProject]
+
+ """
+ Information to aid in pagination.
+ """
+ pageInfo: PageInfo!
+}
+
+"""
+An edge in a connection.
+"""
+type JiraProjectEdge {
+ """
+ A cursor for use in pagination.
+ """
+ cursor: String!
+
+ """
+ The item at the end of the edge.
+ """
+ node: JiraProject
+}
+
type JiraService implements Service {
"""
Indicates if the service is active
@@ -5523,11 +6259,63 @@ type JiraService implements Service {
active: Boolean
"""
+ List of Jira projects fetched through Jira REST API
+ """
+ projects(
+ """
+ Returns the elements in the list that come after the specified cursor.
+ """
+ after: String
+
+ """
+ Returns the elements in the list that come before the specified cursor.
+ """
+ before: String
+
+ """
+ Returns the first _n_ elements from the list.
+ """
+ first: Int
+
+ """
+ Returns the last _n_ elements from the list.
+ """
+ last: Int
+
+ """
+ Project name or key
+ """
+ name: String
+ ): JiraProjectConnection
+
+ """
Class name of the service
"""
type: String
}
+type JiraUser {
+ """
+ Id of the matched GitLab user
+ """
+ gitlabId: Int
+
+ """
+ Account id of the Jira user
+ """
+ jiraAccountId: String!
+
+ """
+ Display name of the Jira user
+ """
+ jiraDisplayName: String!
+
+ """
+ Email of the Jira user, returned only for users with public emails
+ """
+ jiraEmail: String
+}
+
type Label {
"""
Background color of the label
@@ -5639,6 +6427,33 @@ type MarkAsSpamSnippetPayload {
snippet: Snippet
}
+interface MemberInterface {
+ """
+ GitLab::Access level
+ """
+ accessLevel: AccessLevel
+
+ """
+ Date and time the membership was created
+ """
+ createdAt: Time
+
+ """
+ User that authorized membership
+ """
+ createdBy: User
+
+ """
+ Date and time the membership expires
+ """
+ expiresAt: Time
+
+ """
+ Date and time the membership was last updated
+ """
+ updatedAt: Time
+}
+
type MergeRequest implements Noteable {
"""
Indicates if members of the target project can push to the fork
@@ -5671,6 +6486,11 @@ type MergeRequest implements Noteable {
): UserConnection
"""
+ User who created this merge request
+ """
+ author: User
+
+ """
Timestamp of when the merge request was created
"""
createdAt: Time!
@@ -5821,6 +6641,11 @@ type MergeRequest implements Noteable {
mergeableDiscussionsState: Boolean
"""
+ Timestamp of when the merge request was merged, null if not merged
+ """
+ mergedAt: Time
+
+ """
The milestone of the merge request
"""
milestone: Milestone
@@ -5991,6 +6816,11 @@ type MergeRequest implements Noteable {
targetBranch: String!
"""
+ Indicates if the target branch of the merge request exists
+ """
+ targetBranchExists: Boolean!
+
+ """
Target project of the merge request
"""
targetProject: Project!
@@ -6077,6 +6907,61 @@ type MergeRequestConnection {
}
"""
+Autogenerated input type of MergeRequestCreate
+"""
+input MergeRequestCreateInput {
+ """
+ A unique identifier for the client performing the mutation.
+ """
+ clientMutationId: String
+
+ """
+ Description of the merge request (Markdown rendered as HTML for caching)
+ """
+ description: String
+
+ """
+ Project full path the merge request is associated with
+ """
+ projectPath: ID!
+
+ """
+ Source branch of the merge request
+ """
+ sourceBranch: String!
+
+ """
+ Target branch of the merge request
+ """
+ targetBranch: String!
+
+ """
+ Title of the merge request
+ """
+ title: String!
+}
+
+"""
+Autogenerated return type of MergeRequestCreate
+"""
+type MergeRequestCreatePayload {
+ """
+ A unique identifier for the client performing the mutation.
+ """
+ clientMutationId: String
+
+ """
+ Errors encountered during execution of the mutation.
+ """
+ errors: [String!]!
+
+ """
+ The merge request after mutation
+ """
+ mergeRequest: MergeRequest
+}
+
+"""
An edge in a connection.
"""
type MergeRequestEdge {
@@ -6478,6 +7363,11 @@ type MetricsDashboard {
Path to a file with the dashboard definition
"""
path: String
+
+ """
+ Dashboard schema validation warnings
+ """
+ schemaValidationWarnings: [String!]
}
type MetricsDashboardAnnotation {
@@ -6562,11 +7452,21 @@ type Milestone {
dueDate: Time
"""
+ Indicates if milestone is at group level
+ """
+ groupMilestone: Boolean!
+
+ """
ID of the milestone
"""
id: ID!
"""
+ Indicates if milestone is at project level
+ """
+ projectMilestone: Boolean!
+
+ """
Timestamp of the milestone start date
"""
startDate: Time
@@ -6577,6 +7477,11 @@ type Milestone {
state: MilestoneStateEnum!
"""
+ Indicates if milestone is at subgroup level
+ """
+ subgroupMilestone: Boolean!
+
+ """
Title of the milestone
"""
title: String!
@@ -6651,7 +7556,9 @@ type Mutation {
addAwardEmoji(input: AddAwardEmojiInput!): AddAwardEmojiPayload
addProjectToSecurityDashboard(input: AddProjectToSecurityDashboardInput!): AddProjectToSecurityDashboardPayload
adminSidekiqQueuesDeleteJobs(input: AdminSidekiqQueuesDeleteJobsInput!): AdminSidekiqQueuesDeleteJobsPayload
+ alertSetAssignees(input: AlertSetAssigneesInput!): AlertSetAssigneesPayload
boardListUpdateLimitMetrics(input: BoardListUpdateLimitMetricsInput!): BoardListUpdateLimitMetricsPayload
+ commitCreate(input: CommitCreateInput!): CommitCreatePayload
createAlertIssue(input: CreateAlertIssueInput!): CreateAlertIssuePayload
createAnnotation(input: CreateAnnotationInput!): CreateAnnotationPayload
createBranch(input: CreateBranchInput!): CreateBranchPayload
@@ -6662,10 +7569,16 @@ type Mutation {
createNote(input: CreateNoteInput!): CreateNotePayload
createRequirement(input: CreateRequirementInput!): CreateRequirementPayload
createSnippet(input: CreateSnippetInput!): CreateSnippetPayload
+ deleteAnnotation(input: DeleteAnnotationInput!): DeleteAnnotationPayload
designManagementDelete(input: DesignManagementDeleteInput!): DesignManagementDeletePayload
designManagementUpload(input: DesignManagementUploadInput!): DesignManagementUploadPayload
destroyNote(input: DestroyNoteInput!): DestroyNotePayload
destroySnippet(input: DestroySnippetInput!): DestroySnippetPayload
+
+ """
+ Toggles the resolved state of a discussion
+ """
+ discussionToggleResolve(input: DiscussionToggleResolveInput!): DiscussionToggleResolvePayload
dismissVulnerability(input: DismissVulnerabilityInput!): DismissVulnerabilityPayload
epicAddIssue(input: EpicAddIssueInput!): EpicAddIssuePayload
epicSetSubscription(input: EpicSetSubscriptionInput!): EpicSetSubscriptionPayload
@@ -6675,7 +7588,9 @@ type Mutation {
issueSetIteration(input: IssueSetIterationInput!): IssueSetIterationPayload
issueSetWeight(input: IssueSetWeightInput!): IssueSetWeightPayload
jiraImportStart(input: JiraImportStartInput!): JiraImportStartPayload
+ jiraImportUsers(input: JiraImportUsersInput!): JiraImportUsersPayload
markAsSpamSnippet(input: MarkAsSpamSnippetInput!): MarkAsSpamSnippetPayload
+ mergeRequestCreate(input: MergeRequestCreateInput!): MergeRequestCreatePayload
mergeRequestSetAssignees(input: MergeRequestSetAssigneesInput!): MergeRequestSetAssigneesPayload
mergeRequestSetLabels(input: MergeRequestSetLabelsInput!): MergeRequestSetLabelsPayload
mergeRequestSetLocked(input: MergeRequestSetLockedInput!): MergeRequestSetLockedPayload
@@ -6684,12 +7599,14 @@ type Mutation {
mergeRequestSetWip(input: MergeRequestSetWipInput!): MergeRequestSetWipPayload
removeAwardEmoji(input: RemoveAwardEmojiInput!): RemoveAwardEmojiPayload
removeProjectFromSecurityDashboard(input: RemoveProjectFromSecurityDashboardInput!): RemoveProjectFromSecurityDashboardPayload
+ runDastScan(input: RunDASTScanInput!): RunDASTScanPayload
todoMarkDone(input: TodoMarkDoneInput!): TodoMarkDonePayload
todoRestore(input: TodoRestoreInput!): TodoRestorePayload
todoRestoreMany(input: TodoRestoreManyInput!): TodoRestoreManyPayload
todosMarkAllDone(input: TodosMarkAllDoneInput!): TodosMarkAllDonePayload
toggleAwardEmoji(input: ToggleAwardEmojiInput!): ToggleAwardEmojiPayload
updateAlertStatus(input: UpdateAlertStatusInput!): UpdateAlertStatusPayload
+ updateContainerExpirationPolicy(input: UpdateContainerExpirationPolicyInput!): UpdateContainerExpirationPolicyPayload
updateEpic(input: UpdateEpicInput!): UpdateEpicPayload
"""
@@ -6856,7 +7773,7 @@ type NamespaceEdge {
node: Namespace
}
-type Note {
+type Note implements ResolvableInterface {
"""
User who wrote this note
"""
@@ -6903,17 +7820,22 @@ type Note {
project: Project
"""
- Indicates if this note can be resolved. That is, if it is a resolvable discussion or simply a standalone note
+ Indicates if the object can be resolved
"""
resolvable: Boolean!
"""
- Timestamp of the note's resolution
+ Indicates if the object is resolved
+ """
+ resolved: Boolean!
+
+ """
+ Timestamp of when the object was resolved
"""
resolvedAt: Time
"""
- User that resolved the discussion
+ User who resolved the object
"""
resolvedBy: User
@@ -7301,6 +8223,11 @@ type Pipeline {
iid: String!
"""
+ Vulnerability and scanned resource counts for each security scanner of the pipeline
+ """
+ securityReportSummary: SecurityReportSummary
+
+ """
SHA of the pipeline's commit
"""
sha: String!
@@ -7422,7 +8349,12 @@ type Project {
"""
Counts of alerts by status for the project
"""
- alertManagementAlertStatusCounts: AlertManagementAlertStatusCountsType
+ alertManagementAlertStatusCounts(
+ """
+ Search criteria for filtering alerts. This will search on title, description, service, monitoring_tool.
+ """
+ search: String
+ ): AlertManagementAlertStatusCountsType
"""
Alert Management alerts of the project
@@ -7470,6 +8402,12 @@ type Project {
): AlertManagementAlertConnection
"""
+ If `only_allow_merge_if_pipeline_succeeds` is true, indicates if merge
+ requests of the project can also be merged with skipped jobs
+ """
+ allowMergeOnSkippedPipeline: Boolean
+
+ """
Indicates the archived status of the project
"""
archived: Boolean
@@ -7525,6 +8463,11 @@ type Project {
): BoardConnection
"""
+ The container expiration policy of the project
+ """
+ containerExpirationPolicy: ContainerExpirationPolicy
+
+ """
Indicates if the project stores Docker container images in a container registry
"""
containerRegistryEnabled: Boolean
@@ -7840,6 +8783,46 @@ type Project {
jobsEnabled: Boolean
"""
+ A label available on this project
+ """
+ label(
+ """
+ Title of the label
+ """
+ title: String!
+ ): Label
+
+ """
+ Labels available on this project
+ """
+ labels(
+ """
+ Returns the elements in the list that come after the specified cursor.
+ """
+ after: String
+
+ """
+ Returns the elements in the list that come before the specified cursor.
+ """
+ before: String
+
+ """
+ Returns the first _n_ elements from the list.
+ """
+ first: Int
+
+ """
+ Returns the last _n_ elements from the list.
+ """
+ last: Int
+
+ """
+ A search term to find labels with
+ """
+ searchTerm: String
+ ): LabelConnection
+
+ """
Timestamp of the project last activity
"""
lastActivityAt: Time
@@ -7856,12 +8839,7 @@ type Project {
"""
IID of the merge request, for example `1`
"""
- iid: String
-
- """
- Array of IIDs of merge requests, for example `[1, 2]`
- """
- iids: [String!]
+ iid: String!
): MergeRequest
"""
@@ -7884,19 +8862,34 @@ type Project {
first: Int
"""
- IID of the merge request, for example `1`
+ Array of IIDs of merge requests, for example `[1, 2]`
"""
- iid: String
+ iids: [String!]
"""
- Array of IIDs of merge requests, for example `[1, 2]`
+ Array of label names. All resolved merge requests will have all of these labels.
"""
- iids: [String!]
+ labels: [String!]
"""
Returns the last _n_ elements from the list.
"""
last: Int
+
+ """
+ Array of source branch names. All resolved merge requests will have one of these branches as their source.
+ """
+ sourceBranches: [String!]
+
+ """
+ A merge request state. If provided, all resolved merge requests will have this state.
+ """
+ state: MergeRequestState
+
+ """
+ Array of target branch names. All resolved merge requests will have one of these branches as their target.
+ """
+ targetBranches: [String!]
): MergeRequestConnection
"""
@@ -7972,6 +8965,16 @@ type Project {
path: String!
"""
+ Build pipeline of the project
+ """
+ pipeline(
+ """
+ IID of the Pipeline, e.g., "1"
+ """
+ iid: ID!
+ ): Pipeline
+
+ """
Build pipelines of the project
"""
pipelines(
@@ -8018,6 +9021,36 @@ type Project {
printingMergeRequestLinkEnabled: Boolean
"""
+ Members of the project
+ """
+ projectMembers(
+ """
+ Returns the elements in the list that come after the specified cursor.
+ """
+ after: String
+
+ """
+ Returns the elements in the list that come before the specified cursor.
+ """
+ before: String
+
+ """
+ Returns the first _n_ elements from the list.
+ """
+ first: Int
+
+ """
+ Returns the last _n_ elements from the list.
+ """
+ last: Int
+
+ """
+ Search query
+ """
+ search: String
+ ): ProjectMemberConnection
+
+ """
Indicates if there is public access to pipelines and job details of the project, including output logs and artifacts
"""
publicJobs: Boolean
@@ -8077,6 +9110,11 @@ type Project {
"""
requirement(
"""
+ Filter requirements by author username
+ """
+ authorUsername: [String!]
+
+ """
IID of the requirement, e.g., "1"
"""
iid: ID
@@ -8087,6 +9125,11 @@ type Project {
iids: [ID!]
"""
+ Filter requirements by title search
+ """
+ search: String
+
+ """
List requirements by sort order
"""
sort: Sort
@@ -8112,6 +9155,11 @@ type Project {
after: String
"""
+ Filter requirements by author username
+ """
+ authorUsername: [String!]
+
+ """
Returns the elements in the list that come before the specified cursor.
"""
before: String
@@ -8137,6 +9185,11 @@ type Project {
last: Int
"""
+ Filter requirements by title search
+ """
+ search: String
+
+ """
List requirements by sort order
"""
sort: Sort
@@ -8383,6 +9436,91 @@ type ProjectEdge {
node: Project
}
+"""
+Represents a Project Member
+"""
+type ProjectMember implements MemberInterface {
+ """
+ GitLab::Access level
+ """
+ accessLevel: AccessLevel
+
+ """
+ Date and time the membership was created
+ """
+ createdAt: Time
+
+ """
+ User that authorized membership
+ """
+ createdBy: User
+
+ """
+ Date and time the membership expires
+ """
+ expiresAt: Time
+
+ """
+ ID of the member
+ """
+ id: ID!
+
+ """
+ Project that User is a member of
+ """
+ project: Project
+
+ """
+ Date and time the membership was last updated
+ """
+ updatedAt: Time
+
+ """
+ User that is associated with the member object
+ """
+ user: User!
+
+ """
+ Permissions for the current user on the resource
+ """
+ userPermissions: ProjectPermissions!
+}
+
+"""
+The connection type for ProjectMember.
+"""
+type ProjectMemberConnection {
+ """
+ A list of edges.
+ """
+ edges: [ProjectMemberEdge]
+
+ """
+ A list of nodes.
+ """
+ nodes: [ProjectMember]
+
+ """
+ Information to aid in pagination.
+ """
+ pageInfo: PageInfo!
+}
+
+"""
+An edge in a connection.
+"""
+type ProjectMemberEdge {
+ """
+ A cursor for use in pagination.
+ """
+ cursor: String!
+
+ """
+ The item at the end of the edge.
+ """
+ node: ProjectMember
+}
+
type ProjectPermissions {
"""
Indicates the user can perform `admin_operations` on this resource
@@ -8794,6 +9932,61 @@ type Query {
): SnippetConnection
"""
+ Find a user on this instance
+ """
+ user(
+ """
+ ID of the User
+ """
+ id: ID
+
+ """
+ Username of the User
+ """
+ username: String
+ ): User
+
+ """
+ Find users
+ """
+ users(
+ """
+ Returns the elements in the list that come after the specified cursor.
+ """
+ after: String
+
+ """
+ Returns the elements in the list that come before the specified cursor.
+ """
+ before: String
+
+ """
+ Returns the first _n_ elements from the list.
+ """
+ first: Int
+
+ """
+ List of user Global IDs
+ """
+ ids: [ID!]
+
+ """
+ Returns the last _n_ elements from the list.
+ """
+ last: Int
+
+ """
+ Sort users by this criteria
+ """
+ sort: Sort = created_desc
+
+ """
+ List of usernames
+ """
+ usernames: [String!]
+ ): UserConnection
+
+ """
Vulnerabilities reported on projects on the current user's instance security dashboard
"""
vulnerabilities(
@@ -8901,6 +10094,11 @@ enum RegistryState {
type Release {
"""
+ Assets of the release
+ """
+ assets: ReleaseAssets
+
+ """
User that created the release
"""
author: User
@@ -8926,6 +10124,31 @@ type Release {
descriptionHtml: String
"""
+ Evidence for the release
+ """
+ evidences(
+ """
+ Returns the elements in the list that come after the specified cursor.
+ """
+ after: String
+
+ """
+ Returns the elements in the list that come before the specified cursor.
+ """
+ before: String
+
+ """
+ Returns the first _n_ elements from the list.
+ """
+ first: Int
+
+ """
+ Returns the last _n_ elements from the list.
+ """
+ last: Int
+ ): ReleaseEvidenceConnection
+
+ """
Milestones associated to the release
"""
milestones(
@@ -8971,6 +10194,63 @@ type Release {
tagPath: String
}
+type ReleaseAssets {
+ """
+ Number of assets of the release
+ """
+ assetsCount: Int
+
+ """
+ Asset links of the release
+ """
+ links(
+ """
+ Returns the elements in the list that come after the specified cursor.
+ """
+ after: String
+
+ """
+ Returns the elements in the list that come before the specified cursor.
+ """
+ before: String
+
+ """
+ Returns the first _n_ elements from the list.
+ """
+ first: Int
+
+ """
+ Returns the last _n_ elements from the list.
+ """
+ last: Int
+ ): ReleaseLinkConnection
+
+ """
+ Sources of the release
+ """
+ sources(
+ """
+ Returns the elements in the list that come after the specified cursor.
+ """
+ after: String
+
+ """
+ Returns the elements in the list that come before the specified cursor.
+ """
+ before: String
+
+ """
+ Returns the first _n_ elements from the list.
+ """
+ first: Int
+
+ """
+ Returns the last _n_ elements from the list.
+ """
+ last: Int
+ ): ReleaseSourceConnection
+}
+
"""
The connection type for Release.
"""
@@ -9007,6 +10287,200 @@ type ReleaseEdge {
}
"""
+Evidence for a release
+"""
+type ReleaseEvidence {
+ """
+ Timestamp when the evidence was collected
+ """
+ collectedAt: Time
+
+ """
+ URL from where the evidence can be downloaded
+ """
+ filepath: String
+
+ """
+ ID of the evidence
+ """
+ id: ID!
+
+ """
+ SHA1 ID of the evidence hash
+ """
+ sha: String
+}
+
+"""
+The connection type for ReleaseEvidence.
+"""
+type ReleaseEvidenceConnection {
+ """
+ A list of edges.
+ """
+ edges: [ReleaseEvidenceEdge]
+
+ """
+ A list of nodes.
+ """
+ nodes: [ReleaseEvidence]
+
+ """
+ Information to aid in pagination.
+ """
+ pageInfo: PageInfo!
+}
+
+"""
+An edge in a connection.
+"""
+type ReleaseEvidenceEdge {
+ """
+ A cursor for use in pagination.
+ """
+ cursor: String!
+
+ """
+ The item at the end of the edge.
+ """
+ node: ReleaseEvidence
+}
+
+type ReleaseLink {
+ """
+ Indicates the link points to an external resource
+ """
+ external: Boolean
+
+ """
+ ID of the link
+ """
+ id: ID!
+
+ """
+ Type of the link: `other`, `runbook`, `image`, `package`; defaults to `other`
+ """
+ linkType: ReleaseLinkType
+
+ """
+ Name of the link
+ """
+ name: String
+
+ """
+ URL of the link
+ """
+ url: String
+}
+
+"""
+The connection type for ReleaseLink.
+"""
+type ReleaseLinkConnection {
+ """
+ A list of edges.
+ """
+ edges: [ReleaseLinkEdge]
+
+ """
+ A list of nodes.
+ """
+ nodes: [ReleaseLink]
+
+ """
+ Information to aid in pagination.
+ """
+ pageInfo: PageInfo!
+}
+
+"""
+An edge in a connection.
+"""
+type ReleaseLinkEdge {
+ """
+ A cursor for use in pagination.
+ """
+ cursor: String!
+
+ """
+ The item at the end of the edge.
+ """
+ node: ReleaseLink
+}
+
+"""
+Type of the link: `other`, `runbook`, `image`, `package`; defaults to `other`
+"""
+enum ReleaseLinkType {
+ """
+ Image link type
+ """
+ IMAGE
+
+ """
+ Other link type
+ """
+ OTHER
+
+ """
+ Package link type
+ """
+ PACKAGE
+
+ """
+ Runbook link type
+ """
+ RUNBOOK
+}
+
+type ReleaseSource {
+ """
+ Format of the source
+ """
+ format: String
+
+ """
+ Download URL of the source
+ """
+ url: String
+}
+
+"""
+The connection type for ReleaseSource.
+"""
+type ReleaseSourceConnection {
+ """
+ A list of edges.
+ """
+ edges: [ReleaseSourceEdge]
+
+ """
+ A list of nodes.
+ """
+ nodes: [ReleaseSource]
+
+ """
+ Information to aid in pagination.
+ """
+ pageInfo: PageInfo!
+}
+
+"""
+An edge in a connection.
+"""
+type ReleaseSourceEdge {
+ """
+ A cursor for use in pagination.
+ """
+ cursor: String!
+
+ """
+ The item at the end of the edge.
+ """
+ node: ReleaseSource
+}
+
+"""
Autogenerated input type of RemoveAwardEmoji
"""
input RemoveAwardEmojiInput {
@@ -9114,7 +10588,7 @@ type Repository {
}
"""
-Represents a requirement.
+Represents a requirement
"""
type Requirement {
"""
@@ -9148,6 +10622,36 @@ type Requirement {
state: RequirementState!
"""
+ Test reports of the requirement
+ """
+ testReports(
+ """
+ Returns the elements in the list that come after the specified cursor.
+ """
+ after: String
+
+ """
+ Returns the elements in the list that come before the specified cursor.
+ """
+ before: String
+
+ """
+ Returns the first _n_ elements from the list.
+ """
+ first: Int
+
+ """
+ Returns the last _n_ elements from the list.
+ """
+ last: Int
+
+ """
+ List test reports by sort order
+ """
+ sort: Sort
+ ): TestReportConnection
+
+ """
Title of the requirement
"""
title: String
@@ -9251,6 +10755,28 @@ type RequirementStatesCount {
opened: Int
}
+interface ResolvableInterface {
+ """
+ Indicates if the object can be resolved
+ """
+ resolvable: Boolean!
+
+ """
+ Indicates if the object is resolved
+ """
+ resolved: Boolean!
+
+ """
+ Timestamp of when the object was resolved
+ """
+ resolvedAt: Time
+
+ """
+ User who resolved the object
+ """
+ resolvedBy: User
+}
+
type RootStorageStatistics {
"""
The CI artifacts size in bytes
@@ -9284,6 +10810,101 @@ type RootStorageStatistics {
}
"""
+Autogenerated input type of RunDASTScan
+"""
+input RunDASTScanInput {
+ """
+ The branch to be associated with the scan.
+ """
+ branch: String!
+
+ """
+ A unique identifier for the client performing the mutation.
+ """
+ clientMutationId: String
+
+ """
+ The project the DAST scan belongs to.
+ """
+ projectPath: ID!
+
+ """
+ The type of scan to be run.
+ """
+ scanType: DastScanTypeEnum!
+
+ """
+ The URL of the target to be scanned.
+ """
+ targetUrl: String!
+}
+
+"""
+Autogenerated return type of RunDASTScan
+"""
+type RunDASTScanPayload {
+ """
+ A unique identifier for the client performing the mutation.
+ """
+ clientMutationId: String
+
+ """
+ Errors encountered during execution of the mutation.
+ """
+ errors: [String!]!
+
+ """
+ URL of the pipeline that was created.
+ """
+ pipelineUrl: String
+}
+
+"""
+Represents summary of a security report
+"""
+type SecurityReportSummary {
+ """
+ Aggregated counts for the container_scanning scan
+ """
+ containerScanning: SecurityReportSummarySection
+
+ """
+ Aggregated counts for the dast scan
+ """
+ dast: SecurityReportSummarySection
+
+ """
+ Aggregated counts for the dependency_scanning scan
+ """
+ dependencyScanning: SecurityReportSummarySection
+
+ """
+ Aggregated counts for the sast scan
+ """
+ sast: SecurityReportSummarySection
+
+ """
+ Aggregated counts for the secret_detection scan
+ """
+ secretDetection: SecurityReportSummarySection
+}
+
+"""
+Represents a section of a summary of a security report
+"""
+type SecurityReportSummarySection {
+ """
+ Total number of scanned resources
+ """
+ scannedResourcesCount: Int
+
+ """
+ Total number of vulnerabilities
+ """
+ vulnerabilitiesCount: Int
+}
+
+"""
A Sentry error.
"""
type SentryDetailedError {
@@ -9816,7 +11437,7 @@ type Snippet implements Noteable {
"""
The owner of the snippet
"""
- author: User!
+ author: User
"""
Snippet blob
@@ -9824,6 +11445,11 @@ type Snippet implements Noteable {
blob: SnippetBlob!
"""
+ Snippet blobs
+ """
+ blobs: [SnippetBlob!]!
+
+ """
Timestamp this snippet was created
"""
createdAt: Time!
@@ -10234,6 +11860,73 @@ type TaskCompletionStatus {
}
"""
+Represents a requirement test report.
+"""
+type TestReport {
+ """
+ Author of the test report
+ """
+ author: User
+
+ """
+ Timestamp of when the test report was created
+ """
+ createdAt: Time!
+
+ """
+ ID of the test report
+ """
+ id: ID!
+
+ """
+ State of the test report
+ """
+ state: TestReportState!
+}
+
+"""
+The connection type for TestReport.
+"""
+type TestReportConnection {
+ """
+ A list of edges.
+ """
+ edges: [TestReportEdge]
+
+ """
+ A list of nodes.
+ """
+ nodes: [TestReport]
+
+ """
+ Information to aid in pagination.
+ """
+ pageInfo: PageInfo!
+}
+
+"""
+An edge in a connection.
+"""
+type TestReportEdge {
+ """
+ A cursor for use in pagination.
+ """
+ cursor: String!
+
+ """
+ The item at the end of the edge.
+ """
+ node: TestReport
+}
+
+"""
+State of a test report
+"""
+enum TestReportState {
+ PASSED
+}
+
+"""
Time represented in ISO 8601
"""
scalar Time
@@ -10819,6 +12512,61 @@ type UpdateAlertStatusPayload {
issue: Issue
}
+"""
+Autogenerated input type of UpdateContainerExpirationPolicy
+"""
+input UpdateContainerExpirationPolicyInput {
+ """
+ This container expiration policy schedule
+ """
+ cadence: ContainerExpirationPolicyCadenceEnum
+
+ """
+ A unique identifier for the client performing the mutation.
+ """
+ clientMutationId: String
+
+ """
+ Indicates whether this container expiration policy is enabled
+ """
+ enabled: Boolean
+
+ """
+ Number of tags to retain
+ """
+ keepN: ContainerExpirationPolicyKeepEnum
+
+ """
+ Tags older that this will expire
+ """
+ olderThan: ContainerExpirationPolicyOlderThanEnum
+
+ """
+ The project path where the container expiration policy is located
+ """
+ projectPath: ID!
+}
+
+"""
+Autogenerated return type of UpdateContainerExpirationPolicy
+"""
+type UpdateContainerExpirationPolicyPayload {
+ """
+ A unique identifier for the client performing the mutation.
+ """
+ clientMutationId: String
+
+ """
+ The container expiration policy after mutation
+ """
+ containerExpirationPolicy: ContainerExpirationPolicy
+
+ """
+ Errors encountered during execution of the mutation.
+ """
+ errors: [String!]!
+}
+
input UpdateDiffImagePositionInput {
"""
Total height of the image
@@ -11195,11 +12943,156 @@ scalar Upload
type User {
"""
+ Merge Requests assigned to the user
+ """
+ assignedMergeRequests(
+ """
+ Returns the elements in the list that come after the specified cursor.
+ """
+ after: String
+
+ """
+ Returns the elements in the list that come before the specified cursor.
+ """
+ before: String
+
+ """
+ Returns the first _n_ elements from the list.
+ """
+ first: Int
+
+ """
+ Array of IIDs of merge requests, for example `[1, 2]`
+ """
+ iids: [String!]
+
+ """
+ Array of label names. All resolved merge requests will have all of these labels.
+ """
+ labels: [String!]
+
+ """
+ Returns the last _n_ elements from the list.
+ """
+ last: Int
+
+ """
+ The global ID of the project the authored merge requests should be in. Incompatible with projectPath.
+ """
+ projectId: ID
+
+ """
+ The full-path of the project the authored merge requests should be in. Incompatible with projectId.
+ """
+ projectPath: String
+
+ """
+ Array of source branch names. All resolved merge requests will have one of these branches as their source.
+ """
+ sourceBranches: [String!]
+
+ """
+ A merge request state. If provided, all resolved merge requests will have this state.
+ """
+ state: MergeRequestState
+
+ """
+ Array of target branch names. All resolved merge requests will have one of these branches as their target.
+ """
+ targetBranches: [String!]
+ ): MergeRequestConnection
+
+ """
+ Merge Requests authored by the user
+ """
+ authoredMergeRequests(
+ """
+ Returns the elements in the list that come after the specified cursor.
+ """
+ after: String
+
+ """
+ Returns the elements in the list that come before the specified cursor.
+ """
+ before: String
+
+ """
+ Returns the first _n_ elements from the list.
+ """
+ first: Int
+
+ """
+ Array of IIDs of merge requests, for example `[1, 2]`
+ """
+ iids: [String!]
+
+ """
+ Array of label names. All resolved merge requests will have all of these labels.
+ """
+ labels: [String!]
+
+ """
+ Returns the last _n_ elements from the list.
+ """
+ last: Int
+
+ """
+ The global ID of the project the authored merge requests should be in. Incompatible with projectPath.
+ """
+ projectId: ID
+
+ """
+ The full-path of the project the authored merge requests should be in. Incompatible with projectId.
+ """
+ projectPath: String
+
+ """
+ Array of source branch names. All resolved merge requests will have one of these branches as their source.
+ """
+ sourceBranches: [String!]
+
+ """
+ A merge request state. If provided, all resolved merge requests will have this state.
+ """
+ state: MergeRequestState
+
+ """
+ Array of target branch names. All resolved merge requests will have one of these branches as their target.
+ """
+ targetBranches: [String!]
+ ): MergeRequestConnection
+
+ """
URL of the user's avatar
"""
avatarUrl: String
"""
+ Group memberships of the user
+ """
+ groupMemberships(
+ """
+ Returns the elements in the list that come after the specified cursor.
+ """
+ after: String
+
+ """
+ Returns the elements in the list that come before the specified cursor.
+ """
+ before: String
+
+ """
+ Returns the first _n_ elements from the list.
+ """
+ first: Int
+
+ """
+ Returns the last _n_ elements from the list.
+ """
+ last: Int
+ ): GroupMemberConnection
+
+ """
ID of the user
"""
id: ID!
@@ -11210,6 +13103,31 @@ type User {
name: String!
"""
+ Project memberships of the user
+ """
+ projectMemberships(
+ """
+ Returns the elements in the list that come after the specified cursor.
+ """
+ after: String
+
+ """
+ Returns the elements in the list that come before the specified cursor.
+ """
+ before: String
+
+ """
+ Returns the first _n_ elements from the list.
+ """
+ first: Int
+
+ """
+ Returns the last _n_ elements from the list.
+ """
+ last: Int
+ ): ProjectMemberConnection
+
+ """
Snippets authored by the user
"""
snippets(
@@ -11250,9 +13168,9 @@ type User {
): SnippetConnection
"""
- State of the issue
+ State of the user
"""
- state: String!
+ state: UserState!
"""
Todos of the user
@@ -11367,6 +13285,26 @@ type UserPermissions {
createSnippet: Boolean!
}
+"""
+Possible states of a user
+"""
+enum UserState {
+ """
+ The user is active and is able to use the system
+ """
+ active
+
+ """
+ The user has been blocked and is prevented from using the system
+ """
+ blocked
+
+ """
+ The user is no longer active and is unable to use the system
+ """
+ deactivated
+}
+
enum VisibilityLevelsEnum {
internal
private
@@ -11449,6 +13387,36 @@ type Vulnerability {
id: ID!
"""
+ List of issue links related to the vulnerability
+ """
+ issueLinks(
+ """
+ Returns the elements in the list that come after the specified cursor.
+ """
+ after: String
+
+ """
+ Returns the elements in the list that come before the specified cursor.
+ """
+ before: String
+
+ """
+ Returns the first _n_ elements from the list.
+ """
+ first: Int
+
+ """
+ Returns the last _n_ elements from the list.
+ """
+ last: Int
+
+ """
+ Filter issue links by link type
+ """
+ linkType: VulnerabilityIssueLinkType
+ ): VulnerabilityIssueLinkConnection!
+
+ """
Location metadata for the vulnerability. Its fields depend on the type of security scan that found the vulnerability
"""
location: VulnerabilityLocation
@@ -11459,7 +13427,8 @@ type Vulnerability {
project: Project
"""
- Type of the security report that found the vulnerability (SAST, DEPENDENCY_SCANNING, CONTAINER_SCANNING, DAST)
+ Type of the security report that found the vulnerability (SAST,
+ DEPENDENCY_SCANNING, CONTAINER_SCANNING, DAST, SECRET_DETECTION)
"""
reportType: VulnerabilityReportType
@@ -11479,6 +13448,11 @@ type Vulnerability {
title: String
"""
+ Number of user notes attached to the vulnerability
+ """
+ userNotesCount: Int!
+
+ """
Permissions for the current user on the resource
"""
userPermissions: VulnerabilityPermissions!
@@ -11525,9 +13499,72 @@ type VulnerabilityEdge {
}
"""
+Represents an issue link of a vulnerability.
+"""
+type VulnerabilityIssueLink {
+ """
+ GraphQL ID of the vulnerability
+ """
+ id: ID!
+
+ """
+ The issue attached to issue link
+ """
+ issue: Issue!
+
+ """
+ Type of the issue link
+ """
+ linkType: VulnerabilityIssueLinkType!
+}
+
+"""
+The connection type for VulnerabilityIssueLink.
+"""
+type VulnerabilityIssueLinkConnection {
+ """
+ A list of edges.
+ """
+ edges: [VulnerabilityIssueLinkEdge]
+
+ """
+ A list of nodes.
+ """
+ nodes: [VulnerabilityIssueLink]
+
+ """
+ Information to aid in pagination.
+ """
+ pageInfo: PageInfo!
+}
+
+"""
+An edge in a connection.
+"""
+type VulnerabilityIssueLinkEdge {
+ """
+ A cursor for use in pagination.
+ """
+ cursor: String!
+
+ """
+ The item at the end of the edge.
+ """
+ node: VulnerabilityIssueLink
+}
+
+"""
+The type of the issue link related to a vulnerability.
+"""
+enum VulnerabilityIssueLinkType {
+ CREATED
+ RELATED
+}
+
+"""
Represents a vulnerability location. The fields with data will depend on the vulnerability report type
"""
-union VulnerabilityLocation = VulnerabilityLocationContainerScanning | VulnerabilityLocationDast | VulnerabilityLocationDependencyScanning | VulnerabilityLocationSast
+union VulnerabilityLocation = VulnerabilityLocationContainerScanning | VulnerabilityLocationDast | VulnerabilityLocationDependencyScanning | VulnerabilityLocationSast | VulnerabilityLocationSecretDetection
"""
Represents the location of a vulnerability found by a container security scan
@@ -11620,6 +13657,36 @@ type VulnerabilityLocationSast {
}
"""
+Represents the location of a vulnerability found by a secret detection scan
+"""
+type VulnerabilityLocationSecretDetection {
+ """
+ Number of the last relevant line in the vulnerable file
+ """
+ endLine: String
+
+ """
+ Path to the vulnerable file
+ """
+ file: String
+
+ """
+ Number of the first relevant line in the vulnerable file
+ """
+ startLine: String
+
+ """
+ Class containing the vulnerability
+ """
+ vulnerableClass: String
+
+ """
+ Method containing the vulnerability
+ """
+ vulnerableMethod: String
+}
+
+"""
Check permissions for the current user on a vulnerability
"""
type VulnerabilityPermissions {
@@ -11672,6 +13739,7 @@ enum VulnerabilityReportType {
DAST
DEPENDENCY_SCANNING
SAST
+ SECRET_DETECTION
}
"""
diff --git a/doc/api/graphql/reference/gitlab_schema.json b/doc/api/graphql/reference/gitlab_schema.json
index 40bfa08cff3..d2bc599ff9d 100644
--- a/doc/api/graphql/reference/gitlab_schema.json
+++ b/doc/api/graphql/reference/gitlab_schema.json
@@ -10,6 +10,94 @@
"subscriptionType": null,
"types": [
{
+ "kind": "OBJECT",
+ "name": "AccessLevel",
+ "description": "Represents the access level of a relationship between a User and object that it is related to",
+ "fields": [
+ {
+ "name": "integerValue",
+ "description": "Integer representation of access level",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "stringValue",
+ "description": "String representation of access level",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "ENUM",
+ "name": "AccessLevelEnum",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "ENUM",
+ "name": "AccessLevelEnum",
+ "description": "Access level to a resource",
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": [
+ {
+ "name": "NO_ACCESS",
+ "description": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "GUEST",
+ "description": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "REPORTER",
+ "description": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "DEVELOPER",
+ "description": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "MAINTAINER",
+ "description": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "OWNER",
+ "description": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "possibleTypes": null
+ },
+ {
"kind": "INPUT_OBJECT",
"name": "AddAwardEmojiInput",
"description": "Autogenerated input type of AddAwardEmoji",
@@ -395,6 +483,59 @@
"description": "Describes an alert from the project's Alert Management",
"fields": [
{
+ "name": "assignees",
+ "description": "Assignees of the alert",
+ "args": [
+ {
+ "name": "after",
+ "description": "Returns the elements in the list that come after the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "before",
+ "description": "Returns the elements in the list that come before the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "first",
+ "description": "Returns the first _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "last",
+ "description": "Returns the last _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "UserConnection",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "createdAt",
"description": "Timestamp the alert was created",
"args": [
@@ -437,6 +578,63 @@
"deprecationReason": null
},
{
+ "name": "discussions",
+ "description": "All discussions on this noteable",
+ "args": [
+ {
+ "name": "after",
+ "description": "Returns the elements in the list that come after the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "before",
+ "description": "Returns the elements in the list that come before the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "first",
+ "description": "Returns the first _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "last",
+ "description": "Returns the last _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "DiscussionConnection",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "endedAt",
"description": "Timestamp the alert ended",
"args": [
@@ -533,6 +731,63 @@
"deprecationReason": null
},
{
+ "name": "notes",
+ "description": "All notes on this noteable",
+ "args": [
+ {
+ "name": "after",
+ "description": "Returns the elements in the list that come after the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "before",
+ "description": "Returns the elements in the list that come before the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "first",
+ "description": "Returns the first _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "last",
+ "description": "Returns the last _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "NoteConnection",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "service",
"description": "Service the alert came from",
"args": [
@@ -619,7 +874,11 @@
],
"inputFields": null,
"interfaces": [
-
+ {
+ "kind": "INTERFACE",
+ "name": "Noteable",
+ "ofType": null
+ }
],
"enumValues": null,
"possibleTypes": null
@@ -769,25 +1028,25 @@
"deprecationReason": null
},
{
- "name": "START_TIME_ASC",
+ "name": "STARTED_AT_ASC",
"description": "Start time by ascending order",
"isDeprecated": false,
"deprecationReason": null
},
{
- "name": "START_TIME_DESC",
+ "name": "STARTED_AT_DESC",
"description": "Start time by descending order",
"isDeprecated": false,
"deprecationReason": null
},
{
- "name": "END_TIME_ASC",
+ "name": "ENDED_AT_ASC",
"description": "End time by ascending order",
"isDeprecated": false,
"deprecationReason": null
},
{
- "name": "END_TIME_DESC",
+ "name": "ENDED_AT_DESC",
"description": "End time by descending order",
"isDeprecated": false,
"deprecationReason": null
@@ -817,13 +1076,13 @@
"deprecationReason": null
},
{
- "name": "EVENTS_COUNT_ASC",
+ "name": "EVENT_COUNT_ASC",
"description": "Events count by ascending order",
"isDeprecated": false,
"deprecationReason": null
},
{
- "name": "EVENTS_COUNT_DESC",
+ "name": "EVENT_COUNT_DESC",
"description": "Events count by descending order",
"isDeprecated": false,
"deprecationReason": null
@@ -1035,6 +1294,168 @@
"possibleTypes": null
},
{
+ "kind": "INPUT_OBJECT",
+ "name": "AlertSetAssigneesInput",
+ "description": "Autogenerated input type of AlertSetAssignees",
+ "fields": null,
+ "inputFields": [
+ {
+ "name": "projectPath",
+ "description": "The project the alert to mutate is in",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "ID",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "iid",
+ "description": "The iid of the alert to mutate",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "assigneeUsernames",
+ "description": "The usernames to assign to the alert. Replaces existing assignees by default.",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "operationMode",
+ "description": "The operation to perform. Defaults to REPLACE.",
+ "type": {
+ "kind": "ENUM",
+ "name": "MutationOperationMode",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "clientMutationId",
+ "description": "A unique identifier for the client performing the mutation.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "AlertSetAssigneesPayload",
+ "description": "Autogenerated return type of AlertSetAssignees",
+ "fields": [
+ {
+ "name": "alert",
+ "description": "The alert after mutation",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "AlertManagementAlert",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "clientMutationId",
+ "description": "A unique identifier for the client performing the mutation.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "errors",
+ "description": "Errors encountered during execution of the mutation.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "issue",
+ "description": "The issue created after mutation",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "Issue",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
"kind": "OBJECT",
"name": "AwardEmoji",
"description": "An emoji awarded by a user.",
@@ -1519,7 +1940,7 @@
},
{
"name": "lists",
- "description": "Lists of the project board",
+ "description": "Lists of the board",
"args": [
{
"name": "after",
@@ -2517,6 +2938,589 @@
},
{
"kind": "INPUT_OBJECT",
+ "name": "CommitAction",
+ "description": null,
+ "fields": null,
+ "inputFields": [
+ {
+ "name": "action",
+ "description": "The action to perform, create, delete, move, update, chmod",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "ENUM",
+ "name": "CommitActionMode",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "filePath",
+ "description": "Full path to the file",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "content",
+ "description": "Content of the file",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "previousPath",
+ "description": "Original full path to the file being moved",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "lastCommitId",
+ "description": "Last known file commit ID",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "executeFilemode",
+ "description": "Enables/disables the execute flag on the file",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "encoding",
+ "description": "Encoding of the file. Default is text",
+ "type": {
+ "kind": "ENUM",
+ "name": "CommitEncoding",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "ENUM",
+ "name": "CommitActionMode",
+ "description": "Mode of a commit action",
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": [
+ {
+ "name": "CREATE",
+ "description": "Create command",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "DELETE",
+ "description": "Delete command",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "MOVE",
+ "description": "Move command",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "UPDATE",
+ "description": "Update command",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "CHMOD",
+ "description": "Chmod command",
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "possibleTypes": null
+ },
+ {
+ "kind": "INPUT_OBJECT",
+ "name": "CommitCreateInput",
+ "description": "Autogenerated input type of CommitCreate",
+ "fields": null,
+ "inputFields": [
+ {
+ "name": "projectPath",
+ "description": "Project full path the branch is associated with",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "ID",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "branch",
+ "description": "Name of the branch",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "message",
+ "description": "Raw commit message",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "actions",
+ "description": "Array of action hashes to commit as a batch",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "INPUT_OBJECT",
+ "name": "CommitAction",
+ "ofType": null
+ }
+ }
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "clientMutationId",
+ "description": "A unique identifier for the client performing the mutation.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "CommitCreatePayload",
+ "description": "Autogenerated return type of CommitCreate",
+ "fields": [
+ {
+ "name": "clientMutationId",
+ "description": "A unique identifier for the client performing the mutation.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "commit",
+ "description": "The commit after mutation",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "Commit",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "errors",
+ "description": "Errors encountered during execution of the mutation.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "ENUM",
+ "name": "CommitEncoding",
+ "description": null,
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": [
+ {
+ "name": "TEXT",
+ "description": "Text encoding",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "BASE64",
+ "description": "Base64 encoding",
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "ContainerExpirationPolicy",
+ "description": "A tag expiration policy designed to keep only the images that matter most",
+ "fields": [
+ {
+ "name": "cadence",
+ "description": "This container expiration policy schedule",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "ENUM",
+ "name": "ContainerExpirationPolicyCadenceEnum",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "createdAt",
+ "description": "Timestamp of when the container expiration policy was created",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Time",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "enabled",
+ "description": "Indicates whether this container expiration policy is enabled",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "keepN",
+ "description": "Number of tags to retain",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "ENUM",
+ "name": "ContainerExpirationPolicyKeepEnum",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "nameRegex",
+ "description": "Tags with names matching this regex pattern will expire",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "nameRegexKeep",
+ "description": "Tags with names matching this regex pattern will be preserved",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "nextRunAt",
+ "description": "Next time that this container expiration policy will get executed",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Time",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "olderThan",
+ "description": "Tags older that this will expire",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "ENUM",
+ "name": "ContainerExpirationPolicyOlderThanEnum",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "updatedAt",
+ "description": "Timestamp of when the container expiration policy was updated",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Time",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "ENUM",
+ "name": "ContainerExpirationPolicyCadenceEnum",
+ "description": null,
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": [
+ {
+ "name": "EVERY_DAY",
+ "description": "Every day",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "EVERY_WEEK",
+ "description": "Every week",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "EVERY_TWO_WEEKS",
+ "description": "Every two weeks",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "EVERY_MONTH",
+ "description": "Every month",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "EVERY_THREE_MONTHS",
+ "description": "Every three months",
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "possibleTypes": null
+ },
+ {
+ "kind": "ENUM",
+ "name": "ContainerExpirationPolicyKeepEnum",
+ "description": null,
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": [
+ {
+ "name": "ONE_TAG",
+ "description": "1 tag per image name",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "FIVE_TAGS",
+ "description": "5 tags per image name",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "TEN_TAGS",
+ "description": "10 tags per image name",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "TWENTY_FIVE_TAGS",
+ "description": "25 tags per image name",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "FIFTY_TAGS",
+ "description": "50 tags per image name",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "ONE_HUNDRED_TAGS",
+ "description": "100 tags per image name",
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "possibleTypes": null
+ },
+ {
+ "kind": "ENUM",
+ "name": "ContainerExpirationPolicyOlderThanEnum",
+ "description": null,
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": [
+ {
+ "name": "SEVEN_DAYS",
+ "description": "7 days until tags are automatically removed",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "FOURTEEN_DAYS",
+ "description": "14 days until tags are automatically removed",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "THIRTY_DAYS",
+ "description": "30 days until tags are automatically removed",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "NINETY_DAYS",
+ "description": "90 days until tags are automatically removed",
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "possibleTypes": null
+ },
+ {
+ "kind": "INPUT_OBJECT",
"name": "CreateAlertIssueInput",
"description": "Autogenerated input type of CreateAlertIssue",
"fields": null,
@@ -3966,6 +4970,111 @@
"possibleTypes": null
},
{
+ "kind": "ENUM",
+ "name": "DastScanTypeEnum",
+ "description": null,
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": [
+ {
+ "name": "PASSIVE",
+ "description": "Passive DAST scan. This scan will not make active attacks against the target site.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "possibleTypes": null
+ },
+ {
+ "kind": "INPUT_OBJECT",
+ "name": "DeleteAnnotationInput",
+ "description": "Autogenerated input type of DeleteAnnotation",
+ "fields": null,
+ "inputFields": [
+ {
+ "name": "id",
+ "description": "The global id of the annotation to delete",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "ID",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "clientMutationId",
+ "description": "A unique identifier for the client performing the mutation.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "DeleteAnnotationPayload",
+ "description": "Autogenerated return type of DeleteAnnotation",
+ "fields": [
+ {
+ "name": "clientMutationId",
+ "description": "A unique identifier for the client performing the mutation.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "errors",
+ "description": "Errors encountered during execution of the mutation.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
"kind": "OBJECT",
"name": "DeleteJobsResponse",
"description": "The response from the AdminSidekiqQueuesDeleteJobs mutation.",
@@ -7134,11 +8243,79 @@
},
"isDeprecated": false,
"deprecationReason": null
+ },
+ {
+ "name": "resolvable",
+ "description": "Indicates if the object can be resolved",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "resolved",
+ "description": "Indicates if the object is resolved",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "resolvedAt",
+ "description": "Timestamp of when the object was resolved",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Time",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "resolvedBy",
+ "description": "User who resolved the object",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "User",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
-
+ {
+ "kind": "INTERFACE",
+ "name": "ResolvableInterface",
+ "ofType": null
+ }
],
"enumValues": null,
"possibleTypes": null
@@ -7257,6 +8434,122 @@
},
{
"kind": "INPUT_OBJECT",
+ "name": "DiscussionToggleResolveInput",
+ "description": "Autogenerated input type of DiscussionToggleResolve",
+ "fields": null,
+ "inputFields": [
+ {
+ "name": "id",
+ "description": "The global id of the discussion",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "ID",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "resolve",
+ "description": "Will resolve the discussion when true, and unresolve the discussion when false",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "clientMutationId",
+ "description": "A unique identifier for the client performing the mutation.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "DiscussionToggleResolvePayload",
+ "description": "Autogenerated return type of DiscussionToggleResolve",
+ "fields": [
+ {
+ "name": "clientMutationId",
+ "description": "A unique identifier for the client performing the mutation.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "discussion",
+ "description": "The discussion after mutation",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "Discussion",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "errors",
+ "description": "Errors encountered during execution of the mutation.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "INPUT_OBJECT",
"name": "DismissVulnerabilityInput",
"description": "Autogenerated input type of DismissVulnerability",
"fields": null,
@@ -12032,6 +13325,96 @@
"deprecationReason": null
},
{
+ "name": "label",
+ "description": "A label available on this group",
+ "args": [
+ {
+ "name": "title",
+ "description": "Title of the label",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "Label",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "labels",
+ "description": "Labels available on this group",
+ "args": [
+ {
+ "name": "after",
+ "description": "Returns the elements in the list that come after the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "before",
+ "description": "Returns the elements in the list that come before the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "first",
+ "description": "Returns the first _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "last",
+ "description": "Returns the last _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "searchTerm",
+ "description": "A search term to find labels with",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "LabelConnection",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "lfsEnabled",
"description": "Indicates if Large File Storage (LFS) is enabled for namespace",
"args": [
@@ -12740,6 +14123,237 @@
},
{
"kind": "OBJECT",
+ "name": "GroupMember",
+ "description": "Represents a Group Member",
+ "fields": [
+ {
+ "name": "accessLevel",
+ "description": "GitLab::Access level",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "AccessLevel",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "createdAt",
+ "description": "Date and time the membership was created",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Time",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "createdBy",
+ "description": "User that authorized membership",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "User",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "expiresAt",
+ "description": "Date and time the membership expires",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Time",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "group",
+ "description": "Group that a User is a member of",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "Group",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "updatedAt",
+ "description": "Date and time the membership was last updated",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Time",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "userPermissions",
+ "description": "Permissions for the current user on the resource",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "GroupPermissions",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+ {
+ "kind": "INTERFACE",
+ "name": "MemberInterface",
+ "ofType": null
+ }
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "GroupMemberConnection",
+ "description": "The connection type for GroupMember.",
+ "fields": [
+ {
+ "name": "edges",
+ "description": "A list of edges.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "GroupMemberEdge",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "nodes",
+ "description": "A list of nodes.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "GroupMember",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "pageInfo",
+ "description": "Information to aid in pagination.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "PageInfo",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "GroupMemberEdge",
+ "description": "An edge in a connection.",
+ "fields": [
+ {
+ "name": "cursor",
+ "description": "A cursor for use in pagination.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "node",
+ "description": "The item at the end of the edge.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "GroupMember",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
"name": "GroupPermissions",
"description": null,
"fields": [
@@ -15029,6 +16643,42 @@
"deprecationReason": null
},
{
+ "name": "failedToImportCount",
+ "description": "Count of issues that failed to import",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "importedIssuesCount",
+ "description": "Count of issues that were successfully imported",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "jiraProjectKey",
"description": "Project key for the imported Jira project",
"args": [
@@ -15073,6 +16723,24 @@
},
"isDeprecated": false,
"deprecationReason": null
+ },
+ {
+ "name": "totalIssueCount",
+ "description": "Total count of issues that were attempted to import",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
}
],
"inputFields": null,
@@ -15321,6 +16989,301 @@
"possibleTypes": null
},
{
+ "kind": "INPUT_OBJECT",
+ "name": "JiraImportUsersInput",
+ "description": "Autogenerated input type of JiraImportUsers",
+ "fields": null,
+ "inputFields": [
+ {
+ "name": "projectPath",
+ "description": "The project to import the Jira users into",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "ID",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "startAt",
+ "description": "The index of the record the import should started at, default 0 (50 records returned)",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "clientMutationId",
+ "description": "A unique identifier for the client performing the mutation.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "JiraImportUsersPayload",
+ "description": "Autogenerated return type of JiraImportUsers",
+ "fields": [
+ {
+ "name": "clientMutationId",
+ "description": "A unique identifier for the client performing the mutation.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "errors",
+ "description": "Errors encountered during execution of the mutation.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "jiraUsers",
+ "description": "Users returned from Jira, matched by email and name if possible.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "JiraUser",
+ "ofType": null
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "JiraProject",
+ "description": null,
+ "fields": [
+ {
+ "name": "key",
+ "description": "Key of the Jira project",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "name",
+ "description": "Name of the Jira project",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "projectId",
+ "description": "ID of the Jira project",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "JiraProjectConnection",
+ "description": "The connection type for JiraProject.",
+ "fields": [
+ {
+ "name": "edges",
+ "description": "A list of edges.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "JiraProjectEdge",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "nodes",
+ "description": "A list of nodes.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "JiraProject",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "pageInfo",
+ "description": "Information to aid in pagination.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "PageInfo",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "JiraProjectEdge",
+ "description": "An edge in a connection.",
+ "fields": [
+ {
+ "name": "cursor",
+ "description": "A cursor for use in pagination.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "node",
+ "description": "The item at the end of the edge.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "JiraProject",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
"kind": "OBJECT",
"name": "JiraService",
"description": null,
@@ -15340,6 +17303,69 @@
"deprecationReason": null
},
{
+ "name": "projects",
+ "description": "List of Jira projects fetched through Jira REST API",
+ "args": [
+ {
+ "name": "name",
+ "description": "Project name or key",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "after",
+ "description": "Returns the elements in the list that come after the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "before",
+ "description": "Returns the elements in the list that come before the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "first",
+ "description": "Returns the first _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "last",
+ "description": "Returns the last _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "JiraProjectConnection",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "type",
"description": "Class name of the service",
"args": [
@@ -15367,6 +17393,83 @@
},
{
"kind": "OBJECT",
+ "name": "JiraUser",
+ "description": null,
+ "fields": [
+ {
+ "name": "gitlabId",
+ "description": "Id of the matched GitLab user",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "jiraAccountId",
+ "description": "Account id of the Jira user",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "jiraDisplayName",
+ "description": "Display name of the Jira user",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "jiraEmail",
+ "description": "Email of the Jira user, returned only for users with public emails",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
"name": "Label",
"description": null,
"fields": [
@@ -15722,6 +17825,98 @@
"possibleTypes": null
},
{
+ "kind": "INTERFACE",
+ "name": "MemberInterface",
+ "description": null,
+ "fields": [
+ {
+ "name": "accessLevel",
+ "description": "GitLab::Access level",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "AccessLevel",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "createdAt",
+ "description": "Date and time the membership was created",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Time",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "createdBy",
+ "description": "User that authorized membership",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "User",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "expiresAt",
+ "description": "Date and time the membership expires",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Time",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "updatedAt",
+ "description": "Date and time the membership was last updated",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Time",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": [
+ {
+ "kind": "OBJECT",
+ "name": "GroupMember",
+ "ofType": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "ProjectMember",
+ "ofType": null
+ }
+ ]
+ },
+ {
"kind": "OBJECT",
"name": "MergeRequest",
"description": null,
@@ -15794,6 +17989,20 @@
"deprecationReason": null
},
{
+ "name": "author",
+ "description": "User who created this merge request",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "User",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "createdAt",
"description": "Timestamp of when the merge request was created",
"args": [
@@ -16208,6 +18417,20 @@
"deprecationReason": null
},
{
+ "name": "mergedAt",
+ "description": "Timestamp of when the merge request was merged, null if not merged",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Time",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "milestone",
"description": "The milestone of the merge request",
"args": [
@@ -16664,6 +18887,24 @@
"deprecationReason": null
},
{
+ "name": "targetBranchExists",
+ "description": "Indicates if the target branch of the merge request exists",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "targetProject",
"description": "Target project of the merge request",
"args": [
@@ -16965,6 +19206,160 @@
"possibleTypes": null
},
{
+ "kind": "INPUT_OBJECT",
+ "name": "MergeRequestCreateInput",
+ "description": "Autogenerated input type of MergeRequestCreate",
+ "fields": null,
+ "inputFields": [
+ {
+ "name": "projectPath",
+ "description": "Project full path the merge request is associated with",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "ID",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "title",
+ "description": "Title of the merge request",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "sourceBranch",
+ "description": "Source branch of the merge request",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "targetBranch",
+ "description": "Target branch of the merge request",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "description",
+ "description": "Description of the merge request (Markdown rendered as HTML for caching)",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "clientMutationId",
+ "description": "A unique identifier for the client performing the mutation.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "MergeRequestCreatePayload",
+ "description": "Autogenerated return type of MergeRequestCreate",
+ "fields": [
+ {
+ "name": "clientMutationId",
+ "description": "A unique identifier for the client performing the mutation.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "errors",
+ "description": "Errors encountered during execution of the mutation.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "mergeRequest",
+ "description": "The merge request after mutation",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "MergeRequest",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
"kind": "OBJECT",
"name": "MergeRequestEdge",
"description": "An edge in a connection.",
@@ -18157,6 +20552,28 @@
},
"isDeprecated": false,
"deprecationReason": null
+ },
+ {
+ "name": "schemaValidationWarnings",
+ "description": "Dashboard schema validation warnings",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
}
],
"inputFields": null,
@@ -18417,6 +20834,24 @@
"deprecationReason": null
},
{
+ "name": "groupMilestone",
+ "description": "Indicates if milestone is at group level",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "id",
"description": "ID of the milestone",
"args": [
@@ -18435,6 +20870,24 @@
"deprecationReason": null
},
{
+ "name": "projectMilestone",
+ "description": "Indicates if milestone is at project level",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "startDate",
"description": "Timestamp of the milestone start date",
"args": [
@@ -18467,6 +20920,24 @@
"deprecationReason": null
},
{
+ "name": "subgroupMilestone",
+ "description": "Indicates if milestone is at subgroup level",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "title",
"description": "Title of the milestone",
"args": [
@@ -18773,6 +21244,33 @@
"deprecationReason": null
},
{
+ "name": "alertSetAssignees",
+ "description": null,
+ "args": [
+ {
+ "name": "input",
+ "description": null,
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "INPUT_OBJECT",
+ "name": "AlertSetAssigneesInput",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "AlertSetAssigneesPayload",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "boardListUpdateLimitMetrics",
"description": null,
"args": [
@@ -18800,6 +21298,33 @@
"deprecationReason": null
},
{
+ "name": "commitCreate",
+ "description": null,
+ "args": [
+ {
+ "name": "input",
+ "description": null,
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "INPUT_OBJECT",
+ "name": "CommitCreateInput",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "CommitCreatePayload",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "createAlertIssue",
"description": null,
"args": [
@@ -19070,6 +21595,33 @@
"deprecationReason": null
},
{
+ "name": "deleteAnnotation",
+ "description": null,
+ "args": [
+ {
+ "name": "input",
+ "description": null,
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "INPUT_OBJECT",
+ "name": "DeleteAnnotationInput",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "DeleteAnnotationPayload",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "designManagementDelete",
"description": null,
"args": [
@@ -19178,6 +21730,33 @@
"deprecationReason": null
},
{
+ "name": "discussionToggleResolve",
+ "description": "Toggles the resolved state of a discussion",
+ "args": [
+ {
+ "name": "input",
+ "description": null,
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "INPUT_OBJECT",
+ "name": "DiscussionToggleResolveInput",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "DiscussionToggleResolvePayload",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "dismissVulnerability",
"description": null,
"args": [
@@ -19421,6 +22000,33 @@
"deprecationReason": null
},
{
+ "name": "jiraImportUsers",
+ "description": null,
+ "args": [
+ {
+ "name": "input",
+ "description": null,
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "INPUT_OBJECT",
+ "name": "JiraImportUsersInput",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "JiraImportUsersPayload",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "markAsSpamSnippet",
"description": null,
"args": [
@@ -19448,6 +22054,33 @@
"deprecationReason": null
},
{
+ "name": "mergeRequestCreate",
+ "description": null,
+ "args": [
+ {
+ "name": "input",
+ "description": null,
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "INPUT_OBJECT",
+ "name": "MergeRequestCreateInput",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "MergeRequestCreatePayload",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "mergeRequestSetAssignees",
"description": null,
"args": [
@@ -19664,6 +22297,33 @@
"deprecationReason": null
},
{
+ "name": "runDastScan",
+ "description": null,
+ "args": [
+ {
+ "name": "input",
+ "description": null,
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "INPUT_OBJECT",
+ "name": "RunDASTScanInput",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "RunDASTScanPayload",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "todoMarkDone",
"description": null,
"args": [
@@ -19826,6 +22486,33 @@
"deprecationReason": null
},
{
+ "name": "updateContainerExpirationPolicy",
+ "description": null,
+ "args": [
+ {
+ "name": "input",
+ "description": null,
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "INPUT_OBJECT",
+ "name": "UpdateContainerExpirationPolicyInput",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "UpdateContainerExpirationPolicyPayload",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "updateEpic",
"description": null,
"args": [
@@ -20549,7 +23236,25 @@
},
{
"name": "resolvable",
- "description": "Indicates if this note can be resolved. That is, if it is a resolvable discussion or simply a standalone note",
+ "description": "Indicates if the object can be resolved",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "resolved",
+ "description": "Indicates if the object is resolved",
"args": [
],
@@ -20567,7 +23272,7 @@
},
{
"name": "resolvedAt",
- "description": "Timestamp of the note's resolution",
+ "description": "Timestamp of when the object was resolved",
"args": [
],
@@ -20581,7 +23286,7 @@
},
{
"name": "resolvedBy",
- "description": "User that resolved the discussion",
+ "description": "User who resolved the object",
"args": [
],
@@ -20650,7 +23355,11 @@
],
"inputFields": null,
"interfaces": [
-
+ {
+ "kind": "INTERFACE",
+ "name": "ResolvableInterface",
+ "ofType": null
+ }
],
"enumValues": null,
"possibleTypes": null
@@ -20996,6 +23705,11 @@
"possibleTypes": [
{
"kind": "OBJECT",
+ "name": "AlertManagementAlert",
+ "ofType": null
+ },
+ {
+ "kind": "OBJECT",
"name": "Design",
"ofType": null
},
@@ -21772,6 +24486,20 @@
"deprecationReason": null
},
{
+ "name": "securityReportSummary",
+ "description": "Vulnerability and scanned resource counts for each security scanner of the pipeline",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "SecurityReportSummary",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "sha",
"description": "SHA of the pipeline's commit",
"args": [
@@ -22191,7 +24919,16 @@
"name": "alertManagementAlertStatusCounts",
"description": "Counts of alerts by status for the project",
"args": [
-
+ {
+ "name": "search",
+ "description": "Search criteria for filtering alerts. This will search on title, description, service, monitoring_tool.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
],
"type": {
"kind": "OBJECT",
@@ -22303,6 +25040,20 @@
"deprecationReason": null
},
{
+ "name": "allowMergeOnSkippedPipeline",
+ "description": "If `only_allow_merge_if_pipeline_succeeds` is true, indicates if merge requests of the project can also be merged with skipped jobs",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "archived",
"description": "Indicates the archived status of the project",
"args": [
@@ -22431,6 +25182,20 @@
"deprecationReason": null
},
{
+ "name": "containerExpirationPolicy",
+ "description": "The container expiration policy of the project",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "ContainerExpirationPolicy",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "containerRegistryEnabled",
"description": "Indicates if the project stores Docker container images in a container registry",
"args": [
@@ -23181,6 +25946,96 @@
"deprecationReason": null
},
{
+ "name": "label",
+ "description": "A label available on this project",
+ "args": [
+ {
+ "name": "title",
+ "description": "Title of the label",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "Label",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "labels",
+ "description": "Labels available on this project",
+ "args": [
+ {
+ "name": "after",
+ "description": "Returns the elements in the list that come after the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "before",
+ "description": "Returns the elements in the list that come before the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "first",
+ "description": "Returns the first _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "last",
+ "description": "Returns the last _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "searchTerm",
+ "description": "A search term to find labels with",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "LabelConnection",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "lastActivityAt",
"description": "Timestamp of the project last activity",
"args": [
@@ -23216,26 +26071,12 @@
"name": "iid",
"description": "IID of the merge request, for example `1`",
"type": {
- "kind": "SCALAR",
- "name": "String",
- "ofType": null
- },
- "defaultValue": null
- },
- {
- "name": "iids",
- "description": "Array of IIDs of merge requests, for example `[1, 2]`",
- "type": {
- "kind": "LIST",
+ "kind": "NON_NULL",
"name": null,
"ofType": {
- "kind": "NON_NULL",
- "name": null,
- "ofType": {
- "kind": "SCALAR",
- "name": "String",
- "ofType": null
- }
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
}
},
"defaultValue": null
@@ -23254,18 +26095,72 @@
"description": "Merge requests of the project",
"args": [
{
- "name": "iid",
- "description": "IID of the merge request, for example `1`",
+ "name": "iids",
+ "description": "Array of IIDs of merge requests, for example `[1, 2]`",
"type": {
- "kind": "SCALAR",
- "name": "String",
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "sourceBranches",
+ "description": "Array of source branch names. All resolved merge requests will have one of these branches as their source.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "targetBranches",
+ "description": "Array of target branch names. All resolved merge requests will have one of these branches as their target.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "state",
+ "description": "A merge request state. If provided, all resolved merge requests will have this state.",
+ "type": {
+ "kind": "ENUM",
+ "name": "MergeRequestState",
"ofType": null
},
"defaultValue": null
},
{
- "name": "iids",
- "description": "Array of IIDs of merge requests, for example `[1, 2]`",
+ "name": "labels",
+ "description": "Array of label names. All resolved merge requests will have all of these labels.",
"type": {
"kind": "LIST",
"name": null,
@@ -23522,6 +26417,33 @@
"deprecationReason": null
},
{
+ "name": "pipeline",
+ "description": "Build pipeline of the project",
+ "args": [
+ {
+ "name": "iid",
+ "description": "IID of the Pipeline, e.g., \"1\"",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "ID",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "Pipeline",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "pipelines",
"description": "Build pipelines of the project",
"args": [
@@ -23619,6 +26541,69 @@
"deprecationReason": null
},
{
+ "name": "projectMembers",
+ "description": "Members of the project",
+ "args": [
+ {
+ "name": "search",
+ "description": "Search query",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "after",
+ "description": "Returns the elements in the list that come after the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "before",
+ "description": "Returns the elements in the list that come before the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "first",
+ "description": "Returns the first _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "last",
+ "description": "Returns the last _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "ProjectMemberConnection",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "publicJobs",
"description": "Indicates if there is public access to pipelines and job details of the project, including output logs and artifacts",
"args": [
@@ -23805,6 +26790,34 @@
"ofType": null
},
"defaultValue": null
+ },
+ {
+ "name": "search",
+ "description": "Filter requirements by title search",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "authorUsername",
+ "description": "Filter requirements by author username",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null
}
],
"type": {
@@ -23882,6 +26895,34 @@
"defaultValue": null
},
{
+ "name": "search",
+ "description": "Filter requirements by title search",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "authorUsername",
+ "description": "Filter requirements by author username",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null
+ },
+ {
"name": "after",
"description": "Returns the elements in the list that come after the specified cursor.",
"type": {
@@ -24576,6 +27617,273 @@
},
{
"kind": "OBJECT",
+ "name": "ProjectMember",
+ "description": "Represents a Project Member",
+ "fields": [
+ {
+ "name": "accessLevel",
+ "description": "GitLab::Access level",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "AccessLevel",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "createdAt",
+ "description": "Date and time the membership was created",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Time",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "createdBy",
+ "description": "User that authorized membership",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "User",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "expiresAt",
+ "description": "Date and time the membership expires",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Time",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "id",
+ "description": "ID of the member",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "ID",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "project",
+ "description": "Project that User is a member of",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "Project",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "updatedAt",
+ "description": "Date and time the membership was last updated",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Time",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "user",
+ "description": "User that is associated with the member object",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "User",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "userPermissions",
+ "description": "Permissions for the current user on the resource",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "ProjectPermissions",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+ {
+ "kind": "INTERFACE",
+ "name": "MemberInterface",
+ "ofType": null
+ }
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "ProjectMemberConnection",
+ "description": "The connection type for ProjectMember.",
+ "fields": [
+ {
+ "name": "edges",
+ "description": "A list of edges.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "ProjectMemberEdge",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "nodes",
+ "description": "A list of nodes.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "ProjectMember",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "pageInfo",
+ "description": "Information to aid in pagination.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "PageInfo",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "ProjectMemberEdge",
+ "description": "An edge in a connection.",
+ "fields": [
+ {
+ "name": "cursor",
+ "description": "A cursor for use in pagination.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "node",
+ "description": "The item at the end of the edge.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "ProjectMember",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
"name": "ProjectPermissions",
"description": null,
"fields": [
@@ -25873,6 +29181,138 @@
"deprecationReason": null
},
{
+ "name": "user",
+ "description": "Find a user on this instance",
+ "args": [
+ {
+ "name": "id",
+ "description": "ID of the User",
+ "type": {
+ "kind": "SCALAR",
+ "name": "ID",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "username",
+ "description": "Username of the User",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "User",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "users",
+ "description": "Find users",
+ "args": [
+ {
+ "name": "ids",
+ "description": "List of user Global IDs",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "ID",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "usernames",
+ "description": "List of usernames",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "sort",
+ "description": "Sort users by this criteria",
+ "type": {
+ "kind": "ENUM",
+ "name": "Sort",
+ "ofType": null
+ },
+ "defaultValue": "created_desc"
+ },
+ {
+ "name": "after",
+ "description": "Returns the elements in the list that come after the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "before",
+ "description": "Returns the elements in the list that come before the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "first",
+ "description": "Returns the first _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "last",
+ "description": "Returns the last _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "UserConnection",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "vulnerabilities",
"description": "Vulnerabilities reported on projects on the current user's instance security dashboard",
"args": [
@@ -26127,6 +29567,20 @@
"description": null,
"fields": [
{
+ "name": "assets",
+ "description": "Assets of the release",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "ReleaseAssets",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "author",
"description": "User that created the release",
"args": [
@@ -26197,6 +29651,59 @@
"deprecationReason": null
},
{
+ "name": "evidences",
+ "description": "Evidence for the release",
+ "args": [
+ {
+ "name": "after",
+ "description": "Returns the elements in the list that come after the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "before",
+ "description": "Returns the elements in the list that come before the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "first",
+ "description": "Returns the first _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "last",
+ "description": "Returns the last _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "ReleaseEvidenceConnection",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "milestones",
"description": "Milestones associated to the release",
"args": [
@@ -26319,6 +29826,139 @@
},
{
"kind": "OBJECT",
+ "name": "ReleaseAssets",
+ "description": null,
+ "fields": [
+ {
+ "name": "assetsCount",
+ "description": "Number of assets of the release",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "links",
+ "description": "Asset links of the release",
+ "args": [
+ {
+ "name": "after",
+ "description": "Returns the elements in the list that come after the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "before",
+ "description": "Returns the elements in the list that come before the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "first",
+ "description": "Returns the first _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "last",
+ "description": "Returns the last _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "ReleaseLinkConnection",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "sources",
+ "description": "Sources of the release",
+ "args": [
+ {
+ "name": "after",
+ "description": "Returns the elements in the list that come after the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "before",
+ "description": "Returns the elements in the list that come before the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "first",
+ "description": "Returns the first _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "last",
+ "description": "Returns the last _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "ReleaseSourceConnection",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
"name": "ReleaseConnection",
"description": "The connection type for Release.",
"fields": [
@@ -26430,6 +30070,578 @@
"possibleTypes": null
},
{
+ "kind": "OBJECT",
+ "name": "ReleaseEvidence",
+ "description": "Evidence for a release",
+ "fields": [
+ {
+ "name": "collectedAt",
+ "description": "Timestamp when the evidence was collected",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Time",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "filepath",
+ "description": "URL from where the evidence can be downloaded",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "id",
+ "description": "ID of the evidence",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "ID",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "sha",
+ "description": "SHA1 ID of the evidence hash",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "ReleaseEvidenceConnection",
+ "description": "The connection type for ReleaseEvidence.",
+ "fields": [
+ {
+ "name": "edges",
+ "description": "A list of edges.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "ReleaseEvidenceEdge",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "nodes",
+ "description": "A list of nodes.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "ReleaseEvidence",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "pageInfo",
+ "description": "Information to aid in pagination.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "PageInfo",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "ReleaseEvidenceEdge",
+ "description": "An edge in a connection.",
+ "fields": [
+ {
+ "name": "cursor",
+ "description": "A cursor for use in pagination.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "node",
+ "description": "The item at the end of the edge.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "ReleaseEvidence",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "ReleaseLink",
+ "description": null,
+ "fields": [
+ {
+ "name": "external",
+ "description": "Indicates the link points to an external resource",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "id",
+ "description": "ID of the link",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "ID",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "linkType",
+ "description": "Type of the link: `other`, `runbook`, `image`, `package`; defaults to `other`",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "ENUM",
+ "name": "ReleaseLinkType",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "name",
+ "description": "Name of the link",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "url",
+ "description": "URL of the link",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "ReleaseLinkConnection",
+ "description": "The connection type for ReleaseLink.",
+ "fields": [
+ {
+ "name": "edges",
+ "description": "A list of edges.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "ReleaseLinkEdge",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "nodes",
+ "description": "A list of nodes.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "ReleaseLink",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "pageInfo",
+ "description": "Information to aid in pagination.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "PageInfo",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "ReleaseLinkEdge",
+ "description": "An edge in a connection.",
+ "fields": [
+ {
+ "name": "cursor",
+ "description": "A cursor for use in pagination.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "node",
+ "description": "The item at the end of the edge.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "ReleaseLink",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "ENUM",
+ "name": "ReleaseLinkType",
+ "description": "Type of the link: `other`, `runbook`, `image`, `package`; defaults to `other`",
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": [
+ {
+ "name": "OTHER",
+ "description": "Other link type",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "RUNBOOK",
+ "description": "Runbook link type",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "PACKAGE",
+ "description": "Package link type",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "IMAGE",
+ "description": "Image link type",
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "ReleaseSource",
+ "description": null,
+ "fields": [
+ {
+ "name": "format",
+ "description": "Format of the source",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "url",
+ "description": "Download URL of the source",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "ReleaseSourceConnection",
+ "description": "The connection type for ReleaseSource.",
+ "fields": [
+ {
+ "name": "edges",
+ "description": "A list of edges.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "ReleaseSourceEdge",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "nodes",
+ "description": "A list of nodes.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "ReleaseSource",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "pageInfo",
+ "description": "Information to aid in pagination.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "PageInfo",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "ReleaseSourceEdge",
+ "description": "An edge in a connection.",
+ "fields": [
+ {
+ "name": "cursor",
+ "description": "A cursor for use in pagination.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "node",
+ "description": "The item at the end of the edge.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "ReleaseSource",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
"kind": "INPUT_OBJECT",
"name": "RemoveAwardEmojiInput",
"description": "Autogenerated input type of RemoveAwardEmoji",
@@ -26742,7 +30954,7 @@
{
"kind": "OBJECT",
"name": "Requirement",
- "description": "Represents a requirement.",
+ "description": "Represents a requirement",
"fields": [
{
"name": "author",
@@ -26853,6 +31065,69 @@
"deprecationReason": null
},
{
+ "name": "testReports",
+ "description": "Test reports of the requirement",
+ "args": [
+ {
+ "name": "sort",
+ "description": "List test reports by sort order",
+ "type": {
+ "kind": "ENUM",
+ "name": "Sort",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "after",
+ "description": "Returns the elements in the list that come after the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "before",
+ "description": "Returns the elements in the list that come before the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "first",
+ "description": "Returns the first _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "last",
+ "description": "Returns the last _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "TestReportConnection",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "title",
"description": "Title of the requirement",
"args": [
@@ -27190,6 +31465,92 @@
"possibleTypes": null
},
{
+ "kind": "INTERFACE",
+ "name": "ResolvableInterface",
+ "description": null,
+ "fields": [
+ {
+ "name": "resolvable",
+ "description": "Indicates if the object can be resolved",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "resolved",
+ "description": "Indicates if the object is resolved",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "resolvedAt",
+ "description": "Timestamp of when the object was resolved",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Time",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "resolvedBy",
+ "description": "User who resolved the object",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "User",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": [
+ {
+ "kind": "OBJECT",
+ "name": "Discussion",
+ "ofType": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "Note",
+ "ofType": null
+ }
+ ]
+ },
+ {
"kind": "OBJECT",
"name": "RootStorageStatistics",
"description": null,
@@ -27311,6 +31672,274 @@
"possibleTypes": null
},
{
+ "kind": "INPUT_OBJECT",
+ "name": "RunDASTScanInput",
+ "description": "Autogenerated input type of RunDASTScan",
+ "fields": null,
+ "inputFields": [
+ {
+ "name": "projectPath",
+ "description": "The project the DAST scan belongs to.",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "ID",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "targetUrl",
+ "description": "The URL of the target to be scanned.",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "branch",
+ "description": "The branch to be associated with the scan.",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "scanType",
+ "description": "The type of scan to be run.",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "ENUM",
+ "name": "DastScanTypeEnum",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "clientMutationId",
+ "description": "A unique identifier for the client performing the mutation.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "RunDASTScanPayload",
+ "description": "Autogenerated return type of RunDASTScan",
+ "fields": [
+ {
+ "name": "clientMutationId",
+ "description": "A unique identifier for the client performing the mutation.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "errors",
+ "description": "Errors encountered during execution of the mutation.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "pipelineUrl",
+ "description": "URL of the pipeline that was created.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "SecurityReportSummary",
+ "description": "Represents summary of a security report",
+ "fields": [
+ {
+ "name": "containerScanning",
+ "description": "Aggregated counts for the container_scanning scan",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "SecurityReportSummarySection",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "dast",
+ "description": "Aggregated counts for the dast scan",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "SecurityReportSummarySection",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "dependencyScanning",
+ "description": "Aggregated counts for the dependency_scanning scan",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "SecurityReportSummarySection",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "sast",
+ "description": "Aggregated counts for the sast scan",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "SecurityReportSummarySection",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "secretDetection",
+ "description": "Aggregated counts for the secret_detection scan",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "SecurityReportSummarySection",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "SecurityReportSummarySection",
+ "description": "Represents a section of a summary of a security report",
+ "fields": [
+ {
+ "name": "scannedResourcesCount",
+ "description": "Total number of scanned resources",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "vulnerabilitiesCount",
+ "description": "Total number of vulnerabilities",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
"kind": "OBJECT",
"name": "SentryDetailedError",
"description": "A Sentry error.",
@@ -29085,11 +33714,25 @@
],
"type": {
+ "kind": "OBJECT",
+ "name": "User",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "blob",
+ "description": "Snippet blob",
+ "args": [
+
+ ],
+ "type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
- "name": "User",
+ "name": "SnippetBlob",
"ofType": null
}
},
@@ -29097,8 +33740,8 @@
"deprecationReason": null
},
{
- "name": "blob",
- "description": "Snippet blob",
+ "name": "blobs",
+ "description": "Snippet blobs",
"args": [
],
@@ -29106,9 +33749,17 @@
"kind": "NON_NULL",
"name": null,
"ofType": {
- "kind": "OBJECT",
- "name": "SnippetBlob",
- "ofType": null
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "SnippetBlob",
+ "ofType": null
+ }
+ }
}
},
"isDeprecated": false,
@@ -30397,6 +35048,216 @@
"possibleTypes": null
},
{
+ "kind": "OBJECT",
+ "name": "TestReport",
+ "description": "Represents a requirement test report.",
+ "fields": [
+ {
+ "name": "author",
+ "description": "Author of the test report",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "User",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "createdAt",
+ "description": "Timestamp of when the test report was created",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Time",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "id",
+ "description": "ID of the test report",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "ID",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "state",
+ "description": "State of the test report",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "ENUM",
+ "name": "TestReportState",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "TestReportConnection",
+ "description": "The connection type for TestReport.",
+ "fields": [
+ {
+ "name": "edges",
+ "description": "A list of edges.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "TestReportEdge",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "nodes",
+ "description": "A list of nodes.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "TestReport",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "pageInfo",
+ "description": "Information to aid in pagination.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "PageInfo",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "TestReportEdge",
+ "description": "An edge in a connection.",
+ "fields": [
+ {
+ "name": "cursor",
+ "description": "A cursor for use in pagination.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "node",
+ "description": "The item at the end of the edge.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "TestReport",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "ENUM",
+ "name": "TestReportState",
+ "description": "State of a test report",
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": [
+ {
+ "name": "PASSED",
+ "description": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "possibleTypes": null
+ },
+ {
"kind": "SCALAR",
"name": "Time",
"description": "Time represented in ISO 8601",
@@ -32195,6 +37056,148 @@
},
{
"kind": "INPUT_OBJECT",
+ "name": "UpdateContainerExpirationPolicyInput",
+ "description": "Autogenerated input type of UpdateContainerExpirationPolicy",
+ "fields": null,
+ "inputFields": [
+ {
+ "name": "projectPath",
+ "description": "The project path where the container expiration policy is located",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "ID",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "enabled",
+ "description": "Indicates whether this container expiration policy is enabled",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "cadence",
+ "description": "This container expiration policy schedule",
+ "type": {
+ "kind": "ENUM",
+ "name": "ContainerExpirationPolicyCadenceEnum",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "olderThan",
+ "description": "Tags older that this will expire",
+ "type": {
+ "kind": "ENUM",
+ "name": "ContainerExpirationPolicyOlderThanEnum",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "keepN",
+ "description": "Number of tags to retain",
+ "type": {
+ "kind": "ENUM",
+ "name": "ContainerExpirationPolicyKeepEnum",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "clientMutationId",
+ "description": "A unique identifier for the client performing the mutation.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "UpdateContainerExpirationPolicyPayload",
+ "description": "Autogenerated return type of UpdateContainerExpirationPolicy",
+ "fields": [
+ {
+ "name": "clientMutationId",
+ "description": "A unique identifier for the client performing the mutation.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "containerExpirationPolicy",
+ "description": "The container expiration policy after mutation",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "ContainerExpirationPolicy",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "errors",
+ "description": "Errors encountered during execution of the mutation.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "INPUT_OBJECT",
"name": "UpdateDiffImagePositionInput",
"description": null,
"fields": null,
@@ -33184,6 +38187,316 @@
"description": null,
"fields": [
{
+ "name": "assignedMergeRequests",
+ "description": "Merge Requests assigned to the user",
+ "args": [
+ {
+ "name": "iids",
+ "description": "Array of IIDs of merge requests, for example `[1, 2]`",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "sourceBranches",
+ "description": "Array of source branch names. All resolved merge requests will have one of these branches as their source.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "targetBranches",
+ "description": "Array of target branch names. All resolved merge requests will have one of these branches as their target.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "state",
+ "description": "A merge request state. If provided, all resolved merge requests will have this state.",
+ "type": {
+ "kind": "ENUM",
+ "name": "MergeRequestState",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "labels",
+ "description": "Array of label names. All resolved merge requests will have all of these labels.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "projectPath",
+ "description": "The full-path of the project the authored merge requests should be in. Incompatible with projectId.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "projectId",
+ "description": "The global ID of the project the authored merge requests should be in. Incompatible with projectPath.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "ID",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "after",
+ "description": "Returns the elements in the list that come after the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "before",
+ "description": "Returns the elements in the list that come before the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "first",
+ "description": "Returns the first _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "last",
+ "description": "Returns the last _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "MergeRequestConnection",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "authoredMergeRequests",
+ "description": "Merge Requests authored by the user",
+ "args": [
+ {
+ "name": "iids",
+ "description": "Array of IIDs of merge requests, for example `[1, 2]`",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "sourceBranches",
+ "description": "Array of source branch names. All resolved merge requests will have one of these branches as their source.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "targetBranches",
+ "description": "Array of target branch names. All resolved merge requests will have one of these branches as their target.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "state",
+ "description": "A merge request state. If provided, all resolved merge requests will have this state.",
+ "type": {
+ "kind": "ENUM",
+ "name": "MergeRequestState",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "labels",
+ "description": "Array of label names. All resolved merge requests will have all of these labels.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "projectPath",
+ "description": "The full-path of the project the authored merge requests should be in. Incompatible with projectId.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "projectId",
+ "description": "The global ID of the project the authored merge requests should be in. Incompatible with projectPath.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "ID",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "after",
+ "description": "Returns the elements in the list that come after the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "before",
+ "description": "Returns the elements in the list that come before the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "first",
+ "description": "Returns the first _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "last",
+ "description": "Returns the last _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "MergeRequestConnection",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "avatarUrl",
"description": "URL of the user's avatar",
"args": [
@@ -33198,6 +38511,59 @@
"deprecationReason": null
},
{
+ "name": "groupMemberships",
+ "description": "Group memberships of the user",
+ "args": [
+ {
+ "name": "after",
+ "description": "Returns the elements in the list that come after the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "before",
+ "description": "Returns the elements in the list that come before the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "first",
+ "description": "Returns the first _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "last",
+ "description": "Returns the last _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "GroupMemberConnection",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "id",
"description": "ID of the user",
"args": [
@@ -33234,6 +38600,59 @@
"deprecationReason": null
},
{
+ "name": "projectMemberships",
+ "description": "Project memberships of the user",
+ "args": [
+ {
+ "name": "after",
+ "description": "Returns the elements in the list that come after the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "before",
+ "description": "Returns the elements in the list that come before the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "first",
+ "description": "Returns the first _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "last",
+ "description": "Returns the last _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "ProjectMemberConnection",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "snippets",
"description": "Snippets authored by the user",
"args": [
@@ -33326,7 +38745,7 @@
},
{
"name": "state",
- "description": "State of the issue",
+ "description": "State of the user",
"args": [
],
@@ -33334,8 +38753,8 @@
"kind": "NON_NULL",
"name": null,
"ofType": {
- "kind": "SCALAR",
- "name": "String",
+ "kind": "ENUM",
+ "name": "UserState",
"ofType": null
}
},
@@ -33714,6 +39133,35 @@
},
{
"kind": "ENUM",
+ "name": "UserState",
+ "description": "Possible states of a user",
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": [
+ {
+ "name": "active",
+ "description": "The user is active and is able to use the system",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "blocked",
+ "description": "The user has been blocked and is prevented from using the system",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "deactivated",
+ "description": "The user is no longer active and is unable to use the system",
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "possibleTypes": null
+ },
+ {
+ "kind": "ENUM",
"name": "VisibilityLevelsEnum",
"description": null,
"fields": null,
@@ -33975,6 +39423,73 @@
"deprecationReason": null
},
{
+ "name": "issueLinks",
+ "description": "List of issue links related to the vulnerability",
+ "args": [
+ {
+ "name": "linkType",
+ "description": "Filter issue links by link type",
+ "type": {
+ "kind": "ENUM",
+ "name": "VulnerabilityIssueLinkType",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "after",
+ "description": "Returns the elements in the list that come after the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "before",
+ "description": "Returns the elements in the list that come before the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "first",
+ "description": "Returns the first _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "last",
+ "description": "Returns the last _n_ elements from the list.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "VulnerabilityIssueLinkConnection",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "location",
"description": "Location metadata for the vulnerability. Its fields depend on the type of security scan that found the vulnerability",
"args": [
@@ -34004,7 +39519,7 @@
},
{
"name": "reportType",
- "description": "Type of the security report that found the vulnerability (SAST, DEPENDENCY_SCANNING, CONTAINER_SCANNING, DAST)",
+ "description": "Type of the security report that found the vulnerability (SAST, DEPENDENCY_SCANNING, CONTAINER_SCANNING, DAST, SECRET_DETECTION)",
"args": [
],
@@ -34059,6 +39574,24 @@
"deprecationReason": null
},
{
+ "name": "userNotesCount",
+ "description": "Number of user notes attached to the vulnerability",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "userPermissions",
"description": "Permissions for the current user on the resource",
"args": [
@@ -34211,6 +39744,208 @@
"possibleTypes": null
},
{
+ "kind": "OBJECT",
+ "name": "VulnerabilityIssueLink",
+ "description": "Represents an issue link of a vulnerability.",
+ "fields": [
+ {
+ "name": "id",
+ "description": "GraphQL ID of the vulnerability",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "ID",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "issue",
+ "description": "The issue attached to issue link",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "Issue",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "linkType",
+ "description": "Type of the issue link",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "ENUM",
+ "name": "VulnerabilityIssueLinkType",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "VulnerabilityIssueLinkConnection",
+ "description": "The connection type for VulnerabilityIssueLink.",
+ "fields": [
+ {
+ "name": "edges",
+ "description": "A list of edges.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "VulnerabilityIssueLinkEdge",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "nodes",
+ "description": "A list of nodes.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "VulnerabilityIssueLink",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "pageInfo",
+ "description": "Information to aid in pagination.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "PageInfo",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "VulnerabilityIssueLinkEdge",
+ "description": "An edge in a connection.",
+ "fields": [
+ {
+ "name": "cursor",
+ "description": "A cursor for use in pagination.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "node",
+ "description": "The item at the end of the edge.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "VulnerabilityIssueLink",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "ENUM",
+ "name": "VulnerabilityIssueLinkType",
+ "description": "The type of the issue link related to a vulnerability.",
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": [
+ {
+ "name": "RELATED",
+ "description": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "CREATED",
+ "description": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "possibleTypes": null
+ },
+ {
"kind": "UNION",
"name": "VulnerabilityLocation",
"description": "Represents a vulnerability location. The fields with data will depend on the vulnerability report type",
@@ -34238,6 +39973,11 @@
"kind": "OBJECT",
"name": "VulnerabilityLocationSast",
"ofType": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "VulnerabilityLocationSecretDetection",
+ "ofType": null
}
]
},
@@ -34491,6 +40231,89 @@
},
{
"kind": "OBJECT",
+ "name": "VulnerabilityLocationSecretDetection",
+ "description": "Represents the location of a vulnerability found by a secret detection scan",
+ "fields": [
+ {
+ "name": "endLine",
+ "description": "Number of the last relevant line in the vulnerable file",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "file",
+ "description": "Path to the vulnerable file",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "startLine",
+ "description": "Number of the first relevant line in the vulnerable file",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "vulnerableClass",
+ "description": "Class containing the vulnerability",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "vulnerableMethod",
+ "description": "Method containing the vulnerability",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
"name": "VulnerabilityPermissions",
"description": "Check permissions for the current user on a vulnerability",
"fields": [
@@ -34677,6 +40500,12 @@
"description": null,
"isDeprecated": false,
"deprecationReason": null
+ },
+ {
+ "name": "SECRET_DETECTION",
+ "description": null,
+ "isDeprecated": false,
+ "deprecationReason": null
}
],
"possibleTypes": null
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 4164c26e751..befb57c1cba 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -16,6 +16,15 @@ fields and methods on a model are available via GraphQL.
CAUTION: **Caution:**
Fields that are deprecated are marked with **{warning-solid}**.
+## AccessLevel
+
+Represents the access level of a relationship between a User and object that it is related to
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `integerValue` | Int | Integer representation of access level |
+| `stringValue` | AccessLevelEnum | String representation of access level |
+
## AddAwardEmojiPayload
Autogenerated return type of AddAwardEmoji
@@ -81,6 +90,17 @@ Represents total number of alerts for the represented categories
| `resolved` | Int | Number of alerts with status RESOLVED for the project |
| `triggered` | Int | Number of alerts with status TRIGGERED for the project |
+## AlertSetAssigneesPayload
+
+Autogenerated return type of AlertSetAssignees
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `alert` | AlertManagementAlert | The alert after mutation |
+| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
+| `errors` | String! => Array | Errors encountered during execution of the mutation. |
+| `issue` | Issue | The issue created after mutation |
+
## AwardEmoji
An emoji awarded by a user.
@@ -177,6 +197,32 @@ Autogenerated return type of BoardListUpdateLimitMetrics
| `titleHtml` | String | The GitLab Flavored Markdown rendering of `title` |
| `webUrl` | String! | Web URL of the commit |
+## CommitCreatePayload
+
+Autogenerated return type of CommitCreate
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
+| `commit` | Commit | The commit after mutation |
+| `errors` | String! => Array | Errors encountered during execution of the mutation. |
+
+## ContainerExpirationPolicy
+
+A tag expiration policy designed to keep only the images that matter most
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `cadence` | ContainerExpirationPolicyCadenceEnum! | This container expiration policy schedule |
+| `createdAt` | Time! | Timestamp of when the container expiration policy was created |
+| `enabled` | Boolean! | Indicates whether this container expiration policy is enabled |
+| `keepN` | ContainerExpirationPolicyKeepEnum | Number of tags to retain |
+| `nameRegex` | String | Tags with names matching this regex pattern will expire |
+| `nameRegexKeep` | String | Tags with names matching this regex pattern will be preserved |
+| `nextRunAt` | Time | Next time that this container expiration policy will get executed |
+| `olderThan` | ContainerExpirationPolicyOlderThanEnum | Tags older that this will expire |
+| `updatedAt` | Time! | Timestamp of when the container expiration policy was updated |
+
## CreateAlertIssuePayload
Autogenerated return type of CreateAlertIssue
@@ -278,6 +324,15 @@ Autogenerated return type of CreateSnippet
| `errors` | String! => Array | Errors encountered during execution of the mutation. |
| `snippet` | Snippet | The snippet after mutation |
+## DeleteAnnotationPayload
+
+Autogenerated return type of DeleteAnnotation
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
+| `errors` | String! => Array | Errors encountered during execution of the mutation. |
+
## DeleteJobsResponse
The response from the AdminSidekiqQueuesDeleteJobs mutation.
@@ -438,6 +493,20 @@ Autogenerated return type of DestroySnippet
| `createdAt` | Time! | Timestamp of the discussion's creation |
| `id` | ID! | ID of this discussion |
| `replyId` | ID! | ID used to reply to this discussion |
+| `resolvable` | Boolean! | Indicates if the object can be resolved |
+| `resolved` | Boolean! | Indicates if the object is resolved |
+| `resolvedAt` | Time | Timestamp of when the object was resolved |
+| `resolvedBy` | User | User who resolved the object |
+
+## DiscussionToggleResolvePayload
+
+Autogenerated return type of DiscussionToggleResolve
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
+| `discussion` | Discussion | The discussion after mutation |
+| `errors` | String! => Array | Errors encountered during execution of the mutation. |
## DismissVulnerabilityPayload
@@ -665,6 +734,7 @@ Autogenerated return type of EpicTreeReorder
| `fullPath` | ID! | Full path of the namespace |
| `groupTimelogsEnabled` | Boolean | Indicates if Group timelogs are enabled for namespace |
| `id` | ID! | ID of the namespace |
+| `label` | Label | A label available on this group |
| `lfsEnabled` | Boolean | Indicates if Large File Storage (LFS) is enabled for namespace |
| `mentionsDisabled` | Boolean | Indicates if a group is disabled from getting mentioned |
| `name` | String! | Name of the namespace |
@@ -681,6 +751,20 @@ Autogenerated return type of EpicTreeReorder
| `visibility` | String | Visibility of the namespace |
| `webUrl` | String! | Web URL of the group |
+## GroupMember
+
+Represents a Group Member
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `accessLevel` | AccessLevel | GitLab::Access level |
+| `createdAt` | Time | Date and time the membership was created |
+| `createdBy` | User | User that authorized membership |
+| `expiresAt` | Time | Date and time the membership expires |
+| `group` | Group | Group that a User is a member of |
+| `updatedAt` | Time | Date and time the membership was last updated |
+| `userPermissions` | GroupPermissions! | Permissions for the current user on the resource |
+
## GroupPermissions
| Name | Type | Description |
@@ -801,9 +885,12 @@ Represents an iteration object.
| Name | Type | Description |
| --- | ---- | ---------- |
| `createdAt` | Time | Timestamp of when the Jira import was created |
+| `failedToImportCount` | Int! | Count of issues that failed to import |
+| `importedIssuesCount` | Int! | Count of issues that were successfully imported |
| `jiraProjectKey` | String! | Project key for the imported Jira project |
| `scheduledAt` | Time | Timestamp of when the Jira import was scheduled |
| `scheduledBy` | User | User that started the Jira import |
+| `totalIssueCount` | Int! | Total count of issues that were attempted to import |
## JiraImportStartPayload
@@ -815,13 +902,41 @@ Autogenerated return type of JiraImportStart
| `errors` | String! => Array | Errors encountered during execution of the mutation. |
| `jiraImport` | JiraImport | The Jira import data after mutation |
+## JiraImportUsersPayload
+
+Autogenerated return type of JiraImportUsers
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
+| `errors` | String! => Array | Errors encountered during execution of the mutation. |
+| `jiraUsers` | JiraUser! => Array | Users returned from Jira, matched by email and name if possible. |
+
+## JiraProject
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `key` | String! | Key of the Jira project |
+| `name` | String | Name of the Jira project |
+| `projectId` | Int! | ID of the Jira project |
+
## JiraService
| Name | Type | Description |
| --- | ---- | ---------- |
| `active` | Boolean | Indicates if the service is active |
+| `projects` | JiraProjectConnection | List of Jira projects fetched through Jira REST API |
| `type` | String | Class name of the service |
+## JiraUser
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `gitlabId` | Int | Id of the matched GitLab user |
+| `jiraAccountId` | String! | Account id of the Jira user |
+| `jiraDisplayName` | String! | Display name of the Jira user |
+| `jiraEmail` | String | Email of the Jira user, returned only for users with public emails |
+
## Label
| Name | Type | Description |
@@ -848,6 +963,7 @@ Autogenerated return type of MarkAsSpamSnippet
| Name | Type | Description |
| --- | ---- | ---------- |
| `allowCollaboration` | Boolean | Indicates if members of the target project can push to the fork |
+| `author` | User | User who created this merge request |
| `createdAt` | Time! | Timestamp of when the merge request was created |
| `defaultMergeCommitMessage` | String | Default merge commit message of the merge request |
| `description` | String | Description of the merge request (Markdown rendered as HTML for caching) |
@@ -868,6 +984,7 @@ Autogenerated return type of MarkAsSpamSnippet
| `mergeStatus` | String | Status of the merge request |
| `mergeWhenPipelineSucceeds` | Boolean | Indicates if the merge has been set to be merged when its pipeline succeeds (MWPS) |
| `mergeableDiscussionsState` | Boolean | Indicates if all discussions in the merge request have been resolved, allowing the merge request to be merged |
+| `mergedAt` | Time | Timestamp of when the merge request was merged, null if not merged |
| `milestone` | Milestone | The milestone of the merge request |
| `project` | Project! | Alias for target_project |
| `projectId` | Int! | ID of the merge request project |
@@ -883,6 +1000,7 @@ Autogenerated return type of MarkAsSpamSnippet
| `state` | MergeRequestState! | State of the merge request |
| `subscribed` | Boolean! | Indicates if the currently logged in user is subscribed to this merge request |
| `targetBranch` | String! | Target branch of the merge request |
+| `targetBranchExists` | Boolean! | Indicates if the target branch of the merge request exists |
| `targetProject` | Project! | Target project of the merge request |
| `targetProjectId` | Int! | ID of the merge request target project |
| `taskCompletionStatus` | TaskCompletionStatus! | Completion status of tasks |
@@ -897,6 +1015,16 @@ Autogenerated return type of MarkAsSpamSnippet
| `webUrl` | String | Web URL of the merge request |
| `workInProgress` | Boolean! | Indicates if the merge request is a work in progress (WIP) |
+## MergeRequestCreatePayload
+
+Autogenerated return type of MergeRequestCreate
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
+| `errors` | String! => Array | Errors encountered during execution of the mutation. |
+| `mergeRequest` | MergeRequest | The merge request after mutation |
+
## MergeRequestPermissions
Check permissions for the current user on a merge request
@@ -984,6 +1112,7 @@ Autogenerated return type of MergeRequestSetWip
| Name | Type | Description |
| --- | ---- | ---------- |
| `path` | String | Path to a file with the dashboard definition |
+| `schemaValidationWarnings` | String! => Array | Dashboard schema validation warnings |
## MetricsDashboardAnnotation
@@ -1004,9 +1133,12 @@ Represents a milestone.
| `createdAt` | Time! | Timestamp of milestone creation |
| `description` | String | Description of the milestone |
| `dueDate` | Time | Timestamp of the milestone due date |
+| `groupMilestone` | Boolean! | Indicates if milestone is at group level |
| `id` | ID! | ID of the milestone |
+| `projectMilestone` | Boolean! | Indicates if milestone is at project level |
| `startDate` | Time | Timestamp of the milestone start date |
| `state` | MilestoneStateEnum! | State of the milestone |
+| `subgroupMilestone` | Boolean! | Indicates if milestone is at subgroup level |
| `title` | String! | Title of the milestone |
| `updatedAt` | Time! | Timestamp of last milestone update |
| `webPath` | String! | Web path of the milestone |
@@ -1040,9 +1172,10 @@ Represents a milestone.
| `id` | ID! | ID of the note |
| `position` | DiffPosition | The position of this note on a diff |
| `project` | Project | Project associated with the note |
-| `resolvable` | Boolean! | Indicates if this note can be resolved. That is, if it is a resolvable discussion or simply a standalone note |
-| `resolvedAt` | Time | Timestamp of the note's resolution |
-| `resolvedBy` | User | User that resolved the discussion |
+| `resolvable` | Boolean! | Indicates if the object can be resolved |
+| `resolved` | Boolean! | Indicates if the object is resolved |
+| `resolvedAt` | Time | Timestamp of when the object was resolved |
+| `resolvedBy` | User | User who resolved the object |
| `system` | Boolean! | Indicates whether this note was created by the system or by a user |
| `updatedAt` | Time! | Timestamp of the note's last activity |
| `userPermissions` | NotePermissions! | Permissions for the current user on the resource |
@@ -1109,6 +1242,7 @@ Information about pagination in a connection.
| `finishedAt` | Time | Timestamp of the pipeline's completion |
| `id` | ID! | ID of the pipeline |
| `iid` | String! | Internal ID of the pipeline |
+| `securityReportSummary` | SecurityReportSummary | Vulnerability and scanned resource counts for each security scanner of the pipeline |
| `sha` | String! | SHA of the pipeline's commit |
| `startedAt` | Time | Timestamp when the pipeline was started |
| `status` | PipelineStatusEnum! | Status of the pipeline (CREATED, WAITING_FOR_RESOURCE, PREPARING, PENDING, RUNNING, FAILED, SUCCESS, CANCELED, SKIPPED, MANUAL, SCHEDULED) |
@@ -1129,10 +1263,12 @@ Information about pagination in a connection.
| --- | ---- | ---------- |
| `alertManagementAlert` | AlertManagementAlert | A single Alert Management alert of the project |
| `alertManagementAlertStatusCounts` | AlertManagementAlertStatusCountsType | Counts of alerts by status for the project |
+| `allowMergeOnSkippedPipeline` | Boolean | If `only_allow_merge_if_pipeline_succeeds` is true, indicates if merge requests of the project can also be merged with skipped jobs |
| `archived` | Boolean | Indicates the archived status of the project |
| `autocloseReferencedIssues` | Boolean | Indicates if issues referenced by merge requests and commits within the default branch are closed automatically |
| `avatarUrl` | String | URL to avatar image file of the project |
| `board` | Board | A single board of the project |
+| `containerExpirationPolicy` | ContainerExpirationPolicy | The container expiration policy of the project |
| `containerRegistryEnabled` | Boolean | Indicates if the project stores Docker container images in a container registry |
| `createdAt` | Time | Timestamp of the project creation |
| `description` | String | Short description of the project |
@@ -1148,6 +1284,7 @@ Information about pagination in a connection.
| `issuesEnabled` | Boolean | Indicates if Issues are enabled for the current user |
| `jiraImportStatus` | String | Status of Jira import background job of the project |
| `jobsEnabled` | Boolean | Indicates if CI/CD pipeline jobs are enabled for the current user |
+| `label` | Label | A label available on this project |
| `lastActivityAt` | Time | Timestamp of the project last activity |
| `lfsEnabled` | Boolean | Indicates if the project has Large File Storage (LFS) enabled |
| `mergeRequest` | MergeRequest | A single merge request of the project |
@@ -1160,6 +1297,7 @@ Information about pagination in a connection.
| `onlyAllowMergeIfPipelineSucceeds` | Boolean | Indicates if merge requests of the project can only be merged with successful jobs |
| `openIssuesCount` | Int | Number of open issues for the project |
| `path` | String! | Path of the project |
+| `pipeline` | Pipeline | Build pipeline of the project |
| `printingMergeRequestLinkEnabled` | 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 |
| `publicJobs` | Boolean | Indicates if there is public access to pipelines and job details of the project, including output logs and artifacts |
| `release` | Release | A single release of the project. Available only when feature flag `graphql_release_data` is enabled |
@@ -1185,6 +1323,22 @@ Information about pagination in a connection.
| `webUrl` | String | Web URL of the project |
| `wikiEnabled` | Boolean | Indicates if Wikis are enabled for the current user |
+## ProjectMember
+
+Represents a Project Member
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `accessLevel` | AccessLevel | GitLab::Access level |
+| `createdAt` | Time | Date and time the membership was created |
+| `createdBy` | User | User that authorized membership |
+| `expiresAt` | Time | Date and time the membership expires |
+| `id` | ID! | ID of the member |
+| `project` | Project | Project that User is a member of |
+| `updatedAt` | Time | Date and time the membership was last updated |
+| `user` | User! | User that is associated with the member object |
+| `userPermissions` | ProjectPermissions! | Permissions for the current user on the resource |
+
## ProjectPermissions
| Name | Type | Description |
@@ -1248,6 +1402,7 @@ Information about pagination in a connection.
| Name | Type | Description |
| --- | ---- | ---------- |
+| `assets` | ReleaseAssets | Assets of the release |
| `author` | User | User that created the release |
| `commit` | Commit | The commit associated with the release |
| `createdAt` | Time | Timestamp of when the release was created |
@@ -1258,6 +1413,40 @@ Information about pagination in a connection.
| `tagName` | String! | Name of the tag associated with the release |
| `tagPath` | String | Relative web path to the tag associated with the release |
+## ReleaseAssets
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `assetsCount` | Int | Number of assets of the release |
+
+## ReleaseEvidence
+
+Evidence for a release
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `collectedAt` | Time | Timestamp when the evidence was collected |
+| `filepath` | String | URL from where the evidence can be downloaded |
+| `id` | ID! | ID of the evidence |
+| `sha` | String | SHA1 ID of the evidence hash |
+
+## ReleaseLink
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `external` | Boolean | Indicates the link points to an external resource |
+| `id` | ID! | ID of the link |
+| `linkType` | ReleaseLinkType | Type of the link: `other`, `runbook`, `image`, `package`; defaults to `other` |
+| `name` | String | Name of the link |
+| `url` | String | URL of the link |
+
+## ReleaseSource
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `format` | String | Format of the source |
+| `url` | String | Download URL of the source |
+
## RemoveAwardEmojiPayload
Autogenerated return type of RemoveAwardEmoji
@@ -1288,7 +1477,7 @@ Autogenerated return type of RemoveProjectFromSecurityDashboard
## Requirement
-Represents a requirement.
+Represents a requirement
| Name | Type | Description |
| --- | ---- | ---------- |
@@ -1334,6 +1523,37 @@ Counts of requirements by their state.
| `storageSize` | Float! | The total storage in bytes |
| `wikiSize` | Float! | The wiki size in bytes |
+## RunDASTScanPayload
+
+Autogenerated return type of RunDASTScan
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
+| `errors` | String! => Array | Errors encountered during execution of the mutation. |
+| `pipelineUrl` | String | URL of the pipeline that was created. |
+
+## SecurityReportSummary
+
+Represents summary of a security report
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `containerScanning` | SecurityReportSummarySection | Aggregated counts for the container_scanning scan |
+| `dast` | SecurityReportSummarySection | Aggregated counts for the dast scan |
+| `dependencyScanning` | SecurityReportSummarySection | Aggregated counts for the dependency_scanning scan |
+| `sast` | SecurityReportSummarySection | Aggregated counts for the sast scan |
+| `secretDetection` | SecurityReportSummarySection | Aggregated counts for the secret_detection scan |
+
+## SecurityReportSummarySection
+
+Represents a section of a summary of a security report
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `scannedResourcesCount` | Int | Total number of scanned resources |
+| `vulnerabilitiesCount` | Int | Total number of vulnerabilities |
+
## SentryDetailedError
A Sentry error.
@@ -1455,8 +1675,9 @@ Represents a snippet entry
| Name | Type | Description |
| --- | ---- | ---------- |
-| `author` | User! | The owner of the snippet |
+| `author` | User | The owner of the snippet |
| `blob` | SnippetBlob! | Snippet blob |
+| `blobs` | SnippetBlob! => Array | Snippet blobs |
| `createdAt` | Time! | Timestamp this snippet was created |
| `description` | String | Description of the snippet |
| `descriptionHtml` | String | The GitLab Flavored Markdown rendering of `description` |
@@ -1538,6 +1759,17 @@ Completion status of tasks
| `completedCount` | Int! | Number of completed tasks |
| `count` | Int! | Number of total tasks |
+## TestReport
+
+Represents a requirement test report.
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `author` | User | Author of the test report |
+| `createdAt` | Time! | Timestamp of when the test report was created |
+| `id` | ID! | ID of the test report |
+| `state` | TestReportState! | State of the test report |
+
## Timelog
| Name | Type | Description |
@@ -1646,6 +1878,16 @@ Autogenerated return type of UpdateAlertStatus
| `errors` | String! => Array | Errors encountered during execution of the mutation. |
| `issue` | Issue | The issue created after mutation |
+## UpdateContainerExpirationPolicyPayload
+
+Autogenerated return type of UpdateContainerExpirationPolicy
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
+| `containerExpirationPolicy` | ContainerExpirationPolicy | The container expiration policy after mutation |
+| `errors` | String! => Array | Errors encountered during execution of the mutation. |
+
## UpdateEpicPayload
Autogenerated return type of UpdateEpic
@@ -1713,7 +1955,7 @@ Autogenerated return type of UpdateSnippet
| `avatarUrl` | String | URL of the user's avatar |
| `id` | ID! | ID of the user |
| `name` | String! | Human-readable name of the user |
-| `state` | String! | State of the issue |
+| `state` | UserState! | State of the user |
| `userPermissions` | UserPermissions! | Permissions for the current user on the resource |
| `username` | String! | Username of the user. Unique within this instance of GitLab |
| `webUrl` | String! | Web URL of the user |
@@ -1744,13 +1986,24 @@ Represents a vulnerability.
| `id` | ID! | GraphQL ID of the vulnerability |
| `location` | VulnerabilityLocation | Location metadata for the vulnerability. Its fields depend on the type of security scan that found the vulnerability |
| `project` | Project | The project on which the vulnerability was found |
-| `reportType` | VulnerabilityReportType | Type of the security report that found the vulnerability (SAST, DEPENDENCY_SCANNING, CONTAINER_SCANNING, DAST) |
+| `reportType` | VulnerabilityReportType | Type of the security report that found the vulnerability (SAST, DEPENDENCY_SCANNING, CONTAINER_SCANNING, DAST, SECRET_DETECTION) |
| `severity` | VulnerabilitySeverity | Severity of the vulnerability (INFO, UNKNOWN, LOW, MEDIUM, HIGH, CRITICAL) |
| `state` | VulnerabilityState | State of the vulnerability (DETECTED, DISMISSED, RESOLVED, CONFIRMED) |
| `title` | String | Title of the vulnerability |
+| `userNotesCount` | Int! | Number of user notes attached to the vulnerability |
| `userPermissions` | VulnerabilityPermissions! | Permissions for the current user on the resource |
| `vulnerabilityPath` | String | URL to the vulnerability's details page |
+## VulnerabilityIssueLink
+
+Represents an issue link of a vulnerability.
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `id` | ID! | GraphQL ID of the vulnerability |
+| `issue` | Issue! | The issue attached to issue link |
+| `linkType` | VulnerabilityIssueLinkType! | Type of the issue link |
+
## VulnerabilityLocationContainerScanning
Represents the location of a vulnerability found by a container security scan
@@ -1793,6 +2046,18 @@ Represents the location of a vulnerability found by a SAST scan
| `vulnerableClass` | String | Class containing the vulnerability |
| `vulnerableMethod` | String | Method containing the vulnerability |
+## VulnerabilityLocationSecretDetection
+
+Represents the location of a vulnerability found by a secret detection scan
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `endLine` | String | Number of the last relevant line in the vulnerable file |
+| `file` | String | Path to the vulnerable file |
+| `startLine` | String | Number of the first relevant line in the vulnerable file |
+| `vulnerableClass` | String | Class containing the vulnerability |
+| `vulnerableMethod` | String | Method containing the vulnerability |
+
## VulnerabilityPermissions
Check permissions for the current user on a vulnerability
diff --git a/doc/api/group_activity_analytics.md b/doc/api/group_activity_analytics.md
index a211097e30b..302c7703669 100644
--- a/doc/api/group_activity_analytics.md
+++ b/doc/api/group_activity_analytics.md
@@ -17,7 +17,7 @@ Parameters:
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/analytics/group_activity/issues_count?group_path=gitlab-org
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/analytics/group_activity/issues_count?group_path=gitlab-org"
```
Example response:
@@ -41,7 +41,7 @@ Parameters:
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/analytics/group_activity/merge_requests_count?group_path=gitlab-org
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/analytics/group_activity/merge_requests_count?group_path=gitlab-org"
```
Example response:
@@ -65,7 +65,7 @@ Parameters:
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/analytics/group_activity/new_members_count?group_path=gitlab-org
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/analytics/group_activity/new_members_count?group_path=gitlab-org"
```
Example response:
diff --git a/doc/api/group_badges.md b/doc/api/group_badges.md
index 5b7164cdd4d..43e1944226d 100644
--- a/doc/api/group_badges.md
+++ b/doc/api/group_badges.md
@@ -28,7 +28,7 @@ GET /groups/:id/badges
| `name` | string | no | Name of the badges to return (case-sensitive). |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/:id/badges?name=Coverage
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/badges?name=Coverage"
```
Example response:
@@ -61,7 +61,7 @@ GET /groups/:id/badges/:badge_id
| `badge_id` | integer | yes | The badge ID |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/:id/badges/:badge_id
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/badges/:badge_id"
```
Example response:
@@ -92,7 +92,7 @@ POST /groups/:id/badges
| `image_url` | string | yes | URL of the badge image |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --data "link_url=https://gitlab.com/gitlab-org/gitlab-foss/commits/master&image_url=https://shields.io/my/badge1&position=0" https://gitlab.example.com/api/v4/groups/:id/badges
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --data "link_url=https://gitlab.com/gitlab-org/gitlab-foss/commits/master&image_url=https://shields.io/my/badge1&position=0" "https://gitlab.example.com/api/v4/groups/:id/badges"
```
Example response:
@@ -124,7 +124,7 @@ PUT /groups/:id/badges/:badge_id
| `image_url` | string | no | URL of the badge image |
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/:id/badges/:badge_id
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/badges/:badge_id"
```
Example response:
@@ -154,7 +154,7 @@ DELETE /groups/:id/badges/:badge_id
| `badge_id` | integer | yes | The badge ID |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/:id/badges/:badge_id
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/badges/:badge_id"
```
## Preview a badge from a group
@@ -172,7 +172,7 @@ GET /groups/:id/badges/render
| `image_url` | string | yes | URL of the badge image |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/:id/badges/render?link_url=http%3A%2F%2Fexample.com%2Fci_status.svg%3Fproject%3D%25%7Bproject_path%7D%26ref%3D%25%7Bdefault_branch%7D&image_url=https%3A%2F%2Fshields.io%2Fmy%2Fbadge
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/badges/render?link_url=http%3A%2F%2Fexample.com%2Fci_status.svg%3Fproject%3D%25%7Bproject_path%7D%26ref%3D%25%7Bdefault_branch%7D&image_url=https%3A%2F%2Fshields.io%2Fmy%2Fbadge"
```
Example response:
diff --git a/doc/api/group_boards.md b/doc/api/group_boards.md
index adfcd6e65cb..4ff373ce583 100644
--- a/doc/api/group_boards.md
+++ b/doc/api/group_boards.md
@@ -1,3 +1,9 @@
+---
+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/#designated-technical-writers
+---
+
# Group Issue Boards API
Every API call to group boards must be authenticated.
@@ -18,7 +24,7 @@ GET /groups/:id/boards
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/5/boards
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/boards"
```
Example response:
@@ -136,7 +142,7 @@ GET /groups/:id/boards/:board_id
| `board_id` | integer | yes | The ID of a board |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/5/boards/1
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/boards/1"
```
Example response:
@@ -250,7 +256,7 @@ POST /groups/:id/boards
| `name` | string | yes | The name of the new board |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/5/boards?name=newboard
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/boards?name=newboard"
```
Example response:
@@ -321,7 +327,7 @@ PUT /groups/:id/boards/:board_id
| `weight` | integer | no | The weight range from 0 to 9, to which the board should be scoped to |
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/5/boards/1?name=new_name&milestone_id=44&assignee_id=1&labels=GroupLabel&weight=4
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/boards/1?name=new_name&milestone_id=44&assignee_id=1&labels=GroupLabel&weight=4"
```
Example response:
@@ -382,7 +388,7 @@ DELETE /groups/:id/boards/:board_id
| `board_id` | integer | yes | The ID of a board |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/5/boards/1
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/boards/1"
```
## List group issue board lists
@@ -400,7 +406,7 @@ GET /groups/:id/boards/:board_id/lists
| `board_id` | integer | yes | The ID of a board |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/5/boards/1/lists
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/boards/1/lists"
```
Example response:
@@ -452,7 +458,7 @@ GET /groups/:id/boards/:board_id/lists/:list_id
| `list_id` | integer | yes | The ID of a board's list |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/5/boards/1/lists/1
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/boards/1/lists/1"
```
Example response:
@@ -484,7 +490,7 @@ POST /groups/:id/boards/:board_id/lists
| `label_id` | integer | yes | The ID of a label |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/4/boards/12/lists?milestone_id=7
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/4/boards/12/lists?milestone_id=7"
```
Example response:
@@ -526,7 +532,7 @@ PUT /groups/:id/boards/:board_id/lists/:list_id
| `position` | integer | yes | The position of the list |
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/group/5/boards/1/lists/1?position=2
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/group/5/boards/1/lists/1?position=2"
```
Example response:
@@ -558,5 +564,5 @@ DELETE /groups/:id/boards/:board_id/lists/:list_id
| `list_id` | integer | yes | The ID of a board's list |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/5/boards/1/lists/1
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/boards/1/lists/1"
```
diff --git a/doc/api/group_clusters.md b/doc/api/group_clusters.md
index 01c6d59f60d..b600a92bc38 100644
--- a/doc/api/group_clusters.md
+++ b/doc/api/group_clusters.md
@@ -22,7 +22,7 @@ Parameters:
Example request:
```shell
-curl --header 'Private-Token: <your_access_token>' https://gitlab.example.com/api/v4/groups/26/clusters
+curl --header 'Private-Token: <your_access_token>' "https://gitlab.example.com/api/v4/groups/26/clusters"
```
Example response:
@@ -90,7 +90,7 @@ Parameters:
Example request:
```shell
-curl --header 'Private-Token: <your_access_token>' https://gitlab.example.com/api/v4/groups/26/clusters/18
+curl --header "Private-Token: <your_access_token>" "https://gitlab.example.com/api/v4/groups/26/clusters/18"
```
Example response:
@@ -166,7 +166,7 @@ Parameters:
Example request:
```shell
-curl --header 'Private-Token: <your_access_token>' https://gitlab.example.com/api/v4/groups/26/clusters/user \
+curl --header "Private-Token: <your_access_token>" "https://gitlab.example.com/api/v4/groups/26/clusters/user" \
-H "Accept: application/json" \
-H "Content-Type:application/json" \
--request POST --data '{"name":"cluster-5", "platform_kubernetes_attributes":{"api_url":"https://35.111.51.20","token":"12345","ca_cert":"-----BEGIN CERTIFICATE-----\r\nhFiK1L61owwDQYJKoZIhvcNAQELBQAw\r\nLzEtMCsGA1UEAxMkZDA1YzQ1YjctNzdiMS00NDY0LThjNmEtMTQ0ZDJkZjM4ZDBj\r\nMB4XDTE4MTIyNzIwMDM1MVoXDTIzMTIyNjIxMDM1MVowLzEtMCsGA1UEAxMkZDA1\r\nYzQ1YjctNzdiMS00NDY0LThjNmEtMTQ0ZDJkZjM.......-----END CERTIFICATE-----"}}'
@@ -238,7 +238,7 @@ through the ["Add existing cluster to group"](#add-existing-cluster-to-group) en
Example request:
```shell
-curl --header 'Private-Token: <your_access_token>' https://gitlab.example.com/api/v4/groups/26/clusters/24 \
+curl --header 'Private-Token: <your_access_token>' "https://gitlab.example.com/api/v4/groups/26/clusters/24" \
-H "Content-Type:application/json" \
--request PUT --data '{"name":"new-cluster-name","domain":"new-domain.com","api_url":"https://new-api-url.com"}'
```
@@ -307,5 +307,5 @@ Parameters:
Example request:
```shell
-curl --request DELETE --header 'Private-Token: <your_access_token>' https://gitlab.example.com/api/v4/groups/26/clusters/23
+curl --request DELETE --header "Private-Token: <your_access_token>" "https://gitlab.example.com/api/v4/groups/26/clusters/23"
```
diff --git a/doc/api/group_import_export.md b/doc/api/group_import_export.md
index 355ecbfb98f..01d81eb62ac 100644
--- a/doc/api/group_import_export.md
+++ b/doc/api/group_import_export.md
@@ -28,7 +28,7 @@ POST /groups/:id/export
| `id` | integer/string | yes | ID of the group owned by the authenticated user |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/1/export
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/export"
```
```json
@@ -50,7 +50,7 @@ GET /groups/:id/export/download
| `id` | integer/string | yes | ID of the group owned by the authenticated user |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" --remote-header-name --remote-name https://gitlab.example.com/api/v4/groups/1/export/download
+curl --header "PRIVATE-TOKEN: <your_access_token>" --remote-header-name --remote-name "https://gitlab.example.com/api/v4/groups/1/export/download"
```
```shell
@@ -83,9 +83,13 @@ The `file=` parameter must point to a file on your file system and be preceded
by `@`. For example:
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form "name=imported-group" --form "path=imported-group" --form "file=@/path/to/file" https://gitlab.example.com/api/v4/groups/import
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form "name=imported-group" --form "path=imported-group" --form "file=@/path/to/file" "https://gitlab.example.com/api/v4/groups/import"
```
+NOTE: **Note:**
+The maximum import file size can be set by the Administrator, default is 50MB.
+As an administrator, you can modify the maximum import file size. To do so, use the `max_import_size` option in the [Application settings API](settings.md#change-application-settings) or the [Admin UI](../user/admin_area/settings/account_and_limit_settings.md).
+
## Important notes
Note the following:
diff --git a/doc/api/group_labels.md b/doc/api/group_labels.md
index c3b86233836..5ae5ea4286a 100644
--- a/doc/api/group_labels.md
+++ b/doc/api/group_labels.md
@@ -1,3 +1,9 @@
+---
+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/#designated-technical-writers
+---
+
# Group Labels API
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/21368) in GitLab 11.8.
@@ -22,7 +28,7 @@ GET /groups/:id/labels
| `include_ancestor_groups` | boolean | no | Include ancestor groups. Defaults to `true`. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/5/labels?with_counts=true
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/labels?with_counts=true"
```
Example response:
@@ -71,7 +77,7 @@ GET /groups/:id/labels/:label_id
| `include_ancestor_groups` | boolean | no | Include ancestor groups. Defaults to `true`. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/5/labels/bug
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/labels/bug"
```
Example response:
@@ -107,7 +113,7 @@ POST /groups/:id/labels
| `description` | string | no | The description of the label, |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --header "Content-Type: application/json" --data '{"name": "Feature Proposal", "color": "#FFA500", "description": "Describes new ideas" }' https://gitlab.example.com/api/v4/groups/5/labels
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --header "Content-Type: application/json" --data '{"name": "Feature Proposal", "color": "#FFA500", "description": "Describes new ideas" }' "https://gitlab.example.com/api/v4/groups/5/labels"
```
Example response:
@@ -144,7 +150,7 @@ PUT /groups/:id/labels/:label_id
| `description` | string | no | The description of the label. |
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" --header "Content-Type: application/json" --data '{"new_name": "Feature Idea" }' https://gitlab.example.com/api/v4/groups/5/labels/Feature%20Proposal
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" --header "Content-Type: application/json" --data '{"new_name": "Feature Idea" }' "https://gitlab.example.com/api/v4/groups/5/labels/Feature%20Proposal"
```
Example response:
@@ -180,7 +186,7 @@ DELETE /groups/:id/labels/:label_id
| `label_id` | integer or string | yes | The ID or title of a group's label. |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/5/labels/bug
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/labels/bug"
```
NOTE: **Note:** An older endpoint `DELETE /groups/:id/labels` with `name` in the parameters is still available, but deprecated.
@@ -200,7 +206,7 @@ POST /groups/:id/labels/:label_id/subscribe
| `label_id` | integer or string | yes | The ID or title of a group's label. |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/5/labels/9/subscribe
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/labels/9/subscribe"
```
Example response:
@@ -236,7 +242,7 @@ POST /groups/:id/labels/:label_id/unsubscribe
| `label_id` | integer or string | yes | The ID or title of a group's label. |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/5/labels/9/unsubscribe
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/labels/9/unsubscribe"
```
Example response:
diff --git a/doc/api/group_level_variables.md b/doc/api/group_level_variables.md
index e30ee329114..aa5f0b3db72 100644
--- a/doc/api/group_level_variables.md
+++ b/doc/api/group_level_variables.md
@@ -1,6 +1,6 @@
# Group-level Variables API
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/34519) in GitLab 9.5
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/34519) in GitLab 9.5
## List group variables
diff --git a/doc/api/group_milestones.md b/doc/api/group_milestones.md
index 10445acf881..e157655a713 100644
--- a/doc/api/group_milestones.md
+++ b/doc/api/group_milestones.md
@@ -1,7 +1,16 @@
+---
+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/#designated-technical-writers
+---
+
# Group milestones API
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/12819) in GitLab 9.5.
+This page describes the group milestones API.
+There's a separate [project milestones API](./group_milestones.md) page.
+
## List group milestones
Returns a list of group milestones.
@@ -27,7 +36,7 @@ Parameters:
| `search` | string | no | Return only milestones with a title or description matching the provided string |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/5/milestones
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/milestones"
```
Example Response:
@@ -150,7 +159,7 @@ Parameters:
## Get all burndown chart events for a single milestone **(STARTER)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/4737) in GitLab 12.1
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4737) in GitLab 12.1
Get all burndown chart events for a single milestone.
diff --git a/doc/api/groups.md b/doc/api/groups.md
index bc7bff2964b..e58506380d1 100644
--- a/doc/api/groups.md
+++ b/doc/api/groups.md
@@ -20,6 +20,7 @@ Parameters:
| `with_custom_attributes` | boolean | no | Include [custom attributes](custom_attributes.md) in response (admins only) |
| `owned` | boolean | no | Limit to groups explicitly owned by the current user |
| `min_access_level` | integer | no | Limit to groups where current user has at least this [access level](members.md) |
+| `top_level_only` | boolean | no | Limit to top level groups, excluding all subgroups |
```plaintext
GET /groups
@@ -399,13 +400,13 @@ The `projects` and `shared_projects` attributes in the response are deprecated a
To get the details of all projects within a group, use either the [list a group's projects](#list-a-groups-projects) or the [list a group's shared projects](#list-a-groups-shared-projects) endpoint.
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/4
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/4"
```
This endpoint returns:
- All projects and shared projects in GitLab 12.5 and earlier.
-- A maximum of 100 projects and shared projects [in GitLab 12.6](https://gitlab.com/gitlab-org/gitlab/issues/31031)
+- A maximum of 100 projects and shared projects [in GitLab 12.6](https://gitlab.com/gitlab-org/gitlab/-/issues/31031)
and later. To get the details of all projects within a group, use the
[list a group's projects endpoint](#list-a-groups-projects) instead.
@@ -427,6 +428,15 @@ Example response:
"file_template_project_id": 1,
"parent_id": null,
"created_at": "2020-01-15T12:36:29.590Z",
+ "shared_with_groups": [
+ {
+ "group_id": 28,
+ "group_name": "H5bp",
+ "group_full_path": "h5bp",
+ "group_access_level": 20,
+ "expires_at": null
+ }
+ ],
"projects": [ // Deprecated and will be removed in API v5
{
"id": 7,
@@ -577,10 +587,22 @@ Additional response parameters:
}
```
+Users on GitLab [Silver, Premium, or higher](https://about.gitlab.com/pricing/) will also see
+the `marked_for_deletion_on` attribute:
+
+```json
+{
+ "id": 4,
+ "description": "Aliquid qui quis dignissimos distinctio ut commodi voluptas est.",
+ "marked_for_deletion_on": "2020-04-03",
+ ...
+}
+```
+
When adding the parameter `with_projects=false`, projects will not be returned.
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/4?with_projects=false
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/4?with_projects=false"
```
Example response:
@@ -638,7 +660,7 @@ Parameters:
| `auto_devops_enabled` | boolean | no | Default to Auto DevOps pipeline for all projects within this group. |
| `subgroup_creation_level` | string | no | Allowed to create subgroups. Can be `owner` (Owners), or `maintainer` (Maintainers). |
| `emails_disabled` | boolean | no | Disable email notifications |
-| `avatar` | mixed | no | Image file for avatar of the group. [Introduced in GitLab 12.9](https://gitlab.com/gitlab-org/gitlab/issues/36681) |
+| `avatar` | mixed | no | Image file for avatar of the group. [Introduced in GitLab 12.9](https://gitlab.com/gitlab-org/gitlab/-/issues/36681) |
| `mentions_disabled` | boolean | no | Disable the capability of a group from getting mentioned |
| `lfs_enabled` | boolean | no | Enable/disable Large File Storage (LFS) for the projects in this group. |
| `request_access_enabled` | boolean | no | Allow users to request member access. |
@@ -657,6 +679,19 @@ The `default_branch_protection` attribute determines whether developers and main
| `1` | Partial protection. Developers and maintainers can: <br>- Push new commits |
| `2` | Full protection. Only maintainers can: <br>- Push new commits |
+## New Subgroup
+
+This is similar to creating a [New group](#new-group). You'll need the `parent_id` from the [List groups](#list-groups) call. You can then enter the desired:
+
+- `subgroup_path`
+- `subgroup_name`
+
+```shell
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --header "Content-Type: application/json" \
+ --data '{"path": "<subgroup_path>", "name": "<subgroup_name>", "parent_id": <parent_group_id> } \
+ "https://gitlab.example.com/api/v4/groups/"
+```
+
## Transfer project to group
Transfer a project to the Group namespace. Available only to instance administrators, although an [alternative API endpoint](projects.md#transfer-a-project-to-a-new-namespace) is available which does not require instance administrator access. Transferring projects may fail when tagged packages exist in the project's repository.
@@ -673,7 +708,7 @@ Parameters:
| `project_id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/4/projects/56
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/4/projects/56"
```
## Update group
@@ -699,7 +734,7 @@ PUT /groups/:id
| `auto_devops_enabled` | boolean | no | Default to Auto DevOps pipeline for all projects within this group. |
| `subgroup_creation_level` | string | no | Allowed to create subgroups. Can be `owner` (Owners), or `maintainer` (Maintainers). |
| `emails_disabled` | boolean | no | Disable email notifications |
-| `avatar` | mixed | no | Image file for avatar of the group. [Introduced in GitLab 12.9](https://gitlab.com/gitlab-org/gitlab/issues/36681) |
+| `avatar` | mixed | no | Image file for avatar of the group. [Introduced in GitLab 12.9](https://gitlab.com/gitlab-org/gitlab/-/issues/36681) |
| `mentions_disabled` | boolean | no | Disable the capability of a group from getting mentioned |
| `lfs_enabled` (optional) | boolean | no | Enable/disable Large File Storage (LFS) for the projects in this group. |
| `request_access_enabled` | boolean | no | Allow users to request member access. |
@@ -719,7 +754,7 @@ curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab
This endpoint returns:
- All projects and shared projects in GitLab 12.5 and earlier.
-- A maximum of 100 projects and shared projects [in GitLab 12.6](https://gitlab.com/gitlab-org/gitlab/issues/31031)
+- A maximum of 100 projects and shared projects [in GitLab 12.6](https://gitlab.com/gitlab-org/gitlab/-/issues/31031)
and later. To get the details of all projects within a group, use the
[list a group's projects endpoint](#list-a-groups-projects) instead.
@@ -803,7 +838,7 @@ Only available to group owners and administrators.
This endpoint either:
- Removes group, and queues a background job to delete all projects in the group as well.
-- Since [GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/issues/33257), on [Premium or Silver](https://about.gitlab.com/pricing/) or higher tiers, marks a group for deletion. The deletion will happen 7 days later by default, but this can be changed in the [instance settings](../user/admin_area/settings/visibility_and_access_controls.md#default-deletion-adjourned-period-premium-only).
+- Since [GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/-/issues/33257), on [Premium or Silver](https://about.gitlab.com/pricing/) or higher tiers, marks a group for deletion. The deletion will happen 7 days later by default, but this can be changed in the [instance settings](../user/admin_area/settings/visibility_and_access_controls.md#default-deletion-adjourned-period-premium-only).
```plaintext
DELETE /groups/:id
@@ -819,7 +854,7 @@ The response will be `202 Accepted` if the user has authorization.
## Restore group marked for deletion **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/33257) in GitLab 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/33257) in GitLab 12.8.
Restores a group marked for deletion.
@@ -1088,3 +1123,35 @@ Read more in the [Group Badges](group_badges.md) documentation.
## Group Import/Export
Read more in the [Group Import/Export](group_import_export.md) documentation.
+
+## Share Groups with Groups
+
+These endpoints create and delete links for sharing a group with another group. For more information, see the related discussion in the [GitLab Groups](../user/group/index.md#sharing-a-group-with-another-group) page.
+
+### Create a link to share a group with another group
+
+Share group with another group. Returns `200` and the [group details](#details-of-a-group) on success.
+
+```plaintext
+POST /groups/:id/share
+```
+
+| Attribute | Type | Required | Description |
+| --------- | -------------- | -------- | ----------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) |
+| `group_id` | integer | yes | The ID of the group to share with |
+| `group_access` | integer | yes | The [permissions level](members.md) to grant the group |
+| `expires_at` | string | no | Share expiration date in ISO 8601 format: 2016-09-26 |
+
+### Delete link sharing group with another group
+
+Unshare the group from another group. Returns `204` and no content on success.
+
+```plaintext
+DELETE /groups/:id/share/:group_id
+```
+
+| Attribute | Type | Required | Description |
+| --------- | -------------- | -------- | ----------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) |
+| `group_id` | integer | yes | The ID of the group to share with |
diff --git a/doc/api/import.md b/doc/api/import.md
index 9640ba19cf9..307796f8acb 100644
--- a/doc/api/import.md
+++ b/doc/api/import.md
@@ -16,7 +16,7 @@ POST /import/github
| `target_namespace` | string | yes | Namespace to import repository into |
```shell
-curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --data "personal_access_token=abc123&repo_id=12345&target_namespace=root" https://gitlab.example.com/api/v4/import/github
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --data "personal_access_token=abc123&repo_id=12345&target_namespace=root" "https://gitlab.example.com/api/v4/import/github"
```
Example response:
diff --git a/doc/api/instance_level_ci_variables.md b/doc/api/instance_level_ci_variables.md
index d0871fdf4a7..72d20109fbd 100644
--- a/doc/api/instance_level_ci_variables.md
+++ b/doc/api/instance_level_ci_variables.md
@@ -67,8 +67,7 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/a
Create a new instance-level variable.
-NOTE: **Note:**
-The maximum number of instance-level variables is [planned to be 25](https://gitlab.com/gitlab-org/gitlab/-/issues/216097).
+[Since GitLab 13.1](https://gitlab.com/gitlab-org/gitlab/-/issues/216097), the maximum number of allowed instance-level variables can be changed.
```plaintext
POST /admin/ci/variables
@@ -77,7 +76,7 @@ POST /admin/ci/variables
| Attribute | Type | required | Description |
|-----------------|---------|----------|-----------------------|
| `key` | string | yes | The `key` of a variable. Max 255 characters, only `A-Z`, `a-z`, `0-9`, and `_` are allowed. |
-| `value` | string | yes | The `value` of a variable. |
+| `value` | string | yes | The `value` of a variable. Around 700 characters allowed. |
| `variable_type` | string | no | The type of a variable. Available types are: `env_var` (default) and `file`. |
| `protected` | boolean | no | Whether the variable is protected. |
| `masked` | boolean | no | Whether the variable is masked. |
diff --git a/doc/api/issues.md b/doc/api/issues.md
index 8e5882c4d4e..f640300e3ae 100644
--- a/doc/api/issues.md
+++ b/doc/api/issues.md
@@ -1,3 +1,9 @@
+---
+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/#designated-technical-writers
+---
+
# Issues API
Every API call to issues must be authenticated.
@@ -70,7 +76,7 @@ GET /issues?confidential=true
| `non_archived` | boolean | no | Return issues only from non-archived projects. If `false`, response will return issues from both archived and non-archived projects. Default is `true`. _(Introduced in [GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/issues/197170))_ |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/issues
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/issues"
```
Example response:
@@ -226,7 +232,7 @@ GET /groups/:id/issues?confidential=true
| `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))_ |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/4/issues
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/4/issues"
```
Example response:
@@ -357,7 +363,7 @@ GET /projects/:id/issues?confidential=true
| Attribute | Type | Required | Description |
| ------------------- | ---------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
-| `iids[]` | integer array | no | Return only the milestone having the given `iid` |
+| `iids[]` | integer array | no | Return only the issues having the given `iid` |
| `state` | string | no | Return all issues or just those that are `opened` or `closed` |
| `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. |
| `with_labels_details` | boolean | no | If `true`, response will return more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. `description_html` Introduced in [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) |
@@ -380,7 +386,7 @@ GET /projects/:id/issues?confidential=true
| `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` |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/4/issues
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/4/issues"
```
Example response:
@@ -508,7 +514,7 @@ GET /projects/:id/issues/:issue_iid
| `issue_iid` | integer | yes | The internal ID of a project's issue |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/4/issues/41
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/4/issues/41"
```
Example response:
@@ -631,7 +637,7 @@ the `epic` property:
**Note**: The `closed_by` attribute was [introduced in GitLab 10.6](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042). This value will only be present for issues which were closed after GitLab 10.6 and when the user account that closed the issue still exists.
-**Note**: The `epic_iid` attribute is deprecated and [will be removed in version 5](https://gitlab.com/gitlab-org/gitlab/issues/35157).
+**Note**: The `epic_iid` attribute is deprecated and [will be removed in version 5](https://gitlab.com/gitlab-org/gitlab/-/issues/35157).
Please use `iid` of the `epic` attribute instead.
## New issue
@@ -658,10 +664,10 @@ POST /projects/:id/issues
| `discussion_to_resolve` | string | no | The ID of a discussion to resolve. This will fill in the issue with a default description and mark the discussion as resolved. Use in combination with `merge_request_to_resolve_discussions_of`. |
| `weight` **(STARTER)** | integer | no | The weight of the issue. Valid values are greater than or equal to 0. |
| `epic_id` **(ULTIMATE)** | integer | no | ID of the epic to add the issue to. Valid values are greater than or equal to 0. |
-| `epic_iid` **(ULTIMATE)** | integer | no | IID of the epic to add the issue to. Valid values are greater than or equal to 0. (deprecated, [will be removed in version 5](https://gitlab.com/gitlab-org/gitlab/issues/35157)) |
+| `epic_iid` **(ULTIMATE)** | integer | no | IID of the epic to add the issue to. Valid values are greater than or equal to 0. (deprecated, [will be removed in version 5](https://gitlab.com/gitlab-org/gitlab/-/issues/35157)) |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/4/issues?title=Issues%20with%20auth&labels=bug
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/4/issues?title=Issues%20with%20auth&labels=bug"
```
Example response:
@@ -768,16 +774,18 @@ PUT /projects/:id/issues/:issue_iid
| `assignee_ids` | integer array | no | The ID of the user(s) to assign the issue to. Set to `0` or provide an empty value to unassign all assignees. |
| `milestone_id` | integer | no | The global ID of a milestone to assign the issue to. Set to `0` or provide an empty value to unassign a milestone.|
| `labels` | string | no | Comma-separated label names for an issue. Set to an empty string to unassign all labels. |
+| `add_labels` | string | no | Comma-separated label names to add to an issue. |
+| `remove_labels`| string | no | Comma-separated label names to remove from an issue. |
| `state_event` | string | no | The state event of an issue. Set `close` to close the issue and `reopen` to reopen it |
| `updated_at` | string | no | Date time string, ISO 8601 formatted, for example `2016-03-11T03:45:40Z` (requires admin or project owner rights). Empty string or null values are not accepted.|
| `due_date` | string | no | Date time string in the format YEAR-MONTH-DAY, for example `2016-03-11` |
| `weight` **(STARTER)** | integer | no | The weight of the issue. Valid values are greater than or equal to 0. 0 |
| `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. |
| `epic_id` **(ULTIMATE)** | integer | no | ID of the epic to add the issue to. Valid values are greater than or equal to 0. |
-| `epic_iid` **(ULTIMATE)** | integer | no | IID of the epic to add the issue to. Valid values are greater than or equal to 0. (deprecated, [will be removed in version 5](https://gitlab.com/gitlab-org/gitlab/issues/35157)) |
+| `epic_iid` **(ULTIMATE)** | integer | no | IID of the epic to add the issue to. Valid values are greater than or equal to 0. (deprecated, [will be removed in version 5](https://gitlab.com/gitlab-org/gitlab/-/issues/35157)) |
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/4/issues/85?state_event=close
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/4/issues/85?state_event=close"
```
Example response:
@@ -883,7 +891,7 @@ DELETE /projects/:id/issues/:issue_iid
| `issue_iid` | integer | yes | The internal ID of a project's issue |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/4/issues/85
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/4/issues/85"
```
## Move an issue
@@ -906,7 +914,7 @@ POST /projects/:id/issues/:issue_iid/move
| `to_project_id` | integer | yes | The ID of the new project |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" --form to_project_id=5 https://gitlab.example.com/api/v4/projects/4/issues/85/move
+curl --header "PRIVATE-TOKEN: <your_access_token>" --form to_project_id=5 "https://gitlab.example.com/api/v4/projects/4/issues/85/move"
```
Example response:
@@ -1012,7 +1020,7 @@ POST /projects/:id/issues/:issue_iid/subscribe
| `issue_iid` | integer | yes | The internal ID of a project's issue |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/issues/93/subscribe
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/93/subscribe"
```
Example response:
@@ -1118,7 +1126,7 @@ POST /projects/:id/issues/:issue_iid/unsubscribe
| `issue_iid` | integer | yes | The internal ID of a project's issue |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/issues/93/unsubscribe
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/93/unsubscribe"
```
Example response:
@@ -1189,7 +1197,7 @@ POST /projects/:id/issues/:issue_iid/todo
| `issue_iid` | integer | yes | The internal ID of a project's issue |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/issues/93/todo
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/93/todo"
```
Example response:
@@ -1304,7 +1312,7 @@ POST /projects/:id/issues/:issue_iid/time_estimate
| `duration` | string | yes | The duration in human format. e.g: 3h30m |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/issues/93/time_estimate?duration=3h30m
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/93/time_estimate?duration=3h30m"
```
Example response:
@@ -1332,7 +1340,7 @@ POST /projects/:id/issues/:issue_iid/reset_time_estimate
| `issue_iid` | integer | yes | The internal ID of a project's issue |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/issues/93/reset_time_estimate
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/93/reset_time_estimate"
```
Example response:
@@ -1361,7 +1369,7 @@ POST /projects/:id/issues/:issue_iid/add_spent_time
| `duration` | string | yes | The duration in human format. e.g: 3h30m |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/issues/93/add_spent_time?duration=1h
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/93/add_spent_time?duration=1h"
```
Example response:
@@ -1389,7 +1397,7 @@ POST /projects/:id/issues/:issue_iid/reset_spent_time
| `issue_iid` | integer | yes | The internal ID of a project's issue |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/issues/93/reset_spent_time
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/93/reset_spent_time"
```
Example response:
@@ -1415,7 +1423,7 @@ GET /projects/:id/issues/:issue_iid/time_stats
| `issue_iid` | integer | yes | The internal ID of a project's issue |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/issues/93/time_stats
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/93/time_stats"
```
Example response:
@@ -1443,7 +1451,7 @@ GET /projects/:id/issues/:issue_id/related_merge_requests
| `issue_iid` | integer | yes | The internal ID of a project's issue |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/issues/11/related_merge_requests
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/11/related_merge_requests"
```
Example response:
@@ -1599,7 +1607,7 @@ GET /projects/:id/issues/:issue_iid/closed_by
| `issue_iid` | integer | yes | The internal ID of a project issue |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/issues/11/closed_by
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/11/closed_by"
```
Example response:
@@ -1672,7 +1680,7 @@ GET /projects/:id/issues/:issue_iid/participants
| `issue_iid` | integer | yes | The internal ID of a project's issue |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/issues/93/participants
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/93/participants"
```
Example response:
@@ -1716,7 +1724,7 @@ GET /projects/:id/issues/:issue_iid/user_agent_detail
| `issue_iid` | integer | yes | The internal ID of a project's issue |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/issues/93/user_agent_detail
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/93/user_agent_detail"
```
Example response:
diff --git a/doc/api/issues_statistics.md b/doc/api/issues_statistics.md
index 8db99e93f79..8e2dcc07af8 100644
--- a/doc/api/issues_statistics.md
+++ b/doc/api/issues_statistics.md
@@ -46,7 +46,7 @@ GET /issues_statistics?confidential=true
| `confidential` | boolean | no | Filter confidential or public issues. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/issues_statistics
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/issues_statistics"
```
Example response:
@@ -102,7 +102,7 @@ GET /groups/:id/issues_statistics?confidential=true
| `confidential` | boolean | no | Filter confidential or public issues. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/4/issues_statistics
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/4/issues_statistics"
```
Example response:
@@ -158,7 +158,7 @@ GET /projects/:id/issues_statistics?confidential=true
| `confidential` | boolean | no | Filter confidential or public issues. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/4/issues_statistics
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/4/issues_statistics"
```
Example response:
diff --git a/doc/api/jobs.md b/doc/api/jobs.md
index c06dc56407c..4dc29fc897d 100644
--- a/doc/api/jobs.md
+++ b/doc/api/jobs.md
@@ -14,7 +14,7 @@ GET /projects/:id/jobs
| `scope` | string **or** array of strings | no | Scope of jobs to show. Either one of or an array of the following: `created`, `pending`, `running`, `failed`, `success`, `canceled`, `skipped`, or `manual`. All jobs are returned if `scope` is not provided. |
```shell
-curl --globoff --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/1/jobs?scope[]=pending&scope[]=running'
+curl --globoff --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/jobs?scope[]=pending&scope[]=running"
```
Example of response
@@ -149,7 +149,7 @@ GET /projects/:id/pipelines/:pipeline_id/jobs
| `scope` | string **or** array of strings | no | Scope of jobs to show. Either one of or an array of the following: `created`, `pending`, `running`, `failed`, `success`, `canceled`, `skipped`, or `manual`. All jobs are returned if `scope` is not provided. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/1/pipelines/6/jobs?scope[]=pending&scope[]=running'
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/pipelines/6/jobs?scope[]=pending&scope[]=running"
```
Example of response
@@ -269,6 +269,90 @@ Example of response
]
```
+## List pipeline bridges
+
+Get a list of bridge jobs for a pipeline.
+
+```plaintext
+GET /projects/:id/pipelines/:pipeline_id/bridges
+```
+
+| Attribute | Type | Required | Description |
+|---------------|--------------------------------|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `id` | integer/string | yes | ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user. |
+| `pipeline_id` | integer | yes | ID of a pipeline. |
+| `scope` | string **or** array of strings | no | Scope of jobs to show. Either one of or an array of the following: `created`, `pending`, `running`, `failed`, `success`, `canceled`, `skipped`, or `manual`. All jobs are returned if `scope` is not provided. |
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/1/pipelines/6/bridges?scope[]=pending&scope[]=running'
+```
+
+Example of response
+
+```json
+[
+ {
+ "commit": {
+ "author_email": "admin@example.com",
+ "author_name": "Administrator",
+ "created_at": "2015-12-24T16:51:14.000+01:00",
+ "id": "0ff3ae198f8601a285adcf5c0fff204ee6fba5fd",
+ "message": "Test the CI integration.",
+ "short_id": "0ff3ae19",
+ "title": "Test the CI integration."
+ },
+ "coverage": null,
+ "allow_failure": false,
+ "created_at": "2015-12-24T15:51:21.802Z",
+ "started_at": "2015-12-24T17:54:27.722Z",
+ "finished_at": "2015-12-24T17:58:27.895Z",
+ "duration": 240,
+ "id": 7,
+ "name": "teaspoon",
+ "pipeline": {
+ "id": 6,
+ "ref": "master",
+ "sha": "0ff3ae198f8601a285adcf5c0fff204ee6fba5fd",
+ "status": "pending",
+ "created_at": "2015-12-24T15:50:16.123Z",
+ "updated_at": "2015-12-24T18:00:44.432Z",
+ "web_url": "https://example.com/foo/bar/pipelines/6"
+ },
+ "ref": "master",
+ "stage": "test",
+ "status": "pending",
+ "tag": false,
+ "web_url": "https://example.com/foo/bar/-/jobs/7",
+ "user": {
+ "id": 1,
+ "name": "Administrator",
+ "username": "root",
+ "state": "active",
+ "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
+ "web_url": "http://gitlab.dev/root",
+ "created_at": "2015-12-21T13:14:24.077Z",
+ "bio": null,
+ "location": null,
+ "public_email": "",
+ "skype": "",
+ "linkedin": "",
+ "twitter": "",
+ "website_url": "",
+ "organization": ""
+ },
+ "downstream_pipeline": {
+ "id": 5,
+ "sha": "f62a4b2fb89754372a346f24659212eb8da13601",
+ "ref": "master",
+ "status": "pending",
+ "created_at": "2015-12-24T17:54:27.722Z",
+ "updated_at": "2015-12-24T17:58:27.896Z",
+ "web_url": "https://example.com/diaspora/diaspora-client/pipelines/5"
+ }
+ }
+]
+```
+
## Get a single job
Get a single job of a project
diff --git a/doc/api/keys.md b/doc/api/keys.md
index 81ebd70be52..6294ac300ce 100644
--- a/doc/api/keys.md
+++ b/doc/api/keys.md
@@ -15,7 +15,7 @@ GET /keys/:id
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/keys/1
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/keys/1"
```
```json
@@ -74,7 +74,7 @@ GET /keys
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/keys?fingerprint=ba:81:59:68:d7:6c:cd:02:02:bf:6a:9b:55:4e:af:d1'
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/keys?fingerprint=ba:81:59:68:d7:6c:cd:02:02:bf:6a:9b:55:4e:af:d1"
```
If using sha256 fingerprint API calls, make sure that the fingerprint is URL-encoded.
@@ -82,7 +82,7 @@ If using sha256 fingerprint API calls, make sure that the fingerprint is URL-enc
For example, `/` is represented by `%2F` and `:` is represented by`%3A`:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/keys?fingerprint=SHA256%3AnUhzNyftwADy8AH3wFY31tAKs7HufskYTte2aXo%2FlCg
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/keys?fingerprint=SHA256%3AnUhzNyftwADy8AH3wFY31tAKs7HufskYTte2aXo%2FlCg"
```
Example response:
@@ -133,7 +133,7 @@ Example response:
## Get user by deploy key fingerprint
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/119209) in GitLab 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/119209) in GitLab 12.7.
Deploy keys are bound to the creating user, so if you query with a deploy key
fingerprint you get additional information about the projects using that key.
@@ -141,7 +141,7 @@ fingerprint you get additional information about the projects using that key.
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/keys?fingerprint=SHA256%3AnUhzNyftwADy8AH3wFY31tAKs7HufskYTte2aXo%2FlCg
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/keys?fingerprint=SHA256%3AnUhzNyftwADy8AH3wFY31tAKs7HufskYTte2aXo%2FlCg"
```
Example response:
diff --git a/doc/api/labels.md b/doc/api/labels.md
index 3ced7da8ed5..3ab059fca7c 100644
--- a/doc/api/labels.md
+++ b/doc/api/labels.md
@@ -1,3 +1,9 @@
+---
+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/#designated-technical-writers
+---
+
# Labels API
NOTE: **Note:**
@@ -20,7 +26,7 @@ GET /projects/:id/labels
| `include_ancestor_groups` | boolean | no | Include ancestor groups. Defaults to `true`. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/labels?with_counts=true
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/labels?with_counts=true"
```
Example response:
@@ -115,7 +121,7 @@ GET /projects/:id/labels/:label_id
| `include_ancestor_groups` | boolean | no | Include ancestor groups. Defaults to `true`. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/labels/bug
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/labels/bug"
```
Example response:
@@ -291,7 +297,7 @@ POST /projects/:id/labels/:label_id/subscribe
| `label_id` | integer or string | yes | The ID or title of a project's label |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/labels/1/subscribe
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/labels/1/subscribe"
```
Example response:
@@ -329,5 +335,5 @@ POST /projects/:id/labels/:label_id/unsubscribe
| `label_id` | integer or string | yes | The ID or title of a project's label |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/labels/1/unsubscribe
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/labels/1/unsubscribe"
```
diff --git a/doc/api/lint.md b/doc/api/lint.md
index f0e4ad5655a..b5889884e48 100644
--- a/doc/api/lint.md
+++ b/doc/api/lint.md
@@ -13,7 +13,7 @@ POST /ci/lint
| `content` | string | yes | the `.gitlab-ci.yaml` content|
```shell
-curl --header "Content-Type: application/json" https://gitlab.example.com/api/v4/ci/lint --data '{"content": "{ \"image\": \"ruby:2.6\", \"services\": [\"postgres\"], \"before_script\": [\"bundle install\", \"bundle exec rake db:create\"], \"variables\": {\"DB_NAME\": \"postgres\"}, \"types\": [\"test\", \"deploy\", \"notify\"], \"rspec\": { \"script\": \"rake spec\", \"tags\": [\"ruby\", \"postgres\"], \"only\": [\"branches\"]}}"}'
+curl --header "Content-Type: application/json" "https://gitlab.example.com/api/v4/ci/lint" --data '{"content": "{ \"image\": \"ruby:2.6\", \"services\": [\"postgres\"], \"before_script\": [\"bundle install\", \"bundle exec rake db:create\"], \"variables\": {\"DB_NAME\": \"postgres\"}, \"types\": [\"test\", \"deploy\", \"notify\"], \"rspec\": { \"script\": \"rake spec\", \"tags\": [\"ruby\", \"postgres\"], \"only\": [\"branches\"]}}"}'
```
Be sure to copy paste the exact contents of `.gitlab-ci.yml` as YAML is very picky about indentation and spaces.
diff --git a/doc/api/managed_licenses.md b/doc/api/managed_licenses.md
index 13eb3a3fea7..984cfa92d3a 100644
--- a/doc/api/managed_licenses.md
+++ b/doc/api/managed_licenses.md
@@ -13,7 +13,7 @@ GET /projects/:id/managed_licenses
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/managed_licenses
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/managed_licenses"
```
Example response:
diff --git a/doc/api/markdown.md b/doc/api/markdown.md
index 45f105b4e2a..32810ee349e 100644
--- a/doc/api/markdown.md
+++ b/doc/api/markdown.md
@@ -1,3 +1,9 @@
+---
+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/#designated-technical-writers
+---
+
# Markdown API
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/18926) in GitLab 11.0.
@@ -17,7 +23,7 @@ POST /api/v4/markdown
| `project` | string | no (optional) | Use `project` as a context when creating references using GitLab Flavored Markdown. [Authentication](README.md#authentication) is required if a project is not public. |
```shell
-curl --header Content-Type:application/json --data '{"text":"Hello world! :tada:", "gfm":true, "project":"group_example/project_example"}' https://gitlab.example.com/api/v4/markdown
+curl --header Content-Type:application/json --data '{"text":"Hello world! :tada:", "gfm":true, "project":"group_example/project_example"}' "https://gitlab.example.com/api/v4/markdown"
```
Response example:
diff --git a/doc/api/members.md b/doc/api/members.md
index afeda7780d7..dadd609b7ed 100644
--- a/doc/api/members.md
+++ b/doc/api/members.md
@@ -4,13 +4,17 @@
The access levels are defined in the `Gitlab::Access` module. Currently, these levels are recognized:
-```plaintext
-10 => Guest access
-20 => Reporter access
-30 => Developer access
-40 => Maintainer access
-50 => Owner access # Only valid for groups
-```
+- No access (`0`)
+- Guest (`10`)
+- Reporter (`20`)
+- Developer (`30`)
+- Maintainer (`40`)
+- Owner (`50`) - Only valid to set for groups
+
+CAUTION: **Caution:**
+Due to [an issue](https://gitlab.com/gitlab-org/gitlab/-/issues/219299),
+projects in personal namespaces will not show owner (`50`) permission
+for owner.
## List all members of a group or project
@@ -31,8 +35,8 @@ GET /projects/:id/members
| `user_ids` | array of integers | no | Filter the results on the given user IDs |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/:id/members
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:id/members
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/members"
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/members"
```
Example response:
@@ -59,6 +63,7 @@ Example response:
"web_url": "http://192.168.1.8:3000/root",
"expires_at": "2012-10-22T14:13:35Z",
"access_level": 30,
+ "email": "john@example.com",
"group_saml_identity": {
"extern_uid":"ABC-1234567890",
"provider": "group_saml",
@@ -88,8 +93,8 @@ GET /projects/:id/members/all
| `user_ids` | array of integers | no | Filter the results on the given user IDs |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/:id/members/all
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:id/members/all
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/members/all"
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/members/all"
```
Example response:
@@ -116,6 +121,7 @@ Example response:
"web_url": "http://192.168.1.8:3000/root",
"expires_at": "2012-10-22T14:13:35Z",
"access_level": 30
+ "email": "john@example.com",
"group_saml_identity": {
"extern_uid":"ABC-1234567890",
"provider": "group_saml",
@@ -151,8 +157,8 @@ GET /projects/:id/members/:user_id
| `user_id` | integer | yes | The user ID of the member |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/:id/members/:user_id
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:id/members/:user_id
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/members/:user_id"
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/members/:user_id"
```
Example response:
@@ -188,8 +194,8 @@ GET /projects/:id/members/all/:user_id
| `user_id` | integer | yes | The user ID of the member |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/:id/members/all/:user_id
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:id/members/all/:user_id
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/members/all/:user_id"
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/members/all/:user_id"
```
Example response:
@@ -225,8 +231,8 @@ POST /projects/:id/members
| `expires_at` | string | no | A date string in the format YEAR-MONTH-DAY |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --data "user_id=1&access_level=30" https://gitlab.example.com/api/v4/groups/:id/members
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --data "user_id=1&access_level=30" https://gitlab.example.com/api/v4/projects/:id/members
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --data "user_id=1&access_level=30" "https://gitlab.example.com/api/v4/groups/:id/members"
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --data "user_id=1&access_level=30" "https://gitlab.example.com/api/v4/projects/:id/members"
```
Example response:
@@ -262,8 +268,8 @@ PUT /projects/:id/members/:user_id
| `expires_at` | string | no | A date string in the format YEAR-MONTH-DAY |
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/:id/members/:user_id?access_level=40
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:id/members/:user_id?access_level=40
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/members/:user_id?access_level=40"
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/members/:user_id?access_level=40"
```
Example response:
@@ -284,7 +290,7 @@ Example response:
### Set override flag for a member of a group
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/4875) in GitLab 12.10.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4875) in GitLab 12.10.
By default, the access level of LDAP group members is set to the value specified
by LDAP through Group Sync. You can allow access level overrides by calling this endpoint.
@@ -298,8 +304,8 @@ POST /groups/:id/members/:user_id/override
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user |
| `user_id` | integer | yes | The user ID of the member |
-```bash
-curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/groups/:id/members/:user_id/override
+```shell
+curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/groups/:id/members/:user_id/override"
```
Example response:
@@ -320,7 +326,7 @@ Example response:
### Remove override for a member of a group
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/4875) in GitLab 12.10.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4875) in GitLab 12.10.
Sets the override flag to false and allows LDAP Group Sync to reset the access
level to the LDAP-prescribed value.
@@ -334,8 +340,8 @@ DELETE /groups/:id/members/:user_id/override
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user |
| `user_id` | integer | yes | The user ID of the member |
-```bash
-curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/groups/:id/members/:user_id/override
+```shell
+curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/groups/:id/members/:user_id/override"
```
Example response:
@@ -369,10 +375,10 @@ DELETE /projects/:id/members/:user_id
| `user_id` | integer | yes | The user ID of the member |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/:id/members/:user_id
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:id/members/:user_id
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/members/:user_id"
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/members/:user_id"
```
## Give a group access to a project
-Look at [share project with group](projects.md#share-project-with-group)
+See [share project with group](projects.md#share-project-with-group)
diff --git a/doc/api/merge_request_approvals.md b/doc/api/merge_request_approvals.md
index c07e52451d2..746a79e1b8e 100644
--- a/doc/api/merge_request_approvals.md
+++ b/doc/api/merge_request_approvals.md
@@ -6,7 +6,7 @@ Configuration for approvals on all Merge Requests (MR) in the project. Must be a
### Get Configuration
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/183) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/183) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.6.
You can request information about a project's approval configuration using the
following endpoint:
@@ -34,7 +34,7 @@ GET /projects/:id/approvals
### Change configuration
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/183) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/183) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.6.
If you are allowed to, you can change approval configuration using the following
endpoint:
@@ -68,8 +68,8 @@ POST /projects/:id/approvals
### Get project-level rules
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/11877) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.3.
-> - `protected_branches` property was [introduced](https://gitlab.com/gitlab-org/gitlab/issues/460) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.7.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11877) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.3.
+> - `protected_branches` property was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/460) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.7.
You can request information about a project's approval rules using the following endpoint:
@@ -168,7 +168,7 @@ GET /projects/:id/approval_rules
### Create project-level rule
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/11877) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11877) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.3.
You can create project approval rules using the following endpoint:
@@ -270,7 +270,7 @@ POST /projects/:id/approval_rules
### Update project-level rule
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/11877) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11877) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.3.
You can update project approval rules using the following endpoint:
@@ -375,7 +375,7 @@ PUT /projects/:id/approval_rules/:approval_rule_id
### Delete project-level rule
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/11877) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11877) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.3.
You can delete project approval rules using the following endpoint:
@@ -393,7 +393,7 @@ DELETE /projects/:id/approval_rules/:approval_rule_id
### Change allowed approvers
>**Note:** This API endpoint has been deprecated. Please use Approval Rule API instead.
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/183) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/183) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.6.
If you are allowed to, you can change approvers and approver groups using
the following endpoint:
@@ -505,7 +505,7 @@ GET /projects/:id/merge_requests/:merge_request_iid/approvals
### Change approval configuration
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/183) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/183) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.6.
If you are allowed to, you can change `approvals_required` using the following
endpoint:
@@ -542,7 +542,7 @@ POST /projects/:id/merge_requests/:merge_request_iid/approvals
### Change allowed approvers for Merge Request
>**Note:** This API endpoint has been deprecated. Please use Approval Rule API instead.
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/183) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/183) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.6.
If you are allowed to, you can change approvers and approver groups using
the following endpoint:
@@ -613,7 +613,7 @@ PUT /projects/:id/merge_requests/:merge_request_iid/approvers
### Get the approval state of merge requests
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/13712) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13712) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.3.
You can request information about a merge request's approval state by using the following endpoint:
@@ -685,7 +685,7 @@ This includes additional information about the users who have already approved
### Get merge request level rules
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/13712) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13712) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.3.
You can request information about a merge request's approval rules using the following endpoint:
@@ -762,7 +762,7 @@ GET /projects/:id/merge_requests/:merge_request_iid/approval_rules
### Create merge request level rule
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/11877) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11877) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.3.
You can create merge request approval rules using the following endpoint:
@@ -846,7 +846,7 @@ will be used.
### Update merge request level rule
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/11877) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11877) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.3.
You can update merge request approval rules using the following endpoint:
@@ -931,7 +931,7 @@ These are system generated rules.
### Delete merge request level rule
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/11877) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11877) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.3.
You can delete merge request approval rules using the following endpoint:
diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md
index 3834bb6fee3..41c0428485f 100644
--- a/doc/api/merge_requests.md
+++ b/doc/api/merge_requests.md
@@ -73,9 +73,8 @@ operation. If you are interested in the value of these fields from this
endpoint, set the `with_merge_status_recheck` parameter to `true` in the query.
NOTE: **Note:**
-[Starting in GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/issues/29984),
-when `async_merge_request_check_mergeability` feature flag is enabled, the
-mergeability (`merge_status`) of each merge request will be checked
+[Starting in GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/-/issues/29984),
+the mergeability (`merge_status`) of each merge request will be checked
asynchronously when a request is made to this endpoint. Poll this API endpoint
to get updated status. This affects the `has_conflicts` property as it is
dependent on the `merge_status`. It'll return `false` unless `merge_status` is
@@ -554,9 +553,8 @@ Parameters:
- `include_rebase_in_progress` (optional) - If `true` response includes whether a rebase operation is in progress
NOTE: **Note:**
-[Starting in GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/issues/29984),
-when `async_merge_request_check_mergeability` feature flag is enabled, the
-mergeability (`merge_status`) of a merge request will be checked
+[Starting in GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/-/issues/29984),
+the mergeability (`merge_status`) of a merge request will be checked
asynchronously when a request is made to this endpoint. Poll this API endpoint
to get updated status. This affects the `has_conflicts` property as it is
dependent on the `merge_status`. It'll return `false` unless `merge_status` is
@@ -1297,7 +1295,7 @@ DELETE /projects/:id/merge_requests/:merge_request_iid
| `merge_request_iid` | integer | yes | The internal ID of the merge request |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/4/merge_requests/85
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/4/merge_requests/85"
```
## Accept MR
@@ -1655,7 +1653,7 @@ PUT /projects/:id/merge_requests/:merge_request_iid/rebase
| `skip_ci` | boolean | no | Set to `true` to skip creating a CI pipeline |
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/76/merge_requests/1/rebase
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/76/merge_requests/1/rebase"
```
This is an asynchronous request. The API will return a `202 Accepted` response
@@ -1717,7 +1715,7 @@ GET /projects/:id/merge_requests/:merge_request_iid/closes_issues
| `merge_request_iid` | integer | yes | The internal ID of the merge request |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/76/merge_requests/1/closes_issues
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/76/merge_requests/1/closes_issues"
```
Example response when the GitLab issue tracker is used:
@@ -1793,7 +1791,7 @@ POST /projects/:id/merge_requests/:merge_request_iid/subscribe
| `merge_request_iid` | integer | yes | The internal ID of the merge request |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/merge_requests/17/subscribe
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/17/subscribe"
```
Example response:
@@ -1944,7 +1942,7 @@ POST /projects/:id/merge_requests/:merge_request_iid/unsubscribe
| `merge_request_iid` | integer | yes | The internal ID of the merge request |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/merge_requests/17/unsubscribe
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/17/unsubscribe"
```
Example response:
@@ -2095,7 +2093,7 @@ POST /projects/:id/merge_requests/:merge_request_iid/todo
| `merge_request_iid` | integer | yes | The internal ID of the merge request |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/merge_requests/27/todo
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/27/todo"
```
Example response:
@@ -2212,7 +2210,7 @@ GET /projects/:id/merge_requests/:merge_request_iid/versions
| `merge_request_iid` | integer | yes | The internal ID of the merge request |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/merge_requests/1/versions
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/merge_requests/1/versions"
```
Example response:
@@ -2254,7 +2252,7 @@ GET /projects/:id/merge_requests/:merge_request_iid/versions/:version_id
| `version_id` | integer | yes | The ID of the merge request diff version |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/merge_requests/1/versions/1
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/merge_requests/1/versions/1"
```
Example response:
@@ -2322,7 +2320,7 @@ POST /projects/:id/merge_requests/:merge_request_iid/time_estimate
| `duration` | string | yes | The duration in human format. e.g: 3h30m |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/merge_requests/93/time_estimate?duration=3h30m
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/93/time_estimate?duration=3h30m"
```
Example response:
@@ -2350,7 +2348,7 @@ POST /projects/:id/merge_requests/:merge_request_iid/reset_time_estimate
| `merge_request_iid` | integer | yes | The internal ID of a project's merge_request |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/merge_requests/93/reset_time_estimate
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/93/reset_time_estimate"
```
Example response:
@@ -2379,7 +2377,7 @@ POST /projects/:id/merge_requests/:merge_request_iid/add_spent_time
| `duration` | string | yes | The duration in human format. e.g: 3h30m |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/merge_requests/93/add_spent_time?duration=1h
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/93/add_spent_time?duration=1h"
```
Example response:
@@ -2407,7 +2405,7 @@ POST /projects/:id/merge_requests/:merge_request_iid/reset_spent_time
| `merge_request_iid` | integer | yes | The internal ID of a project's merge_request |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/merge_requests/93/reset_spent_time
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/93/reset_spent_time"
```
Example response:
@@ -2433,7 +2431,7 @@ GET /projects/:id/merge_requests/:merge_request_iid/time_stats
| `merge_request_iid` | integer | yes | The internal ID of the merge request |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/merge_requests/93/time_stats
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/93/time_stats"
```
Example response:
diff --git a/doc/api/merge_trains.md b/doc/api/merge_trains.md
index d8446ed445f..3cfef3864ad 100644
--- a/doc/api/merge_trains.md
+++ b/doc/api/merge_trains.md
@@ -1,6 +1,12 @@
+---
+stage: Verify
+group: Continuous Integration
+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
+---
+
# Merge Trains API **(PREMIUM)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/36146) in GitLab 12.9.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/36146) in GitLab 12.9.
> - Using this API you can consume GitLab's [Merge Train](../ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.md) entries.
Every API call to merge trains must be authenticated with Developer or higher [permissions](../user/permissions.md).
@@ -32,7 +38,7 @@ GET /projects/:id/merge_trains?scope=complete
| `sort` | string | no | Return Merge Trains sorted in `asc` or `desc` order. Default is `desc`. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/merge_trains
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/merge_trains"
```
Example response:
diff --git a/doc/api/metrics_dashboard_annotations.md b/doc/api/metrics_dashboard_annotations.md
index 09187a096ef..05bf7156a7e 100644
--- a/doc/api/metrics_dashboard_annotations.md
+++ b/doc/api/metrics_dashboard_annotations.md
@@ -2,7 +2,7 @@
> - [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 timespan.
+Metrics dashboard annotations allow you to indicate events on your graphs at a single point in time or over a time span.
## Create a new annotation
@@ -12,7 +12,7 @@ POST /clusters/:id/metrics_dashboard/annotations/
```
NOTE: **Note:**
-The value of `dashboard_path` will be treated as a CGI-escaped path, and automatically unescaped.
+The value of `dashboard_path` will be treated as a CGI-escaped path, and automatically un-escaped.
Parameters:
@@ -24,7 +24,7 @@ Parameters:
| `description` | string | yes | Description of the annotation. |
```shell
-curl --header 'Private-Token: <your_access_token>' https://gitlab.example.com/api/v4/environments/1/metrics_dashboard/annotations \
+curl --header "Private-Token: <your_access_token>" "https://gitlab.example.com/api/v4/environments/1/metrics_dashboard/annotations" \
--data-urlencode "dashboard_path=.gitlab/dashboards/custom_metrics.yml" \
--data-urlencode "starting_at=2016-03-11T03:45:40Z" \
--data-urlencode "description=annotation description"
diff --git a/doc/api/milestones.md b/doc/api/milestones.md
index 5727a4b637f..b5702c7d6e0 100644
--- a/doc/api/milestones.md
+++ b/doc/api/milestones.md
@@ -1,5 +1,14 @@
+---
+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/#designated-technical-writers
+---
+
# Project milestones API
+This page describes the project milestones API.
+There's a separate [group milestones API](./group_milestones.md) page.
+
## List project milestones
Returns a list of project milestones.
@@ -25,7 +34,7 @@ Parameters:
| `search` | string | optional | Return only milestones with a title or description matching the provided string |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/milestones
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/milestones"
```
Example Response:
@@ -135,7 +144,7 @@ Parameters:
## Promote project milestone to a group milestone
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/53861) in GitLab 11.9
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53861) in GitLab 11.9
Only for users with Developer access to the group.
@@ -150,7 +159,7 @@ Parameters:
## Get all burndown chart events for a single milestone **(STARTER)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/4737) in GitLab 12.1
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4737) in GitLab 12.1
Gets all burndown chart events for a single milestone.
diff --git a/doc/api/namespaces.md b/doc/api/namespaces.md
index 50b5f3f19cd..d1a2812bfb4 100644
--- a/doc/api/namespaces.md
+++ b/doc/api/namespaces.md
@@ -19,7 +19,7 @@ GET /namespaces
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/namespaces
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/namespaces"
```
Example response:
@@ -85,7 +85,7 @@ GET /namespaces?search=foobar
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/namespaces?search=twitter
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/namespaces?search=twitter"
```
Example response:
@@ -119,7 +119,7 @@ GET /namespaces/:id
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/namespaces/2
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/namespaces/2"
```
Example response:
@@ -139,7 +139,7 @@ Example response:
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/namespaces/group1
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/namespaces/group1"
```
Example response:
diff --git a/doc/api/notes.md b/doc/api/notes.md
index 62e1fe44bae..74d941edec1 100644
--- a/doc/api/notes.md
+++ b/doc/api/notes.md
@@ -82,7 +82,7 @@ GET /projects/:id/issues/:issue_iid/notes?sort=asc&order_by=updated_at
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/issues/11/notes
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/11/notes"
```
### Get single issue note
@@ -100,7 +100,7 @@ Parameters:
- `note_id` (required) - The ID of an issue note
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/issues/11/notes/1
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/11/notes/1"
```
### Create new issue note
@@ -119,7 +119,7 @@ Parameters:
- `created_at` (optional) - Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin 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/notes?body=note
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/11/notes?body=note"
```
### Modify existing issue note
@@ -138,7 +138,7 @@ Parameters:
- `body` (required) - The content of a note. Limited to 1,000,000 characters.
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/issues/11/notes?body=note
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/11/notes?body=note"
```
### Delete an issue note
@@ -158,7 +158,7 @@ Parameters:
| `note_id` | integer | yes | The ID of a note |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/issues/11/notes/636
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/11/notes/636"
```
## Snippets
@@ -180,7 +180,7 @@ GET /projects/:id/snippets/:snippet_id/notes?sort=asc&order_by=updated_at
| `order_by` | string | no | Return snippet notes ordered by `created_at` or `updated_at` fields. Default is `created_at`
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/snippets/11/notes
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/snippets/11/notes"
```
### Get single snippet note
@@ -217,7 +217,7 @@ Parameters:
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/snippets/11/notes/11
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/snippets/11/notes/11"
```
### Create new snippet note
@@ -237,7 +237,7 @@ Parameters:
- `created_at` (optional) - Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/snippet/11/notes?body=note
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/snippet/11/notes?body=note"
```
### Modify existing snippet note
@@ -256,7 +256,7 @@ Parameters:
- `body` (required) - The content of a note. Limited to 1,000,000 characters.
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/snippets/11/notes?body=note
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/snippets/11/notes?body=note"
```
### Delete a snippet note
@@ -276,7 +276,7 @@ Parameters:
| `note_id` | integer | yes | The ID of a note |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/snippets/52/notes/1659
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/snippets/52/notes/1659"
```
## Merge Requests
@@ -298,7 +298,7 @@ GET /projects/:id/merge_requests/:merge_request_iid/notes?sort=asc&order_by=upda
| `order_by` | string | no | Return merge request notes ordered by `created_at` or `updated_at` fields. Default is `created_at`
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/merge_requests/11/notes
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/notes"
```
### Get single merge request note
@@ -340,7 +340,7 @@ Parameters:
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/merge_requests/11/notes/1
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/notes/1"
```
### Create new merge request note
@@ -376,7 +376,7 @@ Parameters:
- `body` (required) - The content of a note. Limited to 1,000,000 characters.
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/merge_requests/11/notes?body=note
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/notes?body=note"
```
### Delete a merge request note
@@ -396,7 +396,7 @@ Parameters:
| `note_id` | integer | yes | The ID of a note |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/merge_requests/7/notes/1602
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/7/notes/1602"
```
## Epics **(ULTIMATE)**
@@ -418,7 +418,7 @@ GET /groups/:id/epics/:epic_id/notes?sort=asc&order_by=updated_at
| `order_by` | string | no | Return epic notes ordered by `created_at` or `updated_at` fields. Default is `created_at` |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/5/epics/11/notes
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/epics/11/notes"
```
### Get single epic note
@@ -458,7 +458,7 @@ Parameters:
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/5/epics/11/notes/1
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/epics/11/notes/1"
```
### Create new epic note
@@ -479,7 +479,7 @@ Parameters:
| `body` | string | yes | The content of a note. Limited to 1,000,000 characters. |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/snippet/11/notes?body=note
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/snippet/11/notes?body=note"
```
### Modify existing epic note
@@ -500,7 +500,7 @@ Parameters:
| `body` | string | yes | The content of a note. Limited to 1,000,000 characters. |
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/snippet/11/notes?body=note
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/snippet/11/notes?body=note"
```
### Delete an epic note
@@ -520,5 +520,5 @@ Parameters:
| `note_id` | integer | yes | The ID of a note |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/5/epics/52/notes/1659
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/epics/52/notes/1659"
```
diff --git a/doc/api/notification_settings.md b/doc/api/notification_settings.md
index 596365743fa..ffdf6d34832 100644
--- a/doc/api/notification_settings.md
+++ b/doc/api/notification_settings.md
@@ -43,7 +43,7 @@ GET /notification_settings
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/notification_settings
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/notification_settings"
```
Example response:
@@ -64,7 +64,7 @@ PUT /notification_settings
```
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/notification_settings?level=watch
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/notification_settings?level=watch"
```
| Attribute | Type | Required | Description |
@@ -107,8 +107,8 @@ GET /projects/:id/notification_settings
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/5/notification_settings
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/8/notification_settings
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/notification_settings"
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/8/notification_settings"
```
| Attribute | Type | Required | Description |
@@ -133,8 +133,8 @@ PUT /projects/:id/notification_settings
```
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/5/notification_settings?level=watch
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/8/notification_settings?level=custom&new_note=true
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/notification_settings?level=watch"
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/8/notification_settings?level=custom&new_note=true"
```
| Attribute | Type | Required | Description |
diff --git a/doc/api/oauth2.md b/doc/api/oauth2.md
index a146fdd0d0c..cc8b31ecf17 100644
--- a/doc/api/oauth2.md
+++ b/doc/api/oauth2.md
@@ -173,11 +173,14 @@ the following parameters:
}
```
+Also you must use HTTP Basic authentication using the `client_id` and`client_secret`
+values to authenticate the client that performs a request.
+
Example cURL request:
```shell
echo 'grant_type=password&username=<your_username>&password=<your_password>' > auth.txt
-curl --data "@auth.txt" --request POST https://gitlab.example.com/oauth/token
+curl --data "@auth.txt" --user client_id:client_secret --request POST "https://gitlab.example.com/oauth/token"
```
Then, you'll receive the access token back in the response:
@@ -190,6 +193,8 @@ Then, you'll receive the access token back in the response:
}
```
+By default, the scope of the access token is `api`, which provides complete read/write access.
+
For testing, you can use the `oauth2` Ruby gem:
```ruby
@@ -210,7 +215,7 @@ GET https://gitlab.example.com/api/v4/user?access_token=OAUTH-TOKEN
or you can put the token to the Authorization header:
```shell
-curl --header "Authorization: Bearer OAUTH-TOKEN" https://gitlab.example.com/api/v4/user
+curl --header "Authorization: Bearer OAUTH-TOKEN" "https://gitlab.example.com/api/v4/user"
```
## Retrieving the token information
@@ -229,7 +234,7 @@ You must supply the access token, either:
- In the Authorization header:
```shell
- curl --header "Authorization: Bearer <OAUTH-TOKEN>" https://gitlab.example.com/oauth/token/info
+ curl --header "Authorization: Bearer <OAUTH-TOKEN>" "https://gitlab.example.com/oauth/token/info"
```
The following is an example response:
diff --git a/doc/api/packages.md b/doc/api/packages.md
index 784343d29fd..ca7113bc743 100644
--- a/doc/api/packages.md
+++ b/doc/api/packages.md
@@ -1,3 +1,9 @@
+---
+stage: Package
+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/#designated-technical-writers
+---
+
# Packages API **(PREMIUM)**
This is the API docs of [GitLab Packages](../administration/packages/index.md).
@@ -20,11 +26,11 @@ GET /projects/:id/packages
| `id` | integer/string | yes | ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) |
| `order_by`| string | no | The field to use as order. One of `created_at` (default), `name`, `version`, or `type`. |
| `sort` | string | no | The direction of the order, either `asc` (default) for ascending order or `desc` for descending order. |
-| `package_type` | string | no | Filter the returned packages by type. One of `conan`, `maven`, `npm`, `pypi` or `nuget`. (_Introduced in GitLab 12.9_)
+| `package_type` | string | no | Filter the returned packages by type. One of `conan`, `maven`, `npm`, `pypi`, `composer`, or `nuget`. (_Introduced in GitLab 12.9_)
| `package_name` | string | no | Filter the project packages with a fuzzy search by name. (_Introduced in GitLab 12.9_)
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:id/packages
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/packages"
```
Example response:
@@ -67,11 +73,11 @@ GET /groups/:id/packages
| `exclude_subgroups` | boolean | false | If the parameter is included as true, packages from projects from subgroups are not listed. Default is `false`. |
| `order_by`| string | no | The field to use as order. One of `created_at` (default), `name`, `version`, `type`, or `project_path`. |
| `sort` | string | no | The direction of the order, either `asc` (default) for ascending order or `desc` for descending order. |
-| `package_type` | string | no | Filter the returned packages by type. One of `conan`, `maven`, `npm`, `pypi` or `nuget`. (_Introduced in GitLab 12.9_) |
+| `package_type` | string | no | Filter the returned packages by type. One of `conan`, `maven`, `npm`, `pypi`, `composer`, or `nuget`. (_Introduced in GitLab 12.9_) |
| `package_name` | string | no | Filter the project packages with a fuzzy search by name. (_[Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30980) in GitLab 13.0_)
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/:id/packages?exclude_subgroups=true
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/packages?exclude_subgroups=true"
```
CAUTION: **Deprecation**
@@ -156,7 +162,7 @@ GET /projects/:id/packages/:package_id
| `package_id` | integer | yes | ID of a package. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:id/packages/:package_id
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/packages/:package_id"
```
CAUTION: **Deprecation**
@@ -233,7 +239,7 @@ GET /projects/:id/packages/:package_id/package_files
| `package_id` | integer | yes | ID of a package. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/packages/4/package_files
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/packages/4/package_files"
```
Example response:
@@ -288,7 +294,7 @@ DELETE /projects/:id/packages/:package_id
| `package_id` | integer | yes | ID of a package. |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:id/packages/:package_id
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/packages/:package_id"
```
Can return the following status codes:
diff --git a/doc/api/pages.md b/doc/api/pages.md
index db39ab04d9d..fda4a70cbd9 100644
--- a/doc/api/pages.md
+++ b/doc/api/pages.md
@@ -1,3 +1,9 @@
+---
+stage: Release
+group: Release 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/#designated-technical-writers
+---
+
# Pages API
Endpoints for managing [GitLab Pages](https://about.gitlab.com/stages-devops-lifecycle/pages/).
@@ -17,5 +23,5 @@ DELETE /projects/:id/pages
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
```shell
-curl --request 'DELETE' --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/2/pages
+curl --request 'DELETE' --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/2/pages"
```
diff --git a/doc/api/pages_domains.md b/doc/api/pages_domains.md
index 43bb5a9b774..1fddc79814f 100644
--- a/doc/api/pages_domains.md
+++ b/doc/api/pages_domains.md
@@ -1,3 +1,9 @@
+---
+stage: Release
+group: Release 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/#designated-technical-writers
+---
+
# Pages domains API
Endpoints for connecting custom domain(s) and TLS certificates in [GitLab Pages](https://about.gitlab.com/stages-devops-lifecycle/pages/).
@@ -13,7 +19,7 @@ GET /pages/domains
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/pages/domains
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/pages/domains"
```
```json
@@ -44,7 +50,7 @@ GET /projects/:id/pages/domains
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.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/pages/domains
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/pages/domains"
```
```json
@@ -81,7 +87,7 @@ GET /projects/:id/pages/domains/:domain
| `domain` | string | yes | The custom domain indicated by the user |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/pages/domains/www.domain.example
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/pages/domains/www.domain.example"
```
```json
@@ -92,7 +98,7 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/ap
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example"
```
```json
@@ -126,15 +132,15 @@ POST /projects/:id/pages/domains
| `key` | file/string | no | The certificate key in PEM format. |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form "domain=ssl.domain.example" --form "certificate=@/path/to/cert.pem" --form "key=@/path/to/key.pem" https://gitlab.example.com/api/v4/projects/5/pages/domains
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form "domain=ssl.domain.example" --form "certificate=@/path/to/cert.pem" --form "key=@/path/to/key.pem" "https://gitlab.example.com/api/v4/projects/5/pages/domains"
```
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form "domain=ssl.domain.example" --form "certificate=$CERT_PEM" --form "key=$KEY_PEM" https://gitlab.example.com/api/v4/projects/5/pages/domains
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form "domain=ssl.domain.example" --form "certificate=$CERT_PEM" --form "key=$KEY_PEM" "https://gitlab.example.com/api/v4/projects/5/pages/domains"
```
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form "domain=ssl.domain.example" --form "auto_ssl_enabled=true" https://gitlab.example.com/api/v4/projects/5/pages/domains
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form "domain=ssl.domain.example" --form "auto_ssl_enabled=true" "https://gitlab.example.com/api/v4/projects/5/pages/domains"
```
```json
@@ -170,11 +176,11 @@ PUT /projects/:id/pages/domains/:domain
### Adding certificate
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" --form "certificate=@/path/to/cert.pem" --form "key=@/path/to/key.pem" https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" --form "certificate=@/path/to/cert.pem" --form "key=@/path/to/key.pem" "https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example"
```
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" --form "certificate=$CERT_PEM" --form "key=$KEY_PEM" https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" --form "certificate=$CERT_PEM" --form "key=$KEY_PEM" "https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example"
```
```json
@@ -194,7 +200,7 @@ curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" --form "certifi
### Enabling Let's Encrypt integration for Pages custom domains
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" --form "auto_ssl_enabled=true" https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" --form "auto_ssl_enabled=true" "https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example"
```
```json
@@ -210,7 +216,7 @@ curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" --form "auto_ss
To remove the SSL certificate attached to the Pages domain, run:
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" --form "certificate=" --form "key=" https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" --form "certificate=" --form "key=" "https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example"
```
```json
@@ -235,5 +241,5 @@ DELETE /projects/:id/pages/domains/:domain
| `domain` | string | yes | The custom domain indicated by the user |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example"
```
diff --git a/doc/api/pipeline_schedules.md b/doc/api/pipeline_schedules.md
index 36a18411ceb..dc16157ef4b 100644
--- a/doc/api/pipeline_schedules.md
+++ b/doc/api/pipeline_schedules.md
@@ -16,7 +16,7 @@ GET /projects/:id/pipeline_schedules
| `scope` | string | no | The scope of pipeline schedules, one of: `active`, `inactive` |
```shell
-curl --header "PRIVATE-TOKEN: k5ESFgWY2Qf5xEvDcFxZ" "https://gitlab.example.com/api/v4/projects/29/pipeline_schedules"
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/29/pipeline_schedules"
```
```json
@@ -57,7 +57,7 @@ GET /projects/:id/pipeline_schedules/:pipeline_schedule_id
| `pipeline_schedule_id` | integer | yes | The pipeline schedule ID |
```shell
-curl --header "PRIVATE-TOKEN: k5ESFgWY2Qf5xEvDcFxZ" "https://gitlab.example.com/api/v4/projects/29/pipeline_schedules/13"
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/29/pipeline_schedules/13"
```
```json
@@ -113,7 +113,7 @@ POST /projects/:id/pipeline_schedules
| `active` | boolean | no | The activation of pipeline schedule. If false is set, the pipeline schedule will deactivated initially (default: `true`) |
```shell
-curl --request POST --header "PRIVATE-TOKEN: k5ESFgWY2Qf5xEvDcFxZ" --form description="Build packages" --form ref="master" --form cron="0 1 * * 5" --form cron_timezone="UTC" --form active="true" "https://gitlab.example.com/api/v4/projects/29/pipeline_schedules"
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form description="Build packages" --form ref="master" --form cron="0 1 * * 5" --form cron_timezone="UTC" --form active="true" "https://gitlab.example.com/api/v4/projects/29/pipeline_schedules"
```
```json
@@ -158,7 +158,7 @@ PUT /projects/:id/pipeline_schedules/:pipeline_schedule_id
| `active` | boolean | no | The activation of pipeline schedule. If false is set, the pipeline schedule will deactivated initially. |
```shell
-curl --request PUT --header "PRIVATE-TOKEN: k5ESFgWY2Qf5xEvDcFxZ" --form cron="0 2 * * *" "https://gitlab.example.com/api/v4/projects/29/pipeline_schedules/13"
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" --form cron="0 2 * * *" "https://gitlab.example.com/api/v4/projects/29/pipeline_schedules/13"
```
```json
@@ -203,7 +203,7 @@ POST /projects/:id/pipeline_schedules/:pipeline_schedule_id/take_ownership
| `pipeline_schedule_id` | integer | yes | The pipeline schedule ID |
```shell
-curl --request POST --header "PRIVATE-TOKEN: hf2CvZXB9w8Uc5pZKpSB" "https://gitlab.example.com/api/v4/projects/29/pipeline_schedules/13/take_ownership"
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/29/pipeline_schedules/13/take_ownership"
```
```json
@@ -248,7 +248,7 @@ DELETE /projects/:id/pipeline_schedules/:pipeline_schedule_id
| `pipeline_schedule_id` | integer | yes | The pipeline schedule ID |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: k5ESFgWY2Qf5xEvDcFxZ" "https://gitlab.example.com/api/v4/projects/29/pipeline_schedules/13"
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/29/pipeline_schedules/13"
```
```json
@@ -281,7 +281,7 @@ curl --request DELETE --header "PRIVATE-TOKEN: k5ESFgWY2Qf5xEvDcFxZ" "https://gi
## Run a scheduled pipeline immediately
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/201786) in GitLab 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/201786) in GitLab 12.8.
Trigger a new scheduled pipeline, which runs immediately. The next scheduled run
of this pipeline is not affected.
@@ -298,7 +298,7 @@ POST /projects/:id/pipeline_schedules/:pipeline_schedule_id/play
Example request:
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/42/pipeline_schedules/1/play
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/42/pipeline_schedules/1/play"
```
Example response:
@@ -311,7 +311,7 @@ Example response:
## Pipeline schedule variables
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/34518) in GitLab 10.0.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/34518) in GitLab 10.0.
## Create a new pipeline schedule variable
@@ -330,7 +330,7 @@ POST /projects/:id/pipeline_schedules/:pipeline_schedule_id/variables
| `variable_type` | string | no | The type of a variable. Available types are: `env_var` (default) and `file` |
```shell
-curl --request POST --header "PRIVATE-TOKEN: k5ESFgWY2Qf5xEvDcFxZ" --form "key=NEW_VARIABLE" --form "value=new value" "https://gitlab.example.com/api/v4/projects/29/pipeline_schedules/13/variables"
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form "key=NEW_VARIABLE" --form "value=new value" "https://gitlab.example.com/api/v4/projects/29/pipeline_schedules/13/variables"
```
```json
@@ -358,7 +358,7 @@ PUT /projects/:id/pipeline_schedules/:pipeline_schedule_id/variables/:key
| `variable_type` | string | no | The type of a variable. Available types are: `env_var` (default) and `file` |
```shell
-curl --request PUT --header "PRIVATE-TOKEN: k5ESFgWY2Qf5xEvDcFxZ" --form "value=updated value" "https://gitlab.example.com/api/v4/projects/29/pipeline_schedules/13/variables/NEW_VARIABLE"
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" --form "value=updated value" "https://gitlab.example.com/api/v4/projects/29/pipeline_schedules/13/variables/NEW_VARIABLE"
```
```json
@@ -384,7 +384,7 @@ DELETE /projects/:id/pipeline_schedules/:pipeline_schedule_id/variables/:key
| `key` | string | yes | The `key` of a variable |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: k5ESFgWY2Qf5xEvDcFxZ" "https://gitlab.example.com/api/v4/projects/29/pipeline_schedules/13/variables/NEW_VARIABLE"
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/29/pipeline_schedules/13/variables/NEW_VARIABLE"
```
```json
diff --git a/doc/api/project_aliases.md b/doc/api/project_aliases.md
index 59c0ffee76d..d80decfe53c 100644
--- a/doc/api/project_aliases.md
+++ b/doc/api/project_aliases.md
@@ -1,6 +1,6 @@
# Project Aliases API **(PREMIUM ONLY)**
-> [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 Premium](https://about.gitlab.com/pricing/) 12.1.
All methods require administrator authorization.
diff --git a/doc/api/project_badges.md b/doc/api/project_badges.md
index 4adeb50deca..86b1ba6ce19 100644
--- a/doc/api/project_badges.md
+++ b/doc/api/project_badges.md
@@ -25,7 +25,7 @@ GET /projects/:id/badges
| `name` | string | no | Name of the badges to return (case-sensitive). |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:id/badges
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/badges"
```
Example response:
@@ -67,7 +67,7 @@ GET /projects/:id/badges/:badge_id
| `badge_id` | integer | yes | The badge ID |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:id/badges/:badge_id
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/badges/:badge_id"
```
Example response:
@@ -98,7 +98,7 @@ POST /projects/:id/badges
| `image_url` | string | yes | URL of the badge image |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --data "link_url=https://gitlab.com/gitlab-org/gitlab-foss/commits/master&image_url=https://shields.io/my/badge1&position=0" https://gitlab.example.com/api/v4/projects/:id/badges
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --data "link_url=https://gitlab.com/gitlab-org/gitlab-foss/commits/master&image_url=https://shields.io/my/badge1&position=0" "https://gitlab.example.com/api/v4/projects/:id/badges"
```
Example response:
@@ -130,7 +130,7 @@ PUT /projects/:id/badges/:badge_id
| `image_url` | string | no | URL of the badge image |
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:id/badges/:badge_id
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/badges/:badge_id"
```
Example response:
@@ -160,7 +160,7 @@ DELETE /projects/:id/badges/:badge_id
| `badge_id` | integer | yes | The badge ID |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:id/badges/:badge_id
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/badges/:badge_id"
```
## Preview a badge from a project
@@ -178,7 +178,7 @@ GET /projects/:id/badges/render
| `image_url` | string | yes | URL of the badge image |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:id/badges/render?link_url=http%3A%2F%2Fexample.com%2Fci_status.svg%3Fproject%3D%25%7Bproject_path%7D%26ref%3D%25%7Bdefault_branch%7D&image_url=https%3A%2F%2Fshields.io%2Fmy%2Fbadge
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/badges/render?link_url=http%3A%2F%2Fexample.com%2Fci_status.svg%3Fproject%3D%25%7Bproject_path%7D%26ref%3D%25%7Bdefault_branch%7D&image_url=https%3A%2F%2Fshields.io%2Fmy%2Fbadge"
```
Example response:
diff --git a/doc/api/project_clusters.md b/doc/api/project_clusters.md
index 79800af2f59..f7c8ffc8df6 100644
--- a/doc/api/project_clusters.md
+++ b/doc/api/project_clusters.md
@@ -22,7 +22,7 @@ Parameters:
Example request:
```shell
-curl --header 'Private-Token: <your_access_token>' https://gitlab.example.com/api/v4/projects/26/clusters
+curl --header 'Private-Token: <your_access_token>' "https://gitlab.example.com/api/v4/projects/26/clusters"
```
Example response:
@@ -91,7 +91,7 @@ Parameters:
Example request:
```shell
-curl --header 'Private-Token: <your_access_token>' https://gitlab.example.com/api/v4/projects/26/clusters/18
+curl --header "Private-Token: <your_access_token>" "https://gitlab.example.com/api/v4/projects/26/clusters/18"
```
Example response:
@@ -192,7 +192,7 @@ Parameters:
Example request:
```shell
-curl --header 'Private-Token: <your_access_token>' https://gitlab.example.com/api/v4/projects/26/clusters/user \
+curl --header 'Private-Token: <your_access_token>' "https://gitlab.example.com/api/v4/projects/26/clusters/user" \
-H "Accept: application/json" \
-H "Content-Type:application/json" \
-X POST --data '{"name":"cluster-5", "platform_kubernetes_attributes":{"api_url":"https://35.111.51.20","token":"12345","namespace":"cluster-5-namespace","ca_cert":"-----BEGIN CERTIFICATE-----\r\nhFiK1L61owwDQYJKoZIhvcNAQELBQAw\r\nLzEtMCsGA1UEAxMkZDA1YzQ1YjctNzdiMS00NDY0LThjNmEtMTQ0ZDJkZjM4ZDBj\r\nMB4XDTE4MTIyNzIwMDM1MVoXDTIzMTIyNjIxMDM1MVowLzEtMCsGA1UEAxMkZDA1\r\nYzQ1YjctNzdiMS00NDY0LThjNmEtMTQ0ZDJkZjM.......-----END CERTIFICATE-----"}}'
@@ -289,7 +289,7 @@ through the ["Add existing cluster to project"](#add-existing-cluster-to-project
Example request:
```shell
-curl --header 'Private-Token: <your_access_token>' https://gitlab.example.com/api/v4/projects/26/clusters/24 \
+curl --header 'Private-Token: <your_access_token>' "https://gitlab.example.com/api/v4/projects/26/clusters/24" \
-H "Content-Type:application/json" \
-X PUT --data '{"name":"new-cluster-name","domain":"new-domain.com","api_url":"https://new-api-url.com"}'
```
@@ -383,5 +383,5 @@ Parameters:
Example request:
```shell
-curl --request DELETE --header 'Private-Token: <your_access_token>' https://gitlab.example.com/api/v4/projects/26/clusters/23
+curl --request DELETE --header 'Private-Token: <your_access_token>' "https://gitlab.example.com/api/v4/projects/26/clusters/23"
```
diff --git a/doc/api/project_import_export.md b/doc/api/project_import_export.md
index ae2fbcec0ff..74902a22594 100644
--- a/doc/api/project_import_export.md
+++ b/doc/api/project_import_export.md
@@ -1,6 +1,6 @@
# Project import/export API
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/41899) in GitLab 10.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41899) in GitLab 10.6.
See also:
@@ -31,7 +31,7 @@ POST /projects/:id/export
| `upload[http_method]` | string | no | The HTTP method to upload the exported project. Only `PUT` and `POST` methods allowed. Default is `PUT` |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/export \
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/export" \
--data "upload[http_method]=PUT" \
--data-urlencode "upload[url]=https://example-bucket.s3.eu-west-3.amazonaws.com/backup?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIMBJHN2O62W8IELQ%2F20180312%2Feu-west-3%2Fs3%2Faws4_request&X-Amz-Date=20180312T110328Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Signature=8413facb20ff33a49a147a0b4abcff4c8487cc33ee1f7e450c46e8f695569dbd"
```
@@ -58,7 +58,7 @@ GET /projects/:id/export
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/export
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/export"
```
Status can be one of:
@@ -111,7 +111,7 @@ GET /projects/:id/export/download
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" --remote-header-name --remote-name https://gitlab.example.com/api/v4/projects/5/export/download
+curl --header "PRIVATE-TOKEN: <your_access_token>" --remote-header-name --remote-name "https://gitlab.example.com/api/v4/projects/5/export/download"
```
```shell
@@ -142,7 +142,7 @@ The `file=` parameter must point to a file on your file system and be preceded
by `@`. For example:
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form "path=api-project" --form "file=@/path/to/file" https://gitlab.example.com/api/v4/projects/import
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form "path=api-project" --form "file=@/path/to/file" "https://gitlab.example.com/api/v4/projects/import"
```
cURL doesn't support posting a file from a remote server. Importing a project from a remote server can be accomplished through something like the following:
@@ -181,6 +181,10 @@ requests.post(url, headers=headers, data=data, files=files)
}
```
+NOTE: **Note:**
+The maximum import file size can be set by the Administrator, default is 50MB.
+As an administrator, you can modify the maximum import file size. To do so, use the `max_import_size` option in the [Application settings API](settings.md#change-application-settings) or the [Admin UI](../user/admin_area/settings/account_and_limit_settings.md).
+
## Import status
Get the status of an import.
@@ -194,7 +198,7 @@ GET /projects/:id/import
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/import
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/import"
```
Status can be one of:
diff --git a/doc/api/project_repository_storage_moves.md b/doc/api/project_repository_storage_moves.md
index 8df472f193f..c55d4a19feb 100644
--- a/doc/api/project_repository_storage_moves.md
+++ b/doc/api/project_repository_storage_moves.md
@@ -1,3 +1,10 @@
+---
+stage: Create
+group: Gitaly
+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
+---
+
# Project repository storage move API
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31285) in GitLab 13.0.
@@ -16,7 +23,50 @@ are [paginated](README.md#pagination).
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://primary.example.com/api/v4/project_repository_storage_moves'
+curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/project_repository_storage_moves'
+```
+
+Example response:
+
+```json
+[
+ {
+ "id": 1,
+ "created_at": "2020-05-07T04:27:17.234Z",
+ "state": "scheduled",
+ "source_storage_name": "default",
+ "destination_storage_name": "storage2",
+ "project": {
+ "id": 1,
+ "description": null,
+ "name": "project1",
+ "name_with_namespace": "John Doe2 / project1",
+ "path": "project1",
+ "path_with_namespace": "namespace1/project1",
+ "created_at": "2020-05-07T04:27:17.016Z"
+ }
+]
+```
+
+## Retrieve all repository storage moves for a project
+
+```plaintext
+GET /projects/:project_id/repository_storage_moves
+```
+
+By default, `GET` requests return 20 results at a time because the API results
+are [paginated](README.md#pagination).
+
+Parameters:
+
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `project_id` | integer | yes | ID of the project |
+
+Example request:
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/1/repository_storage_moves'
```
Example response:
@@ -44,19 +94,98 @@ Example response:
## Get a single project repository storage move
```plaintext
-GET /project_repository_storage_moves/:id
+GET /project_repository_storage_moves/:repository_storage_id
+```
+
+Parameters:
+
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `repository_storage_id` | integer | yes | ID of the project repository storage move |
+
+Example request:
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/project_repository_storage_moves/1'
+```
+
+Example response:
+
+```json
+{
+ "id": 1,
+ "created_at": "2020-05-07T04:27:17.234Z",
+ "state": "scheduled",
+ "source_storage_name": "default",
+ "destination_storage_name": "storage2",
+ "project": {
+ "id": 1,
+ "description": null,
+ "name": "project1",
+ "name_with_namespace": "John Doe2 / project1",
+ "path": "project1",
+ "path_with_namespace": "namespace1/project1",
+ "created_at": "2020-05-07T04:27:17.016Z"
+}
+```
+
+## Get a single repository storage move for a project
+
+```plaintext
+GET /projects/:project_id/repository_storage_moves/:repository_storage_id
+```
+
+Parameters:
+
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `project_id` | integer | yes | ID of the project |
+| `repository_storage_id` | integer | yes | ID of the project repository storage move |
+
+Example request:
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/1/repository_storage_moves/1'
+```
+
+Example response:
+
+```json
+{
+ "id": 1,
+ "created_at": "2020-05-07T04:27:17.234Z",
+ "state": "scheduled",
+ "source_storage_name": "default",
+ "destination_storage_name": "storage2",
+ "project": {
+ "id": 1,
+ "description": null,
+ "name": "project1",
+ "name_with_namespace": "John Doe2 / project1",
+ "path": "project1",
+ "path_with_namespace": "namespace1/project1",
+ "created_at": "2020-05-07T04:27:17.016Z"
+}
+```
+
+## Schedule a repository storage move for a project
+
+```plaintext
+POST /projects/:project_id/repository_storage_moves
```
Parameters:
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
-| `id` | integer | yes | The ID of the project repository storage move |
+| `project_id` | integer | yes | ID of the project |
+| `destination_storage_name` | string | yes | Name of the destination storage shard |
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://primary.example.com/api/v4/project_repository_storage_moves/1'
+curl --request POST --header "PRIVATE_TOKEN: <your_access_token>" --header "Content-Type: application/json" \
+--data '{"destination_storage_name":"storage2"}' 'https://gitlab.example.com/api/v4/projects/1/repository_storage_moves'
```
Example response:
diff --git a/doc/api/project_snippets.md b/doc/api/project_snippets.md
index e435f87dcdb..e5dd85fb3bb 100644
--- a/doc/api/project_snippets.md
+++ b/doc/api/project_snippets.md
@@ -17,7 +17,7 @@ NOTE: **Note:**
From July 2019, the `Internal` visibility setting is disabled for new projects, groups,
and snippets on GitLab.com. Existing projects, groups, and snippets using the `Internal`
visibility setting keep this setting. You can read more about the change in the
-[relevant issue](https://gitlab.com/gitlab-org/gitlab/issues/12388).
+[relevant issue](https://gitlab.com/gitlab-org/gitlab/-/issues/12388).
## List snippets
@@ -86,7 +86,7 @@ Parameters:
Example request:
```shell
-curl --request POST https://gitlab.com/api/v4/projects/:id/snippets \
+curl --request POST "https://gitlab.com/api/v4/projects/:id/snippets" \
--header "PRIVATE-TOKEN: <your access token>" \
--header "Content-Type: application/json" \
-d @snippet.json
@@ -125,7 +125,7 @@ Parameters:
Example request:
```shell
-curl --request PUT https://gitlab.com/api/v4/projects/:id/snippets/:snippet_id \
+curl --request PUT "https://gitlab.com/api/v4/projects/:id/snippets/:snippet_id" \
--header "PRIVATE-TOKEN: <your_access_token>" \
--header "Content-Type: application/json" \
-d @snippet.json
@@ -159,7 +159,7 @@ Parameters:
Example request:
```shell
-curl --request DELETE https://gitlab.com/api/v4/projects/:id/snippets/:snippet_id \
+curl --request DELETE "https://gitlab.com/api/v4/projects/:id/snippets/:snippet_id" \
--header "PRIVATE-TOKEN: <your_access_token>"
```
@@ -179,13 +179,13 @@ Parameters:
Example request:
```shell
-curl https://gitlab.com/api/v4/projects/:id/snippets/:snippet_id/raw \
+curl "https://gitlab.com/api/v4/projects/:id/snippets/:snippet_id/raw" \
--header "PRIVATE-TOKEN: <your_access_token>"
```
## Get user agent details
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/29508) in GitLab 9.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/29508) in GitLab 9.4.
Available only for admins.
@@ -201,7 +201,7 @@ GET /projects/:id/snippets/:snippet_id/user_agent_detail
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/snippets/2/user_agent_detail
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/snippets/2/user_agent_detail"
```
Example response:
diff --git a/doc/api/project_templates.md b/doc/api/project_templates.md
index 0c1b483600f..e9658423b63 100644
--- a/doc/api/project_templates.md
+++ b/doc/api/project_templates.md
@@ -4,7 +4,7 @@ This API is a project-specific version of these endpoints:
- [Dockerfile templates](templates/dockerfiles.md)
- [Gitignore templates](templates/gitignores.md)
-- [GitLab CI/CD Config templates](templates/gitlab_ci_ymls.md)
+- [GitLab CI/CD Configuration templates](templates/gitlab_ci_ymls.md)
- [Open source license templates](templates/licenses.md)
It deprecates these endpoints, which will be removed for API version 5.
@@ -16,7 +16,7 @@ Support will be added for [Issue and Merge Request templates](../user/project/de
in a future release.
Support for [Group-level file templates](../user/group/index.md#group-file-templates-premium)
-**(PREMIUM)** was [added](https://gitlab.com/gitlab-org/gitlab/issues/5987)
+**(PREMIUM)** was [added](https://gitlab.com/gitlab-org/gitlab/-/issues/5987)
in GitLab 11.5
## Get all templates of a particular type
diff --git a/doc/api/project_vulnerabilities.md b/doc/api/project_vulnerabilities.md
index 84bbc789b0c..c4f1adccd3c 100644
--- a/doc/api/project_vulnerabilities.md
+++ b/doc/api/project_vulnerabilities.md
@@ -1,14 +1,6 @@
# Project Vulnerabilities API **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/10242) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.6.
-
-CAUTION: **Caution:**
-This API is currently in development and is protected by a **disabled**
-[feature flag](../development/feature_flags/index.md).
-On a self-managed GitLab instance, an administrator can enable it by starting the Rails console
-(`sudo gitlab-rails console`) and then running the following command: `Feature.enable(:first_class_vulnerabilities)`.
-To test if the Vulnerabilities API was successfully enabled, run the following command:
-`Feature.enabled?(:first_class_vulnerabilities)`.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10242) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.6.
CAUTION: **Caution:**
This API is in an alpha stage and considered unstable.
@@ -43,8 +35,8 @@ GET /projects/:id/vulnerabilities
| ------------- | -------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `id` | integer or string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user. |
-```bash
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/4/vulnerabilities
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/4/vulnerabilities"
```
Example response:
@@ -133,7 +125,7 @@ its source Vulnerability Finding, or with these default values:
| `confidence` | The `confidence` attribute of a Vulnerability Finding |
```shell
-curl --header POST "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/vulnerabilities?finding_id=1
+curl --header POST "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/vulnerabilities?finding_id=1"
```
Example response:
diff --git a/doc/api/projects.md b/doc/api/projects.md
index a5bb3f9bebb..b9ba632cd9e 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -1,3 +1,9 @@
+---
+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/#designated-technical-writers
+---
+
# Projects API
## Project visibility level
@@ -152,6 +158,7 @@ When the user is authenticated and `simple` is not set this returns something li
"public_jobs": true,
"shared_with_groups": [],
"only_allow_merge_if_pipeline_succeeds": false,
+ "allow_merge_on_skipped_pipeline": false,
"only_allow_merge_if_all_discussions_are_resolved": false,
"remove_source_branch_after_merge": false,
"request_access_enabled": false,
@@ -242,6 +249,7 @@ When the user is authenticated and `simple` is not set this returns something li
"public_jobs": true,
"shared_with_groups": [],
"only_allow_merge_if_pipeline_succeeds": false,
+ "allow_merge_on_skipped_pipeline": false,
"only_allow_merge_if_all_discussions_are_resolved": false,
"remove_source_branch_after_merge": false,
"request_access_enabled": false,
@@ -309,7 +317,7 @@ GET /projects?custom_attributes[key]=value&custom_attributes[other_key]=other_va
### Pagination limits
From GitLab 13.0, [offset-based pagination](README.md#offset-based-pagination) will be
-[limited to 50,000 records](https://gitlab.com/gitlab-org/gitlab/issues/34565).
+[limited to 50,000 records](https://gitlab.com/gitlab-org/gitlab/-/issues/34565).
[Keyset pagination](README.md#keyset-based-pagination) will be required to retrieve projects
beyond this limit.
@@ -401,6 +409,7 @@ This endpoint supports [keyset pagination](README.md#keyset-based-pagination) fo
"public_jobs": true,
"shared_with_groups": [],
"only_allow_merge_if_pipeline_succeeds": false,
+ "allow_merge_on_skipped_pipeline": false,
"only_allow_merge_if_all_discussions_are_resolved": false,
"remove_source_branch_after_merge": false,
"request_access_enabled": false,
@@ -491,6 +500,7 @@ This endpoint supports [keyset pagination](README.md#keyset-based-pagination) fo
"public_jobs": true,
"shared_with_groups": [],
"only_allow_merge_if_pipeline_succeeds": false,
+ "allow_merge_on_skipped_pipeline": false,
"only_allow_merge_if_all_discussions_are_resolved": false,
"remove_source_branch_after_merge": false,
"request_access_enabled": false,
@@ -617,6 +627,7 @@ Example response:
"public_jobs": true,
"shared_with_groups": [],
"only_allow_merge_if_pipeline_succeeds": false,
+ "allow_merge_on_skipped_pipeline": false,
"only_allow_merge_if_all_discussions_are_resolved": false,
"remove_source_branch_after_merge": false,
"request_access_enabled": false,
@@ -702,6 +713,7 @@ Example response:
"public_jobs": true,
"shared_with_groups": [],
"only_allow_merge_if_pipeline_succeeds": false,
+ "allow_merge_on_skipped_pipeline": false,
"only_allow_merge_if_all_discussions_are_resolved": false,
"remove_source_branch_after_merge": false,
"request_access_enabled": false,
@@ -855,6 +867,7 @@ GET /projects/:id
],
"repository_storage": "default",
"only_allow_merge_if_pipeline_succeeds": false,
+ "allow_merge_on_skipped_pipeline": false,
"only_allow_merge_if_all_discussions_are_resolved": false,
"remove_source_branch_after_merge": false,
"printing_merge_requests_link_enabled": true,
@@ -1038,6 +1051,7 @@ POST /projects
| `import_url` | string | no | URL to import repository from |
| `public_builds` | boolean | no | If `true`, jobs can be viewed by non-project-members |
| `only_allow_merge_if_pipeline_succeeds` | boolean | no | Set whether merge requests can only be merged with successful jobs |
+| `allow_merge_on_skipped_pipeline` | boolean | no | Set whether or not merge requests can be merged with skipped jobs |
| `only_allow_merge_if_all_discussions_are_resolved` | boolean | no | Set whether merge requests can only be merged when all the discussions are resolved |
| `merge_method` | string | no | Set the [merge method](#project-merge-method) used |
| `autoclose_referenced_issues` | boolean | no | Set whether auto-closing referenced issues on default branch |
@@ -1107,6 +1121,7 @@ POST /projects/user/:user_id
| `import_url` | string | no | URL to import repository from |
| `public_builds` | boolean | no | If `true`, jobs can be viewed by non-project-members |
| `only_allow_merge_if_pipeline_succeeds` | boolean | no | Set whether merge requests can only be merged with successful jobs |
+| `allow_merge_on_skipped_pipeline` | boolean | no | Set whether or not merge requests can be merged with skipped jobs |
| `only_allow_merge_if_all_discussions_are_resolved` | boolean | no | Set whether merge requests can only be merged when all the discussions are resolved |
| `merge_method` | string | no | Set the [merge method](#project-merge-method) used |
| `autoclose_referenced_issues` | boolean | no | Set whether auto-closing referenced issues on default branch |
@@ -1177,6 +1192,7 @@ PUT /projects/:id
| `import_url` | string | no | URL to import repository from |
| `public_builds` | boolean | no | If `true`, jobs can be viewed by non-project-members |
| `only_allow_merge_if_pipeline_succeeds` | boolean | no | Set whether merge requests can only be merged with successful jobs |
+| `allow_merge_on_skipped_pipeline` | boolean | no | Set whether or not merge requests can be merged with skipped jobs |
| `only_allow_merge_if_all_discussions_are_resolved` | boolean | no | Set whether merge requests can only be merged when all the discussions are resolved |
| `merge_method` | string | no | Set the [merge method](#project-merge-method) used |
| `autoclose_referenced_issues` | boolean | no | Set whether auto-closing referenced issues on default branch |
@@ -1311,6 +1327,7 @@ Example responses:
"public_jobs": true,
"shared_with_groups": [],
"only_allow_merge_if_pipeline_succeeds": false,
+ "allow_merge_on_skipped_pipeline": false,
"only_allow_merge_if_all_discussions_are_resolved": false,
"remove_source_branch_after_merge": false,
"request_access_enabled": false,
@@ -1402,6 +1419,7 @@ Example response:
"public_jobs": true,
"shared_with_groups": [],
"only_allow_merge_if_pipeline_succeeds": false,
+ "allow_merge_on_skipped_pipeline": false,
"only_allow_merge_if_all_discussions_are_resolved": false,
"remove_source_branch_after_merge": false,
"request_access_enabled": false,
@@ -1492,6 +1510,7 @@ Example response:
"public_jobs": true,
"shared_with_groups": [],
"only_allow_merge_if_pipeline_succeeds": false,
+ "allow_merge_on_skipped_pipeline": false,
"only_allow_merge_if_all_discussions_are_resolved": false,
"remove_source_branch_after_merge": false,
"request_access_enabled": false,
@@ -1674,6 +1693,7 @@ Example response:
"public_jobs": true,
"shared_with_groups": [],
"only_allow_merge_if_pipeline_succeeds": false,
+ "allow_merge_on_skipped_pipeline": false,
"only_allow_merge_if_all_discussions_are_resolved": false,
"remove_source_branch_after_merge": false,
"request_access_enabled": false,
@@ -1783,6 +1803,7 @@ Example response:
"public_jobs": true,
"shared_with_groups": [],
"only_allow_merge_if_pipeline_succeeds": false,
+ "allow_merge_on_skipped_pipeline": false,
"only_allow_merge_if_all_discussions_are_resolved": false,
"remove_source_branch_after_merge": false,
"request_access_enabled": false,
@@ -1806,7 +1827,7 @@ Example response:
This endpoint either:
- Removes a project including all associated resources (issues, merge requests etc).
-- From [GitLab 12.6](https://gitlab.com/gitlab-org/gitlab/issues/32935) on [Premium or Silver](https://about.gitlab.com/pricing/) or higher tiers, marks a project for deletion. Actual
+- From [GitLab 12.6](https://gitlab.com/gitlab-org/gitlab/-/issues/32935) on [Premium or Silver](https://about.gitlab.com/pricing/) or higher tiers, marks a project for deletion. Actual
deletion happens after number of days specified in
[instance settings](../user/admin_area/settings/visibility_and_access_controls.md#default-deletion-adjourned-period-premium-only).
@@ -1820,7 +1841,7 @@ DELETE /projects/:id
## Restore project marked for deletion **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/32935) in GitLab 12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32935) in GitLab 12.6.
Restores project marked for deletion.
@@ -1851,7 +1872,7 @@ The `file=` parameter must point to a file on your filesystem and be preceded
by `@`. For example:
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form "file=@dk.png" https://gitlab.example.com/api/v4/projects/5/uploads
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form "file=@dk.png" "https://gitlab.example.com/api/v4/projects/5/uploads"
```
Returned object:
@@ -1898,7 +1919,7 @@ DELETE /projects/:id/share/:group_id
| `group_id` | integer | yes | The ID of the group |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/share/17
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/share/17"
```
## Hooks
@@ -1943,6 +1964,7 @@ GET /projects/:id/hooks/:hook_id
"merge_requests_events": true,
"tag_push_events": true,
"note_events": true,
+ "confidential_note_events": true,
"job_events": true,
"pipeline_events": true,
"wiki_page_events": true,
@@ -1970,6 +1992,7 @@ POST /projects/:id/hooks
| `merge_requests_events` | boolean | no | Trigger hook on merge requests events |
| `tag_push_events` | boolean | no | Trigger hook on tag push events |
| `note_events` | boolean | no | Trigger hook on note events |
+| `confidential_note_events` | boolean | no | Trigger hook on confidential note events |
| `job_events` | boolean | no | Trigger hook on job events |
| `pipeline_events` | boolean | no | Trigger hook on pipeline events |
| `wiki_page_events` | boolean | no | Trigger hook on wiki events |
@@ -1996,6 +2019,7 @@ PUT /projects/:id/hooks/:hook_id
| `merge_requests_events` | boolean | no | Trigger hook on merge requests events |
| `tag_push_events` | boolean | no | Trigger hook on tag push events |
| `note_events` | boolean | no | Trigger hook on note events |
+| `confidential_note_events` | boolean | no | Trigger hook on confidential note events |
| `job_events` | boolean | no | Trigger hook on job events |
| `pipeline_events` | boolean | no | Trigger hook on pipeline events |
| `wiki_events` | boolean | no | Trigger hook on wiki events |
@@ -2061,7 +2085,7 @@ GET /projects
| `sort` | string | no | Return requests sorted in `asc` or `desc` order |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects?search=test
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects?search=test"
```
## Start the Housekeeping task for a Project
@@ -2221,7 +2245,7 @@ POST /projects/:id/mirror/pull
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:id/mirror/pull
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/mirror/pull"
```
## Project badges
diff --git a/doc/api/protected_branches.md b/doc/api/protected_branches.md
index de862109055..4206fe6a565 100644
--- a/doc/api/protected_branches.md
+++ b/doc/api/protected_branches.md
@@ -27,7 +27,7 @@ GET /projects/:id/protected_branches
| `search` | string | no | Name or part of the name of protected branches to be searched for |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/5/protected_branches'
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/protected_branches"
```
Example response:
@@ -101,7 +101,7 @@ GET /projects/:id/protected_branches/:name
| `name` | string | yes | The name of the branch or wildcard |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/5/protected_branches/master'
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/protected_branches/master"
```
Example response:
@@ -165,7 +165,7 @@ POST /projects/:id/protected_branches
```
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/5/protected_branches?name=*-stable&push_access_level=30&merge_access_level=30&unprotect_access_level=40'
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/protected_branches?name=*-stable&push_access_level=30&merge_access_level=30&unprotect_access_level=40"
```
| Attribute | Type | Required | Description |
@@ -251,7 +251,7 @@ Elements in the `allowed_to_push` / `allowed_to_merge` / `allowed_to_unprotect`
form `{user_id: integer}`, `{group_id: integer}` or `{access_level: integer}`. Each user must have access to the project and each group must [have this project shared](../user/project/members/share_project_with_groups.md). These access levels allow [more granular control over protected branch access](../user/project/protected_branches.md#restricting-push-and-merge-access-to-certain-users-starter) and were [added to the API in](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/3516) in GitLab 10.3 EE.
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/5/protected_branches?name=*-stable&allowed_to_push%5B%5D%5Buser_id%5D=1'
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/protected_branches?name=*-stable&allowed_to_push%5B%5D%5Buser_id%5D=1"
```
Example response:
@@ -297,7 +297,7 @@ DELETE /projects/:id/protected_branches/:name
```
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/5/protected_branches/*-stable'
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/protected_branches/*-stable"
```
| Attribute | Type | Required | Description |
@@ -314,7 +314,7 @@ PATCH /projects/:id/protected_branches/:name
```
```shell
-curl --request PATCH --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/5/protected_branches/feature-branch'
+curl --request PATCH --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/protected_branches/feature-branch"
```
| Attribute | Type | Required | Description |
diff --git a/doc/api/protected_environments.md b/doc/api/protected_environments.md
index dea1382af29..765b8d2364d 100644
--- a/doc/api/protected_environments.md
+++ b/doc/api/protected_environments.md
@@ -1,6 +1,6 @@
# 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 Premium](https://about.gitlab.com/pricing/) 12.8.
## Valid access levels
@@ -26,7 +26,7 @@ GET /projects/:id/protected_environments
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.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/protected_environments/'
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/protected_environments/"
```
Example response:
@@ -61,7 +61,7 @@ GET /projects/:id/protected_environments/:name
| `name` | string | yes | The name of the protected environment |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/5/protected_environments/production'
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/protected_environments/production"
```
Example response:
@@ -89,7 +89,7 @@ POST /projects/:id/protected_environments
```
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/5/protected_environments?name=staging&deploy_access_levels%5B%5D%5Buser_id%5D=1'
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/protected_environments?name=staging&deploy_access_levels%5B%5D%5Buser_id%5D=1"
```
| Attribute | Type | Required | Description |
@@ -127,7 +127,7 @@ DELETE /projects/:id/protected_environments/:name
```
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/5/protected_environments/staging'
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/protected_environments/staging"
```
| Attribute | Type | Required | Description |
diff --git a/doc/api/protected_tags.md b/doc/api/protected_tags.md
index 1d844a2c5c4..01de19f54ea 100644
--- a/doc/api/protected_tags.md
+++ b/doc/api/protected_tags.md
@@ -26,7 +26,7 @@ GET /projects/:id/protected_tags
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.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/protected_tags'
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/protected_tags"
```
Example response:
@@ -61,7 +61,7 @@ GET /projects/:id/protected_tags/:name
| `name` | string | yes | The name of the tag or wildcard |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/5/protected_tags/release-1-0'
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/protected_tags/release-1-0"
```
Example response:
@@ -88,7 +88,7 @@ POST /projects/:id/protected_tags
```
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/5/protected_tags?name=*-stable&create_access_level=30'
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/protected_tags?name=*-stable&create_access_level=30"
```
| Attribute | Type | Required | Description |
@@ -120,7 +120,7 @@ DELETE /projects/:id/protected_tags/:name
```
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/5/protected_tags/*-stable'
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/protected_tags/*-stable"
```
| Attribute | Type | Required | Description |
diff --git a/doc/api/releases/index.md b/doc/api/releases/index.md
index 9c3cac3c64f..2c933061c37 100644
--- a/doc/api/releases/index.md
+++ b/doc/api/releases/index.md
@@ -1,9 +1,15 @@
+---
+stage: Release
+group: Release 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/#designated-technical-writers
+---
+
# Releases API
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/41766) in GitLab 11.7.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41766) in GitLab 11.7.
> - Using this API you can manipulate GitLab's [Release](../../user/project/releases/index.md) entries.
> - For manipulating links as a release asset, see [Release Links API](links.md).
-> - Release Evidences were [introduced](https://gitlab.com/gitlab-org/gitlab/issues/26019) in GitLab 12.5.
+> - Release Evidences were [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/26019) in GitLab 12.5.
## List Releases
@@ -121,13 +127,15 @@ Example response:
"id":2,
"name":"awesome-v0.2.msi",
"url":"http://192.168.10.15:3000/msi",
- "external":true
+ "external":true,
+ "link_type":"other"
},
{
"id":1,
"name":"awesome-v0.2.dmg",
"url":"http://192.168.10.15:3000",
- "external":true
+ "external":true,
+ "link_type":"other"
}
],
"evidence_file_path":"https://gitlab.example.com/root/awesome-app/-/releases/v0.2/evidence.json"
@@ -323,7 +331,8 @@ Example response:
"id":3,
"name":"hoge",
"url":"https://gitlab.example.com/root/awesome-app/-/tags/v0.11.1/binaries/linux-amd64",
- "external":true
+ "external":true,
+ "link_type":"other"
}
]
},
@@ -357,13 +366,14 @@ POST /projects/:id/releases
| `assets:links:name`| string | required by: `assets:links` | The name of the link. |
| `assets:links:url` | string | required by: `assets:links` | The URL of the link. |
| `assets:links:filepath` | string | no | Optional path for a [Direct Asset link](../../user/project/releases.md).
+| `assets:links:link_type` | string | no | The type of the link: `other`, `runbook`, `image`, `package`. Defaults to `other`.
| `released_at` | datetime | no | The date when the release will be/was ready. Defaults to the current time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). |
Example request:
```shell
curl --header 'Content-Type: application/json' --header "PRIVATE-TOKEN: gDybLx3yrUK_HLp3qPjS" \
- --data '{ "name": "New release", "tag_name": "v0.3", "description": "Super nice release", "milestones": ["v1.0", "v1.0-rc"], "assets": { "links": [{ "name": "hoge", "url": "https://google.com", "filepath": "/binaries/linux-amd64" }] } }' \
+ --data '{ "name": "New release", "tag_name": "v0.3", "description": "Super nice release", "milestones": ["v1.0", "v1.0-rc"], "assets": { "links": [{ "name": "hoge", "url": "https://google.com", "filepath": "/binaries/linux-amd64", "link_type":"other" }] } }' \
--request POST https://gitlab.example.com/api/v4/projects/24/releases
```
@@ -465,7 +475,8 @@ Example response:
"id":3,
"name":"hoge",
"url":"https://gitlab.example.com/root/awesome-app/-/tags/v0.11.1/binaries/linux-amd64",
- "external":true
+ "external":true,
+ "link_type":"other"
}
],
"evidence_file_path":"https://gitlab.example.com/root/awesome-app/-/releases/v0.3/evidence.json"
@@ -693,7 +704,7 @@ Example response:
## Upcoming Releases
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/38105) in GitLab 12.1.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/38105) in GitLab 12.1.
A release with a `released_at` attribute set to a future date will be labeled an **Upcoming Release** in the UI:
diff --git a/doc/api/releases/links.md b/doc/api/releases/links.md
index f380ba5a1b2..35cb66e59a1 100644
--- a/doc/api/releases/links.md
+++ b/doc/api/releases/links.md
@@ -1,6 +1,12 @@
+---
+stage: Release
+group: Release 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/#designated-technical-writers
+---
+
# Release links API
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/41766) in GitLab 11.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41766) in GitLab 11.7.
Using this API you can manipulate GitLab's [Release](../../user/project/releases/index.md) links. For manipulating other Release assets, see [Release API](index.md).
GitLab supports links to `http`, `https`, and `ftp` assets.
@@ -32,13 +38,15 @@ Example response:
"id":2,
"name":"awesome-v0.2.msi",
"url":"http://192.168.10.15:3000/msi",
- "external":true
+ "external":true,
+ "link_type":"other"
},
{
"id":1,
"name":"awesome-v0.2.dmg",
"url":"http://192.168.10.15:3000",
- "external":true
+ "external":true,
+ "link_type":"other"
}
]
```
@@ -70,7 +78,8 @@ Example response:
"id":1,
"name":"awesome-v0.2.dmg",
"url":"http://192.168.10.15:3000",
- "external":true
+ "external":true,
+ "link_type":"other"
}
```
@@ -87,7 +96,8 @@ POST /projects/:id/releases/:tag_name/assets/links
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../README.md#namespaced-path-encoding). |
| `tag_name` | string | yes | The tag associated with the Release. |
| `name` | string | yes | The name of the link. |
-| `url` | string | yes | The URL of the link. |
+| `url` | string | yes | The URL of the link. |
+| `link_type` | string | no | The type of the link: `other`, `runbook`, `image`, `package`. Defaults to `other`. |
Example request:
@@ -106,7 +116,8 @@ Example response:
"id":1,
"name":"awesome-v0.2.dmg",
"url":"http://192.168.10.15:3000",
- "external":true
+ "external":true,
+ "link_type":"other"
}
```
@@ -122,9 +133,10 @@ PUT /projects/:id/releases/:tag_name/assets/links/:link_id
| ------------- | -------------- | -------- | --------------------------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../README.md#namespaced-path-encoding). |
| `tag_name` | string | yes | The tag associated with the Release. |
-| `link_id` | integer | yes | The ID of the link. |
+| `link_id` | integer | yes | The ID of the link. |
| `name` | string | no | The name of the link. |
-| `url` | string | no | The URL of the link. |
+| `url` | string | no | The URL of the link. |
+| `link_type` | string | no | The type of the link: `other`, `runbook`, `image`, `package`. Defaults to `other`. |
NOTE: **NOTE**
You have to specify at least one of `name` or `url`
@@ -132,7 +144,7 @@ You have to specify at least one of `name` or `url`
Example request:
```shell
-curl --request PUT --data name="new name" --header "PRIVATE-TOKEN: n671WNGecHugsdEDPsyo" "https://gitlab.example.com/api/v4/projects/24/releases/v0.1/assets/links/1"
+curl --request PUT --data name="new name" --data link_type="runbook" --header "PRIVATE-TOKEN: n671WNGecHugsdEDPsyo" "https://gitlab.example.com/api/v4/projects/24/releases/v0.1/assets/links/1"
```
Example response:
@@ -142,7 +154,8 @@ Example response:
"id":1,
"name":"new name",
"url":"http://192.168.10.15:3000",
- "external":true
+ "external":true,
+ "link_type":"runbook"
}
```
@@ -173,6 +186,7 @@ Example response:
"id":1,
"name":"new name",
"url":"http://192.168.10.15:3000",
- "external":true
+ "external":true,
+ "link_type":"other"
}
```
diff --git a/doc/api/remote_mirrors.md b/doc/api/remote_mirrors.md
index e46a890cbd4..6495f6d8383 100644
--- a/doc/api/remote_mirrors.md
+++ b/doc/api/remote_mirrors.md
@@ -7,7 +7,7 @@ outlined below.
## List a project's remote mirrors
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/38121) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/38121) in GitLab 12.9.
Returns an Array of remote mirrors and their statuses:
@@ -18,7 +18,7 @@ GET /projects/:id/remote_mirrors
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/42/remote_mirrors'
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/42/remote_mirrors"
```
Example response:
@@ -46,7 +46,7 @@ and password information.
## Create a remote mirror
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/24189) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/24189) in GitLab 12.9.
Create a remote mirror for a project. The mirror will be disabled by default. You can enable it by including the optional parameter `enabled` when creating it:
@@ -64,7 +64,7 @@ POST /projects/:id/remote_mirrors
Example request:
```shell
-curl --request POST --data "url=https://username:token@example.com/gitlab/example.git" --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/42/remote_mirrors'
+curl --request POST --data "url=https://username:token@example.com/gitlab/example.git" --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/42/remote_mirrors"
```
Example response:
@@ -86,7 +86,7 @@ Example response:
## Update a remote mirror's attributes
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/38121) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/38121) in GitLab 12.9.
Toggle a remote mirror on or off, or change which types of branches are
mirrored:
@@ -105,7 +105,7 @@ PUT /projects/:id/remote_mirrors/:mirror_id
Example request:
```shell
-curl --request PUT --data "enabled=false" --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/42/remote_mirrors/101486'
+curl --request PUT --data "enabled=false" --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/42/remote_mirrors/101486"
```
Example response:
diff --git a/doc/api/repositories.md b/doc/api/repositories.md
index 440db06792c..7e601ec96ec 100644
--- a/doc/api/repositories.md
+++ b/doc/api/repositories.md
@@ -124,7 +124,7 @@ Parameters:
- `sha` (optional) - The commit SHA to download. A tag, branch reference, or SHA can be used. This defaults to the tip of the default branch if not specified. For example:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.com/api/v4/projects/<project_id>/repository/archive?sha=<commit_sha>
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.com/api/v4/projects/<project_id>/repository/archive?sha=<commit_sha>"
```
## Compare branches, tags or commits
diff --git a/doc/api/repository_files.md b/doc/api/repository_files.md
index a8b58d90c34..9d934a0f855 100644
--- a/doc/api/repository_files.md
+++ b/doc/api/repository_files.md
@@ -25,7 +25,7 @@ GET /projects/:id/repository/files/:file_path
```
```shell
-curl --header 'PRIVATE-TOKEN: <your_access_token>' 'https://gitlab.example.com/api/v4/projects/13083/repository/files/app%2Fmodels%2Fkey%2Erb?ref=master'
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/13083/repository/files/app%2Fmodels%2Fkey%2Erb?ref=master"
```
Example response:
@@ -51,7 +51,7 @@ Parameters:
- `ref` (required) - The name of branch, tag or commit
NOTE: **Note:**
-`blob_id` is the blob sha, see [repositories - Get a blob from repository](repositories.md#get-a-blob-from-repository)
+`blob_id` is the blob SHA, see [repositories - Get a blob from repository](repositories.md#get-a-blob-from-repository)
In addition to the `GET` method, you can also use `HEAD` to get just file metadata.
@@ -60,7 +60,7 @@ HEAD /projects/:id/repository/files/:file_path
```
```shell
-curl --head --header 'PRIVATE-TOKEN: <your_access_token>' 'https://gitlab.example.com/api/v4/projects/13083/repository/files/app%2Fmodels%2Fkey%2Erb?ref=master'
+curl --head --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/13083/repository/files/app%2Fmodels%2Fkey%2Erb?ref=master"
```
Example response:
@@ -89,7 +89,7 @@ GET /projects/:id/repository/files/:file_path/blame
```
```shell
-curl --header 'PRIVATE-TOKEN: <your_access_token>' 'https://gitlab.example.com/api/v4/projects/13083/repository/files/path%2Fto%2Ffile.rb/blame?ref=master'
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/13083/repository/files/path%2Fto%2Ffile.rb/blame?ref=master"
```
Example response:
@@ -129,7 +129,7 @@ NOTE: **Note:**
`HEAD` method return just file metadata as in [Get file from repository](repository_files.md#get-file-from-repository).
```shell
-curl --head --header 'PRIVATE-TOKEN: <your_access_token>' 'https://gitlab.example.com/api/v4/projects/13083/repository/files/path%2Fto%2Ffile.rb/blame?ref=master'
+curl --head --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/13083/repository/files/path%2Fto%2Ffile.rb/blame?ref=master"
```
Example response:
@@ -156,7 +156,7 @@ GET /projects/:id/repository/files/:file_path/raw
```
```shell
-curl --header 'PRIVATE-TOKEN: <your_access_token>' 'https://gitlab.example.com/api/v4/projects/13083/repository/files/app%2Fmodels%2Fkey%2Erb/raw?ref=master'
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/13083/repository/files/app%2Fmodels%2Fkey%2Erb/raw?ref=master"
```
Parameters:
@@ -179,7 +179,7 @@ POST /projects/:id/repository/files/:file_path
curl --request POST --header 'PRIVATE-TOKEN: <your_access_token>' --header "Content-Type: application/json" \
--data '{"branch": "master", "author_email": "author@example.com", "author_name": "Firstname Lastname", \
"content": "some content", "commit_message": "create a new file"}' \
- 'https://gitlab.example.com/api/v4/projects/13083/repository/files/app%2Fproject%2Erb'
+ "https://gitlab.example.com/api/v4/projects/13083/repository/files/app%2Fproject%2Erb"
```
Example response:
@@ -214,7 +214,7 @@ PUT /projects/:id/repository/files/:file_path
curl --request PUT --header 'PRIVATE-TOKEN: <your_access_token>' --header "Content-Type: application/json" \
--data '{"branch": "master", "author_email": "author@example.com", "author_name": "Firstname Lastname", \
"content": "some content", "commit_message": "update file"}' \
- 'https://gitlab.example.com/api/v4/projects/13083/repository/files/app%2Fproject%2Erb'
+ "https://gitlab.example.com/api/v4/projects/13083/repository/files/app%2Fproject%2Erb"
```
Example response:
@@ -260,7 +260,7 @@ DELETE /projects/:id/repository/files/:file_path
curl --request DELETE --header 'PRIVATE-TOKEN: <your_access_token>' --header "Content-Type: application/json" \
--data '{"branch": "master", "author_email": "author@example.com", "author_name": "Firstname Lastname", \
"commit_message": "delete file"}' \
- 'https://gitlab.example.com/api/v4/projects/13083/repository/files/app%2Fproject%2Erb'
+ "https://gitlab.example.com/api/v4/projects/13083/repository/files/app%2Fproject%2Erb"
```
Parameters:
diff --git a/doc/api/repository_submodules.md b/doc/api/repository_submodules.md
index 2ae7afa35b2..40708f5bcb0 100644
--- a/doc/api/repository_submodules.md
+++ b/doc/api/repository_submodules.md
@@ -1,6 +1,6 @@
# Repository submodules API
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/41213) in GitLab 11.5
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41213) in GitLab 11.5
## Update existing submodule reference in repository
diff --git a/doc/api/resource_label_events.md b/doc/api/resource_label_events.md
index 20f48674932..275614a1449 100644
--- a/doc/api/resource_label_events.md
+++ b/doc/api/resource_label_events.md
@@ -65,7 +65,7 @@ GET /projects/:id/issues/:issue_iid/resource_label_events
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/issues/11/resource_label_events
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/11/resource_label_events"
```
### Get single issue label event
@@ -85,7 +85,7 @@ Parameters:
| `resource_label_event_id` | integer | yes | The ID of a label event |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/issues/11/resource_label_events/1
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/11/resource_label_events/1"
```
## Epics **(ULTIMATE)**
@@ -151,7 +151,7 @@ GET /groups/:id/epics/:epic_id/resource_label_events
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/1/epics/11/resource_label_events
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/epics/11/resource_label_events"
```
### Get single epic label event
@@ -171,7 +171,7 @@ Parameters:
| `resource_label_event_id` | integer | yes | The ID of a label event |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/1/epics/11/resource_label_events/107
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/epics/11/resource_label_events/107"
```
## Merge requests
@@ -237,7 +237,7 @@ GET /projects/:id/merge_requests/:merge_request_iid/resource_label_events
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/merge_requests/11/resource_label_events
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/resource_label_events"
```
### Get single merge request label event
@@ -257,5 +257,5 @@ Parameters:
| `resource_label_event_id` | integer | yes | The ID of a label event |
```shell
-curl --request GET --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/merge_requests/11/resource_label_events/120
+curl --request GET --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/resource_label_events/120"
```
diff --git a/doc/api/resource_milestone_events.md b/doc/api/resource_milestone_events.md
new file mode 100644
index 00000000000..695687ada6d
--- /dev/null
+++ b/doc/api/resource_milestone_events.md
@@ -0,0 +1,224 @@
+---
+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/#designated-technical-writers
+---
+
+# Resource milestone events API
+
+Resource milestone events keep track of what happens to GitLab [issues](../user/project/issues/),
+[merge requests](../user/project/merge_requests/), and [epics](../user/group/epics/).
+
+Use them to track which milestone was added or removed, who did it, and when it happened.
+
+## Issues
+
+### List project issue milestone events
+
+Gets a list of all milestone events for a single issue.
+
+```plaintext
+GET /projects/:id/issues/:issue_iid/resource_milestone_events
+```
+
+| Attribute | Type | Required | Description |
+| ----------- | -------------- | -------- | ------------------------------------------------------------------------------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) |
+| `issue_iid` | integer | yes | The IID of an issue |
+
+Example request:
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/11/resource_milestone_events"
+```
+
+Example response:
+
+```json
+[
+ {
+ "id": 142,
+ "user": {
+ "id": 1,
+ "name": "Administrator",
+ "username": "root",
+ "state": "active",
+ "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
+ "web_url": "http://gitlab.example.com/root"
+ },
+ "created_at": "2018-08-20T13:38:20.077Z",
+ "resource_type": "Issue",
+ "resource_id": 253,
+ "milestone": {
+ "id": 61,
+ "iid": 9,
+ "project_id": 7,
+ "title": "v1.2",
+ "description": "Ipsum Lorem",
+ "state": "active",
+ "created_at": "2020-01-27T05:07:12.573Z",
+ "updated_at": "2020-01-27T05:07:12.573Z",
+ "due_date": null,
+ "start_date": null,
+ "web_url": "http://gitlab.example.com:3000/group/project/-/milestones/9"
+ },
+ "action": "add"
+ },
+ {
+ "id": 143,
+ "user": {
+ "id": 1,
+ "name": "Administrator",
+ "username": "root",
+ "state": "active",
+ "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
+ "web_url": "http://gitlab.example.com/root"
+ },
+ "created_at": "2018-08-21T14:38:20.077Z",
+ "resource_type": "Issue",
+ "resource_id": 253,
+ "milestone": {
+ "id": 61,
+ "iid": 9,
+ "project_id": 7,
+ "title": "v1.2",
+ "description": "Ipsum Lorem",
+ "state": "active",
+ "created_at": "2020-01-27T05:07:12.573Z",
+ "updated_at": "2020-01-27T05:07:12.573Z",
+ "due_date": null,
+ "start_date": null,
+ "web_url": "http://gitlab.example.com:3000/group/project/-/milestones/9"
+ },
+ "action": "remove"
+ }
+]
+```
+
+### Get single issue milestone event
+
+Returns a single milestone event for a specific project issue
+
+```plaintext
+GET /projects/:id/issues/:issue_iid/resource_milestone_events/:resource_milestone_event_id
+```
+
+Parameters:
+
+| Attribute | Type | Required | Description |
+| ----------------------------- | -------------- | -------- | ------------------------------------------------------------------------------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path](README.md#namespaced-path-encoding) of the project |
+| `issue_iid` | integer | yes | The IID of an issue |
+| `resource_milestone_event_id` | integer | yes | The ID of a milestone event |
+
+Example request:
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/issues/11/resource_milestone_events/1"
+```
+
+## Merge requests
+
+### List project merge request milestone events
+
+Gets a list of all milestone events for a single merge request.
+
+```plaintext
+GET /projects/:id/merge_requests/:merge_request_iid/resource_milestone_events
+```
+
+| Attribute | Type | Required | Description |
+| ------------------- | -------------- | -------- | ------------------------------------------------------------------------------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path](README.md#namespaced-path-encoding) of the project |
+| `merge_request_iid` | integer | yes | The IID of a merge request |
+
+Example request:
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/resource_milestone_events"
+```
+
+Example response:
+
+```json
+[
+ {
+ "id": 142,
+ "user": {
+ "id": 1,
+ "name": "Administrator",
+ "username": "root",
+ "state": "active",
+ "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
+ "web_url": "http://gitlab.example.com/root"
+ },
+ "created_at": "2018-08-20T13:38:20.077Z",
+ "resource_type": "MergeRequest",
+ "resource_id": 142,
+ "milestone": {
+ "id": 61,
+ "iid": 9,
+ "project_id": 7,
+ "title": "v1.2",
+ "description": "Ipsum Lorem",
+ "state": "active",
+ "created_at": "2020-01-27T05:07:12.573Z",
+ "updated_at": "2020-01-27T05:07:12.573Z",
+ "due_date": null,
+ "start_date": null,
+ "web_url": "http://gitlab.example.com:3000/group/project/-/milestones/9"
+ },
+ "action": "add"
+ },
+ {
+ "id": 143,
+ "user": {
+ "id": 1,
+ "name": "Administrator",
+ "username": "root",
+ "state": "active",
+ "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
+ "web_url": "http://gitlab.example.com/root"
+ },
+ "created_at": "2018-08-21T14:38:20.077Z",
+ "resource_type": "MergeRequest",
+ "resource_id": 142,
+ "milestone": {
+ "id": 61,
+ "iid": 9,
+ "project_id": 7,
+ "title": "v1.2",
+ "description": "Ipsum Lorem",
+ "state": "active",
+ "created_at": "2020-01-27T05:07:12.573Z",
+ "updated_at": "2020-01-27T05:07:12.573Z",
+ "due_date": null,
+ "start_date": null,
+ "web_url": "http://gitlab.example.com:3000/group/project/-/milestones/9"
+ },
+ "action": "remove"
+ }
+]
+```
+
+### Get single merge request milestone event
+
+Returns a single milestone event for a specific project merge request
+
+```plaintext
+GET /projects/:id/merge_requests/:merge_request_iid/resource_milestone_events/:resource_milestone_event_id
+```
+
+Parameters:
+
+| Attribute | Type | Required | Description |
+| ----------------------------- | -------------- | -------- | ------------------------------------------------------------------------------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) |
+| `merge_request_iid` | integer | yes | The IID of a merge request |
+| `resource_milestone_event_id` | integer | yes | The ID of a milestone event |
+
+Example request:
+
+```shell
+curl --request GET --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/resource_milestone_events/120"
+```
diff --git a/doc/api/runners.md b/doc/api/runners.md
index 5db1f116f6c..4cda4b723f5 100644
--- a/doc/api/runners.md
+++ b/doc/api/runners.md
@@ -1,3 +1,9 @@
+---
+stage: Verify
+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/#designated-technical-writers
+---
+
# Runners API
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/2640) in GitLab 8.5
diff --git a/doc/api/scim.md b/doc/api/scim.md
index 4300c9efa3d..7c8da37a949 100644
--- a/doc/api/scim.md
+++ b/doc/api/scim.md
@@ -86,7 +86,7 @@ Parameters:
Example request:
```shell
-curl 'https://example.gitlab.com/api/scim/v2/groups/test_group/Users/f0b1d561c-21ff-4092-beab-8154b17f82f2' --header "Authorization: Bearer <your_scim_token>" --header "Content-Type: application/scim+json"
+curl "https://example.gitlab.com/api/scim/v2/groups/test_group/Users/f0b1d561c-21ff-4092-beab-8154b17f82f2" --header "Authorization: Bearer <your_scim_token>" --header "Content-Type: application/scim+json"
```
Example response:
@@ -130,7 +130,7 @@ Parameters:
Example request:
```shell
-curl --verbose --request POST 'https://example.gitlab.com/api/scim/v2/groups/test_group/Users' --data '{"externalId":"test_uid","active":null,"userName":"username","emails":[{"primary":true,"type":"work","value":"name@example.com"}],"name":{"formatted":"Test User","familyName":"User","givenName":"Test"},"schemas":["urn:ietf:params:scim:schemas:core:2.0:User"],"meta":{"resourceType":"User"}}' --header "Authorization: Bearer <your_scim_token>" --header "Content-Type: application/scim+json"
+curl --verbose --request POST "https://example.gitlab.com/api/scim/v2/groups/test_group/Users" --data '{"externalId":"test_uid","active":null,"userName":"username","emails":[{"primary":true,"type":"work","value":"name@example.com"}],"name":{"formatted":"Test User","familyName":"User","givenName":"Test"},"schemas":["urn:ietf:params:scim:schemas:core:2.0:User"],"meta":{"resourceType":"User"}}' --header "Authorization: Bearer <your_scim_token>" --header "Content-Type: application/scim+json"
```
Example response:
@@ -184,7 +184,7 @@ Parameters:
Example request:
```shell
-curl --verbose --request PATCH 'https://example.gitlab.com/api/scim/v2/groups/test_group/Users/f0b1d561c-21ff-4092-beab-8154b17f82f2' --data '{ "Operations": [{"op":"Add","path":"name.formatted","value":"New Name"}] }' --header "Authorization: Bearer <your_scim_token>" --header "Content-Type: application/scim+json"
+curl --verbose --request PATCH "https://example.gitlab.com/api/scim/v2/groups/test_group/Users/f0b1d561c-21ff-4092-beab-8154b17f82f2" --data '{ "Operations": [{"op":"Add","path":"name.formatted","value":"New Name"}] }' --header "Authorization: Bearer <your_scim_token>" --header "Content-Type: application/scim+json"
```
Returns an empty response with a `204` status code if successful.
@@ -207,7 +207,7 @@ Parameters:
Example request:
```shell
-curl --verbose --request DELETE 'https://example.gitlab.com/api/scim/v2/groups/test_group/Users/f0b1d561c-21ff-4092-beab-8154b17f82f2' --header "Authorization: Bearer <your_scim_token>" --header "Content-Type: application/scim+json"
+curl --verbose --request DELETE "https://example.gitlab.com/api/scim/v2/groups/test_group/Users/f0b1d561c-21ff-4092-beab-8154b17f82f2" --header "Authorization: Bearer <your_scim_token>" --header "Content-Type: application/scim+json"
```
Returns an empty response with a `204` status code if successful.
diff --git a/doc/api/search.md b/doc/api/search.md
index 7940a2fa4e3..9c4eef7dfe8 100644
--- a/doc/api/search.md
+++ b/doc/api/search.md
@@ -1,6 +1,6 @@
# Search API
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/41763) in GitLab 10.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41763) in GitLab 10.5.
Every API call to search must be authenticated.
@@ -26,7 +26,7 @@ The response depends on the requested scope.
### Scope: projects
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/search?scope=projects&search=flight
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/search?scope=projects&search=flight"
```
Example response:
@@ -57,7 +57,7 @@ Example response:
### Scope: issues
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/search?scope=issues&search=file
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/search?scope=issues&search=file"
```
Example response:
@@ -122,7 +122,7 @@ Example response:
### Scope: merge_requests
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/search?scope=merge_requests&search=file
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/search?scope=merge_requests&search=file"
```
Example response:
@@ -200,7 +200,7 @@ Example response:
### Scope: milestones
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/search?scope=milestones&search=release
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/search?scope=milestones&search=release"
```
Example response:
@@ -225,7 +225,7 @@ Example response:
### Scope: snippet_titles
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/search?scope=snippet_titles&search=sample
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/search?scope=snippet_titles&search=sample"
```
Example response:
@@ -258,7 +258,7 @@ Example response:
This scope is available only if [Elasticsearch](../integration/elasticsearch.md) is enabled.
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/search?scope=wiki_blobs&search=bye
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/search?scope=wiki_blobs&search=bye"
```
Example response:
@@ -279,14 +279,14 @@ Example response:
]
```
-**Note:** `filename` is deprecated in favor of `path`. Both return the full path of the file inside the repository, but in the future `filename` will be only the file name and not the full path. For details, see [issue 34521](https://gitlab.com/gitlab-org/gitlab/issues/34521).
+**Note:** `filename` is deprecated in favor of `path`. Both return the full path of the file inside the repository, but in the future `filename` will be only the file name and not the full path. For details, see [issue 34521](https://gitlab.com/gitlab-org/gitlab/-/issues/34521).
### Scope: commits **(STARTER)**
This scope is available only if [Elasticsearch](../integration/elasticsearch.md) is enabled.
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/search?scope=commits&search=bye
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/search?scope=commits&search=bye"
```
Example response:
@@ -329,7 +329,7 @@ to use a filter simply include it in your query like so: `a query filename:some_
You may use wildcards (`*`) to use glob matching.
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/search?scope=blobs&search=installation
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/search?scope=blobs&search=installation"
```
Example response:
@@ -350,12 +350,12 @@ Example response:
]
```
-**Note:** `filename` is deprecated in favor of `path`. Both return the full path of the file inside the repository, but in the future `filename` will be only the file name and not the full path. For details, see [issue 34521](https://gitlab.com/gitlab-org/gitlab/issues/34521).
+**Note:** `filename` is deprecated in favor of `path`. Both return the full path of the file inside the repository, but in the future `filename` will be only the file name and not the full path. For details, see [issue 34521](https://gitlab.com/gitlab-org/gitlab/-/issues/34521).
### Scope: users
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/search?scope=users&search=doe
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/search?scope=users&search=doe"
```
Example response:
@@ -398,7 +398,7 @@ The response depends on the requested scope.
### Scope: projects
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/3/search?scope=projects&search=flight
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/3/search?scope=projects&search=flight"
```
Example response:
@@ -429,7 +429,7 @@ Example response:
### Scope: issues
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/3/search?scope=issues&search=file
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/3/search?scope=issues&search=file"
```
Example response:
@@ -494,7 +494,7 @@ Example response:
### Scope: merge_requests
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/3/search?scope=merge_requests&search=file
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/3/search?scope=merge_requests&search=file"
```
Example response:
@@ -572,7 +572,7 @@ Example response:
### Scope: milestones
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/3/search?scope=milestones&search=release
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/3/search?scope=milestones&search=release"
```
Example response:
@@ -599,7 +599,7 @@ Example response:
This scope is available only if [Elasticsearch](../integration/elasticsearch.md) is enabled.
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/6/search?scope=wiki_blobs&search=bye
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/6/search?scope=wiki_blobs&search=bye"
```
Example response:
@@ -620,14 +620,14 @@ Example response:
]
```
-**Note:** `filename` is deprecated in favor of `path`. Both return the full path of the file inside the repository, but in the future `filename` will be only the file name and not the full path. For details, see [issue 34521](https://gitlab.com/gitlab-org/gitlab/issues/34521).
+**Note:** `filename` is deprecated in favor of `path`. Both return the full path of the file inside the repository, but in the future `filename` will be only the file name and not the full path. For details, see [issue 34521](https://gitlab.com/gitlab-org/gitlab/-/issues/34521).
### Scope: commits **(STARTER)**
This scope is available only if [Elasticsearch](../integration/elasticsearch.md) is enabled.
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/6/search?scope=commits&search=bye
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/6/search?scope=commits&search=bye"
```
Example response:
@@ -670,7 +670,7 @@ to use a filter simply include it in your query like so: `a query filename:some_
You may use wildcards (`*`) to use glob matching.
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/6/search?scope=blobs&search=installation
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/6/search?scope=blobs&search=installation"
```
Example response:
@@ -691,12 +691,12 @@ Example response:
]
```
-**Note:** `filename` is deprecated in favor of `path`. Both return the full path of the file inside the repository, but in the future `filename` will be only the file name and not the full path. For details, see [issue 34521](https://gitlab.com/gitlab-org/gitlab/issues/34521).
+**Note:** `filename` is deprecated in favor of `path`. Both return the full path of the file inside the repository, but in the future `filename` will be only the file name and not the full path. For details, see [issue 34521](https://gitlab.com/gitlab-org/gitlab/-/issues/34521).
### Scope: users
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/3/search?scope=users&search=doe
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/3/search?scope=users&search=doe"
```
Example response:
@@ -738,7 +738,7 @@ The response depends on the requested scope.
### Scope: issues
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/12/search?scope=issues&search=file
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/12/search?scope=issues&search=file"
```
Example response:
@@ -803,7 +803,7 @@ Example response:
### Scope: merge_requests
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/6/search?scope=merge_requests&search=file
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/6/search?scope=merge_requests&search=file"
```
Example response:
@@ -881,7 +881,7 @@ Example response:
### Scope: milestones
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/12/search?scope=milestones&search=release
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/12/search?scope=milestones&search=release"
```
Example response:
@@ -906,7 +906,7 @@ Example response:
### Scope: notes
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/6/search?scope=notes&search=maxime
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/6/search?scope=notes&search=maxime"
```
Example response:
@@ -955,7 +955,7 @@ results:
times in the content.
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/6/search?scope=wiki_blobs&search=bye
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/6/search?scope=wiki_blobs&search=bye"
```
Example response:
@@ -976,12 +976,12 @@ Example response:
]
```
-**Note:** `filename` is deprecated in favor of `path`. Both return the full path of the file inside the repository, but in the future `filename` will be only the file name and not the full path. For details, see [issue 34521](https://gitlab.com/gitlab-org/gitlab/issues/34521).
+**Note:** `filename` is deprecated in favor of `path`. Both return the full path of the file inside the repository, but in the future `filename` will be only the file name and not the full path. For details, see [issue 34521](https://gitlab.com/gitlab-org/gitlab/-/issues/34521).
### Scope: commits
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/6/search?scope=commits&search=bye
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/6/search?scope=commits&search=bye"
```
Example response:
@@ -1028,7 +1028,7 @@ Blobs searches are performed on both filenames and contents. Search results:
times in the content.
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/6/search?scope=blobs&search=installation&ref=feature
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/6/search?scope=blobs&search=installation&ref=feature"
```
Example response:
@@ -1049,12 +1049,12 @@ Example response:
]
```
-**Note:** `filename` is deprecated in favor of `path`. Both return the full path of the file inside the repository, but in the future `filename` will be only the file name and not the full path. For details, see [issue 34521](https://gitlab.com/gitlab-org/gitlab/issues/34521).
+**Note:** `filename` is deprecated in favor of `path`. Both return the full path of the file inside the repository, but in the future `filename` will be only the file name and not the full path. For details, see [issue 34521](https://gitlab.com/gitlab-org/gitlab/-/issues/34521).
### Scope: users
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/6/search?scope=users&search=doe
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/6/search?scope=users&search=doe"
```
Example response:
diff --git a/doc/api/services.md b/doc/api/services.md
index d435dffa651..02048a27c1b 100644
--- a/doc/api/services.md
+++ b/doc/api/services.md
@@ -714,7 +714,7 @@ Parameters:
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `recipients` | string | true | Recipients/channels separated by whitespaces |
-| `default_irc_uri` | string | false | irc://irc.network.net:6697/ |
+| `default_irc_uri` | string | false | `irc://irc.network.net:6697/` |
| `server_host` | string | false | localhost |
| `server_port` | integer | false | 6659 |
| `colorize_messages` | boolean | false | Colorize messages |
@@ -1007,6 +1007,8 @@ Parameters:
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `api_url` | string | true | Prometheus API Base URL. For example, `http://prometheus.example.com/`. |
+| `google_iap_audience_client_id` | string | false | Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com) |
+| `google_iap_service_account_json` | string | false | credentials.json file for your service account, like { "type": "service_account", "project_id": ... } |
### Delete Prometheus service
@@ -1277,7 +1279,7 @@ A continuous integration and build server
Set JetBrains TeamCity CI service for a project.
-> The build configuration in Teamcity must use the build format number %build.vcs.number% you will also want to configure monitoring of all branches so merge requests build, that setting is in the vsc root advanced settings.
+> The build configuration in TeamCity must use the build format number `%build.vcs.number%` you will also want to configure monitoring of all branches so merge requests build, that setting is in the VSC root advanced settings.
```plaintext
PUT /projects/:id/services/teamcity
diff --git a/doc/api/settings.md b/doc/api/settings.md
index f63d126742a..78d992cff58 100644
--- a/doc/api/settings.md
+++ b/doc/api/settings.md
@@ -15,7 +15,7 @@ GET /application/settings
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/application/settings
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/application/settings"
```
Example response:
@@ -30,6 +30,7 @@ Example response:
"password_authentication_enabled_for_web" : true,
"after_sign_out_path" : null,
"max_attachment_size" : 10,
+ "max_import_size": 50,
"user_oauth_applications" : true,
"updated_at" : "2016-01-04T15:44:55.176Z",
"session_expire_delay" : 10080,
@@ -99,7 +100,7 @@ PUT /application/settings
```
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/application/settings?signup_enabled=false&default_project_visibility=internal
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/application/settings?signup_enabled=false&default_project_visibility=internal"
```
Example response:
@@ -118,6 +119,7 @@ Example response:
"default_branch_protection": 2,
"restricted_visibility_levels": [],
"max_attachment_size": 10,
+ "max_import_size": 50,
"session_expire_delay": 10080,
"default_ci_config_path" : null,
"default_project_visibility": "internal",
@@ -280,6 +282,7 @@ are listed in the descriptions of the relevant settings.
| `local_markdown_version` | integer | no | Increase this value when any cached Markdown should be invalidated. |
| `max_artifacts_size` | integer | no | Maximum artifacts size in MB |
| `max_attachment_size` | integer | no | Limit attachment size in MB |
+| `max_import_size` | integer | no | Maximum import size in MB. 0 for unlimited. Default = 50 |
| `max_pages_size` | integer | no | Maximum size of pages repositories in MB |
| `max_personal_access_token_lifetime` | integer | no | **(ULTIMATE ONLY)** Maximum allowable lifetime for personal access tokens in days |
| `metrics_method_call_threshold` | integer | no | A method call is only tracked when it takes longer than the given amount of milliseconds. |
@@ -335,6 +338,8 @@ are listed in the descriptions of the relevant settings.
| `sourcegraph_enabled` | boolean | no | Enables Sourcegraph integration. Default is `false`. **If enabled, requires** `sourcegraph_url`. |
| `sourcegraph_url` | string | required by: `sourcegraph_enabled` | The Sourcegraph instance URL for integration. |
| `sourcegraph_public_only` | boolean | no | Blocks Sourcegraph from being loaded on private and internal projects. Default is `true`. |
+| `spam_check_endpoint_enabled` | boolean | no | Enables Spam Check via external API endpoint. Default is `false`. |
+| `spam_check_endpoint_url` | string | no | URL of the external Spam Check service endpoint. |
| `terminal_max_session_time` | integer | no | Maximum time for web terminal websocket connection (in seconds). Set to `0` for unlimited time. |
| `terms` | text | required by: `enforce_terms` | (**Required by:** `enforce_terms`) Markdown content for the ToS. |
| `throttle_authenticated_api_enabled` | boolean | no | (**If enabled, requires:** `throttle_authenticated_api_period_in_seconds` and `throttle_authenticated_api_requests_per_period`) Enable authenticated API request rate limit. Helps reduce request volume (for example, from crawlers or abusive bots). |
diff --git a/doc/api/sidekiq_metrics.md b/doc/api/sidekiq_metrics.md
index 5350feff4e3..8523ac88e00 100644
--- a/doc/api/sidekiq_metrics.md
+++ b/doc/api/sidekiq_metrics.md
@@ -15,7 +15,7 @@ GET /sidekiq/queue_metrics
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/sidekiq/queue_metrics
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/sidekiq/queue_metrics"
```
Example response:
@@ -40,7 +40,7 @@ GET /sidekiq/process_metrics
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/sidekiq/process_metrics
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/sidekiq/process_metrics"
```
Example response:
@@ -82,7 +82,7 @@ GET /sidekiq/job_stats
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/sidekiq/job_stats
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/sidekiq/job_stats"
```
Example response:
@@ -107,7 +107,7 @@ GET /sidekiq/compound_metrics
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/sidekiq/compound_metrics
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/sidekiq/compound_metrics"
```
Example response:
diff --git a/doc/api/snippets.md b/doc/api/snippets.md
index e2e39de412b..1aa3eecfd29 100644
--- a/doc/api/snippets.md
+++ b/doc/api/snippets.md
@@ -28,7 +28,7 @@ GET /snippets
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/snippets
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/snippets"
```
Example response:
@@ -95,7 +95,7 @@ Parameters:
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/snippets/1
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/snippets/1"
```
Example response:
@@ -141,7 +141,7 @@ Parameters:
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/snippets/1/raw
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/snippets/1/raw"
```
Example response:
@@ -177,8 +177,8 @@ Example request:
curl --request POST \
--data '{"title": "This is a snippet", "content": "Hello world", "description": "Hello World snippet", "file_name": "test.txt", "visibility": "internal" }' \
--header 'Content-Type: application/json' \
- --header "PRIVATE-TOKEN: valid_api_token" \
- https://gitlab.example.com/api/v4/snippets
+ --header "PRIVATE-TOKEN: <your_access_token>" \
+ "https://gitlab.example.com/api/v4/snippets"
```
Example response:
@@ -235,8 +235,8 @@ Example request:
curl --request PUT \
--data '{"title": "foo", "content": "bar"}' \
--header 'Content-Type: application/json' \
- --header "PRIVATE-TOKEN: valid_api_token" \
- https://gitlab.example.com/api/v4/snippets/1
+ --header "PRIVATE-TOKEN: <your_access_token>" \
+ "https://gitlab.example.com/api/v4/snippets/1"
```
Example response:
@@ -310,7 +310,7 @@ Parameters:
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/snippets/public?per_page=2&page=1
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/snippets/public?per_page=2&page=1"
```
Example response:
@@ -375,7 +375,7 @@ GET /snippets/:id/user_agent_detail
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/snippets/1/user_agent_detail
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/snippets/1/user_agent_detail"
```
Example response:
diff --git a/doc/api/statistics.md b/doc/api/statistics.md
index 883a7640cf8..890c6f68898 100644
--- a/doc/api/statistics.md
+++ b/doc/api/statistics.md
@@ -13,7 +13,7 @@ GET /application/statistics
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/application/statistics
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/application/statistics"
```
Example response:
diff --git a/doc/api/suggestions.md b/doc/api/suggestions.md
index 84bafd3c1ea..e3bbcaa51c3 100644
--- a/doc/api/suggestions.md
+++ b/doc/api/suggestions.md
@@ -16,7 +16,7 @@ PUT /suggestions/:id/apply
| `id` | integer/string | yes | The ID of a suggestion |
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/suggestions/5/apply
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/suggestions/5/apply"
```
Example response:
diff --git a/doc/api/system_hooks.md b/doc/api/system_hooks.md
index cd69a6a6b34..3e0d2151428 100644
--- a/doc/api/system_hooks.md
+++ b/doc/api/system_hooks.md
@@ -18,7 +18,7 @@ GET /hooks
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/hooks
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/hooks"
```
Example response:
@@ -92,7 +92,7 @@ GET /hooks/:id
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/hooks/2
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/hooks/2"
```
Example response:
@@ -123,5 +123,5 @@ DELETE /hooks/:id
Example request:
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/hooks/2
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/hooks/2"
```
diff --git a/doc/api/tags.md b/doc/api/tags.md
index 0a0490e072e..569271d6206 100644
--- a/doc/api/tags.md
+++ b/doc/api/tags.md
@@ -19,7 +19,7 @@ Parameters:
| `sort` | string | no | Return tags sorted in `asc` or `desc` order. Default is `desc` |
| `search` | string | no | Return list of tags matching the search criteria. You can use `^term` and `term$` to find tags that begin and end with `term` respectively. |
-> Support for `search` was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/54401) in GitLab 11.8.
+> Support for `search` was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/54401) in GitLab 11.8.
```json
[
@@ -69,7 +69,7 @@ Parameters:
| `tag_name` | string | yes | The name of the tag |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/repository/tags/v1.0.0
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/repository/tags/v1.0.0"
```
Example Response:
diff --git a/doc/api/todos.md b/doc/api/todos.md
index cd6f2468cc6..9d56522c5b8 100644
--- a/doc/api/todos.md
+++ b/doc/api/todos.md
@@ -1,3 +1,9 @@
+---
+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/#designated-technical-writers
+---
+
# Todos API
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/3188) in GitLab 8.10.
@@ -23,7 +29,7 @@ Parameters:
| `type` | string | no | The type of a todo. Can be either `Issue` or `MergeRequest` |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/todos
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/todos"
```
Example Response:
@@ -197,7 +203,7 @@ Parameters:
| `id` | integer | yes | The ID of a todo |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/todos/130/mark_as_done
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/todos/130/mark_as_done"
```
Example Response:
@@ -288,5 +294,5 @@ POST /todos/mark_as_done
```
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/todos/mark_as_done
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/todos/mark_as_done"
```
diff --git a/doc/api/users.md b/doc/api/users.md
index 28d233ce6b3..6ac1cd089e7 100644
--- a/doc/api/users.md
+++ b/doc/api/users.md
@@ -70,12 +70,12 @@ Username search is case insensitive.
GET /users
```
-| Attribute | Type | Required | Description |
-| ------------ | ------ | -------- | ----------- |
-| `order_by` | string | no | Return users ordered by `id`, `name`, `username`, `created_at`, or `updated_at` fields. Default is `id` |
-| `sort` | string | no | Return users sorted in `asc` or `desc` order. Default is `desc` |
-| `two_factor` | string | no | Filter users by Two-factor authentication. Filter values are `enabled` or `disabled`. By default it returns all users |
-| `without_projects` | boolean | no | Filter users without projects. Default is `false` |
+| Attribute | Type | Required | Description |
+| ------------------ | ------- | -------- | --------------------------------------------------------------------------------------------------------------------- |
+| `order_by` | string | no | Return users ordered by `id`, `name`, `username`, `created_at`, or `updated_at` fields. Default is `id` |
+| `sort` | string | no | Return users sorted in `asc` or `desc` order. Default is `desc` |
+| `two_factor` | string | no | Filter users by Two-factor authentication. Filter values are `enabled` or `disabled`. By default it returns all users |
+| `without_projects` | boolean | no | Filter users without projects. Default is `false` |
```json
[
@@ -104,6 +104,7 @@ GET /users
"color_scheme_id": 2,
"projects_limit": 100,
"current_sign_in_at": "2012-06-02T06:36:55Z",
+ "note": "DMCA Request: 2018-11-05 | DMCA Violation | Abuse | https://gitlab.zendesk.com/agent/tickets/123",
"identities": [
{"provider": "github", "extern_uid": "2435223452345"},
{"provider": "bitbucket", "extern_uid": "john.smith"},
@@ -154,7 +155,7 @@ GET /users
]
```
-Users on GitLab [Starter, Bronze, or higher](https://about.gitlab.com/pricing/) will also see the `shared_runners_minutes_limit`, `extra_shared_runners_minutes_limit`, and `note` parameters.
+Users on GitLab [Starter, Bronze, or higher](https://about.gitlab.com/pricing/) will also see the `shared_runners_minutes_limit`, and `extra_shared_runners_minutes_limit` parameters.
```json
[
@@ -163,7 +164,6 @@ Users on GitLab [Starter, Bronze, or higher](https://about.gitlab.com/pricing/)
...
"shared_runners_minutes_limit": 133,
"extra_shared_runners_minutes_limit": 133,
- "note": "DMCA Request: 2018-11-05 | DMCA Violation | Abuse | https://gitlab.zendesk.com/agent/tickets/123",
...
}
]
@@ -296,6 +296,7 @@ Example Responses:
"color_scheme_id": 2,
"projects_limit": 100,
"current_sign_in_at": "2012-06-02T06:36:55Z",
+ "note": "DMCA Request: 2018-11-05 | DMCA Violation | Abuse | https://gitlab.zendesk.com/agent/tickets/123",
"identities": [
{"provider": "github", "extern_uid": "2435223452345"},
{"provider": "bitbucket", "extern_uid": "john.smith"},
@@ -316,7 +317,7 @@ Example Responses:
NOTE: **Note:** The `plan` and `trial` parameters are only available on GitLab Enterprise Edition.
Users on GitLab [Starter, Bronze, or higher](https://about.gitlab.com/pricing/) will also see
-the `shared_runners_minutes_limit`, `extra_shared_runners_minutes_limit`, and `note` parameters.
+the `shared_runners_minutes_limit`, and `extra_shared_runners_minutes_limit` parameters.
```json
{
@@ -324,7 +325,6 @@ the `shared_runners_minutes_limit`, `extra_shared_runners_minutes_limit`, and `n
"username": "john_smith",
"shared_runners_minutes_limit": 133,
"extra_shared_runners_minutes_limit": 133,
- "note": "DMCA Request: 2018-11-05 | DMCA Violation | Abuse | https://gitlab.zendesk.com/agent/tickets/123",
...
}
```
@@ -338,7 +338,6 @@ see the `group_saml` option:
"username": "john_smith",
"shared_runners_minutes_limit": 133,
"extra_shared_runners_minutes_limit": 133,
- "note": "DMCA Request: 2018-11-05 | DMCA Violation | Abuse | https://gitlab.zendesk.com/agent/tickets/123",
"identities": [
{"provider": "github", "extern_uid": "2435223452345"},
{"provider": "bitbucket", "extern_uid": "john.smith"},
@@ -376,7 +375,7 @@ POST /users
Parameters:
| Attribute | Required | Description |
-|:-------------------------------------|:---------|:--------------------------------------------------------------------------------------------------------------------------------------------------------|
+| :----------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `admin` | No | User is admin - true or false (default) |
| `avatar` | No | Image file for user's avatar |
| `bio` | No | User's biography |
@@ -391,6 +390,7 @@ Parameters:
| `linkedin` | No | LinkedIn |
| `location` | No | User's location |
| `name` | Yes | Name |
+| `note` | No | Admin notes for this user |
| `organization` | No | Organization name |
| `password` | No | Password |
| `private_profile` | No | User's profile is private - true, false (default), or null (will be converted to false) |
@@ -417,7 +417,7 @@ PUT /users/:id
Parameters:
| Attribute | Required | Description |
-|:-------------------------------------|:---------|:--------------------------------------------------------------------------------------------------------------------------------------------------------|
+| :----------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `admin` | No | User is admin - true or false (default) |
| `avatar` | No | Image file for user's avatar |
| `bio` | No | User's biography |
@@ -432,7 +432,7 @@ Parameters:
| `linkedin` | No | LinkedIn |
| `location` | No | User's location |
| `name` | No | Name |
-| `note` | No | Admin notes for this user **(STARTER)** |
+| `note` | No | Admin notes for this user |
| `organization` | No | Organization name |
| `password` | No | Password |
| `private_profile` | No | User's profile is private - true, false (default), or null (will be converted to false) |
@@ -609,8 +609,8 @@ Get the status of a user.
GET /users/:id_or_username/status
```
-| Attribute | Type | Required | Description |
-| ---------------- | ------ | -------- | ----------- |
+| Attribute | Type | Required | Description |
+| ---------------- | ------ | -------- | ------------------------------------------------- |
| `id_or_username` | string | yes | The ID or username of the user to get a status of |
```shell
@@ -635,15 +635,15 @@ Set the status of the current user.
PUT /user/status
```
-| Attribute | Type | Required | Description |
-| --------- | ------ | -------- | ----------- |
-| `emoji` | string | no | The name of the emoji to use as status, if omitted `speech_balloon` is used. Emoji name can be one of the specified names in the [Gemojione index](https://github.com/bonusly/gemojione/blob/master/config/index.json). |
-| `message` | string | no | The message to set as a status. It can also contain emoji codes. |
+| Attribute | Type | Required | Description |
+| --------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `emoji` | string | no | The name of the emoji to use as status. If omitted `speech_balloon` is used. Emoji name can be one of the specified names in the [Gemojione index](https://github.com/bonusly/gemojione/blob/master/config/index.json). |
+| `message` | string | no | The message to set as a status. It can also contain emoji codes. |
When both parameters `emoji` and `message` are empty, the status will be cleared.
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" --data "emoji=coffee" --data "message=I crave coffee" https://gitlab.example.com/api/v4/user/status
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" --data "emoji=coffee" --data "message=I crave coffee" "https://gitlab.example.com/api/v4/user/status"
```
Example responses
@@ -660,9 +660,9 @@ Example responses
Get the counts (same as in top right menu) of the currently signed in user.
-| Attribute | Type | Description |
-| --------- | ---- | ----------- |
-| `merge_requests` | number | Merge requests that are active and assigned to current user. |
+| Attribute | Type | Description |
+| ---------------- | ------ | ------------------------------------------------------------ |
+| `merge_requests` | number | Merge requests that are active and assigned to current user. |
```plaintext
GET /user_counts
@@ -721,8 +721,8 @@ Get a list of a specified user's SSH keys.
GET /users/:id_or_username/keys
```
-| Attribute | Type | Required | Description |
-| ---------------- | ------ | -------- | ----------- |
+| Attribute | Type | Required | Description |
+| ---------------- | ------ | -------- | ------------------------------------------------------- |
| `id_or_username` | string | yes | The ID or username of the user to get the SSH keys for. |
## Single SSH key
@@ -758,13 +758,13 @@ Parameters:
- `title` (required) - new SSH Key's title
- `key` (required) - new SSH key
+- `expires_at` (optional) - The expiration date of the SSH key in ISO 8601 format (`YYYY-MM-DDTHH:MM:SSZ`)
```json
{
- "created_at": "2015-01-21T17:44:33.512Z",
- "key": "ssh-dss AAAAB3NzaC1kc3MAAACBAMLrhYgI3atfrSD6KDas1b/3n6R/HP+bLaHHX6oh+L1vg31mdUqK0Ac/NjZoQunavoyzqdPYhFz9zzOezCrZKjuJDS3NRK9rspvjgM0xYR4d47oNZbdZbwkI4cTv/gcMlquRy0OvpfIvJtjtaJWMwTLtM5VhRusRuUlpH99UUVeXAAAAFQCVyX+92hBEjInEKL0v13c/egDCTQAAAIEAvFdWGq0ccOPbw4f/F8LpZqvWDydAcpXHV3thwb7WkFfppvm4SZte0zds1FJ+Hr8Xzzc5zMHe6J4Nlay/rP4ewmIW7iFKNBEYb/yWa+ceLrs+TfR672TaAgO6o7iSRofEq5YLdwgrwkMmIawa21FrZ2D9SPao/IwvENzk/xcHu7YAAACAQFXQH6HQnxOrw4dqf0NqeKy1tfIPxYYUZhPJfo9O0AmBW2S36pD2l14kS89fvz6Y1g8gN/FwFnRncMzlLY/hX70FSc/3hKBSbH6C6j8hwlgFKfizav21eS358JJz93leOakJZnGb8XlWvz1UJbwCsnR2VEY8Dz90uIk1l/UqHkA= loic@call",
"title": "ABC",
- "id": 4
+ "key": "ssh-dss AAAAB3NzaC1kc3MAAACBAMLrhYgI3atfrSD6KDas1b/3n6R/HP+bLaHHX6oh+L1vg31mdUqK0Ac/NjZoQunavoyzqdPYhFz9zzOezCrZKjuJDS3NRK9rspvjgM0xYR4d47oNZbdZbwkI4cTv/gcMlquRy0OvpfIvJtjtaJWMwTLtM5VhRusRuUlpH99UUVeXAAAAFQCVyX+92hBEjInEKL0v13c/egDCTQAAAIEAvFdWGq0ccOPbw4f/F8LpZqvWDydAcpXHV3thwb7WkFfppvm4SZte0zds1FJ+Hr8Xzzc5zMHe6J4Nlay/rP4ewmIW7iFKNBEYb/yWa+ceLrs+TfR672TaAgO6o7iSRofEq5YLdwgrwkMmIawa21FrZ2D9SPao/IwvENzk/xcHu7YAAACAQFXQH6HQnxOrw4dqf0NqeKy1tfIPxYYUZhPJfo9O0AmBW2S36pD2l14kS89fvz6Y1g8gN/FwFnRncMzlLY/hX70FSc/3hKBSbH6C6j8hwlgFKfizav21eS358JJz93leOakJZnGb8XlWvz1UJbwCsnR2VEY8Dz90uIk1l/UqHkA= loic@call",
+ "expires_at": "2016-01-21T00:00:00.000Z"
}
```
@@ -797,6 +797,7 @@ Parameters:
- `id` (required) - ID of specified user
- `title` (required) - new SSH Key's title
- `key` (required) - new SSH key
+- `expires_at` (optional) - The expiration date of the SSH key in ISO 8601 format (`YYYY-MM-DDTHH:MM:SSZ`)
## Delete SSH key for current user
@@ -833,7 +834,7 @@ GET /user/gpg_keys
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/user/gpg_keys
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/user/gpg_keys"
```
Example response:
@@ -858,12 +859,12 @@ GET /user/gpg_keys/:key_id
Parameters:
-| Attribute | Type | Required | Description |
-| --------- | ------- | -------- | ----------- |
+| Attribute | Type | Required | Description |
+| --------- | ------- | -------- | --------------------- |
| `key_id` | integer | yes | The ID of the GPG key |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/user/gpg_keys/1
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/user/gpg_keys/1"
```
Example response:
@@ -886,12 +887,12 @@ POST /user/gpg_keys
Parameters:
-| Attribute | Type | Required | Description |
-| --------- | ------ | -------- | ----------- |
+| Attribute | Type | Required | Description |
+| --------- | ------ | -------- | --------------- |
| key | string | yes | The new GPG key |
```shell
-curl --data "key=-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\nxsBNBFV..." --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/user/gpg_keys
+curl --data "key=-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\nxsBNBFV..." --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/user/gpg_keys"
```
Example response:
@@ -916,12 +917,12 @@ DELETE /user/gpg_keys/:key_id
Parameters:
-| Attribute | Type | Required | Description |
-| --------- | ------- | -------- | ----------- |
+| Attribute | Type | Required | Description |
+| --------- | ------- | -------- | --------------------- |
| `key_id` | integer | yes | The ID of the GPG key |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/user/gpg_keys/1
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/user/gpg_keys/1"
```
Returns `204 No Content` on success, or `404 Not found` if the key cannot be found.
@@ -936,12 +937,12 @@ GET /users/:id/gpg_keys
Parameters:
-| Attribute | Type | Required | Description |
-| --------- | ------- | -------- | ----------- |
+| Attribute | Type | Required | Description |
+| --------- | ------- | -------- | ------------------ |
| `id` | integer | yes | The ID of the user |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/users/2/gpg_keys
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/users/2/gpg_keys"
```
Example response:
@@ -966,13 +967,13 @@ GET /users/:id/gpg_keys/:key_id
Parameters:
-| Attribute | Type | Required | Description |
-| --------- | ------- | -------- | ----------- |
-| `id` | integer | yes | The ID of the user |
+| Attribute | Type | Required | Description |
+| --------- | ------- | -------- | --------------------- |
+| `id` | integer | yes | The ID of the user |
| `key_id` | integer | yes | The ID of the GPG key |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/users/2/gpg_keys/1
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/users/2/gpg_keys/1"
```
Example response:
@@ -995,13 +996,13 @@ POST /users/:id/gpg_keys
Parameters:
-| Attribute | Type | Required | Description |
-| --------- | ------- | -------- | ----------- |
-| `id` | integer | yes | The ID of the user |
+| Attribute | Type | Required | Description |
+| --------- | ------- | -------- | --------------------- |
+| `id` | integer | yes | The ID of the user |
| `key_id` | integer | yes | The ID of the GPG key |
```shell
-curl --data "key=-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\nxsBNBFV..." --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/users/2/gpg_keys
+curl --data "key=-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\nxsBNBFV..." --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/users/2/gpg_keys"
```
Example response:
@@ -1026,13 +1027,13 @@ DELETE /users/:id/gpg_keys/:key_id
Parameters:
-| Attribute | Type | Required | Description |
-| --------- | ------- | -------- | ----------- |
-| `id` | integer | yes | The ID of the user |
+| Attribute | Type | Required | Description |
+| --------- | ------- | -------- | --------------------- |
+| `id` | integer | yes | The ID of the user |
| `key_id` | integer | yes | The ID of the GPG key |
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/users/2/gpg_keys/1
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/users/2/gpg_keys/1"
```
## List emails
@@ -1198,7 +1199,7 @@ Will return `201 OK` on success, `404 User Not Found` is user cannot be found or
## Deactivate user
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/22257) in GitLab 12.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22257) in GitLab 12.4.
Deactivates the specified user. Available only for admin.
@@ -1220,7 +1221,7 @@ Returns:
## Activate user
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/22257) in GitLab 12.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22257) in GitLab 12.4.
Activates the specified user. Available only for admin.
@@ -1261,7 +1262,7 @@ Parameters:
| `state` | string | no | filter tokens based on state (`all`, `active`, `inactive`) |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/users/42/impersonation_tokens
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/users/42/impersonation_tokens"
```
Example response:
@@ -1313,7 +1314,7 @@ Parameters:
| `impersonation_token_id` | integer | yes | The ID of the impersonation token |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/users/42/impersonation_tokens/2
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/users/42/impersonation_tokens/2"
```
Example response:
@@ -1347,15 +1348,15 @@ settings page.
POST /users/:user_id/impersonation_tokens
```
-| Attribute | Type | Required | Description |
-| ------------ | ------- | -------- | ----------- |
-| `user_id` | integer | yes | The ID of the user |
-| `name` | string | yes | The name of the impersonation token |
-| `expires_at` | date | no | The expiration date of the impersonation token in ISO format (`YYYY-MM-DD`)|
-| `scopes` | array | yes | The array of scopes of the impersonation token (`api`, `read_user`) |
+| Attribute | Type | Required | Description |
+| ------------ | ------- | -------- | --------------------------------------------------------------------------- |
+| `user_id` | integer | yes | The ID of the user |
+| `name` | string | yes | The name of the impersonation token |
+| `expires_at` | date | no | The expiration date of the impersonation token in ISO format (`YYYY-MM-DD`) |
+| `scopes` | array | yes | The array of scopes of the impersonation token (`api`, `read_user`) |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --data "name=mytoken" --data "expires_at=2017-04-04" --data "scopes[]=api" https://gitlab.example.com/api/v4/users/42/impersonation_tokens
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --data "name=mytoken" --data "expires_at=2017-04-04" --data "scopes[]=api" "https://gitlab.example.com/api/v4/users/42/impersonation_tokens"
```
Example response:
@@ -1387,15 +1388,15 @@ DELETE /users/:user_id/impersonation_tokens/:impersonation_token_id
```
```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/users/42/impersonation_tokens/1
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/users/42/impersonation_tokens/1"
```
Parameters:
-| Attribute | Type | Required | Description |
-| --------- | ---- | -------- | ----------- |
-| `user_id` | integer | yes | The ID of the user |
-| `impersonation_token_id` | integer | yes | The ID of the impersonation token |
+| Attribute | Type | Required | Description |
+| ------------------------ | ------- | -------- | --------------------------------- |
+| `user_id` | integer | yes | The ID of the user |
+| `impersonation_token_id` | integer | yes | The ID of the impersonation token |
### Get user activities (admin only)
@@ -1406,8 +1407,8 @@ Get the last activity date for all users, sorted from oldest to newest.
The activities that update the timestamp are:
- Git HTTP/SSH activities (such as clone, push)
-- User logging in into GitLab
-- User visiting pages related to Dashboards, Projects, Issues, and Merge Requests ([introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/54947) in GitLab 11.8)
+- User logging in to GitLab
+- User visiting pages related to Dashboards, Projects, Issues, and Merge Requests ([introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/54947) in GitLab 11.8)
- User using the API
- User using the GraphQL API
@@ -1420,12 +1421,12 @@ GET /user/activities
Parameters:
-| Attribute | Type | Required | Description |
-| --------- | ---- | -------- | ----------- |
-| `from` | string | no | Date string in the format YEAR-MONTH-DAY. For example, `2016-03-11`. Defaults to 6 months ago. |
+| Attribute | Type | Required | Description |
+| --------- | ------ | -------- | ---------------------------------------------------------------------------------------------- |
+| `from` | string | no | Date string in the format YEAR-MONTH-DAY. For example, `2016-03-11`. Defaults to 6 months ago. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/user/activities
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/user/activities"
```
Example response:
@@ -1454,7 +1455,7 @@ Please note that `last_activity_at` is deprecated, please use `last_activity_on`
## User memberships (admin only)
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/20532) in GitLab 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/20532) in GitLab 12.8.
Lists all projects and groups a user is a member of. This endpoint is available for admins only.
It returns the `source_id`, `source_name`, `source_type` and `access_level` of a membership.
@@ -1467,10 +1468,10 @@ GET /users/:id/memberships
Parameters:
-| Attribute | Type | Required | Description |
-| --------- | ---- | -------- | ----------- |
-| `id` | integer | yes | The ID of a specified user |
-| `type` | string | no | Filter memberships by type. Can be either `Project` or `Namespace` |
+| Attribute | Type | Required | Description |
+| --------- | ------- | -------- | ------------------------------------------------------------------ |
+| `id` | integer | yes | The ID of a specified user |
+| `type` | string | no | Filter memberships by type. Can be either `Project` or `Namespace` |
Returns:
@@ -1480,7 +1481,7 @@ Returns:
- `400 Bad Request` when requested type is not supported.
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/users/<user_id>/memberships
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/users/:user_id/memberships"
```
Example response:
diff --git a/doc/api/v3_to_v4.md b/doc/api/v3_to_v4.md
index 76e5dd9abb6..4571d4d8304 100644
--- a/doc/api/v3_to_v4.md
+++ b/doc/api/v3_to_v4.md
@@ -3,7 +3,7 @@
Since GitLab 9.0, API V4 is the preferred version to be used.
API V3 was unsupported from GitLab 9.5, released on August
-22, 2017. API v3 was removed in [GitLab 11.0](https://gitlab.com/gitlab-org/gitlab-foss/issues/36819).
+22, 2017. API v3 was removed in [GitLab 11.0](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/36819).
The V3 API documentation is still
[available](https://gitlab.com/gitlab-org/gitlab-foss/blob/8-16-stable/doc/api/README.md).
diff --git a/doc/api/version.md b/doc/api/version.md
index 6c9ff6ac9e1..661fdfb4b03 100644
--- a/doc/api/version.md
+++ b/doc/api/version.md
@@ -10,7 +10,7 @@ GET /version
```
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/version
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/version"
```
Example response:
diff --git a/doc/api/visual_review_discussions.md b/doc/api/visual_review_discussions.md
index 161f84f4618..bcbfdbdc6d0 100644
--- a/doc/api/visual_review_discussions.md
+++ b/doc/api/visual_review_discussions.md
@@ -36,5 +36,5 @@ Parameters:
| `position[y]` | integer | no | Y coordinate (Only stored for `image` diff notes) |
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/merge_requests/11/visual_review_discussions?body=comment
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/visual_review_discussions?body=comment"
```
diff --git a/doc/api/vulnerabilities.md b/doc/api/vulnerabilities.md
index ff1a6a7ebcd..70f29d961e3 100644
--- a/doc/api/vulnerabilities.md
+++ b/doc/api/vulnerabilities.md
@@ -1,6 +1,6 @@
# 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 Ultimate](https://about.gitlab.com/pricing/) 12.6.
NOTE: **Note:**
The former Vulnerabilities API was renamed to Vulnerability Findings API
@@ -9,14 +9,6 @@ This document now describes the new Vulnerabilities API that provides access to
[Standalone Vulnerabilities](https://gitlab.com/groups/gitlab-org/-/epics/634).
CAUTION: **Caution:**
-This API is currently in development and is protected by a **disabled**
-[feature flag](../development/feature_flags/index.md).
-On a self-managed GitLab instance, an administrator can enable it by starting the Rails console
-(`sudo gitlab-rails console`) and then running the following command: `Feature.enable(:first_class_vulnerabilities)`.
-To test if the Vulnerabilities API was successfully enabled, run the following command:
-`Feature.enabled?(:first_class_vulnerabilities)`.
-
-CAUTION: **Caution:**
This API is in an alpha stage and considered unstable.
The response payload may be subject to change or breakage
across GitLab releases.
@@ -40,7 +32,7 @@ GET /vulnerabilities/:id
| `id` | integer or string | yes | The ID of a Vulnerability to get |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/vulnerabilities/1
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/vulnerabilities/1"
```
Example response:
diff --git a/doc/api/vulnerability_exports.md b/doc/api/vulnerability_exports.md
index 2c9ac5d65eb..2cb647e797b 100644
--- a/doc/api/vulnerability_exports.md
+++ b/doc/api/vulnerability_exports.md
@@ -1,14 +1,6 @@
# 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.
-
-CAUTION: **Caution:**
-This API is currently in development and is protected by a **disabled**
-[feature flag](../development/feature_flags/index.md).
-On a self-managed GitLab instance, an administrator can enable it by starting the Rails console
-(`sudo gitlab-rails console`) and then running the following command: `Feature.enable(:first_class_vulnerabilities)`.
-To test if the Vulnerability Exports API was successfully enabled, run the following command:
-`Feature.enabled?(:first_class_vulnerabilities)`.
+> [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.
CAUTION: **Caution:**
This API is in an alpha stage and considered unstable.
@@ -39,7 +31,7 @@ POST /security/projects/:id/vulnerability_exports
| `id` | integer or string | yes | The ID or [URL-encoded path](README.md#namespaced-path-encoding) of the project which the authenticated user is a member of |
```shell
-curl --header POST "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/security/projects/1/vulnerability_exports
+curl --header POST "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/vulnerability_exports"
```
The created vulnerability export is automatically deleted after 1 hour.
@@ -155,7 +147,7 @@ GET /security/vulnerability_exports/:id
| `id` | integer or string | yes | The vulnerability export's ID |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/security/vulnerability_exports/2
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/security/vulnerability_exports/2"
```
If the vulnerability export isn't finished, the response is `202 Accepted`.
@@ -192,7 +184,7 @@ GET /security/vulnerability_exports/:id/download
| `id` | integer or string | yes | The vulnerability export's ID |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/security/vulnerability_exports/2/download
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/security/vulnerability_exports/2/download"
```
The response will be `404 Not Found` if the vulnerability export is not finished yet or was not found.
diff --git a/doc/api/vulnerability_findings.md b/doc/api/vulnerability_findings.md
index f5e607d6829..7fbd58ea62c 100644
--- a/doc/api/vulnerability_findings.md
+++ b/doc/api/vulnerability_findings.md
@@ -4,7 +4,7 @@
NOTE: **Note:**
This API resource is renamed from Vulnerabilities to Vulnerability Findings because the Vulnerabilities are reserved
-for serving the upcoming [Standalone Vulnerability objects](https://gitlab.com/gitlab-org/gitlab/issues/13561).
+for serving the upcoming [Standalone Vulnerability objects](https://gitlab.com/gitlab-org/gitlab/-/issues/13561).
To fix any broken integrations with the former Vulnerabilities API, change the `vulnerabilities` URL part to be
`vulnerability_findings`.
@@ -47,19 +47,19 @@ GET /projects/:id/vulnerability_findings?pipeline_id=42
```
CAUTION: **Deprecation:**
-Beginning with GitLab 12.9, the `undefined` severity level is deprecated and the `undefined` confidence level isn't reported for new vulnerabilities.
+Beginning with GitLab 12.9, the `undefined` severity and confidence level is no longer reported.
| Attribute | Type | Required | Description |
| ------------- | -------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) which the authenticated user is a member of. |
| `report_type` | string array | no | Returns vulnerability findings belonging to specified report type. Valid values: `sast`, `dast`, `dependency_scanning`, or `container_scanning`. Defaults to all. |
| `scope` | string | no | Returns vulnerability findings for the given scope: `all` or `dismissed`. Defaults to `dismissed`. |
-| `severity` | string array | no | Returns vulnerability findings belonging to specified severity level: `undefined`, `info`, `unknown`, `low`, `medium`, `high`, or `critical`. Defaults to all. |
-| `confidence` | string array | no | Returns vulnerability findings belonging to specified confidence level: `undefined`, `ignore`, `unknown`, `experimental`, `low`, `medium`, `high`, or `confirmed`. Defaults to all. |
+| `severity` | string array | no | Returns vulnerability findings belonging to specified severity level: `info`, `unknown`, `low`, `medium`, `high`, or `critical`. Defaults to all. |
+| `confidence` | string array | no | Returns vulnerability findings belonging to specified confidence level: `ignore`, `unknown`, `experimental`, `low`, `medium`, `high`, or `confirmed`. Defaults to all. |
| `pipeline_id` | integer/string | no | Returns vulnerability findings belonging to specified pipeline. |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/4/vulnerability_findings
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/4/vulnerability_findings"
```
Example response:
diff --git a/doc/api/wikis.md b/doc/api/wikis.md
index 48b04fefd39..f7595e7efe6 100644
--- a/doc/api/wikis.md
+++ b/doc/api/wikis.md
@@ -18,7 +18,7 @@ GET /projects/:id/wikis
| `with_content` | boolean | no | Include pages' content |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/wikis?with_content=1
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/wikis?with_content=1"
```
Example response:
@@ -59,7 +59,7 @@ GET /projects/:id/wikis/:slug
| `slug` | string | yes | The slug (a unique string) of the wiki page |
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/wikis/home
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/wikis/home"
```
Example response:
@@ -174,7 +174,7 @@ The `file=` parameter must point to a file on your filesystem and be preceded
by `@`. For example:
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form "file=@dk.png" https://gitlab.example.com/api/v4/projects/1/wikis/attachments
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form "file=@dk.png" "https://gitlab.example.com/api/v4/projects/1/wikis/attachments"
```
Example response:
diff --git a/doc/articles/how_to_configure_ldap_gitlab_ce/index.md b/doc/articles/how_to_configure_ldap_gitlab_ce/index.md
index 8e2e54711e7..2fbeb6f2506 100644
--- a/doc/articles/how_to_configure_ldap_gitlab_ce/index.md
+++ b/doc/articles/how_to_configure_ldap_gitlab_ce/index.md
@@ -1,5 +1,5 @@
---
-redirect_to: '../../administration/auth/how_to_configure_ldap_gitlab_ce/index.md'
+redirect_to: '../../administration/auth/ldap/index.md'
---
-This document was moved to [another location](../../administration/auth/how_to_configure_ldap_gitlab_ce/index.md).
+This document was moved to [another location](../../administration/auth/ldap/index.md).
diff --git a/doc/articles/how_to_configure_ldap_gitlab_ee/index.md b/doc/articles/how_to_configure_ldap_gitlab_ee/index.md
index 3e6f3130437..2fbeb6f2506 100644
--- a/doc/articles/how_to_configure_ldap_gitlab_ee/index.md
+++ b/doc/articles/how_to_configure_ldap_gitlab_ee/index.md
@@ -1,5 +1,5 @@
---
-redirect_to: '../../administration/auth/how_to_configure_ldap_gitlab_ee/index.md'
+redirect_to: '../../administration/auth/ldap/index.md'
---
-This document was moved to [another location](../../administration/auth/how_to_configure_ldap_gitlab_ee/index.md).
+This document was moved to [another location](../../administration/auth/ldap/index.md).
diff --git a/doc/articles/index.md b/doc/articles/index.md
index 0cd9baba20e..7fc4c18f771 100644
--- a/doc/articles/index.md
+++ b/doc/articles/index.md
@@ -8,7 +8,7 @@ Technical articles are
topic-related documentation, written with a user-friendly approach and language, aiming
to provide the community with guidance on specific processes to achieve certain objectives.
-The list of technical articles was [deprecated](https://gitlab.com/gitlab-org/gitlab-foss/issues/41138) in favor of having them linked from their topic-related documentation:
+The list of technical articles was [deprecated](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41138) in favor of having them linked from their topic-related documentation:
- [Git](../topics/git/index.md)
- [GitLab administrator](../administration/index.md)
diff --git a/doc/ci/README.md b/doc/ci/README.md
index fce0ad15b70..150f160b762 100644
--- a/doc/ci/README.md
+++ b/doc/ci/README.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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
comments: false
description: "Learn how to use GitLab CI/CD, the GitLab built-in Continuous Integration, Continuous Deployment, and Continuous Delivery toolset to build, test, and deploy your application."
type: index
@@ -57,8 +60,10 @@ the following documents:
- [GitLab CI/CD basic workflow](introduction/index.md#basic-cicd-workflow).
- [Step-by-step guide for writing `.gitlab-ci.yml` for the first time](../user/project/pages/getting_started_part_four.md).
-If you're coming over from Jenkins, you can also check out our handy [reference](jenkins/index.md)
-for converting your pipelines.
+If you're migrating from another CI/CD tool, check out our handy references:
+
+- [Migrating from CircleCI](migration/circleci.md)
+- [Migrating from Jenkins](jenkins/index.md)
You can also get started by using one of the
[`.gitlab-ci.yml` templates](https://gitlab.com/gitlab-org/gitlab-foss/tree/master/lib/gitlab/ci/templates)
@@ -66,7 +71,7 @@ available through the UI. You can use them by creating a new file,
choosing a template that suits your application, and adjusting it
to your needs:
-![Use a .gitlab-ci.yml template](img/add_file_template_11_10.png)
+![Use a `.gitlab-ci.yml` template](img/add_file_template_11_10.png)
For a broader overview, see the [CI/CD getting started](quick_start/README.md) guide.
@@ -75,7 +80,7 @@ Once you're familiar with how GitLab CI/CD works, see the
for all the attributes you can set and use.
NOTE: **Note:**
-GitLab CI/CD and [shared runners](runners/README.md#shared-specific-and-group-runners) are enabled in GitLab.com and available for all users, limited only to the [user's pipelines quota](../user/gitlab_com/index.md#shared-runners).
+GitLab CI/CD and [shared runners](runners/README.md#shared-runners) are enabled in GitLab.com and available for all users, limited only to the [user's pipelines quota](../user/gitlab_com/index.md#shared-runners).
## Concepts
@@ -103,7 +108,7 @@ GitLab CI/CD supports numerous configuration options:
| [Pipeline triggers](triggers/README.md) | Trigger pipelines through the API. |
| [Pipelines for Merge Requests](merge_request_pipelines/index.md) | Design a pipeline structure for running a pipeline in merge requests. |
| [Integrate with Kubernetes clusters](../user/project/clusters/index.md) | Connect your project to Google Kubernetes Engine (GKE) or an existing Kubernetes cluster. |
-| [Optimize GitLab and Runner for large repositories](large_repositories/index.md) | Recommended strategies for handling large repos. |
+| [Optimize GitLab and Runner for large repositories](large_repositories/index.md) | Recommended strategies for handling large repositories. |
| [`.gitlab-ci.yml` full reference](yaml/README.md) | All the attributes you can use with GitLab CI/CD. |
Note that certain operations can only be performed according to the
@@ -183,22 +188,43 @@ See also the [Why CI/CD?](https://docs.google.com/presentation/d/1OGgk2Tcxbpl7DJ
As GitLab CI/CD has evolved, certain breaking changes have
been necessary. These are:
+#### 13.0
+
+- [Remove Backported
+ `os.Expand`](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4915)
+- [Remove Fedora 29 package
+ support](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/16158)
+- [Remove macOS 32-bit
+ support](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/25466)
+- [Removed `debug/jobs/list?v=1`
+ endpoint](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/6361)
+- [Remove support for array of strings when defining services for Docker
+ executor](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4922)
+- [Remove `--docker-services` flag on register
+ command](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/6404)
+- [Remove legacy build directory
+ caching](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4180)
+- [Remove `FF_USE_LEGACY_VOLUMES_MOUNTING_ORDER` feature
+ flag](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/6581)
+- [Remove support for Windows Server
+ 1803](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/6553)
+
#### 12.0
- [Use refspec to clone/fetch Git
- repository](https://gitlab.com/gitlab-org/gitlab-runner/issues/4069).
+ repository](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4069).
- [Old cache
- configuration](https://gitlab.com/gitlab-org/gitlab-runner/issues/4070).
+ configuration](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4070).
- [Old metrics server
- configuration](https://gitlab.com/gitlab-org/gitlab-runner/issues/4072).
+ configuration](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4072).
- [Remove
- `FF_K8S_USE_ENTRYPOINT_OVER_COMMAND`](https://gitlab.com/gitlab-org/gitlab-runner/issues/4073).
+ `FF_K8S_USE_ENTRYPOINT_OVER_COMMAND`](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4073).
- [Remove Linux distributions that reach
EOL](https://gitlab.com/gitlab-org/gitlab-runner/-/merge_requests/1130).
- [Update command line API for helper
- images](https://gitlab.com/gitlab-org/gitlab-runner/issues/4013).
+ images](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4013).
- [Remove old `git clean`
- flow](https://gitlab.com/gitlab-org/gitlab-runner/issues/4175).
+ flow](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4175).
#### 11.0
diff --git a/doc/ci/caching/index.md b/doc/ci/caching/index.md
index 16cabae353e..392dd4fdeba 100644
--- a/doc/ci/caching/index.md
+++ b/doc/ci/caching/index.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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: index, concepts, howto
---
@@ -83,9 +86,9 @@ which type of Runner you are using, cache can act differently.
From the perspective of the developer, to ensure maximum availability of the
cache, when declaring `cache` in your jobs, use one or a mix of the following:
-- [Tag your Runners](../runners/README.md#using-tags) and use the tag on jobs
+- [Tag your Runners](../runners/README.md#use-tags-to-limit-the-number-of-jobs-using-the-runner) and use the tag on jobs
that share their cache.
-- [Use sticky Runners](../runners/README.md#locking-a-specific-runner-from-being-enabled-for-other-projects)
+- [Use sticky Runners](../runners/README.md#prevent-a-specific-runner-from-being-enabled-for-other-projects)
that will be only available to a particular project.
- [Use a `key`](../yaml/README.md#cachekey) that fits your workflow (for example,
different caches on each branch). For that, you can take advantage of the
@@ -556,7 +559,7 @@ next run of the pipeline, the cache will be stored in a different location.
### Clearing the cache manually
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/41249) in GitLab 10.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41249) in GitLab 10.4.
If you want to avoid editing `.gitlab-ci.yml`, you can easily clear the cache
via GitLab's UI:
diff --git a/doc/ci/chatops/README.md b/doc/ci/chatops/README.md
index 5488834a24e..a8fea0836c1 100644
--- a/doc/ci/chatops/README.md
+++ b/doc/ci/chatops/README.md
@@ -1,4 +1,7 @@
---
+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/#designated-technical-writers
type: index, concepts, howto
---
diff --git a/doc/ci/ci_cd_for_external_repos/bitbucket_integration.md b/doc/ci/ci_cd_for_external_repos/bitbucket_integration.md
index 2836f9932c6..ba801950c40 100644
--- a/doc/ci/ci_cd_for_external_repos/bitbucket_integration.md
+++ b/doc/ci/ci_cd_for_external_repos/bitbucket_integration.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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: howto
---
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 399205d66cf..5365ef49944 100644
--- a/doc/ci/ci_cd_for_external_repos/github_integration.md
+++ b/doc/ci/ci_cd_for_external_repos/github_integration.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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: howto
---
@@ -12,7 +15,7 @@ GitLab.
Watch a video on [Using GitLab CI/CD pipelines with GitHub repositories](https://www.youtube.com/watch?v=qgl3F2j-1cI).
NOTE: **Note:**
-Because of [GitHub limitations](https://gitlab.com/gitlab-org/gitlab/issues/9147),
+Because of [GitHub limitations](https://gitlab.com/gitlab-org/gitlab/-/issues/9147),
[GitHub OAuth](../../integration/github.md#enabling-github-oauth)
cannot be used to authenticate with GitHub as an external CI/CD repository.
@@ -20,7 +23,7 @@ cannot be used to authenticate with GitHub as an external CI/CD repository.
NOTE: **Note:**
Personal access tokens can only be used to connect GitHub.com
-repositories to GitLab.
+repositories to GitLab, and the GitHub user must have the [owner role](https://help.github.com/en/github/getting-started-with-github/access-permissions-on-github).
To perform a one-off authorization with GitHub to grant GitLab access your
repositories:
@@ -33,11 +36,9 @@ repositories:
your project, update commit statuses, and create a web hook to notify
GitLab of new commits.
-1. In GitLab create a **CI/CD for external repo** project and select
+1. In GitLab, go to the [new project page](../../gitlab-basics/create-project.md#create-a-project-in-gitlab), select the **CI/CD for external repo** tab, and then click
**GitHub**.
- ![Create project](img/github_omniauth.png)
-
1. Paste the token into the **Personal access token** field and click **List
Repositories**. Click **Connect** to select the repository.
@@ -91,7 +92,7 @@ To manually enable GitLab CI/CD for your repository:
https://gitlab.com/api/v4/projects/<NAMESPACE>%2F<PROJECT>/mirror/pull?private_token=<PERSONAL_ACCESS_TOKEN>
```
- ![Create web hook](img/github_push_webhook.png)
+ Select the **Let me select individual events** option, then check the **Pull requests** and **Pushes** checkboxes. These settings are needed for [pipelines for external pull requests](index.md#pipelines-for-external-pull-requests).
1. In GitHub add a `.gitlab-ci.yml` to configure GitLab CI/CD.
diff --git a/doc/ci/ci_cd_for_external_repos/index.md b/doc/ci/ci_cd_for_external_repos/index.md
index cc6645b72c2..78988e8a057 100644
--- a/doc/ci/ci_cd_for_external_repos/index.md
+++ b/doc/ci/ci_cd_for_external_repos/index.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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: index, howto
---
@@ -31,7 +34,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 Premium 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.
@@ -87,10 +90,10 @@ The variable names are prefixed with `CI_EXTERNAL_PULL_REQUEST_`.
### Limitations
-This feature currently does not support Pull Requests from fork repositories. Any Pull Requests from fork repositories will be ignored. [Read more](https://gitlab.com/gitlab-org/gitlab/issues/5667).
+This feature currently does not support Pull Requests from fork repositories. Any Pull Requests from fork repositories will be ignored. [Read more](https://gitlab.com/gitlab-org/gitlab/-/issues/5667).
Given that GitLab will create 2 pipelines, if changes are pushed to a remote branch that
references an open Pull Request, both will contribute to the status of the Pull Request
via GitHub integration. If you want to exclusively run pipelines on external pull
requests and not on branches you can add `except: [branches]` to the job specs.
-[Read more](https://gitlab.com/gitlab-org/gitlab/issues/24089#workaround).
+[Read more](https://gitlab.com/gitlab-org/gitlab/-/issues/24089#workaround).
diff --git a/doc/ci/cloud_deployment/index.md b/doc/ci/cloud_deployment/index.md
index 8883ad5dfd6..26eb99bd55a 100644
--- a/doc/ci/cloud_deployment/index.md
+++ b/doc/ci/cloud_deployment/index.md
@@ -7,7 +7,7 @@ type: howto
# Cloud deployment
-Interacting with a major cloud provider such as Amazon AWS may have become a much needed task that's
+Interacting with a major cloud provider may have become a much needed task that's
part of your delivery process. GitLab is making this process less painful by providing Docker images
that come with the needed libraries and tools pre-installed.
By referencing them in your CI/CD pipeline, you'll be able to interact with your chosen
@@ -15,7 +15,12 @@ cloud provider more easily.
## AWS
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/31167) in GitLab 12.6.
+GitLab provides Docker images to simplify working with AWS, and a template to make
+it easier to [deploy to AWS](#deploy-your-application-to-the-aws-elastic-container-service-ecs).
+
+### Run AWS commands from GitLab CI/CD
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/31167) in GitLab 12.6.
GitLab's AWS Docker image provides the [AWS Command Line Interface](https://aws.amazon.com/cli/),
which enables you to run `aws` commands. As part of your deployment strategy, you can run `aws` commands directly from
@@ -30,12 +35,21 @@ Some credentials are required to be able to run `aws` commands:
NOTE: **Note:**
A new **Access key ID** and **Secret access key** pair will be generated. Please take a note of them right away.
-1. In your GitLab project, go to **Settings > CI / CD**. Set the Access key ID and Secret access key as [environment variables](../variables/README.md#gitlab-cicd-environment-variables), using the following variable names:
+1. In your GitLab project, go to **Settings > CI / CD**. Set the following as
+ [environment variables](../variables/README.md#gitlab-cicd-environment-variables)
+ (see table below):
- | Env. variable name | Value |
- |:------------------------|:-------------------------|
- | `AWS_ACCESS_KEY_ID` | Your "Access key ID" |
- | `AWS_SECRET_ACCESS_KEY` | Your "Secret access key" |
+ - Access key ID.
+ - Secret access key.
+ - Region code. You can check the [list of AWS regional endpoints](https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints).
+ You might want to check if the AWS service you intend to use is
+ [available in the chosen region](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/).
+
+ | Env. variable name | Value |
+ |:------------------------|:-----------------------|
+ | `AWS_ACCESS_KEY_ID` | Your Access key ID |
+ | `AWS_SECRET_ACCESS_KEY` | Your Secret access key |
+ | `AWS_DEFAULT_REGION` | Your region code |
1. You can now use `aws` commands in the `.gitlab-ci.yml` file of this project:
@@ -49,25 +63,25 @@ Some credentials are required to be able to run `aws` commands:
```
NOTE: **Note:**
- Please note that the image used in the example above
+ The image used in the example above
(`registry.gitlab.com/gitlab-org/cloud-deploy/aws-base:latest`) is hosted on the [GitLab
Container Registry](../../user/packages/container_registry/index.md) and is
- ready to use. Alternatively, replace the image with another one hosted on [AWS ECR](#aws-ecr).
+ ready to use. Alternatively, replace the image with one hosted on AWS ECR.
-### AWS ECR
+### Use an AWS Elastic Container Registry (ECR) image in your CI/CD
-Instead of referencing an image hosted on the GitLab Registry, you are free to
-reference any other image hosted on any third-party registry, such as
+Instead of referencing an image hosted on the GitLab Registry, you can
+reference an image hosted on any third-party registry, such as the
[Amazon Elastic Container Registry (ECR)](https://aws.amazon.com/ecr/).
-To do so, please make sure to [push your image into your ECR
-repository](https://docs.aws.amazon.com/AmazonECR/latest/userguide/docker-push-ecr-image.html)
-before referencing it in your `.gitlab-ci.yml` file and replace the `image`
-path to point to your ECR.
+To do so, [push your image into your ECR
+repository](https://docs.aws.amazon.com/AmazonECR/latest/userguide/docker-push-ecr-image.html).
+Then reference it in your `.gitlab-ci.yml` file and replace the `image`
+path to point to your ECR image.
-### Deploy your application to AWS Elastic Container Service (ECS)
+### Deploy your application to the AWS Elastic Container Service (ECS)
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/207962) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/207962) in GitLab 12.9.
GitLab provides a series of [CI templates that you can include in your project](../yaml/README.md#include).
To automate deployments of your application to your [Amazon Elastic Container Service](https://aws.amazon.com/ecs/) (AWS ECS)
@@ -80,7 +94,7 @@ components, like an ECS service, ECS task definition, a database on AWS RDS, etc
After you're all set up on AWS ECS, follow these steps:
1. Make sure your AWS credentials are set up as environment variables for your
- project. You can follow [the steps above](#aws) to complete this setup.
+ project. You can follow [the steps above](#run-aws-commands-from-gitlab-cicd) to complete this setup.
1. Add these variables to your project's `.gitlab-ci.yml` file:
```yaml
@@ -107,11 +121,11 @@ After you're all set up on AWS ECS, follow these steps:
```yaml
include:
- - template: Deploy-ECS.gitlab-ci.yml
+ - template: AWS/Deploy-ECS.gitlab-ci.yml
```
The `Deploy-ECS` template ships with GitLab and is available [on
- GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Deploy-ECS.gitlab-ci.yml).
+ GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/AWS/Deploy-ECS.gitlab-ci.yml).
1. Commit and push your updated `.gitlab-ci.yml` to your project's repository, and you're done!
@@ -123,6 +137,17 @@ After you're all set up on AWS ECS, follow these steps:
task definition, making the cluster pull the newest version of your
application.
+CAUTION: **Warning:**
+The [`Deploy-ECS.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/AWS/Deploy-ECS.gitlab-ci.yml)
+template includes both the [`Jobs/Build.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml)
+and [`Jobs/Deploy/ECS.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Jobs/Deploy/ECS.gitlab-ci.yml)
+"sub-templates". Do not include these "sub-templates" on their own, and only include the main
+`Deploy-ECS.gitlab-ci.yml` template. The "sub-templates" are designed to only be
+used along with the main template. They may move or change unexpectedly causing your
+pipeline to fail if you didn't include the main template. Also, the job names within
+these templates may change. Do not override these jobs names in your own pipeline,
+as the override will stop working when the name changes.
+
Alternatively, if you don't wish to use the `Deploy-ECS.gitlab-ci.yml` template
to deploy to AWS ECS, you can always use our
`aws-base` Docker image to run your own [AWS CLI commands for ECS](https://docs.aws.amazon.com/cli/latest/reference/ecs/index.html#cli-aws-ecs).
diff --git a/doc/ci/directed_acyclic_graph/img/dag_graph_example_clicked_v13_1.png b/doc/ci/directed_acyclic_graph/img/dag_graph_example_clicked_v13_1.png
new file mode 100644
index 00000000000..3610d471ef4
--- /dev/null
+++ b/doc/ci/directed_acyclic_graph/img/dag_graph_example_clicked_v13_1.png
Binary files differ
diff --git a/doc/ci/directed_acyclic_graph/img/dag_graph_example_v13_1.png b/doc/ci/directed_acyclic_graph/img/dag_graph_example_v13_1.png
new file mode 100644
index 00000000000..bd5215d31c8
--- /dev/null
+++ b/doc/ci/directed_acyclic_graph/img/dag_graph_example_v13_1.png
Binary files differ
diff --git a/doc/ci/directed_acyclic_graph/index.md b/doc/ci/directed_acyclic_graph/index.md
index 8722efd3b40..fff0fda0ab4 100644
--- a/doc/ci/directed_acyclic_graph/index.md
+++ b/doc/ci/directed_acyclic_graph/index.md
@@ -1,10 +1,13 @@
---
+stage: Verify
+group: Continuous Integration
+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
---
# Directed Acyclic Graph
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/47063) in GitLab 12.2.
+> - [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.
A [directed acyclic graph](https://www.techopedia.com/definition/5739/directed-acyclic-graph-dag) can be
@@ -75,3 +78,34 @@ are certain use cases that you may need to work around. For more information:
- [`needs` requirements and limitations](../yaml/README.md#requirements-and-limitations).
- Related epic [tracking planned improvements](https://gitlab.com/groups/gitlab-org/-/epics/1716).
+
+## DAG Visualization
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/215517) in GitLab 13.1 as a [Beta feature](https://about.gitlab.com/handbook/product/#beta).
+> - It's deployed behind a feature flag, disabled by default.
+> - It's enabled on GitLab.com.
+> - It's not recommended for production use.
+> - For GitLab self-managed instances, GitLab administrators can opt to [enable it](#enable-or-disable-dag-visualization-core-only)
+
+The DAG visualization makes it easier to visualize the relationships between dependent jobs in a DAG. This graph will display all the jobs in a pipeline that need or are needed by other jobs. Jobs with no relationships are not displayed in this view.
+
+![DAG visualization example](img/dag_graph_example_v13_1.png)
+
+Clicking a node will highlight all the job paths it depends on.
+
+![DAG visualization with path highlight](img/dag_graph_example_clicked_v13_1.png)
+
+### Enable or disable DAG Visualization **(CORE ONLY)**
+
+DAG Visualization is under development and requires more testing, but is being made available as a beta features so users can check its limitations and uses.
+
+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 opt to enable it for your instance:
+
+```ruby
+# Instance-wide
+Feature.enable(:dag_pipeline_tab)
+# or by project
+Feature.enable(:dag_pipeline_tab, Project.find(<project id>))
+```
diff --git a/doc/ci/docker/README.md b/doc/ci/docker/README.md
index f76471b50f2..4e7d9015e85 100644
--- a/doc/ci/docker/README.md
+++ b/doc/ci/docker/README.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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
comments: false
type: index
---
diff --git a/doc/ci/docker/using_docker_build.md b/doc/ci/docker/using_docker_build.md
index f992af6c8a5..65b9c03186b 100644
--- a/doc/ci/docker/using_docker_build.md
+++ b/doc/ci/docker/using_docker_build.md
@@ -1,10 +1,13 @@
---
+stage: Verify
+group: Continuous Integration
+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: concepts, howto
---
# Building Docker images with GitLab CI/CD
-GitLab CI/CD allows you to use Docker Engine to build and test docker-based projects.
+GitLab CI/CD allows you to use Docker Engine to build and test Docker-based projects.
One of the new trends in Continuous Integration/Deployment is to:
@@ -91,15 +94,15 @@ NOTE: **Note:**
By adding `gitlab-runner` to the `docker` group you are effectively granting `gitlab-runner` full root permissions.
For more information please read [On Docker security: `docker` group considered harmful](https://www.andreas-jung.com/contents/on-docker-security-docker-group-considered-harmful).
-### Use docker-in-docker workflow with Docker executor
+### Use Docker-in-Docker workflow with Docker executor
-The second approach is to use the special docker-in-docker (dind)
+The second approach is to use the special Docker-in-Docker (dind)
[Docker image](https://hub.docker.com/_/docker/) with all tools installed
(`docker`) and run the job script in context of that
image in privileged mode.
NOTE: **Note:**
-`docker-compose` is not part of docker-in-docker (dind). To use `docker-compose` in your
+`docker-compose` is not part of Docker-in-Docker (dind). To use `docker-compose` in your
CI builds, follow the `docker-compose`
[installation instructions](https://docs.docker.com/compose/install/).
@@ -113,19 +116,19 @@ out the official Docker documentation on
Docker-in-Docker works well, and is the recommended configuration, but it is
not without its own challenges:
-- When using docker-in-docker, each job is in a clean environment without the past
+- When using Docker-in-Docker, each job is in a clean environment without the past
history. Concurrent jobs work fine because every build gets its own
instance of Docker engine so they won't conflict with each other. But this
also means that jobs can be slower because there's no caching of layers.
- By default, Docker 17.09 and higher uses `--storage-driver overlay2` which is
the recommended storage driver. See [Using the overlayfs driver](#use-the-overlayfs-driver)
for details.
-- Since the `docker:19.03.8-dind` container and the Runner container don't share their
+- Since the `docker:19.03.11-dind` container and the Runner container don't share their
root filesystem, the job's working directory can be used as a mount point for
child containers. For example, if you have files you want to share with a
child container, you may create a subdirectory under `/builds/$CI_PROJECT_PATH`
and use it as your mount point (for a more thorough explanation, check [issue
- #41227](https://gitlab.com/gitlab-org/gitlab-foss/issues/41227)):
+ #41227](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41227)):
```yaml
variables:
@@ -139,7 +142,7 @@ not without its own challenges:
An example project using this approach can be found here: <https://gitlab.com/gitlab-examples/docker>.
In the examples below, we are using Docker images tags to specify a
-specific version, such as `docker:19.03.8`. If tags like `docker:stable`
+specific version, such as `docker:19.03.11`. If tags like `docker:stable`
are used, you have no control over what version is going to be used and this
can lead to unpredictable behavior, especially when new versions are
released.
@@ -151,12 +154,12 @@ Requires GitLab Runner 11.11 or later, but is not supported if GitLab
Runner is installed using the [Helm
chart](https://docs.gitlab.com/runner/install/kubernetes.html). See the
[related
-issue](https://gitlab.com/gitlab-org/charts/gitlab-runner/issues/83) for
+issue](https://gitlab.com/gitlab-org/charts/gitlab-runner/-/issues/83) for
details.
The Docker daemon supports connection over TLS and it's done by default
-for Docker 19.03.8 or higher. This is the **suggested** way to use the
-docker-in-docker service and
+for Docker 19.03.11 or higher. This is the **suggested** way to use the
+Docker-in-Docker service and
[GitLab.com Shared Runners](../../user/gitlab_com/index.md#shared-runners)
support this.
@@ -171,19 +174,19 @@ support this.
--registration-token REGISTRATION_TOKEN \
--executor docker \
--description "My Docker Runner" \
- --docker-image "docker:19.03.8" \
+ --docker-image "docker:19.03.11" \
--docker-privileged \
--docker-volumes "/certs/client"
```
The above command will register a new Runner to use the special
- `docker:19.03.8` image, which is provided by Docker. **Notice that it's
+ `docker:19.03.11` image, which is provided by Docker. **Notice that it's
using the `privileged` mode to start the build and service
- containers.** If you want to use [docker-in-docker](https://www.docker.com/blog/docker-can-now-run-within-docker/) mode, you always
+ containers.** If you want to use [Docker-in-Docker](https://www.docker.com/blog/docker-can-now-run-within-docker/) mode, you always
have to use `privileged = true` in your Docker containers.
This will also mount `/certs/client` for the service and build
- container, which is needed for the docker client to use the
+ container, which is needed for the Docker client to use the
certificates inside of that directory. For more information how
Docker with TLS works check <https://hub.docker.com/_/docker/#tls>.
@@ -196,7 +199,7 @@ support this.
executor = "docker"
[runners.docker]
tls_verify = false
- image = "docker:19.03.8"
+ image = "docker:19.03.11"
privileged = true
disable_cache = false
volumes = ["/certs/client", "/cache"]
@@ -206,10 +209,10 @@ support this.
```
1. You can now use `docker` in the build script (note the inclusion of the
- `docker:19.03.8-dind` service):
+ `docker:19.03.11-dind` service):
```yaml
- image: docker:19.03.8
+ image: docker:19.03.11
variables:
# When using dind service, we need to instruct docker, to talk with
@@ -234,7 +237,7 @@ support this.
DOCKER_TLS_CERTDIR: "/certs"
services:
- - docker:19.03.8-dind
+ - docker:19.03.11-dind
before_script:
- docker info
@@ -261,7 +264,7 @@ Assuming that the Runner `config.toml` is similar to:
executor = "docker"
[runners.docker]
tls_verify = false
- image = "docker:19.03.8"
+ image = "docker:19.03.11"
privileged = true
disable_cache = false
volumes = ["/cache"]
@@ -271,10 +274,10 @@ Assuming that the Runner `config.toml` is similar to:
```
You can now use `docker` in the build script (note the inclusion of the
-`docker:19.03.8-dind` service):
+`docker:19.03.11-dind` service):
```yaml
-image: docker:19.03.8
+image: docker:19.03.11
variables:
# When using dind service we need to instruct docker, to talk with the
@@ -295,7 +298,7 @@ variables:
DOCKER_TLS_CERTDIR: ""
services:
- - docker:19.03.8-dind
+ - docker:19.03.11-dind
before_script:
- docker info
@@ -315,7 +318,7 @@ container so that Docker is available in the context of that image.
NOTE: **Note:**
If you bind the Docker socket [when using GitLab Runner 11.11 or
newer](https://gitlab.com/gitlab-org/gitlab-runner/-/merge_requests/1261),
-you can no longer use `docker:19.03.8-dind` as a service because volume bindings
+you can no longer use `docker:19.03.11-dind` as a service because volume bindings
are done to the services as well, making these incompatible.
In order to do that, follow the steps:
@@ -330,12 +333,12 @@ In order to do that, follow the steps:
--registration-token REGISTRATION_TOKEN \
--executor docker \
--description "My Docker Runner" \
- --docker-image "docker:19.03.8" \
+ --docker-image "docker:19.03.11" \
--docker-volumes /var/run/docker.sock:/var/run/docker.sock
```
The above command will register a new Runner to use the special
- `docker:19.03.8` image which is provided by Docker. **Notice that it's using
+ `docker:19.03.11` image which is provided by Docker. **Notice that it's using
the Docker daemon of the Runner itself, and any containers spawned by Docker
commands will be siblings of the Runner rather than children of the Runner.**
This may have complications and limitations that are unsuitable for your workflow.
@@ -349,7 +352,7 @@ In order to do that, follow the steps:
executor = "docker"
[runners.docker]
tls_verify = false
- image = "docker:19.03.8"
+ image = "docker:19.03.11"
privileged = false
disable_cache = false
volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
@@ -358,11 +361,11 @@ In order to do that, follow the steps:
```
1. You can now use `docker` in the build script (note that you don't need to
- include the `docker:19.03.8-dind` service as when using the Docker in Docker
+ include the `docker:19.03.11-dind` service as when using the Docker in Docker
executor):
```yaml
- image: docker:19.03.8
+ image: docker:19.03.11
before_script:
- docker info
@@ -377,7 +380,7 @@ In order to do that, follow the steps:
While the above method avoids using Docker in privileged mode, you should be
aware of the following implications:
-- By sharing the docker daemon, you are effectively disabling all
+- By sharing the Docker daemon, you are effectively disabling all
the security mechanisms of containers and exposing your host to privilege
escalation which can lead to container breakout. For example, if a project
ran `docker rm -f $(docker ps -a -q)` it would remove the GitLab Runner
@@ -392,9 +395,9 @@ aware of the following implications:
docker run --rm -t -i -v $(pwd)/src:/home/app/src test-image:latest run_app_tests
```
-## Making docker-in-docker builds faster with Docker layer caching
+## Making Docker-in-Docker builds faster with Docker layer caching
-When using docker-in-docker, Docker will download all layers of your image every
+When using Docker-in-Docker, Docker will download all layers of your image every
time you create a build. Recent versions of Docker (Docker 1.13 and above) can
use a pre-existing image as a cache during the `docker build` step, considerably
speeding up the build process.
@@ -416,10 +419,10 @@ any image that's used with the `--cache-from` argument must first be pulled
Here's a `.gitlab-ci.yml` file showing how Docker caching can be used:
```yaml
-image: docker:19.03.8
+image: docker:19.03.11
services:
- - docker:19.03.8-dind
+ - docker:19.03.11-dind
variables:
# Use TLS https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled
@@ -514,7 +517,7 @@ Once you've built a Docker image, you can push it up to the built-in
## Troubleshooting
-### docker: Cannot connect to the Docker daemon at tcp://docker:2375. Is the docker daemon running?
+### `docker: Cannot connect to the Docker daemon at tcp://docker:2375. Is the docker daemon running?`
This is a common error when you are using
[Docker in Docker](#use-docker-in-docker-workflow-with-docker-executor)
diff --git a/doc/ci/docker/using_docker_images.md b/doc/ci/docker/using_docker_images.md
index 51139da2d16..2448bb536ab 100644
--- a/doc/ci/docker/using_docker_images.md
+++ b/doc/ci/docker/using_docker_images.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+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/#designated-technical-writers
type: concepts, howto
---
@@ -364,7 +367,7 @@ For example, the following two definitions are equal:
| `alias` | no | 9.4 |Additional alias that can be used to access the service from the job's container. Read [Accessing the services](#accessing-the-services) for more information. |
NOTE: **Note:**
-Alias support for the Kubernetes executor was [introduced](https://gitlab.com/gitlab-org/gitlab-runner/issues/2229) in GitLab Runner 12.8, and is only available for Kubernetes version 1.7 or later.
+Alias support for the Kubernetes executor was [introduced](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/2229) in GitLab Runner 12.8, and is only available for Kubernetes version 1.7 or later.
### Starting multiple services from the same image
@@ -543,7 +546,7 @@ runtime.
of credentials on runner's host. We recommend to upgrade your Runner to
at least version **1.8** if you want to use private registries.
- Not available for [Kubernetes executor](https://docs.gitlab.com/runner/executors/kubernetes.html),
- follow <https://gitlab.com/gitlab-org/gitlab-runner/issues/2673> for
+ follow <https://gitlab.com/gitlab-org/gitlab-runner/-/issues/2673> for
details.
### Using statically-defined credentials
@@ -591,7 +594,7 @@ There are two ways to determine the value of `DOCKER_AUTH_CONFIG`:
```
- **Second way -** In some setups, it's possible that Docker client
- will use the available system keystore to store the result of `docker
+ will use the available system key store to store the result of `docker
login`. In that case, it's impossible to read `~/.docker/config.json`,
so you will need to prepare the required base64-encoded version of
`${username}:${password}` and create the Docker configuration JSON manually.
@@ -709,7 +712,7 @@ To configure credentials store, follow these steps:
```
- Or, if you are running self-managed Runners, add the above JSON to
- `${GITLAB_RUNNER_HOME}/.docker/config.json`. GitLab Runner will read this config file
+ `${GITLAB_RUNNER_HOME}/.docker/config.json`. GitLab Runner will read this configuration file
and will use the needed helper for this specific repository.
NOTE: **Note:** `credsStore` is used to access ALL the registries.
@@ -727,6 +730,9 @@ To configure access for `aws_account_id.dkr.ecr.region.amazonaws.com`, follow th
1. Make sure `docker-credential-ecr-login` is available in GitLab Runner's `$PATH`.
+1. Have any of the following [AWS credentials setup](https://github.com/awslabs/amazon-ecr-credential-helper#aws-credentials).
+ Make sure that GitLab Runner can access the credentials.
+
1. Make GitLab Runner use it. There are two ways to accomplish this. Either:
- Create a [variable](../variables/README.md#gitlab-cicd-environment-variables)
@@ -741,9 +747,21 @@ To configure access for `aws_account_id.dkr.ecr.region.amazonaws.com`, follow th
}
```
+ This configures Docker to use the credential helper for a specific registry.
+
+ or
+
+ ```json
+ {
+ "credsStore": "ecr-login"
+ }
+ ```
+
+ This configures Docker to use the credential helper for all Amazon ECR registries.
+
- Or, if you are running self-managed Runners,
add the above JSON to `${GITLAB_RUNNER_HOME}/.docker/config.json`.
- GitLab Runner will read this config file and will use the needed helper for this
+ GitLab Runner will read this configuration file and will use the needed helper for this
specific repository.
1. You can now use any private image from `aws_account_id.dkr.ecr.region.amazonaws.com` defined in
diff --git a/doc/ci/docker/using_kaniko.md b/doc/ci/docker/using_kaniko.md
index 587f1f91f72..d53430400ec 100644
--- a/doc/ci/docker/using_kaniko.md
+++ b/doc/ci/docker/using_kaniko.md
@@ -1,21 +1,24 @@
---
+stage: Verify
+group: Continuous Integration
+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: howto
---
# Building images with kaniko and GitLab CI/CD
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/45512) in GitLab 11.2. Requires GitLab Runner 11.2 and above.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/45512) in GitLab 11.2. Requires GitLab Runner 11.2 and above.
[kaniko](https://github.com/GoogleContainerTools/kaniko) is a tool to build
container images from a Dockerfile, inside a container or Kubernetes cluster.
kaniko solves two problems with using the
-[docker-in-docker
+[Docker-in-Docker
build](using_docker_build.md#use-docker-in-docker-workflow-with-docker-executor) method:
-- Docker-in-docker requires [privileged mode](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities)
+- Docker-in-Docker requires [privileged mode](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities)
in order to function, which is a significant security concern.
-- Docker-in-docker generally incurs a performance penalty and can be quite slow.
+- Docker-in-Docker generally incurs a performance penalty and can be quite slow.
## Requirements
diff --git a/doc/ci/enable_or_disable_ci.md b/doc/ci/enable_or_disable_ci.md
index 12ed41e81ee..46cf76637a4 100644
--- a/doc/ci/enable_or_disable_ci.md
+++ b/doc/ci/enable_or_disable_ci.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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: howto
---
diff --git a/doc/ci/environments/deployment_safety.md b/doc/ci/environments/deployment_safety.md
new file mode 100644
index 00000000000..055baa78743
--- /dev/null
+++ b/doc/ci/environments/deployment_safety.md
@@ -0,0 +1,106 @@
+# Deployment safety
+
+Deployment jobs can be more sensitive than other jobs in a pipeline,
+and might need to be treated with extra care. GitLab has several features
+that help maintain deployment security and stability.
+
+You can:
+
+- [Restrict write-access to a critical environment](#restrict-write-access-to-a-critical-environment)
+- [Restrict deployments for a particular period](#restrict-deployments-for-a-particular-period)
+
+If you are using a continuous deployment workflow and want to ensure that concurrent deployments to the same environment do not happen, you should enable the following options:
+
+- [Ensure only one deployment job runs at a time](#ensure-only-one-deployment-job-runs-at-a-time)
+- [Skip outdated deployment jobs](#skip-outdated-deployment-jobs)
+
+## Restrict write access to a critical environment
+
+By default, environments can be modified by any team member that has [Developer permission or higher](../../user/permissions.md#project-members-permissions).
+If you want to restrict write access to a critical environment (for example a `production` environment),
+you can set up [protected environments](protected_environments.md).
+
+## Ensure only one deployment job runs at a time
+
+Pipeline jobs in GitLab CI/CD run in parallel, so it's possible that two deployment
+jobs in two different pipelines attempt to deploy to the same environment at the same
+time. This is not desired behavior as deployments should happen sequentially.
+
+You can ensure only one deployment job runs at a time with the [`resource_group` keyword](../yaml/README.md#resource_group) keyword in your `.gitlab-ci.yml`.
+
+For example:
+
+```yaml
+deploy:
+ script: deploy-to-prod
+ resource_group: prod
+```
+
+Example of a problematic pipeline flow **before** using the resource group:
+
+1. `deploy` job in Pipeline-A starts running.
+1. `deploy` job in Pipeline-B starts running. *This is a concurrent deployment that could cause an unexpected result.*
+1. `deploy` job in Pipeline-A finished.
+1. `deploy` job in Pipeline-B finished.
+
+The improved pipeline flow **after** using the resource group:
+
+1. `deploy` job in Pipeline-A starts running.
+1. `deploy` job in Pipeline-B attempts to start, but waits for the first `deploy` job to finish.
+1. `deploy` job in Pipeline-A finishes.
+1. `deploy` job in Pipeline-B starts running.
+
+For more information, see [`resource_group` keyword in `.gitlab-ci.yml`](../yaml/README.md#resource_group).
+
+## Skip outdated deployment jobs
+
+The execution order of pipeline jobs can vary from run to run, which could cause
+undesired behavior. For example, a deployment job in a newer pipeline could
+finish before a deployment job in an older pipeline.
+This creates a race condition where the older deployment finished later,
+overwriting the "newer" deployment.
+
+You can ensure that older deployment jobs are cancelled automatically when a newer deployment
+runs by enabling the [Skip outdated deployment jobs](../pipelines/settings.md#skip-outdated-deployment-jobs) feature.
+
+Example of a problematic pipeline flow **before** enabling Skip outdated deployment jobs:
+
+1. Pipeline-A is created on the master branch.
+1. Later, Pipeline-B is created on the master branch (with a newer commit SHA).
+1. The `deploy` job in Pipeline-B finishes first, and deploys the newer code.
+1. The `deploy` job in Pipeline-A finished later, and deploys the older code, **overwriting** the newer (latest) deployment.
+
+The improved pipeline flow **after** enabling Skip outdated deployment jobs:
+
+1. Pipeline-A is created on the `master` branch.
+1. Later, Pipeline-B is created on the `master` branch (with a newer SHA).
+1. The `deploy` job in Pipeline-B finishes first, and deploys the newer code.
+1. The `deploy` job in Pipeline-A is automatically cancelled, so that it doesn't overwrite the deployment from the newer pipeline.
+
+## Restrict deployments for a particular period
+
+If you want to prevent deployments for a particular period, for example during a planned
+vacation period when most employees are out, you can set up a [Deploy Freeze](../../user/project/releases/index.md#set-a-deploy-freeze).
+During a deploy freeze period, no deployment can be executed. This is helpful to
+ensure that deployments do not happen unexpectedly.
+
+## Troubleshooting
+
+### Pipelines jobs fail with `The deployment job is older than the previously succeeded deployment job...`
+
+This is caused by the [Skip outdated deployment jobs](../pipelines/settings.md#skip-outdated-deployment-jobs) feature.
+If you have multiple jobs for the same environment (including non-deployment jobs), you might encounter this problem, for example:
+
+```yaml
+build:service-a:
+ environment:
+ name: production
+
+build:service-b:
+ environment:
+ name: production
+```
+
+The [Skip outdated deployment jobs](../pipelines/settings.md#skip-outdated-deployment-jobs) might not work well with this configuration, and will need to be disabled.
+
+There is a [plan to introduce a new annotation for environments](https://gitlab.com/gitlab-org/gitlab/-/issues/208655) to address this issue.
diff --git a/doc/ci/environments/environments_dashboard.md b/doc/ci/environments/environments_dashboard.md
index 4a72c0d6d62..e920e0d2400 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 Premium](https://about.gitlab.com/pricing/) 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 016a6ac7cad..5da5c8e0a87 100644
--- a/doc/ci/environments/incremental_rollouts.md
+++ b/doc/ci/environments/incremental_rollouts.md
@@ -1,4 +1,7 @@
---
+stage: Release
+group: Progressive Delivery
+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: concepts, howto
---
@@ -34,7 +37,7 @@ use as examples to build your own:
## Manual Rollouts
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/5415) in GitLab 10.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5415) in GitLab 10.8.
It is possible to configure GitLab to do incremental rollouts manually through `.gitlab-ci.yml`. Manual configuration
allows more control over the this feature. The steps in an incremental rollout depend on the
@@ -74,7 +77,7 @@ available, demonstrating manually triggered incremental rollouts.
## Timed Rollouts
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/7545) in GitLab 11.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7545) in GitLab 11.4.
Timed rollouts behave in the same way as manual rollouts, except that each job is defined with a delay
in minutes before it will deploy. Clicking on the job will reveal the countdown.
@@ -111,3 +114,26 @@ timed rollout 30%:
A [deployable application](https://gitlab.com/gl-release/timed-rollout-example) is
available, [demonstrating configuration of timed rollouts](https://gitlab.com/gl-release/timed-rollout-example/blob/master/.gitlab-ci.yml#L86-95).
+
+## Blue-Green Deployment
+
+Also sometimes known as A/B deployment or red-black deployment, this technique is used to reduce
+downtime and risk during a deployment. When combined with incremental rollouts, you can
+minimize the impact of a deployment causing an issue.
+
+With this technique there are two deployments ("blue" and "green", but any naming can be used).
+Only one of these deployments is live at any given time, except during an incremental rollout.
+
+For example, your blue deployment can be currently active on production, while the
+green deployment is "live" for testing, but not deployed to production. If issues
+are found, the green deployment can be updated without affecting the production
+deployment (currently blue). If testing finds no issues, you switch production to the green
+deployment, and blue is now available to test the next release.
+
+This process reduces downtime as there is no need to take down the production deployment
+to switch to a different deployment. Both deployments are running in parallel, and
+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)
+that demonstrates blue-green deployments.
diff --git a/doc/ci/environments/index.md b/doc/ci/environments/index.md
index b6ec30b5571..84480b836f8 100644
--- a/doc/ci/environments/index.md
+++ b/doc/ci/environments/index.md
@@ -162,7 +162,7 @@ Starting with GitLab 9.3, the environment URL is exposed to the Runner via
#### Set dynamic environment URLs after a job finishes
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/17066) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/17066) in GitLab 12.9.
In a job script, you can specify a static [environment URL](#using-the-environment-url).
However, there may be times when you want a dynamic URL. For example,
@@ -384,7 +384,7 @@ feature.
### Configuring Kubernetes deployments
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/27630) in GitLab 12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27630) in GitLab 12.6.
If you are deploying to a [Kubernetes cluster](../../user/project/clusters/index.md)
associated with your project, you can configure these deployments from your
@@ -421,7 +421,18 @@ NOTE: **Note:**
Kubernetes configuration is not supported for Kubernetes clusters
that are [managed by GitLab](../../user/project/clusters/index.md#gitlab-managed-clusters).
To follow progress on support for GitLab-managed clusters, see the
-[relevant issue](https://gitlab.com/gitlab-org/gitlab/issues/38054).
+[relevant issue](https://gitlab.com/gitlab-org/gitlab/-/issues/38054).
+
+### Deployment safety
+
+Deployment jobs can be more sensitive than other jobs in a pipeline,
+and might need to be treated with an extra care. There are multiple features
+in GitLab that helps maintain deployment security and stability.
+
+- [Restrict write-access to a critical environment](deployment_safety.md#restrict-write-access-to-a-critical-environment)
+- [Limit the job-concurrency for deployment jobs](deployment_safety.md#ensure-only-one-deployment-job-runs-at-a-time)
+- [Skip outdated deployment jobs](deployment_safety.md#skip-outdated-deployment-jobs)
+- [Restrict deployments for a particular period](deployment_safety.md#restrict-deployments-for-a-particular-period)
### Complete example
@@ -699,11 +710,17 @@ stop action when the associated branch is deleted. The `stop_review` job must
be in the same `stage` as the `deploy_review` job in order for the environment
to automatically stop.
+Additionally, both jobs should have matching [`rules`](../yaml/README.md#onlyexcept-basic)
+or [`only/except`](../yaml/README.md#onlyexcept-basic) configuration. In the example
+above, if the configuration is not identical, the `stop_review` job might not be
+included in all pipelines that include the `deploy_review` job, and it will not be
+possible to trigger the `action: stop` to stop the environment automatically.
+
You can read more in the [`.gitlab-ci.yml` reference](../yaml/README.md#environmenton_stop).
#### Environments auto-stop
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/20956) in GitLab 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/20956) in GitLab 12.8.
You can set a expiry time to environments and stop them automatically after a certain period.
@@ -849,10 +866,6 @@ versions of the app, all without leaving GitLab.
![Monitoring dashboard](../img/environments_monitoring.png)
-#### Linking to external dashboard
-
-Add a [button to the Monitoring dashboard](../../user/project/operations/linking_to_an_external_dashboard.md) linking directly to your existing external dashboards.
-
#### Embedding metrics in GitLab Flavored Markdown
Metric charts can be embedded within GitLab Flavored Markdown. See [Embedding Metrics within GitLab Flavored Markdown](../../user/project/integrations/prometheus.md#embedding-metric-charts-within-gitlab-flavored-markdown) for more details.
@@ -912,7 +925,7 @@ fetch = +refs/environments/*:refs/remotes/origin/environments/*
### Scoping environments with specs
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/2112) in [GitLab Premium](https://about.gitlab.com/pricing/) 9.4.
-> - [Scoping for environment variables was moved to Core](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30779) to Core in GitLab 12.2.
+> - [Scoping for environment variables was moved to Core](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30779) in GitLab 12.2.
You can limit the environment scope of a variable by
defining which environments it can be available for.
diff --git a/doc/ci/environments/protected_environments.md b/doc/ci/environments/protected_environments.md
index 43ac42ea0c7..3a44fcfb182 100644
--- a/doc/ci/environments/protected_environments.md
+++ b/doc/ci/environments/protected_environments.md
@@ -55,6 +55,8 @@ Maintainers can:
**Allowed to Deploy** dropdown menu.
- Unprotect a protected environment by clicking the **Unprotect** button for that environment.
+For more information, see [Deployment safety](deployment_safety.md).
+
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
diff --git a/doc/ci/examples/README.md b/doc/ci/examples/README.md
index 1b3c4c887f4..c54e4b96332 100644
--- a/doc/ci/examples/README.md
+++ b/doc/ci/examples/README.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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
comments: false
type: index
---
@@ -10,9 +13,8 @@ implement [GitLab CI/CD](../README.md) for your specific use case.
Examples are available in several forms. As a collection of:
-- `.gitlab-ci.yml` [template files](https://gitlab.com/gitlab-org/gitlab-foss/tree/master/lib/gitlab/ci/templates) maintained in GitLab. When you create a new file via the UI,
- GitLab will give you the option to choose one of these templates. This will allow you to start using CI/CD with your project quickly.
- If your favorite programming language or framework are missing, we would love your help by sending a merge request with a new `.gitlab-ci.yml` to this project.
+- `.gitlab-ci.yml` [template files](#cicd-templates) maintained in GitLab, for many
+ common frameworks and programming languages.
- Repositories with [example projects](https://gitlab.com/gitlab-examples) for various languages. You can fork and adjust them to your own needs. Projects include demonstrations of [multi-project pipelines](https://gitlab.com/gitlab-examples/multi-project-pipelines) and using [Review Apps with a static site served by NGINX](https://gitlab.com/gitlab-examples/review-apps-nginx/).
- Examples and [other resources](#other-resources) listed below.
@@ -47,9 +49,55 @@ language users and GitLab by sending a merge request with a guide for that langu
You may want to apply for the [GitLab Community Writers Program](https://about.gitlab.com/community/writers/)
to get paid for writing complete articles for GitLab.
-## Adding templates to your GitLab installation **(PREMIUM ONLY)**
-
-If you want to have customized examples and templates for your own self-managed GitLab instance available to your team, your GitLab administrator can [designate an instance template repository](../../user/admin_area/settings/instance_template_repository.md) that contains examples and templates specific to your enterprise.
+## CI/CD templates
+
+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
+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)
+- [Android with fastlane (`Android-Fastlane.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Android-Fastlane.gitlab-ci.yml)
+- [Bash (`Bash.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Bash.gitlab-ci.yml)
+- [C++ (`C++.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/C++.gitlab-ci.yml)
+- [Chef (`Chef.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Chef.gitlab-ci.yml)
+- [Clojure (`Clojure.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Clojure.gitlab-ci.yml)
+- [Crystal (`Crystal.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Crystal.gitlab-ci.yml)
+- [Django (`Django.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Django.gitlab-ci.yml)
+- [Docker (`Docker.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Docker.gitlab-ci.yml)
+- [dotNET (`dotNET.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/dotNET.gitlab-ci.yml)
+- [dotNET Core (`dotNET-Core.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/dotNET-Core.yml)
+- [Elixir (`Elixir.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Elixir.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)
+- [Julia (`Julia.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Julia.gitlab-ci.yml)
+- [Laravel (`Laravel.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Laravel.gitlab-ci.yml)
+- [LaTeX (`LaTeX.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/LaTeX.gitlab-ci.yml)
+- [Maven (`Maven.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Maven.gitlab-ci.yml)
+- [Mono (`Mono.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Mono.gitlab-ci.yml)
+- [Node.js (`Nodejs.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml)
+- [OpenShift (`OpenShift.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/OpenShift.gitlab-ci.yml)
+- [Packer (`Packer.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Packer.gitlab-ci.yml)
+- [PHP (`PHP.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/PHP.gitlab-ci.yml)
+- [Python (`Python.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Python.gitlab-ci.yml)
+- [Ruby (`Ruby.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml)
+- [Rust (`Rust.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Rust.gitlab-ci.yml)
+- [Scala (`Scala.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Scala.gitlab-ci.yml)
+- [Swift (`Swift.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Swift.gitlab-ci.yml)
+- [Terraform (`Terraform.gitlab-ci.yml`)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Terraform.gitlab-ci.yml)
+
+If a programming language or framework template is not in this list, you can contribute
+one. To create a template, submit a merge request
+to <https://gitlab.com/gitlab-org/gitlab/tree/master/lib/gitlab/ci/templates>.
+
+### Adding templates to your GitLab installation **(PREMIUM ONLY)**
+
+You can add custom examples and templates to your self-managed GitLab instance.
+Your GitLab administrator can [designate an instance template repository](../../user/admin_area/settings/instance_template_repository.md)
+that contains examples and templates specific to your organization.
## Other resources
diff --git a/doc/ci/examples/artifactory_and_gitlab/index.md b/doc/ci/examples/artifactory_and_gitlab/index.md
index 85dcc199e2b..c1b3ddec1b9 100644
--- a/doc/ci/examples/artifactory_and_gitlab/index.md
+++ b/doc/ci/examples/artifactory_and_gitlab/index.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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
disqus_identifier: 'https://docs.gitlab.com/ee/articles/artifactory_and_gitlab/index.html'
author: Fabio Busatto
author_gitlab: bikebilly
@@ -106,7 +109,7 @@ parameter in `.gitlab-ci.yml` to use the custom location instead of the default
Now it's time we set up [GitLab CI/CD](https://about.gitlab.com/stages-devops-lifecycle/continuous-integration/) to automatically build, test and deploy the dependency!
-GitLab CI/CD uses a file in the root of the repo, named `.gitlab-ci.yml`, to read the definitions for jobs
+GitLab CI/CD uses a file in the root of the repository, named `.gitlab-ci.yml`, to read the definitions for jobs
that will be executed by the configured GitLab Runners. You can read more about this file in the [GitLab Documentation](../../yaml/README.md).
First of all, remember to set up variables for your deployment. Navigate to your project's **Settings > CI/CD > Environment variables** page
@@ -116,7 +119,7 @@ and add the following ones (replace them with your current values, of course):
- **MAVEN_REPO_USER**: `gitlab` (your Artifactory username)
- **MAVEN_REPO_PASS**: `AKCp2WXr3G61Xjz1PLmYa3arm3yfBozPxSta4taP3SeNu2HPXYa7FhNYosnndFNNgoEds8BCS` (your Artifactory Encrypted Password)
-Now it's time to define jobs in `.gitlab-ci.yml` and push it to the repo:
+Now it's time to define jobs in `.gitlab-ci.yml` and push it to the repository:
```yaml
image: maven:latest
@@ -151,7 +154,7 @@ deploy:
GitLab Runner will use the latest [Maven Docker image](https://hub.docker.com/_/maven/), which already contains all the tools and the dependencies you need to manage the project,
in order to run the jobs.
-Environment variables are set to instruct Maven to use the `homedir` of the repo instead of the user's home when searching for configuration and dependencies.
+Environment variables are set to instruct Maven to use the `homedir` of the repository instead of the user's home when searching for configuration and dependencies.
Caching the `.m2/repository folder` (where all the Maven files are stored), and the `target` folder (where our application will be created), is useful for speeding up the process
by running all Maven phases in a sequential order, therefore, executing `mvn test` will automatically run `mvn compile` if necessary.
@@ -161,7 +164,7 @@ Both `build` and `test` jobs leverage the `mvn` command to compile the applicati
Deploy to Artifactory is done as defined by the variables we have just set up.
The deployment occurs only if we're pushing or merging to `master` branch, so that the development versions are tested but not published.
-Done! Now you have all the changes in the GitLab repo, and a pipeline has already been started for this commit. In the **Pipelines** tab you can see what's happening.
+Done! Now you have all the changes in the GitLab repository, and a pipeline has already been started for this commit. In the **Pipelines** tab you can see what's happening.
If the deployment has been successful, the deploy job log will output:
```plaintext
@@ -174,7 +177,7 @@ If the deployment has been successful, the deploy job log will output:
>**Note**:
the `mvn` command downloads a lot of files from the internet, so you'll see a lot of extra activity in the log the first time you run it.
-Yay! You did it! Checking in Artifactory will confirm that you have a new artifact available in the `libs-release-local` repo.
+Yay! You did it! Checking in Artifactory will confirm that you have a new artifact available in the `libs-release-local` repository.
## Create the main Maven application
@@ -225,7 +228,7 @@ Here is how you can get the content of the file directly from Artifactory:
1. Click on **Generate Maven Settings**
1. Click on **Generate Settings**
1. Copy to clipboard the configuration file
-1. Save the file as `.m2/settings.xml` in your repo
+1. Save the file as `.m2/settings.xml` in your repository
Now you are ready to use the Artifactory repository to resolve dependencies and use `simple-maven-dep` in your main application!
@@ -236,7 +239,7 @@ You need a last step to have everything in place: configure the `.gitlab-ci.yml`
You want to leverage [GitLab CI/CD](https://about.gitlab.com/stages-devops-lifecycle/continuous-integration/) to automatically build, test and run your awesome application,
and see if you can get the greeting as expected!
-All you need to do is to add the following `.gitlab-ci.yml` to the repo:
+All you need to do is to add the following `.gitlab-ci.yml` to the repository:
```yaml
image: maven:latest
diff --git a/doc/ci/examples/authenticating-with-hashicorp-vault/index.md b/doc/ci/examples/authenticating-with-hashicorp-vault/index.md
index 089babc8945..3b8be54ae59 100644
--- a/doc/ci/examples/authenticating-with-hashicorp-vault/index.md
+++ b/doc/ci/examples/authenticating-with-hashicorp-vault/index.md
@@ -1,4 +1,7 @@
---
+stage: Release
+group: Release 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/#designated-technical-writers
type: tutorial
---
diff --git a/doc/ci/examples/deploy_spring_boot_to_cloud_foundry/index.md b/doc/ci/examples/deploy_spring_boot_to_cloud_foundry/index.md
index 49f4a14c5ac..87cee1820bc 100644
--- a/doc/ci/examples/deploy_spring_boot_to_cloud_foundry/index.md
+++ b/doc/ci/examples/deploy_spring_boot_to_cloud_foundry/index.md
@@ -1,4 +1,7 @@
---
+stage: Release
+group: Progressive Delivery
+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
author: Dylan Griffith
author_gitlab: DylanGriffith
level: intermediate
@@ -100,7 +103,7 @@ production:
- master
```
-We've used the `java:8` [docker
+We've used the `java:8` [Docker
image](../../docker/using_docker_images.md) to build
our application as it provides the up-to-date Java 8 JDK on [Docker
Hub](https://hub.docker.com/). We've also added the [`only`
diff --git a/doc/ci/examples/deployment/README.md b/doc/ci/examples/deployment/README.md
index 2ed1a99e0d9..ec02fb6dd43 100644
--- a/doc/ci/examples/deployment/README.md
+++ b/doc/ci/examples/deployment/README.md
@@ -1,4 +1,7 @@
---
+stage: Release
+group: Progressive Delivery
+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: tutorial
---
@@ -53,7 +56,7 @@ To use different provider take a look at long list of [Supported Providers](http
## Using Dpl with Docker
In most cases, you will have configured [GitLab Runner](https://docs.gitlab.com/runner/) to use your server's shell commands.
-This means that all commands are run in the context of local user (e.g. gitlab_runner or gitlab_ci_multi_runner).
+This means that all commands are run in the context of local user (e.g. `gitlab_runner` or `gitlab_ci_multi_runner`).
It also means that most probably in your Docker container you don't have the Ruby runtime installed.
You will have to install it:
diff --git a/doc/ci/examples/deployment/composer-npm-deploy.md b/doc/ci/examples/deployment/composer-npm-deploy.md
index c5f49fd6e59..cea6f26181f 100644
--- a/doc/ci/examples/deployment/composer-npm-deploy.md
+++ b/doc/ci/examples/deployment/composer-npm-deploy.md
@@ -1,4 +1,7 @@
---
+stage: Release
+group: Progressive Delivery
+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: tutorial
---
@@ -44,7 +47,7 @@ All these operations will put all files into a `build` folder, which is ready to
## How to transfer files to a live server
-You have multiple options: rsync, scp, sftp, and so on. For now, we will use scp.
+You have multiple options: rsync, SCP, SFTP, and so on. For now, we will use SCP.
To make this work, you need to add a GitLab CI/CD Variable (accessible on `gitlab.example/your-project-name/variables`). That variable will be called `STAGING_PRIVATE_KEY` and it's the **private** SSH key of your server.
@@ -74,7 +77,7 @@ And this is basically all you need in the `before_script` section.
## How to deploy
-As we stated above, we need to deploy the `build` folder from the docker image to our server. To do so, we create a new job:
+As we stated above, we need to deploy the `build` folder from the Docker image to our server. To do so, we create a new job:
```yaml
stage_deploy:
@@ -94,7 +97,7 @@ stage_deploy:
Here's the breakdown:
1. `only:dev` means that this build will run only when something is pushed to the `dev` branch. You can remove this block completely and have everything be ran on every push (but probably this is something you don't want)
-1. `ssh-add ...` we will add that private key you added on the web UI to the docker container
+1. `ssh-add ...` we will add that private key you added on the web UI to the Docker container
1. We will connect via `ssh` and create a new `_tmp` folder
1. We will connect via `scp` and upload the `build` folder (which was generated by a `npm` script) to our previously created `_tmp` folder
1. We will connect again via `ssh` and move the `live` folder to an `_old` folder, then move `_tmp` to `live`.
@@ -120,7 +123,7 @@ Therefore, for a production environment we use additional steps to ensure that a
Since this was a WordPress project, I gave real life code snippets. Some further ideas you can pursue:
- Having a slightly different script for `master` branch will allow you to deploy to a production server from that branch and to a stage server from any other branches.
-- Instead of pushing it live, you can push it to WordPress official repo (with creating a SVN commit, etc.).
+- Instead of pushing it live, you can push it to WordPress official repository (with creating a SVN commit, etc.).
- You could generate i18n text domains on the fly.
---
diff --git a/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/index.md b/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/index.md
index 610220a6bff..51d9f169939 100644
--- a/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/index.md
+++ b/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/index.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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
author: Ryan Hall
author_gitlab: blitzgren
level: intermediate
@@ -353,7 +356,7 @@ test:
### Run your CI/CD pipeline
-That's it! Add all your new files, commit, and push. For a reference of what our repo should
+That's it! Add all your new files, commit, and push. For a reference of what our repository should
look like at this point, please refer to the [final commit related to this article on my sample repository](https://gitlab.com/blitzgren/gitlab-game-demo/commit/8b36ef0ecebcf569aeb251be4ee13743337fcfe2).
By applying both build and test stages, GitLab will run them sequentially at every push to
our repository. If all goes well you'll end up with a green check mark on each job for the pipeline:
@@ -419,15 +422,15 @@ fully understand [IAM Best Practices in AWS](https://docs.aws.amazon.com/IAM/lat
1. Log into your AWS account and go to the [Security Credentials page](https://console.aws.amazon.com/iam/home#/security_credential)
1. Click the **Access Keys** section and **Create New Access Key**. Create the key and keep the ID and secret around, you'll need them later
- ![AWS Access Key Config](img/aws_config_window.png)
+ ![AWS Access Key Configuration](img/aws_config_window.png)
1. Go to your GitLab project, click **Settings > CI/CD** on the left sidebar
1. Expand the **Variables** section
![GitLab Secret Config](img/gitlab_config.png)
-1. Add a key named `AWS_KEY_ID` and copy the key ID from Step 2 into the **Value** textbox
-1. Add a key named `AWS_KEY_SECRET` and copy the key secret from Step 2 into the **Value** textbox
+1. Add a key named `AWS_KEY_ID` and copy the key ID from Step 2 into the **Value** field
+1. Add a key named `AWS_KEY_SECRET` and copy the key secret from Step 2 into the **Value** field
### Deploy your game with GitLab CI/CD
@@ -526,7 +529,7 @@ a lot of breathing room in quickly getting changes to players.
Here are some ideas to further investigate that can speed up or improve your pipeline:
- [Yarn](https://yarnpkg.com) instead of npm
-- Set up a custom [Docker](../../../ci/docker/using_docker_images.md#define-image-and-services-from-gitlab-ciyml) image that can preload dependencies and tools (like AWS CLI)
+- Set up a custom [Docker](../../../ci/docker/using_docker_images.md#define-image-and-services-from-gitlab-ciyml) image that can pre-load dependencies and tools (like AWS CLI)
- Forward a [custom domain](https://docs.aws.amazon.com/AmazonS3/latest/dev/website-hosting-custom-domain-walkthrough.html) to your game's S3 static website
- Combine jobs if you find it unnecessary for a small project
- Avoid the queues and set up your own [custom GitLab CI/CD runner](https://about.gitlab.com/blog/2016/03/01/gitlab-runner-with-docker/)
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 8491881570c..05b3cc257e3 100644
--- a/doc/ci/examples/end_to_end_testing_webdriverio/index.md
+++ b/doc/ci/examples/end_to_end_testing_webdriverio/index.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+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/#designated-technical-writers
author: Vincent Tunru
author_gitlab: Vinnl
level: advanced
diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md b/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
index 0331fa70f06..5b442436baf 100644
--- a/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
+++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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
disqus_identifier: 'https://docs.gitlab.com/ee/articles/laravel_with_gitlab_and_envoy/index.html'
author: Mehran Rasulian
author_gitlab: mehranrasulian
@@ -29,7 +32,7 @@ It uses a clean, minimal [Blade syntax](https://laravel.com/docs/master/blade) t
## Initialize our Laravel app on GitLab
-We assume [you have installed a new laravel project](https://laravel.com/docs/master/installation#installation), so let's start with a unit test, and initialize Git for the project.
+We assume [you have installed a new Laravel project](https://laravel.com/docs/master/installation#installation), so let's start with a unit test, and initialize Git for the project.
### Unit Test
@@ -664,7 +667,7 @@ If something doesn't work as expected, you can roll back to the latest working v
By clicking on the external link icon specified on the right side, GitLab opens the production website.
Our deployment successfully was done and we can see the application is live.
-![laravel welcome page](img/laravel_welcome_page.png)
+![Laravel welcome page](img/laravel_welcome_page.png)
In the case that you're interested to know how is the application directory structure on the production server after deployment, here are three directories named `current`, `releases` and `storage`.
As you know, the `current` directory is a symbolic link that points to the latest release.
diff --git a/doc/ci/examples/php.md b/doc/ci/examples/php.md
index 6a6c0e8fde1..e7768868c15 100644
--- a/doc/ci/examples/php.md
+++ b/doc/ci/examples/php.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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: tutorial
---
@@ -13,7 +16,7 @@ using the Shell executor.
While it is possible to test PHP apps on any system, this would require manual
configuration from the developer. To overcome this we will be using the
-official [PHP docker image](https://hub.docker.com/_/php) that can be found in Docker Hub.
+official [PHP Docker image](https://hub.docker.com/_/php) that can be found in Docker Hub.
This will allow us to test PHP projects against different versions of PHP.
However, not everything is plug 'n' play, you still need to configure some
@@ -62,7 +65,7 @@ docker-php-ext-install pdo_mysql
```
You might wonder what `docker-php-ext-install` is. In short, it is a script
-provided by the official php docker image that you can use to easily install
+provided by the official PHP Docker image that you can use to easily install
extensions. For more information read the documentation at
<https://hub.docker.com/_/php>.
@@ -111,7 +114,7 @@ test:app:
### Test against different PHP versions in Docker builds
Testing against multiple versions of PHP is super easy. Just add another job
-with a different docker image version and the runner will do the rest:
+with a different Docker image version and the runner will do the rest:
```yaml
before_script:
@@ -171,7 +174,7 @@ Finally, push to GitLab and let the tests begin!
### Test against different PHP versions in Shell builds
The [phpenv](https://github.com/phpenv/phpenv) project allows you to easily manage different versions of PHP
-each with its own config. This is especially useful when testing PHP projects
+each with its own configuration. This is especially useful when testing PHP projects
with the Shell executor.
You will have to install it on your build machine under the `gitlab-runner`
diff --git a/doc/ci/examples/test-and-deploy-python-application-to-heroku.md b/doc/ci/examples/test-and-deploy-python-application-to-heroku.md
index 2c626cb458a..30a64e65607 100644
--- a/doc/ci/examples/test-and-deploy-python-application-to-heroku.md
+++ b/doc/ci/examples/test-and-deploy-python-application-to-heroku.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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: tutorial
---
diff --git a/doc/ci/examples/test-and-deploy-ruby-application-to-heroku.md b/doc/ci/examples/test-and-deploy-ruby-application-to-heroku.md
index 5df407f19fe..bf589c5991d 100644
--- a/doc/ci/examples/test-and-deploy-ruby-application-to-heroku.md
+++ b/doc/ci/examples/test-and-deploy-ruby-application-to-heroku.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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: tutorial
---
diff --git a/doc/ci/examples/test-clojure-application.md b/doc/ci/examples/test-clojure-application.md
index 6ea38f22bca..31dacd34730 100644
--- a/doc/ci/examples/test-clojure-application.md
+++ b/doc/ci/examples/test-clojure-application.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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: tutorial
---
diff --git a/doc/ci/examples/test-scala-application.md b/doc/ci/examples/test-scala-application.md
index 1831417e48e..fec376915c9 100644
--- a/doc/ci/examples/test-scala-application.md
+++ b/doc/ci/examples/test-scala-application.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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: tutorial
---
diff --git a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/index.md b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/index.md
index cd1ad923249..c901f6c9c66 100644
--- a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/index.md
+++ b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/index.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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
author: Alexandre S Hostert
author_gitlab: Hostert
level: beginner
@@ -43,9 +46,9 @@ Phoenix can run in any OS where Erlang is supported:
- Debian
- Windows
- Fedora
-- Raspbian
+- Raspberry Pi OS
-Check the [Phoenix learning guide](https://hexdocs.pm/phoenix/learning.html) for more information.
+Check the [Phoenix learning guide](https://hexdocs.pm/phoenix/overview.html) for more information.
### What is Elixir?
@@ -151,7 +154,7 @@ point `localhost` to `127.0.0.1`.
Great, now we have a local Phoenix Server running our app.
-Locally, our application is running in an `iex` session. [iex](https://elixir-lang.org/getting-started/introduction.html#interactive-mode) stands for Interactive Elixir.
+Locally, our application is running in an [`iex`](https://elixir-lang.org/getting-started/introduction.html#interactive-mode) session, which stands for Interactive Elixir.
In this interactive mode, we can type any Elixir expression and get its result. To exit `iex`, we
need to press `Ctrl+C` twice. So, when we need to stop the Phoenix server, we have to hit `Ctrl+C`
twice.
@@ -161,7 +164,7 @@ twice.
With GitLab, we can manage our development workflow, improve our productivity, track issues,
perform code review, and much more from a single platform. With GitLab CI/CD, we can be much more
productive, because every time we, or our co-workers push any code, GitLab CI/CD will build and
-test the changes, telling us in realtime if anything goes wrong.
+test the changes, telling us in real time if anything goes wrong.
Certainly, when our application starts to grow, we'll need more developers working on the same
project and this process of building and testing can easily become a mess without proper management.
@@ -262,7 +265,7 @@ project.
our application? This virtual machine must have all dependencies to run our application. This is
where a Docker image is needed. The correct image will provide the entire system for us.
- As we are focusing on testing (not deploying), you can use the [elixir:latest](https://hub.docker.com/_/elixir) docker image, which already has the
+ As we are focusing on testing (not deploying), you can use the [elixir:latest](https://hub.docker.com/_/elixir) Docker image, which already has the
dependencies for running Phoenix tests installed, such as Elixir and Erlang:
```yaml
diff --git a/doc/ci/git_submodules.md b/doc/ci/git_submodules.md
index 4797251129b..b12ac59625f 100644
--- a/doc/ci/git_submodules.md
+++ b/doc/ci/git_submodules.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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/interactive_web_terminal/index.md b/doc/ci/interactive_web_terminal/index.md
index 661e32b1571..be3741332e0 100644
--- a/doc/ci/interactive_web_terminal/index.md
+++ b/doc/ci/interactive_web_terminal/index.md
@@ -1,10 +1,13 @@
---
+stage: Verify
+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/#designated-technical-writers
type: reference
---
# Interactive Web Terminals
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/50144) in GitLab 11.3.
+> [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
@@ -31,7 +34,7 @@ Two things need to be configured for the interactive web terminal to work:
NOTE: **Note:**
Interactive web terminals are not yet supported by
[`gitlab-runner` Helm chart](https://docs.gitlab.com/charts/charts/gitlab/gitlab-runner/index.html),
-but support [is planned](https://gitlab.com/gitlab-org/charts/gitlab-runner/issues/79).
+but support [is planned](https://gitlab.com/gitlab-org/charts/gitlab-runner/-/issues/79).
## Debugging a running job
@@ -41,7 +44,7 @@ NOTE: **Note:** Not all executors are
NOTE: **Note:** The `docker` executor does not keep running
after the build script is finished. At that point, the terminal will automatically
disconnect and will not wait for the user to finish. Please follow [this
-issue](https://gitlab.com/gitlab-org/gitlab-runner/issues/3605) for updates on
+issue](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/3605) for updates on
improving this behavior.
Sometimes, when a job is running, things don't go as you would expect, and it
diff --git a/doc/ci/introduction/index.md b/doc/ci/introduction/index.md
index b7f1837d83e..7ba24f9c861 100644
--- a/doc/ci/introduction/index.md
+++ b/doc/ci/introduction/index.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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
description: "An overview of Continuous Integration, Continuous Delivery, and Continuous Deployment, as well as an introduction to GitLab CI/CD."
type: concepts
---
diff --git a/doc/ci/jenkins/index.md b/doc/ci/jenkins/index.md
index c4346005138..37e0522e74d 100644
--- a/doc/ci/jenkins/index.md
+++ b/doc/ci/jenkins/index.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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
comments: false
type: index, howto
---
@@ -72,13 +75,13 @@ There are some high level differences between the products worth mentioning:
with the [`rules` syntax](../yaml/README.md#rules).
- GitLab [pipeline scheduling concepts](../pipelines/schedules.md) are also different than with Jenkins.
- You can reuse pipeline configurations using the [`include` keyword](../yaml/README.md#include)
- and [templates](#templates). Your templates can be kept in a central repo (with different
+ and [templates](#templates). Your templates can be kept in a central repository (with different
permissions), and then any project can use them. This central project could also
contain scripts or other reusable code.
- You can also use the [`extends` keyword](../yaml/README.md#extends) to reuse configuration
within a single pipeline configuration.
- All jobs within a single stage always run in parallel, and all stages run in sequence. We are planning
- to allow certain jobs to break this sequencing as needed with our [directed acyclic graph](https://gitlab.com/gitlab-org/gitlab-foss/issues/47063)
+ to allow certain jobs to break this sequencing as needed with our [directed acyclic graph](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/47063)
feature.
- The [`parallel`](../yaml/README.md#parallel) keyword can automatically parallelize tasks,
like tests that support parallelization.
@@ -90,7 +93,7 @@ There are some high level differences between the products worth mentioning:
- One important difference is that jobs run independently of each other and have a
fresh environment in each job. Passing artifacts between jobs is controlled using the
[`artifacts`](../yaml/README.md#artifacts) and [`dependencies`](../yaml/README.md#dependencies)
- keywords. When finished, the planned [Workspaces](https://gitlab.com/gitlab-org/gitlab/issues/29265)
+ keywords. When finished, the planned [Workspaces](https://gitlab.com/gitlab-org/gitlab/-/issues/29265)
feature will allow you to more easily persist a common workspace between serial jobs.
- The `.gitlab-ci.yml` file is checked in to the root of your repository, much like a Jenkinsfile, but
is in the YAML format (see [complete reference](../yaml/README.md)) instead of a Groovy DSL. It's most
@@ -115,13 +118,13 @@ agents you were using.
There are some important differences in the way Runners work in comparison to agents:
-- Runners can be set up as [shared across an instance, be added at the group level, or set up at the project level](../runners/README.md#shared-specific-and-group-runners).
+- Runners can be set up as [shared across an instance, be added at the group level, or set up at the project level](../runners/README.md#types-of-runners).
They will self-select jobs from the scopes you've defined automatically.
-- You can also [use tags](../runners/README.md#using-tags) for finer control, and
+- You can also [use tags](../runners/README.md#use-tags-to-limit-the-number-of-jobs-using-the-runner) 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)
- which will let configure them to be provisioned as needed, and scaled down when not.
+ which will let you configure them to be provisioned as needed, and scaled down when not.
This is similar to ephemeral agents in Jenkins.
If you are using `gitlab.com`, you can take advantage of our [shared Runner fleet](../../user/gitlab_com/index.md#shared-runners)
@@ -136,7 +139,7 @@ GitLab works a bit differently, we use the more highly structured [YAML](https:/
places scripting elements inside of `script:` blocks separate from the pipeline specification itself.
This is a strength of GitLab, in that it helps keep the learning curve much simpler to get up and running
-and avoids some of the problem of unconstrained complexity which can make your Jenkinsfiles hard to understand
+and avoids some of the problem of unconstrained complexity which can make your Jenkinsfile hard to understand
and manage.
That said, we do of course still value DRY (don't repeat yourself) principles and want to ensure that
@@ -202,12 +205,12 @@ be used by all projects in the group. An instance administrator can set a group
the source for [instance project templates](../../user/group/custom_project_templates.md),
which can be used by projects in that instance.
-## Converting Declarative Jenkinsfiles
+## Converting a declarative Jenkinsfile
-Declarative Jenkinsfiles contain "Sections" and "Directives" which are used to control the behavior of your
+A declarative Jenkinsfile contains "Sections" and "Directives" which are used to control the behavior of your
pipelines. There are equivalents for all of these in GitLab, which we've documented below.
-This section is based on the [Jenkinsfile syntax documentation](https://jenkins.io/doc/book/pipeline/syntax/)
+This section is based on the [Jenkinsfile syntax documentation](https://www.jenkins.io/doc/book/pipeline/syntax/)
and is meant to be a mapping of concepts there to concepts in GitLab.
### Sections
@@ -217,7 +220,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 will be executed. For GitLab, we use the [GitLab Runner](../runners/README.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.) The link above will bring you to the documentation which will describe how to get
-up and running quickly. We also support using [tags](../runners/README.md#using-tags) to direct different jobs
+up and running quickly. We also support using [tags](../runners/README.md#use-tags-to-limit-the-number-of-jobs-using-the-runner) 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/junit_test_reports.md b/doc/ci/junit_test_reports.md
index a77044e849d..aa0d40a4d06 100644
--- a/doc/ci/junit_test_reports.md
+++ b/doc/ci/junit_test_reports.md
@@ -1,10 +1,13 @@
---
+stage: Verify
+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/#designated-technical-writers
type: reference
---
# JUnit test reports
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/45318) in GitLab 11.2. Requires GitLab Runner 11.2 and above.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/45318) in GitLab 11.2. Requires GitLab Runner 11.2 and above.
## Overview
@@ -189,6 +192,20 @@ cpp:
junit: report.xml
```
+#### CUnit
+
+[CUnit](https://cunity.gitlab.io/cunit/) can be made to produce [JUnit XML reports](https://cunity.gitlab.io/cunit/group__CI.html) automatically when run using its `CUnitCI.h` macros:
+
+```yaml
+cunit:
+ stage: test
+ script:
+ - ./my-cunit-test
+ artifacts:
+ reports:
+ junit: ./my-cunit-test.xml
+```
+
### .Net example
The [JunitXML.TestLogger](https://www.nuget.org/packages/JunitXml.TestLogger/) NuGet
@@ -215,17 +232,9 @@ Test:
- ./**/*test-result.xml
```
-## Limitations
-
-Currently, the following tools might not work because their XML formats are unsupported in GitLab.
-
-|Case|Tool|Issue|
-|---|---|---|
-|`<testcase>` does not have `classname` attribute|ESlint, sass-lint|<https://gitlab.com/gitlab-org/gitlab-foss/issues/50964>|
-
## Viewing JUnit test reports on GitLab
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/24792) in GitLab 12.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/24792) in GitLab 12.5.
If JUnit XML files are generated and uploaded as part of a pipeline, these reports
can be viewed inside the pipelines details page. The **Tests** tab on this page will
@@ -250,6 +259,9 @@ following command:
```ruby
Feature.enable(:junit_pipeline_view)
+
+# Enable the feature for a specific project
+Feature.enable(:junit_pipeline_view, Project.find(<your-project-id-here>))
```
## Viewing JUnit screenshots on GitLab
diff --git a/doc/ci/large_repositories/index.md b/doc/ci/large_repositories/index.md
index b4059fc252b..b4652050654 100644
--- a/doc/ci/large_repositories/index.md
+++ b/doc/ci/large_repositories/index.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+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/#designated-technical-writers
type: reference
---
@@ -114,6 +117,16 @@ For exact parameters accepted by
for [`git clean`](https://git-scm.com/docs/git-clean). The available parameters
are dependent on Git version.
+## Git fetch extra flags
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4142) in GitLab Runner 13.1.
+
+[`GIT_FETCH_EXTRA_FLAGS`](../yaml/README.md#git-fetch-extra-flags) allows you
+to modify `git fetch` behavior by passing extra flags.
+
+See the [`GIT_FETCH_EXTRA_FLAGS` documentation](../yaml/README.md#git-fetch-extra-flags)
+for more information.
+
## Fork-based workflow
> Introduced in GitLab Runner 11.10.
diff --git a/doc/ci/merge_request_pipelines/index.md b/doc/ci/merge_request_pipelines/index.md
index a724bf416b6..7a4ca989fb6 100644
--- a/doc/ci/merge_request_pipelines/index.md
+++ b/doc/ci/merge_request_pipelines/index.md
@@ -1,11 +1,14 @@
---
+stage: Verify
+group: Continuous Integration
+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, index
last_update: 2019-07-03
---
# Pipelines for Merge Requests
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/15310) in GitLab 11.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/15310) in GitLab 11.6.
In a [basic configuration](../pipelines/pipeline_architectures.md#basic-pipelines), GitLab runs a pipeline each time
changes are pushed to a branch.
@@ -143,7 +146,7 @@ test:
Instead, you can use the
[`$CI_COMMIT_REF_NAME` predefined environment
-variable](../variables/predefined_variables.md#variables-reference) in
+variable](../variables/predefined_variables.md) in
combination with
[`only:variables`](../yaml/README.md#onlyvariablesexceptvariables) to
accomplish this behavior:
diff --git a/doc/ci/merge_request_pipelines/pipelines_for_merged_results/index.md b/doc/ci/merge_request_pipelines/pipelines_for_merged_results/index.md
index c35a5d0a07e..a43085c8e7a 100644
--- a/doc/ci/merge_request_pipelines/pipelines_for_merged_results/index.md
+++ b/doc/ci/merge_request_pipelines/pipelines_for_merged_results/index.md
@@ -1,11 +1,14 @@
---
+stage: Verify
+group: Continuous Integration
+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
last_update: 2019-07-03
---
# Pipelines for Merged Results **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/7380) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.10.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7380) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.10.
When you submit a merge request, you are requesting to merge changes from a
source branch into a target branch. By default, the CI pipeline runs jobs
@@ -44,7 +47,7 @@ To enable pipelines for merge results:
- You must have maintainer [permissions](../../../user/permissions.md).
- You must be using [GitLab Runner](https://gitlab.com/gitlab-org/gitlab-runner) 11.9 or later.
- You must not be forking or using cross-repo workflows. To follow progress,
- see [#11934](https://gitlab.com/gitlab-org/gitlab/issues/11934).
+ see [#11934](https://gitlab.com/gitlab-org/gitlab/-/issues/11934).
- You must not be using
[fast forward merges](../../../user/project/merge_requests/fast_forward_merge.md) yet.
To follow progress, see [#58226](https://gitlab.com/gitlab-org/gitlab/-/issues/26996).
@@ -56,7 +59,7 @@ To enable pipelines for merged results for your project:
1. [Configure your CI/CD configuration file](../index.md#configuring-pipelines-for-merge-requests)
so that the pipeline or individual jobs run for merge requests.
1. Visit your project's **Settings > General** and expand **Merge requests**.
-1. Check **Merge pipelines will try to validate the post-merge result prior to merging**.
+1. Check **Enable merge trains and pipelines for merged results**.
1. Click **Save changes**.
CAUTION: **Caution:**
@@ -76,9 +79,9 @@ merge happens.
For more information, read the [documentation on Merge Trains](merge_trains/index.md).
-## Automatic pipeline cancelation
+## Automatic pipeline cancellation
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/12996) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12996) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.3.
GitLab CI/CD can detect the presence of redundant pipelines,
and will cancel them automatically in order to conserve CI resources.
diff --git a/doc/ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.md b/doc/ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.md
index d921b75aa44..fc8e6368d72 100644
--- a/doc/ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.md
+++ b/doc/ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.md
@@ -1,12 +1,15 @@
---
+stage: Verify
+group: Continuous Integration
+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
last_update: 2019-07-03
---
# Merge Trains **(PREMIUM)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/9186) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.0.
-> - [Squash and merge](../../../../user/project/merge_requests/squash_and_merge.md) support [introduced](https://gitlab.com/gitlab-org/gitlab/issues/13001) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.6.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9186) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.0.
+> - [Squash and merge](../../../../user/project/merge_requests/squash_and_merge.md) support [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13001) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.6.
When [pipelines for merged results](../index.md#pipelines-for-merged-results-premium) are
enabled, the pipeline jobs run as if the changes from your source branch have already
@@ -79,7 +82,7 @@ To enable merge trains for your project:
1. [Configure your CI/CD configuration file](../../index.md#configuring-pipelines-for-merge-requests)
so that the pipeline or individual jobs run for merge requests.
1. Visit your project's **Settings > General** and expand **Merge requests**.
-1. Check **Merge pipelines will try to validate the post-merge result prior to merging**.
+1. Check **Enable merge trains and pipelines for merged results**.
1. Click **Save changes**.
CAUTION: **Caution:**
@@ -164,7 +167,7 @@ To check the reason:
[Merge When Pipeline Succeeds](../../../../user/project/merge_requests/merge_when_pipeline_succeeds.md)
is currently unavailable when Merge Trains are enabled.
-See [the related issue](https://gitlab.com/gitlab-org/gitlab/issues/12267)
+See [the related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/12267)
for more information.
### Merge Train Pipeline cannot be retried
@@ -184,14 +187,14 @@ run a new successful pipeline before you can re-add a merge request to a merge t
Merge trains ensure that each pipeline has succeeded before a merge happens, so
you can clear the **Pipelines must succeed** check box and keep
-**Merge pipelines will try to validate the post-merge result prior to merging** (merge trains) enabled.
+**Enable merge trains and pipelines for merged results** (merge trains) enabled.
If you want to keep the **Pipelines must succeed** option enabled along with Merge
Trains, you can create a new pipeline for merged results when this error occurs by
going to the **Pipelines** tab and clicking **Run pipeline**. Then click
**Start/Add to merge train when pipeline succeeds**.
-See [the related issue](https://gitlab.com/gitlab-org/gitlab/issues/35135)
+See [the related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/35135)
for more information.
### Merge Trains feature flag **(PREMIUM ONLY)**
diff --git a/doc/ci/metrics_reports.md b/doc/ci/metrics_reports.md
index f353aa2670f..67f9ad00c90 100644
--- a/doc/ci/metrics_reports.md
+++ b/doc/ci/metrics_reports.md
@@ -1,14 +1,17 @@
---
+stage: Verify
+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/#designated-technical-writers
type: reference
---
# Metrics Reports **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/9788) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.10. Requires GitLab Runner 11.10 and above.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9788) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.10. Requires GitLab Runner 11.10 and above.
## Overview
-GitLab provides a lot of great reporting tools for [merge requests](../user/project/merge_requests/index.md) - [JUnit reports](junit_test_reports.md), [codequality](../user/project/merge_requests/code_quality.md), performance tests, etc. While JUnit is a great open framework for tests that "pass" or "fail", it is also important to see other types of metrics from a given change.
+GitLab provides a lot of great reporting tools for [merge requests](../user/project/merge_requests/index.md) - [JUnit reports](junit_test_reports.md), [code quality](../user/project/merge_requests/code_quality.md), performance tests, etc. While JUnit is a great open framework for tests that "pass" or "fail", it is also important to see other types of metrics from a given change.
You can configure your job to use custom Metrics Reports, and GitLab will display a report on the merge request so that it's easier and faster to identify changes without having to check the entire log.
diff --git a/doc/ci/migration/circleci.md b/doc/ci/migration/circleci.md
new file mode 100644
index 00000000000..f6868abc334
--- /dev/null
+++ b/doc/ci/migration/circleci.md
@@ -0,0 +1,332 @@
+---
+comments: false
+type: index, howto
+---
+
+# Migrating from CircleCI
+
+If you are currently using CircleCI, you can migrate your CI/CD pipelines to [GitLab CI/CD](../introduction/index.md),
+and start making use of all its powerful features. Check out our
+[CircleCI vs GitLab](https://about.gitlab.com/devops-tools/circle-ci-vs-gitlab.html)
+comparison to see what's different.
+
+We have collected several resources that you may find useful before starting to migrate.
+
+The [Quick Start Guide](../quick_start/README.md) is a good overview of how GitLab CI/CD works. You may also be interested in [Auto DevOps](../../topics/autodevops/index.md) which can be used to build, test, and deploy your applications with little to no configuration needed at all.
+
+For advanced CI/CD teams, [custom project templates](../../user/admin_area/custom_project_templates.md) can enable the reuse of pipeline configurations.
+
+If you have questions that are not answered here, the [GitLab community forum](https://forum.gitlab.com/) can be a great resource.
+
+## `config.yml` vs `gitlab-ci.yml`
+
+CircleCI's `config.yml` configuration file defines scripts, jobs, and workflows (known as "stages" in GitLab). In GitLab, a similar approach is used with a `.gitlab-ci.yml` file in the root directory of your repository.
+
+### Jobs
+
+In CircleCI, jobs are a collection of steps to perform a specific task. In GitLab, [jobs](../yaml/README.md#introduction) are also a fundamental element in the configuration file. The `checkout` parameter is not necessary in GitLab CI/CD as the repository is automatically fetched.
+
+CircleCI example job definition:
+
+```yaml
+jobs:
+ job1:
+ steps:
+ - checkout
+ - run: "execute-script-for-job1"
+```
+
+Example of the same job definition in GitLab CI/CD:
+
+``` yaml
+job1:
+ script: "execute-script-for-job1"
+```
+
+### Docker image definition
+
+CircleCI defines images at the job level, which is also supported by GitLab CI/CD. Additionally, GitLab CI/CD supports setting this globally to be used by all jobs that don't have `image` defined.
+
+CircleCI example image definition:
+
+```yaml
+jobs:
+ job1:
+ docker:
+ - image: ruby:2.6
+```
+
+Example of the same image definition in GitLab CI/CD:
+
+```yaml
+job1:
+ image: ruby:2.6
+```
+
+### Workflows
+
+CircleCI determines the run order for jobs with `workflows`. This is also used to determine concurrent, sequential, scheduled, or manual runs. The equivalent function in GitLab CI/CD is called [stages](../yaml/README.md#stages). Jobs on the same stage run in parallel, and only run after previous stages complete. Execution of the next stage is skipped when a job fails by default, but this can be allowed to continue even [after a failed job](../yaml/README.md#allow_failure).
+
+See [the Pipeline Architecture Overview](../pipelines/pipeline_architectures.md) for guidance on different types of pipelines that you can use. Pipelines can be tailored to meet your needs, such as for a large complex project or a monorepo with independent defined components.
+
+#### Parallel and sequential job execution
+
+The following examples show how jobs can run in parallel, or sequentially:
+
+1. `job1` and `job2` run in parallel (in the `build` stage for GitLab CI/CD).
+1. `job3` runs only after `job1` and `job2` complete successfully (in the `test` stage).
+1. `job4` runs only after `job3` completes successfully (in the `deploy` stage).
+
+CircleCI example with `workflows`:
+
+```yaml
+version: 2
+jobs:
+ job1:
+ steps:
+ - checkout
+ - run: make build dependencies
+ job2:
+ steps:
+ - run: make build artifacts
+ job3:
+ steps:
+ - run: make test
+ job4:
+ steps:
+ - run: make deploy
+
+workflows:
+ version: 2
+ jobs:
+ - job1
+ - job2
+ - job3:
+ requires:
+ - job1
+ - job2
+ - job4:
+ requires:
+ - job3
+```
+
+Example of the same workflow as `stages` in GitLab CI/CD:
+
+```yaml
+stages:
+ - build
+ - test
+ - deploy
+
+job 1:
+ stage: build
+ script: make build dependencies
+
+job 2:
+ stage: build
+ script: make build artifacts
+
+job3:
+ stage: test
+ script: make test
+
+job4:
+ stage: deploy
+ script: make deploy
+```
+
+#### Scheduled run
+
+GitLab CI/CD has an easy to use UI to [schedule pipelines](../pipelines/schedules.md). Also, [rules](../yaml/README.md#rules) can be used to determine if jobs should be included or excluded from a scheduled pipeline.
+
+CircleCI example of a scheduled workflow:
+
+```yaml
+commit-workflow:
+ jobs:
+ - build
+scheduled-workflow:
+ triggers:
+ - schedule:
+ cron: "0 1 * * *"
+ filters:
+ branches:
+ only: try-schedule-workflow
+ jobs:
+ - build
+```
+
+Example of the same scheduled pipeline using [`rules`](../yaml/README.md#rules) in GitLab CI/CD:
+
+```yaml
+job1:
+ script:
+ - make build
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "schedule" && $CI_COMMIT_REF_NAME == "try-schedule-workflow"'
+```
+
+After the pipeline configuration is saved, you configure the cron schedule in the [GitLab UI](../pipelines/schedules.md#configuring-pipeline-schedules), and can enable or disable schedules in the UI as well.
+
+#### Manual run
+
+CircleCI example of a manual workflow:
+
+```yaml
+release-branch-workflow:
+ jobs:
+ - build
+ - testing:
+ requires:
+ - build
+ - deploy:
+ type: approval
+ requires:
+ - testing
+```
+
+Example of the same workflow using [`when: manual`](../yaml/README.md#whenmanual) in GitLab CI/CD:
+
+```yaml
+deploy_prod:
+ stage: deploy
+ script:
+ - echo "Deploy to production server"
+ when: manual
+```
+
+### Filter job by branch
+
+[Rules](../yaml/README.md#rules) are a mechanism to determine if the job will or will not run for a specific branch.
+
+CircleCI example of a job filtered by branch:
+
+```yaml
+jobs:
+ deploy:
+ branches:
+ only:
+ - master
+ - /rc-.*/
+```
+
+Example of the same workflow using `rules` in GitLab CI/CD:
+
+```yaml
+deploy_prod:
+ stage: deploy
+ script:
+ - echo "Deploy to production server"
+ rules:
+ - if: '$CI_COMMIT_BRANCH == "master"'
+```
+
+### Caching
+
+GitLab provides a caching mechanism to speed up build times for your jobs by reusing previously downloaded dependencies. It's important to know the different between [cache and artifacts](../caching/index.md#cache-vs-artifacts) to make the best use of these features.
+
+CircleCI example of a job using a cache:
+
+```yaml
+jobs:
+ job1:
+ steps:
+ - restore_cache:
+ key: source-v1-< .Revision >
+ - checkout
+ - run: npm install
+ - save_cache:
+ key: source-v1-< .Revision >
+ paths:
+ - "node_modules"
+```
+
+Example of the same pipeline using `cache` in GitLab CI/CD:
+
+```yaml
+image: node:latest
+
+# Cache modules in between jobs
+cache:
+ key: $CI_COMMIT_REF_SLUG
+ paths:
+ - .npm/
+
+before_script:
+ - npm ci --cache .npm --prefer-offline
+
+test_async:
+ script:
+ - node ./specs/start.js ./specs/async.spec.js
+```
+
+## Contexts and variables
+
+CircleCI provides [Contexts](https://circleci.com/docs/2.0/contexts/) to securely pass environment variables across project pipelines. In GitLab, a [Group](../../user/group/index.md) can be created to assemble related projects together. At the group level, [variables](../variables/README.md#group-level-environment-variables) can be stored outside the individual projects, and securely passed into pipelines across multiple projects.
+
+## Orbs
+
+There are two GitLab issues open addressing CircleCI Orbs and how GitLab can achieve similar functionality.
+
+- <https://gitlab.com/gitlab-com/Product/-/issues/1151>
+- <https://gitlab.com/gitlab-org/gitlab/-/issues/195173>
+
+## Build environments
+
+CircleCI offers `executors` as the underlying technology to run a specific job. In GitLab, this is done by [Runners](https://docs.gitlab.com/runner/).
+
+The following environments are supported:
+
+Self-Managed Runners:
+
+- Linux
+- Windows
+- macOS
+
+GitLab.com Shared Runners:
+
+- Linux
+- Windows
+- [Planned: macOS](https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues/5720)
+
+### Machine and specific build environments
+
+[Tags](../yaml/README.md#tags) can be used to run jobs on different platforms, by telling GitLab which Runners should run the jobs.
+
+CircleCI example of a job running on a specific environment:
+
+```yaml
+jobs:
+ ubuntuJob:
+ machine:
+ image: ubuntu-1604:201903-01
+ steps:
+ - checkout
+ - run: echo "Hello, $USER!"
+ osxJob:
+ macos:
+ xcode: 11.3.0
+ steps:
+ - checkout
+ - run: echo "Hello, $USER!"
+```
+
+Example of the same job using `tags` in GitLab CI/CD:
+
+```yaml
+windows job:
+ stage:
+ - build
+ tags:
+ - windows
+ script:
+ - echo Hello, %USERNAME%!
+
+osx job:
+ stage:
+ - build
+ tags:
+ - osx
+ script:
+ - echo "Hello, $USER!"
+```
diff --git a/doc/ci/multi_project_pipelines.md b/doc/ci/multi_project_pipelines.md
index 2627f83c043..40d495a69f1 100644
--- a/doc/ci/multi_project_pipelines.md
+++ b/doc/ci/multi_project_pipelines.md
@@ -1,11 +1,14 @@
---
+stage: Verify
+group: Continuous Integration
+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
---
# Multi-project pipelines
> - [Introduced](https://about.gitlab.com/releases/2015/08/22/gitlab-7-14-released/#build-triggers-api-gitlab-ci) in GitLab 7.14, as Build Triggers.
-> - [Made available](https://gitlab.com/gitlab-org/gitlab/issues/199224) in all tiers in GitLab 12.8.
+> - [Made available](https://gitlab.com/gitlab-org/gitlab/-/issues/199224) in all tiers in GitLab 12.8.
You can set up [GitLab CI/CD](README.md) across multiple projects, so that a pipeline
in one project can trigger a pipeline in another project.
@@ -35,7 +38,7 @@ With Multi-Project Pipelines you can visualize the entire pipeline, including al
## Multi-project pipeline visualization **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/2121) in [GitLab Premium 9.3](https://about.gitlab.com/releases/2017/06/22/gitlab-9-3-released/#multi-project-pipeline-graphs).
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2121) in [GitLab Premium 9.3](https://about.gitlab.com/releases/2017/06/22/gitlab-9-3-released/#multi-project-pipeline-graphs).
When you configure GitLab CI/CD for your project, you can visualize the stages of your
[jobs](pipelines/index.md#configure-a-pipeline) on a [pipeline graph](pipelines/index.md#visualize-pipelines).
@@ -50,7 +53,7 @@ and when hovering or tapping (on touchscreen devices) they will expand and be sh
## Triggering multi-project pipelines through API
> - 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.
+> - 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.
When you use the [`CI_JOB_TOKEN` to trigger pipelines](triggers/README.md#ci-job-token), GitLab
recognizes the source of the job token, and thus internally ties these pipelines
@@ -61,8 +64,8 @@ outbound connections for upstream and downstream pipeline dependencies.
## Creating multi-project pipelines from `.gitlab-ci.yml`
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/8997) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.8.
-> - [Made available](https://gitlab.com/gitlab-org/gitlab/issues/199224) in all tiers in 12.8.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8997) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.8.
+> - [Made available](https://gitlab.com/gitlab-org/gitlab/-/issues/199224) in all tiers in 12.8.
### Triggering a downstream pipeline using a bridge job
@@ -129,7 +132,7 @@ Use:
- The `project` keyword to specify the full path to a downstream project.
- The `branch` keyword to specify the name of a branch in the project specified by `project`.
- [From GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/issues/10126), variable expansion is
+ [From GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/-/issues/10126), variable expansion is
supported.
GitLab will use a commit that is currently on the HEAD of the branch when
@@ -192,8 +195,8 @@ the ones defined in the upstream project will take precedence.
### Mirroring status from triggered pipeline
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/11238) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.3.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/issues/199224) to GitLab Core in 12.8.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11238) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.3.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/199224) to GitLab Core in 12.8.
You can mirror the pipeline status from the triggered pipeline to the source
bridge job by using `strategy: depend`. For example:
@@ -240,7 +243,7 @@ Some features are not implemented yet. For example, support for environments.
## Trigger a pipeline when an upstream project is rebuilt
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/9045) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9045) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.8.
You can trigger a pipeline in your project whenever a pipeline finishes for a new
tag in a different project:
diff --git a/doc/ci/parent_child_pipelines.md b/doc/ci/parent_child_pipelines.md
index e28adc2bc01..c936bd8f5fe 100644
--- a/doc/ci/parent_child_pipelines.md
+++ b/doc/ci/parent_child_pipelines.md
@@ -1,10 +1,13 @@
---
+stage: Verify
+group: Continuous Integration
+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
---
# Parent-child pipelines
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/16094) in GitLab 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/16094) in GitLab 12.7.
As pipelines grow more complex, a few related problems start to emerge:
@@ -131,7 +134,7 @@ microservice_a:
## Dynamic child pipelines
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/35632) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35632) in GitLab 12.9.
Instead of running a child pipeline from a static YAML file, you can define a job that runs
your own script to generate a YAML file, which is then [used to trigger a child pipeline](yaml/README.md#trigger-child-pipeline-with-generated-configuration-file).
@@ -148,5 +151,5 @@ This is [resolved in GitLab 12.10](https://gitlab.com/gitlab-org/gitlab/-/issues
## Limitations
A parent pipeline can trigger many child pipelines, but a child pipeline cannot trigger
-further child pipelines. See the [related issue](https://gitlab.com/gitlab-org/gitlab/issues/29651)
+further child pipelines. See the [related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/29651)
for discussion on possible future improvements.
diff --git a/doc/ci/pipelines/img/code_coverage_graph_v13_1.png b/doc/ci/pipelines/img/code_coverage_graph_v13_1.png
new file mode 100644
index 00000000000..da92a1b4a86
--- /dev/null
+++ b/doc/ci/pipelines/img/code_coverage_graph_v13_1.png
Binary files differ
diff --git a/doc/ci/pipelines/index.md b/doc/ci/pipelines/index.md
index 731cb196eaa..48aaebc3456 100644
--- a/doc/ci/pipelines/index.md
+++ b/doc/ci/pipelines/index.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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
disqus_identifier: 'https://docs.gitlab.com/ee/ci/pipelines.html'
type: reference
---
@@ -88,7 +91,7 @@ Clicking a pipeline will bring you to the **Pipeline Details** page and show
the jobs that were run for that pipeline. From here you can cancel a running pipeline,
retry jobs on a failed pipeline, or [delete a pipeline](#delete-a-pipeline).
-[Starting in GitLab 12.3](https://gitlab.com/gitlab-org/gitlab-foss/issues/50499), a link to the
+[Starting in GitLab 12.3](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/50499), a link to the
latest pipeline for the last commit of a given branch is available at `/project/pipelines/[branch]/latest`.
Also, `/project/pipelines/latest` will redirect you to the latest pipeline for the last commit
on the project's default branch.
@@ -98,6 +101,8 @@ you can filter the pipeline list by:
- Trigger author
- Branch name
+- Status ([since GitLab 13.1](https://gitlab.com/gitlab-org/gitlab/-/issues/217617))
+- Tag ([since GitLab 13.1](https://gitlab.com/gitlab-org/gitlab/-/issues/217617))
### Run a pipeline manually
@@ -119,7 +124,7 @@ The pipeline will execute the jobs as configured.
### Run a pipeline by using a URL query string
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/24146) in GitLab 12.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/24146) in GitLab 12.5.
You can use a query string to pre-populate the **Run Pipeline** page. For example, the query string
`.../pipelines/new?ref=my_branch&var[foo]=bar&file_var[file_foo]=file_bar` will pre-populate the
@@ -179,7 +184,7 @@ This functionality is only available:
### Delete a pipeline
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/24851) in GitLab 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/24851) in GitLab 12.7.
Users with [owner permissions](../../user/permissions.md) in a project can delete a pipeline
by clicking on the pipeline in the **CI/CD > Pipelines** to get to the **Pipeline Details**
@@ -403,7 +408,7 @@ For example, if you start rolling out new code and:
### Expand and collapse job log sections
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/14664) in GitLab 12.0.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/14664) in GitLab 12.0.
Job logs are divided into sections that can be collapsed or expanded. Each section will display
the duration.
@@ -500,7 +505,7 @@ Stages in pipeline mini graphs are collapsible. Hover your mouse over them and c
### Pipeline success and duration charts
> - Introduced in GitLab 3.1.1 as Commit Stats, and later renamed to Pipeline Charts.
-> - [Renamed](https://gitlab.com/gitlab-org/gitlab/issues/38318) to CI / CD Analytics in GitLab 12.8.
+> - [Renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/38318) to CI / CD Analytics in GitLab 12.8.
GitLab tracks the history of your pipeline successes and failures, as well as how long each pipeline ran. To view this information, go to **Analytics > CI / CD Analytics**.
diff --git a/doc/ci/pipelines/job_artifacts.md b/doc/ci/pipelines/job_artifacts.md
index d4774016d9c..1d60f412e5e 100644
--- a/doc/ci/pipelines/job_artifacts.md
+++ b/doc/ci/pipelines/job_artifacts.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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
disqus_identifier: 'https://docs.gitlab.com/ee/user/project/pipelines/job_artifacts.html'
type: reference, howto
---
@@ -103,7 +106,7 @@ combination thereof (`junit: [rspec.xml, test-results/TEST-*.xml]`).
#### `artifacts:reports:dotenv`
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/17066) in GitLab 12.9.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/17066) in GitLab 12.9.
> - Requires GitLab Runner 11.5 and later.
The `dotenv` report collects a set of environment variables as artifacts.
@@ -122,7 +125,7 @@ There are a couple of limitations on top of the [original dotenv rules](https://
#### `artifacts:reports:cobertura`
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/3708) in GitLab 12.9.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3708) in GitLab 12.9.
> - Requires [GitLab Runner](https://docs.gitlab.com/runner/) 11.5 and above.
The `cobertura` report collects [Cobertura coverage XML files](../../user/project/merge_requests/test_coverage_visualization.md).
@@ -137,9 +140,10 @@ third party ports for other languages like JavaScript, Python, Ruby, and so on.
> - [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. The collected Terraform
+The `terraform` report obtains a Terraform `tfplan.json` file. [JQ processing required to remove credentials](../../user/infrastructure/index.md#output-terraform-plan-information-into-a-merge-request). The collected Terraform
plan report will be uploaded to GitLab as an artifact and will be automatically shown
-in merge requests.
+in merge requests. For more information, see
+[Output `terraform plan` information into a merge request](../../user/infrastructure/index.md#output-terraform-plan-information-into-a-merge-request).
#### `artifacts:reports:codequality` **(STARTER)**
@@ -164,6 +168,18 @@ The collected SAST report will be uploaded to GitLab as an artifact and will be
in the merge requests and pipeline view. It's also used to provide data for security
dashboards.
+#### `artifacts:reports:secret_detection` **(ULTIMATE)**
+
+> - Introduced in GitLab 13.1.
+> - Requires GitLab Runner 11.5 and above.
+
+The `secret-detection` report collects [detected secrets](../../user/application_security/secret_detection/index.md)
+as artifacts.
+
+The collected Secret Detection report is uploaded to GitLab as an artifact and summarized
+in the merge requests and pipeline view. It's also used to provide data for security
+dashboards.
+
#### `artifacts:reports:dependency_scanning` **(ULTIMATE)**
> - Introduced in GitLab 11.5.
@@ -250,6 +266,17 @@ as artifacts.
The collected Metrics report will be uploaded to GitLab as an artifact and will
be automatically shown in merge requests.
+#### `artifacts:reports:requirements` **(ULTIMATE)**
+
+> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2859) in GitLab 13.1.
+> - Requires GitLab Runner 11.5 and above.
+
+The `requirements` report collects `requirements.json` files as artifacts.
+
+The collected Requirements report will be uploaded to GitLab as an artifact and
+existing [requirements](../../user/project/requirements/index.md) will be
+marked as Satisfied.
+
## Browsing artifacts
> - From GitLab 9.2, PDFs, images, videos, and other formats can be previewed directly in the job artifacts browser without the need to download them.
diff --git a/doc/ci/pipelines/pipeline_architectures.md b/doc/ci/pipelines/pipeline_architectures.md
index 4872e2595f9..9176444660d 100644
--- a/doc/ci/pipelines/pipeline_architectures.md
+++ b/doc/ci/pipelines/pipeline_architectures.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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/pipelines/schedules.md b/doc/ci/pipelines/schedules.md
index 0c0a613c628..e488179ffee 100644
--- a/doc/ci/pipelines/schedules.md
+++ b/doc/ci/pipelines/schedules.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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
disqus_identifier: 'https://docs.gitlab.com/ee/user/project/pipelines/schedules.html'
type: reference, howto
---
diff --git a/doc/ci/pipelines/settings.md b/doc/ci/pipelines/settings.md
index 0a859b5b68f..2c9d4ccf2c4 100644
--- a/doc/ci/pipelines/settings.md
+++ b/doc/ci/pipelines/settings.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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
disqus_identifier: 'https://docs.gitlab.com/ee/user/project/pipelines/settings.html'
type: reference, howto
---
@@ -59,7 +62,7 @@ if the job surpasses the threshold, it is marked as failed.
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17221) in GitLab 10.7.
Project defined timeout (either specific timeout set by user or the default
-60 minutes timeout) may be [overridden on Runner level](../runners/README.md#setting-maximum-job-timeout-for-a-runner).
+60 minutes timeout) may be [overridden on Runner level](../runners/README.md#set-maximum-job-timeout-for-a-runner).
## Maximum artifacts size **(CORE ONLY)**
@@ -69,7 +72,7 @@ For information about setting a maximum artifact size for a project, see
## Custom CI configuration path
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/12509) in GitLab 9.4.
-> - [Support for external `.gitlab-ci.yml` locations](https://gitlab.com/gitlab-org/gitlab/issues/14376) introduced in GitLab 12.6.
+> - [Support for external `.gitlab-ci.yml` locations](https://gitlab.com/gitlab-org/gitlab/-/issues/14376) introduced in GitLab 12.6.
By default we look for the `.gitlab-ci.yml` file in the project's root
directory. If needed, you can specify an alternate path and file name, including locations outside the project.
@@ -118,7 +121,8 @@ job log using a regular expression. In the pipelines settings, search for the
![Pipelines settings test coverage](img/pipelines_settings_test_coverage.png)
Leave blank if you want to disable it or enter a Ruby regular expression. You
-can use <https://rubular.com> to test your regex.
+can use <https://rubular.com> to test your regex. The regex returns the **last**
+match found in the output.
If the pipeline succeeds, the coverage is shown in the merge request widget and
in the jobs table.
@@ -130,15 +134,18 @@ in the jobs table.
A few examples of known coverage tools for a variety of languages can be found
in the pipelines settings page.
-### Download test coverage history
+### Code Coverage history
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/209121) in GitLab 12.10.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/209121) the ability to download a `.csv` in GitLab 12.10.
+> - [Graph introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/33743) in GitLab 13.1.
If you want to see the evolution of your project code coverage over time,
-you can download a CSV file with this data. From your project:
+you can view a graph or download a CSV file with this data. From your project:
-1. Go to **{chart}** **Project Analytics > Repository**.
-1. Click **Download raw data (.csv)**
+1. Go to **{chart}** **Project Analytics > Repository** to see the historic data for each job listed in the dropdown above the graph.
+1. If you want a CSV file of that data, click **Download raw data (.csv)**
+
+![Code coverage graph of a project over time](img/code_coverage_graph_v13_1.png)
### Removing color codes
@@ -205,9 +212,11 @@ you can enable this in the project settings:
1. Check the **Auto-cancel redundant, pending pipelines** checkbox.
1. Click **Save changes**.
+Note that only jobs with [interruptible](../yaml/README.md#interruptible) set to `true` will be cancelled.
+
## Skip outdated deployment jobs
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/25276) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/25276) in GitLab 12.9.
Your project may have multiple concurrent deployment jobs that are
scheduled to run within the same time frame.
@@ -224,6 +233,8 @@ To avoid this scenario:
The pending deployment jobs will be skipped.
+For more information, see [Deployment safety](../environments/deployment_safety.md).
+
## Pipeline Badges
In the pipelines settings page you can find pipeline status and test coverage
@@ -289,7 +300,7 @@ https://example.gitlab.com/<namespace>/<project>/badges/<branch>/coverage.svg?st
#### Flat square
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/30120) in GitLab 11.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/30120) in GitLab 11.8.
```plaintext
https://example.gitlab.com/<namespace>/<project>/badges/<branch>/coverage.svg?style=flat-square
@@ -297,6 +308,16 @@ https://example.gitlab.com/<namespace>/<project>/badges/<branch>/coverage.svg?st
![Badge flat square style](https://gitlab.com/gitlab-org/gitlab-foss/badges/master/coverage.svg?job=coverage&style=flat-square)
+### Custom badge text
+
+The text for a badge can be customized. This can be useful to differentiate between multiple coverage jobs that run in the same pipeline. Customize the badge text and width by adding the `key_text=custom_text` and `key_width=custom_key_width` parameters to the URL:
+
+```plaintext
+https://gitlab.com/gitlab-org/gitlab-foss/badges/master/coverage.svg?job=karma&key_text=Frontend+Coverage&key_width=100
+```
+
+![Badge with custom text and width](https://gitlab.com/gitlab-org/gitlab-foss/badges/master/coverage.svg?job=karma&key_text=Frontend+Coverage&key_width=100)
+
## Environment Variables
[Environment variables](../variables/README.md#gitlab-cicd-environment-variables) can be set in an environment to be available to a runner.
diff --git a/doc/ci/quick_start/README.md b/doc/ci/quick_start/README.md
index a14cfcfa9ed..25469570603 100644
--- a/doc/ci/quick_start/README.md
+++ b/doc/ci/quick_start/README.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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
---
@@ -165,7 +168,7 @@ The next step is to configure a Runner so that it picks the pending jobs.
## Configuring a Runner
In GitLab, Runners run the jobs that you define in `.gitlab-ci.yml`. A Runner
-can be a virtual machine, a VPS, a bare-metal machine, a docker container or
+can be a virtual machine, a VPS, a bare-metal machine, a Docker container or
even a cluster of containers. GitLab and the Runners communicate through an API,
so the only requirement is that the Runner's machine has network access to the
GitLab server.
@@ -184,7 +187,7 @@ can be found at <https://docs.gitlab.com/runner/>.
In order to have a functional Runner you need to follow two steps:
1. [Install it](https://docs.gitlab.com/runner/install/)
-1. [Configure it](../runners/README.md#registering-a-specific-runner)
+1. [Configure it](https://docs.gitlab.com/runner/configuration/)
Follow the links above to set up your own Runner or use a Shared Runner as
described in the next section.
diff --git a/doc/ci/review_apps/index.md b/doc/ci/review_apps/index.md
index ad0a4270f43..67fac70c8de 100644
--- a/doc/ci/review_apps/index.md
+++ b/doc/ci/review_apps/index.md
@@ -7,7 +7,7 @@ type: reference
# Review Apps
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/21971) in GitLab 8.12. Further additions were made in GitLab 8.13 and 8.14.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/21971) in GitLab 8.12. Further additions were made in GitLab 8.13 and 8.14.
> - Inspired by [Heroku's Review Apps](https://devcenter.heroku.com/articles/github-integration-review-apps), which itself was inspired by [Fourchette](https://github.com/rainforestapp/fourchette).
Review Apps is a collaboration tool that takes the hard work out of providing an environment to showcase product changes.
@@ -65,7 +65,7 @@ The process of configuring Review Apps is as follows:
### Enable Review Apps button
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/118844) in GitLab 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118844) in GitLab 12.8.
When configuring Review Apps for a project, you need to add a new job to `.gitlab-ci.yml`,
as mentioned above. To facilitate this and if you are using Kubernetes, you can click
@@ -95,8 +95,11 @@ The following are example projects that demonstrate Review App configuration:
- [NGINX](https://gitlab.com/gitlab-examples/review-apps-nginx).
- [OpenShift](https://gitlab.com/gitlab-examples/review-apps-openshift).
-<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
-See also the video [Demo: Cloud Native Development with GitLab](https://www.youtube.com/watch?v=jfIyQEwrocw), which includes a Review Apps example.
+Other examples of Review Apps:
+
+- <i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
+[Cloud Native Development with GitLab](https://www.youtube.com/watch?v=jfIyQEwrocw).
+- [Review Apps for Android](https://about.gitlab.com/blog/2020/05/06/how-to-create-review-apps-for-android-with-gitlab-fastlane-and-appetize-dot-io/).
## Route Maps
@@ -185,7 +188,7 @@ Once you have the route mapping set up, it will take effect in the following loc
## Visual Reviews **(STARTER)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/10761) in GitLab Starter 12.0.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10761) in GitLab Starter 12.0.
With Visual Reviews, you can provide a feedback form to your Review Apps so
that reviewers can post comments directly from the app back to the merge request
@@ -258,7 +261,7 @@ Then, when your app is deployed via GitLab CI/CD, those variables should get
replaced with their real values.
NOTE: **Note:**
-Future enhancements [are planned](https://gitlab.com/gitlab-org/gitlab/issues/11322)
+Future enhancements [are planned](https://gitlab.com/gitlab-org/gitlab/-/issues/11322)
to make this process even easier.
### Determining merge request ID
diff --git a/doc/ci/runners/README.md b/doc/ci/runners/README.md
index deefd2f0e73..86fabd5d54f 100644
--- a/doc/ci/runners/README.md
+++ b/doc/ci/runners/README.md
@@ -1,190 +1,59 @@
---
+stage: Verify
+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/#designated-technical-writers
type: reference
---
# Configuring GitLab Runners
In GitLab CI/CD, Runners run the code defined in [`.gitlab-ci.yml`](../yaml/README.md).
-They are isolated (virtual) machines that pick up jobs through the coordinator
-API of GitLab CI/CD.
-
-A Runner can be specific to a certain project or serve any project
-in GitLab CI/CD. A Runner that serves all projects is called a shared Runner.
-
-Ideally, the GitLab Runner should not be installed on the same machine as GitLab.
-Read the [requirements documentation](../../install/requirements.md#gitlab-runner)
-for more information.
-
-## Shared, specific and group Runners
-
-After [installing the Runner](https://docs.gitlab.com/runner/install/), you can either register it as shared or
-specific. You can only register a shared Runner if you have admin access to
-the GitLab instance. The main differences between a shared and a specific Runner
-are:
-
-- **Shared Runners** are useful for jobs that have similar requirements,
- between multiple projects. Rather than having multiple Runners idling for
- many projects, you can have a single or a small number of Runners that handle
- multiple projects. This makes it easier to maintain and update them.
- Shared Runners process jobs using a [fair usage queue](#how-shared-runners-pick-jobs).
- In contrast to specific Runners that use a FIFO queue, this prevents
- cases where projects create hundreds of jobs which can lead to eating all
- available shared Runners resources.
-- **Specific Runners** are useful for jobs that have special requirements or for
- projects with a specific demand. If a job has certain requirements, you can set
- up the specific Runner with this in mind, while not having to do this for all
- Runners. For example, if you want to deploy a certain project, you can set up
- a specific Runner to have the right credentials for this. The [usage of tags](#using-tags)
- may be useful in this case. Specific Runners process jobs using a [FIFO](https://en.wikipedia.org/wiki/FIFO_(computing_and_electronics)) queue.
-- **Group Runners** are useful when you have multiple projects under one group
- and would like all projects to have access to a set of Runners. Group Runners
- process jobs using a [FIFO](https://en.wikipedia.org/wiki/FIFO_(computing_and_electronics)) queue.
-
-A Runner that is specific only runs for the specified project(s). A shared Runner
-can run jobs for every project that has enabled the option **Allow shared Runners**
-under **Settings > CI/CD**.
-
-Projects with high demand of CI activity can also benefit from using specific
-Runners. By having dedicated Runners you are guaranteed that the Runner is not
-being held up by another project's jobs.
-
-You can set up a specific Runner to be used by multiple projects. The difference
-with a shared Runner is that you have to enable each project explicitly for
-the Runner to be able to run its jobs.
+A GitLab Runner is a lightweight, highly-scalable agent that picks up a CI job through
+the coordinator API of GitLab CI/CD, runs the job, and sends the result back to the GitLab instance.
-Specific Runners do not get shared with forked projects automatically.
-A fork does copy the CI settings (jobs, allow shared, etc) of the cloned
-repository.
-
-## Registering a shared Runner
-
-You can only register a shared Runner if you are an admin of the GitLab instance.
-
-1. Grab the shared-Runner token on the `admin/runners` page
-
- ![Shared Runners Admin Area](img/shared_runners_admin.png)
-
-1. [Register the Runner](https://docs.gitlab.com/runner/register/)
-
-Shared Runners are enabled by default as of GitLab 8.2, but can be disabled
-with the **Disable shared Runners** button which is present under each project's
-**Settings > CI/CD** page. Previous versions of GitLab defaulted shared
-Runners to disabled.
-
-## Registering a specific Runner
-
-Registering a specific Runner can be done in two ways:
-
-1. Creating a Runner with the project registration token
-1. Converting a shared Runner into a specific Runner (one-way, admin only)
-
-### Registering a specific Runner with a project registration token
-
-To create a specific Runner without having admin rights to the GitLab instance,
-visit the project you want to make the Runner work for in GitLab:
-
-1. Go to **Settings > CI/CD** to obtain the token
-1. [Register the Runner](https://docs.gitlab.com/runner/register/)
-
-## Registering a group Runner
-
-Creating a group Runner requires Owner permissions for the group. To create a
-group Runner visit the group you want to make the Runner work for in GitLab:
-
-1. Go to **Settings > CI/CD** to obtain the token
-1. [Register the Runner](https://docs.gitlab.com/runner/register/)
-
-### Making an existing shared Runner specific
-
-If you are an admin on your GitLab instance, you can turn any shared Runner into
-a specific one, but not the other way around. Keep in mind that this is a one
-way transition.
-
-1. Go to the Runners in the **Admin Area > Overview > Runners** (`/admin/runners`)
- and find your Runner
-1. Enable any projects under **Restrict projects for this Runner** to be used
- with the Runner
-
-From now on, the shared Runner will be specific to those projects.
+Runners are created by an administrator and are visible in the GitLab UI.
+Runners can be specific to certain projects or available to all projects.
-## Locking a specific Runner from being enabled for other projects
+## Types of Runners
-You can configure a Runner to assign it exclusively to a project. When a
-Runner is locked this way, it can no longer be enabled for other projects.
-This setting can be enabled the first time you [register a Runner](https://docs.gitlab.com/runner/register/) and
-can be changed afterwards under each Runner's settings.
+There are three types of Runners:
-To lock/unlock a Runner:
+- [Shared](#shared-runners) (for all projects)
+- [Group](#group-runners) (for all projects in a group)
+- [Specific](#specific-runners) (for specific projects)
-1. Visit your project's **Settings > CI/CD**
-1. Find the Runner you wish to lock/unlock and make sure it's enabled
-1. Click the pencil button
-1. Check the **Lock to current projects** option
-1. Click **Save changes** for the changes to take effect
+If you are running self-managed GitLab, you can create your own Runners.
-## Assigning a Runner to another project
+If you are using GitLab.com, you can use the shared Runners provided by GitLab or
+create your own group or specific Runners.
-If you are an Owner on a project where a specific Runner is assigned to, and the
-Runner is not [locked only to that project](#locking-a-specific-runner-from-being-enabled-for-other-projects),
-you can enable the Runner also on any other project where you have Owner permissions.
-
-To enable/disable a Runner in your project:
-
-1. Visit your project's **Settings > CI/CD**
-1. Find the Runner you wish to enable/disable
-1. Click **Enable for this project** or **Disable for this project**
-
-> **Note**:
-Consider that if you don't lock your specific Runner to a specific project, any
-user with Maintainer role in you project can assign your Runner to another arbitrary
-project without requiring your authorization, so use it with caution.
-
-CAUTION: **Caution:**
-Never add a private Runner that you're using in your private projects to a
-project that you share with other people.
-
-CAUTION: **Caution:**
-Never use a Runner from a project which has multiple maintainers in your
-private project.
-
-An admin can enable/disable a specific Runner for projects:
-
-1. Navigate to **Admin > Runners**
-1. Find the Runner you wish to enable/disable
-1. Click edit on the Runner
-1. Click **Enable** or **Disable** on the project
-
-## Protected Runners
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13194) in GitLab 10.0.
+### Shared Runners
-You can protect Runners from revealing sensitive information.
-Whenever a Runner is protected, the Runner picks only jobs created on
-[protected branches](../../user/project/protected_branches.md) or [protected tags](../../user/project/protected_tags.md), and ignores other jobs.
+*Shared Runners* are available to every project in a GitLab instance.
-To protect/unprotect Runners:
+Use shared Runners when you have multiple jobs with similar requirements. Rather than
+having multiple Runners idling for many projects, you can have a few Runners that handle
+multiple projects.
-1. Visit your project's **Settings > CI/CD**
-1. Find a Runner you want to protect/unprotect and make sure it's enabled
-1. Click the pencil button besides the Runner name
-1. Check the **Protected** option
-1. Click **Save changes** for the changes to take effect
+If you are using a self-managed instance of GitLab, your administrator can create
+shared Runners and configure them to use the
+[executor](https://docs.gitlab.com/runner/executors/README.html) you want.
-![specific Runners edit icon](img/protected_runners_check_box.png)
+If you are using GitLab.com, you can select from a list of
+[shared Runners that GitLab maintains](../../user/gitlab_com/index.md#shared-runners).
-## Manually clearing the Runners cache
+#### How shared Runners pick jobs
-Read [clearing the cache](../caching/index.md#clearing-the-cache).
+Shared Runners process jobs by using a fair usage queue. This queue prevents
+projects from creating hundreds of jobs and using all available
+shared Runner resources.
-## How shared Runners pick jobs
-
-Shared Runners abide to a process queue we call fair usage. The fair usage
-algorithm tries to assign jobs to shared Runners from projects that have the
-lowest number of jobs currently running on shared Runners.
+The fair usage queue algorithm assigns jobs based on the projects that have the
+fewest number of jobs already running on shared Runners.
**Example 1**
-We have following jobs in queue:
+If these jobs are in the queue:
- Job 1 for Project 1
- Job 2 for Project 1
@@ -193,20 +62,20 @@ We have following jobs in queue:
- Job 5 for Project 2
- Job 6 for Project 3
-With the fair usage algorithm jobs are assigned in following order:
+The fair usage algorithm assigns jobs in this order:
-1. Job 1 is chosen first, because it has the lowest job number from projects with no running jobs (that is, all projects)
-1. Job 4 is next, because 4 is now the lowest job number from projects with no running jobs (Project 1 has a job running)
-1. Job 6 is next, because 6 is now the lowest job number from projects with no running jobs (Projects 1 and 2 have jobs running)
-1. Job 2 is next, because, of projects with the lowest number of jobs running (each has 1), it is the lowest job number
+1. Job 1 is chosen first, because it has the lowest job number from projects with no running jobs (that is, all projects).
+1. Job 4 is next, because 4 is now the lowest job number from projects with no running jobs (Project 1 has a job running).
+1. Job 6 is next, because 6 is now the lowest job number from projects with no running jobs (Projects 1 and 2 have jobs running).
+1. Job 2 is next, because, of projects with the lowest number of jobs running (each has 1), it is the lowest job number.
1. Job 5 is next, because Project 1 now has 2 jobs running and Job 5 is the lowest remaining job number between Projects 2 and 3.
-1. Lastly we choose Job 3... because it's the only job left
+1. Finally is Job 3... because it's the only job left.
---
**Example 2**
-We have following jobs in queue:
+If these jobs are in the queue:
- Job 1 for project 1
- Job 2 for project 1
@@ -215,103 +84,129 @@ We have following jobs in queue:
- Job 5 for project 2
- Job 6 for project 3
-With the fair usage algorithm jobs are assigned in following order:
+The fair usage algorithm assigns jobs in this order:
-1. Job 1 is chosen first, because it has the lowest job number from projects with no running jobs (that is, all projects)
-1. We finish job 1
-1. Job 2 is next, because, having finished Job 1, all projects have 0 jobs running again, and 2 is the lowest available job number
-1. Job 4 is next, because with Project 1 running a job, 4 is the lowest number from projects running no jobs (Projects 2 and 3)
-1. We finish job 4
-1. Job 5 is next, because having finished Job 4, Project 2 has no jobs running again
-1. Job 6 is next, because Project 3 is the only project left with no running jobs
-1. Lastly we choose Job 3... because, again, it's the only job left (who says 1 is the loneliest number?)
+1. Job 1 is chosen first, because it has the lowest job number from projects with no running jobs (that is, all projects).
+1. We finish job 1.
+1. Job 2 is next, because, having finished Job 1, all projects have 0 jobs running again, and 2 is the lowest available job number.
+1. Job 4 is next, because with Project 1 running a job, 4 is the lowest number from projects running no jobs (Projects 2 and 3).
+1. We finish job 4.
+1. Job 5 is next, because having finished Job 4, Project 2 has no jobs running again.
+1. Job 6 is next, because Project 3 is the only project left with no running jobs.
+1. Lastly we choose Job 3... because, again, it's the only job left.
-## Using shared Runners effectively
+#### Enable a shared Runner
-If you are planning to use shared Runners, there are several things you
-should keep in mind.
+By default, all projects can use shared Runners, and they are enabled by default.
-### Using tags
+However, you can enable or disable shared Runners for individual projects.
-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 wasn't for tags.
+To enable or disable a shared Runner:
-By tagging a Runner for the types of jobs it can handle, you can make sure
-shared Runners will [only run the jobs they are equipped to run](../yaml/README.md#tags).
+1. Go to the project's **{settings}** **Settings > CI/CD** and expand the **Runners** section.
+1. Click **Allow shared Runners** or **Disable shared Runners**.
-For instance, at GitLab we have Runners tagged with "rails" if they contain
-the appropriate dependencies to run Rails test suites.
+### Group Runners
-### Allowing Runners with tags to pick jobs without tags
+Use *Group Runners* when you want all projects in a group
+to have access to a set of Runners.
-When you [register a Runner](https://docs.gitlab.com/runner/register/), its default behavior is to **only pick**
-[tagged jobs](../yaml/README.md#tags).
+Group Runners process jobs by using a first in, first out ([FIFO](https://en.wikipedia.org/wiki/FIFO_(computing_and_electronics))) queue.
-NOTE: **Note:**
-Owner [permissions](../../user/permissions.md) are required to change the
-Runner settings.
+#### Create a group Runner
-To make a Runner pick untagged jobs:
+You can create a group Runner for your self-managed GitLab instance or for GitLab.com.
+You must have [Owner permissions](../../user/permissions.md#group-members-permissions) for the group.
-1. Visit your project's **Settings > CI/CD > Runners**.
-1. Find the Runner you want to pick untagged jobs and make sure it's enabled.
-1. Click the pencil button.
-1. Check the **Run untagged jobs** option.
-1. Click the **Save changes** button for the changes to take effect.
+To create a group Runner:
+
+1. [Install Runner](https://docs.gitlab.com/runner/install/).
+1. Go to the group you want to make the Runner work for.
+1. Go to **{settings}** **Settings > CI/CD** and expand the **Runners** section.
+1. Note the URL and token.
+1. [Register the Runner](https://docs.gitlab.com/runner/register/).
+
+#### Pause or remove a group Runner
+
+You can pause or remove a group Runner.
+You must have [Owner permissions](../../user/permissions.md#group-members-permissions) for the group.
+
+1. Go to the group you want to remove or pause the Runner for.
+1. Go to **{settings}** **Settings > CI/CD** and expand the **Runners** section.
+1. Click **Pause** or **Remove Runner**.
+1. On the confirmation dialog, click **OK**.
+
+### Specific Runners
+
+Use *Specific Runners* when you want to use Runners for specific projects. For example,
+when you have:
+
+- Jobs with specific requirements, like a deploy job that requires credentials.
+- Projects with a lot of CI activity that can benefit from being separate from other Runners.
+
+You can set up a specific Runner to be used by multiple projects. Specific Runners
+must be enabled for each project explicitly.
+
+Specific Runners process jobs by using a first in, first out ([FIFO](https://en.wikipedia.org/wiki/FIFO_(computing_and_electronics))) queue.
NOTE: **Note:**
-The Runner tags list can not be empty when it's not allowed to pick untagged jobs.
+Specific Runners do not get shared with forked projects automatically.
+A fork *does* copy the CI / CD settings of the cloned repository.
-Below are some example scenarios of different variations.
+#### Create a specific Runner
-#### Runner runs only tagged jobs
+You can create a specific Runner for your self-managed GitLab instance or for GitLab.com.
+You must have [Owner permissions](../../user/permissions.md#project-members-permissions) for the project.
-The following examples illustrate the potential impact of the Runner being set
-to run only tagged jobs.
+To create a specific Runner:
-Example 1:
+1. [Install Runner](https://docs.gitlab.com/runner/install/).
+1. Go to the project's **{settings}** **Settings > CI/CD** and expand the **Runners** section.
+1. Note the URL and token.
+1. [Register the Runner](https://docs.gitlab.com/runner/register/).
-1. The Runner is configured to run only tagged jobs and has the `docker` tag.
-1. A job that has a `hello` tag is executed and stuck.
+#### Enable a specific Runner for a specific project
-Example 2:
+A specific Runner is available in the project it was created for. An administrator can
+enable a specific Runner to apply to additional projects.
-1. The Runner is configured to run only tagged jobs and has the `docker` tag.
-1. A job that has a `docker` tag is executed and run.
+- You must have Owner permissions for the project.
+- The specific Runner must not be [locked](#prevent-a-specific-runner-from-being-enabled-for-other-projects).
-Example 3:
+To enable or disable a specific Runner for a project:
-1. The Runner is configured to run only tagged jobs and has the `docker` tag.
-1. A job that has no tags defined is executed and stuck.
+1. Go to the project's **{settings}** **Settings > CI/CD** and expand the **Runners** section.
+1. Click **Enable for this project** or **Disable for this project**.
-#### Runner is allowed to run untagged jobs
+#### Prevent a specific Runner from being enabled for other projects
-The following examples illustrate the potential impact of the Runner being set
-to run tagged and untagged jobs.
+You can configure a specific Runner so it is "locked" and cannot be enabled for other projects.
+This setting can be enabled when you first [register a Runner](https://docs.gitlab.com/runner/register/),
+but can also be changed later.
-Example 1:
+To lock or unlock a Runner:
-1. The Runner is configured to run untagged jobs and has the `docker` tag.
-1. A job that has no tags defined is executed and run.
-1. A second job that has a `docker` tag defined is executed and run.
+1. Go to the project's **{settings}** **Settings > CI/CD** and expand the **Runners** section.
+1. Find the Runner you want to lock or unlock. Make sure it's enabled.
+1. Click the pencil button.
+1. Check the **Lock to current projects** option.
+1. Click **Save changes**.
-Example 2:
+## Manually clear the Runner cache
-1. The Runner is configured to run untagged jobs and has no tags defined.
-1. A job that has no tags defined is executed and run.
-1. A second job that has a `docker` tag defined is stuck.
+Read [clearing the cache](../caching/index.md#clearing-the-cache).
+
+## Set maximum job timeout for a Runner
-### Setting maximum job timeout for a Runner
+For each Runner, you can specify a *maximum job timeout*. This timeout,
+if smaller than the [project defined timeout](../pipelines/settings.md#timeout), takes precedence.
-For each Runner you can specify a _maximum job timeout_. Such timeout,
-if smaller than [project defined timeout](../pipelines/settings.md#timeout), will take the precedence. This
-feature can be used to prevent Shared Runner from being appropriated
-by a project by setting a ridiculous big timeout (for example, one week).
+This feature can be used to prevent your shared Runner from being overwhelmed
+by a project that has jobs with a long timeout (for example, one week).
-When not configured, Runner will not override project timeout.
+When not configured, Runners will not override the project timeout.
-How this feature will work:
+How this feature works:
**Example 1 - Runner timeout bigger than project timeout**
@@ -334,7 +229,7 @@ How this feature will work:
1. You start a job
1. The job, if running longer, will be timed out after **30 minutes**
-### Be careful with sensitive information
+## Be careful with sensitive information
With some [Runner Executors](https://docs.gitlab.com/runner/executors/README.html),
if you can run a job on the Runner, you can get full access to the file system,
@@ -349,6 +244,25 @@ The above is easily avoided by restricting the usage of shared Runners
on large public GitLab instances, controlling access to your GitLab instance,
and using more secure [Runner Executors](https://docs.gitlab.com/runner/executors/README.html).
+### Prevent Runners from revealing sensitive information
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13194) in GitLab 10.0.
+
+You can protect Runners so they don't reveal sensitive information.
+When a Runner is protected, the Runner picks jobs created on
+[protected branches](../../user/project/protected_branches.md) or [protected tags](../../user/project/protected_tags.md) only,
+and ignores other jobs.
+
+To protect or unprotect a Runner:
+
+1. Go to the project's **{settings}** **Settings > CI/CD** and expand the **Runners** section.
+1. Find the Runner you want to protect or unprotect. Make sure it's enabled.
+1. Click the pencil button.
+1. Check the **Protected** option.
+1. Click **Save changes**.
+
+![specific Runners edit icon](img/protected_runners_check_box.png)
+
### Forks
Whenever a project is forked, it copies the settings of the jobs that relate
@@ -356,23 +270,21 @@ to it. This means that if you have shared Runners set up for a project and
someone forks that project, the shared Runners will also serve jobs of this
project.
-## Attack vectors in Runners
+### Attack vectors in Runners
Mentioned briefly earlier, but the following things of Runners can be exploited.
We're always looking for contributions that can mitigate these
[Security Considerations](https://docs.gitlab.com/runner/security/).
-### Resetting the registration token for a Project
+### Reset the Runner registration token for a project
-If you think that registration token for a Project was revealed, you should
-reset them. It's recommended because such a token can be used to register another
-Runner to the Project. It may then be used to obtain the values of secret
-variables or clone the project code, that normally may be unavailable for the
-attacker.
+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.
To reset the token:
-1. Go to **Settings > CI/CD** for a specified Project.
+1. Go to the project's **{settings}** **Settings > CI/CD**.
1. Expand the **General pipelines settings** section.
1. Find the **Runner token** form field and click the **Reveal value** button.
1. Delete the value and save the form.
@@ -384,7 +296,7 @@ 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.
-## Determining the IP address of a Runner
+## Determine the IP address of a Runner
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17286) in GitLab 10.6.
@@ -397,22 +309,88 @@ automatically updated in GitLab.
The IP address for shared Runners and specific Runners can be found in
different places.
-### Shared Runners
+### Determine the IP address of a shared Runner
To view the IP address of a shared Runner you must have admin access to
the GitLab instance. To determine this:
-1. Visit **Admin Area > Overview > Runners**
-1. Look for the Runner in the table and you should see a column for "IP Address"
+1. Visit **{admin}** **Admin Area > Overview > Runners**.
+1. Look for the Runner in the table and you should see a column for **IP Address**.
![shared Runner IP address](img/shared_runner_ip_address.png)
-### Specific Runners
+### Determine the IP address of a specific Runner
-You can find the IP address of a Runner for a specific project by:
+To can find the IP address of a Runner for a specific project,
+you must have Owner [permissions](../../user/permissions.md#project-members-permissions) for the project.
-1. Visit your project's **Settings > CI/CD**
-1. Find the Runner and click on it's ID which links you to the details page
-1. On the details page you should see a row for "IP Address"
+1. Go to the project's **{settings}** **Settings > CI/CD** and expand the **Runners** section.
+1. On the details page you should see a row for **IP Address**.
![specific Runner IP address](img/specific_runner_ip_address.png)
+
+## Use tags to limit the number of jobs using the Runner
+
+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.
+
+By tagging a Runner for the types of jobs it can handle, you can make sure
+shared Runners will [only run the jobs they are equipped to run](../yaml/README.md#tags).
+
+For instance, at GitLab we have Runners tagged with `rails` if they contain
+the appropriate dependencies to run Rails test suites.
+
+When you [register a Runner](https://docs.gitlab.com/runner/register/), its default behavior is to **only pick**
+[tagged jobs](../yaml/README.md#tags).
+To change this, you must have Owner [permissions](../../user/permissions.md#project-members-permissions) for the project.
+
+To make a Runner pick untagged jobs:
+
+1. Go to the project's **{settings}** **Settings > CI/CD** and expand the **Runners** section.
+1. Find the Runner you want to pick untagged jobs and make sure it's enabled.
+1. Click the pencil button.
+1. Check the **Run untagged jobs** option.
+1. Click the **Save changes** button for the changes to take effect.
+
+NOTE: **Note:**
+The Runner tags list can not be empty when it's not allowed to pick untagged jobs.
+
+Below are some example scenarios of different variations.
+
+### Runner runs only tagged jobs
+
+The following examples illustrate the potential impact of the Runner being set
+to run only tagged jobs.
+
+Example 1:
+
+1. The Runner is configured to run only tagged jobs and has the `docker` tag.
+1. A job that has a `hello` tag is executed and stuck.
+
+Example 2:
+
+1. The Runner is configured to run only tagged jobs and has the `docker` tag.
+1. A job that has a `docker` tag is executed and run.
+
+Example 3:
+
+1. The Runner is configured to run only tagged jobs and has the `docker` tag.
+1. A job that has no tags defined is executed and stuck.
+
+### Runner is allowed to run untagged jobs
+
+The following examples illustrate the potential impact of the Runner being set
+to run tagged and untagged jobs.
+
+Example 1:
+
+1. The Runner is configured to run untagged jobs and has the `docker` tag.
+1. A job that has no tags defined is executed and run.
+1. A second job that has a `docker` tag defined is executed and run.
+
+Example 2:
+
+1. The Runner is configured to run untagged jobs and has no tags defined.
+1. A job that has no tags defined is executed and run.
+1. A second job that has a `docker` tag defined is stuck.
diff --git a/doc/ci/services/README.md b/doc/ci/services/README.md
index 7fe12eb53e7..fda453b7aa0 100644
--- a/doc/ci/services/README.md
+++ b/doc/ci/services/README.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+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/#designated-technical-writers
comments: false
type: index
---
diff --git a/doc/ci/services/mysql.md b/doc/ci/services/mysql.md
index dcfd863709e..1b017111d22 100644
--- a/doc/ci/services/mysql.md
+++ b/doc/ci/services/mysql.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+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/#designated-technical-writers
type: reference
---
@@ -43,7 +46,7 @@ Database: <your_mysql_database>
If you are wondering why we used `mysql` for the `Host`, read more at
[How services are linked to the job](../docker/using_docker_images.md#how-services-are-linked-to-the-job).
-You can also use any other docker image available on [Docker Hub](https://hub.docker.com/_/mysql/).
+You can also use any other Docker image available on [Docker Hub](https://hub.docker.com/_/mysql/).
For example, to use MySQL 5.5 the service becomes `mysql:5.5`.
The `mysql` image can accept some environment variables. For more details
diff --git a/doc/ci/services/postgres.md b/doc/ci/services/postgres.md
index 2f92bd969ff..aadbce5a50a 100644
--- a/doc/ci/services/postgres.md
+++ b/doc/ci/services/postgres.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+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/#designated-technical-writers
type: reference
---
@@ -45,7 +48,7 @@ Database: nice_marmot
If you are wondering why we used `postgres` for the `Host`, read more at
[How services are linked to the job](../docker/using_docker_images.md#how-services-are-linked-to-the-job).
-You can also use any other docker image available on [Docker Hub](https://hub.docker.com/_/postgres).
+You can also use any other Docker image available on [Docker Hub](https://hub.docker.com/_/postgres).
For example, to use PostgreSQL 9.3 the service becomes `postgres:9.3`.
The `postgres` image can accept some environment variables. For more details
diff --git a/doc/ci/services/redis.md b/doc/ci/services/redis.md
index f22ee87a9d3..193f78f240b 100644
--- a/doc/ci/services/redis.md
+++ b/doc/ci/services/redis.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+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/#designated-technical-writers
type: reference
---
@@ -30,7 +33,7 @@ Host: redis
And that's it. Redis will now be available to be used within your testing
framework.
-You can also use any other docker image available on [Docker Hub](https://hub.docker.com/_/redis).
+You can also use any other Docker image available on [Docker Hub](https://hub.docker.com/_/redis).
For example, to use Redis 2.8 the service becomes `redis:2.8`.
## Use Redis with the Shell executor
diff --git a/doc/ci/ssh_keys/README.md b/doc/ci/ssh_keys/README.md
index 16e87e92a07..4ad4758b281 100644
--- a/doc/ci/ssh_keys/README.md
+++ b/doc/ci/ssh_keys/README.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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
last_updated: 2017-12-13
type: tutorial
---
diff --git a/doc/ci/triggers/README.md b/doc/ci/triggers/README.md
index db3d2352f09..c6ac87ef888 100644
--- a/doc/ci/triggers/README.md
+++ b/doc/ci/triggers/README.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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: tutorial
---
@@ -20,7 +23,7 @@ The following methods of authentication are supported:
- [Trigger token](#trigger-token)
- [CI job token](#ci-job-token)
-If using the `$CI_PIPELINE_SOURCE` [predefined environment variable](../variables/predefined_variables.md#variables-reference)
+If using the `$CI_PIPELINE_SOURCE` [predefined environment variable](../variables/predefined_variables.md)
to limit which jobs run in a pipeline, the value could be either `pipeline` or `trigger`,
depending on which trigger method is used.
@@ -49,7 +52,7 @@ with the [GitLab Container Registry](../../user/packages/container_registry/inde
#### 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.
+> - 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
diff --git a/doc/ci/variables/README.md b/doc/ci/variables/README.md
index 3e31a2169e2..541e739082f 100644
--- a/doc/ci/variables/README.md
+++ b/doc/ci/variables/README.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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
---
@@ -17,6 +20,13 @@ that can be reused in different scripts.
Variables are useful for customizing your jobs in GitLab CI/CD.
When you use variables, you don't have to hard-code values.
+> 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/)
+> shared by GitLab engineers.
+> - <i class="fa fa-youtube-play youtube" aria-hidden="true"></i>&nbsp;Learn how the Cloud Native Computing Foundation (CNCF) [eliminates the complexity](https://about.gitlab.com/customers/cncf/)
+> of managing projects across many cloud providers with GitLab CI/CD.
+
## Predefined environment variables
GitLab CI/CD has a [default set of predefined variables](predefined_variables.md)
@@ -106,7 +116,7 @@ From within the UI, you can add or update custom environment variables:
1. Go to your project's **Settings > CI/CD** and expand the **Variables** section.
1. Click the **Add Variable** button. In the **Add variable** modal, fill in the details:
- - **Key**: Must be one line, with no spaces, using only letters, numbers, `-` or `_`.
+ - **Key**: Must be one line, with no spaces, using only letters, numbers, or `_`.
- **Value**: No limitations.
- **Type**: `File` or `Variable`.
- **Environment scope**: `All`, or specific environments.
@@ -133,7 +143,7 @@ The output will be:
### Custom environment variables of type Variable
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/46806) in GitLab 11.11.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/46806) in GitLab 11.11.
For variables with the type **Variable**, the Runner creates an environment variable
that uses the key for the name and the value for the value.
@@ -143,13 +153,13 @@ which may be further validated. They appear when you add or update a variable in
### Custom environment variables of type File
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/46806) in GitLab 11.11.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/46806) in GitLab 11.11.
For variables with the type **File**, the Runner creates an environment variable that uses the key for the name.
For the value, the Runner writes the variable value to a temporary file and uses this path.
You can use tools like [the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html)
-and [kubectl](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/#the-kubeconfig-environment-variable)
+and [`kubectl`](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/#the-kubeconfig-environment-variable)
to customize your configuration by using **File** type variables.
In the past, a common pattern was to read the value of a CI variable, save it in a file, and then
@@ -175,7 +185,7 @@ kubectl config set-cluster e2e --server="$KUBE_URL" --certificate-authority="$KU
### Mask a custom variable
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/13784) in GitLab 11.10
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/13784) in GitLab 11.10
Variables can be masked so that the value of the variable will be hidden in job logs.
@@ -195,7 +205,7 @@ The value of the variable must:
- Be at least 8 characters long.
- Not be a predefined or custom environment variable.
- Consist only of characters from the Base64 alphabet (RFC4648).
- [In GitLab 12.2](https://gitlab.com/gitlab-org/gitlab-foss/issues/63043)
+ [In GitLab 12.2](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/63043)
and newer, `@` and `:` are also valid values.
You can't mask variables that don't meet these requirements.
@@ -242,13 +252,15 @@ In most cases `bash` or `sh` is used to execute the job script.
To access environment variables, use the syntax for your Runner's [shell](https://docs.gitlab.com/runner/executors/).
-| Shell | Usage |
-|----------------------|-----------------|
-| bash/sh | `$variable` |
-| windows batch | `%variable%` |
-| PowerShell | `$env:variable` |
+| Shell | Usage |
+|----------------------|------------------------------------------|
+| bash/sh | `$variable` |
+| PowerShell | `$env:variable` (primary) or `$variable` |
+| Windows Batch | `%variable%` |
+
+### Bash
-To access environment variables in bash, prefix the variable name with (`$`):
+To access environment variables in **bash**, prefix the variable name with (`$`):
```yaml
job_name:
@@ -256,32 +268,54 @@ job_name:
- echo $CI_JOB_ID
```
-To access environment variables in **Windows Batch**, surround the variable
-with (`%`):
+### PowerShell
+
+To access environment variables in a **Windows PowerShell** environment, prefix
+the variable name with (`$env:`). For environment variables set by GitLab CI, including those set by [`variables`](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/ci/yaml/README.md#variables)
+parameter, they can also be accessed by prefixing the variable name with (`$`)
+as of [GitLab Runner 1.0.0](https://gitlab.com/gitlab-org/gitlab-runner/-/commit/abc44bb158008cd3a49c0d8173717c38dadb29ae#47afd7e8f12afdb8f0246262488f24e6dd071a22).
+System set environment variables however must be accessed using (`$env:`).
```yaml
job_name:
script:
- - echo %CI_JOB_ID%
+ - echo $env:CI_JOB_ID
+ - echo $CI_JOB_ID
+ - echo $env:PATH
```
-To access environment variables in a **Windows PowerShell** environment, prefix
-the variable name with (`$env:`):
+In [some cases](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4115#note_157692820)
+environment variables may need to be surrounded by quotes to expand properly:
```yaml
job_name:
script:
- - echo $env:CI_JOB_ID
+ - D:\\qislsf\\apache-ant-1.10.5\\bin\\ant.bat "-DsosposDailyUsr=$env:SOSPOS_DAILY_USR" portal_test
```
-You can also list all environment variables with the `export` command,
-but be aware that this will also expose the values of all the variables
+### Windows Batch
+
+To access environment variables in **Windows Batch**, surround the variable
+with (`%`):
+
+```yaml
+job_name:
+ script:
+ - echo %CI_JOB_ID%
+```
+
+### List all environment variables
+
+You can also list all environment variables with the `export` command in Bash
+or `dir env:` command in PowerShell.
+Be aware that this will also expose the values of all the variables
you set, in the job log:
```yaml
job_name:
script:
- export
+ # - 'dir env:' # use this for PowerShell
```
Example values:
@@ -377,9 +411,8 @@ script:
You can define per-project or per-group variables
that are set in the pipeline environment. Group-level variables are stored out of
-the repository (not in `.gitlab-ci.yml`) and are securely passed to GitLab Runner
-making them available during a pipeline run. It's the **recommended method** to
-use for storing things like passwords, SSH keys, and credentials.
+the repository (not in `.gitlab-ci.yml`) and are securely passed to GitLab Runner,
+which makes them available during a pipeline run. For Premium users who do **not** use an external key store or who use GitLab's [integration with HashiCorp Vault](../examples/authenticating-with-hashicorp-vault/index.md), we recommend using group environment variables to store secrets like passwords, SSH keys, and credentials.
Group-level variables can be added by:
@@ -394,10 +427,55 @@ Once you set them, they will be available for all subsequent pipelines. Any grou
![CI/CD settings - inherited variables](img/inherited_group_variables_v12_5.png)
-### Inherit environment variables
+## Instance-level CI/CD environment variables
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14108) in GitLab 13.0.
+
+Instance variables are useful for no longer needing to manually enter the same credentials repeatedly for all your projects. Instance-level variables are available to all projects and groups on the instance.
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22638) in GitLab 13.0.
-> - It's deployed behind a feature flag (`ci_dependency_variables`), disabled by default.
+NOTE: **Note:**
+The maximum number of instance-level variables is [planned to be 25](https://gitlab.com/gitlab-org/gitlab/-/issues/216097).
+
+You can define instance-level variables via the UI or [API](../../api/instance_level_ci_variables.md).
+
+To add an instance-level variable:
+
+1. Navigate to your admin area's **Settings > CI/CD** and expand the **Variables** section.
+1. Click the **Add variable** button, and fill in the details:
+
+ - **Key**: Must be one line, using only letters, numbers, or `_` (underscore), with no spaces.
+ - **Value**: 700 characters allowed.
+ - **Type**: `File` or `Variable`.
+ - **Protect variable** (Optional): If selected, the variable will only be available in pipelines that run on protected branches or tags.
+ - **Mask variable** (Optional): If selected, the variable's **Value** will not be shown in job logs. The variable will not be saved if the value does not meet the [masking requirements](#masked-variable-requirements).
+
+After a variable is created, you can update any of the details by clicking the **{pencil}** **Edit** button.
+
+### Enable or disable UI interface for instance-level CI/CD variables
+
+The UI interface for Instance-level CI/CD variables 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 for your instance.
+
+NOTE: **Note:**
+This feature will not work if the [instance-level CI/CD variables API feature flag is disabled](../../api/instance_level_ci_variables.md#enable-or-disable-instance-level-cicd-variables-core-only).
+
+To disable it:
+
+```ruby
+Feature.disable(:instance_variables_ui)
+```
+
+To enable it:
+
+```ruby
+Feature.enable(:instance_variables_ui)
+```
+
+## Inherit environment variables
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22638) in GitLab 13.0 behind a disabled [feature flag](../../administration/feature_flags.md): `ci_dependency_variables`.
+> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/217834) in GitLab 13.1.
You can inherit environment variables from dependent jobs.
@@ -442,25 +520,6 @@ deploy:
artifacts: true
```
-### Enable inherited environment variables **(CORE ONLY)**
-
-The Inherited Environment Variables feature 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 for your instance.
-
-To enable it:
-
-```ruby
-Feature.enable(:ci_dependency_variables)
-```
-
-To disable it:
-
-```ruby
-Feature.disable(:ci_dependency_variables)
-```
-
## Priority of environment variables
Variables of different types can take precedence over other
@@ -468,7 +527,8 @@ variables, depending on where they are defined.
The order of precedence for variables is (from highest to lowest):
-1. [Trigger variables](../triggers/README.md#making-use-of-trigger-variables) or [scheduled pipeline variables](../pipelines/schedules.md#using-variables).
+1. [Trigger variables](../triggers/README.md#making-use-of-trigger-variables), [scheduled pipeline variables](../pipelines/schedules.md#using-variables),
+ and [manual pipeline run variables](#override-a-variable-by-manually-running-a-pipeline).
1. Project-level [variables](#custom-environment-variables) or [protected variables](#protect-a-custom-variable).
1. Group-level [variables](#group-level-environment-variables) or [protected variables](#protect-a-custom-variable).
1. [Inherited environment variables](#inherit-environment-variables).
@@ -487,8 +547,10 @@ variables take precedence over those defined in `.gitlab-ci.yml`.
## Unsupported variables
-There are cases where some variables cannot be used in the context of a
-`.gitlab-ci.yml` definition (for example under `script`). Read more about which variables are [not supported](where_variables_can_be_used.md).
+Variable names are limited by the underlying shell used to execute scripts (see [available shells](https://docs.gitlab.com/runner/shells/index.html).
+Each shell has its own unique set of reserved variable names.
+You will also want to keep in mind the [scope of environment variables](where_variables_can_be_used.md) to ensure a variable is defined in the scope
+in which you wish to use it.
## Where variables can be used
@@ -518,7 +580,7 @@ An example integration that defines deployment variables is the
### Auto DevOps environment variables
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/49056) in GitLab 11.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/49056) in GitLab 11.7.
You can configure [Auto DevOps](../../topics/autodevops/index.md) to
pass CI variables to the running application by prefixing the key of the
@@ -530,12 +592,12 @@ then be available as environment variables on the running application
container.
CAUTION: **Caution:**
-Variables with multiline values are not currently supported due to
+Variables with multi-line values are not currently supported due to
limitations with the current Auto DevOps scripting environment.
### Override a variable by manually running a pipeline
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/44059) in GitLab 10.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/44059) in GitLab 10.8.
You can override the value of a current variable by
[running a pipeline manually](../pipelines/index.md#run-a-pipeline-manually).
@@ -555,8 +617,8 @@ value for this specific pipeline.
## Environment variables expressions
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/37397) in GitLab 10.7 for [the `only` and `except` CI keywords](../yaml/README.md#onlyexcept-advanced)
-> - [Expanded](https://gitlab.com/gitlab-org/gitlab/issues/27863) in GitLab 12.3 with [the `rules` keyword](../yaml/README.md#rules)
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/37397) in GitLab 10.7 for [the `only` and `except` CI keywords](../yaml/README.md#onlyexcept-advanced)
+> - [Expanded](https://gitlab.com/gitlab-org/gitlab/-/issues/27863) in GitLab 12.3 with [the `rules` keyword](../yaml/README.md#rules)
Use variable expressions to limit which jobs are created
within a pipeline after changes are pushed to GitLab.
@@ -612,8 +674,8 @@ Below you can find supported syntax reference:
It sometimes happens that you want to check whether a variable is defined
or not. To do that, you can compare a variable to `null` keyword, like
- `$VARIABLE == null`. This expression is going to evaluate to truth if
- variable is not defined when `==` is used, or to falsey if `!=` is used.
+ `$VARIABLE == null`. This expression evaluates to true if
+ variable is not defined when `==` is used, or to false if `!=` is used.
1. Checking for an empty variable
@@ -644,7 +706,7 @@ Below you can find supported syntax reference:
which means that it is defined and non-empty, you can simply use
variable name as an expression, like `$STAGING`. If `$STAGING` variable
is defined, and is non empty, expression will evaluate to truth.
- `$STAGING` value needs to a string, with length higher than zero.
+ `$STAGING` value needs to be a string, with length higher than zero.
Variable that contains only whitespace characters is not an empty variable.
1. Pattern matching (introduced in GitLab 11.0)
@@ -652,7 +714,7 @@ Below you can find supported syntax reference:
Examples:
- `=~`: True if pattern is matched. Ex: `$VARIABLE =~ /^content.*/`
- - `!~`: True if pattern is not matched. Ex: `$VARIABLE_1 !~ /^content.*/` ([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/61900) in GitLab 11.11)
+ - `!~`: True if pattern is not matched. Ex: `$VARIABLE_1 !~ /^content.*/` ([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/61900) in GitLab 11.11)
Variable pattern matching with regular expressions uses the
[RE2 regular expression syntax](https://github.com/google/re2/wiki/Syntax).
@@ -694,7 +756,7 @@ deploy_staging:
```
NOTE: **Note:**
-The available regular expression syntax is limited. See [related issue](https://gitlab.com/gitlab-org/gitlab/issues/35438)
+The available regular expression syntax is limited. See [related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/35438)
for more details.
If needed, you can use a test pipeline to determine whether a regular expression will
diff --git a/doc/ci/variables/deprecated_variables.md b/doc/ci/variables/deprecated_variables.md
index 543da481938..94ec8439605 100644
--- a/doc/ci/variables/deprecated_variables.md
+++ b/doc/ci/variables/deprecated_variables.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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/variables/img/ci_job_stage_output_example.png b/doc/ci/variables/img/ci_job_stage_output_example.png
index e333da57121..2344b19d9b3 100644
--- a/doc/ci/variables/img/ci_job_stage_output_example.png
+++ b/doc/ci/variables/img/ci_job_stage_output_example.png
Binary files differ
diff --git a/doc/ci/variables/img/inherited_group_variables_v12_5.png b/doc/ci/variables/img/inherited_group_variables_v12_5.png
index a13ba711083..cce024cfab8 100644
--- a/doc/ci/variables/img/inherited_group_variables_v12_5.png
+++ b/doc/ci/variables/img/inherited_group_variables_v12_5.png
Binary files differ
diff --git a/doc/ci/variables/img/override_value_via_manual_pipeline_output.png b/doc/ci/variables/img/override_value_via_manual_pipeline_output.png
index 8a13bb3849e..2d4c4d24520 100644
--- a/doc/ci/variables/img/override_value_via_manual_pipeline_output.png
+++ b/doc/ci/variables/img/override_value_via_manual_pipeline_output.png
Binary files differ
diff --git a/doc/ci/variables/img/override_variable_manual_pipeline.png b/doc/ci/variables/img/override_variable_manual_pipeline.png
index de768105aec..2b242466297 100644
--- a/doc/ci/variables/img/override_variable_manual_pipeline.png
+++ b/doc/ci/variables/img/override_variable_manual_pipeline.png
Binary files differ
diff --git a/doc/ci/variables/predefined_variables.md b/doc/ci/variables/predefined_variables.md
index d4d3a13bb2a..8463bbeb582 100644
--- a/doc/ci/variables/predefined_variables.md
+++ b/doc/ci/variables/predefined_variables.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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
---
@@ -7,8 +10,6 @@ type: reference
For an introduction on this subject, read through the
[getting started with environment variables](README.md) document.
-## Overview
-
Some of the predefined environment variables are available only if a minimum
version of [GitLab Runner](https://docs.gitlab.com/runner/) is used. Consult the table below to find the
version of Runner required.
@@ -19,7 +20,8 @@ Starting with GitLab 9.0, we have deprecated some variables. Read the
strongly advised to use the new variables as we will remove the old ones in
future GitLab releases.**
-## Variables reference
+You can add a command to your `.gitlab-ci.yml` file to
+[output the values of all variables available for a job](README.md#list-all-environment-variables).
| Variable | GitLab | Runner | Description |
|-----------------------------------------------|--------|--------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
@@ -42,7 +44,7 @@ future GitLab releases.**
| `CI_COMMIT_TITLE` | 10.8 | all | The title of the commit - the full first line of the message |
| `CI_CONCURRENT_ID` | all | 11.10 | Unique ID of build execution within a single executor. |
| `CI_CONCURRENT_PROJECT_ID` | all | 11.10 | Unique ID of build execution within a single executor and project. |
-| `CI_CONFIG_PATH` | 9.4 | 0.5 | The path to CI config file. Defaults to `.gitlab-ci.yml` |
+| `CI_CONFIG_PATH` | 9.4 | 0.5 | The path to CI configuration file. Defaults to `.gitlab-ci.yml` |
| `CI_DEBUG_TRACE` | all | 1.7 | Whether [debug logging (tracing)](README.md#debug-logging) is enabled |
| `CI_DEFAULT_BRANCH` | 12.4 | all | The name of the default branch for the project. |
| `CI_DEPLOY_PASSWORD` | 10.8 | all | Authentication password of the [GitLab Deploy Token](../../user/project/deploy_tokens/index.md#gitlab-deploy-token), only present if the Project has one related. |
@@ -56,18 +58,17 @@ future GitLab releases.**
| `CI_EXTERNAL_PULL_REQUEST_SOURCE_BRANCH_SHA` | 12.3 | all | The HEAD SHA of the source branch of the pull request if [the pipelines are for external pull requests](../ci_cd_for_external_repos/index.md#pipelines-for-external-pull-requests). Available only if `only: [external_pull_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the pull request is open. |
| `CI_EXTERNAL_PULL_REQUEST_TARGET_BRANCH_NAME` | 12.3 | all | The target branch name of the pull request if [the pipelines are for external pull requests](../ci_cd_for_external_repos/index.md#pipelines-for-external-pull-requests). Available only if `only: [external_pull_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the pull request is open. |
| `CI_EXTERNAL_PULL_REQUEST_TARGET_BRANCH_SHA` | 12.3 | all | The HEAD SHA of the target branch of the pull request if [the pipelines are for external pull requests](../ci_cd_for_external_repos/index.md#pipelines-for-external-pull-requests). Available only if `only: [external_pull_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the pull request is open. |
+| `CI_HAS_OPEN_REQUIREMENTS` | 13.1 | all | Included with the value `true` only if the pipeline's project has any open [requirements](../../user/project/requirements/index.md). Not included if there are no open requirements for the pipeline's project. |
| `CI_JOB_ID` | 9.0 | all | The unique ID of the current job that GitLab CI/CD uses internally |
| `CI_JOB_IMAGE` | 12.9 | 12.9 | The name of the image running the CI job |
| `CI_JOB_MANUAL` | 8.12 | all | The flag to indicate that job was manually started |
| `CI_JOB_NAME` | 9.0 | 0.5 | The name of the job as defined in `.gitlab-ci.yml` |
| `CI_JOB_STAGE` | 9.0 | 0.5 | The name of the stage as defined in `.gitlab-ci.yml` |
-| `CI_JOB_TOKEN` | 9.0 | 1.2 | Token used for authenticating with the [GitLab Container Registry](../../user/packages/container_registry/index.md) and downloading [dependent repositories](../../user/project/new_ci_build_permissions_model.md#dependent-repositories) |
+| `CI_JOB_TOKEN` | 9.0 | 1.2 | Token used for authenticating with the [GitLab Container Registry](../../user/packages/container_registry/index.md), downloading [dependent repositories](../../user/project/new_ci_build_permissions_model.md#dependent-repositories), and accessing [GitLab-managed Terraform state](../../user/infrastructure/index.md#gitlab-managed-terraform-state). |
| `CI_JOB_JWT` | 12.10 | all | RS256 JSON web token that can be used for authenticating with third party systems that support JWT authentication, for example [HashiCorp's Vault](../examples/authenticating-with-hashicorp-vault). |
| `CI_JOB_URL` | 11.1 | 0.5 | Job details URL |
-| `CI_KUBERNETES_ACTIVE` | 13.0 | all | Included with the value `true` only if the pipeline has a Kubernetes cluster available for deployments. Not included if no cluster is availble. Can be used as an alternative to [`only:kubernetes`/`except:kubernetes`](../yaml/README.md#onlykubernetesexceptkubernetes) with [`rules:if`](../yaml/README.md#rulesif) |
+| `CI_KUBERNETES_ACTIVE` | 13.0 | all | Included with the value `true` only if the pipeline has a Kubernetes cluster available for deployments. Not included if no cluster is available. Can be used as an alternative to [`only:kubernetes`/`except:kubernetes`](../yaml/README.md#onlykubernetesexceptkubernetes) with [`rules:if`](../yaml/README.md#rulesif) |
| `CI_MERGE_REQUEST_ASSIGNEES` | 11.9 | all | Comma-separated list of username(s) of assignee(s) for the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the merge request is created. |
-| `CI_MERGE_REQUEST_CHANGED_PAGE_PATHS` | 12.9 | all | Comma-separated list of paths of changed pages in a deployed [Review App](../review_apps/index.md) for a [Merge Request](../merge_request_pipelines/index.md). A [Route Map](../review_apps/index.md#route-maps) must be configured. |
-| `CI_MERGE_REQUEST_CHANGED_PAGE_URLS` | 12.9 | all | Comma-separated list of URLs of changed pages in a deployed [Review App](../review_apps/index.md) for a [Merge Request](../merge_request_pipelines/index.md). A [Route Map](../review_apps/index.md#route-maps) must be configured. |
| `CI_MERGE_REQUEST_ID` | 11.6 | all | The ID of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the merge request is created. |
| `CI_MERGE_REQUEST_IID` | 11.6 | all | The IID of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the merge request is created. |
| `CI_MERGE_REQUEST_LABELS` | 11.9 | all | Comma-separated label names of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the merge request is created. |
@@ -97,7 +98,7 @@ future GitLab releases.**
| `CI_PROJECT_DIR` | all | all | The full path where the repository is cloned and where the job is run. If the GitLab Runner `builds_dir` parameter is set, this variable is set relative to the value of `builds_dir`. For more information, see [Advanced configuration](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runners-section) for GitLab Runner. |
| `CI_PROJECT_ID` | all | all | The unique ID of the current project that GitLab CI/CD uses internally |
| `CI_PROJECT_NAME` | 8.10 | 0.5 | The name of the directory for the project that is currently being built. For example, if the project URL is `gitlab.example.com/group-name/project-1`, the `CI_PROJECT_NAME` would be `project-1`. |
-| `CI_PROJECT_NAMESPACE` | 8.10 | 0.5 | The project namespace (username or groupname) that is currently being built |
+| `CI_PROJECT_NAMESPACE` | 8.10 | 0.5 | The project namespace (username or group name) that is currently being built |
| `CI_PROJECT_PATH` | 8.10 | 0.5 | The namespace with project name |
| `CI_PROJECT_PATH_SLUG` | 9.3 | all | `$CI_PROJECT_PATH` lowercased and with everything except `0-9` and `a-z` replaced with `-`. Use in URLs and domain names. |
| `CI_PROJECT_REPOSITORY_LANGUAGES` | 12.3 | all | Comma-separated, lowercased list of the languages used in the repository (e.g. `ruby,javascript,html,css`) |
diff --git a/doc/ci/variables/where_variables_can_be_used.md b/doc/ci/variables/where_variables_can_be_used.md
index 0c40ac960e5..2f26fddc808 100644
--- a/doc/ci/variables/where_variables_can_be_used.md
+++ b/doc/ci/variables/where_variables_can_be_used.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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
---
@@ -72,10 +75,10 @@ ordering of variables definitions.
### Execution shell environment
This is an expansion that takes place during the `script` execution.
-How it works depends on the used shell (bash/sh/cmd/PowerShell). For example, if the job's
+How it works depends on the used shell (`bash`, `sh`, `cmd`, PowerShell). For example, if the job's
`script` contains a line `echo $MY_VARIABLE-${MY_VARIABLE_2}`, it should be properly handled
by bash/sh (leaving empty strings or some values depending whether the variables were
-defined or not), but will not work with Windows' cmd/PowerShell, since these shells
+defined or not), but will not work with Windows' `cmd` or PowerShell, since these shells
are using a different variables syntax.
Supported:
diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md
index c40580cbfb7..7ed5a8fec01 100644
--- a/doc/ci/yaml/README.md
+++ b/doc/ci/yaml/README.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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
---
@@ -22,6 +25,14 @@ We have complete examples of configuring pipelines:
- For a collection of examples, see [GitLab CI/CD Examples](../examples/README.md).
- To see a large `.gitlab-ci.yml` file used in an enterprise, see the [`.gitlab-ci.yml` file for `gitlab`](https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab-ci.yml).
+> For some additional information about GitLab CI/CD:
+>
+> - <i class="fa fa-youtube-play youtube" aria-hidden="true"></i>&nbsp;Watch the [CI/CD Ease of configuration](https://www.youtube.com/embed/opdLqwz6tcE) video.
+> - Watch the [Making the case for CI/CD in your organization](https://about.gitlab.com/compare/github-actions-alternative/)
+> webcast to learn the benefits of CI/CD and how to measure the results of CI/CD automation.
+> - <i class="fa fa-youtube-play youtube" aria-hidden="true"></i>&nbsp;Learn how [Verizon reduced rebuilds](https://about.gitlab.com/blog/2019/02/14/verizon-customer-story/)
+> from 30 days to under 8 hours with GitLab.
+
NOTE: **Note:**
If you have a [mirrored repository where GitLab pulls from](../../user/project/repository/repository_mirroring.md#pulling-from-a-remote-repository-starter),
you may need to enable pipeline triggering in your project's
@@ -93,8 +104,8 @@ The following table lists available parameters for jobs:
| Keyword | Description |
|:---------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [`script`](#script) | Shell script which is executed by Runner. |
-| [`image`](#image) | Use docker images. Also available: `image:name` and `image:entrypoint`. |
-| [`services`](#services) | Use docker services images. Also available: `services:name`, `services:alias`, `services:entrypoint`, and `services:command`. |
+| [`image`](#image) | Use Docker images. Also available: `image:name` and `image:entrypoint`. |
+| [`services`](#services) | Use Docker services images. Also available: `services:name`, `services:alias`, `services:entrypoint`, and `services:command`. |
| [`before_script`](#before_script-and-after_script) | Override a set of commands that are executed before job. |
| [`after_script`](#before_script-and-after_script) | Override a set of commands that are executed after job. |
| [`stage`](#stage) | Defines a job stage (default: `test`). |
@@ -106,7 +117,7 @@ The following table lists available parameters for jobs:
| [`when`](#when) | When to run job. Also available: `when:manual` and `when:delayed`. |
| [`environment`](#environment) | Name of an environment to which the job deploys. Also available: `environment:name`, `environment:url`, `environment:on_stop`, `environment:auto_stop_in` and `environment:action`. |
| [`cache`](#cache) | List of files that should be cached between subsequent runs. Also available: `cache:paths`, `cache:key`, `cache:untracked`, and `cache:policy`. |
-| [`artifacts`](#artifacts) | List of files and directories to attach to a job on success. Also available: `artifacts:paths`, `artifacts:expose_as`, `artifacts:name`, `artifacts:untracked`, `artifacts:when`, `artifacts:expire_in`, `artifacts:reports`, `artifacts:reports:junit`, `artifacts:reports:cobertura`, and `artifacts:reports:terraform`.<br><br>In GitLab [Enterprise Edition](https://about.gitlab.com/pricing/), these are available: `artifacts:reports:codequality`, `artifacts:reports:sast`, `artifacts:reports:dependency_scanning`, `artifacts:reports:container_scanning`, `artifacts:reports:dast`, `artifacts:reports:license_scanning`, `artifacts:reports:license_management` (removed in GitLab 13.0),`artifacts:reports:performance` and `artifacts:reports:metrics`. |
+| [`artifacts`](#artifacts) | List of files and directories to attach to a job on success. Also available: `artifacts:paths`, `artifacts:exclude`, `artifacts:expose_as`, `artifacts:name`, `artifacts:untracked`, `artifacts:when`, `artifacts:expire_in`, `artifacts:reports`, `artifacts:reports:junit`, `artifacts:reports:cobertura`, and `artifacts:reports:terraform`.<br><br>In GitLab [Enterprise Edition](https://about.gitlab.com/pricing/), these are available: `artifacts:reports:codequality`, `artifacts:reports:sast`, `artifacts:reports:dependency_scanning`, `artifacts:reports:container_scanning`, `artifacts:reports:dast`, `artifacts:reports:license_scanning`, `artifacts:reports:license_management` (removed in GitLab 13.0),`artifacts:reports:performance` and `artifacts:reports:metrics`. |
| [`dependencies`](#dependencies) | Restrict which artifacts are passed to a specific job by providing a list of jobs to fetch artifacts from. |
| [`coverage`](#coverage) | Code coverage settings for a given job. |
| [`retry`](#retry) | When and how many times a job can be auto-retried in case of a failure. |
@@ -163,7 +174,7 @@ rspec 2.6:
#### `inherit`
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/207484) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/207484) in GitLab 12.9.
You can disable inheritance of globally defined defaults
and variables with the `inherit:` parameter.
@@ -279,7 +290,7 @@ There are also two edge cases worth mentioning:
### `workflow:rules`
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/29654) in GitLab 12.5
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/29654) in GitLab 12.5
The top-level `workflow:` key applies to the entirety of a pipeline, and will
determine whether or not a pipeline is created. It currently accepts a single
@@ -310,7 +321,6 @@ include:
- template: 'Workflows/Branch-Pipelines.gitlab-ci.yml'
```
-The [`MergeRequest-Pipelines` include](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates/Workflows/MergeRequest-Pipelines.gitlab-ci.yml) sets your pipelines to run for the default branch (usually `master`), tags, and
The [`MergeRequest-Pipelines` template](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates/Workflows/MergeRequest-Pipelines.gitlab-ci.yml)
makes your pipelines run for the default branch (usually `master`), tags, and
all types of merge request pipelines. Use this template if you use any of the
@@ -418,7 +428,7 @@ include: '.gitlab-ci-production.yml'
#### `include:file`
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/53903) in GitLab 11.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53903) in GitLab 11.7.
To include files from another private project under the same GitLab instance,
use `include:file`. This file is referenced using full paths relative to the
@@ -468,7 +478,7 @@ or public project, or template, is allowed.
#### `include:template`
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/53445) in GitLab 11.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53445) in GitLab 11.7.
`include:template` can be used to include `.gitlab-ci.yml` templates that are
[shipped with GitLab](https://gitlab.com/gitlab-org/gitlab/tree/master/lib/gitlab/ci/templates).
@@ -494,13 +504,13 @@ so it's possible to use project, remote or template includes.
#### Nested includes
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/56836) in GitLab 11.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/56836) in GitLab 11.9.
Nested includes allow you to compose a set of includes.
A total of 100 includes is allowed, but duplicate includes are considered a configuration error.
-Since [GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/issues/28212), the time limit
+Since [GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/-/issues/28212), the time limit
for resolving all files is 30 seconds.
#### Additional `includes` examples
@@ -522,13 +532,13 @@ For:
#### `image:name`
-An [extended docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
+An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
For more information, see [Available settings for `image`](../docker/using_docker_images.md#available-settings-for-image).
#### `image:entrypoint`
-An [extended docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
+An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
For more information, see [Available settings for `image`](../docker/using_docker_images.md#available-settings-for-image).
@@ -544,25 +554,25 @@ For:
##### `services:name`
-An [extended docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
+An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
For more information, see [Available settings for `services`](../docker/using_docker_images.md#available-settings-for-services).
##### `services:alias`
-An [extended docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
+An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
For more information, see [Available settings for `services`](../docker/using_docker_images.md#available-settings-for-services).
##### `services:entrypoint`
-An [extended docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
+An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
For more information, see [Available settings for `services`](../docker/using_docker_images.md#available-settings-for-services).
##### `services:command`
-An [extended docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
+An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
For more information, see [Available settings for `services`](../docker/using_docker_images.md#available-settings-for-services).
@@ -628,7 +638,7 @@ Scripts specified in `after_script` are executed in a new shell, separate from a
- Changes outside of the working tree (depending on the Runner executor), like
software installed by a `before_script` or `script` script.
- Have a separate timeout, which is hard coded to 5 minutes. See
- [related issue](https://gitlab.com/gitlab-org/gitlab-runner/issues/2716) for details.
+ [related issue](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/2716) for details.
- Don't affect the job's exit code. If the `script` section succeeds and the
`after_script` times out or fails, the job will exit with code `0` (`Job Succeeded`).
@@ -651,6 +661,44 @@ job:
[YAML anchors for `before_script` and `after_script`](#yaml-anchors-for-before_script-and-after_script) are available.
+#### Coloring script output
+
+Script output can be colored using [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors),
+or by running commands or programs that output ANSI escape codes.
+
+For example, using [Bash with color codes](https://misc.flogisoft.com/bash/tip_colors_and_formatting):
+
+```yaml
+job:
+ script:
+ - echo -e "\e[31mThis text is red,\e[0m but this text isn't\e[31m however this text is red again."
+```
+
+You can define the color codes in Shell variables, or even [custom environment variables](../variables/README.md#custom-environment-variables),
+which makes the commands easier to read and reusable.
+
+For example, using the same example as above and variables defined in a `before_script`:
+
+```yaml
+job:
+ before_script:
+ - TXT_RED="\e[31m" && TXT_CLEAR="\e[0m"
+ script:
+ - echo -e "${TXT_RED}This text is red,${TXT_CLEAR} but this part isn't${TXT_RED} however this part is again."
+ - echo "This text is not colored"
+```
+
+Or with [PowerShell color codes](https://superuser.com/a/1259916):
+
+```yaml
+job:
+ before_script:
+ - $esc="$([char]27)"; $TXT_RED="$esc[31m"; $TXT_CLEAR="$esc[0m"
+ script:
+ - Write-Host $TXT_RED"This text is red,"$TXT_CLEAR" but this text isn't"$TXT_RED" however this text is red again."
+ - Write-Host "This text is not colored"
+```
+
### `stage`
`stage` is defined per-job and relies on [`stages`](#stages) which is defined
@@ -701,7 +749,7 @@ Jobs will run on your own Runners in parallel only if:
#### `.pre` and `.post`
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/31441) in GitLab 12.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/31441) in GitLab 12.4.
The following stages are available to every pipeline:
@@ -910,7 +958,7 @@ can use one of the [`workflow: rules` templates](#workflowrules-templates) to ge
This will ensure that the behavior is more stable as you start adding additional `rules`
blocks, and will avoid issues like creating a duplicate, merge request (detached) pipeline.
-We don't recomment mixing `only/except` jobs with `rules` jobs in the same pipeline.
+We don't recommend mixing `only/except` jobs with `rules` jobs in the same pipeline.
It may not cause YAML errors, but debugging the exact execution behavior can be complex
due to the different default behaviors of `only/except` and `rules`.
@@ -966,10 +1014,14 @@ job:
- if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME' # If neither of the first two match but the simple presence does, we set to "on_success" by default
```
-If none of the provided rules match, the job will be set to `when:never`, and
-not included in the pipeline. If `rules:when` is not included in the configuration
-at all, the behavior defaults to `job:when`, which continues to default to
-`on_success`.
+Some details regarding the logic that determines the `when` for the job:
+
+- If none of the provided rules match, the job is set to `when: never`, and is
+ not included in the pipeline.
+- A rule without any conditional clause, such as a `when` or `allow_failure`
+ rule without `if` or `changes`, always matches, and is always used if reached.
+- If a rule matches and has no `when` defined, the rule will use the `when`
+ defined for the job, which defaults to `on_success` if not defined.
#### `rules:changes`
@@ -1032,12 +1084,16 @@ checks. After the 10000th check, rules with patterned globs will always match.
#### `rules:allow_failure`
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/30235) in GitLab 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30235) in GitLab 12.8.
You can use [`allow_failure: true`](#allow_failure) within `rules:` to allow a job to fail, or a manual job to
wait for action, without stopping the pipeline itself. All jobs using `rules:` default to `allow_failure: false`
if `allow_failure:` is not defined.
+The rule-level `rules:allow_failure` option overrides the job-level
+[`allow_failure`](#allow_failure) option, and is only applied when the job is
+triggered by the particular rule.
+
```yaml
job:
script: "echo Hello, Rules!"
@@ -1111,7 +1167,7 @@ docker build:
Additional job configuration may be added to rules in the future. If something
useful is not available, please
-[open an issue](https://gitlab.com/gitlab-org/gitlab/issues).
+[open an issue](https://gitlab.com/gitlab-org/gitlab/-/issues).
### `only`/`except` (basic)
@@ -1402,7 +1458,7 @@ Learn more about [variables expressions](../variables/README.md#environment-vari
#### `only:changes`/`except:changes`
-> `changes` policy [introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/19232) in GitLab 11.4.
+> `changes` policy [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/19232) in GitLab 11.4.
Using the `changes` keyword with `only` or `except` makes it possible to define if
a job should be created based on files modified by a Git push event.
@@ -1414,7 +1470,7 @@ This means the `only:changes` policy is useful for pipelines where:
- `$CI_PIPELINE_SOURCE == 'external_pull_request_event'`
If there is no Git push event, such as for pipelines with
-[sources other than the three above](../variables/predefined_variables.md#variables-reference),
+[sources other than the three above](../variables/predefined_variables.md),
`changes` can't determine if a given file is new or old, and will always
return true.
@@ -1548,9 +1604,9 @@ runs.
### `needs`
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/47063) in GitLab 12.2.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/47063) in GitLab 12.2.
> - In GitLab 12.3, maximum number of jobs in `needs` array raised from five to 50.
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/30631) in GitLab 12.8, `needs: []` lets jobs start immediately.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30631) in GitLab 12.8, `needs: []` lets jobs start immediately.
The `needs:` keyword enables executing jobs out-of-order, allowing you to implement
a [directed acyclic graph](../directed_acyclic_graph/index.md) in your `.gitlab-ci.yml`.
@@ -1612,7 +1668,7 @@ This example creates four paths of execution:
pipeline will be created with YAML error.
- The maximum number of jobs that a single job can need in the `needs:` array is limited:
- For GitLab.com, the limit is ten. For more information, see our
- [infrastructure issue](https://gitlab.com/gitlab-com/gl-infra/infrastructure/issues/7541).
+ [infrastructure issue](https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues/7541).
- For self-managed instances, the limit is:
- 10, if the `ci_dag_limit_needs` feature flag is enabled (default).
- 50, if the `ci_dag_limit_needs` feature flag is disabled.
@@ -1620,7 +1676,7 @@ This example creates four paths of execution:
the current job will depend on all parallel jobs created.
- `needs:` is similar to `dependencies:` in that it needs to 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 support [is planned](https://gitlab.com/gitlab-org/gitlab/issues/30632).
+ current stage is not possible either, but support [is planned](https://gitlab.com/gitlab-org/gitlab/-/issues/30632).
- Related to the above, stages must be explicitly defined for all jobs
that have the keyword `needs:` or are referred to by one.
@@ -1643,7 +1699,7 @@ Feature::enable(:ci_dag_limit_needs)
#### 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 v12.6.
When using `needs`, artifact downloads are controlled with `artifacts: true` or `artifacts: false`.
The `dependencies` keyword should not be used with `needs`, as this is deprecated since GitLab 12.6.
@@ -1686,7 +1742,7 @@ rspec:
#### 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 v12.7.
`needs` can be used to download artifacts from up to five jobs in pipelines on
[other refs in the same project](#artifact-downloads-between-pipelines-in-the-same-project),
@@ -2142,9 +2198,15 @@ The `stop_review_app` job is **required** to have the following keywords defined
- `stage` should be the same as the `review_app` in order for the environment
to stop automatically when the branch is deleted
+Additionally, both jobs should have matching [`rules`](../yaml/README.md#onlyexcept-basic)
+or [`only/except`](../yaml/README.md#onlyexcept-basic) configuration. In the example
+above, if the configuration is not identical, the `stop_review_app` job might not be
+included in all pipelines that include the `review_app` job, and it will not be
+possible to trigger the `action: stop` to stop the environment automatically.
+
#### `environment:auto_stop_in`
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/20956) in GitLab 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/20956) in GitLab 12.8.
The `auto_stop_in` keyword is for specifying life period of the environment,
that when expired, GitLab automatically stops them.
@@ -2167,7 +2229,7 @@ For more information, see
#### `environment:kubernetes`
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/27630) in GitLab 12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27630) in GitLab 12.6.
The `kubernetes` block is used to configure deployments to a
[Kubernetes cluster](../../user/project/clusters/index.md) that is associated with your project.
@@ -2195,7 +2257,7 @@ NOTE: **Note:**
Kubernetes configuration is not supported for Kubernetes clusters
that are [managed by GitLab](../../user/project/clusters/index.md#gitlab-managed-clusters).
To follow progress on support for GitLab-managed clusters, see the
-[relevant issue](https://gitlab.com/gitlab-org/gitlab/issues/38054).
+[relevant issue](https://gitlab.com/gitlab-org/gitlab/-/issues/38054).
#### Dynamic environments
@@ -2336,7 +2398,7 @@ cache:
##### `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 v12.5.
The `cache:key:files` keyword extends the `cache:key` functionality by making it easier
to reuse some caches, and rebuild them less often, which will speed up subsequent pipeline
@@ -2366,7 +2428,7 @@ use the new cache, instead of rebuilding the dependencies.
##### `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 v12.5.
The `prefix` parameter adds extra functionality to `key:files` by allowing the key to
be composed of the given `prefix` combined with the SHA computed for `cache:key:files`.
@@ -2545,9 +2607,36 @@ job:
- path/*xyz/*
```
+#### `artifacts:exclude`
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15122) in GitLab 13.1
+> - Requires GitLab Runner 13.1
+
+`exclude` makes it possible to prevent files from being added to an artifacts
+archive.
+
+Similar to [`artifacts:paths`](#artifactspaths), `exclude` paths are relative
+to the project directory. Wildcards can be used that follow the
+[glob](https://en.wikipedia.org/wiki/Glob_(programming)) patterns and
+[`filepath.Match`](https://golang.org/pkg/path/filepath/#Match).
+
+For example, to store all files in `binaries/`, but not `*.o` files located in
+subdirectories of `binaries/`:
+
+```yaml
+artifacts:
+ paths:
+ - binaries/
+ exclude:
+ - binaries/**/*.o
+```
+
+Files matched by [`artifacts:untracked`](#artifactsuntracked) can be excluded using
+`artifacts:exclude` too.
+
#### `artifacts:expose_as`
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/15018) in GitLab 12.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15018) in GitLab 12.5.
The `expose_as` keyword can be used to expose [job artifacts](../pipelines/job_artifacts.md)
in the [merge request](../../user/project/merge_requests/index.md) UI.
@@ -2691,6 +2780,15 @@ artifacts:
- binaries/
```
+Send all untracked files but [exclude](#artifactsexclude) `*.txt`:
+
+```yaml
+artifacts:
+ untracked: true
+ exclude:
+ - *.txt
+```
+
#### `artifacts:when`
> Introduced in GitLab 8.9 and GitLab Runner v1.3.0.
@@ -2748,7 +2846,7 @@ job:
```
NOTE: **Note:**
-For artifacts created in [GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/issues/16267)
+For artifacts created in [GitLab 13.1](https://gitlab.com/gitlab-org/gitlab/-/issues/16267)
and later, the latest artifact for a ref is always kept, regardless of the expiry time.
#### `artifacts:reports`
@@ -2948,7 +3046,7 @@ You can specify the number of [retry attempts for certain stages of job executio
### `timeout`
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/14887) in GitLab 12.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14887) in GitLab 12.3.
`timeout` allows you to configure a timeout for a specific job. For example:
@@ -3017,8 +3115,8 @@ job split into three separate jobs.
### `trigger`
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/8997) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.8.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/issues/199224) to GitLab Core in 12.8.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8997) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.8.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/199224) to GitLab Core in 12.8.
`trigger` allows you to define downstream pipeline trigger. When a job created
from `trigger` definition is started by GitLab, a downstream pipeline gets
@@ -3086,7 +3184,7 @@ upstream_bridge:
#### `trigger` syntax for child pipeline
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/16094) in GitLab 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/16094) in GitLab 12.7.
To create a [child pipeline](../parent_child_pipelines.md), specify the path to the
YAML file containing the CI config of the child pipeline:
@@ -3110,7 +3208,7 @@ trigger_job:
##### Trigger child pipeline with generated configuration file
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/35632) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35632) in GitLab 12.9.
You can also trigger a child pipeline from a [dynamically generated configuration file](../parent_child_pipelines.md#dynamic-child-pipelines):
@@ -3217,7 +3315,7 @@ Once an uninterruptible job is running, the pipeline will never be canceled, reg
### `resource_group`
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/15536) in GitLab 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15536) in GitLab 12.7.
Sometimes running multiples jobs or pipelines at the same time in an environment
can lead to errors during the deployment.
@@ -3252,6 +3350,8 @@ NOTE: **Note:**
This key can only contain letters, digits, `-`, `_`, `/`, `$`, `{`, `}`, `.`, and spaces.
It can't start or end with `/`.
+For more information, see [Deployments Safety](../environments/deployment_safety.md).
+
### `pages`
`pages` is a special job that is used to upload static content to GitLab that
@@ -3351,7 +3451,7 @@ variables:
`none` also re-uses the local working copy, but skips all Git operations
(including GitLab Runner's pre-clone script, if present). It's mostly useful
-for jobs that operate exclusively on artifacts (for examples `deploy`). Git repository
+for jobs that operate exclusively on artifacts (for example, `deploy`). Git repository
data may be present, but it's certain to be out of date, so you should only
rely on files brought into the local working copy from cache or artifacts.
@@ -3362,7 +3462,7 @@ variables:
NOTE: **Note:** `GIT_STRATEGY` is not supported for
[Kubernetes executor](https://docs.gitlab.com/runner/executors/kubernetes.html),
-but may be in the future. See the [support Git strategy with Kubernetes executor feature proposal](https://gitlab.com/gitlab-org/gitlab-runner/issues/3847)
+but may be in the future. See the [support Git strategy with Kubernetes executor feature proposal](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/3847)
for updates.
### Git submodule strategy
@@ -3459,6 +3559,43 @@ script:
- ls -al cache/
```
+### Git fetch extra flags
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4142) in GitLab Runner 13.1.
+
+The `GIT_FETCH_EXTRA_FLAGS` variable is used to control the behavior of
+`git fetch`. You can set it globally or per-job in the [`variables`](#variables) section.
+
+`GIT_FETCH_EXTRA_FLAGS` accepts all possible options of the [`git fetch`](https://git-scm.com/docs/git-fetch) command, but please note that `GIT_FETCH_EXTRA_FLAGS` flags will be appended after the default flags that can't be modified.
+
+The default flags are:
+
+- [GIT_DEPTH](#shallow-cloning).
+- The list of [refspecs](https://git-scm.com/book/en/v2/Git-Internals-The-Refspec).
+- A remote called `origin`.
+
+If `GIT_FETCH_EXTRA_FLAGS` is:
+
+- Not specified, `git fetch` flags default to `--prune --quiet` along with the default flags.
+- Given the value `none`, `git fetch` is executed only with the default flags.
+
+For example, the default flags are `--prune --quiet`, so you can make `git fetch` more verbose by overriding this with just `--prune`:
+
+```yaml
+variables:
+ GIT_FETCH_EXTRA_FLAGS: --prune
+script:
+ - ls -al cache/
+```
+
+The configurtion above will result in `git fetch` being called this way:
+
+```shell
+git fetch origin $REFSPECS --depth 50 --prune
+```
+
+Where `$REFSPECS` is a value provided to the Runner internally by GitLab.
+
### Job stages attempts
> Introduced in GitLab, it requires GitLab Runner v1.9+.
@@ -3488,8 +3625,8 @@ You can set them globally or per-job in the [`variables`](#variables) section.
> Introduced in GitLab 8.9 as an experimental feature.
-CAUTION: **Caution:**
-May change in future releases or be removed completely.
+NOTE: **Note**:
+As of GitLab 12.0, newly created projects will automatically have a [default `git depth` value of `50`](../pipelines/settings.md#git-shallow-clone).
You can specify the depth of fetching and cloning using `GIT_DEPTH`. This allows
shallow cloning of the repository which can significantly speed up cloning for
@@ -3739,7 +3876,7 @@ feature. Anchors are only valid within the file they were defined in.
#### YAML anchors for `before_script` and `after_script`
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/23005) in GitLab 12.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/23005) in GitLab 12.5.
You can use [YAML anchors](#anchors) with `before_script` and `after_script`,
which makes it possible to include a predefined list of commands in multiple
@@ -3753,7 +3890,7 @@ Example:
.something_after: &something_after
- echo 'something after'
-
+- echo 'another thing after'
job_name:
before_script:
@@ -3766,7 +3903,7 @@ job_name:
#### YAML anchors for `script`
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/23005) in GitLab 12.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/23005) in GitLab 12.5.
You can use [YAML anchors](#anchors) with scripts, which makes it possible to
include a predefined list of commands in multiple jobs.
@@ -3796,6 +3933,7 @@ the use of the `SAMPLE_VARIABLE` variable:
# global variables
variables: &global-variables
SAMPLE_VARIABLE: sample_variable_value
+ ANOTHER_SAMPLE_VARIABLE: another_sample_variable_value
# a job that needs to set the GIT_STRATEGY variable, yet depend on global variables
job_no_git_strategy:
@@ -3819,7 +3957,7 @@ lines where the job is defined:
# - run test
```
-you can instead start its name with a dot (`.`) and it won't be processed by
+You can instead start its name with a dot (`.`) and it won't be processed by
GitLab CI/CD. In the following example, `.hidden_job` will be ignored:
```yaml
@@ -3842,11 +3980,11 @@ if using Git 2.10 or newer.
## Processing Git pushes
-GitLab will create at most 4 branch and tags pipelines when
-doing pushing multiple changes in single `git push` invocation.
+GitLab will create at most 4 branch and tag pipelines when
+pushing multiple changes in single `git push` invocation.
-This limitation does not affect any of the updated Merge Request pipelines,
-all updated Merge Requests will have a pipeline created when using
+This limitation does not affect any of the updated Merge Request pipelines.
+All updated Merge Requests will have a pipeline created when using
[pipelines for merge requests](../merge_request_pipelines/index.md).
## Deprecated parameters
diff --git a/doc/ci/yaml/includes.md b/doc/ci/yaml/includes.md
index a7b626bdd7c..969b54d5be8 100644
--- a/doc/ci/yaml/includes.md
+++ b/doc/ci/yaml/includes.md
@@ -1,3 +1,10 @@
+---
+stage: Verify
+group: Continuous Integration
+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
+---
+
# GitLab CI/CD YAML includes
In addition to the [`includes` examples](README.md#include) listed in the
diff --git a/doc/development/README.md b/doc/development/README.md
index 22cc21e12b9..d330d6d466e 100644
--- a/doc/development/README.md
+++ b/doc/development/README.md
@@ -63,7 +63,7 @@ Complementary reads:
- [Working with Gitaly](gitaly.md)
- [Manage feature flags](feature_flags/index.md)
- [Licensed feature availability](licensed_feature_availability.md)
-- [View sent emails or preview mailers](emails.md)
+- [Dealing with email/mailers](emails.md)
- [Shell commands](shell_commands.md) in the GitLab codebase
- [`Gemfile` guidelines](gemfile.md)
- [Pry debugging](pry_debugging.md)
@@ -113,50 +113,7 @@ Complementary reads:
## Database guides
-### Tooling
-
-- [Understanding EXPLAIN plans](understanding_explain_plans.md)
-- [explain.depesz.com](https://explain.depesz.com/) for visualizing the output
- of `EXPLAIN`
-- [pgFormatter](http://sqlformat.darold.net/) a PostgreSQL SQL syntax beautifier
-
-### Migrations
-
-- [What requires downtime?](what_requires_downtime.md)
-- [SQL guidelines](sql.md) for working with SQL queries
-- [Migrations style guide](migration_style_guide.md) for creating safe SQL migrations
-- [Testing Rails migrations](testing_guide/testing_migrations_guide.md) guide
-- [Post deployment migrations](post_deployment_migrations.md)
-- [Background migrations](background_migrations.md)
-- [Swapping tables](swapping_tables.md)
-- [Deleting migrations](deleting_migrations.md)
-
-### Debugging
-
-- Tracing the source of an SQL query using query comments with [Marginalia](database_query_comments.md)
-- Tracing the source of an SQL query in Rails console using [Verbose Query Logs](https://guides.rubyonrails.org/debugging_rails_applications.html#verbose-query-logs)
-
-### Best practices
-
-- [Adding database indexes](adding_database_indexes.md)
-- [Foreign keys & associations](foreign_keys.md)
-- [Single table inheritance](single_table_inheritance.md)
-- [Polymorphic associations](polymorphic_associations.md)
-- [Serializing data](serializing_data.md)
-- [Hash indexes](hash_indexes.md)
-- [Storing SHA1 hashes as binary](sha1_as_binary.md)
-- [Iterating tables in batches](iterating_tables_in_batches.md)
-- [Insert into tables in batches](insert_into_tables_in_batches.md)
-- [Ordering table columns](ordering_table_columns.md)
-- [Verifying database capabilities](verifying_database_capabilities.md)
-- [Database Debugging and Troubleshooting](database_debugging.md)
-- [Query Count Limits](query_count_limits.md)
-- [Creating enums](creating_enums.md)
-
-### Case studies
-
-- [Database case study: Filtering by label](filtering_by_label.md)
-- [Database case study: Namespaces storage statistics](namespaces_storage_statistics.md)
+See [database guidelines](database/index.md).
## Integration guides
diff --git a/doc/development/adding_database_indexes.md b/doc/development/adding_database_indexes.md
index 01b621b6631..7fe047b380b 100644
--- a/doc/development/adding_database_indexes.md
+++ b/doc/development/adding_database_indexes.md
@@ -20,8 +20,8 @@ existing indexes need to be updated. The more indexes there are the slower this
can potentially become. Indexes can also take up quite some disk space depending
on the amount of data indexed and the index type. For example, PostgreSQL offers
"GIN" indexes which can be used to index certain data types that can not be
-indexed by regular btree indexes. These indexes however generally take up more
-data and are slower to update compared to btree indexes.
+indexed by regular B-tree indexes. These indexes however generally take up more
+data and are slower to update compared to B-tree indexes.
Because of all this one should not blindly add a new index for every column used
to filter data by. Instead one should ask themselves the following questions:
diff --git a/doc/development/api_graphql_styleguide.md b/doc/development/api_graphql_styleguide.md
index 6d3c0cf0eac..43e96340d10 100644
--- a/doc/development/api_graphql_styleguide.md
+++ b/doc/development/api_graphql_styleguide.md
@@ -346,7 +346,7 @@ GitLab's GraphQL API is versionless, which means we maintain backwards
compatibility with older versions of the API with every change. Rather
than removing a field, we need to _deprecate_ the field instead. In
future, GitLab
-[may remove deprecated fields](https://gitlab.com/gitlab-org/gitlab/issues/32292).
+[may remove deprecated fields](https://gitlab.com/gitlab-org/gitlab/-/issues/32292).
Fields are deprecated using the `deprecated` property. The value
of the property is a `Hash` of:
@@ -470,6 +470,23 @@ field :confidential, GraphQL::BOOLEAN_TYPE, description: 'Indicates the issue is
field :closed_at, Types::TimeType, description: 'Timestamp of when the issue was closed'
```
+### `copy_field_description` helper
+
+Sometimes we want to ensure that two descriptions will always be identical.
+For example, to keep a type field description the same as a mutation argument
+when they both represent the same property.
+
+Instead of supplying a description, we can use the `copy_field_description` helper,
+passing it the type, and field name to copy the description of.
+
+Example:
+
+```ruby
+argument :title, GraphQL::STRING_TYPE,
+ required: false,
+ description: copy_field_description(Types::MergeRequestType, :title)
+```
+
## Authorization
Authorizations can be applied to both types and fields using the same
@@ -602,6 +619,84 @@ lot of dependent objects.
To limit the amount of queries performed, we can use `BatchLoader`.
+### Correct use of `Resolver#ready?`
+
+Resolvers have two public API methods as part of the framework: `#ready?(**args)` and `#resolve(**args)`.
+We can use `#ready?` to perform set-up, validation or early-return without invoking `#resolve`.
+
+Good reasons to use `#ready?` include:
+
+- validating mutually exclusive arguments (see [validating arguments](#validating-arguments))
+- Returning `Relation.none` if we know before-hand that no results are possible
+- Performing setup such as initializing instance variables (although consider lazily initialized methods for this)
+
+Implementations of [`Resolver#ready?(**args)`](https://graphql-ruby.org/api-doc/1.10.9/GraphQL/Schema/Resolver#ready%3F-instance_method) should
+return `(Boolean, early_return_data)` as follows:
+
+```ruby
+def ready?(**args)
+ [false, 'have this instead']
+end
+```
+
+For this reason, whenever you call a resolver (mainly in tests - as framework
+abstractions Resolvers should not be considered re-usable, finders are to be
+preferred), remember to call the `ready?` method and check the boolean flag
+before calling `resolve`! An example can be seen in our [`GraphQLHelpers`](https://gitlab.com/gitlab-org/gitlab/-/blob/2d395f32d2efbb713f7bc861f96147a2a67e92f2/spec/support/helpers/graphql_helpers.rb#L20-27).
+
+### Look-Ahead
+
+The full query is known in advance during execution, which means we can make use
+of [lookahead](https://graphql-ruby.org/queries/lookahead.html) to optimize our
+queries, and batch load associations we know we will need. Consider adding
+lookahead support in your resolvers to avoid `N+1` performance issues.
+
+To enable support for common lookahead use-cases (pre-loading associations when
+child fields are requested), you can
+include [`LooksAhead`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/graphql/resolvers/concerns/looks_ahead.rb). For example:
+
+```ruby
+# Assuming a model `MyThing` with attributes `[child_attribute, other_attribute, nested]`,
+# where nested has an attribute named `included_attribute`.
+class MyThingResolver < BaseResolver
+ include LooksAhead
+
+ # Rather than defining `resolve(**args)`, we implement: `resolve_with_lookahead(**args)`
+ def resolve_with_lookahead(**args)
+ apply_lookahead(MyThingFinder.new(current_user).execute)
+ end
+
+ # We list things that should always be preloaded:
+ # For example, if child_attribute is always needed (during authorization
+ # perhaps), then we can include it here.
+ def unconditional_includes
+ [:child_attribute]
+ end
+
+ # We list things that should be included if a certain field is selected:
+ def preloads
+ {
+ field_one: [:other_attribute],
+ field_two: [{ nested: [:included_attribute] }]
+ }
+ end
+end
+```
+
+The final thing that is needed is that every field that uses this resolver needs
+to advertise the need for lookahead:
+
+```ruby
+ # in ParentType
+ field :my_things, MyThingType.connection_type, null: true,
+ extras: [:lookahead], # Necessary
+ resolver: MyThingResolver,
+ description: 'My things'
+```
+
+For an example of real world use, please
+see [`ResolvesMergeRequests`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/graphql/resolvers/concerns/resolves_merge_requests.rb).
+
## Mutations
Mutations are used to change any stored values, or to trigger
@@ -613,19 +708,6 @@ To find objects for a mutation, arguments need to be specified. As with
[resolvers](#resolvers), prefer using internal ID or, if needed, a
global ID rather than the database ID.
-### Fields
-
-In the most common situations, a mutation would return 2 fields:
-
-- The resource being modified
-- A list of errors explaining why the action could not be
- performed. If the mutation succeeded, this list would be empty.
-
-By inheriting any new mutations from `Mutations::BaseMutation` the
-`errors` field is automatically added. A `clientMutationId` field is
-also added, this can be used by the client to identify the result of a
-single mutation when multiple are performed within a single request.
-
### Building Mutations
Mutations live in `app/graphql/mutations` ideally grouped per
@@ -633,12 +715,16 @@ resources they are mutating, similar to our services. They should
inherit `Mutations::BaseMutation`. The fields defined on the mutation
will be returned as the result of the mutation.
+### Naming conventions
+
Always provide a consistent GraphQL-name to the mutation, this name is
used to generate the input types and the field the mutation is mounted
on. The name should look like `<Resource being modified><Mutation
class name>`, for example the `Mutations::MergeRequests::SetWip`
mutation has GraphQL name `MergeRequestSetWip`.
+### Arguments
+
Arguments required by the mutation can be defined as arguments
required for a field. These will be wrapped up in an input type for
the mutation. For example, the `Mutations::MergeRequests::SetWip`
@@ -667,11 +753,28 @@ This would automatically generate an input type called
`clientMutationId`.
These arguments are then passed to the `resolve` method of a mutation
-as keyword arguments. From here, we can call the service that will
-modify the resource.
+as keyword arguments.
+
+### Fields
+
+In the most common situations, a mutation would return 2 fields:
+
+- The resource being modified
+- A list of errors explaining why the action could not be
+ performed. If the mutation succeeded, this list would be empty.
+
+By inheriting any new mutations from `Mutations::BaseMutation` the
+`errors` field is automatically added. A `clientMutationId` field is
+also added, this can be used by the client to identify the result of a
+single mutation when multiple are performed within a single request.
+
+### The `resolve` method
+
+The `resolve` method receives the mutation's arguments as keyword arguments.
+From here, we can call the service that will modify the resource.
The `resolve` method should then return a hash with the same field
-names as defined on the mutation and an `errors` array. For example,
+names as defined on the mutation including an `errors` array. For example,
the `Mutations::MergeRequests::SetWip` defines a `merge_request`
field:
@@ -690,12 +793,15 @@ should look like this:
# The merge request modified, this will be wrapped in the type
# defined on the field
merge_request: merge_request,
- # An array if strings if the mutation failed after authorization
- errors: merge_request.errors.full_messages
+ # An array of strings if the mutation failed after authorization.
+ # The `errors_on_object` helper collects `errors.full_messages`
+ errors: errors_on_object(merge_request)
}
```
-To make the mutation available it should be defined on the mutation
+### Mounting the mutation
+
+To make the mutation available it must be defined on the mutation
type that lives in `graphql/types/mutation_types`. The
`mount_mutation` helper method will define a field based on the
GraphQL-name of the mutation:
@@ -744,6 +850,131 @@ found, we should raise a
`Gitlab::Graphql::Errors::ResourceNotAvailable` error. Which will be
correctly rendered to the clients.
+### Errors in mutations
+
+We encourage following the practice of [errors as
+data](https://graphql-ruby.org/mutations/mutation_errors) for mutations, which
+distinguishes errors by who they are relevant to, defined by who can deal with
+them.
+
+Key points:
+
+- All mutation responses have an `errors` field. This should be populated on
+ failure, and may be populated on success.
+- Consider who needs to see the error: the **user** or the **developer**.
+- Clients should always request the `errors` field when performing mutations.
+- Errors may be reported to users either at `$root.errors` (top-level error) or at
+ `$root.data.mutationName.errors` (mutation errors). The location depends on what kind of error
+ this is, and what information it holds.
+
+Consider an example mutation `doTheThing` that returns a response with
+two fields: `errors: [String]`, and `thing: ThingType`. The specific nature of
+the `thing` itself is irrelevant to these examples, as we are considering the
+errors.
+
+There are three states a mutation response can be in:
+
+- [Success](#success)
+- [Failure (relevant to the user)](#failure-relevant-to-the-user)
+- [Failure (irrelevant to the user)](#failure-irrelevant-to-the-user)
+
+#### Success
+
+In the happy path, errors *may* be returned, along with the anticipated payload, but
+if everything was successful, then `errors` should be an empty array, since
+there are no problems we need to inform the user of.
+
+```javascript
+{
+ data: {
+ doTheThing: {
+ errors: [] // if successful, this array will generally be empty.
+ thing: { .. }
+ }
+ }
+}
+```
+
+#### Failure (relevant to the user)
+
+An error that affects the **user** occurred. We refer to these as _mutation errors_. In
+this case there is typically no `thing` to return:
+
+```javascript
+{
+ data: {
+ doTheThing: {
+ errors: ["you cannot touch the thing"],
+ thing: null
+ }
+ }
+}
+```
+
+Examples of this include:
+
+- Model validation errors: the user may need to change the inputs.
+- Permission errors: the user needs to know they cannot do this, they may need to request permission or sign in.
+- Problems with application state that prevent the user's action, for example: merge conflicts, the resource was locked, and so on.
+
+Ideally, we should prevent the user from getting this far, but if they do, they
+need to be told what is wrong, so they understand the reason for the failure and
+what they can do to achieve their intent, even if that is as simple as retrying the
+request.
+
+It is possible to return *recoverable* errors alongside mutation data. For example, if
+a user uploads 10 files and 3 of them fail and the rest succeed, the errors for the
+failures can be made available to the user, alongside the information about
+the successes.
+
+#### Failure (irrelevant to the user)
+
+One or more *non-recoverable* errors can be returned at the _top level_. These
+are things over which the **user** has little to no control, and should mainly
+be system or programming problems, that a **developer** needs to know about.
+In this case there is no `data`:
+
+```javascript
+{
+ errors: [
+ {"message": "argument error: expected an integer, got null"},
+ ]
+}
+```
+
+This is the result of raising an error during the mutation. In our implementation,
+the messages of argument errors and validation errors are returned to the client, and all other
+`StandardError` instances are caught, logged and presented to the client with the message set to `"Internal server error"`.
+See [`GraphqlController`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/graphql_controller.rb) for details.
+
+These represent programming errors, such as:
+
+- A GraphQL syntax error, where an `Int` was passed instead of a `String`, or a required argument was not present.
+- Errors in our schema, such as being unable to provide a value for a non-nullable field.
+- System errors: for example, a Git storage exception, or database unavailability.
+
+The user should not be able to cause such errors in regular usage. This category
+of errors should be treated as internal, and not shown to the user in specific
+detail.
+
+We need to inform the user when the mutation fails, but we do not need to
+tell them why, since they cannot have caused it, and nothing they can do will
+fix it, although we may offer to retry the mutation.
+
+#### Categorizing errors
+
+When we write mutations, we need to be conscious about which of
+these two categories an error state falls into (and communicate about this with
+frontend developers to verify our assumptions). This means distinguishing the
+needs of the _user_ from the needs of the _client_.
+
+> _Never catch an error unless the user needs to know about it._
+
+If the user does need to know about it, communicate with frontend developers
+to make sure the error information we are passing back is useful.
+
+See also the [frontend GraphQL guide](../development/fe_guide/graphql.md#handling-errors).
+
## Validating arguments
For validations of single arguments, use the
@@ -751,8 +982,8 @@ For validations of single arguments, use the
as normal.
Sometimes a mutation or resolver may accept a number of optional
-arguments, but still want to validate that at least one of the optional
-arguments were given. In this situation, consider using the `#ready?`
+arguments, but we still want to validate that at least one of the optional
+arguments is provided. In this situation, consider using the `#ready?`
method within your mutation or resolver to provide the validation. The
`#ready?` method will be called before any work is done within the
`#resolve` method.
@@ -767,7 +998,7 @@ def ready?(**args)
end
# Always remember to call `#super`
- super(args)
+ super
end
```
diff --git a/doc/development/api_styleguide.md b/doc/development/api_styleguide.md
index e9a41e7ec58..6a044004926 100644
--- a/doc/development/api_styleguide.md
+++ b/doc/development/api_styleguide.md
@@ -116,6 +116,73 @@ For instance:
- endpoint = expose_path(api_v4_projects_issues_related_merge_requests_path(id: @project.id, issue_iid: @issue.iid))
```
+## Custom Validators
+
+In order to validate some parameters in the API request, we validate them
+before sending them further (say Gitaly). The following are the
+[custom validators](https://GitLab.com/gitlab-org/gitlab/-/tree/master/lib/api/validations/validators),
+which we have added so far and how to use them. We also wrote a
+guide on how you can add a new custom validator.
+
+### Using custom validators
+
+- `FilePath`:
+
+ GitLab supports various functionalities where we need to traverse a file path.
+ The [`FilePath` validator](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/validations/validators/file_path.rb)
+ validates the parameter value for different cases. Mainly, it checks whether a
+ path is relative and does it contain `../../` relative traversal using
+ `File::Separator` or not, and whether the path is absolute, for example
+ `/etc/passwd/`.
+
+- `Git SHA`:
+
+ The [`Git SHA` validator](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/validations/validators/git_sha.rb)
+ checks whether the Git SHA parameter is a valid SHA.
+ It checks by using the regex mentioned in [`commit.rb`](https://gitlab.com/gitlab-org/gitlab/-/commit/b9857d8b662a2dbbf54f46ecdcecb44702affe55#d1c10892daedb4d4dd3d4b12b6d071091eea83df_30_30) file.
+
+- `Absence`:
+
+ The [`Absence` validator](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/validations/validators/absence.rb)
+ checks whether a particular parameter is absent in a given parameters hash.
+
+- `IntegerNoneAny`:
+
+ The [`IntegerNoneAny` validator](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/validations/validators/integer_none_any.rb)
+ checks if the value of the given parameter is either an `Integer`, `None`, or `Any`.
+ It allows only either of these mentioned values to move forward in the request.
+
+- `ArrayNoneAny`:
+
+ The [`ArrayNoneAny` validator](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/validations/validators/array_none_any.rb)
+ checks if the value of the given parameter is either an `Array`, `None`, or `Any`.
+ It allows only either of these mentioned values to move forward in the request.
+
+### Adding a new custom validator
+
+Custom validators are a great way to validate parameters before sending
+them to platform for further processing. It saves some back-and-forth
+from the server to the platform if we identify invalid parameters at the beginning.
+
+If you need to add a custom validator, it would be added to
+it's own file in the [`validators`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/validations/validators) directory.
+Since we use [Grape](https://github.com/ruby-grape/grape) to add our API
+we inherit from the `Grape::Validations::Base` class in our validator class.
+Now, all you have to do is define the `validate_param!` method which takes
+in two parameters: the `params` hash and the `param` name to validate.
+
+The body of the method does the hard work of validating the parameter value
+and returns appropriate error messages to the caller method.
+
+Lastly, we register the validator using the line below:
+
+```ruby
+Grape::Validations.register_validator(<validator name as symbol>, ::API::Helpers::CustomValidators::<YourCustomValidatorClassName>)
+```
+
+Once you add the validator, make sure you add the `rspec`s for it into
+it's own file in the [`validators`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/spec/lib/api/validations/validators) directory.
+
## Internal API
The [internal API](./internal_api.md) is documented for internal use. Please keep it up to date so we know what endpoints
diff --git a/doc/development/application_limits.md b/doc/development/application_limits.md
index b13e2994c52..1f7a9ff09b9 100644
--- a/doc/development/application_limits.md
+++ b/doc/development/application_limits.md
@@ -11,7 +11,7 @@ coordinate with others to [document](../administration/instance_limits.md)
and communicate those limits.
There is a guide about [introducing application
-limits](https://about.gitlab.com/handbook/product/product-management/process/index.html#introducing-application-limits).
+limits](https://about.gitlab.com/handbook/product/product-management/process/#introducing-application-limits).
## Development
@@ -21,7 +21,7 @@ In the `plan_limits` table, you have to create a new column and insert the
limit values. It's recommended to create separate migration script files.
1. Add new column to the `plan_limits` table with non-null default value
- that represents desired limit, eg:
+ that represents desired limit, such as:
```ruby
add_column(:plan_limits, :project_hooks, :integer, default: 100, null: false)
@@ -31,7 +31,7 @@ limit values. It's recommended to create separate migration script files.
enabled. You should use this setting only in special and documented circumstances.
1. (Optionally) Create the database migration that fine-tunes each level with
- a desired limit using `create_or_update_plan_limit` migration helper, eg:
+ a desired limit using `create_or_update_plan_limit` migration helper, such as:
```ruby
class InsertProjectHooksPlanLimits < ActiveRecord::Migration[5.2]
@@ -65,7 +65,7 @@ for plans that do not exist.
#### Get current limit
Access to the current limit can be done through the project or the namespace,
-eg:
+such as:
```ruby
project.actual_limits.project_hooks
@@ -76,13 +76,13 @@ project.actual_limits.project_hooks
There is one method `PlanLimits#exceeded?` to check if the current limit is
being exceeded. You can use either an `ActiveRecord` object or an `Integer`.
-Ensures that the count of the records does not exceed the defined limit, eg:
+Ensures that the count of the records does not exceed the defined limit, such as:
```ruby
project.actual_limits.exceeded?(:project_hooks, ProjectHook.where(project: project))
```
-Ensures that the number does not exceed the defined limit, eg:
+Ensures that the number does not exceed the defined limit, such as:
```ruby
project.actual_limits.exceeded?(:project_hooks, 10)
@@ -115,6 +115,20 @@ it_behaves_like 'includes Limitable concern' do
end
```
+### Testing instance-wide limits
+
+Instance-wide features always use `default` Plan, as instance-wide features
+do not have license assigned.
+
+```ruby
+class InstanceVariable
+ include Limitable
+
+ self.limit_name = 'instance_variables' # Optional as InstanceVariable corresponds with instance_variables
+ self.limit_scope = Limitable::GLOBAL_SCOPE
+end
+```
+
### Subscription Plans
Self-managed:
@@ -123,9 +137,10 @@ Self-managed:
GitLab.com:
-- `free` - Everyone
-- `bronze`- Namespaces with a Bronze subscription
-- `silver` - Namespaces with a Silver subscription
-- `gold` - Namespaces with a Gold subscription
+- `default` - Any system-wide feature
+- `free` - Namespaces and projects with a Free subscription
+- `bronze`- Namespaces and projects with a Bronze subscription
+- `silver` - Namespaces and projects with a Silver subscription
+- `gold` - Namespaces and projects with a Gold subscription
NOTE: **Note:** The test environment doesn't have any plans.
diff --git a/doc/development/architecture.md b/doc/development/architecture.md
index f52a5d30c1f..f0ce033587d 100644
--- a/doc/development/architecture.md
+++ b/doc/development/architecture.md
@@ -12,7 +12,7 @@ Both EE and CE require some add-on components called GitLab Shell and Gitaly. Th
## Components
-A typical install of GitLab will be on GNU/Linux. It uses NGINX or Apache as a web front end to proxypass the Unicorn web server. By default, communication between Unicorn and the front end is via a Unix domain socket but forwarding requests via TCP is also supported. The web front end accesses `/home/git/gitlab/public` bypassing the Unicorn server to serve static pages, uploads (e.g. avatar images or attachments), and precompiled assets. GitLab serves web pages and the [GitLab API](../api/README.md) using the Unicorn web server. It uses Sidekiq as a job queue which, in turn, uses Redis as a non-persistent database backend for job information, meta data, and incoming jobs.
+A typical install of GitLab will be on GNU/Linux. It uses NGINX or Apache as a web front end to proxypass the Unicorn web server. By default, communication between Unicorn and the front end is via a Unix domain socket but forwarding requests via TCP is also supported. The web front end accesses `/home/git/gitlab/public` bypassing the Unicorn server to serve static pages, uploads (e.g. avatar images or attachments), and pre-compiled assets. GitLab serves web pages and the [GitLab API](../api/README.md) using the Unicorn web server. It uses Sidekiq as a job queue which, in turn, uses Redis as a non-persistent database backend for job information, meta data, and incoming jobs.
We also support deploying GitLab on Kubernetes using our [GitLab Helm chart](https://docs.gitlab.com/charts/).
@@ -196,7 +196,7 @@ GitLab can be considered to have two layers from a process perspective:
- Process: `alertmanager`
- GitLab.com: [Monitoring of GitLab.com](https://about.gitlab.com/handbook/engineering/monitoring/)
-[Alert manager](https://prometheus.io/docs/alerting/alertmanager/) is a tool provided by Prometheus that _"handles alerts sent by client applications such as the Prometheus server. It takes care of deduplicating, grouping, and routing them to the correct receiver integration such as email, PagerDuty, or OpsGenie. It also takes care of silencing and inhibition of alerts."_ You can read more in [issue #45740](https://gitlab.com/gitlab-org/gitlab-foss/issues/45740) about what we will be alerting on.
+[Alert manager](https://prometheus.io/docs/alerting/alertmanager/) is a tool provided by Prometheus that _"handles alerts sent by client applications such as the Prometheus server. It takes care of deduplicating, grouping, and routing them to the correct receiver integration such as email, PagerDuty, or OpsGenie. It also takes care of silencing and inhibition of alerts."_ You can read more in [issue #45740](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/45740) about what we will be alerting on.
#### Certificate management
@@ -227,7 +227,7 @@ Consul is a tool for service discovery and configuration. Consul is distributed,
- Configuration:
- [Omnibus](https://docs.gitlab.com/omnibus/settings/database.html#disabling-automatic-database-migration)
- [Charts](https://docs.gitlab.com/charts/charts/gitlab/migrations/)
- - [Source](../update/upgrading_from_source.md#13-install-libs-migrations-etc)
+ - [Source](../update/upgrading_from_source.md#13-install-libraries-migrations-etc)
- Layer: Core Service (Data)
#### Elasticsearch
@@ -254,7 +254,7 @@ Elasticsearch is a distributed RESTful search engine built for the cloud.
- Process: `gitaly`
- GitLab.com: [Service Architecture](https://about.gitlab.com/handbook/engineering/infrastructure/production/architecture/#service-architecture)
-Gitaly is a service designed by GitLab to remove our need for NFS for Git storage in distributed deployments of GitLab (think GitLab.com or High Availability Deployments). As of 11.3.0, this service handles all Git level access in GitLab. You can read more about the project [in the project's readme](https://gitlab.com/gitlab-org/gitaly).
+Gitaly is a service designed by GitLab to remove our need for NFS for Git storage in distributed deployments of GitLab (think GitLab.com or High Availability Deployments). As of 11.3.0, this service handles all Git level access in GitLab. You can read more about the project [in the project's README](https://gitlab.com/gitlab-org/gitaly).
#### Praefect
@@ -273,7 +273,7 @@ repository updates to secondary nodes.
- Configuration:
- [Omnibus](../administration/geo/replication/index.md#setup-instructions)
- - [Charts](https://gitlab.com/gitlab-org/charts/gitlab/issues/8)
+ - [Charts](https://gitlab.com/gitlab-org/charts/gitlab/-/issues/8)
- [GDK](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/master/doc/howto/geo.md)
- Layer: Core Service (Processor)
@@ -287,13 +287,13 @@ repository updates to secondary nodes.
- Process: `gitlab-exporter`
- GitLab.com: [Monitoring of GitLab.com](https://about.gitlab.com/handbook/engineering/monitoring/)
-GitLab Exporter is a process designed in house that allows us to export metrics about GitLab application internals to Prometheus. You can read more [in the project's readme](https://gitlab.com/gitlab-org/gitlab-exporter).
+GitLab Exporter is a process designed in house that allows us to export metrics about GitLab application internals to Prometheus. You can read more [in the project's README](https://gitlab.com/gitlab-org/gitlab-exporter).
#### GitLab Pages
- Configuration:
- [Omnibus](../administration/pages/index.md)
- - [Charts](https://gitlab.com/gitlab-org/charts/gitlab/issues/37)
+ - [Charts](https://gitlab.com/gitlab-org/charts/gitlab/-/issues/37)
- [Source](../install/installation.md#install-gitlab-pages)
- [GDK](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/master/doc/howto/pages.md)
- Layer: Core Service (Processor)
@@ -359,12 +359,12 @@ Grafana is an open source, feature rich metrics dashboard and graph editor for G
- [Project page](https://github.com/jaegertracing/jaeger/blob/master/README.md)
- Configuration:
- - [Omnibus](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/4104)
- - [Charts](https://gitlab.com/gitlab-org/charts/gitlab/issues/1320)
+ - [Omnibus](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/4104)
+ - [Charts](https://gitlab.com/gitlab-org/charts/gitlab/-/issues/1320)
- [Source](../development/distributed_tracing.md#enabling-distributed-tracing)
- [GDK](../development/distributed_tracing.md#using-jaeger-in-the-gitlab-development-kit)
- Layer: Monitoring
-- GitLab.com: [Configuration to enable Tracing for a GitLab instance](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/4104) issue.
+- GitLab.com: [Configuration to enable Tracing for a GitLab instance](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/4104) issue.
Jaeger, inspired by Dapper and OpenZipkin, is a distributed tracing system.
It can be used for monitoring microservices-based distributed systems.
@@ -424,7 +424,7 @@ NGINX has an Ingress port for all HTTP requests and routes them to the appropria
- [Project page](https://github.com/prometheus/node_exporter/blob/master/README.md)
- Configuration:
- [Omnibus](../administration/monitoring/prometheus/node_exporter.md)
- - [Charts](https://gitlab.com/gitlab-org/charts/gitlab/issues/1332)
+ - [Charts](https://gitlab.com/gitlab-org/charts/gitlab/-/issues/1332)
- Layer: Monitoring
- Process: `node-exporter`
- GitLab.com: [Monitoring of GitLab.com](https://about.gitlab.com/handbook/engineering/monitoring/)
@@ -444,7 +444,7 @@ Lightweight connection pooler for PostgreSQL.
#### PgBouncer Exporter
-- [Project page](https://github.com/stanhu/pgbouncer_exporter/blob/master/README.md)
+- [Project page](https://github.com/prometheus-community/pgbouncer_exporter/blob/master/README.md)
- Configuration:
- [Omnibus](../administration/monitoring/prometheus/pgbouncer_exporter.md)
- [Charts](https://docs.gitlab.com/charts/installation/deployment.html#postgresql)
@@ -523,7 +523,7 @@ Redis is packaged to provide a place to store:
- [Project page](https://github.com/docker/distribution/blob/master/README.md)
- Configuration:
- - [Omnibus](../update/upgrading_from_source.md#13-install-libs-migrations-etc)
+ - [Omnibus](../update/upgrading_from_source.md#13-install-libraries-migrations-etc)
- [Charts](https://docs.gitlab.com/charts/charts/registry/)
- [Source](../administration/packages/container_registry.md#enable-the-container-registry)
- [GDK](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/master/doc/howto/registry.md)
@@ -545,13 +545,13 @@ An external registry can also be configured to use GitLab as an auth endpoint.
- [Project page](https://github.com/getsentry/sentry/)
- Configuration:
- [Omnibus](https://docs.gitlab.com/omnibus/settings/configuration.html#error-reporting-and-logging-with-sentry)
- - [Charts](https://gitlab.com/gitlab-org/charts/gitlab/issues/1319)
+ - [Charts](https://gitlab.com/gitlab-org/charts/gitlab/-/issues/1319)
- [Source](https://gitlab.com/gitlab-org/gitlab/blob/master/config/gitlab.yml.example)
- [GDK](https://gitlab.com/gitlab-org/gitlab/blob/master/config/gitlab.yml.example)
- Layer: Monitoring
- GitLab.com: [Searching Sentry](https://about.gitlab.com/handbook/support/workflows/500_errors.html#searching-sentry)
-Sentry fundamentally is a service that helps you monitor and fix crashes in realtime.
+Sentry fundamentally is a service that helps you monitor and fix crashes in real time.
The server is in Python, but it contains a full API for sending events from any language, in any application.
For monitoring deployed apps, see the [Sentry integration docs](../user/project/operations/error_tracking.md)
@@ -588,7 +588,7 @@ Sidekiq is a Ruby background job processor that pulls jobs from the Redis queue
#### LDAP Authentication
- Configuration:
- - [Omnibus](../administration/auth/ldap.md)
+ - [Omnibus](../administration/auth/ldap/index.md)
- [Charts](https://docs.gitlab.com/charts/charts/globals.html#ldap)
- [Source](https://gitlab.com/gitlab-org/gitlab/blob/master/config/gitlab.yml.example)
- [GDK](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/master/doc/howto/ldap.md)
@@ -657,7 +657,7 @@ When making a request to an HTTP Endpoint (think `/users/sign_in`) the request w
### GitLab Git Request Cycle
-Below we describe the different pathing that HTTP vs. SSH Git requests will take. There is some overlap with the Web Request Cycle but also some differences.
+Below we describe the different paths that HTTP vs. SSH Git requests will take. There is some overlap with the Web Request Cycle but also some differences.
### Web Request (80/443)
@@ -790,7 +790,7 @@ ps aux | grep '^git'
```
GitLab has several components to operate. It requires a persistent database
-(PostgreSQL) and Redis database, and uses Apache httpd or NGINX to proxypass
+(PostgreSQL) and Redis database, and uses Apache `httpd` or NGINX to proxypass
Unicorn. All these components should run as different system users to GitLab
(e.g., `postgres`, `redis` and `www-data`, instead of `git`).
@@ -866,7 +866,7 @@ NGINX:
- `/var/log/nginx/` contains error and access logs.
-Apache httpd:
+Apache `httpd`:
- [Explanation of Apache logs](https://httpd.apache.org/docs/2.2/logs.html).
- `/var/log/apache2/` contains error and output logs (on Ubuntu).
@@ -880,7 +880,7 @@ PostgreSQL:
- `/var/log/postgresql/*`
-### GitLab specific config files
+### GitLab specific configuration files
GitLab has configuration files located in `/home/git/gitlab/config/*`. Commonly referenced config files include:
@@ -902,7 +902,7 @@ bundle exec rake gitlab:env:info RAILS_ENV=production
bundle exec rake gitlab:check RAILS_ENV=production
```
-Note: It is recommended to log into the `git` user using `sudo -i -u git` or `sudo su - git`. While the sudo commands provided by gitlabhq work in Ubuntu they do not always work in RHEL.
+Note: It is recommended to log into the `git` user using `sudo -i -u git` or `sudo su - git`. While the sudo commands provided by GitLab work in Ubuntu they do not always work in RHEL.
## GitLab.com
diff --git a/doc/development/background_migrations.md b/doc/development/background_migrations.md
index 0747224db30..d9e06206961 100644
--- a/doc/development/background_migrations.md
+++ b/doc/development/background_migrations.md
@@ -283,7 +283,7 @@ end
The final step runs for any un-migrated rows after all of the jobs have been
processed. This is in case a Sidekiq process running the background migrations
received SIGKILL, leading to the jobs being lost. (See
-[more reliable Sidekiq queue](https://gitlab.com/gitlab-org/gitlab-foss/issues/36791) for more information.)
+[more reliable Sidekiq queue](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/36791) for more information.)
If the application does not depend on the data being 100% migrated (for
instance, the data is advisory, and not mission-critical), then this final step
@@ -312,7 +312,7 @@ to migrate you database down and up, which can result in other background
migrations being called. That means that using `spy` test doubles with
`have_received` is encouraged, instead of using regular test doubles, because
your expectations defined in a `it` block can conflict with what is being
-called in RSpec hooks. See [issue #35351](https://gitlab.com/gitlab-org/gitlab/issues/18839)
+called in RSpec hooks. See [issue #35351](https://gitlab.com/gitlab-org/gitlab/-/issues/18839)
for more details.
## Best practices
diff --git a/doc/development/build_test_package.md b/doc/development/build_test_package.md
index d478d6e1653..858ff41b685 100644
--- a/doc/development/build_test_package.md
+++ b/doc/development/build_test_package.md
@@ -1,13 +1,13 @@
# Building a package for testing
While developing a new feature or modifying an existing one, it is helpful if an
-installable package (or a docker image) containing those changes is available
+installable package (or a Docker image) containing those changes is available
for testing. For this very purpose, a manual job is provided in the GitLab CI/CD
pipeline that can be used to trigger a pipeline in the Omnibus GitLab repository
that will create:
- A deb package for Ubuntu 16.04, available as a build artifact, and
-- A docker image, which is pushed to [Omnibus GitLab's container
+- A Docker image, which is pushed to [Omnibus GitLab's container
registry](https://gitlab.com/gitlab-org/omnibus-gitlab/container_registry)
(images titled `gitlab-ce` and `gitlab-ee` respectively and image tag is the
commit which triggered the pipeline).
@@ -24,7 +24,7 @@ trigger.
If you want to create a package from a specific branch, commit or tag of any of
the GitLab components (like GitLab Workhorse, Gitaly, GitLab Pages, etc.), you
-can specify the branch name, commit sha or tag in the component's respective
+can specify the branch name, commit SHA or tag in the component's respective
`*_VERSION` file. For example, if you want to build a package that uses the
branch `0-1-stable`, modify the content of `GITALY_SERVER_VERSION` to
`0-1-stable` and push the commit. This will create a manual job that can be
diff --git a/doc/development/changelog.md b/doc/development/changelog.md
index a0e9f9d3be3..5a8e05f888c 100644
--- a/doc/development/changelog.md
+++ b/doc/development/changelog.md
@@ -6,8 +6,8 @@ file, as well as information and history about our changelog process.
## Overview
Each bullet point, or **entry**, in our [`CHANGELOG.md`](https://gitlab.com/gitlab-org/gitlab/blob/master/CHANGELOG.md) file is
-generated from a single data file in the [`changelogs/unreleased/`](https://gitlab.com/gitlab-org/gitlab-foss/tree/master/changelogs/)
-(or corresponding EE) folder. The file is expected to be a [YAML](https://en.wikipedia.org/wiki/YAML) file in the
+generated from a single data file in the [`changelogs/unreleased/`](https://gitlab.com/gitlab-org/gitlab/tree/master/changelogs/unreleased/).
+The file is expected to be a [YAML](https://en.wikipedia.org/wiki/YAML) file in the
following format:
```yaml
@@ -282,7 +282,7 @@ multiple times per patch release. This was compounded when we had to release
multiple patches at once due to a security issue.
We needed to automate all of this manual work. So we
-[started brainstorming](https://gitlab.com/gitlab-org/gitlab-foss/issues/17826).
+[started brainstorming](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/17826).
After much discussion we settled on the current solution of one file per entry,
and then compiling the entries into the overall `CHANGELOG.md` file during the
[release process](https://gitlab.com/gitlab-org/release-tools).
diff --git a/doc/development/cicd/index.md b/doc/development/cicd/index.md
index db3f58d1d22..42d4b494544 100644
--- a/doc/development/cicd/index.md
+++ b/doc/development/cicd/index.md
@@ -10,7 +10,7 @@ the main components.
![CI software architecture](img/ci_architecture.png)
<!-- Editable diagram available at https://app.diagrams.net/#G1LFl-KW4fgpBPzz8VIH9rsOlAH4t0xwKj -->
-On the left side we have the events that can trigger a pipeline based on various events (trigged by a user or automation):
+On the left side we have the events that can trigger a pipeline based on various events (triggered by a user or automation):
- A `git push` is the most common event that triggers a pipeline.
- The [Web API](../../api/pipelines.md#create-a-new-pipeline).
@@ -98,7 +98,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](../../ci/runners/README.md#registering-a-shared-runner) using the registration token, the server knows what type of jobs it can execute. This depends on:
+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:
- The type of runner it is registered as:
- a shared runner
diff --git a/doc/development/code_comments.md b/doc/development/code_comments.md
index a71e2b3c792..b0e83b29cb0 100644
--- a/doc/development/code_comments.md
+++ b/doc/development/code_comments.md
@@ -9,6 +9,6 @@ Examples:
```ruby
# Deprecated scope until code_owner column has been migrated to rule_type.
-# To be removed with https://gitlab.com/gitlab-org/gitlab/issues/11834.
+# To be removed with https://gitlab.com/gitlab-org/gitlab/-/issues/11834.
scope :code_owner, -> { where(code_owner: true).or(where(rule_type: :code_owner)) }
```
diff --git a/doc/development/code_review.md b/doc/development/code_review.md
index a5ad7dc0f46..9c6cb1d0237 100644
--- a/doc/development/code_review.md
+++ b/doc/development/code_review.md
@@ -308,12 +308,13 @@ experience, refactors the existing code). Then:
- Seek to understand the author's perspective.
- If you don't understand a piece of code, _say so_. There's a good chance
someone else would be confused by it as well.
-- Do prefix your comment with "Not blocking:" if you have a small,
- non-mandatory improvement you wish to suggest. This lets the author
- know that they can optionally resolve this issue in this merge request
- or follow-up at a later stage.
+- Ensure the author is clear on what is required from them to address/resolve the suggestion.
+ - Consider using the [Conventional Comment format](https://conventionalcomments.org#format) to
+ convey your intent.
+ - For non-mandatory suggestions, decorate with (non-blocking) so the author knows they can
+ optionally resolve within the merge request or follow-up at a later stage.
- After a round of line notes, it can be helpful to post a summary note such as
- "LGTM :thumbsup:", or "Just a couple things to address."
+ "Looks good to me", or "Just a couple things to address."
- Assign the merge request to the author if changes are required following your
review.
@@ -357,8 +358,8 @@ When ready to merge:
- If the **latest [Pipeline for Merged Results](../ci/merge_request_pipelines/pipelines_for_merged_results/#pipelines-for-merged-results-premium)** finished less than 2 hours ago, you
might merge without starting a new pipeline as the merge request is close
enough to `master`.
- - If the merge request is from a fork, check how far behind `master` the
- source branch is. If it's more than 100 commits behind, ask the author to
+ - If the **merge request is from a fork**, we can't use [Pipelines for Merged Results](../ci/merge_request_pipelines/pipelines_for_merged_results/index.md#prerequisites), therefore, they're more prone to breaking `master`.
+ Check how far behind `master` the source branch is. If it's more than 100 commits behind, ask the author to
rebase it before merging.
- If [master is broken](https://about.gitlab.com/handbook/engineering/workflow/#broken-master),
in addition to the two above rules, check that any failure also happens
@@ -380,7 +381,7 @@ Merge Results against the latest `master` at the time of the pipeline creation.
One of the most difficult things during code review is finding the right
balance in how deep the reviewer can interfere with the code created by a
-reviewee.
+author.
- Learning how to find the right balance takes time; that is why we have
reviewers that become maintainers after some time spent on reviewing merge
@@ -388,7 +389,7 @@ reviewee.
- Finding bugs and improving code style is important, but thinking about good
design is important as well. Building abstractions and good design is what
makes it possible to hide complexity and makes future changes easier.
-- Asking the reviewee to change the design sometimes means the complete rewrite
+- Asking the author to change the design sometimes means the complete rewrite
of the contributed code. It's usually a good idea to ask another maintainer or
reviewer before doing it, but have the courage to do it when you believe it is
important.
@@ -401,7 +402,7 @@ reviewee.
- There is a difference in doing things right and doing things right now.
Ideally, we should do the former, but in the real world we need the latter as
well. A good example is a security fix which should be released as soon as
- possible. Asking the reviewee to do the major refactoring in the merge
+ possible. Asking the author to do the major refactoring in the merge
request that is an urgent fix should be avoided.
- Doing things well today is usually better than doing something perfectly
tomorrow. Shipping a kludge today is usually worse than doing something well
@@ -501,7 +502,7 @@ Properties of customer critical merge requests:
- The DRI will assign 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.
-- It is required to adhere to GitLab [values](https://about.gitlab.com/handbook/values.md) and processes when working on customer critical merge requests, taking particular note of family and friends first/work second, definition of done, iteration, and release when it's ready.
+- It is required to adhere to GitLab [values](https://about.gitlab.com/handbook/values/) and processes when working on customer critical merge requests, taking particular note of family and friends first/work second, definition of done, iteration, and release when it's ready.
- Customer critical merge requests are required to not reduce security, introduce data-loss risk, reduce availability, nor break existing functionality per the process for [prioritizing technical decisions](https://about.gitlab.com/handbook/engineering/#prioritizing-technical-decisions.md).
- On customer critical requests, it is _recommended_ that those involved _consider_ coordinating synchronously (Zoom, Slack) in addition to asynchronously (merge requests comments) if they believe this will reduce elapsed time to merge even though this _may_ sacrifice [efficiency](https://about.gitlab.com/company/culture/all-remote/asynchronous/#evaluating-efficiency.md).
- After a customer critical merge request is merged, a retrospective must be completed with the intention of reducing the frequency of future customer critical merge requests.
diff --git a/doc/development/contributing/index.md b/doc/development/contributing/index.md
index aebff633f58..cea9043a333 100644
--- a/doc/development/contributing/index.md
+++ b/doc/development/contributing/index.md
@@ -6,8 +6,8 @@ to contribute to GitLab in a way that is easy for everyone.
For a first-time step-by-step guide to the contribution process, see our
[Contributing to GitLab](https://about.gitlab.com/community/contribute/) page.
-Looking for something to work on? Look for issues with the label
-[`~Accepting merge requests`](#how-to-contribute).
+Looking for something to work on? See the
+[How to contribute](#how-to-contribute) section for more information.
GitLab comes in two flavors:
@@ -76,9 +76,12 @@ Sign up for the mailing list, answer GitLab questions on StackOverflow or respon
## How to contribute
-If you want to contribute to GitLab,
-[issues with the `~Accepting merge requests` label](issue_workflow.md#label-for-community-contributors)
-are a great place to start.
+If you would like to contribute to GitLab:
+
+- Issues with the
+ [`~Accepting merge requests` label](issue_workflow.md#label-for-community-contributors)
+ are a great place to start.
+- Consult the [Contribution Flow](#contribution-flow) section to learn the process.
If you have any questions or need help visit [Getting Help](https://about.gitlab.com/get-help/) to
learn how to communicate with GitLab. We have a [Gitter channel for contributors](https://gitter.im/gitlab/contributors),
@@ -96,25 +99,77 @@ a Merge Request.
For more information, see the [`gitlab-development-kit`](https://gitlab.com/gitlab-org/gitlab-development-kit)
project.
-## Contribution Flow
-
-When contributing to GitLab, your merge request is subject to review by merge request maintainers of a particular specialty.
-
-When you submit code to GitLab, we really want it to get merged, but there will be times when it will not be merged.
-
-When maintainers are reading through a merge request they may request guidance from other maintainers. If merge request maintainers conclude that the code should not be merged, our reasons will be fully disclosed. If it has been decided that the code quality is not up to GitLab’s standards, the merge request maintainer will refer the author to our docs and code style guides, and provide some guidance.
-
-Sometimes style guides will be followed but the code will lack structural integrity, or the maintainer will have reservations about the code’s overall quality. When there is a reservation the maintainer will inform the author and provide some guidance. The author may then choose to update the merge request. Once the merge request has been updated and reassigned to the maintainer, they will review the code again. Once the code has been resubmitted any number of times, the maintainer may choose to close the merge request with a summary of why it will not be merged, as well as some guidance. If the merge request is closed the maintainer will be open to discussion as to how to improve the code so it can be approved in the future.
-
-GitLab will do its best to review community contributions as quickly as possible. Specially appointed developers review community contributions daily. You may take a look at the [team page](https://about.gitlab.com/company/team/) for the merge request coach who specializes in the type of code you have written and mention them in the merge request. For example, if you have written some JavaScript in your code then you should mention the frontend merge request coach. If your code has multiple disciplines you may mention multiple merge request coaches.
-
-GitLab receives a lot of community contributions, so if your code has not been reviewed within two days (excluding weekend and public holidays) of its initial submission feel free to re-mention the appropriate merge request coach.
-
-When submitting code to GitLab, you may feel that your contribution requires the aid of an external library. If your code includes an external library please provide a link to the library, as well as reasons for including it.
-
-When your code contains more than 500 changes, any major breaking changes, or an external library, `@mention` a maintainer in the merge request. If you are not sure who to mention, the reviewer will add one early in the merge request process.
-
-### Issues workflow
+### Contribution flow
+
+The general flow of contributing to GitLab is:
+
+1. [Create a fork](../../user/project/repository/forking_workflow.md#creating-a-fork)
+ of GitLab. In some cases, you will want to set up the
+ [GitLab Development Kit](https://gitlab.com/gitlab-org/gitlab-development-kit) to
+ [develop against your fork](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/master/doc/index.md#develop-in-your-own-gitlab-fork).
+1. Make your changes in your fork.
+1. When you're ready, [create a new merge request](../../user/project/merge_requests/creating_merge_requests.md).
+1. In the merge request's description:
+ - Ensure you provide complete and accurate information.
+ - Review the provided checklist.
+1. Assign the merge request (if possible) to, or `@mention`, one of the
+ [code owners](../../user/project/code_owners.md) for the relevant project,
+ and explain that you are ready for review.
+
+When you submit code to GitLab, we really want it to get merged! However, we always review
+submissions carefully, and this takes time. Code submissions will usually be reviewed by two
+[domain experts](../code_review.md#domain-experts) before being merged:
+
+- A [reviewer](../code_review.md#the-responsibility-of-the-reviewer).
+- A [maintainer](../code_review.md#the-responsibility-of-the-maintainer).
+
+Keep the following in mind when submitting merge requests:
+
+- When reviewers are reading through a merge request they may request guidance from other
+ reviewers.
+- If the code quality is found to not meet GitLab’s standards, the merge request reviewer will
+ provide guidance and refer the author to our:
+ - [Documentation](../documentation/styleguide.md) style guide.
+ - Code style guides.
+- Sometimes style guides will be followed but the code will lack structural integrity, or the
+ reviewer will have reservations about the code’s overall quality. When there is a reservation,
+ the reviewer will inform the author and provide some guidance.
+- Though GitLab generally allows anyone to indicate
+ [approval](../../user/project/merge_requests/merge_request_approvals.md) of merge requests, the
+ maintainer may require [approvals from certain reviewers](../code_review.md#approval-guidelines)
+ before merging a merge request.
+- After review, the author may be asked to update the merge request. Once the merge request has been
+ updated and reassigned to the reviewer, they will review the code again. This process may repeat
+ any number of times before merge, to help make the contribution the best it can be.
+
+Sometimes a maintainer may choose to close a merge request. They will fully disclose why it will not
+be merged, as well as some guidance. The maintainers will be open to discussion about how to change
+the code so it can be approved and merged in the future.
+
+GitLab will do its best to review community contributions as quickly as possible. Specially
+appointed developers review community contributions daily. Look at the
+[team page](https://about.gitlab.com/company/team/) for the merge request coach who specializes in
+the type of code you have written and mention them in the merge request. For example, if you have
+written some front-end code, you should `@mention` the frontend merge request coach. If
+your code has multiple disciplines, you may `@mention` multiple merge request coaches.
+
+GitLab receives a lot of community contributions. If your code has not been reviewed within two
+working days of its initial submission, feel free to `@mention` all merge request coaches with
+`@gitlab-org/coaches` to get their attention.
+
+When submitting code to GitLab, you may feel that your contribution requires the aid of an external
+library. If your code includes an external library, please provide a link to the library, as well as
+reasons for including it.
+
+`@mention` a maintainer in merge requests that contain:
+
+- More than 500 changes.
+- Any major breaking changes.
+- External libraries.
+
+If you are not sure who to mention, the reviewer will do this for you early in the merge request process.
+
+#### Issues workflow
This [documentation](issue_workflow.md) outlines the current issue workflow:
@@ -127,7 +182,7 @@ This [documentation](issue_workflow.md) outlines the current issue workflow:
- [Technical and UX debt](issue_workflow.md#technical-and-ux-debt)
- [Technical debt in follow-up issues](issue_workflow.md#technical-debt-in-follow-up-issues)
-### Merge requests workflow
+#### Merge requests workflow
This [documentation](merge_request_workflow.md) outlines the current merge request process.
diff --git a/doc/development/contributing/issue_workflow.md b/doc/development/contributing/issue_workflow.md
index be416bf636e..f70299cbfc2 100644
--- a/doc/development/contributing/issue_workflow.md
+++ b/doc/development/contributing/issue_workflow.md
@@ -2,7 +2,7 @@
## Issue tracker guidelines
-**[Search the issue tracker](https://gitlab.com/gitlab-org/gitlab/issues)** for similar entries before
+**[Search the issue tracker](https://gitlab.com/gitlab-org/gitlab/-/issues)** for similar entries before
submitting your own, there's a good chance somebody else had the same issue or
feature proposal. Show your support with an award emoji and/or join the
discussion.
@@ -16,7 +16,7 @@ see fit.
Our issue triage policies are [described in our handbook](https://about.gitlab.com/handbook/engineering/quality/issue-triage/).
You are very welcome to help the GitLab team triage issues.
-We also organize [issue bash events](https://gitlab.com/gitlab-org/gitlab-foss/issues/17815)
+We also organize [issue bash events](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/17815)
once every quarter.
The most important thing is making sure valid issues receive feedback from the
@@ -351,15 +351,15 @@ features from GitLab EE to GitLab CE, related issues would be labeled with
~"stewardship".
A recent example of this was the issue for
-[bringing the time tracking API to GitLab CE](https://gitlab.com/gitlab-org/gitlab-foss/issues/25517#note_20019084).
+[bringing the time tracking API to GitLab CE](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/25517#note_20019084).
## Feature proposals
To create a feature proposal, open an issue on the
-[issue tracker](https://gitlab.com/gitlab-org/gitlab/issues).
+[issue tracker](https://gitlab.com/gitlab-org/gitlab/-/issues).
In order to help track the feature proposals, we have created a
-[`feature`](https://gitlab.com/gitlab-org/gitlab/issues?label_name=feature) label. For the time being, users that are not members
+[`feature`](https://gitlab.com/gitlab-org/gitlab/-/issues?label_name=feature) label. For the time being, users that are not members
of the project cannot add labels. You can instead ask one of the [core team](https://about.gitlab.com/community/core-team/)
members to add the label ~feature to the issue or add the following
code snippet right after your description in a new line: `~feature`.
@@ -403,7 +403,7 @@ below will make it easy to manage this, without unnecessary overhead.
Every monthly release has a corresponding issue on the CE issue tracker to keep
track of functionality broken by that release and any fixes that need to be
included in a patch release (see
-[8.3 Regressions](https://gitlab.com/gitlab-org/gitlab-foss/issues/4127) as an example).
+[8.3 Regressions](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/4127) as an example).
As outlined in the issue description, the intended workflow is to post one note
with a reference to an issue describing the regression, and then to update that
@@ -420,7 +420,7 @@ in the regression issue as fixes are addressed.
## Technical and UX debt
In order to track things that can be improved in GitLab's codebase,
-we use the ~"technical debt" label in [GitLab's issue tracker](https://gitlab.com/gitlab-org/gitlab/issues).
+we use the ~"technical debt" label in [GitLab's issue tracker](https://gitlab.com/gitlab-org/gitlab/-/issues).
For missed user experience requirements, we use the ~"UX debt" label.
These labels should be added to issues that describe things that can be improved,
diff --git a/doc/development/contributing/merge_request_workflow.md b/doc/development/contributing/merge_request_workflow.md
index a70fadfe8a9..14c6b0b1073 100644
--- a/doc/development/contributing/merge_request_workflow.md
+++ b/doc/development/contributing/merge_request_workflow.md
@@ -221,7 +221,7 @@ requirements.
1. [Changelog entry added](../changelog.md), if necessary.
1. Reviewed by relevant (UX/FE/BE/tech writing) reviewers and all concerns are addressed.
1. Merged by a project maintainer.
-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. 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) 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.
diff --git a/doc/development/creating_enums.md b/doc/development/creating_enums.md
index e2ebad538d9..3833f771bb5 100644
--- a/doc/development/creating_enums.md
+++ b/doc/development/creating_enums.md
@@ -83,7 +83,7 @@ module EE
end
```
-This looks working as a workaround, however, this approach has some donwside that:
+This looks working as a workaround, however, this approach has some downsides that:
- Features could move from EE to FOSS or vice versa. Therefore, the offset might be mixed between FOSS and EE in the future.
e.g. When you move `activity_limit_exceeded` to FOSS, you'll see `{ unknown_failure: 0, config_error: 1, activity_limit_exceeded: 1_000 }`.
diff --git a/doc/development/database/index.md b/doc/development/database/index.md
new file mode 100644
index 00000000000..665af623059
--- /dev/null
+++ b/doc/development/database/index.md
@@ -0,0 +1,48 @@
+# Database guides
+
+## Tooling
+
+- [Understanding EXPLAIN plans](../understanding_explain_plans.md)
+- [explain.depesz.com](https://explain.depesz.com/) or [explain.dalibo.com](https://explain.dalibo.com/) for visualizing the output of `EXPLAIN`
+- [pgFormatter](http://sqlformat.darold.net/) a PostgreSQL SQL syntax beautifier
+
+## Migrations
+
+- [What requires downtime?](../what_requires_downtime.md)
+- [SQL guidelines](../sql.md) for working with SQL queries
+- [Migrations style guide](../migration_style_guide.md) for creating safe SQL migrations
+- [Testing Rails migrations](../testing_guide/testing_migrations_guide.md) guide
+- [Post deployment migrations](../post_deployment_migrations.md)
+- [Background migrations](../background_migrations.md)
+- [Swapping tables](../swapping_tables.md)
+- [Deleting migrations](../deleting_migrations.md)
+
+## Debugging
+
+- Tracing the source of an SQL query using query comments with [Marginalia](../database_query_comments.md)
+- Tracing the source of an SQL query in Rails console using [Verbose Query Logs](https://guides.rubyonrails.org/debugging_rails_applications.html#verbose-query-logs)
+
+## Best practices
+
+- [Adding database indexes](../adding_database_indexes.md)
+- [Foreign keys & associations](../foreign_keys.md)
+- [Adding a foreign key constraint to an existing column](add_foreign_key_to_existing_column.md)
+- [`NOT NULL` constraints](not_null_constraints.md)
+- [Strings and the Text data type](strings_and_the_text_data_type.md)
+- [Single table inheritance](../single_table_inheritance.md)
+- [Polymorphic associations](../polymorphic_associations.md)
+- [Serializing data](../serializing_data.md)
+- [Hash indexes](../hash_indexes.md)
+- [Storing SHA1 hashes as binary](../sha1_as_binary.md)
+- [Iterating tables in batches](../iterating_tables_in_batches.md)
+- [Insert into tables in batches](../insert_into_tables_in_batches.md)
+- [Ordering table columns](../ordering_table_columns.md)
+- [Verifying database capabilities](../verifying_database_capabilities.md)
+- [Database Debugging and Troubleshooting](../database_debugging.md)
+- [Query Count Limits](../query_count_limits.md)
+- [Creating enums](../creating_enums.md)
+
+## Case studies
+
+- [Database case study: Filtering by label](../filtering_by_label.md)
+- [Database case study: Namespaces storage statistics](../namespaces_storage_statistics.md)
diff --git a/doc/development/database/not_null_constraints.md b/doc/development/database/not_null_constraints.md
new file mode 100644
index 00000000000..e4dec2afa10
--- /dev/null
+++ b/doc/development/database/not_null_constraints.md
@@ -0,0 +1,217 @@
+# `NOT NULL` constraints
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/38358) in GitLab 13.0.
+
+All attributes that should not have `NULL` as a value, should be defined as `NOT NULL`
+columns in the database.
+
+Depending on the application logic, `NOT NULL` columns should either have a `presence: true`
+validation defined in their Model or have a default value as part of their database definition.
+As an example, the latter can be true for boolean attributes that should always have a non-`NULL`
+value, but have a well defined default value that the application does not need to enforce each
+time (for example, `active=true`).
+
+## Create a new table with `NOT NULL` columns
+
+When adding a new table, all `NOT NULL` columns should be defined as such directly inside `create_table`.
+
+For example, consider a migration that creates a table with two `NOT NULL` columns,
+`db/migrate/20200401000001_create_db_guides.rb`:
+
+```ruby
+class CreateDbGuides < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def change
+ create_table :db_guides do |t|
+ t.bigint :stars, default: 0, null: false
+ t.bigint :guide, null: false
+ end
+ end
+end
+```
+
+## Add a `NOT NULL` column to an existing table
+
+With PostgreSQL 11 being the minimum version since GitLab 13.0, adding columns with `NULL` and/or
+default values has become much easier and the standard `add_column` helper should be used in all cases.
+
+For example, consider a migration that adds a new `NOT NULL` column `active` to table `db_guides`,
+`db/migrate/20200501000001_add_active_to_db_guides.rb`:
+
+```ruby
+class AddExtendedTitleToSprints < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def change
+ add_column :db_guides, :active, :boolean, default: true, null: false
+ end
+end
+```
+
+## Add a `NOT NULL` constraint to an existing column
+
+Adding `NOT NULL` to existing database columns requires multiple steps split into at least two
+different releases:
+
+1. Release `N.M` (current release)
+
+ - Ensure the constraint is enforced at the application level (i.e. add a model validation).
+ - Add a post-deployment migration to add the `NOT NULL` constraint with `validate: false`.
+ - Add a post-deployment migration to fix the existing records.
+
+ NOTE: **Note:**
+ Depending on the size of the table, a background migration for cleanup could be required in the next release.
+ See the [`NOT NULL` constraints on large tables](not_null_constraints.md#not-null-constraints-on-large-tables) section for more information.
+
+ - Create an issue for the next milestone to validate the `NOT NULL` constraint.
+
+1. Release `N.M+1` (next release)
+
+ - Validate the `NOT NULL` constraint using a post-deployment migration.
+
+### Example
+
+Considering a given release milestone, such as 13.0, a model validation has been added into `epic.rb`
+to require a description:
+
+```ruby
+class Epic < ApplicationRecord
+ validates :description, presence: true
+end
+```
+
+The same constraint should be added at the database level for consistency purposes.
+We only want to enforce the `NOT NULL` constraint without setting a default, as we have decided
+that all epics should have a user-generated description.
+
+After checking our production database, we know that there are `epics` with `NULL` descriptions,
+so we can not add and validate the constraint in one step.
+
+NOTE: **Note:**
+Even if we did not have any epic with a `NULL` description, another instance of GitLab could have
+such records, so we would follow the same process either way.
+
+#### Prevent new invalid records (current release)
+
+We first add the `NOT NULL` constraint with a `NOT VALID` parameter, which enforces consistency
+when new records are inserted or current records are updated.
+
+In the example above, the existing epics with a `NULL` description will not be affected and you'll
+still be able to update records in the `epics` table. However, when you try to update or insert
+an epic without providing a description, the constraint causes a database error.
+
+Adding or removing a `NOT NULL` clause requires that any application changes are deployed _first_.
+Thus, adding a `NOT NULL` constraint to an existing column should happen in a post-deployment migration.
+
+Still in our example, for the 13.0 milestone example (current), we add the `NOT NULL` constraint
+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
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ # This will add the `NOT NULL` constraint WITHOUT validating it
+ add_not_null_constraint :epics, :description, validate: false
+ end
+
+ def down
+ # Down is required as `add_not_null_constraint` is not reversible
+ remove_not_null_constraint :epics, :description
+ end
+end
+```
+
+#### Data migration to fix existing records (current release)
+
+The approach here depends on the data volume and the cleanup strategy. The number of records that
+must be fixed on GitLab.com is a nice indicator that will help us decide whether to use a
+post-deployment migration or a background data migration:
+
+- If the data volume is less than `1000` records, then the data migration can be executed within the post-migration.
+- If the data volume is higher than `1000` records, it's advised to create a background migration.
+
+When unsure about which option to use, please contact the Database team for advice.
+
+Back to our example, the epics table is not considerably large nor frequently accessed,
+so we are going to add a post-deployment migration for the 13.0 milestone (current),
+`db/post_migrate/20200501000002_cleanup_epics_with_null_description.rb`:
+
+```ruby
+class CleanupEpicsWithNullDescription < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ # With BATCH_SIZE=1000 and epics.count=29500 on GitLab.com
+ # - 30 iterations will be run
+ # - each requires on average ~150ms
+ # Expected total run time: ~5 seconds
+ BATCH_SIZE = 1000
+
+ disable_ddl_transaction!
+
+ class Epic < ActiveRecord::Base
+ include EachBatch
+
+ self.table_name = 'epics'
+ end
+
+ def up
+ Epic.each_batch(of: BATCH_SIZE) do |relation|
+ relation.
+ where('description IS NULL').
+ update_all(description: 'No description')
+ end
+ end
+
+ def down
+ # no-op : can't go back to `NULL` without first dropping the `NOT NULL` constraint
+ end
+end
+```
+
+#### Validate the text limit (next release)
+
+Validating the `NOT NULL` constraint will scan the whole table and make sure that each record is correct.
+
+Still in our example, for the 13.1 milestone (next), we run the `validate_not_null_constraint`
+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
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ validate_not_null_constraint :epics, :description
+ end
+
+ def down
+ # no-op
+ end
+end
+```
+
+## `NOT NULL` constraints on large tables
+
+If you have to clean up a text column for a really [large table](https://gitlab.com/gitlab-org/gitlab/-/blob/master/rubocop/migration_helpers.rb#L12)
+(for example, the `artifacts` in `ci_builds`), your background migration will go on for a while and
+it will need an additional [background migration cleaning up](../background_migrations.md#cleaning-up)
+in the release after adding the data migration.
+
+In that rare case you will need 3 releases end-to-end:
+
+1. Release `N.M` - Add the `NOT NULL` constraint and the background-migration to fix the existing records.
+1. Release `N.M+1` - Cleanup the background migration.
+1. Release `N.M+2` - Validate the `NOT NULL` constraint.
+
+For these cases, please consult the database team early in the update cycle. The `NOT NULL`
+constraint may not be required or other options could exist that do not affect really large
+or frequently accessed tables.
diff --git a/doc/development/database/strings_and_the_text_data_type.md b/doc/development/database/strings_and_the_text_data_type.md
new file mode 100644
index 00000000000..0e77e3972e0
--- /dev/null
+++ b/doc/development/database/strings_and_the_text_data_type.md
@@ -0,0 +1,288 @@
+# Strings and the Text data type
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30453) in GitLab 13.0.
+
+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 by using the `add_text_limit` migration helper.
+
+The `text` data type can not be defined with a limit, so `add_text_limit` is enforcing that by
+adding a [check constraint](https://www.postgresql.org/docs/11/ddl-constraints.html) on the
+column and then validating it at a followup step.
+
+## Background info
+
+The reason we always want to use `text` instead of `string` is that `string` columns have the
+disadvantage that if you want to update their limit, you have to run an `ALTER TABLE ...` command.
+
+While a limit is added, the `ALTER TABLE ...` command requires an `EXCLUSIVE LOCK` on the table, which
+is held throughout the process of updating the column and while validating all existing records, a
+process that can take a while for large tables.
+
+On the other hand, texts are [more or less equivalent to strings](https://www.depesz.com/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text/) in PostgreSQL,
+while having the additional advantage that adding a limit on an existing column or updating their
+limit does not require the very costly `EXCLUSIVE LOCK` to be held throughout the validation phase.
+We can start by updating the constraint with the valid option off, which requires an `EXCLUSIVE LOCK`
+but only for updating the declaration of the columns. We can then validate it at a later step using
+`VALIDATE CONSTRAINT`, which requires only a `SHARE UPDATE EXCLUSIVE LOCK` (only conflicts with other
+validations and index creation while it allows reads and writes).
+
+## 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.
+
+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]
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ unless table_exists?(:db_guides)
+ create_table :db_guides do |t|
+ t.bigint :stars, default: 0, null: false
+ t.text :title
+ t.text :notes
+ end
+ end
+
+ # The following add the constraints and validate them immediately (no data in the table)
+ add_text_limit :db_guides, :title, 128
+ add_text_limit :db_guides, :notes, 1024
+ end
+
+ def down
+ # No need to drop the constraints, drop_table takes care of everything
+ drop_table :db_guides
+ end
+end
+```
+
+Adding a check constraint requires an exclusive lock while the `ALTER TABLE` that adds is running.
+As we don't want the exclusive lock to be held for the duration of a transaction, `add_text_limit`
+must always run in a migration with `disable_ddl_transaction!`.
+
+Also, note that we have to add a check that the table exists so that the migration can be repeated
+in case of a failure.
+
+## 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
+is held for a brief amount of time, the time `add_column` needs to complete its execution can vary
+depending on how frequently the table is accessed. For example, acquiring an exclusive lock for a very
+frequently accessed table may take minutes in GitLab.com and requires the use of `with_lock_retries`.
+
+For these reasons, it is advised to add the text limit on a separate migration than the `add_column` one.
+
+For example, consider a migration that adds a new text column `extended_title` to table `sprints`,
+`db/migrate/20200501000001_add_extended_title_to_sprints.rb`:
+
+```ruby
+class AddExtendedTitleToSprints < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ # rubocop:disable Migration/AddLimitToTextColumns
+ # limit is added in 20200501000002_add_text_limit_to_sprints_extended_title
+ def change
+ add_column :sprints, :extended_title, :text
+ end
+ # rubocop:enable Migration/AddLimitToTextColumns
+end
+```
+
+A second migration should follow the first one with a limit added to `extended_title`,
+`db/migrate/20200501000002_add_text_limit_to_sprints_extended_title.rb`:
+
+```ruby
+class AddTextLimitToSprintsExtendedTitle < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_text_limit :sprints, :extended_title, 512
+ end
+
+ def down
+ # Down is required as `add_text_limit` is not reversible
+ remove_text_limit :sprints, :extended_title
+ end
+end
+```
+
+## Add a text limit constraint to an existing column
+
+Adding text limits to existing database columns requires multiple steps split into at least two different releases:
+
+1. Release `N.M` (current release)
+
+ - Add a post-deployment migration to add the limit to the text column with `validate: false`.
+ - Add a post-deployment migration to fix the existing records.
+
+ NOTE: **Note:**
+ Depending on the size of the table, a background migration for cleanup could be required in the next release.
+ See [text limit constraints on large tables](strings_and_the_text_data_type.md#text-limit-constraints-on-large-tables) for more information.
+
+ - Create an issue for the next milestone to validate the text limit.
+
+1. Release `N.M+1` (next release)
+
+ - Validate the text limit using a post-deployment migration.
+
+### Example
+
+Let's assume we want to add a `1024` limit to `issues.title_html` for a given release milestone,
+such as 13.0.
+
+Issues is a pretty busy and large table with more than 25 million rows, so we don't want to lock all
+other processes that try to access it while running the update.
+
+Also, after checking our production database, we know that there are `issues` with more characters in
+their title than the 1024 character limit, so we can not add and validate the constraint in one step.
+
+NOTE: **Note:**
+Even if we did not have any record with a title larger than the provided limit, another
+instance of GitLab could have such records, so we would follow the same process either way.
+
+#### Prevent new invalid records (current release)
+
+We first add the limit as a `NOT VALID` check constraint to the table, which enforces consistency when
+new records are inserted or current records are updated.
+
+In the example above, the existing issues with more than 1024 characters in their title will not be
+affected and you'll be still able to update records in the `issues` table. However, when you'd try
+to update the `title_html` with a title that has more than 1024 characters, the constraint causes
+a database error.
+
+Adding or removing a constraint to an existing attribute requires that any application changes are
+deployed _first_, [otherwise servers still in the old version of the application may try to update the
+attribute with invalid values](../multi_version_compatibility.md#ci-artifact-uploads-were-failing).
+For these reasons, `add_text_limit` should run in a post-deployment migration.
+
+Still in our example, for the 13.0 milestone (current), consider that the following validation
+has been added to model `Issue`:
+
+```ruby
+validates :title_html, length: { maximum: 1024 }
+```
+
+We can also update the database in the same milestone by adding the text limit with `validate: false`
+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
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ # This will add the constraint WITHOUT validating it
+ add_text_limit :issues, :title_html, 1024, validate: false
+ end
+
+ def down
+ # Down is required as `add_text_limit` is not reversible
+ remove_text_limit :issues, :title_html
+ end
+end
+```
+
+#### Data migration to fix existing records (current release)
+
+The approach here depends on the data volume and the cleanup strategy. The number of records that must
+be fixed on GitLab.com is a nice indicator that will help us decide whether to use a post-deployment
+migration or a background data migration:
+
+- If the data volume is less than `1,000` records, then the data migration can be executed within the post-migration.
+- If the data volume is higher than `1,000` records, it's advised to create a background migration.
+
+When unsure about which option to use, please contact the Database team for advice.
+
+Back to our example, the issues table is considerably large and frequently accessed, so we are going
+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
+
+ # Info on how many records will be affected on GitLab.com
+ # time each batch needs to run on average, etc ...
+ BATCH_SIZE = 5000
+ DELAY_INTERVAL = 2.minutes.to_i
+
+ # Background migration will update issues whose title is longer than 1024 limit
+ ISSUES_BACKGROUND_MIGRATION = 'CapTitleLengthOnIssues'.freeze
+
+ disable_ddl_transaction!
+
+ class Issue < ActiveRecord::Base
+ include EachBatch
+
+ self.table_name = 'issues'
+ end
+
+ def up
+ queue_background_migration_jobs_by_range_at_intervals(
+ Issue.where('char_length(title_html) > 1024'),
+ ISSUES_MIGRATION,
+ DELAY_INTERVAL,
+ batch_size: BATCH_SIZE
+ )
+ end
+
+ def down
+ # no-op : the part of the title_html after the limit is lost forever
+ end
+end
+```
+
+To keep this guide short, we skipped the definition of the background migration and only
+provided a high level example of the post-deployment migration that is used to schedule the batches.
+You can find more info on the guide about [background migrations](../background_migrations.md)
+
+#### Validate the text limit (next release)
+
+Validating the text limit will scan the whole table and make sure that each record is correct.
+
+Still in our example, for the 13.1 milestone (next), we run the `validate_text_limit` migration
+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
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ validate_text_limit :issues, :title_html
+ end
+
+ def down
+ # no-op
+ end
+end
+```
+
+## Text limit constraints on large tables
+
+If you have to clean up a text column for a really [large table](https://gitlab.com/gitlab-org/gitlab/-/blob/master/rubocop/rubocop-migrations.yml#L3)
+(for example, the `artifacts` in `ci_builds`), your background migration will go on for a while and
+it will need an additional [background migration cleaning up](../background_migrations.md#cleaning-up)
+in the release after adding the data migration.
+
+In that rare case you will need 3 releases end-to-end:
+
+1. Release `N.M` - Add the text limit and the background migration to fix the existing records.
+1. Release `N.M+1` - Cleanup the background migration.
+1. Release `N.M+2` - Validate the text limit.
diff --git a/doc/development/database_debugging.md b/doc/development/database_debugging.md
index 3753baa3c63..629aea5b121 100644
--- a/doc/development/database_debugging.md
+++ b/doc/development/database_debugging.md
@@ -70,7 +70,9 @@ Use these instructions for exploring the GitLab database while developing with t
1. **PostgreSQL user to authenticate as**: usually your local username, unless otherwise specified during PostgreSQL installation.
1. **Password of the PostgreSQL user**: the password you set when installing PostgreSQL.
1. **Port number to connect to**: `5432` (default).
- 1. **Use an ssl connection?** This depends on your installation. Options are:
+ 1. <!-- vale gitlab.Spelling = NO -->
+ **Use an ssl connection?**
+ <!-- vale gitlab.rulename = NO --> This depends on your installation. Options are:
- **Use Secure Connection**
- **Standard Connection** (default)
1. **(Optional) The database to connect to**: `gitlabhq_development`.
@@ -86,7 +88,7 @@ of the extension documentation.
### `ActiveRecord::PendingMigrationError` with Spring
-When running specs with the [Spring preloader](rake_tasks.md#speed-up-tests-rake-tasks-and-migrations),
+When running specs with the [Spring pre-loader](rake_tasks.md#speed-up-tests-rake-tasks-and-migrations),
the test database can get into a corrupted state. Trying to run the migration or
dropping/resetting the test database has no effect.
diff --git a/doc/development/database_review.md b/doc/development/database_review.md
index aa7ebb3756f..5405a8808f0 100644
--- a/doc/development/database_review.md
+++ b/doc/development/database_review.md
@@ -81,13 +81,20 @@ 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/migration_helpers.rb#L12) 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 [`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.
- 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:
+ - Execution time largely varies between `#database-lab` and GitLab.com, but an elevated execution time from `#database-lab`
+ can give a hint that the execution on GitLab.com will also be considerably high.
+ - If the execution from `#database-lab` is longer than `1h`, the index should be moved to a [post-migration](post_deployment_migrations.md).
+ Keep in mind that in this case you may need to split the migration and the application changes in separate releases to ensure the index
+ will be in place when the code that needs it will be deployed.
#### Preparation when adding or modifying queries
- Write the raw SQL in the MR description. Preferably formatted
- nicely with [sqlformat.darold.net](http://sqlformat.darold.net) or
+ nicely with [pgFormatter](https://sqlformat.darold.net) or
[paste.depesz.com](https://paste.depesz.com).
- Include the output of `EXPLAIN (ANALYZE, BUFFERS)` of the relevant
queries in the description. If the output is too long, wrap it in
@@ -134,6 +141,9 @@ the following preparations into account.
- [Check indexes are present for foreign keys](migration_style_guide.md#adding-foreign-key-constraints)
- Ensure that migrations execute in a transaction or only contain
concurrent index/foreign key helpers (with transactions disabled)
+ - If an index to a large table is added and its execution time was elevated (more than 1h) on `#database-lab`:
+ - Ensure it was added in a post-migration.
+ - Maintainer: After the merge request is merged, notify Release Managers about it on `#f_upcoming_release` Slack channel.
- Check consistency with `db/structure.sql` and that migrations are [reversible](migration_style_guide.md#reversibility)
- Check queries timing (If any): Queries executed in a migration
need to fit comfortably within `15s` - preferably much less than that - on GitLab.com.
diff --git a/doc/development/db_dump.md b/doc/development/db_dump.md
index bb740d12f7b..4095932e44c 100644
--- a/doc/development/db_dump.md
+++ b/doc/development/db_dump.md
@@ -2,7 +2,7 @@
Sometimes it is useful to import the database from a production environment
into a staging environment for testing. The procedure below assumes you have
-SSH+sudo access to both the production environment and the staging VM.
+SSH and `sudo` access to both the production environment and the staging VM.
**Destroy your staging VM** when you are done with it. It is important to avoid
data leaks.
@@ -20,7 +20,7 @@ sudo gitlab-ctl stop sidekiq
```
Next, we let the production environment stream a compressed SQL dump to our
-local machine via SSH, and redirect this stream to a psql client on the staging
+local machine via SSH, and redirect this stream to a `psql` client on the staging
VM.
```shell
diff --git a/doc/development/deleting_migrations.md b/doc/development/deleting_migrations.md
index 3ac039a1692..8aa16710d55 100644
--- a/doc/development/deleting_migrations.md
+++ b/doc/development/deleting_migrations.md
@@ -5,7 +5,7 @@ the possibility of the migration already been included in past releases or in th
Because of it, it's not possible to delete existing migrations, as that could lead to:
-- Schema inconsistency, as changes introduced into the database were not rollbacked properly.
+- Schema inconsistency, as changes introduced into the database were not rolled back properly.
- Leaving a record on the `schema_versions` table, that points out to migration that no longer exists on the codebase.
Instead of deleting we can opt for disabling the migration.
@@ -22,7 +22,7 @@ Migrations can be disabled if:
In order to disable a migration, the following steps apply to all types of migrations:
-1. Turn the migration into a noop by removing the code inside `#up`, `#down`
+1. Turn the migration into a no-op by removing the code inside `#up`, `#down`
or `#perform` methods, and adding `#no-op` comment instead.
1. Add a comment explaining why the code is gone.
diff --git a/doc/development/distributed_tracing.md b/doc/development/distributed_tracing.md
index ae84e38e324..7fc33380aba 100644
--- a/doc/development/distributed_tracing.md
+++ b/doc/development/distributed_tracing.md
@@ -27,7 +27,7 @@ process boundaries, the correlation ID is injected into the outgoing request. Th
the propagation of the correlation ID to each downstream subsystem.
Correlation IDs are normally generated in the Rails application in response to
-certain webrequests. Some user facing systems don't generate correlation IDs in
+certain web requests. Some user facing systems don't generate correlation IDs in
response to user requests (for example, Git pushes over SSH).
### Developer guidelines for working with correlation IDs
diff --git a/doc/development/documentation/feature_flags.md b/doc/development/documentation/feature_flags.md
index 373c5a4ee7d..f3ce9ce3a83 100644
--- a/doc/development/documentation/feature_flags.md
+++ b/doc/development/documentation/feature_flags.md
@@ -43,10 +43,11 @@ For feature flags disabled by default, if they can be used by end users:
- Say that it's disabled by default.
- Say whether it's enabled on GitLab.com.
+- Say whether it can be enabled or disabled per-project.
- Say whether it's recommended for production use.
- Document how to enable and disable it.
-For example, for a feature disabled by default, disabled on GitLab.com, and
+For example, for a feature disabled by default, disabled on GitLab.com, can be enabled or disabled per-project, and
not ready for production use:
````markdown
@@ -55,6 +56,7 @@ not ready for production use:
> - [Introduced](link-to-issue) in GitLab 12.0.
> - It's deployed behind a feature flag, disabled by default.
> - It's disabled on GitLab.com.
+> - It's able to be enabled or disabled per-project
> - It's not recommended for production use.
> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#anchor-to-section). **(CORE ONLY)**
@@ -65,18 +67,24 @@ not ready for production use:
<Feature Name> 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](../path/to/administration/feature_flags.md)
-can enable it for your instance.
+can enable it for your instance. <Feature Name> can be enabled or disabled per-project
To enable it:
```ruby
+# Instance-wide
Feature.enable(:<feature flag>)
+# or by project
+Feature.enable(:<feature flag>, Project.find(<project id>))
```
To disable it:
```ruby
+# Instance-wide
Feature.disable(:<feature flag>)
+# or by project
+Feature.disable(:<feature flag>, Project.find(<project id>))
```
````
@@ -88,10 +96,11 @@ For features that became enabled by default:
- Say that it became enabled by default.
- Say whether it's enabled on GitLab.com.
+- Say whether it can be enabled or disabled per-project.
- Say whether it's recommended for production use.
- Document how to disable and enable it.
-For example, for a feature initially deployed disabled by default, that became enabled by default, that is enabled on GitLab.com, and ready for production use:
+For example, for a feature initially deployed disabled by default, that became enabled by default, that is enabled on GitLab.com, that cannot be enabled or disabled per-project, and ready for production use:
````markdown
# Feature Name
@@ -100,6 +109,7 @@ For example, for a feature initially deployed disabled by default, that became e
> - It was deployed behind a feature flag, disabled by default.
> - [Became enabled by default](link-to-issue) on GitLab 12.1.
> - It's enabled on GitLab.com.
+> - It's not able to be enabled or disabled per-project
> - It's recommended for production use.
> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#anchor-to-section). **(CORE ONLY)**
@@ -110,7 +120,7 @@ For example, for a feature initially deployed disabled by default, that became e
<Feature Name> 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](..path/to/administration/feature_flags.md)
-can opt to disable it for your instance.
+can opt to disable it for your instance it cannot be enabled or disabled per-project.
To disable it:
@@ -133,10 +143,11 @@ For features enabled by default:
- Say it's enabled by default.
- Say whether it's enabled on GitLab.com.
+- Say whether it can be enabled or disabled per-project.
- Say whether it's recommended for production use.
- Document how to disable and enable it.
-For example, for a feature enabled by default, enabled on GitLab.com, and ready for production use:
+For example, for a feature enabled by default, enabled on GitLab.com, cannot be enabled or disabled per-project, and ready for production use:
````markdown
# Feature Name
@@ -144,6 +155,7 @@ For example, for a feature enabled by default, enabled on GitLab.com, and ready
> - [Introduced](link-to-issue) in GitLab 12.0.
> - It's deployed behind a feature flag, enabled by default.
> - It's enabled on GitLab.com.
+> - It's not able to be enabled or disabled per-project
> - It's recommended for production use.
> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#anchor-to-section). **(CORE ONLY)**
diff --git a/doc/development/documentation/index.md b/doc/development/documentation/index.md
index 256d3f5d86c..f845a6ec592 100644
--- a/doc/development/documentation/index.md
+++ b/doc/development/documentation/index.md
@@ -59,7 +59,7 @@ However, anyone can contribute [documentation improvements](improvement-workflow
## Markdown and styles
[GitLab docs](https://gitlab.com/gitlab-org/gitlab-docs) uses [GitLab Kramdown](https://gitlab.com/gitlab-org/gitlab_kramdown)
-as its Markdown rendering engine. See the [GitLab Markdown Guide](https://about.gitlab.com/handbook/engineering/ux/technical-writing/markdown-guide/) for a complete Kramdown reference.
+as its Markdown rendering engine. See the [GitLab Markdown Guide](https://about.gitlab.com/handbook/markdown-guide/) for a complete Kramdown reference.
Adhere to the [Documentation Style Guide](styleguide.md). If a style standard is missing, you are welcome to suggest one via a merge request.
@@ -67,6 +67,41 @@ Adhere to the [Documentation Style Guide](styleguide.md). If a style standard is
See the [Structure](styleguide.md#structure) section of the [Documentation Style Guide](styleguide.md).
+## Metadata
+
+To provide additional directives or useful information, we add metadata in YAML
+format to the beginning of each product documentation page.
+
+For example, the following metadata would be at the beginning of a product
+documentation page whose content is primarily associated with the Audit Events
+feature:
+
+```yaml
+---
+stage: Monitor
+group: APM
+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
+---
+```
+
+The following list describes the YAML parameters in use:
+
+- `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](#changing-document-location).
+- `stage`: The [Stage](https://about.gitlab.com/handbook/product/categories/#devops-stages)
+ to which the majority of the page's content belongs.
+- `group`: The [Group](https://about.gitlab.com/company/team/structure/#product-groups)
+ to which the majority of the page's content belongs.
+- `info`: The following line, which provides direction to contributors regarding
+ how to contact the Technical Writer associated with the page's Stage and
+ Group: `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`
+- `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).
+
## Changing document location
Changing a document's location requires specific steps to ensure that
@@ -133,10 +168,9 @@ Things to note:
it in for `workflow/lfs/lfs_administration` and `lfs/lfs_administration`
and will print the file and the line where this file is mentioned.
You may ask why the two greps. Since [we use relative paths to link to
- documentation](styleguide.md#links)
- , sometimes it might be useful to search a path deeper.
+ documentation](styleguide.md#links), sometimes it might be useful to search a path deeper.
- The `*.md` extension is not used when a document is linked to GitLab's
- built-in help page, that's why we omit it in `git grep`.
+ built-in help page, which is why we omit it in `git grep`.
- Use the checklist on the "Change documentation location" MR description template.
### Redirections for pages with Disqus comments
@@ -380,7 +414,7 @@ The following GitLab features are used among others:
- [Multi project pipelines](../../ci/multi_project_pipeline_graphs.md)
- [Review Apps](../../ci/review_apps/index.md)
- [Artifacts](../../ci/yaml/README.md#artifacts)
-- [Specific Runner](../../ci/runners/README.md#locking-a-specific-runner-from-being-enabled-for-other-projects)
+- [Specific Runner](../../ci/runners/README.md#prevent-a-specific-runner-from-being-enabled-for-other-projects)
- [Pipelines for merge requests](../../ci/merge_request_pipelines/index.md)
## Testing
@@ -477,7 +511,7 @@ This list does not limit what other linters you can add to your local documentat
[markdownlint](https://github.com/DavidAnson/markdownlint) checks that Markdown
syntax follows [certain rules](https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md#rules),
and is used by the [`docs-lint` test](#testing) with a [configuration file](#markdownlint-configuration).
-Our [Documentation Style Guide](styleguide.md#markdown) and [Markdown Guide](https://about.gitlab.com/handbook/engineering/ux/technical-writing/markdown-guide/)
+Our [Documentation Style Guide](styleguide.md#markdown) and [Markdown Guide](https://about.gitlab.com/handbook/markdown-guide/)
elaborate on which choices must be made when selecting Markdown syntax for GitLab
documentation. This tool helps catch deviations from those guidelines.
@@ -498,7 +532,9 @@ If you wish to use a different configuration file, use the `-c` flag:
markdownlint -c <config-file-name> 'doc/**/*.md'
```
-markdownlint can also be run from within text editors using [plugins/extensions](https://github.com/DavidAnson/markdownlint#related),
+##### Run markdownlint in an editor
+
+markdownlint can also be run as a linter within text editors using [plugins/extensions](https://github.com/DavidAnson/markdownlint#related),
such as:
- [Sublime Text](https://packagecontrol.io/packages/SublimeLinter-contrib-markdownlint)
@@ -524,7 +560,7 @@ four repositories that are the sources for <https://docs.gitlab.com>:
By default all rules are enabled, so the configuration file is used to disable unwanted
rules, and also to configure optional parameters for enabled rules as needed. You can
-also check [the issue](https://gitlab.com/gitlab-org/gitlab-foss/issues/64352) that
+also check [the issue](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/64352) that
tracked the changes required to implement these rules, and details which rules were
on or off when markdownlint was enabled on the docs.
@@ -546,11 +582,16 @@ and from GitLab's root directory (where `.vale.ini` is located), run:
vale --glob='*.{md}' doc
```
-You can also
-[configure the text editor of your choice](https://errata-ai.github.io/vale/#local-use-by-a-single-writer)
-to display the results.
+Vale's error-level test results [are displayed](#testing) in CI pipelines.
+
+##### Run Vale in an editor
+
+You can run Vale as a linter within your text editor of choice, with:
+
+- The Sublime Text [`SublimeLinter-contrib-vale` plugin](https://packagecontrol.io/packages/SublimeLinter-contrib-vale)
+- The Visual Studio Code [`testthedocs.vale` extension](https://marketplace.visualstudio.com/items?itemName=testthedocs.vale)
-Vale's test results [are displayed](#testing) in CI pipelines.
+We don't use [Vale Server](https://errata-ai.github.io/vale/#using-vale-with-a-text-editor-or-another-third-party-application).
##### Disable a Vale test
diff --git a/doc/development/documentation/site_architecture/global_nav.md b/doc/development/documentation/site_architecture/global_nav.md
index 12190e2cb9e..71020e6054e 100644
--- a/doc/development/documentation/site_architecture/global_nav.md
+++ b/doc/development/documentation/site_architecture/global_nav.md
@@ -356,7 +356,7 @@ files.
```
This also allows the nav to be displayed on other
-highest-level dirs (`/omnibus/`, `/runner/`, etc),
+highest-level directories (`/omnibus/`, `/runner/`, etc),
linking them back to `/ee/`.
The same logic is applied to all sections (`sec[:section_url]`),
diff --git a/doc/development/documentation/site_architecture/index.md b/doc/development/documentation/site_architecture/index.md
index 56dd3821b1c..942b202a3ec 100644
--- a/doc/development/documentation/site_architecture/index.md
+++ b/doc/development/documentation/site_architecture/index.md
@@ -53,12 +53,12 @@ product, and all together are pulled to generate the docs website:
- [GitLab Chart](https://gitlab.com/charts/gitlab/tree/master/doc)
NOTE: **Note:**
-In September 2019, we [moved towards a single codebase](https://gitlab.com/gitlab-org/gitlab/issues/2952),
+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
-[Pages supports redirects](https://gitlab.com/gitlab-org/gitlab-pages/issues/24),
+[Pages supports redirects](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/24),
we will be able to remove this completely.
## Assets
@@ -107,13 +107,13 @@ The pipeline in the `gitlab-docs` project:
Once a week on Mondays, a scheduled pipeline runs and rebuilds the Docker images
used in various pipeline jobs, like `docs-lint`. The Docker image configuration files are
-located at <https://gitlab.com/gitlab-org/gitlab-docs/-/tree/master/dockerfiles>.
+located in the [Dockerfiles directory](https://gitlab.com/gitlab-org/gitlab-docs/-/tree/master/dockerfiles).
If you need to rebuild the Docker images immediately (must have maintainer level permissions):
CAUTION: **Caution**
If you change the dockerfile configuration and rebuild the images, you can break the master
-pipeline in the main `gitlab` repo as well as in `gitlab-docs`. Create an image with
+pipeline in the main `gitlab` repository as well as in `gitlab-docs`. Create an image with
a different name first and test it to ensure you do not break the pipelines.
1. In [`gitlab-docs`](https://gitlab.com/gitlab-org/gitlab-docs), go to **{rocket}** **CI / CD > Pipelines**.
@@ -173,7 +173,7 @@ we reference the array with a symbol (`:versions`).
## Bumping versions of CSS and JavaScript
Whenever the custom CSS and JavaScript files under `content/assets/` change,
-make sure to bump their version in the frontmatter. This method guarantees that
+make sure to bump their version in the front matter. This method guarantees that
your changes will take effect by clearing the cache of previous files.
Always use Nanoc's way of including those files, do not hardcode them in the
@@ -207,22 +207,22 @@ If you don't specify `editor:`, the simple one is used by default.
## Algolia search engine
-The docs site uses [Algolia docsearch](https://community.algolia.com/docsearch/)
+The docs site uses [Algolia DocSearch](https://community.algolia.com/docsearch/)
for its search function. This is how it works:
-1. GitLab is a member of the [docsearch program](https://community.algolia.com/docsearch/#join-docsearch-program),
+1. GitLab is a member of the [DocSearch program](https://community.algolia.com/docsearch/#join-docsearch-program),
which is the free tier of [Algolia](https://www.algolia.com/).
1. Algolia hosts a [DocSearch configuration](https://github.com/algolia/docsearch-configs/blob/master/configs/gitlab.json)
for the GitLab docs site, and we've worked together to refine it.
-1. That [config](https://community.algolia.com/docsearch/config-file.html) is
+1. That [configuration](https://community.algolia.com/docsearch/config-file.html) is
parsed by their [crawler](https://community.algolia.com/docsearch/crawler-overview.html)
every 24h and [stores](https://community.algolia.com/docsearch/inside-the-engine.html)
- the [docsearch index](https://community.algolia.com/docsearch/how-do-we-build-an-index.html)
+ the [DocSearch index](https://community.algolia.com/docsearch/how-do-we-build-an-index.html)
on [Algolia's servers](https://community.algolia.com/docsearch/faq.html#where-is-my-data-hosted%3F).
-1. On the docs side, we use a [docsearch layout](https://gitlab.com/gitlab-org/gitlab-docs/blob/master/layouts/docsearch.html) which
+1. On the docs side, we use a [DocSearch layout](https://gitlab.com/gitlab-org/gitlab-docs/blob/master/layouts/docsearch.html) which
is present on pretty much every page except <https://docs.gitlab.com/search/>,
which uses its [own layout](https://gitlab.com/gitlab-org/gitlab-docs/blob/master/layouts/instantsearch.html). In those layouts,
- there's a JavaScript snippet which initiates docsearch by using an API key
+ there's a JavaScript snippet which initiates DocSearch by using an API key
and an index name (`gitlab`) that are needed for Algolia to show the results.
NOTE: **For GitLab employees:**
diff --git a/doc/development/documentation/site_architecture/release_process.md b/doc/development/documentation/site_architecture/release_process.md
index 13d6540fa35..d100ab8afa8 100644
--- a/doc/development/documentation/site_architecture/release_process.md
+++ b/doc/development/documentation/site_architecture/release_process.md
@@ -62,30 +62,15 @@ The single docs version must be created before the release merge request, but
this needs to happen when the stable branches for all products have been created.
1. Make sure you're in the root path of the `gitlab-docs` repository.
-1. Make sure your `master` is updated:
-
- ```shell
- git pull origin master
- ```
-
1. Run the Rake task to create the single version:
```shell
./bin/rake "release:single[12.0]"
```
- A new `Dockerfile.12.0` should have been created and committed to a new branch.
-
-1. Edit `.gitlab-ci.yml` and replace the `BRANCH_` variables with their respective
- upstream stable branch. For example, 12.6 would look like:
-
- ```yaml
- variables:
- BRANCH_EE: '12-6-stable-ee'
- BRANCH_OMNIBUS: '12-6-stable'
- BRANCH_RUNNER: '12-6-stable'
- BRANCH_CHARTS: '2-6-stable'
- ```
+ A new `Dockerfile.12.0` should have been created and `.gitlab-ci.yml` should
+ have the branches variables updated into a new branch. They will be automatically
+ committed.
1. Push the newly created branch, but **don't create a merge request**.
Once you push, the `image:docker-singe` job will create a new Docker image
@@ -106,6 +91,9 @@ Visit `http://localhost:4000/12.0/` to see if everything works correctly.
### 3. Create the release merge request
+NOTE: **Note:**
+To be [automated](https://gitlab.com/gitlab-org/gitlab-docs/-/issues/750).
+
Now it's time to create the monthly release merge request that adds the new
version and rotates the old one:
@@ -161,7 +149,7 @@ versions:
1. Run the Rake task that will create all the respective merge requests needed to
update the dropdowns and will be set to automatically be merged when their
pipelines succeed. The `release-X-Y` branch needs to be present locally,
- otherwise the Rake task will fail:
+ and you need to have switched to it, otherwise the Rake task will fail:
```shell
./bin/rake release:dropdowns
diff --git a/doc/development/documentation/structure.md b/doc/development/documentation/structure.md
index d19383bee27..eadcedfaac0 100644
--- a/doc/development/documentation/structure.md
+++ b/doc/development/documentation/structure.md
@@ -34,7 +34,7 @@ For additional details on each, see the [template for new docs](#template-for-ne
below.
Note that you can include additional subsections, as appropriate, such as 'How it Works', 'Architecture',
-and other logical divisions such as pre- and post-deployment steps.
+and other logical divisions such as pre-deployment and post-deployment steps.
## Template for new docs
diff --git a/doc/development/documentation/styleguide.md b/doc/development/documentation/styleguide.md
index 6d146051e13..9a93dbf4f94 100644
--- a/doc/development/documentation/styleguide.md
+++ b/doc/development/documentation/styleguide.md
@@ -96,7 +96,7 @@ Having a knowledge base in any form that is separate from the documentation woul
All GitLab documentation is written using [Markdown](https://en.wikipedia.org/wiki/Markdown).
-The [documentation website](https://docs.gitlab.com) uses GitLab Kramdown as its Markdown rendering engine. For a complete Kramdown reference, see the [GitLab Markdown Kramdown Guide](https://about.gitlab.com/handbook/engineering/ux/technical-writing/markdown-guide/).
+The [documentation website](https://docs.gitlab.com) uses GitLab Kramdown as its Markdown rendering engine. For a complete Kramdown reference, see the [GitLab Markdown Kramdown Guide](https://about.gitlab.com/handbook/markdown-guide/).
The [`gitlab-kramdown`](https://gitlab.com/gitlab-org/gitlab_kramdown)
Ruby gem will support all [GFM markup](../../user/markdown.md) in the future. That is,
@@ -134,6 +134,8 @@ be ignored by markdownlint.
In general, product names should follow the exact capitalization of the official names
of the products, protocols, and so on.
+See [`.markdownlint.json`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.markdownlint.json)
+for the words tested for proper capitalization in GitLab documentation.
Some examples fail if incorrect capitalization is used:
@@ -246,13 +248,14 @@ Do not include the same information in multiple places. [Link to a SSOT instead.
GitLab documentation should be clear and easy to understand.
- Be clear, concise, and stick to the goal of the documentation.
-- Write in US English with US grammar.
+- Write in US English with US grammar. (Tested in [`British.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/British.yml).)
- Use inclusive language.
### Point of view
In most cases, it’s appropriate to use the second-person (you, yours) point of view,
because it’s friendly and easy to understand.
+(Tested in [`FirstPerson.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/FirstPerson.yml).)
<!-- How do we harmonize the second person in Pajamas with our first person plural in our doc guide? -->
@@ -272,10 +275,11 @@ because it’s friendly and easy to understand.
- [GitLab Features](https://about.gitlab.com/features/). For example, Issue Board,
Geo, and Runner.
- GitLab [product tiers](https://about.gitlab.com/pricing/). For example, GitLab Core
- and GitLab Ultimate.
+ and GitLab Ultimate. (Tested in [`BadgeCapitalization.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/BadgeCapitalization.yml).)
- Third-party products. For example, Prometheus, Kubernetes, and Git.
- Methods or methodologies. For example, Continuous Integration, Continuous
Deployment, Scrum, and Agile.
+ (Tested in [`.markdownlint.json`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.markdownlint.json).)
NOTE: **Note:**
Some features are also objects. For example, "GitLab's Merge Requests support X" and
@@ -289,6 +293,7 @@ tenses, words, and phrases:
- Avoid jargon.
- Avoid uncommon words.
- Don't write in the first person singular.
+ (Tested in [`FirstPerson.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/FirstPerson.yml).)
- Instead of "I" or "me," use "we," "you," "us," or "one."
- When possible, stay user focused by writing in the second person ("you" or
the imperative).
@@ -311,6 +316,7 @@ tenses, words, and phrases:
- <!-- vale gitlab.LatinTerms = NO -->
We discourage use of Latin abbreviations, such as "e.g.," "i.e.," or "etc.,"
as even native users of English might misunderstand them.
+ (Tested in [`LatinTerms.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/LatinTerms.yml).)
- Instead of "i.e.," use "that is."
- Instead of "e.g.," use "for example," "such as," "for instance," or "like."
- Instead of "etc.," either use "and so on" or consider editing it out, since
@@ -319,6 +325,9 @@ tenses, words, and phrases:
- Avoid using the word *currently* when talking about the product or its
features. The documentation describes the product as it is, and not as it
will be at some indeterminate point in the future.
+- Don't use profanity or obscenities. Doing so may negatively affect other
+ users and contributors, which is contrary to GitLab's value of
+ [diversity and inclusion](https://about.gitlab.com/handbook/values/#diversity-inclusion).
### Word usage clarifications
@@ -331,55 +340,55 @@ tenses, words, and phrases:
### Contractions
-- Use common contractions when it helps create a friendly and informal tone, especially in tutorials, instructional documentation, and [UIs](https://design.gitlab.com/content/punctuation/#contractions).
-
-| Do | Don't |
-|----------|-----------|
-| it's | it is |
-| can't | cannot |
-| wouldn't | would not |
-| you're | you are |
-| you've | you have |
-| haven't | have not |
-| don't | do not |
-| we're | we are |
-| that's | that is |
-| won't | will not |
+- Use common contractions when it helps create a friendly and informal tone, especially in tutorials, instructional documentation, and [UIs](https://design.gitlab.com/content/punctuation/#contractions). (Tested in [`Contractions.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/Contractions.yml).)
+
+ | Do | Don't |
+ |----------|-----------|
+ | it's | it is |
+ | can't | cannot |
+ | wouldn't | would not |
+ | you're | you are |
+ | you've | you have |
+ | haven't | have not |
+ | don't | do not |
+ | we're | we are |
+ | that's | that is |
+ | won't | will not |
- Avoid less common contractions:
-| Do | Don't |
-|--------------|-------------|
-| he would | he'd |
-| it will | it'll |
-| should have | should've |
-| there would | there'd |
+ | Do | Don't |
+ |--------------|-------------|
+ | he would | he'd |
+ | it will | it'll |
+ | should have | should've |
+ | there would | there'd |
- Do not use contractions with a proper noun and a verb. For example:
-| Do | Don't |
-|----------------------|---------------------|
-| GitLab is creating X | GitLab's creating X |
+ | Do | Don't |
+ |----------------------|---------------------|
+ | GitLab is creating X | GitLab's creating X |
- Do not use contractions when you need to emphasize a negative. For example:
-| Do | Don't |
-|-----------------------------|----------------------------|
-| Do **not** install X with Y | **Don't** install X with Y |
+ | Do | Don't |
+ |-----------------------------|----------------------------|
+ | Do **not** install X with Y | **Don't** install X with Y |
- Do not use contractions in reference documentation. For example:
-| Do | Don't |
-|------------------------------------------|----------------------------|
-| Do **not** set a limit greater than 1000 | **Don't** set a limit greater than 1000 |
-| For `parameter1`, the default is 10 | For `parameter1`, the default's 10 |
+ | Do | Don't |
+ |------------------------------------------|----------------------------|
+ | Do **not** set a limit greater than 1000 | **Don't** set a limit greater than 1000 |
+ | For `parameter1`, the default is 10 | For `parameter1`, the default's 10 |
- Avoid contractions in error messages. Examples:
-| Do | Don't |
-|------------------------------------------|----------------------------|
-| Requests to localhost are not allowed | Requests to localhost aren't allowed |
-| Specified URL cannot be used | Specified URL can't be used |
+ | Do | Don't |
+ |------------------------------------------|----------------------------|
+ | Requests to localhost are not allowed | Requests to localhost aren't allowed |
+ | Specified URL cannot be used | Specified URL can't be used |
<!-- vale on -->
@@ -414,9 +423,9 @@ Check specific punctuation rules for [lists](#lists) below.
| ---- | ------- |
| Always end full sentences with a period. | _For a complete overview, read through this document._|
| Always add a space after a period when beginning a new sentence. | _For a complete overview, check this doc. For other references, check out this guide._ |
-| Do not use double spaces. | --- |
+| Do not use double spaces. (Tested in [`SentenceSpacing.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/SentenceSpacing.yml).) | --- |
| Do not use tabs for indentation. Use spaces instead. You can configure your code editor to output spaces instead of tabs when pressing the tab key. | --- |
-| Use serial commas ("Oxford commas") before the final 'and/or' in a list. | _You can create new issues, merge requests, and milestones._ |
+| Use serial commas ("Oxford commas") before the final 'and/or' in a list. (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._ |
| Always use lowercase after a colon. | _Related Issues: a way to create a relationship between issues._ |
@@ -439,7 +448,7 @@ cp <your_source_directory> <your_destination_directory>
- Always start list items with a capital letter, unless they are parameters or commands
that are in backticks, or similar.
- Always leave a blank line before and after a list.
-- Begin a line with spaces (not tabs) to denote a [nested subitem](#nesting-inside-a-list-item).
+- Begin a line with spaces (not tabs) to denote a [nested sub-item](#nesting-inside-a-list-item).
### Ordered vs. unordered lists
@@ -599,7 +608,7 @@ that is best described by a matrix, tables are the best choice for use.
### Creation guidelines
-Due to accessibility and scanability requirements, tables should not have any
+Due to accessibility and scannability requirements, tables should not have any
empty cells. If there is no otherwise meaningful value for a cell, consider entering
*N/A* (for 'not applicable') or *none*.
@@ -648,7 +657,7 @@ For other punctuation rules, please refer to the
links shift too, which eventually leads to dead links. If you think it is
compelling to add numbers in headings, make sure to at least discuss it with
someone in the Merge Request.
-- [Avoid using symbols and special chars](https://gitlab.com/gitlab-org/gitlab-docs/issues/84)
+- [Avoid using symbols and special characters](https://gitlab.com/gitlab-org/gitlab-docs/-/issues/84)
in headers. Whenever possible, they should be plain and short text.
- Avoid adding things that show ephemeral statuses. For example, if a feature is
considered beta or experimental, put this information in a note, not in the heading.
@@ -719,6 +728,7 @@ We include guidance for links in the following categories:
- How to set up [criteria](#basic-link-criteria) for configuring a link.
- What to set up when [linking to a `help`](../documentation/index.md#linking-to-help) page.
- How to set up [links to internal documentation](#links-to-internal-documentation) for cross-references.
+- How to set up [links to external documentation](#links-to-external-documentation) for authoritative sources.
- When to use [links requiring permissions](#links-requiring-permissions).
- How to set up a [link to a video](#link-to-video).
- How to [include links with version text](#text-for-documentation-requiring-version-text).
@@ -771,6 +781,12 @@ To link to internal documentation:
NOTE: **Note**:
Using the Markdown extension is necessary for the [`/help`](index.md#gitlab-help) section of GitLab.
+### Links to external documentation
+
+When describing interactions with external software, it's often helpful to include links to external
+documentation. When possible, make sure that you are linking to an **authoritative** source.
+For example, if you're describing a feature in Microsoft's Active Directory, include a link to official Microsoft documentation.
+
### Links requiring permissions
Don't link directly to:
@@ -793,7 +809,7 @@ Instead:
Example:
```markdown
-For more information, see the [confidential issue](../../user/project/issues/confidential_issues.md) `https://gitlab.com/gitlab-org/gitlab-foss/issues/<issue_number>`.
+For more information, see the [confidential issue](../../user/project/issues/confidential_issues.md) `https://gitlab.com/gitlab-org/gitlab-foss/-/issues/<issue_number>`.
```
### Link to specific lines of code
@@ -1040,11 +1056,11 @@ of language classes available.
| `xml` | |
| `yaml` | Alias: `yml`. |
-For a complete reference on code blocks, check the [Kramdown guide](https://about.gitlab.com/handbook/engineering/ux/technical-writing/markdown-guide/#code-blocks).
+For a complete reference on code blocks, check the [Kramdown guide](https://about.gitlab.com/handbook/markdown-guide/#code-blocks).
## GitLab SVG icons
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-docs/issues/384) in GitLab 12.7.
+> [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.
@@ -1359,7 +1375,35 @@ versions back, you can consider removing the text if it's irrelevant or confusin
For example, if the current major version is 12.x, version text referencing versions of GitLab 8.x
and older are candidates for removal if necessary for clearer or cleaner docs.
-## Product badges
+## Products and features
+
+Refer to the information in this section when describing products and features
+within the GitLab product documentation.
+
+### Avoid line breaks in names
+
+When entering a product or feature name that includes a space (such as
+GitLab Community Edition) or even other companies' products (such as
+Amazon Web Services), be sure to not split the product or feature name across
+lines with an inserted line break. Splitting product or feature names across
+lines makes searching for these items more difficult, and can cause problems if
+names change.
+
+For example, the followng Markdown content is *not* formatted correctly:
+
+```markdown
+When entering a product or feature name that includes a space (such as GitLab
+Community Edition), don't split the product or feature name across lines.
+```
+
+Instead, it should appear similar to the following:
+
+```markdown
+When entering a product or feature name that includes a space (such as
+GitLab Community Edition), don't split the product or feature name across lines.
+```
+
+### Product badges
When a feature is available in EE-only tiers, add the corresponding tier according to the
feature availability:
@@ -1399,7 +1443,7 @@ For example:
The absence of tiers' mentions mean that the feature is available in GitLab Core,
GitLab.com Free, and all higher tiers.
-### How it works
+#### How it works
Introduced by [!244](https://gitlab.com/gitlab-org/gitlab-docs/-/merge_requests/244),
the special markup `**(STARTER)**` will generate a `span` element to trigger the
@@ -1608,7 +1652,7 @@ Rendered example:
- Wherever needed use this personal access token: `<your_access_token>`.
- Always put the request first. `GET` is the default so you don't have to
include it.
-- Use double quotes to the URL when it includes additional parameters.
+- Wrap the URL in double quotes (`"`).
- Prefer to use examples using the personal access token and don't pass data of
username and password.
@@ -1686,9 +1730,8 @@ Use `%2F` for slashes (`/`).
#### Pass arrays to API calls
The GitLab API sometimes accepts arrays of strings or integers. For example, to
-restrict the sign-up e-mail domains of a GitLab instance to `*.example.com` and
-`example.net`, you would do something like this:
+exclude specific users when requesting a list of users for a project, you would do something like this:
```shell
-curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" --data "domain_whitelist[]=*.example.com" --data "domain_whitelist[]=example.net" https://gitlab.example.com/api/v4/application/settings
+curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" --data "skip_users[]=<user_id>" --data "skip_users[]=<user_id>" https://gitlab.example.com/api/v4/projects/<project_id>/users
```
diff --git a/doc/development/documentation/workflow.md b/doc/development/documentation/workflow.md
index ab6200155bf..c3e15cb1b2b 100644
--- a/doc/development/documentation/workflow.md
+++ b/doc/development/documentation/workflow.md
@@ -54,7 +54,7 @@ To update GitLab documentation:
1. Follow the described standards and processes listed on the page, including:
- The [Structure and template](structure.md) page.
- The [Style Guide](styleguide.md).
- - The [Markdown Guide](https://about.gitlab.com/handbook/engineering/ux/technical-writing/markdown-guide/).
+ - The [Markdown Guide](https://about.gitlab.com/handbook/markdown-guide/).
1. Follow GitLab's [Merge Request Guidelines](../contributing/merge_request_workflow.md#merge-request-guidelines).
TIP: **Tip:**
@@ -104,7 +104,7 @@ The process involves the following:
- Ensure the appropriate labels are applied, including any required to pick a merge request into
a release.
- Ensure that, if there has not been a Technical Writer review completed or scheduled, they
- [create the required issue](https://gitlab.com/gitlab-org/gitlab/issues/new?issuable_template=Doc%20Review), assign to the Technical Writer of the given stage group,
+ [create the required issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new?issuable_template=Doc%20Review), assign to the Technical Writer of the given stage group,
and link it from the merge request.
The process is reflected in the **Documentation**
@@ -113,14 +113,14 @@ The process is reflected in the **Documentation**
## Other ways to help
If you have ideas for further documentation resources please
-[create an issue](https://gitlab.com/gitlab-org/gitlab/issues/new?issuable_template=Documentation)
+[create an issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new?issuable_template=Documentation)
using the Documentation template.
## Post-merge reviews
If not assigned to a Technical Writer for review prior to merging, a review must be scheduled
immediately after merge by the developer or maintainer. For this,
-create an issue using the [Doc Review description template](https://gitlab.com/gitlab-org/gitlab/issues/new?issuable_template=Doc%20Review)
+create an issue using the [Doc Review description template](https://gitlab.com/gitlab-org/gitlab/-/issues/new?issuable_template=Doc%20Review)
and link to it from the merged merge request that introduced the documentation change.
Circumstances where a regular pre-merge Technical Writer review might be skipped include:
diff --git a/doc/development/ee_features.md b/doc/development/ee_features.md
index 3951b0516e8..e22e96b6f06 100644
--- a/doc/development/ee_features.md
+++ b/doc/development/ee_features.md
@@ -11,7 +11,7 @@
## Act as CE when unlicensed
Since the implementation of
-[GitLab CE features to work with unlicensed EE instance](https://gitlab.com/gitlab-org/gitlab/issues/2500)
+[GitLab CE features to work with unlicensed EE instance](https://gitlab.com/gitlab-org/gitlab/-/issues/2500)
GitLab Enterprise Edition should work like GitLab Community Edition
when no license is active. So EE features always should be guarded by
`project.feature_available?` or `group.feature_available?` (or
@@ -165,8 +165,6 @@ There are a few gotchas with it:
end
```
- This would require updating CE first, or make sure this is back ported to CE.
-
When prepending, place them in the `ee/` specific sub-directory, and
wrap class or module in `module EE` to avoid naming conflicts.
diff --git a/doc/development/elasticsearch.md b/doc/development/elasticsearch.md
index 185f536fc01..9f54386f1af 100644
--- a/doc/development/elasticsearch.md
+++ b/doc/development/elasticsearch.md
@@ -24,19 +24,19 @@ See the [Elasticsearch GDK setup instructions](https://gitlab.com/gitlab-org/git
- `gitlab:elastic:test:index_size`: Tells you how much space the current index is using, as well as how many documents are in the index.
- `gitlab:elastic:test:index_size_change`: Outputs index size, reindexes, and outputs index size again. Useful when testing improvements to indexing size.
-Additionally, if you need large repos or multiple forks for testing, please consider [following these instructions](rake_tasks.md#extra-project-seed-options)
+Additionally, if you need large repositories or multiple forks for testing, please consider [following these instructions](rake_tasks.md#extra-project-seed-options)
## How does it work?
-The Elasticsearch integration depends on an external indexer. We ship an [indexer written in Go](https://gitlab.com/gitlab-org/gitlab-elasticsearch-indexer). The user must trigger the initial indexing via a Rake task but, after this is done, GitLab itself will trigger reindexing when required via `after_` callbacks on create, update, and destroy that are inherited from [/ee/app/models/concerns/elastic/application_versioned_search.rb](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/app/models/concerns/elastic/application_versioned_search.rb).
+The Elasticsearch integration depends on an external indexer. We ship an [indexer written in Go](https://gitlab.com/gitlab-org/gitlab-elasticsearch-indexer). The user must trigger the initial indexing via a Rake task but, after this is done, GitLab itself will trigger reindexing when required via `after_` callbacks on create, update, and destroy that are inherited from [`/ee/app/models/concerns/elastic/application_versioned_search.rb`](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/app/models/concerns/elastic/application_versioned_search.rb).
-After initial indexing is complete, create, update, and delete operations for all models except projects (see [#207494](https://gitlab.com/gitlab-org/gitlab/issues/207494)) are tracked in a Redis [`ZSET`](https://redis.io/topics/data-types#sorted-sets). A regular `sidekiq-cron` `ElasticIndexBulkCronWorker` processes this queue, updating many Elasticsearch documents at a time with the [Bulk Request API](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html).
+After initial indexing is complete, create, update, and delete operations for all models except projects (see [#207494](https://gitlab.com/gitlab-org/gitlab/-/issues/207494)) are tracked in a Redis [`ZSET`](https://redis.io/topics/data-types#sorted-sets). A regular `sidekiq-cron` `ElasticIndexBulkCronWorker` processes this queue, updating many Elasticsearch documents at a time with the [Bulk Request API](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html).
-Search queries are generated by the concerns found in [ee/app/models/concerns/elastic](https://gitlab.com/gitlab-org/gitlab/tree/master/ee/app/models/concerns/elastic). These concerns are also in charge of access control, and have been a historic source of security bugs so please pay close attention to them!
+Search queries are generated by the concerns found in [`ee/app/models/concerns/elastic`](https://gitlab.com/gitlab-org/gitlab/tree/master/ee/app/models/concerns/elastic). These concerns are also in charge of access control, and have been a historic source of security bugs so please pay close attention to them!
## Existing Analyzers/Tokenizers/Filters
-These are all defined in [ee/lib/elastic/latest/config.rb](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/lib/elastic/latest/config.rb)
+These are all defined in [`ee/lib/elastic/latest/config.rb`](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/lib/elastic/latest/config.rb)
### Analyzers
@@ -54,7 +54,7 @@ Please see the `sha_tokenizer` explanation later below for an example.
#### `code_analyzer`
-Used when indexing a blob's filename and content. Uses the `whitespace` tokenizer and the filters: [`code`](#code), [`edgeNGram_filter`](#edgengram_filter), `lowercase`, and `asciifolding`
+Used when indexing a blob's filename and content. Uses the `whitespace` tokenizer and the filters: [`code`](#code), `lowercase`, and `asciifolding`
The `whitespace` tokenizer was selected in order to have more control over how tokens are split. For example the string `Foo::bar(4)` needs to generate tokens like `Foo` and `bar(4)` in order to be properly searched.
@@ -71,7 +71,7 @@ Not directly used for indexing, but rather used to transform a search input. Use
#### `sha_tokenizer`
-This is a custom tokenizer that uses the [`edgeNGram` tokenizer](https://www.elastic.co/guide/en/elasticsearch/reference/5.5/analysis-edgengram-tokenizer.html) to allow SHAs to be searcheable by any sub-set of it (minimum of 5 chars).
+This is a custom tokenizer that uses the [`edgeNGram` tokenizer](https://www.elastic.co/guide/en/elasticsearch/reference/5.5/analysis-edgengram-tokenizer.html) to allow SHAs to be searchable by any sub-set of it (minimum of 5 chars).
Example:
@@ -149,7 +149,7 @@ These proxy objects would talk to Elasticsearch server directly (see top half of
![Elasticsearch Architecture](img/elasticsearch_architecture.svg)
-In the planned new design, each model would have a pair of corresponding subclassed proxy objects, in which model-specific logic is located. For example, `Snippet` would have `SnippetClassProxy` and `SnippetInstanceProxy` (being subclass of `Elasticsearch::Model::Proxy::ClassMethodsProxy` and `Elasticsearch::Model::Proxy::InstanceMethodsProxy`, respectively).
+In the planned new design, each model would have a pair of corresponding sub-classed proxy objects, in which model-specific logic is located. For example, `Snippet` would have `SnippetClassProxy` and `SnippetInstanceProxy` (being subclass of `Elasticsearch::Model::Proxy::ClassMethodsProxy` and `Elasticsearch::Model::Proxy::InstanceMethodsProxy`, respectively).
`__elasticsearch__` would represent another layer of proxy object, keeping track of multiple actual proxy objects. It would forward method calls to the appropriate index. For example:
@@ -175,6 +175,53 @@ If the current version is `v12p1`, and we need to create a new version for `v12p
1. Change the namespace for files under `v12p1` folder from `Latest` to `V12p1`
1. Make changes to files under the `latest` folder as needed
+## Performance Monitoring
+
+### Prometheus
+
+GitLab exports [Prometheus
+metrics](../administration/monitoring/prometheus/gitlab_metrics.md) relating to
+the number of requests and timing for all web/API requests and Sidekiq jobs,
+which can help diagnose performance trends and compare how Elasticsearch timing
+is impacting overall performance relative to the time spent doing other things.
+
+#### Indexing queues
+
+GitLab also exports [Prometheus
+metrics](../administration/monitoring/prometheus/gitlab_metrics.md) for
+indexing queues, which can help diagnose performance bottlenecks and determine
+whether or not your GitLab instance or Elasticsearch server can keep up with
+the volume of updates.
+
+### Logs
+
+All of the indexing happens in Sidekiq, so much of the relevant logs for the
+Elasticsearch integration can be found in
+[`sidekiq.log`](../administration/logs.md#sidekiqlog). In particular, all
+Sidekiq workers that make requests to Elasticsearch in any way will log the
+number of requests and time taken querying/writing to Elasticsearch. This can
+be useful to understand whether or not your cluster is keeping up with
+indexing.
+
+Searching Elasticsearch is done via ordinary web workers handling requests. Any
+requests to load a page or make an API request, which then make requests to
+Elasticsearch, will log the number of requests and the time taken to
+[`production_json.log`](../administration/logs.md#production_jsonlog). These
+logs will also include the time spent on Database and Gitaly requests, which
+may help to diagnose which part of the search is performing poorly.
+
+There are additional logs specific to Elasticsearch that are sent to
+[`elasticsearch.log`](../administration/logs.md#elasticsearchlog-starter-only)
+that may contain information to help diagnose performance issues.
+
+### Performance Bar
+
+Elasticsearch requests will be displayed in the [`Performance
+Bar`](../administration/monitoring/performance/performance_bar.md), which can
+be used both locally in development and on any deployed GitLab instance to
+diagnose poor search performance. This will show the exact queries being made,
+which is useful to diagnose why a search might be slow.
+
## Troubleshooting
### Getting `flood stage disk watermark [95%] exceeded`
diff --git a/doc/development/emails.md b/doc/development/emails.md
index e6e2ea8aae7..2477a51f78f 100644
--- a/doc/development/emails.md
+++ b/doc/development/emails.md
@@ -1,5 +1,20 @@
# Dealing with email in development
+## Ensuring compatibility with mailer Sidekiq jobs
+
+A Sidekiq job is enqueued whenever `deliver_later` is called on an `ActionMailer`.
+If a mailer argument needs to be added or removed, it is important to ensure
+both backward and forward compatibility. Adhere to the Sidekiq Style Guide steps for
+[changing the arguments for a worker](sidekiq_style_guide.md#changing-the-arguments-for-a-worker).
+
+In the following example from [`NotificationService`](https://gitlab.com/gitlab-org/gitlab/-/blob/33ccb22e4fc271dbaac94b003a7a1a2915a13441/app/services/notification_service.rb#L74)
+adding or removing an argument in this mailer's definition may cause problems
+during deployment before all Rails and Sidekiq nodes have the updated code.
+
+```ruby
+mailer.unknown_sign_in_email(user, ip, time).deliver_later
+```
+
## Sent emails
To view rendered emails "sent" in your development instance, visit
diff --git a/doc/development/fe_guide/axios.md b/doc/development/fe_guide/axios.md
index f8d301dac5e..38a8c8f1086 100644
--- a/doc/development/fe_guide/axios.md
+++ b/doc/development/fe_guide/axios.md
@@ -1,15 +1,15 @@
# Axios
-We use [axios](https://github.com/axios/axios) to communicate with the server in Vue applications and most new code.
+We use [Axios](https://github.com/axios/axios) to communicate with the server in Vue applications and most new code.
-In order to guarantee all defaults are set you *should not use `axios` directly*, you should import `axios` from `axios_utils`.
+In order to guarantee all defaults are set you *should not use Axios directly*, you should import Axios from `axios_utils`.
## CSRF token
-All our request require a CSRF token.
-To guarantee this token is set, we are importing [axios](https://github.com/axios/axios), setting the token, and exporting `axios` .
+All our requests require a CSRF token.
+To guarantee this token is set, we are importing [Axios](https://github.com/axios/axios), setting the token, and exporting `axios` .
-This exported module should be used instead of directly using `axios` to ensure the token is set.
+This exported module should be used instead of directly using Axios to ensure the token is set.
## Usage
@@ -30,7 +30,7 @@ This exported module should be used instead of directly using `axios` to ensure
});
```
-## Mock axios response in tests
+## Mock Axios response in tests
To help us mock the responses we are using [axios-mock-adapter](https://github.com/ctimmerm/axios-mock-adapter).
@@ -41,7 +41,7 @@ Advantages over [`spyOn()`](https://jasmine.github.io/api/edge/global.html#spyOn
- simple API to test error cases
- provides `replyOnce()` to allow for different responses
-We have also decided against using [axios interceptors](https://github.com/axios/axios#interceptors) because they are not suitable for mocking.
+We have also decided against using [Axios interceptors](https://github.com/axios/axios#interceptors) because they are not suitable for mocking.
### Example
@@ -67,7 +67,7 @@ We have also decided against using [axios interceptors](https://github.com/axios
});
```
-### Mock poll requests in tests with 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:
diff --git a/doc/development/fe_guide/dependencies.md b/doc/development/fe_guide/dependencies.md
index 0f5825992e9..7f078df887d 100644
--- a/doc/development/fe_guide/dependencies.md
+++ b/doc/development/fe_guide/dependencies.md
@@ -32,7 +32,7 @@ because they can create conflicts in the dependency tree. Blocked dependencies a
### BootstrapVue
-[BootstrapVue](https://bootstrap-vue.js.org/) is a component library built with Vue.js and Bootstrap.
+[BootstrapVue](https://bootstrap-vue.org/) is a component library built with Vue.js and Bootstrap.
We wrap BootstrapVue components in [GitLab UI](https://gitlab.com/gitlab-org/gitlab-ui/) with the
purpose of applying visual styles and usage guidelines specified in the
[Pajamas Design System](https://design.gitlab.com/). For this reason, we recommend not installing
diff --git a/doc/development/fe_guide/development_process.md b/doc/development/fe_guide/development_process.md
index 6e078f097cd..892e931bf5b 100644
--- a/doc/development/fe_guide/development_process.md
+++ b/doc/development/fe_guide/development_process.md
@@ -23,7 +23,7 @@ Please use your best judgment when to use it and please contribute new points th
- [ ] Are all necessary UX specifications available that you will need in order to implement? Are there new UX components/patterns in the designs? Then contact the UI component team early on. How should error messages or validation be handled?
- [ ] **Library usage** Use Vuex as soon as you have even a medium state to manage, use Vue router if you need to have different views internally and want to link from the outside. Check what libraries we already have for which occasions.
- [ ] **Plan your implementation:**
- - [ ] **Architecture plan:** Create a plan aligned with GitLab's architecture, how you are going to do the implementation, for example Vue application setup and its components (through [onion skinning](https://gitlab.com/gitlab-org/gitlab-foss/issues/35873#note_39994091)), Store structure and data flow, which existing Vue components can you reuse. It's a good idea to go through your plan with another engineer to refine it.
+ - [ ] **Architecture plan:** Create a plan aligned with GitLab's architecture, how you are going to do the implementation, for example Vue application setup and its components (through [onion skinning](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/35873#note_39994091)), Store structure and data flow, which existing Vue components can you reuse. It's a good idea to go through your plan with another engineer to refine it.
- [ ] **Backend:** The best way is to kickoff the implementation in a call and discuss with the assigned Backend engineer what you will need from the backend and also when. Can you reuse existing API's? How is the performance with the planned architecture? Maybe create together a JSON mock object to already start with development.
- [ ] **Communication:** It also makes sense to have for bigger features an own slack channel (normally called #f_{feature_name}) and even weekly demo calls with all people involved.
- [ ] **Dependency Plan:** Are there big dependencies in the plan between you and others, then maybe create an execution diagram to show what is blocking which part and the order of the different parts.
diff --git a/doc/development/fe_guide/droplab/plugins/ajax.md b/doc/development/fe_guide/droplab/plugins/ajax.md
index abc208e7568..f22d95064dd 100644
--- a/doc/development/fe_guide/droplab/plugins/ajax.md
+++ b/doc/development/fe_guide/droplab/plugins/ajax.md
@@ -6,7 +6,7 @@
Add the `Ajax` object to the plugins array of a `DropLab.prototype.init` or `DropLab.prototype.addHook` call.
-`Ajax` requires 2 config values, the `endpoint` and `method`.
+`Ajax` requires 2 configuration values, the `endpoint` and `method`.
- `endpoint` should be a URL to the request endpoint.
- `method` should be `setData` or `addData`.
diff --git a/doc/development/fe_guide/droplab/plugins/filter.md b/doc/development/fe_guide/droplab/plugins/filter.md
index 876149e4872..e8194e45a41 100644
--- a/doc/development/fe_guide/droplab/plugins/filter.md
+++ b/doc/development/fe_guide/droplab/plugins/filter.md
@@ -7,7 +7,7 @@ to the dropdown using a simple fuzzy string search of an input value.
Add the `Filter` object to the plugins array of a `DropLab.prototype.init` or `DropLab.prototype.addHook` call.
-- `Filter` requires a config value for `template`.
+- `Filter` requires a configuration value for `template`.
- `template` should be the key of the objects within your data array that you want to compare
to the user input string, for filtering.
diff --git a/doc/development/fe_guide/droplab/plugins/input_setter.md b/doc/development/fe_guide/droplab/plugins/input_setter.md
index 9b2e1e8faab..b873b7a14ee 100644
--- a/doc/development/fe_guide/droplab/plugins/input_setter.md
+++ b/doc/development/fe_guide/droplab/plugins/input_setter.md
@@ -6,12 +6,12 @@
Add the `InputSetter` object to the plugins array of a `DropLab.prototype.init` or `DropLab.prototype.addHook` call.
-- `InputSetter` requires a config value for `input` and `valueAttribute`.
+- `InputSetter` requires a configuration value for `input` and `valueAttribute`.
- `input` should be the DOM element that you want to manipulate.
- `valueAttribute` should be a string that is the name of an attribute on your list items that is used to get the value
to update the `input` element with.
-You can also set the `InputSetter` config to an array of objects, which will allow you to update multiple elements.
+You can also set the `InputSetter` configuration to an array of objects, which will allow you to update multiple elements.
```html
<input id="input" value="">
diff --git a/doc/development/fe_guide/emojis.md b/doc/development/fe_guide/emojis.md
index 6d324d4c4a0..3cd14c0dfd3 100644
--- a/doc/development/fe_guide/emojis.md
+++ b/doc/development/fe_guide/emojis.md
@@ -1,6 +1,6 @@
# Emojis
-GitLab supports native unicode emojis and fallsback to image-based emojis selectively
+GitLab supports native Unicode emojis and falls back to image-based emojis selectively
when your platform does not support it.
## How to update Emojis
@@ -21,7 +21,7 @@ when your platform does not support it.
1. Ensure you see new individual images copied into `app/assets/images/emoji/`
1. Ensure you can see the new emojis and their aliases in the GFM Autocomplete
1. Ensure you can see the new emojis and their aliases in the award emoji menu
- 1. You might need to add new emoji unicode support checks and rules for platforms
+ 1. You might need to add new emoji Unicode support checks and rules for platforms
that do not support a certain emoji and we need to fallback to an image.
See `app/assets/javascripts/emoji/support/is_emoji_unicode_supported.js`
and `app/assets/javascripts/emoji/support/unicode_support_map.js`
diff --git a/doc/development/fe_guide/frontend_faq.md b/doc/development/fe_guide/frontend_faq.md
index 8f8f162609a..4f814f3cdde 100644
--- a/doc/development/fe_guide/frontend_faq.md
+++ b/doc/development/fe_guide/frontend_faq.md
@@ -82,7 +82,7 @@ To avoid this behavior, add the class `js-no-auto-disable` to the button.
### 5. Should I use a full URL (i.e. `gon.gitlab_url`) or a full path (i.e. `gon.relative_url_root`) when referencing backend endpoints?
It's preferred to use a **full path** over a **full URL** because the URL will use the hostname configured with
-GitLab which may not match the request. This will cause [CORS issues like this Web IDE one](https://gitlab.com/gitlab-org/gitlab/issues/36810).
+GitLab which may not match the request. This will cause [CORS issues like this Web IDE one](https://gitlab.com/gitlab-org/gitlab/-/issues/36810).
Example:
@@ -141,7 +141,7 @@ function initFoo() {
});
}
-// Vuex action can now reference the path from it's state :)
+// Vuex action can now reference the path from its state :)
export const fetchFoos = ({ state }) => {
return axios.get(state.settings.fooPath);
};
diff --git a/doc/development/fe_guide/graphql.md b/doc/development/fe_guide/graphql.md
index caf84d04490..191ebd2ff58 100644
--- a/doc/development/fe_guide/graphql.md
+++ b/doc/development/fe_guide/graphql.md
@@ -1,7 +1,69 @@
# GraphQL
+## Getting Started
+
+### Helpful Resources
+
+**General resources**:
+
+- [📚 Official Introduction to GraphQL](https://graphql.org/learn/)
+- [📚 Official Introduction to Apollo](https://www.apollographql.com/docs/tutorial/introduction/)
+
+**GraphQL at GitLab**:
+
+- [🎬 GitLab Unfiltered GraphQL playlist](https://www.youtube.com/watch?v=wHPKZBDMfxE&list=PL05JrBw4t0KpcjeHjaRMB7IGB2oDWyJzv)
+- [🎬 GraphQL at GitLab: Deep Dive](../api_graphql_styleguide.md#deep-dive) (video) by Nick Thomas
+ - An overview of the history of GraphQL at GitLab (not frontend-specific)
+- [🎬 GitLab Feature Walkthrough with GraphQL and Vue Apollo](https://www.youtube.com/watch?v=6yYp2zB7FrM) (video) by Natalia Tepluhina
+ - A real-life example of implementing a frontend feature in GitLab using GraphQL
+- [🎬 History of client-side GraphQL at GitLab](https://www.youtube.com/watch?v=mCKRJxvMnf0) (video) Illya Klymov and Natalia Tepluhina
+- [🎬 From Vuex to Apollo](https://www.youtube.com/watch?v=9knwu87IfU8) (video) by Natalia Tepluhina
+ - A useful overview of when Apollo might be a better choice than Vuex, and how one could go about the transition
+- [🛠 Vuex -> Apollo Migration: a proof-of-concept project](https://gitlab.com/ntepluhina/vuex-to-apollo/blob/master/README.md)
+ - A collection of examples that show the possible approaches for state management with Vue+GraphQL+(Vuex or Apollo) apps
+
+### Libraries
+
+We use [Apollo](https://www.apollographql.com/) (specifically [Apollo Client](https://www.apollographql.com/docs/react/)) and [Vue Apollo](https://github.com/vuejs/vue-apollo)
+when using GraphQL for frontend development.
+
+If you are using GraphQL within a Vue application, the [Usage in Vue](#usage-in-vue) section
+can help you learn how to integrate Vue Apollo.
+
+For other use cases, check out the [Usage outside of Vue](#usage-outside-of-vue) section.
+
+### Tooling
+
+- [Apollo Client Devtools](https://github.com/apollographql/apollo-client-devtools)
+
+#### [Apollo GraphQL VS Code extension](https://marketplace.visualstudio.com/items?itemName=apollographql.vscode-apollo)
+
+If you use VS Code, the Apollo GraphQL extension supports autocompletion in `.graphql` files. To set up
+the GraphQL extension, follow these steps:
+
+1. Add an `apollo.config.js` file to the root of your `gitlab` local directory.
+1. Populate the file with the following content:
+
+ ```javascript
+ module.exports = {
+ client: {
+ includes: ['./app/assets/javascripts/**/*.graphql', './ee/app/assets/javascripts/**/*.graphql'],
+ service: {
+ name: 'GitLab',
+ localSchemaFile: './doc/api/graphql/reference/gitlab_schema.graphql',
+ },
+ },
+ };
+ ```
+
+1. Restart VS Code.
+
+### Exploring the GraphQL API
+
Our GraphQL API can be explored via GraphiQL at your instance's
-`/-/graphql-explorer` or at [GitLab.com](https://gitlab.com/-/graphql-explorer).
+`/-/graphql-explorer` or at [GitLab.com](https://gitlab.com/-/graphql-explorer). Consult the
+[GitLab GraphQL API Reference documentation](../../api/graphql/reference)
+where needed.
You can check all existing queries and mutations on the right side
of GraphiQL in its **Documentation explorer**. It's also possible to
@@ -10,9 +72,6 @@ their execution by clicking **Execute query** button on the top left:
![GraphiQL interface](img/graphiql_explorer_v12_4.png)
-We use [Apollo](https://www.apollographql.com/) and [Vue Apollo](https://github.com/vuejs/vue-apollo) for working with GraphQL
-on the frontend.
-
## Apollo Client
To save duplicated clients getting created in different apps, we have a
@@ -30,7 +89,7 @@ Default client accepts two parameters: `resolvers` and `config`.
## GraphQL Queries
To save query compilation at runtime, webpack can directly import `.graphql`
-files. This allows webpack to preprocess the query at compile time instead
+files. This allows webpack to pre-process the query at compile time instead
of the client doing compilation of queries.
To distinguish queries from mutations and fragments, the following naming convention is recommended:
@@ -41,7 +100,7 @@ To distinguish queries from mutations and fragments, the following naming conven
### Fragments
-Fragments are a way to make your complex GraphQL queries more readable and re-usable. Here is an example of GraphQL fragment:
+[Fragments](https://graphql.org/learn/queries/#fragments) are a way to make your complex GraphQL queries more readable and re-usable. Here is an example of GraphQL fragment:
```javascript
fragment DesignListItem on Design {
@@ -94,7 +153,7 @@ new Vue({
});
```
-Read more about [Vue Apollo](https://github.com/vuejs/vue-apollo) in the [Vue Apollo documentation](https://vue-apollo.netlify.com/guide/).
+Read more about [Vue Apollo](https://github.com/vuejs/vue-apollo) in the [Vue Apollo documentation](https://vue-apollo.netlify.app/guide/).
### Local state with Apollo
@@ -206,11 +265,11 @@ const defaultClient = createDefaultClient(
Now every single time on attempt to fetch a version, our client will fetch `id` and `sha` from the remote API endpoint and will assign our hardcoded values to `author` and `createdAt` version properties. With this data, frontend developers are able to work on UI part without being blocked by backend. When actual response is added to the API, a custom local resolver can be removed fast and the only change to query/fragment is `@client` directive removal.
-Read more about local state management with Apollo in the [Vue Apollo documentation](https://vue-apollo.netlify.com/guide/local-state.html#local-state).
+Read more about local state management with Apollo in the [Vue Apollo documentation](https://vue-apollo.netlify.app/guide/local-state.html#local-state).
### Using with Vuex
-When Apollo Client is used within Vuex and fetched data is stored in the Vuex store, there is no need in keeping Apollo Client cache enabled. Otherwise we would have data from the API stored in two places - Vuex store and Apollo Client cache. More to say, with Apollo default settings, a subsequent fetch from the GraphQL API could result in fetching data from Apollo cache (in the case where we have the same query and variables). To prevent this behavior, we need to disable Apollo Client cache passing a valid `fetchPolicy` option to its constructor:
+When Apollo Client is used within Vuex and fetched data is stored in the Vuex store, there is no need in keeping Apollo Client cache enabled. Otherwise we would have data from the API stored in two places - Vuex store and Apollo Client cache. More to say, with Apollo's default settings, a subsequent fetch from the GraphQL API could result in fetching data from Apollo cache (in the case where we have the same query and variables). To prevent this behavior, we need to disable Apollo Client cache passing a valid `fetchPolicy` option to its constructor:
```javascript
import fetchPolicies from '~/graphql_shared/fetch_policy_constants';
@@ -411,18 +470,6 @@ fetchNextPage() {
Please note we don't have to save `pageInfo` one more time; `fetchMore` triggers a query
`result` hook as well.
-#### Limitations
-
-Currently, bidirectional pagination doesn't work:
-
-- `hasNextPage` returns a correct value only when we paginate forward using `endCursor`
- and `first` parameters.
-- `hasPreviousPage` returns a correct value only when we paginate backward using
- `startCursor` and `last` parameters.
-
-This should be resolved in the scope of the issue
-[Bi-directional Pagination in GraphQL doesn't work as expected](https://gitlab.com/gitlab-org/gitlab/-/issues/208301).
-
### Testing
#### Mocking response as component data
@@ -599,4 +646,20 @@ defaultClient.query({ query })
.then(result => console.log(result));
```
-Read more about the [Apollo](https://www.apollographql.com/) client in the [Apollo documentation](https://www.apollographql.com/docs/tutorial/client/).
+When [using Vuex](#Using-with-Vuex), disable the cache when:
+
+- The data is being cached elsewhere
+- The use case does not need caching
+if the data is being cached elsewhere, or if there is simply no need for it for the given use case.
+
+```javascript
+import createDefaultClient from '~/lib/graphql';
+import fetchPolicies from '~/graphql_shared/fetch_policy_constants';
+
+const defaultClient = createDefaultClient(
+ {},
+ {
+ fetchPolicy: fetchPolicies.NO_CACHE,
+ },
+);
+```
diff --git a/doc/development/fe_guide/icons.md b/doc/development/fe_guide/icons.md
index 4fb738f5466..131324e6479 100644
--- a/doc/development/fe_guide/icons.md
+++ b/doc/development/fe_guide/icons.md
@@ -24,7 +24,7 @@ sprite_icon(icon_name, size: nil, css_class: '')
- **icon_name** Use the icon_name that you can find in the SVG Sprite
([Overview is available here](https://gitlab-org.gitlab.io/gitlab-svgs)).
- **size (optional)** Use one of the following sizes : 16, 24, 32, 48, 72 (this will be translated into a `s16` class)
-- **css_class (optional)** If you want to add additional css classes
+- **css_class (optional)** If you want to add additional CSS classes
**Example**
@@ -67,8 +67,8 @@ export default {
- **name** Name of the Icon in the SVG Sprite ([Overview is available here](https://gitlab-org.gitlab.io/gitlab-svgs)).
- **size (optional)** Number value for the size which is then mapped to a specific CSS class
- (Available Sizes: 8, 12, 16, 18, 24, 32, 48, 72 are mapped to `sXX` css classes)
-- **css-classes (optional)** Additional CSS Classes to add to the svg tag.
+ (Available Sizes: 8, 12, 16, 18, 24, 32, 48, 72 are mapped to `sXX` CSS classes)
+- **css-classes (optional)** Additional CSS Classes to add to the SVG tag.
### Usage in HTML/JS
@@ -91,7 +91,7 @@ Please use the class `svg-content` around it to ensure nice rendering.
### Usage in Vue
-To use an SVG illustrations in a template provide the path as a property and display it through a standard img tag.
+To use an SVG illustrations in a template provide the path as a property and display it through a standard `img` tag.
Component:
diff --git a/doc/development/fe_guide/performance.md b/doc/development/fe_guide/performance.md
index aaa6bb16fab..5d2b699c40d 100644
--- a/doc/development/fe_guide/performance.md
+++ b/doc/development/fe_guide/performance.md
@@ -65,7 +65,7 @@ within the `pages` directory correspond to Rails controllers and actions. These
auto-generated bundles will be automatically included on the corresponding
pages.
-For example, if you were to visit <https://gitlab.com/gitlab-org/gitlab/issues>,
+For example, if you were to visit <https://gitlab.com/gitlab-org/gitlab/-/issues>,
you would be accessing the `app/controllers/projects/issues_controller.rb`
controller with the `index` action. If a corresponding file exists at
`pages/projects/issues/index/index.js`, it will be compiled into a webpack
diff --git a/doc/development/fe_guide/style/vue.md b/doc/development/fe_guide/style/vue.md
index 46305cc7217..1a64db443bc 100644
--- a/doc/development/fe_guide/style/vue.md
+++ b/doc/development/fe_guide/style/vue.md
@@ -53,7 +53,7 @@ Please check this [rules](https://github.com/vuejs/eslint-plugin-vue#bulb-rules)
## Naming
-1. **Extensions**: Use `.vue` extension for Vue components. Do not use `.js` as file extension ([#34371](https://gitlab.com/gitlab-org/gitlab-foss/issues/34371)).
+1. **Extensions**: Use `.vue` extension for Vue components. Do not use `.js` as file extension ([#34371](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/34371)).
1. **Reference Naming**: Use PascalCase for their instances:
```javascript
diff --git a/doc/development/fe_guide/vue.md b/doc/development/fe_guide/vue.md
index 972c2ded9c9..0d77e4d129b 100644
--- a/doc/development/fe_guide/vue.md
+++ b/doc/development/fe_guide/vue.md
@@ -6,9 +6,9 @@ To get started with Vue, read through [their documentation](https://vuejs.org/v2
What is described in the following sections can be found in these examples:
-- web ide: <https://gitlab.com/gitlab-org/gitlab-foss/tree/master/app/assets/javascripts/ide/stores>
-- security products: <https://gitlab.com/gitlab-org/gitlab/tree/master/ee/app/assets/javascripts/vue_shared/security_reports>
-- registry: <https://gitlab.com/gitlab-org/gitlab-foss/tree/master/app/assets/javascripts/registry/stores>
+- [Web IDE](https://gitlab.com/gitlab-org/gitlab-foss/tree/master/app/assets/javascripts/ide/stores)
+- [Security products](https://gitlab.com/gitlab-org/gitlab/tree/master/ee/app/assets/javascripts/vue_shared/security_reports)
+- [Registry](https://gitlab.com/gitlab-org/gitlab-foss/tree/master/app/assets/javascripts/registry/stores)
## Vue architecture
@@ -16,7 +16,7 @@ All new features built with Vue.js must follow a [Flux architecture](https://fac
The main goal we are trying to achieve is to have only one data flow and only one data entry.
In order to achieve this goal we use [vuex](#vuex).
-You can also read about this architecture in vue docs about [state management](https://vuejs.org/v2/guide/state-management.html#Simple-State-Management-from-Scratch)
+You can also read about this architecture in Vue docs about [state management](https://vuejs.org/v2/guide/state-management.html#Simple-State-Management-from-Scratch)
and about [one way data flow](https://vuejs.org/v2/guide/components.html#One-Way-Data-Flow).
### Components and Store
@@ -59,7 +59,7 @@ To do that, provide the data through `data` attributes in the HTML element and q
_Note:_ You should only do this while initializing the application, because the mounted element will be replaced with Vue-generated DOM.
The advantage of providing data from the DOM to the Vue instance through `props` in the `render` function
-instead of querying the DOM inside the main vue component is that makes tests easier by avoiding the need to
+instead of querying the DOM inside the main Vue component is that makes tests easier by avoiding the need to
create a fixture or an HTML element in the unit test. See the following example:
```javascript
diff --git a/doc/development/feature_flags/controls.md b/doc/development/feature_flags/controls.md
index 309aecd7978..d4d1ec74591 100644
--- a/doc/development/feature_flags/controls.md
+++ b/doc/development/feature_flags/controls.md
@@ -96,7 +96,7 @@ As a guideline:
Before toggling any feature flag, check that there are no ongoing
significant incidents on GitLab.com. You can do this by checking the
`#production` and `#incident-management` Slack channels, or looking for
-[open incident issues](https://gitlab.com/gitlab-com/gl-infra/production/issues/?scope=all&utf8=%E2%9C%93&state=opened&label_name[]=incident)
+[open incident issues](https://gitlab.com/gitlab-com/gl-infra/production/-/issues/?scope=all&utf8=%E2%9C%93&state=opened&label_name[]=incident)
(although check the dates and times).
We do not want to introduce changes during an incident, as it can make
@@ -113,17 +113,58 @@ When you begin to enable the feature, please link to the relevant
Feature Flag Rollout Issue within a Slack thread of the first `/chatops`
command you make so people can understand the change if they need to.
-To enable a feature for 25% of all users, run the following in Slack:
+To enable a feature for 25% of the time, run the following in Slack:
```shell
/chatops run feature set new_navigation_bar 25
```
+This sets a feature flag to `true` based on the following formula:
+
+```ruby
+feature_flag_state = rand < (25 / 100.0)
+```
+
This will enable the feature for GitLab.com, with `new_navigation_bar` being the
name of the feature.
This command does *not* enable the feature for 25% of the total users.
Instead, when the feature is checked with `enabled?`, it will return `true` 25% of the time.
+To enable a feature for 25% of actors such as users, projects, or groups,
+run the following in Slack:
+
+```shell
+/chatops run feature set some_feature 25 --actors
+```
+
+This sets a feature flag to `true` based on the following formula:
+
+```ruby
+feature_flag_state = Zlib.crc32("some_feature<Actor>:#{actor.id}") % (100 * 1_000) < 25 * 1_000]
+# where <Actor>: is a `User`, `Group`, `Project` and actor is an instance
+```
+
+During development, based on the nature of the feature, an actor choice
+should be made.
+
+For user focused features:
+
+```ruby
+Feature.enabled?(:feature_cool_avatars, current_user)
+```
+
+For group or namespace level features:
+
+```ruby
+Feature.enabled?(:feature_cooler_groups, group)
+```
+
+For project level features:
+
+```ruby
+Feature.enabled?(:feature_ice_cold_projects, project)
+```
+
If you are not certain what percentages to use, simply use the following steps:
1. 25%
@@ -158,15 +199,21 @@ you run these 2 commands:
```shell
/chatops run feature set --project=gitlab-org/gitlab some_feature true
-/chatops run feature set some_feature 25
+/chatops run feature set some_feature 25 --actors
+```
+
+Then `some_feature` will be enabled for both 25% of actors and always when interacting with
+`gitlab-org/gitlab`. This is a good idea if the feature flag development makes use of group
+actors.
+
+```ruby
+Feature.enabled?(:some_feature, group)
```
-Then `some_feature` will be enabled for both 25% of users and all users interacting with
-`gitlab-org/gitlab`.
+NOTE:
-NOTE: **Note:**
**Percentage of time** rollout is not a good idea if what you want is to make sure a feature
-is always on or off to the users.
+is always on or off to the users. In that case, **Percentage of actors** rollout is a better method.
### Feature flag change logging
@@ -174,7 +221,7 @@ Any feature flag change that affects GitLab.com (production) will
automatically be logged in an issue.
The issue is created in the
-[gl-infra/feature-flag-log](https://gitlab.com/gitlab-com/gl-infra/feature-flag-log/issues?scope=all&utf8=%E2%9C%93&state=closed)
+[gl-infra/feature-flag-log](https://gitlab.com/gitlab-com/gl-infra/feature-flag-log/-/issues?scope=all&utf8=%E2%9C%93&state=closed)
project, and it will at minimum log the Slack handle of person enabling
a feature flag, the time, and the name of the flag being changed.
diff --git a/doc/development/feature_flags/development.md b/doc/development/feature_flags/development.md
index b20db295919..a44bc70439e 100644
--- a/doc/development/feature_flags/development.md
+++ b/doc/development/feature_flags/development.md
@@ -23,6 +23,9 @@ class Foo < ActiveRecord::Base
end
```
+Only models that `include FeatureGate` or expose `flipper_id` method can be
+used as an actor for `Feature.enabled?`.
+
Features that are developed and are intended to be merged behind a feature flag
should not include a changelog entry. The entry should either be added in the merge
request removing the feature flag or the merge request where the default value of
@@ -87,6 +90,10 @@ this method you can expose the state of a feature flag as follows:
```ruby
before_action do
+ # Prefer to scope it per project or user e.g.
+ push_frontend_feature_flag(:vim_bindings, project)
+
+ # Avoid, if possible
push_frontend_feature_flag(:vim_bindings)
end
@@ -115,17 +122,30 @@ how to access feature flags in a Vue component.
### Specs
-In the test environment `Feature.enabled?` is stubbed to always respond to `true`,
-so we make sure behavior under feature flag doesn't go untested in some non-specific
-contexts.
+Our Flipper engine in the test environment works in a memory mode `Flipper::Adapters::Memory`.
+`production` and `development` modes use `Flipper::Adapters::ActiveRecord`.
+
+### `stub_feature_flags: true` (default and preferred)
-Whenever a feature flag is present, make sure to test _both_ states of the
-feature flag.
+In this mode Flipper is configured to use `Flipper::Adapters::Memory` and mark all feature
+flags to be on-by-default and persisted on a first use. This overwrites the `default_enabled:`
+of `Feature.enabled?` and `Feature.disabled?` returning always `true` unless feature flag
+is persisted.
+
+Make sure behavior under feature flag doesn't go untested in some non-specific contexts.
See the
[testing guide](../testing_guide/best_practices.md#feature-flags-in-tests)
for information and examples on how to stub feature flags in tests.
+### `stub_feature_flags: false`
+
+This disables a memory-stubbed flipper, and uses `Flipper::Adapters::ActiveRecord`
+a mode that is used by `production` and `development`.
+
+You should use this mode only when you really want to tests aspects of Flipper
+with how it interacts with `ActiveRecord`.
+
### Enabling a feature flag (in development)
In the rails console (`rails c`), enter the following command to enable your feature flag
@@ -139,3 +159,9 @@ Similarly, the following command will disable a feature flag:
```ruby
Feature.disable(:feature_flag_name)
```
+
+You can as well enable feature flag for a given gate:
+
+```ruby
+Feature.enable(:feature_flag_name, Project.find_by_full_path("root/my-project"))
+```
diff --git a/doc/development/filtering_by_label.md b/doc/development/filtering_by_label.md
index 19dece0d5c9..ef92bd35985 100644
--- a/doc/development/filtering_by_label.md
+++ b/doc/development/filtering_by_label.md
@@ -40,13 +40,13 @@ In particular, note that:
This is more complicated than is ideal. It makes the query construction more
prone to errors (such as
-[issue #15557](https://gitlab.com/gitlab-org/gitlab-foss/issues/15557)).
+[issue #15557](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/15557)).
## Attempt A: WHERE EXISTS
### Attempt A1: use multiple subqueries with WHERE EXISTS
-In [issue #37137](https://gitlab.com/gitlab-org/gitlab-foss/issues/37137)
+In [issue #37137](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/37137)
and its associated [merge request](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/14022),
we tried to replace the `GROUP BY` with multiple uses of `WHERE EXISTS`. For the
example above, this would give:
@@ -83,7 +83,7 @@ Having [removed MySQL support in GitLab 12.1](https://about.gitlab.com/blog/2019
using [PostgreSQL's arrays](https://www.postgresql.org/docs/11/arrays.html) became more
tractable as we didn't have to support two databases. We discussed denormalizing
the `label_links` table for querying in
-[issue #49651](https://gitlab.com/gitlab-org/gitlab-foss/issues/49651),
+[issue #49651](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/49651),
with two options: label IDs and titles.
We can think of both of those as array columns on `issues`, `merge_requests`,
@@ -147,7 +147,7 @@ WHERE
label_titles @> ARRAY['Plan', 'backend']
```
-And our [tests in issue #49651](https://gitlab.com/gitlab-org/gitlab-foss/issues/49651#note_188777346)
+And our [tests in issue #49651](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/49651#note_188777346)
showed that this could be fast.
However, at present, the disadvantages outweigh the advantages.
diff --git a/doc/development/geo.md b/doc/development/geo.md
index bf56340f8ec..5c781a60bac 100644
--- a/doc/development/geo.md
+++ b/doc/development/geo.md
@@ -94,7 +94,7 @@ projects that need updating. Those projects can be:
[Geo admin panel](../user/admin_area/geo_nodes.md).
When we fail to fetch a repository on the secondary `RETRIES_BEFORE_REDOWNLOAD`
-times, Geo does a so-called _redownload_. It will do a clean clone
+times, Geo does a so-called _re-download_. It will do a clean clone
into the `@geo-temporary` directory in the root of the storage. When
it's successful, we replace the main repo with the newly cloned one.
@@ -218,7 +218,7 @@ the performance of many synchronization operations.
FDW is a PostgreSQL extension ([`postgres_fdw`](https://www.postgresql.org/docs/11/postgres-fdw.html)) that is enabled within
the Geo Tracking Database (on a **secondary** node), which allows it
-to connect to the readonly database replica and perform queries and filter
+to connect to the read-only database replica and perform queries and filter
data from both instances.
This persistent connection is configured as an FDW server
@@ -226,7 +226,7 @@ named `gitlab_secondary`. This configuration exists within the database's user
context only. To access the `gitlab_secondary`, GitLab needs to use the
same database user that had previously been configured.
-The Geo Tracking Database accesses the readonly database replica via FDW as a regular user,
+The Geo Tracking Database accesses the read-only database replica via FDW as a regular user,
limited by its own restrictions. The credentials are configured as a
`USER MAPPING` associated with the `SERVER` mapped previously
(`gitlab_secondary`).
diff --git a/doc/development/geo/framework.md b/doc/development/geo/framework.md
index d72f7cc4cc1..85fecc41cfb 100644
--- a/doc/development/geo/framework.md
+++ b/doc/development/geo/framework.md
@@ -257,6 +257,8 @@ For example, to add support for files referenced by a `Widget` model with a
class Geo::WidgetRegistry < Geo::BaseRegistry
include Geo::StateMachineRegistry
+ MODEL_FOREIGN_KEY = :widget_id
+
belongs_to :widget, class_name: 'Widget'
end
```
@@ -305,6 +307,8 @@ For example, to add support for files referenced by a `Widget` model with a
specify 'factory is valid' do
expect(registry).to be_valid
end
+
+ include_examples 'a Geo framework registry'
end
```
@@ -356,7 +360,8 @@ Widgets should now be replicated by Geo!
end
```
-1. Add fields `widget_count`, `widget_checksummed_count`, and `widget_checksum_failed_count`
+1. Add fields `widget_count`, `widget_checksummed_count`, `widget_checksum_failed_count`,
+ `widget_synced_count` and `widget_failed_count`
to `GeoNodeStatus#RESOURCE_STATUS_FIELDS` array in `ee/app/models/geo_node_status.rb`.
1. Add the same fields to `GeoNodeStatus#PROMETHEUS_METRICS` hash in
`ee/app/models/geo_node_status.rb`.
@@ -370,6 +375,8 @@ Widgets should now be replicated by Geo!
self.widget_count = Geo::WidgetReplicator.model.count
self.widget_checksummed_count = Geo::WidgetReplicator.checksummed.count
self.widget_checksum_failed_count = Geo::WidgetReplicator.checksum_failed.count
+ self.widget_synced_count = Geo::WidgetReplicator.synced_count
+ self.widget_failed_count = Geo::WidgetReplicator.failed_count
```
1. Make sure `Widget` model has `checksummed` and `checksum_failed` scopes.
@@ -450,7 +457,7 @@ Widgets should now be verified by Geo!
end
```
-1. Create `ee/app/graphql/types/geo/package_file_registry_type.rb`:
+1. Create `ee/app/graphql/types/geo/widget_registry_type.rb`:
```ruby
# frozen_string_literal: true
diff --git a/doc/development/git_object_deduplication.md b/doc/development/git_object_deduplication.md
index 938882ba5a2..06af34d9232 100644
--- a/doc/development/git_object_deduplication.md
+++ b/doc/development/git_object_deduplication.md
@@ -89,7 +89,7 @@ are as follows:
(`pool.source_project`)
> TODO Fix invalid SQL data for pools created prior to GitLab 11.11
-> <https://gitlab.com/gitlab-org/gitaly/issues/1653>.
+> <https://gitlab.com/gitlab-org/gitaly/-/issues/1653>.
### Assumptions
@@ -133,7 +133,7 @@ are as follows:
repository.
> TODO should forks of forks be deduplicated?
-> <https://gitlab.com/gitlab-org/gitaly/issues/1532>
+> <https://gitlab.com/gitlab-org/gitaly/-/issues/1532>
### Consequences
@@ -191,4 +191,4 @@ the secondary, at which stage Git objects will get deduplicated.
> TODO How do we handle the edge case where at the time the Geo
> secondary tries to create the pool repository, the source project does
-> not exist? <https://gitlab.com/gitlab-org/gitaly/issues/1533>
+> not exist? <https://gitlab.com/gitlab-org/gitaly/-/issues/1533>
diff --git a/doc/development/gitaly.md b/doc/development/gitaly.md
index 5e5cae7228b..417c96a44dd 100644
--- a/doc/development/gitaly.md
+++ b/doc/development/gitaly.md
@@ -54,7 +54,7 @@ The process for adding new Gitaly features is:
These steps often overlap. It is possible to use an unreleased version
of Gitaly and `gitaly-proto` during testing and development.
-- See the [Gitaly repo](https://gitlab.com/gitlab-org/gitaly/blob/master/CONTRIBUTING.md#development-and-testing-with-a-custom-gitaly-proto) for instructions on writing server side code with an unreleased protocol.
+- See the [Gitaly repository](https://gitlab.com/gitlab-org/gitaly/blob/master/CONTRIBUTING.md#development-and-testing-with-a-custom-gitaly-proto) for instructions on writing server side code with an unreleased protocol.
- See [below](#running-tests-with-a-locally-modified-version-of-gitaly) for instructions on running GitLab CE tests with a modified version of Gitaly.
- In GDK run `gdk install` and restart `gdk run` (or `gdk run app`) to use a locally modified Gitaly version for development
@@ -67,7 +67,7 @@ This should make it easier to contribute for developers who are less
comfortable writing Go code.
There is documentation for this approach in [the Gitaly
-repo](https://gitlab.com/gitlab-org/gitaly/blob/master/doc/ruby_endpoint.md).
+repository](https://gitlab.com/gitlab-org/gitaly/blob/master/doc/ruby_endpoint.md).
## Gitaly-Related Test Failures
@@ -85,7 +85,7 @@ While Gitaly can handle all Git access, many of GitLab customers still
run Gitaly atop NFS. The legacy Rugged implementation for Git calls may
be faster than the Gitaly RPC due to N+1 Gitaly calls and other
reasons. See [the
-issue](https://gitlab.com/gitlab-org/gitlab-foss/issues/57317) for more
+issue](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/57317) for more
details.
Until GitLab has eliminated most of these inefficiencies or the use of
@@ -323,8 +323,8 @@ the integration by using GDK:
1. Navigate to GDK's root directory.
1. Make sure you have the proper branch checked out for Gitaly.
1. Recompile it with `make gitaly-setup` and restart the service with `gdk restart gitaly`.
- 1. Make sure your setup is runnig: `gdk status | grep praefect`.
- 1. Check what config file is used: `cat ./services/praefect/run | grep praefect` value of the `-config` flag
+ 1. Make sure your setup is running: `gdk status | grep praefect`.
+ 1. Check what configuration file is used: `cat ./services/praefect/run | grep praefect` value of the `-config` flag
1. Uncomment `prometheus_listen_addr` in the configuration file and run `gdk restart gitaly`.
1. Make sure that the flag is not enabled yet:
diff --git a/doc/development/github_importer.md b/doc/development/github_importer.md
index 5d37d2f119f..5a490737f37 100644
--- a/doc/development/github_importer.md
+++ b/doc/development/github_importer.md
@@ -121,12 +121,12 @@ also reduce pressure on the system as a whole.
## Refreshing import JIDs
-GitLab includes a worker called `StuckImportJobsWorker` that will periodically
-run and mark project imports as failed if they have been running for more than
-15 hours. For GitHub projects, this poses a bit of a problem: importing large
-projects could take several hours depending on how often we hit the GitHub rate
-limit (more on this below), but we don't want `StuckImportJobsWorker` to mark
-our import as failed because of this.
+GitLab includes a worker called `Gitlab::Import::StuckProjectImportJobsWorker`
+that will periodically run and mark project imports as failed if they have been
+running for more than 15 hours. For GitHub projects, this poses a bit of a
+problem: importing large projects could take several hours depending on how
+often we hit the GitHub rate limit (more on this below), but we don't want
+`Gitlab::Import::StuckProjectImportJobsWorker` to mark our import as failed because of this.
To prevent this from happening we periodically refresh the expiration time of
the import process. This works by storing the JID of the import job in the
diff --git a/doc/development/go_guide/dependencies.md b/doc/development/go_guide/dependencies.md
new file mode 100644
index 00000000000..b85344635c6
--- /dev/null
+++ b/doc/development/go_guide/dependencies.md
@@ -0,0 +1,175 @@
+# Dependency Management in Go
+
+Go takes an unusual approach to dependency management, in that it is
+source-based instead of artifact-based. In an artifact-based dependency
+management system, packages consist of artifacts generated from source code and
+are stored in a separate repository system from source code. For example, many
+NodeJS packages use `npmjs.org` as a package repository and `github.com` as a
+source repository. On the other hand, packages in Go *are* source code and
+releasing a package does not involve artifact generation or a separate
+repository. Go packages must be stored in a version control repository on a VCS
+server. Dependencies are fetched directly from their VCS server or via an
+intermediary proxy which itself fetches them from their VCS server.
+
+## Versioning
+
+Go 1.11 introduced modules and first-class package versioning to the Go ecosystem.
+Prior to this, Go did not have any well-defined mechanism for version management.
+While 3rd party version management tools existed, the default Go experience had
+no support for versioning.
+
+Go modules use [semantic versioning](https://semver.org). The versions of a
+module are defined as VCS (version control system) tags that are valid semantic
+versions prefixed with `v`. For example, to release version `1.0.0` of
+`gitlab.com/my/project`, the developer must create the Git tag `v1.0.0`.
+
+For major versions other than 0 and 1, the module name must be suffixed with
+`/vX` where X is the major version. For example, version `v2.0.0` of
+`gitlab.com/my/project` must be named and imported as
+`gitlab.com/my/project/v2`.
+
+Go uses 'pseudo-versions', which are special semantic versions that reference a
+specific VCS commit. The prerelease component of the semantic version must be or
+end with a timestamp and the first 12 characters of the commit identifier:
+
+- `vX.0.0-yyyymmddhhmmss-abcdefabcdef`, when no earlier tagged commit exists for X.
+- `vX.Y.Z-pre.0.yyyymmddhhmmss-abcdefabcdef`, when most recent prior tag is vX.Y.Z-pre.
+- `vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdefabcdef`, when most recent prior tag is vX.Y.Z.
+
+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
+website.
+
+## 'Module' vs 'Package'
+
+- A package is a folder containing `*.go` files.
+- A module is a folder containing a `go.mod` file.
+- A module is *usually* also a package, that is a folder containing a `go.mod`
+ file and `*.go` files.
+- A module may have subdirectories, which may be packages.
+- Modules usually come in the form of a VCS repository (Git, SVN, Hg, and so on).
+- Any subdirectories of a module that themselves are modules are distinct,
+ separate modules and are excluded from the containing module.
+ - Given a module `repo`, if `repo/sub` contains a `go.mod` file then
+ `repo/sub` and any files contained therein are a separate module and not a
+ part of `repo`.
+
+## Naming
+
+The name of a module or package, excluding the standard library, must be of the
+form `(sub.)*domain.tld(/path)*`. This is similar to a URL, but is not a URL.
+The package name does not have a scheme (such as `https://`) and cannot have a
+port number. `example.com:8443/my/package` is not a valid name.
+
+## Fetching Packages
+
+Prior to Go 1.12, the process for fetching a package was as follows:
+
+1. Query `https://{package name}?go-get=1`.
+1. Scan the response for the `go-import` meta tag.
+1. Fetch the repository indicated by the meta tag using the indicated VCS.
+
+The meta tag should have the form `<meta name="go-import" content="{prefix}
+{vcs} {url}">`. For example, `gitlab.com/my/project git
+https://gitlab.com/my/project.git` indicates that packages beginning with
+`gitlab.com/my/project` should be fetched from
+`https://gitlab.com/my/project.git` using Git.
+
+## Fetching Modules
+
+Go 1.12 introduced checksum databases and module proxies.
+
+### Checksums
+
+In addition to `go.mod`, a module will have a `go.sum` file. This file records a
+SHA-256 checksum of the code and the `go.mod` file of every version of every
+dependency that is referenced by the module or one of the module's dependencies.
+Go continually updates `go.sum` as new dependencies are referenced.
+
+When Go fetches the dependencies of a module, if those dependencies already have
+an entry in `go.sum`, Go will verify the checksum of these dependencies. If the
+checksum does not match what is in `go.sum`, the build will fail. This ensures
+that a given version of a module cannot be changed by its developers or by a
+malicious party without causing build failures.
+
+Go 1.12+ can be configured to use a checksum database. If configured to do so,
+when Go fetches a dependency and there is no corresponding entry in `go.sum`, Go
+will query the configured checksum database(s) for the checksum of the
+dependency instead of calculating it from the downloaded dependency. If the
+dependency cannot be found in the checksum database, the build will fail. If the
+downloaded dependency's checksum does not match the result from the checksum
+database, the build will fail. The following environment variables control this:
+
+- `GOSUMDB` identifies the name, and optionally the public key and server URL,
+ of the checksum database to query.
+ - A value of `off` will entirely disable checksum database queries.
+ - Go 1.13+ uses `sum.golang.org` if `GOSUMDB` is not defined.
+- `GONOSUMDB` is a comma-separated list of module suffixes that checksum
+ database queries should be disabled for. Wildcards are supported.
+- `GOPRIVATE` is a comma-separated list of module names that has the same
+ function as `GONOSUMDB` in addition to disabling other features.
+
+### Proxies
+
+Go 1.12+ can be configured to fetch modules from a Go proxy instead of directly
+from the module's VCS. If configured to do so, when Go fetches a dependency, it
+attempts to fetch the dependency from the configured proxies, in order. The
+following environment variables control this:
+
+- `GOPROXY` is a comma-separated list of module proxies to query.
+ - A value of `direct` will entirely disable module proxy queries.
+ - If the last entry in the list is `direct`, Go will fall back to the process
+ described [above](#fetching-packages) if none of the proxies can provide the
+ dependency.
+ - Go 1.13+ uses `proxy.golang.org,direct` if `GOPROXY` is not defined.
+- `GONOPROXY` is a comma-separated list of module suffixes that should be
+ fetched directly and not from a proxy. Wildcards are supported.
+- `GOPRIVATE` is a comma-separated list of module names that has the same
+ function as `GONOPROXY` in addition to disabling other features.
+
+### Fetching
+
+From Go 1.12 onward, the process for fetching a module or package is as follows:
+
+1. If `GOPROXY` is a list of proxies and the module is not excluded by
+ `GONOPROXY` or `GOPRIVATE`, query them in order, and stop at the first valid
+ response.
+1. If `GOPROXY` is `direct`, or the module is excluded, or `GOPROXY` ends with
+ `,direct` and no proxy provided the module, fall back.
+ 1. Query `https://{module or package name}?go-get=1`.
+ 1. Scan the response for the `go-import` meta tag.
+ 1. Fetch the repository indicated by the meta tag using the indicated VCS.
+ 1. If the `{vcs}` field is `mod`, the URL should be treated as a module proxy instead of a VCS.
+1. If the module is being fetched directly and not as a dependency, stop.
+1. If `go.sum` contains an entry corresponding to the module, validate the checksum and stop.
+1. If `GOSUMDB` identifies a checksum database and the module is not excluded by
+ `GONOSUMDB` or `GOPRIVATE`, retrieve the module's checksum, add it to
+ `go.sum`, and validate the downloaded source against it.
+1. If `GOSUMDB` is `off` or the module is excluded, calculate a checksum from
+ the downloaded source and add it to `go.sum`.
+
+The downloaded source must contain a `go.mod` file. The `go.mod` file must
+contain a `module` directive that specifies the name of the module. If the
+module name as specified by `go.mod` does not match the name that was used to
+fetch the module, the module will fail to compile.
+
+If the module is being fetched directly and no version was specified, or if the
+module is being added as a dependency and no version was specified, Go uses the
+most recent version of the module. If the module is fetched from a proxy, Go
+queries the proxy for a list of versions and chooses the latest. If the module is
+fetched directly, Go queries the repository for a list of tags and chooses the
+latest that is also a valid semantic version.
+
+## Authenticating
+
+In versions prior to Go 1.13, support for authenticating requests made by Go was
+somewhat inconsistent. Go 1.13 improved support for `.netrc` authentication. If
+a request is made over HTTPS and a matching `.netrc` entry can be found, Go will
+add HTTP Basic authentication credentials to the request. Go will not
+authenticate requests made over HTTP. Go will reject HTTP-only entries in
+`GOPROXY` that have embedded credentials.
+
+In a future version, Go may add support for arbitrary authentication headers.
+Follow [golang/go#26232](https://github.com/golang/go/issues/26232) for details.
diff --git a/doc/development/go_guide/index.md b/doc/development/go_guide/index.md
index fe69a4205f8..5a5e163e142 100644
--- a/doc/development/go_guide/index.md
+++ b/doc/development/go_guide/index.md
@@ -17,6 +17,22 @@ experiences. Several projects were started with different standards and they
can still have specifics. They will be described in their respective
`README.md` or `PROCESS.md` files.
+## Dependency Management
+
+Go uses a source-based strategy for dependency management. Dependencies are
+downloaded as source from their source repository. This differs from the more
+common artifact-based strategy where dependencies are downloaded as artifacts
+from a package repository that is separate from the dependency's source
+repository.
+
+Go did not have first-class support for version management prior to 1.11. That
+version introduced Go modules and the use of semantic versioning. Go 1.12
+introduced module proxies, which can serve as an intermediate between clients
+and source version control systems, and checksum databases, which can be used to
+verify the integrity of dependency downloads.
+
+See [Dependency Management in Go](dependencies.md) for more details.
+
## Code Review
We follow the common principles of
@@ -105,7 +121,7 @@ Including a `.golangci.yml` in the root directory of the project allows for
configuration of `golangci-lint`. All options for `golangci-lint` are listed in
this [example](https://github.com/golangci/golangci-lint/blob/master/.golangci.example.yml).
-Once [recursive includes](https://gitlab.com/gitlab-org/gitlab-foss/issues/56836)
+Once [recursive includes](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/56836)
become available, you will be able to share job templates like this
[analyzer](https://gitlab.com/gitlab-org/security-products/ci-templates/raw/master/includes-dev/analyzer.yml).
@@ -260,7 +276,7 @@ easier to debug.
For example:
-```go
+```golang
// Wrap the error
return nil, fmt.Errorf("get cache %s: %w", f.Name, err)
@@ -390,7 +406,7 @@ builds](https://docs.docker.com/develop/develop-images/multistage-build/):
dependencies.
- They generate a small, self-contained image, derived from `Scratch`.
-Generated docker images should have the program at their `Entrypoint` to create
+Generated Docker images should have the program at their `Entrypoint` to create
portable commands. That way, anyone can run the image, and without parameters
it will display its help message (if `cli` has been used).
diff --git a/doc/development/gotchas.md b/doc/development/gotchas.md
index 8f077e613b7..7e08da8162b 100644
--- a/doc/development/gotchas.md
+++ b/doc/development/gotchas.md
@@ -155,7 +155,7 @@ refresh_service.execute(oldrev, newrev, ref)
See ["Why is it bad style to `rescue Exception => e` in Ruby?"](https://stackoverflow.com/questions/10048173/why-is-it-bad-style-to-rescue-exception-e-in-ruby).
_**Note:** This rule is [enforced automatically by
-Rubocop](https://gitlab.com/gitlab-org/gitlab-foss/blob/8-4-stable/.rubocop.yml#L911-914)._
+RuboCop](https://gitlab.com/gitlab-org/gitlab-foss/blob/8-4-stable/.rubocop.yml#L911-914)._
## Do not use inline JavaScript in views
diff --git a/doc/development/hash_indexes.md b/doc/development/hash_indexes.md
index bc962ac0cd6..1ed76e35f69 100644
--- a/doc/development/hash_indexes.md
+++ b/doc/development/hash_indexes.md
@@ -1,6 +1,6 @@
# Hash Indexes
-PostgreSQL supports hash indexes besides the regular btree
+PostgreSQL supports hash indexes besides the regular B-tree
indexes. Hash indexes however are to be avoided at all costs. While they may
_sometimes_ provide better performance the cost of rehashing can be very high.
More importantly: at least until PostgreSQL 10.0 hash indexes are not
@@ -17,4 +17,4 @@ documentation:
RuboCop is configured to register an offense when it detects the use of a hash
index.
-Instead of using hash indexes you should use regular btree indexes.
+Instead of using hash indexes you should use regular B-tree indexes.
diff --git a/doc/development/i18n/externalization.md b/doc/development/i18n/externalization.md
index a81e656fc27..bdd372e90ed 100644
--- a/doc/development/i18n/externalization.md
+++ b/doc/development/i18n/externalization.md
@@ -260,8 +260,22 @@ n_("%{project_name}", "%d projects selected", count) % { project_name: 'GitLab'
### Namespaces
-Sometimes you need to add some context to the text that you want to translate
-(if the word occurs in a sentence and/or the word is ambiguous).
+A namespace is a way to group translations that belong together. They provide context to our translators by adding a prefix followed by the bar symbol (`|`). For example:
+
+```ruby
+'Namespace|Translated string'
+```
+
+A namespace provide the following benefits:
+
+- It addresses ambiguity in words, for example: `Promotions|Promote` vs `Epic|Promote`
+- It allows translators to focus on translating externalized strings that belong to the same product area rather than arbitrary ones.
+- It gives a linguistic context to help the translator.
+
+In some cases, namespaces don't make sense, for example,
+for ubiquitous UI words and phrases such as "Cancel" or phrases like "Save changes" a namespace could
+be counterproductive.
+
Namespaces should be PascalCase.
- In Ruby/HAML:
@@ -292,7 +306,7 @@ const dateFormat = createDateTimeFormat({ year: 'numeric', month: 'long', day: '
console.log(dateFormat.format(new Date('2063-04-05'))) // April 5, 2063
```
-This makes use of [`Intl.DateTimeFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat).
+This makes use of [`Intl.DateTimeFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat).
- In Ruby/HAML, we have two ways of adding format to dates and times:
diff --git a/doc/development/i18n/merging_translations.md b/doc/development/i18n/merging_translations.md
index 5d9dbd23efa..e0fcaddda4c 100644
--- a/doc/development/i18n/merging_translations.md
+++ b/doc/development/i18n/merging_translations.md
@@ -20,7 +20,7 @@ doesn't do. Create a new pipeline at `https://gitlab.com/gitlab-org/gitlab/pipel
If there are validation errors, the easiest solution is to disapprove
the offending string in CrowdIn, leaving a comment with what is
required to fix the offense. There is an
-[issue](https://gitlab.com/gitlab-org/gitlab/issues/23256)
+[issue](https://gitlab.com/gitlab-org/gitlab/-/issues/23256)
suggesting to automate this process. Disapproving will exclude the
invalid translation, the merge request will be updated within a few
minutes.
@@ -31,7 +31,7 @@ clicking `Pause sync` on the [CrowdIn integration settings
page](https://translate.gitlab.com/project/gitlab-ee/settings#integration).
When all failures are resolved, the translations need to be double
-checked once more as discussed in [confidential issue](../../user/project/issues/confidential_issues.md) `https://gitlab.com/gitlab-org/gitlab/issues/19485`.
+checked once more as discussed in [confidential issue](../../user/project/issues/confidential_issues.md) `https://gitlab.com/gitlab-org/gitlab/-/issues/19485`.
## Merging translations
@@ -40,7 +40,7 @@ translations can be merged into the master branch. When merging the translations
make sure to check the **Remove source branch** checkbox, so CrowdIn recreates the
`master-i18n` from master after the new translation was merged.
-We are discussing [automating this entire process](https://gitlab.com/gitlab-org/gitlab/issues/19896).
+We are discussing [automating this entire process](https://gitlab.com/gitlab-org/gitlab/-/issues/19896).
## Recreate the merge request
@@ -53,3 +53,18 @@ and delete the
This might be needed when the merge request contains failures that
have been fixed on master.
+
+## Recreate the GitLab integration in CrowdIn
+
+NOTE: ***Note:**
+These instructions work only for GitLab Team Members.
+
+If for some reason the GitLab integration in CrowdIn does not exist, it can be
+recreated by the following steps:
+
+1. Sign in to GitLab as `gitlab-crowdin-bot` (If you're a GitLab Team Member, find credentials in the GitLab shared [1Password account](https://about.gitlab.com/handbook/security/#1password-for-teams)
+1. Sign in to Crowdin with the GitLab integration
+1. Navigate to Settings > Integrations > GitLab > Set Up Integration
+1. Select `gitlab-org/gitlab` repository
+1. On `Select Branches for Translation`, select `master`
+1. Ensure the `Service Branch Name` is `master-i18n`
diff --git a/doc/development/i18n/proofreader.md b/doc/development/i18n/proofreader.md
index 837da349f7e..8c1f62330f4 100644
--- a/doc/development/i18n/proofreader.md
+++ b/doc/development/i18n/proofreader.md
@@ -5,12 +5,15 @@ are very appreciative of the work done by translators and proofreaders!
## Proofreaders
+<!-- vale gitlab.Spelling = NO -->
- Albanian
- Proofreaders needed.
- Amharic
- Tsegaselassie Tadesse - [GitLab](https://gitlab.com/tsega), [CrowdIn](https://crowdin.com/profile/tsegaselassi/activity)
- Arabic
- Proofreaders needed.
+- Bosnian
+ - Proofreaders needed.
- Bulgarian
- Lyubomir Vasilev - [CrowdIn](https://crowdin.com/profile/lyubomirv)
- Catalan
@@ -26,6 +29,8 @@ are very appreciative of the work done by translators and proofreaders!
- Chinese Traditional, Hong Kong ç¹é«”中文 (香港)
- Victor Wu - [GitLab](https://gitlab.com/victorwuky), [CrowdIn](https://crowdin.com/profile/victorwu)
- Ivan Ip - [GitLab](https://gitlab.com/lifehome), [CrowdIn](https://crowdin.com/profile/lifehome)
+- Croatian
+ - Proofreaders needed.
- Czech
- Jan Urbanec - [GitLab](https://gitlab.com/TatranskyMedved), [CrowdIn](https://crowdin.com/profile/Tatranskymedved)
- Danish
@@ -33,11 +38,11 @@ are very appreciative of the work done by translators and proofreaders!
- Dutch
- Emily Hendle - [GitLab](https://gitlab.com/pundachan), [CrowdIn](https://crowdin.com/profile/pandachan)
- Esperanto
-- Lyubomir Vasilev - [CrowdIn](https://crowdin.com/profile/lyubomirv)
+ - Lyubomir Vasilev - [CrowdIn](https://crowdin.com/profile/lyubomirv)
- Estonian
- Proofreaders needed.
- Filipino
- - Proofreaders needed.
+ - Andrei Jiroh Halili - [GitLab](https://gitlab.com/AJHalili2006DevPH), [Crowdin](https://crowdin.com/profile/AndreiJirohHaliliDev2006)
- French
- Davy Defaud - [GitLab](https://gitlab.com/DevDef), [CrowdIn](https://crowdin.com/profile/DevDef)
- Galician
@@ -50,6 +55,8 @@ are very appreciative of the work done by translators and proofreaders!
- Proofreaders needed.
- Hebrew
- Yaron Shahrabani - [GitLab](https://gitlab.com/yarons), [CrowdIn](https://crowdin.com/profile/YaronSh)
+- Hindi
+ - Proofreaders needed.
- Hungarian
- Proofreaders needed.
- Indonesian
@@ -62,6 +69,7 @@ are very appreciative of the work done by translators and proofreaders!
- Hiroyuki Sato - [GitLab](https://gitlab.com/hiroponz), [CrowdIn](https://crowdin.com/profile/hiroponz)
- Tomo Dote - [GitLab](https://gitlab.com/fu7mu4), [CrowdIn](https://crowdin.com/profile/fu7mu4)
- Hiromi Nozawa - [GitLab](https://gitlab.com/hir0mi), [CrowdIn](https://crowdin.com/profile/hir0mi)
+ - Takuya Noguchi - [GitLab](https://gitlab.com/tnir), [CrowdIn](https://crowdin.com/profile/tnir)
- Korean
- Chang-Ho Cha - [GitLab](https://gitlab.com/changho-cha), [CrowdIn](https://crowdin.com/profile/zzazang)
- Ji Hun Oh - [GitLab](https://gitlab.com/Baw-Appie), [CrowdIn](https://crowdin.com/profile/BawAppie)
@@ -74,7 +82,6 @@ are very appreciative of the work done by translators and proofreaders!
- Filip Mech - [GitLab](https://gitlab.com/mehenz), [CrowdIn](https://crowdin.com/profile/mehenz)
- Maksymilian Roman - [GitLab](https://gitlab.com/villaincandle), [CrowdIn](https://crowdin.com/profile/villaincandle)
- Portuguese
- - Proofreaders needed.
- Diogo Trindade - [GitLab](https://gitlab.com/luisdiogo2071317), [CrowdIn](https://crowdin.com/profile/ldiogotrindade)
- Portuguese, Brazilian
- Paulo George Gomes Bezerra - [GitLab](https://gitlab.com/paulobezerra), [CrowdIn](https://crowdin.com/profile/paulogomes.rep)
@@ -88,21 +95,22 @@ are very appreciative of the work done by translators and proofreaders!
- NickVolynkin - [Crowdin](https://crowdin.com/profile/NickVolynkin)
- Andrey Komarov - [GitLab](https://gitlab.com/elkamarado), [Crowdin](https://crowdin.com/profile/kamarado)
- Iaroslav Postovalov - [GitLab](https://gitlab.com/CMDR_Tvis), [Crowdin](https://crowdin.com/profile/CMDR_Tvis)
-- Serbian (Cyrillic)
- - Proofreaders needed.
-- Serbian (Latin)
+- Serbian (Latin and Cyrillic)
- Proofreaders needed.
- Slovak
- Proofreaders needed.
- Spanish
- Pedro Garcia - [GitLab](https://gitlab.com/pedgarrod), [CrowdIn](https://crowdin.com/profile/breaking_pitt)
+- Swedish
+ - Proofreaders needed.
- Turkish
- Ali DemirtaÅŸ - [GitLab](https://gitlab.com/alidemirtas), [CrowdIn](https://crowdin.com/profile/alidemirtas)
- 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)
- Welsh
- - Proofreaders needed.
+ - Delyth Prys - [GitLab](https://gitlab.com/Delyth), [CrowdIn](https://crowdin.com/profile/DelythPrys)
+<!-- vale gitlab.Spelling = YES -->
## Become a proofreader
diff --git a/doc/development/i18n/translation.md b/doc/development/i18n/translation.md
index e1c02c2c9c2..ed205c20c0d 100644
--- a/doc/development/i18n/translation.md
+++ b/doc/development/i18n/translation.md
@@ -61,8 +61,12 @@ This helps maintain a logical connection and consistency between tools (e.g.
### Formality
-The level of formality used in software varies by language.
-For example, in French we translate `you` as the formal `vous`.
+The level of formality used in software varies by language:
+
+| Language | Formality | Example |
+| -------- | --------- | ------- |
+| French | formal | `vous` for `you` |
+| German | informal | `du` for `you` |
You can refer to other translated strings and notes in the glossary to assist
determining a suitable level of formality.
@@ -75,18 +79,22 @@ ethnicity.
In languages which distinguish between a male and female form, use both or
choose a neutral formulation.
+<!-- vale gitlab.Spelling = NO -->
For example in German, the word "user" can be translated into "Benutzer" (male) or "Benutzerin" (female).
Therefore "create a new user" would translate into "Benutzer(in) anlegen".
+<!-- vale gitlab.Spelling = YES -->
### Updating the glossary
To propose additions to the glossary please
-[open an issue](https://gitlab.com/gitlab-org/gitlab/issues?scope=all&utf8=✓&state=all&label_name[]=Category%3AInternationalization).
+[open an issue](https://gitlab.com/gitlab-org/gitlab/-/issues?scope=all&utf8=✓&state=all&label_name[]=Category%3AInternationalization).
## French Translation Guidelines
### Inclusive language in French
+<!-- vale gitlab.Spelling = NO -->
In French, the "écriture inclusive" is now over (see on [Legifrance](https://www.legifrance.gouv.fr/affichTexte.do?cidTexte=JORFTEXT000036068906&categorieLien=id)).
So, to include both genders, write “Utilisateurs et utilisatrices†instead of “Utilisateur·rice·sâ€.
When space is missing, the male gender should be used alone.
+<!-- vale gitlab.Spelling = YES -->
diff --git a/doc/development/img/bullet_v13_0.png b/doc/development/img/bullet_v13_0.png
new file mode 100644
index 00000000000..04b476db581
--- /dev/null
+++ b/doc/development/img/bullet_v13_0.png
Binary files differ
diff --git a/doc/development/import_export.md b/doc/development/import_export.md
index 6d1b6929667..ecdfd8a853e 100644
--- a/doc/development/import_export.md
+++ b/doc/development/import_export.md
@@ -44,19 +44,34 @@ WARN: Work still in progress <struct with JID>
### Timeouts
-Timeout errors occur due to the `StuckImportJobsWorker` marking the process as failed:
+Timeout errors occur due to the `Gitlab::Import::StuckProjectImportJobsWorker` marking the process as failed:
```ruby
-class StuckImportJobsWorker
- include ApplicationWorker
- include CronjobQueue
-
- IMPORT_JOBS_EXPIRATION = 15.hours.to_i
+module Gitlab
+ module Import
+ class StuckProjectImportJobsWorker
+ include Gitlab::Import::StuckImportJob
+ # ...
+ end
+ end
+end
- def perform
- import_state_without_jid_count = mark_import_states_without_jid_as_failed!
- import_state_with_jid_count = mark_import_states_with_jid_as_failed!
- ...
+module Gitlab
+ module Import
+ module StuckImportJob
+ # ...
+ IMPORT_JOBS_EXPIRATION = 15.hours.to_i
+ # ...
+ def perform
+ stuck_imports_without_jid_count = mark_imports_without_jid_as_failed!
+ stuck_imports_with_jid_count = mark_imports_with_jid_as_failed!
+
+ track_metrics(stuck_imports_with_jid_count, stuck_imports_without_jid_count)
+ end
+ # ...
+ end
+ end
+end
```
```shell
@@ -92,14 +107,14 @@ Marked stuck import jobs as failed. JIDs: xyz
While the performance problems are not tackled, there is a process to workaround
importing big projects, using a foreground import:
-[Foreground import](https://gitlab.com/gitlab-com/gl-infra/infrastructure/issues/5384) of big projects for customers.
+[Foreground import](https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues/5384) of big projects for customers.
(Using the import template in the [infrastructure tracker](https://gitlab.com/gitlab-com/gl-infra/infrastructure/))
## Security
The Import/Export feature is constantly updated (adding new things to export), however
the code hasn't been refactored in a long time. We should perform a code audit (see
-[confidential issue](../user/project/issues/confidential_issues.md) `https://gitlab.com/gitlab-org/gitlab/issues/20720`).
+[confidential issue](../user/project/issues/confidential_issues.md) `https://gitlab.com/gitlab-org/gitlab/-/issues/20720`).
to make sure its dynamic nature does not increase the number of security concerns.
### Security in the code
@@ -192,20 +207,8 @@ module Gitlab
## Version history
-The [current version history](../user/project/settings/import_export.md) also displays the equivalent GitLab version
-and it is useful for knowing which versions won't be compatible between them.
-
-| Exporting GitLab version | Importing GitLab version |
-| -------------------------- | -------------------------- |
-| 11.7 to current | 11.7 to current |
-| 11.1 to 11.6 | 11.1 to 11.6 |
-| 10.8 to 11.0 | 10.8 to 11.0 |
-| 10.4 to 10.7 | 10.4 to 10.7 |
-| ... | ... |
-| 8.10.3 to 8.11 | 8.10.3 to 8.11 |
-| 8.10.0 to 8.10.2 | 8.10.0 to 8.10.2 |
-| 8.9.5 to 8.9.11 | 8.9.5 to 8.9.11 |
-| 8.9.0 to 8.9.4 | 8.9.0 to 8.9.4 |
+Check the [version history](../user/project/settings/import_export.md#version-history)
+for compatibility when importing and exporting projects.
### When to bump the version up
diff --git a/doc/development/insert_into_tables_in_batches.md b/doc/development/insert_into_tables_in_batches.md
index e5c4dc6ee56..d8919789808 100644
--- a/doc/development/insert_into_tables_in_batches.md
+++ b/doc/development/insert_into_tables_in_batches.md
@@ -187,8 +187,6 @@ There are a few restrictions to how these APIs can be used:
- `BulkInsertableAssociations`:
- It is currently only compatible with `has_many` relations.
- It does not yet support `has_many through: ...` relations.
-- Writing [`jsonb`](https://www.postgresql.org/docs/current/datatype-json.html) content is
-[not currently supported](https://gitlab.com/gitlab-org/gitlab/-/issues/210560).
Moreover, input data should either be limited to around 1000 records at most,
or already batched prior to calling bulk insert. The `INSERT` statement will run in a single
diff --git a/doc/development/instrumentation.md b/doc/development/instrumentation.md
index d72e1c6635e..ee1aab1456e 100644
--- a/doc/development/instrumentation.md
+++ b/doc/development/instrumentation.md
@@ -119,9 +119,9 @@ without measuring anything.
Three values are measured for a block:
-- The real time elapsed, stored in NAME_real_time.
-- The CPU time elapsed, stored in NAME_cpu_time.
-- The call count, stored in NAME_call_count.
+- The real time elapsed, stored in `NAME_real_time`.
+- The CPU time elapsed, stored in `NAME_cpu_time`.
+- The call count, stored in `NAME_call_count`.
Both the real and CPU timings are measured in milliseconds.
diff --git a/doc/development/integrations/jenkins.md b/doc/development/integrations/jenkins.md
index 001d1c21fd3..f2bc6532dde 100644
--- a/doc/development/integrations/jenkins.md
+++ b/doc/development/integrations/jenkins.md
@@ -1,6 +1,6 @@
# How to run Jenkins in development environment (on macOS) **(STARTER)**
-This is a step by step guide on how to set up [Jenkins](https://jenkins.io/) on your local machine and connect to it from your GitLab instance. GitLab triggers webhooks on Jenkins, and Jenkins connects to GitLab using the API. By running both applications on the same machine, we can make sure they are able to access each other.
+This is a step by step guide on how to set up [Jenkins](https://www.jenkins.io/) on your local machine and connect to it from your GitLab instance. GitLab triggers webhooks on Jenkins, and Jenkins connects to GitLab using the API. By running both applications on the same machine, we can make sure they are able to access each other.
## Install Jenkins
diff --git a/doc/development/integrations/secure.md b/doc/development/integrations/secure.md
index b0e1e28ba8b..1737daae0e0 100644
--- a/doc/development/integrations/secure.md
+++ b/doc/development/integrations/secure.md
@@ -15,7 +15,7 @@ scanner, as well as requirements and guidelines for the Docker image.
## Job definition
-This section desribes several important fields to add to the security scanner's job
+This section describes several important fields to add to the security scanner's job
definition file. Full documentation on these and other available fields can be viewed
in the [CI documentation](../../ci/yaml/README.md#image).
@@ -69,7 +69,7 @@ For example, here is the definition of a SAST job that generates a file named `g
and uploads it as a SAST report:
```yaml
-mysec_sast_scanning:
+mysec_sast:
image: registry.gitlab.com/secure/mysec
artifacts:
reports:
@@ -89,9 +89,9 @@ for variables such as `DEPENDENCY_SCANNING_DISABLED`, `CONTAINER_SCANNING_DISABL
disable running the custom scanner.
GitLab also defines a `CI_PROJECT_REPOSITORY_LANGUAGES` variable, which provides the list of
-languages in the repo. Depending on this value, your scanner may or may not do something different.
+languages in the repository. Depending on this value, your scanner may or may not do something different.
Language detection currently relies on the [`linguist`](https://github.com/github/linguist) Ruby gem.
-See [GitLab CI/CD prefined variables](../../ci/variables/predefined_variables.md#variables-reference).
+See [GitLab CI/CD predefined variables](../../ci/variables/predefined_variables.md).
#### Policy checking example
@@ -124,9 +124,9 @@ regardless of the individual machine the scanner runs on.
Depending on the CI infrastructure,
the CI may have to fetch the Docker image every time the job runs.
-To make the scanning job run fast, and to avoid wasting bandwidth,
-it is important to make Docker images as small as possible,
-ideally smaller than 50 MB.
+For the scanning job to run fast and avoid wasting bandwidth, Docker images should be as small as
+possible. You should aim for 50MB or smaller. If that isn't possible, try to keep it below 1.46 GB,
+which is the size of a CD-ROM.
If the scanner requires a fully functional Linux environment,
it is recommended to use a [Debian](https://www.debian.org/intro/about) "slim" distribution or [Alpine Linux](https://www.alpinelinux.org/).
@@ -135,11 +135,27 @@ and to compile the scanner with all the libraries it needs.
[Multi-stage builds](https://docs.docker.com/develop/develop-images/multistage-build/)
might also help with keeping the image small.
+To keep an image size small, consider using [dive](https://github.com/wagoodman/dive#dive) to analyze layers in a Docker image to
+identify where additional bloat might be originating from.
+
+In some cases, it might be difficult to remove files from an image. When this occurs, consider using
+[Zstandard](https://github.com/facebook/zstd)
+to compress files or large directories. Zstandard offers many different compression levels that can
+decrease the size of your image with very little impact to decompression speed. It may be helpful to
+automatically decompress any compressed directories as soon as an image launches. You can accomplish
+this by adding a step to the Docker image's `/etc/bashrc` or to a specific user's `$HOME/.bashrc`.
+Remember to change the entry point to launch a bash login shell if you chose the latter option.
+
+Here are some examples to get you started:
+
+- <https://gitlab.com/gitlab-org/security-products/license-management/-/blob/0b976fcffe0a9b8e80587adb076bcdf279c9331c/config/install.sh#L168-170>
+- <https://gitlab.com/gitlab-org/security-products/license-management/-/blob/0b976fcffe0a9b8e80587adb076bcdf279c9331c/config/.bashrc#L49>
+
### Image tag
As documented in the [Docker Official Images](https://github.com/docker-library/official-images#tags-and-aliases) project,
it is strongly encouraged that version number tags be given aliases which allows the user to easily refer to the "most recent" release of a particular series.
-See also [Docker Tagging: Best practices for tagging and versioning docker images](https://docs.microsoft.com/en-us/archive/blogs/stevelasker/docker-tagging-best-practices-for-tagging-and-versioning-docker-images).
+See also [Docker Tagging: Best practices for tagging and versioning Docker images](https://docs.microsoft.com/en-us/archive/blogs/stevelasker/docker-tagging-best-practices-for-tagging-and-versioning-docker-images).
## Command line
@@ -448,7 +464,7 @@ Right now, GitLab cannot track a vulnerability if its location changes
as new Git commits are pushed, and this results in user feedback being lost.
For instance, user feedback on a SAST vulnerability is lost
if the affected file is renamed or the affected line moves down.
-This is addressed in [issue #7586](https://gitlab.com/gitlab-org/gitlab/issues/7586).
+This is addressed in [issue #7586](https://gitlab.com/gitlab-org/gitlab/-/issues/7586).
In some cases, the multiple scans executed in the same CI pipeline result in duplicates
that are automatically merged using the vulnerability location and identifiers.
@@ -470,6 +486,10 @@ The confidence ranges from `Low` to `Confirmed`, but it can also be `Unknown`,
`Experimental` or even `Ignore` if the vulnerability is to be ignored.
Valid values are: `Ignore`, `Unknown`, `Experimental`, `Low`, `Medium`, `High`, or `Confirmed`
+`Unknown` values means that data is unavailable to determine it's actual value. Therefore, it may be `high`, `medium`, or `low`,
+and needs to be investigated. We have [provided a chart](../../user/application_security/sast/analyzers.md#analyzers-data)
+of the available SAST Analyzers and what data is currently available.
+
### Remediations
The `remediations` field of the report is an array of remediation objects.
diff --git a/doc/development/integrations/secure_partner_integration.md b/doc/development/integrations/secure_partner_integration.md
index 59336b0e6a1..22e1f8bf769 100644
--- a/doc/development/integrations/secure_partner_integration.md
+++ b/doc/development/integrations/secure_partner_integration.md
@@ -28,7 +28,7 @@ best place to integrate your own product and its results into GitLab.
implications for app security, corporate policy, or compliance. When complete,
the job reports back on its status and creates a
[job artifact](../../user/project/pipelines/job_artifacts.md) as a result.
-- The [Merge Request Security Widget](../../user/project/merge_requests/index.md#security-reports-ultimate)
+- The [Merge Request Security Widget](../../user/project/merge_requests/testing_and_reports_in_merge_requests.md#security-reports-ultimate)
displays the results of the pipeline's security checks and the developer can
review them. The developer can review both a summary and a detailed version
of the results.
@@ -54,10 +54,10 @@ best place to integrate your own product and its results into GitLab.
## How to onboard
This section describes the steps you need to complete to onboard as a partner
-and complete an intgration with the Secure stage.
+and complete an integration with the Secure stage.
1. Read about our [partnerships](https://about.gitlab.com/partners/integrate/).
-1. [Create an issue](https://gitlab.com/gitlab-com/alliances/alliances/issues/new?issuable_template=new_partner)
+1. [Create an issue](https://gitlab.com/gitlab-com/alliances/alliances/-/issues/new?issuable_template=new_partner)
using our new partner issue template to begin the discussion.
1. Get a test account to begin developing your integration. You can
request a [GitLab.com Gold Subscription Sandbox](https://about.gitlab.com/partners/integrate/#gitlabcom-gold-subscription-sandbox-request)
@@ -76,10 +76,10 @@ and complete an intgration with the Secure stage.
- Documentation for [Dependency Scanning reports](../../user/application_security/dependency_scanning/index.md#reports-json-format).
- Documentation for [Container Scanning reports](../../user/application_security/container_scanning/index.md#reports-json-format).
- See this [example secure job definition that also defines the artifact created](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml).
- - If you need a new kind of scan or report, [create an issue](https://gitlab.com/gitlab-org/gitlab/issues/new#)
+ - If you need a new kind of scan or report, [create an issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new#)
and add the label `devops::secure`.
- Once the job is completed, the data can be seen:
- - In the [Merge Request Security Report](../../user/project/merge_requests/index.md#security-reports-ultimate) ([MR Security Report data flow](https://gitlab.com/snippets/1910005#merge-request-view)).
+ - In the [Merge Request Security Report](../../user/project/merge_requests/testing_and_reports_in_merge_requests.md#security-reports-ultimate) ([MR Security Report data flow](https://gitlab.com/snippets/1910005#merge-request-view)).
- While [browsing a Job Artifact](../../user/project/pipelines/job_artifacts.md).
- In the [Security Dashboard](../../user/application_security/security_dashboard/index.md) ([Dashboard data flow](https://gitlab.com/snippets/1910005#project-and-group-dashboards)).
1. Optional: Provide a way to interact with results as Vulnerabilities:
@@ -99,5 +99,9 @@ and complete an intgration with the Secure stage.
doing an [Unfiltered blog post](https://about.gitlab.com/handbook/marketing/blog/unfiltered/),
doing a co-branded webinar, or producing a co-branded whitepaper.
+We have a [video playlist](https://www.youtube.com/playlist?list=PL05JrBw4t0KpMqYxJiOLz-uBIr5w-yP4A)
+that may be helpful as part of this process. This covers various topics related to integrating your
+tool.
+
If you have any issues while working through your integration or the steps
above, please create an issue to discuss with us further.
diff --git a/doc/development/internal_api.md b/doc/development/internal_api.md
index 5b53f223eb0..d220a2d46fb 100644
--- a/doc/development/internal_api.md
+++ b/doc/development/internal_api.md
@@ -43,11 +43,11 @@ POST /internal/allowed
| `key_id` | string | no | ID of the SSH-key used to connect to GitLab-shell |
| `username` | string | no | Username from the certificate used to connect to GitLab-Shell |
| `project` | string | no (if `gl_repository` is passed) | Path to the project |
-| `gl_repository` | string | no (if `project` is passed) | Path to the project |
+| `gl_repository` | string | no (if `project` is passed) | Repository identifier (e.g. `project-7`) |
| `protocol` | string | yes | SSH when called from GitLab-shell, HTTP or SSH when called from Gitaly |
| `action` | string | yes | Git command being run (`git-upload-pack`, `git-receive-pack`, `git-upload-archive`) |
| `changes` | string | yes | `<oldrev> <newrev> <refname>` when called from Gitaly, The magic string `_any` when called from GitLab Shell |
-| `check_ip` | string | no | Ip address from which call to GitLab Shell was made |
+| `check_ip` | string | no | IP address from which call to GitLab Shell was made |
Example request:
diff --git a/doc/development/issue_types.md b/doc/development/issue_types.md
index bcd3980c298..028d42b27fc 100644
--- a/doc/development/issue_types.md
+++ b/doc/development/issue_types.md
@@ -5,9 +5,9 @@ Sometimes when a new resource type is added it's not clear if it should be only
(similar to Issue, Epic, Merge Request, Snippet).
The idea of Issue Types was first proposed in [this
-issue](https://gitlab.com/gitlab-org/gitlab/issues/8767) and its usage was
+issue](https://gitlab.com/gitlab-org/gitlab/-/issues/8767) and its usage was
discussed few times since then, for example in [incident
-management](https://gitlab.com/gitlab-org/gitlab-foss/issues/55532).
+management](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/55532).
## What is an Issue Type
diff --git a/doc/development/licensing.md b/doc/development/licensing.md
index e1be1faa61b..f92151e7a37 100644
--- a/doc/development/licensing.md
+++ b/doc/development/licensing.md
@@ -12,6 +12,8 @@ Some gems may not include their license information in their `gemspec` file, and
### License Finder commands
+> Note: License Finder currently uses GitLab misused terms of whitelist and blacklist. As a result, the commands below references those terms. We've created an [issue on their project](https://github.com/pivotal/LicenseFinder/issues/745) to propose that they rename their commands.
+
There are a few basic commands License Finder provides that you'll need in order to manage license detection.
To verify that the checks are passing, and/or to see what dependencies are causing the checks to fail:
@@ -20,16 +22,16 @@ To verify that the checks are passing, and/or to see what dependencies are causi
bundle exec license_finder
```
-To whitelist a new license:
+To allowlist a new license:
```shell
license_finder whitelist add MIT
```
-To blacklist a new license:
+To denylist a new license:
```shell
-license_finder blacklist add GPLv2
+license_finder blacklist add Unlicense
```
To tell License Finder about a dependency's license if it isn't auto-detected:
diff --git a/doc/development/logging.md b/doc/development/logging.md
index e7d48e4d278..ccd4adf7cef 100644
--- a/doc/development/logging.md
+++ b/doc/development/logging.md
@@ -284,7 +284,7 @@ creating visualizations in Kibana.
**Note:**
The fields of the context are currently only logged for Sidekiq jobs triggered
through web requests. See the
-[follow-up work](https://gitlab.com/gitlab-com/gl-infra/scalability/issues/68)
+[follow-up work](https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/68)
for more information.
## Exception Handling
@@ -358,8 +358,8 @@ end
for most users, but you may need to tweak them in [Omnibus GitLab](https://gitlab.com/gitlab-org/omnibus-gitlab).
1. If you add a new file, submit an issue to the [production
- tracker](https://gitlab.com/gitlab-com/gl-infra/production/issues) or
- a merge request to the [gitlab_fluentd](https://gitlab.com/gitlab-cookbooks/gitlab_fluentd)
+ tracker](https://gitlab.com/gitlab-com/gl-infra/production/-/issues) or
+ a merge request to the [`gitlab_fluentd`](https://gitlab.com/gitlab-cookbooks/gitlab_fluentd)
project. See [this example](https://gitlab.com/gitlab-cookbooks/gitlab_fluentd/-/merge_requests/51/diffs).
1. Be sure to update the [GitLab CE/EE documentation](../administration/logs.md) and the [GitLab.com
diff --git a/doc/development/merge_request_performance_guidelines.md b/doc/development/merge_request_performance_guidelines.md
index b51fc681e27..ed6d08a9894 100644
--- a/doc/development/merge_request_performance_guidelines.md
+++ b/doc/development/merge_request_performance_guidelines.md
@@ -193,7 +193,7 @@ in Puma/Unicorn threads.
Often, GitLab needs to communicate with an external service such as Kubernetes
clusters. In this case, it's hard to estimate when the external service finishes
the requested process, for example, if it's a user-owned cluster that's inactive for some reason,
-GitLab might wait for the response forever ([Example](https://gitlab.com/gitlab-org/gitlab/issues/31475)).
+GitLab might wait for the response forever ([Example](https://gitlab.com/gitlab-org/gitlab/-/issues/31475)).
This could result in Puma/Unicorn timeout and should be avoided at all cost.
You should set a reasonable timeout, gracefully handle exceptions and surface the
@@ -210,7 +210,7 @@ as an open transaction basically blocks the release of a PostgreSQL backend conn
For keeping transaction as minimal as possible, please consider using `AfterCommitQueue`
module or `after_commit` AR hook.
-Here is [an example](https://gitlab.com/gitlab-org/gitlab/issues/36154#note_247228859)
+Here is [an example](https://gitlab.com/gitlab-org/gitlab/-/issues/36154#note_247228859)
that one request to Gitaly instance during transaction triggered a P1 issue.
## Eager Loading
diff --git a/doc/development/migration_style_guide.md b/doc/development/migration_style_guide.md
index 4cf546173de..7d3d9dac174 100644
--- a/doc/development/migration_style_guide.md
+++ b/doc/development/migration_style_guide.md
@@ -35,7 +35,7 @@ and post-deployment migrations (`db/post_migrate`) are run after the deployment
## Schema Changes
-Changes to the schema should be commited to `db/structure.sql`. This
+Changes to the schema should be committed to `db/structure.sql`. This
file is automatically generated by Rails, so you normally should not
edit this file by hand. If your migration is adding a column to a
table, that column will be added at the bottom. Please do not reorder
@@ -49,7 +49,7 @@ regenerate a clean `db/structure.sql` for the migrations you're
adding. This script will apply all migrations found in `db/migrate`
or `db/post_migrate`, so if there are any migrations you don't want to
commit to the schema, rename or remove them. If your branch is not
-targetting `master` you can set the `TARGET` environment variable.
+targeting `master` you can set the `TARGET` environment variable.
```shell
# Regenerate schema against `master`
@@ -343,7 +343,7 @@ def up
end
```
-The RuboCop rule generally allows standard Rails migration methods, listed below. This example will cause a rubocop offense:
+The RuboCop rule generally allows standard Rails migration methods, listed below. This example will cause a Rubocop offense:
```ruby
disabled_ddl_transaction!
@@ -367,6 +367,8 @@ migration involves one of the high-traffic tables:
- `users`
- `projects`
- `namespaces`
+- `issues`
+- `merge_requests`
- `ci_pipelines`
- `ci_builds`
- `notes`
@@ -550,6 +552,12 @@ operations that don't require `disable_ddl_transaction!`.
You can read more about adding [foreign key constraints to an existing column](database/add_foreign_key_to_existing_column.md).
+## `NOT NULL` constraints
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/38358) in GitLab 13.0.
+
+See the style guide on [`NOT NULL` constraints](database/not_null_constraints.md) for more information.
+
## Adding Columns With Default Values
With PostgreSQL 11 being the minimum version since GitLab 13.0, adding columns with default values has become much easier and
@@ -559,6 +567,11 @@ Before PostgreSQL 11, adding a column with a default was problematic as it would
have caused a full table rewrite. The corresponding helper `add_column_with_default`
has been deprecated and will be removed in a later release.
+NOTE: **Note:**
+If a backport adding a column with a default value is needed for %12.9 or earlier versions,
+it should use `add_column_with_default` helper. If a [large table](https://gitlab.com/gitlab-org/gitlab/-/blob/master/rubocop/rubocop-migrations.yml#L3)
+is involved, backporting to %12.9 is contraindicated.
+
## Changing the column default
One might think that changing a default column with `change_column_default` is an
@@ -611,7 +624,7 @@ end
```
If a computed update is needed, the value can be wrapped in `Arel.sql`, so Arel
-treats it as an SQL literal. It's also a required deprecation for [Rails 6](https://gitlab.com/gitlab-org/gitlab/issues/28497).
+treats it as an SQL literal. It's also a required deprecation for [Rails 6](https://gitlab.com/gitlab-org/gitlab/-/issues/28497).
The below example is the same as the one above, but
the value is set to the product of the `bar` and `baz` columns:
@@ -727,6 +740,12 @@ Rails migration example:
add_column(:projects, :foo, :integer, default: 10, limit: 8)
```
+## Strings and the Text data type
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30453) in GitLab 13.0.
+
+See the [text data type](database/strings_and_the_text_data_type.md) style guide for more information.
+
## Timestamp column type
By default, Rails uses the `timestamp` data type that stores timestamp data
diff --git a/doc/development/module_with_instance_variables.md b/doc/development/module_with_instance_variables.md
index b0eab95190b..2229c99c99b 100644
--- a/doc/development/module_with_instance_variables.md
+++ b/doc/development/module_with_instance_variables.md
@@ -30,11 +30,11 @@ People are saying multiple inheritance is bad. Mixing multiple modules with
multiple instance variables scattering everywhere suffer from the same issue.
The same applies to `ActiveSupport::Concern`. See:
[Consider replacing concerns with dedicated classes & composition](
-https://gitlab.com/gitlab-org/gitlab/issues/16270)
+https://gitlab.com/gitlab-org/gitlab/-/issues/16270)
There's also a similar idea:
[Use decorators and interface segregation to solve overgrowing models problem](
-https://gitlab.com/gitlab-org/gitlab/issues/14235)
+https://gitlab.com/gitlab-org/gitlab/-/issues/14235)
Note that `included` doesn't solve the whole issue. They define the
dependencies, but they still allow each modules to talk implicitly via the
diff --git a/doc/development/multi_version_compatibility.md b/doc/development/multi_version_compatibility.md
index aedd5c1ffb7..001517d44ea 100644
--- a/doc/development/multi_version_compatibility.md
+++ b/doc/development/multi_version_compatibility.md
@@ -45,7 +45,7 @@ and set this column to `false`. The old servers were still updating the old colu
that updated the new column from the old one. For the new servers though, they were only updating the new column and that same trigger
was now working against us and setting it back to the wrong value.
-For more information, see [the relevant issue](https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues/9176).
+For more information, see this [confidential issue](../user/project/issues/confidential_issues.md) `https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues/9176`.
### Sidebar wasn't loading for some users
diff --git a/doc/development/namespaces_storage_statistics.md b/doc/development/namespaces_storage_statistics.md
index 3065d4f84a2..5207276ba73 100644
--- a/doc/development/namespaces_storage_statistics.md
+++ b/doc/development/namespaces_storage_statistics.md
@@ -25,7 +25,7 @@ by [`Namespaces#with_statistics`](https://gitlab.com/gitlab-org/gitlab/blob/4ab5
Additionally, the pattern that is currently used to update the project statistics
(the callback) doesn't scale adequately. It is currently one of the largest
-[database queries transactions on production](https://gitlab.com/gitlab-org/gitlab/issues/29070)
+[database queries transactions on production](https://gitlab.com/gitlab-org/gitlab/-/issues/29070)
that takes the most time overall. We can't add one more query to it as
it will increase the transaction's length.
@@ -142,7 +142,7 @@ but we refresh them through Sidekiq jobs and in different transactions:
1. Create a second table (`namespace_aggregation_schedules`) with two columns `id` and `namespace_id`.
1. Whenever the statistics of a project changes, insert a row into `namespace_aggregation_schedules`
- We don't insert a new row if there's already one related to the root namespace.
- - Keeping in mind the length of the transaction that involves updating `project_statistics`(<https://gitlab.com/gitlab-org/gitlab/issues/29070>), the insertion should be done in a different transaction and through a Sidekiq Job.
+ - Keeping in mind the length of the transaction that involves updating `project_statistics`(<https://gitlab.com/gitlab-org/gitlab/-/issues/29070>), the insertion should be done in a different transaction and through a Sidekiq Job.
1. After inserting the row, we schedule another worker to be executed async at two different moments:
- One enqueued for immediate execution and another one scheduled in `1.5h` hours.
- We only schedule the jobs, if we can obtain a `1.5h` lease on Redis on a key based on the root namespace ID.
@@ -162,7 +162,7 @@ This implementation has the following benefits:
The only downside of this approach is that namespaces' statistics are updated up to `1.5` hours after the change is done,
which means there's a time window in which the statistics are inaccurate. Because we're still not
-[enforcing storage limits](https://gitlab.com/gitlab-org/gitlab/issues/17664), this is not a major problem.
+[enforcing storage limits](https://gitlab.com/gitlab-org/gitlab/-/issues/17664), this is not a major problem.
## Conclusion
@@ -171,8 +171,8 @@ performant approach of aggregating the root namespaces.
All the details regarding this use case can be found on:
-- <https://gitlab.com/gitlab-org/gitlab-foss/issues/62214>
+- <https://gitlab.com/gitlab-org/gitlab-foss/-/issues/62214>
- Merge Request with the implementation: <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/28996>
Performance of the namespace storage statistics were measured in staging and production (GitLab.com). All results were posted
-on <https://gitlab.com/gitlab-org/gitlab-foss/issues/64092>: No problem has been reported so far.
+on <https://gitlab.com/gitlab-org/gitlab-foss/-/issues/64092>: No problem has been reported so far.
diff --git a/doc/development/new_fe_guide/development/accessibility.md b/doc/development/new_fe_guide/development/accessibility.md
index aa76a9fec07..f76fd72d4dc 100644
--- a/doc/development/new_fe_guide/development/accessibility.md
+++ b/doc/development/new_fe_guide/development/accessibility.md
@@ -1,4 +1,4 @@
-# Accessiblity
+# Accessibility
Using semantic HTML plays a key role when it comes to accessibility.
@@ -37,7 +37,7 @@ In forms we should use the `for` attribute in the label statement:
## Testing
1. On MacOS you can use [VoiceOver](https://www.apple.com/accessibility/mac/vision/) by pressing `cmd+F5`.
-1. On Windows you can use [Narrator](https://www.microsoft.com/en-us/accessibility/windows) by pressing Windows logo key + Ctrl + Enter.
+1. On Windows you can use [Narrator](https://www.microsoft.com/en-us/accessibility/windows) by pressing Windows logo key + Control + Enter.
## Online resources
diff --git a/doc/development/new_fe_guide/development/performance.md b/doc/development/new_fe_guide/development/performance.md
index 4a85c04d8cf..7b58a80576a 100644
--- a/doc/development/new_fe_guide/development/performance.md
+++ b/doc/development/new_fe_guide/development/performance.md
@@ -5,11 +5,11 @@
We have a performance dashboard available in one of our [Grafana instances](https://dashboards.gitlab.net/d/1EBTz3Dmz/sitespeed-page-summary?orgId=1). This dashboard automatically aggregates metric data from [sitespeed.io](https://www.sitespeed.io/) every 6 hours. These changes are displayed after a set number of pages are aggregated.
These pages can be found inside a text file in the [`gitlab-build-images` repository](https://gitlab.com/gitlab-org/gitlab-build-images) called [`gitlab.txt`](https://gitlab.com/gitlab-org/gitlab-build-images/blob/master/scripts/gitlab.txt)
-Any frontend engineer can contribute to this dashboard. They can contribute by adding or removing urls of pages from this text file. Please have a [frontend monitoring expert](https://about.gitlab.com/company/team/) review your changes before assigning to a maintainer of the `gitlab-build-images` project. The changes will go live on the next scheduled run after the changes are merged into `master`.
+Any frontend engineer can contribute to this dashboard. They can contribute by adding or removing URLs of pages from this text file. Please have a [frontend monitoring expert](https://about.gitlab.com/company/team/) review your changes before assigning to a maintainer of the `gitlab-build-images` project. The changes will go live on the next scheduled run after the changes are merged into `master`.
There are 3 recommended high impact metrics to review on each page:
-- [First visual change](https://developers.google.com/web/tools/lighthouse/audits/first-meaningful-paint)
+- [First visual change](https://web.dev/first-meaningful-paint/)
- [Speed Index](https://sites.google.com/a/webpagetest.org/docs/using-webpagetest/metrics/speed-index)
- [Visual Complete 95%](https://sites.google.com/a/webpagetest.org/docs/using-webpagetest/metrics/speed-index)
diff --git a/doc/development/omnibus.md b/doc/development/omnibus.md
index 28ca500f21a..deaf72d2ecf 100644
--- a/doc/development/omnibus.md
+++ b/doc/development/omnibus.md
@@ -24,7 +24,7 @@ and write it to the Rails root. In the Omnibus packages, reconfigure writes the
The Omnibus design separates code (read-only, under `/opt/gitlab`) from data
(read/write, under `/var/opt/gitlab`) and logs (read/write, under
`/var/log/gitlab`). To make this happen the reconfigure script sets custom
-paths where it can in GitLab config files, and where there are no path
+paths where it can in GitLab configuration files, and where there are no path
settings, it uses symlinks.
For example, `config/gitlab.yml` is treated as data so that file is a symlink.
diff --git a/doc/development/packages.md b/doc/development/packages.md
index 11fc3faf4ab..edf01255e84 100644
--- a/doc/development/packages.md
+++ b/doc/development/packages.md
@@ -10,7 +10,7 @@ not cover the way the code should be written. However, you can find a good examp
by looking at merge requests with Maven and NPM support:
- [NPM registry support](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/8673).
-- [Conan repository](https://gitlab.com/gitlab-org/gitlab/issues/8248).
+- [Conan repository](https://gitlab.com/gitlab-org/gitlab/-/issues/8248).
- [Maven repository](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/6607).
- [Instance level endpoint for Maven repository](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/8757)
@@ -61,15 +61,19 @@ The current state of existing package registries availability is:
| Repository Type | Project Level | Group Level | Instance Level |
|-----------------|---------------|-------------|----------------|
| Maven | Yes | Yes | Yes |
-| Conan | No - [open issue](https://gitlab.com/gitlab-org/gitlab/issues/11679) | No - [open issue](https://gitlab.com/gitlab-org/gitlab/issues/11679) | Yes |
-| NPM | No - [open issue](https://gitlab.com/gitlab-org/gitlab/issues/36853) | Yes | No - [open issue](https://gitlab.com/gitlab-org/gitlab/issues/36853) |
+| Conan | No - [open issue](https://gitlab.com/gitlab-org/gitlab/-/issues/11679) | No - [open issue](https://gitlab.com/gitlab-org/gitlab/-/issues/11679) | Yes |
+| NPM | No - [open issue](https://gitlab.com/gitlab-org/gitlab/-/issues/36853) | Yes | No - [open issue](https://gitlab.com/gitlab-org/gitlab/-/issues/36853) |
| NuGet | Yes | No - [open issue](https://gitlab.com/gitlab-org/gitlab/-/issues/36423) | No |
| PyPI | Yes | No | No |
+| Go | Yes | No - [open issue](https://gitlab.com/gitlab-org/gitlab/-/issues/213900) | No - [open-issue](https://gitlab.com/gitlab-org/gitlab/-/issues/213902) |
+| Composer | Yes | Yes | No |
NOTE: **Note:** NPM is currently a hybrid of the instance level and group level.
It is using the top-level group or namespace as the defining portion of the name
(for example, `@my-group-name/my-package-name`).
+**Note:** Composer package naming scope is Instance Level.
+
### Naming conventions
To avoid name conflict for instance-level endpoints you will need to define a package naming convention
diff --git a/doc/development/performance.md b/doc/development/performance.md
index 2e73161a11f..69ad524675d 100644
--- a/doc/development/performance.md
+++ b/doc/development/performance.md
@@ -8,7 +8,7 @@ consistent performance of GitLab.
The process of solving performance problems is roughly as follows:
1. Make sure there's an issue open somewhere (for example, on the GitLab CE issue
- tracker), and create one if there is not. See [#15607](https://gitlab.com/gitlab-org/gitlab-foss/issues/15607) for an example.
+ tracker), and create one if there is not. See [#15607](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/15607) for an example.
1. Measure the performance of the code in a production environment such as
GitLab.com (see the [Tooling](#tooling) section below). Performance should be
measured over a period of _at least_ 24 hours.
@@ -42,6 +42,7 @@ GitLab provides built-in tools to help improve performance and availability:
- [Request Profiling](../administration/monitoring/performance/request_profiling.md).
- [QueryRecoder](query_recorder.md) for preventing `N+1` regressions.
- [Chaos endpoints](chaos_endpoints.md) for testing failure scenarios. Intended mainly for testing availability.
+- [Service measurement](service_measurement.md) for measuring and logging service execution.
GitLab team members can use [GitLab.com's performance monitoring systems](https://about.gitlab.com/handbook/engineering/monitoring/) located at
<https://dashboards.gitlab.net>, this requires you to log in using your
diff --git a/doc/development/permissions.md b/doc/development/permissions.md
index 0772389bf9e..06a4a03de38 100644
--- a/doc/development/permissions.md
+++ b/doc/development/permissions.md
@@ -14,7 +14,7 @@ Groups and projects can have the following visibility levels:
- private (`0`) - an entity is visible only to the approved members of the entity
The visibility level of a group can be changed only if all subgroups and
-subprojects have the same or lower visibility level. (e.g., a group can be set
+sub-projects have the same or lower visibility level. (e.g., a group can be set
to internal only if all subgroups and projects are internal or private).
Visibility levels can be found in the `Gitlab::VisibilityLevel` module.
@@ -41,11 +41,12 @@ can be accessed only by project members by default.
Users can be members of multiple groups and projects. The following access
levels are available (defined in the `Gitlab::Access` module):
-- Guest
-- Reporter
-- Developer
-- Maintainer
-- Owner
+- No access (`0`)
+- Guest (`10`)
+- Reporter (`20`)
+- Developer (`30`)
+- Maintainer (`40`)
+- Owner (`50`)
If a user is the member of both a project and the project parent group, the
higher permission is taken into account for the project.
@@ -56,6 +57,12 @@ can still view the groups and their entities (like epics).
Project membership (where the group membership is already taken into account)
is stored in the `project_authorizations` table.
+CAUTION: **Caution:**
+Due to [an issue](https://gitlab.com/gitlab-org/gitlab/-/issues/219299),
+projects in personal namespace will not show owner (`50`) permission in
+`project_authorizations` table. Note however that [`user.owned_projects`](https://gitlab.com/gitlab-org/gitlab/blob/0d63823b122b11abd2492bca47cc26858eee713d/app/models/user.rb#L906-916)
+is calculated properly.
+
### Confidential issues
Confidential issues can be accessed only by project members who are at least
@@ -92,10 +99,10 @@ into different features like Merge Requests and CI flow.
| Activity level | Resource | Locations |Permission dependency|
|----------------|----------|-----------|-----|
-| View | License information | Dependency list, License Compliance | Can view repo |
-| View | Dependency information | Dependency list, License Compliance | Can view repo |
+| View | License information | Dependency list, License Compliance | Can view repository |
+| View | Dependency information | Dependency list, License Compliance | Can view repository |
| View | Vulnerabilities information | Dependency list | Can view security findings |
-| View | Black/Whitelisted licenses for the project | License Compliance, Merge request | Can view repo |
+| View | Black/Whitelisted licenses for the project | License Compliance, Merge request | Can view repository |
| View | Security findings | Merge Request, CI job page, Pipeline security tab | Can read the project and CI jobs |
| View | Vulnerability feedback | Merge Request | Can read security findings |
| View | Dependency List page | Project | Can access Dependency information |
diff --git a/doc/development/pipelines.md b/doc/development/pipelines.md
index 39ca846c1cc..05b80cdb4a6 100644
--- a/doc/development/pipelines.md
+++ b/doc/development/pipelines.md
@@ -11,173 +11,15 @@ We're striving to [dogfood](https://about.gitlab.com/handbook/engineering/#dogfo
GitLab [CI/CD features and best-practices](../ci/yaml/README.md)
as much as possible.
-## Stages
+## Overview
-The current stages are:
-
-- `sync`: This stage is used to synchronize changes from <https://gitlab.com/gitlab-org/gitlab> to
- <https://gitlab.com/gitlab-org/gitlab-foss>.
-- `prepare`: This stage includes jobs that prepare artifacts that are needed by
- jobs in subsequent stages.
-- `build-images`: This stage includes jobs that prepare docker images
- that are needed by jobs in subsequent stages or downstream pipelines.
-- `fixtures`: This stage includes jobs that prepare fixtures needed by frontend tests.
-- `test`: This stage includes most of the tests, DB/migration jobs, and static analysis jobs.
-- `post-test`: This stage includes jobs that build reports or gather data from
- the `test` stage's jobs (e.g. coverage, Knapsack metadata etc.).
-- `review-prepare`: This stage includes a job that build the CNG images that are
- later used by the (Helm) Review App deployment (see
- [Review Apps](testing_guide/review_apps.md) for details).
-- `review`: This stage includes jobs that deploy the GitLab and Docs Review Apps.
-- `qa`: This stage includes jobs that perform QA tasks against the Review App
- that is deployed in the previous stage.
-- `post-qa`: This stage includes jobs that build reports or gather data from
- the `qa` stage's jobs (e.g. Review App performance report).
-- `pages`: This stage includes a job that deploys the various reports as
- GitLab Pages (e.g. <https://gitlab-org.gitlab.io/gitlab/coverage-ruby/>,
- <https://gitlab-org.gitlab.io/gitlab/coverage-javascript/>,
- <https://gitlab-org.gitlab.io/gitlab/webpack-report/>).
-
-## Default image
-
-The default image is defined in <https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab-ci.yml>.
-
-It includes Ruby, Go, Git, Git LFS, Chrome, Node, Yarn, PostgreSQL, and Graphics Magick.
-
-The images used in our pipelines are configured in the
-[`gitlab-org/gitlab-build-images`](https://gitlab.com/gitlab-org/gitlab-build-images)
-project, which is push-mirrored to <https://dev.gitlab.org/gitlab/gitlab-build-images>
-for redundancy.
-
-The current version of the build images can be found in the
-["Used by GitLab section"](https://gitlab.com/gitlab-org/gitlab-build-images/blob/master/.gitlab-ci.yml).
-
-## Default variables
-
-In addition to the [predefined variables](../ci/variables/predefined_variables.md),
-each pipeline includes default variables defined in
-<https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab-ci.yml>.
-
-## Common job definitions
-
-Most of the jobs [extend from a few CI definitions](../ci/yaml/README.md#extends)
-defined in [`.gitlab/ci/global.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab/ci/global.gitlab-ci.yml)
-that are scoped to a single [configuration parameter](../ci/yaml/README.md#configuration-parameters).
-
-| Job definitions | Description |
-|------------------|-------------|
-| `.default-tags` | Ensures a job has the `gitlab-org` tag to ensure it's using our dedicated runners. |
-| `.default-retry` | Allows a job to [retry](../ci/yaml/README.md#retry) upon `unknown_failure`, `api_failure`, `runner_system_failure`, `job_execution_timeout`, or `stuck_or_timeout_failure`. |
-| `.default-before_script` | Allows a job to use a default `before_script` definition suitable for Ruby/Rails tasks that may need a database running (e.g. tests). |
-| `.default-cache` | Allows a job to use a default `cache` definition suitable for Ruby/Rails and frontend tasks. |
-| `.use-pg11` | Allows a job to use the `postgres:11.6` and `redis:alpine` services. |
-| `.use-pg11-ee` | Same as `.use-pg11` but also use the `docker.elastic.co/elasticsearch/elasticsearch:6.4.2` services. |
-| `.use-kaniko` | Allows a job to use the `kaniko` tool to build Docker images. |
-| `.as-if-foss` | Simulate the FOSS project by setting the `FOSS_ONLY='1'` environment variable. |
-
-## `workflow:rules`
-
-We're using the [`workflow:rules` keyword](../ci/yaml/README.md#workflowrules) to
-define default rules to determine whether or not a pipeline is created.
-
-These rules are defined in <https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab-ci.yml>
-and are as follows:
-
-1. If `$FORCE_GITLAB_CI` is set, create a pipeline.
-1. For merge requests, create a pipeline.
-1. For `master` branch, create a pipeline (this includes on schedules, pushes, merges, etc.).
-1. For tags, create a pipeline.
-1. If `$GITLAB_INTERNAL` isn't set, don't create a pipeline.
-1. For stable, auto-deploy, and security branches, create a pipeline.
-1. For any other cases (e.g. when pushing a branch with no MR for it), no pipeline is created.
-
-## `rules`, `if:` conditions and `changes:` patterns
-
-We're using the [`rules` keyword](../ci/yaml/README.md#rules) extensively.
-
-All `rules` definitions are defined in
-<https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/ci/rules.gitlab-ci.yml>,
-then included in individual jobs via [`extends`](../ci/yaml/README.md#extends).
-
-The `rules` definitions are composed of `if:` conditions and `changes:` patterns,
-which are also defined in
-<https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/ci/rules.gitlab-ci.yml>
-and included in `rules` definitions via [YAML anchors](../ci/yaml/README.md#anchors)
-
-### `if:` conditions
-
-| `if:` conditions | Description | Notes |
-|------------------|-------------|-------|
-| `if-not-canonical-namespace` | Matches if the project isn't in the canonical (`gitlab-org/`) or security (`gitlab-org/security`) namespace. | Use to create a job for forks (by using `when: on_success\|manual`), or **not** create a job for forks (by using `when: never`). |
-| `if-not-ee` | Matches if the project isn't EE (i.e. project name isn't `gitlab` or `gitlab-ee`). | Use to create a job only in the FOSS project (by using `when: on_success|manual`), or **not** create a job if the project is EE (by using `when: never`). |
-| `if-not-foss` | Matches if the project isn't FOSS (i.e. project name isn't `gitlab-foss`, `gitlab-ce`, or `gitlabhq`). | Use to create a job only in the EE project (by using `when: on_success|manual`), or **not** create a job if the project is FOSS (by using `when: never`). |
-| `if-default-refs` | Matches if the pipeline is for `master`, `/^[\d-]+-stable(-ee)?$/` (stable branches), `/^\d+-\d+-auto-deploy-\d+$/` (auto-deploy branches), `/^security\//` (security branches), merge requests, and tags. | Note that jobs won't be created for branches with this default configuration. |
-| `if-master-refs` | Matches if the current branch is `master`. | |
-| `if-master-or-tag` | Matches if the pipeline is for the `master` branch or for a tag. | |
-| `if-merge-request` | Matches if the pipeline is for a merge request. | |
-| `if-nightly-master-schedule` | Matches if the pipeline is for a `master` scheduled pipeline with `$NIGHTLY` set. | |
-| `if-dot-com-gitlab-org-schedule` | Limits jobs creation to scheduled pipelines for the `gitlab-org` group on GitLab.com. | |
-| `if-dot-com-gitlab-org-master` | Limits jobs creation to the `master` branch for the `gitlab-org` group on GitLab.com. | |
-| `if-dot-com-gitlab-org-merge-request` | Limits jobs creation to merge requests for the `gitlab-org` group on GitLab.com. | |
-| `if-dot-com-gitlab-org-and-security-tag` | Limits job creation to tags for the `gitlab-org` and `gitlab-org/security` groups on GitLab.com. | |
-| `if-dot-com-gitlab-org-and-security-merge-request` | Limit jobs creation to merge requests for the `gitlab-org` and `gitlab-org/security` groups on GitLab.com. | |
-| `if-dot-com-ee-schedule` | Limits jobs to scheduled pipelines for the `gitlab-org/gitlab` project on GitLab.com. | |
-| `if-cache-credentials-schedule` | Limits jobs to scheduled pipelines with the `$CI_REPO_CACHE_CREDENTIALS` variable set. | |
-
-### `changes:` patterns
-
-| `changes:` patterns | Description |
-|------------------------------|--------------------------------------------------------------------------|
-| `ci-patterns` | Only create job for CI config-related changes. |
-| `yaml-patterns` | Only create job for YAML-related changes. |
-| `docs-patterns` | Only create job for docs-related changes. |
-| `frontend-dependency-patterns` | Only create job when frontend dependencies are updated (i.e. `package.json`, and `yarn.lock`). changes. |
-| `frontend-patterns` | Only create job for frontend-related changes. |
-| `backstage-patterns` | Only create job for backstage-related changes (i.e. Danger, fixtures, RuboCop, specs). |
-| `code-patterns` | Only create job for code-related changes. |
-| `qa-patterns` | Only create job for QA-related changes. |
-| `code-backstage-patterns` | Combination of `code-patterns` and `backstage-patterns`. |
-| `code-qa-patterns` | Combination of `code-patterns` and `qa-patterns`. |
-| `code-backstage-qa-patterns` | Combination of `code-patterns`, `backstage-patterns`, and `qa-patterns`. |
-
-## Interruptible jobs pipelines
-
-By default, all jobs are [interruptible](../ci/yaml/README.md#interruptible), except the
-`dont-interrupt-me` job which runs automatically on `master`, and is `manual`
-otherwise.
-
-If you want a running pipeline to finish even if you push new commits to a merge
-request, be sure to start the `dont-interrupt-me` job before pushing.
-
-## PostgreSQL versions testing
-
-### Current versions testing
-
-| Where? | PostgreSQL version |
-| ------ | ------ |
-| MRs | 11 |
-| `master` (non-scheduled pipelines) | 11 |
-| 2-hourly scheduled pipelines | 11 |
-
-### Long-term plan
-
-We follow the [PostgreSQL versions shipped with Omnibus GitLab](https://docs.gitlab.com/omnibus/package-information/postgresql_versions.html):
-
-| PostgreSQL version | 12.10 (April 2020) | 13.0 (May 2020) | 13.1 (June 2020) | 13.2 (July 2020) | 13.3 (August 2020) | 13.4, 13.5 | 13.6 (November 2020) | 14.0 (May 2021?) |
-| ------ | ------------------ | --------------- | ---------------- | ---------------- | ------------------ | ------------ | -------------------- | ---------------- |
-| PG9.6 | MRs/`master`/`2-hour`/`nightly` | - | - | - | - | - | - | - |
-| PG10 | `nightly` | - | - | - | - | - | - | - |
-| PG11 | `master`/`2-hour` | MRs/`master`/`2-hour`/`nightly` | MRs/`master`/`2-hour`/`nightly` | MRs/`master`/`2-hour`/`nightly` | MRs/`master`/`2-hour`/`nightly` | MRs/`master`/`2-hour`/`nightly` | `nightly` | - |
-| PG12 | - | - | - | - | `master`/`2-hour` | `master`/`2-hour` | MRs/`master`/`2-hour`/`nightly` | `master`/`2-hour` |
-| PG13 | - | - | - | - | - | - | - | MRs/`master`/`2-hour`/`nightly` |
-
-## Pipeline types
+### Pipeline types
Since we use the [`rules:`](../ci/yaml/README.md#rules) and [`needs:`](../ci/yaml/README.md#needs) keywords extensively,
we have four main pipeline types which are described below. Note that an MR that includes multiple types of changes would
have a pipelines that include jobs from multiple types (e.g. a combination of docs-only and code-only pipelines).
-### Docs-only MR pipeline
+#### Docs-only MR pipeline
Reference pipeline: <https://gitlab.com/gitlab-org/gitlab/pipelines/135236627>
@@ -191,7 +33,7 @@ graph LR
end
```
-### Code-only MR pipeline
+#### Code-only MR pipeline
Reference pipeline: <https://gitlab.com/gitlab-org/gitlab/pipelines/136295694>
@@ -204,11 +46,11 @@ graph RL;
click 1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8100542&udv=0"
1-2["build-qa-image (3.4 minutes)"];
click 1-2 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914325&udv=0"
- 1-3["compile-assets pull-cache (9.06 minutes)"];
+ 1-3["compile-test-assets (9.06 minutes)"];
click 1-3 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914317&udv=0"
- 1-4["compile-assets pull-cache as-if-foss (8.35 minutes)"];
+ 1-4["compile-test-assets as-if-foss (8.35 minutes)"];
click 1-4 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356616&udv=0"
- 1-5["gitlab:assets:compile pull-cache (22 minutes)"];
+ 1-5["compile-production-assets (22 minutes)"];
click 1-5 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914312&udv=0"
1-6["setup-test-env (8.22 minutes)"];
click 1-6 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914315&udv=0"
@@ -224,6 +66,8 @@ graph RL;
1-18["kubesec-sast"];
1-19["nodejs-scan-sast"];
1-20["secrets-sast"];
+ 1-21["static-analysis (17 minutes)"];
+ click 1-21 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914471&udv=0"
class 1-3 criticalPath;
class 1-6 criticalPath;
@@ -241,8 +85,6 @@ graph RL;
2_1-1 & 2_1-2 & 2_1-3 & 2_1-4 --> 1-6;
end
- 2_2-1["static-analysis (17 minutes)"];
- click 2_2-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914471&udv=0"
2_2-2["frontend-fixtures (17.2 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"
@@ -252,13 +94,13 @@ graph RL;
click 2_2-4 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356727&udv=0"
2_2-5["webpack-dev-server (6.1 minutes)"];
click 2_2-5 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8404303&udv=0"
- subgraph "Needs `setup-test-env` & `compile-assets`";
- 2_2-1 & 2_2-2 & 2_2-4 & 2_2-5 --> 1-6 & 1-3;
+ subgraph "Needs `setup-test-env` & `compile-test-assets`";
+ 2_2-2 & 2_2-4 & 2_2-5 --> 1-6 & 1-3;
2_2-3 --> 1-6 & 1-4;
end
2_3-1["build-assets-image (2.5 minutes)"];
- subgraph "Needs `gitlab:assets:compile`";
+ subgraph "Needs `compile-production-assets`";
2_3-1 --> 1-5
end
@@ -269,7 +111,7 @@ graph RL;
end
2_5-1["rspec & db jobs (12-22 minutes)"];
- subgraph "Needs `compile-assets`, `setup-test-env`, & `retrieve-tests-metadata`";
+ subgraph "Needs `compile-test-assets`, `setup-test-env`, & `retrieve-tests-metadata`";
2_5-1 --> 1-3 & 1-6 & 1-14;
class 2_5-1 criticalPath;
click 2_5-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations"
@@ -304,7 +146,7 @@ graph RL;
end
```
-### Frontend-only MR pipeline
+#### Frontend-only MR pipeline
Reference pipeline: <https://gitlab.com/gitlab-org/gitlab/pipelines/134661039>
@@ -317,11 +159,11 @@ graph RL;
click 1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8100542&udv=0"
1-2["build-qa-image (3.4 minutes)"];
click 1-2 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914325&udv=0"
- 1-3["compile-assets pull-cache (9.06 minutes)"];
+ 1-3["compile-test-assets (9.06 minutes)"];
click 1-3 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914317&udv=0"
- 1-4["compile-assets pull-cache as-if-foss (8.35 minutes)"];
+ 1-4["compile-test-assets as-if-foss (8.35 minutes)"];
click 1-4 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356616&udv=0"
- 1-5["gitlab:assets:compile pull-cache (22 minutes)"];
+ 1-5["compile-production-assets (22 minutes)"];
click 1-5 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914312&udv=0"
1-6["setup-test-env (8.22 minutes)"];
click 1-6 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914315&udv=0"
@@ -337,6 +179,8 @@ graph RL;
1-18["kubesec-sast"];
1-19["nodejs-scan-sast"];
1-20["secrets-sast"];
+ 1-21["static-analysis (17 minutes)"];
+ click 1-21 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914471&udv=0"
class 1-3 criticalPath;
class 1-5 criticalPath;
@@ -355,8 +199,6 @@ graph RL;
2_1-1 & 2_1-2 & 2_1-3 & 2_1-4 --> 1-6;
end
- 2_2-1["static-analysis (17 minutes)"];
- click 2_2-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914471&udv=0"
2_2-2["frontend-fixtures (17.2 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"
@@ -366,14 +208,14 @@ graph RL;
click 2_2-4 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356727&udv=0"
2_2-5["webpack-dev-server (6.1 minutes)"];
click 2_2-5 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8404303&udv=0"
- subgraph "Needs `setup-test-env` & `compile-assets`";
- 2_2-1 & 2_2-2 & 2_2-4 & 2_2-5 --> 1-6 & 1-3;
+ subgraph "Needs `setup-test-env` & `compile-test-assets`";
+ 2_2-2 & 2_2-4 & 2_2-5 --> 1-6 & 1-3;
2_2-3 --> 1-6 & 1-4;
end
2_3-1["build-assets-image (2.5 minutes)"];
class 2_3-1 criticalPath;
- subgraph "Needs `gitlab:assets:compile`";
+ subgraph "Needs `compile-production-assets`";
2_3-1 --> 1-5
end
@@ -384,7 +226,7 @@ graph RL;
end
2_5-1["rspec & db jobs (12-22 minutes)"];
- subgraph "Needs `compile-assets`, `setup-test-env, & `retrieve-tests-metadata`";
+ subgraph "Needs `compile-test-assets`, `setup-test-env, & `retrieve-tests-metadata`";
2_5-1 --> 1-3 & 1-6 & 1-14;
class 2_5-1 criticalPath;
click 2_5-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations"
@@ -444,7 +286,7 @@ graph RL;
end
```
-### QA-only MR pipeline
+#### QA-only MR pipeline
Reference pipeline: <https://gitlab.com/gitlab-org/gitlab/pipelines/134645109>
@@ -457,11 +299,11 @@ graph RL;
click 1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8100542&udv=0"
1-2["build-qa-image (3.4 minutes)"];
click 1-2 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914325&udv=0"
- 1-3["compile-assets pull-cache (9.06 minutes)"];
+ 1-3["compile-test-assets (9.06 minutes)"];
click 1-3 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914317&udv=0"
- 1-4["compile-assets pull-cache as-if-foss (8.35 minutes)"];
+ 1-4["compile-test-assets as-if-foss (8.35 minutes)"];
click 1-4 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=8356616&udv=0"
- 1-5["gitlab:assets:compile pull-cache (22 minutes)"];
+ 1-5["compile-production-assets (22 minutes)"];
click 1-5 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914312&udv=0"
1-6["setup-test-env (8.22 minutes)"];
click 1-6 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914315&udv=0"
@@ -477,6 +319,8 @@ graph RL;
1-18["kubesec-sast"];
1-19["nodejs-scan-sast"];
1-20["secrets-sast"];
+ 1-21["static-analysis (17 minutes)"];
+ click 1-21 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914471&udv=0"
class 1-5 criticalPath;
end
@@ -487,14 +331,8 @@ graph RL;
2_1-1 --> 1-6;
end
- 2_2-1["static-analysis (17 minutes)"];
- click 2_2-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914471&udv=0"
- subgraph "Needs `setup-test-env` & `compile-assets`";
- 2_2-1 --> 1-6 & 1-3;
- end
-
2_3-1["build-assets-image (2.5 minutes)"];
- subgraph "Needs `gitlab:assets:compile`";
+ subgraph "Needs `compile-production-assets`";
2_3-1 --> 1-5
class 2_3-1 criticalPath;
end
@@ -507,24 +345,61 @@ graph RL;
end
```
-## Test jobs
+### `workflow:rules`
+
+We're using the [`workflow:rules` keyword](../ci/yaml/README.md#workflowrules) to
+define default rules to determine whether or not a pipeline is created.
+
+These rules are defined in <https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab-ci.yml>
+and are as follows:
+
+1. If `$FORCE_GITLAB_CI` is set, create a pipeline.
+1. For merge requests, create a pipeline.
+1. For `master` branch, create a pipeline (this includes on schedules, pushes, merges, etc.).
+1. For tags, create a pipeline.
+1. If `$GITLAB_INTERNAL` isn't set, don't create a pipeline.
+1. For stable, auto-deploy, and security branches, create a pipeline.
+1. For any other cases (e.g. when pushing a branch with no MR for it), no pipeline is created.
+
+### PostgreSQL versions testing
+
+#### Current versions testing
+
+| Where? | PostgreSQL version |
+| ------ | ------ |
+| MRs | 11 |
+| `master` (non-scheduled pipelines) | 11 |
+| 2-hourly scheduled pipelines | 11 |
+
+#### Long-term plan
+
+We follow the [PostgreSQL versions shipped with Omnibus GitLab](https://docs.gitlab.com/omnibus/package-information/postgresql_versions.html):
+
+| PostgreSQL version | 12.10 (April 2020) | 13.0 (May 2020) | 13.1 (June 2020) | 13.2 (July 2020) | 13.3 (August 2020) | 13.4, 13.5 | 13.6 (November 2020) | 14.0 (May 2021?) |
+| ------ | ------------------ | --------------- | ---------------- | ---------------- | ------------------ | ------------ | -------------------- | ---------------- |
+| PG9.6 | MRs/`master`/`2-hour`/`nightly` | - | - | - | - | - | - | - |
+| PG10 | `nightly` | - | - | - | - | - | - | - |
+| PG11 | `master`/`2-hour` | MRs/`master`/`2-hour`/`nightly` | MRs/`master`/`2-hour`/`nightly` | MRs/`master`/`2-hour`/`nightly` | MRs/`master`/`2-hour`/`nightly` | MRs/`master`/`2-hour`/`nightly` | `nightly` | - |
+| PG12 | - | - | - | - | `master`/`2-hour` | `master`/`2-hour` | MRs/`master`/`2-hour`/`nightly` | `master`/`2-hour` |
+| PG13 | - | - | - | - | - | - | - | MRs/`master`/`2-hour`/`nightly` |
+
+### Test jobs
Consult [GitLab tests in the Continuous Integration (CI) context](testing_guide/ci.md)
for more information.
-## Review app jobs
+### Review app jobs
Consult the [Review Apps](testing_guide/review_apps.md) dedicated page for more information.
-## As-if-FOSS jobs
+### As-if-FOSS jobs
The `* as-if-foss` jobs allows to run GitLab's test suite "as-if-FOSS", meaning as if the jobs would run in the context
of the `gitlab-org/gitlab-foss` project. These jobs are only created in the following cases:
-- `master` commits (pushes and scheduled pipelines).
- `gitlab-org/security/gitlab` merge requests.
- Merge requests which include `RUN AS-IF-FOSS` in their title.
-- Merge requests that changes the CI config.
+- Merge requests that changes the CI configuration.
The `* as-if-foss` jobs have the `FOSS_ONLY='1'` variable set and gets their EE-specific
folders removed before the tests start running.
@@ -532,9 +407,41 @@ folders removed before the tests start running.
The intent is to ensure that a change won't introduce a failure once the `gitlab-org/gitlab` project will be synced to
the `gitlab-org/gitlab-foss` project.
-## Pre-clone step
+## Performance
-The `gitlab-org/gitlab` project on GitLab.com uses a [pre-clone step](https://gitlab.com/gitlab-org/gitlab/issues/39134)
+### Interruptible pipelines
+
+By default, all jobs are [interruptible](../ci/yaml/README.md#interruptible), except the
+`dont-interrupt-me` job which runs automatically on `master`, and is `manual`
+otherwise.
+
+If you want a running pipeline to finish even if you push new commits to a merge
+request, be sure to start the `dont-interrupt-me` job before pushing.
+
+### Caching strategy
+
+1. All jobs must only pull caches by default.
+1. All jobs must be able to pass with an empty cache. In other words, caches are only there to speed up jobs.
+1. We currently have 6 different caches defined in
+ [`.gitlab/ci/global.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab/ci/global.gitlab-ci.yml),
+ with fixed keys:
+ - `.rails-cache`.
+ - `.static-analysis-cache`.
+ - `.qa-cache`
+ - `.yarn-cache`.
+ - `.assets-compile-cache` (the key includes `${NODE_ENV}` so it's actually two different caches).
+1. Only 6 specific jobs, running in 2-hourly scheduled pipelines, are pushing (i.e. updating) to the caches:
+ - `update-rails-cache`, defined in [`.gitlab/ci/rails.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab/ci/rails.gitlab-ci.yml).
+ - `update-static-analysis-cache`, defined in [`.gitlab/ci/rails.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab/ci/rails.gitlab-ci.yml).
+ - `update-qa-cache`, defined in [`.gitlab/ci/qa.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab/ci/qa.gitlab-ci.yml).
+ - `update-assets-compile-production-cache`, defined in [`.gitlab/ci/frontend.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab/ci/frontend.gitlab-ci.yml).
+ - `update-assets-compile-test-cache`, defined in [`.gitlab/ci/frontend.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab/ci/frontend.gitlab-ci.yml).
+ - `update-yarn-cache`, defined in [`.gitlab/ci/frontend.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab/ci/frontend.gitlab-ci.yml).
+1. These jobs will run in merge requests whose title include `UPDATE CACHE`.
+
+### Pre-clone step
+
+The `gitlab-org/gitlab` project on GitLab.com uses a [pre-clone step](https://gitlab.com/gitlab-org/gitlab/-/issues/39134)
to seed the project with a recent archive of the repository. This is done for
several reasons:
@@ -597,6 +504,124 @@ credentials are stored in the 1Password GitLab.com Production vault.
Note that this bucket should be located in the same continent as the
runner, or [network egress charges will apply](https://cloud.google.com/storage/pricing).
+## CI configuration internals
+
+### Stages
+
+The current stages are:
+
+- `sync`: This stage is used to synchronize changes from <https://gitlab.com/gitlab-org/gitlab> to
+ <https://gitlab.com/gitlab-org/gitlab-foss>.
+- `prepare`: This stage includes jobs that prepare artifacts that are needed by
+ jobs in subsequent stages.
+- `build-images`: This stage includes jobs that prepare Docker images
+ that are needed by jobs in subsequent stages or downstream pipelines.
+- `fixtures`: This stage includes jobs that prepare fixtures needed by frontend tests.
+- `test`: This stage includes most of the tests, DB/migration jobs, and static analysis jobs.
+- `post-test`: This stage includes jobs that build reports or gather data from
+ the `test` stage's jobs (e.g. coverage, Knapsack metadata etc.).
+- `review-prepare`: This stage includes a job that build the CNG images that are
+ later used by the (Helm) Review App deployment (see
+ [Review Apps](testing_guide/review_apps.md) for details).
+- `review`: This stage includes jobs that deploy the GitLab and Docs Review Apps.
+- `qa`: This stage includes jobs that perform QA tasks against the Review App
+ that is deployed in the previous stage.
+- `post-qa`: This stage includes jobs that build reports or gather data from
+ the `qa` stage's jobs (e.g. Review App performance report).
+- `pages`: This stage includes a job that deploys the various reports as
+ GitLab Pages (e.g. [`coverage-ruby`](https://gitlab-org.gitlab.io/gitlab/coverage-ruby/),
+ [`coverage-javascript`](https://gitlab-org.gitlab.io/gitlab/coverage-javascript/),
+ [`webpack-report`](https://gitlab-org.gitlab.io/gitlab/webpack-report/).
+
+### Default image
+
+The default image is defined in [`.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab-ci.yml).
+
+It includes Ruby, Go, Git, Git LFS, Chrome, Node, Yarn, PostgreSQL, and Graphics Magick.
+
+The images used in our pipelines are configured in the
+[`gitlab-org/gitlab-build-images`](https://gitlab.com/gitlab-org/gitlab-build-images)
+project, which is push-mirrored to [`gitlab/gitlab-build-images`](https://dev.gitlab.org/gitlab/gitlab-build-images)
+for redundancy.
+
+The current version of the build images can be found in the
+["Used by GitLab section"](https://gitlab.com/gitlab-org/gitlab-build-images/blob/master/.gitlab-ci.yml).
+
+### Default variables
+
+In addition to the [predefined variables](../ci/variables/predefined_variables.md),
+each pipeline includes default variables defined in
+<https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab-ci.yml>.
+
+### Common job definitions
+
+Most of the jobs [extend from a few CI definitions](../ci/yaml/README.md#extends)
+defined in [`.gitlab/ci/global.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab/ci/global.gitlab-ci.yml)
+that are scoped to a single [configuration parameter](../ci/yaml/README.md#configuration-parameters).
+
+| Job definitions | Description |
+|------------------|-------------|
+| `.default-tags` | Ensures a job has the `gitlab-org` tag to ensure it's using our dedicated runners. |
+| `.default-retry` | Allows a job to [retry](../ci/yaml/README.md#retry) upon `unknown_failure`, `api_failure`, `runner_system_failure`, `job_execution_timeout`, or `stuck_or_timeout_failure`. |
+| `.default-before_script` | Allows a job to use a default `before_script` definition suitable for Ruby/Rails tasks that may need a database running (e.g. tests). |
+| `.rails-cache` | Allows a job to use a default `cache` definition suitable for Ruby/Rails tasks. |
+| `.static-analysis-cache` | Allows a job to use a default `cache` definition suitable for static analysis tasks. |
+| `.yarn-cache` | Allows a job to use a default `cache` definition suitable for frontend jobs that do a `yarn install`. |
+| `.assets-compile-cache` | Allows a job to use a default `cache` definition suitable for frontend jobs that compile assets. |
+| `.use-pg11` | Allows a job to use the `postgres:11.6` and `redis:alpine` services. |
+| `.use-pg11-ee` | Same as `.use-pg11` but also use the `docker.elastic.co/elasticsearch/elasticsearch:6.4.2` services. |
+| `.use-kaniko` | Allows a job to use the `kaniko` tool to build Docker images. |
+| `.as-if-foss` | Simulate the FOSS project by setting the `FOSS_ONLY='1'` environment variable. |
+
+### `rules`, `if:` conditions and `changes:` patterns
+
+We're using the [`rules` keyword](../ci/yaml/README.md#rules) extensively.
+
+All `rules` definitions are defined in
+<https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/ci/rules.gitlab-ci.yml>,
+then included in individual jobs via [`extends`](../ci/yaml/README.md#extends).
+
+The `rules` definitions are composed of `if:` conditions and `changes:` patterns,
+which are also defined in
+[`rules.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/ci/rules.gitlab-ci.yml)
+and included in `rules` definitions via [YAML anchors](../ci/yaml/README.md#anchors)
+
+#### `if:` conditions
+
+| `if:` conditions | Description | Notes |
+|------------------|-------------|-------|
+| `if-not-canonical-namespace` | Matches if the project isn't in the canonical (`gitlab-org/`) or security (`gitlab-org/security`) namespace. | Use to create a job for forks (by using `when: on_success\|manual`), or **not** create a job for forks (by using `when: never`). |
+| `if-not-ee` | Matches if the project isn't EE (i.e. project name isn't `gitlab` or `gitlab-ee`). | Use to create a job only in the FOSS project (by using `when: on_success|manual`), or **not** create a job if the project is EE (by using `when: never`). |
+| `if-not-foss` | Matches if the project isn't FOSS (i.e. project name isn't `gitlab-foss`, `gitlab-ce`, or `gitlabhq`). | Use to create a job only in the EE project (by using `when: on_success|manual`), or **not** create a job if the project is FOSS (by using `when: never`). |
+| `if-default-refs` | Matches if the pipeline is for `master`, `/^[\d-]+-stable(-ee)?$/` (stable branches), `/^\d+-\d+-auto-deploy-\d+$/` (auto-deploy branches), `/^security\//` (security branches), merge requests, and tags. | Note that jobs won't be created for branches with this default configuration. |
+| `if-master-refs` | Matches if the current branch is `master`. | |
+| `if-master-or-tag` | Matches if the pipeline is for the `master` branch or for a tag. | |
+| `if-merge-request` | Matches if the pipeline is for a merge request. | |
+| `if-nightly-master-schedule` | Matches if the pipeline is for a `master` scheduled pipeline with `$NIGHTLY` set. | |
+| `if-dot-com-gitlab-org-schedule` | Limits jobs creation to scheduled pipelines for the `gitlab-org` group on GitLab.com. | |
+| `if-dot-com-gitlab-org-master` | Limits jobs creation to the `master` branch for the `gitlab-org` group on GitLab.com. | |
+| `if-dot-com-gitlab-org-merge-request` | Limits jobs creation to merge requests for the `gitlab-org` group on GitLab.com. | |
+| `if-dot-com-gitlab-org-and-security-tag` | Limits job creation to tags for the `gitlab-org` and `gitlab-org/security` groups on GitLab.com. | |
+| `if-dot-com-gitlab-org-and-security-merge-request` | Limit jobs creation to merge requests for the `gitlab-org` and `gitlab-org/security` groups on GitLab.com. | |
+| `if-dot-com-ee-schedule` | Limits jobs to scheduled pipelines for the `gitlab-org/gitlab` project on GitLab.com. | |
+| `if-cache-credentials-schedule` | Limits jobs to scheduled pipelines with the `$CI_REPO_CACHE_CREDENTIALS` variable set. | |
+
+#### `changes:` patterns
+
+| `changes:` patterns | Description |
+|------------------------------|--------------------------------------------------------------------------|
+| `ci-patterns` | Only create job for CI config-related changes. |
+| `yaml-patterns` | Only create job for YAML-related changes. |
+| `docs-patterns` | Only create job for docs-related changes. |
+| `frontend-dependency-patterns` | Only create job when frontend dependencies are updated (i.e. `package.json`, and `yarn.lock`). changes. |
+| `frontend-patterns` | Only create job for frontend-related changes. |
+| `backstage-patterns` | Only create job for backstage-related changes (i.e. Danger, fixtures, RuboCop, specs). |
+| `code-patterns` | Only create job for code-related changes. |
+| `qa-patterns` | Only create job for QA-related changes. |
+| `code-backstage-patterns` | Combination of `code-patterns` and `backstage-patterns`. |
+| `code-qa-patterns` | Combination of `code-patterns` and `qa-patterns`. |
+| `code-backstage-qa-patterns` | Combination of `code-patterns`, `backstage-patterns`, and `qa-patterns`. |
+
---
[Return to Development documentation](README.md)
diff --git a/doc/development/polling.md b/doc/development/polling.md
index bc178f8cb21..47cfc32d934 100644
--- a/doc/development/polling.md
+++ b/doc/development/polling.md
@@ -56,4 +56,4 @@ For more information see:
- [`Poll-Interval` header](fe_guide/performance.md#realtime-components)
- [RFC 7232](https://tools.ietf.org/html/rfc7232)
-- [ETag proposal](https://gitlab.com/gitlab-org/gitlab-foss/issues/26926)
+- [ETag proposal](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/26926)
diff --git a/doc/development/profiling.md b/doc/development/profiling.md
index 2589329fc83..2cab6750b9b 100644
--- a/doc/development/profiling.md
+++ b/doc/development/profiling.md
@@ -107,9 +107,13 @@ Recorded transactions can be found by navigating to `/sherlock/transactions`.
## Bullet
-Bullet is a Gem that can be used to track down N+1 query problems. Because
-Bullet adds quite a bit of logging noise it's disabled by default. To enable
-Bullet, set the environment variable `ENABLE_BULLET` to a non-empty value before
+Bullet is a Gem that can be used to track down N+1 query problems. Bullet section is
+displayed on the [performance-bar](../administration/monitoring/performance/performance_bar.md).
+
+![Bullet](img/bullet_v13_0.png)
+
+Because Bullet adds quite a bit of logging noise the logging is disabled by default.
+To enable the logging, set the environment variable `ENABLE_BULLET` to a non-empty value before
starting GitLab. For example:
```shell
diff --git a/doc/development/rake_tasks.md b/doc/development/rake_tasks.md
index 96acce5e4df..3fa6ba40e6c 100644
--- a/doc/development/rake_tasks.md
+++ b/doc/development/rake_tasks.md
@@ -147,7 +147,7 @@ To run several tests inside one directory:
### Speed up tests, Rake tasks, and migrations
-[Spring](https://github.com/rails/spring) is a Rails application preloader. It
+[Spring](https://github.com/rails/spring) is a Rails application pre-loader. It
speeds up development by keeping your application running in the background so
you don't need to boot it every time you run a test, Rake task or migration.
@@ -203,9 +203,9 @@ To generate a sprite file containing all the Emoji, run:
bundle exec rake gemojione:sprite
```
-If new emoji are added, the spritesheet may change size. To compensate for
-such changes, first generate the `emoji.png` spritesheet with the above Rake
-task, then check the dimensions of the new spritesheet and update the
+If new emoji are added, the sprite sheet may change size. To compensate for
+such changes, first generate the `emoji.png` sprite sheet with the above Rake
+task, then check the dimensions of the new sprite sheet and update the
`SPRITESHEET_WIDTH` and `SPRITESHEET_HEIGHT` constants accordingly.
## Update project templates
diff --git a/doc/development/redis.md b/doc/development/redis.md
index a8b7b84bb65..6782ea96448 100644
--- a/doc/development/redis.md
+++ b/doc/development/redis.md
@@ -18,7 +18,7 @@ database.
Redis is a flat namespace with no hierarchy, which means we must pay attention
to key names to avoid collisions. Typically we use colon-separated elements to
-provide a semblence of structure at application level. An example might be
+provide a semblance of structure at application level. An example might be
`projects:1:somekey`.
Although we split our Redis usage into three separate purposes, and those may
@@ -34,7 +34,7 @@ invalidated by a name change, it is better to include a hook that will expire
the entry, instead of relying on the key changing.
We don't use [Redis Cluster](https://redis.io/topics/cluster-tutorial) at the
-moment, but may wish to in the future: [#118820](https://gitlab.com/gitlab-org/gitlab/issues/118820).
+moment, but may wish to in the future: [#118820](https://gitlab.com/gitlab-org/gitlab/-/issues/118820).
This imposes an additional constraint on naming: where GitLab is performing
operations that require several keys to be held on the same Redis server - for
diff --git a/doc/development/refactoring_guide/index.md b/doc/development/refactoring_guide/index.md
index 4bd9d0e9c11..a9ff9556aed 100644
--- a/doc/development/refactoring_guide/index.md
+++ b/doc/development/refactoring_guide/index.md
@@ -21,7 +21,7 @@ Pinning tests help you ensure that you don't unintentionally change the output o
Leaving in the commits for adding and removing pins helps others checkout and verify the result of the test.
-```bash
+```shell
AAAAAA Add pinning tests to funky_foo
BBBBBB Refactor funky_foo into nice_foo
CCCCCC Remove pinning tests for funky_foo
@@ -31,13 +31,13 @@ Then you can leave a reviewer instructions on how to run the pinning test in you
> First revert the commit which removes the pin.
>
-> ```bash
+> ```shell
> git revert --no-commit $(git log -1 --grep="Remove pinning test for funky_foo" --pretty=format:"%H")
> ```
>
> Then run the test
>
-> ```bash
+> ```shell
> yarn run jest path/to/funky_foo_pin_spec.js
> ```
@@ -69,7 +69,7 @@ expect(cleanForSnapshot(wrapper.element)).toMatchSnapshot();
### Examples
-- [Pinning test in a haml to vue refactor](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27691#pinning-tests)
+- [Pinning test in a Haml to Vue refactor](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27691#pinning-tests)
- [Pinning test in isolating a bug](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/32198#note_212736225)
- [Pinning test in refactoring dropdown](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28173)
- [Pinning test in refactoring vulnerability_details.vue](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25830/commits)
diff --git a/doc/development/reference_processing.md b/doc/development/reference_processing.md
index ef1f2f5269c..79377533966 100644
--- a/doc/development/reference_processing.md
+++ b/doc/development/reference_processing.md
@@ -27,7 +27,7 @@ transform them into structured links to the resources they represent.
For example, the class
[`Banzai::Filter::IssueReferenceFilter`](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/banzai/filter/issue_reference_filter.rb)
is responsible for handling references to issues, such as
-`gitlab-org/gitlab#123` and `https://gitlab.com/gitlab-org/gitlab/issues/200048`.
+`gitlab-org/gitlab#123` and `https://gitlab.com/gitlab-org/gitlab/-/issues/200048`.
All reference filters are instances of [`HTML::Pipeline::Filter`](https://www.rubydoc.info/github/jch/html-pipeline/v1.11.0/HTML/Pipeline/Filter),
and inherit (often indirectly) from [`Banzai::Filter::ReferenceFilter`](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/banzai/filter/reference_filter.rb).
diff --git a/doc/development/renaming_features.md b/doc/development/renaming_features.md
index 6a196921a5d..daf437027db 100644
--- a/doc/development/renaming_features.md
+++ b/doc/development/renaming_features.md
@@ -16,7 +16,7 @@ The more of the following that are true, the more likely you should choose the f
- You are not confident the new name is permanent.
- The feature is susceptible to bugs (large, complex, needing refactor, etc).
-- The renaming will be difficult to review (feature spans many lines/files/repos).
+- The renaming will be difficult to review (feature spans many lines, files, or repositories).
- The renaming will be disruptive in some way (database table renaming).
## Consider a façade-first approach
diff --git a/doc/development/routing.md b/doc/development/routing.md
index 97837a917a2..e164431853f 100644
--- a/doc/development/routing.md
+++ b/doc/development/routing.md
@@ -63,11 +63,19 @@ gitlab-org/gitlab/-/settings/repository
gitlab-org/serverless/runtimes/-/settings/repository
```
-Currently, only some project routes are placed under the `/-/` scope. However,
-you can help us migrate more of them! To migrate project routes:
+## Migrating unscoped routes
+
+Currently, the majority of routes are placed under the `/-/` scope. However,
+you can help us migrate the rest of them! To migrate routes:
1. Modify existing routes by adding `-` scope.
1. Add redirects for legacy routes by using `Gitlab::Routing.redirect_legacy_paths`.
1. Create a technical debt issue to remove deprecated routes in later releases.
To get started, see an [example merge request](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/28435).
+
+## Useful links
+
+- [Routing improvements master plan](https://gitlab.com/gitlab-org/gitlab/-/issues/215362)
+- [Scoped routing explained](https://gitlab.com/gitlab-org/gitlab/-/issues/214217)
+- [Removal of deprecated routes](https://gitlab.com/gitlab-org/gitlab/-/issues/28848)
diff --git a/doc/development/scalability.md b/doc/development/scalability.md
index ba25e169d66..c0c26df88b5 100644
--- a/doc/development/scalability.md
+++ b/doc/development/scalability.md
@@ -52,10 +52,10 @@ maintain and support one database with tables with many rows.
There are two ways to deal with this:
-- Partioning. Locally split up tables data.
+- Partitioning. Locally split up tables data.
- Sharding. Distribute data across multiple databases.
-Partioning is a built-in PostgreSQL feature and requires minimal changes
+Partitioning is a built-in PostgreSQL feature and requires minimal changes
in the application. However, it [requires PostgreSQL
11](https://www.2ndquadrant.com/en/blog/partitioning-evolution-postgresql-11/).
@@ -93,12 +93,12 @@ systems.
#### Database size
A recent [database checkup shows a breakdown of the table sizes on
-GitLab.com](https://gitlab.com/gitlab-com/gl-infra/infrastructure/issues/8022#master-1022016101-8).
+GitLab.com](https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues/8022#master-1022016101-8).
Since `merge_request_diff_files` contains over 1 TB of data, we will want to
reduce/eliminate this table first. GitLab has support for [storing diffs in
object storage](../administration/merge_request_diffs.md), which we [will
want to do on
-GitLab.com](https://gitlab.com/gitlab-com/gl-infra/infrastructure/issues/7356).
+GitLab.com](https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues/7356).
#### High availability
@@ -116,7 +116,7 @@ database has reached the target time.
On GitLab.com, Consul and Patroni work together to coordinate failovers with
the read replicas. [Omnibus ships with repmgr instead of
-Consul](../administration/high_availability/database.md).
+Patroni](../administration/postgresql/replication_and_failover.md).
#### Load-balancing
@@ -147,10 +147,10 @@ limitation:
- Run multiple PgBouncer instances.
- Use a multi-threaded connection pooler (e.g.
- [Odyssey](https://gitlab.com/gitlab-com/gl-infra/infrastructure/issues/7776).
+ [Odyssey](https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues/7776).
On some Linux systems, it's possible to run [multiple PgBouncer instances on
-the same port](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/4796).
+the same port](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/4796).
On GitLab.com, we run multiple PgBouncer instances on different ports to
avoid saturating a single core.
@@ -246,9 +246,9 @@ lifting of many activities, including:
- Processing CI builds and pipelines.
The full list of jobs can be found in the
-[app/workers](https://gitlab.com/gitlab-org/gitlab/tree/master/app/workers)
+[`app/workers`](https://gitlab.com/gitlab-org/gitlab/tree/master/app/workers)
and
-[ee/app/workers](https://gitlab.com/gitlab-org/gitlab/tree/master/ee/app/workers)
+[`ee/app/workers`](https://gitlab.com/gitlab-org/gitlab/tree/master/ee/app/workers)
directories in the GitLab code base.
#### Runaway Queues
@@ -275,13 +275,13 @@ in a timely manner:
- Redistribute/gerrymander Sidekiq processes by queue
types. Long-running jobs (e.g. relating to project import) can often
squeeze out jobs that run fast (e.g. delivering e-mail). [This technique
- was used in to optimize our existing Sidekiq deployment](https://gitlab.com/gitlab-com/gl-infra/infrastructure/issues/7219#note_218019483).
+ was used in to optimize our existing Sidekiq deployment](https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues/7219#note_218019483).
- Optimize jobs. Eliminating unnecessary work, reducing network calls
(e.g. SQL, Gitaly, etc.), and optimizing processor time can yield significant
benefits.
From the Sidekiq logs, it's possible to see which jobs run the most
-frequently and/or take the longest. For example, theis Kibana
+frequently and/or take the longest. For example, these Kibana
visualizations show the jobs that consume the most total time:
![Most time-consuming Sidekiq jobs](img/sidekiq_most_time_consuming_jobs.png)
diff --git a/doc/development/secure_coding_guidelines.md b/doc/development/secure_coding_guidelines.md
index b473c310647..912b8fbf043 100644
--- a/doc/development/secure_coding_guidelines.md
+++ b/doc/development/secure_coding_guidelines.md
@@ -23,7 +23,7 @@ For more information about the permission model at GitLab, please see [the GitLa
### Impact
Improper permission handling can have significant impacts on the security of an application.
-Some situations may reveal [sensitive data](https://gitlab.com/gitlab-com/gl-infra/production/issues/477) or allow a malicious actor to perform [harmful actions](https://gitlab.com/gitlab-org/gitlab/issues/8180).
+Some situations may reveal [sensitive data](https://gitlab.com/gitlab-com/gl-infra/production/-/issues/477) or allow a malicious actor to perform [harmful actions](https://gitlab.com/gitlab-org/gitlab/-/issues/8180).
The overall impact depends heavily on what resources can be accessed or modified improperly.
A common vulnerability when permission checks are missing is called [IDOR](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/05-Authorization_Testing/04-Testing_for_Insecure_Direct_Object_References) for Insecure Direct Object References.
@@ -48,11 +48,11 @@ Be careful to **also test [visibility levels](https://gitlab.com/gitlab-org/gitl
Some example of well implemented access controls and tests:
-1. [example1](https://dev.gitlab.org/gitlab/gitlab-ee/merge_requests/710/diffs?diff_id=13750#af40ef0eaae3c1e018809e1d88086e32bccaca40_43_43)
+1. [example1](https://dev.gitlab.org/gitlab/gitlab-ee/-/merge_requests/710/diffs?diff_id=13750#af40ef0eaae3c1e018809e1d88086e32bccaca40_43_43)
1. [example2](https://dev.gitlab.org/gitlab/gitlabhq/-/merge_requests/2511/diffs#ed3aaab1510f43b032ce345909a887e5b167e196_142_155)
1. [example3](https://dev.gitlab.org/gitlab/gitlabhq/-/merge_requests/3170/diffs?diff_id=17494)
-**NB:** any input from development team is welcome, e.g. about rubocop rules.
+**NB:** any input from development team is welcome, e.g. about Rubocop rules.
## Regular Expressions guidelines
@@ -67,7 +67,7 @@ matches = re.findall("^bar$",text)
print(matches)
```
-The Python example will output an emtpy array (`[]`) as the matcher considers the whole string `foo\nbar` including the newline (`\n`). In contrast Ruby's Regular Expression engine acts differently:
+The Python example will output an empty array (`[]`) as the matcher considers the whole string `foo\nbar` including the newline (`\n`). In contrast Ruby's Regular Expression engine acts differently:
```ruby
text = "foo\nbar"
@@ -82,7 +82,7 @@ This Ruby Regex specialty can have security impact, as often regular expressions
#### Examples
-GitLab specific examples can be found [here](https://gitlab.com/gitlab-org/gitlab/issues/36029#note_251262187) and [there](https://gitlab.com/gitlab-org/gitlab/issues/33569).
+GitLab specific examples can be found [here](https://gitlab.com/gitlab-org/gitlab/-/issues/36029#note_251262187) and [there](https://gitlab.com/gitlab-org/gitlab/-/issues/33569).
Another example would be this fictional Ruby On Rails controller:
@@ -111,7 +111,7 @@ or controls the regular expression (regex) used, and is able to enter user input
### Impact
-The resource, for example Unicorn, Puma, or Sidekiq, can be made to hang as it takes a long time to evaulate the bad regex match.
+The resource, for example Unicorn, Puma, or Sidekiq, can be made to hang as it takes a long time to evaluate the bad regex match.
### Examples
@@ -140,9 +140,9 @@ class Email < ApplicationRecord
GitLab has `Gitlab::UntrustedRegexp` which internally uses the [`re2`](https://github.com/google/re2/wiki/Syntax) library.
By utilizing `re2`, we get a strict limit on total execution time, and a smaller subset of available regex features.
-All user-provided regexes should use `Gitlab::UntrustedRegexp`.
+All user-provided regular expressions should use `Gitlab::UntrustedRegexp`.
-For other regexes, here are a few guidelines:
+For other regular expressions, here are a few guidelines:
- Remove unnecessary backtracking.
- Avoid nested quantifiers if possible.
@@ -180,11 +180,11 @@ have been reported to GitLab include:
- Network mapping of internal services
- This can help an attacker gather information about internal services
- that could be used in further attacks. [More details](https://gitlab.com/gitlab-org/gitlab-foss/issues/51327).
+ that could be used in further attacks. [More details](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/51327).
- Reading internal services, including cloud service metadata.
- The latter can be a serious problem, because an attacker can obtain keys that allow control of the victim's cloud infrastructure. (This is also a good reason
- to give only necessary privileges to the token.). [More details](https://gitlab.com/gitlab-org/gitlab-foss/issues/51490).
-- When combined with CRLF vulnerability, remote code execution. [More details](https://gitlab.com/gitlab-org/gitlab-foss/issues/41293)
+ to give only necessary privileges to the token.). [More details](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/51490).
+- When combined with CRLF vulnerability, remote code execution. [More details](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41293)
### When to Consider
@@ -206,14 +206,14 @@ The [GitLab::HTTP](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab
`Outbound requests` options that allow instance administrators to block all internal connections, or limit the networks to which connections can be made.
In some cases, it has been possible to configure GitLab::HTTP as the HTTP
-connection library for 3rd-party gems. This is preferrable over re-implementing
+connection library for 3rd-party gems. This is preferable over re-implementing
the mitigations for a new feature.
- [More details](https://dev.gitlab.org/gitlab/gitlabhq/-/merge_requests/2530/diffs)
#### Feature-specific Mitigations
-For situtions in which a whitelist or GitLab:HTTP cannot be used, it will be necessary to implement mitigations directly in the feature. It is best to validate the destination IP addresses themselves, not just domain names, as DNS can be controlled by the attacker. Below are a list of mitigations that should be implemented.
+For situations in which an allowlist or GitLab:HTTP cannot be used, it will be necessary to implement mitigations directly in the feature. It is best to validate the destination IP addresses themselves, not just domain names, as DNS can be controlled by the attacker. Below are a list of mitigations that should be implemented.
**Important Note:** There are many tricks to bypass common SSRF validations. If feature-specific mitigations are necessary, they should be reviewed by the AppSec team, or a developer who has worked on SSRF mitigations previously.
@@ -230,7 +230,7 @@ For situtions in which a whitelist or GitLab:HTTP cannot be used, it will be nec
- For HTTP connections: Disable redirects or validate the redirect destination
- To mitigate DNS rebinding attacks, validate and use the first IP address received
-See [url_blocker_spec.rb](https://gitlab.com/gitlab-org/gitlab/-/blob/master/spec/lib/gitlab/url_blocker_spec.rb) for examples of SSRF payloads
+See [`url_blocker_spec.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/spec/lib/gitlab/url_blocker_spec.rb) for examples of SSRF payloads
## XSS guidelines
@@ -276,10 +276,10 @@ For any and all input fields, ensure to define expectations on the type/format o
- Treat all user input as untrusted.
- Based on the expectations you [defined above](#setting-expectations):
- Validate the [input size limits](https://youtu.be/2VFavqfDS6w?t=7582).
- - Validate the input using a [whitelist approach](https://youtu.be/2VFavqfDS6w?t=7816) to only allow characters through which you are expecting to receive for the field.
+ - Validate the input using an [allowlist approach](https://youtu.be/2VFavqfDS6w?t=7816) to only allow characters through which you are expecting to receive for the field.
- Input which fails validation should be **rejected**, and not sanitized.
-Note that blacklists should be avoided, as it is near impossible to block all [variations of XSS](https://owasp.org/www-community/xss-filter-evasion-cheatsheet).
+Note that denylists should be avoided, as it is near impossible to block all [variations of XSS](https://owasp.org/www-community/xss-filter-evasion-cheatsheet).
#### Output encoding
@@ -308,7 +308,7 @@ Once you've [determined when and where](#setting-expectations) the user submitte
#### Content Security Policy
- [Content Security Policy](https://www.youtube.com/watch?v=2VFavqfDS6w&t=12991s)
-- [Use nonce-based Content Security Policy for inline JavaScript](https://gitlab.com/gitlab-org/gitlab-foss/issues/65330)
+- [Use nonce-based Content Security Policy for inline JavaScript](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/65330)
#### Free form input fields
@@ -323,7 +323,7 @@ Once you've [determined when and where](#setting-expectations) the user submitte
### Select examples of past XSS issues affecting GitLab
-- [Stored XSS in user status](https://gitlab.com/gitlab-org/gitlab-foss/issues/55320)
+- [Stored XSS in user status](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/55320)
### Developer Training
@@ -345,5 +345,5 @@ Once you've [determined when and where](#setting-expectations) the user submitte
- [Input Validation](https://youtu.be/2VFavqfDS6w?t=7489)
- [Validate size limits](https://youtu.be/2VFavqfDS6w?t=7582)
- [RoR model validators](https://youtu.be/2VFavqfDS6w?t=7636)
-- [Whitelist input validation](https://youtu.be/2VFavqfDS6w?t=7816)
+- [Allowlist input validation](https://youtu.be/2VFavqfDS6w?t=7816)
- [Content Security Policy](https://www.youtube.com/watch?v=2VFavqfDS6w&t=12991s)
diff --git a/doc/development/service_measurement.md b/doc/development/service_measurement.md
new file mode 100644
index 00000000000..e53864c8640
--- /dev/null
+++ b/doc/development/service_measurement.md
@@ -0,0 +1,81 @@
+# GitLab Developers Guide to service measurement
+
+You can enable service measurement in order to debug any slow service's execution time, number of SQL calls, garbage collection stats, memory usage, etc.
+
+## Measuring module
+
+The measuring module is a tool that allows to measure a service's execution, and log:
+
+- Service class name
+- Execution time
+- Number of SQL calls
+- Detailed `gc` stats and diffs
+- RSS memory usage
+- Server worker ID
+
+The measuring module will log these measurements into a structured log called [`service_measurement.log`](../administration/logs.md#service_measurementlog),
+as a single entry for each service execution.
+
+NOTE: **Note:**
+For GitLab.com, `service_measurement.log` is ingested in Elasticsearch and Kibana as part of our monitoring solution.
+
+## How to use it
+
+The measuring module allows you to easily measure and log execution of any service,
+by just prepending `Measurable` in any Service class, on the last line of the file that the class resides in.
+
+For example, to prepend a module into the `DummyService` class, you would use the following approach:
+
+```ruby
+class DummyService
+ def execute
+ # ...
+ end
+end
+
+DummyService.prepend(Measurable)
+```
+
+In case when you are prepending a module from the `EE` namespace with EE features, you need to prepend Measurable after prepending the `EE` module.
+
+This way, `Measurable` will be at the bottom of the ancestor chain, in order to measure execution of `EE` features as well:
+
+```ruby
+class DummyService
+ def execute
+ # ...
+ end
+end
+
+DummyService.prepend_if_ee('EE::DummyService')
+DummyService.prepend(Measurable)
+```
+
+### Log additional attributes
+
+In case you need to log some additional attributes, it is possible to define `extra_attributes_for_measurement` in the service class:
+
+```ruby
+def extra_attributes_for_measurement
+ {
+ project_path: @project.full_path,
+ user: current_user.name
+ }
+end
+```
+
+NOTE: **Note:**
+Once the measurement module is injected in the service, it will be behind generic feature flag.
+In order to actually use it, you need to enable measuring for the desired service by enabling the feature flag.
+
+### Enabling measurement using feature flags
+
+In the following example, the `:gitlab_service_measuring_projects_import_service`
+[feature flag](feature_flags/development.md#enabling-a-feature-flag-in-development) is used to enable the measuring feature
+for `Projects::ImportService`.
+
+From ChatOps:
+
+```shell
+/chatops run feature set gitlab_service_measuring_projects_import_service true
+```
diff --git a/doc/development/shell_scripting_guide/index.md b/doc/development/shell_scripting_guide/index.md
index 99cd1b9d67f..c04a4e90e59 100644
--- a/doc/development/shell_scripting_guide/index.md
+++ b/doc/development/shell_scripting_guide/index.md
@@ -106,7 +106,7 @@ and ignore files starting with a period. To override this, use `-ln` flag to spe
NOTE: **Note:**
This is a work in progress.
-It is an [ongoing effort](https://gitlab.com/gitlab-org/gitlab-foss/issues/64016) to evaluate different tools for the
+It is an [ongoing effort](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/64016) to evaluate different tools for the
automated testing of shell scripts (like [BATS](https://github.com/bats-core/bats-core)).
## Code Review
diff --git a/doc/development/sidekiq_style_guide.md b/doc/development/sidekiq_style_guide.md
index a5d0eecdc7b..7ae3c9e9de2 100644
--- a/doc/development/sidekiq_style_guide.md
+++ b/doc/development/sidekiq_style_guide.md
@@ -78,7 +78,7 @@ As a general rule, a worker can be considered idempotent if:
- It can safely run multiple times with the same arguments.
- Application side-effects are expected to happen only once
- (or side-effects of a second run are not impactful).
+ (or side-effects of a second run do not have an effect).
A good example of that would be a cache expiration worker.
@@ -147,7 +147,7 @@ GitLab doesn't skip jobs scheduled in the future, as we assume that
the state will have changed by the time the job is scheduled to
execute.
-More [deduplication strategies have been suggested](https://gitlab.com/gitlab-com/gl-infra/scalability/issues/195). If you are implementing a worker that
+More [deduplication strategies have been suggested](https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/195). If you are implementing a worker that
could benefit from a different strategy, please comment in the issue.
If the automatic deduplication were to cause issues in certain
@@ -156,7 +156,7 @@ named `disable_<queue name>_deduplication`. For example to disable
deduplication for the `AuthorizedProjectsWorker`, we would enable the
feature flag `disable_authorized_projects_deduplication`.
-From chatops:
+From ChatOps:
```shell
/chatops run feature set disable_authorized_projects_deduplication true
@@ -272,10 +272,10 @@ annotated with the `worker_resource_boundary` method.
Most workers tend to spend most of their time blocked, wait on network responses
from other services such as Redis, PostgreSQL, and Gitaly. Since Sidekiq is a
-multithreaded environment, these jobs can be scheduled with high concurrency.
+multi-threaded environment, these jobs can be scheduled with high concurrency.
Some workers, however, spend large amounts of time _on-CPU_ running logic in
-Ruby. Ruby MRI does not support true multithreading - it relies on the
+Ruby. Ruby MRI does not support true multi-threading - it relies on the
[GIL](https://thoughtbot.com/blog/untangling-ruby-threads#the-global-interpreter-lock)
to greatly simplify application development by only allowing one section of Ruby
code in a process to run at a time, no matter how many cores the machine
@@ -395,7 +395,7 @@ in the default execution mode - using
does not account for weights.
As we are [moving towards using `sidekiq-cluster` in
-Core](https://gitlab.com/gitlab-org/gitlab/issues/34396), newly-added
+Core](https://gitlab.com/gitlab-org/gitlab/-/issues/34396), newly-added
workers do not need to have weights specified. They can simply use the
default weight, which is 1.
@@ -427,7 +427,7 @@ isn't picked up by the cops. In any case, please leave a code-comment
pointing to which context will be used when disabling the cops.
When you do provide objects to the context, please make sure that the
-route for namespaces and projects is preloaded. This can be done using
+route for namespaces and projects is pre-loaded. This can be done using
the `.with_route` scope defined on all `Routable`s.
### Cron-Workers
@@ -518,6 +518,34 @@ job needs to be scheduled with.
The `context_proc` which needs to return a hash with the context
information for the job.
+## Arguments logging
+
+When [`SIDEKIQ_LOG_ARGUMENTS`](../administration/troubleshooting/sidekiq.md#log-arguments-to-sidekiq-jobs)
+is enabled, Sidekiq job arguments will be logged.
+
+By default, the only arguments logged are numeric arguments, because
+arguments of other types could contain sensitive information. To
+override this, use `loggable_arguments` inside a worker with the indexes
+of the arguments to be logged. (Numeric arguments do not need to be
+specified here.)
+
+For example:
+
+```ruby
+class MyWorker
+ include ApplicationWorker
+
+ loggable_arguments 1, 3
+
+ # object_id will be logged as it's numeric
+ # string_a will be logged due to the loggable_arguments call
+ # string_b will be filtered from logs
+ # string_c will be logged due to the loggable_arguments call
+ def perform(object_id, string_a, string_b, string_c)
+ end
+end
+```
+
## Tests
Each Sidekiq worker must be tested using RSpec, just like any other class. These
@@ -537,18 +565,74 @@ possible situations:
### Changing the arguments for a worker
-Jobs need to be backwards- and forwards-compatible between consecutive versions
-of the application.
+Jobs need to be backward and forward compatible between consecutive versions
+of the application. Adding or removing an argument may cause problems
+during deployment before all Rails and Sidekiq nodes have the updated code.
+
+#### Remove an argument
+
+**Do not remove arguments from the `perform` function.**. Instead, use the
+following approach:
+
+1. Provide a default value (usually `nil`) and use a comment to mark the
+ argument as deprecated
+1. Stop using the argument in `perform_async`.
+1. Ignore the value in the worker class, but do not remove it until the next
+ major release.
+
+In the following example, if you want to remove `arg2`, first set a `nil` default value,
+and then update locations where `ExampleWorker.perform_async` is called.
+
+```ruby
+class ExampleWorker
+ def perform(object_id, arg1, arg2 = nil)
+ # ...
+ end
+end
+```
+
+#### Add an argument
+
+There are two options for safely adding new arguments to Sidekiq workers:
+
+1. Set up a [multi-step deployment](#multi-step-deployment) in which the new argument is first added to the worker
+1. Use a [parameter hash](#parameter-hash) for additional arguments. This is perhaps the most flexible option.
+1. Use a parameter hash for additional arguments. This is perhaps the most flexible option.
+
+##### Multi-step deployment
+
+This approach requires multiple merge requests and for the first merge request
+to be merged and deployed before additional changes are merged.
-This can be done by following this process:
+1. In an initial merge request, add the argument to the worker with a default
+ value:
-1. **Do not remove arguments from the `perform` function.**. Instead, use the
- following approach
- 1. Provide a default value (usually `nil`) and use a comment to mark the
- argument as deprecated
- 1. Stop using the argument in `perform_async`.
- 1. Ignore the value in the worker class, but do not remove it until the next
- major release.
+ ```ruby
+ class ExampleWorker
+ def perform(object_id, new_arg = nil)
+ # ...
+ end
+ end
+ ```
+
+1. Merge and deploy the worker with the new argument.
+1. In a further merge request, update `ExampleWorker.perform_async` calls to
+ use the new argument.
+
+##### Parameter hash
+
+This approach will not require multiple deployments if an existing worker already
+utilizes a parameter hash.
+
+1. Use a parameter hash in the worker to allow for future flexibility:
+
+ ```ruby
+ class ExampleWorker
+ def perform(object_id, params = {})
+ # ...
+ end
+ end
+ ```
### Removing workers
diff --git a/doc/development/telemetry/index.md b/doc/development/telemetry/index.md
index 32f63d5221e..aee16e4049a 100644
--- a/doc/development/telemetry/index.md
+++ b/doc/development/telemetry/index.md
@@ -1,3 +1,9 @@
+---
+stage: Growth
+group: Telemetry
+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
+---
+
# Telemetry Guide
At GitLab, we collect telemetry for the purpose of helping us build a better GitLab. Data about how GitLab is used is collected to better understand what parts of GitLab needs improvement and what features to build next. Telemetry also helps our team better understand the reasons why people use GitLab and with this knowledge we are able to make better product decisions.
@@ -19,11 +25,11 @@ Telemetry Guide:
1. [What is Usage Ping](usage_ping.md#what-is-usage-ping)
1. [Usage Ping payload](usage_ping.md#usage-ping-payload)
- 1. [Disabling Usage Ping](usage_ping.md#disabling-usage-ping)
+ 1. [Disable Usage Ping](usage_ping.md#disable-usage-ping)
1. [Usage Ping request flow](usage_ping.md#usage-ping-request-flow)
1. [How Usage Ping works](usage_ping.md#how-usage-ping-works)
1. [Implementing Usage Ping](usage_ping.md#implementing-usage-ping)
- 1. [Developing and testing usage ping](usage_ping.md#developing-and-testing-usage-ping)
+ 1. [Developing and testing Usage Ping](usage_ping.md#developing-and-testing-usage-ping)
[Snowplow Guide](snowplow.md)
@@ -44,27 +50,27 @@ More useful links:
## Our tracking tools
-In this section we will explain the six different technologies we use to gather product usage data.
+We use several different technologies to gather product usage data.
-**Snowplow JS (Frontend)**
+### Snowplow JS (Frontend)
Snowplow is an enterprise-grade marketing and product analytics platform which helps track the way users engage with our website and application. [Snowplow JS](https://github.com/snowplow/snowplow/wiki/javascript-tracker) is a frontend tracker for client-side events.
-**Snowplow Ruby (Backend)**
+### Snowplow Ruby (Backend)
Snowplow is an enterprise-grade marketing and product analytics platform which helps track the way users engage with our website and application. [Snowplow Ruby](https://github.com/snowplow/snowplow/wiki/ruby-tracker) is a backend tracker for server-side events.
-**Usage Ping**
+### Usage Ping
Usage Ping is a method for GitLab Inc to collect usage data on a GitLab instance. Usage Ping is primarily composed of row counts for different tables in the instance’s database. By comparing these counts month over month (or week over week), we can get a rough sense for how an instance is using the different features within the product. This high-level data is used to help our product, support, and sales teams.
-Read more about how this works in the [Usage Ping guide](usage_ping.md)
+For more details, read the [Usage Ping](usage_ping.md) guide.
-**Database import**
+### Database import
Database imports are full imports of data into GitLab's data warehouse. For GitLab.com, the PostgreSQL database is loaded into Snowflake data warehouse every 6 hours. For more details, see the [data team handbook](https://about.gitlab.com/handbook/business-ops/data-team/#extract-and-load).
-**Log system**
+### Log system
System logs are the application logs generated from running the GitLab Rails application. For more details, see the [log system](../../administration/logs.md) and [logging infrastructure](https://gitlab.com/gitlab-com/runbooks/tree/master/logging/doc#logging-infrastructure-overview).
@@ -72,63 +78,63 @@ System logs are the application logs generated from running the GitLab Rails app
Our different tracking tools allows us to track different types of events. The event types and examples of what data can be tracked are outlined below.
-| Event Type | Snowplow JS (Frontend) | Snowplow Ruby (Backend) | Usage Ping | Database import | Log system |
-| ------ | ------ | ------ | ------ | ------ | ------ |
-| Database counts | ⌠| ⌠| ✅ | ✅ | ⌠|
-| Pageview events | ✅ | ✅ | ⌠| ⌠| ⌠|
-| UI events | ✅ | ⌠| ⌠| ⌠| ⌠|
-| CRUD and API events | ⌠| ✅ | ⌠| ⌠| ⌠|
-| Event funnels | ✅ | ✅ | ⌠| ⌠| ⌠|
-| PostgreSQL Data | ⌠| ⌠| ⌠| ✅ | ⌠|
-| Logs | ⌠| ⌠| ⌠| ⌠| ✅ |
-| External services | ⌠| ⌠| ⌠| ⌠| ⌠|
+| Event Type | Snowplow JS (Frontend) | Snowplow Ruby (Backend) | Usage Ping | Database import | Log system |
+|---------------------|------------------------|-------------------------|---------------------|---------------------|---------------------|
+| Database counts | **{dotted-circle}** | **{dotted-circle}** | **{check-circle}** | **{check-circle}** | **{dotted-circle}** |
+| Pageview events | **{check-circle}** | **{check-circle}** | **{dotted-circle}** | **{dotted-circle}** | **{dotted-circle}** |
+| UI events | **{check-circle}** | **{dotted-circle}** | **{dotted-circle}** | **{dotted-circle}** | **{dotted-circle}** |
+| CRUD and API events | **{dotted-circle}** | **{check-circle}** | **{dotted-circle}** | **{dotted-circle}** | **{dotted-circle}** |
+| Event funnels | **{check-circle}** | **{check-circle}** | **{dotted-circle}** | **{dotted-circle}** | **{dotted-circle}** |
+| PostgreSQL Data | **{dotted-circle}** | **{dotted-circle}** | **{dotted-circle}** | **{check-circle}** | **{dotted-circle}** |
+| Logs | **{dotted-circle}** | **{dotted-circle}** | **{dotted-circle}** | **{dotted-circle}** | **{check-circle}** |
+| External services | **{dotted-circle}** | **{dotted-circle}** | **{dotted-circle}** | **{dotted-circle}** | **{dotted-circle}** |
-**Database counts**
+### Database counts
-- How many Projects have been created by unique users
-- How many users logged in the past 28 day
+- Number of Projects created by unique users
+- Number of users logged in the past 28 day
-Database counts are row counts for different tables in an instance’s database. These are SQL count queries which have been filtered, grouped, or aggregated which provide high level usage data. The full list of available tables can be found in [structure.sql](https://gitlab.com/gitlab-org/gitlab/-/blob/master/db/structure.sql)
+Database counts are row counts for different tables in an instance’s database. These are SQL count queries which have been filtered, grouped, or aggregated which provide high level usage data. The full list of available tables can be found in [structure.sql](https://gitlab.com/gitlab-org/gitlab/-/blob/master/db/structure.sql).
-**Pageview events**
+### Pageview events
-- How many sessions visited the /dashboard/groups page
+- Number of sessions that visited the /dashboard/groups page
-**UI Events**
+### UI Events
-- How many sessions clicked on a button or link
-- How many sessions closed a modal
+- Number of sessions that clicked on a button or link
+- Number of sessions that closed a modal
UI events are any interface-driven actions from the browser including click data.
-**CRUD or API events**
+### CRUD or API events
-- How many Git pushes were made
-- How many GraphQL queries were made
-- How many requests were made to a Rails action or controller.
+- Number of Git pushes
+- Number of GraphQL queries
+- Number of requests to a Rails action or controller
-These are backend events that include the creation, read, update, deletion of records and other events that might be triggered from layers that aren't necessarily only available in the interface.
+These are backend events that include the creation, read, update, deletion of records, and other events that might be triggered from layers other than those available in the interface.
-**Event funnels**
+### Event funnels
-- How many sessions performed action A, B, then C
-- What is our conversion rate from step A to B?
+- Number of sessions that performed action A, B, then C
+- Conversion rate from step A to B
-**PostgreSQL data**
+### PostgreSQL data
-These are raw database records which can be explored using business intelligence tools like Sisense. The full list of available tables can be found in [structure.sql](https://gitlab.com/gitlab-org/gitlab/-/blob/master/db/structure.sql)
+These are raw database records which can be explored using business intelligence tools like Sisense. The full list of available tables can be found in [structure.sql](https://gitlab.com/gitlab-org/gitlab/-/blob/master/db/structure.sql).
-**Logs**
+### Logs
These are raw logs such as the [Production logs](../../administration/logs.md#production_jsonlog), [API logs](../../administration/logs.md#api_jsonlog), or [Sidekiq logs](../../administration/logs.md#sidekiqlog). See the [overview of Logging Infrastructure](https://gitlab.com/gitlab-com/runbooks/tree/master/logging/doc#logging-infrastructure-overview) for more details.
-**External services**
+### External services
These are external services a GitLab instance interacts with such as an [external storage provider](../../administration/static_objects_external_storage.md) or an [external container registry](../../administration/packages/container_registry.md#use-an-external-container-registry-with-gitlab-as-an-auth-endpoint). These services must be able to send data back into a GitLab instance for data to be tracked.
## Telemetry systems overview
-The systems overview is a simplified diagram showing the interactions between GitLab Inc and self-managed nstances.
+The systems overview is a simplified diagram showing the interactions between GitLab Inc and self-managed instances.
![Telemetry_Overview](../img/telemetry_system_overview.png)
@@ -140,7 +146,7 @@ For Telemetry purposes, GitLab Inc has three major components:
1. [Data Infrastructure](https://about.gitlab.com/handbook/business-ops/data-team/data-infrastructure/): This contains everything managed by our data team including Sisense Dashboards for visualization, Snowflake for Data Warehousing, incoming data sources such as PostgreSQL Pipeline and S3 Bucket, and lastly our data collectors [GitLab.com's Snowplow Collector](https://about.gitlab.com/handbook/engineering/infrastructure/library/snowplow/) and GitLab's Versions Application.
1. GitLab.com: This is the production GitLab application which is made up of a Client and Server. On the Client or browser side, a Snowplow JS Tracker (Frontend) is used to track client-side events. On the Server or application side, a Snowplow Ruby Tracker (Backend) is used to track server-side events. The server also contains Usage Ping which leverages a PostgreSQL database and a Redis in-memory data store to report on usage data. Lastly, the server also contains System Logs which are generated from running the GitLab application.
-1. [Monitoring infrastructure](https://about.gitlab.com/handbook/engineering/monitoring/): This is the infrastructure used to ensure GitLab.com is operating smoothly. System Logs are sent from GitLab.com to our monitoring infrastructure and collected by a FluentD collector. From FluentD, logs are either sent to long term Google Cloud Services cold storage via Stackdriver, or, they are sent to our Elastic Cluster via Cloud Pub/Sub which can be explored in real-time using Kibana
+1. [Monitoring infrastructure](https://about.gitlab.com/handbook/engineering/monitoring/): This is the infrastructure used to ensure GitLab.com is operating smoothly. System Logs are sent from GitLab.com to our monitoring infrastructure and collected by a FluentD collector. From FluentD, logs are either sent to long term Google Cloud Services cold storage via Stackdriver, or, they are sent to our Elastic Cluster via Cloud Pub/Sub which can be explored in real-time using Kibana.
### Self-managed
@@ -151,15 +157,15 @@ For Telemetry purposes, self-managed instances have two major components:
### Differences between GitLab Inc and Self-managed
-As shown by the orange lines, on GitLab.com Snowplow JS, Snowplow Ruby, Usage Ping, and PostgreSQL database imports all flow into GitLab Inc's data fnfrastructure. However, on self-managed, only Usage Ping flows into GitLab Inc's data infrastructure.
+As shown by the orange lines, on GitLab.com Snowplow JS, Snowplow Ruby, Usage Ping, and PostgreSQL database imports all flow into GitLab Inc's data infrastructure. However, on self-managed, only Usage Ping flows into GitLab Inc's data infrastructure.
As shown by the green lines, on GitLab.com system logs flow into GitLab Inc's monitoring infrastructure. On self-managed, there are no logs sent to GitLab Inc's monitoring infrastructure.
The differences between GitLab.com and self-managed are summarized below:
-| Environment | Snowplow JS (Frontend) | Snowplow Ruby (Backend) | Usage Ping | Database import | Logs system |
-| ------ | ------ | ------ | ------ | ------ | ------ |
-| GitLab.com | ✅ | ✅ | ✅ | ✅ | ✅ |
-| Self-Managed | âŒ(1) | âŒ(1) | ✅ | ⌠| ⌠|
+| Environment | Snowplow JS (Frontend) | Snowplow Ruby (Backend) | Usage Ping | Database import | Logs system |
+|--------------|------------------------|-------------------------|--------------------|---------------------|---------------------|
+| GitLab.com | **{check-circle}** | **{check-circle}** | **{check-circle}** | **{check-circle}** | **{check-circle}** |
+| Self-Managed | **{dotted-circle}**(1) | **{dotted-circle}**(1) | **{check-circle}** | **{dotted-circle}** | **{dotted-circle}** |
Note (1): Snowplow JS and Snowplow Ruby are available on self-managed, however, the Snowplow Collector endpoint is set to a self-managed Snowplow Collector which GitLab Inc does not have access to.
diff --git a/doc/development/telemetry/snowplow.md b/doc/development/telemetry/snowplow.md
index aeaad6e5624..b7090ee4d20 100644
--- a/doc/development/telemetry/snowplow.md
+++ b/doc/development/telemetry/snowplow.md
@@ -1,3 +1,9 @@
+---
+stage: Growth
+group: Telemetry
+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
+---
+
# Snowplow Guide
This guide provides a details about how Snowplow works. It includes the following sections:
@@ -40,7 +46,7 @@ From [Snowplow's documentation](https://github.com/snowplow/snowplow), Snowplow
## Snowplow schema
-We currently have many definitions of Snowplow's schema. We have an active issue to [standardize this schema](https://gitlab.com/gitlab-org/gitlab/issues/207930) including the following definitions:
+We currently have many definitions of Snowplow's schema. We have an active issue to [standardize this schema](https://gitlab.com/gitlab-org/gitlab/-/issues/207930) including the following definitions:
- Frontend and backend taxonomy as listed below
- [Feature instrumentation taxonomy](https://about.gitlab.com/handbook/product/feature-instrumentation/#taxonomy)
@@ -121,7 +127,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 for them to be properly handled on rerendering and changes to the DOM, but it's important to know that because of the way these events are bound, click events shouldn't be stopped from propagating up the DOM tree. If for any reason click events are being stopped from propagating, you'll need to implement your own listeners and follow the instructions in [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 for them to be properly handled on re-rendering and changes to the DOM, but it's important to know that because of the way these events are bound, click events shouldn't be stopped from propagating up the DOM tree. If for any reason click events are being stopped from propagating, you'll need to implement your own listeners and follow the instructions in [Tracking in raw JavaScript](#tracking-in-raw-javascript).
Below is a list of supported `data-track-*` attributes:
@@ -213,7 +219,7 @@ button.addEventListener('click', () => {
### Tests and test helpers
-In Jest particularly in vue tests, you can use the following:
+In Jest particularly in Vue tests, you can use the following:
```javascript
import { mockTracking } from 'helpers/tracking_helper';
@@ -330,10 +336,10 @@ 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 need to 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 repo](https://github.com/snowplow-incubator/snowplow-micro)
+- Look at the [Snowplow Micro repository](https://github.com/snowplow-incubator/snowplow-micro)
- Watch our [installation guide recording](https://www.youtube.com/watch?v=OX46fo_A0Ag)
1. Install [Snowplow Micro](https://github.com/snowplow-incubator/snowplow-micro)
diff --git a/doc/development/telemetry/usage_ping.md b/doc/development/telemetry/usage_ping.md
index e9b959eaa96..0f438e02772 100644
--- a/doc/development/telemetry/usage_ping.md
+++ b/doc/development/telemetry/usage_ping.md
@@ -1,19 +1,17 @@
-# Usage Ping Guide
+---
+stage: Growth
+group: Telemetry
+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
+---
-> - [Introduced][ee-557] in GitLab Enterprise Edition 8.10.
-> - More statistics [were added][ee-735] in GitLab Enterprise Edition 8.12.
-> - [Moved to GitLab Core][ce-23361] in 9.1.
-> - More statistics [were added][ee-6602] in GitLab Ultimate 11.2.
+# Usage Ping Guide
-This guide provides a details about how usage ping works. It includes the following sections:
+> - Introduced in GitLab Enterprise Edition 8.10.
+> - More statistics were added in GitLab Enterprise Edition 8.12.
+> - Moved to GitLab Core in 9.1.
+> - More statistics were added in GitLab Ultimate 11.2.
-1. [What is Usage Ping](#what-is-usage-ping)
-1. [Usage Ping payload](#usage-ping-payload)
-1. [Disabling Usage Ping](#disabling-usage-ping)
-1. [Usage Ping request flow](#usage-ping-request-flow)
-1. [How Usage Ping works](#how-usage-ping-works)
-1. [Implementing Usage Ping](#implementing-usage-ping)
-1. [Developing and testing usage ping](#developing-and-testing-usage-ping)
+This guide describes Usage Ping's purpose and how it's implemented.
For more information about Telemetry, see:
@@ -27,237 +25,50 @@ More useful links:
- [Data for Product Managers](https://about.gitlab.com/handbook/business-ops/data-team/data-for-product-managers/)
- [Data Infrastructure](https://about.gitlab.com/handbook/business-ops/data-team/data-infrastructure/)
-## What is Usage Ping
+## What is Usage Ping?
-- GitLab sends a weekly payload containing usage data to GitLab Inc. The usage ping uses high-level data to help our product, support, and sales teams. It does not send any project names, usernames, or any other specific data. The information from the usage ping is not anonymous, it is linked to the hostname of the instance. Sending usage ping is optional, and any instance can disable analytics.
-- The usage data is primarily composed of row counts for different tables in the instance’s database. By comparing these counts month over month (or week over week), we can get a rough sense for how an instance is using the different features within the product.
-- Usage ping is important to GitLab as we use it to calculate our and Stage Monthly Active Users (SMAU) which helps us measure the success of our stages and features.
+- GitLab sends a weekly payload containing usage data to GitLab Inc. Usage Ping provides high-level data to help our product, support, and sales teams. It does not send any project names, usernames, or any other specific data. The information from the usage ping is not anonymous, it is linked to the hostname of the instance. Sending usage ping is optional, and any instance can disable analytics.
+- The usage data is primarily composed of row counts for different tables in the instance’s database. By comparing these counts month over month (or week over week), we can get a rough sense for how an instance is using the different features within the product. In addition to counts, other facts
+ that help us classify and understand GitLab installations are collected.
+- Usage ping is important to GitLab as we use it to calculate our Stage Monthly Active Users (SMAU) which helps us measure the success of our stages and features.
- Once usage ping is enabled, GitLab will gather data from the other instances and will be able to show usage statistics of your instance to your users.
-### Why Should We Enable Usage Ping?
+### Why should we enable Usage Ping?
-- The main purpose of Usage Ping is to build a better GitLab. Data about how GitLab is used is collected to better understand feature/stage adoption and usage, which helps us understand how GitLab is adding value and helps our team better understand the reasons why people use GitLab and with this knowledge we are able to make better product decisions.
+- The main purpose of Usage Ping is to build a better GitLab. Data about how GitLab is used is collected to better understand feature/stage adoption and usage, which helps us understand how GitLab is adding value and helps our team better understand the reasons why people use GitLab and with this knowledge we're able to make better product decisions.
- As a benefit of having the usage ping active, GitLab lets you analyze the users’ activities over time of your GitLab installation.
- As a benefit of having the usage ping active, GitLab provides you with The DevOps Score,which gives you an overview of your entire instance’s adoption of Concurrent DevOps from planning to monitoring.
- You will get better, more proactive support. (assuming that our TAMs and support organization used the data to deliver more value)
- You will get insight and advice into how to get the most value out of your investment in GitLab. Wouldn't you want to know that a number of features or values are not being adopted in your organization?
- You get a report that illustrates how you compare against other similar organizations (anonymized), with specific advice and recommendations on how to improve your DevOps processes.
+- Usage Ping is enabled by default. To disable it, see [Disable Usage Ping](#disable-usage-ping).
### Limitations
-- Usage Ping does not track frontend events things like page views, link clicks, or user sessions and only focuses on aggregated backend events.
+- Usage Ping does not track frontend events things like page views, link clicks, or user sessions, and only focuses on aggregated backend events.
- Because of these limitations we recommend instrumenting your products with Snowplow for more detailed analytics on GitLab.com and use Usage Ping to track aggregated backend events on self-managed.
## Usage Ping payload
You can view the exact JSON payload sent to GitLab Inc. in the administration panel. To view the payload:
-1. Navigate to the **Admin Area > Settings > Metrics and profiling**.
+1. Navigate to **Admin Area > Settings > Metrics and profiling**.
1. Expand the **Usage statistics** section.
1. Click the **Preview payload** button.
-Here is an example of the payload structure
-
-``` json
-{
- "uuid": "0000000-0000-0000-0000-000000000000",
- "hostname": "example.com",
- "version": "12.10.0-pre",
- "installation_type": "omnibus-gitlab",
- "active_user_count": 999,
- "recorded_at": "2020-04-17T07:43:54.162+00:00",
- "edition": "EEU",
- "license_md5": "00000000000000000000000000000000",
- "license_id": null,
- "historical_max_users": 999,
- "licensee": {
- "Name": "ABC, Inc.",
- "Email": "email@example.com",
- "Company": "ABC, Inc."
- },
- "license_user_count": 999,
- "license_starts_at": "2020-01-01",
- "license_expires_at": "2021-01-01",
- "license_plan": "ultimate",
- "license_add_ons": {
- },
- "license_trial": false,
- "counts": {
- "assignee_lists": 999,
- "boards": 999,
- "ci_builds": 999,
- ...
- },
- "container_registry_enabled": true,
- "dependency_proxy_enabled": false,
- "gitlab_shared_runners_enabled": true,
- "gravatar_enabled": true,
- "influxdb_metrics_enabled": true,
- "ldap_enabled": false,
- "mattermost_enabled": false,
- "omniauth_enabled": true,
- "prometheus_metrics_enabled": false,
- "reply_by_email_enabled": "incoming+%{key}@incoming.gitlab.com",
- "signup_enabled": true,
- "web_ide_clientside_preview_enabled": true,
- "ingress_modsecurity_enabled": true,
- "projects_with_expiration_policy_disabled": 999,
- "projects_with_expiration_policy_enabled": 999,
- ...
- "elasticsearch_enabled": true,
- "license_trial_ends_on": null,
- "geo_enabled": false,
- "git": {
- "version": {
- "major": 2,
- "minor": 26,
- "patch": 1
- }
- },
- "gitaly": {
- "version": "12.10.0-rc1-93-g40980d40",
- "servers": 56,
- "filesystems": [
- "EXT_2_3_4"
- ]
- },
- "gitlab_pages": {
- "enabled": true,
- "version": "1.17.0"
- },
- "database": {
- "adapter": "postgresql",
- "version": "9.6.15"
- },
- "app_server": {
- "type": "console"
- },
- "avg_cycle_analytics": {
- "issue": {
- "average": 999,
- "sd": 999,
- "missing": 999
- },
- "plan": {
- "average": null,
- "sd": 999,
- "missing": 999
- },
- "code": {
- "average": null,
- "sd": 999,
- "missing": 999
- },
- "test": {
- "average": null,
- "sd": 999,
- "missing": 999
- },
- "review": {
- "average": null,
- "sd": 999,
- "missing": 999
- },
- "staging": {
- "average": null,
- "sd": 999,
- "missing": 999
- },
- "production": {
- "average": null,
- "sd": 999,
- "missing": 999
- },
- "total": 999
- },
- "usage_activity_by_stage": {
- "configure": {
- "project_clusters_enabled": 999,
- ...
- },
- "create": {
- "merge_requests": 999,
- ...
- },
- "manage": {
- "events": 999,
- ...
- },
- "monitor": {
- "clusters": 999,
- ...
- },
- "package": {
- "projects_with_packages": 999
- },
- "plan": {
- "issues": 999,
- ...
- },
- "release": {
- "deployments": 999,
- ...
- },
- "secure": {
- "user_container_scanning_jobs": 999,
- ...
- },
- "verify": {
- "ci_builds": 999,
- ...
- }
- },
- "usage_activity_by_stage_monthly": {
- "configure": {
- "project_clusters_enabled": 999,
- ...
- },
- "create": {
- "merge_requests": 999,
- ...
- },
- "manage": {
- "events": 999,
- ...
- },
- "monitor": {
- "clusters": 999,
- ...
- },
- "package": {
- "projects_with_packages": 999
- },
- "plan": {
- "issues": 999,
- ...
- },
- "release": {
- "deployments": 999,
- ...
- },
- "secure": {
- "user_container_scanning_jobs": 999,
- ...
- },
- "verify": {
- "ci_builds": 999,
- ...
- }
- }
-}
-```
+For an example payload, see [Example Usage Ping payload](#example-usage-ping-payload).
-## Disabling usage ping
+## Disable Usage Ping
-The usage ping is opt-out. If you want to deactivate this feature, go to the Settings page of your administration panel and uncheck the Usage Ping checkbox.
+To disable Usage Ping in the GitLab UI, go to the **Settings** page of your administration panel and uncheck the **Usage Ping** checkbox.
-To disable the usage ping and prevent it from being configured in future through the administration panel, Omnibus installs can set the following in [`gitlab.rb`](https://docs.gitlab.com/omnibus/settings/configuration.html#configuration-options):
+To disable Usage Ping and prevent it from being configured in the future through the administration panel, Omnibus installs can set the following in [`gitlab.rb`](https://docs.gitlab.com/omnibus/settings/configuration.html#configuration-options):
```ruby
gitlab_rails['usage_ping_enabled'] = false
```
-And source installs can set the following in `gitlab.yml`:
+Source installations can set the following in `gitlab.yml`:
```yaml
production: &base
@@ -267,9 +78,9 @@ production: &base
usage_ping_enabled: false
```
-## Usage Ping Request Flow
+## Usage Ping request flow
-The following example shows a basic request/response flow between a GitLab Instance, the Versions Application, the License Application, Salesforce, GitLab's S3 Bucket, GitLab's Snowflake Data Warehouse, and Sisense.:
+The following example shows a basic request/response flow between a GitLab instance, the Versions Application, the License Application, Salesforce, GitLab's S3 Bucket, GitLab's Snowflake Data Warehouse, and Sisense:
```mermaid
sequenceDiagram
@@ -303,34 +114,40 @@ sequenceDiagram
## How Usage Ping works
1. The Usage Ping [cron job](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/workers/gitlab_usage_ping_worker.rb#L30) is set in Sidekiq to run weekly.
-1. When the cron job runs, it calls [GitLab::UsageData.to_json](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/services/submit_usage_ping_service.rb#L22).
-1. GitLab::UsageData.to_json [cascades down](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data.rb#L22) to ~400+ other counter method calls.
-1. The response of all methods calls are [merged together](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data.rb#L14) into a single JSON payload in GitLab::UsageData.to_json.
+1. When the cron job runs, it calls [`GitLab::UsageData.to_json`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/services/submit_usage_ping_service.rb#L22).
+1. `GitLab::UsageData.to_json` [cascades down](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data.rb#L22) to ~400+ other counter method calls.
+1. The response of all methods calls are [merged together](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data.rb#L14) into a single JSON payload in `GitLab::UsageData.to_json`.
1. The JSON payload is then [posted to the Versions application]( https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/services/submit_usage_ping_service.rb#L20).
## Implementing Usage Ping
-Usage Ping consists of four types of counters which are all found in `usage_data.rb`:
+Usage 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.
+
+There are four types of counters which are all found in `usage_data.rb`:
- **Ordinary Batch Counters:** Simple count of a given ActiveRecord_Relation
- **Distinct Batch Counters:** Distinct count of a given ActiveRecord_Relation on given column
- **Alternative Counters:** Used for settings and configurations
- **Redis Counters:** Used for in-memory counts. This method is being deprecated due to data inaccuracies and will be replaced with a persistent method.
-Note: Only use the provided counter methods. Each counter method contains a built in fail safe to isolate each counter to avoid breaking the entire Usage Ping.
+NOTE: **Note:**
+Only use the provided counter methods. Each counter method contains a built in fail safe to isolate each counter to avoid breaking the entire Usage Ping.
### Why 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:
+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 |
+| Table | Row counts in millions |
+|------------------------------|------------------------|
+| `merge_request_diff_commits` | 2280 |
+| `ci_build_trace_sections` | 1764 |
+| `merge_request_diff_files` | 1082 |
+| `events` | 514 |
There are two batch counting methods provided, `Ordinary Batch Counters` and `Distinct Batch Counters`. Batch counting requires indexes on columns to calculate max, min, and range queries. In some cases, a specialized index may need to be added on the columns involved in a counter.
@@ -393,7 +210,7 @@ Method: `redis_usage_data(counter, &block)`
Arguments:
- `counter`: a counter from `Gitlab::UsageDataCounters`, that has `fallback_totals` method implemented
-- or a `block`: wich is evaluated
+- or a `block`: which is evaluated
Example of usage:
@@ -413,8 +230,8 @@ Method: `alt_usage_data(value = nil, fallback: -1, &block)`
Arguments:
-- `value`: a simple static value in wich case the value is simply returned.
-- or a `block`: wich is evaluated
+- `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 of usage:
@@ -425,6 +242,29 @@ alt_usage_data { Gitlab::CurrentSettings.uuid }
alt_usage_data(999)
```
+### Prometheus Queries
+
+In those cases where operational metrics should be part of Usage Ping, a database or Redis query is unlikely
+to provide useful data. Instead, Prometheus might be more appropriate, since most of GitLab's architectural
+components publish metrics to it that can be queried back, aggregated, and included as usage data.
+
+NOTE: **Note:**
+Prometheus as a data source for Usage Ping is currently only available for single-node Omnibus installations
+that are running the [bundled Prometheus](../../administration/monitoring/prometheus/index.md) instance.
+
+In order to query Prometheus for metrics, a helper method is available that will `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
+```
+
+Please 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.
+
## Developing and testing Usage Ping
### 1. Use your Rails console to manually test counters
@@ -441,49 +281,591 @@ Gitlab::UsageData.distinct_count(::Note.with_suggestions.where(time_period), :au
### 2. Generate the SQL query
-Your Rails console will give back the generated SQL queries.
+Your Rails console will return the generated SQL queries.
Example:
```ruby
- pry(main)> Gitlab::UsageData.count(User.active)
- (0.4ms) SELECT "features"."key" FROM "features"
- (0.7ms) SELECT MIN("users"."id") FROM "users" WHERE ("users"."state" IN ('active')) AND (ghost IS NOT TRUE) AND ("users"."user_type" IS NULL OR "users"."user_type" NOT IN (2, 1, 3))
- (0.6ms) SELECT MAX("users"."id") FROM "users" WHERE ("users"."state" IN ('active')) AND (ghost IS NOT TRUE) AND ("users"."user_type" IS NULL OR "users"."user_type" NOT IN (2, 1, 3))
- (0.5ms) SELECT COUNT("users"."id") FROM "users" WHERE ("users"."state" IN ('active')) AND (ghost IS NOT TRUE) AND ("users"."user_type" IS NULL OR "users"."user_type" NOT IN (2, 1, 3)) AND "users"."id" BETWEEN 0 AND 99999
+pry(main)> Gitlab::UsageData.count(User.active)
+ (2.6ms) SELECT "features"."key" FROM "features"
+ (15.3ms) SELECT MIN("users"."id") FROM "users" WHERE ("users"."state" IN ('active')) AND ("users"."user_type" IS NULL OR "users"."user_type" IN (6, 4))
+ (2.4ms) SELECT MAX("users"."id") FROM "users" WHERE ("users"."state" IN ('active')) AND ("users"."user_type" IS NULL OR "users"."user_type" IN (6, 4))
+ (1.9ms) SELECT COUNT("users"."id") FROM "users" WHERE ("users"."state" IN ('active')) AND ("users"."user_type" IS NULL OR "users"."user_type" IN (6, 4)) AND "users"."id" BETWEEN 1 AND 100000
```
### 3. Optimize queries with #database-lab
Paste the SQL query into `#database-lab` to see how the query performs at scale.
-- #database-lab is a Slack channel which uses a production-sized environment to test your queries
+- `#database-lab` is a Slack channel which uses a production-sized environment to test your queries.
- GitLab.com’s production database has a 15 second timeout.
-- For each query we require an execution time of under 1 second due do cold caches which can 10x this time.
-- Add a specialized index on columns involved to reduce your the execution time.
-
-In order to have an understanding of the queries execution we add in the MR description the following information
-
-For counters that have a `time_period` test and add information for both cases.
-
-- with `time_period = {}` for all time period
-- and `time_period = { created_at: 28.days.ago..Time.current }` for last 28 days period
-
-Execution plan and query time before and after optimization
-
-Using database-lab and [explain.depesz.com](https://explain.depesz.com/) see more details in [database review guide](../database_review.md#preparation-when-adding-or-modifying-queries)
+- For each query we require an execution time of under 1 second due to cold caches which can 10x this time.
+- Add a specialized index on columns involved to reduce the execution time.
-Query generated for the index and time
+In order to have an understanding of the query's execution we add in the MR description the following information:
-Using database-lab
+- For counters that have a `time_period` test we add information for both cases:
+ - `time_period = {}` for all time periods
+ - `time_period = { created_at: 28.days.ago..Time.current }` for last 28 days period
+- Execution plan and query time before and after optimization
+- Query generated for the index and time
+- Migration output for up and down execution
-Migration output for up and down execution
+We also use `#database-lab` and [explain.depesz.com](https://explain.depesz.com/). For more details, see the [database review guide](../database_review.md#preparation-when-adding-or-modifying-queries).
Examples of query optimization work:
- [Example 1](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26445)
- [Example 2](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26871)
-### 4. Ask for a Telemetry Review
-
-On GitLab.com, we have DangerBot setup to monitor Telemetry related files and DangerBot will recommend a Telemetry review. Simply `@gitlab-org/growth/telemetry/engineers` in your MR for a review.
+### 4. Add the metric definition
+
+When adding, changing, or updating metrics, please update the [Usage Statistics definition table](#usage-statistics-definitions).
+
+### 5. Add new metric to Versions Application
+
+Check if new metrics need to be added to the Versions Application. See `usage_data` [schema](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/master/db/schema.rb#L147) and usage data [parameters accepted](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/master/app/services/usage_ping.rb). Any metrics added under the `counts` key are saved in the `counts` column.
+
+### 6. Ask for a Telemetry Review
+
+On GitLab.com, we have DangerBot setup to monitor Telemetry related files and DangerBot will recommend a Telemetry review. Mention `@gitlab-org/growth/telemetry/engineers` in your MR for a review.
+
+### Optional: Test Prometheus based Usage Ping
+
+If the data submitted includes metrics [queried from Prometheus](#prometheus-queries) that you would like to inspect and verify,
+then you need to ensure that a Prometheus server is running locally, and that furthermore the respective GitLab components
+are exporting metrics to it. If you do not need to test data coming from Prometheus, no further action
+is necessary, since Usage Ping should degrade gracefully in the absence of a running Prometheus server.
+
+There are currently three kinds of components that may export data to Prometheus, and which are included in Usage Ping:
+
+- [`node_exporter`](https://github.com/prometheus/node_exporter) - Exports node metrics from the host machine
+- [`gitlab-exporter`](https://gitlab.com/gitlab-org/gitlab-exporter) - Exports process metrics from various GitLab components
+- various GitLab services such as Sidekiq and the Rails server that export their own metrics
+
+#### Test with an Omnibus container
+
+This is the recommended approach to test Prometheus based Usage Ping.
+
+The easiest way to verify your changes is to build a new Omnibus image from your code branch via CI, then download the image
+and run a local container instance:
+
+1. From your merge request, click on the `qa` stage, then trigger the `package-and-qa` job. This job will trigger an Omnibus
+build in a [downstream pipeline of the `omnibus-gitlab-mirror` project](https://gitlab.com/gitlab-org/build/omnibus-gitlab-mirror/-/pipelines).
+1. In the downstream pipeline, wait for the `gitlab-docker` job to finish.
+1. Open the job logs and locate the full container name including the version. It will take the following form: `registry.gitlab.com/gitlab-org/build/omnibus-gitlab-mirror/gitlab-ee:<VERSION>`.
+1. On your local machine, make sure you are logged in to the GitLab Docker registry. You can find the instructions for this in
+[Authenticating to the GitLab Container Registry](../../user/packages/container_registry/index.md#authenticating-to-the-gitlab-container-registry).
+1. Once logged in, download the new image via `docker pull registry.gitlab.com/gitlab-org/build/omnibus-gitlab-mirror/gitlab-ee:<VERSION>`
+1. For more information about working with and running Omnibus GitLab containers in Docker, please refer to [GitLab Docker images](https://docs.gitlab.com/omnibus/docker/README.html) in the Omnibus documentation.
+
+#### Test with GitLab development toolkits
+
+This is the less recommended approach, since it comes with a number of difficulties when emulating a real GitLab deployment.
+
+The [GDK](https://gitlab.com/gitlab-org/gitlab-development-kit) is not currently set up to run a Prometheus server or `node_exporter` alongside other GitLab components. If you would
+like to do so, [Monitoring the GDK with Prometheus](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/master/doc/howto/prometheus/index.md#monitoring-the-gdk-with-prometheus) is a good start.
+
+The [GCK](https://gitlab.com/gitlab-org/gitlab-compose-kit) has limited support for testing Prometheus based Usage Ping.
+By default, it already comes with a fully configured Prometheus service that is set up to scrape a number of components,
+but with the following limitations:
+
+- It does not currently run a `gitlab-exporter` instance, so several `process_*` metrics from services such as Gitaly may be missing.
+- While it runs a `node_exporter`, `docker-compose` services emulate hosts, meaning that it would normally report itself to not be associated
+with any of the other services that are running. 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. From Usage Ping's perspective none of the node data would therefore
+appear to be associated to any of the services running, since 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 will appear in Usage Ping.
+
+## Usage Statistics definitions
+
+| Statistic | Section | Stage | Tier | Description |
+|:--------------------------------------------------------|:-----------------------------------|:------------|:---------------|:--------------------------------------------------|
+| `uuid` | | | | |
+| `hostname` | | | | |
+| `version` | | | | |
+| `installation_type` | | | | |
+| `active_user_count` | | | | |
+| `recorded_at` | | | | |
+| `edition` | | | | |
+| `license_md5` | | | | |
+| `license_id` | | | | |
+| `historical_max_users` | | | | |
+| `Name` | `licensee` | | | |
+| `Email` | `licensee` | | | |
+| `Company` | `licensee` | | | |
+| `license_user_count` | | | | |
+| `license_starts_at` | | | | |
+| `license_expires_at` | | | | |
+| `license_plan` | | | | |
+| `license_trial` | | | | |
+| `assignee_lists` | `counts` | | | |
+| `boards` | `counts` | | | |
+| `ci_builds` | `counts` | `verify` | | Unique builds in project |
+| `ci_internal_pipelines` | `counts` | `verify` | | Total pipelines in GitLab repositories |
+| `ci_external_pipelines` | `counts` | `verify` | | Total pipelines in external repositories |
+| `ci_pipeline_config_auto_devops` | `counts` | `verify` | | Total pipelines from an Auto DevOps template |
+| `ci_pipeline_config_repository` | `counts` | `verify` | | Total Pipelines from templates in repository |
+| `ci_runners` | `counts` | `verify` | | Total configured Runners in project |
+| `ci_triggers` | `counts` | `verify` | | Total configured Triggers in project |
+| `ci_pipeline_schedules` | `counts` | `verify` | | Pipeline schedules in GitLab |
+| `auto_devops_enabled` | `counts` |`configure` | | Projects with Auto DevOps template enabled |
+| `auto_devops_disabled` | `counts` |`configure` | | Projects with Auto DevOps template disabled |
+| `deploy_keys` | `counts` | | | |
+| `deployments` | `counts` |`release` | | Total deployments |
+| `dast_jobs` | `counts` | | | |
+| `successful_deployments` | `counts` |`release` | | Total successful deployments |
+| `failed_deployments` | `counts` |`release` | | Total failed deployments |
+| `environments` | `counts` |`release` | | Total available and stopped environments |
+| `clusters` | `counts` |`configure` | | Total GitLab Managed clusters both enabled and disabled |
+| `clusters_enabled` | `counts` |`configure` | | Total GitLab Managed clusters currently enabled |
+| `project_clusters_enabled` | `counts` |`configure` | | Total GitLab Managed clusters attached to projects|
+| `group_clusters_enabled` | `counts` |`configure` | | Total GitLab Managed clusters attached to groups |
+| `instance_clusters_enabled` | `counts` |`configure` | | Total GitLab Managed clusters attached to the instance |
+| `clusters_disabled` | `counts` |`configure` | | Total GitLab Managed disabled clusters |
+| `project_clusters_disabled` | `counts` |`configure` | | Total GitLab Managed disabled clusters previously attached to projects |
+| `group_clusters_disabled` | `counts` |`configure` | | Total GitLab Managed disabled clusters previously attached to groups |
+| `instance_clusters_disabled` | `counts` |`configure` | | Total GitLab Managed disabled clusters previously attached to the instance |
+| `clusters_platforms_eks` | `counts` |`configure` | | Total GitLab Managed clusters provisioned with GitLab on AWS EKS |
+| `clusters_platforms_gke` | `counts` |`configure` | | Total GitLab Managed clusters provisioned with GitLab on GCE GKE |
+| `clusters_platforms_user` | `counts` |`configure` | | Total GitLab Managed clusters that are user provisioned |
+| `clusters_applications_helm` | `counts` |`configure` | | Total GitLab Managed clusters with Helm enabled |
+| `clusters_applications_ingress` | `counts` |`configure` | | Total GitLab Managed clusters with Ingress enabled |
+| `clusters_applications_cert_managers` | `counts` |`configure` | | Total GitLab Managed clusters with Cert Manager enabled |
+| `clusters_applications_crossplane` | `counts` |`configure` | | Total GitLab Managed clusters with Crossplane enabled |
+| `clusters_applications_prometheus` | `counts` |`configure` | | Total GitLab Managed clusters with Prometheus enabled |
+| `clusters_applications_runner` | `counts` |`configure` | | Total GitLab Managed clusters with Runner enabled |
+| `clusters_applications_knative` | `counts` |`configure` | | Total GitLab Managed clusters with Knative enabled |
+| `clusters_applications_elastic_stack` | `counts` |`configure` | | Total GitLab Managed clusters with Elastic Stack enabled |
+| `clusters_management_project` | `counts` |`configure` | | Total GitLab Managed clusters with defined cluster management project |
+| `in_review_folder` | `counts` | | | |
+| `grafana_integrated_projects` | `counts` | | | |
+| `groups` | `counts` | | | |
+| `issues` | `counts` | | | |
+| `issues_created_from_gitlab_error_tracking_ui` | `counts` | `monitor` | | |
+| `issues_with_associated_zoom_link` | `counts` | `monitor` | | |
+| `issues_using_zoom_quick_actions` | `counts` | `monitor` | | |
+| `issues_with_embedded_grafana_charts_approx` | `counts` | `monitor` | | |
+| `issues_with_health_status` | `counts` | | | |
+| `keys` | `counts` | | | |
+| `label_lists` | `counts` | | | |
+| `lfs_objects` | `counts` | | | |
+| `milestone_lists` | `counts` | | | |
+| `milestones` | `counts` | | | |
+| `pages_domains` | `counts` |`release` | | Total GitLab Pages domains |
+| `pool_repositories` | `counts` | | | |
+| `projects` | `counts` | | | |
+| `projects_imported_from_github` | `counts` | | | |
+| `projects_with_repositories_enabled` | `counts` | | | |
+| `projects_with_error_tracking_enabled` | `counts` | `monitor` | | |
+| `protected_branches` | `counts` | | | |
+| `releases` | `counts` |`release` | | Unique release tags |
+| `remote_mirrors` | `counts` | | | |
+| `requirements_created` | `counts` | | | |
+| `snippets` | `counts` | | | |
+| `suggestions` | `counts` | | | |
+| `todos` | `counts` | | | |
+| `uploads` | `counts` | | | |
+| `web_hooks` | `counts` | | | |
+| `projects_alerts_active` | `counts` | | | |
+| `projects_asana_active` | `counts` | | | |
+| `projects_assembla_active` | `counts` | | | |
+| `projects_bamboo_active` | `counts` | | | |
+| `projects_bugzilla_active` | `counts` | | | |
+| `projects_buildkite_active` | `counts` | | | |
+| `projects_campfire_active` | `counts` | | | |
+| `projects_custom_issue_tracker_active` | `counts` | | | |
+| `projects_discord_active` | `counts` | | | |
+| `projects_drone_ci_active` | `counts` | | | |
+| `projects_emails_on_push_active` | `counts` | | | |
+| `projects_external_wiki_active` | `counts` | | |
+| `projects_flowdock_active` | `counts` | | | |
+| `projects_github_active` | `counts` | | | |
+| `projects_hangouts_chat_active` | `counts` | | | |
+| `projects_hipchat_active` | `counts` | | | |
+| `projects_irker_active` | `counts` | | | |
+| `projects_jenkins_active` | `counts` | | | |
+| `projects_jira_active` | `counts` | | | |
+| `projects_mattermost_active` | `counts` | | | |
+| `projects_mattermost_slash_commands_active` | `counts` | | | |
+| `projects_microsoft_teams_active` | `counts` | | | |
+| `projects_packagist_active` | `counts` | | | |
+| `projects_pipelines_email_active` | `counts` | | | |
+| `projects_pivotaltracker_active` | `counts` | | | |
+| `projects_prometheus_active` | `counts` | | | |
+| `projects_pushover_active` | `counts` | | | |
+| `projects_redmine_active` | `counts` | | | |
+| `projects_slack_active` | `counts` | | | |
+| `projects_slack_slash_commands_active` | `counts` | | | |
+| `projects_teamcity_active` | `counts` | | | |
+| `projects_unify_circuit_active` | `counts` | | | |
+| `projects_webex_teams_active` | `counts` | | | |
+| `projects_youtrack_active` | `counts` | | | |
+| `projects_slack_notifications_active` | `counts` | | | |
+| `projects_slack_slash_active` | `counts` | | | |
+| `projects_jira_server_active` | `counts` | | | |
+| `projects_jira_cloud_active` | `counts` | | | |
+| `projects_jira_dvcs_cloud_active` | `counts` | | | |
+| `projects_jira_dvcs_server_active` | `counts` | | | |
+| `labels` | `counts` | | | |
+| `merge_requests` | `counts` | | | |
+| `merge_requests_users` | `counts` | | | |
+| `notes` | `counts` | | | |
+| `wiki_pages_create` | `counts` | | | |
+| `wiki_pages_update` | `counts` | | | |
+| `wiki_pages_delete` | `counts` | | | |
+| `web_ide_commits` | `counts` | | | |
+| `web_ide_views` | `counts` | | | |
+| `web_ide_merge_requests` | `counts` | | | |
+| `web_ide_previews` | `counts` | | | |
+| `snippet_comment` | `counts` | | | |
+| `commit_comment` | `counts` | | | |
+| `merge_request_comment` | `counts` | | | |
+| `snippet_create` | `counts` | | | |
+| `snippet_update` | `counts` | | | |
+| `navbar_searches` | `counts` | | | |
+| `cycle_analytics_views` | `counts` | | | |
+| `productivity_analytics_views` | `counts` | | | |
+| `source_code_pushes` | `counts` | | | |
+| `merge_request_create` | `counts` | | | |
+| `design_management_designs_create` | `counts` | | | |
+| `design_management_designs_update` | `counts` | | | |
+| `design_management_designs_delete` | `counts` | | | |
+| `licenses_list_views` | `counts` | | | |
+| `user_preferences_group_overview_details` | `counts` | | | |
+| `user_preferences_group_overview_security_dashboard` | `counts` | | | |
+| `ingress_modsecurity_logging` | `counts` | | | |
+| `ingress_modsecurity_blocking` | `counts` | | | |
+| `ingress_modsecurity_disabled` | `counts` | | | |
+| `ingress_modsecurity_not_installed` | `counts` | | | |
+| `dependency_list_usages_total` | `counts` | | | |
+| `epics` | `counts` | | | |
+| `feature_flags` | `counts` | | | |
+| `geo_nodes` | `counts` | `geo` | | Number of sites in a Geo deployment |
+| `geo_event_log_max_id` | `counts` | `geo` | | Number of replication events on a Geo primary |
+| `incident_issues` | `counts` | `monitor` | | Issues created by the alert bot |
+| `alert_bot_incident_issues` | `counts` | `monitor` | | Issues created by the alert bot |
+| `incident_labeled_issues` | `counts` | `monitor` | | Issues with the incident label |
+| `issues_created_gitlab_alerts` | `counts` | `monitor` | | Issues created from alerts by non-alert bot users |
+| `issues_created_manually_from_alerts` | `counts` | `monitor` | | Issues created from alerts by non-alert bot users |
+| `issues_created_from_alerts` | `counts` | `monitor` | | Issues created from Prometheus and alert management alerts |
+| `ldap_group_links` | `counts` | | | |
+| `ldap_keys` | `counts` | | | |
+| `ldap_users` | `counts` | | | |
+| `pod_logs_usages_total` | `counts` | | | |
+| `projects_enforcing_code_owner_approval` | `counts` | | | |
+| `projects_mirrored_with_pipelines_enabled` | `counts` |`release` | | Projects with repository mirroring enabled |
+| `projects_reporting_ci_cd_back_to_github` | `counts` |`verify` | | Projects with a GitHub service pipeline enabled |
+| `projects_with_packages` | `counts` |`package` | | Projects with package registry configured |
+| `projects_with_prometheus_alerts` | `counts` |`monitor` | | Projects with Prometheus alerting enabled |
+| `projects_with_tracing_enabled` | `counts` |`monitor` | | Projects with tracing enabled |
+| `projects_with_alerts_service_enabled` | `counts` |`monitor` | | Projects with alerting service enabled |
+| `template_repositories` | `counts` | | | |
+| `container_scanning_jobs` | `counts` | | | |
+| `dependency_scanning_jobs` | `counts` | | | |
+| `license_management_jobs` | `counts` | | | |
+| `sast_jobs` | `counts` | | | |
+| `status_page_projects` | `counts` | `monitor` | | Projects with status page enabled |
+| `status_page_issues` | `counts` | `monitor` | | Issues published to a Status Page |
+| `status_page_incident_publishes` | `counts` | `monitor` | | Cumulative count of usages of publish operation |
+| `status_page_incident_unpublishes` | `counts` | `monitor` | | Cumulative count of usages of unpublish operation |
+| `epics_deepest_relationship_level` | `counts` | | | |
+| `operations_dashboard_default_dashboard` | `counts` | `monitor` | | Active users with enabled operations dashboard |
+| `operations_dashboard_users_with_projects_added` | `counts` | `monitor` | | Active users with projects on operations dashboard|
+| `container_registry_enabled` | | | | |
+| `dependency_proxy_enabled` | | | | |
+| `gitlab_shared_runners_enabled` | | | | |
+| `gravatar_enabled` | | | | |
+| `ldap_enabled` | | | | |
+| `mattermost_enabled` | | | | |
+| `omniauth_enabled` | | | | |
+| `prometheus_metrics_enabled` | | | | |
+| `reply_by_email_enabled` | | | | |
+| `average` | `avg_cycle_analytics - code` | | | |
+| `sd` | `avg_cycle_analytics - code` | | | |
+| `missing` | `avg_cycle_analytics - code` | | | |
+| `average` | `avg_cycle_analytics - test` | | | |
+| `sd` | `avg_cycle_analytics - test` | | | |
+| `missing` | `avg_cycle_analytics - test` | | | |
+| `average` | `avg_cycle_analytics - review` | | | |
+| `sd` | `avg_cycle_analytics - review` | | | |
+| `missing` | `avg_cycle_analytics - review` | | | |
+| `average` | `avg_cycle_analytics - staging` | | | |
+| `sd` | `avg_cycle_analytics - staging` | | | |
+| `missing` | `avg_cycle_analytics - staging` | | | |
+| `average` | `avg_cycle_analytics - production` | | | |
+| `sd` | `avg_cycle_analytics - production` | | | |
+| `missing` | `avg_cycle_analytics - production` | | | |
+| `total` | `avg_cycle_analytics` | | | |
+| `clusters_applications_cert_managers` | `usage_activity_by_stage` | `configure` | | Unique clusters with certificate managers enabled |
+| `clusters_applications_helm` | `usage_activity_by_stage` | `configure` | | Unique clusters with Helm enabled |
+| `clusters_applications_ingress` | `usage_activity_by_stage` | `configure` | | Unique clusters with Ingress enabled |
+| `clusters_applications_knative` | `usage_activity_by_stage` | `configure` | | Unique clusters with Knative enabled |
+| `clusters_management_project` | `usage_activity_by_stage` | `configure` | | Unique clusters with project management enabled |
+| `clusters_disabled` | `usage_activity_by_stage` | `configure` | | Total non-"GitLab Managed clusters" |
+| `clusters_enabled` | `usage_activity_by_stage` | `configure` | | Total GitLab Managed clusters |
+| `clusters_platforms_gke` | `usage_activity_by_stage` | `configure` | | Unique clusters with Google Cloud installed |
+| `clusters_platforms_eks` | `usage_activity_by_stage` | `configure` | | Unique clusters with AWS installed |
+| `clusters_platforms_user` | `usage_activity_by_stage` | `configure` | | Unique clusters that are user provided |
+| `instance_clusters_disabled` | `usage_activity_by_stage` | `configure` | | Unique clusters disabled on instance |
+| `instance_clusters_enabled` | `usage_activity_by_stage` | `configure` | | Unique clusters enabled on instance |
+| `group_clusters_disabled` | `usage_activity_by_stage` | `configure` | | Unique clusters disabled on group |
+| `group_clusters_enabled` | `usage_activity_by_stage` | `configure` | | Unique clusters enabled on group |
+| `project_clusters_disabled` | `usage_activity_by_stage` | `configure` | | Unique clusters disabled on project |
+| `project_clusters_enabled` | `usage_activity_by_stage` | `configure` | | Unique clusters enabled on project |
+| `projects_slack_notifications_active` | `usage_activity_by_stage` | `configure` | | Unique projects with Slack service enabled |
+| `projects_slack_slash_active` | `usage_activity_by_stage` | `configure` | | Unique projects with Slack '/' commands enabled |
+| `projects_with_prometheus_alerts: 0` | `usage_activity_by_stage` | `monitor` | | Projects with Prometheus enabled and no alerts |
+| `deploy_keys` | `usage_activity_by_stage` | `create` | | |
+| `keys` | `usage_activity_by_stage` | `create` | | |
+| `projects_jira_dvcs_server_active` | `usage_activity_by_stage` | `plan` | | |
+| `service_desk_enabled_projects` | `usage_activity_by_stage` | `plan` | | |
+| `service_desk_issues` | `usage_activity_by_stage` | `plan` | | |
+| `todos: 0` | `usage_activity_by_stage` | `plan` | | |
+| `deployments` | `usage_activity_by_stage` | `release` | | Total deployments |
+| `failed_deployments` | `usage_activity_by_stage` | `release` | | Total failed deployments |
+| `projects_mirrored_with_pipelines_enabled` | `usage_activity_by_stage` | `release` | | Projects with repository mirroring enabled |
+| `releases` | `usage_activity_by_stage` | `release` | | Unique release tags in project |
+| `successful_deployments: 0` | `usage_activity_by_stage` | `release` | | Total successful deployments |
+| `user_preferences_group_overview_security_dashboard: 0` | `usage_activity_by_stage` | `secure` | | |
+| `ci_builds` | `usage_activity_by_stage` | `verify` | | Unique builds in project |
+| `ci_external_pipelines` | `usage_activity_by_stage` | `verify` | | Total pipelines in external repositories |
+| `ci_internal_pipelines` | `usage_activity_by_stage` | `verify` | | Total pipelines in GitLab repositories |
+| `ci_pipeline_config_auto_devops` | `usage_activity_by_stage` | `verify` | | Total pipelines from an Auto DevOps template |
+| `ci_pipeline_config_repository` | `usage_activity_by_stage` | `verify` | | Pipelines from templates in repository |
+| `ci_pipeline_schedules` | `usage_activity_by_stage` | `verify` | | Pipeline schedules in GitLab |
+| `ci_pipelines` | `usage_activity_by_stage` | `verify` | | Total pipelines |
+| `ci_triggers` | `usage_activity_by_stage` | `verify` | | Triggers enabled |
+| `clusters_applications_runner` | `usage_activity_by_stage` | `verify` | | Unique clusters with Runner enabled |
+| `projects_reporting_ci_cd_back_to_github: 0` | `usage_activity_by_stage` | `verify` | | Unique projects with a GitHub pipeline enabled |
+| `nodes` | `topology` | `enablement`| | The list of server nodes on which GitLab components are running |
+| `duration_s` | `topology` | `enablement`| | Time it took to collect topology data |
+| `node_memory_total_bytes` | `topology > nodes` | `enablement`| | The total available memory of this node |
+| `node_cpus` | `topology > nodes` | `enablement`| | The number of CPU cores of this node |
+| `node_services` | `topology > nodes` | `enablement`| | The list of GitLab services running on this node |
+| `name` | `topology > nodes > node_services` | `enablement`| | The name of the GitLab service running on this node |
+| `process_count` | `topology > nodes > node_services` | `enablement`| | The number of processes running for this service |
+| `process_memory_rss` | `topology > nodes > node_services` | `enablement`| | The average Resident Set Size of a service process |
+| `process_memory_uss` | `topology > nodes > node_services` | `enablement`| | The average Unique Set Size of a service process |
+| `process_memory_pss` | `topology > nodes > node_services` | `enablement`| | The average Proportional Set Size of a service process |
+
+## Example Usage Ping payload
+
+The following is example content of the Usage Ping payload.
+
+```json
+{
+ "uuid": "0000000-0000-0000-0000-000000000000",
+ "hostname": "example.com",
+ "version": "12.10.0-pre",
+ "installation_type": "omnibus-gitlab",
+ "active_user_count": 999,
+ "recorded_at": "2020-04-17T07:43:54.162+00:00",
+ "edition": "EEU",
+ "license_md5": "00000000000000000000000000000000",
+ "license_id": null,
+ "historical_max_users": 999,
+ "licensee": {
+ "Name": "ABC, Inc.",
+ "Email": "email@example.com",
+ "Company": "ABC, Inc."
+ },
+ "license_user_count": 999,
+ "license_starts_at": "2020-01-01",
+ "license_expires_at": "2021-01-01",
+ "license_plan": "ultimate",
+ "license_add_ons": {
+ },
+ "license_trial": false,
+ "counts": {
+ "assignee_lists": 999,
+ "boards": 999,
+ "ci_builds": 999,
+ ...
+ },
+ "container_registry_enabled": true,
+ "dependency_proxy_enabled": false,
+ "gitlab_shared_runners_enabled": true,
+ "gravatar_enabled": true,
+ "influxdb_metrics_enabled": true,
+ "ldap_enabled": false,
+ "mattermost_enabled": false,
+ "omniauth_enabled": true,
+ "prometheus_metrics_enabled": false,
+ "reply_by_email_enabled": "incoming+%{key}@incoming.gitlab.com",
+ "signup_enabled": true,
+ "web_ide_clientside_preview_enabled": true,
+ "ingress_modsecurity_enabled": true,
+ "projects_with_expiration_policy_disabled": 999,
+ "projects_with_expiration_policy_enabled": 999,
+ ...
+ "elasticsearch_enabled": true,
+ "license_trial_ends_on": null,
+ "geo_enabled": false,
+ "git": {
+ "version": {
+ "major": 2,
+ "minor": 26,
+ "patch": 1
+ }
+ },
+ "gitaly": {
+ "version": "12.10.0-rc1-93-g40980d40",
+ "servers": 56,
+ "clusters": 14,
+ "filesystems": [
+ "EXT_2_3_4"
+ ]
+ },
+ "gitlab_pages": {
+ "enabled": true,
+ "version": "1.17.0"
+ },
+ "database": {
+ "adapter": "postgresql",
+ "version": "9.6.15"
+ },
+ "app_server": {
+ "type": "console"
+ },
+ "avg_cycle_analytics": {
+ "issue": {
+ "average": 999,
+ "sd": 999,
+ "missing": 999
+ },
+ "plan": {
+ "average": null,
+ "sd": 999,
+ "missing": 999
+ },
+ "code": {
+ "average": null,
+ "sd": 999,
+ "missing": 999
+ },
+ "test": {
+ "average": null,
+ "sd": 999,
+ "missing": 999
+ },
+ "review": {
+ "average": null,
+ "sd": 999,
+ "missing": 999
+ },
+ "staging": {
+ "average": null,
+ "sd": 999,
+ "missing": 999
+ },
+ "production": {
+ "average": null,
+ "sd": 999,
+ "missing": 999
+ },
+ "total": 999
+ },
+ "usage_activity_by_stage": {
+ "configure": {
+ "project_clusters_enabled": 999,
+ ...
+ },
+ "create": {
+ "merge_requests": 999,
+ ...
+ },
+ "manage": {
+ "events": 999,
+ ...
+ },
+ "monitor": {
+ "clusters": 999,
+ ...
+ },
+ "package": {
+ "projects_with_packages": 999
+ },
+ "plan": {
+ "issues": 999,
+ ...
+ },
+ "release": {
+ "deployments": 999,
+ ...
+ },
+ "secure": {
+ "user_container_scanning_jobs": 999,
+ ...
+ },
+ "verify": {
+ "ci_builds": 999,
+ ...
+ }
+ },
+ "usage_activity_by_stage_monthly": {
+ "configure": {
+ "project_clusters_enabled": 999,
+ ...
+ },
+ "create": {
+ "merge_requests": 999,
+ ...
+ },
+ "manage": {
+ "events": 999,
+ ...
+ },
+ "monitor": {
+ "clusters": 999,
+ ...
+ },
+ "package": {
+ "projects_with_packages": 999
+ },
+ "plan": {
+ "issues": 999,
+ ...
+ },
+ "release": {
+ "deployments": 999,
+ ...
+ },
+ "secure": {
+ "user_container_scanning_jobs": 999,
+ ...
+ },
+ "verify": {
+ "ci_builds": 999,
+ ...
+ }
+ },
+ "topology": {
+ "nodes": [
+ {
+ "node_memory_total_bytes": 33269903360,
+ "node_cpus": 16,
+ "node_services": [
+ {
+ "name": "web",
+ "process_count": 16,
+ "process_memory_pss": 233349888,
+ "process_memory_rss": 788220927,
+ "process_memory_uss": 195295487
+ },
+ {
+ "name": "sidekiq",
+ "process_count": 1,
+ "process_memory_pss": 734080000,
+ "process_memory_rss": 750051328,
+ "process_memory_uss": 731533312
+ },
+ ...
+ ],
+ ...
+ },
+ ...
+ ],
+ "duration_s": 0.013836685999194742
+ }
+}
+```
diff --git a/doc/development/testing_guide/best_practices.md b/doc/development/testing_guide/best_practices.md
index f0137e542cc..7bb8473117f 100644
--- a/doc/development/testing_guide/best_practices.md
+++ b/doc/development/testing_guide/best_practices.md
@@ -35,11 +35,18 @@ Here are some things to keep in mind regarding test performance:
To run RSpec tests:
```shell
-# run all tests
+# run test for a file
+bin/rspec spec/models/project_spec.rb
+
+# run test for the example on line 10 on that file
+bin/rspec spec/models/project_spec.rb:10
+
+# run tests matching the example name has that string
+bin/rspec spec/models/project_spec.rb -e associations
+
+# run all tests, will take hours for GitLab codebase!
bin/rspec
-# run test for path
-bin/rspec spec/[path]/[to]/[spec].rb
```
Use [Guard](https://github.com/guard/guard) to continuously monitor for changes and only run matching tests:
@@ -59,7 +66,7 @@ FDOC=1 bin/rspec spec/[path]/[to]/[spec].rb
### General guidelines
-- Use a single, top-level `describe ClassName` block.
+- Use a single, top-level `RSpec.describe ClassName` block.
- Use `.method` to describe class methods and `#method` to describe instance
methods.
- Use `context` to test branching logic.
@@ -323,7 +330,7 @@ Feature.enabled?(:ci_live_trace) # => false
If you wish to set up a test where a feature flag is enabled only
for some actors and not others, you can specify this in options
passed to the helper. For example, to enable the `ci_live_trace`
-feature flag for a specifc project:
+feature flag for a specific project:
```ruby
project1, project2 = build_list(:project, 2)
@@ -340,7 +347,7 @@ This represents an actual behavior of FlipperGate:
1. You can enable an override for a specified actor to be enabled
1. You can disable (remove) an override for a specified actor,
- fallbacking to default state
+ falling back to default state
1. There's no way to model that you explicitly disable a specified actor
```ruby
@@ -357,6 +364,60 @@ Feature.enabled?(:my_feature2) # => false
Feature.enabled?(:my_feature2, project1) # => true
```
+#### `stub_feature_flags` vs `Feature.enable*`
+
+It is preferred to use `stub_feature_flags` for enabling feature flags
+in testing environment. This method provides a simple and well described
+interface for a simple use-cases.
+
+However, in some cases a more complex behaviors needs to be tested,
+like a feature flag percentage rollouts. This can be achieved using
+the `.enable_percentage_of_time` and `.enable_percentage_of_actors`
+
+```ruby
+# Good: feature needs to be explicitly disabled, as it is enabled by default if not defined
+stub_feature_flags(my_feature: false)
+stub_feature_flags(my_feature: true)
+stub_feature_flags(my_feature: project)
+stub_feature_flags(my_feature: [project, project2])
+
+# Bad
+Feature.enable(:my_feature_2)
+
+# Good: enable my_feature for 50% of time
+Feature.enable_percentage_of_time(:my_feature_3, 50)
+
+# Good: enable my_feature for 50% of actors/gates/things
+Feature.enable_percentage_of_actors(:my_feature_4, 50)
+```
+
+Each feature flag that has a defined state will be persisted
+for test execution time:
+
+```ruby
+Feature.persisted_names.include?('my_feature') => true
+Feature.persisted_names.include?('my_feature_2') => true
+Feature.persisted_names.include?('my_feature_3') => true
+Feature.persisted_names.include?('my_feature_4') => true
+```
+
+#### Stubbing gate
+
+It is required that a gate that is passed as an argument to `Feature.enabled?`
+and `Feature.disabled?` is an object that includes `FeatureGate`.
+
+In specs you can use a `stub_feature_flag_gate` method that allows you to have
+quickly your custom gate:
+
+```ruby
+gate = stub_feature_flag_gate('CustomActor')
+
+stub_feature_flags(ci_live_trace: gate)
+
+Feature.enabled?(:ci_live_trace) # => false
+Feature.enabled?(:ci_live_trace, gate) # => true
+```
+
### Pristine test environments
The code exercised by a single GitLab test may access and modify many items of
@@ -406,7 +467,7 @@ However, if a spec makes direct Redis calls, it should mark itself with the
#### Background jobs / Sidekiq
By default, Sidekiq jobs are enqueued into a jobs array and aren't processed.
-If a test enqueues Sidekiq jobs and need them to be processed, the
+If a test queues Sidekiq jobs and need them to be processed, the
`:sidekiq_inline` trait can be used.
The `:sidekiq_might_not_need_inline` trait was added when [Sidekiq inline mode was
@@ -662,7 +723,7 @@ module Spec
end
```
-Helpers should not change the RSpec config. For instance, the helpers module
+Helpers should not change the RSpec configuration. For instance, the helpers module
described above should not include:
```ruby
@@ -723,9 +784,9 @@ end
This will create a repository containing two files, with default permissions and
the specified content.
-### Config
+### Configuration
-RSpec config files are files that change the RSpec config (i.e.
+RSpec configuration files are files that change the RSpec configuration (i.e.
`RSpec.configure do |config|` blocks). They should be placed under
`spec/support/`.
@@ -744,7 +805,7 @@ RSpec.configure do |config|
end
```
-If a config file only consists of `config.include`, you can add these
+If a configuration file only consists of `config.include`, you can add these
`config.include` directly in `spec/spec_helper.rb`.
For very generic helpers, consider including them in the `spec/support/rspec.rb`
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 57cfcf34726..7df3cd614c7 100644
--- a/doc/development/testing_guide/end_to_end/best_practices.md
+++ b/doc/development/testing_guide/end_to_end/best_practices.md
@@ -91,7 +91,7 @@ point of failure and so the screenshot would not be captured at the right moment
All tests expect to be able to log in at the start of the test.
-For an example see: <https://gitlab.com/gitlab-org/gitlab/issues/34736>
+For an example see: <https://gitlab.com/gitlab-org/gitlab/-/issues/34736>
Ideally, any actions performed in an `after(:context)` (or [`before(:context)`](#limit-the-use-of-the-ui-in-beforecontext-and-after-hooks)) block would be performed via the API. But if it's necessary to do so via the UI (e.g., if API functionality doesn't exist), make sure to log out at the end of the block.
diff --git a/doc/development/testing_guide/end_to_end/feature_flags.md b/doc/development/testing_guide/end_to_end/feature_flags.md
index 3bd07f17207..ada20cc9dad 100644
--- a/doc/development/testing_guide/end_to_end/feature_flags.md
+++ b/doc/development/testing_guide/end_to_end/feature_flags.md
@@ -26,4 +26,4 @@ end
It's also possible to run an entire scenario with a feature flag enabled, without having to edit existing tests or write new ones.
-Please see the [QA readme](https://gitlab.com/gitlab-org/gitlab/tree/master/qa#running-tests-with-a-feature-flag-enabled) for details.
+Please see the [QA README](https://gitlab.com/gitlab-org/gitlab/tree/master/qa#running-tests-with-a-feature-flag-enabled) for details.
diff --git a/doc/development/testing_guide/end_to_end/index.md b/doc/development/testing_guide/end_to_end/index.md
index e6a683e9148..ac051b827d2 100644
--- a/doc/development/testing_guide/end_to_end/index.md
+++ b/doc/development/testing_guide/end_to_end/index.md
@@ -65,18 +65,18 @@ subgraph "gitlab-qa-mirror pipeline"
end
```
-1. Developer triggers a manual action, that can be found in CE / EE merge
+1. Developer triggers a manual action, that can be found in GitLab merge
requests. This starts a chain of pipelines in multiple projects.
1. The script being executed triggers a pipeline in
- [Omnibus GitLab Mirror](https://gitlab.com/gitlab-org/omnibus-gitlab-mirror)
+ [Omnibus GitLab Mirror](https://gitlab.com/gitlab-org/build/omnibus-gitlab-mirror)
and waits for the resulting status. We call this a _status attribution_.
-1. GitLab packages are being built in the [Omnibus GitLab](https://gitlab.com/gitlab-org/omnibus-gitlab)
+1. GitLab packages are being built in the [Omnibus GitLab Mirror](https://gitlab.com/gitlab-org/build/omnibus-gitlab-mirror)
pipeline. Packages are then pushed to its Container Registry.
1. When packages are ready, and available in the registry, a final step in the
- [Omnibus GitLab](https://gitlab.com/gitlab-org/omnibus-gitlab) pipeline, triggers a new
+ [Omnibus GitLab Mirror](https://gitlab.com/gitlab-org/build/omnibus-gitlab-mirror) pipeline, triggers a new
GitLab QA pipeline (those with access can view them at `https://gitlab.com/gitlab-org/gitlab-qa-mirror/pipelines`). It also waits for a resulting status.
1. GitLab QA pulls images from the registry, spins-up containers and runs tests
@@ -84,9 +84,9 @@ subgraph "gitlab-qa-mirror pipeline"
tool.
1. The result of the GitLab QA pipeline is being
- propagated upstream, through Omnibus, back to the CE / EE merge request.
+ propagated upstream, through Omnibus, back to the GitLab merge request.
-Please note, we plan to [add more specific information](https://gitlab.com/gitlab-org/quality/team-tasks/issues/156)
+Please note, we plan to [add more specific information](https://gitlab.com/gitlab-org/quality/team-tasks/-/issues/156)
about the tests included in each job/scenario that runs in `gitlab-qa-mirror`.
#### With Pipeline for Merged Results
@@ -132,7 +132,7 @@ as well as these:
| `QA_RSPEC_TAGS` | The RSpec tags to add (no default) |
For now [manual jobs with custom variables will not use the same variable
-when retried](https://gitlab.com/gitlab-org/gitlab/issues/31367), so if you want to run the same test(s) multiple times,
+when retried](https://gitlab.com/gitlab-org/gitlab/-/issues/31367), so if you want to run the same test(s) multiple times,
specify the same variables in each `custom-parallel` job (up to as
many of the 10 available jobs that you want to run).
@@ -155,7 +155,7 @@ See [Review Apps](../review_apps.md) for more details about Review Apps.
If you are not [testing code in a merge request](#testing-code-in-merge-requests),
there are two main options for running the tests. If you simply want to run
-the existing tests against a live GitLab instance or against a pre-built docker image
+the existing tests against a live GitLab instance or against a pre-built Docker image
you can use the [GitLab QA orchestrator](https://gitlab.com/gitlab-org/gitlab-qa/tree/master/README.md). See also [examples
of the test scenarios you can run via the orchestrator](https://gitlab.com/gitlab-org/gitlab-qa/blob/master/docs/what_tests_can_be_run.md#examples).
@@ -191,5 +191,5 @@ Continued reading:
You can ask question in the `#quality` channel on Slack (GitLab internal) or
you can find an issue you would like to work on in
-[the `gitlab` issue tracker](https://gitlab.com/gitlab-org/gitlab/issues?label_name%5B%5D=QA&label_name%5B%5D=test), or
-[the `gitlab-qa` issue tracker](https://gitlab.com/gitlab-org/gitlab-qa/issues?label_name%5B%5D=new+scenario).
+[the `gitlab` issue tracker](https://gitlab.com/gitlab-org/gitlab/-/issues?label_name%5B%5D=QA&label_name%5B%5D=test), or
+[the `gitlab-qa` issue tracker](https://gitlab.com/gitlab-org/gitlab-qa/-/issues?label_name%5B%5D=new+scenario).
diff --git a/doc/development/testing_guide/end_to_end/page_objects.md b/doc/development/testing_guide/end_to_end/page_objects.md
index 9d4fa5316c4..d43d88779c7 100644
--- a/doc/development/testing_guide/end_to_end/page_objects.md
+++ b/doc/development/testing_guide/end_to_end/page_objects.md
@@ -89,7 +89,7 @@ end
### Defining Elements
-The `view` DSL method will correspond to the rails View, partial, or vue component that renders the elements.
+The `view` DSL method will correspond to the rails View, partial, or Vue component that renders the elements.
The `element` DSL method in turn declares an element for which a corresponding
`data-qa-selector=element_name_snaked` data attribute will need to be added to the view file.
@@ -134,7 +134,7 @@ view 'app/views/my/view.html.haml' do
end
```
-To add these elements to the view, you must change the rails View, partial, or vue component by adding a `data-qa-selector` attribute
+To add these elements to the view, you must change the rails View, partial, or Vue component by adding a `data-qa-selector` attribute
for each element defined.
In our case, `data-qa-selector="login_field"`, `data-qa-selector="password_field"` and `data-qa-selector="sign_in_button"`
@@ -149,7 +149,7 @@ In our case, `data-qa-selector="login_field"`, `data-qa-selector="password_field
Things to note:
-- The name of the element and the qa_selector must match and be snake_cased
+- The name of the element and the `qa_selector` must match and be snake_cased
- If the element appears on the page unconditionally, add `required: true` to the element. See
[Dynamic element validation](dynamic_element_validation.md)
- You may see `.qa-selector` classes in existing Page Objects. We should prefer the [`data-qa-selector`](#data-qa-selector-vs-qa-selector)
@@ -255,7 +255,7 @@ These steps ensure the sanity selectors check will detect problems properly.
For example, `qa/qa/ee/page/merge_request/show.rb` adds EE-specific methods to `qa/qa/page/merge_request/show.rb` (with
`QA::Page::MergeRequest::Show.prepend_if_ee('QA::EE::Page::MergeRequest::Show')`) and following is how it's implemented
-(only showing the relevant part and refering to the 4 steps described above with inline comments):
+(only showing the relevant part and referring to the 4 steps described above with inline comments):
```ruby
module QA
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 b7c93d205a3..b1a8a14163c 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
@@ -9,10 +9,11 @@ This is a partial list of the [RSpec metadata](https://relishapp.com/rspec/rspec
|-----|-------------|
| `:elasticsearch` | The test requires an Elasticsearch service. It is used by the [instance-level scenario](https://gitlab.com/gitlab-org/gitlab-qa#definitions) [`Test::Integration::Elasticsearch`](https://gitlab.com/gitlab-org/gitlab/-/blob/72b62b51bdf513e2936301cb6c7c91ec27c35b4d/qa/qa/ee/scenario/test/integration/elasticsearch.rb) to include only tests that require Elasticsearch. |
| `:kubernetes` | The test includes a GitLab instance that is configured to be run behind an SSH tunnel, allowing a TLS-accessible GitLab. This test will also include provisioning of at least one Kubernetes cluster to test against. *This tag is often be paired with `:orchestrated`.* |
-| `:orchestrated` | The GitLab instance under test may be [configured by `gitlab-qa`](https://gitlab.com/gitlab-org/gitlab-qa/-/blob/master/docs/what_tests_can_be_run.md#orchestrated-tests) to be different to the default GitLab configuration, or `gitlab-qa` may launch additional services in separate docker containers, or both. Tests tagged with `:orchestrated` are excluded when testing environments where we can't dynamically modify GitLab's configuration (for example, Staging). |
+| `:orchestrated` | The GitLab instance under test may be [configured by `gitlab-qa`](https://gitlab.com/gitlab-org/gitlab-qa/-/blob/master/docs/what_tests_can_be_run.md#orchestrated-tests) to be different to the default GitLab configuration, or `gitlab-qa` may launch additional services in separate Docker containers, or both. Tests tagged with `:orchestrated` are excluded when testing environments where we can't dynamically modify GitLab's configuration (for example, Staging). |
| `:quarantine` | The test has been [quarantined](https://about.gitlab.com/handbook/engineering/quality/guidelines/debugging-qa-test-failures/#quarantining-tests), will run in a separate job that only includes quarantined tests, and is allowed to fail. The test will be skipped in its regular job so that if it fails it will not hold up the pipeline. |
| `:reliable` | The test has been [promoted to a reliable test](https://about.gitlab.com/handbook/engineering/quality/guidelines/reliable-tests/#promoting-an-existing-test-to-reliable) meaning it passes consistently in all pipelines, including merge requests. |
| `:requires_admin` | The test requires an admin account. Tests with the tag are excluded when run against Canary and Production environments. |
| `:runner` | The test depends on and will set up a GitLab Runner instance, typically to run a pipeline. |
| `:gitaly_ha` | The test will run against a GitLab instance where repositories are stored on redundant Gitaly nodes behind a Praefect node. All nodes are [separate containers](../../../administration/gitaly/praefect.md#requirements-for-configuring-a-gitaly-cluster). Tests that use this tag have a longer setup time since there are three additional containers that need to be started. |
| `:skip_live_env` | The test will be excluded when run against live deployed environments such as Staging, Canary, and Production. |
+| `:jira` | The test requires a Jira Server. [GitLab-QA](https://gitlab.com/gitlab-org/gitlab-qa) will provision the Jira Server in a Docker container when the `Test::Integration::Jira` test scenario is run.
diff --git a/doc/development/testing_guide/end_to_end/running_tests_that_require_special_setup.md b/doc/development/testing_guide/end_to_end/running_tests_that_require_special_setup.md
index f360226d922..77d820e1686 100644
--- a/doc/development/testing_guide/end_to_end/running_tests_that_require_special_setup.md
+++ b/doc/development/testing_guide/end_to_end/running_tests_that_require_special_setup.md
@@ -2,13 +2,13 @@
## Jenkins spec
-The [`jenkins_build_status_spec`](https://gitlab.com/gitlab-org/gitlab/blob/163c8a8c814db26d11e104d1cb2dcf02eb567dbe/qa/qa/specs/features/ee/browser_ui/3_create/jenkins/jenkins_build_status_spec.rb) spins up a Jenkins instance in a docker container based on an image stored in the [GitLab-QA container registry](https://gitlab.com/gitlab-org/gitlab-qa/container_registry).
-The docker image it uses is preconfigured with some base data and plugins.
+The [`jenkins_build_status_spec`](https://gitlab.com/gitlab-org/gitlab/blob/163c8a8c814db26d11e104d1cb2dcf02eb567dbe/qa/qa/specs/features/ee/browser_ui/3_create/jenkins/jenkins_build_status_spec.rb) spins up a Jenkins instance in a Docker container based on an image stored in the [GitLab-QA container registry](https://gitlab.com/gitlab-org/gitlab-qa/container_registry).
+The Docker image it uses is preconfigured with some base data and plugins.
The test then configures the GitLab plugin in Jenkins with a URL of the GitLab instance that will be used
to run the tests. Unfortunately, the GitLab Jenkins plugin does not accept ports so `http://localhost:3000` would
-not be accepted. Therefore, this requires us to run GitLab on port 80 or inside a docker container.
+not be accepted. Therefore, this requires us to run GitLab on port 80 or inside a Docker container.
-To start a docker container for GitLab based on the nightly image:
+To start a Docker container for GitLab based on the nightly image:
```shell
docker run \
@@ -24,7 +24,7 @@ To run the tests from the `/qa` directory:
CHROME_HEADLESS=false bin/qa Test::Instance::All http://localhost -- qa/specs/features/ee/browser_ui/3_create/jenkins/jenkins_build_status_spec.rb
```
-The test will automatically spinup a docker container for Jenkins and tear down once the test completes.
+The test will automatically spin up a Docker container for Jenkins and tear down once the test completes.
However, if you need to run Jenkins manually outside of the tests, use this command:
@@ -46,5 +46,5 @@ only to prevent it from running in the pipelines for live environments such as S
### Troubleshooting
-If Jenkins docker container exits without providing any information in the logs, try increasing the memory used by
+If Jenkins Docker container exits without providing any information in the logs, try increasing the memory used by
the Docker Engine.
diff --git a/doc/development/testing_guide/end_to_end/style_guide.md b/doc/development/testing_guide/end_to_end/style_guide.md
index 9c02af12d5d..7e9f097f624 100644
--- a/doc/development/testing_guide/end_to_end/style_guide.md
+++ b/doc/development/testing_guide/end_to_end/style_guide.md
@@ -49,7 +49,7 @@ Notice that in the above example, before clicking the `:operations_environments_
When adding new elements to a page, it's important that we have a uniform element naming convention.
-We follow a simple formula roughly based on hungarian notation.
+We follow a simple formula roughly based on Hungarian notation.
*Formula*: `element :<descriptor>_<type>`
@@ -109,7 +109,7 @@ we use the name of the page object in [snake_case](https://en.wikipedia.org/wiki
(all lowercase, with words separated by an underscore). See good and bad examples below.
While we prefer to follow the standard in most cases, it is also acceptable to
-use common abbreviations (e.g., mr) or other alternatives, as long as
+use common abbreviations (e.g., `mr`) or other alternatives, as long as
the name is not ambiguous. This can include appending `_page` if it helps to
avoid confusion or make the code more readable. For example, if a page object is
named `New`, it could be confusing to name the block argument `new` because that
@@ -123,7 +123,7 @@ Capybara DSL, potentially leading to confusion and bugs.
**Good**
```ruby
-Page::Project::Settings::Members.perform do |members|
+Page::Project::Members.perform do |members|
members.do_something
end
```
@@ -149,7 +149,7 @@ end
**Bad**
```ruby
-Page::Project::Settings::Members.perform do |project_settings_members_page|
+Page::Project::Members.perform do |project_settings_members_page|
project_settings_members_page.do_something
end
```
diff --git a/doc/development/testing_guide/flaky_tests.md b/doc/development/testing_guide/flaky_tests.md
index 6c1b06ce59a..7aed908c4f6 100644
--- a/doc/development/testing_guide/flaky_tests.md
+++ b/doc/development/testing_guide/flaky_tests.md
@@ -49,20 +49,20 @@ examples in a JSON report file on `master` (`retrieve-tests-metadata` and
This was originally implemented in: <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13021>.
-If you want to enable retries locally, you can use the `RETRIES` env variable.
+If you want to enable retries locally, you can use the `RETRIES` environment variable.
For instance `RETRIES=1 bin/rspec ...` would retry the failing examples once.
## Problems we had in the past at GitLab
-- [`rspec-retry` is biting us when some API specs fail](https://gitlab.com/gitlab-org/gitlab-foss/issues/29242): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/9825>
-- [Sporadic RSpec failures due to `PG::UniqueViolation`](https://gitlab.com/gitlab-org/gitlab-foss/issues/28307#note_24958837): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/9846>
+- [`rspec-retry` is biting us when some API specs fail](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/29242): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/9825>
+- [Sporadic RSpec failures due to `PG::UniqueViolation`](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/28307#note_24958837): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/9846>
- Follow-up: <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10688>
- - [Capybara.reset_session! should be called before requests are blocked](https://gitlab.com/gitlab-org/gitlab-foss/issues/33779): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/12224>
+ - [Capybara.reset_session! should be called before requests are blocked](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/33779): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/12224>
- FFaker generates funky data that tests are not ready to handle (and tests should be predictable so that's bad!):
- - [Make `spec/mailers/notify_spec.rb` more robust](https://gitlab.com/gitlab-org/gitlab-foss/issues/20121): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10015>
- - [Transient failure in `spec/requests/api/commits_spec.rb`](https://gitlab.com/gitlab-org/gitlab-foss/issues/27988#note_25342521): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/9944>
- - [Replace FFaker factory data with sequences](https://gitlab.com/gitlab-org/gitlab-foss/issues/29643): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10184>
- - [Transient failure in spec/finders/issues_finder_spec.rb](https://gitlab.com/gitlab-org/gitlab-foss/issues/30211#note_26707685): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10404>
+ - [Make `spec/mailers/notify_spec.rb` more robust](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/20121): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10015>
+ - [Transient failure in `spec/requests/api/commits_spec.rb`](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/27988#note_25342521): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/9944>
+ - [Replace FFaker factory data with sequences](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/29643): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10184>
+ - [Transient failure in spec/finders/issues_finder_spec.rb](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/30211#note_26707685): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10404>
### Time-sensitive flaky tests
@@ -75,24 +75,24 @@ For instance `RETRIES=1 bin/rspec ...` would retry the failing examples once.
### Feature tests
-- [Be sure to create all the data the test need before starting exercise](https://gitlab.com/gitlab-org/gitlab-foss/issues/32622#note_31128195): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/12059>
-- [Bis](https://gitlab.com/gitlab-org/gitlab-foss/issues/34609#note_34048715): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/12604>
-- [Bis](https://gitlab.com/gitlab-org/gitlab-foss/issues/34698#note_34276286): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/12664>
-- [Assert against the underlying database state instead of against a page's content](https://gitlab.com/gitlab-org/gitlab-foss/issues/31437): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10934>
-- In JS tests, shifting elements can cause Capybara to misclick when the element moves at the exact time Capybara sends the click
+- [Be sure to create all the data the test need before starting exercise](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/32622#note_31128195): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/12059>
+- [Bis](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/34609#note_34048715): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/12604>
+- [Bis](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/34698#note_34276286): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/12664>
+- [Assert against the underlying database state instead of against a page's content](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/31437): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10934>
+- In JS tests, shifting elements can cause Capybara to mis-click when the element moves at the exact time Capybara sends the click
- [Dropdowns rendering upward or downward due to window size and scroll position](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17660)
- - [Lazy loaded images can cause Capybara to misclick](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/18713)
+ - [Lazy loaded images can cause Capybara to mis-click](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/18713)
- [Triggering JS events before the event handlers are set up](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/18742)
-- [Wait for the image to be lazy-loaded when asserting on a Markdown image's src attribute](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25408)
+- [Wait for the image to be lazy-loaded when asserting on a Markdown image's `src` attribute](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25408)
#### Capybara viewport size related issues
-- [Transient failure of spec/features/issues/filtered_search/filter_issues_spec.rb](https://gitlab.com/gitlab-org/gitlab-foss/issues/29241#note_26743936): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10411>
+- [Transient failure of spec/features/issues/filtered_search/filter_issues_spec.rb](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/29241#note_26743936): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10411>
#### Capybara JS driver related issues
-- [Don't wait for AJAX when no AJAX request is fired](https://gitlab.com/gitlab-org/gitlab-foss/issues/30461): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10454>
-- [Bis](https://gitlab.com/gitlab-org/gitlab-foss/issues/34647): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/12626>
+- [Don't wait for AJAX when no AJAX request is fired](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/30461): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10454>
+- [Bis](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/34647): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/12626>
#### PhantomJS / WebKit related issues
diff --git a/doc/development/testing_guide/frontend_testing.md b/doc/development/testing_guide/frontend_testing.md
index 52d538c7159..37e1066e7aa 100644
--- a/doc/development/testing_guide/frontend_testing.md
+++ b/doc/development/testing_guide/frontend_testing.md
@@ -26,7 +26,7 @@ Jest tests can be found in `/spec/frontend` and `/ee/spec/frontend` in EE.
> **Note:**
>
-> Most examples have a Jest and Karma example. See the Karma examples only as explanation to what's going on in the code, should you stumble over some usescases during your discovery. The Jest examples are the one you should follow.
+> Most examples have a Jest and Karma example. See the Karma examples only as explanation to what's going on in the code, should you stumble over some use cases during your discovery. The Jest examples are the one you should follow.
## Karma test suite
@@ -61,7 +61,7 @@ which could arise (especially with testing against browser specific features).
- Jest runs in a Node.js environment, not in a browser. Support for running Jest tests in a browser [is planned](https://gitlab.com/gitlab-org/gitlab/-/issues/26982).
- 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 config](https://gitlab.com/gitlab-org/gitlab/blob/master/jest.config.js).
+ 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/en/timer-mocks).
- `rewire` is not required because Jest supports mocking modules. See also [Manual Mocks](https://jestjs.io/docs/en/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.
@@ -200,15 +200,15 @@ For example, it's better to use the generated markup to trigger a button click a
## Common practices
-Following you'll find some general common practices you will find as part of our testsuite. Should you stumble over something not following this guide, ideally fix it right away. 🎉
+Following you'll find some general common practices you will find as part of our test suite. Should you stumble over something not following this guide, ideally fix it right away. 🎉
### How to query DOM elements
-When it comes to querying DOM elements in your tests, it is best to uniquely target the element, without adding additional attributes specifically for testing purposes. Sometimes this cannot be done feasibly. In these cases, adding test attributes to simplify the selectors might be the best option.
+When it comes to querying DOM elements in your tests, it is best to uniquely and semantically target the element. Sometimes this cannot be done feasibly. In these cases, adding test attributes to simplify the selectors might be the best option.
Preferentially, in component testing with `@vue/test-utils`, you should query for child components using the component itself. This helps enforce that specific behavior can be covered by that component's individual unit tests. Otherwise, try to use:
-- A behavioral attribute like `name` (also verifies that `name` was setup properly)
+- A semantic attribute like `name` (also verifies that `name` was setup properly)
- A `data-testid` attribute ([recommended by maintainers of `@vue/test-utils`](https://github.com/vuejs/vue-test-utils/issues/1498#issuecomment-610133465))
- a Vue `ref` (if using `@vue/test-utils`)
@@ -216,11 +216,17 @@ Examples:
```javascript
it('exists', () => {
+ // Good
wrapper.find(FooComponent);
wrapper.find('input[name=foo]');
wrapper.find('[data-testid="foo"]');
wrapper.find({ ref: 'foo'});
+
+ // Bad
wrapper.find('.js-foo');
+ wrapper.find('.btn-primary');
+ wrapper.find('.qa-foo-component');
+ wrapper.find('[data-qa-selector="foo"]');
});
```
@@ -556,7 +562,7 @@ The more challenging part are mocks, which can be used for functions or even dep
### Manual module mocks
Manual mocks are used to mock modules across the entire Jest environment. This is a very powerful testing tool that helps simplify
-unit testing by mocking out modules which cannot be easily consumned in our test environment.
+unit testing by mocking out modules which cannot be easily consumed in our test environment.
> **WARNING:** Do not use manual mocks if a mock should not be consistently applied in every spec (i.e. it's only needed by a few specs).
> Instead, consider using [`jest.mock(..)`](https://jestjs.io/docs/en/jest-object#jestmockmodulename-factory-options)
@@ -582,10 +588,10 @@ If a manual mock is needed for a CE module, please place it in `spec/frontend/mo
- [`mocks/axios_utils`](https://gitlab.com/gitlab-org/gitlab/blob/bd20aeb64c4eed117831556c54b40ff4aee9bfd1/spec/frontend/mocks/ce/lib/utils/axios_utils.js#L1) -
This mock is helpful because we don't want any unmocked requests to pass any tests. Also, we are able to inject some test helpers such as `axios.waitForAll`.
- [`__mocks__/mousetrap/index.js`](https://gitlab.com/gitlab-org/gitlab/blob/cd4c086d894226445be9d18294a060ba46572435/spec/frontend/__mocks__/mousetrap/index.js#L1) -
- This mock is helpful because the module itself uses amd format which webpack understands, but is incompatible with the jest environment. This mock doesn't remove
+ This mock is helpful because the module itself uses AMD format which webpack understands, but is incompatible with the jest environment. This mock doesn't remove
any behavior, only provides a nice es6 compatible wrapper.
- [`__mocks__/monaco-editor/index.js`](https://gitlab.com/gitlab-org/gitlab/blob/b7f914cddec9fc5971238cdf12766e79fa1629d7/spec/frontend/__mocks__/monaco-editor/index.js) -
- This mock is helpful because the monaco package is completely incompatible in a Jest environment. In fact, webpack requires a special loader to make it work. This mock
+ This mock is helpful because the Monaco package is completely incompatible in a Jest environment. In fact, webpack requires a special loader to make it work. This mock
simply makes this package consumable by Jest.
### Keep mocks light
@@ -611,7 +617,7 @@ As long as the fixtures don't change, `yarn test` is sufficient (and saves you s
### Live testing and focused testing -- Jest
-While you work on a testsuite, you may want to run these specs in watch mode, so they rerun automatically on every save.
+While you work on a test suite, you may want to run these specs in watch mode, so they rerun automatically on every save.
```shell
# Watch and rerun all specs matching the name icon
@@ -801,9 +807,9 @@ Tests relevant for frontend development can be found at the following places:
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/` will eventually be migrated to `spec/frontend/` (see also [#52483](https://gitlab.com/gitlab-org/gitlab-foss/issues/52483)).
+All tests in `spec/javascripts/` will eventually be migrated to `spec/frontend/` (see also [#52483](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/52483)).
-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)).
+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)).
See also [Notes on testing Vue components](../fe_guide/vue.md#testing-vue-components).
@@ -830,11 +836,11 @@ testAction(
);
```
-Check an example in [spec/javascripts/ide/stores/actions_spec.jsspec/javascripts/ide/stores/actions_spec.js](https://gitlab.com/gitlab-org/gitlab/blob/master/spec/javascripts/ide/stores/actions_spec.js).
+Check an example in [`spec/javascripts/ide/stores/actions_spec.jsspec/javascripts/ide/stores/actions_spec.js`](https://gitlab.com/gitlab-org/gitlab/blob/master/spec/javascripts/ide/stores/actions_spec.js).
-### Wait until axios requests finish
+### Wait until Axios requests finish
-The axios utils mock module located in `spec/frontend/mocks/ce/lib/utils/axios_utils.js` contains two helper methods for Jest tests that spawn HTTP requests.
+The Axios Utils mock module located in `spec/frontend/mocks/ce/lib/utils/axios_utils.js` contains two helper methods for Jest tests that spawn HTTP requests.
These are very useful if you don't have a handle to the request's Promise, for example when a Vue component does a request as part of its life cycle.
- `waitFor(url, callback)`: Runs `callback` after a request to `url` finishes (either successfully or unsuccessfully).
@@ -844,11 +850,11 @@ Both functions run `callback` on the next tick after the requests finish (using
## Testing with older browsers
-Some regressions only affect a specific browser version. We can install and test in particular browsers with either Firefox or Browserstack using the following steps:
+Some regressions only affect a specific browser version. We can install and test in particular browsers with either Firefox or BrowserStack using the following steps:
-### Browserstack
+### BrowserStack
-[Browserstack](https://www.browserstack.com/) allows you to test more than 1200 mobile devices and browsers.
+[BrowserStack](https://www.browserstack.com/) allows you to test more than 1200 mobile devices and browsers.
You can use it directly through the [live app](https://www.browserstack.com/live) or you can install the [chrome extension](https://chrome.google.com/webstore/detail/browserstack/nkihdmlheodkdfojglpcjjmioefjahjb) for easy access.
You can find the credentials on 1Password, under `frontendteam@gitlab.com`.
@@ -860,7 +866,7 @@ You can download any older version of Firefox from the releases FTP server, <htt
1. From the website, select a version, in this case `50.0.1`.
1. Go to the mac folder.
-1. Select your preferred language, you will find the dmg package inside, download it.
+1. Select your preferred language, you will find the DMG package inside, download it.
1. Drag and drop the application to any other folder but the `Applications` folder.
1. Rename the application to something like `Firefox_Old`.
1. Move the application to the `Applications` folder.
diff --git a/doc/development/testing_guide/index.md b/doc/development/testing_guide/index.md
index f0fb06910f8..0d470e0e737 100644
--- a/doc/development/testing_guide/index.md
+++ b/doc/development/testing_guide/index.md
@@ -20,7 +20,7 @@ Following are two great articles that everyone should read to understand what
automated testing means, and what are its principles:
- [Five Factor Testing](https://madeintandem.com/blog/five-factor-testing/): Why do we need tests?
-- [Principles of Automated Testing](http://www.lihaoyi.com/post/PrinciplesofAutomatedTesting.html): Levels of testing. Prioritize tests. Cost of tests.
+- [Principles of Automated Testing](https://www.lihaoyi.com/post/PrinciplesofAutomatedTesting.html): Levels of testing. Prioritize tests. Cost of tests.
## [Testing levels](testing_levels.md)
@@ -58,7 +58,7 @@ Everything you should know about how to test Rake tasks.
## [End-to-end tests](end_to_end/index.md)
Everything you should know about how to run end-to-end tests using
-[GitLab QA](ttps://gitlab.com/gitlab-org/gitlab-qa) testing framework.
+[GitLab QA](https://gitlab.com/gitlab-org/gitlab-qa) testing framework.
## [Migrations tests](testing_migrations_guide.md)
diff --git a/doc/development/testing_guide/review_apps.md b/doc/development/testing_guide/review_apps.md
index 58acf937d77..3d7aea89e73 100644
--- a/doc/development/testing_guide/review_apps.md
+++ b/doc/development/testing_guide/review_apps.md
@@ -55,8 +55,8 @@ subgraph "CNG-mirror pipeline"
each component (e.g. `gitlab-rails-ee`, `gitlab-shell`, `gitaly` etc.)
based on the commit from the [GitLab pipeline](https://gitlab.com/gitlab-org/gitlab/pipelines/125315730) and stores
them in its [registry](https://gitlab.com/gitlab-org/build/CNG-mirror/container_registry).
- - We use the [`CNG-mirror`](https://gitlab.com/gitlab-org/build/CNG-mirror) project so that the `CNG`, (**C**loud
- **N**ative **G**itLab), project's registry is not overloaded with a
+ - We use the [`CNG-mirror`](https://gitlab.com/gitlab-org/build/CNG-mirror) project so that the `CNG`, (Cloud
+ Native GitLab), project's registry is not overloaded with a
lot of transient Docker images.
- Note that the official CNG images are built by the `cloud-native-image`
job, which runs only for tags, and triggers itself a [`CNG`](https://gitlab.com/gitlab-org/build/CNG) pipeline.
@@ -139,8 +139,8 @@ browser performance testing using a
The `review-apps-ee` and `review-apps-ce` clusters are currently set up with
the following node pools:
-- `review-apps-ee` of preemptible `e2-highcpu-16` (16 vCPU, 16 GB memory) nodes with autoscaling
-- `review-apps-ce` of preemptible `n1-standard-8` (8 vCPU, 16 GB memory) nodes with autoscaling
+- `review-apps-ee` of pre-emptible `e2-highcpu-16` (16 vCPU, 16 GB memory) nodes with autoscaling
+- `review-apps-ce` of pre-emptible `n1-standard-8` (8 vCPU, 16 GB memory) nodes with autoscaling
### Helm
@@ -152,7 +152,7 @@ used by the `review-deploy` and `review-stop` jobs.
### Get access to the GCP Review Apps cluster
-You need to [open an access request (internal link)](https://gitlab.com/gitlab-com/access-requests/issues/new)
+You need to [open an access request (internal link)](https://gitlab.com/gitlab-com/access-requests/-/issues/new)
for the `gcp-review-apps-sg` GCP group. In order to join a group, you must specify the desired GCP role in your access request.
The role is what will grant you specific permissions in order to engage with Review App containers.
@@ -212,7 +212,7 @@ If [Review App Stability](https://app.periscopedata.com/app/gitlab/496118/Engine
dips this may be a signal that the `review-apps-ce/ee` cluster is unhealthy.
Leading indicators may be health check failures leading to restarts or majority failure for Review App deployments.
-The [Review Apps Overview dashboard](https://app.google.stackdriver.com/dashboards/6798952013815386466?project=gitlab-review-apps&timeDomain=1d)
+The [Review Apps Overview dashboard](https://console.cloud.google.com/monitoring/classic/dashboards/6798952013815386466?project=gitlab-review-apps&timeDomain=1d)
aids in identifying load spikes on the cluster, and if nodes are problematic or the entire cluster is trending towards unhealthy.
### Release failed with `ImagePullBackOff`
@@ -278,14 +278,14 @@ kubectl top pods | sort --key 2 --numeric
**Potential cause:**
-This could be a sign that there are too many stale secrets and/or config maps.
+This could be a sign that there are too many stale secrets and/or configuration maps.
**Where to look for further debugging:**
Look at [the list of Configurations](https://console.cloud.google.com/kubernetes/config?project=gitlab-review-apps)
or `kubectl get secret,cm --sort-by='{.metadata.creationTimestamp}' | grep 'review-'`.
-Any secrets or config maps older than 5 days are suspect and should be deleted.
+Any secrets or configuration maps older than 5 days are suspect and should be deleted.
**Useful commands:**
@@ -321,7 +321,7 @@ kubectl get cm --sort-by='{.metadata.creationTimestamp}' | grep 'review-' | grep
#### Finding the problem
-[In the past](https://gitlab.com/gitlab-org/gitlab-foss/issues/62834), it happened
+[In the past](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/62834), it happened
that the `dns-gitlab-review-app-external-dns` Deployment was in a pending state,
effectively preventing all the Review Apps from getting a DNS record assigned,
making them unreachable via domain name.
@@ -354,7 +354,7 @@ For the record, the debugging steps to find out this issue were:
1. Web search for exact error message, following rabbit hole to [a relevant Kubernetes bug report](https://github.com/kubernetes/kubernetes/issues/57345)
1. Access the node over SSH via the GCP console (**Computer Engine > VM
instances** then click the "SSH" button for the node where the `dns-gitlab-review-app-external-dns` pod runs)
-1. In the node: `systemctl --version` => systemd 232
+1. In the node: `systemctl --version` => `systemd 232`
1. Gather some more information:
- `mount | grep kube | wc -l` => e.g. 290
- `systemctl list-units --all | grep -i var-lib-kube | wc -l` => e.g. 142
@@ -406,7 +406,7 @@ find a way to limit it to only us.**
## Other resources
- [Review Apps integration for CE/EE (presentation)](https://docs.google.com/presentation/d/1QPLr6FO4LduROU8pQIPkX1yfGvD13GEJIBOenqoKxR8/edit?usp=sharing)
-- [Stability issues](https://gitlab.com/gitlab-org/quality/team-tasks/issues/212)
+- [Stability issues](https://gitlab.com/gitlab-org/quality/team-tasks/-/issues/212)
### Helpful command line tools
diff --git a/doc/development/testing_guide/testing_levels.md b/doc/development/testing_guide/testing_levels.md
index 9285a910ecf..2210ec94696 100644
--- a/doc/development/testing_guide/testing_levels.md
+++ b/doc/development/testing_guide/testing_levels.md
@@ -295,7 +295,7 @@ graph RL
- **DOM**:
Testing on the real DOM ensures your components work in the intended environment.
- Part of DOM testing is delegated to [cross-browser testing](https://gitlab.com/gitlab-org/quality/team-tasks/issues/45).
+ Part of DOM testing is delegated to [cross-browser testing](https://gitlab.com/gitlab-org/quality/team-tasks/-/issues/45).
- **Properties or state of components**:
On this level, all tests can only perform actions a user would do.
For example: to change the state of a component, a click event would be fired.
@@ -366,7 +366,7 @@ See also:
- The [RSpec testing guidelines](../testing_guide/best_practices.md#rspec).
- System / Feature tests in the [Testing Best Practices](best_practices.md#system--feature-tests).
-- [Issue #26159](https://gitlab.com/gitlab-org/gitlab/issues/26159) which aims at combining those guidelines with this page.
+- [Issue #26159](https://gitlab.com/gitlab-org/gitlab/-/issues/26159) which aims at combining those guidelines with this page.
```mermaid
graph RL
diff --git a/doc/development/understanding_explain_plans.md b/doc/development/understanding_explain_plans.md
index 8c71a27540d..797dfc676eb 100644
--- a/doc/development/understanding_explain_plans.md
+++ b/doc/development/understanding_explain_plans.md
@@ -198,8 +198,7 @@ There are quite a few different types of nodes, so we only cover some of the
more common ones here.
A full list of all the available nodes and their descriptions can be found in
-the [PostgreSQL source file
-"plannodes.h"](https://gitlab.com/postgres/postgres/blob/master/src/include/nodes/plannodes.h)
+the [PostgreSQL source file `plannodes.h`](https://gitlab.com/postgres/postgres/blob/master/src/include/nodes/plannodes.h)
### Seq Scan
@@ -315,25 +314,30 @@ the `Indexes:` section:
```sql
Indexes:
"users_pkey" PRIMARY KEY, btree (id)
- "users_confirmation_token_key" UNIQUE CONSTRAINT, btree (confirmation_token)
- "users_email_key" UNIQUE CONSTRAINT, btree (email)
- "users_reset_password_token_key" UNIQUE CONSTRAINT, btree (reset_password_token)
- "index_on_users_lower_email" btree (lower(email::text))
- "index_on_users_lower_username" btree (lower(username::text))
+ "index_users_on_confirmation_token" UNIQUE, btree (confirmation_token)
+ "index_users_on_email" UNIQUE, btree (email)
+ "index_users_on_reset_password_token" UNIQUE, btree (reset_password_token)
+ "index_users_on_static_object_token" UNIQUE, btree (static_object_token)
+ "index_users_on_unlock_token" UNIQUE, btree (unlock_token)
"index_on_users_name_lower" btree (lower(name::text))
+ "index_users_on_accepted_term_id" btree (accepted_term_id)
"index_users_on_admin" btree (admin)
"index_users_on_created_at" btree (created_at)
"index_users_on_email_trigram" gin (email gin_trgm_ops)
"index_users_on_feed_token" btree (feed_token)
- "index_users_on_ghost" btree (ghost)
+ "index_users_on_group_view" btree (group_view)
"index_users_on_incoming_email_token" btree (incoming_email_token)
+ "index_users_on_managing_group_id" btree (managing_group_id)
"index_users_on_name" btree (name)
"index_users_on_name_trigram" gin (name gin_trgm_ops)
+ "index_users_on_public_email" btree (public_email) WHERE public_email::text <> ''::text
"index_users_on_state" btree (state)
- "index_users_on_state_and_internal_attrs" btree (state) WHERE ghost <> true AND support_bot <> true
- "index_users_on_support_bot" btree (support_bot)
+ "index_users_on_state_and_user_type" btree (state, user_type)
+ "index_users_on_unconfirmed_email" btree (unconfirmed_email) WHERE unconfirmed_email IS NOT NULL
+ "index_users_on_user_type" btree (user_type)
"index_users_on_username" btree (username)
"index_users_on_username_trigram" gin (username gin_trgm_ops)
+ "tmp_idx_on_user_id_where_bio_is_filled" btree (id) WHERE COALESCE(bio, ''::character varying)::text IS DISTINCT FROM ''::text
```
Here we can see there is no index on the `twitter` column, which means
@@ -652,7 +656,7 @@ different queries. The only _rule_ is that you _must always measure_ your query
and related tools such as:
- [`explain.depesz.com`](https://explain.depesz.com/).
-- [Pev](http://tatiyants.com/postgres-query-plan-visualization/).
+- [`explain.dalibo.com/`](https://explain.dalibo.com/).
## Producing query plans
@@ -681,11 +685,11 @@ Planning time: 0.411 ms
Execution time: 0.113 ms
```
-### Chatops
+### ChatOps
-[GitLab employees can also use our chatops solution, available in Slack using the
+[GitLab employees can also use our ChatOps solution, available in Slack using the
`/chatops` slash command](chatops_on_gitlabcom.md).
-You can use chatops to get a query plan by running the following:
+You can use ChatOps to get a query plan by running the following:
```sql
/chatops run explain SELECT COUNT(*) FROM projects WHERE visibility_level IN (0, 20)
@@ -714,7 +718,7 @@ with their own clone of the production database.
Joe is available in the
[`#database-lab`](https://gitlab.slack.com/archives/CLJMDRD8C) channel on Slack.
-Unlike chatops, it gives you a way to execute DDL statements (like creating indexes and tables) and get query plan not only for `SELECT` but also `UPDATE` and `DELETE`.
+Unlike ChatOps, it gives you a way to execute DDL statements (like creating indexes and tables) and get query plan not only for `SELECT` but also `UPDATE` and `DELETE`.
For example, in order to test new index you can do the following:
diff --git a/doc/development/uploads.md b/doc/development/uploads.md
index 1dd6ab5496a..4693c93e3d0 100644
--- a/doc/development/uploads.md
+++ b/doc/development/uploads.md
@@ -92,7 +92,7 @@ We can identify three major use-cases for an upload:
1. **storage:** if we are uploading for storing a file (i.e. artifacts, packages, discussion attachments). In this case [direct upload](#direct-upload) is the proper level as it's the less resource-intensive operation. Additional information can be found on [File Storage in GitLab](file_storage.md).
1. **in-controller/synchronous processing:** if we allow processing **small files** synchronously, using [disk buffered upload](#disk-buffered-upload) may speed up development.
-1. **Sidekiq/asynchronous processing:** Async processing must implement [direct upload](#direct-upload), the reason being that it's the only way to support Cloud Native deployments without a shared NFS.
+1. **Sidekiq/asynchronous processing:** Asynchronous processing must implement [direct upload](#direct-upload), the reason being that it's the only way to support Cloud Native deployments without a shared NFS.
For more details about currently broken feature see [epic &1802](https://gitlab.com/groups/gitlab-org/-/epics/1802).
@@ -114,7 +114,7 @@ We have three kinds of file encoding in our uploads:
1. <i class="fa fa-check-circle"></i> **multipart**: `multipart/form-data` is the most common, a file is encoded as a part of a multipart encoded request.
1. <i class="fa fa-check-circle"></i> **body**: some APIs uploads files as the whole request body.
-1. <i class="fa fa-times-circle"></i> **JSON**: some JSON API uploads files as base64 encoded strings. This will require a change to GitLab Workhorse, which [is planned](https://gitlab.com/gitlab-org/gitlab-workhorse/issues/226).
+1. <i class="fa fa-times-circle"></i> **JSON**: some JSON API uploads files as base64 encoded strings. This will require a change to GitLab Workhorse, which [is planned](https://gitlab.com/gitlab-org/gitlab-workhorse/-/issues/226).
## Uploading technologies
@@ -128,7 +128,7 @@ This is the default kind of upload, and it's most expensive in terms of resource
In this case, workhorse is unaware of files being uploaded and acts as a regular proxy.
-When a multipart request reaches the rails application, `Rack::Multipart` leaves behind tempfiles in `/tmp` and uses valuable Ruby process time to copy files around.
+When a multipart request reaches the rails application, `Rack::Multipart` leaves behind temporary files in `/tmp` and uses valuable Ruby process time to copy files around.
```mermaid
sequenceDiagram
diff --git a/doc/development/utilities.md b/doc/development/utilities.md
index dfdc5c66114..52151d37038 100644
--- a/doc/development/utilities.md
+++ b/doc/development/utilities.md
@@ -49,7 +49,7 @@ Refer to: <https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/utils/mer
## `Override`
-Refer to <https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/utils/override.rb>:
+Refer to [`override.rb`](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/utils/override.rb):
- This utility can help you check if one method would override
another or not. It is the same concept as Java's `@Override` annotation
@@ -153,7 +153,7 @@ Refer to <https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/utils/stro
## `RequestCache`
-Refer to <https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/cache/request_cache.rb>.
+Refer to [`request_cache.rb`](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/cache/request_cache.rb).
This module provides a simple way to cache values in RequestStore,
and the cache key would be based on the class name, method name,
diff --git a/doc/development/value_stream_analytics.md b/doc/development/value_stream_analytics.md
index 69b07eb7c86..70b16cc1739 100644
--- a/doc/development/value_stream_analytics.md
+++ b/doc/development/value_stream_analytics.md
@@ -183,7 +183,7 @@ Currently supported parents:
### Default stages
-The [original implementation](https://gitlab.com/gitlab-org/gitlab/issues/847) of value stream analytics defined 7 stages. These stages are always available for each parent, however altering these stages is not possible.
+The [original implementation](https://gitlab.com/gitlab-org/gitlab/-/issues/847) of value stream analytics defined 7 stages. These stages are always available for each parent, however altering these stages is not possible.
​
To make things efficient and reduce the number of records created, the default stages are expressed as in-memory objects (not persisted). When the user creates a custom stage for the first time, all the stages will be persisted. This behavior is implemented in the value stream analytics service objects.
​
diff --git a/doc/development/what_requires_downtime.md b/doc/development/what_requires_downtime.md
index 8ea9f70fc7a..407899b23d5 100644
--- a/doc/development/what_requires_downtime.md
+++ b/doc/development/what_requires_downtime.md
@@ -130,12 +130,12 @@ class CleanupUsersUpdatedAtRename < ActiveRecord::Migration[4.2]
end
```
-NOTE: **Note:** If you're renaming a [large table](https://gitlab.com/gitlab-org/gitlab/-/blob/master/rubocop/migration_helpers.rb#L9), please carefully consider the state when the first migration has run but the second cleanup migration hasn't been run yet.
+NOTE: **Note:** If you're renaming a [large table](https://gitlab.com/gitlab-org/gitlab/-/blob/master/rubocop/rubocop-migrations.yml#L3), please carefully consider the state when the first migration has run but the second cleanup migration hasn't been run yet.
With [Canary](https://about.gitlab.com/handbook/engineering/infrastructure/library/canary/) it is possible that the system runs in this state for a significant amount of time.
## Changing Column Constraints
-Adding or removing a NOT NULL clause (or another constraint) can typically be
+Adding or removing a `NOT NULL` clause (or another constraint) can typically be
done without requiring downtime. However, this does require that any application
changes are deployed _first_. Thus, changing the constraints of a column should
happen in a post-deployment migration.
@@ -143,35 +143,11 @@ happen in a post-deployment migration.
NOTE: Avoid using `change_column` as it produces an inefficient query because it re-defines
the whole column type.
-To add a NOT NULL constraint, use the `add_not_null_constraint` migration helper:
+You can check the following guides for each specific use case:
-```ruby
-# A post-deployment migration in db/post_migrate
-class AddNotNull < ActiveRecord::Migration[4.2]
- include Gitlab::Database::MigrationHelpers
-
- disable_ddl_transaction!
-
- def up
- add_not_null_constraint :users, :username
- end
-
- def down
- remove_not_null_constraint :users, :username
- end
-end
-```
-
-If the column to be updated requires cleaning first (e.g. there are `NULL` values), you should:
-
-1. Add the `NOT NULL` constraint with `validate: false`
-
- `add_not_null_constraint :users, :username, validate: false`
-
-1. Clean up the data with a data migration
-1. Validate the `NOT NULL` constraint with a followup migration
-
- `validate_not_null_constraint :users, :username`
+- [Adding foreign-key constraints](migration_style_guide.md#adding-foreign-key-constraints)
+- [Adding `NOT NULL` constraints](database/not_null_constraints.md)
+- [Adding limits to text columns](database/strings_and_the_text_data_type.md)
## Changing Column Types
diff --git a/doc/development/windows.md b/doc/development/windows.md
index b5309002222..c92a468fad3 100644
--- a/doc/development/windows.md
+++ b/doc/development/windows.md
@@ -47,7 +47,7 @@ There is a chance that your Google Cloud group may already have an image
built. Search the available images before you do the work to build your
own.
-Build a Google Cloud image with the above shared runners repo by doing the following:
+Build a Google Cloud image with the above shared runners repository by doing the following:
1. Install [Packer](https://www.packer.io/) (tested to work with version 1.5.1).
1. Install Packer Windows Update Provisioner.
@@ -55,7 +55,7 @@ Build a Google Cloud image with the above shared runners repo by doing the follo
1. Run the command `go build -o packer-provisioner-windows-update` (requires `go` to be installed).
1. Verify `packer-provisioner-windows-update` is in the `PATH` environment variable.
1. Add all [required environment variables](https://gitlab.com/gitlab-org/ci-cd/shared-runners/images/gcp/windows-containers/-/blob/master/packer.json#L2-10)
- in the `packer.json` file to your environment (perhaps use [direnv](https://direnv.net/)).
+ in the `packer.json` file to your environment (perhaps use [`direnv`](https://direnv.net/)).
1. Build the image by running the command: `packer build packer.json`.
## How to use a Windows image in GCP
@@ -96,7 +96,7 @@ Here are a few tips on GCP and Windows.
### GCP cost savings
To minimise the cost of your GCP VM instance, stop it when you're not using it.
-If you do, you'll need to redownload the RDP file from the console as the IP
+If you do, you'll need to re-download the RDP file from the console as the IP
address changes every time you stop and start it.
### chocolatey
@@ -119,13 +119,13 @@ You can install .NET version 3 support with the following `DISM` command:
`DISM /Online /Enable-Feature /FeatureName:NetFx3 /All`
-### nix -> Windows cmd tips
+### nix -> Windows `cmd` tips
-The first tip for using the Windows command shell is to open Powershell and use that instead.
+The first tip for using the Windows command shell is to open PowerShell and use that instead.
-Start Powershell: `start powershell`.
+Start PowerShell: `start powershell`.
-Powershell has aliases for all of the following commands so you don't have to learn the native commands:
+PowerShell has aliases for all of the following commands so you don't have to learn the native commands:
- `ls` ---> `dir`
- `rm` ---> `del`
diff --git a/doc/gitlab-basics/create-project.md b/doc/gitlab-basics/create-project.md
index 152fb24699e..def14cfce6d 100644
--- a/doc/gitlab-basics/create-project.md
+++ b/doc/gitlab-basics/create-project.md
@@ -103,7 +103,7 @@ You can improve the existing built-in templates or contribute new ones in the
#### Custom project templates **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/6860) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.2.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/6860) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.2.
Creating new projects based on custom project templates is a convenient option for
quickly starting projects.
@@ -123,7 +123,7 @@ To use a custom project template on the **New project** page:
## Push to create a new project
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/26388) in GitLab 10.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/26388) in GitLab 10.5.
When you create a new repository locally, instead of going to GitLab to manually
create a new project and then [clone the repo](start-using-git.md#clone-a-repository)
diff --git a/doc/gitlab-basics/start-using-git.md b/doc/gitlab-basics/start-using-git.md
index 9ebcf258ee9..439032f39b3 100644
--- a/doc/gitlab-basics/start-using-git.md
+++ b/doc/gitlab-basics/start-using-git.md
@@ -22,6 +22,11 @@ This guide will help you get started with Git through the command line and can b
for Git commands in the future. If you're only looking for a quick reference of Git commands, you
can download GitLab's [Git Cheat Sheet](https://about.gitlab.com/images/press/git-cheat-sheet.pdf).
+> For more information about the advantages of working with Git and GitLab:
+>
+> - <i class="fa fa-youtube-play youtube" aria-hidden="true"></i>&nbsp;Watch the [GitLab Source Code Management Walkthrough](https://www.youtube.com/watch?v=wTQ3aXJswtM) video.
+> - Learn how GitLab became the backbone of [Worldline](https://about.gitlab.com/customers/worldline/)’s development environment.
+
TIP: **Tip:**
To help you visualize what you're doing locally, there are
[Git GUI apps](https://git-scm.com/download/gui/) you can install.
@@ -45,7 +50,7 @@ prompt, terminal, and command line) of your preference. Here are some suggestion
- [iTerm2](https://www.iterm2.com/), which you can integrate with [zsh](https://git-scm.com/book/id/v2/Appendix-A%3A-Git-in-Other-Environments-Git-in-Zsh) and [oh my zsh](https://ohmyz.sh/) for color highlighting, among other handy features for Git users.
- For Windows users:
- Built-in: **cmd**. Click the search icon on the bottom navbar on Windows and type "cmd" to find it.
- - [PowerShell](https://docs.microsoft.com/en-us/powershell/scripting/install/installing-windows-powershell?view=powershell-7): a Windows "powered up" shell, from which you can execute a greater number of commands.
+ - [PowerShell](https://docs.microsoft.com/en-us/powershell/scripting/windows-powershell/install/installing-windows-powershell?view=powershell-7): a Windows "powered up" shell, from which you can execute a greater number of commands.
- Git Bash: it comes built into [Git for Windows](https://gitforwindows.org/).
- For Linux users:
- Built-in: [Linux Terminal](https://www.howtogeek.com/140679/beginner-geek-how-to-start-using-the-linux-terminal/).
diff --git a/doc/install/aws/img/aws_ha_architecture_diagram.png b/doc/install/aws/img/aws_ha_architecture_diagram.png
index e019ed61abf..dc63d36e0b3 100644
--- a/doc/install/aws/img/aws_ha_architecture_diagram.png
+++ b/doc/install/aws/img/aws_ha_architecture_diagram.png
Binary files differ
diff --git a/doc/install/aws/img/rds_subnet_group.png b/doc/install/aws/img/rds_subnet_group.png
deleted file mode 100644
index 7c6157e38e0..00000000000
--- a/doc/install/aws/img/rds_subnet_group.png
+++ /dev/null
Binary files differ
diff --git a/doc/install/aws/index.md b/doc/install/aws/index.md
index 41f8d7babac..813e343f2cc 100644
--- a/doc/install/aws/index.md
+++ b/doc/install/aws/index.md
@@ -12,9 +12,7 @@ For organizations with 300 users or less, the recommended AWS installation metho
## Introduction
-GitLab on AWS can leverage many of the services that are already
-configurable. These services offer a great deal of
-flexibility and can be adapted to the needs of most companies.
+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
@@ -59,8 +57,6 @@ Here's a list of the AWS services we will use, with links to pricing information
Redis configuration. See the
[Amazon ElastiCache pricing](https://aws.amazon.com/elasticache/pricing/).
-NOTE: **Note:** Please note that while we will be using EBS for storage, we do not recommend using EFS as it may negatively impact GitLab's performance. You can review the [relevant documentation](../../administration/high_availability/nfs.md#avoid-using-awss-elastic-file-system-efs) for more details.
-
## 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 config, 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:
@@ -227,17 +223,21 @@ We also need to create two private route tables so that instances in each privat
## 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 HTTP port 80, HTTPS port 443, and TCP port 22 for both load balancer and instance protocols and ports.
- 1. In the **Select Subnets** section, select both public subnets from the list.
-1. Click **Assign Security Groups** and select **Create a new security group**, give it a name
+ 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 from a single IP address or an IP address range in CIDR notation.
-1. Click **Configure Security Settings** and select an SSL/TLS certificate from ACM or upload a certificate to IAM.
+ 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.
@@ -261,11 +261,16 @@ On the Route 53 dashboard, click **Hosted zones** in the left navigation bar:
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. Update your DNS records with your domain registrar. The steps for doing this vary depending on which registrar you use and is beyond the scope of this guide.
+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 admin 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
@@ -280,7 +285,10 @@ We need a security group for our database that will allow inbound traffic from t
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 add a **PostgreSQL** rule, and set the "Custom" source as the `gitlab-loadbalancer-sec-group` we created earlier. The default PostgreSQL port is `5432`, which we'll also use when creating our database below.
+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
@@ -288,11 +296,10 @@ We need a security group for our database that will allow inbound traffic from t
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. Under **Add subnets**, click **Add all the subnets related to this VPC** and remove the public ones, we only want the **private subnets**. In the end, you should see `10.0.1.0/24` and `10.0.3.0/24` (as we defined them in the [subnets section](#subnets)).
+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.
- ![RDS Subnet Group](img/rds_subnet_group.png)
-
### Create the database
DANGER: **Danger:** 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.
@@ -301,7 +308,7 @@ 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 **PostgreSQL 10.9-R1** from the version dropdown menu (check the [database requirements](../../install/requirements.md#postgresql-requirements) to see if there are any updates on this for your chosen version of GitLab).
+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.
@@ -329,7 +336,7 @@ Now that the database is created, let's move on to setting up Redis with ElastiC
## Redis with ElastiCache
ElastiCache is an in-memory hosted caching solution. Redis maintains its own
-persistence and is used for certain types of the GitLab application.
+persistence and is used to store session data, temporary cache information, and background job queues for the GitLab application.
### Create a Redis Security Group
@@ -559,9 +566,9 @@ Let's create an EC2 instance where we'll install Gitaly:
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**.
- > **Optional:** 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/).
+NOTE: **Optional:** 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 GitLab’s performance. You can review the [relevant documentation](../../administration/high_availability/nfs.md#avoid-using-awss-elastic-file-system-efs) 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/index.md#running-gitaly-on-its-own-server). Perform the client setup steps from that document on the [GitLab instance we created](#install-gitlab) above.
+Now that we have our EC2 instance ready, follow the [documentation to install GitLab and set up Gitaly on its own server](../../administration/gitaly/index.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
@@ -600,7 +607,7 @@ sudo cp -R /etc/ssh/* /etc/ssh_static
In `/etc/ssh/sshd_config` update the following:
-```bash
+```shell
# HostKeys for protocol version 2
HostKey /etc/ssh_static/ssh_host_rsa_key
HostKey /etc/ssh_static/ssh_host_dsa_key
@@ -620,7 +627,7 @@ Remember to run `sudo gitlab-ctl reconfigure` after saving the changes to the `g
NOTE: **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)
+There is [work in progress](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/196)
to eliminate the need for NFS to support GitLab Pages.
---
@@ -774,7 +781,7 @@ 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)
+[open an issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new)
to request additional material:
- [Scaling GitLab](../../administration/reference_architectures/index.md):
diff --git a/doc/install/azure/index.md b/doc/install/azure/index.md
index fbc81da20d4..3cf963bdf57 100644
--- a/doc/install/azure/index.md
+++ b/doc/install/azure/index.md
@@ -177,7 +177,7 @@ Click **"Save"** for the changes to take effect.
domain registrar which points to the public IP address of your Azure VM. If you do this, you'll need
to make sure your VM is configured to use a _static_ public IP address (i.e. not a _dynamic_ one)
or you will have to reconfigure the DNS `A` record each time Azure reassigns your VM a new public IP
-address. Read [IP address types and allocation methods in Azure](https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-ip-addresses-overview-arm) to learn more.
+address. Read [Public IP addresses](https://docs.microsoft.com/en-us/azure/virtual-network/public-ip-addresses) to learn more.
## Let's open some ports
diff --git a/doc/install/digitaloceandocker.md b/doc/install/digitaloceandocker.md
index ccfb97afe28..fe32b37a9ed 100644
--- a/doc/install/digitaloceandocker.md
+++ b/doc/install/digitaloceandocker.md
@@ -31,12 +31,12 @@ locally on either macOS or Linux.
NOTE: **Note:**
The rest of the steps are identical for macOS and Linux.
-## Create new docker host
+## Create new Docker host
1. Login to Digital Ocean.
1. Generate a new API token at <https://cloud.digitalocean.com/settings/api/tokens>.
- This command will create a new DO droplet called `gitlab-test-env-do` that will act as a docker host.
+ This command will create a new DO droplet called `gitlab-test-env-do` that will act as a Docker host.
NOTE: **Note:**
4GB is the minimum requirement for a Docker host that will run more than one GitLab instance.
@@ -69,20 +69,20 @@ Resource: <https://docs.docker.com/machine/drivers/digital-ocean/>.
In this example we'll create a GitLab EE 8.10.8 instance.
-First connect the docker client to the docker host you created previously.
+First connect the Docker client to the Docker host you created previously.
```shell
eval "$(docker-machine env gitlab-test-env-do)"
```
-You can add this to your `~/.bash_profile` file to ensure the `docker` client uses the `gitlab-test-env-do` docker host
+You can add this to your `~/.bash_profile` file to ensure the `docker` client uses the `gitlab-test-env-do` Docker host
### Create new GitLab container
- HTTP port: `8888`
- SSH port: `2222`
- Set `gitlab_shell_ssh_port` using `--env GITLAB_OMNIBUS_CONFIG`
-- Hostname: IP of docker host
+- Hostname: IP of Docker host
- Container name: `gitlab-test-8.10`
- GitLab version: **EE** `8.10.8-ee.0`
@@ -108,7 +108,7 @@ gitlab/gitlab-ee:$VERSION
### Connect to the GitLab container
-#### Retrieve the docker host IP
+#### Retrieve the Docker host IP
```shell
docker-machine ip gitlab-test-env-do
diff --git a/doc/install/google_cloud_platform/img/boot_disk.png b/doc/install/google_cloud_platform/img/boot_disk.png
deleted file mode 100644
index b9f7eed6601..00000000000
--- a/doc/install/google_cloud_platform/img/boot_disk.png
+++ /dev/null
Binary files differ
diff --git a/doc/install/google_cloud_platform/img/vm_details.png b/doc/install/google_cloud_platform/img/vm_details.png
index 85b9ca066c8..aab9a46fa11 100644
--- a/doc/install/google_cloud_platform/img/vm_details.png
+++ b/doc/install/google_cloud_platform/img/vm_details.png
Binary files differ
diff --git a/doc/install/google_cloud_platform/index.md b/doc/install/google_cloud_platform/index.md
index 433eeda00b1..8ca5c5c266a 100644
--- a/doc/install/google_cloud_platform/index.md
+++ b/doc/install/google_cloud_platform/index.md
@@ -33,13 +33,13 @@ To deploy GitLab on GCP you first need to create a virtual machine:
![Search for GitLab](img/launch_vm.png)
1. On the next page, you can select the type of VM as well as the
- estimated costs. Provide the name of the instance, desired datacenter, and machine type. Note that GitLab recommends at least 2 vCPU's and 4GB of RAM.
+ estimated costs. Provide the name of the instance, desired datacenter, and machine type.
+ Note our [hardware requirements for different user base sizes](../requirements.md#hardware-requirements).
![Launch on Compute Engine](img/vm_details.png)
-1. Click **Change** under Boot disk to select the size, type, and desired operating system. GitLab supports a [variety of linux operating systems](../requirements.md), including Ubuntu and Debian. Click **Select** when finished.
-
- ![Deploy in progress](img/boot_disk.png)
+1. To select the size, type, and desired [operating system](../requirements.md#supported-linux-distributions),
+ click **Change** under `Boot disk`. Click **Select** when finished.
1. As a last step allow HTTP and HTTPS traffic, then click **Create**. The process will finish in a few seconds.
diff --git a/doc/install/installation.md b/doc/install/installation.md
index dd619e9e7b3..0997062006d 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -134,7 +134,7 @@ Make sure you have the right version of Git installed:
# Install Git
sudo apt-get install -y git-core
-# Make sure Git is version 2.26.2 or higher (minimal supported version is 2.22.0)
+# Make sure Git is version 2.27.0 or higher (minimal supported version is 2.25.0)
git --version
```
@@ -142,7 +142,7 @@ Starting with GitLab 12.0, Git is required to be compiled with `libpcre2`.
Find out if that's the case:
```shell
-ldd $(which git) | grep pcre2
+ldd $(command -v git) | grep pcre2
```
The output should contain `libpcre2-8.so.0`.
@@ -181,9 +181,9 @@ sudo make install
# Download and compile from source
cd /tmp
-curl --remote-name --location --progress https://www.kernel.org/pub/software/scm/git/git-2.26.2.tar.gz
-echo 'e1c17777528f55696815ef33587b1d20f5eec246669f3b839d15dbfffad9c121 git-2.26.2.tar.gz' | shasum -a256 -c - && tar -xzf git-2.26.2.tar.gz
-cd git-2.26.2/
+curl --remote-name --location --progress https://www.kernel.org/pub/software/scm/git/git-2.27.0.tar.gz
+echo '77ded85cbe42b1ffdc2578b460a1ef5d23bcbc6683eabcafbb0d394dffe2e787 git-2.27.0.tar.gz' | shasum -a256 -c - && tar -xzf git-2.27.0.tar.gz
+cd git-2.27.0/
./configure --with-libpcre
make prefix=/usr/local all
@@ -200,7 +200,7 @@ needs to be installed.
sudo apt-get install -y graphicsmagick
```
-**Note:** In order to receive mail notifications, make sure to install a mail server. By default, Debian is shipped with exim4 but this [has problems](https://gitlab.com/gitlab-org/gitlab-foss/issues/12754) while Ubuntu does not ship with one. The recommended mail server is postfix and you can install it with:
+**Note:** In order to receive mail notifications, make sure to install a mail server. By default, Debian is shipped with exim4 but this [has problems](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/12754) while Ubuntu does not ship with one. The recommended mail server is postfix and you can install it with:
```shell
sudo apt-get install -y postfix
@@ -208,6 +208,13 @@ sudo apt-get install -y postfix
Then select 'Internet Site' and press enter to confirm the hostname.
+[GitLab Workhorse](https://gitlab.com/gitlab-org/gitlab-workhorse#dependencies)
+requires `exiftool` to remove EXIF data from uploaded images.
+
+```shell
+sudo apt-get install -y libimage-exiftool-perl
+```
+
## 2. Ruby
The Ruby interpreter is required to run GitLab.
@@ -216,10 +223,9 @@ The Ruby interpreter is required to run GitLab.
dropped support for Ruby 2.5.x.
The use of Ruby version managers such as [RVM](https://rvm.io/), [rbenv](https://github.com/rbenv/rbenv) or [chruby](https://github.com/postmodern/chruby) with GitLab
-in production, frequently leads to hard to diagnose problems. For example,
-GitLab Shell is called from OpenSSH, and having a version manager can prevent
-pushing and pulling over SSH. Version managers are not supported and we strongly
-advise everyone to follow the instructions below to use a system Ruby.
+in production, frequently leads to hard to diagnose problems. Version managers
+are not supported and we strongly advise everyone to follow the instructions
+below to use a system Ruby.
Linux distributions generally have older versions of Ruby available, so these
instructions are designed to install Ruby from the official source code.
@@ -234,9 +240,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.6/ruby-2.6.5.tar.gz
-echo '1416ce288fb8bfeae07a12b608540318c9cace71 ruby-2.6.5.tar.gz' | shasum -c - && tar xzf ruby-2.6.5.tar.gz
-cd ruby-2.6.5
+curl --remote-name --progress https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.6.tar.gz
+echo '2d78048e293817f38d4ede4ebc7873013e97bb0b ruby-2.6.6.tar.gz' | shasum -c - && tar xzf ruby-2.6.6.tar.gz
+cd ruby-2.6.6
./configure --disable-install-rdoc
make
@@ -565,8 +571,8 @@ If you want to use Kerberos for user authentication, omit `kerberos` in the `--w
GitLab Shell is an SSH access and repository management software developed specially for GitLab.
```shell
-# Run the installation task for gitlab-shell (replace `REDIS_URL` if needed):
-sudo -u git -H bundle exec rake gitlab:shell:install REDIS_URL=unix:/var/run/redis/redis.sock RAILS_ENV=production SKIP_STORAGE_VALIDATION=true
+# Run the installation task for gitlab-shell:
+sudo -u git -H bundle exec rake gitlab:shell:install RAILS_ENV=production
# By default, the gitlab-shell config is generated from your main GitLab config.
# You can review (and modify) the gitlab-shell config as follows:
@@ -579,13 +585,6 @@ If you want to use HTTPS, see [Using HTTPS](#using-https) for the additional ste
NOTE: **Note:**
Make sure your hostname can be resolved on the machine itself by either a proper DNS record or an additional line in `/etc/hosts` ("127.0.0.1 hostname"). This might be necessary, for example, if you set up GitLab behind a reverse proxy. If the hostname cannot be resolved, the final installation check will fail with `Check GitLab API access: FAILED. code: 401` and pushing commits will be rejected with `[remote rejected] master -> master (hook declined)`.
-NOTE: **Note:**
-GitLab Shell application startup time can be greatly reduced by disabling RubyGems. This can be done in several ways:
-
-- Export `RUBYOPT=--disable-gems` environment variable for the processes.
-- Compile Ruby with `configure --disable-rubygems` to disable RubyGems by default. Not recommended for system-wide Ruby.
-- Omnibus GitLab [replaces the *shebang* line of the `gitlab-shell/bin/*` scripts](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/1707).
-
### Install GitLab Workhorse
GitLab-Workhorse uses [GNU Make](https://www.gnu.org/software/make/). The
@@ -986,7 +985,7 @@ Using Sidekiq directly will still be supported until 14.0. So if you're experien
1. Edit the system `init.d` script to remove the `SIDEKIQ_WORKERS` flag. If you have `/etc/default/gitlab`, then you should edit it instead.
1. Restart GitLab.
-1. [Create an issue](https://gitlab.com/gitlab-org/gitlab/issues/-/new) describing the problem.
+1. [Create an issue](https://gitlab.com/gitlab-org/gitlab/-/issues/-/new) describing the problem.
## Troubleshooting
diff --git a/doc/install/ldap.md b/doc/install/ldap.md
index d8d54864586..164478f09f7 100644
--- a/doc/install/ldap.md
+++ b/doc/install/ldap.md
@@ -1,5 +1,5 @@
---
-redirect_to: '../administration/auth/ldap.md'
+redirect_to: '../administration/auth/ldap/index.md'
---
-This document was moved to [another location](../administration/auth/ldap.md).
+This document was moved to [another location](../administration/auth/ldap/index.md).
diff --git a/doc/install/openshift_and_gitlab/index.md b/doc/install/openshift_and_gitlab/index.md
index fd81b7f6caf..7ae23d6831e 100644
--- a/doc/install/openshift_and_gitlab/index.md
+++ b/doc/install/openshift_and_gitlab/index.md
@@ -253,7 +253,7 @@ related object definitions to be created together, as well as a set of
parameters for those objects.
The template for GitLab resides in the Omnibus GitLab repository under the
-docker directory. Let's download it locally with `wget`:
+Docker directory. Let's download it locally with `wget`:
```shell
wget https://gitlab.com/gitlab-org/omnibus-gitlab/raw/master/docker/openshift-template.json
@@ -324,7 +324,7 @@ Now that we configured this, let's see how to manage and scale GitLab.
Setting up GitLab for the first time might take a while depending on your
internet connection and the resources you have attached to the all-in-one VM.
-GitLab's docker image is quite big (~500MB), so you'll have to wait until
+GitLab's Docker image is quite big (~500MB), so you'll have to wait until
it's downloaded and configured before you use it.
### Watch while GitLab gets deployed
diff --git a/doc/install/requirements.md b/doc/install/requirements.md
index 09ad5f9afd7..0673f3e7ea3 100644
--- a/doc/install/requirements.md
+++ b/doc/install/requirements.md
@@ -35,7 +35,7 @@ Please see the [installation from source guide](installation.md) and the [instal
### Microsoft Windows
GitLab is developed for Linux-based operating systems.
-It does **not** run on Microsoft Windows, and we have no plans to support it in the near future. For the latest development status view this [issue](https://gitlab.com/gitlab-org/gitlab/issues/22337).
+It does **not** run on Microsoft Windows, and we have no plans to support it in the near future. For the latest development status view this [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/22337).
Please consider using a virtual machine to run GitLab.
## Software requirements
@@ -45,29 +45,29 @@ Please consider using a virtual machine to run GitLab.
GitLab requires Ruby (MRI) 2.6. Beginning in GitLab 12.2, we no longer support Ruby 2.5 and lower.
You must use the standard MRI implementation of Ruby.
-We love [JRuby](https://www.jruby.org/) and [Rubinius](https://rubinius.com), but GitLab
+We love [JRuby](https://www.jruby.org/) and [Rubinius](https://github.com/rubinius/rubinius#the-rubinius-language-platform), but GitLab
needs several Gems that have native extensions.
### Go versions
-The minimum required Go version is 1.12.
+The minimum required Go version is 1.13.
### Git versions
-GitLab 11.11 and higher only supports Git 2.21.x and newer, and
-[dropped support for older versions](https://gitlab.com/gitlab-org/gitlab-foss/issues/54255).
+GitLab 11.11 and higher only supports Git 2.24.x and newer, and
+[dropped support for older versions](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/54255).
### Node.js versions
Beginning in GitLab 12.9, we only support node.js 10.13.0 or higher, and we have dropped
support for node.js 8. (node.js 6 support was dropped in GitLab 11.8)
-We recommend Node 12.x, as it is faster.
+We recommend Node 12.x, as it's faster.
GitLab uses [webpack](https://webpack.js.org/) to compile frontend assets, which requires a minimum
version of Node.js 10.13.0.
-You can check which version you are running with `node -v`. If you are running
+You can check which version you're running with `node -v`. If you're running
a version older than `v10.13.0`, you need to update it to a newer version. You
can find instructions to install from community maintained packages or compile
from source at the [Node.js website](https://nodejs.org/en/download/).
@@ -80,122 +80,82 @@ GitLab requires Redis 5.0+. Beginning in GitLab 13.0, lower versions are not sup
### Storage
-The necessary hard drive space largely depends on the size of the repos you want to store in GitLab but as a *rule of thumb* you should have at least as much free space as all your repos combined take up.
+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.
-If you want to be flexible about growing your hard drive space in the future consider mounting it using LVM so you can add more hard drives when you need them.
+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.
-If you have enough RAM memory and a recent CPU the speed of GitLab is mainly limited by hard drive seek times. Having a fast drive (7200 RPM and up) or a solid state drive (SSD) will improve the responsiveness of GitLab.
+If you have enough RAM and a recent CPU the speed of GitLab is mainly limited by hard drive seek times. Having a fast drive (7200 RPM and up) or a solid state drive (SSD) will improve the responsiveness of GitLab.
-NOTE: **Note:** Since file system performance may affect GitLab's overall performance, we do not recommend using EFS for storage. See the [relevant documentation](../administration/high_availability/nfs.md#avoid-using-awss-elastic-file-system-efs) for more details.
+NOTE: **Note:** Since file system performance may affect GitLab's overall performance, [we don't recommend using AWS EFS for storage](../administration/high_availability/nfs.md#avoid-using-awss-elastic-file-system-efs).
### CPU
-This is the recommended minimum hardware for a handful of example GitLab user base sizes. Your exact needs may be more, depending on your workload. Your workload is influenced by factors such as - but not limited to - how active your users are, how much automation you use, mirroring, and repo/change size.
+CPU requirements are dependent on the number of users and expected workload. Your exact needs may be more, depending on your workload. Your workload is influenced by factors such as - but not limited to - how active your users are, how much automation you use, mirroring, and repo/change size.
-- 1 core supports up to 100 users but the application can be a bit slower due to having all workers and background jobs running on the same core
-- **2 cores** is the **recommended** minimum number of cores and supports up to 100 users
-- 4 cores supports up to 500 users
-- 8 cores supports up to 1,000 users
-- 32 cores supports up to 5,000 users
+The following is the recommended minimum CPU hardware guidance for a handful of example GitLab user base sizes.
+
+- **4 cores** is the **recommended** minimum number of cores and supports up to 500 users
+- 8 cores supports up to 1000 users
- More users? Consult the [reference architectures page](../administration/reference_architectures/index.md)
### Memory
-This is the recommended minimum hardware for a handful of example GitLab user base sizes. Your exact needs may be more, depending on your workload. Your workload is influenced by factors such as - but not limited to - how active your users are, how much automation you use, mirroring, and repo/change size.
+Memory requirements are dependent on the number of users and expected workload. Your exact needs may be more, depending on your workload. Your workload is influenced by factors such as - but not limited to - how active your users are, how much automation you use, mirroring, and repo/change size.
-You need at least 8GB of addressable memory (RAM + swap) to install and use GitLab!
-The operating system and any other running applications will also be using memory
-so keep in mind that you need at least 4GB available before running GitLab. With
-less memory GitLab will give strange errors during the reconfigure run and 500
-errors during usage.
+The following is the recommended minimum Memory hardware guidance for a handful of example GitLab user base sizes.
-- 4GB RAM + 4GB swap supports up to 100 users but it will be very slow
-- **8GB RAM** is the **recommended** minimum memory size for all installations and supports up to 100 users
-- 16GB RAM supports up to 500 users
-- 32GB RAM supports up to 1,000 users
-- 128GB RAM supports up to 5,000 users
+- **4GB RAM** is the **required** minimum memory size and supports up to 500 users
+ - Our [Memory Team](https://about.gitlab.com/handbook/engineering/development/enablement/memory/) is working to reduce the memory requirement.
+- 8GB RAM supports up to 1000 users
- More users? Consult the [reference architectures page](../administration/reference_architectures/index.md)
-We recommend having at least [2GB of swap on your server](https://askubuntu.com/a/505344/310789), even if you currently have
-enough available RAM. Having swap will help reduce the chance of errors occurring
-if your available memory changes. We also recommend [configuring the kernel's swappiness setting](https://askubuntu.com/a/103916)
+In addition to the above, we generally recommend having at least 2GB of swap on your server,
+even if you currently have enough available RAM. Having swap will help reduce the chance of errors occurring
+if your available memory changes. We also recommend configuring the kernel's swappiness setting
to a low value like `10` to make the most of your RAM while still having the swap
available when needed.
-Our [Memory Team](https://about.gitlab.com/handbook/engineering/development/enablement/memory/) is actively working to reduce the memory requirement.
-
-NOTE: **Note:** The 25 workers of Sidekiq will show up as separate processes in your process overview (such as `top` or `htop`) but they share the same RAM allocation since Sidekiq is a multithreaded application. Please see the section below about Unicorn workers for information about how many you need for those.
-
## Database
-The server running the database should have _at least_ 5-10 GB of storage
-available, though the exact requirements depend on the size of the GitLab
-installation (e.g. the number of users, projects, etc).
-
-We currently support the following databases:
-
-- PostgreSQL
-
+PostgreSQL is the only supported database, which is bundled with the Omnibus GitLab package.
+You can also use an [external PostgreSQL database](https://docs.gitlab.com/omnibus/settings/database.html#using-a-non-packaged-postgresql-database-management-server).
Support for MySQL was removed in GitLab 12.1. Existing users using GitLab with
MySQL/MariaDB are advised to [migrate to PostgreSQL](../update/mysql_to_postgresql.md) before upgrading.
### PostgreSQL Requirements
+The server running PostgreSQL should have _at least_ 5-10 GB of storage
+available, though the exact requirements [depend on the number of users](../administration/reference_architectures/index.md).
+
We highly recommend users to use the minimum PostgreSQL versions specified below as these are the versions used for development and testing.
GitLab version | Minimum PostgreSQL version
-|-
10.0 | 9.6
12.10 | 11
+13.0 | 11
-Users using PostgreSQL must ensure the `pg_trgm` extension is loaded into every
-GitLab database. This extension can be enabled (using a PostgreSQL super user)
-by running the following query for every database:
-
-```sql
-CREATE EXTENSION pg_trgm;
-```
+You must also ensure the `pg_trgm` extension is loaded into every
+GitLab database. This extension [can be enabled](https://www.postgresql.org/docs/11/sql-createextension.html) using a PostgreSQL super user.
-On some systems you may need to install an additional package (e.g.
+On some systems you may need to install an additional package (for example,
`postgresql-contrib`) for this extension to become available.
-NOTE: **Note:** Support for PostgreSQL 9.6 and 10 will be removed in GitLab 13.0 so that GitLab can benefit from PostgreSQL 11 improvements, such as partitioning. For the schedule on adding support for PostgreSQL 11 and 12, see [the related epic](https://gitlab.com/groups/gitlab-org/-/epics/2184). For the release schedule for GitLab 13.0, see [GitLab's release and maintenance policy](../policy/maintenance.md).
+NOTE: **Note:** Support for [PostgreSQL 9.6 and 10 has been removed in GitLab 13.0](https://about.gitlab.com/releases/2020/05/22/gitlab-13-0-released/#postgresql-11-is-now-the-minimum-required-version-to-install-gitlab) so that GitLab can benefit from PostgreSQL 11 improvements, such as partitioning. For the schedule of transitioning to PostgreSQL 12, see [the related epic](https://gitlab.com/groups/gitlab-org/-/epics/2184).
#### Additional requirements for GitLab Geo
-If you are using [GitLab Geo](../development/geo.md):
+If you're using [GitLab Geo](../administration/geo/replication/index.md):
- We strongly recommend running Omnibus-managed instances as they are actively
developed and tested. We aim to be compatible with most external (not managed
- by Omnibus) databases (for example, AWS RDS) but we do not guarantee
- compatibility.
-- The
- [tracking database](../development/geo.md#using-the-tracking-database)
- requires the
- [postgres_fdw](https://www.postgresql.org/docs/11/postgres-fdw.html)
- extension.
-
-```sql
-CREATE EXTENSION postgres_fdw;
-```
-
-## Unicorn Workers
-
-For most instances we recommend using: (CPU cores * 1.5) + 1 = Unicorn workers.
-For example a node with 4 cores would have 7 Unicorn workers.
-
-For all machines that have 2GB and up we recommend a minimum of three Unicorn workers.
-If you have a 1GB machine we recommend to configure only two Unicorn workers to prevent excessive
-swapping.
-
-As long as you have enough available CPU and memory capacity, it's okay to increase the number of
-Unicorn workers and this will usually help to reduce the response time of the applications and
-increase the ability to handle parallel requests.
-
-To change the Unicorn workers when you have the Omnibus package (which defaults to the
-recommendation above) please see [the Unicorn settings in the Omnibus GitLab documentation](https://docs.gitlab.com/omnibus/settings/unicorn.html).
+ by Omnibus) databases (for example, [AWS Relational Database Service (RDS)](https://aws.amazon.com/rds/)) but we don't guarantee compatibility.
+- You must also ensure the `postgres_fdw` extension is loaded into every
+ GitLab database. This extension
+ [can be enabled](https://www.postgresql.org/docs/11/sql-createextension.html)
+ using a PostgreSQL super user.
## Puma settings
@@ -204,7 +164,7 @@ Omnibus GitLab defaults to the recommended Puma settings. Regardless of installa
tune the Puma settings.
If you're using Omnibus GitLab, see [Puma settings](https://docs.gitlab.com/omnibus/settings/puma.html)
-for instructions on changing the Puma settings.
+for instructions on changing the Puma settings. If you're using the GitLab Helm chart, see the [Webservice chart](https://docs.gitlab.com/charts/charts/gitlab/webservice/index.html).
### Puma workers
@@ -228,10 +188,26 @@ of [legacy Rugged code](../development/gitaly.md#legacy-rugged-code).
- If the operating system has a maximum 2 GB of memory, the recommended number of threads is `1`.
A higher value will result in excess swapping, and decrease performance.
- If legacy Rugged code is in use, the recommended number of threads is `1`.
-- In all other cases, the recommended number of threads is `4`. We do not recommend setting this
+- In all other cases, the recommended number of threads is `4`. We don't recommend setting this
higher, due to how [Ruby MRI multi-threading](https://en.wikipedia.org/wiki/Global_interpreter_lock)
works.
+## Unicorn Workers
+
+For most instances we recommend using: (CPU cores * 1.5) + 1 = Unicorn workers.
+For example a node with 4 cores would have 7 Unicorn workers.
+
+For all machines that have 2GB and up we recommend a minimum of three Unicorn workers.
+If you have a 1GB machine we recommend to configure only two Unicorn workers to prevent excessive
+swapping.
+
+As long as you have enough available CPU and memory capacity, it's okay to increase the number of
+Unicorn workers and this will usually help to reduce the response time of the applications and
+increase the ability to handle parallel requests.
+
+To change the Unicorn workers when you have the Omnibus package (which defaults to the
+recommendation above) please see [the Unicorn settings in the Omnibus GitLab documentation](https://docs.gitlab.com/omnibus/settings/unicorn.html).
+
## Redis and Sidekiq
Redis stores all user sessions and the background task queue.
@@ -257,11 +233,11 @@ to install GitLab on. Depending on how you decide to configure GitLab Runner and
what tools you use to exercise your application in the CI environment, GitLab
Runner can consume significant amount of available memory.
-Memory consumption calculations, that are available above, will not be valid if
+Memory consumption calculations, that are available above, won't be valid if
you decide to run GitLab Runner and the GitLab Rails application on the same
machine.
-It is also not safe to install everything on a single machine, because of the
+It's also not safe to install everything on a single machine, because of the
[security reasons](https://docs.gitlab.com/runner/security/), especially when you plan to use shell executor with GitLab
Runner.
@@ -282,24 +258,24 @@ For reference, GitLab.com's [auto-scaling shared runner](../user/gitlab_com/inde
## Supported web browsers
-CAUTION: **Caution:** With GitLab 13.0 (May 2020) we are removing official support for Internet Explorer 11.
+CAUTION: **Caution:** With GitLab 13.0 (May 2020) we have removed official support for Internet Explorer 11.
With the release of GitLab 13.4 (September 2020) we will remove all code that supports Internet Explorer 11.
-You can provide feedback [on this issue](https://gitlab.com/gitlab-org/gitlab/issues/197987) or via your usual support channels.
+You can provide feedback [on this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/197987) or via your usual support channels.
GitLab supports the following web browsers:
-- Firefox
-- Chrome/Chromium
-- Safari
-- Microsoft Edge
-- Internet Explorer 11 (until May 2020)
+- [Mozilla Firefox](https://www.mozilla.org/en-US/firefox/new/)
+- [Google Chrome](https://www.google.com/chrome/)
+- [Chromium](https://www.chromium.org/getting-involved/dev-channel)
+- [Apple Safari](https://www.apple.com/safari/)
+- [Microsoft Edge](https://www.microsoft.com/en-us/edge)
For the listed web browsers, GitLab supports:
- The current and previous major versions of browsers except Internet Explorer.
- The current minor version of a supported major version.
-NOTE: **Note:** We do not support running GitLab with JavaScript disabled in the browser and have no plans of supporting that
+NOTE: **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.
<!-- ## Troubleshooting
diff --git a/doc/integration/akismet.md b/doc/integration/akismet.md
index 5b697d387e9..7cb8f8b70ce 100644
--- a/doc/integration/akismet.md
+++ b/doc/integration/akismet.md
@@ -1,42 +1,36 @@
# Akismet
-> *Note:* Before 8.11 only issues submitted via the API and for non-project
-members were submitted to Akismet.
-
GitLab leverages [Akismet](https://akismet.com/) to protect against spam. Currently
GitLab uses Akismet to prevent the creation of spam issues on public projects. Issues
-created via the WebUI or the API can be submitted to Akismet for review.
+created via the web UI or the API can be submitted to Akismet for review.
Detected spam will be rejected, and an entry in the "Spam Log" section in the
Admin page will be created.
-Privacy note: GitLab submits the user's IP and user agent to Akismet. Note that
-adding a user to a project will disable the Akismet check and prevent this
-from happening.
+Privacy note: GitLab submits the user's IP and user agent to Akismet.
+
+NOTE: **Note:**
+In GitLab 8.11 and later, all issues are submitted to Akismet.
+In earlier GitLab versions, this only applied to API and non-project members.
## Configuration
To use Akismet:
1. Go to the URL: <https://akismet.com/account/>
-
1. Sign-in or create a new account.
-
1. Click on **Show** to reveal the API key.
-
1. Go to **Admin Area > Settings > Reporting** (`/admin/application_settings/reporting`).
-
1. Check the **Enable Akismet** checkbox.
-
1. Fill in the API key from step 3.
-
1. Save the configuration.
![Screenshot of Akismet settings](img/akismet_settings.png)
## Training
-> *Note:* Training the Akismet filter is only available in 8.11 and above.
+NOTE: **Note:**
+Training the Akismet filter is only available in GitLab 8.11 and later.
As a way to better recognize between spam and ham, you can train the Akismet
filter whenever there is a false positive or false negative.
diff --git a/doc/integration/azure.md b/doc/integration/azure.md
index 809a3b703fc..2059707e38c 100644
--- a/doc/integration/azure.md
+++ b/doc/integration/azure.md
@@ -2,33 +2,18 @@
To enable the Microsoft Azure OAuth2 OmniAuth provider you must register your application with Azure. Azure will generate a client ID and secret key for you to use.
-1. Sign in to the [Azure Management Portal](https://portal.azure.com).
+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).
-1. Select "Active Directory" on the left and choose the directory you want to use to register GitLab.
+As you go through the Microsoft procedure, keep the following in mind:
-1. Select "Applications" at the top bar and click the "Add" button the bottom.
-
-1. Select "Add an application my organization is developing".
-
-1. Provide the project information and click the "Next" button.
- - Name: 'GitLab' works just fine here.
- - Type: 'WEB APPLICATION AND/OR WEB API'
-
-1. On the "App properties" page enter the needed URI's and click the "Complete" button.
- - SIGN-IN URL: Enter the URL of your GitLab installation (e.g `https://gitlab.mycompany.com/`)
- - APP ID URI: Enter the endpoint URL for Microsoft to use, just has to be unique (e.g `https://mycompany.onmicrosoft.com/gitlab`)
-
-1. Select "Configure" in the top menu.
-
-1. Add a "Reply URL" pointing to the Azure OAuth callback of your GitLab installation (e.g. `https://gitlab.mycompany.com/users/auth/azure_oauth2/callback`).
-
-1. Create a "Client secret" by selecting a duration, the secret will be generated as soon as you click the "Save" button in the bottom menu.
-
-1. Note the "CLIENT ID" and the "CLIENT SECRET".
-
-1. Select "View endpoints" from the bottom menu.
-
-1. You will see lots of endpoint URLs in the form `https://login.microsoftonline.com/TENANT ID/...`, note down the TENANT ID part of one of those endpoints.
+- If you have multiple instances of Azure Active Directory, you can switch to the desired tenant.
+- You're setting up a Web application.
+- For the redirect URI, you'll need 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 terms may be listed as `Application ID` and `Application Secret`.
+- If you need to generate a new client secret, follow the Microsoft documentation on how to [Create 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. Once you leave the Azure portal, you won't be able to find the client secret again.
1. On your GitLab server, open the configuration file.
@@ -84,4 +69,7 @@ To enable the Microsoft Azure OAuth2 OmniAuth provider you must register your ap
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 Microsoft icon below the regular sign in form. Click the icon to begin the authentication process. Microsoft will ask the user to sign in and authorize the GitLab application. If everything goes well the user will be returned to GitLab and will be 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 everything goes well, you are returned to GitLab and signed in.
+See [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.
diff --git a/doc/integration/elasticsearch.md b/doc/integration/elasticsearch.md
index ae9d5bd8f60..07ef5dbb99d 100644
--- a/doc/integration/elasticsearch.md
+++ b/doc/integration/elasticsearch.md
@@ -54,7 +54,7 @@ The way you install the Go indexer depends on your version of GitLab:
### Omnibus GitLab
Since GitLab 11.8 the Go indexer is included in Omnibus GitLab.
-The former Ruby-based indexer was removed in [GitLab 12.3](https://gitlab.com/gitlab-org/gitlab/issues/6481).
+The former Ruby-based indexer was removed in [GitLab 12.3](https://gitlab.com/gitlab-org/gitlab/-/issues/6481).
### From source
@@ -142,6 +142,7 @@ The following Elasticsearch settings are available:
| Parameter | Description |
| ----------------------------------------------------- | ----------- |
| `Elasticsearch indexing` | Enables/disables Elasticsearch indexing. You may want to enable indexing but disable search in order to give the index time to be fully completed, for example. Also, keep in mind that this option doesn't have any impact on existing data, this only enables/disables background indexer which tracks data changes. So by enabling this you will not get your existing data indexed, use special Rake task for that as explained in [Adding GitLab's data to the Elasticsearch index](#adding-gitlabs-data-to-the-elasticsearch-index). |
+| `Elasticsearch pause indexing` | Enables/disables temporary indexing pause. This is useful for cluster migration/reindexing. All changes are still tracked, but they are not committed to the Elasticsearch index until unpaused. |
| `Search with Elasticsearch enabled` | Enables/disables using Elasticsearch in search. |
| `URL` | The URL to use for connecting to Elasticsearch. Use a comma-separated list to support clustering (e.g., `http://host1, https://host2:9200`). If your Elasticsearch instance is password protected, pass the `username:password` in the URL (e.g., `http://<username>:<password>@<elastic_host>:9200/`). |
| `Number of Elasticsearch shards` | Elasticsearch indexes are split into multiple shards for performance reasons. In general, larger indexes need to have more shards. 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/indices-create-index.html#create-index-settings) |
@@ -418,14 +419,14 @@ The following are some available Rake tasks:
| [`sudo gitlab-rake gitlab:elastic:index_projects`](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/lib/tasks/gitlab/elastic.rake) | Iterates over all projects and queues Sidekiq jobs to index them in the background. |
| [`sudo gitlab-rake gitlab:elastic:index_projects_status`](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/lib/tasks/gitlab/elastic.rake) | Determines the overall status of the indexing. It is done by counting the total number of indexed projects, dividing by a count of the total number of projects, then multiplying by 100. |
| [`sudo gitlab-rake gitlab:elastic:clear_index_status`](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/lib/tasks/gitlab/elastic.rake) | Deletes all instances of IndexStatus for all projects. |
-| [`sudo gitlab-rake gitlab:elastic:create_empty_index[<INDEX_NAME>]`](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/lib/tasks/gitlab/elastic.rake) | Generates an empty index on the Elasticsearch side only if it doesn't already exist. |
-| [`sudo gitlab-rake gitlab:elastic:delete_index[<INDEX_NAME>]`](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/lib/tasks/gitlab/elastic.rake) | Removes the GitLab index on the Elasticsearch instance. |
-| [`sudo gitlab-rake gitlab:elastic:recreate_index[<INDEX_NAME>]`](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/lib/tasks/gitlab/elastic.rake) | Wrapper task for `gitlab:elastic:delete_index[<INDEX_NAME>]` and `gitlab:elastic:create_empty_index[<INDEX_NAME>]`. |
+| [`sudo gitlab-rake gitlab:elastic:create_empty_index[<TARGET_NAME>]`](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/lib/tasks/gitlab/elastic.rake) | Generates an empty index and assigns an alias for it on the Elasticsearch side only if it doesn't already exist. |
+| [`sudo gitlab-rake gitlab:elastic:delete_index[<TARGET_NAME>]`](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/lib/tasks/gitlab/elastic.rake) | Removes the GitLab index and alias (if exists) on the Elasticsearch instance. |
+| [`sudo gitlab-rake gitlab:elastic:recreate_index[<TARGET_NAME>]`](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/lib/tasks/gitlab/elastic.rake) | Wrapper task for `gitlab:elastic:delete_index[<TARGET_NAME>]` and `gitlab:elastic:create_empty_index[<TARGET_NAME>]`. |
| [`sudo gitlab-rake gitlab:elastic:index_snippets`](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/lib/tasks/gitlab/elastic.rake) | Performs an Elasticsearch import that indexes the snippets data. |
| [`sudo gitlab-rake gitlab:elastic:projects_not_indexed`](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/lib/tasks/gitlab/elastic.rake) | Displays which projects are not indexed. |
NOTE: **Note:**
-The `INDEX_NAME` parameter is optional and will use the default index name from the current `RAILS_ENV` if not set.
+The `TARGET_NAME` parameter is optional and will use the default index/alias name from the current `RAILS_ENV` if not set.
### Environment variables
@@ -511,7 +512,9 @@ Here are some common pitfalls and how to overcome them:
pp s.search_objects.class.name
```
- If you see `Elasticsearch::Model::Response::Records`, you are using Elasticsearch.
+ If you see `"ActiveRecord::Relation"`, you are **not** using Elasticsearch.
+
+ If you see `"Kaminari::PaginatableArray"` you are using Elasticsearch.
NOTE: **Note**:
The above instructions are used to verify that GitLab is using Elasticsearch only when indexing all namespaces. This is not to be used for scenarios that only index a [subset of namespaces](#limiting-namespaces-and-projects).
@@ -627,13 +630,13 @@ Here are some common pitfalls and how to overcome them:
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-elasticsearch-rake-tasks)) and [reindex the content of your instance](#adding-gitlabs-data-to-the-elasticsearch-index).
-### Low level troubleshooting
+### Low-level troubleshooting
-There is more [low level troubleshooting documentation](../administration/troubleshooting/elasticsearch.md) for when you experience other issues, including poor performance.
+There is a [more structured, lower-level troubleshooting document](../administration/troubleshooting/elasticsearch.md) for when you experience other issues, including poor performance.
### Known Issues
-- **[Elasticsearch `code_analyzer` doesn't account for all code cases](https://gitlab.com/gitlab-org/gitlab/issues/10693)**
+- **[Elasticsearch `code_analyzer` doesn't account for all code cases](https://gitlab.com/gitlab-org/gitlab/-/issues/10693)**
The `code_analyzer` pattern and filter configuration is being evaluated for improvement. We have noticed [several edge cases](https://gitlab.com/gitlab-org/gitlab/-/issues/10693#note_158382332) that are not returning expected search results due to our pattern and filter configuration.
diff --git a/doc/integration/gmail_action_buttons_for_gitlab.md b/doc/integration/gmail_action_buttons_for_gitlab.md
index 1ab01494edc..526db8a7338 100644
--- a/doc/integration/gmail_action_buttons_for_gitlab.md
+++ b/doc/integration/gmail_action_buttons_for_gitlab.md
@@ -21,4 +21,4 @@ In particular, note:
- Emails must be authenticated via DKIM or SPF.
- Before sending the final form ("Gmail Schema Whitelist Request"), you must send a real email from your production server. This means that you will have to find a way to send this email from the email address you are registering. You can do this by, for example, forwarding the real email from the email address you are registering or going into the rails console on the GitLab server and triggering the email sending from there.
-You can check how it looks going through all the steps laid out in the "Registering with Google" doc in [this GitLab.com issue](https://gitlab.com/gitlab-org/gitlab-foss/issues/1517).
+You can check how it looks going through all the steps laid out in the "Registering with Google" doc in [this GitLab.com issue](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/1517).
diff --git a/doc/integration/img/ultra_auth_credentials.png b/doc/integration/img/ultra_auth_credentials.png
deleted file mode 100644
index cff98a4b056..00000000000
--- a/doc/integration/img/ultra_auth_credentials.png
+++ /dev/null
Binary files differ
diff --git a/doc/integration/img/ultra_auth_edit_callback_url.png b/doc/integration/img/ultra_auth_edit_callback_url.png
deleted file mode 100644
index b7548122c5e..00000000000
--- a/doc/integration/img/ultra_auth_edit_callback_url.png
+++ /dev/null
Binary files differ
diff --git a/doc/integration/img/ultra_auth_edit_callback_url_highlighted.png b/doc/integration/img/ultra_auth_edit_callback_url_highlighted.png
deleted file mode 100644
index 4abf224756c..00000000000
--- a/doc/integration/img/ultra_auth_edit_callback_url_highlighted.png
+++ /dev/null
Binary files differ
diff --git a/doc/integration/jira_development_panel.md b/doc/integration/jira_development_panel.md
index e9b1c9676bd..f032345b9e0 100644
--- a/doc/integration/jira_development_panel.md
+++ b/doc/integration/jira_development_panel.md
@@ -1,6 +1,6 @@
# GitLab Jira development panel integration **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/2381) in [GitLab Premium](https://about.gitlab.com/pricing/) 10.0.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2381) in [GitLab Premium](https://about.gitlab.com/pricing/) 10.0.
Complementary to our [existing Jira](../user/project/integrations/jira.md) project integration, you're now able to integrate
GitLab projects with [Jira Development Panel](https://confluence.atlassian.com/adminjiraserver070/). Both can be used
@@ -173,8 +173,8 @@ Click the links to see your GitLab repository data.
### 11.10
-- [Instance admins can now setup integration for all namespaces](https://gitlab.com/gitlab-org/gitlab/issues/8902)
+- [Instance admins can now setup integration for all namespaces](https://gitlab.com/gitlab-org/gitlab/-/issues/8902)
### 11.1
-- [Support GitLab subgroups in Jira development panel](https://gitlab.com/gitlab-org/gitlab/issues/3561)
+- [Support GitLab subgroups in Jira development panel](https://gitlab.com/gitlab-org/gitlab/-/issues/3561)
diff --git a/doc/integration/kerberos.md b/doc/integration/kerberos.md
index 01bd2a8c0a0..56f7b50496c 100644
--- a/doc/integration/kerberos.md
+++ b/doc/integration/kerberos.md
@@ -98,12 +98,12 @@ successful.
## Linking Kerberos and LDAP accounts together
-If your users log in with Kerberos, but you also have [LDAP integration](../administration/auth/ldap.md)
+If your users log in with Kerberos, but you also have [LDAP integration](../administration/auth/ldap/index.md)
enabled, then your users will be automatically linked to their LDAP accounts on
first login. For this to work, some prerequisites must be met:
The Kerberos username must match the LDAP user's UID. You can choose which LDAP
-attribute is used as the UID in GitLab's [LDAP configuration](../administration/auth/ldap.md#configuration)
+attribute is used as the UID in GitLab's [LDAP configuration](../administration/auth/ldap/index.md#configuration-core-only)
but for Active Directory, this should be `sAMAccountName`.
The Kerberos realm must match the domain part of the LDAP user's Distinguished
diff --git a/doc/integration/ldap.md b/doc/integration/ldap.md
index 76c124d2ce9..25e4cc52375 100644
--- a/doc/integration/ldap.md
+++ b/doc/integration/ldap.md
@@ -1,5 +1,5 @@
---
-redirect_to: '../administration/auth/ldap.md'
+redirect_to: '../administration/auth/ldap/index.md'
---
-This document was moved to [`administration/auth/ldap`](../administration/auth/ldap.md).
+This document was moved to [`administration/auth/ldap`](../administration/auth/ldap/index.md).
diff --git a/doc/integration/omniauth.md b/doc/integration/omniauth.md
index 2afdeccb764..2ace05a8320 100644
--- a/doc/integration/omniauth.md
+++ b/doc/integration/omniauth.md
@@ -34,7 +34,6 @@ contains some settings that are common for all providers.
- [OAuth2Generic](oauth2_generic.md)
- [JWT](../administration/auth/jwt.md)
- [OpenID Connect](../administration/auth/oidc.md)
-- [UltraAuth](ultra_auth.md)
- [Salesforce](salesforce.md)
- [AWS Cognito](../administration/auth/cognito.md)
diff --git a/doc/integration/saml.md b/doc/integration/saml.md
index 5cb57baf353..97384d8f6cf 100644
--- a/doc/integration/saml.md
+++ b/doc/integration/saml.md
@@ -1,4 +1,4 @@
-# SAML OmniAuth Provider
+# SAML OmniAuth Provider **(CORE ONLY)**
Note that:
diff --git a/doc/integration/ultra_auth.md b/doc/integration/ultra_auth.md
deleted file mode 100644
index 95f2c0feb3b..00000000000
--- a/doc/integration/ultra_auth.md
+++ /dev/null
@@ -1,87 +0,0 @@
-# UltraAuth OmniAuth Provider
-
-You can integrate your GitLab instance with [UltraAuth](https://github.com/ultraauth) to enable users to perform secure biometric authentication to your GitLab instance with your UltraAuth account. Users have to perform the biometric authentication using their mobile device with fingerprint sensor.
-
-## Create UltraAuth Application
-
-To enable UltraAuth OmniAuth provider, you must use UltraAuth's credentials for your GitLab instance.
-To get the credentials (a pair of Client ID and Client Secret), you must register an application on UltraAuth.
-
-1. Sign in to [UltraAuth](https://app.ultraauth.com).
-1. Navigate to **Create an App** and click on **Ruby on Rails**.
-1. Scroll down the page that is displayed to locate the **Client ID** and **Client Secret**.
- Keep this page open as you continue configuration.
-
- ![UltraAuth Credentials: OPENID_CLIENT_ID and OPENID_CLIENT_SECRET](img/ultra_auth_credentials.png)
-
-1. Click on "Edit Callback URL" link.
-
- ![Edit UltraAuth Callback URL](img/ultra_auth_edit_callback_url_highlighted.png)
-
-1. The callback URL will be `http(s)://<your_domain>/users/auth/ultraauth/callback`
-
- ![UltraAuth Callback URL](img/ultra_auth_edit_callback_url.png)
-
-1. Select **Register application**.
-1. On your GitLab server, open the configuration file.
-
- For Omnibus package:
-
- ```shell
- sudo editor /etc/gitlab/gitlab.rb
- ```
-
- For installations from source:
-
- ```shell
- cd /home/git/gitlab
- sudo -u git -H editor config/gitlab.yml
- ```
-
-1. See [Initial OmniAuth Configuration](omniauth.md#initial-omniauth-configuration) for initial settings.
-1. Add the provider configuration:
-
- For Omnibus package:
-
- ```ruby
- gitlab_rails['omniauth_providers'] = [
- {
- "name" => "ultraauth",
- "app_id" => "OPENID_CLIENT_ID",
- "app_secret" => "OPENID_CLIENT_SECRET",
- "args" => {
- "client_options" => {
- "redirect_uri" => "https://example.com/users/auth/ultraauth/callback"
- }
- }
- }
- ]
- ```
-
- For installation from source:
-
- ```yaml
- - { name: 'ultraauth',
- app_id: 'OPENID_CLIENT_ID',
- app_secret: 'OPENID_CLIENT_SECRET',
- args: {
- client_options: {
- redirect_uri: 'https://example.com/users/auth/ultraauth/callback'
- }
- }
- }
- ```
-
- __Replace `https://example.com/users/auth/ultraauth/callback` with your application's Callback URL.__
-
-1. Change `OPENID_CLIENT_ID` to the Client ID from the UltraAuth application page.
-1. Change `OPENID_CLIENT_SECRET` to the Client Secret from the UltraAuth application page.
-1. Save the configuration file.
-1. [Reconfigure GitLab](../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 an UltraAuth icon below the regular sign in form.
-Click the icon to begin the authentication process. UltraAuth will ask the user to sign in and authorize the GitLab application.
-If everything goes well, the user will be returned to GitLab and will be signed in.
-
-GitLab requires the email address of each new user. Once the user is logged in using UltraAuth, GitLab will redirect the user to the profile page where they will have to provide the email and verify the email. Password authentication will be disabled for UltraAuth users and two-factor authentication (2FA) will be enforced.
diff --git a/doc/integration/vault.md b/doc/integration/vault.md
index 0a6ced42925..cead8f7592a 100644
--- a/doc/integration/vault.md
+++ b/doc/integration/vault.md
@@ -7,7 +7,7 @@ type: reference, howto
# Vault Authentication with GitLab OpenID Connect
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/22323) in GitLab 9.0
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/22323) in GitLab 9.0
[Vault](https://www.vaultproject.io/) is a secrets management application offered by HashiCorp.
It allows you to store and manage sensitive information such as secret environment variables, encryption keys, and authentication tokens.
@@ -21,7 +21,7 @@ The following assumes you already have Vault installed and running.
First you'll need to create a GitLab application to obtain an application ID and secret for authenticating into Vault. To do this, sign in to GitLab and follow these steps:
1. On GitLab, click your avatar on the top-right corner, and select your user **Settings > Applications**.
- 1. Fill out the application **Name** and [**Redirect URI**](https://www.vaultproject.io/docs/auth/jwt/#redirect-uris),
+ 1. Fill out the application **Name** and [**Redirect URI**](https://www.vaultproject.io/docs/auth/jwt#redirect-uris),
making sure to select the **OpenID** scope.
1. Save application.
1. Copy client ID and secret, or keep the page open for reference.
@@ -69,7 +69,7 @@ The following assumes you already have Vault installed and running.
1. **Write the OIDC Role Config:**
- Now that Vault has a GitLab application ID and secret, it needs to know the [**Redirect URIs**](https://www.vaultproject.io/docs/auth/jwt/#redirect-uris) and scopes given to GitLab during the application creation process. The redirect URIs need to match where your Vault instance is running. The `oidc_scopes` field needs to include the `openid`. Similarly to the previous step, replace `your_application_id` with the generated application ID from GitLab:
+ Now that Vault has a GitLab application ID and secret, it needs to know the [**Redirect URIs**](https://www.vaultproject.io/docs/auth/jwt#redirect-uris) and scopes given to GitLab during the application creation process. The redirect URIs need to match where your Vault instance is running. The `oidc_scopes` field needs to include the `openid`. Similarly to the previous step, replace `your_application_id` with the generated application ID from GitLab:
This configuration is saved under the name of the role you are creating. In this case, we are creating a `demo` role. Later, we'll show how you can access this role through the Vault CLI.
@@ -110,7 +110,7 @@ The following assumes you already have Vault installed and running.
1. In the **Write the OIDC Role Config** (step 4), we created a role called `demo`. We set `role=demo` so Vault knows which configuration we'd like to login in with.
1. To set Vault to use the `OIDC` sign-in method, we set `-method=oidc`.
- 1. To set the port that GitLab should redirect to, we set `port=8250` or another port number that matches the port given to GitLab when listing [Redirect URIs](https://www.vaultproject.io/docs/auth/jwt/#redirect-uris).
+ 1. To set the port that GitLab should redirect to, we set `port=8250` or another port number that matches the port given to GitLab when listing [Redirect URIs](https://www.vaultproject.io/docs/auth/jwt#redirect-uris).
Once you run the command above, it will present a link in the terminal.
Click the link in the terminal and a tab will open in the browser confirming you're signed into Vault via OIDC:
diff --git a/doc/policy/maintenance.md b/doc/policy/maintenance.md
index cf2a7a375cc..bba16e491d0 100644
--- a/doc/policy/maintenance.md
+++ b/doc/policy/maintenance.md
@@ -5,23 +5,23 @@ type: concepts
# GitLab Release and Maintenance Policy
GitLab has strict policies governing version naming, as well as release pace for major, minor,
-patch and security releases. New releases are usually announced on the [GitLab blog](https://about.gitlab.com/releases/categories/releases/).
+patch, and security releases. New releases are usually announced on the [GitLab blog](https://about.gitlab.com/releases/categories/releases/).
Our current policy is:
-- Backporting bug fixes for **only the current stable release** at any given time, see [patch releases](#patch-releases).
-- Backporting to **to the previous two monthly releases in addition to the current stable release**, see [security releases](#security-releases).
+- Backporting bug fixes for **only the current stable release** at any given time. (See [patch releases](#patch-releases).)
+- Backporting **to the previous two monthly releases in addition to the current stable release**. (See [security releases](#security-releases).)
## Versioning
GitLab uses [Semantic Versioning](https://semver.org/) for its releases:
`(Major).(Minor).(Patch)`.
-For example, for GitLab version 10.5.7:
+For example, for GitLab version 12.10.6:
-- `10` represents the major version. The major release was 10.0.0, but often referred to as 10.0.
-- `5` represents the minor version. The minor release was 10.5.0, but often referred to as 10.5.
-- `7` represents the patch number.
+- `12` represents the major version. The major release was 12.0.0, but often referred to as 12.0.
+- `10` represents the minor version. The minor release was 12.10.0, but often referred to as 12.10.
+- `6` represents the patch number.
Any part of the version number can increment into multiple digits, for example, 13.10.11.
@@ -29,10 +29,118 @@ The following table describes the version types and their release cadence:
| Version type | Description | Cadence |
|:-------------|:------------|:--------|
-| Major | For significant changes, or when any backward-incompatible changes are introduced to the public API. | Yearly. The next major release is GitLab 13.0 on May 22, 2020. Subsequent major releases will be scheduled for May 22 each year, by default. |
+| Major | For significant changes, or when any backward-incompatible changes are introduced to the public API. | Yearly. The next major release is GitLab 14.0 on May 22, 2021. Subsequent major releases will be scheduled for May 22 each year, by default. |
| Minor | For when new backward-compatible functionality is introduced to the public API, a minor feature is introduced, or when a set of smaller features is rolled out. | Monthly on the 22nd. |
| Patch | For backward-compatible bug fixes that fix incorrect behavior. See [Patch releases](#patch-releases). | As needed. |
+## Upgrade recommendations
+
+We encourage everyone to run the [latest stable release](https://about.gitlab.com/releases/categories/releases/)
+to ensure that you can easily upgrade to the most secure and feature-rich GitLab experience.
+In order to make sure you can easily run the most recent stable release, we are working
+hard to keep the update process simple and reliable.
+
+If you are unable to follow our monthly release cycle, there are a couple of
+cases you need to consider.
+
+It is considered safe to jump between patch versions and minor versions within
+one major version. For example, it is safe to:
+
+- Upgrade the *minor* version. For example:
+
+ - `12.7.5` -> `12.10.5`
+ - `11.3.4` -> `11.11.1`
+ - `10.6.6` -> `10.8.3`
+ - `11.3.4` -> `11.11.8`
+ - `10.6.6` -> `10.8.7`
+ - `9.2.3` -> `9.5.5`
+ - `8.9.4` -> `8.12.3`
+
+- Upgrade the *patch* version. For example:
+
+ - `12.0.4` -> `12.0.12`
+ - `11.11.1` -> `11.11.8`
+ - `10.6.3` -> `10.6.6`
+ - `11.11.1` -> `11.11.8`
+ - `10.6.3` -> `10.6.6`
+ - `9.5.5` -> `9.5.9`
+ - `8.9.2` -> `8.9.6`
+
+NOTE **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).
+
+NOTE: **Note:**
+Instructions are available for downloading an Omnibus GitLab Linux package locally and [manually installing](https://docs.gitlab.com/omnibus/manual_install.html) it.
+
+### Upgrading major versions
+
+Upgrading the *major* version requires more attention.
+Backward-incompatible changes and migrations are reserved for major versions.
+We cannot guarantee that upgrading between major versions will be seamless.
+We suggest upgrading to the latest available *minor* version within
+your major version before proceeding to the next major version.
+Doing this will address any backward-incompatible changes or deprecations
+to help ensure a successful upgrade to next major release.
+
+It's also important to ensure that any background migrations have been fully completed
+before upgrading to a new major version. To see the current size of the `background_migration` queue,
+[Check for background migrations before upgrading](../update/README.md#checking-for-background-migrations-before-upgrading).
+
+If your GitLab instance has any GitLab Runners associated with it, it is very
+important to upgrade the GitLab Runners to match the GitLab minor version that was
+upgraded to. This is to ensure [compatibility with GitLab versions](https://docs.gitlab.com/runner/#compatibility-with-gitlab-versions).
+
+### Version 12 onward: Extra step for major upgrades
+
+From version 12 onward, an additional step is required. More significant migrations
+may occur during major release upgrades.
+
+To ensure these are successful:
+
+1. Increment to the first minor version (`x.0.x`) during the major version jump.
+1. Proceed with upgrading to a newer release.
+
+**For example: `11.5.x` -> `11.11.x` -> `12.0.x` -> `12.10.x` -> `13.0.x`**
+
+### Example upgrade paths
+
+Please see the table below for some examples:
+
+| Target version | Your version | Recommended upgrade path | Note |
+| --------------------- | ------------ | ------------------------ | ---- |
+| `13.2.0` | `11.5.0` | `11.5.0` -> `11.11.8` -> `12.0.12` -> `12.10.6` -> `13.0.0` -> `13.2.0` | Four intermediate versions are required: the final 11.11, 12.0, and 12.10 releases, plus 13.0. |
+| `13.0.1` | `11.10.8` | `11.10.5` -> `11.11.8` -> `12.0.12` -> `12.10.6` -> `13.0.1` | Three intermediate versions are required: `11.11`, `12.0`, and `12.10`. |
+| `12.10.6` | `11.3.4` | `11.3.4` -> `11.11.8` -> `12.0.12` -> `12.10.6` | Two intermediate versions are required: `11.11` and `12.0` |
+| `12.9.5.` | `10.4.5` | `10.4.5` -> `10.8.7` -> `11.11.8` -> `12.0.12` -> `12.9.5` | Three intermediate versions are required: `10.8`, `11.11`, and `12.0`, then `12.9.5` |
+| `12.2.5` | `9.2.6` | `9.2.6` -> `9.5.10` -> `10.8.7` -> `11.11.8` -> `12.0.12` -> `12.2.5` | Four intermediate versions are required: `9.5`, `10.8`, `11.11`, `12.0`, then `12.2`. |
+| `11.3.4` | `8.13.4` | `8.13.4` -> `8.17.7` -> `9.5.10` -> `10.8.7` -> `11.3.4` | `8.17.7` is the last version in version 8, `9.5.10` is the last version in version 9, `10.8.7` is the last version in version 10. |
+
+### Upgrades from versions earlier than 8.12
+
+- `8.11.x` 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.
+
+### Multi-step upgrade paths with GitLab all-in-one Linux package repository
+
+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.
+
+When following an upgrade path spanning multiple versions, for each upgrade, specify the intended GitLab version number in your package manager's install or upgrade command.
+
+Examples:
+
+```shell
+# apt-get (Ubuntu/Debian)
+sudo apt-get upgrade gitlab-ee=12.0.12-ee.0
+# yum (RHEL/CentOS 6 and 7)
+yum install gitlab-ee-12.0.12-ee.0.el7
+# dnf (RHEL/CentOS 8)
+dnf install gitlab-ee-12.0.12-ee.0.el8
+# zypper (SUSE)
+zypper install gitlab-ee=12.0.12-ee.0
+```
+
## Patch releases
Patch releases **only include bug fixes** for the current stable released version of
@@ -62,7 +170,7 @@ have to adhere to various internal requirements (for example, org. compliance, v
In cases where a strategic user has a requirement to test a feature before it is
officially released, we can offer to create a Release Candidate (RC) version that will
include the specific feature. This should be needed only in extreme cases, and can be requested for
-consideration by raising an issue in the [release/tasks](https://gitlab.com/gitlab-org/release/tasks/issues/new?issuable_template=Backporting-request) issue tracker.
+consideration by raising an issue in the [release/tasks](https://gitlab.com/gitlab-org/release/tasks/-/issues/new?issuable_template=Backporting-request) issue tracker.
It is important to note that the Release Candidate will also contain other features and changes as
it is not possible to easily isolate a specific feature (similar reasons as noted above). The
Release Candidate will be no different than any code that is deployed to GitLab.com or is publicly
@@ -95,7 +203,7 @@ For instance, if we release `11.2.1` with a fix for a severe bug introduced in
`11.0.0`, we could backport the fix to a new `11.0.x`, and `11.1.x` patch release.
To request backporting to more than one stable release for consideration, raise an issue in the
-[release/tasks](https://gitlab.com/gitlab-org/release/tasks/issues/new?issuable_template=Backporting-request) issue tracker.
+[release/tasks](https://gitlab.com/gitlab-org/release/tasks/-/issues/new?issuable_template=Backporting-request) issue tracker.
### Security releases
@@ -107,86 +215,12 @@ For very serious security issues, there is
to backport security fixes to even more monthly releases of GitLab.
This decision is made on a case-by-case basis.
-## Upgrade recommendations
-
-We encourage everyone to run the [latest stable release](https://about.gitlab.com/releases/categories/releases/) to ensure that you can
-easily upgrade to the most secure and feature-rich GitLab experience. In order
-to make sure you can easily run the most recent stable release, we are working
-hard to keep the update process simple and reliable.
-
-If you are unable to follow our monthly release cycle, there are a couple of
-cases you need to consider.
-
-It is considered safe to jump between patch versions and minor versions within
-one major version. For example, it is safe to:
-
-- Upgrade the patch version:
- - `8.9.0` -> `8.9.7`
- - `8.9.0` -> `8.9.1`
- - `8.9.2` -> `8.9.6`
- - `9.5.5` -> `9.5.9`
- - `10.6.3` -> `10.6.6`
- - `11.11.1` -> `11.11.8`
- - `12.0.4` -> `12.0.12`
-- Upgrade the minor version:
- - `8.9.4` -> `8.12.3`
- - `9.2.3` -> `9.5.5`
- - `10.6.6` -> `10.8.7`
- - `11.3.4` -> `11.11.8`
-
-Upgrading the major version requires more attention.
-We cannot guarantee that upgrading between major versions will be seamless. As previously mentioned, major versions are reserved for backwards incompatible changes.
-We recommend that you first upgrade to the latest available minor version within
-your major version. By doing this, you can address any deprecation messages
-that could change behavior in the next major release.
-
-It's also important to ensure that any background migrations have been fully completed
-before upgrading to a new major version. To see the current size of the `background_migration` queue,
-[Check for background migrations before upgrading](../update/README.md#checking-for-background-migrations-before-upgrading).
-
-### Version 12 onwards: Extra step for major upgrades
-
-From version 12 onwards, an additional step is required. More significant migrations
-may occur during major release upgrades.
-
-To ensure these are successful:
-
-1. Increment to the first minor version (`x.0.x`) during the major version jump.
-1. Proceed with upgrading to a newer release.
-
-For example: `11.11.x` -> `12.0.x` -> `12.8.x`
-
-### Upgrades from old versions
-
-- `8.11.x` 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.
-- Version specific changes in
- [the Omnibus documentation](https://docs.gitlab.com/omnibus/update/README.html#version-specific-changes).
-
-### Example upgrade paths
-
-Please see the table below for some examples:
-
-| Latest stable version | Your version | Recommended upgrade path | Note |
-| --------------------- | ------------ | ------------------------ | ---- |
-| 9.4.5 | 8.13.4 | `8.13.4` -> `8.17.7` -> `9.4.5` | `8.17.7` is the last version in version `8` |
-| 10.1.4 | 8.13.4 | `8.13.4 -> 8.17.7 -> 9.5.10 -> 10.1.4` | `8.17.7` is the last version in version `8`, `9.5.10` is the last version in version `9` |
-| 11.3.4 | 8.13.4 | `8.13.4` -> `8.17.7` -> `9.5.10` -> `10.8.7` -> `11.3.4` | `8.17.7` is the last version in version `8`, `9.5.10` is the last version in version `9`, `10.8.7` is the last version in version `10` |
-| 12.5.10 | 11.3.4 | `11.3.4` -> `11.11.8` -> `12.0.12` -> `12.5.10` | `11.11.8` is the last version in version `11`. `12.0.x` [is a required step](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23211#note_272842444). |
-| 12.8.5 | 9.2.6 | `9.2.6` -> `9.5.10` -> `10.8.7` -> `11.11.8` -> `12.0.12` -> `12.8.5` | Four intermediate versions are required: the final 9.5, 10.8, 11.11 releases, plus 12.0. |
-
-NOTE: **Note:**
-Instructions for installing a specific version of GitLab or downloading the package locally for installation can be found at [GitLab Repositories](https://packages.gitlab.com/gitlab).
-
## More information
Check [our release posts](https://about.gitlab.com/releases/categories/releases/).
Each month, we publish either a major or minor release of GitLab. At the end
-of those release posts there are three sections to look for: deprecations, important notes,
-and upgrade barometer. These will draw your attention to:
+of those release posts there are three sections to look for: Deprecations, Removals, and Important notes on upgrading. These will include:
- Steps you need to perform as part of an upgrade.
For example [8.12](https://about.gitlab.com/releases/2016/09/22/gitlab-8-12-released/#upgrade-barometer)
diff --git a/doc/public_access/public_access.md b/doc/public_access/public_access.md
index 0ca2da1db63..3f93cd7f61f 100644
--- a/doc/public_access/public_access.md
+++ b/doc/public_access/public_access.md
@@ -33,7 +33,7 @@ NOTE: **Note:**
From July 2019, the `Internal` visibility setting is disabled for new projects, groups,
and snippets on GitLab.com. Existing projects, groups, and snippets using the `Internal`
visibility setting keep this setting. You can read more about the change in the
-[relevant issue](https://gitlab.com/gitlab-org/gitlab/issues/12388).
+[relevant issue](https://gitlab.com/gitlab-org/gitlab/-/issues/12388).
### Private projects
@@ -59,6 +59,8 @@ it. The restriction for visibility levels on the application setting level also
applies to groups, so if that's set to internal, the explore page will be empty
for anonymous users. The group page now has a visibility level icon.
+Admin users cannot create subgroups or projects with higher visibility level than that of the parent group.
+
## Visibility of users
The public page of a user, located at `/username`, is always visible whether
@@ -89,7 +91,7 @@ For details, see [Restricted visibility levels](../user/admin_area/settings/visi
## Reducing visibility
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/33358) in GitLab 12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/33358) in GitLab 12.6.
Reducing a project's visibility level will remove the fork relationship between the project and
any forked project. This is a potentially destructive action which requires confirmation before
diff --git a/doc/push_rules/push_rules.md b/doc/push_rules/push_rules.md
index 5685e848a33..e0ca914b67b 100644
--- a/doc/push_rules/push_rules.md
+++ b/doc/push_rules/push_rules.md
@@ -95,15 +95,15 @@ GitLab uses [RE2 syntax](https://github.com/google/re2/wiki/Syntax) for regular
## Prevent pushing secrets to the repository
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/385) in [GitLab Starter](https://about.gitlab.com/pricing/) 8.12.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/385) in [GitLab Starter](https://about.gitlab.com/pricing/) 8.12.
Secrets such as credential files, SSH private keys, and other files containing secrets should never be committed to source control.
-GitLab allows you to turn on a predefined blacklist of files which won't be allowed to be
+GitLab allows you to turn on a predefined denylist of files which won't be allowed to be
pushed to a repository, stopping those commits from reaching the remote repository.
By selecting the checkbox *Prevent committing secrets to Git*, GitLab prevents
pushes to the repository when a file matches a regular expression as read from
-[`files_blacklist.yml`](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/lib/gitlab/checks/files_blacklist.yml) (make sure you are at the right branch
+[`files_denylist.yml`](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/lib/gitlab/checks/files_denylist.yml) (make sure you are at the right branch
as your GitLab version when viewing this file).
NOTE: **Note:**
diff --git a/doc/raketasks/README.md b/doc/raketasks/README.md
index 4bba4f2bc5a..1d8aad25d57 100644
--- a/doc/raketasks/README.md
+++ b/doc/raketasks/README.md
@@ -28,8 +28,9 @@ The following are available Rake tasks:
| [Import repositories](import.md) | Import bare repositories into your GitLab instance. |
| [Import large project exports](../development/import_project.md#importing-via-a-rake-task) | Import large GitLab [project exports](../user/project/settings/import_export.md). |
| [Integrity checks](../administration/raketasks/check.md) | Check the integrity of repositories, files, and LDAP. |
-| [LDAP maintenance](../administration/raketasks/ldap.md) | [LDAP](../administration/auth/ldap.md)-related tasks. |
+| [LDAP maintenance](../administration/raketasks/ldap.md) | [LDAP](../administration/auth/ldap/index.md)-related tasks. |
| [List repositories](list_repos.md) | List of all GitLab-managed Git repositories on disk. |
+| [Migrate Snippets to Git](migrate_snippets.md) | Migrate GitLab Snippets to Git repositories and show migration status |
| [Project import/export](../administration/raketasks/project_import_export.md) | Prepare for [project exports and imports](../user/project/settings/import_export.md). |
| [Sample Prometheus data](generate_sample_prometheus_data.md) | Generate sample Prometheus data. |
| [Repository storage](../administration/raketasks/storage.md) | List and migrate existing projects and attachments from legacy storage to hashed storage. |
@@ -38,4 +39,3 @@ The following are available Rake tasks:
| [User management](user_management.md) | Perform user management tasks. |
| [Webhooks administration](web_hooks.md) | Maintain project Webhooks. |
| [X.509 signatures](x509_signatures.md) | Update X.509 commit signatures, useful if certificate store has changed. |
-| [Migrate Snippets to Git](migrate_snippets.md) | Migrate GitLab Snippets to Git repositories and show migration status |
diff --git a/doc/raketasks/backup_restore.md b/doc/raketasks/backup_restore.md
index 3c81bab644e..e83f51dc84e 100644
--- a/doc/raketasks/backup_restore.md
+++ b/doc/raketasks/backup_restore.md
@@ -641,7 +641,7 @@ recommended that you configure the appropriate retention policy for your object
storage (for example, [AWS S3](https://docs.aws.amazon.com/AmazonS3/latest/user-guide/create-lifecycle.html)).
You may want to set a limited lifetime for backups to prevent regular
-backups using all your disk space.
+backups using all your disk space. The next time the backup task is run, backups older than the `backup_keep_time` will be pruned.
For Omnibus GitLab packages:
@@ -803,7 +803,7 @@ restore:
```shell
# This command will overwrite the contents of your GitLab database!
-sudo gitlab-backup restore BACKUP=1493107454_2018_04_25_10.6.4-ce
+sudo gitlab-backup restore BACKUP=11493107454_2018_04_25_10.6.4-ce
```
NOTE: **Note**
@@ -811,7 +811,7 @@ For GitLab 12.1 and earlier, use `gitlab-rake gitlab:backup:restore`.
CAUTION: **Warning:**
`gitlab-rake gitlab:backup:restore` does not set the right file system permissions on your Registry directory.
-This is a [known issue](https://gitlab.com/gitlab-org/gitlab-foss/issues/62759). On GitLab 12.2 or newer, you can
+This is a [known issue](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/62759). On GitLab 12.2 or newer, you can
use `gitlab-backup restore` to avoid this issue.
Next, restore `/etc/gitlab/gitlab-secrets.json` if necessary as mentioned above.
@@ -832,7 +832,7 @@ version of GitLab, the restore command will abort with an error. Install the
For GitLab installations using the Docker image or the GitLab Helm chart on
a Kubernetes cluster, the restore task expects the restore directories to be empty.
-However, with docker and Kubernetes volume mounts, some system level directories
+However, with Docker and Kubernetes volume mounts, some system level directories
may be created at the volume roots, like `lost+found` directory found in Linux
operating systems. These directories are usually owned by `root`, which can
cause access permission errors since the restore Rake task runs as `git` user.
@@ -842,7 +842,7 @@ directories are empty.
For both these installation types, the backup tarball has to be available in the
backup location (default location is `/var/opt/gitlab/backups`).
-For docker installations, the restore task can be run from host:
+For Docker installations, the restore task can be run from host:
```shell
docker exec -it <name of container> gitlab-backup restore
@@ -853,7 +853,7 @@ For GitLab 12.1 and earlier, use `gitlab-rake gitlab:backup:restore`.
CAUTION: **Warning:**
`gitlab-rake gitlab:backup:restore` does not set the right file system permissions on your Registry directory.
-This is a [known issue](https://gitlab.com/gitlab-org/gitlab-foss/issues/62759). On GitLab 12.2 or newer, you can
+This is a [known issue](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/62759). On GitLab 12.2 or newer, you can
use `gitlab-backup restore` to avoid this issue.
The GitLab Helm chart uses a different process, documented in
@@ -1063,7 +1063,7 @@ err.message="unknown error"
This is caused by the restore being run as the unprivileged user `git` which was
unable to assign the correct ownership to the registry files during the restore
-([issue 62759](https://gitlab.com/gitlab-org/gitlab-foss/issues/62759 "Incorrect permissions on registry filesystem after restore")).
+([issue 62759](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/62759 "Incorrect permissions on registry filesystem after restore")).
To get your registry working again:
diff --git a/doc/raketasks/cleanup.md b/doc/raketasks/cleanup.md
index 7908af8da84..5bdae998ec9 100644
--- a/doc/raketasks/cleanup.md
+++ b/doc/raketasks/cleanup.md
@@ -4,7 +4,7 @@ GitLab provides Rake tasks for cleaning up GitLab instances.
## Remove unreferenced LFS files from filesystem
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/36628) in GitLab 12.10.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/36628) in GitLab 12.10.
DANGER: **Danger:**
Do not run this within 12 hours of a GitLab upgrade. This is to ensure that all background migrations
@@ -44,6 +44,8 @@ later (once a day). If you need to garbage collect them immediately, run
## Remove unreferenced LFS files
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/36628) in GitLab 12.10.
+
Unreferenced LFS files are removed on a daily basis but you can remove them immediately if
you need to. For example:
@@ -64,6 +66,8 @@ I, [2020-01-08T20:51:17.148765 #43765] INFO -- : Removed unreferenced LFS files
## Remove garbage from filesystem
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/20863) in GitLab 11.2.
+
Clean up local project upload files if they don't exist in GitLab database. The
task attempts to fix the file if it can find its project, otherwise it moves the
file to a lost and found directory.
@@ -96,6 +100,10 @@ I, [2018-07-27T12:08:33.755624 #89817] INFO -- : Did fix /opt/gitlab/embedded/s
I, [2018-07-27T12:08:33.760257 #89817] INFO -- : Did move to lost and found /opt/gitlab/embedded/service/gitlab-rails/public/uploads/foo/bar/1dd6f0f7eefd2acc4c2233f89a0f7b0b/image.png -> /opt/gitlab/embedded/service/gitlab-rails/public/uploads/-/project-lost-found/foo/bar/1dd6f0f7eefd2acc4c2233f89a0f7b0b/image.png
```
+## Remove garbage from object storage
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/20918) in GitLab 11.2.
+
Remove object store upload files if they don't exist in GitLab database.
```shell
@@ -127,6 +135,9 @@ I, [2018-08-02T10:26:47.764356 #45087] INFO -- : Moved to lost and found: @hash
## Remove orphan artifact files
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/29681) in GitLab 12.1.
+> - [`ionice` support fixed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28023) in GitLab 12.10.
+
When you notice there are more job artifacts files on disk than there
should be, you can run:
@@ -172,6 +183,8 @@ level with `NICENESS`. Below are the valid levels, but consult
## Remove expired ActiveSession lookup keys
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30668) in GitLab 12.2.
+
```shell
# omnibus-gitlab
sudo gitlab-rake gitlab:cleanup:sessions:active_sessions_lookup_keys
diff --git a/doc/raketasks/import.md b/doc/raketasks/import.md
index 5229ce2ab08..263f9e54a20 100644
--- a/doc/raketasks/import.md
+++ b/doc/raketasks/import.md
@@ -115,16 +115,16 @@ repository in GitLab 10.4 and later:
- Ancestor renamed
- Ancestor transferred to another namespace
-Bare repositories are **not** importable by GitLab 10.4 and later when all the following are true about the repository:
+Bare repositories are **not** importable by GitLab 10.4 to GitLab 11.6, if all the following are true about the repository:
- It was created in GitLab 10.3 or earlier.
-- It was not renamed, transferred, or migrated to hashed storage in GitLab 10.4 and later.
-- Its ancestor namespaces were not renamed or transferred in GitLab 10.4 and later.
+- It was not renamed, transferred, or migrated to [hashed storage](../administration/repository_storage_types.md#hashed-storage) in GitLab 10.4 to GitLab 11.6.
+- Its ancestor namespaces were not renamed or transferred in GitLab 10.4 to GitLab 11.6.
-There is an [open issue to add a migration to make all bare repositories
-importable](https://gitlab.com/gitlab-org/gitlab-foss/issues/41776).
+[Since GitLab 11.6](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41776), all
+bare repositories are importable.
-Until then, you may wish to manually migrate repositories yourself. You can use
+To manually migrate repositories yourself (for GitLab 10.4 to GitLab 11.6), you can use the
[Rails console](../administration/troubleshooting/debug.md#starting-a-rails-console-session)
to do so. In a Rails console session, run the following to migrate a project:
diff --git a/doc/raketasks/migrate_snippets.md b/doc/raketasks/migrate_snippets.md
index fce91ab703e..476615d3926 100644
--- a/doc/raketasks/migrate_snippets.md
+++ b/doc/raketasks/migrate_snippets.md
@@ -35,7 +35,7 @@ bundle exec rake gitlab:snippets:migrate SNIPPET_IDS=1,2,3,4
```
There is a default limit (100) to the number of ids supported in the migration
-process. You can modify this limit by using the env variable `LIMIT`.
+process. You can modify this limit by using the environment variable `LIMIT`.
```shell
sudo gitlab-rake gitlab:snippets:migrate SNIPPET_IDS=1,2,3,4 LIMIT=50
@@ -83,7 +83,7 @@ bundle exec rake gitlab:snippets:list_non_migrated RAILS_ENV=production
As the number of non-migrated snippets can be large, we limit
by default the size of the number of ids returned to 100. You can
-modify this limit by using the env variable `LIMIT`.
+modify this limit by using the environment variable `LIMIT`.
```shell
sudo gitlab-rake gitlab:snippets:list_non_migrated LIMIT=200
diff --git a/doc/security/img/allowlist_v13_0.png b/doc/security/img/allowlist_v13_0.png
new file mode 100644
index 00000000000..973b53a57a4
--- /dev/null
+++ b/doc/security/img/allowlist_v13_0.png
Binary files differ
diff --git a/doc/security/img/whitelist.png b/doc/security/img/whitelist.png
deleted file mode 100644
index 897000e804d..00000000000
--- a/doc/security/img/whitelist.png
+++ /dev/null
Binary files differ
diff --git a/doc/security/rack_attack.md b/doc/security/rack_attack.md
index 5d18746e4e0..605b669d498 100644
--- a/doc/security/rack_attack.md
+++ b/doc/security/rack_attack.md
@@ -121,9 +121,6 @@ The following settings can be configured:
**Installations from source**
-NOTE: **Note:** Rack Attack initializer was temporarily renamed to `rack_attack_new`, to
-support backwards compatibility with the one [Omnibus initializer](https://docs.gitlab.com/omnibus/settings/configuration.html#setting-up-paths-to-be-protected-by-rack-attack). It'll be renamed back to `rack_attack.rb` once Omnibus throttle is removed. Please see the [GitLab issue](https://gitlab.com/gitlab-org/gitlab/issues/29952) for more information.
-
These settings can be found in `config/initializers/rack_attack.rb`. If you are
missing `config/initializers/rack_attack.rb`, the following steps need to be
taken in order to enable protection for your GitLab instance:
diff --git a/doc/security/webhooks.md b/doc/security/webhooks.md
index 27f79dbdf66..af9be499e80 100644
--- a/doc/security/webhooks.md
+++ b/doc/security/webhooks.md
@@ -52,29 +52,29 @@ NOTE: **Note:**
set up by administrators. However, you can turn this off by disabling the
**Allow requests to the local network from system hooks** option.
-## Whitelist for local requests
+## Allowlist for local requests
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/44496) in GitLab 12.2
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/44496) in GitLab 12.2
You can allow certain domains and IP addresses to be accessible to both *system hooks*
and *webhooks* even when local requests are not allowed by adding them to the
-whitelist. Navigate to **Admin Area > Settings > Network** (`/admin/application_settings/network`)
+allowlist. Navigate to **Admin Area > Settings > Network** (`/admin/application_settings/network`)
and expand **Outbound requests**:
-![Outbound local requests whitelist](img/whitelist.png)
+![Outbound local requests allowlist](img/allowlist_v13_0.png)
-The whitelist entries can be separated by semicolons, commas or whitespaces
+The allowed entries can be separated by semicolons, commas or whitespaces
(including newlines) and be in different formats like hostnames, IP addresses and/or
-IP ranges. IPv6 is supported. Hostnames that contain unicode characters should
+IP ranges. IPv6 is supported. Hostnames that contain Unicode characters should
use IDNA encoding.
-The whitelist can hold a maximum of 1000 entries. Each entry can be a maximum of
+The allowlist can hold a maximum of 1000 entries. Each entry can be a maximum of
255 characters.
-You can whitelist a particular port by specifying it in the whitelist entry.
+You can allow a particular port by specifying it in the allowlist entry.
For example `127.0.0.1:8080` will only allow connections to port 8080 on `127.0.0.1`.
-If no port is mentioned, all ports on that IP/domain are whitelisted. An IP range
-will whitelist all ports on all IPs in that range.
+If no port is mentioned, all ports on that IP/domain are allowed. An IP range
+will allow all ports on all IPs in that range.
Example:
diff --git a/doc/ssh/README.md b/doc/ssh/README.md
index 06db8e59850..5db1bde6413 100644
--- a/doc/ssh/README.md
+++ b/doc/ssh/README.md
@@ -119,7 +119,7 @@ Enter file in which to save the key (/home/user/.ssh/id_rsa):
For guidance, proceed to the [common steps](#common-steps-for-generating-an-ssh-key-pair).
NOTE: **Note:**
-If your have OpenSSH version 7.8 or below, consider the problems associated
+If you have OpenSSH version 7.8 or below, consider the problems associated
with [encoding](#rsa-keys-and-openssh-from-versions-65-to-78).
### Common steps for generating an SSH key pair
@@ -141,7 +141,7 @@ You can assign the directory and file name of your choice.
You can also dedicate that SSH key pair to a [specific host](#working-with-non-default-ssh-key-pair-paths).
After assigning a file to save your SSH key, you'll get a chance to set up
-a [passphrase](https://www.ssh.com/ssh/passphrase) for your SSH key:
+a [passphrase](https://www.ssh.com/ssh/passphrase/) for your SSH key:
```plaintext
Enter passphrase (empty for no passphrase):
@@ -344,7 +344,7 @@ NOTE: **Note:**
The example `Host` aliases are defined as `user_1.gitlab.com` and
`user_2.gitlab.com` for efficiency and transparency. Advanced configurations
are more difficult to maintain; using this type of alias makes it easier to
-understand when using other tools such as `git remote` subcommands. SSH
+understand when using other tools such as `git remote` sub-commands. SSH
would understand any string as a `Host` alias thus `Tanuki1` and `Tanuki2`,
despite giving very little context as to where they point, would also work.
@@ -370,80 +370,7 @@ git remote set-url origin git@<user_1.gitlab.com>:gitlab-org/gitlab.git
## Deploy keys
-Deploy keys allow read-only or read-write (if enabled) access to one or
-multiple repositories with a single SSH key pair.
-
-This is useful for cloning repositories to your Continuous
-Integration (CI) server. By using deploy keys, you don't have to set up a
-dummy user account.
-
-If you don't have a key pair, you might want to use a
-[deploy token](../user/project/deploy_tokens/index.md#deploy-tokens) instead.
-
-### Per-repository deploy keys
-
-Project maintainers and owners can add a deploy key for a repository.
-
-1. Navigate to the project's **Settings > Repository** page.
-1. Expand the **Deploy Keys** section.
-1. Specify a title for the new deploy key and paste a public SSH key.
-
-After this, the machine that uses the corresponding private SSH key has read-only or
-read-write (if enabled) access to the project.
-
-You can't add the same deploy key twice using the form.
-If you want to add the same key to another project, please enable it in the
-list that says **Deploy keys from projects available to you**. All the deploy
-keys of all the projects you have access to are available. This project
-access can happen through being a direct member of the project, or through
-a group.
-
-Deploy keys can be shared between projects, you just need to add them to each
-project.
-
-### Global shared deploy keys
-
-Global Shared Deploy keys allow read-only or read-write access to
-any repository in the entire GitLab installation.
-
-This is useful for integrating repositories to secured, shared Continuous
-Integration (CI) services or other shared services.
-GitLab administrators can set up the Global Shared Deploy key in GitLab and
-add the private key to any shared systems. Individual repositories opt into
-exposing their repository using these keys when a project maintainers (or higher)
-authorizes a Global Shared Deploy key to be used with their project.
-
-Global Shared Keys can provide greater security compared to Per-Project Deploy
-Keys since an administrator of the target integrated system is the only one
-who needs to know and configure the private key.
-
-GitLab administrators set up Global Deploy keys in the Admin Area under the
-section **Deploy Keys**. Ensure keys have a meaningful title as that will be
-the primary way for project maintainers and owners to identify the correct Global
-Deploy key to add. For instance, if the key gives access to a SaaS CI instance,
-use the name of that service in the key name if that is all it is used for.
-When creating Global Shared Deploy keys, give some thought to the granularity
-of keys - they could be of very narrow usage such as just a specific service or
-of broader usage for something like "Anywhere you need to give read access to
-your repository".
-
-Once a GitLab administrator adds the Global Deployment key, project maintainers
-and owners can add it by:
-
-1. Navigate to the project's **Settings > Repository** page.
-1. Expanding the **Deploy Keys** section.
-1. Clicking **Enable** next to the appropriate key listed under
- **Public deploy keys available to any project**.
-
-NOTE: **Note:**
-The heading **Public deploy keys available to any project** only appears
-if there is at least one Global Deploy Key configured.
-
-CAUTION: **Warning:**
-Defining Global Deploy Keys does not expose any given repository via
-the key until that repository adds the Global Deploy Key to their project.
-In this way the Global Deploy Keys enable access by other systems, but do
-not implicitly give any access just by setting them up.
+Read the [documentation on Deploy Keys](../user/project/deploy_keys/index.md).
## Applications
@@ -458,7 +385,7 @@ GitLab integrates with the system-installed SSH daemon, designating a user
connecting to the GitLab server over SSH are identified by their SSH key instead
of their username.
-SSH *client* operations performed on the GitLab server wil be executed as this
+SSH *client* operations performed on the GitLab server will be executed as this
user. Although it is possible to modify the SSH configuration for this user to,
e.g., provide a private SSH key to authenticate these requests by, this practice
is **not supported** and is strongly discouraged as it presents significant
@@ -485,7 +412,7 @@ are *explicitly not supported* and may stop working at any time.
### Options for Microsoft Windows
-If you're running Windows 10, the [Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/install-win10), and its latest [WSL 2](https://docs.microsoft.com/en-us/windows/wsl/wsl2-install) version,
+If you're running Windows 10, the [Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/install-win10), and its latest [WSL 2](https://docs.microsoft.com/en-us/install-win10) version,
support the installation of different Linux distributions, which include the Git and SSH clients.
For current versions of Windows, you can also install the Git and SSH clients with
diff --git a/doc/subscriptions/index.md b/doc/subscriptions/index.md
index 3978506cbf9..0425fe98d27 100644
--- a/doc/subscriptions/index.md
+++ b/doc/subscriptions/index.md
@@ -33,6 +33,9 @@ There are some differences in how a subscription applies, depending if you use G
On a self-managed instance, a GitLab subscription provides the same set of features for all users. On GitLab.com you can apply a subscription to either a group or a personal namespace.
+NOTE: **Note:**
+Subscriptions cannot be transferred between GitLab.com and GitLab self-managed. A new subscription must be purchased and applied as needed.
+
### Choosing a GitLab.com group or personal subscription
On GitLab.com you can apply a subscription to either a group or a personal namespace.
@@ -397,6 +400,15 @@ We recommend following these steps during renewal:
TIP: **Tip:**
You can find the _users over license_ in your instance's **Admin** dashboard by clicking on **{admin}** (**Admin Area**) in the top bar, or going to `/admin`.
+ The following table describes details of your admin dashboard and renewal terms:
+
+ | Field | Description |
+ |:------|:------------|
+ | Users in License | The number of users you've paid for in the current license loaded on the system. This does not include the amount you've paid for `Users over license` during renewal. |
+ | Active users | The number of current active users on your system. |
+ | Maximum users | The highest number of active users on your system during the term of the loaded license. If this number exceeds your users in license count at any point, you incur users over license. |
+ | Users over license | The number of users that exceed the `Users in License` for the current license term. Charges for this number of users will be incurred at the next renewal. |
+
1. Review your renewal details and complete the payment process.
1. A license for the renewal term will be available on the [Manage Purchases](https://customers.gitlab.com/subscriptions) page beneath your new subscription details.
1. [Upload](../user/admin_area/license.md) your new license to your instance.
@@ -440,7 +452,7 @@ The new subscription tier is active when the license file is uploaded.
## Subscription expiry
-When your subscription or trial expires, GitLab does not delete your data, but it may become inaccessible, depending on the tier at expiry. Some features may not behave as expected if you're not prepared for the expiry. For example, [environment specific variables not being passed](https://gitlab.com/gitlab-org/gitlab/issues/24759).
+When your subscription or trial expires, GitLab does not delete your data, but it may become inaccessible, depending on the tier at expiry. Some features may not behave as expected if you're not prepared for the expiry. For example, [environment specific variables not being passed](https://gitlab.com/gitlab-org/gitlab/-/issues/24759).
If you renew or upgrade, your data will again be accessible.
@@ -508,7 +520,7 @@ Be aware that:
## Contact Support
We also encourage all users to search our project trackers for known issues and
-existing feature requests in the [GitLab](https://gitlab.com/gitlab-org/gitlab/issues/) project.
+existing feature requests in the [GitLab](https://gitlab.com/gitlab-org/gitlab/-/issues/) project.
These issues are the best avenue for getting updates on specific product plans
and for communicating directly with the relevant GitLab team members.
diff --git a/doc/system_hooks/system_hooks.md b/doc/system_hooks/system_hooks.md
index 5ca8c0687f4..4ece58f533d 100644
--- a/doc/system_hooks/system_hooks.md
+++ b/doc/system_hooks/system_hooks.md
@@ -27,7 +27,7 @@ Your GitLab instance can perform HTTP POST requests on the following events:
- `user_remove_from_group`
- `user_update_for_group`
-The triggers for most of these are self-explanatory, but `project_update` and `project_rename` deserve some clarification: `project_update` is fired any time an attribute of a project is changed (name, description, tags, etc.) *unless* the `path` attribute is also changed. In that case, a `project_rename` is triggered instead (so that, for instance, if all you care about is the repo URL, you can just listen for `project_rename`).
+The triggers for most of these are self-explanatory, but `project_update` and `project_rename` deserve some clarification: `project_update` is fired any time an attribute of a project is changed (name, description, tags, etc.) *unless* the `path` attribute is also changed. In that case, a `project_rename` is triggered instead (so that, for instance, if all you care about is the repository URL, you can just listen for `project_rename`).
`user_failed_login` is sent whenever a **blocked** user attempts to login and denied access.
@@ -296,7 +296,7 @@ If the user is blocked via LDAP, `state` will be `ldap_blocked`.
}
```
-`owner_name` and `owner_email` are always `null`. Please see <https://gitlab.com/gitlab-org/gitlab/issues/20011>.
+`owner_name` and `owner_email` are always `null`. Please see <https://gitlab.com/gitlab-org/gitlab/-/issues/20011>.
**Group removed:**
@@ -313,7 +313,7 @@ If the user is blocked via LDAP, `state` will be `ldap_blocked`.
}
```
-`owner_name` and `owner_email` are always `null`. Please see <https://gitlab.com/gitlab-org/gitlab/issues/20011>.
+`owner_name` and `owner_email` are always `null`. Please see [issue #20011](https://gitlab.com/gitlab-org/gitlab/-/issues/20011).
**Group renamed:**
@@ -333,7 +333,7 @@ If the user is blocked via LDAP, `state` will be `ldap_blocked`.
}
```
-`owner_name` and `owner_email` are always `null`. Please see <https://gitlab.com/gitlab-org/gitlab/issues/20011>.
+`owner_name` and `owner_email` are always `null`. Please see <https://gitlab.com/gitlab-org/gitlab/-/issues/20011>.
**New Group Member:**
diff --git a/doc/topics/airgap/index.md b/doc/topics/airgap/index.md
index 854e0103a69..3866ec50253 100644
--- a/doc/topics/airgap/index.md
+++ b/doc/topics/airgap/index.md
@@ -1,139 +1,3 @@
-# Offline GitLab
-
-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.
-
-## Quick start
-
-If you plan to deploy a GitLab instance on a physically-isolated and offline network, see the
-[quick start guide](quick_start_guide.md) for configuration steps.
-
-## Features
-
-Follow these best practices to use GitLab's features in an offline environment:
-
-- [Operating the GitLab Secure scanners in an offline environment](../../user/application_security/offline_deployments/index.md).
-
-## Loading Docker images onto your offline host
-
-To use many GitLab features, including
-[security scans](../../user/application_security/index.md#working-in-an-offline-environment)
-and [Auto DevOps](../autodevops/), the GitLab Runner must be able to fetch the
-relevant Docker images.
-
-The process for making these images available without direct access to the public internet
-involves downloading the images then packaging and transferring them to the offline host. Here's an
-example of such a transfer:
-
-1. Download Docker images from public internet.
-1. Package Docker images as tar archives.
-1. Transfer images to offline environment.
-1. Load transferred images into offline Docker registry.
-
-### Using the official GitLab template
-
-GitLab provides a [vendored template](../../ci/yaml/README.md#includetemplate)
-to ease this process.
-
-This template should be used in a new, empty project, with a `gitlab-ci.yml` file containing:
-
-```yaml
-include:
- - template: Secure-Binaries.gitlab-ci.yml
-```
-
-The pipeline downloads the Docker images needed for the Security Scanners and saves them as
-[job artifacts](../../ci/pipelines/job_artifacts.md) or pushes them to the [Container Registry](../../user/packages/container_registry/index.md)
-of the project where the pipeline is executed. These archives can be transferred to another location
-and [loaded](https://docs.docker.com/engine/reference/commandline/load/) in a Docker daemon.
-This method requires a GitLab Runner with access to both `gitlab.com` (including
-`registry.gitlab.com`) and the local offline instance. This runner must run in
-[privileged mode](https://docs.gitlab.com/runner/executors/docker.html#use-docker-in-docker-with-privileged-mode)
-to be able to use the `docker` command inside the jobs. This runner can be installed in a DMZ or on
-a bastion, and used only for this specific project.
-
-#### Scheduling the updates
-
-By default, this project's pipeline will run only once, when the `.gitlab-ci.yml` is added to the
-repo. To update the GitLab security scanners and signatures, it's necessary to run this pipeline
-regularly. GitLab provides a way to [schedule pipelines](../../ci/pipelines/schedules.md). For
-example, you can set this up to download and store the Docker images every week.
-
-Some images can be updated more frequently than others. For example, the [vulnerability database](https://hub.docker.com/r/arminc/clair-db/tags)
-for Container Scanning is updated daily. To update this single image, create a new Scheduled
-Pipeline that runs daily and set `SECURE_BINARIES_ANALYZERS` to `clair-vulnerabilities-db`. Only
-this job will be triggered, and the image will be updated daily and made available in the project
-registry.
-
-#### Using the secure bundle created
-
-The project using the `Secure-Binaries.gitlab-ci.yml` template should now host all the required
-images and resources needed to run GitLab Security features.
-
-The next step is to tell the offline instance to use these resources instead of the default ones on
-`gitlab.com`. This can be done by setting the right environment variables:
-`SAST_ANALYZER_IMAGE_PREFIX` for SAST analyzers, `DS_ANALYZER_IMAGE_PREFIX` for Dependency Scanning,
-and so on.
-
-You can set these variables in the project's `.gitlab-ci.yml` files by using the bundle directly, or
-in the GitLab UI at the project or group level. See the [GitLab CI/CD environment variables page](../../ci/variables/README.md#custom-environment-variables)
-for more information.
-
-#### Variables
-
-The following table shows which variables you can use with the `Secure-Binaries.gitlab-ci.yml`
-template:
-
-| VARIABLE | Description | Default value |
-|-------------------------------------------|-----------------------------------------------|-----------------------------------|
-| `SECURE_BINARIES_ANALYZERS` | Comma-separated list of analyzers to download | `"bandit, brakeman, gosec, and so on..."` |
-| `SECURE_BINARIES_DOWNLOAD_IMAGES` | Used to disable jobs | `"true"` |
-| `SECURE_BINARIES_PUSH_IMAGES` | Push files to the project registry | `"true"` |
-| `SECURE_BINARIES_SAVE_ARTIFACTS` | Also save image archives as artifacts | `"false"` |
-| `SECURE_BINARIES_ANALYZER_VERSION` | Default analyzer version (docker tag) | `"2"` |
-
-### Alternate way without the official template
-
-If it's not possible to follow the above method, the images can be transferred manually instead:
-
-#### Example image packager script
-
-```shell
-#!/bin/bash
-set -ux
-
-# Specify needed analyzer images
-analyzers=${SAST_ANALYZERS:-"bandit eslint gosec"}
-gitlab=registry.gitlab.com/gitlab-org/security-products/analyzers/
-
-for i in "${analyzers[@]}"
-do
- tarname="${i}_2.tar"
- docker pull $gitlab$i:2
- docker save $gitlab$i:2 -o ./analyzers/${tarname}
- chmod +r ./analyzers/${tarname}
-done
-```
-
-#### Example image loader script
-
-This example loads the images from a bastion host to an offline host. In certain configurations,
-physical media may be needed for such a transfer:
-
-```shell
-#!/bin/bash
-set -ux
-
-# Specify needed analyzer images
-analyzers=${SAST_ANALYZERS:-"bandit eslint gosec"}
-registry=$GITLAB_HOST:4567
-
-for i in "${analyzers[@]}"
-do
- tarname="${i}_2.tar"
- scp ./analyzers/${tarname} ${GITLAB_HOST}:~/${tarname}
- ssh $GITLAB_HOST "sudo docker load -i ${tarname}"
- ssh $GITLAB_HOST "sudo docker tag $(sudo docker images | grep $i | awk '{print $3}') ${registry}/analyzers/${i}:2"
- ssh $GITLAB_HOST "sudo docker push ${registry}/analyzers/${i}:2"
-done
-```
+---
+redirect_to: '../offline/index.md'
+---
diff --git a/doc/topics/airgap/quick_start_guide.md b/doc/topics/airgap/quick_start_guide.md
deleted file mode 100644
index 8d0ff3558ce..00000000000
--- a/doc/topics/airgap/quick_start_guide.md
+++ /dev/null
@@ -1,157 +0,0 @@
-# Getting started with an offline GitLab Installation
-
-This is a step-by-step guide that helps you install, configure, and use a self-managed GitLab
-instance entirely offline.
-
-## Installation
-
-NOTE: **Note:**
-This guide assumes the server is Ubuntu 18.04. Instructions for other servers may vary.
-
-NOTE: **Note:**
-This guide assumes the server host resolves as `my-host`, which you should replace with your
-server's name.
-
-Follow the installation instructions [as outlined in the omnibus install
-guide](https://about.gitlab.com/install/#ubuntu), but make sure to specify an `http`
-URL for the `EXTERNAL_URL` installation step. Once installed, we will manually
-configure the SSL ourselves.
-
-It is strongly recommended to setup a domain for IP resolution rather than bind
-to the server's IP address. This better ensures a stable target for our certs' CN
-and will make long-term resolution simpler.
-
-```shell
-sudo EXTERNAL_URL="http://my-host.internal" install gitlab-ee
-```
-
-## Enabling SSL
-
-Follow these steps to enable SSL for your fresh instance. Note that these steps reflect those for
-[manually configuring SSL in Omnibus's NGINX configuration](https://docs.gitlab.com/omnibus/settings/nginx.html#manually-configuring-https):
-
-1. Make the following changes to `/etc/gitlab/gitlab.rb`:
-
- ```ruby
- # Update external_url from "http" to "https"
- external_url "https://example.gitlab.com"
-
- # Set Let's Encrypt to false
- letsencrypt['enable'] = false
- ```
-
-1. Create the following directories with the appropriate permissions for generating self-signed
- certificates:
-
- ```shell
- sudo mkdir -p /etc/gitlab/ssl
- sudo chmod 755 /etc/gitlab/ssl
- sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/gitlab/ssl/my-host.internal.key -out /etc/gitlab/ssl/my-host.internal.crt
- ```
-
-1. Reconfigure your instance to apply the changes:
-
- ```shell
- sudo gitlab-ctl reconfigure
- ```
-
-## Enabling the GitLab Container Registry
-
-Follow these steps to enable the container registry. Note that these steps reflect those for
-[configuring the container registry under an existing domain](../../administration/packages/container_registry.md#configure-container-registry-under-an-existing-gitlab-domain):
-
-1. Make the following changes to `/etc/gitlab/gitlab.rb`:
-
- ```ruby
- # Change external_registry_url to match external_url, but append the port 4567
- external_url "https://example.gitlab.com"
- registry_external_url "https://example.gitlab.com:4567"
- ```
-
-1. Reconfigure your instance to apply the changes:
-
- ```shell
- sudo gitlab-ctl reconfigure
- ```
-
-## Allow the docker daemon to trust the registry and GitLab Runner
-
-Provide your Docker daemon with your certs by
-[following the steps for using trusted certificates with your registry](../../administration/packages/container_registry.md#using-self-signed-certificates-with-container-registry):
-
-```shell
-sudo mkdir -p /etc/docker/certs.d/my-host.internal:5000
-
-sudo cp /etc/gitlab/ssl/my-host.internal.crt /etc/docker/certs.d/my-host.internal:5000/ca.crt
-```
-
-Provide your GitLab Runner (to be installed next) with your certs by
-[following the steps for using trusted certificates with your Runner](https://docs.gitlab.com/runner/install/docker.html#installing-trusted-ssl-server-certificates):
-
-```shell
-sudo mkdir -p /etc/gitlab-runner/certs
-
-sudo cp /etc/gitlab/ssl/my-host.internal.crt /etc/gitlab-runner/certs/ca.crt
-```
-
-## Enabling GitLab Runner
-
-[Following a similar process to the steps for installing our GitLab Runner as a
-Docker service](https://docs.gitlab.com/runner/install/docker.html#docker-image-installation), we must first register our Runner:
-
-```shell
-$ sudo docker run --rm -it -v /etc/gitlab-runner:/etc/gitlab-runner gitlab/gitlab-runner register
-Updating CA certificates...
-Runtime platform arch=amd64 os=linux pid=7 revision=1b659122 version=12.8.0
-Running in system-mode.
-
-Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
-https://my-host.internal
-Please enter the gitlab-ci token for this runner:
-XXXXXXXXXXX
-Please enter the gitlab-ci description for this runner:
-[eb18856e13c0]:
-Please enter the gitlab-ci tags for this runner (comma separated):
-
-Registering runner... succeeded runner=FSMwkvLZ
-Please enter the executor: custom, docker, virtualbox, kubernetes, docker+machine, docker-ssh+machine, docker-ssh, parallels, shell, ssh:
-docker
-Please enter the default Docker image (e.g. ruby:2.6):
-ruby:2.6
-Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
-```
-
-Now we must add some additional configuration to our runner:
-
-Make the following changes to `/etc/gitlab-runner/config.toml`:
-
-- Add docker socket to volumes `volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]`
-- Add `pull_policy = "if-not-present"` to the executor configuration
-
-Now we can start our Runner:
-
-```shell
-sudo docker run -d --restart always --name gitlab-runner -v /etc/gitlab-runner:/etc/gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock gitlab/gitlab-runner:latest
-90646b6587127906a4ee3f2e51454c6e1f10f26fc7a0b03d9928d8d0d5897b64
-```
-
-### Authenticating the registry against the host OS
-
-As noted in [Docker's registry authentication documentation](https://docs.docker.com/registry/insecure/#docker-still-complains-about-the-certificate-when-using-authentication),
-certain versions of Docker require trusting the certificate chain at the OS level.
-
-In the case of Ubuntu, this involves using `update-ca-certificates`:
-
-```shell
-sudo cp /etc/docker/certs.d/my-host.internal\:5000/ca.crt /usr/local/share/ca-certificates/my-host.internal.crt
-
-sudo update-ca-certificates
-```
-
-If all goes well, this is what you should see:
-
-```plaintext
-1 added, 0 removed; done.
-Running hooks in /etc/ca-certificates/update.d...
-done.
-```
diff --git a/doc/topics/authentication/index.md b/doc/topics/authentication/index.md
index e4b86a39385..6ce5e203bbf 100644
--- a/doc/topics/authentication/index.md
+++ b/doc/topics/authentication/index.md
@@ -16,12 +16,9 @@ This page gathers all the resources for the topic **Authentication** within GitL
## GitLab administrators
-- [LDAP (Community Edition)](../../administration/auth/ldap.md)
-- [LDAP (Enterprise Edition)](../../administration/auth/ldap-ee.md) **(STARTER)**
+- [LDAP](../../administration/auth/ldap/index.md)
- [Enforce Two-factor Authentication (2FA)](../../security/two_factor_authentication.md#enforce-two-factor-authentication-2fa)
- **Articles:**
- - [How to Configure LDAP with GitLab CE](../../administration/auth/how_to_configure_ldap_gitlab_ce/index.md)
- - [How to Configure LDAP with GitLab EE](../../administration/auth/how_to_configure_ldap_gitlab_ee/index.md) **(STARTER)**
- [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)
- **Integrations:**
@@ -47,5 +44,5 @@ This page gathers all the resources for the topic **Authentication** within GitL
- [Kanboard Plugin GitLab Authentication](https://github.com/kanboard/plugin-gitlab-auth)
- [Jenkins GitLab OAuth Plugin](https://wiki.jenkins.io/display/JENKINS/GitLab+OAuth+Plugin)
-- [How to customize GitLab to support OpenID authentication](http://eric.van-der-vlist.com/blog/2013/11/23/how-to-customize-gitlab-to-support-openid-authentication/)
+- [How to customize GitLab to support OpenID authentication](https://blog.eric.van-der-vlist.com/2013/11/23/how-to-customize-gitlab-to-support-openid-authentication/)
- [OKD - Configuring Authentication and User Agent](https://docs.okd.io/3.11/install_config/configuring_authentication.html#GitLab)
diff --git a/doc/topics/autodevops/customize.md b/doc/topics/autodevops/customize.md
index 056b4c1caf4..253d5e56463 100644
--- a/doc/topics/autodevops/customize.md
+++ b/doc/topics/autodevops/customize.md
@@ -72,25 +72,20 @@ Avoid passing secrets as Docker build arguments if possible, as they may be
persisted in your image. See
[this discussion of best practices with secrets](https://github.com/moby/moby/issues/13490) for details.
-## Passing secrets to `docker build`
+## Forward CI variables to the build environment
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/25514) in GitLab 12.3, but available in versions 11.9 and above.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/25514) in GitLab 12.3, but available in versions 11.9 and above.
-CI environment variables can be passed as
-[build secrets](https://docs.docker.com/develop/develop-images/build_enhancements/#new-docker-build-secret-information) to the `docker build` command by listing them
-by name, comma-separated, in the `AUTO_DEVOPS_BUILD_IMAGE_FORWARDED_CI_VARIABLES`
-variable. For example, to forward the variables `CI_COMMIT_SHA` and `CI_ENVIRONMENT_NAME`,
-set `AUTO_DEVOPS_BUILD_IMAGE_FORWARDED_CI_VARIABLES` to `CI_COMMIT_SHA,CI_ENVIRONMENT_NAME`.
+CI variables can be forwarded into the build environment using the
+`AUTO_DEVOPS_BUILD_IMAGE_FORWARDED_CI_VARIABLES` CI variable.
+The forwarded variables should be specified by name in a comma-separated
+list. For example, to forward the variables `CI_COMMIT_SHA` and
+`CI_ENVIRONMENT_NAME`, set `AUTO_DEVOPS_BUILD_IMAGE_FORWARDED_CI_VARIABLES`
+to `CI_COMMIT_SHA,CI_ENVIRONMENT_NAME`.
-CAUTION: **Caution:**
-Unlike build arguments, these variables are not persisted by Docker in the final image,
-though you can still persist them yourself.
-
-In projects:
-
-- Without a `Dockerfile`, these are available automatically as environment
- variables.
-- With a `Dockerfile`, the following is required:
+- When using Buildpacks, the forwarded variables are available automatically
+ as environment variables.
+- When using a `Dockerfile`, the following additional steps are required:
1. Activate the experimental `Dockerfile` syntax by adding the following code
to the top of the file:
@@ -128,7 +123,7 @@ repository or by specifying a project variable:
## Customize values for Helm Chart
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/30628) in GitLab 12.6, `.gitlab/auto-deploy-values.yaml` will be used by default for Helm upgrades.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30628) in GitLab 12.6, `.gitlab/auto-deploy-values.yaml` will be used by default for Helm upgrades.
You can override the default values in the `values.yaml` file in the
[default Helm chart](https://gitlab.com/gitlab-org/charts/auto-deploy-app) by either:
@@ -175,7 +170,7 @@ into your project and edit it as needed.
## Customizing the Kubernetes namespace
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/27630) in GitLab 12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27630) in GitLab 12.6.
For clusters not managed by GitLab, you can customize the namespace in
`.gitlab-ci.yml` by specifying
@@ -302,13 +297,15 @@ applications.
| `<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_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` | When set to a non-empty value and no `Dockerfile` is present, Auto Build builds your application using Cloud Native Buildpacks instead of Herokuish. [More details](stages.md#auto-build-using-cloud-native-buildpacks-beta). |
+| `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-beta). |
| `AUTO_DEVOPS_BUILD_IMAGE_EXTRA_ARGS` | Extra arguments to be passed to the `docker build` command. Note that using quotes won't prevent word splitting. [More details](#passing-arguments-to-docker-build). |
-| `AUTO_DEVOPS_BUILD_IMAGE_FORWARDED_CI_VARIABLES` | A [comma-separated list of CI variable names](#passing-secrets-to-docker-build) to be passed to the `docker build` command as secrets. |
+| `AUTO_DEVOPS_BUILD_IMAGE_FORWARDED_CI_VARIABLES` | A [comma-separated list of CI variable names](#forward-ci-variables-to-the-build-environment) to be forwarded to the build environment (the buildpack builder or `docker build`). |
| `AUTO_DEVOPS_CHART` | Helm Chart used to deploy your apps. Defaults to the one [provided by GitLab](https://gitlab.com/gitlab-org/charts/auto-deploy-app). |
| `AUTO_DEVOPS_CHART_REPOSITORY` | Helm Chart repository used to search for charts. Defaults to `https://charts.gitlab.io`. |
| `AUTO_DEVOPS_CHART_REPOSITORY_NAME` | From GitLab 11.11, used to set the name of the Helm repository. Defaults to `gitlab`. |
| `AUTO_DEVOPS_CHART_REPOSITORY_USERNAME` | From GitLab 11.11, used to set a username to connect to the Helm repository. Defaults to no credentials. Also set `AUTO_DEVOPS_CHART_REPOSITORY_PASSWORD`. |
| `AUTO_DEVOPS_CHART_REPOSITORY_PASSWORD` | From GitLab 11.11, used to set a password to connect to the Helm repository. Defaults to no credentials. Also set `AUTO_DEVOPS_CHART_REPOSITORY_USERNAME`. |
+| `AUTO_DEVOPS_DEPLOY_DEBUG` | From GitLab 13.1, if this variable is present, Helm will output debug logs. |
| `AUTO_DEVOPS_MODSECURITY_SEC_RULE_ENGINE` | From GitLab 12.5, used in combination with [ModSecurity feature flag](../../user/clusters/applications.md#web-application-firewall-modsecurity) to toggle [ModSecurity's `SecRuleEngine`](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x)#SecRuleEngine) behavior. Defaults to `DetectionOnly`. |
| `BUILDPACK_URL` | Buildpack's full URL. Can point to either [a Git repository URL or a tarball URL](#custom-buildpacks). |
| `CANARY_ENABLED` | From GitLab 11.0, used to define a [deploy policy for canary environments](#deploy-policy-for-canary-environments-premium). |
@@ -368,7 +365,7 @@ The following table lists variables used to disable jobs.
### Application secret variables
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/49056) in GitLab 11.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/49056) in GitLab 11.7.
Some applications need to define secret variables that are accessible by the deployed
application. Auto DevOps detects variables starting with `K8S_SECRET_`, and makes
@@ -506,7 +503,7 @@ If you define `CANARY_ENABLED` in your project, such as setting `CANARY_ENABLED`
### Incremental rollout to production **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/5415) in GitLab 10.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5415) in GitLab 10.8.
TIP: **Tip:**
You can also set this inside your [project's settings](index.md#deployment-strategy).
@@ -563,7 +560,7 @@ removed in the future.
### Timed incremental rollout to production **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/7545) in GitLab 11.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7545) in GitLab 11.4.
TIP: **Tip:**
You can also set this inside your [project's settings](index.md#deployment-strategy).
@@ -597,7 +594,7 @@ The banner can be disabled for:
- By an administrator running the following in a Rails console:
```ruby
- Feature.get(:auto_devops_banner_disabled).enable
+ Feature.enable(:auto_devops_banner_disabled)
```
- Through the REST API with an admin access token:
diff --git a/doc/topics/autodevops/img/guide_pipeline_stages_v12_3.png b/doc/topics/autodevops/img/guide_pipeline_stages_v12_3.png
deleted file mode 100644
index b9bab112a9f..00000000000
--- a/doc/topics/autodevops/img/guide_pipeline_stages_v12_3.png
+++ /dev/null
Binary files differ
diff --git a/doc/topics/autodevops/img/guide_pipeline_stages_v13_0.png b/doc/topics/autodevops/img/guide_pipeline_stages_v13_0.png
new file mode 100644
index 00000000000..fb102879556
--- /dev/null
+++ b/doc/topics/autodevops/img/guide_pipeline_stages_v13_0.png
Binary files differ
diff --git a/doc/topics/autodevops/index.md b/doc/topics/autodevops/index.md
index e7165136cf0..767ea5ee7b7 100644
--- a/doc/topics/autodevops/index.md
+++ b/doc/topics/autodevops/index.md
@@ -1,6 +1,6 @@
# Auto DevOps
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/37115) in GitLab 10.0.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/37115) in GitLab 10.0.
> - Generally available on GitLab 11.0.
Auto DevOps provides pre-defined CI/CD configuration allowing you to automatically
@@ -25,9 +25,11 @@ and GitLab does the rest, improving your productivity and efficiency.
For an introduction to Auto DevOps, watch [AutoDevOps in GitLab 11.0](https://youtu.be/0Tc0YYBxqi4).
+For requirements, see [Requirements for Auto DevOps](requirements.md) for more information.
+
## Enabled by default
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/41729) in GitLab 11.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41729) in GitLab 11.3.
Auto DevOps is enabled by default for all projects and attempts to run on all pipelines
in each project. An instance administrator can enable or disable this default in the
@@ -35,7 +37,7 @@ in each project. An instance administrator can enable or disable this default in
Auto DevOps automatically disables in individual projects on their first pipeline failure,
if it has not been explicitly enabled for the project.
-Since [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/issues/26655), Auto DevOps
+Since [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/issues/26655), Auto DevOps
runs on pipelines automatically only if a [`Dockerfile` or matching buildpack](stages.md#auto-build)
exists.
@@ -54,7 +56,7 @@ configuring a cluster on GKE. After configuring the provider, you can follow
the steps in the [quick start guide](quick_start_guide.md) to get started.
In [GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/issues/208132) and later, it is
-possible to leverage Auto DevOps to deploy to [AWS ECS](#aws-ecs).
+possible to leverage Auto DevOps to deploy to [AWS ECS](requirements.md#auto-devops-requirements-for-amazon-ecs).
## Comparison to application platforms and PaaS
@@ -76,13 +78,14 @@ in multiple ways:
## Features
-Comprised of a set of stages, Auto DevOps brings these best practices to your
+Comprised of a set of [stages](stages.md), Auto DevOps brings these best practices to your
project in a simple and automatic way:
1. [Auto Build](stages.md#auto-build)
1. [Auto Test](stages.md#auto-test)
1. [Auto Code Quality](stages.md#auto-code-quality-starter) **(STARTER)**
1. [Auto SAST (Static Application Security Testing)](stages.md#auto-sast-ultimate) **(ULTIMATE)**
+1. [Auto Secret Detection](stages.md#auto-secret-detection-ultimate) **(ULTIMATE)**
1. [Auto Dependency Scanning](stages.md#auto-dependency-scanning-ultimate) **(ULTIMATE)**
1. [Auto License Compliance](stages.md#auto-license-compliance-ultimate) **(ULTIMATE)**
1. [Auto Container Scanning](stages.md#auto-container-scanning-ultimate) **(ULTIMATE)**
@@ -111,127 +114,6 @@ NOTE: **Note**
Kubernetes clusters can [be used without](../../user/project/clusters/index.md)
Auto DevOps.
-## Requirements
-
-### Kubernetes
-
-To make full use of Auto DevOps with Kubernetes, you need:
-
-- **Kubernetes** (for [Auto Review Apps](stages.md#auto-review-apps),
- [Auto Deploy](stages.md#auto-deploy), and [Auto Monitoring](stages.md#auto-monitoring))
-
- To enable deployments, you need:
-
- 1. A [Kubernetes 1.12+ cluster](../../user/project/clusters/index.md) for your
- project. The easiest way is to create a
- [new cluster using the GitLab UI](../../user/project/clusters/add_remove_clusters.md#create-new-cluster).
- For Kubernetes 1.16+ clusters, you must perform additional configuration for
- [Auto Deploy for Kubernetes 1.16+](stages.md#kubernetes-116).
- 1. NGINX Ingress. You can deploy it to your Kubernetes cluster by installing
- the [GitLab-managed app for Ingress](../../user/clusters/applications.md#ingress),
- after configuring GitLab's Kubernetes integration in the previous step.
-
- Alternatively, you can use the
- [`nginx-ingress`](https://github.com/helm/charts/tree/master/stable/nginx-ingress)
- Helm chart to install Ingress manually.
-
- NOTE: **Note:**
- If you use your own Ingress instead of the one provided by GitLab's managed
- apps, ensure you're running at least version 0.9.0 of NGINX Ingress and
- [enable Prometheus metrics](https://github.com/helm/charts/tree/master/stable/nginx-ingress#prometheus-metrics)
- for the response metrics to appear. You must also
- [annotate](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/)
- the NGINX Ingress deployment to be scraped by Prometheus using
- `prometheus.io/scrape: "true"` and `prometheus.io/port: "10254"`.
-
-- **Base domain** (for [Auto Review Apps](stages.md#auto-review-apps),
- [Auto Deploy](stages.md#auto-deploy), and [Auto Monitoring](stages.md#auto-monitoring))
-
- You need a domain configured with wildcard DNS, which all of your Auto DevOps
- applications will use. If you're using the
- [GitLab-managed app for Ingress](../../user/clusters/applications.md#ingress),
- the URL endpoint is automatically configured for you.
-
- You must also [specify the Auto DevOps base domain](#auto-devops-base-domain).
-
-- **GitLab Runner** (for all stages)
-
- Your Runner must be configured to run Docker, usually with either the
- [Docker](https://docs.gitlab.com/runner/executors/docker.html)
- or [Kubernetes](https://docs.gitlab.com/runner/executors/kubernetes.html) executors, with
- [privileged mode enabled](https://docs.gitlab.com/runner/executors/docker.html#use-docker-in-docker-with-privileged-mode).
- The Runners don't need to be installed in the Kubernetes cluster, but the
- Kubernetes executor is easy to use and automatically autoscales.
- You can configure Docker-based Runners to autoscale as well, using
- [Docker Machine](https://docs.gitlab.com/runner/install/autoscaling.html).
-
- If you've configured GitLab's Kubernetes integration in the first step, you
- can deploy it to your cluster by installing the
- [GitLab-managed app for GitLab Runner](../../user/clusters/applications.md#gitlab-runner).
-
- Runners should be registered as [shared Runners](../../ci/runners/README.md#registering-a-shared-runner)
- for the entire GitLab instance, or [specific Runners](../../ci/runners/README.md#registering-a-specific-runner)
- that are assigned to specific projects (the default if you've installed the
- GitLab Runner managed application).
-
-- **Prometheus** (for [Auto Monitoring](stages.md#auto-monitoring))
-
- To enable Auto Monitoring, you need Prometheus installed either inside or
- outside your cluster, and configured to scrape your Kubernetes cluster.
- If you've configured GitLab's Kubernetes integration, you can deploy it to
- your cluster by installing the
- [GitLab-managed app for Prometheus](../../user/clusters/applications.md#prometheus).
-
- The [Prometheus service](../../user/project/integrations/prometheus.md)
- integration must be enabled for the project, or enabled as a
- [default service template](../../user/project/integrations/services_templates.md)
- for the entire GitLab installation.
-
- To get response metrics (in addition to system metrics), you must
- [configure Prometheus to monitor NGINX](../../user/project/integrations/prometheus_library/nginx_ingress.md#configuring-nginx-ingress-monitoring).
-
-- **cert-manager** (optional, for TLS/HTTPS)
-
- To enable HTTPS endpoints for your application, you must install cert-manager,
- a native Kubernetes certificate management controller that helps with issuing
- certificates. Installing cert-manager on your cluster issues a
- [Let’s Encrypt](https://letsencrypt.org/) certificate and ensures the
- certificates are valid and up-to-date. If you've configured GitLab's Kubernetes
- integration, you can deploy it to your cluster by installing the
- [GitLab-managed app for cert-manager](../../user/clusters/applications.md#cert-manager).
-
-If you don't have Kubernetes or Prometheus installed, then
-[Auto Review Apps](stages.md#auto-review-apps),
-[Auto Deploy](stages.md#auto-deploy), and [Auto Monitoring](stages.md#auto-monitoring)
-are skipped.
-
-After all requirements are met, you can [enable Auto DevOps](#enablingdisabling-auto-devops).
-
-### AWS ECS
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/208132) in GitLab 13.0.
-
-You can choose to target [AWS ECS](../../ci/cloud_deployment/index.md) as a deployment platform instead of using Kubernetes.
-
-To get started on Auto DevOps to ECS, you'll have to add a specific Environment
-Variable. To do so, follow these steps:
-
-1. In your project, go to **Settings > CI / CD** and expand the **Variables**
- section.
-
-1. Specify which AWS platform to target during the Auto DevOps deployment
- by adding the `AUTO_DEVOPS_PLATFORM_TARGET` variable.
-
-1. Give this variable the value `ECS` before saving it.
-
-When you trigger a pipeline, if you have AutoDev Ops enabled and if you have correctly
-[entered AWS credentials as environment variables](../../ci/cloud_deployment/index.md#deploy-your-application-to-aws-elastic-container-service-ecs),
-your application will be deployed to AWS ECS.
-
-NOTE: **Note:**
-If you have both a valid `AUTO_DEVOPS_PLATFORM_TARGET` variable and a Kubernetes cluster tied to your project,
-only the deployment to Kubernetes will run.
-
## Auto DevOps base domain
The Auto DevOps base domain is required to use
@@ -239,16 +121,18 @@ The Auto DevOps base domain is required to use
[Auto Monitoring](stages.md#auto-monitoring). You can define the base domain in
any of the following places:
-- either under the cluster's settings, whether for
+- either under the cluster's settings, whether for an instance,
[projects](../../user/project/clusters/index.md#base-domain) or
[groups](../../user/group/clusters/index.md#base-domain)
-- or in instance-wide settings in **{admin}** **Admin Area > Settings** under the
- **Continuous Integration and Delivery** section
- or at the project level as a variable: `KUBE_INGRESS_BASE_DOMAIN`
-- or at the group level as a variable: `KUBE_INGRESS_BASE_DOMAIN`.
+- or at the group level as a variable: `KUBE_INGRESS_BASE_DOMAIN`
+- or as an instance-wide fallback in **{admin}** **Admin Area > Settings** under the
+ **Continuous Integration and Delivery** section
The base domain variable `KUBE_INGRESS_BASE_DOMAIN` follows the same order of precedence
as other environment [variables](../../ci/variables/README.md#priority-of-environment-variables).
+If the CI/CD variable is not set and the cluster setting is left blank, the instance-wide **Auto DevOps domain**
+setting will be used if set.
TIP: **Tip:**
If you use the [GitLab managed app for Ingress](../../user/clusters/applications.md#ingress),
@@ -256,9 +140,9 @@ the URL endpoint should be automatically configured for you. All you must do
is use its value for the `KUBE_INGRESS_BASE_DOMAIN` variable.
NOTE: **Note:**
-`AUTO_DEVOPS_DOMAIN` was [deprecated in GitLab 11.8](https://gitlab.com/gitlab-org/gitlab-foss/issues/52363)
+`AUTO_DEVOPS_DOMAIN` was [deprecated in GitLab 11.8](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/52363)
and replaced with `KUBE_INGRESS_BASE_DOMAIN`, and removed in
-[GitLab 12.0](https://gitlab.com/gitlab-org/gitlab-foss/issues/56959).
+[GitLab 12.0](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/56959).
Auto DevOps requires a wildcard DNS A record matching the base domain(s). For
a base domain of `example.com`, you'd need a DNS entry like:
@@ -305,7 +189,7 @@ After enabling the feature, an Auto DevOps pipeline is triggered on the default
### At the group level
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/52447) in GitLab 11.10.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/52447) in GitLab 11.10.
Only administrators and group owners can enable or disable Auto DevOps at the group level.
@@ -330,19 +214,9 @@ Auto DevOps at the group and project level, respectively.
for Auto Deploy and Auto Review Apps to use.
1. Click **Save changes** for the changes to take effect.
-### Enable for a percentage of projects
-
-You can use a feature flag to enable Auto DevOps by default to your desired percentage
-of projects. From the console, enter the following command, replacing `10` with
-your desired percentage:
-
-```ruby
-Feature.get(:force_autodevops_on_by_default).enable_percentage_of_actors(10)
-```
-
### 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.
You can change the deployment strategy used by Auto DevOps by going to your
project's **{settings}** **Settings > CI/CD > Auto DevOps**. The following options
@@ -362,13 +236,17 @@ are available:
- `master` branch is directly deployed to staging.
- Manual actions are provided for incremental rollout to production.
+TIP: **Tip:**
+Use the [blue-green deployment](../../ci/environments/incremental_rollouts.md#blue-green-deployment) technique
+to minimize downtime and risk.
+
## Using multiple Kubernetes clusters **(PREMIUM)**
When using Auto DevOps, you can deploy different environments to
different Kubernetes clusters, due to the 1:1 connection
[existing between them](../../user/project/clusters/index.md#multiple-kubernetes-clusters-premium).
-The [template](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml)
+The [Deploy Job template](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml)
used by Auto DevOps currently defines 3 environment names:
- `review/` (every environment starting with `review/`)
@@ -393,9 +271,6 @@ To add a different cluster for each environment:
1. Navigate to your project's **{cloud-gear}** **Operations > Kubernetes**.
1. Create the Kubernetes clusters with their respective environment scope, as
described from the table above.
-
- ![Auto DevOps multiple clusters](img/autodevops_multiple_clusters.png)
-
1. After creating the clusters, navigate to each cluster and install Helm Tiller
and Ingress. Wait for the Ingress IP address to be assigned.
1. Make sure you've [configured your DNS](#auto-devops-base-domain) with the
@@ -408,35 +283,6 @@ and verifying your application is deployed as a Review App in the Kubernetes
cluster with the `review/*` environment scope. Similarly, you can check the
other environments.
-## Currently supported languages
-
-Note that not all buildpacks support Auto Test yet, as it's a relatively new
-enhancement. All of Heroku's
-[officially supported languages](https://devcenter.heroku.com/articles/heroku-ci#supported-languages)
-support Auto Test. The languages supported by Heroku's Herokuish buildpacks all
-support Auto Test, but notably the multi-buildpack does not.
-
-As of GitLab 10.0, the supported buildpacks are:
-
-```plaintext
-- heroku-buildpack-multi v1.0.0
-- heroku-buildpack-ruby v168
-- heroku-buildpack-nodejs v99
-- heroku-buildpack-clojure v77
-- heroku-buildpack-python v99
-- heroku-buildpack-java v53
-- heroku-buildpack-gradle v23
-- heroku-buildpack-scala v78
-- heroku-buildpack-play v26
-- heroku-buildpack-php v122
-- heroku-buildpack-go v72
-- heroku-buildpack-erlang fa17af9
-- buildpack-nginx v8
-```
-
-If your application needs a buildpack that is not in the above list, you
-might want to use a [custom buildpack](customize.md#custom-buildpacks).
-
## Limitations
The following restrictions apply.
@@ -490,11 +336,6 @@ The following are possible reasons:
- No buildpack may exist for your application. Try specifying a
[custom buildpack](customize.md#custom-buildpacks).
-### Mismatch between testing frameworks
-
-Auto Test may fail because of a mismatch between testing frameworks. In this
-case, you may need to customize your `.gitlab-ci.yml` with your test commands.
-
### Pipeline that extends Auto DevOps with only / except fails
If your pipeline fails with the following message:
diff --git a/doc/topics/autodevops/quick_start_guide.md b/doc/topics/autodevops/quick_start_guide.md
index 859219689f9..ec5191dd4ac 100644
--- a/doc/topics/autodevops/quick_start_guide.md
+++ b/doc/topics/autodevops/quick_start_guide.md
@@ -152,8 +152,6 @@ these steps to enable Auto DevOps if it's disabled:
After you save your changes, GitLab creates a new pipeline. To view it, go to
**{rocket}** **CI/CD > Pipelines**.
-![First pipeline](img/guide_first_pipeline_v12_3.png)
-
In the next section, we explain what each job does in the pipeline.
## Deploy the application
@@ -167,7 +165,7 @@ without refreshing the page to **{status_success}** (for success) or
The jobs are separated into stages:
-![Pipeline stages](img/guide_pipeline_stages_v12_3.png)
+![Pipeline stages](img/guide_pipeline_stages_v13_0.png)
- **Build** - The application builds a Docker image and uploads it to your project's
[Container Registry](../../user/packages/container_registry/index.md) ([Auto Build](stages.md#auto-build)).
@@ -182,8 +180,9 @@ The jobs are separated into stages:
- The `dependency_scanning` job checks if the application has any dependencies
susceptible to vulnerabilities and is allowed to fail
([Auto Dependency Scanning](stages.md#auto-dependency-scanning-ultimate)) **(ULTIMATE)**
- - The `sast` job runs static analysis on the current code to check for potential
- security issues and is allowed to fail ([Auto SAST](stages.md#auto-sast-ultimate)) **(ULTIMATE)**
+ - Jobs suffixed with `-sast` run static analysis on the current code to check for potential
+ security issues, and are allowed to fail ([Auto SAST](stages.md#auto-sast-ultimate)) **(ULTIMATE)**
+ - The `secret-detection` job checks for leaked secrets and is allowed to fail ([Auto Secret Detection](stages.md#auto-secret-detection-ultimate)) **(ULTIMATE)**
- The `license_management` job searches the application's dependencies to determine each of their
licenses and is allowed to fail
([Auto License Compliance](stages.md#auto-license-compliance-ultimate)) **(ULTIMATE)**
@@ -191,12 +190,17 @@ The jobs are separated into stages:
NOTE: **Note:**
All jobs except `test` are allowed to fail in the test stage.
+- **Review** - Pipelines on `master` include this stage with a `dast_environment_deploy` job.
+ To learn more, see [Dynamic Application Security Testing (DAST)](../../user/application_security/dast/index.md).
+
- **Production** - After the tests and checks finish, the application deploys in
Kubernetes ([Auto Deploy](stages.md#auto-deploy)).
- **Performance** - Performance tests are run on the deployed application
([Auto Browser Performance Testing](stages.md#auto-browser-performance-testing-premium)). **(PREMIUM)**
+- **Cleanup** - Pipelines on `master` include this stage with a `stop_dast_environment` job.
+
After running a pipeline, you should view your deployed website and learn how
to monitor it.
diff --git a/doc/topics/autodevops/requirements.md b/doc/topics/autodevops/requirements.md
new file mode 100644
index 00000000000..b09a571fd16
--- /dev/null
+++ b/doc/topics/autodevops/requirements.md
@@ -0,0 +1,134 @@
+# Requirements for Auto DevOps
+
+You can set up Auto DevOps for [Kubernetes](#auto-devops-requirements-for-kubernetes)
+or [Amazon Elastic Container Service (ECS)](#auto-devops-requirements-for-amazon-ecs).
+For more information about Auto DevOps, see [the main Auto DevOps page](index.md)
+or the [quick start guide](quick_start_guide.md).
+
+## Auto DevOps requirements for Kubernetes
+
+To make full use of Auto DevOps with Kubernetes, you need:
+
+- **Kubernetes** (for [Auto Review Apps](stages.md#auto-review-apps),
+ [Auto Deploy](stages.md#auto-deploy), and [Auto Monitoring](stages.md#auto-monitoring))
+
+ To enable deployments, you need:
+
+ 1. A [Kubernetes 1.12+ cluster](../../user/project/clusters/index.md) for your
+ project. The easiest way is to create a
+ [new cluster using the GitLab UI](../../user/project/clusters/add_remove_clusters.md#create-new-cluster).
+ For Kubernetes 1.16+ clusters, you must perform additional configuration for
+ [Auto Deploy for Kubernetes 1.16+](stages.md#kubernetes-116).
+ 1. NGINX Ingress. You can deploy it to your Kubernetes cluster by installing
+ the [GitLab-managed app for Ingress](../../user/clusters/applications.md#ingress),
+ after configuring GitLab's Kubernetes integration in the previous step.
+
+ Alternatively, you can use the
+ [`nginx-ingress`](https://github.com/helm/charts/tree/master/stable/nginx-ingress)
+ Helm chart to install Ingress manually.
+
+ NOTE: **Note:**
+ If you use your own Ingress instead of the one provided by GitLab's managed
+ apps, ensure you're running at least version 0.9.0 of NGINX Ingress and
+ [enable Prometheus metrics](https://github.com/helm/charts/tree/master/stable/nginx-ingress#prometheus-metrics)
+ for the response metrics to appear. You must also
+ [annotate](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/)
+ the NGINX Ingress deployment to be scraped by Prometheus using
+ `prometheus.io/scrape: "true"` and `prometheus.io/port: "10254"`.
+
+- **Base domain** (for [Auto Review Apps](stages.md#auto-review-apps),
+ [Auto Deploy](stages.md#auto-deploy), and [Auto Monitoring](stages.md#auto-monitoring))
+
+ You need a domain configured with wildcard DNS, which all of your Auto DevOps
+ applications will use. If you're using the
+ [GitLab-managed app for Ingress](../../user/clusters/applications.md#ingress),
+ the URL endpoint is automatically configured for you.
+
+ You must also [specify the Auto DevOps base domain](index.md#auto-devops-base-domain).
+
+- **GitLab Runner** (for all stages)
+
+ Your Runner must be configured to run Docker, usually with either the
+ [Docker](https://docs.gitlab.com/runner/executors/docker.html)
+ or [Kubernetes](https://docs.gitlab.com/runner/executors/kubernetes.html) executors, with
+ [privileged mode enabled](https://docs.gitlab.com/runner/executors/docker.html#use-docker-in-docker-with-privileged-mode).
+ The Runners don't need to be installed in the Kubernetes cluster, but the
+ Kubernetes executor is easy to use and automatically autoscales.
+ You can configure Docker-based Runners to autoscale as well, using
+ [Docker Machine](https://docs.gitlab.com/runner/install/autoscaling.html).
+
+ If you've configured GitLab's Kubernetes integration in the first step, you
+ can deploy it to your cluster by installing the
+ [GitLab-managed app for GitLab Runner](../../user/clusters/applications.md#gitlab-runner).
+
+ Runners should be registered as [shared Runners](../../ci/runners/README.md#shared-runners)
+ for the entire GitLab instance, or [specific Runners](../../ci/runners/README.md#specific-runners)
+ that are assigned to specific projects (the default if you've installed the
+ GitLab Runner managed application).
+
+- **Prometheus** (for [Auto Monitoring](stages.md#auto-monitoring))
+
+ To enable Auto Monitoring, you need Prometheus installed either inside or
+ outside your cluster, and configured to scrape your Kubernetes cluster.
+ If you've configured GitLab's Kubernetes integration, you can deploy it to
+ your cluster by installing the
+ [GitLab-managed app for Prometheus](../../user/clusters/applications.md#prometheus).
+
+ The [Prometheus service](../../user/project/integrations/prometheus.md)
+ integration must be enabled for the project, or enabled as a
+ [default service template](../../user/project/integrations/services_templates.md)
+ for the entire GitLab installation.
+
+ To get response metrics (in addition to system metrics), you must
+ [configure Prometheus to monitor NGINX](../../user/project/integrations/prometheus_library/nginx_ingress.md#configuring-nginx-ingress-monitoring).
+
+- **cert-manager** (optional, for TLS/HTTPS)
+
+ To enable HTTPS endpoints for your application, you must install cert-manager,
+ a native Kubernetes certificate management controller that helps with issuing
+ certificates. Installing cert-manager on your cluster issues a
+ [Let’s Encrypt](https://letsencrypt.org/) certificate and ensures the
+ certificates are valid and up-to-date. If you've configured GitLab's Kubernetes
+ integration, you can deploy it to your cluster by installing the
+ [GitLab-managed app for cert-manager](../../user/clusters/applications.md#cert-manager).
+
+If you don't have Kubernetes or Prometheus installed, then
+[Auto Review Apps](stages.md#auto-review-apps),
+[Auto Deploy](stages.md#auto-deploy), and [Auto Monitoring](stages.md#auto-monitoring)
+are skipped.
+
+After all requirements are met, you can [enable Auto DevOps](index.md#enablingdisabling-auto-devops).
+
+## Auto DevOps requirements for Amazon ECS
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/208132) in GitLab 13.0.
+
+You can choose to target [Amazon Elastic Container Service (ECS)](../../ci/cloud_deployment/index.md) as a deployment platform instead of using Kubernetes.
+
+To get started on Auto DevOps to Amazon ECS, you'll have to add a specific Environment
+Variable. To do so, follow these steps:
+
+1. In your project, go to **Settings > CI / CD** and expand the **Variables**
+ section.
+
+1. Specify which AWS platform to target during the Auto DevOps deployment
+ by adding the `AUTO_DEVOPS_PLATFORM_TARGET` variable.
+
+1. Give this variable the value `ECS` before saving it.
+
+When you trigger a pipeline, if Auto DevOps is enabled and if you've correctly
+[entered AWS credentials as environment variables](../../ci/cloud_deployment/index.md#deploy-your-application-to-the-aws-elastic-container-service-ecs),
+your application will be deployed to Amazon ECS.
+
+NOTE: **Note:**
+If you have both a valid `AUTO_DEVOPS_PLATFORM_TARGET` variable and a Kubernetes cluster tied to your project,
+only the deployment to Kubernetes will run.
+
+CAUTION: **Warning:**
+Setting the `AUTO_DEVOPS_PLATFORM_TARGET` variable to `ECS` will trigger jobs
+defined in the [`Jobs/Deploy/ECS.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Jobs/Deploy/ECS.gitlab-ci.yml).
+However, it's not recommended to [include](../../ci/yaml/README.md#includetemplate)
+it on its own. This template is designed to be used with Auto DevOps only. It may change
+unexpectedly causing your pipeline to fail if included on its own. Also, the job
+names within this template may also change. Don't override these jobs' names in your
+own pipeline, as the override will stop working when the name changes.
diff --git a/doc/topics/autodevops/stages.md b/doc/topics/autodevops/stages.md
index 8c56a87ba30..0c7c4919431 100644
--- a/doc/topics/autodevops/stages.md
+++ b/doc/topics/autodevops/stages.md
@@ -53,7 +53,9 @@ troubleshoot.
Auto Build supports building your application using [Cloud Native Buildpacks](https://buildpacks.io)
through the [`pack` command](https://github.com/buildpacks/pack). To use Cloud Native Buildpacks,
-set the CI variable `AUTO_DEVOPS_BUILD_IMAGE_CNB_ENABLED` to a non-empty value.
+set the CI variable `AUTO_DEVOPS_BUILD_IMAGE_CNB_ENABLED` to a non-empty
+value. The default builder is `heroku/buildpacks:18` but a different builder
+can be selected using the CI variable `AUTO_DEVOPS_BUILD_IMAGE_CNB_BUILDER`.
Cloud Native Buildpacks (CNBs) are an evolution of Heroku buildpacks, and
will eventually supersede Herokuish-based builds within Auto DevOps. For more
@@ -82,11 +84,39 @@ Auto Test runs the appropriate tests for your application using
your project to detect the language and framework. Several languages and
frameworks are detected automatically, but if your language is not detected,
you may be able to create a [custom buildpack](customize.md#custom-buildpacks).
-Check the [currently supported languages](index.md#currently-supported-languages).
+Check the [currently supported languages](#currently-supported-languages).
Auto Test uses tests you already have in your application. If there are no
tests, it's up to you to add them.
+### Currently supported languages
+
+Note that not all buildpacks support Auto Test yet, as it's a relatively new
+enhancement. All of Heroku's
+[officially supported languages](https://devcenter.heroku.com/articles/heroku-ci#supported-languages)
+support Auto Test. The languages supported by Heroku's Herokuish buildpacks all
+support Auto Test, but notably the multi-buildpack does not.
+
+The supported buildpacks are:
+
+```plaintext
+- heroku-buildpack-multi
+- heroku-buildpack-ruby
+- heroku-buildpack-nodejs
+- heroku-buildpack-clojure
+- heroku-buildpack-python
+- heroku-buildpack-java
+- heroku-buildpack-gradle
+- heroku-buildpack-scala
+- heroku-buildpack-play
+- heroku-buildpack-php
+- heroku-buildpack-go
+- buildpack-nginx
+```
+
+If your application needs a buildpack that is not in the above list, you
+might want to use a [custom buildpack](customize.md#custom-buildpacks).
+
## Auto Code Quality **(STARTER)**
Auto Code Quality uses the
@@ -114,6 +144,22 @@ warnings.
To learn more about [how SAST works](../../user/application_security/sast/index.md),
see the documentation.
+## Auto Secret Detection **(ULTIMATE)**
+
+> Introduced in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.1.
+
+Secret Detection uses the
+[Secret Detection Docker image](https://gitlab.com/gitlab-org/security-products/analyzers/secrets) to run Secret Detection on the current code, and checks for leaked secrets. The
+Auto Secret Detection stage runs only on the
+[Ultimate](https://about.gitlab.com/pricing/) tier, and requires
+[GitLab Runner](https://docs.gitlab.com/runner/) 11.5 or above.
+
+After creating the report, it's uploaded as an artifact which you can later
+download and evaluate. The merge request widget also displays any security
+warnings.
+
+To learn more, see [Secret Detection](../../user/application_security/secret_detection/index.md).
+
## Auto Dependency Scanning **(ULTIMATE)**
> Introduced in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.7.
@@ -166,7 +212,7 @@ see the documentation.
## Auto Review Apps
This is an optional step, since many projects don't have a Kubernetes cluster
-available. If the [requirements](index.md#requirements) are not met, the job is
+available. If the [requirements](requirements.md) are not met, the job is
silently skipped.
[Review Apps](../../ci/review_apps/index.md) are temporary application environments based on the
@@ -267,7 +313,7 @@ Any performance differences between the source and target branches are also
## Auto Deploy
This is an optional step, since many projects don't have a Kubernetes cluster
-available. If the [requirements](index.md#requirements) are not met, the job is skipped.
+available. If the [requirements](requirements.md) are not met, the job is skipped.
After a branch or merge request is merged into the project's default branch (usually
`master`), Auto Deploy deploys the application to a `production` environment in
@@ -328,7 +374,7 @@ as it attempts to fetch the image using `CI_REGISTRY_PASSWORD`.
CAUTION: **Deprecation**
The default value for the `deploymentApiVersion` setting was changed from
-`extensions/v1beta` to `apps/v1` in [GitLab 13.0](https://gitlab.com/gitlab-org/charts/auto-deploy-app/issues/47).
+`extensions/v1beta` to `apps/v1` in [GitLab 13.0](https://gitlab.com/gitlab-org/charts/auto-deploy-app/-/issues/47).
In Kubernetes 1.16 and later, a number of
[APIs were removed](https://kubernetes.io/blog/2019/07/18/api-deprecations-in-1-16/),
@@ -467,7 +513,7 @@ traffic within a local namespace, and from the `gitlab-managed-apps`
namespace. All other inbound connections are blocked. Outbound
traffic (for example, to the Internet) is not affected by the default policy.
-You can also provide a custom [policy specification](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.16/#networkpolicyspec-v1-networking-k8s-io)
+You can also provide a custom [policy specification](https://kubernetes.io/docs/concepts/services-networking/network-policies/)
in the `.gitlab/auto-deploy-values.yaml` file, for example:
```yaml
@@ -568,7 +614,7 @@ GitLab provides some initial alerts for you after you install Prometheus:
To use Auto Monitoring:
-1. [Install and configure the requirements](index.md#requirements).
+1. [Install and configure the Auto DevOps requirements](requirements.md).
1. [Enable Auto DevOps](index.md#enablingdisabling-auto-devops), if you haven't done already.
1. Navigate to your project's **{rocket}** **CI/CD > Pipelines** and click **Run Pipeline**.
1. After the pipeline finishes successfully, open the
diff --git a/doc/topics/git/feature_branch_development.md b/doc/topics/git/feature_branch_development.md
new file mode 100644
index 00000000000..ab3adf54dd7
--- /dev/null
+++ b/doc/topics/git/feature_branch_development.md
@@ -0,0 +1,86 @@
+---
+type: how-tos
+---
+
+# Develop on a feature branch
+
+GitLab values encourage the use of [Minimal Viable Change (MVC)](https://about.gitlab.com/handbook/values/#minimal-viable-change-mvc).
+However, viable changes are not always small. In such cases, it can help to set up a dedicated feature branch.
+People can contribute MRs to that feature branch, without affecting the functionality of the default (usually `master`) branch.
+
+Once work on the development branch is complete, then the feature branch can be finally merged into the default branch.
+
+GitLab frequently implements this process whenever there is an MVC that requires multiple MRs.
+
+## Use case: GitLab's release posts
+
+This section describes the use case with GitLab [release posts](https://about.gitlab.com/handbook/marketing/blog/release-posts/).
+Dozens of GitLab team members contribute to each monthly release post.
+In such cases, it may be more efficient to submit an MR on the release post feature branch instead of master.
+
+In this case, the feature branch would be `release-X-Y`. Assuming the `release-X-Y` branch already exists, you can set up an MR against that branch, with the following steps:
+
+1. Create a new branch (`test-branch`) against the feature branch (`release-X-Y`):
+
+ ```shell
+ git checkout -b test-branch release-X-Y
+ ```
+
+ You should now be on a branch named `test-branch`.
+
+1. Make desired changes on the `test-branch`.
+1. Add your changes, commit, and push to the `test-branch`:
+
+ ```shell
+ git add .
+ ```
+
+1. Commit your changes:
+
+ ```shell
+ git commit -m "Some good reason"
+ ```
+
+1. Push your changes to the repository:
+
+ ```shell
+ git push --set-upstream origin test-branch
+ ```
+
+1. Navigate to the URL for your repository. In this case, the repository is `www-gitlab-com`, available at `https://gitlab.com/gitlab-com/www-gitlab-com`.
+
+ If needed, sign in to GitLab. You should then see an option to **Create merge request**:
+
+ ![Create merge request](img/create_merge_request_v13_1.png)
+
+1. After you click **Create merge request**, you'll see an option to **Change branches**. Select that option.
+
+1. In the **New Merge Request** screen, you can now select the **Source** and **Target** branches.
+In the screenshot shown,
+we have selected `test-branch` as the source, and `release-13-0` as the target.
+
+ ![Modify branches](img/modify_branches_v13_1.png)
+
+1. Once you've selected the Source and Target branches, click **Compare branches and continue**.
+ You should see an entry similar to:
+
+ ```plaintext
+ New Merge Request
+
+ From test-branch into release-13-0
+ ```
+
+ An entry like this confirms that your MR will **not** merge into master.
+
+1. Make any additional changes in the **New Merge Request** screen, and click **Submit merge request**.
+1. In the new merge request, look for **Request to merge**. You'll see an entry similar to:
+
+ ```plaintext
+ Request to merge test-branch into release-13-0
+ ```
+
+ That confirms you've set up the MR to merge into the specified branch, not master.
+
+1. Proceed with the change as you would with any other MR.
+1. When your MR is approved, and an appropriate user merges that MR, you can rest assured that your work is incorporated directly into the feature branch.
+When the feature branch is ready, it can then be merged into master.
diff --git a/doc/topics/git/img/create_merge_request_v13_1.png b/doc/topics/git/img/create_merge_request_v13_1.png
new file mode 100644
index 00000000000..a725149f6a2
--- /dev/null
+++ b/doc/topics/git/img/create_merge_request_v13_1.png
Binary files differ
diff --git a/doc/topics/git/img/modify_branches_v13_1.png b/doc/topics/git/img/modify_branches_v13_1.png
new file mode 100644
index 00000000000..dc517dd249f
--- /dev/null
+++ b/doc/topics/git/img/modify_branches_v13_1.png
Binary files differ
diff --git a/doc/topics/git/index.md b/doc/topics/git/index.md
index 9e6875312f3..2e36fea14bf 100644
--- a/doc/topics/git/index.md
+++ b/doc/topics/git/index.md
@@ -68,6 +68,7 @@ If you have problems with Git, the following may help:
## Branching strategies
- [Feature branch workflow](../../gitlab-basics/feature_branch_workflow.md)
+- [Develop on a feature branch](feature_branch_development.md)
- [GitLab Flow](../gitlab_flow.md)
- [Git Branching - Branches in a Nutshell](https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell)
- [Git Branching - Branching Workflows](https://git-scm.com/book/en/v2/Git-Branching-Branching-Workflows)
@@ -91,7 +92,7 @@ Git-related queries from GitLab.
The following relate to Git Large File Storage:
- [Getting Started with Git LFS](https://about.gitlab.com/blog/2017/01/30/getting-started-with-git-lfs-tutorial/)
-- [Migrate an existing Git repo with Git LFS](lfs/migrate_to_git_lfs.md)
+- [Migrate an existing Git repository with Git LFS](lfs/migrate_to_git_lfs.md)
- [Removing objects from LFS](lfs/index.md#removing-objects-from-lfs)
- [GitLab Git LFS user documentation](lfs/index.md)
- [GitLab Git LFS admin documentation](../../administration/lfs/index.md)
diff --git a/doc/topics/git/lfs/index.md b/doc/topics/git/lfs/index.md
index 33b7fa45691..706d3c3eddf 100644
--- a/doc/topics/git/lfs/index.md
+++ b/doc/topics/git/lfs/index.md
@@ -37,7 +37,7 @@ Documentation for GitLab instance administrators is under [LFS administration do
- Any Git LFS request will ask for HTTPS credentials to be provided so a good Git
credentials store is recommended
- Git LFS always assumes HTTPS so if you have GitLab server on HTTP you will have
- to add the URL to Git config manually (see [troubleshooting](#troubleshooting))
+ to add the URL to Git configuration manually (see [troubleshooting](#troubleshooting))
NOTE: **Note:**
With 8.12 GitLab added LFS support to SSH. The Git LFS communication
@@ -83,7 +83,7 @@ git clone git@gitlab.example.com:group/project.git
```
If you already cloned the repository and you want to get the latest LFS object
-that are on the remote repository, eg. for a branch from origin:
+that are on the remote repository, such as for a branch from origin:
```shell
git lfs fetch origin master
@@ -91,18 +91,18 @@ git lfs fetch origin master
### Migrate an existing repo to Git LFS
-Read the documentation on how to [migrate an existing Git repo with Git LFS](migrate_to_git_lfs.md).
+Read the documentation on how to [migrate an existing Git repository with Git LFS](migrate_to_git_lfs.md).
### Removing objects from LFS
To remove objects from LFS:
-1. Use [BFG-Cleaner](../../../user/project/repository/reducing_the_repo_size_using_git.md#using-the-bfg-repo-cleaner) or [filter-branch](../../../user/project/repository/reducing_the_repo_size_using_git.md#using-git-filter-branch) to remove the objects from the repository.
+1. Use [`git filter-repo`](../../../user/project/repository/reducing_the_repo_size_using_git.md) to remove the objects from the repository.
1. Delete the relevant LFS lines for the objects you have removed from your `.gitattributes` file and commit those changes.
## File Locking
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/35856) in GitLab 10.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/35856) in GitLab 10.5.
The first thing to do before using File Locking is to tell Git LFS which
kind of files are lockable. The following command will store PNG files
@@ -128,7 +128,7 @@ in order to do that you can edit the `.gitattributes` file manually:
```
After a file type has been registered as lockable, Git LFS will make
-them readonly on the file system automatically. This means you will
+them read-only on the file system automatically. This means you will
need to lock the file before editing it.
### Managing Locked Files
@@ -205,8 +205,8 @@ If the status `error 501` is shown, it is because:
on how to enable LFS support.
- Git LFS client version is not supported by GitLab server. Check your Git LFS
- version with `git lfs version`. Check the Git config of the project for traces
- of deprecated API with `git lfs -l`. If `batch = false` is set in the config,
+ version with `git lfs version`. Check the Git configuration of the project for traces
+ of deprecated API with `git lfs -l`. If `batch = false` is set in the configuration,
remove the line and try to update your Git LFS client. Only version 1.0.1 and
newer are supported.
@@ -218,9 +218,9 @@ the LFS client is trying to reach GitLab through HTTPS. However, your GitLab
instance is being served on HTTP.
This behavior is caused by Git LFS using HTTPS connections by default when a
-`lfsurl` is not set in the Git config.
+`lfsurl` is not set in the Git configuration.
-To prevent this from happening, set the lfs URL in project Git config:
+To prevent this from happening, set the LFS URL in project Git configuration:
```shell
git config --add lfs.url "http://gitlab.example.com/group/project.git/info/lfs"
diff --git a/doc/topics/git/lfs/migrate_from_git_annex_to_git_lfs.md b/doc/topics/git/lfs/migrate_from_git_annex_to_git_lfs.md
index 05b749d7b24..09087fcae13 100644
--- a/doc/topics/git/lfs/migrate_from_git_annex_to_git_lfs.md
+++ b/doc/topics/git/lfs/migrate_from_git_annex_to_git_lfs.md
@@ -1,7 +1,7 @@
# Migration guide from Git Annex to Git LFS
>**Note:**
-Git Annex support [has been removed](https://gitlab.com/gitlab-org/gitlab/issues/1648) in GitLab Enterprise
+Git Annex support [has been removed](https://gitlab.com/gitlab-org/gitlab/-/issues/1648) in GitLab Enterprise
Edition 9.0 (2017/03/22).
Both [Git Annex](http://git-annex.branchable.com/) and [Git LFS](https://git-lfs.github.com/) are tools to manage large files in Git.
@@ -172,7 +172,7 @@ GitLab.com), therefore, you don't need to do anything server-side.
If the terminal doesn't prompt you with a full response on `git-lfs` commands,
[install the Git LFS client](https://git-lfs.github.com/) first.
-1. Inside the repo, run the following command to initiate LFS:
+1. Inside the repository, run the following command to initiate LFS:
```shell
git lfs install
@@ -189,7 +189,7 @@ GitLab.com), therefore, you don't need to do anything server-side.
```
Once you do that, run `git status` and you'll see `.gitattributes` added
- to your repo. It collects all file patterns that you chose to track via
+ to your repository. It collects all file patterns that you chose to track via
`git-lfs`.
1. Add the files, commit and push them to GitLab:
diff --git a/doc/topics/git/lfs/migrate_to_git_lfs.md b/doc/topics/git/lfs/migrate_to_git_lfs.md
index 60859686047..a64639a9238 100644
--- a/doc/topics/git/lfs/migrate_to_git_lfs.md
+++ b/doc/topics/git/lfs/migrate_to_git_lfs.md
@@ -16,18 +16,18 @@ the files are still referenced by previous commits.
Through the method described on this document, first migrate
to Git LFS with a tool such as the open source community-maintained [BFG](https://rtyley.github.io/bfg-repo-cleaner/)
-through a mirror repo, then clean up the repository's history,
+through a mirror repository, then clean up the repository's history,
and lastly create LFS tracking rules to prevent new binary files
from being added.
This tutorial was inspired by the guide
-[Use BFG to migrate a repo to Git LFS](https://confluence.atlassian.com/bitbucket/use-bfg-to-migrate-a-repo-to-git-lfs-834233484.html).
+[Use BFG to migrate a repository to Git LFS](https://confluence.atlassian.com/bitbucket/use-bfg-to-migrate-a-repo-to-git-lfs-834233484.html).
For more information on Git LFS, see the [references](#references)
below.
CAUTION: **Warning:**
The method described on this guide rewrites Git history. Make
-sure to back up your repo before beginning and use it at your
+sure to back up your repository before beginning and use it at your
own risk.
## Requirements
@@ -71,7 +71,7 @@ Consider an example upstream project, `git@gitlab.com:gitlab-tests/test-git-lfs-
Create a copy of your repository so that you can
recover it in case something goes wrong.
-1. Clone `--mirror` the repo:
+1. Clone `--mirror` the repository:
Cloning with the mirror flag will create a bare repository.
This ensures you get all the branches within the repo.
@@ -102,7 +102,7 @@ Consider an example upstream project, `git@gitlab.com:gitlab-tests/test-git-lfs-
git reflog expire --expire=now --all && git gc --prune=now --aggressive
```
- You can also take a look on how to further [clean the repo](../../../user/project/repository/reducing_the_repo_size_using_git.md),
+ You can also take a look on how to further [clean the repository](../../../user/project/repository/reducing_the_repo_size_using_git.md),
but it's not necessary for the purposes of this guide.
1. Install Git LFS in the mirror repository:
@@ -166,7 +166,7 @@ but commented out to help encourage others to add to it in the future. -->
- [Migrate from Git Annex to Git LFS](migrate_from_git_annex_to_git_lfs.md)
- [GitLab's Git LFS user documentation](index.md)
- [GitLab's Git LFS administrator documentation](../../../administration/lfs/index.md)
-- Alternative method to [migrate an existing repo to Git LFS](https://github.com/git-lfs/git-lfs/wiki/Tutorial#migrating-existing-repository-data-to-lfs)
+- Alternative method to [migrate an existing repository to Git LFS](https://github.com/git-lfs/git-lfs/wiki/Tutorial#migrating-existing-repository-data-to-lfs)
<!--
Test project:
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 8597325db7b..fdf86d8f646 100644
--- a/doc/topics/git/numerous_undo_possibilities_in_git/index.md
+++ b/doc/topics/git/numerous_undo_possibilities_in_git/index.md
@@ -26,6 +26,11 @@ This means that until Git automatically cleans detached commits (which cannot be
accessed by branch or tag) it will be possible to view them with `git reflog` command
and access them with direct commit ID. Read more about _[redoing the undo](#redoing-the-undo)_ in the section below.
+> For more information about working with Git and GitLab:
+>
+> - <i class="fa fa-youtube-play youtube" aria-hidden="true"></i>&nbsp;Learn why [North Western Mutual chose GitLab](https://youtu.be/kPNMyxKRRoM) for their Enterprise source code management.
+> - Learn how to [get started with Git](https://about.gitlab.com/resources/whitepaper-moving-to-git/).
+
## Introduction
This guide is organized depending on the [stage of development](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository)
diff --git a/doc/topics/git/partial_clone.md b/doc/topics/git/partial_clone.md
index 46318a7f30d..7462406cad3 100644
--- a/doc/topics/git/partial_clone.md
+++ b/doc/topics/git/partial_clone.md
@@ -141,7 +141,7 @@ enabled on the Git server:
1. **Create a new Git repository and fetch.** Support for `--filter=sparse:oid`
using the clone command is incomplete, so we will emulate the clone command
by hand, using `git init` and `git fetch`. Follow
- [issue tracking support for `--filter=sparse:oid`](https://gitlab.com/gitlab-org/git/issues/4)
+ [issue tracking support for `--filter=sparse:oid`](https://gitlab.com/gitlab-org/git/-/issues/4)
for updates.
```shell
@@ -173,7 +173,7 @@ enabled on the Git server:
1. **Sparse checkout** must be enabled and configured to prevent objects from
other paths being downloaded automatically when checking out branches. Follow
- [issue proposing automating sparse checkouts](https://gitlab.com/gitlab-org/git/issues/5) for updates.
+ [issue proposing automating sparse checkouts](https://gitlab.com/gitlab-org/git/-/issues/5) for updates.
```shell
# Enable sparse checkout
diff --git a/doc/topics/gitlab_flow.md b/doc/topics/gitlab_flow.md
index 4738c5b23d7..6382ac0957a 100644
--- a/doc/topics/gitlab_flow.md
+++ b/doc/topics/gitlab_flow.md
@@ -15,7 +15,7 @@ Organizations coming to Git from other version control systems frequently find i
This article describes GitLab flow, which integrates the Git workflow with an issue tracking system.
It offers a simple, transparent, and effective way to work with Git.
-![Four stages (working copy, index, local repo, remote repo) and three steps between them](img/gitlab_flow_four_stages.png)
+![Four stages (working copy, index, local repository, remote repository) and three steps between them](img/gitlab_flow_four_stages.png)
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.
diff --git a/doc/topics/index.md b/doc/topics/index.md
index e2749b58b03..634dd70613a 100644
--- a/doc/topics/index.md
+++ b/doc/topics/index.md
@@ -14,5 +14,6 @@ tutorials, technical overviews, blog posts) and videos.
- [GitLab Flow](gitlab_flow.md)
- [GitLab Installation](../install/README.md)
- [GitLab Pages](../user/project/pages/index.md)
+- [Offline GitLab](offline/index.md)
>**Note:** More topics will be available soon.
diff --git a/doc/topics/offline/index.md b/doc/topics/offline/index.md
new file mode 100644
index 00000000000..6d4c486d350
--- /dev/null
+++ b/doc/topics/offline/index.md
@@ -0,0 +1,138 @@
+# Offline GitLab
+
+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.
+
+## Quick start
+
+If you plan to deploy a GitLab instance on a physically-isolated and offline network, see the
+[quick start guide](quick_start_guide.md) for configuration steps.
+
+## Features
+
+Follow these best practices to use GitLab's features in an offline environment:
+
+- [Operating the GitLab Secure scanners in an offline environment](../../user/application_security/offline_deployments/index.md).
+
+## Loading Docker images onto your offline host
+
+To use many GitLab features, including
+[security scans](../../user/application_security/index.md#working-in-an-offline-environment)
+and [Auto DevOps](../autodevops/), the GitLab Runner must be able to fetch the
+relevant Docker images.
+
+The process for making these images available without direct access to the public internet
+involves downloading the images then packaging and transferring them to the offline host. Here's an
+example of such a transfer:
+
+1. Download Docker images from public internet.
+1. Package Docker images as tar archives.
+1. Transfer images to offline environment.
+1. Load transferred images into offline Docker registry.
+
+### Using the official GitLab template
+
+GitLab provides a [vendored template](../../ci/yaml/README.md#includetemplate)
+to ease this process.
+
+This template should be used in a new, empty project, with a `gitlab-ci.yml` file containing:
+
+```yaml
+include:
+ - template: Secure-Binaries.gitlab-ci.yml
+```
+
+The pipeline downloads the Docker images needed for the Security Scanners and saves them as
+[job artifacts](../../ci/pipelines/job_artifacts.md) or pushes them to the [Container Registry](../../user/packages/container_registry/index.md)
+of the project where the pipeline is executed. These archives can be transferred to another location
+and [loaded](https://docs.docker.com/engine/reference/commandline/load/) in a Docker daemon.
+This method requires a GitLab Runner with access to both `gitlab.com` (including
+`registry.gitlab.com`) and the local offline instance. This runner must run in
+[privileged mode](https://docs.gitlab.com/runner/executors/docker.html#use-docker-in-docker-with-privileged-mode)
+to be able to use the `docker` command inside the jobs. This runner can be installed in a DMZ or on
+a bastion, and used only for this specific project.
+
+#### Scheduling the updates
+
+By default, this project's pipeline will run only once, when the `.gitlab-ci.yml` is added to the
+repo. To update the GitLab security scanners and signatures, it's necessary to run this pipeline
+regularly. GitLab provides a way to [schedule pipelines](../../ci/pipelines/schedules.md). For
+example, you can set this up to download and store the Docker images every week.
+
+Some images can be updated more frequently than others. For example, the [vulnerability database](https://hub.docker.com/r/arminc/clair-db/tags)
+for Container Scanning is updated daily. To update this single image, create a new Scheduled
+Pipeline that runs daily and set `SECURE_BINARIES_ANALYZERS` to `clair-vulnerabilities-db`. Only
+this job will be triggered, and the image will be updated daily and made available in the project
+registry.
+
+#### Using the secure bundle created
+
+The project using the `Secure-Binaries.gitlab-ci.yml` template should now host all the required
+images and resources needed to run GitLab Security features.
+
+Next, you must tell the offline instance to use these resources instead of the default ones on
+GitLab.com. To do so, set the environment variable `SECURE_ANALYZERS_PREFIX` with the URL of the
+project [container registry](../../user/packages/container_registry/index.md).
+
+You can set this variable in the projects' `.gitlab-ci.yml`, or
+in the GitLab UI at the project or group level. See the [GitLab CI/CD environment variables page](../../ci/variables/README.md#custom-environment-variables)
+for more information.
+
+#### Variables
+
+The following table shows which variables you can use with the `Secure-Binaries.gitlab-ci.yml`
+template:
+
+| VARIABLE | Description | Default value |
+|-------------------------------------------|-----------------------------------------------|-----------------------------------|
+| `SECURE_BINARIES_ANALYZERS` | Comma-separated list of analyzers to download | `"bandit, brakeman, gosec, and so on..."` |
+| `SECURE_BINARIES_DOWNLOAD_IMAGES` | Used to disable jobs | `"true"` |
+| `SECURE_BINARIES_PUSH_IMAGES` | Push files to the project registry | `"true"` |
+| `SECURE_BINARIES_SAVE_ARTIFACTS` | Also save image archives as artifacts | `"false"` |
+| `SECURE_BINARIES_ANALYZER_VERSION` | Default analyzer version (Docker tag) | `"2"` |
+
+### Alternate way without the official template
+
+If it's not possible to follow the above method, the images can be transferred manually instead:
+
+#### Example image packager script
+
+```shell
+#!/bin/bash
+set -ux
+
+# Specify needed analyzer images
+analyzers=${SAST_ANALYZERS:-"bandit eslint gosec"}
+gitlab=registry.gitlab.com/gitlab-org/security-products/analyzers/
+
+for i in "${analyzers[@]}"
+do
+ tarname="${i}_2.tar"
+ docker pull $gitlab$i:2
+ docker save $gitlab$i:2 -o ./analyzers/${tarname}
+ chmod +r ./analyzers/${tarname}
+done
+```
+
+#### Example image loader script
+
+This example loads the images from a bastion host to an offline host. In certain configurations,
+physical media may be needed for such a transfer:
+
+```shell
+#!/bin/bash
+set -ux
+
+# Specify needed analyzer images
+analyzers=${SAST_ANALYZERS:-"bandit eslint gosec"}
+registry=$GITLAB_HOST:4567
+
+for i in "${analyzers[@]}"
+do
+ tarname="${i}_2.tar"
+ scp ./analyzers/${tarname} ${GITLAB_HOST}:~/${tarname}
+ ssh $GITLAB_HOST "sudo docker load -i ${tarname}"
+ ssh $GITLAB_HOST "sudo docker tag $(sudo docker images | grep $i | awk '{print $3}') ${registry}/analyzers/${i}:2"
+ ssh $GITLAB_HOST "sudo docker push ${registry}/analyzers/${i}:2"
+done
+```
diff --git a/doc/topics/offline/quick_start_guide.md b/doc/topics/offline/quick_start_guide.md
new file mode 100644
index 00000000000..0abdd08ffcf
--- /dev/null
+++ b/doc/topics/offline/quick_start_guide.md
@@ -0,0 +1,157 @@
+# Getting started with an offline GitLab Installation
+
+This is a step-by-step guide that helps you install, configure, and use a self-managed GitLab
+instance entirely offline.
+
+## Installation
+
+NOTE: **Note:**
+This guide assumes the server is Ubuntu 18.04. Instructions for other servers may vary.
+
+NOTE: **Note:**
+This guide assumes the server host resolves as `my-host`, which you should replace with your
+server's name.
+
+Follow the installation instructions [as outlined in the omnibus install
+guide](https://about.gitlab.com/install/#ubuntu), but make sure to specify an `http`
+URL for the `EXTERNAL_URL` installation step. Once installed, we will manually
+configure the SSL ourselves.
+
+It is strongly recommended to setup a domain for IP resolution rather than bind
+to the server's IP address. This better ensures a stable target for our certs' CN
+and will make long-term resolution simpler.
+
+```shell
+sudo EXTERNAL_URL="http://my-host.internal" install gitlab-ee
+```
+
+## Enabling SSL
+
+Follow these steps to enable SSL for your fresh instance. Note that these steps reflect those for
+[manually configuring SSL in Omnibus's NGINX configuration](https://docs.gitlab.com/omnibus/settings/nginx.html#manually-configuring-https):
+
+1. Make the following changes to `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ # Update external_url from "http" to "https"
+ external_url "https://example.gitlab.com"
+
+ # Set Let's Encrypt to false
+ letsencrypt['enable'] = false
+ ```
+
+1. Create the following directories with the appropriate permissions for generating self-signed
+ certificates:
+
+ ```shell
+ sudo mkdir -p /etc/gitlab/ssl
+ sudo chmod 755 /etc/gitlab/ssl
+ sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/gitlab/ssl/my-host.internal.key -out /etc/gitlab/ssl/my-host.internal.crt
+ ```
+
+1. Reconfigure your instance to apply the changes:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+## Enabling the GitLab Container Registry
+
+Follow these steps to enable the container registry. Note that these steps reflect those for
+[configuring the container registry under an existing domain](../../administration/packages/container_registry.md#configure-container-registry-under-an-existing-gitlab-domain):
+
+1. Make the following changes to `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ # Change external_registry_url to match external_url, but append the port 4567
+ external_url "https://example.gitlab.com"
+ registry_external_url "https://example.gitlab.com:4567"
+ ```
+
+1. Reconfigure your instance to apply the changes:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+## Allow the Docker daemon to trust the registry and GitLab Runner
+
+Provide your Docker daemon with your certs by
+[following the steps for using trusted certificates with your registry](../../administration/packages/container_registry.md#using-self-signed-certificates-with-container-registry):
+
+```shell
+sudo mkdir -p /etc/docker/certs.d/my-host.internal:5000
+
+sudo cp /etc/gitlab/ssl/my-host.internal.crt /etc/docker/certs.d/my-host.internal:5000/ca.crt
+```
+
+Provide your GitLab Runner (to be installed next) with your certs by
+[following the steps for using trusted certificates with your Runner](https://docs.gitlab.com/runner/install/docker.html#installing-trusted-ssl-server-certificates):
+
+```shell
+sudo mkdir -p /etc/gitlab-runner/certs
+
+sudo cp /etc/gitlab/ssl/my-host.internal.crt /etc/gitlab-runner/certs/ca.crt
+```
+
+## Enabling GitLab Runner
+
+[Following a similar process to the steps for installing our GitLab Runner as a
+Docker service](https://docs.gitlab.com/runner/install/docker.html#docker-image-installation), we must first register our Runner:
+
+```shell
+$ sudo docker run --rm -it -v /etc/gitlab-runner:/etc/gitlab-runner gitlab/gitlab-runner register
+Updating CA certificates...
+Runtime platform arch=amd64 os=linux pid=7 revision=1b659122 version=12.8.0
+Running in system-mode.
+
+Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
+https://my-host.internal
+Please enter the gitlab-ci token for this runner:
+XXXXXXXXXXX
+Please enter the gitlab-ci description for this runner:
+[eb18856e13c0]:
+Please enter the gitlab-ci tags for this runner (comma separated):
+
+Registering runner... succeeded runner=FSMwkvLZ
+Please enter the executor: custom, docker, virtualbox, kubernetes, docker+machine, docker-ssh+machine, docker-ssh, parallels, shell, ssh:
+docker
+Please enter the default Docker image (e.g. ruby:2.6):
+ruby:2.6
+Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
+```
+
+Now we must add some additional configuration to our runner:
+
+Make the following changes to `/etc/gitlab-runner/config.toml`:
+
+- Add Docker socket to volumes `volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]`
+- Add `pull_policy = "if-not-present"` to the executor configuration
+
+Now we can start our Runner:
+
+```shell
+sudo docker run -d --restart always --name gitlab-runner -v /etc/gitlab-runner:/etc/gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock gitlab/gitlab-runner:latest
+90646b6587127906a4ee3f2e51454c6e1f10f26fc7a0b03d9928d8d0d5897b64
+```
+
+### Authenticating the registry against the host OS
+
+As noted in [Docker's registry authentication documentation](https://docs.docker.com/registry/insecure/#docker-still-complains-about-the-certificate-when-using-authentication),
+certain versions of Docker require trusting the certificate chain at the OS level.
+
+In the case of Ubuntu, this involves using `update-ca-certificates`:
+
+```shell
+sudo cp /etc/docker/certs.d/my-host.internal\:5000/ca.crt /usr/local/share/ca-certificates/my-host.internal.crt
+
+sudo update-ca-certificates
+```
+
+If all goes well, this is what you should see:
+
+```plaintext
+1 added, 0 removed; done.
+Running hooks in /etc/ca-certificates/update.d...
+done.
+```
diff --git a/doc/topics/web_application_firewall/index.md b/doc/topics/web_application_firewall/index.md
index 9f3289cd797..57043bf73b3 100644
--- a/doc/topics/web_application_firewall/index.md
+++ b/doc/topics/web_application_firewall/index.md
@@ -70,7 +70,7 @@ more advanced rules around threat detection.
## Features
-ModSecurity is enabled with the [OWASP Core Rule Set (CRS)](https://modsecurity.org/crs/) by
+ModSecurity is enabled with the [OWASP Core Rule Set (CRS)](https://github.com/coreruleset/coreruleset/) by
default. The OWASP CRS logs attempts to the following attacks:
- [SQL Injection](https://wiki.owasp.org/index.php/OWASP_Periodic_Table_of_Vulnerabilities_-_SQL_Injection)
@@ -87,7 +87,7 @@ It is good to have a basic knowledge of the following:
- [Kubernetes](https://kubernetes.io/docs/home/)
- [Ingress](https://kubernetes.github.io/ingress-nginx/)
- [ModSecurity](https://www.modsecurity.org/)
-- [OWASP Core Rule Set](https://modsecurity.org/crs/)
+- [OWASP Core Rule Set](https://github.com/coreruleset/coreruleset/)
## Roadmap
diff --git a/doc/topics/web_application_firewall/quick_start_guide.md b/doc/topics/web_application_firewall/quick_start_guide.md
index d55ab03a3f2..ec6702bb457 100644
--- a/doc/topics/web_application_firewall/quick_start_guide.md
+++ b/doc/topics/web_application_firewall/quick_start_guide.md
@@ -150,7 +150,7 @@ By now you should see the pipeline running, but what is it running exactly?
To navigate inside the pipeline, click its status badge (its status should be "Running").
The pipeline is split into a few stages, each running a couple of jobs.
-![Pipeline stages](../autodevops/img/guide_pipeline_stages_v12_3.png)
+![Pipeline stages](../autodevops/img/guide_pipeline_stages_v13_0.png)
In the **build** stage, the application is built into a Docker image and then
uploaded to your project's [Container Registry](../../user/packages/container_registry/index.md) ([Auto Build](../autodevops/stages.md#auto-build)).
@@ -254,5 +254,5 @@ You can explore them in more detail:
- [GitLab Defend Vision](https://about.gitlab.com/direction/defend/#waf)
- [ModSecurity](https://www.modsecurity.org/)
-- [OWASP Core Rule Set](https://modsecurity.org/crs/)
+- [OWASP Core Rule Set](https://github.com/coreruleset/coreruleset/)
- [AutoDevOps](../autodevops/index.md)
diff --git a/doc/university/README.md b/doc/university/README.md
index 84e3b84139b..df41167dbe9 100644
--- a/doc/university/README.md
+++ b/doc/university/README.md
@@ -11,7 +11,7 @@ If you're looking for a GitLab subscription for _your university_, see our [GitL
CAUTION: **Caution:**
Some of the content in GitLab University may be out of date and we plan to
-[evaluate](https://gitlab.com/gitlab-org/gitlab-foss/issues/41064) it.
+[evaluate](https://gitlab.com/gitlab-org/gitlab/-/issues/20403) it.
The GitLab University curriculum is composed of GitLab videos, screencasts, presentations, projects and external GitLab content hosted on other services and has been organized into the following sections:
@@ -76,7 +76,6 @@ The GitLab University curriculum is composed of GitLab videos, screencasts, pres
- Getting Technical Support
- Being part of our Great Community and Contributing to GitLab
1. [Getting Started with the GitLab Development Kit (GDK)](https://about.gitlab.com/blog/2016/06/08/getting-started-with-gitlab-development-kit/)
-1. [Contributing Technical Articles to the GitLab Blog](https://about.gitlab.com/blog/2016/01/26/call-for-writers/)
1. [GitLab Training Workshops](training/end-user/README.md)
1. [GitLab Professional Services](https://about.gitlab.com/services/)
@@ -176,7 +175,7 @@ The GitLab University curriculum is composed of GitLab videos, screencasts, pres
1. [Scalability and High Availability - Video](https://www.youtube.com/watch?v=cXRMJJb6sp4&list=PLFGfElNsQthbQu_IWlNOxul0TbS_2JH-e&index=2)
1. [High Availability - Video](https://www.youtube.com/watch?v=36KS808u6bE&index=15&list=PLFGfElNsQthbQu_IWlNOxul0TbS_2JH-e)
-1. [High Availability Documentation](https://about.gitlab.com/solutions/high-availability/)
+1. [High Availability Documentation](https://about.gitlab.com/solutions/reference-architectures/)
### 3.8 Cycle Analytics
@@ -204,7 +203,6 @@ The GitLab University curriculum is composed of GitLab videos, screencasts, pres
NOTE: **Note:**
Some content can only be accessed by GitLab team members.
-1. [Support Path](support/README.md)
1. [Sales Path](https://about.gitlab.com/handbook/sales/onboarding/)
1. [User Training](training/user_training.md)
1. [GitLab Flow Training](training/gitlab_flow.md)
diff --git a/doc/university/support/README.md b/doc/university/support/README.md
deleted file mode 100644
index 5e824bcb6f9..00000000000
--- a/doc/university/support/README.md
+++ /dev/null
@@ -1,202 +0,0 @@
----
-comments: false
-type: reference
----
-
-# Support Boot Camp
-
-**Goal:** Prepare new Service Engineers at GitLab
-
-For each stage, there are learning goals and content to support the learning of the engineer.
-The goal of this boot camp is to have every Service Engineer prepared to help our customers
-with whatever needs they might have and to also assist our awesome community with their
-questions.
-
-Always start with the [University Overview](../README.md) and then work
-your way here for more advanced and specific training. Once you feel comfortable
-with the topics of the current stage, move to the next.
-
-## Stage 1
-
-Follow the topics on the [University Overview](../README.md), concentrate on it
-during your first Stage, but also:
-
-- Perform the [first steps](https://about.gitlab.com/handbook/support/onboarding/#first-steps) of
- the on-boarding process for new Service Engineers
-
-### Goals
-
-Aim to have a good overview of the Product and main features, Git and the Company
-
-## Stage 2
-
-Continue to look over remaining portions of the [University Overview](../README.md) and continue on to these topics:
-
-### Set up your development machine
-
-Get your development machine ready to familiarize yourself with the codebase, the components, and to be prepared to reproduce issues that our users encounter
-
-- Install the [GDK](https://gitlab.com/gitlab-org/gitlab-development-kit)
- - [Set up OpenLDAP as part of this](https://gitlab.com/gitlab-org/gitlab-development-kit#openldap)
-
-### Become comfortable with the Installation processes that we support
-
-It's important to understand how to install GitLab in the same way that our users do. Try installing different versions and upgrading and downgrading between them. Installation from source will give you a greater understanding of the components that we employ and how everything fits together.
-
-Sometimes we need to upgrade customers from old versions of GitLab to latest, so it's good to get some experience of doing that now.
-
-- [Installation Methods](https://about.gitlab.com/install/):
- - [Omnibus](https://gitlab.com/gitlab-org/omnibus-gitlab/)
- - [Docker](https://gitlab.com/gitlab-org/gitlab-foss/tree/master/docker)
- - [Source](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/install/installation.md)
-- Get yourself a Digital Ocean droplet, where you can install and maintain your own instance of GitLab
- - Ask in #infrastructure about this
- - Populate with some test data
- - Keep this up-to-date as patch and version releases become available, just like our customers would
-- Try out the following installation path
- - [Install GitLab 4.2 from source](https://gitlab.com/gitlab-org/gitlab-foss/blob/d67117b5a185cfb15a1d7e749588ff981ffbf779/doc/install/installation.md)
- - External MySQL database
- - External NGINX
- - Create some test data
- - Populated Repos
- - Users
- - Groups
- - Projects
- - [Back up using our backup Rake task](../../raketasks/backup_restore.md#back-up-gitlab)
- - [Upgrade to 5.0 source using our Upgrade documentation](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/update/4.2-to-5.0.md)
- - [Upgrade to 5.1 source](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/update/5.0-to-5.1.md)
- - [Upgrade to 6.0 source](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/update/5.1-to-6.0.md)
- - [Upgrade to 7.14 source](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/update/6.x-or-7.x-to-7.14.md)
- - [Perform the MySQL to PostgreSQL migration to convert your backup](../../update/mysql_to_postgresql.md)
- - [Upgrade to Omnibus 7.14](https://docs.gitlab.com/omnibus/update/README.html#upgrading-from-a-non-omnibus-installation-to-an-omnibus-installation)
- - [Restore backup using our Restore Rake task](../../raketasks/backup_restore.md#restore-gitlab)
- - [Upgrade to latest EE](https://about.gitlab.com/update/)
- - (GitLab inc. only) Acquire and apply a license for the Enterprise Edition product, ask in #support
-- Perform a downgrade from [EE to CE](../../downgrade_ee_to_ce/README.md)
-
-### Start to learn about some of the integrations that we support
-
-Our integrations add great value to GitLab. User questions often relate to integrating GitLab with existing external services and the configuration involved
-
-- Learn about our Integrations (specially, not only):
- - [LDAP](../../integration/ldap.md)
- - [Jira](../../project_services/jira.md)
- - [Jenkins](../../integration/jenkins.md)
- - [SAML](../../integration/saml.md)
-
-### Goals
-
-- Aim to be comfortable with installation of the GitLab product and configuration of some of the major integrations
-- Aim to have an installation available for reproducing customer reports
-
-## Stage 3
-
-### Understand the gathering of diagnostics for GitLab instances
-
-- Learn about the GitLab checks that are available:
- - [Environment Information and maintenance checks](../../raketasks/maintenance.md)
- - [GitLab check](../../raketasks/check.md)
- - Omnibus commands
- - [Status](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/maintenance/README.md#get-service-status)
- - [Starting and stopping services](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/maintenance/README.md#starting-and-stopping)
- - [Starting a rails console](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/maintenance/README.md#invoking-rake-tasks)
-
-### Learn about the Support process
-
-Zendesk is our Support Center and our main communication line with our Customers. We communicate with customers through several other channels too
-
-- Familiarize yourself with ZenDesk:
- - [UI Overview](https://support.zendesk.com/hc/en-us/articles/203661806-Introduction-to-the-Zendesk-agent-interface)
- - [Updating Tickets](https://support.zendesk.com/hc/en-us/articles/212530318-Updating-and-solving-tickets)
- - [Working w/ Tickets](https://support.zendesk.com/hc/en-us/articles/203690856-Working-with-tickets) *Read: avoiding agent collision.*
-- Dive into our ZenDesk support process by reading how to [handle tickets](https://about.gitlab.com/handbook/support/onboarding/#handling-tickets)
-- Start getting real world experience by handling real tickets, all the while gaining further experience with the Product.
- - First, learn about our [Support Channels](https://about.gitlab.com/handbook/support/#support-channels)
- - Ask other Service Engineers for help, when necessary, and to review your responses
- - Start with [StackOverflow](https://about.gitlab.com/handbook/support/#stack-overflowa-namestack-overflowa) and the [GitLab forum](https://about.gitlab.com/handbook/support/#foruma-namegitlab-foruma)
- - Here you will find a large variety of queries mainly from our Users who are self hosting GitLab CE
- - Understand the questions that are asked and dig in to try to find a solution
- - [Proceed on to the GitLab.com Support Forum](https://about.gitlab.com/handbook/support/#gitlabcom-support-trackera-namesupp-foruma)
- - Here you will find queries regarding our own GitLab.com
- - Helping Users here will give you an understanding of our Admin interface and other tools
- - [Proceed on to the Twitter tickets in Zendesk](https://about.gitlab.com/handbook/support/#twitter)
- - Here you will gain a great insight into our userbase
- - Learn from any complaints and problems and feed them back to the team
- - Tweets can range from help needed with GitLab installations, the API and just general queries
- - [Proceed on to Regular email Support tickets](https://about.gitlab.com/handbook/support/#regular-zendesk-tickets-a-nameregulara)
- - Here you will find tickets from our GitLab EE Customers and GitLab CE Users
- - Tickets here are extremely varied and often very technical
- - You should be prepared for these tickets, given the knowledge gained from previous tiers and your training
-- Check out your colleagues' responses
- - Hop on to the #support-live-feed channel in Slack and see the tickets as they come in and are updated
- - Read through old tickets that your colleagues have worked on
-- Start arranging to pair on calls with other Service Engineers. Aim to cover a few of each type of call
- - [Learn about Cisco WebEx](https://about.gitlab.com/handbook/support/onboarding/#webexa-namewebexa)
- - Training calls
- - Information gathering calls
- - It's good to find out how new and prospective customers are going to be using the product and how they will set up their infrastructure
- - Diagnosis calls
- - When email isn't enough we may need to hop on a call and do some debugging along side the customer
- - These paired calls are a great learning experience
- - Upgrade calls
- - Emergency calls
-
-### Learn about the Escalation process for tickets
-
-Some tickets need specific knowledge or a deep understanding of a particular component and will need to be escalated to a Senior Service Engineer or Developer
-
-- Read about [Escalation](https://about.gitlab.com/handbook/support/workflows/issue_escalations.html)
-- Find the macros in Zendesk for ticket escalations
-- Take a look at the [GitLab.com Team page](https://about.gitlab.com/company/team/) to find the resident experts in their fields
-
-### Learn about raising issues and fielding feature proposals
-
-- Understand what's in the pipeline and proposed features at GitLab: [Direction Page](https://about.gitlab.com/direction/)
-- Practice searching issues and filtering using [labels](https://gitlab.com/gitlab-org/gitlab/-/labels) to find existing feature proposals and bugs
-- If raising a new issue always provide a relevant label and a link to the relevant ticket in Zendesk
-- Add [customer labels](https://gitlab.com/gitlab-org/gitlab-foss/issues?label_name%5B%5D=customer) for those issues relevant to our subscribers
-- Take a look at the [existing issue templates](https://gitlab.com/gitlab-org/gitlab/blob/master/CONTRIBUTING.md#issue-tracker) to see what is expected
-- Raise issues for bugs in a manner that would make the issue easily reproducible. A Developer or a contributor may work on your issue
-
-### Goals
-
-- Aim to have a good understanding of the problems that customers are facing
-- Aim to have gained experience in scheduling and participating in calls with customers
-- Aim to have a good understanding of ticket flow through Zendesk and how to interact with our various channels
-
-## Stage 4
-
-### Advanced GitLab topics
-
-Move on to understanding some of GitLab's more advanced features. You can make use of GitLab.com to understand the features from an end-user perspective and then use your own instance to understand setup and configuration of the feature from an Administrative perspective
-
-- Set up and try [Git LFS](../../topics/git/lfs/index.md)
-- Get to know the [GitLab API](../../api/README.md), its capabilities and shortcomings
-- Learn how to [migrate from SVN to Git](../../user/project/import/svn.md)
-- Set up [GitLab CI/CD](../../ci/quick_start/README.md)
-- Create your first [GitLab Page](../../administration/pages/index.md)
-- Get to know the GitLab Codebase by reading through the source code:
- - Find the differences between the [EE codebase](https://gitlab.com/gitlab-org/gitlab-foss)
- and the [CE codebase](https://gitlab.com/gitlab-org/gitlab-foss)
-- Ask as many questions as you can think of on the `#support` chat channel
-
-### Get initiated for on-call duty
-
-- Read over the [public run-books to understand common tasks](https://gitlab.com/gitlab-com/runbooks)
-- Create an issue on the internal Organization tracker to schedule time with the DevOps / Production team, so that you learn how to handle GitLab.com going down. Once you are trained for this, you are ready to be added to the on-call rotation.
-
-### Goals
-
-- Aim to become a fully-fledged Service Engineer!
-
-<!-- ## 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/university/training/user_training.md b/doc/university/training/user_training.md
index 663ae0126c9..d2def1f3199 100644
--- a/doc/university/training/user_training.md
+++ b/doc/university/training/user_training.md
@@ -222,7 +222,7 @@ See GitLab merge requests for examples: <https://gitlab.com/gitlab-org/gitlab-fo
- Dashboard
- User Preferences
-- ReadMe, Changelog, License shortcuts
+- README, Changelog, License shortcuts
- Issues
- Milestones and Labels
- Manage project members
@@ -314,7 +314,7 @@ Squash the commits on the same branch we used for the merge conflicts step.
git rebase -i master
```
-In the editor, leave the first commit as 'pick' and set others to 'fixup'.
+In the editor, leave the first commit as `pick` and set others to `fixup`.
## Questions?
diff --git a/doc/update/README.md b/doc/update/README.md
index 8056460ceaa..f36a304495c 100644
--- a/doc/update/README.md
+++ b/doc/update/README.md
@@ -22,7 +22,7 @@ Based on your installation, choose a section below that fits your needs.
source](upgrading_from_source.md) - The guidelines for upgrading Community
Edition and Enterprise Edition from source.
- [Patch versions](patch_versions.md) guide includes the steps needed for a
- patch version, eg. 6.2.0 to 6.2.1, and apply to both Community and Enterprise
+ patch version, such as 6.2.0 to 6.2.1, and apply to both Community and Enterprise
Editions.
In the past we used separate documents for the upgrading instructions, but we
@@ -178,7 +178,7 @@ If you wish to upgrade your GitLab installation from Community to Enterprise
Edition, follow the guides below based on the installation method:
- [Source CE to EE update guides](upgrading_from_ce_to_ee.md) - The steps are very similar
- to a version upgrade: stop the server, get the code, update config files for
+ 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#updating-community-edition-to-enterprise-edition) - Follow this guide to update your Omnibus
@@ -192,6 +192,16 @@ possible.
## Version specific upgrading instructions
+### 13.1.0
+
+In 13.1.0, you must upgrade to either:
+
+- At least Git v2.24 (previously, the minimum required version was Git v2.22).
+- The recommended Git v2.26.
+
+Failure to do so will result in internal errors in the Gitaly service in some RPCs due
+to the use of the new `--end-of-options` Git flag.
+
### 12.2.0
In 12.2.0, we enabled Rails' authenticated cookie encryption. Old sessions are
diff --git a/doc/update/patch_versions.md b/doc/update/patch_versions.md
index f226ad9ac28..0092df7b89d 100644
--- a/doc/update/patch_versions.md
+++ b/doc/update/patch_versions.md
@@ -7,7 +7,7 @@ comments: false
## Select Version to Install
Make sure you view [this update guide](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/update/patch_versions.md) from the tag (version) of GitLab you would like to install.
-In most cases this should be the highest numbered production tag (without rc in it).
+In most cases this should be the highest numbered production tag (without `rc` in it).
You can select the tag in the version dropdown in the top left corner of GitLab (below the menu bar).
### 0. Backup
@@ -35,7 +35,7 @@ sudo -u git -H git checkout -- Gemfile.lock db/structure.sql locale
sudo -u git -H git checkout LATEST_TAG -b LATEST_TAG
```
-### 3. Install libs, migrations, etc
+### 3. Install libraries, migrations, etc
```shell
cd /home/git/gitlab
@@ -49,10 +49,9 @@ sudo -u git -H bundle clean
sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
# Compile GetText PO files
-# Internationalization was added in `v9.2.0` so these commands are only
+# Internationalization was added in `v9.2.0` so this command is only
# required for versions equal or major to it.
-sudo -u git -H bundle exec rake gettext:pack RAILS_ENV=production
-sudo -u git -H bundle exec rake gettext:po_to_json RAILS_ENV=production
+sudo -u git -H bundle exec rake gettext:compile RAILS_ENV=production
# Clean up assets and cache
sudo -u git -H bundle exec rake yarn:install gitlab:assets:clean gitlab:assets:compile cache:clear RAILS_ENV=production NODE_ENV=production NODE_OPTIONS="--max_old_space_size=4096"
diff --git a/doc/update/upgrading_from_ce_to_ee.md b/doc/update/upgrading_from_ce_to_ee.md
index 2415d3b2741..78227f18457 100644
--- a/doc/update/upgrading_from_ce_to_ee.md
+++ b/doc/update/upgrading_from_ce_to_ee.md
@@ -54,7 +54,7 @@ sudo -u git -H git remote add -f ee https://gitlab.com/gitlab-org/gitlab.git
sudo -u git -H git checkout EE_BRANCH
```
-### 3. Install libs, migrations, etc
+### 3. Install libraries, migrations, etc
```shell
cd /home/git/gitlab
diff --git a/doc/update/upgrading_from_source.md b/doc/update/upgrading_from_source.md
index 76a0d5bde98..af461b93910 100644
--- a/doc/update/upgrading_from_source.md
+++ b/doc/update/upgrading_from_source.md
@@ -12,7 +12,7 @@ Make sure you view this update guide from the branch (version) of GitLab you
would like to install (e.g., `11.8`. You can select the version in the version
dropdown at the top left corner of GitLab (below the menu bar).
-In all examples, replace `BRANCH` with the branch for the version you uprading
+In all examples, replace `BRANCH` with the branch for the version you upgrading
to (e.g. `11-8-stable` for `11.8`), and replace `PREVIOUS_BRANCH` with the
branch for the version you are upgrading from (e.g. `11-7-stable` for `11.7`).
@@ -67,9 +67,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.6/ruby-2.6.5.tar.gz
-echo '1416ce288fb8bfeae07a12b608540318c9cace71 ruby-2.6.5.tar.gz' | shasum -c - && tar xzf ruby-2.6.5.tar.gz
-cd ruby-2.6.5
+curl --remote-name --progress https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.6.tar.gz
+echo '2d78048e293817f38d4ede4ebc7873013e97bb0b ruby-2.6.6.tar.gz' | shasum -c - && tar xzf ruby-2.6.6.tar.gz
+cd ruby-2.6.6
./configure --disable-install-rdoc
make
@@ -122,12 +122,17 @@ rm go1.13.5.linux-amd64.tar.gz
### 6. Update Git
-NOTE: To check the minimum required Git version, see [Git versions](../install/requirements.md#git-versions).
+CAUTION: **Caution:**
+From GitLab 13.1, you must use at least Git v2.24 (previous minimum version was v2.22).
+Git v2.26 is recommended.
+
+To check you are running the minimum required Git version, see
+[Git versions](../install/requirements.md#git-versions).
In Debian or Ubuntu:
```shell
-# Make sure Git is version 2.21.0 or higher
+# Make sure Git is version 2.24.0 or higher
git --version
# Remove packaged Git
@@ -147,9 +152,9 @@ make install
# Download and compile from source
cd /tmp
-curl --remote-name --location --progress https://www.kernel.org/pub/software/scm/git/git-2.21.0.tar.gz
-echo '85eca51c7404da75e353eba587f87fea9481ba41e162206a6f70ad8118147bee git-2.21.0.tar.gz' | shasum -a256 -c - && tar -xzf git-2.21.0.tar.gz
-cd git-2.21.0/
+curl --remote-name --location --progress https://www.kernel.org/pub/software/scm/git/git-2.26.0.tar.gz
+echo 'aa168c2318e7187cd295a645f7370cc6d71a324aafc932f80f00c780b6a26bed git-2.26.0.tar.gz' | shasum -a256 -c - && tar -xzf git-2.26.0.tar.gz
+cd git-2.26.0/
./configure --with-libpcre
make prefix=/usr/local all
@@ -285,7 +290,7 @@ add the following line to `config/initializers/smtp_settings.rb`:
ActionMailer::Base.delivery_method = :smtp
```
-See [smtp_settings.rb.sample](https://gitlab.com/gitlab-org/gitlab/blob/master/config/initializers/smtp_settings.rb.sample#L13) as an example.
+See [`smtp_settings.rb.sample`](https://gitlab.com/gitlab-org/gitlab/blob/master/config/initializers/smtp_settings.rb.sample#L13) as an example.
#### Init script
@@ -313,7 +318,7 @@ For Ubuntu 16.04.1 LTS:
sudo systemctl daemon-reload
```
-### 13. Install libs, migrations, etc
+### 13. Install libraries, migrations, etc
```shell
cd /home/git/gitlab
@@ -378,6 +383,18 @@ Example:
Additional instructions here.
-->
+### 13.0.1
+
+As part of [deprecating Rack Attack throttles on Omnibus GitLab](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/4750), Rack Attack initializer on GitLab
+was renamed from [`config/initializers/rack_attack_new.rb` to `config/initializers/rack_attack.rb`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33072).
+If this file exists on your installation, consider creating a backup before updating:
+
+```shell
+cd /home/git/gitlab
+
+cp config/initializers/rack_attack.rb config/initializers/rack_attack_backup.rb
+```
+
## Troubleshooting
### 1. Revert the code to the previous version
diff --git a/doc/update/upgrading_postgresql_using_slony.md b/doc/update/upgrading_postgresql_using_slony.md
index fdd035c7940..5133e4cf4e5 100644
--- a/doc/update/upgrading_postgresql_using_slony.md
+++ b/doc/update/upgrading_postgresql_using_slony.md
@@ -56,7 +56,7 @@ server.
## Installing Slony
-Slony will be used to upgrade the database without requiring long downtimes.
+Slony will be used to upgrade the database without requiring a long downtime.
Slony can be downloaded from <https://www.slony.info/>. If you have installed
PostgreSQL using your operating system's package manager you may also be able to
install Slony using said package manager.
@@ -88,7 +88,7 @@ test -f /opt/gitlab/embedded/bin/slonik_init_cluster && echo 'Slony Perl tools a
```
This assumes Slony was installed to `/opt/gitlab/embedded`. If Slony was
-installed properly the output of these commands will be (the mentioned "slonik"
+installed properly the output of these commands will be (the mentioned `slonik`
version may be different):
```plaintext
diff --git a/doc/user/admin_area/abuse_reports.md b/doc/user/admin_area/abuse_reports.md
index 77f4a84cf6f..783aadc0974 100644
--- a/doc/user/admin_area/abuse_reports.md
+++ b/doc/user/admin_area/abuse_reports.md
@@ -1,4 +1,7 @@
---
+stage: Manage
+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
type: reference, howto
---
diff --git a/doc/user/admin_area/activating_deactivating_users.md b/doc/user/admin_area/activating_deactivating_users.md
index 7c8ab18ccef..06a26737495 100644
--- a/doc/user/admin_area/activating_deactivating_users.md
+++ b/doc/user/admin_area/activating_deactivating_users.md
@@ -1,4 +1,7 @@
---
+stage: Manage
+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
type: howto
---
@@ -8,7 +11,7 @@ GitLab administrators can deactivate and activate users.
## Deactivating a user
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/22257) in GitLab 12.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22257) in GitLab 12.4.
In order to temporarily prevent access by a GitLab user that has no recent activity, administrators
can choose to deactivate the user.
@@ -45,7 +48,7 @@ A deactivated user does not consume a [seat](../../subscriptions/index.md#choosi
## Activating a user
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/22257) in GitLab 12.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22257) in GitLab 12.4.
A deactivated user can be activated from the Admin Area.
@@ -63,4 +66,4 @@ Activating a user will change the user's state to active and it consumes a
[seat](../../subscriptions/index.md#choosing-the-number-of-users).
TIP: **Tip:**
-A deactivated user can also activate their account by themselves by simply logging back via the UI.
+A deactivated user can also activate their account themselves by simply logging back in via the UI.
diff --git a/doc/user/admin_area/appearance.md b/doc/user/admin_area/appearance.md
index 80440b63f71..55dabce7342 100644
--- a/doc/user/admin_area/appearance.md
+++ b/doc/user/admin_area/appearance.md
@@ -15,7 +15,7 @@ By default, the navigation bar has the GitLab logo, but this can be customized w
any image desired. It is optimized for images 28px high (any width), but any image can be
used (less than 1MB) and it will automatically be resized.
-![navbar header logo screenshot](img/appearance_header_logo_v12_3.png)
+![Navigation bar header logo screenshot](img/appearance_header_logo_v12_3.png)
Once you select and upload an image, click **Update appearance settings** at the bottom
of the page to activate it in the GitLab instance.
@@ -38,8 +38,8 @@ of the page to activate it in the GitLab instance.
## System header and footer messages
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/5023) in [GitLab Premium](https://about.gitlab.com/pricing/) 10.7.
-> - [Added](https://gitlab.com/gitlab-org/gitlab-foss/issues/55057) to [GitLab Core](https://about.gitlab.com/pricing/) in 11.9.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5023) in [GitLab Premium](https://about.gitlab.com/pricing/) 10.7.
+> - [Added](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/55057) to [GitLab Core](https://about.gitlab.com/pricing/) in 11.9.
You can add a small header message, a small footer message, or both, to the interface
of your GitLab instance. These messages will appear on all projects and pages of the
diff --git a/doc/user/admin_area/blocking_unblocking_users.md b/doc/user/admin_area/blocking_unblocking_users.md
index e3b9cd1218c..2f98709a089 100644
--- a/doc/user/admin_area/blocking_unblocking_users.md
+++ b/doc/user/admin_area/blocking_unblocking_users.md
@@ -1,4 +1,7 @@
---
+stage: Manage
+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
type: howto
---
diff --git a/doc/user/admin_area/broadcast_messages.md b/doc/user/admin_area/broadcast_messages.md
index 5427b0c5200..7e1a4faee75 100644
--- a/doc/user/admin_area/broadcast_messages.md
+++ b/doc/user/admin_area/broadcast_messages.md
@@ -24,7 +24,7 @@ Banners are shown on the top of a page and in Git remote responses.
![Broadcast Message Banner](img/broadcast_messages_banner_v12_10.png)
-```bash
+```shell
$ git push
...
remote:
diff --git a/doc/user/admin_area/credentials_inventory.md b/doc/user/admin_area/credentials_inventory.md
index 79e9cbc5b14..5eecfbb73c6 100644
--- a/doc/user/admin_area/credentials_inventory.md
+++ b/doc/user/admin_area/credentials_inventory.md
@@ -1,3 +1,10 @@
+---
+stage: Manage
+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
+type: howto
+---
+
# Credentials inventory **(ULTIMATE ONLY)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20912) in GitLab 12.6.
diff --git a/doc/user/admin_area/custom_project_templates.md b/doc/user/admin_area/custom_project_templates.md
index f9a4dad2500..d194ca42215 100644
--- a/doc/user/admin_area/custom_project_templates.md
+++ b/doc/user/admin_area/custom_project_templates.md
@@ -1,10 +1,13 @@
---
+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/#designated-technical-writers
type: reference
---
# Custom instance-level project templates **(PREMIUM ONLY)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/6860) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.2.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/6860) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.2.
GitLab administrators can configure the group where all the custom project
templates are sourced.
diff --git a/doc/user/admin_area/diff_limits.md b/doc/user/admin_area/diff_limits.md
index bc6f93891df..b9bd94e65be 100644
--- a/doc/user/admin_area/diff_limits.md
+++ b/doc/user/admin_area/diff_limits.md
@@ -1,4 +1,7 @@
---
+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/#designated-technical-writers
type: reference
---
diff --git a/doc/user/admin_area/geo_nodes.md b/doc/user/admin_area/geo_nodes.md
index bb4ca8ca618..d17e0f7430c 100644
--- a/doc/user/admin_area/geo_nodes.md
+++ b/doc/user/admin_area/geo_nodes.md
@@ -1,4 +1,7 @@
---
+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/#designated-technical-writers
type: howto
---
diff --git a/doc/user/admin_area/labels.md b/doc/user/admin_area/labels.md
index 1d15be89bd5..3c35276b843 100644
--- a/doc/user/admin_area/labels.md
+++ b/doc/user/admin_area/labels.md
@@ -1,4 +1,7 @@
---
+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/#designated-technical-writers
type: reference
---
diff --git a/doc/user/admin_area/license.md b/doc/user/admin_area/license.md
index 59b71b05b16..1ffaf4e0678 100644
--- a/doc/user/admin_area/license.md
+++ b/doc/user/admin_area/license.md
@@ -1,4 +1,7 @@
---
+stage: Growth
+group: Conversion
+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: howto
---
@@ -64,12 +67,12 @@ export GITLAB_LICENSE_FILE="/path/to/license/file"
Omnibus installations should add this entry to `gitlab.rb`:
```ruby
-gitlab_rails['license_file'] = "/path/to/license/file"
+gitlab_rails['initial_license_file'] = "/path/to/license/file"
```
CAUTION: **Caution:**
These methods will only add a license at the time of installation. Use the
-Admin Area in the web ui to renew or upgrade licenses.
+Admin Area in the web user interface to renew or upgrade licenses.
---
diff --git a/doc/user/admin_area/merge_requests_approvals.md b/doc/user/admin_area/merge_requests_approvals.md
index 0c7beadad48..153ccfc128a 100644
--- a/doc/user/admin_area/merge_requests_approvals.md
+++ b/doc/user/admin_area/merge_requests_approvals.md
@@ -1,10 +1,13 @@
---
+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/#designated-technical-writers
type: reference, concepts
---
# Instance-level merge request approval rules **(PREMIUM ONLY)**
-> Introduced in [GitLab Premium](https://gitlab.com/gitlab-org/gitlab/issues/39060) 12.8.
+> Introduced in [GitLab Premium](https://gitlab.com/gitlab-org/gitlab/-/issues/39060) 12.8.
Merge request approvals rules prevent users overriding certain settings on a project
level. When configured, only administrators can change these settings on a project level
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 83b29597bec..b4fb7a524da 100644
--- a/doc/user/admin_area/settings/account_and_limit_settings.md
+++ b/doc/user/admin_area/settings/account_and_limit_settings.md
@@ -15,6 +15,17 @@ If you choose a size larger than what is currently configured for the web server
you will likely get errors. See the [troubleshooting section](#troubleshooting) for more
details.
+## Max import size
+
+You can change the maximum file size for imports in GitLab.
+Navigate to **Admin Area (wrench icon) > Settings > General**, then expand **Account and Limit**.
+From here, you can increase or decrease by changing the value in `Maximum import size (MB)`.
+
+NOTE: **Note:**
+If you choose a size larger than what is currently configured for the web server,
+you will likely get errors. See the [troubleshooting section](#troubleshooting) for more
+details.
+
## Maximum namespace storage size
This sets a maximum size limit on each namespace. The following are included in the namespace size:
@@ -99,7 +110,7 @@ nginx['client_max_body_size'] = "200m"
## Limiting lifetime of personal access tokens **(ULTIMATE ONLY)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/3649) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3649) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.6.
Users can optionally specify an expiration date for
[personal access tokens](../../profile/personal_access_tokens.md).
@@ -131,7 +142,7 @@ Once a lifetime for personal access tokens is set, GitLab will:
## Disabling user profile name changes **(PREMIUM ONLY)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/24605) in GitLab 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/24605) in GitLab 12.7.
To maintain integrity of user details in [Audit Events](../../../administration/audit_events.md), GitLab administrators can choose to disable a user's ability to change their profile name.
diff --git a/doc/user/admin_area/settings/continuous_integration.md b/doc/user/admin_area/settings/continuous_integration.md
index 4a401210928..3a287f29a0a 100644
--- a/doc/user/admin_area/settings/continuous_integration.md
+++ b/doc/user/admin_area/settings/continuous_integration.md
@@ -1,4 +1,7 @@
---
+stage: Verify
+group: Continuous Integration
+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
---
@@ -32,7 +35,7 @@ The maximum size of the [job artifacts](../../../administration/job_artifacts.md
can be set at:
- The instance level.
-- [From GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/issues/21688), the project and group level.
+- [From GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/-/issues/21688), the project and group level.
The value is:
@@ -169,7 +172,7 @@ but commented out to help encourage others to add to it in the future. -->
CAUTION: **Caution:**
This feature is being re-evaluated in favor of a different
-[compliance solution](https://gitlab.com/gitlab-org/gitlab/issues/34830).
+[compliance solution](https://gitlab.com/gitlab-org/gitlab/-/issues/34830).
We recommend that users who haven't yet implemented this feature wait for
the new solution.
diff --git a/doc/user/admin_area/settings/email.md b/doc/user/admin_area/settings/email.md
index a99897657ae..d956364b3ea 100644
--- a/doc/user/admin_area/settings/email.md
+++ b/doc/user/admin_area/settings/email.md
@@ -1,7 +1,11 @@
---
type: reference
+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/#designated-technical-writers
---
+
# Email **(CORE ONLY)**
You can customize some of the content in emails sent from your GitLab instance.
diff --git a/doc/user/admin_area/settings/external_authorization.md b/doc/user/admin_area/settings/external_authorization.md
index 3a03e46fa1f..c5c5f08aea1 100644
--- a/doc/user/admin_area/settings/external_authorization.md
+++ b/doc/user/admin_area/settings/external_authorization.md
@@ -4,7 +4,7 @@ type: reference
# External authorization control **(CORE ONLY)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/4216) in [GitLab Premium](https://about.gitlab.com/pricing/) 10.6.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4216) in [GitLab Premium](https://about.gitlab.com/pricing/) 10.6.
> - [Moved](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/27056) to [GitLab Core](https://about.gitlab.com/pricing/) in 11.10.
In highly controlled environments, it may be necessary for access policy to be
@@ -31,7 +31,7 @@ functionality that render cross-project data. That includes:
This is to prevent performing to many requests at once to the external
authorization service.
-Whenever access is granted or denied this is logged in a logfile called
+Whenever access is granted or denied this is logged in a log file called
`external-policy-access-control.log`.
Read more about logs GitLab keeps in the [omnibus documentation](https://docs.gitlab.com/omnibus/settings/logs.html).
@@ -60,7 +60,7 @@ The available required properties are:
requesting authorization if no specific label is defined on the project
When using TLS Authentication with a self signed certificate, the CA certificate
-needs to be trusted by the openssl installation. When using GitLab installed using
+needs to be trusted by the OpenSSL installation. When using GitLab installed using
Omnibus, learn to install a custom CA in the
[omnibus documentation](https://docs.gitlab.com/omnibus/settings/ssl.html). Alternatively learn where to install
custom certificates using `openssl version -d`.
diff --git a/doc/user/admin_area/settings/gitaly_timeouts.md b/doc/user/admin_area/settings/gitaly_timeouts.md
index 775a99d7574..68f359368f0 100644
--- a/doc/user/admin_area/settings/gitaly_timeouts.md
+++ b/doc/user/admin_area/settings/gitaly_timeouts.md
@@ -4,7 +4,7 @@ type: reference
# Gitaly timeouts
-![gitaly timeouts](img/gitaly_timeouts.png)
+![Gitaly timeouts](img/gitaly_timeouts.png)
3 timeout types can be configured to make sure that long running
Gitaly calls don't needlessly take up resources.
diff --git a/doc/user/admin_area/settings/img/rate_limit_on_issues_creation.png b/doc/user/admin_area/settings/img/rate_limit_on_issues_creation.png
deleted file mode 100644
index 5aa9b95f835..00000000000
--- a/doc/user/admin_area/settings/img/rate_limit_on_issues_creation.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/admin_area/settings/img/rate_limit_on_issues_creation_v13_1.png b/doc/user/admin_area/settings/img/rate_limit_on_issues_creation_v13_1.png
new file mode 100644
index 00000000000..9edc916c7fb
--- /dev/null
+++ b/doc/user/admin_area/settings/img/rate_limit_on_issues_creation_v13_1.png
Binary files differ
diff --git a/doc/user/admin_area/settings/index.md b/doc/user/admin_area/settings/index.md
index 761d640c535..df087722fcf 100644
--- a/doc/user/admin_area/settings/index.md
+++ b/doc/user/admin_area/settings/index.md
@@ -32,7 +32,7 @@ Access the default page for admin area settings by navigating to
| Option | Description |
| ------ | ----------- |
| [Elasticsearch](../../../integration/elasticsearch.md#enabling-elasticsearch) | Elasticsearch integration. Elasticsearch AWS IAM. |
-| [PlantUML](../../../administration/integration/plantuml.md#gitlab) | Allow rendering of PlantUML diagrams in Asciidoc documents. |
+| [PlantUML](../../../administration/integration/plantuml.md#gitlab) | Allow rendering of PlantUML diagrams in AsciiDoc documents. |
| [Slack application](../../../user/project/integrations/gitlab_slack_application.md#configuration) **(FREE ONLY)** | 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. |
| [Snowplow](../../../development/telemetry/snowplow.md) | Configure the Snowplow integration. |
diff --git a/doc/user/admin_area/settings/instance_template_repository.md b/doc/user/admin_area/settings/instance_template_repository.md
index bef4e31259f..ae56c67f0ab 100644
--- a/doc/user/admin_area/settings/instance_template_repository.md
+++ b/doc/user/admin_area/settings/instance_template_repository.md
@@ -4,7 +4,7 @@ type: reference
# Instance template repository **(PREMIUM ONLY)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/5986) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5986) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.3.
## Overview
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 9850de0f4b3..bbc5ed04202 100644
--- a/doc/user/admin_area/settings/push_event_activities_limit.md
+++ b/doc/user/admin_area/settings/push_event_activities_limit.md
@@ -4,7 +4,7 @@ type: reference
# Push event activities limit and bulk push events
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/31007) in GitLab 12.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/31007) in GitLab 12.4.
This allows you to set the number of changes (branches or tags) in a single push
to determine whether individual push events or bulk push event will be created.
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 dc23865e730..bae60aba15f 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
@@ -1,5 +1,8 @@
---
type: reference
+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/#designated-technical-writers
---
# Rate limits on issue creation
@@ -14,7 +17,7 @@ For example, requests using the
[Projects::IssuesController#create](https://gitlab.com/gitlab-org/gitlab/raw/master/app/controllers/projects/issues_controller.rb)
action exceeding a rate of 300 per minute are blocked. Access to the endpoint is allowed after one minute.
-![Rate limits on issues creation](img/rate_limit_on_issues_creation.png)
+![Rate limits on issues creation](img/rate_limit_on_issues_creation_v13_1.png)
This limit is:
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 95748f68a55..d9ca4a0881a 100644
--- a/doc/user/admin_area/settings/visibility_and_access_controls.md
+++ b/doc/user/admin_area/settings/visibility_and_access_controls.md
@@ -66,7 +66,7 @@ To ensure only admin users can delete projects:
## Default deletion adjourned period **(PREMIUM ONLY)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/32935) in GitLab 12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32935) in GitLab 12.6.
By default, a project or group marked for removal will be permanently removed after 7 days.
This period may be changed, and setting this period to 0 will enable immediate removal
diff --git a/doc/user/analytics/code_review_analytics.md b/doc/user/analytics/code_review_analytics.md
index e0aa01c29b2..8c4c54153bb 100644
--- a/doc/user/analytics/code_review_analytics.md
+++ b/doc/user/analytics/code_review_analytics.md
@@ -2,14 +2,13 @@
description: "Learn how long your open merge requests have spent in code review, and what distinguishes the longest-running." # Up to ~200 chars long. They will be displayed in Google Search snippets. It may help to write the page intro first, and then reuse it here.
stage: Manage
group: Analytics
-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
+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
---
# Code Review Analytics **(STARTER)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/38062) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/38062) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.7.
Code Review Analytics makes it easy to view the longest-running reviews among open merge requests,
enabling you to take action on individual merge requests and reduce overall cycle time.
diff --git a/doc/user/analytics/img/vsa_time_metrics_v13_0.png b/doc/user/analytics/img/vsa_time_metrics_v13_0.png
new file mode 100644
index 00000000000..073976fd740
--- /dev/null
+++ b/doc/user/analytics/img/vsa_time_metrics_v13_0.png
Binary files differ
diff --git a/doc/user/analytics/index.md b/doc/user/analytics/index.md
index 48df7bc340a..18f6d79ef23 100644
--- a/doc/user/analytics/index.md
+++ b/doc/user/analytics/index.md
@@ -1,15 +1,14 @@
---
stage: Manage
group: Analytics
-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
+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
---
# Analytics
## Analytics workspace
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/12077) in GitLab 12.2.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12077) in GitLab 12.2.
The Analytics workspace will make it possible to aggregate analytics across
GitLab, so that users can view information across multiple projects and groups
@@ -19,7 +18,7 @@ To access the Analytics workspace, click on **More > Analytics** in the top navi
## Group-level analytics
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/195979) in GitLab 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/195979) in GitLab 12.8.
The following analytics features are available at the group level:
diff --git a/doc/user/analytics/productivity_analytics.md b/doc/user/analytics/productivity_analytics.md
index d0fda61d6a5..653836de8be 100644
--- a/doc/user/analytics/productivity_analytics.md
+++ b/doc/user/analytics/productivity_analytics.md
@@ -1,17 +1,16 @@
---
stage: Manage
group: Analytics
-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
+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
---
# Productivity Analytics **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/12079) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12079) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.3.
Track development velocity with Productivity Analytics.
-For many companies, the development cycle is a blackbox and getting an estimate of how
+For many companies, the development cycle is a black box and getting an estimate of how
long, on average, it takes to deliver features is an enormous endeavor.
While [Value Stream Analytics](../project/cycle_analytics.md) focuses on the entire
@@ -49,7 +48,7 @@ The following metrics and visualizations are available on a project or group lev
## Date ranges
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/13188) in GitLab 12.4.
+> [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:
diff --git a/doc/user/analytics/repository_analytics.md b/doc/user/analytics/repository_analytics.md
index 17032990b09..6d2de951a55 100644
--- a/doc/user/analytics/repository_analytics.md
+++ b/doc/user/analytics/repository_analytics.md
@@ -1,8 +1,7 @@
---
stage: Manage
group: Analytics
-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
+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
---
# Repository Analytics
@@ -34,6 +33,7 @@ The data in the charts are updated soon after each commit in the default branch.
Available charts:
- Programming languages used in the repository
+- Code coverage history (last 3 months) ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/33743) in GitLab 13.1)
- Commit statistics (last month)
- Commits per day of month
- Commits per weekday
diff --git a/doc/user/analytics/value_stream_analytics.md b/doc/user/analytics/value_stream_analytics.md
index 90a4f96f00b..0efe28ac5f7 100644
--- a/doc/user/analytics/value_stream_analytics.md
+++ b/doc/user/analytics/value_stream_analytics.md
@@ -1,14 +1,13 @@
---
stage: Manage
group: Analytics
-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
+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
---
# Value Stream Analytics
> - Introduced as Cycle Analytics prior to GitLab 12.3 at the project level.
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/12077) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.3 at the group level.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12077) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.3 at the group level.
> - [Renamed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23427) from Cycle Analytics to Value Stream Analytics in GitLab 12.8.
Value Stream Analytics measures the time spent to go from an
@@ -47,11 +46,11 @@ There are seven stages that are tracked as part of the Value Stream Analytics ca
- **Staging** (Continuous Deployment)
- Time between merging and deploying to production
- **Total** (Total)
- - Total lifecycle time. That is, the velocity of the project or team. [Previously known](https://gitlab.com/gitlab-org/gitlab/issues/38317) as **Production**.
+ - Total lifecycle time. That is, the velocity of the project or team. [Previously known](https://gitlab.com/gitlab-org/gitlab/-/issues/38317) as **Production**.
## Date ranges
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/13216) in GitLab 12.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13216) in GitLab 12.4.
GitLab provides the ability to filter analytics based on a date range. To filter results:
@@ -59,9 +58,20 @@ GitLab provides the ability to filter analytics based on a date range. To filter
1. Optionally select a project.
1. Select a date range using the available date pickers.
-## How the data is measured
+## How Time metrics are measured
-Value Stream Analytics records cycle time and data based on the project issues with the
+The "Time" metrics near the top of the page are measured as follows:
+
+- **Lead time**: median time from issue created to issue closed.
+- **Cycle time**: median time from first commit to issue closed.
+
+Note: A commit is associated with an issue by [crosslinking](../project/issues/crosslinking_issues.md) in the commit message or by manually linking the merge request containing the commit.
+
+![Value stream analytics time metrics](img/vsa_time_metrics_v13_0.png "Time metrics for value stream analytics")
+
+## How the stages are measured
+
+Value Stream Analytics records stage time and data based on the project issues with the
exception of the staging and total stages, where only data deployed to
production are measured.
@@ -79,7 +89,7 @@ Each stage of Value Stream Analytics is further described in the table below.
| 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. |
| Review | Measures the median time taken to review the merge request that has a closing issue pattern, between its creation and until it's merged. |
| Staging | Measures the median time between merging the merge request with a closing issue pattern until the very first deployment to production. It's tracked by the environment set to `production` or matching `production/*` (case-sensitive, `Production` won't work) in your GitLab CI/CD configuration. If there isn't a production environment, this is not tracked. |
-| Total | The sum of all time (medians) taken to run the entire process, from issue creation to deploying the code to production. [Previously known](https://gitlab.com/gitlab-org/gitlab/issues/38317) as **Production**. |
+| Total | The sum of all time (medians) taken to run the entire process, from issue creation to deploying the code to production. [Previously known](https://gitlab.com/gitlab-org/gitlab/-/issues/38317) as **Production**. |
How this works, behind the scenes:
@@ -274,7 +284,7 @@ from within the chart itself.
### Chart median line
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/36675) in GitLab 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/36675) in GitLab 12.7.
The median line on the chart displays data that is offset by the number of days selected.
For example, if 30 days worth of data has been selected (for example, 2019-12-16 to 2020-01-15) the
diff --git a/doc/user/application_security/configuration/index.md b/doc/user/application_security/configuration/index.md
index dfddbde379d..f0fcd0c4419 100644
--- a/doc/user/application_security/configuration/index.md
+++ b/doc/user/application_security/configuration/index.md
@@ -1,5 +1,8 @@
---
type: reference, howto
+stage: Secure
+group: Static Analysis
+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
---
# Security Configuration **(ULTIMATE)**
diff --git a/doc/user/application_security/container_scanning/index.md b/doc/user/application_security/container_scanning/index.md
index 6e52d7dbdcf..0ffe83cdfc9 100644
--- a/doc/user/application_security/container_scanning/index.md
+++ b/doc/user/application_security/container_scanning/index.md
@@ -1,5 +1,8 @@
---
type: reference, howto
+stage: Defend
+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
---
# Container Scanning **(ULTIMATE)**
@@ -8,35 +11,28 @@ type: reference, howto
## Overview
-If you are using [GitLab CI/CD](../../../ci/README.md), you can check your Docker
-images (or more precisely the containers) for known vulnerabilities by using
-[Clair](https://github.com/quay/clair) and [klar](https://github.com/optiopay/klar),
-two open source tools for Vulnerability Static Analysis for containers.
+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.
+By default, container scanning in GitLab is based on [Clair](https://github.com/quay/clair) and
+[Klar](https://github.com/optiopay/klar), which are open-source tools for vulnerability static analysis in
+containers. [GitLab's Klar analyzer](https://gitlab.com/gitlab-org/security-products/analyzers/klar/)
+scans the containers and serves as a wrapper for Clair.
-You can take advantage of Container Scanning by either [including the CI job](#configuration) in
-your existing `.gitlab-ci.yml` file or by implicitly using
-[Auto Container Scanning](../../../topics/autodevops/stages.md#auto-container-scanning-ultimate)
-that is provided by [Auto DevOps](../../../topics/autodevops/index.md).
-
-GitLab checks the Container Scanning report, compares the found vulnerabilities
-between the source and target branches, and shows the information right on the
-merge request.
-
-![Container Scanning Widget](img/container_scanning_v13_0.png)
-
-## Contribute your scanner
+NOTE: **Note:**
+To integrate security scanners other than Clair and Klar into GitLab, see
+[Security scanner integration](../../../development/integrations/secure.md).
-The [Security Scanner Integration](../../../development/integrations/secure.md) documentation explains how to integrate other security scanners into GitLab.
+You can enable container scanning by doing one of the following:
-## Use cases
+- [Include the CI job](#configuration) in your existing `.gitlab-ci.yml` file.
+- Implicitly use [Auto Container Scanning](../../../topics/autodevops/stages.md#auto-container-scanning-ultimate)
+ provided by [Auto DevOps](../../../topics/autodevops/index.md).
-If you distribute your application with Docker, then there's a great chance
-that your image is based on other Docker images that may in turn contain some
-known vulnerabilities that could be exploited.
+GitLab compares the found vulnerabilities between the source and target branches, and shows the
+information directly in the merge request.
-Having an extra job in your pipeline that checks for those vulnerabilities,
-and the fact that they are displayed inside a merge request, makes it very easy
-to perform audits for your Docker-based apps.
+![Container Scanning Widget](img/container_scanning_v13_0.png)
<!-- NOTE: The container scanning tool references the following heading in the code, so if you
make a change to this heading, make sure to update the documentation URLs used in the
@@ -44,33 +40,28 @@ to perform audits for your Docker-based apps.
## Requirements
-To enable Container Scanning in your pipeline, you need:
-
-- A GitLab Runner with the
- [`docker`](https://docs.gitlab.com/runner/executors/docker.html) or
- [`kubernetes`](https://docs.gitlab.com/runner/install/kubernetes.html)
- executor.
-- Docker `18.09.03` or higher installed on the machine where the Runners are
- running. If you're using the shared Runners on GitLab.com, this is already
- the case.
-- To [build and push](../../packages/container_registry/index.md#container-registry-examples-with-gitlab-cicd)
- your Docker image to your project's Container Registry.
- The name of the Docker image should use the following
- [predefined environment variables](../../../ci/variables/predefined_variables.md)
- as defined below:
+To enable Container Scanning in your pipeline, you need the following:
+
+- [GitLab Runner](https://docs.gitlab.com/runner/) with the [Docker](https://docs.gitlab.com/runner/executors/docker.html)
+ or [Kubernetes](https://docs.gitlab.com/runner/install/kubernetes.html) executor.
+- Docker `18.09.03` or higher installed on the same computer as the Runner. If you're using the
+ shared Runners on GitLab.com, then this is already the case.
+- [Build and push](../../packages/container_registry/index.md#container-registry-examples-with-gitlab-cicd)
+ your Docker image to your project's container registry. The name of the Docker image should use
+ the following [predefined environment variables](../../../ci/variables/predefined_variables.md):
```plaintext
$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:$CI_COMMIT_SHA
```
- These can be used directly in your `.gitlab-ci.yml` file:
+ You can use these directly in your `.gitlab-ci.yml` file:
```yaml
build:
- image: docker:19.03.8
+ image: docker:19.03.11
stage: build
services:
- - docker:19.03.8-dind
+ - docker:19.03.11-dind
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:$CI_COMMIT_SHA
script:
@@ -81,45 +72,40 @@ To enable Container Scanning in your pipeline, you need:
## Configuration
-For GitLab 11.9 and later, to enable Container Scanning, you must
-[include](../../../ci/yaml/README.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's provided as a part of your GitLab installation.
-For GitLab versions earlier than 11.9, you can copy and use the job as defined
-in that template.
+How you enable Container Scanning depends on your GitLab version:
-Add the following to your `.gitlab-ci.yml` file:
+- GitLab 11.9 and later: [Include](../../../ci/yaml/README.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).
+
+To include the `Container-Scanning.gitlab-ci.yml` template (GitLab 11.9 and later), add the
+following to your `.gitlab-ci.yml` file:
```yaml
include:
- template: Container-Scanning.gitlab-ci.yml
```
-The included template will:
+The included template:
-1. Create a `container_scanning` job in your CI/CD pipeline.
-1. Pull the already built Docker image from your project's
- [Container Registry](../../packages/container_registry/index.md) (see [requirements](#requirements))
- and scan it for possible vulnerabilities.
+- Creates a `container_scanning` job in your CI/CD pipeline.
+- Pulls the built Docker image from your project's [Container Registry](../../packages/container_registry/index.md)
+ (see [requirements](#requirements)) and scans it for possible vulnerabilities.
-The results will be saved as a
+GitLab saves the results as a
[Container Scanning report artifact](../../../ci/pipelines/job_artifacts.md#artifactsreportscontainer_scanning-ultimate)
-that you can later download and analyze.
-Due to implementation limitations, we always take the latest Container Scanning
-artifact available. Behind the scenes, the
-[GitLab Klar analyzer](https://gitlab.com/gitlab-org/security-products/analyzers/klar/)
-is used and runs the scans.
+that you can download and analyze later. When downloading, you always receive the most-recent
+artifact.
-The following is a sample `.gitlab-ci.yml` that will build your Docker image,
-push it to the Container Registry, and run Container Scanning:
+The following is a sample `.gitlab-ci.yml` that builds your Docker image, pushes it to the Container
+Registry, and scans the containers:
```yaml
variables:
DOCKER_DRIVER: overlay2
-services:
- - docker:19.03.8-dind
-
stages:
- build
- test
@@ -127,6 +113,8 @@ stages:
build:
image: docker:stable
stage: build
+ services:
+ - docker:19.03.11-dind
variables:
IMAGE: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:$CI_COMMIT_SHA
script:
@@ -141,11 +129,15 @@ include:
### Customizing the Container Scanning settings
-You can change container scanning settings by using the [`variables`](../../../ci/yaml/README.md#variables)
-parameter in your `.gitlab-ci.yml` to change [environment variables](#available-variables).
+There may be cases where you want to customize how GitLab scans your containers. For example, you
+may want to enable more verbose output from Clair or Klar, access a Docker registry that requires
+authentication, and more. To change such settings, use the [`variables`](../../../ci/yaml/README.md#variables)
+parameter in your `.gitlab-ci.yml` to set [environment variables](#available-variables).
+The environment variables you set in your `.gitlab-ci.yml` overwrite those in
+`Container-Scanning.gitlab-ci.yml`.
-In the following example, we [include](../../../ci/yaml/README.md#include) the template and also
-set the `CLAIR_OUTPUT` variable to `High`:
+This example [includes](../../../ci/yaml/README.md#include) the Container Scanning template and
+enables verbose output from Clair by setting the `CLAIR_OUTPUT` environment variable to `High`:
```yaml
include:
@@ -155,9 +147,6 @@ variables:
CLAIR_OUTPUT: High
```
-The `CLAIR_OUTPUT` variable defined in the main `gitlab-ci.yml` will overwrite what's
-defined in `Container-Scanning.gitlab-ci.yml`, changing the Container Scanning behavior.
-
<!-- NOTE: The container scanning tool references the following heading in the code, so if you"
make a change to this heading, make sure to update the documentation URLs used in the"
container scanning tool (https://gitlab.com/gitlab-org/security-products/analyzers/klar)" -->
@@ -188,13 +177,9 @@ using environment variables.
### Overriding the Container Scanning template
-CAUTION: **Deprecation:**
-Beginning in GitLab 13.0, the use of [`only` and `except`](../../../ci/yaml/README.md#onlyexcept-basic)
-is no longer supported. When overriding the template, you must use [`rules`](../../../ci/yaml/README.md#rules) instead.
-
-If you want to override the job definition (for example, change properties like
-`variables`), you need to declare a `container_scanning` job after the
-template inclusion and specify any additional keys under it. For example:
+If you want to override the job definition (for example, to change properties like `variables`), you
+must declare a `container_scanning` job after the template inclusion, and then
+specify any additional keys. For example:
```yaml
include:
@@ -205,15 +190,20 @@ container_scanning:
GIT_STRATEGY: fetch
```
+CAUTION: **Deprecated:**
+GitLab 13.0 and later doesn't support [`only` and `except`](../../../ci/yaml/README.md#onlyexcept-basic).
+When overriding the template, you must use [`rules`](../../../ci/yaml/README.md#rules)
+instead.
+
### Vulnerability whitelisting
-If you want to whitelist specific vulnerabilities, you'll need to:
+To whitelist specific vulnerabilities, follow these steps:
-1. Set `GIT_STRATEGY: fetch` in your `.gitlab-ci.yml` file by following the instructions described in the
- [overriding the Container Scanning template](#overriding-the-container-scanning-template) section of this document.
-1. Define the whitelisted vulnerabilities in a YAML file named `clair-whitelist.yml` which must use the format described
- in the [whitelist example file](https://github.com/arminc/clair-scanner/blob/v12/example-whitelist.yaml).
-1. Add the `clair-whitelist.yml` file to the Git repository of your project.
+1. Set `GIT_STRATEGY: fetch` in your `.gitlab-ci.yml` file by following the instructions in
+ [overriding the Container Scanning template](#overriding-the-container-scanning-template).
+1. Define the whitelisted vulnerabilities in a YAML file named `clair-whitelist.yml`. This must use
+ the format described in the [whitelist example file](https://github.com/arminc/clair-scanner/blob/v12/example-whitelist.yaml).
+1. Add the `clair-whitelist.yml` file to your project's Git repository.
### Running Container Scanning in an offline environment
@@ -286,14 +276,13 @@ this with a pipeline means you won't have to do it manually each time. You can u
```yaml
image: docker:stable
-services:
- - docker:19.03.8-dind
-
stages:
- build
build_latest_vulnerabilities:
stage: build
+ services:
+ - docker:19.03.11-dind
script:
- docker pull arminc/clair-db:latest
- docker tag arminc/clair-db:latest $CI_REGISTRY/namespace/clair-vulnerabilities-db
@@ -339,11 +328,10 @@ The results are stored in `gl-container-scanning-report.json`.
## Reports JSON format
-CAUTION: **Caution:**
-The JSON report artifacts are not a public API of Container Scanning and their format may change in the future.
+The Container Scanning tool emits a JSON report file. For more information, see the
+[schema for this report](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/blob/master/dist/container-scanning-report-format.json).
-The Container Scanning tool emits a JSON report file. Here is an example of the report structure with all important parts of
-it highlighted:
+Here's an example Container Scanning report:
```json-doc
{
@@ -400,49 +388,6 @@ it highlighted:
}
```
-CAUTION: **Deprecation:**
-Beginning with GitLab 12.9, container scanning no longer reports `undefined` severity and confidence levels.
-
-Here is the description of the report file structure nodes and their meaning. All fields are mandatory to be present in
-the report JSON unless stated otherwise. Presence of optional fields depends on the underlying analyzers being used.
-
-| Report JSON node | Description |
-|------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| `version` | Report syntax version used to generate this JSON. |
-| `vulnerabilities` | Array of vulnerability objects. |
-| `vulnerabilities[].id` | Unique identifier of the vulnerability. |
-| `vulnerabilities[].category` | Where this vulnerability belongs (for example, SAST or Container Scanning). For Container Scanning, it will always be `container_scanning`. |
-| `vulnerabilities[].message` | A short text that describes the vulnerability, it may include occurrence's specific information. Optional. |
-| `vulnerabilities[].description` | A long text that describes the vulnerability. Optional. |
-| `vulnerabilities[].cve` | (**DEPRECATED - use `vulnerabilities[].id` instead**) A fingerprint string value that represents a concrete occurrence of the vulnerability. It's used to determine whether two vulnerability occurrences are same or different. May not be 100% accurate. **This is NOT a [CVE](https://cve.mitre.org/)**. |
-| `vulnerabilities[].severity` | How much the vulnerability impacts the software. Possible values: `Info`, `Unknown`, `Low`, `Medium`, `High`, `Critical`. **Note:** Our current container scanning tool based on [klar](https://github.com/optiopay/klar) only provides the following levels: `Unknown`, `Low`, `Medium`, `High`, `Critical`. |
-| `vulnerabilities[].confidence` | How reliable the vulnerability's assessment is. Possible values: `Ignore`, `Unknown`, `Experimental`, `Low`, `Medium`, `High`, `Confirmed`. **Note:** Our current container scanning tool based on [klar](https://github.com/optiopay/klar) does not provide a confidence level, so this value is currently hardcoded to `Unknown`. |
-| `vulnerabilities[].solution` | Explanation of how to fix the vulnerability. Optional. |
-| `vulnerabilities[].scanner` | A node that describes the analyzer used to find this vulnerability. |
-| `vulnerabilities[].scanner.id` | ID of the scanner as a snake_case string. |
-| `vulnerabilities[].scanner.name` | Name of the scanner, for display purposes. |
-| `vulnerabilities[].location` | A node that tells where the vulnerability is located. |
-| `vulnerabilities[].location.dependency` | A node that describes the dependency of a project where the vulnerability is located. |
-| `vulnerabilities[].location.dependency.package` | A node that provides the information on the package where the vulnerability is located. |
-| `vulnerabilities[].location.dependency.package.name` | Name of the package where the vulnerability is located. |
-| `vulnerabilities[].location.dependency.version` | Version of the vulnerable package. Optional. |
-| `vulnerabilities[].location.operating_system` | The operating system that contains the vulnerable package. |
-| `vulnerabilities[].location.image` | The Docker image that was analyzed. |
-| `vulnerabilities[].identifiers` | An ordered array of references that identify a vulnerability on internal or external DBs. |
-| `vulnerabilities[].identifiers[].type` | Type of the identifier. Possible values: common identifier types (among `cve`, `cwe`, `osvdb`, and `usn`). |
-| `vulnerabilities[].identifiers[].name` | Name of the identifier for display purpose. |
-| `vulnerabilities[].identifiers[].value` | Value of the identifier for matching purpose. |
-| `vulnerabilities[].identifiers[].url` | URL to identifier's documentation. Optional. |
-| `vulnerabilities[].links` | An array of references to external documentation pieces or articles that describe the vulnerability further. Optional. |
-| `vulnerabilities[].links[].name` | Name of the vulnerability details link. Optional. |
-| `vulnerabilities[].links[].url` | URL of the vulnerability details document. Optional. |
-| `remediations` | An array of objects containing information on cured vulnerabilities along with patch diffs to apply. Empty if no remediations provided by an underlying analyzer. |
-| `remediations[].fixes` | An array of strings that represent references to vulnerabilities fixed by this particular remediation. |
-| `remediations[].fixes[].id` | The ID of a fixed vulnerability. |
-| `remediations[].fixes[].cve` | (**DEPRECATED - use `remediations[].fixes[].id` instead**) A string value that describes a fixed vulnerability in the same format as `vulnerabilities[].cve`. |
-| `remediations[].summary` | Overview of how the vulnerabilities have been fixed. |
-| `remediations[].diff` | base64-encoded remediation code diff, compatible with [`git apply`](https://git-scm.com/docs/git-format-patch#_discussion). |
-
## Security Dashboard
The [Security Dashboard](../security_dashboard/index.md) shows you an overview of all
@@ -473,7 +418,7 @@ Read more about the [solutions for vulnerabilities](../index.md#solutions-for-vu
## Troubleshooting
-### docker: Error response from daemon: failed to copy xattrs
+### `docker: Error response from daemon: failed to copy xattrs`
When the GitLab Runner uses the Docker executor and NFS is used
(for example, `/var/lib/docker` is on an NFS mount), Container Scanning might fail with
@@ -486,4 +431,4 @@ docker: Error response from daemon: failed to copy xattrs: failed to set xattr "
This is a result of a bug in Docker which is now [fixed](https://github.com/containerd/continuity/pull/138 "fs: add WithAllowXAttrErrors CopyOpt").
To prevent the error, ensure the Docker version that the Runner is using is
`18.09.03` or higher. For more information, see
-[issue #10241](https://gitlab.com/gitlab-org/gitlab/issues/10241 "Investigate why Container Scanning is not working with NFS mounts").
+[issue #10241](https://gitlab.com/gitlab-org/gitlab/-/issues/10241 "Investigate why Container Scanning is not working with NFS mounts").
diff --git a/doc/user/application_security/dast/index.md b/doc/user/application_security/dast/index.md
index cfc679f13a7..256daae46d7 100644
--- a/doc/user/application_security/dast/index.md
+++ b/doc/user/application_security/dast/index.md
@@ -1,10 +1,13 @@
---
+stage: Secure
+group: Dynamic Analysis
+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, howto
---
# Dynamic Application Security Testing (DAST) **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/4348) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4348) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.4.
NOTE: **4 of the top 6 attacks were application based.**
Download our whitepaper,
@@ -142,7 +145,14 @@ the site during a scan could lead to inaccurate results.
### Authentication
-It's also possible to authenticate the user before performing the DAST checks:
+It's also possible to authenticate the user before performing the DAST checks.
+
+Create masked variables to pass the credentials that DAST will use.
+To create masked variables for the username and password, see [Create a custom variable in the UI](../../../ci/variables/README.md#create-a-custom-variable-in-the-ui).
+Note that the key of the username variable must be `DAST_USERNAME`
+and the key of the password variable must be `DAST_PASSWORD`.
+
+Other variables that are related to authenticated scans are:
```yaml
include:
@@ -151,8 +161,6 @@ include:
variables:
DAST_WEBSITE: https://example.com
DAST_AUTH_URL: https://example.com/sign-in
- DAST_USERNAME: john.doe@example.com
- DAST_PASSWORD: john-doe-password
DAST_USERNAME_FIELD: session[user] # the name of username field at the sign-in HTML form
DAST_PASSWORD_FIELD: session[password] # the name of password field at the sign-in HTML form
DAST_AUTH_EXCLUDE_URLS: http://example.com/sign-out,http://example.com/sign-out-2 # optional, URLs to skip during the authenticated scan; comma-separated, no spaces in between
@@ -439,7 +447,7 @@ DAST can be [configured](#customizing-the-dast-settings) using environment varia
| Environment variable | Required | Description |
|-----------------------------| -----------|--------------------------------------------------------------------------------|
-| `SECURE_ANALYZERS_PREFIX` | no | Set the Docker registry base address from which to download the analyzer. |
+| `SECURE_ANALYZERS_PREFIX` | no | Set the Docker registry base address from which to download the analyzer. |
| `DAST_WEBSITE` | no| The URL of the website to scan. `DAST_API_SPECIFICATION` must be specified if this is omitted. |
| `DAST_API_SPECIFICATION` | no | The API specification to import. `DAST_WEBSITE` must be specified if this is omitted. |
| `DAST_AUTH_URL` | no | The authentication URL of the website to scan. Not supported for API scans. |
@@ -455,7 +463,15 @@ DAST can be [configured](#customizing-the-dast-settings) using environment varia
| `DAST_API_HOST_OVERRIDE` | no | Used to override domains defined in API specification files. |
| `DAST_EXCLUDE_RULES` | no | Set to a comma-separated list of Vulnerability Rule IDs to exclude them from the scan report. Currently, excluded rules will get executed but the alerts from them will be suppressed. Rule IDs are numbers and can be found from the DAST log or on the [ZAP project](https://github.com/zaproxy/zaproxy/blob/develop/docs/scanners.md). For example, `HTTP Parameter Override` has a rule ID of `10026`. |
| `DAST_REQUEST_HEADERS` | no | Set to a comma-separated list of request header names and values. For example, `Cache-control: no-cache,User-Agent: DAST/1.0` |
-| `DAST_ZAP_USE_AJAX_SPIDER` | no | Use the AJAX spider in addition to the traditional spider, useful for crawling sites that require JavaScript. Boolean. `true`, `True`, or `1` are considered as true value, otherwise false. Defaults to `false`. |
+| `DAST_DEBUG` | no | Enable debug message output. Boolean. `true`, `True`, or `1` are considered as true value, otherwise false. Defaults to `false`. |
+| `DAST_SPIDER_MINS` | no | The maximum duration of the spider scan in minutes. Set to zero for unlimited. Defaults to one minute, or unlimited when the scan is a full scan. |
+| `DAST_HTML_REPORT` | no | The file name of the HTML report written at the end of a scan. |
+| `DAST_MARKDOWN_REPORT` | no | The file name of the Markdown report written at the end of a scan. |
+| `DAST_XML_REPORT` | no | The file name of the XML report written at the end of a scan. |
+| `DAST_INCLUDE_ALPHA_VULNERABILITIES` | no | Include alpha passive and active scan rules. Boolean. `true`, `True`, or `1` are considered as true value, otherwise false. Defaults to `false`. |
+| `DAST_USE_AJAX_SPIDER` | no | Use the AJAX spider in addition to the traditional spider, useful for crawling sites that require JavaScript. Boolean. `true`, `True`, or `1` are considered as true value, otherwise false. Defaults to `false`. |
+| `DAST_ZAP_CLI_OPTIONS` | no | ZAP server command-line options. For example, `-Xmx3072m` would set the Java maximum memory allocation pool size. |
+| `DAST_ZAP_LOG_CONFIGURATION` | no | Set to a semicolon-separated list of additional log4j properties for the ZAP Server. For example, `log4j.logger.org.parosproxy.paros.network.HttpSender=DEBUG` |
### DAST command-line options
@@ -472,8 +488,9 @@ dast:
- /analyze --help
```
-You must then overwrite the `script` command to pass in the appropriate argument.
-For example, debug messages can be enabled by using `-d`, as shown in the following configuration:
+You must then overwrite the `script` command to pass in the appropriate
+argument. For example, passive scanning can be delayed using option `-D`. The following
+configuration delays passive scanning by five minutes:
```yaml
include:
@@ -482,14 +499,14 @@ include:
dast:
script:
- export DAST_WEBSITE=${DAST_WEBSITE:-$(cat environment_url.txt)}
- - /analyze -d -t $DAST_WEBSITE
+ - /analyze -D 300 -t $DAST_WEBSITE
```
### Custom ZAProxy configuration
-The ZAProxy server contains many [useful configurable values](https://gitlab.com/gitlab-org/gitlab/issues/36437#note_245801885).
+The ZAProxy server contains many [useful configurable values](https://gitlab.com/gitlab-org/gitlab/-/issues/36437#note_245801885).
Many key/values for `-config` remain undocumented, but there is an untested list of
-[possible keys](https://gitlab.com/gitlab-org/gitlab/issues/36437#note_244981023).
+[possible keys](https://gitlab.com/gitlab-org/gitlab/-/issues/36437#note_244981023).
Note that these options are not supported by DAST, and may break the DAST scan
when used. An example of how to rewrite the Authorization header value with `TOKEN` follows:
@@ -497,10 +514,8 @@ when used. An example of how to rewrite the Authorization header value with `TOK
include:
template: DAST.gitlab-ci.yml
-dast:
- script:
- - export DAST_WEBSITE=${DAST_WEBSITE:-$(cat environment_url.txt)}
- - /analyze -z"-config replacer.full_list\(0\).description=auth -config replacer.full_list\(0\).enabled=true -config replacer.full_list\(0\).matchtype=REQ_HEADER -config replacer.full_list\(0\).matchstr=Authorization -config replacer.full_list\(0\).regex=false -config replacer.full_list\(0\).replacement=TOKEN" -t $DAST_WEBSITE
+variables:
+ DAST_ZAP_CLI_OPTIONS: "-config replacer.full_list(0).description=auth -config replacer.full_list(0).enabled=true -config replacer.full_list(0).matchtype=REQ_HEADER -config replacer.full_list(0).matchstr=Authorization -config replacer.full_list(0).regex=false -config replacer.full_list(0).replacement=TOKEN"
```
### Cloning the project's repository
@@ -508,6 +523,29 @@ dast:
The DAST job does not require the project's repository to be present when running, so by default
[`GIT_STRATEGY`](../../../ci/yaml/README.md#git-strategy) is set to `none`.
+### Debugging DAST jobs
+
+A DAST job has two executing processes:
+
+- The ZAP server.
+- A series of scripts that start, control and stop the ZAP server.
+
+Debug mode of the scripts can be enabled by using the `DAST_DEBUG` environment variable. This can help when troubleshooting the job,
+and will output statements indicating what percentage of the scan is complete.
+For details on using variables, see [Overriding the DAST template](#overriding-the-dast-template).
+
+Debug mode of the ZAP server can be enabled using the `DAST_ZAP_LOG_CONFIGURATION` environment variable.
+The following table outlines examples of values that can be set and the effect that they have on the output that is logged.
+Multiple values can be specified, separated by semicolons.
+
+| Log configuration value | Effect |
+|-------------------------------------------------- | ----------------------------------------------------------------- |
+| `log4j.rootLogger=DEBUG` | Enable all debug logging statements. |
+| `log4j.logger.org.apache.commons.httpclient=DEBUG` | Log every HTTP request and response made by the ZAP server. |
+| `log4j.logger.com.crawljax=DEBUG` | Enable Ajax Crawler debug logging statements. |
+| `log4j.logger.org.parosproxy.paros=DEBUG` | Enable ZAP server proxy debug logging statements. |
+| `log4j.logger.org.zaproxy.zap=DEBUG` | Enable debug logging statements of the general ZAP server code. |
+
## Running DAST in an offline environment
For self-managed GitLab instances in an environment with limited, restricted, or intermittent access
@@ -568,7 +606,8 @@ Alternatively, you can use the variable `SECURE_ANALYZERS_PREFIX` to override th
## Reports
-The DAST job can emit various reports.
+The DAST tool outputs a report file in JSON format by default. However, this tool can also generate reports in
+Markdown, HTML, and XML. For more information, see the [schema for DAST reports](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/blob/master/dist/dast-report-format.json).
### List of URLs scanned
@@ -593,24 +632,22 @@ There are two formats of data in the JSON report that are used side by side:
### Other formats
-Reports can also be generated in Markdown, HTML, and XML.
-
-Reports can be published as artifacts using the following configuration:
+Reports can also be generated in Markdown, HTML, and XML. These can be published as artifacts using the following configuration:
```yaml
include:
template: DAST.gitlab-ci.yml
dast:
- script:
- - export DAST_WEBSITE=${DAST_WEBSITE:-$(cat environment_url.txt)}
- - /analyze -r report.html -w report.md -x report.xml -t $DAST_WEBSITE
- - cp /zap/wrk/report.{html,md,xml} "$PWD"
+ variables:
+ DAST_HTML_REPORT: report.html
+ DAST_MARKDOWN_REPORT: report.md
+ DAST_XML_REPORT: report.xml
artifacts:
paths:
- - report.html
- - report.md
- - report.xml
+ - $DAST_HTML_REPORT
+ - $DAST_MARKDOWN_REPORT
+ - $DAST_XML_REPORT
- gl-dast-report.json
```
@@ -622,18 +659,18 @@ vulnerabilities in your groups, projects and pipelines. Read more about the
## Bleeding-edge vulnerability definitions
-ZAProxy first creates rules in the `alpha` class. After a testing period with the
-community, they are promoted to `beta`. DAST uses `beta` definitions by default.
-To request `alpha` definitions, use `-a` as shown in the following configuration:
+ZAP first creates rules in the `alpha` class. After a testing period with
+the community, they are promoted to `beta`. DAST uses `beta` definitions by
+default. To request `alpha` definitions, use the
+`DAST_INCLUDE_ALPHA_VULNERABILITIES` environment variable as shown in the
+following configuration:
```yaml
include:
template: DAST.gitlab-ci.yml
-dast:
- script:
- - export DAST_WEBSITE=${DAST_WEBSITE:-$(cat environment_url.txt)}
- - /analyze -a -t $DAST_WEBSITE
+variables:
+ DAST_INCLUDE_ALPHA_VULNERABILITIES: true
```
## Interacting with the vulnerabilities
@@ -685,16 +722,14 @@ This results in the following error:
```
Fortunately, it's straightforward to increase the amount of memory available
-for DAST by overwriting the `script` key in the DAST template:
+for DAST by using the `DAST_ZAP_CLI_OPTIONS` environment variable:
```yaml
include:
- template: DAST.gitlab-ci.yml
-dast:
- script:
- - export DAST_WEBSITE=${DAST_WEBSITE:-$(cat environment_url.txt)}
- - /analyze -t $DAST_WEBSITE -z"-Xmx3072m"
+variables:
+ DAST_ZAP_CLI_OPTIONS: "-Xmx3072m"
```
Here, DAST is being allocated 3072 MB.
diff --git a/doc/user/application_security/dependency_list/index.md b/doc/user/application_security/dependency_list/index.md
index 73d2cfeaf00..1f730e5f205 100644
--- a/doc/user/application_security/dependency_list/index.md
+++ b/doc/user/application_security/dependency_list/index.md
@@ -1,6 +1,13 @@
+---
+type: reference, howto
+stage: Secure
+group: Composition Analysis
+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
+---
+
# Dependency List **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/10075) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.0.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10075) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.0.
The Dependency list allows you to see your project's dependencies, and key
details about them, including their known vulnerabilities. To see it,
@@ -24,8 +31,8 @@ Dependencies are displayed with the following information:
| Field | Description |
| --------- | ----------- |
| Component | The dependency's name and version |
-| Packager | The packager used to install the depedency |
-| Location | A link to the packager-specific lockfile in your project that declared the dependency |
+| Packager | The packager used to install the dependency |
+| Location | A link to the packager-specific lock file in your project that declared the dependency |
| License | Links to dependency's software licenses |
Dependencies shown are initially sorted by the severity of their known vulnerabilities, if any. They
@@ -39,7 +46,7 @@ vulnerability, its severity and description then appears below it.
## Licenses
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/10536) in GitLab Ultimate 12.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10536) in GitLab Ultimate 12.3.
If the [License Compliance](../../compliance/license_compliance/index.md) CI job is configured,
the [discovered licenses](../../compliance/license_compliance/index.md#supported-languages-and-package-managers) will be displayed on this page.
diff --git a/doc/user/application_security/dependency_scanning/index.md b/doc/user/application_security/dependency_scanning/index.md
index 53462cf232e..84ec0ec976d 100644
--- a/doc/user/application_security/dependency_scanning/index.md
+++ b/doc/user/application_security/dependency_scanning/index.md
@@ -1,10 +1,13 @@
---
type: reference, howto
+stage: Secure
+group: Composition Analysis
+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
---
# Dependency Scanning **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/5105) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5105) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.7.
Dependency Scanning helps to automatically find security vulnerabilities in your dependencies
while you're developing and testing your applications, such as when your
@@ -50,20 +53,27 @@ Beginning with GitLab 13.0, Docker privileged mode is necessary only if you've [
## Supported languages and package managers
-The following languages and dependency managers are supported.
-
-| Language (package managers) | Supported | Scan tool(s) |
-|----------------------------- | --------- | ------------ |
-| Java ([Gradle](https://gradle.org/)) | yes | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) |
-| Java ([Maven](https://maven.apache.org/)) | yes | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) |
-| JavaScript ([npm](https://www.npmjs.com/), [yarn](https://classic.yarnpkg.com/en/)) | yes | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium), [Retire.js](https://retirejs.github.io/retire.js/) |
-| PHP ([Composer](https://getcomposer.org/)) | yes | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) |
-| Python ([pip](https://pip.pypa.io/en/stable/)) | yes | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) |
-| Python ([Pipfile](https://pipenv.kennethreitz.org/en/latest/basics/)) | not currently ([issue](https://gitlab.com/gitlab-org/gitlab/issues/11756 "Pipfile.lock support for Dependency Scanning"))| not available |
-| Python ([poetry](https://python-poetry.org/)) | not currently ([issue](https://gitlab.com/gitlab-org/gitlab/issues/7006 "Support Poetry in Dependency Scanning")) | not available |
-| Ruby ([gem](https://rubygems.org/)) | yes | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium), [bundler-audit](https://github.com/rubysec/bundler-audit) |
-| Scala ([sbt](https://www.scala-sbt.org/)) | yes | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) |
-| Go ([Go Modules](https://github.com/golang/go/wiki/Modules)) | yes ([alpha](https://gitlab.com/gitlab-org/gitlab/issues/7132)) | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) |
+GitLab relies on [`rules`](../../../ci/yaml/README.md#rules) to start relevant analyzers depending on the languages detected in the repository.
+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` or `api/Gemfile` file, but not if the only supported dependency file is `api/client/Gemfile`.
+
+The following languages and dependency managers are supported:
+
+| Language (package managers) | Supported files | Scan tool(s) |
+|----------------------------- | --------------- | ------------ |
+| Java ([Gradle](https://gradle.org/), [Maven](https://maven.apache.org/)) | `build.gradle`, `build.gradle.kts`, `pom.xml` | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) |
+| JavaScript ([npm](https://www.npmjs.com/), [yarn](https://yarnpkg.com/en/)) | `package-lock.json`, `npm-shrinkwrap.json`, `yarn.lock` | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium), [Retire.js](https://retirejs.github.io/retire.js) |
+| Go ([Golang](https://golang.org/)) | `go.sum` | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) |
+| PHP ([Composer](https://getcomposer.org/)) | `composer.lock` | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) |
+| Python ([setuptools](https://setuptools.readthedocs.io/en/latest/), [pip](https://pip.pypa.io/en/stable/), [Pipenv](https://pipenv.pypa.io/en/latest/)) | `setup.py`, `requirements.txt`, `requirements.pip`, `requires.txt`, `Pipfile` | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) |
+| Ruby ([Bundler](https://bundler.io/)) | `Gemfile.lock`, `gems.locked` | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium), [bundler-audit](https://github.com/rubysec/bundler-audit) |
+| Scala ([sbt](https://www.scala-sbt.org/)) | `build.sbt` | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) |
+
+Plans are underway for supporting the following languages, dependency managers, and dependency files. For details, see the issue link for each.
+
+| Language (package managers) | Supported files | Scan tool(s) | Issue |
+|----------------------------- | --------------- | ------------ | ----- |
+| Python ([Poetry](https://poetry.eustace.io/)) | `poetry.lock` | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) | [GitLab#7006](https://gitlab.com/gitlab-org/gitlab/issues/7006) |
+| Python ([Pipenv](https://pipenv.pypa.io/en/latest/)) | `Pipfile.lock` | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) | [GitLab#11756](https://gitlab.com/gitlab-org/gitlab/-/issues/11756) |
## Contribute your scanner
@@ -145,7 +155,7 @@ The following variables allow configuration of global dependency scanning settin
| `DS_DEFAULT_ANALYZERS` | Override the names of the official default images. Read more about [customizing analyzers](analyzers.md). |
| `DS_DISABLE_DIND` | Disable Docker-in-Docker and run analyzers [individually](#enabling-docker-in-docker). This variable is `true` by default. |
| `ADDITIONAL_CA_CERT_BUNDLE` | Bundle of CA certs to trust. |
-| `DS_EXCLUDED_PATHS` | Exclude vulnerabilities from output based on the paths. A comma-separated list of patterns. Patterns can be globs, or file or folder paths (for example, `doc,spec`). Parent directories also match patterns. |
+| `DS_EXCLUDED_PATHS` | Exclude vulnerabilities from output based on the paths. A comma-separated list of patterns. Patterns can be globs, or file or folder paths (for example, `doc,spec`). Parent directories also match patterns. Default: `"spec, test, tests, tmp"` |
#### Configuring Docker-in-Docker orchestrator
@@ -173,9 +183,9 @@ The following variables are used for configuring specific analyzers (used for a
| `PIP_INDEX_URL` | `gemnasium-python` | `https://pypi.org/simple` | Base URL of Python Package Index. |
| `PIP_EXTRA_INDEX_URL` | `gemnasium-python` | | Array of [extra URLs](https://pip.pypa.io/en/stable/reference/pip_install/#cmdoption-extra-index-url) of package indexes to use in addition to `PIP_INDEX_URL`. Comma-separated. |
| `PIP_REQUIREMENTS_FILE` | `gemnasium-python` | | Pip requirements file to be scanned. |
-| `DS_PIP_VERSION` | `gemnasium-python` | | Force the install of a specific pip version (example: `"19.3"`), otherwise the pip installed in the Docker image is used. ([Introduced](https://gitlab.com/gitlab-org/gitlab/issues/12811) in GitLab 12.7) |
-| `DS_PIP_DEPENDENCY_PATH` | `gemnasium-python` | | Path to load Python pip dependencies from. ([Introduced](https://gitlab.com/gitlab-org/gitlab/issues/12412) in GitLab 12.2) |
-| `DS_PYTHON_VERSION` | `retire.js` | | Version of Python. If set to 2, dependencies are installed using Python 2.7 instead of Python 3.6. ([Introduced](https://gitlab.com/gitlab-org/gitlab/issues/12296) in GitLab 12.1)|
+| `DS_PIP_VERSION` | `gemnasium-python` | | Force the install of a specific pip version (example: `"19.3"`), otherwise the pip installed in the Docker image is used. ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12811) in GitLab 12.7) |
+| `DS_PIP_DEPENDENCY_PATH` | `gemnasium-python` | | Path to load Python pip dependencies from. ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12412) in GitLab 12.2) |
+| `DS_PYTHON_VERSION` | `retire.js` | | Version of Python. If set to 2, dependencies are installed using Python 2.7 instead of Python 3.6. ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12296) in GitLab 12.1)|
| `MAVEN_CLI_OPTS` | `gemnasium-maven` | `"-DskipTests --batch-mode"` | List of command line arguments that will be passed to `maven` by the analyzer. See an example for [using private repositories](../index.md#using-private-maven-repos). |
| `GRADLE_CLI_OPTS` | `gemnasium-maven` | | List of command line arguments that will be passed to `gradle` by the analyzer. |
| `SBT_CLI_OPTS` | `gemnasium-maven` | | List of command-line arguments that the analyzer will pass to `sbt`. |
@@ -195,7 +205,7 @@ Read more on [how to use private Maven repositories](../index.md#using-private-m
### Enabling Docker-in-Docker
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/12487) in GitLab Ultimate 12.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12487) in GitLab Ultimate 12.5.
If needed, you can enable Docker-in-Docker to restore the Dependency Scanning behavior that existed
prior to GitLab 13.0. Follow these steps to do so:
@@ -244,11 +254,10 @@ the [Dependency List](../dependency_list/index.md).
## Reports JSON format
-CAUTION: **Caution:**
-The JSON report artifacts are not a public API of Dependency Scanning and their format may change in the future.
+The Dependency Scanning tool emits a JSON report file. For more information, see the
+[schema for this report](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/blob/master/dist/dependency-scanning-report-format.json).
-The Dependency Scanning tool emits a JSON report file. Here is an example of the report structure with all important parts of
-it highlighted:
+Here's an example Dependency Scanning report:
```json-doc
{
@@ -357,49 +366,6 @@ it highlighted:
}
```
-CAUTION: **Deprecation:**
-Beginning with GitLab 12.9, dependency scanning no longer reports `undefined` severity and confidence levels.
-
-This table describes the report file structure nodes and their meaning. All fields are mandatory to be present in
-the report JSON, unless stated otherwise. The presence of optional fields depends on the underlying analyzers used.
-
-| Report JSON node | Description |
-|------------------------------------------------------|-------------|
-| `version` | Report syntax version used to generate this JSON. |
-| `vulnerabilities` | Array of vulnerability objects. |
-| `vulnerabilities[].id` | Unique identifier of the vulnerability. |
-| `vulnerabilities[].category` | Where this vulnerability belongs, such as SAST or Dependency Scanning. For Dependency Scanning, it will always be `dependency_scanning`. |
-| `vulnerabilities[].name` | Name of the vulnerability. Must not include the occurrence's specific information. Optional. |
-| `vulnerabilities[].message` | A short text that describes the vulnerability. May include occurrence's specific information. Optional. |
-| `vulnerabilities[].description` | A long text that describes the vulnerability. Optional. |
-| `vulnerabilities[].cve` | (**DEPRECATED - use `vulnerabilities[].id` instead**) A fingerprint string value that represents a concrete occurrence of the vulnerability. Used to determine whether two vulnerability occurrences are same or different. May not be 100% accurate. **This is NOT a [CVE](https://cve.mitre.org/)**. |
-| `vulnerabilities[].severity` | How much the vulnerability impacts the software. Possible values: `Info`, `Unknown`, `Low`, `Medium`, `High`, `Critical`. |
-| `vulnerabilities[].confidence` | How reliable the vulnerability's assessment is. Possible values: `Ignore`, `Unknown`, `Experimental`, `Low`, `Medium`, `High`, `Confirmed`. |
-| `vulnerabilities[].solution` | Explanation of how to fix the vulnerability. Optional. |
-| `vulnerabilities[].scanner` | A node that describes the analyzer used to find this vulnerability. |
-| `vulnerabilities[].scanner.id` | ID of the scanner as a `snake_case` string. |
-| `vulnerabilities[].scanner.name` | Name of the scanner, for display purposes. |
-| `vulnerabilities[].location` | A node that tells where the vulnerability is located. |
-| `vulnerabilities[].location.file` | Path to the dependencies file (such as `yarn.lock`). Optional. |
-| `vulnerabilities[].location.dependency` | A node that describes the dependency of a project where the vulnerability is located. |
-| `vulnerabilities[].location.dependency.package` | A node that provides the information on the package where the vulnerability is located. |
-| `vulnerabilities[].location.dependency.package.name` | Name of the package where the vulnerability is located. Optional. |
-| `vulnerabilities[].location.dependency.version` | Version of the vulnerable package. Optional. |
-| `vulnerabilities[].identifiers` | An ordered array of references that identify a vulnerability on internal or external DBs. |
-| `vulnerabilities[].identifiers[].type` | Type of the identifier. Possible values: common identifier types (among `cve`, `cwe`, `osvdb`, and `usn`) or analyzer-dependent ones (such as `gemnasium` for [Gemnasium](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/)). |
-| `vulnerabilities[].identifiers[].name` | Name of the identifier for display purpose. |
-| `vulnerabilities[].identifiers[].value` | Value of the identifier for matching purpose. |
-| `vulnerabilities[].identifiers[].url` | URL to identifier's documentation. Optional. |
-| `vulnerabilities[].links` | An array of references to external documentation pieces or articles that describe the vulnerability further. Optional. |
-| `vulnerabilities[].links[].name` | Name of the vulnerability details link. Optional. |
-| `vulnerabilities[].links[].url` | URL of the vulnerability details document. Optional. |
-| `remediations` | An array of objects containing information on cured vulnerabilities along with patch diffs to apply. Empty if no remediations provided by an underlying analyzer. |
-| `remediations[].fixes` | An array of strings that represent references to vulnerabilities fixed by this particular remediation. |
-| `remediations[].fixes[].id` | The ID of a fixed vulnerability. |
-| `remediations[].fixes[].cve` | (**DEPRECATED - use `remediations[].fixes[].id` instead**) A string value that describes a fixed vulnerability in the same format as `vulnerabilities[].cve`. |
-| `remediations[].summary` | Overview of how the vulnerabilities have been fixed. |
-| `remediations[].diff` | Base64-encoded remediation code diff, compatible with [`git apply`](https://git-scm.com/docs/git-format-patch#_discussion). |
-
## Versioning and release process
Please check the [Release Process documentation](https://gitlab.com/gitlab-org/security-products/release/blob/master/docs/release_process.md).
@@ -498,42 +464,6 @@ BUNDLER_AUDIT_ADVISORY_DB_REF_NAME: "master"
BUNDLER_AUDIT_ADVISORY_DB_URL: "gitlab.example.com/ruby-advisory-db.git"
```
-#### Java (Maven) projects
-
-When using self-signed certificates, add the following job section to the `.gitlab-ci.yml`:
-
-```yaml
-gemnasium-maven-dependency_scanning:
- variables:
- MAVEN_CLI_OPTS: "-s settings.xml -Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true -Dmaven.wagon.http.ssl.ignore.validity.dates=true"
-```
-
-#### Java (Gradle) projects
-
-When using self-signed certificates, add the following job section to the `.gitlab-ci.yml`:
-
-```yaml
-gemnasium-maven-dependency_scanning:
- before_script:
- - echo -n | openssl s_client -connect maven-repo.example.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /tmp/internal.crt
- - keytool -importcert -file /tmp/internal.crt -cacerts -storepass changeit -noprompt
-```
-
-This adds the self-signed certificates of your Maven repository to the Java KeyStore of the analyzer's Docker image.
-
-#### Scala (sbt) projects
-
-When using self-signed certificates, add the following job section to the `.gitlab-ci.yml`:
-
-```yaml
-gemnasium-maven-dependency_scanning:
- before_script:
- - echo -n | openssl s_client -connect maven-repo.example.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /tmp/internal.crt
- - keytool -importcert -file /tmp/internal.crt -cacerts -storepass changeit -noprompt
-```
-
-This adds the self-signed certificates of your Maven repository to the Java KeyStore of the analyzer's Docker image.
-
#### Python (setuptools)
When using self-signed certificates for your private PyPi repository, no extra job configuration (aside
@@ -543,23 +473,23 @@ ensure that it can reach your private repository. Here is an example configurati
1. Update `setup.py` to create a `dependency_links` attribute pointing at your private repository for each
dependency in the `install_requires` list:
- ```python
- install_requires=['pyparsing>=2.0.3'],
- dependency_links=['https://pypi.example.com/simple/pyparsing'],
- ```
+ ```python
+ install_requires=['pyparsing>=2.0.3'],
+ dependency_links=['https://pypi.example.com/simple/pyparsing'],
+ ```
1. Fetch the certificate from your repository URL and add it to the project:
- ```bash
- echo -n | openssl s_client -connect pypi.example.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > internal.crt
- ```
+ ```shell
+ echo -n | openssl s_client -connect pypi.example.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > internal.crt
+ ```
1. Point `setup.py` at the newly downloaded certificate:
- ```python
- import setuptools.ssl_support
- setuptools.ssl_support.cert_paths = ['internal.crt']
- ```
+ ```python
+ import setuptools.ssl_support
+ setuptools.ssl_support.cert_paths = ['internal.crt']
+ ```
## Limitations
@@ -579,9 +509,9 @@ As a workaround, remove the [`retire.js`](analyzers.md#selecting-specific-analyz
## Troubleshooting
-### Error response from daemon: error processing tar file: docker-tar: relocation error
+### `Error response from daemon: error processing tar file: docker-tar: relocation error`
This error occurs when the Docker version that runs the Dependency Scanning job is `19.03.00`.
Consider updating to Docker `19.03.1` or greater. Older versions are not
affected. Read more in
-[this issue](https://gitlab.com/gitlab-org/gitlab/issues/13830#note_211354992 "Current SAST container fails").
+[this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/13830#note_211354992 "Current SAST container fails").
diff --git a/doc/user/application_security/img/security_configuration_page_v13_1.png b/doc/user/application_security/img/security_configuration_page_v13_1.png
index 0147084f705..176c64a9e87 100644
--- a/doc/user/application_security/img/security_configuration_page_v13_1.png
+++ b/doc/user/application_security/img/security_configuration_page_v13_1.png
Binary files differ
diff --git a/doc/user/application_security/img/vulnerability-check_v13_0.png b/doc/user/application_security/img/vulnerability-check_v13_0.png
new file mode 100644
index 00000000000..536fc4f10f7
--- /dev/null
+++ b/doc/user/application_security/img/vulnerability-check_v13_0.png
Binary files differ
diff --git a/doc/user/application_security/index.md b/doc/user/application_security/index.md
index eefa52eb5c3..49580f494a2 100644
--- a/doc/user/application_security/index.md
+++ b/doc/user/application_security/index.md
@@ -17,14 +17,15 @@ For an overview of application security with GitLab, see
## Quick start
-Get started quickly with Dependency Scanning, License Scanning, and Static Application Security
-Testing (SAST) by adding the following to your `.gitlab-ci.yml`:
+Get started quickly with Dependency Scanning, License Scanning, Static Application Security
+Testing (SAST), and Secret Detection by adding the following to your `.gitlab-ci.yml`:
```yaml
include:
- template: Dependency-Scanning.gitlab-ci.yml
- template: License-Scanning.gitlab-ci.yml
- template: SAST.gitlab-ci.yml
+ - template: Secret-Detection.gitlab-ci.yml
```
To add Dynamic Application Security Testing (DAST) scanning, add the following to your
@@ -64,14 +65,27 @@ GitLab uses the following tools to scan and report known vulnerabilities found i
| [Security Dashboard](security_dashboard/index.md) **(ULTIMATE)** | View vulnerabilities in all your projects and groups. |
| [Static Application Security Testing (SAST)](sast/index.md) **(ULTIMATE)** | Analyze source code for known vulnerabilities. |
+## Security Scanning with Auto DevOps
+
+When [Auto DevOps](../../topics/autodevops/) is enabled, all GitLab Security scanning tools will be configured using default settings.
+
+- [Auto SAST](../../topics/autodevops/stages.md#auto-sast-ultimate)
+- [Auto Secret Detection](../../topics/autodevops/stages.md#auto-secret-detection-ultimate)
+- [Auto DAST](../../topics/autodevops/stages.md#auto-dast-ultimate)
+- [Auto Dependency Scanning](../../topics/autodevops/stages.md#auto-dependency-scanning-ultimate)
+- [Auto License Compliance](../../topics/autodevops/stages.md#auto-license-compliance-ultimate)
+- [Auto Container Scanning](../../topics/autodevops/stages.md#auto-container-scanning-ultimate)
+
+While you cannot directly customize Auto DevOps, you can [include the Auto DevOps template in your project's `.gitlab-ci.yml` file](../../topics/autodevops/customize.md#customizing-gitlab-ciyml).
+
## Maintenance and update of the vulnerabilities database
The scanning tools and vulnerabilities database are updated regularly.
| Secure scanning tool | Vulnerabilities database updates |
|:-------------------------------------------------------------|-------------------------------------------|
-| [Container Scanning](container_scanning/index.md) | Uses `clair`. The latest `clair-db` version is used for each job by running the [`latest` docker image tag](https://gitlab.com/gitlab-org/gitlab/blob/438a0a56dc0882f22bdd82e700554525f552d91b/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml#L37). The `clair-db` database [is updated daily according to the author](https://github.com/arminc/clair-local-scan#clair-server-or-local). |
-| [Dependency Scanning](dependency_scanning/index.md) | Relies on `bundler-audit` (for Rubygems), `retire.js` (for NPM packages), and `gemnasium` (GitLab's own tool for all libraries). Both `bundler-audit` and `retire.js` fetch their vulnerabilities data from GitHub repositories, so vulnerabilities added to `ruby-advisory-db` and `retire.js` are immediately available. The tools themselves are updated once per month if there's a new version. The [Gemnasium DB](https://gitlab.com/gitlab-org/security-products/gemnasium-db) is updated at least once a week. See our [current measurement of time from CVE being issued to our product being updated](https://about.gitlab.com/handbook/engineering/development/performance-indicators/#cve-issue-to-update). |
+| [Container Scanning](container_scanning/index.md) | Uses `clair`. The latest `clair-db` version is used for each job by running the [`latest` Docker image tag](https://gitlab.com/gitlab-org/gitlab/blob/438a0a56dc0882f22bdd82e700554525f552d91b/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml#L37). The `clair-db` database [is updated daily according to the author](https://github.com/arminc/clair-local-scan#clair-server-or-local). |
+| [Dependency Scanning](dependency_scanning/index.md) | Relies on `bundler-audit` (for Ruby gems), `retire.js` (for NPM packages), and `gemnasium` (GitLab's own tool for all libraries). Both `bundler-audit` and `retire.js` fetch their vulnerabilities data from GitHub repositories, so vulnerabilities added to `ruby-advisory-db` and `retire.js` are immediately available. The tools themselves are updated once per month if there's a new version. The [Gemnasium DB](https://gitlab.com/gitlab-org/security-products/gemnasium-db) is updated at least once a week. See our [current measurement of time from CVE being issued to our product being updated](https://about.gitlab.com/handbook/engineering/development/performance-indicators/#cve-issue-to-update). |
| [Dynamic Application Security Testing (DAST)](dast/index.md) | The scanning engine is updated on a periodic basis. See the [version of the underlying tool `zaproxy`](https://gitlab.com/gitlab-org/security-products/dast/blob/master/Dockerfile#L1). The scanning rules are downloaded at scan runtime. |
| [Static Application Security Testing (SAST)](sast/index.md) | Relies exclusively on [the tools GitLab wraps](sast/index.md#supported-languages-and-frameworks). The underlying analyzers are updated at least once per month if a relevant update is available. The vulnerabilities database is updated by the upstream tools. |
@@ -82,7 +96,7 @@ tools overrides these tags.
The Docker images are updated to match the previous GitLab releases, so users automatically get the
latest versions of the scanning tools without having to do anything. There are some known issues
with this approach, however, and there is a
-[plan to resolve them](https://gitlab.com/gitlab-org/gitlab/issues/9725).
+[plan to resolve them](https://gitlab.com/gitlab-org/gitlab/-/issues/9725).
## Interacting with the vulnerabilities
@@ -95,7 +109,7 @@ information with several options:
- [Dismiss vulnerability](#dismissing-a-vulnerability): Dismissing a vulnerability styles it in
strikethrough.
- [Create issue](#creating-an-issue-for-a-vulnerability): Create a new issue with the title and
- description prepopulated with information from the vulnerability report. By default, such issues
+ description pre-populated with information from the vulnerability report. By default, such issues
are [confidential](../project/issues/confidential_issues.md).
- [Solution](#solutions-for-vulnerabilities-auto-remediation): For some vulnerabilities,
a solution is provided for how to fix the vulnerability.
@@ -142,7 +156,7 @@ button from within the vulnerability modal, or by using the action buttons to th
a vulnerability row in the group security dashboard.
This creates a [confidential issue](../project/issues/confidential_issues.md) in the project the
-vulnerability came from, and prepopulates it with some useful information taken from the vulnerability
+vulnerability came from, and pre-populates it with some useful information taken from the vulnerability
report. Once the issue is created, you are redirected to it so you can edit, assign, or comment on
it.
@@ -153,7 +167,7 @@ to the name.
### Solutions for vulnerabilities (auto-remediation)
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/5656) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5656) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.7.
Some vulnerabilities can be fixed by applying the solution that GitLab
automatically generates. The following scanners are supported:
@@ -178,7 +192,7 @@ generated by GitLab. To apply the fix:
#### Creating a merge request from a vulnerability
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/9224) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9224) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.9.
In certain cases, GitLab allows you to create a merge request that automatically remediates the
vulnerability. Any vulnerability that has a
@@ -192,7 +206,7 @@ Click this button to create a merge request to apply the solution onto the sourc
## Security approvals in merge requests
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/9928) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.2.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9928) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.2.
Merge Request Approvals can be configured to require approval from a member of your
security team when a merge request would introduce one of the following security issues:
@@ -216,9 +230,15 @@ rating.
### Enabling Security Approvals within a project
-To enable Security Approvals, a [project approval rule](../project/merge_requests/merge_request_approvals.md#multiple-approval-rules-premium)
+To enable Security Approvals, a [project approval rule](../project/merge_requests/merge_request_approvals.md#adding--editing-a-default-approval-rule)
must be created with the case-sensitive name `Vulnerability-Check`. This approval group must be set
-with the number of approvals required greater than zero.
+with the number of approvals required greater than zero. You must have Maintainer or Owner [permissions](../permissions.md#project-members-permissions) to manage approval rules.
+
+1. Navigate to your project's **{settings}** **Settings > General** and expand **Merge request approvals**.
+1. Click **Add approval rule**, or **Edit**.
+ - Add or change the **Rule name** to `Vulnerability-Check` (case sensitive).
+
+![Vulnerability Check Approver Rule](img/vulnerability-check_v13_0.png)
Once this group is added to your project, the approval rule is enabled for all merge requests.
@@ -236,7 +256,7 @@ An approval is optional when a security report:
## Enabling License Approvals within a project
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/13067) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13067) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.3.
To enable License Approvals, a [project approval rule](../project/merge_requests/merge_request_approvals.md#multiple-approval-rules-premium)
must be created with the case-sensitive name `License-Check`. This approval group must be set
@@ -299,7 +319,7 @@ under your project's settings:
## Outdated security reports
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/4913) in GitLab 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4913) in GitLab 12.7.
When a security report generated for a merge request becomes outdated, the merge request shows a warning
message in the security widget and prompts you to take an appropriate action.
diff --git a/doc/user/application_security/offline_deployments/index.md b/doc/user/application_security/offline_deployments/index.md
index 3deb38902f2..9a2f8768fc0 100644
--- a/doc/user/application_security/offline_deployments/index.md
+++ b/doc/user/application_security/offline_deployments/index.md
@@ -1,5 +1,8 @@
---
type: reference, howto
+stage: Secure
+group: Static Analysis
+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
---
# Offline environments
@@ -49,7 +52,7 @@ you must update each of the scanners to either reference a different,
internally-hosted registry or provide access to the individual scanner images.
You must also ensure that your app has access to common package repositories
-that are not hosted on GitLab.com, such as npm, yarn, or rubygems. Packages
+that are not hosted on GitLab.com, such as npm, yarn, or Ruby gems. Packages
from these repos can be obtained by temporarily connecting to a network or by
mirroring the packages inside your own offline network.
diff --git a/doc/user/application_security/sast/analyzers.md b/doc/user/application_security/sast/analyzers.md
index 08078a66719..0aa20bf4373 100644
--- a/doc/user/application_security/sast/analyzers.md
+++ b/doc/user/application_security/sast/analyzers.md
@@ -1,3 +1,9 @@
+---
+stage: Secure
+group: Static Analysis
+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
+---
+
# SAST Analyzers **(ULTIMATE)**
SAST relies on underlying third party tools that are wrapped into what we call
@@ -139,7 +145,7 @@ The [Security Scanner Integration](../../../development/integrations/secure.md)
## Analyzers Data
-| Property \ Tool | Apex | Bandit | Brakeman | ESLint security | Find Sec Bugs | Flawfinder | Gosec | Kubesec Scanner | NodeJsScan | Php CS Security Audit | Security code Scan (.NET) | Sobelow | TSLint Security |
+| Property \ Tool | Apex | Bandit | Brakeman | ESLint security | Find Sec Bugs | Flawfinder | Gosec | Kubesec Scanner | NodeJsScan | PHP CS Security Audit | Security code Scan (.NET) | Sobelow | TSLint Security |
| --------------------------------------- | :------------------: | :------------------: | :------------------: | :------------------: | :------------------: | :------------------: | :------------------: | :------------------: | :------------------: | :---------------------: | :-------------------------: | :----------------: | :-------------: |
| Severity | ✓ | ✓ | ð„‚ | ð„‚ | ✓ | ð„‚ | ✓ | ✓ | ð„‚ | ✓ | ð„‚ | ð„‚ | ✓ |
| Title | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
diff --git a/doc/user/application_security/sast/index.md b/doc/user/application_security/sast/index.md
index 370c6d0e8e7..a5497e3d38c 100644
--- a/doc/user/application_security/sast/index.md
+++ b/doc/user/application_security/sast/index.md
@@ -1,10 +1,13 @@
---
+stage: Secure
+group: Static Analysis
+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, howto
---
# Static Application Security Testing (SAST) **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/3775) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3775) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.3.
NOTE: **4 of the top 6 attacks were application based.**
Download our whitepaper,
@@ -71,10 +74,11 @@ The following table shows which languages, package managers and frameworks are s
| .NET Framework | [Security Code Scan](https://security-code-scan.github.io) | 13.0 |
| Any | [Gitleaks](https://github.com/zricethezav/gitleaks) and [TruffleHog](https://github.com/dxa4481/truffleHog) | 11.9 |
| Apex (Salesforce) | [PMD](https://pmd.github.io/pmd/index.html) | 12.1 |
-| C/C++ | [Flawfinder](https://dwheeler.com/flawfinder/) | 10.7 |
+| C/C++ | [Flawfinder](https://github.com/david-a-wheeler/flawfinder) | 10.7 |
| Elixir (Phoenix) | [Sobelow](https://github.com/nccgroup/sobelow) | 11.10 |
| Go | [Gosec](https://github.com/securego/gosec) | 10.7 |
| Groovy ([Ant](https://ant.apache.org/), [Gradle](https://gradle.org/), [Maven](https://maven.apache.org/) and [SBT](https://www.scala-sbt.org/)) | [SpotBugs](https://spotbugs.github.io/) with the [find-sec-bugs](https://find-sec-bugs.github.io/) plugin | 11.3 (Gradle) & 11.9 (Ant, Maven, SBT) |
+| Helm Charts | [Kubesec](https://github.com/controlplaneio/kubesec) | 13.1 |
| Java ([Ant](https://ant.apache.org/), [Gradle](https://gradle.org/), [Maven](https://maven.apache.org/) and [SBT](https://www.scala-sbt.org/)) | [SpotBugs](https://spotbugs.github.io/) with the [find-sec-bugs](https://find-sec-bugs.github.io/) plugin | 10.6 (Maven), 10.8 (Gradle) & 11.9 (Ant, SBT) |
| JavaScript | [ESLint security plugin](https://github.com/nodesecurity/eslint-plugin-security) | 11.8 |
| Kubernetes manifests | [Kubesec](https://github.com/controlplaneio/kubesec) | 12.6 |
@@ -196,7 +200,7 @@ jobs.
#### Enabling Kubesec analyzer
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/12752) in GitLab Ultimate 12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12752) in GitLab Ultimate 12.6.
You need to set `SCAN_KUBERNETES_MANIFESTS` to `"true"` to enable the
Kubesec analyzer. In `.gitlab-ci.yml`, define:
@@ -285,8 +289,8 @@ Some analyzers make it possible to filter out vulnerabilities under a given thre
| Environment variable | Default value | Description |
|-------------------------|---------------|-------------|
-| `SAST_EXCLUDED_PATHS` | - | Exclude vulnerabilities from output based on the paths. This is a comma-separated list of patterns. Patterns can be globs, or file or folder paths (for example, `doc,spec` ). Parent directories will also match patterns. |
-| `SAST_BANDIT_EXCLUDED_PATHS` | - | comma-separated list of paths to exclude from scan. Uses Python's [`fnmatch` syntax](https://docs.python.org/2/library/fnmatch.html) |
+| `SAST_EXCLUDED_PATHS` | `spec, test, tests, tmp` | Exclude vulnerabilities from output based on the paths. This is a comma-separated list of patterns. Patterns can be globs, or file or folder paths (for example, `doc,spec` ). Parent directories will also match patterns. |
+| `SAST_BANDIT_EXCLUDED_PATHS` | - | comma-separated list of paths to exclude from scan. Uses Python's [`fnmatch` syntax](https://docs.python.org/2/library/fnmatch.html); For example: `'*/tests/*'` |
| `SAST_BRAKEMAN_LEVEL` | 1 | Ignore Brakeman vulnerabilities under given confidence level. Integer, 1=Low 3=High. |
| `SAST_FLAWFINDER_LEVEL` | 1 | Ignore Flawfinder vulnerabilities under given risk level. Integer, 0=No risk, 5=High risk. |
| `SAST_GITLEAKS_ENTROPY_LEVEL` | 8.0 | Minimum entropy for secret detection. Float, 0.0 = low, 8.0 = high. |
@@ -313,19 +317,22 @@ Some analyzers can be customized with environment variables.
| Environment variable | Analyzer | Description |
|-----------------------------|----------|-------------|
-| `SCAN_KUBERNETES_MANIFESTS` | Kubesec | Set to `"true"` to scan Kubernetes manifests. |
-| `ANT_HOME` | SpotBugs | The `ANT_HOME` environment variable. |
-| `ANT_PATH` | SpotBugs | Path to the `ant` executable. |
-| `GRADLE_PATH` | SpotBugs | Path to the `gradle` executable. |
-| `JAVA_OPTS` | SpotBugs | Additional arguments for the `java` executable. |
-| `JAVA_PATH` | SpotBugs | Path to the `java` executable. |
-| `SAST_JAVA_VERSION` | SpotBugs | Which Java version to use. Supported versions are `8` and `11`. Defaults to `8`. |
-| `MAVEN_CLI_OPTS` | SpotBugs | Additional arguments for the `mvn` or `mvnw` executable. |
-| `MAVEN_PATH` | SpotBugs | Path to the `mvn` executable. |
-| `MAVEN_REPO_PATH` | SpotBugs | Path to the Maven local repository (shortcut for the `maven.repo.local` property). |
-| `SBT_PATH` | SpotBugs | Path to the `sbt` executable. |
-| `FAIL_NEVER` | SpotBugs | Set to `1` to ignore compilation failure. |
-| `SAST_GOSEC_CONFIG` | Gosec | Path to configuration for Gosec (optional). |
+| `SCAN_KUBERNETES_MANIFESTS` | Kubesec | Set to `"true"` to scan Kubernetes manifests. |
+| `KUBESEC_HELM_CHARTS_PATH` | Kubesec | Optional path to Helm charts that `helm` will use to generate a Kubernetes manifest that `kubesec` will scan. If dependencies are defined, `helm dependency build` should be ran in a `before_script` to fetch the necessary dependencies. |
+| `KUBESEC_HELM_OPTIONS` | Kubesec | Additional arguments for the `helm` executable. |
+| `ANT_HOME` | SpotBugs | The `ANT_HOME` environment variable. |
+| `ANT_PATH` | SpotBugs | Path to the `ant` executable. |
+| `GRADLE_PATH` | SpotBugs | Path to the `gradle` executable. |
+| `JAVA_OPTS` | SpotBugs | Additional arguments for the `java` executable. |
+| `JAVA_PATH` | SpotBugs | Path to the `java` executable. |
+| `SAST_JAVA_VERSION` | SpotBugs | Which Java version to use. Supported versions are `8` and `11`. Defaults to `8`. |
+| `MAVEN_CLI_OPTS` | SpotBugs | Additional arguments for the `mvn` or `mvnw` executable. |
+| `MAVEN_PATH` | SpotBugs | Path to the `mvn` executable. |
+| `MAVEN_REPO_PATH` | SpotBugs | Path to the Maven local repository (shortcut for the `maven.repo.local` property). |
+| `SBT_PATH` | SpotBugs | Path to the `sbt` executable. |
+| `FAIL_NEVER` | SpotBugs | Set to `1` to ignore compilation failure. |
+| `SAST_GOSEC_CONFIG` | Gosec | Path to configuration for Gosec (optional). |
+| `PHPCS_SECURITY_AUDIT_PHP_EXTENSIONS` | phpcs-security-audit | Comma separated list of additional PHP Extensions. |
#### Custom environment variables
@@ -342,11 +349,10 @@ analyzer containers: `DOCKER_`, `CI`, `GITLAB_`, `FF_`, `HOME`, `PWD`, `OLDPWD`,
## Reports JSON format
-CAUTION: **Caution:**
-The JSON report artifacts are not a public API of SAST and their format may change in the future.
+The SAST tool emits a JSON report file. For more information, see the
+[schema for this report](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/blob/master/dist/sast-report-format.json).
-The SAST tool emits a JSON report file. Here is an example of the report structure with all important parts of
-it highlighted:
+Here's an example SAST report:
```json-doc
{
@@ -421,40 +427,6 @@ it highlighted:
}
```
-CAUTION: **Deprecation:**
-Beginning with GitLab 12.9, SAST no longer reports `undefined` severity and confidence levels.
-
-Here is the description of the report file structure nodes and their meaning. All fields are mandatory in
-the report JSON unless stated otherwise. Presence of optional fields depends on the underlying analyzers being used.
-
-| Report JSON node | Function |
-|-----------------------------------------|----------|
-| `version` | Report syntax version used to generate this JSON. |
-| `vulnerabilities` | Array of vulnerability objects. |
-| `vulnerabilities[].id` | Unique identifier of the vulnerability. |
-| `vulnerabilities[].category` | Where this vulnerability belongs (such as SAST, Dependency Scanning). For SAST, it will always be `sast`. |
-| `vulnerabilities[].name` | Name of the vulnerability. Must not include the occurrence's specific information. Optional. |
-| `vulnerabilities[].message` | A short text that describes the vulnerability, it may include the occurrence's specific information. Optional. |
-| `vulnerabilities[].description` | A long text that describes the vulnerability. Optional. |
-| `vulnerabilities[].cve` | (**DEPRECATED - use `vulnerabilities[].id` instead**) A fingerprint string value that represents a concrete occurrence of the vulnerability. It's used to determine whether two vulnerability occurrences are same or different. May not be 100% accurate. **This is NOT a [CVE](https://cve.mitre.org/)**. |
-| `vulnerabilities[].severity` | How much the vulnerability impacts the software. Possible values: `Info`, `Unknown`, `Low`, `Medium`, `High`, `Critical`. |
-| `vulnerabilities[].confidence` | How reliable the vulnerability's assessment is. Possible values: `Ignore`, `Unknown`, `Experimental`, `Low`, `Medium`, `High`, `Confirmed`. |
-| `vulnerabilities[].solution` | Explanation of how to fix the vulnerability. Optional. |
-| `vulnerabilities[].scanner` | A node that describes the analyzer used to find this vulnerability. |
-| `vulnerabilities[].scanner.id` | ID of the scanner as a snake_case string. |
-| `vulnerabilities[].scanner.name` | Name of the scanner, for display purposes. |
-| `vulnerabilities[].location` | A node that tells where the vulnerability is located. |
-| `vulnerabilities[].location.file` | Path to the file where the vulnerability is located. Optional. |
-| `vulnerabilities[].location.start_line` | The first line of the code affected by the vulnerability. Optional. |
-| `vulnerabilities[].location.end_line` | The last line of the code affected by the vulnerability. Optional. |
-| `vulnerabilities[].location.class` | If specified, provides the name of the class where the vulnerability is located. Optional. |
-| `vulnerabilities[].location.method` | If specified, provides the name of the method where the vulnerability is located. Optional. |
-| `vulnerabilities[].identifiers` | An ordered array of references that identify a vulnerability on internal or external databases. |
-| `vulnerabilities[].identifiers[].type` | Type of the identifier. Possible values: common identifier types (among `cve`, `cwe`, `osvdb`, and `usn`) or analyzer-dependent ones (like `bandit_test_id` for [Bandit analyzer](https://wiki.openstack.org/wiki/Security/Projects/Bandit)). |
-| `vulnerabilities[].identifiers[].name` | Name of the identifier for display purposes. |
-| `vulnerabilities[].identifiers[].value` | Value of the identifier for matching purposes. |
-| `vulnerabilities[].identifiers[].url` | URL to identifier's documentation. Optional. |
-
## Secret detection
Learn more about [Secret Detection](../secret_detection).
@@ -513,7 +485,6 @@ 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/go-ast-scanner: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
@@ -553,9 +524,9 @@ security reports without requiring internet access.
## Troubleshooting
-### Error response from daemon: error processing tar file: docker-tar: relocation error
+### `Error response from daemon: error processing tar file: docker-tar: relocation error`
This error occurs when the Docker version that runs the SAST job is `19.03.0`.
Consider updating to Docker `19.03.1` or greater. Older versions are not
affected. Read more in
-[this issue](https://gitlab.com/gitlab-org/gitlab/issues/13830#note_211354992 "Current SAST container fails").
+[this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/13830#note_211354992 "Current SAST container fails").
diff --git a/doc/user/application_security/secret_detection/index.md b/doc/user/application_security/secret_detection/index.md
index 74dd3c89984..85933c31a34 100644
--- a/doc/user/application_security/secret_detection/index.md
+++ b/doc/user/application_security/secret_detection/index.md
@@ -1,5 +1,8 @@
---
type: reference, howto
+stage: Secure
+group: Static Analysis
+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
---
# Secret Detection **(ULTIMATE)**
@@ -26,18 +29,30 @@ GitLab displays identified secrets as part of the SAST reports visibly in a few
## Use cases
-- Detecting accidental commit of secrets like keys, passwords, and API tokens.
+- Detecting unintentional commit of secrets like keys, passwords, and API tokens.
- Performing a single or recurring scan of the full history of your repository for secrets.
+## Requirements
+
+To run Secret Detection jobs, by default, you need GitLab Runner with the
+[`docker`](https://docs.gitlab.com/runner/executors/docker.html) or
+[`kubernetes`](https://docs.gitlab.com/runner/install/kubernetes.html) executor.
+If you're using the shared Runners on GitLab.com, this is enabled by default.
+
+CAUTION: **Caution:** Our Secret Detection jobs currently expect a Linux container type. Windows containers are not yet supported.
+
+CAUTION: **Caution:**
+If you use your own Runners, make sure the Docker version installed
+is **not** `19.03.0`. See [troubleshooting information](../sast#error-response-from-daemon-error-processing-tar-file-docker-tar-relocation-error) for details.
+
## Configuration
-If you already have SAST enabled for your app, you don’t need to take any action to benefit from this
-new feature. It is also included in the Auto DevOps default configuration.
+NOTE: **Note:**
+With GitLab 13.1 Secret Detection was split into its own CI/CD template.
-Secret Detection is performed by a [specific analyzer](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml#L180)
-during the `sast` job. It runs regardless of the programming
-language of your app, and you don't need to change your
-CI/CD configuration file to enable it. Results are available in the SAST report.
+Secret Detection is performed by a [specific analyzer](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/Secret-Detection.gitlab-ci.yml)
+during the `secret-detection` job. It runs regardless of the programming
+language of your app.
The Secret Detection analyzer includes [Gitleaks](https://github.com/zricethezav/gitleaks) and [TruffleHog](https://github.com/dxa4481/truffleHog) checks.
@@ -47,15 +62,99 @@ with a dollar sign (`$`) as this likely indicates the password being used is an
variable. For example, `https://username:$password@example.com/path/to/repo` won't be
detected, whereas `https://username:password@example.com/path/to/repo` would be detected.
+NOTE: **Note:**
+You don't have to configure Secret Detection manually as shown in this section if you're using [Auto Secret Detection](../../../topics/autodevops/stages.md#auto-secret-detection-ultimate)
+provided by [Auto DevOps](../../../topics/autodevops/index.md).
+
+To enable Secret Detection for GitLab 13.1 and later, you must include the `Secret-Detection.gitlab-ci.yml` template that’s provided as a part of your GitLab installation. For GitLab versions earlier than 11.9, you can copy and use the job as defined in that template.
+
+Add the following to your `.gitlab-ci.yml` file:
+
+```yaml
+include:
+ - template: Secret-Detection.gitlab-ci.yml
+```
+
+The included template creates Secret Detection jobs in your CI/CD pipeline and scans
+your project's source code for secrets.
+
+The results are saved as a
+[Secret Detection report artifact](../../../ci/pipelines/job_artifacts.md#artifactsreportssecret_detection-ultimate)
+that you can later download and analyze. Due to implementation limitations, we
+always take the latest Secret Detection artifact available.
+
+### Using the SAST Template
+
+Prior to GitLab 13.1, Secret Detection was part of [SAST configuration](../sast#configuration).
+If you already have SAST enabled for your app configured before GitLab 13.1,
+you don't need to manually configure it.
+
+CAUTION: **Planned Deprecation:**
+In a future GitLab release, configuring Secret Detection with the SAST template will be deprecated. Please begin using `Secret-Detection.gitlab-ci.yml`
+to prevent future issues. We have made a
+[video to guide you through the process of transitioning](https://www.youtube.com/watch?v=W2tjcQreDwQ)
+to this new template.
+
+<div class="video-fallback">
+ See the video: <a href="https://www.youtube.com/watch?v=W2tjcQreDwQ">Walkthrough of historical secret scan</a>.
+</div>
+<figure class="video-container">
+ <iframe src="https://www.youtube.com/embed/W2tjcQreDwQ" frameborder="0" allowfullscreen="true"> </iframe>
+</figure>
+
+When using the SAST template, Secret Detection is performed by a [specific analyzer](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml#L180)
+during the `sast` job. It runs regardless of the programming
+language of your app, and you don't need to change your
+CI/CD configuration file to enable it. Results are available in the SAST report.
+
+### Customizing settings
+
+The Secret Detection scan settings can be changed through [environment variables](#available-variables)
+by using the
+[`variables`](../../../ci/yaml/README.md#variables) parameter in `.gitlab-ci.yml`.
+
+To override a job definition, (for example, change properties like `variables` or `dependencies`),
+declare a job with the same name as the SAST job to override. Place this new job after the template
+inclusion and specify any additional keys under it.
+
+In the following example, we include the Secret Detection template and at the same time we
+override the `secret-scan` job with the `SECRET_DETECTION_HISTORIC_SCAN` variable to `true`:
+
+```yaml
+include:
+ - template: Secret-Detection.gitlab-ci.yml
+
+secrets-scan:
+ variables:
+ SECRET_DETECTION_HISTORIC_SCAN: true
+```
+
+Because the template is [evaluated before](../../../ci/yaml/README.md#include)
+the pipeline configuration, the last mention of the variable takes precedence.
+
+CAUTION: **Deprecation:**
+Beginning in GitLab 13.0, the use of [`only` and `except`](../../../ci/yaml/README.md#onlyexcept-basic)
+is no longer supported. When overriding the template, you must use [`rules`](../../../ci/yaml/README.md#rules) instead.
+
+#### Available variables
+
+Secret Detection can be customized by defining available variables:
+
+| Environment variable | Default value | Description |
+|-------------------------|---------------|-------------|
+| `SECRET_DETECTION_COMMIT_FROM` | - | The commit a Gitleaks scan starts at. |
+| `SECRET_DETECTION_COMMIT_TO` | - | The commit a Gitleaks scan ends at. |
+| `SECRET_DETECTION_HISTORIC_SCAN` | false | Flag to enable a historic Gitleaks scan. |
+
## Full History Secret Scan
-GitLab 12.11 introduced support for scanning the full history of a reposity. This new functionality
+GitLab 12.11 introduced support for scanning the full history of a repository. This new functionality
is particularly useful when you are enabling Secret Detection in a repository for the first time and you
want to perform a full secret scan. Running a secret scan on the full history can take a long time,
especially for larger repositories with lengthy Git histories. We recommend not setting this variable
-as part of your normal job defintion.
+as part of your normal job definition.
-A new configuration variable ([`SAST_GITLEAKS_HISTORIC_SCAN`](../sast/#vulnerability-filters))
+A new configuration variable ([`SECRET_DETECTION_HISTORIC_SCAN`](../sast/#vulnerability-filters))
can be set to change the behavior of the GitLab Secret Detection scan to run on the entire Git history of a repository.
We have created a [short video walkthrough](https://youtu.be/wDtc_K00Y0A) showcasing how you can perform a full history secret scan.
diff --git a/doc/user/application_security/security_dashboard/img/group_security_dashboard_export_csv_v13_1.png b/doc/user/application_security/security_dashboard/img/group_security_dashboard_export_csv_v13_1.png
new file mode 100644
index 00000000000..0dfe7b637cd
--- /dev/null
+++ b/doc/user/application_security/security_dashboard/img/group_security_dashboard_export_csv_v13_1.png
Binary files differ
diff --git a/doc/user/application_security/security_dashboard/img/group_security_dashboard_v13_0.png b/doc/user/application_security/security_dashboard/img/group_security_dashboard_v13_0.png
index c788e2165ad..4c7b5cc724f 100644
--- a/doc/user/application_security/security_dashboard/img/group_security_dashboard_v13_0.png
+++ b/doc/user/application_security/security_dashboard/img/group_security_dashboard_v13_0.png
Binary files differ
diff --git a/doc/user/application_security/security_dashboard/img/project_security_dashboard_v13_0.png b/doc/user/application_security/security_dashboard/img/project_security_dashboard_v13_0.png
index bb88b7f371c..878bb83c2a2 100644
--- a/doc/user/application_security/security_dashboard/img/project_security_dashboard_v13_0.png
+++ b/doc/user/application_security/security_dashboard/img/project_security_dashboard_v13_0.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 2988b3642ef..60798b9c921 100644
--- a/doc/user/application_security/security_dashboard/index.md
+++ b/doc/user/application_security/security_dashboard/index.md
@@ -36,7 +36,7 @@ To use the instance, group, project, or pipeline security dashboard:
## 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 Ultimate](https://about.gitlab.com/pricing/) 12.3.
At the pipeline level, the Security section displays the vulnerabilities present in the branch of the project the pipeline was run against.
@@ -49,7 +49,7 @@ A pipeline consists of multiple jobs, including SAST and DAST scanning. If any j
## Project Security Dashboard
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/6165) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.1.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/6165) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.1.
At the project level, the Security Dashboard displays the latest security reports for your project.
Use it to find and fix vulnerabilities.
@@ -70,7 +70,7 @@ of thousands of vulnerabilities. Do not close the page until the download finish
## 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 Ultimate](https://about.gitlab.com/pricing/) 11.5.
The group Security Dashboard gives an overview of the vulnerabilities of all the
projects in a group and its subgroups.
@@ -120,9 +120,24 @@ vulnerabilities are not included either.
Read more on how to [interact with the vulnerabilities](../index.md#interacting-with-the-vulnerabilities).
+### Export vulnerabilities
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/213013) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.1.
+
+You can export all your vulnerabilities as CSV by clicking the **{upload}** **Export** button
+located at the top right of the **Group Security Dashboard**. After the report builds, the CSV
+report downloads to your local machine. The report contains all vulnerabilities for the projects
+defined in the **Group Security Dashboard**, as filters don't apply to the export function.
+
+NOTE: **Note:**
+It may take several minutes for the download to start if your project contains thousands of
+vulnerabilities. Don't close the page until the download finishes.
+
+![CSV Export Button](img/group_security_dashboard_export_csv_v13_1.png)
+
## Instance Security Dashboard
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/6953) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/6953) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.8.
At the instance level, the Security Dashboard displays the vulnerabilities
present in all of the projects that you have added to it. It includes all
diff --git a/doc/user/application_security/threat_monitoring/index.md b/doc/user/application_security/threat_monitoring/index.md
index 7bd148edd15..434048896fe 100644
--- a/doc/user/application_security/threat_monitoring/index.md
+++ b/doc/user/application_security/threat_monitoring/index.md
@@ -1,14 +1,18 @@
---
type: reference, howto
+stage: Defend
+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
---
# Threat Monitoring **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/14707) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.9.
+> [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 for the GitLab
-application runtime security features. You can access these metrics by
-navigating to your project's **Security & Compliance > Threat Monitoring** page.
+The **Threat Monitoring** page provides metrics and policy management
+for the GitLab application runtime security features. You can access
+these by navigating to your project's **Security & Compliance > Threat
+Monitoring** page.
GitLab supports statistics for the following security features:
@@ -42,7 +46,7 @@ investigate it for potential threats by
## Container Network Policy
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/32365) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.9.
+> [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
@@ -74,3 +78,41 @@ about your packet flow:
If a significant percentage of packets is dropped, you should
investigate it for potential threats by
[examining the Cilium logs](../../clusters/applications.md#install-cilium-using-gitlab-cicd).
+
+## 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 and toggle the policy's enforcement
+status. This section has the following prerequisites:
+
+- Your project contains at least one [environment](../../../ci/environments/index.md)
+- You've [installed Cilium](../../clusters/applications.md#install-cilium-using-gitlab-cicd)
+
+Network policies are fetched directly from the selected environment's
+deployment platform. Changes performed outside of this tab are
+reflected upon refresh. Enforcement status changes are deployed
+directly to a deployment namespace of the selected environment.
+
+NOTE: **Note:**
+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 **Enforcement status** toggle to update the selected policy.
+- Click the **Apply changes** button to deploy network policy changes.
+
+NOTE: **Note:**
+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.
diff --git a/doc/user/application_security/vulnerabilities/img/standalone_vulnerability_page_download_patch_button_v13_1.png b/doc/user/application_security/vulnerabilities/img/standalone_vulnerability_page_download_patch_button_v13_1.png
new file mode 100644
index 00000000000..b925c342a11
--- /dev/null
+++ b/doc/user/application_security/vulnerabilities/img/standalone_vulnerability_page_download_patch_button_v13_1.png
Binary files differ
diff --git a/doc/user/application_security/vulnerabilities/img/standalone_vulnerability_page_merge_request_button_dropdown_v13_1.png b/doc/user/application_security/vulnerabilities/img/standalone_vulnerability_page_merge_request_button_dropdown_v13_1.png
new file mode 100644
index 00000000000..2063762d3eb
--- /dev/null
+++ b/doc/user/application_security/vulnerabilities/img/standalone_vulnerability_page_merge_request_button_dropdown_v13_1.png
Binary files differ
diff --git a/doc/user/application_security/vulnerabilities/img/standalone_vulnerability_page_merge_request_button_v13_1.png b/doc/user/application_security/vulnerabilities/img/standalone_vulnerability_page_merge_request_button_v13_1.png
new file mode 100644
index 00000000000..ee4e97bcafe
--- /dev/null
+++ b/doc/user/application_security/vulnerabilities/img/standalone_vulnerability_page_merge_request_button_v13_1.png
Binary files differ
diff --git a/doc/user/application_security/vulnerabilities/index.md b/doc/user/application_security/vulnerabilities/index.md
index b691a97fc32..b3128e49980 100644
--- a/doc/user/application_security/vulnerabilities/index.md
+++ b/doc/user/application_security/vulnerabilities/index.md
@@ -1,10 +1,13 @@
---
type: reference, howto
+stage: Secure
+group: Vulnerability Research
+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
---
# Standalone Vulnerability pages
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/13561) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.0.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13561) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.0.
Each security vulnerability in the [Vulnerability List](../dependency_list/index.md) has its own standalone
page.
@@ -17,7 +20,7 @@ several different ways:
- [Change the Vulnerability Status](#changing-vulnerability-status) - You can change the
status of a vulnerability to **Detected**, **Confirmed**, **Dismissed**, or **Resolved**.
- [Create issue](#creating-an-issue-for-a-vulnerability) - Create a new issue with the
- title and description prepopulated with information from the vulnerability report.
+ title and description pre-populated with information from the vulnerability report.
By default, such issues are [confidential](../../project/issues/confidential_issues.md).
- [Solution](#automatic-remediation-solutions-for-vulnerabilities) - For some vulnerabilities,
a solution is provided for how to fix the vulnerability.
@@ -39,7 +42,7 @@ the following values:
You can create an issue for a vulnerability by selecting the **Create issue** button.
This creates a [confidential issue](../../project/issues/confidential_issues.md) in the
-project the vulnerability came from, and prepopulates it with useful information from
+project the vulnerability came from, and pre-populates it with useful information from
the vulnerability report. After the issue is created, GitLab redirects you to the
issue page so you can edit, assign, or comment on the issue.
@@ -52,14 +55,19 @@ generates for you. GitLab supports the following scanners:
is only available for Node.js projects managed with `yarn`.
- [Container Scanning](../container_scanning/index.md).
+When an automatic solution is available, the button in the header will show "Resolve with merge request":
+
+![Resolve with Merge Request button](img/standalone_vulnerability_page_merge_request_button_v13_1.png)
+
+Selecting the button will create a merge request with the automatic solution.
+
### Manually applying a suggested patch
-To apply a patch automatically generated by GitLab to fix a vulnerability:
+To manually apply the patch that was generated by GitLab for a vulnerability, select the dropdown arrow on the "Resolve
+with merge request" button, then select the "Download patch to resolve" option:
+
+![Resolve with Merge Request button dropdown](img/standalone_vulnerability_page_merge_request_button_dropdown_v13_1.png)
-1. Open the issue created in [Create issue](#creating-an-issue-for-a-vulnerability).
-1. In the **Issue description**, scroll to **Solution** and download the linked patch file.
-1. Ensure your local project has the same commit checked out that was used to generate the patch.
-1. Run `git apply remediation.patch` to apply the patch.
-1. Verify and commit the changes to your branch.
+This will change the button text to "Download patch to resolve". Click on it to download the patch:
-![Apply patch for dependency scanning](../img/vulnerability_solution.png)
+![Download patch button](img/standalone_vulnerability_page_download_patch_button_v13_1.png)
diff --git a/doc/user/award_emojis.md b/doc/user/award_emojis.md
index 5a82712c055..47249a44bc1 100644
--- a/doc/user/award_emojis.md
+++ b/doc/user/award_emojis.md
@@ -1,9 +1,15 @@
+---
+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/#designated-technical-writers
+---
+
# Award emoji
-> - First [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/1825) in GitLab 8.2.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/1825) in GitLab 8.2.
> - GitLab 9.0 [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/9570) the usage of native emoji if the platform
-> supports them and falls back to images or CSS sprites. This change greatly
-> improved award emoji performance overall.
+> supports them and falls back to images or CSS sprites. This change greatly
+> improved award emoji performance overall.
When you're collaborating online, you get fewer opportunities for high-fives
and thumbs-ups. Emoji can be awarded to [issues](project/issues/index.md), [merge requests](project/merge_requests/index.md),
diff --git a/doc/user/clusters/applications.md b/doc/user/clusters/applications.md
index 9ede9d9fdef..86624d12bcf 100644
--- a/doc/user/clusters/applications.md
+++ b/doc/user/clusters/applications.md
@@ -332,7 +332,7 @@ Updating [Ingress](#ingress) to the most recent version enables you to take adva
##### Viewing Web Application Firewall traffic
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/14707) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14707) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.9.
You can view Web Application Firewall traffic by navigating to your project's
**Security & Compliance > Threat Monitoring** page.
@@ -458,7 +458,7 @@ file.
### Crossplane
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/34702) in GitLab 12.5 for project-level clusters.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34702) in GitLab 12.5 for project-level clusters.
[Crossplane](https://crossplane.github.io/docs/v0.9/) is a multi-cloud control plane useful for
managing applications and infrastructure across multiple clouds. It extends the
@@ -483,7 +483,7 @@ For information on configuring Crossplane installed on the cluster, see
[Crossplane configuration](crossplane.md).
NOTE: **Note:**
-[`alpha/crossplane`](https://charts.crossplane.io/alpha/) chart v0.4.1 is used to
+[`alpha/crossplane`](https://github.com/crossplane/crossplane/tree/v0.4.1/cluster/charts/crossplane) chart v0.4.1 is used to
install Crossplane using the
[`values.yaml`](https://github.com/crossplane/crossplane/blob/master/cluster/charts/crossplane/values.yaml.tmpl)
file.
@@ -615,6 +615,8 @@ Supported applications:
- [Crossplane](#install-crossplane-using-gitlab-cicd)
- [Fluentd](#install-fluentd-using-gitlab-cicd)
- [Knative](#install-knative-using-gitlab-cicd)
+- [PostHog](#install-posthog-using-gitlab-cicd)
+- [Prometheus](#install-prometheus-using-gitlab-cicd)
### Usage
@@ -779,6 +781,77 @@ postgresql:
postgresqlPassword: example-postgresql-password
```
+### Install PostHog using GitLab CI/CD
+
+[PostHog](https://www.posthog.com) 🦔 is a developer-friendly, open-source product analytics platform.
+
+To install PostHog into the `gitlab-managed-apps` namespace of your cluster,
+define the `.gitlab/managed-apps/config.yaml` file with:
+
+```yaml
+posthog:
+ installed: true
+```
+
+You can customize the installation of PostHog by defining `.gitlab/managed-apps/posthog/values.yaml`
+in your cluster management project. Refer to the [Configuration section of the PostHog chart's README](https://github.com/PostHog/charts/tree/master/charts/posthog)
+for the available configuration options.
+
+NOTE: **Note:**
+You must provide a PostgreSQL password in `postgresql.postgresqlPassword`
+or you will receive authentication errors.
+See the [PostgreSQL chart documentation](https://github.com/helm/charts/tree/master/stable/postgresql#upgrade) for more information.
+
+Redis pods are restarted between upgrades. To prevent downtime, provide a Redis
+password using the `redis.password` key. This prevents a new password from
+being generated on each restart.
+
+Here is an example configuration for PostHog:
+
+```yaml
+ingress:
+ enabled: true
+ hostname: "<posthog.example.com>"
+
+# This will be autogenerated if you skip it. Include if you have 2 or more web replicas
+posthogSecret: 'long-secret-key-used-to-sign-cookies'
+
+# Needs to be here between runs.
+# See https://github.com/helm/charts/tree/master/stable/postgresql#upgrade for more info
+postgresql:
+ postgresqlPassword: example-postgresql-password
+
+# Recommended to set this to a value to redis prevent downtime between upgrades
+redis:
+ password: example-redis-password
+```
+
+NOTE: **Note:**
+Support for the PostHog managed application is provided by the PostHog team.
+If you run into issues, please [open a support ticket](https://github.com/PostHog/posthog/issues/new/choose) directly.
+
+### Install Prometheus using GitLab CI/CD
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25138) in GitLab 12.8.
+
+[Prometheus](https://prometheus.io/docs/introduction/overview/) is an
+open-source monitoring and alerting system for supervising your
+deployed applications.
+
+To install Prometheus into the `gitlab-managed-apps` namespace of your cluster,
+define the `.gitlab/managed-apps/config.yaml` file with:
+
+```yaml
+prometheus:
+ installed: true
+```
+
+You can customize the installation of Prometheus by defining
+`.gitlab/managed-apps/prometheus/values.yaml` in your cluster management
+project. Refer to the
+[Configuration section of the Prometheus chart's README](https://github.com/helm/charts/tree/master/stable/prometheus#configuration)
+for the available configuration options.
+
### Install GitLab Runner using GitLab CI/CD
GitLab Runner is installed using GitLab CI/CD by defining configuration in
@@ -857,10 +930,10 @@ Major upgrades might require additional setup steps, please consult
the official [upgrade guide](https://docs.cilium.io/en/stable/install/upgrade/) for more
information.
-By default, Cilium will drop all non-whitelisted packets upon policy
+By default, Cilium will drop all disallowed packets upon policy
deployment. The audit mode is scheduled for release in
[Cilium 1.8](https://github.com/cilium/cilium/pull/9970). In the audit
-mode, non-whitelisted packets will not be dropped, and audit
+mode, disallowed packets will not be dropped, and audit
notifications will be generated instead. GitLab provides alternative Docker
images for Cilium with the audit patch included. You can switch to the
custom build and enable the audit mode by adding the following to
@@ -915,7 +988,7 @@ metrics:
### Install Vault using GitLab CI/CD
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/9982) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9982) in GitLab 12.9.
[Hashicorp Vault](https://www.vaultproject.io/) is a secrets management solution which
can be used to safely manage and store passwords, credentials, certificates and more. A Vault
@@ -940,17 +1013,17 @@ when upgrading the Vault application.
To optimally use Vault in a production environment, it's ideal to have a good understanding
of the internals of Vault and how to configure it. This can be done by reading the
-[the Vault documentation](https://www.vaultproject.io/docs/internals/) as well as
+[the Vault documentation](https://www.vaultproject.io/docs/internals) as well as
the Vault Helm chart [`values.yaml` file](https://github.com/hashicorp/vault-helm/blob/v0.3.3/values.yaml).
At a minimum you will likely set up:
-- A [seal](https://www.vaultproject.io/docs/configuration/seal/) for extra encryption
+- A [seal](https://www.vaultproject.io/docs/configuration/seal) for extra encryption
of the master key.
-- A [storage backend](https://www.vaultproject.io/docs/configuration/storage/) that is
+- A [storage backend](https://www.vaultproject.io/docs/configuration/storage) that is
suitable for environment and storage security requirements.
-- [HA Mode](https://www.vaultproject.io/docs/concepts/ha/).
-- [The Vault UI](https://www.vaultproject.io/docs/configuration/ui/).
+- [HA Mode](https://www.vaultproject.io/docs/concepts/ha).
+- [The Vault UI](https://www.vaultproject.io/docs/configuration/ui).
The following is an example values file (`.gitlab/managed-apps/vault/values.yaml`)
that configures Google Key Management Service for auto-unseal, using a Google Cloud Storage backend, enabling
@@ -1048,12 +1121,12 @@ You can customize the installation of JupyterHub by defining a
`.gitlab/managed-apps/jupyterhub/values.yaml` file in your cluster management project.
Refer to the
-[chart reference](https://zero-to-jupyterhub.readthedocs.io/en/stable/reference.html) for the
+[chart reference](https://zero-to-jupyterhub.readthedocs.io/en/stable/reference/reference.html) for the
available configuration options.
### Install Elastic Stack using GitLab CI/CD
-> [Introduced](https://gitlab.com/gitlab-org/cluster-integration/cluster-applications/-/merge_requests/45) in GitLab 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25138) in GitLab 12.8.
Elastic Stack is installed using GitLab CI/CD by defining configuration in
`.gitlab/managed-apps/config.yaml`.
@@ -1080,7 +1153,7 @@ In this alpha implementation of installing Elastic Stack through CI, reading the
### Install Crossplane using GitLab CI/CD
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/35675) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35675) in GitLab 12.9.
Crossplane is installed using GitLab CI/CD by defining configuration in
`.gitlab/managed-apps/config.yaml`.
@@ -1157,7 +1230,7 @@ GitLab provides [Invocation Metrics](../project/clusters/serverless/index.md#inv
1. Knative and Prometheus managed applications installed on your cluster.
1. Manually applied the custom metrics on your cluster by running the following command:
- ```bash
+ ```shell
kubectl apply -f https://gitlab.com/gitlab-org/cluster-integration/cluster-applications/-/raw/02c8231e30ef5b6725e6ba368bc63863ceb3c07d/src/default-data/knative/istio-metrics.yaml
```
@@ -1166,7 +1239,7 @@ GitLab provides [Invocation Metrics](../project/clusters/serverless/index.md#inv
To uninstall Knative, you must first manually remove any custom metrics you have added
by running the following command:
-```bash
+```shell
kubectl delete -f https://gitlab.com/gitlab-org/cluster-integration/cluster-applications/-/raw/02c8231e30ef5b6725e6ba368bc63863ceb3c07d/src/default-data/knative/istio-metrics.yaml
```
@@ -1197,7 +1270,7 @@ chart plus the values set by
## Uninstalling applications
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/60665) in GitLab 11.11.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/60665) in GitLab 11.11.
The applications below can be uninstalled.
diff --git a/doc/user/clusters/crossplane.md b/doc/user/clusters/crossplane.md
index a9a5f768ec8..3a430ad55bd 100644
--- a/doc/user/clusters/crossplane.md
+++ b/doc/user/clusters/crossplane.md
@@ -151,7 +151,7 @@ kubectl describe globaladdress.compute.gcp.crossplane.io gitlab-ad-globaladdress
Resource classes are a way of defining a configuration for the required managed service. We will define the PostgreSQL Resource class
-- Define a `gcp-postgres-standard.yaml` resourceclass which contains
+- Define a `gcp-postgres-standard.yaml` resource class which contains
1. A default CloudSQLInstanceClass.
1. A CloudSQLInstanceClass with labels.
diff --git a/doc/user/clusters/environments.md b/doc/user/clusters/environments.md
index a2adf238dda..2b342ceb06d 100644
--- a/doc/user/clusters/environments.md
+++ b/doc/user/clusters/environments.md
@@ -6,8 +6,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Cluster Environments **(PREMIUM)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/13392) for group-level clusters in [GitLab Premium](https://about.gitlab.com/pricing/) 12.3.
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/14809) for instance-level clusters in [GitLab Premium](https://about.gitlab.com/pricing/) 12.4.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13392) for group-level clusters in [GitLab Premium](https://about.gitlab.com/pricing/) 12.3.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14809) for instance-level clusters in [GitLab Premium](https://about.gitlab.com/pricing/) 12.4.
Cluster environments provide a consolidated view of which CI [environments](../../ci/environments/index.md) are
deployed to the Kubernetes cluster and it:
diff --git a/doc/user/clusters/management_project.md b/doc/user/clusters/management_project.md
index 03b4dc45015..c8755af29a3 100644
--- a/doc/user/clusters/management_project.md
+++ b/doc/user/clusters/management_project.md
@@ -10,7 +10,7 @@ CAUTION: **Warning:**
This is an _alpha_ feature, and it is subject to change at any time without
prior notice.
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/32810) in GitLab 12.5
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32810) in GitLab 12.5
A project can be designated as the management project for a cluster.
A management project can be used to run deployment jobs with
diff --git a/doc/user/compliance/compliance_dashboard/index.md b/doc/user/compliance/compliance_dashboard/index.md
index 25feb6e56bc..08a26a45b17 100644
--- a/doc/user/compliance/compliance_dashboard/index.md
+++ b/doc/user/compliance/compliance_dashboard/index.md
@@ -1,10 +1,13 @@
---
type: reference, howto
+stage: Manage
+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/#designated-technical-writers
---
# Compliance Dashboard **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/36524) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/36524) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.8.
The Compliance Dashboard gives you the ability to see a group's Merge Request activity
by providing a high-level view for all projects in the group. For example, code approved
diff --git a/doc/user/compliance/index.md b/doc/user/compliance/index.md
index fd4af74e086..d0e73b47358 100644
--- a/doc/user/compliance/index.md
+++ b/doc/user/compliance/index.md
@@ -1,3 +1,10 @@
+---
+type: reference
+stage: Manage
+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/#designated-technical-writers
+---
+
# Compliance **(ULTIMATE)**
The compliance tools provided by GitLab let you keep an eye on various aspects of your project. The
diff --git a/doc/user/compliance/license_compliance/index.md b/doc/user/compliance/license_compliance/index.md
index cbabed00283..4ceb393af8c 100644
--- a/doc/user/compliance/license_compliance/index.md
+++ b/doc/user/compliance/license_compliance/index.md
@@ -1,10 +1,13 @@
---
type: reference, howto
+stage: Secure
+group: Composition Analysis
+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
---
# License Compliance **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/5483) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.0.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5483) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.0.
## Overview
@@ -61,10 +64,14 @@ The following languages and package managers are supported.
| Go | [Godep](https://github.com/tools/godep), [go mod](https://github.com/golang/go/wiki/Modules) |[License Finder](https://github.com/pivotal/LicenseFinder)|
| Java | [Gradle](https://gradle.org/), [Maven](https://maven.apache.org/) |[License Finder](https://github.com/pivotal/LicenseFinder)|
| .NET | [Nuget](https://www.nuget.org/) (.NET Framework is supported via the [mono project](https://www.mono-project.com/). Windows specific dependencies are not supported at this time.) |[License Finder](https://github.com/pivotal/LicenseFinder)|
-| Python | [pip](https://pip.pypa.io/en/stable/) (Python is supported through [requirements.txt](https://pip.readthedocs.io/en/1.1/requirements.html) and [Pipfile.lock](https://github.com/pypa/pipfile#pipfilelock).) |[License Finder](https://github.com/pivotal/LicenseFinder)|
+| Python | [pip](https://pip.pypa.io/en/stable/) (Python is supported through [requirements.txt](https://pip.pypa.io/en/1.1/requirements/) and [Pipfile.lock](https://github.com/pypa/pipfile#pipfilelock).) |[License Finder](https://github.com/pivotal/LicenseFinder)|
| Ruby | [gem](https://rubygems.org/) |[License Finder](https://github.com/pivotal/LicenseFinder)|
| Objective-C, Swift | [Carthage](https://github.com/Carthage/Carthage) |[License Finder](https://github.com/pivotal/LicenseFinder)|
+NOTE: **Note:**
+
+Java 8 and Gradle 1.x projects are not supported.
+
### Experimental support
The following languages and package managers are [supported experimentally](https://github.com/pivotal/LicenseFinder#experimental-project-types),
@@ -135,14 +142,18 @@ License Compliance can be configured using environment variables.
| Environment variable | Required | Description |
|-----------------------------|----------|-------------|
-| `SECURE_ANALYZERS_PREFIX` | no | Set the Docker registry base address to download the analyzer from. |
| `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_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 your project has both Golang and Ruby code stored in different directories and you want to only scan the Ruby code, you can update your `.gitlab-ci-yml` template to specify which project directories to scan, like `LICENSE_FINDER_CLI_OPTS: '--debug --aggregate-paths=. ruby'`. |
| `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. |
| `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. |
| `SETUP_CMD` | no | Custom setup for the dependency installation (experimental). |
### Installing custom dependencies
@@ -242,7 +253,7 @@ generate a key store file, see the
### 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.
-> - In [GitLab 12.2](https://gitlab.com/gitlab-org/gitlab/issues/12032), Python 3.5 became the default.
+> - In [GitLab 12.2](https://gitlab.com/gitlab-org/gitlab/-/issues/12032), Python 3.5 became the default.
> - In [GitLab 12.7](https://gitlab.com/gitlab-org/security-products/license-management/-/merge_requests/101), Python 3.8 became the default.
License Compliance uses Python 3.8 and pip 19.1 by default.
@@ -328,7 +339,7 @@ strict-ssl = false
### Configuring Yarn projects
-You can configure Yarn projects by using a [`.yarnrc.yml`](https://yarnpkg.com/configuration/yarnrc)
+You can configure Yarn projects by using a [`.yarnrc.yml`](https://yarnpkg.com/configuration/yarnrc/)
file.
#### Using private Yarn registries
@@ -339,7 +350,7 @@ setting to specify its location.
For example:
-```text
+```plaintext
npmRegistryServer: "https://npm.example.com"
```
@@ -348,6 +359,137 @@ npmRegistryServer: "https://npm.example.com"
You can supply a custom root certificate to complete TLS verification by using the
`ADDITIONAL_CA_CERT_BUNDLE` [environment variable](#available-variables).
+### Configuring Bower projects
+
+You can configure Bower projects by using a [`.bowerrc`](https://bower.io/docs/config/#bowerrc-specification)
+file.
+
+#### Using private Bower registries
+
+If you have a private Bower registry you can use the
+[`registry`](https://bower.io/docs/config/#bowerrc-specification)
+setting to specify its location.
+
+For example:
+
+```plaintext
+{
+ "registry": "https://registry.bower.io"
+}
+```
+
+#### Custom root certificates for Bower
+
+You can supply a custom root certificate to complete TLS verification by using the
+`ADDITIONAL_CA_CERT_BUNDLE` [environment variable](#available-variables), or by
+specifying a `ca` setting in a [`.bowerrc`](https://bower.io/docs/config/#bowerrc-specification)
+file.
+
+### Configuring Conan projects
+
+You can configure [Conan](https://conan.io/) projects by adding a `.conan` directory to your
+project root. The project root serves as the [`CONAN_USER_HOME`](https://docs.conan.io/en/latest/reference/env_vars.html#conan-user-home).
+
+Consult the [Conan](https://docs.conan.io/en/latest/reference/config_files/conan.conf.html#conan-conf)
+documentation for a list of settings that you can apply.
+
+The `license_scanning` job runs in a [Debian 10](https://www.debian.org/releases/buster/) Docker
+image. The supplied image ships with some build tools such as [CMake](https://cmake.org/) and [GCC](https://gcc.gnu.org/).
+However, not all project types are supported by default. To install additional tools needed to
+compile dependencies, use a [`before_script`](../../../ci/yaml/README.md#before_script-and-after_script)
+to install the necessary build tools using the [`apt`](https://wiki.debian.org/PackageManagementTools)
+package manager. For a comprehensive list, consult [the Conan documentation](https://docs.conan.io/en/latest/introduction.html#all-platforms-all-build-systems-and-compilers).
+
+The default [Conan](https://conan.io/) configuration sets [`CONAN_LOGIN_USERNAME`](https://docs.conan.io/en/latest/reference/env_vars.html#conan-login-username-conan-login-username-remote-name)
+to `ci_user`, and binds [`CONAN_PASSWORD`](https://docs.conan.io/en/latest/reference/env_vars.html#conan-password-conan-password-remote-name)
+to the [`CI_JOB_TOKEN`](../../../ci/variables/predefined_variables.md)
+for the running job. This allows Conan projects to fetch packages from a [GitLab Conan Repository](../../packages/conan_repository/#fetching-conan-package-information-from-the-gitlab-package-registry)
+if a GitLab remote is specified in the `.conan/remotes.json` file.
+
+To override the default credentials specify a [`CONAN_LOGIN_USERNAME_{REMOTE_NAME}`](https://docs.conan.io/en/latest/reference/env_vars.html#conan-login-username-conan-login-username-remote-name)
+matching the name of the remote specified in the `.conan/remotes.json` file.
+
+NOTE: **Note:**
+[MSBuild](https://github.com/mono/msbuild#microsoftbuild-msbuild) projects aren't supported. The
+`license_scanning` image ships with [Mono](https://www.mono-project.com/) and [MSBuild](https://github.com/mono/msbuild#microsoftbuild-msbuild).
+Additional setup may be required to build packages for this project configuration.
+
+#### Using private Conan registries
+
+By default, [Conan](https://conan.io/) uses the `conan-center` remote. For example:
+
+```json
+{
+ "remotes": [
+ {
+ "name": "conan-center",
+ "url": "https://conan.bintray.com",
+ "verify_ssl": true
+ }
+ ]
+}
+```
+
+To fetch dependencies from an alternate remote, specify that remote in a `.conan/remotes.json`. For
+example:
+
+```json
+{
+ "remotes": [
+ {
+ "name": "gitlab",
+ "url": "https://gitlab.com/api/v4/packages/conan",
+ "verify_ssl": true
+ }
+ ]
+}
+```
+
+If credentials are required to authenticate then you can configure a [protected variable](../../../ci/variables/README.md#protect-a-custom-variable)
+following the naming convention described in the [`CONAN_LOGIN_USERNAME` documentation](https://docs.conan.io/en/latest/reference/env_vars.html#conan-login-username-conan-login-username-remote-name).
+
+#### Custom root certificates for Conan
+
+You can provide custom certificates by adding a `.conan/cacert.pem` file to the project root and
+setting [`CA_CERT_PATH`](https://docs.conan.io/en/latest/reference/env_vars.html#conan-cacert-path)
+to `.conan/cacert.pem`.
+
+If you specify the `ADDITIONAL_CA_CERT_BUNDLE` [environment variable](#available-variables), this
+variable's X.509 certificates are installed in the Docker image's default trust store and Conan is
+configured to use this as the default `CA_CERT_PATH`.
+
+### Configuring Go projects
+
+To configure [Go modules](https://github.com/golang/go/wiki/Modules)
+based projects, specify [environment variables](https://golang.org/pkg/cmd/go/#hdr-Environment_variables)
+in the `license_scanning` job's [variables](#available-variables) section in `.gitlab-ci.yml`.
+
+If a project has [vendored](https://golang.org/pkg/cmd/go/#hdr-Vendor_Directories) its modules,
+then the combination of the `vendor` directory and `mod.sum` file are used to detect the software
+licenses associated with the Go module dependencies.
+
+#### Using private Go registries
+
+You can use the [`GOPRIVATE`](https://golang.org/pkg/cmd/go/#hdr-Environment_variables)
+and [`GOPROXY`](https://golang.org/pkg/cmd/go/#hdr-Environment_variables)
+environment variables to control where modules are sourced from. Alternatively, you can use
+[`go mod vendor`](https://golang.org/ref/mod#tmp_28) to vendor a project's modules.
+
+#### Custom root certificates for Go
+
+You can specify the [`-insecure`](https://golang.org/pkg/cmd/go/internal/get/) flag by exporting the
+[`GOFLAGS`](https://golang.org/cmd/go/#hdr-Environment_variables)
+environment variable. For example:
+
+```yaml
+include:
+ - template: License-Scanning.gitlab-ci.yml
+
+license_scanning:
+ variables:
+ GOFLAGS: '-insecure'
+```
+
### Migration from `license_management` to `license_scanning`
In GitLab 12.8 a new name for `license_management` job was introduced. This change was made to improve clarity around the purpose of the scan, which is to scan and collect the types of licenses present in a projects dependencies.
@@ -450,15 +592,21 @@ license_scanning:
The License Compliance job should now use local copies of the License Compliance analyzers to scan
your code and generate security reports, without requiring internet access.
-Additional configuration may be needed for connecting to [private Maven repositories](#using-private-maven-repos),
-[private NPM registries](#using-private-npm-registries), [private Yarn registries](#using-private-yarn-registries), and [private Python repositories](#using-private-python-repos).
+Additional configuration may be needed for connecting to
+[private Bower registries](#using-private-bower-registries),
+[private Conan registries](#using-private-bower-registries),
+[private Go registries](#using-private-go-registries),
+[private Maven repositories](#using-private-maven-repos),
+[private NPM registries](#using-private-npm-registries),
+[private Python repositories](#using-private-python-repos),
+and [private Yarn registries](#using-private-yarn-registries).
Exact name matches are required for [project policies](#project-policies-for-license-compliance)
when running in an offline environment ([see related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/212388)).
## Project policies for License Compliance
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/5940) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5940) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.4.
From the project's settings:
@@ -496,7 +644,7 @@ Searching for Licenses:
## License Compliance report under pipelines
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/5491) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.2.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5491) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.2.
From your project's left sidebar, navigate to **CI/CD > Pipelines** and click on the
pipeline ID that has a `license_scanning` job to see the Licenses tab with the listed
@@ -518,7 +666,7 @@ but commented out to help encourage others to add to it in the future. -->
## License list
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/13582) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13582) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.7.
The License list allows you to see your project's licenses and key
details about them.
@@ -554,3 +702,78 @@ Policies can be configured by maintainers of the project.
Developers of the project can view the policies configured in a project.
![View Policies](img/policies_v13_0.png)
+
+## Troubleshooting
+
+### `ERROR -- : asdf: No preset version installed for command`
+
+This error occurs when the version of the tools used by your project
+do not match the version of the pre-installed tools available in the
+`license_scanning` Docker image. The `license_scanning` job uses
+[asdf-vm](https://asdf-vm.com/) to activate the appropriate version of
+a tool that your project relies on. For example, if your project relies on a specific
+version of [Node.js](https://nodejs.org/) or any other supported tool you can
+specify the desired version by adding a
+[`.tool-versions`](https://asdf-vm.com/#/core-configuration?id=tool-versions) file to the project
+or using the appropriate [`ASDF_<tool>_VERSION`](https://asdf-vm.com/#/core-configuration?id=environment-variables) environment variable to
+activate the appropriate version.
+
+For example, the following `.tool-versions` file will activate version `12.16.3` of [Node.js](https://nodejs.org/)
+and version `2.6.6` of [Ruby](https://www.ruby-lang.org/).
+
+```plaintext
+nodejs 12.16.3
+ruby 2.6.6
+```
+
+The next example shows how to activate the same versions of the tools mentioned above by using environment variables defined in your
+project's `.gitlab-ci.yml` file.
+
+```yaml
+include:
+ - template: License-Scanning.gitlab-ci.yml
+
+license_scanning:
+ variables:
+ ASDF_NODEJS_VERSION: '12.16.3'
+ ASDF_RUBY_VERSION: '2.6.6'
+```
+
+A full list of variables can be found in [environment variables](#available-variables).
+
+To find out what tools are pre-installed in the `license_scanning` Docker image use the following command:
+
+```shell
+$ docker run --entrypoint='' registry.gitlab.com/gitlab-org/security-products/analyzers/license-finder:3 /bin/bash -lc 'asdf list'
+golang
+ 1.14
+gradle
+ 6.3
+java
+ adopt-openjdk-11.0.7+10
+ adopt-openjdk-8u242-b08
+maven
+ 3.6.3
+nodejs
+ 10.20.1
+ 12.16.3
+php
+ 7.4.5
+python
+ 2.7.18
+ 3.8.2
+ruby
+ 2.6.6
+sbt
+ 1.3.8
+```
+
+To interact with the `license_scanning` runtime environment use the following command:
+
+```shell
+$ docker run -it --entrypoint='' registry.gitlab.com/gitlab-org/security-products/analyzers/license-finder:3 /bin/bash -l
+root@6abb70e9f193:~#
+```
+
+NOTE: **Note:**
+Selecting a custom version of [Mono](https://www.mono-project.com/) or [.NET Core](https://dotnet.microsoft.com/download/dotnet-core) is currently not supported.
diff --git a/doc/user/discussions/img/add_another_suggestion_to_batch_v13_1.jpg b/doc/user/discussions/img/add_another_suggestion_to_batch_v13_1.jpg
new file mode 100644
index 00000000000..e8aa4b7c730
--- /dev/null
+++ b/doc/user/discussions/img/add_another_suggestion_to_batch_v13_1.jpg
Binary files differ
diff --git a/doc/user/discussions/img/add_first_suggestion_to_batch_v13_1.jpg b/doc/user/discussions/img/add_first_suggestion_to_batch_v13_1.jpg
new file mode 100644
index 00000000000..d15f5d53e55
--- /dev/null
+++ b/doc/user/discussions/img/add_first_suggestion_to_batch_v13_1.jpg
Binary files differ
diff --git a/doc/user/discussions/img/apply_batch_of_suggestions_v13_1.jpg b/doc/user/discussions/img/apply_batch_of_suggestions_v13_1.jpg
new file mode 100644
index 00000000000..3e1e9c20af9
--- /dev/null
+++ b/doc/user/discussions/img/apply_batch_of_suggestions_v13_1.jpg
Binary files differ
diff --git a/doc/user/discussions/img/quickly_assign_commenter_v13_1.png b/doc/user/discussions/img/quickly_assign_commenter_v13_1.png
new file mode 100644
index 00000000000..e19a3ed4f75
--- /dev/null
+++ b/doc/user/discussions/img/quickly_assign_commenter_v13_1.png
Binary files differ
diff --git a/doc/user/discussions/img/remove_suggestion_from_batch_v13_1.jpg b/doc/user/discussions/img/remove_suggestion_from_batch_v13_1.jpg
new file mode 100644
index 00000000000..fa8331effdb
--- /dev/null
+++ b/doc/user/discussions/img/remove_suggestion_from_batch_v13_1.jpg
Binary files differ
diff --git a/doc/user/discussions/img/suggestions_custom_commit_messages_v12_7.png b/doc/user/discussions/img/suggestions_custom_commit_messages_v12_7.png
deleted file mode 100644
index 8bbc0fcb99b..00000000000
--- a/doc/user/discussions/img/suggestions_custom_commit_messages_v12_7.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/discussions/img/suggestions_custom_commit_messages_v13_1.jpg b/doc/user/discussions/img/suggestions_custom_commit_messages_v13_1.jpg
new file mode 100644
index 00000000000..a4c9df0ebb9
--- /dev/null
+++ b/doc/user/discussions/img/suggestions_custom_commit_messages_v13_1.jpg
Binary files differ
diff --git a/doc/user/discussions/index.md b/doc/user/discussions/index.md
index 9f24807ddf4..5ee11c553af 100644
--- a/doc/user/discussions/index.md
+++ b/doc/user/discussions/index.md
@@ -1,3 +1,9 @@
+---
+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/#designated-technical-writers
+---
+
# Threads
The ability to contribute conversationally is offered throughout GitLab.
@@ -48,7 +54,7 @@ to address feedback and lets you hide threads that are no longer relevant.
### Commit threads in the context of a merge request
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/31847) in GitLab 10.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/31847) in GitLab 10.3.
For reviewers with commit-based workflow, it may be useful to add threads to
specific commit diffs in the context of a merge request. These threads will
@@ -290,9 +296,10 @@ edit existing comments. Non-team members are restricted from adding or editing c
Additionally, locked issues and merge requests can not be reopened.
-## Merge Request Reviews **(PREMIUM)**
+## Merge Request Reviews
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/4213) in GitLab 11.4.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/4213) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.4.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/28154) to GitLab Core in 13.1.
When looking at a Merge Request diff, you are able to start a review.
This allows you to create comments inside a Merge Request that are **only visible to you** until published,
@@ -364,7 +371,7 @@ Replying to this email will, consequentially, create a new comment on the associ
## Filtering notes
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/26723) in GitLab 11.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/26723) in GitLab 11.5.
For issues with many comments like activity notes and user comments, sometimes
finding useful information can be hard. There is a way to filter comments from single notes and threads for merge requests and issues.
@@ -384,7 +391,7 @@ from any device you're logged into.
## Suggest Changes
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/18008) in GitLab 11.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/18008) in GitLab 11.6.
As a reviewer, you're able to suggest code changes with a simple
Markdown syntax in Merge Request Diff threads. Then, the
@@ -402,10 +409,7 @@ the merge request authored by the user that applied them.
![Add a suggestion into a code block tagged properly](img/make_suggestion_v12_7.png)
-1. Click **Comment**.
-
- NOTE: **Note:**
- If you're using GitLab Premium, GitLab.com Silver, and higher tiers, the thread will display [Review](#merge-request-reviews-premium) options. Click either **Start a review**, **Add comment now**, or **Add to review** to obtain the same result.
+1. Click either **Start a review** or **Add to review** to add your comment to a [review](#merge-request-reviews), or **Add comment now** to add the comment to the thread immediately.
The Suggestion in the comment can be applied by the merge request author
directly from the merge request:
@@ -419,7 +423,7 @@ branch. [Developer permission](../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
@@ -451,38 +455,66 @@ instead of the usual three.
### Configure the commit message for applied Suggestions
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/13086) in GitLab 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13086) in GitLab 12.7.
+
+GitLab uses a default commit message
+when applying Suggestions: `Apply %{suggestions_count} suggestion(s) to %{files_count} file(s)`
-GitLab uses `Apply suggestion to %{file_path}` by default as commit messages
-when applying Suggestions. This commit message can be customized to
-follow any guidelines you might have. To do so, expand the **Merge requests**
+For example, consider that a user applied 3 suggestions to 2 different files, the default commit message will be: **Apply 3 suggestion(s) to 2 file(s)**
+
+These commit messages can be customized to follow any guidelines you might have. To do so, expand the **Merge requests**
tab within your project's **General** settings and change the
**Merge suggestions** text:
-![Custom commit message for applied Suggestions](img/suggestions_custom_commit_messages_v12_7.png)
+![Custom commit message for applied Suggestions](img/suggestions_custom_commit_messages_v13_1.jpg)
You can also use following variables besides static text:
| Variable | Description | Output example |
|---|---|---|
+| `%{branch_name}` | The name of the branch the Suggestion(s) was(were) applied to. | `my-feature-branch` |
+| `%{files_count}` | The number of file(s) to which Suggestion(s) was(were) applied.| **2** |
+| `%{file_paths}` | The path(s) of the file(s) Suggestion(s) was(were) applied to. Paths are separated by commas.| `docs/index.md, docs/about.md` |
| `%{project_path}` | The project path. | `my-group/my-project` |
| `%{project_name}` | The human-readable name of the project. | **My Project** |
-| `%{file_path}` | The path of the file the Suggestion is applied to. | `docs/index.md` |
-| `%{branch_name}` | The name of the branch the Suggestion is applied on. | `my-feature-branch` |
-| `%{username}` | The username of the user applying the Suggestion. | `user_1` |
-| `%{user_full_name}` | The full name of the user applying the Suggestion. | **User 1** |
+| `%{suggestions_count}` | The number of Suggestions applied.| **3** |
+| `%{username}` | The username of the user applying Suggestion(s). | `user_1` |
+| `%{user_full_name}` | The full name of the user applying Suggestion(s). | **User 1** |
For example, to customize the commit message to output
**Addresses user_1's review**, set the custom text to
`Addresses %{username}'s review`.
NOTE: **Note:**
-Custom commit messages for each applied Suggestion will be
+Custom commit messages for each applied Suggestion (and for batch Suggestions) will be
introduced by [#25381](https://gitlab.com/gitlab-org/gitlab/issues/25381).
+### Batch Suggestions
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/25486) in GitLab 13.1.
+
+You can apply multiple suggestions at once to reduce the number of commits added
+to your branch to address your reviewers' requests.
+
+1. To start a batch of suggestions that will be applied with a single commit, click **Add suggestion to batch**:
+
+ ![A code change suggestion displayed, with the button to add the suggestion to a batch highlighted.](img/add_first_suggestion_to_batch_v13_1.jpg "Add a suggestion to a batch")
+
+1. Add as many additional suggestions to the batch as you wish:
+
+ ![A code change suggestion displayed, with the button to add an additional suggestion to a batch highlighted.](img/add_another_suggestion_to_batch_v13_1.jpg "Add another suggestion to a batch")
+
+1. To remove suggestions, click **Remove from batch**:
+
+ ![A code change suggestion displayed, with the button to remove that suggestion from its batch highlighted.](img/remove_suggestion_from_batch_v13_1.jpg "Remove a suggestion from a batch")
+
+1. Having added all the suggestions to your liking, when ready, click **Apply suggestions**:
+
+ ![A code change suggestion displayed, with the button to apply the batch of suggestions highlighted.](img/apply_batch_of_suggestions_v13_1.jpg "Apply a batch of suggestions")
+
## Start a thread by replying to a standard comment
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/30299) in GitLab 11.9
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/30299) in GitLab 11.9
To reply to a standard (non-thread) comment, you can use the **Reply to comment** button.
@@ -500,3 +532,15 @@ to the original comment, so a note about when it was last edited will appear und
This feature only exists for Issues, Merge requests, and Epics. Commits, Snippets and Merge request diff threads are
not supported yet.
+
+## Assign an issue to the commenting user
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/191455) in GitLab 13.1.
+
+You can assign an issue to a user who made a comment.
+
+In the comment, click the **More Actions** menu and click **Assign to commenting user**.
+
+Click the button again to unassign the commenter.
+
+![Assign to commenting user](img/quickly_assign_commenter_v13_1.png)
diff --git a/doc/user/feature_highlight.md b/doc/user/feature_highlight.md
index 47f8671afae..9b52c178493 100644
--- a/doc/user/feature_highlight.md
+++ b/doc/user/feature_highlight.md
@@ -3,11 +3,11 @@
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/16379) in GitLab 10.5
Feature highlights are represented by a pulsing blue dot. Hovering over the dot
-will open up callout with more information.
+will display more information.
They are used to emphasize a certain feature and make something more visible to the user.
You can dismiss any feature highlight permanently by clicking the "Got it" link
-at the bottom of the callout. There isn't a way to restore the feature highlight
+at the bottom of the modal window. There isn't a way to restore the feature highlight
after it has been dismissed.
![Clusters feature highlight](img/feature_highlight_example.png)
diff --git a/doc/user/gitlab_com/index.md b/doc/user/gitlab_com/index.md
index d615b67f3d2..6522f5c4053 100644
--- a/doc/user/gitlab_com/index.md
+++ b/doc/user/gitlab_com/index.md
@@ -31,6 +31,10 @@ gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAA
GitLab.com sends emails from the `mg.gitlab.com` domain via [Mailgun](https://www.mailgun.com/) and has
its own dedicated IP address (`198.61.254.240`).
+## Backups
+
+[See our backup strategy](https://about.gitlab.com/handbook/engineering/infrastructure/production/#backups).
+
## Alternative SSH port
GitLab.com can be reached via a [different SSH port](https://about.gitlab.com/blog/2016/02/18/gitlab-dot-com-now-supports-an-alternate-git-plus-ssh-port/) for `git+ssh`.
@@ -78,6 +82,7 @@ Below are the current settings regarding [GitLab CI/CD](../../ci/README.md).
| Scheduled Pipeline Cron | `*/5 * * * *` | `19 * * * *` |
| [Max jobs in active pipelines](../../administration/instance_limits.md#number-of-jobs-in-active-pipelines) | `500` for Free tier, unlimited otherwise | 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 number of instance level variables](../../administration/instance_limits.md#number-of-instance-level-variables) | `25` | `25` |
## Repository size limit
@@ -136,7 +141,7 @@ The `gitlab-shared-runners-manager-X.gitlab.com` fleet of Runners are dedicated
Jobs handled by the shared Runners on GitLab.com (`shared-runners-manager-X.gitlab.com`),
**will be timed out after 3 hours**, regardless of the timeout configured in a
-project. Check the issues [4010](https://gitlab.com/gitlab-com/infrastructure/issues/4010) and [4070](https://gitlab.com/gitlab-com/infrastructure/issues/4070) for the reference.
+project. Check the issues [4010](https://gitlab.com/gitlab-com/infrastructure/-/issues/4010) and [4070](https://gitlab.com/gitlab-com/infrastructure/-/issues/4070) for the reference.
Below are the shared Runners settings.
@@ -152,7 +157,7 @@ Below are the shared Runners settings.
Linux Shared Runners on GitLab.com provide a way to run commands in a CI
job before the Runner attempts to run `git init` and `git fetch` to
download a GitLab repository. The
-[pre_clone_script](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runners-section)
+[`pre_clone_script`](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runners-section)
can be used for:
- Seeding the build directory with repository data
@@ -219,7 +224,7 @@ sentry_dsn = "X"
"google-tags=gitlab-com,srm",
"google-use-internal-ip",
"google-zone=us-east1-d",
- "engine-opt=mtu=1460", # Set MTU for container interface, for more information check https://gitlab.com/gitlab-org/gitlab-runner/issues/3214#note_82892928
+ "engine-opt=mtu=1460", # Set MTU for container interface, for more information check https://gitlab.com/gitlab-org/gitlab-runner/-/issues/3214#note_82892928
"google-machine-image=PROJECT/global/images/IMAGE",
"engine-opt=ipv6", # This will create IPv6 interfaces in the containers.
"engine-opt=fixed-cidr-v6=fc00::/7",
@@ -243,7 +248,7 @@ During the beta period, the
[shared runner pipeline quota](../admin_area/settings/continuous_integration.md#shared-runners-pipeline-minutes-quota-starter-only)
will apply for groups and projects in the same way as Linux Runners.
This may change when the beta period ends, as discussed in this
-[related issue](https://gitlab.com/gitlab-org/gitlab/issues/30834).
+[related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/30834).
Windows Shared Runners on GitLab.com automatically autoscale by
launching virtual machines on the Google Cloud Platform. This solution uses
@@ -367,7 +372,7 @@ test:
release we will update the autoscaler to enable
the pre-provisioning of virtual machines. This will significantly reduce
the time it takes to provision a VM on the Windows fleet. You can
- follow along in the [related issue](https://gitlab.com/gitlab-org/ci-cd/custom-executor-drivers/autoscaler/issues/32).
+ follow along in the [related issue](https://gitlab.com/gitlab-org/ci-cd/custom-executor-drivers/autoscaler/-/issues/32).
- The Windows Shared Runner fleet may be unavailable occasionally
for maintenance or updates.
- The Windows Shared Runner virtual machine instances do not use the
@@ -415,44 +420,44 @@ different database servers.
The list of GitLab.com specific settings (and their defaults) is as follows:
-| Setting | GitLab.com | Default |
-|:------------------------------------|:--------------------------------------------------------------------|:--------------------------------------|
-| archive_command | `/usr/bin/envdir /etc/wal-e.d/env /opt/wal-e/bin/wal-e wal-push %p` | empty |
-| archive_mode | on | off |
-| autovacuum_analyze_scale_factor | 0.01 | 0.01 |
-| autovacuum_max_workers | 6 | 3 |
-| autovacuum_vacuum_cost_limit | 1000 | -1 |
-| autovacuum_vacuum_scale_factor | 0.01 | 0.02 |
-| checkpoint_completion_target | 0.7 | 0.9 |
-| checkpoint_segments | 32 | 10 |
-| effective_cache_size | 338688MB | Based on how much memory is available |
-| hot_standby | on | off |
-| hot_standby_feedback | on | off |
-| log_autovacuum_min_duration | 0 | -1 |
-| log_checkpoints | on | off |
-| log_line_prefix | `%t [%p]: [%l-1]` | empty |
-| log_min_duration_statement | 1000 | -1 |
-| log_temp_files | 0 | -1 |
-| maintenance_work_mem | 2048MB | 16 MB |
-| max_replication_slots | 5 | 0 |
-| max_wal_senders | 32 | 0 |
-| max_wal_size | 5GB | 1GB |
-| shared_buffers | 112896MB | Based on how much memory is available |
-| shared_preload_libraries | pg_stat_statements | empty |
-| shmall | 30146560 | Based on the server's capabilities |
-| shmmax | 123480309760 | Based on the server's capabilities |
-| wal_buffers | 16MB | -1 |
-| wal_keep_segments | 512 | 10 |
-| wal_level | replica | minimal |
-| statement_timeout | 15s | 60s |
-| idle_in_transaction_session_timeout | 60s | 60s |
+| Setting | GitLab.com | Default |
+|:--------------------------------------|:--------------------------------------------------------------------|:--------------------------------------|
+| `archive_command` | `/usr/bin/envdir /etc/wal-e.d/env /opt/wal-e/bin/wal-e wal-push %p` | empty |
+| `archive_mode` | on | off |
+| `autovacuum_analyze_scale_factor` | 0.01 | 0.01 |
+| `autovacuum_max_workers` | 6 | 3 |
+| `autovacuum_vacuum_cost_limit` | 1000 | -1 |
+| `autovacuum_vacuum_scale_factor` | 0.01 | 0.02 |
+| `checkpoint_completion_target` | 0.7 | 0.9 |
+| `checkpoint_segments` | 32 | 10 |
+| `effective_cache_size` | 338688MB | Based on how much memory is available |
+| `hot_standby` | on | off |
+| `hot_standby_feedback` | on | off |
+| `log_autovacuum_min_duration` | 0 | -1 |
+| `log_checkpoints` | on | off |
+| `log_line_prefix` | `%t [%p]: [%l-1]` | empty |
+| `log_min_duration_statement` | 1000 | -1 |
+| `log_temp_files` | 0 | -1 |
+| `maintenance_work_mem` | 2048MB | 16 MB |
+| `max_replication_slots` | 5 | 0 |
+| `max_wal_senders` | 32 | 0 |
+| `max_wal_size` | 5GB | 1GB |
+| `shared_buffers` | 112896MB | Based on how much memory is available |
+| `shared_preload_libraries` | pg_stat_statements | empty |
+| `shmall` | 30146560 | Based on the server's capabilities |
+| `shmmax` | 123480309760 | Based on the server's capabilities |
+| `wal_buffers` | 16MB | -1 |
+| `wal_keep_segments` | 512 | 10 |
+| `wal_level` | replica | minimal |
+| `statement_timeout` | 15s | 60s |
+| `idle_in_transaction_session_timeout` | 60s | 60s |
Some of these settings are in the process being adjusted. For example, the value
for `shared_buffers` is quite high and as such we are looking into adjusting it.
More information on this particular change can be found at
-<https://gitlab.com/gitlab-com/infrastructure/issues/1555>. An up to date list
+<https://gitlab.com/gitlab-com/infrastructure/-/issues/1555>. An up to date list
of proposed changes can be found at
-<https://gitlab.com/gitlab-com/infrastructure/issues?scope=all&utf8=%E2%9C%93&state=opened&label_name[]=database&label_name[]=change>.
+<https://gitlab.com/gitlab-com/infrastructure/-/issues?scope=all&utf8=%E2%9C%93&state=opened&label_name[]=database&label_name[]=change>.
## Unicorn
@@ -553,7 +558,7 @@ GitLab.com:
On GitLab.com, projects, groups, and snippets created
As of GitLab 12.2 (July 2019), projects, groups, and snippets have the
-[**Internal** visibility](../../public_access/public_access.md#internal-projects) setting [disabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/issues/12388).
+[**Internal** visibility](../../public_access/public_access.md#internal-projects) setting [disabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/12388).
### SSH maximum number of connections
@@ -563,6 +568,10 @@ If more than the maximum number of allowed connections occur concurrently, they
dropped and users get
[an `ssh_exchange_identification` error](../../topics/git/troubleshooting_git.md#ssh_exchange_identification-error).
+### Import/export
+
+To help avoid abuse, project and group imports, exports, and export downloads are rate limited. See [Project import/export rate limits](../../user/project/settings/import_export.md#rate-limits) and [Group import/export rate limits](../../user/group/settings/import_export.md#rate-limits) for details.
+
## GitLab.com Logging
We use [Fluentd](https://gitlab.com/gitlab-com/runbooks/tree/master/logging/doc#fluentd) to parse our logs. Fluentd sends our logs to
diff --git a/doc/user/group/bulk_editing/index.md b/doc/user/group/bulk_editing/index.md
index a90097c848f..c4ccc1f7b52 100644
--- a/doc/user/group/bulk_editing/index.md
+++ b/doc/user/group/bulk_editing/index.md
@@ -1,31 +1,74 @@
-# Bulk editing issues, merge requests, and epics at the group level **(PREMIUM)**
+---
+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/#designated-technical-writers
+---
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/7249) for issues in [GitLab Premium](https://about.gitlab.com/pricing/) 12.1.
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/12719) for merge requests in [GitLab Premium](https://about.gitlab.com/pricing/) 12.2.
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/7250) for epics in [GitLab Premium](https://about.gitlab.com/pricing/) 12.2.
+# Bulk editing issues, epics, and merge requests at the group level **(PREMIUM)**
-## Editing milestones and labels
+NOTE: **Note:**
+Bulk editing issues and merge requests is also available at the **project level**.
+For more details, see [Bulk editing issues, epics, and merge requests](../../project/bulk_editing.md).
-> **Notes:**
->
-> - A permission level of `Reporter` or higher is required in order to manage issues.
-> - A permission level of `Developer` or higher is required in order to manage merge requests.
-> - A permission level of `Reporter` or higher is required in order to manage epics.
+If you want to update attributes across multiple issues, epics, or merge requests in a group, you
+can do it by bulk editing them, that is, editing them together.
-By using the bulk editing feature:
+![Bulk editing](img/bulk-editing.png)
-- Milestones can be updated simultaneously across multiple issues or merge requests.
-- Labels can be updated simultaneously across multiple issues, merge requests, or epics.
+## Bulk edit issues at the group level
-![Bulk editing](img/bulk-editing.png)
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7249) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.1.
+
+NOTE: **Note:**
+You need a permission level of [Reporter or higher](../../permissions.md) to manage issues.
+
+When bulk editing issues in a group, you can edit the following attributes:
+
+- Milestone
+- Labels
+
+To update multiple project issues at the same time:
+
+1. In a group, go to **{issues}** **Issues > List**.
+1. Click **Edit issues**. A sidebar on the right-hand side of your screen appears with editable fields.
+1. Select the checkboxes next to each issue you want to edit.
+1. Select the appropriate fields and their values from the sidebar.
+1. Click **Update all**.
+
+## Bulk edit epics
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7250) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.2.
+
+NOTE: **Note:**
+You need a permission level of [Reporter or higher](../../permissions.md) to manage epics.
+
+When bulk editing epics in a group, you can edit their labels.
+
+To update multiple epics at the same time:
+
+1. In a group, go to **{epic}** **Epics > List**.
+1. Click **Edit epics**. A sidebar on the right-hand side of your screen appears with editable fields.
+1. Check the checkboxes next to each epic you want to edit.
+1. Select the appropriate fields and their values from the sidebar.
+1. Click **Update all**.
+
+## Bulk edit merge requests at the group level
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12719) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.2.
+
+NOTE: **Note:**
+You need a permission level of [Developer or higher](../../permissions.md) to manage merge requests.
+
+When bulk editing merge requests in a group, you can edit the following attributes:
+
+- Milestone
+- Labels
-To bulk update group issues, merge requests, or epics:
+To update multiple group merge requests at the same time:
-1. Navigate to the issues, merge requests, or epics list.
-1. Click **Edit issues**, **Edit merge requests**, or **Edit epics**.
- - This will open a sidebar on the right-hand side where editable fields
- for milestones and labels will be displayed.
- - Checkboxes will also appear beside each issue, merge request, or epic.
-1. Check the checkbox beside each issue, merge request, or epic to be edited.
-1. Select the desired new values from the sidebar.
+1. In a group, go to **{merge-request}** **Merge Requests**.
+1. Click **Edit merge requests**. A sidebar on the right-hand side of your screen appears with
+ editable fields.
+1. Select the checkboxes next to each merge request you want to edit.
+1. Select the appropriate fields and their values from the sidebar.
1. Click **Update all**.
diff --git a/doc/user/group/clusters/index.md b/doc/user/group/clusters/index.md
index 5e6ff980c8b..5cdac7ae892 100644
--- a/doc/user/group/clusters/index.md
+++ b/doc/user/group/clusters/index.md
@@ -7,7 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Group-level Kubernetes clusters
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/34758) in GitLab 11.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/34758) in GitLab 11.6.
Similar to [project-level](../../project/clusters/index.md) and
[instance-level](../../instance/clusters/index.md) Kubernetes clusters,
@@ -23,8 +23,8 @@ and troubleshooting applications for your group cluster, see
## RBAC compatibility
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/29398) in GitLab 11.4.
-> - [Project namespace restriction](https://gitlab.com/gitlab-org/gitlab-foss/issues/51716) was introduced in GitLab 11.5.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/29398) in GitLab 11.4.
+> - [Project namespace restriction](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/51716) was introduced in GitLab 11.5.
For each project under a group with a Kubernetes cluster, GitLab creates a restricted
service account with [`edit` privileges](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles)
@@ -65,7 +65,7 @@ for deployments with a cluster not managed by GitLab, you must ensure:
- The project's deployment service account has permissions to deploy to
[`KUBE_NAMESPACE`](../../project/clusters/index.md#deployment-variables).
- `KUBECONFIG` correctly reflects any changes to `KUBE_NAMESPACE`
- (this is [not automatic](https://gitlab.com/gitlab-org/gitlab/issues/31519)). Editing
+ (this is [not automatic](https://gitlab.com/gitlab-org/gitlab/-/issues/31519)). Editing
`KUBE_NAMESPACE` directly is discouraged.
NOTE: **Note:**
@@ -74,7 +74,7 @@ the resources required to run them even if you choose to manage your own cluster
### Clearing the cluster cache
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/31759) in GitLab 12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/31759) in GitLab 12.6.
If you choose to allow GitLab to manage your cluster for you, GitLab stores a cached
version of the namespaces and service accounts it creates for your projects. If you
diff --git a/doc/user/group/contribution_analytics/img/group_stats_table.png b/doc/user/group/contribution_analytics/img/group_stats_table.png
index f1d1031fa18..1f58b9717d0 100644
--- a/doc/user/group/contribution_analytics/img/group_stats_table.png
+++ b/doc/user/group/contribution_analytics/img/group_stats_table.png
Binary files differ
diff --git a/doc/user/group/contribution_analytics/index.md b/doc/user/group/contribution_analytics/index.md
index 03f0ad6ad1c..bcc6d958427 100644
--- a/doc/user/group/contribution_analytics/index.md
+++ b/doc/user/group/contribution_analytics/index.md
@@ -2,13 +2,12 @@
type: reference
stage: Manage
group: Analytics
-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
+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
---
# Contribution Analytics **(STARTER)**
> - Introduced in [GitLab Starter](https://about.gitlab.com/pricing/) 8.3.
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/3090) for subgroups in GitLab 12.2.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3090) for subgroups in GitLab 12.2.
## Overview
@@ -63,7 +62,7 @@ Contributions per group member are also presented in tabular format. Click a col
- Number of opened issues
- Number of closed issues
- Number of opened MRs
-- Number of accepted MRs
+- Number of merged MRs
- Number of total contributions
![Contribution analytics contributions table](img/group_stats_table.png)
diff --git a/doc/user/group/custom_project_templates.md b/doc/user/group/custom_project_templates.md
index e47a281141d..ebeacda24c6 100644
--- a/doc/user/group/custom_project_templates.md
+++ b/doc/user/group/custom_project_templates.md
@@ -1,10 +1,13 @@
---
type: reference
+stage: Manage
+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/#designated-technical-writers
---
# Custom group-level project templates **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/6861) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/6861) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.6.
When you create a new [project](../project/index.md), creating it based on custom project templates is
a convenient option.
diff --git a/doc/user/group/epics/img/bulk_editing.png b/doc/user/group/epics/img/bulk_editing.png
deleted file mode 100644
index 85610bef83e..00000000000
--- a/doc/user/group/epics/img/bulk_editing.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/group/epics/img/issue_list_v13_1.png b/doc/user/group/epics/img/issue_list_v13_1.png
new file mode 100644
index 00000000000..f08f774e986
--- /dev/null
+++ b/doc/user/group/epics/img/issue_list_v13_1.png
Binary files differ
diff --git a/doc/user/group/epics/index.md b/doc/user/group/epics/index.md
index d53acaf502a..85164292265 100644
--- a/doc/user/group/epics/index.md
+++ b/doc/user/group/epics/index.md
@@ -1,11 +1,14 @@
---
type: reference, howto
+stage: Plan
+group: Portfolio 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/#designated-technical-writers
---
# Epics **(PREMIUM)**
> - Introduced in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.2.
-> - Single-level Epics [were moved](https://gitlab.com/gitlab-org/gitlab/issues/37081) to [GitLab Premium](https://about.gitlab.com/pricing/) in 12.8.
+> - Single-level Epics [were moved](https://gitlab.com/gitlab-org/gitlab/-/issues/37081) to [GitLab Premium](https://about.gitlab.com/pricing/) in 12.8.
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
@@ -25,7 +28,7 @@ milestones.
To learn what you can do with an epic, see [Manage epics](manage_epics.md). Possible actions include:
- [Create an epic](manage_epics.md#create-an-epic)
-- [Bulk-edit epics](manage_epics.md#bulk-edit-epics)
+- [Bulk-edit epics](../bulk_editing/index.md#bulk-edit-epics)
- [Delete an epic](manage_epics.md#delete-an-epic)
- [Close an epic](manage_epics.md#close-an-epic)
- [Reopen a closed epic](manage_epics.md#reopen-a-closed-epic)
@@ -67,7 +70,7 @@ This feature comes with a feature flag enabled by default. For steps to disable
## Multi-level child epics **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/8333) in GitLab Ultimate 11.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8333) in GitLab Ultimate 11.7.
Any epic that belongs to a group, or subgroup of the parent epic's group, is eligible to be added.
New child epics appear at the top of the list of epics in the **Epics and Issues** tab.
@@ -86,11 +89,11 @@ To set a **Start date** and **Due date** for an epic, select one of the followin
- **Fixed**: Enter a fixed value.
- **From milestones**: Inherit a dynamic value from the milestones currently assigned to the epic's issues.
Note that GitLab 12.5 replaced this option with **Inherited**.
-- **Inherited**: Inherit a dynamic value from the epic's issues, child epics, and milestones ([Introduced](https://gitlab.com/gitlab-org/gitlab/issues/7332) in GitLab 12.5 to replace **From milestones**).
+- **Inherited**: Inherit a dynamic value from the epic's issues, child epics, and milestones ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7332) in GitLab 12.5 to replace **From milestones**).
### From milestones
-> [Replaced](https://gitlab.com/gitlab-org/gitlab/issues/7332) in GitLab 12.5 by **Inherited**.
+> [Replaced](https://gitlab.com/gitlab-org/gitlab/-/issues/7332) in GitLab 12.5 by **Inherited**.
If you select **From milestones** for the start date, GitLab will automatically set the date to be earliest
start date across all milestones that are currently assigned to the issues that are added to the epic.
@@ -105,7 +108,7 @@ These are dynamic dates which are recalculated if any of the following occur:
### Inherited
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/7332) in GitLab 12.5 to replace **From milestones**.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7332) in GitLab 12.5 to replace **From milestones**.
If you select:
@@ -127,7 +130,7 @@ then the parent epic's start date will reflect the change and this will propagat
## Roadmap in epics
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/7327) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.10.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7327) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.10.
If your epic contains one or more [child epics](#multi-level-child-epics-ultimate) which
have a [start or due date](#start-date-and-due-date), a
diff --git a/doc/user/group/epics/manage_epics.md b/doc/user/group/epics/manage_epics.md
index 50eb0c64f4b..26d5cb51e01 100644
--- a/doc/user/group/epics/manage_epics.md
+++ b/doc/user/group/epics/manage_epics.md
@@ -1,8 +1,11 @@
---
type: howto
+stage: Plan
+group: Portfolio 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/#designated-technical-writers
---
-<!-- When adding a new section here, remember to mention it in index.md#manage-epics -->
+<!-- When adding a new h2 section here, remember to mention it in index.md#manage-epics -->
# Manage epics **(PREMIUM)**
@@ -30,7 +33,8 @@ You will be taken to the new epic where can edit the following details:
An epic's page contains the following tabs:
-- **Epics and Issues**: epics and issues added to this epic. Child epics, and their issues, are shown in a tree view.
+- **Epics and Issues**: epics and issues added to this epic. Child epics, and their issues, are
+ shown in a tree view.
- Click the <kbd>></kbd> beside a parent epic to reveal the child epics and issues.
- Hover over the total counts to see a breakdown of open and closed items.
- **Roadmap**: a roadmap view of child epics which have start and due dates.
@@ -39,17 +43,8 @@ An epic's page contains the following tabs:
## Bulk-edit epics
-You can edit multiple epics at once. For example, to apply labels to multiple epics:
-
-1. Go to the Epics list.
-1. Click **Edit epics**.
- - Checkboxes appear next to each epic.
- - A sidebar on the right-hand side appears with an editable field for labels.
-1. Select the checkbox next to each epic to be edited.
-1. Select the labels you want.
-1. Click **Update all**.
-
-![bulk editing](img/bulk_editing.png)
+You can edit multiple epics at once. To learn how to do it, visit
+[Bulk editing issues, epics, and merge requests at the group level](../bulk_editing/index.md#bulk-edit-epics).
## Delete an epic
@@ -92,7 +87,7 @@ link in the issue sidebar.
## Search for an epic from epics list page
> - Introduced in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.5.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/issues/37081) to the [Premium](https://about.gitlab.com/pricing/) tier in GitLab 12.8.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/37081) to the [Premium](https://about.gitlab.com/pricing/) tier in GitLab 12.8.
You can search for an epic from the list of epics using filtered search bar (similar to
that of Issues and Merge Requests) based on following parameters:
@@ -134,8 +129,8 @@ confidential** checkbox.
### Enable Confidential Epics **(PREMIUM ONLY)**
-The Confidential Epics feature is under development and not ready for production use. It's deployed behind a
-feature flag that is **disabled by default**.
+The Confidential Epics feature is under development and not ready for production use.
+It's 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 for your instance.
@@ -175,14 +170,14 @@ To add an issue to an epic:
1. Identify the issue to be added, using either of the following methods:
- Paste the link of the issue.
- Search for the desired issue by entering part of the issue's title, then selecting the desired
- match (introduced in [GitLab 12.5](https://gitlab.com/gitlab-org/gitlab/issues/9126)).
+ match (introduced in [GitLab 12.5](https://gitlab.com/gitlab-org/gitlab/-/issues/9126)).
If there are multiple issues to be added, press <kbd>Spacebar</kbd> and repeat this step.
1. Click **Add**.
#### Create an issue from an epic
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/5419) in GitLab 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5419) in GitLab 12.7.
Creating an issue from an epic enables you to maintain focus on the broader context of the epic
while dividing work into smaller parts.
@@ -195,46 +190,49 @@ To create an issue from an epic:
1. From the **Project** dropdown, select the project in which the issue should be created.
1. Click **Create issue**.
+### Remove an issue from an epic
+
+You can remove issues from an epic when you're on the epic's details page.
+After you remove an issue from an epic, the issue will no longer be associated with this epic.
+
To remove an issue from an epic:
-1. Click the <kbd>x</kbd> button in the epic's issue list.
-1. Click **Remove** in the **Remove issue** warning message.
+1. Click the **Remove** (**{close}**) button next to the issue you want to remove.
+ The **Remove issue** warning appears.
+1. Click **Remove**.
+
+![List of issues assigned to an epic](img/issue_list_v13_1.png)
### Reorder issues assigned to an epic
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/9367) in GitLab 12.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9367) in GitLab 12.5.
-New issues are added to the top of their list in the **Epics and Issues** tab.
-You can reorder the list of issues. Issues and child epics cannot be intermingled.
+New issues appear at the top of the list in the **Epics and Issues** tab.
+You can reorder the list of issues by dragging them.
To reorder issues assigned to an epic:
1. Go to the **Epics and Issues** tab.
-1. Drag and drop issues into the desired order.
-
-To reorder child epics assigned to an epic:
-
-1. Go to the **Epics and Issues** tab.
-1. Drag and drop epics into the desired order.
+1. Drag issues into the desired order.
### Move issues between epics **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/33039) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.0.
-New issues are added to the top of their list in the **Epics and Issues**
-tab. You can move issues from one epic to another. Issues and child epics cannot be intermingled.
+New issues appear at the top of the list in the **Epics and Issues**
+tab. You can move issues from one epic to another.
To move an issue to another epic:
1. Go to the **Epics and Issues** tab.
-1. Drag and drop issues into the desired parent epic.
+1. Drag issues into the desired parent epic.
### Promote an issue to an epic
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/3777) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.6.
-> - In [GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/issues/37081), it was moved to the Premium tier.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3777) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.6.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/37081) to [GitLab Premium](https://about.gitlab.com/pricing/) in 12.8.
-If you have [permissions](../../permissions.md) to close an issue and create an
+If you have the necessary [permissions](../../permissions.md) to close an issue and create an
epic in the parent group, you can promote an issue to an epic with the `/promote`
[quick action](../../project/quick_actions.md#quick-actions-for-issues-merge-requests-and-epics).
Only issues from projects that are in groups can be promoted. When attempting to promote a confidential
@@ -263,7 +261,8 @@ To add a child epic to an epic:
1. Click **Add an epic**.
1. Identify the epic to be added, using either of the following methods:
- Paste the link of the epic.
- - Search for the desired issue by entering part of the epic's title, then selecting the desired match (introduced in [GitLab 12.5](https://gitlab.com/gitlab-org/gitlab/issues/9126)).
+ - Search for the desired issue by entering part of the epic's title, then selecting the desired
+ match (introduced in [GitLab 12.5](https://gitlab.com/gitlab-org/gitlab/-/issues/9126)).
If there are multiple epics to be added, press <kbd>Spacebar</kbd> and repeat this step.
1. Click **Add**.
@@ -272,7 +271,7 @@ To add a child epic to an epic:
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/33039) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.0.
-New child epics are added to the top of their list in the **Epics and Issues** tab.
+New child epics appear at the top of the list in the **Epics and Issues** tab.
You can move child epics from one epic to another.
When you add an epic that's already linked to a parent epic, the link to its current parent is removed.
Issues and child epics cannot be intermingled.
@@ -280,19 +279,19 @@ Issues and child epics cannot be intermingled.
To move child epics to another epic:
1. Go to the **Epics and Issues** tab.
-1. Drag and drop epics into the desired parent epic.
+1. Drag epics into the desired parent epic.
### Reorder child epics assigned to an epic
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/9367) in GitLab 12.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9367) in GitLab 12.5.
-New child epics are added to the top of their list in the **Epics and Issues** tab.
-You can reorder the list of child epics. Issues and child epics cannot be intermingled.
+New child epics appear at the top of the list in the **Epics and Issues** tab.
+You can reorder the list of child epics.
To reorder child epics assigned to an epic:
1. Go to the **Epics and Issues** tab.
-1. Drag and drop epics into the desired order.
+1. Drag epics into the desired order.
### Remove a child epic from a parent epic
diff --git a/doc/user/group/img/ldap_sync_cn_v13_1.png b/doc/user/group/img/ldap_sync_cn_v13_1.png
new file mode 100644
index 00000000000..1b0a20b7e64
--- /dev/null
+++ b/doc/user/group/img/ldap_sync_cn_v13_1.png
Binary files differ
diff --git a/doc/user/group/img/ldap_sync_filter_v13_1.png b/doc/user/group/img/ldap_sync_filter_v13_1.png
new file mode 100644
index 00000000000..3fc1f28becd
--- /dev/null
+++ b/doc/user/group/img/ldap_sync_filter_v13_1.png
Binary files differ
diff --git a/doc/user/group/img/manual_permissions_v13_1.png b/doc/user/group/img/manual_permissions_v13_1.png
new file mode 100644
index 00000000000..504e6ab3a42
--- /dev/null
+++ b/doc/user/group/img/manual_permissions_v13_1.png
Binary files differ
diff --git a/doc/user/group/index.md b/doc/user/group/index.md
index f36f3b3fd4f..324c912b2be 100644
--- a/doc/user/group/index.md
+++ b/doc/user/group/index.md
@@ -1,5 +1,8 @@
---
type: reference, howto
+stage: Manage
+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
---
# Groups
@@ -17,7 +20,7 @@ Find your groups by clicking **Groups > Your Groups** in the top navigation.
![GitLab Groups](img/groups.png)
-> The **Groups** dropdown in the top navigation was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/36234) in [GitLab 11.1](https://about.gitlab.com/releases/2018/07/22/gitlab-11-1-released/#groups-dropdown-in-navigation).
+> The **Groups** dropdown in the top navigation was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/36234) in [GitLab 11.1](https://about.gitlab.com/releases/2018/07/22/gitlab-11-1-released/#groups-dropdown-in-navigation).
The **Groups** page displays:
@@ -183,7 +186,7 @@ of a group:
## Changing the default branch protection of a group
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/7583) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7583) in GitLab 12.9.
By default, every group inherits the branch protection set at the global level.
@@ -214,7 +217,7 @@ There are two different ways to add a new project to a group:
### Default project-creation level
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/2534) in [GitLab Premium](https://about.gitlab.com/pricing/) 10.5.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2534) in [GitLab Premium](https://about.gitlab.com/pricing/) 10.5.
> - Brought to [GitLab Starter](https://about.gitlab.com/pricing/) in 10.7.
> - [Moved](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/25975) to [GitLab Core](https://about.gitlab.com/pricing/) in 11.10.
@@ -287,7 +290,7 @@ Alternatively, you can [lock the sharing with group feature](#share-with-group-l
## Sharing a group with another group
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/18328) in GitLab 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18328) in GitLab 12.7.
Similarly to [sharing a project with a group](#sharing-a-project-with-a-group),
you can share a group with another group to give direct group members access
@@ -306,8 +309,50 @@ All the members of the 'Engineering' group will have been added to 'Frontend'.
## Manage group memberships via LDAP
-In GitLab Enterprise Edition, it is possible to manage GitLab group memberships using LDAP groups.
-See [the GitLab Enterprise Edition documentation](../../integration/ldap.md) for more information.
+Group syncing allows LDAP groups to be mapped to GitLab groups. This provides more control over per-group user management. To configure group syncing edit the `group_base` **DN** (`'OU=Global Groups,OU=GitLab INT,DC=GitLab,DC=org'`). This **OU** contains all groups that will be associated with GitLab groups.
+
+Group links can be created using either a CN or a filter. These group links are created on the **Group Settings -> LDAP Synchronization** page. After configuring the link, it may take over an hour for the users to sync with the GitLab group.
+
+For more information on the administration of LDAP and group sync, refer to the [main LDAP documentation](../../administration/auth/ldap/index.md#group-sync-starter-only).
+
+NOTE: **Note:**
+If an LDAP user is a group member when LDAP Synchronization is added, and they are not part of the LDAP group, they will be removed from the group.
+
+### Creating group links via CN **(STARTER ONLY)**
+
+To create group links via CN:
+
+1. Select the **LDAP Server** for the link.
+1. Select `LDAP Group cn` as the **Sync method**.
+1. In the **LDAP Group cn** text input box, begin typing the CN of the group. There will be a dropdown menu with matching CNs within the configured `group_base`. Select your CN from this list.
+1. In the **LDAP Access** section, select the [permission level](../permissions.md) for users synced in this group.
+1. Click the `Add Synchronization` button to save this group link.
+
+![Creating group links via CN](img/ldap_sync_cn_v13_1.png)
+
+### Creating group links via filter **(PREMIUM ONLY)**
+
+To create group links via filter:
+
+1. Select the **LDAP Server** for the link.
+1. Select `LDAP user filter` as the **Sync method**.
+1. Input your filter in the **LDAP User filter** box. Follow the [documentation on user filters](../../administration/auth/ldap/index.md#set-up-ldap-user-filter-core-only).
+1. In the **LDAP Access** section, select the [permission level](../permissions.md) for users synced in this group.
+1. Click the `Add Synchronization` button to save this group link.
+
+![Creating group links via filter](img/ldap_sync_filter_v13_1.png)
+
+### Overriding user permissions **(STARTER ONLY)**
+
+Since GitLab [v8.15](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/822) LDAP user permissions can now be manually overridden by an admin user. To override a user's permissions:
+
+1. Go to your group's **Members** page.
+1. Select the pencil icon in the row for the user you are editing.
+1. Select the orange `Change permissions` button.
+
+![Setting manual permissions](img/manual_permissions_v13_1.png)
+
+Now you will be able to edit the user's permissions from the **Members** page.
## Epics **(ULTIMATE)**
@@ -407,11 +452,11 @@ To remove a group and its contents:
This action either:
- Removes the group, and also queues a background job to delete all projects in that group.
-- Since [GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/issues/33257), on [Premium or Silver](https://about.gitlab.com/pricing/premium/) or higher tiers, marks a group for deletion. The deletion will happen 7 days later by default, but this can be changed in the [instance settings](../admin_area/settings/visibility_and_access_controls.md#default-deletion-adjourned-period-premium-only).
+- Since [GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/-/issues/33257), on [Premium or Silver](https://about.gitlab.com/pricing/premium/) or higher tiers, marks a group for deletion. The deletion will happen 7 days later by default, but this can be changed in the [instance settings](../admin_area/settings/visibility_and_access_controls.md#default-deletion-adjourned-period-premium-only).
### Restore a group **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/33257) in GitLab 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/33257) in GitLab 12.8.
To restore a group that is marked for deletion:
@@ -460,9 +505,10 @@ This will disable the option for all users who previously had permissions to
operate project memberships, so no new users can be added. Furthermore, any
request to add a new user to a project through API will not be possible.
-#### IP access restriction **(ULTIMATE)**
+#### IP access restriction **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/1985) in [GitLab Ultimate and Gold](https://about.gitlab.com/pricing/) 12.0.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/1985) in [GitLab Ultimate and Gold](https://about.gitlab.com/pricing/) 12.0.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/215410) to [GitLab Premium and Silver](https://about.gitlab.com/pricing/) in 13.1.
To make sure only people from within your organization can access particular
resources, you have the option to restrict access to groups and their
@@ -470,28 +516,27 @@ underlying projects, issues, etc, by IP address. This can help ensure that
particular content doesn't leave the premises, while not blocking off access to
the entire instance.
-Add one or more whitelisted IP subnets using CIDR notation in comma separated format to the group settings and anyone
+Add one or more allowed IP subnets using CIDR notation in comma separated format to the group settings and anyone
coming from a different IP address won't be able to access the restricted
content.
Restriction currently applies to:
- UI.
-- [From GitLab 12.3](https://gitlab.com/gitlab-org/gitlab/issues/12874), API access.
-- [From GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/issues/32113), Git actions via SSH.
+- [From GitLab 12.3](https://gitlab.com/gitlab-org/gitlab/-/issues/12874), API access.
+- [From GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/-/issues/32113), Git actions via SSH.
To avoid accidental lock-out, admins and group owners are able to access
the group regardless of the IP restriction.
#### Allowed domain restriction **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/7297) in [GitLab Premium and Silver](https://about.gitlab.com/pricing/) 12.2.
+>- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7297) in [GitLab Premium and Silver](https://about.gitlab.com/pricing/) 12.2.
+>- Support for specifying multiple email domains [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/33143) in GitLab 13.1
-You can restrict access to groups by
-allowing only users with email addresses in particular domains to be added to the group.
+You can restrict access to groups by allowing only users with email addresses in particular domains to be added to the group.
-Add email domains you want to whitelist and users with emails from different
-domains won't be allowed to be added to this group.
+Add email domains you want to allow and users with emails from different domains won't be allowed to be added to this group.
Some domains cannot be restricted. These are the most popular public email domains, such as:
@@ -509,7 +554,7 @@ Some domains cannot be restricted. These are the most popular public email domai
To enable this feature:
1. Navigate to the group's **Settings > General** page.
-1. Expand the **Permissions, LFS, 2FA** section, and enter the domain name into **Restrict membership by email** field.
+1. Expand the **Permissions, LFS, 2FA** section, and enter the domain names into **Restrict membership by email** field. You can enter multiple domains by separating each domain with a comma (,).
1. Click **Save changes**.
This will enable the domain-checking for all new users added to the group from this moment on.
@@ -545,7 +590,7 @@ Define project templates at a group level by setting a group as the template sou
#### Disabling email notifications
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/23585) in GitLab 12.2.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/23585) in GitLab 12.2.
You can disable all email notifications related to the group, which includes its subgroups and projects.
@@ -557,7 +602,7 @@ To enable this feature:
#### Disabling group mentions
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/21301) in GitLab 12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/21301) in GitLab 12.6.
You can prevent users from being added to a conversation and getting notified when
anyone mentions a group in which those users are members.
@@ -598,7 +643,7 @@ If your namespace shows `N/A` as the total storage usage, you can trigger a reca
#### Group push rules **(STARTER)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/34370) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34370) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.8.
Group push rules allow group maintainers to set
[push rules](../../push_rules/push_rules.md) for newly created projects within the specific group.
diff --git a/doc/user/group/insights/index.md b/doc/user/group/insights/index.md
index cffbc013e66..dd1f8914392 100644
--- a/doc/user/group/insights/index.md
+++ b/doc/user/group/insights/index.md
@@ -2,8 +2,7 @@
type: reference, howto
stage: Manage
group: Analytics
-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
+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
---
# Insights **(ULTIMATE)**
diff --git a/doc/user/group/issues_analytics/img/issues_table_v13_1.png b/doc/user/group/issues_analytics/img/issues_table_v13_1.png
new file mode 100644
index 00000000000..0f94f1ba2c5
--- /dev/null
+++ b/doc/user/group/issues_analytics/img/issues_table_v13_1.png
Binary files differ
diff --git a/doc/user/group/issues_analytics/index.md b/doc/user/group/issues_analytics/index.md
index df96f2626e1..01cee3d09b8 100644
--- a/doc/user/group/issues_analytics/index.md
+++ b/doc/user/group/issues_analytics/index.md
@@ -2,14 +2,13 @@
type: reference
stage: Manage
group: Analytics
-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
+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
---
# Issues 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/196561) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.9 at the project level.
+> - [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/196561) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.9 at the project level.
Issues Analytics is a bar graph which illustrates the number of issues created each month.
The default timespan is 13 months, which includes the current month, and the 12 months
@@ -35,6 +34,17 @@ shows a total of 15 months for the chart in the GitLab.org group.
![Issues created per month](img/issues_created_per_month_v12_8.png)
+## Drill into the information
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196547) in GitLab 13.1.
+
+You can examine details of individual issues by browsing the table
+located below the chart.
+
+The chart displays the top 100 issues based on the global page filters.
+
+![Issues table](img/issues_table_v13_1.png)
+
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
diff --git a/doc/user/group/iterations/index.md b/doc/user/group/iterations/index.md
new file mode 100644
index 00000000000..2704147dcdd
--- /dev/null
+++ b/doc/user/group/iterations/index.md
@@ -0,0 +1,85 @@
+---
+type: reference
+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/#designated-technical-writers
+---
+
+# Iterations **(STARTER)**
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214713) in [GitLab Starter](https://about.gitlab.com/pricing/) 13.1.
+> - It's deployed behind a feature flag, disabled by default.
+> - It's disabled on GitLab.com.
+> - It's able to be enabled or disabled per-group
+> - It's not recommended for production use.
+> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-iterations-core-only). **(CORE ONLY)**
+
+Iterations are a way to track issues over a period of time. This allows teams
+to track velocity and volatility metrics. Iterations can be used with [milestones](../../project/milestones/index.md)
+for tracking over different time periods.
+
+For example, you can use:
+
+- Milestones for Program Increments, which span 8-12 weeks.
+- Iterations for Sprints, which span 2 weeks.
+
+In GitLab, iterations are similar to milestones, with a few differences:
+
+- Iterations are only available to groups.
+- A group can only have one active iteration at a time.
+- Iterations require both a start and an end date.
+- Iteration date ranges cannot overlap.
+
+## View the iterations list
+
+To view the iterations list, in a group, go to **{issues}** **Issues > Iterations**.
+From there you can create a new iteration or click an iteration to get a more detailed view.
+
+## Create an iteration
+
+NOTE: **Note:**
+A permission level of [Developer or higher](../../permissions.md) is required to create iterations.
+
+To create an iteration:
+
+1. In a group, go to **{issues}** **Issues > Iterations**.
+1. Click **New iteration**.
+1. Enter the title, a description (optional), a start date, and a due date.
+1. Click **Create iteration**. The iteration details page opens.
+
+### Enable Iterations **(CORE ONLY)**
+
+GitLab Iterations feature 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 for your instance. `:group_iterations` can be enabled or disabled per-group.
+
+To enable it:
+
+```ruby
+# Instance-wide
+Feature.enable(:group_iterations)
+# or by group
+Feature.enable(:group_iterations, Group.find(<group id>))
+```
+
+To disable it:
+
+```ruby
+# Instance-wide
+Feature.disable(:group_iterations)
+# or by group
+Feature.disable(:group_iterations, Group.find(<group id>))
+```
+
+<!-- ## 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/user/group/roadmap/index.md b/doc/user/group/roadmap/index.md
index 6bee552d433..614ed700cfc 100644
--- a/doc/user/group/roadmap/index.md
+++ b/doc/user/group/roadmap/index.md
@@ -1,14 +1,17 @@
---
type: reference
+stage: Plan
+group: Portfolio 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/#designated-technical-writers
---
# Roadmap **(PREMIUM)**
> - Introduced in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.5.
-> - In [GitLab 12.9](https://gitlab.com/gitlab-org/gitlab/issues/198062), Roadmaps were moved to the Premium tier.
-> - In [GitLab 12.9](https://gitlab.com/gitlab-org/gitlab/issues/5164) and later, the epic bars show epics' title, progress, and completed weight percentage.
-> - Milestones appear in Roadmaps in [GitLab 12.10](https://gitlab.com/gitlab-org/gitlab/-/issues/6802), and later.
-> - Feature flag removed in [GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29641).
+> - In [GitLab 12.9](https://gitlab.com/gitlab-org/gitlab/-/issues/198062), Roadmaps were moved to the Premium tier.
+> - In [GitLab 12.9](https://gitlab.com/gitlab-org/gitlab/-/issues/5164) and later, the epic bars show epics' title, progress, and completed weight percentage.
+> - Milestones appear in roadmaps in [GitLab 12.10](https://gitlab.com/gitlab-org/gitlab/-/issues/6802), and later.
+> - Feature flag for milestones visible in roadmaps removed in [GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29641).
Epics and milestones within a group containing **Start date** and/or **Due date**
can be visualized in a form of a timeline (that is, a Gantt chart). The Roadmap page
@@ -45,7 +48,7 @@ Roadmaps can also be [visualized inside an epic](../epics/index.md#roadmap-in-ep
## Timeline duration
> - 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.
+> - 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:
diff --git a/doc/user/group/saml_sso/index.md b/doc/user/group/saml_sso/index.md
index a3d9a14df10..81684038dc2 100644
--- a/doc/user/group/saml_sso/index.md
+++ b/doc/user/group/saml_sso/index.md
@@ -1,5 +1,8 @@
---
type: reference, howto
+stage: Manage
+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
---
# SAML SSO for GitLab.com groups **(SILVER ONLY)**
@@ -54,14 +57,14 @@ We recommend setting the NameID format to `Persistent` unless using a field (suc
### SSO enforcement
-- [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/5291) in GitLab 11.8.
-- [Improved](https://gitlab.com/gitlab-org/gitlab/issues/9255) in GitLab 11.11 with ongoing enforcement in the GitLab UI.
+- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5291) in GitLab 11.8.
+- [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/9255) in GitLab 11.11 with ongoing enforcement in the GitLab UI.
With this option enabled, users must use your group's GitLab single sign on URL to be added to the group or be added via SCIM. Users cannot be added manually, and may only access project/group resources via the UI by signing in through the SSO URL.
However, users will not be prompted to log via SSO on each visit. GitLab will check whether a user has authenticated through the SSO link, and will only prompt the user to login via SSO if the session has expired.
-We intend to add a similar SSO requirement for [Git and API activity](https://gitlab.com/gitlab-org/gitlab/issues/9152) in the future.
+We intend to add a similar SSO requirement for [Git and API activity](https://gitlab.com/gitlab-org/gitlab/-/issues/9152) in the future.
When SSO enforcement is enabled for a group, users cannot share a project in the group outside the top-level group, even if the project is forked.
@@ -82,7 +85,7 @@ When this option is enabled:
Upon successful authentication, GitLab prompts the user with options, based on the email address received from the configured identity provider:
- To create a unique account with the newly received email address.
-- If the received email address matches one of the user's verified GitLab email addresses, the option to convert the existing account to a group-managed account. ([Introduced in GitLab 12.9](https://gitlab.com/gitlab-org/gitlab/issues/13481).)
+- If the received email address matches one of the user's verified GitLab email addresses, the option to convert the existing account to a group-managed account. ([Introduced in GitLab 12.9](https://gitlab.com/gitlab-org/gitlab/-/issues/13481).)
Since use of the group-managed account requires the use of SSO, users of group-managed accounts will lose access to these accounts when they are no longer able to authenticate with the connected identity provider. In the case of an offboarded employee who has been removed from your identity provider:
@@ -100,7 +103,7 @@ Feature.enable(:group_managed_accounts)
##### Credentials inventory for Group-managed accounts **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/38133) in GitLab 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/38133) in GitLab 12.8.
Owners who manage user accounts in a group can view the following details of personal access tokens and SSH keys:
@@ -140,7 +143,7 @@ Once a lifetime for personal access tokens is set, GitLab will:
##### Outer forks restriction for Group-managed accounts
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/34648) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34648) in GitLab 12.9.
Groups with group-managed accounts can disallow forking of projects to destinations outside the group.
To do so, enable the "Prohibit outer forks" option in **Settings > SAML SSO**.
@@ -148,7 +151,7 @@ When enabled, projects within the group can only be forked to other destinations
##### Other restrictions for Group-managed accounts
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/12420) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12420) in GitLab 12.9.
Projects within groups with enabled group-managed accounts are not to be shared with:
@@ -231,7 +234,7 @@ NOTE: **Note:** GitLab is unable to provide support for IdPs that are not listed
|----------|---------------|
| ADFS (Active Directory Federation Services) | [Create a Relying Party Trust](https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/operations/create-a-relying-party-trust) |
| Azure | [Configuring single sign-on to applications](https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/configure-single-sign-on-non-gallery-applications) |
-| Okta | [Setting up a SAML application in Okta](https://developer.okta.com/docs/guides/saml-application-setup/overview/) |
+| Okta | [Setting up a SAML application in Okta](https://developer.okta.com/docs/guides/build-sso-integration/saml2/overview/) |
| OneLogin | [Use the OneLogin SAML Test Connector](https://onelogin.service-now.com/support?id=kb_article&sys_id=93f95543db109700d5505eea4b96198f) |
When [configuring your identify provider](#configuring-your-identity-provider), please consider the notes below for specific providers to help avoid common issues and as a guide for terminology used.
@@ -373,8 +376,8 @@ To proceed with configuring Group SAML SSO instead, you'll need to enable the `g
Group SAML on a self-managed instance is limited when compared to the recommended
[instance-wide SAML](../../../integration/saml.md). The recommended solution allows you to take advantage of:
-- [LDAP compatibility](../../../administration/auth/ldap.md).
-- [LDAP group Sync](../../../administration/auth/how_to_configure_ldap_gitlab_ee/index.md#group-sync).
+- [LDAP compatibility](../../../administration/auth/ldap/index.md).
+- [LDAP Group Sync](../index.md#manage-group-memberships-via-ldap)
- [Required groups](../../../integration/saml.md#required-groups-starter-only).
- [Admin groups](../../../integration/saml.md#admin-groups-starter-only).
- [Auditor groups](../../../integration/saml.md#auditor-groups-starter-only).
diff --git a/doc/user/group/saml_sso/scim_setup.md b/doc/user/group/saml_sso/scim_setup.md
index f66c8a788b6..a891962b38e 100644
--- a/doc/user/group/saml_sso/scim_setup.md
+++ b/doc/user/group/saml_sso/scim_setup.md
@@ -1,5 +1,8 @@
---
type: howto, reference
+stage: Manage
+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
---
# SCIM provisioning using SAML SSO for GitLab.com groups **(SILVER ONLY)**
@@ -117,7 +120,7 @@ Once synchronized, changing the field mapped to `id` and `externalId` will likel
### Okta configuration steps
-The SAML application that was created during [Single sign-on](index.md#okta-setup-notes) setup for [Okta](https://developer.okta.com/docs/guides/saml-application-setup/overview/) now needs to be set up for SCIM.
+The SAML application that was created during [Single sign-on](index.md#okta-setup-notes) setup for [Okta](https://developer.okta.com/docs/guides/build-sso-integration/saml2/overview/) now needs to be set up for SCIM.
Before proceeding, be sure to complete the [GitLab configuration](#gitlab-configuration) process.
1. Sign in to Okta.
diff --git a/doc/user/group/settings/img/export_panel.png b/doc/user/group/settings/img/export_panel.png
deleted file mode 100644
index 2a987f04e35..00000000000
--- a/doc/user/group/settings/img/export_panel.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/group/settings/img/export_panel_v13_0.png b/doc/user/group/settings/img/export_panel_v13_0.png
new file mode 100644
index 00000000000..36549e1f3f5
--- /dev/null
+++ b/doc/user/group/settings/img/export_panel_v13_0.png
Binary files differ
diff --git a/doc/user/group/settings/img/import_panel_v13_1.png b/doc/user/group/settings/img/import_panel_v13_1.png
new file mode 100644
index 00000000000..ce2eb579446
--- /dev/null
+++ b/doc/user/group/settings/img/import_panel_v13_1.png
Binary files differ
diff --git a/doc/user/group/settings/img/new_group_navigation_v13_1.png b/doc/user/group/settings/img/new_group_navigation_v13_1.png
new file mode 100644
index 00000000000..98d45a694b6
--- /dev/null
+++ b/doc/user/group/settings/img/new_group_navigation_v13_1.png
Binary files differ
diff --git a/doc/user/group/settings/import_export.md b/doc/user/group/settings/import_export.md
index 3f14fea673b..cca918d44f3 100644
--- a/doc/user/group/settings/import_export.md
+++ b/doc/user/group/settings/import_export.md
@@ -1,3 +1,9 @@
+---
+type: reference
+stage: Manage
+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/#designated-technical-writers
+---
# Group Import/Export
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2888) in GitLab 13.0 as an experimental feature. May change in future releases.
@@ -61,7 +67,7 @@ For more details on the specific data persisted in a group export, see the
1. In the **Advanced** section, click the **Export Group** button.
- ![Export group panel](img/export_panel.png)
+ ![Export group panel](img/export_panel_v13_0.png)
1. Once the export is generated, you should receive an e-mail with a link to the [exported contents](#exported-contents)
in a compressed tar archive, with contents in JSON format.
@@ -69,12 +75,37 @@ For more details on the specific data persisted in a group export, see the
1. Alternatively, you can come back to the project settings and download the
file from there by clicking **Download export**, or generate a new file by clicking **Regenerate export**.
+NOTE: **Note:**
+The maximum import file size can be set by the Administrator, default is 50MB.
+As an administrator, you can modify the maximum import file size. To do so, use the `max_import_size` option in the [Application settings API](../../../api/settings.md#change-application-settings) or the [Admin UI](../../admin_area/settings/account_and_limit_settings.md).
+
### Between CE and EE
You can export groups from the [Community Edition to the Enterprise Edition](https://about.gitlab.com/install/ce-or-ee/) and vice versa.
If you're exporting a group from the Enterprise Edition to the Community Edition, you may lose data that is retained only in the Enterprise Edition. For more information, see [downgrading from EE to CE](../../../README.md).
+## Importing the group
+
+1. Navigate to the New Group page, either via the `+` button in the top navigation bar, or the **New subgroup** button
+on an existing group's page.
+
+ ![Navigation paths to create a new group](img/new_group_navigation_v13_1.png)
+
+1. On the New Group page, select the **Import group** tab.
+
+ ![Fill in group details](img/import_panel_v13_1.png)
+
+1. Enter your group name.
+
+1. Accept or modify the associated group URL.
+
+1. Click **Choose file**
+
+1. Select the file that you exported in the [exporting a group](#exporting-a-group) section.
+
+1. Click **Import group** to begin importing. Your newly imported group page will appear shortly.
+
## Version history
GitLab can import bundles that were exported from a different GitLab deployment.
@@ -92,7 +123,8 @@ For example:
To help avoid abuse, users are rate limited to:
-| Request Type | Limit |
-| ---------------- | ------------------------------ |
-| Export | 1 group every 5 minutes |
-| Download export | 10 downloads every 10 minutes |
+| Request Type | Limit |
+| ---------------- | ---------------------------------------- |
+| Export | 30 groups every 5 minutes |
+| Download export | 10 downloads per group every 10 minutes |
+| Import | 30 groups every 5 minutes |
diff --git a/doc/user/group/subgroups/index.md b/doc/user/group/subgroups/index.md
index 49f6ddc3986..842e2082be4 100644
--- a/doc/user/group/subgroups/index.md
+++ b/doc/user/group/subgroups/index.md
@@ -4,7 +4,7 @@ type: reference, howto, concepts
# Subgroups
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/2772) in GitLab 9.0.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/2772) in GitLab 9.0.
GitLab supports up to 20 levels of subgroups, also known as nested groups or hierarchical groups.
levels of groups.
@@ -139,7 +139,7 @@ From the image above, we can deduce the following things:
- Administrator is the Owner and member of **all** subgroups and for that reason,
as with User3, there is no indication of an ancestor group.
-[From](https://gitlab.com/gitlab-org/gitlab/issues/21727) GitLab 12.6, you can filter
+[From](https://gitlab.com/gitlab-org/gitlab/-/issues/21727) GitLab 12.6, you can filter
this list using dropdown on the right side:
![Group members filter](img/group_members_filter_v12_6.png)
diff --git a/doc/user/incident_management/index.md b/doc/user/incident_management/index.md
index 73d6e0e055d..48805bda909 100644
--- a/doc/user/incident_management/index.md
+++ b/doc/user/incident_management/index.md
@@ -7,47 +7,49 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Incident Management
GitLab offers solutions for handling incidents in your applications and services,
-from setting up an alert with Prometheus, to receiving a notification through a
-monitoring tool like Slack, and [setting up Zoom calls](#zoom-integration-in-issues) with your
-support team. Incidents can display [metrics](#embed-metrics-in-incidents-and-issues)
-and [logs](#view-logs-from-metrics-panel).
+such as setting up Prometheus alerts, displaying metrics, and sending notifications.
## Configure incidents **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/4925) in GitLab Ultimate 11.11.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4925) in GitLab Ultimate 11.11.
-You can enable or disable Incident Management features in your project's
-**{settings}** **Settings > Operations > Incidents**. Issues can be created for
-each alert triggered, and separate email notifications can be sent to users with
-[Developer permissions](../permissions.md). Appropriately configured alerts include an
-[embedded chart](../project/integrations/prometheus.md#embedding-metrics-based-on-alerts-in-incident-issues)
-for the query corresponding to the alert. You can also configure GitLab to
-[close issues](../project/integrations/prometheus.md#taking-action-on-incidents-ultimate)
-when you receive notification that the alert is resolved.
-
-![Incident Management Settings](img/incident_management_settings.png)
+You can enable or disable Incident Management features in the GitLab user interface
+to create issues when alerts are triggered:
-### Create issues from alerts
+1. Navigate to **{settings}** **Settings > Operations > Incidents** and expand
+ **Incidents**:
-You can create GitLab issues from an alert notification. These issues contain
-information about the alerts to help you diagnose the source of the alerts.
+ ![Incident Management Settings](img/incident_management_settings.png)
-1. Visit your project's **{settings}** **Settings > Operations > Incidents**.
-1. Select the **Create an issue** checkbox for GitLab to create an issue from
- the incident.
-1. Select the template from the **Issue Template** dropdown.
- You can create your own [issue templates](../project/description_templates.md#creating-issue-templates)
- to [use within Incident Management](../project/integrations/prometheus.md#taking-action-on-incidents-ultimate).
+1. For GitLab versions 11.11 and greater, you can select the **Create an issue**
+ checkbox to create an issue based on your own
+ [issue templates](../project/description_templates.md#creating-issue-templates).
+ For more information, see
+ [Taking Action on Incidents](../project/integrations/prometheus.md#taking-action-on-incidents-ultimate) **(ULTIMATE)**.
+1. To create issues from alerts, select the template in the **Issue Template**
+ select box.
+1. To send [separate email notifications](#notify-developers-of-alerts) to users
+ with [Developer permissions](../permissions.md), select
+ **Send a separate email notification to Developers**.
1. Click **Save changes**.
-## Notify developers of alerts
+Appropriately configured alerts include an
+[embedded chart](../project/integrations/prometheus.md#embedding-metrics-based-on-alerts-in-incident-issues)
+for the query corresponding to the alert. You can also configure GitLab to
+[close issues](../project/integrations/prometheus.md#taking-action-on-incidents-ultimate)
+when you receive notification that the alert is resolved.
+
+### Notify developers of alerts
GitLab can react to the alerts triggered from your applications and services
-by creating issues and alerting developers through email. GitLab sends these emails
-to [owners and maintainers](../permissions.md) of the project. They contain details
-of the alert, and a link for more information.
+by creating issues and alerting developers through email. By default, GitLab
+sends these emails to [owners and maintainers](../permissions.md) of the project.
+These emails contain details of the alert, and a link for more information.
+
+To send separate email notifications to users with
+[Developer permissions](../permissions.md), see [Configure incidents](#configure-incidents-ultimate).
-### Configure Prometheus alerts
+## Configure Prometheus alerts
You can set up Prometheus alerts in:
@@ -57,7 +59,7 @@ You can set up Prometheus alerts in:
Prometheus alerts are created by the special Alert Bot user. You can't remove this
user, but it does not count toward your license limit.
-### Configure external generic alerts
+## Configure external generic alerts
GitLab can accept alerts from any source through a generic webhook receiver. When
[configuring the generic alerts integration](../project/integrations/generic_alerts.md),
@@ -65,7 +67,7 @@ GitLab creates a unique endpoint which receives a JSON-formatted, customizable p
## Embed metrics in incidents and issues
-You can embed metrics anywhere GitLab Markdown is used, such as descriptions,
+You can embed metrics anywhere [GitLab Markdown](../markdown.md) is used, such as descriptions,
comments on issues, and merge requests. Embedding metrics helps you share them
when discussing incidents or performance issues. You can output the dashboard directly
into any issue, merge request, epic, or any other Markdown text field in GitLab
@@ -78,10 +80,9 @@ in incidents and issue templates.
### Context menu
-From each of the embedded metrics panels, you can access more details
-about the data you're viewing from a context menu. You can access the context menu
-by clicking the **{ellipsis_v}** **More actions** dropdown box above the
-upper right corner of the panel. The options are:
+You can view more details about an embedded metrics panel from the context menu.
+To access the context menu, click the **{ellipsis_v}** **More actions** dropdown box
+above the upper right corner of the panel. The options are:
- [View logs](#view-logs-from-metrics-panel).
- **Download CSV** - Data from embedded charts can be
@@ -89,7 +90,7 @@ upper right corner of the panel. The options are:
#### View logs from metrics panel
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/201846) in GitLab Ultimate 12.8.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/201846) in GitLab Ultimate 12.8.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25455) to [GitLab Core](https://about.gitlab.com/pricing/) 12.9.
Viewing logs from a metrics panel can be useful if you're triaging an application
@@ -97,16 +98,16 @@ incident and need to [explore logs](../project/integrations/prometheus.md#view-l
from across your application. These logs help you understand what is affecting
your application's performance and resolve any problems.
-## Slack integration
+## Integrate incidents with Slack
Slack slash commands allow you to control GitLab and view GitLab content without leaving Slack.
Learn how to [set up Slack slash commands](../project/integrations/slack_slash_commands.md)
and how to [use the available slash commands](../../integration/slash_commands.md).
-## Zoom integration in issues
+## Integrate issues with Zoom
GitLab enables you to [associate a Zoom meeting with an issue](../project/issues/associate_zoom_meeting.md)
for synchronous communication during incident management. After starting a Zoom
-call for an incident, you can associate the conference call with an issue, so your
-team members can join without requesting a link.
+call for an incident, you can associate the conference call with an issue. Your
+team members can join the Zoom call without requesting a link.
diff --git a/doc/user/infrastructure/index.md b/doc/user/infrastructure/index.md
index 65237bf24e0..c17d1831b50 100644
--- a/doc/user/infrastructure/index.md
+++ b/doc/user/infrastructure/index.md
@@ -22,136 +22,146 @@ Amazon S3 or Google Cloud Storage. Its features include:
- Locking and unlocking state.
- Remote Terraform plan and apply execution.
-To get started, there are two different options when using GitLab managed Terraform State.
+To get started with a GitLab-managed Terraform State, there are two different options:
-- Use a local machine
-- Use GitLab CI
+- [Use a local machine](#get-started-using-local-development).
+- [Use GitLab CI](#get-started-using-gitlab-ci).
-## Get Started using local development
+## Get started using local development
-If you are planning to only run `terraform plan` and `terraform apply` commands from your local machine, this is a simple way to get started.
+If you plan to only run `terraform plan` and `terraform apply` commands from your
+local machine, this is a simple way to get started:
-First, create your project on your GitLab instance.
+1. Create your project on your GitLab instance.
+1. Navigate to **{settings}** **Settings > General** and note your **Project name**
+ and **Project ID**.
+1. Define the Terraform backend in your Terraform project to be:
-Next, define the Terraform backend in your Terraform project to be:
-
-```hcl
-terraform {
- backend "http" {
- }
-}
-```
-
-Finally, you need to run `terraform init` on your local machine and pass in the following options. The below example is using GitLab.com:
-
-```bash
-terraform init \
- -backend-config="address=https://gitlab.com/api/v4/projects/<YOUR-PROJECT-ID>/terraform/state/<YOUR-PROJECT-NAME>" \
- -backend-config="lock_address=https://gitlab.com/api/v4/projects/<YOUR-PROJECT-ID>/terraform/state/<YOUR-PROJECT-NAME>/lock" \
- -backend-config="unlock_address=https://gitlab.com/api/v4/projects/<YOUR-PROJECT-ID>/terraform/state/<YOUR-PROJECT-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"
-```
-
-This will initialize your Terraform state and store that state within your GitLab project.
-
-NOTE: YOUR-PROJECT-ID and YOUR-PROJECT-NAME can be accessed from the project main page.
-
-## Get Started using a GitLab CI
-
-Another route is to leverage GitLab CI to run your `terraform plan` and `terraform apply` commands.
-
-### Configure the CI variables
+ ```hcl
+ terraform {
+ backend "http" {
+ }
+ }
+ ```
-To use the Terraform backend, [first create a Personal Access Token](../profile/personal_access_tokens.md) with the `api` scope. Keep in mind that the Terraform backend is restricted to tokens with [Maintainer access](../permissions.md) to the repository.
+1. Create a [Personal Access Token](../profile/personal_access_tokens.md) with
+ the `api` scope. The Terraform backend is restricted to users with
+ [Maintainer access](../permissions.md) to the repository.
+
+1. On your local machine, run `terraform init`, passing in the following options,
+ replacing `<YOUR-PROJECT-NAME>`, `<YOUR-PROJECT-ID>`, `<YOUR-USERNAME>` and
+ `<YOUR-ACCESS-TOKEN>` with the relevant values. This command initializes your
+ Terraform state, and stores that state within your GitLab project. This example
+ uses `gitlab.com`:
+
+ ```shell
+ terraform init \
+ -backend-config="address=https://gitlab.com/api/v4/projects/<YOUR-PROJECT-ID>/terraform/state/<YOUR-PROJECT-NAME>" \
+ -backend-config="lock_address=https://gitlab.com/api/v4/projects/<YOUR-PROJECT-ID>/terraform/state/<YOUR-PROJECT-NAME>/lock" \
+ -backend-config="unlock_address=https://gitlab.com/api/v4/projects/<YOUR-PROJECT-ID>/terraform/state/<YOUR-PROJECT-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"
+ ```
-To keep the Personal Access Token secure, add it as a [CI/CD environment variable](../../ci/variables/README.md). In this example we set ours to the ENV: `GITLAB_TF_PASSWORD`.
+Next, [configure the backend](#configure-the-backend).
-If you are planning to use the ENV on a branch which is not protected, make sure to set the variable protection settings correctly.
+## Get started using GitLab CI
-### Configure the Terraform backend
+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 we need to define the [http backend](https://www.terraform.io/docs/backends/types/http.html). In your Terraform project add the following code block in a `.tf` file such as `backend.tf` or wherever you desire to define the remote backend:
+Next, [configure the backend](#configure-the-backend).
-```hcl
-terraform {
- backend "http" {
- }
-}
-```
+## Configure the backend
-### Configure the CI YAML file
+After executing the `terraform init` command, you must configure the Terraform backend
+and the CI YAML file:
-Finally, configure a `.gitlab-ci.yaml`, which lives in the root of your project repository.
+CAUTION: **Important:**
+The Terraform backend is restricted to users with [Maintainer access](../permissions.md)
+to the repository.
-In our case we are using a pre-built image:
+1. In your Terraform project, define the [HTTP backend](https://www.terraform.io/docs/backends/types/http.html)
+ by adding the following code block in a `.tf` file (such as `backend.tf`) to
+ define the remote backend:
-```yaml
-image:
- name: hashicorp/terraform:light
- entrypoint:
- - '/usr/bin/env'
- - 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
-```
-
-We then define some environment variables to make life easier. `GITLAB_TF_ADDRESS` is the URL of the GitLab instance where this pipeline runs, and `TF_ROOT` is the directory where the Terraform commands must be executed.
-
-```yaml
-variables:
- GITLAB_TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/${CI_PROJECT_NAME}
- TF_ROOT: ${CI_PROJECT_DIR}/environments/cloudflare/production
-
-cache:
- paths:
- - .terraform
-```
+ ```hcl
+ terraform {
+ backend "http" {
+ }
+ }
+ ```
-In a `before_script`, pass a `terraform init` call containing configuration parameters.
-These parameters correspond to variables required by the
-[http backend](https://www.terraform.io/docs/backends/types/http.html):
+1. In the root directory of your project repository, configure a `.gitlab-ci.yaml` file.
+ This example uses a pre-built image:
-```yaml
-before_script:
- - cd ${TF_ROOT}
- - terraform --version
- - terraform init -backend-config="address=${GITLAB_TF_ADDRESS}" -backend-config="lock_address=${GITLAB_TF_ADDRESS}/lock" -backend-config="unlock_address=${GITLAB_TF_ADDRESS}/lock" -backend-config="username=${GITLAB_USER_LOGIN}" -backend-config="password=${GITLAB_TF_PASSWORD}" -backend-config="lock_method=POST" -backend-config="unlock_method=DELETE" -backend-config="retry_wait_min=5"
+ ```yaml
+ image:
+ name: hashicorp/terraform:light
+ entrypoint:
+ - '/usr/bin/env'
+ - 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
+ ```
-stages:
- - validate
- - build
- - test
- - deploy
+1. In the `.gitlab-ci.yaml` file, define some environment variables to ease development. In this
+ example, `GITLAB_TF_ADDRESS` is the URL of the GitLab instance where this pipeline
+ runs, and `TF_ROOT` is the directory where the Terraform commands must be executed:
-validate:
- stage: validate
- script:
- - terraform validate
+ ```yaml
+ variables:
+ GITLAB_TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/${CI_PROJECT_NAME}
+ TF_ROOT: ${CI_PROJECT_DIR}/environments/cloudflare/production
-plan:
- stage: build
- script:
- - terraform plan
- - terraform show
+ cache:
+ paths:
+ - .terraform
+ ```
-apply:
- stage: deploy
- environment:
- name: production
- script:
- - terraform apply
- dependencies:
- - plan
- when: manual
- only:
- - master
-```
+1. In a `before_script`, pass a `terraform init` call containing configuration parameters
+ corresponding to variables required by the
+ [HTTP backend](https://www.terraform.io/docs/backends/types/http.html):
-### Push to GitLab
+ ```yaml
+ before_script:
+ - cd ${TF_ROOT}
+ - terraform --version
+ - terraform init -backend-config="address=${GITLAB_TF_ADDRESS}" -backend-config="lock_address=${GITLAB_TF_ADDRESS}/lock" -backend-config="unlock_address=${GITLAB_TF_ADDRESS}/lock" -backend-config="username=gitlab-ci-token" -backend-config="password=${CI_JOB_TOKEN}" -backend-config="lock_method=POST" -backend-config="unlock_method=DELETE" -backend-config="retry_wait_min=5"
+
+ stages:
+ - validate
+ - build
+ - test
+ - deploy
+
+ validate:
+ stage: validate
+ script:
+ - terraform validate
+
+ plan:
+ stage: build
+ script:
+ - terraform plan
+ - terraform show
+
+ apply:
+ stage: deploy
+ environment:
+ name: production
+ script:
+ - terraform apply
+ dependencies:
+ - plan
+ when: manual
+ only:
+ - master
+ ```
-Pushing your project to GitLab triggers a CI job pipeline, which runs the `terraform init`, `terraform validate`, and `terraform plan` commands automatically.
+1. Push your project to GitLab, which triggers a CI job pipeline. This pipeline runs
+ the `terraform init`, `terraform validate`, and `terraform plan` commands.
The output from the above `terraform` commands should be viewable in the job logs.
@@ -161,14 +171,14 @@ See [this reference project](https://gitlab.com/nicholasklick/gitlab-terraform-a
## Output Terraform Plan information into a merge request
-Using the [GitLab Terraform Report Artifact](../../ci/pipelines/job_artifacts.md#artifactsreportsterraform),
+Using the [GitLab Terraform Report artifact](../../ci/pipelines/job_artifacts.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 will create,
modify, or destroy.
-Let's explore how to configure a GitLab Terraform Report Artifact:
+Let's explore how to configure a GitLab Terraform Report artifact:
-1. First, for simplicity, let's define a few reusable variables to allow us to
+1. For simplicity, let's define a few reusable variables to allow us to
refer to these files multiple times:
```yaml
@@ -177,96 +187,39 @@ Let's explore how to configure a GitLab Terraform Report Artifact:
PLAN_JSON: tfplan.json
```
-1. Next we need to install `jq`, a [lightweight and flexible command-line JSON processor](https://stedolan.github.io/jq/). We will also create an alias for a specific `jq` command that parses out the extact 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)}'"
-```
-
-1. Finally, we define a `script` that runs `terraform plan` and also a `terraform show` which pipes the output and converts the relevant bits into a store variable `PLAN_JSON`. This json is then leveraged to create a [GitLab Terraform Report Artifact](../../ci/pipelines/job_artifacts.md#artifactsreportsterraform).
-
-The terraform report obtains a Terraform tfplan.json file. The collected Terraform plan report will be uploaded to GitLab as an artifact and will be automatically shown in merge requests.
-
-```yaml
-plan:
- stage: build
- script:
- - terraform plan -out=$PLAN
- - terraform show --json $PLAN | convert_report > $PLAN_JSON
- artifacts:
- name: plan
- paths:
- - $PLAN
- reports:
- terraform: $PLAN_JSON
-```
-
-A full `.gitlab-ci.yaml` file could look like this:
-
-```yaml
-image:
- name: hashicorp/terraform:light
- entrypoint:
- - '/usr/bin/env'
- - 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
-
-# Default output file for Terraform plan
-variables:
- GITLAB_TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/${CI_PROJECT_NAME}
- PLAN: plan.tfplan
- PLAN_JSON: tfplan.json
- TF_ROOT: ${CI_PROJECT_DIR}
-
-cache:
- paths:
- - .terraform
-
-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)}'"
- - cd ${TF_ROOT}
- - terraform --version
- - terraform init -backend-config="address=${GITLAB_TF_ADDRESS}" -backend-config="lock_address=${GITLAB_TF_ADDRESS}/lock" -backend-config="unlock_address=${GITLAB_TF_ADDRESS}/lock" -backend-config="username=${GITLAB_USER_LOGIN}" -backend-config="password=${GITLAB_TF_PASSWORD}" -backend-config="lock_method=POST" -backend-config="unlock_method=DELETE" -backend-config="retry_wait_min=5"
-
-stages:
- - validate
- - build
- - deploy
+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:
-validate:
- stage: validate
- script:
- - terraform validate
+ ```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)}'"
+ ```
-plan:
- stage: build
- script:
- - terraform plan -out=$PLAN
- - terraform show --json $PLAN | convert_report > $PLAN_JSON
- artifacts:
- name: plan
- paths:
- - ${TF_ROOT}/plan.tfplan
- reports:
- terraform: ${TF_ROOT}/tfplan.json
+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/pipelines/job_artifacts.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.
-# Separate apply job for manual launching Terraform as it can be destructive
-# action.
-apply:
- stage: deploy
- environment:
- name: production
- script:
- - terraform apply -input=false $PLAN
- dependencies:
- - plan
- when: manual
- only:
- - master
+ ```yaml
+ plan:
+ stage: build
+ script:
+ - terraform plan -out=$PLAN
+ - terraform show --json $PLAN | convert_report > $PLAN_JSON
+ artifacts:
+ name: plan
+ paths:
+ - $PLAN
+ reports:
+ terraform: $PLAN_JSON
+ ```
-```
+ For a full example, see [Example `.gitlab-ci.yaml` file](#example-gitlab-ciyaml-file).
1. Running the pipeline displays the widget in the merge request, like this:
diff --git a/doc/user/instance/clusters/index.md b/doc/user/instance/clusters/index.md
index 495bfdeed6e..8059b8ca642 100644
--- a/doc/user/instance/clusters/index.md
+++ b/doc/user/instance/clusters/index.md
@@ -1,6 +1,6 @@
# Instance-level Kubernetes clusters
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/39840) in GitLab 11.11.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/39840) in GitLab 11.11.
## Overview
@@ -12,8 +12,7 @@ projects.
## Cluster precedence
-GitLab will try [to match](../../../ci/environments/index.md#scoping-environments-with-specs) clusters in
-the following order:
+GitLab will try to match clusters in the following order:
- Project-level clusters.
- Group-level clusters.
diff --git a/doc/user/instance_statistics/dev_ops_score.md b/doc/user/instance_statistics/dev_ops_score.md
index 216a79f8beb..73b9532015d 100644
--- a/doc/user/instance_statistics/dev_ops_score.md
+++ b/doc/user/instance_statistics/dev_ops_score.md
@@ -1,7 +1,7 @@
# DevOps Score
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/30469) in GitLab 9.3.
-> - [Renamed from Conversational Development Index](https://gitlab.com/gitlab-org/gitlab/issues/20976) in GitLab 12.6.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/30469) in GitLab 9.3.
+> - [Renamed from Conversational Development Index](https://gitlab.com/gitlab-org/gitlab/-/issues/20976) in GitLab 12.6.
NOTE: **Note:**
Your GitLab instance's [usage ping](../admin_area/settings/usage_statistics.md#usage-ping-core-only) must be activated in order to use this feature.
diff --git a/doc/user/instance_statistics/index.md b/doc/user/instance_statistics/index.md
index 15e061b118e..b09651e04ee 100644
--- a/doc/user/instance_statistics/index.md
+++ b/doc/user/instance_statistics/index.md
@@ -1,6 +1,6 @@
# Instance statistics
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/41416) in GitLab 11.2.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41416) in GitLab 11.2.
Instance statistics gives users or admins access to instance-wide analytics.
They are accessible to all users by default (GitLab admins can restrict its
diff --git a/doc/user/instance_statistics/user_cohorts.md b/doc/user/instance_statistics/user_cohorts.md
index b3ef99473e4..8da2d57d474 100644
--- a/doc/user/instance_statistics/user_cohorts.md
+++ b/doc/user/instance_statistics/user_cohorts.md
@@ -1,6 +1,6 @@
# Cohorts
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/23361) in GitLab 9.1.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/23361) in GitLab 9.1.
As a benefit of having the [usage ping active](../admin_area/settings/usage_statistics.md),
GitLab lets you analyze the users' activities over time of your GitLab installation.
@@ -24,6 +24,6 @@ How do we measure the activity of users? GitLab considers a user active if:
- The user signs in.
- The user has Git activity (whether push or pull).
-- The user visits pages related to Dashboards, Projects, Issues, and Merge Requests ([introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/54947) in GitLab 11.8).
+- The user visits pages related to Dashboards, Projects, Issues, and Merge Requests ([introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/54947) in GitLab 11.8).
- The user uses the API
- The user uses the GraphQL API
diff --git a/doc/user/markdown.md b/doc/user/markdown.md
index 102eb1f8f53..0d028cfe77a 100644
--- a/doc/user/markdown.md
+++ b/doc/user/markdown.md
@@ -1,3 +1,9 @@
+---
+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/#designated-technical-writers
+---
+
# GitLab Markdown
This Markdown guide is **valid only for GitLab's internal Markdown rendering system for entries and files**.
@@ -5,7 +11,7 @@ It is **not** valid for the [GitLab documentation website](https://docs.gitlab.c
or [GitLab's main website](https://about.gitlab.com), as they both use
[Kramdown](https://kramdown.gettalong.org) as their Markdown engine. The documentation
website uses an extended Kramdown gem, [GitLab Kramdown](https://gitlab.com/gitlab-org/gitlab_kramdown).
-Consult the [GitLab Kramdown Guide](https://about.gitlab.com/handbook/engineering/ux/technical-writing/markdown-guide/)
+Consult the [GitLab Kramdown Guide](https://about.gitlab.com/handbook/markdown-guide/)
for a complete Kramdown reference.
NOTE: **Note:** We encourage you to view this document as [rendered by GitLab itself](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/user/markdown.md).
@@ -76,7 +82,7 @@ NOTE: **Note:** We will flag any significant differences between Redcarpet and C
If you have a large volume of Markdown files, it can be tedious to determine
if they will display correctly or not. You can use the
[diff_redcarpet_cmark](https://gitlab.com/digitalmoksha/diff_redcarpet_cmark)
-tool (not an officially supported product) to generate a list of files, and the
+tool (not an officially supported product) to generate a list of files and the
differences between how RedCarpet and CommonMark render the files. It can give
an indication if anything needs to be changed - often nothing will need
to change.
@@ -253,7 +259,7 @@ Consult the [Emoji Cheat Sheet](https://www.webfx.com/tools/emoji-cheat-sheet/)
> **Note:** The emoji example above uses hard-coded images for this documentation. The emoji,
when rendered within GitLab, may appear different depending on the OS and browser used.
-Most emoji are natively supported on macOS, Windows, iOS, Android and will fallback to image-based emoji where there is lack of support.
+Most emoji are natively supported on macOS, Windows, iOS, Android, and will fall back on image-based emoji where there is no support.
NOTE: **Note:** On Linux, you can download [Noto Color Emoji](https://www.google.com/get/noto/help/emoji/)
to get full native emoji support. Ubuntu 18.04 (like many modern Linux distributions) has
@@ -272,7 +278,7 @@ in a box at the top of the document, before the rendered HTML content. To view a
you can toggle between the source and rendered version of a [GitLab documentation file](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/README.md).
In GitLab, front matter is only used in Markdown files and wiki pages, not the other
-places where Markdown formatting is supported. It must be at the very top of the document,
+places where Markdown formatting is supported. It must be at the very top of the document
and must be between delimiters, as explained below.
The following delimiters are supported:
@@ -405,7 +411,7 @@ GFM recognizes special GitLab related references. For example, you can easily re
an issue, a commit, a team member, or even the whole team within a project. GFM will turn
that reference into a link so you can navigate between them easily.
-Additionally, GFM recognizes certain cross-project references, and also has a shorthand
+Additionally, GFM recognizes certain cross-project references and also has a shorthand
version to reference other projects from the same namespace.
GFM will recognize the following:
@@ -435,8 +441,8 @@ GFM will recognize the following:
In addition to this, links to some objects are also recognized and formatted. Some examples of these are:
- Comments on issues: `"https://gitlab.com/gitlab-org/gitlab/-/issues/1234#note_101075757"`, which will be rendered as `#1234 (note1)`
-- The issues designs tab: `"https://gitlab.com/gitlab-org/gitlab/issues/1234/designs"`, which will be rendered as `#1234 (designs)`.
- **(PREMIUM)**
+- The issues designs tab: `"https://gitlab.com/gitlab-org/gitlab/-/issues/1234/designs"`, which will be rendered as `#1234 (designs)`.
+- Links to individual designs: `"https://gitlab.com/gitlab-org/gitlab/-/issues/1234/designs/layout.png"`, which will be rendered as `#1234[layout.png]`.
### Task lists
@@ -825,7 +831,7 @@ Regardless of the tag names, the relative order of the reference tags determines
numbering.
Reference tags can use letters and other characters. Avoid using lowercase `w` or an underscore
-(`_`) in footnote tag names until [this bug](https://gitlab.com/gitlab-org/gitlab/issues/24423) is
+(`_`) in footnote tag names until [this bug](https://gitlab.com/gitlab-org/gitlab/-/issues/24423) is
resolved.
<!--
@@ -1011,7 +1017,7 @@ You can also use raw HTML in your Markdown, and it will usually work pretty well
See the documentation for HTML::Pipeline's [SanitizationFilter](https://github.com/jch/html-pipeline/blob/v2.12.3/lib/html/pipeline/sanitization_filter.rb#L42)
class for the list of allowed HTML tags and attributes. In addition to the default
-`SanitizationFilter` whitelist, GitLab allows `span`, `abbr`, `details` and `summary` elements.
+`SanitizationFilter` allowlist, GitLab allows `span`, `abbr`, `details` and `summary` elements.
```html
<dl>
@@ -1103,6 +1109,11 @@ These details <em>will</em> remain <strong>hidden</strong> until expanded.
Markdown inside these tags is supported as well.
+NOTE: **Note:**
+If your Markdown isn't rendering correctly, try adding
+`{::options parse_block_html="true" /}` to the top of the page, and add
+`markdown="span"` to the opening summary tag like this: `<summary markdown="span">`.
+
Remember to leave a blank line after the `</summary>` tag and before the `</details>` tag,
as shown in the example:
@@ -1427,7 +1438,9 @@ Example:
Additionally, you can choose the alignment of text within columns by adding colons (`:`)
to the sides of the "dash" lines in the second row. This will affect every cell in the column.
-> Note that the headers are always right aligned [within GitLab itself](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/user/markdown.md#tables).
+NOTE: **Note:**
+[Within GitLab itself](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/user/markdown.md#tables),
+the headers are always left-aligned in Chrome and Firefox, and centered in Safari.
```markdown
| Left Aligned | Centered | Right Aligned | Left Aligned | Centered | Right Aligned |
@@ -1443,7 +1456,7 @@ to the sides of the "dash" lines in the second row. This will affect every cell
#### Copy from spreadsheet and paste in Markdown
-[Introduced](https://gitlab.com/gitlab-org/gitlab/issues/27205) in GitLab 12.7.
+[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27205) in GitLab 12.7.
If you're working in spreadsheet software (for example, Microsoft Excel, Google
Sheets, or Apple Numbers), you can copy from a spreadsheet, and GitLab will
diff --git a/doc/user/operations_dashboard/index.md b/doc/user/operations_dashboard/index.md
index 531422ca077..5a2ff410253 100644
--- a/doc/user/operations_dashboard/index.md
+++ b/doc/user/operations_dashboard/index.md
@@ -1,6 +1,6 @@
# Operations Dashboard **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/5781) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.5. [Moved](https://gitlab.com/gitlab-org/gitlab/issues/9218) to [GitLab Premium](https://about.gitlab.com/pricing/) in 11.10.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5781) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.5. [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/9218) to [GitLab Premium](https://about.gitlab.com/pricing/) in 11.10.
The Operations Dashboard provides a summary of each project's operational health,
including pipeline and alert status.
diff --git a/doc/user/packages/composer_repository/index.md b/doc/user/packages/composer_repository/index.md
new file mode 100644
index 00000000000..8a7c70ec74d
--- /dev/null
+++ b/doc/user/packages/composer_repository/index.md
@@ -0,0 +1,155 @@
+---
+stage: Package
+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/#designated-technical-writers
+---
+
+# GitLab Composer Repository **(PREMIUM)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15886) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.1.
+
+With the GitLab Composer Repository, every project can have its own space to store [Composer](https://getcomposer.org/) packages.
+
+## Enabling the Composer Repository
+
+NOTE: **Note:**
+This option is available only if your GitLab administrator has
+[enabled support for the Package Registry](../../../administration/packages/index.md). **(PREMIUM ONLY)**
+
+After the Composer Repository is enabled, it will be available for all new projects
+by default. To enable it for existing projects, or if you want to disable it:
+
+1. Navigate to your project's **Settings > General > Permissions**.
+1. Find the Packages feature and enable or disable it.
+1. Click on **Save changes** for the changes to take effect.
+
+You should then be able to see the **Packages & Registries** section on the left sidebar.
+
+## Getting started
+
+This section will cover creating a new example Composer package to publish. This is a
+quickstart to test out the **GitLab Composer Registry**.
+
+You will need a recent version of [Composer](https://getcomposer.org/).
+
+### Creating a package project
+
+Understanding how to create a full Composer project is outside the scope of this
+guide, but you can create a small package to test out the registry. Start by
+creating a new directory called `my-composer-package`:
+
+```shell
+mkdir my-composer-package && cd my-composer-package
+```
+
+Create a new `composer.json` file inside this directory to set up the basic project:
+
+```shell
+touch composer.json
+```
+
+Inside `composer.json`, add the following code:
+
+```json
+{
+ "name": "<namespace>/composer-test",
+ "type": "library",
+ "license": "GPL-3.0-only",
+ "version": "1.0.0"
+}
+```
+
+Replace `<namespace>` with a unique namespace like your GitLab username or group name.
+
+After this basic package structure is created, we need to tag it in Git and push it to the repository.
+
+```shell
+git init
+git add composer.json
+git commit -m 'Composer package test'
+git tag v1.0.0
+git add origin git@gitlab.com:<namespace>/<project-name>.git
+git push origin v1.0.0
+```
+
+### Publishing the package
+
+Now that the basics of our project is completed, we can publish the package.
+For accomplishing this you will need the following:
+
+- A personal access token. You can generate a [personal access token](../../../user/profile/personal_access_tokens.md) with the scope set to `api` for repository authentication.
+- Your project ID which can be found on the home page of your project.
+
+To publish the package hosted on GitLab we'll need to make a `POST` to the GitLab package API using a tool like `curl`:
+
+```shell
+curl --data tag=<tag> 'https://__token__:<personal-access-token>@gitlab.com/api/v4/projects/<project_id>/packages/composer'
+```
+
+Where:
+
+- `<personal-access-token>` is your personal access token.
+- `<project_id>` is your project ID.
+- `<tag>` is the Git tag name of the version you want to publish. In this example it should be `v1.0.0`. Notice that instead of `tag=<tag>` you can also use `branch=<branch>` to publish branches.
+
+If the above command succeeds, you now should be able to see the package under the **Packages & Registries** section of your project page.
+
+### Installing a package
+
+To install your package you will need:
+
+- A personal access token. You can generate a [personal access token](../../../user/profile/personal_access_tokens.md) with the scope set to `api` for repository authentication.
+- Your group ID which can be found on the home page of your project's group.
+
+Add the GitLab Composer package repository to your existing project's `composer.json` file, along with the package name and version you want to install like so:
+
+```json
+{
+ ...
+ "repositories": [
+ { "type": "composer", "url": "https://gitlab.com/api/v4/group/<group_id>/-/packages/composer/packages.json" }
+ ],
+ "require": {
+ ...
+ "<package_name>": "<version>"
+ },
+ ...
+}
+```
+
+Where:
+
+- `<group_id>` is the group ID found under your project's group page.
+- `<package_name>` is your package name as defined in your package's `composer.json` file.
+- `<version>` is your package version (`1.0.0` in this example).
+
+You will also need to create a `auth.json` file with your GitLab credentials:
+
+```json
+{
+ "http-basic": {
+ "gitlab.com": {
+ "username": "___token___",
+ "password": "<personal_access_token>"
+ }
+ }
+}
+```
+
+Where:
+
+- `<personal_access_token>` is your personal access token.
+
+With the `composer.json` and `auth.json` files configured, you can install the package by running `composer`:
+
+```shell
+composer update
+```
+
+If successful, you should be able to see the output indicating that the package has been successfully installed.
+
+CAUTION: **Important:**
+Make sure to never commit the `auth.json` file to your repository. To install packages from a CI job,
+consider using the [`composer config`](https://getcomposer.org/doc/articles/handling-private-packages-with-satis.md#authentication) tool with your personal access token
+stored in a [GitLab CI/CD environment variable](../../../ci/variables/README.md) or in
+[Hashicorp Vault](../../../ci/examples/authenticating-with-hashicorp-vault/index.md).
diff --git a/doc/user/packages/conan_repository/index.md b/doc/user/packages/conan_repository/index.md
index a56a67d4959..020028dfc10 100644
--- a/doc/user/packages/conan_repository/index.md
+++ b/doc/user/packages/conan_repository/index.md
@@ -1,6 +1,12 @@
+---
+stage: Package
+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/#designated-technical-writers
+---
+
# GitLab Conan Repository **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/8248) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8248) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.6.
With the GitLab Conan Repository, every
project can have its own space to store Conan packages.
@@ -184,7 +190,7 @@ it is not possible due to a naming collision. For example:
| `gitlab-org/gitlab-ce` | `my-package/1.0.0@foo/stable` | No |
NOTE: **Note:**
-A future iteration will extend support to [project and group level](https://gitlab.com/gitlab-org/gitlab/issues/11679) remotes which will allow for more flexible naming conventions.
+A future iteration will extend support to [project and group level](https://gitlab.com/gitlab-org/gitlab/-/issues/11679) remotes which will allow for more flexible naming conventions.
## Installing a package
@@ -271,7 +277,7 @@ The GitLab Conan repository supports the following Conan CLI commands:
## Using GitLab CI with Conan packages
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/11678) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11678) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.7.
To work with Conan commands within [GitLab CI/CD](./../../../ci/README.md), you can use
`CI_JOB_TOKEN` in place of the personal access token in your commands.
diff --git a/doc/user/packages/container_registry/img/container_registry_group_repositories_v13_0.png b/doc/user/packages/container_registry/img/container_registry_group_repositories_v13_0.png
deleted file mode 100644
index 14119abd56a..00000000000
--- a/doc/user/packages/container_registry/img/container_registry_group_repositories_v13_0.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/packages/container_registry/img/container_registry_group_repositories_v13_1.png b/doc/user/packages/container_registry/img/container_registry_group_repositories_v13_1.png
new file mode 100644
index 00000000000..bbbba44eb9b
--- /dev/null
+++ b/doc/user/packages/container_registry/img/container_registry_group_repositories_v13_1.png
Binary files differ
diff --git a/doc/user/packages/container_registry/img/container_registry_repositories_v13_0.png b/doc/user/packages/container_registry/img/container_registry_repositories_v13_0.png
deleted file mode 100644
index 7286007b953..00000000000
--- a/doc/user/packages/container_registry/img/container_registry_repositories_v13_0.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/packages/container_registry/img/container_registry_repositories_v13_1.png b/doc/user/packages/container_registry/img/container_registry_repositories_v13_1.png
new file mode 100644
index 00000000000..13a6d1a4470
--- /dev/null
+++ b/doc/user/packages/container_registry/img/container_registry_repositories_v13_1.png
Binary files differ
diff --git a/doc/user/packages/container_registry/img/container_registry_repositories_with_quickstart_v13_0.png b/doc/user/packages/container_registry/img/container_registry_repositories_with_quickstart_v13_0.png
deleted file mode 100644
index f7c3aafcc8e..00000000000
--- a/doc/user/packages/container_registry/img/container_registry_repositories_with_quickstart_v13_0.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/packages/container_registry/img/container_registry_repositories_with_quickstart_v13_1.png b/doc/user/packages/container_registry/img/container_registry_repositories_with_quickstart_v13_1.png
new file mode 100644
index 00000000000..35a02182a77
--- /dev/null
+++ b/doc/user/packages/container_registry/img/container_registry_repositories_with_quickstart_v13_1.png
Binary files differ
diff --git a/doc/user/packages/container_registry/index.md b/doc/user/packages/container_registry/index.md
index 5e642e1e21c..eb1933de62a 100644
--- a/doc/user/packages/container_registry/index.md
+++ b/doc/user/packages/container_registry/index.md
@@ -1,3 +1,9 @@
+---
+stage: Package
+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/#designated-technical-writers
+---
+
# GitLab Container Registry
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/4040) in GitLab 8.8.
@@ -20,7 +26,7 @@ have its own space to store its Docker images.
You can read more about Docker Registry at <https://docs.docker.com/registry/introduction/>.
-![Container Registry repositories](img/container_registry_repositories_v13_0.png)
+![Container Registry repositories](img/container_registry_repositories_v13_1.png)
## Enable the Container Registry for your project
@@ -56,7 +62,7 @@ for both projects and groups.
Navigate to your project's **{package}** **Packages & Registries > Container Registry**.
-![Container Registry project repositories](img/container_registry_repositories_with_quickstart_v13_0.png)
+![Container Registry project repositories](img/container_registry_repositories_with_quickstart_v13_1.png)
This view will:
@@ -71,7 +77,7 @@ This view will:
Navigate to your groups's **{package}** **Packages & Registries > Container Registry**.
-![Container Registry group repositories](img/container_registry_group_repositories_v13_0.png)
+![Container Registry group repositories](img/container_registry_group_repositories_v13_1.png)
This view will:
@@ -237,29 +243,29 @@ For private and internal projects:
### Container Registry examples with GitLab CI/CD
-If you're using docker-in-docker on your Runners, this is how your `.gitlab-ci.yml`
+If you're using Docker-in-Docker on your Runners, this is how your `.gitlab-ci.yml`
should look similar to this:
```yaml
build:
- image: docker:19.03.8
+ image: docker:19.03.11
stage: build
services:
- - docker:19.03.8-dind
+ - docker:19.03.11-dind
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $CI_REGISTRY/group/project/image:latest .
- docker push $CI_REGISTRY/group/project/image:latest
```
-You can also make use of [other variables](../../../ci/variables/README.md) to avoid hardcoding:
+You can also make use of [other variables](../../../ci/variables/README.md) to avoid hard-coding:
```yaml
build:
- image: docker:19.03.8
+ image: docker:19.03.11
stage: build
services:
- - docker:19.03.8-dind
+ - docker:19.03.11-dind
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
script:
@@ -282,9 +288,9 @@ when needed. Changes to `master` also get tagged as `latest` and deployed using
an application-specific deploy script:
```yaml
-image: docker:19.03.8
+image: docker:19.03.11
services:
- - docker:19.03.8-dind
+ - docker:19.03.11-dind
stages:
- build
@@ -344,11 +350,11 @@ or [Kubernetes](https://docs.gitlab.com/runner/executors/kubernetes.html) execut
make sure that [`pull_policy`](https://docs.gitlab.com/runner/executors/docker.html#how-pull-policies-work)
is set to `always`.
-### Using a docker-in-docker image from your Container Registry
+### Using a Docker-in-Docker image from your Container Registry
-If you want to use your own Docker images for docker-in-docker, there are a few
+If you want to use your own Docker images for Docker-in-Docker, there are a few
things you need to do in addition to the steps in the
-[docker-in-docker](../../../ci/docker/using_docker_build.md#use-docker-in-docker-workflow-with-docker-executor) section:
+[Docker-in-Docker](../../../ci/docker/using_docker_build.md#use-docker-in-docker-workflow-with-docker-executor) section:
1. Update the `image` and `service` to point to your registry.
1. Add a service [alias](../../../ci/yaml/README.md#servicesalias).
@@ -357,9 +363,9 @@ Below is an example of what your `.gitlab-ci.yml` should look like:
```yaml
build:
- image: $CI_REGISTRY/group/project/docker:19.03.8
+ image: $CI_REGISTRY/group/project/docker:19.03.11
services:
- - name: $CI_REGISTRY/group/project/docker:19.03.8-dind
+ - name: $CI_REGISTRY/group/project/docker:19.03.11-dind
alias: docker
stage: build
script:
@@ -367,7 +373,7 @@ Below is an example of what your `.gitlab-ci.yml` should look like:
- docker run my-docker-image /script/to/run/tests
```
-If you forget to set the service alias, the `docker:19.03.8` image won't find the
+If you forget to set the service alias, the `docker:19.03.11` image won't find the
`dind` service, and an error like the following will be thrown:
```plaintext
@@ -437,10 +443,10 @@ stages:
- clean
build_image:
- image: docker:19.03.8
+ image: docker:19.03.11
stage: build
services:
- - docker:19.03.8-dind
+ - docker:19.03.11-dind
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
script:
@@ -453,10 +459,10 @@ build_image:
- master
delete_image:
- image: docker:19.03.8
+ image: docker:19.03.11
stage: clean
services:
- - docker:19.03.8-dind
+ - docker:19.03.11-dind
variables:
IMAGE_TAG: $CI_PROJECT_PATH:$CI_COMMIT_REF_SLUG
REG_SHA256: ade837fc5224acd8c34732bf54a94f579b47851cc6a7fd5899a98386b782e228
@@ -487,11 +493,12 @@ older tags and images are regularly removed from the Container Registry.
## Expiration policy
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/15398) in GitLab 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15398) in GitLab 12.8.
NOTE: **Note:**
-Expiration policies for projects created before GitLab 12.8 may be enabled by an
-admin in the [CI/CD Package Registry settings](./../../admin_area/settings/index.md#cicd).
+For GitLab.com, expiration policies are not available for projects created before GitLab 12.8.
+For self-managed instances, expiration policies may be enabled by an admin in the
+[CI/CD Package Registry settings](./../../admin_area/settings/index.md#cicd).
Note the inherent [risks involved](./index.md#use-with-external-container-registries).
It is possible to create a per-project expiration policy, so that you can make sure that
@@ -506,7 +513,7 @@ then goes through a process of excluding tags from it until only the ones to be
1. Excludes any tags that do not have a manifest (not part of the options).
1. Orders the remaining tags by `created_date`.
1. Excludes from the list the N tags based on the `keep_n` value (Number of tags to retain).
-1. Excludes from the list the tags older than the `older_than` value (Expiration interval).
+1. Excludes from the list the tags more recent than the `older_than` value (Expiration interval).
1. Excludes from the list any tags matching the `name_regex_keep` value (Images to preserve).
1. Finally, the remaining tags in the list are deleted from the Container Registry.
@@ -525,6 +532,17 @@ The UI allows you to configure the following:
- **Docker tags with names matching this regex pattern will expire:** the regex used to determine what tags should be expired. To qualify all tags for expiration, use the default value of `.*`.
- **Docker tags with names matching this regex pattern will be preserved:** the regex used to determine what tags should be preserved. To preserve all tags, use the default value of `.*`.
+#### Troubleshooting expiration policies
+
+If you see the following message:
+
+"Something went wrong while updating the expiration policy."
+
+Check the regex patterns to ensure they are valid.
+
+You can use [Rubular](https://rubular.com/) to check your regex.
+View some common [regex pattern examples](#regex-pattern-examples).
+
### Managing project expiration policy through the API
You can set, update, and disable the expiration policies using the GitLab API.
@@ -548,6 +566,36 @@ run the policy may get backed up or fail completely. It is recommended you only
policies for projects that were created before GitLab 12.8 if you are confident the amount of tags
being cleaned up will be minimal.
+### Regex pattern examples
+
+Expiration policies use regex patterns to determine which tags should be preserved or removed, both in the UI and the API.
+
+Here are examples of regex patterns you may want to use:
+
+- Match all tags:
+
+ ```plaintext
+ .*
+ ```
+
+- Match tags that start with `v`:
+
+ ```plaintext
+ v.+
+ ```
+
+- Match tags that contain `master`:
+
+ ```plaintext
+ master
+ ```
+
+- Match tags that either start with `v`, contain `master`, or contain `release`:
+
+ ```plaintext
+ (?:v.+|master|release)
+ ```
+
## Limitations
- Moving or renaming existing Container Registry repositories is not supported
diff --git a/doc/user/packages/dependency_proxy/index.md b/doc/user/packages/dependency_proxy/index.md
index be9710053dd..e68883a1382 100644
--- a/doc/user/packages/dependency_proxy/index.md
+++ b/doc/user/packages/dependency_proxy/index.md
@@ -1,6 +1,12 @@
+---
+stage: Package
+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/#designated-technical-writers
+---
+
# Dependency Proxy **(PREMIUM ONLY)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/7934) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.11.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7934) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.11.
NOTE: **Note:**
This is the user guide. In order to use the dependency proxy, an administrator
diff --git a/doc/user/packages/go_proxy/index.md b/doc/user/packages/go_proxy/index.md
new file mode 100644
index 00000000000..a705b956d30
--- /dev/null
+++ b/doc/user/packages/go_proxy/index.md
@@ -0,0 +1,169 @@
+---
+stage: Package
+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/#designated-technical-writers
+---
+
+# GitLab Go Proxy **(PREMIUM)**
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27376) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.1.
+> - 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](#enable-the-go-proxy). **(PREMIUM)**
+
+With the Go proxy for GitLab, every project in GitLab can be fetched with the
+[Go proxy protocol](https://proxy.golang.org/).
+
+## Prerequisites
+
+### Enable the Go proxy
+
+The Go proxy for GitLab is under development and not ready for production use, due to
+[potential performance issues with large repositories](https://gitlab.com/gitlab-org/gitlab/-/issues/218083).
+
+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 for your instance.
+
+To enable it:
+
+```ruby
+Feature.enable(:go_proxy) # or
+```
+
+To disable it:
+
+```ruby
+Feature.disable(:go_proxy)
+```
+
+To enable or disable it for specific projects:
+
+```ruby
+Feature.enable(:go_proxy, Project.find(1))
+Feature.disable(:go_proxy, Project.find(2))
+```
+
+### Enable the Package Registry
+
+The Package Registry is enabled for new projects by default. If you cannot find
+the **{package}** **Packages > List** entry under your project's sidebar, verify
+the following:
+
+1. Your GitLab administrator has
+ [enabled support for the Package Registry](../../../administration/packages/index.md). **(PREMIUM ONLY)**
+1. The Package Registry is [enabled for your project](../index.md).
+
+NOTE: **Note:**
+GitLab does not currently display Go modules in the **Packages Registry** of a project.
+Follow [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/213770) for details.
+
+## Add GitLab as a Go proxy
+
+NOTE: **Note:**
+To use a Go proxy, you must be using Go 1.13 or later.
+
+The available proxy endpoints are:
+
+- Project - can fetch modules defined by a project - `/api/v4/projects/:id/packages/go`
+
+To use the Go proxy for GitLab to fetch Go modules from GitLab, add the
+appropriate proxy endpoint to `GOPROXY`. For details on setting Go environment
+variables, see [Set environment variables](#set-environment-variables). For
+details on configuring `GOPROXY`, see [Dependency Management in Go >
+Proxies](../../../development/go_guide/dependencies.md#proxies).
+
+For example, adding the project-specific endpoint to `GOPROXY` will tell Go
+to initially query that endpoint and fall back to the default behavior:
+
+```shell
+go env -w GOPROXY='https://gitlab.com/api/v4/projects/1234/packages/go,https://proxy.golang.org,direct'
+```
+
+With this configuration, Go fetches dependencies as follows:
+
+1. Attempt to fetch from the project-specific Go proxy.
+1. Attempt to fetch from [proxy.golang.org](https://proxy.golang.org).
+1. Fetch directly with version control system operations (such as `git clone`,
+ `svn checkout`, and so on).
+
+If `GOPROXY` is not specified, Go follows steps 2 and 3, which corresponds to
+setting `GOPROXY` to `https://proxy.golang.org,direct`. If `GOPROXY` only
+contains the project-specific endpoint, Go will only query that endpoint.
+
+## Fetch modules from private projects
+
+`go` does not support transmitting credentials over insecure connections. The
+steps below work only if GitLab is configured for HTTPS.
+
+1. Configure Go to include HTTP basic authentication credentials when fetching
+ from the Go proxy for GitLab.
+1. Configure Go to skip downloading of checksums for private GitLab projects
+ from the public checksum database.
+
+### Enable request authentication
+
+Create a [personal access token](../../profile/personal_access_tokens.md) with
+the `api` or `read_api` scope and add it to
+[`~/.netrc`](https://ec.haxx.se/usingcurl/usingcurl-netrc):
+
+```netrc
+machine <url> login <username> password <token>
+```
+
+`<url>` should be the URL of the GitLab instance, for example `gitlab.com`.
+`<username>` and `<token>` should be your username and the personal access
+token, respectively.
+
+### Disable checksum database queries
+
+When downloading dependencies, by default Go 1.13 and later validate fetched
+sources against the checksum database `sum.golang.org`. If the checksum of the
+fetched sources does not match the checksum from the database, Go will not build
+the dependency. This causes private modules to fail to build, as
+`sum.golang.org` cannot fetch the source of private modules and thus cannot
+provide a checksum. To resolve this issue, `GONOSUMDB` should be set to a
+comma-separated list of private projects. For details on setting Go environment
+variables, see [Set environment variables](#set-environment-variables). For more
+details on disabling this feature of Go, see [Dependency Management in Go >
+Checksums](../../../development/go_guide/dependencies.md#checksums).
+
+For example, to disable checksum queries for `gitlab.com/my/project`, set `GONOSUMDB`:
+
+```shell
+go env -w GONOSUMDB='gitlab.com/my/project,<previous value>'
+```
+
+## Working with Go
+
+If you are unfamiliar with managing dependencies in Go, or Go in general,
+consider reviewing the following documentation:
+
+- [Dependency Management in Go](../../../development/go_guide/dependencies.md)
+- [Go Modules Reference](https://golang.org/ref/mod)
+- [Documentation (golang.org)](https://golang.org/doc/)
+- [Learn (learn.go.dev)](https://learn.go.dev/)
+
+### Set environment variables
+
+Go uses environment variables to control various features. These can be managed
+in all the usual ways, but Go 1.14 will read and write Go environment variables
+from and to a special Go environment file, `~/.go/env` by default. If `GOENV` is
+set to a file, Go will read and write that file instead. If `GOENV` is not set
+but `GOPATH` is set, Go will read and write `$GOPATH/env`.
+
+Go environment variables can be read with `go env <var>` and, in Go 1.14 and
+later, can be written with `go env -w <var>=<value>`. For example, `go env
+GOPATH` or `go env -w GOPATH=/go`.
+
+### Release a module
+
+Go modules and module versions are defined by source repositories, such as Git,
+SVN, Mercurial, and so on. A module is a repository containing `go.mod` and Go
+files. Module versions are defined by VCS tags. To publish a module, push
+`go.mod` and source files to a VCS repository. To publish a module version, push
+a VCS tag. See [Dependency Management in Go >
+Versioning](../../../development/go_guide/dependencies.md#versioning) for more
+details on what constitutes a valid module or module version.
diff --git a/doc/user/packages/index.md b/doc/user/packages/index.md
index 132a64d99a3..6e59a87ae36 100644
--- a/doc/user/packages/index.md
+++ b/doc/user/packages/index.md
@@ -1,3 +1,9 @@
+---
+stage: Package
+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/#designated-technical-writers
+---
+
# GitLab Package Registry
GitLab Packages allows organizations to utilize GitLab as a private repository
@@ -15,6 +21,8 @@ The Packages feature allows GitLab to act as a repository for the following:
| [NPM Registry](npm_registry/index.md) **(PREMIUM)** | The GitLab NPM Registry enables every project in GitLab to have its own space to store [NPM](https://www.npmjs.com/) packages. | 11.7+ |
| [NuGet Repository](nuget_repository/index.md) **(PREMIUM)** | The GitLab NuGet Repository will enable every project in GitLab to have its own space to store [NuGet](https://www.nuget.org/) packages. | 12.8+ |
| [PyPi Repository](pypi_repository/index.md) **(PREMIUM)** | The GitLab PyPi Repository will enable every project in GitLab to have its own space to store [PyPi](https://pypi.org/) packages. | 12.10+ |
+| [Go Proxy](go_proxy/index.md) **(PREMIUM)** | The Go proxy for GitLab enables every project in GitLab to be fetched with the [Go proxy protocol](https://proxy.golang.org/). | 13.1+ |
+| [Composer Repository](composer_repository/index.md) **(PREMIUM)** | The GitLab Composer Repository will enable every project in GitLab to have its own space to store [Composer](https://getcomposer.org/) packages. | 13.1+ |
## Enable the Package Registry for your project
@@ -104,20 +112,19 @@ are adding support for [PHP](https://gitlab.com/gitlab-org/gitlab/-/merge_reques
| Format | Use case |
| ------ | ------ |
-| [Cargo](https://gitlab.com/gitlab-org/gitlab/issues/33060) | Cargo is the Rust package manager. Build, publish and share Rust packages |
-| [Chef](https://gitlab.com/gitlab-org/gitlab/issues/36889) | Configuration management with Chef using all the benefits of a repository manager. |
-| [CocoaPods](https://gitlab.com/gitlab-org/gitlab/issues/36890) | Speed up development with Xcode and CocoaPods. |
-| [Conda](https://gitlab.com/gitlab-org/gitlab/issues/36891) | Secure and private local Conda repositories. |
-| [CRAN](https://gitlab.com/gitlab-org/gitlab/issues/36892) | Deploy and resolve CRAN packages for the R language. |
-| [Debian](https://gitlab.com/gitlab-org/gitlab/issues/5835) | Host and provision Debian packages. |
-| [Go](https://gitlab.com/gitlab-org/gitlab/issues/9773) | Resolve Go dependencies from and publish your Go packages to GitLab. |
-| [Opkg](https://gitlab.com/gitlab-org/gitlab/issues/36894) | Optimize your work with OpenWrt using Opkg repositories. |
-| [P2](https://gitlab.com/gitlab-org/gitlab/issues/36895) | Host all your Eclipse plugins in your own GitLab P2 repository. |
-| [Puppet](https://gitlab.com/gitlab-org/gitlab/issues/36897) | Configuration management meets repository management with Puppet repositories. |
-| [RPM](https://gitlab.com/gitlab-org/gitlab/issues/5932) | Distribute RPMs directly from GitLab. |
-| [RubyGems](https://gitlab.com/gitlab-org/gitlab/issues/803) | Use GitLab to host your own gems. |
-| [SBT](https://gitlab.com/gitlab-org/gitlab/issues/36898) | Resolve dependencies from and deploy build output to SBT repositories when running SBT builds. |
-| [Vagrant](https://gitlab.com/gitlab-org/gitlab/issues/36899) | Securely host your Vagrant boxes in local repositories. |
+| [Cargo](https://gitlab.com/gitlab-org/gitlab/-/issues/33060) | Cargo is the Rust package manager. Build, publish and share Rust packages |
+| [Chef](https://gitlab.com/gitlab-org/gitlab/-/issues/36889) | Configuration management with Chef using all the benefits of a repository manager. |
+| [CocoaPods](https://gitlab.com/gitlab-org/gitlab/-/issues/36890) | Speed up development with Xcode and CocoaPods. |
+| [Conda](https://gitlab.com/gitlab-org/gitlab/-/issues/36891) | Secure and private local Conda repositories. |
+| [CRAN](https://gitlab.com/gitlab-org/gitlab/-/issues/36892) | Deploy and resolve CRAN packages for the R language. |
+| [Debian](https://gitlab.com/gitlab-org/gitlab/-/issues/5835) | Host and provision Debian packages. |
+| [Opkg](https://gitlab.com/gitlab-org/gitlab/-/issues/36894) | Optimize your work with OpenWrt using Opkg repositories. |
+| [P2](https://gitlab.com/gitlab-org/gitlab/-/issues/36895) | Host all your Eclipse plugins in your own GitLab P2 repository. |
+| [Puppet](https://gitlab.com/gitlab-org/gitlab/-/issues/36897) | Configuration management meets repository management with Puppet repositories. |
+| [RPM](https://gitlab.com/gitlab-org/gitlab/-/issues/5932) | Distribute RPMs directly from GitLab. |
+| [RubyGems](https://gitlab.com/gitlab-org/gitlab/-/issues/803) | Use GitLab to host your own gems. |
+| [SBT](https://gitlab.com/gitlab-org/gitlab/-/issues/36898) | Resolve dependencies from and deploy build output to SBT repositories when running SBT builds. |
+| [Vagrant](https://gitlab.com/gitlab-org/gitlab/-/issues/36899) | Securely host your Vagrant boxes in local repositories. |
## Package workflows
diff --git a/doc/user/packages/maven_repository/index.md b/doc/user/packages/maven_repository/index.md
index 51e62dc871e..2d40a623fb8 100644
--- a/doc/user/packages/maven_repository/index.md
+++ b/doc/user/packages/maven_repository/index.md
@@ -1,6 +1,12 @@
+---
+stage: Package
+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/#designated-technical-writers
+---
+
# GitLab Maven Repository **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/5811) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5811) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.3.
With the GitLab [Maven](https://maven.apache.org) Repository, every
project can have its own space to store its Maven artifacts.
diff --git a/doc/user/packages/npm_registry/index.md b/doc/user/packages/npm_registry/index.md
index b909646431b..4d60c227ccd 100644
--- a/doc/user/packages/npm_registry/index.md
+++ b/doc/user/packages/npm_registry/index.md
@@ -1,6 +1,12 @@
+---
+stage: Package
+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/#designated-technical-writers
+---
+
# GitLab NPM Registry **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/5934) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5934) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.7.
With the GitLab NPM Registry, every
project can have its own space to store NPM packages.
@@ -159,7 +165,7 @@ Then, you could run `npm publish` either locally or via GitLab CI/CD:
### Authenticating with a CI job token
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/9104) in GitLab Premium 12.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9104) in GitLab Premium 12.5.
If you’re using NPM with GitLab CI/CD, a CI job token can be used instead of a personal access token or deploy token.
The token will inherit the permissions of the user that generates the pipeline.
@@ -272,7 +278,7 @@ yarn add @my-project-scope/my-package
### Forwarding requests to npmjs.org
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/55344) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/55344) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.9.
By default, when an NPM package is not found in the GitLab NPM Registry, the request will be forwarded to [npmjs.com](https://www.npmjs.com/).
@@ -374,7 +380,7 @@ NPM_TOKEN=<your_token> npm install
## NPM dependencies metadata
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/11867) in GitLab Premium 12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11867) in GitLab Premium 12.6.
Starting from GitLab 12.6, new packages published to the GitLab NPM Registry expose the following attributes to the NPM client:
@@ -390,7 +396,7 @@ Starting from GitLab 12.6, new packages published to the GitLab NPM Registry exp
## NPM distribution tags
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/9425) in GitLab Premium 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9425) in GitLab Premium 12.8.
You can add [distribution tags](https://docs.npmjs.com/cli/dist-tag) for newly published packages.
They follow NPM's convention where they are optional, and each tag can only be assigned to one
diff --git a/doc/user/packages/nuget_repository/index.md b/doc/user/packages/nuget_repository/index.md
index d9efb3239a8..6ada68dcceb 100644
--- a/doc/user/packages/nuget_repository/index.md
+++ b/doc/user/packages/nuget_repository/index.md
@@ -1,6 +1,12 @@
+---
+stage: Package
+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/#designated-technical-writers
+---
+
# GitLab NuGet Repository **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/20050) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/20050) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.8.
With the GitLab NuGet Repository, every project can have its own space to store NuGet packages.
@@ -95,7 +101,7 @@ Where:
For example:
```shell
-nuget source Add -Name "GitLab" -Source "https//gitlab.example/api/v4/projects/10/packages/nuget/index.json" -UserName carol -Password 12345678asdf
+nuget source Add -Name "GitLab" -Source "https://gitlab.example/api/v4/projects/10/packages/nuget/index.json" -UserName carol -Password 12345678asdf
```
### Add NuGet Repository source with Visual Studio
diff --git a/doc/user/packages/pypi_repository/index.md b/doc/user/packages/pypi_repository/index.md
index 979f7a3c966..6f6609d82b1 100644
--- a/doc/user/packages/pypi_repository/index.md
+++ b/doc/user/packages/pypi_repository/index.md
@@ -1,3 +1,9 @@
+---
+stage: Package
+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/#designated-technical-writers
+---
+
# GitLab PyPi Repository **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/208747) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.10.
diff --git a/doc/user/permissions.md b/doc/user/permissions.md
index e5893b291dc..ecae119e9f1 100644
--- a/doc/user/permissions.md
+++ b/doc/user/permissions.md
@@ -23,9 +23,6 @@ GitLab [administrators](../administration/index.md) receive all permissions.
To add or import a user, you can follow the
[project members documentation](project/members/index.md).
-For information on eligible approvers for Merge Requests, see
-[Eligible approvers](project/merge_requests/merge_request_approvals.md#eligible-approvers).
-
## Principles behind permissions
See our [product handbook on permissions](https://about.gitlab.com/handbook/product/#permissions-in-gitlab)
@@ -50,7 +47,7 @@ The following table depicts the various user permission levels in a project.
|---------------------------------------------------|---------|------------|-------------|----------|--------|
| Download project | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
| Leave comments | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| View approved/blacklisted licenses **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| View allowed and denied licenses **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
| View License Compliance reports **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
| View Security reports **(ULTIMATE)** | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
| View Dependency list **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
@@ -99,6 +96,7 @@ The following table depicts the various user permission levels in a project.
| Assign merge requests | | | ✓ | ✓ | ✓ |
| Label merge requests | | | ✓ | ✓ | ✓ |
| Lock merge request threads | | | ✓ | ✓ | ✓ |
+| Approve merge requests (*9*) | | | ✓ | ✓ | ✓ |
| Manage/Accept merge requests | | | ✓ | ✓ | ✓ |
| Create new environments | | | ✓ | ✓ | ✓ |
| Stop environments | | | ✓ | ✓ | ✓ |
@@ -131,6 +129,7 @@ The following table depicts the various user permission levels in a project.
| Enable/disable tag protections | | | | ✓ | ✓ |
| Edit project | | | | ✓ | ✓ |
| Edit project badges | | | | ✓ | ✓ |
+| Share (invite) projects with groups | | | | ✓ (*8*) | ✓ (*8*)|
| Add deploy keys to project | | | | ✓ | ✓ |
| Configure project hooks | | | | ✓ | ✓ |
| Manage Runners | | | | ✓ | ✓ |
@@ -150,9 +149,12 @@ The following table depicts the various user permission levels in a project.
| Manage [project access tokens](./project/settings/project_access_tokens.md) **(CORE ONLY)** | | | | ✓ | ✓ |
| Switch visibility level | | | | | ✓ |
| Transfer project to another namespace | | | | | ✓ |
+| Rename project | | | | | ✓ |
| Remove fork relationship | | | | | ✓ |
| Remove project | | | | | ✓ |
+| Archive project | | | | | ✓ |
| Delete issues | | | | | ✓ |
+| Delete merge request | | | | | ✓ |
| Disable notification emails | | | | | ✓ |
| Force push to protected branches (*4*) | | | | | |
| Remove protected branches (*4*) | | | | | |
@@ -172,6 +174,9 @@ The following table depicts the various user permission levels in a project.
1. If the [branch is protected](./project/protected_branches.md#using-the-allowed-to-merge-and-allowed-to-push-settings), this depends on the access Developers and Maintainers are given.
1. Guest users can access GitLab [**Releases**](project/releases/index.md) for downloading assets but are not allowed to download the source code nor see repository information like tags and commits.
1. Actions are limited only to records owned (referenced) by user.
+1. When [Share Group Lock](./group/index.md#share-with-group-lock) is enabled the project can't be shared with other groups. It does not affect group with group sharing.
+1. For information on eligible approvers for merge requests, see
+ [Eligible approvers](project/merge_requests/merge_request_approvals.md#eligible-approvers).
## Project features permissions
@@ -239,6 +244,7 @@ group.
| Publish [packages](packages/index.md) **(PREMIUM)** | | | ✓ | ✓ | ✓ |
| View metrics dashboard annotations | | ✓ | ✓ | ✓ | ✓ |
| Create project in group | | | ✓ (3) | ✓ (3) | ✓ (3) |
+| Share (invite) groups with groups | | | | | ✓ |
| Create/edit/delete group milestones | | | ✓ | ✓ | ✓ |
| Enable/disable a dependency proxy **(PREMIUM)** | | | ✓ | ✓ | ✓ |
| Use security dashboard **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
@@ -246,11 +252,12 @@ group.
| View/manage group-level Kubernetes cluster | | | | ✓ | ✓ |
| Create subgroup | | | | ✓ (1) | ✓ |
| Edit epic comments (posted by any user) **(ULTIMATE)** | | | | ✓ (2) | ✓ (2) |
-| Edit group | | | | | ✓ |
+| Edit group settings | | | | | ✓ |
| Manage group level CI/CD variables | | | | | ✓ |
| Manage group members | | | | | ✓ |
-| Remove group | | | | | ✓ |
+| Delete group | | | | | ✓ |
| Delete group epic **(ULTIMATE)** | | | | | ✓ |
+| Edit SAML SSO Billing **(SILVER ONLY)** | ✓ | ✓ | ✓ | ✓ | ✓ (4) |
| View group Audit Events | | | | | ✓ |
| Disable notification emails | | | | | ✓ |
| View Contribution analytics | ✓ | ✓ | ✓ | ✓ | ✓ |
@@ -258,6 +265,8 @@ group.
| View Issues analytics **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ |
| View Productivity analytics **(PREMIUM)** | | ✓ | ✓ | ✓ | ✓ |
| View Value Stream analytics | ✓ | ✓ | ✓ | ✓ | ✓ |
+| View Billing **(FREE ONLY)** | ✓ | ✓ | ✓ | ✓ | ✓ (4) |
+| View Usage Quotas **(FREE ONLY)** | ✓ | ✓ | ✓ | ✓ | ✓ (4) |
1. Groups can be set to [allow either Owners or Owners and
Maintainers to create subgroups](group/subgroups/index.md#creating-a-subgroup)
@@ -265,6 +274,7 @@ group.
1. Default project creation role can be changed at:
- The [instance level](admin_area/settings/visibility_and_access_controls.md#default-project-creation-protection).
- The [group level](group/index.md#default-project-creation-level).
+1. Does not apply to subgroups.
### Subgroup permissions
@@ -285,7 +295,7 @@ project and should only have access to that project.
External users:
- Cannot create groups, projects, or personal snippets.
-- Can only access projects to which they are explicitly granted access,
+- Can only access public projects and projects to which they are explicitly granted access,
thus hiding all other internal or private ones from them (like being
logged out).
@@ -455,7 +465,7 @@ for details about the pipelines security model.
## LDAP users permissions
Since GitLab 8.15, LDAP user permissions can now be manually overridden by an admin user.
-Read through the documentation on [LDAP users permissions](../administration/auth/how_to_configure_ldap_gitlab_ee/index.md) to learn more.
+Read through the documentation on [LDAP users permissions](group/index.md#manage-group-memberships-via-ldap) to learn more.
## Project aliases
diff --git a/doc/user/profile/account/create_accounts.md b/doc/user/profile/account/create_accounts.md
index 27aa57e7f99..26c2c1bed89 100644
--- a/doc/user/profile/account/create_accounts.md
+++ b/doc/user/profile/account/create_accounts.md
@@ -1,5 +1,8 @@
---
type: reference
+stage: Manage
+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
---
# Creating users **(CORE ONLY)**
@@ -32,5 +35,5 @@ You can also [create users through the API](../../../api/users.md) as an admin.
Users will be:
-- Automatically created upon first login with the [LDAP integration](../../../administration/auth/ldap.md).
+- Automatically created upon first login with the [LDAP integration](../../../administration/auth/ldap/index.md).
- Created when first logging in via an [OmniAuth provider](../../../integration/omniauth.md) if the `allow_single_sign_on` setting is present.
diff --git a/doc/user/profile/account/delete_account.md b/doc/user/profile/account/delete_account.md
index c9193c6d94c..3c6f2989091 100644
--- a/doc/user/profile/account/delete_account.md
+++ b/doc/user/profile/account/delete_account.md
@@ -1,5 +1,8 @@
---
type: howto
+stage: Manage
+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
---
# Deleting a User account
diff --git a/doc/user/profile/account/two_factor_authentication.md b/doc/user/profile/account/two_factor_authentication.md
index ac0835911d2..bfcaeaf6a15 100644
--- a/doc/user/profile/account/two_factor_authentication.md
+++ b/doc/user/profile/account/two_factor_authentication.md
@@ -1,5 +1,8 @@
---
type: howto
+stage: Manage
+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
---
# Two-Factor Authentication
@@ -65,19 +68,22 @@ in a safe place.
### Enable 2FA via U2F device
+> Introduced in [GitLab 8.9](https://about.gitlab.com/blog/2016/06/22/gitlab-adds-support-for-u2f/).
+
GitLab officially only supports [YubiKey](https://www.yubico.com/products/)
-U2F devices, but users have successfully used [SoloKeys](https://solokeys.com/).
+U2F devices, but users have successfully used [SoloKeys](https://solokeys.com/)
+or [Google Titan Security Key](https://cloud.google.com/titan-security-key).
The U2F workflow is [supported by](https://caniuse.com/#search=U2F) the
following desktop browsers:
- Chrome
- Edge
-- Firefox (disabled by default)
+- Firefox 67+
- Opera
NOTE: **Note:**
-For Firefox, you can enable the FIDO U2F API in
+For Firefox 47-66, you can enable the FIDO U2F API in
[about:config](https://support.mozilla.org/en-US/kb/about-config-editor-firefox).
Search for `security.webauth.u2f` and double click on it to toggle to `true`.
diff --git a/doc/user/profile/active_sessions.md b/doc/user/profile/active_sessions.md
index 408276127a2..4dbb11b581d 100644
--- a/doc/user/profile/active_sessions.md
+++ b/doc/user/profile/active_sessions.md
@@ -19,7 +19,7 @@ review the sessions, and revoke any you don't recognize.
## Active sessions limit
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/31611) in GitLab 12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/31611) in GitLab 12.6.
GitLab allows users to have up to 100 active sessions at once. If the number of active sessions
exceeds 100, the oldest ones are deleted.
diff --git a/doc/user/profile/img/unknown_sign_in_email_v13_1.png b/doc/user/profile/img/unknown_sign_in_email_v13_1.png
new file mode 100644
index 00000000000..586be483be9
--- /dev/null
+++ b/doc/user/profile/img/unknown_sign_in_email_v13_1.png
Binary files differ
diff --git a/doc/user/profile/index.md b/doc/user/profile/index.md
index 383c7fe73aa..663a2888ee7 100644
--- a/doc/user/profile/index.md
+++ b/doc/user/profile/index.md
@@ -1,5 +1,8 @@
---
type: index, howto
+stage: Manage
+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
---
# User account
@@ -147,7 +150,7 @@ To add links to other accounts:
## Private contributions
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/14078) in GitLab 11.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/14078) in GitLab 11.3.
Enabling private contributions will include contributions to private projects, in the user contribution calendar graph and user recent activity.
@@ -250,7 +253,27 @@ When the `_gitlab_session` expires or isn't available, GitLab uses the `remember
to get you a new `_gitlab_session` and keep you signed in through browser restarts.
After your `remember_user_token` expires and your `_gitlab_session` is cleared/expired,
-you will be asked to sign in again to verify your identity (which is for security reasons).
+you will be asked to sign in again to verify your identity for security reasons.
+
+### Increased sign-in time
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/20340) in GitLab 13.1.
+
+The `remember_user_token` lifetime of a cookie can now extend beyond the deadline set by `config.remember_for`, as the `config.extend_remember_period` flag is now set to true.
+
+GitLab uses both session and persistent cookies:
+
+- Session cookie: Session cookies are normally removed at the end of the browser session when the browser is closed. The `_gitlab_session` cookie has no expiration date.
+- Persistent cookie: The `remember_me_token` is a cookie with an expiration date of two weeks. GitLab activates this cookie if you click Remember Me when you sign in.
+
+By default, the server sets a time-to-live (TTL) of 1-week on any session that is used.
+
+When you close a browser, the session cookie may still remain. For example, Chrome has the "Continue where you left off" option that restores session cookies.
+In other words, as long as you access GitLab at least once every 2 weeks, you could remain signed in with GitLab, as long as your browser tab is open.
+The server continues to reset the TTL for that session, independent of whether 2FA is installed,
+If you close your browser and open it up again, the `remember_user_token` cookie allows your user to reauthenticate itself.
+
+Without the `config.extend_remember_period` flag, you would be forced to sign in again after two weeks.
<!-- ## Troubleshooting
diff --git a/doc/user/profile/notifications.md b/doc/user/profile/notifications.md
index ae00f3ace57..ee228050945 100644
--- a/doc/user/profile/notifications.md
+++ b/doc/user/profile/notifications.md
@@ -1,5 +1,8 @@
---
disqus_identifier: 'https://docs.gitlab.com/ee/workflow/notifications.html'
+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/#designated-technical-writers
---
# GitLab Notification Emails
@@ -163,7 +166,7 @@ In most of the below cases, the notification will be sent to:
- Custom: Users with notification level "custom" who turned on notifications for any of the events present in the table below
NOTE: **Note:**
-To minimize the number of notifications that do not require any action, from [GitLab 12.9 onwards](https://gitlab.com/gitlab-org/gitlab/issues/616), eligible approvers are no longer notified for all the activities in their projects. To receive them they have to change their user notification settings to **Watch** instead.
+To minimize the number of notifications that do not require any action, from [GitLab 12.9 onwards](https://gitlab.com/gitlab-org/gitlab/-/issues/616), eligible approvers are no longer notified for all the activities in their projects. To receive them they have to change their user notification settings to **Watch** instead.
| Event | Sent to |
|------------------------|---------|
@@ -237,4 +240,4 @@ reason `assigned` will have this sentence in the footer:
- `You are receiving this email because you have been assigned an item on <configured GitLab hostname>.`
NOTE: **Note:**
-Notification of other events is being considered for inclusion in the `X-GitLab-NotificationReason` header. For details, see this [related issue](https://gitlab.com/gitlab-org/gitlab/issues/20689).
+Notification of other events is being considered for inclusion in the `X-GitLab-NotificationReason` header. For details, see this [related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/20689).
diff --git a/doc/user/profile/personal_access_tokens.md b/doc/user/profile/personal_access_tokens.md
index 87c1fe4007a..e2c3dc74cf1 100644
--- a/doc/user/profile/personal_access_tokens.md
+++ b/doc/user/profile/personal_access_tokens.md
@@ -1,5 +1,8 @@
---
type: concepts, howto
+stage: Manage
+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
---
# Personal access tokens
@@ -56,6 +59,58 @@ the following table.
| `read_repository` | [GitLab 10.7](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17894) | Allows read-only access (pull) to the repository through `git clone`. |
| `write_repository` | [GitLab 11.11](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/26021) | Allows read-write access (pull, push) to the repository through `git clone`. Required for accessing Git repositories over HTTP when 2FA is enabled. |
+## Programmatically creating a personal access token
+
+You can programmatically create a predetermined personal access token for use in
+automation or tests. You will need sufficient access to run a
+[Rails console session](../../administration/troubleshooting/debug.md#starting-a-rails-console-session)
+for your GitLab instance.
+
+To create a token belonging to a user with username `automation-bot`, run the
+following in the Rails console (`sudo gitlab-rails console`):
+
+```ruby
+user = User.find_by_username('automation-bot')
+token = user.personal_access_tokens.create(scopes: [:read_user, :read_repository], name: 'Automation token')
+token.set_token('token-string-here123')
+token.save!
+```
+
+This can be shortened into a single-line shell command using the
+[GitLab Rails Runner](../../administration/troubleshooting/debug.md#using-the-rails-runner):
+
+```shell
+sudo gitlab-rails runner "token = User.find_by_username('automation-bot').personal_access_tokens.create(scopes: [:read_user, :read_repository], name: 'Automation token'); token.set_token('token-string-here123'); token.save!"
+```
+
+NOTE: **Note:**
+The token string must be 20 characters in length, or it will not be
+recognized as a personal access token.
+
+The list of valid scopes and what they do can be found
+[in the source code](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/auth.rb).
+
+## Programmatically revoking a personal access token
+
+You can programmatically revoke a personal access token. You will need
+sufficient access to run a [Rails console session](../../administration/troubleshooting/debug.md#starting-a-rails-console-session)
+for your GitLab instance.
+
+To revoke a known token `token-string-here123`, run the following in the Rails
+console (`sudo gitlab-rails console`):
+
+```ruby
+token = PersonalAccessToken.find_by_token('token-string-here123')
+token.revoke!
+```
+
+This can be shorted into a single-line shell command using the
+[GitLab Rails Runner](../../administration/troubleshooting/debug.md#using-the-rails-runner):
+
+```shell
+sudo gitlab-rails runner "PersonalAccessToken.find_by_token('token-string-here123').revoke!"
+```
+
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
diff --git a/doc/user/profile/preferences.md b/doc/user/profile/preferences.md
index 55781b48a27..ccaea61ae4b 100644
--- a/doc/user/profile/preferences.md
+++ b/doc/user/profile/preferences.md
@@ -36,6 +36,29 @@ The default theme is Indigo. You can choose between 10 themes:
![Profile preferences navigation themes](img/profil-preferences-navigation-theme.png)
+## Dark mode
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28252) in GitLab 13.1 as an Alpha release.
+
+GitLab has started work on dark mode! The dark mode Alpha release is available in the
+spirit of iteration and the lower expectations of
+[Alpha versions](https://about.gitlab.com/handbook/product/#alpha).
+
+Progress on dark mode is tracked in the [Dark theme epic](https://gitlab.com/groups/gitlab-org/-/epics/2902). See the epic for:
+
+- A list of known issues.
+- Our planned direction and next steps.
+
+If you find an issue that isn’t listed, please leave a comment on the epic or create a
+new issue.
+
+Dark mode is available as a navigation theme, for MVC and compatibility reasons. In
+the future, we plan to make it configurable in its own section along with support for
+[different navigation themes](https://gitlab.com/gitlab-org/gitlab/-/issues/219512).
+
+NOTE: **Note:**
+Dark theme currently only works with the 'Dark' syntax highlighting.
+
## Syntax highlighting theme
NOTE: **Note:**
diff --git a/doc/user/profile/unknown_sign_in_notification.md b/doc/user/profile/unknown_sign_in_notification.md
index 9400ead1922..200358bb050 100644
--- a/doc/user/profile/unknown_sign_in_notification.md
+++ b/doc/user/profile/unknown_sign_in_notification.md
@@ -1,5 +1,14 @@
+---
+type: concepts, howto
+stage: Manage
+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
+---
+
# Email notification for unknown sign-ins
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27211) in GitLab 13.0.
+
When a user successfully signs in from a previously unknown IP address,
GitLab notifies the user by email. In this way, GitLab proactively alerts users of potentially
malicious or unauthorized sign-ins.
@@ -13,4 +22,4 @@ There are two methods used to identify a known sign-in:
## Example email
-![Unknown sign in email](./img/unknown_sign_in_email_v13_0.png)
+![Unknown sign in email](./img/unknown_sign_in_email_v13_1.png)
diff --git a/doc/user/project/badges.md b/doc/user/project/badges.md
index 6994f16cf52..542a3763008 100644
--- a/doc/user/project/badges.md
+++ b/doc/user/project/badges.md
@@ -1,6 +1,6 @@
# Badges
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/41174) in GitLab 10.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41174) in GitLab 10.7.
Badges are a unified way to present condensed pieces of information about your
projects. They consist of a small image and additionally a URL that the image
diff --git a/doc/user/project/bulk_editing.md b/doc/user/project/bulk_editing.md
index f4733620640..6d091c431a2 100644
--- a/doc/user/project/bulk_editing.md
+++ b/doc/user/project/bulk_editing.md
@@ -1,32 +1,60 @@
-# Bulk editing issues and merge requests
+---
+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/#designated-technical-writers
+---
-> **Notes:**
->
-> - A permission level of `Reporter` or higher is required in order to manage
-> issues.
-> - A permission level of `Developer` or higher is required in order to manage
-> merge requests.
+# Bulk editing issues and merge requests at the project level
-Attributes can be updated simultaneously across multiple issues or merge requests
-by using the bulk editing feature.
+NOTE: **Note:**
+Bulk editing issues, epics, and merge requests is also available at the **group level**.
+For more details, see
+[Bulk editing issues, epics, and merge requests at the group level](../group/bulk_editing/index.md).
+
+If you want to update attributes across multiple issues or merge requests, you can do it
+by bulk editing them, that is, editing them together.
![Bulk editing](img/bulk-editing.png)
+## Bulk edit issues at the project level
+
NOTE: **Note:**
-Bulk editing issues and merge requests is also available at the group level.
-For more details, see [bulk editing group issues and merge requests](../group/bulk_editing/index.md).
+You need a permission level of [Reporter or higher](../permissions.md) to manage issues.
+
+When bulk editing issues in a project, you can edit the following attributes:
+
+- Status (open/closed)
+- Assignee
+- Milestone
+- Labels
+- Subscriptions
-To update multiple project issues or merge requests at the same time:
+To update multiple project issues at the same time:
-1. Navigate to their respective list.
+1. In a project, go to **{issues}** **Issues > List**.
+1. Click **Edit issues**. A sidebar on the right-hand side of your screen appears with editable fields.
+1. Select the checkboxes next to each issue you want to edit.
+1. Select the appropriate fields and their values from the sidebar.
+1. Click **Update all**.
+
+## Bulk edit merge requests at the project level
+
+NOTE: **Note:**
+You need a permission level of [Developer or higher](../permissions.md) to manage merge requests.
-1. Click **Edit issues** or **Edit merge requests**.
+When bulk editing merge requests in a project, you can edit the following attributes:
- - This will open a sidebar on the right-hand side of your screen
- where editable fields will be displayed.
+- Status (open/closed)
+- Assignee
+- Milestone
+- Labels
+- Subscriptions
- - Checkboxes will also appear beside each issue or merge request.
+To update multiple project merge requests at the same time:
-1. Check the checkboxes of each items to be edited.
-1. Choose the appropriate fields and their values from the sidebar.
+1. In a project, go to **{merge-request}** **Merge Requests**.
+1. Click **Edit merge requests**. A sidebar on the right-hand side of your screen appears with
+ editable fields.
+1. Select the checkboxes next to each merge request you want to edit.
+1. Select the appropriate fields and their values from the sidebar.
1. Click **Update all**.
diff --git a/doc/user/project/canary_deployments.md b/doc/user/project/canary_deployments.md
index 86e9df1d162..852baf1f628 100644
--- a/doc/user/project/canary_deployments.md
+++ b/doc/user/project/canary_deployments.md
@@ -1,6 +1,6 @@
# Canary Deployments **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/1659) in [GitLab Premium](https://about.gitlab.com/pricing/) 9.1.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/1659) in [GitLab Premium](https://about.gitlab.com/pricing/) 9.1.
A popular [Continuous Deployment](https://en.wikipedia.org/wiki/Continuous_deployment)
strategy, where a small portion of the fleet is updated to the new version of
diff --git a/doc/user/project/clusters/add_eks_clusters.md b/doc/user/project/clusters/add_eks_clusters.md
index 712f8ea0adc..b11483a7446 100644
--- a/doc/user/project/clusters/add_eks_clusters.md
+++ b/doc/user/project/clusters/add_eks_clusters.md
@@ -51,7 +51,7 @@ Generate an access key for the IAM user, and configure GitLab with the credentia
## New EKS cluster
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/22392) in GitLab 12.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22392) in GitLab 12.5.
To create and add a new Kubernetes cluster to your project, group, or instance:
@@ -147,7 +147,7 @@ To create and add a new Kubernetes cluster to your project, group, or instance:
- **VPC** - Select a [VPC](https://docs.aws.amazon.com/vpc/latest/userguide/what-is-amazon-vpc.html)
to use for your EKS Cluster resources.
- **Subnets** - Choose the [subnets](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Subnets.html)
- in your VPC where your worker nodes will run.
+ in your VPC where your worker nodes will run. You must select at least two.
- **Security group** - Choose the [security group](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html)
to apply to the EKS-managed Elastic Network Interfaces that are created in your worker node subnets.
- **Instance type** - The [instance type](https://aws.amazon.com/ec2/instance-types/) of your worker nodes.
@@ -164,114 +164,45 @@ You will need to add your AWS external ID to the
[IAM Role in the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html#cli-configure-role-xaccount)
to manage your cluster using `kubectl`.
+### Troubleshooting creating a new cluster
+
+The following errors are commonly encountered when creating a new cluster.
+
+#### Error: Request failed with status code 422
+
+When submitting the initial authentication form, GitLab returns a status code 422
+error when it can't determine the role you've provided. Make sure you've
+correctly configured your role with the **Account ID** and **External ID**
+provided by GitLab. In GitLab, make sure to enter the correct **Role ARN**.
+
+#### Could not load Security Groups for this VPC
+
+When populating options in the configuration form, GitLab returns this error
+because GitLab has successfully assumed your provided role, but the role has
+insufficient permissions to retrieve the resources needed for the form. Make sure
+you've assigned the role the correct permissions.
+
+#### `ROLLBACK_FAILED` during cluster creation
+
+The creation process halted because GitLab encountered an error when creating
+one or more resources. You can inspect the associated
+[CloudFormation stack](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-console-view-stack-data-resources.html)
+to find the specific resources that failed to create.
+
+If the `Cluster` resource failed with the error
+`The provided role doesn't have the Amazon EKS Managed Policies associated with it.`,
+the role specified in **Role name** is not configured correctly.
+
+NOTE: **Note:**
+This role should not be the same as the one created above. If you don't have an
+existing
+[EKS cluster IAM role](https://docs.aws.amazon.com/eks/latest/userguide/service_IAM_role.html),
+you must create one.
+
## Existing EKS cluster
-To add an existing EKS cluster to your project, group, or instance:
-
-1. Perform the following steps on the EKS cluster:
- 1. Retrieve the certificate. A valid Kubernetes certificate is needed to authenticate to the
- EKS cluster. We will use the certificate created by default.
- Open a shell and use `kubectl` to retrieve it:
-
- 1. List the secrets with `kubectl get secrets`, and one should named similar to
- `default-token-xxxxx`. Copy that token name for use below.
- 1. Get the certificate with:
-
- ```shell
- kubectl get secret <secret name> -o jsonpath="{['data']['ca\.crt']}" | base64 --decode
- ```
-
- 1. Create admin token. A `cluster-admin` token is required to install and manage Helm Tiller.
- GitLab establishes mutual SSL authentication with Helm Tiller and creates limited service
- accounts for each application. To create the token we will create an admin service account as
- follows:
-
- 1. Create a file called `eks-admin-service-account.yaml` with contents:
-
- ```yaml
- apiVersion: v1
- kind: ServiceAccount
- metadata:
- name: eks-admin
- namespace: kube-system
- ```
-
- 1. Apply the service account to your cluster:
-
- ```shell
- $ kubectl apply -f eks-admin-service-account.yaml
- serviceaccount "eks-admin" created
- ```
-
- 1. Create a file called `eks-admin-cluster-role-binding.yaml` with contents:
-
- ```yaml
- apiVersion: rbac.authorization.k8s.io/v1beta1
- kind: ClusterRoleBinding
- metadata:
- name: eks-admin
- roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: ClusterRole
- name: cluster-admin
- subjects:
- - kind: ServiceAccount
- name: eks-admin
- namespace: kube-system
- ```
-
- 1. Apply the cluster role binding to your cluster:
-
- ```shell
- $ kubectl apply -f eks-admin-cluster-role-binding.yaml
- clusterrolebinding "eks-admin" created
- ```
-
- 1. Retrieve the token for the `eks-admin` service account:
-
- ```shell
- kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep eks-admin | awk '{print $1}')
- ```
-
- Copy the `<authentication_token>` value from the output:
-
- ```yaml
- Name: eks-admin-token-b5zv4
- Namespace: kube-system
- Labels: <none>
- Annotations: kubernetes.io/service-account.name=eks-admin
- kubernetes.io/service-account.uid=bcfe66ac-39be-11e8-97e8-026dce96b6e8
-
- Type: kubernetes.io/service-account-token
-
- Data
- ====
- ca.crt: 1025 bytes
- namespace: 11 bytes
- token: <authentication_token>
- ```
-
- 1. Locate the API server endpoint so GitLab can connect to the cluster. This is displayed on
- the AWS EKS console, when viewing the EKS cluster details.
-1. Navigate to your:
- - Project's **{cloud-gear}** **Operations > Kubernetes** page, for a project-level cluster.
- - Group's **{cloud-gear}** **Kubernetes** page, for a group-level cluster.
- - **{admin}** **Admin Area >** **{cloud-gear}** **Kubernetes** page, for an instance-level cluster.
-1. Click **Add Kubernetes cluster**.
-1. Click the **Add existing cluster** tab and fill in the details:
- - **Kubernetes cluster name**: A name for the cluster to identify it within GitLab.
- - **Environment scope**: Leave this as `*` for now, since we are only connecting a single cluster.
- - **API URL**: The API server endpoint retrieved earlier.
- - **CA Certificate**: The certificate data from the earlier step, as-is.
- - **Service Token**: The admin token value.
- - For project-level clusters, **Project namespace prefix**: This can be left blank to accept the
- default namespace, based on the project name.
-1. Click on **Add Kubernetes cluster**. The cluster is now connected to GitLab.
-
-At this point, [Kubernetes deployment variables](index.md#deployment-variables) will
-automatically be available during CI/CD jobs, making it easy to interact with the cluster.
-
-If you would like to utilize your own CI/CD scripts to deploy to the cluster, you can stop here.
+For information on adding an existing EKS cluster, see
+[Existing Kubernetes cluster](add_remove_clusters.md#existing-kubernetes-cluster).
### Create a default Storage Class
diff --git a/doc/user/project/clusters/add_gke_clusters.md b/doc/user/project/clusters/add_gke_clusters.md
index 4094828323a..2746076befe 100644
--- a/doc/user/project/clusters/add_gke_clusters.md
+++ b/doc/user/project/clusters/add_gke_clusters.md
@@ -21,26 +21,25 @@ requirements are met:
## New GKE cluster
-Starting from [GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/issues/25925), all the GKE clusters
+Starting from [GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/-/issues/25925), all the GKE clusters
provisioned by GitLab are [VPC-native](https://cloud.google.com/kubernetes-engine/docs/how-to/alias-ips).
-### Important notes
-
Note the following:
- The [Google authentication integration](../../../integration/google.md) must be enabled in GitLab
at the instance level. If that's not the case, ask your GitLab administrator to enable it. On
GitLab.com, this is enabled.
-- Starting from [GitLab 12.1](https://gitlab.com/gitlab-org/gitlab-foss/issues/55902), all GKE clusters
+- Starting from [GitLab 12.1](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/55902), all GKE clusters
created by GitLab are RBAC-enabled. Take a look at the [RBAC section](add_remove_clusters.md#rbac-cluster-resources) for
more information.
- Starting from [GitLab 12.5](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/18341), the
cluster's pod address IP range will be set to /16 instead of the regular /14. /16 is a CIDR
notation.
- GitLab requires basic authentication enabled and a client certificate issued for the cluster to
- set up an [initial service account](add_remove_clusters.md#access-controls). Starting from [GitLab
- 11.10](https://gitlab.com/gitlab-org/gitlab-foss/issues/58208), the cluster creation process will
- explicitly request that basic authentication and client certificate is enabled.
+ set up an [initial service account](add_remove_clusters.md#access-controls). In [GitLab versions
+ 11.10 and later](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/58208), the cluster creation process
+ explicitly requests GKE to create clusters with basic authentication enabled and a client
+ certificate.
### Creating the cluster on GKE
diff --git a/doc/user/project/clusters/add_remove_clusters.md b/doc/user/project/clusters/add_remove_clusters.md
index fddc9873f17..d0cba729e35 100644
--- a/doc/user/project/clusters/add_remove_clusters.md
+++ b/doc/user/project/clusters/add_remove_clusters.md
@@ -50,7 +50,7 @@ a `gitlab` service account with `cluster-admin` privileges is created in the `de
to manage the newly created cluster.
NOTE: **Note:**
-Restricted service account for deployment was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/51716) in GitLab 11.5.
+Restricted service account for deployment was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/51716) in GitLab 11.5.
When you install Helm into your cluster, the `tiller` service account
is created with `cluster-admin` privileges in the `gitlab-managed-apps`
@@ -151,146 +151,142 @@ For more information, see information for adding an:
NOTE: **Note:**
Kubernetes integration is not supported for arm64 clusters. See the issue
-[Helm Tiller fails to install on arm64 cluster](https://gitlab.com/gitlab-org/gitlab-foss/issues/64044) for details.
+[Helm Tiller fails to install on arm64 cluster](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/64044) for details.
### Existing Kubernetes cluster
To add a Kubernetes cluster to your project, group, or instance:
1. Navigate to your:
- - Project's **{cloud-gear}** **Operations > Kubernetes** page, for a project-level cluster.
- - Group's **{cloud-gear}** **Kubernetes** page, for a group-level cluster.
- - **{admin}** **Admin Area >** **{cloud-gear}** **Kubernetes** page, for an instance-level cluster.
+ 1. Project's **{cloud-gear}** **Operations > Kubernetes** page, for a project-level cluster.
+ 1. Group's **{cloud-gear}** **Kubernetes** page, for a group-level cluster.
+ 1. **{admin}** **Admin Area >** **{cloud-gear}** **Kubernetes** page, for an instance-level cluster.
1. Click **Add Kubernetes cluster**.
1. Click the **Add existing cluster** tab and fill in the details:
- - **Kubernetes cluster name** (required) - The name you wish to give the cluster.
- - **Environment scope** (required) - The
- [associated environment](index.md#setting-the-environment-scope-premium) to this cluster.
- - **API URL** (required) -
- It's the URL that GitLab uses to access the Kubernetes API. Kubernetes
- exposes several APIs, we want the "base" URL that is common to all of them.
- For example, `https://kubernetes.example.com` rather than `https://kubernetes.example.com/api/v1`.
-
- Get the API URL by running this command:
-
- ```shell
- kubectl cluster-info | grep 'Kubernetes master' | awk '/http/ {print $NF}'
- ```
-
- - **CA certificate** (required) - A valid Kubernetes certificate is needed to authenticate to the cluster. We will use the certificate created by default.
- - List the secrets with `kubectl get secrets`, and one should be named similar to
- `default-token-xxxxx`. Copy that token name for use below.
- - Get the certificate by running this command:
-
- ```shell
-
- kubectl get secret <secret name> -o jsonpath="{['data']['ca\.crt']}" | base64 --decode
-
- ```
-
- NOTE: **Note:**
- If the command returns the entire certificate chain, you need copy the *root ca*
- certificate at the bottom of the chain.
-
- - **Token** -
- GitLab authenticates against Kubernetes using service tokens, which are
- scoped to a particular `namespace`.
- **The token used should belong to a service account with
- [`cluster-admin`](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles)
- privileges.** To create this service account:
-
- 1. Create a file called `gitlab-admin-service-account.yaml` with contents:
-
- ```yaml
- apiVersion: v1
- kind: ServiceAccount
- metadata:
- name: gitlab-admin
- namespace: kube-system
- ---
- apiVersion: rbac.authorization.k8s.io/v1beta1
- kind: ClusterRoleBinding
- metadata:
- name: gitlab-admin
- roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: ClusterRole
- name: cluster-admin
- subjects:
- - kind: ServiceAccount
- name: gitlab-admin
- namespace: kube-system
- ```
-
- 1. Apply the service account and cluster role binding to your cluster:
-
- ```shell
- kubectl apply -f gitlab-admin-service-account.yaml
- ```
-
- You will need the `container.clusterRoleBindings.create` permission
- to create cluster-level roles. If you do not have this permission,
- you can alternatively enable Basic Authentication and then run the
- `kubectl apply` command as an admin:
-
- ```shell
- kubectl apply -f gitlab-admin-service-account.yaml --username=admin --password=<password>
- ```
-
- NOTE: **Note:**
- Basic Authentication can be turned on and the password credentials
- can be obtained using the Google Cloud Console.
-
- Output:
-
- ```shell
- serviceaccount "gitlab-admin" created
- clusterrolebinding "gitlab-admin" created
- ```
-
- 1. Retrieve the token for the `gitlab-admin` service account:
-
- ```shell
- kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep gitlab-admin | awk '{print $1}')
- ```
-
- Copy the `<authentication_token>` value from the output:
-
- ```yaml
- Name: gitlab-admin-token-b5zv4
- Namespace: kube-system
- Labels: <none>
- Annotations: kubernetes.io/service-account.name=gitlab-admin
+ 1. **Kubernetes cluster name** (required) - The name you wish to give the cluster.
+ 1. **Environment scope** (required) - The
+ [associated environment](index.md#setting-the-environment-scope-premium) to this cluster.
+ 1. **API URL** (required) -
+ It's the URL that GitLab uses to access the Kubernetes API. Kubernetes
+ exposes several APIs, we want the "base" URL that is common to all of them.
+ For example, `https://kubernetes.example.com` rather than `https://kubernetes.example.com/api/v1`.
+
+ Get the API URL by running this command:
+
+ ```shell
+ kubectl cluster-info | grep 'Kubernetes master' | awk '/http/ {print $NF}'
+ ```
+
+ 1. **CA certificate** (required) - A valid Kubernetes certificate is needed to authenticate to the cluster. We will use the certificate created by default.
+ 1. List the secrets with `kubectl get secrets`, and one should be named similar to
+ `default-token-xxxxx`. Copy that token name for use below.
+ 1. Get the certificate by running this command:
+
+ ```shell
+ kubectl get secret <secret name> -o jsonpath="{['data']['ca\.crt']}" | base64 --decode
+ ```
+
+ NOTE: **Note:**
+ If the command returns the entire certificate chain, you need copy the *root ca*
+ certificate at the bottom of the chain.
+
+ 1. **Token** -
+ GitLab authenticates against Kubernetes using service tokens, which are
+ scoped to a particular `namespace`.
+ **The token used should belong to a service account with
+ [`cluster-admin`](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles)
+ privileges.** To create this service account:
+ 1. Create a file called `gitlab-admin-service-account.yaml` with contents:
+
+ ```yaml
+ apiVersion: v1
+ kind: ServiceAccount
+ metadata:
+ name: gitlab-admin
+ namespace: kube-system
+ ---
+ apiVersion: rbac.authorization.k8s.io/v1beta1
+ kind: ClusterRoleBinding
+ metadata:
+ name: gitlab-admin
+ roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: cluster-admin
+ subjects:
+ - kind: ServiceAccount
+ name: gitlab-admin
+ namespace: kube-system
+ ```
+
+ 1. Apply the service account and cluster role binding to your cluster:
+
+ ```shell
+ kubectl apply -f gitlab-admin-service-account.yaml
+ ```
+
+ You will need the `container.clusterRoleBindings.create` permission
+ to create cluster-level roles. If you do not have this permission,
+ you can alternatively enable Basic Authentication and then run the
+ `kubectl apply` command as an admin:
+
+ ```shell
+ kubectl apply -f gitlab-admin-service-account.yaml --username=admin --password=<password>
+ ```
+
+ NOTE: **Note:**
+ Basic Authentication can be turned on and the password credentials
+ can be obtained using the Google Cloud Console.
+
+ Output:
+
+ ```shell
+ serviceaccount "gitlab-admin" created
+ clusterrolebinding "gitlab-admin" created
+ ```
+
+ 1. Retrieve the token for the `gitlab-admin` service account:
+
+ ```shell
+ kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep gitlab-admin | awk '{print $1}')
+ ```
+
+ Copy the `<authentication_token>` value from the output:
+
+ ```yaml
+ Name: gitlab-admin-token-b5zv4
+ Namespace: kube-system
+ Labels: <none>
+ Annotations: kubernetes.io/service-account.name=gitlab-admin
kubernetes.io/service-account.uid=bcfe66ac-39be-11e8-97e8-026dce96b6e8
- Type: kubernetes.io/service-account-token
-
- Data
- ====
- ca.crt: 1025 bytes
- namespace: 11 bytes
- token: <authentication_token>
- ```
-
- NOTE: **Note:**
- For GKE clusters, you will need the
- `container.clusterRoleBindings.create` permission to create a cluster
- role binding. You can follow the [Google Cloud
- documentation](https://cloud.google.com/iam/docs/granting-changing-revoking-access)
- to grant access.
-
- - **GitLab-managed cluster** - Leave this checked if you want GitLab to manage namespaces and service accounts for this cluster.
- See the [Managed clusters section](index.md#gitlab-managed-clusters) for more information.
-
- - **Project namespace** (optional) - You don't have to fill it in; by leaving
- it blank, GitLab will create one for you. Also:
- - Each project should have a unique namespace.
- - The project namespace is not necessarily the namespace of the secret, if
- you're using a secret with broader permissions, like the secret from `default`.
- - You should **not** use `default` as the project namespace.
- - If you or someone created a secret specifically for the project, usually
- with limited permissions, the secret's namespace and project namespace may
- be the same.
+ Type: kubernetes.io/service-account-token
+
+ Data
+ ====
+ ca.crt: 1025 bytes
+ namespace: 11 bytes
+ token: <authentication_token>
+ ```
+
+ NOTE: **Note:**
+ For GKE clusters, you will need the
+ `container.clusterRoleBindings.create` permission to create a cluster
+ role binding. You can follow the [Google Cloud
+ documentation](https://cloud.google.com/iam/docs/granting-changing-revoking-access)
+ to grant access.
+
+ 1. **GitLab-managed cluster** - Leave this checked if you want GitLab to manage namespaces and service accounts for this cluster.
+ See the [Managed clusters section](index.md#gitlab-managed-clusters) for more information.
+ 1. **Project namespace** (optional) - You don't have to fill it in; by leaving
+ it blank, GitLab will create one for you. Also:
+ - Each project should have a unique namespace.
+ - The project namespace is not necessarily the namespace of the secret, if
+ you're using a secret with broader permissions, like the secret from `default`.
+ - You should **not** use `default` as the project namespace.
+ - If you or someone created a secret specifically for the project, usually
+ with limited permissions, the secret's namespace and project namespace may
+ be the same.
1. Finally, click the **Create Kubernetes cluster** button.
@@ -337,7 +333,7 @@ To disable the Kubernetes cluster integration, follow the same procedure.
To remove the Kubernetes cluster integration from your project, either:
- Select **Remove integration**, to remove only the Kubernetes integration.
-- [From GitLab 12.6](https://gitlab.com/gitlab-org/gitlab/issues/26815), select
+- [From GitLab 12.6](https://gitlab.com/gitlab-org/gitlab/-/issues/26815), select
**Remove integration and resources**, to also remove all related GitLab cluster resources (for
example, namespaces, roles, and bindings) when removing the integration.
diff --git a/doc/user/project/clusters/index.md b/doc/user/project/clusters/index.md
index 1298a24fcac..961a9fda5ff 100644
--- a/doc/user/project/clusters/index.md
+++ b/doc/user/project/clusters/index.md
@@ -6,10 +6,10 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Kubernetes clusters
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/35954) in GitLab 10.1 for projects.
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/34758) in
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/35954) in GitLab 10.1 for projects.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/34758) in
> GitLab 11.6 for [groups](../../group/clusters/index.md).
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/39840) in
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/39840) in
> GitLab 11.11 for [instances](../../instance/clusters/index.md).
GitLab provides many features with a Kubernetes integration. Kubernetes can be
@@ -46,6 +46,7 @@ GitLab is committed to support at least two production-ready Kubernetes minor ve
Currently, GitLab supports the following Kubernetes versions:
+- 1.16
- 1.15
- 1.14
- 1.13 (deprecated, support ends on November 22, 2020)
@@ -171,7 +172,7 @@ Note the following with GitLab and clusters:
#### Clearing the cluster cache
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/31759) in GitLab 12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/31759) in GitLab 12.6.
If you choose to allow GitLab to manage your cluster for you, GitLab stores a cached
version of the namespaces and service accounts it creates for your projects. If you
@@ -314,7 +315,7 @@ If your cluster was created before GitLab 12.2, default `KUBE_NAMESPACE` will be
### Custom namespace
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/27630) in GitLab 12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27630) in GitLab 12.6.
The Kubernetes integration defaults to project-environment-specific namespaces
of the form `<project_name>-<project_id>-<environment>` (see [Deployment
@@ -326,7 +327,7 @@ in `.gitlab-ci.yml`.
NOTE: **Note:** When using a [GitLab-managed cluster](#gitlab-managed-clusters), the
namespaces are created automatically prior to deployment and [can not be
-customized](https://gitlab.com/gitlab-org/gitlab/issues/38054).
+customized](https://gitlab.com/gitlab-org/gitlab/-/issues/38054).
### Troubleshooting
diff --git a/doc/user/project/clusters/kubernetes_pod_logs.md b/doc/user/project/clusters/kubernetes_pod_logs.md
index 8577231b69b..509be4ed0a8 100644
--- a/doc/user/project/clusters/kubernetes_pod_logs.md
+++ b/doc/user/project/clusters/kubernetes_pod_logs.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Kubernetes Logs
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/4752) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.0.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4752) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.0.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26383) to [GitLab Core](https://about.gitlab.com/pricing/) 12.9.
GitLab makes it easy to view the logs of running pods in [connected Kubernetes clusters](index.md).
@@ -65,23 +65,23 @@ Logs can be displayed by clicking on a specific pod from [Deploy Boards](../depl
The **Log Explorer** lets you filter the logs by:
- Pods.
-- [From GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/issues/5769), environments.
+- [From GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/-/issues/5769), environments.
- [From GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21656),
[full text search](#full-text-search).
-- [From GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/issues/197879), dates.
+- [From GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/-/issues/197879), dates.
Loading more than 500 log lines is possible from
[GitLab 12.9](https://gitlab.com/gitlab-org/gitlab/-/issues/198050) onward.
Support for pods with multiple containers is coming
-[in a future release](https://gitlab.com/gitlab-org/gitlab/issues/13404).
+[in a future release](https://gitlab.com/gitlab-org/gitlab/-/issues/13404).
Support for historical data is coming
-[in a future release](https://gitlab.com/gitlab-org/gitlab/issues/196191).
+[in a future release](https://gitlab.com/gitlab-org/gitlab/-/issues/196191).
### Filter by date
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/197879) in GitLab 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/197879) in GitLab 12.8.
When you enable [Elastic Stack](../../clusters/applications.md#elastic-stack)
on your cluster, you can filter logs displayed in the **Log Explorer** by date.
diff --git a/doc/user/project/clusters/runbooks/index.md b/doc/user/project/clusters/runbooks/index.md
index dfed43470bc..92ef35ad93f 100644
--- a/doc/user/project/clusters/runbooks/index.md
+++ b/doc/user/project/clusters/runbooks/index.md
@@ -23,7 +23,7 @@ pre-written code blocks or database queries against a given environment.
## Executable Runbooks
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/45912) in GitLab 11.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/45912) in GitLab 11.4.
The JupyterHub app offered via GitLab’s Kubernetes integration now ships
with Nurtch’s Rubix library, providing a simple way to create DevOps
diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md
index 124a0d4bf9f..15f7e14fda9 100644
--- a/doc/user/project/clusters/serverless/aws.md
+++ b/doc/user/project/clusters/serverless/aws.md
@@ -15,7 +15,7 @@ GitLab supports deployment of AWS Lambda functions through GitLab CI/CD using th
## Serverless Framework
-The [Serverless Framework can deploy to AWS](https://serverless.com/framework/docs/providers/aws/).
+The [Serverless Framework can deploy to AWS](https://www.serverless.com/framework/docs/providers/aws/).
We have prepared an example with a step-by-step guide to create a simple function and deploy it on AWS.
@@ -101,7 +101,7 @@ The handler definition will provision the Lambda function using the source code
The `events` declaration will create a AWS API Gateway `GET` endpoint to receive external requests and hand them over to the Lambda function via a service integration.
-You can read more about the available properties and additional configuration possibilities of the Serverless Framework here: <https://serverless.com/framework/docs/providers/aws/guide/serverless.yml/>
+You can read more about the [available properties and additional configuration possibilities](https://www.serverless.com/framework/docs/providers/aws/guide/serverless.yml/) of the Serverless Framework.
#### Crafting the `.gitlab-ci.yml` file
@@ -134,7 +134,7 @@ This example code does the following:
#### Setting up your AWS credentials with your GitLab account
In order to interact with your AWS account, the GitLab CI/CD pipelines require both `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` to be defined in your GitLab settings under **Settings > CI/CD > Variables**.
-For more information please see: <https://docs.gitlab.com/ee/ci/variables/README.html#via-the-ui>
+For more information please see [Create a custom variable in the UI](../../../../ci/variables/README.md#create-a-custom-variable-in-the-ui).
NOTE: **Note:**
The AWS credentials you provide must include IAM policies that provision correct access control to AWS Lambda, API Gateway, CloudFormation, and IAM resources.
@@ -275,7 +275,7 @@ module.exports.hello = async event => {
};
```
-For more information, see the [Your CORS and API Gateway survival guide](https://serverless.com/blog/cors-api-gateway-survival-guide/)
+For more information, see the [Your CORS and API Gateway survival guide](https://www.serverless.com/blog/cors-api-gateway-survival-guide/)
blog post written by the Serverless Framework team.
#### Writing automated tests
@@ -288,7 +288,7 @@ automated testing of both local and deployed serverless function.
The example code is available:
-- As a [cloneable repository](https://gitlab.com/gitlab-org/serverless/examples/serverless-framework-js).
+- As a [clonable repository](https://gitlab.com/gitlab-org/serverless/examples/serverless-framework-js).
- In a version with [tests and secret variables](https://gitlab.com/gitlab-org/project-templates/serverless-framework/).
You can also use a [template](../../../../gitlab-basics/create-project.md#project-templates)
@@ -416,7 +416,7 @@ production:
environment: production
```
-Let’s examine the config file more closely:
+Let’s examine the configuration file more closely:
- `image` specifies the Docker image to use for this build. This is the latest Python
image since the sample application is written in Python.
diff --git a/doc/user/project/clusters/serverless/index.md b/doc/user/project/clusters/serverless/index.md
index 2156d96f92a..45fb313d177 100644
--- a/doc/user/project/clusters/serverless/index.md
+++ b/doc/user/project/clusters/serverless/index.md
@@ -33,7 +33,7 @@ of the box through its main components:
- [Serving](https://github.com/knative/serving): Request-driven compute that can scale to zero.
- [Eventing](https://github.com/knative/eventing): Management and delivery of events.
-For more information on Knative, visit the [Knative docs repo](https://github.com/knative/docs).
+For more information on Knative, visit the [Knative docs repository](https://github.com/knative/docs).
With GitLab Serverless, you can deploy both functions-as-a-service (FaaS) and serverless applications.
@@ -61,14 +61,14 @@ To run Knative on GitLab, you will need:
wildcard domain where your applications will be served. Configure your DNS server to use the
external IP address or hostname for that domain.
1. **`.gitlab-ci.yml`:** GitLab uses [Kaniko](https://github.com/GoogleContainerTools/kaniko)
- to build the application. We also use [gitlabktl](https://gitlab.com/gitlab-org/gitlabktl)
+ to build the application. We also use [GitLab Knative tool](https://gitlab.com/gitlab-org/gitlabktl)
CLI to simplify the deployment of services and functions to Knative.
1. **`serverless.yml`** (for [functions only](#deploying-functions)): When using serverless to deploy functions, the `serverless.yml` file
will contain the information for all the functions being hosted in the repository as well as a reference to the
runtime being used.
1. **`Dockerfile`** (for [applications only](#deploying-serverless-applications)): Knative requires a
`Dockerfile` in order to build your applications. It should be included at the root of your
- project's repo and expose port `8080`. `Dockerfile` is not require if you plan to build serverless functions
+ project's repository and expose port `8080`. `Dockerfile` is not require if you plan to build serverless functions
using our [runtimes](https://gitlab.com/gitlab-org/serverless/runtimes).
1. **Prometheus** (optional): Installing Prometheus allows you to monitor the scale and traffic of your serverless function/application.
See [Installing Applications](../index.md#installing-applications) for more information.
@@ -97,9 +97,9 @@ The minimum recommended cluster size to run Knative is 3-nodes, 6 vCPUs, and 22.
1. The Ingress is now available at this address and will route incoming requests to the proper service based on the DNS
name in the request. To support this, a wildcard DNS record should be created for the desired domain name. For example,
if your Knative base domain is `knative.info` then you need to create an A record or CNAME record with domain `*.knative.info`
- pointing the ip address or hostname of the Ingress.
+ pointing the IP address or hostname of the Ingress.
- ![dns entry](img/dns-entry.png)
+ ![DNS entry](img/dns-entry.png)
NOTE: **Note:**
You can deploy either [functions](#deploying-functions) or [serverless applications](#deploying-serverless-applications)
@@ -107,7 +107,7 @@ on a given project but not both. The current implementation makes use of a `serv
## Using an existing installation of Knative
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/58941) in GitLab 12.0.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/58941) in GitLab 12.0.
NOTE: **Note:**
The "invocations" monitoring feature of GitLab serverless will not work when
@@ -199,7 +199,7 @@ You must provide a `Dockerfile` to run serverless functions if no runtime is spe
### OpenFaaS runtimes
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/29253) in GitLab 12.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/29253) in GitLab 12.5.
[OpenFaaS classic runtimes](https://github.com/openfaas/templates#templates-in-store) can be used with GitLab serverless.
@@ -318,7 +318,7 @@ Explanation of the fields used above:
|-----------|-------------|
| `name` | Indicates which provider is used to execute the `serverless.yml` file. In this case, the TriggerMesh middleware. |
| `envs` | Includes the environment variables to be passed as part of function execution for **all** functions in the file, where `FOO` is the variable name and `BAR` are the variable contents. You may replace this with your own variables. |
-| `secrets` | Includes the contents of the Kubernetes secret as environment variables accessible to be passed as part of function execution for **all** functions in the file. The secrets are expected in ini format. |
+| `secrets` | Includes the contents of the Kubernetes secret as environment variables accessible to be passed as part of function execution for **all** functions in the file. The secrets are expected in INI format. |
### `functions`
@@ -332,7 +332,7 @@ subsequent lines contain the function attributes.
| `runtime` (optional)| The runtime to be used to execute the function. This can be a runtime alias (see [Runtime aliases](#runtime-aliases)), or it can be a full URL to a custom runtime repository. When the runtime is not specified, we assume that `Dockerfile` is present in the function directory specified by `source`. |
| `description` | A short description of the function. |
| `envs` | Sets an environment variable for the specific function only. |
-| `secrets` | Includes the contents of the Kubernetes secret as environment variables accessible to be passed as part of function execution for the specific function only. The secrets are expected in ini format. |
+| `secrets` | Includes the contents of the Kubernetes secret as environment variables accessible to be passed as part of function execution for the specific function only. The secrets are expected in INI format. |
### Deployment
@@ -384,7 +384,7 @@ The sample function can now be triggered from any HTTP client using a simple `PO
http://functions-echo.functions-1.functions.example.com/
```
- 1. Using a web-based tool (ie. postman, restlet, etc)
+ 1. Using a web-based tool (such as Postman or Restlet)
![function execution](img/function-execution.png)
@@ -516,7 +516,7 @@ cluster.
## Configuring logging
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/33330) in GitLab 12.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/33330) in GitLab 12.5.
### Prerequisites
diff --git a/doc/user/project/code_owners.md b/doc/user/project/code_owners.md
index 40ea1833fa3..6b81aea4b87 100644
--- a/doc/user/project/code_owners.md
+++ b/doc/user/project/code_owners.md
@@ -6,8 +6,8 @@ type: reference
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/6916)
in [GitLab Starter](https://about.gitlab.com/pricing/) 11.3.
-> - [Support for group namespaces](https://gitlab.com/gitlab-org/gitlab-foss/issues/53182) added in GitLab Starter 12.1.
-> - Code Owners for Merge Request approvals was [introduced](https://gitlab.com/gitlab-org/gitlab/issues/4418) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.9.
+> - [Support for group namespaces](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53182) added in GitLab Starter 12.1.
+> - Code Owners for Merge Request approvals was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4418) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.9.
## Introduction
@@ -73,12 +73,28 @@ be used for merge request approvals:
- As [merge request eligible approvers](merge_requests/merge_request_approvals.md#code-owners-as-eligible-approvers).
- As required approvers for [protected branches](protected_branches.md#protected-branches-approval-by-code-owners-premium). **(PREMIUM)**
+NOTE: **Note**:
+Developer or higher [permissions](../permissions.md) are required in order to
+approve a merge request.
+
Once set, Code Owners are displayed in merge requests widgets:
![MR widget - Code Owners](img/code_owners_mr_widget_v12_4.png)
-NOTE: **Note**:
- While the`CODEOWNERS` file can be used in addition to Merge Request [Approval Rules](merge_requests/merge_request_approvals.md#approval-rules) it can also be used as the sole driver of a Merge Request approval (without using [Approval Rules](merge_requests/merge_request_approvals.md#approval-rules)) by simply creating the file in one of the three locations specified above, configuring the Code Owners to be required approvers for [protected branches](protected_branches.md#protected-branches-approval-by-code-owners-premium) and then using [the syntax of Code Owners files](code_owners.md#the-syntax-of-code-owners-files) to specify the actual owners and granular permissions.
+While the `CODEOWNERS` file can be used in addition to Merge Request [Approval Rules](merge_requests/merge_request_approvals.md#approval-rules)
+it can also be used as the sole driver of merge request approvals
+(without using [Approval Rules](merge_requests/merge_request_approvals.md#approval-rules)).
+To do so, create the file in one of the three locations specified above and
+set the code owners as required approvers for [protected branches](protected_branches.md#protected-branches-approval-by-code-owners-premium).
+Use [the syntax of Code Owners files](code_owners.md#the-syntax-of-code-owners-files)
+to specify the actual owners and granular permissions.
+
+Using Code Owners in conjunction with [Protected Branches Approvals](protected_branches.md#protected-branches-approval-by-code-owners-premium)
+will prevent any user who is not specified in the `CODEOWNERS` file from pushing changes
+for the specified files/paths, even if their role is included in the **Allowed to push** column.
+This allows for a more inclusive push strategy, as administrators don't have to restrict developers
+from pushing directly to the protected branch, but can restrict pushing to certain
+files where a review by Code Owners is required.
## The syntax of Code Owners files
@@ -93,7 +109,7 @@ groups or subgroups from the project's group hierarchy as potential code owners.
For example, consider the following hierarchy for a given project:
-```text
+```plaintext
group >> sub-group >> sub-subgroup >> myproject >> file.md
```
@@ -103,7 +119,7 @@ Any of the following groups would be eligible to be specified as code owners:
- `@group/sub-group`
- `@group/sub-group/sub-subgroup`
-In addition, any groups that have been invited to the project using the **Settings > Members** tool will also be recognized as eligible code owners.
+In addition, any groups that have been invited to the project using the **Members** tool will also be recognized as eligible code owners.
The order in which the paths are defined is significant: the last
pattern that matches a given path will be used to find the code
diff --git a/doc/user/project/deploy_boards.md b/doc/user/project/deploy_boards.md
index 8f7bb844e37..0a613ff918b 100644
--- a/doc/user/project/deploy_boards.md
+++ b/doc/user/project/deploy_boards.md
@@ -1,6 +1,13 @@
+---
+stage: Release
+group: Progressive Delivery
+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: howto, reference
+---
+
# Deploy Boards **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/1589) in [GitLab Premium](https://about.gitlab.com/pricing/) 9.0.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/1589) in [GitLab Premium](https://about.gitlab.com/pricing/) 9.0.
GitLab's 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
@@ -34,6 +41,10 @@ knowledge. In particular, you should be familiar with:
- [Kubernetes namespaces](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/)
- [Kubernetes canary deployments](https://kubernetes.io/docs/concepts/cluster-administration/manage-deployment/#canary-deployments)
+NOTE: **Note:**
+Apps that consist of multiple deployments are shown as duplicates on the deploy board.
+Follow [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/8463) for details.
+
## Use cases
Since the Deploy Board is a visual representation of the Kubernetes pods for a
@@ -68,7 +79,7 @@ To display the Deploy Boards for a specific [environment](../../ci/environments/
instead of `DeploymentConfiguration`. Otherwise, the Deploy Boards won'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).
+ and [GitLab issue #4584](https://gitlab.com/gitlab-org/gitlab/-/issues/4584).
1. [Configure GitLab Runner](../../ci/runners/README.md) with the [Docker](https://docs.gitlab.com/runner/executors/docker.html) or
[Kubernetes](https://docs.gitlab.com/runner/executors/kubernetes.html) executor.
diff --git a/doc/user/project/deploy_keys/img/deploy_keys_v13_0.png b/doc/user/project/deploy_keys/img/deploy_keys_v13_0.png
new file mode 100644
index 00000000000..462141ef82a
--- /dev/null
+++ b/doc/user/project/deploy_keys/img/deploy_keys_v13_0.png
Binary files differ
diff --git a/doc/user/project/deploy_keys/img/public_deploy_key_v13_0.png b/doc/user/project/deploy_keys/img/public_deploy_key_v13_0.png
new file mode 100644
index 00000000000..3e6d1605f95
--- /dev/null
+++ b/doc/user/project/deploy_keys/img/public_deploy_key_v13_0.png
Binary files differ
diff --git a/doc/user/project/deploy_keys/index.md b/doc/user/project/deploy_keys/index.md
new file mode 100644
index 00000000000..32d3eab5e62
--- /dev/null
+++ b/doc/user/project/deploy_keys/index.md
@@ -0,0 +1,164 @@
+---
+stage: Release
+group: Progressive Delivery
+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: howto, reference
+---
+
+# Deploy Keys
+
+Deploy keys allow read-only or read-write (if enabled) access to one or
+more repositories, by importing an SSH public key to your GitLab instance.
+
+This is useful for cloning repositories to your Continuous
+Integration (CI) server. By using deploy keys, you don't have to set up a
+dummy user account.
+
+There are two types of deploy keys:
+
+- [Project deploy keys](#project-deploy-keys)
+- [Public deploy keys](#public-deploy-keys)
+
+## Key details on deploy keys
+
+Deploy Keys allow a remote machine (VM, physical, and so on) to access a GitLab
+repository with just a few steps. If you want a remote machine to interact with a GitLab
+repository in automation, it's a simple solution.
+
+A drawback is that your repository could become vulnerable if a remote machine is compromised
+by a hacker. You should limit access to the remote machine before a deploy key is
+enabled on your repository. A good rule to follow is to access only to trusted users,
+and make sure that the allowed users have [maintainer permissions or higher](../../permissions.md)
+in the GitLab project.
+
+If this security implication is a concern for your organization,
+[Deploy Tokens](../deploy_tokens/index.md) works as an alternative, but with more
+security control.
+
+## Deploy Keys Permissions
+
+You can choose the access level of a deploy key when you enable it on a project:
+
+- `read-only`: The deploy key can read a repository.
+- `read-write`: The deploy key can read a repository and write to it.
+
+Project maintainers and owners can activate and deactivate deploy keys.
+They can also add their own deploy keys and enable them for this project.
+
+When a `write-access` deploy key is used to push a commit, GitLab checks if
+the **creator** of the deploy key has permission to access the resource. For example:
+
+- When a deploy key is used to push a commit to a [protected branch](../protected_branches.md),
+ the **creator** of the deploy key must have access to the branch.
+- When a deploy key is used to push a commit that triggers a CI/CD pipelines, the **creator** of
+ the deploy key must have access to the CI/CD resources (like protected environments, secret variables, and so on).
+- If the **creator** of a deploy key does not have permissions to read a project's
+ repository, the deploy key _might_ encounter an error during the process.
+
+## Differences between deploy keys and deploy tokens
+
+Both deploy keys and [deploy tokens](../deploy_tokens/index.md#deploy-tokens) can
+help you access a repository, but there are some notables differences between them:
+
+- Deploy keys are shareable between projects that are not related or don't even
+ belong to the same group. Deploy tokens belong to either a project or
+ [a group](../deploy_tokens/index.md#group-deploy-token).
+- A deploy key is an SSH key you need to generate yourself on your machine. A deploy
+ token is generated by your GitLab instance, and is provided to users only once
+ (at creation time).
+- A deploy key is valid as long as it's registered and enabled. Deploy tokens can
+ be time-sensitive, as you can control their validity by setting an expiration date to them.
+- You can't log in to a registry with deploy keys, or perform read / write operations
+ on it, but this [is possible with deploy tokens](../deploy_tokens/index.md#gitlab-deploy-token).
+- You need an SSH key pair to use deploy keys, but not deploy tokens.
+
+## How to enable Deploy Keys
+
+### Project deploy keys
+
+[Project maintainers and owners](../../permissions.md#project-members-permissions)
+can add or enable a deploy key for a project repository:
+
+1. Navigate to the project's **Settings > Repository** page.
+1. Expand the **Deploy Keys** section.
+1. Specify a title for the new deploy key and paste your public SSH key.
+1. (Optional) Check **Write access allowed** to allow `read-write` access. Leave it unchecked for `read-only` access.
+
+There are three lists of Project Deploy Keys:
+
+- Enabled deploy keys
+- Privately accessible deploy keys
+- Public accessible deploy keys
+
+![Deploy Keys section](img/deploy_keys_v13_0.png)
+
+After you add a key, it will be enabled for this project by default, and it'll appear
+in the **Enabled deploy keys** tab.
+
+In the **Privately accessible deploy keys** tab, you can enable a private key which
+has been already imported in a different project. If you have access to these keys,
+it's because you have either:
+
+- Previously uploaded the keys yourself in a different project.
+- You are a maintainer or owner of the other project where the keys were imported.
+
+In the **Publicly accessible deploy keys** tab, you can enable
+keys that were [made available to your entire GitLab instance](#public-deploy-keys).
+
+After a key is added, you can edit it to update its title, or switch between `read-only`
+and `read-write` access.
+
+NOTE: **Note:**
+If you have enabled a privately or publicly accessible or deploy key for your
+project, and if you then update the access level for this key from `read-only` to
+`read-write`, the change will be only for the **current project**.
+
+### Public deploy keys
+
+Public deploy keys allow `read-only` or `read-write`
+access to any repository in your GitLab instance. This is useful for integrating
+repositories to secure, shared services, such as CI/CD.
+
+Instance administrators can add public deploy keys:
+
+1. Go to **Admin Area** (**{admin}**) **> Deploy Keys**.
+1. Click on **New deploy key**.
+
+ Make sure your new key has a meaningful title, as it is the primary way for project
+ maintainers and owners to identify the correct public deploy key to add. For example,
+ if the key gives access to a SaaS CI/CD instance, use the name of that service
+ in the key name if that is all the key is used for.
+
+![Public Deploy Keys section](img/public_deploy_key_v13_0.png)
+
+After adding a key, it will be available to any shared systems. Project maintainers
+or higher can [authorize a public deploy key](#project-deploy-keys) to start using it with the project.
+
+NOTE: **Note:**
+The **Publicly accessible deploy keys** tab within Project's CI/CD settings only appears
+if there is at least one Public deploy key configured.
+
+Public deploy keys can provide greater security compared to project deploy keys, as
+the administrator of the target integrated system is the only one who needs to know the key value,
+or configure it.
+
+When creating a Public deploy key, determine whether or not it can be defined for
+very narrow usage, such as just a specific service, or if it needs to be defined for
+broader usage, such as full `read-write` access for all services.
+
+CAUTION: **Warning:**
+Adding a public deploy key does not immediately expose any repository to it. Public
+deploy keys enable access from other systems, but access is not given to any project
+until a project maintainer chooses to make use of it.
+
+## Troubleshooting
+
+### Deploy Key cannot push to a protected branch
+
+If the owner of this deploy key does not have access to a [protected
+branch](../protected_branches.md), then this deploy key won't have access to
+the branch either. In addition to this, choosing the **No one** value in
+[the "Allowed to push" section](../protected_branches.md#configuring-protected-branches)
+means that no users **and** no services using deploy keys can push to that selected branch.
+
+Refer to [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/30769) for more information.
diff --git a/doc/user/project/deploy_tokens/index.md b/doc/user/project/deploy_tokens/index.md
index 2d42debed68..10f0281d0eb 100644
--- a/doc/user/project/deploy_tokens/index.md
+++ b/doc/user/project/deploy_tokens/index.md
@@ -1,7 +1,14 @@
+---
+stage: Release
+group: Progressive Delivery
+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: howto
+---
+
# Deploy Tokens
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17894) in GitLab 10.7.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/issues/199370) from **Settings > Repository** in GitLab 12.9.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/199370) from **Settings > Repository** in GitLab 12.9.
> - [Added `write_registry` scope](https://gitlab.com/gitlab-org/gitlab/-/issues/22743) in GitLab 12.10.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29280) from **Settings > CI / CD** in GitLab 12.10.1.
> - [Added package registry scopes](https://gitlab.com/gitlab-org/gitlab/-/issues/213566) from **Settings > CI / CD** in GitLab 13.0.
@@ -120,7 +127,7 @@ To upload packages in the GitLab package registry, you'll need to:
### Group Deploy Token
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/21765) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/21765) in GitLab 12.9.
A deploy token created at the group level can be used across all projects that
belong either to the specific group or to one of its subgroups.
diff --git a/doc/user/project/description_templates.md b/doc/user/project/description_templates.md
index 16ac53a2b52..0f90c321a14 100644
--- a/doc/user/project/description_templates.md
+++ b/doc/user/project/description_templates.md
@@ -1,3 +1,9 @@
+---
+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/#designated-technical-writers
+---
+
# Description templates
>[Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/4981) in GitLab 8.11.
@@ -29,7 +35,7 @@ templates of the default branch will be taken into account.
For example, if you have a project for tracking new blog posts, you can require the
title, outlines, author name, author social media information, and so on.
- Following the previous example, you can make a template for every MR submitted
- with a new blog post, requiring information about the post date, frontmatter data,
+ with a new blog post, requiring information about the post date, front matter data,
images guidelines, link to the related issue, reviewer name, and so on.
- You can also create issues and merge request templates for different
stages of your workflow, for example, feature proposal, feature improvement, or a bug report.
diff --git a/doc/user/project/img/status_page_detail_link_v13_1.png b/doc/user/project/img/status_page_detail_link_v13_1.png
new file mode 100644
index 00000000000..f3d1005447c
--- /dev/null
+++ b/doc/user/project/img/status_page_detail_link_v13_1.png
Binary files differ
diff --git a/doc/user/project/import/bitbucket.md b/doc/user/project/import/bitbucket.md
index 56717858b53..56266718d12 100644
--- a/doc/user/project/import/bitbucket.md
+++ b/doc/user/project/import/bitbucket.md
@@ -1,3 +1,10 @@
+---
+type: reference, howto
+stage: Manage
+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/#designated-technical-writers
+---
+
# Import your project from Bitbucket Cloud to GitLab
NOTE: **Note:**
diff --git a/doc/user/project/import/bitbucket_server.md b/doc/user/project/import/bitbucket_server.md
index 55df2d7294d..f0e730564d8 100644
--- a/doc/user/project/import/bitbucket_server.md
+++ b/doc/user/project/import/bitbucket_server.md
@@ -1,3 +1,10 @@
+---
+type: reference, howto
+stage: Manage
+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/#designated-technical-writers
+---
+
# Import your project from Bitbucket Server to GitLab
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/20164) in GitLab 11.2.
diff --git a/doc/user/project/import/clearcase.md b/doc/user/project/import/clearcase.md
index 89a9f7da852..173ba71b167 100644
--- a/doc/user/project/import/clearcase.md
+++ b/doc/user/project/import/clearcase.md
@@ -1,3 +1,10 @@
+---
+type: reference, howto
+stage: Manage
+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/#designated-technical-writers
+---
+
# Migrating from ClearCase
[ClearCase](https://www.ibm.com/us-en/marketplace/rational-clearcase) is a set of
diff --git a/doc/user/project/import/cvs.md b/doc/user/project/import/cvs.md
index 3b2404912f7..d2e79458526 100644
--- a/doc/user/project/import/cvs.md
+++ b/doc/user/project/import/cvs.md
@@ -1,3 +1,10 @@
+---
+type: reference, howto
+stage: Manage
+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/#designated-technical-writers
+---
+
# Migrating from CVS
[CVS](https://savannah.nongnu.org/projects/cvs) is an old centralized version
diff --git a/doc/user/project/import/fogbugz.md b/doc/user/project/import/fogbugz.md
index 13409c93929..149b5d1913c 100644
--- a/doc/user/project/import/fogbugz.md
+++ b/doc/user/project/import/fogbugz.md
@@ -1,3 +1,10 @@
+---
+type: reference, howto
+stage: Manage
+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/#designated-technical-writers
+---
+
# Import your project from FogBugz to GitLab
It only takes a few simple steps to import your project from FogBugz.
diff --git a/doc/user/project/import/gemnasium.md b/doc/user/project/import/gemnasium.md
index cf9ac15f5ac..0d6e059f1cf 100644
--- a/doc/user/project/import/gemnasium.md
+++ b/doc/user/project/import/gemnasium.md
@@ -1,3 +1,10 @@
+---
+type: reference, howto
+stage: Manage
+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/#designated-technical-writers
+---
+
# Gemnasium **(ULTIMATE)**
This guide describes how to migrate from Gemnasium.com to your own GitLab
diff --git a/doc/user/project/import/gitea.md b/doc/user/project/import/gitea.md
index 94ab9d9195b..543fffd33d6 100644
--- a/doc/user/project/import/gitea.md
+++ b/doc/user/project/import/gitea.md
@@ -1,3 +1,10 @@
+---
+type: reference, howto
+stage: Manage
+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/#designated-technical-writers
+---
+
# Import your project from Gitea to GitLab
Import your projects from Gitea to GitLab with minimal effort.
diff --git a/doc/user/project/import/github.md b/doc/user/project/import/github.md
index 4c213f21920..b7754e60837 100644
--- a/doc/user/project/import/github.md
+++ b/doc/user/project/import/github.md
@@ -1,3 +1,10 @@
+---
+type: reference, howto
+stage: Manage
+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/#designated-technical-writers
+---
+
# Import your project from GitHub to GitLab
Using the importer, you can import your GitHub repositories to GitLab.com or to
diff --git a/doc/user/project/import/gitlab_com.md b/doc/user/project/import/gitlab_com.md
index 2f87f257754..b9aea629e85 100644
--- a/doc/user/project/import/gitlab_com.md
+++ b/doc/user/project/import/gitlab_com.md
@@ -1,3 +1,10 @@
+---
+type: reference, howto
+stage: Manage
+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/#designated-technical-writers
+---
+
# Project importing from GitLab.com to your private GitLab instance
You can import your existing GitLab.com projects to your GitLab instance, but keep in
diff --git a/doc/user/project/import/index.md b/doc/user/project/import/index.md
index a0da68eb513..86b671c8371 100644
--- a/doc/user/project/import/index.md
+++ b/doc/user/project/import/index.md
@@ -1,3 +1,10 @@
+---
+type: reference, howto
+stage: Manage
+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/#designated-technical-writers
+---
+
# Migrating projects to a GitLab instance
1. [From Bitbucket Cloud](bitbucket.md)
@@ -47,6 +54,10 @@ Keep in mind the limitations of the [import/export feature](../settings/import_e
You will still need to migrate your Container Registry over a series of
Docker pulls and pushes and re-run any CI pipelines to retrieve any build artifacts.
+## Migrating from GitLab.com to self-managed GitLab
+
+The process is essentially the same as for [migrating from self-managed GitLab to GitLab.com](#migrating-from-self-managed-gitlab-to-gitlabcom). The main difference is that users can be created on the self-managed GitLab instance by an admin through the UI or the [users API](../../../api/users.md#user-creation).
+
## Migrating between two self-managed GitLab instances
The best method for migrating from one GitLab instance to another,
diff --git a/doc/user/project/import/jira.md b/doc/user/project/import/jira.md
index db48282a8f3..0b8807bb9b3 100644
--- a/doc/user/project/import/jira.md
+++ b/doc/user/project/import/jira.md
@@ -1,3 +1,9 @@
+---
+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/#designated-technical-writers
+---
+
# Import your Jira project issues to GitLab
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2766) in GitLab 12.10.
@@ -43,6 +49,7 @@ Importing large projects may take several minutes depending on the size of the i
1. On the **{issues}** **Issues** page, click the **Import Issues** (**{import}**) button.
1. Select **Import from Jira**.
+ This option is only visible if you have the [correct permissions](#permissions).
![Import issues from Jira button](img/jira/import_issues_from_jira_button_v12_10.png)
diff --git a/doc/user/project/import/manifest.md b/doc/user/project/import/manifest.md
index 86c8b276887..0374e0acf9a 100644
--- a/doc/user/project/import/manifest.md
+++ b/doc/user/project/import/manifest.md
@@ -1,6 +1,13 @@
+---
+type: howto
+stage: Manage
+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/#designated-technical-writers
+---
+
# Import multiple repositories by uploading a manifest file
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/28811) in GitLab 11.2.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/28811) in GitLab 11.2.
GitLab allows you to import all the required Git repositories
based on a manifest file like the one used by the
diff --git a/doc/user/project/import/perforce.md b/doc/user/project/import/perforce.md
index cbcef7a2fb0..dbc1c491493 100644
--- a/doc/user/project/import/perforce.md
+++ b/doc/user/project/import/perforce.md
@@ -1,3 +1,10 @@
+---
+type: howto
+stage: Manage
+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/#designated-technical-writers
+---
+
# Migrating from Perforce Helix
[Perforce Helix](https://www.perforce.com/) provides a set of tools which also
diff --git a/doc/user/project/import/phabricator.md b/doc/user/project/import/phabricator.md
index c81d489f12b..a19068199db 100644
--- a/doc/user/project/import/phabricator.md
+++ b/doc/user/project/import/phabricator.md
@@ -1,6 +1,13 @@
+---
+type: howto
+stage: Manage
+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/#designated-technical-writers
+---
+
# Import Phabricator tasks into a GitLab project
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/60562) in GitLab 12.0.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/60562) in GitLab 12.0.
GitLab allows you to import all tasks from a Phabricator instance into
GitLab issues. The import creates a single project with the
diff --git a/doc/user/project/import/repo_by_url.md b/doc/user/project/import/repo_by_url.md
index c20b1cb7f5e..9b5e43aae79 100644
--- a/doc/user/project/import/repo_by_url.md
+++ b/doc/user/project/import/repo_by_url.md
@@ -1,3 +1,10 @@
+---
+type: howto
+stage: Manage
+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/#designated-technical-writers
+---
+
# Import project from repo by URL
You can import your existing repositories by providing the Git URL:
diff --git a/doc/user/project/import/svn.md b/doc/user/project/import/svn.md
index cf034aafca9..d5f4a014705 100644
--- a/doc/user/project/import/svn.md
+++ b/doc/user/project/import/svn.md
@@ -1,3 +1,10 @@
+---
+type: howto
+stage: Manage
+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/#designated-technical-writers
+---
+
# Migrating from SVN to GitLab
Subversion (SVN) is a central version control system (VCS) while
@@ -75,7 +82,7 @@ For more information regarding the SubGit configuration options, refer to
### Initial translation
-Now that SubGit has configured the Git/SVN repos, run `subgit` to perform the
+Now that SubGit has configured the Git/SVN repositories, run `subgit` to perform the
initial translation of existing SVN revisions into the Git repository:
```shell
@@ -159,7 +166,7 @@ svn2git https://svn.example.com/path/to/repo --authors /path/to/authors.txt
```
If your SVN repository requires a username and password add the
-`--username <username>` and `--password <password` flags to the above command.
+`--username <username>` and `--password <password>` flags to the above command.
`svn2git` also supports excluding certain file paths, branches, tags, etc. See
[svn2git documentation](https://github.com/nirvdrum/svn2git) or run
`svn2git --help` for full documentation on all of the available options.
diff --git a/doc/user/project/import/tfvc.md b/doc/user/project/import/tfvc.md
index 9b148224e10..1c9ee7476bd 100644
--- a/doc/user/project/import/tfvc.md
+++ b/doc/user/project/import/tfvc.md
@@ -6,7 +6,7 @@ type: concepts
Team Foundation Server (TFS), renamed [Azure DevOps Server](https://azure.microsoft.com/en-us/services/devops/server/)
in 2019, is a set of tools developed by Microsoft which also includes
-[Team Foundation Version Control](https://docs.microsoft.com/en-us/azure/devops/repos/tfvc/overview?view=azure-devops)
+[Team Foundation Version Control](https://docs.microsoft.com/en-us/azure/devops/repos/tfvc/what-is-tfvc?view=azure-devops)
(TFVC), a centralized version control system similar to Git.
In this document, we focus on the TFVC to Git migration.
diff --git a/doc/user/project/index.md b/doc/user/project/index.md
index 50272f0e007..3a4e240fb6c 100644
--- a/doc/user/project/index.md
+++ b/doc/user/project/index.md
@@ -100,7 +100,7 @@ When you create a project in GitLab, you'll have access to a large number of
- [Maven packages](../packages/maven_repository/index.md): your private Maven repository in GitLab. **(PREMIUM)**
- [NPM packages](../packages/npm_registry/index.md): your private NPM package registry in GitLab. **(PREMIUM)**
- [Code owners](code_owners.md): specify code owners for certain files **(STARTER)**
-- [License Compliance](../compliance/license_compliance/index.md): approve and blacklist licenses for projects. **(ULTIMATE)**
+- [License Compliance](../compliance/license_compliance/index.md): approve and deny licenses for projects. **(ULTIMATE)**
- [Dependency List](../application_security/dependency_list/index.md): view project dependencies. **(ULTIMATE)**
- [Requirements](requirements/index.md): Requirements allow you to create criteria to check your products against. **(ULTIMATE)**
- [Static Site Editor](static_site_editor/index.md): quickly edit content on static websites without prior knowledge of the codebase or Git commands.
@@ -144,6 +144,17 @@ To view your starred projects:
- Number of open merge requests
- Number of open issues
+### Explore projects
+
+You can explore other popular projects available on GitLab. To explore projects:
+
+1. Click **Projects** in the navigation bar.
+1. Click **Explore Projects**.
+
+GitLab displays a list of projects, sorted by last updated date. To view
+projects with the most [stars](#star-a-project), click **Most stars**. To view
+projects with the largest number of comments in the past month, click **Trending**.
+
## Project settings
Set the project's visibility level and the access levels to its various pages
@@ -250,14 +261,14 @@ password <personal_access_token>
## Access project page with project ID
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/53671) in GitLab 11.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53671) in GitLab 11.8.
To quickly access a project from the GitLab UI using the project ID,
visit the `/projects/:id` URL in your browser or other tool accessing the project.
## Project aliases **(PREMIUM ONLY)**
-> [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 Premium](https://about.gitlab.com/pricing/) 12.1.
When migrating repositories to GitLab and they are being accessed by other systems,
it's very useful to be able to access them using the same name especially when
diff --git a/doc/user/project/insights/index.md b/doc/user/project/insights/index.md
index 52fcad8dd80..3cc76beb323 100644
--- a/doc/user/project/insights/index.md
+++ b/doc/user/project/insights/index.md
@@ -273,7 +273,7 @@ you defined.
### `projects`
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/10904) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10904) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.4.
You can limit where the "issuables" can be queried from:
diff --git a/doc/user/project/integrations/bamboo.md b/doc/user/project/integrations/bamboo.md
index db8f24fc1e1..7b21c590c8a 100644
--- a/doc/user/project/integrations/bamboo.md
+++ b/doc/user/project/integrations/bamboo.md
@@ -22,7 +22,7 @@ need to be configured in a Bamboo build plan before GitLab can integrate.
1. Choose 'Repository triggers the build when changes are committed'
1. Check one or more repositories checkboxes
1. Enter the GitLab IP address in the 'Trigger IP addresses' box. This is a
- whitelist of IP addresses that are allowed to trigger Bamboo builds.
+ list of IP addresses that are allowed to trigger Bamboo builds.
1. Save the trigger.
1. In the left pane, select a build stage. If you have multiple build stages
you want to select the last stage that contains the Git checkout task.
diff --git a/doc/user/project/integrations/custom_issue_tracker.md b/doc/user/project/integrations/custom_issue_tracker.md
index 848e89c18cb..4eaf3a0d4b4 100644
--- a/doc/user/project/integrations/custom_issue_tracker.md
+++ b/doc/user/project/integrations/custom_issue_tracker.md
@@ -1,25 +1,34 @@
-# Custom Issue Tracker Service
+# Custom Issue Tracker service
-To enable the Custom Issue Tracker integration in a project, navigate to the
-[Integrations page](overview.md#accessing-integrations), click
-the **Customer Issue Tracker** service, and fill in the required details on the page as described
-in the table below. You will be able to edit the title and description later as well.
+To enable the Custom Issue Tracker integration in a project:
-| Field | Description |
-| ----- | ----------- |
-| `title` | A title for the issue tracker (to differentiate between instances, for example). |
-| `description` | A name for the issue tracker (to differentiate between instances, for example) |
-| `project_url` | The URL to the project in the custom issue tracker. |
-| `issues_url` | The URL to the issue in the issue tracker project that is linked to this GitLab project. Note that the `issues_url` requires `:id` in the URL. This ID is used by GitLab as a placeholder to replace the issue number. For example, `https://customissuetracker.com/project-name/:id`. |
-| `new_issue_url` | Currently unused. Will be changed in a future release. |
+1. Go to **{settings}** **Settings > Integrations**.
+1. Click **Custom Issue Tracker**
+1. Fill in the tracker's details, such as title, description, and URLs.
+ You will be able to edit these fields later as well.
-Once you have configured and enabled Custom Issue Tracker Service you'll see a link on the GitLab project pages that takes you to that custom issue tracker.
+ These are some of the required fields:
+
+ | Field | Description |
+ | --------------- | ----------- |
+ | **Title** | A title for the issue tracker (for example, to differentiate between instances). |
+ | **Description** | A name for the issue tracker (for example, to differentiate between instances). |
+ | **Project URL** | The URL to the project in the custom issue tracker. |
+ | **Issues URL** | The URL to the issue in the issue tracker project that is linked to this GitLab project. Note that the `issues_url` requires `:id` in the URL. This ID is used by GitLab as a placeholder to replace the issue number. For example, `https://customissuetracker.com/project-name/:id`. |
+ | **New issue URL** | Currently unused. Will be changed in a future release. |
+
+1. Click **Test settings and save changes**.
+
+After you configure and enable the Custom Issue Tracker service, you'll see a link on the GitLab
+project pages that takes you to that custom issue tracker.
## Referencing issues
-- Issues are referenced with `ANYTHING-<ID>`, where `ANYTHING` can be any string in CAPS and `<ID>`
-is a number used in the target project of the custom integration (for example, `PROJECT-143`).
-- `ANYTHING` is a placeholder to differentiate against GitLab issues, which are referenced with `#<ID>`. You can use a project name or project key to replace it for example.
-- When building the hyperlink, the `ANYTHING` part is ignored, and links always point to the address
+Issues are referenced with `<ANYTHING>-<ID>` (for example, `PROJECT-143`), where `<ANYTHING>` can be any string in CAPS, and `<ID>`
+is a number used in the target project of the custom integration.
+
+`<ANYTHING>` is a placeholder to differentiate against GitLab issues, which are referenced with `#<ID>`. You can use a project name or project key to replace it for example.
+
+When building the hyperlink, the `<ANYTHING>` part is ignored, and links always point to the address
specified in `issues_url`, so in the example above, `PROJECT-143` would refer to
`https://customissuetracker.com/project-name/143`.
diff --git a/doc/user/project/integrations/generic_alerts.md b/doc/user/project/integrations/generic_alerts.md
index 2234727dd82..57c1e54e48c 100644
--- a/doc/user/project/integrations/generic_alerts.md
+++ b/doc/user/project/integrations/generic_alerts.md
@@ -6,8 +6,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Generic alerts integration
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/13203) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.4.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/issues/42640) to [GitLab Core](https://about.gitlab.com/pricing/) in 12.8.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13203) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.4.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/42640) to [GitLab Core](https://about.gitlab.com/pricing/) in 12.8.
GitLab can accept alerts from any source via a generic webhook receiver.
When you set up the generic alerts integration, a unique endpoint will
@@ -18,6 +18,9 @@ create an issue with the payload in the body of the issue. You can always
The entire payload will be posted in the issue discussion as a comment
authored by the GitLab Alert Bot.
+NOTE: **Note**
+In GitLab versions 13.1 and greater, you can configure [External Prometheus instances](prometheus.md#external-prometheus-instances) to use this endpoint.
+
## Setting up generic alerts
To set up the generic alerts integration:
@@ -28,7 +31,7 @@ To set up the generic alerts integration:
## Customizing the payload
-You can customize the payload by sending the following parameters. All fields are optional:
+You can customize the payload by sending the following parameters. All fields other than `title` are optional:
| Property | Type | Description |
| -------- | ---- | ----------- |
@@ -39,6 +42,7 @@ You can customize the payload by sending the following parameters. All fields ar
| `monitoring_tool` | String | The name of the associated monitoring tool. |
| `hosts` | String or Array | One or more hosts, as to where this incident occurred. |
| `severity` | String | The severity of the alert. Must be one of `critical`, `high`, `medium`, `low`, `info`, `unknown`. Default is `critical`. |
+| `fingerprint` | String or Array | The unique identifier of the alert. This can be used to group occurrences of the same alert. |
TIP: **Payload size:**
Ensure your requests are smaller than the [payload application limits](../../../administration/instance_limits.md#generic-alert-json-payloads).
@@ -65,5 +69,7 @@ Example payload:
"service": "service affected",
"monitoring_tool": "value",
"hosts": "value",
+ "severity": "high",
+ "fingerprint": "d19381d4e8ebca87b55cda6e8eee7385"
}
```
diff --git a/doc/user/project/integrations/github.md b/doc/user/project/integrations/github.md
index 42d8eadd35e..f0977a4ea76 100644
--- a/doc/user/project/integrations/github.md
+++ b/doc/user/project/integrations/github.md
@@ -1,6 +1,6 @@
# GitHub project integration **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/3836) in GitLab Premium 10.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3836) in GitLab Premium 10.6.
GitLab provides an integration for updating the pipeline statuses on GitHub.
This is especially useful if using GitLab for CI/CD only.
@@ -39,7 +39,7 @@ to configure pipelines to run for open pull requests.
#### Static / dynamic status check names
> - Introduced in GitLab 11.5: using static status check names as opt-in option.
-> - [In GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/issues/9931), static status check names is default behavior for new projects.
+> - [In GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/-/issues/9931), static status check names is default behavior for new projects.
This makes it possible to mark these status checks as _Required_ on GitHub.
With **Static status check names** enabled on the integration page, your
diff --git a/doc/user/project/integrations/gitlab_slack_application.md b/doc/user/project/integrations/gitlab_slack_application.md
index 49b6a3f6450..7a827364d41 100644
--- a/doc/user/project/integrations/gitlab_slack_application.md
+++ b/doc/user/project/integrations/gitlab_slack_application.md
@@ -8,7 +8,7 @@ The GitLab Slack application is only configurable for GitLab.com. It will **not*
work for on-premises installations where you can configure the
[Slack slash commands](slack_slash_commands.md) service instead. We're planning
to make this configurable for all GitLab installations, but there's
-no ETA - see [#28164](https://gitlab.com/gitlab-org/gitlab/issues/28164).
+no ETA - see [#28164](https://gitlab.com/gitlab-org/gitlab/-/issues/28164).
Slack provides a native application which you can enable via your project's
integrations on GitLab.com.
@@ -32,7 +32,7 @@ integration settings.
Keep in mind that you need to have the appropriate permissions for your Slack
team in order to be able to install a new application, read more in Slack's
-docs on [Adding an app to your team](https://slack.com/help/articles/202035138).
+docs on [Adding an app to your workspace](https://slack.com/help/articles/202035138-Add-an-app-to-your-workspace).
To enable GitLab's service for your Slack team:
diff --git a/doc/user/project/integrations/hangouts_chat.md b/doc/user/project/integrations/hangouts_chat.md
index f33833a9c93..f65b31150a9 100644
--- a/doc/user/project/integrations/hangouts_chat.md
+++ b/doc/user/project/integrations/hangouts_chat.md
@@ -1,6 +1,6 @@
# Hangouts Chat service
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/43756) in GitLab 11.2.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/43756) in GitLab 11.2.
The Hangouts Chat service sends notifications from GitLab to the room for which the webhook was created.
diff --git a/doc/user/project/integrations/img/prometheus_dashboard_yaml_validation_v13_1.png b/doc/user/project/integrations/img/prometheus_dashboard_yaml_validation_v13_1.png
new file mode 100644
index 00000000000..08d7d6603d2
--- /dev/null
+++ b/doc/user/project/integrations/img/prometheus_dashboard_yaml_validation_v13_1.png
Binary files differ
diff --git a/doc/user/project/integrations/img/prometheus_monitoring_dashboard_v12_8.png b/doc/user/project/integrations/img/prometheus_monitoring_dashboard_v12_8.png
deleted file mode 100644
index 8899852ed04..00000000000
--- a/doc/user/project/integrations/img/prometheus_monitoring_dashboard_v12_8.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/integrations/img/prometheus_monitoring_dashboard_v13_1.png b/doc/user/project/integrations/img/prometheus_monitoring_dashboard_v13_1.png
new file mode 100644
index 00000000000..56a0a508a1d
--- /dev/null
+++ b/doc/user/project/integrations/img/prometheus_monitoring_dashboard_v13_1.png
Binary files differ
diff --git a/doc/user/project/integrations/img/related_links_v13_1.png b/doc/user/project/integrations/img/related_links_v13_1.png
new file mode 100644
index 00000000000..4dc141f0e7f
--- /dev/null
+++ b/doc/user/project/integrations/img/related_links_v13_1.png
Binary files differ
diff --git a/doc/user/project/integrations/img/slack_configuration.png b/doc/user/project/integrations/img/slack_configuration.png
deleted file mode 100644
index 4d5e6ae7856..00000000000
--- a/doc/user/project/integrations/img/slack_configuration.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/integrations/jira_cloud_configuration.md b/doc/user/project/integrations/jira_cloud_configuration.md
index 9fa92f19e4f..619c94b282b 100644
--- a/doc/user/project/integrations/jira_cloud_configuration.md
+++ b/doc/user/project/integrations/jira_cloud_configuration.md
@@ -3,7 +3,7 @@
An API token is needed when integrating with Jira Cloud, follow the steps
below to create one:
-1. Log in to <https://id.atlassian.com/manage/api-tokens> with your email address.
+1. Log in to [`id.atlassian.com`](https://id.atlassian.com/manage-profile/security/api-tokens) with your email address.
NOTE: **Note**
It is important that the user associated with this email address has *write* access
diff --git a/doc/user/project/integrations/prometheus.md b/doc/user/project/integrations/prometheus.md
index 6c40e5b9696..0d17ff51372 100644
--- a/doc/user/project/integrations/prometheus.md
+++ b/doc/user/project/integrations/prometheus.md
@@ -25,7 +25,7 @@ Once enabled, GitLab will automatically detect metrics from known services in th
### Managed Prometheus on Kubernetes
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/28916) in GitLab 10.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/28916) in GitLab 10.5.
GitLab can seamlessly deploy and manage Prometheus on a [connected Kubernetes cluster](../clusters/index.md), making monitoring of your apps easy.
@@ -61,7 +61,7 @@ will help you to quickly create a deployment:
1. Navigate to your project's **CI/CD > Pipelines** page, and run a pipeline on any branch.
1. When the pipeline has run successfully, graphs will be available on the **Operations > Metrics** page.
-![Monitoring Dashboard](img/prometheus_monitoring_dashboard_v12_8.png)
+![Monitoring Dashboard](img/prometheus_monitoring_dashboard_v13_1.png)
#### Using the Metrics Dashboard
@@ -209,10 +209,19 @@ GitLab supports a limited set of [CI variables](../../../ci/variables/README.md)
- `ci_project_namespace`
- `ci_project_path`
- `ci_environment_name`
+- `__range`
NOTE: **Note:**
Variables for Prometheus queries must be lowercase.
+###### __range
+
+The `__range` variable is useful in Prometheus
+[range vector selectors](https://prometheus.io/docs/prometheus/latest/querying/basics/#range-vector-selectors).
+Its value is the total number of seconds in the dashboard's time range.
+For example, if the dashboard time range is set to 8 hours, the value of
+`__range` is `28800s`.
+
##### User-defined variables
[Variables can be defined](#templating-templating-properties) in a custom dashboard YAML file.
@@ -244,7 +253,7 @@ http://gitlab.com/<user>/<project>/-/environments/<environment_id>/metrics?dashb
#### Editing additional metrics from the dashboard
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/208976) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/208976) in GitLab 12.9.
You can edit existing additional custom metrics by clicking the **{ellipsis_v}** **More actions** dropdown and selecting **Edit metric**.
@@ -252,7 +261,7 @@ You can edit existing additional custom metrics by clicking the **{ellipsis_v}**
### Defining custom dashboards per project
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/59974) in GitLab 12.1.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/59974) in GitLab 12.1.
By default, all projects include a GitLab-defined Prometheus dashboard, which
includes a few key metrics, but you can also define your own custom dashboards.
@@ -308,8 +317,8 @@ supported and will not be available in the UI.
#### Duplicating a GitLab-defined dashboard
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/37238) in GitLab 12.7.
-> - From [GitLab 12.8 onwards](https://gitlab.com/gitlab-org/gitlab/issues/39505), custom metrics are also duplicated when you duplicate a dashboard.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/37238) in GitLab 12.7.
+> - From [GitLab 12.8 onwards](https://gitlab.com/gitlab-org/gitlab/-/issues/39505), custom metrics are also duplicated when you duplicate a dashboard.
You can save a complete copy of a GitLab defined dashboard along with all custom metrics added to it.
Resulting `.yml` file can be customized and adapted to your project.
@@ -326,6 +335,42 @@ new branch.
If you select your **default** branch, the new dashboard becomes immediately available.
If you select another branch, this branch should be merged to your **default** branch first.
+#### Dashboard YAML syntax validation
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33202) in GitLab 13.1.
+
+To confirm your dashboard definition contains valid YAML syntax:
+
+1. Navigate to **{doc-text}** **Repository > Files**.
+1. Navigate to your dashboard file in your repository.
+1. Review the information pane about the file, displayed above the file contents.
+
+Files with valid syntax display **Metrics Dashboard YAML definition is valid**,
+and files with invalid syntax display **Metrics Dashboard YAML definition is invalid**.
+
+![Metrics Dashboard_YAML_syntax_validation](img/prometheus_dashboard_yaml_validation_v13_1.png)
+
+When **Metrics Dashboard YAML definition is invalid** at least one of the following messages is displayed:
+
+1. `dashboard: can't be blank` [learn more](#dashboard-top-level-properties)
+1. `panel_groups: can't be blank` [learn more](#dashboard-top-level-properties)
+1. `group: can't be blank` [learn more](#panel-group-panel_groups-properties)
+1. `panels: can't be blank` [learn more](#panel-group-panel_groups-properties)
+1. `metrics: can't be blank` [learn more](#panel-panels-properties)
+1. `title: can't be blank` [learn more](#panel-panels-properties)
+1. `query: can't be blank` [learn more](#metrics-metrics-properties)
+1. `query_range: can't be blank` [learn more](#metrics-metrics-properties)
+1. `unit: can't be blank` [learn more](#metrics-metrics-properties)
+1. `YAML syntax: The parsed YAML is too big`
+
+ This is displayed when the YAML file is larger than 1 MB.
+
+1. `YAML syntax: Invalid configuration format`
+
+ This is displayed when the YAML file is empty or does not contain valid YAML.
+
+Metrics Dashboard YAML definition validation information is also available as a [GraphQL API field](../../../api/graphql/reference/index.md#metricsdashboard)
+
#### Dashboard YAML properties
Dashboards have several components:
@@ -342,16 +387,27 @@ The following tables outline the details of expected properties.
| ------ | ------ | ------ | ------ |
| `dashboard` | string | yes | Heading for the dashboard. Only one dashboard should be defined per file. |
| `panel_groups` | array | yes | The panel groups which should be on the dashboard. |
-| `templating` | Hash | no | Top level key under which templating related options can be added. |
+| `templating` | hash | no | Top level key under which templating related options can be added. |
+| `links` | array | no | Add links to display on the dashboard. |
##### **Templating (`templating`) properties**
| Property | Type | Required | Description |
| -------- | ---- | -------- | ----------- |
-| `variables` | Hash | no | Variables can be defined here. |
+| `variables` | hash | yes | Variables can be defined here. |
Read the documentation on [templating](#templating-variables-for-metrics-dashboards).
+##### **Links (`links`) properties**
+
+| Property | Type | Required | Description |
+| -------- | ---- | -------- | ----------- |
+| `url` | string | yes | The address of the link. |
+| `title` | string | no | Display title for the link. |
+| `type` | string | no | Type of the link. Specifies the link type, can be: `grafana` |
+
+Read the documentation on [links](#add-related-links-to-custom-dashboards).
+
##### **Panel group (`panel_groups`) properties**
| Property | Type | Required | Description |
@@ -371,6 +427,7 @@ Read the documentation on [templating](#templating-variables-for-metrics-dashboa
| `max_value` | number | no | Denominator value used for calculating [percentile based results](#percentile-based-results) |
| `weight` | number | no, defaults to order in file | Order to appear within the grouping. Lower number means higher priority, which will be higher on the page. Numbers do not need to be consecutive. |
| `metrics` | array | yes | The metrics which should be displayed in the panel. Any number of metrics can be displayed when `type` is `area-chart` or `line-chart`, whereas only 3 can be displayed when `type` is `anomaly-chart`. |
+| `links` | array | no | Add links to display on the chart's [context menu](#chart-context-menu). |
##### **Axis (`panels[].y_axis`) properties**
@@ -472,7 +529,7 @@ Note the following properties:
![area panel chart](img/prometheus_dashboard_area_panel_type_v12_8.png)
-Starting in [version 12.8](https://gitlab.com/gitlab-org/gitlab/issues/202696), the y-axis values will automatically scale according to the data. Previously, it always started from 0.
+Starting in [version 12.8](https://gitlab.com/gitlab-org/gitlab/-/issues/202696), the y-axis values will automatically scale according to the data. Previously, it always started from 0.
##### Anomaly chart
@@ -574,7 +631,7 @@ Note the following properties:
##### Stacked column
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/30583) in GitLab 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30583) in GitLab 12.8.
To add a stacked column panel type to a dashboard, look at the following sample dashboard file:
@@ -639,7 +696,7 @@ Note the following properties:
###### Percentile based results
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/201946) in GitLab 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/201946) in GitLab 12.8.
Query results sometimes need to be represented as a percentage value out of 100. You can use the `max_value` property at the root of the panel definition:
@@ -662,7 +719,7 @@ For example, if you have a query value of `53.6`, adding `%` as the unit results
##### Heatmaps
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/30581) in GitLab 12.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30581) in GitLab 12.5.
To add a heatmap panel type to a dashboard, look at the following sample dashboard file:
@@ -699,7 +756,7 @@ Templating variables can be used to make your metrics dashboard more versatile.
[dashboard YAML](#dashboard-top-level-properties).
Define your variables in the `variables` key, under `templating`. The value of
the `variables` key should be a hash, and each key under `variables`
-defines a templating variable on the dashboard.
+defines a templating variable on the dashboard, and may contain alphanumeric and underscore characters.
A variable can be used in a Prometheus query in the same dashboard using the syntax
described [here](#using-variables).
@@ -766,7 +823,7 @@ templating:
###### Full syntax
-This example creates a variable called `variable1`, with a default value of `var1_option_2`.
+This example creates a variable called `variable1`, with a default value of `value_option_2`.
The label for the text box on the UI will be the value of the `label` key.
The dashboard UI will display a dropdown with `Option 1` and `Option 2`
as the choices.
@@ -789,9 +846,50 @@ templating:
default: true # (Optional) This option should be the default value of this variable.
```
+### Add related links to custom dashboards
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216385) in GitLab 13.1.
+
+You can embed links to other dashboards or external services in your custom
+dashboard by adding **Related links** to your dashboard's YAML file. Related links
+open in the same tab as the dashboard. Related links can be displayed in the
+following locations on your dashboard:
+
+- At the top of your dashboard as the top level [`links` dashboard property](#dashboard-top-level-properties).
+- In charts context menus as the [`links` property of a panel](#panel-panels-properties).
+
+Related links can contain the following attributes:
+
+- `url`: The full URL to the link. Required.
+- `title`: A phrase describing the link. Optional. If this attribute is not set,
+ the full URL is used for the link title.
+- `type`: A string declaring the type of link. Optional. If set to `grafana`, the
+ dashboard's time range values are converted to Grafana's time range format and
+ appended to the `url`.
+
+The dashboard's time range is appended to the `url` as URL parameters.
+
+The following example shows two related links (`GitLab.com` and `GitLab Documentation`)
+added to a dashboard:
+
+![Links UI](img/related_links_v13_1.png)
+
+#### Links Syntax
+
+```yaml
+links:
+ - title: GitLab.com
+ url: https://gitlab.com
+ - title: GitLab Documentation
+ url: https://docs.gitlab.com
+ - title: Public Grafana playground dashboard
+ url: https://play.grafana.org/d/000000012/grafana-play-home?orgId=1
+ type: grafana
+```
+
### View and edit the source file of a custom dashboard
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/34779) in GitLab 12.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34779) in GitLab 12.5.
When viewing a custom dashboard of a project, you can view the original
`.yml` file by clicking on the **Edit dashboard** button.
@@ -812,7 +910,7 @@ The options are:
### Dashboard Annotations
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/211330) in GitLab 12.10 (enabled by feature flag `metrics_dashboard_annotations`).
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/211330) in GitLab 12.10 (enabled by feature flag `metrics_dashboard_annotations`).
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/215224) in GitLab 13.0.
You can use **Metrics Dashboard Annotations** to mark any important events on
@@ -827,6 +925,14 @@ You can create annotations by making requests to the
![Annotations UI](img/metrics_dashboard_annotations_ui_v13.0.png)
+#### Retention policy
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/211433) in GitLab 13.01.
+
+To avoid excessive storage space consumption by stale annotations, records attached
+to time periods older than two weeks are removed daily. This recurring background
+job runs at 1:00 a.m. local server time.
+
### Expand panel
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3100) in GitLab 13.0.
@@ -839,7 +945,7 @@ browser, or pressing the <kbd>Esc</kbd> key.
### View Logs **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/122013) in GitLab 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/122013) in GitLab 12.8.
If you have [Logs](../clusters/kubernetes_pod_logs.md) enabled,
you can navigate from the charts in the dashboard to view Logs by
@@ -881,8 +987,8 @@ To remove the alert, click back on the alert icon for the desired metric, and cl
#### External Prometheus instances
->- [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/9258) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.8.
->- [Moved](https://gitlab.com/gitlab-org/gitlab/issues/42640) to [GitLab Core](https://about.gitlab.com/pricing/) in 12.10.
+>- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9258) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.8.
+>- [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/42640) to [GitLab Core](https://about.gitlab.com/pricing/) in 12.10.
For manually configured Prometheus servers, a notify endpoint is provided to use with Prometheus webhooks. If you have manual configuration enabled, an **Alerts** section is added to **Settings > Integrations > Prometheus**. This contains the *URL* and *Authorization Key*. The **Reset Key** button will invalidate the key and generate a new one.
@@ -903,12 +1009,15 @@ receivers:
In order for GitLab to associate your alerts with an [environment](../../../ci/environments/index.md), you need to configure a `gitlab_environment_name` label on the alerts you set up in Prometheus. The value of this should match the name of your Environment in GitLab.
+NOTE: **Note**
+In GitLab versions 13.1 and greater, you can configure your manually configured Prometheus server to use the [Generic alerts integration](generic_alerts.md).
+
### Taking action on incidents **(ULTIMATE)**
->- [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/4925) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.11.
->- [From GitLab Ultimate 12.5](https://gitlab.com/gitlab-org/gitlab/issues/13401), when GitLab receives a recovery alert, it will automatically close the associated issue.
+>- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4925) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.11.
+>- [From GitLab Ultimate 12.5](https://gitlab.com/gitlab-org/gitlab/-/issues/13401), when GitLab receives a recovery alert, it will automatically close the associated issue.
-Alerts can be used to trigger actions, like opening an issue automatically (enabled by default since `12.1`). To configure the actions:
+Alerts can be used to trigger actions, like opening an issue automatically (disabled by default since `13.1`). To configure the actions:
1. Navigate to your project's **Settings > Operations > Incidents**.
1. Enable the option to create issues.
@@ -931,14 +1040,14 @@ When GitLab receives a **Recovery Alert**, it will automatically close the assoc
To further customize the issue, you can add labels, mentions, or any other supported [quick action](../quick_actions.md) in the selected issue template, which will apply to all incidents. To limit quick actions or other information to only specific types of alerts, use the `annotations/gitlab_incident_markdown` field.
-Since [version 12.2](https://gitlab.com/gitlab-org/gitlab-foss/issues/63373), GitLab will tag each incident issue with the `incident` label automatically. If the label does not yet exist, it will be created automatically as well.
+Since [version 12.2](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/63373), GitLab will tag each incident issue with the `incident` label automatically. If the label does not yet exist, it will be created automatically as well.
If the metric exceeds the threshold of the alert for over 5 minutes, an email will be sent to all [Maintainers and Owners](../../permissions.md#project-members-permissions) of the project.
## Determining the performance impact of a merge
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10408) in GitLab 9.2.
-> - GitLab 9.3 added the [numeric comparison](https://gitlab.com/gitlab-org/gitlab-foss/issues/27439) of the 30 minute averages.
+> - GitLab 9.3 added the [numeric comparison](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/27439) of the 30 minute averages.
Developers can view the performance impact of their changes within the merge
request workflow.
@@ -1031,7 +1140,7 @@ For [manually configured Prometheus instances](#manual-configuration-of-promethe
### Embedding Cluster Health Charts **(ULTIMATE)**
-> [Introduced](<https://gitlab.com/gitlab-org/gitlab/issues/40997>) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.9.
+> [Introduced](<https://gitlab.com/gitlab-org/gitlab/-/issues/40997>) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.9.
[Cluster Health Metrics](../clusters/index.md#monitoring-your-kubernetes-cluster-ultimate) can also be embedded in [GitLab-flavored Markdown](../../markdown.md).
@@ -1075,7 +1184,7 @@ This will render like so:
#### Embedding charts via integration with Grafana HTTP API
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/31376) in GitLab 12.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/31376) in GitLab 12.5.
Each project can support integration with one Grafana instance. This configuration allows a user to copy a link to a panel in Grafana, then paste it into a GitLab Markdown field. The chart will be rendered in the GitLab chart format.
diff --git a/doc/user/project/integrations/prometheus_units.md b/doc/user/project/integrations/prometheus_units.md
index 691d20e5de2..7b216ced1cc 100644
--- a/doc/user/project/integrations/prometheus_units.md
+++ b/doc/user/project/integrations/prometheus_units.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Unit formats reference
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/201999) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/201999) in GitLab 12.9.
You can select units to format your charts by adding `format` to your
[axis configuration](prometheus.md#dashboard-yaml-properties).
@@ -19,7 +19,7 @@ Currently, your [internationalization and localization options](https://en.wikip
For generic or default data, numbers are formatted according to the current locale in [engineering notation](https://en.wikipedia.org/wiki/Engineering_notation).
-While an [engineering notation exists for the web](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat), GitLab uses a version based off the [scientific notation](https://en.wikipedia.org/wiki/Scientific_notation). GitLab formatting acts in accordance with SI prefixes. For example, using GitLab notation, `1500.00` becomes `1.5k` instead of `1.5E3`. Keep this distinction in mind when using the engineering notation for your metrics.
+While an [engineering notation exists for the web](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat), GitLab uses a version based off the [scientific notation](https://en.wikipedia.org/wiki/Scientific_notation). GitLab formatting acts in accordance with SI prefixes. For example, using GitLab notation, `1500.00` becomes `1.5k` instead of `1.5E3`. Keep this distinction in mind when using the engineering notation for your metrics.
Formats: `engineering`
diff --git a/doc/user/project/integrations/slack.md b/doc/user/project/integrations/slack.md
index 419340c14ef..79fc8eceddf 100644
--- a/doc/user/project/integrations/slack.md
+++ b/doc/user/project/integrations/slack.md
@@ -23,7 +23,23 @@ The Slack Notifications Service allows your GitLab project to send events (e.g.
Your Slack team will now start receiving GitLab event notifications as configured.
-![Slack configuration](img/slack_configuration.png)
+### Triggers available for Slack notifications
+
+The following triggers are available for Slack notifications:
+
+- **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 finishes.
+- **Alert**: Triggered when a new, unique alert is recorded.
## Troubleshooting
diff --git a/doc/user/project/integrations/webex_teams.md b/doc/user/project/integrations/webex_teams.md
index a6e688887b6..10735e33746 100644
--- a/doc/user/project/integrations/webex_teams.md
+++ b/doc/user/project/integrations/webex_teams.md
@@ -4,7 +4,7 @@ You can configure GitLab to send notifications to a Webex Teams space.
## Create a webhook for the space
-1. Go to the [Incoming Webooks app page](https://apphub.webex.com/teams/applications/incoming-webhooks-cisco-systems).
+1. Go to the [Incoming Webhooks app page](https://apphub.webex.com/teams/applications/incoming-webhooks-cisco-systems).
1. Click **Connect** and log in to Webex Teams, if required.
1. Enter a name for the webhook and select the space that will receive the notifications.
1. Click **ADD**.
diff --git a/doc/user/project/integrations/webhooks.md b/doc/user/project/integrations/webhooks.md
index 89e84dda0e8..5a0ca03a646 100644
--- a/doc/user/project/integrations/webhooks.md
+++ b/doc/user/project/integrations/webhooks.md
@@ -89,7 +89,7 @@ You can turn this off in the webhook settings in your GitLab projects.
## Branch filtering
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/20338) in GitLab 11.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/20338) in GitLab 11.3.
Push events can be filtered by branch using a branch name or wildcard pattern
to limit which push events are sent to your webhook endpoint. By default the
diff --git a/doc/user/project/issue_board.md b/doc/user/project/issue_board.md
index 9903a711987..89b17609698 100644
--- a/doc/user/project/issue_board.md
+++ b/doc/user/project/issue_board.md
@@ -1,3 +1,9 @@
+---
+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/#designated-technical-writers
+---
+
# Issue Boards
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/5554) in [GitLab 8.11](https://about.gitlab.com/releases/2016/08/22/gitlab-8-11-released/#issue-board).
@@ -190,7 +196,7 @@ as shown in the following table:
### Multiple issue boards
> - [Introduced](https://about.gitlab.com/releases/2016/10/22/gitlab-8-13-released/) in GitLab 8.13.
-> - Multiple issue boards per project [moved](https://gitlab.com/gitlab-org/gitlab-foss/issues/53811) to [GitLab Core](https://about.gitlab.com/pricing/) in GitLab 12.1.
+> - Multiple issue boards per project [moved](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53811) to [GitLab Core](https://about.gitlab.com/pricing/) in GitLab 12.1.
> - Multiple issue boards per group are available in [GitLab Premium](https://about.gitlab.com/pricing/).
Multiple issue boards allow for more than one issue board for a given project or group.
@@ -290,7 +296,7 @@ Multiple group issue boards were originally [introduced](https://about.gitlab.co
### Assignee lists **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/5784) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.0.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5784) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.0.
Like in a regular list that shows all issues with a chosen label, you can add
an assignee list that shows all issues assigned to a user.
@@ -311,7 +317,7 @@ To remove an assignee list, just as with a label list, click the trash icon.
### Milestone lists **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/6469) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.2.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/6469) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.2.
You're also able to create lists of a milestone. These are lists that filter issues by the assigned
milestone, giving you more freedom and visibility on the issue board. To add a milestone list:
@@ -330,7 +336,7 @@ As in other list types, click the trash icon to remove a list.
## Work In Progress limits **(STARTER)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/11403) in GitLab 12.7
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11403) in GitLab 12.7
You can set Work In Progress (WIP) limits per issues list. When a limit is set, the list's header
shows the number of issues in the list and the soft limit of issues.
@@ -352,7 +358,7 @@ To set a WIP limit for a list:
## Blocked issues
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/34723) in GitLab 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34723) in GitLab 12.8.
If an issue is blocked by another issue, an icon appears next to its title to indicate its blocked
status.
@@ -370,7 +376,7 @@ status.
- [Filter issues](#filter-issues) that appear across your issue board.
- [Create workflows](#create-workflows).
- [Drag issues between lists](#drag-issues-between-lists).
-- [Mulit-select issue cards](#multi-select-issue-cards).
+- [Multi-select issue cards](#multi-select-issue-cards).
- [Re-order issues in lists](#issue-ordering-in-a-list).
- Drag and reorder the lists.
- Change issue labels (by dragging an issue between lists).
@@ -501,7 +507,7 @@ When dragging issues between lists, different behavior occurs depending on the s
### Multi-select issue cards
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/18954) in GitLab 12.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18954) in GitLab 12.4.
You can select multiple issue cards, then drag the group to another position within the list, or to another list. This makes it faster to reorder many issues at once.
diff --git a/doc/user/project/issues/associate_zoom_meeting.md b/doc/user/project/issues/associate_zoom_meeting.md
index 3bfd24c9654..a026854a947 100644
--- a/doc/user/project/issues/associate_zoom_meeting.md
+++ b/doc/user/project/issues/associate_zoom_meeting.md
@@ -1,3 +1,9 @@
+---
+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/#designated-technical-writers
+---
+
# Associate a Zoom meeting with an issue
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/16609) in GitLab 12.4.
diff --git a/doc/user/project/issues/confidential_issues.md b/doc/user/project/issues/confidential_issues.md
index a292ce64af9..602a6d79848 100644
--- a/doc/user/project/issues/confidential_issues.md
+++ b/doc/user/project/issues/confidential_issues.md
@@ -1,3 +1,9 @@
+---
+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/#designated-technical-writers
+---
+
# Confidential issues
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/3282) in GitLab 8.6.
@@ -80,7 +86,7 @@ project's search results respectively.
## Merge Requests for Confidential Issues
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/58583) in GitLab 12.1.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/58583) in GitLab 12.1.
To help prevent confidential information being leaked from a public project
in the process of resolving a confidential issue, confidential issues can be
diff --git a/doc/user/project/issues/crosslinking_issues.md b/doc/user/project/issues/crosslinking_issues.md
index e774fd4480b..6cc31a45309 100644
--- a/doc/user/project/issues/crosslinking_issues.md
+++ b/doc/user/project/issues/crosslinking_issues.md
@@ -1,3 +1,9 @@
+---
+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/#designated-technical-writers
+---
+
# Crosslinking Issues
Please read through the [GitLab Issue Documentation](index.md) for an overview on GitLab Issues.
diff --git a/doc/user/project/issues/design_management.md b/doc/user/project/issues/design_management.md
index 64f56221632..981c2a7c34a 100644
--- a/doc/user/project/issues/design_management.md
+++ b/doc/user/project/issues/design_management.md
@@ -3,10 +3,6 @@
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/660) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.2.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212566) to GitLab Core in 13.0.
-CAUTION: **Warning:**
-This an **alpha** feature and is subject to change at any time without
-prior notice.
-
## Overview
Design Management allows you to upload design assets (wireframes, mockups, etc.)
@@ -45,19 +41,19 @@ If the requirements are not met, the **Designs** tab displays a message to the u
Files uploaded must have a file extension of either `png`, `jpg`, `jpeg`,
`gif`, `bmp`, `tiff` or `ico`.
-Support for [SVG files](https://gitlab.com/gitlab-org/gitlab/issues/12771)
-and [PDFs](https://gitlab.com/gitlab-org/gitlab/issues/32811) is planned for a future release.
+Support for [SVG files](https://gitlab.com/gitlab-org/gitlab/-/issues/12771)
+and [PDFs](https://gitlab.com/gitlab-org/gitlab/-/issues/32811) is planned for a future release.
## Limitations
- Design uploads are limited to 10 files at a time.
- Design Management data
- [isn't deleted when a project is destroyed](https://gitlab.com/gitlab-org/gitlab/issues/13429) yet.
-- Design Management data [won't be moved](https://gitlab.com/gitlab-org/gitlab/issues/13426)
- when an issue is moved, nor [deleted](https://gitlab.com/gitlab-org/gitlab/issues/13427)
+ [isn't deleted when a project is destroyed](https://gitlab.com/gitlab-org/gitlab/-/issues/13429) yet.
+- Design Management data [won't be moved](https://gitlab.com/gitlab-org/gitlab/-/issues/13426)
+ when an issue is moved, nor [deleted](https://gitlab.com/gitlab-org/gitlab/-/issues/13427)
when an issue is deleted.
- From GitLab 12.7, Design Management data [can be replicated](../../../administration/geo/replication/datatypes.md#limitations-on-replicationverification)
- by Geo but [not verified](https://gitlab.com/gitlab-org/gitlab/issues/32467).
+ by Geo but [not verified](https://gitlab.com/gitlab-org/gitlab/-/issues/32467).
- Only the latest version of the designs can be deleted.
- Deleted designs cannot be recovered but you can see them on previous designs versions.
@@ -71,8 +67,8 @@ Navigate to the **Design Management** page from any issue by clicking the **Desi
To upload design images, click the **Upload Designs** button and select images to upload.
-[Introduced](https://gitlab.com/gitlab-org/gitlab/issues/34353) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.9,
-you can drag and drop designs onto the dedicated dropzone to upload them.
+[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34353) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.9,
+you can drag and drop designs onto the dedicated drop zone to upload them.
![Drag and drop design uploads](img/design_drag_and_drop_uploads_v12_9.png)
@@ -91,7 +87,7 @@ Copy-and-pasting has some limitations:
- Copy/pasting designs is not supported on Internet Explorer.
Designs with the same filename as an existing uploaded design will create a new version
-of the design, and will replace the previous version. [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/34353) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.9, dropping a design on an existing uploaded design will also create a new version,
+of the design, and will replace the previous version. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34353) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.9, dropping a design on an existing uploaded design will also create a new version,
provided the filenames are the same.
Designs cannot be added if the issue has been moved, or its
@@ -123,19 +119,19 @@ to help summarize changes between versions.
### Exploring designs by zooming
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/13217) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13217) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.7.
Designs can be explored in greater detail by zooming in and out of the image.
Control the amount of zoom with the `+` and `-` buttons at the bottom of the image.
While zoomed, you can still [start new discussions](#starting-discussions-on-designs) on the image, and see any existing ones.
-[Introduced](https://gitlab.com/gitlab-org/gitlab/issues/197324) in GitLab 12.10, while zoomed in,
+[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/197324) in GitLab 12.10, while zoomed in,
you can click-and-drag on the image to move around it.
![Design zooming](img/design_zooming_v12_7.png)
## Deleting designs
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/11089) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11089) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.4.
There are two ways to delete designs: manually delete them
individually, or select a few of them to delete at once,
@@ -169,7 +165,7 @@ A pin is added to the image, identifying the discussion's location.
![Starting a new discussion on design](img/adding_note_to_design_1.png)
-[Introduced](https://gitlab.com/gitlab-org/gitlab/issues/34353) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.8,
+[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34353) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.8,
you can adjust a pin's position by dragging it around the image. This is useful
for when your design layout has changed between revisions, or if you need to move an
existing pin to add a new one in its place.
@@ -180,3 +176,60 @@ Different discussions have different pin numbers:
From GitLab 12.5 on, new discussions will be outputted to the issue activity,
so that everyone involved can participate in the discussion.
+
+## Resolve Design threads
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13049) in GitLab 13.1.
+
+Discussion threads can be resolved on Designs. You can mark a thread as resolved
+or unresolved by clicking the **Resolve thread** icon at the first comment of the
+discussion.
+
+![Resolve thread icon](img/resolve_design-discussion_icon_v13_1.png)
+
+Pinned comments can also be resolved or unresolved in their threads.
+When replying to a comment, you will see a checkbox that you can click in order to resolve or unresolve
+the thread once published.
+
+![Resolve checkbox](img/resolve_design-discussion_checkbox_v13_1.png)
+
+## Referring to designs in Markdown
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217160) in **GitLab 13.1**.
+> - It is deployed behind a feature flag, disabled by default.
+> - It is disabled on GitLab.com.
+> - It is not recommended for production use.
+> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-design-references-core-only). **(CORE ONLY)**
+
+We support referring to designs in [Markdown](../../markdown.md), which is available
+throughout the application, including in merge request and issue descriptions, in discussions and comments, and in wiki pages.
+
+At present, full URL references are supported. For example, if we refer to a design
+somewhere with:
+
+```markdown
+See https://gitlab.com/your-group/your-project/-/issues/123/designs/homescreen.png
+```
+
+This will be rendered as:
+
+> See [#123[homescreen.png]](https://gitlab.com/your-group/your-project/-/issues/123/designs/homescreen.png)
+
+### Enable or disable design references **(CORE ONLY)**
+
+Design reference parsing 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 for your instance.
+
+To enable it:
+
+```ruby
+Feature.enable(:design_management_reference_filter_gfm_pipeline)
+```
+
+To disable it:
+
+```ruby
+Feature.disable(:design_management_reference_filter_gfm_pipeline)
+```
diff --git a/doc/user/project/issues/due_dates.md b/doc/user/project/issues/due_dates.md
index 0be0cdd11bd..56fb4ca5cc7 100644
--- a/doc/user/project/issues/due_dates.md
+++ b/doc/user/project/issues/due_dates.md
@@ -1,3 +1,9 @@
+---
+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/#designated-technical-writers
+---
+
# Due dates
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/3614) in GitLab 8.7.
diff --git a/doc/user/project/issues/img/new_issue.png b/doc/user/project/issues/img/new_issue.png
deleted file mode 100644
index 07d65a93070..00000000000
--- a/doc/user/project/issues/img/new_issue.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/issues/img/new_issue_v13_1.png b/doc/user/project/issues/img/new_issue_v13_1.png
new file mode 100644
index 00000000000..a66846c234e
--- /dev/null
+++ b/doc/user/project/issues/img/new_issue_v13_1.png
Binary files differ
diff --git a/doc/user/project/issues/img/resolve_design-discussion_checkbox_v13_1.png b/doc/user/project/issues/img/resolve_design-discussion_checkbox_v13_1.png
new file mode 100644
index 00000000000..bd9d1f7a77c
--- /dev/null
+++ b/doc/user/project/issues/img/resolve_design-discussion_checkbox_v13_1.png
Binary files differ
diff --git a/doc/user/project/issues/img/resolve_design-discussion_icon_v13_1.png b/doc/user/project/issues/img/resolve_design-discussion_icon_v13_1.png
new file mode 100644
index 00000000000..5cd005f0799
--- /dev/null
+++ b/doc/user/project/issues/img/resolve_design-discussion_icon_v13_1.png
Binary files differ
diff --git a/doc/user/project/issues/index.md b/doc/user/project/issues/index.md
index 22221531360..06a80672769 100644
--- a/doc/user/project/issues/index.md
+++ b/doc/user/project/issues/index.md
@@ -1,3 +1,9 @@
+---
+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/#designated-technical-writers
+---
+
# Issues
Issues are the fundamental medium for collaborating on ideas and planning work in GitLab.
@@ -151,7 +157,7 @@ context, such as past work, dependencies, or duplicates.
### Crosslinking issues
-You can [crosslink issues](crosslinking_issues.md) by referencing an issue from another
+You can [cross-link issues](crosslinking_issues.md) by referencing an issue from another
issue or merge request by including its URL or ID. The referenced issue displays a
message in the Activity stream about the reference, with a link to the other issue or MR.
@@ -173,7 +179,7 @@ requires [GraphQL](../../../api/graphql/index.md) to be enabled.
### Health status **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/36427) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.10.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/36427) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.10.
To help you track the status of your issues, you can assign a status to each issue to flag work
that's progressing as planned or needs attention to keep on schedule:
diff --git a/doc/user/project/issues/issue_data_and_actions.md b/doc/user/project/issues/issue_data_and_actions.md
index 65e21566d5d..6d34f91d37f 100644
--- a/doc/user/project/issues/issue_data_and_actions.md
+++ b/doc/user/project/issues/issue_data_and_actions.md
@@ -1,3 +1,9 @@
+---
+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/#designated-technical-writers
+---
+
# Issue Data and Actions
Please read through the [GitLab Issue Documentation](index.md) for an overview on GitLab Issues.
@@ -185,7 +191,7 @@ The plain text title and description of the issue fill the top center of the iss
The description fully supports [GitLab Flavored Markdown](../../markdown.md#gitlab-flavored-markdown-gfm),
allowing many formatting options.
-> [Since GitLab 12.6](https://gitlab.com/gitlab-org/gitlab/issues/10103), changes to an issue's description are listed in the [issue history](#issue-history).**(STARTER)**
+> [Since GitLab 12.6](https://gitlab.com/gitlab-org/gitlab/-/issues/10103), changes to an issue's description are listed in the [issue history](#issue-history).**(STARTER)**
### Mentions
@@ -296,7 +302,7 @@ You can also close the issue from here, so you don't need to scroll to the top o
### Zoom meetings
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/31103) in GitLab 12.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/31103) in GitLab 12.3.
You can attach and remove Zoom meetings to issues using the `/zoom` and `/remove_zoom` [quick actions](../quick_actions.md) as part of
[GitLab Flavored Markdown](../../markdown.md#gitlab-flavored-markdown-gfm).
@@ -305,3 +311,9 @@ Attaching a [Zoom](https://zoom.us) call an issue
results in a **Join Zoom meeting** button at the top of the issue, just under the header.
Read more how to [add or remove a zoom meeting](associate_zoom_meeting.md).
+
+### Publish an issue **(ULTIMATE)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30906) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.1.
+
+If a status page application is associated with the project, you can use the `/publish` [quick action](../quick_actions.md) to publish the issue. Refer to [GitLab Status Page](../status_page/index.md) for more information.
diff --git a/doc/user/project/issues/issue_weight.md b/doc/user/project/issues/issue_weight.md
index 74f607dd407..23c1520294d 100644
--- a/doc/user/project/issues/issue_weight.md
+++ b/doc/user/project/issues/issue_weight.md
@@ -1,5 +1,8 @@
---
disqus_identifier: 'https://docs.gitlab.com/ee/workflow/issue_weight.html'
+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/#designated-technical-writers
---
# Issue weight **(STARTER)**
diff --git a/doc/user/project/issues/managing_issues.md b/doc/user/project/issues/managing_issues.md
index 4e329889e7c..08e3164b2eb 100644
--- a/doc/user/project/issues/managing_issues.md
+++ b/doc/user/project/issues/managing_issues.md
@@ -1,21 +1,28 @@
-# Managing Issues
+---
+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/#designated-technical-writers
+---
+
+# Managing issues
[GitLab Issues](index.md) are the fundamental medium for collaborating on ideas and
planning work in GitLab. [Creating](#create-a-new-issue), [moving](#moving-issues),
[closing](#closing-issues), and [deleting](#deleting-issues) are key actions that
you can do with issues.
-## Create a new Issue
+## Create a new issue
-When you create a new issue, you'll be prompted to fill in the [data and fields of the issue](issue_data_and_actions.md), as illustrated below. If you know
-the values you want to assign to an issue, you can use the [Quick actions](../quick_actions.md)
-feature to input values, instead of selecting them from lists.
+When you create a new issue, you'll be prompted to fill in the [data and fields of the issue](issue_data_and_actions.md),
+as illustrated below. If you know the values you want to assign to an issue, you can use the
+[Quick actions](../quick_actions.md) feature to input values, instead of selecting them from lists.
-![New issue from the issues list](img/new_issue.png)
+While creating an issue, you can associate it to an existing epic from current group by
+selecting it using **Epic** dropdown.
-### Accessing the new Issue form
+### Accessing the New Issue form
-There are many ways to get to the new Issue form from within a project:
+There are many ways to get to the New Issue form from within a project:
- Navigate to your **Project's Dashboard** > **Issues** > **New Issue**:
@@ -36,9 +43,28 @@ There are many ways to get to the new Issue form from within a project:
![From the issue board](img/new_issue_from_issue_board.png)
+### Elements of the New Issue form
+
+> Ability to add the new issue to an epic [was introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13847)
+> in [GitLab Premium](https://about.gitlab.com/pricing/) 13.1.
+
+![New issue from the issues list](img/new_issue_v13_1.png)
+
+When you're creating a new issue, these are the fields you can fill in:
+
+- Title
+- Description
+- Checkbox to make the issue confidential
+- Assignee
+- Weight
+- Epic **(PREMIUM)**
+- Due date
+- Milestone
+- Labels
+
### New issue from the group-level Issue Tracker
-Go to the Group dashboard and click "Issues" in the sidebar to visit the Issue Tracker
+Go to the Group dashboard and click **Issues** in the sidebar to visit the Issue Tracker
for all projects in your Group. Select the project you'd like to add an issue for
using the dropdown button at the top-right of the page.
@@ -107,11 +133,11 @@ field).
Follow these examples to form your new issue URL with prefilled fields.
- For a new issue in the GitLab Community Edition project with a pre-filled title
- and a pre-filled description, the URL would be `https://gitlab.com/gitlab-org/gitlab-foss/issues/new?issue[title]=Validate%20new%20concept&issue[description]=Research%20idea`
+ and a pre-filled description, the URL would be `https://gitlab.com/gitlab-org/gitlab-foss/-/issues/new?issue[title]=Validate%20new%20concept&issue[description]=Research%20idea`
- For a new issue in the GitLab Community Edition project with a pre-filled title
- and a pre-filled description template, the URL would be `https://gitlab.com/gitlab-org/gitlab-foss/issues/new?issue[title]=Validate%20new%20concept&issuable_template=Research%20proposal`
+ and a pre-filled description template, the URL would be `https://gitlab.com/gitlab-org/gitlab-foss/-/issues/new?issue[title]=Validate%20new%20concept&issuable_template=Research%20proposal`
- For a new issue in the GitLab Community Edition project with a pre-filled title,
- a pre-filled description, and the confidential flag set, the URL would be `https://gitlab.com/gitlab-org/gitlab-foss/issues/new?issue[title]=Validate%20new%20concept&issue[description]=Research%20idea&issue[confidential]=true`
+ a pre-filled description, and the confidential flag set, the URL would be `https://gitlab.com/gitlab-org/gitlab-foss/-/issues/new?issue[title]=Validate%20new%20concept&issue[description]=Research%20idea&issue[confidential]=true`
## Moving Issues
@@ -147,7 +173,7 @@ issues.each do |issue|
end; nil
```
-## Closing Issues
+## Closing issues
When you decide that an issue is resolved, or no longer needed, you can close the issue
using the close button:
@@ -226,6 +252,8 @@ when used from the command line with `git commit -m`.
#### Disabling automatic issue closing
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/19754) in GitLab 12.7.
+
The automatic issue closing feature can be disabled on a per-project basis
within the [project's repository settings](../settings/index.md). Referenced
issues will still be displayed as such but won't be closed automatically.
@@ -243,7 +271,7 @@ In order to change the default issue closing pattern, GitLab administrators must
[`gitlab.rb` or `gitlab.yml` file](../../../administration/issue_closing_pattern.md)
of your installation.
-## Deleting Issues
+## Deleting issues
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/2982) in GitLab 8.6
diff --git a/doc/user/project/issues/multiple_assignees_for_issues.md b/doc/user/project/issues/multiple_assignees_for_issues.md
index dff6a6031d7..c11977f5bee 100644
--- a/doc/user/project/issues/multiple_assignees_for_issues.md
+++ b/doc/user/project/issues/multiple_assignees_for_issues.md
@@ -1,6 +1,12 @@
+---
+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/#designated-technical-writers
+---
+
# Multiple Assignees for Issues **(STARTER)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/1904) in [GitLab Starter 9.2](https://about.gitlab.com/releases/2017/05/22/gitlab-9-2-released/#multiple-assignees-for-issues).
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/1904) in [GitLab Starter 9.2](https://about.gitlab.com/releases/2017/05/22/gitlab-9-2-released/#multiple-assignees-for-issues).
## Overview
diff --git a/doc/user/project/issues/related_issues.md b/doc/user/project/issues/related_issues.md
index 8002b528a80..445c28492df 100644
--- a/doc/user/project/issues/related_issues.md
+++ b/doc/user/project/issues/related_issues.md
@@ -1,3 +1,9 @@
+---
+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/#designated-technical-writers
+---
+
# Related issues **(STARTER)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/1797) in [GitLab Starter](https://about.gitlab.com/pricing/) 9.4.
diff --git a/doc/user/project/issues/sorting_issue_lists.md b/doc/user/project/issues/sorting_issue_lists.md
index d52b629bfed..7cbd9906800 100644
--- a/doc/user/project/issues/sorting_issue_lists.md
+++ b/doc/user/project/issues/sorting_issue_lists.md
@@ -1,4 +1,10 @@
-# Sorting and Ordering Issue Lists
+---
+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/#designated-technical-writers
+---
+
+# Sorting and ordering issue lists
You can sort a list of issues several ways, including by issue creation date, milestone due date,
etc. The available sorting options can change based on the context of the list.
@@ -9,7 +15,7 @@ similar to [issue boards](../issue_board.md#issue-ordering-in-a-list).
## Manual sorting
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/62178) in GitLab 12.2.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/62178) in GitLab 12.2.
When you select **Manual** sorting, you can change
the order by dragging and dropping the issues. The changed order will persist. Everyone who visits the same list will see the reordered list, with some exceptions.
diff --git a/doc/user/project/labels.md b/doc/user/project/labels.md
index f3b59147d5b..406938519b1 100644
--- a/doc/user/project/labels.md
+++ b/doc/user/project/labels.md
@@ -1,3 +1,9 @@
+---
+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/#designated-technical-writers
+---
+
# Labels
## Overview
@@ -131,7 +137,7 @@ to the project:
## Scoped labels **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/9175) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.10.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9175) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.10.
Scoped labels allow teams to use the label feature to annotate issues, merge requests
and epics with mutually exclusive labels. This can enable more complicated workflows
@@ -203,8 +209,8 @@ to label notifications for the project only, or the whole group.
## Label priority
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/14189) in GitLab 8.9.
-> - Priority sorting is based on the highest priority label only. [This discussion](https://gitlab.com/gitlab-org/gitlab/issues/14523) considers changing this.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/14189) in GitLab 8.9.
+> - Priority sorting is based on the highest priority label only. [This discussion](https://gitlab.com/gitlab-org/gitlab/-/issues/14523) considers changing this.
Labels can have relative priorities, which are used in the **Label priority** and
**Priority** sort orders of the epic, issue, and merge request list pages. Prioritization
@@ -229,7 +235,7 @@ If you sort by `Label priority`, GitLab uses this sort comparison order:
1. Items without a prioritized label.
Ties are broken arbitrarily. Note that only the highest prioritized label is checked,
-and labels with a lower priority are ignored. See this [related issue](https://gitlab.com/gitlab-org/gitlab/issues/14523)
+and labels with a lower priority are ignored. See this [related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/14523)
for more information.
![Labels sort label priority](img/labels_sort_label_priority.png)
diff --git a/doc/user/project/members/index.md b/doc/user/project/members/index.md
index 9020dc335b6..787a74b0065 100644
--- a/doc/user/project/members/index.md
+++ b/doc/user/project/members/index.md
@@ -8,7 +8,7 @@ You should have Maintainer or Owner [permissions](../../permissions.md) to add
or import a new user to your project.
To view, edit, add, and remove project's members, go to your
-project's **Settings > Members**.
+project's **Members**.
## Inherited membership
@@ -27,7 +27,7 @@ From the image above, we can deduce the following things:
- Administrator is the Owner and member of **all** groups and for that reason,
there is an indication of an ancestor group and inherited Owner permissions.
-[From GitLab 12.6](https://gitlab.com/gitlab-org/gitlab/issues/21727), you can filter this list
+[From GitLab 12.6](https://gitlab.com/gitlab-org/gitlab/-/issues/21727), you can filter this list
using the dropdown on the right side:
![Project members filter](img/project_members_filter_v12_6.png)
diff --git a/doc/user/project/members/share_project_with_groups.md b/doc/user/project/members/share_project_with_groups.md
index d0ceac3e1f3..033d69cbbfa 100644
--- a/doc/user/project/members/share_project_with_groups.md
+++ b/doc/user/project/members/share_project_with_groups.md
@@ -18,7 +18,7 @@ This is where the group sharing feature can be of use.
To share 'Project Acme' with the 'Engineering' group:
-1. For 'Project Acme' use the left navigation menu to go to **Settings > Members**
+1. For 'Project Acme' use the left navigation menu to go to **Members**
![share project with groups](img/share_project_with_groups.png)
diff --git a/doc/user/project/merge_requests/accessibility_testing.md b/doc/user/project/merge_requests/accessibility_testing.md
index 427761281f6..417b85a6082 100644
--- a/doc/user/project/merge_requests/accessibility_testing.md
+++ b/doc/user/project/merge_requests/accessibility_testing.md
@@ -25,16 +25,6 @@ Accessibility Report in the merge request widget area:
![Accessibility Merge Request Widget](img/accessibility_mr_widget_v13_0.png)
-This widget comes with the `:accessibility_report_view` feature flag disabled by default while we test feature stability.
-Once we have determined the widget is stable, this feature will be enabled 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
-Feature.enable(:accessibility_report_view)
-```
-
## Configure Accessibility Testing
This example shows how to run [pa11y](https://pa11y.org/)
diff --git a/doc/user/project/merge_requests/browser_performance_testing.md b/doc/user/project/merge_requests/browser_performance_testing.md
index 0fa3d7be265..390d480724d 100644
--- a/doc/user/project/merge_requests/browser_performance_testing.md
+++ b/doc/user/project/merge_requests/browser_performance_testing.md
@@ -60,7 +60,7 @@ on your code by using GitLab CI/CD and [sitespeed.io](https://www.sitespeed.io)
using Docker-in-Docker.
1. First, set up GitLab Runner with a
- [docker-in-docker build](../../../ci/docker/using_docker_build.md#use-docker-in-docker-workflow-with-docker-executor).
+ [Docker-in-Docker build](../../../ci/docker/using_docker_build.md#use-docker-in-docker-workflow-with-docker-executor).
1. After configuring the Runner, add a new job to `.gitlab-ci.yml` that generates
the expected report.
1. Define the `performance` job according to your version of GitLab:
@@ -125,7 +125,7 @@ Key metrics are automatically extracted and shown in the merge request widget.
### Configuring degradation threshold
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/27599) in GitLab 13.0.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27599) in GitLab 13.0.
You can configure the sensitivity of degradation alerts to avoid getting alerts for minor drops in metrics.
This is done by setting the `DEGRADATION_THRESHOLD` variable. In the example below, the alert will only show up
diff --git a/doc/user/project/merge_requests/cherry_pick_changes.md b/doc/user/project/merge_requests/cherry_pick_changes.md
index 3e76b9ec6b9..6685c50c1ed 100644
--- a/doc/user/project/merge_requests/cherry_pick_changes.md
+++ b/doc/user/project/merge_requests/cherry_pick_changes.md
@@ -33,7 +33,7 @@ request thread crosslinking the new commit and the existing merge request.
Each deployment's [list of associated merge requests](../../../api/deployments.md#list-of-merge-requests-associated-with-a-deployment) will include cherry-picked merge commits.
NOTE: **Note:**
-We only track cherry-pick executed from GitLab (both UI and API). Support for [tracking cherry-picked commits through the command line](https://gitlab.com/gitlab-org/gitlab/issues/202215) is planned for a future release.
+We only track cherry-pick executed from GitLab (both UI and API). Support for [tracking cherry-picked commits through the command line](https://gitlab.com/gitlab-org/gitlab/-/issues/202215) is planned for a future release.
## Cherry-picking a commit
diff --git a/doc/user/project/merge_requests/code_quality.md b/doc/user/project/merge_requests/code_quality.md
index beb90e30906..7b4d4b668d5 100644
--- a/doc/user/project/merge_requests/code_quality.md
+++ b/doc/user/project/merge_requests/code_quality.md
@@ -12,7 +12,7 @@ source code quality using GitLab Code Quality.
Code Quality:
- Uses [Code Climate Engines](https://codeclimate.com), which are
- free and open source. Code Quality doesn't require a Code Climate
+ free and open source. Code Quality does not require a Code Climate
subscription.
- Runs in [pipelines](../../../ci/pipelines/index.md) using a Docker image built in the
[GitLab Code
@@ -67,10 +67,10 @@ This example shows how to run Code Quality on your code by using GitLab CI/CD an
First, you need GitLab Runner configured:
-- For the [docker-in-docker workflow](../../../ci/docker/using_docker_build.md#use-docker-in-docker-workflow-with-docker-executor).
+- For the [Docker-in-Docker workflow](../../../ci/docker/using_docker_build.md#use-docker-in-docker-workflow-with-docker-executor).
- With enough disk space to handle generated Code Quality files. For example on the [GitLab project](https://gitlab.com/gitlab-org/gitlab) the files are approximately 7 GB.
-Once you set up the Runner, include the CodeQuality template in your CI config:
+Once you set up the Runner, include the Code Quality template in your CI configuration:
```yaml
include:
@@ -80,10 +80,9 @@ include:
The above example will create a `code_quality` job in your CI/CD pipeline which
will scan your source code for code quality issues. The report will be saved as a
[Code Quality report artifact](../../../ci/pipelines/job_artifacts.md#artifactsreportscodequality-starter)
-that you can later download and analyze. Due to implementation limitations we always
-take the latest Code Quality artifact available.
+that you can later download and analyze.
-It is also possible to override the URL to the Code Quality image by
+It's also possible to override the URL to the Code Quality image by
setting the `CODE_QUALITY_IMAGE` variable. This is particularly useful if you want
to lock in a specific version of Code Quality, or use a fork of it:
@@ -108,7 +107,7 @@ code_quality:
paths: [gl-code-quality-report.json]
```
-The included `code_quality` job is running in the `test` stage, so it needs to be included in your CI config, like so:
+The included `code_quality` job is running in the `test` stage, so it needs to be included in your CI configuration, like so:
```yaml
stages:
@@ -120,7 +119,7 @@ This information will be automatically extracted and shown right in the merge re
CAUTION: **Caution:**
On self-managed instances, if a malicious actor compromises the Code Quality job
-definition they will be able to execute privileged docker commands on the Runner
+definition they will be able to execute privileged Docker commands on the Runner
host. Having proper access control policies mitigates this attack vector by
allowing access only to trusted actors.
@@ -129,9 +128,8 @@ allowing access only to trusted actors.
CAUTION: **Caution:**
Before GitLab 11.5, Code Quality job and artifact had to be named specifically to
automatically extract report data and show it in the merge request widget. While these
-old job definitions are still maintained they have been deprecated and may be removed
-in the next major release, GitLab 12.0. You are advised to update your current `.gitlab-ci.yml`
-configuration to reflect that change.
+old job definitions are still maintained they have been deprecated and are no longer supported on GitLab 12.0 or higher.
+You're advised to update your `.gitlab-ci.yml` configuration to reflect that change.
For GitLab 11.5 and later, the job should look like:
@@ -157,7 +155,7 @@ code_quality:
In GitLab 12.6, Code Quality switched to the
[new versioning scheme](https://gitlab.com/gitlab-org/ci-cd/codequality#versioning-and-release-cycle).
-It is highly recommended to include the Code Quality template as shown in the
+It's highly recommended to include the Code Quality template as shown in the
[example configuration](#example-configuration), which uses the new versioning scheme.
If not using the template, the `SP_VERSION` variable can be hardcoded to use the
new image versions:
@@ -241,7 +239,7 @@ do this:
[Code Quality report
artifact](../../../ci/pipelines/job_artifacts.md#artifactsreportscodequality-starter).
1. Configure your tool to generate the Code Quality report artifact as a JSON
- file that implements subset of the [Code Climate
+ file that implements a subset of the [Code Climate
spec](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#data-types).
The Code Quality report artifact JSON file must contain an array of objects
@@ -288,28 +286,28 @@ Once the Code Quality job has completed:
[downloadable artifact](../../../ci/pipelines/job_artifacts.md#downloading-artifacts)
for the `code_quality` job.
-If multiple jobs in a pipeline generate a code quality artifact, only the artifact from
-the last created job (the job with the largest job ID) is used. To avoid confusion,
-configure only one job to generate a code quality artifact.
+## Troubleshooting
-If the Code Quality report doesn't have anything to compare to, no information
-will be displayed in the merge request area. That is the case when you add the
-Code Quality job in your `.gitlab-ci.yml` for the very first time.
-Consecutive merge requests will have something to compare to and the Code Quality
-report will be shown properly.
+### No Code Quality report is displayed in a Merge Request
-These reports will only be available as long as the Code Quality artifact(s) required to generate
-them are also available. See
-[`artifacts:expire_in`](../../../ci/yaml/README.md#artifactsexpire_in) for more details.
+This can be due to multiple reasons:
-<!-- ## Troubleshooting
+- You just added the Code Quality job in your `.gitlab-ci.yml`. The report does not
+ have anything to compare to yet, so no information can be displayed. Future merge
+ requests will have something to compare to.
+- If no [degradation or error is detected](https://docs.codeclimate.com/docs/maintainability#section-checks),
+ nothing will be displayed.
+- The [`artifacts:expire_in`](../../../ci/yaml/README.md#artifactsexpire_in) CI/CD
+ setting can cause the Code Quality artifact(s) to expire faster than desired.
+- Large `codeclimate.json` files (esp. >10 MB) are [known to prevent the report from being displayed](https://gitlab.com/gitlab-org/gitlab/-/issues/2737).
+ As a work-around, try removing [properties](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#data-types)
+ that are [ignored by GitLab](#implementing-a-custom-tool). You can:
+ - Configure the Code Quality tool to not output those types.
+ - Use `sed`, `awk` or similar commands in the `.gitlab-ci.yml` script to
+ edit the `codeclimate.json` before the job completes.
-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.
+### Only a single Code Quality report is displayed, but more are defined
-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. -->
+GitLab only uses the Code Quality artifact from the latest created job (with the largest job ID).
+If multiple jobs in a pipeline generate a code quality artifact, those of earlier jobs are ignored.
+To avoid confusion, configure only one job to generate a `codeclimate.json`.
diff --git a/doc/user/project/merge_requests/creating_merge_requests.md b/doc/user/project/merge_requests/creating_merge_requests.md
index 544727380e7..50d5decc2cc 100644
--- a/doc/user/project/merge_requests/creating_merge_requests.md
+++ b/doc/user/project/merge_requests/creating_merge_requests.md
@@ -12,8 +12,8 @@ to familiarize yourself with the concept, the terminology,
and to learn what you can do with them.
Every merge request starts by creating a branch. You can either
-do it locally through the command line, via a Git CLI application,
-or through the GitLab UI.
+do it locally through the [command line](#new-merge-request-from-your-local-environment), via a Git CLI application,
+or through the [GitLab UI](#new-merge-request-from-a-new-branch-created-through-the-ui).
This document describes the several ways to create a merge request.
@@ -100,7 +100,7 @@ button to open the [**New Merge Request** page](#new-merge-request-page).
A new merge request will be started using the current branch as the source,
and the default branch in the current project as the target.
-## New merge request from you local environment
+## New merge request from your local environment
Assuming you have your repository cloned into your computer and you'd
like to start working on changes to files, start by creating and
diff --git a/doc/user/project/merge_requests/getting_started.md b/doc/user/project/merge_requests/getting_started.md
index 0ab8d31403e..32eb0c73ed4 100644
--- a/doc/user/project/merge_requests/getting_started.md
+++ b/doc/user/project/merge_requests/getting_started.md
@@ -67,7 +67,7 @@ Once you have created the merge request, you can also:
- Preview continuous integration [pipelines on the merge request widget](reviewing_and_managing_merge_requests.md#pipeline-status-in-merge-requests-widgets).
- Preview how your changes look directly on your deployed application with [Review Apps](reviewing_and_managing_merge_requests.md#live-preview-with-review-apps).
- [Allow collaboration on merge requests across forks](allow_collaboration.md).
-- Perform a [Review](../../discussions/index.md#merge-request-reviews-premium) in order to create multiple comments on a diff and publish them once you're ready. **(PREMIUM)**
+- Perform a [Review](../../discussions/index.md#merge-request-reviews) in order to create multiple comments on a diff and publish them once you're ready.
- Add [code suggestions](../../discussions/index.md#suggest-changes) to change the content of merge requests directly into merge request threads, and easily apply them to the codebase directly from the UI.
- Add a time estimation and the time spent with that merge request with [Time Tracking](../time_tracking.md#time-tracking).
@@ -86,7 +86,7 @@ and the merge request will be added to their
#### Multiple assignees **(STARTER)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/2004) in [GitLab Starter 11.11](https://about.gitlab.com/pricing/).
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2004) in [GitLab Starter 11.11](https://about.gitlab.com/pricing/).
Multiple people often review merge requests at the same time.
GitLab allows you to have multiple assignees for merge requests
diff --git a/doc/user/project/merge_requests/index.md b/doc/user/project/merge_requests/index.md
index 2038414dab8..5d2813f5bfc 100644
--- a/doc/user/project/merge_requests/index.md
+++ b/doc/user/project/merge_requests/index.md
@@ -54,7 +54,7 @@ To get started, read the [introduction to merge requests](getting_started.md).
## Merge request navigation tabs at the top
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/33813) in GitLab 12.6. This positioning is experimental.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/33813) in GitLab 12.6. This positioning is experimental.
So far, the navigation tabs present in merge requests to display **Discussion**,
**Commits**, **Pipelines**, and **Changes** were located after the merge request
@@ -86,35 +86,7 @@ See the features at your disposal to [review and manage merge requests](reviewin
## Testing and reports in merge requests
-GitLab has the ability to test the changes included in a merge request, and can display
-or link to useful information directly in the merge request page:
-
-| Feature | Description |
-|--------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| [Accessibility Testing](accessibility_testing.md) | Automatically report A11y violations for changed pages in merge requests |
-| [Browser Performance Testing](browser_performance_testing.md) **(PREMIUM)** | Quickly determine the performance impact of pending code changes. |
-| [Code Quality](code_quality.md) **(STARTER)** | Analyze your source code quality using the [Code Climate](https://codeclimate.com/) analyzer and show the Code Climate report right in the merge request widget area. |
-| [Display arbitrary job artifacts](../../../ci/yaml/README.md#artifactsexpose_as) | Configure CI pipelines with the `artifacts:expose_as` parameter to directly link to selected [artifacts](../../../ci/pipelines/job_artifacts.md) in merge requests. |
-| [GitLab CI/CD](../../../ci/README.md) | Build, test, and deploy your code in a per-branch basis with built-in CI/CD. |
-| [JUnit test reports](../../../ci/junit_test_reports.md) | Configure your CI jobs to use JUnit test reports, and let GitLab display a report on the merge request so that it’s easier and faster to identify the failure without having to check the entire job log. |
-| [License Compliance](../../compliance/license_compliance/index.md) **(ULTIMATE)** | Manage the licenses of your dependencies. |
-| [Metrics Reports](../../../ci/metrics_reports.md) **(PREMIUM)** | Display the Metrics Report on the merge request so that it's fast and easy to identify changes to important metrics. |
-| [Multi-Project pipelines](../../../ci/multi_project_pipelines.md) **(PREMIUM)** | When you set up GitLab CI/CD across multiple projects, you can visualize the entire pipeline, including all cross-project interdependencies. |
-| [Pipelines for merge requests](../../../ci/merge_request_pipelines/index.md) | Customize a specific pipeline structure for merge requests in order to speed the cycle up by running only important jobs. |
-| [Pipeline Graphs](../../../ci/pipelines/index.md#visualize-pipelines) | View the status of pipelines within the merge request, including the deployment process. |
-| [Test Coverage visualization](test_coverage_visualization.md) | See test coverage results for merge requests, within the file diff. |
-
-### Security Reports **(ULTIMATE)**
-
-In addition to the reports listed above, GitLab can do many types of [Security reports](../../application_security/index.md),
-generated by scanning and reporting any vulnerabilities found in your project:
-
-| Feature | Description |
-|-----------------------------------------------------------------------------------------|------------------------------------------------------------------|
-| [Container Scanning](../../application_security/container_scanning/index.md) | Analyze your Docker images for known vulnerabilities. |
-| [Dynamic Application Security Testing (DAST)](../../application_security/dast/index.md) | Analyze your running web applications for known vulnerabilities. |
-| [Dependency Scanning](../../application_security/dependency_scanning/index.md) | Analyze your dependencies for known vulnerabilities. |
-| [Static Application Security Testing (SAST)](../../application_security/sast/index.md) | Analyze your source code for known vulnerabilities. |
+Learn about the options for [testing and reports](testing_and_reports_in_merge_requests.md) on the changes in a merge request.
## Authorization for merge requests
diff --git a/doc/user/project/merge_requests/merge_request_approvals.md b/doc/user/project/merge_requests/merge_request_approvals.md
index e5896e62397..dd90449cd86 100644
--- a/doc/user/project/merge_requests/merge_request_approvals.md
+++ b/doc/user/project/merge_requests/merge_request_approvals.md
@@ -34,10 +34,12 @@ minimum number of required approvers can still be set in the [project settings f
### Eligible approvers
-The following can approve merge requests:
+The following users can approve merge requests:
-- Users being added as approvers at project or merge request level.
-- [Code owners](#code-owners-as-eligible-approvers) to the files changed by the merge request.
+- Users who have been added as approvers at the project or merge request levels with
+ developer or higher [permissions](../../permissions.md).
+- [Code owners](#code-owners-as-eligible-approvers) of the files changed by the merge request
+ that have developer or higher [permissions](../../permissions.md).
An individual user can be added as an approver for a project if they are a member of:
@@ -46,7 +48,7 @@ An individual user can be added as an approver for a project if they are a membe
- A group that has access to the project via a [share](../members/share_project_with_groups.md).
A group of users can also be added as approvers. In the future, group approvers may be
-[restricted to only groups with share access to the project](https://gitlab.com/gitlab-org/gitlab/issues/2048).
+[restricted to only groups with share access to the project](https://gitlab.com/gitlab-org/gitlab/-/issues/2048).
If a user is added as an individual approver and is also part of a group approver,
then that user is just counted once. The merge request author, as well as users who have committed
@@ -68,7 +70,7 @@ were not explicitly listed in the approval rules.
If you add [Code Owners](../code_owners.md) to your repository, the owners to the
corresponding files will become eligible approvers, together with members with Developer
-or higher permissions.
+or higher [permissions](../../permissions.md).
To enable this merge request approval rule:
@@ -127,7 +129,7 @@ the same steps as [Adding / editing a default approval rule](#adding--editing-a-
### Multiple approval rules **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/1979) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.10.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/1979) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.10.
In GitLab Premium, it is possible to have multiple approval rules per merge request,
as well as multiple default approval rules per project.
@@ -149,7 +151,7 @@ reduce the number of approvals left for all rules that the approver belongs to.
### Scoped to Protected Branch **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/460) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/460) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.8.
Approval rules are often only relevant to specific branches, like `master`.
When configuring [**Default Approval Rules**](#adding--editing-a-default-approval-rule)
@@ -222,7 +224,7 @@ from the UI. However, approvals will be reset if the target branch is changed.
### Allowing merge request authors to approve their own merge requests
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/3349) in [GitLab Starter](https://about.gitlab.com/pricing/) 11.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3349) in [GitLab Starter](https://about.gitlab.com/pricing/) 11.3.
You can allow merge request authors to self-approve merge requests. Authors
also need to be included in the approvers list in order to be able to
@@ -234,7 +236,7 @@ approve their merge request. To enable this feature:
### Prevent approval of merge requests by their committers
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/10441) in [GitLab Starter](https://about.gitlab.com/pricing/) 11.10.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10441) in [GitLab Starter](https://about.gitlab.com/pricing/) 11.10.
You can prevent users that have committed to a merge request from approving it. To
enable this feature:
@@ -244,7 +246,12 @@ enable this feature:
### Require authentication when approving a merge request
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/5981) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.0.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5981) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.0.
+
+NOTE: **Note:**
+To require authentication when approving a merge request, you must enable
+**Password authentication enabled for web interface** under [sign-in restrictions](../../admin_area/settings/sign_in_restrictions.md#password-authentication-enabled).
+in the Admin area.
You can force the approver to enter a password in order to authenticate before adding
the approval. This enables an Electronic Signature for approvals such as the one defined
@@ -264,7 +271,7 @@ For more information, see
## Enabling the new approvals interface
-Since [GitLab v12.0](https://gitlab.com/gitlab-org/gitlab/issues/10685), an updated approvals
+Since [GitLab v12.0](https://gitlab.com/gitlab-org/gitlab/-/issues/10685), an updated approvals
interface is available by default. In versions older than 12.0, the updated interface is not
available unless the `approval_rules` feature flag is enabled, which can be done from
the Rails console by instance administrators.
diff --git a/doc/user/project/merge_requests/merge_request_dependencies.md b/doc/user/project/merge_requests/merge_request_dependencies.md
index 66a1d2ac6af..a1012e27d32 100644
--- a/doc/user/project/merge_requests/merge_request_dependencies.md
+++ b/doc/user/project/merge_requests/merge_request_dependencies.md
@@ -4,7 +4,7 @@ type: reference, concepts
# Merge Request dependencies **(PREMIUM)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/9688) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.2.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9688) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.2.
> - [Renamed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17291) from "Cross-project dependencies" to "Merge Requests dependencies" in [GitLab Premium](https://about.gitlab.com/pricing/) 12.4.
> - Intra-project MR dependencies were [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/16799) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.4.
@@ -94,9 +94,9 @@ merge.
## Limitations
-- API support: [issue #12551](https://gitlab.com/gitlab-org/gitlab/issues/12551)
-- Dependencies are not preserved across project export/import: [issue #12549](https://gitlab.com/gitlab-org/gitlab/issues/12549)
-- Complex merge order dependencies are not supported: [issue #11393](https://gitlab.com/gitlab-org/gitlab/issues/11393)
+- API support: [issue #12551](https://gitlab.com/gitlab-org/gitlab/-/issues/12551)
+- Dependencies are not preserved across project export/import: [issue #12549](https://gitlab.com/gitlab-org/gitlab/-/issues/12549)
+- Complex merge order dependencies are not supported: [issue #11393](https://gitlab.com/gitlab-org/gitlab/-/issues/11393)
The last item merits a little more explanation. Dependencies between merge
requests can be described as a graph of relationships. The simplest possible
diff --git a/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md b/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md
index 50412e0b319..d45ccdc9be9 100644
--- a/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md
+++ b/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md
@@ -59,11 +59,24 @@ merge request from the UI, until you make all relevant jobs pass.
![Only allow merge if pipeline succeeds message](img/merge_when_pipeline_succeeds_only_if_succeeds_msg.png)
+### Skipped pipelines
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/211482) in GitLab 13.1.
+
+When the **Pipelines must succeed** checkbox is checked, [skipped pipelines](../../../ci/yaml/README.md#skip-pipeline) prevent
+merge requests from being merged. To change this behavior:
+
+1. Navigate to your project's **Settings > General** page.
+1. Expand the **Merge requests** section.
+1. In the **Merge checks** subsection, ensure **Pipelines must succeed** is checked.
+1. In the **Merge checks** subsection, select the **Skipped pipelines are considered successful** checkbox.
+1. Press **Save** for the changes to take effect.
+
### Limitations
When this setting is enabled, a merge request is prevented from being merged if there is no pipeline. This may conflict with some use cases where [`only/except`](../../../ci/yaml/README.md#onlyexcept-advanced) rules are used and they don't generate any pipelines.
-Users that expect to be able to merge a merge request in this scenario should ensure that [there is always a pipeline](https://gitlab.com/gitlab-org/gitlab-foss/issues/54226) and that it's successful.
+Users that expect to be able to merge a merge request in this scenario should ensure that [there is always a pipeline](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/54226) and that it's successful.
For example, to that on merge requests there is always a passing job even though `only/except` rules may not generate any other jobs:
diff --git a/doc/user/project/merge_requests/reviewing_and_managing_merge_requests.md b/doc/user/project/merge_requests/reviewing_and_managing_merge_requests.md
index fdcb1049ef7..a3ad41d8dd8 100644
--- a/doc/user/project/merge_requests/reviewing_and_managing_merge_requests.md
+++ b/doc/user/project/merge_requests/reviewing_and_managing_merge_requests.md
@@ -82,6 +82,10 @@ to expand the entire file.
![Incrementally expand merge request diffs](img/incrementally_expand_merge_request_diffs_v12_2.png)
+[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/205401) in GitLab 13.1, when viewing a
+merge request's **Changes** tab, if a certain file was only renamed, you can expand it to see the
+entire content by clicking **Show file contents**.
+
### Ignore whitespace changes in Merge Request diff view
If you click the **Hide whitespace changes** button, you can see the diff
@@ -96,7 +100,7 @@ whitespace changes.
## Perform inline code reviews
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/13950) in GitLab 11.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/13950) in GitLab 11.5.
GitLab provides a way of leaving comments in any part of the file being changed
in a Merge Request. To do so, click the **...** button in the gutter of the Merge Request diff UI to expand the diff lines and leave a comment, just as you would for a changed line.
@@ -108,7 +112,7 @@ in a Merge Request. To do so, click the **...** button in the gutter of the Merg
If you've set up [GitLab CI/CD](../../../ci/README.md) in your project,
you will be able to see:
-- Both pre and post-merge pipelines and the environment information if any.
+- Both pre-merge and post-merge pipelines and the environment information if any.
- Which deployments are in progress.
If there's an [environment](../../../ci/environments/index.md) and the application is
diff --git a/doc/user/project/merge_requests/test_coverage_visualization.md b/doc/user/project/merge_requests/test_coverage_visualization.md
index 84d60fca72d..1c0e698aba5 100644
--- a/doc/user/project/merge_requests/test_coverage_visualization.md
+++ b/doc/user/project/merge_requests/test_coverage_visualization.md
@@ -4,7 +4,7 @@ type: reference, howto
# Test Coverage Visualization
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/3708) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3708) in GitLab 12.9.
With the help of [GitLab CI/CD](../../../ci/README.md), you can collect the test
coverage information of your favorite testing or coverage-analysis tool, and visualize
@@ -67,7 +67,7 @@ test:
This feature comes with the `:coverage_report_view` feature flag disabled by
default. This feature is disabled due to some performance issues with very large
-data sets. When [the performance issue](https://gitlab.com/gitlab-org/gitlab/issues/211410)
+data sets. When [the performance issue](https://gitlab.com/gitlab-org/gitlab/-/issues/211410)
is resolved, the feature will be enabled by default.
To enable this feature, ask a GitLab administrator with Rails console access to
diff --git a/doc/user/project/merge_requests/testing_and_reports_in_merge_requests.md b/doc/user/project/merge_requests/testing_and_reports_in_merge_requests.md
new file mode 100644
index 00000000000..f7614ed7996
--- /dev/null
+++ b/doc/user/project/merge_requests/testing_and_reports_in_merge_requests.md
@@ -0,0 +1,36 @@
+---
+type: index
+description: "Test your code and display reports in merge requests"
+---
+
+# Tests and reports in merge requests
+
+GitLab has the ability to test the changes included in a feature branch and display reports
+or link to useful information directly from merge requests:
+
+| Feature | Description |
+|--------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| [Accessibility Testing](accessibility_testing.md) | Automatically report A11y violations for changed pages in merge requests. |
+| [Browser Performance Testing](browser_performance_testing.md) **(PREMIUM)** | Quickly determine the performance impact of pending code changes. |
+| [Code Quality](code_quality.md) **(STARTER)** | Analyze your source code quality using the [Code Climate](https://codeclimate.com/) analyzer and show the Code Climate report right in the merge request widget area. |
+| [Display arbitrary job artifacts](../../../ci/yaml/README.md#artifactsexpose_as) | Configure CI pipelines with the `artifacts:expose_as` parameter to directly link to selected [artifacts](../../../ci/pipelines/job_artifacts.md) in merge requests. |
+| [GitLab CI/CD](../../../ci/README.md) | Build, test, and deploy your code in a per-branch basis with built-in CI/CD. |
+| [JUnit test reports](../../../ci/junit_test_reports.md) | Configure your CI jobs to use JUnit test reports, and let GitLab display a report on the merge request so that it’s easier and faster to identify the failure without having to check the entire job log. |
+| [License Compliance](../../compliance/license_compliance/index.md) **(ULTIMATE)** | Manage the licenses of your dependencies. |
+| [Metrics Reports](../../../ci/metrics_reports.md) **(PREMIUM)** | Display the Metrics Report on the merge request so that it's fast and easy to identify changes to important metrics. |
+| [Multi-Project pipelines](../../../ci/multi_project_pipelines.md) **(PREMIUM)** | When you set up GitLab CI/CD across multiple projects, you can visualize the entire pipeline, including all cross-project interdependencies. |
+| [Pipelines for merge requests](../../../ci/merge_request_pipelines/index.md) | Customize a specific pipeline structure for merge requests in order to speed the cycle up by running only important jobs. |
+| [Pipeline Graphs](../../../ci/pipelines/index.md#visualize-pipelines) | View the status of pipelines within the merge request, including the deployment process. |
+| [Test Coverage visualization](test_coverage_visualization.md) | See test coverage results for merge requests, within the file diff. |
+
+## Security Reports **(ULTIMATE)**
+
+In addition to the reports listed above, GitLab can do many types of [Security reports](../../application_security/index.md),
+generated by scanning and reporting any vulnerabilities found in your project:
+
+| Feature | Description |
+|-----------------------------------------------------------------------------------------|------------------------------------------------------------------|
+| [Container Scanning](../../application_security/container_scanning/index.md) | Analyze your Docker images for known vulnerabilities. |
+| [Dynamic Application Security Testing (DAST)](../../application_security/dast/index.md) | Analyze your running web applications for known vulnerabilities. |
+| [Dependency Scanning](../../application_security/dependency_scanning/index.md) | Analyze your dependencies for known vulnerabilities. |
+| [Static Application Security Testing (SAST)](../../application_security/sast/index.md) | Analyze your source code for known vulnerabilities. |
diff --git a/doc/user/project/merge_requests/versions.md b/doc/user/project/merge_requests/versions.md
index 84934148bdc..9581c974414 100644
--- a/doc/user/project/merge_requests/versions.md
+++ b/doc/user/project/merge_requests/versions.md
@@ -37,7 +37,7 @@ changes appears as a system note.
## Find the merge request that introduced a change
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/2383) in GitLab 10.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/2383) in GitLab 10.5.
When viewing the commit details page, GitLab will link to the merge request (or
merge requests, if it's in more than one) containing that commit.
@@ -48,7 +48,7 @@ request, they will not be linked.
## `HEAD` comparison mode for Merge Requests
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/27008) in GitLab 12.10.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27008) in GitLab 12.10.
Merge Requests, particularly the **Changes** tab, is where source code
is reviewed and discussed. In circumstances where the target branch was
@@ -62,7 +62,7 @@ shows a diff calculated by simulating how it would look like once merged - a mor
representation of the changes rather than using the base of the two
branches. The new mode is available from the comparison target drop down
by selecting **master (HEAD)**. In the future it will
-[replace](https://gitlab.com/gitlab-org/gitlab/issues/198458) the
+[replace](https://gitlab.com/gitlab-org/gitlab/-/issues/198458) the
current default comparison.
![Merge request versions compare HEAD](img/versions_compare_head_v12_10.png)
diff --git a/doc/user/project/milestones/burndown_charts.md b/doc/user/project/milestones/burndown_charts.md
index e9f23899068..e28ba1d2d5f 100644
--- a/doc/user/project/milestones/burndown_charts.md
+++ b/doc/user/project/milestones/burndown_charts.md
@@ -1,5 +1,8 @@
---
type: reference
+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/#designated-technical-writers
---
# Burndown Charts **(STARTER)**
diff --git a/doc/user/project/milestones/index.md b/doc/user/project/milestones/index.md
index 085c1bd143e..421cb42de1e 100644
--- a/doc/user/project/milestones/index.md
+++ b/doc/user/project/milestones/index.md
@@ -1,5 +1,8 @@
---
type: index, reference
+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/#designated-technical-writers
---
# Milestones
diff --git a/doc/user/project/new_ci_build_permissions_model.md b/doc/user/project/new_ci_build_permissions_model.md
index 120c7a35cb2..cfcbf11a407 100644
--- a/doc/user/project/new_ci_build_permissions_model.md
+++ b/doc/user/project/new_ci_build_permissions_model.md
@@ -1,10 +1,17 @@
+---
+stage: Verify
+group: Continuous Integration
+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
+---
+
# New CI job permissions model
> Introduced in GitLab 8.12.
GitLab 8.12 has a completely redesigned [job permissions](../permissions.md#job-permissions) system. You can find
all discussion and all our concerns when choosing the current approach in issue
-[#18994](https://gitlab.com/gitlab-org/gitlab-foss/issues/18994).
+[#18994](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/18994).
Jobs permissions should be tightly integrated with the permissions of a user
who is triggering a job.
@@ -68,7 +75,7 @@ Let's consider the following scenario:
A unique job token is generated for each job and provides the user read
access all projects that would be normally accessible to the user creating that
job. The unique job token does not have any write permissions, but there
-is a [proposal to add support](https://gitlab.com/gitlab-org/gitlab/issues/35067).
+is a [proposal to add support](https://gitlab.com/gitlab-org/gitlab/-/issues/35067).
We try to make sure that this token doesn't leak by:
@@ -156,7 +163,7 @@ As an administrator:
[check manually](https://gitlab.com/gitlab-org/gitlab-foss/tree/master/doc/update) for installations from source.
- **500 errors**: Check if you have another web proxy sitting in front of NGINX (HAProxy,
Apache, etc.). It might be a good idea to let GitLab use the internal NGINX
- web server and not disable it completely. See [this comment](https://gitlab.com/gitlab-org/gitlab-foss/issues/22484#note_16648302) for an
+ web server and not disable it completely. See [this comment](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/22484#note_16648302) for an
example.
- **403 errors**: You need to make sure that your installation has [HTTP(S)
cloning enabled](../admin_area/settings/visibility_and_access_controls.md#enabled-git-access-protocols). HTTP(S) support is now a **requirement** by GitLab CI
@@ -178,7 +185,7 @@ git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/<user>/<mydependent
```
It can also be used for system-wide authentication
-(only do this in a docker container, it will overwrite ~/.netrc):
+(only do this in a Docker container, it will overwrite ~/.netrc):
```shell
echo -e "machine gitlab.com\nlogin gitlab-ci-token\npassword ${CI_JOB_TOKEN}" > ~/.netrc
diff --git a/doc/user/project/operations/alert_management.md b/doc/user/project/operations/alert_management.md
index 2dcf72aaf01..411b36411af 100644
--- a/doc/user/project/operations/alert_management.md
+++ b/doc/user/project/operations/alert_management.md
@@ -1,3 +1,9 @@
+---
+stage: Monitor
+group: Health
+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
+---
+
# Alert Management
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2877) in GitLab 13.0.
@@ -32,12 +38,14 @@ immediately identify which alerts you should prioritize investigating:
Alerts contain one of the following icons:
-- **Critical**: **{severity-critical}** and hexadecimal color `#8b2615`
-- **High**: **{severity-high}** and hexadecimal color `#c0341d`
-- **Medium**: **{severity-medium}** and hexadecimal color `#fca429`
-- **Low**: **{severity-low}** and hexadecimal color `#fdbc60`
-- **Info**: **{severity-info}** and hexadecimal color `#418cd8`
-- **Unknown**: **{severity-unknown}** and hexadecimal color `#bababa`
+| Severity | Icon | Color (hexadecimal) |
+|---|---|---|
+| Critical | **{severity-critical}** | `#8b2615` |
+| High | **{severity-high}** | `#c0341d` |
+| Medium | **{severity-medium}** | `#fca429` |
+| Low | **{severity-low}** | `#fdbc60` |
+| Info | **{severity-info}** | `#418cd8` |
+| Unknown | **{severity-unknown}** | `#bababa` |
## Alert Management list
@@ -72,8 +80,91 @@ You will need at least Developer [permissions](../../permissions.md) to view Ale
Navigate to the Alert Management detail view by visiting the [Alert Management list](#alert-management-list) and selecting an Alert from the list.
-![Alert Management Detail View](img/alert_detail_v13_0.png)
+![Alert Management Detail Overview](img/alert_detail_overview_v13_1.png)
+
+![Alert Management Full Details](img/alert_detail_full_v13_1.png)
### Update an Alert's status
-The Alert Management detail view allows users to update the Alert Status. See [Alert Management statuses](#alert-management-statuses) for more details.
+The Alert Management detail view enables you to update the Alert Status.
+See [Alert Management statuses](#alert-management-statuses) for more details.
+
+### Create an Issue from an Alert
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217745) in GitLab 13.1.
+
+The Alert Management detail view enables you to create an issue with a
+description automatically populated from an alert. To create the issue,
+click the **Create Issue** button. You can then view the issue from the
+alert by clicking the **View Issue** button.
+
+Closing a GitLab issue associated with an alert changes the alert's status to Resolved.
+See [Alert Management statuses](#alert-management-statuses) for more details about statuses.
+
+### Update an Alert's assignee
+
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3066) in GitLab 13.1.
+
+The Alert Management detail view allows users to update the Alert assignee.
+
+In large teams, where there is shared ownership of an alert, it can be difficult
+to track who is investigating and working on it. The Alert Management detail view
+enables you to update the Alert assignee:
+
+NOTE: **Note:**
+GitLab currently only supports a single assignee per alert.
+
+1. To display the list of current alerts, click
+ **{cloud-gear}** **Operations > Alerts**:
+
+ ![Alert Management List View Assignee(s)](img/alert_list_assignees_v13_1.png)
+
+1. Select your desired alert to display its **Alert Management Details View**:
+
+ ![Alert Management Details View Assignee(s)](img/alert_details_assignees_v13_1.png)
+
+1. If the right sidebar is not expanded, click
+ **{angle-double-right}** **Expand sidebar** to expand it.
+1. In the right sidebar, locate the **Assignee** and click **Edit**. From the
+ dropdown menu, select each user you want to assign to the alert. GitLab creates
+ a [To-Do list item](../../todos.md) for each user.
+
+ ![Alert Management Details View Assignee(s)](img/alert_todo_assignees_v13_1.png)
+
+To remove an assignee, click **Edit** next to the **Assignee** dropdown menu and
+deselect the user from the list of assignees, or click **Unassigned**.
+
+### Alert system notes
+
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3066) in GitLab 13.1.
+
+NOTE: **Note:**
+GitLab currently only supports creating system notes when assigning an Alert.
+
+Assigning a user an Alert creates a system note, visible in the Alert Details view,
+giving you a linear timeline of the alert's investigation and assignment history.
+
+![Alert Management Details View System Notes](img/alert_detail_system_notes_v13_1.png)
+
+## Use cases for assigning alerts
+
+Consider a team formed by different sections of monitoring, collaborating on a
+single application. After an alert surfaces, it's extremely important to
+route the alert to the team members who can address and resolve the alert.
+
+Assigning Alerts to multiple assignees eases collaboration and delegation. All
+assignees are shown in your team's work-flows, and all assignees receive
+notifications, simplifying communication and ownership of the alert.
+
+After completing their portion of investigating or fixing the alert, users can
+unassign their account from the alert when their role is complete.
+The [alerts status](#alert-management-statuses) can be updated to
+reflect if the alert has been resolved.
+
+### Slack Notifications
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216326) in GitLab 13.1.
+
+You can be alerted via a Slack message when a new alert has been received.
+
+See the [Slack Notifications Service docs](../integrations/slack.md) for information on how to set this up.
diff --git a/doc/user/project/operations/dashboard_settings.md b/doc/user/project/operations/dashboard_settings.md
new file mode 100644
index 00000000000..e14c478ab7a
--- /dev/null
+++ b/doc/user/project/operations/dashboard_settings.md
@@ -0,0 +1,47 @@
+---
+stage: Monitor
+group: APM
+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
+---
+
+# Metrics dashboard settings
+
+You can configure your [Monitoring dashboard](../integrations/prometheus.md) to
+display the time zone of your choice, and the links of your choice.
+
+## Change the dashboard time zone
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214370) in GitLab 13.1.
+
+By default, your monitoring dashboard displays dates and times in your local
+time zone, but you can display dates and times in UTC format. To change the
+time zone:
+
+1. Navigate to **{settings}** **Settings > Operations**, and scroll to
+ **Metrics Dashboard**.
+1. In the **Dashboard timezone** select box, select *User's local timezone*
+ or *UTC*:
+
+ ![Dashboard timezone setting](img/dashboard_local_timezone_v13_1.png)
+1. Click **Save changes**.
+
+## Link to an external dashboard
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/57171) in GitLab 12.0.
+
+You can add a button on your monitoring dashboard that links directly to your
+existing external dashboards:
+
+1. Navigate to **{settings}** **Settings > Operations**, and scroll to
+ **Metrics Dashboard**.
+1. In **External dashboard URL**, provide the URL to your external dashboard:
+
+ ![External Dashboard Setting](img/dashboard_external_link_v13_1.png)
+
+1. Click **Save changes**.
+
+GitLab displays a **View full dashboard** button in the top right corner of your
+[monitoring dashboard](../../../ci/environments/index.md#monitoring-environments)
+which opens the URL you provided:
+
+![External Dashboard Link](img/external_dashboard_link.png)
diff --git a/doc/user/project/operations/error_tracking.md b/doc/user/project/operations/error_tracking.md
index 23a50fd7766..a7a16de90e0 100644
--- a/doc/user/project/operations/error_tracking.md
+++ b/doc/user/project/operations/error_tracking.md
@@ -61,7 +61,7 @@ This page has:
- A link to the Sentry issue.
- A link to the GitLab commit if the Sentry [release ID/version](https://docs.sentry.io/workflow/releases/?platform=javascript#configure-sdk) on the Sentry Issue's first release matches a commit SHA in your GitLab hosted project.
- Other details about the issue, including a full stack trace.
-- In [GitLab 12.7 and newer](https://gitlab.com/gitlab-org/gitlab/issues/36246), language and urgency are displayed.
+- In [GitLab 12.7 and newer](https://gitlab.com/gitlab-org/gitlab/-/issues/36246), language and urgency are displayed.
By default, a **Create issue** button is displayed:
@@ -77,7 +77,7 @@ You can take action on Sentry Errors from within the GitLab UI.
### Ignoring errors
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/39665) in GitLab 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/39665) in GitLab 12.7.
From within the [Error Details](#error-details) page you can ignore a Sentry error by simply clicking the **Ignore** button near the top of the page.
@@ -85,7 +85,7 @@ Ignoring an error will prevent it from appearing in the [Error Tracking List](#e
### Resolving errors
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/39825) in GitLab 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/39825) in GitLab 12.7.
From within the [Error Details](#error-details) page you can resolve a Sentry error by
clicking the **Resolve** button near the top of the page.
diff --git a/doc/user/project/operations/feature_flags.md b/doc/user/project/operations/feature_flags.md
index 8716d5feb4a..a9729204cd7 100644
--- a/doc/user/project/operations/feature_flags.md
+++ b/doc/user/project/operations/feature_flags.md
@@ -8,100 +8,73 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/7433) in GitLab 11.4.
-Feature flags allow you to ship a project in different flavors by
-dynamically toggling certain functionality.
+With Feature Flags, you can deploy your application's new features to production in smaller batches.
+You can toggle a feature on and off to subsets of users, helping you achieve Continuous Delivery.
+Feature flags help reduce risk, allowing you to do controlled testing, and separate feature
+delivery from customer launch.
-## Overview
-
-Feature Flags offer a feature toggle system for your application. They enable teams
-to achieve Continuous Delivery by deploying new features to production at smaller
-batches for controlled testing, separating feature delivery from customer launch.
-This helps reducing risk and allows you to easily manage which features to enable.
-
-GitLab offers a Feature Flags interface that allows you to create, toggle and
-remove feature flags.
-
-<div class="video-fallback">
- <a href="https://www.youtube.com/watch?v=5tw2p6lwXxo">Watch</a> a use case between Feature Flags and Sentry Error Tracking
-</div>
-<figure class="video-container">
- <iframe src="https://www.youtube.com/embed/5tw2p6lwXxo" frameborder="0" allowfullscreen="true"> </iframe>
-</figure>
+<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
+For an example of feature flags in action, see [GitLab for Deploys, Feature Flags, and Error Tracking](https://www.youtube.com/embed/5tw2p6lwXxo).
## How it works
-Underneath, GitLab uses [unleash](https://github.com/Unleash/unleash), a feature
-toggle service. GitLab provides an API where your application can talk to and get the
-list of feature flags you set in GitLab.
+GitLab uses [Unleash](https://github.com/Unleash/unleash), a feature
+toggle service.
-The application must be configured to talk to GitLab, so that's up to the
-developers to use a compatible [client library](#client-libraries) and
-integrate it in their app.
+By enabling or disabling a flag in GitLab, your application
+can determine which features to enable or disable.
-By setting a flag active or inactive via GitLab, your application will automatically
-know which features to enable or disable respectively.
+You can create feature flags in GitLab and use the API from your application
+to get the list of feature flags and their statuses. The application must be configured to communicate
+with GitLab, so it's up to developers to use a compatible client library and
+[integrate the feature flags in your app](#integrate-feature-flags-with-your-application).
-## Adding a new feature flag
+## Create a feature flag
-To add a new feature flag:
+To create and enable a feature flag:
1. Navigate to your project's **Operations > Feature Flags**.
-1. Click on the **New Feature Flag** button.
-1. Give it a name.
-
- NOTE: **Note:**
- A name can contain only lowercase letters, digits, underscores (`_`)
- and dashes (`-`), must start with a letter, and cannot end with a dash (`-`)
- or an underscore (`_`).
-
-1. Give it a description (optional, 255 characters max).
-1. Define environment [specs](#define-environment-specs). If you want the flag on by default, enable the catch-all [wildcard spec (`*`)](#define-environment-specs)
+1. Click the **New feature flag** button.
+1. Enter a name that starts with a letter and contains only lowercase letters, digits, underscores (`_`)
+ and dashes (`-`), and does not end with a dash (`-`) or underscore (`_`).
+1. Enter a description (optional, 255 characters max).
+1. Enter details about how the flag should be applied:
+ - In GitLab 13.0 and earlier: Enter an environment spec,
+ enable or disable the flag in this environment, and select a rollout strategy.
+ - In GitLab 13.1 and later (when [this feature flag](#feature-flag-behavior-change-in-130) is enabled): Select a strategy and then
+ the environments to apply the strategy to.
1. Click **Create feature flag**.
-Once a feature flag is created, the list of existing feature flags will be presented
-with ability to edit or remove them.
-
-To make a feature flag active or inactive, click the pencil icon to edit it,
-and toggle the status for each [spec](#define-environment-specs).
+The feature flag is displayed in the list. It is enabled by default.
-The toggles next to each feature flag on the list page function as global shutoff switches.
-If a toggle is off, that feature flag is disabled for every environment.
+## Disable a feature flag for a specific environment
-![Feature flags list](img/feature_flags_list_v12_7.png)
+In [GitLab 13.0 and earlier](https://gitlab.com/gitlab-org/gitlab/-/issues/8621),
+to disable a feature flag for a specific environment:
-## Define environment specs
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/8621) in GitLab 11.8.
-
-In general, an application is deployed to multiple environments, such as
-production, staging and [review apps](../../../ci/review_apps/index.md).
-For example, you may not want to enable a feature flag on production until your QA team has
-first confirmed that the feature is working correctly on testing environments.
+1. Navigate to your project's **Operations > Feature Flags**.
+1. For the feature flag you want to disable, click the Pencil icon.
+1. To disable the flag:
+ - In GitLab 13.0 and earlier: Slide the Status toggle for the environment. Or, to delete the
+ environment spec, on the right, click the **Remove (X)** icon.
+ - In GitLab 13.1 and later (when [this feature flag](#feature-flag-behavior-change-in-130) is
+ enabled): For each strategy it applies to, under **Environments**, delete the environment.
+1. Click **Save changes**.
-To handle these situations, you can enable a feature flag on a particular environment
-with [Environment specs](../../../ci/environments/index.md#scoping-environments-with-specs).
-You can define multiple specs per flag so that you can control your feature flag more granularly.
+## Disable a feature flag for all environments
-To define specs for each environment:
+To disable a feature flag for all environments:
1. Navigate to your project's **Operations > Feature Flags**.
-1. Click on the **New Feature Flag** button or edit an existing flag.
-1. Set the status of the default [spec](../../../ci/environments/index.md#scoping-environments-with-specs) (`*`). Choose a rollout strategy. This status and rollout strategy combination will be used for _all_ environments.
-1. If you want to enable/disable the feature on a specific environment, create a new [spec](../../../ci/environments/index.md#scoping-environments-with-specs) and type the environment name.
-1. Set the status and rollout strategy of the additional spec. This status and rollout strategy combination takes precedence over the default spec since we always use the most specific match available.
-1. Click **Create feature flag** or **Update feature flag**.
+1. For the feature flag you want to disable, slide the Status toggle to **Disabled**.
-![Feature flag specs list](img/specs_list_v12_6.png)
-
-NOTE: **NOTE**
-We'd highly recommend you to use the [Environment](../../../ci/environments/index.md)
-feature in order to quickly assess which flag is enabled per environment.
+The feature flag is displayed on the **Disabled** tab.
## Feature flag behavior change in 13.0
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35555) in GitLab 13.0.
-Starting in GitLab 13.0, you can apply a feature flag strategy across multiple environment specs,
+Starting in GitLab 13.0, you can apply a feature flag strategy across multiple environments,
without defining the strategy multiple times.
This feature is under development and not ready for production use. It is
@@ -121,29 +94,18 @@ To disable it:
Feature.disable(:feature_flags_new_version)
```
-### Applying a strategy to environments
-
-After a strategy is defined, it applies to **All Environments** by default. To
-make a strategy apply to a specific environment spec:
+## Feature flag strategies
-1. Click the **Add Environment** button.
-1. Create a new
- [spec](../../../ci/environments/index.md#scoping-environments-with-specs).
-
-To apply the strategy to multiple environment specs, repeat these steps.
-
-## Feature Flag strategies
-
-GitLab Feature Flag adopts [Unleash](https://unleash.github.io)
-as the feature flag engine. In unleash, there is a concept of rulesets for granular feature flag controls,
+GitLab Feature Flag uses [Unleash](https://unleash.github.io)
+as the feature flag engine. In Unleash, there is a concept of rulesets for granular feature flag controls,
called [strategies](https://unleash.github.io/docs/activation_strategy).
Supported strategies for GitLab Feature Flags are described below.
### Rollout strategy
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/8240) in GitLab 12.2.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8240) in GitLab 12.2.
-The selected rollout strategy affects which users will experience the feature enabled.
+The selected rollout strategy affects which users will experience the feature as enabled.
The status of an environment spec ultimately determines whether or not a feature is enabled at all.
For instance, a feature will always be disabled for every user if the matching environment spec has a disabled status, regardless of the chosen rollout strategy.
@@ -172,36 +134,34 @@ ID for the feature to be enabled. See the [Ruby example](#ruby-application-examp
#### User IDs
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/8240) in GitLab 12.2. [Updated](https://gitlab.com/gitlab-org/gitlab/issues/34363) to be defined per environment in GitLab 12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8240) in GitLab 12.2. [Updated](https://gitlab.com/gitlab-org/gitlab/-/issues/34363) to be defined per environment in GitLab 12.6.
A feature flag may be enabled for a list of target users. It is implemented
using the Unleash [`userWithId`](https://unleash.github.io/docs/activation_strategy#userwithid)
activation strategy.
-User IDs should be a comma separated list of values. For example, `user@example.com, user2@example.com`, or `username1,username2,username3`, etc.
+User IDs should be a comma-separated list of values. For example, `user@example.com, user2@example.com`, or `username1,username2,username3`, etc.
CAUTION: **Caution:**
The Unleash client **must** be given a user ID for the feature to be enabled for
target users. See the [Ruby example](#ruby-application-example) below.
-## Integrating with your application
+## Integrate feature flags with your application
-In order to use Feature Flags, you need to first
-[get the access credentials](#configuring-feature-flags) from GitLab and then
-prepare your application and hook it with a [client library](#client-libraries).
+To use feature flags with your application, get access credentials from GitLab.
+Then prepare your application with a client library.
-## Configuring Feature Flags
+### Get access credentials
-To get the access credentials that your application will need to talk to GitLab:
+To get the access credentials that your application needs to communicate with GitLab:
1. Navigate to your project's **Operations > Feature Flags**.
-1. Click on the **Configure** button to see the values:
+1. Click the **Configure** button to view the following:
- **API URL**: URL where the client (application) connects to get a list of feature flags.
- **Instance ID**: Unique token that authorizes the retrieval of the feature flags.
- **Application name**: The name of the running environment. For instance,
- if the application runs for a production server, application name would be
- `production` or similar. This value is used for
- [the environment spec evaluation](#define-environment-specs).
+ if the application runs for a production server, the application name would be
+ `production` or similar. This value is used for the environment spec evaluation.
NOTE: **Note:**
The meaning of these fields might change over time. For example, we are not sure
@@ -209,34 +169,28 @@ if **Instance ID** will be single token or multiple tokens, assigned to the
**Environment**. Also, **Application name** could describe the version of
application instead of the running environment.
-## Client libraries
+### Choose a client library
-GitLab currently implements a single backend that is compatible with
-[Unleash](https://github.com/Unleash/unleash#client-implementations) clients.
+GitLab implements a single backend that is compatible with Unleash clients.
-Unleash clients allow the developers to define in the app's code the default
-values for flags. Each feature flag evaluation can express the desired
-outcome in case the flag isn't present on the provided configuration file.
+With the Unleash client, developers can define, in the application code, the default values for flags.
+Each feature flag evaluation can express the desired outcome if the flag isn't present in the
+provided configuration file.
-Unleash currently offers a number of official SDKs for various frameworks and
-a number of community contributed libraries.
+Unleash currently [offers many SDKs for various languages and frameworks](https://github.com/Unleash/unleash#client-implementations).
-Official clients:
+### Feature flags API information
-- [Unleash client SDK for Java](https://github.com/unleash/unleash-client-java)
-- [Unleash client SDK for Node.js](https://github.com/unleash/unleash-client-node)
-- [Unleash client for Go](https://github.com/unleash/unleash-client-go)
-- [Unleash client for Ruby](https://github.com/unleash/unleash-client-ruby)
+For API content, see:
-Community contributed clients:
-
-- [Unleash FeatureToggle Client for .Net](https://github.com/stiano/unleash-client-dotnet)
-- [Unofficial .Net Core Unleash client](https://github.com/onybo/unleash-client-core)
-- [Unleash client for Python 3](https://github.com/aes/unleash-client-python)
+- [Feature Flags API](../../../api/feature_flags.md)
+- [Feature Flag Specs API](../../../api/feature_flag_specs.md) (Deprecated and [scheduled for removal in GitLab 14.0](https://gitlab.com/gitlab-org/gitlab/-/issues/213369).)
+- [Feature Flag User Lists API](../../../api/feature_flag_user_lists.md)
+- [Legacy Feature Flags API](../../../api/feature_flags_legacy.md)
-## Golang application example
+### Golang application example
-Here's an example of how to integrate the feature flags in a Golang application:
+Here's an example of how to integrate feature flags in a Golang application:
```golang
package main
@@ -275,9 +229,9 @@ func main() {
}
```
-## Ruby application example
+### Ruby application example
-Here's an example of how to integrate the feature flags in a Ruby application.
+Here's an example of how to integrate feature flags in a Ruby application.
The Unleash client is given a user ID for use with a **Percent rollout (logged in users)** rollout strategy or a list of **Target Users**.
@@ -305,12 +259,3 @@ else
puts "hello, world!"
end
```
-
-## Feature Flags API
-
-You can create, update, read, and delete Feature Flags via API
-to control them in an automated flow:
-
-- [Feature Flags API](../../../api/feature_flags.md)
-- [Feature Flag Specs API](../../../api/feature_flag_specs.md)
-- [Feature Flag User Lists API](../../../api/feature_flag_user_lists.md)
diff --git a/doc/user/project/operations/img/alert_detail_full_v13_1.png b/doc/user/project/operations/img/alert_detail_full_v13_1.png
new file mode 100644
index 00000000000..18a6f4fb67b
--- /dev/null
+++ b/doc/user/project/operations/img/alert_detail_full_v13_1.png
Binary files differ
diff --git a/doc/user/project/operations/img/alert_detail_overview_v13_1.png b/doc/user/project/operations/img/alert_detail_overview_v13_1.png
new file mode 100644
index 00000000000..10c945d3810
--- /dev/null
+++ b/doc/user/project/operations/img/alert_detail_overview_v13_1.png
Binary files differ
diff --git a/doc/user/project/operations/img/alert_detail_system_notes_v13_1.png b/doc/user/project/operations/img/alert_detail_system_notes_v13_1.png
new file mode 100644
index 00000000000..2a6d0320a54
--- /dev/null
+++ b/doc/user/project/operations/img/alert_detail_system_notes_v13_1.png
Binary files differ
diff --git a/doc/user/project/operations/img/alert_detail_v13_0.png b/doc/user/project/operations/img/alert_detail_v13_0.png
deleted file mode 100644
index 7da09407cd5..00000000000
--- a/doc/user/project/operations/img/alert_detail_v13_0.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/operations/img/alert_details_assignees_v13_1.png b/doc/user/project/operations/img/alert_details_assignees_v13_1.png
new file mode 100644
index 00000000000..dab4eac384a
--- /dev/null
+++ b/doc/user/project/operations/img/alert_details_assignees_v13_1.png
Binary files differ
diff --git a/doc/user/project/operations/img/alert_issue_v13_1.png b/doc/user/project/operations/img/alert_issue_v13_1.png
new file mode 100644
index 00000000000..da79074aa2f
--- /dev/null
+++ b/doc/user/project/operations/img/alert_issue_v13_1.png
Binary files differ
diff --git a/doc/user/project/operations/img/alert_list_assignees_v13_1.png b/doc/user/project/operations/img/alert_list_assignees_v13_1.png
new file mode 100644
index 00000000000..db1e0d8dcb7
--- /dev/null
+++ b/doc/user/project/operations/img/alert_list_assignees_v13_1.png
Binary files differ
diff --git a/doc/user/project/operations/img/alert_management_1_v13_1.png b/doc/user/project/operations/img/alert_management_1_v13_1.png
index c01b4749eda..00aa56a6050 100644
--- a/doc/user/project/operations/img/alert_management_1_v13_1.png
+++ b/doc/user/project/operations/img/alert_management_1_v13_1.png
Binary files differ
diff --git a/doc/user/project/operations/img/alert_todo_assignees_v13_1.png b/doc/user/project/operations/img/alert_todo_assignees_v13_1.png
new file mode 100644
index 00000000000..637f8be5d25
--- /dev/null
+++ b/doc/user/project/operations/img/alert_todo_assignees_v13_1.png
Binary files differ
diff --git a/doc/user/project/operations/img/dashboard_external_link_v13_1.png b/doc/user/project/operations/img/dashboard_external_link_v13_1.png
new file mode 100644
index 00000000000..3e8d792c53e
--- /dev/null
+++ b/doc/user/project/operations/img/dashboard_external_link_v13_1.png
Binary files differ
diff --git a/doc/user/project/operations/img/dashboard_local_timezone_v13_1.png b/doc/user/project/operations/img/dashboard_local_timezone_v13_1.png
new file mode 100644
index 00000000000..8d45607a940
--- /dev/null
+++ b/doc/user/project/operations/img/dashboard_local_timezone_v13_1.png
Binary files differ
diff --git a/doc/user/project/operations/img/external_dashboard_settings.png b/doc/user/project/operations/img/external_dashboard_settings.png
deleted file mode 100644
index e1b7fa56a1c..00000000000
--- a/doc/user/project/operations/img/external_dashboard_settings.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/operations/index.md b/doc/user/project/operations/index.md
index 954f88fe4f2..ca38eab9455 100644
--- a/doc/user/project/operations/index.md
+++ b/doc/user/project/operations/index.md
@@ -10,4 +10,4 @@ your applications:
- Discover and view errors generated by your applications with [Error Tracking](error_tracking.md).
- Create, toggle, and remove [Feature Flags](feature_flags.md). **(PREMIUM)**
- [Trace](tracing.md) the performance and health of a deployed application. **(ULTIMATE)**
-- Add a [button to the Monitoring dashboard](linking_to_an_external_dashboard.md) linking directly to your existing external dashboards.
+- Change the [settings of the Monitoring Dashboard](dashboard_settings.md).
diff --git a/doc/user/project/operations/linking_to_an_external_dashboard.md b/doc/user/project/operations/linking_to_an_external_dashboard.md
index 8e1117de4c7..ff609a3720e 100644
--- a/doc/user/project/operations/linking_to_an_external_dashboard.md
+++ b/doc/user/project/operations/linking_to_an_external_dashboard.md
@@ -1,19 +1,5 @@
-# Linking to an external dashboard
+---
+redirect_to: 'dashboard_settings.md'
+---
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/57171) in GitLab 12.0.
-
-You can add a button to the Monitoring dashboard linking directly to your existing external dashboards.
-
-## Enabling the external dashboard link
-
-1. Go to **Settings > Operations** and scroll to the section titled **External dashboard**.
-
-1. Fill in the URL to your external dashboard and click **Save changes**.
-
- ![External Dashboard Settings](img/external_dashboard_settings.png)
-
-1. There should now be a button on your
- [Monitoring dashboard](../../../ci/environments/index.md#monitoring-environments) which
- will open the URL you entered in the above step.
-
- ![External Dashboard Link](img/external_dashboard_link.png)
+This document was moved to [another location](dashboard_settings.md).
diff --git a/doc/user/project/pages/custom_domains_ssl_tls_certification/index.md b/doc/user/project/pages/custom_domains_ssl_tls_certification/index.md
index a5fc5b00b53..bf9b58acf14 100644
--- a/doc/user/project/pages/custom_domains_ssl_tls_certification/index.md
+++ b/doc/user/project/pages/custom_domains_ssl_tls_certification/index.md
@@ -273,7 +273,7 @@ Sublime Text, Atom, Dreamweaver, Brackets, etc).
## Force HTTPS for GitLab Pages websites
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/28857) in GitLab 10.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/28857) in GitLab 10.7.
To make your website's visitors even more secure, you can choose to
force HTTPS for GitLab Pages. By doing so, all attempts to visit your
@@ -287,6 +287,9 @@ To enable this setting:
1. Navigate to your project's **Settings > Pages**.
1. Tick the checkbox **Force HTTPS (requires valid certificates)**.
+NOTE: **Note**
+If you use CloudFlare CDN in front of GitLab Pages, make sure to set the SSL connection setting to `full` instead of `flexible`. For more details, see the [CloudFlare CDN directions](https://support.cloudflare.com/hc/en-us/articles/200170416-End-to-end-HTTPS-with-Cloudflare-Part-3-SSL-options#h_4e0d1a7c-eb71-4204-9e22-9d3ef9ef7fef).
+
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
diff --git a/doc/user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration.md b/doc/user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration.md
index 8b180d438ef..4b4b430b663 100644
--- a/doc/user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration.md
+++ b/doc/user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration.md
@@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# GitLab Pages integration with Let's Encrypt
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/28996) in GitLab 12.1. For versions earlier than GitLab 12.1, see the [manual Let's Encrypt instructions](../lets_encrypt_for_gitlab_pages.md).
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/28996) in GitLab 12.1. For versions earlier than GitLab 12.1, see the [manual Let's Encrypt instructions](../lets_encrypt_for_gitlab_pages.md).
The GitLab Pages integration with Let's Encrypt (LE) allows you
to use LE certificates for your Pages website with custom domains
@@ -19,7 +19,7 @@ GitLab does it for you, out-of-the-box.
open source Certificate Authority.
CAUTION: **Caution:**
-This feature covers only certificates for **custom domains**, not the wildcard certificate required to run [Pages daemon](../../../../administration/pages/index.md) **(CORE ONLY)**. Wildcard certificate generation is tracked in [this issue](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/3342).
+This feature covers only certificates for **custom domains**, not the wildcard certificate required to run [Pages daemon](../../../../administration/pages/index.md) **(CORE ONLY)**. Wildcard certificate generation is tracked in [this issue](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/3342).
## Requirements
diff --git a/doc/user/project/pages/getting_started/fork_sample_project.md b/doc/user/project/pages/getting_started/fork_sample_project.md
index 00cea846f91..de9bd97b262 100644
--- a/doc/user/project/pages/getting_started/fork_sample_project.md
+++ b/doc/user/project/pages/getting_started/fork_sample_project.md
@@ -5,68 +5,52 @@ group: Release 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/#designated-technical-writers
---
-# New Pages website from a forked sample
-
-To get started with GitLab Pages from a sample website, the easiest
-way to do it is by using one of the [bundled templates](pages_bundled_template.md).
-If you don't find one that suits your needs, you can opt by
-forking (copying) a [sample project from the most popular Static Site Generators](https://gitlab.com/pages).
-
-<table class="borderless-table center fixed-table middle width-80">
- <tr>
- <td style="width: 30%"><img src="../img/icons/fork.png" alt="Fork" class="image-noshadow half-width"></td>
- <td style="width: 10%">
- <strong>
- <i class="fa fa-angle-double-right" aria-hidden="true"></i>
- </strong>
- </td>
- <td style="width: 30%"><img src="../img/icons/terminal.png" alt="Deploy" class="image-noshadow half-width"></td>
- <td style="width: 10%">
- <strong>
- <i class="fa fa-angle-double-right" aria-hidden="true"></i>
- </strong>
- </td>
- <td style="width: 30%"><img src="../img/icons/click.png" alt="Visit" class="image-noshadow half-width"></td>
- </tr>
- <tr>
- <td><em>Fork an example project</em></td>
- <td></td>
- <td><em>Deploy your website</em></td>
- <td></td>
- <td><em>Visit your website's URL</em></td>
- </tr>
-</table>
-
-**<i class="fa fa-youtube-play youtube" aria-hidden="true"></i> Watch a [video tutorial](https://www.youtube.com/watch?v=TWqh9MtT4Bg) with all the steps below.**
-
-1. [Fork](../../../../gitlab-basics/fork-project.md) a sample project from the [GitLab Pages examples](https://gitlab.com/pages) group.
-1. From the left sidebar, navigate to your project's **CI/CD > Pipelines**
- and click **Run pipeline** to trigger GitLab CI/CD to build and deploy your
- site to the server.
-1. Once the pipeline has finished successfully, find the link to visit your
- website from your project's **Settings > Pages**. It can take approximately
- 30 minutes to be deployed.
-
-You can also take some **optional** further steps:
-
-- _Remove the fork relationship._ The fork relationship is necessary to contribute back to the project you originally forked from. If you don't have any intentions to do so, you can remove it. To do so, navigate to your project's **Settings**, expand **Advanced settings**, and scroll down to **Remove fork relationship**:
-
- ![Remove fork relationship](../img/remove_fork_relationship.png)
-
-- _Make it a user or group website._ To turn a **project website** forked
- from the Pages group into a **user/group** website, you'll need to:
- - Rename it to `namespace.gitlab.io`: go to your project's
- **Settings > General** and expand **Advanced**. Scroll down to
- **Change path** and change the path to `namespace.gitlab.io`.
-
- For example, consider the group `https://gitlab.com/gitlab-tests`:
- `gitlab-tests` is the group's namespace, the repository path should be set
- to `gitlab-tests.gitlab.io` (yes, weird like that), and the
- resulting URL for your Pages website will be `https://gitlab-tests.gitlab.io`.
+# Create a Pages website from a forked sample
+
+GitLab provides [sample projects for the most popular Static Site Generators](https://gitlab.com/pages).
+You can fork one of the sample projects and run the CI/CD pipeline to generate a Pages website.
+
+Fork a sample project when you want to test GitLab Pages or start a new project that's already
+configured to generate a Pages site.
+
+<i class="fa fa-youtube-play youtube" aria-hidden="true"></i> Watch a [video tutorial](https://www.youtube.com/watch?v=TWqh9MtT4Bg) of how this works.
+
+To fork a sample project and create a Pages website:
+
+1. View the sample projects by going to the [GitLab Pages examples](https://gitlab.com/pages) group.
+1. Click the name of the project you want to [fork](../../../../gitlab-basics/fork-project.md).
+1. In the top right, click the **Fork** button, and then choose a namespace to fork to.
+1. Go to your project's **CI/CD > Pipelines** and click **Run pipeline**.
+ GitLab CI/CD builds and deploys your site.
+
+The site can take approximately 30 minutes to deploy.
+When the pipeline is finished, go to **Settings > Pages** to find the link to your website from your project.
+
+For every change pushed to your repository, GitLab CI/CD runs a new pipeline
+that immediately publishes your changes to the Pages site.
+
+You can take some **optional** further steps:
+
+- _Remove the fork relationship._ If you want to contribute to the project you forked from,
+ you can keep this relationship. Otherwise, go to your project's **Settings > General**,
+ expand **Advanced settings**, and scroll down to **Remove fork relationship**:
+
+ ![Remove fork relationship](../img/remove_fork_relationship_v13_1.png)
+
+- _Change the URL to match your namespace._ If your Pages site is hosted on GitLab.com,
+ you can rename it to `<namespace>.gitlab.io`, where `<namespace>` is your GitLab namespace
+ (the one you chose when you forked the project).
+
+ - Go to your project's **Settings > General** and expand **Advanced**. Scroll down to
+ **Change path** and change the path to `<namespace>.gitlab.io`.
+
+ For example, if your project's URL is `gitlab.com/gitlab-tests/jekyll`, your namespace is
+ `gitlab-tests`.
+
+ If you set the repository path to `gitlab-tests.gitlab.io`,
+ the resulting URL for your Pages website is `https://gitlab-tests.gitlab.io`.
![Change repo's path](../img/change_path_v12_10.png)
- - Adjust your SSG's [base URL](../getting_started_part_one.md#urls-and-baseurls) from `"project-name"` to
- `""`. This setting will be at a different place for each SSG, as each of them
- have their own structure and file tree. Most likely, it will be in the SSG's
- config file.
+ - Now go to your SSG's configuration file and change the [base URL](../getting_started_part_one.md#urls-and-baseurls)
+ from `"project-name"` to `""`. The project name setting varies by SSG and may not be in the config file.
diff --git a/doc/user/project/pages/getting_started/new_or_existing_website.md b/doc/user/project/pages/getting_started/new_or_existing_website.md
index 9a00b724753..5d7126ab22e 100644
--- a/doc/user/project/pages/getting_started/new_or_existing_website.md
+++ b/doc/user/project/pages/getting_started/new_or_existing_website.md
@@ -5,44 +5,45 @@ group: Release 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/#designated-technical-writers
---
-# Start a new Pages website from scratch or deploy an existing website
+# Create a Pages website by using a CI/CD template
-If you already have a website and want to deploy it with GitLab Pages,
-or, if you want to start a new site from scratch, you'll need to:
+GitLab provides `.gitlab-ci.yml` templates for the most popular Static Site Generators (SSGs).
+You can create your own `.gitlab-ci.yml` file from one of these templates, and run
+the CI/CD pipeline to generate a Pages website.
-- Create a new project in GitLab to hold your site content.
-- Set up GitLab CI/CD to deploy your website to Pages.
+Use a `.gitlab-ci.yml` template when you have an existing project that you want to add a Pages site to.
-To do so, follow the steps below.
+Your GitLab repository should contain files specific to an SSG, or plain HTML.
+After you complete these steps, you may need to do additional
+configuration for the Pages site to generate properly.
-1. From your **Project**'s **[Dashboard](https://gitlab.com/dashboard/projects)**,
- click **New project**, and name it according to the
- [Pages domain names](../getting_started_part_one.md#gitlab-pages-default-domain-names).
-1. Clone it to your local computer, add your website
- files to your project, add, commit, and push to GitLab.
- Alternatively, you can run `git init` in your local directory,
- add the remote URL:
- `git remote add origin git@gitlab.com:namespace/project-name.git`,
- then add, commit, and push to GitLab.
-1. From the your **Project**'s page, click **Set up CI/CD**:
+1. In the left sidebar, click **Project overview**.
+1. Click **Set up CI/CD**.
- ![setup GitLab CI/CD](../img/setup_ci.png)
+ ![setup GitLab CI/CD](../img/setup_ci_v13_1.png)
-1. Choose one of the templates from the dropbox menu.
- Pick up the template corresponding to the SSG you're using (or plain HTML).
+ If this button is not available, CI/CD is already configured for
+ your project. You may want to browse the `.gitlab-ci.yml` files
+ [in these projects instead](https://gitlab.com/pages).
- ![gitlab-ci templates](../img/choose_ci_template.png)
+1. From the **Apply a template** list, choose a template for the SSG you're using.
+ You can also choose plain HTML.
- Note that, if you don't find a corresponding template, you can look into
- [GitLab Pages group of sample projects](https://gitlab.com/pages),
- you may find one among them that suits your needs, from which you
- can copy `.gitlab-ci.yml`'s content and adjust for your case.
- If you don't find it there either, [learn how to write a `.gitlab-ci.yml`
+ ![gitlab-ci templates](../img/choose_ci_template_v13_1.png)
+
+ If you don't find a corresponding template, you can view the
+ [GitLab Pages group of sample projects](https://gitlab.com/pages).
+ These projects contain `.gitlab-ci.yml` files that you can modify for your needs.
+ You can also [learn how to write your own `.gitlab-ci.yml`
file for GitLab Pages](../getting_started_part_four.md).
-Once you have both site files and `.gitlab-ci.yml` in your project's
-root, GitLab CI/CD will build your site and deploy it with Pages.
-Once the first build passes, you access your site by
-navigating to your **Project**'s **Settings** > **Pages**,
-where you'll find its default URL. It can take approximately 30 min to be
-deployed.
+1. Save and commit the `.gitlab-ci.yml` file.
+
+If everything is configured correctly, the site can take approximately 30 minutes to deploy.
+
+You can watch the pipeline run by going to **CI / CD > Pipelines**.
+When the pipeline is finished, go to **Settings > Pages** to find the link to
+your Pages website.
+
+For every change pushed to your repository, GitLab CI/CD runs a new pipeline
+that immediately publishes your changes to the Pages site.
diff --git a/doc/user/project/pages/getting_started/pages_bundled_template.md b/doc/user/project/pages/getting_started/pages_bundled_template.md
index 745c50e8d65..cfa4e0910db 100644
--- a/doc/user/project/pages/getting_started/pages_bundled_template.md
+++ b/doc/user/project/pages/getting_started/pages_bundled_template.md
@@ -5,27 +5,30 @@ group: Release 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/#designated-technical-writers
---
-# New Pages website from a bundled template
+# Create a Pages website from a new project template
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/47857) in GitLab 11.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/47857) in GitLab 11.8.
-The simplest way to create a GitLab Pages site is to use one of the most
-popular templates, which come already bundled with GitLab and are ready to go.
+GitLab provides templates for the most popular Static Site Generators (SSGs).
+You can create a new project from a template and run the CI/CD pipeline to generate a Pages website.
+
+Use a template when you want to test GitLab Pages or start a new project that's already
+configured to generate a Pages site.
1. From the top navigation, click the **+** button and select **New project**.
1. Select **Create from Template**.
-1. Choose one of the templates starting with **Pages**:
+1. Next to one of the templates starting with **Pages**, click **Use template**.
- ![Project templates for Pages](../img/pages_project_templates_v11_8.png)
+ ![Project templates for Pages](../img/pages_project_templates_v13_1.png)
+1. Complete the form and click **Create project**.
1. From the left sidebar, navigate to your project's **CI/CD > Pipelines**
and click **Run pipeline** to trigger GitLab CI/CD to build and deploy your
- site to the server.
-1. After the pipeline has finished successfully, wait approximately 30 minutes
- for your website to be visible. After waiting 30 minutes, find the link to
- visit your website from your project's **Settings > Pages**. If the link
- leads to a 404 page, wait a few minutes and try again.
-
-Your website is then visible on your domain and you can modify your files
-as you wish. For every modification pushed to your repository, GitLab CI/CD
-will run a new pipeline to immediately publish your changes to the server.
+ site.
+
+The site can take approximately 30 minutes to deploy.
+When the pipeline is finished, go to **Settings > Pages** to find the link to
+your Pages website.
+
+For every change pushed to your repository, GitLab CI/CD runs a new pipeline
+that immediately publishes your changes to the Pages site.
diff --git a/doc/user/project/pages/getting_started_part_four.md b/doc/user/project/pages/getting_started_part_four.md
index 4e95b5d5a69..8cf58280b88 100644
--- a/doc/user/project/pages/getting_started_part_four.md
+++ b/doc/user/project/pages/getting_started_part_four.md
@@ -6,137 +6,146 @@ group: Release 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/#designated-technical-writers
---
-# Creating and Tweaking GitLab CI/CD for GitLab Pages
-
-To [get started with GitLab Pages](index.md#getting-started), you can
-use one of the project templates, a `.gitlab-ci.yml` template,
-or fork an existing example project. Therefore, you don't need to
-understand _all_ the ins and odds of GitLab CI/CD to get your site
-deployed. Still, there are cases where you want to write your own
-script or tweak an existing one. This document guides you through
-this process.
-
-This guide also provides a general overview and clear introduction
-for **getting familiar with the `.gitlab-ci.yml` file and writing
-one for the first time.**
-
-[GitLab CI/CD](../../../ci/README.md) serves
-numerous purposes, to build, test, and deploy your app
-from GitLab through
-[Continuous Integration, Continuous Delivery, and Continuous Deployment](../../../ci/introduction/index.md#introduction-to-cicd-methodologies)
-methods. You will need it to build your website with GitLab Pages,
-and deploy it to the Pages server.
-
-To implement GitLab CI/CD, the first thing you need is a configuration
-file called `.gitlab-ci.yml` placed at your website's root directory.
-
-What this file actually does is telling the
-[GitLab Runner](https://docs.gitlab.com/runner/) to run scripts
-as you would do from the command line. The Runner acts as your
-terminal. GitLab CI/CD tells the Runner which commands to run.
-Both are built-in in GitLab, and you don't need to set up
-anything for them to work.
-
-Explaining [every detail of GitLab CI/CD](../../../ci/yaml/README.md)
-and GitLab Runner is out of the scope of this guide, but we'll
-need to understand just a few things to be able to write our own
-`.gitlab-ci.yml` or tweak an existing one. It's a
-[YAML](https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html) file,
-with its own syntax. You can always check your CI syntax with
-the [GitLab CI/CD Lint Tool](https://gitlab.com/ci/lint).
-
-## Practical example
-
-Let's consider you have a [Jekyll](https://jekyllrb.com/) site.
-To build it locally, you would open your terminal, and run `jekyll build`.
-Of course, before building it, you had to install Jekyll in your computer.
-For that, you had to open your terminal and run `gem install jekyll`.
-Right? GitLab CI/CD + GitLab Runner do the same thing. But you need to
-write in the `.gitlab-ci.yml` the script you want to run so
-GitLab Runner will do it for you. It looks more complicated than it
-is. What you need to tell the Runner:
-
-```shell
-gem install jekyll
-jekyll build
+# Create a GitLab Pages website from scratch
+
+This tutorial shows you how to create a Pages site from scratch. You will start with
+a blank project and create your own CI file, which gives instruction to the
+[GitLab Runner](https://docs.gitlab.com/runner/). When your CI/CD
+[pipeline](../../../ci/pipelines/index.md) runs, the Pages site is created.
+
+This example uses the [Jekyll](https://jekyllrb.com/) Static Site Generator (SSG).
+Other SSGs follow similar steps. You do not need to be familiar with Jekyll or SSGs
+to complete this tutorial.
+
+## Prerequisites
+
+To follow along with this example, start with a blank project in GitLab.
+Create three files in the root (top-level) directory.
+
+- `.gitlab-ci.yml` A YAML file that contains the commands you want to run.
+ For now, leave the file's contents blank.
+
+- `index.html` An HTML file you can populate with whatever HTML content you'd like,
+ for example:
+
+ ```html
+ <html>
+ <head>
+ <title>Home</title>
+ </head>
+ <body>
+ <h1>Hello World!</h1>
+ </body>
+ </html>
+ ```
+
+- [`Gemfile`](https://bundler.io/gemfile.html) A file that describes dependencies for Ruby programs.
+ Populate it with this content:
+
+ ```ruby
+ source "https://rubygems.org"
+
+ gem "jekyll"
+ ```
+
+## Choose a Docker image
+
+In this example, the Runner uses a [Docker image](../../../ci/docker/using_docker_images.md)
+to run scripts and deploy the site.
+
+This specific Ruby image is maintained on [DockerHub](https://hub.docker.com/_/ruby).
+
+Edit your `.gitlab-ci.yml` and add this text as the first line.
+
+```yaml
+image: ruby:2.7
```
-### Script
+If your SSG needs [NodeJS](https://nodejs.org/) to build, you must specify an
+image that contains NodeJS as part of its file system. For example, for a
+[Hexo](https://gitlab.com/pages/hexo) site, you can use `image: node:12.17.0`.
+
+## Install Jekyll
+
+To run [Jekyll](https://jekyllrb.com/) locally, you would open your terminal and:
-To transpose this script to YAML, it would be like this:
+- Install [Bundler](https://bundler.io/) by running `gem install bundler`.
+- Create `Gemfile.lock` by running `bundle install`.
+- Install Jekyll by running `bundle exec jekyll build`.
+
+In the `.gitlab-ci.yml` file, this is written as:
```yaml
script:
- - gem install jekyll
- - jekyll build
+ - gem install bundler
+ - bundle install
+ - bundle exec jekyll build
```
-### Job
-
-So far so good. Now, each `script`, in GitLab is organized by
-a `job`, which is a bunch of scripts and settings you want to
-apply to that specific task.
+In addition, in the `.gitlab-ci.yml` file, each `script` is organized by a `job`.
+A `job` includes the scripts and settings you want to apply to that specific
+task.
```yaml
job:
script:
- - gem install jekyll
- - jekyll build
+ - gem install bundler
+ - bundle install
+ - bundle exec jekyll build
```
-For GitLab Pages, this `job` has a specific name, called `pages`,
-which tells the Runner you want that task to deploy your website
+For GitLab Pages, this `job` has a specific name, called `pages`.
+This setting tells the Runner you want the job to deploy your website
with GitLab Pages:
```yaml
pages:
script:
- - gem install jekyll
- - jekyll build
+ - gem install bundler
+ - bundle install
+ - bundle exec jekyll build
```
-### The `public` directory
+## Specify the `public` directory for output
+
+Jekyll needs to know where to generate its output.
+GitLab Pages only considers files in a directory called `public`.
-We also need to tell Jekyll where do you want the website to build,
-and GitLab Pages will only consider files in a directory called `public`.
-To do that with Jekyll, we need to add a flag specifying the
-[destination (`-d`)](https://jekyllrb.com/docs/usage/) of the
-built website: `jekyll build -d public`. Of course, we need
-to tell this to our Runner:
+Jekyll uses destination (`-d`) to specify an output directory for the built website:
```yaml
pages:
script:
- - gem install jekyll
- - jekyll build -d public
+ - gem install bundler
+ - bundle install
+ - bundle exec jekyll build -d public
```
-### Artifacts
+## Specify the `public` directory for artifacts
-We also need to tell the Runner that this _job_ generates
-_artifacts_, which is the site built by Jekyll.
-Where are these artifacts stored? In the `public` directory:
+Now that Jekyll has output the files to the `public` directory,
+the Runner needs to know where to get them. The artifacts are stored
+in the `public` directory:
```yaml
pages:
script:
- - gem install jekyll
- - jekyll build -d public
+ - gem install bundler
+ - bundle install
+ - bundle exec jekyll build -d public
artifacts:
paths:
- public
```
-The script above would be enough to build your Jekyll
-site with GitLab Pages. But, from Jekyll 3.4.0 on, its default
-template originated by `jekyll new project` requires
-[Bundler](https://bundler.io) to install Jekyll dependencies
-and the default theme. To adjust our script to meet these new
-requirements, we only need to install and build Jekyll with Bundler:
+Paste this into `.gitlab-ci.yml` file, so it now looks like this:
```yaml
+image: ruby:2.7
+
pages:
script:
+ - gem install bundler
- bundle install
- bundle exec jekyll build -d public
artifacts:
@@ -144,27 +153,35 @@ pages:
- public
```
-That's it! A `.gitlab-ci.yml` with the content above would deploy
-your Jekyll 3.4.0 site with GitLab Pages. This is the minimum
-configuration for our example. On the steps below, we'll refine
-the script by adding extra options to our GitLab CI/CD.
+Now save and commit the `.gitlab-ci.yml` file. You can watch the pipeline run
+by going to **CI / CD > Pipelines**.
+
+When it succeeds, go to **Settings > Pages** to view the URL where your site
+is now available.
+
+If you want to do more advanced tasks, you can update your `.gitlab-ci.yml` file
+with [any of the available settings](../../../ci/yaml/README.md). You can check
+your CI syntax with the [GitLab CI/CD Lint Tool](https://gitlab.com/ci/lint).
+
+The following topics show other examples of other options you can add to your CI/CD file.
-Artifacts will be automatically deleted once GitLab Pages got deployed.
-You can preserve artifacts for limited time by specifying the expiry time.
+## Deploy specific branches to a Pages site
-### Image
+You may want to deploy to a Pages site only from specific branches.
-At this point, you probably ask yourself: "okay, but to install Jekyll
-I need Ruby. Where is Ruby on that script?". The answer is simple: the
-first thing GitLab Runner will look for in your `.gitlab-ci.yml` is a
-[Docker](https://www.docker.com/) image specifying what do you need in
-your container to run that script:
+First, add a `workflow` section to force the pipeline to run only when changes are
+pushed to branches:
```yaml
image: ruby:2.7
+workflow:
+ rules:
+ - if: '$CI_COMMIT_BRANCH'
+
pages:
script:
+ - gem install bundler
- bundle install
- bundle exec jekyll build -d public
artifacts:
@@ -172,134 +189,122 @@ pages:
- public
```
-In this case, you're telling the Runner to pull this image, which
-contains Ruby 2.7 as part of its file system. When you don't specify
-this image in your configuration, the Runner will use a default
-image, which is Ruby 2.6.
-
-If your SSG needs [NodeJS](https://nodejs.org/) to build, you'll
-need to specify which image you want to use, and this image should
-contain NodeJS as part of its file system. E.g., for a
-[Hexo](https://gitlab.com/pages/hexo) site, you can use `image: node:4.2.2`.
-
->**Note:**
-We're not trying to explain what a Docker image is,
-we just need to introduce the concept with a minimum viable
-explanation. To know more about Docker images, please visit
-their website or take a look at a
-[summarized explanation](http://paislee.io/how-to-automate-docker-deployments/) here.
-
-Let's go a little further.
-
-### Branching
-
-If you use GitLab as a version control platform, you will have your
-branching strategy to work on your project. Meaning, you will have
-other branches in your project, but you'll want only pushes to the
-default branch (usually `master`) to be deployed to your website.
-To do that, we need to add another line to our CI, telling the Runner
-to only perform that _job_ called `pages` on the `master` branch `only`:
+Then configure the pipeline to run the job for the master branch only.
```yaml
-image: ruby:2.6
+image: ruby:2.7
+
+workflow:
+ rules:
+ - if: '$CI_COMMIT_BRANCH'
pages:
script:
+ - gem install bundler
- bundle install
- bundle exec jekyll build -d public
artifacts:
paths:
- public
- only:
- - master
+ rules:
+ - if: '$CI_COMMIT_BRANCH == "master"'
```
-### Stages
+## Specify a stage to deploy
-Another interesting concept to keep in mind are build stages.
-Your web app can pass through a lot of tests and other tasks
-until it's deployed to staging or production environments.
-There are three default stages on GitLab CI/CD: build, test,
-and deploy. To specify which stage your _job_ is running,
-simply add another line to your CI:
+There are three default stages for GitLab CI/CD: build, test,
+and deploy.
+
+If you want to test your script and check the built site before deploying
+to production, you can run the test exactly as it will run when you
+push to `master`.
+
+To specify a stage for your job to run in,
+add a `stage` line to your CI file:
```yaml
-image: ruby:2.6
+image: ruby:2.7
+
+workflow:
+ rules:
+ - if: '$CI_COMMIT_BRANCH'
pages:
stage: deploy
script:
+ - gem install bundler
- bundle install
- bundle exec jekyll build -d public
artifacts:
paths:
- public
- only:
- - master
+ rules:
+ - if: '$CI_COMMIT_BRANCH == "master"'
```
-You might ask yourself: "why should I bother with stages
-at all?" Well, let's say you want to be able to test your
-script and check the built site before deploying your site
-to production. You want to run the test exactly as your
-script will do when you push to `master`. It's simple,
-let's add another task (_job_) to our CI, telling it to
-test every push to other branches, `except` the `master` branch:
+Now add another job to the CI file, telling it to
+test every push to every branch **except** the `master` branch:
```yaml
-image: ruby:2.6
+image: ruby:2.7
+
+workflow:
+ rules:
+ - if: '$CI_COMMIT_BRANCH'
pages:
stage: deploy
script:
+ - gem install bundler
- bundle install
- bundle exec jekyll build -d public
artifacts:
paths:
- public
- only:
- - master
+ rules:
+ - if: '$CI_COMMIT_BRANCH == "master"'
test:
stage: test
script:
+ - gem install bundler
- bundle install
- bundle exec jekyll build -d test
artifacts:
paths:
- test
- except:
- - master
+ rules:
+ - if: '$CI_COMMIT_BRANCH != "master"'
```
-The `test` job is running on the stage `test`, Jekyll
-will build the site in a directory called `test`, and
-this job will affect all the branches except `master`.
-
-The best benefit of applying _stages_ to different
-_jobs_ is that every job in the same stage builds in
-parallel. So, if your web app needs more than one test
-before being deployed, you can run all your test at the
-same time, it's not necessary to wait one test to finish
-to run the other. Of course, this is just a brief
-introduction of GitLab CI/CD and GitLab Runner, which are
-tools much more powerful than that. This is what you
-need to be able to create and tweak your builds for
-your GitLab Pages site.
-
-### Before Script
-
-To avoid running the same script multiple times across
-your _jobs_, you can add the parameter `before_script`,
-in which you specify which commands you want to run for
-every single _job_. In our example, notice that we run
-`bundle install` for both jobs, `pages` and `test`.
-We don't need to repeat it:
+When the `test` job runs in the `test` stage, Jekyll
+builds the site in a directory called `test`. The job affects
+all branches except `master`.
+
+When you apply stages to different jobs, every job in the same
+stage builds in parallel. If your web application needs more than
+one test before being deployed, you can run all your tests at the
+same time.
+
+## Remove duplicate commands
+
+To avoid duplicating the same scripts in every job, you can add them
+to a `before_script` section.
+
+In the example, `gem install bundler` and `bundle install` were running
+for both jobs, `pages` and `test`.
+
+Move these commands to a `before_script` section:
```yaml
-image: ruby:2.6
+image: ruby:2.7
+
+workflow:
+ rules:
+ - if: '$CI_COMMIT_BRANCH'
before_script:
+ - gem install bundler
- bundle install
pages:
@@ -309,8 +314,8 @@ pages:
artifacts:
paths:
- public
- only:
- - master
+ rules:
+ - if: '$CI_COMMIT_BRANCH == "master"'
test:
stage: test
@@ -319,26 +324,31 @@ test:
artifacts:
paths:
- test
- except:
- - master
+ rules:
+ - if: '$CI_COMMIT_BRANCH != "master"'
```
-### Caching Dependencies
+## Build faster with cached dependencies
+
+To build faster, you can cache the installation files for your
+project's dependencies by using the `cache` parameter.
-If you want to cache the installation files for your
-projects dependencies, for building faster, you can
-use the parameter `cache`. For this example, we'll
-cache Jekyll dependencies in a `vendor` directory
-when we run `bundle install`:
+This example caches Jekyll dependencies in a `vendor` directory
+when you run `bundle install`:
```yaml
-image: ruby:2.6
+image: ruby:2.7
+
+workflow:
+ rules:
+ - if: '$CI_COMMIT_BRANCH'
cache:
paths:
- vendor/
before_script:
+ - gem install bundler
- bundle install --path vendor
pages:
@@ -348,8 +358,8 @@ pages:
artifacts:
paths:
- public
- only:
- - master
+ rules:
+ - if: '$CI_COMMIT_BRANCH == "master"'
test:
stage: test
@@ -358,40 +368,35 @@ test:
artifacts:
paths:
- test
- except:
- - master
+ rules:
+ - if: '$CI_COMMIT_BRANCH != "master"'
```
-For this specific case, we need to exclude `/vendor`
-from Jekyll `_config.yml` file, otherwise Jekyll will
-understand it as a regular directory to build
-together with the site:
+In this case, you need to exclude the `/vendor`
+directory from the list of folders Jekyll builds. Otherwise, Jekyll
+will try to build the directory contents along with the site.
+
+In the root directory, create a file called `_config.yml`
+and add this content:
```yaml
exclude:
- vendor
```
-There we go! Now our GitLab CI/CD not only builds our website,
-but also **continuously test** pushes to feature-branches,
+Now GitLab CI/CD not only builds the website,
+but also pushes with **continuous tests** to feature-branches,
**caches** dependencies installed with Bundler, and
-**continuously deploy** every push to the `master` branch.
+**continuously deploys** every push to the `master` branch.
-## Advanced GitLab CI for GitLab Pages
+## Related topics
-What you can do with GitLab CI/CD is pretty much up to your
-creativity. Once you get used to it, you start creating
-awesome scripts that automate most of tasks you'd do
-manually in the past. Read through the
-[documentation of GitLab CI/CD](../../../ci/yaml/README.md)
-to understand how to go even further on your scripts.
+For more information, see the following blog posts.
-- On this blog post, understand the concept of
- [using GitLab CI/CD `environments` to deploy your
+- [Use GitLab CI/CD `environments` to deploy your
web app to staging and production](https://about.gitlab.com/blog/2016/08/26/ci-deployment-and-environments/).
-- On this post, learn [how to run jobs sequentially,
- in parallel, or build a custom pipeline](https://about.gitlab.com/blog/2016/07/29/the-basics-of-gitlab-ci/)
-- On this blog post, we go through the process of
- [pulling specific directories from different projects](https://about.gitlab.com/blog/2016/12/07/building-a-new-gitlab-docs-site-with-nanoc-gitlab-ci-and-gitlab-pages/)
- to deploy this website you're looking at, <https://docs.gitlab.com>.
-- On this blog post, we teach you [how to use GitLab Pages to produce a code coverage report](https://about.gitlab.com/blog/2016/11/03/publish-code-coverage-report-with-gitlab-pages/).
+- Learn [how to run jobs sequentially,
+ in parallel, or build a custom pipeline](https://about.gitlab.com/blog/2016/07/29/the-basics-of-gitlab-ci/).
+- Learn [how to pull specific directories from different projects](https://about.gitlab.com/blog/2016/12/07/building-a-new-gitlab-docs-site-with-nanoc-gitlab-ci-and-gitlab-pages/)
+ to deploy this website, <https://docs.gitlab.com>.
+- Learn [how to use GitLab Pages to produce a code coverage report](https://about.gitlab.com/blog/2016/11/03/publish-code-coverage-report-with-gitlab-pages/).
diff --git a/doc/user/project/pages/img/change_path_v12_10.png b/doc/user/project/pages/img/change_path_v12_10.png
index 7ca09bd21a3..9b5c17f1dda 100644
--- a/doc/user/project/pages/img/change_path_v12_10.png
+++ b/doc/user/project/pages/img/change_path_v12_10.png
Binary files differ
diff --git a/doc/user/project/pages/img/choose_ci_template.png b/doc/user/project/pages/img/choose_ci_template.png
deleted file mode 100644
index 0697542abc8..00000000000
--- a/doc/user/project/pages/img/choose_ci_template.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/pages/img/choose_ci_template_v13_1.png b/doc/user/project/pages/img/choose_ci_template_v13_1.png
new file mode 100644
index 00000000000..84dd9fe2e0f
--- /dev/null
+++ b/doc/user/project/pages/img/choose_ci_template_v13_1.png
Binary files differ
diff --git a/doc/user/project/pages/img/pages_project_templates_v11_8.png b/doc/user/project/pages/img/pages_project_templates_v11_8.png
deleted file mode 100644
index 61cae88b5a8..00000000000
--- a/doc/user/project/pages/img/pages_project_templates_v11_8.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/pages/img/pages_project_templates_v13_1.png b/doc/user/project/pages/img/pages_project_templates_v13_1.png
new file mode 100644
index 00000000000..3f6d1ecd786
--- /dev/null
+++ b/doc/user/project/pages/img/pages_project_templates_v13_1.png
Binary files differ
diff --git a/doc/user/project/pages/img/remove_fork_relationship.png b/doc/user/project/pages/img/remove_fork_relationship.png
deleted file mode 100644
index 67c45491f08..00000000000
--- a/doc/user/project/pages/img/remove_fork_relationship.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/pages/img/remove_fork_relationship_v13_1.png b/doc/user/project/pages/img/remove_fork_relationship_v13_1.png
new file mode 100644
index 00000000000..1bc7bcd253b
--- /dev/null
+++ b/doc/user/project/pages/img/remove_fork_relationship_v13_1.png
Binary files differ
diff --git a/doc/user/project/pages/img/setup_ci.png b/doc/user/project/pages/img/setup_ci.png
deleted file mode 100644
index 214c1cc668f..00000000000
--- a/doc/user/project/pages/img/setup_ci.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/pages/img/setup_ci_v13_1.png b/doc/user/project/pages/img/setup_ci_v13_1.png
new file mode 100644
index 00000000000..2cf1c05d6d8
--- /dev/null
+++ b/doc/user/project/pages/img/setup_ci_v13_1.png
Binary files differ
diff --git a/doc/user/project/pages/index.md b/doc/user/project/pages/index.md
index e81c9699153..5861282ca6f 100644
--- a/doc/user/project/pages/index.md
+++ b/doc/user/project/pages/index.md
@@ -1,7 +1,5 @@
---
description: 'Learn how to use GitLab Pages to deploy a static website at no additional cost.'
-last_updated: 2019-06-04
-type: index, reference
stage: Release
group: Release 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/#designated-technical-writers
@@ -11,46 +9,76 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80) in GitLab Enterprise Edition 8.3.
> - Custom CNAMEs with TLS support were [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/173) in GitLab Enterprise Edition 8.5.
-> - [Ported](https://gitlab.com/gitlab-org/gitlab-foss/issues/14605) to GitLab Community Edition in GitLab 8.17.
-> - Support for subgroup project's websites was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/30548) in GitLab 11.8.
-> - Bundled project templates were [introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/47857) in GitLab 11.8.
+> - [Ported](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/14605) to GitLab Community Edition in GitLab 8.17.
+> - Support for subgroup project's websites was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/30548) in GitLab 11.8.
+> - Bundled project templates were [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/47857) in GitLab 11.8.
-**GitLab Pages is a feature that allows you to publish static websites
-directly from a repository in GitLab.**
-
-You can use it either for personal or business websites, such as
-portfolios, documentation, manifestos, and business presentations.
-You can also attribute any license to your content.
-
-<img src="img/pages_workflow_v12_5.png" alt="Pages websites workflow" class="image-noshadow">
-
-Pages is available for free for all GitLab.com users as well as for self-managed
-instances (GitLab Core, Starter, Premium, and Ultimate).
-
-## Overview
+With GitLab Pages, you can publish static websites
+directly from a repository in GitLab.
<div class="row">
<div class="col-md-9">
<p style="margin-top: 18px;">
-To publish a website with Pages, you can use any Static Site Generator (SSG),
-such as Gatsby, Jekyll, Hugo, Middleman, Harp, Hexo, and Brunch, just to name a few. You can also
-publish any website written directly in plain HTML, CSS, and JavaScript.</p>
-<p>Pages does <strong>not</strong> support dynamic server-side processing, for instance, as <code>.php</code> and <code>.asp</code> requires. See this article to learn more about
-<a href="https://about.gitlab.com/blog/2016/06/03/ssg-overview-gitlab-pages-part-1-dynamic-x-static/">static websites vs dynamic websites</a>.</p>
+<ul>
+<li>Use for any personal or business website.</li>
+<li>Use any Static Site Generator (SSG) or plain HTML.</li>
+<li>Create websites for your projects, groups, or user account.</li>
+<li>Host your site on your own GitLab instance or on GitLab.com for free.</li>
+<li>Connect your custom domains and TLS certificates.</li>
+<li>Attribute any license to your content.</li>
+</ul>
+</p>
</div>
<div class="col-md-3"><img src="img/ssgs_pages.png" alt="Examples of SSGs supported by Pages" class="image-noshadow middle display-block"></div>
</div>
-### How it works
+To publish a website with Pages, you can use any SSG,
+like Gatsby, Jekyll, Hugo, Middleman, Harp, Hexo, and Brunch, just to name a few. You can also
+publish any website written directly in plain HTML, CSS, and JavaScript.
-To use GitLab Pages, first you need to create a project in GitLab to upload your website's
-files to. These projects can be either public, internal, or private, at your own choice.
+Pages does **not** support dynamic server-side processing, for instance, as `.php` and `.asp` requires.
+Learn more about
+[static websites compared to dynamic websites](https://about.gitlab.com/blog/2016/06/03/ssg-overview-gitlab-pages-part-1-dynamic-x-static/).
+
+## Getting started
+
+To create a GitLab Pages website:
+
+| Document | Description |
+| -------- | ----------- |
+| [Use a `.gitlab-ci.yml` template](getting_started/new_or_existing_website.md) | Add a Pages site to an existing project. Use a pre-populated CI template file. |
+| [Create a `gitlab-ci.yml` file from scratch](getting_started_part_four.md) | Add a Pages site to an existing project. Learn how to create and configure your own CI file. |
+| [Use a new project template](getting_started/pages_bundled_template.md) | Create a new project with Pages already configured by using a new project template. |
+| [Fork a sample project](getting_started/fork_sample_project.md) | Create a new project with Pages already configured by forking a sample project. |
+
+To update a GitLab Pages website:
+
+| Document | Description |
+| -------- | ----------- |
+| [GitLab Pages domain names, URLs, and base URLs](getting_started_part_one.md) | Learn about GitLab Pages default domains. |
+| [Explore GitLab Pages](introduction.md) | Requirements, technical aspects, specific GitLab CI/CD configuration options, Access Control, custom 404 pages, limitations, FAQ. |
+| [Custom domains and SSL/TLS Certificates](custom_domains_ssl_tls_certification/index.md) | Custom domains and subdomains, DNS records, and SSL/TLS certificates. |
+| [Let's Encrypt integration](custom_domains_ssl_tls_certification/lets_encrypt_integration.md) | Secure your Pages sites with Let's Encrypt certificates, which are automatically obtained and renewed by GitLab. |
+| [CloudFlare certificates](https://about.gitlab.com/blog/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/) | Secure your Pages site with CloudFlare certificates. |
+
+Learn more and see examples:
+
+| Document | Description |
+| -------- | ----------- |
+| [Static vs dynamic websites](https://about.gitlab.com/blog/2016/06/03/ssg-overview-gitlab-pages-part-1-dynamic-x-static/) | Static versus dynamic site overview. |
+| [Modern static site generators](https://about.gitlab.com/blog/2016/06/10/ssg-overview-gitlab-pages-part-2/) | SSG overview. |
+| [Build any SSG site with GitLab Pages](https://about.gitlab.com/blog/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/) | Use SSGs for GitLab Pages. |
-GitLab will always deploy your website from a very specific folder called `public` in your
-repository. Note that when you create a new project in GitLab, a [repository](../repository/index.md)
+## How it works
+
+To use GitLab Pages, you must create a project in GitLab to upload your website's
+files to. These projects can be either public, internal, or private.
+
+GitLab always deploys your website from a very specific folder called `public` in your
+repository. When you create a new project in GitLab, a [repository](../repository/index.md)
becomes available automatically.
-To deploy your site, GitLab will use its built-in tool called [GitLab CI/CD](../../../ci/README.md),
+To deploy your site, GitLab uses its built-in tool called [GitLab CI/CD](../../../ci/README.md)
to build your site and publish it to the GitLab Pages server. The sequence of
scripts that GitLab CI/CD runs to accomplish this task is created from a file named
`.gitlab-ci.yml`, which you can [create and modify](getting_started_part_four.md) at will. A specific `job` called `pages` in the configuration file will make GitLab aware that you are deploying a GitLab Pages website.
@@ -59,59 +87,29 @@ You can either use GitLab's [default domain for GitLab Pages websites](getting_s
`*.gitlab.io`, or your own domain (`example.com`). In that case, you'll
need admin access to your domain's registrar (or control panel) to set it up with Pages.
-### Getting started
-
-To get started with GitLab Pages, you can either:
-
-- [Use a bundled website template ready to go](getting_started/pages_bundled_template.md).
-- [Copy an existing sample](getting_started/fork_sample_project.md).
-- [Create a website from scratch or deploy an existing one](getting_started/new_or_existing_website.md).
+The following diagrams show the workflows you might follow to get started with Pages.
<img src="img/new_project_for_pages_v12_5.png" alt="New projects for GitLab Pages" class="image-noshadow">
-Optional features:
+## Access to your Pages site
-- Use a [custom domain or subdomain](custom_domains_ssl_tls_certification/index.md#set-up-pages-with-a-custom-domain).
-- Add an [SSL/TLS certificate to secure your site under the HTTPS protocol](custom_domains_ssl_tls_certification/index.md#adding-an-ssltls-certificate-to-pages).
-
-Note that, if you're using GitLab Pages default domain (`.gitlab.io`),
+If you're using GitLab Pages default domain (`.gitlab.io`),
your website will be automatically secure and available under
HTTPS. If you're using your own custom domain, you can
optionally secure it with SSL/TLS certificates.
-## Availability
-
If you're using GitLab.com, your website will be publicly available to the internet.
-
To restrict access to your website, enable [GitLab Pages Access Control](pages_access_control.md).
-If you're using self-managed instances (Core, Starter, Premium, or Ultimate),
+If you're using a self-managed instance (Core, Starter, Premium, or Ultimate),
your websites will be published on your own server, according to the
[Pages admin settings](../../../administration/pages/index.md) chosen by your sysadmin,
-who can opt for making them public or internal to your server.
+who can make them public or internal.
-## Explore GitLab Pages
+## Pages examples
-To learn more about configuration options for GitLab Pages, read the following:
-
-| Document | Description |
-| --- | --- |
-| [GitLab Pages domain names, URLs, and baseurls](getting_started_part_one.md) | Understand how GitLab Pages default domains work. |
-| [GitLab CI/CD for GitLab Pages](getting_started_part_four.md) | Understand how to create your own `.gitlab-ci.yml` for your site. |
-| [Exploring GitLab Pages](introduction.md) | Requirements, technical aspects, specific GitLab CI/CD's configuration options, Access Control, custom 404 pages, limitations, FAQ. |
-|---+---|
-| [Custom domains and SSL/TLS Certificates](custom_domains_ssl_tls_certification/index.md) | How to add custom domains and subdomains to your website, configure DNS records and SSL/TLS certificates. |
-| [Let's Encrypt integration](custom_domains_ssl_tls_certification/lets_encrypt_integration.md) | Secure your Pages sites with Let's Encrypt certificates automatically obtained and renewed by GitLab. |
-| [CloudFlare certificates](https://about.gitlab.com/blog/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/) | Secure your Pages site with CloudFlare certificates. |
-|---+---|
-| [Static vs dynamic websites](https://about.gitlab.com/blog/2016/06/03/ssg-overview-gitlab-pages-part-1-dynamic-x-static/) | A conceptual overview on static versus dynamic sites. |
-| [Modern static site generators](https://about.gitlab.com/blog/2016/06/10/ssg-overview-gitlab-pages-part-2/) | A conceptual overview on SSGs. |
-| [Build any SSG site with GitLab Pages](https://about.gitlab.com/blog/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/) | An overview on using SSGs for GitLab Pages. |
-
-## Advanced use
-
-There are quite some great examples of GitLab Pages websites built for some
-specific reasons. These examples can teach you some advanced techniques
+There are some great examples of GitLab Pages websites built for
+specific reasons. These examples can teach you advanced techniques
to use and adapt to your own needs:
- [Posting to your GitLab Pages blog from iOS](https://about.gitlab.com/blog/2016/08/19/posting-to-your-gitlab-pages-blog-from-ios/).
@@ -120,14 +118,9 @@ to use and adapt to your own needs:
- [Building a new GitLab docs site with Nanoc, GitLab CI, and GitLab Pages](https://about.gitlab.com/blog/2016/12/07/building-a-new-gitlab-docs-site-with-nanoc-gitlab-ci-and-gitlab-pages/).
- [Publish code coverage reports with GitLab Pages](https://about.gitlab.com/blog/2016/11/03/publish-code-coverage-report-with-gitlab-pages/).
-## Admin GitLab Pages for self-managed instances
-
-Enable and configure GitLab Pages on your own instance (GitLab Community Edition and Enterprise Editions) with
-the [admin guide](../../../administration/pages/index.md).
-
-**<i class="fa fa-youtube-play youtube" aria-hidden="true"></i> Watch a [video tutorial](https://www.youtube.com/watch?v=dD8c7WNcc6s) for getting started with GitLab Pages admin!**
+## Administer GitLab Pages for self-managed instances
-## More information about GitLab Pages
+If you are running a self-managed instance of GitLab (GitLab Community Edition and Enterprise Editions),
+[follow the administration steps](../../../administration/pages/index.md) to configure Pages.
-- Announcement (2016-12-24): ["We're bringing GitLab Pages to CE"](https://about.gitlab.com/releases/2016/12/24/were-bringing-gitlab-pages-to-community-edition/)
-- Announcement (2017-03-06): ["We are changing the IP of GitLab Pages on GitLab.com"](https://about.gitlab.com/releases/2017/03/06/we-are-changing-the-ip-of-gitlab-pages-on-gitlab-com/)
+<i class="fa fa-youtube-play youtube" aria-hidden="true"></i> Watch a [video tutorial](https://www.youtube.com/watch?v=dD8c7WNcc6s) about how to get started with GitLab Pages administration.
diff --git a/doc/user/project/pages/introduction.md b/doc/user/project/pages/introduction.md
index e36dfd89ab3..614a0d0dd19 100644
--- a/doc/user/project/pages/introduction.md
+++ b/doc/user/project/pages/introduction.md
@@ -25,7 +25,7 @@ In brief, this is what you need to upload your website in GitLab Pages:
1. Domain of the instance: domain name that is used for GitLab Pages
(ask your administrator).
1. GitLab CI/CD: a `.gitlab-ci.yml` file with a specific job named [`pages`](../../../ci/yaml/README.md#pages) in the root directory of your repository.
-1. A directory called `public` in your site's repo containing the content
+1. A directory called `public` in your site's repository containing the content
to be published.
1. GitLab Runner enabled for the project.
@@ -87,7 +87,7 @@ will be deleted.
When using Pages under the general domain of a GitLab instance (`*.example.io`),
you _cannot_ use HTTPS with sub-subdomains. That means that if your
-username/groupname contains a dot, for example `foo.bar`, the domain
+username or group name contains a dot, for example `foo.bar`, the domain
`https://foo.bar.example.io` will _not_ work. This is a limitation of the
[HTTP Over TLS protocol](https://tools.ietf.org/html/rfc2818#section-3.1). HTTP pages will continue to work provided you
don't redirect HTTP to HTTPS.
@@ -217,7 +217,7 @@ needing to compress files on-demand.
### Resolving ambiguous URLs
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-pages/issues/95) in GitLab 11.8
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/95) in GitLab 11.8
GitLab Pages makes assumptions about which files to serve when receiving a
request for a URL that does not include an extension.
diff --git a/doc/user/project/pages/lets_encrypt_for_gitlab_pages.md b/doc/user/project/pages/lets_encrypt_for_gitlab_pages.md
index 33181828fb2..d86704eb703 100644
--- a/doc/user/project/pages/lets_encrypt_for_gitlab_pages.md
+++ b/doc/user/project/pages/lets_encrypt_for_gitlab_pages.md
@@ -105,7 +105,7 @@ operating systems the steps might be slightly different. Follow the
therefore, it needs to be part of the website content under the
repo's [`public`](index.md#how-it-works) folder.
-1. Add, commit, and push the file into your repo in GitLab. Once the pipeline
+1. Add, commit, and push the file into your repository in GitLab. Once the pipeline
passes, press **Enter** on your terminal to continue issuing your
certificate. CertBot will then prompt you with the following message:
diff --git a/doc/user/project/pages/pages_access_control.md b/doc/user/project/pages/pages_access_control.md
index 7fe4c4c051d..6fcad0a5357 100644
--- a/doc/user/project/pages/pages_access_control.md
+++ b/doc/user/project/pages/pages_access_control.md
@@ -7,7 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# GitLab Pages Access Control
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/33422) in GitLab 11.5.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/33422) in GitLab 11.5.
> - Available on GitLab.com in GitLab 12.4.
You can enable Pages access control on your project, so that only
diff --git a/doc/user/project/protected_branches.md b/doc/user/project/protected_branches.md
index e2ee0dd47fe..d0baf57f169 100644
--- a/doc/user/project/protected_branches.md
+++ b/doc/user/project/protected_branches.md
@@ -2,7 +2,7 @@
type: reference, howto
---
-# Protected Branches
+# Protected branches
[Permissions](../permissions.md) in GitLab are fundamentally defined around the
idea of having read or write permission to the repository and branches. To impose
@@ -114,7 +114,7 @@ all matching branches:
## Creating a protected branch
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/53361) in GitLab 11.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53361) in GitLab 11.9.
When a protected branch or wildcard protected branches are set to
[**No one** is **Allowed to push**](#using-the-allowed-to-merge-and-allowed-to-push-settings),
@@ -134,7 +134,7 @@ To create a new branch through the user interface:
## Deleting a protected branch
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/21393) in GitLab 9.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/21393) in GitLab 9.3.
From time to time, it may be required to delete or clean up branches that are
protected.
@@ -155,7 +155,7 @@ command line or a Git client application.
## Protected Branches approval by Code Owners **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/13251) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13251) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.4.
It is possible to require at least one approval by a
[Code Owner](code_owners.md) to a file changed by the
@@ -194,11 +194,11 @@ for details about the pipelines security model.
**11.9**
-- [Allow protected branches to be created](https://gitlab.com/gitlab-org/gitlab-foss/issues/53361) by Developers (and users with higher permission levels) through the API and the user interface.
+- [Allow protected branches to be created](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53361) by Developers (and users with higher permission levels) through the API and the user interface.
**9.2**
-- Allow deletion of protected branches via the web interface ([issue #21393](https://gitlab.com/gitlab-org/gitlab-foss/issues/21393)).
+- Allow deletion of protected branches via the web interface ([issue #21393](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/21393)).
**8.11**
diff --git a/doc/user/project/protected_tags.md b/doc/user/project/protected_tags.md
index b134d283ba9..e80b8098bec 100644
--- a/doc/user/project/protected_tags.md
+++ b/doc/user/project/protected_tags.md
@@ -2,13 +2,13 @@
type: reference, howto
---
-# Protected Tags
+# Protected tags
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10356) in GitLab 9.1.
-Protected Tags allow control over who has permission to create tags as well as preventing accidental update or deletion once created. Each rule allows you to match either an individual tag name, or use wildcards to control multiple tags at once.
+Protected tags allow control over who has permission to create tags as well as preventing accidental update or deletion once created. Each rule allows you to match either an individual tag name, or use wildcards to control multiple tags at once.
-This feature evolved out of [Protected Branches](protected_branches.md)
+This feature evolved out of [protected branches](protected_branches.md)
## Overview
diff --git a/doc/user/project/push_options.md b/doc/user/project/push_options.md
index eab88d59867..ca658c06647 100644
--- a/doc/user/project/push_options.md
+++ b/doc/user/project/push_options.md
@@ -36,7 +36,7 @@ You can use push options to skip a CI/CD pipeline, or pass environment variables
| Push option | Description | Introduced in version |
| ------------------------------ | ------------------------------------------------------------------------------------------- |---------------------- |
| `ci.skip` | Do not create a CI pipeline for the latest push. | [11.7](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/15643) |
-| `ci.variable="<name>=<value>"` | Provide [environment variables](../../ci/variables/README.md) to be used in a CI pipeline, if one is created due to the push. | [12.6](https://gitlab.com/gitlab-org/gitlab/issues/27983) |
+| `ci.variable="<name>=<value>"` | Provide [environment variables](../../ci/variables/README.md) to be used in a CI pipeline, if one is created due to the push. | [12.6](https://gitlab.com/gitlab-org/gitlab/-/issues/27983) |
An example of using `ci.skip`:
@@ -60,9 +60,9 @@ time as pushing changes:
| `merge_request.create` | Create a new merge request for the pushed branch. | [11.10](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/26752) |
| `merge_request.target=<branch_name>` | Set the target of the merge request to a particular branch. | [11.10](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/26752) |
| `merge_request.merge_when_pipeline_succeeds` | Set the merge request to [merge when its pipeline succeeds](merge_requests/merge_when_pipeline_succeeds.md). | [11.10](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/26752) |
-| `merge_request.remove_source_branch` | Set the merge request to remove the source branch when it's merged. | [12.2](https://gitlab.com/gitlab-org/gitlab-foss/issues/64320) |
-| `merge_request.title="<title>"` | Set the title of the merge request. Ex: `git push -o merge_request.title="The title I want"`. | [12.2](https://gitlab.com/gitlab-org/gitlab-foss/issues/64320) |
-| `merge_request.description="<description>"` | Set the description of the merge request. Ex: `git push -o merge_request.description="The description I want"`. | [12.2](https://gitlab.com/gitlab-org/gitlab-foss/issues/64320) |
+| `merge_request.remove_source_branch` | Set the merge request to remove the source branch when it's merged. | [12.2](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/64320) |
+| `merge_request.title="<title>"` | Set the title of the merge request. Ex: `git push -o merge_request.title="The title I want"`. | [12.2](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/64320) |
+| `merge_request.description="<description>"` | Set the description of the merge request. Ex: `git push -o merge_request.description="The description I want"`. | [12.2](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/64320) |
| `merge_request.label="<label>"` | Add labels to the merge request. If the label does not exist, it will be created. For example, for two labels: `git push -o merge_request.label="label1" -o merge_request.label="label2"`. | [12.3](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/31831) |
| `merge_request.unlabel="<label>"` | Remove labels from the merge request. For example, for two labels: `git push -o merge_request.unlabel="label1" -o merge_request.unlabel="label2"`. | [12.3](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/31831) |
diff --git a/doc/user/project/quick_actions.md b/doc/user/project/quick_actions.md
index e2d0b616e4b..a3df173bd9d 100644
--- a/doc/user/project/quick_actions.md
+++ b/doc/user/project/quick_actions.md
@@ -1,5 +1,8 @@
---
type: reference
+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/#designated-technical-writers
---
# GitLab Quick Actions
@@ -10,7 +13,8 @@ You can enter these commands while creating a new issue or merge request, or
in comments of issues, epics, merge requests, and commits. Each command should be
on a separate line in order to be properly detected and executed.
-> From [GitLab 12.1](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/26672), once an action is executed, an alert is displayed when a quick action is successfully applied.
+> From [GitLab 12.1](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/26672), once an
+> action is executed, an alert appears when a quick action is successfully applied.
## Quick Actions for issues, merge requests and epics
@@ -18,63 +22,66 @@ The following quick actions are applicable to descriptions, discussions and thre
- Issues
- Merge requests
-- Epics **(ULTIMATE)**
-
-| Command | Issue | Merge request | Epic | Action |
-|:--------------------------------------|:------|:--------------|:-----|:------ |
-| `/tableflip <comment>` | ✓ | ✓ | ✓ | Append the comment with `(╯°□°)╯︵ â”»â”â”»` |
-| `/shrug <comment>` | ✓ | ✓ | ✓ | Append the comment with `¯\_(ツ)_/¯` |
-| `/todo` | ✓ | ✓ | ✓ | Add a To Do |
-| `/done` | ✓ | ✓ | ✓ | Mark To Do as done |
-| `/subscribe` | ✓ | ✓ | ✓ | Subscribe |
-| `/unsubscribe` | ✓ | ✓ | ✓ | Unsubscribe |
-| `/close` | ✓ | ✓ | ✓ | Close |
-| `/reopen` | ✓ | ✓ | ✓ | Reopen |
-| `/title <new title>` | ✓ | ✓ | ✓ | Change title |
-| `/award :emoji:` | ✓ | ✓ | ✓ | Toggle emoji award |
-| `/assign me` | ✓ | ✓ | | Assign yourself |
-| `/assign @user` | ✓ | ✓ | | Assign one user |
-| `/assign @user1 @user2` | ✓ | ✓ | | Assign multiple users **(STARTER)** |
-| `/reassign @user1 @user2` | ✓ | ✓ | | Change assignee **(STARTER)** |
-| `/unassign` | ✓ | ✓ | | Remove current assignee |
-| `/unassign @user1 @user2` | ✓ | ✓ | | Remove assignee(s) **(STARTER)** |
-| `/milestone %milestone` | ✓ | ✓ | | Set milestone |
-| `/remove_milestone` | ✓ | ✓ | | Remove milestone |
-| `/label ~label1 ~label2` | ✓ | ✓ | ✓ | Add label(s). Label names can also start without `~` but mixed syntax is not supported |
-| `/relabel ~label1 ~label2` | ✓ | ✓ | ✓ | Replace existing label(s) with those specified |
-| `/unlabel ~label1 ~label2` or `/remove_label ~label1 ~label2` | ✓ | ✓ | ✓ | Remove all or specific label(s) |
-| `/copy_metadata <#issue>` | ✓ | ✓ | | Copy labels and milestone from another issue in the project |
-| `/copy_metadata <!merge_request>` | ✓ | ✓ | | Copy labels and milestone from another merge request in the project |
-| `/estimate <<W>w <DD>d <hh>h <mm>m>` | ✓ | ✓ | | Set time estimate. For example, `/estimate 1w 3d 2h 14m` |
-| `/remove_estimate` | ✓ | ✓ | | Remove time estimate |
-| `/spend <time(<h>h <mm>m)> <date(<YYYY-MM-DD>)>` | ✓ | ✓ | | Add spent time; optionally specify the date that time was spent on. For example, `/spend time(1h 30m)` or `/spend time(1h 30m) date(2018-08-26)` |
-| `/spend <time(-<h>h <mm>m)> <date(<YYYY-MM-DD>)>` | ✓ | ✓ | | Subtract spent time; optionally specify the date that time was spent on. For example, `/spend time(-1h 30m)` or `/spend time(-1h 30m) date(2018-08-26)` |
-| `/remove_time_spent` | ✓ | ✓ | | Remove time spent |
-| `/lock` | ✓ | ✓ | | Lock the thread |
-| `/unlock` | ✓ | ✓ | | Unlock the thread |
-| `/due <date>` | ✓ | | | Set due date. Examples of valid `<date>` include `in 2 days`, `this Friday` and `December 31st` |
-| `/remove_due_date` | ✓ | | | Remove due date |
-| `/weight <value>` | ✓ | | | Set weight. Valid options for `<value>` include `0`, `1`, `2`, etc **(STARTER)** |
-| `/clear_weight` | ✓ | | | Clear weight **(STARTER)** |
-| `/epic <epic>` | ✓ | | | Add to epic `<epic>`. The `<epic>` value should be in the format of `&epic`, `group&epic`, or a URL to an epic. **(ULTIMATE)** |
-| `/remove_epic` | ✓ | | | Remove from epic **(ULTIMATE)** |
-| `/promote` | ✓ | | | Promote issue to epic **(ULTIMATE)** |
-| `/confidential` | ✓ | | | Make confidential |
-| `/duplicate <#issue>` | ✓ | | | Mark this issue as a duplicate of another issue and relate them for **(STARTER)** |
-| `/create_merge_request <branch name>` | ✓ | | | Create a new merge request starting from the current issue |
-| `/relate #issue1 #issue2` | ✓ | | | Mark issues as related **(STARTER)** |
-| `/move <path/to/project>` | ✓ | | | Move this issue to another project |
-| `/zoom <Zoom URL>` | ✓ | | | Add Zoom meeting to this issue. ([Introduced in GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/16609)) |
-| `/remove_zoom` | ✓ | | | Remove Zoom meeting from this issue. ([Introduced in GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/16609)) |
-| `/target_branch <local branch name>` | | ✓ | | Set target branch |
-| `/wip` | | ✓ | | Toggle the Work In Progress status |
-| `/approve` | | ✓ | | Approve the merge request **(STARTER)** |
-| `/submit_review` | | ✓ | | Submit a pending review. ([Introduced in GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/issues/8041)) **(PREMIUM)** |
-| `/merge` | | ✓ | | Merge changes. Depending on the project setting, this may be [when the pipeline succeeds](merge_requests/merge_when_pipeline_succeeds.md), adding to a [Merge Train](../../ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.md), etc). |
-| `/child_epic <epic>` | | | ✓ | Add child epic to `<epic>`. The `<epic>` value should be in the format of `&epic`, `group&epic`, or a URL to an epic. ([Introduced in GitLab 12.0](https://gitlab.com/gitlab-org/gitlab/issues/7330)) **(ULTIMATE)** |
-| `/remove_child_epic <epic>` | | | ✓ | Remove child epic from `<epic>`. The `<epic>` value should be in the format of `&epic`, `group&epic`, or a URL to an epic. ([Introduced in GitLab 12.0](https://gitlab.com/gitlab-org/gitlab/issues/7330)) **(ULTIMATE)** |
-| `/parent_epic <epic>` | | | ✓ | Set parent epic to `<epic>`. The `<epic>` value should be in the format of `&epic`, `group&epic`, or a URL to an epic. ([introduced in GitLab 12.1](https://gitlab.com/gitlab-org/gitlab/issues/10556)) **(ULTIMATE)** |
-| `/remove_parent_epic` | | | ✓ | Remove parent epic from epic ([introduced in GitLab 12.1](https://gitlab.com/gitlab-org/gitlab/issues/10556)) **(ULTIMATE)** |
+- Epics **(PREMIUM)**
+
+| Command | Issue | Merge request | Epic | Action |
+| :------------------------------------ | :---- | :------------ | :--- | :------------------------------------------------------------------------------------------------------------------------------ |
+| `/approve` | | ✓ | | Approve the merge request. **(STARTER)** |
+| `/assign @user` | ✓ | ✓ | | Assign one user. |
+| `/assign @user1 @user2` | ✓ | ✓ | | Assign multiple users. **(STARTER)** |
+| `/assign me` | ✓ | ✓ | | Assign yourself. |
+| `/award :emoji:` | ✓ | ✓ | ✓ | Toggle emoji award. |
+| `/child_epic <epic>` | | | ✓ | Add child epic to `<epic>`. The `<epic>` value should be in the format of `&epic`, `group&epic`, or a URL to an epic ([introduced in GitLab 12.0](https://gitlab.com/gitlab-org/gitlab/-/issues/7330)). **(ULTIMATE)** |
+| `/clear_weight` | ✓ | | | Clear weight. **(STARTER)** |
+| `/close` | ✓ | ✓ | ✓ | Close. |
+| `/confidential` | ✓ | | | Make confidential. |
+| `/copy_metadata <!merge_request>` | ✓ | ✓ | | Copy labels and milestone from another merge request in the project. |
+| `/copy_metadata <#issue>` | ✓ | ✓ | | Copy labels and milestone from another issue in the project. |
+| `/create_merge_request <branch name>` | ✓ | | | Create a new merge request starting from the current issue. |
+| `/done` | ✓ | ✓ | ✓ | Mark To-Do as done. |
+| `/due <date>` | ✓ | | | Set due date. Examples of valid `<date>` include `in 2 days`, `this Friday` and `December 31st`. |
+| `/duplicate <#issue>` | ✓ | | | Mark this issue as a duplicate of another issue and mark them as related. **(STARTER)** |
+| `/epic <epic>` | ✓ | | | Add to epic `<epic>`. The `<epic>` value should be in the format of `&epic`, `group&epic`, or a URL to an epic. **(PREMIUM)** |
+| `/estimate <<W>w <DD>d <hh>h <mm>m>` | ✓ | ✓ | | Set time estimate. For example, `/estimate 1w 3d 2h 14m`. |
+| `/iteration *iteration:iteration` | ✓ | | | Set iteration ([Introduced in GitLab 13.1](https://gitlab.com/gitlab-org/gitlab/-/issues/196795)) **(STARTER)** |
+| `/label ~label1 ~label2` | ✓ | ✓ | ✓ | Add one or more labels. Label names can also start without a tilde (`~`), but mixed syntax is not supported. |
+| `/lock` | ✓ | ✓ | | Lock the thread. |
+| `/merge` | | ✓ | | Merge changes. Depending on the project setting, this may be [when the pipeline succeeds](merge_requests/merge_when_pipeline_succeeds.md), adding to a [Merge Train](../../ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.md), etc. |
+| `/milestone %milestone` | ✓ | ✓ | | Set milestone. |
+| `/move <path/to/project>` | ✓ | | | Move this issue to another project. |
+| `/parent_epic <epic>` | | | ✓ | Set parent epic to `<epic>`. The `<epic>` value should be in the format of `&epic`, `group&epic`, or a URL to an epic ([introduced in GitLab 12.1](https://gitlab.com/gitlab-org/gitlab/-/issues/10556)). **(ULTIMATE)** |
+| `/promote` | ✓ | | | Promote issue to epic. **(PREMIUM)** |
+| `/publish` | ✓ | | | Publish issue to an associated [Status Page](status_page/index.md) ([Introduced in GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30906)) **(ULTIMATE)** |
+| `/reassign @user1 @user2` | ✓ | ✓ | | Change assignee. **(STARTER)** |
+| `/relabel ~label1 ~label2` | ✓ | ✓ | ✓ | Replace existing labels with those specified. |
+| `/relate #issue1 #issue2` | ✓ | | | Mark issues as related. **(STARTER)** |
+| `/remove_child_epic <epic>` | | | ✓ | Remove child epic from `<epic>`. The `<epic>` value should be in the format of `&epic`, `group&epic`, or a URL to an epic ([introduced in GitLab 12.0](https://gitlab.com/gitlab-org/gitlab/-/issues/7330)). **(ULTIMATE)** |
+| `/remove_due_date` | ✓ | | | Remove due date. |
+| `/remove_epic` | ✓ | | | Remove from epic. **(PREMIUM)** |
+| `/remove_estimate` | ✓ | ✓ | | Remove time estimate. |
+| `/remove_iteration` | ✓ | | | Remove iteration ([Introduced in GitLab 13.1](https://gitlab.com/gitlab-org/gitlab/-/issues/196795)) **(STARTER)** |
+| `/remove_milestone` | ✓ | ✓ | | Remove milestone. |
+| `/remove_parent_epic` | | | ✓ | Remove parent epic from epic ([introduced in GitLab 12.1](https://gitlab.com/gitlab-org/gitlab/-/issues/10556)). **(ULTIMATE)** |
+| `/remove_time_spent` | ✓ | ✓ | | Remove time spent. |
+| `/remove_zoom` | ✓ | | | Remove Zoom meeting from this issue ([introduced in GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/16609)). |
+| `/reopen` | ✓ | ✓ | ✓ | Reopen. |
+| `/shrug <comment>` | ✓ | ✓ | ✓ | Append the comment with `¯\_(ツ)_/¯`. |
+| `/spend <time(-<h>h <mm>m)> <date(<YYYY-MM-DD>)>` | ✓ | ✓ | | Subtract spent time. Optionally, specify the date that time was spent on. For example, `/spend time(-1h 30m)` or `/spend time(-1h 30m) date(2018-08-26)`. |
+| `/spend <time(<h>h <mm>m)> <date(<YYYY-MM-DD>)>` | ✓ | ✓ | | Add spent time. Optionally, specify the date that time was spent on. For example, `/spend time(1h 30m)` or `/spend time(1h 30m) date(2018-08-26)`. |
+| `/submit_review` | | ✓ | | Submit a pending review ([introduced in GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/issues/8041)). **(PREMIUM)** |
+| `/subscribe` | ✓ | ✓ | ✓ | Subscribe to notifications. |
+| `/tableflip <comment>` | ✓ | ✓ | ✓ | Append the comment with `(╯°□°)╯︵ â”»â”â”»`. |
+| `/target_branch <local branch name>` | | ✓ | | Set target branch. |
+| `/title <new title>` | ✓ | ✓ | ✓ | Change title. |
+| `/todo` | ✓ | ✓ | ✓ | Add a To-Do. |
+| `/unassign @user1 @user2` | ✓ | ✓ | | Remove specific assignees. **(STARTER)** |
+| `/unassign` | ✓ | ✓ | | Remove all assignees. |
+| `/unlabel ~label1 ~label2` or `/remove_label ~label1 ~label2` | ✓ | ✓ | ✓ | Remove all or specific labels. |
+| `/unlock` | ✓ | ✓ | | Unlock the thread. |
+| `/unsubscribe` | ✓ | ✓ | ✓ | Unsubscribe from notifications. |
+| `/weight <value>` | ✓ | | | Set weight. Valid options for `<value>` include `0`, `1`, `2`, and so on. **(STARTER)** |
+| `/wip` | | ✓ | | Toggle the Work In Progress status. |
+| `/zoom <Zoom URL>` | ✓ | | | Add Zoom meeting to this issue ([introduced in GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/16609)). |
## Autocomplete characters
@@ -86,11 +93,11 @@ to enter a parameter, compared to selecting items from a list.
The easiest way to set parameters for quick actions is to use autocomplete. If
you manually enter a parameter, it must be enclosed in double quotation marks
-(`"`), unless it contains only:
+(`"`), unless it contains only these characters:
1. ASCII letters.
-1. Numerals.
-1. Underscore, hyphen, question mark, dot, and ampersand.
+1. Numerals (0-9).
+1. Underscore (`_`), hyphen (`-`), question mark (`?`), dot (`.`), or ampersand (`&`).
Parameters are also case-sensitive. Autocomplete handles this, and the insertion
of quotation marks, automatically.
@@ -100,7 +107,7 @@ of quotation marks, automatically.
The following quick actions are applicable for commit messages:
| Command | Action |
-|:------------------------|:------------------------------------------|
+| :---------------------- | :---------------------------------------- |
| `/tag v1.2.3 <message>` | Tags this commit with an optional message |
<!-- ## Troubleshooting
diff --git a/doc/user/project/releases/index.md b/doc/user/project/releases/index.md
index bdb99d16625..58d143fb32b 100644
--- a/doc/user/project/releases/index.md
+++ b/doc/user/project/releases/index.md
@@ -7,7 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Releases
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/41766) in GitLab 11.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41766) in GitLab 11.7.
It is typical to create a [Git tag](../../../university/training/topics/tags.md) at
the moment of release to introduce a checkpoint in your source code
@@ -67,9 +67,11 @@ A link is any URL which can point to whatever you like; documentation, built
binaries, or other related materials. These can be both internal or external
links from your GitLab instance.
+The four types of links are "Runbook," "Package," "Image," and "Other."
+
#### Permanent links to Release assets
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/27300) in GitLab 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27300) in GitLab 12.9.
The assets associated with a Release are accessible through a permanent URL.
GitLab will always redirect this URL to the actual asset
@@ -105,7 +107,7 @@ The physical location of the asset can change at any time and the direct link wi
### Releases associated with milestones
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/29020) in GitLab 12.5.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/29020) in GitLab 12.5.
> - [Updated](https://gitlab.com/gitlab-org/gitlab/-/issues/39467) to edit milestones in the UI in GitLab 13.0.
Releases can optionally be associated with one or more
@@ -141,7 +143,7 @@ project.
### Number of Releases
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/36667) in GitLab 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/36667) in GitLab 12.8.
The incremental number of Releases is displayed on the project's details page. When clicked,
it takes you to the list of Releases.
@@ -154,7 +156,7 @@ it is displayed to every user regardless of their permission level.
### Upcoming Releases
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/38105) in GitLab 12.1.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/38105) in GitLab 12.1.
A Release may be created ahead of time by specifying a future `released_at` date. Until
the `released_at` date and time is reached, an **Upcoming Release** badge will appear next to the
@@ -186,7 +188,7 @@ we recommend doing this as one of the last steps in your CI/CD release pipeline.
## Editing a release
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/26016) in GitLab 12.6. Asset link editing was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9427) in GitLab 12.10.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/26016) in GitLab 12.6. Asset link editing was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9427) in GitLab 12.10.
To edit the details of a release, navigate to **Project overview > Releases** and click
the edit button (pencil icon) in the top-right corner of the release you want to modify.
@@ -205,7 +207,7 @@ through the **Edit Release** page is planned for a future version of GitLab.
## Notification for Releases
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/26001) in GitLab 12.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/26001) in GitLab 12.4.
You can be notified by email when a new Release is created for your project.
@@ -243,7 +245,7 @@ You can also edit an existing tag to add release notes:
## Release Evidence
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/26019) in GitLab 12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/26019) in GitLab 12.6.
Each time a release is created, GitLab takes a snapshot of data that's related to it.
This data is called Release Evidence. It includes linked milestones and issues, and
@@ -256,7 +258,7 @@ can have multiple Release Evidence snapshots. You can view the Release Evidence
its details on the Release page.
NOTE: **Note:**
-When the issue tracker is disabled, release evidence [is not collected](https://gitlab.com/gitlab-org/gitlab/-/issues/208397).
+When the issue tracker is disabled, release evidence [cannot be downloaded](https://gitlab.com/gitlab-org/gitlab/-/issues/208397).
Release Evidence is stored as a JSON object, so you can compare evidence by using
commonly-available tools.
@@ -267,11 +269,16 @@ Here is an example of a Release Evidence object:
{
"release": {
"id": 5,
- "tag": "v4.0",
+ "tag_name": "v4.0",
"name": "New release",
- "project_id": 45,
- "project_name": "Project name",
- "released_at": "2019-06-28 13:23:40 UTC",
+ "project": {
+ "id": 20,
+ "name": "Project name",
+ "created_at": "2019-04-14T11:12:13.940Z",
+ "description": "Project description"
+ },
+ "created_at": "2019-06-28 13:23:40 UTC",
+ "description": "Release description",
"milestones": [
{
"id": 11,
@@ -311,7 +318,7 @@ Here is an example of a Release Evidence object:
}
```
-### Enabling Release Evidence display **(CORE ONLY)**
+### Diabling Release Evidence display **(CORE ONLY)**
This feature comes with the `:release_evidence_collection` feature flag
enabled by default in GitLab self-managed instances. To turn it off,
@@ -393,6 +400,8 @@ deploy_to_production:
- if: $CI_DEPLOY_FREEZE == null
```
+For more information, see [Deployment safety](../../../ci/environments/deployment_safety.md).
+
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
diff --git a/doc/user/project/repository/forking_workflow.md b/doc/user/project/repository/forking_workflow.md
index a49701017f3..75a84e36169 100644
--- a/doc/user/project/repository/forking_workflow.md
+++ b/doc/user/project/repository/forking_workflow.md
@@ -46,7 +46,7 @@ You can use [repository mirroring](repository_mirroring.md) to keep your fork sy
The main difference is that with repository mirroring your remote fork will be automatically kept up-to-date.
-Without mirroring, to work locally you'll have to use `git pull` to update your local repo
+Without mirroring, to work locally you'll have to use `git pull` to update your local repository
with the upstream project, then push the changes back to your fork to update it.
CAUTION: **Caution:**
diff --git a/doc/user/project/repository/git_blame.md b/doc/user/project/repository/git_blame.md
index 2deb53b313c..e63b57747ef 100644
--- a/doc/user/project/repository/git_blame.md
+++ b/doc/user/project/repository/git_blame.md
@@ -25,7 +25,7 @@ for that commit.
## Blame previous commit
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/19299) in GitLab 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/19299) in GitLab 12.7.
To see earlier revisions of a specific line, click **View blame prior to this change**
until you've found the changes you're interested in viewing:
diff --git a/doc/user/project/repository/img/repository_cleanup.png b/doc/user/project/repository/img/repository_cleanup.png
deleted file mode 100644
index e343f23ac27..00000000000
--- a/doc/user/project/repository/img/repository_cleanup.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/repository/index.md b/doc/user/project/repository/index.md
index 055443daa1f..48975b7864e 100644
--- a/doc/user/project/repository/index.md
+++ b/doc/user/project/repository/index.md
@@ -27,7 +27,7 @@ that you [connect with GitLab via SSH](../../../ssh/README.md).
## Files
-Use a repository to store your files in GitLab. From [GitLab 12.10 onwards](https://gitlab.com/gitlab-org/gitlab/issues/33806),
+Use a repository to store your files in GitLab. In [GitLab 12.10 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/33806),
you'll see on the repository's file tree an icon next to the file name
according to its extension:
@@ -84,9 +84,9 @@ according to the markup language.
| [AsciiDoc](../../asciidoc.md) | `adoc`, `ad`, `asciidoc` |
| [Textile](https://textile-lang.com/) | `textile` |
| [rdoc](http://rdoc.sourceforge.net/doc/index.html) | `rdoc` |
-| [Orgmode](https://orgmode.org/) | `org` |
+| [Org mode](https://orgmode.org/) | `org` |
| [creole](http://www.wikicreole.org/) | `creole` |
-| [Mediawiki](https://www.mediawiki.org/wiki/MediaWiki) | `wiki`, `mediawiki` |
+| [MediaWiki](https://www.mediawiki.org/wiki/MediaWiki) | `wiki`, `mediawiki` |
### Repository README and index files
@@ -116,7 +116,7 @@ user's sessions and include code, narrative text, equations, and rich output.
### OpenAPI viewer
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/19515) in GitLab 12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/19515) in GitLab 12.6.
GitLab can render OpenAPI specification files with its file viewer, provided
their filenames include `openapi` or `swagger` and their extension is `yaml`,
@@ -219,7 +219,9 @@ vendored code, and most markup languages are excluded. This behavior can be
adjusted by overriding the default. For example, to enable `.proto` files to be
detected, add the following to `.gitattributes` in the root of your repository.
-> *.proto linguist-detectable=true
+```plaintext
+*.proto linguist-detectable=true
+```
## Locked files **(PREMIUM)**
@@ -232,7 +234,7 @@ You can access your repos via [repository API](../../../api/repositories.md).
## Clone in Apple Xcode
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/45820) in GitLab 11.0
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/45820) in GitLab 11.0
Projects that contain a `.xcodeproj` or `.xcworkspace` directory can now be cloned
in Xcode using the new **Open in Xcode** button, located next to the Git URL
@@ -240,7 +242,7 @@ used for cloning your project. The button is only shown on macOS.
## Download Source Code
-> Support for directory download was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/24704) in GitLab 11.11.
+> Support for directory download was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/24704) in GitLab 11.11.
The source code stored in a repository can be downloaded from the UI.
By clicking the download icon, a dropdown will open with links to download the following:
diff --git a/doc/user/project/repository/jupyter_notebooks/index.md b/doc/user/project/repository/jupyter_notebooks/index.md
index ca82be280d9..1948b12aacd 100644
--- a/doc/user/project/repository/jupyter_notebooks/index.md
+++ b/doc/user/project/repository/jupyter_notebooks/index.md
@@ -1,6 +1,6 @@
# Jupyter Notebook Files
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/2508/) in GitLab 9.1.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/2508/) in GitLab 9.1.
[Jupyter](https://jupyter.org/) Notebook (previously IPython Notebook) files are used for
interactive computing in many fields and contain a complete record of the
diff --git a/doc/user/project/repository/reducing_the_repo_size_using_git.md b/doc/user/project/repository/reducing_the_repo_size_using_git.md
index 16bffe5417d..124150c441a 100644
--- a/doc/user/project/repository/reducing_the_repo_size_using_git.md
+++ b/doc/user/project/repository/reducing_the_repo_size_using_git.md
@@ -1,150 +1,244 @@
---
+stage: Create
+group: Gitaly
+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: howto
---
-# Reducing the repository size using Git
-
-A GitLab Enterprise Edition administrator can set a [repository size limit](../../admin_area/settings/account_and_limit_settings.md)
-which will prevent you from exceeding it.
-
-When a project has reached its size limit, you will not be able to push to it,
-create a new merge request, or merge existing ones. You will still be able to
-create new issues, and clone the project though. Uploading LFS objects will
-also be denied.
-
-If you exceed the repository size limit, your first thought might be to remove
-some data, make a new commit and push back to the repository. Perhaps you can
-move some blobs to LFS, or remove some old dependency updates from history.
-Unfortunately, it's not so easy and that workflow won't work. Deleting files in
-a commit doesn't actually reduce the size of the repo since the earlier commits
-and blobs are still around. What you need to do is rewrite history with Git's
-[`filter-branch` option](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History#The-Nuclear-Option:-filter-branch),
-or an open source community-maintained tool like the
-[BFG](https://rtyley.github.io/bfg-repo-cleaner/).
-
-Note that even with that method, until `git gc` runs on the GitLab side, the
-"removed" commits and blobs will still be around. You also need to be able to
-push the rewritten history to GitLab, which may be impossible if you've already
-exceeded the maximum size limit.
+# Reduce repository size
-In order to lift these restrictions, the administrator of the GitLab instance
-needs to increase the limit on the particular project that exceeded it, so it's
-always better to spot that you're approaching the limit and act proactively to
-stay underneath it. If you hit the limit, and your admin can't - or won't -
-temporarily increase it for you, your only option is to prune all the unneeded
-stuff locally, and then create a new project on GitLab and start using that
-instead.
+Git repositories become larger over time. When large files are added to a Git repository:
-If you can continue to use the original project, we recommend [using
-BFG](#using-the-bfg-repo-cleaner), a tool that's built and
-maintained by the open source community. It's faster and simpler than
-`git filter-branch`, and GitLab can use its account of what has changed to clean
-up its own internal state, maximizing the space saved.
+- Fetching the repository becomes slower because everyone must download the files.
+- They take up a large amount of storage space on the server.
+- Git repository storage limits [can be reached](#storage-limits).
-CAUTION: **Caution:**
-Make sure to first make a copy of your repository since rewriting history will
-purge the files and information you are about to delete. Also make sure to
-inform any collaborators to not use `pull` after your changes, but use `rebase`.
+Rewriting a repository can remove unwanted history to make the repository smaller.
+[`git filter-repo`](https://github.com/newren/git-filter-repo) is a tool for quickly rewriting Git
+repository history, and is recommended over both:
-CAUTION: **Caution:**
-This process is not suitable for removing sensitive data like password or keys
-from your repository. Information about commits, including file content, is
-cached in the database, and will remain visible even after they have been
-removed from the repository.
+- [`git filter-branch`](https://git-scm.com/docs/git-filter-branch).
+- [BFG](https://rtyley.github.io/bfg-repo-cleaner/).
+
+DANGER: **Danger:**
+Rewriting repository history is a destructive operation. Make sure to backup your repository before
+you begin. The best way back up a repository is to
+[export the project](../settings/import_export.md#exporting-a-project-and-its-data).
-## Using the BFG Repo-Cleaner
+## Purge files from repository history
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/19376) in GitLab 11.6.
+To make cloning your project faster, rewrite branches and tags to remove unwanted files.
-1. [Install BFG](https://rtyley.github.io/bfg-repo-cleaner/) from its open source community repository.
+1. [Install `git filter-repo`](https://github.com/newren/git-filter-repo/blob/master/INSTALL.md)
+ using a supported package manager or from source.
-1. Navigate to your repository:
+1. Clone a fresh copy of the repository using `--bare`:
```shell
- cd my_repository/
+ git clone --bare https://example.gitlab.com/my/project.git
```
-1. Change to the branch you want to remove the big file from:
+1. Using `git filter-repo`, purge any files from the history of your repository.
+
+ To purge all large files, the `--strip-blobs-bigger-than` option can be used:
```shell
- git checkout master
+ git filter-repo --strip-blobs-bigger-than 10M
```
-1. Create a commit removing the large file from the branch, if it still exists:
+ To purge specific large files by path, the `--path` and `--invert-paths` options can be combined:
```shell
- git rm path/to/big_file.mpg
- git commit -m 'Remove unneeded large file'
+ git filter-repo --path path/to/big/file.m4v --invert-paths
```
-1. Rewrite history:
+ See the
+ [`git filter-repo` documentation](https://htmlpreview.github.io/?https://github.com/newren/git-filter-repo/blob/docs/html/git-filter-repo.html#EXAMPLES)
+ for more examples and the complete documentation.
+
+1. Running `git filter-repo` removes all remotes. To restore the remote for your project, run:
```shell
- bfg --delete-files path/to/big_file.mpg
+ git remote add origin https://example.gitlab.com/<namespace>/<project_name>.git
```
- An object map file will be written to `object-id-map.old-new.txt`. Keep it
- around - you'll need it for the final step!
+1. Force push your changes to overwrite all branches on GitLab:
-1. Force-push the changes to GitLab:
+ ```shell
+ git push origin --force --all
+ ```
+
+ [Protected branches](../protected_branches.md) will cause this to fail. To proceed, you must
+ remove branch protection, push, and then re-enable protected branches.
+
+1. To remove large files from tagged releases, force push your changes to all tags on GitLab:
```shell
- git push --force-with-lease origin master
+ git push origin --force --tags
```
- If this step fails, someone has changed the `master` branch while you were
- rewriting history. You could restore the branch and re-run BFG to preserve
- their changes, or use `git push --force` to overwrite their changes.
+ [Protected tags](../protected_tags.md) will cause this to fail. To proceed, you must remove tag
+ protection, push, and then re-enable protected tags.
-1. Navigate to **Project > Settings > Repository > Repository Cleanup**:
+## Purge files from GitLab storage
- ![Repository settings cleanup form](img/repository_cleanup.png)
+To reduce the size of your repository in GitLab, you must remove GitLab internal references to
+commits that contain large files. Before completing these steps,
+[purge files from your repository history](#purge-files-from-repository-history).
- Upload the `object-id-map.old-new.txt` file and press **Start cleanup**.
- This will remove any internal Git references to the old commits, and run
- `git gc` against the repository. You will receive an email once it has
- completed.
+As well as [branches](branches/index.md) and tags, which are a type of Git ref, GitLab automatically
+creates other refs. These refs prevent dead links to commits, or missing diffs when viewing merge
+requests. [Repository cleanup](#repository-cleanup) can be used to remove these from GitLab.
-NOTE: **Note:**
-This process will remove some copies of the rewritten commits from GitLab's
-cache and database, but there are still numerous gaps in coverage - at present,
-some of the copies may persist indefinitely. [Clearing the instance cache](../../../administration/raketasks/maintenance.md#clear-redis-cache)
-may help to remove some of them, but it should not be depended on for security
-purposes!
+The following internal refs are not advertised:
-## Using `git filter-branch`
+- `refs/merge-requests/*` for merge requests.
+- `refs/pipelines/*` for
+ [pipelines](../../../ci/pipelines/index.md#troubleshooting-fatal-reference-is-not-a-tree).
+- `refs/environments/*` for environments.
-1. Navigate to your repository:
+This means they are not usually included when fetching, which makes fetching faster. In addition,
+`refs/keep-around/*` are hidden refs to prevent commits with discussion from being deleted and
+cannot be fetched at all.
- ```shell
- cd my_repository/
- ```
+However, these refs can be accessed from the Git bundle inside a project export.
-1. Change to the branch you want to remove the big file from:
+1. [Install `git filter-repo`](https://github.com/newren/git-filter-repo/blob/master/INSTALL.md)
+ using a supported package manager or from source.
+
+1. Generate a fresh [export from the
+ project](../settings/import_export.html#exporting-a-project-and-its-data) and download it.
+
+1. Decompress the backup using `tar`:
```shell
- git checkout master
+ tar xzf project-backup.tar.gz
```
-1. Use `filter-branch` to remove the big file:
+ This will contain a `project.bundle` file, which was created by
+ [`git bundle`](https://git-scm.com/docs/git-bundle).
+
+1. Clone a fresh copy of the repository from the bundle:
```shell
- git filter-branch --force --tree-filter 'rm -f path/to/big_file.mpg' HEAD
+ git clone --bare --mirror /path/to/project.bundle
```
-1. Instruct Git to purge the unwanted data:
+1. Using `git filter-repo`, purge any files from the history of your repository. Because we are
+ trying to remove internal refs, we will rely on the `commit-map` produced by each run to tell us
+ which internal refs to remove.
+
+ NOTE:**Note:**
+ `git filter-repo` creates a new `commit-map` file every run, and overwrite the `commit-map` from
+ the previous run. You will need this file from **every** run. Do the next step every time you run
+ `git filter-repo`.
+
+ To purge all large files, the `--strip-blobs-bigger-than` option can be used:
```shell
- git reflog expire --expire=now --all && git gc --prune=now --aggressive
+ git filter-repo --strip-blobs-bigger-than 10M
```
-1. Lastly, force push to the repository:
+ To purge specific large files by path, the `--path` and `--invert-paths` options can be combined.
```shell
- git push --force origin master
+ git filter-repo --path path/to/big/file.m4v --invert-paths
```
-Your repository should now be below the size limit.
+ See the
+ [`git filter-repo` documentation](https://htmlpreview.github.io/?https://github.com/newren/git-filter-repo/blob/docs/html/git-filter-repo.html#EXAMPLES)
+ for more examples and the complete documentation.
+
+1. Run a [repository cleanup](#repository-cleanup).
+
+## Repository cleanup
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/19376) in GitLab 11.6.
+
+Repository cleanup allows you to upload a text file of objects and GitLab will remove internal Git
+references to these objects. You can use
+[`git filter-repo`](https://github.com/newren/git-filter-repo) to produce a list of objects (in a
+`commit-map` file) that can be used with repository cleanup.
+
+To clean up a repository:
+
+1. Go to the project for the repository.
+1. Navigate to **{settings}** **Settings > Repository**.
+1. Upload a list of objects. For example, a `commit-map` file.
+1. Click **Start cleanup**.
+
+This will:
+
+- Remove any internal Git references to old commits.
+- Run `git gc` against the repository.
+
+You will receive an email once it has completed.
+
+When using repository cleanup, note:
+
+- Housekeeping prunes loose objects older than 2 weeks. This means objects added in the last 2 weeks
+ will not be removed immediately. If you have access to the
+ [Gitaly](../../../administration/gitaly/index.md) server, you may run `git gc --prune=now` to
+ prune all loose objects immediately.
+- This process will remove some copies of the rewritten commits from GitLab's cache and database,
+ but there are still numerous gaps in coverage and some of the copies may persist indefinitely.
+ [Clearing the instance cache](../../../administration/raketasks/maintenance.md#clear-redis-cache)
+ may help to remove some of them, but it should not be depended on for security purposes!
+
+## Storage limits
+
+Repository size limits:
+
+- Can [be set by an administrator](../../admin_area/settings/account_and_limit_settings.md#repository-size-limit-starter-only)
+ on self-managed instances. **(STARTER ONLY)**
+- Are [set for GitLab.com](../../gitlab_com/index.md#repository-size-limit).
+
+When a project has reached its size limit, you cannot:
+
+- Push to the project.
+- Create a new merge request.
+- Merge existing merge requests.
+- Upload LFS objects.
+
+You can still:
+
+- Create new issues.
+- Clone the project.
+
+If you exceed the repository size limit, you might try to:
+
+1. Remove some data.
+1. Make a new commit.
+1. Push back to the repository.
+
+Perhaps you might also:
+
+- Move some blobs to LFS.
+- Remove some old dependency updates from history.
+
+Unfortunately, this workflow won't work. Deleting files in a commit doesn't actually reduce the size
+of the repository because the earlier commits and blobs still exist.
+
+What you need to do is rewrite history. We recommend the open-source community-maintained tool
+[`git filter-repo`](https://github.com/newren/git-filter-repo).
+
+NOTE: **Note:**
+Until `git gc` runs on the GitLab side, the "removed" commits and blobs will still exist. You also
+must be able to push the rewritten history to GitLab, which may be impossible if you've already
+exceeded the maximum size limit.
+
+In order to lift these restrictions, the administrator of the self-managed GitLab instance must
+increase the limit on the particular project that exceeded it. Therefore, it's always better to
+proactively stay underneath the limit. If you hit the limit, and can't have it temporarily
+increased, your only option is to:
+
+1. Prune all the unneeded stuff locally.
+1. Create a new project on GitLab and start using that instead.
+
+CAUTION: **Caution:**
+This process is not suitable for removing sensitive data like password or keys from your repository.
+Information about commits, including file content, is cached in the database, and will remain
+visible even after they have been removed from the repository.
<!-- ## Troubleshooting
diff --git a/doc/user/project/repository/repository_mirroring.md b/doc/user/project/repository/repository_mirroring.md
index fdbea385998..f75b083e6dc 100644
--- a/doc/user/project/repository/repository_mirroring.md
+++ b/doc/user/project/repository/repository_mirroring.md
@@ -28,7 +28,7 @@ immediate update, unless:
- The mirror is already being updated.
- 5 minutes haven't elapsed since its last update.
-For security reasons, from [GitLab 12.10 onwards](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27166),
+For security reasons, in [GitLab 12.10 and later](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27166),
the URL to the original repository is only displayed to users with
Maintainer or Owner permissions to the mirrored project.
@@ -134,7 +134,7 @@ The repository will push soon. To force a push, click the appropriate button.
## Pulling from a remote repository **(STARTER)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51) in GitLab Enterprise Edition 8.2.
-> - [Added Git LFS support](https://gitlab.com/gitlab-org/gitlab/issues/10871) in [GitLab Starter](https://about.gitlab.com/pricing/) 11.11.
+> - [Added Git LFS support](https://gitlab.com/gitlab-org/gitlab/-/issues/10871) in [GitLab Starter](https://about.gitlab.com/pricing/) 11.11.
You can set up a repository to automatically have its branches, tags, and commits updated from an
upstream repository.
@@ -356,6 +356,24 @@ a [Push event webhook](../integrations/webhooks.md#push-events) to trigger an im
pull to GitLab. Push mirroring from GitLab is rate limited to once per minute when only push mirroring
protected branches.
+### Configure a webhook to trigger an immediate pull to GitLab
+
+Assuming you have already configured the [push](#setting-up-a-push-mirror-to-another-gitlab-instance-with-2fa-activated) and [pull](#pulling-from-a-remote-repository-starter) mirrors in the upstream GitLab instance, to trigger an immediate pull as suggested above, you will need to configure a [Push Event Web Hook](../integrations/webhooks.md#push-events) in the downstream instance.
+
+To do this:
+
+- Create a [personal access token](../../profile/personal_access_tokens.md) with `API` scope.
+- Navigate to **Settings > Webhooks**
+- Add the webhook URL which in this case will use the [Pull Mirror API](../../../api/projects.md#start-the-pull-mirroring-process-for-a-project-starter) request to trigger an immediate pull after updates to the repository.
+
+ ```plaintext
+ https://gitlab.example.com/api/v4/projects/:id/mirror/pull?private_token=<your_access_token>
+ ```
+
+- Ensure that the **Push Events** checkbox is selected.
+- Click on **Add Webhook** button to save the webhook.
+- To test the integration click on the **Test** button and confirm GitLab does not return any error.
+
### Preventing conflicts using a `pre-receive` hook
CAUTION: **Warning:**
@@ -388,13 +406,13 @@ proxy_push()
REFNAME="$3"
# --- Pattern of branches to proxy pushes
- whitelisted=$(expr "$branch" : "\(master\)")
+ allowlist=$(expr "$branch" : "\(master\)")
case "$refname" in
refs/heads/*)
branch=$(expr "$refname" : "refs/heads/\(.*\)")
- if [ "$whitelisted" = "$branch" ]; then
+ if [ "$allowlist" = "$branch" ]; then
unset GIT_QUARANTINE_PATH # handle https://git-scm.com/docs/git-receive-pack#_quarantine_environment
error="$(git push --quiet $TARGET_REPO $NEWREV:$REFNAME 2>&1)"
fail=$?
@@ -435,7 +453,7 @@ Note that this sample has a few limitations:
- This example may not work verbatim for your use case and might need modification.
- It does not regard different types of authentication mechanisms for the mirror.
- It does not work with forced updates (rewriting history).
- - Only branches that match the `whitelisted` patterns will be proxy pushed.
+ - Only branches that match the `allowlist` patterns will be proxy pushed.
- The script circumvents the Git hook quarantine environment because the update of `$TARGET_REPO`
is seen as a ref update and Git will complain about it.
diff --git a/doc/user/project/repository/x509_signed_commits/index.md b/doc/user/project/repository/x509_signed_commits/index.md
index 20143af0b33..d55d5c5c2d8 100644
--- a/doc/user/project/repository/x509_signed_commits/index.md
+++ b/doc/user/project/repository/x509_signed_commits/index.md
@@ -65,11 +65,11 @@ git config --global gpg.format x509
### Windows and MacOS
-Install [smimesign](https://github.com/github/smimesign) by downloading the
+Install [S/MIME Sign](https://github.com/github/smimesign) by downloading the
installer or via `brew install smimesign` on MacOS.
Get the ID of your certificate with `smimesign --list-keys` and set your
-signingkey `git config --global user.signingkey ID`, then configure X.509:
+signing key `git config --global user.signingkey ID`, then configure X.509:
```shell
git config --global gpg.x509.program smimesign
diff --git a/doc/user/project/requirements/img/requirement_edit_save_v12_10.png b/doc/user/project/requirements/img/requirement_edit_save_v12_10.png
deleted file mode 100644
index 6cf7db361b8..00000000000
--- a/doc/user/project/requirements/img/requirement_edit_save_v12_10.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/requirements/index.md b/doc/user/project/requirements/index.md
index 50343e52a68..d9bd02518a4 100644
--- a/doc/user/project/requirements/index.md
+++ b/doc/user/project/requirements/index.md
@@ -1,14 +1,23 @@
---
type: reference, howto
+stage: Plan
+group: Certify
+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
---
-# Requirements **(ULTIMATE)**
+# Requirements Management **(ULTIMATE)**
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2703) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.10.
-Requirements allow you to create criteria to check your products against. They
-can be based on users, stakeholders, system, software, or anything else you
-find important to capture.
+With requirements, you can set criteria to check your products against. They can be based on users,
+stakeholders, system, software, or anything else you find important to capture.
+
+A requirement is an artifact in GitLab which describes the specific behavior of your product.
+Requirements are long-lived and don't disappear unless manually cleared.
+
+If an industry standard *requires* that your application has a certain feature or behavior, you can
+[create a requirement](#create-a-requirement) to reflect this.
+When a feature is no longer necessary, you can [archive the related requirement](#archive-a-requirement).
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
For an overview, see [GitLab 12.10 Introduces Requirements Management](https://www.youtube.com/watch?v=uSS7oUNSEoU).
@@ -38,22 +47,18 @@ list page.
To edit a requirement:
-1. From the requirements list, click the **Edit** (**{pencil}**) button.
+1. From the requirements list, click **Edit** (**{pencil}**).
1. Update the title in text input field.
1. Click **Save changes**.
![requirement edit view](img/requirement_edit_view_v12_10.png)
-The requirements list shows the new title immediately.
-
-![requirement edit saved](img/requirement_edit_save_v12_10.png)
-
## Archive a requirement
You can archive an open requirement (if you have the necessary privileges) while
you're in the **Open** tab.
-From the requirements list page, click the **Archive** (**{archive}**) button.
+From the requirements list page, click **Archive** (**{archive}**).
![requirement archive view](img/requirement_archive_view_v12_10.png)
@@ -65,6 +70,84 @@ You can view the list of archived requirements in the **Archived** tab.
![archived requirements list](img/requirements_archived_list_view_v12_10.png)
-To reopen an archived requirement, click the **Reopen** button.
+To reopen an archived requirement, click **Reopen**.
As soon as a requirement is reopened, it no longer appears in the **Archived** tab.
+
+## Search for a requirement from the requirements list page
+
+> - Introduced in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.1.
+
+You can search for a requirement from the list of requirements using filtered search bar (similar to
+that of Issues and Merge Requests) based on following parameters:
+
+- Title
+- Author username
+
+To search, go to the list of requirements and click the field **Search or filter results**.
+It will display a dropdown menu, from which you can add an author. You can also enter plain
+text to search by epic title or description. When done, press <kbd>Enter</kbd> on your
+keyboard to filter the list.
+
+You can also sort requirements list by:
+
+- Created date
+- Last updated
+
+## Allow requirements to be satisfied from a CI job
+
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2859) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.1.
+
+GitLab supports [requirements test
+reports](../../../ci/pipelines/job_artifacts.md#artifactsreportsrequirements-ultimate) now.
+You can add a job to your CI pipeline that, when triggered, marks all existing
+requirements as Satisfied.
+
+### Add the manual job to CI
+
+To configure your CI to mark requirements as Satisfied when the manual job is
+triggered, add the code below to your `.gitlab-ci.yml` file.
+
+```yaml
+requirements_confirmation:
+ when: manual
+ allow_failure: false
+ script:
+ - mkdir tmp
+ - echo "{\"*\":\"passed\"}" > tmp/requirements.json
+ artifacts:
+ reports:
+ requirements: tmp/requirements.json
+```
+
+This definition adds a manually-triggered (`when: manual`) job to the CI
+pipeline. It's blocking (`allow_failure: false`), but it's up to you what
+conditions you use for triggering the CI job. Also, you can use any existing CI job
+to mark all requirements as satisfied, as long as the `requirements.json`
+artifact is generated and uploaded by the CI job.
+
+When you manually trigger this job, the `requirements.json` file containing
+`{"*":"passed"}` is uploaded as an artifact to the server. On the server side,
+the requirement report is checked for the "all passed" record
+(`{"*":"passed"}`), and on success, it marks all existing open requirements as
+Satisfied.
+
+### Add the manual job to CI conditionally
+
+To configure your CI to include the manual job only when there are some open
+requirements, add a rule which checks `CI_HAS_OPEN_REQUIREMENTS` CI variable.
+
+```yaml
+requirements_confirmation:
+ rules:
+ - if: "$CI_HAS_OPEN_REQUIREMENTS" == "true"
+ when: manual
+ - when: never
+ allow_failure: false
+ script:
+ - mkdir tmp
+ - echo "{\"*\":\"passed\"}" > tmp/requirements.json
+ artifacts:
+ reports:
+ requirements: tmp/requirements.json
+```
diff --git a/doc/user/project/service_desk.md b/doc/user/project/service_desk.md
index d021f259015..ffb1f6a1407 100644
--- a/doc/user/project/service_desk.md
+++ b/doc/user/project/service_desk.md
@@ -1,6 +1,13 @@
+---
+stage: Plan
+group: Certify
+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
+---
+
# Service Desk **(STARTER)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/149) in [GitLab Premium 9.1](https://about.gitlab.com/releases/2017/04/22/gitlab-9-1-released/#service-desk-eep).
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/149) in [GitLab Premium](https://about.gitlab.com/pricing/) 9.1.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/214839) to [GitLab Starter](https://about.gitlab.com/pricing/) in 13.0.
## Overview
@@ -28,14 +35,19 @@ with GitLab CI/CD.
Here's how Service Desk will work for you:
-1. You'll provide a project-specific email address to your paying customers, who can email you directly from within the app
-1. Each email they send creates an issue in the appropriate project
-1. Your team members navigate to the Service Desk issue tracker, where they can see new support requests and respond inside associated issues
-1. Your team communicates back and forth with the customer to understand the request
-1. Your team starts working on implementing code to solve your customer's problem
-1. When your team finishes the implementation, whereupon the merge request is merged and the issue is closed automatically
-1. The customer will have been attended successfully via email, without having real access to your GitLab instance
-1. Your team saved time by not having to leave GitLab (or setup any integrations) to follow up with your customer
+1. You provide a project-specific email address to your paying customers, who can email you directly
+ from within the app.
+1. Each email they send creates an issue in the appropriate project.
+1. Your team members navigate to the Service Desk issue tracker, where they can see new support
+ requests and respond inside associated issues.
+1. Your team communicates back and forth with the customer to understand the request.
+1. Your team starts working on implementing code to solve your customer's problem.
+1. When your team finishes the implementation, whereupon the merge request is merged and the issue
+ is closed automatically.
+1. The customer will have been attended successfully via email, without having real access to your
+ GitLab instance.
+1. Your team saved time by not having to leave GitLab (or setup any integrations) to follow up with
+ your customer.
## How it works
@@ -56,7 +68,8 @@ If you have the correct access and a Premium license, you have the option to set
Follow these steps to do so:
1. [Set up incoming email](../../administration/incoming_email.md#set-it-up) for the GitLab instance.
- This must support [email sub-addressing](../../administration/incoming_email.md#email-sub-addressing).
+ - We recommend using [email sub-addressing](../../administration/incoming_email.md#email-sub-addressing),
+ but in GitLab 11.7 and later you can also use [catch-all mailboxes](../../administration/incoming_email.md#catch-all-mailbox).
1. Navigate to your project's **Settings > General** and locate the **Service Desk** section.
1. Enable the **Activate Service Desk** toggle. This reveals a unique email address to email issues
to the project. These issues will be [confidential](issues/confidential_issues.md), so they will
@@ -83,7 +96,7 @@ navigation's **Issues** menu.
### Using customized email templates
- > [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/2460) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.7.
+ > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2460) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.7.
When a user submits a new issue using Service Desk, or when a new note is created on a Service Desk issue, an email is sent to the author.
@@ -110,14 +123,14 @@ in the email, `%{ISSUE_PATH}` placeholder which will be replaced by
### Using custom email display name
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/7529) in GitLab 12.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7529) in GitLab 12.8.
You can customize the email display name. Emails sent from Service Desk will have
this name in the `From` header. The default display name is `GitLab Support Bot`.
### Using custom email address
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/2201) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.0.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2201) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.0.
NOTE: **Note:**
This feature is disabled by default. For steps to enable it, see [Enable custom email address](#enable-custom-email-address).
@@ -160,12 +173,12 @@ As a result, a new Service Desk issue is created from this email in the `mygroup
#### Enable custom email address
-This feature comes with the `service_desk_email` feature flag disabled by default.
+This feature comes with the `service_desk_custom_address` feature flag disabled by default.
To turn on the feature, ask a GitLab administrator with Rails console access to run the following
command:
```ruby
-Feature.enable(service_desk_email)
+Feature.enable(:service_desk_custom_address)
```
The configuration options are the same as for configuring
diff --git a/doc/user/project/settings/import_export.md b/doc/user/project/settings/import_export.md
index e9521a0567e..5a364eb89aa 100644
--- a/doc/user/project/settings/import_export.md
+++ b/doc/user/project/settings/import_export.md
@@ -1,6 +1,6 @@
# Project import/export
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/3050) in GitLab 8.9.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/3050) in GitLab 8.9.
> - From GitLab 10.0, administrators can disable the project export option on the GitLab instance.
Existing projects running on any GitLab instance or GitLab.com can be exported with all their related
@@ -158,12 +158,16 @@ If use of the `Internal` visibility level
[is restricted](../../../public_access/public_access.md#restricting-the-use-of-public-or-internal-projects),
all imported projects are given the visibility of `Private`.
+NOTE: **Note:**
+The maximum import file size can be set by the Administrator, default is 50MB.
+As an administrator, you can modify the maximum import file size. To do so, use the `max_import_size` option in the [Application settings API](../../../api/settings.md#change-application-settings) or the [Admin UI](../../admin_area/settings/account_and_limit_settings.md).
+
## Rate limits
To help avoid abuse, users are rate limited to:
-| Request Type | Limit |
-| ---------------- | --------------------------- |
-| Export | 1 project per 5 minutes |
-| Download export | 10 projects per 10 minutes |
-| Import | 30 projects per 5 minutes |
+| Request Type | Limit |
+| ---------------- | ----------------------------------------- |
+| Export | 30 projects per 5 minutes |
+| Download export | 10 downloads per project every 10 minutes |
+| Import | 30 projects per 5 minutes |
diff --git a/doc/user/project/settings/index.md b/doc/user/project/settings/index.md
index 0c98772237b..0798c39fff5 100644
--- a/doc/user/project/settings/index.md
+++ b/doc/user/project/settings/index.md
@@ -55,7 +55,7 @@ Use the switches to enable or disable the following features:
| **Merge Requests** | ✓ | Enables [merge request](../merge_requests/) functionality; also see [Merge request settings](#merge-request-settings) |
| **Forks** | ✓ | Enables [forking](../index.md#fork-a-project) functionality |
| **Pipelines** | ✓ | Enables [CI/CD](../../../ci/README.md) functionality |
-| **Container Registry** | | Activates a [registry](../../packages/container_registry/) for your docker images |
+| **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-premium-only) functionality |
| **Wiki** | ✓ | Enables a separate system for [documentation](../wiki/) |
@@ -192,11 +192,9 @@ to transfer a project.
You can transfer an existing project into a [group](../../group/index.md) if:
-1. You have at least **Maintainer** [permissions](../../permissions.md#project-members-permissions) to that group.
-1. The project is in a subgroup you own.
-1. You're at least a **Maintainer** of the project under your personal namespace.
- Similarly, if you're an owner of a group, you can transfer any of its projects
- under your own user.
+- You have at least **Maintainer** [permissions](../../permissions.md#project-members-permissions) to 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.
To transfer a project:
@@ -228,14 +226,14 @@ To remove a project:
This action either:
- Removes a project including all associated resources (issues, merge requests etc).
-- Since [GitLab 12.6](https://gitlab.com/gitlab-org/gitlab/issues/32935), on
+- Since [GitLab 12.6](https://gitlab.com/gitlab-org/gitlab/-/issues/32935), on
[GitLab Premium or GitLab.com Silver](https://about.gitlab.com/pricing/) or higher tiers, marks a project for
deletion. The deletion will happen 7 days later by default, but this can be changed in the
[instance settings](../../admin_area/settings/visibility_and_access_controls.md#default-deletion-adjourned-period-premium-only).
#### Restore a project **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/32935) in GitLab 12.6.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32935) in GitLab 12.6.
To restore a project marked for deletion:
@@ -272,3 +270,8 @@ Configure Error Tracking to discover and view [Sentry errors within GitLab](../o
### Jaeger tracing **(ULTIMATE)**
Add the URL of a Jaeger server to allow your users to [easily access the Jaeger UI from within GitLab](../operations/tracing.md).
+
+### Status Page
+
+[Add Storage credentials](../status_page/#syncing-incidents-to-the-status-page)
+to enable the syncing of public Issues to a [deployed status page](../status_page/#status-page-project).
diff --git a/doc/user/project/settings/project_access_tokens.md b/doc/user/project/settings/project_access_tokens.md
index 303a6f6d3be..42ba2654b42 100644
--- a/doc/user/project/settings/project_access_tokens.md
+++ b/doc/user/project/settings/project_access_tokens.md
@@ -1,6 +1,13 @@
-# Project access tokens **(CORE ONLY)**
+# Project access tokens (Alpha) **(CORE ONLY)**
-> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2587) in GitLab 13.0.
+CAUTION: **Warning:**
+This is an [Alpha](https://about.gitlab.com/handbook/product/#alpha) feature, and it is subject to change at any time without
+prior notice.
+
+> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2587) in GitLab 13.0.
+> - It's deployed behind a feature flag, disabled by default.
+> - It's disabled on GitLab.com.
+> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-project-access-tokens).
Project access tokens are scoped to a project and can be used to authenticate with the [GitLab API](../../../api/README.md#personalproject-access-tokens).
@@ -27,7 +34,7 @@ For each project access token created, a bot user will also be created and added
["Maintainer" level permissions](../../permissions.md#project-members-permissions). API calls made with a
project access token will be associated to the corresponding bot user.
-These users will appear in **{settings}** **Settings > Members** but can not be modified.
+These users will appear in **Members** but can not be modified.
Furthermore, the bot user can not be added to any other project.
When the project access token is [revoked](#revoking-a-project-access-token) the bot user will be deleted and all
@@ -53,3 +60,22 @@ the following table.
| `write_registry` | Allows write-access (push) to [container registry](../../packages/container_registry/index.md). |
| `read_repository` | Allows read-only access (pull) to the repository. |
| `write_repository` | Allows read-write access (pull, push) to the repository. |
+
+### Enable or disable project access tokens
+
+Project access tokens is an [Alpha](https://about.gitlab.com/handbook/product/#alpha) feature and is not recommended 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 for your instance.
+
+To enable it:
+
+```ruby
+Feature.enable(:resource_access_token)
+```
+
+To disable it:
+
+```ruby
+Feature.disable(:resource_access_token)
+```
diff --git a/doc/user/project/status_page/index.md b/doc/user/project/status_page/index.md
index 8ebfb638894..ec0a79583d5 100644
--- a/doc/user/project/status_page/index.md
+++ b/doc/user/project/status_page/index.md
@@ -55,7 +55,7 @@ To deploy the Status Page to AWS S3 you need to add the Status Page project & co
Once the CI/CD variables are set, you'll need to set up the Project you want to use for Incident issues:
-1. Navigate to **Settings > Operations > Status Page**.
+1. To view the [Operations Settings](../settings/#operations-settings) page, navigate to **{settings}** **Settings > Operations > Status Page**.
1. Fill in your cloud provider's credentials and make sure the **Active** checkbox is checked.
1. Click **Save changes**.
@@ -71,7 +71,8 @@ The incident detail page shows detailed information about a particular incident.
- Status on the incident, including when the incident was last updated.
- The incident title, including any emojis.
-- The description of the incident, including emojis and static images.
+- The description of the incident, including emojis.
+- Any file attachments provided in the incident description or comments with a valid image extension. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/205166) in GitLab 13.1.
- A chronological ordered list of updates to the incident.
![Status Page detail](../img/status_page_detail_v12_10.png)
@@ -82,12 +83,21 @@ The incident detail page shows detailed information about a particular incident.
To publish an Incident, you first need to create an issue in the Project you enabled the Status Page settings in.
-Once this issue is created, a background worker will publish the issue onto the Status Page using the credentials you provided during setup.
+Issues are not published to the Status Page by default. Use the `/publish` [quick action](../quick_actions.md) in an issue to publish the issue. Only [project or group owners](../../permissions.md) are permitted to publish issues.
+
+After the quick action is used, a background worker publishes the issue onto the Status Page using the credentials you provided during setup.
+
Since all incidents are published publicly, user and group mentions are anonymized with `Incident Responder`,
and titles of non-public [GitLab references](../../markdown.md#special-gitlab-references) are removed.
+When an Incident is published in the GitLab project, you can access the
+details page of the Incident by clicking the **Published on status page** button
+displayed under the Incident's title.
+
+![Status Page detail link](../img/status_page_detail_link_v13_1.png)
+
NOTE: **Note:**
-Confidential issues are not published. If a published issue is made confidential it will be unpublished.
+Confidential issues can't be published. If you make a published issue confidential, it will be unpublished.
### Publishing updates
@@ -108,3 +118,15 @@ Anyone with access to view the Issue can add an Emoji Award to a comment, so you
### Changing the Incident status
To change the incident status from `open` to `closed`, close the incident issue within GitLab. This will then be updated shortly on the Status Page website.
+
+## Attachment storage
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/205166) in GitLab 13.1.
+
+Beginning with GitLab 13.1, files attached to incident issue descriptions or
+comments are published and unpublished to the status page storage as part of
+the [publication flow](#how-it-works).
+
+### Limit
+
+Only 5000 attachments per issue will be transferred to the status page.
diff --git a/doc/user/project/time_tracking.md b/doc/user/project/time_tracking.md
index 57a26f4e928..b88e1ed2d37 100644
--- a/doc/user/project/time_tracking.md
+++ b/doc/user/project/time_tracking.md
@@ -1,6 +1,9 @@
---
type: reference
disqus_identifier: 'https://docs.gitlab.com/ee/workflow/time_tracking.html'
+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/#designated-technical-writers
---
# Time Tracking
diff --git a/doc/user/project/web_ide/index.md b/doc/user/project/web_ide/index.md
index d4daca0e1e4..0ddc9762bc5 100644
--- a/doc/user/project/web_ide/index.md
+++ b/doc/user/project/web_ide/index.md
@@ -1,7 +1,7 @@
# Web IDE
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/4539) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.4.
-> - [Brought to GitLab Core](https://gitlab.com/gitlab-org/gitlab-foss/issues/44157) in 10.7.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4539) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.4.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/44157) to GitLab Core in 10.7.
The Web IDE editor makes it faster and easier to contribute changes to your
projects by providing an advanced editor with commit staging.
@@ -57,10 +57,30 @@ which applies to the entire Web IDE screen.
|---------------------------------------------------------------|-----------------------------------------|
| ![Solarized Light Theme](img/solarized_light_theme_v13.0.png) | ![Dark Theme](img/dark_theme_v13.0.png) |
+## Configure the Web IDE
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/23352) in [GitLab Core](https://about.gitlab.com/pricing/) 13.1.
+
+The Web IDE supports configuration of certain editor settings by using
+[`.editorconfig` files](https://editorconfig.org/). When opening a file, the
+Web IDE looks for a file named `.editorconfig` in the current directory
+and all parent directories. If a configuration file is found and has settings
+that match the file's path, these settings will be enforced on the opened file.
+
+The Web IDE currently supports the following `.editorconfig` settings:
+
+- `indent_style`
+- `indent_size`
+- `end_of_line`
+- `trim_trailing_whitespace`
+- `tab_width`
+- `insert_final_newline`
+
## Commit changes
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/4539) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.4 and [brought to GitLab Core](https://gitlab.com/gitlab-org/gitlab-foss/issues/44157) in 10.7.
-> - From [GitLab 12.7 onward](https://gitlab.com/gitlab-org/gitlab/issues/33441), files were automatically staged.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4539) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.4.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/44157) to GitLab Core in 10.7.
+> - From [GitLab 12.7 onward](https://gitlab.com/gitlab-org/gitlab/-/issues/33441), files were automatically staged.
> - From [GitLab 12.9 onward](https://gitlab.com/gitlab-org/gitlab/-/issues/196609), support for staging files was removed to prevent loss of unstaged data. All your current changes necessarily have to be committed or discarded.
After making your changes, click the **Commit** button on the bottom-left to
@@ -116,6 +136,20 @@ in the top of the sidebar to open a list of branches.
You will need to commit or discard all your changes before switching to a
different branch.
+## Markdown editing
+
+> - Markdown preview [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/18059) in [GitLab Core](https://about.gitlab.com/pricing/) 10.7.
+> - Support for pasting images [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22822) in [GitLab Core](https://about.gitlab.com/pricing/) 13.1.
+
+When you edit Markdown files in the Web IDE, you can preview your changes by
+clicking the **Preview Markdown** tab above the file editor. The Markdown preview
+supports [GitLab Flavored Markdown](../../markdown.md#gitlab-flavored-markdown-gfm).
+
+You can also upload any local images by pasting them directly in the Markdown file.
+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 file name.
+
## Live Preview
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/19764) in [GitLab Core](https://about.gitlab.com/pricing/) 11.2.
@@ -152,9 +186,10 @@ below.
}
```
-## Interactive Web Terminals for the Web IDE **(ULTIMATE ONLY)**
+## Interactive Web Terminals for the Web IDE
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/5426) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.6.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5426) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.6.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/211685) to GitLab Core in 13.1.
CAUTION: **Warning:**
Interactive Web Terminals for the Web IDE is currently in **Beta**.
@@ -252,7 +287,8 @@ click **Restart Terminal** to start a new terminal session.
### File syncing to web terminal
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/5276) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.0.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5276) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.0.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/211686) to GitLab Core in 13.1.
File changes in the Web IDE can be synced to a running web terminal.
This enables users to test their code changes in a preconfigured terminal
@@ -284,7 +320,7 @@ terminal:
- The `webide-file-sync` executable must start **after** the project
directory is available. This is why we need to add `sleep 5` to the `command`.
- See [this issue](https://gitlab.com/gitlab-org/webide-file-sync/issues/7) for
+ See [this issue](https://gitlab.com/gitlab-org/webide-file-sync/-/issues/7) for
more information.
- `$CI_PROJECT_DIR` is a
[predefined environment variable](../../../ci/variables/predefined_variables.md)
diff --git a/doc/user/project/wiki/index.md b/doc/user/project/wiki/index.md
index fa3ad4536ef..82dbeb0ff7e 100644
--- a/doc/user/project/wiki/index.md
+++ b/doc/user/project/wiki/index.md
@@ -52,7 +52,7 @@ When you're ready, click the **Create page** and the new page will be created.
### Attachment storage
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/33475) in GitLab 11.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/33475) in GitLab 11.3.
Starting with GitLab 11.3, any file that is uploaded to the wiki via GitLab's
interface will be stored in the wiki Git repository, and it will be available
@@ -185,6 +185,14 @@ them like you would do with every other Git repository.
On the right sidebar, click on **Clone repository** and follow the on-screen
instructions.
+Files that you add to your wiki locally must have one of the following
+supported extensions, depending on the markup language you wish to use,
+otherwise they will not display when pushed to GitLab:
+
+- Markdown extensions: `.mdown`, `.mkd`, `.mkdn`, `.md`, `.markdown`.
+- AsciiDoc extensions: `.adoc`, `.ad`, `.asciidoc`.
+- Other markup extensions: `.textile`, `.rdoc`, `.org`, `.creole`, `.wiki`, `.mediawiki`, `.rst`.
+
## Customizing sidebar
On the project's Wiki page, there is a right side navigation that renders the full Wiki pages list by default, with hierarchy.
diff --git a/doc/user/search/advanced_global_search.md b/doc/user/search/advanced_global_search.md
index fac1702f2ac..eaa57395b8f 100644
--- a/doc/user/search/advanced_global_search.md
+++ b/doc/user/search/advanced_global_search.md
@@ -2,9 +2,10 @@
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/109) in GitLab [Starter](https://about.gitlab.com/pricing/) 8.4.
-NOTE: **Note**
-Advanced Global Search (powered by Elasticsearch) is not yet available on GitLab.com. We are working on adding it.
-[Follow this epic for the latest updates](https://gitlab.com/groups/gitlab-org/-/epics/153).
+NOTE: **GitLab.com availability:**
+Advanced Global Search (powered by Elasticsearch) is not yet available on GitLab.com.
+It will be progressively enabled for all paid groups in Q3 of 2020.
+[Follow this epic](https://gitlab.com/groups/gitlab-com/-/epics/649) for the latest updates on the timeline.
Leverage Elasticsearch for faster, more advanced code search across your entire
GitLab instance.
diff --git a/doc/user/search/advanced_search_syntax.md b/doc/user/search/advanced_search_syntax.md
index 5113578af9e..1ca9649b581 100644
--- a/doc/user/search/advanced_search_syntax.md
+++ b/doc/user/search/advanced_search_syntax.md
@@ -4,9 +4,10 @@
>
> - Introduced in [GitLab Enterprise Starter](https://about.gitlab.com/pricing/) 9.2
-NOTE: **Note**
-Advanced Global Search (powered by Elasticsearch) is not yet available on GitLab.com. We are working on adding it.
-[Follow this epic for the latest updates](https://gitlab.com/groups/gitlab-org/-/epics/153).
+NOTE: **GitLab.com availability:**
+Advanced Global Search (powered by Elasticsearch) is not yet available on GitLab.com.
+It will be progressively enabled for all paid groups in Q3 of 2020.
+[Follow this epic](https://gitlab.com/groups/gitlab-com/-/epics/649) for the latest updates on the timeline.
Use advanced queries for more targeted search results.
diff --git a/doc/user/search/index.md b/doc/user/search/index.md
index f5efa3519d9..b616b606b64 100644
--- a/doc/user/search/index.md
+++ b/doc/user/search/index.md
@@ -49,8 +49,8 @@ groups:
1. Select or type the operator to use for filtering the attribute. The following operators are
available:
- `=`: Is
- - `!=`: Is not ([Introduced](https://gitlab.com/gitlab-org/gitlab/issues/18059) in GitLab 12.7)
-1. Enter the text to filter the attribute by.
+ - `!=`: 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`.
@@ -86,7 +86,7 @@ You can filter issues and merge requests by specific terms included in titles or
### Filtering by ID
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/39908) in GitLab 12.1.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/39908) in GitLab 12.1.
You can filter the **Issues** list to individual instances by their ID. For example, enter filter `#10` to return only issue 10. The same applies to the **Merge Requests** list. Enter filter `#30` to return only merge request 30.
@@ -110,6 +110,18 @@ the dropdown) **Approved-By** and select the user.
![Filter MRs by approved by](img/filter_approved_by_merge_requests_v13_0.png)
+## Filters autocomplete
+
+GitLab provides many filters across many pages (issues, merge requests, epics,
+and pipelines among others) which you can use to narrow down your search. When
+using the filter functionality, you can start typing characters to bring up
+relevant users or other attributes.
+
+For performance optimization, there is a requirement of a minimum of three
+characters to begin your search. For example, if you want to search for
+issues that have the assignee "Simone Presley", you'll need to type at
+least "Sim" before autocomplete gives any relevant results.
+
## Search history
You can view recent searches by clicking on the little arrow-clock icon, which is to the left of the search input. Click the search entry to run that search again. This feature is available for issues and merge requests. Searches are stored locally in your browser.
@@ -149,9 +161,9 @@ You can search through your projects from the left menu, by clicking the menu ba
On the field **Filter by name**, type the project or group name you want to find, and GitLab
will filter them for you as you type.
-You can also look for the projects you starred (**Starred projects**), and **Explore** all
+You can also look for the projects you [starred](../project/index.md#star-a-project) (**Starred projects**), and **Explore** all
public and internal projects available in GitLab.com, from which you can filter by visibility,
-through **Trending**, best rated with **Most starts**, or **All** of them.
+through **Trending**, best rated with **Most stars**, or **All** of them.
You can also sort them by **Name**, **Last created**, **Oldest created**, **Last updated**,
**Oldest updated**, **Owner**, and choose to hide or show **archived projects**:
diff --git a/doc/user/shortcuts.md b/doc/user/shortcuts.md
index fa466fdb3b9..efa374cf1c3 100644
--- a/doc/user/shortcuts.md
+++ b/doc/user/shortcuts.md
@@ -8,7 +8,7 @@ disqus_identifier: 'https://docs.gitlab.com/ee/workflow/shortcuts.html'
GitLab has many useful keyboard shortcuts to make it easier to access different features.
You can see a modal listing keyboard shortcuts within GitLab itself by pressing <kbd>?</kbd>,
or clicking **Keyboard shortcuts** in the Help menu at the top right.
-From [GitLab 12.8 onwards](https://gitlab.com/gitlab-org/gitlab/issues/22113),
+In [GitLab 12.8 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/22113),
keyboard shortcuts can be disabled using the **Enable**/**Disable** toggle in this modal window.
The [Global Shortcuts](#global-shortcuts) work from any area of GitLab, but you must
diff --git a/doc/user/snippets.md b/doc/user/snippets.md
index 96c8dba11e5..68e5c5ac92c 100644
--- a/doc/user/snippets.md
+++ b/doc/user/snippets.md
@@ -129,7 +129,7 @@ different visibility level from the dropdown menu.
## Snippet comments
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/12910) in GitLab 9.2.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/12910) in GitLab 9.2.
With GitLab Snippets you engage in a conversation about that piece of code,
facilitating the collaboration among users.
@@ -147,8 +147,8 @@ snippet was created using the GitLab web interface the original line ending is W
> Introduced in GitLab 10.8.
-Public snippets can not only be shared, but also embedded on any website. This
-allows us to reuse a GitLab snippet in multiple places and any change to the source
+Public snippets can not only be shared, but also embedded on any website. With
+this, you can reuse a GitLab snippet in multiple places and any change to the source
is automatically reflected in the embedded snippet.
To embed a snippet, first make sure that:
@@ -172,6 +172,6 @@ Here's how an embedded snippet looks like:
<script src="https://gitlab.com/gitlab-org/gitlab-foss/snippets/1717978.js"></script>
-Embedded snippets are displayed with a header that shows the file name is defined,
+Embedded snippets are displayed with a header that shows the file name if it's defined,
the snippet size, a link to GitLab, and the actual snippet content. Actions in
the header allow users to see the snippet in raw format and download it.
diff --git a/doc/user/todos.md b/doc/user/todos.md
index 84a7b6afdac..5d3e3e62652 100644
--- a/doc/user/todos.md
+++ b/doc/user/todos.md
@@ -1,5 +1,8 @@
---
disqus_identifier: 'https://docs.gitlab.com/ee/workflow/todos.html'
+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/#designated-technical-writers
---
# GitLab To-Do List
diff --git a/jest.config.unit.js b/jest.config.js
index 4627462c730..4627462c730 100644
--- a/jest.config.unit.js
+++ b/jest.config.js
diff --git a/lib/api/api.rb b/lib/api/api.rb
index b8135539cda..fb67258f331 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -159,7 +159,6 @@ module API
mount ::API::Keys
mount ::API::Labels
mount ::API::Lint
- mount ::API::LsifData
mount ::API::Markdown
mount ::API::Members
mount ::API::MergeRequestDiffs
@@ -170,6 +169,7 @@ module API
mount ::API::Notes
mount ::API::Discussions
mount ::API::ResourceLabelEvents
+ mount ::API::ResourceMilestoneEvents
mount ::API::NotificationSettings
mount ::API::Pages
mount ::API::PagesDomains
diff --git a/lib/api/deploy_keys.rb b/lib/api/deploy_keys.rb
index e86bcc19b2b..11340e91aae 100644
--- a/lib/api/deploy_keys.rb
+++ b/lib/api/deploy_keys.rb
@@ -25,7 +25,8 @@ module API
get "deploy_keys" do
authenticated_as_admin!
- present paginate(DeployKey.all), with: Entities::SSHKey
+ deploy_keys = DeployKey.all.preload_users
+ present paginate(deploy_keys), with: Entities::SSHKey
end
params do
@@ -42,7 +43,7 @@ module API
end
# rubocop: disable CodeReuse/ActiveRecord
get ":id/deploy_keys" do
- keys = user_project.deploy_keys_projects.preload(:deploy_key)
+ keys = user_project.deploy_keys_projects.preload(deploy_key: [:user])
present paginate(keys), with: Entities::DeployKeysProject
end
diff --git a/lib/api/discussions.rb b/lib/api/discussions.rb
index 0dd1850e526..7b453ada41c 100644
--- a/lib/api/discussions.rb
+++ b/lib/api/discussions.rb
@@ -78,6 +78,8 @@ module API
optional :line_range, type: Hash, desc: 'Multi-line start and end' do
requires :start_line_code, type: String, desc: 'Start line code for multi-line note'
requires :end_line_code, type: String, desc: 'End line code for multi-line note'
+ requires :start_line_type, type: String, desc: 'Start line type for multi-line note'
+ requires :end_line_type, type: String, desc: 'End line type for multi-line note'
end
end
end
diff --git a/lib/api/entities/bridge.rb b/lib/api/entities/bridge.rb
new file mode 100644
index 00000000000..8f0ee69399a
--- /dev/null
+++ b/lib/api/entities/bridge.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+module API
+ module Entities
+ class Bridge < Entities::JobBasic
+ expose :downstream_pipeline, with: Entities::PipelineBasic
+ end
+ end
+end
diff --git a/lib/api/entities/container_registry.rb b/lib/api/entities/container_registry.rb
index 6250f35c7cb..cff627ab50a 100644
--- a/lib/api/entities/container_registry.rb
+++ b/lib/api/entities/container_registry.rb
@@ -16,6 +16,7 @@ module API
expose :project_id
expose :location
expose :created_at
+ expose :tags_count, if: -> (_, options) { options[:tags_count] }
expose :tags, using: Tag, if: -> (_, options) { options[:tags] }
end
diff --git a/lib/api/entities/group_detail.rb b/lib/api/entities/group_detail.rb
index e03047a6e75..93dc41da81d 100644
--- a/lib/api/entities/group_detail.rb
+++ b/lib/api/entities/group_detail.rb
@@ -3,6 +3,9 @@
module API
module Entities
class GroupDetail < Group
+ expose :shared_with_groups do |group, options|
+ SharedGroupWithGroup.represent(group.shared_with_group_links.public_or_visible_to_user(group, options[:current_user]))
+ end
expose :runners_token, if: lambda { |group, options| options[:user_can_admin_group] }
expose :projects, using: Entities::Project do |group, options|
projects = GroupProjectsFinder.new(
diff --git a/lib/api/entities/merge_request_basic.rb b/lib/api/entities/merge_request_basic.rb
index 1a89a83a619..1643f267938 100644
--- a/lib/api/entities/merge_request_basic.rb
+++ b/lib/api/entities/merge_request_basic.rb
@@ -6,19 +6,15 @@ module API
expose :merged_by, using: Entities::UserBasic do |merge_request, _options|
merge_request.metrics&.merged_by
end
-
expose :merged_at do |merge_request, _options|
merge_request.metrics&.merged_at
end
-
expose :closed_by, using: Entities::UserBasic do |merge_request, _options|
merge_request.metrics&.latest_closed_by
end
-
expose :closed_at do |merge_request, _options|
merge_request.metrics&.latest_closed_at
end
-
expose :title_html, if: -> (_, options) { options[:render_html] } do |entity|
MarkupHelper.markdown_field(entity, :title)
end
@@ -33,7 +29,6 @@ module API
merge_request.assignee
end
expose :author, :assignees, using: Entities::UserBasic
-
expose :source_project_id, :target_project_id
expose :labels do |merge_request, options|
if options[:with_labels_details]
@@ -85,11 +80,8 @@ module API
end
expose :squash
-
expose :task_completion_status
-
expose :cannot_be_merged?, as: :has_conflicts
-
expose :mergeable_discussions_state?, as: :blocking_discussions_resolved
end
end
diff --git a/lib/api/entities/project.rb b/lib/api/entities/project.rb
index 39cd2d610e4..55a57501858 100644
--- a/lib/api/entities/project.rb
+++ b/lib/api/entities/project.rb
@@ -90,9 +90,10 @@ module API
expose :build_coverage_regex
expose :ci_config_path, if: -> (project, options) { Ability.allowed?(options[:current_user], :download_code, project) }
expose :shared_with_groups do |project, options|
- SharedGroup.represent(project.project_group_links, options)
+ SharedGroupWithProject.represent(project.project_group_links, options)
end
expose :only_allow_merge_if_pipeline_succeeds
+ expose :allow_merge_on_skipped_pipeline
expose :request_access_enabled
expose :only_allow_merge_if_all_discussions_are_resolved
expose :remove_source_branch_after_merge
@@ -119,6 +120,7 @@ module API
# MR describing the solution: https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/20555
super(projects_relation).preload(:group)
.preload(:ci_cd_settings)
+ .preload(:project_setting)
.preload(:container_expiration_policy)
.preload(:auto_devops)
.preload(project_group_links: { group: :route },
diff --git a/lib/api/entities/releases/evidence.rb b/lib/api/entities/releases/evidence.rb
index 25b2bf6bf6f..01603a71dbf 100644
--- a/lib/api/entities/releases/evidence.rb
+++ b/lib/api/entities/releases/evidence.rb
@@ -6,7 +6,7 @@ module API
class Evidence < Grape::Entity
include ::API::Helpers::Presentable
- expose :summary_sha, as: :sha
+ expose :sha
expose :filepath
expose :collected_at
end
diff --git a/lib/api/entities/releases/link.rb b/lib/api/entities/releases/link.rb
index f4edb83bd58..654df2e2caf 100644
--- a/lib/api/entities/releases/link.rb
+++ b/lib/api/entities/releases/link.rb
@@ -9,6 +9,7 @@ module API
expose :url
expose :direct_asset_url
expose :external?, as: :external
+ expose :link_type
def direct_asset_url
return object.url unless object.filepath
diff --git a/lib/api/entities/resource_milestone_event.rb b/lib/api/entities/resource_milestone_event.rb
new file mode 100644
index 00000000000..26dc6620cbe
--- /dev/null
+++ b/lib/api/entities/resource_milestone_event.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module API
+ module Entities
+ class ResourceMilestoneEvent < Grape::Entity
+ expose :id
+ expose :user, using: Entities::UserBasic
+ expose :created_at
+ expose :resource_type do |event, _options|
+ event.issuable.class.name
+ end
+ expose :resource_id do |event, _options|
+ event.issuable.id
+ end
+ expose :milestone, using: Entities::Milestone
+ expose :action
+ expose :state
+ end
+ end
+end
diff --git a/lib/api/entities/runner_details.rb b/lib/api/entities/runner_details.rb
index 1dd8543d595..0afe298ef64 100644
--- a/lib/api/entities/runner_details.rb
+++ b/lib/api/entities/runner_details.rb
@@ -11,13 +11,6 @@ module API
expose :version, :revision, :platform, :architecture
expose :contacted_at
- # Will be removed: https://gitlab.com/gitlab-org/gitlab/-/issues/217105
- expose(:token, if: ->(runner, options) do
- return false if ::Feature.enabled?(:hide_token_from_runners_api, default_enabled: true)
-
- options[:current_user].admin? || !runner.instance_type?
- end)
-
# rubocop: disable CodeReuse/ActiveRecord
expose :projects, with: Entities::BasicProjectDetails do |runner, options|
if options[:current_user].admin?
diff --git a/lib/api/entities/shared_group.rb b/lib/api/entities/shared_group.rb
deleted file mode 100644
index 862e73e07f0..00000000000
--- a/lib/api/entities/shared_group.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-module API
- module Entities
- class SharedGroup < Grape::Entity
- expose :group_id
- expose :group_name do |group_link, options|
- group_link.group.name
- end
- expose :group_full_path do |group_link, options|
- group_link.group.full_path
- end
- expose :group_access, as: :group_access_level
- expose :expires_at
- end
- end
-end
diff --git a/lib/api/entities/shared_group_with_group.rb b/lib/api/entities/shared_group_with_group.rb
new file mode 100644
index 00000000000..1ca879182eb
--- /dev/null
+++ b/lib/api/entities/shared_group_with_group.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module API
+ module Entities
+ class SharedGroupWithGroup < Grape::Entity
+ expose :shared_with_group_id, as: :group_id
+ expose :group_name do |group_link|
+ group_link.shared_with_group.name
+ end
+ expose :group_full_path do |group_link|
+ group_link.shared_with_group.full_path
+ end
+ expose :group_access, as: :group_access_level
+ expose :expires_at
+ end
+ end
+end
diff --git a/lib/api/entities/shared_group_with_project.rb b/lib/api/entities/shared_group_with_project.rb
new file mode 100644
index 00000000000..d91bee31b04
--- /dev/null
+++ b/lib/api/entities/shared_group_with_project.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module API
+ module Entities
+ class SharedGroupWithProject < Grape::Entity
+ expose :group_id
+ expose :group_name do |group_link, options|
+ group_link.group.name
+ end
+ expose :group_full_path do |group_link, options|
+ group_link.group.full_path
+ end
+ expose :group_access, as: :group_access_level
+ expose :expires_at
+ end
+ end
+end
diff --git a/lib/api/entities/ssh_key.rb b/lib/api/entities/ssh_key.rb
index aae216173c7..e1554730cb6 100644
--- a/lib/api/entities/ssh_key.rb
+++ b/lib/api/entities/ssh_key.rb
@@ -3,7 +3,8 @@
module API
module Entities
class SSHKey < Grape::Entity
- expose :id, :title, :key, :created_at, :expires_at
+ expose :id, :title, :created_at, :expires_at
+ expose :publishable_key, as: :key
end
end
end
diff --git a/lib/api/entities/user_with_admin.rb b/lib/api/entities/user_with_admin.rb
index d3df12200ff..c225ade6eb6 100644
--- a/lib/api/entities/user_with_admin.rb
+++ b/lib/api/entities/user_with_admin.rb
@@ -4,8 +4,7 @@ module API
module Entities
class UserWithAdmin < UserPublic
expose :admin?, as: :is_admin
+ expose :note
end
end
end
-
-API::Entities::UserWithAdmin.prepend_if_ee('EE::API::Entities::UserWithAdmin', with_descendants: true)
diff --git a/lib/api/features.rb b/lib/api/features.rb
index f507919b055..3fb3fc92e42 100644
--- a/lib/api/features.rb
+++ b/lib/api/features.rb
@@ -61,7 +61,7 @@ module API
mutually_exclusive :key, :project
end
post ':name' do
- feature = Feature.get(params[:name])
+ feature = Feature.get(params[:name]) # rubocop:disable Gitlab/AvoidFeatureGet
targets = gate_targets(params)
value = gate_value(params)
key = gate_key(params)
@@ -92,7 +92,7 @@ module API
desc 'Remove the gate value for the given feature'
delete ':name' do
- Feature.get(params[:name]).remove
+ Feature.remove(params[:name])
no_content!
end
diff --git a/lib/api/group_container_repositories.rb b/lib/api/group_container_repositories.rb
index 7f95b411b36..d34317b5271 100644
--- a/lib/api/group_container_repositories.rb
+++ b/lib/api/group_container_repositories.rb
@@ -20,6 +20,7 @@ module API
params do
use :pagination
optional :tags, type: Boolean, default: false, desc: 'Determines if tags should be included'
+ optional :tags_count, type: Boolean, default: false, desc: 'Determines if the tags count should be included'
end
get ':id/registry/repositories' do
repositories = ContainerRepositoriesFinder.new(
@@ -28,7 +29,7 @@ module API
track_event('list_repositories')
- present paginate(repositories), with: Entities::ContainerRegistry::Repository, tags: params[:tags]
+ present paginate(repositories), with: Entities::ContainerRegistry::Repository, tags: params[:tags], tags_count: params[:tags_count]
end
end
diff --git a/lib/api/group_export.rb b/lib/api/group_export.rb
index 8ca5dfa082e..d3010b6d147 100644
--- a/lib/api/group_export.rb
+++ b/lib/api/group_export.rb
@@ -2,6 +2,8 @@
module API
class GroupExport < Grape::API
+ helpers Helpers::RateLimiter
+
before do
not_found! unless Feature.enabled?(:group_import_export, user_group, default_enabled: true)
@@ -16,6 +18,8 @@ module API
detail 'This feature was introduced in GitLab 12.5.'
end
get ':id/export/download' do
+ check_rate_limit! :group_download_export, [current_user, user_group]
+
if user_group.export_file_exists?
present_carrierwave_file!(user_group.export_file)
else
@@ -27,6 +31,8 @@ module API
detail 'This feature was introduced in GitLab 12.5.'
end
post ':id/export' do
+ check_rate_limit! :group_export, [current_user]
+
export_service = ::Groups::ImportExport::ExportService.new(group: user_group, user: current_user)
if export_service.async_execute
diff --git a/lib/api/group_import.rb b/lib/api/group_import.rb
index ec51c2f44c3..afcbc24d3ce 100644
--- a/lib/api/group_import.rb
+++ b/lib/api/group_import.rb
@@ -2,8 +2,6 @@
module API
class GroupImport < Grape::API
- MAXIMUM_FILE_SIZE = 50.megabytes.freeze
-
helpers Helpers::FileUploadHelpers
helpers do
@@ -40,7 +38,10 @@ module API
status 200
content_type Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE
- ImportExportUploader.workhorse_authorize(has_length: false, maximum_size: MAXIMUM_FILE_SIZE)
+ ImportExportUploader.workhorse_authorize(
+ has_length: false,
+ maximum_size: Gitlab::CurrentSettings.max_import_size.megabytes
+ )
end
desc 'Create a new group import' do
@@ -69,7 +70,7 @@ module API
group = ::Groups::CreateService.new(current_user, group_params).execute
if group.persisted?
- GroupImportWorker.perform_async(current_user.id, group.id) # rubocop:disable CodeReuse/Worker
+ ::Groups::ImportExport::ImportService.new(group: group, user: current_user).async_execute
accepted!
else
diff --git a/lib/api/groups.rb b/lib/api/groups.rb
index 353c8b4b242..6e07bb46721 100644
--- a/lib/api/groups.rb
+++ b/lib/api/groups.rb
@@ -23,13 +23,20 @@ module API
optional :order_by, type: String, values: %w[name path id], default: 'name', desc: 'Order by name, path or id'
optional :sort, type: String, values: %w[asc desc], default: 'asc', desc: 'Sort by asc (ascending) or desc (descending)'
optional :min_access_level, type: Integer, values: Gitlab::Access.all_values, desc: 'Minimum access level of authenticated user'
+ optional :top_level_only, type: Boolean, desc: 'Only include top level groups'
use :pagination
end
# rubocop: disable CodeReuse/ActiveRecord
def find_groups(params, parent_id = nil)
find_params = params.slice(:all_available, :custom_attributes, :owned, :min_access_level)
- find_params[:parent] = find_group!(parent_id) if parent_id
+
+ find_params[:parent] = if params[:top_level_only]
+ [nil]
+ elsif parent_id
+ find_group!(parent_id)
+ end
+
find_params[:all_available] =
find_params.fetch(:all_available, current_user&.can_read_all_resources?)
@@ -144,6 +151,7 @@ module API
end
group = create_group
+ group.preload_shared_group_links
if group.persisted?
present group, with: Entities::GroupDetail, current_user: current_user
@@ -168,6 +176,8 @@ module API
end
put ':id' do
group = find_group!(params[:id])
+ group.preload_shared_group_links
+
authorize! :admin_group, group
if update_group(group)
@@ -186,6 +196,7 @@ module API
end
get ":id" do
group = find_group!(params[:id])
+ group.preload_shared_group_links
options = {
with: params[:with_projects] ? Entities::GroupDetail : Entities::Group,
@@ -292,6 +303,7 @@ module API
post ":id/projects/:project_id", requirements: { project_id: /.+/ } do
authenticated_as_admin!
group = find_group!(params[:id])
+ group.preload_shared_group_links
project = find_project!(params[:project_id])
result = ::Projects::TransferService.new(project, current_user).execute(group)
@@ -301,6 +313,49 @@ module API
render_api_error!("Failed to transfer project #{project.errors.messages}", 400)
end
end
+
+ desc 'Share a group with a group' do
+ success Entities::GroupDetail
+ end
+ params do
+ requires :group_id, type: Integer, desc: 'The ID of the group to share'
+ requires :group_access, type: Integer, values: Gitlab::Access.all_values, desc: 'The group access level'
+ optional :expires_at, type: Date, desc: 'Share expiration date'
+ end
+ post ":id/share" do
+ shared_group = find_group!(params[:id])
+ shared_with_group = find_group!(params[:group_id])
+
+ group_link_create_params = {
+ shared_group_access: params[:group_access],
+ expires_at: params[:expires_at]
+ }
+
+ result = ::Groups::GroupLinks::CreateService.new(shared_with_group, current_user, group_link_create_params).execute(shared_group)
+ shared_group.preload_shared_group_links
+
+ if result[:status] == :success
+ present shared_group, with: Entities::GroupDetail, current_user: current_user
+ else
+ render_api_error!(result[:message], result[:http_status])
+ end
+ end
+
+ params do
+ requires :group_id, type: Integer, desc: 'The ID of the shared group'
+ end
+ # rubocop: disable CodeReuse/ActiveRecord
+ delete ":id/share/:group_id" do
+ shared_group = find_group!(params[:id])
+
+ link = shared_group.shared_with_group_links.find_by(shared_with_group_id: params[:group_id])
+ not_found!('Group Link') unless link
+
+ ::Groups::GroupLinks::DestroyService.new(shared_group, current_user).execute(link)
+
+ no_content!
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
end
end
end
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index c6f6dc255d4..bbdb45da3b1 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -437,7 +437,7 @@ module API
if report_exception?(exception)
define_params_for_grape_middleware
Gitlab::ErrorTracking.with_context(current_user) do
- Gitlab::ErrorTracking.track_exception(exception, params)
+ Gitlab::ErrorTracking.track_exception(exception)
end
end
diff --git a/lib/api/helpers/issues_helpers.rb b/lib/api/helpers/issues_helpers.rb
index e272b13f3ae..638b31cc7ba 100644
--- a/lib/api/helpers/issues_helpers.rb
+++ b/lib/api/helpers/issues_helpers.rb
@@ -24,6 +24,8 @@ module API
:discussion_locked,
:due_date,
:labels,
+ :add_labels,
+ :remove_labels,
:milestone_id,
:state_event,
:title
diff --git a/lib/api/helpers/notes_helpers.rb b/lib/api/helpers/notes_helpers.rb
index c85a38fc18b..f88624ed63e 100644
--- a/lib/api/helpers/notes_helpers.rb
+++ b/lib/api/helpers/notes_helpers.rb
@@ -133,7 +133,7 @@ module API
if resolved
parent = noteable_parent(noteable)
- ::Discussions::ResolveService.new(parent, current_user, merge_request: noteable).execute(discussion)
+ ::Discussions::ResolveService.new(parent, current_user, one_or_more_discussions: discussion).execute
else
discussion.unresolve!
end
diff --git a/lib/api/helpers/projects_helpers.rb b/lib/api/helpers/projects_helpers.rb
index 5afdb34da97..8a115d42929 100644
--- a/lib/api/helpers/projects_helpers.rb
+++ b/lib/api/helpers/projects_helpers.rb
@@ -44,6 +44,7 @@ module API
optional :public_builds, type: Boolean, desc: 'Perform public builds'
optional :request_access_enabled, type: Boolean, desc: 'Allow users to request member access'
optional :only_allow_merge_if_pipeline_succeeds, type: Boolean, desc: 'Only allow to merge if builds succeed'
+ optional :allow_merge_on_skipped_pipeline, type: Boolean, desc: 'Allow to merge if pipeline is skipped'
optional :only_allow_merge_if_all_discussions_are_resolved, type: Boolean, desc: 'Only allow to merge if all discussions are resolved'
optional :tag_list, type: Array[String], desc: 'The list of tags for a project'
# TODO: remove rubocop disable - https://gitlab.com/gitlab-org/gitlab/issues/14960
@@ -92,6 +93,7 @@ module API
def self.update_params_at_least_one_of
[
+ :allow_merge_on_skipped_pipeline,
:autoclose_referenced_issues,
:auto_devops_enabled,
:auto_devops_deploy_strategy,
diff --git a/lib/api/helpers/runner.rb b/lib/api/helpers/runner.rb
index 1f1253c8542..293d7ed9a6a 100644
--- a/lib/api/helpers/runner.rb
+++ b/lib/api/helpers/runner.rb
@@ -3,6 +3,8 @@
module API
module Helpers
module Runner
+ include Gitlab::Utils::StrongMemoize
+
prepend_if_ee('EE::API::Helpers::Runner') # rubocop: disable Cop/InjectEnterpriseEditionModule
JOB_TOKEN_HEADER = 'HTTP_JOB_TOKEN'
@@ -16,7 +18,7 @@ module API
forbidden! unless current_runner
current_runner
- .update_cached_info(get_runner_details_from_request)
+ .heartbeat(get_runner_details_from_request)
end
def get_runner_details_from_request
@@ -31,31 +33,35 @@ module API
end
def current_runner
- @runner ||= ::Ci::Runner.find_by_token(params[:token].to_s)
+ strong_memoize(:current_runner) do
+ ::Ci::Runner.find_by_token(params[:token].to_s)
+ end
end
- def validate_job!(job)
- not_found! unless job
+ def authenticate_job!(require_running: true)
+ job = current_job
- yield if block_given?
+ not_found! unless job
+ forbidden! unless job_token_valid?(job)
- project = job.project
- forbidden!('Project has been deleted!') if project.nil? || project.pending_delete?
+ forbidden!('Project has been deleted!') if job.project.nil? || job.project.pending_delete?
forbidden!('Job has been erased!') if job.erased?
- end
- def authenticate_job!
- job = current_job
+ if require_running
+ job_forbidden!(job, 'Job is not running') unless job.running?
+ end
- validate_job!(job) do
- forbidden! unless job_token_valid?(job)
+ if Gitlab::Ci::Features.job_heartbeats_runner?(job.project)
+ job.runner&.heartbeat(get_runner_ip)
end
job
end
def current_job
- @current_job ||= Ci::Build.find_by_id(params[:id])
+ strong_memoize(:current_job) do
+ Ci::Build.find_by_id(params[:id])
+ end
end
def job_token_valid?(job)
diff --git a/lib/api/helpers/services_helpers.rb b/lib/api/helpers/services_helpers.rb
index 02e60ff5db5..3d6039cacaa 100644
--- a/lib/api/helpers/services_helpers.rb
+++ b/lib/api/helpers/services_helpers.rb
@@ -583,6 +583,18 @@ module API
name: :api_url,
type: String,
desc: 'Prometheus API Base URL, like http://prometheus.example.com/'
+ },
+ {
+ required: true,
+ name: :google_iap_audience_client_id,
+ type: String,
+ desc: 'Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)'
+ },
+ {
+ required: true,
+ name: :google_iap_service_account_json,
+ type: String,
+ desc: 'Contents of the credentials.json file of your service account, like: { "type": "service_account", "project_id": ... }'
}
],
'pushover' => [
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
index be50c3e0381..2374ac11f4a 100644
--- a/lib/api/issues.rb
+++ b/lib/api/issues.rb
@@ -5,7 +5,6 @@ module API
include PaginationParams
helpers Helpers::IssuesHelpers
helpers Helpers::RateLimiter
- helpers ::Gitlab::IssuableMetadata
before { authenticate_non_get! }
@@ -67,6 +66,8 @@ module API
optional :assignee_id, type: Integer, desc: '[Deprecated] The ID of a user to assign issue'
optional :milestone_id, type: Integer, desc: 'The ID of a milestone to assign issue'
optional :labels, type: Array[String], coerce_with: Validations::Types::LabelsList.coerce, desc: 'Comma-separated list of label names'
+ optional :add_labels, type: Array[String], coerce_with: Validations::Types::LabelsList.coerce, desc: 'Comma-separated list of label names'
+ optional :remove_labels, type: Array[String], coerce_with: Validations::Types::LabelsList.coerce, desc: 'Comma-separated list of label names'
optional :due_date, type: String, desc: 'Date string in the format YEAR-MONTH-DAY'
optional :confidential, type: Boolean, desc: 'Boolean parameter if the issue should be confidential'
optional :discussion_locked, type: Boolean, desc: " Boolean parameter indicating if the issue's discussion is locked"
@@ -106,7 +107,7 @@ module API
with: Entities::Issue,
with_labels_details: declared_params[:with_labels_details],
current_user: current_user,
- issuable_metadata: issuable_meta_data(issues, 'Issue', current_user),
+ issuable_metadata: Gitlab::IssuableMetadata.new(current_user, issues).data,
include_subscribed: false
}
@@ -132,7 +133,7 @@ module API
with: Entities::Issue,
with_labels_details: declared_params[:with_labels_details],
current_user: current_user,
- issuable_metadata: issuable_meta_data(issues, 'Issue', current_user),
+ issuable_metadata: Gitlab::IssuableMetadata.new(current_user, issues).data,
include_subscribed: false,
group: user_group
}
@@ -169,7 +170,7 @@ module API
with_labels_details: declared_params[:with_labels_details],
current_user: current_user,
project: user_project,
- issuable_metadata: issuable_meta_data(issues, 'Issue', current_user),
+ issuable_metadata: Gitlab::IssuableMetadata.new(current_user, issues).data,
include_subscribed: false
}
diff --git a/lib/api/jobs.rb b/lib/api/jobs.rb
index 59f0dbe8a9b..61a7fc107ef 100644
--- a/lib/api/jobs.rb
+++ b/lib/api/jobs.rb
@@ -70,6 +70,32 @@ module API
end
# rubocop: enable CodeReuse/ActiveRecord
+ desc 'Get pipeline bridge jobs' do
+ success Entities::Bridge
+ end
+ params do
+ requires :pipeline_id, type: Integer, desc: 'The pipeline ID'
+ use :optional_scope
+ use :pagination
+ end
+ # rubocop: disable CodeReuse/ActiveRecord
+ get ':id/pipelines/:pipeline_id/bridges' do
+ authorize!(:read_build, user_project)
+ pipeline = user_project.ci_pipelines.find(params[:pipeline_id])
+ authorize!(:read_pipeline, pipeline)
+
+ bridges = pipeline.bridges
+ bridges = filter_builds(bridges, params[:scope])
+ bridges = bridges.preload(
+ :metadata,
+ downstream_pipeline: [project: [:route, { namespace: :route }]],
+ project: [:namespace]
+ )
+
+ present paginate(bridges), with: Entities::Bridge
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
desc 'Get a specific job of a project' do
success Entities::Job
end
diff --git a/lib/api/lsif_data.rb b/lib/api/lsif_data.rb
deleted file mode 100644
index a673ccb4af0..00000000000
--- a/lib/api/lsif_data.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-# frozen_string_literal: true
-
-module API
- class LsifData < Grape::API
- MAX_FILE_SIZE = 10.megabytes
-
- before do
- not_found! if Feature.disabled?(:code_navigation, user_project)
- end
-
- params do
- requires :id, type: String, desc: 'The ID of a project'
- requires :commit_id, type: String, desc: 'The ID of a commit'
- end
- resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
- segment ':id/commits/:commit_id' do
- params do
- requires :paths, type: Array, desc: 'The paths of the files'
- end
- get 'lsif/info' do
- authorize! :download_code, user_project
-
- artifact =
- Ci::JobArtifact
- .with_file_types(['lsif'])
- .for_sha(params[:commit_id], @project.id)
- .last
-
- not_found! unless artifact
- authorize! :read_pipeline, artifact.job.pipeline
- file_too_large! if artifact.file.cached_size > MAX_FILE_SIZE
-
- service = ::Projects::LsifDataService.new(artifact.file, @project, params[:commit_id])
-
- params[:paths].to_h { |path| [path, service.execute(path)] }
- end
- end
- end
- end
-end
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb
index ff4ad85115b..773a451d3a8 100644
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -8,7 +8,6 @@ module API
before { authenticate_non_get! }
- helpers ::Gitlab::IssuableMetadata
helpers Helpers::MergeRequestsHelpers
# EE::API::MergeRequests would override the following helpers
@@ -92,10 +91,8 @@ module API
if params[:view] == 'simple'
options[:with] = Entities::MergeRequestSimple
else
- options[:issuable_metadata] = issuable_meta_data(merge_requests, 'MergeRequest', current_user)
- if Feature.enabled?(:mr_list_api_skip_merge_status_recheck, default_enabled: true)
- options[:skip_merge_status_recheck] = !declared_params[:with_merge_status_recheck]
- end
+ options[:issuable_metadata] = Gitlab::IssuableMetadata.new(current_user, merge_requests).data
+ options[:skip_merge_status_recheck] = !declared_params[:with_merge_status_recheck]
end
options
@@ -478,7 +475,7 @@ module API
squash_commit_message: params[:squash_commit_message],
should_remove_source_branch: params[:should_remove_source_branch],
sha: params[:sha] || merge_request.diff_head_sha
- )
+ ).compact
if immediately_mergeable
::MergeRequests::MergeService
diff --git a/lib/api/project_container_repositories.rb b/lib/api/project_container_repositories.rb
index 555fd98b451..2a0099018d9 100644
--- a/lib/api/project_container_repositories.rb
+++ b/lib/api/project_container_repositories.rb
@@ -21,6 +21,7 @@ module API
params do
use :pagination
optional :tags, type: Boolean, default: false, desc: 'Determines if tags should be included'
+ optional :tags_count, type: Boolean, default: false, desc: 'Determines if the tags count should be included'
end
get ':id/registry/repositories' do
repositories = ContainerRepositoriesFinder.new(
@@ -29,7 +30,7 @@ module API
track_event( 'list_repositories')
- present paginate(repositories), with: Entities::ContainerRegistry::Repository, tags: params[:tags]
+ present paginate(repositories), with: Entities::ContainerRegistry::Repository, tags: params[:tags], tags_count: params[:tags_count]
end
desc 'Delete repository' do
@@ -69,11 +70,11 @@ module API
end
params do
requires :repository_id, type: Integer, desc: 'The ID of the repository'
- optional :name_regex_delete, type: String, desc: 'The tag name regexp to delete, specify .* to delete all'
- optional :name_regex, type: String, desc: 'The tag name regexp to delete, specify .* to delete all'
+ optional :name_regex_delete, type: String, untrusted_regexp: true, desc: 'The tag name regexp to delete, specify .* to delete all'
+ optional :name_regex, type: String, untrusted_regexp: true, desc: 'The tag name regexp to delete, specify .* to delete all'
# require either name_regex (deprecated) or name_regex_delete, it is ok to have both
at_least_one_of :name_regex, :name_regex_delete
- optional :name_regex_keep, type: String, desc: 'The tag name regexp to retain'
+ optional :name_regex_keep, type: String, untrusted_regexp: true, desc: 'The tag name regexp to retain'
optional :keep_n, type: Integer, desc: 'Keep n of latest tags with matching name'
optional :older_than, type: String, desc: 'Delete older than: 1h, 1d, 1month'
end
diff --git a/lib/api/project_export.rb b/lib/api/project_export.rb
index 9fd9d13a20c..4b35f245b8c 100644
--- a/lib/api/project_export.rb
+++ b/lib/api/project_export.rb
@@ -25,7 +25,7 @@ module API
detail 'This feature was introduced in GitLab 10.6.'
end
get ':id/export/download' do
- check_rate_limit! :project_download_export, [current_user, :project_download_export, user_project]
+ check_rate_limit! :project_download_export, [current_user, user_project]
if user_project.export_file_exists?
present_carrierwave_file!(user_project.export_file)
@@ -45,7 +45,7 @@ module API
end
end
post ':id/export' do
- check_rate_limit! :project_export, [current_user, :project_export, user_project]
+ check_rate_limit! :project_export, [current_user]
project_export_params = declared_params(include_missing: false)
after_export_params = project_export_params.delete(:upload) || {}
diff --git a/lib/api/project_import.rb b/lib/api/project_import.rb
index 0e83686cab2..17d08d14a20 100644
--- a/lib/api/project_import.rb
+++ b/lib/api/project_import.rb
@@ -30,7 +30,10 @@ module API
status 200
content_type Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE
- ImportExportUploader.workhorse_authorize(has_length: false, maximum_size: MAXIMUM_FILE_SIZE)
+ ImportExportUploader.workhorse_authorize(
+ has_length: false,
+ maximum_size: Gitlab::CurrentSettings.max_import_size.megabytes
+ )
end
params do
diff --git a/lib/api/project_repository_storage_moves.rb b/lib/api/project_repository_storage_moves.rb
index 1a63e984fbf..5de623102fb 100644
--- a/lib/api/project_repository_storage_moves.rb
+++ b/lib/api/project_repository_storage_moves.rb
@@ -24,11 +24,64 @@ module API
detail 'This feature was introduced in GitLab 13.0.'
success Entities::ProjectRepositoryStorageMove
end
- get ':id' do
- storage_move = ProjectRepositoryStorageMove.find(params[:id])
+ params do
+ requires :repository_storage_move_id, type: Integer, desc: 'The ID of a project repository storage move'
+ end
+ get ':repository_storage_move_id' do
+ storage_move = ProjectRepositoryStorageMove.find(params[:repository_storage_move_id])
+
+ present storage_move, with: Entities::ProjectRepositoryStorageMove, current_user: current_user
+ end
+ end
+
+ params do
+ requires :id, type: String, desc: 'The ID of a project'
+ end
+ resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
+ desc 'Get a list of all project repository storage moves' do
+ detail 'This feature was introduced in GitLab 13.1.'
+ success Entities::ProjectRepositoryStorageMove
+ end
+ params do
+ use :pagination
+ end
+ get ':id/repository_storage_moves' do
+ storage_moves = user_project.repository_storage_moves.with_projects.order_created_at_desc
+
+ present paginate(storage_moves), with: Entities::ProjectRepositoryStorageMove, current_user: current_user
+ end
+
+ desc 'Get a project repository storage move' do
+ detail 'This feature was introduced in GitLab 13.1.'
+ success Entities::ProjectRepositoryStorageMove
+ end
+ params do
+ requires :repository_storage_move_id, type: Integer, desc: 'The ID of a project repository storage move'
+ end
+ get ':id/repository_storage_moves/:repository_storage_move_id' do
+ storage_move = user_project.repository_storage_moves.find(params[:repository_storage_move_id])
present storage_move, with: Entities::ProjectRepositoryStorageMove, current_user: current_user
end
+
+ desc 'Schedule a project repository storage move' do
+ detail 'This feature was introduced in GitLab 13.1.'
+ success Entities::ProjectRepositoryStorageMove
+ end
+ params do
+ requires :destination_storage_name, type: String, desc: 'The destination storage shard'
+ end
+ post ':id/repository_storage_moves' do
+ storage_move = user_project.repository_storage_moves.build(
+ declared_params.merge(source_storage_name: user_project.repository_storage)
+ )
+
+ if storage_move.schedule
+ present storage_move, with: Entities::ProjectRepositoryStorageMove, current_user: current_user
+ else
+ render_validation_error!(storage_move)
+ end
+ end
end
end
end
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index f305da681c4..e00fb61f478 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -502,7 +502,9 @@ module API
link = user_project.project_group_links.find_by(group_id: params[:group_id])
not_found!('Group Link') unless link
- destroy_conditionally!(link)
+ destroy_conditionally!(link) do
+ ::Projects::GroupLinks::DestroyService.new(user_project, current_user).execute(link)
+ end
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/lib/api/release/links.rb b/lib/api/release/links.rb
index f72230c084c..07c27f39539 100644
--- a/lib/api/release/links.rb
+++ b/lib/api/release/links.rb
@@ -40,6 +40,7 @@ module API
requires :name, type: String, desc: 'The name of the link'
requires :url, type: String, desc: 'The URL of the link'
optional :filepath, type: String, desc: 'The filepath of the link'
+ optional :link_type, type: String, desc: 'The link type'
end
post 'links' do
authorize! :create_release, release
@@ -75,6 +76,7 @@ module API
optional :name, type: String, desc: 'The name of the link'
optional :url, type: String, desc: 'The URL of the link'
optional :filepath, type: String, desc: 'The filepath of the link'
+ optional :link_type, type: String, desc: 'The link type'
at_least_one_of :name, :url
end
put do
diff --git a/lib/api/releases.rb b/lib/api/releases.rb
index 95b3e90323c..a5bb1a44f1f 100644
--- a/lib/api/releases.rb
+++ b/lib/api/releases.rb
@@ -67,7 +67,6 @@ module API
if result[:status] == :success
log_release_created_audit_event(result[:release])
- create_evidence!
present result[:release], with: Entities::Release, current_user: current_user
else
@@ -169,16 +168,6 @@ module API
def log_release_milestones_updated_audit_event
# This is a separate method so that EE can extend its behaviour
end
-
- def create_evidence!
- return if release.historical_release?
-
- if release.upcoming_release?
- CreateEvidenceWorker.perform_at(release.released_at, release.id) # rubocop:disable CodeReuse/Worker
- else
- CreateEvidenceWorker.perform_async(release.id) # rubocop:disable CodeReuse/Worker
- end
- end
end
end
end
diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb
index 0b2df85f61f..bf4f08ce390 100644
--- a/lib/api/repositories.rb
+++ b/lib/api/repositories.rb
@@ -6,6 +6,8 @@ module API
class Repositories < Grape::API
include PaginationParams
+ helpers ::API::Helpers::HeadersHelpers
+
before { authorize! :download_code, user_project }
params do
@@ -67,6 +69,8 @@ module API
get ':id/repository/blobs/:sha/raw' do
assign_blob_vars!
+ no_cache_headers
+
send_git_blob @repo, @blob
end
diff --git a/lib/api/resource_label_events.rb b/lib/api/resource_label_events.rb
index f7f7c881f4a..1fa6898b92c 100644
--- a/lib/api/resource_label_events.rb
+++ b/lib/api/resource_label_events.rb
@@ -27,10 +27,9 @@ module API
get ":id/#{eventables_str}/:eventable_id/resource_label_events" do
eventable = find_noteable(eventable_type, params[:eventable_id])
- opts = { page: params[:page], per_page: params[:per_page] }
- events = ResourceLabelEventFinder.new(current_user, eventable, opts).execute
+ events = eventable.resource_label_events.inc_relations
- present paginate(events), with: Entities::ResourceLabelEvent
+ present ResourceLabelEvent.visible_to_user?(current_user, paginate(events)), with: Entities::ResourceLabelEvent
end
desc "Get a single #{eventable_type.to_s.downcase} resource label event" do
diff --git a/lib/api/resource_milestone_events.rb b/lib/api/resource_milestone_events.rb
new file mode 100644
index 00000000000..30ff5a9b4be
--- /dev/null
+++ b/lib/api/resource_milestone_events.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+module API
+ class ResourceMilestoneEvents < Grape::API
+ include PaginationParams
+ helpers ::API::Helpers::NotesHelpers
+
+ before { authenticate! }
+
+ [Issue, MergeRequest].each do |eventable_type|
+ parent_type = eventable_type.parent_class.to_s.underscore
+ eventables_str = eventable_type.to_s.underscore.pluralize
+
+ params do
+ requires :id, type: String, desc: "The ID of a #{parent_type}"
+ end
+ resource parent_type.pluralize.to_sym, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
+ desc "Get a list of #{eventable_type.to_s.downcase} resource milestone events" do
+ success Entities::ResourceMilestoneEvent
+ end
+ params do
+ requires :eventable_id, types: [Integer, String], desc: 'The ID of the eventable'
+ use :pagination
+ end
+
+ get ":id/#{eventables_str}/:eventable_id/resource_milestone_events" do
+ eventable = find_noteable(eventable_type, params[:eventable_id])
+
+ opts = { page: params[:page], per_page: params[:per_page] }
+ events = ResourceMilestoneEventFinder.new(current_user, eventable, opts).execute
+
+ present paginate(events), with: Entities::ResourceMilestoneEvent
+ end
+
+ desc "Get a single #{eventable_type.to_s.downcase} resource milestone event" do
+ success Entities::ResourceMilestoneEvent
+ end
+ params do
+ requires :event_id, type: String, desc: 'The ID of a resource milestone event'
+ requires :eventable_id, types: [Integer, String], desc: 'The ID of the eventable'
+ end
+ get ":id/#{eventables_str}/:eventable_id/resource_milestone_events/:event_id" do
+ eventable = find_noteable(eventable_type, params[:eventable_id])
+
+ event = eventable.resource_milestone_events.find(params[:event_id])
+
+ not_found!('ResourceMilestoneEvent') unless can?(current_user, :read_milestone, event.milestone_parent)
+
+ present event, with: Entities::ResourceMilestoneEvent
+ end
+ end
+ end
+ end
+end
diff --git a/lib/api/runner.rb b/lib/api/runner.rb
index 9095aba7340..5f08ebe4a06 100644
--- a/lib/api/runner.rb
+++ b/lib/api/runner.rb
@@ -154,7 +154,6 @@ module API
end
put '/:id' do
job = authenticate_job!
- job_forbidden!(job, 'Job is not running') unless job.running?
job.trace.set(params[:trace]) if params[:trace]
@@ -182,7 +181,6 @@ module API
end
patch '/:id/trace' do
job = authenticate_job!
- job_forbidden!(job, 'Job is not running') unless job.running?
error!('400 Missing header Content-Range', 400) unless request.headers.key?('Content-Range')
content_range = request.headers['Content-Range']
@@ -220,6 +218,8 @@ module API
requires :id, type: Integer, desc: %q(Job's ID)
optional :token, type: String, desc: %q(Job's authentication token)
optional :filesize, type: Integer, desc: %q(Artifacts filesize)
+ optional :artifact_type, type: String, desc: %q(The type of artifact),
+ default: 'archive', values: Ci::JobArtifact.file_types.keys
end
post '/:id/artifacts/authorize' do
not_allowed! unless Gitlab.config.artifacts.enabled
@@ -227,18 +227,15 @@ module API
Gitlab::Workhorse.verify_api_request!(headers)
job = authenticate_job!
- forbidden!('Job is not running') unless job.running?
- max_size = max_artifacts_size(job)
+ service = Ci::AuthorizeJobArtifactService.new(job, params, max_size: max_artifacts_size(job))
- if params[:filesize]
- file_size = params[:filesize].to_i
- file_too_large! unless file_size < max_size
- end
+ forbidden! if service.forbidden?
+ file_too_large! if service.too_large?
status 200
content_type Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE
- JobArtifactUploader.workhorse_authorize(has_length: false, maximum_size: max_size)
+ service.headers
end
desc 'Upload artifacts for job' do
@@ -265,7 +262,6 @@ module API
require_gitlab_workhorse!
job = authenticate_job!
- forbidden!('Job is not running!') unless job.running?
artifacts = params[:file]
metadata = params[:metadata]
@@ -292,7 +288,7 @@ module API
optional :direct_download, default: false, type: Boolean, desc: %q(Perform direct download from remote storage instead of proxying artifacts)
end
get '/:id/artifacts' do
- job = authenticate_job!
+ job = authenticate_job!(require_running: false)
present_carrierwave_file!(job.artifacts_file, supports_direct_download: params[:direct_download])
end
diff --git a/lib/api/search.rb b/lib/api/search.rb
index 3d2d4527e30..ac00d3682a0 100644
--- a/lib/api/search.rb
+++ b/lib/api/search.rb
@@ -20,6 +20,13 @@ module API
users: Entities::UserBasic
}.freeze
+ SCOPE_PRELOAD_METHOD = {
+ merge_requests: :with_api_entity_associations,
+ projects: :with_api_entity_associations,
+ issues: :with_api_entity_associations,
+ milestones: :with_api_entity_associations
+ }.freeze
+
def search(additional_params = {})
search_params = {
scope: params[:scope],
@@ -29,7 +36,9 @@ module API
per_page: params[:per_page]
}.merge(additional_params)
- results = SearchService.new(current_user, search_params).search_objects
+ results = SearchService.new(current_user, search_params).search_objects(preload_method)
+
+ Gitlab::UsageDataCounters::SearchCounter.count(:all_searches)
paginate(results)
end
@@ -42,6 +51,10 @@ module API
SCOPE_ENTITY[params[:scope].to_sym]
end
+ def preload_method
+ SCOPE_PRELOAD_METHOD[params[:scope].to_sym]
+ end
+
def verify_search_scope!(resource:)
# In EE we have additional validation requirements for searches.
# Defining this method here as a noop allows us to easily extend it in
diff --git a/lib/api/settings.rb b/lib/api/settings.rb
index e3a8f0671ef..0bf5eed26b4 100644
--- a/lib/api/settings.rb
+++ b/lib/api/settings.rb
@@ -83,6 +83,7 @@ module API
desc: 'Enabled sources for code import during project creation. OmniAuth must be configured for GitHub, Bitbucket, and GitLab.com'
optional :max_artifacts_size, type: Integer, desc: "Set the maximum file size for each job's artifacts"
optional :max_attachment_size, type: Integer, desc: 'Maximum attachment size in MB'
+ optional :max_import_size, type: Integer, desc: 'Maximum import size in MB'
optional :max_pages_size, type: Integer, desc: 'Maximum size of pages in MB'
optional :metrics_method_call_threshold, type: Integer, desc: 'A method call is only tracked when it takes longer to complete than the given amount of milliseconds.'
optional :password_authentication_enabled, type: Boolean, desc: 'Flag indicating if password authentication is enabled for the web interface' # support legacy names, can be removed in v5
@@ -113,6 +114,7 @@ module API
end
optional :repository_checks_enabled, type: Boolean, desc: "GitLab will periodically run 'git fsck' in all project and wiki repositories to look for silent disk corruption issues."
optional :repository_storages, type: Array[String], desc: 'Storage paths for new projects'
+ optional :repository_storages_weighted, type: Hash, desc: 'Storage paths for new projects with a weighted value between 0 and 100'
optional :require_two_factor_authentication, type: Boolean, desc: 'Require all users to set up Two-factor authentication'
given require_two_factor_authentication: ->(val) { val } do
requires :two_factor_grace_period, type: Integer, desc: 'Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication'
@@ -132,6 +134,10 @@ module API
given sourcegraph_enabled: ->(val) { val } do
requires :sourcegraph_url, type: String, desc: 'The configured Sourcegraph instance URL'
end
+ optional :spam_check_endpoint_enabled, type: Boolean, desc: 'Enable Spam Check via external API endpoint'
+ given spam_check_endpoint_enabled: ->(val) { val } do
+ requires :spam_check_endpoint_url, type: String, desc: 'The URL of the external Spam Check service endpoint'
+ end
optional :terminal_max_session_time, type: Integer, desc: 'Maximum time for web terminal websocket connection (in seconds). Set to 0 for unlimited time.'
optional :usage_ping_enabled, type: Boolean, desc: 'Every week GitLab will report license usage back to GitLab, Inc.'
optional :instance_statistics_visibility_private, type: Boolean, desc: 'When set to `true` Instance statistics will only be available to admins'
diff --git a/lib/api/suggestions.rb b/lib/api/suggestions.rb
index d008d1b9e97..05aaa8a6f41 100644
--- a/lib/api/suggestions.rb
+++ b/lib/api/suggestions.rb
@@ -14,18 +14,51 @@ module API
put ':id/apply' do
suggestion = Suggestion.find_by_id(params[:id])
- not_found! unless suggestion
- authorize! :apply_suggestion, suggestion
+ if suggestion
+ apply_suggestions(suggestion, current_user)
+ else
+ render_api_error!(_('Suggestion is not applicable as the suggestion was not found.'), :not_found)
+ end
+ end
+
+ desc 'Apply multiple suggestion patches in the Merge Request where they were created' do
+ success Entities::Suggestion
+ end
+ params do
+ requires :ids, type: Array[String], desc: "An array of suggestion ID's"
+ end
+ put 'batch_apply' do
+ ids = params[:ids]
+
+ suggestions = Suggestion.id_in(ids)
- result = ::Suggestions::ApplyService.new(current_user).execute(suggestion)
+ if suggestions.size == ids.length
+ apply_suggestions(suggestions, current_user)
+ else
+ render_api_error!(_('Suggestions are not applicable as one or more suggestions were not found.'), :not_found)
+ end
+ end
+ end
+
+ helpers do
+ def apply_suggestions(suggestions, current_user)
+ authorize_suggestions(*suggestions)
+
+ result = ::Suggestions::ApplyService.new(current_user, *suggestions).execute
if result[:status] == :success
- present suggestion, with: Entities::Suggestion, current_user: current_user
+ present suggestions, with: Entities::Suggestion, current_user: current_user
else
- http_status = result[:http_status] || 400
+ http_status = result[:http_status] || :bad_request
render_api_error!(result[:message], http_status)
end
end
+
+ def authorize_suggestions(*suggestions)
+ suggestions.each do |suggestion|
+ authorize! :apply_suggestion, suggestion
+ end
+ end
end
end
end
diff --git a/lib/api/terraform/state.rb b/lib/api/terraform/state.rb
index 5141d1fd499..e7c9627c753 100644
--- a/lib/api/terraform/state.rb
+++ b/lib/api/terraform/state.rb
@@ -32,7 +32,7 @@ module API
end
desc 'Get a terraform state by its name'
- route_setting :authentication, basic_auth_personal_access_token: true
+ route_setting :authentication, basic_auth_personal_access_token: true, job_token_allowed: :basic_auth
get do
remote_state_handler.find_with_lock do |state|
no_content! unless state.file.exists?
@@ -44,7 +44,7 @@ module API
end
desc 'Add a new terraform state or update an existing one'
- route_setting :authentication, basic_auth_personal_access_token: true
+ route_setting :authentication, basic_auth_personal_access_token: true, job_token_allowed: :basic_auth
post do
data = request.body.read
no_content! if data.empty?
@@ -57,7 +57,7 @@ module API
end
desc 'Delete a terraform state of a certain name'
- route_setting :authentication, basic_auth_personal_access_token: true
+ route_setting :authentication, basic_auth_personal_access_token: true, job_token_allowed: :basic_auth
delete do
remote_state_handler.handle_with_lock do |state|
state.destroy!
@@ -66,7 +66,7 @@ module API
end
desc 'Lock a terraform state of a certain name'
- route_setting :authentication, basic_auth_personal_access_token: true
+ route_setting :authentication, basic_auth_personal_access_token: true, job_token_allowed: :basic_auth
params do
requires :ID, type: String, limit: 255, desc: 'Terraform state lock ID'
requires :Operation, type: String, desc: 'Terraform operation'
@@ -103,7 +103,7 @@ module API
end
desc 'Unlock a terraform state of a certain name'
- route_setting :authentication, basic_auth_personal_access_token: true
+ route_setting :authentication, basic_auth_personal_access_token: true, job_token_allowed: :basic_auth
params do
optional :ID, type: String, limit: 255, desc: 'Terraform state lock ID'
end
diff --git a/lib/api/todos.rb b/lib/api/todos.rb
index 02b8bb55274..e36ddf21277 100644
--- a/lib/api/todos.rb
+++ b/lib/api/todos.rb
@@ -6,8 +6,6 @@ module API
before { authenticate! }
- helpers ::Gitlab::IssuableMetadata
-
ISSUABLE_TYPES = {
'merge_requests' => ->(iid) { find_merge_request_with_access(iid) },
'issues' => ->(iid) { find_project_issue(iid) }
@@ -65,7 +63,7 @@ module API
next unless collection
targets = collection.map(&:target)
- options[type] = { issuable_metadata: issuable_meta_data(targets, type, current_user) }
+ options[type] = { issuable_metadata: Gitlab::IssuableMetadata.new(current_user, targets).data }
end
end
end
@@ -91,16 +89,18 @@ module API
requires :id, type: Integer, desc: 'The ID of the todo being marked as done'
end
post ':id/mark_as_done' do
- TodoService.new.mark_todos_as_done_by_ids(params[:id], current_user)
todo = current_user.todos.find(params[:id])
+ TodoService.new.resolve_todo(todo, current_user, resolved_by_action: :api_done)
+
present todo, with: Entities::Todo, current_user: current_user
end
desc 'Mark all todos as done'
post '/mark_as_done' do
todos = find_todos
- TodoService.new.mark_todos_as_done(todos, current_user)
+
+ TodoService.new.resolve_todos(todos, current_user, resolved_by_action: :api_all_done)
no_content!
end
diff --git a/lib/api/users.rb b/lib/api/users.rb
index c986414c223..3d8ae09edf1 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -55,6 +55,7 @@ module API
optional :theme_id, type: Integer, desc: 'The GitLab theme for the user'
optional :color_scheme_id, type: Integer, desc: 'The color scheme for the file viewer'
optional :private_profile, type: Boolean, desc: 'Flag indicating the user has a private profile'
+ optional :note, type: String, desc: 'Admin note for this user'
all_or_none_of :extern_uid, :provider
use :optional_params_ee
@@ -254,6 +255,7 @@ module API
requires :id, type: Integer, desc: 'The ID of the user'
requires :key, type: String, desc: 'The new SSH key'
requires :title, type: String, desc: 'The title of the new SSH key'
+ optional :expires_at, type: DateTime, desc: 'The expiration date of the SSH key in ISO 8601 format (YYYY-MM-DDTHH:MM:SSZ)'
end
# rubocop: disable CodeReuse/ActiveRecord
post ":id/keys" do
@@ -262,9 +264,9 @@ module API
user = User.find_by(id: params.delete(:id))
not_found!('User') unless user
- key = user.keys.new(declared_params(include_missing: false))
+ key = ::Keys::CreateService.new(current_user, declared_params(include_missing: false).merge(user: user)).execute
- if key.save
+ if key.persisted?
present key, with: Entities::SSHKey
else
render_validation_error!(key)
@@ -283,7 +285,8 @@ module API
user = find_user(params[:user_id])
not_found!('User') unless user && can?(current_user, :read_user, user)
- present paginate(user.keys), with: Entities::SSHKey
+ keys = user.keys.preload_users
+ present paginate(keys), with: Entities::SSHKey
end
desc 'Delete an existing SSH key from a specified user. Available only for admins.' do
@@ -303,7 +306,10 @@ module API
key = user.keys.find_by(id: params[:key_id])
not_found!('Key') unless key
- destroy_conditionally!(key)
+ destroy_conditionally!(key) do |key|
+ destroy_service = ::Keys::DestroyService.new(current_user)
+ destroy_service.execute(key)
+ end
end
# rubocop: enable CodeReuse/ActiveRecord
@@ -695,7 +701,9 @@ module API
use :pagination
end
get "keys" do
- present paginate(current_user.keys), with: Entities::SSHKey
+ keys = current_user.keys.preload_users
+
+ present paginate(keys), with: Entities::SSHKey
end
desc 'Get a single key owned by currently authenticated user' do
@@ -719,6 +727,7 @@ module API
params do
requires :key, type: String, desc: 'The new SSH key'
requires :title, type: String, desc: 'The title of the new SSH key'
+ optional :expires_at, type: DateTime, desc: 'The expiration date of the SSH key in ISO 8601 format (YYYY-MM-DDTHH:MM:SSZ)'
end
post "keys" do
key = current_user.keys.new(declared_params)
diff --git a/lib/api/validations/validators/file_path.rb b/lib/api/validations/validators/file_path.rb
index 93a20e5bf7d..fee71373170 100644
--- a/lib/api/validations/validators/file_path.rb
+++ b/lib/api/validations/validators/file_path.rb
@@ -8,7 +8,7 @@ module API
path = params[attr_name]
Gitlab::Utils.check_path_traversal!(path)
- rescue StandardError
+ rescue ::Gitlab::Utils::PathTraversalAttackError
raise Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)],
message: "should be a valid file path"
end
diff --git a/lib/api/validations/validators/untrusted_regexp.rb b/lib/api/validations/validators/untrusted_regexp.rb
new file mode 100644
index 00000000000..ec623684e67
--- /dev/null
+++ b/lib/api/validations/validators/untrusted_regexp.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module API
+ module Validations
+ module Validators
+ class UntrustedRegexp < Grape::Validations::Base
+ def validate_param!(attr_name, params)
+ value = params[attr_name]
+ return unless value
+
+ Gitlab::UntrustedRegexp.new(value)
+ rescue RegexpError => e
+ message = "is an invalid regexp: #{e.message}"
+ raise Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: message
+ end
+ end
+ end
+ end
+end
diff --git a/lib/api/wikis.rb b/lib/api/wikis.rb
index 884e3019a2d..c1bf3a64923 100644
--- a/lib/api/wikis.rb
+++ b/lib/api/wikis.rb
@@ -24,7 +24,7 @@ module API
params :common_wiki_page_params do
optional :format,
type: String,
- values: ProjectWiki::MARKUPS.values.map(&:to_s),
+ values: Wiki::MARKUPS.values.map(&:to_s),
default: 'markdown',
desc: 'Format of a wiki page. Available formats are markdown, rdoc, asciidoc and org'
end
diff --git a/lib/backup/files.rb b/lib/backup/files.rb
index 098f2da6d88..5e784dadb14 100644
--- a/lib/backup/files.rb
+++ b/lib/backup/files.rb
@@ -78,7 +78,8 @@ module Backup
return if status.compact.all?(&:success?)
regex = /^g?tar: \.: Cannot mkdir: No such file or directory$/
- raise Backup::Error, 'Backup failed' unless err_r.read =~ regex
+ error = err_r.read
+ raise Backup::Error, "Backup failed. #{error}" unless error =~ regex
end
end
end
diff --git a/lib/banzai/filter/ascii_doc_sanitization_filter.rb b/lib/banzai/filter/ascii_doc_sanitization_filter.rb
index e41f7d8488a..a1a204ec652 100644
--- a/lib/banzai/filter/ascii_doc_sanitization_filter.rb
+++ b/lib/banzai/filter/ascii_doc_sanitization_filter.rb
@@ -18,6 +18,7 @@ module Banzai
# Classes used by Asciidoctor to style components
ADMONITION_CLASSES = %w(fa icon-note icon-tip icon-warning icon-caution icon-important).freeze
+ ALIGNMENT_BUILTINS_CLASSES = %w(text-center text-left text-right text-justify).freeze
CALLOUT_CLASSES = ['conum'].freeze
CHECKLIST_CLASSES = %w(fa fa-check-square-o fa-square-o).freeze
LIST_CLASSES = %w(checklist none no-bullet unnumbered unstyled).freeze
@@ -28,7 +29,7 @@ module Banzai
ELEMENT_CLASSES_WHITELIST = {
span: %w(big small underline overline line-through).freeze,
- div: ['admonitionblock'].freeze,
+ div: ALIGNMENT_BUILTINS_CLASSES + ['admonitionblock'].freeze,
td: ['icon'].freeze,
i: ADMONITION_CLASSES + CALLOUT_CLASSES + CHECKLIST_CLASSES,
ul: LIST_CLASSES,
diff --git a/lib/banzai/filter/design_reference_filter.rb b/lib/banzai/filter/design_reference_filter.rb
new file mode 100644
index 00000000000..7455dfe00ef
--- /dev/null
+++ b/lib/banzai/filter/design_reference_filter.rb
@@ -0,0 +1,121 @@
+# frozen_string_literal: true
+
+module Banzai
+ module Filter
+ class DesignReferenceFilter < AbstractReferenceFilter
+ FEATURE_FLAG = :design_management_reference_filter_gfm_pipeline
+
+ class Identifier
+ include Comparable
+ attr_reader :issue_iid, :filename
+
+ def initialize(issue_iid:, filename:)
+ @issue_iid = issue_iid
+ @filename = filename
+ end
+
+ def as_composite_id(id_for_iid)
+ id = id_for_iid[issue_iid]
+ return unless id
+
+ { issue_id: id, filename: filename }
+ end
+
+ def <=>(other)
+ return unless other.is_a?(Identifier)
+
+ [issue_iid, filename] <=> [other.issue_iid, other.filename]
+ end
+ alias_method :eql?, :==
+
+ def hash
+ [issue_iid, filename].hash
+ end
+ end
+
+ self.reference_type = :design
+
+ # This filter must be enabled by setting the
+ # design_management_reference_filter_gfm_pipeline flag
+ def call
+ return doc unless enabled?
+
+ super
+ end
+
+ def find_object(project, identifier)
+ records_per_parent[project][identifier]
+ end
+
+ def parent_records(project, identifiers)
+ return [] unless project.design_management_enabled?
+
+ iids = identifiers.map(&:issue_iid).to_set
+ issues = project.issues.where(iid: iids)
+ id_for_iid = issues.index_by(&:iid).transform_values(&:id)
+ issue_by_id = issues.index_by(&:id)
+
+ designs(identifiers, id_for_iid).each do |d|
+ issue = issue_by_id[d.issue_id]
+ # optimisation: assign values we have already fetched
+ d.project = project
+ d.issue = issue
+ end
+ end
+
+ def relation_for_paths(paths)
+ super.includes(:route, :namespace, :group)
+ end
+
+ def parent_type
+ :project
+ end
+
+ # optimisation to reuse the parent_per_reference query information
+ def parent_from_ref(ref)
+ parent_per_reference[ref || current_parent_path]
+ end
+
+ def url_for_object(design, project)
+ path_options = { vueroute: design.filename }
+ Gitlab::Routing.url_helpers.designs_project_issue_path(project, design.issue, path_options)
+ end
+
+ def data_attributes_for(_text, _project, design, **_kwargs)
+ super.merge(issue: design.issue_id)
+ end
+
+ def self.object_class
+ ::DesignManagement::Design
+ end
+
+ def self.object_sym
+ :design
+ end
+
+ def self.parse_symbol(raw, match_data)
+ filename = match_data[:url_filename]
+ iid = match_data[:issue].to_i
+ Identifier.new(filename: CGI.unescape(filename), issue_iid: iid)
+ end
+
+ def record_identifier(design)
+ Identifier.new(filename: design.filename, issue_iid: design.issue.iid)
+ end
+
+ private
+
+ def designs(identifiers, id_for_iid)
+ identifiers
+ .map { |identifier| identifier.as_composite_id(id_for_iid) }
+ .compact
+ .in_groups_of(100, false) # limitation of by_issue_id_and_filename, so we batch
+ .flat_map { |ids| DesignManagement::Design.by_issue_id_and_filename(ids) }
+ end
+
+ def enabled?
+ Feature.enabled?(FEATURE_FLAG, parent)
+ end
+ end
+ end
+end
diff --git a/lib/banzai/filter/external_issue_reference_filter.rb b/lib/banzai/filter/external_issue_reference_filter.rb
index 8159dcfed72..74bc102320c 100644
--- a/lib/banzai/filter/external_issue_reference_filter.rb
+++ b/lib/banzai/filter/external_issue_reference_filter.rb
@@ -54,6 +54,8 @@ module Banzai
doc
end
+ private
+
# Replace `JIRA-123` issue references in text with links to the referenced
# issue's details page.
#
@@ -63,27 +65,31 @@ module Banzai
# Returns a String with `JIRA-123` references replaced with links. All
# links have `gfm` and `gfm-issue` class names attached for styling.
def issue_link_filter(text, link_content: nil)
- project = context[:project]
-
self.class.references_in(text, issue_reference_pattern) do |match, id|
- ExternalIssue.new(id, project)
-
- url = url_for_issue(id, project, only_path: context[:only_path])
-
- title = "Issue in #{project.external_issue_tracker.title}"
+ url = url_for_issue(id)
klass = reference_class(:issue)
data = data_attribute(project: project.id, external_issue: id)
-
content = link_content || match
%(<a href="#{url}" #{data}
- title="#{escape_once(title)}"
+ title="#{escape_once(issue_title)}"
class="#{klass}">#{content}</a>)
end
end
- def url_for_issue(*args)
- IssuesHelper.url_for_issue(*args)
+ def url_for_issue(issue_id)
+ return '' if project.nil?
+
+ url = if only_path?
+ project.external_issue_tracker.issue_path(issue_id)
+ else
+ project.external_issue_tracker.issue_url(issue_id)
+ end
+
+ # Ensure we return a valid URL to prevent possible XSS.
+ URI.parse(url).to_s
+ rescue URI::InvalidURIError
+ ''
end
def default_issues_tracker?
@@ -94,7 +100,13 @@ module Banzai
external_issues_cached(:external_issue_reference_pattern)
end
- private
+ def project
+ context[:project]
+ end
+
+ def issue_title
+ "Issue in #{project.external_issue_tracker.title}"
+ end
def external_issues_cached(attribute)
cached_attributes = Gitlab::SafeRequestStore[:banzai_external_issues_tracker_attributes] ||= Hash.new { |h, k| h[k] = {} }
diff --git a/lib/banzai/filter/gollum_tags_filter.rb b/lib/banzai/filter/gollum_tags_filter.rb
index dec4ec871f1..033e3d2c33e 100644
--- a/lib/banzai/filter/gollum_tags_filter.rb
+++ b/lib/banzai/filter/gollum_tags_filter.rb
@@ -30,7 +30,7 @@ module Banzai
# Note: the table of contents tag is now handled by TableOfContentsTagFilter
#
# Context options:
- # :project_wiki (required) - Current project wiki.
+ # :wiki [Wiki] (required) - Current wiki instance.
#
class GollumTagsFilter < HTML::Pipeline::Filter
include ActionView::Helpers::TagHelper
@@ -100,8 +100,8 @@ module Banzai
if url?(content)
path = content
- elsif file = project_wiki.find_file(content)
- path = ::File.join project_wiki_base_path, file.path
+ elsif file = wiki.find_file(content)
+ path = ::File.join(wiki_base_path, file.path)
end
if path
@@ -134,25 +134,25 @@ module Banzai
if url?(reference)
reference
else
- ::File.join(project_wiki_base_path, reference)
+ ::File.join(wiki_base_path, reference)
end
content_tag(:a, name || reference, href: href, class: 'gfm')
end
- def project_wiki
- context[:project_wiki]
+ def wiki
+ context[:wiki]
end
- def project_wiki_base_path
- project_wiki && project_wiki.wiki_base_path
+ def wiki_base_path
+ wiki&.wiki_base_path
end
- # Ensure that a :project_wiki key exists in context
+ # Ensure that a :wiki key exists in context
#
# Note that while the key might exist, its value could be nil!
def validate
- needs :project_wiki
+ needs :wiki
end
end
end
diff --git a/lib/banzai/filter/issue_reference_filter.rb b/lib/banzai/filter/issue_reference_filter.rb
index 37e66387f2e..dc4b865bfb6 100644
--- a/lib/banzai/filter/issue_reference_filter.rb
+++ b/lib/banzai/filter/issue_reference_filter.rb
@@ -18,7 +18,9 @@ module Banzai
end
def url_for_object(issue, project)
- IssuesHelper.url_for_issue(issue.iid, project, only_path: context[:only_path], internal: true)
+ return issue_path(issue, project) if only_path?
+
+ issue_url(issue, project)
end
def projects_relation_for_paths(paths)
@@ -35,6 +37,14 @@ module Banzai
private
+ def issue_path(issue, project)
+ Gitlab::Routing.url_helpers.namespace_project_issue_path(namespace_id: project.namespace, project_id: project, id: issue.iid)
+ end
+
+ def issue_url(issue, project)
+ Gitlab::Routing.url_helpers.namespace_project_issue_url(namespace_id: project.namespace, project_id: project, id: issue.iid)
+ end
+
def design_link_extras(issue, path)
if path == '/designs' && read_designs?(issue)
['designs']
@@ -44,7 +54,7 @@ module Banzai
end
def read_designs?(issue)
- Ability.allowed?(current_user, :read_design, issue)
+ issue.project.design_management_enabled?
end
end
end
diff --git a/lib/banzai/filter/iteration_reference_filter.rb b/lib/banzai/filter/iteration_reference_filter.rb
new file mode 100644
index 00000000000..9d2b533e6da
--- /dev/null
+++ b/lib/banzai/filter/iteration_reference_filter.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Banzai
+ module Filter
+ # The actual filter is implemented in the EE mixin
+ class IterationReferenceFilter < AbstractReferenceFilter
+ self.reference_type = :iteration
+
+ def self.object_class
+ Iteration
+ end
+ end
+ end
+end
+
+Banzai::Filter::IterationReferenceFilter.prepend_if_ee('EE::Banzai::Filter::IterationReferenceFilter')
diff --git a/lib/banzai/filter/label_reference_filter.rb b/lib/banzai/filter/label_reference_filter.rb
index 60ffb178393..7cda4699ae6 100644
--- a/lib/banzai/filter/label_reference_filter.rb
+++ b/lib/banzai/filter/label_reference_filter.rb
@@ -71,13 +71,16 @@ module Banzai
end
def url_for_object(label, parent)
- h = Gitlab::Routing.url_helpers
+ label_url_method =
+ if context[:label_url_method]
+ context[:label_url_method]
+ elsif parent.is_a?(Project)
+ :project_issues_url
+ end
- if parent.is_a?(Project)
- h.project_issues_url(parent, label_name: label.name, only_path: context[:only_path])
- elsif context[:label_url_method]
- h.public_send(context[:label_url_method], parent, label_name: label.name, only_path: context[:only_path]) # rubocop:disable GitlabSecurity/PublicSend
- end
+ return unless label_url_method
+
+ Gitlab::Routing.url_helpers.public_send(label_url_method, parent, label_name: label.name, only_path: context[:only_path]) # rubocop:disable GitlabSecurity/PublicSend
end
def object_link_text(object, matches)
diff --git a/lib/banzai/filter/reference_filter.rb b/lib/banzai/filter/reference_filter.rb
index 38bbed3cf72..9e932ccf9f8 100644
--- a/lib/banzai/filter/reference_filter.rb
+++ b/lib/banzai/filter/reference_filter.rb
@@ -142,6 +142,12 @@ module Banzai
def element_node?(node)
node.is_a?(Nokogiri::XML::Element)
end
+
+ private
+
+ def only_path?
+ context[:only_path]
+ end
end
end
end
diff --git a/lib/banzai/filter/repository_link_filter.rb b/lib/banzai/filter/repository_link_filter.rb
index 24900217560..66b9aac3e7e 100644
--- a/lib/banzai/filter/repository_link_filter.rb
+++ b/lib/banzai/filter/repository_link_filter.rb
@@ -10,7 +10,7 @@ module Banzai
# :commit
# :current_user
# :project
- # :project_wiki
+ # :wiki
# :ref
# :requested_path
# :system_note
@@ -53,7 +53,7 @@ module Banzai
def linkable_files?
strong_memoize(:linkable_files) do
- context[:project_wiki].nil? && repository.try(:exists?) && !repository.empty?
+ context[:wiki].nil? && repository.try(:exists?) && !repository.empty?
end
end
diff --git a/lib/banzai/filter/wiki_link_filter.rb b/lib/banzai/filter/wiki_link_filter.rb
index 205f777bc90..44f13612fde 100644
--- a/lib/banzai/filter/wiki_link_filter.rb
+++ b/lib/banzai/filter/wiki_link_filter.rb
@@ -6,12 +6,12 @@ module Banzai
# Rewrite rules are documented in the `WikiPipeline` spec.
#
# Context options:
- # :project_wiki
+ # :wiki
class WikiLinkFilter < HTML::Pipeline::Filter
include Gitlab::Utils::SanitizeNodeLink
def call
- return doc unless project_wiki?
+ return doc unless wiki?
doc.search('a:not(.gfm)').each { |el| process_link(el.attribute('href'), el) }
@@ -33,8 +33,8 @@ module Banzai
remove_unsafe_links({ node: node }, remove_invalid_links: false)
end
- def project_wiki?
- !context[:project_wiki].nil?
+ def wiki?
+ !context[:wiki].nil?
end
def process_link_attr(html_attr)
@@ -46,7 +46,7 @@ module Banzai
end
def apply_rewrite_rules(link_string)
- Rewriter.new(link_string, wiki: context[:project_wiki], slug: context[:page_slug]).apply_rules
+ Rewriter.new(link_string, wiki: context[:wiki], slug: context[:page_slug]).apply_rules
end
end
end
diff --git a/lib/banzai/pipeline/gfm_pipeline.rb b/lib/banzai/pipeline/gfm_pipeline.rb
index 329bbb270bd..2ea5fd3388a 100644
--- a/lib/banzai/pipeline/gfm_pipeline.rb
+++ b/lib/banzai/pipeline/gfm_pipeline.rb
@@ -56,6 +56,7 @@ module Banzai
[
Filter::UserReferenceFilter,
Filter::ProjectReferenceFilter,
+ Filter::DesignReferenceFilter,
Filter::IssueReferenceFilter,
Filter::ExternalIssueReferenceFilter,
Filter::MergeRequestReferenceFilter,
diff --git a/lib/banzai/reference_parser/iteration_parser.rb b/lib/banzai/reference_parser/iteration_parser.rb
new file mode 100644
index 00000000000..45253fa1977
--- /dev/null
+++ b/lib/banzai/reference_parser/iteration_parser.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module Banzai
+ module ReferenceParser
+ # The actual parser is implemented in the EE mixin
+ class IterationParser < BaseParser
+ self.reference_type = :iteration
+
+ def references_relation
+ Iteration
+ end
+
+ private
+
+ def can_read_reference?(_user, _ref_project, _node)
+ false
+ end
+ end
+ end
+end
+
+Banzai::ReferenceParser::IterationParser.prepend_if_ee('::EE::Banzai::ReferenceParser::IterationParser')
diff --git a/lib/event_filter.rb b/lib/event_filter.rb
index 8cb0b1441df..538727dc422 100644
--- a/lib/event_filter.rb
+++ b/lib/event_filter.rb
@@ -27,15 +27,15 @@ class EventFilter
case filter
when PUSH
- events.where(action: Event::PUSHED)
+ events.pushed_action
when MERGED
- events.where(action: Event::MERGED)
+ events.merged_action
when COMMENTS
- events.where(action: Event::COMMENTED)
+ events.commented_action
when TEAM
- events.where(action: [Event::JOINED, Event::LEFT, Event::EXPIRED])
+ events.where(action: [:joined, :left, :expired])
when ISSUE
- events.where(action: [Event::CREATED, Event::UPDATED, Event::CLOSED, Event::REOPENED], target_type: 'Issue')
+ events.where(action: [:created, :updated, :closed, :reopened], target_type: 'Issue')
when WIKI
wiki_events(events)
else
diff --git a/lib/extracts_path.rb b/lib/extracts_path.rb
index 44a9c7ea536..4c537eeaa89 100644
--- a/lib/extracts_path.rb
+++ b/lib/extracts_path.rb
@@ -3,79 +3,8 @@
# Module providing methods for dealing with separating a tree-ish string and a
# file path string when combined in a request parameter
module ExtractsPath
- # Raised when given an invalid file path
- InvalidPathError = Class.new(StandardError)
-
- # Given a string containing both a Git tree-ish, such as a branch or tag, and
- # a filesystem path joined by forward slashes, attempts to separate the two.
- #
- # Expects a @project instance variable to contain the active project. This is
- # used to check the input against a list of valid repository refs.
- #
- # Examples
- #
- # # No @project available
- # extract_ref('master')
- # # => ['', '']
- #
- # extract_ref('master')
- # # => ['master', '']
- #
- # extract_ref("f4b14494ef6abf3d144c28e4af0c20143383e062/CHANGELOG")
- # # => ['f4b14494ef6abf3d144c28e4af0c20143383e062', 'CHANGELOG']
- #
- # extract_ref("v2.0.0/README.md")
- # # => ['v2.0.0', 'README.md']
- #
- # extract_ref('master/app/models/project.rb')
- # # => ['master', 'app/models/project.rb']
- #
- # extract_ref('issues/1234/app/models/project.rb')
- # # => ['issues/1234', 'app/models/project.rb']
- #
- # # Given an invalid branch, we fall back to just splitting on the first slash
- # extract_ref('non/existent/branch/README.md')
- # # => ['non', 'existent/branch/README.md']
- #
- # Returns an Array where the first value is the tree-ish and the second is the
- # path
- def extract_ref(id)
- pair = ['', '']
-
- return pair unless @project # rubocop:disable Gitlab/ModuleWithInstanceVariables
-
- if id =~ /^(\h{40})(.+)/
- # If the ref appears to be a SHA, we're done, just split the string
- pair = $~.captures
- else
- # Otherwise, attempt to detect the ref using a list of the project's
- # branches and tags
-
- # Append a trailing slash if we only get a ref and no file path
- unless id.ends_with?('/')
- id = [id, '/'].join
- end
-
- valid_refs = ref_names.select { |v| id.start_with?("#{v}/") }
-
- if valid_refs.empty?
- # No exact ref match, so just try our best
- pair = id.match(%r{([^/]+)(.*)}).captures
- else
- # There is a distinct possibility that multiple refs prefix the ID.
- # Use the longest match to maximize the chance that we have the
- # right ref.
- best_match = valid_refs.max_by(&:length)
- # Partition the string into the ref and the path, ignoring the empty first value
- pair = id.partition(best_match)[1..-1]
- end
- end
-
- # Remove ending slashes from path
- pair[1].gsub!(%r{^/|/$}, '')
-
- pair
- end
+ extend ::Gitlab::Utils::Override
+ include ExtractsRef
# If we have an ID of 'foo.atom', and the controller provides Atom and HTML
# formats, then we have to check if the request was for the Atom version of
@@ -90,34 +19,17 @@ module ExtractsPath
valid_refs.max_by(&:length)
end
- # Assigns common instance variables for views working with Git tree-ish objects
- #
- # Assignments are:
- #
- # - @id - A string representing the joined ref and path
- # - @ref - A string representing the ref (e.g., the branch, tag, or commit SHA)
- # - @path - A string representing the filesystem path
- # - @commit - A Commit representing the commit from the given ref
- #
- # If the :id parameter appears to be requesting a specific response format,
- # that will be handled as well.
- #
- # If there is no path and the ref doesn't exist in the repo, try to resolve
- # the ref without an '.atom' suffix. If _that_ ref is found, set the request's
- # format to Atom manually.
+ # Extends the method to handle if there is no path and the ref doesn't
+ # exist in the repo, try to resolve the ref without an '.atom' suffix.
+ # If _that_ ref is found, set the request's format to Atom manually.
#
# Automatically renders `not_found!` if a valid tree path could not be
# resolved (e.g., when a user inserts an invalid path or ref).
+ #
# rubocop:disable Gitlab/ModuleWithInstanceVariables
+ override :assign_ref_vars
def assign_ref_vars
- @id = get_id
- @ref, @path = extract_ref(@id)
- @repo = @project.repository
- @ref.strip!
-
- raise InvalidPathError if @ref.match?(/\s/)
-
- @commit = @repo.commit(@ref)
+ super
if @path.empty? && !@commit && @id.ends_with?('.atom')
@id = @ref = extract_ref_without_atom(@id)
@@ -135,10 +47,6 @@ module ExtractsPath
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
- def tree
- @tree ||= @repo.tree(@commit.id, @path) # rubocop:disable Gitlab/ModuleWithInstanceVariables
- end
-
def lfs_blob_ids
blob_ids = tree.blobs.map(&:id)
@@ -146,21 +54,13 @@ module ExtractsPath
# the current Blob in order to determine if it's a LFS object
blob_ids = Array.wrap(@repo.blob_at(@commit.id, @path)&.id) if blob_ids.empty? # rubocop:disable Gitlab/ModuleWithInstanceVariables
- @lfs_blob_ids = Gitlab::Git::Blob.batch_lfs_pointers(@project.repository, blob_ids).map(&:id) # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ @lfs_blob_ids = Gitlab::Git::Blob.batch_lfs_pointers(repository_container.repository, blob_ids).map(&:id) # rubocop:disable Gitlab/ModuleWithInstanceVariables
end
private
- # overridden in subclasses, do not remove
- def get_id
- id = [params[:id] || params[:ref]]
- id << "/" + params[:path] unless params[:path].blank?
- id.join
- end
-
- def ref_names
- return [] unless @project # rubocop:disable Gitlab/ModuleWithInstanceVariables
-
- @ref_names ||= @project.repository.ref_names # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ override :repository_container
+ def repository_container
+ @project
end
end
diff --git a/lib/extracts_ref.rb b/lib/extracts_ref.rb
new file mode 100644
index 00000000000..346ed6b6f60
--- /dev/null
+++ b/lib/extracts_ref.rb
@@ -0,0 +1,128 @@
+# frozen_string_literal: true
+
+# Module providing methods for dealing with separating a tree-ish string and a
+# file path string when combined in a request parameter
+# Can be extended for different types of repository object, e.g. Project or Snippet
+module ExtractsRef
+ InvalidPathError = Class.new(StandardError)
+
+ # Given a string containing both a Git tree-ish, such as a branch or tag, and
+ # a filesystem path joined by forward slashes, attempts to separate the two.
+ #
+ # Expects a repository_container method that returns the active repository object. This is
+ # used to check the input against a list of valid repository refs.
+ #
+ # Examples
+ #
+ # # No repository_container available
+ # extract_ref('master')
+ # # => ['', '']
+ #
+ # extract_ref('master')
+ # # => ['master', '']
+ #
+ # extract_ref("f4b14494ef6abf3d144c28e4af0c20143383e062/CHANGELOG")
+ # # => ['f4b14494ef6abf3d144c28e4af0c20143383e062', 'CHANGELOG']
+ #
+ # extract_ref("v2.0.0/README.md")
+ # # => ['v2.0.0', 'README.md']
+ #
+ # extract_ref('master/app/models/project.rb')
+ # # => ['master', 'app/models/project.rb']
+ #
+ # extract_ref('issues/1234/app/models/project.rb')
+ # # => ['issues/1234', 'app/models/project.rb']
+ #
+ # # Given an invalid branch, we fall back to just splitting on the first slash
+ # extract_ref('non/existent/branch/README.md')
+ # # => ['non', 'existent/branch/README.md']
+ #
+ # Returns an Array where the first value is the tree-ish and the second is the
+ # path
+ def extract_ref(id)
+ pair = ['', '']
+
+ return pair unless repository_container
+
+ if id =~ /^(\h{40})(.+)/
+ # If the ref appears to be a SHA, we're done, just split the string
+ pair = $~.captures
+ else
+ # Otherwise, attempt to detect the ref using a list of the repository_container's
+ # branches and tags
+
+ # Append a trailing slash if we only get a ref and no file path
+ unless id.ends_with?('/')
+ id = [id, '/'].join
+ end
+
+ valid_refs = ref_names.select { |v| id.start_with?("#{v}/") }
+
+ if valid_refs.empty?
+ # No exact ref match, so just try our best
+ pair = id.match(%r{([^/]+)(.*)}).captures
+ else
+ # There is a distinct possibility that multiple refs prefix the ID.
+ # Use the longest match to maximize the chance that we have the
+ # right ref.
+ best_match = valid_refs.max_by(&:length)
+ # Partition the string into the ref and the path, ignoring the empty first value
+ pair = id.partition(best_match)[1..-1]
+ end
+ end
+
+ pair[0] = pair[0].strip
+
+ # Remove ending slashes from path
+ pair[1].gsub!(%r{^/|/$}, '')
+
+ pair
+ end
+
+ # Assigns common instance variables for views working with Git tree-ish objects
+ #
+ # Assignments are:
+ #
+ # - @id - A string representing the joined ref and path
+ # - @ref - A string representing the ref (e.g., the branch, tag, or commit SHA)
+ # - @path - A string representing the filesystem path
+ # - @commit - A Commit representing the commit from the given ref
+ #
+ # If the :id parameter appears to be requesting a specific response format,
+ # that will be handled as well.
+ #
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ def assign_ref_vars
+ @id = get_id
+ @ref, @path = extract_ref(@id)
+ @repo = repository_container.repository
+
+ raise InvalidPathError if @ref.match?(/\s/)
+
+ @commit = @repo.commit(@ref)
+ end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
+
+ def tree
+ @tree ||= @repo.tree(@commit.id, @path) # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ end
+
+ private
+
+ # overridden in subclasses, do not remove
+ def get_id
+ id = [params[:id] || params[:ref]]
+ id << "/" + params[:path] unless params[:path].blank?
+ id.join
+ end
+
+ def ref_names
+ return [] unless repository_container
+
+ @ref_names ||= repository_container.repository.ref_names # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ end
+
+ def repository_container
+ raise NotImplementedError
+ end
+end
diff --git a/lib/feature.rb b/lib/feature.rb
index dc7e8da8f35..d995e0a988f 100644
--- a/lib/feature.rb
+++ b/lib/feature.rb
@@ -4,8 +4,6 @@ require 'flipper/adapters/active_record'
require 'flipper/adapters/active_support_cache_store'
class Feature
- prepend_if_ee('EE::Feature') # rubocop: disable Cop/InjectEnterpriseEditionModule
-
# Classes to override flipper table names
class FlipperFeature < Flipper::Adapters::ActiveRecord::Feature
# Using `self.table_name` won't work. ActiveRecord bug?
@@ -20,6 +18,8 @@ class Feature
superclass.table_name = 'feature_gates'
end
+ InvalidFeatureFlagError = Class.new(Exception) # rubocop:disable Lint/InheritException
+
class << self
delegate :group, to: :flipper
@@ -34,37 +34,58 @@ class Feature
def persisted_names
return [] unless Gitlab::Database.exists?
- Gitlab::SafeRequestStore[:flipper_persisted_names] ||=
- begin
- # We saw on GitLab.com, this database request was called 2300
- # times/s. Let's cache it for a minute to avoid that load.
- Gitlab::ProcessMemoryCache.cache_backend.fetch('flipper:persisted_names', expires_in: 1.minute) do
- FlipperFeature.feature_names
+ if Gitlab::Utils.to_boolean(ENV['FF_LEGACY_PERSISTED_NAMES'])
+ # To be removed:
+ # This uses a legacy persisted names that are know to work (always)
+ Gitlab::SafeRequestStore[:flipper_persisted_names] ||=
+ begin
+ # We saw on GitLab.com, this database request was called 2300
+ # times/s. Let's cache it for a minute to avoid that load.
+ Gitlab::ProcessMemoryCache.cache_backend.fetch('flipper:persisted_names', expires_in: 1.minute) do
+ FlipperFeature.feature_names
+ end.to_set
end
- end
+ else
+ # This loads names of all stored feature flags
+ # and returns a stable Set in the following order:
+ # - Memoized: using Gitlab::SafeRequestStore or @flipper
+ # - L1: using Process cache
+ # - L2: using Redis cache
+ # - DB: using a single SQL query
+ flipper.adapter.features
+ end
end
- def persisted?(feature)
+ def persisted_name?(feature_name)
# Flipper creates on-memory features when asked for a not-yet-created one.
# If we want to check if a feature has been actually set, we look for it
# on the persisted features list.
- persisted_names.include?(feature.name.to_s)
+ persisted_names.include?(feature_name.to_s)
end
# use `default_enabled: true` to default the flag to being `enabled`
# unless set explicitly. The default is `disabled`
+ # TODO: remove the `default_enabled:` and read it from the `defintion_yaml`
+ # check: https://gitlab.com/gitlab-org/gitlab/-/issues/30228
def enabled?(key, thing = nil, default_enabled: false)
+ if check_feature_flags_definition?
+ if thing && !thing.respond_to?(:flipper_id)
+ raise InvalidFeatureFlagError,
+ "The thing '#{thing.class.name}' for feature flag '#{key}' needs to include `FeatureGate` or implement `flipper_id`"
+ end
+ end
+
# During setup the database does not exist yet. So we haven't stored a value
# for the feature yet and return the default.
return default_enabled unless Gitlab::Database.exists?
- feature = Feature.get(key)
+ feature = get(key)
# If we're not default enabling the flag or the feature has been set, always evaluate.
# `persisted?` can potentially generate DB queries and also checks for inclusion
# in an array of feature names (177 at last count), possibly reducing performance by half.
# So we only perform the `persisted` check if `default_enabled: true`
- !default_enabled || Feature.persisted?(feature) ? feature.enabled?(thing) : true
+ !default_enabled || Feature.persisted_name?(feature.name) ? feature.enabled?(thing) : true
end
def disabled?(key, thing = nil, default_enabled: false)
@@ -88,23 +109,31 @@ class Feature
get(key).disable_group(group)
end
- def remove(key)
- feature = get(key)
- return unless persisted?(feature)
+ def enable_percentage_of_time(key, percentage)
+ get(key).enable_percentage_of_time(percentage)
+ end
- feature.remove
+ def disable_percentage_of_time(key)
+ get(key).disable_percentage_of_time
end
- def flipper
- if Gitlab::SafeRequestStore.active?
- Gitlab::SafeRequestStore[:flipper] ||= build_flipper_instance
- else
- @flipper ||= build_flipper_instance
- end
+ def enable_percentage_of_actors(key, percentage)
+ get(key).enable_percentage_of_actors(percentage)
end
- def build_flipper_instance
- Flipper.new(flipper_adapter).tap { |flip| flip.memoize = true }
+ def disable_percentage_of_actors(key)
+ get(key).disable_percentage_of_actors
+ end
+
+ def remove(key)
+ return unless persisted_name?(key)
+
+ get(key).remove
+ end
+
+ def reset
+ Gitlab::SafeRequestStore.delete(:flipper) if Gitlab::SafeRequestStore.active?
+ @flipper = nil
end
# This method is called from config/initializers/flipper.rb and can be used
@@ -113,7 +142,17 @@ class Feature
def register_feature_groups
end
- def flipper_adapter
+ private
+
+ def flipper
+ if Gitlab::SafeRequestStore.active?
+ Gitlab::SafeRequestStore[:flipper] ||= build_flipper_instance
+ else
+ @flipper ||= build_flipper_instance
+ end
+ end
+
+ def build_flipper_instance
active_record_adapter = Flipper::Adapters::ActiveRecord.new(
feature_class: FlipperFeature,
gate_class: FlipperGate)
@@ -127,10 +166,20 @@ class Feature
# Thread-local L1 cache: use a short timeout since we don't have a
# way to expire this cache all at once
- Flipper::Adapters::ActiveSupportCacheStore.new(
+ flipper_adapter = Flipper::Adapters::ActiveSupportCacheStore.new(
redis_cache_adapter,
l1_cache_backend,
expires_in: 1.minute)
+
+ Flipper.new(flipper_adapter).tap do |flip|
+ flip.memoize = true
+ end
+ end
+
+ def check_feature_flags_definition?
+ # We want to check feature flags usage only when
+ # running in development or test environment
+ Gitlab.dev_or_test_env?
end
def l1_cache_backend
@@ -186,3 +235,5 @@ class Feature
end
end
end
+
+Feature.prepend_if_ee('EE::Feature')
diff --git a/lib/gitaly/server.rb b/lib/gitaly/server.rb
index 89a836e629f..a816dd89e9c 100644
--- a/lib/gitaly/server.rb
+++ b/lib/gitaly/server.rb
@@ -3,6 +3,7 @@
module Gitaly
class Server
SHA_VERSION_REGEX = /\A\d+\.\d+\.\d+-\d+-g([a-f0-9]{8})\z/.freeze
+ DEFAULT_REPLICATION_FACTOR = 1
class << self
def all
@@ -16,6 +17,10 @@ module Gitaly
def filesystems
all.map(&:filesystem_type).compact.uniq
end
+
+ def gitaly_clusters
+ all.count { |g| g.replication_factor > DEFAULT_REPLICATION_FACTOR }
+ end
end
attr_reader :storage
@@ -73,6 +78,10 @@ module Gitaly
"Error getting the address: #{e.message}"
end
+ def replication_factor
+ storage_status&.replication_factor
+ end
+
private
def storage_status
diff --git a/lib/gitlab.rb b/lib/gitlab.rb
index f2bff51df38..43785d165fb 100644
--- a/lib/gitlab.rb
+++ b/lib/gitlab.rb
@@ -36,6 +36,7 @@ module Gitlab
end
COM_URL = 'https://gitlab.com'
+ STAGING_COM_URL = 'https://staging.gitlab.com'
APP_DIRS_PATTERN = %r{^/?(app|config|ee|lib|spec|\(\w*\))}.freeze
SUBDOMAIN_REGEX = %r{\Ahttps://[a-z0-9]+\.gitlab\.com\z}.freeze
VERSION = File.read(root.join("VERSION")).strip.freeze
@@ -47,6 +48,10 @@ module Gitlab
Gitlab.config.gitlab.url == COM_URL || gl_subdomain?
end
+ def self.staging?
+ Gitlab.config.gitlab.url == STAGING_COM_URL
+ end
+
def self.canary?
Gitlab::Utils.to_boolean(ENV['CANARY'])
end
@@ -75,6 +80,10 @@ module Gitlab
Rails.env.development? || com?
end
+ def self.dev_or_test_env?
+ Rails.env.development? || Rails.env.test?
+ end
+
def self.ee?
@is_ee ||=
# We use this method when the Rails environment is not loaded. This
diff --git a/lib/gitlab/alert_management/alert_params.rb b/lib/gitlab/alert_management/alert_params.rb
index 982479784a9..789a4fe246a 100644
--- a/lib/gitlab/alert_management/alert_params.rb
+++ b/lib/gitlab/alert_management/alert_params.rb
@@ -20,7 +20,8 @@ module Gitlab
hosts: Array(annotations[:hosts]),
payload: payload,
started_at: parsed_payload['startsAt'],
- severity: annotations[:severity]
+ severity: annotations[:severity],
+ fingerprint: annotations[:fingerprint]
}
end
diff --git a/lib/gitlab/alert_management/fingerprint.rb b/lib/gitlab/alert_management/fingerprint.rb
new file mode 100644
index 00000000000..6ab47c88ca1
--- /dev/null
+++ b/lib/gitlab/alert_management/fingerprint.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module AlertManagement
+ class Fingerprint
+ def self.generate(data)
+ new.generate(data)
+ end
+
+ def generate(data)
+ return unless data.present?
+
+ if data.is_a?(Array)
+ data = flatten_array(data)
+ end
+
+ Digest::SHA1.hexdigest(data.to_s)
+ end
+
+ private
+
+ def flatten_array(array)
+ array.flatten.map!(&:to_s).join
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/alerting/alert.rb b/lib/gitlab/alerting/alert.rb
index d859ca89418..dad3dabb4fc 100644
--- a/lib/gitlab/alerting/alert.rb
+++ b/lib/gitlab/alerting/alert.rb
@@ -106,7 +106,7 @@ module Gitlab
end
def gitlab_fingerprint
- Digest::SHA1.hexdigest(plain_gitlab_fingerprint)
+ Gitlab::AlertManagement::Fingerprint.generate(plain_gitlab_fingerprint)
end
def valid?
@@ -121,9 +121,9 @@ module Gitlab
def plain_gitlab_fingerprint
if gitlab_managed?
- [metric_id, starts_at].join('/')
+ [metric_id, starts_at_raw].join('/')
else # self managed
- [starts_at, title, full_query].join('/')
+ [starts_at_raw, title, full_query].join('/')
end
end
@@ -173,7 +173,10 @@ module Gitlab
value = payload&.dig(field)
return unless value
- Time.rfc3339(value)
+ # value is a rfc3339 timestamp
+ # Timestamps from Prometheus and Alertmanager are UTC RFC3339 timestamps like: '2018-03-12T09:06:00Z' (Z represents 0 offset or UTC)
+ # .utc sets the datetime zone to `UTC`
+ Time.rfc3339(value).utc
rescue ArgumentError
end
diff --git a/lib/gitlab/alerting/notification_payload_parser.rb b/lib/gitlab/alerting/notification_payload_parser.rb
index c79d69613f3..d98b9296347 100644
--- a/lib/gitlab/alerting/notification_payload_parser.rb
+++ b/lib/gitlab/alerting/notification_payload_parser.rb
@@ -35,6 +35,10 @@ module Gitlab
payload[:severity].presence || DEFAULT_SEVERITY
end
+ def fingerprint
+ Gitlab::AlertManagement::Fingerprint.generate(payload[:fingerprint])
+ end
+
def annotations
primary_params
.reverse_merge(flatten_secondary_params)
@@ -49,7 +53,8 @@ module Gitlab
'monitoring_tool' => payload[:monitoring_tool],
'service' => payload[:service],
'hosts' => hosts.presence,
- 'severity' => severity
+ 'severity' => severity,
+ 'fingerprint' => fingerprint
}
end
diff --git a/lib/gitlab/analytics/cycle_analytics/base_query_builder.rb b/lib/gitlab/analytics/cycle_analytics/base_query_builder.rb
index 9ea20a4d6a4..4dec71b35e8 100644
--- a/lib/gitlab/analytics/cycle_analytics/base_query_builder.rb
+++ b/lib/gitlab/analytics/cycle_analytics/base_query_builder.rb
@@ -8,21 +8,24 @@ module Gitlab
delegate :subject_class, to: :stage
- # rubocop: disable CodeReuse/ActiveRecord
+ FINDER_CLASSES = {
+ MergeRequest.to_s => MergeRequestsFinder,
+ Issue.to_s => IssuesFinder
+ }.freeze
def initialize(stage:, params: {})
@stage = stage
- @params = params
+ @params = build_finder_params(params)
end
+ # rubocop: disable CodeReuse/ActiveRecord
def build
- query = subject_class
- query = filter_by_parent_model(query)
- query = filter_by_time_range(query)
+ query = finder.execute
query = stage.start_event.apply_query_customization(query)
query = stage.end_event.apply_query_customization(query)
query.where(duration_condition)
end
+ # rubocop: enable CodeReuse/ActiveRecord
private
@@ -32,38 +35,33 @@ module Gitlab
stage.end_event.timestamp_projection.gteq(stage.start_event.timestamp_projection)
end
- def filter_by_parent_model(query)
- if parent_class.eql?(Project)
- if subject_class.eql?(Issue)
- query.where(project_id: stage.parent_id)
- elsif subject_class.eql?(MergeRequest)
- query.where(target_project_id: stage.parent_id)
- else
- raise ArgumentError, "unknown subject_class: #{subject_class}"
- end
- else
- raise ArgumentError, "unknown parent_class: #{parent_class}"
- end
+ def finder
+ FINDER_CLASSES.fetch(subject_class.to_s).new(params[:current_user], params)
end
- def filter_by_time_range(query)
- from = params.fetch(:from, 30.days.ago)
- to = params[:to]
-
- query = query.where(subject_table[:created_at].gteq(from))
- query = query.where(subject_table[:created_at].lteq(to)) if to
- query
+ def parent_class
+ stage.parent.class
end
- def subject_table
- subject_class.arel_table
+ def build_finder_params(params)
+ {}.tap do |finder_params|
+ finder_params[:current_user] = params[:current_user]
+
+ add_parent_model_params!(finder_params)
+ add_time_range_params!(finder_params, params[:from], params[:to])
+ end
end
- def parent_class
- stage.parent.class
+ def add_parent_model_params!(finder_params)
+ raise(ArgumentError, "unknown parent_class: #{parent_class}") unless parent_class.eql?(Project)
+
+ finder_params[:project_id] = stage.parent_id
end
- # rubocop: enable CodeReuse/ActiveRecord
+ def add_time_range_params!(finder_params, from, to)
+ finder_params[:created_after] = from || 30.days.ago
+ finder_params[:created_before] = to if to
+ end
end
end
end
diff --git a/lib/gitlab/analytics/cycle_analytics/median.rb b/lib/gitlab/analytics/cycle_analytics/median.rb
index 9fcaeadf351..6c0450ac9e5 100644
--- a/lib/gitlab/analytics/cycle_analytics/median.rb
+++ b/lib/gitlab/analytics/cycle_analytics/median.rb
@@ -11,12 +11,14 @@ module Gitlab
@query = query
end
+ # rubocop: disable CodeReuse/ActiveRecord
def seconds
- @query = @query.select(median_duration_in_seconds.as('median'))
+ @query = @query.select(median_duration_in_seconds.as('median')).reorder(nil)
result = execute_query(@query).first || {}
result['median'] || nil
end
+ # rubocop: enable CodeReuse/ActiveRecord
def days
seconds ? seconds.fdiv(1.day) : nil
diff --git a/lib/gitlab/analytics/cycle_analytics/records_fetcher.rb b/lib/gitlab/analytics/cycle_analytics/records_fetcher.rb
index e8e269a88f0..e7352a23b99 100644
--- a/lib/gitlab/analytics/cycle_analytics/records_fetcher.rb
+++ b/lib/gitlab/analytics/cycle_analytics/records_fetcher.rb
@@ -12,13 +12,11 @@ module Gitlab
MAPPINGS = {
Issue => {
- finder_class: IssuesFinder,
serializer_class: AnalyticsIssueSerializer,
includes_for_query: { project: [:namespace], author: [] },
columns_for_select: %I[title iid id created_at author_id project_id]
},
MergeRequest => {
- finder_class: MergeRequestsFinder,
serializer_class: AnalyticsMergeRequestSerializer,
includes_for_query: { target_project: [:namespace], author: [] },
columns_for_select: %I[title iid id created_at author_id state_id target_project_id]
@@ -56,27 +54,12 @@ module Gitlab
attr_reader :stage, :query, :params
- def finder_query
- MAPPINGS
- .fetch(subject_class)
- .fetch(:finder_class)
- .new(params.fetch(:current_user), finder_params.fetch(stage.parent.class))
- .execute
- end
-
def columns
MAPPINGS.fetch(subject_class).fetch(:columns_for_select).map do |column_name|
subject_class.arel_table[column_name]
end
end
- # EE will override this to include Group rules
- def finder_params
- {
- Project => { project_id: stage.parent_id }
- }
- end
-
def default_test_stage?
stage.matches_with_stage_params?(Gitlab::Analytics::CycleAnalytics::DefaultStages.params_for_test_stage)
end
@@ -113,8 +96,7 @@ module Gitlab
end
def records
- results = finder_query
- .merge(ordered_and_limited_query)
+ results = ordered_and_limited_query
.select(*columns, round_duration_to_seconds.as('total_time'))
# using preloader instead of includes to avoid AR generating a large column list
diff --git a/lib/gitlab/application_rate_limiter.rb b/lib/gitlab/application_rate_limiter.rb
index 2defbd26b98..3277ddd9f49 100644
--- a/lib/gitlab/application_rate_limiter.rb
+++ b/lib/gitlab/application_rate_limiter.rb
@@ -20,15 +20,16 @@ module Gitlab
def rate_limits
{
issues_create: { threshold: -> { Gitlab::CurrentSettings.current_application_settings.issues_create_limit }, interval: 1.minute },
- project_export: { threshold: 1, interval: 5.minutes },
+ project_export: { threshold: 30, interval: 5.minutes },
project_download_export: { threshold: 10, interval: 10.minutes },
project_repositories_archive: { threshold: 5, interval: 1.minute },
- project_generate_new_export: { threshold: 1, interval: 5.minutes },
+ project_generate_new_export: { threshold: 30, interval: 5.minutes },
project_import: { threshold: 30, interval: 5.minutes },
play_pipeline_schedule: { threshold: 1, interval: 1.minute },
show_raw_controller: { threshold: -> { Gitlab::CurrentSettings.current_application_settings.raw_blob_request_limit }, interval: 1.minute },
- group_export: { threshold: 1, interval: 5.minutes },
- group_download_export: { threshold: 10, interval: 10.minutes }
+ group_export: { threshold: 30, interval: 5.minutes },
+ group_download_export: { threshold: 10, interval: 10.minutes },
+ group_import: { threshold: 30, interval: 5.minutes }
}.freeze
end
diff --git a/lib/gitlab/auth/auth_finders.rb b/lib/gitlab/auth/auth_finders.rb
index b7e78189d37..93342fbad51 100644
--- a/lib/gitlab/auth/auth_finders.rb
+++ b/lib/gitlab/auth/auth_finders.rb
@@ -56,6 +56,7 @@ module Gitlab
def find_user_from_job_token
return unless route_authentication_setting[:job_token_allowed]
+ return find_user_from_basic_auth_job if route_authentication_setting[:job_token_allowed] == :basic_auth
token = current_request.params[JOB_TOKEN_PARAM].presence ||
current_request.params[RUNNER_JOB_TOKEN_PARAM].presence ||
diff --git a/lib/gitlab/auth/ldap/person.rb b/lib/gitlab/auth/ldap/person.rb
index e4a4900c37a..b3321c0b1fb 100644
--- a/lib/gitlab/auth/ldap/person.rb
+++ b/lib/gitlab/auth/ldap/person.rb
@@ -39,7 +39,7 @@ module Gitlab
*config.attributes['name'],
*config.attributes['email'],
*config.attributes['username']
- ].compact.uniq
+ ].compact.uniq.reject(&:blank?)
end
def self.normalize_dn(dn)
diff --git a/lib/gitlab/auth/o_auth/provider.rb b/lib/gitlab/auth/o_auth/provider.rb
index 6d699d37a8c..1ca59aa827b 100644
--- a/lib/gitlab/auth/o_auth/provider.rb
+++ b/lib/gitlab/auth/o_auth/provider.rb
@@ -41,10 +41,6 @@ module Gitlab
name.to_s.start_with?('ldap')
end
- def self.ultraauth_provider?(name)
- name.to_s.eql?('ultraauth')
- end
-
def self.sync_profile_from_provider?(provider)
return true if ldap_provider?(provider)
diff --git a/lib/gitlab/background_migration/.rubocop.yml b/lib/gitlab/background_migration/.rubocop.yml
index 8242821cedc..50112a51675 100644
--- a/lib/gitlab/background_migration/.rubocop.yml
+++ b/lib/gitlab/background_migration/.rubocop.yml
@@ -15,7 +15,7 @@ Metrics/AbcSize:
Metrics/PerceivedComplexity:
Enabled: true
-Metrics/LineLength:
+Layout/LineLength:
Enabled: true
Details: >
Long lines are very hard to read and make it more difficult to review
diff --git a/lib/gitlab/background_migration/backfill_project_repositories.rb b/lib/gitlab/background_migration/backfill_project_repositories.rb
index 263546bd132..bc113a1e33d 100644
--- a/lib/gitlab/background_migration/backfill_project_repositories.rb
+++ b/lib/gitlab/background_migration/backfill_project_repositories.rb
@@ -189,7 +189,7 @@ module Gitlab
end
def perform(start_id, stop_id)
- Gitlab::Database.bulk_insert(:project_repositories, project_repositories(start_id, stop_id))
+ Gitlab::Database.bulk_insert(:project_repositories, project_repositories(start_id, stop_id)) # rubocop:disable Gitlab/BulkInsert
end
private
diff --git a/lib/gitlab/background_migration/fix_projects_without_prometheus_service.rb b/lib/gitlab/background_migration/fix_projects_without_prometheus_service.rb
index c652a5bb3fc..e750b8ca374 100644
--- a/lib/gitlab/background_migration/fix_projects_without_prometheus_service.rb
+++ b/lib/gitlab/background_migration/fix_projects_without_prometheus_service.rb
@@ -62,7 +62,7 @@ module Gitlab
class PrometheusService < ActiveRecord::Base
self.inheritance_column = :_type_disabled
self.table_name = 'services'
- default_scope { where(type: type) }
+ default_scope { where(type: type) } # rubocop:disable Cop/DefaultScope
def self.type
'PrometheusService'
diff --git a/lib/gitlab/background_migration/fix_ruby_object_in_audit_events.rb b/lib/gitlab/background_migration/fix_ruby_object_in_audit_events.rb
new file mode 100644
index 00000000000..46921a070c3
--- /dev/null
+++ b/lib/gitlab/background_migration/fix_ruby_object_in_audit_events.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module BackgroundMigration
+ # Remove serialized Ruby object in audit_events
+ class FixRubyObjectInAuditEvents
+ def perform(start_id, stop_id)
+ end
+ end
+ end
+end
+
+Gitlab::BackgroundMigration::FixRubyObjectInAuditEvents.prepend_if_ee('EE::Gitlab::BackgroundMigration::FixRubyObjectInAuditEvents')
diff --git a/lib/gitlab/background_migration/migrate_fingerprint_sha256_within_keys.rb b/lib/gitlab/background_migration/migrate_fingerprint_sha256_within_keys.rb
index 899f381e911..d2a9939b9ee 100644
--- a/lib/gitlab/background_migration/migrate_fingerprint_sha256_within_keys.rb
+++ b/lib/gitlab/background_migration/migrate_fingerprint_sha256_within_keys.rb
@@ -34,7 +34,7 @@ module Gitlab
end
end
- Gitlab::Database.bulk_insert(TEMP_TABLE, fingerprints)
+ Gitlab::Database.bulk_insert(TEMP_TABLE, fingerprints) # rubocop:disable Gitlab/BulkInsert
execute("ANALYZE #{TEMP_TABLE}")
diff --git a/lib/gitlab/background_migration/migrate_issue_trackers_sensitive_data.rb b/lib/gitlab/background_migration/migrate_issue_trackers_sensitive_data.rb
index 956f9daa493..2bce5037d03 100644
--- a/lib/gitlab/background_migration/migrate_issue_trackers_sensitive_data.rb
+++ b/lib/gitlab/background_migration/migrate_issue_trackers_sensitive_data.rb
@@ -65,7 +65,7 @@ module Gitlab
next if service_ids.empty?
migrated_ids += service_ids
- Gitlab::Database.bulk_insert(table, data)
+ Gitlab::Database.bulk_insert(table, data) # rubocop:disable Gitlab/BulkInsert
end
return if migrated_ids.empty?
diff --git a/lib/gitlab/background_migration/populate_cluster_kubernetes_namespace_table.rb b/lib/gitlab/background_migration/populate_cluster_kubernetes_namespace_table.rb
index 35bfc381180..fcbcaacb2d6 100644
--- a/lib/gitlab/background_migration/populate_cluster_kubernetes_namespace_table.rb
+++ b/lib/gitlab/background_migration/populate_cluster_kubernetes_namespace_table.rb
@@ -73,7 +73,7 @@ module Gitlab
end
def insert_into_cluster_kubernetes_namespace(rows)
- Gitlab::Database.bulk_insert(Migratable::KubernetesNamespace.table_name,
+ Gitlab::Database.bulk_insert(Migratable::KubernetesNamespace.table_name, # rubocop:disable Gitlab/BulkInsert
rows,
disable_quote: [:created_at, :updated_at])
end
diff --git a/lib/gitlab/background_migration/populate_untracked_uploads.rb b/lib/gitlab/background_migration/populate_untracked_uploads.rb
index d2924d10225..43698b7955f 100644
--- a/lib/gitlab/background_migration/populate_untracked_uploads.rb
+++ b/lib/gitlab/background_migration/populate_untracked_uploads.rb
@@ -95,7 +95,7 @@ module Gitlab
file.to_h.merge(created_at: 'NOW()')
end
- Gitlab::Database.bulk_insert('uploads',
+ Gitlab::Database.bulk_insert('uploads', # rubocop:disable Gitlab/BulkInsert
rows,
disable_quote: :created_at)
end
diff --git a/lib/gitlab/background_migration/reset_merge_status.rb b/lib/gitlab/background_migration/reset_merge_status.rb
index 447fec8903c..d040b4931be 100644
--- a/lib/gitlab/background_migration/reset_merge_status.rb
+++ b/lib/gitlab/background_migration/reset_merge_status.rb
@@ -7,7 +7,7 @@ module Gitlab
class ResetMergeStatus
def perform(from_id, to_id)
relation = MergeRequest.where(id: from_id..to_id,
- state: 'opened',
+ state_id: 1, # opened
merge_status: 'can_be_merged')
relation.update_all(merge_status: 'unchecked')
diff --git a/lib/gitlab/background_migration/user_mentions/create_resource_user_mention.rb b/lib/gitlab/background_migration/user_mentions/create_resource_user_mention.rb
index cf0f582a2d4..d71a50a0af6 100644
--- a/lib/gitlab/background_migration/user_mentions/create_resource_user_mention.rb
+++ b/lib/gitlab/background_migration/user_mentions/create_resource_user_mention.rb
@@ -25,7 +25,7 @@ module Gitlab
mentions << mention_record unless mention_record.blank?
end
- Gitlab::Database.bulk_insert(
+ Gitlab::Database.bulk_insert( # rubocop:disable Gitlab/BulkInsert
resource_user_mention_model.table_name,
mentions,
return_ids: true,
diff --git a/lib/gitlab/badge/coverage/report.rb b/lib/gitlab/badge/coverage/report.rb
index 15cccc6f287..0df6e858bf4 100644
--- a/lib/gitlab/badge/coverage/report.rb
+++ b/lib/gitlab/badge/coverage/report.rb
@@ -7,12 +7,16 @@ module Gitlab
# Test coverage report badge
#
class Report < Badge::Base
- attr_reader :project, :ref, :job
+ attr_reader :project, :ref, :job, :customization
- def initialize(project, ref, job = nil)
+ def initialize(project, ref, opts: { job: nil })
@project = project
@ref = ref
- @job = job
+ @job = opts[:job]
+ @customization = {
+ key_width: opts[:key_width].to_i,
+ key_text: opts[:key_text]
+ }
@pipeline = @project.ci_pipelines.latest_successful_for_ref(@ref)
end
diff --git a/lib/gitlab/badge/coverage/template.rb b/lib/gitlab/badge/coverage/template.rb
index 817dc28f84a..6b78825aefd 100644
--- a/lib/gitlab/badge/coverage/template.rb
+++ b/lib/gitlab/badge/coverage/template.rb
@@ -20,10 +20,16 @@ module Gitlab
def initialize(badge)
@entity = badge.entity
@status = badge.status
+ @key_text = badge.customization.dig(:key_text)
+ @key_width = badge.customization.dig(:key_width)
end
def key_text
- @entity.to_s
+ if @key_text && @key_text.size <= MAX_KEY_SIZE
+ @key_text
+ else
+ @entity.to_s
+ end
end
def value_text
@@ -31,7 +37,11 @@ module Gitlab
end
def key_width
- 62
+ if @key_width && @key_width.between?(1, MAX_KEY_SIZE)
+ @key_width
+ else
+ 62
+ end
end
def value_width
diff --git a/lib/gitlab/badge/pipeline/status.rb b/lib/gitlab/badge/pipeline/status.rb
index a403d839517..17f179f027d 100644
--- a/lib/gitlab/badge/pipeline/status.rb
+++ b/lib/gitlab/badge/pipeline/status.rb
@@ -7,11 +7,15 @@ module Gitlab
# Pipeline status badge
#
class Status < Badge::Base
- attr_reader :project, :ref
+ attr_reader :project, :ref, :customization
- def initialize(project, ref)
+ def initialize(project, ref, opts: {})
@project = project
@ref = ref
+ @customization = {
+ key_width: opts[:key_width].to_i,
+ key_text: opts[:key_text]
+ }
@sha = @project.commit(@ref).try(:sha)
end
diff --git a/lib/gitlab/badge/pipeline/template.rb b/lib/gitlab/badge/pipeline/template.rb
index 0d3d44135e7..781897fab4b 100644
--- a/lib/gitlab/badge/pipeline/template.rb
+++ b/lib/gitlab/badge/pipeline/template.rb
@@ -24,10 +24,16 @@ module Gitlab
def initialize(badge)
@entity = badge.entity
@status = badge.status
+ @key_text = badge.customization.dig(:key_text)
+ @key_width = badge.customization.dig(:key_width)
end
def key_text
- @entity.to_s
+ if @key_text && @key_text.size <= MAX_KEY_SIZE
+ @key_text
+ else
+ @entity.to_s
+ end
end
def value_text
@@ -35,7 +41,11 @@ module Gitlab
end
def key_width
- 62
+ if @key_width && @key_width.between?(1, MAX_KEY_SIZE)
+ @key_width
+ else
+ 62
+ end
end
def value_width
diff --git a/lib/gitlab/badge/template.rb b/lib/gitlab/badge/template.rb
index ed2ec50b197..97103e3f42c 100644
--- a/lib/gitlab/badge/template.rb
+++ b/lib/gitlab/badge/template.rb
@@ -6,6 +6,8 @@ module Gitlab
# Abstract template class for badges
#
class Template
+ MAX_KEY_SIZE = 128
+
def initialize(badge)
@entity = badge.entity
@status = badge.status
diff --git a/lib/gitlab/bitbucket_import/importer.rb b/lib/gitlab/bitbucket_import/importer.rb
index d8f9105d66d..5a9fad3be56 100644
--- a/lib/gitlab/bitbucket_import/importer.rb
+++ b/lib/gitlab/bitbucket_import/importer.rb
@@ -43,7 +43,7 @@ module Gitlab
def store_pull_request_error(pull_request, ex)
backtrace = Gitlab::BacktraceCleaner.clean_backtrace(ex.backtrace)
- error = { type: :pull_request, iid: pull_request.iid, errors: ex.message, trace: backtrace, raw_response: pull_request.raw }
+ error = { type: :pull_request, iid: pull_request.iid, errors: ex.message, trace: backtrace, raw_response: pull_request.raw&.to_json }
Gitlab::ErrorTracking.log_exception(ex, error)
diff --git a/lib/gitlab/cache/import/caching.rb b/lib/gitlab/cache/import/caching.rb
index 7f2d2858149..ec94991157a 100644
--- a/lib/gitlab/cache/import/caching.rb
+++ b/lib/gitlab/cache/import/caching.rb
@@ -113,15 +113,18 @@ module Gitlab
end
end
- # Sets multiple keys to a given value.
+ # Sets multiple keys to given values.
#
# mapping - A Hash mapping the cache keys to their values.
+ # key_prefix - prefix inserted before each key
# timeout - The time after which the cache key should expire.
- def self.write_multiple(mapping, timeout: TIMEOUT)
+ def self.write_multiple(mapping, key_prefix: nil, timeout: TIMEOUT)
Redis::Cache.with do |redis|
- redis.multi do |multi|
+ redis.pipelined do |multi|
mapping.each do |raw_key, value|
- multi.set(cache_key_for(raw_key), value, ex: timeout)
+ key = cache_key_for("#{key_prefix}#{raw_key}")
+
+ multi.set(key, value, ex: timeout)
end
end
end
diff --git a/lib/gitlab/ci/build/releaser.rb b/lib/gitlab/ci/build/releaser.rb
new file mode 100644
index 00000000000..ba6c7857e96
--- /dev/null
+++ b/lib/gitlab/ci/build/releaser.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Build
+ class Releaser
+ BASE_COMMAND = 'release-cli create'
+
+ attr_reader :config
+
+ def initialize(config:)
+ @config = config
+ end
+
+ def script
+ command = BASE_COMMAND.dup
+ config.each { |k, v| command.concat(" --#{k.to_s.dasherize} \"#{v}\"") }
+
+ command
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/build/step.rb b/lib/gitlab/ci/build/step.rb
index 48111ae5717..f8550b50905 100644
--- a/lib/gitlab/ci/build/step.rb
+++ b/lib/gitlab/ci/build/step.rb
@@ -20,6 +20,19 @@ module Gitlab
end
end
+ def from_release(job)
+ return unless Gitlab::Ci::Features.release_generation_enabled?
+
+ release = job.options[:release]
+ return unless release
+
+ self.new(:release).tap do |step|
+ step.script = Gitlab::Ci::Build::Releaser.new(config: job.options[:release]).script
+ step.timeout = job.metadata_timeout
+ step.when = WHEN_ON_SUCCESS
+ end
+ end
+
def from_after_script(job)
after_script = job.options[:after_script]
return unless after_script
diff --git a/lib/gitlab/ci/config/entry/job.rb b/lib/gitlab/ci/config/entry/job.rb
index 1ea59491378..66050a7bbe0 100644
--- a/lib/gitlab/ci/config/entry/job.rb
+++ b/lib/gitlab/ci/config/entry/job.rb
@@ -28,7 +28,7 @@ module Gitlab
in: %i[release],
message: 'release features are not enabled'
},
- unless: -> { Feature.enabled?(:ci_release_generation, default_enabled: false) }
+ unless: -> { Gitlab::Ci::Features.release_generation_enabled? }
with_options allow_nil: true do
validates :allow_failure, boolean: true
diff --git a/lib/gitlab/ci/config/entry/reports.rb b/lib/gitlab/ci/config/entry/reports.rb
index 1a871e043a6..74736b24d73 100644
--- a/lib/gitlab/ci/config/entry/reports.rb
+++ b/lib/gitlab/ci/config/entry/reports.rb
@@ -12,9 +12,10 @@ module Gitlab
include ::Gitlab::Config::Entry::Attributable
ALLOWED_KEYS =
- %i[junit codequality sast dependency_scanning container_scanning
+ %i[junit codequality sast secret_detection dependency_scanning container_scanning
dast performance license_management license_scanning metrics lsif
- dotenv cobertura terraform accessibility cluster_applications].freeze
+ dotenv cobertura terraform accessibility cluster_applications
+ requirements].freeze
attributes ALLOWED_KEYS
@@ -26,6 +27,7 @@ module Gitlab
validates :junit, array_of_strings_or_string: true
validates :codequality, array_of_strings_or_string: true
validates :sast, array_of_strings_or_string: true
+ validates :secret_detection, array_of_strings_or_string: true
validates :dependency_scanning, array_of_strings_or_string: true
validates :container_scanning, array_of_strings_or_string: true
validates :dast, array_of_strings_or_string: true
@@ -39,6 +41,7 @@ module Gitlab
validates :terraform, array_of_strings_or_string: true
validates :accessibility, array_of_strings_or_string: true
validates :cluster_applications, array_of_strings_or_string: true
+ validates :requirements, array_of_strings_or_string: true
end
end
diff --git a/lib/gitlab/ci/features.rb b/lib/gitlab/ci/features.rb
index 48f3d4fdd2f..a2eb31369c7 100644
--- a/lib/gitlab/ci/features.rb
+++ b/lib/gitlab/ci/features.rb
@@ -7,12 +7,40 @@ module Gitlab
#
module Features
def self.artifacts_exclude_enabled?
- ::Feature.enabled?(:ci_artifacts_exclude, default_enabled: false)
+ ::Feature.enabled?(:ci_artifacts_exclude, default_enabled: true)
end
def self.ensure_scheduling_type_enabled?
::Feature.enabled?(:ci_ensure_scheduling_type, default_enabled: true)
end
+
+ def self.job_heartbeats_runner?(project)
+ ::Feature.enabled?(:ci_job_heartbeats_runner, project, default_enabled: true)
+ end
+
+ def self.instance_level_variables_limit_enabled?
+ ::Feature.enabled?(:ci_instance_level_variables_limit, default_enabled: true)
+ end
+
+ def self.pipeline_fixed_notifications?
+ ::Feature.enabled?(:ci_pipeline_fixed_notifications)
+ end
+
+ def self.instance_variables_ui_enabled?
+ ::Feature.enabled?(:ci_instance_variables_ui, default_enabled: true)
+ end
+
+ def self.composite_status?(project)
+ ::Feature.enabled?(:ci_composite_status, project, default_enabled: true)
+ end
+
+ def self.atomic_processing?(project)
+ ::Feature.enabled?(:ci_atomic_processing, project, default_enabled: true)
+ end
+
+ def self.release_generation_enabled?
+ ::Feature.enabled?(:ci_release_generation)
+ end
end
end
end
diff --git a/lib/gitlab/ci/parsers/terraform/tfplan.rb b/lib/gitlab/ci/parsers/terraform/tfplan.rb
index 26a18c6603e..19f724b79af 100644
--- a/lib/gitlab/ci/parsers/terraform/tfplan.rb
+++ b/lib/gitlab/ci/parsers/terraform/tfplan.rb
@@ -8,15 +8,11 @@ module Gitlab
TfplanParserError = Class.new(Gitlab::Ci::Parsers::ParserError)
def parse!(json_data, terraform_reports, artifact:)
- tfplan = Gitlab::Json.parse(json_data).tap do |parsed_data|
- parsed_data['job_path'] = Gitlab::Routing.url_helpers.project_job_path(
- artifact.job.project, artifact.job
- )
- end
+ plan_data = Gitlab::Json.parse(json_data)
- raise TfplanParserError, 'Tfplan missing required key' unless valid_supported_keys?(tfplan)
+ raise TfplanParserError, 'Tfplan missing required key' unless has_required_keys?(plan_data)
- terraform_reports.add_plan(artifact.filename, tfplan)
+ terraform_reports.add_plan(artifact.job.id.to_s, tfplan(plan_data, artifact.job))
rescue JSON::ParserError
raise TfplanParserError, 'JSON parsing failed'
rescue
@@ -25,8 +21,18 @@ module Gitlab
private
- def valid_supported_keys?(tfplan)
- tfplan.keys == %w[create update delete job_path]
+ def has_required_keys?(plan_data)
+ (%w[create update delete] - plan_data.keys).empty?
+ end
+
+ def tfplan(plan_data, artifact_job)
+ {
+ 'create' => plan_data['create'].to_i,
+ 'delete' => plan_data['delete'].to_i,
+ 'job_name' => artifact_job.options.dig(:artifacts, :name).to_s,
+ 'job_path' => Gitlab::Routing.url_helpers.project_job_path(artifact_job.project, artifact_job),
+ 'update' => plan_data['update'].to_i
+ }
end
end
end
diff --git a/lib/gitlab/ci/pipeline/chain/command.rb b/lib/gitlab/ci/pipeline/chain/command.rb
index 73187401903..8118e7b2487 100644
--- a/lib/gitlab/ci/pipeline/chain/command.rb
+++ b/lib/gitlab/ci/pipeline/chain/command.rb
@@ -77,19 +77,18 @@ module Gitlab
bridge&.parent_pipeline
end
- def duration_histogram
- strong_memoize(:duration_histogram) do
- name = :gitlab_ci_pipeline_creation_duration_seconds
- comment = 'Pipeline creation duration'
- labels = {}
- buckets = [0.01, 0.05, 0.1, 0.5, 1.0, 2.0, 5.0, 20.0, 50.0, 240.0]
-
- Gitlab::Metrics.histogram(name, comment, labels, buckets)
- end
+ def metrics
+ @metrics ||= Chain::Metrics.new
end
def observe_creation_duration(duration)
- duration_histogram.observe({}, duration.seconds)
+ metrics.pipeline_creation_duration_histogram
+ .observe({}, duration.seconds)
+ end
+
+ def observe_pipeline_size(pipeline)
+ metrics.pipeline_size_histogram
+ .observe({ source: pipeline.source.to_s }, pipeline.total_size)
end
end
end
diff --git a/lib/gitlab/ci/pipeline/chain/metrics.rb b/lib/gitlab/ci/pipeline/chain/metrics.rb
new file mode 100644
index 00000000000..980ab2de9b0
--- /dev/null
+++ b/lib/gitlab/ci/pipeline/chain/metrics.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Pipeline
+ module Chain
+ class Metrics
+ include Gitlab::Utils::StrongMemoize
+
+ def pipeline_creation_duration_histogram
+ strong_memoize(:pipeline_creation_duration_histogram) do
+ name = :gitlab_ci_pipeline_creation_duration_seconds
+ comment = 'Pipeline creation duration'
+ labels = {}
+ buckets = [0.01, 0.05, 0.1, 0.5, 1.0, 2.0, 5.0, 20.0, 50.0, 240.0]
+
+ ::Gitlab::Metrics.histogram(name, comment, labels, buckets)
+ end
+ end
+
+ def pipeline_size_histogram
+ strong_memoize(:pipeline_size_histogram) do
+ name = :gitlab_ci_pipeline_size_builds
+ comment = 'Pipeline size'
+ labels = { source: nil }
+ buckets = [0, 1, 5, 10, 20, 50, 100, 200, 500, 1000]
+
+ ::Gitlab::Metrics.histogram(name, comment, labels, buckets)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/pipeline/chain/seed.rb b/lib/gitlab/ci/pipeline/chain/seed.rb
index 2e177cfec7e..e48e79d561b 100644
--- a/lib/gitlab/ci/pipeline/chain/seed.rb
+++ b/lib/gitlab/ci/pipeline/chain/seed.rb
@@ -13,6 +13,7 @@ module Gitlab
# Allocate next IID. This operation must be outside of transactions of pipeline creations.
pipeline.ensure_project_iid!
+ pipeline.ensure_ci_ref!
# Protect the pipeline. This is assigned in Populate instead of
# Build to prevent erroring out on ambiguous refs.
diff --git a/lib/gitlab/ci/pipeline/chain/sequence.rb b/lib/gitlab/ci/pipeline/chain/sequence.rb
index a7c671e76d3..204c7725214 100644
--- a/lib/gitlab/ci/pipeline/chain/sequence.rb
+++ b/lib/gitlab/ci/pipeline/chain/sequence.rb
@@ -27,6 +27,7 @@ module Gitlab
yield @pipeline, self if block_given?
@command.observe_creation_duration(Time.now - @start)
+ @command.observe_pipeline_size(@pipeline)
end
end
diff --git a/lib/gitlab/ci/reports/terraform_reports.rb b/lib/gitlab/ci/reports/terraform_reports.rb
index f955d007daf..4b52c25d724 100644
--- a/lib/gitlab/ci/reports/terraform_reports.rb
+++ b/lib/gitlab/ci/reports/terraform_reports.rb
@@ -10,14 +10,6 @@ module Gitlab
@plans = {}
end
- def pick(keys)
- terraform_plans = plans.select do |key|
- keys.include?(key)
- end
-
- { plans: terraform_plans }
- end
-
def add_plan(name, plan)
plans[name] = plan
end
diff --git a/lib/gitlab/ci/status/bridge/failed.rb b/lib/gitlab/ci/status/bridge/failed.rb
index de7446c238c..b0ab0992594 100644
--- a/lib/gitlab/ci/status/bridge/failed.rb
+++ b/lib/gitlab/ci/status/bridge/failed.rb
@@ -5,6 +5,14 @@ module Gitlab
module Status
module Bridge
class Failed < Status::Build::Failed
+ private
+
+ def failure_reason_message
+ [
+ self.class.reasons.fetch(subject.failure_reason.to_sym),
+ subject.options[:downstream_errors]
+ ].flatten.compact.join(', ')
+ end
end
end
end
diff --git a/lib/gitlab/ci/status/core.rb b/lib/gitlab/ci/status/core.rb
index ea773ee9944..4779c8d3d53 100644
--- a/lib/gitlab/ci/status/core.rb
+++ b/lib/gitlab/ci/status/core.rb
@@ -3,7 +3,7 @@
module Gitlab
module Ci
module Status
- # Base abstract class fore core status
+ # Base abstract class for core status
#
class Core
include Gitlab::Routing
diff --git a/lib/gitlab/ci/templates/AWS/Deploy-ECS.gitlab-ci.yml b/lib/gitlab/ci/templates/AWS/Deploy-ECS.gitlab-ci.yml
new file mode 100644
index 00000000000..82b2f5c035e
--- /dev/null
+++ b/lib/gitlab/ci/templates/AWS/Deploy-ECS.gitlab-ci.yml
@@ -0,0 +1,13 @@
+stages:
+ - build
+ - test
+ - review
+ - deploy
+ - production
+
+variables:
+ AUTO_DEVOPS_PLATFORM_TARGET: ECS
+
+include:
+ - template: Jobs/Build.gitlab-ci.yml
+ - template: Jobs/Deploy/ECS.gitlab-ci.yml
diff --git a/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml b/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml
index 5017037fb5a..e37cd14d1d1 100644
--- a/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml
@@ -13,6 +13,7 @@
# * license_management: LICENSE_MANAGEMENT_DISABLED
# * performance: PERFORMANCE_DISABLED
# * sast: SAST_DISABLED
+# * secret_detection: SECRET_DETECTION_DISABLED
# * dependency_scanning: DEPENDENCY_SCANNING_DISABLED
# * container_scanning: CONTAINER_SCANNING_DISABLED
# * dast: DAST_DISABLED
@@ -160,3 +161,4 @@ include:
- template: Security/Dependency-Scanning.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml
- template: Security/License-Scanning.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Security/License-Scanning.gitlab-ci.yml
- template: Security/SAST.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml
+ - template: Security/Secret-Detection.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Security/Secret-Detection.gitlab-ci.yml
diff --git a/lib/gitlab/ci/templates/Deploy-ECS.gitlab-ci.yml b/lib/gitlab/ci/templates/Deploy-ECS.gitlab-ci.yml
index 82b2f5c035e..5f4bd631db6 100644
--- a/lib/gitlab/ci/templates/Deploy-ECS.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Deploy-ECS.gitlab-ci.yml
@@ -1,3 +1,18 @@
+# This template is deprecated and will be removed as part of GitLab 13.2!
+#
+# If you have referenced this template in your CI pipeline, please
+# update your CI configuration by replacing the following occurrence(s):
+#
+# template: Deploy-ECS.gitlab-ci.yml
+#
+# with
+#
+# template: AWS/Deploy-ECS.gitlab-ci.yml
+#
+# --------------------
+#
+# Documentation: https://docs.gitlab.com/ee/ci/cloud_deployment/#deploy-your-application-to-the-aws-elastic-container-service-ecs
+
stages:
- build
- test
@@ -5,6 +20,9 @@ stages:
- deploy
- production
+before_script:
+ - printf '\nWARNING!\nThis job includes "Deploy-ECS.gitlab-ci.yml". Please rename this to "AWS/Deploy-ECS.gitlab-ci.yml".\n'
+
variables:
AUTO_DEVOPS_PLATFORM_TARGET: ECS
diff --git a/lib/gitlab/ci/templates/Jobs/Browser-Performance-Testing.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Browser-Performance-Testing.gitlab-ci.yml
index adbf9731e43..9a34f8cb113 100644
--- a/lib/gitlab/ci/templates/Jobs/Browser-Performance-Testing.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Browser-Performance-Testing.gitlab-ci.yml
@@ -1,11 +1,11 @@
performance:
stage: performance
- image: docker:19.03.8
+ image: docker:19.03.11
allow_failure: true
variables:
DOCKER_TLS_CERTDIR: ""
services:
- - docker:19.03.8-dind
+ - docker:19.03.11-dind
script:
- |
if ! docker info &>/dev/null; then
diff --git a/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml
index 787f07521e0..b5550461482 100644
--- a/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml
@@ -1,10 +1,10 @@
build:
stage: build
- image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-build-image:v0.2.2"
+ image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-build-image:v0.2.3"
variables:
DOCKER_TLS_CERTDIR: ""
services:
- - docker:19.03.8-dind
+ - docker:19.03.11-dind
script:
- |
if [[ -z "$CI_COMMIT_TAG" ]]; then
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 24e75c56a75..bde6f185d3a 100644
--- a/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml
@@ -1,9 +1,9 @@
code_quality:
stage: test
- image: docker:19.03.8
+ image: docker:19.03.11
allow_failure: true
services:
- - docker:19.03.8-dind
+ - docker:19.03.11-dind
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
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 5174aed04ba..bab4fae67f0 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,5 @@
.dast-auto-deploy:
- image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v0.15.0"
+ image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v0.17.0"
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 3fbae496896..97b5f3fd7f5 100644
--- a/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
@@ -1,5 +1,5 @@
.auto-deploy:
- image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v0.15.0"
+ image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v0.17.0"
include:
- template: Jobs/Deploy/ECS.gitlab-ci.yml
@@ -177,6 +177,7 @@ production_manual:
.manual_rollout_template: &manual_rollout_template
<<: *rollout_template
stage: production
+ resource_group: production
allow_failure: true
rules:
- if: '$CI_KUBERNETES_ACTIVE == null || $CI_KUBERNETES_ACTIVE == ""'
diff --git a/lib/gitlab/ci/templates/Jobs/Deploy/ECS.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Deploy/ECS.gitlab-ci.yml
index 642f0ebeaf7..bb3d5526f3a 100644
--- a/lib/gitlab/ci/templates/Jobs/Deploy/ECS.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Deploy/ECS.gitlab-ci.yml
@@ -1,3 +1,13 @@
+# WARNING (post-GitLab 13.0):
+#
+# This CI template should NOT be included in your own CI configuration files:
+# 'review_ecs' and 'production_ecs' are two temporary names given to the jobs below.
+#
+# Should this template be included in your CI configuration, the upcoming name changes could
+# then result in potentially breaking your future pipelines.
+#
+# More about including CI templates: https://docs.gitlab.com/ee/ci/yaml/#includetemplate
+
.deploy_to_ecs:
image: 'registry.gitlab.com/gitlab-org/cloud-deploy/aws-ecs:latest'
script:
@@ -15,7 +25,9 @@ review_ecs:
when: never
- if: '$REVIEW_DISABLED'
when: never
- - if: '$CI_COMMIT_BRANCH != "master"'
+ - if: '$CI_COMMIT_BRANCH == "master"'
+ when: never
+ - if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH'
production_ecs:
extends: .deploy_to_ecs
@@ -27,4 +39,6 @@ production_ecs:
when: never
- if: '$CI_KUBERNETES_ACTIVE'
when: never
- - if: '$CI_COMMIT_BRANCH == "master"'
+ - if: '$CI_COMMIT_BRANCH != "master"'
+ when: never
+ - if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH'
diff --git a/lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml b/lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml
index 54a29b04d39..316647b5921 100644
--- a/lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml
@@ -1,6 +1,6 @@
apply:
stage: deploy
- image: "registry.gitlab.com/gitlab-org/cluster-integration/cluster-applications:v0.15.0"
+ image: "registry.gitlab.com/gitlab-org/cluster-integration/cluster-applications:v0.20.0"
environment:
name: production
variables:
@@ -19,12 +19,17 @@ apply:
CROSSPLANE_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/crossplane/values.yaml
FLUENTD_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/fluentd/values.yaml
KNATIVE_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/knative/values.yaml
+ POSTHOG_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/posthog/values.yaml
+ FALCO_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/falco/values.yaml
+ APPARMOR_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/apparmor/values.yaml
script:
- gitlab-managed-apps /usr/local/share/gitlab-managed-apps/helmfile.yaml
only:
refs:
- master
artifacts:
+ reports:
+ cluster_applications: gl-cluster-applications.json
when: on_failure
paths:
- tiller.log
diff --git a/lib/gitlab/ci/templates/Rust.gitlab-ci.yml b/lib/gitlab/ci/templates/Rust.gitlab-ci.yml
index a25dc38e4e7..f35470367cc 100644
--- a/lib/gitlab/ci/templates/Rust.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Rust.gitlab-ci.yml
@@ -20,4 +20,4 @@ image: "rust:latest"
test:cargo:
script:
- rustc --version && cargo --version # Print version info for debugging
- - cargo test --all --verbose
+ - cargo test --workspace --verbose
diff --git a/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml
index 616966b4f04..fa8ccb7cf93 100644
--- a/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml
@@ -13,6 +13,7 @@ variables:
DS_ANALYZER_IMAGE_PREFIX: "$SECURE_ANALYZERS_PREFIX"
DS_DEFAULT_ANALYZERS: "bundler-audit, retire.js, gemnasium, gemnasium-maven, gemnasium-python"
+ DS_EXCLUDED_PATHS: "spec, test, tests, tmp"
DS_MAJOR_VERSION: 2
DS_DISABLE_DIND: "true"
@@ -125,6 +126,7 @@ gemnasium-maven-dependency_scanning:
$DS_DEFAULT_ANALYZERS =~ /gemnasium-maven/
exists:
- '{build.gradle,*/build.gradle,*/*/build.gradle}'
+ - '{build.gradle.kts,*/build.gradle.kts,*/*/build.gradle.kts}'
- '{build.sbt,*/build.sbt,*/*/build.sbt}'
- '{pom.xml,*/pom.xml,*/*/pom.xml}'
diff --git a/lib/gitlab/ci/templates/Security/License-Scanning.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/License-Scanning.gitlab-ci.yml
index b86014c1ebc..b0c75b0aab0 100644
--- a/lib/gitlab/ci/templates/Security/License-Scanning.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/License-Scanning.gitlab-ci.yml
@@ -19,6 +19,7 @@ license_scanning:
entrypoint: [""]
variables:
LM_REPORT_FILE: gl-license-scanning-report.json
+ LM_REPORT_VERSION: '2.1'
SETUP_CMD: $LICENSE_MANAGEMENT_SETUP_CMD
allow_failure: true
script:
diff --git a/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml
index 47f68118ee0..ec7b34d17b5 100644
--- a/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml
@@ -13,6 +13,7 @@ variables:
SAST_ANALYZER_IMAGE_PREFIX: "$SECURE_ANALYZERS_PREFIX"
SAST_DEFAULT_ANALYZERS: "bandit, brakeman, gosec, spotbugs, flawfinder, phpcs-security-audit, security-code-scan, nodejs-scan, eslint, tslint, secrets, sobelow, pmd-apex, kubesec"
+ SAST_EXCLUDED_PATHS: "spec, test, tests, tmp"
SAST_ANALYZER_IMAGE_TAG: 2
SAST_DISABLE_DIND: "true"
SCAN_KUBERNETES_MANIFESTS: "false"
@@ -80,10 +81,9 @@ brakeman-sast:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
- if: $CI_COMMIT_BRANCH &&
- $GITLAB_FEATURES =~ /\bsast\b/ &&
$SAST_DEFAULT_ANALYZERS =~ /brakeman/
exists:
- - '**/*.rb'
+ - 'config/routes.rb'
eslint-sast:
extends: .sast-analyzer
@@ -149,7 +149,7 @@ nodejs-scan-sast:
$GITLAB_FEATURES =~ /\bsast\b/ &&
$SAST_DEFAULT_ANALYZERS =~ /nodejs-scan/
exists:
- - '**/*.js'
+ - 'package.json'
phpcs-security-audit-sast:
extends: .sast-analyzer
@@ -213,8 +213,7 @@ sobelow-sast:
$GITLAB_FEATURES =~ /\bsast\b/ &&
$SAST_DEFAULT_ANALYZERS =~ /sobelow/
exists:
- - '**/*.ex'
- - '**/*.exs'
+ - 'mix.exs'
spotbugs-sast:
extends: .sast-analyzer
diff --git a/lib/gitlab/ci/templates/Security/Secret-Detection.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/Secret-Detection.gitlab-ci.yml
new file mode 100644
index 00000000000..e18f89cadd7
--- /dev/null
+++ b/lib/gitlab/ci/templates/Security/Secret-Detection.gitlab-ci.yml
@@ -0,0 +1,24 @@
+# Read more about this feature here: https://docs.gitlab.com/ee/user/application_security/secret_detection
+#
+# Configure the scanning tool through the environment variables.
+# List of the variables: https://gitlab.com/gitlab-org/security-products/secret_detection#available-variables
+# How to set: https://docs.gitlab.com/ee/ci/yaml/#variables
+
+variables:
+ SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
+ SECRETS_ANALYZER_VERSION: "3"
+
+secret_detection:
+ stage: test
+ image: "$SECURE_ANALYZERS_PREFIX/secrets:$SECRETS_ANALYZER_VERSION"
+ services: []
+ rules:
+ - if: $SECRET_DETECTION_DISABLED
+ when: never
+ - if: $CI_COMMIT_BRANCH && $GITLAB_FEATURES =~ /\bsecret_detection\b/
+ when: on_success
+ artifacts:
+ reports:
+ secret_detection: gl-secret-detection-report.json
+ script:
+ - /analyzer run
diff --git a/lib/gitlab/ci/templates/Terraform.gitlab-ci.yml b/lib/gitlab/ci/templates/Terraform.gitlab-ci.yml
index a0832718214..377c72e8031 100644
--- a/lib/gitlab/ci/templates/Terraform.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Terraform.gitlab-ci.yml
@@ -40,7 +40,6 @@ plan:
- terraform plan -out=$PLAN
- "terraform show --json $PLAN | convert_report > $JSON_PLAN_FILE"
artifacts:
- name: plan
paths:
- $PLAN
reports:
diff --git a/lib/gitlab/ci/templates/Verify/FailFast.gitlab-ci.yml b/lib/gitlab/ci/templates/Verify/FailFast.gitlab-ci.yml
new file mode 100644
index 00000000000..77a1b57d92f
--- /dev/null
+++ b/lib/gitlab/ci/templates/Verify/FailFast.gitlab-ci.yml
@@ -0,0 +1,17 @@
+rspec-rails-modified-path-specs:
+ stage: .pre
+ rules:
+ - if: $CI_MERGE_REQUEST_EVENT_TYPE == "merged_result" || $CI_MERGE_REQUEST_EVENT_TYPE == "merge_train"
+ changes: ["**/*.rb"]
+ script:
+ - gem install test_file_finder
+ - spec_files=$(tff $(git diff --name-only "$CI_MERGE_REQUEST_TARGET_BRANCH_SHA..$CI_MERGE_REQUEST_SOURCE_BRANCH_SHA"))
+ - |
+ if [ -n "$spec_files" ]
+ then
+ bundle install
+ bundle exec rspec -- $spec_files
+ else
+ echo "No relevant spec files found by tff"
+ exit 0
+ fi
diff --git a/lib/gitlab/ci/trace.rb b/lib/gitlab/ci/trace.rb
index 4e83826b249..f76aacc2d19 100644
--- a/lib/gitlab/ci/trace.rb
+++ b/lib/gitlab/ci/trace.rb
@@ -147,7 +147,7 @@ module Gitlab
raise AlreadyArchivedError, 'Could not write to the archived trace'
elsif current_path
File.open(current_path, mode)
- elsif Feature.enabled?('ci_enable_live_trace', job.project)
+ elsif Feature.enabled?(:ci_enable_live_trace, job.project)
Gitlab::Ci::Trace::ChunkedIO.new(job)
else
File.open(ensure_path, mode)
diff --git a/lib/gitlab/ci/yaml_processor.rb b/lib/gitlab/ci/yaml_processor.rb
index 5816ac3bc54..6a9b7b2fc85 100644
--- a/lib/gitlab/ci/yaml_processor.rb
+++ b/lib/gitlab/ci/yaml_processor.rb
@@ -88,7 +88,7 @@ module Gitlab
end
def release(job)
- job[:release] if Feature.enabled?(:ci_release_generation, default_enabled: false)
+ job[:release] if Gitlab::Ci::Features.release_generation_enabled?
end
def stage_builds_attributes(stage)
diff --git a/lib/gitlab/code_navigation_path.rb b/lib/gitlab/code_navigation_path.rb
index 57aeb6c4fb2..faf623faccf 100644
--- a/lib/gitlab/code_navigation_path.rb
+++ b/lib/gitlab/code_navigation_path.rb
@@ -13,7 +13,7 @@ module Gitlab
end
def full_json_path_for(path)
- return if Feature.disabled?(:code_navigation, project)
+ return unless Feature.enabled?(:code_navigation, project, default_enabled: true)
return unless build
raw_project_job_artifacts_path(project, build, path: "lsif/#{path}.json", file_type: :lsif)
diff --git a/lib/gitlab/config/loader/yaml.rb b/lib/gitlab/config/loader/yaml.rb
index 4cedab1545c..e001742a7f8 100644
--- a/lib/gitlab/config/loader/yaml.rb
+++ b/lib/gitlab/config/loader/yaml.rb
@@ -21,11 +21,15 @@ module Gitlab
hash? && !too_big?
end
- def load!
+ def load_raw!
raise DataTooLargeError, 'The parsed YAML is too big' if too_big?
raise Loader::FormatError, 'Invalid configuration format' unless hash?
- @config.deep_symbolize_keys
+ @config
+ end
+
+ def load!
+ @symbolized_config ||= load_raw!.deep_symbolize_keys
end
private
diff --git a/lib/gitlab/contributions_calendar.rb b/lib/gitlab/contributions_calendar.rb
index 5b0b91de5da..4e430d8937d 100644
--- a/lib/gitlab/contributions_calendar.rb
+++ b/lib/gitlab/contributions_calendar.rb
@@ -24,13 +24,13 @@ module Gitlab
# project_features for the (currently) 3 different contribution types
date_from = 1.year.ago
repo_events = event_counts(date_from, :repository)
- .having(action: Event::PUSHED)
+ .having(action: :pushed)
issue_events = event_counts(date_from, :issues)
- .having(action: [Event::CREATED, Event::CLOSED], target_type: "Issue")
+ .having(action: [:created, :closed], target_type: "Issue")
mr_events = event_counts(date_from, :merge_requests)
- .having(action: [Event::MERGED, Event::CREATED, Event::CLOSED], target_type: "MergeRequest")
+ .having(action: [:merged, :created, :closed], target_type: "MergeRequest")
note_events = event_counts(date_from, :merge_requests)
- .having(action: [Event::COMMENTED])
+ .having(action: :commented)
events = Event
.from_union([repo_events, issue_events, mr_events, note_events])
diff --git a/lib/gitlab/cycle_analytics/summary/commit.rb b/lib/gitlab/cycle_analytics/summary/commit.rb
index 1f426b81800..1dc9d5de966 100644
--- a/lib/gitlab/cycle_analytics/summary/commit.rb
+++ b/lib/gitlab/cycle_analytics/summary/commit.rb
@@ -5,7 +5,7 @@ module Gitlab
module Summary
class Commit < Base
def title
- n_('Commit', 'Commits', value)
+ n_('Commit', 'Commits', value.to_i)
end
def value
diff --git a/lib/gitlab/cycle_analytics/summary/deploy.rb b/lib/gitlab/cycle_analytics/summary/deploy.rb
index 8544ea1a91e..5125c8e64ee 100644
--- a/lib/gitlab/cycle_analytics/summary/deploy.rb
+++ b/lib/gitlab/cycle_analytics/summary/deploy.rb
@@ -5,7 +5,7 @@ module Gitlab
module Summary
class Deploy < Base
def title
- n_('Deploy', 'Deploys', value)
+ n_('Deploy', 'Deploys', value.to_i)
end
def value
diff --git a/lib/gitlab/cycle_analytics/summary/issue.rb b/lib/gitlab/cycle_analytics/summary/issue.rb
index ce7788590b9..462fd4c2d3d 100644
--- a/lib/gitlab/cycle_analytics/summary/issue.rb
+++ b/lib/gitlab/cycle_analytics/summary/issue.rb
@@ -12,7 +12,7 @@ module Gitlab
end
def title
- n_('New Issue', 'New Issues', value)
+ n_('New Issue', 'New Issues', value.to_i)
end
def value
diff --git a/lib/gitlab/cycle_analytics/summary/value.rb b/lib/gitlab/cycle_analytics/summary/value.rb
index ce32132e048..e443e037517 100644
--- a/lib/gitlab/cycle_analytics/summary/value.rb
+++ b/lib/gitlab/cycle_analytics/summary/value.rb
@@ -15,6 +15,14 @@ module Gitlab
end
class None < self
+ def raw_value
+ 0
+ end
+
+ def to_i
+ raw_value
+ end
+
def to_s
'-'
end
@@ -28,6 +36,10 @@ module Gitlab
def to_s
value.zero? ? '0' : value.to_s
end
+
+ def to_i
+ raw_value
+ end
end
class PrettyNumeric < Numeric
diff --git a/lib/gitlab/danger/emoji_checker.rb b/lib/gitlab/danger/emoji_checker.rb
index a2867087428..e31a6ae5011 100644
--- a/lib/gitlab/danger/emoji_checker.rb
+++ b/lib/gitlab/danger/emoji_checker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative '../json'
+require 'json'
module Gitlab
module Danger
@@ -25,8 +25,8 @@ module Gitlab
)}x.freeze
def initialize
- names = Gitlab::Json.parse(File.read(DIGESTS)).keys +
- Gitlab::Json.parse(File.read(ALIASES)).keys
+ names = JSON.parse(File.read(DIGESTS)).keys +
+ JSON.parse(File.read(ALIASES)).keys
@emoji = names.map { |name| ":#{name}:" }
end
diff --git a/lib/gitlab/danger/helper.rb b/lib/gitlab/danger/helper.rb
index 0f0af5f777b..327418ad100 100644
--- a/lib/gitlab/danger/helper.rb
+++ b/lib/gitlab/danger/helper.rb
@@ -142,6 +142,7 @@ module Gitlab
%r{Dangerfile\z} => :engineering_productivity,
%r{\A(ee/)?(danger/|lib/gitlab/danger/)} => :engineering_productivity,
%r{\A(ee/)?scripts/} => :engineering_productivity,
+ %r{\A\.codeclimate\.yml\z} => :engineering_productivity,
%r{\A(ee/)?app/(?!assets|views)[^/]+} => :backend,
%r{\A(ee/)?(bin|config|generator_templates|lib|rubocop)/} => :backend,
@@ -151,6 +152,7 @@ module Gitlab
%r{\A(Gemfile|Gemfile.lock|Rakefile)\z} => :backend,
%r{\A[A-Z_]+_VERSION\z} => :backend,
%r{\A\.rubocop(_todo)?\.yml\z} => :backend,
+ %r{\Afile_hooks/} => :backend,
%r{\A(ee/)?qa/} => :qa,
diff --git a/lib/gitlab/danger/request_helper.rb b/lib/gitlab/danger/request_helper.rb
index ef51c3f2052..06da4ed9ad3 100644
--- a/lib/gitlab/danger/request_helper.rb
+++ b/lib/gitlab/danger/request_helper.rb
@@ -16,7 +16,7 @@ module Gitlab
raise HTTPError, "Failed to read #{url}: #{rsp.code} #{rsp.message}"
end
- Gitlab::Json.parse(rsp.body)
+ JSON.parse(rsp.body)
end
end
end
diff --git a/lib/gitlab/danger/roulette.rb b/lib/gitlab/danger/roulette.rb
index dbf42912882..9f7980dc20a 100644
--- a/lib/gitlab/danger/roulette.rb
+++ b/lib/gitlab/danger/roulette.rb
@@ -6,6 +6,46 @@ module Gitlab
module Danger
module Roulette
ROULETTE_DATA_URL = 'https://about.gitlab.com/roulette.json'
+ OPTIONAL_CATEGORIES = [:qa, :test].freeze
+
+ Spin = Struct.new(:category, :reviewer, :maintainer, :optional_role)
+
+ # Assigns GitLab team members to be reviewer and maintainer
+ # for each change category that a Merge Request contains.
+ #
+ # @return [Array<Spin>]
+ def spin(project, categories, branch_name)
+ team =
+ begin
+ project_team(project)
+ rescue => err
+ warn("Reviewer roulette failed to load team data: #{err.message}")
+ []
+ end
+
+ canonical_branch_name = canonical_branch_name(branch_name)
+
+ spin_per_category = categories.each_with_object({}) do |category, memo|
+ memo[category] = spin_for_category(team, project, category, canonical_branch_name)
+ end
+
+ spin_per_category.map do |category, spin|
+ case category
+ when :test
+ if spin.reviewer.nil?
+ # Fetch an already picked backend reviewer, or pick one otherwise
+ spin.reviewer = spin_per_category[:backend]&.reviewer || spin_for_category(team, project, :backend, canonical_branch_name).reviewer
+ end
+ when :engineering_productivity
+ if spin.maintainer.nil?
+ # Fetch an already picked backend maintainer, or pick one otherwise
+ spin.maintainer = spin_per_category[:backend]&.maintainer || spin_for_category(team, project, :backend, canonical_branch_name).maintainer
+ end
+ end
+
+ spin
+ end
+ end
# Looks up the current list of GitLab team members and parses it into a
# useful form
@@ -58,6 +98,33 @@ module Gitlab
def mr_author?(person)
person.username == gitlab.mr_author
end
+
+ def spin_role_for_category(team, role, project, category)
+ team.select do |member|
+ member.public_send("#{role}?", project, category, gitlab.mr_labels) # rubocop:disable GitlabSecurity/PublicSend
+ end
+ end
+
+ def spin_for_category(team, project, category, branch_name)
+ reviewers, traintainers, maintainers =
+ %i[reviewer traintainer maintainer].map do |role|
+ spin_role_for_category(team, role, project, category)
+ end
+
+ # TODO: take CODEOWNERS into account?
+ # https://gitlab.com/gitlab-org/gitlab/issues/26723
+
+ # Make traintainers have triple the chance to be picked as a reviewer
+ random = new_random(branch_name)
+ reviewer = spin_for_person(reviewers + traintainers + traintainers, random: random)
+ maintainer = spin_for_person(maintainers, random: random)
+
+ Spin.new(category, reviewer, maintainer).tap do |spin|
+ if OPTIONAL_CATEGORIES.include?(category)
+ spin.optional_role = :maintainer
+ end
+ end
+ end
end
end
end
diff --git a/lib/gitlab/data_builder/alert.rb b/lib/gitlab/data_builder/alert.rb
new file mode 100644
index 00000000000..e34bdeea799
--- /dev/null
+++ b/lib/gitlab/data_builder/alert.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module DataBuilder
+ module Alert
+ extend self
+
+ def build(alert)
+ {
+ object_kind: 'alert',
+ object_attributes: hook_attrs(alert)
+ }
+ end
+
+ def hook_attrs(alert)
+ {
+ title: alert.title,
+ url: Gitlab::Routing.url_helpers.details_project_alert_management_url(alert.project, alert.iid),
+ severity: alert.severity,
+ events: alert.events,
+ status: alert.status_name,
+ started_at: alert.started_at
+ }
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/data_builder/note.rb b/lib/gitlab/data_builder/note.rb
index 2c4ef73a688..73518d36d43 100644
--- a/lib/gitlab/data_builder/note.rb
+++ b/lib/gitlab/data_builder/note.rb
@@ -55,7 +55,7 @@ module Gitlab
end
def build_base_data(project, user, note)
- event_type = note.confidential? ? 'confidential_note' : 'note'
+ event_type = note.confidential?(include_noteable: true) ? 'confidential_note' : 'note'
base_data = {
object_kind: "note",
diff --git a/lib/gitlab/database/custom_structure.rb b/lib/gitlab/database/custom_structure.rb
new file mode 100644
index 00000000000..c5a76c5a787
--- /dev/null
+++ b/lib/gitlab/database/custom_structure.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ class CustomStructure
+ CUSTOM_DUMP_FILE = 'db/gitlab_structure.sql'
+
+ def dump
+ File.open(self.class.custom_dump_filepath, 'wb') do |io|
+ io << "-- this file tracks custom GitLab data, such as foreign keys referencing partitioned tables\n"
+ io << "-- more details can be found in the issue: https://gitlab.com/gitlab-org/gitlab/-/issues/201872\n"
+ io << "SET search_path=public;\n\n"
+
+ dump_partitioned_foreign_keys(io) if partitioned_foreign_keys_exist?
+ end
+ end
+
+ def self.custom_dump_filepath
+ Rails.root.join(CUSTOM_DUMP_FILE)
+ end
+
+ private
+
+ def dump_partitioned_foreign_keys(io)
+ io << "COPY partitioned_foreign_keys (#{partitioned_fk_columns.join(", ")}) FROM STDIN;\n"
+
+ PartitioningMigrationHelpers::PartitionedForeignKey.find_each do |fk|
+ io << fk.attributes.values_at(*partitioned_fk_columns).join("\t") << "\n"
+ end
+ io << "\\.\n"
+ end
+
+ def partitioned_foreign_keys_exist?
+ return false unless PartitioningMigrationHelpers::PartitionedForeignKey.table_exists?
+
+ PartitioningMigrationHelpers::PartitionedForeignKey.exists?
+ end
+
+ def partitioned_fk_columns
+ @partitioned_fk_columns ||= PartitioningMigrationHelpers::PartitionedForeignKey.column_names
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb
index 96be057f77e..fd09c31e994 100644
--- a/lib/gitlab/database/migration_helpers.rb
+++ b/lib/gitlab/database/migration_helpers.rb
@@ -3,6 +3,8 @@
module Gitlab
module Database
module MigrationHelpers
+ # https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS
+ MAX_IDENTIFIER_NAME_LENGTH = 63
BACKGROUND_MIGRATION_BATCH_SIZE = 1000 # Number of rows to process per job
BACKGROUND_MIGRATION_JOB_BUFFER_SIZE = 1000 # Number of jobs to bulk queue at a time
@@ -1209,6 +1211,8 @@ into similar problems in the future (e.g. when new tables are created).
#
# rubocop:disable Gitlab/RailsLogger
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?
@@ -1244,6 +1248,8 @@ into similar problems in the future (e.g. when new tables are created).
end
def validate_check_constraint(table, constraint_name)
+ validate_check_constraint_name!(constraint_name)
+
unless check_constraint_exists?(table, constraint_name)
raise missing_schema_object_message(table, "check constraint", constraint_name)
end
@@ -1256,6 +1262,8 @@ into similar problems in the future (e.g. when new tables are created).
end
def remove_check_constraint(table, constraint_name)
+ validate_check_constraint_name!(constraint_name)
+
# DROP CONSTRAINT requires an EXCLUSIVE lock
# Use with_lock_retries to make sure that this will not timeout
with_lock_retries do
@@ -1330,6 +1338,12 @@ into similar problems in the future (e.g. when new tables are created).
private
+ 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"
+ end
+ end
+
def statement_timeout_disabled?
# This is a string of the form "100ms" or "0" when disabled
connection.select_value('SHOW statement_timeout') == "0"
diff --git a/lib/gitlab/database/partitioning_migration_helpers.rb b/lib/gitlab/database/partitioning_migration_helpers.rb
index 55649ebbf8a..881177a195e 100644
--- a/lib/gitlab/database/partitioning_migration_helpers.rb
+++ b/lib/gitlab/database/partitioning_migration_helpers.rb
@@ -3,120 +3,8 @@
module Gitlab
module Database
module PartitioningMigrationHelpers
- include SchemaHelpers
-
- def add_partitioned_foreign_key(from_table, to_table, column: nil, primary_key: :id, on_delete: :cascade)
- cascade_delete = extract_cascade_option(on_delete)
-
- update_foreign_keys(from_table, to_table, column, primary_key, cascade_delete) do |current_keys, existing_key, specified_key|
- if existing_key.nil?
- unless specified_key.save
- raise "failed to create foreign key: #{specified_key.errors.full_messages.to_sentence}"
- end
-
- current_keys << specified_key
- else
- Rails.logger.warn "foreign key not added because it already exists: #{specified_key}" # rubocop:disable Gitlab/RailsLogger
- current_keys
- end
- end
- end
-
- def remove_partitioned_foreign_key(from_table, to_table, column: nil, primary_key: :id)
- update_foreign_keys(from_table, to_table, column, primary_key) do |current_keys, existing_key, specified_key|
- if existing_key
- existing_key.destroy!
- current_keys.delete(existing_key)
- else
- Rails.logger.warn "foreign key not removed because it doesn't exist: #{specified_key}" # rubocop:disable Gitlab/RailsLogger
- end
-
- current_keys
- end
- end
-
- def fk_function_name(table)
- object_name(table, 'fk_cascade_function')
- end
-
- def fk_trigger_name(table)
- object_name(table, 'fk_cascade_trigger')
- end
-
- private
-
- def fk_from_spec(from_table, to_table, from_column, to_column, cascade_delete)
- PartitionedForeignKey.new(from_table: from_table.to_s, to_table: to_table.to_s, from_column: from_column.to_s,
- to_column: to_column.to_s, cascade_delete: cascade_delete)
- end
-
- def update_foreign_keys(from_table, to_table, from_column, to_column, cascade_delete = nil)
- if transaction_open?
- raise 'partitioned foreign key operations can not be run inside a transaction block, ' \
- 'you can disable transaction blocks by calling disable_ddl_transaction! ' \
- 'in the body of your migration class'
- end
-
- from_column ||= "#{to_table.to_s.singularize}_id"
- specified_key = fk_from_spec(from_table, to_table, from_column, to_column, cascade_delete)
-
- current_keys = PartitionedForeignKey.by_referenced_table(to_table).to_a
- existing_key = find_existing_key(current_keys, specified_key)
-
- final_keys = yield current_keys, existing_key, specified_key
-
- fn_name = fk_function_name(to_table)
- trigger_name = fk_trigger_name(to_table)
-
- with_lock_retries do
- drop_trigger(to_table, trigger_name, if_exists: true)
-
- if final_keys.empty?
- drop_function(fn_name, if_exists: true)
- else
- create_or_replace_fk_function(fn_name, final_keys)
- create_function_trigger(trigger_name, fn_name, fires: "AFTER DELETE ON #{to_table}")
- end
- end
- end
-
- def extract_cascade_option(on_delete)
- case on_delete
- when :cascade then true
- when :nullify then false
- else raise ArgumentError, "invalid option #{on_delete} for :on_delete"
- end
- end
-
- def with_lock_retries(&block)
- Gitlab::Database::WithLockRetries.new({
- klass: self.class,
- logger: Gitlab::BackgroundMigration::Logger
- }).run(&block)
- end
-
- def find_existing_key(keys, key)
- keys.find { |k| k.from_table == key.from_table && k.from_column == key.from_column }
- end
-
- def create_or_replace_fk_function(fn_name, fk_specs)
- create_trigger_function(fn_name, replace: true) do
- cascade_statements = build_cascade_statements(fk_specs)
- cascade_statements << 'RETURN OLD;'
-
- cascade_statements.join("\n")
- end
- end
-
- def build_cascade_statements(foreign_keys)
- foreign_keys.map do |fks|
- if fks.cascade_delete?
- "DELETE FROM #{fks.from_table} WHERE #{fks.from_column} = OLD.#{fks.to_column};"
- else
- "UPDATE #{fks.from_table} SET #{fks.from_column} = NULL WHERE #{fks.from_column} = OLD.#{fks.to_column};"
- end
- end
- end
+ include ForeignKeyHelpers
+ include TableManagementHelpers
end
end
end
diff --git a/lib/gitlab/database/partitioning_migration_helpers/foreign_key_helpers.rb b/lib/gitlab/database/partitioning_migration_helpers/foreign_key_helpers.rb
new file mode 100644
index 00000000000..9e687009cd7
--- /dev/null
+++ b/lib/gitlab/database/partitioning_migration_helpers/foreign_key_helpers.rb
@@ -0,0 +1,140 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module PartitioningMigrationHelpers
+ module ForeignKeyHelpers
+ include ::Gitlab::Database::SchemaHelpers
+
+ # Creates a "foreign key" that references a partitioned table. Because foreign keys referencing partitioned
+ # tables are not supported in PG11, this does not create a true database foreign key, but instead implements the
+ # same functionality at the database level by using triggers.
+ #
+ # Example:
+ #
+ # add_partitioned_foreign_key :issues, :projects
+ #
+ # Available options:
+ #
+ # :column - name of the referencing column (otherwise inferred from the referenced table name)
+ # :primary_key - name of the primary key in the referenced table (defaults to id)
+ # :on_delete - supports either :cascade for ON DELETE CASCADE or :nullify for ON DELETE SET NULL
+ #
+ def add_partitioned_foreign_key(from_table, to_table, column: nil, primary_key: :id, on_delete: :cascade)
+ cascade_delete = extract_cascade_option(on_delete)
+
+ update_foreign_keys(from_table, to_table, column, primary_key, cascade_delete) do |current_keys, existing_key, specified_key|
+ if existing_key.nil?
+ unless specified_key.save
+ raise "failed to create foreign key: #{specified_key.errors.full_messages.to_sentence}"
+ end
+
+ current_keys << specified_key
+ else
+ Rails.logger.warn "foreign key not added because it already exists: #{specified_key}" # rubocop:disable Gitlab/RailsLogger
+ current_keys
+ end
+ end
+ end
+
+ # Drops a "foreign key" that references a partitioned table. This method ONLY applies to foreign keys previously
+ # created through the `add_partitioned_foreign_key` method. Standard database foreign keys should be managed
+ # through the familiar Rails helpers.
+ #
+ # Example:
+ #
+ # remove_partitioned_foreign_key :issues, :projects
+ #
+ # Available options:
+ #
+ # :column - name of the referencing column (otherwise inferred from the referenced table name)
+ # :primary_key - name of the primary key in the referenced table (defaults to id)
+ #
+ def remove_partitioned_foreign_key(from_table, to_table, column: nil, primary_key: :id)
+ update_foreign_keys(from_table, to_table, column, primary_key) do |current_keys, existing_key, specified_key|
+ if existing_key
+ existing_key.delete
+ current_keys.delete(existing_key)
+ else
+ Rails.logger.warn "foreign key not removed because it doesn't exist: #{specified_key}" # rubocop:disable Gitlab/RailsLogger
+ end
+
+ current_keys
+ end
+ end
+
+ private
+
+ def fk_function_name(table)
+ object_name(table, 'fk_cascade_function')
+ end
+
+ def fk_trigger_name(table)
+ object_name(table, 'fk_cascade_trigger')
+ end
+
+ def fk_from_spec(from_table, to_table, from_column, to_column, cascade_delete)
+ PartitionedForeignKey.new(from_table: from_table.to_s, to_table: to_table.to_s, from_column: from_column.to_s,
+ to_column: to_column.to_s, cascade_delete: cascade_delete)
+ end
+
+ def update_foreign_keys(from_table, to_table, from_column, to_column, cascade_delete = nil)
+ assert_not_in_transaction_block(scope: 'partitioned foreign key')
+
+ from_column ||= "#{to_table.to_s.singularize}_id"
+ specified_key = fk_from_spec(from_table, to_table, from_column, to_column, cascade_delete)
+
+ current_keys = PartitionedForeignKey.by_referenced_table(to_table).to_a
+ existing_key = find_existing_key(current_keys, specified_key)
+
+ final_keys = yield current_keys, existing_key, specified_key
+
+ fn_name = fk_function_name(to_table)
+ trigger_name = fk_trigger_name(to_table)
+
+ with_lock_retries do
+ drop_trigger(to_table, trigger_name, if_exists: true)
+
+ if final_keys.empty?
+ drop_function(fn_name, if_exists: true)
+ else
+ create_or_replace_fk_function(fn_name, final_keys)
+ create_trigger(trigger_name, fn_name, fires: "AFTER DELETE ON #{to_table}")
+ end
+ end
+ end
+
+ def extract_cascade_option(on_delete)
+ case on_delete
+ when :cascade then true
+ when :nullify then false
+ else raise ArgumentError, "invalid option #{on_delete} for :on_delete"
+ end
+ end
+
+ def find_existing_key(keys, key)
+ keys.find { |k| k.from_table == key.from_table && k.from_column == key.from_column }
+ end
+
+ def create_or_replace_fk_function(fn_name, fk_specs)
+ create_trigger_function(fn_name, replace: true) do
+ cascade_statements = build_cascade_statements(fk_specs)
+ cascade_statements << 'RETURN OLD;'
+
+ cascade_statements.join("\n")
+ end
+ end
+
+ def build_cascade_statements(foreign_keys)
+ foreign_keys.map do |fks|
+ if fks.cascade_delete?
+ "DELETE FROM #{fks.from_table} WHERE #{fks.from_column} = OLD.#{fks.to_column};"
+ else
+ "UPDATE #{fks.from_table} SET #{fks.from_column} = NULL WHERE #{fks.from_column} = OLD.#{fks.to_column};"
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers.rb b/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers.rb
new file mode 100644
index 00000000000..f77fbe98df1
--- /dev/null
+++ b/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers.rb
@@ -0,0 +1,198 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module PartitioningMigrationHelpers
+ module TableManagementHelpers
+ include ::Gitlab::Database::SchemaHelpers
+
+ WHITELISTED_TABLES = %w[audit_events].freeze
+ ERROR_SCOPE = 'table partitioning'
+
+ # Creates a partitioned copy of an existing table, using a RANGE partitioning strategy on a timestamp column.
+ # One partition is created per month between the given `min_date` and `max_date`.
+ #
+ # A copy of the original table is required as PG currently does not support partitioning existing tables.
+ #
+ # Example:
+ #
+ # partition_table_by_date :audit_events, :created_at, min_date: Date.new(2020, 1), max_date: Date.new(2020, 6)
+ #
+ # Required options are:
+ # :min_date - a date specifying the lower bounds of the partition range
+ # :max_date - a date specifying the upper bounds of the partitioning range
+ #
+ def partition_table_by_date(table_name, column_name, min_date:, max_date:)
+ assert_table_is_whitelisted(table_name)
+ assert_not_in_transaction_block(scope: ERROR_SCOPE)
+
+ raise "max_date #{max_date} must be greater than min_date #{min_date}" if min_date >= max_date
+
+ primary_key = connection.primary_key(table_name)
+ raise "primary key not defined for #{table_name}" if primary_key.nil?
+
+ partition_column = find_column_definition(table_name, column_name)
+ raise "partition column #{column_name} does not exist on #{table_name}" if partition_column.nil?
+
+ new_table_name = partitioned_table_name(table_name)
+ create_range_partitioned_copy(new_table_name, table_name, partition_column, primary_key)
+ create_daterange_partitions(new_table_name, partition_column.name, min_date, max_date)
+ create_sync_trigger(table_name, new_table_name, primary_key)
+ end
+
+ # Clean up a partitioned copy of an existing table. This deletes the partitioned table and all partitions.
+ #
+ # Example:
+ #
+ # drop_partitioned_table_for :audit_events
+ #
+ def drop_partitioned_table_for(table_name)
+ assert_table_is_whitelisted(table_name)
+ assert_not_in_transaction_block(scope: ERROR_SCOPE)
+
+ with_lock_retries do
+ trigger_name = sync_trigger_name(table_name)
+ drop_trigger(table_name, trigger_name)
+ end
+
+ function_name = sync_function_name(table_name)
+ drop_function(function_name)
+
+ part_table_name = partitioned_table_name(table_name)
+ drop_table(part_table_name)
+ end
+
+ private
+
+ def assert_table_is_whitelisted(table_name)
+ return if WHITELISTED_TABLES.include?(table_name.to_s)
+
+ raise "partitioning helpers are in active development, and #{table_name} is not whitelisted for use, " \
+ "for more information please contact the database team"
+ end
+
+ def partitioned_table_name(table)
+ tmp_table_name("#{table}_part")
+ end
+
+ def sync_function_name(table)
+ object_name(table, 'table_sync_function')
+ end
+
+ def sync_trigger_name(table)
+ object_name(table, 'table_sync_trigger')
+ end
+
+ def find_column_definition(table, column)
+ connection.columns(table).find { |c| c.name == column.to_s }
+ end
+
+ def create_range_partitioned_copy(table_name, template_table_name, partition_column, primary_key)
+ if table_exists?(table_name)
+ # rubocop:disable Gitlab/RailsLogger
+ Rails.logger.warn "Partitioned table not created because it already exists" \
+ " (this may be due to an aborted migration or similar): table_name: #{table_name} "
+ # rubocop:enable Gitlab/RailsLogger
+ return
+ end
+
+ tmp_column_name = object_name(partition_column.name, 'partition_key')
+ transaction do
+ execute(<<~SQL)
+ CREATE TABLE #{table_name} (
+ LIKE #{template_table_name} INCLUDING ALL EXCLUDING INDEXES,
+ #{tmp_column_name} #{partition_column.sql_type} NOT NULL,
+ PRIMARY KEY (#{[primary_key, tmp_column_name].join(", ")})
+ ) PARTITION BY RANGE (#{tmp_column_name})
+ SQL
+
+ remove_column(table_name, partition_column.name)
+ rename_column(table_name, tmp_column_name, partition_column.name)
+ change_column_default(table_name, primary_key, nil)
+
+ if column_of_type?(table_name, primary_key, :integer)
+ # Default to int8 primary keys to prevent overflow
+ change_column(table_name, primary_key, :bigint)
+ end
+ end
+ end
+
+ def column_of_type?(table_name, column, type)
+ find_column_definition(table_name, column).type == type
+ end
+
+ def create_daterange_partitions(table_name, column_name, min_date, max_date)
+ min_date = min_date.beginning_of_month.to_date
+ max_date = max_date.next_month.beginning_of_month.to_date
+
+ create_range_partition_safely("#{table_name}_000000", table_name, 'MINVALUE', to_sql_date_literal(min_date))
+
+ while min_date < max_date
+ partition_name = "#{table_name}_#{min_date.strftime('%Y%m')}"
+ next_date = min_date.next_month
+ lower_bound = to_sql_date_literal(min_date)
+ upper_bound = to_sql_date_literal(next_date)
+
+ create_range_partition_safely(partition_name, table_name, lower_bound, upper_bound)
+ min_date = next_date
+ end
+ end
+
+ def to_sql_date_literal(date)
+ connection.quote(date.strftime('%Y-%m-%d'))
+ end
+
+ def create_range_partition_safely(partition_name, table_name, lower_bound, upper_bound)
+ if table_exists?(partition_name)
+ # rubocop:disable Gitlab/RailsLogger
+ Rails.logger.warn "Partition not created because it already exists" \
+ " (this may be due to an aborted migration or similar): partition_name: #{partition_name}"
+ # rubocop:enable Gitlab/RailsLogger
+ return
+ end
+
+ create_range_partition(partition_name, table_name, lower_bound, upper_bound)
+ end
+
+ def create_sync_trigger(source_table, target_table, unique_key)
+ function_name = sync_function_name(source_table)
+ trigger_name = sync_trigger_name(source_table)
+
+ with_lock_retries do
+ create_sync_function(function_name, target_table, unique_key)
+ create_comment('FUNCTION', function_name, "Partitioning migration: table sync for #{source_table} table")
+
+ create_trigger(trigger_name, function_name, fires: "AFTER INSERT OR UPDATE OR DELETE ON #{source_table}")
+ end
+ end
+
+ def create_sync_function(name, target_table, unique_key)
+ delimiter = ",\n "
+ column_names = connection.columns(target_table).map(&:name)
+ set_statements = build_set_statements(column_names, unique_key)
+ insert_values = column_names.map { |name| "NEW.#{name}" }
+
+ create_trigger_function(name, replace: false) do
+ <<~SQL
+ IF (TG_OP = 'DELETE') THEN
+ DELETE FROM #{target_table} where #{unique_key} = OLD.#{unique_key};
+ ELSIF (TG_OP = 'UPDATE') THEN
+ UPDATE #{target_table}
+ SET #{set_statements.join(delimiter)}
+ WHERE #{target_table}.#{unique_key} = NEW.#{unique_key};
+ ELSIF (TG_OP = 'INSERT') THEN
+ INSERT INTO #{target_table} (#{column_names.join(delimiter)})
+ VALUES (#{insert_values.join(delimiter)});
+ END IF;
+ RETURN NULL;
+ SQL
+ end
+ end
+
+ def build_set_statements(column_names, unique_key)
+ column_names.reject { |name| name == unique_key }.map { |column_name| "#{column_name} = NEW.#{column_name}" }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/schema_cleaner.rb b/lib/gitlab/database/schema_cleaner.rb
index c1436d3e7ca..ae9d77e635e 100644
--- a/lib/gitlab/database/schema_cleaner.rb
+++ b/lib/gitlab/database/schema_cleaner.rb
@@ -12,27 +12,15 @@ module Gitlab
def clean(io)
structure = original_schema.dup
- # Postgres compat fix for PG 9.6 (which doesn't support (AS datatype) syntax for sequences)
- structure.gsub!(/CREATE SEQUENCE [^.]+\.\S+\n(\s+AS integer\n)/) { |m| m.gsub(Regexp.last_match[1], '') }
-
- # Also a PG 9.6 compatibility fix, see below.
- structure.gsub!(/^CREATE EXTENSION IF NOT EXISTS plpgsql.*/, '')
- structure.gsub!(/^COMMENT ON EXTENSION.*/, '')
-
# Remove noise
+ structure.gsub!(/^COMMENT ON EXTENSION.*/, '')
structure.gsub!(/^SET.+/, '')
structure.gsub!(/^SELECT pg_catalog\.set_config\('search_path'.+/, '')
structure.gsub!(/^--.*/, "\n")
- structure.gsub!(/\n{3,}/, "\n\n")
- io << "SET search_path=public;\n\n"
+ structure = "SET search_path=public;\n" + structure
- # Adding plpgsql explicitly is again a compatibility fix for PG 9.6
- # In more recent versions of pg_dump, the extension isn't explicitly dumped anymore.
- # We use PG 9.6 still on CI and for schema checks - here this is still the case.
- io << <<~SQL.strip
- CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
- SQL
+ structure.gsub!(/\n{3,}/, "\n\n")
io << structure
diff --git a/lib/gitlab/database/schema_helpers.rb b/lib/gitlab/database/schema_helpers.rb
index f8d01c78ae8..8e544307d81 100644
--- a/lib/gitlab/database/schema_helpers.rb
+++ b/lib/gitlab/database/schema_helpers.rb
@@ -16,12 +16,12 @@ module Gitlab
SQL
end
- def create_function_trigger(name, fn_name, fires: nil)
+ def create_trigger(name, function_name, fires: nil)
execute(<<~SQL)
CREATE TRIGGER #{name}
#{fires}
FOR EACH ROW
- EXECUTE PROCEDURE #{fn_name}()
+ EXECUTE PROCEDURE #{function_name}()
SQL
end
@@ -35,6 +35,16 @@ module Gitlab
execute("DROP TRIGGER #{exists_clause} #{name} ON #{table_name}")
end
+ def create_comment(type, name, text)
+ execute("COMMENT ON #{type} #{name} IS '#{text}'")
+ end
+
+ def tmp_table_name(base)
+ hashed_base = Digest::SHA256.hexdigest(base).first(10)
+
+ "#{base}_#{hashed_base}"
+ end
+
def object_name(table, type)
identifier = "#{table}_#{type}"
hashed_identifier = Digest::SHA256.hexdigest(identifier).first(10)
@@ -42,8 +52,30 @@ module Gitlab
"#{type}_#{hashed_identifier}"
end
+ def with_lock_retries(&block)
+ Gitlab::Database::WithLockRetries.new({
+ klass: self.class,
+ logger: Gitlab::BackgroundMigration::Logger
+ }).run(&block)
+ end
+
+ def assert_not_in_transaction_block(scope:)
+ return unless transaction_open?
+
+ raise "#{scope} operations can not be run inside a transaction block, " \
+ "you can disable transaction blocks by calling disable_ddl_transaction! " \
+ "in the body of your migration class"
+ end
+
private
+ def create_range_partition(partition_name, table_name, lower_bound, upper_bound)
+ execute(<<~SQL)
+ CREATE TABLE #{partition_name} PARTITION OF #{table_name}
+ FOR VALUES FROM (#{lower_bound}) TO (#{upper_bound})
+ SQL
+ end
+
def optional_clause(flag, clause)
flag ? clause : ""
end
diff --git a/lib/gitlab/dependency_linker.rb b/lib/gitlab/dependency_linker.rb
index 7af380689d5..db60128b979 100644
--- a/lib/gitlab/dependency_linker.rb
+++ b/lib/gitlab/dependency_linker.rb
@@ -13,7 +13,9 @@ module Gitlab
CartfileLinker,
GodepsJsonLinker,
RequirementsTxtLinker,
- CargoTomlLinker
+ CargoTomlLinker,
+ GoModLinker,
+ GoSumLinker
].freeze
def self.linker(blob_name)
diff --git a/lib/gitlab/dependency_linker/go_mod_linker.rb b/lib/gitlab/dependency_linker/go_mod_linker.rb
new file mode 100644
index 00000000000..4d6fe366333
--- /dev/null
+++ b/lib/gitlab/dependency_linker/go_mod_linker.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module DependencyLinker
+ class GoModLinker < BaseLinker
+ include Gitlab::Golang
+
+ self.file_type = :go_mod
+
+ private
+
+ SEMVER = Gitlab::Regex.unbounded_semver_regex
+ NAME = Gitlab::Regex.go_package_regex
+ REGEX = Regexp.new("(?<name>#{NAME.source})(?:\\s+(?<version>v#{SEMVER.source}))?", SEMVER.options | NAME.options).freeze
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def link_dependencies
+ highlighted_lines.map!.with_index do |rich_line, i|
+ plain_line = plain_lines[i].chomp
+ match = REGEX.match(plain_line)
+ next rich_line unless match
+
+ i, j = match.offset(:name)
+ marker = StringRangeMarker.new(plain_line, rich_line.html_safe)
+ marker.mark([i..(j - 1)]) do |text, left:, right:|
+ url = package_url(text, match[:version])
+ url ? link_tag(text, url) : text
+ end
+ end
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+ end
+ end
+end
diff --git a/lib/gitlab/dependency_linker/go_sum_linker.rb b/lib/gitlab/dependency_linker/go_sum_linker.rb
new file mode 100644
index 00000000000..20dc82ede9f
--- /dev/null
+++ b/lib/gitlab/dependency_linker/go_sum_linker.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module DependencyLinker
+ class GoSumLinker < GoModLinker
+ self.file_type = :go_sum
+
+ private
+
+ BASE64 = Gitlab::Regex.base64_regex
+ REGEX = Regexp.new("^\\s*(?<name>#{NAME.source})\\s+(?<version>v#{SEMVER.source})(\/go.mod)?\\s+h1:(?<checksum>#{BASE64.source})\\s*$", NAME.options).freeze
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def link_dependencies
+ highlighted_lines.map!.with_index do |rich_line, i|
+ plain_line = plain_lines[i].chomp
+ match = REGEX.match(plain_line)
+ next rich_line unless match
+
+ i0, j0 = match.offset(:name)
+ i2, j2 = match.offset(:checksum)
+
+ marker = StringRangeMarker.new(plain_line, rich_line.html_safe)
+ marker.mark([i0..(j0 - 1), i2..(j2 - 1)]) do |text, left:, right:|
+ if left
+ url = package_url(text, match[:version])
+ url ? link_tag(text, url) : text
+
+ elsif right
+ link_tag(text, "https://sum.golang.org/lookup/#{match[:name]}@#{match[:version]}")
+ end
+ end
+ end
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+ end
+ end
+end
diff --git a/lib/gitlab/diff/file.rb b/lib/gitlab/diff/file.rb
index d1398ddb642..72dcc4fde71 100644
--- a/lib/gitlab/diff/file.rb
+++ b/lib/gitlab/diff/file.rb
@@ -225,6 +225,10 @@ module Gitlab
new_path.presence || old_path
end
+ def file_hash
+ Digest::SHA1.hexdigest(file_path)
+ end
+
def added_lines
@stats&.additions || diff_lines.count(&:added?)
end
@@ -237,6 +241,10 @@ module Gitlab
"#{file_path}-#{new_file?}-#{deleted_file?}-#{renamed_file?}"
end
+ def file_identifier_hash
+ Digest::SHA1.hexdigest(file_identifier)
+ end
+
def diffable?
repository.attributes(file_path).fetch('diff') { true }
end
diff --git a/lib/gitlab/diff/formatters/base_formatter.rb b/lib/gitlab/diff/formatters/base_formatter.rb
index 9704aed82c1..31eeadc45f7 100644
--- a/lib/gitlab/diff/formatters/base_formatter.rb
+++ b/lib/gitlab/diff/formatters/base_formatter.rb
@@ -6,6 +6,7 @@ module Gitlab
class BaseFormatter
attr_reader :old_path
attr_reader :new_path
+ attr_reader :file_identifier_hash
attr_reader :base_sha
attr_reader :start_sha
attr_reader :head_sha
@@ -16,6 +17,7 @@ module Gitlab
attrs[:diff_refs] = diff_file.diff_refs
attrs[:old_path] = diff_file.old_path
attrs[:new_path] = diff_file.new_path
+ attrs[:file_identifier_hash] = diff_file.file_identifier_hash
end
if diff_refs = attrs[:diff_refs]
@@ -26,6 +28,7 @@ module Gitlab
@old_path = attrs[:old_path]
@new_path = attrs[:new_path]
+ @file_identifier_hash = attrs[:file_identifier_hash]
@base_sha = attrs[:base_sha]
@start_sha = attrs[:start_sha]
@head_sha = attrs[:head_sha]
@@ -36,7 +39,7 @@ module Gitlab
end
def to_h
- {
+ out = {
base_sha: base_sha,
start_sha: start_sha,
head_sha: head_sha,
@@ -44,6 +47,12 @@ module Gitlab
new_path: new_path,
position_type: position_type
}
+
+ if Feature.enabled?(:file_identifier_hash)
+ out[:file_identifier_hash] = file_identifier_hash
+ end
+
+ out
end
def position_type
diff --git a/lib/gitlab/diff/position.rb b/lib/gitlab/diff/position.rb
index 10ad23b7774..e43f301c280 100644
--- a/lib/gitlab/diff/position.rb
+++ b/lib/gitlab/diff/position.rb
@@ -9,6 +9,7 @@ module Gitlab
delegate :old_path,
:new_path,
+ :file_identifier_hash,
:base_sha,
:start_sha,
:head_sha,
@@ -156,13 +157,23 @@ module Gitlab
position_type == 'text'
end
+ def find_diff_file_from(diffable)
+ diff_files = diffable.diffs(diff_options).diff_files
+
+ if Feature.enabled?(:file_identifier_hash) && file_identifier_hash.present?
+ diff_files.find { |df| df.file_identifier_hash == file_identifier_hash }
+ else
+ diff_files.first
+ end
+ end
+
private
def find_diff_file(repository)
return unless diff_refs.complete?
return unless comparison = diff_refs.compare_in(repository.project)
- comparison.diffs(diff_options).diff_files.first
+ find_diff_file_from(comparison)
end
def get_formatter_class(type)
diff --git a/lib/gitlab/doctor/secrets.rb b/lib/gitlab/doctor/secrets.rb
new file mode 100644
index 00000000000..31c5dded3ff
--- /dev/null
+++ b/lib/gitlab/doctor/secrets.rb
@@ -0,0 +1,87 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Doctor
+ class Secrets
+ attr_reader :logger
+
+ def initialize(logger)
+ @logger = logger
+ end
+
+ def run!
+ logger.info "Checking encrypted values in the database"
+ Rails.application.eager_load! unless Rails.application.config.eager_load
+
+ models_with_attributes = Hash.new { |h, k| h[k] = [] }
+
+ models_with_encrypted_attributes.each do |model|
+ models_with_attributes[model] += model.encrypted_attributes.keys
+ end
+
+ models_with_encrypted_tokens.each do |model|
+ models_with_attributes[model] += model.encrypted_token_authenticatable_fields
+ end
+
+ check_model_attributes(models_with_attributes)
+
+ logger.info "Done!"
+ end
+
+ private
+
+ def check_model_attributes(models_with_attributes)
+ running_failures = 0
+
+ models_with_attributes.each do |model, attributes|
+ failures_per_row = Hash.new { |h, k| h[k] = [] }
+ model.find_each do |data|
+ attributes.each do |att|
+ failures_per_row[data.id] << att unless valid_attribute?(data, att)
+ end
+ end
+
+ running_failures += failures_per_row.keys.count
+ output_failures_for_model(model, failures_per_row)
+ end
+
+ logger.info "Total: #{running_failures} row(s) affected".color(:blue)
+ end
+
+ def output_failures_for_model(model, failures)
+ status_color = failures.empty? ? :green : :red
+
+ logger.info "- #{model} failures: #{failures.count}".color(status_color)
+ failures.each do |row_id, attributes|
+ logger.debug " - #{model}[#{row_id}]: #{attributes.join(", ")}".color(:red)
+ end
+ end
+
+ def models_with_encrypted_attributes
+ all_models.select { |d| d.encrypted_attributes.present? }
+ end
+
+ def models_with_encrypted_tokens
+ all_models.select do |d|
+ d.include?(TokenAuthenticatable) && d.encrypted_token_authenticatable_fields.present?
+ end
+ end
+
+ def all_models
+ @all_models ||= ApplicationRecord.descendants
+ end
+
+ def valid_attribute?(data, attr)
+ data.public_send(attr) # rubocop:disable GitlabSecurity/PublicSend
+
+ true
+ rescue OpenSSL::Cipher::CipherError, TypeError
+ false
+ rescue => e
+ logger.debug "> Something went wrong for #{data.class.name}[#{data.id}].#{attr}: #{e}".color(:red)
+
+ false
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/error_tracking.rb b/lib/gitlab/error_tracking.rb
index b893d625f8d..a19ce22e53f 100644
--- a/lib/gitlab/error_tracking.rb
+++ b/lib/gitlab/error_tracking.rb
@@ -26,10 +26,13 @@ module Gitlab
# Sanitize fields based on those sanitized from Rails.
config.sanitize_fields = Rails.application.config.filter_parameters.map(&:to_s)
+ config.processors << ::Gitlab::ErrorTracking::Processor::SidekiqProcessor
# Sanitize authentication headers
config.sanitize_http_headers = %w[Authorization Private-Token]
config.tags = { program: Gitlab.process_name }
config.before_send = method(:before_send)
+
+ yield config if block_given?
end
end
diff --git a/lib/gitlab/error_tracking/processor/sidekiq_processor.rb b/lib/gitlab/error_tracking/processor/sidekiq_processor.rb
new file mode 100644
index 00000000000..272cb689ad5
--- /dev/null
+++ b/lib/gitlab/error_tracking/processor/sidekiq_processor.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require 'set'
+
+module Gitlab
+ module ErrorTracking
+ module Processor
+ class SidekiqProcessor < ::Raven::Processor
+ FILTERED_STRING = '[FILTERED]'
+
+ def self.filter_arguments(args, klass)
+ args.lazy.with_index.map do |arg, i|
+ case arg
+ when Numeric
+ arg
+ else
+ if permitted_arguments_for_worker(klass).include?(i)
+ arg
+ else
+ FILTERED_STRING
+ end
+ end
+ end
+ end
+
+ def self.permitted_arguments_for_worker(klass)
+ @permitted_arguments_for_worker ||= {}
+ @permitted_arguments_for_worker[klass] ||=
+ begin
+ klass.constantize&.loggable_arguments&.to_set
+ rescue
+ Set.new
+ end
+ end
+
+ def self.loggable_arguments(args, klass)
+ Gitlab::Utils::LogLimitedArray
+ .log_limited_array(filter_arguments(args, klass))
+ .map(&:to_s)
+ .to_a
+ end
+
+ def process(value, key = nil)
+ sidekiq = value.dig(:extra, :sidekiq)
+
+ return value unless sidekiq
+
+ sidekiq = sidekiq.deep_dup
+ sidekiq.delete(:jobstr)
+
+ # 'args' in this hash => from Gitlab::ErrorTracking.track_*
+ # 'args' in :job => from default error handler
+ job_holder = sidekiq.key?('args') ? sidekiq : sidekiq[:job]
+
+ if job_holder['args']
+ job_holder['args'] = self.class.filter_arguments(job_holder['args'], job_holder['class']).to_a
+ end
+
+ value[:extra][:sidekiq] = sidekiq
+
+ value
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/exception_log_formatter.rb b/lib/gitlab/exception_log_formatter.rb
index 92d55213cc2..2da1b8915e4 100644
--- a/lib/gitlab/exception_log_formatter.rb
+++ b/lib/gitlab/exception_log_formatter.rb
@@ -12,6 +12,16 @@ module Gitlab
'exception.message' => exception.message
)
+ payload.delete('extra.server')
+
+ payload['extra.sidekiq'].tap do |value|
+ if value.is_a?(Hash) && value.key?('args')
+ value = value.dup
+ payload['extra.sidekiq']['args'] = Gitlab::ErrorTracking::Processor::SidekiqProcessor
+ .loggable_arguments(value['args'], value['class'])
+ end
+ end
+
if exception.backtrace
payload['exception.backtrace'] = Gitlab::BacktraceCleaner.clean_backtrace(exception.backtrace)
end
diff --git a/lib/gitlab/experimentation.rb b/lib/gitlab/experimentation.rb
index 3495b4a0b72..d3df9be0d63 100644
--- a/lib/gitlab/experimentation.rb
+++ b/lib/gitlab/experimentation.rb
@@ -13,18 +13,20 @@
# To enable the experiment for 10% of the users:
#
# chatops: `/chatops run feature set experiment_key_experiment_percentage 10`
-# console: `Feature.get(:experiment_key_experiment_percentage).enable_percentage_of_time(10)`
+# console: `Feature.enable_percentage_of_time(:experiment_key_experiment_percentage, 10)`
#
# To disable the experiment:
#
# chatops: `/chatops run feature delete experiment_key_experiment_percentage`
-# console: `Feature.get(:experiment_key_experiment_percentage).remove`
+# console: `Feature.remove(:experiment_key_experiment_percentage)`
#
# To check the current rollout percentage:
#
# chatops: `/chatops run feature get experiment_key_experiment_percentage`
# console: `Feature.get(:experiment_key_experiment_percentage).percentage_of_time_value`
#
+
+# TODO: see https://gitlab.com/gitlab-org/gitlab/-/issues/217490
module Gitlab
module Experimentation
EXPERIMENTS = {
@@ -45,6 +47,12 @@ module Gitlab
},
upgrade_link_in_user_menu_a: {
tracking_category: 'Growth::Expansion::Experiment::UpgradeLinkInUserMenuA'
+ },
+ invite_members_version_a: {
+ tracking_category: 'Growth::Expansion::Experiment::InviteMembersVersionA'
+ },
+ new_create_project_ui: {
+ tracking_category: 'Manage::Import::Experiment::NewCreateProjectUi'
}
}.freeze
@@ -66,7 +74,6 @@ module Gitlab
cookies.permanent.signed[:experimentation_subject_id] = {
value: SecureRandom.uuid,
- domain: :all,
secure: ::Gitlab.config.gitlab.https,
httponly: true
}
@@ -179,7 +186,7 @@ module Gitlab
# When a feature does not exist, the `percentage_of_time_value` method will return 0
def experiment_percentage
- @experiment_percentage ||= Feature.get(:"#{key}_experiment_percentage").percentage_of_time_value
+ @experiment_percentage ||= Feature.get(:"#{key}_experiment_percentage").percentage_of_time_value # rubocop:disable Gitlab/AvoidFeatureGet
end
end
end
diff --git a/lib/gitlab/export/logger.rb b/lib/gitlab/export/logger.rb
new file mode 100644
index 00000000000..b3c05651cd4
--- /dev/null
+++ b/lib/gitlab/export/logger.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Export
+ class Logger < ::Gitlab::JsonLogger
+ def self.file_name_noext
+ 'exporter'
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/file_detector.rb b/lib/gitlab/file_detector.rb
index a9e9261cd3c..13959f6aa68 100644
--- a/lib/gitlab/file_detector.rb
+++ b/lib/gitlab/file_detector.rb
@@ -32,6 +32,8 @@ module Gitlab
gemfile_lock: 'Gemfile.lock',
gemspec: %r{\A[^/]*\.gemspec\z},
godeps_json: 'Godeps.json',
+ go_mod: 'go.mod',
+ go_sum: 'go.sum',
package_json: 'package.json',
podfile: 'Podfile',
podspec_json: %r{\A[^/]*\.podspec\.json\z},
diff --git a/lib/gitlab/gfm/uploads_rewriter.rb b/lib/gitlab/gfm/uploads_rewriter.rb
index 23af0a9bb18..08321d5fda6 100644
--- a/lib/gitlab/gfm/uploads_rewriter.rb
+++ b/lib/gitlab/gfm/uploads_rewriter.rb
@@ -22,9 +22,10 @@ module Gitlab
return @text unless needs_rewrite?
@text.gsub(@pattern) do |markdown|
- Gitlab::Utils.check_path_traversal!($~[:file])
+ file = find_file($~[:secret], $~[:file])
+ # No file will be returned for a path traversal
+ next if file.nil?
- file = find_file(@source_project, $~[:secret], $~[:file])
break markdown unless file.try(:exists?)
klass = target_parent.is_a?(Namespace) ? NamespaceFileUploader : FileUploader
@@ -47,7 +48,7 @@ module Gitlab
def files
referenced_files = @text.scan(@pattern).map do
- find_file(@source_project, $~[:secret], $~[:file])
+ find_file($~[:secret], $~[:file])
end
referenced_files.compact.select(&:exists?)
@@ -57,12 +58,8 @@ module Gitlab
markdown.starts_with?("!")
end
- private
-
- def find_file(project, secret, file)
- uploader = FileUploader.new(project, secret: secret)
- uploader.retrieve_from_store!(file)
- uploader
+ def find_file(secret, file_name)
+ UploaderFinder.new(@source_project, secret, file_name).execute
end
end
end
diff --git a/lib/gitlab/git/commit.rb b/lib/gitlab/git/commit.rb
index a554dc0b667..17d0a62ba8c 100644
--- a/lib/gitlab/git/commit.rb
+++ b/lib/gitlab/git/commit.rb
@@ -7,6 +7,7 @@ module Gitlab
include Gitlab::EncodingHelper
prepend Gitlab::Git::RuggedImpl::Commit
extend Gitlab::Git::WrapsGitalyErrors
+ include Gitlab::Utils::StrongMemoize
attr_accessor :raw_commit, :head
@@ -231,6 +232,18 @@ module Gitlab
parent_ids.first
end
+ def committed_date
+ strong_memoize(:committed_date) do
+ init_date_from_gitaly(raw_commit.committer) if raw_commit
+ end
+ end
+
+ def authored_date
+ strong_memoize(:authored_date) do
+ init_date_from_gitaly(raw_commit.author) if raw_commit
+ end
+ end
+
# Returns a diff object for the changes from this commit's first parent.
# If there is no parent, then the diff is between this commit and an
# empty repo. See Repository#diff for keys allowed in the +options+
@@ -369,11 +382,9 @@ module Gitlab
# subject from the message to make it clearer when there's one
# available but not the other.
@message = message_from_gitaly_body
- @authored_date = init_date_from_gitaly(commit.author)
@author_name = commit.author.name.dup
@author_email = commit.author.email.dup
- @committed_date = init_date_from_gitaly(commit.committer)
@committer_name = commit.committer.name.dup
@committer_email = commit.committer.email.dup
@parent_ids = Array(commit.parent_ids)
diff --git a/lib/gitlab/git/diff.rb b/lib/gitlab/git/diff.rb
index 74a4633424f..bb845f11181 100644
--- a/lib/gitlab/git/diff.rb
+++ b/lib/gitlab/git/diff.rb
@@ -225,7 +225,7 @@ module Gitlab
end
def init_from_gitaly(diff)
- @diff = encode!(diff.patch) if diff.respond_to?(:patch)
+ @diff = diff.respond_to?(:patch) ? encode!(diff.patch) : ''
@new_path = encode!(diff.to_path.dup)
@old_path = encode!(diff.from_path.dup)
@a_mode = diff.old_mode.to_s(8)
diff --git a/lib/gitlab/git/rugged_impl/use_rugged.rb b/lib/gitlab/git/rugged_impl/use_rugged.rb
index f9573bedba7..dae208e6955 100644
--- a/lib/gitlab/git/rugged_impl/use_rugged.rb
+++ b/lib/gitlab/git/rugged_impl/use_rugged.rb
@@ -5,8 +5,7 @@ module Gitlab
module RuggedImpl
module UseRugged
def use_rugged?(repo, feature_key)
- feature = Feature.get(feature_key)
- return feature.enabled? if Feature.persisted?(feature)
+ return Feature.enabled?(feature_key) if Feature.persisted_name?(feature_key)
# Disable Rugged auto-detect(can_use_disk?) when Puma threads>1
# https://gitlab.com/gitlab-org/gitlab/issues/119326
@@ -25,7 +24,7 @@ module Gitlab
if Gitlab::RuggedInstrumentation.active?
Gitlab::RuggedInstrumentation.increment_query_count
- Gitlab::RuggedInstrumentation.query_time += duration
+ Gitlab::RuggedInstrumentation.add_query_time(duration)
Gitlab::RuggedInstrumentation.add_call_details(
feature: method_name,
diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb
index f1ca8900c30..37e3da984d6 100644
--- a/lib/gitlab/git_access.rb
+++ b/lib/gitlab/git_access.rb
@@ -8,7 +8,6 @@ module Gitlab
ForbiddenError = Class.new(StandardError)
NotFoundError = Class.new(StandardError)
- ProjectCreationError = Class.new(StandardError)
TimeoutError = Class.new(StandardError)
ProjectMovedError = Class.new(NotFoundError)
@@ -24,6 +23,7 @@ module Gitlab
deploy_key_upload: 'This deploy key does not have write access to this project.',
no_repo: 'A repository for this project does not exist yet.',
project_not_found: 'The project you were looking for could not be found.',
+ namespace_not_found: 'The namespace you were looking for could not be found.',
command_not_allowed: "The command you're trying to execute is not allowed.",
upload_pack_disabled_over_http: 'Pulling over HTTP is not allowed.',
receive_pack_disabled_over_http: 'Pushing over HTTP is not allowed.',
@@ -73,7 +73,8 @@ module Gitlab
return custom_action if custom_action
check_db_accessibility!(cmd)
- check_project!(changes, cmd)
+ check_namespace!
+ check_project!(cmd)
check_repository_existence!
case cmd
@@ -110,9 +111,7 @@ module Gitlab
private
- def check_project!(changes, cmd)
- check_namespace!
- ensure_project_on_push!(cmd, changes)
+ def check_project!(_cmd)
check_project_accessibility!
add_project_moved_message!
end
@@ -156,7 +155,7 @@ module Gitlab
def check_namespace!
return if namespace_path.present?
- raise NotFoundError, ERROR_MESSAGES[:project_not_found]
+ raise NotFoundError, ERROR_MESSAGES[:namespace_not_found]
end
def check_active_user!
@@ -229,32 +228,6 @@ module Gitlab
end
end
- def ensure_project_on_push!(cmd, changes)
- return if project || deploy_key?
- return unless receive_pack?(cmd) && changes == ANY && authentication_abilities.include?(:push_code)
-
- namespace = Namespace.find_by_full_path(namespace_path)
-
- return unless user&.can?(:create_projects, namespace)
-
- project_params = {
- path: repository_path,
- namespace_id: namespace.id,
- visibility_level: Gitlab::VisibilityLevel::PRIVATE
- }
-
- project = Projects::CreateService.new(user, project_params).execute
-
- unless project.saved?
- raise ProjectCreationError, "Could not create project: #{project.errors.full_messages.join(', ')}"
- end
-
- @project = project
- user_access.project = @project
-
- Checks::ProjectCreated.new(repository, user, protocol).add_message
- end
-
def check_repository_existence!
unless repository.exists?
raise NotFoundError, ERROR_MESSAGES[:no_repo]
diff --git a/lib/gitlab/git_access_project.rb b/lib/gitlab/git_access_project.rb
new file mode 100644
index 00000000000..c79a61c263e
--- /dev/null
+++ b/lib/gitlab/git_access_project.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+module Gitlab
+ class GitAccessProject < GitAccess
+ extend ::Gitlab::Utils::Override
+
+ CreationError = Class.new(StandardError)
+
+ private
+
+ override :check_project!
+ def check_project!(cmd)
+ ensure_project_on_push!(cmd)
+
+ super
+ end
+
+ def ensure_project_on_push!(cmd)
+ return if project || deploy_key?
+ return unless receive_pack?(cmd) && changes == ANY && authentication_abilities.include?(:push_code)
+
+ namespace = Namespace.find_by_full_path(namespace_path)
+
+ return unless user&.can?(:create_projects, namespace)
+
+ project_params = {
+ path: repository_path,
+ namespace_id: namespace.id,
+ visibility_level: Gitlab::VisibilityLevel::PRIVATE
+ }
+
+ project = Projects::CreateService.new(user, project_params).execute
+
+ unless project.saved?
+ raise CreationError, "Could not create project: #{project.errors.full_messages.join(', ')}"
+ end
+
+ @project = project
+ user_access.project = @project
+
+ Checks::ProjectCreated.new(repository, user, protocol).add_message
+ end
+ end
+end
diff --git a/lib/gitlab/git_access_snippet.rb b/lib/gitlab/git_access_snippet.rb
index 70db4271469..3de6c9ee30a 100644
--- a/lib/gitlab/git_access_snippet.rb
+++ b/lib/gitlab/git_access_snippet.rb
@@ -39,13 +39,18 @@ module Gitlab
private
+ override :check_namespace!
+ def check_namespace!
+ return unless snippet.is_a?(ProjectSnippet)
+
+ super
+ end
+
override :check_project!
- def check_project!(cmd, changes)
+ def check_project!(cmd)
return unless snippet.is_a?(ProjectSnippet)
- check_namespace!
- check_project_accessibility!
- add_project_moved_message!
+ super
end
override :check_push_access!
diff --git a/lib/gitlab/git_access_wiki.rb b/lib/gitlab/git_access_wiki.rb
index 3c0dbba64bf..aad46937c32 100644
--- a/lib/gitlab/git_access_wiki.rb
+++ b/lib/gitlab/git_access_wiki.rb
@@ -2,6 +2,8 @@
module Gitlab
class GitAccessWiki < GitAccess
+ prepend_if_ee('EE::Gitlab::GitAccessWiki') # rubocop: disable Cop/InjectEnterpriseEditionModule
+
ERROR_MESSAGES = {
read_only: "You can't push code to a read-only GitLab instance.",
write_to_wiki: "You are not allowed to write to this project's wiki."
@@ -31,8 +33,10 @@ module Gitlab
ERROR_MESSAGES[:read_only]
end
- def container
- project.wiki
+ private
+
+ def repository
+ project.wiki.repository
end
end
end
diff --git a/lib/gitlab/gitaly_client.rb b/lib/gitlab/gitaly_client.rb
index 3aaed0edb87..bed99ef0ed4 100644
--- a/lib/gitlab/gitaly_client.rb
+++ b/lib/gitlab/gitaly_client.rb
@@ -201,7 +201,8 @@ module Gitlab
request_hash = request.is_a?(Google::Protobuf::MessageExts) ? request.to_h : {}
# Keep track, separately, for the performance bar
- self.query_time += duration
+ self.add_query_time(duration)
+
if Gitlab::PerformanceBar.enabled_for_request?
add_call_details(feature: "#{service}##{rpc}", duration: duration, request: request_hash, rpc: rpc,
backtrace: Gitlab::BacktraceCleaner.clean_backtrace(caller))
@@ -209,12 +210,15 @@ module Gitlab
end
def self.query_time
- query_time = SafeRequestStore[:gitaly_query_time] ||= 0
+ query_time = Gitlab::SafeRequestStore[:gitaly_query_time] || 0
query_time.round(Gitlab::InstrumentationHelper::DURATION_PRECISION)
end
- def self.query_time=(duration)
- SafeRequestStore[:gitaly_query_time] = duration
+ def self.add_query_time(duration)
+ return unless Gitlab::SafeRequestStore.active?
+
+ Gitlab::SafeRequestStore[:gitaly_query_time] ||= 0
+ Gitlab::SafeRequestStore[:gitaly_query_time] += duration
end
def self.current_transaction_labels
diff --git a/lib/gitlab/gitaly_client/commit_service.rb b/lib/gitlab/gitaly_client/commit_service.rb
index 1f914dc95d1..aed132aaca0 100644
--- a/lib/gitlab/gitaly_client/commit_service.rb
+++ b/lib/gitlab/gitaly_client/commit_service.rb
@@ -212,8 +212,9 @@ module Gitlab
right_commit_id: right_commit_sha
)
- response = GitalyClient.call(@repository.storage, :diff_service, :diff_stats, request, timeout: GitalyClient.medium_timeout)
- response.flat_map(&:stats)
+ GitalyClient.streaming_call(@repository.storage, :diff_service, :diff_stats, request, timeout: GitalyClient.medium_timeout) do |response|
+ response.flat_map(&:stats)
+ end
end
def find_all_commits(opts = {})
@@ -246,8 +247,8 @@ module Gitlab
request = Gitaly::CommitsByMessageRequest.new(
repository: @gitaly_repo,
query: query,
- revision: revision.to_s.force_encoding(Encoding::ASCII_8BIT),
- path: path.to_s.force_encoding(Encoding::ASCII_8BIT),
+ revision: encode_binary(revision),
+ path: encode_binary(path),
limit: limit.to_i,
offset: offset.to_i
)
diff --git a/lib/gitlab/github_import/bulk_importing.rb b/lib/gitlab/github_import/bulk_importing.rb
index 147597289cf..0d448b55104 100644
--- a/lib/gitlab/github_import/bulk_importing.rb
+++ b/lib/gitlab/github_import/bulk_importing.rb
@@ -17,7 +17,7 @@ module Gitlab
# Bulk inserts the given rows into the database.
def bulk_insert(model, rows, batch_size: 100)
rows.each_slice(batch_size) do |slice|
- Gitlab::Database.bulk_insert(model.table_name, slice)
+ Gitlab::Database.bulk_insert(model.table_name, slice) # rubocop:disable Gitlab/BulkInsert
end
end
end
diff --git a/lib/gitlab/github_import/importer/diff_note_importer.rb b/lib/gitlab/github_import/importer/diff_note_importer.rb
index d562958e955..53b17f77ccd 100644
--- a/lib/gitlab/github_import/importer/diff_note_importer.rb
+++ b/lib/gitlab/github_import/importer/diff_note_importer.rb
@@ -47,7 +47,7 @@ module Gitlab
# To work around this we're using bulk_insert with a single row. This
# allows us to efficiently insert data (even if it's just 1 row)
# without having to use all sorts of hacks to disable callbacks.
- Gitlab::Database.bulk_insert(LegacyDiffNote.table_name, [attributes])
+ Gitlab::Database.bulk_insert(LegacyDiffNote.table_name, [attributes]) # rubocop:disable Gitlab/BulkInsert
rescue ActiveRecord::InvalidForeignKey
# It's possible the project and the issue have been deleted since
# scheduling this job. In this case we'll just skip creating the note.
diff --git a/lib/gitlab/github_import/importer/issue_importer.rb b/lib/gitlab/github_import/importer/issue_importer.rb
index 8648cbaec9d..13061d2c9df 100644
--- a/lib/gitlab/github_import/importer/issue_importer.rb
+++ b/lib/gitlab/github_import/importer/issue_importer.rb
@@ -75,7 +75,7 @@ module Gitlab
end
end
- Gitlab::Database.bulk_insert(IssueAssignee.table_name, assignees)
+ Gitlab::Database.bulk_insert(IssueAssignee.table_name, assignees) # rubocop:disable Gitlab/BulkInsert
end
end
end
diff --git a/lib/gitlab/github_import/importer/label_links_importer.rb b/lib/gitlab/github_import/importer/label_links_importer.rb
index 2001b7e3482..77eb4542195 100644
--- a/lib/gitlab/github_import/importer/label_links_importer.rb
+++ b/lib/gitlab/github_import/importer/label_links_importer.rb
@@ -40,7 +40,7 @@ module Gitlab
}
end
- Gitlab::Database.bulk_insert(LabelLink.table_name, rows)
+ Gitlab::Database.bulk_insert(LabelLink.table_name, rows) # rubocop:disable Gitlab/BulkInsert
end
def find_target_id
diff --git a/lib/gitlab/github_import/importer/lfs_objects_importer.rb b/lib/gitlab/github_import/importer/lfs_objects_importer.rb
index 30763492235..5980b3c2179 100644
--- a/lib/gitlab/github_import/importer/lfs_objects_importer.rb
+++ b/lib/gitlab/github_import/importer/lfs_objects_importer.rb
@@ -29,7 +29,10 @@ module Gitlab
yield object
end
rescue StandardError => e
- Rails.logger.error("The Lfs import process failed. #{e.message}") # rubocop:disable Gitlab/RailsLogger
+ Gitlab::Import::Logger.error(
+ message: 'The Lfs import process failed',
+ error: e.message
+ )
end
end
end
diff --git a/lib/gitlab/github_import/importer/note_importer.rb b/lib/gitlab/github_import/importer/note_importer.rb
index 2b06d1b3baf..41f179d275b 100644
--- a/lib/gitlab/github_import/importer/note_importer.rb
+++ b/lib/gitlab/github_import/importer/note_importer.rb
@@ -38,7 +38,7 @@ module Gitlab
# We're using bulk_insert here so we can bypass any validations and
# callbacks. Running these would result in a lot of unnecessary SQL
# queries being executed when importing large projects.
- Gitlab::Database.bulk_insert(Note.table_name, [attributes])
+ Gitlab::Database.bulk_insert(Note.table_name, [attributes]) # rubocop:disable Gitlab/BulkInsert
rescue ActiveRecord::InvalidForeignKey
# It's possible the project and the issue have been deleted since
# scheduling this job. In this case we'll just skip creating the note.
diff --git a/lib/gitlab/github_import/importer/pull_requests_importer.rb b/lib/gitlab/github_import/importer/pull_requests_importer.rb
index 929fceaacf2..dcae8ca01fa 100644
--- a/lib/gitlab/github_import/importer/pull_requests_importer.rb
+++ b/lib/gitlab/github_import/importer/pull_requests_importer.rb
@@ -40,8 +40,10 @@ module Gitlab
pname = project.path_with_namespace
- Rails.logger # rubocop:disable Gitlab/RailsLogger
- .info("GitHub importer finished updating repository for #{pname}")
+ Gitlab::Import::Logger.info(
+ message: 'GitHub importer finished updating repository',
+ project_name: pname
+ )
repository_updates_counter.increment
end
diff --git a/lib/gitlab/gl_repository.rb b/lib/gitlab/gl_repository.rb
index 8abefad1ef3..abd4e847a50 100644
--- a/lib/gitlab/gl_repository.rb
+++ b/lib/gitlab/gl_repository.rb
@@ -6,20 +6,21 @@ module Gitlab
PROJECT = RepoType.new(
name: :project,
- access_checker_class: Gitlab::GitAccess,
+ access_checker_class: Gitlab::GitAccessProject,
repository_resolver: -> (project) { project&.repository }
).freeze
WIKI = RepoType.new(
name: :wiki,
access_checker_class: Gitlab::GitAccessWiki,
- repository_resolver: -> (project) { project&.wiki&.repository },
+ repository_resolver: -> (container) { container&.wiki&.repository },
+ project_resolver: -> (container) { container.is_a?(Project) ? container : nil },
suffix: :wiki
).freeze
SNIPPET = RepoType.new(
name: :snippet,
access_checker_class: Gitlab::GitAccessSnippet,
repository_resolver: -> (snippet) { snippet&.repository },
- container_resolver: -> (id) { Snippet.find_by_id(id) },
+ container_class: Snippet,
project_resolver: -> (snippet) { snippet&.project },
guest_read_ability: :read_snippet
).freeze
@@ -42,16 +43,12 @@ module Gitlab
end
def self.parse(gl_repository)
- type_name, _id = gl_repository.split('-').first
- type = types[type_name]
+ result = ::Gitlab::GlRepository::Identifier.new(gl_repository)
- unless type
- raise ArgumentError, "Invalid GL Repository \"#{gl_repository}\""
- end
+ repo_type = result.repo_type
+ container = result.fetch_container!
- container = type.fetch_container!(gl_repository)
-
- [container, type.project_for(container), type]
+ [container, repo_type.project_for(container), repo_type]
end
def self.default_type
diff --git a/lib/gitlab/gl_repository/identifier.rb b/lib/gitlab/gl_repository/identifier.rb
new file mode 100644
index 00000000000..dc3e7931696
--- /dev/null
+++ b/lib/gitlab/gl_repository/identifier.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+module Gitlab
+ class GlRepository
+ class Identifier
+ attr_reader :gl_repository, :repo_type
+
+ def initialize(gl_repository)
+ @gl_repository = gl_repository
+ @segments = gl_repository.split('-')
+
+ raise_error if segments.size > 3
+
+ @repo_type = find_repo_type
+ @container_id = find_container_id
+ @container_class = find_container_class
+ end
+
+ def fetch_container!
+ container_class.find_by_id(container_id)
+ end
+
+ private
+
+ attr_reader :segments, :container_class, :container_id
+
+ def find_repo_type
+ type_name = three_segments_format? ? segments.last : segments.first
+ type = Gitlab::GlRepository.types[type_name]
+
+ raise_error unless type
+
+ type
+ end
+
+ def find_container_class
+ if three_segments_format?
+ case segments[0]
+ when 'project'
+ Project
+ when 'group'
+ Group
+ else
+ raise_error
+ end
+ else
+ repo_type.container_class
+ end
+ end
+
+ def find_container_id
+ id = Integer(segments[1], 10, exception: false)
+
+ raise_error unless id
+
+ id
+ end
+
+ # gl_repository can either have 2 or 3 segments:
+ # "wiki-1" is the older 2-segment format, where container is implied.
+ # "group-1-wiki" is the newer 3-segment format, including container information.
+ #
+ # TODO: convert all 2-segment format to 3-segment:
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/219192
+ def three_segments_format?
+ segments.size == 3
+ end
+
+ def raise_error
+ raise ArgumentError, "Invalid GL Repository \"#{gl_repository}\""
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/gl_repository/repo_type.rb b/lib/gitlab/gl_repository/repo_type.rb
index 64c329b15ae..2b482ee3d2d 100644
--- a/lib/gitlab/gl_repository/repo_type.rb
+++ b/lib/gitlab/gl_repository/repo_type.rb
@@ -6,7 +6,7 @@ module Gitlab
attr_reader :name,
:access_checker_class,
:repository_resolver,
- :container_resolver,
+ :container_class,
:project_resolver,
:guest_read_ability,
:suffix
@@ -15,34 +15,25 @@ module Gitlab
name:,
access_checker_class:,
repository_resolver:,
- container_resolver: default_container_resolver,
+ container_class: default_container_class,
project_resolver: nil,
guest_read_ability: :download_code,
suffix: nil)
@name = name
@access_checker_class = access_checker_class
@repository_resolver = repository_resolver
- @container_resolver = container_resolver
+ @container_class = container_class
@project_resolver = project_resolver
@guest_read_ability = guest_read_ability
@suffix = suffix
end
def identifier_for_container(container)
- "#{name}-#{container.id}"
- end
-
- def fetch_id(identifier)
- match = /\A#{name}-(?<id>\d+)\z/.match(identifier)
- match[:id] if match
- end
+ if container.is_a?(Group)
+ return "#{container.class.name.underscore}-#{container.id}-#{name}"
+ end
- def fetch_container!(identifier)
- id = fetch_id(identifier)
-
- raise ArgumentError, "Invalid GL Repository \"#{identifier}\"" unless id
-
- container_resolver.call(id)
+ "#{name}-#{container.id}"
end
def wiki?
@@ -85,8 +76,8 @@ module Gitlab
private
- def default_container_resolver
- -> (id) { Project.find_by_id(id) }
+ def default_container_class
+ Project
end
end
end
diff --git a/lib/gitlab/golang.rb b/lib/gitlab/golang.rb
new file mode 100644
index 00000000000..f2dc668c482
--- /dev/null
+++ b/lib/gitlab/golang.rb
@@ -0,0 +1,99 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Golang
+ extend self
+
+ def local_module_prefix
+ @gitlab_prefix ||= "#{Settings.build_gitlab_go_url}/".freeze
+ end
+
+ def semver_tag?(tag)
+ return false if tag.dereferenced_target.nil?
+
+ Packages::SemVer.match?(tag.name, prefixed: true)
+ end
+
+ def pseudo_version?(version)
+ return false unless version
+
+ if version.is_a? String
+ version = parse_semver version
+ return false unless version
+ end
+
+ pre = version.prerelease
+
+ # Valid pseudo-versions are:
+ # vX.0.0-yyyymmddhhmmss-sha1337beef0, when no earlier tagged commit exists for X
+ # vX.Y.Z-pre.0.yyyymmddhhmmss-sha1337beef0, when most recent prior tag is vX.Y.Z-pre
+ # vX.Y.(Z+1)-0.yyyymmddhhmmss-sha1337beef0, when most recent prior tag is vX.Y.Z
+
+ if version.minor != 0 || version.patch != 0
+ m = /\A(.*\.)?0\./.freeze.match pre
+ return false unless m
+
+ pre = pre[m[0].length..]
+ end
+
+ # This pattern is intentionally more forgiving than the patterns
+ # above. Correctness is verified by #pseudo_version_commit.
+ /\A\d{14}-\h+\z/.freeze.match? pre
+ end
+
+ def pseudo_version_commit(project, semver)
+ # Per Go's implementation of pseudo-versions, a tag should be
+ # considered a pseudo-version if it matches one of the patterns
+ # listed in #pseudo_version?, regardless of the content of the
+ # timestamp or the length of the SHA fragment. However, an error
+ # should be returned if the timestamp is not correct or if the SHA
+ # fragment is not exactly 12 characters long. See also Go's
+ # implementation of:
+ #
+ # - [*codeRepo.validatePseudoVersion](https://github.com/golang/go/blob/daf70d6c1688a1ba1699c933b3c3f04d6f2f73d9/src/cmd/go/internal/modfetch/coderepo.go#L530)
+ # - [Pseudo-version parsing](https://github.com/golang/go/blob/master/src/cmd/go/internal/modfetch/pseudo.go)
+ # - [Pseudo-version request processing](https://github.com/golang/go/blob/master/src/cmd/go/internal/modfetch/coderepo.go)
+
+ # Go ignores anything before '.' or after the second '-', so we will do the same
+ timestamp, sha = semver.prerelease.split('-').last 2
+ timestamp = timestamp.split('.').last
+ commit = project.repository.commit_by(oid: sha)
+
+ # Error messages are based on the responses of proxy.golang.org
+
+ # Verify that the SHA fragment references a commit
+ raise ArgumentError.new 'invalid pseudo-version: unknown commit' unless commit
+
+ # Require the SHA fragment to be 12 characters long
+ raise ArgumentError.new 'invalid pseudo-version: revision is shorter than canonical' unless sha.length == 12
+
+ # Require the timestamp to match that of the commit
+ raise ArgumentError.new 'invalid pseudo-version: does not match version-control timestamp' unless commit.committed_date.strftime('%Y%m%d%H%M%S') == timestamp
+
+ commit
+ end
+
+ def parse_semver(str)
+ Packages::SemVer.parse(str, prefixed: true)
+ end
+
+ def pkg_go_dev_url(name, version = nil)
+ if version
+ "https://pkg.go.dev/#{name}@#{version}"
+ else
+ "https://pkg.go.dev/#{name}"
+ end
+ end
+
+ def package_url(name, version = nil)
+ return unless UrlSanitizer.valid?("https://#{name}")
+
+ return pkg_go_dev_url(name, version) unless name.starts_with?(local_module_prefix)
+
+ # This will not work if `name` refers to a subdirectory of a project. This
+ # could be expanded with logic similar to Gitlab::Middleware::Go to locate
+ # the project, check for permissions, and return a smarter result.
+ "#{Gitlab.config.gitlab.protocol}://#{name}/"
+ end
+ end
+end
diff --git a/lib/gitlab/graphql/authorize/authorize_field_service.rb b/lib/gitlab/graphql/authorize/authorize_field_service.rb
index 61668b634fd..cbf3e7b8429 100644
--- a/lib/gitlab/graphql/authorize/authorize_field_service.rb
+++ b/lib/gitlab/graphql/authorize/authorize_field_service.rb
@@ -84,13 +84,25 @@ module Gitlab
elsif resolved_type.is_a? Array
# A simple list of rendered types each object being an object to authorize
resolved_type.select do |single_object_type|
- allowed_access?(current_user, single_object_type.object)
+ allowed_access?(current_user, realized(single_object_type).object)
end
else
raise "Can't authorize #{@field}"
end
end
+ # Ensure that we are dealing with realized objects, not delayed promises
+ def realized(thing)
+ case thing
+ when BatchLoader::GraphQL
+ thing.sync
+ when GraphQL::Execution::Lazy
+ thing.value # part of the private api, but we need to unwrap it here.
+ else
+ thing
+ end
+ end
+
def allowed_access?(current_user, object)
object = object.sync if object.respond_to?(:sync)
diff --git a/lib/gitlab/graphql/authorize/instrumentation.rb b/lib/gitlab/graphql/authorize/instrumentation.rb
index f9ff2b30eae..15ecc3b04f0 100644
--- a/lib/gitlab/graphql/authorize/instrumentation.rb
+++ b/lib/gitlab/graphql/authorize/instrumentation.rb
@@ -9,16 +9,12 @@ module Gitlab
def instrument(_type, field)
service = AuthorizeFieldService.new(field)
- if service.authorizations? && !resolver_skips_authorizations?(field)
+ if service.authorizations?
field.redefine { resolve(service.authorized_resolve) }
else
field
end
end
-
- def resolver_skips_authorizations?(field)
- field.metadata[:resolver].try(:skip_authorizations?)
- end
end
end
end
diff --git a/lib/gitlab/graphql/filterable_array.rb b/lib/gitlab/graphql/filterable_array.rb
deleted file mode 100644
index 4909d291fd6..00000000000
--- a/lib/gitlab/graphql/filterable_array.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Graphql
- class FilterableArray < Array
- attr_reader :filter_callback
-
- def initialize(filter_callback, *args)
- super(args)
- @filter_callback = filter_callback
- end
- end
- end
-end
diff --git a/lib/gitlab/graphql/loaders/full_path_model_loader.rb b/lib/gitlab/graphql/loaders/full_path_model_loader.rb
new file mode 100644
index 00000000000..0aa237c78de
--- /dev/null
+++ b/lib/gitlab/graphql/loaders/full_path_model_loader.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Graphql
+ module Loaders
+ # Suitable for use to find resources that expose `where_full_path_in`,
+ # such as Project, Group, Namespace
+ class FullPathModelLoader
+ attr_reader :model_class, :full_path
+
+ def initialize(model_class, full_path)
+ @model_class, @full_path = model_class, full_path
+ 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)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/graphql/pagination/connections.rb b/lib/gitlab/graphql/pagination/connections.rb
index febdc938317..8f37fa3f474 100644
--- a/lib/gitlab/graphql/pagination/connections.rb
+++ b/lib/gitlab/graphql/pagination/connections.rb
@@ -10,10 +10,6 @@ module Gitlab
Gitlab::Graphql::Pagination::Keyset::Connection)
schema.connections.add(
- Gitlab::Graphql::FilterableArray,
- Gitlab::Graphql::Pagination::FilterableArrayConnection)
-
- schema.connections.add(
Gitlab::Graphql::ExternallyPaginatedArray,
Gitlab::Graphql::Pagination::ExternallyPaginatedArrayConnection)
end
diff --git a/lib/gitlab/graphql/pagination/filterable_array_connection.rb b/lib/gitlab/graphql/pagination/filterable_array_connection.rb
deleted file mode 100644
index 4a76cd5fb00..00000000000
--- a/lib/gitlab/graphql/pagination/filterable_array_connection.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Graphql
- module Pagination
- # FilterableArrayConnection is useful especially for lazy-loaded values.
- # It allows us to call a callback only on the slice of array being
- # rendered in the "after loaded" phase. For example we can check
- # permissions only on a small subset of items.
- class FilterableArrayConnection < GraphQL::Pagination::ArrayConnection
- def nodes
- @nodes ||= items.filter_callback.call(super)
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/graphql/pagination/keyset/connection.rb b/lib/gitlab/graphql/pagination/keyset/connection.rb
index 1a32ab468b1..17cd22d38ad 100644
--- a/lib/gitlab/graphql/pagination/keyset/connection.rb
+++ b/lib/gitlab/graphql/pagination/keyset/connection.rb
@@ -32,6 +32,49 @@ module Gitlab
class Connection < GraphQL::Pagination::ActiveRecordRelationConnection
include Gitlab::Utils::StrongMemoize
+ # rubocop: disable Naming/PredicateName
+ # https://relay.dev/graphql/connections.htm#sec-undefined.PageInfo.Fields
+ def has_previous_page
+ strong_memoize(:has_previous_page) do
+ if after
+ # If `after` is specified, that points to a specific record,
+ # even if it's the first one. Since we're asking for `after`,
+ # then the specific record we're pointing to is in the
+ # previous page
+ true
+ elsif last
+ limited_nodes
+ !!@has_previous_page
+ else
+ # Key thing to remember. When `before` is specified (and no `last`),
+ # the spec says return _all_ edges minus anything after the `before`.
+ # Which means the returned list starts at the very first record.
+ # Then the max_page kicks in, and returns the first max_page items.
+ # Because of this, `has_previous_page` will be false
+ false
+ end
+ end
+ end
+
+ def has_next_page
+ strong_memoize(:has_next_page) do
+ if before
+ # If `before` is specified, that points to a specific record,
+ # even if it's the last one. Since we're asking for `before`,
+ # then the specific record we're pointing to is in the
+ # next page
+ true
+ elsif first
+ # If we count the number of requested items plus one (`limit_value + 1`),
+ # then if we get `limit_value + 1` then we know there is a next page
+ relation_count(set_limit(sliced_nodes, limit_value + 1)) == limit_value + 1
+ else
+ false
+ end
+ end
+ end
+ # rubocop: enable Naming/PredicateName
+
def cursor_for(node)
encoded_json_from_ordering(node)
end
@@ -39,7 +82,7 @@ module Gitlab
def sliced_nodes
@sliced_nodes ||=
begin
- OrderInfo.validate_ordering(ordered_items, order_list)
+ OrderInfo.validate_ordering(ordered_items, order_list) unless loaded?(ordered_items)
sliced = ordered_items
sliced = slice_nodes(sliced, before, :before) if before.present?
@@ -54,20 +97,30 @@ module Gitlab
# So we're ok loading them into memory here as that's bound to happen
# anyway. Having them ready means we can modify the result while
# rendering the fields.
- @nodes ||= load_paged_nodes.to_a
+ @nodes ||= limited_nodes.to_a
end
private
- def load_paged_nodes
- if first && last
- raise Gitlab::Graphql::Errors::ArgumentError.new("Can only provide either `first` or `last`, not both")
- end
+ # Apply `first` and `last` to `sliced_nodes`
+ def limited_nodes
+ strong_memoize(:limited_nodes) do
+ if first && last
+ raise Gitlab::Graphql::Errors::ArgumentError.new("Can only provide either `first` or `last`, not both")
+ end
- if last
- sliced_nodes.last(limit_value)
- else
- sliced_nodes.limit(limit_value) # rubocop: disable CodeReuse/ActiveRecord
+ if last
+ # grab one more than we need
+ paginated_nodes = sliced_nodes.last(limit_value + 1)
+
+ # there is an extra node, so there is a previous page
+ @has_previous_page = paginated_nodes.count > limit_value
+ @has_previous_page ? paginated_nodes.last(limit_value) : paginated_nodes
+ elsif loaded?(sliced_nodes)
+ sliced_nodes.take(limit_value) # rubocop: disable CodeReuse/ActiveRecord
+ else
+ sliced_nodes.limit(limit_value) # rubocop: disable CodeReuse/ActiveRecord
+ end
end
end
@@ -82,9 +135,19 @@ module Gitlab
# rubocop: enable CodeReuse/ActiveRecord
def limit_value
+ # note: only first _or_ last can be specified, not both
@limit_value ||= [first, last, max_page_size].compact.min
end
+ def loaded?(items)
+ case items
+ when Array
+ true
+ else
+ items.loaded?
+ end
+ end
+
def ordered_items
strong_memoize(:ordered_items) do
unless items.primary_key.present?
@@ -93,6 +156,16 @@ module Gitlab
list = OrderInfo.build_order_list(items)
+ if loaded?(items)
+ @order_list = list.presence || [items.primary_key]
+
+ # already sorted, or trivially sorted
+ next items if list.present? || items.size <= 1
+
+ pkey = items.primary_key.to_sym
+ next items.sort_by { |item| item[pkey] }.reverse
+ end
+
# ensure there is a primary key ordering
if list&.last&.attribute_name != items.primary_key
items.order(arel_table[items.primary_key].desc) # rubocop: disable CodeReuse/ActiveRecord
@@ -121,7 +194,12 @@ module Gitlab
order_list.each do |field|
field_name = field.attribute_name
- ordering[field_name] = node[field_name].to_s
+ field_value = node[field_name]
+ ordering[field_name] = if field_value.is_a?(Time)
+ field_value.strftime('%Y-%m-%d %H:%M:%S.%N %Z')
+ else
+ field_value.to_s
+ end
end
encode(ordering.to_json)
diff --git a/lib/gitlab/import/database_helpers.rb b/lib/gitlab/import/database_helpers.rb
index aaade39dd62..f8ea7a7adcd 100644
--- a/lib/gitlab/import/database_helpers.rb
+++ b/lib/gitlab/import/database_helpers.rb
@@ -11,7 +11,7 @@ module Gitlab
# We use bulk_insert here so we can bypass any queries executed by
# callbacks or validation rules, as doing this wouldn't scale when
# importing very large projects.
- result = Gitlab::Database
+ result = Gitlab::Database # rubocop:disable Gitlab/BulkInsert
.bulk_insert(relation.table_name, [attributes], return_ids: true)
result.first
diff --git a/lib/gitlab/import/set_async_jid.rb b/lib/gitlab/import/set_async_jid.rb
index 3b11c92fb56..527d84477fe 100644
--- a/lib/gitlab/import/set_async_jid.rb
+++ b/lib/gitlab/import/set_async_jid.rb
@@ -2,8 +2,8 @@
# The original import JID is the JID of the RepositoryImportWorker job,
# which will be removed once that job completes. Reusing that JID could
-# result in StuckImportJobsWorker marking the job as stuck before we get
-# to running Stage::ImportRepositoryWorker.
+# result in Gitlab::Import::StuckProjectImportJobsWorker marking the job
+# as stuck before we get to running Stage::ImportRepositoryWorker.
#
# We work around this by setting the JID to a custom generated one, then
# refreshing it in the various stages whenever necessary.
@@ -13,8 +13,7 @@ module Gitlab
def self.set_jid(import_state)
jid = generate_jid(import_state)
- Gitlab::SidekiqStatus
- .set(jid, StuckImportJobsWorker::IMPORT_JOBS_EXPIRATION)
+ Gitlab::SidekiqStatus.set(jid, Gitlab::Import::StuckImportJob::IMPORT_JOBS_EXPIRATION)
import_state.update_column(:jid, jid)
end
diff --git a/lib/gitlab/import_export/attributes_finder.rb b/lib/gitlab/import_export/attributes_finder.rb
index bab473741b1..1e98595bb07 100644
--- a/lib/gitlab/import_export/attributes_finder.rb
+++ b/lib/gitlab/import_export/attributes_finder.rb
@@ -3,6 +3,8 @@
module Gitlab
module ImportExport
class AttributesFinder
+ attr_reader :tree, :included_attributes, :excluded_attributes, :methods, :preloads
+
def initialize(config:)
@tree = config[:tree] || {}
@included_attributes = config[:included_attributes] || {}
diff --git a/lib/gitlab/import_export/attributes_permitter.rb b/lib/gitlab/import_export/attributes_permitter.rb
new file mode 100644
index 00000000000..86f51add504
--- /dev/null
+++ b/lib/gitlab/import_export/attributes_permitter.rb
@@ -0,0 +1,105 @@
+# frozen_string_literal: true
+
+# AttributesPermitter builds a hash of permitted attributes for
+# every model defined in import_export.yml that is used to validate and
+# filter out any attributes that are not permitted when doing Project/Group Import
+#
+# Each model's list includes:
+# - attributes defined under included_attributes section
+# - associations defined under project/group tree
+# - methods defined under methods section
+#
+# Given the following import_export.yml example:
+# ```
+# tree:
+# project:
+# - labels:
+# - :priorities
+# included_attributes:
+# labels:
+# - :title
+# - :description
+# methods:
+# labels:
+# - :type
+# ```
+#
+# Produces a list of permitted attributes:
+# ```
+# Gitlab::ImportExport::AttributesPermitter.new.permitted_attributes
+#
+# => { labels: [:priorities, :title, :description, :type] }
+# ```
+#
+# Filters out any other attributes from specific relation hash:
+# ```
+# Gitlab::ImportExport::AttributesPermitter.new.permit(:labels, {id: 5, type: 'opened', description: 'test', sensitive_attribute: 'my_sensitive_attribute'})
+#
+# => {:type=>"opened", :description=>"test"}
+# ```
+module Gitlab
+ module ImportExport
+ class AttributesPermitter
+ attr_reader :permitted_attributes
+
+ def initialize(config: ImportExport::Config.new.to_h)
+ @config = config
+ @attributes_finder = Gitlab::ImportExport::AttributesFinder.new(config: @config)
+ @permitted_attributes = {}
+
+ build_permitted_attributes
+ end
+
+ def permit(relation_name, relation_hash)
+ permitted_attributes = permitted_attributes_for(relation_name)
+
+ relation_hash.select do |key, _|
+ permitted_attributes.include?(key)
+ end
+ end
+
+ def permitted_attributes_for(relation_name)
+ @permitted_attributes[relation_name] || []
+ end
+
+ private
+
+ def build_permitted_attributes
+ build_associations
+ build_attributes
+ build_methods
+ end
+
+ # Deep traverse relations tree to build a list of allowed model relations
+ def build_associations
+ stack = @attributes_finder.tree.to_a
+
+ while stack.any?
+ model_name, relations = stack.pop
+
+ if relations.is_a?(Hash)
+ add_permitted_attributes(model_name, relations.keys)
+
+ stack.concat(relations.to_a)
+ end
+ end
+
+ @permitted_attributes
+ end
+
+ def build_attributes
+ @attributes_finder.included_attributes.each(&method(:add_permitted_attributes))
+ end
+
+ def build_methods
+ @attributes_finder.methods.each(&method(:add_permitted_attributes))
+ end
+
+ def add_permitted_attributes(model_name, attributes)
+ @permitted_attributes[model_name] ||= []
+
+ @permitted_attributes[model_name].concat(attributes) if attributes.any?
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/import_export/importer.rb b/lib/gitlab/import_export/importer.rb
index b1219384732..7b8689069d8 100644
--- a/lib/gitlab/import_export/importer.rb
+++ b/lib/gitlab/import_export/importer.rb
@@ -24,8 +24,14 @@ module Gitlab
raise Projects::ImportService::Error.new(shared.errors.to_sentence)
end
rescue => e
+ # If some exception was raised could mean that the SnippetsRepoRestorer
+ # was not called. This would leave us with snippets without a repository.
+ # This is a state we don't want them to be, so we better delete them.
+ remove_non_migrated_snippets
+
raise Projects::ImportService::Error.new(e.message)
ensure
+ remove_base_tmp_dir
remove_import_file
end
@@ -148,6 +154,18 @@ module Gitlab
::Project.find_by_full_path("#{project.namespace.full_path}/#{original_path}")
end
end
+
+ def remove_base_tmp_dir
+ FileUtils.rm_rf(@shared.base_path)
+ end
+
+ def remove_non_migrated_snippets
+ project
+ .snippets
+ .left_joins(:snippet_repository)
+ .where(snippet_repositories: { snippet_id: nil })
+ .delete_all
+ end
end
end
end
diff --git a/lib/gitlab/import_export/json/streaming_serializer.rb b/lib/gitlab/import_export/json/streaming_serializer.rb
index 7f55a0a3821..20f9c668b9c 100644
--- a/lib/gitlab/import_export/json/streaming_serializer.rb
+++ b/lib/gitlab/import_export/json/streaming_serializer.rb
@@ -7,6 +7,15 @@ module Gitlab
include Gitlab::ImportExport::CommandLineUtil
BATCH_SIZE = 100
+ SMALLER_BATCH_SIZE = 20
+
+ def self.batch_size(exportable)
+ if Feature.enabled?(:export_reduce_relation_batch_size, exportable)
+ SMALLER_BATCH_SIZE
+ else
+ BATCH_SIZE
+ end
+ end
class Raw < String
def to_json(*_args)
@@ -60,7 +69,7 @@ module Gitlab
key_preloads = preloads&.dig(key)
records = records.preload(key_preloads) if key_preloads
- records.find_each(batch_size: BATCH_SIZE) do |record|
+ records.find_each(batch_size: batch_size) do |record|
items << Raw.new(record.to_json(options))
end
end
@@ -91,6 +100,10 @@ module Gitlab
def preloads
relations_schema[:preload]
end
+
+ def batch_size
+ @batch_size ||= self.class.batch_size(@exportable)
+ end
end
end
end
diff --git a/lib/gitlab/import_export/legacy_relation_tree_saver.rb b/lib/gitlab/import_export/legacy_relation_tree_saver.rb
index cf75a2c7fa8..f8b8b74ffd7 100644
--- a/lib/gitlab/import_export/legacy_relation_tree_saver.rb
+++ b/lib/gitlab/import_export/legacy_relation_tree_saver.rb
@@ -7,7 +7,7 @@ module Gitlab
def serialize(exportable, relations_tree)
Gitlab::ImportExport::FastHashSerializer
- .new(exportable, relations_tree)
+ .new(exportable, relations_tree, batch_size: batch_size(exportable))
.execute
end
@@ -18,6 +18,12 @@ module Gitlab
File.write(File.join(dir_path, filename), tree_json)
end
+
+ private
+
+ def batch_size(exportable)
+ Gitlab::ImportExport::JSON::StreamingSerializer.batch_size(exportable)
+ end
end
end
end
diff --git a/lib/gitlab/import_export/members_mapper.rb b/lib/gitlab/import_export/members_mapper.rb
index 263c49c509f..31d1f7b48bd 100644
--- a/lib/gitlab/import_export/members_mapper.rb
+++ b/lib/gitlab/import_export/members_mapper.rb
@@ -49,7 +49,7 @@ module Gitlab
def ensure_default_member!
return if user_already_member?
- @importable.members.destroy_all # rubocop: disable DestroyAll
+ @importable.members.destroy_all # rubocop: disable Cop/DestroyAll
relation_class.create!(user: @user, access_level: highest_access_level, source_id: @importable.id, importing: true)
rescue => e
diff --git a/lib/gitlab/import_export/merge_request_parser.rb b/lib/gitlab/import_export/merge_request_parser.rb
index f735b9612aa..4643742b607 100644
--- a/lib/gitlab/import_export/merge_request_parser.rb
+++ b/lib/gitlab/import_export/merge_request_parser.rb
@@ -41,7 +41,13 @@ module Gitlab
def create_source_branch
@project.repository.create_branch(@merge_request.source_branch, @diff_head_sha)
rescue => err
- Rails.logger.warn("Import/Export warning: Failed to create source branch #{@merge_request.source_branch} => #{@diff_head_sha} for MR #{@merge_request.iid}: #{err}") # rubocop:disable Gitlab/RailsLogger
+ Gitlab::Import::Logger.warn(
+ message: 'Import warning: Failed to create source branch',
+ source_branch: @merge_request.source_branch,
+ diff_head_sha: @diff_head_sha,
+ merge_request_iid: @merge_request.iid,
+ error: err.message
+ )
end
def create_target_branch
diff --git a/lib/gitlab/import_export/project/import_export.yml b/lib/gitlab/import_export/project/import_export.yml
index 8851b106ad5..f0b733d7e95 100644
--- a/lib/gitlab/import_export/project/import_export.yml
+++ b/lib/gitlab/import_export/project/import_export.yml
@@ -312,6 +312,7 @@ excluded_attributes:
- :pipeline_schedule_id
- :merge_request_id
- :external_pull_request_id
+ - :ci_ref_id
stages:
- :pipeline_id
merge_access_levels:
@@ -397,3 +398,4 @@ ee:
- protected_environments:
- :deploy_access_levels
- :service_desk_setting
+ - :security_setting
diff --git a/lib/gitlab/import_export/repo_restorer.rb b/lib/gitlab/import_export/repo_restorer.rb
index 3123687453f..9e10e7aea13 100644
--- a/lib/gitlab/import_export/repo_restorer.rb
+++ b/lib/gitlab/import_export/repo_restorer.rb
@@ -16,6 +16,8 @@ module Gitlab
repository.create_from_bundle(path_to_bundle)
rescue => e
+ Repositories::DestroyService.new(repository).execute
+
shared.error(e)
false
end
diff --git a/lib/gitlab/import_export/saver.rb b/lib/gitlab/import_export/saver.rb
index ae82c380755..e4724659eff 100644
--- a/lib/gitlab/import_export/saver.rb
+++ b/lib/gitlab/import_export/saver.rb
@@ -11,14 +11,16 @@ module Gitlab
def initialize(exportable:, shared:)
@exportable = exportable
- @shared = shared
+ @shared = shared
end
def save
if compress_and_save
- remove_export_path
-
- Rails.logger.info("Saved #{@exportable.class} export #{archive_file}") # rubocop:disable Gitlab/RailsLogger
+ Gitlab::Export::Logger.info(
+ message: 'Export archive saved',
+ exportable_class: @exportable.class.to_s,
+ archive_file: archive_file
+ )
save_upload
else
@@ -29,8 +31,7 @@ module Gitlab
@shared.error(e)
false
ensure
- remove_archive
- remove_export_path
+ remove_base_tmp_dir
end
private
@@ -39,12 +40,8 @@ module Gitlab
tar_czf(archive: archive_file, dir: @shared.export_path)
end
- def remove_export_path
- FileUtils.rm_rf(@shared.export_path)
- end
-
- def remove_archive
- FileUtils.rm_rf(@shared.archive_path)
+ def remove_base_tmp_dir
+ FileUtils.rm_rf(@shared.base_path)
end
def archive_file
diff --git a/lib/gitlab/import_export/snippet_repo_restorer.rb b/lib/gitlab/import_export/snippet_repo_restorer.rb
index b58ea14a3a8..334d13a13ae 100644
--- a/lib/gitlab/import_export/snippet_repo_restorer.rb
+++ b/lib/gitlab/import_export/snippet_repo_restorer.rb
@@ -5,6 +5,8 @@ module Gitlab
class SnippetRepoRestorer < RepoRestorer
attr_reader :snippet
+ SnippetRepositoryError = Class.new(StandardError)
+
def initialize(snippet:, user:, shared:, path_to_bundle:)
@snippet = snippet
@user = user
@@ -34,14 +36,11 @@ module Gitlab
end
def create_repository_from_db
- snippet.create_repository
-
- commit_attrs = {
- branch_name: 'master',
- message: 'Initial commit'
- }
+ Gitlab::BackgroundMigration::BackfillSnippetRepositories.new.perform_by_ids([snippet.id])
- repository.create_file(@user, snippet.file_name, snippet.content, commit_attrs)
+ unless snippet.reset.snippet_repository
+ raise SnippetRepositoryError, _("Error creating repository for snippet with id %{snippet_id}") % { snippet_id: snippet.id }
+ end
end
end
end
diff --git a/lib/gitlab/import_export/snippets_repo_restorer.rb b/lib/gitlab/import_export/snippets_repo_restorer.rb
index 9ff3e74a6b1..5ab28f8dd83 100644
--- a/lib/gitlab/import_export/snippets_repo_restorer.rb
+++ b/lib/gitlab/import_export/snippets_repo_restorer.rb
@@ -10,15 +10,13 @@ module Gitlab
end
def restore
- return true unless Dir.exist?(snippets_repo_bundle_path)
-
- @project.snippets.find_each.all? do |snippet|
+ @project.snippets.find_each.map do |snippet|
Gitlab::ImportExport::SnippetRepoRestorer.new(snippet: snippet,
user: @user,
shared: @shared,
path_to_bundle: snippet_repo_bundle_path(snippet))
.restore
- end
+ end.all?(true)
end
private
diff --git a/lib/gitlab/import_export/version_checker.rb b/lib/gitlab/import_export/version_checker.rb
index 86ea7a30e69..4154d4fe775 100644
--- a/lib/gitlab/import_export/version_checker.rb
+++ b/lib/gitlab/import_export/version_checker.rb
@@ -36,7 +36,11 @@ module Gitlab
def different_version?(version)
Gem::Version.new(version) != Gem::Version.new(Gitlab::ImportExport.version)
rescue => e
- Rails.logger.error("Import/Export error: #{e.message}") # rubocop:disable Gitlab/RailsLogger
+ Gitlab::Import::Logger.error(
+ message: 'Import error',
+ error: e.message
+ )
+
raise Gitlab::ImportExport::Error.new('Incorrect VERSION format')
end
end
diff --git a/lib/gitlab/instrumentation/elasticsearch_transport.rb b/lib/gitlab/instrumentation/elasticsearch_transport.rb
new file mode 100644
index 00000000000..deee0127c0c
--- /dev/null
+++ b/lib/gitlab/instrumentation/elasticsearch_transport.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+require 'elasticsearch-transport'
+
+module Gitlab
+ module Instrumentation
+ module ElasticsearchTransportInterceptor
+ def perform_request(*args)
+ start = Time.now
+ super
+ ensure
+ if ::Gitlab::SafeRequestStore.active?
+ duration = (Time.now - start)
+
+ ::Gitlab::Instrumentation::ElasticsearchTransport.increment_request_count
+ ::Gitlab::Instrumentation::ElasticsearchTransport.add_duration(duration)
+ ::Gitlab::Instrumentation::ElasticsearchTransport.add_call_details(duration, args)
+ end
+ end
+ end
+
+ class ElasticsearchTransport
+ ELASTICSEARCH_REQUEST_COUNT = :elasticsearch_request_count
+ ELASTICSEARCH_CALL_DURATION = :elasticsearch_call_duration
+ ELASTICSEARCH_CALL_DETAILS = :elasticsearch_call_details
+
+ def self.get_request_count
+ ::Gitlab::SafeRequestStore[ELASTICSEARCH_REQUEST_COUNT] || 0
+ end
+
+ def self.increment_request_count
+ ::Gitlab::SafeRequestStore[ELASTICSEARCH_REQUEST_COUNT] ||= 0
+ ::Gitlab::SafeRequestStore[ELASTICSEARCH_REQUEST_COUNT] += 1
+ end
+
+ def self.detail_store
+ ::Gitlab::SafeRequestStore[ELASTICSEARCH_CALL_DETAILS] ||= []
+ end
+
+ def self.query_time
+ query_time = ::Gitlab::SafeRequestStore[ELASTICSEARCH_CALL_DURATION] || 0
+ query_time.round(::Gitlab::InstrumentationHelper::DURATION_PRECISION)
+ end
+
+ def self.add_duration(duration)
+ ::Gitlab::SafeRequestStore[ELASTICSEARCH_CALL_DURATION] ||= 0
+ ::Gitlab::SafeRequestStore[ELASTICSEARCH_CALL_DURATION] += duration
+ end
+
+ def self.add_call_details(duration, args)
+ return unless Gitlab::PerformanceBar.enabled_for_request?
+
+ detail_store << {
+ method: args[0],
+ path: args[1],
+ params: args[2],
+ body: args[3],
+ duration: duration,
+ backtrace: ::Gitlab::BacktraceCleaner.clean_backtrace(caller)
+ }
+ end
+ end
+ end
+end
+
+class ::Elasticsearch::Transport::Client
+ prepend ::Gitlab::Instrumentation::ElasticsearchTransportInterceptor
+end
diff --git a/lib/gitlab/instrumentation/redis.rb b/lib/gitlab/instrumentation/redis.rb
index cc99e828251..82b4701872f 100644
--- a/lib/gitlab/instrumentation/redis.rb
+++ b/lib/gitlab/instrumentation/redis.rb
@@ -1,67 +1,46 @@
# frozen_string_literal: true
-require 'redis'
-
module Gitlab
module Instrumentation
- module RedisInterceptor
- def call(*args, &block)
- start = Time.now
- super(*args, &block)
- ensure
- duration = (Time.now - start)
-
- if ::RequestStore.active?
- ::Gitlab::Instrumentation::Redis.increment_request_count
- ::Gitlab::Instrumentation::Redis.add_duration(duration)
- ::Gitlab::Instrumentation::Redis.add_call_details(duration, args)
- end
- end
- end
-
+ # Aggregates Redis measurements from different request storage sources.
class Redis
- REDIS_REQUEST_COUNT = :redis_request_count
- REDIS_CALL_DURATION = :redis_call_duration
- REDIS_CALL_DETAILS = :redis_call_details
+ ActionCable = Class.new(RedisBase)
+ Cache = Class.new(RedisBase)
+ Queues = Class.new(RedisBase)
+ SharedState = Class.new(RedisBase)
- def self.get_request_count
- ::RequestStore[REDIS_REQUEST_COUNT] || 0
- end
+ STORAGES = [ActionCable, Cache, Queues, SharedState].freeze
- def self.increment_request_count
- ::RequestStore[REDIS_REQUEST_COUNT] ||= 0
- ::RequestStore[REDIS_REQUEST_COUNT] += 1
- end
+ # Milliseconds represented in seconds (from 1 millisecond to 2 seconds).
+ QUERY_TIME_BUCKETS = [0.001, 0.0025, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2].freeze
- def self.detail_store
- ::RequestStore[REDIS_CALL_DETAILS] ||= []
- end
+ class << self
+ include ::Gitlab::Instrumentation::RedisPayload
- def self.query_time
- query_time = ::RequestStore[REDIS_CALL_DURATION] || 0
- query_time.round(::Gitlab::InstrumentationHelper::DURATION_PRECISION)
- end
+ def storage_key
+ nil
+ end
- def self.add_duration(duration)
- total_time = query_time + duration
- ::RequestStore[REDIS_CALL_DURATION] = total_time
- end
+ def known_payload_keys
+ super + STORAGES.flat_map(&:known_payload_keys)
+ end
- def self.add_call_details(duration, args)
- return unless Gitlab::PerformanceBar.enabled_for_request?
- # redis-rb passes an array (e.g. [:get, key])
- return unless args.length == 1
+ def payload
+ super.merge(*STORAGES.flat_map(&:payload))
+ end
- detail_store << {
- cmd: args.first,
- duration: duration,
- backtrace: ::Gitlab::BacktraceCleaner.clean_backtrace(caller)
- }
+ def detail_store
+ STORAGES.flat_map do |storage|
+ storage.detail_store.map { |details| details.merge(storage: storage.name.demodulize) }
+ end
+ end
+
+ %i[get_request_count query_time read_bytes write_bytes].each do |method|
+ define_method method do
+ STORAGES.sum(&method) # rubocop:disable CodeReuse/ActiveRecord
+ end
+ end
end
end
end
end
-
-class ::Redis::Client
- prepend ::Gitlab::Instrumentation::RedisInterceptor
-end
diff --git a/lib/gitlab/instrumentation/redis_base.rb b/lib/gitlab/instrumentation/redis_base.rb
new file mode 100644
index 00000000000..012543e1645
--- /dev/null
+++ b/lib/gitlab/instrumentation/redis_base.rb
@@ -0,0 +1,102 @@
+# frozen_string_literal: true
+
+require 'redis'
+
+module Gitlab
+ module Instrumentation
+ class RedisBase
+ class << self
+ include ::Gitlab::Utils::StrongMemoize
+ include ::Gitlab::Instrumentation::RedisPayload
+
+ # TODO: To be used by https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/395
+ # as a 'label' alias.
+ def storage_key
+ self.name.demodulize.underscore
+ end
+
+ def add_duration(duration)
+ ::RequestStore[call_duration_key] ||= 0
+ ::RequestStore[call_duration_key] += duration
+ end
+
+ def add_call_details(duration, args)
+ return unless Gitlab::PerformanceBar.enabled_for_request?
+ # redis-rb passes an array (e.g. [[:get, key]])
+ return unless args.length == 1
+
+ # TODO: Add information about current Redis client
+ # being instrumented.
+ # https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/316.
+ detail_store << {
+ cmd: args.first,
+ duration: duration,
+ backtrace: ::Gitlab::BacktraceCleaner.clean_backtrace(caller)
+ }
+ end
+
+ def increment_request_count
+ ::RequestStore[request_count_key] ||= 0
+ ::RequestStore[request_count_key] += 1
+ end
+
+ def increment_read_bytes(num_bytes)
+ ::RequestStore[read_bytes_key] ||= 0
+ ::RequestStore[read_bytes_key] += num_bytes
+ end
+
+ def increment_write_bytes(num_bytes)
+ ::RequestStore[write_bytes_key] ||= 0
+ ::RequestStore[write_bytes_key] += num_bytes
+ end
+
+ def get_request_count
+ ::RequestStore[request_count_key] || 0
+ end
+
+ def read_bytes
+ ::RequestStore[read_bytes_key] || 0
+ end
+
+ def write_bytes
+ ::RequestStore[write_bytes_key] || 0
+ end
+
+ def detail_store
+ ::RequestStore[call_details_key] ||= []
+ end
+
+ def query_time
+ query_time = ::RequestStore[call_duration_key] || 0
+ query_time.round(::Gitlab::InstrumentationHelper::DURATION_PRECISION)
+ end
+
+ private
+
+ def request_count_key
+ strong_memoize(:request_count_key) { build_key(:redis_request_count) }
+ end
+
+ def read_bytes_key
+ strong_memoize(:read_bytes_key) { build_key(:redis_read_bytes) }
+ end
+
+ def write_bytes_key
+ strong_memoize(:write_bytes_key) { build_key(:redis_write_bytes) }
+ end
+
+ def call_duration_key
+ strong_memoize(:call_duration_key) { build_key(:redis_call_duration) }
+ end
+
+ def call_details_key
+ strong_memoize(:call_details_key) { build_key(:redis_call_details) }
+ end
+
+ def build_key(namespace)
+ "#{storage_key}_#{namespace}"
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/instrumentation/redis_interceptor.rb b/lib/gitlab/instrumentation/redis_interceptor.rb
new file mode 100644
index 00000000000..a36aade59c3
--- /dev/null
+++ b/lib/gitlab/instrumentation/redis_interceptor.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+require 'redis'
+
+module Gitlab
+ module Instrumentation
+ module RedisInterceptor
+ def call(*args, &block)
+ start = Time.now
+ super(*args, &block)
+ ensure
+ duration = (Time.now - start)
+
+ if ::RequestStore.active?
+ instrumentation_class.increment_request_count
+ instrumentation_class.add_duration(duration)
+ instrumentation_class.add_call_details(duration, args)
+ end
+ end
+
+ def write(command)
+ measure_write_size(command) if ::RequestStore.active?
+ super
+ end
+
+ def read
+ result = super
+ measure_read_size(result) if ::RequestStore.active?
+ result
+ end
+
+ private
+
+ def measure_write_size(command)
+ size = 0
+
+ # Mimic what happens in
+ # https://github.com/redis/redis-rb/blob/f597f21a6b954b685cf939febbc638f6c803e3a7/lib/redis/connection/command_helper.rb#L8.
+ # This count is an approximation that omits the Redis protocol overhead
+ # of type prefixes, length prefixes and line endings.
+ command.each do |x|
+ size += begin
+ if x.is_a? Array
+ x.inject(0) { |sum, y| sum + y.to_s.bytesize }
+ else
+ x.to_s.bytesize
+ end
+ end
+ end
+
+ instrumentation_class.increment_write_bytes(size)
+ end
+
+ def measure_read_size(result)
+ # The Connection::Ruby#read class can return one of four types of results from read:
+ # https://github.com/redis/redis-rb/blob/f597f21a6b954b685cf939febbc638f6c803e3a7/lib/redis/connection/ruby.rb#L406
+ #
+ # 1. Error (exception, will not reach this line)
+ # 2. Status (string)
+ # 3. Integer (will be converted to string by to_s.bytesize and thrown away)
+ # 4. "Binary" string (i.e. may contain zero byte)
+ # 5. Array of binary string
+
+ if result.is_a? Array
+ # Redis can return nested arrays, e.g. from XRANGE or GEOPOS, so we use recursion here.
+ result.each { |x| measure_read_size(x) }
+ else
+ # This count is an approximation that omits the Redis protocol overhead
+ # of type prefixes, length prefixes and line endings.
+ instrumentation_class.increment_read_bytes(result.to_s.bytesize)
+ end
+ end
+
+ # That's required so it knows which GitLab Redis instance
+ # it's interacting with in order to categorize accordingly.
+ #
+ def instrumentation_class
+ @options[:instrumentation_class] # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ end
+ end
+ end
+end
+
+class ::Redis::Client
+ prepend ::Gitlab::Instrumentation::RedisInterceptor
+end
diff --git a/lib/gitlab/instrumentation/redis_payload.rb b/lib/gitlab/instrumentation/redis_payload.rb
new file mode 100644
index 00000000000..69aafffd124
--- /dev/null
+++ b/lib/gitlab/instrumentation/redis_payload.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Instrumentation
+ module RedisPayload
+ include ::Gitlab::Utils::StrongMemoize
+
+ # Fetches payload keys from the lazy payload (this avoids
+ # unnecessary processing of the values).
+ def known_payload_keys
+ to_lazy_payload.keys
+ end
+
+ def payload
+ to_lazy_payload.transform_values do |value|
+ result = value.call
+ result if result > 0
+ end.compact
+ end
+
+ private
+
+ def to_lazy_payload
+ strong_memoize(:to_lazy_payload) do
+ key_prefix = storage_key ? "redis_#{storage_key}" : 'redis'
+
+ {
+ "#{key_prefix}_calls": -> { get_request_count },
+ "#{key_prefix}_duration_s": -> { query_time },
+ "#{key_prefix}_read_bytes": -> { read_bytes },
+ "#{key_prefix}_write_bytes": -> { write_bytes }
+ }.symbolize_keys
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/instrumentation_helper.rb b/lib/gitlab/instrumentation_helper.rb
index 7c5a601cd5b..3a29d2e7efa 100644
--- a/lib/gitlab/instrumentation_helper.rb
+++ b/lib/gitlab/instrumentation_helper.rb
@@ -4,30 +4,56 @@ module Gitlab
module InstrumentationHelper
extend self
- KEYS = %i(gitaly_calls gitaly_duration_s rugged_calls rugged_duration_s redis_calls redis_duration_s).freeze
DURATION_PRECISION = 6 # microseconds
+ def keys
+ @keys ||= [:gitaly_calls,
+ :gitaly_duration_s,
+ :rugged_calls,
+ :rugged_duration_s,
+ :elasticsearch_calls,
+ :elasticsearch_duration_s,
+ *::Gitlab::Instrumentation::Redis.known_payload_keys]
+ end
+
def add_instrumentation_data(payload)
+ instrument_gitaly(payload)
+ instrument_rugged(payload)
+ instrument_redis(payload)
+ instrument_elasticsearch(payload)
+ end
+
+ def instrument_gitaly(payload)
gitaly_calls = Gitlab::GitalyClient.get_request_count
- if gitaly_calls > 0
- payload[:gitaly_calls] = gitaly_calls
- payload[:gitaly_duration_s] = Gitlab::GitalyClient.query_time
- end
+ return if gitaly_calls == 0
+
+ payload[:gitaly_calls] = gitaly_calls
+ payload[:gitaly_duration_s] = Gitlab::GitalyClient.query_time
+ end
+ def instrument_rugged(payload)
rugged_calls = Gitlab::RuggedInstrumentation.query_count
- if rugged_calls > 0
- payload[:rugged_calls] = rugged_calls
- payload[:rugged_duration_s] = Gitlab::RuggedInstrumentation.query_time
- end
+ return if rugged_calls == 0
+
+ payload[:rugged_calls] = rugged_calls
+ payload[:rugged_duration_s] = Gitlab::RuggedInstrumentation.query_time
+ end
+
+ def instrument_redis(payload)
+ payload.merge! ::Gitlab::Instrumentation::Redis.payload
+ end
+
+ def instrument_elasticsearch(payload)
+ # Elasticsearch integration is only available in EE but instrumentation
+ # only depends on the Gem which is also available in FOSS.
+ elasticsearch_calls = Gitlab::Instrumentation::ElasticsearchTransport.get_request_count
- redis_calls = Gitlab::Instrumentation::Redis.get_request_count
+ return if elasticsearch_calls == 0
- if redis_calls > 0
- payload[:redis_calls] = redis_calls
- payload[:redis_duration_s] = Gitlab::Instrumentation::Redis.query_time
- end
+ payload[:elasticsearch_calls] = elasticsearch_calls
+ payload[:elasticsearch_duration_s] = Gitlab::Instrumentation::ElasticsearchTransport.query_time
end
# Returns the queuing duration for a Sidekiq job in seconds, as a float, if the
diff --git a/lib/gitlab/issuable_metadata.rb b/lib/gitlab/issuable_metadata.rb
index 6f760751b0f..e946fc00c4d 100644
--- a/lib/gitlab/issuable_metadata.rb
+++ b/lib/gitlab/issuable_metadata.rb
@@ -1,8 +1,52 @@
# frozen_string_literal: true
module Gitlab
- module IssuableMetadata
- def issuable_meta_data(issuable_collection, collection_type, user = nil)
+ class IssuableMetadata
+ include Gitlab::Utils::StrongMemoize
+
+ # data structure to store issuable meta data like
+ # upvotes, downvotes, notes and closing merge requests counts for issues and merge requests
+ # this avoiding n+1 queries when loading issuable collections on frontend
+ IssuableMeta = Struct.new(:upvotes, :downvotes, :user_notes_count, :mrs_count) do
+ def merge_requests_count(user = nil)
+ mrs_count
+ end
+ end
+
+ attr_reader :current_user, :issuable_collection
+
+ def initialize(current_user, issuable_collection)
+ @current_user = current_user
+ @issuable_collection = issuable_collection
+
+ validate_collection!
+ end
+
+ def data
+ return {} if issuable_ids.empty?
+
+ issuable_ids.each_with_object({}) do |id, issuable_meta|
+ issuable_meta[id] = metadata_for_issuable(id)
+ end
+ end
+
+ private
+
+ def metadata_for_issuable(id)
+ downvotes = group_issuable_votes_count.find { |votes| votes.awardable_id == id && votes.downvote? }
+ upvotes = group_issuable_votes_count.find { |votes| votes.awardable_id == id && votes.upvote? }
+ notes = grouped_issuable_notes_count.find { |notes| notes.noteable_id == id }
+ merge_requests = grouped_issuable_merge_requests_count.find { |mr| mr.first == id }
+
+ IssuableMeta.new(
+ upvotes.try(:count).to_i,
+ downvotes.try(:count).to_i,
+ notes.try(:count).to_i,
+ merge_requests.try(:last).to_i
+ )
+ end
+
+ def validate_collection!
# ActiveRecord uses Object#extend for null relations.
if !(issuable_collection.singleton_class < ActiveRecord::NullRelation) &&
issuable_collection.respond_to?(:limit_value) &&
@@ -10,36 +54,43 @@ module Gitlab
raise 'Collection must have a limit applied for preloading meta-data'
end
+ end
- # map has to be used here since using pluck or select will
- # throw an error when ordering issuables by priority which inserts
- # a new order into the collection.
- # We cannot use reorder to not mess up the paginated collection.
- issuable_ids = issuable_collection.map(&:id)
+ def issuable_ids
+ strong_memoize(:issuable_ids) do
+ # map has to be used here since using pluck or select will
+ # throw an error when ordering issuables by priority which inserts
+ # a new order into the collection.
+ # We cannot use reorder to not mess up the paginated collection.
+ issuable_collection.map(&:id)
+ end
+ end
- return {} if issuable_ids.empty?
+ def collection_type
+ # Supports relations or paginated arrays
+ issuable_collection.try(:model)&.name ||
+ issuable_collection.first&.model_name.to_s
+ end
- issuable_notes_count = ::Note.count_for_collection(issuable_ids, collection_type)
- issuable_votes_count = ::AwardEmoji.votes_for_collection(issuable_ids, collection_type)
- issuable_merge_requests_count =
+ def group_issuable_votes_count
+ strong_memoize(:group_issuable_votes_count) do
+ AwardEmoji.votes_for_collection(issuable_ids, collection_type)
+ end
+ end
+
+ def grouped_issuable_notes_count
+ strong_memoize(:grouped_issuable_notes_count) do
+ ::Note.count_for_collection(issuable_ids, collection_type)
+ end
+ end
+
+ def grouped_issuable_merge_requests_count
+ strong_memoize(:grouped_issuable_merge_requests_count) do
if collection_type == 'Issue'
- ::MergeRequestsClosingIssues.count_for_collection(issuable_ids, user)
+ ::MergeRequestsClosingIssues.count_for_collection(issuable_ids, current_user)
else
[]
end
-
- issuable_ids.each_with_object({}) do |id, issuable_meta|
- downvotes = issuable_votes_count.find { |votes| votes.awardable_id == id && votes.downvote? }
- upvotes = issuable_votes_count.find { |votes| votes.awardable_id == id && votes.upvote? }
- notes = issuable_notes_count.find { |notes| notes.noteable_id == id }
- merge_requests = issuable_merge_requests_count.find { |mr| mr.first == id }
-
- issuable_meta[id] = ::Issuable::IssuableMeta.new(
- upvotes.try(:count).to_i,
- downvotes.try(:count).to_i,
- notes.try(:count).to_i,
- merge_requests.try(:last).to_i
- )
end
end
end
diff --git a/lib/gitlab/jira/http_client.rb b/lib/gitlab/jira/http_client.rb
index b973244a531..c09d8170d17 100644
--- a/lib/gitlab/jira/http_client.rb
+++ b/lib/gitlab/jira/http_client.rb
@@ -12,12 +12,7 @@ module Gitlab
def request(*args)
result = make_request(*args)
- unless result.response.is_a?(Net::HTTPSuccess)
- Gitlab::ErrorTracking.track_and_raise_exception(
- JIRA::HTTPError.new(result.response),
- response: result.body
- )
- end
+ raise JIRA::HTTPError.new(result.response) unless result.response.is_a?(Net::HTTPSuccess)
result
end
diff --git a/lib/gitlab/jira_import.rb b/lib/gitlab/jira_import.rb
index 3f56094956a..75d6fdc07b6 100644
--- a/lib/gitlab/jira_import.rb
+++ b/lib/gitlab/jira_import.rb
@@ -7,11 +7,30 @@ module Gitlab
FAILED_ISSUES_COUNTER_KEY = 'jira-import/failed/%{project_id}/%{collection_type}'
NEXT_ITEMS_START_AT_KEY = 'jira-import/paginator/%{project_id}/%{collection_type}'
JIRA_IMPORT_LABEL = 'jira-import/import-label/%{project_id}'
- ITEMS_MAPPER_CACHE_KEY = 'jira-import/items-mapper/%{project_id}/%{collection_type}/%{jira_isssue_id}'
+ ITEMS_MAPPER_CACHE_KEY = 'jira-import/items-mapper/%{project_id}/%{collection_type}/%{jira_item_id}'
+ USERS_MAPPER_KEY_PREFIX = 'jira-import/items-mapper/%{project_id}/users/'
ALREADY_IMPORTED_ITEMS_CACHE_KEY = 'jira-importer/already-imported/%{project}/%{collection_type}'
- def self.jira_issue_cache_key(project_id, jira_issue_id)
- ITEMS_MAPPER_CACHE_KEY % { project_id: project_id, collection_type: :issues, jira_isssue_id: jira_issue_id }
+ def self.validate_project_settings!(project, user: nil, configuration_check: true)
+ if user
+ raise Projects::ImportService::Error, _('Cannot import because issues are not available in this project.') unless project.feature_available?(:issues, user)
+ raise Projects::ImportService::Error, _('You do not have permissions to run the import.') unless user.can?(:admin_project, project)
+ end
+
+ return unless configuration_check
+
+ jira_service = project.jira_service
+
+ raise Projects::ImportService::Error, _('Jira integration not configured.') unless jira_service&.active?
+ raise Projects::ImportService::Error, _('Unable to connect to the Jira instance. Please check your Jira integration configuration.') unless jira_service&.valid_connection?
+ end
+
+ def self.jira_item_cache_key(project_id, jira_item_id, collection_type)
+ ITEMS_MAPPER_CACHE_KEY % { project_id: project_id, collection_type: collection_type, jira_item_id: jira_item_id }
+ end
+
+ def self.jira_user_key_prefix(project_id)
+ USERS_MAPPER_KEY_PREFIX % { project_id: project_id }
end
def self.already_imported_cache_key(collection_type, project_id)
@@ -48,7 +67,7 @@ module Gitlab
end
def self.cache_issue_mapping(issue_id, jira_issue_id, project_id)
- cache_key = JiraImport.jira_issue_cache_key(project_id, jira_issue_id)
+ cache_key = JiraImport.jira_item_cache_key(project_id, jira_issue_id, :issues)
cache_class.write(cache_key, issue_id)
end
@@ -67,6 +86,19 @@ module Gitlab
cache_class.expire(self.already_imported_cache_key(:issues, project_id), JIRA_IMPORT_CACHE_TIMEOUT)
end
+ # Caches the mapping of jira_account_id -> gitlab user id
+ # project_id - id of a project
+ # mapping - hash in format of jira_account_id -> gitlab user id
+ def self.cache_users_mapping(project_id, mapping)
+ cache_class.write_multiple(mapping, key_prefix: jira_user_key_prefix(project_id))
+ end
+
+ def self.get_user_mapping(project_id, jira_account_id)
+ cache_key = JiraImport.jira_item_cache_key(project_id, jira_account_id, :users)
+
+ cache_class.read(cache_key)&.to_i
+ end
+
def self.cache_class
Gitlab::Cache::Import::Caching
end
diff --git a/lib/gitlab/jira_import/base_importer.rb b/lib/gitlab/jira_import/base_importer.rb
index 306736df30f..688254bf91f 100644
--- a/lib/gitlab/jira_import/base_importer.rb
+++ b/lib/gitlab/jira_import/base_importer.rb
@@ -6,7 +6,7 @@ module Gitlab
attr_reader :project, :client, :formatter, :jira_project_key, :running_import
def initialize(project)
- project.validate_jira_import_settings!
+ Gitlab::JiraImport.validate_project_settings!(project)
@running_import = project.latest_jira_import
@jira_project_key = running_import&.jira_project_key
diff --git a/lib/gitlab/jira_import/issues_importer.rb b/lib/gitlab/jira_import/issues_importer.rb
index 8c18e58d9df..26fa01755d1 100644
--- a/lib/gitlab/jira_import/issues_importer.rb
+++ b/lib/gitlab/jira_import/issues_importer.rb
@@ -57,17 +57,27 @@ module Gitlab
# For such cases we exit early if issue was already imported.
next if already_imported?(jira_issue.id)
- issue_attrs = IssueSerializer.new(project, jira_issue, running_import.user_id, { iid: next_iid }).execute
- Gitlab::JiraImport::ImportIssueWorker.perform_async(project.id, jira_issue.id, issue_attrs, job_waiter.key)
-
- job_waiter.jobs_remaining += 1
- next_iid += 1
-
- # Mark the issue as imported immediately so we don't end up
- # importing it multiple times within same import.
- # These ids are cleaned-up when import finishes.
- # see Gitlab::JiraImport::Stage::FinishImportWorker
- mark_as_imported(jira_issue.id)
+ begin
+ issue_attrs = IssueSerializer.new(project, jira_issue, running_import.user_id, { iid: next_iid }).execute
+
+ Gitlab::JiraImport::ImportIssueWorker.perform_async(project.id, jira_issue.id, issue_attrs, job_waiter.key)
+
+ job_waiter.jobs_remaining += 1
+ next_iid += 1
+
+ # Mark the issue as imported immediately so we don't end up
+ # importing it multiple times within same import.
+ # These ids are cleaned-up when import finishes.
+ # see Gitlab::JiraImport::Stage::FinishImportWorker
+ mark_as_imported(jira_issue.id)
+ rescue => ex
+ # handle exceptionn here and skip the failed to import issue, instead of
+ # failing to import the entire batch of issues
+
+ # track the failed to import issue.
+ Gitlab::ErrorTracking.track_exception(ex, project_id: project.id)
+ JiraImport.increment_issue_failures(project.id)
+ end
end
job_waiter
diff --git a/lib/gitlab/kubernetes/helm.rb b/lib/gitlab/kubernetes/helm.rb
index 00ab7109267..9507f7bc117 100644
--- a/lib/gitlab/kubernetes/helm.rb
+++ b/lib/gitlab/kubernetes/helm.rb
@@ -10,12 +10,6 @@ module Gitlab
SERVICE_ACCOUNT = 'tiller'
CLUSTER_ROLE_BINDING = 'tiller-admin'
CLUSTER_ROLE = 'cluster-admin'
-
- MANAGED_APPS_LOCAL_TILLER_FEATURE_FLAG = :managed_apps_local_tiller
-
- def self.local_tiller_enabled?
- Feature.enabled?(MANAGED_APPS_LOCAL_TILLER_FEATURE_FLAG)
- end
end
end
end
diff --git a/lib/gitlab/kubernetes/helm/base_command.rb b/lib/gitlab/kubernetes/helm/base_command.rb
index 31cd21f17e0..f27ad05599e 100644
--- a/lib/gitlab/kubernetes/helm/base_command.rb
+++ b/lib/gitlab/kubernetes/helm/base_command.rb
@@ -3,7 +3,24 @@
module Gitlab
module Kubernetes
module Helm
- module BaseCommand
+ class BaseCommand
+ attr_reader :name, :files
+
+ def initialize(rbac:, name:, files:, local_tiller_enabled:)
+ @rbac = rbac
+ @name = name
+ @files = files
+ @local_tiller_enabled = local_tiller_enabled
+ end
+
+ def rbac?
+ @rbac
+ end
+
+ def local_tiller_enabled?
+ @local_tiller_enabled
+ end
+
def pod_resource
pod_service_account_name = rbac? ? service_account_name : nil
@@ -46,18 +63,6 @@ module Gitlab
files.keys
end
- def name
- raise "Not implemented"
- end
-
- def rbac?
- raise "Not implemented"
- end
-
- def files
- raise "Not implemented"
- end
-
private
def files_dir
diff --git a/lib/gitlab/kubernetes/helm/client_command.rb b/lib/gitlab/kubernetes/helm/client_command.rb
index e7ade7e4d39..24458e1b4b3 100644
--- a/lib/gitlab/kubernetes/helm/client_command.rb
+++ b/lib/gitlab/kubernetes/helm/client_command.rb
@@ -57,10 +57,6 @@ module Gitlab
'--tls-key', "#{files_dir}/key.pem"
]
end
-
- def local_tiller_enabled?
- ::Gitlab::Kubernetes::Helm.local_tiller_enabled?
- end
end
end
end
diff --git a/lib/gitlab/kubernetes/helm/delete_command.rb b/lib/gitlab/kubernetes/helm/delete_command.rb
index 771444ee9ee..3bb41d09994 100644
--- a/lib/gitlab/kubernetes/helm/delete_command.rb
+++ b/lib/gitlab/kubernetes/helm/delete_command.rb
@@ -3,17 +3,13 @@
module Gitlab
module Kubernetes
module Helm
- class DeleteCommand
- include BaseCommand
+ class DeleteCommand < BaseCommand
include ClientCommand
attr_reader :predelete, :postdelete
- attr_accessor :name, :files
- def initialize(name:, rbac:, files:, predelete: nil, postdelete: nil)
- @name = name
- @files = files
- @rbac = rbac
+ def initialize(predelete: nil, postdelete: nil, **args)
+ super(**args)
@predelete = predelete
@postdelete = postdelete
end
@@ -32,10 +28,6 @@ module Gitlab
"uninstall-#{name}"
end
- def rbac?
- @rbac
- end
-
def delete_command
command = ['helm', 'delete', '--purge', name] + tls_flags_if_remote_tiller
diff --git a/lib/gitlab/kubernetes/helm/init_command.rb b/lib/gitlab/kubernetes/helm/init_command.rb
index 058f38f2c9c..e4844e255c5 100644
--- a/lib/gitlab/kubernetes/helm/init_command.rb
+++ b/lib/gitlab/kubernetes/helm/init_command.rb
@@ -3,27 +3,13 @@
module Gitlab
module Kubernetes
module Helm
- class InitCommand
- include BaseCommand
-
- attr_reader :name, :files
-
- def initialize(name:, files:, rbac:)
- @name = name
- @files = files
- @rbac = rbac
- end
-
+ class InitCommand < BaseCommand
def generate_script
super + [
init_helm_command
].join("\n")
end
- def rbac?
- @rbac
- end
-
private
def init_helm_command
diff --git a/lib/gitlab/kubernetes/helm/install_command.rb b/lib/gitlab/kubernetes/helm/install_command.rb
index 3784aecccb5..cf6d993cad4 100644
--- a/lib/gitlab/kubernetes/helm/install_command.rb
+++ b/lib/gitlab/kubernetes/helm/install_command.rb
@@ -3,19 +3,16 @@
module Gitlab
module Kubernetes
module Helm
- class InstallCommand
- include BaseCommand
+ class InstallCommand < BaseCommand
include ClientCommand
- attr_reader :name, :files, :chart, :repository, :preinstall, :postinstall
+ attr_reader :chart, :repository, :preinstall, :postinstall
attr_accessor :version
- def initialize(name:, chart:, files:, rbac:, version: nil, repository: nil, preinstall: nil, postinstall: nil)
- @name = name
+ def initialize(chart:, version: nil, repository: nil, preinstall: nil, postinstall: nil, **args)
+ super(**args)
@chart = chart
@version = version
- @rbac = rbac
- @files = files
@repository = repository
@preinstall = preinstall
@postinstall = postinstall
@@ -33,10 +30,6 @@ module Gitlab
].compact.join("\n")
end
- def rbac?
- @rbac
- end
-
private
# Uses `helm upgrade --install` which means we can use this for both
diff --git a/lib/gitlab/kubernetes/helm/patch_command.rb b/lib/gitlab/kubernetes/helm/patch_command.rb
index ed7a5c2b2d6..1a5fab116bd 100644
--- a/lib/gitlab/kubernetes/helm/patch_command.rb
+++ b/lib/gitlab/kubernetes/helm/patch_command.rb
@@ -5,23 +5,21 @@
module Gitlab
module Kubernetes
module Helm
- class PatchCommand
- include BaseCommand
+ class PatchCommand < BaseCommand
include ClientCommand
- attr_reader :name, :files, :chart, :repository
+ attr_reader :chart, :repository
attr_accessor :version
- def initialize(name:, chart:, files:, rbac:, version:, repository: nil)
+ def initialize(chart:, version:, repository: nil, **args)
+ super(**args)
+
# version is mandatory to prevent chart mismatches
# we do not want our values interpreted in the context of the wrong version
raise ArgumentError, 'version is required' if version.blank?
- @name = name
@chart = chart
@version = version
- @rbac = rbac
- @files = files
@repository = repository
end
@@ -35,10 +33,6 @@ module Gitlab
].compact.join("\n")
end
- def rbac?
- @rbac
- end
-
private
def upgrade_command
diff --git a/lib/gitlab/kubernetes/helm/reset_command.rb b/lib/gitlab/kubernetes/helm/reset_command.rb
index 13176360227..f1f7938039c 100644
--- a/lib/gitlab/kubernetes/helm/reset_command.rb
+++ b/lib/gitlab/kubernetes/helm/reset_command.rb
@@ -3,18 +3,9 @@
module Gitlab
module Kubernetes
module Helm
- class ResetCommand
- include BaseCommand
+ class ResetCommand < BaseCommand
include ClientCommand
- attr_reader :name, :files
-
- def initialize(name:, rbac:, files:)
- @name = name
- @files = files
- @rbac = rbac
- end
-
def generate_script
super + [
reset_helm_command,
@@ -23,10 +14,6 @@ module Gitlab
].join("\n")
end
- def rbac?
- @rbac
- end
-
def pod_name
"uninstall-#{name}"
end
diff --git a/lib/gitlab/kubernetes/network_policy.rb b/lib/gitlab/kubernetes/network_policy.rb
index ea25d81cbd2..dc13a614551 100644
--- a/lib/gitlab/kubernetes/network_policy.rb
+++ b/lib/gitlab/kubernetes/network_policy.rb
@@ -3,9 +3,12 @@
module Gitlab
module Kubernetes
class NetworkPolicy
- def initialize(name:, namespace:, pod_selector:, ingress:, creation_timestamp: nil, policy_types: ["Ingress"], egress: nil)
+ DISABLED_BY_LABEL = :'network-policy.gitlab.com/disabled_by'
+
+ def initialize(name:, namespace:, pod_selector:, ingress:, labels: nil, creation_timestamp: nil, policy_types: ["Ingress"], egress: nil)
@name = name
@namespace = namespace
+ @labels = labels
@creation_timestamp = creation_timestamp
@pod_selector = pod_selector
@policy_types = policy_types
@@ -24,6 +27,7 @@ module Gitlab
self.new(
name: metadata[:name],
namespace: metadata[:namespace],
+ labels: metadata[:labels],
pod_selector: spec[:podSelector],
policy_types: spec[:policyTypes],
ingress: spec[:ingress],
@@ -42,6 +46,7 @@ module Gitlab
self.new(
name: metadata[:name],
namespace: metadata[:namespace],
+ labels: metadata[:labels]&.to_h,
creation_timestamp: metadata[:creationTimestamp],
pod_selector: spec[:podSelector],
policy_types: spec[:policyTypes],
@@ -62,16 +67,48 @@ module Gitlab
name: name,
namespace: namespace,
creation_timestamp: creation_timestamp,
- manifest: manifest
+ manifest: manifest,
+ is_autodevops: autodevops?,
+ is_enabled: enabled?
}
end
+ def autodevops?
+ return false unless labels
+
+ !labels[:chart].nil? && labels[:chart].start_with?('auto-deploy-app-')
+ end
+
+ # podSelector selects pods that should be targeted by this
+ # policy. We can narrow selection by requiring this policy to
+ # match our custom labels. Since DISABLED_BY label will not be
+ # on any pod a policy will be effectively disabled.
+ def enabled?
+ return true unless pod_selector&.key?(:matchLabels)
+
+ !pod_selector[:matchLabels]&.key?(DISABLED_BY_LABEL)
+ end
+
+ def enable
+ return if enabled?
+
+ pod_selector[:matchLabels].delete(DISABLED_BY_LABEL)
+ end
+
+ def disable
+ @pod_selector ||= {}
+ pod_selector[:matchLabels] ||= {}
+ pod_selector[:matchLabels].merge!(DISABLED_BY_LABEL => 'gitlab')
+ end
+
private
- attr_reader :name, :namespace, :creation_timestamp, :pod_selector, :policy_types, :ingress, :egress
+ attr_reader :name, :namespace, :labels, :creation_timestamp, :pod_selector, :policy_types, :ingress, :egress
def metadata
- { name: name, namespace: namespace }
+ meta = { name: name, namespace: namespace }
+ meta[:labels] = labels if labels
+ meta
end
def spec
diff --git a/lib/gitlab/lfs_token.rb b/lib/gitlab/lfs_token.rb
index e90f3f05a33..c7f2adb27d1 100644
--- a/lib/gitlab/lfs_token.rb
+++ b/lib/gitlab/lfs_token.rb
@@ -14,7 +14,7 @@ module Gitlab
include LfsTokenHelper
- DEFAULT_EXPIRE_TIME = 1800
+ DEFAULT_EXPIRE_TIME = 7200 # Default value 2 hours
attr_accessor :actor
diff --git a/lib/gitlab/lograge/custom_options.rb b/lib/gitlab/lograge/custom_options.rb
index 55c46c365f6..17a36c292c0 100644
--- a/lib/gitlab/lograge/custom_options.rb
+++ b/lib/gitlab/lograge/custom_options.rb
@@ -12,24 +12,24 @@ module Gitlab
params = event
.payload[:params]
.each_with_object([]) { |(k, v), array| array << { key: k, value: v } unless IGNORE_PARAMS.include?(k) }
-
payload = {
time: Time.now.utc.iso8601(3),
params: Gitlab::Utils::LogLimitedArray.log_limited_array(params, sentinel: LIMITED_ARRAY_SENTINEL),
remote_ip: event.payload[:remote_ip],
user_id: event.payload[:user_id],
username: event.payload[:username],
- ua: event.payload[:ua],
- queue_duration_s: event.payload[:queue_duration_s]
+ ua: event.payload[:ua]
}
+ add_db_counters!(payload)
payload.merge!(event.payload[:metadata]) if event.payload[:metadata]
::Gitlab::InstrumentationHelper.add_instrumentation_data(payload)
+ payload[:queue_duration_s] = event.payload[:queue_duration_s] if event.payload[:queue_duration_s]
payload[:response] = event.payload[:response] if event.payload[:response]
payload[:etag_route] = event.payload[:etag_route] if event.payload[:etag_route]
- payload[Labkit::Correlation::CorrelationId::LOG_KEY] = Labkit::Correlation::CorrelationId.current_id
+ payload[Labkit::Correlation::CorrelationId::LOG_KEY] = event.payload[Labkit::Correlation::CorrelationId::LOG_KEY] || Labkit::Correlation::CorrelationId.current_id
if cpu_s = Gitlab::Metrics::System.thread_cpu_duration(::Gitlab::RequestContext.instance.start_thread_cpu_time)
payload[:cpu_s] = cpu_s.round(2)
@@ -46,6 +46,16 @@ module Gitlab
payload
end
+
+ def self.add_db_counters!(payload)
+ current_transaction = Gitlab::Metrics::Transaction.current
+ if current_transaction
+ payload[:db_count] = current_transaction.get(:db_count, :counter).to_i
+ payload[:db_write_count] = current_transaction.get(:db_write_count, :counter).to_i
+ payload[:db_cached_count] = current_transaction.get(:db_cached_count, :counter).to_i
+ end
+ end
+ private_class_method :add_db_counters!
end
end
end
diff --git a/lib/gitlab/looping_batcher.rb b/lib/gitlab/looping_batcher.rb
deleted file mode 100644
index adf0aeda506..00000000000
--- a/lib/gitlab/looping_batcher.rb
+++ /dev/null
@@ -1,99 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- # Returns an ID range within a table so it can be iterated over. Repeats from
- # the beginning after it reaches the end.
- #
- # Used by Geo in particular to iterate over a replicable and its registry
- # table.
- #
- # Tracks a cursor for each table, by "key". If the table is smaller than
- # batch_size, then a range for the whole table is returned on every call.
- class LoopingBatcher
- # @param [Class] model_class the class of the table to iterate on
- # @param [String] key to identify the cursor. Note, cursor is already unique
- # per table.
- # @param [Integer] batch_size to limit the number of records in a batch
- def initialize(model_class, key:, batch_size: 1000)
- @model_class = model_class
- @key = key
- @batch_size = batch_size
- end
-
- # @return [Range] a range of IDs. `nil` if 0 records at or after the cursor.
- def next_range!
- return unless @model_class.any?
-
- batch_first_id = cursor_id
-
- batch_last_id = get_batch_last_id(batch_first_id)
- return unless batch_last_id
-
- batch_first_id..batch_last_id
- end
-
- private
-
- # @private
- #
- # Get the last ID of the batch. Increment the cursor or reset it if at end.
- #
- # @param [Integer] batch_first_id the first ID of the batch
- # @return [Integer] batch_last_id the last ID of the batch (not the table)
- def get_batch_last_id(batch_first_id)
- batch_last_id, more_rows = run_query(@model_class.table_name, @model_class.primary_key, batch_first_id, @batch_size)
-
- if more_rows
- increment_batch(batch_last_id)
- else
- reset if batch_first_id > 1
- end
-
- batch_last_id
- end
-
- def run_query(table, primary_key, batch_first_id, batch_size)
- sql = <<~SQL
- SELECT MAX(batch.id) AS batch_last_id,
- EXISTS (
- SELECT #{primary_key}
- FROM #{table}
- WHERE #{primary_key} > MAX(batch.id)
- ) AS more_rows
- FROM (
- SELECT #{primary_key}
- FROM #{table}
- WHERE #{primary_key} >= #{batch_first_id}
- ORDER BY #{primary_key}
- LIMIT #{batch_size}) AS batch;
- SQL
-
- result = ActiveRecord::Base.connection.exec_query(sql).first
-
- [result["batch_last_id"], result["more_rows"]]
- end
-
- def reset
- set_cursor_id(1)
- end
-
- def increment_batch(batch_last_id)
- set_cursor_id(batch_last_id + 1)
- end
-
- # @private
- #
- # @return [Integer] the cursor ID, or 1 if it is not set
- def cursor_id
- Rails.cache.fetch("#{cache_key}:cursor_id") || 1
- end
-
- def set_cursor_id(id)
- Rails.cache.write("#{cache_key}:cursor_id", id)
- end
-
- def cache_key
- @cache_key ||= "#{self.class.name.parameterize}:#{@model_class.name.parameterize}:#{@key}:cursor_id"
- end
- end
-end
diff --git a/lib/gitlab/metrics/dashboard/stages/url_validator.rb b/lib/gitlab/metrics/dashboard/stages/url_validator.rb
new file mode 100644
index 00000000000..ff36f7b605e
--- /dev/null
+++ b/lib/gitlab/metrics/dashboard/stages/url_validator.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Metrics
+ module Dashboard
+ module Stages
+ class UrlValidator < BaseStage
+ def transform!
+ dashboard[:links]&.each do |link|
+ Gitlab::UrlBlocker.validate!(link[:url])
+ rescue Gitlab::UrlBlocker::BlockedUrlError
+ link[:url] = ''
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/metrics/elasticsearch_rack_middleware.rb b/lib/gitlab/metrics/elasticsearch_rack_middleware.rb
new file mode 100644
index 00000000000..6830eed68d5
--- /dev/null
+++ b/lib/gitlab/metrics/elasticsearch_rack_middleware.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Metrics
+ # Rack middleware for tracking Elasticsearch metrics from Grape and Web requests.
+ class ElasticsearchRackMiddleware
+ HISTOGRAM_BUCKETS = [0.1, 0.25, 0.5, 1, 2.5, 5, 10, 60].freeze
+
+ def initialize(app)
+ @app = app
+
+ @requests_total_counter = Gitlab::Metrics.counter(:http_elasticsearch_requests_total,
+ 'Amount of calls to Elasticsearch servers during web requests',
+ Gitlab::Metrics::Transaction::BASE_LABELS)
+ @requests_duration_histogram = Gitlab::Metrics.histogram(:http_elasticsearch_requests_duration_seconds,
+ 'Query time for Elasticsearch servers during web requests',
+ Gitlab::Metrics::Transaction::BASE_LABELS,
+ HISTOGRAM_BUCKETS)
+ end
+
+ def call(env)
+ transaction = Gitlab::Metrics.current_transaction
+
+ @app.call(env)
+ ensure
+ record_metrics(transaction)
+ end
+
+ private
+
+ def record_metrics(transaction)
+ labels = transaction.labels
+ query_time = ::Gitlab::Instrumentation::ElasticsearchTransport.query_time
+ request_count = ::Gitlab::Instrumentation::ElasticsearchTransport.get_request_count
+
+ @requests_total_counter.increment(labels, request_count)
+ @requests_duration_histogram.observe(labels, query_time)
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/metrics/methods.rb b/lib/gitlab/metrics/methods.rb
index cee601ff14c..5955987541c 100644
--- a/lib/gitlab/metrics/methods.rb
+++ b/lib/gitlab/metrics/methods.rb
@@ -52,7 +52,7 @@ module Gitlab
end
def disabled_by_feature(options)
- options.with_feature && !::Feature.get(options.with_feature).enabled?
+ options.with_feature && !::Feature.enabled?(options.with_feature)
end
def build_metric!(type, name, options)
diff --git a/lib/gitlab/metrics/redis_rack_middleware.rb b/lib/gitlab/metrics/redis_rack_middleware.rb
new file mode 100644
index 00000000000..f0f99c5f45d
--- /dev/null
+++ b/lib/gitlab/metrics/redis_rack_middleware.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Metrics
+ # Rack middleware for tracking Redis metrics from Grape and Web requests.
+ class RedisRackMiddleware
+ def initialize(app)
+ @app = app
+
+ @requests_total_counter = Gitlab::Metrics.counter(:http_redis_requests_total,
+ 'Amount of calls to Redis servers during web requests',
+ Gitlab::Metrics::Transaction::BASE_LABELS)
+ @requests_duration_histogram = Gitlab::Metrics.histogram(:http_redis_requests_duration_seconds,
+ 'Query time for Redis servers during web requests',
+ Gitlab::Metrics::Transaction::BASE_LABELS,
+ Gitlab::Instrumentation::Redis::QUERY_TIME_BUCKETS)
+ end
+
+ def call(env)
+ transaction = Gitlab::Metrics.current_transaction
+
+ @app.call(env)
+ ensure
+ record_metrics(transaction)
+ end
+
+ private
+
+ def record_metrics(transaction)
+ labels = transaction.labels
+ query_time = Gitlab::Instrumentation::Redis.query_time
+ request_count = Gitlab::Instrumentation::Redis.get_request_count
+
+ @requests_total_counter.increment(labels, request_count)
+ @requests_duration_histogram.observe(labels, query_time)
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/metrics/samplers/base_sampler.rb b/lib/gitlab/metrics/samplers/base_sampler.rb
index 90051f85f31..ff3e7be567f 100644
--- a/lib/gitlab/metrics/samplers/base_sampler.rb
+++ b/lib/gitlab/metrics/samplers/base_sampler.rb
@@ -6,8 +6,10 @@ module Gitlab
module Metrics
module Samplers
class BaseSampler < Daemon
+ attr_reader :interval
+
# interval - The sampling interval in seconds.
- def initialize(interval)
+ def initialize(interval = self.class::SAMPLING_INTERVAL_SECONDS)
interval_half = interval.to_f / 2
@interval = interval
diff --git a/lib/gitlab/metrics/samplers/puma_sampler.rb b/lib/gitlab/metrics/samplers/puma_sampler.rb
index 98dd517ee3b..b5343d5e66a 100644
--- a/lib/gitlab/metrics/samplers/puma_sampler.rb
+++ b/lib/gitlab/metrics/samplers/puma_sampler.rb
@@ -4,6 +4,8 @@ module Gitlab
module Metrics
module Samplers
class PumaSampler < BaseSampler
+ SAMPLING_INTERVAL_SECONDS = 5
+
def metrics
@metrics ||= init_metrics
end
diff --git a/lib/gitlab/metrics/samplers/ruby_sampler.rb b/lib/gitlab/metrics/samplers/ruby_sampler.rb
index df59c06911b..dac9fbd1247 100644
--- a/lib/gitlab/metrics/samplers/ruby_sampler.rb
+++ b/lib/gitlab/metrics/samplers/ruby_sampler.rb
@@ -6,9 +6,10 @@ module Gitlab
module Metrics
module Samplers
class RubySampler < BaseSampler
+ SAMPLING_INTERVAL_SECONDS = 60
GC_REPORT_BUCKETS = [0.005, 0.01, 0.02, 0.04, 0.07, 0.1, 0.5].freeze
- def initialize(interval)
+ def initialize(*)
GC::Profiler.clear
metrics[:process_start_time_seconds].set(labels, Time.now.to_i)
diff --git a/lib/gitlab/metrics/sidekiq_middleware.rb b/lib/gitlab/metrics/sidekiq_middleware.rb
index 8dfb61046c4..de8e1ca3256 100644
--- a/lib/gitlab/metrics/sidekiq_middleware.rb
+++ b/lib/gitlab/metrics/sidekiq_middleware.rb
@@ -6,19 +6,30 @@ module Gitlab
#
# This middleware is intended to be used as a server-side middleware.
class SidekiqMiddleware
- def call(worker, message, queue)
+ def call(worker, payload, queue)
trans = BackgroundTransaction.new(worker.class)
begin
# Old gitlad-shell messages don't provide enqueued_at/created_at attributes
- trans.set(:sidekiq_queue_duration, Time.now.to_f - (message['enqueued_at'] || message['created_at'] || 0))
+ enqueued_at = payload['enqueued_at'] || payload['created_at'] || 0
+ trans.set(:sidekiq_queue_duration, Time.current.to_f - enqueued_at)
trans.run { yield }
rescue Exception => error # rubocop: disable Lint/RescueException
trans.add_event(:sidekiq_exception)
raise error
+ ensure
+ add_info_to_payload(payload, trans)
end
end
+
+ private
+
+ def add_info_to_payload(payload, trans)
+ payload[:db_count] = trans.get(:db_count, :counter).to_i
+ payload[:db_write_count] = trans.get(:db_write_count, :counter).to_i
+ payload[:db_cached_count] = trans.get(:db_cached_count, :counter).to_i
+ end
end
end
end
diff --git a/lib/gitlab/metrics/subscribers/active_record.rb b/lib/gitlab/metrics/subscribers/active_record.rb
index a02dd850582..1628eeb5a95 100644
--- a/lib/gitlab/metrics/subscribers/active_record.rb
+++ b/lib/gitlab/metrics/subscribers/active_record.rb
@@ -9,6 +9,7 @@ module Gitlab
attach_to :active_record
IGNORABLE_SQL = %w{BEGIN COMMIT}.freeze
+ DB_COUNTERS = %i{db_count db_write_count db_cached_count}.freeze
def sql(event)
return unless current_transaction
@@ -19,8 +20,7 @@ module Gitlab
self.class.gitlab_sql_duration_seconds.observe(current_transaction.labels, event.duration / 1000.0)
- current_transaction.increment(:sql_duration, event.duration, false)
- current_transaction.increment(:sql_count, 1, false)
+ increment_db_counters(payload)
end
private
@@ -31,6 +31,20 @@ module Gitlab
buckets [0.01, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0]
end
+ def select_sql_command?(payload)
+ payload[:sql].match(/\A((?!(.*[^\w'"](DELETE|UPDATE|INSERT INTO)[^\w'"])))(WITH.*)?(SELECT)((?!(FOR UPDATE|FOR SHARE)).)*$/i)
+ end
+
+ def increment_db_counters(payload)
+ current_transaction.increment(:db_count, 1)
+
+ if payload.fetch(:cached, payload[:name] == 'CACHE')
+ current_transaction.increment(:db_cached_count, 1)
+ end
+
+ current_transaction.increment(:db_write_count, 1) unless select_sql_command?(payload)
+ end
+
def current_transaction
Transaction.current
end
diff --git a/lib/gitlab/metrics/transaction.rb b/lib/gitlab/metrics/transaction.rb
index b126efd2dd5..822f5243e9d 100644
--- a/lib/gitlab/metrics/transaction.rb
+++ b/lib/gitlab/metrics/transaction.rb
@@ -16,7 +16,7 @@ module Gitlab
# The series to store events (e.g. Git pushes) in.
EVENT_SERIES = 'events'
- attr_reader :tags, :method
+ attr_reader :method
def self.current
Thread.current[THREAD_KEY]
@@ -28,8 +28,6 @@ module Gitlab
@started_at = nil
@finished_at = nil
- @tags = {}
-
@memory_before = 0
@memory_after = 0
end
@@ -94,6 +92,12 @@ module Gitlab
self.class.transaction_metric(name, :gauge).set(labels, value) if use_prometheus
end
+ def get(name, type, tags = {})
+ metric = self.class.transaction_metric(name, type)
+
+ metric.get(filter_tags(tags).merge(labels))
+ end
+
def labels
BASE_LABELS
end
diff --git a/lib/gitlab/middleware/handle_ip_spoof_attack_error.rb b/lib/gitlab/middleware/handle_ip_spoof_attack_error.rb
new file mode 100644
index 00000000000..2fc08db9b4d
--- /dev/null
+++ b/lib/gitlab/middleware/handle_ip_spoof_attack_error.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Middleware
+ # ActionDispatch::RemoteIp tries to set the `request.ip` for controllers by
+ # looking at the request IP and headers. It needs to see through any reverse
+ # proxies to get the right answer, but there are some security issues with
+ # that.
+ #
+ # Proxies can specify `Client-Ip` or `X-Forwarded-For`, and the security of
+ # that is determined at the edge. If both headers are present, it's likely
+ # that the edge is securing one, but ignoring the other. Rails blocks this,
+ # which is correct, because we don't know which header is the safe one - but
+ # we want the block to be a 400, rather than 500, error.
+ #
+ # This middleware needs to go before ActionDispatch::RemoteIp in the chain.
+ class HandleIpSpoofAttackError
+ attr_reader :app
+
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ app.call(env)
+ rescue ActionDispatch::RemoteIp::IpSpoofAttackError => err
+ Gitlab::ErrorTracking.track_exception(err)
+
+ [400, { 'Content-Type' => 'text/plain' }, ['Bad Request']]
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/monitor/demo_projects.rb b/lib/gitlab/monitor/demo_projects.rb
new file mode 100644
index 00000000000..c617f895e4c
--- /dev/null
+++ b/lib/gitlab/monitor/demo_projects.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Monitor
+ # See Demo Project documentation
+ # https://about.gitlab.com/handbook/engineering/development/ops/monitor/#demo-environments
+ module DemoProjects
+ # [https://gitlab.com/gitlab-org/monitor/tanuki-inc, https://gitlab.com/gitlab-org/monitor/monitor-sandbox]
+ DOT_COM_IDS = [14986497, 12507547].freeze
+ # [https://staging.gitlab.com/gitlab-org/monitor/monitor-sandbox]
+ STAGING_IDS = [4422333].freeze
+
+ def self.primary_keys
+ # .com? returns true for staging
+ if ::Gitlab.com? && !::Gitlab.staging?
+ DOT_COM_IDS
+ elsif ::Gitlab.staging?
+ STAGING_IDS
+ elsif ::Gitlab.dev_or_test_env?
+ Project.limit(100).pluck(:id) # rubocop: disable CodeReuse/ActiveRecord
+ else
+ []
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/pagination/keyset/request_context.rb b/lib/gitlab/pagination/keyset/request_context.rb
index 8c8138b3076..070fa844347 100644
--- a/lib/gitlab/pagination/keyset/request_context.rb
+++ b/lib/gitlab/pagination/keyset/request_context.rb
@@ -24,7 +24,9 @@ module Gitlab
end
def apply_headers(next_page)
- request.header('Links', pagination_links(next_page))
+ link = pagination_links(next_page)
+ request.header('Links', link)
+ request.header('Link', link)
end
private
diff --git a/lib/gitlab/pagination/offset_pagination.rb b/lib/gitlab/pagination/offset_pagination.rb
index 11a5ef4e518..8796dd4d7ec 100644
--- a/lib/gitlab/pagination/offset_pagination.rb
+++ b/lib/gitlab/pagination/offset_pagination.rb
@@ -19,7 +19,13 @@ module Gitlab
private
def paginate_with_limit_optimization(relation)
- pagination_data = relation.page(params[:page]).per(params[:per_page])
+ # do not paginate relation if it is already paginated
+ pagination_data = if relation.respond_to?(:current_page) && relation.current_page == params[:page] && relation.limit_value == params[:per_page]
+ relation
+ else
+ relation.page(params[:page]).per(params[:per_page])
+ end
+
return pagination_data unless pagination_data.is_a?(ActiveRecord::Relation)
return pagination_data unless Feature.enabled?(:api_kaminari_count_with_limit)
diff --git a/lib/gitlab/phabricator_import/cache/map.rb b/lib/gitlab/phabricator_import/cache/map.rb
index 6a2841b6a8e..7aba3cf26fd 100644
--- a/lib/gitlab/phabricator_import/cache/map.rb
+++ b/lib/gitlab/phabricator_import/cache/map.rb
@@ -63,7 +63,7 @@ module Gitlab
def timeout
# Setting the timeout to the same one as we do for clearing stuck jobs
# this makes sure all cache is available while the import is running.
- StuckImportJobsWorker::IMPORT_JOBS_EXPIRATION
+ Gitlab::Import::StuckImportJob::IMPORT_JOBS_EXPIRATION
end
end
end
diff --git a/lib/gitlab/phabricator_import/worker_state.rb b/lib/gitlab/phabricator_import/worker_state.rb
index 38829e34509..ffa2d3d7a43 100644
--- a/lib/gitlab/phabricator_import/worker_state.rb
+++ b/lib/gitlab/phabricator_import/worker_state.rb
@@ -40,7 +40,7 @@ module Gitlab
def timeout
# Make sure we get rid of all the information after a job is marked
# as failed/succeeded
- StuckImportJobsWorker::IMPORT_JOBS_EXPIRATION
+ Gitlab::Import::StuckImportJob::IMPORT_JOBS_EXPIRATION
end
end
end
diff --git a/lib/gitlab/process_memory_cache/helper.rb b/lib/gitlab/process_memory_cache/helper.rb
new file mode 100644
index 00000000000..ee4b81a9a19
--- /dev/null
+++ b/lib/gitlab/process_memory_cache/helper.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+module Gitlab
+ class ProcessMemoryCache
+ module Helper
+ def fetch_memory_cache(key, &payload)
+ cache = cache_backend.read(key)
+
+ if cache && !stale_cache?(key, cache)
+ cache[:data]
+ else
+ store_cache(key, &payload)
+ end
+ end
+
+ def invalidate_memory_cache(key)
+ touch_cache_timestamp(key)
+ end
+
+ private
+
+ def touch_cache_timestamp(key, time = Time.current.to_f)
+ shared_backend.write(key, time)
+ end
+
+ def stale_cache?(key, cache_info)
+ shared_timestamp = shared_backend.read(key)
+ return true unless shared_timestamp
+
+ shared_timestamp.to_f > cache_info[:cached_at].to_f
+ end
+
+ def store_cache(key)
+ data = yield
+ time = Time.current.to_f
+
+ cache_backend.write(key, data: data, cached_at: time)
+ touch_cache_timestamp(key, time)
+ data
+ end
+
+ def shared_backend
+ Rails.cache
+ end
+
+ def cache_backend
+ ::Gitlab::ProcessMemoryCache.cache_backend
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/project_search_results.rb b/lib/gitlab/project_search_results.rb
index fbdfe166645..e6b25e71eb3 100644
--- a/lib/gitlab/project_search_results.rb
+++ b/lib/gitlab/project_search_results.rb
@@ -11,7 +11,7 @@ module Gitlab
@query = query
end
- def objects(scope, page: nil, per_page: DEFAULT_PER_PAGE)
+ def objects(scope, page: nil, per_page: DEFAULT_PER_PAGE, preload_method: nil)
case scope
when 'notes'
notes.page(page).per(per_page)
@@ -20,7 +20,7 @@ module Gitlab
when 'wiki_blobs'
paginated_wiki_blobs(wiki_blobs(limit: limit_up_to_page(page, per_page)), page, per_page)
when 'commits'
- Kaminari.paginate_array(commits).page(page).per(per_page)
+ paginated_commits(page, per_page)
when 'users'
users.page(page).per(per_page)
else
@@ -37,7 +37,7 @@ module Gitlab
when 'wiki_blobs'
wiki_blobs_count.to_s
when 'commits'
- commits_count.to_s
+ formatted_limited_count(commits_count)
else
super
end
@@ -72,7 +72,7 @@ module Gitlab
end
def commits_count
- @commits_count ||= commits.count
+ @commits_count ||= commits(limit: count_limit).count
end
def single_commit_result?
@@ -86,6 +86,12 @@ module Gitlab
private
+ def paginated_commits(page, per_page)
+ results = commits(limit: limit_up_to_page(page, per_page))
+
+ Kaminari.paginate_array(results).page(page).per(per_page)
+ end
+
def paginated_blobs(blobs, page, per_page)
results = Kaminari.paginate_array(blobs).page(page).per(per_page)
@@ -139,21 +145,21 @@ module Gitlab
end
# rubocop: enable CodeReuse/ActiveRecord
- def commits
- @commits ||= find_commits(query)
+ def commits(limit:)
+ @commits ||= find_commits(query, limit: limit)
end
- def find_commits(query)
+ def find_commits(query, limit:)
return [] unless Ability.allowed?(@current_user, :download_code, @project)
- commits = find_commits_by_message(query)
+ commits = find_commits_by_message(query, limit: limit)
commit_by_sha = find_commit_by_sha(query)
commits |= [commit_by_sha] if commit_by_sha
commits
end
- def find_commits_by_message(query)
- project.repository.find_commits_by_message(query)
+ def find_commits_by_message(query, limit:)
+ project.repository.find_commits_by_message(query, repository_project_ref, nil, limit)
end
def find_commit_by_sha(query)
diff --git a/lib/gitlab/project_template.rb b/lib/gitlab/project_template.rb
index 38adfc03ea7..fdb3fbc03bc 100644
--- a/lib/gitlab/project_template.rb
+++ b/lib/gitlab/project_template.rb
@@ -44,13 +44,13 @@ module Gitlab
ProjectTemplate.new('iosswift', 'iOS (Swift)', _('A ready-to-go template for use with iOS Swift apps.'), 'https://gitlab.com/gitlab-org/project-templates/iosswift', 'illustrations/logos/swift.svg'),
ProjectTemplate.new('dotnetcore', '.NET Core', _('A .NET Core console application template, customizable for any .NET Core project'), 'https://gitlab.com/gitlab-org/project-templates/dotnetcore', 'illustrations/logos/dotnet.svg'),
ProjectTemplate.new('android', 'Android', _('A ready-to-go template for use with Android apps.'), 'https://gitlab.com/gitlab-org/project-templates/android', 'illustrations/logos/android.svg'),
- ProjectTemplate.new('gomicro', 'Go Micro', _('Go Micro is a framework for micro service development.'), 'https://gitlab.com/gitlab-org/project-templates/go-micro'),
+ ProjectTemplate.new('gomicro', 'Go Micro', _('Go Micro is a framework for micro service development.'), 'https://gitlab.com/gitlab-org/project-templates/go-micro', 'illustrations/logos/gomicro.svg'),
ProjectTemplate.new('gatsby', 'Pages/Gatsby', _('Everything you need to create a GitLab Pages site using Gatsby.'), 'https://gitlab.com/pages/gatsby'),
- ProjectTemplate.new('hugo', 'Pages/Hugo', _('Everything you need to create a GitLab Pages site using Hugo.'), 'https://gitlab.com/pages/hugo'),
- ProjectTemplate.new('jekyll', 'Pages/Jekyll', _('Everything you need to create a GitLab Pages site using Jekyll.'), 'https://gitlab.com/pages/jekyll'),
+ ProjectTemplate.new('hugo', 'Pages/Hugo', _('Everything you need to create a GitLab Pages site using Hugo.'), 'https://gitlab.com/pages/hugo', 'illustrations/logos/hugo.svg'),
+ ProjectTemplate.new('jekyll', 'Pages/Jekyll', _('Everything you need to create a GitLab Pages site using Jekyll.'), 'https://gitlab.com/pages/jekyll', 'illustrations/logos/jekyll.svg'),
ProjectTemplate.new('plainhtml', 'Pages/Plain HTML', _('Everything you need to create a GitLab Pages site using plain HTML.'), 'https://gitlab.com/pages/plain-html'),
- ProjectTemplate.new('gitbook', 'Pages/GitBook', _('Everything you need to create a GitLab Pages site using GitBook.'), 'https://gitlab.com/pages/gitbook'),
- ProjectTemplate.new('hexo', 'Pages/Hexo', _('Everything you need to create a GitLab Pages site using Hexo.'), 'https://gitlab.com/pages/hexo'),
+ ProjectTemplate.new('gitbook', 'Pages/GitBook', _('Everything you need to create a GitLab Pages site using GitBook.'), 'https://gitlab.com/pages/gitbook', 'illustrations/logos/gitbook.svg'),
+ ProjectTemplate.new('hexo', 'Pages/Hexo', _('Everything you need to create a GitLab Pages site using Hexo.'), 'https://gitlab.com/pages/hexo', 'illustrations/logos/hexo.svg'),
ProjectTemplate.new('sse_middleman', 'Static Site Editor/Middleman', _('Middleman project with Static Site Editor support'), 'https://gitlab.com/gitlab-org/project-templates/static-site-editor-middleman'),
ProjectTemplate.new('nfhugo', 'Netlify/Hugo', _('A Hugo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features.'), 'https://gitlab.com/pages/nfhugo', 'illustrations/logos/netlify.svg'),
ProjectTemplate.new('nfjekyll', 'Netlify/Jekyll', _('A Jekyll site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features.'), 'https://gitlab.com/pages/nfjekyll', 'illustrations/logos/netlify.svg'),
diff --git a/lib/gitlab/prometheus/query_variables.rb b/lib/gitlab/prometheus/query_variables.rb
index 4d48c4a3af7..5b688f83545 100644
--- a/lib/gitlab/prometheus/query_variables.rb
+++ b/lib/gitlab/prometheus/query_variables.rb
@@ -3,8 +3,10 @@
module Gitlab
module Prometheus
module QueryVariables
- def self.call(environment)
+ # start_time and end_time should be Time objects.
+ def self.call(environment, start_time: nil, end_time: nil)
{
+ __range: range(start_time, end_time),
ci_environment_slug: environment.slug,
kube_namespace: environment.deployment_namespace || '',
environment_filter: %{container_name!="POD",environment="#{environment.slug}"},
@@ -14,6 +16,16 @@ module Gitlab
ci_environment_name: environment.name
}
end
+
+ private
+
+ def self.range(start_time, end_time)
+ if start_time && end_time
+ range_seconds = (end_time - start_time).to_i
+ "#{range_seconds}s"
+ end
+ end
+ private_class_method :range
end
end
end
diff --git a/lib/gitlab/prometheus_client.rb b/lib/gitlab/prometheus_client.rb
index b03d8a4d254..213e3ba835d 100644
--- a/lib/gitlab/prometheus_client.rb
+++ b/lib/gitlab/prometheus_client.rb
@@ -71,6 +71,19 @@ module Gitlab
end
end
+ # Queries Prometheus with the given aggregate query and groups the results by mapping
+ # metric labels to their respective values.
+ #
+ # @return [Hash] mapping labels to their aggregate numeric values, or the empty hash if no results were found
+ def aggregate(aggregate_query, time: Time.now)
+ response = query(aggregate_query, time: time)
+ response.to_h do |result|
+ key = block_given? ? yield(result['metric']) : result['metric']
+ _timestamp, value = result['value']
+ [key, value.to_i]
+ end
+ end
+
def label_values(name = '__name__')
json_api_get("label/#{name}/values")
end
diff --git a/lib/gitlab/quick_actions/merge_request_actions.rb b/lib/gitlab/quick_actions/merge_request_actions.rb
index 7c06698ffec..98db8ff761e 100644
--- a/lib/gitlab/quick_actions/merge_request_actions.rb
+++ b/lib/gitlab/quick_actions/merge_request_actions.rb
@@ -104,6 +104,23 @@ module Gitlab
command :target_branch do |branch_name|
@updates[:target_branch] = branch_name if project.repository.branch_exists?(branch_name)
end
+
+ desc _('Submit a review')
+ explanation _('Submit the current review.')
+ types MergeRequest
+ condition do
+ quick_action_target.persisted?
+ end
+ command :submit_review do
+ next if params[:review_id]
+
+ result = DraftNotes::PublishService.new(quick_action_target, current_user).execute
+ @execution_message[:submit_review] = if result[:status] == :success
+ _('Submitted the current review.')
+ else
+ result[:message]
+ end
+ end
end
def merge_orchestration_service
diff --git a/lib/gitlab/redis/cache.rb b/lib/gitlab/redis/cache.rb
index 6e31c506438..a634f12345a 100644
--- a/lib/gitlab/redis/cache.rb
+++ b/lib/gitlab/redis/cache.rb
@@ -27,6 +27,10 @@ module Gitlab
# this will force use of DEFAULT_REDIS_QUEUES_URL when config file is absent
super
end
+
+ def instrumentation_class
+ ::Gitlab::Instrumentation::Redis::Cache
+ end
end
end
end
diff --git a/lib/gitlab/redis/queues.rb b/lib/gitlab/redis/queues.rb
index 0375e4a221a..42d5167beb3 100644
--- a/lib/gitlab/redis/queues.rb
+++ b/lib/gitlab/redis/queues.rb
@@ -28,6 +28,10 @@ module Gitlab
# this will force use of DEFAULT_REDIS_QUEUES_URL when config file is absent
super
end
+
+ def instrumentation_class
+ ::Gitlab::Instrumentation::Redis::Queues
+ end
end
end
end
diff --git a/lib/gitlab/redis/shared_state.rb b/lib/gitlab/redis/shared_state.rb
index 35356083f26..8ab53700932 100644
--- a/lib/gitlab/redis/shared_state.rb
+++ b/lib/gitlab/redis/shared_state.rb
@@ -30,6 +30,10 @@ module Gitlab
# this will force use of DEFAULT_REDIS_SHARED_STATE_URL when config file is absent
super
end
+
+ def instrumentation_class
+ ::Gitlab::Instrumentation::Redis::SharedState
+ end
end
end
end
diff --git a/lib/gitlab/redis/wrapper.rb b/lib/gitlab/redis/wrapper.rb
index 06ee81ba172..5584323789b 100644
--- a/lib/gitlab/redis/wrapper.rb
+++ b/lib/gitlab/redis/wrapper.rb
@@ -71,6 +71,10 @@ module Gitlab
# nil will force use of DEFAULT_REDIS_URL when config file is absent
nil
end
+
+ def instrumentation_class
+ raise NotImplementedError
+ end
end
def initialize(rails_env = nil)
@@ -100,6 +104,8 @@ module Gitlab
redis_url = config.delete(:url)
redis_uri = URI.parse(redis_url)
+ config[:instrumentation_class] ||= self.class.instrumentation_class
+
if redis_uri.scheme == 'unix'
# Redis::Store does not handle Unix sockets well, so let's do it for them
config[:path] = redis_uri.path
diff --git a/lib/gitlab/reference_extractor.rb b/lib/gitlab/reference_extractor.rb
index d07d6440c6b..01aff48b08b 100644
--- a/lib/gitlab/reference_extractor.rb
+++ b/lib/gitlab/reference_extractor.rb
@@ -4,7 +4,7 @@ module Gitlab
# Extract possible GFM references from an arbitrary String for further processing.
class ReferenceExtractor < Banzai::ReferenceExtractor
REFERABLES = %i(user issue label milestone mentioned_user mentioned_group mentioned_project
- merge_request snippet commit commit_range directly_addressed_user epic).freeze
+ merge_request snippet commit commit_range directly_addressed_user epic iteration).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
diff --git a/lib/gitlab/regex.rb b/lib/gitlab/regex.rb
index c8b04ce2a5c..4caff8ae679 100644
--- a/lib/gitlab/regex.rb
+++ b/lib/gitlab/regex.rb
@@ -2,7 +2,93 @@
module Gitlab
module Regex
+ module Packages
+ CONAN_RECIPE_FILES = %w[conanfile.py conanmanifest.txt].freeze
+ CONAN_PACKAGE_FILES = %w[conaninfo.txt conanmanifest.txt conan_package.tgz].freeze
+
+ def conan_file_name_regex
+ @conan_file_name_regex ||=
+ %r{\A#{(CONAN_RECIPE_FILES + CONAN_PACKAGE_FILES).join("|")}\z}.freeze
+ end
+
+ def conan_package_reference_regex
+ @conan_package_reference_regex ||= %r{\A[A-Za-z0-9]+\z}.freeze
+ end
+
+ def conan_revision_regex
+ @conan_revision_regex ||= %r{\A0\z}.freeze
+ end
+
+ def conan_recipe_component_regex
+ @conan_recipe_component_regex ||= %r{\A[a-zA-Z0-9_][a-zA-Z0-9_\+\.-]{1,49}\z}.freeze
+ end
+
+ def composer_package_version_regex
+ @composer_package_version_regex ||= %r{^v?(\d+(\.(\d+|x))*(-.+)?)}.freeze
+ end
+
+ def package_name_regex
+ @package_name_regex ||= %r{\A\@?(([\w\-\.\+]*)\/)*([\w\-\.]+)@?(([\w\-\.\+]*)\/)*([\w\-\.]*)\z}.freeze
+ end
+
+ def maven_file_name_regex
+ @maven_file_name_regex ||= %r{\A[A-Za-z0-9\.\_\-\+]+\z}.freeze
+ end
+
+ def maven_path_regex
+ @maven_path_regex ||= %r{\A\@?(([\w\-\.]*)/)*([\w\-\.\+]*)\z}.freeze
+ end
+
+ def maven_app_name_regex
+ @maven_app_name_regex ||= /\A[\w\-\.]+\z/.freeze
+ end
+
+ def maven_app_group_regex
+ maven_app_name_regex
+ end
+
+ def unbounded_semver_regex
+ # See the official regex: https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
+
+ # The order of the alternatives in <prerelease> are intentionally
+ # reordered to be greedy. Without this change, the unbounded regex would
+ # only partially match "v0.0.0-20201230123456-abcdefabcdef".
+ @unbounded_semver_regex ||= /
+ (?<major>0|[1-9]\d*)
+ \.(?<minor>0|[1-9]\d*)
+ \.(?<patch>0|[1-9]\d*)
+ (?:-(?<prerelease>(?:\d*[a-zA-Z-][0-9a-zA-Z-]*|[1-9]\d*|0)(?:\.(?:\d*[a-zA-Z-][0-9a-zA-Z-]*|[1-9]\d*|0))*))?
+ (?:\+(?<build>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?
+ /x.freeze
+ end
+
+ def semver_regex
+ @semver_regex ||= Regexp.new("\\A#{::Gitlab::Regex.unbounded_semver_regex.source}\\z", ::Gitlab::Regex.unbounded_semver_regex.options)
+ end
+
+ def go_package_regex
+ # A Go package name looks like a URL but is not; it:
+ # - Must not have a scheme, such as http:// or https://
+ # - Must not have a port number, such as :8080 or :8443
+
+ @go_package_regex ||= /
+ \b (?# word boundary)
+ (?<domain>
+ [0-9a-z](?:(?:-|[0-9a-z]){0,61}[0-9a-z])? (?# first domain)
+ (?:\.[0-9a-z](?:(?:-|[0-9a-z]){0,61}[0-9a-z])?)* (?# inner domains)
+ \.[a-z]{2,} (?# top-level domain)
+ )
+ (?<path>\/(?:
+ [-\/$_.+!*'(),0-9a-z] (?# plain URL character)
+ | %[0-9a-f]{2})* (?# URL encoded character)
+ )? (?# path)
+ \b (?# word boundary)
+ /ix.freeze
+ end
+ end
+
extend self
+ extend Packages
def project_name_regex
# The character range \p{Alnum} overlaps with \u{00A9}-\u{1f9ff}
@@ -163,6 +249,10 @@ module Gitlab
def issue
@issue ||= /(?<issue>\d+\b)/
end
+
+ def base64_regex
+ @base64_regex ||= /(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?/.freeze
+ end
end
end
diff --git a/lib/gitlab/routing.rb b/lib/gitlab/routing.rb
index 84885be9bda..cad127922df 100644
--- a/lib/gitlab/routing.rb
+++ b/lib/gitlab/routing.rb
@@ -4,6 +4,36 @@ module Gitlab
module Routing
extend ActiveSupport::Concern
+ class LegacyRedirector
+ # @params path_type [symbol] type of path to do "-" redirection
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/16854
+ def initialize(path_type)
+ @path_type = path_type
+ end
+
+ def call(_params, request)
+ ensure_valid_uri!(request)
+
+ # Only replace the last occurrence of `path`.
+ #
+ # `request.fullpath` includes the querystring
+ new_path = request.path.sub(%r{/#{@path_type}(/*)(?!.*#{@path_type})}, "/-/#{@path_type}\\1")
+ new_path = "#{new_path}?#{request.query_string}" if request.query_string.present?
+
+ new_path
+ end
+
+ private
+
+ def ensure_valid_uri!(request)
+ URI.parse(request.path)
+ rescue URI::InvalidURIError => e
+ # If url is invalid, raise custom error,
+ # which can be ignored by monitoring tools.
+ raise ActionController::RoutingError.new(e.message)
+ end
+ end
+
mattr_accessor :_includers
self._includers = []
@@ -44,20 +74,10 @@ module Gitlab
end
def self.redirect_legacy_paths(router, *paths)
- build_redirect_path = lambda do |request, _params, path|
- # Only replace the last occurrence of `path`.
- #
- # `request.fullpath` includes the querystring
- new_path = request.path.sub(%r{/#{path}(/*)(?!.*#{path})}, "/-/#{path}\\1")
- new_path = "#{new_path}?#{request.query_string}" if request.query_string.present?
-
- new_path
- end
-
paths.each do |path|
router.match "/#{path}(/*rest)",
via: [:get, :post, :patch, :delete],
- to: router.redirect { |params, request| build_redirect_path.call(request, params, path) },
+ to: router.redirect(LegacyRedirector.new(path)),
as: "legacy_#{path}_redirect"
end
end
diff --git a/lib/gitlab/rugged_instrumentation.rb b/lib/gitlab/rugged_instrumentation.rb
index 9a5917ffba9..36a3a491de6 100644
--- a/lib/gitlab/rugged_instrumentation.rb
+++ b/lib/gitlab/rugged_instrumentation.rb
@@ -3,12 +3,13 @@
module Gitlab
module RuggedInstrumentation
def self.query_time
- query_time = SafeRequestStore[:rugged_query_time] ||= 0
+ query_time = SafeRequestStore[:rugged_query_time] || 0
query_time.round(Gitlab::InstrumentationHelper::DURATION_PRECISION)
end
- def self.query_time=(duration)
- SafeRequestStore[:rugged_query_time] = duration
+ def self.add_query_time(duration)
+ SafeRequestStore[:rugged_query_time] ||= 0
+ SafeRequestStore[:rugged_query_time] += duration
end
def self.query_time_ms
diff --git a/lib/gitlab/search_context.rb b/lib/gitlab/search_context.rb
new file mode 100644
index 00000000000..c3bb0ff26f2
--- /dev/null
+++ b/lib/gitlab/search_context.rb
@@ -0,0 +1,162 @@
+# frozen_string_literal: true
+
+module Gitlab
+ # Holds the contextual data used by navbar search component to
+ # determine the search scope, whether to search for code, or if
+ # a search should target snippets.
+ #
+ # Use the SearchContext::Builder to create an instance of this class
+ class SearchContext
+ attr_accessor :project, :project_metadata, :ref,
+ :group, :group_metadata,
+ :snippets,
+ :scope, :search_url
+
+ def initialize
+ @ref = nil
+ @project = nil
+ @project_metadata = {}
+ @group = nil
+ @group_metadata = {}
+ @snippets = []
+ @scope = nil
+ @search_url = nil
+ end
+
+ def for_project?
+ project.present? && project.persisted?
+ end
+
+ def for_group?
+ group.present? && group.persisted?
+ end
+
+ def for_snippets?
+ snippets.any?
+ end
+
+ def code_search?
+ project.present? && scope.nil?
+ end
+
+ class Builder
+ def initialize(view_context)
+ @view_context = view_context
+ @snippets = []
+ end
+
+ def with_snippet(snippet)
+ @snippets << snippet
+
+ self
+ end
+
+ def with_project(project)
+ @project = project
+ with_group(project&.group)
+
+ self
+ end
+
+ def with_group(group)
+ @group = group
+
+ self
+ end
+
+ def with_ref(ref)
+ @ref = ref
+
+ self
+ end
+
+ def build!
+ SearchContext.new.tap do |context|
+ context.project = @project
+ context.group = @group
+ context.ref = @ref
+ context.snippets = @snippets.dup
+ context.scope = search_scope
+ context.search_url = search_url
+ context.group_metadata = group_search_metadata(@group)
+ context.project_metadata = project_search_metadata(@project)
+ end
+ end
+
+ private
+
+ attr_accessor :view_context
+
+ def project_search_metadata(project)
+ return {} unless project
+
+ {
+ project_path: project.path,
+ name: project.name,
+ issues_path: view_context.project_issues_path(project),
+ mr_path: view_context.project_merge_requests_path(project),
+ issues_disabled: !project.issues_enabled?
+ }
+ end
+
+ def group_search_metadata(group)
+ return {} unless group
+
+ {
+ group_path: group.path,
+ name: group.name,
+ issues_path: view_context.issues_group_path(group),
+ mr_path: view_context.merge_requests_group_path(group)
+ }
+ end
+
+ def search_url
+ if @project.present?
+ view_context.search_path(project_id: @project.id)
+ elsif @group.present?
+ view_context.search_path(group_id: @group.id)
+ else
+ view_context.search_path
+ end
+ end
+
+ def search_scope
+ if view_context.current_controller?(:issues)
+ 'issues'
+ elsif view_context.current_controller?(:merge_requests)
+ 'merge_requests'
+ elsif view_context.current_controller?(:wikis)
+ 'wiki_blobs'
+ elsif view_context.current_controller?(:commits)
+ 'commits'
+ else nil
+ end
+ end
+ end
+
+ module ControllerConcern
+ extend ActiveSupport::Concern
+
+ included do
+ helper_method :search_context
+ end
+
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ #
+ # Introspect the current controller's assignments and
+ # and builds the proper SearchContext object for it.
+ def search_context
+ builder = Builder.new(view_context)
+
+ builder.with_snippet(@snippet) if @snippet.present?
+ @snippets.each(&builder.method(:with_snippet)) if @snippets.present?
+ builder.with_project(@project) if @project.present? && @project.persisted?
+ builder.with_group(@group) if @group.present? && @group.persisted?
+ builder.with_ref(@ref) if @ref.present?
+
+ builder.build!
+ end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
+ end
+ end
+end
diff --git a/lib/gitlab/search_results.rb b/lib/gitlab/search_results.rb
index c35ee62163a..6239158ef06 100644
--- a/lib/gitlab/search_results.rb
+++ b/lib/gitlab/search_results.rb
@@ -26,7 +26,7 @@ module Gitlab
@default_project_filter = default_project_filter
end
- def objects(scope, page: nil, per_page: DEFAULT_PER_PAGE, without_count: true)
+ def objects(scope, page: nil, per_page: DEFAULT_PER_PAGE, without_count: true, preload_method: nil)
collection = case scope
when 'projects'
projects
diff --git a/lib/gitlab/setup_helper.rb b/lib/gitlab/setup_helper.rb
index 3f36725cb66..64a30fbe16c 100644
--- a/lib/gitlab/setup_helper.rb
+++ b/lib/gitlab/setup_helper.rb
@@ -79,6 +79,7 @@ module Gitlab
config[:'gitaly-ruby'] = { dir: File.join(gitaly_dir, 'ruby') } if gitaly_ruby
config[:'gitlab-shell'] = { dir: Gitlab.config.gitlab_shell.path }
config[:bin_dir] = Gitlab.config.gitaly.client_path
+ config[:gitlab] = { url: Gitlab.config.gitlab.url }
TomlRB.dump(config)
end
@@ -97,7 +98,8 @@ module Gitlab
def configuration_toml(gitaly_dir, storage_paths)
nodes = [{ storage: 'default', address: "unix:#{gitaly_dir}/gitaly.socket", primary: true, token: 'secret' }]
storages = [{ name: 'default', node: nodes }]
- config = { socket_path: "#{gitaly_dir}/praefect.socket", virtual_storage: storages }
+ failover = { enabled: false }
+ config = { socket_path: "#{gitaly_dir}/praefect.socket", memory_queue_enabled: true, virtual_storage: storages, failover: failover }
config[:token] = 'secret' if Rails.env.test?
TomlRB.dump(config)
diff --git a/lib/gitlab/sidekiq_config.rb b/lib/gitlab/sidekiq_config.rb
index 4e0d3da1868..633291dcdf3 100644
--- a/lib/gitlab/sidekiq_config.rb
+++ b/lib/gitlab/sidekiq_config.rb
@@ -14,8 +14,8 @@ module Gitlab
].compact.freeze
DEFAULT_WORKERS = [
- DummyWorker.new('default', weight: 1),
- DummyWorker.new('mailers', weight: 2)
+ DummyWorker.new('default', weight: 1, tags: []),
+ DummyWorker.new('mailers', weight: 2, tags: [])
].map { |worker| Gitlab::SidekiqConfig::Worker.new(worker, ee: false) }.freeze
class << self
diff --git a/lib/gitlab/sidekiq_config/cli_methods.rb b/lib/gitlab/sidekiq_config/cli_methods.rb
index 0d0efe8ffbd..a256632bc12 100644
--- a/lib/gitlab/sidekiq_config/cli_methods.rb
+++ b/lib/gitlab/sidekiq_config/cli_methods.rb
@@ -28,6 +28,7 @@ module Gitlab
has_external_dependencies: lambda { |value| value == 'true' },
name: :to_s,
resource_boundary: :to_sym,
+ tags: :to_sym,
urgency: :to_sym
}.freeze
@@ -117,7 +118,11 @@ module Gitlab
raise UnknownPredicate.new("Unknown predicate: #{lhs}") unless values_block
- lambda { |queue| values.map(&values_block).include?(queue[lhs.to_sym]) }
+ lambda do |queue|
+ comparator = Array(queue[lhs.to_sym]).to_set
+
+ values.map(&values_block).to_set.intersect?(comparator)
+ end
end
end
end
diff --git a/lib/gitlab/sidekiq_config/dummy_worker.rb b/lib/gitlab/sidekiq_config/dummy_worker.rb
index bd205c81931..7568840410b 100644
--- a/lib/gitlab/sidekiq_config/dummy_worker.rb
+++ b/lib/gitlab/sidekiq_config/dummy_worker.rb
@@ -12,7 +12,8 @@ module Gitlab
urgency: :get_urgency,
resource_boundary: :get_worker_resource_boundary,
idempotent: :idempotent?,
- weight: :get_weight
+ weight: :get_weight,
+ tags: :get_tags
}.freeze
def initialize(queue, attributes = {})
diff --git a/lib/gitlab/sidekiq_config/worker.rb b/lib/gitlab/sidekiq_config/worker.rb
index ec7a82f6459..46fa0aa5be1 100644
--- a/lib/gitlab/sidekiq_config/worker.rb
+++ b/lib/gitlab/sidekiq_config/worker.rb
@@ -6,7 +6,7 @@ module Gitlab
include Comparable
attr_reader :klass
- delegate :feature_category_not_owned?, :get_feature_category,
+ delegate :feature_category_not_owned?, :get_feature_category, :get_tags,
:get_urgency, :get_weight, :get_worker_resource_boundary,
:idempotent?, :queue, :queue_namespace,
:worker_has_external_dependencies?,
@@ -52,7 +52,8 @@ module Gitlab
urgency: get_urgency,
resource_boundary: get_worker_resource_boundary,
weight: get_weight,
- idempotent: idempotent?
+ idempotent: idempotent?,
+ tags: get_tags
}
end
diff --git a/lib/gitlab/sidekiq_logging/json_formatter.rb b/lib/gitlab/sidekiq_logging/json_formatter.rb
index 64782e1e1d1..8894b48417c 100644
--- a/lib/gitlab/sidekiq_logging/json_formatter.rb
+++ b/lib/gitlab/sidekiq_logging/json_formatter.rb
@@ -18,10 +18,15 @@ module Gitlab
when String
output[:message] = data
when Hash
- convert_to_iso8601!(data)
- convert_retry_to_integer!(data)
- stringify_args!(data)
output.merge!(data)
+
+ # jobstr is redundant and can include information we wanted to
+ # exclude (like arguments)
+ output.delete(:jobstr)
+
+ convert_to_iso8601!(output)
+ convert_retry_to_integer!(output)
+ process_args!(output)
end
output.to_json + "\n"
@@ -56,8 +61,11 @@ module Gitlab
end
end
- def stringify_args!(payload)
- payload['args'] = Gitlab::Utils::LogLimitedArray.log_limited_array(payload['args'].map(&:to_s)) if payload['args']
+ def process_args!(payload)
+ return unless payload['args']
+
+ payload['args'] = Gitlab::ErrorTracking::Processor::SidekiqProcessor
+ .loggable_arguments(payload['args'], payload['class'])
end
end
end
diff --git a/lib/gitlab/sidekiq_logging/structured_logger.rb b/lib/gitlab/sidekiq_logging/structured_logger.rb
index 4e39120f8a7..eb845c5ff8d 100644
--- a/lib/gitlab/sidekiq_logging/structured_logger.rb
+++ b/lib/gitlab/sidekiq_logging/structured_logger.rb
@@ -27,7 +27,7 @@ module Gitlab
private
def add_instrumentation_keys!(job, output_payload)
- output_payload.merge!(job.slice(*::Gitlab::InstrumentationHelper::KEYS))
+ output_payload.merge!(job.slice(*::Gitlab::InstrumentationHelper.keys))
end
def add_logging_extras!(job, output_payload)
@@ -36,6 +36,10 @@ module Gitlab
)
end
+ def add_db_counters!(job, output_payload)
+ output_payload.merge!(job.slice(*::Gitlab::Metrics::Subscribers::ActiveRecord::DB_COUNTERS))
+ end
+
def log_job_start(payload)
payload['message'] = "#{base_message(payload)}: start"
payload['job_status'] = 'start'
@@ -50,6 +54,7 @@ module Gitlab
payload = payload.dup
add_instrumentation_keys!(job, payload)
add_logging_extras!(job, payload)
+ add_db_counters!(job, payload)
elapsed_time = elapsed(started_time)
add_time_keys!(elapsed_time, payload)
diff --git a/lib/gitlab/sidekiq_middleware/duplicate_jobs/client.rb b/lib/gitlab/sidekiq_middleware/duplicate_jobs/client.rb
index ddd1b91410b..bb0c18735bb 100644
--- a/lib/gitlab/sidekiq_middleware/duplicate_jobs/client.rb
+++ b/lib/gitlab/sidekiq_middleware/duplicate_jobs/client.rb
@@ -5,9 +5,6 @@ module Gitlab
module DuplicateJobs
class Client
def call(worker_class, job, queue, _redis_pool, &block)
- # We don't try to deduplicate jobs that are scheduled in the future
- return yield if job['at']
-
DuplicateJob.new(job, queue).schedule(&block)
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 fa742d07af2..0dc53c61e84 100644
--- a/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb
+++ b/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb
@@ -18,13 +18,13 @@ module Gitlab
# When new jobs can be scheduled again, the strategy calls `#delete`.
class DuplicateJob
DUPLICATE_KEY_TTL = 6.hours
+ DEFAULT_STRATEGY = :until_executing
attr_reader :existing_jid
- def initialize(job, queue_name, strategy: :until_executing)
+ def initialize(job, queue_name)
@job = job
@queue_name = queue_name
- @strategy = strategy
end
# This will continue the middleware chain if the job should be scheduled
@@ -41,12 +41,12 @@ module Gitlab
end
# This method will return the jid that was set in redis
- def check!
+ def check!(expiry = DUPLICATE_KEY_TTL)
read_jid = nil
Sidekiq.redis do |redis|
redis.multi do |multi|
- redis.set(idempotency_key, jid, ex: DUPLICATE_KEY_TTL, nx: true)
+ redis.set(idempotency_key, jid, ex: expiry, nx: true)
read_jid = redis.get(idempotency_key)
end
end
@@ -60,6 +60,10 @@ module Gitlab
end
end
+ def scheduled?
+ scheduled_at.present?
+ end
+
def duplicate?
raise "Call `#check!` first to check for existing duplicates" unless existing_jid
@@ -67,14 +71,36 @@ module Gitlab
end
def droppable?
- idempotent? && duplicate? && ::Feature.disabled?("disable_#{queue_name}_deduplication")
+ idempotent? && ::Feature.disabled?("disable_#{queue_name}_deduplication")
+ end
+
+ def scheduled_at
+ job['at']
+ end
+
+ def options
+ return {} unless worker_klass
+ return {} unless worker_klass.respond_to?(:get_deduplication_options)
+
+ worker_klass.get_deduplication_options
end
private
- attr_reader :queue_name, :strategy, :job
+ attr_reader :queue_name, :job
attr_writer :existing_jid
+ def worker_klass
+ @worker_klass ||= worker_class_name.to_s.safe_constantize
+ end
+
+ def strategy
+ return DEFAULT_STRATEGY unless worker_klass
+ return DEFAULT_STRATEGY unless worker_klass.respond_to?(:idempotent?)
+
+ worker_klass.get_deduplicate_strategy
+ end
+
def worker_class_name
job['class']
end
@@ -104,11 +130,10 @@ module Gitlab
end
def idempotent?
- worker_class = worker_class_name.to_s.safe_constantize
- return false unless worker_class
- return false unless worker_class.respond_to?(:idempotent?)
+ return false unless worker_klass
+ return false unless worker_klass.respond_to?(:idempotent?)
- worker_class.idempotent?
+ worker_klass.idempotent?
end
end
end
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 674e436b714..0ed4912c4cc 100644
--- a/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executing.rb
+++ b/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executing.rb
@@ -13,13 +13,13 @@ module Gitlab
end
def schedule(job)
- if duplicate_job.check! && duplicate_job.duplicate?
+ if deduplicatable_job? && check! && duplicate_job.duplicate?
job['duplicate-of'] = duplicate_job.existing_jid
- end
- if duplicate_job.droppable?
- Gitlab::SidekiqLogging::DeduplicationLogger.instance.log(job, "dropped until executing")
- return false
+ if duplicate_job.droppable?
+ Gitlab::SidekiqLogging::DeduplicationLogger.instance.log(job, "dropped until executing")
+ return false
+ end
end
yield
@@ -34,6 +34,22 @@ module Gitlab
private
attr_reader :duplicate_job
+
+ def deduplicatable_job?
+ !duplicate_job.scheduled? || duplicate_job.options[:including_scheduled]
+ end
+
+ def check!
+ duplicate_job.check!(expiry)
+ end
+
+ def expiry
+ return DuplicateJob::DUPLICATE_KEY_TTL unless duplicate_job.scheduled?
+
+ time_diff = duplicate_job.scheduled_at.to_i - Time.now.to_i
+
+ time_diff > 0 ? time_diff : DuplicateJob::DUPLICATE_KEY_TTL
+ end
end
end
end
diff --git a/lib/gitlab/sidekiq_middleware/server_metrics.rb b/lib/gitlab/sidekiq_middleware/server_metrics.rb
index 61ed2fe1a06..6a942a6ce06 100644
--- a/lib/gitlab/sidekiq_middleware/server_metrics.rb
+++ b/lib/gitlab/sidekiq_middleware/server_metrics.rb
@@ -47,6 +47,10 @@ module Gitlab
@metrics[:sidekiq_jobs_completion_seconds].observe(labels, monotonic_time)
@metrics[:sidekiq_jobs_db_seconds].observe(labels, ActiveRecord::LogSubscriber.runtime / 1000)
@metrics[:sidekiq_jobs_gitaly_seconds].observe(labels, get_gitaly_time(job))
+ @metrics[:sidekiq_redis_requests_total].increment(labels, get_redis_calls(job))
+ @metrics[:sidekiq_redis_requests_duration_seconds].observe(labels, get_redis_time(job))
+ @metrics[:sidekiq_elasticsearch_requests_total].increment(labels, get_elasticsearch_calls(job))
+ @metrics[:sidekiq_elasticsearch_requests_duration_seconds].observe(labels, get_elasticsearch_time(job))
end
end
@@ -54,15 +58,19 @@ module Gitlab
def init_metrics
{
- sidekiq_jobs_cpu_seconds: ::Gitlab::Metrics.histogram(:sidekiq_jobs_cpu_seconds, 'Seconds of cpu time to run Sidekiq job', {}, SIDEKIQ_LATENCY_BUCKETS),
- sidekiq_jobs_completion_seconds: ::Gitlab::Metrics.histogram(:sidekiq_jobs_completion_seconds, 'Seconds to complete Sidekiq job', {}, SIDEKIQ_LATENCY_BUCKETS),
- sidekiq_jobs_db_seconds: ::Gitlab::Metrics.histogram(:sidekiq_jobs_db_seconds, 'Seconds of database time to run Sidekiq job', {}, SIDEKIQ_LATENCY_BUCKETS),
- sidekiq_jobs_gitaly_seconds: ::Gitlab::Metrics.histogram(:sidekiq_jobs_gitaly_seconds, 'Seconds of Gitaly time to run Sidekiq job', {}, SIDEKIQ_LATENCY_BUCKETS),
- sidekiq_jobs_queue_duration_seconds: ::Gitlab::Metrics.histogram(:sidekiq_jobs_queue_duration_seconds, 'Duration in seconds that a Sidekiq job was queued before being executed', {}, SIDEKIQ_LATENCY_BUCKETS),
- sidekiq_jobs_failed_total: ::Gitlab::Metrics.counter(:sidekiq_jobs_failed_total, 'Sidekiq jobs failed'),
- sidekiq_jobs_retried_total: ::Gitlab::Metrics.counter(:sidekiq_jobs_retried_total, 'Sidekiq jobs retried'),
- sidekiq_running_jobs: ::Gitlab::Metrics.gauge(:sidekiq_running_jobs, 'Number of Sidekiq jobs running', {}, :all),
- sidekiq_concurrency: ::Gitlab::Metrics.gauge(:sidekiq_concurrency, 'Maximum number of Sidekiq jobs', {}, :all)
+ sidekiq_jobs_cpu_seconds: ::Gitlab::Metrics.histogram(:sidekiq_jobs_cpu_seconds, 'Seconds of cpu time to run Sidekiq job', {}, SIDEKIQ_LATENCY_BUCKETS),
+ sidekiq_jobs_completion_seconds: ::Gitlab::Metrics.histogram(:sidekiq_jobs_completion_seconds, 'Seconds to complete Sidekiq job', {}, SIDEKIQ_LATENCY_BUCKETS),
+ sidekiq_jobs_db_seconds: ::Gitlab::Metrics.histogram(:sidekiq_jobs_db_seconds, 'Seconds of database time to run Sidekiq job', {}, SIDEKIQ_LATENCY_BUCKETS),
+ sidekiq_jobs_gitaly_seconds: ::Gitlab::Metrics.histogram(:sidekiq_jobs_gitaly_seconds, 'Seconds of Gitaly time to run Sidekiq job', {}, SIDEKIQ_LATENCY_BUCKETS),
+ sidekiq_jobs_queue_duration_seconds: ::Gitlab::Metrics.histogram(:sidekiq_jobs_queue_duration_seconds, 'Duration in seconds that a Sidekiq job was queued before being executed', {}, SIDEKIQ_LATENCY_BUCKETS),
+ sidekiq_redis_requests_duration_seconds: ::Gitlab::Metrics.histogram(:sidekiq_redis_requests_duration_seconds, 'Duration in seconds that a Sidekiq job spent requests a Redis server', {}, Gitlab::Instrumentation::Redis::QUERY_TIME_BUCKETS),
+ sidekiq_elasticsearch_requests_duration_seconds: ::Gitlab::Metrics.histogram(:sidekiq_elasticsearch_requests_duration_seconds, 'Duration in seconds that a Sidekiq job spent in requests to an Elasticsearch server', {}, SIDEKIQ_LATENCY_BUCKETS),
+ sidekiq_jobs_failed_total: ::Gitlab::Metrics.counter(:sidekiq_jobs_failed_total, 'Sidekiq jobs failed'),
+ sidekiq_jobs_retried_total: ::Gitlab::Metrics.counter(:sidekiq_jobs_retried_total, 'Sidekiq jobs retried'),
+ sidekiq_redis_requests_total: ::Gitlab::Metrics.counter(:sidekiq_redis_requests_total, 'Redis requests during a Sidekiq job execution'),
+ sidekiq_elasticsearch_requests_total: ::Gitlab::Metrics.counter(:sidekiq_elasticsearch_requests_total, 'Elasticsearch requests during a Sidekiq job execution'),
+ sidekiq_running_jobs: ::Gitlab::Metrics.gauge(:sidekiq_running_jobs, 'Number of Sidekiq jobs running', {}, :all),
+ sidekiq_concurrency: ::Gitlab::Metrics.gauge(:sidekiq_concurrency, 'Maximum number of Sidekiq jobs', {}, :all)
}
end
@@ -70,6 +78,22 @@ module Gitlab
defined?(Process::CLOCK_THREAD_CPUTIME_ID) ? Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID) : 0
end
+ def get_redis_time(job)
+ job.fetch(:redis_duration_s, 0)
+ end
+
+ def get_redis_calls(job)
+ job.fetch(:redis_calls, 0)
+ end
+
+ def get_elasticsearch_time(job)
+ job.fetch(:elasticsearch_duration_s, 0)
+ end
+
+ def get_elasticsearch_calls(job)
+ job.fetch(:elasticsearch_calls, 0)
+ end
+
def get_gitaly_time(job)
job.fetch(:gitaly_duration_s, 0)
end
diff --git a/lib/gitlab/slash_commands/presenters/help.rb b/lib/gitlab/slash_commands/presenters/help.rb
index 342dae456a8..2d8df2ca204 100644
--- a/lib/gitlab/slash_commands/presenters/help.rb
+++ b/lib/gitlab/slash_commands/presenters/help.rb
@@ -21,7 +21,7 @@ module Gitlab
This chatops integration does not have any commands that can be
executed.
- #{footer}
+ #{help_footer}
MESSAGE
end
diff --git a/lib/gitlab/snippet_search_results.rb b/lib/gitlab/snippet_search_results.rb
index 9911f9e62a6..1d253ca90f3 100644
--- a/lib/gitlab/snippet_search_results.rb
+++ b/lib/gitlab/snippet_search_results.rb
@@ -11,7 +11,7 @@ module Gitlab
@query = query
end
- def objects(scope, page: nil, per_page: DEFAULT_PER_PAGE)
+ def objects(scope, page: nil, per_page: DEFAULT_PER_PAGE, preload_method: nil)
paginated_objects(snippet_titles, page, per_page)
end
diff --git a/lib/gitlab/sourcegraph.rb b/lib/gitlab/sourcegraph.rb
index d0f12c8364a..ec404ebd309 100644
--- a/lib/gitlab/sourcegraph.rb
+++ b/lib/gitlab/sourcegraph.rb
@@ -19,7 +19,7 @@ module Gitlab
private
def feature
- Feature.get(:sourcegraph)
+ Feature.get(:sourcegraph) # rubocop:disable Gitlab/AvoidFeatureGet
end
end
end
diff --git a/lib/gitlab/suggestions/commit_message.rb b/lib/gitlab/suggestions/commit_message.rb
new file mode 100644
index 00000000000..d59a8fc3730
--- /dev/null
+++ b/lib/gitlab/suggestions/commit_message.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Suggestions
+ class CommitMessage
+ DEFAULT_SUGGESTION_COMMIT_MESSAGE =
+ 'Apply %{suggestions_count} suggestion(s) to %{files_count} file(s)'
+
+ def initialize(user, suggestion_set)
+ @user = user
+ @suggestion_set = suggestion_set
+ end
+
+ def message
+ project = suggestion_set.project
+ user_defined_message = project.suggestion_commit_message.presence
+ message = user_defined_message || DEFAULT_SUGGESTION_COMMIT_MESSAGE
+
+ Gitlab::StringPlaceholderReplacer
+ .replace_string_placeholders(message, PLACEHOLDERS_REGEX) do |key|
+ PLACEHOLDERS[key].call(user, suggestion_set)
+ end
+ end
+
+ def self.format_paths(paths)
+ paths.sort.join(', ')
+ end
+
+ private_class_method :format_paths
+
+ private
+
+ attr_reader :user, :suggestion_set
+
+ PLACEHOLDERS = {
+ 'branch_name' => ->(user, suggestion_set) { suggestion_set.branch },
+ 'files_count' => ->(user, suggestion_set) { suggestion_set.file_paths.length },
+ 'file_paths' => ->(user, suggestion_set) { format_paths(suggestion_set.file_paths) },
+ 'project_name' => ->(user, suggestion_set) { suggestion_set.project.name },
+ 'project_path' => ->(user, suggestion_set) { suggestion_set.project.path },
+ 'user_full_name' => ->(user, suggestion_set) { user.name },
+ 'username' => ->(user, suggestion_set) { user.username },
+ 'suggestions_count' => ->(user, suggestion_set) { suggestion_set.suggestions.size }
+ }.freeze
+
+ # This regex is built dynamically using the keys from the PLACEHOLDER struct.
+ # So, we can easily add new placeholder just by modifying the PLACEHOLDER hash.
+ # This regex will build the new PLACEHOLDER_REGEX with the new information
+ PLACEHOLDERS_REGEX = Regexp.union(PLACEHOLDERS.keys.map do |key|
+ Regexp.new(Regexp.escape(key))
+ end).freeze
+ end
+ end
+end
diff --git a/lib/gitlab/suggestions/file_suggestion.rb b/lib/gitlab/suggestions/file_suggestion.rb
new file mode 100644
index 00000000000..73b9800f0b8
--- /dev/null
+++ b/lib/gitlab/suggestions/file_suggestion.rb
@@ -0,0 +1,107 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Suggestions
+ class FileSuggestion
+ include Gitlab::Utils::StrongMemoize
+
+ SuggestionForDifferentFileError = Class.new(StandardError)
+
+ def initialize
+ @suggestions = []
+ end
+
+ def add_suggestion(new_suggestion)
+ if for_different_file?(new_suggestion)
+ raise SuggestionForDifferentFileError,
+ 'Only add suggestions for the same file.'
+ end
+
+ suggestions << new_suggestion
+ end
+
+ def line_conflict?
+ strong_memoize(:line_conflict) do
+ _line_conflict?
+ end
+ end
+
+ def new_content
+ @new_content ||= _new_content
+ end
+
+ def file_path
+ @file_path ||= _file_path
+ end
+
+ private
+
+ attr_accessor :suggestions
+
+ def blob
+ first_suggestion&.diff_file&.new_blob
+ end
+
+ def blob_data_lines
+ blob.load_all_data!
+ blob.data.lines
+ end
+
+ def current_content
+ @current_content ||= blob.nil? ? [''] : blob_data_lines
+ end
+
+ def _new_content
+ current_content.tap do |content|
+ suggestions.each do |suggestion|
+ range = line_range(suggestion)
+ content[range] = suggestion.to_content
+ end
+ end.join
+ end
+
+ def line_range(suggestion)
+ suggestion.from_line_index..suggestion.to_line_index
+ end
+
+ def for_different_file?(suggestion)
+ file_path && file_path != suggestion_file_path(suggestion)
+ end
+
+ def suggestion_file_path(suggestion)
+ suggestion&.diff_file&.file_path
+ end
+
+ def first_suggestion
+ suggestions.first
+ end
+
+ def _file_path
+ suggestion_file_path(first_suggestion)
+ end
+
+ def _line_conflict?
+ has_conflict = false
+
+ suggestions.each_with_object([]) do |suggestion, ranges|
+ range_in_test = line_range(suggestion)
+
+ if has_range_conflict?(range_in_test, ranges)
+ has_conflict = true
+ break
+ end
+
+ ranges << range_in_test
+ end
+
+ has_conflict
+ end
+
+ def has_range_conflict?(range_in_test, ranges)
+ ranges.any? do |range|
+ range.overlaps?(range_in_test)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/suggestions/suggestion_set.rb b/lib/gitlab/suggestions/suggestion_set.rb
new file mode 100644
index 00000000000..22abef98bf0
--- /dev/null
+++ b/lib/gitlab/suggestions/suggestion_set.rb
@@ -0,0 +1,120 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Suggestions
+ class SuggestionSet
+ attr_reader :suggestions
+
+ def initialize(suggestions)
+ @suggestions = suggestions
+ end
+
+ def project
+ first_suggestion.project
+ end
+
+ def branch
+ first_suggestion.branch
+ end
+
+ def valid?
+ error_message.nil?
+ end
+
+ def error_message
+ @error_message ||= _error_message
+ end
+
+ def actions
+ @actions ||= suggestions_per_file.map do |file_path, file_suggestion|
+ {
+ action: 'update',
+ file_path: file_path,
+ content: file_suggestion.new_content
+ }
+ end
+ end
+
+ def file_paths
+ @file_paths ||= suggestions.map(&:file_path).uniq
+ end
+
+ private
+
+ def first_suggestion
+ suggestions.first
+ end
+
+ def suggestions_per_file
+ @suggestions_per_file ||= _suggestions_per_file
+ end
+
+ def _suggestions_per_file
+ suggestions.each_with_object({}) do |suggestion, result|
+ file_path = suggestion.diff_file.file_path
+ file_suggestion = result[file_path] ||= FileSuggestion.new
+ file_suggestion.add_suggestion(suggestion)
+ end
+ end
+
+ def file_suggestions
+ suggestions_per_file.values
+ end
+
+ def first_file_suggestion
+ file_suggestions.first
+ end
+
+ def _error_message
+ suggestions.each do |suggestion|
+ message = error_for_suggestion(suggestion)
+
+ return message if message
+ end
+
+ has_line_conflict = file_suggestions.any? do |file_suggestion|
+ file_suggestion.line_conflict?
+ end
+
+ if has_line_conflict
+ return _('Suggestions are not applicable as their lines cannot overlap.')
+ end
+
+ nil
+ end
+
+ def error_for_suggestion(suggestion)
+ unless suggestion.diff_file
+ return _('A file was not found.')
+ end
+
+ unless on_same_branch?(suggestion)
+ return _('Suggestions must all be on the same branch.')
+ end
+
+ unless suggestion.appliable?(cached: false)
+ return _('A suggestion is not applicable.')
+ end
+
+ unless latest_source_head?(suggestion)
+ return _('A file has been changed.')
+ end
+
+ nil
+ end
+
+ def on_same_branch?(suggestion)
+ branch == suggestion.branch
+ end
+
+ # Checks whether the latest source branch HEAD matches with
+ # the position HEAD we're using to update the file content. Since
+ # the persisted HEAD is updated async (for MergeRequest),
+ # it's more consistent to fetch this data directly from the
+ # repository.
+ def latest_source_head?(suggestion)
+ suggestion.position.head_sha == suggestion.noteable.source_branch_sha
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/themes.rb b/lib/gitlab/themes.rb
index 5992f24f4e9..72783a2d682 100644
--- a/lib/gitlab/themes.rb
+++ b/lib/gitlab/themes.rb
@@ -23,7 +23,8 @@ module Gitlab
Theme.new(9, 'Red', 'ui-red'),
Theme.new(10, 'Light Red', 'ui-light-red'),
Theme.new(2, 'Dark', 'ui-dark'),
- Theme.new(3, 'Light', 'ui-light')
+ Theme.new(3, 'Light', 'ui-light'),
+ Theme.new(11, 'Dark Mode (alpha)', 'gl-dark')
].freeze
# Convenience method to get a space-separated String of all the theme
diff --git a/lib/gitlab/url_builder.rb b/lib/gitlab/url_builder.rb
index 329f87d8be8..cd15130cee6 100644
--- a/lib/gitlab/url_builder.rb
+++ b/lib/gitlab/url_builder.rb
@@ -41,7 +41,7 @@ module Gitlab
when Wiki
wiki_url(object, **options)
when WikiPage
- instance.project_wiki_url(object.wiki.project, object.slug, **options)
+ wiki_page_url(object.wiki, object, **options)
when ::DesignManagement::Design
design_url(object, **options)
else
@@ -78,12 +78,21 @@ module Gitlab
end
end
- def wiki_url(object, **options)
- if object.container.is_a?(Project)
- instance.project_wiki_url(object.container, Wiki::HOMEPAGE, **options)
- else
- raise NotImplementedError.new("No URL builder defined for #{object.inspect}")
- end
+ def wiki_url(wiki, **options)
+ return wiki_page_url(wiki, Wiki::HOMEPAGE, **options) unless options[:action]
+
+ options[:controller] = 'projects/wikis'
+ options[:namespace_id] = wiki.container.namespace
+ options[:project_id] = wiki.container
+
+ instance.url_for(**options)
+ end
+
+ def wiki_page_url(wiki, page, **options)
+ options[:action] ||= :show
+ options[:id] = page
+
+ wiki_url(wiki, **options)
end
def design_url(design, **options)
diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb
index e60c786b52c..7b6f5e69ee1 100644
--- a/lib/gitlab/usage_data.rb
+++ b/lib/gitlab/usage_data.rb
@@ -1,27 +1,25 @@
# frozen_string_literal: true
-# For hardening usage ping and make it easier to add measures there is in place
-# * alt_usage_data method
-# handles StandardError and fallbacks into -1 this way not all measures fail if we encounter one exception
+# When developing usage data metrics use the below usage data interface methods
+# unless you have good reasons to implement custom usage data
+# See `lib/gitlab/utils/usage_data.rb`
#
-# Examples:
-# alt_usage_data { Gitlab::VERSION }
-# alt_usage_data { Gitlab::CurrentSettings.uuid }
-#
-# * redis_usage_data method
-# handles ::Redis::CommandError, Gitlab::UsageDataCounters::BaseCounter::UnknownEvent
-# returns -1 when a block is sent or hash with all values -1 when a counter is sent
-# different behaviour due to 2 different implementations of redis counter
-#
-# Examples:
-# redis_usage_data(Gitlab::UsageDataCounters::WikiPageCounter)
-# redis_usage_data { ::Gitlab::UsageCounters::PodLogs.usage_totals[:total] }
+# Examples
+# issues_using_zoom_quick_actions: distinct_count(ZoomMeeting, :issue_id),
+# active_user_count: count(User.active)
+# alt_usage_data { Gitlab::VERSION }
+# redis_usage_data(Gitlab::UsageDataCounters::WikiPageCounter)
+# redis_usage_data { ::Gitlab::UsageCounters::PodLogs.usage_totals[:total] }
+
module Gitlab
class UsageData
BATCH_SIZE = 100
- FALLBACK = -1
class << self
+ include Gitlab::Utils::UsageData
+ include Gitlab::Utils::StrongMemoize
+ include Gitlab::UsageDataConcerns::Topology
+
def data(force_refresh: false)
Rails.cache.fetch('usage_data', force: force_refresh, expires_in: 2.weeks) do
uncached_data
@@ -29,12 +27,15 @@ module Gitlab
end
def uncached_data
+ clear_memoized_limits
+
license_usage_data
.merge(system_usage_data)
.merge(features_usage_data)
.merge(components_usage_data)
.merge(cycle_analytics_usage_data)
.merge(object_store_usage_data)
+ .merge(topology_usage_data)
.merge(recording_ce_finish_data)
end
@@ -44,7 +45,7 @@ module Gitlab
def license_usage_data
{
- recorded_at: Time.now, # should be calculated very first
+ recorded_at: recorded_at,
uuid: alt_usage_data { Gitlab::CurrentSettings.uuid },
hostname: alt_usage_data { Gitlab.config.gitlab.host },
version: alt_usage_data { Gitlab::VERSION },
@@ -54,6 +55,10 @@ module Gitlab
}
end
+ def recorded_at
+ Time.now
+ end
+
def recording_ce_finish_data
{
recording_ce_finished_at: Time.now
@@ -64,6 +69,7 @@ module Gitlab
# rubocop: disable CodeReuse/ActiveRecord
def system_usage_data
alert_bot_incident_count = count(::Issue.authored(::User.alert_bot))
+ issues_created_manually_from_alerts = count(Issue.with_alert_management_alerts.not_authored_by(::User.alert_bot))
{
counts: {
@@ -114,7 +120,9 @@ module Gitlab
issues_with_associated_zoom_link: count(ZoomMeeting.added_to_issue),
issues_using_zoom_quick_actions: distinct_count(ZoomMeeting, :issue_id),
issues_with_embedded_grafana_charts_approx: grafana_embed_usage_data,
- issues_created_gitlab_alerts: count(Issue.with_alert_management_alerts.not_authored_by(::User.alert_bot)),
+ issues_created_from_alerts: total_alert_issues,
+ issues_created_gitlab_alerts: issues_created_manually_from_alerts,
+ issues_created_manually_from_alerts: issues_created_manually_from_alerts,
incident_issues: alert_bot_incident_count,
alert_bot_incident_issues: alert_bot_incident_count,
incident_labeled_issues: count(::Issue.with_label_attributes(IncidentManagement::CreateIssueService::INCIDENT_LABEL)),
@@ -131,11 +139,17 @@ module Gitlab
projects_with_error_tracking_enabled: count(::ErrorTracking::ProjectErrorTrackingSetting.where(enabled: true)),
projects_with_alerts_service_enabled: count(AlertsService.active),
projects_with_prometheus_alerts: distinct_count(PrometheusAlert, :project_id),
+ projects_with_terraform_reports: distinct_count(::Ci::JobArtifact.terraform_reports, :project_id),
+ projects_with_terraform_states: distinct_count(::Terraform::State, :project_id),
protected_branches: count(ProtectedBranch),
releases: count(Release),
remote_mirrors: count(RemoteMirror),
snippets: count(Snippet),
+ personal_snippets: count(PersonalSnippet),
+ project_snippets: count(ProjectSnippet),
suggestions: count(Suggestion),
+ terraform_reports: count(::Ci::JobArtifact.terraform_reports),
+ terraform_states: count(::Terraform::State),
todos: count(Todo),
uploads: count(Upload),
web_hooks: count(WebHook),
@@ -147,7 +161,8 @@ module Gitlab
usage_counters,
user_preferences_usage,
ingress_modsecurity_usage,
- container_expiration_policies_usage
+ container_expiration_policies_usage,
+ merge_requests_usage(default_time_period)
)
}
end
@@ -174,19 +189,20 @@ module Gitlab
def features_usage_data_ce
{
- container_registry_enabled: alt_usage_data { Gitlab.config.registry.enabled },
+ instance_auto_devops_enabled: alt_usage_data(fallback: nil) { Gitlab::CurrentSettings.auto_devops_enabled? },
+ container_registry_enabled: alt_usage_data(fallback: nil) { Gitlab.config.registry.enabled },
dependency_proxy_enabled: Gitlab.config.try(:dependency_proxy)&.enabled,
- gitlab_shared_runners_enabled: alt_usage_data { Gitlab.config.gitlab_ci.shared_runners_enabled },
- gravatar_enabled: alt_usage_data { Gitlab::CurrentSettings.gravatar_enabled? },
- ldap_enabled: alt_usage_data { Gitlab.config.ldap.enabled },
- mattermost_enabled: alt_usage_data { Gitlab.config.mattermost.enabled },
- omniauth_enabled: alt_usage_data { Gitlab::Auth.omniauth_enabled? },
- prometheus_metrics_enabled: alt_usage_data { Gitlab::Metrics.prometheus_metrics_enabled? },
- reply_by_email_enabled: alt_usage_data { Gitlab::IncomingEmail.enabled? },
- signup_enabled: alt_usage_data { Gitlab::CurrentSettings.allow_signup? },
- web_ide_clientside_preview_enabled: alt_usage_data { Gitlab::CurrentSettings.web_ide_clientside_preview_enabled? },
+ gitlab_shared_runners_enabled: alt_usage_data(fallback: nil) { Gitlab.config.gitlab_ci.shared_runners_enabled },
+ gravatar_enabled: alt_usage_data(fallback: nil) { Gitlab::CurrentSettings.gravatar_enabled? },
+ ldap_enabled: alt_usage_data(fallback: nil) { Gitlab.config.ldap.enabled },
+ mattermost_enabled: alt_usage_data(fallback: nil) { Gitlab.config.mattermost.enabled },
+ omniauth_enabled: alt_usage_data(fallback: nil) { Gitlab::Auth.omniauth_enabled? },
+ prometheus_metrics_enabled: alt_usage_data(fallback: nil) { Gitlab::Metrics.prometheus_metrics_enabled? },
+ reply_by_email_enabled: alt_usage_data(fallback: nil) { Gitlab::IncomingEmail.enabled? },
+ signup_enabled: alt_usage_data(fallback: nil) { Gitlab::CurrentSettings.allow_signup? },
+ web_ide_clientside_preview_enabled: alt_usage_data(fallback: nil) { Gitlab::CurrentSettings.web_ide_clientside_preview_enabled? },
ingress_modsecurity_enabled: Feature.enabled?(:ingress_modsecurity),
- grafana_link_enabled: alt_usage_data { Gitlab::CurrentSettings.grafana_enabled? }
+ grafana_link_enabled: alt_usage_data(fallback: nil) { Gitlab::CurrentSettings.grafana_enabled? }
}
end
@@ -213,14 +229,15 @@ module Gitlab
def components_usage_data
{
- git: { version: alt_usage_data { Gitlab::Git.version } },
+ git: { version: alt_usage_data(fallback: { major: -1 }) { Gitlab::Git.version } },
gitaly: {
version: alt_usage_data { Gitaly::Server.all.first.server_version },
servers: alt_usage_data { Gitaly::Server.count },
- filesystems: alt_usage_data { Gitaly::Server.filesystems }
+ clusters: alt_usage_data { Gitaly::Server.gitaly_clusters },
+ filesystems: alt_usage_data(fallback: ["-1"]) { Gitaly::Server.filesystems }
},
gitlab_pages: {
- enabled: alt_usage_data { Gitlab.config.pages.enabled },
+ enabled: alt_usage_data(fallback: nil) { Gitlab.config.pages.enabled },
version: alt_usage_data { Gitlab::Pages::VERSION }
},
database: {
@@ -382,65 +399,67 @@ module Gitlab
{} # augmented in EE
end
- def count(relation, column = nil, batch: true, start: nil, finish: nil)
- if batch && Feature.enabled?(:usage_ping_batch_counter, default_enabled: true)
- Gitlab::Database::BatchCount.batch_count(relation, column, start: start, finish: finish)
- else
- relation.count
- end
- rescue ActiveRecord::StatementInvalid
- FALLBACK
- end
+ # rubocop: disable CodeReuse/ActiveRecord
+ def merge_requests_usage(time_period)
+ query =
+ Event
+ .where(target_type: Event::TARGET_TYPES[:merge_request].to_s)
+ .where(time_period)
+
+ merge_request_users = distinct_count(
+ query,
+ :author_id,
+ batch_size: 5_000, # Based on query performance, this is the optimal batch size.
+ start: User.minimum(:id),
+ finish: User.maximum(:id)
+ )
- def distinct_count(relation, column = nil, batch: true, start: nil, finish: nil)
- if batch && Feature.enabled?(:usage_ping_batch_counter, default_enabled: true)
- Gitlab::Database::BatchCount.batch_distinct_count(relation, column, start: start, finish: finish)
- else
- relation.distinct_count_by(column)
- end
- rescue ActiveRecord::StatementInvalid
- FALLBACK
+ {
+ merge_requests_users: merge_request_users
+ }
end
+ # rubocop: enable CodeReuse/ActiveRecord
- def alt_usage_data(value = nil, fallback: FALLBACK, &block)
- if block_given?
- yield
+ def installation_type
+ if Rails.env.production?
+ Gitlab::INSTALLATION_TYPE
else
- value
+ "gitlab-development-kit"
end
- rescue
- fallback
end
- def redis_usage_data(counter = nil, &block)
- if block_given?
- redis_usage_counter(&block)
- elsif counter.present?
- redis_usage_data_totals(counter)
- end
+ def default_time_period
+ { created_at: 28.days.ago..Time.current }
end
private
- def redis_usage_counter
- yield
- rescue ::Redis::CommandError, Gitlab::UsageDataCounters::BaseCounter::UnknownEvent
- FALLBACK
+ def total_alert_issues
+ # Remove prometheus table queries once they are deprecated
+ # To be removed with https://gitlab.com/gitlab-org/gitlab/-/issues/217407.
+ [
+ count(Issue.with_alert_management_alerts),
+ count(::Issue.with_self_managed_prometheus_alert_events),
+ count(::Issue.with_prometheus_alert_events)
+ ].reduce(:+)
end
- def redis_usage_data_totals(counter)
- counter.totals
- rescue ::Redis::CommandError, Gitlab::UsageDataCounters::BaseCounter::UnknownEvent
- counter.fallback_totals
+ def user_minimum_id
+ strong_memoize(:user_minimum_id) do
+ ::User.minimum(:id)
+ end
end
- def installation_type
- if Rails.env.production?
- Gitlab::INSTALLATION_TYPE
- else
- "gitlab-development-kit"
+ def user_maximum_id
+ strong_memoize(:user_maximum_id) do
+ ::User.maximum(:id)
end
end
+
+ def clear_memoized_limits
+ clear_memoization(:user_minimum_id)
+ clear_memoization(:user_maximum_id)
+ end
end
end
end
diff --git a/lib/gitlab/usage_data_concerns/topology.rb b/lib/gitlab/usage_data_concerns/topology.rb
new file mode 100644
index 00000000000..6e1d29f2a17
--- /dev/null
+++ b/lib/gitlab/usage_data_concerns/topology.rb
@@ -0,0 +1,137 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module UsageDataConcerns
+ module Topology
+ include Gitlab::Utils::UsageData
+
+ JOB_TO_SERVICE_NAME = {
+ 'gitlab-rails' => 'web',
+ 'gitlab-sidekiq' => 'sidekiq',
+ 'gitlab-workhorse' => 'workhorse',
+ 'redis' => 'redis',
+ 'postgres' => 'postgres',
+ 'gitaly' => 'gitaly',
+ 'prometheus' => 'prometheus',
+ 'node' => 'node-exporter'
+ }.freeze
+
+ def topology_usage_data
+ topology_data, duration = measure_duration do
+ alt_usage_data(fallback: {}) do
+ {
+ nodes: topology_node_data
+ }.compact
+ end
+ end
+ { topology: topology_data.merge(duration_s: duration) }
+ end
+
+ private
+
+ def topology_node_data
+ with_prometheus_client do |client|
+ # node-level data
+ by_instance_mem = topology_node_memory(client)
+ by_instance_cpus = topology_node_cpus(client)
+ # service-level data
+ by_instance_by_job_by_metric_memory = topology_all_service_memory(client)
+ by_instance_by_job_process_count = topology_all_service_process_count(client)
+
+ instances = Set.new(by_instance_mem.keys + by_instance_cpus.keys)
+ instances.map do |instance|
+ {
+ node_memory_total_bytes: by_instance_mem[instance],
+ node_cpus: by_instance_cpus[instance],
+ node_services:
+ topology_node_services(instance, by_instance_by_job_process_count, by_instance_by_job_by_metric_memory)
+ }.compact
+ end
+ end
+ end
+
+ def topology_node_memory(client)
+ aggregate_single(client, 'avg (node_memory_MemTotal_bytes) by (instance)')
+ end
+
+ def topology_node_cpus(client)
+ aggregate_single(client, 'count (node_cpu_seconds_total{mode="idle"}) by (instance)')
+ end
+
+ def topology_all_service_memory(client)
+ aggregate_many(
+ client,
+ 'avg ({__name__ =~ "(ruby_){0,1}process_(resident|unique|proportional)_memory_bytes", job != "gitlab_exporter_process"}) by (instance, job, __name__)'
+ )
+ end
+
+ def topology_all_service_process_count(client)
+ aggregate_many(client, 'count ({__name__ =~ "(ruby_){0,1}process_start_time_seconds", job != "gitlab_exporter_process"}) by (instance, job)')
+ end
+
+ def topology_node_services(instance, all_process_counts, all_process_memory)
+ # returns all node service data grouped by service name as the key
+ instance_service_data =
+ topology_instance_service_process_count(instance, all_process_counts)
+ .deep_merge(topology_instance_service_memory(instance, all_process_memory))
+
+ # map to list of hashes where service names become values instead, and remove
+ # unknown services, since they might not be ours
+ instance_service_data.each_with_object([]) do |entry, list|
+ service, service_metrics = entry
+ gitlab_service = JOB_TO_SERVICE_NAME[service.to_s]
+ next unless gitlab_service
+
+ list << { name: gitlab_service }.merge(service_metrics)
+ end
+ end
+
+ def topology_instance_service_process_count(instance, all_instance_data)
+ topology_data_for_instance(instance, all_instance_data).to_h do |metric, count|
+ [metric['job'], { process_count: count }]
+ end
+ end
+
+ def topology_instance_service_memory(instance, all_instance_data)
+ topology_data_for_instance(instance, all_instance_data).each_with_object({}) do |entry, hash|
+ metric, memory = entry
+ job = metric['job']
+ key =
+ case metric['__name__']
+ when match_process_memory_metric_for_type('resident') then :process_memory_rss
+ when match_process_memory_metric_for_type('unique') then :process_memory_uss
+ when match_process_memory_metric_for_type('proportional') then :process_memory_pss
+ end
+
+ hash[job] ||= {}
+ hash[job][key] ||= memory
+ end
+ end
+
+ def match_process_memory_metric_for_type(type)
+ /(ruby_){0,1}process_#{type}_memory_bytes/
+ end
+
+ def topology_data_for_instance(instance, all_instance_data)
+ all_instance_data.filter { |metric, _value| metric['instance'] == instance }
+ end
+
+ def drop_port(instance)
+ instance.gsub(/:.+$/, '')
+ end
+
+ # Will retain a single `instance` key that values are mapped to
+ def aggregate_single(client, query)
+ client.aggregate(query) { |metric| drop_port(metric['instance']) }
+ end
+
+ # Will retain a composite key that values are mapped to
+ def aggregate_many(client, query)
+ client.aggregate(query) do |metric|
+ metric['instance'] = drop_port(metric['instance'])
+ metric
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/usage_data_counters/base_counter.rb b/lib/gitlab/usage_data_counters/base_counter.rb
index 96898e5189c..44893645cc2 100644
--- a/lib/gitlab/usage_data_counters/base_counter.rb
+++ b/lib/gitlab/usage_data_counters/base_counter.rb
@@ -8,7 +8,7 @@ module Gitlab::UsageDataCounters
class << self
def redis_key(event)
- Gitlab::ErrorTracking.track_and_raise_for_dev_exception(UnknownEvent.new, event: event) unless known_events.include?(event.to_s)
+ require_known_event(event)
"USAGE_#{prefix}_#{event}".upcase
end
@@ -31,6 +31,10 @@ module Gitlab::UsageDataCounters
private
+ def require_known_event(event)
+ Gitlab::ErrorTracking.track_and_raise_for_dev_exception(UnknownEvent.new, event: event) unless known_events.include?(event.to_s)
+ end
+
def counter_key(event)
"#{prefix}_#{event}".to_sym
end
diff --git a/lib/gitlab/usage_data_counters/designs_counter.rb b/lib/gitlab/usage_data_counters/designs_counter.rb
index 801fb8f3b3d..22188b555d2 100644
--- a/lib/gitlab/usage_data_counters/designs_counter.rb
+++ b/lib/gitlab/usage_data_counters/designs_counter.rb
@@ -4,7 +4,7 @@ module Gitlab::UsageDataCounters
class DesignsCounter
extend Gitlab::UsageDataCounters::RedisCounter
- KNOWN_EVENTS = %w[create update delete].map(&:freeze).freeze
+ KNOWN_EVENTS = %w[create update delete].freeze
UnknownEvent = Class.new(StandardError)
diff --git a/lib/gitlab/usage_data_counters/search_counter.rb b/lib/gitlab/usage_data_counters/search_counter.rb
index b9e3a5c0104..61f98887adc 100644
--- a/lib/gitlab/usage_data_counters/search_counter.rb
+++ b/lib/gitlab/usage_data_counters/search_counter.rb
@@ -2,28 +2,20 @@
module Gitlab
module UsageDataCounters
- class SearchCounter
- extend RedisCounter
-
- NAVBAR_SEARCHES_COUNT_KEY = 'NAVBAR_SEARCHES_COUNT'
+ class SearchCounter < BaseCounter
+ KNOWN_EVENTS = %w[all_searches navbar_searches].freeze
class << self
- def increment_navbar_searches_count
- increment(NAVBAR_SEARCHES_COUNT_KEY)
- end
+ def redis_key(event)
+ require_known_event(event)
- def total_navbar_searches_count
- total_count(NAVBAR_SEARCHES_COUNT_KEY)
+ "#{event}_COUNT".upcase
end
- def totals
- {
- navbar_searches: total_navbar_searches_count
- }
- end
+ private
- def fallback_totals
- { navbar_searches: -1 }
+ def counter_key(event)
+ "#{event}".to_sym
end
end
end
diff --git a/lib/gitlab/utils.rb b/lib/gitlab/utils.rb
index d46601fa2e8..e80cc51dc3b 100644
--- a/lib/gitlab/utils.rb
+++ b/lib/gitlab/utils.rb
@@ -3,6 +3,7 @@
module Gitlab
module Utils
extend self
+ PathTraversalAttackError ||= Class.new(StandardError)
# Ensure that the relative path will not traverse outside the base directory
# We url decode the path to avoid passing invalid paths forward in url encoded format.
@@ -17,7 +18,7 @@ module Gitlab
path.end_with?("#{File::SEPARATOR}..") ||
(!allowed_absolute && Pathname.new(path).absolute?)
- raise StandardError.new("Invalid path")
+ raise PathTraversalAttackError.new('Invalid path')
end
path
@@ -159,5 +160,23 @@ module Gitlab
Addressable::URI.parse(uri_string)
rescue Addressable::URI::InvalidURIError, TypeError
end
+
+ # Invert a hash, collecting all keys that map to a given value in an array.
+ #
+ # Unlike `Hash#invert`, where the last encountered pair wins, and which has the
+ # type `Hash[k, v] => Hash[v, k]`, `multiple_key_invert` does not lose any
+ # information, has the type `Hash[k, v] => Hash[v, Array[k]]`, and the original
+ # hash can always be reconstructed.
+ #
+ # example:
+ #
+ # multiple_key_invert({ a: 1, b: 2, c: 1 })
+ # # => { 1 => [:a, :c], 2 => [:b] }
+ #
+ def multiple_key_invert(hash)
+ hash.flat_map { |k, v| Array.wrap(v).zip([k].cycle) }
+ .group_by(&:first)
+ .transform_values { |kvs| kvs.map(&:last) }
+ end
end
end
diff --git a/lib/gitlab/utils/log_limited_array.rb b/lib/gitlab/utils/log_limited_array.rb
index e0589c3df4c..fbbba568d14 100644
--- a/lib/gitlab/utils/log_limited_array.rb
+++ b/lib/gitlab/utils/log_limited_array.rb
@@ -9,14 +9,14 @@ module Gitlab
# to around 10 kilobytes. Once we hit the limit, add the sentinel
# value as the last item in the returned array.
def self.log_limited_array(array, sentinel: '...')
- return [] unless array.is_a?(Array)
+ return [] unless array.is_a?(Array) || array.is_a?(Enumerator::Lazy)
total_length = 0
limited_array = array.take_while do |arg|
total_length += JsonSizeEstimator.estimate(arg)
total_length <= MAXIMUM_ARRAY_LENGTH
- end
+ end.to_a
limited_array.push(sentinel) if total_length > MAXIMUM_ARRAY_LENGTH
diff --git a/lib/gitlab/utils/usage_data.rb b/lib/gitlab/utils/usage_data.rb
new file mode 100644
index 00000000000..afc4e000977
--- /dev/null
+++ b/lib/gitlab/utils/usage_data.rb
@@ -0,0 +1,110 @@
+# frozen_string_literal: true
+
+# Usage data utilities
+#
+# * distinct_count(relation, column = nil, batch: true, start: nil, finish: nil)
+# Does a distinct batch count, smartly reduces batch_size and handles errors
+#
+# Examples:
+# issues_using_zoom_quick_actions: distinct_count(ZoomMeeting, :issue_id),
+#
+# * count(relation, column = nil, batch: true, start: nil, finish: nil)
+# Does a non-distinct batch count, smartly reduces batch_size and handles errors
+#
+# Examples:
+# active_user_count: count(User.active)
+#
+# * alt_usage_data method
+# handles StandardError and fallbacks by default into -1 this way not all measures fail if we encounter one exception
+# there might be cases where we need to set a specific fallback in order to be aligned wih what version app is expecting as a type
+#
+# Examples:
+# alt_usage_data { Gitlab::VERSION }
+# alt_usage_data { Gitlab::CurrentSettings.uuid }
+# alt_usage_data(fallback: nil) { Gitlab.config.registry.enabled }
+#
+# * redis_usage_data method
+# handles ::Redis::CommandError, Gitlab::UsageDataCounters::BaseCounter::UnknownEvent
+# returns -1 when a block is sent or hash with all values -1 when a counter is sent
+# different behaviour due to 2 different implementations of redis counter
+#
+# Examples:
+# redis_usage_data(Gitlab::UsageDataCounters::WikiPageCounter)
+# redis_usage_data { ::Gitlab::UsageCounters::PodLogs.usage_totals[:total] }
+
+module Gitlab
+ module Utils
+ module UsageData
+ extend self
+
+ FALLBACK = -1
+
+ def count(relation, column = nil, batch: true, start: nil, finish: nil)
+ if batch
+ Gitlab::Database::BatchCount.batch_count(relation, column, start: start, finish: finish)
+ else
+ relation.count
+ end
+ rescue ActiveRecord::StatementInvalid
+ FALLBACK
+ end
+
+ def distinct_count(relation, column = nil, batch: true, batch_size: nil, start: nil, finish: nil)
+ if batch
+ Gitlab::Database::BatchCount.batch_distinct_count(relation, column, batch_size: batch_size, start: start, finish: finish)
+ else
+ relation.distinct_count_by(column)
+ end
+ rescue ActiveRecord::StatementInvalid
+ FALLBACK
+ end
+
+ def alt_usage_data(value = nil, fallback: FALLBACK, &block)
+ if block_given?
+ yield
+ else
+ value
+ end
+ rescue
+ fallback
+ end
+
+ def redis_usage_data(counter = nil, &block)
+ if block_given?
+ redis_usage_counter(&block)
+ elsif counter.present?
+ redis_usage_data_totals(counter)
+ end
+ end
+
+ def with_prometheus_client
+ if Gitlab::Prometheus::Internal.prometheus_enabled?
+ prometheus_address = Gitlab::Prometheus::Internal.uri
+ yield Gitlab::PrometheusClient.new(prometheus_address, allow_local_requests: true)
+ end
+ end
+
+ def measure_duration
+ result = nil
+ duration = Benchmark.realtime do
+ result = yield
+ end
+ [result, duration]
+ end
+
+ private
+
+ def redis_usage_counter
+ yield
+ rescue ::Redis::CommandError, Gitlab::UsageDataCounters::BaseCounter::UnknownEvent
+ FALLBACK
+ end
+
+ def redis_usage_data_totals(counter)
+ counter.totals
+ rescue ::Redis::CommandError, Gitlab::UsageDataCounters::BaseCounter::UnknownEvent
+ counter.fallback_totals
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/web_ide/config.rb b/lib/gitlab/web_ide/config.rb
new file mode 100644
index 00000000000..3b1fa162b53
--- /dev/null
+++ b/lib/gitlab/web_ide/config.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module WebIde
+ #
+ # Base GitLab WebIde Configuration facade
+ #
+ class Config
+ ConfigError = Class.new(StandardError)
+
+ def initialize(config, opts = {})
+ @config = build_config(config, opts)
+
+ @global = Entry::Global.new(@config,
+ with_image_ports: true)
+ @global.compose!
+ rescue Gitlab::Config::Loader::FormatError => e
+ raise Config::ConfigError, e.message
+ end
+
+ def valid?
+ @global.valid?
+ end
+
+ def errors
+ @global.errors
+ end
+
+ def to_hash
+ @config
+ end
+
+ def terminal_value
+ @global.terminal_value
+ end
+
+ private
+
+ def build_config(config, opts = {})
+ Gitlab::Config::Loader::Yaml.new(config).load!
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/web_ide/config/entry/global.rb b/lib/gitlab/web_ide/config/entry/global.rb
new file mode 100644
index 00000000000..50c3f2d294f
--- /dev/null
+++ b/lib/gitlab/web_ide/config/entry/global.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module WebIde
+ class Config
+ module Entry
+ ##
+ # This class represents a global entry - root Entry for entire
+ # GitLab WebIde Configuration file.
+ #
+ class Global < ::Gitlab::Config::Entry::Node
+ include ::Gitlab::Config::Entry::Configurable
+ include ::Gitlab::Config::Entry::Attributable
+
+ ALLOWED_KEYS = %i[terminal].freeze
+
+ validations do
+ validates :config, allowed_keys: ALLOWED_KEYS
+ end
+
+ entry :terminal, Entry::Terminal,
+ description: 'Configuration of the webide terminal.'
+
+ attributes :terminal
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/web_ide/config/entry/terminal.rb b/lib/gitlab/web_ide/config/entry/terminal.rb
new file mode 100644
index 00000000000..403e308d45b
--- /dev/null
+++ b/lib/gitlab/web_ide/config/entry/terminal.rb
@@ -0,0 +1,75 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module WebIde
+ class Config
+ module Entry
+ ##
+ # Entry that represents a concrete CI/CD job.
+ #
+ class Terminal < ::Gitlab::Config::Entry::Node
+ include ::Gitlab::Config::Entry::Configurable
+ include ::Gitlab::Config::Entry::Attributable
+
+ # By default the build will finish in a few seconds, not giving the webide
+ # enough time to connect to the terminal. This default script provides
+ # those seconds blocking the build from finishing inmediately.
+ DEFAULT_SCRIPT = ['sleep 60'].freeze
+
+ ALLOWED_KEYS = %i[image services tags before_script script variables].freeze
+
+ validations do
+ validates :config, allowed_keys: ALLOWED_KEYS
+ validates :config, job_port_unique: { data: ->(record) { record.ports } }
+
+ with_options allow_nil: true do
+ validates :tags, array_of_strings: true
+ end
+ end
+
+ entry :before_script, ::Gitlab::Ci::Config::Entry::Script,
+ description: 'Global before script overridden in this job.'
+
+ entry :script, ::Gitlab::Ci::Config::Entry::Commands,
+ description: 'Commands that will be executed in this job.'
+
+ entry :image, ::Gitlab::Ci::Config::Entry::Image,
+ description: 'Image that will be used to execute this job.'
+
+ entry :services, ::Gitlab::Ci::Config::Entry::Services,
+ description: 'Services that will be used to execute this job.'
+
+ entry :variables, ::Gitlab::Ci::Config::Entry::Variables,
+ description: 'Environment variables available for this job.'
+
+ attributes :tags
+
+ def value
+ to_hash.compact
+ end
+
+ private
+
+ def to_hash
+ { tag_list: tags || [],
+ yaml_variables: yaml_variables,
+ options: {
+ image: image_value,
+ services: services_value,
+ before_script: before_script_value,
+ script: script_value || DEFAULT_SCRIPT
+ }.compact }
+ end
+
+ def yaml_variables
+ return unless variables_value
+
+ variables_value.map do |key, value|
+ { key: key.to_s, value: value, public: true }
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/milestone_array.rb b/lib/milestone_array.rb
deleted file mode 100644
index 461e73e9670..00000000000
--- a/lib/milestone_array.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-# frozen_string_literal: true
-
-module MilestoneArray
- class << self
- def sort(array, sort_method)
- case sort_method
- when 'due_date_asc'
- sort_asc_nulls_last(array, 'due_date')
- when 'due_date_desc'
- sort_desc_nulls_last(array, 'due_date')
- when 'start_date_asc'
- sort_asc_nulls_last(array, 'start_date')
- when 'start_date_desc'
- sort_desc_nulls_last(array, 'start_date')
- when 'name_asc'
- sort_asc(array, 'title')
- when 'name_desc'
- sort_asc(array, 'title').reverse
- else
- array
- end
- end
-
- private
-
- def sort_asc_nulls_last(array, attribute)
- attribute = attribute.to_sym
-
- array.select(&attribute).sort_by(&attribute) + array.reject(&attribute)
- end
-
- def sort_desc_nulls_last(array, attribute)
- attribute = attribute.to_sym
-
- array.select(&attribute).sort_by(&attribute).reverse + array.reject(&attribute)
- end
-
- def sort_asc(array, attribute)
- array.sort_by(&attribute.to_sym)
- end
- end
-end
diff --git a/lib/object_storage/direct_upload.rb b/lib/object_storage/direct_upload.rb
index fd26663fef0..5eab882039d 100644
--- a/lib/object_storage/direct_upload.rb
+++ b/lib/object_storage/direct_upload.rb
@@ -2,7 +2,7 @@
module ObjectStorage
#
- # The DirectUpload c;ass generates a set of presigned URLs
+ # The DirectUpload class generates a set of presigned URLs
# that can be used to upload data to object storage from untrusted component: Workhorse, Runner?
#
# For Google it assumes that the platform supports variable Content-Length.
@@ -46,7 +46,7 @@ module ObjectStorage
MultipartUpload: multipart_upload_hash,
CustomPutHeaders: true,
PutHeaders: upload_options
- }.compact
+ }.merge(workhorse_client_hash).compact
end
def multipart_upload_hash
@@ -60,6 +60,32 @@ module ObjectStorage
}
end
+ def workhorse_client_hash
+ return {} unless aws?
+
+ {
+ UseWorkhorseClient: use_workhorse_s3_client?,
+ RemoteTempObjectID: object_name,
+ ObjectStorage: {
+ Provider: 'AWS',
+ S3Config: {
+ Bucket: bucket_name,
+ Region: credentials[:region],
+ Endpoint: credentials[:endpoint],
+ PathStyle: credentials.fetch(:path_style, false),
+ UseIamProfile: credentials.fetch(:use_iam_profile, false)
+ }
+ }
+ }
+ end
+
+ def use_workhorse_s3_client?
+ Feature.enabled?(:use_workhorse_s3_client, default_enabled: true) &&
+ credentials.fetch(:use_iam_profile, false) &&
+ # The Golang AWS SDK does not support V2 signatures
+ credentials.fetch(:aws_signature_version, 4).to_i >= 4
+ end
+
def provider
credentials[:provider].to_s
end
diff --git a/lib/peek/views/bullet_detailed.rb b/lib/peek/views/bullet_detailed.rb
new file mode 100644
index 00000000000..8e6f72f565e
--- /dev/null
+++ b/lib/peek/views/bullet_detailed.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+module Peek
+ module Views
+ class BulletDetailed < DetailedView
+ WARNING_MESSAGE = "Unoptimized queries detected"
+
+ def key
+ 'bullet'
+ end
+
+ def results
+ return {} unless ::Bullet.enable?
+ return {} unless calls > 0
+
+ {
+ calls: calls,
+ details: details,
+ warnings: [WARNING_MESSAGE]
+ }
+ end
+
+ private
+
+ def details
+ notifications.map do |notification|
+ # there is no public method which returns pure backtace:
+ # https://github.com/flyerhzm/bullet/blob/9cda9c224a46786ecfa894480c4dd4d304db2adb/lib/bullet/notification/n_plus_one_query.rb
+ backtrace = notification.body_with_caller
+
+ {
+ notification: "#{notification.title}: #{notification.body}",
+ backtrace: backtrace
+ }
+ end
+ end
+
+ def calls
+ notifications.size
+ end
+
+ def notifications
+ ::Bullet.notification_collector&.collection || []
+ end
+ end
+ end
+end
diff --git a/lib/peek/views/elasticsearch.rb b/lib/peek/views/elasticsearch.rb
new file mode 100644
index 00000000000..626a6fb1316
--- /dev/null
+++ b/lib/peek/views/elasticsearch.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+module Peek
+ module Views
+ class Elasticsearch < DetailedView
+ DEFAULT_THRESHOLDS = {
+ calls: 5,
+ duration: 1000,
+ individual_call: 1000
+ }.freeze
+
+ THRESHOLDS = {
+ production: {
+ calls: 5,
+ duration: 1000,
+ individual_call: 1000
+ }
+ }.freeze
+
+ def key
+ 'es'
+ end
+
+ def self.thresholds
+ @thresholds ||= THRESHOLDS.fetch(Rails.env.to_sym, DEFAULT_THRESHOLDS)
+ end
+
+ private
+
+ def duration
+ ::Gitlab::Instrumentation::ElasticsearchTransport.query_time * 1000
+ end
+
+ def calls
+ ::Gitlab::Instrumentation::ElasticsearchTransport.get_request_count
+ end
+
+ def call_details
+ ::Gitlab::Instrumentation::ElasticsearchTransport.detail_store
+ end
+
+ def format_call_details(call)
+ super.merge(request: "#{call[:method]} #{call[:path]}")
+ end
+ end
+ end
+end
diff --git a/lib/peek/views/gitaly.rb b/lib/peek/views/gitaly.rb
index 7dc00b16cc0..566ca4496c4 100644
--- a/lib/peek/views/gitaly.rb
+++ b/lib/peek/views/gitaly.rb
@@ -40,12 +40,6 @@ module Peek
super.merge(request: pretty_request || {})
end
-
- def setup_subscribers
- subscribe 'start_processing.action_controller' do
- ::Gitlab::GitalyClient.query_time = 0
- end
- end
end
end
end
diff --git a/lib/peek/views/redis_detailed.rb b/lib/peek/views/redis_detailed.rb
index 79845044d75..44ec0ec0f68 100644
--- a/lib/peek/views/redis_detailed.rb
+++ b/lib/peek/views/redis_detailed.rb
@@ -9,10 +9,15 @@ module Peek
'redis'
end
+ def detail_store
+ ::Gitlab::Instrumentation::Redis.detail_store
+ end
+
private
def format_call_details(call)
- super.merge(cmd: format_command(call[:cmd]))
+ super.merge(cmd: format_command(call[:cmd]),
+ instance: call[:storage])
end
def format_command(cmd)
diff --git a/lib/quality/test_level.rb b/lib/quality/test_level.rb
index 97b86fa8c2e..334643fd0d3 100644
--- a/lib/quality/test_level.rb
+++ b/lib/quality/test_level.rb
@@ -44,6 +44,7 @@ module Quality
views
workers
elastic_integration
+ tooling
],
integration: %w[
controllers
diff --git a/lib/support/init.d/gitlab b/lib/support/init.d/gitlab
index 8e9f220ec85..98cac0b0d1d 100755
--- a/lib/support/init.d/gitlab
+++ b/lib/support/init.d/gitlab
@@ -67,13 +67,13 @@ gitaly_log="$app_root/log/gitaly.log"
test -f /etc/default/gitlab && . /etc/default/gitlab
# Switch to the app_user if it is not they who are running the script.
-if [ `whoami` != "$app_user" ]; then
+if [ $(whoami) != "$app_user" ]; then
eval su - "$app_user" -c $(echo \")$shell_path -l -c \'$0 "$@"\'$(echo \"); exit;
fi
# Switch to the gitlab path, exit on failure.
if ! cd "$app_root" ; then
- echo "Failed to cd into $app_root, exiting!"; exit 1
+ echo "Failed to cd into $app_root, exiting!"; exit 1
fi
if [ -z "$SIDEKIQ_WORKERS" ]; then
@@ -341,7 +341,7 @@ start_gitlab() {
echo "Gitaly is already running with pid $gapid, not restarting"
else
$app_root/bin/daemon_with_pidfile $gitaly_pid_path \
- $gitaly_dir/gitaly $gitaly_dir/config.toml >> $gitaly_log 2>&1 &
+ $gitaly_dir/gitaly $gitaly_dir/config.toml >> $gitaly_log 2>&1 &
fi
fi
@@ -413,39 +413,39 @@ print_status() {
return
fi
if [ "$web_status" = "0" ]; then
- echo "The GitLab web server with pid $wpid is running."
+ echo "The GitLab web server with pid $wpid is running."
else
- printf "The GitLab web server is \033[31mnot running\033[0m.\n"
+ printf "The GitLab web server is \033[31mnot running\033[0m.\n"
fi
if [ "$sidekiq_status" = "0" ]; then
- echo "The GitLab Sidekiq job dispatcher with pid $spid is running."
+ echo "The GitLab Sidekiq job dispatcher with pid $spid is running."
else
- printf "The GitLab Sidekiq job dispatcher is \033[31mnot running\033[0m.\n"
+ printf "The GitLab Sidekiq job dispatcher is \033[31mnot running\033[0m.\n"
fi
if [ "$gitlab_workhorse_status" = "0" ]; then
- echo "The GitLab Workhorse with pid $hpid is running."
+ echo "The GitLab Workhorse with pid $hpid is running."
else
- printf "The GitLab Workhorse is \033[31mnot running\033[0m.\n"
+ printf "The GitLab Workhorse is \033[31mnot running\033[0m.\n"
fi
if [ "$mail_room_enabled" = true ]; then
if [ "$mail_room_status" = "0" ]; then
- echo "The GitLab MailRoom email processor with pid $mpid is running."
+ echo "The GitLab MailRoom email processor with pid $mpid is running."
else
- printf "The GitLab MailRoom email processor is \033[31mnot running\033[0m.\n"
+ printf "The GitLab MailRoom email processor is \033[31mnot running\033[0m.\n"
fi
fi
if [ "$gitlab_pages_enabled" = true ]; then
if [ "$gitlab_pages_status" = "0" ]; then
- echo "The GitLab Pages with pid $gppid is running."
+ echo "The GitLab Pages with pid $gppid is running."
else
- printf "The GitLab Pages is \033[31mnot running\033[0m.\n"
+ printf "The GitLab Pages is \033[31mnot running\033[0m.\n"
fi
fi
if [ "$gitaly_enabled" = true ]; then
if [ "$gitaly_status" = "0" ]; then
- echo "Gitaly with pid $gapid is running."
+ echo "Gitaly with pid $gapid is running."
else
- printf "Gitaly is \033[31mnot running\033[0m.\n"
+ printf "Gitaly is \033[31mnot running\033[0m.\n"
fi
fi
if [ "$web_status" = "0" ] && [ "$sidekiq_status" = "0" ] && [ "$gitlab_workhorse_status" = "0" ] && { [ "$mail_room_enabled" != true ] || [ "$mail_room_status" = "0" ]; } && { [ "$gitlab_pages_enabled" != true ] || [ "$gitlab_pages_status" = "0" ]; } && { [ "$gitaly_enabled" != true ] || [ "$gitaly_status" = "0" ]; }; then
@@ -490,25 +490,25 @@ restart_gitlab(){
case "$1" in
start)
- start_gitlab
- ;;
+ start_gitlab
+ ;;
stop)
- stop_gitlab
- ;;
+ stop_gitlab
+ ;;
restart)
- restart_gitlab
- ;;
+ restart_gitlab
+ ;;
reload|force-reload)
- reload_gitlab
- ;;
+ reload_gitlab
+ ;;
status)
- print_status
- exit $gitlab_status
- ;;
+ print_status
+ exit $gitlab_status
+ ;;
*)
- echo "Usage: service gitlab {start|stop|restart|reload|status}"
- exit 1
- ;;
+ echo "Usage: service gitlab {start|stop|restart|reload|status}"
+ exit 1
+ ;;
esac
exit
diff --git a/lib/tasks/gemojione.rake b/lib/tasks/gemojione.rake
index 3833689e07e..85393bba9a6 100644
--- a/lib/tasks/gemojione.rake
+++ b/lib/tasks/gemojione.rake
@@ -32,6 +32,7 @@ namespace :gemojione do
dir = Gemojione.images_path
resultant_emoji_map = {}
+ resultant_emoji_map_new = {}
Gitlab::Emoji.emojis.each do |name, emoji_hash|
# Ignore aliases
@@ -53,6 +54,16 @@ namespace :gemojione do
}
resultant_emoji_map[name] = entry
+
+ # Our new map is only characters to make the json substantially smaller
+ new_entry = {
+ c: category,
+ e: emoji_hash['moji'],
+ d: emoji_hash['description'],
+ u: Gitlab::Emoji.emoji_unicode_version(name)
+ }
+
+ resultant_emoji_map_new[name] = new_entry
end
end
@@ -60,6 +71,11 @@ namespace :gemojione do
File.open(out, 'w') do |handle|
handle.write(Gitlab::Json.pretty_generate(resultant_emoji_map))
end
+
+ out_new = File.join(Rails.root, 'public', '-', 'emojis', '1', 'emojis.json')
+ File.open(out_new, 'w') do |handle|
+ handle.write(Gitlab::Json.pretty_generate(resultant_emoji_map_new))
+ end
end
# This task will generate a standard and Retina sprite of all of the current
diff --git a/lib/tasks/gitlab/container_registry.rake b/lib/tasks/gitlab/container_registry.rake
new file mode 100644
index 00000000000..7687cb237cc
--- /dev/null
+++ b/lib/tasks/gitlab/container_registry.rake
@@ -0,0 +1,35 @@
+namespace :gitlab do
+ namespace :container_registry do
+ desc "GitLab | Container Registry | Configure"
+ task configure: :gitlab_environment do
+ configure
+ end
+
+ def configure
+ registry_config = Gitlab.config.registry
+
+ unless registry_config.enabled && registry_config.api_url.presence
+ puts "Registry is not enabled or registry api url is not present.".color(:yellow)
+ return
+ end
+
+ warn_user_is_not_gitlab
+
+ url = registry_config.api_url
+ # registry_info will query the /v2 route of the registry API. This route
+ # requires authentication, but not authorization (the response has no body,
+ # only headers that show the version of the registry). There is no
+ # associated user when running this rake, so we need to generate a valid
+ # JWT token with no access permissions to authenticate as a trusted client.
+ token = Auth::ContainerRegistryAuthenticationService.access_token([], [])
+ client = ContainerRegistry::Client.new(url, token: token)
+ info = client.registry_info
+
+ Gitlab::CurrentSettings.update!(
+ container_registry_vendor: info[:vendor] || '',
+ container_registry_version: info[:version] || '',
+ container_registry_features: info[:features] || []
+ )
+ end
+ end
+end
diff --git a/lib/tasks/gitlab/db.rake b/lib/tasks/gitlab/db.rake
index 506027aa866..4917d496d07 100644
--- a/lib/tasks/gitlab/db.rake
+++ b/lib/tasks/gitlab/db.rake
@@ -92,9 +92,42 @@ namespace :gitlab do
Rake::Task[task_name].reenable
end
- # Inform Rake that gitlab:schema:clean_structure_sql should be run every time rake db:structure:dump is run
+ desc 'This dumps GitLab specific database details - it runs after db:structure:dump'
+ task :dump_custom_structure do |task_name|
+ Gitlab::Database::CustomStructure.new.dump
+
+ # Allow this task to be called multiple times, as happens when running db:migrate:redo
+ Rake::Task[task_name].reenable
+ end
+
+ desc 'This loads GitLab specific database details - runs after db:structure:dump'
+ task :load_custom_structure do
+ configuration = Rails.application.config_for(:database)
+
+ ENV['PGHOST'] = configuration['host'] if configuration['host']
+ ENV['PGPORT'] = configuration['port'].to_s if configuration['port']
+ ENV['PGPASSWORD'] = configuration['password'].to_s if configuration['password']
+ ENV['PGUSER'] = configuration['username'].to_s if configuration['username']
+
+ command = 'psql'
+ dump_filepath = Gitlab::Database::CustomStructure.custom_dump_filepath.to_path
+ args = ['-v', 'ON_ERROR_STOP=1', '-q', '-X', '-f', dump_filepath, configuration['database']]
+
+ unless Kernel.system(command, *args)
+ raise "failed to execute:\n#{command} #{args.join(' ')}\n\n" \
+ "Please ensure `#{command}` is installed in your PATH and has proper permissions.\n\n"
+ end
+ end
+
+ # Inform Rake that custom tasks should be run every time rake db:structure:dump is run
Rake::Task['db:structure:dump'].enhance do
Rake::Task['gitlab:db:clean_structure_sql'].invoke
+ Rake::Task['gitlab:db:dump_custom_structure'].invoke
+ end
+
+ # Inform Rake that custom tasks should be run every time rake db:structure:load is run
+ Rake::Task['db:structure:load'].enhance do
+ Rake::Task['gitlab:db:load_custom_structure'].invoke
end
end
end
diff --git a/lib/tasks/gitlab/doctor/secrets.rake b/lib/tasks/gitlab/doctor/secrets.rake
new file mode 100644
index 00000000000..3fdef9dfc80
--- /dev/null
+++ b/lib/tasks/gitlab/doctor/secrets.rake
@@ -0,0 +1,12 @@
+namespace :gitlab do
+ namespace :doctor do
+ desc "GitLab | Check if the database encrypted values can be decrypted using current secrets"
+ task secrets: :gitlab_environment do
+ logger = Logger.new(STDOUT)
+
+ logger.level = Gitlab::Utils.to_boolean(ENV['VERBOSE']) ? Logger::DEBUG : Logger::INFO
+
+ Gitlab::Doctor::Secrets.new(logger).run!
+ end
+ end
+end
diff --git a/lib/tasks/gitlab/features.rake b/lib/tasks/gitlab/features.rake
index 9cf568c07fe..2309aa5d214 100644
--- a/lib/tasks/gitlab/features.rake
+++ b/lib/tasks/gitlab/features.rake
@@ -21,7 +21,7 @@ namespace :gitlab do
Gitlab::Git::RuggedImpl::Repository::FEATURE_FLAGS.each do |flag|
case status
when nil
- Feature.get(flag).remove
+ Feature.remove(flag)
when true
Feature.enable(flag)
when false
diff --git a/lib/tasks/gitlab/shell.rake b/lib/tasks/gitlab/shell.rake
index d6e62a5c550..edbaec85bd9 100644
--- a/lib/tasks/gitlab/shell.rake
+++ b/lib/tasks/gitlab/shell.rake
@@ -21,25 +21,12 @@ namespace :gitlab do
gitlab_url: gitlab_url,
http_settings: { self_signed_cert: false }.stringify_keys,
auth_file: File.join(user_home, ".ssh", "authorized_keys"),
- redis: {
- bin: `which redis-cli`.chomp,
- namespace: "resque:gitlab"
- }.stringify_keys,
log_level: "INFO",
audit_usernames: false
}.stringify_keys
- redis_url = URI.parse(ENV['REDIS_URL'] || "redis://localhost:6379")
-
- if redis_url.scheme == 'unix'
- config['redis']['socket'] = redis_url.path
- else
- config['redis']['host'] = redis_url.host
- config['redis']['port'] = redis_url.port
- end
-
# Generate config.yml based on existing gitlab settings
- File.open("config.yml", "w+") {|f| f.puts config.to_yaml}
+ File.open("config.yml", "w+") {|f| f.puts config.to_yaml }
[
%w(bin/install) + repository_storage_paths_args,
diff --git a/locale/am_ET/gitlab.po b/locale/am_ET/gitlab.po
index debbaaead07..bb68ba8c616 100644
--- a/locale/am_ET/gitlab.po
+++ b/locale/am_ET/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: am\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:37\n"
+"PO-Revision-Date: 2020-06-08 15:20\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] "%d አስተያየት"
msgstr[1] "%d አስተያየቶች"
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] "%d commit"
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] "%d መዋጮ"
msgstr[1] "%d መዋጮዎች"
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] "%d ተጨማሪ አስተያየት"
msgstr[1] "%d ተጨማሪ አስተያየቶች"
+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] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] "%d á•áˆ®áŒ€áŠ­á‰µ"
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr "%{commit_timeago} በ%{commit_author_link} የተደረሰ"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} ኮሮች"
@@ -316,6 +354,9 @@ msgstr "%{filePath} ተሰርዟáˆ"
msgid "%{firstLabel} +%{labelCount} more"
msgstr "%{firstLabel} +%{labelCount} ተጨማሪ"
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr "%{global_id} ለ%{expected_type} ትክክለኛ መታወቂያ አይደለáˆá¡á¡"
@@ -325,6 +366,9 @@ msgstr "%{group_docs_link_start}ቡድኖች %{group_docs_link_end} በርካታ
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr "%{group_name} በቡድን የሚተዳደሩ መለያዎችን ይጠቀማáˆá¢ በ%{group_name} የሚተዳደር አዲስ የGitLab መለያ መáጠር ይኖርቦታáˆá¢"
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr "%{icon} %{usersTag} ሰዎችን ወደ á‹á‹­á‹­á‰± ሊያክሉ áŠá‹á¢ ጥንቃቄ ያድርጉá¢"
@@ -337,6 +381,30 @@ msgstr "%{issuesSize} ጉዳዮች"
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr "%{issuesSize} ጉዳዮች ባለ %{maxIssueCount} ወሰን"
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr "%{label_for_message} አáˆá‰°áŒˆáŠ˜áˆ"
@@ -370,12 +438,21 @@ msgstr "%{loadingIcon} ተጀáˆáˆ¯áˆ"
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr "%{lock_path} በ GitLab ተጠቃሚ %{lock_user_id} ተቆáˆááˆ"
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr "%{mergeLength}/%{usersLength} merge ማድረጠይቻላáˆ"
msgid "%{mrText}, this issue will be closed automatically."
msgstr "%{mrText}ᣠይህ እትሠበራስ-ሰር ይዘጋáˆá¢"
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr "የ%{name} አáˆáˆ³á‹«"
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,13 +8991,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8627,7 +9009,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] ""
msgstr[1] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/ar_SA/gitlab.po b/locale/ar_SA/gitlab.po
index 64c1936c4a2..7fba63a73c0 100644
--- a/locale/ar_SA/gitlab.po
+++ b/locale/ar_SA/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: ar\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:31\n"
+"PO-Revision-Date: 2020-06-08 15:15\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -86,6 +86,24 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -122,6 +140,15 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -161,6 +188,15 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -287,6 +323,15 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+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[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -341,6 +386,24 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -371,6 +434,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -464,6 +530,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -473,6 +542,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -485,6 +557,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -518,12 +614,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -539,6 +644,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -587,6 +698,12 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -758,6 +875,9 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -1034,6 +1154,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -1064,6 +1187,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -1073,6 +1199,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -1109,7 +1238,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -1160,6 +1292,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -1172,9 +1307,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -1220,9 +1352,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1313,12 +1442,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1355,7 +1478,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1364,6 +1487,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1412,7 +1538,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1427,6 +1553,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1436,9 +1565,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1454,7 +1589,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1520,6 +1658,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1610,16 +1751,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1946,6 +2087,15 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
@@ -1955,58 +2105,103 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
+msgstr ""
+
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -2015,16 +2210,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -2198,6 +2411,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2363,9 +2579,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2387,6 +2600,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2462,6 +2678,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2498,9 +2717,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2516,6 +2741,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2525,6 +2753,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2549,12 +2780,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2564,9 +2789,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2630,6 +2861,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2714,12 +2948,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2729,12 +2957,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2843,6 +3077,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2855,7 +3092,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2969,6 +3206,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -3053,15 +3293,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -3119,6 +3377,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -3140,9 +3401,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -3161,6 +3419,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -3191,6 +3452,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -3206,6 +3470,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3683,16 +3950,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3716,7 +3983,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3725,6 +3992,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3743,6 +4013,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3773,9 +4046,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3803,6 +4073,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3878,7 +4154,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3893,6 +4169,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3929,6 +4208,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3971,6 +4256,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3989,6 +4277,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -4094,15 +4385,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4451,9 +4733,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4466,6 +4745,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4478,6 +4760,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4505,9 +4790,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4547,6 +4829,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4742,6 +5027,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4763,9 +5051,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4817,7 +5102,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4844,6 +5129,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4922,10 +5210,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -5084,6 +5372,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5318,9 +5612,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5399,6 +5690,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5429,6 +5723,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5438,9 +5735,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5498,6 +5801,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5516,6 +5822,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5555,6 +5864,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5564,6 +5876,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5600,6 +5915,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5765,7 +6083,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5789,9 +6110,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5825,9 +6143,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5876,16 +6191,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5912,6 +6221,24 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5924,6 +6251,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5948,27 +6278,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5990,10 +6332,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -6017,9 +6356,6 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -6041,6 +6377,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -6068,12 +6407,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -6092,7 +6425,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -6101,7 +6437,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -6140,10 +6476,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -6230,6 +6566,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -6275,9 +6614,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6293,9 +6629,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6392,7 +6725,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6410,9 +6743,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6431,9 +6761,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6443,9 +6770,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6488,6 +6812,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6500,6 +6827,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6539,6 +6869,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6572,6 +6908,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6623,9 +6962,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6662,6 +6998,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6686,6 +7025,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6734,6 +7076,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6758,6 +7103,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -7013,6 +7361,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -7049,6 +7400,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -7091,6 +7445,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -7184,15 +7544,6 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-msgstr[4] ""
-msgstr[5] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -7232,12 +7583,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -7247,9 +7592,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7376,12 +7718,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7403,13 +7751,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7529,10 +7877,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7541,9 +7889,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7553,6 +7916,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7580,12 +7946,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7595,6 +7976,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7607,6 +7994,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7838,6 +8228,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7886,6 +8279,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7910,6 +8306,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -8057,6 +8456,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -8072,6 +8474,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -8165,6 +8570,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -8174,9 +8582,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -8204,6 +8609,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8327,6 +8735,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8351,10 +8762,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8411,7 +8822,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8624,10 +9035,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8639,12 +9050,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8714,7 +9119,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8819,9 +9233,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8837,6 +9248,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8888,10 +9302,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8933,13 +9347,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8951,7 +9365,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8990,6 +9404,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -9008,6 +9425,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -9041,6 +9461,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -9056,6 +9479,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -9065,6 +9491,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -9143,18 +9572,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -9281,6 +9698,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9356,7 +9776,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9419,6 +9839,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9431,6 +9857,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9440,15 +9869,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9467,6 +9905,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9482,9 +9923,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9575,6 +10022,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9587,6 +10037,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9596,9 +10049,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9614,24 +10064,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9641,6 +10112,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9872,9 +10346,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9914,15 +10385,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -10100,6 +10571,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -10109,10 +10586,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -10163,6 +10640,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -10214,6 +10697,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -10232,6 +10718,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -10241,6 +10730,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10493,9 +10988,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10529,9 +11021,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10694,12 +11183,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10733,6 +11231,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10745,10 +11249,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10766,10 +11273,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10787,12 +11297,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10859,9 +11375,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -11063,6 +11576,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -11168,6 +11684,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -11177,6 +11696,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -11291,6 +11813,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -11300,6 +11825,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11450,6 +11978,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11459,7 +11990,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11468,6 +12002,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11480,7 +12020,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11498,13 +12041,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11516,6 +12059,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11525,6 +12071,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11534,10 +12083,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11630,10 +12179,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11666,6 +12215,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11699,6 +12251,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11723,18 +12281,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11789,6 +12365,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11828,6 +12428,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11864,18 +12470,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11888,6 +12503,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11951,6 +12569,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11963,6 +12584,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -12020,6 +12668,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -12065,6 +12716,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -12077,19 +12752,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -12215,6 +12893,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -12254,6 +12935,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12437,6 +13121,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12521,6 +13208,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12542,9 +13232,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12572,6 +13259,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12584,6 +13274,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12608,15 +13301,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12767,6 +13454,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12782,6 +13472,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12881,6 +13574,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12995,10 +13691,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -13025,6 +13721,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -13076,9 +13775,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -13088,9 +13784,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -13268,6 +13961,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -13277,9 +13973,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -13292,6 +13985,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -13325,6 +14021,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13373,9 +14072,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13436,7 +14144,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13454,6 +14162,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13475,9 +14186,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13499,19 +14207,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13535,6 +14246,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13595,6 +14327,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13613,6 +14351,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13649,6 +14390,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13715,6 +14459,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13724,6 +14525,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13733,21 +14540,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13808,6 +14633,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13922,6 +14750,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13931,6 +14762,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13943,9 +14777,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13955,9 +14786,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13991,6 +14819,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -14024,6 +14900,9 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -14090,6 +14969,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -14147,6 +15029,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -14165,18 +15050,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -14267,12 +15143,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -14297,6 +15179,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14432,6 +15317,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14456,6 +15344,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14570,9 +15461,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14639,6 +15536,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14648,9 +15554,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14720,7 +15623,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14765,7 +15668,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14780,6 +15683,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14810,7 +15716,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14858,6 +15764,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14876,6 +15785,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14897,6 +15809,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14984,6 +15902,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -15002,6 +15923,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -15032,22 +15956,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -15080,6 +16019,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -15167,6 +16109,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -15185,6 +16130,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -15227,9 +16175,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -15251,9 +16205,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -15275,9 +16226,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15386,6 +16334,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15446,15 +16397,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15467,30 +16427,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15506,6 +16490,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15542,6 +16529,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15635,6 +16628,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15710,6 +16706,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15800,6 +16799,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15836,6 +16838,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -16055,9 +17060,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -16103,9 +17105,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -16250,12 +17249,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -16286,6 +17279,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -16307,6 +17303,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -16337,6 +17336,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -16361,7 +17363,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -16370,6 +17372,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16484,9 +17489,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16652,6 +17654,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16697,6 +17702,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16847,6 +17855,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16940,12 +17951,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -17021,9 +18038,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -17042,30 +18056,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -17201,9 +18269,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -17213,6 +18278,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -17315,6 +18386,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -17324,9 +18398,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -17363,9 +18434,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17465,6 +18533,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17513,6 +18596,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17534,6 +18629,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17603,6 +18701,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17645,6 +18749,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17684,6 +18791,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17735,6 +18845,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17765,6 +18878,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17780,7 +18896,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17888,6 +19007,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17924,6 +19046,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17939,10 +19064,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17957,6 +19085,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17978,10 +19112,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -18059,6 +19190,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -18071,6 +19205,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -18221,6 +19361,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -18284,9 +19427,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -18323,9 +19463,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18455,9 +19592,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18515,6 +19658,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18545,10 +19691,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18677,9 +19823,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18692,9 +19844,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18704,24 +19853,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18857,6 +20006,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18938,6 +20090,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18989,12 +20144,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -19040,9 +20201,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -19115,6 +20285,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -19280,6 +20456,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -19316,6 +20495,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -19400,6 +20582,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -19418,7 +20603,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19457,15 +20642,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19490,12 +20675,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19520,6 +20714,18 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19706,6 +20912,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19742,9 +20951,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19841,6 +21056,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19880,6 +21098,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19928,6 +21149,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -20045,6 +21272,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -20210,7 +21440,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -20285,6 +21515,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -20411,6 +21644,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -20438,6 +21674,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20465,6 +21704,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20645,9 +21887,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20732,6 +21980,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20759,9 +22010,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -21017,6 +22265,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -21104,9 +22355,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -21143,9 +22391,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -21188,6 +22442,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -21362,6 +22619,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -21410,6 +22670,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21485,6 +22748,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21557,6 +22829,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21620,6 +22895,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21704,6 +22982,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21743,6 +23024,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21788,9 +23072,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21902,7 +23183,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21929,6 +23210,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21965,12 +23249,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21983,12 +23273,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -22007,7 +23309,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -22016,9 +23318,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -22073,9 +23372,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -22322,6 +23627,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -22394,6 +23702,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22514,6 +23828,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22571,15 +23888,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22595,9 +23906,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22616,6 +23924,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22727,6 +24038,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22784,10 +24098,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22796,6 +24110,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22835,6 +24152,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22844,9 +24164,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -23096,18 +24422,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -23126,6 +24446,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -23144,6 +24467,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -23168,9 +24494,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -23180,12 +24503,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -23195,12 +24524,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -23219,12 +24554,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -23249,7 +24590,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -23324,9 +24665,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23573,6 +24911,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23633,6 +24977,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23660,7 +25007,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23702,6 +25052,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23756,6 +25109,9 @@ msgstr[5] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23819,6 +25175,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23900,9 +25259,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23933,9 +25289,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -24044,6 +25397,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -24056,6 +25412,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -24077,7 +25436,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -24119,9 +25484,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -24161,12 +25523,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -24206,9 +25577,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -24242,9 +25610,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -24365,10 +25730,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -24377,10 +25745,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24497,6 +25865,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24524,6 +25895,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24539,6 +25913,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24617,6 +25994,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24665,6 +26045,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24680,7 +26063,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24773,6 +26156,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24800,6 +26186,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24818,6 +26207,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24851,7 +26246,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24887,7 +26285,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24980,9 +26378,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24992,12 +26399,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -25022,9 +26435,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -25076,6 +26495,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -25118,6 +26540,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -25307,6 +26732,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -25325,6 +26753,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -25343,6 +26774,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -25388,6 +26822,9 @@ msgstr[5] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -25397,6 +26834,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -25406,6 +26846,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25460,6 +26903,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -25475,7 +26921,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -25508,10 +26957,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25580,9 +27029,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25649,6 +27107,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25670,6 +27131,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25709,6 +27176,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25841,7 +27311,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -26021,9 +27491,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -26033,15 +27500,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -26054,6 +27512,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -26099,6 +27560,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -26138,9 +27602,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -26171,6 +27644,12 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -26225,6 +27704,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -26291,10 +27773,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -26357,6 +27839,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -26384,6 +27872,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -26411,6 +27902,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/az_AZ/gitlab.po b/locale/az_AZ/gitlab.po
new file mode 100644
index 00000000000..4a0b7d37c98
--- /dev/null
+++ b/locale/az_AZ/gitlab.po
@@ -0,0 +1,27339 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: gitlab-ee\n"
+"Report-Msgid-Bugs-To: \n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: Azerbaijani\n"
+"Language: az_AZ\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Crowdin-Project: gitlab-ee\n"
+"X-Crowdin-Language: az\n"
+"X-Crowdin-File: /master/locale/gitlab.pot\n"
+"PO-Revision-Date: 2020-06-08 15:11\n"
+
+msgid " %{start} to %{end}"
+msgstr ""
+
+msgid " (from %{timeoutSource})"
+msgstr ""
+
+msgid " Collected %{time}"
+msgstr ""
+
+msgid " Please sign in."
+msgstr ""
+
+msgid " Try to %{action} this file again."
+msgstr ""
+
+msgid " You need to do this before %{grace_period_deadline}."
+msgstr ""
+
+msgid " and"
+msgstr ""
+
+msgid " and "
+msgstr ""
+
+msgid " and %{sliced}"
+msgstr ""
+
+msgid " degraded on %d point"
+msgid_plural " degraded on %d points"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid " improved on %d point"
+msgid_plural " improved on %d points"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid " or "
+msgstr ""
+
+msgid " or <!merge request id>"
+msgstr ""
+
+msgid " or <#issue id>"
+msgstr ""
+
+msgid " or <&epic id>"
+msgstr ""
+
+msgid " or references (e.g. path/to/project!merge_request_id)"
+msgstr ""
+
+msgid "\"%{path}\" did not exist on \"%{ref}\""
+msgstr ""
+
+msgid "%d URL scanned"
+msgid_plural "%d URLs scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d changed file"
+msgid_plural "%d changed files"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d child epic"
+msgid_plural "%d child epics"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d code quality issue"
+msgid_plural "%d code quality issues"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d comment"
+msgid_plural "%d comments"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d commit"
+msgid_plural "%d commits"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d commit behind"
+msgid_plural "%d commits behind"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d commit,"
+msgid_plural "%d commits,"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d commits"
+msgstr ""
+
+msgid "%d contribution"
+msgid_plural "%d contributions"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d error"
+msgid_plural "%d errors"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d exporter"
+msgid_plural "%d exporters"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d failed"
+msgid_plural "%d failed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d fixed test result"
+msgid_plural "%d fixed test results"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d group selected"
+msgid_plural "%d groups selected"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d inaccessible merge request"
+msgid_plural "%d inaccessible merge requests"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d issue"
+msgid_plural "%d issues"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d issue selected"
+msgid_plural "%d issues selected"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d layer"
+msgid_plural "%d layers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d merge request"
+msgid_plural "%d merge requests"
+msgstr[0] ""
+msgstr[1] ""
+
+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] ""
+
+msgid "%d metric"
+msgid_plural "%d metrics"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d minute"
+msgid_plural "%d minutes"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d more comment"
+msgid_plural "%d more comments"
+msgstr[0] ""
+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] ""
+msgstr[1] ""
+
+msgid "%d project"
+msgid_plural "%d projects"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d request with warnings"
+msgid_plural "%d requests with warnings"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d second"
+msgid_plural "%d seconds"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d shard selected"
+msgid_plural "%d shards selected"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d tag"
+msgid_plural "%d tags"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d unresolved thread"
+msgid_plural "%d unresolved threads"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability dismissed"
+msgid_plural "%d vulnerabilities dismissed"
+msgstr[0] ""
+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] ""
+msgstr[1] ""
+
+msgid "%{actionText} & %{openOrClose} %{noteable}"
+msgstr ""
+
+msgid "%{authorsName}'s thread"
+msgstr ""
+
+msgid "%{commit_author_link} authored %{commit_timeago}"
+msgstr ""
+
+msgid "%{completedWeight} of %{totalWeight} weight completed"
+msgstr ""
+
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
+msgid "%{cores} cores"
+msgstr ""
+
+msgid "%{count} LOC/commit"
+msgstr ""
+
+msgid "%{count} approval required from %{name}"
+msgid_plural "%{count} approvals required from %{name}"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%{count} approvals from %{name}"
+msgstr ""
+
+msgid "%{count} files touched"
+msgstr ""
+
+msgid "%{count} more"
+msgstr ""
+
+msgid "%{count} more assignees"
+msgstr ""
+
+msgid "%{count} more release"
+msgid_plural "%{count} more releases"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%{count} of %{required} approvals from %{name}"
+msgstr ""
+
+msgid "%{count} of %{total}"
+msgstr ""
+
+msgid "%{count} participant"
+msgid_plural "%{count} participants"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%{count} pending comment"
+msgid_plural "%{count} pending comments"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%{count} related %{pluralized_subject}: %{links}"
+msgstr ""
+
+msgid "%{days} days until tags are automatically removed"
+msgstr ""
+
+msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
+msgstr ""
+
+msgid "%{duration}ms"
+msgstr ""
+
+msgid "%{edit_in_new_fork_notice} Try to cherry-pick this commit again."
+msgstr ""
+
+msgid "%{edit_in_new_fork_notice} Try to create a new directory again."
+msgstr ""
+
+msgid "%{edit_in_new_fork_notice} Try to revert this commit again."
+msgstr ""
+
+msgid "%{edit_in_new_fork_notice} Try to upload a file again."
+msgstr ""
+
+msgid "%{extra} more downstream pipelines"
+msgstr ""
+
+msgid "%{filePath} deleted"
+msgstr ""
+
+msgid "%{firstLabel} +%{labelCount} more"
+msgstr ""
+
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
+msgid "%{global_id} is not a valid id for %{expected_type}."
+msgstr ""
+
+msgid "%{group_docs_link_start}Groups%{group_docs_link_end} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
+msgstr ""
+
+msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
+msgstr ""
+
+msgid "%{host} sign-in from new location"
+msgstr ""
+
+msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
+msgstr ""
+
+msgid "%{issuableType} will be removed! Are you sure?"
+msgstr ""
+
+msgid "%{issuesSize} issues"
+msgstr ""
+
+msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
+msgstr ""
+
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
+msgid "%{label_for_message} unavailable"
+msgstr ""
+
+msgid "%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end} is a free, automated, and open certificate authority (CA), that give digital certificates in order to enable HTTPS (SSL/TLS) for websites."
+msgstr ""
+
+msgid "%{level_name} is not allowed in a %{group_level_name} group."
+msgstr ""
+
+msgid "%{level_name} is not allowed since the fork source project has lower visibility."
+msgstr ""
+
+msgid "%{lineOneStart}Drag and drop to upload your designs%{lineOneEnd} or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "%{link_start}Learn more%{link_end} about what information is shared with GitLab Inc."
+msgstr ""
+
+msgid "%{link_start}Read more%{link_end} about role permissions"
+msgstr ""
+
+msgid "%{link} can be used for binding events when something is happening within the project."
+msgstr ""
+
+msgid "%{listToShow}, and %{awardsListLength} more."
+msgstr ""
+
+msgid "%{loadingIcon} Started"
+msgstr ""
+
+msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
+msgstr ""
+
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
+msgid "%{mergeLength}/%{usersLength} can merge"
+msgstr ""
+
+msgid "%{mrText}, this issue will be closed automatically."
+msgstr ""
+
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
+msgstr ""
+
+msgid "%{name} contained %{resultsString}"
+msgstr ""
+
+msgid "%{name} found %{resultsString}"
+msgstr ""
+
+msgid "%{name} is scheduled for %{action}"
+msgstr ""
+
+msgid "%{name}'s avatar"
+msgstr ""
+
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{no_of_days} day"
+msgid_plural "%{no_of_days} days"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%{number_commits_behind} commits behind %{default_branch}, %{number_commits_ahead} commits ahead"
+msgstr ""
+
+msgid "%{openOrClose} %{noteable}"
+msgstr ""
+
+msgid "%{openedEpics} open, %{closedEpics} closed"
+msgstr ""
+
+msgid "%{openedIssues} open, %{closedIssues} closed"
+msgstr ""
+
+msgid "%{percentage}%% weight completed"
+msgstr ""
+
+msgid "%{percent}%% complete"
+msgstr ""
+
+msgid "%{percent}%{percentSymbol} complete"
+msgstr ""
+
+msgid "%{placeholder} is not a valid color scheme"
+msgstr ""
+
+msgid "%{placeholder} is not a valid theme"
+msgstr ""
+
+msgid "%{primary} (%{secondary})"
+msgstr ""
+
+msgid "%{releases} release"
+msgid_plural "%{releases} releases"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
+msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
+msgstr ""
+
+msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Enabled"
+msgstr ""
+
+msgid "%{service_title} %{message}."
+msgstr ""
+
+msgid "%{size} GiB"
+msgstr ""
+
+msgid "%{size} KiB"
+msgstr ""
+
+msgid "%{size} MiB"
+msgstr ""
+
+msgid "%{size} bytes"
+msgstr ""
+
+msgid "%{spammable_titlecase} was submitted to Akismet successfully."
+msgstr ""
+
+msgid "%{spanStart}at line%{spanEnd} %{errorLine}%{errorColumn}"
+msgstr ""
+
+msgid "%{spanStart}in%{spanEnd} %{errorFn}"
+msgstr ""
+
+msgid "%{start} to %{end}"
+msgstr ""
+
+msgid "%{state} epics"
+msgstr ""
+
+msgid "%{strongStart}Note:%{strongEnd} Once a custom stage has been added you can re-order stages by dragging them into the desired position."
+msgstr ""
+
+msgid "%{strong_start}%{branch_count}%{strong_end} Branch"
+msgid_plural "%{strong_start}%{branch_count}%{strong_end} Branches"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%{strong_start}%{commit_count}%{strong_end} Commit"
+msgid_plural "%{strong_start}%{commit_count}%{strong_end} Commits"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%{strong_start}%{human_size}%{strong_end} Files"
+msgstr ""
+
+msgid "%{strong_start}%{human_size}%{strong_end} Storage"
+msgstr ""
+
+msgid "%{strong_start}%{release_count}%{strong_end} Release"
+msgid_plural "%{strong_start}%{release_count}%{strong_end} Releases"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%{strong_start}%{tag_count}%{strong_end} Tag"
+msgid_plural "%{strong_start}%{tag_count}%{strong_end} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%{tabname} changed"
+msgstr ""
+
+msgid "%{tags} tag per image name"
+msgstr ""
+
+msgid "%{tags} tags per image name"
+msgstr ""
+
+msgid "%{tag}-%{evidence}-%{filename}"
+msgstr ""
+
+msgid "%{template_project_id} is unknown or invalid"
+msgstr ""
+
+msgid "%{text} %{files}"
+msgid_plural "%{text} %{files} files"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%{text} is available"
+msgstr ""
+
+msgid "%{timebox_name} should belong either to a project or a group."
+msgstr ""
+
+msgid "%{title} %{operator} %{threshold}"
+msgstr ""
+
+msgid "%{title} changes"
+msgstr ""
+
+msgid "%{token}..."
+msgstr ""
+
+msgid "%{totalWeight} total weight"
+msgstr ""
+
+msgid "%{total} open issue weight"
+msgstr ""
+
+msgid "%{total} open issues"
+msgstr ""
+
+msgid "%{usage_ping_link_start}Learn more%{usage_ping_link_end} about what information is shared with GitLab Inc."
+msgstr ""
+
+msgid "%{userName} (cannot merge)"
+msgstr ""
+
+msgid "%{userName}'s avatar"
+msgstr ""
+
+msgid "%{user_name} profile page"
+msgstr ""
+
+msgid "%{username}'s avatar"
+msgstr ""
+
+msgid "%{value} s"
+msgstr ""
+
+msgid "%{verb} %{time_spent_value} spent time."
+msgstr ""
+
+msgid "'%{level}' is not a valid visibility level"
+msgstr ""
+
+msgid "'%{name}' stage already exists"
+msgstr ""
+
+msgid "'%{source}' is not a import source"
+msgstr ""
+
+msgid "'%{template_name}' is unknown or invalid"
+msgstr ""
+
+msgid "(%d closed)"
+msgid_plural "(%d closed)"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
+msgid "(%{mrCount} merged)"
+msgstr ""
+
+msgid "(No changes)"
+msgstr ""
+
+msgid "(Show all)"
+msgstr ""
+
+msgid "(check progress)"
+msgstr ""
+
+msgid "(external source)"
+msgstr ""
+
+msgid "(removed)"
+msgstr ""
+
+msgid "(revoked)"
+msgstr ""
+
+msgid "*"
+msgstr ""
+
+msgid "+ %{amount} more"
+msgstr ""
+
+msgid "+ %{count} more"
+msgstr ""
+
+msgid "+ %{moreCount} more"
+msgstr ""
+
+msgid "+ %{numberOfHiddenAssignees} more"
+msgstr ""
+
+msgid "+%d more"
+msgid_plural "+%d more"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "+%{approvers} more approvers"
+msgstr ""
+
+msgid "+%{tags} more"
+msgstr ""
+
+msgid ", or "
+msgstr ""
+
+msgid "- Event"
+msgid_plural "- Events"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "- Runner is active and can process any new jobs"
+msgstr ""
+
+msgid "- Runner is paused and will not receive any new jobs"
+msgstr ""
+
+msgid "- User"
+msgid_plural "- Users"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "- of - weight completed"
+msgstr ""
+
+msgid "- show less"
+msgstr ""
+
+msgid "0 for unlimited"
+msgstr ""
+
+msgid "1 %{type} addition"
+msgid_plural "%{count} %{type} additions"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 %{type} modification"
+msgid_plural "%{count} %{type} modifications"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 Day"
+msgid_plural "%d Days"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 closed issue"
+msgid_plural "%{issues} closed issues"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 closed merge request"
+msgid_plural "%{merge_requests} closed merge requests"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 group"
+msgid_plural "%d groups"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 hour"
+msgid_plural "%d hours"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 merged merge request"
+msgid_plural "%{merge_requests} merged merge requests"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 minute"
+msgid_plural "%d minutes"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 month"
+msgstr ""
+
+msgid "1 open issue"
+msgid_plural "%{issues} open issues"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 open merge request"
+msgid_plural "%{merge_requests} open merge requests"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 pipeline"
+msgid_plural "%d pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 role"
+msgid_plural "%d roles"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 user"
+msgid_plural "%{num} users"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 week"
+msgstr ""
+
+msgid "1-9 contributions"
+msgstr ""
+
+msgid "10-19 contributions"
+msgstr ""
+
+msgid "1st contribution!"
+msgstr ""
+
+msgid "20-29 contributions"
+msgstr ""
+
+msgid "2FA"
+msgstr ""
+
+msgid "2FADevice|Registered On"
+msgstr ""
+
+msgid "3 days"
+msgstr ""
+
+msgid "3 hours"
+msgstr ""
+
+msgid "30 minutes"
+msgstr ""
+
+msgid "30+ contributions"
+msgstr ""
+
+msgid "403|Please contact your GitLab administrator to get permission."
+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 ""
+
+msgid "404|Page Not Found"
+msgstr ""
+
+msgid "404|Please contact your GitLab administrator if you think this is a mistake."
+msgstr ""
+
+msgid "8 hours"
+msgstr ""
+
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
+msgid "< 1 hour"
+msgstr ""
+
+msgid "<code>\"johnsmith@example.com\": \"@johnsmith\"</code> will add \"By <a href=\"#\">@johnsmith</a>\" to all issues and comments originally created by johnsmith@example.com, and will set <a href=\"#\">@johnsmith</a> as the assignee on all issues originally assigned to johnsmith@example.com."
+msgstr ""
+
+msgid "<code>\"johnsmith@example.com\": \"John Smith\"</code> will add \"By John Smith\" to all issues and comments originally created by johnsmith@example.com."
+msgstr ""
+
+msgid "<code>\"johnsmith@example.com\": \"johnsm...@example.com\"</code> will add \"By johnsm...@example.com\" to all issues and comments originally created by johnsmith@example.com. The email address or username is masked to ensure the user's privacy."
+msgstr ""
+
+msgid "<code>\"johnsmith@example.com\": \"johnsmith@example.com\"</code> will add \"By <a href=\"#\">johnsmith@example.com</a>\" to all issues and comments originally created by johnsmith@example.com. By default, the email address or username is masked to ensure the user's privacy. Use this option if you want to show the full email address."
+msgstr ""
+
+msgid "<namespace / project>"
+msgstr ""
+
+msgid "<no name set>"
+msgstr ""
+
+msgid "<no scopes selected>"
+msgstr ""
+
+msgid "<project name>"
+msgstr ""
+
+msgid "<strong>%{group_name}</strong> group members"
+msgstr ""
+
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
+msgid "<strong>Deletes</strong> source branch"
+msgstr ""
+
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
+msgstr ""
+
+msgid "A .NET Core console application template, customizable for any .NET Core project"
+msgstr ""
+
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
+msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
+msgstr ""
+
+msgid "A Hexo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
+msgstr ""
+
+msgid "A Hugo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
+msgstr ""
+
+msgid "A Jekyll site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
+msgstr ""
+
+msgid "A Let's Encrypt SSL certificate can not be obtained until your domain is verified."
+msgstr ""
+
+msgid "A Let's Encrypt account will be configured for this GitLab installation using your email address. You will receive emails to warn of expiring certificates."
+msgstr ""
+
+msgid "A basic page and serverless function that uses AWS Lambda, AWS API Gateway, and GitLab Pages"
+msgstr ""
+
+msgid "A complete DevOps platform"
+msgstr ""
+
+msgid "A default branch cannot be chosen for an empty project."
+msgstr ""
+
+msgid "A deleted user"
+msgstr ""
+
+msgid "A file with '%{file_name}' already exists in %{branch} branch"
+msgstr ""
+
+msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
+msgstr ""
+
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
+msgstr ""
+
+msgid "A member of the abuse team will review your report as soon as possible."
+msgstr ""
+
+msgid "A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgstr ""
+
+msgid "A merge request approval is required when the license compliance report contains a blacklisted license."
+msgstr ""
+
+msgid "A new Auto DevOps pipeline has been created, go to %{pipelines_link_start}Pipelines page%{pipelines_link_end} for details"
+msgstr ""
+
+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 ""
+
+msgid "A new Release %{tag} for %{name} was published. Visit the Releases page to read more about it:"
+msgstr ""
+
+msgid "A new branch will be created in your fork and a new merge request will be started."
+msgstr ""
+
+msgid "A new impersonation token has been created."
+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 project boilerplate for Salesforce App development with Salesforce Developer tools."
+msgstr ""
+
+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 ""
+
+msgid "A project is where you house your files (repository), plan your work (issues), and publish your documentation (wiki), %{among_other_things_link}."
+msgstr ""
+
+msgid "A ready-to-go template for use with Android apps."
+msgstr ""
+
+msgid "A ready-to-go template for use with iOS Swift apps."
+msgstr ""
+
+msgid "A regular expression that will be used to find the test coverage output in the job log. Leave blank to disable"
+msgstr ""
+
+msgid "A secure token that identifies an external storage request."
+msgstr ""
+
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
+msgid "A subscription will 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 ""
+
+msgid "A terraform report was generated in your pipelines."
+msgstr ""
+
+msgid "A user with write access to the source branch selected this option"
+msgstr ""
+
+msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
+msgstr ""
+
+msgid "API Token"
+msgstr ""
+
+msgid "AWS Access Key"
+msgstr ""
+
+msgid "AWS Access Key. Only required if not using role instance credentials"
+msgstr ""
+
+msgid "AWS Secret Access Key"
+msgstr ""
+
+msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgstr ""
+
+msgid "Abort"
+msgstr ""
+
+msgid "About GitLab"
+msgstr ""
+
+msgid "About GitLab CE"
+msgstr ""
+
+msgid "About auto deploy"
+msgstr ""
+
+msgid "About this feature"
+msgstr ""
+
+msgid "Abuse Reports"
+msgstr ""
+
+msgid "Abuse reports"
+msgstr ""
+
+msgid "Accept invitation"
+msgstr ""
+
+msgid "Accept terms"
+msgstr ""
+
+msgid "Acceptable for use in this project"
+msgstr ""
+
+msgid "Access Tokens"
+msgstr ""
+
+msgid "Access denied for your LDAP account."
+msgstr ""
+
+msgid "Access denied! Please verify you can add deploy keys to this repository."
+msgstr ""
+
+msgid "Access expiration date"
+msgstr ""
+
+msgid "Access forbidden. Check your access level."
+msgstr ""
+
+msgid "Access to '%{classification_label}' not allowed"
+msgstr ""
+
+msgid "Access to Pages websites are controlled based on the user's membership to a given project. By checking this box, users will be required to be logged in to have access to all Pages websites in your instance."
+msgstr ""
+
+msgid "AccessDropdown|Groups"
+msgstr ""
+
+msgid "AccessDropdown|Roles"
+msgstr ""
+
+msgid "AccessDropdown|Users"
+msgstr ""
+
+msgid "AccessTokens|Access Tokens"
+msgstr ""
+
+msgid "AccessTokens|Are you sure?"
+msgstr ""
+
+msgid "AccessTokens|Are you sure? Any RSS or calendar URLs currently in use will stop working."
+msgstr ""
+
+msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
+msgstr ""
+
+msgid "AccessTokens|Created"
+msgstr ""
+
+msgid "AccessTokens|Feed token"
+msgstr ""
+
+msgid "AccessTokens|Incoming email token"
+msgstr ""
+
+msgid "AccessTokens|It cannot be used to access any other data."
+msgstr ""
+
+msgid "AccessTokens|Keep this token secret. Anyone who gets ahold of it can access repository static objects as if they were you. You should %{reset_link_start}reset it%{reset_link_end} if that ever happens."
+msgstr ""
+
+msgid "AccessTokens|Keep this token secret. Anyone who gets ahold of it can create issues as if they were you. You should %{link_reset_it} if that ever happens."
+msgstr ""
+
+msgid "AccessTokens|Keep this token secret. Anyone who gets ahold of it can read activity and issue RSS feeds or your calendar feed as if they were you. You should %{link_reset_it} if that ever happens."
+msgstr ""
+
+msgid "AccessTokens|Personal Access Tokens"
+msgstr ""
+
+msgid "AccessTokens|Static object token"
+msgstr ""
+
+msgid "AccessTokens|They are the only accepted password when you have Two-Factor Authentication (2FA) enabled."
+msgstr ""
+
+msgid "AccessTokens|You can also use personal access tokens to authenticate against Git over HTTP."
+msgstr ""
+
+msgid "AccessTokens|You can generate a personal access token for each application you use that needs access to the GitLab API."
+msgstr ""
+
+msgid "AccessTokens|Your feed token is used to authenticate you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar, and is included in those feed URLs."
+msgstr ""
+
+msgid "AccessTokens|Your incoming email token is used to authenticate you when you create a new issue by email, and is included in your personal project-specific email addresses."
+msgstr ""
+
+msgid "AccessTokens|Your static object token is used to authenticate you when repository static objects (e.g. archives, blobs, ...) are being served from an external storage."
+msgstr ""
+
+msgid "AccessTokens|reset it"
+msgstr ""
+
+msgid "AccessibilityReport|Learn More"
+msgstr ""
+
+msgid "AccessibilityReport|Message: %{message}"
+msgstr ""
+
+msgid "AccessibilityReport|New"
+msgstr ""
+
+msgid "AccessibilityReport|The accessibility scanning found an error of the following type: %{code}"
+msgstr ""
+
+msgid "Account"
+msgstr ""
+
+msgid "Account ID"
+msgstr ""
+
+msgid "Account and limit"
+msgstr ""
+
+msgid "Account: %{account}"
+msgstr ""
+
+msgid "Action to take when receiving an alert."
+msgstr ""
+
+msgid "Activate"
+msgstr ""
+
+msgid "Activate Service Desk"
+msgstr ""
+
+msgid "Active"
+msgstr ""
+
+msgid "Active %{type} (%{token_length})"
+msgstr ""
+
+msgid "Active Sessions"
+msgstr ""
+
+msgid "Active Users:"
+msgstr ""
+
+msgid "Active users"
+msgstr ""
+
+msgid "Activity"
+msgstr ""
+
+msgid "Add"
+msgstr ""
+
+msgid "Add %d issue"
+msgid_plural "Add %d issues"
+msgstr[0] ""
+msgstr[1] ""
+
+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 ""
+
+msgid "Add CONTRIBUTING"
+msgstr ""
+
+msgid "Add GitLab to Slack"
+msgstr ""
+
+msgid "Add Group Webhooks and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Add Jaeger URL"
+msgstr ""
+
+msgid "Add Kubernetes cluster"
+msgstr ""
+
+msgid "Add LICENSE"
+msgstr ""
+
+msgid "Add README"
+msgstr ""
+
+msgid "Add Variable"
+msgstr ""
+
+msgid "Add Zoom meeting"
+msgstr ""
+
+msgid "Add a %{type}"
+msgstr ""
+
+msgid "Add a GPG key"
+msgstr ""
+
+msgid "Add a Grafana button in the admin sidebar, monitoring section, to access a variety of statistics on the health and performance of GitLab."
+msgstr ""
+
+msgid "Add a To Do"
+msgstr ""
+
+msgid "Add a bullet list"
+msgstr ""
+
+msgid "Add a comment to this line"
+msgstr ""
+
+msgid "Add a general comment to this %{noteableDisplayName}."
+msgstr ""
+
+msgid "Add a general comment to this %{noteable_name}."
+msgstr ""
+
+msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
+msgstr ""
+
+msgid "Add a line"
+msgstr ""
+
+msgid "Add a link"
+msgstr ""
+
+msgid "Add a new issue"
+msgstr ""
+
+msgid "Add a numbered list"
+msgstr ""
+
+msgid "Add a table"
+msgstr ""
+
+msgid "Add a task list"
+msgstr ""
+
+msgid "Add additional text to appear in all email communications. %{character_limit} character limit"
+msgstr ""
+
+msgid "Add an SSH key"
+msgstr ""
+
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
+msgstr ""
+
+msgid "Add an issue"
+msgstr ""
+
+msgid "Add another link"
+msgstr ""
+
+msgid "Add approval rule"
+msgstr ""
+
+msgid "Add bold text"
+msgstr ""
+
+msgid "Add child epic to an epic"
+msgstr ""
+
+msgid "Add comment now"
+msgstr ""
+
+msgid "Add domain"
+msgstr ""
+
+msgid "Add email address"
+msgstr ""
+
+msgid "Add environment"
+msgstr ""
+
+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 ""
+
+msgid "Add issues"
+msgstr ""
+
+msgid "Add italic text"
+msgstr ""
+
+msgid "Add label(s)"
+msgstr ""
+
+msgid "Add license"
+msgstr ""
+
+msgid "Add list"
+msgstr ""
+
+msgid "Add new application"
+msgstr ""
+
+msgid "Add new directory"
+msgstr ""
+
+msgid "Add or subtract spent time"
+msgstr ""
+
+msgid "Add reaction"
+msgstr ""
+
+msgid "Add request manually"
+msgstr ""
+
+msgid "Add strikethrough text"
+msgstr ""
+
+msgid "Add system hook"
+msgstr ""
+
+msgid "Add to Slack"
+msgstr ""
+
+msgid "Add to epic"
+msgstr ""
+
+msgid "Add to merge train"
+msgstr ""
+
+msgid "Add to merge train when pipeline succeeds"
+msgstr ""
+
+msgid "Add to review"
+msgstr ""
+
+msgid "Add to tree"
+msgstr ""
+
+msgid "Add user(s) to the group:"
+msgstr ""
+
+msgid "Add users to group"
+msgstr ""
+
+msgid "Add variable"
+msgstr ""
+
+msgid "Add webhook"
+msgstr ""
+
+msgid "AddMember|No users specified."
+msgstr ""
+
+msgid "AddMember|Too many users specified (limit is %{user_limit})"
+msgstr ""
+
+msgid "Added"
+msgstr ""
+
+msgid "Added %{epic_ref} as a child epic."
+msgstr ""
+
+msgid "Added %{label_references} %{label_text}."
+msgstr ""
+
+msgid "Added a To Do."
+msgstr ""
+
+msgid "Added an issue to an epic."
+msgstr ""
+
+msgid "Added at"
+msgstr ""
+
+msgid "Added for this merge request"
+msgstr ""
+
+msgid "Added in this version"
+msgstr ""
+
+msgid "Adding new applications is disabled in your GitLab instance. Please contact your GitLab administrator to get the permission"
+msgstr ""
+
+msgid "Additional minutes"
+msgstr ""
+
+msgid "Additional text"
+msgstr ""
+
+msgid "Adds"
+msgstr ""
+
+msgid "Adds %{epic_ref} as child epic."
+msgstr ""
+
+msgid "Adds %{labels} %{label_text}."
+msgstr ""
+
+msgid "Adds a To Do."
+msgstr ""
+
+msgid "Adds a Zoom meeting"
+msgstr ""
+
+msgid "Adds an issue to an epic."
+msgstr ""
+
+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 ""
+
+msgid "Admin Area"
+msgstr ""
+
+msgid "Admin Note"
+msgstr ""
+
+msgid "Admin Overview"
+msgstr ""
+
+msgid "Admin mode already enabled"
+msgstr ""
+
+msgid "Admin mode disabled"
+msgstr ""
+
+msgid "Admin mode enabled"
+msgstr ""
+
+msgid "Admin notes"
+msgstr ""
+
+msgid "AdminArea|Active users"
+msgstr ""
+
+msgid "AdminArea|Billable users"
+msgstr ""
+
+msgid "AdminArea|Blocked users"
+msgstr ""
+
+msgid "AdminArea|Bots"
+msgstr ""
+
+msgid "AdminArea|Developer"
+msgstr ""
+
+msgid "AdminArea|Guest"
+msgstr ""
+
+msgid "AdminArea|Included Free in license"
+msgstr ""
+
+msgid "AdminArea|Maintainer"
+msgstr ""
+
+msgid "AdminArea|Owner"
+msgstr ""
+
+msgid "AdminArea|Reporter"
+msgstr ""
+
+msgid "AdminArea|Stop all jobs"
+msgstr ""
+
+msgid "AdminArea|Stop all jobs?"
+msgstr ""
+
+msgid "AdminArea|Stop jobs"
+msgstr ""
+
+msgid "AdminArea|Stopping jobs failed"
+msgstr ""
+
+msgid "AdminArea|Total users"
+msgstr ""
+
+msgid "AdminArea|Users statistics"
+msgstr ""
+
+msgid "AdminArea|Users with highest role"
+msgstr ""
+
+msgid "AdminArea|Users without a Group and Project"
+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 "AdminNote|Note"
+msgstr ""
+
+msgid "AdminProjects| You’re about to permanently delete the project %{projectName}, its repository, and all related resources including issues, merge requests, etc.. Once you confirm and press %{strong_start}Delete project%{strong_end}, it cannot be undone or recovered."
+msgstr ""
+
+msgid "AdminProjects|Delete"
+msgstr ""
+
+msgid "AdminProjects|Delete Project %{projectName}?"
+msgstr ""
+
+msgid "AdminProjects|Delete project"
+msgstr ""
+
+msgid "AdminSettings|Apply integration settings to all Projects"
+msgstr ""
+
+msgid "AdminSettings|Auto DevOps domain"
+msgstr ""
+
+msgid "AdminSettings|Elasticsearch, PlantUML, Slack application, Third party offers, Snowplow, Amazon EKS have moved to Settings > General."
+msgstr ""
+
+msgid "AdminSettings|Enable shared runners for new projects"
+msgstr ""
+
+msgid "AdminSettings|Environment variables are protected by default"
+msgstr ""
+
+msgid "AdminSettings|Go to General Settings"
+msgstr ""
+
+msgid "AdminSettings|Integrations configured here will automatically apply to all projects on this instance."
+msgstr ""
+
+msgid "AdminSettings|No required pipeline"
+msgstr ""
+
+msgid "AdminSettings|Required pipeline configuration"
+msgstr ""
+
+msgid "AdminSettings|Select a pipeline configuration file"
+msgstr ""
+
+msgid "AdminSettings|Select a template"
+msgstr ""
+
+msgid "AdminSettings|Service template allows you to set default values for integrations"
+msgstr ""
+
+msgid "AdminSettings|Set an instance-wide auto included %{link_start}pipeline configuration%{link_end}. This pipeline configuration will be run after the project's own configuration."
+msgstr ""
+
+msgid "AdminSettings|Some settings have moved"
+msgstr ""
+
+msgid "AdminSettings|Specify a domain to use by default for every project's Auto Review Apps and Auto Deploy stages."
+msgstr ""
+
+msgid "AdminSettings|The required pipeline configuration can be selected from the %{code_start}gitlab-ci%{code_end} directory inside of the configured %{link_start}instance template repository%{link_end} or from GitLab provided configurations."
+msgstr ""
+
+msgid "AdminSettings|When creating a new environment variable it will be protected by default."
+msgstr ""
+
+msgid "AdminStatistics|Active Users"
+msgstr ""
+
+msgid "AdminStatistics|Forks"
+msgstr ""
+
+msgid "AdminStatistics|Issues"
+msgstr ""
+
+msgid "AdminStatistics|Merge Requests"
+msgstr ""
+
+msgid "AdminStatistics|Milestones"
+msgstr ""
+
+msgid "AdminStatistics|Notes"
+msgstr ""
+
+msgid "AdminStatistics|SSH Keys"
+msgstr ""
+
+msgid "AdminStatistics|Snippets"
+msgstr ""
+
+msgid "AdminUsers|2FA Disabled"
+msgstr ""
+
+msgid "AdminUsers|2FA Enabled"
+msgstr ""
+
+msgid "AdminUsers|Active"
+msgstr ""
+
+msgid "AdminUsers|Admin"
+msgstr ""
+
+msgid "AdminUsers|Admins"
+msgstr ""
+
+msgid "AdminUsers|Block"
+msgstr ""
+
+msgid "AdminUsers|Block user"
+msgstr ""
+
+msgid "AdminUsers|Block user %{username}?"
+msgstr ""
+
+msgid "AdminUsers|Blocked"
+msgstr ""
+
+msgid "AdminUsers|Blocking user has the following effects:"
+msgstr ""
+
+msgid "AdminUsers|Cannot unblock LDAP blocked users"
+msgstr ""
+
+msgid "AdminUsers|Deactivate"
+msgstr ""
+
+msgid "AdminUsers|Deactivate User %{username}?"
+msgstr ""
+
+msgid "AdminUsers|Deactivate user"
+msgstr ""
+
+msgid "AdminUsers|Deactivated"
+msgstr ""
+
+msgid "AdminUsers|Deactivating a user has the following effects:"
+msgstr ""
+
+msgid "AdminUsers|Delete User %{username} and contributions?"
+msgstr ""
+
+msgid "AdminUsers|Delete User %{username}?"
+msgstr ""
+
+msgid "AdminUsers|Delete user"
+msgstr ""
+
+msgid "AdminUsers|Delete user and contributions"
+msgstr ""
+
+msgid "AdminUsers|External"
+msgstr ""
+
+msgid "AdminUsers|Is using seat"
+msgstr ""
+
+msgid "AdminUsers|It's you!"
+msgstr ""
+
+msgid "AdminUsers|New user"
+msgstr ""
+
+msgid "AdminUsers|No users found"
+msgstr ""
+
+msgid "AdminUsers|Owned groups will be left"
+msgstr ""
+
+msgid "AdminUsers|Personal projects will be left"
+msgstr ""
+
+msgid "AdminUsers|Personal projects, group and user history will be left intact"
+msgstr ""
+
+msgid "AdminUsers|Reactivating a user will:"
+msgstr ""
+
+msgid "AdminUsers|Restore user access to the account, including web, Git and API."
+msgstr ""
+
+msgid "AdminUsers|Search by name, email or username"
+msgstr ""
+
+msgid "AdminUsers|Search users"
+msgstr ""
+
+msgid "AdminUsers|Send email to users"
+msgstr ""
+
+msgid "AdminUsers|Sort by"
+msgstr ""
+
+msgid "AdminUsers|The user will be logged out"
+msgstr ""
+
+msgid "AdminUsers|The user will not be able to access git repositories"
+msgstr ""
+
+msgid "AdminUsers|The user will not be able to access the API"
+msgstr ""
+
+msgid "AdminUsers|The user will not be able to use slash commands"
+msgstr ""
+
+msgid "AdminUsers|The user will not receive any notifications"
+msgstr ""
+
+msgid "AdminUsers|To confirm, type %{projectName}"
+msgstr ""
+
+msgid "AdminUsers|To confirm, type %{username}"
+msgstr ""
+
+msgid "AdminUsers|User will not be able to access git repositories"
+msgstr ""
+
+msgid "AdminUsers|User will not be able to login"
+msgstr ""
+
+msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
+msgstr ""
+
+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 %{strong_start}block user%{strong_end} feature instead. Once you %{strong_start}Delete user%{strong_end}, it cannot be undone or recovered."
+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 %{strong_start}block user%{strong_end} feature instead. Once you %{strong_start}Delete user%{strong_end}, it cannot be undone or recovered."
+msgstr ""
+
+msgid "Administration"
+msgstr ""
+
+msgid "Advanced"
+msgstr ""
+
+msgid "Advanced Settings"
+msgstr ""
+
+msgid "Advanced permissions, Large File Storage and Two-Factor authentication settings."
+msgstr ""
+
+msgid "Advanced search functionality"
+msgstr ""
+
+msgid "After a successful password update you will be redirected to login screen."
+msgstr ""
+
+msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
+msgid "Alert"
+msgid_plural "Alerts"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "AlertManagement|Acknowledged"
+msgstr ""
+
+msgid "AlertManagement|Alert"
+msgstr ""
+
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
+msgid "AlertManagement|Authorize external service"
+msgstr ""
+
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
+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 ""
+
+msgid "AlertManagement|End time"
+msgstr ""
+
+msgid "AlertManagement|Events"
+msgstr ""
+
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
+msgstr ""
+
+msgid "AlertManagement|Medium"
+msgstr ""
+
+msgid "AlertManagement|More information"
+msgstr ""
+
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
+msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
+msgstr ""
+
+msgid "AlertManagement|No alerts to display."
+msgstr ""
+
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
+msgid "AlertManagement|Overview"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
+msgid "AlertManagement|Resolved"
+msgstr ""
+
+msgid "AlertManagement|Service"
+msgstr ""
+
+msgid "AlertManagement|Severity"
+msgstr ""
+
+msgid "AlertManagement|Start time"
+msgstr ""
+
+msgid "AlertManagement|Status"
+msgstr ""
+
+msgid "AlertManagement|Surface alerts in GitLab"
+msgstr ""
+
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
+msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
+msgstr ""
+
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
+msgid "AlertManagement|Triggered"
+msgstr ""
+
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
+msgstr ""
+
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
+msgstr ""
+
+msgid "Alerts"
+msgstr ""
+
+msgid "Alerts endpoint"
+msgstr ""
+
+msgid "Algorithm"
+msgstr ""
+
+msgid "All"
+msgstr ""
+
+msgid "All %{replicableType} are being scheduled for %{action}"
+msgstr ""
+
+msgid "All (default)"
+msgstr ""
+
+msgid "All Members"
+msgstr ""
+
+msgid "All branches"
+msgstr ""
+
+msgid "All changes are committed"
+msgstr ""
+
+msgid "All default stages are currently visible"
+msgstr ""
+
+msgid "All email addresses will be used to identify your commits."
+msgstr ""
+
+msgid "All environments"
+msgstr ""
+
+msgid "All features are enabled for blank projects, from templates, or when importing, but you can disable them afterward in the project settings."
+msgstr ""
+
+msgid "All groups and projects"
+msgstr ""
+
+msgid "All issues for this milestone are closed."
+msgstr ""
+
+msgid "All issues for this milestone are closed. You may close this milestone now."
+msgstr ""
+
+msgid "All merge conflicts were resolved. The merge request can now be merged."
+msgstr ""
+
+msgid "All merge request dependencies have been merged"
+msgstr ""
+
+msgid "All paths are relative to the GitLab URL. Do not include %{relative_url_link_start}relative URL%{relative_url_link_end}."
+msgstr ""
+
+msgid "All projects"
+msgstr ""
+
+msgid "All security scans are enabled because %{linkStart}Auto DevOps%{linkEnd} is enabled on this project"
+msgstr ""
+
+msgid "All threads resolved"
+msgstr ""
+
+msgid "All users"
+msgstr ""
+
+msgid "All users must have a name."
+msgstr ""
+
+msgid "Allow \"%{group_name}\" to sign you in"
+msgstr ""
+
+msgid "Allow commits from members who can merge to the target branch."
+msgstr ""
+
+msgid "Allow group owners to manage LDAP-related settings"
+msgstr ""
+
+msgid "Allow only the selected protocols to be used for Git access."
+msgstr ""
+
+msgid "Allow owners to manage default branch protection per group"
+msgstr ""
+
+msgid "Allow owners to manually add users outside of LDAP"
+msgstr ""
+
+msgid "Allow projects within this group to use Git LFS"
+msgstr ""
+
+msgid "Allow public access to pipelines and job details, including output logs and artifacts"
+msgstr ""
+
+msgid "Allow rendering of PlantUML diagrams in Asciidoc documents."
+msgstr ""
+
+msgid "Allow repository mirroring to be configured by project maintainers"
+msgstr ""
+
+msgid "Allow requests to the local network from hooks and services."
+msgstr ""
+
+msgid "Allow requests to the local network from system hooks"
+msgstr ""
+
+msgid "Allow requests to the local network from web hooks and services"
+msgstr ""
+
+msgid "Allow this key to push to repository as well? (Default only allows pull access.)"
+msgstr ""
+
+msgid "Allow this secondary node to replicate content on Object Storage"
+msgstr ""
+
+msgid "Allow users to dismiss the broadcast message"
+msgstr ""
+
+msgid "Allow users to register any application to use GitLab as an OAuth provider"
+msgstr ""
+
+msgid "Allow users to request access (if visibility is public or internal)"
+msgstr ""
+
+msgid "Allowed email domain restriction only permitted for top-level groups"
+msgstr ""
+
+msgid "Allowed to fail"
+msgstr ""
+
+msgid "Allows you to add and manage Kubernetes clusters."
+msgstr ""
+
+msgid "Almost there"
+msgstr ""
+
+msgid "Also called \"Issuer\" or \"Relying party trust identifier\""
+msgstr ""
+
+msgid "Also called \"Relying party service URL\" or \"Reply URL\""
+msgstr ""
+
+msgid "Alternate support URL for help page and help dropdown"
+msgstr ""
+
+msgid "Alternatively, you can convert your account to a managed account by the %{group_name} group."
+msgstr ""
+
+msgid "Amazon EKS"
+msgstr ""
+
+msgid "Amazon EKS integration allows you to provision EKS clusters from GitLab."
+msgstr ""
+
+msgid "Amazon Web Services"
+msgstr ""
+
+msgid "Amazon authentication is not %{link_start}correctly configured%{link_end}. Ask your GitLab administrator if you want to use this service."
+msgstr ""
+
+msgid "Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication"
+msgstr ""
+
+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 ""
+
+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 ""
+
+msgid "An error has occurred"
+msgstr ""
+
+msgid "An error occurred adding a draft to the thread."
+msgstr ""
+
+msgid "An error occurred adding a new draft."
+msgstr ""
+
+msgid "An error occurred creating the new branch."
+msgstr ""
+
+msgid "An error occurred fetching the approval rules."
+msgstr ""
+
+msgid "An error occurred fetching the approvers for the new rule."
+msgstr ""
+
+msgid "An error occurred fetching the dropdown data."
+msgstr ""
+
+msgid "An error occurred fetching the project authors."
+msgstr ""
+
+msgid "An error occurred previewing the blob"
+msgstr ""
+
+msgid "An error occurred when toggling the notification subscription"
+msgstr ""
+
+msgid "An error occurred when trying to resolve a comment. Please try again."
+msgstr ""
+
+msgid "An error occurred when trying to resolve a discussion. Please try again."
+msgstr ""
+
+msgid "An error occurred when updating the issue weight"
+msgstr ""
+
+msgid "An error occurred while adding formatted title for epic"
+msgstr ""
+
+msgid "An error occurred while checking group path"
+msgstr ""
+
+msgid "An error occurred while committing your changes."
+msgstr ""
+
+msgid "An error occurred while decoding the file."
+msgstr ""
+
+msgid "An error occurred while deleting the approvers group"
+msgstr ""
+
+msgid "An error occurred while deleting the comment"
+msgstr ""
+
+msgid "An error occurred while deleting the pipeline."
+msgstr ""
+
+msgid "An error occurred while detecting host keys"
+msgstr ""
+
+msgid "An error occurred while disabling Service Desk."
+msgstr ""
+
+msgid "An error occurred while dismissing the alert. Refresh the page and try again."
+msgstr ""
+
+msgid "An error occurred while dismissing the feature highlight. Refresh the page and try dismissing again."
+msgstr ""
+
+msgid "An error occurred while enabling Service Desk."
+msgstr ""
+
+msgid "An error occurred while fetching coverage reports."
+msgstr ""
+
+msgid "An error occurred while fetching environments."
+msgstr ""
+
+msgid "An error occurred while fetching exposed artifacts."
+msgstr ""
+
+msgid "An error occurred while fetching folder content."
+msgstr ""
+
+msgid "An error occurred while fetching issues."
+msgstr ""
+
+msgid "An error occurred while fetching label colors."
+msgstr ""
+
+msgid "An error occurred while fetching markdown preview"
+msgstr ""
+
+msgid "An error occurred while fetching pending comments"
+msgstr ""
+
+msgid "An error occurred while fetching projects autocomplete."
+msgstr ""
+
+msgid "An error occurred while fetching sidebar data"
+msgstr ""
+
+msgid "An error occurred while fetching terraform reports."
+msgstr ""
+
+msgid "An error occurred while fetching the Service Desk address."
+msgstr ""
+
+msgid "An error occurred while fetching the board lists. Please try again."
+msgstr ""
+
+msgid "An error occurred while fetching the builds."
+msgstr ""
+
+msgid "An error occurred while fetching the job log."
+msgstr ""
+
+msgid "An error occurred while fetching the job trace."
+msgstr ""
+
+msgid "An error occurred while fetching the job."
+msgstr ""
+
+msgid "An error occurred while fetching the jobs."
+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 ""
+
+msgid "An error occurred while fetching this tab."
+msgstr ""
+
+msgid "An error occurred while generating a username. Please try again."
+msgstr ""
+
+msgid "An error occurred while getting files for - %{branchId}"
+msgstr ""
+
+msgid "An error occurred while getting projects"
+msgstr ""
+
+msgid "An error occurred while importing project: %{details}"
+msgstr ""
+
+msgid "An error occurred while initializing path locks"
+msgstr ""
+
+msgid "An error occurred while loading all the files."
+msgstr ""
+
+msgid "An error occurred while loading chart data"
+msgstr ""
+
+msgid "An error occurred while loading commit signatures"
+msgstr ""
+
+msgid "An error occurred while loading designs. Please try again."
+msgstr ""
+
+msgid "An error occurred while loading diff"
+msgstr ""
+
+msgid "An error occurred while loading filenames"
+msgstr ""
+
+msgid "An error occurred while loading group members."
+msgstr ""
+
+msgid "An error occurred while loading issues"
+msgstr ""
+
+msgid "An error occurred while loading merge requests."
+msgstr ""
+
+msgid "An error occurred while loading milestones"
+msgstr ""
+
+msgid "An error occurred while loading terraform report"
+msgstr ""
+
+msgid "An error occurred while loading the data. Please try again."
+msgstr ""
+
+msgid "An error occurred while loading the file"
+msgstr ""
+
+msgid "An error occurred while loading the file content."
+msgstr ""
+
+msgid "An error occurred while loading the file."
+msgstr ""
+
+msgid "An error occurred while loading the file. Please try again later."
+msgstr ""
+
+msgid "An error occurred while loading the merge request changes."
+msgstr ""
+
+msgid "An error occurred while loading the merge request version data."
+msgstr ""
+
+msgid "An error occurred while loading the merge request."
+msgstr ""
+
+msgid "An error occurred while loading the pipelines jobs."
+msgstr ""
+
+msgid "An error occurred while loading the subscription details."
+msgstr ""
+
+msgid "An error occurred while making the request."
+msgstr ""
+
+msgid "An error occurred while moving the issue."
+msgstr ""
+
+msgid "An error occurred while parsing recent searches"
+msgstr ""
+
+msgid "An error occurred while parsing the file."
+msgstr ""
+
+msgid "An error occurred while removing epics."
+msgstr ""
+
+msgid "An error occurred while removing issues."
+msgstr ""
+
+msgid "An error occurred while rendering preview broadcast message"
+msgstr ""
+
+msgid "An error occurred while reordering issues."
+msgstr ""
+
+msgid "An error occurred while retrieving calendar activity"
+msgstr ""
+
+msgid "An error occurred while retrieving diff"
+msgstr ""
+
+msgid "An error occurred while saving LDAP override status. Please try again."
+msgstr ""
+
+msgid "An error occurred while saving assignees"
+msgstr ""
+
+msgid "An error occurred while saving the approval settings"
+msgstr ""
+
+msgid "An error occurred while saving the template. Please check if the template exists."
+msgstr ""
+
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
+msgid "An error occurred while subscribing to notifications."
+msgstr ""
+
+msgid "An error occurred while triggering the job."
+msgstr ""
+
+msgid "An error occurred while trying to run a new pipeline for this Merge Request."
+msgstr ""
+
+msgid "An error occurred while unsubscribing to notifications."
+msgstr ""
+
+msgid "An error occurred while updating approvers"
+msgstr ""
+
+msgid "An error occurred while updating the comment"
+msgstr ""
+
+msgid "An error occurred while validating group path"
+msgstr ""
+
+msgid "An error occurred while validating username"
+msgstr ""
+
+msgid "An error occurred. Please try again."
+msgstr ""
+
+msgid "An error ocurred while loading your content. Please try again."
+msgstr ""
+
+msgid "An example project for managing Kubernetes clusters integrated with GitLab."
+msgstr ""
+
+msgid "An instance-level serverless domain already exists."
+msgstr ""
+
+msgid "An issue already exists"
+msgstr ""
+
+msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
+msgstr ""
+
+msgid "An unauthenticated user"
+msgstr ""
+
+msgid "An unexpected error occurred while checking the project environment."
+msgstr ""
+
+msgid "An unexpected error occurred while checking the project runners."
+msgstr ""
+
+msgid "An unexpected error occurred while communicating with the Web Terminal."
+msgstr ""
+
+msgid "An unexpected error occurred while starting the Web Terminal."
+msgstr ""
+
+msgid "An unexpected error occurred while stopping the Web Terminal."
+msgstr ""
+
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
+msgid "Analytics"
+msgstr ""
+
+msgid "Analyze a review version of your web application."
+msgstr ""
+
+msgid "Analyze your dependencies for known vulnerabilities."
+msgstr ""
+
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
+msgid "Analyze your source code for known vulnerabilities."
+msgstr ""
+
+msgid "Ancestors"
+msgstr ""
+
+msgid "Anonymous"
+msgstr ""
+
+msgid "Another action is currently in progress"
+msgstr ""
+
+msgid "Another issue tracker is already in use. Only one issue tracker service can be active at a time"
+msgstr ""
+
+msgid "Anti-spam verification"
+msgstr ""
+
+msgid "Any"
+msgstr ""
+
+msgid "Any Author"
+msgstr ""
+
+msgid "Any branch"
+msgstr ""
+
+msgid "Any eligible user"
+msgstr ""
+
+msgid "Any encrypted tokens"
+msgstr ""
+
+msgid "Any label"
+msgstr ""
+
+msgid "Any member with Developer or higher permissions to the project."
+msgstr ""
+
+msgid "Any milestone"
+msgstr ""
+
+msgid "Any namespace"
+msgstr ""
+
+msgid "Any user"
+msgstr ""
+
+msgid "App ID"
+msgstr ""
+
+msgid "Appearance"
+msgstr ""
+
+msgid "Appearance was successfully created."
+msgstr ""
+
+msgid "Appearance was successfully updated."
+msgstr ""
+
+msgid "Append the comment with %{shrug}"
+msgstr ""
+
+msgid "Append the comment with %{tableflip}"
+msgstr ""
+
+msgid "Application"
+msgstr ""
+
+msgid "Application ID"
+msgstr ""
+
+msgid "Application settings saved successfully"
+msgstr ""
+
+msgid "Application settings update failed"
+msgstr ""
+
+msgid "Application uninstalled but failed to destroy: %{error_message}"
+msgstr ""
+
+msgid "Application was successfully destroyed."
+msgstr ""
+
+msgid "Application was successfully updated."
+msgstr ""
+
+msgid "Application: %{name}"
+msgstr ""
+
+msgid "Applications"
+msgstr ""
+
+msgid "Applied"
+msgstr ""
+
+msgid "Apply"
+msgstr ""
+
+msgid "Apply a label"
+msgstr ""
+
+msgid "Apply a template"
+msgstr ""
+
+msgid "Apply changes"
+msgstr ""
+
+msgid "Apply suggestion"
+msgstr ""
+
+msgid "Apply template"
+msgstr ""
+
+msgid "Apply this approval rule to any branch or a specific protected branch."
+msgstr ""
+
+msgid "Applying a template will replace the existing issue description. Any changes you have made will be lost."
+msgstr ""
+
+msgid "Applying command"
+msgstr ""
+
+msgid "Applying command to %{commandDescription}"
+msgstr ""
+
+msgid "Applying multiple commands"
+msgstr ""
+
+msgid "Applying suggestion"
+msgstr ""
+
+msgid "Approval rules"
+msgstr ""
+
+msgid "ApprovalRuleRemove|%d member"
+msgid_plural "ApprovalRuleRemove|%d members"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ApprovalRuleRemove|Approvals from this member are not revoked."
+msgid_plural "ApprovalRuleRemove|Approvals from these members are not revoked."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ApprovalRuleRemove|You are about to remove the %{name} approver group which has %{nMembers}."
+msgstr ""
+
+msgid "ApprovalRuleSummary|%d member"
+msgid_plural "ApprovalRuleSummary|%d members"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ApprovalRuleSummary|%{count} approval required from %{membersCount}"
+msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCount}"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ApprovalRule|Approvers"
+msgstr ""
+
+msgid "ApprovalRule|Name"
+msgstr ""
+
+msgid "ApprovalRule|No. approvals required"
+msgstr ""
+
+msgid "ApprovalRule|Rule name"
+msgstr ""
+
+msgid "ApprovalRule|Target branch"
+msgstr ""
+
+msgid "ApprovalRule|e.g. QA, Security, etc."
+msgstr ""
+
+msgid "Approve"
+msgstr ""
+
+msgid "Approve a merge request"
+msgstr ""
+
+msgid "Approve the current merge request."
+msgstr ""
+
+msgid "Approved"
+msgstr ""
+
+msgid "Approved by: "
+msgstr ""
+
+msgid "Approved the current merge request."
+msgstr ""
+
+msgid "Approved-By"
+msgstr ""
+
+msgid "Approver"
+msgstr ""
+
+msgid "Approvers"
+msgstr ""
+
+msgid "Apr"
+msgstr ""
+
+msgid "April"
+msgstr ""
+
+msgid "Archive"
+msgstr ""
+
+msgid "Archive jobs"
+msgstr ""
+
+msgid "Archive project"
+msgstr ""
+
+msgid "Archived"
+msgstr ""
+
+msgid "Archived project! Repository and other project resources are read only"
+msgstr ""
+
+msgid "Archived project! Repository and other project resources are read-only"
+msgstr ""
+
+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}"
+msgstr ""
+
+msgid "Are you setting up GitLab for a company?"
+msgstr ""
+
+msgid "Are you sure that you want to archive this project?"
+msgstr ""
+
+msgid "Are you sure that you want to unarchive this project?"
+msgstr ""
+
+msgid "Are you sure you want to cancel editing this comment?"
+msgstr ""
+
+msgid "Are you sure you want to close this blocked issue?"
+msgstr ""
+
+msgid "Are you sure you want to delete %{name}?"
+msgstr ""
+
+msgid "Are you sure you want to delete these artifacts?"
+msgstr ""
+
+msgid "Are you sure you want to delete this %{typeOfComment}?"
+msgstr ""
+
+msgid "Are you sure you want to delete this board?"
+msgstr ""
+
+msgid "Are you sure you want to delete this device? This action cannot be undone."
+msgstr ""
+
+msgid "Are you sure you want to delete this list?"
+msgstr ""
+
+msgid "Are you sure you want to delete this pipeline schedule?"
+msgstr ""
+
+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 ""
+
+msgid "Are you sure you want to deploy this environment?"
+msgstr ""
+
+msgid "Are you sure you want to discard this comment?"
+msgstr ""
+
+msgid "Are you sure you want to erase this build?"
+msgstr ""
+
+msgid "Are you sure you want to lose unsaved changes?"
+msgstr ""
+
+msgid "Are you sure you want to lose your issue information?"
+msgstr ""
+
+msgid "Are you sure you want to merge immediately?"
+msgstr ""
+
+msgid "Are you sure you want to permanently delete this license?"
+msgstr ""
+
+msgid "Are you sure you want to re-deploy this environment?"
+msgstr ""
+
+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 ""
+
+msgid "Are you sure you want to remove %{group_name}?"
+msgstr ""
+
+msgid "Are you sure you want to remove the attachment?"
+msgstr ""
+
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
+msgid "Are you sure you want to remove this identity?"
+msgstr ""
+
+msgid "Are you sure you want to reset registration token?"
+msgstr ""
+
+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 ""
+
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
+msgstr ""
+
+msgid "Are you sure you want to revoke this nickname?"
+msgstr ""
+
+msgid "Are you sure you want to stop this environment?"
+msgstr ""
+
+msgid "Are you sure you want to unlock %{path_lock_path}?"
+msgstr ""
+
+msgid "Are you sure you want to unsubscribe from the %{type}: %{link_to_noteable_text}?"
+msgstr ""
+
+msgid "Are you sure?"
+msgstr ""
+
+msgid "Are you sure? All commits that were signed with this GPG key will be unverified."
+msgstr ""
+
+msgid "Are you sure? Removing this GPG key does not affect already signed commits."
+msgstr ""
+
+msgid "Are you sure? The device will be signed out of GitLab."
+msgstr ""
+
+msgid "Are you sure? This will invalidate your registered applications and U2F devices."
+msgstr ""
+
+msgid "Arrange charts"
+msgstr ""
+
+msgid "Artifact"
+msgstr ""
+
+msgid "Artifact ID"
+msgstr ""
+
+msgid "Artifact could not be deleted."
+msgstr ""
+
+msgid "Artifact was successfully deleted."
+msgstr ""
+
+msgid "Artifacts"
+msgstr ""
+
+msgid "As U2F devices are only supported by a few browsers, we require that you set up a two-factor authentication app before a U2F device. That way you'll always be able to log in - even when you're using an unsupported browser."
+msgstr ""
+
+msgid "AsanaService|%{user} pushed to branch %{branch} of %{project_name} ( %{commit_url} ):"
+msgstr ""
+
+msgid "AsanaService|Asana - Teamwork without email"
+msgstr ""
+
+msgid "AsanaService|Comma-separated list of branches which will be automatically inspected. Leave blank to include all branches."
+msgstr ""
+
+msgid "AsanaService|User Personal Access Token. User must have access to task, all comments will be attributed to this user."
+msgstr ""
+
+msgid "Ascending"
+msgstr ""
+
+msgid "Ask your group maintainer to set up a group Runner."
+msgstr ""
+
+msgid "Assertion consumer service URL"
+msgstr ""
+
+msgid "Assets"
+msgstr ""
+
+msgid "Assets:"
+msgstr ""
+
+msgid "Assign"
+msgstr ""
+
+msgid "Assign custom color like #FF0000"
+msgstr ""
+
+msgid "Assign epic"
+msgstr ""
+
+msgid "Assign labels"
+msgstr ""
+
+msgid "Assign milestone"
+msgstr ""
+
+msgid "Assign some issues to this milestone."
+msgstr ""
+
+msgid "Assign to"
+msgstr ""
+
+msgid "Assign yourself to these issues"
+msgstr ""
+
+msgid "Assign yourself to this issue"
+msgstr ""
+
+msgid "Assigned %{assignee_users_sentence}."
+msgstr ""
+
+msgid "Assigned Issues"
+msgstr ""
+
+msgid "Assigned Merge Requests"
+msgstr ""
+
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
+msgid "Assigned to me"
+msgstr ""
+
+msgid "Assignee"
+msgid_plural "%d Assignees"
+msgstr[0] ""
+msgstr[1] ""
+
+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 ""
+
+msgid "Assigns %{assignee_users_sentence}."
+msgstr ""
+
+msgid "At least one approval from a code owner is required to change files matching the respective CODEOWNER rules."
+msgstr ""
+
+msgid "At least one logging option is required to be enabled"
+msgstr ""
+
+msgid "At least one of group_id or project_id must be specified"
+msgstr ""
+
+msgid "At risk"
+msgstr ""
+
+msgid "Attach a file"
+msgstr ""
+
+msgid "Attach a file by drag &amp; drop or %{upload_link}"
+msgstr ""
+
+msgid "Attaching a file"
+msgid_plural "Attaching %d files"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Attaching the file failed."
+msgstr ""
+
+msgid "Audit Events"
+msgstr ""
+
+msgid "Audit Events is a way to keep track of important events that happened in GitLab."
+msgstr ""
+
+msgid "AuditEvents|(removed)"
+msgstr ""
+
+msgid "AuditEvents|Action"
+msgstr ""
+
+msgid "AuditEvents|At"
+msgstr ""
+
+msgid "AuditEvents|Target"
+msgstr ""
+
+msgid "AuditLogs|(removed)"
+msgstr ""
+
+msgid "AuditLogs|Action"
+msgstr ""
+
+msgid "AuditLogs|Author"
+msgstr ""
+
+msgid "AuditLogs|Date"
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
+msgid "AuditLogs|IP Address"
+msgstr ""
+
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
+msgid "AuditLogs|Object"
+msgstr ""
+
+msgid "AuditLogs|Project Events"
+msgstr ""
+
+msgid "AuditLogs|Target"
+msgstr ""
+
+msgid "AuditLogs|User Events"
+msgstr ""
+
+msgid "Aug"
+msgstr ""
+
+msgid "August"
+msgstr ""
+
+msgid "Authenticate"
+msgstr ""
+
+msgid "Authenticate with GitHub"
+msgstr ""
+
+msgid "Authenticating"
+msgstr ""
+
+msgid "Authentication Failure"
+msgstr ""
+
+msgid "Authentication Log"
+msgstr ""
+
+msgid "Authentication failed: %{error_message}"
+msgstr ""
+
+msgid "Authentication log"
+msgstr ""
+
+msgid "Authentication method"
+msgstr ""
+
+msgid "Authentication method updated"
+msgstr ""
+
+msgid "Authentication via U2F device failed."
+msgstr ""
+
+msgid "Author"
+msgstr ""
+
+msgid "Authored %{timeago} by %{author}"
+msgstr ""
+
+msgid "Authorization code:"
+msgstr ""
+
+msgid "Authorization key"
+msgstr ""
+
+msgid "Authorization was granted by entering your username and password in the application."
+msgstr ""
+
+msgid "Authorize"
+msgstr ""
+
+msgid "Authorize %{link_to_client} to use your account?"
+msgstr ""
+
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
+msgid "Authorized %{new_chat_name}"
+msgstr ""
+
+msgid "Authorized At"
+msgstr ""
+
+msgid "Authorized applications (%{size})"
+msgstr ""
+
+msgid "Authors: %{authors}"
+msgstr ""
+
+msgid "Auto DevOps"
+msgstr ""
+
+msgid "Auto DevOps enabled"
+msgstr ""
+
+msgid "Auto DevOps, runners and job artifacts"
+msgstr ""
+
+msgid "Auto stop successfully canceled."
+msgstr ""
+
+msgid "Auto-cancel redundant, pending pipelines"
+msgstr ""
+
+msgid "Auto-close referenced issues on default branch"
+msgstr ""
+
+msgid "AutoDevOps|Auto DevOps"
+msgstr ""
+
+msgid "AutoDevOps|Auto DevOps can automatically build, test, and deploy applications based on predefined continuous integration and delivery configuration. %{auto_devops_start}Learn more about Auto DevOps%{auto_devops_end} or use our %{quickstart_start}quick start guide%{quickstart_end} to get started right away."
+msgstr ""
+
+msgid "AutoDevOps|Auto DevOps documentation"
+msgstr ""
+
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
+msgid "AutoDevOps|Enable in settings"
+msgstr ""
+
+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 ""
+
+msgid "AutoDevOps|The Auto DevOps pipeline has been enabled and will be used if no alternative CI configuration file is found. %{more_information_link}"
+msgstr ""
+
+msgid "Autocomplete"
+msgstr ""
+
+msgid "Autocomplete description"
+msgstr ""
+
+msgid "Autocomplete hint"
+msgstr ""
+
+msgid "Autocomplete usage hint"
+msgstr ""
+
+msgid "Automatic certificate management using %{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end}"
+msgstr ""
+
+msgid "Automatic certificate management using Let's Encrypt"
+msgstr ""
+
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
+msgid "Automatically marked as default internal user"
+msgstr ""
+
+msgid "Automatically resolved"
+msgstr ""
+
+msgid "Automatically update this project's branches and tags from the upstream repository every hour."
+msgstr ""
+
+msgid "Autosave|Note"
+msgstr ""
+
+msgid "Available"
+msgstr ""
+
+msgid "Available for dependency and container scanning"
+msgstr ""
+
+msgid "Available group Runners: %{runners}"
+msgstr ""
+
+msgid "Available shared Runners:"
+msgstr ""
+
+msgid "Available specific runners"
+msgstr ""
+
+msgid "Avatar for %{assigneeName}"
+msgstr ""
+
+msgid "Avatar for %{name}"
+msgstr ""
+
+msgid "Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Average per day: %{average}"
+msgstr ""
+
+msgid "Back to page %{number}"
+msgstr ""
+
+msgid "Background Color"
+msgstr ""
+
+msgid "Background Jobs"
+msgstr ""
+
+msgid "Background color"
+msgstr ""
+
+msgid "Badges"
+msgstr ""
+
+msgid "Badges|A new badge was added."
+msgstr ""
+
+msgid "Badges|Add badge"
+msgstr ""
+
+msgid "Badges|Adding the badge failed, please check the entered URLs and try again."
+msgstr ""
+
+msgid "Badges|Badge image URL"
+msgstr ""
+
+msgid "Badges|Badge image preview"
+msgstr ""
+
+msgid "Badges|Delete badge"
+msgstr ""
+
+msgid "Badges|Delete badge?"
+msgstr ""
+
+msgid "Badges|Deleting the badge failed, please try again."
+msgstr ""
+
+msgid "Badges|Group Badge"
+msgstr ""
+
+msgid "Badges|Link"
+msgstr ""
+
+msgid "Badges|Name"
+msgstr ""
+
+msgid "Badges|No badge image"
+msgstr ""
+
+msgid "Badges|No image to preview"
+msgstr ""
+
+msgid "Badges|Please fill in a valid URL"
+msgstr ""
+
+msgid "Badges|Project Badge"
+msgstr ""
+
+msgid "Badges|Reload badge image"
+msgstr ""
+
+msgid "Badges|Save changes"
+msgstr ""
+
+msgid "Badges|Saving the badge failed, please check the entered URLs and try again."
+msgstr ""
+
+msgid "Badges|The %{docsLinkStart}variables%{docsLinkEnd} GitLab supports: %{placeholders}"
+msgstr ""
+
+msgid "Badges|The badge was deleted."
+msgstr ""
+
+msgid "Badges|The badge was saved."
+msgstr ""
+
+msgid "Badges|This group has no badges"
+msgstr ""
+
+msgid "Badges|This project has no badges"
+msgstr ""
+
+msgid "Badges|You are going to delete this badge. Deleted badges <strong>cannot</strong> be restored."
+msgstr ""
+
+msgid "Badges|Your badges"
+msgstr ""
+
+msgid "Badges|e.g. %{exampleUrl}"
+msgstr ""
+
+msgid "Badge|New"
+msgstr ""
+
+msgid "Balsamiq file could not be loaded."
+msgstr ""
+
+msgid "BambooService|A continuous integration and build server"
+msgstr ""
+
+msgid "BambooService|A user with API access, if applicable"
+msgstr ""
+
+msgid "BambooService|Atlassian Bamboo CI"
+msgstr ""
+
+msgid "BambooService|Bamboo build plan key like KEY"
+msgstr ""
+
+msgid "BambooService|Bamboo root URL like https://bamboo.example.com"
+msgstr ""
+
+msgid "BambooService|You must set up automatic revision labeling and a repository trigger in Bamboo."
+msgstr ""
+
+msgid "BatchComments|Delete all pending comments"
+msgstr ""
+
+msgid "BatchComments|Discard review?"
+msgstr ""
+
+msgid "BatchComments|You're about to discard your review which will delete all of your pending comments. The deleted comments %{strong_start}cannot%{strong_end} be restored."
+msgstr ""
+
+msgid "Be careful. Changing the project's namespace can have unintended side effects."
+msgstr ""
+
+msgid "Be careful. Renaming a project's repository can have unintended side effects."
+msgstr ""
+
+msgid "Begin with the selected commit"
+msgstr ""
+
+msgid "Below are examples of regex for existing tools:"
+msgstr ""
+
+msgid "Below are the fingerprints for the current instance SSH host keys."
+msgstr ""
+
+msgid "Below you will find all the groups that are public."
+msgstr ""
+
+msgid "Billing"
+msgstr ""
+
+msgid "BillingPlans|%{group_name} is currently using the %{plan_name} plan."
+msgstr ""
+
+msgid "BillingPlans|@%{user_name} you are currently using the %{plan_name} plan."
+msgstr ""
+
+msgid "BillingPlans|Congratulations, your new trial is activated"
+msgstr ""
+
+msgid "BillingPlans|If you would like to downgrade your plan please contact %{support_link_start}Customer Support%{support_link_end}."
+msgstr ""
+
+msgid "BillingPlans|Learn more about each plan by reading our %{faq_link}, or start a free 30-day trial of GitLab.com Gold."
+msgstr ""
+
+msgid "BillingPlans|Learn more about each plan by visiting our %{pricing_page_link}."
+msgstr ""
+
+msgid "BillingPlans|Manage plan"
+msgstr ""
+
+msgid "BillingPlans|Pricing page"
+msgstr ""
+
+msgid "BillingPlans|See all %{plan_name} features"
+msgstr ""
+
+msgid "BillingPlans|This group uses the plan associated with its parent group."
+msgstr ""
+
+msgid "BillingPlans|To manage the plan for this group, visit the billing section of %{parent_billing_page_link}."
+msgstr ""
+
+msgid "BillingPlans|Your GitLab.com %{plan} trial will <strong>expire after %{expiration_date}</strong>. You can retain access to the %{plan} features by upgrading below."
+msgstr ""
+
+msgid "BillingPlans|Your GitLab.com trial expired on %{expiration_date}. You can restore access to the features at any time by upgrading below."
+msgstr ""
+
+msgid "BillingPlans|billed annually at %{price_per_year}"
+msgstr ""
+
+msgid "BillingPlans|frequently asked questions"
+msgstr ""
+
+msgid "BillingPlans|monthly"
+msgstr ""
+
+msgid "BillingPlans|per user"
+msgstr ""
+
+msgid "BillingPlan|Upgrade"
+msgstr ""
+
+msgid "Bitbucket Server Import"
+msgstr ""
+
+msgid "Bitbucket import"
+msgstr ""
+
+msgid "Blocked"
+msgstr ""
+
+msgid "Blocked issue"
+msgstr ""
+
+msgid "Blocks"
+msgstr ""
+
+msgid "Blog"
+msgstr ""
+
+msgid "Blue helpers indicate an action to be taken."
+msgstr ""
+
+msgid "Board name"
+msgstr ""
+
+msgid "Board scope"
+msgstr ""
+
+msgid "Board scope affects which issues are displayed for anyone who visits this board"
+msgstr ""
+
+msgid "BoardBlankState|Add default lists"
+msgstr ""
+
+msgid "BoardBlankState|Add the following default lists to your Issue Board with one click:"
+msgstr ""
+
+msgid "BoardBlankState|Nevermind, I'll use my own"
+msgstr ""
+
+msgid "BoardBlankState|Starting out with the default set of lists will get you right on the way to making the most of your board."
+msgstr ""
+
+msgid "Boards"
+msgstr ""
+
+msgid "Boards and Board Lists"
+msgstr ""
+
+msgid "Boards|Collapse"
+msgstr ""
+
+msgid "Boards|Edit board"
+msgstr ""
+
+msgid "Boards|Expand"
+msgstr ""
+
+msgid "Boards|View scope"
+msgstr ""
+
+msgid "Branch"
+msgstr ""
+
+msgid "Branch %{branchName} was not found in this project's repository."
+msgstr ""
+
+msgid "Branch <strong>%{branch_name}</strong> was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}"
+msgstr ""
+
+msgid "Branch has changed"
+msgstr ""
+
+msgid "Branch is already taken"
+msgstr ""
+
+msgid "Branch name"
+msgstr ""
+
+msgid "Branch not loaded - %{branchId}"
+msgstr ""
+
+msgid "Branch prefix"
+msgstr ""
+
+msgid "BranchSwitcherPlaceholder|Search branches"
+msgstr ""
+
+msgid "BranchSwitcherTitle|Switch branch"
+msgstr ""
+
+msgid "Branches"
+msgstr ""
+
+msgid "Branches|Active"
+msgstr ""
+
+msgid "Branches|Active branches"
+msgstr ""
+
+msgid "Branches|All"
+msgstr ""
+
+msgid "Branches|Cant find HEAD commit for this branch"
+msgstr ""
+
+msgid "Branches|Compare"
+msgstr ""
+
+msgid "Branches|Delete all branches that are merged into '%{default_branch}'"
+msgstr ""
+
+msgid "Branches|Delete branch"
+msgstr ""
+
+msgid "Branches|Delete merged branches"
+msgstr ""
+
+msgid "Branches|Delete protected branch"
+msgstr ""
+
+msgid "Branches|Delete protected branch '%{branch_name}'?"
+msgstr ""
+
+msgid "Branches|Deleting the '%{branch_name}' branch cannot be undone. Are you sure?"
+msgstr ""
+
+msgid "Branches|Deleting the merged branches cannot be undone. Are you sure?"
+msgstr ""
+
+msgid "Branches|Filter by branch name"
+msgstr ""
+
+msgid "Branches|Merged into %{default_branch}"
+msgstr ""
+
+msgid "Branches|New branch"
+msgstr ""
+
+msgid "Branches|No branches to show"
+msgstr ""
+
+msgid "Branches|Once you confirm and press %{delete_protected_branch}, it cannot be undone or recovered."
+msgstr ""
+
+msgid "Branches|Only a project maintainer or owner can delete a protected branch"
+msgstr ""
+
+msgid "Branches|Overview"
+msgstr ""
+
+msgid "Branches|Protected branches can be managed in %{project_settings_link}."
+msgstr ""
+
+msgid "Branches|Show active branches"
+msgstr ""
+
+msgid "Branches|Show all branches"
+msgstr ""
+
+msgid "Branches|Show more active branches"
+msgstr ""
+
+msgid "Branches|Show more stale branches"
+msgstr ""
+
+msgid "Branches|Show overview of the branches"
+msgstr ""
+
+msgid "Branches|Show stale branches"
+msgstr ""
+
+msgid "Branches|Sort by"
+msgstr ""
+
+msgid "Branches|Stale"
+msgstr ""
+
+msgid "Branches|Stale branches"
+msgstr ""
+
+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 ""
+
+msgid "Branches|This branch hasn’t been merged into %{default_branch}."
+msgstr ""
+
+msgid "Branches|To avoid data loss, consider merging this branch before deleting it."
+msgstr ""
+
+msgid "Branches|To confirm, type %{branch_name_confirmation}:"
+msgstr ""
+
+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|You’re about to permanently delete the protected branch %{branch_name}."
+msgstr ""
+
+msgid "Branches|diverged from upstream"
+msgstr ""
+
+msgid "Branches|merged"
+msgstr ""
+
+msgid "Branches|project settings"
+msgstr ""
+
+msgid "Branches|protected"
+msgstr ""
+
+msgid "Broadcast Message was successfully created."
+msgstr ""
+
+msgid "Broadcast Message was successfully updated."
+msgstr ""
+
+msgid "Browse Directory"
+msgstr ""
+
+msgid "Browse File"
+msgstr ""
+
+msgid "Browse Files"
+msgstr ""
+
+msgid "Browse artifacts"
+msgstr ""
+
+msgid "Browse files"
+msgstr ""
+
+msgid "BuildArtifacts|An error occurred while fetching the artifacts"
+msgstr ""
+
+msgid "BuildArtifacts|Loading artifacts"
+msgstr ""
+
+msgid "Built-in"
+msgstr ""
+
+msgid "Bulk request concurrency"
+msgstr ""
+
+msgid "Burndown chart"
+msgstr ""
+
+msgid "BurndownChartLabel|Open issue weight"
+msgstr ""
+
+msgid "BurndownChartLabel|Open issues"
+msgstr ""
+
+msgid "Burnup chart"
+msgstr ""
+
+msgid "Business"
+msgstr ""
+
+msgid "Business metrics (Custom)"
+msgstr ""
+
+msgid "Buy License"
+msgstr ""
+
+msgid "Buy more Pipeline minutes"
+msgstr ""
+
+msgid "By %{user_name}"
+msgstr ""
+
+msgid "By default GitLab sends emails in HTML and plain text formats so mail clients can choose what format to use. Disable this option if you only want to send emails in plain text format."
+msgstr ""
+
+msgid "By default, all projects and groups will use the global notifications setting."
+msgstr ""
+
+msgid "ByAuthor|by"
+msgstr ""
+
+msgid "CHANGELOG"
+msgstr ""
+
+msgid "CI / CD"
+msgstr ""
+
+msgid "CI / CD Analytics"
+msgstr ""
+
+msgid "CI / CD Settings"
+msgstr ""
+
+msgid "CI Lint"
+msgstr ""
+
+msgid "CI settings"
+msgstr ""
+
+msgid "CI variables"
+msgstr ""
+
+msgid "CI will run using the credentials assigned above."
+msgstr ""
+
+msgid "CI/CD"
+msgstr ""
+
+msgid "CI/CD configuration"
+msgstr ""
+
+msgid "CI/CD for external repo"
+msgstr ""
+
+msgid "CI/CD settings"
+msgstr ""
+
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
+msgid "CICD|Auto DevOps"
+msgstr ""
+
+msgid "CICD|Automatic deployment to staging, manual deployment to production"
+msgstr ""
+
+msgid "CICD|Continuous deployment to production"
+msgstr ""
+
+msgid "CICD|Continuous deployment to production using timed incremental rollout"
+msgstr ""
+
+msgid "CICD|Default to Auto DevOps pipeline"
+msgstr ""
+
+msgid "CICD|Default to Auto DevOps pipeline for all projects"
+msgstr ""
+
+msgid "CICD|Deployment strategy"
+msgstr ""
+
+msgid "CICD|Jobs"
+msgstr ""
+
+msgid "CICD|The Auto DevOps pipeline will run if no alternative CI configuration file is found."
+msgstr ""
+
+msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
+msgstr ""
+
+msgid "CICD|group enabled"
+msgstr ""
+
+msgid "CICD|instance enabled"
+msgstr ""
+
+msgid "CLOSED"
+msgstr ""
+
+msgid "CLOSED (MOVED)"
+msgstr ""
+
+msgid "CONTRIBUTING"
+msgstr ""
+
+msgid "CPU"
+msgstr ""
+
+msgid "Callback URL"
+msgstr ""
+
+msgid "Can be manually deployed to"
+msgstr ""
+
+msgid "Can override approvers and approvals required per merge request"
+msgstr ""
+
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
+msgid "Can't find HEAD commit for this branch"
+msgstr ""
+
+msgid "Can't find variable: ZiteReader"
+msgstr ""
+
+msgid "Can't load mermaid module: %{err}"
+msgstr ""
+
+msgid "Can't remove group members without group managed account"
+msgstr ""
+
+msgid "Can't scan the code?"
+msgstr ""
+
+msgid "Can't update snippet: %{err}"
+msgstr ""
+
+msgid "Canary"
+msgstr ""
+
+msgid "Canary Deployments is a popular CI strategy, where a small portion of the fleet is updated to the new version of your application."
+msgstr ""
+
+msgid "Cancel"
+msgstr ""
+
+msgid "Cancel running"
+msgstr ""
+
+msgid "Cancel this job"
+msgstr ""
+
+msgid "Canceled deployment to"
+msgstr ""
+
+msgid "Cancelling Preview"
+msgstr ""
+
+msgid "Cannot be merged automatically"
+msgstr ""
+
+msgid "Cannot create the abuse report. The user has been deleted."
+msgstr ""
+
+msgid "Cannot create the abuse report. This user has been blocked."
+msgstr ""
+
+msgid "Cannot have multiple Jira imports running at the same time"
+msgstr ""
+
+msgid "Cannot import because issues are not available in this project."
+msgstr ""
+
+msgid "Cannot make epic confidential if it contains not-confidential issues"
+msgstr ""
+
+msgid "Cannot make epic confidential if it contains not-confidential sub-epics"
+msgstr ""
+
+msgid "Cannot merge"
+msgstr ""
+
+msgid "Cannot modify managed Kubernetes cluster"
+msgstr ""
+
+msgid "Cannot modify provider during creation"
+msgstr ""
+
+msgid "Cannot promote issue because it does not belong to a group."
+msgstr ""
+
+msgid "Cannot promote issue due to insufficient permissions."
+msgstr ""
+
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
+msgstr ""
+
+msgid "Cannot set confidential epic for not-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 ""
+
+msgid "Cannot skip two factor authentication setup"
+msgstr ""
+
+msgid "Capacity threshold"
+msgstr ""
+
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
+msgid "Certificate"
+msgstr ""
+
+msgid "Certificate (PEM)"
+msgstr ""
+
+msgid "Certificate Issuer"
+msgstr ""
+
+msgid "Certificate Subject"
+msgstr ""
+
+msgid "Change assignee"
+msgstr ""
+
+msgid "Change assignee(s)"
+msgstr ""
+
+msgid "Change assignee(s)."
+msgstr ""
+
+msgid "Change branches"
+msgstr ""
+
+msgid "Change label"
+msgstr ""
+
+msgid "Change milestone"
+msgstr ""
+
+msgid "Change path"
+msgstr ""
+
+msgid "Change permissions"
+msgstr ""
+
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
+msgid "Change template"
+msgstr ""
+
+msgid "Change this value to influence how frequently the GitLab UI polls for updates."
+msgstr ""
+
+msgid "Change title"
+msgstr ""
+
+msgid "Change your password"
+msgstr ""
+
+msgid "Change your password or recover your current one"
+msgstr ""
+
+msgid "ChangeTypeActionLabel|Pick into branch"
+msgstr ""
+
+msgid "ChangeTypeActionLabel|Revert in branch"
+msgstr ""
+
+msgid "ChangeTypeAction|Cherry-pick"
+msgstr ""
+
+msgid "ChangeTypeAction|Revert"
+msgstr ""
+
+msgid "ChangeTypeAction|This will create a new commit in order to revert the existing changes."
+msgstr ""
+
+msgid "Changed assignee(s)."
+msgstr ""
+
+msgid "Changed the title to \"%{title_param}\"."
+msgstr ""
+
+msgid "Changes"
+msgstr ""
+
+msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
+msgstr ""
+
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
+msgid "Changes are unknown"
+msgstr ""
+
+msgid "Changes suppressed. Click to show."
+msgstr ""
+
+msgid "Changes the title to \"%{title_param}\"."
+msgstr ""
+
+msgid "Changes won't take place until the index is %{link_start}recreated%{link_end}."
+msgstr ""
+
+msgid "Changing a Release tag is only supported via Releases API. %{linkStart}More information%{linkEnd}"
+msgstr ""
+
+msgid "Changing group path can have unintended side effects."
+msgstr ""
+
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
+msgid "Charts"
+msgstr ""
+
+msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
+msgstr ""
+
+msgid "Chat"
+msgstr ""
+
+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 ""
+
+msgid "ChatMessage|Commit"
+msgstr ""
+
+msgid "ChatMessage|Failed job"
+msgstr ""
+
+msgid "ChatMessage|Failed stage"
+msgstr ""
+
+msgid "ChatMessage|Invalid CI config YAML file"
+msgstr ""
+
+msgid "ChatMessage|Pipeline #%{pipeline_id} %{humanized_status} in %{duration}"
+msgstr ""
+
+msgid "ChatMessage|Pipeline %{pipeline_link} of %{ref_type} %{ref_link} by %{user_combined_name} %{humanized_status}"
+msgstr ""
+
+msgid "ChatMessage|Tag"
+msgstr ""
+
+msgid "ChatMessage|and [%{count} more](%{pipeline_failed_jobs_url})"
+msgstr ""
+
+msgid "ChatMessage|has failed"
+msgstr ""
+
+msgid "ChatMessage|has passed"
+msgstr ""
+
+msgid "ChatMessage|has passed with warnings"
+msgstr ""
+
+msgid "ChatMessage|in %{duration}"
+msgstr ""
+
+msgid "ChatMessage|in %{project_link}"
+msgstr ""
+
+msgid "Check again"
+msgstr ""
+
+msgid "Check feature availability on namespace plan"
+msgstr ""
+
+msgid "Check the %{docs_link_start}documentation%{docs_link_end}."
+msgstr ""
+
+msgid "Check your .gitlab-ci.yml"
+msgstr ""
+
+msgid "Check your Docker images for known vulnerabilities."
+msgstr ""
+
+msgid "Checking %{text} availability…"
+msgstr ""
+
+msgid "Checking approval status"
+msgstr ""
+
+msgid "Checking branch availability..."
+msgstr ""
+
+msgid "Checking group path availability..."
+msgstr ""
+
+msgid "Checking username availability..."
+msgstr ""
+
+msgid "Checkout"
+msgstr ""
+
+msgid "Checkout|$%{selectedPlanPrice} per user per year"
+msgstr ""
+
+msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
+msgstr ""
+
+msgid "Checkout|%{name}'s GitLab subscription"
+msgstr ""
+
+msgid "Checkout|%{selectedPlanText} plan"
+msgstr ""
+
+msgid "Checkout|%{startDate} - %{endDate}"
+msgstr ""
+
+msgid "Checkout|(x%{numberOfUsers})"
+msgstr ""
+
+msgid "Checkout|Billing address"
+msgstr ""
+
+msgid "Checkout|Checkout"
+msgstr ""
+
+msgid "Checkout|City"
+msgstr ""
+
+msgid "Checkout|Confirm purchase"
+msgstr ""
+
+msgid "Checkout|Confirming..."
+msgstr ""
+
+msgid "Checkout|Continue to billing"
+msgstr ""
+
+msgid "Checkout|Continue to payment"
+msgstr ""
+
+msgid "Checkout|Country"
+msgstr ""
+
+msgid "Checkout|Create a new group"
+msgstr ""
+
+msgid "Checkout|Credit card form failed to load. Please try again."
+msgstr ""
+
+msgid "Checkout|Credit card form failed to load: %{message}"
+msgstr ""
+
+msgid "Checkout|Edit"
+msgstr ""
+
+msgid "Checkout|Exp %{expirationMonth}/%{expirationYear}"
+msgstr ""
+
+msgid "Checkout|Failed to confirm your order! Please try again."
+msgstr ""
+
+msgid "Checkout|Failed to confirm your order: %{message}. Please try again."
+msgstr ""
+
+msgid "Checkout|Failed to load countries. Please try again."
+msgstr ""
+
+msgid "Checkout|Failed to load states. Please try again."
+msgstr ""
+
+msgid "Checkout|Failed to register credit card. Please try again."
+msgstr ""
+
+msgid "Checkout|GitLab group"
+msgstr ""
+
+msgid "Checkout|GitLab plan"
+msgstr ""
+
+msgid "Checkout|Group"
+msgstr ""
+
+msgid "Checkout|Name of company or organization using GitLab"
+msgstr ""
+
+msgid "Checkout|Need more users? Purchase GitLab for your %{company}."
+msgstr ""
+
+msgid "Checkout|Number of users"
+msgstr ""
+
+msgid "Checkout|Payment method"
+msgstr ""
+
+msgid "Checkout|Please select a country"
+msgstr ""
+
+msgid "Checkout|Please select a state"
+msgstr ""
+
+msgid "Checkout|Select"
+msgstr ""
+
+msgid "Checkout|State"
+msgstr ""
+
+msgid "Checkout|Street address"
+msgstr ""
+
+msgid "Checkout|Submitting the credit card form failed with code %{errorCode}: %{errorMessage}"
+msgstr ""
+
+msgid "Checkout|Subscription details"
+msgstr ""
+
+msgid "Checkout|Subtotal"
+msgstr ""
+
+msgid "Checkout|Tax"
+msgstr ""
+
+msgid "Checkout|Total"
+msgstr ""
+
+msgid "Checkout|Users"
+msgstr ""
+
+msgid "Checkout|You'll create your new group after checkout"
+msgstr ""
+
+msgid "Checkout|Your organization"
+msgstr ""
+
+msgid "Checkout|Your subscription will be applied to this group"
+msgstr ""
+
+msgid "Checkout|Zip code"
+msgstr ""
+
+msgid "Checkout|company or team"
+msgstr ""
+
+msgid "Cherry-pick this commit"
+msgstr ""
+
+msgid "Cherry-pick this merge request"
+msgstr ""
+
+msgid "Child"
+msgstr ""
+
+msgid "Child epic does not exist."
+msgstr ""
+
+msgid "Child epic doesn't exist."
+msgstr ""
+
+msgid "Choose <strong>Create archive</strong> and wait for archiving to complete."
+msgstr ""
+
+msgid "Choose <strong>Next</strong> at the bottom of the page."
+msgstr ""
+
+msgid "Choose a branch/tag (e.g. %{master}) or enter a commit (e.g. %{sha}) to see what's changed or to create a merge request."
+msgstr ""
+
+msgid "Choose a file"
+msgstr ""
+
+msgid "Choose a group"
+msgstr ""
+
+msgid "Choose a role permission"
+msgstr ""
+
+msgid "Choose a template"
+msgstr ""
+
+msgid "Choose a template..."
+msgstr ""
+
+msgid "Choose a type..."
+msgstr ""
+
+msgid "Choose any color."
+msgstr ""
+
+msgid "Choose between <code>clone</code> or <code>fetch</code> to get the recent application code"
+msgstr ""
+
+msgid "Choose file…"
+msgstr ""
+
+msgid "Choose the top-level group for your repository imports."
+msgstr ""
+
+msgid "Choose visibility level, enable/disable project features (issues, repository, wiki, snippets) and set permissions."
+msgstr ""
+
+msgid "Choose what content you want to see on a group’s overview page"
+msgstr ""
+
+msgid "Choose which groups you wish to synchronize to this secondary node"
+msgstr ""
+
+msgid "Choose which repositories you want to connect and run CI/CD pipelines."
+msgstr ""
+
+msgid "Choose which shards you wish to synchronize to this secondary node"
+msgstr ""
+
+msgid "Choose your framework"
+msgstr ""
+
+msgid "CiStatusLabel|canceled"
+msgstr ""
+
+msgid "CiStatusLabel|created"
+msgstr ""
+
+msgid "CiStatusLabel|delayed"
+msgstr ""
+
+msgid "CiStatusLabel|failed"
+msgstr ""
+
+msgid "CiStatusLabel|manual action"
+msgstr ""
+
+msgid "CiStatusLabel|passed"
+msgstr ""
+
+msgid "CiStatusLabel|passed with warnings"
+msgstr ""
+
+msgid "CiStatusLabel|pending"
+msgstr ""
+
+msgid "CiStatusLabel|preparing"
+msgstr ""
+
+msgid "CiStatusLabel|skipped"
+msgstr ""
+
+msgid "CiStatusLabel|waiting for delayed job"
+msgstr ""
+
+msgid "CiStatusLabel|waiting for manual action"
+msgstr ""
+
+msgid "CiStatusLabel|waiting for resource"
+msgstr ""
+
+msgid "CiStatusText|blocked"
+msgstr ""
+
+msgid "CiStatusText|canceled"
+msgstr ""
+
+msgid "CiStatusText|created"
+msgstr ""
+
+msgid "CiStatusText|delayed"
+msgstr ""
+
+msgid "CiStatusText|failed"
+msgstr ""
+
+msgid "CiStatusText|manual"
+msgstr ""
+
+msgid "CiStatusText|passed"
+msgstr ""
+
+msgid "CiStatusText|pending"
+msgstr ""
+
+msgid "CiStatusText|preparing"
+msgstr ""
+
+msgid "CiStatusText|skipped"
+msgstr ""
+
+msgid "CiStatusText|waiting"
+msgstr ""
+
+msgid "CiStatus|running"
+msgstr ""
+
+msgid "CiVariables|Cannot use Masked Variable with current value"
+msgstr ""
+
+msgid "CiVariables|Environments"
+msgstr ""
+
+msgid "CiVariables|Input variable key"
+msgstr ""
+
+msgid "CiVariables|Input variable value"
+msgstr ""
+
+msgid "CiVariables|Key"
+msgstr ""
+
+msgid "CiVariables|Masked"
+msgstr ""
+
+msgid "CiVariables|Protected"
+msgstr ""
+
+msgid "CiVariables|Remove variable row"
+msgstr ""
+
+msgid "CiVariables|Scope"
+msgstr ""
+
+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 ""
+
+msgid "CiVariables|Type"
+msgstr ""
+
+msgid "CiVariables|Value"
+msgstr ""
+
+msgid "CiVariables|Variables"
+msgstr ""
+
+msgid "CiVariable|* (All environments)"
+msgstr ""
+
+msgid "CiVariable|All environments"
+msgstr ""
+
+msgid "CiVariable|Create wildcard"
+msgstr ""
+
+msgid "CiVariable|Error occurred while saving variables"
+msgstr ""
+
+msgid "CiVariable|Masked"
+msgstr ""
+
+msgid "CiVariable|New environment"
+msgstr ""
+
+msgid "CiVariable|Protected"
+msgstr ""
+
+msgid "CiVariable|Search environments"
+msgstr ""
+
+msgid "CiVariable|Toggle masked"
+msgstr ""
+
+msgid "CiVariable|Toggle protected"
+msgstr ""
+
+msgid "CiVariable|Validation failed"
+msgstr ""
+
+msgid "Class"
+msgstr ""
+
+msgid "Classification Label (optional)"
+msgstr ""
+
+msgid "ClassificationLabelUnavailable|is unavailable: %{reason}"
+msgstr ""
+
+msgid "Clear"
+msgstr ""
+
+msgid "Clear chart filters"
+msgstr ""
+
+msgid "Clear due date"
+msgstr ""
+
+msgid "Clear input"
+msgstr ""
+
+msgid "Clear recent searches"
+msgstr ""
+
+msgid "Clear search"
+msgstr ""
+
+msgid "Clear search input"
+msgstr ""
+
+msgid "Clear start date"
+msgstr ""
+
+msgid "Clear templates search input"
+msgstr ""
+
+msgid "Clear weight"
+msgstr ""
+
+msgid "Cleared weight."
+msgstr ""
+
+msgid "Clears weight."
+msgstr ""
+
+msgid "Click any <strong>project name</strong> in the project list below to navigate to the project milestone."
+msgstr ""
+
+msgid "Click the <strong>Download</strong> button and wait for downloading to complete."
+msgstr ""
+
+msgid "Click the <strong>Promote</strong> button in the top right corner to promote it to a group milestone."
+msgstr ""
+
+msgid "Click the <strong>Select none</strong> button on the right, since we only need \"Google Code Project Hosting\"."
+msgstr ""
+
+msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
+msgstr ""
+
+msgid "Click to expand it."
+msgstr ""
+
+msgid "Click to expand text"
+msgstr ""
+
+msgid "Client authentication certificate"
+msgstr ""
+
+msgid "Client authentication key"
+msgstr ""
+
+msgid "Client authentication key password"
+msgstr ""
+
+msgid "Clients"
+msgstr ""
+
+msgid "Clone"
+msgstr ""
+
+msgid "Clone repository"
+msgstr ""
+
+msgid "Clone with %{http_label}"
+msgstr ""
+
+msgid "Clone with %{protocol}"
+msgstr ""
+
+msgid "Clone with KRB5"
+msgstr ""
+
+msgid "Clone with SSH"
+msgstr ""
+
+msgid "Close"
+msgstr ""
+
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
+msgid "Close %{tabname}"
+msgstr ""
+
+msgid "Close epic"
+msgstr ""
+
+msgid "Close milestone"
+msgstr ""
+
+msgid "Close sidebar"
+msgstr ""
+
+msgid "Close this %{quick_action_target}"
+msgstr ""
+
+msgid "Closed"
+msgstr ""
+
+msgid "Closed issues"
+msgstr ""
+
+msgid "Closed this %{quick_action_target}."
+msgstr ""
+
+msgid "Closed: %{closedIssuesCount}"
+msgstr ""
+
+msgid "Closes this %{quick_action_target}."
+msgstr ""
+
+msgid "Cluster"
+msgstr ""
+
+msgid "Cluster Health"
+msgstr ""
+
+msgid "Cluster cache cleared."
+msgstr ""
+
+msgid "Cluster does not exist"
+msgstr ""
+
+msgid "Cluster level"
+msgstr ""
+
+msgid "ClusterIntegration| %{custom_domain_start}More information%{custom_domain_end}."
+msgstr ""
+
+msgid "ClusterIntegration| This will permanently delete the following resources: <ul> <li>All installed applications and related resources</li> <li>The <code>gitlab-managed-apps</code> namespace</li> <li>Any project namespaces</li> <li><code>clusterroles</code></li> <li><code>clusterrolebindings</code></li> </ul>"
+msgstr ""
+
+msgid "ClusterIntegration| can be used instead of a custom domain."
+msgstr ""
+
+msgid "ClusterIntegration| is the default environment scope for this cluster. This means that all jobs, regardless of their environment, will use this cluster. %{environment_scope_start}More information%{environment_scope_end}"
+msgstr ""
+
+msgid "ClusterIntegration|%{appList} was successfully installed on your Kubernetes cluster"
+msgstr ""
+
+msgid "ClusterIntegration|%{external_ip}.nip.io"
+msgstr ""
+
+msgid "ClusterIntegration|%{title} uninstalled successfully."
+msgstr ""
+
+msgid "ClusterIntegration|%{title} updated successfully."
+msgstr ""
+
+msgid "ClusterIntegration|A cluster management project can be used to run deployment jobs with Kubernetes <code>cluster-admin</code> privileges."
+msgstr ""
+
+msgid "ClusterIntegration|A service token scoped to %{code}kube-system%{end_code} with %{code}cluster-admin%{end_code} privileges."
+msgstr ""
+
+msgid "ClusterIntegration|API URL"
+msgstr ""
+
+msgid "ClusterIntegration|API URL should be a valid http/https url."
+msgstr ""
+
+msgid "ClusterIntegration|Add Kubernetes cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Add a Kubernetes cluster integration"
+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 ""
+
+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 ""
+
+msgid "ClusterIntegration|Adding an integration to your group will share the cluster across all your projects."
+msgstr ""
+
+msgid "ClusterIntegration|Adding an integration will share the cluster across all projects."
+msgstr ""
+
+msgid "ClusterIntegration|Advanced options on this Kubernetes cluster’s integration"
+msgstr ""
+
+msgid "ClusterIntegration|All data not committed to GitLab will be deleted and cannot be restored."
+msgstr ""
+
+msgid "ClusterIntegration|All data will be deleted and cannot be restored."
+msgstr ""
+
+msgid "ClusterIntegration|Allow GitLab to manage namespace and service accounts for this cluster."
+msgstr ""
+
+msgid "ClusterIntegration|Allow GitLab to manage namespace and service accounts for this cluster. %{startLink}More information%{endLink}"
+msgstr ""
+
+msgid "ClusterIntegration|Alternatively"
+msgstr ""
+
+msgid "ClusterIntegration|Amazon EKS"
+msgstr ""
+
+msgid "ClusterIntegration|An error occurred when trying to contact the Google Cloud API. Please try again later."
+msgstr ""
+
+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 ""
+
+msgid "ClusterIntegration|An error occurred while trying to fetch zone machine types: %{error}"
+msgstr ""
+
+msgid "ClusterIntegration|Any running pipelines will be canceled."
+msgstr ""
+
+msgid "ClusterIntegration|Apply for credit"
+msgstr ""
+
+msgid "ClusterIntegration|Authenticate with AWS"
+msgstr ""
+
+msgid "ClusterIntegration|Authenticate with Amazon Web Services"
+msgstr ""
+
+msgid "ClusterIntegration|Base domain"
+msgstr ""
+
+msgid "ClusterIntegration|Blocking mode"
+msgstr ""
+
+msgid "ClusterIntegration|CA Certificate"
+msgstr ""
+
+msgid "ClusterIntegration|Cert-Manager"
+msgstr ""
+
+msgid "ClusterIntegration|Cert-Manager is a native Kubernetes certificate management controller that helps with issuing certificates. Installing Cert-Manager on your cluster will issue a certificate by %{letsEncrypt} and ensure that certificates are valid and up-to-date."
+msgstr ""
+
+msgid "ClusterIntegration|Certificate Authority bundle (PEM format)"
+msgstr ""
+
+msgid "ClusterIntegration|Choose the %{startLink}security group %{externalLinkIcon} %{endLink} to apply to the EKS-managed Elastic Network Interfaces that are created in your worker node subnets."
+msgstr ""
+
+msgid "ClusterIntegration|Choose the %{startLink}subnets %{externalLinkIcon} %{endLink} in your VPC where your worker nodes will run."
+msgstr ""
+
+msgid "ClusterIntegration|Choose the worker node %{startLink}instance type %{externalLinkIcon} %{endLink}."
+msgstr ""
+
+msgid "ClusterIntegration|Choose which applications to install on your Kubernetes cluster. Helm Tiller is required to install any of the following applications."
+msgstr ""
+
+msgid "ClusterIntegration|Choose which of your environments will use this cluster."
+msgstr ""
+
+msgid "ClusterIntegration|Clear cluster cache"
+msgstr ""
+
+msgid "ClusterIntegration|Clear the local cache of namespace and service accounts. 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 ""
+
+msgid "ClusterIntegration|Cloud Run"
+msgstr ""
+
+msgid "ClusterIntegration|Cluster being created"
+msgstr ""
+
+msgid "ClusterIntegration|Cluster management project (alpha)"
+msgstr ""
+
+msgid "ClusterIntegration|Cluster name is required."
+msgstr ""
+
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
+msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
+msgstr ""
+
+msgid "ClusterIntegration|Copy API URL"
+msgstr ""
+
+msgid "ClusterIntegration|Copy CA Certificate"
+msgstr ""
+
+msgid "ClusterIntegration|Copy Ingress Endpoint"
+msgstr ""
+
+msgid "ClusterIntegration|Copy Jupyter Hostname"
+msgstr ""
+
+msgid "ClusterIntegration|Copy Knative Endpoint"
+msgstr ""
+
+msgid "ClusterIntegration|Copy Kubernetes cluster name"
+msgstr ""
+
+msgid "ClusterIntegration|Could not load IAM roles"
+msgstr ""
+
+msgid "ClusterIntegration|Could not load Key Pairs"
+msgstr ""
+
+msgid "ClusterIntegration|Could not load VPCs for the selected region"
+msgstr ""
+
+msgid "ClusterIntegration|Could not load instance types"
+msgstr ""
+
+msgid "ClusterIntegration|Could not load networks"
+msgstr ""
+
+msgid "ClusterIntegration|Could not load regions from your AWS account"
+msgstr ""
+
+msgid "ClusterIntegration|Could not load security groups for the selected VPC"
+msgstr ""
+
+msgid "ClusterIntegration|Could not load subnets for the selected VPC"
+msgstr ""
+
+msgid "ClusterIntegration|Could not load subnetworks"
+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 ""
+
+msgid "ClusterIntegration|Create new cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Create new cluster on EKS"
+msgstr ""
+
+msgid "ClusterIntegration|Create new cluster on GKE"
+msgstr ""
+
+msgid "ClusterIntegration|Creating Kubernetes cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Crossplane"
+msgstr ""
+
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgstr ""
+
+msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
+msgstr ""
+
+msgid "ClusterIntegration|Did you know?"
+msgstr ""
+
+msgid "ClusterIntegration|Elastic Kubernetes Service"
+msgstr ""
+
+msgid "ClusterIntegration|Elastic Stack"
+msgstr ""
+
+msgid "ClusterIntegration|Enable Cloud Run for Anthos"
+msgstr ""
+
+msgid "ClusterIntegration|Enable or disable GitLab's connection to your Kubernetes cluster."
+msgstr ""
+
+msgid "ClusterIntegration|Enable this setting if using role-based access control (RBAC)."
+msgstr ""
+
+msgid "ClusterIntegration|Enabled stack"
+msgstr ""
+
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
+msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Enter the details for your Kubernetes cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Environment scope"
+msgstr ""
+
+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 ""
+
+msgid "ClusterIntegration|Failed to configure EKS provider: %{message}"
+msgstr ""
+
+msgid "ClusterIntegration|Failed to configure Google Kubernetes Engine Cluster: %{message}"
+msgstr ""
+
+msgid "ClusterIntegration|Failed to fetch CloudFormation stack: %{message}"
+msgstr ""
+
+msgid "ClusterIntegration|Failed to request to Google Cloud Platform: %{message}"
+msgstr ""
+
+msgid "ClusterIntegration|Failed to run Kubeclient: %{message}"
+msgstr ""
+
+msgid "ClusterIntegration|Fetching machine types"
+msgstr ""
+
+msgid "ClusterIntegration|Fetching projects"
+msgstr ""
+
+msgid "ClusterIntegration|Fetching zones"
+msgstr ""
+
+msgid "ClusterIntegration|Fluentd"
+msgstr ""
+
+msgid "ClusterIntegration|Fluentd is an open source data collector, which lets you unify the data collection and consumption for a better use and understanding of data. It requires at least one of the following logs to be successfully installed."
+msgstr ""
+
+msgid "ClusterIntegration|GitLab Integration"
+msgstr ""
+
+msgid "ClusterIntegration|GitLab Runner"
+msgstr ""
+
+msgid "ClusterIntegration|GitLab Runner connects to the repository and executes CI/CD jobs, pushing results back and deploying applications to production."
+msgstr ""
+
+msgid "ClusterIntegration|GitLab-managed cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Gitlab Integration"
+msgstr ""
+
+msgid "ClusterIntegration|Global default"
+msgstr ""
+
+msgid "ClusterIntegration|Google Cloud Platform project"
+msgstr ""
+
+msgid "ClusterIntegration|Google GKE"
+msgstr ""
+
+msgid "ClusterIntegration|Google Kubernetes Engine"
+msgstr ""
+
+msgid "ClusterIntegration|Google Kubernetes Engine project"
+msgstr ""
+
+msgid "ClusterIntegration|Group cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Helm Tiller"
+msgstr ""
+
+msgid "ClusterIntegration|Helm release failed to install"
+msgstr ""
+
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgstr ""
+
+msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
+msgstr ""
+
+msgid "ClusterIntegration|If you do not wish to delete all associated GitLab resources, you can simply remove the integration."
+msgstr ""
+
+msgid "ClusterIntegration|In order to view the health of your cluster, you must first install Prometheus in the Applications tab."
+msgstr ""
+
+msgid "ClusterIntegration|Ingress"
+msgstr ""
+
+msgid "ClusterIntegration|Ingress Endpoint"
+msgstr ""
+
+msgid "ClusterIntegration|Ingress gives you a way to route requests to services based on the request host or path, centralizing a number of services into a single entrypoint."
+msgstr ""
+
+msgid "ClusterIntegration|Installing Ingress may incur additional costs. Learn more about %{pricingLink}."
+msgstr ""
+
+msgid "ClusterIntegration|Instance cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Instance type"
+msgstr ""
+
+msgid "ClusterIntegration|Integrate Kubernetes cluster automation"
+msgstr ""
+
+msgid "ClusterIntegration|Issuer Email"
+msgstr ""
+
+msgid "ClusterIntegration|Issuers represent a certificate authority. You must provide an email address for your Issuer. "
+msgstr ""
+
+msgid "ClusterIntegration|Jupyter Hostname"
+msgstr ""
+
+msgid "ClusterIntegration|JupyterHub"
+msgstr ""
+
+msgid "ClusterIntegration|JupyterHub, a multi-user Hub, spawns, manages, and proxies multiple instances of the single-user Jupyter notebook server. JupyterHub can be used to serve notebooks to a class of students, a corporate data science group, or a scientific research group."
+msgstr ""
+
+msgid "ClusterIntegration|Key pair name"
+msgstr ""
+
+msgid "ClusterIntegration|Knative"
+msgstr ""
+
+msgid "ClusterIntegration|Knative Domain Name:"
+msgstr ""
+
+msgid "ClusterIntegration|Knative Endpoint:"
+msgstr ""
+
+msgid "ClusterIntegration|Knative domain name was updated successfully."
+msgstr ""
+
+msgid "ClusterIntegration|Knative extends Kubernetes to provide a set of middleware components that are essential to build modern, source-centric, and container-based applications that can run anywhere: on premises, in the cloud, or even in a third-party data center."
+msgstr ""
+
+msgid "ClusterIntegration|Kubernetes cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Kubernetes cluster is being created..."
+msgstr ""
+
+msgid "ClusterIntegration|Kubernetes cluster name"
+msgstr ""
+
+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 ""
+
+msgid "ClusterIntegration|Kubernetes clusters can be used to deploy applications and to provide Review Apps for this project"
+msgstr ""
+
+msgid "ClusterIntegration|Kubernetes version"
+msgstr ""
+
+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 ""
+
+msgid "ClusterIntegration|Learn more about %{help_link_start}zones%{help_link_end}."
+msgstr ""
+
+msgid "ClusterIntegration|Learn more about %{startLink}Regions %{externalLinkIcon}%{endLink}."
+msgstr ""
+
+msgid "ClusterIntegration|Learn more about Kubernetes"
+msgstr ""
+
+msgid "ClusterIntegration|Learn more about group Kubernetes clusters"
+msgstr ""
+
+msgid "ClusterIntegration|Learn more about instance Kubernetes clusters"
+msgstr ""
+
+msgid "ClusterIntegration|Let's Encrypt"
+msgstr ""
+
+msgid "ClusterIntegration|Loading IAM Roles"
+msgstr ""
+
+msgid "ClusterIntegration|Loading Key Pairs"
+msgstr ""
+
+msgid "ClusterIntegration|Loading Regions"
+msgstr ""
+
+msgid "ClusterIntegration|Loading VPCs"
+msgstr ""
+
+msgid "ClusterIntegration|Loading instance types"
+msgstr ""
+
+msgid "ClusterIntegration|Loading networks"
+msgstr ""
+
+msgid "ClusterIntegration|Loading security groups"
+msgstr ""
+
+msgid "ClusterIntegration|Loading subnets"
+msgstr ""
+
+msgid "ClusterIntegration|Loading subnetworks"
+msgstr ""
+
+msgid "ClusterIntegration|Logging mode"
+msgstr ""
+
+msgid "ClusterIntegration|Machine type"
+msgstr ""
+
+msgid "ClusterIntegration|Make sure your account %{link_to_requirements} to create Kubernetes clusters"
+msgstr ""
+
+msgid "ClusterIntegration|Manage your Kubernetes cluster by visiting %{provider_link}"
+msgstr ""
+
+msgid "ClusterIntegration|No IAM Roles found"
+msgstr ""
+
+msgid "ClusterIntegration|No Key Pairs found"
+msgstr ""
+
+msgid "ClusterIntegration|No VPCs found"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No instance type found"
+msgstr ""
+
+msgid "ClusterIntegration|No machine types matched your search"
+msgstr ""
+
+msgid "ClusterIntegration|No networks found"
+msgstr ""
+
+msgid "ClusterIntegration|No projects found"
+msgstr ""
+
+msgid "ClusterIntegration|No projects matched your search"
+msgstr ""
+
+msgid "ClusterIntegration|No region found"
+msgstr ""
+
+msgid "ClusterIntegration|No security group found"
+msgstr ""
+
+msgid "ClusterIntegration|No subnet found"
+msgstr ""
+
+msgid "ClusterIntegration|No subnetworks found"
+msgstr ""
+
+msgid "ClusterIntegration|No zones matched your search"
+msgstr ""
+
+msgid "ClusterIntegration|Number of nodes"
+msgstr ""
+
+msgid "ClusterIntegration|Number of nodes must be a numerical value."
+msgstr ""
+
+msgid "ClusterIntegration|Please enter access information for your Kubernetes cluster. If you need help, you can read our %{link_to_help_page} on Kubernetes"
+msgstr ""
+
+msgid "ClusterIntegration|Please make sure that your Google account meets the following requirements:"
+msgstr ""
+
+msgid "ClusterIntegration|Point a wildcard DNS to this generated endpoint in order to access your application after it has been deployed."
+msgstr ""
+
+msgid "ClusterIntegration|Project cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Project namespace (optional, unique)"
+msgstr ""
+
+msgid "ClusterIntegration|Project namespace prefix (optional, unique)"
+msgstr ""
+
+msgid "ClusterIntegration|Prometheus"
+msgstr ""
+
+msgid "ClusterIntegration|Prometheus is an open-source monitoring system with %{gitlabIntegrationLink} to monitor deployed applications."
+msgstr ""
+
+msgid "ClusterIntegration|Provider details"
+msgstr ""
+
+msgid "ClusterIntegration|Provision Role ARN"
+msgstr ""
+
+msgid "ClusterIntegration|RBAC-enabled cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Read our %{link_start}help page%{link_end} on Kubernetes cluster integration."
+msgstr ""
+
+msgid "ClusterIntegration|Real-time web application monitoring, logging and access control. %{linkStart}More information%{linkEnd}"
+msgstr ""
+
+msgid "ClusterIntegration|Region"
+msgstr ""
+
+msgid "ClusterIntegration|Remove Kubernetes cluster integration"
+msgstr ""
+
+msgid "ClusterIntegration|Remove integration"
+msgstr ""
+
+msgid "ClusterIntegration|Remove integration and resources"
+msgstr ""
+
+msgid "ClusterIntegration|Remove integration and resources?"
+msgstr ""
+
+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 ""
+
+msgid "ClusterIntegration|Removes cluster from project but keeps associated resources"
+msgstr ""
+
+msgid "ClusterIntegration|Replace this with your own hostname if you want. If you do so, point hostname to Ingress IP Address from above."
+msgstr ""
+
+msgid "ClusterIntegration|Request to begin installing failed"
+msgstr ""
+
+msgid "ClusterIntegration|Request to begin uninstalling failed"
+msgstr ""
+
+msgid "ClusterIntegration|SIEM Hostname"
+msgstr ""
+
+msgid "ClusterIntegration|SIEM Port"
+msgstr ""
+
+msgid "ClusterIntegration|SIEM Protocol"
+msgstr ""
+
+msgid "ClusterIntegration|Save changes"
+msgstr ""
+
+msgid "ClusterIntegration|Search IAM Roles"
+msgstr ""
+
+msgid "ClusterIntegration|Search Key Pairs"
+msgstr ""
+
+msgid "ClusterIntegration|Search VPCs"
+msgstr ""
+
+msgid "ClusterIntegration|Search domains"
+msgstr ""
+
+msgid "ClusterIntegration|Search instance types"
+msgstr ""
+
+msgid "ClusterIntegration|Search machine types"
+msgstr ""
+
+msgid "ClusterIntegration|Search networks"
+msgstr ""
+
+msgid "ClusterIntegration|Search projects"
+msgstr ""
+
+msgid "ClusterIntegration|Search regions"
+msgstr ""
+
+msgid "ClusterIntegration|Search security groups"
+msgstr ""
+
+msgid "ClusterIntegration|Search subnets"
+msgstr ""
+
+msgid "ClusterIntegration|Search subnetworks"
+msgstr ""
+
+msgid "ClusterIntegration|Search zones"
+msgstr ""
+
+msgid "ClusterIntegration|Security group"
+msgstr ""
+
+msgid "ClusterIntegration|See and edit the details for your Kubernetes cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Select a VPC to choose a security group"
+msgstr ""
+
+msgid "ClusterIntegration|Select a VPC to choose a subnet"
+msgstr ""
+
+msgid "ClusterIntegration|Select a VPC to use for your EKS Cluster resources. To use a new VPC, first create one on %{startLink}Amazon Web Services %{externalLinkIcon} %{endLink}."
+msgstr ""
+
+msgid "ClusterIntegration|Select a network to choose a subnetwork"
+msgstr ""
+
+msgid "ClusterIntegration|Select a region to choose a Key Pair"
+msgstr ""
+
+msgid "ClusterIntegration|Select a region to choose a VPC"
+msgstr ""
+
+msgid "ClusterIntegration|Select a stack to install Crossplane."
+msgstr ""
+
+msgid "ClusterIntegration|Select a zone to choose a network"
+msgstr ""
+
+msgid "ClusterIntegration|Select existing domain or use new"
+msgstr ""
+
+msgid "ClusterIntegration|Select machine type"
+msgstr ""
+
+msgid "ClusterIntegration|Select project"
+msgstr ""
+
+msgid "ClusterIntegration|Select project and zone to choose machine type"
+msgstr ""
+
+msgid "ClusterIntegration|Select project to choose zone"
+msgstr ""
+
+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 %{startLink}Amazon Web Services %{externalLinkIcon} %{endLink}."
+msgstr ""
+
+msgid "ClusterIntegration|Select zone"
+msgstr ""
+
+msgid "ClusterIntegration|Select zone to choose machine type"
+msgstr ""
+
+msgid "ClusterIntegration|Send Cilium Logs"
+msgstr ""
+
+msgid "ClusterIntegration|Send ModSecurity Logs"
+msgstr ""
+
+msgid "ClusterIntegration|Service Token"
+msgstr ""
+
+msgid "ClusterIntegration|Service role"
+msgstr ""
+
+msgid "ClusterIntegration|Service token is required."
+msgstr ""
+
+msgid "ClusterIntegration|Set a prefix for your namespaces. If not set, defaults to your project path. If modified, existing environments will use their current namespaces until the cluster cache is cleared."
+msgstr ""
+
+msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
+msgstr ""
+
+msgid "ClusterIntegration|Something went wrong on our end."
+msgstr ""
+
+msgid "ClusterIntegration|Something went wrong while creating your Kubernetes cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Something went wrong while installing %{title}"
+msgstr ""
+
+msgid "ClusterIntegration|Something went wrong while trying to save your settings. Please try again."
+msgstr ""
+
+msgid "ClusterIntegration|Something went wrong while uninstalling %{title}"
+msgstr ""
+
+msgid "ClusterIntegration|Something went wrong while updating Knative domain name."
+msgstr ""
+
+msgid "ClusterIntegration|Specifying a domain will allow you to use Auto Review Apps and Auto Deploy stages for %{auto_devops_start}Auto DevOps%{auto_devops_end}. The domain should have a wildcard DNS configured matching the domain."
+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 ""
+
+msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
+msgstr ""
+
+msgid "ClusterIntegration|The URL used to access the Kubernetes API."
+msgstr ""
+
+msgid "ClusterIntegration|The associated IP and all deployed services will be deleted and cannot be restored. Uninstalling Knative will also remove Istio from your cluster. This will not effect any other applications."
+msgstr ""
+
+msgid "ClusterIntegration|The associated Tiller pod, the %{gitlabManagedAppsNamespace} namespace, and all of its resources will be deleted and cannot be restored."
+msgstr ""
+
+msgid "ClusterIntegration|The associated load balancer and IP will be deleted and cannot be restored."
+msgstr ""
+
+msgid "ClusterIntegration|The associated private key will be deleted and cannot be restored."
+msgstr ""
+
+msgid "ClusterIntegration|The elastic stack collects logs from all pods in your cluster"
+msgstr ""
+
+msgid "ClusterIntegration|The endpoint is in the process of being assigned. Please check your Kubernetes cluster or Quotas on Google Kubernetes Engine if it takes a long time."
+msgstr ""
+
+msgid "ClusterIntegration|The namespace associated with your project. This will be used for deploy boards, logs, and Web terminals."
+msgstr ""
+
+msgid "ClusterIntegration|There was a problem authenticating with your cluster. Please ensure your CA Certificate and Token are valid."
+msgstr ""
+
+msgid "ClusterIntegration|This account must have permissions to create a Kubernetes cluster in the %{link_to_container_project} specified below"
+msgstr ""
+
+msgid "ClusterIntegration|This option will allow you to install applications on RBAC clusters."
+msgstr ""
+
+msgid "ClusterIntegration|To access your application after deployment, point a wildcard DNS to the Knative Endpoint."
+msgstr ""
+
+msgid "ClusterIntegration|To remove your integration and resources, type %{clusterName} to confirm:"
+msgstr ""
+
+msgid "ClusterIntegration|To remove your integration, type %{clusterName} to confirm:"
+msgstr ""
+
+msgid "ClusterIntegration|Toggle Kubernetes cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Uninstall %{appTitle}"
+msgstr ""
+
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
+msgid "ClusterIntegration|Update failed. Please check the logs and try again."
+msgstr ""
+
+msgid "ClusterIntegration|Use %{query}"
+msgstr ""
+
+msgid "ClusterIntegration|Uses the Cloud Run, Istio, and HTTP Load Balancing addons for this cluster."
+msgstr ""
+
+msgid "ClusterIntegration|VPC"
+msgstr ""
+
+msgid "ClusterIntegration|Validating project billing status"
+msgstr ""
+
+msgid "ClusterIntegration|We could not verify that one of your projects on GCP has billing enabled. Please try again."
+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 ""
+
+msgid "ClusterIntegration|You are about to remove your cluster integration and all GitLab-created resources associated with this cluster."
+msgstr ""
+
+msgid "ClusterIntegration|You are about to remove your cluster integration."
+msgstr ""
+
+msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
+msgstr ""
+
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
+msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
+msgstr ""
+
+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 ""
+
+msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
+msgstr ""
+
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
+msgid "ClusterIntegration|You should select at least two subnets"
+msgstr ""
+
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
+msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
+msgstr ""
+
+msgid "ClusterIntegration|Your cluster API is unreachable. Please ensure your API URL is correct."
+msgstr ""
+
+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 %{startLink}Amazon Web Services %{externalLinkIcon} %{endLink}."
+msgstr ""
+
+msgid "ClusterIntegration|Zone"
+msgstr ""
+
+msgid "ClusterIntegration|access to Google Kubernetes Engine"
+msgstr ""
+
+msgid "ClusterIntegration|documentation"
+msgstr ""
+
+msgid "ClusterIntegration|installed via %{installed_via}"
+msgstr ""
+
+msgid "ClusterIntegration|meets the requirements"
+msgstr ""
+
+msgid "ClusterIntegration|pricing"
+msgstr ""
+
+msgid "ClusterIntegration|sign up"
+msgstr ""
+
+msgid "ClusterIntergation|Select a VPC"
+msgstr ""
+
+msgid "ClusterIntergation|Select a network"
+msgstr ""
+
+msgid "ClusterIntergation|Select a region"
+msgstr ""
+
+msgid "ClusterIntergation|Select a security group"
+msgstr ""
+
+msgid "ClusterIntergation|Select a subnet"
+msgstr ""
+
+msgid "ClusterIntergation|Select a subnetwork"
+msgstr ""
+
+msgid "ClusterIntergation|Select an instance type"
+msgstr ""
+
+msgid "ClusterIntergation|Select key pair"
+msgstr ""
+
+msgid "ClusterIntergation|Select service role"
+msgstr ""
+
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
+msgid "Code"
+msgstr ""
+
+msgid "Code Owners"
+msgstr ""
+
+msgid "Code Owners to the merge request changes."
+msgstr ""
+
+msgid "Code Quality"
+msgstr ""
+
+msgid "Code Review"
+msgstr ""
+
+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 ""
+
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
+msgid "Code owner approval is required"
+msgstr ""
+
+msgid "Code owners"
+msgstr ""
+
+msgid "CodeOwner|Pattern"
+msgstr ""
+
+msgid "Cohorts"
+msgstr ""
+
+msgid "Cohorts|Inactive users"
+msgstr ""
+
+msgid "Cohorts|Month %{month_index}"
+msgstr ""
+
+msgid "Cohorts|New users"
+msgstr ""
+
+msgid "Cohorts|Registration month"
+msgstr ""
+
+msgid "Cohorts|Returning users"
+msgstr ""
+
+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 ""
+
+msgid "Collapse approvers"
+msgstr ""
+
+msgid "Collapse child epics"
+msgstr ""
+
+msgid "Collapse replies"
+msgstr ""
+
+msgid "Collapse sidebar"
+msgstr ""
+
+msgid "Collector hostname"
+msgstr ""
+
+msgid "ComboSearch is not defined"
+msgstr ""
+
+msgid "Coming soon"
+msgstr ""
+
+msgid "Command"
+msgstr ""
+
+msgid "Command line instructions"
+msgstr ""
+
+msgid "Commands applied"
+msgstr ""
+
+msgid "Commands did not apply"
+msgstr ""
+
+msgid "Comment"
+msgstr ""
+
+msgid "Comment & close %{noteable_name}"
+msgstr ""
+
+msgid "Comment & reopen %{noteable_name}"
+msgstr ""
+
+msgid "Comment & resolve thread"
+msgstr ""
+
+msgid "Comment & unresolve thread"
+msgstr ""
+
+msgid "Comment '%{label}' position"
+msgstr ""
+
+msgid "Comment form position"
+msgstr ""
+
+msgid "Comment is being updated"
+msgstr ""
+
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
+msgid "Comment/Reply (quoting selected text)"
+msgstr ""
+
+msgid "Comments"
+msgstr ""
+
+msgid "Commit"
+msgid_plural "Commits"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Commit %{commit_id}"
+msgstr ""
+
+msgid "Commit (when editing commit message)"
+msgstr ""
+
+msgid "Commit Message"
+msgstr ""
+
+msgid "Commit deleted"
+msgstr ""
+
+msgid "Commit message"
+msgstr ""
+
+msgid "Commit message (optional)"
+msgstr ""
+
+msgid "Commit statistics for %{ref} %{start_time} - %{end_time}"
+msgstr ""
+
+msgid "Commit to %{branchName} branch"
+msgstr ""
+
+msgid "CommitBoxTitle|Commit"
+msgstr ""
+
+msgid "CommitMessage|Add %{file_name}"
+msgstr ""
+
+msgid "CommitWidget|authored"
+msgstr ""
+
+msgid "Commits"
+msgstr ""
+
+msgid "Commits feed"
+msgstr ""
+
+msgid "Commits per day hour (UTC)"
+msgstr ""
+
+msgid "Commits per day of month"
+msgstr ""
+
+msgid "Commits per weekday"
+msgstr ""
+
+msgid "Commits to"
+msgstr ""
+
+msgid "Commits|An error occurred while fetching merge requests data."
+msgstr ""
+
+msgid "Commits|History"
+msgstr ""
+
+msgid "Commits|No related merge requests found"
+msgstr ""
+
+msgid "Committed by"
+msgstr ""
+
+msgid "Commit…"
+msgstr ""
+
+msgid "Company"
+msgstr ""
+
+msgid "Company name"
+msgstr ""
+
+msgid "Compare"
+msgstr ""
+
+msgid "Compare Git revisions"
+msgstr ""
+
+msgid "Compare Revisions"
+msgstr ""
+
+msgid "Compare changes"
+msgstr ""
+
+msgid "Compare changes with the last commit"
+msgstr ""
+
+msgid "Compare changes with the merge request target branch"
+msgstr ""
+
+msgid "Compare with previous version"
+msgstr ""
+
+msgid "CompareBranches|%{source_branch} and %{target_branch} are the same."
+msgstr ""
+
+msgid "CompareBranches|Compare"
+msgstr ""
+
+msgid "CompareBranches|Source"
+msgstr ""
+
+msgid "CompareBranches|Target"
+msgstr ""
+
+msgid "CompareBranches|There isn't anything to compare."
+msgstr ""
+
+msgid "Complete"
+msgstr ""
+
+msgid "Compliance"
+msgstr ""
+
+msgid "Compliance Dashboard"
+msgstr ""
+
+msgid "Compliance framework (optional)"
+msgstr ""
+
+msgid "ComplianceFramework|GDPR"
+msgstr ""
+
+msgid "ComplianceFramework|GDPR - General Data Protection Regulation"
+msgstr ""
+
+msgid "ComplianceFramework|HIPAA"
+msgstr ""
+
+msgid "ComplianceFramework|HIPAA - Health Insurance Portability and Accountability Act"
+msgstr ""
+
+msgid "ComplianceFramework|PCI-DSS"
+msgstr ""
+
+msgid "ComplianceFramework|PCI-DSS - Payment Card Industry-Data Security Standard"
+msgstr ""
+
+msgid "ComplianceFramework|SOC 2"
+msgstr ""
+
+msgid "ComplianceFramework|SOC 2 - Service Organization Control 2"
+msgstr ""
+
+msgid "ComplianceFramework|SOX"
+msgstr ""
+
+msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
+msgstr ""
+
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
+msgstr ""
+
+msgid "Confidential"
+msgstr ""
+
+msgid "Confidentiality"
+msgstr ""
+
+msgid "Configuration"
+msgstr ""
+
+msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
+msgstr ""
+
+msgid "Configure Gitaly timeouts."
+msgstr ""
+
+msgid "Configure Let's Encrypt"
+msgstr ""
+
+msgid "Configure Prometheus"
+msgstr ""
+
+msgid "Configure Tracing"
+msgstr ""
+
+msgid "Configure a <code>.gitlab-webide.yml</code> file in the <code>.gitlab</code> directory to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
+msgstr ""
+
+msgid "Configure automatic git checks and housekeeping on repositories."
+msgstr ""
+
+msgid "Configure existing installation"
+msgstr ""
+
+msgid "Configure limit for issues created per minute by web and API requests."
+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 ""
+
+msgid "Configure repository mirroring."
+msgstr ""
+
+msgid "Configure storage path settings."
+msgstr ""
+
+msgid "Configure the %{link} integration."
+msgstr ""
+
+msgid "Configure the way a user creates a new account."
+msgstr ""
+
+msgid "Confirm"
+msgstr ""
+
+msgid "Confirmation email sent to %{email}"
+msgstr ""
+
+msgid "Confirmation required"
+msgstr ""
+
+msgid "Congratulations! You have enabled Two-factor Authentication!"
+msgstr ""
+
+msgid "Connect"
+msgstr ""
+
+msgid "Connect all repositories"
+msgstr ""
+
+msgid "Connect repositories from GitHub"
+msgstr ""
+
+msgid "Connect your external repositories, and CI/CD pipelines will run for new commits. A GitLab project will be created with only CI/CD features enabled."
+msgstr ""
+
+msgid "Connected"
+msgstr ""
+
+msgid "Connecting"
+msgstr ""
+
+msgid "Connecting to terminal sync service"
+msgstr ""
+
+msgid "Connecting..."
+msgstr ""
+
+msgid "Connection failed"
+msgstr ""
+
+msgid "Connection failure"
+msgstr ""
+
+msgid "Connection timed out"
+msgstr ""
+
+msgid "Contact sales to upgrade"
+msgstr ""
+
+msgid "Contact support"
+msgstr ""
+
+msgid "Container Registry"
+msgstr ""
+
+msgid "Container Registry tag expiration policy"
+msgstr ""
+
+msgid "Container Scanning"
+msgstr ""
+
+msgid "Container does not exist"
+msgstr ""
+
+msgid "Container registry images"
+msgstr ""
+
+msgid "Container registry is not enabled on this GitLab instance. Ask an administrator to enable it in order for Auto DevOps to work."
+msgstr ""
+
+msgid "Container repositories sync capacity"
+msgstr ""
+
+msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
+msgstr ""
+
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{imageName} tags"
+msgstr ""
+
+msgid "ContainerRegistry|%{title} was successfully scheduled for deletion"
+msgstr ""
+
+msgid "ContainerRegistry|Automatically remove extra images that aren't designed to be kept."
+msgstr ""
+
+msgid "ContainerRegistry|Build an image"
+msgstr ""
+
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
+msgid "ContainerRegistry|Compressed Size"
+msgstr ""
+
+msgid "ContainerRegistry|Container Registry"
+msgstr ""
+
+msgid "ContainerRegistry|Container Registry tag expiration and retention policy is disabled"
+msgstr ""
+
+msgid "ContainerRegistry|Copy build command"
+msgstr ""
+
+msgid "ContainerRegistry|Copy login command"
+msgstr ""
+
+msgid "ContainerRegistry|Copy push command"
+msgstr ""
+
+msgid "ContainerRegistry|Docker connection error"
+msgstr ""
+
+msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration interval:"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy successfully saved."
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy:"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration schedule:"
+msgstr ""
+
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
+msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
+msgstr ""
+
+msgid "ContainerRegistry|Image ID"
+msgstr ""
+
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
+msgid "ContainerRegistry|Keep and protect the images that matter most."
+msgstr ""
+
+msgid "ContainerRegistry|Last Updated"
+msgstr ""
+
+msgid "ContainerRegistry|Login"
+msgstr ""
+
+msgid "ContainerRegistry|Missing or insufficient permission, delete button disabled"
+msgstr ""
+
+msgid "ContainerRegistry|Number of tags to retain:"
+msgstr ""
+
+msgid "ContainerRegistry|Please contact your administrator."
+msgstr ""
+
+msgid "ContainerRegistry|Push an image"
+msgstr ""
+
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
+msgstr ""
+
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Remember to run %{docLinkStart}garbage collection%{docLinkEnd} to remove the stale data from storage."
+msgstr ""
+
+msgid "ContainerRegistry|Remove repository"
+msgstr ""
+
+msgid "ContainerRegistry|Remove selected tags"
+msgstr ""
+
+msgid "ContainerRegistry|Remove tag"
+msgid_plural "ContainerRegistry|Remove tags"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
+msgstr ""
+
+msgid "ContainerRegistry|Something went wrong while fetching the repository list."
+msgstr ""
+
+msgid "ContainerRegistry|Something went wrong while fetching the tags list."
+msgstr ""
+
+msgid "ContainerRegistry|Something went wrong while marking the tag for deletion."
+msgstr ""
+
+msgid "ContainerRegistry|Something went wrong while marking the tags for deletion."
+msgstr ""
+
+msgid "ContainerRegistry|Something went wrong while scheduling %{title} for deletion. Please try again."
+msgstr ""
+
+msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
+msgstr ""
+
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "ContainerRegistry|Tag"
+msgstr ""
+
+msgid "ContainerRegistry|Tag expiration policy"
+msgstr ""
+
+msgid "ContainerRegistry|Tag expiration policy is designed to:"
+msgstr ""
+
+msgid "ContainerRegistry|Tag successfully marked for deletion."
+msgstr ""
+
+msgid "ContainerRegistry|Tags successfully marked for deletion."
+msgstr ""
+
+msgid "ContainerRegistry|Tags with names matching this regex pattern will %{italicStart}be preserved:%{italicEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Tags with names matching this regex pattern will %{italicStart}expire:%{italicEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|The Container Registry tag expiration and retention policies for this project have not been enabled."
+msgstr ""
+
+msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
+msgstr ""
+
+msgid "ContainerRegistry|The value of this input should be less than 255 characters"
+msgstr ""
+
+msgid "ContainerRegistry|There are no container images available in this group"
+msgstr ""
+
+msgid "ContainerRegistry|There are no container images stored for this project"
+msgstr ""
+
+msgid "ContainerRegistry|There was an error during the deletion of this image repository, please try again."
+msgstr ""
+
+msgid "ContainerRegistry|This image has no active tags"
+msgstr ""
+
+msgid "ContainerRegistry|This image repository is scheduled for deletion"
+msgstr ""
+
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgstr ""
+
+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 ""
+
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+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 ""
+
+msgid "ContainerRegistry|You are about to remove repository %{title}. Once you confirm, this repository will be permanently deleted."
+msgstr ""
+
+msgid "ContainerRegistry|You can add an image to this registry with the following commands:"
+msgstr ""
+
+msgid "Contains %{count} blobs of images (%{size})"
+msgstr ""
+
+msgid "Contents of .gitlab-ci.yml"
+msgstr ""
+
+msgid "Continue"
+msgstr ""
+
+msgid "Continue to the next step"
+msgstr ""
+
+msgid "Continuous Integration and Deployment"
+msgstr ""
+
+msgid "Contribute to GitLab"
+msgstr ""
+
+msgid "Contribution"
+msgstr ""
+
+msgid "Contribution Analytics"
+msgstr ""
+
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgstr ""
+
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
+msgstr ""
+
+msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
+msgstr ""
+
+msgid "ContributionAnalytics|Contribution analytics for issues, merge requests and push events since %{start_date}"
+msgstr ""
+
+msgid "ContributionAnalytics|Issues"
+msgstr ""
+
+msgid "ContributionAnalytics|Last 3 months"
+msgstr ""
+
+msgid "ContributionAnalytics|Last month"
+msgstr ""
+
+msgid "ContributionAnalytics|Last week"
+msgstr ""
+
+msgid "ContributionAnalytics|Merge Requests"
+msgstr ""
+
+msgid "ContributionAnalytics|No issues for the selected time period."
+msgstr ""
+
+msgid "ContributionAnalytics|No merge requests for the selected time period."
+msgstr ""
+
+msgid "ContributionAnalytics|No pushes for the selected time period."
+msgstr ""
+
+msgid "Contributions for <strong>%{calendar_date}</strong>"
+msgstr ""
+
+msgid "Contributions per group member"
+msgstr ""
+
+msgid "Contributors"
+msgstr ""
+
+msgid "Control emails linked to your account"
+msgstr ""
+
+msgid "Control the display of third party offers."
+msgstr ""
+
+msgid "Control the maximum concurrency of LFS/attachment backfill for this secondary node"
+msgstr ""
+
+msgid "Control the maximum concurrency of container repository operations for this Geo node"
+msgstr ""
+
+msgid "Control the maximum concurrency of repository backfill for this secondary node"
+msgstr ""
+
+msgid "Control the maximum concurrency of verification operations for this Geo node"
+msgstr ""
+
+msgid "Control the minimum interval in days that a repository should be reverified for this primary node"
+msgstr ""
+
+msgid "Cookie domain"
+msgstr ""
+
+msgid "Copied"
+msgstr ""
+
+msgid "Copied labels and milestone from %{source_issuable_reference}."
+msgstr ""
+
+msgid "Copy"
+msgstr ""
+
+msgid "Copy %{field}"
+msgstr ""
+
+msgid "Copy %{http_label} clone URL"
+msgstr ""
+
+msgid "Copy %{protocol} clone URL"
+msgstr ""
+
+msgid "Copy %{proxy_url}"
+msgstr ""
+
+msgid "Copy %{type}"
+msgstr ""
+
+msgid "Copy Account ID to clipboard"
+msgstr ""
+
+msgid "Copy External ID to clipboard"
+msgstr ""
+
+msgid "Copy ID"
+msgstr ""
+
+msgid "Copy KRB5 clone URL"
+msgstr ""
+
+msgid "Copy SSH clone URL"
+msgstr ""
+
+msgid "Copy SSH public key"
+msgstr ""
+
+msgid "Copy URL"
+msgstr ""
+
+msgid "Copy branch name"
+msgstr ""
+
+msgid "Copy command"
+msgstr ""
+
+msgid "Copy commands"
+msgstr ""
+
+msgid "Copy commit SHA"
+msgstr ""
+
+msgid "Copy environment"
+msgstr ""
+
+msgid "Copy evidence SHA"
+msgstr ""
+
+msgid "Copy file contents"
+msgstr ""
+
+msgid "Copy file path"
+msgstr ""
+
+msgid "Copy key"
+msgstr ""
+
+msgid "Copy labels and milestone from %{source_issuable_reference}."
+msgstr ""
+
+msgid "Copy labels and milestone from other issue or merge request in this project"
+msgstr ""
+
+msgid "Copy link"
+msgstr ""
+
+msgid "Copy link to chart"
+msgstr ""
+
+msgid "Copy reference"
+msgstr ""
+
+msgid "Copy secret"
+msgstr ""
+
+msgid "Copy token"
+msgstr ""
+
+msgid "Copy trigger token"
+msgstr ""
+
+msgid "Copy value"
+msgstr ""
+
+msgid "Could not add admins as members"
+msgstr ""
+
+msgid "Could not authorize chat nickname. Try again!"
+msgstr ""
+
+msgid "Could not change HEAD: branch '%{branch}' does not exist"
+msgstr ""
+
+msgid "Could not connect to FogBugz, check your URL"
+msgstr ""
+
+msgid "Could not connect to Sentry. Refresh the page to try again."
+msgstr ""
+
+msgid "Could not connect to Web IDE file mirror service."
+msgstr ""
+
+msgid "Could not create Wiki Repository at this time. Please try again later."
+msgstr ""
+
+msgid "Could not create environment"
+msgstr ""
+
+msgid "Could not create group"
+msgstr ""
+
+msgid "Could not create project"
+msgstr ""
+
+msgid "Could not delete %{design}. Please try again."
+msgstr ""
+
+msgid "Could not delete chat nickname %{chat_name}."
+msgstr ""
+
+msgid "Could not find design."
+msgstr ""
+
+msgid "Could not remove the trigger."
+msgstr ""
+
+msgid "Could not restore the group"
+msgstr ""
+
+msgid "Could not revoke impersonation token %{token_name}."
+msgstr ""
+
+msgid "Could not revoke personal access token %{personal_access_token_name}."
+msgstr ""
+
+msgid "Could not revoke project access token %{project_access_token_name}."
+msgstr ""
+
+msgid "Could not save group ID"
+msgstr ""
+
+msgid "Could not save project ID"
+msgstr ""
+
+msgid "Could not save prometheus manual configuration"
+msgstr ""
+
+msgid "Could not update the LDAP settings"
+msgstr ""
+
+msgid "Could not upload your designs as one or more files uploaded are not supported."
+msgstr ""
+
+msgid "Country"
+msgstr ""
+
+msgid "Coverage"
+msgstr ""
+
+msgid "Create"
+msgstr ""
+
+msgid "Create %{environment}"
+msgstr ""
+
+msgid "Create %{type}"
+msgstr ""
+
+msgid "Create New Directory"
+msgstr ""
+
+msgid "Create New Domain"
+msgstr ""
+
+msgid "Create Project"
+msgstr ""
+
+msgid "Create a GitLab account first, and then connect it to your %{label} account."
+msgstr ""
+
+msgid "Create a Mattermost team for this group"
+msgstr ""
+
+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 ""
+
+msgid "Create a new branch"
+msgstr ""
+
+msgid "Create a new deploy key for this project"
+msgstr ""
+
+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 ""
+
+msgid "Create a new repository"
+msgstr ""
+
+msgid "Create a personal access token on your account to pull or push via %{protocol}."
+msgstr ""
+
+msgid "Create an account using:"
+msgstr ""
+
+msgid "Create an issue. Issues are created for each alert triggered."
+msgstr ""
+
+msgid "Create and provide your GitHub %{link_start}Personal Access Token%{link_end}. You will need to select the <code>repo</code> scope, so we can display a list of your public and private repositories which are available to import."
+msgstr ""
+
+msgid "Create board"
+msgstr ""
+
+msgid "Create branch"
+msgstr ""
+
+msgid "Create commit"
+msgstr ""
+
+msgid "Create confidential merge request"
+msgstr ""
+
+msgid "Create confidential merge request and branch"
+msgstr ""
+
+msgid "Create directory"
+msgstr ""
+
+msgid "Create empty repository"
+msgstr ""
+
+msgid "Create epic"
+msgstr ""
+
+msgid "Create file"
+msgstr ""
+
+msgid "Create group"
+msgstr ""
+
+msgid "Create group label"
+msgstr ""
+
+msgid "Create issue"
+msgstr ""
+
+msgid "Create iteration"
+msgstr ""
+
+msgid "Create lists from labels. Issues with that label appear in that list."
+msgstr ""
+
+msgid "Create merge request"
+msgstr ""
+
+msgid "Create merge request and branch"
+msgstr ""
+
+msgid "Create milestone"
+msgstr ""
+
+msgid "Create new"
+msgstr ""
+
+msgid "Create new board"
+msgstr ""
+
+msgid "Create new branch"
+msgstr ""
+
+msgid "Create new directory"
+msgstr ""
+
+msgid "Create new file"
+msgstr ""
+
+msgid "Create new file or directory"
+msgstr ""
+
+msgid "Create new label"
+msgstr ""
+
+msgid "Create new..."
+msgstr ""
+
+msgid "Create project"
+msgstr ""
+
+msgid "Create project label"
+msgstr ""
+
+msgid "Create requirement"
+msgstr ""
+
+msgid "Create snippet"
+msgstr ""
+
+msgid "Create wildcard: %{searchTerm}"
+msgstr ""
+
+msgid "Create your first page"
+msgstr ""
+
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
+msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
+msgstr ""
+
+msgid "CreateGroup|You don’t have permission to create groups."
+msgstr ""
+
+msgid "CreateTag|Tag"
+msgstr ""
+
+msgid "CreateTokenToCloneLink|create a personal access token"
+msgstr ""
+
+msgid "Created"
+msgstr ""
+
+msgid "Created %{timestamp}"
+msgstr ""
+
+msgid "Created At"
+msgstr ""
+
+msgid "Created On"
+msgstr ""
+
+msgid "Created a branch and a merge request to resolve this issue."
+msgstr ""
+
+msgid "Created branch '%{branch_name}' and a merge request to resolve this issue."
+msgstr ""
+
+msgid "Created by me"
+msgstr ""
+
+msgid "Created date"
+msgstr ""
+
+msgid "Created issue %{issueLink}"
+msgstr ""
+
+msgid "Created issue %{issueLink} at %{projectLink}"
+msgstr ""
+
+msgid "Created merge request %{mergeRequestLink}"
+msgstr ""
+
+msgid "Created merge request %{mergeRequestLink} at %{projectLink}"
+msgstr ""
+
+msgid "Created on"
+msgstr ""
+
+msgid "Created on:"
+msgstr ""
+
+msgid "Creates a branch and a merge request to resolve this issue."
+msgstr ""
+
+msgid "Creates branch '%{branch_name}' and a merge request to resolve this issue."
+msgstr ""
+
+msgid "Creating epic"
+msgstr ""
+
+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 ""
+
+msgid "Credentials"
+msgstr ""
+
+msgid "CredentialsInventory|No credentials found"
+msgstr ""
+
+msgid "CredentialsInventory|Personal Access Tokens"
+msgstr ""
+
+msgid "CredentialsInventory|SSH Keys"
+msgstr ""
+
+msgid "Critical vulnerabilities present"
+msgstr ""
+
+msgid "Cron Timezone"
+msgstr ""
+
+msgid "Crossplane"
+msgstr ""
+
+msgid "Current Branch"
+msgstr ""
+
+msgid "Current Plan"
+msgstr ""
+
+msgid "Current Project"
+msgstr ""
+
+msgid "Current node"
+msgstr ""
+
+msgid "Current node must be the primary node or you will be locking yourself out"
+msgstr ""
+
+msgid "Current password"
+msgstr ""
+
+msgid "Current vulnerabilities count"
+msgstr ""
+
+msgid "CurrentUser|Buy CI minutes"
+msgstr ""
+
+msgid "CurrentUser|Profile"
+msgstr ""
+
+msgid "CurrentUser|Settings"
+msgstr ""
+
+msgid "CurrentUser|Start a Gold trial"
+msgstr ""
+
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
+msgid "Custom CI configuration path"
+msgstr ""
+
+msgid "Custom Git clone URL for HTTP(S)"
+msgstr ""
+
+msgid "Custom hostname (for private commit emails)"
+msgstr ""
+
+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 %{notification_link}."
+msgstr ""
+
+msgid "Custom project templates"
+msgstr ""
+
+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 ""
+
+msgid "Custom range"
+msgstr ""
+
+msgid "Custom range (UTC)"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Add a stage"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Add stage"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Editing stage"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Enter a name for the stage"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Name"
+msgstr ""
+
+msgid "CustomCycleAnalytics|New stage"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Please select a start event first"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Select start event"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Select stop event"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Stage name already exists"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Start event"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Start event changed, please select a valid stop event"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Start event label"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Stop event"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Stop event label"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Update stage"
+msgstr ""
+
+msgid "Customer Portal"
+msgstr ""
+
+msgid "Customize colors"
+msgstr ""
+
+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 how Google Code 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 ""
+
+msgid "Customize language and region related settings."
+msgstr ""
+
+msgid "Customize name"
+msgstr ""
+
+msgid "Customize your pipeline configuration, view your pipeline status and coverage report."
+msgstr ""
+
+msgid "Customize your pipeline configuration."
+msgstr ""
+
+msgid "Cycle Time"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Issue closed"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Issue created"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Issue first added to a board"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Issue first associated with a milestone"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Issue first associated with a milestone or issue first added to a board"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Issue first mentioned in a commit"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Issue label was added"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Issue label was removed"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Issue last edited"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Merge request closed"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Merge request created"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Merge request first deployed to production"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Merge request label was added"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Merge request label was removed"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Merge request last build finish time"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Merge request last build start time"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Merge request last edited"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Merge request merged"
+msgstr ""
+
+msgid "CycleAnalyticsStage|Code"
+msgstr ""
+
+msgid "CycleAnalyticsStage|Issue"
+msgstr ""
+
+msgid "CycleAnalyticsStage|Plan"
+msgstr ""
+
+msgid "CycleAnalyticsStage|Review"
+msgstr ""
+
+msgid "CycleAnalyticsStage|Staging"
+msgstr ""
+
+msgid "CycleAnalyticsStage|Test"
+msgstr ""
+
+msgid "CycleAnalyticsStage|Total"
+msgstr ""
+
+msgid "CycleAnalyticsStage|is not available for the selected group"
+msgstr ""
+
+msgid "CycleAnalyticsStage|should be under a group"
+msgstr ""
+
+msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
+msgstr ""
+
+msgid "CycleAnalytics|%{stageCount} stages selected"
+msgstr ""
+
+msgid "CycleAnalytics|All stages"
+msgstr ""
+
+msgid "CycleAnalytics|Date"
+msgstr ""
+
+msgid "CycleAnalytics|Days to completion"
+msgstr ""
+
+msgid "CycleAnalytics|Display chart filters"
+msgstr ""
+
+msgid "CycleAnalytics|No stages selected"
+msgstr ""
+
+msgid "CycleAnalytics|Number of tasks"
+msgstr ""
+
+msgid "CycleAnalytics|Only %{maxLabels} labels can be selected at this time"
+msgstr ""
+
+msgid "CycleAnalytics|Project selected"
+msgid_plural "CycleAnalytics|%d projects selected"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "CycleAnalytics|Select labels"
+msgstr ""
+
+msgid "CycleAnalytics|Show"
+msgstr ""
+
+msgid "CycleAnalytics|Showing %{subjectFilterText} and %{selectedLabelsCount} labels"
+msgstr ""
+
+msgid "CycleAnalytics|Showing data for group '%{groupName}' and %{selectedProjectCount} projects from %{startDate} to %{endDate}"
+msgstr ""
+
+msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{startDate} to %{endDate}"
+msgstr ""
+
+msgid "CycleAnalytics|Stages"
+msgstr ""
+
+msgid "CycleAnalytics|Tasks by type"
+msgstr ""
+
+msgid "CycleAnalytics|The given date range is larger than 180 days"
+msgstr ""
+
+msgid "CycleAnalytics|Total days to completion"
+msgstr ""
+
+msgid "CycleAnalytics|Type of work"
+msgstr ""
+
+msgid "CycleAnalytics|group dropdown filter"
+msgstr ""
+
+msgid "CycleAnalytics|not allowed for the given start event"
+msgstr ""
+
+msgid "CycleAnalytics|project dropdown filter"
+msgstr ""
+
+msgid "CycleAnalytics|stage dropdown"
+msgstr ""
+
+msgid "DAG"
+msgstr ""
+
+msgid "DNS"
+msgstr ""
+
+msgid "Dashboard"
+msgstr ""
+
+msgid "DashboardProjects|All"
+msgstr ""
+
+msgid "DashboardProjects|Personal"
+msgstr ""
+
+msgid "DashboardProjects|Trending"
+msgstr ""
+
+msgid "Dashboards"
+msgstr ""
+
+msgid "Dashboard|%{firstProject} and %{secondProject}"
+msgstr ""
+
+msgid "Dashboard|%{firstProject}, %{rest}, and %{secondProject}"
+msgstr ""
+
+msgid "Dashboard|Unable to add %{invalidProjects}. This dashboard is available for public projects, and private projects in groups with a Silver plan."
+msgstr ""
+
+msgid "Data is still calculating..."
+msgstr ""
+
+msgid "Date"
+msgstr ""
+
+msgid "Date picker"
+msgstr ""
+
+msgid "Date range cannot exceed %{maxDateRange} days."
+msgstr ""
+
+msgid "Day of month"
+msgstr ""
+
+msgid "DayTitle|F"
+msgstr ""
+
+msgid "DayTitle|M"
+msgstr ""
+
+msgid "DayTitle|S"
+msgstr ""
+
+msgid "DayTitle|W"
+msgstr ""
+
+msgid "Days"
+msgstr ""
+
+msgid "Days to merge"
+msgstr ""
+
+msgid "Debug"
+msgstr ""
+
+msgid "Dec"
+msgstr ""
+
+msgid "December"
+msgstr ""
+
+msgid "Decline"
+msgstr ""
+
+msgid "Decline and sign out"
+msgstr ""
+
+msgid "Default Branch"
+msgstr ""
+
+msgid "Default CI configuration path"
+msgstr ""
+
+msgid "Default artifacts expiration"
+msgstr ""
+
+msgid "Default branch"
+msgstr ""
+
+msgid "Default branch and protected branches"
+msgstr ""
+
+msgid "Default classification label"
+msgstr ""
+
+msgid "Default dashboard"
+msgstr ""
+
+msgid "Default deletion adjourned period"
+msgstr ""
+
+msgid "Default description template for issues"
+msgstr ""
+
+msgid "Default description template for merge requests"
+msgstr ""
+
+msgid "Default first day of the week"
+msgstr ""
+
+msgid "Default first day of the week in calendars and date pickers."
+msgstr ""
+
+msgid "Default issue template"
+msgstr ""
+
+msgid "Default project deletion protection"
+msgstr ""
+
+msgid "Default projects limit"
+msgstr ""
+
+msgid "Default stages"
+msgstr ""
+
+msgid "Default: Directly import the Google Code email address or username"
+msgstr ""
+
+msgid "Default: Map a FogBugz account ID to a full name"
+msgstr ""
+
+msgid "Define a custom pattern with cron syntax"
+msgstr ""
+
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
+msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
+msgstr ""
+
+msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise 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 it's timer finishes."
+msgstr ""
+
+msgid "DelayedJobs|Start now"
+msgstr ""
+
+msgid "DelayedJobs|Unschedule"
+msgstr ""
+
+msgid "DelayedJobs|delayed"
+msgstr ""
+
+msgid "Delete"
+msgstr ""
+
+msgid "Delete Comment"
+msgstr ""
+
+msgid "Delete Package"
+msgstr ""
+
+msgid "Delete Snippet"
+msgstr ""
+
+msgid "Delete artifacts"
+msgstr ""
+
+msgid "Delete board"
+msgstr ""
+
+msgid "Delete comment"
+msgstr ""
+
+msgid "Delete domain"
+msgstr ""
+
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
+msgid "Delete license"
+msgstr ""
+
+msgid "Delete list"
+msgstr ""
+
+msgid "Delete pipeline"
+msgstr ""
+
+msgid "Delete project"
+msgstr ""
+
+msgid "Delete serverless domain?"
+msgstr ""
+
+msgid "Delete snippet"
+msgstr ""
+
+msgid "Delete snippet?"
+msgstr ""
+
+msgid "Delete source branch"
+msgstr ""
+
+msgid "Delete this attachment"
+msgstr ""
+
+msgid "Delete variable"
+msgstr ""
+
+msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
+msgstr ""
+
+msgid "DeleteProject|Failed to remove project snippets. Please try again or contact administrator."
+msgstr ""
+
+msgid "DeleteProject|Failed to remove some tags in project container registry. Please try again or contact administrator."
+msgstr ""
+
+msgid "DeleteProject|Failed to remove wiki repository. Please try again or contact administrator."
+msgstr ""
+
+msgid "DeleteProject|Failed to restore project repository. Please contact the administrator."
+msgstr ""
+
+msgid "DeleteProject|Failed to restore wiki repository. Please contact the administrator."
+msgstr ""
+
+msgid "Deleted"
+msgstr ""
+
+msgid "Deleted chat nickname: %{chat_name}!"
+msgstr ""
+
+msgid "Deleted in this version"
+msgstr ""
+
+msgid "Deleting"
+msgstr ""
+
+msgid "Deleting the license failed."
+msgstr ""
+
+msgid "Deleting the license failed. The license was not found."
+msgstr ""
+
+msgid "Deleting the license failed. You are not permitted to perform this action."
+msgstr ""
+
+msgid "Deletion pending. This project will be removed on %{date}. Repository and other project resources are read-only."
+msgstr ""
+
+msgid "Denied authorization of chat nickname %{user_name}."
+msgstr ""
+
+msgid "Deny"
+msgstr ""
+
+msgid "Dependencies"
+msgstr ""
+
+msgid "Dependencies help page link"
+msgstr ""
+
+msgid "Dependencies|%d additional vulnerability not shown"
+msgid_plural "Dependencies|%d additional vulnerabilities not shown"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Dependencies|%d vulnerability detected"
+msgid_plural "Dependencies|%d vulnerabilities detected"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Dependencies|%{remainingLicensesCount} more"
+msgstr ""
+
+msgid "Dependencies|All"
+msgstr ""
+
+msgid "Dependencies|Based on the %{linkStart}latest successful%{linkEnd} scan"
+msgstr ""
+
+msgid "Dependencies|Component"
+msgstr ""
+
+msgid "Dependencies|Component name"
+msgstr ""
+
+msgid "Dependencies|Export as JSON"
+msgstr ""
+
+msgid "Dependencies|Job failed to generate the dependency list"
+msgstr ""
+
+msgid "Dependencies|License"
+msgstr ""
+
+msgid "Dependencies|Location"
+msgstr ""
+
+msgid "Dependencies|Packager"
+msgstr ""
+
+msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
+msgstr ""
+
+msgid "Dependencies|Toggle vulnerability list"
+msgstr ""
+
+msgid "Dependencies|Unsupported file(s) detected"
+msgstr ""
+
+msgid "Dependencies|Vulnerable components"
+msgstr ""
+
+msgid "Dependency List"
+msgstr ""
+
+msgid "Dependency List has no entries"
+msgstr ""
+
+msgid "Dependency Proxy"
+msgstr ""
+
+msgid "Dependency Scanning"
+msgstr ""
+
+msgid "Dependency proxy"
+msgstr ""
+
+msgid "Dependency proxy URL"
+msgstr ""
+
+msgid "Dependency proxy feature is limited to public groups for now."
+msgstr ""
+
+msgid "DependencyProxy|Toggle Dependency Proxy"
+msgstr ""
+
+msgid "Depends on %d merge request being merged"
+msgid_plural "Depends on %d merge requests being merged"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Depends on <strong>%d closed</strong> merge request."
+msgid_plural "Depends on <strong>%d closed</strong> merge requests."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Deploy"
+msgid_plural "Deploys"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Deploy Keys"
+msgstr ""
+
+msgid "Deploy key was successfully updated."
+msgstr ""
+
+msgid "Deploy keys allow read-only or read-write (if enabled) access to your repository. Deploy keys can be used for CI, staging or production servers. You can create a deploy key or add an existing one."
+msgstr ""
+
+msgid "Deploy progress not found. To see pods, ensure your environment matches %{linkStart}deploy board criteria%{linkEnd}."
+msgstr ""
+
+msgid "Deploy to..."
+msgstr ""
+
+msgid "DeployBoard|Matching on the %{appLabel} label has been removed for deploy boards. To see all instances on your board, you must update your chart and redeploy."
+msgstr ""
+
+msgid "DeployKeys|+%{count} others"
+msgstr ""
+
+msgid "DeployKeys|Current project"
+msgstr ""
+
+msgid "DeployKeys|Deploy key"
+msgstr ""
+
+msgid "DeployKeys|Enabled deploy keys"
+msgstr ""
+
+msgid "DeployKeys|Error enabling deploy key"
+msgstr ""
+
+msgid "DeployKeys|Error getting deploy keys"
+msgstr ""
+
+msgid "DeployKeys|Error removing deploy key"
+msgstr ""
+
+msgid "DeployKeys|Expand %{count} other projects"
+msgstr ""
+
+msgid "DeployKeys|Loading deploy keys"
+msgstr ""
+
+msgid "DeployKeys|No deploy keys found. Create one with the form above."
+msgstr ""
+
+msgid "DeployKeys|Privately accessible deploy keys"
+msgstr ""
+
+msgid "DeployKeys|Project usage"
+msgstr ""
+
+msgid "DeployKeys|Publicly accessible deploy keys"
+msgstr ""
+
+msgid "DeployKeys|Read access only"
+msgstr ""
+
+msgid "DeployKeys|Write access allowed"
+msgstr ""
+
+msgid "DeployKeys|You are going to remove this deploy key. Are you sure?"
+msgstr ""
+
+msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
+msgstr ""
+
+msgid "DeployTokens|Add a deploy token"
+msgstr ""
+
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
+msgid "DeployTokens|Allows read-only access to the registry images"
+msgstr ""
+
+msgid "DeployTokens|Allows read-only access to the repository"
+msgstr ""
+
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
+msgid "DeployTokens|Allows write access to the registry images"
+msgstr ""
+
+msgid "DeployTokens|Copy deploy token"
+msgstr ""
+
+msgid "DeployTokens|Copy username"
+msgstr ""
+
+msgid "DeployTokens|Create deploy token"
+msgstr ""
+
+msgid "DeployTokens|Created"
+msgstr ""
+
+msgid "DeployTokens|Default format is \"gitlab+deploy-token-{n}\". Enter custom username if you want to change it."
+msgstr ""
+
+msgid "DeployTokens|Deploy Tokens"
+msgstr ""
+
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
+msgstr ""
+
+msgid "DeployTokens|Expires"
+msgstr ""
+
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
+msgstr ""
+
+msgid "DeployTokens|Name"
+msgstr ""
+
+msgid "DeployTokens|Pick a name for the application, and we'll give you a unique deploy token."
+msgstr ""
+
+msgid "DeployTokens|Revoke"
+msgstr ""
+
+msgid "DeployTokens|Revoke %{b_start}%{name}%{b_end}?"
+msgstr ""
+
+msgid "DeployTokens|Revoke %{name}"
+msgstr ""
+
+msgid "DeployTokens|Scopes"
+msgstr ""
+
+msgid "DeployTokens|This %{entity_type} has no active Deploy Tokens."
+msgstr ""
+
+msgid "DeployTokens|This action cannot be undone."
+msgstr ""
+
+msgid "DeployTokens|Use this token as a password. Make sure you save it - you won't be able to access it again."
+msgstr ""
+
+msgid "DeployTokens|Use this username as a login."
+msgstr ""
+
+msgid "DeployTokens|Username"
+msgstr ""
+
+msgid "DeployTokens|You are about to revoke %{b_start}%{name}%{b_end}."
+msgstr ""
+
+msgid "DeployTokens|Your New Deploy Token"
+msgstr ""
+
+msgid "DeployTokens|Your new group deploy token has been created."
+msgstr ""
+
+msgid "DeployTokens|Your new project deploy token has been created."
+msgstr ""
+
+msgid "Deployed"
+msgstr ""
+
+msgid "Deployed to"
+msgstr ""
+
+msgid "Deploying to"
+msgstr ""
+
+msgid "Deployment Frequency"
+msgstr ""
+
+msgid "Deployment|API"
+msgstr ""
+
+msgid "Deployment|This deployment was created using the API"
+msgstr ""
+
+msgid "Deployment|canceled"
+msgstr ""
+
+msgid "Deployment|created"
+msgstr ""
+
+msgid "Deployment|failed"
+msgstr ""
+
+msgid "Deployment|running"
+msgstr ""
+
+msgid "Deployment|success"
+msgstr ""
+
+msgid "Deprioritize label"
+msgstr ""
+
+msgid "Descending"
+msgstr ""
+
+msgid "Describe the goal of the changes and what reviewers should be aware of."
+msgstr ""
+
+msgid "Describe the requirement here"
+msgstr ""
+
+msgid "Description"
+msgstr ""
+
+msgid "Description parsed with %{link_start}GitLab Flavored Markdown%{link_end}"
+msgstr ""
+
+msgid "Description templates allow you to define context-specific templates for issue and merge request description fields for your project."
+msgstr ""
+
+msgid "Description:"
+msgstr ""
+
+msgid "Descriptive label"
+msgstr ""
+
+msgid "Deselect all"
+msgstr ""
+
+msgid "Design Management files and data"
+msgstr ""
+
+msgid "DesignManagement|%{current_design} of %{designs_count}"
+msgstr ""
+
+msgid "DesignManagement|%{filename} did not change."
+msgstr ""
+
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgstr ""
+
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
+msgstr ""
+
+msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
+msgstr ""
+
+msgid "DesignManagement|Are you sure you want to delete the selected designs?"
+msgstr ""
+
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
+msgid "DesignManagement|Cancel comment confirmation"
+msgstr ""
+
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
+msgid "DesignManagement|Could not add a new comment. Please try again."
+msgstr ""
+
+msgid "DesignManagement|Could not create new discussion. Please try again."
+msgstr ""
+
+msgid "DesignManagement|Could not update discussion. Please try again."
+msgstr ""
+
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
+msgid "DesignManagement|Delete"
+msgstr ""
+
+msgid "DesignManagement|Delete designs confirmation"
+msgstr ""
+
+msgid "DesignManagement|Delete selected"
+msgstr ""
+
+msgid "DesignManagement|Deselect all"
+msgstr ""
+
+msgid "DesignManagement|Discard comment"
+msgstr ""
+
+msgid "DesignManagement|Error uploading a new design. Please try again."
+msgstr ""
+
+msgid "DesignManagement|Go back to designs"
+msgstr ""
+
+msgid "DesignManagement|Go to next design"
+msgstr ""
+
+msgid "DesignManagement|Go to previous design"
+msgstr ""
+
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
+msgid "DesignManagement|Keep comment"
+msgstr ""
+
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
+msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
+msgstr ""
+
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
+msgid "DesignManagement|Select all"
+msgstr ""
+
+msgid "DesignManagement|The maximum number of designs allowed to be uploaded is %{upload_limit}. Please try again."
+msgstr ""
+
+msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
+msgstr ""
+
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
+msgid "DesignManagement|Upload skipped."
+msgstr ""
+
+msgid "DesignManagement|and %{moreCount} more."
+msgstr ""
+
+msgid "Designs"
+msgstr ""
+
+msgid "Destroy"
+msgstr ""
+
+msgid "Detail"
+msgstr ""
+
+msgid "Details"
+msgstr ""
+
+msgid "Details (default)"
+msgstr ""
+
+msgid "Detect host keys"
+msgstr ""
+
+msgid "DevOps Score"
+msgstr ""
+
+msgid "Diff content limits"
+msgstr ""
+
+msgid "Diff limits"
+msgstr ""
+
+msgid "Difference between start date and now"
+msgstr ""
+
+msgid "DiffsCompareBaseBranch|(HEAD)"
+msgstr ""
+
+msgid "DiffsCompareBaseBranch|(base)"
+msgstr ""
+
+msgid "Diffs|No file name available"
+msgstr ""
+
+msgid "Diffs|Show unchanged lines"
+msgstr ""
+
+msgid "Diffs|Something went wrong while fetching diff lines."
+msgstr ""
+
+msgid "Direction"
+msgstr ""
+
+msgid "Directory name"
+msgstr ""
+
+msgid "Disable"
+msgstr ""
+
+msgid "Disable for this project"
+msgstr ""
+
+msgid "Disable group Runners"
+msgstr ""
+
+msgid "Disable public access to Pages sites"
+msgstr ""
+
+msgid "Disable shared Runners"
+msgstr ""
+
+msgid "Disable two-factor authentication"
+msgstr ""
+
+msgid "Disabled"
+msgstr ""
+
+msgid "Disabled mirrors can only be enabled by instance owners. It is recommended that you delete them."
+msgstr ""
+
+msgid "Discard all changes"
+msgstr ""
+
+msgid "Discard all changes?"
+msgstr ""
+
+msgid "Discard changes"
+msgstr ""
+
+msgid "Discard changes to %{path}?"
+msgstr ""
+
+msgid "Discard draft"
+msgstr ""
+
+msgid "Discard review"
+msgstr ""
+
+msgid "DiscordService|Discord Notifications"
+msgstr ""
+
+msgid "DiscordService|Receive event notifications in Discord"
+msgstr ""
+
+msgid "Discover GitLab Geo"
+msgstr ""
+
+msgid "Discover projects, groups and snippets. Share your projects with others"
+msgstr ""
+
+msgid "Discover|Check your application for security vulnerabilities that may lead to unauthorized access, data leaks, and denial of services."
+msgstr ""
+
+msgid "Discover|For code that's already live in production, our dashboards give you an easy way to prioritize any issues that are found, empowering your team to ship quickly and securely."
+msgstr ""
+
+msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
+msgstr ""
+
+msgid "Discover|Give feedback for this page"
+msgstr ""
+
+msgid "Discover|Security capabilities, integrated into your development lifecycle"
+msgstr ""
+
+msgid "Discover|See the other features of the %{linkStart}gold plan%{linkEnd}"
+msgstr ""
+
+msgid "Discover|Start a free trial"
+msgstr ""
+
+msgid "Discover|Upgrade now"
+msgstr ""
+
+msgid "Discuss a specific suggestion or question"
+msgstr ""
+
+msgid "Discuss a specific suggestion or question that needs to be resolved"
+msgstr ""
+
+msgid "Discuss a specific suggestion or question that needs to be resolved."
+msgstr ""
+
+msgid "Discuss a specific suggestion or question."
+msgstr ""
+
+msgid "Discussion"
+msgstr ""
+
+msgid "Discussion to reply to cannot be found"
+msgstr ""
+
+msgid "Disk Usage"
+msgstr ""
+
+msgid "Dismiss"
+msgstr ""
+
+msgid "Dismiss %d selected vulnerability as"
+msgid_plural "Dismiss %d selected vulnerabilities as"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Dismiss DevOps Score introduction"
+msgstr ""
+
+msgid "Dismiss Merge Request promotion"
+msgstr ""
+
+msgid "Dismiss Selected"
+msgstr ""
+
+msgid "Dismiss Value Stream Analytics introduction box"
+msgstr ""
+
+msgid "Dismiss trial promotion"
+msgstr ""
+
+msgid "Dismissable"
+msgstr ""
+
+msgid "Dismissed"
+msgstr ""
+
+msgid "Dismissed at %{projectLink}"
+msgstr ""
+
+msgid "Dismissed on pipeline %{pipelineLink}"
+msgstr ""
+
+msgid "Dismissed on pipeline %{pipelineLink} at %{projectLink}"
+msgstr ""
+
+msgid "Display name"
+msgstr ""
+
+msgid "Display rendered file"
+msgstr ""
+
+msgid "Display source"
+msgstr ""
+
+msgid "Do not display offers from third parties within GitLab"
+msgstr ""
+
+msgid "Do you want to customize how Google Code email addresses and usernames are imported into GitLab?"
+msgstr ""
+
+msgid "Dockerfile"
+msgstr ""
+
+msgid "Documentation"
+msgstr ""
+
+msgid "Documentation for popular identity providers"
+msgstr ""
+
+msgid "Doing"
+msgstr ""
+
+msgid "Domain"
+msgstr ""
+
+msgid "Domain cannot be deleted while associated to one or more clusters."
+msgstr ""
+
+msgid "Domain verification is an essential security measure for public GitLab sites. Users are required to demonstrate they control a domain before it is enabled"
+msgstr ""
+
+msgid "Domain was successfully created."
+msgstr ""
+
+msgid "Domain was successfully deleted."
+msgstr ""
+
+msgid "Domain was successfully updated."
+msgstr ""
+
+msgid "Don't have an account yet?"
+msgstr ""
+
+msgid "Don't include description in commit message"
+msgstr ""
+
+msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
+msgstr ""
+
+msgid "Don't show again"
+msgstr ""
+
+msgid "Don't worry, you can access this tour by clicking on the help icon in the top right corner and choose <strong>Learn GitLab</strong>."
+msgstr ""
+
+msgid "Done"
+msgstr ""
+
+msgid "Download"
+msgstr ""
+
+msgid "Download %{format}"
+msgstr ""
+
+msgid "Download %{format}:"
+msgstr ""
+
+msgid "Download CSV"
+msgstr ""
+
+msgid "Download artifacts"
+msgstr ""
+
+msgid "Download as"
+msgstr ""
+
+msgid "Download asset"
+msgstr ""
+
+msgid "Download codes"
+msgstr ""
+
+msgid "Download evidence JSON"
+msgstr ""
+
+msgid "Download export"
+msgstr ""
+
+msgid "Download image"
+msgstr ""
+
+msgid "Download license"
+msgstr ""
+
+msgid "Download raw data (.csv)"
+msgstr ""
+
+msgid "Download source code"
+msgstr ""
+
+msgid "Download this directory"
+msgstr ""
+
+msgid "DownloadCommit|Email Patches"
+msgstr ""
+
+msgid "DownloadCommit|Plain Diff"
+msgstr ""
+
+msgid "DownloadSource|Download"
+msgstr ""
+
+msgid "Downstream"
+msgstr ""
+
+msgid "Downvotes"
+msgstr ""
+
+msgid "Drop your designs to start your upload."
+msgstr ""
+
+msgid "Due Date"
+msgstr ""
+
+msgid "Due date"
+msgstr ""
+
+msgid "Duration"
+msgstr ""
+
+msgid "Duration for the last 30 commits"
+msgstr ""
+
+msgid "During this process, you’ll be asked for URLs from GitLab’s side. Use the URLs shown below."
+msgstr ""
+
+msgid "Dynamic Application Security Testing (DAST)"
+msgstr ""
+
+msgid "Each Runner can be in one of the following states and/or belong to one of the following types:"
+msgstr ""
+
+msgid "Each Runner can be in one of the following states:"
+msgstr ""
+
+msgid "Edit"
+msgstr ""
+
+msgid "Edit %{issuable}"
+msgstr ""
+
+msgid "Edit %{name}"
+msgstr ""
+
+msgid "Edit Comment"
+msgstr ""
+
+msgid "Edit Deploy Key"
+msgstr ""
+
+msgid "Edit Geo Node"
+msgstr ""
+
+msgid "Edit Group Hook"
+msgstr ""
+
+msgid "Edit Label"
+msgstr ""
+
+msgid "Edit Milestone"
+msgstr ""
+
+msgid "Edit Password"
+msgstr ""
+
+msgid "Edit Pipeline Schedule %{id}"
+msgstr ""
+
+msgid "Edit Release"
+msgstr ""
+
+msgid "Edit Snippet"
+msgstr ""
+
+msgid "Edit System Hook"
+msgstr ""
+
+msgid "Edit application"
+msgstr ""
+
+msgid "Edit board"
+msgstr ""
+
+msgid "Edit comment"
+msgstr ""
+
+msgid "Edit dashboard"
+msgstr ""
+
+msgid "Edit description"
+msgstr ""
+
+msgid "Edit environment"
+msgstr ""
+
+msgid "Edit file"
+msgstr ""
+
+msgid "Edit files in the editor and commit changes here"
+msgstr ""
+
+msgid "Edit group: %{group_name}"
+msgstr ""
+
+msgid "Edit identity for %{user_name}"
+msgstr ""
+
+msgid "Edit issues"
+msgstr ""
+
+msgid "Edit public deploy key"
+msgstr ""
+
+msgid "Edit stage"
+msgstr ""
+
+msgid "Edit this release"
+msgstr ""
+
+msgid "Edit wiki page"
+msgstr ""
+
+msgid "Edit your most recent comment in a thread (from an empty textarea)"
+msgstr ""
+
+msgid "Edited %{timeago}"
+msgstr ""
+
+msgid "Editing"
+msgstr ""
+
+msgid "Elasticsearch"
+msgstr ""
+
+msgid "Elasticsearch AWS IAM credentials"
+msgstr ""
+
+msgid "Elasticsearch indexing restrictions"
+msgstr ""
+
+msgid "Elasticsearch indexing started"
+msgstr ""
+
+msgid "Elasticsearch integration. Elasticsearch AWS IAM."
+msgstr ""
+
+msgid "Elasticsearch returned status code: %{status_code}"
+msgstr ""
+
+msgid "Elastic|None. Select namespaces to index."
+msgstr ""
+
+msgid "Elastic|None. Select projects to index."
+msgstr ""
+
+msgid "Email"
+msgstr ""
+
+msgid "Email address"
+msgstr ""
+
+msgid "Email could not be sent"
+msgstr ""
+
+msgid "Email display name"
+msgstr ""
+
+msgid "Email not verified. Please verify your email in Salesforce."
+msgstr ""
+
+msgid "Email patch"
+msgstr ""
+
+msgid "Email restrictions"
+msgstr ""
+
+msgid "Email restrictions for sign-ups"
+msgstr ""
+
+msgid "Email sent"
+msgstr ""
+
+msgid "Email the pipelines status to a list of recipients."
+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 ""
+
+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 ""
+
+msgid "EmailError|We couldn't figure out what the email is for. Please create your issue or comment through the web interface."
+msgstr ""
+
+msgid "EmailError|We couldn't figure out what the email is in reply to. Please create your comment through the web interface."
+msgstr ""
+
+msgid "EmailError|We couldn't figure out what user corresponds to the email. Please create your comment through the web interface."
+msgstr ""
+
+msgid "EmailError|We couldn't find the project. Please check if there's any typo."
+msgstr ""
+
+msgid "EmailError|You are not allowed to perform this action. If you believe this is in error, contact a staff member."
+msgstr ""
+
+msgid "EmailError|Your account has been blocked. If you believe this is in error, contact a staff member."
+msgstr ""
+
+msgid "EmailToken|reset it"
+msgstr ""
+
+msgid "EmailToken|resetting..."
+msgstr ""
+
+msgid "Emails"
+msgstr ""
+
+msgid "Emails sent from Service Desk will have this name"
+msgstr ""
+
+msgid "Emails separated by comma"
+msgstr ""
+
+msgid "EmailsOnPushService|Disable code diffs"
+msgstr ""
+
+msgid "EmailsOnPushService|Don't include possibly sensitive code diffs in notification body."
+msgstr ""
+
+msgid "EmailsOnPushService|Email the commits and diff of each push to a list of recipients."
+msgstr ""
+
+msgid "EmailsOnPushService|Emails on push"
+msgstr ""
+
+msgid "EmailsOnPushService|Emails separated by whitespace"
+msgstr ""
+
+msgid "EmailsOnPushService|Send from committer"
+msgstr ""
+
+msgid "EmailsOnPushService|Send notifications from the committer's email address if the domain is part of the domain GitLab is running on (e.g. %{domains})."
+msgstr ""
+
+msgid "Embed"
+msgstr ""
+
+msgid "Empty file"
+msgstr ""
+
+msgid "Enable"
+msgstr ""
+
+msgid "Enable Auto DevOps"
+msgstr ""
+
+msgid "Enable HTML emails"
+msgstr ""
+
+msgid "Enable Incident Management inbound alert limit"
+msgstr ""
+
+msgid "Enable PlantUML"
+msgstr ""
+
+msgid "Enable Pseudonymizer data collection"
+msgstr ""
+
+msgid "Enable SAML authentication for this group"
+msgstr ""
+
+msgid "Enable Seat Link"
+msgstr ""
+
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
+msgid "Enable access to Grafana"
+msgstr ""
+
+msgid "Enable access to the Performance Bar for a given group."
+msgstr ""
+
+msgid "Enable and configure Grafana."
+msgstr ""
+
+msgid "Enable and configure Prometheus metrics."
+msgstr ""
+
+msgid "Enable classification control using an external service"
+msgstr ""
+
+msgid "Enable container expiration and retention policies for projects created earlier than GitLab 12.7."
+msgstr ""
+
+msgid "Enable email restrictions for sign ups"
+msgstr ""
+
+msgid "Enable error tracking"
+msgstr ""
+
+msgid "Enable feature to choose access level"
+msgstr ""
+
+msgid "Enable for this project"
+msgstr ""
+
+msgid "Enable group Runners"
+msgstr ""
+
+msgid "Enable header and footer in emails"
+msgstr ""
+
+msgid "Enable integration"
+msgstr ""
+
+msgid "Enable maintenance mode"
+msgstr ""
+
+msgid "Enable mirror configuration"
+msgstr ""
+
+msgid "Enable or disable Seat Link."
+msgstr ""
+
+msgid "Enable or disable keyboard shortcuts"
+msgstr ""
+
+msgid "Enable or disable the Pseudonymizer data collection."
+msgstr ""
+
+msgid "Enable or disable version check and usage ping."
+msgstr ""
+
+msgid "Enable protected paths rate limit"
+msgstr ""
+
+msgid "Enable proxy"
+msgstr ""
+
+msgid "Enable reCAPTCHA or Akismet and set IP limits. For reCAPTCHA, we currently only support %{recaptcha_v2_link_start}v2%{recaptcha_v2_link_end}"
+msgstr ""
+
+msgid "Enable shared Runners"
+msgstr ""
+
+msgid "Enable snowplow tracking"
+msgstr ""
+
+msgid "Enable two-factor authentication"
+msgstr ""
+
+msgid "Enable usage ping"
+msgstr ""
+
+msgid "Enable usage ping to get an overview of how you are using GitLab from a feature perspective."
+msgstr ""
+
+msgid "Enable/disable your service desk. %{link_start}Learn more about service desk%{link_end}."
+msgstr ""
+
+msgid "EnableReviewApp|%{stepStart}Step 1%{stepEnd}. Ensure you have Kubernetes set up and have a base domain for your %{linkStart}cluster%{linkEnd}."
+msgstr ""
+
+msgid "EnableReviewApp|%{stepStart}Step 2%{stepEnd}. Copy the following snippet:"
+msgstr ""
+
+msgid "EnableReviewApp|%{stepStart}Step 3%{stepEnd}. Add it to the project %{linkStart}gitlab-ci.yml%{linkEnd} file."
+msgstr ""
+
+msgid "EnableReviewApp|Close"
+msgstr ""
+
+msgid "EnableReviewApp|Copy snippet text"
+msgstr ""
+
+msgid "Enabled"
+msgstr ""
+
+msgid "Enabled Git access protocols"
+msgstr ""
+
+msgid "Enabled sources for code import during project creation. OmniAuth must be configured for GitHub"
+msgstr ""
+
+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 ""
+
+msgid "Encountered an error while rendering: %{err}"
+msgstr ""
+
+msgid "End date"
+msgstr ""
+
+msgid "Ends at (UTC)"
+msgstr ""
+
+msgid "Enforce DNS rebinding attack protection"
+msgstr ""
+
+msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
+msgstr ""
+
+msgid "Ensure your %{linkStart}environment is part of the deploy stage%{linkEnd} of your CI pipeline to track deployments to your cluster."
+msgstr ""
+
+msgid "Enter 2FA for Admin Mode"
+msgstr ""
+
+msgid "Enter Admin Mode"
+msgstr ""
+
+msgid "Enter IP address range"
+msgstr ""
+
+msgid "Enter a number"
+msgstr ""
+
+msgid "Enter a whole number between 0 and 100"
+msgstr ""
+
+msgid "Enter at least three characters to search"
+msgstr ""
+
+msgid "Enter board name"
+msgstr ""
+
+msgid "Enter domain"
+msgstr ""
+
+msgid "Enter in your Bitbucket Server URL and personal access token below"
+msgstr ""
+
+msgid "Enter in your Phabricator Server URL and personal access token below"
+msgstr ""
+
+msgid "Enter merge request URLs"
+msgstr ""
+
+msgid "Enter new %{field_title}"
+msgstr ""
+
+msgid "Enter new AWS Secret Access Key"
+msgstr ""
+
+msgid "Enter number of issues"
+msgstr ""
+
+msgid "Enter one or more user ID separated by commas"
+msgstr ""
+
+msgid "Enter the code from the two-factor app on your mobile device. If you've lost your device, you may enter one of your recovery codes."
+msgstr ""
+
+msgid "Enter the issue description"
+msgstr ""
+
+msgid "Enter the issue title"
+msgstr ""
+
+msgid "Enter the merge request description"
+msgstr ""
+
+msgid "Enter the merge request title"
+msgstr ""
+
+msgid "Enter the name of your application, and we'll return a unique %{type}."
+msgstr ""
+
+msgid "Enter your password to approve"
+msgstr ""
+
+msgid "Environment"
+msgstr ""
+
+msgid "Environment does not have deployments"
+msgstr ""
+
+msgid "Environment scope"
+msgstr ""
+
+msgid "Environment variables are applied to environments via the runner. They can be protected by only exposing them to protected branches or tags. Additionally, they can be masked so they are hidden in job logs, though they must match certain regexp requirements to do so. You can use environment variables for passwords, secret keys, or whatever you want."
+msgstr ""
+
+msgid "Environment variables are configured by your administrator to be %{link_start}protected%{link_end} by default"
+msgstr ""
+
+msgid "Environment:"
+msgstr ""
+
+msgid "EnvironmentDashboard|API"
+msgstr ""
+
+msgid "EnvironmentDashboard|Created through the Deployment API"
+msgstr ""
+
+msgid "EnvironmentDashboard|You are looking at the last updated environment"
+msgstr ""
+
+msgid "Environments"
+msgstr ""
+
+msgid "Environments Dashboard"
+msgstr ""
+
+msgid "Environments allow you to track deployments of your application %{link_to_read_more}."
+msgstr ""
+
+msgid "Environments in %{name}"
+msgstr ""
+
+msgid "EnvironmentsDashboard|Add a project to the dashboard"
+msgstr ""
+
+msgid "EnvironmentsDashboard|Add projects"
+msgstr ""
+
+msgid "EnvironmentsDashboard|Environments Dashboard"
+msgstr ""
+
+msgid "EnvironmentsDashboard|Job: %{job}"
+msgstr ""
+
+msgid "EnvironmentsDashboard|More actions"
+msgstr ""
+
+msgid "EnvironmentsDashboard|More information"
+msgstr ""
+
+msgid "EnvironmentsDashboard|Remove"
+msgstr ""
+
+msgid "EnvironmentsDashboard|The environments dashboard provides a summary of each project's environments' status, including pipeline and alert statuses."
+msgstr ""
+
+msgid "EnvironmentsDashboard|This dashboard displays a maximum of 7 projects and 3 environments per project. %{readMoreLink}"
+msgstr ""
+
+msgid "Environments|An error occurred while canceling the auto stop, please try again"
+msgstr ""
+
+msgid "Environments|An error occurred while deleting the environment. Check if the environment stopped; if not, stop it and try again."
+msgstr ""
+
+msgid "Environments|An error occurred while fetching the environments."
+msgstr ""
+
+msgid "Environments|An error occurred while making the request."
+msgstr ""
+
+msgid "Environments|An error occurred while re-deploying the environment, please try again"
+msgstr ""
+
+msgid "Environments|An error occurred while rolling back the environment, please try again"
+msgstr ""
+
+msgid "Environments|An error occurred while stopping the environment, please try again"
+msgstr ""
+
+msgid "Environments|Are you sure you want to stop this environment?"
+msgstr ""
+
+msgid "Environments|Auto stop in"
+msgstr ""
+
+msgid "Environments|Auto stops %{auto_stop_time}"
+msgstr ""
+
+msgid "Environments|Commit"
+msgstr ""
+
+msgid "Environments|Currently showing %{fetched} results."
+msgstr ""
+
+msgid "Environments|Currently showing all results."
+msgstr ""
+
+msgid "Environments|Delete"
+msgstr ""
+
+msgid "Environments|Delete environment"
+msgstr ""
+
+msgid "Environments|Deleting the '%{environmentName}' environment cannot be undone. Do you want to delete it anyway?"
+msgstr ""
+
+msgid "Environments|Deploy to..."
+msgstr ""
+
+msgid "Environments|Deployment"
+msgstr ""
+
+msgid "Environments|Enable review app"
+msgstr ""
+
+msgid "Environments|Environment"
+msgstr ""
+
+msgid "Environments|Environments"
+msgstr ""
+
+msgid "Environments|Environments are places where code gets deployed, such as staging or production."
+msgstr ""
+
+msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
+msgstr ""
+
+msgid "Environments|Job"
+msgstr ""
+
+msgid "Environments|Learn about environments"
+msgstr ""
+
+msgid "Environments|Learn more about stopping environments"
+msgstr ""
+
+msgid "Environments|Logs from %{start} to %{end}."
+msgstr ""
+
+msgid "Environments|New environment"
+msgstr ""
+
+msgid "Environments|No deployed environments"
+msgstr ""
+
+msgid "Environments|No deployments yet"
+msgstr ""
+
+msgid "Environments|No pod selected"
+msgstr ""
+
+msgid "Environments|No pods to display"
+msgstr ""
+
+msgid "Environments|Note that this action will stop the environment, but it will %{emphasisStart}not%{emphasisEnd} have an effect on any existing deployment due to no “stop environment action†being defined in the %{ciConfigLinkStart}.gitlab-ci.yml%{ciConfigLinkEnd} file."
+msgstr ""
+
+msgid "Environments|Note that this action will stop the environment, but it will %{emphasis_start}not%{emphasis_end} have an effect on any existing deployment due to no “stop environment action†being defined in the %{ci_config_link_start}.gitlab-ci.yml%{ci_config_link_end} file."
+msgstr ""
+
+msgid "Environments|Open live environment"
+msgstr ""
+
+msgid "Environments|Pod name"
+msgstr ""
+
+msgid "Environments|Re-deploy"
+msgstr ""
+
+msgid "Environments|Re-deploy environment %{environment_name}?"
+msgstr ""
+
+msgid "Environments|Re-deploy environment %{name}?"
+msgstr ""
+
+msgid "Environments|Re-deploy to environment"
+msgstr ""
+
+msgid "Environments|Read more about environments"
+msgstr ""
+
+msgid "Environments|Rollback"
+msgstr ""
+
+msgid "Environments|Rollback environment"
+msgstr ""
+
+msgid "Environments|Rollback environment %{environment_name}?"
+msgstr ""
+
+msgid "Environments|Rollback environment %{name}?"
+msgstr ""
+
+msgid "Environments|Select environment"
+msgstr ""
+
+msgid "Environments|Select pod"
+msgstr ""
+
+msgid "Environments|Show all"
+msgstr ""
+
+msgid "Environments|Stop"
+msgstr ""
+
+msgid "Environments|Stop environment"
+msgstr ""
+
+msgid "Environments|Stopping"
+msgstr ""
+
+msgid "Environments|There was an error fetching the logs. Please try again."
+msgstr ""
+
+msgid "Environments|This action will relaunch the job for commit %{commit_id}, putting the environment in a previous version. Are you sure you want to continue?"
+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 ""
+
+msgid "Environments|This action will run the job defined by %{environment_name} for commit %{commit_id}, 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 ""
+
+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 ""
+
+msgid "Environments|Updated"
+msgstr ""
+
+msgid "Environments|You don't have any environments right now"
+msgstr ""
+
+msgid "Environments|protected"
+msgstr ""
+
+msgid "Epic"
+msgstr ""
+
+msgid "Epic cannot be found."
+msgstr ""
+
+msgid "Epic events"
+msgstr ""
+
+msgid "Epics"
+msgstr ""
+
+msgid "Epics Roadmap"
+msgstr ""
+
+msgid "Epics and Issues"
+msgstr ""
+
+msgid "Epics let you manage your portfolio of projects more efficiently and with less effort"
+msgstr ""
+
+msgid "Epics, Issues, and Merge Requests"
+msgstr ""
+
+msgid "Epics|Add a new epic"
+msgstr ""
+
+msgid "Epics|Add an existing epic"
+msgstr ""
+
+msgid "Epics|An error occurred while saving the %{epicDateType} date"
+msgstr ""
+
+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 ""
+
+msgid "Epics|How can I solve this?"
+msgstr ""
+
+msgid "Epics|More information"
+msgstr ""
+
+msgid "Epics|Remove epic"
+msgstr ""
+
+msgid "Epics|Remove issue"
+msgstr ""
+
+msgid "Epics|Show more"
+msgstr ""
+
+msgid "Epics|Something went wrong while assigning issue to epic."
+msgstr ""
+
+msgid "Epics|Something went wrong while creating child epics."
+msgstr ""
+
+msgid "Epics|Something went wrong while creating issue."
+msgstr ""
+
+msgid "Epics|Something went wrong while fetching child epics."
+msgstr ""
+
+msgid "Epics|Something went wrong while fetching group epics."
+msgstr ""
+
+msgid "Epics|Something went wrong while moving item."
+msgstr ""
+
+msgid "Epics|Something went wrong while ordering item."
+msgstr ""
+
+msgid "Epics|Something went wrong while removing issue from epic."
+msgstr ""
+
+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 ""
+
+msgid "Epics|This will also remove any descendents of %{bStart}%{targetEpicTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}. Are you sure?"
+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 ""
+
+msgid "Epics|due"
+msgstr ""
+
+msgid "Epics|start"
+msgstr ""
+
+msgid "Error"
+msgstr ""
+
+msgid "Error Details"
+msgstr ""
+
+msgid "Error Tracking"
+msgstr ""
+
+msgid "Error creating epic"
+msgstr ""
+
+msgid "Error creating label."
+msgstr ""
+
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
+msgstr ""
+
+msgid "Error deleting project. Check logs for error details."
+msgstr ""
+
+msgid "Error fetching diverging counts for branches. Please try again."
+msgstr ""
+
+msgid "Error fetching forked projects. Please try again."
+msgstr ""
+
+msgid "Error fetching labels."
+msgstr ""
+
+msgid "Error fetching network graph."
+msgstr ""
+
+msgid "Error fetching payload data."
+msgstr ""
+
+msgid "Error fetching projects"
+msgstr ""
+
+msgid "Error fetching refs"
+msgstr ""
+
+msgid "Error fetching the dependency list. Please check your network connection and try again."
+msgstr ""
+
+msgid "Error loading branch data. Please try again."
+msgstr ""
+
+msgid "Error loading branches."
+msgstr ""
+
+msgid "Error loading burndown chart data"
+msgstr ""
+
+msgid "Error loading countries data."
+msgstr ""
+
+msgid "Error loading file viewer."
+msgstr ""
+
+msgid "Error loading last commit."
+msgstr ""
+
+msgid "Error loading markdown preview"
+msgstr ""
+
+msgid "Error loading merge requests."
+msgstr ""
+
+msgid "Error loading milestone tab"
+msgstr ""
+
+msgid "Error loading project data. Please try again."
+msgstr ""
+
+msgid "Error loading template types."
+msgstr ""
+
+msgid "Error loading template."
+msgstr ""
+
+msgid "Error loading viewer"
+msgstr ""
+
+msgid "Error occurred when fetching sidebar data"
+msgstr ""
+
+msgid "Error occurred when saving assignees"
+msgstr ""
+
+msgid "Error occurred when toggling the notification subscription"
+msgstr ""
+
+msgid "Error occurred while updating the issue status"
+msgstr ""
+
+msgid "Error occurred while updating the issue weight"
+msgstr ""
+
+msgid "Error occurred. A blocked user cannot be deactivated"
+msgstr ""
+
+msgid "Error occurred. A blocked user must be unblocked to be activated"
+msgstr ""
+
+msgid "Error occurred. User was not blocked"
+msgstr ""
+
+msgid "Error occurred. User was not confirmed"
+msgstr ""
+
+msgid "Error occurred. User was not unblocked"
+msgstr ""
+
+msgid "Error occurred. User was not unlocked"
+msgstr ""
+
+msgid "Error rendering markdown preview"
+msgstr ""
+
+msgid "Error saving label update."
+msgstr ""
+
+msgid "Error setting up editor. Please try again."
+msgstr ""
+
+msgid "Error updating %{issuableType}"
+msgstr ""
+
+msgid "Error updating status for all to-do items."
+msgstr ""
+
+msgid "Error updating status of to-do item."
+msgstr ""
+
+msgid "Error updating the snippet"
+msgstr ""
+
+msgid "Error uploading file"
+msgstr ""
+
+msgid "Error uploading file: %{stripped}"
+msgstr ""
+
+msgid "Error while loading the merge request. Please try again."
+msgstr ""
+
+msgid "Error while loading the project data. Please try again."
+msgstr ""
+
+msgid "Error while migrating %{upload_id}: %{error_message}"
+msgstr ""
+
+msgid "Error with Akismet. Please check the logs for more info."
+msgstr ""
+
+msgid "ErrorTracking|Active"
+msgstr ""
+
+msgid "ErrorTracking|After adding your Auth Token, use the 'Connect' button to load projects"
+msgstr ""
+
+msgid "ErrorTracking|Auth Token"
+msgstr ""
+
+msgid "ErrorTracking|Click 'Connect' to re-establish the connection to Sentry and activate the dropdown."
+msgstr ""
+
+msgid "ErrorTracking|Connection has failed. Re-check Auth Token and try again."
+msgstr ""
+
+msgid "ErrorTracking|If you self-host Sentry, enter the full URL of your Sentry instance. If you're using Sentry's hosted solution, enter https://sentry.io"
+msgstr ""
+
+msgid "ErrorTracking|No projects available"
+msgstr ""
+
+msgid "ErrorTracking|Select project"
+msgstr ""
+
+msgid "ErrorTracking|To enable project selection, enter a valid Auth Token"
+msgstr ""
+
+msgid "Errors"
+msgstr ""
+
+msgid "Errors:"
+msgstr ""
+
+msgid "Estimate"
+msgstr ""
+
+msgid "Estimated"
+msgstr ""
+
+msgid "EventFilterBy|Filter by all"
+msgstr ""
+
+msgid "EventFilterBy|Filter by comments"
+msgstr ""
+
+msgid "EventFilterBy|Filter by epic events"
+msgstr ""
+
+msgid "EventFilterBy|Filter by issue events"
+msgstr ""
+
+msgid "EventFilterBy|Filter by merge events"
+msgstr ""
+
+msgid "EventFilterBy|Filter by push events"
+msgstr ""
+
+msgid "EventFilterBy|Filter by team"
+msgstr ""
+
+msgid "EventFilterBy|Filter by wiki"
+msgstr ""
+
+msgid "Events"
+msgstr ""
+
+msgid "Events in %{group_name}"
+msgstr ""
+
+msgid "Events in %{project_path}"
+msgstr ""
+
+msgid "Every %{action} attempt has failed: %{job_error_message}. Please try again."
+msgstr ""
+
+msgid "Every day"
+msgstr ""
+
+msgid "Every day (at %{time})"
+msgstr ""
+
+msgid "Every month"
+msgstr ""
+
+msgid "Every month (Day %{day} at %{time})"
+msgstr ""
+
+msgid "Every three months"
+msgstr ""
+
+msgid "Every two weeks"
+msgstr ""
+
+msgid "Every week"
+msgstr ""
+
+msgid "Every week (%{weekday} at %{time})"
+msgstr ""
+
+msgid "Everyone"
+msgstr ""
+
+msgid "Everyone With Access"
+msgstr ""
+
+msgid "Everyone can contribute"
+msgstr ""
+
+msgid "Everything on your to-do list is marked as done."
+msgstr ""
+
+msgid "Everything you need to create a GitLab Pages site using Gatsby."
+msgstr ""
+
+msgid "Everything you need to create a GitLab Pages site using GitBook."
+msgstr ""
+
+msgid "Everything you need to create a GitLab Pages site using Hexo."
+msgstr ""
+
+msgid "Everything you need to create a GitLab Pages site using Hugo."
+msgstr ""
+
+msgid "Everything you need to create a GitLab Pages site using Jekyll."
+msgstr ""
+
+msgid "Everything you need to create a GitLab Pages site using plain HTML."
+msgstr ""
+
+msgid "Evidence collection"
+msgstr ""
+
+msgid "Exactly one of %{attributes} is required"
+msgstr ""
+
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
+msgid "Example: @sub\\.company\\.com$"
+msgstr ""
+
+msgid "Example: Usage = single query. (Requested) / (Capacity) = multiple queries combined into a formula."
+msgstr ""
+
+msgid "Except policy:"
+msgstr ""
+
+msgid "Excluding merge commits. Limited to %{limit} commits."
+msgstr ""
+
+msgid "Excluding merge commits. Limited to 6,000 commits."
+msgstr ""
+
+msgid "Existing members and groups"
+msgstr ""
+
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
+msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
+msgstr ""
+
+msgid "Existing shares"
+msgstr ""
+
+msgid "Existing sign in methods may be removed"
+msgstr ""
+
+msgid "Expand"
+msgstr ""
+
+msgid "Expand all"
+msgstr ""
+
+msgid "Expand approvers"
+msgstr ""
+
+msgid "Expand child epics"
+msgstr ""
+
+msgid "Expand down"
+msgstr ""
+
+msgid "Expand dropdown"
+msgstr ""
+
+msgid "Expand sidebar"
+msgstr ""
+
+msgid "Expand up"
+msgstr ""
+
+msgid "Experienced"
+msgstr ""
+
+msgid "Expiration"
+msgstr ""
+
+msgid "Expiration date"
+msgstr ""
+
+msgid "Expiration policy for the Container Registry is a perfect solution for keeping the Registry space down while still enjoying the full power of GitLab CI/CD."
+msgstr ""
+
+msgid "Expired"
+msgstr ""
+
+msgid "Expired %{expiredOn}"
+msgstr ""
+
+msgid "Expired:"
+msgstr ""
+
+msgid "Expires"
+msgstr ""
+
+msgid "Expires at"
+msgstr ""
+
+msgid "Expires in %{expires_at}"
+msgstr ""
+
+msgid "Expires on"
+msgstr ""
+
+msgid "Expires:"
+msgstr ""
+
+msgid "Explain the problem. If appropriate, provide a link to the relevant issue or comment."
+msgstr ""
+
+msgid "Explore"
+msgstr ""
+
+msgid "Explore GitLab"
+msgstr ""
+
+msgid "Explore Groups"
+msgstr ""
+
+msgid "Explore groups"
+msgstr ""
+
+msgid "Explore projects"
+msgstr ""
+
+msgid "Explore public groups"
+msgstr ""
+
+msgid "Export as CSV"
+msgstr ""
+
+msgid "Export group"
+msgstr ""
+
+msgid "Export issues"
+msgstr ""
+
+msgid "Export project"
+msgstr ""
+
+msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgstr ""
+
+msgid "Export this project with all its related data in order to move your project to a new GitLab instance. Once the export is finished, you can import the file from the \"New Project\" page."
+msgstr ""
+
+msgid "Export variable to pipelines running on protected branches and tags only."
+msgstr ""
+
+msgid "External Classification Policy Authorization"
+msgstr ""
+
+msgid "External ID"
+msgstr ""
+
+msgid "External URL"
+msgstr ""
+
+msgid "External Wiki"
+msgstr ""
+
+msgid "External authentication"
+msgstr ""
+
+msgid "External authorization denied access to this project"
+msgstr ""
+
+msgid "External authorization request timeout"
+msgstr ""
+
+msgid "External storage URL"
+msgstr ""
+
+msgid "External storage authentication token"
+msgstr ""
+
+msgid "ExternalAuthorizationService|Classification label"
+msgstr ""
+
+msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
+msgstr ""
+
+msgid "ExternalWikiService|External Wiki"
+msgstr ""
+
+msgid "ExternalWikiService|Replaces the link to the internal wiki with a link to an external wiki."
+msgstr ""
+
+msgid "ExternalWikiService|The URL of the external Wiki"
+msgstr ""
+
+msgid "Facebook"
+msgstr ""
+
+msgid "Failed"
+msgstr ""
+
+msgid "Failed Jobs"
+msgstr ""
+
+msgid "Failed to add a Zoom meeting"
+msgstr ""
+
+msgid "Failed to apply commands."
+msgstr ""
+
+msgid "Failed to assign a user because no user was found."
+msgstr ""
+
+msgid "Failed to cancel auto stop because failed to update the environment."
+msgstr ""
+
+msgid "Failed to cancel auto stop because the environment is not set as auto stop."
+msgstr ""
+
+msgid "Failed to cancel auto stop because you do not have permission to update the environment."
+msgstr ""
+
+msgid "Failed to change the owner"
+msgstr ""
+
+msgid "Failed to check related branches."
+msgstr ""
+
+msgid "Failed to create Merge Request. Please try again."
+msgstr ""
+
+msgid "Failed to create a branch for this issue. Please try again."
+msgstr ""
+
+msgid "Failed to create import label for jira import."
+msgstr ""
+
+msgid "Failed to create repository"
+msgstr ""
+
+msgid "Failed to create resources"
+msgstr ""
+
+msgid "Failed to create wiki"
+msgstr ""
+
+msgid "Failed to delete board. Please try again."
+msgstr ""
+
+msgid "Failed to deploy to"
+msgstr ""
+
+msgid "Failed to enqueue the rebase operation, possibly due to a long-lived transaction. Try again later."
+msgstr ""
+
+msgid "Failed to find import label for Jira import."
+msgstr ""
+
+msgid "Failed to get ref."
+msgstr ""
+
+msgid "Failed to install."
+msgstr ""
+
+msgid "Failed to load emoji list."
+msgstr ""
+
+msgid "Failed to load error details from Sentry."
+msgstr ""
+
+msgid "Failed to load errors from Sentry. Error message: %{errorMessage}"
+msgstr ""
+
+msgid "Failed to load group activity metrics. Please try again."
+msgstr ""
+
+msgid "Failed to load groups & users."
+msgstr ""
+
+msgid "Failed to load labels. Please try again."
+msgstr ""
+
+msgid "Failed to load milestones. Please try again."
+msgstr ""
+
+msgid "Failed to load related branches"
+msgstr ""
+
+msgid "Failed to load stacktrace."
+msgstr ""
+
+msgid "Failed to mark this issue as a duplicate because referenced issue was not found."
+msgstr ""
+
+msgid "Failed to move this issue because label was not found."
+msgstr ""
+
+msgid "Failed to move this issue because only a single label can be provided."
+msgstr ""
+
+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 ""
+
+msgid "Failed to protect the branch"
+msgstr ""
+
+msgid "Failed to protect the environment"
+msgstr ""
+
+msgid "Failed to publish issue on status page."
+msgstr ""
+
+msgid "Failed to remove a Zoom meeting"
+msgstr ""
+
+msgid "Failed to remove issue from board, please try again."
+msgstr ""
+
+msgid "Failed to remove mirror."
+msgstr ""
+
+msgid "Failed to remove the pipeline schedule"
+msgstr ""
+
+msgid "Failed to remove user identity."
+msgstr ""
+
+msgid "Failed to remove user key."
+msgstr ""
+
+msgid "Failed to reset key. Please try again."
+msgstr ""
+
+msgid "Failed to save merge conflicts resolutions. Please try again!"
+msgstr ""
+
+msgid "Failed to save new settings"
+msgstr ""
+
+msgid "Failed to save preferences (%{error_message})."
+msgstr ""
+
+msgid "Failed to save preferences."
+msgstr ""
+
+msgid "Failed to set due date because the date format is invalid."
+msgstr ""
+
+msgid "Failed to signing using smartcard authentication"
+msgstr ""
+
+msgid "Failed to update branch!"
+msgstr ""
+
+msgid "Failed to update environment!"
+msgstr ""
+
+msgid "Failed to update issue status"
+msgstr ""
+
+msgid "Failed to update issues, please try again."
+msgstr ""
+
+msgid "Failed to update tag!"
+msgstr ""
+
+msgid "Failed to update."
+msgstr ""
+
+msgid "Failed to upgrade."
+msgstr ""
+
+msgid "Failed to upload object map file"
+msgstr ""
+
+msgid "Failed to verify domain ownership"
+msgstr ""
+
+msgid "Failure"
+msgstr ""
+
+msgid "False positive"
+msgstr ""
+
+msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
+msgstr ""
+
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
+msgstr ""
+
+msgid "Fast-forward merge without a merge commit"
+msgstr ""
+
+msgid "Faster as it re-uses the project workspace (falling back to clone if it doesn't exist)"
+msgstr ""
+
+msgid "Faster releases. Better code. Less pain."
+msgstr ""
+
+msgid "Favicon was successfully removed."
+msgstr ""
+
+msgid "Feature Flags"
+msgstr ""
+
+msgid "Feature flag was not removed."
+msgstr ""
+
+msgid "Feature flag was successfully removed."
+msgstr ""
+
+msgid "FeatureFlags|* (All Environments)"
+msgstr ""
+
+msgid "FeatureFlags|* (All environments)"
+msgstr ""
+
+msgid "FeatureFlags|API URL"
+msgstr ""
+
+msgid "FeatureFlags|Active"
+msgstr ""
+
+msgid "FeatureFlags|Add strategy"
+msgstr ""
+
+msgid "FeatureFlags|All users"
+msgstr ""
+
+msgid "FeatureFlags|Configure"
+msgstr ""
+
+msgid "FeatureFlags|Configure feature flags"
+msgstr ""
+
+msgid "FeatureFlags|Create feature flag"
+msgstr ""
+
+msgid "FeatureFlags|Delete %{name}?"
+msgstr ""
+
+msgid "FeatureFlags|Delete feature flag"
+msgstr ""
+
+msgid "FeatureFlags|Description"
+msgstr ""
+
+msgid "FeatureFlags|Edit Feature Flag"
+msgstr ""
+
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
+msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
+msgstr ""
+
+msgid "FeatureFlags|Environment Spec"
+msgstr ""
+
+msgid "FeatureFlags|Environment Specs"
+msgstr ""
+
+msgid "FeatureFlags|Feature Flag"
+msgstr ""
+
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
+msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
+msgstr ""
+
+msgid "FeatureFlags|Feature Flag has no strategies"
+msgstr ""
+
+msgid "FeatureFlags|Feature Flags"
+msgstr ""
+
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
+msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
+msgstr ""
+
+msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
+msgstr ""
+
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
+msgid "FeatureFlags|Get started with feature flags"
+msgstr ""
+
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
+msgid "FeatureFlags|ID"
+msgstr ""
+
+msgid "FeatureFlags|Inactive"
+msgstr ""
+
+msgid "FeatureFlags|Inactive flag for %{scope}"
+msgstr ""
+
+msgid "FeatureFlags|Include additional user IDs"
+msgstr ""
+
+msgid "FeatureFlags|Install a %{docs_link_anchored_start}compatible client library%{docs_link_anchored_end} and specify the API URL, application name, and instance ID during the configuration setup. %{docs_link_start}More Information%{docs_link_end}"
+msgstr ""
+
+msgid "FeatureFlags|Instance ID"
+msgstr ""
+
+msgid "FeatureFlags|List details"
+msgstr ""
+
+msgid "FeatureFlags|Loading feature flags"
+msgstr ""
+
+msgid "FeatureFlags|More information"
+msgstr ""
+
+msgid "FeatureFlags|Name"
+msgstr ""
+
+msgid "FeatureFlags|New"
+msgstr ""
+
+msgid "FeatureFlags|New Feature Flag"
+msgstr ""
+
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|New feature flag"
+msgstr ""
+
+msgid "FeatureFlags|New list"
+msgstr ""
+
+msgid "FeatureFlags|Percent rollout (logged in users)"
+msgstr ""
+
+msgid "FeatureFlags|Percent rollout must be a whole number between 0 and 100"
+msgstr ""
+
+msgid "FeatureFlags|Protected"
+msgstr ""
+
+msgid "FeatureFlags|Remove"
+msgstr ""
+
+msgid "FeatureFlags|Rollout Percentage"
+msgstr ""
+
+msgid "FeatureFlags|Rollout Strategy"
+msgstr ""
+
+msgid "FeatureFlags|Status"
+msgstr ""
+
+msgid "FeatureFlags|Strategies"
+msgstr ""
+
+msgid "FeatureFlags|Target environments"
+msgstr ""
+
+msgid "FeatureFlags|There are no active feature flags"
+msgstr ""
+
+msgid "FeatureFlags|There are no inactive feature flags"
+msgstr ""
+
+msgid "FeatureFlags|There was an error fetching the feature flags."
+msgstr ""
+
+msgid "FeatureFlags|Try again in a few moments or contact your support team."
+msgstr ""
+
+msgid "FeatureFlags|User IDs"
+msgstr ""
+
+msgid "FeatureFlag|Delete strategy"
+msgstr ""
+
+msgid "FeatureFlag|Percentage"
+msgstr ""
+
+msgid "FeatureFlag|Type"
+msgstr ""
+
+msgid "FeatureFlag|User IDs"
+msgstr ""
+
+msgid "Feb"
+msgstr ""
+
+msgid "February"
+msgstr ""
+
+msgid "Fetching incoming email"
+msgstr ""
+
+msgid "Fetching licenses failed."
+msgstr ""
+
+msgid "Fetching licenses failed. The request endpoint was not found."
+msgstr ""
+
+msgid "Fetching licenses failed. You are not permitted to perform this action."
+msgstr ""
+
+msgid "File"
+msgstr ""
+
+msgid "File Hooks"
+msgstr ""
+
+msgid "File Hooks (%{count})"
+msgstr ""
+
+msgid "File added"
+msgstr ""
+
+msgid "File browser"
+msgstr ""
+
+msgid "File deleted"
+msgstr ""
+
+msgid "File format is no longer supported"
+msgstr ""
+
+msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
+msgstr ""
+
+msgid "File mode changed from %{a_mode} to %{b_mode}"
+msgstr ""
+
+msgid "File moved"
+msgstr ""
+
+msgid "File name"
+msgstr ""
+
+msgid "File renamed with no changes."
+msgstr ""
+
+msgid "File sync capacity"
+msgstr ""
+
+msgid "File templates"
+msgstr ""
+
+msgid "File upload error."
+msgstr ""
+
+msgid "Files"
+msgstr ""
+
+msgid "Files breadcrumb"
+msgstr ""
+
+msgid "Files, directories, and submodules in the path %{path} for commit reference %{ref}"
+msgstr ""
+
+msgid "Fill in the fields below, turn on <strong>%{enable_label}</strong>, and press <strong>%{save_changes}</strong>"
+msgstr ""
+
+msgid "Filter"
+msgstr ""
+
+msgid "Filter by %{issuable_type} that are currently closed."
+msgstr ""
+
+msgid "Filter by %{issuable_type} that are currently opened."
+msgstr ""
+
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
+msgid "Filter by commit message"
+msgstr ""
+
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
+msgid "Filter by milestone name"
+msgstr ""
+
+msgid "Filter by name"
+msgstr ""
+
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
+msgid "Filter by status"
+msgstr ""
+
+msgid "Filter by two-factor authentication"
+msgstr ""
+
+msgid "Filter by user"
+msgstr ""
+
+msgid "Filter pipelines"
+msgstr ""
+
+msgid "Filter projects"
+msgstr ""
+
+msgid "Filter results"
+msgstr ""
+
+msgid "Filter results by group"
+msgstr ""
+
+msgid "Filter results by project"
+msgstr ""
+
+msgid "Filter results..."
+msgstr ""
+
+msgid "Filter your projects by name"
+msgstr ""
+
+msgid "Filter..."
+msgstr ""
+
+msgid "Find by path"
+msgstr ""
+
+msgid "Find existing members by name"
+msgstr ""
+
+msgid "Find file"
+msgstr ""
+
+msgid "Find the downloaded ZIP file and decompress it."
+msgstr ""
+
+msgid "Find the newly extracted <code>Takeout/Google Code Project Hosting/GoogleCodeProjectHosting.json</code> file."
+msgstr ""
+
+msgid "Fingerprint"
+msgstr ""
+
+msgid "Fingerprints"
+msgstr ""
+
+msgid "Finish editing this message first!"
+msgstr ""
+
+msgid "Finish review"
+msgstr ""
+
+msgid "Finish setting up your dedicated account for <strong>%{group_name}</strong>."
+msgstr ""
+
+msgid "Finished"
+msgstr ""
+
+msgid "First Name is too long (maximum is %{max_length} characters)."
+msgstr ""
+
+msgid "First Seen"
+msgstr ""
+
+msgid "First day of the week"
+msgstr ""
+
+msgid "First name"
+msgstr ""
+
+msgid "First seen"
+msgstr ""
+
+msgid "Fixed date"
+msgstr ""
+
+msgid "Fixed due date"
+msgstr ""
+
+msgid "Fixed start date"
+msgstr ""
+
+msgid "Fixed:"
+msgstr ""
+
+msgid "Flags"
+msgstr ""
+
+msgid "FlowdockService|Flowdock Git source token"
+msgstr ""
+
+msgid "FlowdockService|Flowdock is a collaboration web app for technical teams."
+msgstr ""
+
+msgid "FogBugz Email"
+msgstr ""
+
+msgid "FogBugz Import"
+msgstr ""
+
+msgid "FogBugz Password"
+msgstr ""
+
+msgid "FogBugz URL"
+msgstr ""
+
+msgid "FogBugz import"
+msgstr ""
+
+msgid "Folder/%{name}"
+msgstr ""
+
+msgid "Follow the steps below to export your Google Code project data."
+msgstr ""
+
+msgid "Font Color"
+msgstr ""
+
+msgid "Footer message"
+msgstr ""
+
+msgid "For each Jira issue successfully imported, we'll create a new GitLab issue with the following data:"
+msgstr ""
+
+msgid "For internal projects, any logged in user can view pipelines and access job details (output logs and artifacts)"
+msgstr ""
+
+msgid "For more info, read the documentation."
+msgstr ""
+
+msgid "For more information, go to the "
+msgstr ""
+
+msgid "For more information, please review %{link_start_tag}Jaeger's configuration doc%{link_end_tag}"
+msgstr ""
+
+msgid "For more information, see the File Hooks documentation."
+msgstr ""
+
+msgid "For more information, see the documentation on %{deactivating_usage_ping_link_start}deactivating the usage ping%{deactivating_usage_ping_link_end}."
+msgstr ""
+
+msgid "For more information, see the documentation on %{link_start}disabling Seat Link%{link_end}."
+msgstr ""
+
+msgid "For private projects, any member (guest or higher) can view pipelines and access job details (output logs and artifacts)"
+msgstr ""
+
+msgid "For public projects, anyone can view pipelines and access job details (output logs and artifacts)"
+msgstr ""
+
+msgid "Forgot your password?"
+msgstr ""
+
+msgid "Fork"
+msgstr ""
+
+msgid "Fork Error!"
+msgstr ""
+
+msgid "Fork project"
+msgstr ""
+
+msgid "Fork project?"
+msgstr ""
+
+msgid "ForkedFromProjectPath|Forked from"
+msgstr ""
+
+msgid "ForkedFromProjectPath|Forked from an inaccessible project"
+msgstr ""
+
+msgid "Forking in progress"
+msgstr ""
+
+msgid "Forks"
+msgstr ""
+
+msgid "Format"
+msgstr ""
+
+msgid "Format: %{dateFormat}"
+msgstr ""
+
+msgid "Forward external support email address to"
+msgstr ""
+
+msgid "Found errors in your %{gitlab_ci_yml}:"
+msgstr ""
+
+msgid "Found errors in your .gitlab-ci.yml:"
+msgstr ""
+
+msgid "Free Trial"
+msgstr ""
+
+msgid "Free Trial of GitLab.com Gold"
+msgstr ""
+
+msgid "Frequency"
+msgstr ""
+
+msgid "Friday"
+msgstr ""
+
+msgid "From"
+msgstr ""
+
+msgid "From %{providerTitle}"
+msgstr ""
+
+msgid "From <code>%{source_title}</code> into"
+msgstr ""
+
+msgid "From Bitbucket"
+msgstr ""
+
+msgid "From Bitbucket Server"
+msgstr ""
+
+msgid "From FogBugz"
+msgstr ""
+
+msgid "From GitLab.com"
+msgstr ""
+
+msgid "From Google Code"
+msgstr ""
+
+msgid "From issue creation until deploy to production"
+msgstr ""
+
+msgid "From merge request merge until deploy to production"
+msgstr ""
+
+msgid "From the Kubernetes cluster details view, install Runner from the applications list"
+msgstr ""
+
+msgid "Full name"
+msgstr ""
+
+msgid "GPG Key ID:"
+msgstr ""
+
+msgid "GPG Keys"
+msgstr ""
+
+msgid "GPG keys allow you to verify signed commits."
+msgstr ""
+
+msgid "GPG signature (loading...)"
+msgstr ""
+
+msgid "General"
+msgstr ""
+
+msgid "General Settings"
+msgstr ""
+
+msgid "General pipelines"
+msgstr ""
+
+msgid "Generate a default set of labels"
+msgstr ""
+
+msgid "Generate key"
+msgstr ""
+
+msgid "Generate new export"
+msgstr ""
+
+msgid "Geo"
+msgstr ""
+
+msgid "Geo Nodes"
+msgstr ""
+
+msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
+msgstr ""
+
+msgid "Geo Replication"
+msgstr ""
+
+msgid "Geo Settings"
+msgstr ""
+
+msgid "Geo allows you to replicate your GitLab instance to other geographical locations."
+msgstr ""
+
+msgid "GeoNodeStatusEvent|%{timeAgoStr} (%{pendingEvents} events)"
+msgstr ""
+
+msgid "GeoNodeSyncStatus|Node is failing or broken."
+msgstr ""
+
+msgid "GeoNodeSyncStatus|Node is slow, overloaded, or it just recovered after an outage."
+msgstr ""
+
+msgid "GeoNodes|Attachments"
+msgstr ""
+
+msgid "GeoNodes|Checksummed"
+msgstr ""
+
+msgid "GeoNodes|Consult Geo troubleshooting information"
+msgstr ""
+
+msgid "GeoNodes|Container repositories"
+msgstr ""
+
+msgid "GeoNodes|Data replication lag"
+msgstr ""
+
+msgid "GeoNodes|Design repositories"
+msgstr ""
+
+msgid "GeoNodes|Does not match the primary storage configuration"
+msgstr ""
+
+msgid "GeoNodes|Failed"
+msgstr ""
+
+msgid "GeoNodes|Full"
+msgstr ""
+
+msgid "GeoNodes|GitLab version"
+msgstr ""
+
+msgid "GeoNodes|GitLab version does not match the primary node version"
+msgstr ""
+
+msgid "GeoNodes|Health status"
+msgstr ""
+
+msgid "GeoNodes|Internal URL"
+msgstr ""
+
+msgid "GeoNodes|Job artifacts"
+msgstr ""
+
+msgid "GeoNodes|LFS objects"
+msgstr ""
+
+msgid "GeoNodes|Last event ID processed by cursor"
+msgstr ""
+
+msgid "GeoNodes|Last event ID seen from primary"
+msgstr ""
+
+msgid "GeoNodes|Learn more about Geo node statuses"
+msgstr ""
+
+msgid "GeoNodes|Loading nodes"
+msgstr ""
+
+msgid "GeoNodes|New node"
+msgstr ""
+
+msgid "GeoNodes|Node Authentication was successfully repaired."
+msgstr ""
+
+msgid "GeoNodes|Node URL"
+msgstr ""
+
+msgid "GeoNodes|Node was successfully removed."
+msgstr ""
+
+msgid "GeoNodes|Node's status was updated %{timeAgo}."
+msgstr ""
+
+msgid "GeoNodes|Not checksummed"
+msgstr ""
+
+msgid "GeoNodes|Pausing replication stops the sync process. Are you sure?"
+msgstr ""
+
+msgid "GeoNodes|Removing a Geo primary node stops the synchronization to all nodes. Are you sure?"
+msgstr ""
+
+msgid "GeoNodes|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgstr ""
+
+msgid "GeoNodes|Replicated data is verified with the %{nodeText} using checksums"
+msgstr ""
+
+msgid "GeoNodes|Replication slot WAL"
+msgstr ""
+
+msgid "GeoNodes|Replication slots"
+msgstr ""
+
+msgid "GeoNodes|Repositories"
+msgstr ""
+
+msgid "GeoNodes|Repository checksum progress"
+msgstr ""
+
+msgid "GeoNodes|Repository verification progress"
+msgstr ""
+
+msgid "GeoNodes|Selective (%{syncLabel})"
+msgstr ""
+
+msgid "GeoNodes|Selective synchronization"
+msgstr ""
+
+msgid "GeoNodes|Something went wrong while changing node status"
+msgstr ""
+
+msgid "GeoNodes|Something went wrong while fetching nodes"
+msgstr ""
+
+msgid "GeoNodes|Something went wrong while removing node"
+msgstr ""
+
+msgid "GeoNodes|Something went wrong while repairing node"
+msgstr ""
+
+msgid "GeoNodes|Storage config"
+msgstr ""
+
+msgid "GeoNodes|Sync settings"
+msgstr ""
+
+msgid "GeoNodes|Unused slots"
+msgstr ""
+
+msgid "GeoNodes|Unverified"
+msgstr ""
+
+msgid "GeoNodes|Updated %{timeAgo}"
+msgstr ""
+
+msgid "GeoNodes|Used slots"
+msgstr ""
+
+msgid "GeoNodes|Verified"
+msgstr ""
+
+msgid "GeoNodes|Wiki checksum progress"
+msgstr ""
+
+msgid "GeoNodes|Wiki verification progress"
+msgstr ""
+
+msgid "GeoNodes|Wikis"
+msgstr ""
+
+msgid "GeoNodes|With %{geo} you can install a special read-only and replicated instance anywhere. Before you add nodes, follow the %{instructions} in the exact order they appear."
+msgstr ""
+
+msgid "GeoNodes|You have configured Geo nodes using an insecure HTTP connection. We recommend the use of HTTPS."
+msgstr ""
+
+msgid "GeoNodes|primary node"
+msgstr ""
+
+msgid "GeoNodes|secondary nodes"
+msgstr ""
+
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
+msgid "Geo|%{name} is scheduled for forced re-download"
+msgstr ""
+
+msgid "Geo|%{name} is scheduled for re-sync"
+msgstr ""
+
+msgid "Geo|%{name} is scheduled for re-verify"
+msgstr ""
+
+msgid "Geo|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 ""
+
+msgid "Geo|All %{replicable_name}"
+msgstr ""
+
+msgid "Geo|All projects"
+msgstr ""
+
+msgid "Geo|All projects are being scheduled for resync"
+msgstr ""
+
+msgid "Geo|All projects are being scheduled for reverify"
+msgstr ""
+
+msgid "Geo|Could not remove tracking entry for an existing project."
+msgstr ""
+
+msgid "Geo|Could not remove tracking entry for an existing upload."
+msgstr ""
+
+msgid "Geo|Failed"
+msgstr ""
+
+msgid "Geo|Filter by status"
+msgstr ""
+
+msgid "Geo|Geo Status"
+msgstr ""
+
+msgid "Geo|In progress"
+msgstr ""
+
+msgid "Geo|In sync"
+msgstr ""
+
+msgid "Geo|Last repository check run"
+msgstr ""
+
+msgid "Geo|Last successful sync"
+msgstr ""
+
+msgid "Geo|Last sync attempt"
+msgstr ""
+
+msgid "Geo|Last time verified"
+msgstr ""
+
+msgid "Geo|Never"
+msgstr ""
+
+msgid "Geo|Next sync scheduled at"
+msgstr ""
+
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
+msgid "Geo|Not synced yet"
+msgstr ""
+
+msgid "Geo|Pending synchronization"
+msgstr ""
+
+msgid "Geo|Pending verification"
+msgstr ""
+
+msgid "Geo|Please refer to Geo Troubleshooting."
+msgstr ""
+
+msgid "Geo|Project"
+msgstr ""
+
+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 ""
+
+msgid "Geo|Projects in certain groups"
+msgstr ""
+
+msgid "Geo|Projects in certain storage shards"
+msgstr ""
+
+msgid "Geo|Redownload"
+msgstr ""
+
+msgid "Geo|Remove"
+msgstr ""
+
+msgid "Geo|Remove entry"
+msgstr ""
+
+msgid "Geo|Remove tracking database entry"
+msgstr ""
+
+msgid "Geo|Resync"
+msgstr ""
+
+msgid "Geo|Resync all"
+msgstr ""
+
+msgid "Geo|Retry count"
+msgstr ""
+
+msgid "Geo|Reverify"
+msgstr ""
+
+msgid "Geo|Reverify all"
+msgstr ""
+
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
+msgid "Geo|Status"
+msgstr ""
+
+msgid "Geo|Synced"
+msgstr ""
+
+msgid "Geo|Synced at"
+msgstr ""
+
+msgid "Geo|Synchronization failed - %{error}"
+msgstr ""
+
+msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgstr ""
+
+msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgstr ""
+
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
+msgid "Geo|Tracking database entry will be removed. Are you sure?"
+msgstr ""
+
+msgid "Geo|Tracking entry for project (%{project_id}) was successfully removed."
+msgstr ""
+
+msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
+msgstr ""
+
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
+msgid "Geo|Unknown state"
+msgstr ""
+
+msgid "Geo|Verification failed - %{error}"
+msgstr ""
+
+msgid "Geo|Waiting for scheduler"
+msgstr ""
+
+msgid "Geo|You are on a secondary, <b>read-only</b> Geo node. If you want to make changes, you must visit this page on the %{primary_node}."
+msgstr ""
+
+msgid "Geo|You are on a secondary, <b>read-only</b> Geo node. You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
+msgstr ""
+
+msgid "Geo|misconfigured"
+msgstr ""
+
+msgid "Geo|primary"
+msgstr ""
+
+msgid "Geo|secondary"
+msgstr ""
+
+msgid "Get a free instance review"
+msgstr ""
+
+msgid "Get started"
+msgstr ""
+
+msgid "Get started with error tracking"
+msgstr ""
+
+msgid "Get started with performance monitoring"
+msgstr ""
+
+msgid "Get started!"
+msgstr ""
+
+msgid "Getting started with releases"
+msgstr ""
+
+msgid "Git"
+msgstr ""
+
+msgid "Git LFS is not enabled on this GitLab server, contact your admin."
+msgstr ""
+
+msgid "Git LFS objects will be synced in pull mirrors if LFS is %{docs_link_start}enabled for the project%{docs_link_end}. They will <strong>not</strong> be synced in push mirrors."
+msgstr ""
+
+msgid "Git global setup"
+msgstr ""
+
+msgid "Git repository URL"
+msgstr ""
+
+msgid "Git revision"
+msgstr ""
+
+msgid "Git shallow clone"
+msgstr ""
+
+msgid "Git strategy for pipelines"
+msgstr ""
+
+msgid "Git version"
+msgstr ""
+
+msgid "GitHub API rate limit exceeded. Try again after %{reset_time}"
+msgstr ""
+
+msgid "GitHub import"
+msgstr ""
+
+msgid "GitLab / Unsubscribe"
+msgstr ""
+
+msgid "GitLab Enterprise Edition %{plan}"
+msgstr ""
+
+msgid "GitLab Group Runners can execute code for all the projects in this group."
+msgstr ""
+
+msgid "GitLab Import"
+msgstr ""
+
+msgid "GitLab Issue"
+msgstr ""
+
+msgid "GitLab Shared Runners execute code of different projects on the same Runner unless you configure GitLab Runner Autoscale with MaxBuilds 1 (which it is on GitLab.com)."
+msgstr ""
+
+msgid "GitLab Support Bot"
+msgstr ""
+
+msgid "GitLab Team Member"
+msgstr ""
+
+msgid "GitLab User"
+msgstr ""
+
+msgid "GitLab allows you to continue using your license even if you exceed the number of seats you purchased. You will be required to pay for these seats when you renew your license."
+msgstr ""
+
+msgid "GitLab commit"
+msgstr ""
+
+msgid "GitLab for Slack"
+msgstr ""
+
+msgid "GitLab is a single application for the entire software development lifecycle. From project planning and source code management to CI/CD, monitoring, and security."
+msgstr ""
+
+msgid "GitLab is obtaining a Let's Encrypt SSL certificate for this domain. This process can take some time. Please try again later."
+msgstr ""
+
+msgid "GitLab is undergoing maintenance and is operating in a read-only mode."
+msgstr ""
+
+msgid "GitLab member or Email address"
+msgstr ""
+
+msgid "GitLab metadata URL"
+msgstr ""
+
+msgid "GitLab project export"
+msgstr ""
+
+msgid "GitLab restart is required to apply changes."
+msgstr ""
+
+msgid "GitLab single sign on URL"
+msgstr ""
+
+msgid "GitLab uses %{jaeger_link} to monitor distributed systems."
+msgstr ""
+
+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 import"
+msgstr ""
+
+msgid "GitLabPagesDomains|Retry"
+msgstr ""
+
+msgid "GitLabPages|%{domain} is not verified. To learn how to verify ownership, visit your %{link_start}domain details%{link_end}."
+msgstr ""
+
+msgid "GitLabPages|Access Control is enabled for this Pages website; only authorized users will be able to access it. To make your website publicly available, navigate to your project's %{strong_start}Settings > General > Visibility%{strong_end} and select %{strong_start}Everyone%{strong_end} in pages section. Read the %{link_start}documentation%{link_end} for more information."
+msgstr ""
+
+msgid "GitLabPages|Access pages"
+msgstr ""
+
+msgid "GitLabPages|Are you sure?"
+msgstr ""
+
+msgid "GitLabPages|Certificate: %{subject}"
+msgstr ""
+
+msgid "GitLabPages|Configure pages"
+msgstr ""
+
+msgid "GitLabPages|Domains"
+msgstr ""
+
+msgid "GitLabPages|Edit"
+msgstr ""
+
+msgid "GitLabPages|Expired"
+msgstr ""
+
+msgid "GitLabPages|Force HTTPS (requires valid certificates)"
+msgstr ""
+
+msgid "GitLabPages|GitLab Pages are disabled for this project. You can enable them on your project's %{strong_start}Settings > General > Visibility%{strong_end} page."
+msgstr ""
+
+msgid "GitLabPages|It may take up to 30 minutes before the site is available after the first deployment."
+msgstr ""
+
+msgid "GitLabPages|Learn how to upload your static site and have it served by GitLab by following the %{link_start}documentation on GitLab Pages%{link_end}."
+msgstr ""
+
+msgid "GitLabPages|Learn more."
+msgstr ""
+
+msgid "GitLabPages|Maximum size of pages (MB)"
+msgstr ""
+
+msgid "GitLabPages|New Domain"
+msgstr ""
+
+msgid "GitLabPages|Only project maintainers can remove pages"
+msgstr ""
+
+msgid "GitLabPages|Pages"
+msgstr ""
+
+msgid "GitLabPages|Remove"
+msgstr ""
+
+msgid "GitLabPages|Remove pages"
+msgstr ""
+
+msgid "GitLabPages|Removing pages will prevent them from being exposed to the outside world."
+msgstr ""
+
+msgid "GitLabPages|Save"
+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 ""
+
+msgid "GitLabPages|Support for domains and certificates is disabled. Ask your system's administrator to enable it."
+msgstr ""
+
+msgid "GitLabPages|The total size of deployed static content will be limited to this size. 0 for unlimited. Leave empty to inherit the global value."
+msgstr ""
+
+msgid "GitLabPages|Unverified"
+msgstr ""
+
+msgid "GitLabPages|Verified"
+msgstr ""
+
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with sub-subdomains. This means that if your username/groupname contains a dot it will not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages will continue to work provided you don't redirect HTTP to HTTPS."
+msgstr ""
+
+msgid "GitLabPages|With GitLab Pages you can host your static websites on GitLab. Combined with the power of GitLab CI and the help of GitLab Runner you can deploy static pages for your individual projects, your user or your group."
+msgstr ""
+
+msgid "GitLabPages|Your pages are served under:"
+msgstr ""
+
+msgid "Gitaly"
+msgstr ""
+
+msgid "Gitaly Servers"
+msgstr ""
+
+msgid "Gitaly|Address"
+msgstr ""
+
+msgid "Gitea Host URL"
+msgstr ""
+
+msgid "Gitea Import"
+msgstr ""
+
+msgid "Gitlab Pages"
+msgstr ""
+
+msgid "Given access %{time_ago}"
+msgstr ""
+
+msgid "Given epic is already related to this epic."
+msgstr ""
+
+msgid "Global Shortcuts"
+msgstr ""
+
+msgid "Global notification settings"
+msgstr ""
+
+msgid "Go Back"
+msgstr ""
+
+msgid "Go Micro is a framework for micro service development."
+msgstr ""
+
+msgid "Go back"
+msgstr ""
+
+msgid "Go back (while searching for files)"
+msgstr ""
+
+msgid "Go back to %{startTag}Open issues%{endTag} and select some issues to add to your board."
+msgstr ""
+
+msgid "Go full screen"
+msgstr ""
+
+msgid "Go to %{link_to_google_takeout}."
+msgstr ""
+
+msgid "Go to Pipelines"
+msgstr ""
+
+msgid "Go to Webhooks"
+msgstr ""
+
+msgid "Go to commits"
+msgstr ""
+
+msgid "Go to definition"
+msgstr ""
+
+msgid "Go to environments"
+msgstr ""
+
+msgid "Go to file"
+msgstr ""
+
+msgid "Go to file permalink (while viewing a file)"
+msgstr ""
+
+msgid "Go to files"
+msgstr ""
+
+msgid "Go to find file"
+msgstr ""
+
+msgid "Go to issue boards"
+msgstr ""
+
+msgid "Go to issues"
+msgstr ""
+
+msgid "Go to jobs"
+msgstr ""
+
+msgid "Go to kubernetes"
+msgstr ""
+
+msgid "Go to merge requests"
+msgstr ""
+
+msgid "Go to metrics"
+msgstr ""
+
+msgid "Go to parent"
+msgstr ""
+
+msgid "Go to project"
+msgstr ""
+
+msgid "Go to releases"
+msgstr ""
+
+msgid "Go to repository charts"
+msgstr ""
+
+msgid "Go to repository graph"
+msgstr ""
+
+msgid "Go to snippets"
+msgstr ""
+
+msgid "Go to the activity feed"
+msgstr ""
+
+msgid "Go to the milestone list"
+msgstr ""
+
+msgid "Go to the project's activity feed"
+msgstr ""
+
+msgid "Go to the project's overview page"
+msgstr ""
+
+msgid "Go to wiki"
+msgstr ""
+
+msgid "Go to your To-Do list"
+msgstr ""
+
+msgid "Go to your fork"
+msgstr ""
+
+msgid "Go to your groups"
+msgstr ""
+
+msgid "Go to your issues"
+msgstr ""
+
+msgid "Go to your merge requests"
+msgstr ""
+
+msgid "Go to your projects"
+msgstr ""
+
+msgid "Go to your snippets"
+msgstr ""
+
+msgid "Golden Tanuki"
+msgstr ""
+
+msgid "Google Cloud Platform"
+msgstr ""
+
+msgid "Google Code import"
+msgstr ""
+
+msgid "Google Takeout"
+msgstr ""
+
+msgid "Google authentication is not %{link_start}properly configured%{link_end}. Ask your GitLab administrator if you want to use this service."
+msgstr ""
+
+msgid "Got it"
+msgstr ""
+
+msgid "Got it!"
+msgstr ""
+
+msgid "Grafana URL"
+msgstr ""
+
+msgid "GrafanaIntegration|API Token"
+msgstr ""
+
+msgid "GrafanaIntegration|Active"
+msgstr ""
+
+msgid "GrafanaIntegration|Embed Grafana charts in GitLab issues."
+msgstr ""
+
+msgid "GrafanaIntegration|Enter the Grafana API Token."
+msgstr ""
+
+msgid "GrafanaIntegration|Enter the base URL of the Grafana instance."
+msgstr ""
+
+msgid "GrafanaIntegration|Grafana Authentication"
+msgstr ""
+
+msgid "GrafanaIntegration|Grafana URL"
+msgstr ""
+
+msgid "Grant access"
+msgstr ""
+
+msgid "Graph"
+msgstr ""
+
+msgid "Gravatar"
+msgstr ""
+
+msgid "Gravatar enabled"
+msgstr ""
+
+msgid "Group"
+msgstr ""
+
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
+msgid "Group %{group_name} was scheduled for deletion."
+msgstr ""
+
+msgid "Group %{group_name} was successfully created."
+msgstr ""
+
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
+msgid "Group Audit Events"
+msgstr ""
+
+msgid "Group CI/CD settings"
+msgstr ""
+
+msgid "Group Git LFS status:"
+msgstr ""
+
+msgid "Group Hooks"
+msgstr ""
+
+msgid "Group ID"
+msgstr ""
+
+msgid "Group ID: %{group_id}"
+msgstr ""
+
+msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
+msgstr ""
+
+msgid "Group Runners"
+msgstr ""
+
+msgid "Group SAML must be enabled to test"
+msgstr ""
+
+msgid "Group URL"
+msgstr ""
+
+msgid "Group avatar"
+msgstr ""
+
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
+msgid "Group description"
+msgstr ""
+
+msgid "Group description (optional)"
+msgstr ""
+
+msgid "Group details"
+msgstr ""
+
+msgid "Group export could not be started."
+msgstr ""
+
+msgid "Group export error"
+msgstr ""
+
+msgid "Group export link has expired. Please generate a new export from your group settings."
+msgstr ""
+
+msgid "Group export started. A download link will be sent by email and made available on this page."
+msgstr ""
+
+msgid "Group has been already marked for deletion"
+msgstr ""
+
+msgid "Group has not been marked for deletion"
+msgstr ""
+
+msgid "Group info:"
+msgstr ""
+
+msgid "Group maintainers can register group runners in the %{link}"
+msgstr ""
+
+msgid "Group members"
+msgstr ""
+
+msgid "Group milestone"
+msgstr ""
+
+msgid "Group name"
+msgstr ""
+
+msgid "Group name (your organization)"
+msgstr ""
+
+msgid "Group overview"
+msgstr ""
+
+msgid "Group overview content"
+msgstr ""
+
+msgid "Group path is already taken. Suggestions: "
+msgstr ""
+
+msgid "Group path is available."
+msgstr ""
+
+msgid "Group pipeline minutes were successfully reset."
+msgstr ""
+
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
+msgid "Group requires separate account"
+msgstr ""
+
+msgid "Group variables (inherited)"
+msgstr ""
+
+msgid "Group was exported"
+msgstr ""
+
+msgid "Group was successfully updated."
+msgstr ""
+
+msgid "Group: %{group_name}"
+msgstr ""
+
+msgid "Group: %{name}"
+msgstr ""
+
+msgid "GroupActivityMetrics|New Members created"
+msgstr ""
+
+msgid "GroupActivyMetrics|Issues created"
+msgstr ""
+
+msgid "GroupActivyMetrics|Merge Requests created"
+msgstr ""
+
+msgid "GroupActivyMetrics|Recent activity (last 90 days)"
+msgstr ""
+
+msgid "GroupRoadmap|%{dateWord} – No end date"
+msgstr ""
+
+msgid "GroupRoadmap|%{startDateInWords} – %{endDateInWords}"
+msgstr ""
+
+msgid "GroupRoadmap|No start date – %{dateWord}"
+msgstr ""
+
+msgid "GroupRoadmap|Something went wrong while fetching epics"
+msgstr ""
+
+msgid "GroupRoadmap|Something went wrong while fetching milestones"
+msgstr ""
+
+msgid "GroupRoadmap|Sorry, no epics matched your search"
+msgstr ""
+
+msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
+msgstr ""
+
+msgid "GroupRoadmap|To view the roadmap, add a start or due date to one of the %{linkStart}child epics%{linkEnd}."
+msgstr ""
+
+msgid "GroupRoadmap|To view the roadmap, add a start or due date to one of your epics in this group or its subgroups; from %{startDate} to %{endDate}."
+msgstr ""
+
+msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
+msgstr ""
+
+msgid "GroupSAML|Certificate fingerprint"
+msgstr ""
+
+msgid "GroupSAML|Configuration"
+msgstr ""
+
+msgid "GroupSAML|Copy SAML Response XML"
+msgstr ""
+
+msgid "GroupSAML|Enable SAML authentication for this group."
+msgstr ""
+
+msgid "GroupSAML|Enforce SSO-only authentication for this group."
+msgstr ""
+
+msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
+msgstr ""
+
+msgid "GroupSAML|Enforced SSO"
+msgstr ""
+
+msgid "GroupSAML|Generate a SCIM token"
+msgstr ""
+
+msgid "GroupSAML|Generate a SCIM token to set up your System for Cross-Domain Identity Management."
+msgstr ""
+
+msgid "GroupSAML|Identity"
+msgstr ""
+
+msgid "GroupSAML|Identity provider single sign on URL"
+msgstr ""
+
+msgid "GroupSAML|Make sure you save this token — you won't be able to access it again."
+msgstr ""
+
+msgid "GroupSAML|Manage your group’s membership while adding another level of security with SAML."
+msgstr ""
+
+msgid "GroupSAML|Members"
+msgstr ""
+
+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 ""
+
+msgid "GroupSAML|NameID Format"
+msgstr ""
+
+msgid "GroupSAML|Prohibit outer forks"
+msgstr ""
+
+msgid "GroupSAML|Prohibit outer forks for this group."
+msgstr ""
+
+msgid "GroupSAML|SAML Response Output"
+msgstr ""
+
+msgid "GroupSAML|SAML Response XML"
+msgstr ""
+
+msgid "GroupSAML|SAML Single Sign On"
+msgstr ""
+
+msgid "GroupSAML|SAML Single Sign On Settings"
+msgstr ""
+
+msgid "GroupSAML|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSAML|SCIM Token"
+msgstr ""
+
+msgid "GroupSAML|SHA1 fingerprint of the SAML token signing certificate. Get this from your identity provider, where it can also be called \"Thumbprint\"."
+msgstr ""
+
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
+msgstr ""
+
+msgid "GroupSAML|To be able to enable enforced SSO, you first need to enable SAML authentication."
+msgstr ""
+
+msgid "GroupSAML|To be able to enable group managed accounts, you first need to enable enforced SSO."
+msgstr ""
+
+msgid "GroupSAML|To be able to prohibit outer forks, you first need to enforce dedicate group managed accounts."
+msgstr ""
+
+msgid "GroupSAML|Toggle SAML authentication"
+msgstr ""
+
+msgid "GroupSAML|Valid SAML Response"
+msgstr ""
+
+msgid "GroupSAML|With group managed accounts enabled, all the users without a group managed account will be excluded from the group."
+msgstr ""
+
+msgid "GroupSAML|With prohibit outer forks flag enabled group members will be able to fork project only inside your group."
+msgstr ""
+
+msgid "GroupSAML|Your SCIM token"
+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\""
+msgstr ""
+
+msgid "GroupSAML|should be a random persistent ID, emails are discouraged"
+msgstr ""
+
+msgid "GroupSettings|Apply integration settings to all Projects"
+msgstr ""
+
+msgid "GroupSettings|Auto DevOps pipeline was updated for the group"
+msgstr ""
+
+msgid "GroupSettings|Badges"
+msgstr ""
+
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgstr ""
+
+msgid "GroupSettings|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 ""
+
+msgid "GroupSettings|Change group path"
+msgstr ""
+
+msgid "GroupSettings|Changing group path can have unintended side effects."
+msgstr ""
+
+msgid "GroupSettings|Custom project templates"
+msgstr ""
+
+msgid "GroupSettings|Customize your group badges."
+msgstr ""
+
+msgid "GroupSettings|Default to Auto DevOps pipeline for all projects within this group"
+msgstr ""
+
+msgid "GroupSettings|Disable email notifications"
+msgstr ""
+
+msgid "GroupSettings|Disable group mentions"
+msgstr ""
+
+msgid "GroupSettings|Export group"
+msgstr ""
+
+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 ""
+
+msgid "GroupSettings|Integrations configured here will automatically apply to all projects in this group."
+msgstr ""
+
+msgid "GroupSettings|Learn more about badges."
+msgstr ""
+
+msgid "GroupSettings|Learn more about group-level project templates."
+msgstr ""
+
+msgid "GroupSettings|New runners registration token has been generated!"
+msgstr ""
+
+msgid "GroupSettings|Pipeline settings was updated for the group"
+msgstr ""
+
+msgid "GroupSettings|Please choose a group path with no special characters."
+msgstr ""
+
+msgid "GroupSettings|Prevent sharing a project within %{group} with other groups"
+msgstr ""
+
+msgid "GroupSettings|Select a sub-group as the custom project template source for this group."
+msgstr ""
+
+msgid "GroupSettings|The Auto DevOps pipeline will run if no alternative CI configuration file is found."
+msgstr ""
+
+msgid "GroupSettings|There was a problem updating Auto DevOps pipeline: %{error_messages}."
+msgstr ""
+
+msgid "GroupSettings|There was a problem updating the pipeline settings: %{error_messages}."
+msgstr ""
+
+msgid "GroupSettings|This setting is applied on %{ancestor_group} and has been overridden on this subgroup."
+msgstr ""
+
+msgid "GroupSettings|This setting is applied on %{ancestor_group}. To share projects in this group with another group, ask the owner to override the setting or %{remove_ancestor_share_with_group_lock}."
+msgstr ""
+
+msgid "GroupSettings|This setting is applied on %{ancestor_group}. You can override the setting or %{remove_ancestor_share_with_group_lock}."
+msgstr ""
+
+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 ""
+
+msgid "GroupSettings|This setting will override user notification preferences for all members of the group, subgroups, and projects."
+msgstr ""
+
+msgid "GroupSettings|This setting will prevent group members from being notified if the group is mentioned."
+msgstr ""
+
+msgid "GroupSettings|Transfer group"
+msgstr ""
+
+msgid "GroupSettings|You can only transfer the group to a group you manage."
+msgstr ""
+
+msgid "GroupSettings|You will need to update your local repositories to point to the new location."
+msgstr ""
+
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
+msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
+msgstr ""
+
+msgid "GroupSettings|cannot change when group contains projects with NPM packages"
+msgstr ""
+
+msgid "GroupSettings|remove the share with group lock from %{ancestor_group_name}"
+msgstr ""
+
+msgid "Groups"
+msgstr ""
+
+msgid "Groups (%{count})"
+msgstr ""
+
+msgid "Groups (%{groups})"
+msgstr ""
+
+msgid "Groups can also be nested by creating %{subgroup_docs_link_start}subgroups%{subgroup_docs_link_end}."
+msgstr ""
+
+msgid "Groups to synchronize"
+msgstr ""
+
+msgid "Groups with access to %{strong_start}%{group_name}%{strong_end}"
+msgstr ""
+
+msgid "Groups with access to <strong>%{project_name}</strong>"
+msgstr ""
+
+msgid "GroupsDropdown|Frequently visited"
+msgstr ""
+
+msgid "GroupsDropdown|Groups you visit often will appear here"
+msgstr ""
+
+msgid "GroupsDropdown|Loading groups"
+msgstr ""
+
+msgid "GroupsDropdown|Search your groups"
+msgstr ""
+
+msgid "GroupsDropdown|Something went wrong on our end."
+msgstr ""
+
+msgid "GroupsDropdown|Sorry, no groups matched your search"
+msgstr ""
+
+msgid "GroupsDropdown|This feature requires browser localStorage support"
+msgstr ""
+
+msgid "GroupsEmptyState|A group is a collection of several projects."
+msgstr ""
+
+msgid "GroupsEmptyState|If you organize your projects under a group, it works like a folder."
+msgstr ""
+
+msgid "GroupsEmptyState|No groups found"
+msgstr ""
+
+msgid "GroupsEmptyState|You can manage your group member’s permissions and access to each project in the group."
+msgstr ""
+
+msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
+msgstr ""
+
+msgid "GroupsTree|Create a project in this group."
+msgstr ""
+
+msgid "GroupsTree|Create a subgroup in this group."
+msgstr ""
+
+msgid "GroupsTree|Edit group"
+msgstr ""
+
+msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
+msgstr ""
+
+msgid "GroupsTree|Leave this group"
+msgstr ""
+
+msgid "GroupsTree|Loading groups"
+msgstr ""
+
+msgid "GroupsTree|No groups matched your search"
+msgstr ""
+
+msgid "GroupsTree|No groups or projects matched your search"
+msgstr ""
+
+msgid "GroupsTree|Search by name"
+msgstr ""
+
+msgid "Guideline"
+msgstr ""
+
+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 ""
+
+msgid "Hashed Storage must be enabled to use Geo"
+msgstr ""
+
+msgid "Hashed repository storage paths"
+msgstr ""
+
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
+msgid "Have your users email"
+msgstr ""
+
+msgid "Header logo was successfully removed."
+msgstr ""
+
+msgid "Header message"
+msgstr ""
+
+msgid "Headings"
+msgstr ""
+
+msgid "Health"
+msgstr ""
+
+msgid "Health Check"
+msgstr ""
+
+msgid "Health information can be retrieved from the following endpoints. More information is available"
+msgstr ""
+
+msgid "HealthCheck|Access token is"
+msgstr ""
+
+msgid "HealthCheck|Healthy"
+msgstr ""
+
+msgid "HealthCheck|No Health Problems Detected"
+msgstr ""
+
+msgid "HealthCheck|Unhealthy"
+msgstr ""
+
+msgid "Hello there"
+msgstr ""
+
+msgid "Help"
+msgstr ""
+
+msgid "Help page"
+msgstr ""
+
+msgid "Help page text and support page url."
+msgstr ""
+
+msgid "Helps prevent bots from brute-force attacks."
+msgstr ""
+
+msgid "Helps prevent bots from creating accounts."
+msgstr ""
+
+msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgstr ""
+
+msgid "Helps reduce request volume for protected paths"
+msgstr ""
+
+msgid "Here you will find recent merge request activity"
+msgstr ""
+
+msgid "Hi %{username}!"
+msgstr ""
+
+msgid "Hide archived projects"
+msgstr ""
+
+msgid "Hide chart"
+msgid_plural "Hide charts"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Hide file browser"
+msgstr ""
+
+msgid "Hide group projects"
+msgstr ""
+
+msgid "Hide host keys manual input"
+msgstr ""
+
+msgid "Hide marketing-related entries from help"
+msgstr ""
+
+msgid "Hide payload"
+msgstr ""
+
+msgid "Hide shared projects"
+msgstr ""
+
+msgid "Hide stage"
+msgstr ""
+
+msgid "Hide value"
+msgid_plural "Hide values"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Hide values"
+msgstr ""
+
+msgid "Hiding all labels"
+msgstr ""
+
+msgid "High or unknown vulnerabilities present"
+msgstr ""
+
+msgid "Highest number of requests per minute for each raw path, default to 300. To disable throttling set to 0."
+msgstr ""
+
+msgid "Highest role:"
+msgstr ""
+
+msgid "History"
+msgstr ""
+
+msgid "History of authentications"
+msgstr ""
+
+msgid "Homepage"
+msgstr ""
+
+msgid "Hook execution failed. Ensure the group has a project with commits."
+msgstr ""
+
+msgid "Hook was successfully created."
+msgstr ""
+
+msgid "Hook was successfully updated."
+msgstr ""
+
+msgid "Hostname"
+msgstr ""
+
+msgid "Hour (UTC)"
+msgstr ""
+
+msgid "Housekeeping"
+msgstr ""
+
+msgid "Housekeeping successfully started"
+msgstr ""
+
+msgid "Housekeeping, export, path, transfer, remove, archive."
+msgstr ""
+
+msgid "How it works"
+msgstr ""
+
+msgid "How many days need to pass between marking entity for deletion and actual removing it."
+msgstr ""
+
+msgid "How many replicas each Elasticsearch shard has."
+msgstr ""
+
+msgid "How many shards to split the Elasticsearch index over."
+msgstr ""
+
+msgid "How many users will be evaluating the trial?"
+msgstr ""
+
+msgid "However, you are already a member of this %{member_source}. Sign in using a different account to accept the invitation."
+msgstr ""
+
+msgid "I accept the %{terms_link_start}Terms of Service and Privacy Policy%{terms_link_end}"
+msgstr ""
+
+msgid "I accept the %{terms_link}"
+msgstr ""
+
+msgid "I accept the|Terms of Service and Privacy Policy"
+msgstr ""
+
+msgid "I forgot my password"
+msgstr ""
+
+msgid "I have read and agree to the Let's Encrypt %{link_start}Terms of Service%{link_end} (PDF)"
+msgstr ""
+
+msgid "I'd like to receive updates via email about GitLab"
+msgstr ""
+
+msgid "ID"
+msgstr ""
+
+msgid "ID:"
+msgstr ""
+
+msgid "IDE|Allow live previews of JavaScript projects in the Web IDE using CodeSandbox Live Preview."
+msgstr ""
+
+msgid "IDE|Back"
+msgstr ""
+
+msgid "IDE|Commit"
+msgstr ""
+
+msgid "IDE|Commit to %{branchName} branch"
+msgstr ""
+
+msgid "IDE|Edit"
+msgstr ""
+
+msgid "IDE|Get started with Live Preview"
+msgstr ""
+
+msgid "IDE|Go to project"
+msgstr ""
+
+msgid "IDE|Live Preview"
+msgstr ""
+
+msgid "IDE|Preview your web application using Web IDE client-side evaluation."
+msgstr ""
+
+msgid "IDE|Refresh preview"
+msgstr ""
+
+msgid "IDE|Review"
+msgstr ""
+
+msgid "IDE|Successful commit"
+msgstr ""
+
+msgid "IDE|This option is disabled because you are not allowed to create merge requests in this project."
+msgstr ""
+
+msgid "IDE|This option is disabled because you don't have write permissions for the current branch."
+msgstr ""
+
+msgid "INFO: Your SSH key has expired. Please generate a new key."
+msgstr ""
+
+msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
+msgstr ""
+
+msgid "IP Address"
+msgstr ""
+
+msgid "IP subnet restriction only allowed for top-level groups"
+msgstr ""
+
+msgid "Identifier"
+msgstr ""
+
+msgid "Identifiers"
+msgstr ""
+
+msgid "Identities"
+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 any job surpasses this timeout threshold, it will be marked as failed. Human readable time input language is accepted like \"1 hour\". Values without specification represent seconds."
+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 ""
+
+msgid "If checked, group owners can manage LDAP group links and LDAP member overrides"
+msgstr ""
+
+msgid "If checked, new group memberships and permissions can only be added via LDAP synchronization"
+msgstr ""
+
+msgid "If disabled, a diverged local branch will not be automatically updated with commits from its remote counterpart, to prevent local data loss. If the default branch (%{default_branch}) has diverged and cannot be updated, mirroring will fail. Other diverged branches are silently ignored."
+msgstr ""
+
+msgid "If disabled, only admins will be able to configure repository mirroring."
+msgstr ""
+
+msgid "If disabled, the access level will depend on the user's permissions in the project."
+msgstr ""
+
+msgid "If enabled"
+msgstr ""
+
+msgid "If enabled, access to projects will be validated on an external service using their classification label."
+msgstr ""
+
+msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
+msgstr ""
+
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
+msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
+msgstr ""
+
+msgid "If this was a mistake you can leave the %{source_type}."
+msgstr ""
+
+msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
+msgstr ""
+
+msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
+msgstr ""
+
+msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
+msgstr ""
+
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
+msgid "If your HTTP repository is not publicly accessible, add your credentials."
+msgstr ""
+
+msgid "Iglu registry URL (optional)"
+msgstr ""
+
+msgid "Ignore"
+msgstr ""
+
+msgid "Ignored"
+msgstr ""
+
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
+msgstr ""
+
+msgid "ImageDiffViewer|2-up"
+msgstr ""
+
+msgid "ImageDiffViewer|Onion skin"
+msgstr ""
+
+msgid "ImageDiffViewer|Swipe"
+msgstr ""
+
+msgid "ImageViewerDimensions|H"
+msgstr ""
+
+msgid "ImageViewerDimensions|W"
+msgstr ""
+
+msgid "Impersonation Tokens"
+msgstr ""
+
+msgid "Impersonation has been disabled"
+msgstr ""
+
+msgid "Import"
+msgstr ""
+
+msgid "Import CSV"
+msgstr ""
+
+msgid "Import Projects from Gitea"
+msgstr ""
+
+msgid "Import all compatible projects"
+msgstr ""
+
+msgid "Import all compatible repositories"
+msgstr ""
+
+msgid "Import all projects"
+msgstr ""
+
+msgid "Import all repositories"
+msgstr ""
+
+msgid "Import an exported GitLab project"
+msgstr ""
+
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
+msgid "Import from"
+msgstr ""
+
+msgid "Import from Jira"
+msgstr ""
+
+msgid "Import in progress"
+msgstr ""
+
+msgid "Import in progress. Refresh page to see newly added issues."
+msgstr ""
+
+msgid "Import issues"
+msgstr ""
+
+msgid "Import members"
+msgstr ""
+
+msgid "Import members from another project"
+msgstr ""
+
+msgid "Import multiple repositories by uploading a manifest file."
+msgstr ""
+
+msgid "Import project"
+msgstr ""
+
+msgid "Import project members"
+msgstr ""
+
+msgid "Import projects from Bitbucket"
+msgstr ""
+
+msgid "Import projects from Bitbucket Server"
+msgstr ""
+
+msgid "Import projects from FogBugz"
+msgstr ""
+
+msgid "Import projects from GitLab.com"
+msgstr ""
+
+msgid "Import projects from Google Code"
+msgstr ""
+
+msgid "Import repositories from Bitbucket Server"
+msgstr ""
+
+msgid "Import repositories from GitHub"
+msgstr ""
+
+msgid "Import repository"
+msgstr ""
+
+msgid "Import started by: %{importInitiator}"
+msgstr ""
+
+msgid "Import tasks"
+msgstr ""
+
+msgid "Import tasks from Phabricator into issues"
+msgstr ""
+
+msgid "Import timed out. Import took longer than %{import_jobs_expiration} seconds"
+msgstr ""
+
+msgid "Import/Export illustration"
+msgstr ""
+
+msgid "ImportButtons|Connect repositories from"
+msgstr ""
+
+msgid "ImportProjects|Blocked import URL: %{message}"
+msgstr ""
+
+msgid "ImportProjects|Error importing repository %{project_safe_import_url} into %{project_full_path} - %{message}"
+msgstr ""
+
+msgid "ImportProjects|Importing the project failed"
+msgstr ""
+
+msgid "ImportProjects|Requesting your %{provider} repositories failed"
+msgstr ""
+
+msgid "ImportProjects|Select the projects you want to import"
+msgstr ""
+
+msgid "ImportProjects|The remote data could not be imported."
+msgstr ""
+
+msgid "ImportProjects|The repository could not be created."
+msgstr ""
+
+msgid "ImportProjects|Update of imported projects with realtime changes failed"
+msgstr ""
+
+msgid "Improve Issue boards"
+msgstr ""
+
+msgid "Improve Issue boards with GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "In %{time_to_now}"
+msgstr ""
+
+msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
+msgstr ""
+
+msgid "In order to gather accurate feature usage data, it can take 1 to 2 weeks to see your index."
+msgstr ""
+
+msgid "In order to personalize your experience with GitLab<br>we would like to know a bit more about you."
+msgstr ""
+
+msgid "In order to tailor your experience with GitLab we<br>would like to know a bit more about you."
+msgstr ""
+
+msgid "In progress"
+msgstr ""
+
+msgid "In the next step, you'll be able to select the projects you want to import."
+msgstr ""
+
+msgid "Incident Management Limits"
+msgstr ""
+
+msgid "Incidents"
+msgstr ""
+
+msgid "Include a Terms of Service agreement and Privacy Policy that all users must accept."
+msgstr ""
+
+msgid "Include author name in notification email body"
+msgstr ""
+
+msgid "Include description in commit message"
+msgstr ""
+
+msgid "Include merge request description"
+msgstr ""
+
+msgid "Include the username in the URL if required: <code>https://username@gitlab.company.com/group/project.git</code>."
+msgstr ""
+
+msgid "Includes LFS objects. It can be overridden per group, or per project. 0 for unlimited."
+msgstr ""
+
+msgid "Includes an MVC structure to help you get started."
+msgstr ""
+
+msgid "Includes an MVC structure, Gemfile, Rakefile, along with many others, to help you get started."
+msgstr ""
+
+msgid "Includes an MVC structure, mvnw and pom.xml to help you get started."
+msgstr ""
+
+msgid "Includes repository storage, wiki storage, LFS objects, build artifacts and packages. 0 for unlimited."
+msgstr ""
+
+msgid "Incoming email"
+msgstr ""
+
+msgid "Incoming!"
+msgstr ""
+
+msgid "Incompatible Project"
+msgstr ""
+
+msgid "Incompatible options set!"
+msgstr ""
+
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
+msgid "Index all projects"
+msgstr ""
+
+msgid "Indicates whether this runner can pick jobs without tags"
+msgstr ""
+
+msgid "Inform users without uploaded SSH keys that they can't push over SSH until one is added"
+msgstr ""
+
+msgid "Information about additional Pages templates and how to install them can be found in our %{pages_getting_started_guide}."
+msgstr ""
+
+msgid "Inherited:"
+msgstr ""
+
+msgid "Inline"
+msgstr ""
+
+msgid "Input host keys manually"
+msgstr ""
+
+msgid "Input your repository URL"
+msgstr ""
+
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
+msgid "Insert a quote"
+msgstr ""
+
+msgid "Insert an image"
+msgstr ""
+
+msgid "Insert code"
+msgstr ""
+
+msgid "Insert inline code"
+msgstr ""
+
+msgid "Insert suggestion"
+msgstr ""
+
+msgid "Insights"
+msgstr ""
+
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Install"
+msgstr ""
+
+msgid "Install GitLab Runner"
+msgstr ""
+
+msgid "Install Runner on Kubernetes"
+msgstr ""
+
+msgid "Install a soft token authenticator like %{free_otp_link} or Google Authenticator from your application repository and use that app to scan this QR code. More information is available in the %{help_link_start}documentation%{help_link_end}."
+msgstr ""
+
+msgid "Install on clusters"
+msgstr ""
+
+msgid "Installed"
+msgstr ""
+
+msgid "Installing"
+msgstr ""
+
+msgid "Instance"
+msgid_plural "Instances"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Instance Statistics visibility"
+msgstr ""
+
+msgid "Instance administrators group already exists"
+msgstr ""
+
+msgid "Instance does not support multiple Kubernetes clusters"
+msgstr ""
+
+msgid "Instance license"
+msgstr ""
+
+msgid "Integration"
+msgstr ""
+
+msgid "Integration Settings"
+msgstr ""
+
+msgid "Integrations"
+msgstr ""
+
+msgid "Integrations allow you to integrate GitLab with other applications"
+msgstr ""
+
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "Interested parties can even contribute by pushing commits if they want to."
+msgstr ""
+
+msgid "Internal"
+msgstr ""
+
+msgid "Internal - The group and any internal projects can be viewed by any logged in user."
+msgstr ""
+
+msgid "Internal - The project can be accessed by any logged in user."
+msgstr ""
+
+msgid "Internal URL (optional)"
+msgstr ""
+
+msgid "Internal users"
+msgstr ""
+
+msgid "Interval Pattern"
+msgstr ""
+
+msgid "Introducing Value Stream Analytics"
+msgstr ""
+
+msgid "Introducing Your DevOps Score"
+msgstr ""
+
+msgid "Invalid Git ref"
+msgstr ""
+
+msgid "Invalid Insights config file detected"
+msgstr ""
+
+msgid "Invalid Login or password"
+msgstr ""
+
+msgid "Invalid URL"
+msgstr ""
+
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
+msgid "Invalid cursor value provided"
+msgstr ""
+
+msgid "Invalid date"
+msgstr ""
+
+msgid "Invalid date format. Please use UTC format as YYYY-MM-DD"
+msgstr ""
+
+msgid "Invalid date range"
+msgstr ""
+
+msgid "Invalid feature"
+msgstr ""
+
+msgid "Invalid field"
+msgstr ""
+
+msgid "Invalid file format with specified file type"
+msgstr ""
+
+msgid "Invalid file."
+msgstr ""
+
+msgid "Invalid import params"
+msgstr ""
+
+msgid "Invalid input, please avoid emojis"
+msgstr ""
+
+msgid "Invalid login or password"
+msgstr ""
+
+msgid "Invalid pin code"
+msgstr ""
+
+msgid "Invalid pod_name"
+msgstr ""
+
+msgid "Invalid query"
+msgstr ""
+
+msgid "Invalid repository path"
+msgstr ""
+
+msgid "Invalid search parameter"
+msgstr ""
+
+msgid "Invalid server response"
+msgstr ""
+
+msgid "Invalid start or end time format"
+msgstr ""
+
+msgid "Invalid status"
+msgstr ""
+
+msgid "Invalid two-factor code."
+msgstr ""
+
+msgid "Invitation"
+msgstr ""
+
+msgid "Invite"
+msgstr ""
+
+msgid "Invite \"%{trimmed}\" by email"
+msgstr ""
+
+msgid "Invite Members"
+msgstr ""
+
+msgid "Invite group"
+msgstr ""
+
+msgid "Invite member"
+msgstr ""
+
+msgid "Invocations"
+msgstr ""
+
+msgid "Is blocked by"
+msgstr ""
+
+msgid "Is this GitLab trial for your company?"
+msgstr ""
+
+msgid "Is using license seat:"
+msgstr ""
+
+msgid "Is using seat"
+msgstr ""
+
+msgid "IssuableStatus|Closed"
+msgstr ""
+
+msgid "IssuableStatus|Closed (%{link})"
+msgstr ""
+
+msgid "IssuableStatus|duplicated"
+msgstr ""
+
+msgid "IssuableStatus|moved"
+msgstr ""
+
+msgid "IssuableStatus|promoted"
+msgstr ""
+
+msgid "Issue"
+msgstr ""
+
+msgid "Issue %{issue_reference} has already been added to epic %{epic_reference}."
+msgstr ""
+
+msgid "Issue Boards"
+msgstr ""
+
+msgid "Issue already promoted to epic."
+msgstr ""
+
+msgid "Issue cannot be found."
+msgstr ""
+
+msgid "Issue events"
+msgstr ""
+
+msgid "Issue first depoloyed to production"
+msgstr ""
+
+msgid "Issue label"
+msgstr ""
+
+msgid "Issue or Merge Request ID is required"
+msgstr ""
+
+msgid "Issue published on status page."
+msgstr ""
+
+msgid "Issue template (optional)"
+msgstr ""
+
+msgid "Issue update failed"
+msgstr ""
+
+msgid "Issue was closed by %{name} %{reason}"
+msgstr ""
+
+msgid "Issue weight"
+msgstr ""
+
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
+msgid "IssueBoards|Board"
+msgstr ""
+
+msgid "IssueBoards|Boards"
+msgstr ""
+
+msgid "IssueBoards|Create new board"
+msgstr ""
+
+msgid "IssueBoards|Delete board"
+msgstr ""
+
+msgid "IssueBoards|No matching boards found"
+msgstr ""
+
+msgid "IssueBoards|Some of your boards are hidden, activate a license to see them again."
+msgstr ""
+
+msgid "IssueBoards|Switch board"
+msgstr ""
+
+msgid "IssueTracker|Bugzilla issue tracker"
+msgstr ""
+
+msgid "IssueTracker|Custom issue tracker"
+msgstr ""
+
+msgid "IssueTracker|GitLab issue tracker"
+msgstr ""
+
+msgid "IssueTracker|Redmine issue tracker"
+msgstr ""
+
+msgid "IssueTracker|YouTrack issue tracker"
+msgstr ""
+
+msgid "Issues"
+msgstr ""
+
+msgid "Issues Analytics"
+msgstr ""
+
+msgid "Issues Rate Limits"
+msgstr ""
+
+msgid "Issues and Merge Requests"
+msgstr ""
+
+msgid "Issues can be bugs, tasks or ideas to be discussed. Also, issues are searchable and filterable."
+msgstr ""
+
+msgid "Issues closed"
+msgstr ""
+
+msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
+msgstr ""
+
+msgid "Issues successfully imported with the label"
+msgstr ""
+
+msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
+msgstr ""
+
+msgid "Issues, merge requests, pushes, and comments."
+msgstr ""
+
+msgid "IssuesAnalytics|After you begin creating issues for your projects, we can start tracking and displaying metrics for them"
+msgstr ""
+
+msgid "IssuesAnalytics|Avg/Month:"
+msgstr ""
+
+msgid "IssuesAnalytics|Issues opened"
+msgstr ""
+
+msgid "IssuesAnalytics|Issues opened per month"
+msgstr ""
+
+msgid "IssuesAnalytics|Last 12 months"
+msgstr ""
+
+msgid "IssuesAnalytics|Sorry, your filter produced no results"
+msgstr ""
+
+msgid "IssuesAnalytics|There are no issues for the projects in your group"
+msgstr ""
+
+msgid "IssuesAnalytics|To widen your search, change or remove filters in the filter bar above"
+msgstr ""
+
+msgid "IssuesAnalytics|Total:"
+msgstr ""
+
+msgid "Issue|Title"
+msgstr ""
+
+msgid "It must have a header row and at least two columns: the first column is the issue title and the second column is the issue description. The separator is automatically detected."
+msgstr ""
+
+msgid "It seems like the Dependency Scanning job ran successfully, but no dependencies have been detected in your project."
+msgstr ""
+
+msgid "It's you"
+msgstr ""
+
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "Jaeger URL"
+msgstr ""
+
+msgid "Jaeger tracing"
+msgstr ""
+
+msgid "Jan"
+msgstr ""
+
+msgid "January"
+msgstr ""
+
+msgid "Jira import is already running."
+msgstr ""
+
+msgid "Jira integration not configured."
+msgstr ""
+
+msgid "Jira project: %{importProject}"
+msgstr ""
+
+msgid "Jira service not configured."
+msgstr ""
+
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
+msgstr ""
+
+msgid "JiraService|Events for %{noteable_model_name} are disabled."
+msgstr ""
+
+msgid "JiraService|If different from Web URL"
+msgstr ""
+
+msgid "JiraService|Jira API URL"
+msgstr ""
+
+msgid "JiraService|Jira comments will be created when an issue gets referenced in a commit."
+msgstr ""
+
+msgid "JiraService|Jira comments will be created when an issue gets referenced in a merge request."
+msgstr ""
+
+msgid "JiraService|Jira issue tracker"
+msgstr ""
+
+msgid "JiraService|Password or API token"
+msgstr ""
+
+msgid "JiraService|Transition ID(s)"
+msgstr ""
+
+msgid "JiraService|Use , or ; to separate multiple transition IDs"
+msgstr ""
+
+msgid "JiraService|Use a password for server version and an API token for cloud version"
+msgstr ""
+
+msgid "JiraService|Use a username for server version and an email for cloud version"
+msgstr ""
+
+msgid "JiraService|Username or Email"
+msgstr ""
+
+msgid "JiraService|Web URL"
+msgstr ""
+
+msgid "JiraService|transition ids can have only numbers which can be split with , or ;"
+msgstr ""
+
+msgid "Job"
+msgstr ""
+
+msgid "Job Failed #%{build_id}"
+msgstr ""
+
+msgid "Job ID"
+msgstr ""
+
+msgid "Job has been erased"
+msgstr ""
+
+msgid "Job has been successfully erased!"
+msgstr ""
+
+msgid "Job has wrong arguments format."
+msgstr ""
+
+msgid "Job is missing the `model_type` argument."
+msgstr ""
+
+msgid "Job is stuck. Check runners."
+msgstr ""
+
+msgid "Job logs and artifacts"
+msgstr ""
+
+msgid "Job to create self-monitoring project is in progress"
+msgstr ""
+
+msgid "Job to delete self-monitoring project is in progress"
+msgstr ""
+
+msgid "Job was retried"
+msgstr ""
+
+msgid "Jobs"
+msgstr ""
+
+msgid "Job|Browse"
+msgstr ""
+
+msgid "Job|Complete Raw"
+msgstr ""
+
+msgid "Job|Download"
+msgstr ""
+
+msgid "Job|Erase job log"
+msgstr ""
+
+msgid "Job|Job artifacts"
+msgstr ""
+
+msgid "Job|Job has been erased"
+msgstr ""
+
+msgid "Job|Job has been erased by"
+msgstr ""
+
+msgid "Job|Keep"
+msgstr ""
+
+msgid "Job|Pipeline"
+msgstr ""
+
+msgid "Job|Scroll to bottom"
+msgstr ""
+
+msgid "Job|Scroll to top"
+msgstr ""
+
+msgid "Job|Show complete raw"
+msgstr ""
+
+msgid "Job|The artifacts were removed"
+msgstr ""
+
+msgid "Job|The artifacts will be removed"
+msgstr ""
+
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
+msgid "Job|This job failed because the necessary resources were not successfully created."
+msgstr ""
+
+msgid "Job|This job is stuck because the project doesn't have any runners online assigned to it."
+msgstr ""
+
+msgid "Job|for"
+msgstr ""
+
+msgid "Job|into"
+msgstr ""
+
+msgid "Job|with"
+msgstr ""
+
+msgid "Join Zoom meeting"
+msgstr ""
+
+msgid "Jul"
+msgstr ""
+
+msgid "July"
+msgstr ""
+
+msgid "Jump to first unresolved thread"
+msgstr ""
+
+msgid "Jump to next unresolved thread"
+msgstr ""
+
+msgid "Jun"
+msgstr ""
+
+msgid "June"
+msgstr ""
+
+msgid "Just me"
+msgstr ""
+
+msgid "Keep divergent refs"
+msgstr ""
+
+msgid "Key"
+msgstr ""
+
+msgid "Key (PEM)"
+msgstr ""
+
+msgid "Key: %{key}"
+msgstr ""
+
+msgid "Keyboard Shortcuts"
+msgstr ""
+
+msgid "Keyboard shortcuts"
+msgstr ""
+
+msgid "Kubernetes"
+msgstr ""
+
+msgid "Kubernetes API returned status code: %{error_code}"
+msgstr ""
+
+msgid "Kubernetes Cluster"
+msgstr ""
+
+msgid "Kubernetes Clusters"
+msgstr ""
+
+msgid "Kubernetes cluster"
+msgstr ""
+
+msgid "Kubernetes cluster creation time exceeds timeout; %{timeout}"
+msgstr ""
+
+msgid "Kubernetes cluster integration and resources are being removed."
+msgstr ""
+
+msgid "Kubernetes cluster integration was successfully removed."
+msgstr ""
+
+msgid "Kubernetes cluster was successfully updated."
+msgstr ""
+
+msgid "Kubernetes deployment not found"
+msgstr ""
+
+msgid "Kubernetes error: %{error_code}"
+msgstr ""
+
+msgid "Kubernetes popover"
+msgstr ""
+
+msgid "LDAP"
+msgstr ""
+
+msgid "LDAP settings"
+msgstr ""
+
+msgid "LDAP settings updated"
+msgstr ""
+
+msgid "LDAP sync in progress. This could take a few minutes. Refresh the page to see the changes."
+msgstr ""
+
+msgid "LFS"
+msgstr ""
+
+msgid "LFS objects"
+msgstr ""
+
+msgid "LFSStatus|Disabled"
+msgstr ""
+
+msgid "LFSStatus|Enabled"
+msgstr ""
+
+msgid "LICENSE"
+msgstr ""
+
+msgid "Label"
+msgstr ""
+
+msgid "Label actions dropdown"
+msgstr ""
+
+msgid "Label lists show all issues with the selected label."
+msgstr ""
+
+msgid "Label was created"
+msgstr ""
+
+msgid "Label was removed"
+msgstr ""
+
+msgid "Label was successfully updated."
+msgstr ""
+
+msgid "LabelSelect|%{firstLabelName} +%{remainingLabelCount} more"
+msgstr ""
+
+msgid "LabelSelect|%{labelsString}, and %{remainingLabelCount} more"
+msgstr ""
+
+msgid "LabelSelect|Labels"
+msgstr ""
+
+msgid "Labels"
+msgstr ""
+
+msgid "Labels can be applied to %{features}. Group labels are available for any project within the group."
+msgstr ""
+
+msgid "Labels can be applied to issues and merge requests to categorize them."
+msgstr ""
+
+msgid "Labels can be applied to issues and merge requests."
+msgstr ""
+
+msgid "Labels|<span>Promote label</span> %{labelTitle} <span>to Group Label?</span>"
+msgstr ""
+
+msgid "Labels|Promote Label"
+msgstr ""
+
+msgid "Labels|Promoting %{labelTitle} will make it available for all projects inside %{groupName}. Existing project labels with the same title will be merged. If a group label with the same title exists, it will also be merged. This action cannot be reversed."
+msgstr ""
+
+msgid "Labels|and %{count} more"
+msgstr ""
+
+msgid "Language"
+msgstr ""
+
+msgid "Large File Storage"
+msgstr ""
+
+msgid "Last %d day"
+msgid_plural "Last %d days"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Last %{days} days"
+msgstr ""
+
+msgid "Last Accessed On"
+msgstr ""
+
+msgid "Last Name is too long (maximum is %{max_length} characters)."
+msgstr ""
+
+msgid "Last Pipeline"
+msgstr ""
+
+msgid "Last Seen"
+msgstr ""
+
+msgid "Last accessed on"
+msgstr ""
+
+msgid "Last activity"
+msgstr ""
+
+msgid "Last commit"
+msgstr ""
+
+msgid "Last contact"
+msgstr ""
+
+msgid "Last edited %{date}"
+msgstr ""
+
+msgid "Last edited by %{name}"
+msgstr ""
+
+msgid "Last name"
+msgstr ""
+
+msgid "Last reply by"
+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 ""
+
+msgid "Last successful sync"
+msgstr ""
+
+msgid "Last successful update"
+msgstr ""
+
+msgid "Last time verified"
+msgstr ""
+
+msgid "Last update"
+msgstr ""
+
+msgid "Last update attempt"
+msgstr ""
+
+msgid "Last updated"
+msgstr ""
+
+msgid "Last used"
+msgstr ""
+
+msgid "Last used on:"
+msgstr ""
+
+msgid "LastCommit|authored"
+msgstr ""
+
+msgid "LastPushEvent|You pushed to"
+msgstr ""
+
+msgid "LastPushEvent|at"
+msgstr ""
+
+msgid "Latest changes"
+msgstr ""
+
+msgid "Latest pipeline for the most recent commit on this branch"
+msgstr ""
+
+msgid "Lead"
+msgstr ""
+
+msgid "Lead Time"
+msgstr ""
+
+msgid "Learn GitLab"
+msgstr ""
+
+msgid "Learn More"
+msgstr ""
+
+msgid "Learn how to %{link_start}contribute to the built-in templates%{link_end}"
+msgstr ""
+
+msgid "Learn how to %{no_packages_link_start}publish and share your packages%{no_packages_link_end} with GitLab."
+msgstr ""
+
+msgid "Learn how to enable synchronization"
+msgstr ""
+
+msgid "Learn more"
+msgstr ""
+
+msgid "Learn more about Auto DevOps"
+msgstr ""
+
+msgid "Learn more about Kubernetes"
+msgstr ""
+
+msgid "Learn more about License-Check"
+msgstr ""
+
+msgid "Learn more about Vulnerability-Check"
+msgstr ""
+
+msgid "Learn more about Web Terminal"
+msgstr ""
+
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
+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 approvals."
+msgstr ""
+
+msgid "Learn more about custom project templates"
+msgstr ""
+
+msgid "Learn more about deploying to a cluster"
+msgstr ""
+
+msgid "Learn more about group-level project templates"
+msgstr ""
+
+msgid "Learn more about signing commits"
+msgstr ""
+
+msgid "Learn more about the dependency list"
+msgstr ""
+
+msgid "Learn more in the"
+msgstr ""
+
+msgid "Learn more in the|pipeline schedules documentation"
+msgstr ""
+
+msgid "Leave"
+msgstr ""
+
+msgid "Leave Admin Mode"
+msgstr ""
+
+msgid "Leave blank for no limit. Once set, existing personal access tokens may be revoked."
+msgstr ""
+
+msgid "Leave edit mode? All unsaved changes will be lost."
+msgstr ""
+
+msgid "Leave group"
+msgstr ""
+
+msgid "Leave project"
+msgstr ""
+
+msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
+msgstr ""
+
+msgid "Leave zen mode"
+msgstr ""
+
+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 ""
+
+msgid "License"
+msgstr ""
+
+msgid "License Compliance"
+msgstr ""
+
+msgid "License History"
+msgstr ""
+
+msgid "License-Check"
+msgstr ""
+
+msgid "LicenseCompliance|Add a license"
+msgstr ""
+
+msgid "LicenseCompliance|Add license and related policy"
+msgstr ""
+
+msgid "LicenseCompliance|Allow"
+msgstr ""
+
+msgid "LicenseCompliance|Allowed"
+msgstr ""
+
+msgid "LicenseCompliance|Cancel"
+msgstr ""
+
+msgid "LicenseCompliance|Denied"
+msgstr ""
+
+msgid "LicenseCompliance|Deny"
+msgstr ""
+
+msgid "LicenseCompliance|License"
+msgstr ""
+
+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] ""
+
+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] ""
+
+msgid "LicenseCompliance|License Compliance detected %d new license"
+msgid_plural "LicenseCompliance|License Compliance detected %d new licenses"
+msgstr[0] ""
+msgstr[1] ""
+
+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] ""
+
+msgid "LicenseCompliance|License Compliance detected no licenses for the source branch only"
+msgstr ""
+
+msgid "LicenseCompliance|License Compliance detected no new licenses"
+msgstr ""
+
+msgid "LicenseCompliance|License details"
+msgstr ""
+
+msgid "LicenseCompliance|License name"
+msgstr ""
+
+msgid "LicenseCompliance|License review"
+msgstr ""
+
+msgid "LicenseCompliance|Packages"
+msgstr ""
+
+msgid "LicenseCompliance|Remove license"
+msgstr ""
+
+msgid "LicenseCompliance|Remove license?"
+msgstr ""
+
+msgid "LicenseCompliance|Submit"
+msgstr ""
+
+msgid "LicenseCompliance|There are currently no approved or blacklisted licenses in this project."
+msgstr ""
+
+msgid "LicenseCompliance|There are currently no approved or blacklisted licenses that match in this project."
+msgstr ""
+
+msgid "LicenseCompliance|This license already exists in this project."
+msgstr ""
+
+msgid "LicenseCompliance|URL"
+msgstr ""
+
+msgid "LicenseCompliance|You are about to remove the license, %{name}, from this project."
+msgstr ""
+
+msgid "LicenseManagement|Allowed"
+msgstr ""
+
+msgid "LicenseManagement|Denied"
+msgstr ""
+
+msgid "LicenseManagement|Uncategorized"
+msgstr ""
+
+msgid "Licensed Features"
+msgstr ""
+
+msgid "Licensed to"
+msgstr ""
+
+msgid "Licenses"
+msgstr ""
+
+msgid "Licenses|%{remainingComponentsCount} more"
+msgstr ""
+
+msgid "Licenses|Component"
+msgstr ""
+
+msgid "Licenses|Components"
+msgstr ""
+
+msgid "Licenses|Detected in Project"
+msgstr ""
+
+msgid "Licenses|Detected licenses that are out-of-compliance with the project's assigned policies"
+msgstr ""
+
+msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
+msgstr ""
+
+msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
+msgstr ""
+
+msgid "Licenses|Learn more about license compliance"
+msgstr ""
+
+msgid "Licenses|License Compliance"
+msgstr ""
+
+msgid "Licenses|Name"
+msgstr ""
+
+msgid "Licenses|Policies"
+msgstr ""
+
+msgid "Licenses|Policy"
+msgstr ""
+
+msgid "Licenses|Policy violation: denied"
+msgstr ""
+
+msgid "Licenses|Specified policies in this project"
+msgstr ""
+
+msgid "Licenses|The license list details information about the licenses used within your project."
+msgstr ""
+
+msgid "Licenses|View license details for your project"
+msgstr ""
+
+msgid "License|Buy license"
+msgstr ""
+
+msgid "License|License"
+msgstr ""
+
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
+msgid "License|You can restore access to the Gold features at any time by upgrading."
+msgstr ""
+
+msgid "License|You can start a free trial of GitLab Ultimate without any obligation or payment details."
+msgstr ""
+
+msgid "License|You do not have a license."
+msgstr ""
+
+msgid "License|Your License"
+msgstr ""
+
+msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
+msgstr ""
+
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
+msgid "Limit display of time tracking units to hours."
+msgstr ""
+
+msgid "Limit namespaces and projects that can be indexed"
+msgstr ""
+
+msgid "Limited to showing %d event at most"
+msgid_plural "Limited to showing %d events at most"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Line changes"
+msgstr ""
+
+msgid "Link Prometheus monitoring to GitLab."
+msgstr ""
+
+msgid "Link copied"
+msgstr ""
+
+msgid "Link title"
+msgstr ""
+
+msgid "Link title is required"
+msgstr ""
+
+msgid "Linked emails (%{email_count})"
+msgstr ""
+
+msgid "Linked issues"
+msgstr ""
+
+msgid "LinkedIn"
+msgstr ""
+
+msgid "LinkedPipelines|%{counterLabel} more downstream pipelines"
+msgstr ""
+
+msgid "Links"
+msgstr ""
+
+msgid "List"
+msgstr ""
+
+msgid "List Your Gitea Repositories"
+msgstr ""
+
+msgid "List available repositories"
+msgstr ""
+
+msgid "List of IPs and CIDRs of allowed secondary nodes. Comma-separated, e.g. \"1.1.1.1, 2.2.2.0/24\""
+msgstr ""
+
+msgid "List settings"
+msgstr ""
+
+msgid "List the merge requests that must be merged before this one."
+msgstr ""
+
+msgid "List view"
+msgstr ""
+
+msgid "List your Bitbucket Server repositories"
+msgstr ""
+
+msgid "Live preview"
+msgstr ""
+
+msgid "Loading"
+msgstr ""
+
+msgid "Loading contribution stats for group members"
+msgstr ""
+
+msgid "Loading files, directories, and submodules in the path %{path} for commit reference %{ref}"
+msgstr ""
+
+msgid "Loading functions timed out. Please reload the page to try again."
+msgstr ""
+
+msgid "Loading issues"
+msgstr ""
+
+msgid "Loading snippet"
+msgstr ""
+
+msgid "Loading the GitLab IDE..."
+msgstr ""
+
+msgid "Loading..."
+msgstr ""
+
+msgid "Loading…"
+msgstr ""
+
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
+msgid "Localization"
+msgstr ""
+
+msgid "Location"
+msgstr ""
+
+msgid "Lock"
+msgstr ""
+
+msgid "Lock %{issuableDisplayName}"
+msgstr ""
+
+msgid "Lock memberships to LDAP synchronization"
+msgstr ""
+
+msgid "Lock not found"
+msgstr ""
+
+msgid "Lock the discussion"
+msgstr ""
+
+msgid "Lock this %{issuableDisplayName}? Only <strong>project members</strong> will be able to comment."
+msgstr ""
+
+msgid "Lock to current projects"
+msgstr ""
+
+msgid "Locked"
+msgstr ""
+
+msgid "Locked Files"
+msgstr ""
+
+msgid "Locked by %{fileLockUserName}"
+msgstr ""
+
+msgid "Locked the discussion."
+msgstr ""
+
+msgid "Locked to current projects"
+msgstr ""
+
+msgid "Locks give the ability to lock specific file or folder."
+msgstr ""
+
+msgid "Locks the discussion."
+msgstr ""
+
+msgid "Login with smartcard"
+msgstr ""
+
+msgid "Logo was successfully removed."
+msgstr ""
+
+msgid "Logs"
+msgstr ""
+
+msgid "Logs|To see the logs, deploy your code to an environment."
+msgstr ""
+
+msgid "Low vulnerabilities present"
+msgstr ""
+
+msgid "MB"
+msgstr ""
+
+msgid "MD5"
+msgstr ""
+
+msgid "MERGED"
+msgstr ""
+
+msgid "MR widget|Take a look at our %{beginnerLinkStart}Beginner's Guide to Continuous Integration%{beginnerLinkEnd} and our %{exampleLinkStart}examples of GitLab CI/CD%{exampleLinkEnd} to see all the cool stuff you can do with it."
+msgstr ""
+
+msgid "MR widget|The pipeline will now run automatically every time you commit code. Pipelines are useful for deploying static web pages, detecting vulnerabilities in dependencies, static or dynamic application security testing (SAST and DAST), and so much more!"
+msgstr ""
+
+msgid "MRApprovals|Approvals"
+msgstr ""
+
+msgid "MRApprovals|Approved by"
+msgstr ""
+
+msgid "MRApprovals|Approvers"
+msgstr ""
+
+msgid "MRDiff|Show changes only"
+msgstr ""
+
+msgid "MRDiff|Show full file"
+msgstr ""
+
+msgid "Made this issue confidential."
+msgstr ""
+
+msgid "Maintenance mode"
+msgstr ""
+
+msgid "Make and review changes in the browser with the Web IDE"
+msgstr ""
+
+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 ""
+
+msgid "Make issue confidential"
+msgstr ""
+
+msgid "Make sure you save it - you won't be able to access it again."
+msgstr ""
+
+msgid "Make sure you're logged into the account that owns the projects you'd like to import."
+msgstr ""
+
+msgid "Make this epic confidential"
+msgstr ""
+
+msgid "Makes this issue confidential."
+msgstr ""
+
+msgid "Manage"
+msgstr ""
+
+msgid "Manage Web IDE features"
+msgstr ""
+
+msgid "Manage access"
+msgstr ""
+
+msgid "Manage all notifications"
+msgstr ""
+
+msgid "Manage applications that can use GitLab as an OAuth provider, and applications that you've authorized to use your account."
+msgstr ""
+
+msgid "Manage applications that you've authorized to use your account."
+msgstr ""
+
+msgid "Manage group labels"
+msgstr ""
+
+msgid "Manage labels"
+msgstr ""
+
+msgid "Manage milestones"
+msgstr ""
+
+msgid "Manage project labels"
+msgstr ""
+
+msgid "Manage two-factor authentication"
+msgstr ""
+
+msgid "Manage your license"
+msgstr ""
+
+msgid "Managed Account"
+msgstr ""
+
+msgid "Manifest"
+msgstr ""
+
+msgid "Manifest file import"
+msgstr ""
+
+msgid "Manual job"
+msgstr ""
+
+msgid "ManualOrdering|Couldn't save the order of the issues"
+msgstr ""
+
+msgid "Map a FogBugz account ID to a GitLab user"
+msgstr ""
+
+msgid "Map a Google Code user to a GitLab user"
+msgstr ""
+
+msgid "Map a Google Code user to a full email address"
+msgstr ""
+
+msgid "Map a Google Code user to a full name"
+msgstr ""
+
+msgid "Mar"
+msgstr ""
+
+msgid "March"
+msgstr ""
+
+msgid "Mark To Do as done"
+msgstr ""
+
+msgid "Mark as done"
+msgstr ""
+
+msgid "Mark as resolved"
+msgstr ""
+
+msgid "Mark this issue as a duplicate of another issue"
+msgstr ""
+
+msgid "Mark this issue as related to another issue"
+msgstr ""
+
+msgid "Markdown"
+msgstr ""
+
+msgid "Markdown enabled"
+msgstr ""
+
+msgid "Markdown is supported"
+msgstr ""
+
+msgid "Marked To Do as done."
+msgstr ""
+
+msgid "Marked this %{noun} as Work In Progress."
+msgstr ""
+
+msgid "Marked this issue as a duplicate of %{duplicate_param}."
+msgstr ""
+
+msgid "Marked this issue as related to %{issue_ref}."
+msgstr ""
+
+msgid "Marks To Do as done."
+msgstr ""
+
+msgid "Marks this %{noun} as Work In Progress."
+msgstr ""
+
+msgid "Marks this issue as a duplicate of %{duplicate_reference}."
+msgstr ""
+
+msgid "Marks this issue as related to %{issue_ref}."
+msgstr ""
+
+msgid "Mask variable"
+msgstr ""
+
+msgid "Match not found; try refining your search query."
+msgstr ""
+
+msgid "MattermostService|Add to Mattermost"
+msgstr ""
+
+msgid "MattermostService|Command trigger word"
+msgstr ""
+
+msgid "MattermostService|Fill in the word that works best for your team."
+msgstr ""
+
+msgid "MattermostService|Request URL"
+msgstr ""
+
+msgid "MattermostService|Request method"
+msgstr ""
+
+msgid "MattermostService|Response icon"
+msgstr ""
+
+msgid "MattermostService|Response username"
+msgstr ""
+
+msgid "MattermostService|See list of available commands in Mattermost after setting up this service, by entering"
+msgstr ""
+
+msgid "MattermostService|Suggestions:"
+msgstr ""
+
+msgid "MattermostService|This service allows users to perform common operations on this project by entering slash commands in Mattermost."
+msgstr ""
+
+msgid "Maven Metadata"
+msgstr ""
+
+msgid "Max access level"
+msgstr ""
+
+msgid "Max seats used"
+msgstr ""
+
+msgid "Maximum Users:"
+msgstr ""
+
+msgid "Maximum allowable lifetime for personal access token (days)"
+msgstr ""
+
+msgid "Maximum artifacts size (MB)"
+msgstr ""
+
+msgid "Maximum attachment size (MB)"
+msgstr ""
+
+msgid "Maximum bulk request size (MiB)"
+msgstr ""
+
+msgid "Maximum capacity"
+msgstr ""
+
+msgid "Maximum concurrency of Elasticsearch bulk requests per indexing operation."
+msgstr ""
+
+msgid "Maximum delay (Minutes)"
+msgstr ""
+
+msgid "Maximum duration of a session."
+msgstr ""
+
+msgid "Maximum field length"
+msgstr ""
+
+msgid "Maximum job timeout"
+msgstr ""
+
+msgid "Maximum job timeout has a value which could not be accepted"
+msgstr ""
+
+msgid "Maximum lifetime allowable for Personal Access Tokens is active, your expire date must be set before %{maximum_allowable_date}."
+msgstr ""
+
+msgid "Maximum namespace storage (MB)"
+msgstr ""
+
+msgid "Maximum number of %{name} (%{count}) exceeded"
+msgstr ""
+
+msgid "Maximum number of comments exceeded"
+msgstr ""
+
+msgid "Maximum number of mirrors that can be synchronizing at the same time."
+msgstr ""
+
+msgid "Maximum number of projects."
+msgstr ""
+
+msgid "Maximum page reached"
+msgstr ""
+
+msgid "Maximum push size (MB)"
+msgstr ""
+
+msgid "Maximum size limit for a single commit."
+msgstr ""
+
+msgid "Maximum size limit for each repository."
+msgstr ""
+
+msgid "Maximum size of Elasticsearch bulk indexing requests."
+msgstr ""
+
+msgid "Maximum size of individual attachments in comments."
+msgstr ""
+
+msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
+msgstr ""
+
+msgid "May"
+msgstr ""
+
+msgid "Measured in bytes of code. Excludes generated and vendored code."
+msgstr ""
+
+msgid "Median"
+msgstr ""
+
+msgid "Medium vulnerabilities present"
+msgstr ""
+
+msgid "Member lock"
+msgstr ""
+
+msgid "Member since %{date}"
+msgstr ""
+
+msgid "Members"
+msgstr ""
+
+msgid "Members can be added by project <i>Maintainers</i> or <i>Owners</i>"
+msgstr ""
+
+msgid "Members of <strong>%{project_name}</strong>"
+msgstr ""
+
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
+msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
+msgstr ""
+
+msgid "Members with pending access to %{strong_start}%{group_name}%{strong_end}"
+msgstr ""
+
+msgid "Memory Usage"
+msgstr ""
+
+msgid "Merge"
+msgstr ""
+
+msgid "Merge (when the pipeline succeeds)"
+msgstr ""
+
+msgid "Merge Request"
+msgstr ""
+
+msgid "Merge Request Approvals"
+msgstr ""
+
+msgid "Merge Request Commits"
+msgstr ""
+
+msgid "Merge Requests"
+msgstr ""
+
+msgid "Merge Requests created"
+msgstr ""
+
+msgid "Merge Requests in Review"
+msgstr ""
+
+msgid "Merge automatically (%{strategy})"
+msgstr ""
+
+msgid "Merge commit message"
+msgstr ""
+
+msgid "Merge events"
+msgstr ""
+
+msgid "Merge immediately"
+msgstr ""
+
+msgid "Merge in progress"
+msgstr ""
+
+msgid "Merge options"
+msgstr ""
+
+msgid "Merge request"
+msgstr ""
+
+msgid "Merge request %{iid} authored by %{authorName}"
+msgstr ""
+
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
+msgid "Merge request approvals"
+msgstr ""
+
+msgid "Merge request approvals allow you to set the number of necessary approvals and predefine a list of approvers that will need to approve every merge request in a project."
+msgstr ""
+
+msgid "Merge request dependencies"
+msgstr ""
+
+msgid "Merge requests"
+msgstr ""
+
+msgid "Merge requests approvals"
+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 when pipeline succeeds"
+msgstr ""
+
+msgid "MergeConflict|Commit to source branch"
+msgstr ""
+
+msgid "MergeConflict|Committing..."
+msgstr ""
+
+msgid "MergeConflict|HEAD//our changes"
+msgstr ""
+
+msgid "MergeConflict|Use ours"
+msgstr ""
+
+msgid "MergeConflict|Use theirs"
+msgstr ""
+
+msgid "MergeConflict|conflict"
+msgstr ""
+
+msgid "MergeConflict|conflicts"
+msgstr ""
+
+msgid "MergeConflict|origin//their changes"
+msgstr ""
+
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
+msgid "MergeRequests|Add a reply"
+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."
+msgstr ""
+
+msgid "MergeRequests|Jump to next unresolved thread"
+msgstr ""
+
+msgid "MergeRequests|Reply..."
+msgstr ""
+
+msgid "MergeRequests|Resolve this thread in a new issue"
+msgstr ""
+
+msgid "MergeRequests|Saving the comment failed"
+msgstr ""
+
+msgid "MergeRequests|Squash task canceled: another squash is already in progress."
+msgstr ""
+
+msgid "MergeRequests|Thread stays resolved"
+msgstr ""
+
+msgid "MergeRequests|Thread stays unresolved"
+msgstr ""
+
+msgid "MergeRequests|Thread will be resolved"
+msgstr ""
+
+msgid "MergeRequests|Thread will be unresolved"
+msgstr ""
+
+msgid "MergeRequests|Toggle comments for this file"
+msgstr ""
+
+msgid "MergeRequests|View file @ %{commitId}"
+msgstr ""
+
+msgid "MergeRequests|View replaced file @ %{commitId}"
+msgstr ""
+
+msgid "MergeRequests|commented on commit %{commitLink}"
+msgstr ""
+
+msgid "MergeRequests|started a thread"
+msgstr ""
+
+msgid "MergeRequests|started a thread on %{linkStart}an old version of the diff%{linkEnd}"
+msgstr ""
+
+msgid "MergeRequests|started a thread on %{linkStart}the diff%{linkEnd}"
+msgstr ""
+
+msgid "MergeRequests|started a thread on an outdated change in commit %{linkStart}%{commitDisplay}%{linkEnd}"
+msgstr ""
+
+msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
+msgstr ""
+
+msgid "MergeRequest|Compare %{target} and %{source}"
+msgstr ""
+
+msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
+msgstr ""
+
+msgid "MergeRequest|Error loading full diff. Please try again."
+msgstr ""
+
+msgid "MergeRequest|No files found"
+msgstr ""
+
+msgid "MergeRequest|Search files (%{modifier_key}P)"
+msgstr ""
+
+msgid "Merged"
+msgstr ""
+
+msgid "Merged MRs"
+msgstr ""
+
+msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
+msgstr ""
+
+msgid "Merged this merge request."
+msgstr ""
+
+msgid "Merges this merge request immediately."
+msgstr ""
+
+msgid "Merges this merge request when the pipeline succeeds."
+msgstr ""
+
+msgid "Merging immediately isn't recommended as it may negatively impact the existing merge train. Read the %{docsLinkStart}documentation%{docsLinkEnd} for more information."
+msgstr ""
+
+msgid "Messages"
+msgstr ""
+
+msgid "Method"
+msgstr ""
+
+msgid "Metric was successfully added."
+msgstr ""
+
+msgid "Metric was successfully updated."
+msgstr ""
+
+msgid "Metric:"
+msgstr ""
+
+msgid "MetricChart|Please select a metric"
+msgstr ""
+
+msgid "MetricChart|Selected"
+msgstr ""
+
+msgid "Metrics"
+msgstr ""
+
+msgid "Metrics - Grafana"
+msgstr ""
+
+msgid "Metrics - Prometheus"
+msgstr ""
+
+msgid "Metrics Dashboard"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
+msgstr ""
+
+msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
+msgstr ""
+
+msgid "Metrics::Dashboard::Annotation|Annotation has not been deleted"
+msgstr ""
+
+msgid "Metrics::Dashboard::Annotation|Annotation must belong to a cluster or an environment"
+msgstr ""
+
+msgid "Metrics::Dashboard::Annotation|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::Dashboard::Annotation|You are not authorized to create annotation for selected cluster"
+msgstr ""
+
+msgid "Metrics::Dashboard::Annotation|You are not authorized to create annotation for selected environment"
+msgstr ""
+
+msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
+msgstr ""
+
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
+msgid "Metrics|Add metric"
+msgstr ""
+
+msgid "Metrics|Avg"
+msgstr ""
+
+msgid "Metrics|Check out the CI/CD documentation on deploying to an environment"
+msgstr ""
+
+msgid "Metrics|Create custom dashboard %{fileName}"
+msgstr ""
+
+msgid "Metrics|Create metric"
+msgstr ""
+
+msgid "Metrics|Delete metric"
+msgstr ""
+
+msgid "Metrics|Delete metric?"
+msgstr ""
+
+msgid "Metrics|Duplicate"
+msgstr ""
+
+msgid "Metrics|Duplicate dashboard"
+msgstr ""
+
+msgid "Metrics|Duplicating..."
+msgstr ""
+
+msgid "Metrics|Edit metric"
+msgid_plural "Metrics|Edit metrics"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Metrics|Expand panel"
+msgstr ""
+
+msgid "Metrics|For grouping similar metrics"
+msgstr ""
+
+msgid "Metrics|Go back (Esc)"
+msgstr ""
+
+msgid "Metrics|Invalid time range, please verify."
+msgstr ""
+
+msgid "Metrics|Label of the y-axis (usually the unit). The x-axis always represents time."
+msgstr ""
+
+msgid "Metrics|Legend label (optional)"
+msgstr ""
+
+msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
+msgstr ""
+
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
+msgid "Metrics|Max"
+msgstr ""
+
+msgid "Metrics|Must be a valid PromQL query."
+msgstr ""
+
+msgid "Metrics|New metric"
+msgstr ""
+
+msgid "Metrics|PromQL query is valid"
+msgstr ""
+
+msgid "Metrics|Prometheus Query Documentation"
+msgstr ""
+
+msgid "Metrics|Refresh dashboard"
+msgstr ""
+
+msgid "Metrics|Star dashboard"
+msgstr ""
+
+msgid "Metrics|There was an error creating the dashboard."
+msgstr ""
+
+msgid "Metrics|There was an error creating the dashboard. %{error}"
+msgstr ""
+
+msgid "Metrics|There was an error fetching annotations. Please try again."
+msgstr ""
+
+msgid "Metrics|There was an error fetching the environments data, please try again"
+msgstr ""
+
+msgid "Metrics|There was an error getting annotations information."
+msgstr ""
+
+msgid "Metrics|There was an error getting deployment information."
+msgstr ""
+
+msgid "Metrics|There was an error getting environments information."
+msgstr ""
+
+msgid "Metrics|There was an error trying to validate your query"
+msgstr ""
+
+msgid "Metrics|There was an error while retrieving metrics"
+msgstr ""
+
+msgid "Metrics|There was an error while retrieving metrics. %{message}"
+msgstr ""
+
+msgid "Metrics|Unexpected deployment data response from prometheus endpoint"
+msgstr ""
+
+msgid "Metrics|Unit label"
+msgstr ""
+
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
+msgid "Metrics|Used as a title for the chart"
+msgstr ""
+
+msgid "Metrics|Used if the query returns a single series. If it returns multiple series, their legend labels will be picked up from the response."
+msgstr ""
+
+msgid "Metrics|Validating query"
+msgstr ""
+
+msgid "Metrics|Values"
+msgstr ""
+
+msgid "Metrics|View logs"
+msgstr ""
+
+msgid "Metrics|Y-axis label"
+msgstr ""
+
+msgid "Metrics|You can save a copy of this dashboard to your repository so it can be customized. Select a file name and branch to save it."
+msgstr ""
+
+msgid "Metrics|You're about to permanently delete this metric. This cannot be undone."
+msgstr ""
+
+msgid "Metrics|e.g. HTTP requests"
+msgstr ""
+
+msgid "Metrics|e.g. Requests/second"
+msgstr ""
+
+msgid "Metrics|e.g. Throughput"
+msgstr ""
+
+msgid "Metrics|e.g. rate(http_requests_total[5m])"
+msgstr ""
+
+msgid "Metrics|e.g. req/sec"
+msgstr ""
+
+msgid "Microsoft Azure"
+msgstr ""
+
+msgid "Middleman project with Static Site Editor support"
+msgstr ""
+
+msgid "Migrated %{success_count}/%{total_count} files."
+msgstr ""
+
+msgid "Migration successful."
+msgstr ""
+
+msgid "Milestone"
+msgid_plural "Milestones"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Milestone lists not available with your current license"
+msgstr ""
+
+msgid "Milestone lists show all issues from the selected milestone."
+msgstr ""
+
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
+msgid "Milestones"
+msgstr ""
+
+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 ""
+
+msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
+msgstr ""
+
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
+msgid "Milestones|Delete milestone"
+msgstr ""
+
+msgid "Milestones|Delete milestone %{milestoneTitle}?"
+msgstr ""
+
+msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
+msgstr ""
+
+msgid "Milestones|Group Milestone"
+msgstr ""
+
+msgid "Milestones|Milestone %{milestoneTitle} was not found"
+msgstr ""
+
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
+msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
+msgstr ""
+
+msgid "Milestones|Promote Milestone"
+msgstr ""
+
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
+msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
+msgstr ""
+
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
+msgid "Milestones|This action cannot be reversed."
+msgstr ""
+
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
+msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
+msgstr ""
+
+msgid "Minimum length is %{minimum_password_length} characters"
+msgstr ""
+
+msgid "Minimum length is %{minimum_password_length} characters."
+msgstr ""
+
+msgid "Minimum password length (number of characters)"
+msgstr ""
+
+msgid "Minutes"
+msgstr ""
+
+msgid "Mirror direction"
+msgstr ""
+
+msgid "Mirror repository"
+msgstr ""
+
+msgid "Mirror settings are only available to GitLab administrators."
+msgstr ""
+
+msgid "Mirror user"
+msgstr ""
+
+msgid "Mirrored branches will have this prefix. If you enabled 'Only mirror protected branches' you need to include this prefix on protected branches in this project or nothing will be mirrored."
+msgstr ""
+
+msgid "Mirrored repositories"
+msgstr ""
+
+msgid "Mirroring repositories"
+msgstr ""
+
+msgid "Mirroring settings were successfully updated."
+msgstr ""
+
+msgid "Mirroring settings were successfully updated. The project is being updated."
+msgstr ""
+
+msgid "Mirroring was successfully disabled."
+msgstr ""
+
+msgid "Mirroring will only be available if the feature is included in the plan of the selected group or user."
+msgstr ""
+
+msgid "Missing commit signatures endpoint!"
+msgstr ""
+
+msgid "MissingSSHKeyWarningLink|Add SSH key"
+msgstr ""
+
+msgid "MissingSSHKeyWarningLink|Don't show again"
+msgstr ""
+
+msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
+msgstr ""
+
+msgid "ModalButton|Add projects"
+msgstr ""
+
+msgid "Modal|Cancel"
+msgstr ""
+
+msgid "Modal|Close"
+msgstr ""
+
+msgid "Modified"
+msgstr ""
+
+msgid "Modified in this version"
+msgstr ""
+
+msgid "Modify commit message"
+msgstr ""
+
+msgid "Modify commit messages"
+msgstr ""
+
+msgid "Modify merge commit"
+msgstr ""
+
+msgid "Monday"
+msgstr ""
+
+msgid "Monitor your errors by integrating with Sentry."
+msgstr ""
+
+msgid "Monitoring"
+msgstr ""
+
+msgid "Months"
+msgstr ""
+
+msgid "More"
+msgstr ""
+
+msgid "More Information"
+msgstr ""
+
+msgid "More Slack commands"
+msgstr ""
+
+msgid "More actions"
+msgstr ""
+
+msgid "More details"
+msgstr ""
+
+msgid "More info"
+msgstr ""
+
+msgid "More information"
+msgstr ""
+
+msgid "More information and share feedback"
+msgstr ""
+
+msgid "More information is available|here"
+msgstr ""
+
+msgid "More than %{number_commits_distance} commits different with %{default_branch}"
+msgstr ""
+
+msgid "Most stars"
+msgstr ""
+
+msgid "Mount point %{mounted_as} not found in %{model_class}."
+msgstr ""
+
+msgid "Move"
+msgstr ""
+
+msgid "Move issue"
+msgstr ""
+
+msgid "Move issue from one column of the board to another"
+msgstr ""
+
+msgid "Move selection down"
+msgstr ""
+
+msgid "Move selection up"
+msgstr ""
+
+msgid "Move this issue to another project."
+msgstr ""
+
+msgid "MoveIssue|Cannot move issue due to insufficient permissions!"
+msgstr ""
+
+msgid "MoveIssue|Cannot move issue to project it originates from!"
+msgstr ""
+
+msgid "Moved issue to %{label} column in the board."
+msgstr ""
+
+msgid "Moved this issue to %{path_to_project}."
+msgstr ""
+
+msgid "Moves issue to %{label} column in the board."
+msgstr ""
+
+msgid "Moves this issue to %{path_to_project}."
+msgstr ""
+
+msgid "MrDeploymentActions|Deploy"
+msgstr ""
+
+msgid "MrDeploymentActions|Re-deploy"
+msgstr ""
+
+msgid "MrDeploymentActions|Stop environment"
+msgstr ""
+
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
+msgid "Multiple issue boards"
+msgstr ""
+
+msgid "Multiple model types found: %{model_types}"
+msgstr ""
+
+msgid "Multiple uploaders found: %{uploader_types}"
+msgstr ""
+
+msgid "My Awesome Group"
+msgstr ""
+
+msgid "My company or team"
+msgstr ""
+
+msgid "My-Reaction"
+msgstr ""
+
+msgid "Name"
+msgstr ""
+
+msgid "Name has already been taken"
+msgstr ""
+
+msgid "Name new label"
+msgstr ""
+
+msgid "Name:"
+msgstr ""
+
+msgid "Namespace is empty"
+msgstr ""
+
+msgid "Namespaces to index"
+msgstr ""
+
+msgid "Naming, topics, avatar"
+msgstr ""
+
+msgid "Naming, visibility"
+msgstr ""
+
+msgid "Navigate to the project to close the milestone."
+msgstr ""
+
+msgid "Nav|Help"
+msgstr ""
+
+msgid "Nav|Home"
+msgstr ""
+
+msgid "Nav|Sign In / Register"
+msgstr ""
+
+msgid "Nav|Sign out and sign in with a different account"
+msgstr ""
+
+msgid "Need help?"
+msgstr ""
+
+msgid "Needs attention"
+msgstr ""
+
+msgid "Network"
+msgstr ""
+
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
+msgid "Never"
+msgstr ""
+
+msgid "New"
+msgstr ""
+
+msgid "New Application"
+msgstr ""
+
+msgid "New Environment"
+msgstr ""
+
+msgid "New Geo Node"
+msgstr ""
+
+msgid "New Group"
+msgstr ""
+
+msgid "New Group Name"
+msgstr ""
+
+msgid "New Identity"
+msgstr ""
+
+msgid "New Issue"
+msgid_plural "New Issues"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "New Iteration"
+msgstr ""
+
+msgid "New Jira import"
+msgstr ""
+
+msgid "New Label"
+msgstr ""
+
+msgid "New Milestone"
+msgstr ""
+
+msgid "New Pages Domain"
+msgstr ""
+
+msgid "New Password"
+msgstr ""
+
+msgid "New Pipeline Schedule"
+msgstr ""
+
+msgid "New Project"
+msgstr ""
+
+msgid "New Snippet"
+msgstr ""
+
+msgid "New branch"
+msgstr ""
+
+msgid "New branch unavailable"
+msgstr ""
+
+msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
+msgstr ""
+
+msgid "New deploy key"
+msgstr ""
+
+msgid "New directory"
+msgstr ""
+
+msgid "New environment"
+msgstr ""
+
+msgid "New epic"
+msgstr ""
+
+msgid "New epic title"
+msgstr ""
+
+msgid "New file"
+msgstr ""
+
+msgid "New group"
+msgstr ""
+
+msgid "New health check access token has been generated!"
+msgstr ""
+
+msgid "New identity"
+msgstr ""
+
+msgid "New issue"
+msgstr ""
+
+msgid "New issue title"
+msgstr ""
+
+msgid "New iteration created"
+msgstr ""
+
+msgid "New label"
+msgstr ""
+
+msgid "New merge request"
+msgstr ""
+
+msgid "New milestone"
+msgstr ""
+
+msgid "New password"
+msgstr ""
+
+msgid "New pipelines will cancel older, pending pipelines on the same branch"
+msgstr ""
+
+msgid "New project"
+msgstr ""
+
+msgid "New release"
+msgstr ""
+
+msgid "New requirement"
+msgstr ""
+
+msgid "New runners registration token has been generated!"
+msgstr ""
+
+msgid "New schedule"
+msgstr ""
+
+msgid "New snippet"
+msgstr ""
+
+msgid "New subgroup"
+msgstr ""
+
+msgid "New tag"
+msgstr ""
+
+msgid "New users set to external"
+msgstr ""
+
+msgid "New! Suggest changes directly"
+msgstr ""
+
+msgid "New..."
+msgstr ""
+
+msgid "Newest first"
+msgstr ""
+
+msgid "Newly registered users will by default be external"
+msgstr ""
+
+msgid "Next"
+msgstr ""
+
+msgid "Next commit"
+msgstr ""
+
+msgid "Next file in diff"
+msgstr ""
+
+msgid "Next unresolved discussion"
+msgstr ""
+
+msgid "Nickname"
+msgstr ""
+
+msgid "No"
+msgstr ""
+
+msgid "No %{header} for this request."
+msgstr ""
+
+msgid "No %{providerTitle} repositories found"
+msgstr ""
+
+msgid "No Epic"
+msgstr ""
+
+msgid "No Scopes"
+msgstr ""
+
+msgid "No Tag"
+msgstr ""
+
+msgid "No active admin user found"
+msgstr ""
+
+msgid "No activities found"
+msgstr ""
+
+msgid "No application_settings found"
+msgstr ""
+
+msgid "No approvers"
+msgstr ""
+
+msgid "No authentication methods configured."
+msgstr ""
+
+msgid "No available namespaces to fork the project."
+msgstr ""
+
+msgid "No branches found"
+msgstr ""
+
+msgid "No changes"
+msgstr ""
+
+msgid "No changes between %{ref_start}%{source_branch}%{ref_end} and %{ref_start}%{target_branch}%{ref_end}"
+msgstr ""
+
+msgid "No child epics match applied filters"
+msgstr ""
+
+msgid "No connection could be made to a Gitaly Server, please check your logs!"
+msgstr ""
+
+msgid "No containers available"
+msgstr ""
+
+msgid "No contributions"
+msgstr ""
+
+msgid "No contributions were found"
+msgstr ""
+
+msgid "No credit card required."
+msgstr ""
+
+msgid "No data found"
+msgstr ""
+
+msgid "No data to display"
+msgstr ""
+
+msgid "No deployments found"
+msgstr ""
+
+msgid "No due date"
+msgstr ""
+
+msgid "No endpoint provided"
+msgstr ""
+
+msgid "No errors to display."
+msgstr ""
+
+msgid "No estimate or time spent"
+msgstr ""
+
+msgid "No file chosen"
+msgstr ""
+
+msgid "No file hooks found."
+msgstr ""
+
+msgid "No file selected"
+msgstr ""
+
+msgid "No files"
+msgstr ""
+
+msgid "No files found."
+msgstr ""
+
+msgid "No forks are available to you."
+msgstr ""
+
+msgid "No grouping"
+msgstr ""
+
+msgid "No job log"
+msgstr ""
+
+msgid "No jobs to show"
+msgstr ""
+
+msgid "No label"
+msgstr ""
+
+msgid "No labels with such name or description"
+msgstr ""
+
+msgid "No license. All rights reserved"
+msgstr ""
+
+msgid "No licenses found."
+msgstr ""
+
+msgid "No matches found"
+msgstr ""
+
+msgid "No matching labels"
+msgstr ""
+
+msgid "No matching results"
+msgstr ""
+
+msgid "No merge requests found"
+msgstr ""
+
+msgid "No messages were logged"
+msgstr ""
+
+msgid "No milestone"
+msgstr ""
+
+msgid "No milestones to show"
+msgstr ""
+
+msgid "No other labels with such name or description"
+msgstr ""
+
+msgid "No parent group"
+msgstr ""
+
+msgid "No pods available"
+msgstr ""
+
+msgid "No policy matches this license"
+msgstr ""
+
+msgid "No preview for this file type"
+msgstr ""
+
+msgid "No prioritized labels with such name or description"
+msgstr ""
+
+msgid "No public groups"
+msgstr ""
+
+msgid "No related merge requests found."
+msgstr ""
+
+msgid "No repository"
+msgstr ""
+
+msgid "No required pipeline"
+msgstr ""
+
+msgid "No runners found"
+msgstr ""
+
+msgid "No schedules"
+msgstr ""
+
+msgid "No starrers matched your search"
+msgstr ""
+
+msgid "No start date"
+msgstr ""
+
+msgid "No template"
+msgstr ""
+
+msgid "No test coverage"
+msgstr ""
+
+msgid "No thanks, don't show this again"
+msgstr ""
+
+msgid "No vulnerabilities present"
+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, directly import the existing email addresses and usernames."
+msgstr ""
+
+msgid "No, not interested right now"
+msgstr ""
+
+msgid "No. of commits"
+msgstr ""
+
+msgid "Nobody has starred this repository yet"
+msgstr ""
+
+msgid "Node was successfully created."
+msgstr ""
+
+msgid "Node was successfully updated."
+msgstr ""
+
+msgid "Nodes"
+msgstr ""
+
+msgid "Non-admin users can sign in with read-only access and make read-only API requests."
+msgstr ""
+
+msgid "None"
+msgstr ""
+
+msgid "Not Implemented"
+msgstr ""
+
+msgid "Not all data has been processed yet, the accuracy of the chart for the selected timeframe is limited."
+msgstr ""
+
+msgid "Not available"
+msgstr ""
+
+msgid "Not available for private projects"
+msgstr ""
+
+msgid "Not available for protected branches"
+msgstr ""
+
+msgid "Not confidential"
+msgstr ""
+
+msgid "Not enough data"
+msgstr ""
+
+msgid "Not found."
+msgstr ""
+
+msgid "Not helpful"
+msgstr ""
+
+msgid "Not now"
+msgstr ""
+
+msgid "Not ready yet. Try again later."
+msgstr ""
+
+msgid "Not started"
+msgstr ""
+
+msgid "Not-confidential epic cannot be assigned to a confidential parent epic"
+msgstr ""
+
+msgid "Note"
+msgstr ""
+
+msgid "Note parameters are invalid: %{errors}"
+msgstr ""
+
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
+msgid "Note that 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 ""
+
+msgid "Note: As an administrator you may like to configure %{github_integration_link}, which will allow login via GitHub and allow connecting repositories without generating a Personal Access Token."
+msgstr ""
+
+msgid "Note: As an administrator you may like to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
+msgstr ""
+
+msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow connecting repositories without generating a Personal Access Token."
+msgstr ""
+
+msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
+msgstr ""
+
+msgid "NoteForm|Note"
+msgstr ""
+
+msgid "Notes|Are you sure you want to cancel creating this comment?"
+msgstr ""
+
+msgid "Notes|Collapse replies"
+msgstr ""
+
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
+msgid "Notes|Show all activity"
+msgstr ""
+
+msgid "Notes|Show comments only"
+msgstr ""
+
+msgid "Notes|Show history only"
+msgstr ""
+
+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 ""
+
+msgid "Nothing found…"
+msgstr ""
+
+msgid "Nothing to preview."
+msgstr ""
+
+msgid "Nothing to synchronize"
+msgstr ""
+
+msgid "Notification events"
+msgstr ""
+
+msgid "Notification setting"
+msgstr ""
+
+msgid "Notification setting - %{notification_title}"
+msgstr ""
+
+msgid "Notification settings saved"
+msgstr ""
+
+msgid "NotificationEvent|Close issue"
+msgstr ""
+
+msgid "NotificationEvent|Close merge request"
+msgstr ""
+
+msgid "NotificationEvent|Failed pipeline"
+msgstr ""
+
+msgid "NotificationEvent|Fixed pipeline"
+msgstr ""
+
+msgid "NotificationEvent|Merge merge request"
+msgstr ""
+
+msgid "NotificationEvent|New epic"
+msgstr ""
+
+msgid "NotificationEvent|New issue"
+msgstr ""
+
+msgid "NotificationEvent|New merge request"
+msgstr ""
+
+msgid "NotificationEvent|New note"
+msgstr ""
+
+msgid "NotificationEvent|New release"
+msgstr ""
+
+msgid "NotificationEvent|Reassign issue"
+msgstr ""
+
+msgid "NotificationEvent|Reassign merge request"
+msgstr ""
+
+msgid "NotificationEvent|Reopen issue"
+msgstr ""
+
+msgid "NotificationEvent|Successful pipeline"
+msgstr ""
+
+msgid "NotificationLevel|Custom"
+msgstr ""
+
+msgid "NotificationLevel|Disabled"
+msgstr ""
+
+msgid "NotificationLevel|Global"
+msgstr ""
+
+msgid "NotificationLevel|On mention"
+msgstr ""
+
+msgid "NotificationLevel|Participate"
+msgstr ""
+
+msgid "NotificationLevel|Watch"
+msgstr ""
+
+msgid "NotificationSetting|Custom"
+msgstr ""
+
+msgid "Notifications"
+msgstr ""
+
+msgid "Notifications have been disabled by the project or group owner"
+msgstr ""
+
+msgid "Notifications off"
+msgstr ""
+
+msgid "Notifications on"
+msgstr ""
+
+msgid "Nov"
+msgstr ""
+
+msgid "November"
+msgstr ""
+
+msgid "Novice"
+msgstr ""
+
+msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
+msgstr ""
+
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
+msgid "Number of %{itemTitle}"
+msgstr ""
+
+msgid "Number of Elasticsearch replicas"
+msgstr ""
+
+msgid "Number of Elasticsearch shards"
+msgstr ""
+
+msgid "Number of LOCs per commit"
+msgstr ""
+
+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 ""
+
+msgid "Number of changes (branches or tags) in a single push to determine whether webhooks and services will be fired or not. Webhooks and services won't be submitted if it surpasses that value."
+msgstr ""
+
+msgid "Number of commits"
+msgstr ""
+
+msgid "Number of commits per MR"
+msgstr ""
+
+msgid "Number of employees"
+msgstr ""
+
+msgid "Number of files touched"
+msgstr ""
+
+msgid "OK"
+msgstr ""
+
+msgid "Object Storage replication"
+msgstr ""
+
+msgid "Object does not exist on the server or you don't have permissions to access it"
+msgstr ""
+
+msgid "Oct"
+msgstr ""
+
+msgid "October"
+msgstr ""
+
+msgid "OfSearchInADropdown|Filter"
+msgstr ""
+
+msgid "Oh no!"
+msgstr ""
+
+msgid "Ok let's go"
+msgstr ""
+
+msgid "Oldest first"
+msgstr ""
+
+msgid "OmniAuth"
+msgstr ""
+
+msgid "Omnibus Protected Paths throttle is active, and takes priority over these settings. From 12.4, Omnibus throttle is deprecated and will be removed in a future release. Please read the %{relative_url_link_start}Migrating Protected Paths documentation%{relative_url_link_end}."
+msgstr ""
+
+msgid "On track"
+msgstr ""
+
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
+msgid "Onboarding"
+msgstr ""
+
+msgid "Once imported, repositories can be mirrored over SSH. Read more %{link_start}here%{link_end}."
+msgstr ""
+
+msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
+msgstr ""
+
+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 ""
+
+msgid "Once you confirm and press \"Reduce project visibility\":"
+msgstr ""
+
+msgid "One more item"
+msgid_plural "%d more items"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "One or more groups that you don't have access to."
+msgstr ""
+
+msgid "One or more of you personal access tokens were revoked"
+msgstr ""
+
+msgid "One or more of your Bitbucket projects cannot be imported into GitLab directly because they use Subversion or Mercurial for version control, rather than Git."
+msgstr ""
+
+msgid "One or more of your Google Code projects cannot be imported into GitLab directly because they use Subversion or Mercurial for version control, rather than Git."
+msgstr ""
+
+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 ""
+
+msgid "One or more of your personal access tokens will expire in %{days_to_expire} days or less."
+msgstr ""
+
+msgid "Only 'Reporter' roles and above on tiers Premium / Silver and above can see Value Stream Analytics."
+msgstr ""
+
+msgid "Only 1 appearances row can exist"
+msgstr ""
+
+msgid "Only Issue ID or Merge Request ID is required"
+msgstr ""
+
+msgid "Only Project Members"
+msgstr ""
+
+msgid "Only active this projects shows up in the search and on the dashboard."
+msgstr ""
+
+msgid "Only admins"
+msgstr ""
+
+msgid "Only admins can delete project"
+msgstr ""
+
+msgid "Only mirror protected branches"
+msgstr ""
+
+msgid "Only policy:"
+msgstr ""
+
+msgid "Only proceed if you trust %{idp_url} to control your GitLab account sign in."
+msgstr ""
+
+msgid "Only project members can comment."
+msgstr ""
+
+msgid "Only project members will be imported. Group members will be skipped."
+msgstr ""
+
+msgid "Only verified users with an email address in any of these domains can be added to the group."
+msgstr ""
+
+msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
+msgstr ""
+
+msgid "Oops, are you sure?"
+msgstr ""
+
+msgid "Open"
+msgstr ""
+
+msgid "Open Selection"
+msgstr ""
+
+msgid "Open comment type dropdown"
+msgstr ""
+
+msgid "Open errors"
+msgstr ""
+
+msgid "Open in Xcode"
+msgstr ""
+
+msgid "Open issues"
+msgstr ""
+
+msgid "Open projects"
+msgstr ""
+
+msgid "Open raw"
+msgstr ""
+
+msgid "Open sidebar"
+msgstr ""
+
+msgid "Open: %{openIssuesCount}"
+msgstr ""
+
+msgid "Open: %{open} • Closed: %{closed}"
+msgstr ""
+
+msgid "Opened"
+msgstr ""
+
+msgid "Opened MRs"
+msgstr ""
+
+msgid "Opened issues"
+msgstr ""
+
+msgid "OpenedNDaysAgo|Opened"
+msgstr ""
+
+msgid "Opens in a new window"
+msgstr ""
+
+msgid "Operation failed. Check pod logs for %{pod_name} for more details."
+msgstr ""
+
+msgid "Operation not allowed"
+msgstr ""
+
+msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
+msgstr ""
+
+msgid "Operations"
+msgstr ""
+
+msgid "Operations Dashboard"
+msgstr ""
+
+msgid "Operations Settings"
+msgstr ""
+
+msgid "OperationsDashboard|Add a project to the dashboard"
+msgstr ""
+
+msgid "OperationsDashboard|Add projects"
+msgstr ""
+
+msgid "OperationsDashboard|More information"
+msgstr ""
+
+msgid "OperationsDashboard|Operations Dashboard"
+msgstr ""
+
+msgid "OperationsDashboard|The operations dashboard provides a summary of each project's operational health, including pipeline and alert statuses."
+msgstr ""
+
+msgid "Optional"
+msgstr ""
+
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
+msgstr ""
+
+msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
+msgstr ""
+
+msgid "Optionally, you can %{link_to_customize} how Google Code email addresses and usernames are imported into GitLab."
+msgstr ""
+
+msgid "Options"
+msgstr ""
+
+msgid "Or you can choose one of the suggested colors below"
+msgstr ""
+
+msgid "Origin"
+msgstr ""
+
+msgid "Other Labels"
+msgstr ""
+
+msgid "Other information"
+msgstr ""
+
+msgid "Other merge requests block this MR"
+msgstr ""
+
+msgid "Other visibility settings have been disabled by the administrator."
+msgstr ""
+
+msgid "Out-of-compliance with this project's policies and should be removed"
+msgstr ""
+
+msgid "Outbound requests"
+msgstr ""
+
+msgid "OutdatedBrowser|From May 2020 GitLab no longer supports Internet Explorer 11."
+msgstr ""
+
+msgid "OutdatedBrowser|GitLab may not work properly, because you are using an outdated web browser."
+msgstr ""
+
+msgid "OutdatedBrowser|Please install a %{browser_link_start}supported web browser%{browser_link_end} for a better experience."
+msgstr ""
+
+msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
+msgstr ""
+
+msgid "Outdent"
+msgstr ""
+
+msgid "Overridden"
+msgstr ""
+
+msgid "Overview"
+msgstr ""
+
+msgid "Overwrite diverged branches"
+msgstr ""
+
+msgid "Owned by anyone"
+msgstr ""
+
+msgid "Owned by me"
+msgstr ""
+
+msgid "Owner"
+msgstr ""
+
+msgid "Package Files"
+msgstr ""
+
+msgid "Package Registry"
+msgstr ""
+
+msgid "Package already exists"
+msgstr ""
+
+msgid "Package deleted successfully"
+msgstr ""
+
+msgid "Package information"
+msgstr ""
+
+msgid "Package recipe already exists"
+msgstr ""
+
+msgid "Package type must be Conan"
+msgstr ""
+
+msgid "Package type must be Maven"
+msgstr ""
+
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
+msgid "Package was removed"
+msgstr ""
+
+msgid "PackageRegistry|Add Conan Remote"
+msgstr ""
+
+msgid "PackageRegistry|Add NuGet Source"
+msgstr ""
+
+msgid "PackageRegistry|Conan"
+msgstr ""
+
+msgid "PackageRegistry|Conan Command"
+msgstr ""
+
+msgid "PackageRegistry|Copy .pypirc content"
+msgstr ""
+
+msgid "PackageRegistry|Copy Conan Command"
+msgstr ""
+
+msgid "PackageRegistry|Copy Conan Setup Command"
+msgstr ""
+
+msgid "PackageRegistry|Copy Maven XML"
+msgstr ""
+
+msgid "PackageRegistry|Copy Maven command"
+msgstr ""
+
+msgid "PackageRegistry|Copy Maven registry XML"
+msgstr ""
+
+msgid "PackageRegistry|Copy NuGet Command"
+msgstr ""
+
+msgid "PackageRegistry|Copy NuGet Setup Command"
+msgstr ""
+
+msgid "PackageRegistry|Copy Pip command"
+msgstr ""
+
+msgid "PackageRegistry|Copy and paste this inside your %{codeStart}pom.xml%{codeEnd} %{codeStart}dependencies%{codeEnd} block."
+msgstr ""
+
+msgid "PackageRegistry|Copy npm command"
+msgstr ""
+
+msgid "PackageRegistry|Copy npm setup command"
+msgstr ""
+
+msgid "PackageRegistry|Copy yarn command"
+msgstr ""
+
+msgid "PackageRegistry|Copy yarn setup command"
+msgstr ""
+
+msgid "PackageRegistry|Delete Package Version"
+msgstr ""
+
+msgid "PackageRegistry|Delete package"
+msgstr ""
+
+msgid "PackageRegistry|Filter by name"
+msgstr ""
+
+msgid "PackageRegistry|For more information on the Conan registry, %{linkStart}see the documentation%{linkEnd}."
+msgstr ""
+
+msgid "PackageRegistry|For more information on the Maven registry, %{linkStart}see the documentation%{linkEnd}."
+msgstr ""
+
+msgid "PackageRegistry|For more information on the NuGet registry, %{linkStart}see the documentation%{linkEnd}."
+msgstr ""
+
+msgid "PackageRegistry|For more information on the PyPi registry, %{linkStart}see the documentation%{linkEnd}."
+msgstr ""
+
+msgid "PackageRegistry|If you haven't already done so, you will need to add the below to your %{codeStart}.pypirc%{codeEnd} file."
+msgstr ""
+
+msgid "PackageRegistry|If you haven't already done so, you will need to add the below to your %{codeStart}pom.xml%{codeEnd} file."
+msgstr ""
+
+msgid "PackageRegistry|Installation"
+msgstr ""
+
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
+msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
+msgstr ""
+
+msgid "PackageRegistry|Manually Published"
+msgstr ""
+
+msgid "PackageRegistry|Maven"
+msgstr ""
+
+msgid "PackageRegistry|Maven Command"
+msgstr ""
+
+msgid "PackageRegistry|Maven XML"
+msgstr ""
+
+msgid "PackageRegistry|NPM"
+msgstr ""
+
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
+msgid "PackageRegistry|NuGet"
+msgstr ""
+
+msgid "PackageRegistry|NuGet Command"
+msgstr ""
+
+msgid "PackageRegistry|Pip Command"
+msgstr ""
+
+msgid "PackageRegistry|Pipeline %{linkStart}%{linkEnd} triggered %{timestamp} by %{author}"
+msgstr ""
+
+msgid "PackageRegistry|Published to the repository at %{timestamp}"
+msgstr ""
+
+msgid "PackageRegistry|PyPi"
+msgstr ""
+
+msgid "PackageRegistry|Registry Setup"
+msgstr ""
+
+msgid "PackageRegistry|Remove package"
+msgstr ""
+
+msgid "PackageRegistry|Sorry, your filter produced no results"
+msgstr ""
+
+msgid "PackageRegistry|There are no %{packageType} packages yet"
+msgstr ""
+
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
+msgid "PackageRegistry|There are no packages yet"
+msgstr ""
+
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
+msgid "PackageRegistry|There was a problem fetching the details for this package."
+msgstr ""
+
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
+msgid "PackageRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
+msgid "PackageRegistry|Unable to load package"
+msgstr ""
+
+msgid "PackageRegistry|Upcoming package managers"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
+msgstr ""
+
+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 ""
+
+msgid "PackageRegistry|published by %{author}"
+msgstr ""
+
+msgid "PackageRegistry|yarn"
+msgstr ""
+
+msgid "PackageType|Conan"
+msgstr ""
+
+msgid "PackageType|Maven"
+msgstr ""
+
+msgid "PackageType|NPM"
+msgstr ""
+
+msgid "PackageType|NuGet"
+msgstr ""
+
+msgid "PackageType|PyPi"
+msgstr ""
+
+msgid "Packages"
+msgstr ""
+
+msgid "Packages & Registries"
+msgstr ""
+
+msgid "Page not found"
+msgstr ""
+
+msgid "Page was successfully deleted"
+msgstr ""
+
+msgid "Pages"
+msgstr ""
+
+msgid "Pages Domain"
+msgstr ""
+
+msgid "Pages getting started guide"
+msgstr ""
+
+msgid "Pagination|Go to first page"
+msgstr ""
+
+msgid "Pagination|Go to last page"
+msgstr ""
+
+msgid "Pagination|Go to next page"
+msgstr ""
+
+msgid "Pagination|Go to previous page"
+msgstr ""
+
+msgid "Pagination|Last »"
+msgstr ""
+
+msgid "Pagination|Next"
+msgstr ""
+
+msgid "Pagination|Prev"
+msgstr ""
+
+msgid "Pagination|« First"
+msgstr ""
+
+msgid "Parameter"
+msgstr ""
+
+msgid "Parameter \"job_id\" cannot exceed length of %{job_id_max_size}"
+msgstr ""
+
+msgid "Parent"
+msgstr ""
+
+msgid "Parent epic doesn't exist."
+msgstr ""
+
+msgid "Parent epic is not present."
+msgstr ""
+
+msgid "Part of merge request changes"
+msgstr ""
+
+msgid "Partial token for reference only"
+msgstr ""
+
+msgid "Participants"
+msgstr ""
+
+msgid "Passed"
+msgstr ""
+
+msgid "Password"
+msgstr ""
+
+msgid "Password (optional)"
+msgstr ""
+
+msgid "Password Policy Guidelines"
+msgstr ""
+
+msgid "Password authentication is unavailable."
+msgstr ""
+
+msgid "Password confirmation"
+msgstr ""
+
+msgid "Password successfully changed"
+msgstr ""
+
+msgid "Password was successfully updated. Please login with it"
+msgstr ""
+
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
+msgid "Past due"
+msgstr ""
+
+msgid "Paste a machine public key here. Read more about how to generate it"
+msgstr ""
+
+msgid "Paste a machine public key here. Read more about how to generate it %{link_start}here%{link_end}"
+msgstr ""
+
+msgid "Paste epic link"
+msgstr ""
+
+msgid "Paste issue link"
+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'. Don't use your private SSH key."
+msgstr ""
+
+msgid "Patch to apply"
+msgstr ""
+
+msgid "Path"
+msgstr ""
+
+msgid "Path:"
+msgstr ""
+
+msgid "Paths can contain wildcards, like */welcome"
+msgstr ""
+
+msgid "Pause"
+msgstr ""
+
+msgid "Pause replication"
+msgstr ""
+
+msgid "Paused Runners don't accept new jobs"
+msgstr ""
+
+msgid "Pending"
+msgstr ""
+
+msgid "People without permission will never get a notification and won't be able to comment."
+msgstr ""
+
+msgid "People without permission will never get a notification."
+msgstr ""
+
+msgid "Percent rollout (logged in users)"
+msgstr ""
+
+msgid "Percentage"
+msgstr ""
+
+msgid "Perform advanced options such as changing path, transferring, exporting, or removing the group."
+msgstr ""
+
+msgid "Perform common operations on GitLab project"
+msgstr ""
+
+msgid "Performance optimization"
+msgstr ""
+
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
+msgid "PerformanceBar|Download"
+msgstr ""
+
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
+msgid "PerformanceBar|Frontend resources"
+msgstr ""
+
+msgid "PerformanceBar|Gitaly calls"
+msgstr ""
+
+msgid "PerformanceBar|Redis calls"
+msgstr ""
+
+msgid "PerformanceBar|Rugged calls"
+msgstr ""
+
+msgid "PerformanceBar|SQL queries"
+msgstr ""
+
+msgid "PerformanceBar|trace"
+msgstr ""
+
+msgid "Permissions"
+msgstr ""
+
+msgid "Permissions, LFS, 2FA"
+msgstr ""
+
+msgid "Personal Access Token"
+msgstr ""
+
+msgid "Personal project creation is not allowed. Please contact your administrator with questions"
+msgstr ""
+
+msgid "Phabricator Server Import"
+msgstr ""
+
+msgid "Phabricator Server URL"
+msgstr ""
+
+msgid "Phabricator Tasks"
+msgstr ""
+
+msgid "Pick a name"
+msgstr ""
+
+msgid "Pin code"
+msgstr ""
+
+msgid "Pipeline"
+msgstr ""
+
+msgid "Pipeline %{label}"
+msgstr ""
+
+msgid "Pipeline %{label} for \"%{dataTitle}\""
+msgstr ""
+
+msgid "Pipeline Schedule"
+msgstr ""
+
+msgid "Pipeline Schedules"
+msgstr ""
+
+msgid "Pipeline minutes quota"
+msgstr ""
+
+msgid "Pipeline subscriptions"
+msgstr ""
+
+msgid "Pipeline triggers"
+msgstr ""
+
+msgid "Pipeline: %{status}"
+msgstr ""
+
+msgid "PipelineCharts|CI / CD Analytics"
+msgstr ""
+
+msgid "PipelineCharts|Failed:"
+msgstr ""
+
+msgid "PipelineCharts|Overall statistics"
+msgstr ""
+
+msgid "PipelineCharts|Success ratio:"
+msgstr ""
+
+msgid "PipelineCharts|Successful:"
+msgstr ""
+
+msgid "PipelineCharts|Total:"
+msgstr ""
+
+msgid "PipelineSchedules|Activated"
+msgstr ""
+
+msgid "PipelineSchedules|Active"
+msgstr ""
+
+msgid "PipelineSchedules|All"
+msgstr ""
+
+msgid "PipelineSchedules|Inactive"
+msgstr ""
+
+msgid "PipelineSchedules|Next Run"
+msgstr ""
+
+msgid "PipelineSchedules|None"
+msgstr ""
+
+msgid "PipelineSchedules|Provide a short description for this pipeline"
+msgstr ""
+
+msgid "PipelineSchedules|Take ownership"
+msgstr ""
+
+msgid "PipelineSchedules|Target"
+msgstr ""
+
+msgid "PipelineSchedules|Variables"
+msgstr ""
+
+msgid "PipelineSheduleIntervalPattern|Custom"
+msgstr ""
+
+msgid "PipelineStatusTooltip|Pipeline: %{ciStatus}"
+msgstr ""
+
+msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
+msgstr ""
+
+msgid "Pipelines"
+msgstr ""
+
+msgid "Pipelines charts"
+msgstr ""
+
+msgid "Pipelines emails"
+msgstr ""
+
+msgid "Pipelines for last month (%{oneMonthAgo} - %{today})"
+msgstr ""
+
+msgid "Pipelines for last week (%{oneWeekAgo} - %{today})"
+msgstr ""
+
+msgid "Pipelines for last year"
+msgstr ""
+
+msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
+msgstr ""
+
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
+msgid "Pipelines settings for '%{project_name}' were successfully updated."
+msgstr ""
+
+msgid "Pipelines|API"
+msgstr ""
+
+msgid "Pipelines|Build with confidence"
+msgstr ""
+
+msgid "Pipelines|CI Lint"
+msgstr ""
+
+msgid "Pipelines|Child pipeline"
+msgstr ""
+
+msgid "Pipelines|Clear Runner Caches"
+msgstr ""
+
+msgid "Pipelines|Continuous Integration can help catch bugs by running your tests automatically, while Continuous Deployment can help you deliver code to your product environment."
+msgstr ""
+
+msgid "Pipelines|Get started with Pipelines"
+msgstr ""
+
+msgid "Pipelines|Group %{namespace_name} has %{percentage}%% or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "Pipelines|Group %{namespace_name} has exceeded its pipeline minutes quota. Unless you buy additional pipeline minutes, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "Pipelines|Loading Pipelines"
+msgstr ""
+
+msgid "Pipelines|Project cache successfully reset."
+msgstr ""
+
+msgid "Pipelines|Run Pipeline"
+msgstr ""
+
+msgid "Pipelines|Something went wrong while cleaning runners cache."
+msgstr ""
+
+msgid "Pipelines|There are currently no %{scope} pipelines."
+msgstr ""
+
+msgid "Pipelines|There are currently no pipelines."
+msgstr ""
+
+msgid "Pipelines|There was an error fetching the pipelines. Try again in a few moments or contact your support team."
+msgstr ""
+
+msgid "Pipelines|This is a child pipeline within the parent pipeline"
+msgstr ""
+
+msgid "Pipelines|This project is not currently set up to run pipelines."
+msgstr ""
+
+msgid "Pipelines|parent"
+msgstr ""
+
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
+msgid "Pipeline|Commit"
+msgstr ""
+
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
+msgstr ""
+
+msgid "Pipeline|Coverage"
+msgstr ""
+
+msgid "Pipeline|Created"
+msgstr ""
+
+msgid "Pipeline|Date"
+msgstr ""
+
+msgid "Pipeline|Detached merge request pipeline"
+msgstr ""
+
+msgid "Pipeline|Duration"
+msgstr ""
+
+msgid "Pipeline|Existing branch name or tag"
+msgstr ""
+
+msgid "Pipeline|Failed"
+msgstr ""
+
+msgid "Pipeline|Key"
+msgstr ""
+
+msgid "Pipeline|Manual"
+msgstr ""
+
+msgid "Pipeline|Merge train pipeline"
+msgstr ""
+
+msgid "Pipeline|Merged result pipeline"
+msgstr ""
+
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
+msgid "Pipeline|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Pipelines"
+msgstr ""
+
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
+msgid "Pipeline|Run Pipeline"
+msgstr ""
+
+msgid "Pipeline|Run for"
+msgstr ""
+
+msgid "Pipeline|Running"
+msgstr ""
+
+msgid "Pipeline|Search branches"
+msgstr ""
+
+msgid "Pipeline|Skipped"
+msgstr ""
+
+msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
+msgstr ""
+
+msgid "Pipeline|Stages"
+msgstr ""
+
+msgid "Pipeline|Status"
+msgstr ""
+
+msgid "Pipeline|Stop pipeline"
+msgstr ""
+
+msgid "Pipeline|Stop pipeline #%{pipelineId}?"
+msgstr ""
+
+msgid "Pipeline|Trigger author"
+msgstr ""
+
+msgid "Pipeline|Triggerer"
+msgstr ""
+
+msgid "Pipeline|Value"
+msgstr ""
+
+msgid "Pipeline|Variables"
+msgstr ""
+
+msgid "Pipeline|You’re about to stop pipeline %{pipelineId}."
+msgstr ""
+
+msgid "Pipeline|for"
+msgstr ""
+
+msgid "Pipeline|on"
+msgstr ""
+
+msgid "Pipeline|with stage"
+msgstr ""
+
+msgid "Pipeline|with stages"
+msgstr ""
+
+msgid "PivotalTrackerService|Comma-separated list of branches which will be automatically inspected. Leave blank to include all branches."
+msgstr ""
+
+msgid "PivotalTrackerService|Pivotal Tracker API token."
+msgstr ""
+
+msgid "PivotalTrackerService|Project Management Software (Source Commits Endpoint)"
+msgstr ""
+
+msgid "Plain diff"
+msgstr ""
+
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
+msgid "PlantUML"
+msgstr ""
+
+msgid "Play"
+msgstr ""
+
+msgid "Play all manual"
+msgstr ""
+
+msgid "Please %{link_to_register} or %{link_to_sign_in} to comment"
+msgstr ""
+
+msgid "Please %{startTagRegister}register%{endRegisterTag} or %{startTagSignIn}sign in%{endSignInTag} to reply"
+msgstr ""
+
+msgid "Please accept the Terms of Service before continuing."
+msgstr ""
+
+msgid "Please add a comment in the text area above"
+msgstr ""
+
+msgid "Please add a list to your board first"
+msgstr ""
+
+msgid "Please check the configuration file for this chart"
+msgstr ""
+
+msgid "Please check the configuration file to ensure that a collection of charts has been declared."
+msgstr ""
+
+msgid "Please check the configuration file to ensure that it is available and the YAML is valid"
+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 ""
+
+msgid "Please choose a group URL with no special characters."
+msgstr ""
+
+msgid "Please complete your profile with email address"
+msgstr ""
+
+msgid "Please convert them to %{link_to_git}, and go through the %{link_to_import_flow} again."
+msgstr ""
+
+msgid "Please convert them to Git on Google Code, and go through the %{link_to_import_flow} again."
+msgstr ""
+
+msgid "Please create a password for your new account."
+msgstr ""
+
+msgid "Please create a username with only alphanumeric characters."
+msgstr ""
+
+msgid "Please create an index before enabling indexing"
+msgstr ""
+
+msgid "Please enable and migrate to hashed storage to avoid security issues and ensure data integrity. %{migrate_link}"
+msgstr ""
+
+msgid "Please ensure your account's %{account_link_start}recovery settings%{account_link_end} are up to date."
+msgstr ""
+
+msgid "Please enter a non-negative number"
+msgstr ""
+
+msgid "Please enter a number greater than %{number} (from the project settings)"
+msgstr ""
+
+msgid "Please enter a valid number"
+msgstr ""
+
+msgid "Please enter or upload a license."
+msgstr ""
+
+msgid "Please fill in a descriptive name for your group."
+msgstr ""
+
+msgid "Please follow the %{link_start}Let's Encrypt troubleshooting instructions%{link_end} to re-obtain your Let's Encrypt certificate."
+msgstr ""
+
+msgid "Please follow the Let's Encrypt troubleshooting instructions to re-obtain your Let's Encrypt certificate: %{docs_url}."
+msgstr ""
+
+msgid "Please migrate all existing projects to hashed storage to avoid security issues and ensure data integrity. %{migrate_link}"
+msgstr ""
+
+msgid "Please note that this application is not provided by GitLab and you should verify its authenticity before allowing access."
+msgstr ""
+
+msgid "Please provide a name"
+msgstr ""
+
+msgid "Please provide a valid URL"
+msgstr ""
+
+msgid "Please provide a valid email address."
+msgstr ""
+
+msgid "Please refer to <a href=\"%{docs_url}\">%{docs_url}</a>"
+msgstr ""
+
+msgid "Please retype the email address."
+msgstr ""
+
+msgid "Please select"
+msgstr ""
+
+msgid "Please select a Jira project"
+msgstr ""
+
+msgid "Please select a country"
+msgstr ""
+
+msgid "Please select a file"
+msgstr ""
+
+msgid "Please select a group."
+msgstr ""
+
+msgid "Please select a valid target branch"
+msgstr ""
+
+msgid "Please select and add a member"
+msgstr ""
+
+msgid "Please select at least one filter to see results"
+msgstr ""
+
+msgid "Please set a new password before proceeding."
+msgstr ""
+
+msgid "Please solve the reCAPTCHA"
+msgstr ""
+
+msgid "Please try again"
+msgstr ""
+
+msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
+msgstr ""
+
+msgid "Please upgrade PostgreSQL to version 9.6 or greater. The status of the replication cannot be determined reliably with the current version."
+msgstr ""
+
+msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
+msgstr ""
+
+msgid "Please wait a moment, this page will automatically refresh when ready."
+msgstr ""
+
+msgid "Please wait while we connect to your repository. Refresh at will."
+msgstr ""
+
+msgid "Please wait while we import the repository for you. Refresh at will."
+msgstr ""
+
+msgid "Plugins directory is deprecated and will be removed in 14.0. Please move this file into /file_hooks directory."
+msgstr ""
+
+msgid "Pod does not exist"
+msgstr ""
+
+msgid "Pod not found"
+msgstr ""
+
+msgid "Pods in use"
+msgstr ""
+
+msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
+msgstr ""
+
+msgid "Pre-defined push rules."
+msgstr ""
+
+msgid "Preferences"
+msgstr ""
+
+msgid "Preferences saved."
+msgstr ""
+
+msgid "Preferences|Behavior"
+msgstr ""
+
+msgid "Preferences|Choose between fixed (max. 1280px) and fluid (%{percentage}) application layout."
+msgstr ""
+
+msgid "Preferences|Choose what content you want to see on a project’s overview page."
+msgstr ""
+
+msgid "Preferences|Customize integrations with third party services."
+msgstr ""
+
+msgid "Preferences|Customize the appearance of the application header and navigation sidebar."
+msgstr ""
+
+msgid "Preferences|Default dashboard"
+msgstr ""
+
+msgid "Preferences|Display time in 24-hour format"
+msgstr ""
+
+msgid "Preferences|Enable integrated code intelligence on code views"
+msgstr ""
+
+msgid "Preferences|For example: 30 mins ago."
+msgstr ""
+
+msgid "Preferences|Integrations"
+msgstr ""
+
+msgid "Preferences|Layout width"
+msgstr ""
+
+msgid "Preferences|Must be a number between %{min} and %{max}"
+msgstr ""
+
+msgid "Preferences|Navigation theme"
+msgstr ""
+
+msgid "Preferences|Project overview content"
+msgstr ""
+
+msgid "Preferences|Render whitespace characters in the Web IDE"
+msgstr ""
+
+msgid "Preferences|Show whitespace changes in diffs"
+msgstr ""
+
+msgid "Preferences|Sourcegraph"
+msgstr ""
+
+msgid "Preferences|Syntax highlighting theme"
+msgstr ""
+
+msgid "Preferences|Tab width"
+msgstr ""
+
+msgid "Preferences|These settings will update how dates and times are displayed for you."
+msgstr ""
+
+msgid "Preferences|This feature is experimental and translations are not complete yet"
+msgstr ""
+
+msgid "Preferences|This setting allows you to customize the appearance of the syntax."
+msgstr ""
+
+msgid "Preferences|This setting allows you to customize the behavior of the system layout and default views."
+msgstr ""
+
+msgid "Preferences|Time display"
+msgstr ""
+
+msgid "Preferences|Time format"
+msgstr ""
+
+msgid "Preferences|Time preferences"
+msgstr ""
+
+msgid "Preferences|Use relative times"
+msgstr ""
+
+msgid "Press %{key}-C to copy"
+msgstr ""
+
+msgid "Prev"
+msgstr ""
+
+msgid "Prevent adding new members to project membership within this group"
+msgstr ""
+
+msgid "Prevent approval of merge requests by merge request author"
+msgstr ""
+
+msgid "Prevent approval of merge requests by merge request committers"
+msgstr ""
+
+msgid "Prevent environment from auto-stopping"
+msgstr ""
+
+msgid "Prevent users from changing their profile name"
+msgstr ""
+
+msgid "Prevent users from modifying merge request approvers list"
+msgstr ""
+
+msgid "Prevent users from performing write operations on GitLab while performing maintenance."
+msgstr ""
+
+msgid "Preview"
+msgstr ""
+
+msgid "Preview Markdown"
+msgstr ""
+
+msgid "Preview changes"
+msgstr ""
+
+msgid "Preview payload"
+msgstr ""
+
+msgid "Previous Artifacts"
+msgstr ""
+
+msgid "Previous commit"
+msgstr ""
+
+msgid "Previous file in diff"
+msgstr ""
+
+msgid "Previous unresolved discussion"
+msgstr ""
+
+msgid "Primary"
+msgstr ""
+
+msgid "Prioritize"
+msgstr ""
+
+msgid "Prioritize label"
+msgstr ""
+
+msgid "Prioritized Labels"
+msgstr ""
+
+msgid "Prioritized label"
+msgstr ""
+
+msgid "Private"
+msgstr ""
+
+msgid "Private - 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 "Private - The group and its projects can only be viewed by members."
+msgstr ""
+
+msgid "Private group(s)"
+msgstr ""
+
+msgid "Private profile"
+msgstr ""
+
+msgid "Private projects Minutes cost factor"
+msgstr ""
+
+msgid "Private projects can be created in your personal namespace with:"
+msgstr ""
+
+msgid "Proceed"
+msgstr ""
+
+msgid "Productivity"
+msgstr ""
+
+msgid "Productivity Analytics"
+msgstr ""
+
+msgid "Productivity analytics can help identify the problems that are delaying your team"
+msgstr ""
+
+msgid "ProductivityAanalytics|Merge requests"
+msgstr ""
+
+msgid "ProductivityAanalytics|is earlier than the allowed minimum date"
+msgstr ""
+
+msgid "ProductivityAnalytics|Ascending"
+msgstr ""
+
+msgid "ProductivityAnalytics|Days"
+msgstr ""
+
+msgid "ProductivityAnalytics|Days to merge"
+msgstr ""
+
+msgid "ProductivityAnalytics|Descending"
+msgstr ""
+
+msgid "ProductivityAnalytics|Hours"
+msgstr ""
+
+msgid "ProductivityAnalytics|List"
+msgstr ""
+
+msgid "ProductivityAnalytics|Merge Requests"
+msgstr ""
+
+msgid "ProductivityAnalytics|Merge date"
+msgstr ""
+
+msgid "ProductivityAnalytics|Merge requests"
+msgstr ""
+
+msgid "ProductivityAnalytics|Time to merge"
+msgstr ""
+
+msgid "ProductivityAnalytics|Trendline"
+msgstr ""
+
+msgid "ProductivityAnalytics|is earlier than the given merged at after date"
+msgstr ""
+
+msgid "Profile"
+msgstr ""
+
+msgid "Profile Settings"
+msgstr ""
+
+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 ""
+
+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 ""
+
+msgid "Profiles|@username"
+msgstr ""
+
+msgid "Profiles|Account scheduled for removal."
+msgstr ""
+
+msgid "Profiles|Activate signin with one of the following services"
+msgstr ""
+
+msgid "Profiles|Active"
+msgstr ""
+
+msgid "Profiles|Add key"
+msgstr ""
+
+msgid "Profiles|Add status emoji"
+msgstr ""
+
+msgid "Profiles|Avatar cropper"
+msgstr ""
+
+msgid "Profiles|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Profiles|Bio"
+msgstr ""
+
+msgid "Profiles|Change username"
+msgstr ""
+
+msgid "Profiles|Changing your username can have unintended side effects."
+msgstr ""
+
+msgid "Profiles|Choose file..."
+msgstr ""
+
+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 ""
+
+msgid "Profiles|Clear status"
+msgstr ""
+
+msgid "Profiles|Click on icon to activate signin with one of the following services"
+msgstr ""
+
+msgid "Profiles|Commit email"
+msgstr ""
+
+msgid "Profiles|Connect"
+msgstr ""
+
+msgid "Profiles|Connected Accounts"
+msgstr ""
+
+msgid "Profiles|Current path: %{path}"
+msgstr ""
+
+msgid "Profiles|Current status"
+msgstr ""
+
+msgid "Profiles|Default notification email"
+msgstr ""
+
+msgid "Profiles|Delete Account"
+msgstr ""
+
+msgid "Profiles|Delete account"
+msgstr ""
+
+msgid "Profiles|Delete your account?"
+msgstr ""
+
+msgid "Profiles|Deleting an account has the following effects:"
+msgstr ""
+
+msgid "Profiles|Disconnect"
+msgstr ""
+
+msgid "Profiles|Do not show on profile"
+msgstr ""
+
+msgid "Profiles|Don't display activity-related personal information on your profiles"
+msgstr ""
+
+msgid "Profiles|Edit Profile"
+msgstr ""
+
+msgid "Profiles|Enter your name, so people you know can recognize you"
+msgstr ""
+
+msgid "Profiles|Expires at"
+msgstr ""
+
+msgid "Profiles|Expires:"
+msgstr ""
+
+msgid "Profiles|Feed token was successfully reset"
+msgstr ""
+
+msgid "Profiles|Full name"
+msgstr ""
+
+msgid "Profiles|Give your individual key a title"
+msgstr ""
+
+msgid "Profiles|Include private contributions on my profile"
+msgstr ""
+
+msgid "Profiles|Incoming email token was successfully reset"
+msgstr ""
+
+msgid "Profiles|Increase your account's security by enabling Two-Factor Authentication (2FA)"
+msgstr ""
+
+msgid "Profiles|Invalid password"
+msgstr ""
+
+msgid "Profiles|Invalid username"
+msgstr ""
+
+msgid "Profiles|Key"
+msgstr ""
+
+msgid "Profiles|Last used:"
+msgstr ""
+
+msgid "Profiles|Learn more"
+msgstr ""
+
+msgid "Profiles|Location"
+msgstr ""
+
+msgid "Profiles|Made a private contribution"
+msgstr ""
+
+msgid "Profiles|Main settings"
+msgstr ""
+
+msgid "Profiles|No file chosen"
+msgstr ""
+
+msgid "Profiles|Notification email"
+msgstr ""
+
+msgid "Profiles|Organization"
+msgstr ""
+
+msgid "Profiles|Path"
+msgstr ""
+
+msgid "Profiles|Position and size your new avatar"
+msgstr ""
+
+msgid "Profiles|Primary email"
+msgstr ""
+
+msgid "Profiles|Private contributions"
+msgstr ""
+
+msgid "Profiles|Profile was successfully updated"
+msgstr ""
+
+msgid "Profiles|Public Avatar"
+msgstr ""
+
+msgid "Profiles|Public email"
+msgstr ""
+
+msgid "Profiles|Remove avatar"
+msgstr ""
+
+msgid "Profiles|Set new profile picture"
+msgstr ""
+
+msgid "Profiles|Social sign-in"
+msgstr ""
+
+msgid "Profiles|Some options are unavailable for LDAP accounts"
+msgstr ""
+
+msgid "Profiles|Static object token was successfully reset"
+msgstr ""
+
+msgid "Profiles|Tell us about yourself in fewer than 250 characters"
+msgstr ""
+
+msgid "Profiles|The ability to update your name has been disabled by your administrator."
+msgstr ""
+
+msgid "Profiles|The maximum file size allowed is 200KB."
+msgstr ""
+
+msgid "Profiles|This doesn't look like a public SSH key, are you sure you want to add it?"
+msgstr ""
+
+msgid "Profiles|This email will be displayed on your public profile"
+msgstr ""
+
+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 ""
+
+msgid "Profiles|This emoji and message will appear on your profile and throughout the interface."
+msgstr ""
+
+msgid "Profiles|This information will appear on your profile"
+msgstr ""
+
+msgid "Profiles|Time settings"
+msgstr ""
+
+msgid "Profiles|Two-Factor Authentication"
+msgstr ""
+
+msgid "Profiles|Type your %{confirmationValue} to confirm:"
+msgstr ""
+
+msgid "Profiles|Typically starts with \"ssh-ed25519 …\" or \"ssh-rsa …\""
+msgstr ""
+
+msgid "Profiles|Update profile settings"
+msgstr ""
+
+msgid "Profiles|Update username"
+msgstr ""
+
+msgid "Profiles|Upload new avatar"
+msgstr ""
+
+msgid "Profiles|Use a private email - %{email}"
+msgstr ""
+
+msgid "Profiles|User ID"
+msgstr ""
+
+msgid "Profiles|Username change failed - %{message}"
+msgstr ""
+
+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|What's your status?"
+msgstr ""
+
+msgid "Profiles|Who you represent or work for"
+msgstr ""
+
+msgid "Profiles|You can change your avatar here"
+msgstr ""
+
+msgid "Profiles|You can change your avatar here or remove the current avatar to revert to %{gravatar_link}"
+msgstr ""
+
+msgid "Profiles|You can set your current timezone here"
+msgstr ""
+
+msgid "Profiles|You can upload your avatar here"
+msgstr ""
+
+msgid "Profiles|You can upload your avatar here or change it at %{gravatar_link}"
+msgstr ""
+
+msgid "Profiles|You don't have access to delete this user."
+msgstr ""
+
+msgid "Profiles|You must transfer ownership or delete these groups before you can delete your account."
+msgstr ""
+
+msgid "Profiles|Your LinkedIn profile name from linkedin.com/in/profilename"
+msgstr ""
+
+msgid "Profiles|Your account is currently an owner in these groups:"
+msgstr ""
+
+msgid "Profiles|Your email address was automatically set based on your %{provider_label} account"
+msgstr ""
+
+msgid "Profiles|Your key has expired"
+msgstr ""
+
+msgid "Profiles|Your location was automatically set based on your %{provider_label} account"
+msgstr ""
+
+msgid "Profiles|Your name was automatically set based on your %{provider_label} account, so people you know can recognize you"
+msgstr ""
+
+msgid "Profiles|Your status"
+msgstr ""
+
+msgid "Profiles|e.g. My MacBook key"
+msgstr ""
+
+msgid "Profiles|username"
+msgstr ""
+
+msgid "Profiles|website.com"
+msgstr ""
+
+msgid "Profiles|your account"
+msgstr ""
+
+msgid "Profile|%{job_title} at %{organization}"
+msgstr ""
+
+msgid "Profiling - Performance bar"
+msgstr ""
+
+msgid "Programming languages used in this repository"
+msgstr ""
+
+msgid "Progress"
+msgstr ""
+
+msgid "Project"
+msgstr ""
+
+msgid "Project \"%{name}\" is no longer available. Select another project to continue."
+msgstr ""
+
+msgid "Project %{project_repo} could not be found"
+msgstr ""
+
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
+msgid "Project '%{project_name}' is being imported."
+msgstr ""
+
+msgid "Project '%{project_name}' is in the process of being deleted."
+msgstr ""
+
+msgid "Project '%{project_name}' is restored."
+msgstr ""
+
+msgid "Project '%{project_name}' queued for deletion."
+msgstr ""
+
+msgid "Project '%{project_name}' was successfully created."
+msgstr ""
+
+msgid "Project '%{project_name}' was successfully updated."
+msgstr ""
+
+msgid "Project '%{project_name}' will be deleted on %{date}"
+msgstr ""
+
+msgid "Project Access Tokens"
+msgstr ""
+
+msgid "Project Audit Events"
+msgstr ""
+
+msgid "Project Badges"
+msgstr ""
+
+msgid "Project Files"
+msgstr ""
+
+msgid "Project ID"
+msgstr ""
+
+msgid "Project URL"
+msgstr ""
+
+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 ""
+
+msgid "Project already deleted"
+msgstr ""
+
+msgid "Project and wiki repositories"
+msgstr ""
+
+msgid "Project avatar"
+msgstr ""
+
+msgid "Project cannot be shared with the group it is in or one of its ancestors."
+msgstr ""
+
+msgid "Project clone URL"
+msgstr ""
+
+msgid "Project configuration, including services"
+msgstr ""
+
+msgid "Project description (optional)"
+msgstr ""
+
+msgid "Project details"
+msgstr ""
+
+msgid "Project does not exist or you don't have permission to perform this action"
+msgstr ""
+
+msgid "Project export could not be deleted."
+msgstr ""
+
+msgid "Project export enabled"
+msgstr ""
+
+msgid "Project export has been deleted."
+msgstr ""
+
+msgid "Project export link has expired. Please generate a new export from your project settings."
+msgstr ""
+
+msgid "Project export started. A download link will be sent by email and made available on this page."
+msgstr ""
+
+msgid "Project has too many %{label_for_message} to search"
+msgstr ""
+
+msgid "Project members"
+msgstr ""
+
+msgid "Project milestone"
+msgstr ""
+
+msgid "Project name"
+msgstr ""
+
+msgid "Project name suffix"
+msgstr ""
+
+msgid "Project name suffix is a user-defined string which will be appended to the project path, and will form the Service Desk email address."
+msgstr ""
+
+msgid "Project order will not be saved as local storage is not available."
+msgstr ""
+
+msgid "Project overview"
+msgstr ""
+
+msgid "Project path"
+msgstr ""
+
+msgid "Project scanning help page"
+msgstr ""
+
+msgid "Project security status"
+msgstr ""
+
+msgid "Project security status help page"
+msgstr ""
+
+msgid "Project slug"
+msgstr ""
+
+msgid "Project uploads"
+msgstr ""
+
+msgid "Project visibility level will be changed to match namespace rules when transferring to a group."
+msgstr ""
+
+msgid "Project: %{name}"
+msgstr ""
+
+msgid "ProjectActivityRSS|Subscribe"
+msgstr ""
+
+msgid "ProjectCreationLevel|Allowed to create projects"
+msgstr ""
+
+msgid "ProjectCreationLevel|Default project creation protection"
+msgstr ""
+
+msgid "ProjectCreationLevel|Developers + Maintainers"
+msgstr ""
+
+msgid "ProjectCreationLevel|Maintainers"
+msgstr ""
+
+msgid "ProjectCreationLevel|No one"
+msgstr ""
+
+msgid "ProjectFileTree|Name"
+msgstr ""
+
+msgid "ProjectLastActivity|Never"
+msgstr ""
+
+msgid "ProjectLifecycle|Stage"
+msgstr ""
+
+msgid "ProjectOverview|Fork"
+msgstr ""
+
+msgid "ProjectOverview|Forks"
+msgstr ""
+
+msgid "ProjectOverview|Go to your fork"
+msgstr ""
+
+msgid "ProjectOverview|Star"
+msgstr ""
+
+msgid "ProjectOverview|Starrer"
+msgstr ""
+
+msgid "ProjectOverview|Starrers"
+msgstr ""
+
+msgid "ProjectOverview|Unstar"
+msgstr ""
+
+msgid "ProjectOverview|You have reached your project limit"
+msgstr ""
+
+msgid "ProjectOverview|You must sign in to star a project"
+msgstr ""
+
+msgid "ProjectPage|Project ID: %{project_id}"
+msgstr ""
+
+msgid "ProjectSelect| or group"
+msgstr ""
+
+msgid "ProjectSelect|Search for project"
+msgstr ""
+
+msgid "ProjectService|%{service_title}: status off"
+msgstr ""
+
+msgid "ProjectService|%{service_title}: status on"
+msgstr ""
+
+msgid "ProjectService|Comment"
+msgstr ""
+
+msgid "ProjectService|Comment will be posted on each event"
+msgstr ""
+
+msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
+msgstr ""
+
+msgid "ProjectService|To set up this service:"
+msgstr ""
+
+msgid "ProjectSettings|Additional merge request capabilities that influence how and when merges will be performed"
+msgstr ""
+
+msgid "ProjectSettings|All discussions must be resolved"
+msgstr ""
+
+msgid "ProjectSettings|Allow users to make copies of your repository to a new project"
+msgstr ""
+
+msgid "ProjectSettings|Allow users to request access"
+msgstr ""
+
+msgid "ProjectSettings|Automatically resolve merge request diff discussions when they become outdated"
+msgstr ""
+
+msgid "ProjectSettings|Badges"
+msgstr ""
+
+msgid "ProjectSettings|Build, test, and deploy your changes"
+msgstr ""
+
+msgid "ProjectSettings|Choose your merge method, merge options, merge checks, and merge suggestions."
+msgstr ""
+
+msgid "ProjectSettings|Choose your merge method, merge options, merge checks, merge suggestions, and set up a default description template for merge requests."
+msgstr ""
+
+msgid "ProjectSettings|Contact an admin to change this setting."
+msgstr ""
+
+msgid "ProjectSettings|Container registry"
+msgstr ""
+
+msgid "ProjectSettings|Customize your project badges."
+msgstr ""
+
+msgid "ProjectSettings|Disable email notifications"
+msgstr ""
+
+msgid "ProjectSettings|Enable 'Delete source branch' option by default"
+msgstr ""
+
+msgid "ProjectSettings|Every merge creates a merge commit"
+msgstr ""
+
+msgid "ProjectSettings|Every project can have its own space to store its Docker images"
+msgstr ""
+
+msgid "ProjectSettings|Every project can have its own space to store its packages"
+msgstr ""
+
+msgid "ProjectSettings|Everyone"
+msgstr ""
+
+msgid "ProjectSettings|Existing merge requests and protected branches are not affected"
+msgstr ""
+
+msgid "ProjectSettings|Failed to protect the tag"
+msgstr ""
+
+msgid "ProjectSettings|Failed to update tag!"
+msgstr ""
+
+msgid "ProjectSettings|Fast-forward merge"
+msgstr ""
+
+msgid "ProjectSettings|Fast-forward merges only"
+msgstr ""
+
+msgid "ProjectSettings|Forks"
+msgstr ""
+
+msgid "ProjectSettings|Git Large File Storage"
+msgstr ""
+
+msgid "ProjectSettings|Internal"
+msgstr ""
+
+msgid "ProjectSettings|Issues"
+msgstr ""
+
+msgid "ProjectSettings|LFS objects from this repository are still available to forks. %{linkStart}How do I remove them?%{linkEnd}"
+msgstr ""
+
+msgid "ProjectSettings|Learn more about badges."
+msgstr ""
+
+msgid "ProjectSettings|Lightweight issue tracking system for this project"
+msgstr ""
+
+msgid "ProjectSettings|Manages large files such as audio, video, and graphics files"
+msgstr ""
+
+msgid "ProjectSettings|Merge checks"
+msgstr ""
+
+msgid "ProjectSettings|Merge commit"
+msgstr ""
+
+msgid "ProjectSettings|Merge commit with semi-linear history"
+msgstr ""
+
+msgid "ProjectSettings|Merge method"
+msgstr ""
+
+msgid "ProjectSettings|Merge options"
+msgstr ""
+
+msgid "ProjectSettings|Merge pipelines will try to validate the post-merge result prior to merging"
+msgstr ""
+
+msgid "ProjectSettings|Merge requests"
+msgstr ""
+
+msgid "ProjectSettings|Merge suggestions"
+msgstr ""
+
+msgid "ProjectSettings|No merge commits are created"
+msgstr ""
+
+msgid "ProjectSettings|Note: the container registry is always visible when a project is public"
+msgstr ""
+
+msgid "ProjectSettings|Only signed commits can be pushed to this repository."
+msgstr ""
+
+msgid "ProjectSettings|Packages"
+msgstr ""
+
+msgid "ProjectSettings|Pages"
+msgstr ""
+
+msgid "ProjectSettings|Pages for project documentation"
+msgstr ""
+
+msgid "ProjectSettings|Pipelines"
+msgstr ""
+
+msgid "ProjectSettings|Pipelines must succeed"
+msgstr ""
+
+msgid "ProjectSettings|Pipelines need to be configured to enable this feature."
+msgstr ""
+
+msgid "ProjectSettings|Private"
+msgstr ""
+
+msgid "ProjectSettings|Project visibility"
+msgstr ""
+
+msgid "ProjectSettings|Public"
+msgstr ""
+
+msgid "ProjectSettings|Repository"
+msgstr ""
+
+msgid "ProjectSettings|Share code pastes with others out of Git repository"
+msgstr ""
+
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
+msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
+msgstr ""
+
+msgid "ProjectSettings|Snippets"
+msgstr ""
+
+msgid "ProjectSettings|Submit changes to be merged upstream"
+msgstr ""
+
+msgid "ProjectSettings|The commit message used to apply merge request suggestions"
+msgstr ""
+
+msgid "ProjectSettings|The variables GitLab supports:"
+msgstr ""
+
+msgid "ProjectSettings|These checks must pass before merge requests can be merged"
+msgstr ""
+
+msgid "ProjectSettings|This setting is applied on the server level and can be overridden by an admin."
+msgstr ""
+
+msgid "ProjectSettings|This setting is applied on the server level but has been overridden for this project."
+msgstr ""
+
+msgid "ProjectSettings|This setting will be applied to all projects unless overridden by an admin."
+msgstr ""
+
+msgid "ProjectSettings|This setting will override user notification preferences for all project members."
+msgstr ""
+
+msgid "ProjectSettings|This will dictate the commit history when you merge a merge request"
+msgstr ""
+
+msgid "ProjectSettings|Users can only push commits to this repository that were committed with one of their own verified emails."
+msgstr ""
+
+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 ""
+
+msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
+msgstr ""
+
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
+msgid "ProjectSettings|Wiki"
+msgstr ""
+
+msgid "ProjectSettings|With GitLab Pages you can host your static websites on GitLab"
+msgstr ""
+
+msgid "ProjectSettings|With Metrics Dashboard you can visualize this project performance metrics"
+msgstr ""
+
+msgid "ProjectTemplates|.NET Core"
+msgstr ""
+
+msgid "ProjectTemplates|Android"
+msgstr ""
+
+msgid "ProjectTemplates|GitLab Cluster Management"
+msgstr ""
+
+msgid "ProjectTemplates|Go Micro"
+msgstr ""
+
+msgid "ProjectTemplates|HIPAA Audit Protocol"
+msgstr ""
+
+msgid "ProjectTemplates|Netlify/GitBook"
+msgstr ""
+
+msgid "ProjectTemplates|Netlify/Hexo"
+msgstr ""
+
+msgid "ProjectTemplates|Netlify/Hugo"
+msgstr ""
+
+msgid "ProjectTemplates|Netlify/Jekyll"
+msgstr ""
+
+msgid "ProjectTemplates|Netlify/Plain HTML"
+msgstr ""
+
+msgid "ProjectTemplates|NodeJS Express"
+msgstr ""
+
+msgid "ProjectTemplates|Pages/Gatsby"
+msgstr ""
+
+msgid "ProjectTemplates|Pages/GitBook"
+msgstr ""
+
+msgid "ProjectTemplates|Pages/Hexo"
+msgstr ""
+
+msgid "ProjectTemplates|Pages/Hugo"
+msgstr ""
+
+msgid "ProjectTemplates|Pages/Jekyll"
+msgstr ""
+
+msgid "ProjectTemplates|Pages/Plain HTML"
+msgstr ""
+
+msgid "ProjectTemplates|Ruby on Rails"
+msgstr ""
+
+msgid "ProjectTemplates|SalesforceDX"
+msgstr ""
+
+msgid "ProjectTemplates|Serverless Framework/JS"
+msgstr ""
+
+msgid "ProjectTemplates|Spring"
+msgstr ""
+
+msgid "ProjectTemplates|Static Site Editor/Middleman"
+msgstr ""
+
+msgid "ProjectTemplates|iOS (Swift)"
+msgstr ""
+
+msgid "Projects"
+msgstr ""
+
+msgid "Projects (%{count})"
+msgstr ""
+
+msgid "Projects Successfully Retrieved"
+msgstr ""
+
+msgid "Projects are graded based on the highest severity vulnerability present"
+msgstr ""
+
+msgid "Projects shared with %{group_name}"
+msgstr ""
+
+msgid "Projects that belong to a group are prefixed with the group namespace. Existing projects may be moved into a group."
+msgstr ""
+
+msgid "Projects to index"
+msgstr ""
+
+msgid "Projects with critical vulnerabilities"
+msgstr ""
+
+msgid "Projects with high or unknown vulnerabilities"
+msgstr ""
+
+msgid "Projects with low vulnerabilities"
+msgstr ""
+
+msgid "Projects with medium vulnerabilities"
+msgstr ""
+
+msgid "Projects with no vulnerabilities and security scanning enabled"
+msgstr ""
+
+msgid "Projects with write access"
+msgstr ""
+
+msgid "ProjectsDropdown|Frequently visited"
+msgstr ""
+
+msgid "ProjectsDropdown|Loading projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Projects you visit often will appear here"
+msgstr ""
+
+msgid "ProjectsDropdown|Search your projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Something went wrong on our end."
+msgstr ""
+
+msgid "ProjectsDropdown|Sorry, no projects matched your search"
+msgstr ""
+
+msgid "ProjectsDropdown|This feature requires browser localStorage support"
+msgstr ""
+
+msgid "ProjectsNew|Allows you to immediately clone this project’s repository. Skip this if you plan to push up an existing repository."
+msgstr ""
+
+msgid "ProjectsNew|Blank"
+msgstr ""
+
+msgid "ProjectsNew|Blank project"
+msgstr ""
+
+msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
+msgstr ""
+
+msgid "ProjectsNew|Create"
+msgstr ""
+
+msgid "ProjectsNew|Create from template"
+msgstr ""
+
+msgid "ProjectsNew|Creating project & repository."
+msgstr ""
+
+msgid "ProjectsNew|Description format"
+msgstr ""
+
+msgid "ProjectsNew|Import"
+msgstr ""
+
+msgid "ProjectsNew|Import project"
+msgstr ""
+
+msgid "ProjectsNew|Initialize repository with a README"
+msgstr ""
+
+msgid "ProjectsNew|No import options available"
+msgstr ""
+
+msgid "ProjectsNew|Please wait a moment, this page will automatically refresh when ready."
+msgstr ""
+
+msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
+msgstr ""
+
+msgid "ProjectsNew|Template"
+msgstr ""
+
+msgid "ProjectsNew|Visibility Level"
+msgstr ""
+
+msgid "ProjectsNew|Want to house several dependent projects under the same namespace? %{link_start}Create a group.%{link_end}"
+msgstr ""
+
+msgid "Prometheus"
+msgstr ""
+
+msgid "PrometheusAlerts|%{count} alerts applied"
+msgstr ""
+
+msgid "PrometheusAlerts|%{firingCount} firing"
+msgstr ""
+
+msgid "PrometheusAlerts|Add alert"
+msgstr ""
+
+msgid "PrometheusAlerts|Edit alert"
+msgstr ""
+
+msgid "PrometheusAlerts|Error creating alert"
+msgstr ""
+
+msgid "PrometheusAlerts|Error deleting alert"
+msgstr ""
+
+msgid "PrometheusAlerts|Error fetching alert"
+msgstr ""
+
+msgid "PrometheusAlerts|Error saving alert"
+msgstr ""
+
+msgid "PrometheusAlerts|Firing: %{alerts}"
+msgstr ""
+
+msgid "PrometheusAlerts|Firing: %{alert}"
+msgstr ""
+
+msgid "PrometheusAlerts|Operator"
+msgstr ""
+
+msgid "PrometheusAlerts|Select query"
+msgstr ""
+
+msgid "PrometheusAlerts|Threshold"
+msgstr ""
+
+msgid "PrometheusService|%{exporters} with %{metrics} were found"
+msgstr ""
+
+msgid "PrometheusService|<p class=\"text-tertiary\">No <a href=\"%{docsUrl}\">common metrics</a> were found</p>"
+msgstr ""
+
+msgid "PrometheusService|Active"
+msgstr ""
+
+msgid "PrometheusService|Auto configuration"
+msgstr ""
+
+msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
+msgstr ""
+
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
+msgid "PrometheusService|Common metrics"
+msgstr ""
+
+msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
+msgstr ""
+
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
+msgid "PrometheusService|Custom metrics"
+msgstr ""
+
+msgid "PrometheusService|Custom metrics require Prometheus installed on a cluster with environment scope \"*\" OR a manually configured Prometheus to be available."
+msgstr ""
+
+msgid "PrometheusService|Enable Prometheus to define custom metrics, using either option above"
+msgstr ""
+
+msgid "PrometheusService|Finding and configuring metrics..."
+msgstr ""
+
+msgid "PrometheusService|Finding custom metrics..."
+msgstr ""
+
+msgid "PrometheusService|Install Prometheus on clusters"
+msgstr ""
+
+msgid "PrometheusService|Manage clusters"
+msgstr ""
+
+msgid "PrometheusService|Manual configuration"
+msgstr ""
+
+msgid "PrometheusService|Metrics"
+msgstr ""
+
+msgid "PrometheusService|Missing environment variable"
+msgstr ""
+
+msgid "PrometheusService|More information"
+msgstr ""
+
+msgid "PrometheusService|New metric"
+msgstr ""
+
+msgid "PrometheusService|No custom metrics have been created. Create one using the button above"
+msgstr ""
+
+msgid "PrometheusService|Prometheus API Base URL, like http://prometheus.example.com/"
+msgstr ""
+
+msgid "PrometheusService|Prometheus is being automatically managed on your clusters"
+msgstr ""
+
+msgid "PrometheusService|Select the Active checkbox to override the Auto Configuration with custom settings. If unchecked, Auto Configuration settings are used."
+msgstr ""
+
+msgid "PrometheusService|These metrics will only be monitored after your first deployment to an environment"
+msgstr ""
+
+msgid "PrometheusService|Time-series monitoring service"
+msgstr ""
+
+msgid "PrometheusService|To enable the installation of Prometheus on your clusters, deactivate the manual configuration below"
+msgstr ""
+
+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 has been deprecated."
+msgstr ""
+
+msgid "Promote"
+msgstr ""
+
+msgid "Promote confidential issue to a non-confidential epic"
+msgstr ""
+
+msgid "Promote issue to an epic"
+msgstr ""
+
+msgid "Promote these project milestones into a group milestone."
+msgstr ""
+
+msgid "Promote to group label"
+msgstr ""
+
+msgid "PromoteMilestone|Only project milestones can be promoted."
+msgstr ""
+
+msgid "PromoteMilestone|Project does not belong to a group."
+msgstr ""
+
+msgid "PromoteMilestone|Promotion failed - %{message}"
+msgstr ""
+
+msgid "Promoted confidential issue to a non-confidential epic. Information in this issue is no longer confidential as epics are public to group members."
+msgstr ""
+
+msgid "Promoted issue to an epic."
+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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
+msgid "Promotions|Don't show me this again"
+msgstr ""
+
+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 ""
+
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Learn more"
+msgstr ""
+
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
+msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
+msgstr ""
+
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
+msgid "Promotions|This feature is locked."
+msgstr ""
+
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
+msgid "Promotions|Upgrade plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
+msgid "Promotions|Weighting your issue"
+msgstr ""
+
+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 ""
+
+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 ""
+
+msgid "Prompt users to upload SSH keys"
+msgstr ""
+
+msgid "Protect variable"
+msgstr ""
+
+msgid "Protected"
+msgstr ""
+
+msgid "Protected Branch"
+msgstr ""
+
+msgid "Protected Environment"
+msgstr ""
+
+msgid "Protected Environments"
+msgstr ""
+
+msgid "Protected Paths"
+msgstr ""
+
+msgid "Protected Tag"
+msgstr ""
+
+msgid "Protected branches"
+msgstr ""
+
+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 ""
+
+msgid "ProtectedBranch|Allowed to merge"
+msgstr ""
+
+msgid "ProtectedBranch|Allowed to merge:"
+msgstr ""
+
+msgid "ProtectedBranch|Allowed to push"
+msgstr ""
+
+msgid "ProtectedBranch|Allowed to push:"
+msgstr ""
+
+msgid "ProtectedBranch|Branch"
+msgstr ""
+
+msgid "ProtectedBranch|Code owner approval"
+msgstr ""
+
+msgid "ProtectedBranch|Protect"
+msgstr ""
+
+msgid "ProtectedBranch|Protect a branch"
+msgstr ""
+
+msgid "ProtectedBranch|Protected branch (%{protected_branches_count})"
+msgstr ""
+
+msgid "ProtectedBranch|Pushes that change filenames matched by the CODEOWNERS file will be rejected"
+msgstr ""
+
+msgid "ProtectedBranch|Require approval from code owners:"
+msgstr ""
+
+msgid "ProtectedBranch|There are currently no protected branches, protect a branch with the form above."
+msgstr ""
+
+msgid "ProtectedBranch|Toggle code owner approval"
+msgstr ""
+
+msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
+msgstr ""
+
+msgid "ProtectedEnvironment|Allowed to deploy"
+msgstr ""
+
+msgid "ProtectedEnvironment|Environment"
+msgstr ""
+
+msgid "ProtectedEnvironment|Protect"
+msgstr ""
+
+msgid "ProtectedEnvironment|Protect an environment"
+msgstr ""
+
+msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
+msgstr ""
+
+msgid "ProtectedEnvironment|Protecting an environment restricts the users who can execute deployments."
+msgstr ""
+
+msgid "ProtectedEnvironment|Select an environment"
+msgstr ""
+
+msgid "ProtectedEnvironment|Select users"
+msgstr ""
+
+msgid "ProtectedEnvironment|Select users to deploy and manage Feature Flag settings"
+msgstr ""
+
+msgid "ProtectedEnvironment|There are currently no protected environments, protect an environment with the form above."
+msgstr ""
+
+msgid "ProtectedEnvironment|Unprotect"
+msgstr ""
+
+msgid "ProtectedEnvironment|Your environment can't be unprotected"
+msgstr ""
+
+msgid "ProtectedEnvironment|Your environment has been protected."
+msgstr ""
+
+msgid "ProtectedEnvironment|Your environment has been unprotected"
+msgstr ""
+
+msgid "Protip:"
+msgstr ""
+
+msgid "Protocol"
+msgstr ""
+
+msgid "Provider"
+msgstr ""
+
+msgid "Pseudonymizer data collection"
+msgstr ""
+
+msgid "Public"
+msgstr ""
+
+msgid "Public - The group and any public projects can be viewed without any authentication."
+msgstr ""
+
+msgid "Public - The project can be accessed without any authentication."
+msgstr ""
+
+msgid "Public deploy keys (%{deploy_keys_count})"
+msgstr ""
+
+msgid "Public pipelines"
+msgstr ""
+
+msgid "Public projects Minutes cost factor"
+msgstr ""
+
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
+msgid "Pull"
+msgstr ""
+
+msgid "Pull requests from fork are not supported"
+msgstr ""
+
+msgid "Puma is running with a thread count above 1 and the Rugged service is enabled. This may decrease performance in some environments. See our %{link_start}documentation%{link_end} for details of this issue."
+msgstr ""
+
+msgid "Purchase more minutes"
+msgstr ""
+
+msgid "Push"
+msgstr ""
+
+msgid "Push Rule updated successfully."
+msgstr ""
+
+msgid "Push Rules"
+msgstr ""
+
+msgid "Push Rules updated successfully."
+msgstr ""
+
+msgid "Push an existing Git repository"
+msgstr ""
+
+msgid "Push an existing folder"
+msgstr ""
+
+msgid "Push events"
+msgstr ""
+
+msgid "Push project from command line"
+msgstr ""
+
+msgid "Push to create a project"
+msgstr ""
+
+msgid "PushRule|Committer restriction"
+msgstr ""
+
+msgid "Pushed"
+msgstr ""
+
+msgid "Pushes"
+msgstr ""
+
+msgid "PushoverService|%{user_name} deleted branch \"%{ref}\"."
+msgstr ""
+
+msgid "PushoverService|%{user_name} push to branch \"%{ref}\"."
+msgstr ""
+
+msgid "PushoverService|%{user_name} pushed new branch \"%{ref}\"."
+msgstr ""
+
+msgid "PushoverService|High Priority"
+msgstr ""
+
+msgid "PushoverService|Leave blank for all active devices"
+msgstr ""
+
+msgid "PushoverService|Low Priority"
+msgstr ""
+
+msgid "PushoverService|Lowest Priority"
+msgstr ""
+
+msgid "PushoverService|Normal Priority"
+msgstr ""
+
+msgid "PushoverService|Pushover makes it easy to get real-time notifications on your Android device, iPhone, iPad, and Desktop."
+msgstr ""
+
+msgid "PushoverService|See project %{project_full_name}"
+msgstr ""
+
+msgid "PushoverService|Total commits count: %{total_commits_count}"
+msgstr ""
+
+msgid "PushoverService|Your application key"
+msgstr ""
+
+msgid "PushoverService|Your user key"
+msgstr ""
+
+msgid "Quarters"
+msgstr ""
+
+msgid "Query"
+msgstr ""
+
+msgid "Query cannot be processed"
+msgstr ""
+
+msgid "Query is valid"
+msgstr ""
+
+msgid "Queued"
+msgstr ""
+
+msgid "Quick actions"
+msgstr ""
+
+msgid "Quick actions can be used in the issues description and comment boxes."
+msgstr ""
+
+msgid "Quick range"
+msgstr ""
+
+msgid "README"
+msgstr ""
+
+msgid "Raw blob request rate limit per minute"
+msgstr ""
+
+msgid "Re-authentication period expired or never requested. Please try again"
+msgstr ""
+
+msgid "Re-authentication required"
+msgstr ""
+
+msgid "Re-verification interval"
+msgstr ""
+
+msgid "Read more"
+msgstr ""
+
+msgid "Read more about environments"
+msgstr ""
+
+msgid "Read more about project permissions <strong>%{link_to_help}</strong>"
+msgstr ""
+
+msgid "Read more about related issues"
+msgstr ""
+
+msgid "Real-time features"
+msgstr ""
+
+msgid "Rebase"
+msgstr ""
+
+msgid "Rebase in progress"
+msgstr ""
+
+msgid "Receive alerts from manually configured Prometheus servers."
+msgstr ""
+
+msgid "Receive notifications about your own activity"
+msgstr ""
+
+msgid "Recent"
+msgstr ""
+
+msgid "Recent Activity"
+msgstr ""
+
+msgid "Recent Project Activity"
+msgstr ""
+
+msgid "Recent Searches Service is unavailable"
+msgstr ""
+
+msgid "Recent searches"
+msgstr ""
+
+msgid "Recipe"
+msgstr ""
+
+msgid "Recover hidden stage"
+msgstr ""
+
+msgid "Recovery Codes"
+msgstr ""
+
+msgid "Redirect to SAML provider to test configuration"
+msgstr ""
+
+msgid "Reduce project visibility"
+msgstr ""
+
+msgid "Reduce this project’s visibility?"
+msgstr ""
+
+msgid "Reference:"
+msgstr ""
+
+msgid "Refresh"
+msgstr ""
+
+msgid "Refreshing in a second to show the updated status..."
+msgid_plural "Refreshing in %d seconds to show the updated status..."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Regenerate export"
+msgstr ""
+
+msgid "Regenerate instance ID"
+msgstr ""
+
+msgid "Regenerate key"
+msgstr ""
+
+msgid "Regenerate recovery codes"
+msgstr ""
+
+msgid "Regenerating the instance ID can break integration depending on the client you are using."
+msgstr ""
+
+msgid "Regex pattern"
+msgstr ""
+
+msgid "Region that Elasticsearch is configured"
+msgstr ""
+
+msgid "Register"
+msgstr ""
+
+msgid "Register / Sign In"
+msgstr ""
+
+msgid "Register Two-Factor Authenticator"
+msgstr ""
+
+msgid "Register U2F device"
+msgstr ""
+
+msgid "Register Universal Two-Factor (U2F) Device"
+msgstr ""
+
+msgid "Register for GitLab"
+msgstr ""
+
+msgid "Register now"
+msgstr ""
+
+msgid "Register with two-factor app"
+msgstr ""
+
+msgid "Registration"
+msgstr ""
+
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
+msgid "Related Deployed Jobs"
+msgstr ""
+
+msgid "Related Issues"
+msgstr ""
+
+msgid "Related Jobs"
+msgstr ""
+
+msgid "Related Merge Requests"
+msgstr ""
+
+msgid "Related Merged Requests"
+msgstr ""
+
+msgid "Related merge requests"
+msgstr ""
+
+msgid "Relates to"
+msgstr ""
+
+msgid "Release"
+msgid_plural "Releases"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Release assets"
+msgstr ""
+
+msgid "Release assets documentation"
+msgstr ""
+
+msgid "Release does not have the same project as the milestone"
+msgstr ""
+
+msgid "Release notes"
+msgstr ""
+
+msgid "Release notes:"
+msgstr ""
+
+msgid "Release title"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
+msgid "Releases"
+msgstr ""
+
+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 ""
+
+msgid "Releases are based on Git tags. We recommend tags that use semantic versioning, for example %{codeStart}v1.0%{codeEnd}, %{codeStart}v2.0-pre%{codeEnd}."
+msgstr ""
+
+msgid "Releases documentation"
+msgstr ""
+
+msgid "Release|Something went wrong while getting the release details"
+msgstr ""
+
+msgid "Release|Something went wrong while saving the release details"
+msgstr ""
+
+msgid "Remediated: needs review"
+msgstr ""
+
+msgid "Remediations"
+msgstr ""
+
+msgid "Remember me"
+msgstr ""
+
+msgid "Remind later"
+msgstr ""
+
+msgid "Remote object has no absolute path."
+msgstr ""
+
+msgid "Remove"
+msgstr ""
+
+msgid "Remove %{displayReference}"
+msgstr ""
+
+msgid "Remove Runner"
+msgstr ""
+
+msgid "Remove Zoom meeting"
+msgstr ""
+
+msgid "Remove all approvals in a merge request when new commits are pushed to its source branch"
+msgstr ""
+
+msgid "Remove all or specific assignee(s)"
+msgstr ""
+
+msgid "Remove all or specific label(s)"
+msgstr ""
+
+msgid "Remove approvers"
+msgstr ""
+
+msgid "Remove approvers?"
+msgstr ""
+
+msgid "Remove asset link"
+msgstr ""
+
+msgid "Remove assignee"
+msgstr ""
+
+msgid "Remove avatar"
+msgstr ""
+
+msgid "Remove card"
+msgstr ""
+
+msgid "Remove child epic from an epic"
+msgstr ""
+
+msgid "Remove description history"
+msgstr ""
+
+msgid "Remove due date"
+msgstr ""
+
+msgid "Remove fork relationship"
+msgstr ""
+
+msgid "Remove from board"
+msgstr ""
+
+msgid "Remove from epic"
+msgstr ""
+
+msgid "Remove group"
+msgstr ""
+
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
+msgid "Remove limit"
+msgstr ""
+
+msgid "Remove milestone"
+msgstr ""
+
+msgid "Remove node"
+msgstr ""
+
+msgid "Remove parent epic from an epic"
+msgstr ""
+
+msgid "Remove primary node"
+msgstr ""
+
+msgid "Remove priority"
+msgstr ""
+
+msgid "Remove project"
+msgstr ""
+
+msgid "Remove secondary node"
+msgstr ""
+
+msgid "Remove spent time"
+msgstr ""
+
+msgid "Remove stage"
+msgstr ""
+
+msgid "Remove time estimate"
+msgstr ""
+
+msgid "Removed"
+msgstr ""
+
+msgid "Removed %{assignee_text} %{assignee_references}."
+msgstr ""
+
+msgid "Removed %{epic_ref} from child epics."
+msgstr ""
+
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
+msgid "Removed %{label_references} %{label_text}."
+msgstr ""
+
+msgid "Removed %{milestone_reference} milestone."
+msgstr ""
+
+msgid "Removed %{type} with id %{id}"
+msgstr ""
+
+msgid "Removed all labels."
+msgstr ""
+
+msgid "Removed an issue from an epic."
+msgstr ""
+
+msgid "Removed group can not be restored!"
+msgstr ""
+
+msgid "Removed parent epic %{epic_ref}."
+msgstr ""
+
+msgid "Removed projects cannot be restored!"
+msgstr ""
+
+msgid "Removed spent time."
+msgstr ""
+
+msgid "Removed the due date."
+msgstr ""
+
+msgid "Removed time estimate."
+msgstr ""
+
+msgid "Removes %{assignee_text} %{assignee_references}."
+msgstr ""
+
+msgid "Removes %{epic_ref} from child epics."
+msgstr ""
+
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
+msgid "Removes %{label_references} %{label_text}."
+msgstr ""
+
+msgid "Removes %{milestone_reference} milestone."
+msgstr ""
+
+msgid "Removes all labels."
+msgstr ""
+
+msgid "Removes an issue from an epic."
+msgstr ""
+
+msgid "Removes parent epic %{epic_ref}."
+msgstr ""
+
+msgid "Removes spent time."
+msgstr ""
+
+msgid "Removes the due date."
+msgstr ""
+
+msgid "Removes time estimate."
+msgstr ""
+
+msgid "Removing a project places it into a read-only state until %{date}, at which point the project will be permanantly removed. Are you ABSOLUTELY sure?"
+msgstr ""
+
+msgid "Removing a project places it into a read-only state until %{date}, at which point the project will be permanently removed."
+msgstr ""
+
+msgid "Removing license…"
+msgstr ""
+
+msgid "Removing the project will delete its repository and all related resources including issues, merge requests etc."
+msgstr ""
+
+msgid "Removing this group also removes all child projects, including archived projects, and their resources."
+msgstr ""
+
+msgid "Rename file"
+msgstr ""
+
+msgid "Rename folder"
+msgstr ""
+
+msgid "Rename/Move"
+msgstr ""
+
+msgid "Reopen"
+msgstr ""
+
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
+msgid "Reopen epic"
+msgstr ""
+
+msgid "Reopen milestone"
+msgstr ""
+
+msgid "Reopen this %{quick_action_target}"
+msgstr ""
+
+msgid "Reopened this %{quick_action_target}."
+msgstr ""
+
+msgid "Reopens this %{quick_action_target}."
+msgstr ""
+
+msgid "Repair authentication"
+msgstr ""
+
+msgid "Replace"
+msgstr ""
+
+msgid "Replace all label(s)"
+msgstr ""
+
+msgid "Replaced all labels with %{label_references} %{label_text}."
+msgstr ""
+
+msgid "Replaces the clone URL root."
+msgstr ""
+
+msgid "Replication"
+msgstr ""
+
+msgid "Reply by email"
+msgstr ""
+
+msgid "Reply to comment"
+msgstr ""
+
+msgid "Reply to this email directly or %{view_it_on_gitlab}."
+msgstr ""
+
+msgid "Reply..."
+msgstr ""
+
+msgid "Repo by URL"
+msgstr ""
+
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
+msgstr ""
+
+msgid "Report abuse to admin"
+msgstr ""
+
+msgid "Reported %{timeAgo} by %{reportedBy}"
+msgstr ""
+
+msgid "Reported Resource Changes: %{addNum} to add, %{changeNum} to change, %{deleteNum} to delete"
+msgstr ""
+
+msgid "Reporter"
+msgstr ""
+
+msgid "Reporting"
+msgstr ""
+
+msgid "Reports|%{combinedString} and %{resolvedString}"
+msgstr ""
+
+msgid "Reports|Accessibility scanning detected %d issue for the source branch only"
+msgid_plural "Reports|Accessibility scanning detected %d issues for the source branch only"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Reports|Accessibility scanning detected no issues for the source branch only"
+msgstr ""
+
+msgid "Reports|Accessibility scanning failed loading results"
+msgstr ""
+
+msgid "Reports|Accessibility scanning results are being parsed"
+msgstr ""
+
+msgid "Reports|Actions"
+msgstr ""
+
+msgid "Reports|An error occured while loading report"
+msgstr ""
+
+msgid "Reports|An error occurred while loading %{name} results"
+msgstr ""
+
+msgid "Reports|Class"
+msgstr ""
+
+msgid "Reports|Classname"
+msgstr ""
+
+msgid "Reports|Execution time"
+msgstr ""
+
+msgid "Reports|Failure"
+msgstr ""
+
+msgid "Reports|Metrics reports are loading"
+msgstr ""
+
+msgid "Reports|Metrics reports changed on %{numberOfChanges} %{pointsString}"
+msgstr ""
+
+msgid "Reports|Metrics reports did not change"
+msgstr ""
+
+msgid "Reports|Metrics reports failed loading results"
+msgstr ""
+
+msgid "Reports|Severity"
+msgstr ""
+
+msgid "Reports|System output"
+msgstr ""
+
+msgid "Reports|Test summary"
+msgstr ""
+
+msgid "Reports|Test summary failed loading results"
+msgstr ""
+
+msgid "Reports|Test summary results are being parsed"
+msgstr ""
+
+msgid "Reports|Vulnerability"
+msgstr ""
+
+msgid "Reports|no changed test results"
+msgstr ""
+
+msgid "Repository"
+msgstr ""
+
+msgid "Repository Analytics"
+msgstr ""
+
+msgid "Repository Graph"
+msgstr ""
+
+msgid "Repository Settings"
+msgstr ""
+
+msgid "Repository URL"
+msgstr ""
+
+msgid "Repository check"
+msgstr ""
+
+msgid "Repository check was triggered."
+msgstr ""
+
+msgid "Repository cleanup"
+msgstr ""
+
+msgid "Repository cleanup has started. You will receive an email once the cleanup operation is complete."
+msgstr ""
+
+msgid "Repository has no locks."
+msgstr ""
+
+msgid "Repository maintenance"
+msgstr ""
+
+msgid "Repository mirroring"
+msgstr ""
+
+msgid "Repository static objects"
+msgstr ""
+
+msgid "Repository storage"
+msgstr ""
+
+msgid "Repository sync capacity"
+msgstr ""
+
+msgid "Repository: %{counter_repositories} / Wikis: %{counter_wikis} / Build Artifacts: %{counter_build_artifacts} / LFS: %{counter_lfs_objects}"
+msgstr ""
+
+msgid "RepositorySettingsAccessLevel|Select"
+msgstr ""
+
+msgid "Request Access"
+msgstr ""
+
+msgid "Request Headers"
+msgstr ""
+
+msgid "Request parameter %{param} is missing."
+msgstr ""
+
+msgid "Request to link SAML account must be authorized"
+msgstr ""
+
+msgid "Requested %{time_ago}"
+msgstr ""
+
+msgid "Requested design version does not exist."
+msgstr ""
+
+msgid "Requested states are invalid"
+msgstr ""
+
+msgid "Requests"
+msgstr ""
+
+msgid "Requests Profiles"
+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 ""
+
+msgid "Require all users in this group to setup Two-factor authentication"
+msgstr ""
+
+msgid "Require all users to accept Terms of Service and Privacy Policy when they access GitLab."
+msgstr ""
+
+msgid "Require user password to approve"
+msgstr ""
+
+msgid "Require users to prove ownership of custom domains"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
+msgid "Requirement"
+msgstr ""
+
+msgid "Requirement %{reference} has been added"
+msgstr ""
+
+msgid "Requirement %{reference} has been archived"
+msgstr ""
+
+msgid "Requirement %{reference} has been reopened"
+msgstr ""
+
+msgid "Requirement %{reference} has been updated"
+msgstr ""
+
+msgid "Requirement title cannot have more than %{limit} characters."
+msgstr ""
+
+msgid "Requirements"
+msgstr ""
+
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
+msgstr ""
+
+msgid "Requires approval from %{names}."
+msgid_plural "Requires %{count} more approvals from %{names}."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Requires approval."
+msgid_plural "Requires %d more approvals."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Requires values to meet regular expression requirements."
+msgstr ""
+
+msgid "Resend confirmation email"
+msgstr ""
+
+msgid "Resend invite"
+msgstr ""
+
+msgid "Resend it"
+msgstr ""
+
+msgid "Reset authorization key"
+msgstr ""
+
+msgid "Reset authorization key?"
+msgstr ""
+
+msgid "Reset health check access token"
+msgstr ""
+
+msgid "Reset key"
+msgstr ""
+
+msgid "Reset runners registration token"
+msgstr ""
+
+msgid "Reset template"
+msgstr ""
+
+msgid "Resetting the authorization key for this project will require updating the authorization key in every alert source it is enabled in."
+msgstr ""
+
+msgid "Resetting the authorization key will invalidate the previous key. Existing alert configurations will need to be updated with the new key."
+msgstr ""
+
+msgid "Resolve"
+msgstr ""
+
+msgid "Resolve all threads in new issue"
+msgstr ""
+
+msgid "Resolve conflicts on source branch"
+msgstr ""
+
+msgid "Resolve thread"
+msgstr ""
+
+msgid "Resolved"
+msgstr ""
+
+msgid "Resolved 1 discussion."
+msgstr ""
+
+msgid "Resolved all discussions."
+msgstr ""
+
+msgid "Resolved by"
+msgstr ""
+
+msgid "Resolved by %{name}"
+msgstr ""
+
+msgid "Resolved by %{resolvedByName}"
+msgstr ""
+
+msgid "Resolves IP addresses once and uses them to submit requests"
+msgstr ""
+
+msgid "Response"
+msgstr ""
+
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
+msgid "Response didn't include `service_desk_address`"
+msgstr ""
+
+msgid "Response metrics (AWS ELB)"
+msgstr ""
+
+msgid "Response metrics (Custom)"
+msgstr ""
+
+msgid "Response metrics (HA Proxy)"
+msgstr ""
+
+msgid "Response metrics (NGINX Ingress VTS)"
+msgstr ""
+
+msgid "Response metrics (NGINX Ingress)"
+msgstr ""
+
+msgid "Response metrics (NGINX)"
+msgstr ""
+
+msgid "Restart Terminal"
+msgstr ""
+
+msgid "Restore group"
+msgstr ""
+
+msgid "Restore project"
+msgstr ""
+
+msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
+msgstr ""
+
+msgid "Restoring the project will prevent the project from being removed on this date and restore people's ability to make changes to it."
+msgstr ""
+
+msgid "Restrict access by IP address"
+msgstr ""
+
+msgid "Restrict membership by email"
+msgstr ""
+
+msgid "Restricts sign-ups for email addresses that match the given regex. See the %{supported_syntax_link_start}supported syntax%{supported_syntax_link_end} for more information."
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Resume replication"
+msgstr ""
+
+msgid "Resync"
+msgstr ""
+
+msgid "Resync all"
+msgstr ""
+
+msgid "Resync all %{replicableType}"
+msgstr ""
+
+msgid "Retry"
+msgstr ""
+
+msgid "Retry this job"
+msgstr ""
+
+msgid "Retry this job in order to create the necessary resources."
+msgstr ""
+
+msgid "Retry update"
+msgstr ""
+
+msgid "Retry verification"
+msgstr ""
+
+msgid "Reveal value"
+msgid_plural "Reveal values"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Reveal values"
+msgstr ""
+
+msgid "Revert this commit"
+msgstr ""
+
+msgid "Revert this merge request"
+msgstr ""
+
+msgid "Review"
+msgstr ""
+
+msgid "Review App|View app"
+msgstr ""
+
+msgid "Review App|View latest app"
+msgstr ""
+
+msgid "Review the process for configuring service providers in your identity provider — in this case, GitLab is the \"service provider\" or \"relying party\"."
+msgstr ""
+
+msgid "Review time"
+msgstr ""
+
+msgid "Review time is defined as the time it takes from first comment until merged."
+msgstr ""
+
+msgid "ReviewApp|Enable Review App"
+msgstr ""
+
+msgid "Reviewing"
+msgstr ""
+
+msgid "Reviewing (merge request !%{mergeRequestId})"
+msgstr ""
+
+msgid "Revoke"
+msgstr ""
+
+msgid "Revoked impersonation token %{token_name}!"
+msgstr ""
+
+msgid "Revoked personal access token %{personal_access_token_name}!"
+msgstr ""
+
+msgid "Revoked project access token %{project_access_token_name}!"
+msgstr ""
+
+msgid "RightSidebar|adding a"
+msgstr ""
+
+msgid "RightSidebar|deleting the"
+msgstr ""
+
+msgid "Roadmap"
+msgstr ""
+
+msgid "Role"
+msgstr ""
+
+msgid "Rollback"
+msgstr ""
+
+msgid "Rook"
+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 ""
+
+msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
+msgstr ""
+
+msgid "Run CI/CD pipelines for external repositories"
+msgstr ""
+
+msgid "Run housekeeping"
+msgstr ""
+
+msgid "Run tests against your code live using the Web Terminal"
+msgstr ""
+
+msgid "Run untagged jobs"
+msgstr ""
+
+msgid "Runner cannot be assigned to other projects"
+msgstr ""
+
+msgid "Runner runs jobs from all unassigned projects"
+msgstr ""
+
+msgid "Runner runs jobs from all unassigned projects in its group"
+msgstr ""
+
+msgid "Runner runs jobs from assigned projects"
+msgstr ""
+
+msgid "Runner token"
+msgstr ""
+
+msgid "Runner tokens"
+msgstr ""
+
+msgid "Runner was not updated."
+msgstr ""
+
+msgid "Runner was successfully updated."
+msgstr ""
+
+msgid "Runner will not receive any new jobs"
+msgstr ""
+
+msgid "Runners"
+msgstr ""
+
+msgid "Runners API"
+msgstr ""
+
+msgid "Runners activated for this project"
+msgstr ""
+
+msgid "Runners are processes that pick up and execute jobs for GitLab. Here you can register and see your Runners for this project."
+msgstr ""
+
+msgid "Runners can be placed on separate users, servers, and even on your local machine."
+msgstr ""
+
+msgid "Runners can be placed on separate users, servers, even on your local machine."
+msgstr ""
+
+msgid "Runners currently online: %{active_runners_count}"
+msgstr ""
+
+msgid "Runners page."
+msgstr ""
+
+msgid "Runners|You have used %{quotaUsed} out of %{quotaLimit} of your shared Runners pipeline minutes."
+msgstr ""
+
+msgid "Running"
+msgstr ""
+
+msgid "Running…"
+msgstr ""
+
+msgid "Runs a number of housekeeping tasks within the current repository, such as compressing file revisions and removing unreachable objects."
+msgstr ""
+
+msgid "SAML SSO"
+msgstr ""
+
+msgid "SAML SSO for %{group_name}"
+msgstr ""
+
+msgid "SAML discovery tokens"
+msgstr ""
+
+msgid "SAML for %{group_name}"
+msgstr ""
+
+msgid "SHA256"
+msgstr ""
+
+msgid "SSH Key"
+msgstr ""
+
+msgid "SSH Keys"
+msgstr ""
+
+msgid "SSH host key fingerprints"
+msgstr ""
+
+msgid "SSH host keys"
+msgstr ""
+
+msgid "SSH host keys are not available on this system. Please use <code>ssh-keyscan</code> command or contact your GitLab administrator for more information."
+msgstr ""
+
+msgid "SSH keys allow you to establish a secure connection between your computer and GitLab."
+msgstr ""
+
+msgid "SSH public key"
+msgstr ""
+
+msgid "SSL Verification:"
+msgstr ""
+
+msgid "Saturday"
+msgstr ""
+
+msgid "Save"
+msgstr ""
+
+msgid "Save Changes"
+msgstr ""
+
+msgid "Save anyway"
+msgstr ""
+
+msgid "Save application"
+msgstr ""
+
+msgid "Save changes"
+msgstr ""
+
+msgid "Save changes before testing"
+msgstr ""
+
+msgid "Save comment"
+msgstr ""
+
+msgid "Save expiration policy"
+msgstr ""
+
+msgid "Save password"
+msgstr ""
+
+msgid "Save pipeline schedule"
+msgstr ""
+
+msgid "Save template"
+msgstr ""
+
+msgid "Save variables"
+msgstr ""
+
+msgid "Saving"
+msgstr ""
+
+msgid "Saving project."
+msgstr ""
+
+msgid "Schedule a new pipeline"
+msgstr ""
+
+msgid "Scheduled"
+msgstr ""
+
+msgid "Scheduled to merge this merge request (%{strategy})."
+msgstr ""
+
+msgid "Scheduled to merge this merge request when the pipeline succeeds."
+msgstr ""
+
+msgid "Schedules"
+msgstr ""
+
+msgid "Schedules to merge this merge request (%{strategy})."
+msgstr ""
+
+msgid "Scheduling"
+msgstr ""
+
+msgid "Scheduling Pipelines"
+msgstr ""
+
+msgid "Scope"
+msgstr ""
+
+msgid "Scope not supported with disabled 'users_search' feature!"
+msgstr ""
+
+msgid "Scoped issue boards"
+msgstr ""
+
+msgid "Scopes"
+msgstr ""
+
+msgid "Scopes can't be blank"
+msgstr ""
+
+msgid "Scroll down"
+msgstr ""
+
+msgid "Scroll down to <strong>Google Code Project Hosting</strong> and enable the switch on the right."
+msgstr ""
+
+msgid "Scroll left"
+msgstr ""
+
+msgid "Scroll right"
+msgstr ""
+
+msgid "Scroll to bottom"
+msgstr ""
+
+msgid "Scroll to top"
+msgstr ""
+
+msgid "Scroll up"
+msgstr ""
+
+msgid "Search"
+msgstr ""
+
+msgid "Search Button"
+msgstr ""
+
+msgid "Search Milestones"
+msgstr ""
+
+msgid "Search an environment spec"
+msgstr ""
+
+msgid "Search authors"
+msgstr ""
+
+msgid "Search branches"
+msgstr ""
+
+msgid "Search branches and tags"
+msgstr ""
+
+msgid "Search by author"
+msgstr ""
+
+msgid "Search files"
+msgstr ""
+
+msgid "Search for a LDAP group"
+msgstr ""
+
+msgid "Search for a group"
+msgstr ""
+
+msgid "Search for a user"
+msgstr ""
+
+msgid "Search for projects, issues, etc."
+msgstr ""
+
+msgid "Search for this text"
+msgstr ""
+
+msgid "Search forks"
+msgstr ""
+
+msgid "Search groups"
+msgstr ""
+
+msgid "Search merge requests"
+msgstr ""
+
+msgid "Search milestones"
+msgstr ""
+
+msgid "Search or filter results..."
+msgstr ""
+
+msgid "Search or filter results…"
+msgstr ""
+
+msgid "Search or jump to…"
+msgstr ""
+
+msgid "Search project"
+msgstr ""
+
+msgid "Search projects"
+msgstr ""
+
+msgid "Search projects..."
+msgstr ""
+
+msgid "Search requirements"
+msgstr ""
+
+msgid "Search users"
+msgstr ""
+
+msgid "Search users or groups"
+msgstr ""
+
+msgid "Search your project dependencies for their licenses and apply policies."
+msgstr ""
+
+msgid "Search your projects"
+msgstr ""
+
+msgid "SearchAutocomplete|All GitLab"
+msgstr ""
+
+msgid "SearchAutocomplete|Issues I've created"
+msgstr ""
+
+msgid "SearchAutocomplete|Issues assigned to me"
+msgstr ""
+
+msgid "SearchAutocomplete|Merge requests I've created"
+msgstr ""
+
+msgid "SearchAutocomplete|Merge requests assigned to me"
+msgstr ""
+
+msgid "SearchAutocomplete|in all GitLab"
+msgstr ""
+
+msgid "SearchAutocomplete|in group %{groupName}"
+msgstr ""
+
+msgid "SearchAutocomplete|in project %{projectName}"
+msgstr ""
+
+msgid "SearchCodeResults|in"
+msgstr ""
+
+msgid "SearchCodeResults|of %{link_to_project}"
+msgstr ""
+
+msgid "SearchResults|Showing %{count} %{scope} for%{term_element}"
+msgstr ""
+
+msgid "SearchResults|Showing %{count} %{scope} for%{term_element} in your personal and project snippets"
+msgstr ""
+
+msgid "SearchResults|Showing %{from} - %{to} of %{count} %{scope} for%{term_element}"
+msgstr ""
+
+msgid "SearchResults|Showing %{from} - %{to} of %{count} %{scope} for%{term_element} in your personal and project snippets"
+msgstr ""
+
+msgid "SearchResults|We couldn't find any %{scope} matching %{term}"
+msgstr ""
+
+msgid "SearchResults|code result"
+msgid_plural "SearchResults|code results"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "SearchResults|comment"
+msgid_plural "SearchResults|comments"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "SearchResults|commit"
+msgid_plural "SearchResults|commits"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "SearchResults|issue"
+msgid_plural "SearchResults|issues"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "SearchResults|merge request"
+msgid_plural "SearchResults|merge requests"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "SearchResults|milestone"
+msgid_plural "SearchResults|milestones"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "SearchResults|project"
+msgid_plural "SearchResults|projects"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "SearchResults|snippet"
+msgid_plural "SearchResults|snippets"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "SearchResults|user"
+msgid_plural "SearchResults|users"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "SearchResults|wiki result"
+msgid_plural "SearchResults|wiki results"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Searching by both author and message is currently not supported."
+msgstr ""
+
+msgid "Seat Link"
+msgstr ""
+
+msgid "Seat Link is disabled, and cannot be configured through this form."
+msgstr ""
+
+msgid "Seats currently in use"
+msgstr ""
+
+msgid "Seats in license"
+msgstr ""
+
+msgid "Secondary"
+msgstr ""
+
+msgid "Secret"
+msgstr ""
+
+msgid "Secret Detection"
+msgstr ""
+
+msgid "Security"
+msgstr ""
+
+msgid "Security & Compliance"
+msgstr ""
+
+msgid "Security Configuration"
+msgstr ""
+
+msgid "Security Dashboard"
+msgstr ""
+
+msgid "Security dashboard"
+msgstr ""
+
+msgid "Security report is out of date. Please update your branch with the latest changes from the target branch (%{targetBranchName})"
+msgstr ""
+
+msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
+msgstr ""
+
+msgid "SecurityConfiguration|Enabled"
+msgstr ""
+
+msgid "SecurityConfiguration|Feature documentation for %{featureName}"
+msgstr ""
+
+msgid "SecurityConfiguration|Not yet enabled"
+msgstr ""
+
+msgid "SecurityConfiguration|Security Control"
+msgstr ""
+
+msgid "SecurityConfiguration|Status"
+msgstr ""
+
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
+msgid "SecurityReports|%{firstProject} and %{secondProject}"
+msgstr ""
+
+msgid "SecurityReports|%{firstProject}, %{secondProject}, and %{rest}"
+msgstr ""
+
+msgid "SecurityReports|Add a project to your dashboard"
+msgstr ""
+
+msgid "SecurityReports|Add or remove projects from your dashboard"
+msgstr ""
+
+msgid "SecurityReports|Add projects"
+msgstr ""
+
+msgid "SecurityReports|Comment added to '%{vulnerabilityName}'"
+msgstr ""
+
+msgid "SecurityReports|Comment deleted on '%{vulnerabilityName}'"
+msgstr ""
+
+msgid "SecurityReports|Comment edited on '%{vulnerabilityName}'"
+msgstr ""
+
+msgid "SecurityReports|Create issue"
+msgstr ""
+
+msgid "SecurityReports|Dismiss Selected"
+msgstr ""
+
+msgid "SecurityReports|Dismiss vulnerability"
+msgstr ""
+
+msgid "SecurityReports|Dismissed '%{vulnerabilityName}'"
+msgstr ""
+
+msgid "SecurityReports|Dismissed '%{vulnerabilityName}'. Turn off the hide dismissed toggle to view."
+msgstr ""
+
+msgid "SecurityReports|Each vulnerability now has a unique page that can be directly linked to, shared, referenced, and tracked as the single source of truth. Vulnerability occurrences also persist across scanner runs, which improves tracking and visibility and reduces duplicates between scans."
+msgstr ""
+
+msgid "SecurityReports|Edit dashboard"
+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 ""
+
+msgid "SecurityReports|Error fetching the vulnerability counts. Please check your network connection and try again."
+msgstr ""
+
+msgid "SecurityReports|Error fetching the vulnerability list. Please check your network connection and try again."
+msgstr ""
+
+msgid "SecurityReports|False positive"
+msgstr ""
+
+msgid "SecurityReports|Hide dismissed"
+msgstr ""
+
+msgid "SecurityReports|Introducing standalone vulnerabilities"
+msgstr ""
+
+msgid "SecurityReports|Issue Created"
+msgstr ""
+
+msgid "SecurityReports|Learn More"
+msgstr ""
+
+msgid "SecurityReports|Learn more about setting up your dashboard"
+msgstr ""
+
+msgid "SecurityReports|Load more vulnerabilities"
+msgstr ""
+
+msgid "SecurityReports|Monitor vulnerabilities in your code"
+msgstr ""
+
+msgid "SecurityReports|More info"
+msgstr ""
+
+msgid "SecurityReports|More information"
+msgstr ""
+
+msgid "SecurityReports|No vulnerabilities found for dashboard"
+msgstr ""
+
+msgid "SecurityReports|No vulnerabilities found for this group"
+msgstr ""
+
+msgid "SecurityReports|No vulnerabilities found for this pipeline"
+msgstr ""
+
+msgid "SecurityReports|No vulnerabilities found for this project"
+msgstr ""
+
+msgid "SecurityReports|Oops, something doesn't seem right."
+msgstr ""
+
+msgid "SecurityReports|Pipeline %{pipelineLink} triggered %{timeago} by %{user}"
+msgstr ""
+
+msgid "SecurityReports|Project"
+msgstr ""
+
+msgid "SecurityReports|Projects added"
+msgstr ""
+
+msgid "SecurityReports|Remove project from dashboard"
+msgstr ""
+
+msgid "SecurityReports|Report type"
+msgstr ""
+
+msgid "SecurityReports|Return to dashboard"
+msgstr ""
+
+msgid "SecurityReports|Security Dashboard"
+msgstr ""
+
+msgid "SecurityReports|Security reports can only be accessed by authorized users."
+msgstr ""
+
+msgid "SecurityReports|Select a project to add by using the project search field above."
+msgstr ""
+
+msgid "SecurityReports|Select a reason"
+msgstr ""
+
+msgid "SecurityReports|Severity"
+msgstr ""
+
+msgid "SecurityReports|Status"
+msgstr ""
+
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
+msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
+msgstr ""
+
+msgid "SecurityReports|The security dashboard displays the latest security report. Use it to find and fix vulnerabilities."
+msgstr ""
+
+msgid "SecurityReports|There was an error adding the comment."
+msgstr ""
+
+msgid "SecurityReports|There was an error creating the issue."
+msgstr ""
+
+msgid "SecurityReports|There was an error creating the merge request."
+msgstr ""
+
+msgid "SecurityReports|There was an error deleting the comment."
+msgstr ""
+
+msgid "SecurityReports|There was an error dismissing the vulnerabilities."
+msgstr ""
+
+msgid "SecurityReports|There was an error dismissing the vulnerability."
+msgstr ""
+
+msgid "SecurityReports|There was an error reverting the dismissal."
+msgstr ""
+
+msgid "SecurityReports|There was an error reverting this dismissal."
+msgstr ""
+
+msgid "SecurityReports|There was an error while generating the report."
+msgstr ""
+
+msgid "SecurityReports|Unable to add %{invalidProjects}"
+msgstr ""
+
+msgid "SecurityReports|Undo dismiss"
+msgstr ""
+
+msgid "SecurityReports|While it's rare to have no vulnerabilities for your group, it can happen. In any event, we ask that you double check your settings to make sure you've set up your dashboard correctly."
+msgstr ""
+
+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 ""
+
+msgid "SecurityReports|While it's rare to have no vulnerabilities for your project, it can happen. In any event, we ask that you double check your settings to make sure you've set up your dashboard correctly."
+msgstr ""
+
+msgid "SecurityReports|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 "SecurityReports|Won't fix / Accept risk"
+msgstr ""
+
+msgid "SecurityReports|You do not have sufficient permissions to access this report"
+msgstr ""
+
+msgid "SecurityReports|You must sign in as an authorized user to see this report"
+msgstr ""
+
+msgid "SecurityReports|[No reason]"
+msgstr ""
+
+msgid "See GitLab's %{password_policy_guidelines}"
+msgstr ""
+
+msgid "See metrics"
+msgstr ""
+
+msgid "See the affected projects in the GitLab admin panel"
+msgstr ""
+
+msgid "See what's new at GitLab"
+msgstr ""
+
+msgid "Select"
+msgstr ""
+
+msgid "Select Archive Format"
+msgstr ""
+
+msgid "Select Git revision"
+msgstr ""
+
+msgid "Select GitLab project to link with your Slack team"
+msgstr ""
+
+msgid "Select Page"
+msgstr ""
+
+msgid "Select Stack"
+msgstr ""
+
+msgid "Select a file from the left sidebar to begin editing. Afterwards, you'll be able to commit your changes."
+msgstr ""
+
+msgid "Select a group to invite"
+msgstr ""
+
+msgid "Select a label"
+msgstr ""
+
+msgid "Select a namespace to fork the project"
+msgstr ""
+
+msgid "Select a new namespace"
+msgstr ""
+
+msgid "Select a project"
+msgstr ""
+
+msgid "Select a project to read Insights configuration file"
+msgstr ""
+
+msgid "Select a reason"
+msgstr ""
+
+msgid "Select a repository"
+msgstr ""
+
+msgid "Select a template repository"
+msgstr ""
+
+msgid "Select a template type"
+msgstr ""
+
+msgid "Select a timezone"
+msgstr ""
+
+msgid "Select all"
+msgstr ""
+
+msgid "Select an existing Kubernetes cluster or create a new one"
+msgstr ""
+
+msgid "Select assignee"
+msgstr ""
+
+msgid "Select branch"
+msgstr ""
+
+msgid "Select branch/tag"
+msgstr ""
+
+msgid "Select due date"
+msgstr ""
+
+msgid "Select group or project"
+msgstr ""
+
+msgid "Select groups to replicate"
+msgstr ""
+
+msgid "Select health status"
+msgstr ""
+
+msgid "Select labels"
+msgstr ""
+
+msgid "Select merge moment"
+msgstr ""
+
+msgid "Select milestone"
+msgstr ""
+
+msgid "Select private project"
+msgstr ""
+
+msgid "Select project"
+msgstr ""
+
+msgid "Select project and zone to choose machine type"
+msgstr ""
+
+msgid "Select project to choose zone"
+msgstr ""
+
+msgid "Select projects"
+msgstr ""
+
+msgid "Select projects you want to import."
+msgstr ""
+
+msgid "Select required regulatory standard"
+msgstr ""
+
+msgid "Select shards to replicate"
+msgstr ""
+
+msgid "Select source branch"
+msgstr ""
+
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
+msgid "Select strategy activation method"
+msgstr ""
+
+msgid "Select subscription"
+msgstr ""
+
+msgid "Select target branch"
+msgstr ""
+
+msgid "Select the branch you want to set as the default for this project. All merge requests and commits will automatically be made against this branch unless you specify a different one."
+msgstr ""
+
+msgid "Select the configured storage available for new repositories to be placed on."
+msgstr ""
+
+msgid "Select the custom project template source group."
+msgstr ""
+
+msgid "Select timeframe"
+msgstr ""
+
+msgid "Select user"
+msgstr ""
+
+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 "Selecting a GitLab user will add a link to the GitLab user in the descriptions of issues and comments (e.g. \"By <a href=\"#\">@johnsmith</a>\"). It will also associate and/or assign these issues and comments with the selected user."
+msgstr ""
+
+msgid "Selective synchronization"
+msgstr ""
+
+msgid "Self monitoring project does not exist"
+msgstr ""
+
+msgid "Self-monitoring project does not exist. Please check logs for any error messages"
+msgstr ""
+
+msgid "Self-monitoring project has been successfully deleted"
+msgstr ""
+
+msgid "Self-monitoring project was not deleted. Please check logs for any error messages"
+msgstr ""
+
+msgid "SelfMonitoring|Disable self monitoring?"
+msgstr ""
+
+msgid "SelfMonitoring|Disabling this feature will delete the self monitoring project. Are you sure you want to delete the project?"
+msgstr ""
+
+msgid "SelfMonitoring|Enable or disable instance self monitoring"
+msgstr ""
+
+msgid "SelfMonitoring|Enabling this feature creates a %{projectLinkStart}project%{projectLinkEnd} that can be used to monitor the health of your instance."
+msgstr ""
+
+msgid "SelfMonitoring|Enabling this feature creates a project that can be used to monitor the health of your instance."
+msgstr ""
+
+msgid "SelfMonitoring|Self monitoring"
+msgstr ""
+
+msgid "SelfMonitoring|Self monitoring project has been successfully created."
+msgstr ""
+
+msgid "SelfMonitoring|Self monitoring project has been successfully deleted."
+msgstr ""
+
+msgid "Send a separate email notification to Developers."
+msgstr ""
+
+msgid "Send confirmation email"
+msgstr ""
+
+msgid "Send email"
+msgstr ""
+
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
+msgid "Send report"
+msgstr ""
+
+msgid "Send usage data"
+msgstr ""
+
+msgid "Sentry API URL"
+msgstr ""
+
+msgid "Sentry event"
+msgstr ""
+
+msgid "Sep"
+msgstr ""
+
+msgid "Separate topics with commas."
+msgstr ""
+
+msgid "September"
+msgstr ""
+
+msgid "SeriesFinalConjunction|and"
+msgstr ""
+
+msgid "Serve repository static objects (e.g. archives, blobs, ...) from an external storage (e.g. a CDN)."
+msgstr ""
+
+msgid "Server supports batch API only, please update your Git LFS client to version 1.0.1 and up."
+msgstr ""
+
+msgid "Server version"
+msgstr ""
+
+msgid "Serverless"
+msgstr ""
+
+msgid "Serverless domain"
+msgstr ""
+
+msgid "ServerlessDetails|Function invocation metrics require Prometheus to be installed first."
+msgstr ""
+
+msgid "ServerlessDetails|Install Prometheus"
+msgstr ""
+
+msgid "ServerlessDetails|Invocation metrics loading or not available at this time."
+msgstr ""
+
+msgid "ServerlessDetails|Invocations"
+msgstr ""
+
+msgid "ServerlessDetails|Kubernetes Pods"
+msgstr ""
+
+msgid "ServerlessDetails|More information"
+msgstr ""
+
+msgid "ServerlessDetails|No pods loaded at this time."
+msgstr ""
+
+msgid "ServerlessDetails|Number of Kubernetes pods in use over time based on necessity."
+msgstr ""
+
+msgid "ServerlessDetails|pod in use"
+msgstr ""
+
+msgid "ServerlessDetails|pods in use"
+msgstr ""
+
+msgid "ServerlessURL|Copy URL"
+msgstr ""
+
+msgid "Serverless| In order to start using functions as a service, you must first install Knative on your Kubernetes cluster."
+msgstr ""
+
+msgid "Serverless|Getting started with serverless"
+msgstr ""
+
+msgid "Serverless|Help shape the future of Serverless at GitLab"
+msgstr ""
+
+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 ""
+
+msgid "Serverless|Install Knative"
+msgstr ""
+
+msgid "Serverless|Learn more about Serverless"
+msgstr ""
+
+msgid "Serverless|No functions available"
+msgstr ""
+
+msgid "Serverless|Sign up for First Look"
+msgstr ""
+
+msgid "Serverless|The deploy job has not finished."
+msgstr ""
+
+msgid "Serverless|The functions listed in the %{startTag}serverless.yml%{endTag} file don't match the namespace of your cluster."
+msgstr ""
+
+msgid "Serverless|There is currently no function data available from Knative. This could be for a variety of reasons including:"
+msgstr ""
+
+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 ""
+
+msgid "Serverless|Your %{startTag}.gitlab-ci.yml%{endTag} file is not properly configured."
+msgstr ""
+
+msgid "Serverless|Your repository does not have a corresponding %{startTag}serverless.yml%{endTag} file."
+msgstr ""
+
+msgid "Service"
+msgstr ""
+
+msgid "Service Desk"
+msgstr ""
+
+msgid "Service Desk is enabled but not yet active"
+msgstr ""
+
+msgid "Service Desk is off"
+msgstr ""
+
+msgid "Service Desk is on"
+msgstr ""
+
+msgid "Service Templates"
+msgstr ""
+
+msgid "Service URL"
+msgstr ""
+
+msgid "Session duration (minutes)"
+msgstr ""
+
+msgid "Set %{epic_ref} as the parent epic."
+msgstr ""
+
+msgid "Set a default template for issue descriptions."
+msgstr ""
+
+msgid "Set a number of approvals required, the approvers and other approval settings."
+msgstr ""
+
+msgid "Set a password on your account to pull or push via %{protocol}."
+msgstr ""
+
+msgid "Set a template repository for projects in this group"
+msgstr ""
+
+msgid "Set an instance-wide domain that will be available to all clusters when installing Knative."
+msgstr ""
+
+msgid "Set default and restrict visibility levels. Configure import sources and git access protocol."
+msgstr ""
+
+msgid "Set due date"
+msgstr ""
+
+msgid "Set instance-wide template repository"
+msgstr ""
+
+msgid "Set iteration"
+msgstr ""
+
+msgid "Set max session time for web terminal."
+msgstr ""
+
+msgid "Set milestone"
+msgstr ""
+
+msgid "Set new password"
+msgstr ""
+
+msgid "Set notification email for abuse reports."
+msgstr ""
+
+msgid "Set parent epic to an epic"
+msgstr ""
+
+msgid "Set projects and maximum size limits, session duration, user options, and check feature availability for namespace plan."
+msgstr ""
+
+msgid "Set requirements for a user to sign-in. Enable mandatory two-factor authentication."
+msgstr ""
+
+msgid "Set target branch"
+msgstr ""
+
+msgid "Set target branch to %{branch_name}."
+msgstr ""
+
+msgid "Set the default expiration time for each job's artifacts. 0 for unlimited. The default unit is in seconds, but you can define an alternative. For example: <code>4 mins 2 sec</code>, <code>2h42min</code>."
+msgstr ""
+
+msgid "Set the due date to %{due_date}."
+msgstr ""
+
+msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
+msgstr ""
+
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
+msgid "Set the maximum file size for each job's artifacts"
+msgstr ""
+
+msgid "Set the maximum number of pipeline minutes that a group can use on shared Runners per month. 0 for unlimited."
+msgstr ""
+
+msgid "Set the milestone to %{milestone_reference}."
+msgstr ""
+
+msgid "Set time estimate"
+msgstr ""
+
+msgid "Set time estimate to %{time_estimate}."
+msgstr ""
+
+msgid "Set up CI/CD"
+msgstr ""
+
+msgid "Set up Jira Integration"
+msgstr ""
+
+msgid "Set up a %{type} Runner automatically"
+msgstr ""
+
+msgid "Set up a %{type} Runner manually"
+msgstr ""
+
+msgid "Set up assertions/attributes/claims (email, first_name, last_name) and NameID according to %{docsLinkStart}the documentation %{icon}%{docsLinkEnd}"
+msgstr ""
+
+msgid "Set up new U2F device"
+msgstr ""
+
+msgid "Set up new password"
+msgstr ""
+
+msgid "Set up pipeline subscriptions for this project."
+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 ""
+
+msgid "Set weight"
+msgstr ""
+
+msgid "Set weight to %{weight}."
+msgstr ""
+
+msgid "SetPasswordToCloneLink|set a password"
+msgstr ""
+
+msgid "SetStatusModal|Add status emoji"
+msgstr ""
+
+msgid "SetStatusModal|Clear status"
+msgstr ""
+
+msgid "SetStatusModal|Edit status"
+msgstr ""
+
+msgid "SetStatusModal|Remove status"
+msgstr ""
+
+msgid "SetStatusModal|Set a status"
+msgstr ""
+
+msgid "SetStatusModal|Set status"
+msgstr ""
+
+msgid "SetStatusModal|Sorry, we weren't able to set your status. Please try again later."
+msgstr ""
+
+msgid "SetStatusModal|What's your status?"
+msgstr ""
+
+msgid "Sets %{epic_ref} as parent epic."
+msgstr ""
+
+msgid "Sets target branch to %{branch_name}."
+msgstr ""
+
+msgid "Sets the due date to %{due_date}."
+msgstr ""
+
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
+msgid "Sets the milestone to %{milestone_reference}."
+msgstr ""
+
+msgid "Sets time estimate to %{time_estimate}."
+msgstr ""
+
+msgid "Sets weight to %{weight}."
+msgstr ""
+
+msgid "Settings"
+msgstr ""
+
+msgid "Settings related to the use and experience of using GitLab's Package Registry."
+msgstr ""
+
+msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
+msgstr ""
+
+msgid "Severity"
+msgstr ""
+
+msgid "Shards (%{shards})"
+msgstr ""
+
+msgid "Shards to synchronize"
+msgstr ""
+
+msgid "Share"
+msgstr ""
+
+msgid "Share the <strong>%{sso_label}</strong> with members so they can sign in to your group through your identity provider"
+msgstr ""
+
+msgid "Shared Runners"
+msgstr ""
+
+msgid "Shared projects"
+msgstr ""
+
+msgid "Shared runners help link"
+msgstr ""
+
+msgid "SharedRunnersMinutesSettings|By resetting the pipeline minutes for this namespace, the currently used minutes will be set to zero."
+msgstr ""
+
+msgid "SharedRunnersMinutesSettings|Reset pipeline minutes"
+msgstr ""
+
+msgid "SharedRunnersMinutesSettings|Reset used pipeline minutes"
+msgstr ""
+
+msgid "Sherlock Transactions"
+msgstr ""
+
+msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
+msgstr ""
+
+msgid "Show all activity"
+msgstr ""
+
+msgid "Show all members"
+msgstr ""
+
+msgid "Show all requirements."
+msgstr ""
+
+msgid "Show archived projects"
+msgstr ""
+
+msgid "Show archived projects only"
+msgstr ""
+
+msgid "Show command"
+msgstr ""
+
+msgid "Show comments"
+msgstr ""
+
+msgid "Show comments only"
+msgstr ""
+
+msgid "Show commit description"
+msgstr ""
+
+msgid "Show complete raw log"
+msgstr ""
+
+msgid "Show file browser"
+msgstr ""
+
+msgid "Show file contents"
+msgstr ""
+
+msgid "Show latest version"
+msgstr ""
+
+msgid "Show me everything"
+msgstr ""
+
+msgid "Show me how"
+msgstr ""
+
+msgid "Show me more advanced stuff"
+msgstr ""
+
+msgid "Show only direct members"
+msgstr ""
+
+msgid "Show only inherited members"
+msgstr ""
+
+msgid "Show parent pages"
+msgstr ""
+
+msgid "Show parent subgroups"
+msgstr ""
+
+msgid "Show whitespace changes"
+msgstr ""
+
+msgid "Showing %d event"
+msgid_plural "Showing %d events"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Showing %{limit} of %{total_count} issues. "
+msgstr ""
+
+msgid "Showing %{pageSize} of %{total} issues"
+msgstr ""
+
+msgid "Showing Latest Version"
+msgstr ""
+
+msgid "Showing Version #%{versionNumber}"
+msgstr ""
+
+msgid "Showing all issues"
+msgstr ""
+
+msgid "Showing all labels"
+msgstr ""
+
+msgid "Showing last %{size} of log -"
+msgstr ""
+
+msgid "Side-by-side"
+msgstr ""
+
+msgid "Sidebar|Assign health status"
+msgstr ""
+
+msgid "Sidebar|Change weight"
+msgstr ""
+
+msgid "Sidebar|Health status"
+msgstr ""
+
+msgid "Sidebar|No status"
+msgstr ""
+
+msgid "Sidebar|None"
+msgstr ""
+
+msgid "Sidebar|Only numeral characters allowed"
+msgstr ""
+
+msgid "Sidebar|Weight"
+msgstr ""
+
+msgid "Sign in"
+msgstr ""
+
+msgid "Sign in / Register"
+msgstr ""
+
+msgid "Sign in to \"%{group_name}\""
+msgstr ""
+
+msgid "Sign in using smart card"
+msgstr ""
+
+msgid "Sign in via 2FA code"
+msgstr ""
+
+msgid "Sign in with Single Sign-On"
+msgstr ""
+
+msgid "Sign in with smart card"
+msgstr ""
+
+msgid "Sign out"
+msgstr ""
+
+msgid "Sign out & Register"
+msgstr ""
+
+msgid "Sign up"
+msgstr ""
+
+msgid "Sign up was successful! Please confirm your email to sign in."
+msgstr ""
+
+msgid "Sign-in restrictions"
+msgstr ""
+
+msgid "Sign-up restrictions"
+msgstr ""
+
+msgid "SignUp|First Name is too long (maximum is %{max_length} characters)."
+msgstr ""
+
+msgid "SignUp|Last Name is too long (maximum is %{max_length} characters)."
+msgstr ""
+
+msgid "SignUp|Name is too long (maximum is %{max_length} characters)."
+msgstr ""
+
+msgid "SignUp|Username is too long (maximum is %{max_length} characters)."
+msgstr ""
+
+msgid "Signed in"
+msgstr ""
+
+msgid "Signed in with %{authentication} authentication"
+msgstr ""
+
+msgid "Signing in using %{label} has been disabled"
+msgstr ""
+
+msgid "Signing in using your %{label} account without a pre-existing GitLab account is not allowed."
+msgstr ""
+
+msgid "Similar issues"
+msgstr ""
+
+msgid "Single or combined queries"
+msgstr ""
+
+msgid "Size"
+msgstr ""
+
+msgid "Size and domain settings for static websites"
+msgstr ""
+
+msgid "Size limit per repository (MB)"
+msgstr ""
+
+msgid "Size settings for static websites"
+msgstr ""
+
+msgid "Skip outdated deployment jobs"
+msgstr ""
+
+msgid "Skip this for now"
+msgstr ""
+
+msgid "Skipped"
+msgstr ""
+
+msgid "Slack application"
+msgstr ""
+
+msgid "Slack channels (e.g. general, development)"
+msgstr ""
+
+msgid "Slack integration allows you to interact with GitLab via slash commands in a chat window."
+msgstr ""
+
+msgid "SlackIntegration|%{webhooks_link_start}Add an incoming webhook%{webhooks_link_end} in your Slack team. The default channel can be overridden for each event."
+msgstr ""
+
+msgid "SlackIntegration|<strong>Note:</strong> Usernames and private channels are not supported."
+msgstr ""
+
+msgid "SlackIntegration|Paste the <strong>Webhook URL</strong> into the field below."
+msgstr ""
+
+msgid "SlackIntegration|Select events below to enable notifications. The <strong>Slack channel names</strong> and <strong>Slack username</strong> fields are optional."
+msgstr ""
+
+msgid "SlackIntegration|This service send notifications about projects' events to Slack channels. To set up this service:"
+msgstr ""
+
+msgid "SlackService|2. Paste the <strong>Token</strong> into the field below"
+msgstr ""
+
+msgid "SlackService|3. Select the <strong>Active</strong> checkbox, press <strong>Save changes</strong> and start using GitLab inside Slack!"
+msgstr ""
+
+msgid "SlackService|Fill in the word that works best for your team."
+msgstr ""
+
+msgid "SlackService|See list of available commands in Slack after setting up this service, by entering"
+msgstr ""
+
+msgid "SlackService|This service allows users to perform common operations on this project by entering slash commands in Slack."
+msgstr ""
+
+msgid "Slower but makes sure the project workspace is pristine as it clones the repository from scratch for every job"
+msgstr ""
+
+msgid "Smartcard"
+msgstr ""
+
+msgid "Smartcard authentication failed: client certificate header is missing."
+msgstr ""
+
+msgid "Snippets"
+msgstr ""
+
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
+msgid "SnippetsEmptyState|Code snippets"
+msgstr ""
+
+msgid "SnippetsEmptyState|Documentation"
+msgstr ""
+
+msgid "SnippetsEmptyState|New snippet"
+msgstr ""
+
+msgid "SnippetsEmptyState|No snippets found"
+msgstr ""
+
+msgid "SnippetsEmptyState|Store, share, and embed small pieces of code and text."
+msgstr ""
+
+msgid "SnippetsEmptyState|There are no snippets to show."
+msgstr ""
+
+msgid "Snippets|Description (optional)"
+msgstr ""
+
+msgid "Snippets|File"
+msgstr ""
+
+msgid "Snippets|Give your file a name to add code highlighting, e.g. example.rb for Ruby"
+msgstr ""
+
+msgid "Snippets|Optionally add a description about what your snippet does or how to use it..."
+msgstr ""
+
+msgid "Snippets|Optionally add a description about what your snippet does or how to use it…"
+msgstr ""
+
+msgid "Snowplow"
+msgstr ""
+
+msgid "Solution"
+msgstr ""
+
+msgid "Some child epics may be hidden due to applied filters"
+msgstr ""
+
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
+msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
+msgstr ""
+
+msgid "Some of the designs you tried uploading did not change:"
+msgstr ""
+
+msgid "Some of your epics may not be visible. A roadmap is limited to the first 1,000 epics, in your selected sort order."
+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 ""
+
+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 ""
+
+msgid "Something went wrong on our end"
+msgstr ""
+
+msgid "Something went wrong on our end."
+msgstr ""
+
+msgid "Something went wrong on our end. Please try again!"
+msgstr ""
+
+msgid "Something went wrong on our end. Please try again."
+msgstr ""
+
+msgid "Something went wrong trying to change the confidentiality of this issue"
+msgstr ""
+
+msgid "Something went wrong trying to change the locked state of this %{issuableDisplayName}"
+msgstr ""
+
+msgid "Something went wrong when toggling the button"
+msgstr ""
+
+msgid "Something went wrong while adding your award. Please try again."
+msgstr ""
+
+msgid "Something went wrong while applying the suggestion. Please try again."
+msgstr ""
+
+msgid "Something went wrong while archiving a requirement."
+msgstr ""
+
+msgid "Something went wrong while closing the %{issuable}. Please try again later"
+msgstr ""
+
+msgid "Something went wrong while creating a requirement."
+msgstr ""
+
+msgid "Something went wrong while deleting description changes. Please try again."
+msgstr ""
+
+msgid "Something went wrong while deleting the package."
+msgstr ""
+
+msgid "Something went wrong while deleting the source branch. Please try again."
+msgstr ""
+
+msgid "Something went wrong while deleting your note. Please try again."
+msgstr ""
+
+msgid "Something went wrong while deploying this environment. Please try again."
+msgstr ""
+
+msgid "Something went wrong while editing your comment. Please try again."
+msgstr ""
+
+msgid "Something went wrong while fetching %{listType} list"
+msgstr ""
+
+msgid "Something went wrong while fetching comments. Please try again."
+msgstr ""
+
+msgid "Something went wrong while fetching description changes. Please try again."
+msgstr ""
+
+msgid "Something went wrong while fetching group member contributions"
+msgstr ""
+
+msgid "Something went wrong while fetching latest comments."
+msgstr ""
+
+msgid "Something went wrong while fetching projects"
+msgstr ""
+
+msgid "Something went wrong while fetching projects."
+msgstr ""
+
+msgid "Something went wrong while fetching related merge requests."
+msgstr ""
+
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
+msgid "Something went wrong while fetching requirements list."
+msgstr ""
+
+msgid "Something went wrong while fetching the environments for this merge request. Please try again."
+msgstr ""
+
+msgid "Something went wrong while fetching the package."
+msgstr ""
+
+msgid "Something went wrong while fetching the packages list."
+msgstr ""
+
+msgid "Something went wrong while initializing the OpenAPI viewer"
+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 reopening a requirement."
+msgstr ""
+
+msgid "Something went wrong while reopening the %{issuable}. Please try again later"
+msgstr ""
+
+msgid "Something went wrong while resolving this discussion. Please try again."
+msgstr ""
+
+msgid "Something went wrong while stopping this environment. Please try again."
+msgstr ""
+
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
+msgid "Something went wrong while updating a requirement."
+msgstr ""
+
+msgid "Something went wrong while updating your list settings"
+msgstr ""
+
+msgid "Something went wrong with your automatic subscription renewal"
+msgstr ""
+
+msgid "Something went wrong, unable to add %{project} to dashboard"
+msgstr ""
+
+msgid "Something went wrong, unable to add projects to dashboard"
+msgstr ""
+
+msgid "Something went wrong, unable to get projects"
+msgstr ""
+
+msgid "Something went wrong, unable to remove project"
+msgstr ""
+
+msgid "Something went wrong, unable to search projects"
+msgstr ""
+
+msgid "Something went wrong. Please try again."
+msgstr ""
+
+msgid "Something went wrong. Try again later."
+msgstr ""
+
+msgid "Sorry, no epics matched your search"
+msgstr ""
+
+msgid "Sorry, no projects matched your search"
+msgstr ""
+
+msgid "Sorry, you have exceeded the maximum browsable page number. Please use the API to explore further."
+msgstr ""
+
+msgid "Sorry, your filter produced no results"
+msgstr ""
+
+msgid "Sort by"
+msgstr ""
+
+msgid "Sort direction"
+msgstr ""
+
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
+msgid "SortOptions|Access level, ascending"
+msgstr ""
+
+msgid "SortOptions|Access level, descending"
+msgstr ""
+
+msgid "SortOptions|Created date"
+msgstr ""
+
+msgid "SortOptions|Due date"
+msgstr ""
+
+msgid "SortOptions|Due later"
+msgstr ""
+
+msgid "SortOptions|Due soon"
+msgstr ""
+
+msgid "SortOptions|Expired date"
+msgstr ""
+
+msgid "SortOptions|Label priority"
+msgstr ""
+
+msgid "SortOptions|Largest group"
+msgstr ""
+
+msgid "SortOptions|Largest repository"
+msgstr ""
+
+msgid "SortOptions|Last Contact"
+msgstr ""
+
+msgid "SortOptions|Last created"
+msgstr ""
+
+msgid "SortOptions|Last joined"
+msgstr ""
+
+msgid "SortOptions|Last updated"
+msgstr ""
+
+msgid "SortOptions|Least popular"
+msgstr ""
+
+msgid "SortOptions|Less weight"
+msgstr ""
+
+msgid "SortOptions|Manual"
+msgstr ""
+
+msgid "SortOptions|Milestone due date"
+msgstr ""
+
+msgid "SortOptions|Milestone due later"
+msgstr ""
+
+msgid "SortOptions|Milestone due soon"
+msgstr ""
+
+msgid "SortOptions|More weight"
+msgstr ""
+
+msgid "SortOptions|Most popular"
+msgstr ""
+
+msgid "SortOptions|Most stars"
+msgstr ""
+
+msgid "SortOptions|Name"
+msgstr ""
+
+msgid "SortOptions|Name, ascending"
+msgstr ""
+
+msgid "SortOptions|Name, descending"
+msgstr ""
+
+msgid "SortOptions|Oldest created"
+msgstr ""
+
+msgid "SortOptions|Oldest joined"
+msgstr ""
+
+msgid "SortOptions|Oldest last activity"
+msgstr ""
+
+msgid "SortOptions|Oldest sign in"
+msgstr ""
+
+msgid "SortOptions|Oldest starred"
+msgstr ""
+
+msgid "SortOptions|Oldest updated"
+msgstr ""
+
+msgid "SortOptions|Popularity"
+msgstr ""
+
+msgid "SortOptions|Priority"
+msgstr ""
+
+msgid "SortOptions|Project"
+msgstr ""
+
+msgid "SortOptions|Recent last activity"
+msgstr ""
+
+msgid "SortOptions|Recent sign in"
+msgstr ""
+
+msgid "SortOptions|Recently starred"
+msgstr ""
+
+msgid "SortOptions|Size"
+msgstr ""
+
+msgid "SortOptions|Sort by:"
+msgstr ""
+
+msgid "SortOptions|Sort direction"
+msgstr ""
+
+msgid "SortOptions|Stars"
+msgstr ""
+
+msgid "SortOptions|Start date"
+msgstr ""
+
+msgid "SortOptions|Start later"
+msgstr ""
+
+msgid "SortOptions|Start soon"
+msgstr ""
+
+msgid "SortOptions|Type"
+msgstr ""
+
+msgid "SortOptions|Version"
+msgstr ""
+
+msgid "SortOptions|Weight"
+msgstr ""
+
+msgid "Source"
+msgstr ""
+
+msgid "Source (branch or tag)"
+msgstr ""
+
+msgid "Source code"
+msgstr ""
+
+msgid "Source is not available"
+msgstr ""
+
+msgid "Source project cannot be found."
+msgstr ""
+
+msgid "Sourcegraph"
+msgstr ""
+
+msgid "SourcegraphAdmin|Block on private and internal projects"
+msgstr ""
+
+msgid "SourcegraphAdmin|Configure the URL to a Sourcegraph instance which can read your GitLab projects."
+msgstr ""
+
+msgid "SourcegraphAdmin|Enable Sourcegraph"
+msgstr ""
+
+msgid "SourcegraphAdmin|Enable code intelligence powered by %{link_start}Sourcegraph%{link_end} on your GitLab instance's code views and merge requests."
+msgstr ""
+
+msgid "SourcegraphAdmin|If checked, only public projects will have code intelligence and communicate with Sourcegraph."
+msgstr ""
+
+msgid "SourcegraphAdmin|More information"
+msgstr ""
+
+msgid "SourcegraphAdmin|Save changes"
+msgstr ""
+
+msgid "SourcegraphAdmin|Sourcegraph URL"
+msgstr ""
+
+msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgstr ""
+
+msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
+msgstr ""
+
+msgid "SourcegraphPreferences|This feature is experimental and limited to public projects."
+msgstr ""
+
+msgid "SourcegraphPreferences|This feature is experimental."
+msgstr ""
+
+msgid "SourcegraphPreferences|Uses %{link_start}Sourcegraph.com%{link_end}."
+msgstr ""
+
+msgid "SourcegraphPreferences|Uses a custom %{link_start}Sourcegraph instance%{link_end}."
+msgstr ""
+
+msgid "Spam Logs"
+msgstr ""
+
+msgid "Spam and Anti-bot Protection"
+msgstr ""
+
+msgid "Spam log successfully submitted as ham."
+msgstr ""
+
+msgid "Specific Runners"
+msgstr ""
+
+msgid "Specified URL cannot be used: \"%{reason}\""
+msgstr ""
+
+msgid "Specify an e-mail address regex pattern to identify default internal users."
+msgstr ""
+
+msgid "Specify the following URL during the Runner setup:"
+msgstr ""
+
+msgid "Speed up your DevOps<br>with GitLab"
+msgstr ""
+
+msgid "Squash commit message"
+msgstr ""
+
+msgid "Squash commits"
+msgstr ""
+
+msgid "Stack trace"
+msgstr ""
+
+msgid "Stage"
+msgstr ""
+
+msgid "Stage & Commit"
+msgstr ""
+
+msgid "Stage data updated"
+msgstr ""
+
+msgid "Stage removed"
+msgstr ""
+
+msgid "Standard"
+msgstr ""
+
+msgid "Star a label to make it a priority label. Order the prioritized labels to change their relative priority, by dragging."
+msgstr ""
+
+msgid "Star labels to start sorting by priority"
+msgstr ""
+
+msgid "Star toggle failed. Try again later."
+msgstr ""
+
+msgid "StarProject|Star"
+msgstr ""
+
+msgid "Starred Projects"
+msgstr ""
+
+msgid "Starred Projects' Activity"
+msgstr ""
+
+msgid "Starred projects"
+msgstr ""
+
+msgid "StarredProjectsEmptyState|Visit a project page and press on a star icon. Then, you can find the project on this page."
+msgstr ""
+
+msgid "StarredProjectsEmptyState|You don't have starred projects yet."
+msgstr ""
+
+msgid "Starrers"
+msgstr ""
+
+msgid "Stars"
+msgstr ""
+
+msgid "Start Date"
+msgstr ""
+
+msgid "Start Web Terminal"
+msgstr ""
+
+msgid "Start a %{new_merge_request} with these changes"
+msgstr ""
+
+msgid "Start a Free Gold Trial"
+msgstr ""
+
+msgid "Start a new discussion..."
+msgstr ""
+
+msgid "Start a new merge request"
+msgstr ""
+
+msgid "Start a review"
+msgstr ""
+
+msgid "Start and due date"
+msgstr ""
+
+msgid "Start by choosing a group to see how your team is spending time. You can then drill down to the project level."
+msgstr ""
+
+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 ""
+
+msgid "Start date"
+msgstr ""
+
+msgid "Start merge train"
+msgstr ""
+
+msgid "Start merge train when pipeline succeeds"
+msgstr ""
+
+msgid "Start search"
+msgstr ""
+
+msgid "Start the Runner!"
+msgstr ""
+
+msgid "Start thread"
+msgstr ""
+
+msgid "Start thread & close %{noteable_name}"
+msgstr ""
+
+msgid "Start thread & reopen %{noteable_name}"
+msgstr ""
+
+msgid "Start your Free Gold Trial"
+msgstr ""
+
+msgid "Start your free trial"
+msgstr ""
+
+msgid "Start your trial"
+msgstr ""
+
+msgid "Started"
+msgstr ""
+
+msgid "Started %{startsIn}"
+msgstr ""
+
+msgid "Started asynchronous removal of all repository check states."
+msgstr ""
+
+msgid "Started:"
+msgstr ""
+
+msgid "Starting..."
+msgstr ""
+
+msgid "Starts %{startsIn}"
+msgstr ""
+
+msgid "Starts at (UTC)"
+msgstr ""
+
+msgid "State your message to activate"
+msgstr ""
+
+msgid "Static Application Security Testing (SAST)"
+msgstr ""
+
+msgid "StaticSiteEditor|An error occurred while submitting your changes."
+msgstr ""
+
+msgid "StaticSiteEditor|Branch could not be created."
+msgstr ""
+
+msgid "StaticSiteEditor|Could not commit the content changes."
+msgstr ""
+
+msgid "StaticSiteEditor|Could not create merge request."
+msgstr ""
+
+msgid "StaticSiteEditor|Incompatible file content"
+msgstr ""
+
+msgid "StaticSiteEditor|Return to site"
+msgstr ""
+
+msgid "StaticSiteEditor|Static site editor"
+msgstr ""
+
+msgid "StaticSiteEditor|Success!"
+msgstr ""
+
+msgid "StaticSiteEditor|Summary of changes"
+msgstr ""
+
+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 ""
+
+msgid "StaticSiteEditor|Update %{sourcePath} file"
+msgstr ""
+
+msgid "StaticSiteEditor|View documentation"
+msgstr ""
+
+msgid "StaticSiteEditor|View merge request"
+msgstr ""
+
+msgid "StaticSiteEditor|You added a commit:"
+msgstr ""
+
+msgid "StaticSiteEditor|You created a merge request:"
+msgstr ""
+
+msgid "StaticSiteEditor|You created a new branch:"
+msgstr ""
+
+msgid "StaticSiteEditor|Your changes have been submitted and a merge request has been created. The changes won’t be visible on the site until the merge request has been accepted."
+msgstr ""
+
+msgid "Statistics"
+msgstr ""
+
+msgid "Status"
+msgstr ""
+
+msgid "Status:"
+msgstr ""
+
+msgid "Status: %{title}"
+msgstr ""
+
+msgid "StatusPage|AWS Secret access key"
+msgstr ""
+
+msgid "StatusPage|AWS access key ID"
+msgstr ""
+
+msgid "StatusPage|AWS documentation"
+msgstr ""
+
+msgid "StatusPage|AWS region"
+msgstr ""
+
+msgid "StatusPage|Active"
+msgstr ""
+
+msgid "StatusPage|Bucket %{docsLink}"
+msgstr ""
+
+msgid "StatusPage|Configure file storage settings to link issues in this project to an external status page."
+msgstr ""
+
+msgid "StatusPage|For help with configuration, visit %{docsLink}"
+msgstr ""
+
+msgid "StatusPage|S3 Bucket name"
+msgstr ""
+
+msgid "StatusPage|Status page"
+msgstr ""
+
+msgid "StatusPage|Status page URL"
+msgstr ""
+
+msgid "StatusPage|Status page frontend documentation"
+msgstr ""
+
+msgid "StatusPage|To publish incidents to an external status page, GitLab will store a JSON file in your Amazon S3 account in a location accessible to your external status page service. Make sure to also set up %{docsLink}"
+msgstr ""
+
+msgid "StatusPage|configuration documentation"
+msgstr ""
+
+msgid "StatusPage|your status page frontend."
+msgstr ""
+
+msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
+msgstr ""
+
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
+msgid "Stop Terminal"
+msgstr ""
+
+msgid "Stop impersonation"
+msgstr ""
+
+msgid "Stop this environment"
+msgstr ""
+
+msgid "Stopped"
+msgstr ""
+
+msgid "Stopping..."
+msgstr ""
+
+msgid "Storage"
+msgstr ""
+
+msgid "Storage nodes for new repositories"
+msgstr ""
+
+msgid "Storage:"
+msgstr ""
+
+msgid "StorageSize|Unknown"
+msgstr ""
+
+msgid "Subgroup milestone"
+msgstr ""
+
+msgid "Subgroup overview"
+msgstr ""
+
+msgid "SubgroupCreationLevel|Allowed to create subgroups"
+msgstr ""
+
+msgid "SubgroupCreationlevel|Allowed to create subgroups"
+msgstr ""
+
+msgid "SubgroupCreationlevel|Maintainers"
+msgstr ""
+
+msgid "SubgroupCreationlevel|Owners"
+msgstr ""
+
+msgid "Subgroups"
+msgstr ""
+
+msgid "Subgroups and projects"
+msgstr ""
+
+msgid "Subject Key Identifier:"
+msgstr ""
+
+msgid "Subkeys"
+msgstr ""
+
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
+msgid "Submit Changes"
+msgstr ""
+
+msgid "Submit a review"
+msgstr ""
+
+msgid "Submit as spam"
+msgstr ""
+
+msgid "Submit feedback"
+msgstr ""
+
+msgid "Submit issue"
+msgstr ""
+
+msgid "Submit review"
+msgstr ""
+
+msgid "Submit search"
+msgstr ""
+
+msgid "Submit the current review."
+msgstr ""
+
+msgid "Submitted the current review."
+msgstr ""
+
+msgid "Subscribe"
+msgstr ""
+
+msgid "Subscribe at group level"
+msgstr ""
+
+msgid "Subscribe at project level"
+msgstr ""
+
+msgid "Subscribe to RSS feed"
+msgstr ""
+
+msgid "Subscribe to calendar"
+msgstr ""
+
+msgid "Subscribed"
+msgstr ""
+
+msgid "Subscribed to this %{quick_action_target}."
+msgstr ""
+
+msgid "Subscribes to this %{quick_action_target}."
+msgstr ""
+
+msgid "Subscription"
+msgstr ""
+
+msgid "Subscription deletion failed."
+msgstr ""
+
+msgid "Subscription successfully applied to \"%{group_name}\""
+msgstr ""
+
+msgid "Subscription successfully created."
+msgstr ""
+
+msgid "Subscription successfully deleted."
+msgstr ""
+
+msgid "SubscriptionTable|Billing"
+msgstr ""
+
+msgid "SubscriptionTable|Free"
+msgstr ""
+
+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 ""
+
+msgid "SubscriptionTable|Last invoice"
+msgstr ""
+
+msgid "SubscriptionTable|Loading subscriptions"
+msgstr ""
+
+msgid "SubscriptionTable|Manage"
+msgstr ""
+
+msgid "SubscriptionTable|Max seats used"
+msgstr ""
+
+msgid "SubscriptionTable|Next invoice"
+msgstr ""
+
+msgid "SubscriptionTable|Seats currently in use"
+msgstr ""
+
+msgid "SubscriptionTable|Seats in subscription"
+msgstr ""
+
+msgid "SubscriptionTable|Seats owed"
+msgstr ""
+
+msgid "SubscriptionTable|Subscription end date"
+msgstr ""
+
+msgid "SubscriptionTable|Subscription start date"
+msgstr ""
+
+msgid "SubscriptionTable|This is the last time the GitLab.com team was in contact with you to settle any outstanding balances."
+msgstr ""
+
+msgid "SubscriptionTable|This is the maximum number of users that have existed at the same time since this subscription started."
+msgstr ""
+
+msgid "SubscriptionTable|This is the next date when the GitLab.com team is scheduled to get in contact with you to settle any outstanding balances."
+msgstr ""
+
+msgid "SubscriptionTable|This is the number of seats you will be required to purchase if you update to a paid plan."
+msgstr ""
+
+msgid "SubscriptionTable|Trial"
+msgstr ""
+
+msgid "SubscriptionTable|Trial end date"
+msgstr ""
+
+msgid "SubscriptionTable|Trial start date"
+msgstr ""
+
+msgid "SubscriptionTable|Upgrade"
+msgstr ""
+
+msgid "SubscriptionTable|Usage"
+msgstr ""
+
+msgid "SubscriptionTable|Usage count is performed once a day at 12:00 PM."
+msgstr ""
+
+msgid "Subscriptions"
+msgstr ""
+
+msgid "Subtracted"
+msgstr ""
+
+msgid "Subtracts"
+msgstr ""
+
+msgid "Succeeded"
+msgstr ""
+
+msgid "Successfully activated"
+msgstr ""
+
+msgid "Successfully blocked"
+msgstr ""
+
+msgid "Successfully confirmed"
+msgstr ""
+
+msgid "Successfully deactivated"
+msgstr ""
+
+msgid "Successfully deleted U2F device."
+msgstr ""
+
+msgid "Successfully removed email."
+msgstr ""
+
+msgid "Successfully scheduled a pipeline to run. Go to the %{pipelines_link_start}Pipelines page%{pipelines_link_end} for details."
+msgstr ""
+
+msgid "Successfully unblocked"
+msgstr ""
+
+msgid "Successfully unlocked"
+msgstr ""
+
+msgid "Successfully verified domain ownership"
+msgstr ""
+
+msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
+msgstr ""
+
+msgid "Suggested Solutions"
+msgstr ""
+
+msgid "Suggested change"
+msgstr ""
+
+msgid "Suggested solutions help link"
+msgstr ""
+
+msgid "SuggestedColors|Bright green"
+msgstr ""
+
+msgid "SuggestedColors|Dark grayish cyan"
+msgstr ""
+
+msgid "SuggestedColors|Dark moderate blue"
+msgstr ""
+
+msgid "SuggestedColors|Dark moderate orange"
+msgstr ""
+
+msgid "SuggestedColors|Dark moderate pink"
+msgstr ""
+
+msgid "SuggestedColors|Dark moderate violet"
+msgstr ""
+
+msgid "SuggestedColors|Feijoa"
+msgstr ""
+
+msgid "SuggestedColors|Lime green"
+msgstr ""
+
+msgid "SuggestedColors|Moderate blue"
+msgstr ""
+
+msgid "SuggestedColors|Pure red"
+msgstr ""
+
+msgid "SuggestedColors|Slightly desaturated blue"
+msgstr ""
+
+msgid "SuggestedColors|Slightly desaturated green"
+msgstr ""
+
+msgid "SuggestedColors|Soft orange"
+msgstr ""
+
+msgid "SuggestedColors|Soft red"
+msgstr ""
+
+msgid "SuggestedColors|Strong pink"
+msgstr ""
+
+msgid "SuggestedColors|Strong red"
+msgstr ""
+
+msgid "SuggestedColors|Strong yellow"
+msgstr ""
+
+msgid "SuggestedColors|UA blue"
+msgstr ""
+
+msgid "SuggestedColors|Very dark desaturated blue"
+msgstr ""
+
+msgid "SuggestedColors|Very dark lime green"
+msgstr ""
+
+msgid "SuggestedColors|Very pale orange"
+msgstr ""
+
+msgid "Suggestions:"
+msgstr ""
+
+msgid "Suite"
+msgstr ""
+
+msgid "Summary"
+msgstr ""
+
+msgid "Sunday"
+msgstr ""
+
+msgid "Support"
+msgstr ""
+
+msgid "Support for custom certificates is disabled. Ask your system's administrator to enable it."
+msgstr ""
+
+msgid "Support page URL"
+msgstr ""
+
+msgid "Survey Response"
+msgstr ""
+
+msgid "Switch branch/tag"
+msgstr ""
+
+msgid "Switch to GitLab Next"
+msgstr ""
+
+msgid "Switch to the source to copy the file contents"
+msgstr ""
+
+msgid "Sync information"
+msgstr ""
+
+msgid "Synced"
+msgstr ""
+
+msgid "Synchronization disabled"
+msgstr ""
+
+msgid "Synchronization of container repositories is disabled."
+msgstr ""
+
+msgid "System"
+msgstr ""
+
+msgid "System Hooks"
+msgstr ""
+
+msgid "System Info"
+msgstr ""
+
+msgid "System default (%{default})"
+msgstr ""
+
+msgid "System header and footer"
+msgstr ""
+
+msgid "System hook was successfully updated."
+msgstr ""
+
+msgid "System metrics (Custom)"
+msgstr ""
+
+msgid "System metrics (Kubernetes)"
+msgstr ""
+
+msgid "Table of Contents"
+msgstr ""
+
+msgid "Tag"
+msgstr ""
+
+msgid "Tag list:"
+msgstr ""
+
+msgid "Tag name"
+msgstr ""
+
+msgid "Tag this commit."
+msgstr ""
+
+msgid "Tagged this commit to %{tag_name} with \"%{message}\"."
+msgstr ""
+
+msgid "Tagged this commit to %{tag_name}."
+msgstr ""
+
+msgid "Tags"
+msgstr ""
+
+msgid "Tags feed"
+msgstr ""
+
+msgid "Tags this commit to %{tag_name} with \"%{message}\"."
+msgstr ""
+
+msgid "Tags this commit to %{tag_name}."
+msgstr ""
+
+msgid "Tags:"
+msgstr ""
+
+msgid "TagsPage|Browse commits"
+msgstr ""
+
+msgid "TagsPage|Browse files"
+msgstr ""
+
+msgid "TagsPage|Can't find HEAD commit for this tag"
+msgstr ""
+
+msgid "TagsPage|Cancel"
+msgstr ""
+
+msgid "TagsPage|Create tag"
+msgstr ""
+
+msgid "TagsPage|Delete tag"
+msgstr ""
+
+msgid "TagsPage|Deleting the %{tag_name} tag cannot be undone. Are you sure?"
+msgstr ""
+
+msgid "TagsPage|Edit release notes"
+msgstr ""
+
+msgid "TagsPage|Existing branch name, tag, or commit SHA"
+msgstr ""
+
+msgid "TagsPage|Filter by tag name"
+msgstr ""
+
+msgid "TagsPage|New Tag"
+msgstr ""
+
+msgid "TagsPage|New tag"
+msgstr ""
+
+msgid "TagsPage|Optionally, add a message to the tag. Leaving this blank creates a %{link_start}lightweight tag.%{link_end}"
+msgstr ""
+
+msgid "TagsPage|Optionally, create a public Release of your project, based on this tag. Release notes are displayed on the %{releases_page_link_start}Releases%{link_end} page. %{docs_link_start}More information%{link_end}"
+msgstr ""
+
+msgid "TagsPage|Release notes"
+msgstr ""
+
+msgid "TagsPage|Repository has no tags yet."
+msgstr ""
+
+msgid "TagsPage|Sort by"
+msgstr ""
+
+msgid "TagsPage|Tags"
+msgstr ""
+
+msgid "TagsPage|Tags give the ability to mark specific points in history as being important"
+msgstr ""
+
+msgid "TagsPage|This tag has no release notes."
+msgstr ""
+
+msgid "TagsPage|Use git tag command to add a new one:"
+msgstr ""
+
+msgid "TagsPage|Write your release notes or drag files here…"
+msgstr ""
+
+msgid "TagsPage|protected"
+msgstr ""
+
+msgid "Target Branch"
+msgstr ""
+
+msgid "Target Path"
+msgstr ""
+
+msgid "Target branch"
+msgstr ""
+
+msgid "Target-Branch"
+msgstr ""
+
+msgid "Team"
+msgstr ""
+
+msgid "Team domain"
+msgstr ""
+
+msgid "Telephone number"
+msgstr ""
+
+msgid "Telephone number (Optional)"
+msgstr ""
+
+msgid "Template"
+msgstr ""
+
+msgid "Template to append to all Service Desk issues"
+msgstr ""
+
+msgid "Template was successfully saved."
+msgstr ""
+
+msgid "Templates"
+msgstr ""
+
+msgid "Terminal"
+msgstr ""
+
+msgid "Terminal for environment"
+msgstr ""
+
+msgid "Terminal sync service is running"
+msgstr ""
+
+msgid "Terms of Service Agreement and Privacy Policy"
+msgstr ""
+
+msgid "Terms of Service and Privacy Policy"
+msgstr ""
+
+msgid "Test"
+msgstr ""
+
+msgid "Test coverage parsing"
+msgstr ""
+
+msgid "Test coverage: %d hit"
+msgid_plural "Test coverage: %d hits"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Test failed."
+msgstr ""
+
+msgid "Test settings and save changes"
+msgstr ""
+
+msgid "TestHooks|Ensure one of your projects has merge requests."
+msgstr ""
+
+msgid "TestHooks|Ensure the project has CI jobs."
+msgstr ""
+
+msgid "TestHooks|Ensure the project has CI pipelines."
+msgstr ""
+
+msgid "TestHooks|Ensure the project has at least one commit."
+msgstr ""
+
+msgid "TestHooks|Ensure the project has issues."
+msgstr ""
+
+msgid "TestHooks|Ensure the project has merge requests."
+msgstr ""
+
+msgid "TestHooks|Ensure the project has notes."
+msgstr ""
+
+msgid "TestHooks|Ensure the wiki is enabled and has pages."
+msgstr ""
+
+msgid "TestReports|%{count} errors"
+msgstr ""
+
+msgid "TestReports|%{count} failures"
+msgstr ""
+
+msgid "TestReports|%{count} jobs"
+msgstr ""
+
+msgid "TestReports|%{rate}%{sign} success rate"
+msgstr ""
+
+msgid "TestReports|Test suites"
+msgstr ""
+
+msgid "TestReports|Tests"
+msgstr ""
+
+msgid "TestReports|There are no test cases to display."
+msgstr ""
+
+msgid "TestReports|There are no test suites to show."
+msgstr ""
+
+msgid "TestReports|There are no tests to show."
+msgstr ""
+
+msgid "TestReports|There was an error fetching the test reports."
+msgstr ""
+
+msgid "Tests"
+msgstr ""
+
+msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
+msgstr ""
+
+msgid "Thank you for your feedback!"
+msgstr ""
+
+msgid "Thank you for your report. A GitLab administrator will look into it shortly."
+msgstr ""
+
+msgid "Thanks for your purchase!"
+msgstr ""
+
+msgid "Thanks! Don't show me this again"
+msgstr ""
+
+msgid "That's it, well done!%{celebrate}"
+msgstr ""
+
+msgid "The \"%{group_path}\" group allows you to sign in with your Single Sign-On Account"
+msgstr ""
+
+msgid "The \"Require approval from CODEOWNERS\" setting was moved to %{banner_link_start}Protected Branches%{banner_link_end}"
+msgstr ""
+
+msgid "The %{link_start}true-up model%{link_end} allows having more users, and additional users will incur a retroactive charge on renewal."
+msgstr ""
+
+msgid "The %{true_up_link_start}true-up model%{link_end} has a retroactive charge for these users at the next renewal. If you want to update your license sooner to prevent this, %{support_link_start}please contact our Support team%{link_end}."
+msgstr ""
+
+msgid "The %{type} contains the following error:"
+msgid_plural "The %{type} contains the following errors:"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "The Advanced Global 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 "The CSV export will be created in the background. Once finished, it will be sent to <strong>%{email}</strong> in an attachment."
+msgstr ""
+
+msgid "The Git LFS objects will <strong>not</strong> be synced."
+msgstr ""
+
+msgid "The Issue Tracker is the place to add things that need to be improved or solved in a project"
+msgstr ""
+
+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 ""
+
+msgid "The Prometheus server responded with \"bad request\". Please check your queries are correct and are supported in your Prometheus version. %{documentationLink}"
+msgstr ""
+
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. Defaults to URL"
+msgstr ""
+
+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 ""
+
+msgid "The X509 Certificate to use when mutual TLS is required to communicate with the external authorization service. If left blank, the server certificate is still validated when accessing over HTTPS."
+msgstr ""
+
+msgid "The amount of seconds after which a request to get a secondary node status will time out."
+msgstr ""
+
+msgid "The application will be used where the client secret can be kept confidential. Native mobile apps and Single Page Apps are considered non-confidential."
+msgstr ""
+
+msgid "The associated issue #%{issueId} has been closed as the error is now resolved."
+msgstr ""
+
+msgid "The branch for this project has no active pipeline configuration."
+msgstr ""
+
+msgid "The branch or tag does not exist"
+msgstr ""
+
+msgid "The character highlighter helps you keep the subject line to %{titleLength} characters and wrap the body at %{bodyLength} so they are readable in git."
+msgstr ""
+
+msgid "The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request."
+msgstr ""
+
+msgid "The collection of events added to the data gathered for that stage."
+msgstr ""
+
+msgid "The commit does not exist"
+msgstr ""
+
+msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
+msgstr ""
+
+msgid "The content of this page is not encoded in UTF-8. Edits can only be made via the Git repository."
+msgstr ""
+
+msgid "The contents of this group, its subgroups and projects will be permanently removed after %{deletion_adjourned_period} days on %{date}. After this point, your data cannot be recovered."
+msgstr ""
+
+msgid "The current issue"
+msgstr ""
+
+msgid "The data source is connected, but there is no data to display. %{documentationLink}"
+msgstr ""
+
+msgid "The default CI configuration path for new projects."
+msgstr ""
+
+msgid "The dependency list details information about the components used within your project."
+msgstr ""
+
+msgid "The deployment of this job to %{environmentLink} did not succeed."
+msgstr ""
+
+msgid "The designs you tried uploading did not change."
+msgstr ""
+
+msgid "The directory has been successfully created."
+msgstr ""
+
+msgid "The domain you entered is misformatted."
+msgstr ""
+
+msgid "The domain you entered is not allowed."
+msgstr ""
+
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
+msgid "The entered user map is not a valid JSON user map."
+msgstr ""
+
+msgid "The errors we encountered were:"
+msgstr ""
+
+msgid "The file has been successfully created."
+msgstr ""
+
+msgid "The file has been successfully deleted."
+msgstr ""
+
+msgid "The file name should have a .yml extension"
+msgstr ""
+
+msgid "The following items will NOT be exported:"
+msgstr ""
+
+msgid "The following items will be exported:"
+msgstr ""
+
+msgid "The following personal access token: %{token_names} was revoked, because a new policy to expire personal access tokens were set."
+msgid_plural "The following personal access tokens: %{token_names} were revoked, because a new policy to expire personal access tokens were set."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "The fork relationship has been removed."
+msgstr ""
+
+msgid "The global settings require you to enable Two-Factor Authentication for your account."
+msgstr ""
+
+msgid "The group and any internal projects can be viewed by any logged in user."
+msgstr ""
+
+msgid "The group and any public projects can be viewed without any authentication."
+msgstr ""
+
+msgid "The group and its projects can only be viewed by members."
+msgstr ""
+
+msgid "The group can be fully restored"
+msgstr ""
+
+msgid "The group export can be downloaded from:"
+msgstr ""
+
+msgid "The group has already been shared with this group"
+msgstr ""
+
+msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
+msgstr ""
+
+msgid "The group will be placed in 'pending removal' state"
+msgstr ""
+
+msgid "The import will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
+msgstr ""
+
+msgid "The invitation could not be accepted."
+msgstr ""
+
+msgid "The invitation could not be declined."
+msgstr ""
+
+msgid "The invitation has already been accepted."
+msgstr ""
+
+msgid "The invitation was successfully resent."
+msgstr ""
+
+msgid "The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage."
+msgstr ""
+
+msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
+msgstr ""
+
+msgid "The license was removed. GitLab has fallen back on the previous license."
+msgstr ""
+
+msgid "The license was removed. GitLab now no longer has a valid license."
+msgstr ""
+
+msgid "The license was successfully uploaded and is now active. You can see the details below."
+msgstr ""
+
+msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
+msgstr ""
+
+msgid "The maximum file size allowed is %{size}."
+msgstr ""
+
+msgid "The maximum file size allowed is 200KB."
+msgstr ""
+
+msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
+msgstr ""
+
+msgid "The merge conflicts for this merge request have already been resolved."
+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 name \"%{name}\" is already taken in this directory."
+msgstr ""
+
+msgid "The number of changes to be fetched from GitLab when cloning a repository. This can speed up Pipelines execution. Keep empty or set to 0 to disable shallow clone by default and make GitLab CI fetch all branches and tags each time."
+msgstr ""
+
+msgid "The number of times an upload record could not find its file"
+msgstr ""
+
+msgid "The one place for your designs"
+msgstr ""
+
+msgid "The passphrase required to decrypt the private key. This is optional and the value is encrypted at rest."
+msgstr ""
+
+msgid "The path to the CI configuration file. Defaults to <code>.gitlab-ci.yml</code>"
+msgstr ""
+
+msgid "The phase of the development lifecycle."
+msgstr ""
+
+msgid "The pipeline has been deleted"
+msgstr ""
+
+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 ""
+
+msgid "The planning stage shows the time from the previous step to pushing your first commit. This time will be added automatically once you push your first commit."
+msgstr ""
+
+msgid "The private key to use when a client certificate is provided. This value is encrypted at rest."
+msgstr ""
+
+msgid "The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle."
+msgstr ""
+
+msgid "The project can be accessed by any logged in user."
+msgstr ""
+
+msgid "The project can be accessed by any user who is logged in."
+msgstr ""
+
+msgid "The project can be accessed by anyone, regardless of authentication."
+msgstr ""
+
+msgid "The project can be accessed without any authentication."
+msgstr ""
+
+msgid "The project is accessible only by members of the project. Access must be granted explicitly to each user."
+msgstr ""
+
+msgid "The project is still being deleted. Please try again later."
+msgstr ""
+
+msgid "The project was successfully forked."
+msgstr ""
+
+msgid "The project was successfully imported."
+msgstr ""
+
+msgid "The pseudonymizer data collection is disabled. When enabled, 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 "The remote mirror took to long to complete."
+msgstr ""
+
+msgid "The remote repository is being updated..."
+msgstr ""
+
+msgid "The repository can be commited to, and issues, comments and other entities can be created."
+msgstr ""
+
+msgid "The repository for this project does not exist."
+msgstr ""
+
+msgid "The repository for this project is empty"
+msgstr ""
+
+msgid "The repository is being updated..."
+msgstr ""
+
+msgid "The repository must be accessible over <code>http://</code>, <code>https://</code> or <code>git://</code>."
+msgstr ""
+
+msgid "The repository must be accessible over <code>http://</code>, <code>https://</code>, <code>ssh://</code> or <code>git://</code>."
+msgstr ""
+
+msgid "The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request."
+msgstr ""
+
+msgid "The roadmap shows the progress of your epics along a timeline"
+msgstr ""
+
+msgid "The schedule time must be in the future!"
+msgstr ""
+
+msgid "The snippet can be accessed without any authentication."
+msgstr ""
+
+msgid "The snippet is visible only to me."
+msgstr ""
+
+msgid "The snippet is visible only to project members."
+msgstr ""
+
+msgid "The snippet is visible to any logged in user."
+msgstr ""
+
+msgid "The specified tab is invalid, please select another"
+msgstr ""
+
+msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
+msgstr ""
+
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
+msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
+msgstr ""
+
+msgid "The time taken by each data entry gathered by that stage."
+msgstr ""
+
+msgid "The total stage shows the time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle."
+msgstr ""
+
+msgid "The unique identifier for the Geo node. Must match %{geoNodeName} if it is set in gitlab.rb, otherwise it must match %{externalUrl} with a trailing slash"
+msgstr ""
+
+msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
+msgstr ""
+
+msgid "The uploaded file is not a valid Google Takeout archive."
+msgstr ""
+
+msgid "The usage ping is disabled, and cannot be configured through this form."
+msgstr ""
+
+msgid "The user is being deleted."
+msgstr ""
+
+msgid "The user map has been saved. Continue by selecting the projects you want to import."
+msgstr ""
+
+msgid "The user map is a JSON document mapping the Google Code users that participated on your projects to the way their email addresses and usernames will be imported into GitLab. You can change this by changing the value on the right hand side of <code>:</code>. Be sure to preserve the surrounding double quotes, other punctuation and the email address or username on the left hand side."
+msgstr ""
+
+msgid "The user map is a mapping of the FogBugz users that participated on your projects to the way their email address and usernames will be imported into GitLab. You can change this by populating the table below."
+msgstr ""
+
+msgid "The user you are trying to deactivate has been active in the past %{minimum_inactive_days} days and cannot be deactivated"
+msgstr ""
+
+msgid "The user-facing URL of the Geo node"
+msgstr ""
+
+msgid "The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6."
+msgstr ""
+
+msgid "The vulnerability is no longer detected. Verify the vulnerability has been fixed or removed before changing its status."
+msgstr ""
+
+msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
+msgstr ""
+
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
+msgid "There are no GPG keys associated with this account."
+msgstr ""
+
+msgid "There are no GPG keys with access to your account."
+msgstr ""
+
+msgid "There are no SSH keys associated with this account."
+msgstr ""
+
+msgid "There are no SSH keys with access to your account."
+msgstr ""
+
+msgid "There are no archived projects yet"
+msgstr ""
+
+msgid "There are no archived requirements"
+msgstr ""
+
+msgid "There are no changes"
+msgstr ""
+
+msgid "There are no charts configured for this page"
+msgstr ""
+
+msgid "There are no closed issues"
+msgstr ""
+
+msgid "There are no closed merge requests"
+msgstr ""
+
+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 ""
+
+msgid "There are no issues to show."
+msgstr ""
+
+msgid "There are no labels yet"
+msgstr ""
+
+msgid "There are no matching files"
+msgstr ""
+
+msgid "There are no open issues"
+msgstr ""
+
+msgid "There are no open merge requests"
+msgstr ""
+
+msgid "There are no open requirements"
+msgstr ""
+
+msgid "There are no packages yet"
+msgstr ""
+
+msgid "There are no projects shared with this group yet"
+msgstr ""
+
+msgid "There are no variables yet."
+msgstr ""
+
+msgid "There is a limit of %{ci_project_subscriptions_limit} subscriptions from or to a project."
+msgstr ""
+
+msgid "There is already a repository with that name on disk"
+msgstr ""
+
+msgid "There is no data available. Please change your selection."
+msgstr ""
+
+msgid "There was a problem communicating with your device."
+msgstr ""
+
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
+msgid "There was a problem refreshing the data, please try again"
+msgstr ""
+
+msgid "There was a problem saving your custom stage, please try again"
+msgstr ""
+
+msgid "There was a problem sending the confirmation email"
+msgstr ""
+
+msgid "There was an error %{message} todo."
+msgstr ""
+
+msgid "There was an error adding a To Do."
+msgstr ""
+
+msgid "There was an error creating the dashboard, branch name is invalid."
+msgstr ""
+
+msgid "There was an error creating the dashboard, branch named: %{branch} already exists."
+msgstr ""
+
+msgid "There was an error creating the issue"
+msgstr ""
+
+msgid "There was an error deleting the To Do."
+msgstr ""
+
+msgid "There was an error fetching configuration for charts"
+msgstr ""
+
+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 ""
+
+msgid "There was an error fetching label data for the selected group"
+msgstr ""
+
+msgid "There was an error fetching median data for stages"
+msgstr ""
+
+msgid "There was an error fetching the %{replicableType}"
+msgstr ""
+
+msgid "There was an error fetching the Node's Groups"
+msgstr ""
+
+msgid "There was an error fetching the environments information."
+msgstr ""
+
+msgid "There was an error fetching the top labels for the selected group"
+msgstr ""
+
+msgid "There was an error fetching the variables."
+msgstr ""
+
+msgid "There was an error fetching value stream analytics stages."
+msgstr ""
+
+msgid "There was an error gathering the chart data"
+msgstr ""
+
+msgid "There was an error getting the epic participants."
+msgstr ""
+
+msgid "There was an error importing the Jira project."
+msgstr ""
+
+msgid "There was an error loading users activity calendar."
+msgstr ""
+
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
+msgid "There was an error removing the e-mail."
+msgstr ""
+
+msgid "There was an error removing your custom stage, please try again"
+msgstr ""
+
+msgid "There was an error resetting group pipeline minutes."
+msgstr ""
+
+msgid "There was an error resetting user pipeline minutes."
+msgstr ""
+
+msgid "There was an error saving this Geo Node."
+msgstr ""
+
+msgid "There was an error saving your changes."
+msgstr ""
+
+msgid "There was an error saving your notification settings."
+msgstr ""
+
+msgid "There was an error subscribing to this label."
+msgstr ""
+
+msgid "There was an error syncing project %{name}"
+msgstr ""
+
+msgid "There was an error syncing the %{replicableType}"
+msgstr ""
+
+msgid "There was an error trying to validate your query"
+msgstr ""
+
+msgid "There was an error updating the dashboard, branch name is invalid."
+msgstr ""
+
+msgid "There was an error updating the dashboard, branch named: %{branch} already exists."
+msgstr ""
+
+msgid "There was an error updating the stage order. Please try reloading the page."
+msgstr ""
+
+msgid "There was an error when reseting email token."
+msgstr ""
+
+msgid "There was an error when subscribing to this label."
+msgstr ""
+
+msgid "There was an error when unsubscribing from this label."
+msgstr ""
+
+msgid "There was an error while fetching value stream analytics data."
+msgstr ""
+
+msgid "There was an error while fetching value stream analytics duration data."
+msgstr ""
+
+msgid "There was an error while fetching value stream analytics duration median data."
+msgstr ""
+
+msgid "There was an error while fetching value stream analytics recent activity data."
+msgstr ""
+
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
+msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
+msgstr ""
+
+msgid "These existing issues have a similar title. It might be better to comment there instead of creating another similar issue."
+msgstr ""
+
+msgid "These variables are configured in the parent group settings, and will be active in the current project in addition to the project variables."
+msgstr ""
+
+msgid "They can be managed using the %{link}."
+msgstr ""
+
+msgid "Third Party Advisory Link"
+msgstr ""
+
+msgid "Third party offers"
+msgstr ""
+
+msgid "This %{issuableDisplayName} is locked. Only project members can comment."
+msgstr ""
+
+msgid "This %{issuable} is locked. Only <strong>project members</strong> can comment."
+msgstr ""
+
+msgid "This %{viewer} could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
+msgid "This GitLab instance does not provide any shared Runners yet. Instance administrators can register shared Runners in the admin area."
+msgstr ""
+
+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 ""
+
+msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
+msgstr ""
+
+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 ""
+
+msgid "This also resolves the discussion"
+msgstr ""
+
+msgid "This application was created by %{link_to_owner}."
+msgstr ""
+
+msgid "This application will be able to:"
+msgstr ""
+
+msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of 15MB. %{written_count} of %{issues_count} issues have been included. Consider re-exporting with a narrower selection of issues."
+msgstr ""
+
+msgid "This block is self-referential"
+msgstr ""
+
+msgid "This board's scope is reduced"
+msgstr ""
+
+msgid "This branch has changed since you started editing. Would you like to create a new branch?"
+msgstr ""
+
+msgid "This chart could not be displayed"
+msgstr ""
+
+msgid "This comment has changed since you started editing, please review the %{startTag}updated comment%{endTag} to ensure information is not lost."
+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 ""
+
+msgid "This commit was signed with a <strong>verified</strong> signature and the committer email is verified to belong to the same user."
+msgstr ""
+
+msgid "This commit was signed with a different user's verified signature."
+msgstr ""
+
+msgid "This commit was signed with a verified signature, but the committer email is <strong>not verified</strong> to belong to the same user."
+msgstr ""
+
+msgid "This commit was signed with an <strong>unverified</strong> signature."
+msgstr ""
+
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
+msgid "This date is after the due date, so this epic won't appear in the roadmap."
+msgstr ""
+
+msgid "This date is before the start date, so this epic won't appear in the roadmap."
+msgstr ""
+
+msgid "This device has already been registered with us."
+msgstr ""
+
+msgid "This device has not been registered with us."
+msgstr ""
+
+msgid "This diff is collapsed."
+msgstr ""
+
+msgid "This diff was suppressed by a .gitattributes entry."
+msgstr ""
+
+msgid "This directory"
+msgstr ""
+
+msgid "This domain is not verified. You will need to verify ownership before access is enabled."
+msgstr ""
+
+msgid "This endpoint has been requested too many times. Try again later."
+msgstr ""
+
+msgid "This environment has no deployments yet."
+msgstr ""
+
+msgid "This environment is being deployed"
+msgstr ""
+
+msgid "This environment is being re-deployed"
+msgstr ""
+
+msgid "This epic already has the maximum number of child epics."
+msgstr ""
+
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
+msgid "This epic does not exist or you don't have sufficient permission."
+msgstr ""
+
+msgid "This feature requires local storage to be enabled"
+msgstr ""
+
+msgid "This field is required."
+msgstr ""
+
+msgid "This group"
+msgstr ""
+
+msgid "This group cannot be invited to a project inside a group with enforced SSO"
+msgstr ""
+
+msgid "This group does not provide any group Runners yet."
+msgstr ""
+
+msgid "This group has been scheduled for permanent removal on %{date}"
+msgstr ""
+
+msgid "This group, including all subgroups, projects and git repositories, will only be reachable from the specified IP address range. Multiple addresses are supported with comma delimiters.<br>Example: <code>192.168.0.0/24,192.168.1.0/24</code>. %{read_more_link}."
+msgstr ""
+
+msgid "This group, its subgroups and projects has been scheduled for removal on %{date}."
+msgstr ""
+
+msgid "This group, its subgroups and projects will be removed on %{date} since its parent group '%{parent_group_name}'' has been scheduled for removal."
+msgstr ""
+
+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 Work in Progress"
+msgstr ""
+
+msgid "This is a confidential issue."
+msgstr ""
+
+msgid "This is a delayed job to run in %{remainingTime}"
+msgstr ""
+
+msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
+msgstr ""
+
+msgid "This is a security log of important events involving your account."
+msgstr ""
+
+msgid "This is the author's first Merge Request to this project."
+msgstr ""
+
+msgid "This is the highest peak of users on your installation since the license started."
+msgstr ""
+
+msgid "This is the maximum number of users that have existed at the same time since the license started. This is the minimum number of seats you will need to buy when you renew your license."
+msgstr ""
+
+msgid "This is the number of currently active users on your installation, and this is the minimum number you need to purchase when you renew your license."
+msgstr ""
+
+msgid "This is your current session"
+msgstr ""
+
+msgid "This issue is %{confidentialLinkStart}confidential%{linkEnd} and %{lockedLinkStart}locked%{linkEnd}."
+msgstr ""
+
+msgid "This issue is confidential"
+msgstr ""
+
+msgid "This issue is currently blocked by the following issues: %{issues}."
+msgstr ""
+
+msgid "This issue is in a child epic of the filtered epic"
+msgstr ""
+
+msgid "This issue is locked."
+msgstr ""
+
+msgid "This job depends on other jobs with expired/erased artifacts: %{invalid_dependencies}"
+msgstr ""
+
+msgid "This job depends on upstream jobs that need to succeed in order for this job to be triggered"
+msgstr ""
+
+msgid "This job does not have a trace."
+msgstr ""
+
+msgid "This job has been canceled"
+msgstr ""
+
+msgid "This job has been skipped"
+msgstr ""
+
+msgid "This job has not been triggered yet"
+msgstr ""
+
+msgid "This job has not started yet"
+msgstr ""
+
+msgid "This job is an out-of-date deployment to %{environmentLink} using cluster %{clusterNameOrLink} and namespace %{kubernetesNamespace}."
+msgstr ""
+
+msgid "This job is an out-of-date deployment to %{environmentLink} using cluster %{clusterNameOrLink} and namespace %{kubernetesNamespace}. View the %{deploymentLink}."
+msgstr ""
+
+msgid "This job is an out-of-date deployment to %{environmentLink} using cluster %{clusterNameOrLink}."
+msgstr ""
+
+msgid "This job is an out-of-date deployment to %{environmentLink} using cluster %{clusterNameOrLink}. View the %{deploymentLink}."
+msgstr ""
+
+msgid "This job is an out-of-date deployment to %{environmentLink}."
+msgstr ""
+
+msgid "This job is an out-of-date deployment to %{environmentLink}. View the %{deploymentLink}."
+msgstr ""
+
+msgid "This job is archived. Only the complete pipeline can be retried."
+msgstr ""
+
+msgid "This job is creating a deployment to %{environmentLink} using cluster %{clusterNameOrLink} and namespace %{kubernetesNamespace}."
+msgstr ""
+
+msgid "This job is creating a deployment to %{environmentLink} using cluster %{clusterNameOrLink} and namespace %{kubernetesNamespace}. This will overwrite the %{deploymentLink}."
+msgstr ""
+
+msgid "This job is creating a deployment to %{environmentLink} using cluster %{clusterNameOrLink}."
+msgstr ""
+
+msgid "This job is creating a deployment to %{environmentLink} using cluster %{clusterNameOrLink}. This will overwrite the %{deploymentLink}."
+msgstr ""
+
+msgid "This job is creating a deployment to %{environmentLink}."
+msgstr ""
+
+msgid "This job is creating a deployment to %{environmentLink}. This will overwrite the %{deploymentLink}."
+msgstr ""
+
+msgid "This job is deployed to %{environmentLink} using cluster %{clusterNameOrLink} and namespace %{kubernetesNamespace}."
+msgstr ""
+
+msgid "This job is deployed to %{environmentLink} using cluster %{clusterNameOrLink}."
+msgstr ""
+
+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 ""
+
+msgid "This job is performing tasks that must complete before it can start"
+msgstr ""
+
+msgid "This job is preparing to start"
+msgstr ""
+
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
+msgstr ""
+
+msgid "This job is stuck because you don't have any active runners that can run this job."
+msgstr ""
+
+msgid "This job is waiting for resource: "
+msgstr ""
+
+msgid "This job requires a manual action"
+msgstr ""
+
+msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
+msgstr ""
+
+msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
+msgstr ""
+
+msgid "This license has already expired."
+msgstr ""
+
+msgid "This may expose confidential information as the selected fork is in another namespace that can have other members."
+msgstr ""
+
+msgid "This means you can not push code until you create an empty repository or import existing one."
+msgstr ""
+
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
+msgid "This merge request is locked."
+msgstr ""
+
+msgid "This namespace has already been taken! Please choose another one."
+msgstr ""
+
+msgid "This only applies to repository indexing operations."
+msgstr ""
+
+msgid "This option is only available on GitLab.com"
+msgstr ""
+
+msgid "This page is unavailable because you are not allowed to read information across multiple projects."
+msgstr ""
+
+msgid "This page will be removed in a future release."
+msgstr ""
+
+msgid "This pipeline makes use of a predefined CI/CD configuration enabled by %{strongStart}Auto DevOps.%{strongEnd}"
+msgstr ""
+
+msgid "This pipeline makes use of a predefined CI/CD configuration enabled by <b>Auto DevOps.</b>"
+msgstr ""
+
+msgid "This pipeline triggered a child pipeline"
+msgstr ""
+
+msgid "This pipeline was triggered by a parent pipeline"
+msgstr ""
+
+msgid "This project"
+msgstr ""
+
+msgid "This project does not belong to a group and can therefore not make use of group Runners."
+msgstr ""
+
+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 ""
+
+msgid "This project does not have a wiki homepage yet"
+msgstr ""
+
+msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
+msgstr ""
+
+msgid "This project has no active access tokens."
+msgstr ""
+
+msgid "This project is archived and cannot be commented on."
+msgstr ""
+
+msgid "This project path either does not exist or you do not have access."
+msgstr ""
+
+msgid "This project will be removed on %{date}"
+msgstr ""
+
+msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
+msgstr ""
+
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
+msgid "This repository"
+msgstr ""
+
+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 ""
+
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
+msgid "This runner will only run on pipelines triggered on protected branches"
+msgstr ""
+
+msgid "This setting can be overridden in each project."
+msgstr ""
+
+msgid "This setting will update the hostname that is used to generate private commit emails. %{learn_more}"
+msgstr ""
+
+msgid "This subscription is for"
+msgstr ""
+
+msgid "This timeout will take precedence when lower than project-defined timeout and accepts a human readable time input language like \"1 hour\". Values without specification represent seconds."
+msgstr ""
+
+msgid "This user cannot be unlocked manually from GitLab"
+msgstr ""
+
+msgid "This user has no active %{type}."
+msgstr ""
+
+msgid "This user has no identities"
+msgstr ""
+
+msgid "This 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 ""
+
+msgid "This variable can not be masked."
+msgstr ""
+
+msgid "This variable does not match the expected pattern."
+msgstr ""
+
+msgid "This will help us personalize your onboarding experience."
+msgstr ""
+
+msgid "This will redirect you to an external sign in page."
+msgstr ""
+
+msgid "This will remove the fork relationship between this project and %{fork_source}."
+msgstr ""
+
+msgid "This will remove the fork relationship between this project and other projects in the fork network."
+msgstr ""
+
+msgid "Those emails automatically become issues (with the comments becoming the email conversation) listed here."
+msgstr ""
+
+msgid "Thread to reply to cannot be found"
+msgstr ""
+
+msgid "Threat Monitoring"
+msgstr ""
+
+msgid "ThreatMonitoring|Anomalous Requests"
+msgstr ""
+
+msgid "ThreatMonitoring|Application firewall not detected"
+msgstr ""
+
+msgid "ThreatMonitoring|Container Network Policies are not installed or have been disabled. To view this data, ensure your Network Policies are installed and enabled for your cluster."
+msgstr ""
+
+msgid "ThreatMonitoring|Container Network Policy"
+msgstr ""
+
+msgid "ThreatMonitoring|Container NetworkPolicies not detected"
+msgstr ""
+
+msgid "ThreatMonitoring|Dropped Packets"
+msgstr ""
+
+msgid "ThreatMonitoring|Environment"
+msgstr ""
+
+msgid "ThreatMonitoring|No environments detected"
+msgstr ""
+
+msgid "ThreatMonitoring|Operations Per Second"
+msgstr ""
+
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
+msgid "ThreatMonitoring|Packet Activity"
+msgstr ""
+
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
+msgid "ThreatMonitoring|Requests"
+msgstr ""
+
+msgid "ThreatMonitoring|Show last"
+msgstr ""
+
+msgid "ThreatMonitoring|Something went wrong, unable to fetch environments"
+msgstr ""
+
+msgid "ThreatMonitoring|Something went wrong, unable to fetch statistics"
+msgstr ""
+
+msgid "ThreatMonitoring|The firewall is not installed or has been disabled. To view this data, ensure the web application firewall is installed and enabled for your cluster."
+msgstr ""
+
+msgid "ThreatMonitoring|The graph below is an overview of traffic coming to your application as tracked by the Web Application Firewall (WAF). View the docs for instructions on how to access the WAF logs to see what type of malicious traffic is trying to access your app. The docs link is also accessible by clicking the \"?\" icon next to the title below."
+msgstr ""
+
+msgid "ThreatMonitoring|Threat Monitoring"
+msgstr ""
+
+msgid "ThreatMonitoring|Threat Monitoring help page link"
+msgstr ""
+
+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."
+msgstr ""
+
+msgid "ThreatMonitoring|Total Packets"
+msgstr ""
+
+msgid "ThreatMonitoring|Total Requests"
+msgstr ""
+
+msgid "ThreatMonitoring|View documentation"
+msgstr ""
+
+msgid "ThreatMonitoring|Web Application Firewall"
+msgstr ""
+
+msgid "ThreatMonitoring|While it's rare to have no traffic coming to your application, it can happen. In any event, we ask that you double check your settings to make sure you've set up the WAF correctly."
+msgstr ""
+
+msgid "Thursday"
+msgstr ""
+
+msgid "Time"
+msgstr ""
+
+msgid "Time based: Yes"
+msgstr ""
+
+msgid "Time before an issue gets scheduled"
+msgstr ""
+
+msgid "Time before an issue starts implementation"
+msgstr ""
+
+msgid "Time before enforced"
+msgstr ""
+
+msgid "Time between merge request creation and merge/close"
+msgstr ""
+
+msgid "Time estimate"
+msgstr ""
+
+msgid "Time from first comment to last commit"
+msgstr ""
+
+msgid "Time from first commit until first comment"
+msgstr ""
+
+msgid "Time from last commit to merge"
+msgstr ""
+
+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 ""
+
+msgid "Time of import: %{importTime}"
+msgstr ""
+
+msgid "Time remaining"
+msgstr ""
+
+msgid "Time spent"
+msgstr ""
+
+msgid "Time to merge"
+msgstr ""
+
+msgid "Time to subtract exceeds the total time spent"
+msgstr ""
+
+msgid "Time tracking"
+msgstr ""
+
+msgid "Time until first merge request"
+msgstr ""
+
+msgid "TimeTrackingEstimated|Est"
+msgstr ""
+
+msgid "TimeTracking|%{startTag}Spent: %{endTag}%{timeSpentHumanReadable}"
+msgstr ""
+
+msgid "TimeTracking|Estimated:"
+msgstr ""
+
+msgid "TimeTracking|Over by %{timeRemainingHumanReadable}"
+msgstr ""
+
+msgid "TimeTracking|Spent"
+msgstr ""
+
+msgid "TimeTracking|Time remaining: %{timeRemainingHumanReadable}"
+msgstr ""
+
+msgid "Timeago|%s days ago"
+msgstr ""
+
+msgid "Timeago|%s days remaining"
+msgstr ""
+
+msgid "Timeago|%s hours ago"
+msgstr ""
+
+msgid "Timeago|%s hours remaining"
+msgstr ""
+
+msgid "Timeago|%s minutes ago"
+msgstr ""
+
+msgid "Timeago|%s minutes remaining"
+msgstr ""
+
+msgid "Timeago|%s months ago"
+msgstr ""
+
+msgid "Timeago|%s months remaining"
+msgstr ""
+
+msgid "Timeago|%s seconds remaining"
+msgstr ""
+
+msgid "Timeago|%s weeks ago"
+msgstr ""
+
+msgid "Timeago|%s weeks remaining"
+msgstr ""
+
+msgid "Timeago|%s years ago"
+msgstr ""
+
+msgid "Timeago|%s years remaining"
+msgstr ""
+
+msgid "Timeago|1 day ago"
+msgstr ""
+
+msgid "Timeago|1 day remaining"
+msgstr ""
+
+msgid "Timeago|1 hour ago"
+msgstr ""
+
+msgid "Timeago|1 hour remaining"
+msgstr ""
+
+msgid "Timeago|1 minute ago"
+msgstr ""
+
+msgid "Timeago|1 minute remaining"
+msgstr ""
+
+msgid "Timeago|1 month ago"
+msgstr ""
+
+msgid "Timeago|1 month remaining"
+msgstr ""
+
+msgid "Timeago|1 week ago"
+msgstr ""
+
+msgid "Timeago|1 week remaining"
+msgstr ""
+
+msgid "Timeago|1 year ago"
+msgstr ""
+
+msgid "Timeago|1 year remaining"
+msgstr ""
+
+msgid "Timeago|Past due"
+msgstr ""
+
+msgid "Timeago|in %s days"
+msgstr ""
+
+msgid "Timeago|in %s hours"
+msgstr ""
+
+msgid "Timeago|in %s minutes"
+msgstr ""
+
+msgid "Timeago|in %s months"
+msgstr ""
+
+msgid "Timeago|in %s seconds"
+msgstr ""
+
+msgid "Timeago|in %s weeks"
+msgstr ""
+
+msgid "Timeago|in %s years"
+msgstr ""
+
+msgid "Timeago|in 1 day"
+msgstr ""
+
+msgid "Timeago|in 1 hour"
+msgstr ""
+
+msgid "Timeago|in 1 minute"
+msgstr ""
+
+msgid "Timeago|in 1 month"
+msgstr ""
+
+msgid "Timeago|in 1 week"
+msgstr ""
+
+msgid "Timeago|in 1 year"
+msgstr ""
+
+msgid "Timeago|just now"
+msgstr ""
+
+msgid "Timeago|right now"
+msgstr ""
+
+msgid "Timeout"
+msgstr ""
+
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
+msgid "Time|hr"
+msgid_plural "Time|hrs"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Time|min"
+msgid_plural "Time|mins"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Time|s"
+msgstr ""
+
+msgid "Tip:"
+msgstr ""
+
+msgid "Title"
+msgstr ""
+
+msgid "Title:"
+msgstr ""
+
+msgid "Titles and Descriptions"
+msgstr ""
+
+msgid "To"
+msgstr ""
+
+msgid "To %{link_to_help} of your domain, add the above key to a TXT record within to your DNS configuration."
+msgstr ""
+
+msgid "To Do"
+msgstr ""
+
+msgid "To GitLab"
+msgstr ""
+
+msgid "To access this domain create a new DNS record"
+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 ""
+
+msgid "To add the entry manually, provide the following details to the application on your phone."
+msgstr ""
+
+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>repo</code> scope, so we can display a list of your public and private repositories which are available to connect."
+msgstr ""
+
+msgid "To connect GitHub repositories, you first need to authorize GitLab to access the list of your GitHub repositories."
+msgstr ""
+
+msgid "To connect GitHub repositories, you first need to authorize GitLab to access the list of your GitHub repositories:"
+msgstr ""
+
+msgid "To connect an SVN repository, check out %{svn_link}."
+msgstr ""
+
+msgid "To define internal users, first enable new users set to external"
+msgstr ""
+
+msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
+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 ""
+
+msgid "To get started, link this page to your Jaeger server, or find out how to %{link_start_tag}install Jaeger%{link_end_tag}"
+msgstr ""
+
+msgid "To get started, please enter your Gitea Host URL and a %{link_to_personal_token}."
+msgstr ""
+
+msgid "To help improve GitLab and its user experience, GitLab will periodically collect usage information."
+msgstr ""
+
+msgid "To help improve GitLab, we would like to periodically collect usage information. This can be changed at any time in %{settings_link_start}Settings%{link_end}. %{info_link_start}More Information%{link_end}"
+msgstr ""
+
+msgid "To import an SVN repository, check out %{svn_link}."
+msgstr ""
+
+msgid "To keep this project going, create a new issue"
+msgstr ""
+
+msgid "To keep this project going, create a new merge request"
+msgstr ""
+
+msgid "To link Sentry to GitLab, enter your Sentry URL and Auth Token."
+msgstr ""
+
+msgid "To move or copy an entire GitLab project from another GitLab installation to this one, navigate to the original project's settings page, generate an export file, and upload it here."
+msgstr ""
+
+msgid "To only use CI/CD features for an external repository, choose <strong>CI/CD for external repo</strong>."
+msgstr ""
+
+msgid "To open Jaeger and easily view tracing from GitLab, link the %{link} page to your server"
+msgstr ""
+
+msgid "To preserve performance only <strong>%{display_size} of %{real_size}</strong> files are displayed."
+msgstr ""
+
+msgid "To protect this issue's confidentiality, %{forkLink} and set the fork's visibility to private."
+msgstr ""
+
+msgid "To protect this issue's confidentiality, a private fork of this project was selected."
+msgstr ""
+
+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 ""
+
+msgid "To see all the user's personal access tokens you must impersonate them first."
+msgstr ""
+
+msgid "To see this project's operational details, %{linkStart}upgrade its group plan to Silver%{linkEnd}. You can also remove the project from the dashboard."
+msgstr ""
+
+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 ""
+
+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:"
+msgstr ""
+
+msgid "To simplify the billing process, GitLab will collect user counts in order to prorate charges for user growth throughout the year using a quarterly reconciliation process."
+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."
+msgstr ""
+
+msgid "To start serving your jobs you can add Runners to your group"
+msgstr ""
+
+msgid "To start serving your jobs you can either add specific Runners to your project or use shared Runners"
+msgstr ""
+
+msgid "To this GitLab instance"
+msgstr ""
+
+msgid "To view the roadmap, add a start or due date to one of your epics in this group or its subgroups. In the months view, only epics in the past month, current month, and next 5 months are shown."
+msgstr ""
+
+msgid "To widen your search, change or remove filters above"
+msgstr ""
+
+msgid "To widen your search, change or remove filters."
+msgstr ""
+
+msgid "To-Do List"
+msgstr ""
+
+msgid "To-do item successfully marked as done."
+msgstr ""
+
+msgid "Today"
+msgstr ""
+
+msgid "Toggle Markdown preview"
+msgstr ""
+
+msgid "Toggle Sidebar"
+msgstr ""
+
+msgid "Toggle all threads"
+msgstr ""
+
+msgid "Toggle backtrace"
+msgstr ""
+
+msgid "Toggle collapse"
+msgstr ""
+
+msgid "Toggle comments for this file"
+msgstr ""
+
+msgid "Toggle commit description"
+msgstr ""
+
+msgid "Toggle commit list"
+msgstr ""
+
+msgid "Toggle dropdown"
+msgstr ""
+
+msgid "Toggle emoji award"
+msgstr ""
+
+msgid "Toggle navigation"
+msgstr ""
+
+msgid "Toggle project"
+msgstr ""
+
+msgid "Toggle sidebar"
+msgstr ""
+
+msgid "Toggle the Performance Bar"
+msgstr ""
+
+msgid "Toggle this dialog"
+msgstr ""
+
+msgid "Toggle thread"
+msgstr ""
+
+msgid "ToggleButton|Toggle Status: OFF"
+msgstr ""
+
+msgid "ToggleButton|Toggle Status: ON"
+msgstr ""
+
+msgid "Toggled :%{name}: emoji award."
+msgstr ""
+
+msgid "Toggles :%{name}: emoji award."
+msgstr ""
+
+msgid "Tomorrow"
+msgstr ""
+
+msgid "Too many changes to show."
+msgstr ""
+
+msgid "Too many namespaces enabled. You will need to manage them via the console or the API."
+msgstr ""
+
+msgid "Too many projects enabled. You will need to manage them via the console or the API."
+msgstr ""
+
+msgid "Topics (optional)"
+msgstr ""
+
+msgid "Total"
+msgstr ""
+
+msgid "Total Contributions"
+msgstr ""
+
+msgid "Total artifacts size: %{total_size}"
+msgstr ""
+
+msgid "Total issues"
+msgstr ""
+
+msgid "Total test time for all commits/merges"
+msgstr ""
+
+msgid "Total weight"
+msgstr ""
+
+msgid "Total: %{total}"
+msgstr ""
+
+msgid "Trace"
+msgstr ""
+
+msgid "Tracing"
+msgstr ""
+
+msgid "Track groups of issues that share a theme, across projects and milestones"
+msgstr ""
+
+msgid "Track time with quick actions"
+msgstr ""
+
+msgid "Track your GitLab projects with GitLab for Slack."
+msgstr ""
+
+msgid "Track your project with Audit Events."
+msgstr ""
+
+msgid "Transfer ownership"
+msgstr ""
+
+msgid "Transfer project"
+msgstr ""
+
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
+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 ""
+
+msgid "TransferGroup|Database is not supported."
+msgstr ""
+
+msgid "TransferGroup|Group contains projects with NPM packages."
+msgstr ""
+
+msgid "TransferGroup|Group is already a root group."
+msgstr ""
+
+msgid "TransferGroup|Group is already associated to the parent group."
+msgstr ""
+
+msgid "TransferGroup|The parent group already has a subgroup with the same path."
+msgstr ""
+
+msgid "TransferGroup|Transfer failed: %{error_message}"
+msgstr ""
+
+msgid "TransferGroup|You don't have enough permissions."
+msgstr ""
+
+msgid "TransferProject|Cannot move project"
+msgstr ""
+
+msgid "TransferProject|Please select a new namespace for your project."
+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"
+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 "Tree view"
+msgstr ""
+
+msgid "Trending"
+msgstr ""
+
+msgid "Trials|Go back to GitLab"
+msgstr ""
+
+msgid "Trials|Skip Trial (Continue with Free Account)"
+msgstr ""
+
+msgid "Trials|You can always resume this process by selecting your avatar and choosing 'Start a Gold trial'"
+msgstr ""
+
+msgid "Trials|You won't get a free trial right now but you can always resume this process by clicking on your avatar and choosing 'Start a free trial'"
+msgstr ""
+
+msgid "Trigger"
+msgstr ""
+
+msgid "Trigger pipelines for mirror updates"
+msgstr ""
+
+msgid "Trigger pipelines when branches or tags are updated from the upstream repository. Depending on the activity of the upstream repository, this may greatly increase the load on your CI runners. Only enable this if you know they can handle the load."
+msgstr ""
+
+msgid "Trigger removed."
+msgstr ""
+
+msgid "Trigger this manual action"
+msgstr ""
+
+msgid "Trigger token:"
+msgstr ""
+
+msgid "Trigger variables:"
+msgstr ""
+
+msgid "Trigger was created successfully."
+msgstr ""
+
+msgid "Trigger was successfully updated."
+msgstr ""
+
+msgid "Triggerer"
+msgstr ""
+
+msgid "Triggers can force a specific branch or tag to get rebuilt with an API call. These tokens will impersonate their associated user including their access to projects and their project permissions."
+msgstr ""
+
+msgid "Troubleshoot and monitor your application with tracing"
+msgstr ""
+
+msgid "Try again"
+msgstr ""
+
+msgid "Try again?"
+msgstr ""
+
+msgid "Try all GitLab has to offer for 30 days."
+msgstr ""
+
+msgid "Try changing or removing filters."
+msgstr ""
+
+msgid "Try to fork again"
+msgstr ""
+
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
+msgid "Try using a different search term to find the file you are looking for."
+msgstr ""
+
+msgid "Trying to communicate with your device. Plug it in (if you haven't already) and press the button on the device now."
+msgstr ""
+
+msgid "Tuesday"
+msgstr ""
+
+msgid "Turn Off"
+msgstr ""
+
+msgid "Turn On"
+msgstr ""
+
+msgid "Turn on Service Desk"
+msgstr ""
+
+msgid "Twitter"
+msgstr ""
+
+msgid "Two-Factor Authentication"
+msgstr ""
+
+msgid "Two-Factor Authentication code"
+msgstr ""
+
+msgid "Two-factor Authentication"
+msgstr ""
+
+msgid "Two-factor Authentication Recovery codes"
+msgstr ""
+
+msgid "Two-factor Authentication has been disabled for this user"
+msgstr ""
+
+msgid "Two-factor authentication"
+msgstr ""
+
+msgid "Type"
+msgstr ""
+
+msgid "Type/State"
+msgstr ""
+
+msgid "U2F Devices (%{length})"
+msgstr ""
+
+msgid "U2F only works with HTTPS-enabled websites. Contact your administrator for more details."
+msgstr ""
+
+msgid "URL"
+msgstr ""
+
+msgid "URL is required"
+msgstr ""
+
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgstr ""
+
+msgid "URL of the external Spam Check endpoint"
+msgstr ""
+
+msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
+msgstr ""
+
+msgid "URL or request ID"
+msgstr ""
+
+msgid "UTC"
+msgstr ""
+
+msgid "Unable to apply suggestions to a deleted line."
+msgstr ""
+
+msgid "Unable to build Slack link."
+msgstr ""
+
+msgid "Unable to collect CPU info"
+msgstr ""
+
+msgid "Unable to collect memory info"
+msgstr ""
+
+msgid "Unable to connect to Elasticsearch"
+msgstr ""
+
+msgid "Unable to connect to Prometheus server"
+msgstr ""
+
+msgid "Unable to connect to server: %{error}"
+msgstr ""
+
+msgid "Unable to connect to the Jira instance. Please check your Jira integration configuration."
+msgstr ""
+
+msgid "Unable to convert Kubernetes logs encoding to UTF-8"
+msgstr ""
+
+msgid "Unable to fetch unscanned projects"
+msgstr ""
+
+msgid "Unable to fetch vulnerable projects"
+msgstr ""
+
+msgid "Unable to find Jira project to import data from."
+msgstr ""
+
+msgid "Unable to generate new instance ID"
+msgstr ""
+
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
+msgid "Unable to load the diff"
+msgstr ""
+
+msgid "Unable to load the diff. %{button_try_again}"
+msgstr ""
+
+msgid "Unable to load the merge request widget. Try reloading the page."
+msgstr ""
+
+msgid "Unable to process group import file"
+msgstr ""
+
+msgid "Unable to resolve"
+msgstr ""
+
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
+msgid "Unable to save your changes. Please try again."
+msgstr ""
+
+msgid "Unable to schedule a pipeline to run immediately"
+msgstr ""
+
+msgid "Unable to sign you in to the group with SAML due to \"%{reason}\""
+msgstr ""
+
+msgid "Unable to update label prioritization at this time"
+msgstr ""
+
+msgid "Unable to update this epic at this time."
+msgstr ""
+
+msgid "Unable to update this issue at this time."
+msgstr ""
+
+msgid "Unarchive project"
+msgstr ""
+
+msgid "Unarchiving the project will restore people's ability to make changes to it. The repository can be committed to, and issues, comments, and other entities can be created. %{strong_start}Once active, this project shows up in the search and on the dashboard.%{strong_end}"
+msgstr ""
+
+msgid "Unblock"
+msgstr ""
+
+msgid "Undo"
+msgstr ""
+
+msgid "Undo Ignore"
+msgstr ""
+
+msgid "Undo ignore"
+msgstr ""
+
+msgid "Unfortunately, your email message to GitLab could not be processed."
+msgstr ""
+
+msgid "Uninstall"
+msgstr ""
+
+msgid "Uninstalling"
+msgstr ""
+
+msgid "Units|ms"
+msgstr ""
+
+msgid "Units|s"
+msgstr ""
+
+msgid "Unknown"
+msgstr ""
+
+msgid "Unknown Error"
+msgstr ""
+
+msgid "Unknown cache key"
+msgstr ""
+
+msgid "Unknown encryption strategy: %{encrypted_strategy}!"
+msgstr ""
+
+msgid "Unknown format"
+msgstr ""
+
+msgid "Unknown response text"
+msgstr ""
+
+msgid "Unlimited"
+msgstr ""
+
+msgid "Unlock"
+msgstr ""
+
+msgid "Unlock the discussion"
+msgstr ""
+
+msgid "Unlock this %{issuableDisplayName}? <strong>Everyone</strong> will be able to comment."
+msgstr ""
+
+msgid "Unlocked"
+msgstr ""
+
+msgid "Unlocked the discussion."
+msgstr ""
+
+msgid "Unlocks the discussion."
+msgstr ""
+
+msgid "Unmarked this %{noun} as Work In Progress."
+msgstr ""
+
+msgid "Unmarks this %{noun} as Work In Progress."
+msgstr ""
+
+msgid "Unreachable"
+msgstr ""
+
+msgid "Unresolve"
+msgstr ""
+
+msgid "Unresolve thread"
+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 "UnscannedProjects|Default branch scanning by project"
+msgstr ""
+
+msgid "UnscannedProjects|Out of date"
+msgstr ""
+
+msgid "UnscannedProjects|Project scanning"
+msgstr ""
+
+msgid "UnscannedProjects|Untested"
+msgstr ""
+
+msgid "UnscannedProjects|Your projects are up do date! Nice job!"
+msgstr ""
+
+msgid "Unschedule job"
+msgstr ""
+
+msgid "Unstar"
+msgstr ""
+
+msgid "Unsubscribe"
+msgstr ""
+
+msgid "Unsubscribe at group level"
+msgstr ""
+
+msgid "Unsubscribe at project level"
+msgstr ""
+
+msgid "Unsubscribe from %{type}"
+msgstr ""
+
+msgid "Unsubscribed from this %{quick_action_target}."
+msgstr ""
+
+msgid "Unsubscribes from this %{quick_action_target}."
+msgstr ""
+
+msgid "Until"
+msgstr ""
+
+msgid "Until that time, the project can be restored."
+msgstr ""
+
+msgid "Unverified"
+msgstr ""
+
+msgid "Up to date"
+msgstr ""
+
+msgid "Upcoming"
+msgstr ""
+
+msgid "Upcoming Release"
+msgstr ""
+
+msgid "Update"
+msgstr ""
+
+msgid "Update all"
+msgstr ""
+
+msgid "Update approval rule"
+msgstr ""
+
+msgid "Update failed"
+msgstr ""
+
+msgid "Update failed. Please try again."
+msgstr ""
+
+msgid "Update it"
+msgstr ""
+
+msgid "Update now"
+msgstr ""
+
+msgid "Update variable"
+msgstr ""
+
+msgid "Update your bookmarked URLs as filtered/sorted branches URL has been changed."
+msgstr ""
+
+msgid "Update your group name, description, avatar, and visibility."
+msgstr ""
+
+msgid "Update your project name, topics, description and avatar."
+msgstr ""
+
+msgid "UpdateProject|Cannot rename project because it contains container registry tags!"
+msgstr ""
+
+msgid "UpdateProject|Could not set the default branch"
+msgstr ""
+
+msgid "UpdateProject|New visibility level not allowed!"
+msgstr ""
+
+msgid "UpdateProject|Project could not be updated!"
+msgstr ""
+
+msgid "UpdateRepositoryStorage|Error moving repository storage for %{project_full_path} - %{message}"
+msgstr ""
+
+msgid "UpdateRepositoryStorage|Failed to verify %{type} repository checksum from %{old} to %{new}"
+msgstr ""
+
+msgid "UpdateRepositoryStorage|Timeout waiting for %{type} repository pushes"
+msgstr ""
+
+msgid "Updated"
+msgstr ""
+
+msgid "Updated %{updated_at} by %{updated_by}"
+msgstr ""
+
+msgid "Updated at"
+msgstr ""
+
+msgid "Updated to"
+msgstr ""
+
+msgid "Updating"
+msgstr ""
+
+msgid "Upgrade plan to unlock Canary Deployments feature"
+msgstr ""
+
+msgid "Upgrade your plan to activate Advanced Global Search."
+msgstr ""
+
+msgid "Upgrade your plan to activate Audit Events."
+msgstr ""
+
+msgid "Upgrade your plan to activate Group Webhooks."
+msgstr ""
+
+msgid "Upgrade your plan to improve Issue boards."
+msgstr ""
+
+msgid "Upgrade your plan to improve Merge Requests."
+msgstr ""
+
+msgid "Upload <code>GoogleCodeProjectHosting.json</code> here:"
+msgstr ""
+
+msgid "Upload CSV file"
+msgstr ""
+
+msgid "Upload New File"
+msgstr ""
+
+msgid "Upload New License"
+msgstr ""
+
+msgid "Upload a certificate for your domain with all intermediates"
+msgstr ""
+
+msgid "Upload a private key for your certificate"
+msgstr ""
+
+msgid "Upload file"
+msgstr ""
+
+msgid "Upload object map"
+msgstr ""
+
+msgid "UploadLink|click to upload"
+msgstr ""
+
+msgid "Uploaded on"
+msgstr ""
+
+msgid "Uploaded:"
+msgstr ""
+
+msgid "Uploading changes to terminal"
+msgstr ""
+
+msgid "Uploads"
+msgstr ""
+
+msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently removed after %{deletion_adjourned_period} days on <strong>%{date}</strong>. Until that time:"
+msgstr ""
+
+msgid "Upstream"
+msgstr ""
+
+msgid "Uptime"
+msgstr ""
+
+msgid "Upvotes"
+msgstr ""
+
+msgid "Usage"
+msgstr ""
+
+msgid "Usage ping is not enabled"
+msgstr ""
+
+msgid "Usage statistics"
+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|Artifacts"
+msgstr ""
+
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
+msgid "UsageQuota|Buy additional minutes"
+msgstr ""
+
+msgid "UsageQuota|Current period usage"
+msgstr ""
+
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
+msgid "UsageQuota|LFS Storage"
+msgstr ""
+
+msgid "UsageQuota|Packages"
+msgstr ""
+
+msgid "UsageQuota|Pipelines"
+msgstr ""
+
+msgid "UsageQuota|Repositories"
+msgstr ""
+
+msgid "UsageQuota|Repository"
+msgstr ""
+
+msgid "UsageQuota|Storage"
+msgstr ""
+
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
+msgid "UsageQuota|This namespace has no projects which use shared runners"
+msgstr ""
+
+msgid "UsageQuota|Unlimited"
+msgstr ""
+
+msgid "UsageQuota|Usage"
+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 resources across your projects"
+msgstr ""
+
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
+msgid "UsageQuota|Usage since"
+msgstr ""
+
+msgid "UsageQuota|Wiki"
+msgstr ""
+
+msgid "UsageQuota|Wikis"
+msgstr ""
+
+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 <code>%{native_redirect_uri}</code> for local tests"
+msgstr ""
+
+msgid "Use Service Desk to connect with your users (e.g. to offer customer support) through email right inside GitLab"
+msgstr ""
+
+msgid "Use a hardware device to add the second factor of authentication."
+msgstr ""
+
+msgid "Use an one time password authenticator on your mobile device or computer to enable two-factor authentication (2FA)."
+msgstr ""
+
+msgid "Use custom color #FF0000"
+msgstr ""
+
+msgid "Use group milestones to manage issues from multiple projects in the same milestone."
+msgstr ""
+
+msgid "Use hashed storage"
+msgstr ""
+
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
+msgstr ""
+
+msgid "Use one line per URI"
+msgstr ""
+
+msgid "Use template"
+msgstr ""
+
+msgid "Use the following registration token during setup:"
+msgstr ""
+
+msgid "Use your global notification setting"
+msgstr ""
+
+msgid "Use your smart card to authenticate with the LDAP server."
+msgstr ""
+
+msgid "Used by members to sign in to your group in GitLab"
+msgstr ""
+
+msgid "Used programming language"
+msgstr ""
+
+msgid "Used to help configure your identity provider"
+msgstr ""
+
+msgid "User"
+msgstr ""
+
+msgid "User %{current_user_username} has started impersonating %{username}"
+msgstr ""
+
+msgid "User %{username} was successfully removed."
+msgstr ""
+
+msgid "User Cohorts are only shown when the %{usage_ping_link_start}usage ping%{usage_ping_link_end} is enabled."
+msgstr ""
+
+msgid "User IDs"
+msgstr ""
+
+msgid "User OAuth applications"
+msgstr ""
+
+msgid "User Settings"
+msgstr ""
+
+msgid "User and IP Rate Limits"
+msgstr ""
+
+msgid "User identity was successfully created."
+msgstr ""
+
+msgid "User identity was successfully removed."
+msgstr ""
+
+msgid "User identity was successfully updated."
+msgstr ""
+
+msgid "User is not allowed to resolve thread"
+msgstr ""
+
+msgid "User key was successfully removed."
+msgstr ""
+
+msgid "User map"
+msgstr ""
+
+msgid "User pipeline minutes were successfully reset."
+msgstr ""
+
+msgid "User restrictions"
+msgstr ""
+
+msgid "User was successfully created."
+msgstr ""
+
+msgid "User was successfully removed from group and any subresources."
+msgstr ""
+
+msgid "User was successfully removed from project."
+msgstr ""
+
+msgid "User was successfully updated."
+msgstr ""
+
+msgid "UserOnboardingTour|%{activeTour}/%{totalTours}"
+msgstr ""
+
+msgid "UserOnboardingTour|%{completed}/%{total} steps completed"
+msgstr ""
+
+msgid "UserOnboardingTour|%{emphasisStart}Well done!%{emphasisEnd}%{lineBreak}%{lineBreak}That's it for our guided tour, congratulations for making it all the way to the end!%{lineBreak}%{lineBreak}We hope this gave you a good overview of GitLab and how it can help you. We'll now show you how to create your own project and invite your colleagues."
+msgstr ""
+
+msgid "UserOnboardingTour|Adding other members to a project is done through Project Settings. Click on %{emphasisStart}Settings%{emphasisEnd}."
+msgstr ""
+
+msgid "UserOnboardingTour|Alright, that's it for Commits. Let's take a look at the %{emphasisStart}Branches%{emphasisEnd}."
+msgstr ""
+
+msgid "UserOnboardingTour|Awesome! Now click on %{emphasisStart}Members%{emphasisEnd}."
+msgstr ""
+
+msgid "UserOnboardingTour|Click on one of the %{emphasisStart}Compare%{emphasisEnd} buttons to compare a branch to master."
+msgstr ""
+
+msgid "UserOnboardingTour|Click on one of the %{emphasisStart}pipeline IDs%{emphasisEnd} to see the details of a pipeline."
+msgstr ""
+
+msgid "UserOnboardingTour|Click to open the latest commit to see its details."
+msgstr ""
+
+msgid "UserOnboardingTour|Close 'Learn GitLab'"
+msgstr ""
+
+msgid "UserOnboardingTour|Commits are shown in chronological order and can be filtered by the commit message or by the branch."
+msgstr ""
+
+msgid "UserOnboardingTour|Create a project"
+msgstr ""
+
+msgid "UserOnboardingTour|Exit 'Learn GitLab'"
+msgstr ""
+
+msgid "UserOnboardingTour|Got it"
+msgstr ""
+
+msgid "UserOnboardingTour|Great job! %{clapHands} We hope the tour was helpful and that you learned how to use GitLab.%{lineBreak}%{lineBreak}We'd love to get your feedback on this tour.%{lineBreak}%{lineBreak}%{emphasisStart}How helpful would you say this guided tour was?%{emphasisEnd}%{lineBreak}%{lineBreak}"
+msgstr ""
+
+msgid "UserOnboardingTour|Guided GitLab Tour"
+msgstr ""
+
+msgid "UserOnboardingTour|Here you can compare the changes of this branch to another one. Changes are divided by files so that it's easier to see what was changed where."
+msgstr ""
+
+msgid "UserOnboardingTour|Here you can create a project from scratch, start with a template or import a repository from other platforms. Whatever you choose, we'll guide you through the process.%{lineBreak}%{lineBreak}Fill in your new project information and click on %{emphasisStart}Create Project%{emphasisEnd} to progress to the next step."
+msgstr ""
+
+msgid "UserOnboardingTour|Here you can see the breakdown of the pipelines: its stages and jobs in each of the stages and their status.%{lineBreak}%{lineBreak}Our CI/CD pipelines are quite complex, most of our users have fewer and simpler pipelines."
+msgstr ""
+
+msgid "UserOnboardingTour|Here you can see the current members of the project (just you at the moment) and invite new members.%{lineBreak}%{lineBreak}You can invite multiple members at once (existing GitLab users or invite by email) and you can also set their roles and permissions.%{lineBreak}%{lineBreak}Add a few members and click on %{emphasisStart}Add to project%{emphasisEnd} to complete this step."
+msgstr ""
+
+msgid "UserOnboardingTour|Here you can see what changes were made with this commit, on what branch and if there's a related merge request. The status of the pipeline will also show up if CI/CD is set up.%{lineBreak}%{lineBreak}You can also comment on the lines of code that were changed and start a discussion with your colleagues!"
+msgstr ""
+
+msgid "UserOnboardingTour|Here's an overview of branches in the %{emphasisStart}%{projectName}%{emphasisEnd} project. They're split into Active and Stale.%{lineBreak}%{lineBreak}From here, you can create a new merge request from a branch, or compare the branch to any other branch in the project. By default, it will compare it to the master branch."
+msgstr ""
+
+msgid "UserOnboardingTour|Invite colleagues"
+msgstr ""
+
+msgid "UserOnboardingTour|Issues are great for communicating and keeping track of progress in GitLab. These are all issues that are open in the %{emphasisStart}%{projectName}%{emphasisEnd}.%{lineBreak}%{lineBreak}You can help us improve GitLab by contributing work to issues that are labeled <span class=\"badge color-label accept-mr-label\">Accepting merge requests</span>.%{lineBreak}%{lineBreak}This list can be filtered by labels, milestones, assignees, authors... We'll show you how it looks when the list is filtered by a label."
+msgstr ""
+
+msgid "UserOnboardingTour|Learn GitLab"
+msgstr ""
+
+msgid "UserOnboardingTour|Let's take a closer look at a merge request. Click on the title of one."
+msgstr ""
+
+msgid "UserOnboardingTour|Let's take a closer look at all the commits. Click on %{emphasisStart}Commits%{emphasisEnd}."
+msgstr ""
+
+msgid "UserOnboardingTour|Let's take a closer look at the repository of this project. Click on %{emphasisStart}Repository%{emphasisEnd}."
+msgstr ""
+
+msgid "UserOnboardingTour|No thanks"
+msgstr ""
+
+msgid "UserOnboardingTour|Ok, let's go"
+msgstr ""
+
+msgid "UserOnboardingTour|Ok, show me"
+msgstr ""
+
+msgid "UserOnboardingTour|Open one of the issues by clicking on its title."
+msgstr ""
+
+msgid "UserOnboardingTour|Restart this step"
+msgstr ""
+
+msgid "UserOnboardingTour|Skip this step"
+msgstr ""
+
+msgid "UserOnboardingTour|Sweet! Your project was created and is ready to be used.%{lineBreak}%{lineBreak}You can start adding files to the repository or clone it. One last thing we want to show you is how to invite your colleagues to your new project."
+msgstr ""
+
+msgid "UserOnboardingTour|Take a look. Here's a nifty menu for quickly creating issues, merge requests, snippets, projects and groups. Click on it and select \"New project\" from the \"GitLab\" section to get started."
+msgstr ""
+
+msgid "UserOnboardingTour|Thanks for taking the guided tour. Remember, if you want to go through it again, you can start %{emphasisStart}Learn GitLab%{emphasisEnd} in the help menu on the top right."
+msgstr ""
+
+msgid "UserOnboardingTour|Thanks for the feedback! %{thumbsUp}"
+msgstr ""
+
+msgid "UserOnboardingTour|That's it for issues. Let'st take a look at %{emphasisStart}Merge Requests%{emphasisEnd}."
+msgstr ""
+
+msgid "UserOnboardingTour|That's it for merge requests. Now for the final part of this guided tour - the %{emphasisStart}CI/CD%{emphasisEnd}."
+msgstr ""
+
+msgid "UserOnboardingTour|That's it for the Repository. Let's take a look at the %{emphasisStart}Issues%{emphasisEnd}."
+msgstr ""
+
+msgid "UserOnboardingTour|The structure of this page is very similar to issues. Status, description, discussion and the sidebar are all here.%{lineBreak}%{lineBreak}But take a look below the description and you'll notice that there's more information about the merge request, the CI/CD pipeline and the options for approving it.%{lineBreak}%{lineBreak}Alongside the discussion you can also see more information about commits in this merge request, the status of pipelines and review all changes that were made."
+msgstr ""
+
+msgid "UserOnboardingTour|There's a lot of information here but don't worry, we'll go through it.%{lineBreak}%{lineBreak}On the top you can see the status of the issue and when it was opened and by whom. Directly below it is the issue description and below that are other %{emphasisStart}related issues%{emphasisEnd} and %{emphasisStart}merge requests%{emphasisEnd} (if any). Then below that is the %{emphasisStart}discussion%{emphasisEnd}, that's where most of the communication happens.%{lineBreak}%{lineBreak}On the right, there's a sidebar where you can view/change the %{emphasisStart}assignee, milestone, due date, labels, weight%{emphasisEnd}, etc."
+msgstr ""
+
+msgid "UserOnboardingTour|These are all the CI/CD pipelines we have for our %{emphasisStart}%{projectName}%{emphasisEnd} project.%{lineBreak}%{lineBreak}Here you can see the status of each pipeline, for what commit it's running for, its stages and the status for them."
+msgstr ""
+
+msgid "UserOnboardingTour|These are all the issues that are available for community contributions. Let's take a closer look at one of them."
+msgstr ""
+
+msgid "UserOnboardingTour|This is an overview of all merge requests in this project. Similarly to the issues overview it can be filtered down by things like labels, milestones, authors, assignees, etc."
+msgstr ""
+
+msgid "UserOnboardingTour|This is the repository for the %{emphasisStart}%{projectName}%{emphasisEnd} project. All our code is stored here. Feel free to explore and take a closer look at folders and files.%{lineBreak}%{lineBreak}Above the file structure you can see the latest commit, who the author is and the status of the CI/CD pipeline.%{lineBreak}%{lineBreak}If you scroll down below the file structure, you'll find the Readme of this project. This is defined in the README.md file at the root of the repository."
+msgstr ""
+
+msgid "UserOnboardingTour|Welcome to the project overview of the %{emphasisStart}%{projectName}%{emphasisEnd} project. This is the project that we use to work on GitLab. At first, a project seems like a simple repository, but at GitLab, a project is so much more.%{lineBreak}%{lineBreak}You can create projects for hosting your codebase, use it as an issue tracker, collaborate on code, and continuously build, test, and deploy your app with built-in GitLab CI/CD."
+msgstr ""
+
+msgid "UserProfile|Activity"
+msgstr ""
+
+msgid "UserProfile|Already reported for abuse"
+msgstr ""
+
+msgid "UserProfile|Blocked user"
+msgstr ""
+
+msgid "UserProfile|Contributed projects"
+msgstr ""
+
+msgid "UserProfile|Edit profile"
+msgstr ""
+
+msgid "UserProfile|Explore public groups to find projects to contribute to."
+msgstr ""
+
+msgid "UserProfile|Groups"
+msgstr ""
+
+msgid "UserProfile|Groups are the best way to manage projects and members."
+msgstr ""
+
+msgid "UserProfile|Join or create a group to start contributing by commenting on issues or submitting merge requests!"
+msgstr ""
+
+msgid "UserProfile|Most Recent Activity"
+msgstr ""
+
+msgid "UserProfile|No snippets found."
+msgstr ""
+
+msgid "UserProfile|Overview"
+msgstr ""
+
+msgid "UserProfile|Personal projects"
+msgstr ""
+
+msgid "UserProfile|Report abuse"
+msgstr ""
+
+msgid "UserProfile|Snippets"
+msgstr ""
+
+msgid "UserProfile|Snippets in GitLab can either be private, internal, or public."
+msgstr ""
+
+msgid "UserProfile|Star projects to track their progress and show your appreciation."
+msgstr ""
+
+msgid "UserProfile|Starred projects"
+msgstr ""
+
+msgid "UserProfile|Subscribe"
+msgstr ""
+
+msgid "UserProfile|This user doesn't have any personal projects"
+msgstr ""
+
+msgid "UserProfile|This user has a private profile"
+msgstr ""
+
+msgid "UserProfile|This user hasn't contributed to any projects"
+msgstr ""
+
+msgid "UserProfile|This user hasn't starred any projects"
+msgstr ""
+
+msgid "UserProfile|This user is blocked"
+msgstr ""
+
+msgid "UserProfile|View all"
+msgstr ""
+
+msgid "UserProfile|View user in admin area"
+msgstr ""
+
+msgid "UserProfile|You can create a group for several dependent projects."
+msgstr ""
+
+msgid "UserProfile|You haven't created any personal projects."
+msgstr ""
+
+msgid "UserProfile|You haven't created any snippets."
+msgstr ""
+
+msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
+msgstr ""
+
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
+msgid "Username (optional)"
+msgstr ""
+
+msgid "Username is already taken."
+msgstr ""
+
+msgid "Username is available."
+msgstr ""
+
+msgid "Username is too long (maximum is %{max_length} characters)."
+msgstr ""
+
+msgid "Username or email"
+msgstr ""
+
+msgid "Users"
+msgstr ""
+
+msgid "Users in License:"
+msgstr ""
+
+msgid "Users or groups set as approvers in the project's or merge request's settings."
+msgstr ""
+
+msgid "Users outside of license"
+msgstr ""
+
+msgid "Users over License:"
+msgstr ""
+
+msgid "Users requesting access to"
+msgstr ""
+
+msgid "Users were successfully added."
+msgstr ""
+
+msgid "Users with a Guest role or those who don't belong to any projects or groups don't count towards seats in use."
+msgstr ""
+
+msgid "UsersSelect|%{name} + %{length} more"
+msgstr ""
+
+msgid "UsersSelect|Any User"
+msgstr ""
+
+msgid "UsersSelect|Assignee"
+msgstr ""
+
+msgid "UsersSelect|No assignee - %{openingTag} assign yourself %{closingTag}"
+msgstr ""
+
+msgid "UsersSelect|Unassigned"
+msgstr ""
+
+msgid "Using %{code_start}::%{code_end} denotes a %{link_start}scoped label set%{link_end}"
+msgstr ""
+
+msgid "Using required encryption strategy when encrypted field is missing!"
+msgstr ""
+
+msgid "Valid from"
+msgstr ""
+
+msgid "Validate"
+msgstr ""
+
+msgid "Validate your GitLab CI configuration file"
+msgstr ""
+
+msgid "Validations failed."
+msgstr ""
+
+msgid "Validity"
+msgstr ""
+
+msgid "Value"
+msgstr ""
+
+msgid "Value Stream"
+msgstr ""
+
+msgid "Value Stream Analytics"
+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 "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
+msgstr ""
+
+msgid "Variable will be masked in job logs."
+msgstr ""
+
+msgid "Variables"
+msgstr ""
+
+msgid "Various container registry settings."
+msgstr ""
+
+msgid "Various email settings."
+msgstr ""
+
+msgid "Various localization settings."
+msgstr ""
+
+msgid "Various settings that affect GitLab performance."
+msgstr ""
+
+msgid "Verification capacity"
+msgstr ""
+
+msgid "Verification information"
+msgstr ""
+
+msgid "Verification status"
+msgstr ""
+
+msgid "Verified"
+msgstr ""
+
+msgid "Verify SAML Configuration"
+msgstr ""
+
+msgid "Verify configuration"
+msgstr ""
+
+msgid "Version"
+msgstr ""
+
+msgid "Versions"
+msgstr ""
+
+msgid "Very helpful"
+msgstr ""
+
+msgid "View Documentation"
+msgstr ""
+
+msgid "View all issues"
+msgstr ""
+
+msgid "View blame prior to this change"
+msgstr ""
+
+msgid "View chart"
+msgid_plural "View charts"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "View dependency details for your project"
+msgstr ""
+
+msgid "View deployment"
+msgstr ""
+
+msgid "View details"
+msgstr ""
+
+msgid "View details: %{details_url}"
+msgstr ""
+
+msgid "View documentation"
+msgstr ""
+
+msgid "View eligible approvers"
+msgstr ""
+
+msgid "View epics list"
+msgstr ""
+
+msgid "View exposed artifact"
+msgid_plural "View %d exposed artifacts"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "View file @ "
+msgstr ""
+
+msgid "View file @ %{commitSha}"
+msgstr ""
+
+msgid "View full dashboard"
+msgstr ""
+
+msgid "View full log"
+msgstr ""
+
+msgid "View group labels"
+msgstr ""
+
+msgid "View incident issues."
+msgstr ""
+
+msgid "View issue"
+msgstr ""
+
+msgid "View issues"
+msgstr ""
+
+msgid "View it on GitLab"
+msgstr ""
+
+msgid "View job"
+msgstr ""
+
+msgid "View job log"
+msgstr ""
+
+msgid "View jobs"
+msgstr ""
+
+msgid "View labels"
+msgstr ""
+
+msgid "View log"
+msgstr ""
+
+msgid "View open merge request"
+msgstr ""
+
+msgid "View performance dashboard."
+msgstr ""
+
+msgid "View project"
+msgstr ""
+
+msgid "View project labels"
+msgstr ""
+
+msgid "View replaced file @ "
+msgstr ""
+
+msgid "View supported languages and frameworks"
+msgstr ""
+
+msgid "View the documentation"
+msgstr ""
+
+msgid "View the latest successful deployment to this environment"
+msgstr ""
+
+msgid "View the performance dashboard at"
+msgstr ""
+
+msgid "View users statistics"
+msgstr ""
+
+msgid "Viewing commit"
+msgstr ""
+
+msgid "Visibility"
+msgstr ""
+
+msgid "Visibility and access controls"
+msgstr ""
+
+msgid "Visibility level"
+msgstr ""
+
+msgid "Visibility level:"
+msgstr ""
+
+msgid "Visibility settings have been disabled by the administrator."
+msgstr ""
+
+msgid "Visibility, project features, permissions"
+msgstr ""
+
+msgid "Visibility:"
+msgstr ""
+
+msgid "VisibilityLevel|Internal"
+msgstr ""
+
+msgid "VisibilityLevel|Private"
+msgstr ""
+
+msgid "VisibilityLevel|Public"
+msgstr ""
+
+msgid "VisibilityLevel|Unknown"
+msgstr ""
+
+msgid "VisualReviewApp|%{stepStart}Step 1%{stepEnd}. Copy the following script:"
+msgstr ""
+
+msgid "VisualReviewApp|%{stepStart}Step 2%{stepEnd}. Add it to the %{headTags} tags of every page of your application, ensuring the merge request ID is set or not set as required. "
+msgstr ""
+
+msgid "VisualReviewApp|%{stepStart}Step 3%{stepEnd}. If not previously %{linkStart}configured%{linkEnd} by a developer, enter the merge request ID for the review when prompted. The ID of this merge request is %{stepStart}%{mrId}%{stepStart}."
+msgstr ""
+
+msgid "VisualReviewApp|%{stepStart}Step 4%{stepEnd}. Leave feedback in the Review App."
+msgstr ""
+
+msgid "VisualReviewApp|Cancel"
+msgstr ""
+
+msgid "VisualReviewApp|Copy merge request ID"
+msgstr ""
+
+msgid "VisualReviewApp|Copy script"
+msgstr ""
+
+msgid "VisualReviewApp|Enable Visual Reviews"
+msgstr ""
+
+msgid "VisualReviewApp|Follow the steps below to enable Visual Reviews inside your application."
+msgstr ""
+
+msgid "VisualReviewApp|No review app found or available."
+msgstr ""
+
+msgid "VisualReviewApp|Open review app"
+msgstr ""
+
+msgid "VisualReviewApp|Review"
+msgstr ""
+
+msgid "VisualReviewApp|Steps 1 and 2 (and sometimes 3) are performed once by the developer before requesting feedback. Steps 3 (if necessary), 4 is performed by the reviewer each time they perform a review."
+msgstr ""
+
+msgid "Vulnerabilities"
+msgstr ""
+
+msgid "Vulnerabilities over time"
+msgstr ""
+
+msgid "Vulnerability remediated. Review before resolving."
+msgstr ""
+
+msgid "Vulnerability resolved in %{branch}"
+msgstr ""
+
+msgid "Vulnerability resolved in the default branch"
+msgstr ""
+
+msgid "Vulnerability-Check"
+msgstr ""
+
+msgid "VulnerabilityChart|%{formattedStartDate} to today"
+msgstr ""
+
+msgid "VulnerabilityChart|Severity"
+msgstr ""
+
+msgid "VulnerabilityManagement|A true-positive and will fix"
+msgstr ""
+
+msgid "VulnerabilityManagement|Change status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Confirm"
+msgstr ""
+
+msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
+msgstr ""
+
+msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
+msgstr ""
+
+msgid "VulnerabilityManagement|Dismiss"
+msgstr ""
+
+msgid "VulnerabilityManagement|Dismissed %{timeago} by %{user}"
+msgstr ""
+
+msgid "VulnerabilityManagement|Resolved"
+msgstr ""
+
+msgid "VulnerabilityManagement|Resolved %{timeago} by %{user}"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while trying to retrieve the vulnerability history. Please try again later."
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while trying to save the comment. Please try again later."
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong, could not create an issue."
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong, could not get user."
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
+msgstr ""
+
+msgid "VulnerabilityManagement|Verified as fixed or mitigated"
+msgstr ""
+
+msgid "VulnerabilityManagement|Will not fix or a false-positive"
+msgstr ""
+
+msgid "VulnerabilityStatusTypes|All"
+msgstr ""
+
+msgid "VulnerabilityStatusTypes|Confirmed"
+msgstr ""
+
+msgid "VulnerabilityStatusTypes|Detected"
+msgstr ""
+
+msgid "VulnerabilityStatusTypes|Dismissed"
+msgstr ""
+
+msgid "VulnerabilityStatusTypes|Resolved"
+msgstr ""
+
+msgid "Vulnerability|%{scannerName} (version %{scannerVersion})"
+msgstr ""
+
+msgid "Vulnerability|Class"
+msgstr ""
+
+msgid "Vulnerability|Description"
+msgstr ""
+
+msgid "Vulnerability|Evidence"
+msgstr ""
+
+msgid "Vulnerability|File"
+msgstr ""
+
+msgid "Vulnerability|Identifiers"
+msgstr ""
+
+msgid "Vulnerability|Image"
+msgstr ""
+
+msgid "Vulnerability|Instances"
+msgstr ""
+
+msgid "Vulnerability|Links"
+msgstr ""
+
+msgid "Vulnerability|Method"
+msgstr ""
+
+msgid "Vulnerability|Namespace"
+msgstr ""
+
+msgid "Vulnerability|Project"
+msgstr ""
+
+msgid "Vulnerability|Scanner Provider"
+msgstr ""
+
+msgid "Vulnerability|Scanner Type"
+msgstr ""
+
+msgid "Vulnerability|Severity"
+msgstr ""
+
+msgid "Vulnerability|Status"
+msgstr ""
+
+msgid "WIP"
+msgstr ""
+
+msgid "Wait for the file to load to copy its contents"
+msgstr ""
+
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
+msgid "Waiting for performance data"
+msgstr ""
+
+msgid "Want to see the data? Please ask an administrator for access."
+msgstr ""
+
+msgid "Warning:"
+msgstr ""
+
+msgid "Warning: Displaying this diagram might cause performance issues on this page."
+msgstr ""
+
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
+msgid "We could not determine the path to remove the epic"
+msgstr ""
+
+msgid "We could not determine the path to remove the issue"
+msgstr ""
+
+msgid "We couldn't reach the Prometheus server. Either the server no longer exists or the configuration details need updating."
+msgstr ""
+
+msgid "We created a short guided tour that will help you learn the basics of GitLab and how it will help you be better at your job. It should only take a couple of minutes. You will be guided by two types of helpers, best recognized by their color."
+msgstr ""
+
+msgid "We detected potential spam in the %{humanized_resource_name}. Please solve the reCAPTCHA to proceed."
+msgstr ""
+
+msgid "We don't have enough data to show this stage."
+msgstr ""
+
+msgid "We have found the following errors:"
+msgstr ""
+
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
+msgstr ""
+
+msgid "We sent you an email with reset password instructions"
+msgstr ""
+
+msgid "We tried to automatically renew your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} on %{expires_on} but something went wrong so your subscription was downgraded to the free plan. Don't worry, your data is safe. We suggest you check your payment method and get in touch with our support team (%{support_link}). They'll gladly help with your subscription renewal."
+msgstr ""
+
+msgid "We want to be sure it is you, please confirm you are not a robot."
+msgstr ""
+
+msgid "We will automatically renew your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} on %{strong}%{expires_on}%{strong_close}. There's nothing that you need to do, we'll let you know when the renewal is complete. Need more seats, a higher plan or just want to review your payment method?"
+msgstr ""
+
+msgid "We've found no vulnerabilities"
+msgstr ""
+
+msgid "Web IDE"
+msgstr ""
+
+msgid "Web Terminal"
+msgstr ""
+
+msgid "Web terminal"
+msgstr ""
+
+msgid "WebIDE|Merge request"
+msgstr ""
+
+msgid "Webhook"
+msgstr ""
+
+msgid "Webhook Logs"
+msgstr ""
+
+msgid "Webhook Settings"
+msgstr ""
+
+msgid "Webhooks"
+msgstr ""
+
+msgid "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 "Webhooks have moved. They can now be found under the Settings menu."
+msgstr ""
+
+msgid "Wednesday"
+msgstr ""
+
+msgid "Weekday"
+msgstr ""
+
+msgid "Weeks"
+msgstr ""
+
+msgid "Weight"
+msgstr ""
+
+msgid "Weight %{weight}"
+msgstr ""
+
+msgid "Welcome back! Your account had been deactivated due to inactivity but is now reactivated."
+msgstr ""
+
+msgid "Welcome to GitLab"
+msgstr ""
+
+msgid "Welcome to GitLab %{name}!"
+msgstr ""
+
+msgid "Welcome to GitLab, %{first_name}!"
+msgstr ""
+
+msgid "Welcome to GitLab.com<br>@%{name}!"
+msgstr ""
+
+msgid "Welcome to the Guided GitLab Tour"
+msgstr ""
+
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
+msgid "Welcome to your Issue Board!"
+msgstr ""
+
+msgid "What are you searching for?"
+msgstr ""
+
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
+msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
+msgstr ""
+
+msgid "When a runner is locked, it cannot be assigned to other projects"
+msgstr ""
+
+msgid "When enabled, any user visiting %{host} will be able to create an account."
+msgstr ""
+
+msgid "When enabled, if an NPM package isn't found in the GitLab Registry, we will attempt to pull from the global NPM registry."
+msgstr ""
+
+msgid "When enabled, users cannot use GitLab until the terms have been accepted."
+msgstr ""
+
+msgid "When leaving the URL blank, classification labels can still be specified without disabling cross project features or performing external authorization checks."
+msgstr ""
+
+msgid "When this merge request is accepted"
+msgid_plural "When these merge requests are accepted"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "When using the <code>http://</code> or <code>https://</code> protocols, please provide the exact URL to the repository. HTTP redirects will not be followed."
+msgstr ""
+
+msgid "When:"
+msgstr ""
+
+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 "White helpers give contextual information."
+msgstr ""
+
+msgid "Who can be an approver?"
+msgstr ""
+
+msgid "Who can see this group?"
+msgstr ""
+
+msgid "Who will be able to see this group?"
+msgstr ""
+
+msgid "Who will be using GitLab?"
+msgstr ""
+
+msgid "Who will be using this GitLab subscription?"
+msgstr ""
+
+msgid "Who will be using this GitLab trial?"
+msgstr ""
+
+msgid "Wiki"
+msgstr ""
+
+msgid "Wiki was successfully updated."
+msgstr ""
+
+msgid "WikiClone|Clone your wiki"
+msgstr ""
+
+msgid "WikiClone|Git Access"
+msgstr ""
+
+msgid "WikiClone|Install Gollum"
+msgstr ""
+
+msgid "WikiClone|Start Gollum and edit locally"
+msgstr ""
+
+msgid "WikiEditPageTip|Tip: You can move this page by adding the path to the beginning of the title."
+msgstr ""
+
+msgid "WikiEdit|There is already a page with the same title in that path."
+msgstr ""
+
+msgid "WikiEmptyIssueMessage|Suggest wiki improvement"
+msgstr ""
+
+msgid "WikiEmptyIssueMessage|You must be a project member in order to add wiki pages. If you have suggestions for how to improve the wiki for this project, consider opening an issue in the %{issues_link}."
+msgstr ""
+
+msgid "WikiEmptyIssueMessage|issue tracker"
+msgstr ""
+
+msgid "WikiEmpty|A wiki is where you can store all the details about your project. This can include why you've created it, its principles, how to use it, and so on."
+msgstr ""
+
+msgid "WikiEmpty|Create your first page"
+msgstr ""
+
+msgid "WikiEmpty|Suggest wiki improvement"
+msgstr ""
+
+msgid "WikiEmpty|The wiki lets you write documentation for your project"
+msgstr ""
+
+msgid "WikiEmpty|This project has no wiki pages"
+msgstr ""
+
+msgid "WikiEmpty|You must be a project member in order to add wiki pages."
+msgstr ""
+
+msgid "WikiHistoricalPage|This is an old version of this page."
+msgstr ""
+
+msgid "WikiHistoricalPage|You can view the %{most_recent_link} or browse the %{history_link}."
+msgstr ""
+
+msgid "WikiHistoricalPage|history"
+msgstr ""
+
+msgid "WikiHistoricalPage|most recent version"
+msgstr ""
+
+msgid "WikiMarkdownDocs|More examples are in the %{docs_link}"
+msgstr ""
+
+msgid "WikiMarkdownDocs|documentation"
+msgstr ""
+
+msgid "WikiMarkdownTip|To link to a (new) page, simply type <code class=\"js-markup-link-example\">%{link_example}</code>"
+msgstr ""
+
+msgid "WikiNewPageTip|Tip: You can specify the full path for the new file. We will automatically create any missing directories."
+msgstr ""
+
+msgid "WikiPageConfirmDelete|Are you sure you want to delete this page?"
+msgstr ""
+
+msgid "WikiPageConfirmDelete|Delete page"
+msgstr ""
+
+msgid "WikiPageConfirmDelete|Delete page %{pageTitle}?"
+msgstr ""
+
+msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{page_link} and make sure your changes will not unintentionally remove theirs."
+msgstr ""
+
+msgid "WikiPageConflictMessage|the page"
+msgstr ""
+
+msgid "WikiPageCreate|Create %{pageTitle}"
+msgstr ""
+
+msgid "WikiPageEdit|Update %{pageTitle}"
+msgstr ""
+
+msgid "WikiPage|Write your content or drag files here…"
+msgstr ""
+
+msgid "Wiki|Create New Page"
+msgstr ""
+
+msgid "Wiki|Create page"
+msgstr ""
+
+msgid "Wiki|Created date"
+msgstr ""
+
+msgid "Wiki|Edit Page"
+msgstr ""
+
+msgid "Wiki|New page"
+msgstr ""
+
+msgid "Wiki|Page history"
+msgstr ""
+
+msgid "Wiki|Page title"
+msgstr ""
+
+msgid "Wiki|Page version"
+msgstr ""
+
+msgid "Wiki|Pages"
+msgstr ""
+
+msgid "Wiki|Title"
+msgstr ""
+
+msgid "Wiki|View All Pages"
+msgstr ""
+
+msgid "Wiki|Wiki Pages"
+msgstr ""
+
+msgid "Will be created"
+msgstr ""
+
+msgid "Will deploy to"
+msgstr ""
+
+msgid "With requirements, you can set criteria to check your products against."
+msgstr ""
+
+msgid "Withdraw Access Request"
+msgstr ""
+
+msgid "Won't fix / Accept risk"
+msgstr ""
+
+msgid "Work in progress (open and unassigned)"
+msgstr ""
+
+msgid "Work in progress Limit"
+msgstr ""
+
+msgid "Write"
+msgstr ""
+
+msgid "Write a comment or drag your files here…"
+msgstr ""
+
+msgid "Write a comment…"
+msgstr ""
+
+msgid "Write access allowed"
+msgstr ""
+
+msgid "Write milestone description..."
+msgstr ""
+
+msgid "Write your release notes or drag your files here…"
+msgstr ""
+
+msgid "Wrong extern UID provided. Make sure Auth0 is configured correctly."
+msgstr ""
+
+msgid "Yes"
+msgstr ""
+
+msgid "Yes or No"
+msgstr ""
+
+msgid "Yes, add it"
+msgstr ""
+
+msgid "Yes, close issue"
+msgstr ""
+
+msgid "Yes, let me map Google Code users to full names or GitLab users."
+msgstr ""
+
+msgid "Yesterday"
+msgstr ""
+
+msgid "You"
+msgstr ""
+
+msgid "You are about to delete %{domain} from your instance. This domain will no longer be available to any Knative application."
+msgstr ""
+
+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 ""
+
+msgid "You are an admin, which means granting access to <strong>%{client_name}</strong> will allow them to interact with GitLab as an admin as well. Proceed with caution."
+msgstr ""
+
+msgid "You are attempting to delete a file that has been previously updated."
+msgstr ""
+
+msgid "You are attempting to update a file that has changed since you started editing it."
+msgstr ""
+
+msgid "You are connected to the Prometheus server, but there is currently no data to display."
+msgstr ""
+
+msgid "You are going to remove %{group_name}, this will also remove all of its subgroups and projects. Removed groups CANNOT be restored! Are you ABSOLUTELY sure?"
+msgstr ""
+
+msgid "You are going to remove %{project_full_name}. Removed project CANNOT be restored! Are you ABSOLUTELY sure?"
+msgstr ""
+
+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 owner. Are you ABSOLUTELY sure?"
+msgstr ""
+
+msgid "You are not allowed to push into this branch. Create another branch or open a merge request."
+msgstr ""
+
+msgid "You are not allowed to unlink your primary login account"
+msgstr ""
+
+msgid "You are not authorized to perform this action"
+msgstr ""
+
+msgid "You are now impersonating %{username}"
+msgstr ""
+
+msgid "You are on a read-only GitLab instance."
+msgstr ""
+
+msgid "You are receiving this message because you are a GitLab administrator for %{url}."
+msgstr ""
+
+msgid "You are trying to upload something other than an image. Please upload a .png, .jpg, .jpeg, .gif, .bmp, .tiff or .ico."
+msgstr ""
+
+msgid "You can %{linkStart}view the blob%{linkEnd} instead."
+msgstr ""
+
+msgid "You can also create a project from the command line."
+msgstr ""
+
+msgid "You can also press &#8984;-Enter"
+msgstr ""
+
+msgid "You can also press Ctrl-Enter"
+msgstr ""
+
+msgid "You can also star a label to make it a priority label."
+msgstr ""
+
+msgid "You can also test your %{gitlab_ci_yml} in %{lint_link_start}CI Lint%{lint_link_end}"
+msgstr ""
+
+msgid "You can also upload existing files from your computer using the instructions below."
+msgstr ""
+
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
+msgid "You can always edit this later"
+msgstr ""
+
+msgid "You can apply your Trial to your Personal account or create a New Group."
+msgstr ""
+
+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 Personal Access Tokens settings %{pat_link}"
+msgstr ""
+
+msgid "You can create new ones at your %{pat_link_start}Personal Access Tokens%{pat_link_end} settings"
+msgstr ""
+
+msgid "You can create new ones at your Personal Access Tokens settings %{pat_link}"
+msgstr ""
+
+msgid "You can easily contribute to them by requesting to join these groups."
+msgstr ""
+
+msgid "You can easily install a Runner on a Kubernetes cluster. %{link_to_help_page}"
+msgstr ""
+
+msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
+msgstr ""
+
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
+msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
+msgstr ""
+
+msgid "You can invite a new member to <strong>%{project_name}</strong> or invite another group."
+msgstr ""
+
+msgid "You can invite a new member to <strong>%{project_name}</strong>."
+msgstr ""
+
+msgid "You can invite another group to <strong>%{project_name}</strong>."
+msgstr ""
+
+msgid "You can move around the graph by using the arrow keys."
+msgstr ""
+
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
+msgid "You can now export your security dashboard to a CSV report."
+msgstr ""
+
+msgid "You can now submit a merge request to get this change into the original branch."
+msgstr ""
+
+msgid "You can now submit a merge request to get this change into the original project."
+msgstr ""
+
+msgid "You can only add files when you are on a branch"
+msgstr ""
+
+msgid "You can only edit files when you are on a branch"
+msgstr ""
+
+msgid "You can only merge once the items above are resolved."
+msgstr ""
+
+msgid "You can only merge once this merge request is approved."
+msgstr ""
+
+msgid "You can only transfer the project to namespaces you manage."
+msgstr ""
+
+msgid "You can only upload one design when dropping onto an existing design."
+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 ""
+
+msgid "You can see your chat accounts."
+msgstr ""
+
+msgid "You can set up as many Runners as you need to run your jobs."
+msgstr ""
+
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
+msgstr ""
+
+msgid "You can specify notification level per group or per project."
+msgstr ""
+
+msgid "You can test your .gitlab-ci.yml in %{linkStart}CI Lint%{linkEnd}."
+msgstr ""
+
+msgid "You can try again using %{begin_link}basic search%{end_link}"
+msgstr ""
+
+msgid "You cannot access the raw file. Please wait a minute."
+msgstr ""
+
+msgid "You cannot impersonate a blocked user"
+msgstr ""
+
+msgid "You cannot impersonate a user who cannot log in"
+msgstr ""
+
+msgid "You cannot impersonate an internal user"
+msgstr ""
+
+msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
+msgstr ""
+
+msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
+msgstr ""
+
+msgid "You cannot write to this read-only GitLab instance."
+msgstr ""
+
+msgid "You could not create a new trigger."
+msgstr ""
+
+msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} so it was downgraded to the free plan."
+msgstr ""
+
+msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
+msgstr ""
+
+msgid "You do not have an active license"
+msgstr ""
+
+msgid "You do not have any subscriptions yet"
+msgstr ""
+
+msgid "You do not have permission to leave this %{namespaceType}."
+msgstr ""
+
+msgid "You do not have permission to run the Web Terminal. Please contact a project administrator."
+msgstr ""
+
+msgid "You do not have permissions to run the import."
+msgstr ""
+
+msgid "You do not have the correct permissions to override the settings from the LDAP group sync."
+msgstr ""
+
+msgid "You don't have any U2F devices registered yet."
+msgstr ""
+
+msgid "You don't have any active chat names."
+msgstr ""
+
+msgid "You don't have any applications"
+msgstr ""
+
+msgid "You don't have any authorized applications"
+msgstr ""
+
+msgid "You don't have any deployments right now."
+msgstr ""
+
+msgid "You don't have any open merge requests"
+msgstr ""
+
+msgid "You don't have any projects available."
+msgstr ""
+
+msgid "You don't have any recent searches"
+msgstr ""
+
+msgid "You don't have sufficient permission to perform this action."
+msgstr ""
+
+msgid "You don’t have access to Productivity Analytics in this group"
+msgstr ""
+
+msgid "You don’t have access to Value Stream Analytics for this group"
+msgstr ""
+
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
+msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
+msgstr ""
+
+msgid "You have been granted %{access_level} access to the %{source_name} %{source_type}."
+msgstr ""
+
+msgid "You have been granted %{member_human_access} access to %{label}."
+msgstr ""
+
+msgid "You have been unsubscribed from this thread."
+msgstr ""
+
+msgid "You have declined the invitation to join %{label}."
+msgstr ""
+
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
+msgstr ""
+
+msgid "You have no permissions"
+msgstr ""
+
+msgid "You have not added any approvers. Start by adding users or groups."
+msgstr ""
+
+msgid "You have reached your project limit"
+msgstr ""
+
+msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
+msgstr ""
+
+msgid "You haven't added any issues to your project yet"
+msgstr ""
+
+msgid "You haven't selected any issues yet"
+msgstr ""
+
+msgid "You left the \"%{membershipable_human_name}\" %{source_type}."
+msgstr ""
+
+msgid "You may also add variables that are made available to the running application by prepending the variable key with <code>K8S_SECRET_</code>."
+msgstr ""
+
+msgid "You may close the milestone now."
+msgstr ""
+
+msgid "You must accept our Terms of Service and privacy policy in order to register an account"
+msgstr ""
+
+msgid "You must disassociate %{domain} from all clusters it is attached to before deletion."
+msgstr ""
+
+msgid "You must have maintainer access to force delete a lock"
+msgstr ""
+
+msgid "You must have permission to create a project in a namespace before forking."
+msgstr ""
+
+msgid "You must provide a valid current password"
+msgstr ""
+
+msgid "You must provide your current password in order to change it."
+msgstr ""
+
+msgid "You must select a stack for configuring your cloud provider. Learn more about"
+msgstr ""
+
+msgid "You must set up incoming email before it becomes active."
+msgstr ""
+
+msgid "You must upload a file with the same file name when dropping onto an existing design."
+msgstr ""
+
+msgid "You need a different license to enable FileLocks feature"
+msgstr ""
+
+msgid "You need git-lfs version %{min_git_lfs_version} (or greater) to continue. Please visit https://git-lfs.github.com"
+msgstr ""
+
+msgid "You need permission."
+msgstr ""
+
+msgid "You need to be logged in."
+msgstr ""
+
+msgid "You need to register a two-factor authentication app before you can set up a U2F device."
+msgstr ""
+
+msgid "You need to set terms to be enforced"
+msgstr ""
+
+msgid "You need to specify both an Access Token and a Host URL."
+msgstr ""
+
+msgid "You need to upload a GitLab project export archive (ending in .gz)."
+msgstr ""
+
+msgid "You need to upload a Google Takeout archive."
+msgstr ""
+
+msgid "You reached %{usage_in_percent} of %{namespace_name}'s capacity (%{used_storage} of %{storage_limit})"
+msgstr ""
+
+msgid "You tried to fork %{link_to_the_project} but it failed for the following reason:"
+msgstr ""
+
+msgid "You will be removed from existing projects/groups"
+msgstr ""
+
+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 ""
+
+msgid "You will first need to set up Jira Integration to use this feature."
+msgstr ""
+
+msgid "You will lose all changes you've made to this file. This action cannot be undone."
+msgstr ""
+
+msgid "You will lose all uncommitted changes you've made in this project. This action cannot be undone."
+msgstr ""
+
+msgid "You will need to update your local repositories to point to the new location."
+msgstr ""
+
+msgid "You will not get any notifications via email"
+msgstr ""
+
+msgid "You will only receive notifications for the events you choose"
+msgstr ""
+
+msgid "You will only receive notifications for threads you have participated in"
+msgstr ""
+
+msgid "You will receive notifications for any activity"
+msgstr ""
+
+msgid "You will receive notifications only for comments in which you were @mentioned"
+msgstr ""
+
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
+msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
+msgstr ""
+
+msgid "You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
+msgstr ""
+
+msgid "You'll be signed out from your current account automatically."
+msgstr ""
+
+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 ""
+
+msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
+msgstr ""
+
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
+
+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 ""
+
+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 ""
+
+msgid "You're only seeing %{startTag}other activity%{endTag} in the feed. To add a comment, switch to one of the following options."
+msgstr ""
+
+msgid "You're receiving this email because of your account on %{host}."
+msgstr ""
+
+msgid "You're receiving this email because of your account on %{host}. %{manage_notifications_link} &middot; %{help_link}"
+msgstr ""
+
+msgid "You're receiving this email because of your activity on %{host}."
+msgstr ""
+
+msgid "You're receiving this email because you have been assigned an item on %{host}."
+msgstr ""
+
+msgid "You're receiving this email because you have been mentioned on %{host}."
+msgstr ""
+
+msgid "You've already enabled two-factor authentication using one time password authenticators. In order to register a different device, you must first disable two-factor authentication."
+msgstr ""
+
+msgid "YouTube"
+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}."
+msgstr ""
+
+msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+msgstr ""
+
+msgid "Your CSV export has started. It will be emailed to %{email} when complete."
+msgstr ""
+
+msgid "Your CSV export of %{issues_count} from project %{project_link} has been added to this email as an attachment."
+msgstr ""
+
+msgid "Your CSV export of %{written_count} from project %{project_name} (%{project_url}) has been added to this email as an attachment."
+msgstr ""
+
+msgid "Your Commit Email will be used for web based operations, such as edits and merges."
+msgstr ""
+
+msgid "Your Default Notification Email will be used for account notifications if a %{openingTag}group-specific email address%{closingTag} is not set."
+msgstr ""
+
+msgid "Your DevOps Score gives an overview of how you are using GitLab from a feature perspective. View how you compare with other organizations, discover features you are not using, and learn best practices through blog posts and white papers."
+msgstr ""
+
+msgid "Your GPG keys (%{count})"
+msgstr ""
+
+msgid "Your GitLab group"
+msgstr ""
+
+msgid "Your Gitlab Gold trial will last 30 days after which point you can keep your free Gitlab account forever. We just need some additional information to activate your trial."
+msgstr ""
+
+msgid "Your Groups"
+msgstr ""
+
+msgid "Your License"
+msgstr ""
+
+msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
+msgstr ""
+
+msgid "Your Primary Email will be used for avatar detection."
+msgstr ""
+
+msgid "Your Projects (default)"
+msgstr ""
+
+msgid "Your Projects' Activity"
+msgstr ""
+
+msgid "Your Public Email will be displayed on your public profile."
+msgstr ""
+
+msgid "Your SSH keys (%{count})"
+msgstr ""
+
+msgid "Your To-Do List"
+msgstr ""
+
+msgid "Your U2F device did not send a valid JSON response."
+msgstr ""
+
+msgid "Your U2F device needs to be set up. Plug it in (if not already) and click the button on the left."
+msgstr ""
+
+msgid "Your U2F device was registered!"
+msgstr ""
+
+msgid "Your access request to the %{source_type} has been withdrawn."
+msgstr ""
+
+msgid "Your account has been deactivated by your administrator. Please log back in to reactivate your account."
+msgstr ""
+
+msgid "Your account is locked."
+msgstr ""
+
+msgid "Your account uses dedicated credentials for the \"%{group_name}\" group and can only be updated through SSO."
+msgstr ""
+
+msgid "Your applications (%{size})"
+msgstr ""
+
+msgid "Your authorized applications"
+msgstr ""
+
+msgid "Your browser doesn't support U2F. Please use Google Chrome desktop (version 41 or newer)."
+msgstr ""
+
+msgid "Your changes can be committed to %{branch_name} because a merge request is open."
+msgstr ""
+
+msgid "Your changes have been committed. Commit %{commitId} %{commitStats}"
+msgstr ""
+
+msgid "Your changes have been saved"
+msgstr ""
+
+msgid "Your changes have been successfully committed."
+msgstr ""
+
+msgid "Your comment could not be submitted because %{error}"
+msgstr ""
+
+msgid "Your comment could not be submitted! Please check your network connection and try again."
+msgstr ""
+
+msgid "Your comment could not be updated! Please check your network connection and try again."
+msgstr ""
+
+msgid "Your comment will be discarded."
+msgstr ""
+
+msgid "Your custom stage '%{title}' was created"
+msgstr ""
+
+msgid "Your dashboard has been copied. You can %{web_ide_link_start}edit it here%{web_ide_link_end}."
+msgstr ""
+
+msgid "Your dashboard has been updated. You can %{web_ide_link_start}edit it here%{web_ide_link_end}."
+msgstr ""
+
+msgid "Your deployment services will be broken, you will need to manually fix the services after renaming."
+msgstr ""
+
+msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
+msgstr ""
+
+msgid "Your first project"
+msgstr ""
+
+msgid "Your groups"
+msgstr ""
+
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
+msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
+msgstr ""
+
+msgid "Your issues will be imported in the background. Once finished, you'll get a confirmation email."
+msgstr ""
+
+msgid "Your license is valid from"
+msgstr ""
+
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
+msgid "Your message here"
+msgstr ""
+
+msgid "Your name"
+msgstr ""
+
+msgid "Your new %{type}"
+msgstr ""
+
+msgid "Your new SCIM token"
+msgstr ""
+
+msgid "Your new personal access token has been created."
+msgstr ""
+
+msgid "Your new project access token has been created."
+msgstr ""
+
+msgid "Your password isn't required to view this page. If a password or any other personal details are requested, please contact your administrator to report abuse."
+msgstr ""
+
+msgid "Your password reset token has expired."
+msgstr ""
+
+msgid "Your profile"
+msgstr ""
+
+msgid "Your project limit is %{limit} projects! Please contact your administrator to increase it"
+msgstr ""
+
+msgid "Your projects"
+msgstr ""
+
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
+msgid "Your request for access has been queued for review."
+msgstr ""
+
+msgid "Your response has been recorded."
+msgstr ""
+
+msgid "Your search didn't match any commits."
+msgstr ""
+
+msgid "Your subscription expired!"
+msgstr ""
+
+msgid "Your subscription has been downgraded"
+msgstr ""
+
+msgid "Your subscription will automatically renew in %{remaining_days}"
+msgstr ""
+
+msgid "Your subscription will expire in %{remaining_days}"
+msgstr ""
+
+msgid "Zoom meeting added"
+msgstr ""
+
+msgid "Zoom meeting removed"
+msgstr ""
+
+msgid "[No reason]"
+msgstr ""
+
+msgid "a deleted user"
+msgstr ""
+
+msgid "a design"
+msgstr ""
+
+msgid "about 1 hour"
+msgid_plural "about %d hours"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "activated"
+msgstr ""
+
+msgid "added %{created_at_timeago}"
+msgstr ""
+
+msgid "added a Zoom call to this issue"
+msgstr ""
+
+msgid "ago"
+msgstr ""
+
+msgid "alert"
+msgstr ""
+
+msgid "allowed to fail"
+msgstr ""
+
+msgid "already being used for another group or project %{timebox_name}."
+msgstr ""
+
+msgid "already has a \"created\" issue link"
+msgstr ""
+
+msgid "already shared with this group"
+msgstr ""
+
+msgid "among other things"
+msgstr ""
+
+msgid "any-approver for the merge request already exists"
+msgstr ""
+
+msgid "any-approver for the project already exists"
+msgstr ""
+
+msgid "archived"
+msgstr ""
+
+msgid "assign yourself"
+msgstr ""
+
+msgid "at risk"
+msgstr ""
+
+msgid "attach a new file"
+msgstr ""
+
+msgid "authored"
+msgstr ""
+
+msgid "blocks"
+msgstr ""
+
+msgid "branch name"
+msgstr ""
+
+msgid "build pipeline reference mismatch"
+msgstr ""
+
+msgid "by"
+msgstr ""
+
+msgid "by %{user}"
+msgstr ""
+
+msgid "cannot be changed if a personal project has container registry tags."
+msgstr ""
+
+msgid "cannot be enabled unless all domains have TLS certificates"
+msgstr ""
+
+msgid "cannot be modified"
+msgstr ""
+
+msgid "cannot block others"
+msgstr ""
+
+msgid "cannot include leading slash or directory traversal."
+msgstr ""
+
+msgid "cannot itself be blocked"
+msgstr ""
+
+msgid "cannot merge"
+msgstr ""
+
+msgid "ciReport|%{linkStartTag}Learn more about Container Scanning %{linkEndTag}"
+msgstr ""
+
+msgid "ciReport|%{linkStartTag}Learn more about DAST %{linkEndTag}"
+msgstr ""
+
+msgid "ciReport|%{linkStartTag}Learn more about Dependency Scanning %{linkEndTag}"
+msgstr ""
+
+msgid "ciReport|%{linkStartTag}Learn more about SAST %{linkEndTag}"
+msgstr ""
+
+msgid "ciReport|%{linkStartTag}Learn more about Secret Scanning %{linkEndTag}"
+msgstr ""
+
+msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
+msgstr ""
+
+msgid "ciReport|%{remainingPackagesCount} more"
+msgstr ""
+
+msgid "ciReport|%{reportType} %{status} detected %{dismissedCount} dismissed vulnerability"
+msgid_plural "ciReport|%{reportType} %{status} detected %{dismissedCount} dismissed vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ciReport|%{reportType} %{status} detected %{dismissedCount} dismissed vulnerability for the source branch only"
+msgid_plural "ciReport|%{reportType} %{status} detected %{dismissedCount} dismissed vulnerabilities for the source branch only"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ciReport|%{reportType} %{status} detected %{fixedCount} fixed vulnerability"
+msgid_plural "ciReport|%{reportType} %{status} detected %{fixedCount} fixed vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ciReport|%{reportType} %{status} detected %{fixedCount} fixed, and %{dismissedCount} dismissed vulnerabilities"
+msgstr ""
+
+msgid "ciReport|%{reportType} %{status} detected %{newCount} new vulnerability"
+msgid_plural "ciReport|%{reportType} %{status} detected %{newCount} new vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ciReport|%{reportType} %{status} detected %{newCount} new, %{fixedCount} fixed, and %{dismissedCount} dismissed vulnerabilities"
+msgstr ""
+
+msgid "ciReport|%{reportType} %{status} detected %{newCount} new, and %{dismissedCount} dismissed vulnerabilities"
+msgstr ""
+
+msgid "ciReport|%{reportType} %{status} detected %{newCount} new, and %{dismissedCount} dismissed vulnerabilities for the source branch only"
+msgstr ""
+
+msgid "ciReport|%{reportType} %{status} detected %{newCount} new, and %{fixedCount} fixed vulnerabilities"
+msgstr ""
+
+msgid "ciReport|%{reportType} %{status} detected %{newCount} vulnerability for the source branch only"
+msgid_plural "ciReport|%{reportType} %{status} detected %{newCount} vulnerabilities for the source branch only"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ciReport|%{reportType} %{status} detected no new vulnerabilities"
+msgstr ""
+
+msgid "ciReport|%{reportType} %{status} detected no vulnerabilities"
+msgstr ""
+
+msgid "ciReport|%{reportType} %{status} detected no vulnerabilities for the source branch only"
+msgstr ""
+
+msgid "ciReport|%{reportType} is loading"
+msgstr ""
+
+msgid "ciReport|%{reportType}: Loading resulted in an error"
+msgstr ""
+
+msgid "ciReport|(errors when loading results)"
+msgstr ""
+
+msgid "ciReport|(is loading)"
+msgstr ""
+
+msgid "ciReport|(is loading, errors when loading results)"
+msgstr ""
+
+msgid "ciReport|All projects"
+msgstr ""
+
+msgid "ciReport|All report types"
+msgstr ""
+
+msgid "ciReport|All severities"
+msgstr ""
+
+msgid "ciReport|Automatically apply the patch in a new branch"
+msgstr ""
+
+msgid "ciReport|Base pipeline codequality artifact not found"
+msgstr ""
+
+msgid "ciReport|Code quality"
+msgstr ""
+
+msgid "ciReport|Container Scanning"
+msgstr ""
+
+msgid "ciReport|Container scanning"
+msgstr ""
+
+msgid "ciReport|Container scanning detects known vulnerabilities in your docker images."
+msgstr ""
+
+msgid "ciReport|Create a merge request to implement this solution, or download and apply the patch manually."
+msgstr ""
+
+msgid "ciReport|Create issue"
+msgstr ""
+
+msgid "ciReport|DAST"
+msgstr ""
+
+msgid "ciReport|Dependency Scanning"
+msgstr ""
+
+msgid "ciReport|Dependency Scanning detects known vulnerabilities in your source code's dependencies."
+msgstr ""
+
+msgid "ciReport|Dependency scanning"
+msgstr ""
+
+msgid "ciReport|Download patch to resolve"
+msgstr ""
+
+msgid "ciReport|Download the patch to apply it manually"
+msgstr ""
+
+msgid "ciReport|Dynamic Application Security Testing (DAST) detects known vulnerabilities in your web application."
+msgstr ""
+
+msgid "ciReport|Failed to load %{reportName} report"
+msgstr ""
+
+msgid "ciReport|Fixed"
+msgstr ""
+
+msgid "ciReport|Fixed:"
+msgstr ""
+
+msgid "ciReport|Found %{issuesWithCount}"
+msgstr ""
+
+msgid "ciReport|Investigate this vulnerability by creating an issue"
+msgstr ""
+
+msgid "ciReport|Learn more about interacting with security reports"
+msgstr ""
+
+msgid "ciReport|Loading %{reportName} report"
+msgstr ""
+
+msgid "ciReport|Manage licenses"
+msgstr ""
+
+msgid "ciReport|New"
+msgstr ""
+
+msgid "ciReport|No changes to code quality"
+msgstr ""
+
+msgid "ciReport|No changes to performance metrics"
+msgstr ""
+
+msgid "ciReport|No code quality issues found"
+msgstr ""
+
+msgid "ciReport|Performance metrics"
+msgstr ""
+
+msgid "ciReport|Resolve with merge request"
+msgstr ""
+
+msgid "ciReport|SAST"
+msgstr ""
+
+msgid "ciReport|Secret Detection"
+msgstr ""
+
+msgid "ciReport|Secret scanning"
+msgstr ""
+
+msgid "ciReport|Secret scanning detects secrets and credentials vulnerabilities in your source code."
+msgstr ""
+
+msgid "ciReport|Security scanning"
+msgstr ""
+
+msgid "ciReport|Security scanning failed loading any results"
+msgstr ""
+
+msgid "ciReport|Solution"
+msgstr ""
+
+msgid "ciReport|Static Application Security Testing (SAST) detects known vulnerabilities in your source code."
+msgstr ""
+
+msgid "ciReport|There was an error creating the issue. Please try again."
+msgstr ""
+
+msgid "ciReport|There was an error creating the merge request. Please try again."
+msgstr ""
+
+msgid "ciReport|There was an error dismissing the vulnerability. Please try again."
+msgstr ""
+
+msgid "ciReport|There was an error fetching the codequality report."
+msgstr ""
+
+msgid "ciReport|There was an error reverting the dismissal. Please try again."
+msgstr ""
+
+msgid "ciReport|Used by %{packagesString}"
+msgid_plural "ciReport|Used by %{packagesString}, and %{lastPackage}"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ciReport|View full report"
+msgstr ""
+
+msgid "closed issue"
+msgstr ""
+
+msgid "comment"
+msgstr ""
+
+msgid "commented on %{link_to_project}"
+msgstr ""
+
+msgid "commit %{commit_id}"
+msgstr ""
+
+msgid "committed"
+msgstr ""
+
+msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
+msgstr ""
+
+msgid "confidentiality|You are going to turn on the confidentiality. This means that only team members with <strong>at least Reporter access</strong> are able to see and leave comments on the issue."
+msgstr ""
+
+msgid "connecting"
+msgstr ""
+
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
+msgid "container_name cannot be larger than %{max_length} chars"
+msgstr ""
+
+msgid "could not read private key, is the passphrase correct?"
+msgstr ""
+
+msgid "created"
+msgstr ""
+
+msgid "created %{timeAgo}"
+msgstr ""
+
+msgid "customize"
+msgstr ""
+
+msgid "date must not be after 9999-12-31"
+msgstr ""
+
+msgid "day"
+msgid_plural "days"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "default branch"
+msgstr ""
+
+msgid "deleted"
+msgstr ""
+
+msgid "deploy"
+msgstr ""
+
+msgid "design"
+msgstr ""
+
+msgid "designs"
+msgstr ""
+
+msgid "detached"
+msgstr ""
+
+msgid "disabled"
+msgstr ""
+
+msgid "does not have a supported extension. Only %{extension_list} are supported"
+msgstr ""
+
+msgid "done"
+msgstr ""
+
+msgid "download it"
+msgstr ""
+
+msgid "draft"
+msgid_plural "drafts"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "e.g. %{token}"
+msgstr ""
+
+msgid "element is not a hierarchy"
+msgstr ""
+
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
+msgstr ""
+
+msgid "enabled"
+msgstr ""
+
+msgid "encrypted: needs to be a :required, :optional or :migrating!"
+msgstr ""
+
+msgid "entries cannot be larger than 255 characters"
+msgstr ""
+
+msgid "entries cannot be nil"
+msgstr ""
+
+msgid "entries cannot contain HTML tags"
+msgstr ""
+
+msgid "error"
+msgstr ""
+
+msgid "error code:"
+msgstr ""
+
+msgid "estimateCommand|%{slash_command} will update the estimated time with the latest command."
+msgstr ""
+
+msgid "exceeds the limit of %{bytes} bytes"
+msgstr ""
+
+msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
+msgstr ""
+
+msgid "expired on %{timebox_due_date}"
+msgstr ""
+
+msgid "expires on %{timebox_due_date}"
+msgstr ""
+
+msgid "external_url"
+msgstr ""
+
+msgid "failed"
+msgstr ""
+
+msgid "failed to dismiss associated finding(id=%{finding_id}): %{message}"
+msgstr ""
+
+msgid "file"
+msgid_plural "files"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "finding is not found or is already attached to a vulnerability"
+msgstr ""
+
+msgid "for %{link_to_merge_request} with %{link_to_merge_request_source_branch}"
+msgstr ""
+
+msgid "for %{link_to_merge_request} with %{link_to_merge_request_source_branch} into %{link_to_merge_request_target_branch}"
+msgstr ""
+
+msgid "for %{link_to_pipeline_ref}"
+msgstr ""
+
+msgid "for %{ref}"
+msgstr ""
+
+msgid "for this project"
+msgstr ""
+
+msgid "fork this project"
+msgstr ""
+
+msgid "from"
+msgstr ""
+
+msgid "geo_node_name"
+msgstr ""
+
+msgid "group"
+msgstr ""
+
+msgid "groups"
+msgstr ""
+
+msgid "has already been linked to another vulnerability"
+msgstr ""
+
+msgid "has already been taken"
+msgstr ""
+
+msgid "help"
+msgstr ""
+
+msgid "here"
+msgstr ""
+
+msgid "https://your-bitbucket-server"
+msgstr ""
+
+msgid "image"
+msgstr ""
+
+msgid "image diff"
+msgstr ""
+
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
+msgid "import flow"
+msgstr ""
+
+msgid "importing"
+msgstr ""
+
+msgid "in group %{link_to_group}"
+msgstr ""
+
+msgid "in project %{link_to_project}"
+msgstr ""
+
+msgid "index"
+msgstr ""
+
+msgid "instance completed"
+msgid_plural "instances completed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "invalid milestone state `%{state}`"
+msgstr ""
+
+msgid "is"
+msgstr ""
+
+msgid "is already associated to a GitLab Issue. New issue will not be associated."
+msgstr ""
+
+msgid "is an invalid IP address range"
+msgstr ""
+
+msgid "is blocked by"
+msgstr ""
+
+msgid "is enabled."
+msgstr ""
+
+msgid "is invalid because there is downstream lock"
+msgstr ""
+
+msgid "is invalid because there is upstream lock"
+msgstr ""
+
+msgid "is not"
+msgstr ""
+
+msgid "is not a descendant of the Group owning the template"
+msgstr ""
+
+msgid "is not a valid X509 certificate."
+msgstr ""
+
+msgid "is not allowed. Try again with a different email address, or contact your GitLab admin."
+msgstr ""
+
+msgid "is not an email you own"
+msgstr ""
+
+msgid "is not in the group enforcing Group Managed Account"
+msgstr ""
+
+msgid "is read only"
+msgstr ""
+
+msgid "is too long (%{current_value}). The maximum size is %{max_size}."
+msgstr ""
+
+msgid "is too long (maximum is 100 entries)"
+msgstr ""
+
+msgid "is too long (maximum is 1000 entries)"
+msgstr ""
+
+msgid "issue"
+msgstr ""
+
+msgid "issues at risk"
+msgstr ""
+
+msgid "issues need attention"
+msgstr ""
+
+msgid "issues on track"
+msgstr ""
+
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
+msgid "it is stored externally"
+msgstr ""
+
+msgid "it is stored in LFS"
+msgstr ""
+
+msgid "it is too large"
+msgstr ""
+
+msgid "jigsaw is not defined"
+msgstr ""
+
+msgid "jira.issue.description.content"
+msgstr ""
+
+msgid "jira.issue.summary"
+msgstr ""
+
+msgid "latest"
+msgstr ""
+
+msgid "latest deployment"
+msgstr ""
+
+msgid "latest version"
+msgstr ""
+
+msgid "leave %{group_name}"
+msgstr ""
+
+msgid "less than a minute"
+msgstr ""
+
+msgid "level: %{level}"
+msgstr ""
+
+msgid "limit of %{project_limit} reached"
+msgstr ""
+
+msgid "load it anyway"
+msgstr ""
+
+msgid "locked by %{path_lock_user_name} %{created_at}"
+msgstr ""
+
+msgid "log in"
+msgstr ""
+
+msgid "manual"
+msgstr ""
+
+msgid "math|The math in this entry is taking too long to render and may not be displayed as expected. For performance reasons, math blocks are also limited to %{maxChars} characters. Consider splitting up large formulae, splitting math blocks among multiple entries, or using an image instead."
+msgstr ""
+
+msgid "math|There was an error rendering this math block"
+msgstr ""
+
+msgid "merge request"
+msgid_plural "merge requests"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "merged %{time_ago}"
+msgstr ""
+
+msgid "missing"
+msgstr ""
+
+msgid "most recent deployment"
+msgstr ""
+
+msgid "mrWidgetCommitsAdded|%{commitCount} and %{mergeCommitCount} will be added to %{targetBranch}."
+msgstr ""
+
+msgid "mrWidgetCommitsAdded|%{commitCount} will be added to %{targetBranch}."
+msgstr ""
+
+msgid "mrWidgetCommitsAdded|1 merge commit"
+msgstr ""
+
+msgid "mrWidgetNothingToMerge|Currently there are no changes in this merge request's source branch. Please push new commits or use a different branch."
+msgstr ""
+
+msgid "mrWidgetNothingToMerge|Interested parties can even contribute by pushing commits if they want to."
+msgstr ""
+
+msgid "mrWidgetNothingToMerge|Merge requests are a place to propose changes you have made to a project and discuss those changes with others."
+msgstr ""
+
+msgid "mrWidget| Please restore it or use a different %{missingBranchName} branch"
+msgstr ""
+
+msgid "mrWidget|%{link_start}Learn more about resolving conflicts%{link_end}"
+msgstr ""
+
+msgid "mrWidget|%{metricsLinkStart} Memory %{metricsLinkEnd} usage %{emphasisStart} decreased %{emphasisEnd} from %{memoryFrom}MB to %{memoryTo}MB"
+msgstr ""
+
+msgid "mrWidget|%{metricsLinkStart} Memory %{metricsLinkEnd} usage %{emphasisStart} increased %{emphasisEnd} from %{memoryFrom}MB to %{memoryTo}MB"
+msgstr ""
+
+msgid "mrWidget|%{metricsLinkStart} Memory %{metricsLinkEnd} usage is %{emphasisStart} unchanged %{emphasisEnd} at %{memoryFrom}MB"
+msgstr ""
+
+msgid "mrWidget|%{prefixToLinkStart}No pipeline%{prefixToLinkEnd} %{addPipelineLinkStart}Add the .gitlab-ci.yml file%{addPipelineLinkEnd} to create one."
+msgstr ""
+
+msgid "mrWidget|Added to the merge train by"
+msgstr ""
+
+msgid "mrWidget|Allows commits from members who can merge to the target branch"
+msgstr ""
+
+msgid "mrWidget|An error occurred while removing your approval."
+msgstr ""
+
+msgid "mrWidget|An error occurred while retrieving approval data for this merge request."
+msgstr ""
+
+msgid "mrWidget|An error occurred while submitting your approval."
+msgstr ""
+
+msgid "mrWidget|Approval password is invalid."
+msgstr ""
+
+msgid "mrWidget|Approve"
+msgstr ""
+
+msgid "mrWidget|Approve additionally"
+msgstr ""
+
+msgid "mrWidget|Approved by"
+msgstr ""
+
+msgid "mrWidget|Are you adding technical debt or code vulnerabilities?"
+msgstr ""
+
+msgid "mrWidget|Cancel automatic merge"
+msgstr ""
+
+msgid "mrWidget|Check out branch"
+msgstr ""
+
+msgid "mrWidget|Checking ability to merge automatically…"
+msgstr ""
+
+msgid "mrWidget|Cherry-pick"
+msgstr ""
+
+msgid "mrWidget|Cherry-pick this merge request in a new merge request"
+msgstr ""
+
+msgid "mrWidget|Closed"
+msgstr ""
+
+msgid "mrWidget|Closed by"
+msgstr ""
+
+msgid "mrWidget|Closes"
+msgstr ""
+
+msgid "mrWidget|Create an issue to resolve them later"
+msgstr ""
+
+msgid "mrWidget|Delete source branch"
+msgstr ""
+
+msgid "mrWidget|Deployment statistics are not available currently"
+msgstr ""
+
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
+msgstr ""
+
+msgid "mrWidget|Did not close"
+msgstr ""
+
+msgid "mrWidget|Email patches"
+msgstr ""
+
+msgid "mrWidget|Failed to load deployment statistics"
+msgstr ""
+
+msgid "mrWidget|Fast-forward merge is not possible. To merge this request, first rebase locally."
+msgstr ""
+
+msgid "mrWidget|Fork merge requests do not create merge request pipelines which validate a post merge result"
+msgstr ""
+
+msgid "mrWidget|If the %{branch} branch exists in your local repository, you can merge this merge request manually using the"
+msgstr ""
+
+msgid "mrWidget|If the %{missingBranchName} branch exists in your local repository, you can merge this merge request manually using the command line"
+msgstr ""
+
+msgid "mrWidget|In the merge train at position %{mergeTrainPosition}"
+msgstr ""
+
+msgid "mrWidget|Loading deployment statistics"
+msgstr ""
+
+msgid "mrWidget|Mentions"
+msgstr ""
+
+msgid "mrWidget|Merge"
+msgstr ""
+
+msgid "mrWidget|Merge failed."
+msgstr ""
+
+msgid "mrWidget|Merge failed: %{mergeError}. Please try again."
+msgstr ""
+
+msgid "mrWidget|Merge locally"
+msgstr ""
+
+msgid "mrWidget|Merge request approved."
+msgstr ""
+
+msgid "mrWidget|Merged by"
+msgstr ""
+
+msgid "mrWidget|More information"
+msgstr ""
+
+msgid "mrWidget|No approval required"
+msgstr ""
+
+msgid "mrWidget|No approval required; you can still approve"
+msgstr ""
+
+msgid "mrWidget|Open in Web IDE"
+msgstr ""
+
+msgid "mrWidget|Pipeline blocked. The pipeline for this merge request requires a manual action to proceed"
+msgstr ""
+
+msgid "mrWidget|Plain diff"
+msgstr ""
+
+msgid "mrWidget|Ready to be merged automatically. Ask someone with write access to this repository to merge this request"
+msgstr ""
+
+msgid "mrWidget|Refresh"
+msgstr ""
+
+msgid "mrWidget|Refresh now"
+msgstr ""
+
+msgid "mrWidget|Refreshing now"
+msgstr ""
+
+msgid "mrWidget|Remove from merge train"
+msgstr ""
+
+msgid "mrWidget|Request to merge"
+msgstr ""
+
+msgid "mrWidget|Resolve WIP status"
+msgstr ""
+
+msgid "mrWidget|Resolve conflicts"
+msgstr ""
+
+msgid "mrWidget|Resolve these conflicts or ask someone with write access to this repository to merge it locally"
+msgstr ""
+
+msgid "mrWidget|Revert"
+msgstr ""
+
+msgid "mrWidget|Revert this merge request in a new merge request"
+msgstr ""
+
+msgid "mrWidget|Revoke approval"
+msgstr ""
+
+msgid "mrWidget|Set by"
+msgstr ""
+
+msgid "mrWidget|The changes were merged into"
+msgstr ""
+
+msgid "mrWidget|The changes were not merged into"
+msgstr ""
+
+msgid "mrWidget|The changes will be merged into"
+msgstr ""
+
+msgid "mrWidget|The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure"
+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 ""
+
+msgid "mrWidget|The source branch is %{commitsBehindLinkStart}%{commitsBehind}%{commitsBehindLinkEnd} the target branch"
+msgstr ""
+
+msgid "mrWidget|The source branch is being deleted"
+msgstr ""
+
+msgid "mrWidget|The source branch will be deleted"
+msgstr ""
+
+msgid "mrWidget|The source branch will not be deleted"
+msgstr ""
+
+msgid "mrWidget|There are merge conflicts"
+msgstr ""
+
+msgid "mrWidget|There are unresolved threads. Please resolve these threads"
+msgstr ""
+
+msgid "mrWidget|This feature merges changes from the target branch to the source branch. You cannot use this feature since the source branch is protected."
+msgstr ""
+
+msgid "mrWidget|This merge request failed to be merged automatically"
+msgstr ""
+
+msgid "mrWidget|This merge request is in the process of being merged"
+msgstr ""
+
+msgid "mrWidget|This merge request will be added to the merge train when pipeline %{linkStart}#%{pipelineId}%{linkEnd} succeeds."
+msgstr ""
+
+msgid "mrWidget|This merge request will start a merge train when pipeline %{linkStart}#%{pipelineId}%{linkEnd} succeeds."
+msgstr ""
+
+msgid "mrWidget|This project is archived, write access has been disabled"
+msgstr ""
+
+msgid "mrWidget|To approve this merge request, please enter your password. This project requires all approvals to be authenticated."
+msgstr ""
+
+msgid "mrWidget|When this merge request is ready, remove the WIP: prefix from the title to allow it to be merged"
+msgstr ""
+
+msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
+msgstr ""
+
+msgid "mrWidget|You can delete the source branch now"
+msgstr ""
+
+msgid "mrWidget|You can merge this merge request manually using the"
+msgstr ""
+
+msgid "mrWidget|Your password"
+msgstr ""
+
+msgid "mrWidget|branch does not exist."
+msgstr ""
+
+msgid "mrWidget|command line"
+msgstr ""
+
+msgid "mrWidget|into"
+msgstr ""
+
+msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
+msgstr ""
+
+msgid "mrWidget|to be merged automatically when the pipeline succeeds"
+msgstr ""
+
+msgid "mrWidget|to start a merge train when the pipeline succeeds"
+msgstr ""
+
+msgid "must be greater than start date"
+msgstr ""
+
+msgid "my-awesome-group"
+msgstr ""
+
+msgid "n/a"
+msgstr ""
+
+msgid "need attention"
+msgstr ""
+
+msgid "needs to be between 10 minutes and 1 month"
+msgstr ""
+
+msgid "never expires"
+msgstr ""
+
+msgid "new merge request"
+msgstr ""
+
+msgid "no contributions"
+msgstr ""
+
+msgid "no expiration"
+msgstr ""
+
+msgid "no one can merge"
+msgstr ""
+
+msgid "none"
+msgstr ""
+
+msgid "not found"
+msgstr ""
+
+msgid "notification emails"
+msgstr ""
+
+msgid "nounSeries|%{firstItem} and %{lastItem}"
+msgstr ""
+
+msgid "nounSeries|%{item}, %{nextItem}"
+msgstr ""
+
+msgid "nounSeries|%{item}, and %{lastItem}"
+msgstr ""
+
+msgid "on track"
+msgstr ""
+
+msgid "open issue"
+msgstr ""
+
+msgid "opened %{timeAgoString} by %{user}"
+msgstr ""
+
+msgid "opened %{timeAgo}"
+msgstr ""
+
+msgid "or"
+msgstr ""
+
+msgid "out of %d total test"
+msgid_plural "out of %d total tests"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "parent"
+msgid_plural "parents"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "password"
+msgstr ""
+
+msgid "pending comment"
+msgstr ""
+
+msgid "pending removal"
+msgstr ""
+
+msgid "per day"
+msgstr ""
+
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
+msgid "pipeline"
+msgstr ""
+
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
+msgid "pod_name cannot be larger than %{max_length} chars"
+msgstr ""
+
+msgid "point"
+msgid_plural "points"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "private"
+msgstr ""
+
+msgid "private key does not match certificate."
+msgstr ""
+
+msgid "processing"
+msgstr ""
+
+msgid "project"
+msgid_plural "projects"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
+msgid "project avatar"
+msgstr ""
+
+msgid "projects"
+msgstr ""
+
+msgid "push to your repository, create pipelines, create issues or add comments. To reduce storage capacity, delete unused repositories, artifacts, wikis, issues, and pipelines."
+msgstr ""
+
+msgid "quick actions"
+msgstr ""
+
+msgid "register"
+msgstr ""
+
+msgid "relates to"
+msgstr ""
+
+msgid "released %{time}"
+msgstr ""
+
+msgid "remaining"
+msgstr ""
+
+msgid "remove"
+msgstr ""
+
+msgid "remove due date"
+msgstr ""
+
+msgid "remove weight"
+msgstr ""
+
+msgid "removed a Zoom call from this issue"
+msgstr ""
+
+msgid "rendered diff"
+msgstr ""
+
+msgid "reply"
+msgid_plural "replies"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "reset it."
+msgstr ""
+
+msgid "resolved the corresponding error and closed the issue."
+msgstr ""
+
+msgid "revised"
+msgstr ""
+
+msgid "score"
+msgstr ""
+
+msgid "security Reports|There was an error creating the merge request"
+msgstr ""
+
+msgid "settings saved, but not activated"
+msgstr ""
+
+msgid "severity|Critical"
+msgstr ""
+
+msgid "severity|High"
+msgstr ""
+
+msgid "severity|Info"
+msgstr ""
+
+msgid "severity|Low"
+msgstr ""
+
+msgid "severity|Medium"
+msgstr ""
+
+msgid "severity|None"
+msgstr ""
+
+msgid "severity|Unknown"
+msgstr ""
+
+msgid "should be greater than or equal to %{access} inherited membership from group %{group_name}"
+msgstr ""
+
+msgid "show %{count} more"
+msgstr ""
+
+msgid "show fewer"
+msgstr ""
+
+msgid "show less"
+msgstr ""
+
+msgid "sign in"
+msgstr ""
+
+msgid "sort:"
+msgstr ""
+
+msgid "source"
+msgstr ""
+
+msgid "source diff"
+msgstr ""
+
+msgid "specified top is not part of the tree"
+msgstr ""
+
+msgid "spendCommand|%{slash_command} will update the sum of the time spent."
+msgstr ""
+
+msgid "started"
+msgstr ""
+
+msgid "started a discussion on %{design_link}"
+msgstr ""
+
+msgid "started on %{timebox_start_date}"
+msgstr ""
+
+msgid "starts on %{timebox_start_date}"
+msgstr ""
+
+msgid "stuck"
+msgstr ""
+
+msgid "success"
+msgstr ""
+
+msgid "suggestPipeline|1/2: Choose a template"
+msgstr ""
+
+msgid "suggestPipeline|2/2: Commit your changes"
+msgstr ""
+
+msgid "suggestPipeline|Commit the changes and your pipeline will automatically run for the first time."
+msgstr ""
+
+msgid "suggestPipeline|We recommend the %{boldStart}Code Quality%{boldEnd} template, which will add a report widget to your Merge Requests. This way you’ll learn about code quality degradations much sooner. %{footerStart} Goodbye technical debt! %{footerEnd}"
+msgstr ""
+
+msgid "syntax is correct"
+msgstr ""
+
+msgid "syntax is incorrect"
+msgstr ""
+
+msgid "tag name"
+msgstr ""
+
+msgid "the following issue(s)"
+msgstr ""
+
+msgid "this document"
+msgstr ""
+
+msgid "to help your contributors communicate effectively!"
+msgstr ""
+
+msgid "to list"
+msgstr ""
+
+msgid "toggle collapse"
+msgstr ""
+
+msgid "toggle dropdown"
+msgstr ""
+
+msgid "triggered"
+msgstr ""
+
+msgid "unicode domains should use IDNA encoding"
+msgstr ""
+
+msgid "updated"
+msgstr ""
+
+msgid "updated %{timeAgo}"
+msgstr ""
+
+msgid "updated %{time_ago}"
+msgstr ""
+
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
+msgid "user avatar"
+msgstr ""
+
+msgid "username"
+msgstr ""
+
+msgid "uses Kubernetes clusters to deploy your code!"
+msgstr ""
+
+msgid "verify ownership"
+msgstr ""
+
+msgid "version %{versionIndex}"
+msgstr ""
+
+msgid "via %{closed_via}"
+msgstr ""
+
+msgid "via merge request %{link}"
+msgstr ""
+
+msgid "view it on GitLab"
+msgstr ""
+
+msgid "view the blob"
+msgstr ""
+
+msgid "view the source"
+msgstr ""
+
+msgid "vulnerability|Add a comment"
+msgstr ""
+
+msgid "vulnerability|Add a comment or reason for dismissal"
+msgstr ""
+
+msgid "vulnerability|Add comment"
+msgstr ""
+
+msgid "vulnerability|Add comment & dismiss"
+msgstr ""
+
+msgid "vulnerability|Dismiss vulnerability"
+msgstr ""
+
+msgid "vulnerability|Save comment"
+msgstr ""
+
+msgid "vulnerability|Undo dismiss"
+msgstr ""
+
+msgid "vulnerability|dismissed"
+msgstr ""
+
+msgid "wiki page"
+msgstr ""
+
+msgid "will be released %{time}"
+msgstr ""
+
+msgid "with %{additions} additions, %{deletions} deletions."
+msgstr ""
+
+msgid "with expiry changing from %{old_expiry} to %{new_expiry}"
+msgstr ""
+
+msgid "with expiry remaining unchanged at %{old_expiry}"
+msgstr ""
+
+msgid "yaml invalid"
+msgstr ""
+
diff --git a/locale/bg/gitlab.po b/locale/bg/gitlab.po
index d9feb7039b4..3b400885dfb 100644
--- a/locale/bg/gitlab.po
+++ b/locale/bg/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: bg\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:36\n"
+"PO-Revision-Date: 2020-06-08 15:15\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] "%d подаване"
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr "Ðктивно"
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr "ДейноÑÑ‚"
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|Unknown"
+msgstr ""
+
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr "Създайте Ñи личен жетон за доÑтъп в акаÑ
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr "ЧаÑова зона за „Cron“"
-msgid "Cron syntax"
-msgstr "СинтакÑÐ¸Ñ Ð½Ð° „Cron“"
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr "Задайте потребителÑки шаблон, използвайки ÑинтакÑиÑа на „Cron“"
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,14 +8991,14 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
-msgstr "Ð’Ñеки ден (в 4 ч. Ñутринта)"
+msgid "Every day (at %{time})"
+msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
-msgstr "Ð’Ñеки меÑец (на 1-во чиÑло, в 4 ч. Ñутринта)"
+msgid "Every month (Day %{day} at %{time})"
+msgstr ""
msgid "Every three months"
msgstr ""
@@ -8627,8 +9009,8 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
-msgstr "Ð’ÑÑка Ñедмица (в неделÑ, в 4 ч. Ñутринта)"
+msgid "Every week (%{weekday} at %{time})"
+msgstr ""
msgid "Everyone"
msgstr ""
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr "Файлове"
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr "Филтриране по Ñъобщение"
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr "От Ñъздаването на проблема до внедрÑваÐ
msgid "From merge request merge until deploy to production"
msgstr "От прилагането на заÑвката за Ñливане до внедрÑването в крайната верÑиÑ"
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr "Ðаучете повече в"
@@ -12232,6 +12887,9 @@ msgstr "ÐапуÑкане на проекта"
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] "Ðов проблем"
msgstr[1] "Ðови проблема"
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr "Ðов проблем"
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr "СобÑтвеник"
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr "Проектът „%{project_name}“ беше обновен уÑпеÑ
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,8 +16955,8 @@ msgstr "ИзнеÑените данни на проекта бÑха изтриÑ
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr "Връзката към изнеÑените данни на проекта изгуби давноÑÑ‚. МолÑ, Ñъздайте нова от наÑтройките на проекта."
-msgid "Project export started. A download link will be sent by email."
-msgstr "ИзнаÑÑнето на проекта започна. Ще получите връзка към данните по е-поща."
+msgid "Project export started. A download link will be sent by email and made available on this page."
+msgstr ""
msgid "Project has too many %{label_for_message} to search"
msgstr ""
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr "Свързани внедрени задачи"
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr "ЗаÑвка за доÑтъп"
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr "Изберете формата на архива"
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr "Изберете целеви клон"
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] "Показване на %d Ñъбитие"
msgstr[1] "Показване на %d ÑъбитиÑ"
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr "Преминаване към клон/етикет"
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr "СъвкупноÑтта от ÑÑŠÐ±Ð¸Ñ‚Ð¸Ñ Ð´Ð¾Ð±Ð°Ð²ÐµÐ½Ð¸ към дÐ
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr "Етапът на подготовка за издаване показва времето между прилагането на заÑвката за Ñливане и внедрÑването на кода в Ñредата на работещата крайна верÑиÑ. Данните ще бъдат добавени автоматично Ñлед като направите първото Ñи внедрÑване в крайната верÑиÑ."
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr "Етапът на теÑтване показва времето, което е нужно на „Gitlab CI“ да изпълни вÑÑка Ñхема от задачи за Ñвързаната заÑвка за Ñливане. Данните ще бъдат добавени автоматично Ñлед като приключи изпълнението на първата Ви Ñхема."
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr "Това означава, че нÑма да можете да изпращате код, докато не Ñъздадете празно хранилище или не внеÑете ÑъщеÑтвуващо такова."
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] "чаÑ"
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr "Общо време за теÑтване на вÑички подаваниÑ/ÑливаниÑ"
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr "Качване на нов файл"
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr "щракнете за качване"
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr "ÐÑма доÑтатъчно данни за този етап."
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr "ОттеглÑне на заÑвката за доÑтъп"
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr "Ще получавате извеÑÑ‚Ð¸Ñ Ð·Ð° вÑÑка дейноÑÑ
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr "Ще получавате извеÑÑ‚Ð¸Ñ Ñамо за коментари, в които Ви @Ñпоменават"
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr "ÐÑма да можете да изтеглÑте или изпращате код в проекта чрез %{protocol}, докато не %{set_password_link} за акаунта Ñи"
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr "Вашето име"
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/bn_BD/gitlab.po b/locale/bn_BD/gitlab.po
index 26747c5d718..3ecb75f23e6 100644
--- a/locale/bn_BD/gitlab.po
+++ b/locale/bn_BD/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: bn\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:31\n"
+"PO-Revision-Date: 2020-06-08 15:10\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,13 +8991,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8627,7 +9009,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] ""
msgstr[1] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/bn_IN/gitlab.po b/locale/bn_IN/gitlab.po
index 8dd05d90fc5..f8d446f1eb9 100644
--- a/locale/bn_IN/gitlab.po
+++ b/locale/bn_IN/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: bn-IN\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:34\n"
+"PO-Revision-Date: 2020-06-08 15:13\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,13 +8991,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8627,7 +9009,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] ""
msgstr[1] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/bs_BA/gitlab.po b/locale/bs_BA/gitlab.po
index 69c02aa8f3f..6d09e32936f 100644
--- a/locale/bs_BA/gitlab.po
+++ b/locale/bs_BA/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: bs\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:33\n"
+"PO-Revision-Date: 2020-06-08 15:12\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -77,6 +77,18 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -101,6 +113,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -128,6 +146,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -212,6 +236,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+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] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -248,6 +278,18 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -272,6 +314,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -353,6 +398,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -362,6 +410,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -374,6 +425,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -407,12 +482,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -428,6 +512,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -470,6 +560,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -623,6 +719,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -845,6 +944,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -875,6 +977,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -884,6 +989,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -920,7 +1028,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -971,6 +1082,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -983,9 +1097,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -1031,9 +1142,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1124,12 +1232,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1166,7 +1268,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1175,6 +1277,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1220,7 +1325,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1235,6 +1340,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1244,9 +1352,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1262,7 +1376,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1328,6 +1445,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1418,16 +1538,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1754,64 +1874,118 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1820,16 +1994,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|Unknown"
+msgstr ""
+
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -2003,6 +2195,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2168,9 +2363,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2192,6 +2384,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2267,6 +2462,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2303,9 +2501,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2321,6 +2525,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2330,6 +2537,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2354,12 +2564,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2369,9 +2573,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2435,6 +2645,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2507,12 +2720,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2522,12 +2729,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2636,6 +2849,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2648,7 +2864,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2762,6 +2978,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2840,15 +3059,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2906,6 +3143,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2927,9 +3167,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2948,6 +3185,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2978,6 +3218,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2993,6 +3236,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3470,16 +3716,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3503,7 +3749,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3512,6 +3758,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3530,6 +3779,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3560,9 +3812,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3590,6 +3839,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3665,7 +3920,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3680,6 +3935,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3716,6 +3974,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3758,6 +4022,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3776,6 +4043,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3881,15 +4151,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4238,9 +4499,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4253,6 +4511,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4265,6 +4526,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4292,9 +4556,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4334,6 +4595,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4529,6 +4793,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4550,9 +4817,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4604,7 +4868,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4631,6 +4895,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4709,10 +4976,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4871,6 +5138,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5105,9 +5378,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5186,6 +5456,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5216,6 +5489,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5225,9 +5501,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5285,6 +5567,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5303,6 +5588,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5342,6 +5630,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5351,6 +5642,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5387,6 +5681,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5549,7 +5846,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5573,9 +5873,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5609,9 +5906,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5660,16 +5954,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5696,6 +5984,18 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5708,6 +6008,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5732,27 +6035,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5774,10 +6089,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5798,9 +6110,6 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5822,6 +6131,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5849,12 +6161,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5873,7 +6179,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5882,7 +6191,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5921,10 +6230,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -6011,6 +6320,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -6056,9 +6368,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6074,9 +6383,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6173,7 +6479,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6191,9 +6497,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6212,9 +6515,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6224,9 +6524,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6269,6 +6566,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6281,6 +6581,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6320,6 +6623,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6353,6 +6662,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6404,9 +6716,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6443,6 +6752,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6467,6 +6779,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6515,6 +6830,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6539,6 +6857,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6791,6 +7112,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6827,6 +7151,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6869,6 +7196,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6959,12 +7292,6 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -7001,12 +7328,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -7016,9 +7337,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7136,12 +7454,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7163,13 +7487,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7289,10 +7613,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7301,9 +7625,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7313,6 +7652,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7340,12 +7682,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7355,6 +7712,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7367,6 +7730,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7595,6 +7961,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7643,6 +8012,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7667,6 +8039,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7814,6 +8189,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7829,6 +8207,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7922,6 +8303,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7931,9 +8315,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7961,6 +8342,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8084,6 +8468,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8108,10 +8495,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8168,7 +8555,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8381,10 +8768,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8396,12 +8783,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr "Jesi li siguran da želiš ukloniti %{bStart}%{targetIssueTitle}%{bEnd} iz %{bStart}%{parentEpicTitle}%{bEnd}?"
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8471,7 +8852,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8576,9 +8966,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8594,6 +8981,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8645,10 +9035,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8690,14 +9080,14 @@ msgstr ""
msgid "Every day"
msgstr "Svaki dan"
-msgid "Every day (at 4:00am)"
-msgstr "Svaki dan (u 4:00 h)"
+msgid "Every day (at %{time})"
+msgstr ""
msgid "Every month"
msgstr "MjeseÄno"
-msgid "Every month (on the 1st at 4:00am)"
-msgstr "MjeseÄno (1. u 4:00 h)"
+msgid "Every month (Day %{day} at %{time})"
+msgstr ""
msgid "Every three months"
msgstr "TromjeseÄno"
@@ -8708,8 +9098,8 @@ msgstr "DvosedmiÄno"
msgid "Every week"
msgstr "SedmiÄno"
-msgid "Every week (Sundays at 4:00am)"
-msgstr "Svake sedmice (nedjeljom u 4:00 h)"
+msgid "Every week (%{weekday} at %{time})"
+msgstr ""
msgid "Everyone"
msgstr ""
@@ -8747,6 +9137,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8765,6 +9158,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8798,6 +9194,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8813,6 +9212,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8822,6 +9224,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8900,18 +9305,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -9038,6 +9431,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9113,7 +9509,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9176,6 +9572,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9188,6 +9590,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9197,15 +9602,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9224,6 +9638,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9239,9 +9656,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9332,6 +9755,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9344,6 +9770,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9353,9 +9782,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9371,24 +9797,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9398,6 +9845,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9629,9 +10079,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9671,15 +10118,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9857,6 +10304,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9866,10 +10319,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9920,6 +10373,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9971,6 +10430,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9989,6 +10451,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9998,6 +10463,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10250,9 +10721,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10286,9 +10754,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10451,12 +10916,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10490,6 +10964,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10502,10 +10982,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10523,10 +11006,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10544,12 +11030,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10616,9 +11108,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10820,6 +11309,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10925,6 +11417,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10934,6 +11429,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -11042,6 +11540,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -11051,6 +11552,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11201,6 +11705,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11210,7 +11717,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11219,6 +11729,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11231,7 +11747,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11249,13 +11768,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11267,6 +11786,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11276,6 +11798,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11285,10 +11810,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11381,10 +11906,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11417,6 +11942,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11450,6 +11978,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11474,18 +12008,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11537,6 +12089,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11576,6 +12152,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11612,18 +12194,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11636,6 +12227,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11699,6 +12293,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11711,6 +12308,33 @@ msgstr ""
msgid "Issue weight"
msgstr "Težina zadatka"
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11768,6 +12392,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11813,6 +12440,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11825,19 +12476,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11963,6 +12617,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -12002,6 +12659,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12182,6 +12842,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12266,6 +12929,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12287,9 +12953,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12317,6 +12980,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12329,6 +12995,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12353,15 +13022,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12500,6 +13163,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12515,6 +13181,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12611,6 +13280,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12725,10 +13397,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12755,6 +13427,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12806,9 +13481,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12818,9 +13490,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12998,6 +13667,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -13007,9 +13679,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -13022,6 +13691,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -13055,6 +13727,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13103,9 +13778,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13166,7 +13850,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13184,6 +13868,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13205,9 +13892,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13229,19 +13913,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13265,6 +13952,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13322,6 +14030,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13340,6 +14054,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13376,6 +14093,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13439,6 +14159,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13448,6 +14225,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13457,21 +14240,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13532,6 +14333,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13646,6 +14450,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13655,6 +14462,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13667,9 +14477,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13679,9 +14486,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13715,6 +14519,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13745,6 +14597,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13811,6 +14666,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13868,6 +14726,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13886,18 +14747,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13988,12 +14840,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -14018,6 +14876,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14153,6 +15014,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14177,6 +15041,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14291,9 +15158,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14360,6 +15233,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14369,9 +15251,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14438,7 +15317,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14483,7 +15362,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14498,6 +15377,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14528,7 +15410,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14576,6 +15458,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14594,6 +15479,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14615,6 +15503,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14702,6 +15596,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14720,6 +15617,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14750,22 +15650,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14798,6 +15713,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14885,6 +15803,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14903,6 +15824,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14945,9 +15869,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14969,9 +15899,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14993,9 +15920,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15104,6 +16028,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15164,15 +16091,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15185,30 +16121,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15224,6 +16184,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15260,6 +16223,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15353,6 +16322,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15428,6 +16400,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15518,6 +16493,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15554,6 +16532,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15773,9 +16754,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15821,9 +16799,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15968,12 +16943,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -16004,6 +16973,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -16025,6 +16997,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -16055,6 +17030,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -16079,7 +17057,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -16088,6 +17066,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16202,9 +17183,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16370,6 +17348,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16415,6 +17396,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16565,6 +17549,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16658,12 +17645,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16739,9 +17732,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16760,30 +17750,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16919,9 +17963,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16931,6 +17972,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -17033,6 +18080,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -17042,9 +18092,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -17081,9 +18128,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17180,6 +18224,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17225,6 +18284,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17246,6 +18317,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17315,6 +18389,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17357,6 +18437,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17396,6 +18479,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17447,6 +18533,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17477,6 +18566,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17492,7 +18584,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17597,6 +18692,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17633,6 +18731,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17648,10 +18749,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17666,6 +18770,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17687,10 +18797,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17762,6 +18869,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17774,6 +18884,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17921,6 +19037,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17984,9 +19103,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -18023,9 +19139,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18155,9 +19268,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18215,6 +19334,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18245,10 +19367,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18347,9 +19469,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18362,9 +19490,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18374,24 +19499,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18527,6 +19652,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18608,6 +19736,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18659,12 +19790,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18710,9 +19847,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18785,6 +19931,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18950,6 +20102,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18986,6 +20141,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -19070,6 +20228,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -19088,7 +20249,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19127,15 +20288,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19160,12 +20321,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19187,6 +20357,15 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19373,6 +20552,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19409,9 +20591,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19508,6 +20696,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19547,6 +20738,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19595,6 +20789,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19712,6 +20912,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19877,7 +21080,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19952,6 +21155,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -20078,6 +21284,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -20105,6 +21314,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20132,6 +21344,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20312,9 +21527,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20399,6 +21620,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20426,9 +21650,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20681,6 +21902,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20765,9 +21989,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20804,9 +22025,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20846,6 +22073,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -21020,6 +22250,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -21068,6 +22301,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21143,6 +22379,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21215,6 +22460,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21278,6 +22526,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21362,6 +22613,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21401,6 +22655,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21446,9 +22703,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21560,7 +22814,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21587,6 +22841,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21623,12 +22880,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21641,12 +22904,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21665,7 +22940,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21674,9 +22949,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21731,9 +23003,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21980,6 +23258,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -22046,6 +23327,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22166,6 +23453,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22223,15 +23513,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22247,9 +23531,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22268,6 +23549,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22379,6 +23663,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22436,10 +23723,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22448,6 +23735,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22487,6 +23777,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22496,9 +23789,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22748,18 +24047,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22778,6 +24071,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22796,6 +24092,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22820,9 +24119,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22832,12 +24128,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22847,12 +24149,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22871,12 +24179,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22901,7 +24215,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22976,9 +24290,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23225,6 +24536,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23285,6 +24602,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23312,7 +24632,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23354,6 +24677,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23402,6 +24728,9 @@ msgstr[2] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23465,6 +24794,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23546,9 +24878,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23579,9 +24908,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23690,6 +25016,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23702,6 +25031,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23723,7 +25055,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23765,9 +25103,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23807,12 +25142,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23849,9 +25193,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23885,9 +25226,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -24008,10 +25346,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -24020,10 +25361,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24140,6 +25481,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24167,6 +25511,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24182,6 +25529,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24260,6 +25610,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24308,6 +25661,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24323,7 +25679,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24416,6 +25772,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24443,6 +25802,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24461,6 +25823,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24494,7 +25862,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24530,7 +25901,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24623,9 +25994,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24635,12 +26015,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24665,9 +26051,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24716,6 +26108,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24758,6 +26153,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24932,6 +26330,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24950,6 +26351,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24968,6 +26372,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -25010,6 +26417,9 @@ msgstr[2] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -25019,6 +26429,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -25028,6 +26441,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25079,6 +26495,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -25091,7 +26510,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -25124,10 +26546,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25193,9 +26615,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25259,6 +26690,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25280,6 +26714,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25319,6 +26759,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25448,7 +26891,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25628,9 +27071,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25640,15 +27080,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25661,6 +27092,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25706,6 +27140,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25739,9 +27176,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25766,6 +27212,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25817,6 +27269,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25883,10 +27338,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25949,6 +27404,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25976,6 +27437,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -26003,6 +27467,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/ca_ES/gitlab.po b/locale/ca_ES/gitlab.po
index 6f3785e8e5a..c664d2013c5 100644
--- a/locale/ca_ES/gitlab.po
+++ b/locale/ca_ES/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: ca\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:15\n"
+"PO-Revision-Date: 2020-06-08 15:15\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -24,53 +24,63 @@ msgid " Collected %{time}"
msgstr ""
msgid " Please sign in."
-msgstr ""
+msgstr " Inicieu la sessió."
msgid " Try to %{action} this file again."
-msgstr ""
+msgstr " Intenta %{action} aquest fitxer de nou."
msgid " You need to do this before %{grace_period_deadline}."
-msgstr ""
+msgstr " Cal que ho feu abans 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[0] " degradat en %d punts"
+msgstr[1] " degradat en %d punts"
msgid " improved on %d point"
msgid_plural " improved on %d points"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] " millorat en %d punt"
+msgstr[1] " millorat en %d punts"
msgid " or "
-msgstr ""
+msgstr " o "
msgid " or <!merge request id>"
-msgstr ""
+msgstr " o <!merge request id>"
msgid " or <#issue id>"
-msgstr ""
+msgstr " o <#issue id>"
msgid " or <&epic id>"
msgstr ""
msgid " or references (e.g. path/to/project!merge_request_id)"
-msgstr ""
+msgstr " o referències (per ex. el camí/al/projecte!merge_request_id)"
msgid "\"%{path}\" did not exist on \"%{ref}\""
-msgstr ""
+msgstr "\"%{path}\" no existeix a \"%{ref}\""
msgid "%d URL scanned"
msgid_plural "%d URLs scanned"
+msgstr[0] "%d URL escanejada"
+msgstr[1] "%d URL escanejades"
+
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] "%d comissió"
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -801,7 +896,7 @@ msgid "<namespace / project>"
msgstr ""
msgid "<no name set>"
-msgstr ""
+msgstr "<sense nom establert>"
msgid "<no scopes selected>"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -954,7 +1058,7 @@ msgid "About this feature"
msgstr ""
msgid "Abuse Reports"
-msgstr ""
+msgstr "Informes d'abús"
msgid "Abuse reports"
msgstr "Informes d'abús"
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr "Actiu"
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr "Sessions actives"
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr "Activitat"
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr "Afegeix una reacció"
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,18 +1467,18 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr "Àrea d'administració"
+msgid "Admin Note"
+msgstr ""
+
msgid "Admin Overview"
msgstr "Informació general d'administració"
-msgid "Admin Section"
-msgstr ""
-
msgid "Admin mode already enabled"
msgstr ""
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Low"
+msgstr ""
+
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
+msgstr ""
+
+msgid "AlertManagement|View issue"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr "Analítiques"
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr "Qualsevol"
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr "Qualsevol etiqueta"
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr "Peticions de fusió assignades"
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr "ag."
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr "Canvia la plantilla"
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr "Tanca"
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr "Etiqueta"
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr "Crea una petició de fusió i una branca"
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr "Creat per mi"
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr "Configuració"
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr "Personalitza els colors"
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr "Detalls"
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr "Vots negatius"
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr "Adreça electrònica"
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr "Introduïu el títol de la petició de fusió"
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr "Com ho puc resoldre-ho?"
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,14 +8991,14 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
-msgstr "Cada dia (a les 4:00)"
+msgid "Every day (at %{time})"
+msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
-msgstr "Cada mes (el dia 1 a les 4:00)"
+msgid "Every month (Day %{day} at %{time})"
+msgstr ""
msgid "Every three months"
msgstr ""
@@ -8627,8 +9009,8 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
-msgstr "Cada setmana (diumenge a les 4:00)"
+msgid "Every week (%{weekday} at %{time})"
+msgstr ""
msgid "Everyone"
msgstr ""
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr "Nova"
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr "Plantilles de fitxers"
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr "Fitxers"
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr "Filtra"
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr "Mai"
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr "Estat"
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr "Estat desconegut"
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr "Vés a"
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr "Grup"
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr "Detalls del grup"
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr "Historial"
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,15 +11677,15 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
+msgid "Impersonation Tokens"
+msgstr ""
+
msgid "Impersonation has been disabled"
msgstr ""
msgid "Import"
msgstr "Importa"
-msgid "Import %{status}"
-msgstr ""
-
msgid "Import CSV"
msgstr ""
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr "Petició de fusió"
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr "Peticions de fusió"
@@ -12965,6 +13629,9 @@ msgstr "Petició de fusió"
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr "Missatges"
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr "Mètriques"
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr "Cancel·la"
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr "Nom"
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr "Nom:"
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr "Xarxa"
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr "Mai"
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] ""
msgstr[1] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/cs_CZ/gitlab.po b/locale/cs_CZ/gitlab.po
index 55a1492cdad..f3a82fa067c 100644
--- a/locale/cs_CZ/gitlab.po
+++ b/locale/cs_CZ/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: cs\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:14\n"
+"PO-Revision-Date: 2020-06-08 15:15\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -80,6 +80,20 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -108,6 +122,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] "%d commit"
@@ -139,6 +160,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -237,6 +265,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+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[3] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -279,6 +314,20 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -305,6 +354,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -390,6 +442,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -399,6 +454,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -411,6 +469,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -444,12 +526,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -465,6 +556,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr "Profilový obrázek %{name}"
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -509,6 +606,12 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -668,6 +771,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -908,6 +1014,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -938,6 +1047,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -947,6 +1059,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -983,7 +1098,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -1034,6 +1152,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -1046,9 +1167,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -1094,9 +1212,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1187,12 +1302,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1229,7 +1338,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1238,6 +1347,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1284,7 +1396,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1299,6 +1411,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1308,9 +1423,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1326,7 +1447,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1392,6 +1516,9 @@ msgstr "Přidat reakci"
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1482,16 +1609,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1818,6 +1945,15 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
@@ -1825,58 +1961,103 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
+msgstr ""
+
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1885,16 +2066,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -2068,6 +2267,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2233,9 +2435,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2257,6 +2456,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2332,6 +2534,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2368,9 +2573,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2386,6 +2597,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2395,6 +2609,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2419,12 +2636,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2434,9 +2645,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2500,6 +2717,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2576,12 +2796,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2591,12 +2805,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2705,6 +2925,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2717,7 +2940,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2831,6 +3054,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2911,15 +3137,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr "Srp"
@@ -2977,6 +3221,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2998,9 +3245,6 @@ msgstr "Auto DevOps aktivní"
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -3019,6 +3263,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -3049,6 +3296,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -3064,6 +3314,9 @@ msgstr ""
msgid "Available"
msgstr "K dispozici"
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3541,16 +3794,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3574,7 +3827,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3583,6 +3836,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3601,6 +3857,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3631,9 +3890,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3661,6 +3917,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3736,7 +3998,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3751,6 +4013,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3787,6 +4052,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3829,6 +4100,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3847,6 +4121,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3952,15 +4229,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4309,9 +4577,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4324,6 +4589,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4336,6 +4604,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4363,9 +4634,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4405,6 +4673,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4600,6 +4871,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4621,9 +4895,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4675,7 +4946,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4702,6 +4973,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4780,10 +5054,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4942,6 +5216,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5176,9 +5456,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5257,6 +5534,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5287,6 +5567,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5296,9 +5579,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5356,6 +5645,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5374,6 +5666,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5413,6 +5708,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5422,6 +5720,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5458,6 +5759,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5621,7 +5925,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5645,9 +5952,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5681,9 +5985,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5732,16 +6033,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5768,6 +6063,20 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5780,6 +6089,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5804,27 +6116,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5846,10 +6170,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5871,9 +6192,6 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5895,6 +6213,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5922,12 +6243,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5946,7 +6261,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5955,7 +6273,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5994,10 +6312,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -6084,6 +6402,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -6129,9 +6450,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6147,9 +6465,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6246,7 +6561,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6264,9 +6579,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6285,9 +6597,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6297,9 +6606,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6342,6 +6648,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6354,6 +6663,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6393,6 +6705,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6426,6 +6744,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6477,9 +6798,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6516,6 +6834,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6540,6 +6861,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6588,6 +6912,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6612,6 +6939,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6865,6 +7195,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6901,6 +7234,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6943,6 +7279,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -7034,13 +7376,6 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -7078,12 +7413,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -7093,9 +7422,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7216,12 +7542,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7243,13 +7575,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7369,10 +7701,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7381,9 +7713,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7393,6 +7740,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7420,12 +7770,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7435,6 +7800,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7447,6 +7818,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7676,6 +8050,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7724,6 +8101,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7748,6 +8128,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7895,6 +8278,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7910,6 +8296,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -8003,6 +8392,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -8012,9 +8404,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -8042,6 +8431,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8165,6 +8557,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8189,10 +8584,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8249,7 +8644,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8462,10 +8857,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8477,12 +8872,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8552,7 +8941,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8657,9 +9055,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8675,6 +9070,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8726,10 +9124,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8771,13 +9169,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8789,7 +9187,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8828,6 +9226,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8846,6 +9247,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8879,6 +9283,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8894,6 +9301,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8903,6 +9313,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8981,18 +9394,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -9119,6 +9520,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9194,7 +9598,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9257,6 +9661,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9269,6 +9679,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9278,15 +9691,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9305,6 +9727,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9320,9 +9745,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9413,6 +9844,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9425,6 +9859,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9434,9 +9871,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9452,24 +9886,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9479,6 +9934,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9710,9 +10168,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9752,15 +10207,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9938,6 +10393,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9947,10 +10408,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -10001,6 +10462,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -10052,6 +10519,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -10070,6 +10540,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -10079,6 +10552,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10331,9 +10810,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10367,9 +10843,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10532,12 +11005,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10571,6 +11053,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10583,10 +11071,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10604,10 +11095,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10625,12 +11119,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10697,9 +11197,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10901,6 +11398,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -11006,6 +11506,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -11015,6 +11518,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -11125,6 +11631,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -11134,6 +11643,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11284,6 +11796,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11293,7 +11808,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11302,6 +11820,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11314,7 +11838,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11332,13 +11859,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11350,6 +11877,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11359,6 +11889,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11368,10 +11901,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11464,10 +11997,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11500,6 +12033,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11533,6 +12069,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11557,18 +12099,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11621,6 +12181,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11660,6 +12244,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11696,18 +12286,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11720,6 +12319,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11783,6 +12385,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11795,6 +12400,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11852,6 +12484,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11897,6 +12532,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11909,19 +12568,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -12047,6 +12709,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -12086,6 +12751,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12267,6 +12935,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12351,6 +13022,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12372,9 +13046,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12402,6 +13073,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12414,6 +13088,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12438,15 +13115,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12589,6 +13260,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12604,6 +13278,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12701,6 +13378,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12815,10 +13495,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12845,6 +13525,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12896,9 +13579,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12908,9 +13588,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -13088,6 +13765,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -13097,9 +13777,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -13112,6 +13789,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -13145,6 +13825,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13193,9 +13876,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13256,7 +13948,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13274,6 +13966,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13295,9 +13990,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13319,19 +14011,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13355,6 +14050,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13413,6 +14129,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13431,6 +14153,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13467,6 +14192,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13531,6 +14259,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13540,6 +14325,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13549,21 +14340,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13624,6 +14433,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13738,6 +14550,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13747,6 +14562,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13759,9 +14577,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13771,9 +14586,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13807,6 +14619,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13838,6 +14698,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13904,6 +14767,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13961,6 +14827,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13979,18 +14848,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -14081,12 +14941,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -14111,6 +14977,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14246,6 +15115,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14270,6 +15142,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14384,9 +15259,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14453,6 +15334,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14462,9 +15352,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14532,7 +15419,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14577,7 +15464,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14592,6 +15479,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14622,7 +15512,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14670,6 +15560,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14688,6 +15581,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14709,6 +15605,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14796,6 +15698,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14814,6 +15719,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14844,22 +15752,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14892,6 +15815,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14979,6 +15905,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14997,6 +15926,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -15039,9 +15971,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -15063,9 +16001,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -15087,9 +16022,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15198,6 +16130,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15258,15 +16193,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15279,30 +16223,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15318,6 +16286,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15354,6 +16325,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15447,6 +16424,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15522,6 +16502,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15612,6 +16595,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15648,6 +16634,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15867,9 +16856,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15915,9 +16901,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -16062,12 +17045,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -16098,6 +17075,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -16119,6 +17099,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -16149,6 +17132,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -16173,7 +17159,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -16182,6 +17168,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16296,9 +17285,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16464,6 +17450,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16509,6 +17498,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16659,6 +17651,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16752,12 +17747,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16833,9 +17834,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16854,30 +17852,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -17013,9 +18065,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -17025,6 +18074,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -17127,6 +18182,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -17136,9 +18194,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -17175,9 +18230,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17275,6 +18327,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17321,6 +18388,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17342,6 +18421,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17411,6 +18493,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17453,6 +18541,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17492,6 +18583,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17543,6 +18637,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17573,6 +18670,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17588,7 +18688,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17694,6 +18797,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17730,6 +18836,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17745,10 +18854,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17763,6 +18875,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17784,10 +18902,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17861,6 +18976,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17873,6 +18991,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -18021,6 +19145,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -18084,9 +19211,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -18123,9 +19247,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18255,9 +19376,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18315,6 +19442,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18345,10 +19475,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18457,9 +19587,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18472,9 +19608,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18484,24 +19617,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18637,6 +19770,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18718,6 +19854,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18769,12 +19908,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18820,9 +19965,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18895,6 +20049,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -19060,6 +20220,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -19096,6 +20259,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -19180,6 +20346,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -19198,7 +20367,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19237,15 +20406,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19270,12 +20439,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19298,6 +20476,16 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19484,6 +20672,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19520,9 +20711,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19619,6 +20816,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19658,6 +20858,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19706,6 +20909,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19823,6 +21032,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19988,7 +21200,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -20063,6 +21275,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -20189,6 +21404,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -20216,6 +21434,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20243,6 +21464,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20423,9 +21647,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20510,6 +21740,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20537,9 +21770,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20793,6 +22023,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20878,9 +22111,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20917,9 +22147,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20960,6 +22196,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -21134,6 +22373,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -21182,6 +22424,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21257,6 +22502,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21329,6 +22583,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21392,6 +22649,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21476,6 +22736,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21515,6 +22778,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21674,7 +22937,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21701,6 +22964,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21737,12 +23003,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21755,12 +23027,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21779,7 +23063,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21788,9 +23072,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21845,9 +23126,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -22094,6 +23381,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -22162,6 +23452,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22282,6 +23578,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22339,15 +23638,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22363,9 +23656,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22384,6 +23674,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22495,6 +23788,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22552,10 +23848,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22564,6 +23860,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22603,6 +23902,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22612,9 +23914,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22864,18 +24172,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22894,6 +24196,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22912,6 +24217,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22936,9 +24244,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22948,12 +24253,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22963,12 +24274,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22987,12 +24304,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr "Pomocí %{code_start}::%{code_end} vytvořte sadu %{link_start} štítků s rozsahem %{link_end} (např. Priorita %{code_start}::1%{code_end})"
@@ -23017,7 +24340,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -23092,9 +24415,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23341,6 +24661,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23401,6 +24727,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23428,7 +24757,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23470,6 +24802,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23520,6 +24855,9 @@ msgstr[3] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23583,6 +24921,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23664,9 +25005,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23697,9 +25035,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23808,6 +25143,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23820,6 +25158,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23841,7 +25182,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23883,9 +25230,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23925,12 +25269,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23968,9 +25321,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -24004,9 +25354,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -24127,10 +25474,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -24139,10 +25489,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24259,6 +25609,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24286,6 +25639,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24301,6 +25657,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24379,6 +25738,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24427,6 +25789,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24442,7 +25807,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24535,6 +25900,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24562,6 +25930,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24580,6 +25951,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24613,7 +25990,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24649,7 +26029,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24742,9 +26122,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24754,12 +26143,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24784,9 +26179,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24836,6 +26237,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24878,6 +26282,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -25057,6 +26464,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -25075,6 +26485,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -25093,6 +26506,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -25136,6 +26552,9 @@ msgstr[3] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -25145,6 +26564,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -25154,6 +26576,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25206,6 +26631,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -25219,7 +26647,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -25252,10 +26683,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25322,9 +26753,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25389,6 +26829,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25410,6 +26853,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25449,6 +26898,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25579,7 +27031,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25759,9 +27211,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25771,15 +27220,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25792,6 +27232,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25837,6 +27280,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25872,9 +27318,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25901,6 +27356,12 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25953,6 +27414,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -26019,10 +27483,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -26085,6 +27549,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -26112,6 +27582,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -26139,6 +27612,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/cy_GB/gitlab.po b/locale/cy_GB/gitlab.po
index 1b1664ca998..d82e768cebe 100644
--- a/locale/cy_GB/gitlab.po
+++ b/locale/cy_GB/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: cy\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:32\n"
+"PO-Revision-Date: 2020-06-08 15:11\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -86,6 +86,24 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -122,6 +140,15 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -161,6 +188,15 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -287,6 +323,15 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+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[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -341,6 +386,24 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -371,6 +434,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -464,6 +530,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -473,6 +542,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -485,6 +557,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -518,12 +614,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -539,6 +644,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -587,6 +698,12 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -758,6 +875,9 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -1034,6 +1154,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -1064,6 +1187,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -1073,6 +1199,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -1109,7 +1238,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -1160,6 +1292,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -1172,9 +1307,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -1220,9 +1352,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1313,12 +1442,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1355,7 +1478,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1364,6 +1487,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1412,7 +1538,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1427,6 +1553,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1436,9 +1565,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1454,7 +1589,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1520,6 +1658,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1610,16 +1751,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1946,6 +2087,15 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
@@ -1955,58 +2105,103 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
+msgstr ""
+
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -2015,16 +2210,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -2198,6 +2411,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2363,9 +2579,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2387,6 +2600,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2462,6 +2678,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2498,9 +2717,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2516,6 +2741,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2525,6 +2753,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2549,12 +2780,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2564,9 +2789,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2630,6 +2861,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2714,12 +2948,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2729,12 +2957,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2843,6 +3077,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2855,7 +3092,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2969,6 +3206,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -3053,15 +3293,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -3119,6 +3377,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -3140,9 +3401,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -3161,6 +3419,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -3191,6 +3452,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -3206,6 +3470,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3683,16 +3950,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3716,7 +3983,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3725,6 +3992,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3743,6 +4013,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3773,9 +4046,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3803,6 +4073,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3878,7 +4154,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3893,6 +4169,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3929,6 +4208,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3971,6 +4256,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3989,6 +4277,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -4094,15 +4385,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4451,9 +4733,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4466,6 +4745,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4478,6 +4760,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4505,9 +4790,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4547,6 +4829,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4742,6 +5027,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4763,9 +5051,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4817,7 +5102,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4844,6 +5129,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4922,10 +5210,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -5084,6 +5372,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5318,9 +5612,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5399,6 +5690,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5429,6 +5723,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5438,9 +5735,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5498,6 +5801,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5516,6 +5822,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5555,6 +5864,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5564,6 +5876,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5600,6 +5915,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5765,7 +6083,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5789,9 +6110,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5825,9 +6143,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5876,16 +6191,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5912,6 +6221,24 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5924,6 +6251,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5948,27 +6278,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5990,10 +6332,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -6017,9 +6356,6 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -6041,6 +6377,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -6068,12 +6407,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -6092,7 +6425,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -6101,7 +6437,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -6140,10 +6476,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -6230,6 +6566,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -6275,9 +6614,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6293,9 +6629,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6392,7 +6725,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6410,9 +6743,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6431,9 +6761,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6443,9 +6770,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6488,6 +6812,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6500,6 +6827,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6539,6 +6869,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6572,6 +6908,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6623,9 +6962,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6662,6 +6998,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6686,6 +7025,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6734,6 +7076,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6758,6 +7103,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -7013,6 +7361,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -7049,6 +7400,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -7091,6 +7445,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -7184,15 +7544,6 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-msgstr[4] ""
-msgstr[5] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -7232,12 +7583,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -7247,9 +7592,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7376,12 +7718,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7403,13 +7751,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7529,10 +7877,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7541,9 +7889,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7553,6 +7916,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7580,12 +7946,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7595,6 +7976,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7607,6 +7994,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7838,6 +8228,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7886,6 +8279,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7910,6 +8306,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -8057,6 +8456,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -8072,6 +8474,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -8165,6 +8570,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -8174,9 +8582,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -8204,6 +8609,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8327,6 +8735,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8351,10 +8762,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8411,7 +8822,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8624,10 +9035,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8639,12 +9050,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8714,7 +9119,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8819,9 +9233,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8837,6 +9248,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8888,10 +9302,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8933,13 +9347,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8951,7 +9365,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8990,6 +9404,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -9008,6 +9425,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -9041,6 +9461,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -9056,6 +9479,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -9065,6 +9491,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -9143,18 +9572,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -9281,6 +9698,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9356,7 +9776,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9419,6 +9839,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9431,6 +9857,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9440,15 +9869,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9467,6 +9905,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9482,9 +9923,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9575,6 +10022,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9587,6 +10037,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9596,9 +10049,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9614,24 +10064,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9641,6 +10112,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9872,9 +10346,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9914,15 +10385,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -10100,6 +10571,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -10109,10 +10586,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -10163,6 +10640,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -10214,6 +10697,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -10232,6 +10718,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -10241,6 +10730,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10493,9 +10988,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10529,9 +11021,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10694,12 +11183,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10733,6 +11231,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10745,10 +11249,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10766,10 +11273,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10787,12 +11297,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10859,9 +11375,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -11063,6 +11576,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -11168,6 +11684,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -11177,6 +11696,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -11291,6 +11813,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -11300,6 +11825,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11450,6 +11978,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11459,7 +11990,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11468,6 +12002,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11480,7 +12020,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11498,13 +12041,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11516,6 +12059,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11525,6 +12071,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11534,10 +12083,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11630,10 +12179,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11666,6 +12215,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11699,6 +12251,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11723,18 +12281,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11789,6 +12365,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11828,6 +12428,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11864,18 +12470,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11888,6 +12503,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11951,6 +12569,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11963,6 +12584,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -12020,6 +12668,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -12065,6 +12716,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -12077,19 +12752,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -12215,6 +12893,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -12254,6 +12935,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12437,6 +13121,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12521,6 +13208,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12542,9 +13232,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12572,6 +13259,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12584,6 +13274,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12608,15 +13301,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12767,6 +13454,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12782,6 +13472,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12881,6 +13574,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12995,10 +13691,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -13025,6 +13721,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -13076,9 +13775,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -13088,9 +13784,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -13268,6 +13961,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -13277,9 +13973,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -13292,6 +13985,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -13325,6 +14021,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13373,9 +14072,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13436,7 +14144,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13454,6 +14162,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13475,9 +14186,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13499,19 +14207,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13535,6 +14246,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13595,6 +14327,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13613,6 +14351,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13649,6 +14390,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13715,6 +14459,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13724,6 +14525,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13733,21 +14540,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13808,6 +14633,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13922,6 +14750,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13931,6 +14762,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13943,9 +14777,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13955,9 +14786,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13991,6 +14819,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -14024,6 +14900,9 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -14090,6 +14969,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -14147,6 +15029,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -14165,18 +15050,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -14267,12 +15143,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -14297,6 +15179,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14432,6 +15317,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14456,6 +15344,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14570,9 +15461,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14639,6 +15536,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14648,9 +15554,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14720,7 +15623,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14765,7 +15668,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14780,6 +15683,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14810,7 +15716,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14858,6 +15764,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14876,6 +15785,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14897,6 +15809,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14984,6 +15902,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -15002,6 +15923,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -15032,22 +15956,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -15080,6 +16019,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -15167,6 +16109,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -15185,6 +16130,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -15227,9 +16175,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -15251,9 +16205,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -15275,9 +16226,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15386,6 +16334,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15446,15 +16397,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15467,30 +16427,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15506,6 +16490,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15542,6 +16529,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15635,6 +16628,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15710,6 +16706,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15800,6 +16799,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15836,6 +16838,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -16055,9 +17060,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -16103,9 +17105,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -16250,12 +17249,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -16286,6 +17279,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -16307,6 +17303,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -16337,6 +17336,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -16361,7 +17363,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -16370,6 +17372,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16484,9 +17489,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16652,6 +17654,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16697,6 +17702,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16847,6 +17855,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16940,12 +17951,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -17021,9 +18038,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -17042,30 +18056,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -17201,9 +18269,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -17213,6 +18278,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -17315,6 +18386,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -17324,9 +18398,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -17363,9 +18434,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17465,6 +18533,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17513,6 +18596,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17534,6 +18629,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17603,6 +18701,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17645,6 +18749,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17684,6 +18791,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17735,6 +18845,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17765,6 +18878,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17780,7 +18896,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17888,6 +19007,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17924,6 +19046,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17939,10 +19064,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17957,6 +19085,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17978,10 +19112,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -18059,6 +19190,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -18071,6 +19205,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -18221,6 +19361,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -18284,9 +19427,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -18323,9 +19463,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18455,9 +19592,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18515,6 +19658,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18545,10 +19691,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18677,9 +19823,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18692,9 +19844,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18704,24 +19853,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18857,6 +20006,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18938,6 +20090,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18989,12 +20144,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -19040,9 +20201,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -19115,6 +20285,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -19280,6 +20456,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -19316,6 +20495,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -19400,6 +20582,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -19418,7 +20603,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19457,15 +20642,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19490,12 +20675,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19520,6 +20714,18 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19706,6 +20912,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19742,9 +20951,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19841,6 +21056,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19880,6 +21098,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19928,6 +21149,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -20045,6 +21272,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -20210,7 +21440,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -20285,6 +21515,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -20411,6 +21644,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -20438,6 +21674,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20465,6 +21704,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20645,9 +21887,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20732,6 +21980,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20759,9 +22010,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -21017,6 +22265,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -21104,9 +22355,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -21143,9 +22391,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -21188,6 +22442,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -21362,6 +22619,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -21410,6 +22670,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21485,6 +22748,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21557,6 +22829,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21620,6 +22895,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21704,6 +22982,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21743,6 +23024,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21788,9 +23072,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21902,7 +23183,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21929,6 +23210,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21965,12 +23249,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21983,12 +23273,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -22007,7 +23309,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -22016,9 +23318,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -22073,9 +23372,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -22322,6 +23627,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -22394,6 +23702,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22514,6 +23828,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22571,15 +23888,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22595,9 +23906,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22616,6 +23924,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22727,6 +24038,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22784,10 +24098,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22796,6 +24110,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22835,6 +24152,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22844,9 +24164,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -23096,18 +24422,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -23126,6 +24446,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -23144,6 +24467,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -23168,9 +24494,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -23180,12 +24503,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -23195,12 +24524,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -23219,12 +24554,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -23249,7 +24590,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -23324,9 +24665,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23573,6 +24911,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23633,6 +24977,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23660,7 +25007,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23702,6 +25052,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23756,6 +25109,9 @@ msgstr[5] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23819,6 +25175,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23900,9 +25259,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23933,9 +25289,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -24044,6 +25397,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -24056,6 +25412,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -24077,7 +25436,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -24119,9 +25484,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -24161,12 +25523,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -24206,9 +25577,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -24242,9 +25610,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -24365,10 +25730,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -24377,10 +25745,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24497,6 +25865,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24524,6 +25895,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24539,6 +25913,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24617,6 +25994,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24665,6 +26045,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24680,7 +26063,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24773,6 +26156,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24800,6 +26186,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24818,6 +26207,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24851,7 +26246,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24887,7 +26285,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24980,9 +26378,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24992,12 +26399,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -25022,9 +26435,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -25076,6 +26495,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -25118,6 +26540,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -25307,6 +26732,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -25325,6 +26753,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -25343,6 +26774,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -25388,6 +26822,9 @@ msgstr[5] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -25397,6 +26834,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -25406,6 +26846,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25460,6 +26903,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -25475,7 +26921,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -25508,10 +26957,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25580,9 +27029,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25649,6 +27107,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25670,6 +27131,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25709,6 +27176,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25841,7 +27311,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -26021,9 +27491,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -26033,15 +27500,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -26054,6 +27512,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -26099,6 +27560,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -26138,9 +27602,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -26171,6 +27644,12 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -26225,6 +27704,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -26291,10 +27773,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -26357,6 +27839,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -26384,6 +27872,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -26411,6 +27902,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/da_DK/gitlab.po b/locale/da_DK/gitlab.po
index 65964e7b148..4a82e2d2927 100644
--- a/locale/da_DK/gitlab.po
+++ b/locale/da_DK/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: da\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:14\n"
+"PO-Revision-Date: 2020-06-08 15:15\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|Unknown"
+msgstr ""
+
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,14 +8991,14 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
-msgstr "Hver dag (klokken 4:00)"
+msgid "Every day (at %{time})"
+msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
-msgstr "Hver måned (d. 1. klokken 4:00)"
+msgid "Every month (Day %{day} at %{time})"
+msgstr ""
msgid "Every three months"
msgstr ""
@@ -8627,8 +9009,8 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
-msgstr "Hver uge (søndag klokken 4:00)"
+msgid "Every week (%{weekday} at %{time})"
+msgstr ""
msgid "Everyone"
msgstr ""
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] ""
msgstr[1] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/de/gitlab.po b/locale/de/gitlab.po
index d0782b75010..6f4e1d4a33d 100644
--- a/locale/de/gitlab.po
+++ b/locale/de/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: de\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:14\n"
+"PO-Revision-Date: 2020-06-08 15:16\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] "%d Kommentar"
msgstr[1] "%d Kommentare"
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] "%d Commit"
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] "%d Beitrag"
msgstr[1] "%d Beiträge"
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] "%d weiterer Kommentar"
msgstr[1] "%d weiterere Kommentare"
+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] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] "%d Projekt"
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr "%{commit_author_link} verfasste %{commit_timeago}"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} Kerne"
@@ -316,6 +354,9 @@ msgstr "%{filePath} gelöscht"
msgid "%{firstLabel} +%{labelCount} more"
msgstr "%{firstLabel} +%{labelCount} mehr"
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr "%{group_docs_link_start}Gruppen%{group_docs_link_end} ermöglichen dir d
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr "%{group_name} nutzt Accounts, die von einer Gruppe verwaltet werden. Du musst dir einen neuen GitLab-Account erstellen, welcher von %{group_name} verwaltet wird."
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr "%{icon}Sie sind dabei, %{usersTag} Personen zur Diskussion hinzuzufügen. Lassen Sie Vorsicht walten."
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr "%{label_for_message} nicht verfügbar"
@@ -370,12 +438,21 @@ msgstr "%{loadingIcon} Gestartet"
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr "%{lock_path} ist durch Gitlab-Benutzer(in) %{lock_user_id} gesperrt"
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr "%{mergeLength}/%{usersLength} können zusammenführen"
msgid "%{mrText}, this issue will be closed automatically."
msgstr "%{mrText}, dieses Ticket wird automatisch geschlossen werden."
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr "Avatar von %{name}"
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] "%{releases} Release"
msgstr[1] "%{releases} Releases"
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] "(%d geschlossen)"
msgstr[1] "(%d geschlossen)"
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr "(%{mrCount} zusammengeführt)"
@@ -782,6 +874,9 @@ msgstr "Bitte kontaktiere deine(n) GitLab-Administrator(in), wenn du denkst, das
msgid "8 hours"
msgstr "8 Stunden"
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr "<strong>%{group_name}</strong> Gruppenmitglieder"
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr "<strong>Löscht</strong> den Quellbranch"
@@ -821,6 +919,9 @@ msgstr "Ein 'Runner' ist ein Prozess, welcher ein Job ausführt. Du kannst so vi
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr "Eine .NET Core-Konsolenanwendungsvorlage, anpassbar für jedes .NET Core-Projekt"
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr "Eine GitBook-Seite, welche statt GitLab Netlify für CI/CD nutzt, aber trotzdem von all den anderen nützlichen GitLab-Funktionen profitiert."
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr "Ein Fork ist eine Kopie eines Projekts.<br />Wenn du ein Repository forkst, kannst du, ohne Auswirkungen auf das ursprüngliche Projekt, Änderungen vornehmen."
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr "Ein regulärer Ausdruck, der zum Suchen der Testabdeckung im Joblog verw
msgid "A secure token that identifies an external storage request."
msgstr "Ein sicheres Token, das die Anfrage eines externen Speichers identifiziert."
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr "Ein(e) Benutzer(in) mit Schreibzugriff auf den Quellbranch hat diese Opt
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr "API-Hilfe"
-
msgid "API Token"
msgstr "API Token"
@@ -968,9 +1072,6 @@ msgstr "Bedingungen akzeptieren"
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr "Akzeptierter MR"
-
msgid "Access Tokens"
msgstr "Zugangs-Token"
@@ -1061,12 +1162,6 @@ msgstr "Dein Token für statische Objekte wird verwendet, um dich zu authentifiz
msgid "AccessTokens|reset it"
msgstr "Zurücksetzen"
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,8 +1198,8 @@ msgstr "Service-Desk aktivieren"
msgid "Active"
msgstr "Aktiv"
-msgid "Active %{type} Tokens (%{token_length})"
-msgstr "Aktive %{type}-Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
+msgstr ""
msgid "Active Sessions"
msgstr "Aktive Sitzungen"
@@ -1112,6 +1207,9 @@ msgstr "Aktive Sitzungen"
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr "Aktivität"
@@ -1156,8 +1254,8 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr "Zoom-Besprechung hinzufügen"
-msgid "Add a %{type} token"
-msgstr "Fügen Sie ein %{type} Token hinzu"
+msgid "Add a %{type}"
+msgstr ""
msgid "Add a GPG key"
msgstr "GPG-Schlüssel hinzufügen"
@@ -1171,6 +1269,9 @@ msgstr "To-Do hinzufügen"
msgid "Add a bullet list"
msgstr "Aufzählungsliste hinzufügen"
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr "Füge einen allgemeinen Kommentar zu %{noteableDisplayName} hinzu."
@@ -1180,9 +1281,15 @@ msgstr "Trage einen allgemeinen Kommentar zu diesem %{noteable_name} bei."
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr "Füge zu deinem Wiki eine Startseite mit Informationen zu deinem GitLab-Project hinzu und GitLab wird sie hier anstatt dieser Meldung anzeigen."
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr "Einen Link hinzufügen"
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr "Eine nummerierte Liste hinzufügen"
@@ -1198,8 +1305,11 @@ msgstr "Füge zusätzlichen Text hinzu, der in jeglicher E-Mail-Kommunikation an
msgid "Add an SSH key"
msgstr "SSH-Schlüssel hinzufügen"
-msgid "Add an existing issue to the epic."
-msgstr "Füge dem Epic ein vorhandenes Ticket hinzu."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
+msgstr ""
msgid "Add an issue"
msgstr "Ticket hinzufügen"
@@ -1264,6 +1374,9 @@ msgstr "Reaktion hinzufügen"
msgid "Add request manually"
msgstr "Anfrage manuell hinzufügen"
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr "System-Hook hinzufügen"
@@ -1354,18 +1467,18 @@ msgstr "Fügt ein Zoom-Meeting hinzu"
msgid "Adds an issue to an epic."
msgstr "Fügt ein Ticket zu einem Epic hinzu."
-msgid "Adjust your filters/search criteria above."
-msgstr "Passe deine Filter/Suchkriterien oben an."
+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 ""
msgid "Admin Area"
msgstr "Adminbereich"
+msgid "Admin Note"
+msgstr ""
+
msgid "Admin Overview"
msgstr "Admin-Ãœbersicht"
-msgid "Admin Section"
-msgstr "Admin-Bereich"
-
msgid "Admin mode already enabled"
msgstr "Adminmodus bereits aktiviert"
@@ -1690,81 +1803,153 @@ msgstr "Nach dem erfolgreichen Ändern des Passwortes wirst du zum Anmeldebildsc
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr "Nach einer erfolgreichen Passwortaktualisierung wirst du zur Anmeldeseite weitergeleitet, wo du dich mit deinem neuen Passwort anmelden kannst."
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] "Alarm"
msgstr[1] "Alarme"
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
-msgstr ""
+msgstr "Status"
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
+msgstr ""
+
+msgid "AlertManagement|View issue"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr "Eine Anwendung namens %{link_to_client} fordert Zugriff auf dein GitLab-Konto an."
+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 "Bei einem leeren GitLab-Benutzerfeld wird der vollständigen Namen des FogBugz-Benutzers/-Benutzerin (z. B. \"Von John Smith\") in die Beschreibung aller Tickets und Kommentare eingefügt. Außerdem werden diese Tickets und Kommentare auch mit dem/der Projektersteller(in) assoziiert und/oder ihm/ihr zugewiesen."
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr "Beim Laden der Diagrammdaten ist ein Fehler aufgetreten"
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr "Beim Laden der Commit-Signaturen ist ein Fehler aufgetreten"
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr "Beim Speichern der Genehmigungseinstellungen ist ein Fehler aufgetreten"
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr "Beim Abonnieren von Benachrichtigungen ist ein Fehler aufgetreten."
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr "Ein Ticket kann ein Fehler, ein To-do oder eine Feature-Anfrage sein, das in einem Projekt diskutiert werden muss. Außerdem sind Tickets durchsuchbar und filterbar."
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr "Beim Überprüfen der Projektumgebung ist ein unerwarteter Fehler aufgetreten."
@@ -2256,6 +2453,9 @@ msgstr "Beim Starten des Web-Terminals ist ein unerwarteter Fehler aufgetreten."
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr "Beim Beenden des Web-Terminals ist ein unerwarteter Fehler aufgetreten."
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr "Analysen"
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr "Irgendein"
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr "Beliebiges Label"
-
-msgid "Any Milestone"
-msgstr "Jeder Meilenstein"
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr "Alle verschlüsselten Tokens"
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr "Jeder Namensraum"
@@ -2370,6 +2573,9 @@ msgstr "Label hinzufügen"
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr "Vorschlag anwenden"
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr "z.B. QS, Sicherheit, etc."
-msgid "Approvals"
-msgstr "Zustimmungen"
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr "Genehmigen"
@@ -2453,12 +2653,18 @@ msgstr "Einen Merge-Request genehmigen"
msgid "Approve the current merge request."
msgstr "Aktuellen Merge-Request genehmigen."
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr "Der aktuelle Merge-Request wurde genehmigt."
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr "Bist du sicher, dass du %{group_name} wirklich entfernen willst?"
msgid "Are you sure you want to remove the attachment?"
msgstr "Möchtest du den Anhang wirklich entfernen?"
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr "Bist du sicher, dass du diese Identität entfernen willst?"
@@ -2579,7 +2788,7 @@ msgstr "Möchtest du wirklich das SCIM-Token zurücksetzen? Die SCIM-Bereitstell
msgid "Are you sure you want to reset the health check token?"
msgstr "Bist du sicher, dass du den Health-Check-Token zurücksetzen willst?"
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr "Zugewiesene Tickets"
msgid "Assigned Merge Requests"
msgstr "Zugewiesene Merge-Requests"
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr "Mir zugewiesen"
@@ -2758,7 +2970,7 @@ msgid "AuditEvents|Target"
msgstr ""
msgid "AuditLogs|(removed)"
-msgstr ""
+msgstr "(entfernt)"
msgid "AuditLogs|Action"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr "Aug"
@@ -2835,6 +3065,9 @@ msgstr "Autorisieren"
msgid "Authorize %{link_to_client} to use your account?"
msgstr "Autorisierst du %{link_to_client} dein Konto zu verwenden?"
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr "%{new_chat_name} autorisiert"
@@ -2856,9 +3089,6 @@ msgstr "Auto-DevOps aktiviert"
msgid "Auto DevOps, runners and job artifacts"
msgstr "Auto-DevOps, Runners und Jobartefakte"
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr "Auto DevOps kann Anwendungen basierend auf einer vordefinierten Konfigur
msgid "AutoDevOps|Auto DevOps documentation"
msgstr "Auto-DevOps-Dokumentation"
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr "Aktiviere in den Einstellungen"
@@ -2887,7 +3120,7 @@ msgid "AutoDevOps|Learn more in the %{link_to_documentation}"
msgstr "Erfahre mehr in der %{link_to_documentation}"
msgid "AutoDevOps|The Auto DevOps pipeline has been enabled and will be used if no alternative CI configuration file is found. %{more_information_link}"
-msgstr "Die Auto-DevOps-Pipeline wurde aktiviert und wir verwendet, falls keine alternative CI-Konfigurationsdatei gefunden wurde. %{more_information_link}"
+msgstr ""
msgid "Autocomplete"
msgstr "Autovervollständigung"
@@ -2907,6 +3140,9 @@ msgstr "Automatische Zertifikatsverwaltung mit %{lets_encrypt_link_start}Let's E
msgid "Automatic certificate management using Let's Encrypt"
msgstr "Automatische Zertifikatsverwaltung mit Let's Encrypt"
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr "Automatisch als interne(r) Standardbenutzer(in) gekennzeichnet"
@@ -2922,6 +3158,9 @@ msgstr "Notiz"
msgid "Available"
msgstr "Verfügbar"
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr "Verfügbare Gruppen-Runner: %{runners}"
@@ -3388,7 +3627,7 @@ msgid "Built-in"
msgstr "Integriert"
msgid "Bulk request concurrency"
-msgstr ""
+msgstr "Parallelität von Massenanfragen"
msgid "Burndown chart"
msgstr ""
@@ -3399,17 +3638,17 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr "Offene Tickets"
+msgid "Burnup chart"
+msgstr ""
+
msgid "Business"
msgstr "Business"
msgid "Business metrics (Custom)"
msgstr "Business-Metriken (benutzerdefiniert)"
-msgid "Buy EE"
-msgstr "EE kaufen"
-
-msgid "Buy GitLab Enterprise Edition"
-msgstr "Kaufe die GitLab Enterprise Edition"
+msgid "Buy License"
+msgstr ""
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -3432,8 +3671,8 @@ msgstr "CHANGELOG"
msgid "CI / CD"
msgstr "CI / CD"
-msgid "CI / CD Charts"
-msgstr "CI/CD-Diagramme"
+msgid "CI / CD Analytics"
+msgstr ""
msgid "CI / CD Settings"
msgstr "CI/CD-Einstellungen"
@@ -3441,6 +3680,9 @@ msgstr "CI/CD-Einstellungen"
msgid "CI Lint"
msgstr "CI Lint"
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr "CI-Variablen"
@@ -3459,6 +3701,9 @@ msgstr "CI/CD für externes Repo"
msgid "CI/CD settings"
msgstr "CI/CD-Einstellungen"
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr "Auto-DevOps"
@@ -3489,9 +3734,6 @@ msgstr "Die Auto-DevOps-Pipeline wird ausgeführt, wenn keine alternative CI-Kon
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr "Gruppe aktiviert"
@@ -3519,6 +3761,12 @@ msgstr "Kann manuell bereitgestellt werden für"
msgid "Can override approvers and approvals required per merge request"
msgstr "Kann erforderliche Genehmigungsberechtigte und Genehmigungen pro Merge-Request überschreiben"
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr "HEAD-Commit kann für diesen Branch nicht gefunden werden"
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr "Kapazitätsschwelle"
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr "Zertifikat"
@@ -3645,6 +3896,12 @@ msgstr "Pfad ändern"
msgid "Change permissions"
msgstr "Berechtigungen ändern"
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr "Vorlage ändern"
@@ -3687,6 +3944,9 @@ msgstr "Änderungen"
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr "Änderungen werden angezeigt, als ob die <b>Quell</b>-Revision in die <b>Ziel</b>-Revision gemerged wurde."
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr "Das Ändern eines Release-Tags wird nur über die Release-API unterstüt
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr "%{startDate} - %{endDate}"
msgid "Checkout|(x%{numberOfUsers})"
msgstr "(x%{numberOfUsers})"
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -3904,7 +4158,7 @@ msgid "Checkout|Select"
msgstr ""
msgid "Checkout|State"
-msgstr ""
+msgstr "Status"
msgid "Checkout|Street address"
msgstr ""
@@ -4012,7 +4266,7 @@ msgid "Choose which shards you wish to synchronize to this secondary node"
msgstr ""
msgid "Choose your framework"
-msgstr ""
+msgstr "Wähle dein Framework"
msgid "CiStatusLabel|canceled"
msgstr "abgebrochen"
@@ -4167,9 +4421,6 @@ msgstr "Validierung fehlgeschlagen"
msgid "Class"
msgstr "Klasse"
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr "Leeren"
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr "Eingabe löschen"
@@ -4194,6 +4448,9 @@ msgstr "Suche löschen"
msgid "Clear search input"
msgstr "Suchfelder löschen"
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr "Klicke auf die Schaltfläche <strong>Keine auswählen</strong> auf der r
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr "Klicke auf die Schaltfläche unten um den Installationsprozess zu starten indem du auf die Kubernetes-Seite gehst"
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr "Zum Erweitern klicken."
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr "Schließen"
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr "Schließe %{tabname}"
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr "Kubernetes-Clusternamen kopieren"
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr "Aktiviere diese Einstellung, wenn rollenbasierte Zugriffskontrolle (RBAC
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4597,7 +4857,7 @@ msgid "ClusterIntegration|Fetching zones"
msgstr "Rufe Zonen ab"
msgid "ClusterIntegration|Fluentd"
-msgstr ""
+msgstr "Fluentd"
msgid "ClusterIntegration|Fluentd is an open source data collector, which lets you unify the data collection and consumption for a better use and understanding of data. It requires at least one of the following logs to be successfully installed."
msgstr ""
@@ -4638,12 +4898,12 @@ msgstr "Cluster gruppieren"
msgid "ClusterIntegration|Helm Tiller"
msgstr "Helm Tiller"
+msgid "ClusterIntegration|Helm release failed to install"
+msgstr ""
+
msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr "Helm optimiert die Installation und Verwaltung von Kubernetes-Anwendungen. Tiller läuft innerhalb deines Kubernetes-Clusters und verwaltet Versionen deiner Charts."
-msgid "ClusterIntegration|Hide"
-msgstr "Ausblenden"
-
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
msgstr "Wenn du mehrere Cluster einrichtest und Auto-DevOps verwendest, lies zuerst %{help_link_start}dies%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr "Keine VPCs gefunden"
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -4930,7 +5196,7 @@ msgid "ClusterIntegration|Search VPCs"
msgstr "VPCs suchen"
msgid "ClusterIntegration|Search domains"
-msgstr ""
+msgstr "Suchdomains"
msgid "ClusterIntegration|Search instance types"
msgstr ""
@@ -4990,7 +5256,7 @@ msgid "ClusterIntegration|Select a zone to choose a network"
msgstr "Wähle eine Zone aus, um das Netzwerk auszuwählen"
msgid "ClusterIntegration|Select existing domain or use new"
-msgstr ""
+msgstr "Existierende Domain auswählen oder neue verwenden"
msgid "ClusterIntegration|Select machine type"
msgstr "Wähle den Maschinentyp aus"
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr "Zeige"
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr "Auf unserer Seite ist etwas schief gelaufen."
@@ -5115,6 +5378,9 @@ msgstr "Kubernetes-Cluster umschalten"
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr "%{appTitle} deinstallieren"
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr "Du musst zuerst Helm Tiller installieren, bevor du die Anwendung unten installierst"
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr "Dein Account benötigt eine %{link_to_kubernetes_engine}"
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr "Genehmigungsberechtigte ausblenden"
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr "Seitenleiste einklappen"
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr "Befehl"
@@ -5316,6 +5603,9 @@ msgstr "Position des Kommentarformulars"
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5448,19 +5738,19 @@ msgid "Compliance framework (optional)"
msgstr ""
msgid "ComplianceFramework|GDPR"
-msgstr ""
+msgstr "DSGVO"
msgid "ComplianceFramework|GDPR - General Data Protection Regulation"
msgstr ""
msgid "ComplianceFramework|HIPAA"
-msgstr ""
+msgstr "HIPAA"
msgid "ComplianceFramework|HIPAA - Health Insurance Portability and Accountability Act"
msgstr ""
msgid "ComplianceFramework|PCI-DSS"
-msgstr ""
+msgstr "PCI-DSS"
msgid "ComplianceFramework|PCI-DSS - Payment Card Industry-Data Security Standard"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr "Let's Encrypt konfigurieren"
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr "Tracing konfigurieren"
@@ -5537,9 +5827,6 @@ msgstr "Konfiguriere die Speicherpfadeinstellungen."
msgid "Configure the %{link} integration."
msgstr "Die %{link}-Integration konfigurieren."
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr "Konfiguriere, wie ein(e) Benutzer(in) ein neues Konto erstellt."
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr "Zeitüberschreitung der Verbindung"
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr "Kontaktiere eine/n Eigentümer(in) der Gruppe %{namespace_name}, um den Tarif anzuheben."
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr "Eigentümer(in) %{link_start}%{owner_name}%{link_end} kontaktieren, um den Tarif anzuheben."
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
-msgstr ""
-
msgid "ContainerRegistry|Expiration interval:"
msgstr "Ablaufintervall:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr "Ablaufrichtlinie erfolgreich gespeichert."
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr "Tag"
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr "Beitrag"
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr "Kopiere %{protocol} clone-URL"
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr "Link kopieren"
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr "Erstellen"
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr "Neues Ticket erstellen"
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr "Erstelle einen persönlichen Zugriffstoken in deinem Konto um mittels %{
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr "Gruppen-Label erstellen"
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr "Erstelle Listen anhand von Labels. Tickets mit diesem Label werden in dieser Liste angezeigt."
@@ -6208,6 +6499,9 @@ msgstr "Merge-Request und Branch erstellen"
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6239,7 +6533,7 @@ msgid "Create requirement"
msgstr ""
msgid "Create snippet"
-msgstr ""
+msgstr "Snippet erstellen"
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr "Erstelle deine erste Seite"
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6263,7 +6563,7 @@ msgid "Created"
msgstr "Erstellt"
msgid "Created %{timestamp}"
-msgstr ""
+msgstr "Erstellt %{timestamp}"
msgid "Created At"
msgstr "Erstellt am"
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr "Von mir erstellt"
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr "Cron-Zeitzone"
-msgid "Cron syntax"
-msgstr "Cron-Syntax"
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr "Einstellungen"
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr "Farben anpassen"
@@ -6466,6 +6775,9 @@ msgstr "Passe deine Pipeline-Konfiguration an und zeige deinen Pipeline-Status u
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr "Standardklassifikationslabel"
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr "Standard: Ordne eine FogBugz-Konto-ID einem vollständigen Namen zu"
msgid "Define a custom pattern with cron syntax"
msgstr "Erstelle ein benutzerdefiniertes Muster mittels Cron-Syntax"
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr "Kommentar entfernen"
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] "%d weitere Sicherheitslücke nicht angezeigt"
msgstr[1] "%d weitere Sicherheitslücken nicht angezeigt"
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -6952,13 +7262,13 @@ msgid "Dependency List has no entries"
msgstr ""
msgid "Dependency Proxy"
-msgstr ""
+msgstr "Abhängigkeitsproxy"
msgid "Dependency Scanning"
msgstr ""
msgid "Dependency proxy"
-msgstr ""
+msgstr "Abhängigkeitsproxy"
msgid "Dependency proxy URL"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr "Aktive Bereitstellungstoken (%{active_tokens})"
msgid "DeployTokens|Add a deploy token"
msgstr "Bereitstellungstoken hinzufügen"
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr "Ermöglicht schreibgeschützten Zugriff auf die Registry-Images"
msgid "DeployTokens|Allows read-only access to the repository"
msgstr "Ermöglicht schreibgeschützten Zugriff auf das Repository"
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr "Bereitstellungstoken"
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr "Verfällt"
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr "Designs"
msgid "Destroy"
msgstr "Löschen"
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr "Details"
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr "Quellcode herunterladen"
@@ -7586,6 +7950,9 @@ msgstr "Negativ bewertet"
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr "Fälligkeitsdatum"
@@ -7733,9 +8100,12 @@ msgstr "E-Mail"
msgid "Email address"
msgstr ""
-msgid "Email display name"
+msgid "Email could not be sent"
msgstr ""
+msgid "Email display name"
+msgstr "E-Mail-Anzeigename"
+
msgid "Email not verified. Please verify your email in Salesforce."
msgstr ""
@@ -7743,9 +8113,12 @@ msgid "Email patch"
msgstr "E-Mail-Patch"
msgid "Email restrictions"
-msgstr ""
+msgstr "E-Mail-Beschränkungen"
msgid "Email restrictions for sign-ups"
+msgstr "E-Mail-Beschränkungen fürs Registrieren"
+
+msgid "Email sent"
msgstr ""
msgid "Email the pipelines status to a list of recipients."
@@ -7841,6 +8214,9 @@ msgstr "SAML-Authentifizierung für diese Gruppe aktivieren"
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr "Aktiviere und konfiguriere InfluxDB-Messwerte."
-
msgid "Enable and configure Prometheus metrics."
msgstr "Aktiviere und konfiguriere Prometheus-Messwerte."
@@ -7880,6 +8253,9 @@ msgstr "Gruppen-Runner aktivieren"
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,11 +8379,14 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr "Neuen AWS Secret Access Key eingeben"
msgid "Enter number of issues"
-msgstr ""
+msgstr "Anzahl der Tickets eingeben"
msgid "Enter one or more user ID separated by commas"
msgstr ""
@@ -8027,17 +8406,17 @@ msgstr "Gib die Beschreibung des Merge-Requests ein"
msgid "Enter the merge request title"
msgstr "Gib den Titel des Merge-Requests ein"
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
msgstr ""
msgid "Environment does not have deployments"
-msgstr ""
+msgstr "Umgebung hat keine Bereitstellungen"
msgid "Environment scope"
msgstr ""
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8136,7 +8515,7 @@ msgid "Environments|Currently showing %{fetched} results."
msgstr ""
msgid "Environments|Currently showing all results."
-msgstr ""
+msgstr "Derzeit werden alle Ergebnisse angezeigt."
msgid "Environments|Delete"
msgstr ""
@@ -8300,11 +8679,11 @@ msgstr "Mit Epics kannst du deine Projekte effizienter und mit weniger Aufwand v
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
-msgstr "Ein vorhandenes Epic als untergeordnetes Epic hinzufügen."
+msgid "Epics|Add an existing epic"
+msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
msgstr ""
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr "Erstellen Sie ein Epic in dieser Gruppe und fügen Sie es als untergeordnetes Epic hinzu."
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr "Wie kann ich dieses Problem lösen?"
@@ -8390,7 +8763,16 @@ msgstr "Fehler beim Erstellen des Epics"
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr "Fehler beim Rendern der Abfrage"
-
msgid "Error saving label update."
msgstr "Fehler beim Speichern der Label-Aktualisierung."
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8562,14 +8944,14 @@ msgid "Errors"
msgstr ""
msgid "Errors:"
+msgstr "Fehler:"
+
+msgid "Estimate"
msgstr ""
msgid "Estimated"
msgstr "Geschätzt"
-msgid "Event Actions"
-msgstr "Ereignisaktionen"
-
msgid "EventFilterBy|Filter by all"
msgstr "Filtere alle"
@@ -8609,14 +8991,14 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
-msgstr "Täglich (um 4:00 Uhr)"
+msgid "Every day (at %{time})"
+msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
-msgstr "Monatlich (am Ersten um 4:00 Uhr)"
+msgid "Every month (Day %{day} at %{time})"
+msgstr ""
msgid "Every three months"
msgstr ""
@@ -8627,8 +9009,8 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
-msgstr "Wöchentlich (Sonntags um 4:00 Uhr)"
+msgid "Every week (%{weekday} at %{time})"
+msgstr ""
msgid "Everyone"
msgstr ""
@@ -8666,6 +9048,9 @@ msgstr "Beweissammlung"
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr "Menüleiste ausklappen"
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr "Ablaufzeitpunkt"
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8769,7 +9166,7 @@ msgid "Export as CSV"
msgstr ""
msgid "Export group"
-msgstr ""
+msgstr "Gruppe exportieren"
msgid "Export issues"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr "Klassifizierungslabel"
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr "Wenn kein Klassifizierungslabel gesetzt ist, wird das Standardlabel `%{default_label}` benutzt."
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr "Beschreibung"
msgid "FeatureFlags|Edit Feature Flag"
msgstr "Feature-Flag bearbeiten"
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr "Feature-Flag"
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr "Instanz-ID"
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr "Neu"
msgid "FeatureFlags|New Feature Flag"
msgstr "Neues Feature-Flag"
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9207,7 +9622,7 @@ msgid "FeatureFlag|Delete strategy"
msgstr ""
msgid "FeatureFlag|Percentage"
-msgstr ""
+msgstr "Prozentsatz"
msgid "FeatureFlag|Type"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr "Dateivorlagen"
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr "Dateien"
@@ -9290,22 +9708,43 @@ msgstr "Fülle die Felder unten aus, schalte <strong>%{enable_label}</strong> an
msgid "Filter"
msgstr "Filter"
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr "Filtern nach %{issuable_type}, die derzeit geschlossen sind."
msgid "Filter by %{issuable_type} that are currently opened."
msgstr "Filtern nach %{issuable_type}, die derzeit offen sind."
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr "Filter nach Commit-Nachricht"
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
+msgstr "Nach Name filtern"
+
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
msgstr ""
msgid "Filter by status"
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr "Von der Ticketbeschreibung bis zur Bereitstellung"
msgid "From merge request merge until deploy to production"
msgstr "Vom Umsetzen des Merge Request bis zur Bereitstellung auf dem Produktivsystem"
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr "Installiere den Runner aus der Anwendungsliste in der Kubernetes-Cluster Detailansicht"
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr "Geo"
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr "Geo-Knoten"
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9771,9 +10210,15 @@ msgid "GeoNodes|You have configured Geo nodes using an insecure HTTP connection.
msgstr "Du hast Geo-Knoten mit einer unsicheren HTTP-Verbindung konfiguriert. Wir empfehlen die Verwendung von HTTPS."
msgid "GeoNodes|primary node"
-msgstr ""
+msgstr "Primärknoten"
msgid "GeoNodes|secondary nodes"
+msgstr "Sekundärknoten"
+
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
msgstr ""
msgid "Geo|%{name} is scheduled for forced re-download"
@@ -9785,10 +10230,10 @@ msgstr "%{name} ist für die erneute Synchronisierung vorgemerkt"
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
-msgstr "Alle"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr "Nie"
msgid "Geo|Next sync scheduled at"
msgstr "Nächste Synchronisierung geplant um"
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr "Noch nicht synchronisiert"
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr "Status"
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr "Tracking-Eintrag für Projekt (%{project_id}) wurde erfolgreich entfernt
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr "Tracking-Eintrag für Upload (%{type}/%{id}) wurde erfolgreich entfernt."
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr "Unbekannter Status"
@@ -10169,9 +10632,6 @@ msgstr "Gitea-Host-URL"
msgid "Gitea Import"
msgstr "Gitea-Import"
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr "Gehe zu"
-
msgid "Go to %{link_to_google_takeout}."
msgstr "Gehe zu %{link_to_google_takeout}."
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr "Gruppe"
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10386,7 +10852,7 @@ msgid "Group Git LFS status:"
msgstr "Gruppen-Git-LFS-Status:"
msgid "Group Hooks"
-msgstr ""
+msgstr "Gruppen-Hooks"
msgid "Group ID"
msgstr "Gruppen-ID"
@@ -10409,6 +10875,12 @@ msgstr "Gruppen-URL"
msgid "Group avatar"
msgstr "Gruppenavatar"
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr "Gruppenbeschreibung"
@@ -10419,12 +10891,15 @@ msgid "Group details"
msgstr "Gruppendetails"
msgid "Group export could not be started."
+msgstr "Gruppenexport konnte nicht gestartet werden."
+
+msgid "Group export error"
msgstr ""
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr "Gruppenbetreuer können Gruppen-Runner unter %{link} registrieren"
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr "Gruppenname"
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr "Die Pipeline-Minuten der Gruppe wurden erfolgreich zurückgesetzt."
-msgid "Group requires separate account"
+msgid "Group project URLs are prefixed with the group namespace"
msgstr ""
+msgid "Group requires separate account"
+msgstr "Gruppe benötigt ein separates Konto"
+
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10479,13 +10963,13 @@ msgid "Group: %{name}"
msgstr ""
msgid "GroupActivityMetrics|New Members created"
-msgstr ""
+msgstr "Neue Mitglieder erstellt"
msgid "GroupActivyMetrics|Issues created"
msgstr ""
msgid "GroupActivyMetrics|Merge Requests created"
-msgstr ""
+msgstr "Merge-Requests erstellt"
msgid "GroupActivyMetrics|Recent activity (last 90 days)"
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10575,10 +11056,10 @@ msgid "GroupSAML|NameID Format"
msgstr ""
msgid "GroupSAML|Prohibit outer forks"
-msgstr ""
+msgstr "Äußere Forks verbieten"
msgid "GroupSAML|Prohibit outer forks for this group."
-msgstr ""
+msgstr "Äußere Forks für diese Gruppe verbieten"
msgid "GroupSAML|SAML Response Output"
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr "wenn bei der übergeordneten Gruppe „Freigeben mit Gruppensperre“ aktiviert ist, kann nur der/die Eigentümer(in) der übergeordneten Gruppe dies deaktivieren"
@@ -10755,7 +11239,7 @@ msgid "Groups (%{count})"
msgstr ""
msgid "Groups (%{groups})"
-msgstr ""
+msgstr "Gruppen (%{groups})"
msgid "Groups can also be nested by creating %{subgroup_docs_link_start}subgroups%{subgroup_docs_link_end}."
msgstr "Gruppen können durch %{subgroup_docs_link_start}Untergruppen%{subgroup_docs_link_end} verschachtelt werden."
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr "Lasse deine Nutzer an diese Adresse mailen"
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr "Kopfzeilennachricht"
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr "Verlauf"
msgid "History of authentications"
msgstr "Verlauf der Authentifizierungen"
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr "Wenn diese Option aktiviert ist, wird der Zugriff auf Projekte mit einem
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr "Wenn du GitHub verwendest, siehst du den Pipeline-Status für deine Commits und Pull-Anfragen, auf GitHub. %{more_info_link}"
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,15 +11677,15 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
+msgid "Impersonation Tokens"
+msgstr ""
+
msgid "Impersonation has been disabled"
msgstr ""
msgid "Import"
msgstr "Importieren"
-msgid "Import %{status}"
-msgstr ""
-
msgid "Import CSV"
msgstr ""
@@ -11184,6 +11695,9 @@ msgstr "Importiere Projekte von Gitea"
msgid "Import all compatible projects"
msgstr "Importiere alle kompatiblen Projekte"
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr "Alle Projekte importieren"
@@ -11193,19 +11707,22 @@ msgstr "Alle Repositories importieren"
msgid "Import an exported GitLab project"
msgstr "Importiere ein exportiertes GitLab-Projekt"
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
msgid "Import from Jira"
-msgstr ""
+msgstr "Aus Jira importieren"
msgid "Import in progress"
msgstr "Import wird durchgeführt"
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,12 +11815,12 @@ msgstr "Verbessere Ticketboards mit der GitLab Enterprise Edition."
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr "Verbessere Merge-Requests und den Kundensupport mit GitLab Enterprise Edition."
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
-msgstr "Verbessere das Ticketmanagement mit Ticketgewichtung und der Gitlab Enterprise Edition."
-
msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr "Verbessere die Suche mit der „Erweiterten globalen Suche“ und GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
+msgstr ""
+
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
msgstr "Um die Analyse auf Instanzebene zu aktivieren, bitte eine(n) Administrator(in), den %{usage_ping_link_start}Nutzungsbericht%{usage_ping_link_end} zu aktivieren."
@@ -11317,7 +11834,7 @@ msgid "In order to tailor your experience with GitLab we<br>would like to know a
msgstr ""
msgid "In progress"
-msgstr ""
+msgstr "In Bearbeitung"
msgid "In the next step, you'll be able to select the projects you want to import."
msgstr "Im nächsten Schritt kannst du die Projekte auswählen, die du importieren möchtest."
@@ -11334,6 +11851,9 @@ msgstr "Füge Nutzungsbedingungen und eine Datenschutzrichtlinie hinzu, die alle
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr "Inkompatibles Projekt"
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr "Gib die Host-Schlüssel manuell ein"
msgid "Input your repository URL"
msgstr "Gib deine Repository-URL ein"
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr "Integrationen"
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr "Interessierte können auch etwas beitragen wenn sie möchten, indem sie Commits pushen."
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr "Einladen"
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr "Board"
@@ -11684,6 +12300,9 @@ msgstr "Geschlossene Tickets"
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr "Jaeger-URL"
@@ -11741,19 +12384,22 @@ msgstr "Jan"
msgid "January"
msgstr "Januar"
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr "Die Artefakte wurden entfernt"
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr "Juni"
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
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 ""
@@ -12181,6 +12836,9 @@ msgstr "Mehr über den Schwachstellen-Check erfahren"
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr "Erfahre mehr in den"
@@ -12232,6 +12887,9 @@ msgstr "Verlasse das Projekt"
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr "Belasse die Optionen \"Dateityp\" und \"Ãœbergabemethode\" auf ihren Standardwerten."
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr "Lizenz"
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12450,7 +13111,7 @@ msgid "Link title"
msgstr ""
msgid "Link title is required"
-msgstr ""
+msgstr "Ein Link-Titel ist erforderlich."
msgid "Linked emails (%{email_count})"
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr "Lade..."
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr "Lokalisierung"
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr "Stelle sicher, dass du mit dem Konto angemeldet bist, welches Besitzer der zu importierenden Projekte ist."
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr "Gruppenlabels verwalten"
msgid "Manage labels"
msgstr "Label verwalten"
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr "Projektlabel verwalten"
@@ -12675,7 +13342,7 @@ msgid "Manage your license"
msgstr ""
msgid "Managed Account"
-msgstr ""
+msgstr "Verwaltetes Konto"
msgid "Manifest"
msgstr "Manifest"
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr "Markdown aktiviert"
@@ -12861,7 +13522,7 @@ msgid "Maximum number of projects."
msgstr ""
msgid "Maximum page reached"
-msgstr ""
+msgstr "Maximale Seite erreicht"
msgid "Maximum push size (MB)"
msgstr ""
@@ -12870,7 +13531,7 @@ msgid "Maximum size limit for a single commit."
msgstr ""
msgid "Maximum size limit for each repository."
-msgstr ""
+msgstr "Maximale Größenbeschränkung für jedes Repository."
msgid "Maximum size of Elasticsearch bulk indexing requests."
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr "Speicherlimit beim Rendern der Vorlage überschritten"
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr "Merge-Request"
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr "Merge-Requests"
@@ -12965,6 +13629,9 @@ msgstr "Merge-Request"
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr "Merge-Request-Genehmigungen"
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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."
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr "Merged"
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr "Nachrichten"
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,21 +13815,24 @@ msgstr "Metriken"
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr "Metriken - Influx"
-
msgid "Metrics - Prometheus"
msgstr "Metriken - Prometheus"
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
-msgstr "Metriken und Profiling"
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is valid."
msgstr ""
+msgid "Metrics and profiling"
+msgstr "Metriken und Profiling"
+
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13217,7 +13917,7 @@ msgid "Metrics|For grouping similar metrics"
msgstr "Zum Gruppieren ähnlicher Metriken"
msgid "Metrics|Go back (Esc)"
-msgstr ""
+msgstr "Zurück (Esc)"
msgid "Metrics|Invalid time range, please verify."
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr "Legendenbeschriftung (optional)"
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,9 +13955,12 @@ msgstr "Prometheus Query-Dokumentation"
msgid "Metrics|Refresh dashboard"
msgstr ""
-msgid "Metrics|There was an error creating the dashboard."
+msgid "Metrics|Star dashboard"
msgstr ""
+msgid "Metrics|There was an error creating the dashboard."
+msgstr "Beim Erstellen des Dashboards ist ein Fehler aufgetreten."
+
msgid "Metrics|There was an error creating the dashboard. %{error}"
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr "Unerwartete Bereitstellungs-Datenantwort vom Prometheus-Endpunkt"
msgid "Metrics|Unit label"
msgstr "Bezeichnung der Einheit"
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr "Wird als Titel für das Diagramm verwendet"
@@ -13347,6 +14059,63 @@ 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 "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr "Meilensteine"
@@ -13356,6 +14125,12 @@ msgstr "Du bist dabei, den Meilenstein %{milestoneTitle} endgültig zu löschen
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr "Du bist dabei, den Meilenstein %{milestoneTitle} endgültig zu löschen. Dieser Meilenstein wird zur Zeit von keinem Ticket und keinem Merge-Request verwendet."
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr "Meilenstein löschen"
@@ -13365,21 +14140,39 @@ msgstr "Meilenstein %{milestoneTitle} löschen?"
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr "Das Löschen des Meilenstein %{milestoneTitle} ist fehlgeschlagen"
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr "Meilenstein %{milestoneTitle} wurde nicht gefunden"
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr "%{milestoneTitle} zum Gruppenmeilenstein hochstufen?"
msgid "Milestones|Promote Milestone"
msgstr "Meilenstein hochstufen"
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr "Diese Aktion kann nicht rückgängig gemacht werden."
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr "Abbrechen"
@@ -13447,7 +14243,7 @@ msgid "Modal|Close"
msgstr "Schließen"
msgid "Modified"
-msgstr ""
+msgstr "Geändert"
msgid "Modified in this version"
msgstr "In dieser Version geändert"
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr "Mehrere Ticket-Boards"
@@ -13563,9 +14362,12 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
-msgid "My company or team"
+msgid "My Awesome Group"
msgstr ""
+msgid "My company or team"
+msgstr "Meine Firma oder Team"
+
msgid "My-Reaction"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr "Name"
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr "Neues Label benennen"
@@ -13585,10 +14384,7 @@ msgid "Name:"
msgstr "Name:"
msgid "Namespace is empty"
-msgstr ""
-
-msgid "Namespace: %{namespace}"
-msgstr "Namensraum: %{namespace}"
+msgstr "Namensraum ist leer"
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr "Netzwerk"
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr "Niemals"
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] "Neues Ticket"
msgstr[1] "Neue Tickets"
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr "Neues Ticket"
msgid "New issue title"
msgstr "Neuer Ticket-Titel"
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr "Neues Label"
@@ -13740,7 +14590,7 @@ msgid "New release"
msgstr ""
msgid "New requirement"
-msgstr ""
+msgstr "Neue Anforderung"
msgid "New runners registration token has been generated!"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr "Kein Label"
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13881,7 +14725,7 @@ msgid "No file chosen"
msgstr "Keine Datei ausgewählt"
msgid "No file hooks found."
-msgstr ""
+msgstr "Keine Datei-Hooks gefunden."
msgid "No file selected"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr "Keine Dateien gefunden."
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr "Kein Jobprotokoll"
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr "Keine Tags mit einem solchen Namen oder einer solchen Beschreibung"
@@ -13925,6 +14775,9 @@ msgstr "Keine Merge-Requests gefunden"
msgid "No messages were logged"
msgstr "Es wurden Nachrichten protokolliert"
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr "Bist du sicher, dass du die Erstellung dieses Kommentars abbrechen möch
msgid "Notes|Collapse replies"
msgstr "Antworten reduzieren"
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr "Alle Aktivitäten anzeigen"
@@ -14198,9 +15057,15 @@ msgstr "Nov"
msgid "November"
msgstr "November"
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr "Nur Projektmitglieder können kommentieren."
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,8 +15260,8 @@ msgstr "Offen: %{open} • Geschlossen: %{closed}"
msgid "Opened"
msgstr "Geöffnet"
-msgid "Opened MR"
-msgstr "Geöffneter MR"
+msgid "Opened MRs"
+msgstr ""
msgid "Opened issues"
msgstr "Geöffnete Tickets"
@@ -14404,6 +15275,9 @@ msgstr "Wird in einem neuen Fenster geöffnet"
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr "Im Besitz von mir"
msgid "Owner"
msgstr "Besitzer(in)"
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr "Paket wurde entfernt"
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr "Paket konnte nicht geladen werden"
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr "Pakete"
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr "Leistungsoptimierung"
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr "Frontend-Ressourcen"
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr "Zugriffsberechtigungen"
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr "Berechtigungen, LFS, 2FA"
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr "Pipelines des letzten Jahres"
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr "Dieses Projekt ist derzeit nicht zum Ausführen von Pipelines eingericht
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr "Commit"
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr "Dauer"
msgid "Pipeline|Existing branch name or tag"
msgstr "Bestehender Branchname oder Tag"
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr "Pipeline"
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr "Pipeline ausführen"
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr "Branches durchsuchen"
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr "Gib die für diesen Lauf zu verwendenden Variablenwerte an. Die in %{settings_link} angegebenen Werte werden standardmäßig verwendet."
@@ -15130,6 +16082,9 @@ msgstr "Pipeline stoppen"
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr "Pipeline #%{pipelineId} stoppen?"
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr "Unformatierter Diff"
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr "PlantUML"
@@ -15259,6 +16220,9 @@ msgstr "Bitte beachte, dass diese Anwendung nicht von GitLab bereitgestellt wird
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr "Pods im Einsatz"
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr "Einstellungen"
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr "Verhindere das Hinzufügen neuer Mitglieder zur Projektmitgliedschaft in dieser Gruppe"
@@ -15460,6 +16430,9 @@ msgstr "Vorschau der Nutzdaten"
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15536,7 +16509,7 @@ msgid "ProductivityAnalytics|Hours"
msgstr ""
msgid "ProductivityAnalytics|List"
-msgstr ""
+msgstr "Liste"
msgid "ProductivityAnalytics|Merge Requests"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr "Pfad"
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr "Lege Position und Größe deines neuen Avatars fest"
@@ -15874,12 +16841,6 @@ msgstr "Dein Status"
msgid "Profiles|e.g. My MacBook key"
msgstr "z. B. Mein MacBook-Schlüssel"
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr "Das Projekt '%{project_name}' wurde erfolgreich aktualisiert."
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr "Projektavatar"
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,8 +16955,8 @@ msgstr "Der Export des Projekts wurde gelöscht."
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr "Der Link für den Export des Projektes ist abgelaufen. Bitte generiere einen neuen Export in den Projekteinstellungen."
-msgid "Project export started. A download link will be sent by email."
-msgstr "Export des Projektes gestartet. Ein Link zum Herunterladen wir dir per E-Mail zugesandt."
+msgid "Project export started. A download link will be sent by email and made available on this page."
+msgstr ""
msgid "Project has too many %{label_for_message} to search"
msgstr ""
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr "Projektname"
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr "Automatische Konfiguration"
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr "Konfiguriere und stelle Prometheus automatisch auf deinen Clustern bereit, um deine Projektumgebungen zu überwachen"
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr "Allgemeine Metriken"
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr "Gemeinsame Metriken werden anhand einer Bibliothek von Metriken bekannter Exporter automatisch überwacht."
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr "Benutzerdefinierte Metriken"
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr "Stufe diese Projektmeilensteine zu einem Gruppenmeilenstein hoch."
-msgid "Promote to Group Milestone"
-msgstr "Zum Gruppenmeilenstein hochstufen"
-
msgid "Promote to group label"
msgstr "Hochstufen zum Gruppenlabel"
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr "Nicht wieder anzeigen"
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 "Mit Epics kannst du dein Projekt-Portfolio effizienter und mit weniger Aufwand verwalten, indem du Gruppen von Tickets, die ein Thema teilen, über Projekte und Meilensteine ​​hinweg verfolgst."
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr "Diese Funktion ist gesperrt."
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr "Upgrade-Plan"
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16739,10 +17775,10 @@ msgid "ProtectedBranch|Code owner approval"
msgstr ""
msgid "ProtectedBranch|Protect"
-msgstr ""
+msgstr "Schützen"
msgid "ProtectedBranch|Protect a branch"
-msgstr ""
+msgstr "Branch schützen"
msgid "ProtectedBranch|Protected branch (%{protected_branches_count})"
msgstr ""
@@ -16808,7 +17844,7 @@ msgid "Protip:"
msgstr "Protipp:"
msgid "Protocol"
-msgstr ""
+msgstr "Protokoll"
msgid "Provider"
msgstr "Provider"
@@ -16825,9 +17861,6 @@ msgstr "Öffentlich - Die Gruppe und alle öffentlichen Projekte können ohne Au
msgid "Public - The project can be accessed without any authentication."
msgstr "Öffentlich - Auf das Projekt kann ohne Authentifizierung zugegriffen werden."
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr "Öffentliche Pipelines"
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr "Pull"
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr "Kurzbefehle können in Ticket-Beschreibungen und Kommentarfeldern verwendet werden."
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr "Zugehörige Bereitstellungsjobs"
@@ -17129,6 +18180,18 @@ msgstr "Versionshinweise:"
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr "Releases"
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr "Gruppe entfernen"
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17349,6 +18427,9 @@ msgid "Rename/Move"
msgstr ""
msgid "Reopen"
+msgstr "Wieder öffnen"
+
+msgid "Reopen %{display_issuable_type}"
msgstr ""
msgid "Reopen epic"
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr "Antworten..."
msgid "Repo by URL"
msgstr "Repo via URL"
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr "Repository-Einstellungen"
msgid "Repository URL"
msgstr "Repository-URL"
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr "Auswählen"
msgid "Request Access"
msgstr "Anfrage auf Zugriff"
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
msgstr "Fordert Profile an"
-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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr "Verlange von Benutzer(inne)n, das Eigentum an benutzerdefinierten Domains nachzuweisen"
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17819,6 +18927,9 @@ msgid "Rollback"
msgstr ""
msgid "Rook"
+msgstr "Rook"
+
+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 ""
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
@@ -17884,9 +18995,6 @@ msgstr "Runner können durch separate Benutzer, auf Servern und sogar auf deinem
msgid "Runners currently online: %{active_runners_count}"
msgstr "Runner derzeit online: %{active_runners_count}"
-msgid "Runners page"
-msgstr "Runners-Seite"
-
msgid "Runners page."
msgstr "Runners-Seite."
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr "SSH-Schlüssel"
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr "Suche"
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr "Branches durchsuchen"
@@ -18115,6 +19226,9 @@ msgstr "Projekte suchen"
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr "Suche Benutzer(innen)"
@@ -18145,11 +19259,11 @@ msgstr "Merge-Requests, die mir zugewiesen sind"
msgid "SearchAutocomplete|in all GitLab"
msgstr "im ganzen GitLab"
-msgid "SearchAutocomplete|in this group"
-msgstr "in dieser Gruppe"
+msgid "SearchAutocomplete|in group %{groupName}"
+msgstr ""
-msgid "SearchAutocomplete|in this project"
-msgstr "in diesem Projekt"
+msgid "SearchAutocomplete|in project %{projectName}"
+msgstr ""
msgid "SearchCodeResults|in"
msgstr ""
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr "Secret"
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr "Sicherheit"
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr "Sicherheits-Dashboard"
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18295,7 +19412,7 @@ msgid "SecurityReports|Add or remove projects from your dashboard"
msgstr ""
msgid "SecurityReports|Add projects"
-msgstr ""
+msgstr "Projekte hinzufügen"
msgid "SecurityReports|Comment added to '%{vulnerabilityName}'"
msgstr ""
@@ -18325,7 +19442,7 @@ msgid "SecurityReports|Each vulnerability now has a unique page that can be dire
msgstr ""
msgid "SecurityReports|Edit dashboard"
-msgstr ""
+msgstr "Dashboard bearbeiten"
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 ""
@@ -18349,7 +19466,7 @@ msgid "SecurityReports|Issue Created"
msgstr ""
msgid "SecurityReports|Learn More"
-msgstr ""
+msgstr "Mehr erfahren"
msgid "SecurityReports|Learn more about setting up your dashboard"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr "Auswählen"
msgid "Select Archive Format"
msgstr "Archivierungsformat auswählen"
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18529,7 +19652,7 @@ msgid "Select a project to read Insights configuration file"
msgstr ""
msgid "Select a reason"
-msgstr ""
+msgstr "Grund auswählen"
msgid "Select a repository"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr "Wähle eine existierendes Kubernetes-Cluster aus oder erstelle ein neues"
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr "Branch/Tag auswählen"
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr "Quellbranch auswählen"
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr "Zielbranch auswählen"
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr "E-Mail senden"
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr "Lege ein Instanz-weites Vorlagen-Repository"
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr "Lege die maximale Sitzungszeit für das Web-Terminal fest."
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr "Sherlock-Transaktionen"
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr "Alle Mitglieder anzeigen"
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr "Archivierte Projekte anzeigen"
@@ -19050,12 +20203,21 @@ msgstr "Zeige komplettes Rohprotokoll"
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr "Neuste Version zeigen"
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] "Zeige %d Ereignis"
msgstr[1] "Zeige %d Ereignisse"
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr "Zeige %{limit} von %{total_count} Tickets. "
@@ -19215,7 +20385,7 @@ msgid "Slack application"
msgstr "Slack-Anwendung"
msgid "Slack channels (e.g. general, development)"
-msgstr ""
+msgstr "Slack Channels (z.B. Allgemein, Entwicklung)"
msgid "Slack integration allows you to interact with GitLab via slash commands in a chat window."
msgstr "Die Slack-Integration ermöglicht es dir, mit GitLab über Slash-Befehle im Chat-Fenster zu interagieren."
@@ -19262,6 +20432,9 @@ msgstr "Smartcard-Authentifizierung fehlgeschlagen: Client-Zertifikat-Header feh
msgid "Snippets"
msgstr "Codeausschnitte"
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr "Etwas ist beim Auflösen der Diskussion fehlgeschlagen. Versuche es spä
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr "Sortieren nach"
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr "Zugriffsebene, aufsteigend"
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr "Größe"
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr "Speicher:"
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr "Zu Branch/Tag wechseln"
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr "System-Hooks"
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr "Systeminformationen"
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr "Ereignisse, die für diese Phase ausgewertet wurden."
msgid "The commit does not exist"
msgstr "Der Commit existiert nicht"
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr "Die Verbindung wird nach %{timeout} beendet. Verwende eine Clone/Push-Kombination für Repositorys, die länger brauchen."
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr "Die Staging-Phase stellt die Zeit zwischen dem Mergen des Merge-Requests und der Bereitstellung des Codes zur Produktivumgebung dar. Sobald du das erste Mal zur Produktivumgebung ausgeliefert hast, werden deren Daten hier automatisch angezeigt."
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr "Die Testphase stellt die Zeit dar, die GitLab CI benötigt um die Pipelines von zugehörigen Merge-Requests abzuarbeiten. Sobald die erste Pipeline abgeschlossen ist, werden deren Daten hier automatisch angezeigt."
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr "Beim Laden des Benutzeraktivitäts-Kalenders ist ein Fehler aufgetreten."
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr "Dieses Datum ist nach dem Fälligkeitsdatum, daher erscheint dieses Epic nicht in der Roadmap."
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr "Dies ist ein in %{remainingTime} auszuführender verzögerter Job"
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr "Dies bedeutet, dass du keinen Code pushen kannst, bevor du kein leeres Repository erstellt oder ein existierendes importiert hast."
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr "Dieser Merge-Request ist gesperrt."
@@ -21509,12 +22757,18 @@ msgstr "Dieses Projekt"
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr "Dieses Projekt gehört keiner Gruppe an und kann daher keine Gruppenrunner verwenden."
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr "Dieses Projekt hat derzeit noch keine Wiki-Startseite"
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr "Für dieses Projekt ist keine Abrechnung aktiviert. Um ein Cluster zu erstellen, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">aktiviere die Abrechnung<i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> und versuche es erneut."
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr "Dieses Projekt ist archiviert und kann nicht kommentiert werden."
@@ -21527,12 +22781,24 @@ msgstr "Dieses Projekt wird am %{date} entfernt"
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr "Dieses Repository"
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr "Dieser Runner wird nur Pipelines von geschützen Branches ausführen"
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr "Diese(r) Benutzer(in) hat keine Identitäten"
msgid "This 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 "Diese(r) Benutzer(in) wird der/die Autor(in) aller Ereignisse im Aktivitätsfeed sein, die die Folge eines Updates, wie die Erstellung neuer Branches oder das Pushen neuer Commits zu existierenden Branches, sind."
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr "Diese(r) Benutzer(in) wird der/die Autor(in) aller Ereignisse im Aktivitätsfeed sein, die die Folge eines Updates, wie die Erstellung neuer Branches oder das Pushen neuer Commits zu existierenden Branches, sind. Bei der Erstellung oder der Neuzuweisung kannst du nur dich selbst als Mirror-Benutzer(in) zuweisen."
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr "gerade jetzt"
msgid "Timeout"
msgstr "Zeitüberschreitung"
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] "Std."
@@ -21930,6 +23202,12 @@ msgstr "Um interne Benutzer(innen) zu definieren, musst du zunächst externe Ben
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr "Um es zu aktivieren und Benutzer-Kohorten zu sehen, gehe zu den %{application_settings_link_start}Anwendungseinstellungen%{application_settings_link_end}."
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 "Gib zunächst deine FogBuz-URL und Anmeldeinformationen unten ein. In den nächsten Schritten kannst du Benutzer(innen) zuordnen und die Projekte für den Import auswählen."
@@ -22050,6 +23328,9 @@ msgstr "Beschreibung des Commits ein-/ausklappen"
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr "Gesamte Beiträge"
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr "Gesamte Testzeit für alle Commits/Merges"
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr "Verfolge Aktivitäten mit der Beitragsanalyse."
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr "Verfolge Gruppen von Tickets, die ein Thema teilen, über Projekte und Meilensteine hinweg"
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22318,12 +23596,12 @@ msgid "URL"
msgstr ""
msgid "URL is required"
-msgstr ""
+msgstr "URL erforderlich"
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr "Der Diff konnten nicht geladen werden. %{button_try_again}"
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr "Das Merge-Request-Widget konnte nicht geladen werden. Versuchen Sie die Seite neu zu laden."
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr "Aktualisiere"
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr "Aktualisiere deinen Tarif, um die erweiterte globale Suche zu aktivieren."
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr "Aktualisiere deinen Tarif, um Beitragsanalysen zu aktivieren."
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr "Aktualisiere deinen Tarif, um Gruppen-Webhooks zu aktivieren."
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr "Neue Datei hochladen"
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr "Zum Upload klicken"
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr "Der Nutzungsbericht ist nicht aktiviert"
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr "Nutzungsstatistiken"
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22777,7 +24082,7 @@ msgid "Use an one time password authenticator on your mobile device or computer
msgstr ""
msgid "Use custom color #FF0000"
-msgstr ""
+msgstr "Verwende benutzerdefinierte Farbe #FF0000"
msgid "Use group milestones to manage issues from multiple projects in the same milestone."
msgstr "Verwende Gruppenmeilensteine, um Tickets aus mehreren Projekten im selben Meilenstein zu verwalten."
@@ -22785,7 +24090,7 @@ msgstr "Verwende Gruppenmeilensteine, um Tickets aus mehreren Projekten im selbe
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr "Die Pipeline-Minuten des Users wurden erfolgreich zurückgesetzt."
msgid "User restrictions"
msgstr "Benutzerbeschränkungen"
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr "Konfiguration verifizieren"
msgid "Version"
msgstr "Version"
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr "Zeige Datei @ "
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23567,11 +24884,14 @@ msgid "Vulnerability|Status"
msgstr ""
msgid "WIP"
-msgstr ""
+msgstr "WIP"
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr "Es liegen nicht genügend Daten vor, um diese Phase anzuzeigen."
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 "Webhooks ermöglichen es dir eine URL aufzurufen, wenn z. B. neuer Code gepusht oder ein neues Ticket erstellt wird. Du kannst Webhooks so konfigurieren, dass sie auf bestimmte Ereignisse wie Pushes, Tickets oder Merge-Requests reagieren. Gruppen-Webhooks werden auf alle Projekte in einer Gruppe angewendet, so dass du die Webhook-Funktionalität in der gesamten Gruppe standardisieren kannst."
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23743,7 +25075,7 @@ msgid "Who will be able to see this group?"
msgstr "Wer wird in der Lage sein diese Gruppe zu sehen?"
msgid "Who will be using GitLab?"
-msgstr ""
+msgstr "Wer wird GitLab verwenden?"
msgid "Who will be using this GitLab subscription?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr "Git-Zugang"
msgid "WikiClone|Install Gollum"
msgstr "Gollum installieren"
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr "Es wird empfohlen, %{markdown} zu installieren, damit die GFM-Funktionen lokal gerendert werden:"
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr "Gollum starten und lokal bearbeiten"
@@ -23889,11 +25218,14 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr "Wiki-Seiten"
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "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 "Mit der Beitragsanalyse hast du einen Überblick über die Aktivitäten von Tickets, Merge-Requests und Push-Events deiner Organisation und seiner Mitglieder."
+msgid "With requirements, you can set criteria to check your products against."
+msgstr ""
msgid "Withdraw Access Request"
msgstr "Zugriffsanfrage widerrufen"
@@ -23901,10 +25233,10 @@ msgstr "Zugriffsanfrage widerrufen"
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr "Du kannst ganz einfach einen Runner auf einem Kubernetes-Cluster install
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr "Du kannst das Diagramm mit den Pfeiltasten bewegen."
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr "Du hast noch keine Abonnements"
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr "Du wirst bei jeder Aktivität Benachrichtigungen erhalten"
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr "Du wirst nur Benachrichtigungen für Kommentare erhalten, in denen du @erwähnt wurdest"
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr "Du kannst erst mittels '%{protocol}' übertragen (push) oder abrufen (pull), nachdem du für dein Konto '%{set_password_link}'"
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr "YouTube"
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr "Deine Gruppen"
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr "Deine Gruppen"
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr "Dein Name"
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr "Deine Projekte"
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr "vor"
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr "Branch-Name"
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr "von"
@@ -24807,6 +26196,9 @@ msgstr "Dynamic Application Security Testing (DAST) entdeckt Schwachstellen in d
msgid "ciReport|Failed to load %{reportName} report"
msgstr "Fehler beim Laden des Berichts %{reportName}"
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr "Behoben:"
@@ -24825,6 +26217,9 @@ msgstr "Lade Bericht %{reportName}"
msgid "ciReport|Manage licenses"
msgstr "Lizenzen verwalten"
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr "Keine Änderungen an der Codequalität"
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr "SAST"
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] "Verwendet von %{packagesString} und %{lastPackage}"
msgid "ciReport|View full report"
msgstr "Gesamten Bericht anzeigen"
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr "Du willst die Vertraulichkeit deaktivieren. Das bedeutet, dass <strong>alle</strong> das Ticket betrachten und kommentieren können."
@@ -24902,6 +26306,9 @@ msgstr "Du willst die Vertraulichkeit aktivieren. Das bedeutet, dass nur Teammit
msgid "connecting"
msgstr "Verbinde"
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr "erledigt"
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] "Entwurf"
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,14 +26409,14 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
-msgstr ""
+msgstr "external_url"
msgid "failed"
msgstr ""
@@ -25047,7 +26460,7 @@ msgid "group"
msgstr ""
msgid "groups"
-msgstr ""
+msgstr "Gruppen"
msgid "has already been linked to another vulnerability"
msgstr ""
@@ -25064,9 +26477,18 @@ msgstr "hier"
msgid "https://your-bitbucket-server"
msgstr "https://dein-bitbucket-server"
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr "Vorgehen beim Import"
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr "gesperrt durch %{path_lock_user_name} %{created_at}"
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr "Bereitstellungsstatistiken derzeit nicht verfügbar"
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr "Du kannst diesen Merge-Request manuell mergen mit der"
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr "Branch existiert nicht."
@@ -25509,15 +26940,6 @@ msgstr "Befehlszeile"
msgid "mrWidget|into"
msgstr "hinein"
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr "nicht verfügbar"
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25604,11 +27032,20 @@ msgid "pending removal"
msgstr ""
msgid "per day"
+msgstr "pro Tag"
+
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
msgstr ""
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,11 +27068,17 @@ msgid_plural "projects"
msgstr[0] "Projekt"
msgstr[1] "Projekte"
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
msgid "projects"
-msgstr ""
+msgstr "Projekte"
msgid "push to your repository, create pipelines, create issues or add comments. To reduce storage capacity, delete unused repositories, artifacts, wikis, issues, and pipelines."
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr "Zurücksetzen."
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25706,7 +27152,7 @@ msgid "severity|Medium"
msgstr ""
msgid "severity|None"
-msgstr ""
+msgstr "Keine"
msgid "severity|Unknown"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr "gestartet"
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr "sieh es auf GitLab an"
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr "verworfen"
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr "mit %{additions} Ergänzungen, %{deletions} Löschungen."
diff --git a/locale/el_GR/gitlab.po b/locale/el_GR/gitlab.po
index 86197dbbef9..12a2ec0292c 100644
--- a/locale/el_GR/gitlab.po
+++ b/locale/el_GR/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: el\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:35\n"
+"PO-Revision-Date: 2020-06-08 15:16\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,13 +8991,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8627,7 +9009,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] ""
msgstr[1] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/eo/gitlab.po b/locale/eo/gitlab.po
index 447e4effc83..56a72d10892 100644
--- a/locale/eo/gitlab.po
+++ b/locale/eo/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: eo\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:31\n"
+"PO-Revision-Date: 2020-06-08 15:12\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] "%d enmetado"
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr "Aktiva"
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr "Aktiveco"
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|Unknown"
+msgstr ""
+
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr "Kreu propran atingoĵetonon en via konto por ebligi al vi eltiri kaj alp
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr "Horzono por Cron"
-msgid "Cron syntax"
-msgstr "La sintakso de Cron"
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr "Difini propran Åablonon, uzante la sintakson de Cron"
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,14 +8991,14 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
-msgstr "Ĉiutage (je 4:00)"
+msgid "Every day (at %{time})"
+msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
-msgstr "Ĉiumonate (en la 1a de la monato, je 4:00)"
+msgid "Every month (Day %{day} at %{time})"
+msgstr ""
msgid "Every three months"
msgstr ""
@@ -8627,8 +9009,8 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
-msgstr "Ĉiusemajne (en dimanĉo, je 4:00)"
+msgid "Every week (%{weekday} at %{time})"
+msgstr ""
msgid "Everyone"
msgstr ""
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr "Dosieroj"
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr "Filtri per mesaÄo"
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr "De la kreado de la problemo Äis la disponigado en la publika versio"
msgid "From merge request merge until deploy to production"
msgstr "De la kunfandado de la peto pri kunfando Äis la disponigado en la publika versio"
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr "Lernu pli en la"
@@ -12232,6 +12887,9 @@ msgstr "Forlasi la projekton"
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] "Nova problemo"
msgstr[1] "Novaj problemoj"
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr "Nova problemo"
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr "Posedanto"
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr "La projekto „%{project_name}“ estis sukcese Äisdatigita."
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,8 +16955,8 @@ msgstr "La projekta elporto estis forigita."
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr "La ligilo por la projekta elporto eksvalidiÄis. Bonvolu krei novan elporton en la agordoj de la projekto."
-msgid "Project export started. A download link will be sent by email."
-msgstr "La elporto de la projekto komenciÄis. Vi ricevos ligilon per retpoÅto por elÅuti la datenoj."
+msgid "Project export started. A download link will be sent by email and made available on this page."
+msgstr ""
msgid "Project has too many %{label_for_message} to search"
msgstr ""
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr "Rilataj disponigitaj taskoj"
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr "Peti atingeblon"
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr "Elektu formaton de arkivo"
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr "Elektu celan branĉon"
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] "Estas montrata %d evento"
msgstr[1] "Estas montrataj %d eventoj"
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr "Iri al branĉo/etikedo"
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr "La aro da eventoj, kiuj estas aldonitaj al la datenoj kolektitaj por la
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr "La etapo de preparo por eldono montras la tempon inter la aplikado de la peto pri kunfando kaj la disponigado de la kodo en la publika versio. La datenoj aldoniÄos aÅ­tomate post kiam vi faros la unuan disponigadon en la publika versio."
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr "La etapo de testado montras kiom da tempo necesas al „GitLab CI“ por plenumi ĉiujn ĉenstablojn por la rilata peto pri kunfando. La datenoj aldoniÄos aÅ­tomate post kiam via unua ĉenstablo finiÄos."
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr "Ĉi tiu signifas, ke vi ne povos alpuÅi kodon, antaÅ­ ol vi kreos malplenan deponejon aÅ­ enportos jam ekzistantan."
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] "h"
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr "Totala tempo por la testado de ĉiuj enmetadoj/kunfandoj"
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr "AlÅuti novan dosieron"
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr "alklaku por alÅuti"
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr "Ne estas sufiĉe da datenoj por montri ĉi tiun etapon."
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr "Nuligi la peton pri atingeblo"
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr "Vi ricevos sciigojn por ĉiu ago"
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr "Vi ricevos sciigojn nur por komentoj, en kiuj vi estas @menciita"
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr "Vi ne povos eltiri aÅ­ alpuÅi kodon per %{protocol} antaÅ­ ol vi %{set_password_link} por via konto"
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr "Via nomo"
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/es/gitlab.po b/locale/es/gitlab.po
index d69bcadc687..63a85ad2419 100644
--- a/locale/es/gitlab.po
+++ b/locale/es/gitlab.po
@@ -12,10 +12,10 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: es-ES\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:14\n"
+"PO-Revision-Date: 2020-06-08 15:14\n"
msgid " %{start} to %{end}"
-msgstr ""
+msgstr " %{start} hasta %{end}"
msgid " (from %{timeoutSource})"
msgstr " (desde %{timeoutSource})"
@@ -71,14 +71,24 @@ msgstr "\"%{path}\" no existía en \"%{ref}\""
msgid "%d URL scanned"
msgid_plural "%d URLs scanned"
+msgstr[0] "%d URL escaneada"
+msgstr[1] "%d URLs escaneadas"
+
+msgid "%d approver"
+msgid_plural "%d approvers"
msgstr[0] ""
msgstr[1] ""
-msgid "%d changed file"
-msgid_plural "%d changed files"
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d changed file"
+msgid_plural "%d changed files"
+msgstr[0] "%d archivo modificado"
+msgstr[1] "%d archivos modificados"
+
msgid "%d child epic"
msgid_plural "%d child epics"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] "%d comentario"
msgstr[1] "%d comentarios"
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] "%d cambio"
@@ -117,11 +132,16 @@ msgid_plural "%d contributions"
msgstr[0] "%d contribución"
msgstr[1] "%d contribuciones"
-msgid "%d error"
-msgid_plural "%d errors"
+msgid "%d day"
+msgid_plural "%d days"
msgstr[0] ""
msgstr[1] ""
+msgid "%d error"
+msgid_plural "%d errors"
+msgstr[0] "%d error"
+msgstr[1] "%d errores"
+
msgid "%d exporter"
msgid_plural "%d exporters"
msgstr[0] "%d exportador"
@@ -139,8 +159,8 @@ msgstr[1] "%d solucionados los resultados de la prueba"
msgid "%d group selected"
msgid_plural "%d groups selected"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d grupo seleccionado"
+msgstr[1] "%d grupos seleccionados"
msgid "%d inaccessible merge request"
msgid_plural "%d inaccessible merge requests"
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] "%d comentarios más"
msgstr[1] "%d comentarios más"
+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] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] "%d proyecto"
@@ -204,8 +229,8 @@ msgstr[1] "%d segundos"
msgid "%d shard selected"
msgid_plural "%d shards selected"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d shard seleccionado"
+msgstr[1] "%d shards seleccionados"
msgid "%d tag"
msgid_plural "%d tags"
@@ -214,14 +239,24 @@ msgstr[1] ""
msgid "%d unresolved thread"
msgid_plural "%d unresolved threads"
+msgstr[0] "%d hilo sin resolver"
+msgstr[1] "%d hilos sin resolver"
+
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability dismissed"
-msgid_plural "%d vulnerabilities dismissed"
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
msgstr[0] ""
msgstr[1] ""
+msgid "%d vulnerability dismissed"
+msgid_plural "%d vulnerabilities dismissed"
+msgstr[0] "%d vulnerabilidad descartada"
+msgstr[1] "%d vulnerabilidades descartadas"
+
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 cambio adicional ha sido omitido para evitar problemas de rendimiento."
@@ -239,6 +274,9 @@ msgstr "%{commit_author_link} escribió %{commit_timeago}"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} núcleos"
@@ -316,6 +354,9 @@ msgstr "%{filePath} eliminado"
msgid "%{firstLabel} +%{labelCount} more"
msgstr "%{firstLabel} +%{labelCount} más"
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr "%{global_id} no es un identificador válido para %{expected_type}."
@@ -325,6 +366,9 @@ msgstr "Los %{group_docs_link_start}Grupos%{group_docs_link_end} le permiten adm
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr "%{group_name} utiliza cuentas administradas de grupo. Debe crear una nueva cuenta de GitLab que será administrada por %{group_name}."
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr "%{icon} Está apunto de añadir %{usersTag} gente a la discusión.Por favor, proceda con precaución."
@@ -337,6 +381,30 @@ msgstr "%{issuesSize} incidencias"
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr "%{issuesSize} incidencias con un límite de %{maxIssueCount}"
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr "%{label_for_message} no disponible"
@@ -370,12 +438,21 @@ msgstr "%{loadingIcon} Iniciado"
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 ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr "%{mergeLength}/%{usersLength} puede fusionarse"
msgid "%{mrText}, this issue will be closed automatically."
msgstr "%{mrText}, esta incidencia se cerrará automáticamente."
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,10 +468,16 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr "Avatar de %{name}"
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{no_of_days} día"
+msgstr[1] "%{no_of_days} días"
msgid "%{number_commits_behind} commits behind %{default_branch}, %{number_commits_ahead} commits ahead"
msgstr "%{number_commits_behind} commits detrás de %{default_branch}, %{number_commits_ahead} commits por delante"
@@ -418,10 +501,10 @@ msgid "%{percent}%{percentSymbol} complete"
msgstr "%{percent}%{percentSymbol} completo"
msgid "%{placeholder} is not a valid color scheme"
-msgstr ""
+msgstr "%{placeholder} no es un esquema de color válido"
msgid "%{placeholder} is not a valid theme"
-msgstr ""
+msgstr "%{placeholder} no es un tema válido"
msgid "%{primary} (%{secondary})"
msgstr "%{primary} (%{secondary})"
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] "%{releases} lanzamiento"
msgstr[1] "%{releases} lanzamientos"
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -438,7 +527,7 @@ msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Enabled"
msgstr ""
msgid "%{service_title} %{message}."
-msgstr ""
+msgstr "%{service_title} %{message}."
msgid "%{size} GiB"
msgstr "%{size} Gb"
@@ -484,7 +573,7 @@ msgid "%{strong_start}%{human_size}%{strong_end} Files"
msgstr "%{strong_start}%{human_size}%{strong_end} Archivos"
msgid "%{strong_start}%{human_size}%{strong_end} Storage"
-msgstr ""
+msgstr "%{strong_start}%{human_size}%{strong_end} Almacenamiento"
msgid "%{strong_start}%{release_count}%{strong_end} Release"
msgid_plural "%{strong_start}%{release_count}%{strong_end} Releases"
@@ -506,7 +595,7 @@ msgid "%{tags} tags per image name"
msgstr "%{tags} etiquetas por nombre de la imagen"
msgid "%{tag}-%{evidence}-%{filename}"
-msgstr ""
+msgstr "%{tag}-%{evidence}-%{filename}"
msgid "%{template_project_id} is unknown or invalid"
msgstr "%{template_project_id} es desconocido o no es válido"
@@ -529,7 +618,7 @@ msgid "%{title} changes"
msgstr "%{title} cambios"
msgid "%{token}..."
-msgstr ""
+msgstr "%{token}..."
msgid "%{totalWeight} total weight"
msgstr ""
@@ -556,7 +645,7 @@ msgid "%{username}'s avatar"
msgstr "Avatar de %{username}"
msgid "%{value} s"
-msgstr ""
+msgstr "%{value} s"
msgid "%{verb} %{time_spent_value} spent time."
msgstr "%{verb} %{time_spent_value} tiempo gastado."
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] "(%d cerrado)"
msgstr[1] "(%d cerrados)"
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr "(%{mrCount} fusionado)"
@@ -597,10 +689,10 @@ msgid "(removed)"
msgstr "(eliminado)"
msgid "(revoked)"
-msgstr ""
+msgstr "(revocado)"
msgid "*"
-msgstr ""
+msgstr "*"
msgid "+ %{amount} more"
msgstr "+ %{amount} más"
@@ -616,14 +708,14 @@ msgstr "+ %{numberOfHiddenAssignees} más"
msgid "+%d more"
msgid_plural "+%d more"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "+%d más"
+msgstr[1] "+%d más"
msgid "+%{approvers} more approvers"
msgstr ""
msgid "+%{tags} more"
-msgstr ""
+msgstr "+%{tags} más"
msgid ", or "
msgstr ", o "
@@ -704,7 +796,7 @@ msgstr[0] "1 minuto"
msgstr[1] "%d minutos"
msgid "1 month"
-msgstr ""
+msgstr "1 mes"
msgid "1 open issue"
msgid_plural "%{issues} open issues"
@@ -782,6 +874,9 @@ msgstr "Por favor, contacte con su administrador de GitLab si cree que se trata
msgid "8 hours"
msgstr "8 horas"
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr "< 1 hora"
@@ -798,7 +893,7 @@ msgid "<code>\"johnsmith@example.com\": \"johnsmith@example.com\"</code> will ad
msgstr "<code>\"johnsmith@example.com\": \"johnsmith@example.com\"</code> añadirá \"Por <a href=\"#\">johnsmith@example.com</a>\" a todas las incidencias y comentarios originalmente creados por johnsmith@example.com. Por defecto, el correo electrónico o el nombre de usuario está oculto para asegurar la privacidad del usuario. Utilice esta opción si desea mostrar la dirección de correo electrónico completa."
msgid "<namespace / project>"
-msgstr ""
+msgstr "<namespace / project>"
msgid "<no name set>"
msgstr "<no tiene el nombre establecido>"
@@ -807,11 +902,14 @@ msgid "<no scopes selected>"
msgstr "<ningún alcance seleccionado>"
msgid "<project name>"
-msgstr ""
+msgstr "<project name>"
msgid "<strong>%{group_name}</strong> group members"
msgstr "miembros del grupo <strong>%{group_name}</strong>"
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr "<strong>elimina</strong> la rama origen"
@@ -821,6 +919,9 @@ msgstr "Un ejecutor es un proceso que ejecuta un trabajo. Puede configurar tanto
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr "Una plantilla de aplicación de consola .NET Core, personalizable para cualquier proyecto .NET Core"
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr "Un sitio basado en GitBook que utiliza Netlify como herramienta de CI/CD en lugar de GitLab, pero con las demás excelentes características de GitLab."
@@ -843,7 +944,7 @@ msgid "A basic page and serverless function that uses AWS Lambda, AWS API Gatewa
msgstr ""
msgid "A complete DevOps platform"
-msgstr ""
+msgstr "Una plataforma DevOps completa"
msgid "A default branch cannot be chosen for an empty project."
msgstr "No se puede elegir una rama por defecto para un proyecto vacío."
@@ -857,7 +958,10 @@ msgstr "Ya existe un archivo con '%{file_name}' en %{branch} rama"
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr "Un fork es una copia de un proyecto.<br />Realizar un fork de un repositorio le permite realizar cambios sin afectar al proyecto original."
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr "Una expresión regular que se utilizará para rastrear la cantidad de co
msgid "A secure token that identifies an external storage request."
msgstr "Un token seguro que identifica una petición de almacenamiento externo."
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr "Un usuario con acceso de escritura a la rama origen seleccionó esta opc
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr "Ayuda de la API"
-
msgid "API Token"
msgstr "Token del API"
@@ -968,9 +1072,6 @@ msgstr "Aceptar los términos"
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr "Merge Request aceptado"
-
msgid "Access Tokens"
msgstr "Tokens de acceso"
@@ -1061,20 +1162,14 @@ msgstr "Su token se utiliza para autenticarle cuando los objetos estáticos del
msgid "AccessTokens|reset it"
msgstr "Reiniciarlo"
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
-msgstr ""
+msgstr "Más información"
msgid "AccessibilityReport|Message: %{message}"
-msgstr ""
+msgstr "Mensaje: %{message}"
msgid "AccessibilityReport|New"
-msgstr ""
+msgstr "Nuevo"
msgid "AccessibilityReport|The accessibility scanning found an error of the following type: %{code}"
msgstr ""
@@ -1103,13 +1198,16 @@ msgstr "Activar Service Desk"
msgid "Active"
msgstr "Activo"
-msgid "Active %{type} Tokens (%{token_length})"
-msgstr "Tokens activos %{type} (%{token_length})"
+msgid "Active %{type} (%{token_length})"
+msgstr ""
msgid "Active Sessions"
msgstr "Sesiones activas"
msgid "Active Users:"
+msgstr "Usuarios activos:"
+
+msgid "Active users"
msgstr ""
msgid "Activity"
@@ -1151,13 +1249,13 @@ msgid "Add README"
msgstr "Añadir README"
msgid "Add Variable"
-msgstr ""
+msgstr "Añadir variable"
msgid "Add Zoom meeting"
msgstr "Añadir una reunión de Zoom"
-msgid "Add a %{type} token"
-msgstr "Añadir un token %{type}"
+msgid "Add a %{type}"
+msgstr ""
msgid "Add a GPG key"
msgstr "Añadir una clave GPG"
@@ -1171,6 +1269,9 @@ msgstr "Añadir a tareas pendientes"
msgid "Add a bullet list"
msgstr "Añadir una lista de viñetas"
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr "Añadir un comentario general a este %{noteableDisplayName}."
@@ -1180,9 +1281,15 @@ msgstr "Añadir un comentario general a este %{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 "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 line"
+msgstr ""
+
msgid "Add a link"
msgstr "Añadir un enlace"
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr "Añadir una lista numerada"
@@ -1198,14 +1305,17 @@ msgstr "Añada un texto adicional que aparecerá en todas las comunicaciones ví
msgid "Add an SSH key"
msgstr "Añadir una clave SSH"
-msgid "Add an existing issue to the epic."
-msgstr "Agregar una incidencia existente a la épica."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
+msgstr ""
msgid "Add an issue"
msgstr "Agregar una incidencia"
msgid "Add another link"
-msgstr ""
+msgstr "Añadir otro enlace"
msgid "Add approval rule"
msgstr "Agregar una regla de aprobación"
@@ -1220,13 +1330,13 @@ msgid "Add comment now"
msgstr "Añadir comentario ahora"
msgid "Add domain"
-msgstr ""
+msgstr "Añadir dominio"
msgid "Add email address"
msgstr "Añadir dirección de correo electrónico"
msgid "Add environment"
-msgstr ""
+msgstr "Añadir entorno"
msgid "Add header and footer to emails. Please note that color settings will only be applied within the application interface"
msgstr "Añadir encabezado y pie de página a los correos electrónicos. Tenga en cuenta que la configuración de los colores solo se aplicará dentro de la interfaz de la aplicación"
@@ -1264,6 +1374,9 @@ msgstr "Añadir reacción"
msgid "Add request manually"
msgstr "Añadir solicitud manualmente"
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr "Añadir hook del sistema"
@@ -1292,7 +1405,7 @@ msgid "Add users to group"
msgstr "Agregar usuarios al grupo"
msgid "Add variable"
-msgstr ""
+msgstr "Añadir variable"
msgid "Add webhook"
msgstr "Añadir webhook"
@@ -1354,18 +1467,18 @@ msgstr "Agregar una reunión de Zoom"
msgid "Adds an issue to an epic."
msgstr "Agregar una incidencia a una tarea épica."
-msgid "Adjust your filters/search criteria above."
-msgstr "Ajuste sus filtros o criterios de búsqueda arriba."
+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 ""
msgid "Admin Area"
msgstr "Ãrea de administración"
+msgid "Admin Note"
+msgstr ""
+
msgid "Admin Overview"
msgstr "Vista de administrador"
-msgid "Admin Section"
-msgstr "Sección de administración"
-
msgid "Admin mode already enabled"
msgstr "Ya está habilitado el modo de administración"
@@ -1379,31 +1492,31 @@ msgid "Admin notes"
msgstr "Notas del administrador"
msgid "AdminArea|Active users"
-msgstr ""
+msgstr "Usuarios activos"
msgid "AdminArea|Billable users"
-msgstr ""
+msgstr "Usuarios facturables"
msgid "AdminArea|Blocked users"
-msgstr ""
+msgstr "Usuarios bloqueados"
msgid "AdminArea|Bots"
-msgstr ""
+msgstr "Bots"
msgid "AdminArea|Developer"
-msgstr ""
+msgstr "Desarrollador"
msgid "AdminArea|Guest"
-msgstr ""
+msgstr "Invitado"
msgid "AdminArea|Included Free in license"
-msgstr ""
+msgstr "AdminArea|Incluido gratis en la licencia"
msgid "AdminArea|Maintainer"
msgstr ""
msgid "AdminArea|Owner"
-msgstr ""
+msgstr "Propietario"
msgid "AdminArea|Reporter"
msgstr ""
@@ -1421,7 +1534,7 @@ msgid "AdminArea|Stopping jobs failed"
msgstr "Error al detener trabajos"
msgid "AdminArea|Total users"
-msgstr ""
+msgstr "Usuarios totales"
msgid "AdminArea|Users statistics"
msgstr ""
@@ -1670,7 +1783,7 @@ msgid "AdminUsers|You are about to permanently delete the user %{username}. This
msgstr "Está a punto de eliminar permanentemente el usuario %{username}. Esto eliminará todas las incidencias, merge requests y todos los grupos vinculados al mismo. Para evitar la pérdida de datos, considere utilizar la característica %{strong_start}bloquear usuario%{strong_end} en su lugar. Una vez %{strong_start}eliminado un usuario%{strong_end}, no se puede deshacer o volver recuperar esta acción."
msgid "Administration"
-msgstr ""
+msgstr "‫Administración"
msgid "Advanced"
msgstr "Avanzado"
@@ -1690,82 +1803,154 @@ msgstr "Después de una actualización correcta de la contraseña, será redirig
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr "Después de una actualización correcta de la contraseña, se le redirigirá a la página de inicio de sesión donde podrá iniciar sesión con su nueva contraseña."
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] "Alerta"
msgstr[1] "Alertas"
-msgid "Alert Details"
+msgid "AlertManagement|Acknowledged"
+msgstr "Confirmado"
+
+msgid "AlertManagement|Alert"
+msgstr ""
+
+msgid "AlertManagement|Alert detail"
msgstr ""
-msgid "AlertManagement|Acknowledged"
+msgid "AlertManagement|Alert details"
msgstr ""
-msgid "AlertManagement|Alert"
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
msgstr ""
msgid "AlertManagement|Authorize external service"
msgstr ""
-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."
+msgid "AlertManagement|Create issue"
msgstr ""
-msgid "AlertManagement|End time"
+msgid "AlertManagement|Critical"
msgstr ""
-msgid "AlertManagement|End time:"
+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 ""
+msgid "AlertManagement|End time"
+msgstr "Hora de finalización"
+
msgid "AlertManagement|Events"
+msgstr "Eventos"
+
+msgid "AlertManagement|High"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|Info"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Low"
+msgstr ""
+
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
+msgstr "Más información"
+
+msgid "AlertManagement|No alert data to display."
msgstr ""
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
-msgstr ""
+msgstr "No hay alertas disponibles para mostrar. Si cree que estás viendo este mensaje por error, por favor actualice la página."
msgid "AlertManagement|No alerts to display."
+msgstr "No hay alertas que mostrar."
+
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
msgstr ""
msgid "AlertManagement|Overview"
+msgstr "Descripción general"
+
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
msgstr ""
msgid "AlertManagement|Resolved"
+msgstr "Resuelto"
+
+msgid "AlertManagement|Service"
msgstr ""
msgid "AlertManagement|Severity"
-msgstr ""
+msgstr "Gravedad"
msgid "AlertManagement|Start time"
+msgstr "Hora de inicio"
+
+msgid "AlertManagement|Status"
+msgstr "Estado"
+
+msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
msgstr ""
-msgid "AlertManagement|Status"
+msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
-msgid "AlertManagement|Surface alerts in GitLab"
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
msgstr ""
-msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
+msgid "AlertManagement|Tool"
msgstr ""
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
-msgstr "%{linkStart}Aprenda más%{linkEnd} sobre la configuración de este endpoint para recibir alertas."
+msgid "AlertManagement|Unassigned"
+msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
-msgstr "Cada origen de la alerta debe ser autorizado mediante la siguiente URL y la clave de autorización."
+msgid "AlertManagement|Unknown"
+msgstr ""
+
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
+msgstr ""
msgid "Alerts"
msgstr "Alertas"
@@ -1783,7 +1968,7 @@ msgid "All %{replicableType} are being scheduled for %{action}"
msgstr ""
msgid "All (default)"
-msgstr ""
+msgstr "Todos (por defecto)"
msgid "All Members"
msgstr "Todos los miembros"
@@ -1801,7 +1986,7 @@ msgid "All email addresses will be used to identify your commits."
msgstr "Todas las direcciones de correo electrónico se utilizarán para identificar sus commits."
msgid "All environments"
-msgstr ""
+msgstr "Todos los entornos"
msgid "All features are enabled for blank projects, from templates, or when importing, but you can disable them afterward in the project settings."
msgstr "Todas las funcionalidades están habilitadas para proyectos en blanco, plantillas, o al importar, pero puedes deshabilitarlas posteriormente en la configuración del proyecto."
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr "Una aplicación llamada %{link_to_client} está solicitando el acceso a su cuenta de 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 ""
+
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 "Se agregará a un campo de usuario de Gitlab el nombre completo del usuario de FogBugz (por ejemplo, \"John Smith\") en la descripción de todos los errores y los comentarios. También se asociarán o asignarán estos errores y comentarios al creador del proyecto."
@@ -1981,7 +2169,7 @@ 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 while adding formatted title for epic"
-msgstr ""
+msgstr "Se ha producido un error al añadir el título formateado para la tarea épica"
msgid "An error occurred while checking group path"
msgstr "Se ha producido un error al comprobar la ruta del grupo"
@@ -1990,7 +2178,7 @@ msgid "An error occurred while committing your changes."
msgstr "Se ha producido un error al hacer commit de sus cambios."
msgid "An error occurred while decoding the file."
-msgstr ""
+msgstr "Se ha producido un error mientras al cargar el archivo."
msgid "An error occurred while deleting the approvers group"
msgstr "Se ha producido un error al eliminar el grupo de aprobadores"
@@ -2017,7 +2205,7 @@ msgid "An error occurred while enabling Service Desk."
msgstr "Se ha producido un error al habilitar Service Desk."
msgid "An error occurred while fetching coverage reports."
-msgstr ""
+msgstr "Se ha producido un error al recuperar los informes de cobertura."
msgid "An error occurred while fetching environments."
msgstr "Se ha producido un error al obtener los entornos."
@@ -2047,7 +2235,7 @@ 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 terraform reports."
-msgstr ""
+msgstr "Se ha producido un error al obtener los informes de terraform."
msgid "An error occurred while fetching the Service Desk address."
msgstr "Se ha producido un error al obtener la dirección de Service Desk."
@@ -2103,9 +2291,6 @@ msgstr "Se ha producido un error al cargar todos los archivos."
msgid "An error occurred while loading chart data"
msgstr "Se ha producido un error al cargar los datos del gráfico."
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr "Se ha producido un error al cargar las firmas de los commits"
@@ -2127,9 +2312,12 @@ 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 terraform report"
+msgid "An error occurred while loading milestones"
msgstr ""
+msgid "An error occurred while loading terraform report"
+msgstr "Se ha producido un error al cargar el informe de terraform"
+
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."
@@ -2143,7 +2331,7 @@ msgid "An error occurred while loading the file."
msgstr "Se ha producido un error al cargar el archivo."
msgid "An error occurred while loading the file. Please try again later."
-msgstr ""
+msgstr "Se ha producido un error al cargar el archivo. Por favor, inténtelo más tarde."
msgid "An error occurred while loading the merge request changes."
msgstr "Se ha producido un error al cargar los cambios del merge request."
@@ -2202,6 +2390,9 @@ msgstr "Se ha producido un error al guardar la configuración de aprobaciones"
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr "Se ha producido un error al guardar la plantilla. Por favor, compruebe si la plantilla existe."
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr "Se ha producido un error al suscribirse a las notificaciones."
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr "Una incidencia puede ser un error, una tarea pendiente o una solicitud de una nueva funcionalidad que debe tratarse en un proyecto. Además, recuerde que las incidencias se pueden buscar y filtrar."
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr "Se ha producido un error inesperado al comprobar el entorno del proyecto."
@@ -2256,6 +2453,9 @@ msgstr "Se ha producido un error inesperado al iniciar el Terminal Web."
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr "Se ha producido un error inesperado al detener el Terminal Web."
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr "Analíticas"
@@ -2263,10 +2463,13 @@ msgid "Analyze a review version of your web application."
msgstr "Analizar una revisión de la versión de la aplicación web."
msgid "Analyze your dependencies for known vulnerabilities."
+msgstr "Analizar sus dependencias en busca de vulnerabilidades conocidas."
+
+msgid "Analyze your source code and git history for secrets"
msgstr ""
msgid "Analyze your source code for known vulnerabilities."
-msgstr ""
+msgstr "Analiza el código fuente en busca de vulnerabilidades conocidas."
msgid "Ancestors"
msgstr "Antepasados"
@@ -2275,10 +2478,10 @@ msgid "Anonymous"
msgstr "Anónimo"
msgid "Another action is currently in progress"
-msgstr ""
+msgstr "Hay una acción en curso actualmente"
msgid "Another issue tracker is already in use. Only one issue tracker service can be active at a time"
-msgstr ""
+msgstr "Ya hay otro gestor de incidencias ya está en uso. Sólo puede estar activo un servicio de gestión de incidencias al mismo tiempo"
msgid "Anti-spam verification"
msgstr "Verificación de correo no deseado"
@@ -2287,16 +2490,10 @@ msgid "Any"
msgstr "Cualquiera"
msgid "Any Author"
-msgstr ""
-
-msgid "Any Label"
-msgstr "Cualquier etiqueta"
-
-msgid "Any Milestone"
-msgstr "Cualquier hito"
+msgstr "Cualquier autor"
msgid "Any branch"
-msgstr ""
+msgstr "Cualquier rama"
msgid "Any eligible user"
msgstr "Cualquier usuario elegible"
@@ -2304,9 +2501,15 @@ msgstr "Cualquier usuario elegible"
msgid "Any encrypted tokens"
msgstr "Cualquier token encriptado"
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr "Cualquier miembro con permisos de desarrollador o con permisos superiores para el proyecto."
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr "Cualquier espacio de nombres"
@@ -2341,7 +2544,7 @@ msgid "Application settings saved successfully"
msgstr "Se ha guardado correctamente la configuración de la aplicación"
msgid "Application settings update failed"
-msgstr ""
+msgstr "Se ha producido un error al actualizar los ajustes de la aplicación"
msgid "Application uninstalled but failed to destroy: %{error_message}"
msgstr "La aplicación se ha desinstalado correctamente pero no se ha podido destruir: %{error_message}"
@@ -2370,6 +2573,9 @@ msgstr "Aplicar a la etiqueta"
msgid "Apply a template"
msgstr "Aplicar una plantilla"
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr "Aplicar sugerencia"
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr "por ejemplo, QA, Seguridad, etc."
-msgid "Approvals"
-msgstr "Aprobaciones"
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr "Aprobar"
@@ -2453,12 +2653,18 @@ msgstr "Aprobar el merge request"
msgid "Approve the current merge request."
msgstr "Aprobar el merge request actual."
-msgid "Approved by: "
+msgid "Approved"
msgstr ""
+msgid "Approved by: "
+msgstr "Aprobado por: "
+
msgid "Approved the current merge request."
msgstr "Aprobado el merge request actual."
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr "Aprobador"
@@ -2472,7 +2678,7 @@ msgid "April"
msgstr "Abril"
msgid "Archive"
-msgstr ""
+msgstr "Archivar"
msgid "Archive jobs"
msgstr "Archivar trabajos"
@@ -2481,7 +2687,7 @@ msgid "Archive project"
msgstr "Archivar proyecto"
msgid "Archived"
-msgstr ""
+msgstr "Archivado"
msgid "Archived project! Repository and other project resources are read only"
msgstr "¡Proyecto archivado! El repositorio y otros recursos del proyecto son de sólo lectura"
@@ -2511,7 +2717,7 @@ msgid "Are you sure you want to close this blocked issue?"
msgstr ""
msgid "Are you sure you want to delete %{name}?"
-msgstr ""
+msgstr "¿Estás seguro de que deseas eliminar %{name}?"
msgid "Are you sure you want to delete these artifacts?"
msgstr "¿Está seguro de que desea eliminar estos artefactos?"
@@ -2535,7 +2741,7 @@ msgid "Are you sure you want to delete this pipeline? Doing so will expire all p
msgstr "¿Está seguro que desea eliminar este pipeline? Al hacerlo caducarán todas las cachés del pipeline y se eliminarán todos los objetos relacionados, como construcciones, logs, artefactos y disparadores. Esta acción no se puede deshacer."
msgid "Are you sure you want to deploy this environment?"
-msgstr ""
+msgstr "¿Estás seguro de que deseas desplegar este entorno?"
msgid "Are you sure you want to discard this comment?"
msgstr ""
@@ -2556,7 +2762,7 @@ msgid "Are you sure you want to permanently delete this license?"
msgstr "¿Está seguro de que desea eliminar de forma permanente esta licencia?"
msgid "Are you sure you want to re-deploy this environment?"
-msgstr ""
+msgstr "¿Está seguro de que desea volver a desplegar este entorno?"
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 "¿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."
@@ -2567,6 +2773,9 @@ msgstr "¿Está seguro que desea eliminar %{group_name}?"
msgid "Are you sure you want to remove the attachment?"
msgstr "¿Está seguro que desea eliminar el archivo adjunto?"
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr "¿Está seguro de que desea eliminar esta identidad?"
@@ -2579,8 +2788,8 @@ msgstr "¿Está seguro de que desea restablecer el token SCIM? La provisión de
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 revoke this %{type} Token? This action cannot be undone."
-msgstr "¿Está seguro de que desea revocar este token %{type}? Esta acción no se puede deshacer."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
+msgstr ""
msgid "Are you sure you want to revoke this nickname?"
msgstr "¿Está seguro que desea revocar este nick?"
@@ -2693,6 +2902,9 @@ msgstr "Incidencias asignadas"
msgid "Assigned Merge Requests"
msgstr "Merge requests asignados"
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr "Asignado a mí"
@@ -2723,7 +2935,7 @@ msgid "At least one of group_id or project_id must be specified"
msgstr "Debe especificar por lo menos un group_id o un project_id"
msgid "At risk"
-msgstr ""
+msgstr "En riesgo"
msgid "Attach a file"
msgstr "Adjuntar un archivo"
@@ -2758,24 +2970,42 @@ msgid "AuditEvents|Target"
msgstr "Objetivo"
msgid "AuditLogs|(removed)"
-msgstr ""
+msgstr "(eliminado)"
msgid "AuditLogs|Action"
-msgstr ""
+msgstr "Acción"
msgid "AuditLogs|Author"
-msgstr ""
+msgstr "Autor"
msgid "AuditLogs|Date"
+msgstr "Fecha"
+
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
msgstr ""
msgid "AuditLogs|IP Address"
+msgstr "Dirección IP"
+
+msgid "AuditLogs|No matching %{type} found."
msgstr ""
msgid "AuditLogs|Object"
+msgstr "Objeto"
+
+msgid "AuditLogs|Project Events"
msgstr ""
msgid "AuditLogs|Target"
+msgstr "Destino"
+
+msgid "AuditLogs|User Events"
msgstr ""
msgid "Aug"
@@ -2794,7 +3024,7 @@ msgid "Authenticating"
msgstr "Autenticando"
msgid "Authentication Failure"
-msgstr ""
+msgstr "Error de autenticación"
msgid "Authentication Log"
msgstr "Registro de Autenticación"
@@ -2818,7 +3048,7 @@ msgid "Author"
msgstr "Autor"
msgid "Authored %{timeago} by %{author}"
-msgstr ""
+msgstr "Creado %{timeago} por %{author}"
msgid "Authorization code:"
msgstr "Código de autorización:"
@@ -2835,6 +3065,9 @@ msgstr "Autorizar"
msgid "Authorize %{link_to_client} to use your account?"
msgstr "¿Autorizar %{link_to_client} para utilizar su cuenta?"
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr "Autorizado %{new_chat_name}"
@@ -2856,9 +3089,6 @@ msgstr "Auto DevOps habilitado"
msgid "Auto DevOps, runners and job artifacts"
msgstr "Auto DevOps, ejecutores y artefactos"
-msgid "Auto License Compliance"
-msgstr "License Compliance automático"
-
msgid "Auto stop successfully canceled."
msgstr "Parada automática cancelada con éxito."
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr "Documentación de Auto DevOps"
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr "Habilitar en la configuración"
@@ -2907,6 +3140,9 @@ msgstr "Gestión automática de los certificados utilizando %{lets_encrypt_link_
msgid "Automatic certificate management using Let's Encrypt"
msgstr "Gestión automática de los certificados utilizando Let's Encrypt"
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr "Marcado automáticamente como usuario interno por defecto"
@@ -2922,6 +3158,9 @@ msgstr "Nota"
msgid "Available"
msgstr "Disponible"
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr "Grupo de ejecutores disponible: %{runners}"
@@ -2944,7 +3183,7 @@ msgid "Average per day: %{average}"
msgstr "Promedio por día: %{average}"
msgid "Back to page %{number}"
-msgstr ""
+msgstr "Volver a la página %{number}"
msgid "Background Color"
msgstr "Color de fondo"
@@ -3154,7 +3393,7 @@ msgid "Blocked"
msgstr "Bloqueado"
msgid "Blocked issue"
-msgstr ""
+msgstr "Incidencia bloqueada"
msgid "Blocks"
msgstr ""
@@ -3292,7 +3531,7 @@ msgid "Branches|Only a project maintainer or owner can delete a protected branch
msgstr "Sólo el responsable del proyecto o el propietario pueden borrar una rama protegida"
msgid "Branches|Overview"
-msgstr "Resumen"
+msgstr "Descripción general"
msgid "Branches|Protected branches can be managed in %{project_settings_link}."
msgstr "Puede gestionar las ramas protegidas desde %{project_settings_link}."
@@ -3310,7 +3549,7 @@ msgid "Branches|Show more stale branches"
msgstr "Mostrar más ramas obsoletas"
msgid "Branches|Show overview of the branches"
-msgstr "Mostrar un resumen de las ramas"
+msgstr "Mostrar una descripción de las ramas"
msgid "Branches|Show stale branches"
msgstr ""
@@ -3399,20 +3638,20 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr "Incidencias abiertas"
+msgid "Burnup chart"
+msgstr ""
+
msgid "Business"
msgstr "Negocio"
msgid "Business metrics (Custom)"
msgstr "Métricas de negocio (personalizadas)"
-msgid "Buy EE"
-msgstr "Comprar EE"
-
-msgid "Buy GitLab Enterprise Edition"
-msgstr "Comprar GitLab Enterprise Edition"
+msgid "Buy License"
+msgstr ""
msgid "Buy more Pipeline minutes"
-msgstr ""
+msgstr "Compre más minutos de pipelines"
msgid "By %{user_name}"
msgstr "Por %{user_name}"
@@ -3432,8 +3671,8 @@ msgstr "CHANGELOG"
msgid "CI / CD"
msgstr "CI / CD"
-msgid "CI / CD Charts"
-msgstr "Gráficos de CI/CD"
+msgid "CI / CD Analytics"
+msgstr ""
msgid "CI / CD Settings"
msgstr "Configuración de CI/CD"
@@ -3441,6 +3680,9 @@ msgstr "Configuración de CI/CD"
msgid "CI Lint"
msgstr "Cl Lint"
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr "Variables de CI/CD"
@@ -3459,6 +3701,9 @@ msgstr "CI/CD para repositorio externo"
msgid "CI/CD settings"
msgstr "Configuración de CI/CD"
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr "Auto DevOps"
@@ -3489,9 +3734,6 @@ msgstr "El pipeline de Auto DevOps se ejecutará si no se encuentra ningún arch
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr "Debe agregar un %{base_domain_link_start}dominio base%{link_end} a su %{kubernetes_cluster_link_start}clúster de Kubernetes%{link_end} para que su estrategia de despliegue funcione."
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr "Debe añadir un %{kubernetes_cluster_link_start} cluster de integración de Kubernetes%{link_end} a este proyecto con un dominio para que su estrategia de despliegue funcione correctamente."
-
msgid "CICD|group enabled"
msgstr "grupo habilitado"
@@ -3519,6 +3761,12 @@ msgstr "Puede ser desplegado manualmente en"
msgid "Can override approvers and approvals required per merge request"
msgstr "Los aprobadores y las aprobaciones requeridas se pueden sobreescribir por cada merge request"
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr "No se puede encontrar el commit HEAD para este 'branch'"
@@ -3535,7 +3783,7 @@ msgid "Can't scan the code?"
msgstr "¿No puede escanear el código?"
msgid "Can't update snippet: %{err}"
-msgstr ""
+msgstr "No se puede actualizar el fragmento de código: %{err}"
msgid "Canary"
msgstr "Canary"
@@ -3594,8 +3842,8 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
-msgstr "¡No se puede referir a un hito de grupo por un id interno!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
+msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
msgstr ""
@@ -3609,6 +3857,9 @@ msgstr "No se puede omitir la configuración de autenticación de dos factores"
msgid "Capacity threshold"
msgstr "Límite de capacidad"
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr "Certificado"
@@ -3645,6 +3896,12 @@ msgstr "Cambiar la ruta"
msgid "Change permissions"
msgstr "Modificar los permisos"
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr "Cambiar plantilla"
@@ -3687,6 +3944,9 @@ msgstr "Cambios"
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr "Los cambios se muestran como si la revisión del <b>origen</b> se ha fusionado con la revisión del <b>objetivo</b>."
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,9 +3965,12 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr "Cambiar la ruta del grupo puede tener efectos secundarios no deseados."
-msgid "Charts"
+msgid "Channel handle (e.g. town-square)"
msgstr ""
+msgid "Charts"
+msgstr "Gráficos"
+
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -3796,7 +4059,7 @@ msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr "$%{selectedPlanPrice} por usuario y año"
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
-msgstr ""
+msgstr "%{cardType} terminada en %{lastFourDigits}"
msgid "Checkout|%{name}'s GitLab subscription"
msgstr "Suscripción de GitLab de%{name}"
@@ -3810,41 +4073,32 @@ msgstr "%{startDate} - %{endDate}"
msgid "Checkout|(x%{numberOfUsers})"
msgstr "(x%{numberOfUsers})"
-msgid "Checkout|1. Your profile"
-msgstr "1. Su perfil"
-
-msgid "Checkout|2. Checkout"
-msgstr "2. Checkout"
-
-msgid "Checkout|3. Your GitLab group"
-msgstr "3. Su grupo de GitLab"
-
msgid "Checkout|Billing address"
-msgstr ""
+msgstr "Dirección de facturación"
msgid "Checkout|Checkout"
msgstr " Checkout"
msgid "Checkout|City"
-msgstr ""
+msgstr "Ciudad"
msgid "Checkout|Confirm purchase"
-msgstr ""
+msgstr "Confirmar compra"
msgid "Checkout|Confirming..."
-msgstr ""
+msgstr "Confirmando..."
msgid "Checkout|Continue to billing"
msgstr "Continuar a la facturación"
msgid "Checkout|Continue to payment"
-msgstr ""
+msgstr "Continuar con el pago"
msgid "Checkout|Country"
-msgstr ""
+msgstr "País"
msgid "Checkout|Create a new group"
-msgstr ""
+msgstr "Crear un nuevo grupo"
msgid "Checkout|Credit card form failed to load. Please try again."
msgstr ""
@@ -3856,25 +4110,25 @@ msgid "Checkout|Edit"
msgstr "Editar"
msgid "Checkout|Exp %{expirationMonth}/%{expirationYear}"
-msgstr ""
+msgstr "Checkout|Exp %{expirationMonth}/%{expirationYear}"
msgid "Checkout|Failed to confirm your order! Please try again."
-msgstr ""
+msgstr "Checkout|¡Se ha producido un error al confirmar su pedido!. Por favor, inténtalo de nuevo"
msgid "Checkout|Failed to confirm your order: %{message}. Please try again."
-msgstr ""
+msgstr "Checkout|Se ha producido un error al confirmar su pedido %{message}. Por favor, inténtalo de nuevo"
msgid "Checkout|Failed to load countries. Please try again."
-msgstr ""
+msgstr "Ckeckout|Se ha producido un error al cargar los países. Por favor, inténtalo de nuevo"
msgid "Checkout|Failed to load states. Please try again."
-msgstr ""
+msgstr "Ckeckout|Se ha producido un error al cargar los estados. Por favor, inténtalo de nuevo."
msgid "Checkout|Failed to register credit card. Please try again."
-msgstr ""
+msgstr "Se ha producido un error al registrar la tarjeta de crédito. Por favor, inténtelo de nuevo."
msgid "Checkout|GitLab group"
-msgstr ""
+msgstr "Grupo de GitLab"
msgid "Checkout|GitLab plan"
msgstr "Plan de GitLab"
@@ -3892,22 +4146,22 @@ msgid "Checkout|Number of users"
msgstr "Número de usuarios"
msgid "Checkout|Payment method"
-msgstr ""
+msgstr "Forma de pago"
msgid "Checkout|Please select a country"
-msgstr ""
+msgstr "Por favor, seleccione un pais"
msgid "Checkout|Please select a state"
-msgstr ""
+msgstr "Por favor, seleccione un estado"
msgid "Checkout|Select"
-msgstr ""
+msgstr "Seleccionar"
msgid "Checkout|State"
-msgstr ""
+msgstr "Estado"
msgid "Checkout|Street address"
-msgstr ""
+msgstr "Dirección"
msgid "Checkout|Submitting the credit card form failed with code %{errorCode}: %{errorMessage}"
msgstr ""
@@ -3934,10 +4188,10 @@ msgid "Checkout|Your organization"
msgstr "Su organización"
msgid "Checkout|Your subscription will be applied to this group"
-msgstr ""
+msgstr "Su suscripción se aplicará a este grupo"
msgid "Checkout|Zip code"
-msgstr ""
+msgstr "Código postal"
msgid "Checkout|company or team"
msgstr "empresa o equipo"
@@ -4093,7 +4347,7 @@ msgid "CiVariables|Cannot use Masked Variable with current value"
msgstr "No se puede utilizar una variable enmascarada con el valor actual"
msgid "CiVariables|Environments"
-msgstr ""
+msgstr "Entornos"
msgid "CiVariables|Input variable key"
msgstr ""
@@ -4108,7 +4362,7 @@ msgid "CiVariables|Masked"
msgstr "Máscara"
msgid "CiVariables|Protected"
-msgstr ""
+msgstr "Protegido"
msgid "CiVariables|Remove variable row"
msgstr "Eliminar fila de variables"
@@ -4167,9 +4421,6 @@ msgstr "Error de validación"
msgid "Class"
msgstr "Clase"
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr "Etiqueta de clasificación (opcional)"
@@ -4182,6 +4433,9 @@ msgstr "Limpiar"
msgid "Clear chart filters"
msgstr "Borrar los filtros del gráfico"
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr "Limpiar entrada"
@@ -4194,6 +4448,9 @@ msgstr "Limpiar búsqueda"
msgid "Clear search input"
msgstr "Limpiar el historial de búsqueda"
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr "Borrar entrada de búsqueda de plantillas"
@@ -4221,9 +4478,6 @@ msgstr "Haga click en el botón <strong>Seleccionar uno</strong> en la parte der
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr "Haga clic en el botón que se muestra a continuación para comenzar con el proceso de instalación navegando hasta la página de Kubernetes"
-msgid "Click the image where you'd like to start a new discussion"
-msgstr "Haga clic en la imagen donde desea comenzar una nueva discusión"
-
msgid "Click to expand it."
msgstr "Haga clic para expandir."
@@ -4252,7 +4506,7 @@ msgid "Clone with %{http_label}"
msgstr "Clonar con %{http_label}"
msgid "Clone with %{protocol}"
-msgstr ""
+msgstr "Clonar con %{protocol}"
msgid "Clone with KRB5"
msgstr "Clonar con KRB5"
@@ -4263,6 +4517,9 @@ msgstr "Clonar con SSH"
msgid "Close"
msgstr "Cerrar"
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr "Cerrar %{tabname}"
@@ -4288,13 +4545,13 @@ msgid "Closed this %{quick_action_target}."
msgstr "Cerrado este %{quick_action_target}."
msgid "Closed: %{closedIssuesCount}"
-msgstr ""
+msgstr "Cerrados: %{closedIssuesCount}"
msgid "Closes this %{quick_action_target}."
msgstr "Cierra este %{quick_action_target}."
msgid "Cluster"
-msgstr ""
+msgstr "Clúster"
msgid "Cluster Health"
msgstr "Estado de salud del clúster"
@@ -4303,10 +4560,10 @@ msgid "Cluster cache cleared."
msgstr "Borrada la caché del clúster."
msgid "Cluster does not exist"
-msgstr ""
+msgstr "El clúster no existe"
msgid "Cluster level"
-msgstr ""
+msgstr "Nivel de clúster"
msgid "ClusterIntegration| %{custom_domain_start}More information%{custom_domain_end}."
msgstr "ClusterIntegration | %{custom_domain_start}Más información%{custom_domain_end}."
@@ -4324,7 +4581,7 @@ msgid "ClusterIntegration|%{appList} was successfully installed on your Kubernet
msgstr "%{appList} se instaló correctamente en su clúster de Kubernetes"
msgid "ClusterIntegration|%{external_ip}.nip.io"
-msgstr ""
+msgstr "%{external_ip}.nip.io"
msgid "ClusterIntegration|%{title} uninstalled successfully."
msgstr "%{title} desinstalado correctamente."
@@ -4411,7 +4668,7 @@ msgid "ClusterIntegration|Base domain"
msgstr "Dominio base"
msgid "ClusterIntegration|Blocking mode"
-msgstr ""
+msgstr "Modo de bloqueo"
msgid "ClusterIntegration|CA Certificate"
msgstr "Certificado CA"
@@ -4450,7 +4707,7 @@ msgid "ClusterIntegration|Cloud Run"
msgstr "Cloud Run"
msgid "ClusterIntegration|Cluster being created"
-msgstr ""
+msgstr "Se está creando el clúster"
msgid "ClusterIntegration|Cluster management project (alpha)"
msgstr "Proyecto de administración de cluster (alpha)"
@@ -4458,6 +4715,9 @@ msgstr "Proyecto de administración de cluster (alpha)"
msgid "ClusterIntegration|Cluster name is required."
msgstr "Se requiere el nombre del clúster."
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr "Los clusters se utilizan al seleccionar el ancestro más cercano en un ámbito de entorno coincidente. Por ejemplo, los grupos de proyectos anularán los grupos de clusters."
@@ -4479,9 +4739,6 @@ msgstr "Copiar el endpoint de Knative"
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr "Copiar el nombre del clúster Kubernetes"
-msgid "ClusterIntegration|Copy Service Token"
-msgstr "Copiar token de servicio"
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr "Se ha producido un error al cargar los roles de IAM"
@@ -4533,7 +4790,7 @@ msgstr "Creando el cluster de Kubernetes"
msgid "ClusterIntegration|Crossplane"
msgstr "Crossplane"
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr "Habilite esta configuración si utiliza el control de acceso basado en r
msgid "ClusterIntegration|Enabled stack"
msgstr "Stack habilitado"
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr "Introduzca los detalles de su clúster EKS Kubernetes de Amazon"
@@ -4597,7 +4857,7 @@ msgid "ClusterIntegration|Fetching zones"
msgstr "Obtener zonas"
msgid "ClusterIntegration|Fluentd"
-msgstr ""
+msgstr "Fluentd"
msgid "ClusterIntegration|Fluentd is an open source data collector, which lets you unify the data collection and consumption for a better use and understanding of data. It requires at least one of the following logs to be successfully installed."
msgstr ""
@@ -4638,12 +4898,12 @@ msgstr "ClusterIntegration|Grupo de clúster"
msgid "ClusterIntegration|Helm Tiller"
msgstr "Helm Tiller"
+msgid "ClusterIntegration|Helm release failed to install"
+msgstr ""
+
msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr "Helm optimiza la instalación y la administración de aplicaciones de Kubernetes. Tiller se ejecuta dentro de su cluster de Kubernetes y gestiona las versiones de sus charts."
-msgid "ClusterIntegration|Hide"
-msgstr "Ocultar"
-
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
msgstr "Si está configurando varios clústeres y utiliza Auto DevOps, por favor lea primero, %{help_link_start} y %{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr "No se han encontrado pares de claves"
msgid "ClusterIntegration|No VPCs found"
msgstr "No se han encontrado VPCs"
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr "No se encontró ningún tipo de instancia"
@@ -4861,7 +5127,7 @@ msgid "ClusterIntegration|Prometheus is an open-source monitoring system with %{
msgstr "Prometheus es un sistema de monitorización de código abierto con %{gitlabIntegrationLink} para monitorizar las aplicaciones desplegadas."
msgid "ClusterIntegration|Provider details"
-msgstr ""
+msgstr "Detalles del proveedor"
msgid "ClusterIntegration|Provision Role ARN"
msgstr "ARN del rol de provision"
@@ -4909,13 +5175,13 @@ msgid "ClusterIntegration|Request to begin uninstalling failed"
msgstr "La solicitud para comenzar la desinstalación ha fallado"
msgid "ClusterIntegration|SIEM Hostname"
-msgstr ""
+msgstr "Nombre de host SIEM"
msgid "ClusterIntegration|SIEM Port"
-msgstr ""
+msgstr "Puerto SIEM"
msgid "ClusterIntegration|SIEM Protocol"
-msgstr ""
+msgstr "Protocolo SIEM"
msgid "ClusterIntegration|Save changes"
msgstr "Guardar cambios"
@@ -5014,10 +5280,10 @@ msgid "ClusterIntegration|Select zone to choose machine type"
msgstr "Seleccione la zona para elegir el tipo de máquina"
msgid "ClusterIntegration|Send Cilium Logs"
-msgstr ""
+msgstr "ClusterIntegration | Enviar registros de Cilium"
msgid "ClusterIntegration|Send ModSecurity Logs"
-msgstr ""
+msgstr "ClusterIntegration | Enviar registros de ModSecurity"
msgid "ClusterIntegration|Service Token"
msgstr "Token de servicio"
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr "Mostrar"
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr "Algo salió mal de nuestro lado."
@@ -5115,11 +5378,14 @@ msgstr "Activar/Desactivar el clúster de Kubernetes"
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr "ClusterIntegration | Desinstalar %{appTitle}"
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr "Se ha podroducido un erro al actualizar. Por favor revise los registros y vuelva a intentarlo."
msgid "ClusterIntegration|Use %{query}"
-msgstr ""
+msgstr "Usar %{query}"
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."
@@ -5145,6 +5411,9 @@ msgstr "Está a punto de eliminar la integración de clúster."
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr "Está a punto de desinstalar %{appTitle} de su cluster."
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr "Primero debe instalar Helm Tiller antes de instalar las aplicaciones que se muestran a continuación"
@@ -5154,7 +5423,13 @@ msgstr "Debes conceder acceso a los recursos AWS de su organización para poder
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr "Debe tener un cluster RBAC habilitado para instalar Knative."
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
+msgstr "Debe seleccionar al menos dos subredes"
+
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
msgstr ""
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
@@ -5214,6 +5489,9 @@ msgstr "Seleccione el par de claves"
msgid "ClusterIntergation|Select service role"
msgstr "Seleccione el rol de servicio"
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr "Código"
@@ -5224,7 +5502,7 @@ msgid "Code Owners to the merge request changes."
msgstr ""
msgid "Code Quality"
-msgstr ""
+msgstr "Calidad del código"
msgid "Code Review"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr "Se requiere la aprobación del propietario del código"
@@ -5271,6 +5552,9 @@ msgstr "Contraer aprobadores"
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr "Contraer la barra lateral"
@@ -5280,6 +5564,9 @@ msgstr "Nombre del recolector"
msgid "ComboSearch is not defined"
msgstr "ComboSearch no está definido"
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr "Comando"
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr "El comentario está siendo actualizado"
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr "Comentar/Responder (citando el texto seleccionado)"
@@ -5361,7 +5651,7 @@ msgid "CommitWidget|authored"
msgstr "autorizado"
msgid "Commits"
-msgstr "Cambios"
+msgstr "Commits"
msgid "Commits feed"
msgstr "Feed de cambios"
@@ -5448,37 +5738,40 @@ msgid "Compliance framework (optional)"
msgstr ""
msgid "ComplianceFramework|GDPR"
-msgstr ""
+msgstr "GDPR"
msgid "ComplianceFramework|GDPR - General Data Protection Regulation"
msgstr ""
msgid "ComplianceFramework|HIPAA"
-msgstr ""
+msgstr "HIPAA"
msgid "ComplianceFramework|HIPAA - Health Insurance Portability and Accountability Act"
msgstr ""
msgid "ComplianceFramework|PCI-DSS"
-msgstr ""
+msgstr "PCI-DSS"
msgid "ComplianceFramework|PCI-DSS - Payment Card Industry-Data Security Standard"
msgstr ""
msgid "ComplianceFramework|SOC 2"
-msgstr ""
+msgstr "SOC 2"
msgid "ComplianceFramework|SOC 2 - Service Organization Control 2"
msgstr ""
msgid "ComplianceFramework|SOX"
-msgstr ""
+msgstr "ComplianceFramework|SOX"
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
+msgstr "ComplianceFramework|SOX - ley Sarbanes-Oxley"
+
+msgid "ComplianceFramework|This project is regulated by %{framework}."
msgstr ""
-msgid "Confidence: %{confidence}"
-msgstr "Confianza: %{confidence}"
+msgid "Confidence"
+msgstr ""
msgid "Confidential"
msgstr "Confidencial"
@@ -5501,9 +5794,6 @@ msgstr "Configurar Let's Encrypt"
msgid "Configure Prometheus"
msgstr "Configurar Prometheus"
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr "Configurar seguimiento"
@@ -5537,9 +5827,6 @@ msgstr "Configure los ajustes de la ruta de almacenamiento."
msgid "Configure the %{link} integration."
msgstr "Configurar la %{link} integración."
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr "Configure la forma en la que un usuario crea una cuenta nueva."
@@ -5568,7 +5855,7 @@ msgid "Connect your external repositories, and CI/CD pipelines will run for new
msgstr "Conecte sus repositorios externos, y los pipelines de CI/CD se ejecutarán para los nuevos commits. Se creará un proyecto de Gitlab sólo con las caracteristicas de CI/CD habilitadas."
msgid "Connected"
-msgstr ""
+msgstr "Conectado"
msgid "Connecting"
msgstr "Conectando"
@@ -5588,17 +5875,11 @@ msgstr "Error de conexión"
msgid "Connection timed out"
msgstr "Tiempo de espera agotado"
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr "Póngase en contacto con el propietario del grupo %{namespace_name} para actualizar el plan."
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr "Póngase en contacto con el propietario %{link_start}%{owner_name}%{link_end} para actualizar el plan."
-
msgid "Contact sales to upgrade"
msgstr "Póngase en contacto con ventas para actualizar"
-msgid "Contact your Administrator to upgrade your license."
-msgstr "Póngase en contacto con el administrador para actualizar su licencia."
+msgid "Contact support"
+msgstr ""
msgid "Container Registry"
msgstr "Registro de contenedores"
@@ -5610,7 +5891,7 @@ msgid "Container Scanning"
msgstr "Escaneo de contenedores"
msgid "Container does not exist"
-msgstr ""
+msgstr "El contenedor no existe"
msgid "Container registry images"
msgstr "Imágenes del registro de contenedores"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,9 +5927,12 @@ msgstr "Eliminar automáticamente las imágenes adicionales que no están diseñ
msgid "ContainerRegistry|Build an image"
msgstr ""
-msgid "ContainerRegistry|Compressed Size"
+msgid "ContainerRegistry|CLI Commands"
msgstr ""
+msgid "ContainerRegistry|Compressed Size"
+msgstr "Tamaño comprimido"
+
msgid "ContainerRegistry|Container Registry"
msgstr "Registro de contenedores"
@@ -5660,27 +5954,39 @@ msgstr "Error de conexión de Docker"
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
-msgstr ""
-
msgid "ContainerRegistry|Expiration interval:"
msgstr "Intervalo de caducidad:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr "Si no ha iniciado sesión, necesita autenticarse en el registro de contenedores utilizando su nombre de usuario y su contraseña de GitLab. Si tiene habilitada la %{twofaDocLinkStart}autenticación de dos factores%{twofaDocLinkEnd}, utilice un %{personalAccessTokensDocLinkStart}token de acceso personal%{personalAccessTokensDocLinkEnd} en lugar de una contraseña."
msgid "ContainerRegistry|Image ID"
msgstr "ID de la imagen"
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5688,24 +5994,21 @@ msgid "ContainerRegistry|Last Updated"
msgstr "Última actualización"
msgid "ContainerRegistry|Login"
-msgstr ""
+msgstr "Iniciar sesión"
msgid "ContainerRegistry|Missing or insufficient permission, delete button disabled"
msgstr ""
msgid "ContainerRegistry|Number of tags to retain:"
-msgstr ""
+msgstr "ContainerRegistry|Número de etiquetas a retener:"
msgid "ContainerRegistry|Please contact your administrator."
-msgstr ""
+msgstr "ContainerRegistry|Por favor, póngase en contacto con su administrador."
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr "Inicio rápido"
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] "Eliminar etiqueta"
msgstr[1] "Eliminar etiquetas"
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr "Se ha producido un error al actualizar la política de caducidad."
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr "Etiqueta"
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr "La última etiqueta relacionada con esta imagen fue eliminada recientemente. Esta imagen vacía y cualquier dato asociado se eliminarán automáticamente como parte del proceso llamado \"Garbage Collection\". Si tienes alguna pregunta, póngase en contacto con su administrador."
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr "El valor de esta entrada debe ser menor de 255 caracteres"
@@ -5800,8 +6097,11 @@ msgstr "Esta imagen no tiene etiquetas activas"
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
-msgstr "Estamos teniendo problemas para conectar con Docker, lo que podría deberse a una incidencia con la ruta o el nombre de su proyecto. %{docLinkStart}Más Información%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
msgstr "Con el registro de contenedores, cada proyecto puede tener su propio espacio para almacenar sus imágenes de Docker. %{docLinkStart}Más Información%{docLinkEnd}"
@@ -5809,8 +6109,8 @@ msgstr "Con el registro de contenedores, cada proyecto puede tener su propio esp
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 "Con el registro de contenedores, cada proyecto puede tener su propio espacio para almacenar sus imágenes de Docker. Envíe al menos una imagen de Docker a uno de los proyectos de este grupo para que aparezca aquí. %{docLinkStart}Más información%{docLinkEnd}"
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
-msgstr "Con el registro de contenedores de Docker integrado en GitLab, cada proyecto puede tener su propio espacio para almacenar sus imágenes de contenedores. %{docLinkStart}Más Información%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
msgstr ""
@@ -5848,12 +6148,12 @@ msgstr "Contribución"
msgid "Contribution Analytics"
msgstr "Análisis de contribución"
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
-msgstr "<strong>%{created_count}</strong> creado, <strong>%{accepted_count}</strong> aceptado."
-
msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr "<strong>%{created_count}</strong> creado, <strong>%{closed_count}</strong> cerrado."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
+msgstr ""
+
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
msgstr ""
@@ -5938,6 +6238,9 @@ msgstr "Copiar la URL de clonado del protocolo %{protocol}"
msgid "Copy %{proxy_url}"
msgstr "Copiar %{proxy_url}"
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr "Copiar ID de la cuenta al portapapeles"
@@ -5972,10 +6275,10 @@ msgid "Copy commit SHA"
msgstr "Copiar el SHA del commit"
msgid "Copy environment"
-msgstr ""
+msgstr "Copiar entorno"
msgid "Copy evidence SHA"
-msgstr ""
+msgstr "Copia evidencia SHA"
msgid "Copy file contents"
msgstr "Copia el contenido del archivo"
@@ -5983,11 +6286,8 @@ msgstr "Copia el contenido del archivo"
msgid "Copy file path"
msgstr "Copiar la ruta del archivo"
-msgid "Copy impersonation token"
-msgstr "Copiar token de suplantación"
-
msgid "Copy key"
-msgstr ""
+msgstr "Copiar clave"
msgid "Copy labels and milestone from %{source_issuable_reference}."
msgstr "Copiar las etiquetas y el hito desde %{source_issuable_reference}."
@@ -5999,10 +6299,7 @@ msgid "Copy link"
msgstr "Copiar enlace"
msgid "Copy link to chart"
-msgstr ""
-
-msgid "Copy personal access token"
-msgstr "Copiar token de acceso personal"
+msgstr "Copiar enlace al gráfico"
msgid "Copy reference"
msgstr "Copiar la referencia"
@@ -6017,7 +6314,7 @@ msgid "Copy trigger token"
msgstr "Copiar token de activación"
msgid "Copy value"
-msgstr ""
+msgstr "Copiar valor"
msgid "Could not add admins as members"
msgstr "No se puede agregar administradores como miembros"
@@ -6050,7 +6347,7 @@ msgid "Could not create project"
msgstr "Se ha producido un error al crear el proyecto"
msgid "Could not delete %{design}. Please try again."
-msgstr ""
+msgstr "No se puede eliminar %{design}. Por favor, inténtelo de nuevo."
msgid "Could not delete chat nickname %{chat_name}."
msgstr "No es posible eliminar el apodo del chate %{chat_name}."
@@ -6074,7 +6371,7 @@ msgid "Could not revoke project access token %{project_access_token_name}."
msgstr ""
msgid "Could not save group ID"
-msgstr ""
+msgstr "Se ha producido un error al guardar el ID del grupo"
msgid "Could not save project ID"
msgstr "Se ha producido un error al guardar el ID del proyecto"
@@ -6098,10 +6395,10 @@ msgid "Create"
msgstr "Crear"
msgid "Create %{environment}"
-msgstr ""
+msgstr "Crear %{environment}"
-msgid "Create %{type} token"
-msgstr "Crear un token %{type}"
+msgid "Create %{type}"
+msgstr ""
msgid "Create New Directory"
msgstr "Crear Nuevo Directorio"
@@ -6118,9 +6415,6 @@ msgstr "Cree primero una cuenta de GitLab y luego conéctela a su cuenta %{label
msgid "Create a Mattermost team for this group"
msgstr "Crear un equipo de Mattermost para este grupo"
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr "Cree un proxy local para almacenar las imágenes usadas frecuentemente con anterioridad. %{link_start}Obtenga más%{link_end} información sobre los proxies de dependencias."
@@ -6131,7 +6425,7 @@ msgid "Create a new branch"
msgstr "Crear un nuevo 'branch'"
msgid "Create a new deploy key for this project"
-msgstr ""
+msgstr "Crear una nueva clave de despliegue para este proyecto"
msgid "Create a new file as there are no files yet. Afterwards, you'll be able to commit your changes."
msgstr "Cree un nuevo archivo ya todavía no hay archivos. Posteriormente, podrá confirmar los cambios con sus commits."
@@ -6139,9 +6433,6 @@ msgstr "Cree un nuevo archivo ya todavía no hay archivos. Posteriormente, podrÃ
msgid "Create a new issue"
msgstr "Crear una nueva incidencia"
-msgid "Create a new issue and add it to the epic."
-msgstr "Crear una nueva incidencia y añadirla a la épica."
-
msgid "Create a new repository"
msgstr "Crear un nuevo repositorio"
@@ -6151,9 +6442,6 @@ msgstr "Crear un token de acceso personal en tu cuenta para actualizar o enviar
msgid "Create an account using:"
msgstr "Crear una cuenta utilizando:"
-msgid "Create an issue"
-msgstr "Crear una nueva incidencia"
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr "Crear una incidencia. Se crearán incidencias para cada alerta activada."
@@ -6196,6 +6484,9 @@ msgstr "Crear etiqueta de grupo"
msgid "Create issue"
msgstr "Crear incidencia"
+msgid "Create iteration"
+msgstr ""
+
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."
@@ -6208,6 +6499,9 @@ msgstr "Crear un merge request y un branch"
msgid "Create milestone"
msgstr "Crear hito"
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr "Crear nuevo tablero"
@@ -6236,17 +6530,23 @@ msgid "Create project label"
msgstr "Crear etiqueta de proyecto"
msgid "Create requirement"
-msgstr ""
+msgstr "Crear requisito"
msgid "Create snippet"
-msgstr ""
+msgstr "Crear fragmento de código"
msgid "Create wildcard: %{searchTerm}"
-msgstr ""
+msgstr "Crear comodín: %{searchTerm}"
msgid "Create your first page"
msgstr "Crea tu primera página"
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr "No tiene permiso para crear un subgrupo en este grupo."
@@ -6263,7 +6563,7 @@ msgid "Created"
msgstr "Creado"
msgid "Created %{timestamp}"
-msgstr ""
+msgstr "Creado %{timestamp}"
msgid "Created At"
msgstr "Creado en"
@@ -6280,6 +6580,9 @@ msgstr "Creada una rama '%{branch_name}' y un merge request para resolver esta i
msgid "Created by me"
msgstr "Creado por mí"
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr "Incidencia creada %{issueLink}"
@@ -6317,13 +6620,13 @@ msgid "Credentials"
msgstr "Credenciales"
msgid "CredentialsInventory|No credentials found"
-msgstr ""
+msgstr "No se encontraron credenciales"
msgid "CredentialsInventory|Personal Access Tokens"
-msgstr ""
+msgstr "Tokens de acceso personal"
msgid "CredentialsInventory|SSH Keys"
-msgstr ""
+msgstr "Claves SSH"
msgid "Critical vulnerabilities present"
msgstr "Vulnerabilidades críticas presentes"
@@ -6331,9 +6634,6 @@ msgstr "Vulnerabilidades críticas presentes"
msgid "Cron Timezone"
msgstr "Zona horaria del Cron"
-msgid "Cron syntax"
-msgstr "Sintaxis de Cron"
-
msgid "Crossplane"
msgstr "Crossplane"
@@ -6359,7 +6659,7 @@ msgid "Current vulnerabilities count"
msgstr "Contador de vulnerabilidades"
msgid "CurrentUser|Buy CI minutes"
-msgstr ""
+msgstr "Comprar minutos de CI"
msgid "CurrentUser|Profile"
msgstr "Perfil"
@@ -6370,6 +6670,9 @@ msgstr "Configuración"
msgid "CurrentUser|Start a Gold trial"
msgstr "Inicie periodo de prueba Gold"
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr "Ruta de configuración CI personalizada"
@@ -6394,6 +6697,9 @@ msgstr "No se han configurado plantillas de proyecto personalizadas para grupos
msgid "Custom range"
msgstr "Rango personalizado"
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr "Añadir una etapa"
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr "Actualizar etapa"
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr "Personalizar colores"
@@ -6466,6 +6775,9 @@ msgstr "Personalice la configuración de su pipeline, vea el estado de su pipeli
msgid "Customize your pipeline configuration."
msgstr "Personalice la configuración de su pipeline."
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr "Incidencia cerrada"
@@ -6664,7 +6976,7 @@ msgid "Date range cannot exceed %{maxDateRange} days."
msgstr ""
msgid "Day of month"
-msgstr ""
+msgstr "Día del mes"
msgid "DayTitle|F"
msgstr "V"
@@ -6717,6 +7029,9 @@ msgstr "Ramas por defecto y ramas protegidas"
msgid "Default classification label"
msgstr "Etiqueta de clasificación por defecto"
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr "Por defecto: Asignar un ID de cuenta de FogBugz a un nombre completo"
msgid "Define a custom pattern with cron syntax"
msgstr "Definir un patrón personalizado con la sintaxis de cron"
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr "Defina entornos en las distintas etapas de despliegue en el fichero <code>.gitlab-ci.yml</code> para llevar un registro de las implementaciones desde aquí."
@@ -6795,6 +7113,12 @@ msgstr "Eliminar comentario"
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr "Eliminar la licencia"
@@ -6823,7 +7147,7 @@ msgid "Delete this attachment"
msgstr "Eliminar este adjunto"
msgid "Delete variable"
-msgstr ""
+msgstr "Eliminar variable"
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr "Se ha producido un error al eliminar el repositorio del proyecto. Por favor, inténtelo de nuevo o póngase en contacto con el administrador."
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] "%d vulnerabilidad adicional no mostrada"
msgstr[1] "%d vulnerabilidades adicionales no mostradas"
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] "%d vulnerabilidad"
-msgstr[1] "%d vulnerabilidades"
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr "Ubicación"
msgid "Dependencies|Packager"
msgstr "Empaquetador"
-msgid "Dependencies|Safe"
-msgstr "Seguras"
-
-msgid "Dependencies|Status"
-msgstr "Estado"
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr "Ficheros no admitidos detectados"
-msgid "Dependencies|Version"
-msgstr "Versión"
-
msgid "Dependencies|Vulnerable components"
msgstr "Componentes vulnerables"
@@ -7056,12 +7366,18 @@ msgstr "Claves de despliegue activas (%{active_tokens})"
msgid "DeployTokens|Add a deploy token"
msgstr "Añadir un token de despliegue"
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr "Permite el acceso en modo de sólo lectura al registro de imágenes"
msgid "DeployTokens|Allows read-only access to the repository"
msgstr "Permite el acceso en modo de sólo lectura al repositorio"
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr "El formato por defecto es \"GitLab+token-de-despliegue-{n}\". Por favor,
msgid "DeployTokens|Deploy Tokens"
msgstr "Tokens de despliegue"
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr "Expira"
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7147,7 +7463,7 @@ msgid "Deploying to"
msgstr "Desplegando en"
msgid "Deployment Frequency"
-msgstr ""
+msgstr "Frecuencia de despliegue"
msgid "Deployment|API"
msgstr "API"
@@ -7180,7 +7496,7 @@ msgid "Describe the goal of the changes and what reviewers should be aware of."
msgstr ""
msgid "Describe the requirement here"
-msgstr ""
+msgstr "Describa el requisito aquí"
msgid "Description"
msgstr "Descripción"
@@ -7209,21 +7525,36 @@ msgstr "%{current_design} de %{designs_count}"
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
-msgstr "Agregar diseños"
-
msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr "Agregar un diseño con el mismo nombre de archivo reemplaza el archivo en una nueva versión."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
+msgstr ""
+
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
msgstr "¿Está seguro de que desea cancelar la creación de este comentario?"
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr "¿Está seguro de que desea eliminar los diseños seleccionados?"
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr "Cancelar la confirmación de comentario"
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr "Se ha producido un error al crear el comentario. Por favor, inténtelo de nuevo."
@@ -7233,6 +7564,9 @@ msgstr "Se ha producido un error al crear una nueva discusión. Por favor, inté
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr "Eliminar"
@@ -7260,12 +7594,27 @@ msgstr "Ir al siguiente diseño"
msgid "DesignManagement|Go to previous design"
msgstr "Ir al diseño anterior"
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr "Mantener comentario"
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr "La versión del diseño solicitada no existe. Mostrando la última versión en su lugar"
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr "Seleccionar todo"
@@ -7275,11 +7624,17 @@ msgstr "El número máximo de diseños permitidos que se pueden cargar es %{uplo
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
msgid "DesignManagement|and %{moreCount} more."
-msgstr ""
+msgstr "y %{moreCount} más."
msgid "Designs"
msgstr "Diseños"
@@ -7287,6 +7642,9 @@ msgstr "Diseños"
msgid "Destroy"
msgstr "Destruir"
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr "Detalles"
@@ -7306,7 +7664,7 @@ msgid "Diff limits"
msgstr "Límites del diff"
msgid "Difference between start date and now"
-msgstr ""
+msgstr "Diferencia entre la fecha de inicio y ahora"
msgid "DiffsCompareBaseBranch|(HEAD)"
msgstr ""
@@ -7339,7 +7697,7 @@ msgid "Disable group Runners"
msgstr "Desactivar el grupo de ejecutores"
msgid "Disable public access to Pages sites"
-msgstr ""
+msgstr "Deshabilitar el acceso público a los sitios de Pages"
msgid "Disable shared Runners"
msgstr "Deshabilitar los ejecutores compartidos"
@@ -7357,7 +7715,7 @@ msgid "Discard all changes"
msgstr "Descartar todos los cambios"
msgid "Discard all changes?"
-msgstr ""
+msgstr "¿Descartar todos los cambios?"
msgid "Discard changes"
msgstr "Descartar los cambios"
@@ -7402,10 +7760,10 @@ msgid "Discover|See the other features of the %{linkStart}gold plan%{linkEnd}"
msgstr ""
msgid "Discover|Start a free trial"
-msgstr ""
+msgstr "Iniciar una prueba gratuita"
msgid "Discover|Upgrade now"
-msgstr ""
+msgstr "Actualizar ahora"
msgid "Discuss a specific suggestion or question"
msgstr "Discuta una sugerencia específica o una pregunta"
@@ -7503,17 +7861,20 @@ msgid "Domain verification is an essential security measure for public GitLab si
msgstr "La verificación del dominio es una medida de seguridad esencial para los sitios públicos de GitLab. Los usuarios deben demostrar que administran o que son los propietarios de un dominio antes de poder habilitarlo"
msgid "Domain was successfully created."
-msgstr ""
+msgstr "El dominio se ha creado correctamente."
msgid "Domain was successfully deleted."
-msgstr ""
+msgstr "El dominio se ha eliminado correctamente."
msgid "Domain was successfully updated."
-msgstr ""
+msgstr "El dominio se ha actualizado correctamente."
msgid "Don't have an account yet?"
msgstr "¿Todavía no tiene una cuenta?"
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr "No pegue la parte privada de la clave GPG. Pegue la parte pública que empieza por: '----- BEGIN PGP PUBLIC KEY BLOCK -----'."
@@ -7562,6 +7923,9 @@ msgstr "Descargar imagen"
msgid "Download license"
msgstr "Descargar licencia"
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr "Descargar el código fuente"
@@ -7586,6 +7950,9 @@ msgstr "Voto negativo"
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr "Fecha de vencimiento"
@@ -7698,7 +8065,7 @@ msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr "Edite su comentario más reciente en un hilo (desde un cuadro de texto vacío)"
msgid "Edited %{timeago}"
-msgstr ""
+msgstr "Editado %{timeago}"
msgid "Editing"
msgstr "Editando"
@@ -7719,7 +8086,7 @@ msgid "Elasticsearch integration. Elasticsearch AWS IAM."
msgstr "Integración de Elastisearch. Elasticsearch AWS IAM."
msgid "Elasticsearch returned status code: %{status_code}"
-msgstr ""
+msgstr "Elasticsearch ha devuelto el código de estado: %{status_code}"
msgid "Elastic|None. Select namespaces to index."
msgstr "Ninguno. Seleccione los espacios de nombres a indexar."
@@ -7733,6 +8100,9 @@ msgstr "Correo electrónico"
msgid "Email address"
msgstr "Correo electrónico"
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr "Envía el estado de los pipelines a una lista de destinatarios."
@@ -7841,6 +8214,9 @@ msgstr "Habilitar autenticación SAML para este grupo"
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr "Habilitar el acceso a Grafana"
@@ -7850,9 +8226,6 @@ msgstr "Habilitar el acceso a la barra de rendimiento para un grupos determinado
msgid "Enable and configure Grafana."
msgstr "Habilitar y configurar Grafana."
-msgid "Enable and configure InfluxDB metrics."
-msgstr "Habilitar y configurar las métricas de InfluxDB."
-
msgid "Enable and configure Prometheus metrics."
msgstr "Habilitar y configurar las métricas de Prometheus."
@@ -7880,9 +8253,12 @@ msgstr "Habilitar el grupo de ejecutores"
msgid "Enable header and footer in emails"
msgstr "Habilitar el encabezado y pie de página en los correos electrónicos"
-msgid "Enable maintenance mode"
+msgid "Enable integration"
msgstr ""
+msgid "Enable maintenance mode"
+msgstr "Habilitar el modo de mantenimiento"
+
msgid "Enable mirror configuration"
msgstr "Habilitar configuración de espejo"
@@ -7935,10 +8311,10 @@ msgid "EnableReviewApp|%{stepStart}Step 3%{stepEnd}. Add it to the project %{lin
msgstr ""
msgid "EnableReviewApp|Close"
-msgstr ""
+msgstr "Cerrar"
msgid "EnableReviewApp|Copy snippet text"
-msgstr ""
+msgstr "Copia el fragmento de texto"
msgid "Enabled"
msgstr "Habilitado"
@@ -7953,7 +8329,7 @@ msgid "Enabling this will only make licensed EE features available to projects i
msgstr "Habilitar esta opción solo hará que las funciones con licencia EE estén disponibles para los proyectos si el plan del espacio de nombres del proyecto incluye esta opción o si el proyecto es público."
msgid "Encountered an error while rendering: %{err}"
-msgstr ""
+msgstr "Se ha producido un error al renderizar: %{err}"
msgid "End date"
msgstr "Fecha de finalización"
@@ -7971,7 +8347,7 @@ msgid "Ensure your %{linkStart}environment is part of the deploy stage%{linkEnd}
msgstr ""
msgid "Enter 2FA for Admin Mode"
-msgstr ""
+msgstr "Introduzca el 2FA para el modo de administración"
msgid "Enter Admin Mode"
msgstr "Entrar en el modo de administración"
@@ -7983,7 +8359,7 @@ msgid "Enter a number"
msgstr "Introduzca un número"
msgid "Enter a whole number between 0 and 100"
-msgstr ""
+msgstr "Introduzca un número entero entre 0 y 100"
msgid "Enter at least three characters to search"
msgstr "Introduzca al menos tres caracteres para buscar"
@@ -8003,14 +8379,17 @@ msgstr "Introduzca la URL de su servidor Phabricator y su token de acceso"
msgid "Enter merge request URLs"
msgstr "Introduzca las URL de la solicitud de fusión"
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr "Introduzca su nueva AWS Secret Acess Key"
msgid "Enter number of issues"
-msgstr ""
+msgstr "Introduzca el número de incidencias"
msgid "Enter one or more user ID separated by commas"
-msgstr ""
+msgstr "Introduzca uno o más ID de usuario separados por comas"
msgid "Enter the code from the two-factor app on your mobile device. If you've lost your device, you may enter one of your recovery codes."
msgstr ""
@@ -8027,12 +8406,12 @@ msgstr "Introduzca la descripción del merge request"
msgid "Enter the merge request title"
msgstr "Introduzca el título del merge request"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
+msgstr ""
+
msgid "Enter your password to approve"
msgstr "Introduzca su contraseña para aprobar"
-msgid "Enter zen mode"
-msgstr "Acceder al modo zen"
-
msgid "Environment"
msgstr "Entorno"
@@ -8055,10 +8434,10 @@ msgid "EnvironmentDashboard|API"
msgstr "API"
msgid "EnvironmentDashboard|Created through the Deployment API"
-msgstr ""
+msgstr "Creado a través del API de despliegue"
msgid "EnvironmentDashboard|You are looking at the last updated environment"
-msgstr ""
+msgstr "Está viendo el último entorno actualizado"
msgid "Environments"
msgstr "Entornos"
@@ -8087,8 +8466,8 @@ msgstr "Trabajo: %{job}"
msgid "EnvironmentsDashboard|More actions"
msgstr "Más acciones"
-msgid "EnvironmentsDashboard|Read more."
-msgstr "Leer más."
+msgid "EnvironmentsDashboard|More information"
+msgstr ""
msgid "EnvironmentsDashboard|Remove"
msgstr "Eliminar"
@@ -8097,13 +8476,13 @@ msgid "EnvironmentsDashboard|The environments dashboard provides a summary of ea
msgstr "El panel de control de entornos proporciona un resumen detallado del estado de los entornos de cada proyecto, incluidos los estados de alerta y de los pipelines."
msgid "EnvironmentsDashboard|This dashboard displays a maximum of 7 projects and 3 environments per project. %{readMoreLink}"
-msgstr ""
+msgstr "Este panel muestra un máximo de 7 proyectos y 3 entornos por proyecto. %{readMoreLink}"
msgid "Environments|An error occurred while canceling the auto stop, please try again"
-msgstr ""
+msgstr "Se ha producido un error al cancelar la parada automática, inténtelo de nuevo"
msgid "Environments|An error occurred while deleting the environment. Check if the environment stopped; if not, stop it and try again."
-msgstr ""
+msgstr "Se ha producido un error al eliminar el entorno. Por favor, compruebe si el entorno se ha detenido; si no, detenenlo e inténtalo de nuevo."
msgid "Environments|An error occurred while fetching the environments."
msgstr "Se ha producido un error al recuperar los entornos."
@@ -8133,16 +8512,16 @@ msgid "Environments|Commit"
msgstr "Commit"
msgid "Environments|Currently showing %{fetched} results."
-msgstr ""
+msgstr "Environments|Mostrando %{fetched} resultados."
msgid "Environments|Currently showing all results."
-msgstr ""
+msgstr "Environments|Mostrando todos los resultados."
msgid "Environments|Delete"
-msgstr ""
+msgstr "Eliminar"
msgid "Environments|Delete environment"
-msgstr ""
+msgstr "Eliminar entorno"
msgid "Environments|Deleting the '%{environmentName}' environment cannot be undone. Do you want to delete it anyway?"
msgstr ""
@@ -8178,7 +8557,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 ""
+msgstr "Environments|Logs desde %{start} hasta %{end}."
msgid "Environments|New environment"
msgstr "Nuevo entorno"
@@ -8190,7 +8569,7 @@ msgid "Environments|No deployments yet"
msgstr "Todavía no hay despliegues"
msgid "Environments|No pod selected"
-msgstr ""
+msgstr "Environments|No hay nigún pod seleccionado"
msgid "Environments|No pods to display"
msgstr "No hay pods para mostrar"
@@ -8205,7 +8584,7 @@ msgid "Environments|Open live environment"
msgstr ""
msgid "Environments|Pod name"
-msgstr ""
+msgstr "Nombre del Pod"
msgid "Environments|Re-deploy"
msgstr "Re-desplegar"
@@ -8300,27 +8679,21 @@ msgstr "Las tareas épicas le permiten administrar sus proyectos de manera más
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
-msgstr "Añadir una tarea épica"
+msgid "Epics|Add a new epic"
+msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
-msgstr "Añadir una tarea épica existente como sub tarea épica."
+msgid "Epics|Add an existing epic"
+msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
msgstr "Se ha producido un error mientras se guardaba la fecha tipo %{epicDateType}"
msgid "Epics|An error occurred while updating labels."
-msgstr ""
+msgstr "Se ha producido un error al actualizar las etiquetas."
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr "¿Está seguro de que desea eliminar %{bStart}%{targetIssueTitle}%{bEnd} de %{bStart}%{parentEpicTitle}%{bEnd}?"
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr "Cree una tarea épica dentro de este grupo y agréguela como una tarea épica hija."
-
-msgid "Epics|Create new epic"
-msgstr "Crear nueva épica"
-
msgid "Epics|How can I solve this?"
msgstr "¿Cómo puedo resolver esto?"
@@ -8390,8 +8763,17 @@ msgstr "Error al crear la tarea épica"
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr "Se ha producido un error al eliminar %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
+msgstr ""
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -8495,9 +8877,6 @@ msgstr "Se ha producido un error. El usuario no estaba desbloqueado"
msgid "Error rendering markdown preview"
msgstr "Se ha producido un error al renderizar la vista previa de markdown"
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr "Se ha producido un error al guardar la actualización de la etiqueta."
@@ -8513,6 +8892,9 @@ msgstr "Se ha producido un error al actualizar el estado de todas las tareas pen
msgid "Error updating status of to-do item."
msgstr "Se ha producido un error al actualizar el estado de la tarea pendiente."
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr "Se ha producido un error al enviar el fichero"
@@ -8562,14 +8944,14 @@ msgid "Errors"
msgstr "Errores"
msgid "Errors:"
+msgstr "Errores:"
+
+msgid "Estimate"
msgstr ""
msgid "Estimated"
msgstr "Estimado"
-msgid "Event Actions"
-msgstr ""
-
msgid "EventFilterBy|Filter by all"
msgstr "Filtrar por todos"
@@ -8609,14 +8991,14 @@ msgstr "Cada intento de %{action} ha fallado: %{job_error_message}. Por favor, i
msgid "Every day"
msgstr "Diario"
-msgid "Every day (at 4:00am)"
-msgstr "Todos los días (a las 4:00 am)"
+msgid "Every day (at %{time})"
+msgstr ""
msgid "Every month"
msgstr "Cada mes"
-msgid "Every month (on the 1st at 4:00am)"
-msgstr "Todos los meses (el día 1 a las 4:00 am)"
+msgid "Every month (Day %{day} at %{time})"
+msgstr ""
msgid "Every three months"
msgstr "Cada tres meses"
@@ -8627,8 +9009,8 @@ msgstr "Cada dos semanas"
msgid "Every week"
msgstr "Cada semana"
-msgid "Every week (Sundays at 4:00am)"
-msgstr "Todas las semanas (domingos a las 4:00 am)"
+msgid "Every week (%{weekday} at %{time})"
+msgstr ""
msgid "Everyone"
msgstr "Todo el mundo"
@@ -8666,6 +9048,9 @@ msgstr "Recopilación de evidencias"
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr "Ejemplo: @sub\\.empresa\\.com$"
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr "Miembros y grupos existentes"
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr "Expandir barra lateral"
msgid "Expand up"
msgstr "Expandir todo"
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr "Vencimiento"
@@ -8732,6 +9123,9 @@ msgstr "Caducó"
msgid "Expired %{expiredOn}"
msgstr "Caducado el %{expiredOn}"
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr "Caduca"
@@ -8741,9 +9135,12 @@ msgstr "Caduca a las"
msgid "Expires in %{expires_at}"
msgstr "Caduca en %{expires_at}"
-msgid "Expires:"
+msgid "Expires on"
msgstr ""
+msgid "Expires:"
+msgstr "Caduca:"
+
msgid "Explain the problem. If appropriate, provide a link to the relevant issue or comment."
msgstr "Explique el problema. Si es necesario, proporcione un enlace al problema o a un comentario relevante."
@@ -8769,7 +9166,7 @@ msgid "Export as CSV"
msgstr "Exportar como CSV"
msgid "Export group"
-msgstr ""
+msgstr "Exportar grupo"
msgid "Export issues"
msgstr "Exportar incidencias"
@@ -8819,18 +9216,6 @@ msgstr "Etiqueta de clasificación"
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr "Cuando no existe ninguna etiqueta de clasificación se utilizará la etiqueta predeterminada `%{default_label}'."
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr "Agregue un botón al panel de control de métricas que se enlaza directamente con sus paneles de control externos existentes."
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr "Introduzca la URL del panel de control que desea enlazar"
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr "Panel de control externo"
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr "URL completa del panel del control"
-
msgid "ExternalWikiService|External Wiki"
msgstr "Wiki externo"
@@ -8883,13 +9268,13 @@ msgid "Failed to create import label for jira import."
msgstr ""
msgid "Failed to create repository"
-msgstr ""
+msgstr "Se ha producido un error al crear el repositorio"
msgid "Failed to create resources"
msgstr "Se ha producido un error al crear los recursos"
msgid "Failed to create wiki"
-msgstr ""
+msgstr "Se ha producido un error al crear el wiki"
msgid "Failed to delete board. Please try again."
msgstr "Se ha producido un error al eliminar el panel de control. Por favor, inténtelo de nuevo."
@@ -8957,6 +9342,9 @@ msgstr "Se ha producido un error al proteger la rama"
msgid "Failed to protect the environment"
msgstr "Se ha producido un error al proteger el entorno"
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr "Se ha producido un error al eliminar una reunión de Zoom"
@@ -9027,12 +9415,12 @@ msgid "Failure"
msgstr "Error"
msgid "False positive"
-msgstr ""
+msgstr "Falso positivo"
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr "Descripción"
msgid "FeatureFlags|Edit Feature Flag"
msgstr "Editar Feature Flag"
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr "Especificaciones del entorno"
msgid "FeatureFlags|Feature Flag"
msgstr "Feature Flag"
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr "Feature Flags"
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
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?"
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr "ID"
@@ -9143,6 +9549,9 @@ msgstr "Instale un %{docs_link_anchored_start}cliente compatible con la bibliote
msgid "FeatureFlags|Instance ID"
msgstr "ID de instancia"
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr "Nuevo"
msgid "FeatureFlags|New Feature Flag"
msgstr "Nueva Feature Flag"
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9234,7 +9649,7 @@ msgid "Fetching licenses failed. You are not permitted to perform this action."
msgstr "Se ha producido un error al obtener las licencias. No está autorizado a realizar esta acción."
msgid "File"
-msgstr ""
+msgstr "Archivo"
msgid "File Hooks"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr "Explorador de archivos"
msgid "File deleted"
msgstr "Archivo eliminado"
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr "Archivo movido"
msgid "File name"
msgstr "Nombre del archivo"
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr "Plantillas de archivos"
msgid "File upload error."
msgstr "Error al subir el archivo."
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr "Archivos"
@@ -9290,38 +9708,62 @@ msgstr "Rellene los siguientes campos, active <strong>%{enable_label}</strong>y
msgid "Filter"
msgstr "Filtro"
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr "Filtrar por %{issuable_type} que actualmente estén cerrados."
msgid "Filter by %{issuable_type} that are currently opened."
msgstr "Filtrar por %{issuable_type} que actualmente estén abiertos."
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr "Filtrar por mensaje del cambio"
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr "Filtrar por nombre del hito"
msgid "Filter by name"
+msgstr "Filtrar por nombre"
+
+msgid "Filter by requirements that are currently archived."
msgstr ""
-msgid "Filter by status"
+msgid "Filter by requirements that are currently opened."
msgstr ""
+msgid "Filter by status"
+msgstr "Filtrar por estado"
+
msgid "Filter by two-factor authentication"
msgstr "Filtrar por autenticación de dos factores"
msgid "Filter by user"
msgstr "Filtrar por usuario"
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr "Filtrar proyectos"
msgid "Filter results"
-msgstr ""
+msgstr "Filtrar resultados"
msgid "Filter results by group"
msgstr "Filtrar resultados por grupo"
@@ -9330,7 +9772,7 @@ msgid "Filter results by project"
msgstr "Filtrar resultados por proyecto"
msgid "Filter results..."
-msgstr ""
+msgstr "Filtrar resultados..."
msgid "Filter your projects by name"
msgstr "Filtra sus proyectos por nombre"
@@ -9548,9 +9990,6 @@ msgstr "Desde la creación de la incidencia hasta el despliegue a producción"
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 "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr "Desde la vista de detalles del clúster de Kubernetes, seleccione instalar 'runner' desde la lista de aplicaciones"
@@ -9590,15 +10029,15 @@ msgstr "Generar nueva exportación"
msgid "Geo"
msgstr "Geo"
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr "Geo Nodos"
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr "%{name} está programado para una nueva descarga forzada"
@@ -9785,10 +10230,10 @@ msgstr "%{name} está programado para volver a sincronizar"
msgid "Geo|%{name} is scheduled for re-verify"
msgstr "Se ha programado %{name} para que se vuelva a comprobar"
-msgid "Geo|All"
-msgstr "Todos"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9810,13 +10255,13 @@ msgid "Geo|Failed"
msgstr "Fallido"
msgid "Geo|Filter by status"
-msgstr ""
+msgstr "Filtrar por estado"
msgid "Geo|Geo Status"
msgstr "Estado de Geo"
msgid "Geo|In progress"
-msgstr ""
+msgstr "En curso"
msgid "Geo|In sync"
msgstr "Sincronizado"
@@ -9839,6 +10284,12 @@ msgstr "Nunca"
msgid "Geo|Next sync scheduled at"
msgstr "Próxima sincronización programada en"
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr "Sin sincronizar aún"
@@ -9870,7 +10321,7 @@ msgid "Geo|Remove"
msgstr "Eliminar"
msgid "Geo|Remove entry"
-msgstr ""
+msgstr "Eliminar entrada"
msgid "Geo|Remove tracking database entry"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr "Volver a comprobar"
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr "Estado"
@@ -9908,6 +10362,9 @@ msgstr "La base de datos está %{db_lag} detrás del nodo primario."
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|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr "La entrada de seguimiento del proyecto (%{project_id}) se eliminó corre
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr "La entrada de seguimiento de carga (%{type}/%{id}) se ha eliminado correctamente."
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr "Estado desconocido"
@@ -9945,7 +10408,7 @@ msgid "Get a free instance review"
msgstr "Obtenga una revisión de instancia gratuita"
msgid "Get started"
-msgstr ""
+msgstr "Empezar"
msgid "Get started with error tracking"
msgstr "Comenzar con el control de errores"
@@ -9993,7 +10456,7 @@ msgid "GitHub import"
msgstr "Importar desde GitHub"
msgid "GitLab / Unsubscribe"
-msgstr ""
+msgstr "GitLab / Darse de baja"
msgid "GitLab Enterprise Edition %{plan}"
msgstr "GitLab Enterprise Edition %{plan}"
@@ -10011,10 +10474,10 @@ msgid "GitLab Shared Runners execute code of different projects on the same Runn
msgstr "Los ejecutores compartidos de GitLab ejecutan el código de diferentes proyectos en el mismo ejecutor a menos que configure el auto escalado de os ejecutores de GitLab con MaxBuilds 1 (que se encuentra en GitLab.com)."
msgid "GitLab Support Bot"
-msgstr ""
+msgstr "Bot de soporte de GitLab"
msgid "GitLab Team Member"
-msgstr ""
+msgstr "Miembro del equipo de GitLab"
msgid "GitLab User"
msgstr "Usuario de GitLab"
@@ -10169,9 +10632,6 @@ msgstr "URL del host de Gitea"
msgid "Gitea Import"
msgstr "Importar desde Gitea"
-msgid "Gitlab CI/CD"
-msgstr "Gitlab CI/CD"
-
msgid "Gitlab Pages"
msgstr "GitLab Pages"
@@ -10205,9 +10665,6 @@ msgstr "Vuelva a %{startTag}Incidencias abiertas%{endTag} y seleccione alguna de
msgid "Go full screen"
msgstr "Ir a pantalla completa"
-msgid "Go to"
-msgstr "Ir a"
-
msgid "Go to %{link_to_google_takeout}."
msgstr "Ir a %{link_to_google_takeout}."
@@ -10370,12 +10827,21 @@ msgstr "Gravatar habilitado"
msgid "Group"
msgstr "Grupo"
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr "Se ha programado el grupo %{group_name} para su eliminación."
msgid "Group %{group_name} was successfully created."
msgstr "El grupo %{group_name} se actualizó correctamente."
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr "URL del grupo"
msgid "Group avatar"
msgstr "Avatar del grupo"
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr "Descripción del grupo"
@@ -10421,10 +10893,13 @@ msgstr "Detalles del grupo"
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,14 +10917,17 @@ msgstr "Los mantenedores de grupo pueden registrar grupos de ejecutores en el %{
msgid "Group members"
msgstr "Miembros del grupo"
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr "Nombre del grupo"
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
-msgstr "Resumen del grupo"
+msgstr "Descripción general del grupo"
msgid "Group overview content"
msgstr "Resumen del contenido del grupo"
@@ -10463,12 +10941,18 @@ msgstr "La ruta del grupo está disponible."
msgid "Group pipeline minutes were successfully reset."
msgstr "La cuota de minutos del pipeline fue restablecida con éxito."
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr "Variables de grupo (heredadas)"
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr "Grupo actualizado correctamente."
@@ -10535,9 +11019,6 @@ msgstr "Habilitar la autenticación SAML para este grupo."
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr "Forzar autenticación SSO para este grupo."
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr "Forzar la autenticación mediante SSO para este grupo."
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr "Obligar a los usuarios tener cuentas administradas de grupo dedicadas para este grupo."
@@ -10674,7 +11155,7 @@ msgid "GroupSettings|Disable group mentions"
msgstr "Desactivar las menciones de grupo"
msgid "GroupSettings|Export group"
-msgstr ""
+msgstr "Exportar grupo"
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 "Si la visibilidad del grupo principal es menor que la visibilidad actual del grupo, los niveles de visibilidad para subgrupos y proyectos se cambiarán para que coincidan con la visibilidad del nuevo grupo principal."
@@ -10739,6 +11220,9 @@ msgstr "Sólo puede transferir el grupo a un grupo que administre."
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr "Necesitará actualizar sus repositorios locales para apuntar a la nueva ubicación."
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr "No se puede deshabilitar cuando el grupo principal \"Compartir con bloqueo de grupo\" está habilitado, excepto por el propietario del grupo principal"
@@ -10755,13 +11239,13 @@ msgid "Groups (%{count})"
msgstr "Grupos: (%{count})"
msgid "Groups (%{groups})"
-msgstr ""
+msgstr "Grupos (%{groups})"
msgid "Groups can also be nested by creating %{subgroup_docs_link_start}subgroups%{subgroup_docs_link_end}."
msgstr "Los grupos también se pueden anidar creando %{subgroup_docs_link_start}subgrupos%{subgroup_docs_link_end}."
msgid "Groups to synchronize"
-msgstr ""
+msgstr "Grupos para sincronizar"
msgid "Groups with access to %{strong_start}%{group_name}%{strong_end}"
msgstr "Grupos con acceso a %{strong_start}%{group_name}%{strong_end}"
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,9 +11340,12 @@ msgstr "Se ha eliminado el logo del encabezado correctamente."
msgid "Header message"
msgstr "Encabezado del mensaje"
-msgid "Health"
+msgid "Headings"
msgstr ""
+msgid "Health"
+msgstr "Salud"
+
msgid "Health Check"
msgstr "Verificación de estado"
@@ -10959,6 +11449,9 @@ msgstr "Historial"
msgid "History of authentications"
msgstr "Historial de autentificación"
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr "Falló la ejecución del hook. Asegúrese de que el grupo tiene, al menos, un proyecto con commits."
@@ -10968,9 +11461,12 @@ msgstr "El hook se ha creado correctamente."
msgid "Hook was successfully updated."
msgstr "El hook se actualizó correctamente."
-msgid "Hour (UTC)"
+msgid "Hostname"
msgstr ""
+msgid "Hour (UTC)"
+msgstr "Hora (UTC)"
+
msgid "Housekeeping"
msgstr "Mantenimiento"
@@ -11118,6 +11614,9 @@ msgstr "Si está habilitado, el acceso a los proyectos se validará en un servic
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr "Si esto fue un error puede %{leave_link_start}dejar el %{source_type}%{link_end}."
@@ -11127,8 +11626,11 @@ msgstr "Si esto fue un error puede dejar el %{source_type}."
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr "Si utiliza GitHub, verá los estados del pipeline en GitHub para sus commit y sus pull request. %{more_info_link}"
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
-msgstr "Si cree que esto puede ser un error, consulte la documentación para la solución de problemas de Geo %{linkStart}%{linkEnd} para obtener más información."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
+msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
msgstr "Si pierde los códigos de recuperación, puede generar otros nuevos, invalidando todos los códigos anteriores."
@@ -11136,6 +11638,12 @@ msgstr "Si pierde los códigos de recuperación, puede generar otros nuevos, inv
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr "Si su repositorio HTTP no es accesible públicamente, añada sus credenciales."
@@ -11146,10 +11654,13 @@ msgid "Ignore"
msgstr "Ignorar"
msgid "Ignored"
+msgstr "Ignorado"
+
+msgid "Image Details"
msgstr ""
-msgid "Image: %{image}"
-msgstr "Imagen: %{image}"
+msgid "Image URL"
+msgstr ""
msgid "ImageDiffViewer|2-up"
msgstr "2-up"
@@ -11166,15 +11677,15 @@ msgstr "Alto"
msgid "ImageViewerDimensions|W"
msgstr "Ancho"
+msgid "Impersonation Tokens"
+msgstr ""
+
msgid "Impersonation has been disabled"
msgstr "La suplantación ha sido deshabilitada"
msgid "Import"
msgstr "Importar"
-msgid "Import %{status}"
-msgstr ""
-
msgid "Import CSV"
msgstr "Importar CSV"
@@ -11184,6 +11695,9 @@ msgstr "Importar proyectos desde Gitea"
msgid "Import all compatible projects"
msgstr "Importar todos los proyectos compatibles"
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr "Importar todos los proyectos"
@@ -11193,21 +11707,24 @@ msgstr "Importar todos los repositorios"
msgid "Import an exported GitLab project"
msgstr "Importar un proyecto exportado desde GitLab"
-msgid "Import from"
+msgid "Import failed due to a GitHub error: %{original}"
msgstr ""
+msgid "Import from"
+msgstr "Importar desde"
+
msgid "Import from Jira"
-msgstr ""
+msgstr "Importado desde JIRA"
msgid "Import in progress"
msgstr "Importación en progreso"
+msgid "Import in progress. Refresh page to see newly added issues."
+msgstr ""
+
msgid "Import issues"
msgstr "Importar incidencias"
-msgid "Import issues from Jira"
-msgstr ""
-
msgid "Import members"
msgstr "Importar miembros"
@@ -11248,7 +11765,7 @@ msgid "Import repository"
msgstr "Importar repositorio"
msgid "Import started by: %{importInitiator}"
-msgstr ""
+msgstr "Importación iniciada por: %{importInitiator}"
msgid "Import tasks"
msgstr "Importar tareas"
@@ -11298,12 +11815,12 @@ msgstr "Mejore los tableros de incidencias con GitLab Enterprise Edition."
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr "Mejore los merge request y la atención al cliente con GitLab Enterprise Edition."
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
-msgstr "Mejore la gestión de incidencias con Issue weight y GitLab Enterprise Edition."
-
msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr "Mejore la búsqueda con Advanced Global Search y GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
+msgstr ""
+
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
msgstr "Con el fin de permitir el análisis a nivel de instancia, por favor solicite a un administrador que habilite %{usage_ping_link_start}el uso de ping%{usage_ping_link_end}."
@@ -11311,13 +11828,13 @@ msgid "In order to gather accurate feature usage data, it can take 1 to 2 weeks
msgstr "Con el fin de recopilar datos precisos sobre los datos de uso, es posible que tarde de 1 a 2 semanas en poder ver su índice."
msgid "In order to personalize your experience with GitLab<br>we would like to know a bit more about you."
-msgstr ""
+msgstr "Con el fin de adaptar su experiencia con GitLab<br>nos gustaría saber un poco más sobre usted."
msgid "In order to tailor your experience with GitLab we<br>would like to know a bit more about you."
msgstr "Para personalizar su experiencia con GitLab <br>nos gustaría conocer un poco más sobre usted."
msgid "In progress"
-msgstr ""
+msgstr "En progreso"
msgid "In the next step, you'll be able to select the projects you want to import."
msgstr "En el siguiente paso, podrá seleccionar los proyectos que desea importar."
@@ -11334,6 +11851,9 @@ msgstr "Incluya un acuerdo de términos de servicio y una política de privacida
msgid "Include author name in notification email body"
msgstr "Incluir el nombre del autor en el cuerpo del correo electrónico de notificación"
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr "Introduzca la descripción del merge request"
@@ -11353,13 +11873,13 @@ msgid "Includes an MVC structure, mvnw and pom.xml to help you get started."
msgstr "Incluye una estructura MVC, mvnw y pom.xml para ayudarle a comenzar."
msgid "Includes repository storage, wiki storage, LFS objects, build artifacts and packages. 0 for unlimited."
-msgstr ""
+msgstr "Incluye almacenamiento del repositorio, almacenamiento del wiki, objetos LFS, artefactos de compilación y paquetes. 0 para ilimitado."
msgid "Incoming email"
msgstr "Correo electrónico entrante"
msgid "Incoming!"
-msgstr ""
+msgstr "¡Entrante!"
msgid "Incompatible Project"
msgstr "Proyecto incompatible"
@@ -11367,6 +11887,12 @@ msgstr "Proyecto incompatible"
msgid "Incompatible options set!"
msgstr "¡Conjunto de opciones incompatibles configuradas!"
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr "Indexar todos los proyectos"
@@ -11391,18 +11917,36 @@ msgstr "Introducir las claves del host manualmente"
msgid "Input your repository URL"
msgstr "Introduzca la URL de su repositorio"
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr "Insertar una cita"
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr "Insertar código"
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr "Insertar sugerencia"
msgid "Insights"
msgstr "Insights"
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr "Instalar"
@@ -11442,15 +11986,39 @@ msgid "Instance license"
msgstr "Licencia de la instancia"
msgid "Integration"
-msgstr ""
+msgstr "Integración"
msgid "Integration Settings"
-msgstr ""
+msgstr "Ajustes de integración"
msgid "Integrations"
msgstr "Integraciones"
msgid "Integrations allow you to integrate GitLab with other applications"
+msgstr "Las integraciones le permiten integrar GitLab con otras aplicaciones"
+
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
msgstr ""
msgid "Interested parties can even contribute by pushing commits if they want to."
@@ -11466,7 +12034,7 @@ msgid "Internal - The project can be accessed by any logged in user."
msgstr "Interno - cualquier usuario haya iniciado sesión puede acceder a este proyecto."
msgid "Internal URL (optional)"
-msgstr ""
+msgstr "URL interna (opcional)"
msgid "Internal users"
msgstr "Usuarios internos"
@@ -11492,6 +12060,12 @@ msgstr "Inicio de sesión o contraseña no válida"
msgid "Invalid URL"
msgstr "URL no válida"
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr "Nombre de usuario o contraseña no válidos"
msgid "Invalid pin code"
msgstr "Código PIN inválido."
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr "Consulta no válida"
msgid "Invalid repository path"
msgstr "Ruta del repositorio no válida"
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr "Respuesta del servidor no válida"
msgid "Invalid start or end time format"
msgstr "Formato de hora inicial o final no válido"
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr "Código de dos factores no válido."
@@ -11552,6 +12135,9 @@ msgstr "Invitar"
msgid "Invite \"%{trimmed}\" by email"
msgstr "Invitar a \"%{trimmed}\" por correo electrónico"
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr "Invitar al grupo"
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr "Plantilla de la incidencia (opcional)"
@@ -11627,6 +12216,33 @@ msgstr "La incidencia fue cerrada por %{name} %{reason}"
msgid "Issue weight"
msgstr "Peso de la incidencia"
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr "Tablero"
@@ -11684,6 +12300,9 @@ msgstr "Incidencias cerradas"
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr "Incidencias con comentarios, merge requests con diffs y comentarios, etiquetas, hitos, fragmentos de código y otras entidades de proyecto"
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr "¡Es usted!"
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr "URL de Jaeger"
@@ -11741,19 +12384,22 @@ msgstr "Ene"
msgid "January"
msgstr "Enero"
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
-msgstr ""
+msgid "Jira integration not configured."
+msgstr "Integración con Jira no configurada."
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
+msgstr "Proyecto Jira: %{importProject}"
+
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira integration not configured."
+msgid "JiraService| on branch %{branch_link}"
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr "Se han eliminado los artefactos"
msgid "Job|The artifacts will be removed"
msgstr "Los artefactos serán eliminados"
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr "Este trabajo falló porque los recursos necesarios no se crearon correctamente."
@@ -11916,6 +12565,9 @@ msgid "June"
msgstr "Junio"
msgid "Just me"
+msgstr "Solo yo"
+
+msgid "Keep divergent refs"
msgstr ""
msgid "Key"
@@ -11931,7 +12583,7 @@ msgid "Keyboard Shortcuts"
msgstr "Atajos de teclado"
msgid "Keyboard shortcuts"
-msgstr ""
+msgstr "Atajos de teclado"
msgid "Kubernetes"
msgstr "Kubernetes"
@@ -11946,7 +12598,7 @@ msgid "Kubernetes Clusters"
msgstr "Clúster de Kubernetes"
msgid "Kubernetes cluster"
-msgstr ""
+msgstr "Clúster de Kubernetes"
msgid "Kubernetes cluster creation time exceeds timeout; %{timeout}"
msgstr "El tiempo de creación del clúster de Kubernetes excede el tiempo de espera; %{timeout}"
@@ -11976,7 +12628,7 @@ msgid "LDAP settings"
msgstr "Configuración LDAP"
msgid "LDAP settings updated"
-msgstr ""
+msgstr "Configuración de LDAP actualizada"
msgid "LDAP sync in progress. This could take a few minutes. Refresh the page to see the changes."
msgstr "Sincronización LDAP en curso. Esto podría tardar unos minutos. Por favor, actualice la página para ver los cambios."
@@ -12097,6 +12749,9 @@ msgstr "Apellido(s)"
msgid "Last reply by"
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"
@@ -12161,7 +12816,7 @@ msgid "Learn how to %{no_packages_link_start}publish and share your packages%{no
msgstr "Aprenda como %{no_packages_link_start}publicar y compartir sus paquetes%{no_packages_link_end} con GitLab."
msgid "Learn how to enable synchronization"
-msgstr ""
+msgstr "Aprenda cómo habilitar la sincronización"
msgid "Learn more"
msgstr "Conozca más"
@@ -12181,6 +12836,9 @@ msgstr "Más información sobre la revisión de vulnerabilidades"
msgid "Learn more about Web Terminal"
msgstr "Aprenda más sobre la Terminal Web"
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr "Obtenga más información sobre cómo agregar certificados a su proyecto siguiendo la documentación %{docs_link_start}en las páginas%{docs_link_end}GitLab."
@@ -12202,9 +12860,6 @@ msgstr "Más información sobre los commits firmados"
msgid "Learn more about the dependency list"
msgstr "Obtenga más información sobre la lista de dependencias"
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr "Más información en la"
@@ -12232,6 +12887,9 @@ msgstr "Abandonar proyecto"
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr "Deja las opciones \"Tipo de archivo\" y \"Método de entrega\" con sus valores por defecto."
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr "Let's Encrypt no acepta correos electrónicos de example.com"
@@ -12244,6 +12902,9 @@ msgstr "Licencia"
msgid "License Compliance"
msgstr "License Compliance"
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr "Comprobación de licencia"
@@ -12254,29 +12915,23 @@ msgid "LicenseCompliance|Add license and related policy"
msgstr ""
msgid "LicenseCompliance|Allow"
-msgstr ""
+msgstr "Permitir"
msgid "LicenseCompliance|Allowed"
-msgstr ""
+msgstr "Permitido"
msgid "LicenseCompliance|Cancel"
msgstr "Cancelar"
msgid "LicenseCompliance|Denied"
-msgstr ""
+msgstr "Denegado"
msgid "LicenseCompliance|Deny"
-msgstr ""
-
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
+msgstr "Denegar"
msgid "LicenseCompliance|License"
msgstr "Licencia"
-msgid "LicenseCompliance|License Compliance"
-msgstr "License Compliance"
-
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] ""
@@ -12367,7 +13022,7 @@ msgid "Licenses|Components"
msgstr "Componentes"
msgid "Licenses|Detected in Project"
-msgstr ""
+msgstr "Detectado en proyecto"
msgid "Licenses|Detected licenses that are out-of-compliance with the project's assigned policies"
msgstr ""
@@ -12388,10 +13043,10 @@ msgid "Licenses|Name"
msgstr "Nombre"
msgid "Licenses|Policies"
-msgstr ""
+msgstr "Políticas"
msgid "Licenses|Policy"
-msgstr ""
+msgstr "Política"
msgid "Licenses|Policy violation: denied"
msgstr ""
@@ -12411,6 +13066,9 @@ msgstr "Comprar licencia"
msgid "License|License"
msgstr "Licencia"
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr "Puede restaurar el acceso a las características Gold en cualquier momento haciendo una actualización."
@@ -12426,6 +13084,9 @@ msgstr "Su licencia"
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr "Su periodo de prueba gratuito de GitLab Ultimate finalizó el %{trial_ends_on}."
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr "Limitar la visualización de las unidades de seguimiento de tiempo a horas."
@@ -12495,7 +13156,7 @@ msgid "Live preview"
msgstr "Vista previa"
msgid "Loading"
-msgstr ""
+msgstr "Cargando"
msgid "Loading contribution stats for group members"
msgstr "Cargando las estadísticas de las colaboraciones de los miembros del grupo"
@@ -12521,11 +13182,14 @@ msgstr "Cargando..."
msgid "Loading…"
msgstr "Cargando…"
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr "Localización"
msgid "Location"
-msgstr ""
+msgstr "Ubicación"
msgid "Lock"
msgstr "Bloquear"
@@ -12618,7 +13282,7 @@ msgid "Made this issue confidential."
msgstr "Convierte este problema en confidencial."
msgid "Maintenance mode"
-msgstr ""
+msgstr "Modo mantenimiento"
msgid "Make and review changes in the browser with the Web IDE"
msgstr "Realice y revise los cambios en el navegador con el Web IDE"
@@ -12635,12 +13299,12 @@ msgstr "Asegúrese de guardarlo, no podrá volver a acceder a él."
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr "Asegúrese de haber iniciado sesión en la cuenta que posee los proyectos que desea importar."
+msgid "Make this epic confidential"
+msgstr ""
+
msgid "Makes this issue confidential."
msgstr "Convierte la incidencia en confidencial."
-msgid "Malformed string"
-msgstr "Cadena mal formada"
-
msgid "Manage"
msgstr "Administrar"
@@ -12665,6 +13329,9 @@ msgstr "Administrar etiquetas de grupo"
msgid "Manage labels"
msgstr "Administrar etiquetas"
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr "Administrar etiquetas de proyectos"
@@ -12672,10 +13339,10 @@ msgid "Manage two-factor authentication"
msgstr "Administrar autenticación de dos factores"
msgid "Manage your license"
-msgstr ""
+msgstr "Administrar su licencia"
msgid "Managed Account"
-msgstr ""
+msgstr "Cuenta gestionada"
msgid "Manifest"
msgstr "Manifiesto"
@@ -12716,9 +13383,6 @@ msgstr "Marcar como completado"
msgid "Mark as resolved"
msgstr "Marcar como resuelto"
-msgid "Mark comment as resolved"
-msgstr "Marcar comentario como resuelto"
-
msgid "Mark this issue as a duplicate of another issue"
msgstr "Marque esta incidencia como duplicada de otra incidencia"
@@ -12728,9 +13392,6 @@ msgstr "Marque esta incidencia como relacionada con otra incidencia"
msgid "Markdown"
msgstr "Markdown"
-msgid "Markdown Help"
-msgstr "Ayuda de Markdown"
-
msgid "Markdown enabled"
msgstr "Markdown habilitado"
@@ -12762,7 +13423,7 @@ msgid "Marks this issue as related to %{issue_ref}."
msgstr "Marca esta incidencia como una incidencia relacionada con %{issue_ref}."
msgid "Mask variable"
-msgstr ""
+msgstr "Enmascarar variable"
msgid "Match not found; try refining your search query."
msgstr "No se encontró la coincidencia; por favor refine la consulta de su búsqueda."
@@ -12774,7 +13435,7 @@ msgid "MattermostService|Command trigger word"
msgstr ""
msgid "MattermostService|Fill in the word that works best for your team."
-msgstr ""
+msgstr "MattermostService|Escriba la palabra que mejor describa a su equipo."
msgid "MattermostService|Request URL"
msgstr "URL de la petición"
@@ -12807,7 +13468,7 @@ msgid "Max seats used"
msgstr "Máximo de puestos utilizados"
msgid "Maximum Users:"
-msgstr ""
+msgstr "Número máximo de usuarios:"
msgid "Maximum allowable lifetime for personal access token (days)"
msgstr ""
@@ -12831,10 +13492,10 @@ msgid "Maximum delay (Minutes)"
msgstr "Retraso máximo (minutos)"
msgid "Maximum duration of a session."
-msgstr ""
+msgstr "Duración máxima de una sesión."
msgid "Maximum field length"
-msgstr ""
+msgstr "Longitud máxima del campo"
msgid "Maximum job timeout"
msgstr "Tiempo de espera máximo para el trabajo"
@@ -12858,7 +13519,7 @@ msgid "Maximum number of mirrors that can be synchronizing at the same time."
msgstr "Número máximo de réplicas que se pueden sincronizar al mismo tiempo."
msgid "Maximum number of projects."
-msgstr ""
+msgstr "Número máximo de proyectos."
msgid "Maximum page reached"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr "Los miembros se pueden añadir por proyecto <i>Mantenedores</i> o <i>Pro
msgid "Members of <strong>%{project_name}</strong>"
msgstr "Miembros de <strong>%{project_name}</strong>"
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr "Miembros con acceso a %{strong_start}%{group_name}%{strong_end}"
@@ -12917,9 +13581,6 @@ msgstr "Miembros pendientes de acceso a %{strong_start}%{group_name}%{strong_end
msgid "Memory Usage"
msgstr "Uso de memoria"
-msgid "Memory limit exceeded while rendering template"
-msgstr "Se ha superado el límite de memoria al procesar la plantilla"
-
msgid "Merge"
msgstr "Merge"
@@ -12932,6 +13593,9 @@ msgstr "Merge request"
msgid "Merge Request Approvals"
msgstr "Autorizar los merge request"
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr "Merge requests"
@@ -12965,6 +13629,9 @@ msgstr "Merge request"
msgid "Merge request %{iid} authored by %{authorName}"
msgstr "Merge request %{iid} creado por %{authorName}"
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr "Aprobar los merge request"
@@ -13013,9 +13680,18 @@ msgstr "conflictos"
msgid "MergeConflict|origin//their changes"
msgstr "origen//sus cambios"
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
msgstr "Añadir una respuesta"
+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."
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr "Fusionado"
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr "Mensajes"
msgid "Method"
msgstr "Método"
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr "La métrica se añadió correctamente."
@@ -13125,7 +13801,7 @@ msgid "Metric was successfully updated."
msgstr "La métrica se actualizó correctamente."
msgid "Metric:"
-msgstr ""
+msgstr "Métrica:"
msgid "MetricChart|Please select a metric"
msgstr "Por favor seleccione una métrica"
@@ -13139,21 +13815,24 @@ msgstr "Métricas"
msgid "Metrics - Grafana"
msgstr "Métricas - Grafana"
-msgid "Metrics - Influx"
-msgstr "Métricas - Influx"
-
msgid "Metrics - Prometheus"
msgstr "Métricas - Prometheus"
msgid "Metrics Dashboard"
msgstr "Panel de control de métricas"
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
msgid "Metrics and profiling"
msgstr "Métricas e informes"
-msgid "Metrics for environment"
-msgstr "Métricas para el entorno"
-
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr "Añadir métrica"
@@ -13229,6 +13929,12 @@ 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."
+
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
msgstr ""
msgid "Metrics|Max"
@@ -13249,6 +13955,9 @@ msgstr "Documentción sobre las consultas de Prometheus"
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr "Se ha producido una respuesta inesperada de los datos de las métricas d
msgid "Metrics|Unit label"
msgstr "Etiqueta de las unidades"
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr "Utilizado como título para el gráfico"
@@ -13295,10 +14007,10 @@ msgid "Metrics|Validating query"
msgstr "Validando consulta"
msgid "Metrics|Values"
-msgstr ""
+msgstr "Nombre"
msgid "Metrics|View logs"
-msgstr ""
+msgstr "Ver registros"
msgid "Metrics|Y-axis label"
msgstr "Etiqueta del eje Y"
@@ -13347,6 +14059,63 @@ 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 "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr "Hitos"
@@ -13356,6 +14125,12 @@ msgstr "Está a punto de eliminar permanentemente el hito %{milestoneTitle} y el
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr "Está a punto de eliminar permanentemente el hito %{milestoneTitle}. Este hito no está siendo utilizado actualmente en ninguna incidencia ni en ningún merge request."
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr "Eliminar hito"
@@ -13365,21 +14140,39 @@ msgstr "¿Desea eliminar el hito %{milestoneTitle}?"
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr "Se ha producido un error al eliminar el hito %{milestoneTitle}"
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr "No se puede encontrar el hito %{milestoneTitle}"
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr "¿Promocionar %{milestoneTitle} para agrupar el hito?"
msgid "Milestones|Promote Milestone"
msgstr "Hitos|Promover hito"
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr "Promover a %{milestoneTitle} lo hará disponible para todos los proyectos dentro de %{groupName}. Los hitos de proyecto existentes con el mismo nombre serán fusionados."
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr "Esta acción no se puede deshacer"
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr "Capacidad mínima que debe estar disponible antes de que programemos más mirrors de forma preventiva."
@@ -13432,14 +14225,17 @@ msgid "Missing commit signatures endpoint!"
msgstr ""
msgid "MissingSSHKeyWarningLink|Add SSH key"
-msgstr ""
+msgstr "Añadir clave SSH"
msgid "MissingSSHKeyWarningLink|Don't show again"
-msgstr ""
+msgstr "No mostrar de nuevo"
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr "Cancelar"
@@ -13447,7 +14243,7 @@ msgid "Modal|Close"
msgstr "Cerrar"
msgid "Modified"
-msgstr ""
+msgstr "Modificado"
msgid "Modified in this version"
msgstr "Modificado en esta versión"
@@ -13495,7 +14291,7 @@ msgid "More information"
msgstr "Más información"
msgid "More information and share feedback"
-msgstr ""
+msgstr "Más información y compartir comentarios"
msgid "More information is available|here"
msgstr "Hay más información disponible | aquí"
@@ -13546,12 +14342,15 @@ msgid "Moves this issue to %{path_to_project}."
msgstr "Mueve esta incidencia a %{path_to_project}."
msgid "MrDeploymentActions|Deploy"
-msgstr ""
+msgstr "Desplegar"
msgid "MrDeploymentActions|Re-deploy"
-msgstr ""
+msgstr "Volver a desplegar"
msgid "MrDeploymentActions|Stop environment"
+msgstr "Detener entorno"
+
+msgid "Multiple domains are supported with comma delimiters."
msgstr ""
msgid "Multiple issue boards"
@@ -13563,9 +14362,12 @@ msgstr "Se encontraron varios tipos de modelo: %{model_types}"
msgid "Multiple uploaders found: %{uploader_types}"
msgstr "Se encontraron varios tipos de cargadores: %{uploader_types}"
-msgid "My company or team"
+msgid "My Awesome Group"
msgstr ""
+msgid "My company or team"
+msgstr "Mi empresa o equipo"
+
msgid "My-Reaction"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr "Nombre"
msgid "Name has already been taken"
msgstr "El nombre ya está en uso"
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr "Nombre de la nueva etiqueta"
@@ -13585,10 +14384,7 @@ msgid "Name:"
msgstr "Nombre:"
msgid "Namespace is empty"
-msgstr ""
-
-msgid "Namespace: %{namespace}"
-msgstr ""
+msgstr "Espacio de nombres está vacía"
msgid "Namespaces to index"
msgstr "Espacios de nombres a indexar"
@@ -13618,11 +14414,59 @@ msgid "Need help?"
msgstr "¿Necesita ayuda?"
msgid "Needs attention"
-msgstr ""
+msgstr "Necesita atención"
msgid "Network"
msgstr "Red"
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr "Nunca"
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] "Nueva incidencia"
msgstr[1] "Nuevas incidencias"
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr "Nueva incidencia"
msgid "New issue title"
msgstr "Nuevo título de la incidencia"
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr "Nueva etiqueta"
@@ -13737,10 +14587,10 @@ msgid "New project"
msgstr "Nuevo proyecto"
msgid "New release"
-msgstr ""
+msgstr "Nueva versión"
msgid "New requirement"
-msgstr ""
+msgstr "Nuevo requisito"
msgid "New runners registration token has been generated!"
msgstr "¡Se ha generado el token de registro para los nuevos ejecutores!"
@@ -13767,7 +14617,7 @@ msgid "New..."
msgstr "Nuevo..."
msgid "Newest first"
-msgstr ""
+msgstr "La más reciente primero"
msgid "Newly registered users will by default be external"
msgstr "Los usuarios recién registrados serán creados, por defecto, como externos"
@@ -13775,6 +14625,9 @@ msgstr "Los usuarios recién registrados serán creados, por defecto, como exter
msgid "Next"
msgstr "Siguiente"
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr "Sin %{header} para esta solicitud."
msgid "No %{providerTitle} repositories found"
msgstr "No se han encontrado repositorios de %{providerTitle}"
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr "No hay tarea épica"
-msgid "No Label"
-msgstr "Sin etiqueta"
-
-msgid "No Milestone"
-msgstr "Sin hito"
-
msgid "No Scopes"
msgstr ""
@@ -13845,7 +14689,7 @@ msgid "No connection could be made to a Gitaly Server, please check your logs!"
msgstr "¡No ha sido posible realizar la conexión con un servidor de Gitaly, por favor compruebe sus logs!"
msgid "No containers available"
-msgstr ""
+msgstr "No hay contenedores disponibles"
msgid "No contributions"
msgstr "Sin contribuciones"
@@ -13895,12 +14739,18 @@ msgstr "No se han encontrado archivos."
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr "No hay registro de tareas"
msgid "No jobs to show"
msgstr "No hay trabajos para mostrar"
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr "No hay etiquetas con ese nombre o descripción"
@@ -13925,6 +14775,9 @@ msgstr "No se han encontrado merge requests"
msgid "No messages were logged"
msgstr "No se registraron mensajes"
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr "No hay hitos para mostrar"
@@ -13974,10 +14827,10 @@ msgid "No template"
msgstr "Ninguna plantilla"
msgid "No test coverage"
-msgstr ""
+msgstr "No existe ninguna prueba de cobertura"
msgid "No thanks, don't show this again"
-msgstr ""
+msgstr "¡Gracias! No mostrar de nuevo"
msgid "No vulnerabilities present"
msgstr "No se han encontrado vulnerabilidades"
@@ -13995,7 +14848,7 @@ msgid "No, not interested right now"
msgstr "No, no estoy interesado ahora mismo"
msgid "No. of commits"
-msgstr ""
+msgstr "Número de commits"
msgid "Nobody has starred this repository yet"
msgstr "Nadie ha marcado este repositorio como favorito"
@@ -14060,6 +14913,9 @@ msgstr "Nota"
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 "Tenga en cuenta que esta invitación se envió a %{mail_to_invite_email}, pero ha iniciado sesión como %{link_to_current_user} con el correo electrónico %{mail_to_current_user}."
@@ -14084,6 +14940,9 @@ msgstr "¿Está seguro de que desea cancelar la creación de este comentario?"
msgid "Notes|Collapse replies"
msgstr "Contraer respuestas"
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr "Mostrar toda la actividad"
@@ -14097,13 +14956,13 @@ msgid "Notes|This comment has changed since you started editing, please review t
msgstr "Este comentario ha cambiado desde que se comenzó a editar, por favor revise el %{open_link}comentario actualizado%{close_link} para asegurar que no se pierde ningún tipo de información"
msgid "Nothing found…"
-msgstr ""
+msgstr "Nada encontrado…"
msgid "Nothing to preview."
msgstr "Nada para previsualizar."
msgid "Nothing to synchronize"
-msgstr ""
+msgstr "Nada que sincronizar"
msgid "Notification events"
msgstr "Eventos de notificación"
@@ -14198,12 +15057,18 @@ msgstr "Nov"
msgid "November"
msgstr "Noviembre"
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
-msgid "Number of %{itemTitle}"
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
+msgid "Number of %{itemTitle}"
+msgstr "Número de %{itemTitle}"
+
msgid "Number of Elasticsearch replicas"
msgstr "Número de réplicas de Elasticsearch"
@@ -14250,13 +15115,13 @@ msgid "OfSearchInADropdown|Filter"
msgstr "Filtrar"
msgid "Oh no!"
-msgstr ""
+msgstr "¡Oh, no!"
msgid "Ok let's go"
msgstr "Adelante"
msgid "Oldest first"
-msgstr ""
+msgstr "Más antiguo primero"
msgid "OmniAuth"
msgstr "OmniAuth"
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr "Primeros pasos"
@@ -14276,9 +15150,6 @@ msgstr "Una vez importados, los repositorios se pueden replicar vía de SSH. Par
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 "Una vez que el archivo exportado esté preparado, recibirá una notificación por correo electrónico con un enlace para su descarga, también puede descargarlo desde esta página."
@@ -14344,7 +15215,7 @@ msgstr "Sólo los miembros de proyecto pueden comentar."
msgid "Only project members will be imported. Group members will be skipped."
msgstr "Solo se importarán los miembros del proyecto. Los miembros del grupo se omitirán."
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,8 +15260,8 @@ msgstr "Abierto: %{open} • Cerrado: %{closed}"
msgid "Opened"
msgstr "Abierto"
-msgid "Opened MR"
-msgstr "MR abiertos"
+msgid "Opened MRs"
+msgstr ""
msgid "Opened issues"
msgstr "Incidencias abiertas"
@@ -14404,6 +15275,9 @@ msgstr "Abre en una nueva ventana"
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr "La operación ha fallado. Por favor, compruebe los registros del pod para %{pod_name} para más obtener más información."
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr "Se ha agotado el tiempo de la operación. Por favor, compruebe los registros del pod para %{pod_name} para obtener más información."
@@ -14434,7 +15308,7 @@ msgstr "El panel de control de operaciones proporciona un resumen del estado ope
msgid "Optional"
msgstr "Opcional"
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr "De mi propiedad"
msgid "Owner"
msgstr "Propietario"
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr "El paquete ha sido eliminado"
@@ -14540,7 +15426,7 @@ msgid "PackageRegistry|Copy .pypirc content"
msgstr ""
msgid "PackageRegistry|Copy Conan Command"
-msgstr ""
+msgstr "Copiar comando de Conan"
msgid "PackageRegistry|Copy Conan Setup Command"
msgstr ""
@@ -14552,16 +15438,16 @@ msgid "PackageRegistry|Copy Maven command"
msgstr "Copiar comando Maven"
msgid "PackageRegistry|Copy Maven registry XML"
-msgstr ""
+msgstr "Copiar el registro XML de Maven"
msgid "PackageRegistry|Copy NuGet Command"
-msgstr ""
+msgstr "Copiar comando de NuGet"
msgid "PackageRegistry|Copy NuGet Setup Command"
-msgstr ""
+msgstr "Copiar comando de configuración de NuGet"
msgid "PackageRegistry|Copy Pip command"
-msgstr ""
+msgstr "Copiar comando de Pip"
msgid "PackageRegistry|Copy and paste this inside your %{codeStart}pom.xml%{codeEnd} %{codeStart}dependencies%{codeEnd} block."
msgstr ""
@@ -14608,14 +15494,17 @@ msgstr "Si aún no lo ha hecho, debe añadir lo siguiente a su archivo %{codeSta
msgid "PackageRegistry|Installation"
msgstr "Instalación"
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr "Aprenda a %{noPackagesLinkStart}publicar y compartir sus paquetes%{noPackagesLinkEnd} con GitLab."
msgid "PackageRegistry|Manually Published"
-msgstr ""
+msgstr "Publicado manualmente"
msgid "PackageRegistry|Maven"
-msgstr ""
+msgstr "Maven"
msgid "PackageRegistry|Maven Command"
msgstr "Comando Maven"
@@ -14624,16 +15513,19 @@ msgid "PackageRegistry|Maven XML"
msgstr "Maven XML"
msgid "PackageRegistry|NPM"
+msgstr "NPM"
+
+msgid "PackageRegistry|No upcoming issues"
msgstr ""
msgid "PackageRegistry|NuGet"
-msgstr ""
+msgstr "NuGet"
msgid "PackageRegistry|NuGet Command"
-msgstr ""
+msgstr "Comando NuGet"
msgid "PackageRegistry|Pip Command"
-msgstr ""
+msgstr "Comando Pip"
msgid "PackageRegistry|Pipeline %{linkStart}%{linkEnd} triggered %{timestamp} by %{author}"
msgstr ""
@@ -14642,7 +15534,7 @@ msgid "PackageRegistry|Published to the repository at %{timestamp}"
msgstr ""
msgid "PackageRegistry|PyPi"
-msgstr ""
+msgstr "PyPi"
msgid "PackageRegistry|Registry Setup"
msgstr "Configuración del registro"
@@ -14656,23 +15548,38 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr "Todavía no hay paquetes"
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr "Se ha producido un error al obtener los detalles de este paquete."
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr "Se ha producido un error al cargar el paquete"
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
-msgstr "Está a punto de eliminar <b>%{packageName}</b>, esta operación es irreversible, ¿está seguro?"
+msgid "PackageRegistry|Upcoming package managers"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
-msgstr "Está a punto de eliminar la versión %{boldStart}%{version}%{boldEnd} de %{boldStart}%{name}%{boldEnd}. ¿Está seguro?"
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
+msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
msgstr ""
@@ -14681,29 +15588,32 @@ msgid "PackageRegistry|npm"
msgstr "npm"
msgid "PackageRegistry|published by %{author}"
-msgstr ""
+msgstr "publicado por %{author}"
msgid "PackageRegistry|yarn"
msgstr "yarn"
msgid "PackageType|Conan"
-msgstr ""
+msgstr "Conan"
msgid "PackageType|Maven"
-msgstr ""
+msgstr "Maven"
msgid "PackageType|NPM"
-msgstr ""
+msgstr "NPM"
msgid "PackageType|NuGet"
-msgstr ""
+msgstr "NuGet"
msgid "PackageType|PyPi"
-msgstr ""
+msgstr "PyPi"
msgid "Packages"
msgstr "Paquetes"
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr "Página no encontrada"
@@ -14735,10 +15645,10 @@ msgid "Pagination|Last »"
msgstr "Último »"
msgid "Pagination|Next"
-msgstr ""
+msgstr "Siguiente"
msgid "Pagination|Prev"
-msgstr ""
+msgstr "Previo"
msgid "Pagination|« First"
msgstr "« Primero"
@@ -14791,6 +15701,9 @@ msgstr "La contraseña se ha cambiado correctamente"
msgid "Password was successfully updated. Please login with it"
msgstr "La contraseña se actualizó correctamente. Por favor, inicie la sesión de nuevo"
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr "Vencido"
@@ -14809,6 +15722,9 @@ msgstr "Pegar el enlace de la incidencia"
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'. Don't use your private SSH key."
msgstr "Pegue su clave pública SSH, que generalmente está contenida en el archivo ~/.ssh/id_ed25519.pub o en el archivo '~/ .ssh/id_rsa.pub' y comienza con 'ssh-rsa'. No utilice su clave SSH privada."
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr "Ruta"
@@ -14851,9 +15767,15 @@ msgstr "Realice operaciones comunes en el proyecto GitLab"
msgid "Performance optimization"
msgstr "Optimización del rendimiento"
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr "Descargar"
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr "Recursos de Frontend"
@@ -14875,9 +15797,6 @@ msgstr "traza"
msgid "Permissions"
msgstr "Permisos"
-msgid "Permissions Help"
-msgstr "Ayuda de los permisos"
-
msgid "Permissions, LFS, 2FA"
msgstr "Permisos, LFS, 2FA"
@@ -14899,9 +15818,6 @@ msgstr "Tareas de Phabricator"
msgid "Pick a name"
msgstr "Escoja un nombre"
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr "Seleccione un nombre para la aplicación, y le proporcionaremos un token %{type} único."
-
msgid "Pin code"
msgstr "Código pin"
@@ -15010,6 +15926,9 @@ msgstr "Pipelines del año pasado"
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr "La configuración de los pipelines para '%{project_name}' se actualizó correctamente."
@@ -15070,18 +15989,27 @@ msgstr "Este proyecto no está configurado para ejecutar pipelines."
msgid "Pipelines|parent"
msgstr "padre"
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr "Commit"
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr "Cobertura"
-msgid "Pipeline|Date"
+msgid "Pipeline|Created"
msgstr ""
+msgid "Pipeline|Date"
+msgstr "Fecha"
+
msgid "Pipeline|Detached merge request pipeline"
msgstr ""
@@ -15091,19 +16019,37 @@ msgstr "Duración"
msgid "Pipeline|Existing branch name or tag"
msgstr "Nombre de la rama o etiqueta existente"
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr "Clave"
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr "Pipeline"
msgid "Pipeline|Pipelines"
+msgstr "Pipelines"
+
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
msgstr ""
msgid "Pipeline|Run Pipeline"
@@ -15112,9 +16058,15 @@ msgstr "Ejecutar Pipeline"
msgid "Pipeline|Run for"
msgstr "Ejecutar para"
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr "Buscar ramas"
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr "Especifique los valores de las variables que se utilizarán en esta ejecución. Se usarán los valores especificados por defecto en %{settings_link}."
@@ -15130,6 +16082,9 @@ msgstr "Detener pipeline"
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr "¿Desea detener la ejecución del pipeline #%{pipelineId}?"
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr "Disparador"
@@ -15166,6 +16121,12 @@ msgstr "Software de gestión de proyectos (Source Commits Endpoint)"
msgid "Plain diff"
msgstr "Dif simple"
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr "PlantUML"
@@ -15221,7 +16182,7 @@ msgid "Please create a username with only alphanumeric characters."
msgstr "Por favor, cree un nombre de usuario con sólo caracteres alfanuméricos."
msgid "Please create an index before enabling indexing"
-msgstr ""
+msgstr "Por favor, cree un índice antes de habilitar la indexación"
msgid "Please enable and migrate to hashed storage to avoid security issues and ensure data integrity. %{migrate_link}"
msgstr "Por favor, habilite y migre todos los proyectos existentes al almacenamiento de tipo hash para evitar problemas de seguridad y asegurar la integridad de los datos. %{migrate_link}"
@@ -15259,6 +16220,9 @@ msgstr "Por favor, tenga en cuenta que esta aplicación no la proporciona GitLab
msgid "Please provide a name"
msgstr "Por favor, proporcione un nombre"
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr "Por favor proporcione una dirección de correo electrónico válida."
@@ -15272,7 +16236,7 @@ msgid "Please select"
msgstr "Por favor, seleccione"
msgid "Please select a Jira project"
-msgstr ""
+msgstr "Por favor, seleccione un proyecto Jira"
msgid "Please select a country"
msgstr "Por favor, seleccione un país"
@@ -15284,7 +16248,7 @@ msgid "Please select a group."
msgstr "Por favor, seleccione un grupo."
msgid "Please select a valid target branch"
-msgstr ""
+msgstr "Por favor, seleccione una rama de destino válida"
msgid "Please select and add a member"
msgstr "Por favor seleccione y añada un miembro"
@@ -15323,7 +16287,7 @@ msgid "Plugins directory is deprecated and will be removed in 14.0. Please move
msgstr ""
msgid "Pod does not exist"
-msgstr ""
+msgstr "El Pod no existe"
msgid "Pod not found"
msgstr "Pod no encontrado"
@@ -15334,6 +16298,9 @@ msgstr "Pods en uso"
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr "Preferencias"
@@ -15389,7 +16356,7 @@ msgid "Preferences|Show whitespace changes in diffs"
msgstr ""
msgid "Preferences|Sourcegraph"
-msgstr ""
+msgstr "Sourcegraph"
msgid "Preferences|Syntax highlighting theme"
msgstr "Tema del resaltado de la sintaxis"
@@ -15424,6 +16391,9 @@ msgstr "Utilizar tiempos relativos"
msgid "Press %{key}-C to copy"
msgstr "Presione %{key}-C para copiar"
+msgid "Prev"
+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"
@@ -15460,6 +16430,9 @@ msgstr "Vista previa del payload"
msgid "Previous Artifacts"
msgstr "Artefactos anteriores"
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15506,7 +16479,7 @@ msgid "Proceed"
msgstr "Continuar"
msgid "Productivity"
-msgstr ""
+msgstr "Productividad"
msgid "Productivity Analytics"
msgstr "Análisis de productividad"
@@ -15665,10 +16638,10 @@ msgid "Profiles|Enter your name, so people you know can recognize you"
msgstr "Introduzca su nombre para que las personas que le conozca puedan reconocer su perfil"
msgid "Profiles|Expires at"
-msgstr ""
+msgstr "Caduca el"
msgid "Profiles|Expires:"
-msgstr ""
+msgstr "Caduca:"
msgid "Profiles|Feed token was successfully reset"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr "Nombre completo"
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr "Suplantación"
-
msgid "Profiles|Include private contributions on my profile"
msgstr "Incluir las contribuciones privadas en mi perfil"
@@ -15727,9 +16697,6 @@ msgstr "Organización"
msgid "Profiles|Path"
msgstr "Ruta"
-msgid "Profiles|Personal Access"
-msgstr "Acceso personal"
-
msgid "Profiles|Position and size your new avatar"
msgstr "Posición y tamaño de su nuevo avatar"
@@ -15860,7 +16827,7 @@ msgid "Profiles|Your email address was automatically set based on your %{provide
msgstr "Su dirección de correo electrónico se ha establecido automáticamente en base a su cuenta %{provider_label}"
msgid "Profiles|Your key has expired"
-msgstr ""
+msgstr "Su clave ha caducado"
msgid "Profiles|Your location was automatically set based on your %{provider_label} account"
msgstr "Su ubicación se ha establecido automáticamente basándose en su cuenta %{provider_label}"
@@ -15874,12 +16841,6 @@ msgstr "Su estado"
msgid "Profiles|e.g. My MacBook key"
msgstr "por ejemplo, mi clave MacBook"
-msgid "Profiles|impersonation"
-msgstr "Suplantación"
-
-msgid "Profiles|personal access"
-msgstr "Acceso personal"
-
msgid "Profiles|username"
msgstr "Nombre de usuario"
@@ -15890,7 +16851,7 @@ msgid "Profiles|your account"
msgstr "tu cuenta"
msgid "Profile|%{job_title} at %{organization}"
-msgstr ""
+msgstr "%{job_title} en %{organization}"
msgid "Profiling - Performance bar"
msgstr "Profiling - Barra de rendimiento"
@@ -15910,6 +16871,9 @@ msgstr "El proyecto \"%{name}\" ya no está disponible. Por favor, seleccione ot
msgid "Project %{project_repo} could not be found"
msgstr "No es posible encontrar el proyecto %{project_repo}"
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr "Se está importando el proyecto '%{project_name}'."
@@ -15931,9 +16895,12 @@ msgstr "Proyecto ‘%{project_name}’ fue actualizado satisfactoriamente."
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr "El proyecto '%{project_name}' será eliminado el %{date}"
-msgid "Project Audit Events"
+msgid "Project Access Tokens"
msgstr ""
+msgid "Project Audit Events"
+msgstr "Eventos de auditoría del proyecto"
+
msgid "Project Badges"
msgstr "Insignias de proyecto"
@@ -15961,6 +16928,9 @@ msgstr "Avatar del proyecto"
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr "No se puede compartir el proyecto con el grupo en el que está o con uno de sus grupos padre."
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr "Configuración del proyecto, incluyendo sus servicios"
@@ -15985,8 +16955,8 @@ msgstr "La exportación del proyecto ha sido eliminada."
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr "El enlace de exportación del proyecto ha caducado. Por favor, genera una nueva exportación desde la configuración del proyecto."
-msgid "Project export started. A download link will be sent by email."
-msgstr "Se inició la exportación del proyecto. Se enviará un enlace de descarga por correo electrónico."
+msgid "Project export started. A download link will be sent by email and made available on this page."
+msgstr ""
msgid "Project has too many %{label_for_message} to search"
msgstr "El proyecto tiene demasiadas %{label_for_message} para buscar"
@@ -15994,11 +16964,14 @@ msgstr "El proyecto tiene demasiadas %{label_for_message} para buscar"
msgid "Project members"
msgstr "Miembros del proyecto"
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr "Nombre del proyecto"
msgid "Project name suffix"
-msgstr ""
+msgstr "Sufijo del nombre del proyecto"
msgid "Project name suffix is a user-defined string which will be appended to the project path, and will form the Service Desk email address."
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr "Comentar"
msgid "ProjectService|Comment will be posted on each event"
msgstr "El comentario se publicará en cada evento"
-msgid "ProjectService|Last edit"
-msgstr "Última edición"
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr "Realice operaciones comunes en el proyecto GitLab: %{project_name}"
@@ -16276,6 +17246,9 @@ msgstr "Repositorio"
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr "Mostrar el enlace para crear/ver los merge requests cuando se haga push desde la línea de comandos"
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr "Cuando surgen conflictos, al usuario se le da la opción de realizar un rebase"
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr "Wiki"
@@ -16471,6 +17447,9 @@ msgstr "Proyecto en blanco"
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr "Contacte con un administrador para habilitar opciones importantes para su proyecto."
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr "Crear desde una plantilla"
@@ -16508,7 +17487,7 @@ msgid "ProjectsNew|Want to house several dependent projects under the same names
msgstr "¿Desea alojar varios proyectos independientes bajo el mismo espacio de nombres? %{link_start}Crear un grupo%{link_end}"
msgid "Prometheus"
-msgstr ""
+msgstr "Prometheus"
msgid "PrometheusAlerts|%{count} alerts applied"
msgstr "%{count} alertas aplicadas"
@@ -16564,12 +17543,18 @@ msgstr "Configuración automática"
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr "Implemente y configure Prometheus automáticamente en sus clústeres para supervisar los entornos de su proyecto"
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr "Métricas comunes"
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr "Las métricas comunes más son monitorizadas automáticamente en base a una librería de métricas de los exportadores más populares."
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr "Métricas personalizadas"
@@ -16645,9 +17630,6 @@ msgstr "Promocionar la incidencia a una tarea épica"
msgid "Promote these project milestones into a group milestone."
msgstr "Promocionar estos hitos del proyecto a hitos de grupo."
-msgid "Promote to Group Milestone"
-msgstr "Promocionar a hito de grupo"
-
msgid "Promote to group label"
msgstr "Promocionar a etiqueta de grupo"
@@ -16666,35 +17648,89 @@ msgstr ""
msgid "Promoted issue to an epic."
msgstr "Incidencia promocionada a tarea épica."
+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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr "No mostrar este mensaje de nuevo"
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 "La tareas épicas le permiten administrar su cartera de proyectos de manera más eficiente y con menos esfuerzo mediante el seguimiento de grupos de incidencias comunes, a través de proyectos e hitos."
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr "Más información"
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr "Vea el resto de características del %{subscription_link_start}plan Bronze%{subscription_link_end}"
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr "Esta funcionalidad está bloqueada."
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr "Plan de actualización"
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr "Ponderar su problema"
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 "Cuando tienes muchas incidencias, puede ser difícil obtener una visión general. Al añadir un peso a tus problemas, puedes tener una mejor idea del esfuerzo, del costo, del tiempo requerido, o valor de cada uno, y por lo tanto poder manejarlos mejor."
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr "Solicitar a los usuarios que carguen claves SSH"
msgid "Protect variable"
-msgstr ""
+msgstr "Proteger variable"
msgid "Protected"
msgstr "Protegido"
@@ -16808,7 +17844,7 @@ msgid "Protip:"
msgstr "Sugerencia:"
msgid "Protocol"
-msgstr ""
+msgstr "Protocolo"
msgid "Provider"
msgstr "Proveedor"
@@ -16825,9 +17861,6 @@ msgstr "Público - El grupo y cualquier proyecto público puede ser visto sin au
msgid "Public - The project can be accessed without any authentication."
msgstr "Público - El proyecto puede ser accedido sin ninguna autenticación."
-msgid "Public Access Help"
-msgstr "Ayuda de acceso público"
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr "Claves de despliegue público (%{deploy_keys_count})"
@@ -16837,6 +17870,12 @@ msgstr "Pipelines públicos"
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr "Pull"
@@ -16939,6 +17978,9 @@ msgstr "La consulta es válida"
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr "Se pueden utilizar acciones rápidas en la descripción de las incidencias y en los cuadros de texto de los comentarios."
@@ -16948,9 +17990,6 @@ msgstr "Rango rápido"
msgid "README"
msgstr "README"
-msgid "Rake Tasks Help"
-msgstr "Ayuda sobre las tareas de Rake"
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr "Rebase en progreso"
msgid "Receive alerts from manually configured Prometheus servers."
msgstr "Recibe alertas desde los servidores de Prometheus configurados manualmente."
-msgid "Receive alerts on GitLab from any source"
-msgstr "Reciba alertas en GitLab desde cualquier fuente"
-
msgid "Receive notifications about your own activity"
msgstr "Recibir notificaciones acerca de su propia actividad"
@@ -17085,6 +18121,21 @@ msgstr "Registrarse con la aplicación de dos factores"
msgid "Registration"
msgstr "Registro"
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr "Trabajos Desplegados Relacionados"
@@ -17129,6 +18180,18 @@ msgstr "Notas de versión:"
msgid "Release title"
msgstr "Título de la versión"
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr "Versiones"
@@ -17150,6 +18213,9 @@ msgstr "Se ha producido un error al guardar los detalles de la versión"
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr "Recordar mis datos acceso"
@@ -17219,9 +18285,15 @@ msgstr "Eliminar de la tarea épica"
msgid "Remove group"
msgstr "Eliminar grupo"
-msgid "Remove limit"
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
msgstr ""
+msgid "Remove limit"
+msgstr "Eliminar límite"
+
msgid "Remove milestone"
msgstr "Eliminar el hito"
@@ -17261,6 +18333,9 @@ msgstr "Eliminado %{assignee_text} %{assignee_references}."
msgid "Removed %{epic_ref} from child epics."
msgstr "Se eliminó %{epic_ref} de las tareas épicas hijas."
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr "Eliminada %{label_references} %{label_text}."
@@ -17300,6 +18375,9 @@ msgstr "Eliminar %{assignee_text} %{assignee_references}."
msgid "Removes %{epic_ref} from child epics."
msgstr "Eliminar %{epic_ref} de las tareas épicas hijas."
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr "Eliminar %{label_references} %{label_text}."
@@ -17346,11 +18424,14 @@ msgid "Rename folder"
msgstr "Renombrar carpeta"
msgid "Rename/Move"
-msgstr ""
+msgstr "Renombrar/Mover"
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr "Reabrir la tarea épica"
@@ -17381,6 +18462,9 @@ msgstr "Reemplazadas todas las etiquetas %{label_references} %{label_text}."
msgid "Replaces the clone URL root."
msgstr "Reemplaza la raíz de la URL de clonado."
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr "Responder por correo electrónico"
@@ -17396,8 +18480,11 @@ msgstr "Responder..."
msgid "Repo by URL"
msgstr "Repo por URL"
-msgid "Report Type: %{report_type}"
-msgstr "Tipo de informe: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
+msgstr ""
msgid "Report abuse to admin"
msgstr "Informar de un abuso al administrador"
@@ -17500,6 +18587,9 @@ msgstr "Configuración del repositorio"
msgid "Repository URL"
msgstr "URL del repositorio"
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr "Se activó la verificación del repositorio."
@@ -17536,6 +18626,9 @@ msgstr "Seleccionar"
msgid "Request Access"
msgstr "Solicitar acceso"
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,31 +18665,34 @@ msgstr "Requiere una contraseña de usuario para aprobar"
msgid "Require users to prove ownership of custom domains"
msgstr "Requerir a los usuarios desmostrar la propiedad de los dominios personalizados"
-msgid "Requirement"
+msgid "Required approvals (%{approvals_given} given)"
msgstr ""
-msgid "Requirement %{reference} has been added"
+msgid "Required approvals (%{approvals_given} given, you've approved)"
msgstr ""
+msgid "Requirement"
+msgstr "Requisito"
+
+msgid "Requirement %{reference} has been added"
+msgstr "Se ha añadido el requisito %{reference}"
+
msgid "Requirement %{reference} has been archived"
-msgstr ""
+msgstr "Se ha archivado el requisito %{reference}"
msgid "Requirement %{reference} has been reopened"
-msgstr ""
+msgstr "Se ha reabierto el requisito %{reference}"
msgid "Requirement %{reference} has been updated"
-msgstr ""
+msgstr "Se ha actualizado el requisito %{reference}"
msgid "Requirement title cannot have more than %{limit} characters."
-msgstr ""
+msgstr "El título del requisito no puede tener más de %{limit} caracteres."
msgid "Requirements"
-msgstr ""
-
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
+msgstr "Requisitos"
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr "Resolver una discusión."
msgid "Resolved all discussions."
msgstr "Resolver todas las discusiones."
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr "Resuelto por %{name}"
@@ -17675,6 +18777,12 @@ msgstr "Resuelve las direcciones IP una vez y las utiliza para enviar peticiones
msgid "Response"
msgstr "Respuesta"
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr "La respuesta no contiene `service_desk_address`"
@@ -17700,7 +18808,7 @@ msgid "Restart Terminal"
msgstr "Reiniciar el terminal"
msgid "Restore group"
-msgstr ""
+msgstr "Restaurar grupo"
msgid "Restore project"
msgstr "Restaurar proyecto"
@@ -17730,10 +18838,10 @@ msgid "Resync"
msgstr "Resincronizar"
msgid "Resync all"
-msgstr ""
+msgstr "Resincronizar todo"
msgid "Resync all %{replicableType}"
-msgstr ""
+msgstr "Resincronizar todo %{replicableType}"
msgid "Retry"
msgstr "Reintentar"
@@ -17821,6 +18929,9 @@ msgstr "Restaurar"
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17852,7 +18963,7 @@ msgid "Runner token"
msgstr "Token del ejecutor"
msgid "Runner tokens"
-msgstr ""
+msgstr "Token del ejecutor"
msgid "Runner was not updated."
msgstr "No se actualizó el ejecutor."
@@ -17884,9 +18995,6 @@ msgstr "Los ejecutores se pueden colocar como usuarios separados, en servidores
msgid "Runners currently online: %{active_runners_count}"
msgstr "Ejecutores actualmente en línea: %{active_runners_count}"
-msgid "Runners page"
-msgstr "Página de ejecutores"
-
msgid "Runners page."
msgstr "Página de ejecutores."
@@ -17909,7 +19017,7 @@ msgid "SAML SSO for %{group_name}"
msgstr "SAML SSO para %{group_name}"
msgid "SAML discovery tokens"
-msgstr ""
+msgstr "Tokens de descubrimiento SAML"
msgid "SAML for %{group_name}"
msgstr "SAML para %{group_name}"
@@ -17923,9 +19031,6 @@ msgstr "Clave SSH"
msgid "SSH Keys"
msgstr "Claves SSH"
-msgid "SSH Keys Help"
-msgstr "Ayuda sobre las claves SSH"
-
msgid "SSH host key fingerprints"
msgstr "Huella digital de la clave SSH del host"
@@ -17969,7 +19074,7 @@ msgid "Save comment"
msgstr "Guardar comentario"
msgid "Save expiration policy"
-msgstr ""
+msgstr "Guardar política de caducidad"
msgid "Save password"
msgstr "Guardar la contraseña"
@@ -18055,9 +19160,15 @@ msgstr "Buscar"
msgid "Search Button"
msgstr "Botón de búsqueda"
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr "Buscar un entorno específico"
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr "Buscar ramas"
@@ -18065,7 +19176,7 @@ msgid "Search branches and tags"
msgstr "Buscar ramas y etiquetas"
msgid "Search by author"
-msgstr ""
+msgstr "Buscar por autor"
msgid "Search files"
msgstr "Buscar archivos"
@@ -18083,7 +19194,7 @@ msgid "Search for projects, issues, etc."
msgstr "Buscar proyectos, incidencias, etc."
msgid "Search for this text"
-msgstr ""
+msgstr "Buscar este texto"
msgid "Search forks"
msgstr "Buscar forks"
@@ -18115,6 +19226,9 @@ msgstr "Buscar proyectos"
msgid "Search projects..."
msgstr "Buscar proyectos..."
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr "Buscar usuarios"
@@ -18145,11 +19259,11 @@ msgstr "Merge requests asignados a mí"
msgid "SearchAutocomplete|in all GitLab"
msgstr "en todo GitLab"
-msgid "SearchAutocomplete|in this group"
-msgstr "en este grupo"
+msgid "SearchAutocomplete|in group %{groupName}"
+msgstr ""
-msgid "SearchAutocomplete|in this project"
-msgstr "en este proyecto"
+msgid "SearchAutocomplete|in project %{projectName}"
+msgstr ""
msgid "SearchCodeResults|in"
msgstr "en"
@@ -18237,9 +19351,15 @@ msgstr "Puestos actualmente en uso"
msgid "Seats in license"
msgstr "Puestos en la licencia"
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr "Secreto"
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr "Seguridad"
@@ -18252,9 +19372,6 @@ msgstr "Configuración de seguridad"
msgid "Security Dashboard"
msgstr "Panel de control de seguridad"
-msgid "Security configuration help link"
-msgstr "Enlace de ayuda de configuración de seguridad"
-
msgid "Security dashboard"
msgstr "Panel de control de seguridad"
@@ -18264,50 +19381,50 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr "Configurado"
-
-msgid "SecurityConfiguration|Feature"
-msgstr "Característica"
+msgid "SecurityConfiguration|Enabled"
+msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
-msgstr "Todavía no está configurado"
+msgid "SecurityConfiguration|Not yet enabled"
+msgstr ""
-msgid "SecurityConfiguration|Secure features"
-msgstr "Características seguras"
+msgid "SecurityConfiguration|Security Control"
+msgstr ""
msgid "SecurityConfiguration|Status"
msgstr "Estado"
-msgid "SecurityReports|%{firstProject} and %{secondProject}"
+msgid "SecurityConfiguration|Testing & Compliance"
msgstr ""
+msgid "SecurityReports|%{firstProject} and %{secondProject}"
+msgstr "%{firstProject} y %{secondProject}"
+
msgid "SecurityReports|%{firstProject}, %{secondProject}, and %{rest}"
-msgstr ""
+msgstr "%{firstProject}, %{secondProject} y %{rest}"
msgid "SecurityReports|Add a project to your dashboard"
-msgstr ""
+msgstr "Añadir un proyecto al panel de control"
msgid "SecurityReports|Add or remove projects from your dashboard"
-msgstr ""
+msgstr "Añadir o eliminar proyectos de su panel de control"
msgid "SecurityReports|Add projects"
-msgstr ""
+msgstr "Añadir proyectos"
msgid "SecurityReports|Comment added to '%{vulnerabilityName}'"
-msgstr ""
+msgstr "Comentario añadido a '%{vulnerabilityName}'"
msgid "SecurityReports|Comment deleted on '%{vulnerabilityName}'"
-msgstr ""
+msgstr "Comentario eliminado en '%{vulnerabilityName}'"
msgid "SecurityReports|Comment edited on '%{vulnerabilityName}'"
-msgstr ""
+msgstr "Comentario editado en '%{vulnerabilityName}'"
msgid "SecurityReports|Create issue"
-msgstr ""
+msgstr "Crear incidencia"
msgid "SecurityReports|Dismiss Selected"
msgstr ""
@@ -18385,16 +19502,16 @@ msgid "SecurityReports|Pipeline %{pipelineLink} triggered %{timeago} by %{user}"
msgstr ""
msgid "SecurityReports|Project"
-msgstr ""
+msgstr "Proyecto"
msgid "SecurityReports|Projects added"
-msgstr ""
+msgstr "Proyectos añadidos"
msgid "SecurityReports|Remove project from dashboard"
-msgstr ""
+msgstr "Eliminar proyecto del panel de control"
msgid "SecurityReports|Report type"
-msgstr ""
+msgstr "Tipo de informe"
msgid "SecurityReports|Return to dashboard"
msgstr ""
@@ -18409,12 +19526,15 @@ msgid "SecurityReports|Select a project to add by using the project search field
msgstr ""
msgid "SecurityReports|Select a reason"
-msgstr ""
+msgstr "Seleccione una razón"
msgid "SecurityReports|Severity"
-msgstr ""
+msgstr "Gravedad"
msgid "SecurityReports|Status"
+msgstr "Estado"
+
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
msgstr ""
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
@@ -18498,6 +19618,9 @@ msgstr "Seleccionar"
msgid "Select Archive Format"
msgstr "Seleccionar formato de archivo"
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr "Seleccione el proyecto GitLab para vincular con su equipo de Slack"
@@ -18529,7 +19652,7 @@ msgid "Select a project to read Insights configuration file"
msgstr "Seleccione un proyecto para leer el archivo de configuración de Insights"
msgid "Select a reason"
-msgstr ""
+msgstr "Seleccione una razón"
msgid "Select a repository"
msgstr "Seleccione un repositorio"
@@ -18549,20 +19672,26 @@ msgstr "Seleccionar todo"
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr "Seleccione un clúster existente de Kubernetes o cree un cluster nuevo"
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr "Seleccione la rama"
msgid "Select branch/tag"
msgstr "Selecciona rama/etiqueta"
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr "Seleccione un grupo o proyecto"
msgid "Select groups to replicate"
-msgstr ""
+msgstr "Seleccionar grupos a replicar"
msgid "Select health status"
-msgstr ""
+msgstr "Seleccionar estado de salud"
msgid "Select labels"
msgstr "Seleccione las etiquetas"
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr "Seleccione la rama de origen"
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr "Selecciona una rama de destino"
@@ -18628,7 +19766,7 @@ msgid "Selecting a GitLab user will add a link to the GitLab user in the descrip
msgstr "Al seleccionar un usuario de GitLab añadirá un link al usuario en la descripción de las incidencias, así como también, en los comentarios (por ejemplo, \"Por <a href=\"#\">@johnsmith</a>\"). Al hacer esto, también asociará y asignará dichas incidencias y comentarios con el usuario seleccionado."
msgid "Selective synchronization"
-msgstr ""
+msgstr "Sincronización selectiva"
msgid "Self monitoring project does not exist"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr "Enviar un correo electrónico de confirmación"
msgid "Send email"
msgstr "Enviar correo electrónico"
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr "Enviar informe"
@@ -18840,6 +19984,9 @@ msgstr "Establecer fecha de finalización"
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr "Establecer el tiempo máximo de sesión para el terminal de web."
@@ -18876,6 +20023,9 @@ msgstr "Establecer la fecha de vencimiento a %{due_date}."
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr "Establezca la duración durante la cual los trabajos se considerarán antiguos y vencidos. Una vez pasado ese tiempo, los trabajos se archivarán y ya no se podrá volver a reintentar su ejecución. Establezca este campo como nulo para que los trabajos no caduquen. Este valor, no debe ser inferior a 1 día, por ejemplo: <code>15 días</code>, <code>1 mes</code>, <code>2 años</code>."
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr "Establecer el tamaño máximo de archivo para los artefactos de cada trabajo"
@@ -18960,6 +20110,9 @@ msgstr "Establece la rama de destino a %{branch_name}."
msgid "Sets the due date to %{due_date}."
msgstr "Establecer la fecha de vencimiento a %{due_date}."
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr "Establece el hito en %{milestone_reference}."
@@ -18978,8 +20131,8 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
-msgstr "Gravedad: %{severity}"
+msgid "Severity"
+msgstr ""
msgid "Shards (%{shards})"
msgstr ""
@@ -19017,15 +20170,15 @@ msgstr "Transacciones de Sherlock"
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr "Mostrar toda la actividad"
msgid "Show all members"
msgstr "Mostrar todos los miembros"
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr "Mostrar proyectos archivados"
@@ -19050,12 +20203,21 @@ msgstr "Mostrar el registro completo sin procesar"
msgid "Show file browser"
msgstr "Mostrar el explorador de archivos"
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr "Mostrar la última versión"
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr "Mostrar solo los miembros directos"
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] "Mostrando %d evento"
msgstr[1] "Mostrando %d eventos"
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr "Mostrando %{limit} de %{total_count} incidencias. "
@@ -19101,16 +20271,16 @@ msgid "Side-by-side"
msgstr "En paralelo"
msgid "Sidebar|Assign health status"
-msgstr ""
+msgstr "Asignar estado de salud"
msgid "Sidebar|Change weight"
msgstr "Cambiar peso"
msgid "Sidebar|Health status"
-msgstr ""
+msgstr "Estado de salud"
msgid "Sidebar|No status"
-msgstr ""
+msgstr "Sin estado"
msgid "Sidebar|None"
msgstr "Ninguno"
@@ -19215,7 +20385,7 @@ msgid "Slack application"
msgstr "Aplicación Slack"
msgid "Slack channels (e.g. general, development)"
-msgstr ""
+msgstr "Canales de Slack (p.ej. general, desarrollo)"
msgid "Slack integration allows you to interact with GitLab via slash commands in a chat window."
msgstr "La integración con Slack le permite interactuar con GitLab mediante comandos slash en una ventana de chat."
@@ -19262,11 +20432,14 @@ msgstr "Falló la autenticación de la tarjeta inteligente: falta la cabecera de
msgid "Snippets"
msgstr "Fragmentos de código"
-msgid "SnippetsEmptyState|Code snippets"
+msgid "Snippets with non-text files can only be edited via Git."
msgstr ""
+msgid "SnippetsEmptyState|Code snippets"
+msgstr "Fragmentos de código"
+
msgid "SnippetsEmptyState|Documentation"
-msgstr ""
+msgstr "Documentación"
msgid "SnippetsEmptyState|New snippet"
msgstr "Nuevo fragmento de código"
@@ -19281,10 +20454,10 @@ msgid "SnippetsEmptyState|There are no snippets to show."
msgstr "No hay fragmentos de código que mostrar."
msgid "Snippets|Description (optional)"
-msgstr ""
+msgstr "Descripción (opcional)"
msgid "Snippets|File"
-msgstr ""
+msgstr "Archivo"
msgid "Snippets|Give your file a name to add code highlighting, e.g. example.rb for Ruby"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr "Snowplow"
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr "Algunos servidores de correo electrónico no permiten sobreescribir el nombre del remitente del correo electrónico. Habilite esta opción para incluir el nombre del autor de la incidencia, del merge request o del comentario en el cuerpo del correo electrónico."
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr "Se ha producido un error al obtener los merge request relacionados."
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr "Algo salió mal al resolver esta discusión. ¡Por favor, inténtelo de
msgid "Something went wrong while stopping this environment. Please try again."
msgstr "Se ha producido un error al detener este entorno. Por favor, inténtalo de nuevo."
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr "Ordenar por"
msgid "Sort direction"
msgstr "Dirección de clasificación"
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr "Nivel de acceso, ascendente"
@@ -19601,6 +20792,9 @@ msgstr "Destacados más recientes"
msgid "SortOptions|Size"
msgstr "Tamaño"
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr "Dirección de clasificación"
@@ -19698,7 +20892,7 @@ msgid "Specific Runners"
msgstr "Ejecutores específicos"
msgid "Specified URL cannot be used: \"%{reason}\""
-msgstr ""
+msgstr "No se puede usar la URL especificada: \"%{reason}\""
msgid "Specify an e-mail address regex pattern to identify default internal users."
msgstr "Especifique un patrón para la expresión regular de direcciones de correo electrónico para identificar usuarios internos predeterminados."
@@ -19707,7 +20901,7 @@ msgid "Specify the following URL during the Runner setup:"
msgstr "Especifique la siguiente dirección URL durante la configuración del ejecutor:"
msgid "Speed up your DevOps<br>with GitLab"
-msgstr ""
+msgstr "Acelere sus DevOps<br>con GitLab"
msgid "Squash commit message"
msgstr "Modificar el mensaje de commit"
@@ -19731,7 +20925,7 @@ msgid "Stage removed"
msgstr "Etapa eliminada"
msgid "Standard"
-msgstr ""
+msgstr "Estándar"
msgid "Star a label to make it a priority label. Order the prioritized labels to change their relative priority, by dragging."
msgstr "Resalte una etiqueta para convertirla en una etiqueta con prioridad. Ordene las etiquetas priorizadas para cambiar su prioridad relativa, arrastrando."
@@ -19766,8 +20960,8 @@ msgstr "Favoritos"
msgid "Stars"
msgstr "Estrellas"
-msgid "Start GitLab Ultimate trial"
-msgstr "Iniciar el periodo de prueba de GitLab Ultimate"
+msgid "Start Date"
+msgstr ""
msgid "Start Web Terminal"
msgstr "Iniciar Terminal web"
@@ -19841,6 +21035,9 @@ msgstr "Iniciado %{startsIn}"
msgid "Started asynchronous removal of all repository check states."
msgstr "Se inició la eliminación asíncrona de todos los estados de verificación del repositorio."
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr "Iniciando..."
@@ -19926,13 +21123,13 @@ msgid "StatusPage|AWS access key ID"
msgstr ""
msgid "StatusPage|AWS documentation"
-msgstr ""
+msgstr "Documentación de AWS"
msgid "StatusPage|AWS region"
-msgstr ""
+msgstr "Región de AWS"
msgid "StatusPage|Active"
-msgstr ""
+msgstr "Activo"
msgid "StatusPage|Bucket %{docsLink}"
msgstr ""
@@ -19944,13 +21141,13 @@ msgid "StatusPage|For help with configuration, visit %{docsLink}"
msgstr ""
msgid "StatusPage|S3 Bucket name"
-msgstr ""
+msgstr "Nombre del bucket S3"
msgid "StatusPage|Status page"
-msgstr ""
+msgstr "Página de estado"
msgid "StatusPage|Status page URL"
-msgstr ""
+msgstr "URL de la página de estado"
msgid "StatusPage|Status page frontend documentation"
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr "Manténgase informado sobre el rendimiento y la salud de su entorno mediante la configuración dePrometheus para monitorizar sus despliegues."
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr "Detener Terminal"
@@ -19994,6 +21194,9 @@ msgstr "Almacenamiento:"
msgid "StorageSize|Unknown"
msgstr "Desconocido"
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr "Resumen del subgrupo"
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr "Subclaves"
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr "Cambio sugerido"
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr "Verde brillante"
@@ -20288,6 +21500,9 @@ msgstr "El soporte para certificados personalizados está deshabilitado. Pida al
msgid "Support page URL"
msgstr "URL de la página de soporte"
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr "Cambiar rama/etiqueta"
@@ -20301,13 +21516,13 @@ msgid "Sync information"
msgstr "Sincronizar información"
msgid "Synced"
-msgstr ""
+msgstr "Sincronizado"
msgid "Synchronization disabled"
-msgstr ""
+msgstr "Sincronización deshabilitada"
msgid "Synchronization of container repositories is disabled."
-msgstr ""
+msgstr "La sincronización de los repositorios de contenedores está deshabilitada."
msgid "System"
msgstr "Sistema"
@@ -20315,9 +21530,6 @@ msgstr "Sistema"
msgid "System Hooks"
msgstr "Hooks de sistema"
-msgid "System Hooks Help"
-msgstr "Ayuda de los hooks del sistema"
-
msgid "System Info"
msgstr "Información del sistema"
@@ -20463,7 +21675,7 @@ msgid "Telephone number"
msgstr "Número de teléfono"
msgid "Telephone number (Optional)"
-msgstr ""
+msgstr "Número de teléfono (opcional)"
msgid "Template"
msgstr "Plantilla"
@@ -20500,8 +21712,8 @@ msgstr "Análisis de cobertura de las pruebas"
msgid "Test coverage: %d hit"
msgid_plural "Test coverage: %d hits"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Cobertura de la prueba: %d"
+msgstr[1] "Cobertura de la prueba: %d"
msgid "Test failed."
msgstr "Prueba fallida."
@@ -20569,11 +21781,14 @@ msgstr "Pruebas"
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr "¡Gracias por registrarse en la versión de prueba! En breve recibirá instrucciones adicionales en su bandeja de entrada."
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr "Gracias por su informe. Un administrador de GitLab lo examinará en breve."
msgid "Thanks for your purchase!"
-msgstr ""
+msgstr "¡Gracias por su compra!"
msgid "Thanks! Don't show me this again"
msgstr "¡Gracias! No mostrar esto de nuevo"
@@ -20652,9 +21867,6 @@ msgstr "La colección de eventos agregados a los datos recopilados para esa etap
msgid "The commit does not exist"
msgstr "El commit no existe"
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr "La conexión terminará después de %{timeout}. Para los repositorios que tarden más tiempo, utilice una combinación de git clone y git push."
@@ -20691,9 +21903,15 @@ msgstr "El dominio que ha introducido está mal formateado."
msgid "The domain you entered is not allowed."
msgstr "El dominio que ha introducido no está permitido."
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr "El mapa de usuario introducido no es un mapa de usuario JSON válido."
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr "El archivo se ha creado correctamente."
@@ -20732,6 +21950,9 @@ msgstr "El grupo y sus proyectos sólo se pueden ver por sus miembros."
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr "El grupo ya ha sido compartido con este grupo"
@@ -20906,6 +22127,9 @@ msgstr "La pestaña especificada no es válida, por favor seleccione otra"
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr "La etapa de puesta en escena muestra el tiempo entre la fusión y el despliegue de código en el entorno de producción. Los datos se añadirán automáticamente una vez que se despliega a producción por primera vez."
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr "La etapa de pruebas muestra el tiempo que GitLab CI toma para ejecutar cada pipeline para la solicitud de fusión relacionada. Los datos se añadirán automáticamente luego de que el primer pipeline termine de ejecutarse."
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr "No hay claves GPG asociadas con esta cuenta."
@@ -21029,6 +22256,15 @@ msgstr "No hay datos disponibles. Por favor, cambie su selección."
msgid "There was a problem communicating with your device."
msgstr "Se ha producido un problema al conectarse con su dispositivo."
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr "Se ha producido un error al cargar el calendario de actividades de los usuarios."
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr "Se ha producido un error al eliminar el correo electrónico."
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr "Se ha producido un error con reCAPTCHA. Por favor, resuelva el reCAPTCHA de nuevo."
@@ -21248,6 +22490,9 @@ msgstr "Este commit fue firmado con una firma verificada, pero <strong>no se ha
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr "Esta commit fue firmado con una firma <strong>no verificada</strong>."
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr "Esta fecha es posterior a la fecha de vencimiento, por lo que esta tarea épica no aparecerá en la hoja de ruta."
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr "Esta tarea épica no existe o no tiene permisos suficientes."
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr "Esta es una lista de dispositivos desde los que ha iniciado sesión. Cierre todas las sesiones que no reconozca."
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr "Este es un registro de seguridad de eventos importantes relacionados con su cuenta."
@@ -21446,8 +22691,8 @@ msgstr "Este trabajo está realizando tareas que deben completarse antes de que
msgid "This job is preparing to start"
msgstr "Este trabajo se está preparando para empezar"
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
-msgstr "Este trabajo está bloqueado porque no tienes ningún ejecutor activo en línea con ninguna de estas etiquetas asignadas:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
+msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
msgstr "Este trabajo está bloqueado porque no tiene ningún ejecutor activo que pueda ejecutar este trabajo."
@@ -21473,6 +22718,9 @@ msgstr "Esto puede exponer información confidencial ya que el fork seleccionado
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr "Esto significa que no puede enviar código hasta que cree un repositorio vacío o importe uno existente."
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr "Este merge request está bloqueado."
@@ -21509,12 +22757,18 @@ msgstr "Este proyecto"
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr "Este proyecto no pertenece a ningún grupo y, por lo tanto, no puede hacer uso de un grupo de ejecutores."
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr "Este proyecto todavía no tiene una pagina de inicio del wiki"
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr "Este proyecto no tiene la facturación habilitada. Para crear un clúster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">habilite la facturación <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> e inténtelo de nuevo."
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr "Este proyecto está archivado y no se puede comentar en el."
@@ -21527,12 +22781,24 @@ msgstr "Este proyecto será eliminado el %{date}"
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr "Este repositorio"
+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 "Actualmente, este repositorio está vacío. Se creará un nuevo pipeline de Auto DevOps tan pronto como haya añadido un archivo a una rama."
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr "Este ejecutor solo se ejecutará en pipelines disparados sobre ramas protegidas"
@@ -21551,8 +22817,8 @@ msgstr "Este tiempo de espera tendrá prioridad cuando sea más bajo que el tiem
msgid "This user cannot be unlocked manually from GitLab"
msgstr "Este usuario no puede ser desbloqueado manualmente desde GitLab"
-msgid "This user has no active %{type} Tokens."
-msgstr "Este usuario no tiene tokens %{type} activos."
+msgid "This user has no active %{type}."
+msgstr ""
msgid "This user has no identities"
msgstr "El usuario no tiene ninguna identidad"
@@ -21560,9 +22826,6 @@ msgstr "El usuario no tiene ninguna identidad"
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr "Peticiones"
@@ -21866,6 +23135,9 @@ msgstr "justo ahora"
msgid "Timeout"
msgstr "Tiempo de espera"
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] "hr"
@@ -21930,6 +23202,12 @@ msgstr "Para definir los usuarios internos, primero habilite nuevos usuarios ext
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 comenzar, introduzca su URL de FogBugz, y a continuación, introduzca la información de inicio de sesión. En los siguientes pasos, podrá asignar usuarios y seleccionar los proyectos que desea importar."
@@ -22050,6 +23328,9 @@ msgstr "Cambiar la descripción del commit"
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr "Contribuciones totales"
msgid "Total artifacts size: %{total_size}"
msgstr "Tamaño total de los artefactos: %{total_size}"
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr "Total de incidencias"
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr "Tiempo total de pruebas para todos los cambios o integraciones"
@@ -22131,9 +23406,6 @@ msgstr "Traza"
msgid "Tracing"
msgstr "Seguimiento"
-msgid "Track activity with Contribution Analytics."
-msgstr "Monitorizar la actividad con Contribution Analytics."
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr "Haga un seguimiento de grupos de incidencias que comparten un tema, a través de proyectos e hitos"
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr "Transferir proyecto"
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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."
@@ -22263,6 +23538,9 @@ msgstr ""
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 ""
+
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."
@@ -22320,10 +23598,10 @@ msgstr "URL"
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr "URL del almacenamiento externo que servirá los objetos estáticos del r
msgid "URL or request ID"
msgstr "URL o ID de solicitud"
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr "No se puede aplicar sugerencias a una línea eliminada."
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr "No se puede generar un nuevo ID de instancia"
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr "No se puede cargar el fichero diff. %{button_try_again}"
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr "No se puede resolver"
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr "No se pueden guardar sus cambios. Por favor, inténtelo de nuevo."
@@ -22632,18 +23922,12 @@ msgstr "Actualizando"
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr "Actualice su plan"
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr "Actualice su plan para activar la búsqueda global avanzada."
msgid "Upgrade your plan to activate Audit Events."
msgstr "Actualice su plan para activar Audit Events."
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr "Actualice su plan para activar la herramienta Contribution Analytics."
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr "Actualice su plan para activar la herramienta Group Webhooks."
@@ -22662,6 +23946,9 @@ msgstr "Subir fichero CSV"
msgid "Upload New File"
msgstr "Subir nuevo archivo"
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr "Suba un certificado para su dominio con todos los certificados intermedios"
@@ -22680,6 +23967,9 @@ msgstr "Hacer clic para subir"
msgid "Uploaded on"
msgstr "Subido en"
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr "Subir los cambios al terminal"
@@ -22704,9 +23994,6 @@ msgstr "Uso"
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr "Estadísticas de uso"
@@ -22716,12 +24003,18 @@ msgstr "%{help_link_start}Los ejecutores compartidos%{help_link_end} están desh
msgid "UsageQuota|Artifacts"
msgstr "Artefactos"
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr "Comprar minutos adicionales"
msgid "UsageQuota|Current period usage"
msgstr "Periodo actual de uso"
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr "Almacenamiento LFS"
@@ -22731,12 +24024,18 @@ msgstr "Paquetes"
msgid "UsageQuota|Pipelines"
msgstr "Pipelines"
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr "Repositorio"
msgid "UsageQuota|Storage"
msgstr "Almacenamiento"
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr "Este espacio de nombres no tiene proyectos que utilicen ejecutores compartidos"
@@ -22755,12 +24054,18 @@ msgstr "Uso de los recursos del grupo a través de los proyectos en el grupo %{s
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr "Uso desde"
msgid "UsageQuota|Wiki"
msgstr "Wiki"
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr "Use los hitos de grupo para administrar incidencias de múltiples proyec
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr "La cuota de minutos del pipeline fue restablecida con éxito."
msgid "User restrictions"
msgstr "Restricciones de usuario"
-msgid "User settings"
-msgstr "Configuración del usuario"
-
msgid "User was successfully created."
msgstr "Usuario creado correctamente."
@@ -23109,6 +24411,12 @@ msgstr "No has creado ningún fragmento de código."
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr "A su elección, sus proyectos pueden estar disponible públicamente, internamente o ser privados."
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr "Nombre de usuario (opcional)"
@@ -23169,6 +24477,9 @@ msgstr "Uso de %{code_start}::%{code_end} denota un %{link_start}con ámbito de
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr "Utilizar la estrategia de cifrado requerida cuando falta el campo cifrado"
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr "Validar"
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr "Verificar la configuración"
msgid "Version"
msgstr "Versión"
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr "Muy útil"
@@ -23284,6 +24601,9 @@ msgstr[1] "Ver %d artefactos expuestos"
msgid "View file @ "
msgstr "Ver archivo @ "
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr "Ver el panel de control completo"
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr "Ver commit"
@@ -23428,9 +24751,6 @@ msgstr "Vulnerabilidades"
msgid "Vulnerabilities over time"
msgstr "Vulnerabilidades a lo largo del tiempo"
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr "Trabajo en curso"
msgid "Wait for the file to load to copy its contents"
msgstr "Espera a que el archivo se cargue para copiar su contenido"
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr "Esperar por los datos de rendimiento"
@@ -23584,6 +24904,9 @@ msgstr "Advertencia:"
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr "No es posible determinar la ruta para eliminar esta tarea épica"
@@ -23605,8 +24928,14 @@ msgstr "No hay suficientes datos para mostrar en esta etapa."
msgid "We have found the following errors:"
msgstr "Hemos encontrado los siguientes errores:"
-msgid "We heard back from your U2F device. You have been authenticated."
-msgstr "Hemos obtenido respuesta desde su dispositivo U2F. Ha sido autenticado correctamente."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
+msgstr ""
msgid "We sent you an email with reset password instructions"
msgstr "Le enviamos un correo electrónico con las instrucciones para restablecer la contraseña"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr "Webhooks"
-msgid "Webhooks Help"
-msgstr "Ayuda de Webhooks"
-
msgid "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 "Los Webhooks le permiten invocar una URL si, por ejemplo, se realiza un push a o se crea una nueva incidencia. Puede configurar los webhooks para escuchar eventos específicos como pushes, incidencias, o merge request. Los webhooks de grupo se aplicarán a todos los proyectos de un grupo, permitiéndote estandarizar la funcionalidad del webhook a través de todo el grupo."
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr "Bienvenido al tour guiado de GitLab"
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr "¡Bienvenido a su tablón de incidencias!"
msgid "What are you searching for?"
msgstr "¿Qué está buscando?"
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr "Los ayudantes blancos proporcionan información contextual."
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr "¿Quién puede ser un aprobador?"
@@ -23766,9 +25098,6 @@ msgstr "Acceso Git"
msgid "WikiClone|Install Gollum"
msgstr "Instalar Gollum"
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr "Se recomienda instalar %{markdown} para que las características de GFM se procesen localmente:"
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr "Iniciar a Gollum y editar localmente"
@@ -23889,11 +25218,14 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr "Páginas del Wiki"
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr "Se desplegará a"
-msgid "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 "Con contribution analytics, puede tener una visión general de la actividad de las incidencias, los merge requests y los eventos push de su organización y sus miembros."
+msgid "With requirements, you can set criteria to check your products against."
+msgstr ""
msgid "Withdraw Access Request"
msgstr "Retirar Solicitud de Acceso"
@@ -23901,11 +25233,11 @@ msgstr "Retirar Solicitud de Acceso"
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
-msgstr "Ayuda sobre el flujo de trabajo"
+msgid "Work in progress Limit"
+msgstr ""
msgid "Write"
msgstr "Escritura"
@@ -24021,6 +25353,9 @@ msgstr "También puede validar su fichero %{gitlab_ci_yml} en %{lint_link_start}
msgid "You can also upload existing files from your computer using the instructions below."
msgstr "También puede subir archivos existentes desde su ordenador utilizando las instrucciones que se muestran a continuación."
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr "Puede instalar fácilmente un ejecutor en un clúster de Kubernetes. %{l
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr "Puedes invitar a otro grupo a <strong>%{project_name}</strong>."
msgid "You can move around the graph by using the arrow keys."
msgstr "Puede moverse por el gráfico usando las teclas de flecha."
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr "Aún no tiene ninguna suscripción"
@@ -24189,6 +25533,9 @@ msgstr "No tiene acceso a Productivity Analytics en este grupo"
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr "Se le ha concedido %{access_level} acceso al %{source_link} %{source_type}."
@@ -24204,7 +25551,7 @@ msgstr "Se ha cancelado la suscripción a este hilo."
msgid "You have declined the invitation to join %{label}."
msgstr "Has rechazado la invitación para unirse a %{label}."
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr "Trató de hacer un fork de %{link_to_the_project} pero falló por la sig
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr "Recibirás notificaciones por cualquier actividad"
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr "Recibirás notificaciones solo para los comentarios en los que se te mencionó"
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr "No podrás actualizar o enviar código al proyecto a través de %{protocol} hasta que %{set_password_link} en tu cuenta"
@@ -24342,6 +25695,12 @@ msgstr "Estás a punto de reducir la visibilidad del proyecto %{strong_start}%{p
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr "Estás a punto de reducir la visibilidad del proyecto %{strong_start}%{project_name}%{strong_end}."
+msgid "You're at the first commit"
+msgstr ""
+
+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 "No tiene permiso para %{tag_start}editar%{tag_end} directamente los archivos de este proyecto. Haga un fork de este proyecto, realice sus cambios y haga un merge request."
@@ -24375,7 +25734,10 @@ msgstr "Ya ha habilitado la autenticación de dos pasos utilizando una contraseÃ
msgid "YouTube"
msgstr "YouTube"
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,8 +25773,8 @@ msgstr ""
msgid "Your Groups"
msgstr "Sus grupos"
-msgid "Your New Personal Access Token"
-msgstr "Su nuevo token de acceso personal"
+msgid "Your License"
+msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
msgstr "Sus tokens de acceso personal caducarán en %{days_to_expire} días o menos"
@@ -24504,9 +25866,18 @@ msgstr "Se interrumpirán sus servicios de despliegue, tendrá que arreglarlos m
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr "¡El dispositivo se ha configurado correctamente!. Por favor, asígnele un nombre y regístrelo con el servidor de GitLab."
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr "Tus grupos"
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr "Se están importando sus incidencias. Al finalizar el proceso, recibirá un correo electrónico de confirmación."
@@ -24516,12 +25887,18 @@ msgstr "Sus incidencias serán importados como tarea de fondo. Al finalizar el p
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr "Su mensaje aquí"
msgid "Your name"
msgstr "Tu nombre"
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr "Su nuevo token SCIM"
@@ -24529,7 +25906,7 @@ msgid "Your new personal access token has been created."
msgstr "Se ha creado su nuevo token de acceso personal."
msgid "Your new project access token has been created."
-msgstr ""
+msgstr "Se ha creado un nuevo token de acceso al proyecto."
msgid "Your password isn't required to view this page. If a password or any other personal details are requested, please contact your administrator to report abuse."
msgstr "Su contraseña no es necesaria para ver esta página. Si se le solicita una contraseña o cualquier otro dato personal, póngase en contacto con su administrador para denunciar el abuso."
@@ -24546,9 +25923,15 @@ msgstr "¡Su límite de proyecto es %{limit} proyectos! Por favor, contacte con
msgid "Your projects"
msgstr "Tus proyectos"
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr "Su solicitud de acceso ha sido puesta en cola para su revisión."
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr "añadió una llamada de Zoom a esta incidencia"
msgid "ago"
msgstr "hace"
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr "permitido fallar"
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr "nombre de la rama"
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr "por"
@@ -24807,6 +26196,9 @@ msgstr "Dynamic Application Security Testing (DAST) detecta vulnerabilidades con
msgid "ciReport|Failed to load %{reportName} report"
msgstr "Se ha producido un error al cargar el informe %{reportName}"
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr "Solucionado:"
@@ -24825,6 +26217,9 @@ msgstr "Cargando el informe %{reportName}"
msgid "ciReport|Manage licenses"
msgstr "Administrar licencias"
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr "No hay cambios en la calidad del código"
@@ -24843,6 +26238,9 @@ msgstr "Resolver con un merge request"
msgid "ciReport|SAST"
msgstr "SAST"
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] "Utilizado por %{packagesString} y %{lastPackage}"
msgid "ciReport|View full report"
msgstr "Ver informe completo"
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr "comentario"
@@ -24893,6 +26294,9 @@ msgstr "comentado en %{link_to_project}"
msgid "commit %{commit_id}"
msgstr "commit %{commit_id}"
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr "Va a desactivar la confidencialidad. Esto significa que <strong>todos</strong> podrán ver y dejar un comentario sobre este tema."
@@ -24902,6 +26306,9 @@ msgstr "Va a activar la confidencialidad. Esto significa que solo los miembros d
msgid "connecting"
msgstr "conectando"
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr "el nombre contenedor no puede ser mayor que %{max_length} caracteres"
@@ -24952,6 +26359,9 @@ msgstr "no tiene una extensión compatible. Sólo %{extension_list} son compatib
msgid "done"
msgstr "hecho"
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] "borrador"
@@ -24963,8 +26373,11 @@ msgstr "por ejemplo %{token}"
msgid "element is not a hierarchy"
msgstr "el elemento no es una jerarquía"
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
-msgstr "el correo electrónico '%{email}' no coincide con el dominio permitido de '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
+msgstr ""
msgid "enabled"
msgstr "habilitado"
@@ -24996,11 +26409,11 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
-msgstr "expiró el %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
+msgstr ""
-msgid "expires on %{milestone_due_date}"
-msgstr "expira el %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
+msgstr ""
msgid "external_url"
msgstr ""
@@ -25064,9 +26477,18 @@ msgstr "aquí"
msgid "https://your-bitbucket-server"
msgstr "https://tu-servidor-bitbucket"
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr "imagen dif"
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr "flujo de importación"
@@ -25129,6 +26551,9 @@ msgstr "no es un correo electrónico de su propiedad"
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr "es demasiado largo (%{current_value}). El tamaño máximo permitido es de %{max_size}."
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr "es almacenado externamente"
@@ -25189,6 +26620,9 @@ msgstr "nivel %{level}"
msgid "limit of %{project_limit} reached"
msgstr "límite de %{project_limit} alcanzado"
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr "bloqueado por %{path_lock_user_name} %{created_at}"
@@ -25317,7 +26751,7 @@ msgstr "Eliminar la rama de origen"
msgid "mrWidget|Deployment statistics are not available currently"
msgstr "Las estadísticas de los despliegues no están disponibles actualmente"
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr "Puede hacer merge de este merge request manualmente usando el"
msgid "mrWidget|Your password"
msgstr "Su contraseña"
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr "la rama no existe."
@@ -25509,15 +26940,6 @@ msgstr "línea de comandos"
msgid "mrWidget|into"
msgstr "en"
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr "debe ser mayor que la fecha de inicio"
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr "n/a"
@@ -25575,6 +27000,9 @@ msgstr "%{item}, y %{lastItem}"
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr "abierto el %{timeAgoString} por %{user}"
@@ -25606,9 +27034,18 @@ msgstr "pendiente de eliminación"
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr "pipeline"
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr "el nombre del pod no puede ser mayor que %{max_length} chars"
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] "proyecto"
msgstr[1] "proyectos"
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr "avatar del proyecto"
@@ -25681,6 +27124,9 @@ msgstr "restablecer."
msgid "resolved the corresponding error and closed the issue."
msgstr "resolvió el error correspondiente y cerró la incidencia."
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr "puntuación"
@@ -25747,11 +27193,11 @@ msgstr "iniciado"
msgid "started a discussion on %{design_link}"
msgstr "inició una discusión en %{design_link}"
-msgid "started on %{milestone_start_date}"
-msgstr "comenzó en %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
+msgstr ""
-msgid "starts on %{milestone_start_date}"
-msgstr "comienza en %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
+msgstr ""
msgid "stuck"
msgstr "bloqueado"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr "actualizado %{time_ago}"
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr "avatar del usuario"
@@ -25840,6 +27292,9 @@ msgstr "ver en GitLab"
msgid "view the blob"
msgstr "ver el blob"
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr "Descartado"
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr "con %{additions} adiciones, %{deletions} eliminaciones."
diff --git a/locale/et_EE/gitlab.po b/locale/et_EE/gitlab.po
index d1cb6cb1c03..cf8248f2989 100644
--- a/locale/et_EE/gitlab.po
+++ b/locale/et_EE/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: et\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:32\n"
+"PO-Revision-Date: 2020-06-08 15:08\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,13 +8991,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8627,7 +9009,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] ""
msgstr[1] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/fa_IR/gitlab.po b/locale/fa_IR/gitlab.po
index 0fe3aefd655..d16e8bf2da1 100644
--- a/locale/fa_IR/gitlab.po
+++ b/locale/fa_IR/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: fa\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:31\n"
+"PO-Revision-Date: 2020-06-08 15:10\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,13 +8991,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8627,7 +9009,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] ""
msgstr[1] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/fi_FI/gitlab.po b/locale/fi_FI/gitlab.po
index 4ec4ee77c25..7b9c52d631d 100644
--- a/locale/fi_FI/gitlab.po
+++ b/locale/fi_FI/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: fi\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:14\n"
+"PO-Revision-Date: 2020-06-08 15:16\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,13 +8991,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8627,7 +9009,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] ""
msgstr[1] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/fil_PH/gitlab.po b/locale/fil_PH/gitlab.po
index 07f7779ecec..75ef8bbce44 100644
--- a/locale/fil_PH/gitlab.po
+++ b/locale/fil_PH/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: fil\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:33\n"
+"PO-Revision-Date: 2020-06-08 15:12\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,13 +8991,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8627,7 +9009,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] ""
msgstr[1] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/fr/gitlab.po b/locale/fr/gitlab.po
index fc31e7c2d23..2454a76cfb0 100644
--- a/locale/fr/gitlab.po
+++ b/locale/fr/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: fr\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:11\n"
+"PO-Revision-Date: 2020-06-08 15:14\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] "%d commentaire"
msgstr[1] "%d commentaires"
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] "%d commit"
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] "%d contribution"
msgstr[1] "%d contributions"
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr "%{commit_author_link} a créé %{commit_timeago}"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr "%{filePath} supprimé"
msgid "%{firstLabel} +%{labelCount} more"
msgstr "%{firstLabel} et %{labelCount} de plus"
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr "Les %{group_docs_link_start}groupes%{group_docs_link_end} vous permetten
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr "%{label_for_message} indisponible"
@@ -370,12 +438,21 @@ msgstr "%{loadingIcon} Démarré"
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr "%{lock_path} est verrouillé par l’utilisateur GitLab %{lock_user_id}"
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr "Avatar de %{name}"
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr "Veuillez contacter votre administrateur GitLab si vous pensez qu’il sâ
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr "Membres du groupe <strong>%{group_name}</strong>"
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr "<strong>Supprime</strong> la branche source"
@@ -821,6 +919,9 @@ msgstr "Un « exécuteur » est un processus qui exécute une tâche. Vous pou
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr "Un modèle d’application de console .NET Core, personnalisable pour tout projet .NET Core"
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr "Un site GitBook qui utilise Netlify comme intégration et livraison continues (CI/CD) au lieu de GitLab, mais en gardant toutes les autres fonctionnalités géniales de GitLab."
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr "Une personne avec un accès en écriture à la branche source a sélecti
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr "Accepter les conditions"
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr "Demandes de fusion acceptées"
-
msgid "Access Tokens"
msgstr "Jetons d’accès"
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr "Actif"
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr "Sessions actives"
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr "Activité"
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr "Ajouter une liste à puces"
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr "Ajoutez un commentaire général à %{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 "Ajoutez une page d’accueil à votre wiki contenant des informations sur votre projet. GitLab l’affichera ici à la place de ce message."
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr "Ajouter un lien"
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr "Ajouter une liste numérotée"
@@ -1198,7 +1305,10 @@ msgstr "Ajouter un texte apparaissant dans toutes communications par courriel (%
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr "Ajouter une réaction"
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,18 +1467,18 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr "Espace d’administration"
+msgid "Admin Note"
+msgstr ""
+
msgid "Admin Overview"
msgstr "Vue administrateur"
-msgid "Admin Section"
-msgstr ""
-
msgid "Admin mode already enabled"
msgstr ""
@@ -1690,63 +1803,117 @@ msgstr "Après modification de votre mot de passe, vous serez redirigé vers lâ€
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] "Alerte"
msgstr[1] "Alertes"
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr "Une application appelée %{link_to_client} demande l’accès à votre compte 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 ""
+
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 "Un champ utilisateur Gitlab vide ajoutera le nom complet de l’utilisateur FogBugz (p. ex., « Par John Smith ») dans la description de tous les tickets et commentaires. Il associera ou assignera ces tickets et commentaires au créateur du projet."
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr "Une erreur est survenue lors du chargement des données du graphique"
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr "Une erreur s’est produite lors du chargement des signatures du commit"
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr "Une erreur est survenue lors de l’abonnement aux notifications."
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr "Analyse"
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr "Tout"
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr "Toute étiquette"
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr "Voulezâ€vous vraiment supprimer %{group_name} ?"
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr "Êtesâ€vous sûr(e) de vouloir supprimer cette identité ?"
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr "Êtesâ€vous sûr·e de vouloir réinitialiser le jeton de bilan de santé ?"
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr "Tickets assignés"
msgid "Assigned Merge Requests"
msgstr "Demandes de fusion assignées"
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr "Assigné à moi"
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr "août"
@@ -2835,6 +3065,9 @@ msgstr "Autoriser"
msgid "Authorize %{link_to_client} to use your account?"
msgstr "Autoriser %{link_to_client} à utiliser votre compte ?"
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr "Auto DevOps activé"
msgid "Auto DevOps, runners and job artifacts"
msgstr "Auto DevOps, exécuteurs et artéfacts de tâches"
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr "documentation Auto DevOps"
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr "Activer dans les paramètres"
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr "Marqué automatiquement comme utilisateur interne par défaut"
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr "Disponible"
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
+msgid "Burnup chart"
+msgstr ""
+
msgid "Business"
msgstr ""
msgid "Business metrics (Custom)"
msgstr "Métriques commerciales (personnalisées)"
-msgid "Buy EE"
-msgstr ""
-
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr "Intégration et livraison continues"
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr "Paramètres CI / CD (intégration et livraison continues)"
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr "Intégration et livraison continues pour dépôt externe"
msgid "CI/CD settings"
msgstr "Paramètres de l’intégration et de la livraison continues"
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr "Auto DevOps"
@@ -3489,9 +3734,6 @@ msgstr "Le pipeline Auto DevOps sera exécuté si aucun autre fichier de config
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr "Impossible de trouver le dernier commit (HEAD) pour cette branche"
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr "Changer de modèle"
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr "Les modifications sont affichées comme si la révision <b>source</b> était fusionnée dans la révision<b>cible</b>."
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr "La validation a échoué"
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr "Effacer la recherche"
msgid "Clear search input"
msgstr "Vider le champ de recherche"
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr "Cliquez sur le bouton <strong>Sélectionner aucun</strong> sur la droit
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr "Cliquez sur le bouton ci-dessous pour lancer le processus d’installation en accédant à la page Kubernetes"
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr "Cliquez pour l’agrandir."
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr "Fermer"
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr "Copier le nom de la grappe de serveurs Kubernetes"
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr "Activez ce paramètre si vous utilisez le contrôle d’accès basé sur
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,12 +4898,12 @@ msgstr "Groupe de la grappe de serveurs"
msgid "ClusterIntegration|Helm Tiller"
msgstr "Helm Tiller"
+msgid "ClusterIntegration|Helm release failed to install"
+msgstr ""
+
msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr "Helm rationalise l’installation et la gestion des applications Kubernetes. Tiller s’exécute sur votre grappe de serveurs Kubernetes et gère les publications de vos graphiques."
-msgid "ClusterIntegration|Hide"
-msgstr "Masquer"
-
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
msgstr "Si vous configurez plusieurs grappes de serveurs et que vous utilisez Auto DevOps, %{help_link_start}veillez d’abord lire ceci%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr "Afficher"
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr "Un problème est survenu de notre côté."
@@ -5115,6 +5378,9 @@ msgstr "Activer/désactiver la grappe de serveurs Kubernetes"
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr "Vous devez d’abord installer Helm Tiller avant d’installer les applications ciâ€dessous"
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr "Votre compte doit disposer de %{link_to_kubernetes_engine}"
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr "Masquer la barre latérale"
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr "Position du formulaire de commentaire"
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr "Configurer le traçage"
@@ -5537,9 +5827,6 @@ msgstr "Configurez le chemin d’accès au stockage."
msgid "Configure the %{link} integration."
msgstr "Configurez l’intégration de %{link}."
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr "Configurez la manière dont une personne crée un nouveau compte."
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr "Étiquette"
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr "Contribution"
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr "Copier l’URL %{protocol} de clonage"
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr "Copier le lien"
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr "Créer"
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr "Créer un nouveau ticket"
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr "Créer un jeton d’accès personnel pour votre compte afin de récupér
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr "Créer une étiquette de groupe"
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr "Créer des listes à partir d’étiquettes. Les tickets avec l’étiquette sélectionnée apparaissent dans cette liste."
@@ -6208,6 +6499,9 @@ msgstr "Créer une demande de fusion et une branche"
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr "Créer votre première page"
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr "Créé par moi"
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr "Fuseau horaire des tâches planifiées cron"
-msgid "Cron syntax"
-msgstr "Syntaxe de la planification cron"
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr "Paramètres"
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr "Personnaliser les couleurs"
@@ -6466,6 +6775,9 @@ msgstr "Personnalisez la configuration de votre pipeline et affichez son état e
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr "Étiquette de classement par défaut"
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr "Par défaut : associer un identifiant de compte FogBugz à un nom compl
msgid "Define a custom pattern with cron syntax"
msgstr "Définir un schéma personnalisé avec une syntaxe Cron"
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr "Supprimer le commentaire"
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr "Jetons de déploiement actifs : (%{active_tokens})"
msgid "DeployTokens|Add a deploy token"
msgstr "Ajouter un jeton de déploiement"
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr "Autorise l’accès en lecture seule aux images du registre"
msgid "DeployTokens|Allows read-only access to the repository"
msgstr "Autorise l’accès en lecture seule au dépôt"
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr "Jetons de déploiement"
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr "Expire"
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr "Détruire"
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr "Détails"
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr "Votes négatifs"
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr "Date d’échéance"
@@ -7733,6 +8100,9 @@ msgstr "Courriel"
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr "Activer l’authentification SAML pour ce groupe"
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr "Activer et configurer les métriques InfluxDB."
-
msgid "Enable and configure Prometheus metrics."
msgstr "Activer et configurer les métriques Prometheus."
@@ -7880,6 +8253,9 @@ msgstr "Activer les exécuteurs de groupe"
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr "Entrez la description de la demande de fusion"
msgid "Enter the merge request title"
msgstr "Entrez l’intitulé de la demande de fusion"
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr "Les épopées vous permettent de gérer votre portefeuille de projets pl
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr "Comment puisâ€je résoudre ceci ?"
@@ -8390,7 +8763,16 @@ msgstr "Erreur lors de la création de l’épopée"
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr "Erreur lors de la mise à jour de l’étiquette."
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,12 +8946,12 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Estimate"
+msgstr ""
+
msgid "Estimated"
msgstr "Estimé"
-msgid "Event Actions"
-msgstr ""
-
msgid "EventFilterBy|Filter by all"
msgstr "Tout filtrer"
@@ -8609,14 +8991,14 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
-msgstr "Chaque jour (à 4 h du matin)"
+msgid "Every day (at %{time})"
+msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
-msgstr "Chaque mois (le 1ᵉʳ à 4 h du matin)"
+msgid "Every month (Day %{day} at %{time})"
+msgstr ""
msgid "Every three months"
msgstr ""
@@ -8627,8 +9009,8 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
-msgstr "Chaque semaine (dimanche à 4 h du matin)"
+msgid "Every week (%{weekday} at %{time})"
+msgstr ""
msgid "Everyone"
msgstr ""
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr "Étendre la barre latérale"
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr "Étiquette de classification"
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr "Lorsqu’aucune étiquette de classification n’est définie, l’étiquette par défaut « %{default_label} » sera utilisée."
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr "Description"
msgid "FeatureFlags|Edit Feature Flag"
msgstr "Modifier l’indicateur de fonctionnalité"
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr "Indicateur de fonctionnalité"
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr "Identifiant d’instance"
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr "Nouveau"
msgid "FeatureFlags|New Feature Flag"
msgstr "Nouvel indicateur de fonctionnalité"
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr "Modèles de fichiers"
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr "Fichiers"
@@ -9290,24 +9708,45 @@ msgstr "Renseignez les champs ciâ€dessous, activez <strong>%{enable_label}</str
msgid "Filter"
msgstr "Filtrer"
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr "Filtrer sur les tickets de type %{issuable_type} qui sont actuellement fermés."
msgid "Filter by %{issuable_type} that are currently opened."
msgstr "Filtrer sur les tickets de type %{issuable_type} qui sont actuellement ouverts."
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr "Filtrer par message de commit"
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9396,7 +9838,7 @@ msgid "Fixed start date"
msgstr "Date de début fixe"
msgid "Fixed:"
-msgstr "Fixée :"
+msgstr "Corrigé :"
msgid "Flags"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr "Depuis la création du ticket jusqu’au déploiement en production"
msgid "From merge request merge until deploy to production"
msgstr "Depuis la fusion de la demande de fusion jusqu’au déploiement en production"
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr "À partir de l’affichage des détails de la grappe de serveurs Kubernetes, installez un exécuteur à partir de la liste des applications"
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr "Geo"
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr "NÅ“uds Geo"
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr "%{name} est programmé pour le reâ€téléchargement forcé"
@@ -9785,10 +10230,10 @@ msgstr "%{name} est programmé pour la reâ€synchronisation"
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
-msgstr "Tous"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr "Jamais"
msgid "Geo|Next sync scheduled at"
msgstr "Prochaine synchro programmée à"
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr "Pas encore synchronisé"
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr "Statut"
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr "L’entrée de suivi du projet (%{project_id}) a été supprimée avec s
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr "État inconnu"
@@ -10169,9 +10632,6 @@ msgstr "URL de l’hôte Gitea"
msgid "Gitea Import"
msgstr "Importation depuis Gitea"
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr "Aller vers"
-
msgid "Go to %{link_to_google_takeout}."
msgstr "Consultez le site de %{link_to_google_takeout}."
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr "Groupe"
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr "URL du groupe"
msgid "Group avatar"
msgstr "Avatar de groupe"
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr "Description du groupe"
@@ -10421,10 +10893,13 @@ msgstr "Détails du groupe"
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr "Les responsables de groupe peuvent créer des exécuteurs de groupe via
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr "Nom du groupe"
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr "ne peut pas être désactivé lorsque le groupe parent a activé le « Partage avec verrou de groupe », sauf par le propriétaire du groupe parent."
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr "Récupérer les adresses de courriel des utilisateurs"
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr "Message d’enâ€tête"
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr "Historique"
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr "Si activé, l’accès aux projets sera validé sur un service externe e
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr "Si vous utilisez GitHub, vous verrez les statuts des pipelines sur GitHub pour vos commits et demandes d’intégration (pull requests). %{more_info_link}"
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,15 +11677,15 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
+msgid "Impersonation Tokens"
+msgstr ""
+
msgid "Impersonation has been disabled"
msgstr ""
msgid "Import"
msgstr "Importer"
-msgid "Import %{status}"
-msgstr ""
-
msgid "Import CSV"
msgstr ""
@@ -11184,6 +11695,9 @@ msgstr "Importe des projets depuis Gitea"
msgid "Import all compatible projects"
msgstr "Importer tous les projets compatibles"
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr "Importer tous les projets"
@@ -11193,6 +11707,9 @@ msgstr "Importer tous les dépôts"
msgid "Import an exported GitLab project"
msgstr "Importer un projet GitLab exporté"
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr "Importation en cours"
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,12 +11815,12 @@ msgstr "Améliorez le tableau des tickets avec Gitlab Entreprise Edition."
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
-msgstr "Améliorez la gestion des tickets grâce à la pondération disponible dans la version Entreprise Edition de GitLab."
-
msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr "Améliorez vos recherches avec la recherche globale avancée de GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
+msgstr ""
+
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
msgstr "Afin d’activer les statistiques au niveau de l’instance, veuillez demander à un administrateur d’activer la %{usage_ping_link_start}collecte des données d’utilisation%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr "Inclure un accord sur les conditions générales d’utilisation et la p
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr "Projet incompatible"
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr "Entrer les clefs d’hôte manuellement"
msgid "Input your repository URL"
msgstr "Entrez l’URL de votre dépôt"
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr "Intégrations"
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr "Les personnes intéressées peuvent même contribuer en poussant des commits si elles le souhaitent."
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr "Inviter"
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr "Tableau"
@@ -11684,6 +12300,9 @@ msgstr "Tickets clos"
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr "URL Jaeger"
@@ -11741,19 +12384,22 @@ msgstr "janv."
msgid "January"
msgstr "janvier"
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr "Les artefacts ont été supprimés"
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr "juin"
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
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 ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr "Apprenezâ€en plus dans la"
@@ -12232,6 +12887,9 @@ msgstr "Quitter le projet"
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr "Laisser les options « type de fichier » et « mode de livraison » à leurs valeurs par défaut."
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr "Licence"
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr "Chargement…"
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr "Assurezâ€vous d’être connecté avec le compte propriétaire des projets que vous souhaitez importer."
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr "Gérer les étiquettes de groupe"
msgid "Manage labels"
msgstr "Gérer les étiquettes"
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr "Gérer les étiquettes de projet"
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr "Markdown activé"
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr "Demande de fusion"
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr "Demandes de fusion"
@@ -12965,6 +13629,9 @@ msgstr "Demande de fusion"
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr "Approbations de la demande de fusion"
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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."
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr "Fusionnée"
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr "Messages"
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,21 +13815,24 @@ msgstr "Métriques"
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr "Métriques — Influx"
-
msgid "Metrics - Prometheus"
msgstr "Métriques — Prometheus"
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
-msgstr "Statistiques et rapports"
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is valid."
msgstr ""
+msgid "Metrics and profiling"
+msgstr "Statistiques et rapports"
+
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr "Libellé de légende (facultatif)"
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr "Documentation des requêtes Prometheus"
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr "Le point de terminaison Prometheus a renvoyé une réponse contenant des
msgid "Metrics|Unit label"
msgstr "Libellé de l’unité"
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr "Utilisé comme titre pour le graphique"
@@ -13347,6 +14059,63 @@ 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 "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr "Jalons"
@@ -13356,6 +14125,12 @@ msgstr "Vous êtes sur le point de supprimer définitivement le jalon %{mileston
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr "Vous êtes sur le point de supprimer définitivement le jalon %{milestoneTitle}. Ce jalon n’est actuellement référencé par aucun ticket ni aucune demande de fusion."
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr "Supprimer le jalon"
@@ -13365,21 +14140,39 @@ msgstr "Supprimer le jalon %{milestoneTitle} ?"
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr "Impossible de supprimer le jalon %{milestoneTitle}"
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr "Le jalon %{milestoneTitle} est introuvable"
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr "Promouvoir %{milestoneTitle} en tant que jalon de groupe ?"
msgid "Milestones|Promote Milestone"
msgstr "Promouvoir le jalon"
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr "Cette action ne peut pas être annulée."
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr "Annuler"
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr "Tableaux de tickets multiples"
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr "Nom"
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr "Nommez la nouvelle étiquette"
@@ -13587,9 +14386,6 @@ msgstr "Nom :"
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr "Réseau"
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr "Jamais"
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] "Nouveau ticket"
msgstr[1] "Nouveaux tickets"
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr "Nouveau ticket"
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr "Nouvelle étiquette"
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr "Aucune étiquette"
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr "Aucun fichier trouvé."
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr "Aucune étiquette avec un tel nom ou une telle description"
@@ -13925,6 +14775,9 @@ msgstr "Aucune demande de fusion trouvée"
msgid "No messages were logged"
msgstr "Aucun message n’a été enregistré"
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr "Souhaitezâ€vous réellement annuler la création de ce commentaire ?"
msgid "Notes|Collapse replies"
msgstr "Réduire les réponses"
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr "Afficher toute l’activité"
@@ -14198,9 +15057,15 @@ msgstr "nov."
msgid "November"
msgstr "novembre"
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr "Seuls les membres du projet peuvent commenter."
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,8 +15260,8 @@ msgstr ""
msgid "Opened"
msgstr "Ouvert"
-msgid "Opened MR"
-msgstr "Demandes de fusion ouvertes"
+msgid "Opened MRs"
+msgstr ""
msgid "Opened issues"
msgstr "Tickets ouverts"
@@ -14404,6 +15275,9 @@ msgstr "Ouvrir dans une nouvelle fenêtre"
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr "Le tableau de bord des opérations fournit un résumé de l’état de s
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr "Propriétaire"
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr "Le paquet a été supprimé"
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr "Paquets"
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr "Optimisation des performances"
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr "Droits d’accès"
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr "Autorisations, LFS, 2FA"
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr "Pipelines de l’année dernière"
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr "Ce projet n’est actuellement pas configuré pour exécuter des pipelin
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr "Commit"
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr "Durée"
msgid "Pipeline|Existing branch name or tag"
msgstr "Nom de branche ou d’étiquette existant"
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr "Pipeline"
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr "Exécuter le pipeline"
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr "Chercher des branches"
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr "Spécifier la valeur de la variable à utiliser lors de l’exécution. Les valeurs spécifiées dans %{settings_link} seront utilisées par défaut."
@@ -15130,6 +16082,9 @@ msgstr "Arrêter le pipeline"
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr "Arrêter le pipeline numéro %{pipelineId} ?"
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr "Diff brut"
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr "PlantUML"
@@ -15259,6 +16220,9 @@ msgstr "Veuillez noter que cette application n’est pas fournie par GitLab, vou
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr "Préférences"
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+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"
@@ -15460,6 +16430,9 @@ msgstr "Aperçu de la charge utile"
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr "Chemin d’accès"
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr "Position et taille de votre nouvel avatar"
@@ -15874,12 +16841,6 @@ msgstr "Votre statut"
msgid "Profiles|e.g. My MacBook key"
msgstr "p. ex., Ma clef MacBook"
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr "Mise à jour du projet « %{project_name} » effectuée."
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr "Avatar du projet"
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,8 +16955,8 @@ msgstr "L’exportation du projet a été supprimée."
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr "Le lien de l’exportation du projet a expiré. Merci de générer une nouvelle exportation depuis les paramètres du projet."
-msgid "Project export started. A download link will be sent by email."
-msgstr "L’exportation du projet a débuté. Un lien de téléchargement sera envoyé par courriel."
+msgid "Project export started. A download link will be sent by email and made available on this page."
+msgstr ""
msgid "Project has too many %{label_for_message} to search"
msgstr ""
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr "Nom du projet"
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr "Configuration automatique"
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr "Déployer et configurer automatiquement Prometheus sur vos grappes de serveurs pour surveiller les environnements de vos projets"
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr "Métriques communes"
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr "Les métriques courantes sont automatiquement supervisées grâce à une bibliothèque de métriques provenant d’exportateurs populaires."
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr "Métriques personnalisées"
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr "Promouvoir ces jalons de projets en jalon de groupe."
-msgid "Promote to Group Milestone"
-msgstr "Promouvoir en jalon de groupe"
-
msgid "Promote to group label"
msgstr "Promouvoir en tant qu’étiquette de groupe"
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr "Ne plus réafficher ce message"
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 "Les épopées vous permettent de gérer votre portefeuille de projets plus efficacement et avec moins d’efforts grâce au suivi de groupes de tickets qui partagent un thème commun au travers de différents projets et jalons."
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr "Cette fonctionnalité est verrouillée."
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr "Mise à niveau du forfait"
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr "Public — le groupe ainsi que n’importe quel projet public est access
msgid "Public - The project can be accessed without any authentication."
msgstr "Public - le projet est accessible sans aucune authentification."
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr "Pipelines publics"
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr "Récupérer"
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr "Les actions rapides peuvent être utilisées dans la description des tickets et dans les zones de commentaire."
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr "Tâches déployées liées"
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr "Supprimer le groupe"
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr "Rouvrir l’épopée"
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr "Dépôt par URL"
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr "Paramètres du dépôt"
msgid "Repository URL"
msgstr "URL du dépôt"
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr "Sélectionner"
msgid "Request Access"
msgstr "Demander l’accès"
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
msgstr "Profils de requêtes"
-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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr "Les exécuteurs peuvent fonctionner sur différents serveurs, avec diffÃ
msgid "Runners currently online: %{active_runners_count}"
msgstr "Exécuteurs actuellement en ligne : %{active_runners_count}"
-msgid "Runners page"
-msgstr "Page des exécuteurs"
-
msgid "Runners page."
msgstr "Page des exécuteurs."
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr "Clefs SSH"
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr "Rechercher"
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr "Rechercher des branches"
@@ -18115,6 +19226,9 @@ msgstr "Rechercher des projets"
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr "Rechercher des utilisateurs et utilisatrices"
@@ -18145,11 +19259,11 @@ msgstr "Demandes de fusion qui me sont assignées"
msgid "SearchAutocomplete|in all GitLab"
msgstr "Dans tout GitLab"
-msgid "SearchAutocomplete|in this group"
-msgstr "Dans ce groupe"
+msgid "SearchAutocomplete|in group %{groupName}"
+msgstr ""
-msgid "SearchAutocomplete|in this project"
-msgstr "Dans ce projet"
+msgid "SearchAutocomplete|in project %{projectName}"
+msgstr ""
msgid "SearchCodeResults|in"
msgstr ""
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr "Secret"
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr "Sécurité"
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr "Tableau de bord de sécurité"
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr "Sélectionner"
msgid "Select Archive Format"
msgstr "Sélectionnez le format de l’archive"
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr "Sélectionnez une grappe de serveurs Kubernetes existante ou créezâ€en une nouvelle"
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr "Sélectionner une branche ou une étiquette"
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr "Sélectionner une branche source"
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr "Sélectionner une branche cible"
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr "Envoyer un courriel"
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr "Définir un dépôt de modèles au niveau de l’instance"
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr "Définissez le temps maximal de la session pour le terminal Web."
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr "Transactions Sherlock"
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr "Afficher le journal brut complet"
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr "Afficher la dernière version"
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] "Affichage de %d évènement"
msgstr[1] "Affichage de %d événements"
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr "L’authentification par carte à puce a échoué : un enâ€tête de ce
msgid "Snippets"
msgstr "Extraits de code"
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr "Une erreur s’est produite lors de la « résolution » de la discuss
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr "Trier par"
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr "Niveau d’accès, croissant"
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr "Stockage :"
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr "Changer de branche ou d’étiquette"
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr "« Hooks » système"
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr "Informations système"
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr "L’ensemble d’événements ajoutés aux données recueillies pour cet
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr "La connexion expirera après %{timeout}. Pour les dépôts qui nécessitent plus de temps, utilisez une combinaison de clone et push."
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr "L’étape de pré-production indique le temps entre l’acceptation d’une demande fusion et le déploiement du code dans l’environnent de production. Les données seront automatiquement ajoutées lorsque vous aurez fait votre première mise en production."
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr "L’étape de test montre le temps que que met l’intégration continue de GitLab pour exécuter chaque pipeline pour une demande de fusion donnée. Les données seront automatiquement ajoutées après que votre premier pipeline s’achèvera."
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr "Une erreur s’est produite lors du chargement du calendrier d’activité des utilisateurs."
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr "Cette date est postérieure à la date d’échéance, cette épopée n’apparaîtra donc pas dans la feuille de route."
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr "Il s’agit d’une tâche différée devant être exécutée dans %{rem
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr "Cela signifie que vous ne pouvez pas pousser du code tant que vous n’avez pas créé un dépôt vide ou que vous n’avez pas importé un dépôt existant."
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr "Cette demande de fusion est verrouillée."
@@ -21509,12 +22757,18 @@ msgstr "Ce projet"
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr "Ce projet n’appartient pas à un groupe et ne peut donc pas faire appel à un exécuteur de groupe."
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr "Ce projet n’a pas encore de page d’accueil de wiki"
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr "Ce projet n’a pas de facturation activée. Afin de créer une grappe de serveurs, veuillez <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">activer la facturation<i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> et réessayer."
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr "Ce dépôt"
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr "Cet exécuteur ne fonctionnera que sur les pipelines déclenchés sur des branches protégées"
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr "Cet utilisateur ou cette utilisatrice n’a aucune identité"
msgid "This 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 "Cet utilisateur sera l’auteur de tous les événements du flux d’activité résultant d’une mise à jour, comme la création de nouvelles branches ou les nouveaux commits poussés vers des branches existantes."
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr "Cet utilisateur sera l’auteur de tous les événements du flux d’activité résultant d’une mise à jour, comme la création de nouvelles branches ou les nouveaux commits poussés vers des branches existantes. Lors de la création ou lors de la réaffectation, vous ne pouvez assigner que vousâ€même comme utilisateur du miroir."
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr "immédiatement"
msgid "Timeout"
msgstr "Délai d’attente"
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] "hr"
@@ -21930,6 +23202,12 @@ msgstr "Afin de définir les utilisateurs internes, veuillez d’abord activer l
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr "Afin d’activer et d’afficher les cohortes d’utilisateurs, consultez les %{application_settings_link_start}paramètres de l’application%{application_settings_link_end}."
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 "Pour commencer, entrez votre URL FogBugz et vos informations de connexion ciâ€dessous. Dans les étapes suivantes, vous pourrez mettre en correspondance les comptes des utilisateurs et sélectionner les projets à importer."
@@ -22050,6 +23328,9 @@ msgstr "Afficher ou masquer la description du commit"
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr "Total des contributions"
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr "Temps total de test pour tous les commits/fusions"
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr "Traçage"
-msgid "Track activity with Contribution Analytics."
-msgstr "Suivre l’activité avec l’analyse des contributions."
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr "Suivre les groupes de tickets qui partagent un thème, entre différents projets et jalons"
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr "Impossible de charger le diff. %{button_try_again}"
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr "Mise à jour en cours"
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr "Mettez à niveau votre forfait pour activer la recherche globale avancée."
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr "Mettez à niveau votre forfait pour activer l’analyse des contributions."
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr "Mettez à niveau votre forfait pour activer les webhooks de groupe."
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr "Téléverser un nouveau fichier"
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr "Cliquez pour envoyer"
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr "L’envoi des données d’utilisation est désactivé"
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr "Statistiques d’utilisation"
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr "Utilisez les jalons de groupe pour gérer les tickets de plusieurs proje
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr "Version"
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr "Voir le fichier @ "
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr "Nous n’avons pas suffisamment de données pour afficher cette étape."
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 "Les webhooks vous permettent de déclencher une URL si, par exemple, du nouveau code est poussé ou un nouveau ticket est créé. Vous pouvez configurer les webhooks pour écouter les événements spécifiques comme des poussées de code, des tickets ou des demandes de fusion. Les webhooks de groupes s’appliqueront à tous les projets dans un groupe, ce qui vous permet de normaliser la fonctionnalité du webhook dans votre groupe entier."
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr "Accès git"
msgid "WikiClone|Install Gollum"
msgstr "Installer Gollum"
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr "Il est recommandé d’installer %{markdown} pour que les spécificités de GFM s’affichent en local :"
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr "Démarrer Gollum et modifier localement"
@@ -23889,11 +25218,14 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr "Pages du Wiki"
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "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 "Grâce à l’analyse des contributions, vous pouvez avoir une vue d’ensemble de l’activité concernant les tickets, les demandes de fusion et les poussées Git de l’ensemble de votre organisation et de chacun de ses membres."
+msgid "With requirements, you can set criteria to check your products against."
+msgstr ""
msgid "Withdraw Access Request"
msgstr "Retirer la demande d’accès"
@@ -23901,10 +25233,10 @@ msgstr "Retirer la demande d’accès"
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr "Vous pouvez facilement installer un Exécuteur sur un cluster Kubernetes
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr "Vous pouvez vous déplacer dans le graphique en utilisant les touches fléchées."
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr "Vous n’avez souscrit à aucun abonnement pour le moment"
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr "Vous recevrez des notifications pour n’importe quelles activités"
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr "Vous ne recevrez de notifications que pour les commentaires où vous êtes @mentionné"
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr "Vous devez %{set_password_link} pour votre compte afin de pouvoir récupérer ou pousser du code via %{protocol}"
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr "YouTube"
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr "Vos groupes"
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr "Vos groupes"
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr "Votre nom"
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr "Vos projets"
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr "auparavant "
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr "nom de la branche"
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr "par"
@@ -24807,6 +26196,9 @@ msgstr "Le test de sécurité d’applications dynamique (Dynamic Application Se
msgid "ciReport|Failed to load %{reportName} report"
msgstr "Impossible de charger le rapport %{reportName}"
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr "Corrigé :"
@@ -24825,6 +26217,9 @@ msgstr "Chargement du rapport %{reportName}"
msgid "ciReport|Manage licenses"
msgstr "Gérer les licences"
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr "Aucun changement dans la qualité du code"
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr "SAST"
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] "Utilisé par %{packagesString} et %{lastPackage}"
msgid "ciReport|View full report"
msgstr "Voir le rapport complet"
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr "Vous êtes sur le point de désactiver la confidentialité. Cela signifie que <strong>tout le monde</strong> sera en mesure de voir et de laisser un commentaire sur ce ticket."
@@ -24902,6 +26306,9 @@ msgstr "Vous êtes sur le point de d’activer la confidentialité. Cela signifi
msgid "connecting"
msgstr "connexion en cours"
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr "terminé"
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] "brouillon"
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr "ici"
msgid "https://your-bitbucket-server"
msgstr "https://votre-serveur-bitbucket"
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr "flux d’importation"
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr "verrouillé par %{path_lock_user_name} %{created_at}"
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr "Les statistiques de déploiement ne sont pas disponibles pour le moment"
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr "Vous pouvez fusionner cette demande de fusion manuellement à l’aide d
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr "la branche n’existe pas."
@@ -25509,15 +26940,6 @@ msgstr "ligne de commande"
msgid "mrWidget|into"
msgstr "dans"
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr "non disponible"
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] "projet"
msgstr[1] "projets"
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr "démarré"
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr "voir sur GitLab"
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr "avec %{additions} ajouts, %{deletions} suppressions."
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 7d7701bd617..17203d2f16e 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -76,6 +76,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -96,6 +106,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -119,6 +134,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -189,6 +209,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -219,6 +244,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -294,6 +329,9 @@ msgstr ""
msgid "%{days} days until tags are automatically removed"
msgstr ""
+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 ""
+
msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgstr ""
@@ -333,18 +371,51 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
-msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
+msgid "%{host} sign-in from new location"
+msgstr ""
+
+msgid "%{icon}You are about to add %{usersTag} people to the discussion. They will all receive a notification."
+msgstr ""
+
+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 ""
msgid "%{issuableType} will be removed! Are you sure?"
msgstr ""
+msgid "%{issuesCount} issues in this group"
+msgstr ""
+
msgid "%{issuesSize} issues"
msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -366,9 +437,6 @@ msgstr ""
msgid "%{link_start}Read more%{link_end} about role permissions"
msgstr ""
-msgid "%{link} can be used for binding events when something is happening within the project."
-msgstr ""
-
msgid "%{listToShow}, and %{awardsListLength} more."
msgstr ""
@@ -378,12 +446,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -393,16 +470,16 @@ msgstr ""
msgid "%{name} found %{resultsString}"
msgstr ""
-msgid "%{name} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgid "%{name} is scheduled for %{action}"
msgstr ""
-msgid "%{name} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgid "%{name}'s avatar"
msgstr ""
-msgid "%{name} is scheduled for %{action}"
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
msgstr ""
-msgid "%{name}'s avatar"
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
msgstr ""
msgid "%{no_of_days} day"
@@ -445,6 +522,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -545,6 +628,12 @@ msgstr ""
msgid "%{token}..."
msgstr ""
+msgid "%{totalCpu} (%{freeSpacePercentage}%{percentSymbol} free)"
+msgstr ""
+
+msgid "%{totalMemory} (%{freeSpacePercentage}%{percentSymbol} free)"
+msgstr ""
+
msgid "%{totalWeight} total weight"
msgstr ""
@@ -575,6 +664,12 @@ msgstr ""
msgid "%{verb} %{time_spent_value} spent time."
msgstr ""
+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 ""
+
+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 ""
+
msgid "'%{level}' is not a valid visibility level"
msgstr ""
@@ -670,6 +765,9 @@ msgstr ""
msgid "0 for unlimited"
msgstr ""
+msgid "0 for unlimited, only effective with remote storage enabled."
+msgstr ""
+
msgid "1 %{type} addition"
msgid_plural "%{count} %{type} additions"
msgstr[0] ""
@@ -799,6 +897,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -814,6 +915,12 @@ msgstr ""
msgid "<code>\"johnsmith@example.com\": \"johnsmith@example.com\"</code> will add \"By <a href=\"#\">johnsmith@example.com</a>\" to all issues and comments originally created by johnsmith@example.com. By default, the email address or username is masked to ensure the user's privacy. Use this option if you want to show the full email address."
msgstr ""
+msgid "<code>Masked</code> to prevent the values from being displayed in job logs (must match certain regexp requirements)."
+msgstr ""
+
+msgid "<code>Protected</code> to expose them to protected branches or tags only."
+msgstr ""
+
msgid "<namespace / project>"
msgstr ""
@@ -841,6 +948,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -871,6 +981,12 @@ msgstr ""
msgid "A deleted user"
msgstr ""
+msgid "A file has been changed."
+msgstr ""
+
+msgid "A file was not found."
+msgstr ""
+
msgid "A file with '%{file_name}' already exists in %{branch} branch"
msgstr ""
@@ -934,10 +1050,10 @@ msgstr ""
msgid "A sign-in to your account has been made from the following IP address: %{ip}"
msgstr ""
-msgid "A sign-in to your account has been made from the following IP address: %{ip}."
+msgid "A subscription will 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 ""
-msgid "A subscription will 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."
+msgid "A suggestion is not applicable."
msgstr ""
msgid "A terraform report was generated in your pipelines."
@@ -949,9 +1065,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -997,9 +1110,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1135,6 +1245,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1194,6 +1307,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1299,6 +1415,9 @@ msgstr ""
msgid "Add strikethrough text"
msgstr ""
+msgid "Add suggestion to batch"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1395,10 +1514,10 @@ msgstr ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1739,24 +1858,45 @@ msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
+msgid "AlertManagement| assign yourself"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert assignee(s): %{assignees}"
+msgstr ""
+
msgid "AlertManagement|Alert detail"
msgstr ""
msgid "AlertManagement|Alert details"
msgstr ""
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
msgid "AlertManagement|Alerts"
msgstr ""
msgid "AlertManagement|All alerts"
msgstr ""
+msgid "AlertManagement|Assign To"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignee"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
@@ -1769,6 +1909,9 @@ msgstr ""
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 ""
+
msgid "AlertManagement|End time"
msgstr ""
@@ -1790,6 +1933,9 @@ msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No Matching Results"
+msgstr ""
+
msgid "AlertManagement|No alert data to display."
msgstr ""
@@ -1799,6 +1945,12 @@ msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|None -"
+msgstr ""
+
msgid "AlertManagement|Open"
msgstr ""
@@ -1835,6 +1987,12 @@ msgstr ""
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the assignee(s) list. Please try again."
+msgstr ""
+
+msgid "AlertManagement|There was an error while updating the assignee(s) of the alert. Please try again."
+msgstr ""
+
msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
msgstr ""
@@ -1844,13 +2002,19 @@ msgstr ""
msgid "AlertManagement|Triggered"
msgstr ""
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|View issue"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1979,6 +2143,9 @@ msgstr ""
msgid "Allow users to request access (if visibility is public or internal)"
msgstr ""
+msgid "Allowed Geo IP"
+msgstr ""
+
msgid "Allowed email domain restriction only permitted for top-level groups"
msgstr ""
@@ -2012,6 +2179,9 @@ msgstr ""
msgid "Amazon Web Services"
msgstr ""
+msgid "Amazon Web Services Logo"
+msgstr ""
+
msgid "Amazon authentication is not %{link_start}correctly configured%{link_end}. Ask your GitLab administrator if you want to use this service."
msgstr ""
@@ -2072,7 +2242,7 @@ msgstr ""
msgid "An error occurred while adding formatted title for epic"
msgstr ""
-msgid "An error occurred while checking group path"
+msgid "An error occurred while checking group path. Please refresh and try again."
msgstr ""
msgid "An error occurred while committing your changes."
@@ -2192,9 +2362,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2219,6 +2386,9 @@ msgstr ""
msgid "An error occurred while loading milestones"
msgstr ""
+msgid "An error occurred while loading project creation UI"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2357,6 +2527,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2366,6 +2539,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2471,9 +2647,15 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
+msgid "Apply suggestions"
+msgstr ""
+
msgid "Apply template"
msgstr ""
@@ -2492,12 +2674,18 @@ msgstr ""
msgid "Applying multiple commands"
msgstr ""
-msgid "Applying suggestion"
+msgid "Applying suggestion..."
+msgstr ""
+
+msgid "Applying suggestions..."
msgstr ""
msgid "Approval rules"
msgstr ""
+msgid "Approval rules reset to project defaults"
+msgstr ""
+
msgid "ApprovalRuleRemove|%d member"
msgid_plural "ApprovalRuleRemove|%d members"
msgstr[0] ""
@@ -2539,19 +2727,19 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
+msgid "Approve"
msgstr ""
-msgid "Approvals (you've approved)"
+msgid "Approve a merge request"
msgstr ""
-msgid "Approve"
+msgid "Approve the current merge request."
msgstr ""
-msgid "Approve a merge request"
+msgid "Approved"
msgstr ""
-msgid "Approve the current merge request."
+msgid "Approved MRs"
msgstr ""
msgid "Approved by: "
@@ -2671,6 +2859,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2764,6 +2955,9 @@ msgstr ""
msgid "Assign"
msgstr ""
+msgid "Assign Iteration"
+msgstr ""
+
msgid "Assign custom color like #FF0000"
msgstr ""
@@ -2782,6 +2976,9 @@ msgstr ""
msgid "Assign to"
msgstr ""
+msgid "Assign to commenting user"
+msgstr ""
+
msgid "Assign yourself to these issues"
msgstr ""
@@ -2817,6 +3014,9 @@ msgstr ""
msgid "Assignee(s)"
msgstr ""
+msgid "Assignees"
+msgstr ""
+
msgid "Assigns %{assignee_users_sentence}."
msgstr ""
@@ -2960,6 +3160,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2981,9 +3184,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -3221,6 +3421,12 @@ msgstr ""
msgid "Below you will find all the groups that are public."
msgstr ""
+msgid "Beta"
+msgstr ""
+
+msgid "Bi-weekly code coverage"
+msgstr ""
+
msgid "Billing"
msgstr ""
@@ -3542,6 +3748,9 @@ msgstr ""
msgid "Business metrics (Custom)"
msgstr ""
+msgid "Buy License"
+msgstr ""
+
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -3563,7 +3772,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3572,6 +3781,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3650,6 +3862,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't apply as this line has changed or the suggestion already matches its content."
+msgstr ""
+
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
msgid "Can't edit as source branch was deleted"
msgstr ""
@@ -3728,7 +3946,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3830,6 +4048,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -4304,9 +4525,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4319,6 +4537,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4331,6 +4552,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4358,9 +4582,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4559,7 +4780,7 @@ msgstr ""
msgid "ClusterIntegration|Cert-Manager"
msgstr ""
-msgid "ClusterIntegration|Cert-Manager is a native Kubernetes certificate management controller that helps with issuing certificates. Installing Cert-Manager on your cluster will issue a certificate by %{letsEncrypt} and ensure that certificates are valid and up-to-date."
+msgid "ClusterIntegration|Cert-Manager is a native Kubernetes certificate management controller that helps with issuing certificates. Installing Cert-Manager on your cluster will issue a certificate by %{linkStart}Let's Encrypt%{linkEnd} and ensure that certificates are valid and up-to-date."
msgstr ""
msgid "ClusterIntegration|Certificate Authority bundle (PEM format)"
@@ -4586,9 +4807,6 @@ msgstr ""
msgid "ClusterIntegration|Clear the local cache of namespace and service accounts. 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 ""
-msgid "ClusterIntegration|Cloud Run"
-msgstr ""
-
msgid "ClusterIntegration|Cluster being created"
msgstr ""
@@ -4673,7 +4891,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{linkStart}GitLab Integration%{linkEnd}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4757,9 +4975,6 @@ msgstr ""
msgid "ClusterIntegration|GitLab-managed cluster"
msgstr ""
-msgid "ClusterIntegration|Gitlab Integration"
-msgstr ""
-
msgid "ClusterIntegration|Global default"
msgstr ""
@@ -4805,7 +5020,7 @@ msgstr ""
msgid "ClusterIntegration|Ingress gives you a way to route requests to services based on the request host or path, centralizing a number of services into a single entrypoint."
msgstr ""
-msgid "ClusterIntegration|Installing Ingress may incur additional costs. Learn more about %{pricingLink}."
+msgid "ClusterIntegration|Installing Ingress may incur additional costs. Learn more about %{linkStart}pricing%{linkEnd}."
msgstr ""
msgid "ClusterIntegration|Instance cluster"
@@ -4820,7 +5035,7 @@ msgstr ""
msgid "ClusterIntegration|Issuer Email"
msgstr ""
-msgid "ClusterIntegration|Issuers represent a certificate authority. You must provide an email address for your Issuer. "
+msgid "ClusterIntegration|Issuers represent a certificate authority. You must provide an email address for your Issuer."
msgstr ""
msgid "ClusterIntegration|Jupyter Hostname"
@@ -4892,9 +5107,6 @@ msgstr ""
msgid "ClusterIntegration|Learn more about instance Kubernetes clusters"
msgstr ""
-msgid "ClusterIntegration|Let's Encrypt"
-msgstr ""
-
msgid "ClusterIntegration|Loading IAM Roles"
msgstr ""
@@ -4946,6 +5158,9 @@ msgstr ""
msgid "ClusterIntegration|No deployment cluster found for this job"
msgstr ""
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5003,7 +5218,7 @@ msgstr ""
msgid "ClusterIntegration|Prometheus"
msgstr ""
-msgid "ClusterIntegration|Prometheus is an open-source monitoring system with %{gitlabIntegrationLink} to monitor deployed applications."
+msgid "ClusterIntegration|Prometheus is an open-source monitoring system with %{linkStart}GitLab Integration%{linkEnd} to monitor deployed applications."
msgstr ""
msgid "ClusterIntegration|Provider details"
@@ -5159,10 +5374,10 @@ msgstr ""
msgid "ClusterIntegration|Select zone to choose machine type"
msgstr ""
-msgid "ClusterIntegration|Send Cilium Logs"
+msgid "ClusterIntegration|Send Container Network Policies Logs"
msgstr ""
-msgid "ClusterIntegration|Send ModSecurity Logs"
+msgid "ClusterIntegration|Send Web Application Firewall Logs"
msgstr ""
msgid "ClusterIntegration|Service Token"
@@ -5258,6 +5473,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5288,6 +5506,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5297,9 +5518,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5318,15 +5545,12 @@ msgstr ""
msgid "ClusterIntegration|documentation"
msgstr ""
-msgid "ClusterIntegration|installed via %{installed_via}"
+msgid "ClusterIntegration|installed via %{linkStart}Cloud Run%{linkEnd}"
msgstr ""
msgid "ClusterIntegration|meets the requirements"
msgstr ""
-msgid "ClusterIntegration|pricing"
-msgstr ""
-
msgid "ClusterIntegration|sign up"
msgstr ""
@@ -5357,9 +5581,21 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
+msgid "Code Coverage: %{coveragePercentage}%{percentSymbol}"
+msgstr ""
+
+msgid "Code Coverage| Empty code coverage data"
+msgstr ""
+
+msgid "Code Coverage|Couldn't fetch the code coverage data"
+msgstr ""
+
msgid "Code Owners"
msgstr ""
@@ -5417,6 +5653,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5429,6 +5668,9 @@ msgstr ""
msgid "Coming soon"
msgstr ""
+msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5465,6 +5707,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5629,7 +5874,7 @@ msgstr ""
msgid "ComplianceFramework|This project is regulated by %{framework}."
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5653,9 +5898,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5689,9 +5931,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5740,6 +5979,9 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
+msgid "Connection timeout"
+msgstr ""
+
msgid "Contact sales to upgrade"
msgstr ""
@@ -5770,6 +6012,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5782,6 +6034,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5806,15 +6061,21 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
@@ -5854,9 +6115,6 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
@@ -5877,9 +6135,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5931,12 +6186,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5958,7 +6207,7 @@ msgstr ""
msgid "ContainerRegistry|To widen your search, change or remove the filters above."
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5967,7 +6216,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -6006,10 +6255,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -6297,6 +6546,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project pre-populated with the necessary files to get you started quickly."
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -6342,6 +6594,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6399,6 +6654,9 @@ msgstr ""
msgid "Create your group"
msgstr ""
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6432,6 +6690,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6456,6 +6717,9 @@ msgstr ""
msgid "Creates branch '%{branch_name}' and a merge request to resolve this issue."
msgstr ""
+msgid "Creating"
+msgstr ""
+
msgid "Creating epic"
msgstr ""
@@ -6507,7 +6771,7 @@ msgstr ""
msgid "Current vulnerabilities count"
msgstr ""
-msgid "CurrentUser|Buy CI minutes"
+msgid "CurrentUser|Buy Pipeline minutes"
msgstr ""
msgid "CurrentUser|Profile"
@@ -6522,6 +6786,9 @@ msgstr ""
msgid "CurrentUser|Upgrade"
msgstr ""
+msgid "Custom Attributes"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6546,6 +6813,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6594,6 +6864,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6872,6 +7145,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6908,6 +7184,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -7299,6 +7578,9 @@ msgstr ""
msgid "Deploying to"
msgstr ""
+msgid "Deploying to AWS is easy with GitLab"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
@@ -7362,9 +7644,6 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
-msgstr ""
-
msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
@@ -7386,9 +7665,15 @@ msgstr ""
msgid "DesignManagement|Cancel comment update confirmation"
msgstr ""
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
msgid "DesignManagement|Comment"
msgstr ""
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7434,9 +7719,18 @@ msgstr ""
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
msgid "DesignManagement|Save comment"
msgstr ""
@@ -7449,6 +7743,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7769,6 +8069,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -8030,6 +8333,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -8066,6 +8372,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8150,6 +8459,9 @@ msgstr ""
msgid "Enforce DNS rebinding attack protection"
msgstr ""
+msgid "Enforce personal access token expiration"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -8222,9 +8534,6 @@ msgstr ""
msgid "Enter your password to approve"
msgstr ""
-msgid "Enter zen mode"
-msgstr ""
-
msgid "Environment"
msgstr ""
@@ -8234,12 +8543,18 @@ msgstr ""
msgid "Environment scope"
msgstr ""
+msgid "Environment variables are applied to all project environments in this instance via the Runner. You can use environment variables for passwords, secret keys, etc. Make variables available to the running application by prepending the variable key with <code>K8S_SECRET_</code>. You can set variables to be:"
+msgstr ""
+
msgid "Environment variables are applied to environments via the runner. They can be protected by only exposing them to protected branches or tags. Additionally, they can be masked so they are hidden in job logs, though they must match certain regexp requirements to do so. You can use environment variables for passwords, secret keys, or whatever you want."
msgstr ""
msgid "Environment variables are configured by your administrator to be %{link_start}protected%{link_end} by default"
msgstr ""
+msgid "Environment variables on this GitLab instance are configured to be %{link_start}protected%{link_end} by default"
+msgstr ""
+
msgid "Environment:"
msgstr ""
@@ -8279,7 +8594,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8579,6 +8894,9 @@ msgstr ""
msgid "Error creating new iteration"
msgstr ""
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
msgid "Error creating the snippet"
msgstr ""
@@ -8756,6 +9074,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Estimate"
+msgstr ""
+
msgid "Estimated"
msgstr ""
@@ -8855,6 +9176,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8909,6 +9233,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8924,6 +9251,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8933,6 +9263,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -9011,18 +9344,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -9041,6 +9362,9 @@ msgstr ""
msgid "Failed Jobs"
msgstr ""
+msgid "Failed on"
+msgstr ""
+
msgid "Failed to add a Zoom meeting"
msgstr ""
@@ -9107,7 +9431,7 @@ msgstr ""
msgid "Failed to load error details from Sentry."
msgstr ""
-msgid "Failed to load errors from Sentry. Error message: %{errorMessage}"
+msgid "Failed to load errors from Sentry."
msgstr ""
msgid "Failed to load group activity metrics. Please try again."
@@ -9149,6 +9473,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9185,6 +9512,9 @@ msgstr ""
msgid "Failed to set due date because the date format is invalid."
msgstr ""
+msgid "Failed to set iteration on this issue. Please try again."
+msgstr ""
+
msgid "Failed to signing using smartcard authentication"
msgstr ""
@@ -9224,7 +9554,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9407,13 +9737,10 @@ msgstr ""
msgid "FeatureFlags|Target environments"
msgstr ""
-msgid "FeatureFlags|There are no active feature flags"
-msgstr ""
-
-msgid "FeatureFlags|There are no inactive feature flags"
+msgid "FeatureFlags|There was an error fetching the feature flags."
msgstr ""
-msgid "FeatureFlags|There was an error fetching the feature flags."
+msgid "FeatureFlags|There was an error retrieving user lists"
msgstr ""
msgid "FeatureFlags|Try again in a few moments or contact your support team."
@@ -9425,9 +9752,18 @@ msgstr ""
msgid "FeatureFlag|Delete strategy"
msgstr ""
+msgid "FeatureFlag|List"
+msgstr ""
+
msgid "FeatureFlag|Percentage"
msgstr ""
+msgid "FeatureFlag|Select a user list"
+msgstr ""
+
+msgid "FeatureFlag|There are no configured user lists"
+msgstr ""
+
msgid "FeatureFlag|Type"
msgstr ""
@@ -9485,6 +9821,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9494,9 +9833,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9794,9 +10130,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9935,6 +10268,9 @@ msgstr ""
msgid "GeoNodes|Not checksummed"
msgstr ""
+msgid "GeoNodes|Package files"
+msgstr ""
+
msgid "GeoNodes|Pausing replication stops the sync process. Are you sure?"
msgstr ""
@@ -10022,6 +10358,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -10085,6 +10427,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -10151,6 +10499,9 @@ msgstr ""
msgid "Geo|Synchronization failed - %{error}"
msgstr ""
+msgid "Geo|Synchronization of %{itemTitle} is disabled."
+msgstr ""
+
msgid "Geo|The database is currently %{db_lag} behind the primary node."
msgstr ""
@@ -10169,6 +10520,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10421,9 +10778,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10457,10 +10811,10 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
+msgid "Go to %{link_to_google_takeout}."
msgstr ""
-msgid "Go to %{link_to_google_takeout}."
+msgid "Go to <strong>Issues</strong> > <strong>Boards</strong> to access your personalized learning issue board."
msgstr ""
msgid "Go to Pipelines"
@@ -10667,6 +11021,9 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10694,6 +11051,9 @@ msgstr ""
msgid "Group has not been marked for deletion"
msgstr ""
+msgid "Group import could not be scheduled"
+msgstr ""
+
msgid "Group info:"
msgstr ""
@@ -10703,6 +11063,9 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
@@ -10757,6 +11120,24 @@ msgstr ""
msgid "GroupActivyMetrics|Recent activity (last 90 days)"
msgstr ""
+msgid "GroupImport|Failed to import group."
+msgstr ""
+
+msgid "GroupImport|Group '%{group_name}' is being imported."
+msgstr ""
+
+msgid "GroupImport|Group could not be imported: %{errors}"
+msgstr ""
+
+msgid "GroupImport|Please wait while we import the group for you. Refresh at will."
+msgstr ""
+
+msgid "GroupImport|The group was successfully imported."
+msgstr ""
+
+msgid "GroupImport|Unable to process group import file"
+msgstr ""
+
msgid "GroupRoadmap|%{dateWord} – No end date"
msgstr ""
@@ -11003,6 +11384,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -11066,6 +11450,33 @@ msgstr ""
msgid "GroupsEmptyState|You can manage your group member’s permissions and access to each project in the group."
msgstr ""
+msgid "GroupsNew|Contact an administrator to enable options for importing your group."
+msgstr ""
+
+msgid "GroupsNew|Create"
+msgstr ""
+
+msgid "GroupsNew|Create group"
+msgstr ""
+
+msgid "GroupsNew|GitLab group export"
+msgstr ""
+
+msgid "GroupsNew|Import"
+msgstr ""
+
+msgid "GroupsNew|Import group"
+msgstr ""
+
+msgid "GroupsNew|My Awesome Group"
+msgstr ""
+
+msgid "GroupsNew|No import options available"
+msgstr ""
+
+msgid "GroupsNew|To copy a GitLab group between installations, navigate to the group settings page for the original installation, generate an export file, and upload it here."
+msgstr ""
+
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
@@ -11168,6 +11579,9 @@ msgstr ""
msgid "Helps reduce request volume for protected paths"
msgstr ""
+msgid "Here are all your projects in your group, including the one you just created. To start, let’s take a look at your personalized learning project which will help you learn about GitLab at your own pace."
+msgstr ""
+
msgid "Here you will find recent merge request activity"
msgstr ""
@@ -11229,6 +11643,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -11238,6 +11655,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11388,6 +11808,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11412,6 +11835,9 @@ msgstr ""
msgid "If you recently signed in and recognize the IP address, you may disregard this email."
msgstr ""
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11424,7 +11850,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11451,9 +11880,6 @@ msgstr ""
msgid "Import"
msgstr ""
-msgid "Import %{status}"
-msgstr ""
-
msgid "Import CSV"
msgstr ""
@@ -11463,6 +11889,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11472,6 +11901,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11487,9 +11919,6 @@ msgstr ""
msgid "Import issues"
msgstr ""
-msgid "Import issues from Jira"
-msgstr ""
-
msgid "Import members"
msgstr ""
@@ -11652,6 +12081,9 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
msgid "Indent"
msgstr ""
@@ -11679,12 +12111,18 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
msgid "Insert a code block"
msgstr ""
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
@@ -11750,9 +12188,6 @@ msgstr ""
msgid "Integrations"
msgstr ""
-msgid "Integrations allow you to integrate GitLab with other applications"
-msgstr ""
-
msgid "Integrations|All details"
msgstr ""
@@ -11891,6 +12326,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11954,6 +12392,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11966,6 +12407,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -12068,9 +12536,21 @@ msgstr ""
msgid "It seems like the Dependency Scanning job ran successfully, but no dependencies have been detected in your project."
msgstr ""
+msgid "It seems that there is currently no available data for code coverage"
+msgstr ""
+
msgid "It's you"
msgstr ""
+msgid "Iteration"
+msgstr ""
+
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
msgid "Iterations"
msgstr ""
@@ -12083,22 +12563,22 @@ msgstr ""
msgid "Iteration|cannot be more than 500 years in the future"
msgstr ""
-msgid "Jaeger URL"
+msgid "I’m familiar with the basics of project management and DevOps."
msgstr ""
-msgid "Jaeger tracing"
+msgid "I’m not very familiar with the basics of project management and DevOps."
msgstr ""
-msgid "Jan"
+msgid "Jaeger URL"
msgstr ""
-msgid "January"
+msgid "Jaeger tracing"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jan"
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "January"
msgstr ""
msgid "Jira import is already running."
@@ -12110,6 +12590,9 @@ msgstr ""
msgid "Jira project: %{importProject}"
msgstr ""
+msgid "Jira service not configured."
+msgstr ""
+
msgid "JiraService| on branch %{branch_link}"
msgstr ""
@@ -12239,6 +12722,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -12296,6 +12782,9 @@ msgstr ""
msgid "Keyboard shortcuts"
msgstr ""
+msgid "Ki"
+msgstr ""
+
msgid "Kubernetes"
msgstr ""
@@ -12559,6 +13048,9 @@ msgstr ""
msgid "Learn more about custom project templates"
msgstr ""
+msgid "Learn more about deploying to AWS"
+msgstr ""
+
msgid "Learn more about deploying to a cluster"
msgstr ""
@@ -12598,6 +13090,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12610,6 +13105,12 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
+msgid "License URL"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12634,15 +13135,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12863,6 +13358,9 @@ msgstr ""
msgid "List your Bitbucket Server repositories"
msgstr ""
+msgid "Lists"
+msgstr ""
+
msgid "Live preview"
msgstr ""
@@ -12893,6 +13391,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -13043,6 +13544,9 @@ msgstr ""
msgid "Manage project labels"
msgstr ""
+msgid "Manage storage usage"
+msgstr ""
+
msgid "Manage two-factor authentication"
msgstr ""
@@ -13091,9 +13595,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -13103,9 +13604,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -13211,6 +13709,9 @@ msgstr ""
msgid "Maximum field length"
msgstr ""
+msgid "Maximum import size (MB)"
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -13250,6 +13751,9 @@ msgstr ""
msgid "Maximum size of Elasticsearch bulk indexing requests."
msgstr ""
+msgid "Maximum size of import files."
+msgstr ""
+
msgid "Maximum size of individual attachments in comments."
msgstr ""
@@ -13343,6 +13847,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13391,6 +13898,12 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
msgstr ""
@@ -13457,7 +13970,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13475,6 +13988,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13496,9 +14012,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13526,10 +14039,16 @@ msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13553,12 +14072,39 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
msgstr ""
msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
msgstr ""
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|Choose whether to display dashboard metrics in UTC or the user's local timezone."
+msgstr ""
+
+msgid "MetricsSettings|Dashboard timezone"
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
+msgid "MetricsSettings|UTC (Coordinated Universal Time)"
+msgstr ""
+
+msgid "MetricsSettings|User's local timezone"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13574,6 +14120,9 @@ msgstr ""
msgid "Metrics|Create metric"
msgstr ""
+msgid "Metrics|Current"
+msgstr ""
+
msgid "Metrics|Delete metric"
msgstr ""
@@ -13618,9 +14167,15 @@ msgstr ""
msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
msgstr ""
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
+msgid "Metrics|Min"
+msgstr ""
+
msgid "Metrics|Must be a valid PromQL query."
msgstr ""
@@ -13717,12 +14272,18 @@ msgstr ""
msgid "Metrics|e.g. req/sec"
msgstr ""
+msgid "Mi"
+msgstr ""
+
msgid "Microsoft Azure"
msgstr ""
msgid "Middleman project with Static Site Editor support"
msgstr ""
+msgid "Migrate your data from an external source like GitHub, Bitbucket, or another instance of GitLab."
+msgstr ""
+
msgid "Migrated %{success_count}/%{total_count} files."
msgstr ""
@@ -13740,6 +14301,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13857,6 +14475,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13971,6 +14592,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13995,9 +14619,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -14007,9 +14628,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -14043,18 +14661,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
msgid "NetworkPolicies|Environment does not have deployment platform"
msgstr ""
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
msgstr ""
msgid "NetworkPolicies|Kubernetes error: %{error}"
msgstr ""
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
msgstr ""
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -14153,6 +14807,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration"
+msgstr ""
+
msgid "New iteration created"
msgstr ""
@@ -14327,6 +14984,15 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
+msgid "No iteration"
+msgstr ""
+
+msgid "No iterations to show"
+msgstr ""
+
msgid "No job log"
msgstr ""
@@ -14642,6 +15308,9 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
@@ -14714,6 +15383,51 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Attached branch"
+msgstr ""
+
+msgid "OnDemandScans|Attached branch is where the scan job runs."
+msgstr ""
+
+msgid "OnDemandScans|Could not run the scan. Please try again."
+msgstr ""
+
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|DAST will scan the target URL and any discovered sub URLs."
+msgstr ""
+
+msgid "OnDemandScans|New on-demand DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|On-demand scans run outside the DevOps cycle and find vulnerabilities in your projects. %{learnMoreLinkStart}Learn more%{learnMoreLinkEnd}"
+msgstr ""
+
+msgid "OnDemandScans|Only a passive scan can be performed on demand."
+msgstr ""
+
+msgid "OnDemandScans|Passive DAST Scan"
+msgstr ""
+
+msgid "OnDemandScans|Please enter a valid URL format, ex: http://www.example.com/home"
+msgstr ""
+
+msgid "OnDemandScans|Run this scan"
+msgstr ""
+
+msgid "OnDemandScans|Scan mode"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
+msgid "OnDemandScans|Target URL"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14740,6 +15454,9 @@ msgstr ""
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 ""
+
msgid "One or more of your Bitbucket projects cannot be imported into GitLab directly because they use Subversion or Mercurial for version control, rather than Git."
msgstr ""
@@ -14788,7 +15505,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14833,7 +15550,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14950,6 +15667,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -15130,6 +15850,9 @@ msgstr ""
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
@@ -15142,10 +15865,10 @@ msgstr ""
msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -15247,6 +15970,9 @@ msgstr ""
msgid "Passed"
msgstr ""
+msgid "Passed on"
+msgstr ""
+
msgid "Password"
msgstr ""
@@ -15289,6 +16015,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -15331,9 +16060,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -15355,9 +16090,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -15553,6 +16285,9 @@ msgstr ""
msgid "Pipeline|Branch name"
msgstr ""
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
@@ -15562,6 +16297,9 @@ msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15574,9 +16312,15 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
@@ -15586,6 +16330,12 @@ msgstr ""
msgid "Pipeline|No pipeline has been run for this commit."
msgstr ""
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
@@ -15601,9 +16351,15 @@ msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15619,6 +16375,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Tag name"
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -15658,6 +16417,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15700,6 +16465,9 @@ msgstr ""
msgid "Please complete your profile with email address"
msgstr ""
+msgid "Please convert %{linkStart}them to Git%{linkEnd}, and go through the %{linkToImportFlow} again."
+msgstr ""
+
msgid "Please convert them to %{link_to_git}, and go through the %{link_to_import_flow} again."
msgstr ""
@@ -15751,9 +16519,15 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
+msgid "Please provide attributes to update"
+msgstr ""
+
msgid "Please refer to <a href=\"%{docs_url}\">%{docs_url}</a>"
msgstr ""
@@ -16492,6 +17266,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16654,6 +17431,9 @@ msgstr ""
msgid "ProjectSettings|Enable 'Delete source branch' option by default"
msgstr ""
+msgid "ProjectSettings|Enable merge trains and pipelines for merged results"
+msgstr ""
+
msgid "ProjectSettings|Every merge creates a merge commit"
msgstr ""
@@ -16720,9 +17500,6 @@ msgstr ""
msgid "ProjectSettings|Merge options"
msgstr ""
-msgid "ProjectSettings|Merge pipelines will try to validate the post-merge result prior to merging"
-msgstr ""
-
msgid "ProjectSettings|Merge requests"
msgstr ""
@@ -16750,6 +17527,9 @@ msgstr ""
msgid "ProjectSettings|Pipelines"
msgstr ""
+msgid "ProjectSettings|Pipelines for merge requests must be enabled in the CI/CD configuration file, or pipelines could be unresolvable or dropped"
+msgstr ""
+
msgid "ProjectSettings|Pipelines must succeed"
msgstr ""
@@ -16777,6 +17557,9 @@ msgstr ""
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
+msgid "ProjectSettings|Skipped pipelines are considered successful"
+msgstr ""
+
msgid "ProjectSettings|Snippets"
msgstr ""
@@ -16792,6 +17575,9 @@ msgstr ""
msgid "ProjectSettings|These checks must pass before merge requests can be merged"
msgstr ""
+msgid "ProjectSettings|This introduces the risk of merging changes that will not pass the pipeline."
+msgstr ""
+
msgid "ProjectSettings|This setting is applied on the server level and can be overridden by an admin."
msgstr ""
@@ -16969,12 +17755,27 @@ msgstr ""
msgid "ProjectsNew|Blank project"
msgstr ""
+msgid "ProjectsNew|Connect your external repository to GitLab CI/CD."
+msgstr ""
+
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
+msgid "ProjectsNew|Create a blank project to house your files, plan your work, and collaborate on code, among other things."
+msgstr ""
+
+msgid "ProjectsNew|Create blank project"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
+msgid "ProjectsNew|Create new project"
+msgstr ""
+
msgid "ProjectsNew|Creating project & repository."
msgstr ""
@@ -16999,6 +17800,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Run CI/CD for external repository"
+msgstr ""
+
msgid "ProjectsNew|Template"
msgstr ""
@@ -17065,12 +17869,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -17200,6 +18010,9 @@ msgstr ""
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
@@ -17212,6 +18025,9 @@ msgstr ""
msgid "Promotions|Track activity with Contribution Analytics."
msgstr ""
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
@@ -17371,9 +18187,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -17383,6 +18196,15 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Published on status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -17485,6 +18307,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -17494,9 +18319,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -17533,9 +18355,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17557,6 +18376,9 @@ msgstr ""
msgid "Recipe"
msgstr ""
+msgid "Reconfigure"
+msgstr ""
+
msgid "Recover hidden stage"
msgstr ""
@@ -17690,6 +18512,27 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Images"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Packages"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbooks"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17711,6 +18554,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17771,6 +18617,9 @@ msgstr ""
msgid "Remove fork relationship"
msgstr ""
+msgid "Remove from batch"
+msgstr ""
+
msgid "Remove from board"
msgstr ""
@@ -17780,6 +18629,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17822,6 +18677,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17861,6 +18719,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17966,9 +18827,6 @@ msgstr ""
msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
msgstr ""
-msgid "Report Type: %{report_type}"
-msgstr ""
-
msgid "Report abuse"
msgstr ""
@@ -18130,10 +18988,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -18148,6 +19009,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -18169,10 +19036,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -18215,6 +19079,9 @@ msgstr ""
msgid "Reset template"
msgstr ""
+msgid "Reset to project defaults"
+msgstr ""
+
msgid "Resetting the authorization key for this project will require updating the authorization key in every alert source it is enabled in."
msgstr ""
@@ -18242,6 +19109,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -18472,9 +19342,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -18511,9 +19378,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18709,6 +19573,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18739,10 +19606,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18837,6 +19704,9 @@ msgstr ""
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18849,9 +19719,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18864,21 +19731,21 @@ msgstr ""
msgid "SecurityConfiguration|Enabled"
msgstr ""
-msgid "SecurityConfiguration|Feature"
-msgstr ""
-
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18936,6 +19803,9 @@ msgstr ""
msgid "SecurityReports|False positive"
msgstr ""
+msgid "SecurityReports|Group Security Dashboard"
+msgstr ""
+
msgid "SecurityReports|Hide dismissed"
msgstr ""
@@ -19014,6 +19884,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -19143,6 +20016,9 @@ msgstr ""
msgid "Select a timezone"
msgstr ""
+msgid "Select a weight for the storage new repositories will be placed on."
+msgstr ""
+
msgid "Select all"
msgstr ""
@@ -19158,6 +20034,9 @@ msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -19203,6 +20082,9 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
msgid "Select status"
msgstr ""
@@ -19218,9 +20100,6 @@ msgstr ""
msgid "Select the branch you want to set as the default for this project. All merge requests and commits will automatically be made against this branch unless you specify a different one."
msgstr ""
-msgid "Select the configured storage available for new repositories to be placed on."
-msgstr ""
-
msgid "Select the custom project template source group."
msgstr ""
@@ -19455,6 +20334,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -19491,6 +20373,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -19500,6 +20385,9 @@ 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."
+msgstr ""
+
msgid "Set time estimate"
msgstr ""
@@ -19575,6 +20463,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -19593,7 +20484,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19665,12 +20556,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19691,6 +20591,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19916,9 +20824,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19961,6 +20875,9 @@ msgstr ""
msgid "Something went wrong while adding your award. Please try again."
msgstr ""
+msgid "Something went wrong while applying the batch of suggestions. Please try again."
+msgstr ""
+
msgid "Something went wrong while applying the suggestion. Please try again."
msgstr ""
@@ -20063,10 +20980,13 @@ msgstr ""
msgid "Something went wrong while updating a requirement."
msgstr ""
+msgid "Something went wrong while updating assignees"
+msgstr ""
+
msgid "Something went wrong while updating your list settings"
msgstr ""
-msgid "Something went wrong with your automatic subscription renewal"
+msgid "Something went wrong with your automatic subscription renewal."
msgstr ""
msgid "Something went wrong, unable to add %{project} to dashboard"
@@ -20108,6 +21028,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -20225,6 +21151,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -20258,6 +21187,9 @@ msgstr ""
msgid "Source code"
msgstr ""
+msgid "Source code (%{fileExtension})"
+msgstr ""
+
msgid "Source is not available"
msgstr ""
@@ -20390,6 +21322,9 @@ msgstr ""
msgid "Stars"
msgstr ""
+msgid "Start Date"
+msgstr ""
+
msgid "Start Web Terminal"
msgstr ""
@@ -20462,6 +21397,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -20471,9 +21409,6 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
-msgid "State"
-msgstr ""
-
msgid "State your message to activate"
msgstr ""
@@ -20591,6 +21526,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -20618,6 +21556,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20900,6 +21841,21 @@ msgstr ""
msgid "SuggestedColors|Very pale orange"
msgstr ""
+msgid "Suggestion is not applicable as the suggestion was not found."
+msgstr ""
+
+msgid "Suggestions are not applicable as one or more suggestions were not found."
+msgstr ""
+
+msgid "Suggestions are not applicable as their lines cannot overlap."
+msgstr ""
+
+msgid "Suggestions must all be on the same branch."
+msgstr ""
+
+msgid "Suggestions that change line count can't be added to batches, yet."
+msgstr ""
+
msgid "Suggestions:"
msgstr ""
@@ -20942,18 +21898,12 @@ msgstr ""
msgid "Synchronization disabled"
msgstr ""
-msgid "Synchronization of container repositories is disabled."
-msgstr ""
-
msgid "System"
msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -21154,7 +22104,7 @@ msgstr ""
msgid "TestHooks|Ensure the project has CI pipelines."
msgstr ""
-msgid "TestHooks|Ensure the project has at least one commit."
+msgid "TestHooks|Ensure the project has deployments."
msgstr ""
msgid "TestHooks|Ensure the project has issues."
@@ -21602,7 +22552,7 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
-msgid "There are no %{replicableType} to show"
+msgid "There are no %{replicableTypeName} to show"
msgstr ""
msgid "There are no GPG keys associated with this account."
@@ -21683,9 +22633,15 @@ msgstr ""
msgid "There was a problem fetching project branches."
msgstr ""
+msgid "There was a problem fetching project tags."
+msgstr ""
+
msgid "There was a problem fetching project users."
msgstr ""
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21758,6 +22714,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21866,6 +22825,9 @@ msgstr ""
msgid "This action can lead to data loss. To prevent accidental actions we ask you to confirm your intention."
msgstr ""
+msgid "This also resolves all related threads"
+msgstr ""
+
msgid "This also resolves the discussion"
msgstr ""
@@ -21956,6 +22918,9 @@ msgstr ""
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
+msgid "This feature is currently in beta. We invite you to %{linkStart}give feedback%{linkEnd}."
+msgstr ""
+
msgid "This feature requires local storage to be enabled"
msgstr ""
@@ -21989,6 +22954,9 @@ msgstr ""
msgid "This is a Work in Progress"
msgstr ""
+msgid "This is a confidential epic."
+msgstr ""
+
msgid "This is a confidential issue."
msgstr ""
@@ -22109,7 +23077,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -22130,6 +23098,9 @@ msgstr ""
msgid "This license has already expired."
msgstr ""
+msgid "This link points to external content"
+msgstr ""
+
msgid "This may expose confidential information as the selected fork is in another namespace that can have other members."
msgstr ""
@@ -22175,6 +23146,9 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
@@ -22196,6 +23170,9 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
@@ -22292,9 +23269,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -22373,6 +23356,9 @@ msgstr ""
msgid "Time from last commit to merge"
msgstr ""
+msgid "Time in seconds"
+msgstr ""
+
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 ""
@@ -22794,9 +23780,15 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
+msgid "Total cores (CPUs)"
+msgstr ""
+
msgid "Total issues"
msgstr ""
+msgid "Total memory (GB)"
+msgstr ""
+
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22830,6 +23822,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -23001,10 +23996,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -23013,6 +24008,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -23052,6 +24050,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -23064,6 +24065,9 @@ msgstr ""
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -23073,6 +24077,9 @@ msgstr ""
msgid "Unable to sign you in to the group with SAML due to \"%{reason}\""
msgstr ""
+msgid "Unable to suggest a path. Please refresh and try again."
+msgstr ""
+
msgid "Unable to update label prioritization at this time"
msgstr ""
@@ -23088,6 +24095,9 @@ msgstr ""
msgid "Unarchiving the project will restore people's ability to make changes to it. The repository can be committed to, and issues, comments, and other entities can be created. %{strong_start}Once active, this project shows up in the search and on the dashboard.%{strong_end}"
msgstr ""
+msgid "Unassign from commenting user"
+msgstr ""
+
msgid "Unblock"
msgstr ""
@@ -23133,9 +24143,6 @@ msgstr ""
msgid "Unknown response text"
msgstr ""
-msgid "Unknown sign-in from new location"
-msgstr ""
-
msgid "Unlimited"
msgstr ""
@@ -23307,7 +24314,7 @@ msgstr ""
msgid "Updated at"
msgstr ""
-msgid "Updated to"
+msgid "Updated to %{linkStart}chart v%{linkEnd}"
msgstr ""
msgid "Updating"
@@ -23340,6 +24347,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -23358,6 +24368,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -23382,9 +24395,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -23394,12 +24404,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -23409,12 +24425,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -23433,12 +24455,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -23505,6 +24533,9 @@ msgstr ""
msgid "User IDs"
msgstr ""
+msgid "User Lists can only be created and modified with %{linkStart}the API%{linkEnd}"
+msgstr ""
+
msgid "User OAuth applications"
msgstr ""
@@ -23538,9 +24569,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23853,6 +24881,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23974,6 +25005,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -24037,6 +25071,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -24271,6 +25308,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -24292,7 +25332,7 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
msgstr ""
msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
@@ -24316,6 +25356,9 @@ msgstr ""
msgid "We've found no vulnerabilities"
msgstr ""
+msgid "Web Application Firewall"
+msgstr ""
+
msgid "Web IDE"
msgstr ""
@@ -24340,9 +25383,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -24382,12 +25422,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -24423,9 +25472,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -24471,12 +25517,18 @@ msgstr ""
msgid "WikiEmptyIssueMessage|Suggest wiki improvement"
msgstr ""
+msgid "WikiEmptyIssueMessage|You must be a group member in order to add wiki pages. If you have suggestions for how to improve the wiki for this group, consider opening an issue in the %{issues_link}."
+msgstr ""
+
msgid "WikiEmptyIssueMessage|You must be a project member in order to add wiki pages. If you have suggestions for how to improve the wiki for this project, consider opening an issue in the %{issues_link}."
msgstr ""
msgid "WikiEmptyIssueMessage|issue tracker"
msgstr ""
+msgid "WikiEmpty|A wiki is where you can store all the details about your group. This can include why you've created it, its principles, how to use it, and so on."
+msgstr ""
+
msgid "WikiEmpty|A wiki is where you can store all the details about your project. This can include why you've created it, its principles, how to use it, and so on."
msgstr ""
@@ -24486,12 +25538,21 @@ msgstr ""
msgid "WikiEmpty|Suggest wiki improvement"
msgstr ""
+msgid "WikiEmpty|The wiki lets you write documentation for your group"
+msgstr ""
+
msgid "WikiEmpty|The wiki lets you write documentation for your project"
msgstr ""
+msgid "WikiEmpty|This group has no wiki pages"
+msgstr ""
+
msgid "WikiEmpty|This project has no wiki pages"
msgstr ""
+msgid "WikiEmpty|You must be a group member in order to add wiki pages."
+msgstr ""
+
msgid "WikiEmpty|You must be a project member in order to add wiki pages."
msgstr ""
@@ -24585,6 +25646,9 @@ msgstr ""
msgid "Will deploy to"
msgstr ""
+msgid "With requirements, you can set criteria to check your products against."
+msgstr ""
+
msgid "Withdraw Access Request"
msgstr ""
@@ -24597,9 +25661,6 @@ msgstr ""
msgid "Work in progress Limit"
msgstr ""
-msgid "Workflow Help"
-msgstr ""
-
msgid "Write"
msgstr ""
@@ -24894,7 +25955,7 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
-msgid "You have a license(s) that activates at a future date. Please see the License History table below."
+msgid "You have a license that activates at a future date. Please see the License History table below."
msgstr ""
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
@@ -24912,7 +25973,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24996,7 +26057,7 @@ msgstr ""
msgid "You need to upload a Google Takeout archive."
msgstr ""
-msgid "You reached %{usage_in_percent} of %{namespace_name}'s capacity (%{used_storage} of %{storage_limit})"
+msgid "You reached %{usage_in_percent} of %{namespace_name}'s storage capacity (%{used_storage} of %{storage_limit})"
msgstr ""
msgid "You tried to fork %{link_to_the_project} but it failed for the following reason:"
@@ -25095,6 +26156,9 @@ msgstr ""
msgid "YouTube"
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}."
msgstr ""
@@ -25131,6 +26195,9 @@ msgstr ""
msgid "Your Groups"
msgstr ""
+msgid "Your License"
+msgstr ""
+
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
msgstr ""
@@ -25221,9 +26288,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -25233,6 +26309,9 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
@@ -25281,13 +26360,13 @@ msgstr ""
msgid "Your subscription expired!"
msgstr ""
-msgid "Your subscription has been downgraded"
+msgid "Your subscription has been downgraded."
msgstr ""
-msgid "Your subscription will automatically renew in %{remaining_days}"
+msgid "Your subscription will automatically renew in %{remaining_days}."
msgstr ""
-msgid "Your subscription will expire in %{remaining_days}"
+msgid "Your subscription will expire in %{remaining_days}."
msgstr ""
msgid "Zoom meeting added"
@@ -25322,6 +26401,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -25364,6 +26446,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -25575,6 +26660,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -25628,6 +26716,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -25652,9 +26743,15 @@ msgstr ""
msgid "created %{timeAgo}"
msgstr ""
+msgid "created %{timeago}"
+msgstr ""
+
msgid "customize"
msgstr ""
+msgid "data"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -25704,7 +26801,7 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
msgstr ""
msgid "email '%{email}' is not a verified email."
@@ -25740,10 +26837,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25808,6 +26905,9 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
@@ -25879,6 +26979,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -26365,11 +27468,6 @@ msgstr ""
msgid "personal access tokens"
msgstr ""
-msgid "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] ""
-
msgid "pipeline"
msgstr ""
@@ -26454,6 +27552,12 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
+msgid "satisfied"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -26520,10 +27624,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -26586,6 +27690,9 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
msgid "uploads"
msgstr ""
@@ -26598,6 +27705,9 @@ msgstr ""
msgid "uses Kubernetes clusters to deploy your code!"
msgstr ""
+msgid "v%{version} published %{timeAgo}"
+msgstr ""
+
msgid "verify ownership"
msgstr ""
diff --git a/locale/gl_ES/gitlab.po b/locale/gl_ES/gitlab.po
index 14066fd10dc..842686f7eb1 100644
--- a/locale/gl_ES/gitlab.po
+++ b/locale/gl_ES/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: gl\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:34\n"
+"PO-Revision-Date: 2020-06-08 15:09\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] "%d commit"
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,13 +8991,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8627,7 +9009,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] ""
msgstr[1] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/he_IL/gitlab.po b/locale/he_IL/gitlab.po
index b25581c3683..e9d1d2e23c0 100644
--- a/locale/he_IL/gitlab.po
+++ b/locale/he_IL/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: he\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:11\n"
+"PO-Revision-Date: 2020-06-08 15:16\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -80,6 +80,20 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -108,6 +122,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -139,6 +160,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -237,6 +265,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+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[3] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -279,6 +314,20 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -305,6 +354,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -390,6 +442,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -399,6 +454,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -411,6 +469,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -444,12 +526,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -465,6 +556,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -509,6 +606,12 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -668,6 +771,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -908,6 +1014,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -938,6 +1047,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -947,6 +1059,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -983,7 +1098,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -1034,6 +1152,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -1046,9 +1167,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -1094,9 +1212,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1187,12 +1302,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1229,7 +1338,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1238,6 +1347,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1284,7 +1396,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1299,6 +1411,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1308,9 +1423,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1326,7 +1447,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr "הוספת מפתח SSH"
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1392,6 +1516,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1482,16 +1609,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1818,6 +1945,15 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
@@ -1825,58 +1961,103 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
+msgstr ""
+
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1885,16 +2066,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -2068,6 +2267,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2233,9 +2435,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2257,6 +2456,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2332,6 +2534,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2368,9 +2573,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2386,6 +2597,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2395,6 +2609,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2419,12 +2636,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2434,9 +2645,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2500,6 +2717,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2576,12 +2796,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2591,12 +2805,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2705,6 +2925,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2717,7 +2940,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2831,6 +3054,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2911,15 +3137,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2977,6 +3221,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2998,9 +3245,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -3019,6 +3263,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -3049,6 +3296,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -3064,6 +3314,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3541,16 +3794,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3574,7 +3827,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3583,6 +3836,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3601,6 +3857,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3631,9 +3890,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3661,6 +3917,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3736,7 +3998,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3751,6 +4013,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3787,6 +4052,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3829,6 +4100,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3847,6 +4121,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3952,15 +4229,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4309,9 +4577,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4324,6 +4589,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4336,6 +4604,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4363,9 +4634,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4405,6 +4673,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4600,6 +4871,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4621,9 +4895,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4675,7 +4946,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4702,6 +4973,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4780,10 +5054,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4942,6 +5216,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5176,9 +5456,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5257,6 +5534,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5287,6 +5567,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5296,9 +5579,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5356,6 +5645,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5374,6 +5666,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5413,6 +5708,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5422,6 +5720,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5458,6 +5759,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5621,7 +5925,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5645,9 +5952,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5681,9 +5985,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5732,16 +6033,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5768,6 +6063,20 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5780,6 +6089,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5804,27 +6116,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5846,10 +6170,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5871,9 +6192,6 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5895,6 +6213,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5922,12 +6243,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5946,7 +6261,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5955,7 +6273,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5994,10 +6312,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -6084,6 +6402,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -6129,9 +6450,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6147,9 +6465,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6246,7 +6561,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6264,9 +6579,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6285,9 +6597,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6297,9 +6606,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6342,6 +6648,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6354,6 +6663,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6393,6 +6705,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6426,6 +6744,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6477,9 +6798,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6516,6 +6834,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6540,6 +6861,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6588,6 +6912,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6612,6 +6939,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6865,6 +7195,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6901,6 +7234,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6943,6 +7279,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -7034,13 +7376,6 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -7078,12 +7413,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -7093,9 +7422,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7216,12 +7542,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7243,13 +7575,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7369,10 +7701,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7381,9 +7713,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7393,6 +7740,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7420,12 +7770,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7435,6 +7800,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7447,6 +7818,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7676,6 +8050,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7724,6 +8101,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7748,6 +8128,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7895,6 +8278,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7910,6 +8296,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -8003,6 +8392,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -8012,9 +8404,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -8042,6 +8431,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8165,6 +8557,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8189,10 +8584,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8249,7 +8644,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8462,10 +8857,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8477,12 +8872,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8552,7 +8941,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8657,9 +9055,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8675,6 +9070,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8726,10 +9124,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8771,13 +9169,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8789,7 +9187,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8828,6 +9226,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8846,6 +9247,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8879,6 +9283,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8894,6 +9301,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8903,6 +9313,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8981,18 +9394,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -9119,6 +9520,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9194,7 +9598,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9257,6 +9661,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9269,6 +9679,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9278,15 +9691,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9305,6 +9727,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9320,9 +9745,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9413,6 +9844,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9425,6 +9859,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9434,9 +9871,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9452,24 +9886,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9479,6 +9934,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9710,9 +10168,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9752,15 +10207,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9938,6 +10393,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9947,10 +10408,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -10001,6 +10462,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -10052,6 +10519,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -10070,6 +10540,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -10079,6 +10552,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10331,9 +10810,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10367,9 +10843,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10532,12 +11005,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10571,6 +11053,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10583,10 +11071,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10604,10 +11095,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10625,12 +11119,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10697,9 +11197,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10901,6 +11398,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -11006,6 +11506,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -11015,6 +11518,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -11125,6 +11631,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -11134,6 +11643,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11284,6 +11796,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11293,7 +11808,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11302,6 +11820,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11314,7 +11838,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11332,13 +11859,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11350,6 +11877,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11359,6 +11889,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11368,10 +11901,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11464,10 +11997,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11500,6 +12033,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11533,6 +12069,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11557,18 +12099,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11621,6 +12181,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11660,6 +12244,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11696,18 +12286,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11720,6 +12319,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11783,6 +12385,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11795,6 +12400,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11852,6 +12484,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11897,6 +12532,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11909,19 +12568,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -12047,6 +12709,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -12086,6 +12751,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12267,6 +12935,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12351,6 +13022,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12372,9 +13046,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12402,6 +13073,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12414,6 +13088,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12438,15 +13115,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12589,6 +13260,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12604,6 +13278,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12701,6 +13378,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12815,10 +13495,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12845,6 +13525,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12896,9 +13579,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12908,9 +13588,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -13088,6 +13765,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -13097,9 +13777,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -13112,6 +13789,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -13145,6 +13825,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13193,9 +13876,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13256,7 +13948,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13274,6 +13966,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13295,9 +13990,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13319,19 +14011,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13355,6 +14050,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13413,6 +14129,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13431,6 +14153,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13467,6 +14192,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13531,6 +14259,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13540,6 +14325,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13549,21 +14340,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13624,6 +14433,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13738,6 +14550,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13747,6 +14562,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13759,9 +14577,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13771,9 +14586,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13807,6 +14619,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13838,6 +14698,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13904,6 +14767,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13961,6 +14827,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13979,18 +14848,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -14081,12 +14941,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -14111,6 +14977,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14246,6 +15115,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14270,6 +15142,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14384,9 +15259,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14453,6 +15334,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14462,9 +15352,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14532,7 +15419,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14577,7 +15464,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14592,6 +15479,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14622,7 +15512,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14670,6 +15560,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14688,6 +15581,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14709,6 +15605,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14796,6 +15698,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14814,6 +15719,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14844,22 +15752,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14892,6 +15815,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14979,6 +15905,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14997,6 +15926,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -15039,9 +15971,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -15063,9 +16001,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -15087,9 +16022,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15198,6 +16130,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15258,15 +16193,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15279,30 +16223,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15318,6 +16286,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15354,6 +16325,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15447,6 +16424,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15522,6 +16502,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15612,6 +16595,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15648,6 +16634,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15867,9 +16856,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15915,9 +16901,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -16062,12 +17045,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -16098,6 +17075,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -16119,6 +17099,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -16149,6 +17132,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -16173,7 +17159,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -16182,6 +17168,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16296,9 +17285,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16464,6 +17450,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16509,6 +17498,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16659,6 +17651,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16752,12 +17747,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16833,9 +17834,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16854,30 +17852,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -17013,9 +18065,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -17025,6 +18074,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -17127,6 +18182,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -17136,9 +18194,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -17175,9 +18230,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17275,6 +18327,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17321,6 +18388,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17342,6 +18421,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17411,6 +18493,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17453,6 +18541,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17492,6 +18583,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17543,6 +18637,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17573,6 +18670,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17588,7 +18688,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17694,6 +18797,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17730,6 +18836,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17745,10 +18854,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17763,6 +18875,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17784,10 +18902,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17861,6 +18976,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17873,6 +18991,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -18021,6 +19145,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -18084,9 +19211,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -18123,9 +19247,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18255,9 +19376,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18315,6 +19442,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18345,10 +19475,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18457,9 +19587,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18472,9 +19608,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18484,24 +19617,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18637,6 +19770,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18718,6 +19854,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18769,12 +19908,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18820,9 +19965,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18895,6 +20049,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -19060,6 +20220,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -19096,6 +20259,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -19180,6 +20346,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -19198,7 +20367,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19237,15 +20406,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19270,12 +20439,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19298,6 +20476,16 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19484,6 +20672,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19520,9 +20711,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19619,6 +20816,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19658,6 +20858,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19706,6 +20909,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19823,6 +21032,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19988,7 +21200,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -20063,6 +21275,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -20189,6 +21404,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -20216,6 +21434,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20243,6 +21464,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20423,9 +21647,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20510,6 +21740,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20537,9 +21770,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20793,6 +22023,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20878,9 +22111,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20917,9 +22147,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20960,6 +22196,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -21134,6 +22373,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -21182,6 +22424,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21257,6 +22502,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21329,6 +22583,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21392,6 +22649,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21476,6 +22736,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21515,6 +22778,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21674,7 +22937,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21701,6 +22964,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21737,12 +23003,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21755,12 +23027,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21779,7 +23063,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21788,9 +23072,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21845,9 +23126,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -22094,6 +23381,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -22162,6 +23452,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22282,6 +23578,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22339,15 +23638,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22363,9 +23656,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22384,6 +23674,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22495,6 +23788,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22552,10 +23848,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22564,6 +23860,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22603,6 +23902,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22612,9 +23914,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22864,18 +24172,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22894,6 +24196,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22912,6 +24217,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22936,9 +24244,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22948,12 +24253,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22963,12 +24274,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22987,12 +24304,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -23017,7 +24340,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -23092,9 +24415,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23341,6 +24661,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23401,6 +24727,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23428,7 +24757,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23470,6 +24802,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23520,6 +24855,9 @@ msgstr[3] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23583,6 +24921,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23664,9 +25005,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23697,9 +25035,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23808,6 +25143,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23820,6 +25158,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23841,7 +25182,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23883,9 +25230,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23925,12 +25269,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23968,9 +25321,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -24004,9 +25354,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -24127,10 +25474,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -24139,10 +25489,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24259,6 +25609,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24286,6 +25639,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24301,6 +25657,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24379,6 +25738,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24427,6 +25789,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24442,7 +25807,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24535,6 +25900,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24562,6 +25930,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24580,6 +25951,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24613,7 +25990,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24649,7 +26029,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24742,9 +26122,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24754,12 +26143,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24784,9 +26179,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24836,6 +26237,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24878,6 +26282,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -25057,6 +26464,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -25075,6 +26485,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -25093,6 +26506,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -25136,6 +26552,9 @@ msgstr[3] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -25145,6 +26564,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -25154,6 +26576,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25206,6 +26631,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -25219,7 +26647,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -25252,10 +26683,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25322,9 +26753,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25389,6 +26829,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25410,6 +26853,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25449,6 +26898,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25579,7 +27031,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25759,9 +27211,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25771,15 +27220,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25792,6 +27232,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25837,6 +27280,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25872,9 +27318,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25901,6 +27356,12 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25953,6 +27414,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -26019,10 +27483,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -26085,6 +27549,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -26112,6 +27582,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -26139,6 +27612,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/hi_IN/gitlab.po b/locale/hi_IN/gitlab.po
index 220339b757d..41fcd919403 100644
--- a/locale/hi_IN/gitlab.po
+++ b/locale/hi_IN/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: hi\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:32\n"
+"PO-Revision-Date: 2020-06-08 15:11\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,13 +8991,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8627,7 +9009,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] ""
msgstr[1] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/hr_HR/gitlab.po b/locale/hr_HR/gitlab.po
index 31ef7dcfe58..f209887ac99 100644
--- a/locale/hr_HR/gitlab.po
+++ b/locale/hr_HR/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: hr\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:32\n"
+"PO-Revision-Date: 2020-06-08 15:10\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -77,6 +77,18 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -101,6 +113,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -128,6 +146,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -212,6 +236,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+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] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -248,6 +278,18 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -272,6 +314,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -353,6 +398,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -362,6 +410,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -374,6 +425,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -407,12 +482,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -428,6 +512,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -470,6 +560,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -623,6 +719,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -845,6 +944,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -875,6 +977,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -884,6 +989,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -920,7 +1028,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -971,6 +1082,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -983,9 +1097,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -1031,9 +1142,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1124,12 +1232,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1166,7 +1268,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1175,6 +1277,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1220,7 +1325,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1235,6 +1340,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1244,9 +1352,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1262,7 +1376,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1328,6 +1445,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1418,16 +1538,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1754,64 +1874,118 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1820,16 +1994,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|Unknown"
+msgstr ""
+
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -2003,6 +2195,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2168,9 +2363,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2192,6 +2384,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2267,6 +2462,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2303,9 +2501,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2321,6 +2525,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2330,6 +2537,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2354,12 +2564,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2369,9 +2573,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2435,6 +2645,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2507,12 +2720,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2522,12 +2729,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2636,6 +2849,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2648,7 +2864,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2762,6 +2978,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2840,15 +3059,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2906,6 +3143,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2927,9 +3167,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2948,6 +3185,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2978,6 +3218,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2993,6 +3236,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3470,16 +3716,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3503,7 +3749,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3512,6 +3758,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3530,6 +3779,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3560,9 +3812,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3590,6 +3839,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3665,7 +3920,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3680,6 +3935,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3716,6 +3974,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3758,6 +4022,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3776,6 +4043,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3881,15 +4151,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4238,9 +4499,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4253,6 +4511,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4265,6 +4526,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4292,9 +4556,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4334,6 +4595,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4529,6 +4793,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4550,9 +4817,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4604,7 +4868,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4631,6 +4895,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4709,10 +4976,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4871,6 +5138,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5105,9 +5378,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5186,6 +5456,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5216,6 +5489,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5225,9 +5501,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5285,6 +5567,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5303,6 +5588,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5342,6 +5630,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5351,6 +5642,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5387,6 +5681,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5549,7 +5846,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5573,9 +5873,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5609,9 +5906,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5660,16 +5954,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5696,6 +5984,18 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5708,6 +6008,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5732,27 +6035,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5774,10 +6089,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5798,9 +6110,6 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5822,6 +6131,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5849,12 +6161,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5873,7 +6179,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5882,7 +6191,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5921,10 +6230,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -6011,6 +6320,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -6056,9 +6368,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6074,9 +6383,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6173,7 +6479,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6191,9 +6497,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6212,9 +6515,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6224,9 +6524,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6269,6 +6566,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6281,6 +6581,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6320,6 +6623,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6353,6 +6662,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6404,9 +6716,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6443,6 +6752,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6467,6 +6779,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6515,6 +6830,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6539,6 +6857,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6791,6 +7112,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6827,6 +7151,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6869,6 +7196,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6959,12 +7292,6 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -7001,12 +7328,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -7016,9 +7337,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7136,12 +7454,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7163,13 +7487,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7289,10 +7613,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7301,9 +7625,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7313,6 +7652,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7340,12 +7682,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7355,6 +7712,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7367,6 +7730,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7595,6 +7961,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7643,6 +8012,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7667,6 +8039,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7814,6 +8189,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7829,6 +8207,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7922,6 +8303,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7931,9 +8315,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7961,6 +8342,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8084,6 +8468,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8108,10 +8495,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8168,7 +8555,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8381,10 +8768,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8396,12 +8783,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8471,7 +8852,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8576,9 +8966,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8594,6 +8981,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8645,10 +9035,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8690,13 +9080,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8708,7 +9098,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8747,6 +9137,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8765,6 +9158,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8798,6 +9194,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8813,6 +9212,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8822,6 +9224,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8900,18 +9305,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -9038,6 +9431,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9113,7 +9509,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9176,6 +9572,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9188,6 +9590,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9197,15 +9602,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9224,6 +9638,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9239,9 +9656,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9332,6 +9755,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9344,6 +9770,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9353,9 +9782,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9371,24 +9797,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9398,6 +9845,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9629,9 +10079,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9671,15 +10118,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9857,6 +10304,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9866,10 +10319,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9920,6 +10373,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9971,6 +10430,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9989,6 +10451,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9998,6 +10463,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10250,9 +10721,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10286,9 +10754,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10451,12 +10916,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10490,6 +10964,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10502,10 +10982,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10523,10 +11006,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10544,12 +11030,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10616,9 +11108,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10820,6 +11309,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10925,6 +11417,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10934,6 +11429,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -11042,6 +11540,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -11051,6 +11552,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11201,6 +11705,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11210,7 +11717,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11219,6 +11729,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11231,7 +11747,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11249,13 +11768,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11267,6 +11786,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11276,6 +11798,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11285,10 +11810,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11381,10 +11906,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11417,6 +11942,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11450,6 +11978,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11474,18 +12008,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11537,6 +12089,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11576,6 +12152,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11612,18 +12194,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11636,6 +12227,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11699,6 +12293,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11711,6 +12308,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11768,6 +12392,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11813,6 +12440,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11825,19 +12476,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11963,6 +12617,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -12002,6 +12659,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12182,6 +12842,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12266,6 +12929,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12287,9 +12953,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12317,6 +12980,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12329,6 +12995,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12353,15 +13022,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12500,6 +13163,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12515,6 +13181,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12611,6 +13280,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12725,10 +13397,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12755,6 +13427,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12806,9 +13481,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12818,9 +13490,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12998,6 +13667,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -13007,9 +13679,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -13022,6 +13691,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -13055,6 +13727,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13103,9 +13778,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13166,7 +13850,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13184,6 +13868,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13205,9 +13892,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13229,19 +13913,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13265,6 +13952,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13322,6 +14030,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13340,6 +14054,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13376,6 +14093,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13439,6 +14159,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13448,6 +14225,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13457,21 +14240,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13532,6 +14333,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13646,6 +14450,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13655,6 +14462,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13667,9 +14477,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13679,9 +14486,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13715,6 +14519,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13745,6 +14597,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13811,6 +14666,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13868,6 +14726,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13886,18 +14747,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13988,12 +14840,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -14018,6 +14876,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14153,6 +15014,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14177,6 +15041,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14291,9 +15158,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14360,6 +15233,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14369,9 +15251,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14438,7 +15317,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14483,7 +15362,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14498,6 +15377,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14528,7 +15410,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14576,6 +15458,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14594,6 +15479,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14615,6 +15503,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14702,6 +15596,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14720,6 +15617,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14750,22 +15650,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14798,6 +15713,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14885,6 +15803,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14903,6 +15824,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14945,9 +15869,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14969,9 +15899,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14993,9 +15920,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15104,6 +16028,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15164,15 +16091,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15185,30 +16121,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15224,6 +16184,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15260,6 +16223,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15353,6 +16322,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15428,6 +16400,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15518,6 +16493,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15554,6 +16532,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15773,9 +16754,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15821,9 +16799,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15968,12 +16943,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -16004,6 +16973,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -16025,6 +16997,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -16055,6 +17030,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -16079,7 +17057,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -16088,6 +17066,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16202,9 +17183,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16370,6 +17348,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16415,6 +17396,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16565,6 +17549,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16658,12 +17645,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16739,9 +17732,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16760,30 +17750,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16919,9 +17963,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16931,6 +17972,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -17033,6 +18080,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -17042,9 +18092,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -17081,9 +18128,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17180,6 +18224,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17225,6 +18284,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17246,6 +18317,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17315,6 +18389,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17357,6 +18437,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17396,6 +18479,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17447,6 +18533,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17477,6 +18566,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17492,7 +18584,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17597,6 +18692,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17633,6 +18731,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17648,10 +18749,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17666,6 +18770,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17687,10 +18797,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17762,6 +18869,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17774,6 +18884,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17921,6 +19037,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17984,9 +19103,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -18023,9 +19139,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18155,9 +19268,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18215,6 +19334,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18245,10 +19367,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18347,9 +19469,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18362,9 +19490,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18374,24 +19499,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18527,6 +19652,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18608,6 +19736,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18659,12 +19790,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18710,9 +19847,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18785,6 +19931,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18950,6 +20102,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18986,6 +20141,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -19070,6 +20228,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -19088,7 +20249,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19127,15 +20288,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19160,12 +20321,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19187,6 +20357,15 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19373,6 +20552,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19409,9 +20591,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19508,6 +20696,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19547,6 +20738,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19595,6 +20789,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19712,6 +20912,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19877,7 +21080,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19952,6 +21155,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -20078,6 +21284,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -20105,6 +21314,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20132,6 +21344,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20312,9 +21527,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20399,6 +21620,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20426,9 +21650,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20681,6 +21902,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20765,9 +21989,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20804,9 +22025,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20846,6 +22073,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -21020,6 +22250,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -21068,6 +22301,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21143,6 +22379,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21215,6 +22460,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21278,6 +22526,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21362,6 +22613,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21401,6 +22655,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21446,9 +22703,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21560,7 +22814,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21587,6 +22841,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21623,12 +22880,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21641,12 +22904,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21665,7 +22940,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21674,9 +22949,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21731,9 +23003,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21980,6 +23258,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -22046,6 +23327,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22166,6 +23453,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22223,15 +23513,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22247,9 +23531,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22268,6 +23549,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22379,6 +23663,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22436,10 +23723,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22448,6 +23735,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22487,6 +23777,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22496,9 +23789,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22748,18 +24047,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22778,6 +24071,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22796,6 +24092,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22820,9 +24119,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22832,12 +24128,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22847,12 +24149,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22871,12 +24179,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22901,7 +24215,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22976,9 +24290,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23225,6 +24536,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23285,6 +24602,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23312,7 +24632,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23354,6 +24677,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23402,6 +24728,9 @@ msgstr[2] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23465,6 +24794,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23546,9 +24878,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23579,9 +24908,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23690,6 +25016,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23702,6 +25031,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23723,7 +25055,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23765,9 +25103,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23807,12 +25142,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23849,9 +25193,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23885,9 +25226,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -24008,10 +25346,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -24020,10 +25361,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24140,6 +25481,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24167,6 +25511,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24182,6 +25529,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24260,6 +25610,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24308,6 +25661,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24323,7 +25679,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24416,6 +25772,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24443,6 +25802,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24461,6 +25823,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24494,7 +25862,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24530,7 +25901,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24623,9 +25994,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24635,12 +26015,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24665,9 +26051,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24716,6 +26108,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24758,6 +26153,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24932,6 +26330,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24950,6 +26351,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24968,6 +26372,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -25010,6 +26417,9 @@ msgstr[2] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -25019,6 +26429,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -25028,6 +26441,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25079,6 +26495,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -25091,7 +26510,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -25124,10 +26546,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25193,9 +26615,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25259,6 +26690,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25280,6 +26714,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25319,6 +26759,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25448,7 +26891,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25628,9 +27071,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25640,15 +27080,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25661,6 +27092,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25706,6 +27140,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25739,9 +27176,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25766,6 +27212,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25817,6 +27269,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25883,10 +27338,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25949,6 +27404,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25976,6 +27437,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -26003,6 +27467,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/hu_HU/gitlab.po b/locale/hu_HU/gitlab.po
index 340f3e57d82..c0a1414f43a 100644
--- a/locale/hu_HU/gitlab.po
+++ b/locale/hu_HU/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: hu\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:13\n"
+"PO-Revision-Date: 2020-06-08 15:16\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,13 +8991,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8627,7 +9009,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] ""
msgstr[1] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/id_ID/gitlab.po b/locale/id_ID/gitlab.po
index 0c3e1a9e5ed..509cfa6426e 100644
--- a/locale/id_ID/gitlab.po
+++ b/locale/id_ID/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: id\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:34\n"
+"PO-Revision-Date: 2020-06-08 15:09\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -71,6 +71,14 @@ msgid "%d URL scanned"
msgid_plural "%d URLs scanned"
msgstr[0] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -87,6 +95,10 @@ msgid "%d comment"
msgid_plural "%d comments"
msgstr[0] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -106,6 +118,10 @@ msgid "%d contribution"
msgid_plural "%d contributions"
msgstr[0] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -162,6 +178,10 @@ msgid "%d more comment"
msgid_plural "%d more comments"
msgstr[0] ""
+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] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -186,6 +206,14 @@ msgid "%d unresolved thread"
msgid_plural "%d unresolved threads"
msgstr[0] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -206,6 +234,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -279,6 +310,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -288,6 +322,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -300,6 +337,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -333,12 +394,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -354,6 +424,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -392,6 +468,12 @@ msgid "%{releases} release"
msgid_plural "%{releases} releases"
msgstr[0] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -533,6 +615,9 @@ msgid "(%d closed)"
msgid_plural "(%d closed)"
msgstr[0] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -719,6 +804,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -749,6 +837,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -758,6 +849,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -794,7 +888,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -845,6 +942,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -857,9 +957,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -905,9 +1002,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -998,12 +1092,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1040,7 +1128,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1049,6 +1137,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1092,7 +1183,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1107,6 +1198,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1116,9 +1210,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1134,7 +1234,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1200,6 +1303,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1290,16 +1396,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1626,62 +1732,116 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Low"
+msgstr ""
+
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1690,16 +1850,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|Unknown"
+msgstr ""
+
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1873,6 +2051,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2038,9 +2219,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2062,6 +2240,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2137,6 +2318,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2173,9 +2357,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2191,6 +2381,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2200,6 +2393,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2224,12 +2420,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2239,9 +2429,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2305,6 +2501,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2369,12 +2568,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2384,12 +2577,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2498,6 +2697,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2510,7 +2712,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2624,6 +2826,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2698,15 +2903,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2764,6 +2987,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2785,9 +3011,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2806,6 +3029,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2836,6 +3062,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2851,6 +3080,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3328,16 +3560,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3361,7 +3593,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3370,6 +3602,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3388,6 +3623,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3418,9 +3656,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3448,6 +3683,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3523,7 +3764,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3538,6 +3779,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3574,6 +3818,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3616,6 +3866,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3634,6 +3887,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3739,15 +3995,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4096,9 +4343,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4111,6 +4355,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4123,6 +4370,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4150,9 +4400,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4192,6 +4439,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4387,6 +4637,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4408,9 +4661,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4462,7 +4712,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4489,6 +4739,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4567,10 +4820,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4729,6 +4982,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -4963,9 +5222,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5044,6 +5300,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5074,6 +5333,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5083,9 +5345,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5143,6 +5411,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5161,6 +5432,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5200,6 +5474,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5209,6 +5486,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5245,6 +5525,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5405,7 +5688,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5429,9 +5715,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5465,9 +5748,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5516,16 +5796,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5552,6 +5826,14 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5564,6 +5846,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5588,27 +5873,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5630,10 +5927,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5652,9 +5946,6 @@ msgid "ContainerRegistry|Remove tag"
msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5676,6 +5967,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5703,12 +5997,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5727,7 +6015,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5736,7 +6027,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5775,10 +6066,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5865,6 +6156,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5910,9 +6204,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -5928,9 +6219,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6027,7 +6315,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6045,9 +6333,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6066,9 +6351,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6078,9 +6360,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6123,6 +6402,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6135,6 +6417,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6174,6 +6459,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6207,6 +6498,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6258,9 +6552,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6297,6 +6588,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6321,6 +6615,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6369,6 +6666,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6393,6 +6693,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6643,6 +6946,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6679,6 +6985,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6721,6 +7030,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6809,10 +7124,6 @@ msgid "Dependencies|%d additional vulnerability not shown"
msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6847,12 +7158,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6862,9 +7167,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -6976,12 +7278,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7003,13 +7311,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7129,10 +7437,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7141,9 +7449,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7153,6 +7476,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7180,12 +7506,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7195,6 +7536,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7207,6 +7554,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7433,6 +7783,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7481,6 +7834,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7505,6 +7861,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7652,6 +8011,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7667,6 +8029,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7760,6 +8125,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7769,9 +8137,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7799,6 +8164,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -7922,6 +8290,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -7946,10 +8317,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8006,7 +8377,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8219,10 +8590,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8234,12 +8605,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8309,7 +8674,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8414,9 +8788,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8432,6 +8803,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8483,10 +8857,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8528,13 +8902,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8546,7 +8920,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8585,6 +8959,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8603,6 +8980,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8636,6 +9016,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8651,6 +9034,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8660,6 +9046,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8738,18 +9127,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8876,6 +9253,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -8951,7 +9331,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9014,6 +9394,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9026,6 +9412,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9035,15 +9424,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9062,6 +9460,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9077,9 +9478,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9170,6 +9577,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9182,6 +9592,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9191,9 +9604,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9209,24 +9619,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9236,6 +9667,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9467,9 +9901,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9509,15 +9940,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9695,6 +10126,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9704,10 +10141,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9758,6 +10195,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9809,6 +10252,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9827,6 +10273,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9836,6 +10285,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10088,9 +10543,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10124,9 +10576,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10289,12 +10738,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10328,6 +10786,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10340,10 +10804,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10361,10 +10828,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10382,12 +10852,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10454,9 +10930,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10658,6 +11131,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10763,6 +11239,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10772,6 +11251,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10876,6 +11358,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10885,6 +11370,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11035,6 +11523,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11044,7 +11535,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11053,6 +11547,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11065,7 +11565,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11083,13 +11586,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11101,6 +11604,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11110,6 +11616,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11119,10 +11628,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11215,10 +11724,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11251,6 +11760,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11284,6 +11796,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11308,18 +11826,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11369,6 +11905,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11408,6 +11968,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11444,18 +12010,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11468,6 +12043,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11531,6 +12109,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11543,6 +12124,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11600,6 +12208,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11645,6 +12256,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11657,19 +12292,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11795,6 +12433,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11834,6 +12475,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12012,6 +12656,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12096,6 +12743,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12117,9 +12767,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12147,6 +12794,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12159,6 +12809,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12183,15 +12836,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12322,6 +12969,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12337,6 +12987,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12431,6 +13084,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12545,10 +13201,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12575,6 +13231,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12626,9 +13285,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12638,9 +13294,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12818,6 +13471,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12827,9 +13483,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12842,6 +13495,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12875,6 +13531,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -12923,9 +13582,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -12986,7 +13654,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13004,6 +13672,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13025,9 +13696,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13049,19 +13717,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13085,6 +13756,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13140,6 +13832,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13158,6 +13856,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13194,6 +13895,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13255,6 +13959,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13264,6 +14025,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13273,21 +14040,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13348,6 +14133,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13462,6 +14250,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13471,6 +14262,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13483,9 +14277,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13495,9 +14286,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13531,6 +14319,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13559,6 +14395,9 @@ msgid "New Issue"
msgid_plural "New Issues"
msgstr[0] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13625,6 +14464,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13682,6 +14524,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13700,18 +14545,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13802,12 +14638,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13832,6 +14674,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -13967,6 +14812,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -13991,6 +14839,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14105,9 +14956,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14174,6 +15031,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14183,9 +15049,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14250,7 +15113,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14295,7 +15158,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14310,6 +15173,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14340,7 +15206,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14388,6 +15254,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14406,6 +15275,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14427,6 +15299,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14514,6 +15392,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14532,6 +15413,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14562,22 +15446,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14610,6 +15509,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14697,6 +15599,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14715,6 +15620,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14757,9 +15665,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14781,9 +15695,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14805,9 +15716,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -14916,6 +15824,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -14976,15 +15887,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -14997,30 +15917,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15036,6 +15980,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15072,6 +16019,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15165,6 +16118,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15240,6 +16196,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15330,6 +16289,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15366,6 +16328,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15585,9 +16550,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15633,9 +16595,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15780,12 +16739,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15816,6 +16769,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15837,6 +16793,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15867,6 +16826,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15891,7 +16853,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15900,6 +16862,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16014,9 +16979,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16182,6 +17144,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16227,6 +17192,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16377,6 +17345,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16470,12 +17441,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16551,9 +17528,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16572,30 +17546,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16731,9 +17759,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16743,6 +17768,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16845,6 +17876,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16854,9 +17888,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16893,9 +17924,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -16990,6 +18018,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17033,6 +18076,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17054,6 +18109,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17123,6 +18181,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17165,6 +18229,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17204,6 +18271,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17255,6 +18325,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17285,6 +18358,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17300,7 +18376,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17403,6 +18482,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17439,6 +18521,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17454,10 +18539,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17472,6 +18560,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17493,10 +18587,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17564,6 +18655,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17576,6 +18670,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17721,6 +18821,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17784,9 +18887,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17823,9 +18923,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -17955,9 +19052,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18015,6 +19118,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18045,10 +19151,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18127,9 +19233,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18142,9 +19254,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18154,24 +19263,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18307,6 +19416,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18388,6 +19500,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18439,12 +19554,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18490,9 +19611,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18565,6 +19695,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18730,6 +19866,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18766,6 +19905,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18850,6 +19992,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18868,7 +20013,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -18907,15 +20052,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -18940,12 +20085,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -18965,6 +20119,13 @@ msgid "Showing %d event"
msgid_plural "Showing %d events"
msgstr[0] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19151,6 +20312,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19187,9 +20351,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19286,6 +20456,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19325,6 +20498,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19373,6 +20549,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19490,6 +20672,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19655,7 +20840,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19730,6 +20915,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19856,6 +21044,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19883,6 +21074,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -19910,6 +21104,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20090,9 +21287,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20177,6 +21380,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20204,9 +21410,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20457,6 +21660,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20539,9 +21745,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20578,9 +21781,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20618,6 +21827,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20792,6 +22004,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20840,6 +22055,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -20915,6 +22133,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -20987,6 +22214,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21050,6 +22280,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21134,6 +22367,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21173,6 +22409,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21218,9 +22457,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21332,7 +22568,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21359,6 +22595,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21395,12 +22634,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21413,12 +22658,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21437,7 +22694,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21446,9 +22703,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21503,9 +22757,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21752,6 +23012,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21814,6 +23077,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -21934,6 +23203,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -21991,15 +23263,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22015,9 +23281,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22036,6 +23299,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22147,6 +23413,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22204,10 +23473,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22216,6 +23485,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22255,6 +23527,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22264,9 +23539,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22516,18 +23797,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22546,6 +23821,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22564,6 +23842,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22588,9 +23869,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22600,12 +23878,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22615,12 +23899,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22639,12 +23929,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22669,7 +23965,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22744,9 +24040,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -22993,6 +24286,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23053,6 +24352,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23080,7 +24382,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23122,6 +24427,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23166,6 +24474,9 @@ msgstr[0] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23229,6 +24540,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23310,9 +24624,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23343,9 +24654,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23454,6 +24762,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23466,6 +24777,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23487,7 +24801,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23529,9 +24849,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23571,12 +24888,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23611,9 +24937,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23647,9 +24970,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23770,10 +25090,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23782,10 +25105,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -23902,6 +25225,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -23929,6 +25255,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -23944,6 +25273,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24022,6 +25354,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24070,6 +25405,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24085,7 +25423,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24178,6 +25516,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24205,6 +25546,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24223,6 +25567,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24256,7 +25606,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24292,7 +25645,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24385,9 +25738,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24397,12 +25759,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24427,9 +25795,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24476,6 +25850,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24518,6 +25895,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24682,6 +26062,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24700,6 +26083,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24718,6 +26104,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24758,6 +26147,9 @@ msgstr[0] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24767,6 +26159,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24776,6 +26171,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24825,6 +26223,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24835,7 +26236,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24868,10 +26272,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -24935,9 +26339,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -24999,6 +26412,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25020,6 +26436,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25059,6 +26481,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25186,7 +26611,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25366,9 +26791,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25378,15 +26800,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25399,6 +26812,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25444,6 +26860,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25473,9 +26892,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25496,6 +26924,12 @@ msgid "project"
msgid_plural "projects"
msgstr[0] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25545,6 +26979,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25611,10 +27048,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25677,6 +27114,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25704,6 +27147,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25731,6 +27177,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/is_IS/gitlab.po b/locale/is_IS/gitlab.po
new file mode 100644
index 00000000000..436367793f1
--- /dev/null
+++ b/locale/is_IS/gitlab.po
@@ -0,0 +1,27339 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: gitlab-ee\n"
+"Report-Msgid-Bugs-To: \n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: Icelandic\n"
+"Language: is_IS\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Crowdin-Project: gitlab-ee\n"
+"X-Crowdin-Language: is\n"
+"X-Crowdin-File: /master/locale/gitlab.pot\n"
+"PO-Revision-Date: 2020-06-08 15:09\n"
+
+msgid " %{start} to %{end}"
+msgstr ""
+
+msgid " (from %{timeoutSource})"
+msgstr ""
+
+msgid " Collected %{time}"
+msgstr ""
+
+msgid " Please sign in."
+msgstr ""
+
+msgid " Try to %{action} this file again."
+msgstr ""
+
+msgid " You need to do this before %{grace_period_deadline}."
+msgstr ""
+
+msgid " and"
+msgstr ""
+
+msgid " and "
+msgstr ""
+
+msgid " and %{sliced}"
+msgstr ""
+
+msgid " degraded on %d point"
+msgid_plural " degraded on %d points"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid " improved on %d point"
+msgid_plural " improved on %d points"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid " or "
+msgstr ""
+
+msgid " or <!merge request id>"
+msgstr ""
+
+msgid " or <#issue id>"
+msgstr ""
+
+msgid " or <&epic id>"
+msgstr ""
+
+msgid " or references (e.g. path/to/project!merge_request_id)"
+msgstr ""
+
+msgid "\"%{path}\" did not exist on \"%{ref}\""
+msgstr ""
+
+msgid "%d URL scanned"
+msgid_plural "%d URLs scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d changed file"
+msgid_plural "%d changed files"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d child epic"
+msgid_plural "%d child epics"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d code quality issue"
+msgid_plural "%d code quality issues"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d comment"
+msgid_plural "%d comments"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d commit"
+msgid_plural "%d commits"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d commit behind"
+msgid_plural "%d commits behind"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d commit,"
+msgid_plural "%d commits,"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d commits"
+msgstr ""
+
+msgid "%d contribution"
+msgid_plural "%d contributions"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d error"
+msgid_plural "%d errors"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d exporter"
+msgid_plural "%d exporters"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d failed"
+msgid_plural "%d failed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d fixed test result"
+msgid_plural "%d fixed test results"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d group selected"
+msgid_plural "%d groups selected"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d inaccessible merge request"
+msgid_plural "%d inaccessible merge requests"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d issue"
+msgid_plural "%d issues"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d issue selected"
+msgid_plural "%d issues selected"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d layer"
+msgid_plural "%d layers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d merge request"
+msgid_plural "%d merge requests"
+msgstr[0] ""
+msgstr[1] ""
+
+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] ""
+
+msgid "%d metric"
+msgid_plural "%d metrics"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d minute"
+msgid_plural "%d minutes"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d more comment"
+msgid_plural "%d more comments"
+msgstr[0] ""
+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] ""
+msgstr[1] ""
+
+msgid "%d project"
+msgid_plural "%d projects"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d request with warnings"
+msgid_plural "%d requests with warnings"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d second"
+msgid_plural "%d seconds"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d shard selected"
+msgid_plural "%d shards selected"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d tag"
+msgid_plural "%d tags"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d unresolved thread"
+msgid_plural "%d unresolved threads"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability dismissed"
+msgid_plural "%d vulnerabilities dismissed"
+msgstr[0] ""
+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] ""
+msgstr[1] ""
+
+msgid "%{actionText} & %{openOrClose} %{noteable}"
+msgstr ""
+
+msgid "%{authorsName}'s thread"
+msgstr ""
+
+msgid "%{commit_author_link} authored %{commit_timeago}"
+msgstr ""
+
+msgid "%{completedWeight} of %{totalWeight} weight completed"
+msgstr ""
+
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
+msgid "%{cores} cores"
+msgstr ""
+
+msgid "%{count} LOC/commit"
+msgstr ""
+
+msgid "%{count} approval required from %{name}"
+msgid_plural "%{count} approvals required from %{name}"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%{count} approvals from %{name}"
+msgstr ""
+
+msgid "%{count} files touched"
+msgstr ""
+
+msgid "%{count} more"
+msgstr ""
+
+msgid "%{count} more assignees"
+msgstr ""
+
+msgid "%{count} more release"
+msgid_plural "%{count} more releases"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%{count} of %{required} approvals from %{name}"
+msgstr ""
+
+msgid "%{count} of %{total}"
+msgstr ""
+
+msgid "%{count} participant"
+msgid_plural "%{count} participants"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%{count} pending comment"
+msgid_plural "%{count} pending comments"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%{count} related %{pluralized_subject}: %{links}"
+msgstr ""
+
+msgid "%{days} days until tags are automatically removed"
+msgstr ""
+
+msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last seen: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
+msgstr ""
+
+msgid "%{duration}ms"
+msgstr ""
+
+msgid "%{edit_in_new_fork_notice} Try to cherry-pick this commit again."
+msgstr ""
+
+msgid "%{edit_in_new_fork_notice} Try to create a new directory again."
+msgstr ""
+
+msgid "%{edit_in_new_fork_notice} Try to revert this commit again."
+msgstr ""
+
+msgid "%{edit_in_new_fork_notice} Try to upload a file again."
+msgstr ""
+
+msgid "%{extra} more downstream pipelines"
+msgstr ""
+
+msgid "%{filePath} deleted"
+msgstr ""
+
+msgid "%{firstLabel} +%{labelCount} more"
+msgstr ""
+
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
+msgid "%{global_id} is not a valid id for %{expected_type}."
+msgstr ""
+
+msgid "%{group_docs_link_start}Groups%{group_docs_link_end} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
+msgstr ""
+
+msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
+msgstr ""
+
+msgid "%{host} sign-in from new location"
+msgstr ""
+
+msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
+msgstr ""
+
+msgid "%{issuableType} will be removed! Are you sure?"
+msgstr ""
+
+msgid "%{issuesSize} issues"
+msgstr ""
+
+msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
+msgstr ""
+
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
+msgid "%{label_for_message} unavailable"
+msgstr ""
+
+msgid "%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end} is a free, automated, and open certificate authority (CA), that give digital certificates in order to enable HTTPS (SSL/TLS) for websites."
+msgstr ""
+
+msgid "%{level_name} is not allowed in a %{group_level_name} group."
+msgstr ""
+
+msgid "%{level_name} is not allowed since the fork source project has lower visibility."
+msgstr ""
+
+msgid "%{lineOneStart}Drag and drop to upload your designs%{lineOneEnd} or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "%{link_start}Learn more%{link_end} about what information is shared with GitLab Inc."
+msgstr ""
+
+msgid "%{link_start}Read more%{link_end} about role permissions"
+msgstr ""
+
+msgid "%{link} can be used for binding events when something is happening within the project."
+msgstr ""
+
+msgid "%{listToShow}, and %{awardsListLength} more."
+msgstr ""
+
+msgid "%{loadingIcon} Started"
+msgstr ""
+
+msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
+msgstr ""
+
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
+msgid "%{mergeLength}/%{usersLength} can merge"
+msgstr ""
+
+msgid "%{mrText}, this issue will be closed automatically."
+msgstr ""
+
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
+msgstr ""
+
+msgid "%{name} contained %{resultsString}"
+msgstr ""
+
+msgid "%{name} found %{resultsString}"
+msgstr ""
+
+msgid "%{name} is scheduled for %{action}"
+msgstr ""
+
+msgid "%{name}'s avatar"
+msgstr ""
+
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{no_of_days} day"
+msgid_plural "%{no_of_days} days"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%{number_commits_behind} commits behind %{default_branch}, %{number_commits_ahead} commits ahead"
+msgstr ""
+
+msgid "%{openOrClose} %{noteable}"
+msgstr ""
+
+msgid "%{openedEpics} open, %{closedEpics} closed"
+msgstr ""
+
+msgid "%{openedIssues} open, %{closedIssues} closed"
+msgstr ""
+
+msgid "%{percentage}%% weight completed"
+msgstr ""
+
+msgid "%{percent}%% complete"
+msgstr ""
+
+msgid "%{percent}%{percentSymbol} complete"
+msgstr ""
+
+msgid "%{placeholder} is not a valid color scheme"
+msgstr ""
+
+msgid "%{placeholder} is not a valid theme"
+msgstr ""
+
+msgid "%{primary} (%{secondary})"
+msgstr ""
+
+msgid "%{releases} release"
+msgid_plural "%{releases} releases"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
+msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
+msgstr ""
+
+msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Enabled"
+msgstr ""
+
+msgid "%{service_title} %{message}."
+msgstr ""
+
+msgid "%{size} GiB"
+msgstr ""
+
+msgid "%{size} KiB"
+msgstr ""
+
+msgid "%{size} MiB"
+msgstr ""
+
+msgid "%{size} bytes"
+msgstr ""
+
+msgid "%{spammable_titlecase} was submitted to Akismet successfully."
+msgstr ""
+
+msgid "%{spanStart}at line%{spanEnd} %{errorLine}%{errorColumn}"
+msgstr ""
+
+msgid "%{spanStart}in%{spanEnd} %{errorFn}"
+msgstr ""
+
+msgid "%{start} to %{end}"
+msgstr ""
+
+msgid "%{state} epics"
+msgstr ""
+
+msgid "%{strongStart}Note:%{strongEnd} Once a custom stage has been added you can re-order stages by dragging them into the desired position."
+msgstr ""
+
+msgid "%{strong_start}%{branch_count}%{strong_end} Branch"
+msgid_plural "%{strong_start}%{branch_count}%{strong_end} Branches"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%{strong_start}%{commit_count}%{strong_end} Commit"
+msgid_plural "%{strong_start}%{commit_count}%{strong_end} Commits"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%{strong_start}%{human_size}%{strong_end} Files"
+msgstr ""
+
+msgid "%{strong_start}%{human_size}%{strong_end} Storage"
+msgstr ""
+
+msgid "%{strong_start}%{release_count}%{strong_end} Release"
+msgid_plural "%{strong_start}%{release_count}%{strong_end} Releases"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%{strong_start}%{tag_count}%{strong_end} Tag"
+msgid_plural "%{strong_start}%{tag_count}%{strong_end} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%{tabname} changed"
+msgstr ""
+
+msgid "%{tags} tag per image name"
+msgstr ""
+
+msgid "%{tags} tags per image name"
+msgstr ""
+
+msgid "%{tag}-%{evidence}-%{filename}"
+msgstr ""
+
+msgid "%{template_project_id} is unknown or invalid"
+msgstr ""
+
+msgid "%{text} %{files}"
+msgid_plural "%{text} %{files} files"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%{text} is available"
+msgstr ""
+
+msgid "%{timebox_name} should belong either to a project or a group."
+msgstr ""
+
+msgid "%{title} %{operator} %{threshold}"
+msgstr ""
+
+msgid "%{title} changes"
+msgstr ""
+
+msgid "%{token}..."
+msgstr ""
+
+msgid "%{totalWeight} total weight"
+msgstr ""
+
+msgid "%{total} open issue weight"
+msgstr ""
+
+msgid "%{total} open issues"
+msgstr ""
+
+msgid "%{usage_ping_link_start}Learn more%{usage_ping_link_end} about what information is shared with GitLab Inc."
+msgstr ""
+
+msgid "%{userName} (cannot merge)"
+msgstr ""
+
+msgid "%{userName}'s avatar"
+msgstr ""
+
+msgid "%{user_name} profile page"
+msgstr ""
+
+msgid "%{username}'s avatar"
+msgstr ""
+
+msgid "%{value} s"
+msgstr ""
+
+msgid "%{verb} %{time_spent_value} spent time."
+msgstr ""
+
+msgid "'%{level}' is not a valid visibility level"
+msgstr ""
+
+msgid "'%{name}' stage already exists"
+msgstr ""
+
+msgid "'%{source}' is not a import source"
+msgstr ""
+
+msgid "'%{template_name}' is unknown or invalid"
+msgstr ""
+
+msgid "(%d closed)"
+msgid_plural "(%d closed)"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
+msgid "(%{mrCount} merged)"
+msgstr ""
+
+msgid "(No changes)"
+msgstr ""
+
+msgid "(Show all)"
+msgstr ""
+
+msgid "(check progress)"
+msgstr ""
+
+msgid "(external source)"
+msgstr ""
+
+msgid "(removed)"
+msgstr ""
+
+msgid "(revoked)"
+msgstr ""
+
+msgid "*"
+msgstr ""
+
+msgid "+ %{amount} more"
+msgstr ""
+
+msgid "+ %{count} more"
+msgstr ""
+
+msgid "+ %{moreCount} more"
+msgstr ""
+
+msgid "+ %{numberOfHiddenAssignees} more"
+msgstr ""
+
+msgid "+%d more"
+msgid_plural "+%d more"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "+%{approvers} more approvers"
+msgstr ""
+
+msgid "+%{tags} more"
+msgstr ""
+
+msgid ", or "
+msgstr ""
+
+msgid "- Event"
+msgid_plural "- Events"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "- Runner is active and can process any new jobs"
+msgstr ""
+
+msgid "- Runner is paused and will not receive any new jobs"
+msgstr ""
+
+msgid "- User"
+msgid_plural "- Users"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "- of - weight completed"
+msgstr ""
+
+msgid "- show less"
+msgstr ""
+
+msgid "0 for unlimited"
+msgstr ""
+
+msgid "1 %{type} addition"
+msgid_plural "%{count} %{type} additions"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 %{type} modification"
+msgid_plural "%{count} %{type} modifications"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 Day"
+msgid_plural "%d Days"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 closed issue"
+msgid_plural "%{issues} closed issues"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 closed merge request"
+msgid_plural "%{merge_requests} closed merge requests"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 group"
+msgid_plural "%d groups"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 hour"
+msgid_plural "%d hours"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 merged merge request"
+msgid_plural "%{merge_requests} merged merge requests"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 minute"
+msgid_plural "%d minutes"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 month"
+msgstr ""
+
+msgid "1 open issue"
+msgid_plural "%{issues} open issues"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 open merge request"
+msgid_plural "%{merge_requests} open merge requests"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 pipeline"
+msgid_plural "%d pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 role"
+msgid_plural "%d roles"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 user"
+msgid_plural "%{num} users"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "1 week"
+msgstr ""
+
+msgid "1-9 contributions"
+msgstr ""
+
+msgid "10-19 contributions"
+msgstr ""
+
+msgid "1st contribution!"
+msgstr ""
+
+msgid "20-29 contributions"
+msgstr ""
+
+msgid "2FA"
+msgstr ""
+
+msgid "2FADevice|Registered On"
+msgstr ""
+
+msgid "3 days"
+msgstr ""
+
+msgid "3 hours"
+msgstr ""
+
+msgid "30 minutes"
+msgstr ""
+
+msgid "30+ contributions"
+msgstr ""
+
+msgid "403|Please contact your GitLab administrator to get permission."
+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 ""
+
+msgid "404|Page Not Found"
+msgstr ""
+
+msgid "404|Please contact your GitLab administrator if you think this is a mistake."
+msgstr ""
+
+msgid "8 hours"
+msgstr ""
+
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
+msgid "< 1 hour"
+msgstr ""
+
+msgid "<code>\"johnsmith@example.com\": \"@johnsmith\"</code> will add \"By <a href=\"#\">@johnsmith</a>\" to all issues and comments originally created by johnsmith@example.com, and will set <a href=\"#\">@johnsmith</a> as the assignee on all issues originally assigned to johnsmith@example.com."
+msgstr ""
+
+msgid "<code>\"johnsmith@example.com\": \"John Smith\"</code> will add \"By John Smith\" to all issues and comments originally created by johnsmith@example.com."
+msgstr ""
+
+msgid "<code>\"johnsmith@example.com\": \"johnsm...@example.com\"</code> will add \"By johnsm...@example.com\" to all issues and comments originally created by johnsmith@example.com. The email address or username is masked to ensure the user's privacy."
+msgstr ""
+
+msgid "<code>\"johnsmith@example.com\": \"johnsmith@example.com\"</code> will add \"By <a href=\"#\">johnsmith@example.com</a>\" to all issues and comments originally created by johnsmith@example.com. By default, the email address or username is masked to ensure the user's privacy. Use this option if you want to show the full email address."
+msgstr ""
+
+msgid "<namespace / project>"
+msgstr ""
+
+msgid "<no name set>"
+msgstr ""
+
+msgid "<no scopes selected>"
+msgstr ""
+
+msgid "<project name>"
+msgstr ""
+
+msgid "<strong>%{group_name}</strong> group members"
+msgstr ""
+
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
+msgid "<strong>Deletes</strong> source branch"
+msgstr ""
+
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
+msgstr ""
+
+msgid "A .NET Core console application template, customizable for any .NET Core project"
+msgstr ""
+
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
+msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
+msgstr ""
+
+msgid "A Hexo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
+msgstr ""
+
+msgid "A Hugo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
+msgstr ""
+
+msgid "A Jekyll site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
+msgstr ""
+
+msgid "A Let's Encrypt SSL certificate can not be obtained until your domain is verified."
+msgstr ""
+
+msgid "A Let's Encrypt account will be configured for this GitLab installation using your email address. You will receive emails to warn of expiring certificates."
+msgstr ""
+
+msgid "A basic page and serverless function that uses AWS Lambda, AWS API Gateway, and GitLab Pages"
+msgstr ""
+
+msgid "A complete DevOps platform"
+msgstr ""
+
+msgid "A default branch cannot be chosen for an empty project."
+msgstr ""
+
+msgid "A deleted user"
+msgstr ""
+
+msgid "A file with '%{file_name}' already exists in %{branch} branch"
+msgstr ""
+
+msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
+msgstr ""
+
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
+msgstr ""
+
+msgid "A member of the abuse team will review your report as soon as possible."
+msgstr ""
+
+msgid "A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
+msgstr ""
+
+msgid "A merge request approval is required when the license compliance report contains a blacklisted license."
+msgstr ""
+
+msgid "A new Auto DevOps pipeline has been created, go to %{pipelines_link_start}Pipelines page%{pipelines_link_end} for details"
+msgstr ""
+
+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 ""
+
+msgid "A new Release %{tag} for %{name} was published. Visit the Releases page to read more about it:"
+msgstr ""
+
+msgid "A new branch will be created in your fork and a new merge request will be started."
+msgstr ""
+
+msgid "A new impersonation token has been created."
+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 project boilerplate for Salesforce App development with Salesforce Developer tools."
+msgstr ""
+
+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 ""
+
+msgid "A project is where you house your files (repository), plan your work (issues), and publish your documentation (wiki), %{among_other_things_link}."
+msgstr ""
+
+msgid "A ready-to-go template for use with Android apps."
+msgstr ""
+
+msgid "A ready-to-go template for use with iOS Swift apps."
+msgstr ""
+
+msgid "A regular expression that will be used to find the test coverage output in the job log. Leave blank to disable"
+msgstr ""
+
+msgid "A secure token that identifies an external storage request."
+msgstr ""
+
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
+msgid "A subscription will 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 ""
+
+msgid "A terraform report was generated in your pipelines."
+msgstr ""
+
+msgid "A user with write access to the source branch selected this option"
+msgstr ""
+
+msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
+msgstr ""
+
+msgid "API Token"
+msgstr ""
+
+msgid "AWS Access Key"
+msgstr ""
+
+msgid "AWS Access Key. Only required if not using role instance credentials"
+msgstr ""
+
+msgid "AWS Secret Access Key"
+msgstr ""
+
+msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgstr ""
+
+msgid "Abort"
+msgstr ""
+
+msgid "About GitLab"
+msgstr ""
+
+msgid "About GitLab CE"
+msgstr ""
+
+msgid "About auto deploy"
+msgstr ""
+
+msgid "About this feature"
+msgstr ""
+
+msgid "Abuse Reports"
+msgstr ""
+
+msgid "Abuse reports"
+msgstr ""
+
+msgid "Accept invitation"
+msgstr ""
+
+msgid "Accept terms"
+msgstr ""
+
+msgid "Acceptable for use in this project"
+msgstr ""
+
+msgid "Access Tokens"
+msgstr ""
+
+msgid "Access denied for your LDAP account."
+msgstr ""
+
+msgid "Access denied! Please verify you can add deploy keys to this repository."
+msgstr ""
+
+msgid "Access expiration date"
+msgstr ""
+
+msgid "Access forbidden. Check your access level."
+msgstr ""
+
+msgid "Access to '%{classification_label}' not allowed"
+msgstr ""
+
+msgid "Access to Pages websites are controlled based on the user's membership to a given project. By checking this box, users will be required to be logged in to have access to all Pages websites in your instance."
+msgstr ""
+
+msgid "AccessDropdown|Groups"
+msgstr ""
+
+msgid "AccessDropdown|Roles"
+msgstr ""
+
+msgid "AccessDropdown|Users"
+msgstr ""
+
+msgid "AccessTokens|Access Tokens"
+msgstr ""
+
+msgid "AccessTokens|Are you sure?"
+msgstr ""
+
+msgid "AccessTokens|Are you sure? Any RSS or calendar URLs currently in use will stop working."
+msgstr ""
+
+msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
+msgstr ""
+
+msgid "AccessTokens|Created"
+msgstr ""
+
+msgid "AccessTokens|Feed token"
+msgstr ""
+
+msgid "AccessTokens|Incoming email token"
+msgstr ""
+
+msgid "AccessTokens|It cannot be used to access any other data."
+msgstr ""
+
+msgid "AccessTokens|Keep this token secret. Anyone who gets ahold of it can access repository static objects as if they were you. You should %{reset_link_start}reset it%{reset_link_end} if that ever happens."
+msgstr ""
+
+msgid "AccessTokens|Keep this token secret. Anyone who gets ahold of it can create issues as if they were you. You should %{link_reset_it} if that ever happens."
+msgstr ""
+
+msgid "AccessTokens|Keep this token secret. Anyone who gets ahold of it can read activity and issue RSS feeds or your calendar feed as if they were you. You should %{link_reset_it} if that ever happens."
+msgstr ""
+
+msgid "AccessTokens|Personal Access Tokens"
+msgstr ""
+
+msgid "AccessTokens|Static object token"
+msgstr ""
+
+msgid "AccessTokens|They are the only accepted password when you have Two-Factor Authentication (2FA) enabled."
+msgstr ""
+
+msgid "AccessTokens|You can also use personal access tokens to authenticate against Git over HTTP."
+msgstr ""
+
+msgid "AccessTokens|You can generate a personal access token for each application you use that needs access to the GitLab API."
+msgstr ""
+
+msgid "AccessTokens|Your feed token is used to authenticate you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar, and is included in those feed URLs."
+msgstr ""
+
+msgid "AccessTokens|Your incoming email token is used to authenticate you when you create a new issue by email, and is included in your personal project-specific email addresses."
+msgstr ""
+
+msgid "AccessTokens|Your static object token is used to authenticate you when repository static objects (e.g. archives, blobs, ...) are being served from an external storage."
+msgstr ""
+
+msgid "AccessTokens|reset it"
+msgstr ""
+
+msgid "AccessibilityReport|Learn More"
+msgstr ""
+
+msgid "AccessibilityReport|Message: %{message}"
+msgstr ""
+
+msgid "AccessibilityReport|New"
+msgstr ""
+
+msgid "AccessibilityReport|The accessibility scanning found an error of the following type: %{code}"
+msgstr ""
+
+msgid "Account"
+msgstr ""
+
+msgid "Account ID"
+msgstr ""
+
+msgid "Account and limit"
+msgstr ""
+
+msgid "Account: %{account}"
+msgstr ""
+
+msgid "Action to take when receiving an alert."
+msgstr ""
+
+msgid "Activate"
+msgstr ""
+
+msgid "Activate Service Desk"
+msgstr ""
+
+msgid "Active"
+msgstr ""
+
+msgid "Active %{type} (%{token_length})"
+msgstr ""
+
+msgid "Active Sessions"
+msgstr ""
+
+msgid "Active Users:"
+msgstr ""
+
+msgid "Active users"
+msgstr ""
+
+msgid "Activity"
+msgstr ""
+
+msgid "Add"
+msgstr ""
+
+msgid "Add %d issue"
+msgid_plural "Add %d issues"
+msgstr[0] ""
+msgstr[1] ""
+
+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 ""
+
+msgid "Add CONTRIBUTING"
+msgstr ""
+
+msgid "Add GitLab to Slack"
+msgstr ""
+
+msgid "Add Group Webhooks and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Add Jaeger URL"
+msgstr ""
+
+msgid "Add Kubernetes cluster"
+msgstr ""
+
+msgid "Add LICENSE"
+msgstr ""
+
+msgid "Add README"
+msgstr ""
+
+msgid "Add Variable"
+msgstr ""
+
+msgid "Add Zoom meeting"
+msgstr ""
+
+msgid "Add a %{type}"
+msgstr ""
+
+msgid "Add a GPG key"
+msgstr ""
+
+msgid "Add a Grafana button in the admin sidebar, monitoring section, to access a variety of statistics on the health and performance of GitLab."
+msgstr ""
+
+msgid "Add a To Do"
+msgstr ""
+
+msgid "Add a bullet list"
+msgstr ""
+
+msgid "Add a comment to this line"
+msgstr ""
+
+msgid "Add a general comment to this %{noteableDisplayName}."
+msgstr ""
+
+msgid "Add a general comment to this %{noteable_name}."
+msgstr ""
+
+msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
+msgstr ""
+
+msgid "Add a line"
+msgstr ""
+
+msgid "Add a link"
+msgstr ""
+
+msgid "Add a new issue"
+msgstr ""
+
+msgid "Add a numbered list"
+msgstr ""
+
+msgid "Add a table"
+msgstr ""
+
+msgid "Add a task list"
+msgstr ""
+
+msgid "Add additional text to appear in all email communications. %{character_limit} character limit"
+msgstr ""
+
+msgid "Add an SSH key"
+msgstr ""
+
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
+msgstr ""
+
+msgid "Add an issue"
+msgstr ""
+
+msgid "Add another link"
+msgstr ""
+
+msgid "Add approval rule"
+msgstr ""
+
+msgid "Add bold text"
+msgstr ""
+
+msgid "Add child epic to an epic"
+msgstr ""
+
+msgid "Add comment now"
+msgstr ""
+
+msgid "Add domain"
+msgstr ""
+
+msgid "Add email address"
+msgstr ""
+
+msgid "Add environment"
+msgstr ""
+
+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 ""
+
+msgid "Add issues"
+msgstr ""
+
+msgid "Add italic text"
+msgstr ""
+
+msgid "Add label(s)"
+msgstr ""
+
+msgid "Add license"
+msgstr ""
+
+msgid "Add list"
+msgstr ""
+
+msgid "Add new application"
+msgstr ""
+
+msgid "Add new directory"
+msgstr ""
+
+msgid "Add or subtract spent time"
+msgstr ""
+
+msgid "Add reaction"
+msgstr ""
+
+msgid "Add request manually"
+msgstr ""
+
+msgid "Add strikethrough text"
+msgstr ""
+
+msgid "Add system hook"
+msgstr ""
+
+msgid "Add to Slack"
+msgstr ""
+
+msgid "Add to epic"
+msgstr ""
+
+msgid "Add to merge train"
+msgstr ""
+
+msgid "Add to merge train when pipeline succeeds"
+msgstr ""
+
+msgid "Add to review"
+msgstr ""
+
+msgid "Add to tree"
+msgstr ""
+
+msgid "Add user(s) to the group:"
+msgstr ""
+
+msgid "Add users to group"
+msgstr ""
+
+msgid "Add variable"
+msgstr ""
+
+msgid "Add webhook"
+msgstr ""
+
+msgid "AddMember|No users specified."
+msgstr ""
+
+msgid "AddMember|Too many users specified (limit is %{user_limit})"
+msgstr ""
+
+msgid "Added"
+msgstr ""
+
+msgid "Added %{epic_ref} as a child epic."
+msgstr ""
+
+msgid "Added %{label_references} %{label_text}."
+msgstr ""
+
+msgid "Added a To Do."
+msgstr ""
+
+msgid "Added an issue to an epic."
+msgstr ""
+
+msgid "Added at"
+msgstr ""
+
+msgid "Added for this merge request"
+msgstr ""
+
+msgid "Added in this version"
+msgstr ""
+
+msgid "Adding new applications is disabled in your GitLab instance. Please contact your GitLab administrator to get the permission"
+msgstr ""
+
+msgid "Additional minutes"
+msgstr ""
+
+msgid "Additional text"
+msgstr ""
+
+msgid "Adds"
+msgstr ""
+
+msgid "Adds %{epic_ref} as child epic."
+msgstr ""
+
+msgid "Adds %{labels} %{label_text}."
+msgstr ""
+
+msgid "Adds a To Do."
+msgstr ""
+
+msgid "Adds a Zoom meeting"
+msgstr ""
+
+msgid "Adds an issue to an epic."
+msgstr ""
+
+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 ""
+
+msgid "Admin Area"
+msgstr ""
+
+msgid "Admin Note"
+msgstr ""
+
+msgid "Admin Overview"
+msgstr ""
+
+msgid "Admin mode already enabled"
+msgstr ""
+
+msgid "Admin mode disabled"
+msgstr ""
+
+msgid "Admin mode enabled"
+msgstr ""
+
+msgid "Admin notes"
+msgstr ""
+
+msgid "AdminArea|Active users"
+msgstr ""
+
+msgid "AdminArea|Billable users"
+msgstr ""
+
+msgid "AdminArea|Blocked users"
+msgstr ""
+
+msgid "AdminArea|Bots"
+msgstr ""
+
+msgid "AdminArea|Developer"
+msgstr ""
+
+msgid "AdminArea|Guest"
+msgstr ""
+
+msgid "AdminArea|Included Free in license"
+msgstr ""
+
+msgid "AdminArea|Maintainer"
+msgstr ""
+
+msgid "AdminArea|Owner"
+msgstr ""
+
+msgid "AdminArea|Reporter"
+msgstr ""
+
+msgid "AdminArea|Stop all jobs"
+msgstr ""
+
+msgid "AdminArea|Stop all jobs?"
+msgstr ""
+
+msgid "AdminArea|Stop jobs"
+msgstr ""
+
+msgid "AdminArea|Stopping jobs failed"
+msgstr ""
+
+msgid "AdminArea|Total users"
+msgstr ""
+
+msgid "AdminArea|Users statistics"
+msgstr ""
+
+msgid "AdminArea|Users with highest role"
+msgstr ""
+
+msgid "AdminArea|Users without a Group and Project"
+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 "AdminNote|Note"
+msgstr ""
+
+msgid "AdminProjects| You’re about to permanently delete the project %{projectName}, its repository, and all related resources including issues, merge requests, etc.. Once you confirm and press %{strong_start}Delete project%{strong_end}, it cannot be undone or recovered."
+msgstr ""
+
+msgid "AdminProjects|Delete"
+msgstr ""
+
+msgid "AdminProjects|Delete Project %{projectName}?"
+msgstr ""
+
+msgid "AdminProjects|Delete project"
+msgstr ""
+
+msgid "AdminSettings|Apply integration settings to all Projects"
+msgstr ""
+
+msgid "AdminSettings|Auto DevOps domain"
+msgstr ""
+
+msgid "AdminSettings|Elasticsearch, PlantUML, Slack application, Third party offers, Snowplow, Amazon EKS have moved to Settings > General."
+msgstr ""
+
+msgid "AdminSettings|Enable shared runners for new projects"
+msgstr ""
+
+msgid "AdminSettings|Environment variables are protected by default"
+msgstr ""
+
+msgid "AdminSettings|Go to General Settings"
+msgstr ""
+
+msgid "AdminSettings|Integrations configured here will automatically apply to all projects on this instance."
+msgstr ""
+
+msgid "AdminSettings|No required pipeline"
+msgstr ""
+
+msgid "AdminSettings|Required pipeline configuration"
+msgstr ""
+
+msgid "AdminSettings|Select a pipeline configuration file"
+msgstr ""
+
+msgid "AdminSettings|Select a template"
+msgstr ""
+
+msgid "AdminSettings|Service template allows you to set default values for integrations"
+msgstr ""
+
+msgid "AdminSettings|Set an instance-wide auto included %{link_start}pipeline configuration%{link_end}. This pipeline configuration will be run after the project's own configuration."
+msgstr ""
+
+msgid "AdminSettings|Some settings have moved"
+msgstr ""
+
+msgid "AdminSettings|Specify a domain to use by default for every project's Auto Review Apps and Auto Deploy stages."
+msgstr ""
+
+msgid "AdminSettings|The required pipeline configuration can be selected from the %{code_start}gitlab-ci%{code_end} directory inside of the configured %{link_start}instance template repository%{link_end} or from GitLab provided configurations."
+msgstr ""
+
+msgid "AdminSettings|When creating a new environment variable it will be protected by default."
+msgstr ""
+
+msgid "AdminStatistics|Active Users"
+msgstr ""
+
+msgid "AdminStatistics|Forks"
+msgstr ""
+
+msgid "AdminStatistics|Issues"
+msgstr ""
+
+msgid "AdminStatistics|Merge Requests"
+msgstr ""
+
+msgid "AdminStatistics|Milestones"
+msgstr ""
+
+msgid "AdminStatistics|Notes"
+msgstr ""
+
+msgid "AdminStatistics|SSH Keys"
+msgstr ""
+
+msgid "AdminStatistics|Snippets"
+msgstr ""
+
+msgid "AdminUsers|2FA Disabled"
+msgstr ""
+
+msgid "AdminUsers|2FA Enabled"
+msgstr ""
+
+msgid "AdminUsers|Active"
+msgstr ""
+
+msgid "AdminUsers|Admin"
+msgstr ""
+
+msgid "AdminUsers|Admins"
+msgstr ""
+
+msgid "AdminUsers|Block"
+msgstr ""
+
+msgid "AdminUsers|Block user"
+msgstr ""
+
+msgid "AdminUsers|Block user %{username}?"
+msgstr ""
+
+msgid "AdminUsers|Blocked"
+msgstr ""
+
+msgid "AdminUsers|Blocking user has the following effects:"
+msgstr ""
+
+msgid "AdminUsers|Cannot unblock LDAP blocked users"
+msgstr ""
+
+msgid "AdminUsers|Deactivate"
+msgstr ""
+
+msgid "AdminUsers|Deactivate User %{username}?"
+msgstr ""
+
+msgid "AdminUsers|Deactivate user"
+msgstr ""
+
+msgid "AdminUsers|Deactivated"
+msgstr ""
+
+msgid "AdminUsers|Deactivating a user has the following effects:"
+msgstr ""
+
+msgid "AdminUsers|Delete User %{username} and contributions?"
+msgstr ""
+
+msgid "AdminUsers|Delete User %{username}?"
+msgstr ""
+
+msgid "AdminUsers|Delete user"
+msgstr ""
+
+msgid "AdminUsers|Delete user and contributions"
+msgstr ""
+
+msgid "AdminUsers|External"
+msgstr ""
+
+msgid "AdminUsers|Is using seat"
+msgstr ""
+
+msgid "AdminUsers|It's you!"
+msgstr ""
+
+msgid "AdminUsers|New user"
+msgstr ""
+
+msgid "AdminUsers|No users found"
+msgstr ""
+
+msgid "AdminUsers|Owned groups will be left"
+msgstr ""
+
+msgid "AdminUsers|Personal projects will be left"
+msgstr ""
+
+msgid "AdminUsers|Personal projects, group and user history will be left intact"
+msgstr ""
+
+msgid "AdminUsers|Reactivating a user will:"
+msgstr ""
+
+msgid "AdminUsers|Restore user access to the account, including web, Git and API."
+msgstr ""
+
+msgid "AdminUsers|Search by name, email or username"
+msgstr ""
+
+msgid "AdminUsers|Search users"
+msgstr ""
+
+msgid "AdminUsers|Send email to users"
+msgstr ""
+
+msgid "AdminUsers|Sort by"
+msgstr ""
+
+msgid "AdminUsers|The user will be logged out"
+msgstr ""
+
+msgid "AdminUsers|The user will not be able to access git repositories"
+msgstr ""
+
+msgid "AdminUsers|The user will not be able to access the API"
+msgstr ""
+
+msgid "AdminUsers|The user will not be able to use slash commands"
+msgstr ""
+
+msgid "AdminUsers|The user will not receive any notifications"
+msgstr ""
+
+msgid "AdminUsers|To confirm, type %{projectName}"
+msgstr ""
+
+msgid "AdminUsers|To confirm, type %{username}"
+msgstr ""
+
+msgid "AdminUsers|User will not be able to access git repositories"
+msgstr ""
+
+msgid "AdminUsers|User will not be able to login"
+msgstr ""
+
+msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
+msgstr ""
+
+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 %{strong_start}block user%{strong_end} feature instead. Once you %{strong_start}Delete user%{strong_end}, it cannot be undone or recovered."
+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 %{strong_start}block user%{strong_end} feature instead. Once you %{strong_start}Delete user%{strong_end}, it cannot be undone or recovered."
+msgstr ""
+
+msgid "Administration"
+msgstr ""
+
+msgid "Advanced"
+msgstr ""
+
+msgid "Advanced Settings"
+msgstr ""
+
+msgid "Advanced permissions, Large File Storage and Two-Factor authentication settings."
+msgstr ""
+
+msgid "Advanced search functionality"
+msgstr ""
+
+msgid "After a successful password update you will be redirected to login screen."
+msgstr ""
+
+msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
+msgid "Alert"
+msgid_plural "Alerts"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "AlertManagement|Acknowledged"
+msgstr ""
+
+msgid "AlertManagement|Alert"
+msgstr ""
+
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
+msgid "AlertManagement|Authorize external service"
+msgstr ""
+
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
+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 ""
+
+msgid "AlertManagement|End time"
+msgstr ""
+
+msgid "AlertManagement|Events"
+msgstr ""
+
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
+msgstr ""
+
+msgid "AlertManagement|Medium"
+msgstr ""
+
+msgid "AlertManagement|More information"
+msgstr ""
+
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
+msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
+msgstr ""
+
+msgid "AlertManagement|No alerts to display."
+msgstr ""
+
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
+msgid "AlertManagement|Overview"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
+msgid "AlertManagement|Resolved"
+msgstr ""
+
+msgid "AlertManagement|Service"
+msgstr ""
+
+msgid "AlertManagement|Severity"
+msgstr ""
+
+msgid "AlertManagement|Start time"
+msgstr ""
+
+msgid "AlertManagement|Status"
+msgstr ""
+
+msgid "AlertManagement|Surface alerts in GitLab"
+msgstr ""
+
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
+msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
+msgstr ""
+
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
+msgid "AlertManagement|Triggered"
+msgstr ""
+
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
+msgstr ""
+
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
+msgstr ""
+
+msgid "Alerts"
+msgstr ""
+
+msgid "Alerts endpoint"
+msgstr ""
+
+msgid "Algorithm"
+msgstr ""
+
+msgid "All"
+msgstr ""
+
+msgid "All %{replicableType} are being scheduled for %{action}"
+msgstr ""
+
+msgid "All (default)"
+msgstr ""
+
+msgid "All Members"
+msgstr ""
+
+msgid "All branches"
+msgstr ""
+
+msgid "All changes are committed"
+msgstr ""
+
+msgid "All default stages are currently visible"
+msgstr ""
+
+msgid "All email addresses will be used to identify your commits."
+msgstr ""
+
+msgid "All environments"
+msgstr ""
+
+msgid "All features are enabled for blank projects, from templates, or when importing, but you can disable them afterward in the project settings."
+msgstr ""
+
+msgid "All groups and projects"
+msgstr ""
+
+msgid "All issues for this milestone are closed."
+msgstr ""
+
+msgid "All issues for this milestone are closed. You may close this milestone now."
+msgstr ""
+
+msgid "All merge conflicts were resolved. The merge request can now be merged."
+msgstr ""
+
+msgid "All merge request dependencies have been merged"
+msgstr ""
+
+msgid "All paths are relative to the GitLab URL. Do not include %{relative_url_link_start}relative URL%{relative_url_link_end}."
+msgstr ""
+
+msgid "All projects"
+msgstr ""
+
+msgid "All security scans are enabled because %{linkStart}Auto DevOps%{linkEnd} is enabled on this project"
+msgstr ""
+
+msgid "All threads resolved"
+msgstr ""
+
+msgid "All users"
+msgstr ""
+
+msgid "All users must have a name."
+msgstr ""
+
+msgid "Allow \"%{group_name}\" to sign you in"
+msgstr ""
+
+msgid "Allow commits from members who can merge to the target branch."
+msgstr ""
+
+msgid "Allow group owners to manage LDAP-related settings"
+msgstr ""
+
+msgid "Allow only the selected protocols to be used for Git access."
+msgstr ""
+
+msgid "Allow owners to manage default branch protection per group"
+msgstr ""
+
+msgid "Allow owners to manually add users outside of LDAP"
+msgstr ""
+
+msgid "Allow projects within this group to use Git LFS"
+msgstr ""
+
+msgid "Allow public access to pipelines and job details, including output logs and artifacts"
+msgstr ""
+
+msgid "Allow rendering of PlantUML diagrams in Asciidoc documents."
+msgstr ""
+
+msgid "Allow repository mirroring to be configured by project maintainers"
+msgstr ""
+
+msgid "Allow requests to the local network from hooks and services."
+msgstr ""
+
+msgid "Allow requests to the local network from system hooks"
+msgstr ""
+
+msgid "Allow requests to the local network from web hooks and services"
+msgstr ""
+
+msgid "Allow this key to push to repository as well? (Default only allows pull access.)"
+msgstr ""
+
+msgid "Allow this secondary node to replicate content on Object Storage"
+msgstr ""
+
+msgid "Allow users to dismiss the broadcast message"
+msgstr ""
+
+msgid "Allow users to register any application to use GitLab as an OAuth provider"
+msgstr ""
+
+msgid "Allow users to request access (if visibility is public or internal)"
+msgstr ""
+
+msgid "Allowed email domain restriction only permitted for top-level groups"
+msgstr ""
+
+msgid "Allowed to fail"
+msgstr ""
+
+msgid "Allows you to add and manage Kubernetes clusters."
+msgstr ""
+
+msgid "Almost there"
+msgstr ""
+
+msgid "Also called \"Issuer\" or \"Relying party trust identifier\""
+msgstr ""
+
+msgid "Also called \"Relying party service URL\" or \"Reply URL\""
+msgstr ""
+
+msgid "Alternate support URL for help page and help dropdown"
+msgstr ""
+
+msgid "Alternatively, you can convert your account to a managed account by the %{group_name} group."
+msgstr ""
+
+msgid "Amazon EKS"
+msgstr ""
+
+msgid "Amazon EKS integration allows you to provision EKS clusters from GitLab."
+msgstr ""
+
+msgid "Amazon Web Services"
+msgstr ""
+
+msgid "Amazon authentication is not %{link_start}correctly configured%{link_end}. Ask your GitLab administrator if you want to use this service."
+msgstr ""
+
+msgid "Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication"
+msgstr ""
+
+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 ""
+
+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 ""
+
+msgid "An error has occurred"
+msgstr ""
+
+msgid "An error occurred adding a draft to the thread."
+msgstr ""
+
+msgid "An error occurred adding a new draft."
+msgstr ""
+
+msgid "An error occurred creating the new branch."
+msgstr ""
+
+msgid "An error occurred fetching the approval rules."
+msgstr ""
+
+msgid "An error occurred fetching the approvers for the new rule."
+msgstr ""
+
+msgid "An error occurred fetching the dropdown data."
+msgstr ""
+
+msgid "An error occurred fetching the project authors."
+msgstr ""
+
+msgid "An error occurred previewing the blob"
+msgstr ""
+
+msgid "An error occurred when toggling the notification subscription"
+msgstr ""
+
+msgid "An error occurred when trying to resolve a comment. Please try again."
+msgstr ""
+
+msgid "An error occurred when trying to resolve a discussion. Please try again."
+msgstr ""
+
+msgid "An error occurred when updating the issue weight"
+msgstr ""
+
+msgid "An error occurred while adding formatted title for epic"
+msgstr ""
+
+msgid "An error occurred while checking group path"
+msgstr ""
+
+msgid "An error occurred while committing your changes."
+msgstr ""
+
+msgid "An error occurred while decoding the file."
+msgstr ""
+
+msgid "An error occurred while deleting the approvers group"
+msgstr ""
+
+msgid "An error occurred while deleting the comment"
+msgstr ""
+
+msgid "An error occurred while deleting the pipeline."
+msgstr ""
+
+msgid "An error occurred while detecting host keys"
+msgstr ""
+
+msgid "An error occurred while disabling Service Desk."
+msgstr ""
+
+msgid "An error occurred while dismissing the alert. Refresh the page and try again."
+msgstr ""
+
+msgid "An error occurred while dismissing the feature highlight. Refresh the page and try dismissing again."
+msgstr ""
+
+msgid "An error occurred while enabling Service Desk."
+msgstr ""
+
+msgid "An error occurred while fetching coverage reports."
+msgstr ""
+
+msgid "An error occurred while fetching environments."
+msgstr ""
+
+msgid "An error occurred while fetching exposed artifacts."
+msgstr ""
+
+msgid "An error occurred while fetching folder content."
+msgstr ""
+
+msgid "An error occurred while fetching issues."
+msgstr ""
+
+msgid "An error occurred while fetching label colors."
+msgstr ""
+
+msgid "An error occurred while fetching markdown preview"
+msgstr ""
+
+msgid "An error occurred while fetching pending comments"
+msgstr ""
+
+msgid "An error occurred while fetching projects autocomplete."
+msgstr ""
+
+msgid "An error occurred while fetching sidebar data"
+msgstr ""
+
+msgid "An error occurred while fetching terraform reports."
+msgstr ""
+
+msgid "An error occurred while fetching the Service Desk address."
+msgstr ""
+
+msgid "An error occurred while fetching the board lists. Please try again."
+msgstr ""
+
+msgid "An error occurred while fetching the builds."
+msgstr ""
+
+msgid "An error occurred while fetching the job log."
+msgstr ""
+
+msgid "An error occurred while fetching the job trace."
+msgstr ""
+
+msgid "An error occurred while fetching the job."
+msgstr ""
+
+msgid "An error occurred while fetching the jobs."
+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 ""
+
+msgid "An error occurred while fetching this tab."
+msgstr ""
+
+msgid "An error occurred while generating a username. Please try again."
+msgstr ""
+
+msgid "An error occurred while getting files for - %{branchId}"
+msgstr ""
+
+msgid "An error occurred while getting projects"
+msgstr ""
+
+msgid "An error occurred while importing project: %{details}"
+msgstr ""
+
+msgid "An error occurred while initializing path locks"
+msgstr ""
+
+msgid "An error occurred while loading all the files."
+msgstr ""
+
+msgid "An error occurred while loading chart data"
+msgstr ""
+
+msgid "An error occurred while loading commit signatures"
+msgstr ""
+
+msgid "An error occurred while loading designs. Please try again."
+msgstr ""
+
+msgid "An error occurred while loading diff"
+msgstr ""
+
+msgid "An error occurred while loading filenames"
+msgstr ""
+
+msgid "An error occurred while loading group members."
+msgstr ""
+
+msgid "An error occurred while loading issues"
+msgstr ""
+
+msgid "An error occurred while loading merge requests."
+msgstr ""
+
+msgid "An error occurred while loading milestones"
+msgstr ""
+
+msgid "An error occurred while loading terraform report"
+msgstr ""
+
+msgid "An error occurred while loading the data. Please try again."
+msgstr ""
+
+msgid "An error occurred while loading the file"
+msgstr ""
+
+msgid "An error occurred while loading the file content."
+msgstr ""
+
+msgid "An error occurred while loading the file."
+msgstr ""
+
+msgid "An error occurred while loading the file. Please try again later."
+msgstr ""
+
+msgid "An error occurred while loading the merge request changes."
+msgstr ""
+
+msgid "An error occurred while loading the merge request version data."
+msgstr ""
+
+msgid "An error occurred while loading the merge request."
+msgstr ""
+
+msgid "An error occurred while loading the pipelines jobs."
+msgstr ""
+
+msgid "An error occurred while loading the subscription details."
+msgstr ""
+
+msgid "An error occurred while making the request."
+msgstr ""
+
+msgid "An error occurred while moving the issue."
+msgstr ""
+
+msgid "An error occurred while parsing recent searches"
+msgstr ""
+
+msgid "An error occurred while parsing the file."
+msgstr ""
+
+msgid "An error occurred while removing epics."
+msgstr ""
+
+msgid "An error occurred while removing issues."
+msgstr ""
+
+msgid "An error occurred while rendering preview broadcast message"
+msgstr ""
+
+msgid "An error occurred while reordering issues."
+msgstr ""
+
+msgid "An error occurred while retrieving calendar activity"
+msgstr ""
+
+msgid "An error occurred while retrieving diff"
+msgstr ""
+
+msgid "An error occurred while saving LDAP override status. Please try again."
+msgstr ""
+
+msgid "An error occurred while saving assignees"
+msgstr ""
+
+msgid "An error occurred while saving the approval settings"
+msgstr ""
+
+msgid "An error occurred while saving the template. Please check if the template exists."
+msgstr ""
+
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
+msgid "An error occurred while subscribing to notifications."
+msgstr ""
+
+msgid "An error occurred while triggering the job."
+msgstr ""
+
+msgid "An error occurred while trying to run a new pipeline for this Merge Request."
+msgstr ""
+
+msgid "An error occurred while unsubscribing to notifications."
+msgstr ""
+
+msgid "An error occurred while updating approvers"
+msgstr ""
+
+msgid "An error occurred while updating the comment"
+msgstr ""
+
+msgid "An error occurred while validating group path"
+msgstr ""
+
+msgid "An error occurred while validating username"
+msgstr ""
+
+msgid "An error occurred. Please try again."
+msgstr ""
+
+msgid "An error ocurred while loading your content. Please try again."
+msgstr ""
+
+msgid "An example project for managing Kubernetes clusters integrated with GitLab."
+msgstr ""
+
+msgid "An instance-level serverless domain already exists."
+msgstr ""
+
+msgid "An issue already exists"
+msgstr ""
+
+msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
+msgstr ""
+
+msgid "An unauthenticated user"
+msgstr ""
+
+msgid "An unexpected error occurred while checking the project environment."
+msgstr ""
+
+msgid "An unexpected error occurred while checking the project runners."
+msgstr ""
+
+msgid "An unexpected error occurred while communicating with the Web Terminal."
+msgstr ""
+
+msgid "An unexpected error occurred while starting the Web Terminal."
+msgstr ""
+
+msgid "An unexpected error occurred while stopping the Web Terminal."
+msgstr ""
+
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
+msgid "Analytics"
+msgstr ""
+
+msgid "Analyze a review version of your web application."
+msgstr ""
+
+msgid "Analyze your dependencies for known vulnerabilities."
+msgstr ""
+
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
+msgid "Analyze your source code for known vulnerabilities."
+msgstr ""
+
+msgid "Ancestors"
+msgstr ""
+
+msgid "Anonymous"
+msgstr ""
+
+msgid "Another action is currently in progress"
+msgstr ""
+
+msgid "Another issue tracker is already in use. Only one issue tracker service can be active at a time"
+msgstr ""
+
+msgid "Anti-spam verification"
+msgstr ""
+
+msgid "Any"
+msgstr ""
+
+msgid "Any Author"
+msgstr ""
+
+msgid "Any branch"
+msgstr ""
+
+msgid "Any eligible user"
+msgstr ""
+
+msgid "Any encrypted tokens"
+msgstr ""
+
+msgid "Any label"
+msgstr ""
+
+msgid "Any member with Developer or higher permissions to the project."
+msgstr ""
+
+msgid "Any milestone"
+msgstr ""
+
+msgid "Any namespace"
+msgstr ""
+
+msgid "Any user"
+msgstr ""
+
+msgid "App ID"
+msgstr ""
+
+msgid "Appearance"
+msgstr ""
+
+msgid "Appearance was successfully created."
+msgstr ""
+
+msgid "Appearance was successfully updated."
+msgstr ""
+
+msgid "Append the comment with %{shrug}"
+msgstr ""
+
+msgid "Append the comment with %{tableflip}"
+msgstr ""
+
+msgid "Application"
+msgstr ""
+
+msgid "Application ID"
+msgstr ""
+
+msgid "Application settings saved successfully"
+msgstr ""
+
+msgid "Application settings update failed"
+msgstr ""
+
+msgid "Application uninstalled but failed to destroy: %{error_message}"
+msgstr ""
+
+msgid "Application was successfully destroyed."
+msgstr ""
+
+msgid "Application was successfully updated."
+msgstr ""
+
+msgid "Application: %{name}"
+msgstr ""
+
+msgid "Applications"
+msgstr ""
+
+msgid "Applied"
+msgstr ""
+
+msgid "Apply"
+msgstr ""
+
+msgid "Apply a label"
+msgstr ""
+
+msgid "Apply a template"
+msgstr ""
+
+msgid "Apply changes"
+msgstr ""
+
+msgid "Apply suggestion"
+msgstr ""
+
+msgid "Apply template"
+msgstr ""
+
+msgid "Apply this approval rule to any branch or a specific protected branch."
+msgstr ""
+
+msgid "Applying a template will replace the existing issue description. Any changes you have made will be lost."
+msgstr ""
+
+msgid "Applying command"
+msgstr ""
+
+msgid "Applying command to %{commandDescription}"
+msgstr ""
+
+msgid "Applying multiple commands"
+msgstr ""
+
+msgid "Applying suggestion"
+msgstr ""
+
+msgid "Approval rules"
+msgstr ""
+
+msgid "ApprovalRuleRemove|%d member"
+msgid_plural "ApprovalRuleRemove|%d members"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ApprovalRuleRemove|Approvals from this member are not revoked."
+msgid_plural "ApprovalRuleRemove|Approvals from these members are not revoked."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ApprovalRuleRemove|You are about to remove the %{name} approver group which has %{nMembers}."
+msgstr ""
+
+msgid "ApprovalRuleSummary|%d member"
+msgid_plural "ApprovalRuleSummary|%d members"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ApprovalRuleSummary|%{count} approval required from %{membersCount}"
+msgid_plural "ApprovalRuleSummary|%{count} approvals required from %{membersCount}"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ApprovalRule|Approvers"
+msgstr ""
+
+msgid "ApprovalRule|Name"
+msgstr ""
+
+msgid "ApprovalRule|No. approvals required"
+msgstr ""
+
+msgid "ApprovalRule|Rule name"
+msgstr ""
+
+msgid "ApprovalRule|Target branch"
+msgstr ""
+
+msgid "ApprovalRule|e.g. QA, Security, etc."
+msgstr ""
+
+msgid "Approve"
+msgstr ""
+
+msgid "Approve a merge request"
+msgstr ""
+
+msgid "Approve the current merge request."
+msgstr ""
+
+msgid "Approved"
+msgstr ""
+
+msgid "Approved by: "
+msgstr ""
+
+msgid "Approved the current merge request."
+msgstr ""
+
+msgid "Approved-By"
+msgstr ""
+
+msgid "Approver"
+msgstr ""
+
+msgid "Approvers"
+msgstr ""
+
+msgid "Apr"
+msgstr ""
+
+msgid "April"
+msgstr ""
+
+msgid "Archive"
+msgstr ""
+
+msgid "Archive jobs"
+msgstr ""
+
+msgid "Archive project"
+msgstr ""
+
+msgid "Archived"
+msgstr ""
+
+msgid "Archived project! Repository and other project resources are read only"
+msgstr ""
+
+msgid "Archived project! Repository and other project resources are read-only"
+msgstr ""
+
+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}"
+msgstr ""
+
+msgid "Are you setting up GitLab for a company?"
+msgstr ""
+
+msgid "Are you sure that you want to archive this project?"
+msgstr ""
+
+msgid "Are you sure that you want to unarchive this project?"
+msgstr ""
+
+msgid "Are you sure you want to cancel editing this comment?"
+msgstr ""
+
+msgid "Are you sure you want to close this blocked issue?"
+msgstr ""
+
+msgid "Are you sure you want to delete %{name}?"
+msgstr ""
+
+msgid "Are you sure you want to delete these artifacts?"
+msgstr ""
+
+msgid "Are you sure you want to delete this %{typeOfComment}?"
+msgstr ""
+
+msgid "Are you sure you want to delete this board?"
+msgstr ""
+
+msgid "Are you sure you want to delete this device? This action cannot be undone."
+msgstr ""
+
+msgid "Are you sure you want to delete this list?"
+msgstr ""
+
+msgid "Are you sure you want to delete this pipeline schedule?"
+msgstr ""
+
+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 ""
+
+msgid "Are you sure you want to deploy this environment?"
+msgstr ""
+
+msgid "Are you sure you want to discard this comment?"
+msgstr ""
+
+msgid "Are you sure you want to erase this build?"
+msgstr ""
+
+msgid "Are you sure you want to lose unsaved changes?"
+msgstr ""
+
+msgid "Are you sure you want to lose your issue information?"
+msgstr ""
+
+msgid "Are you sure you want to merge immediately?"
+msgstr ""
+
+msgid "Are you sure you want to permanently delete this license?"
+msgstr ""
+
+msgid "Are you sure you want to re-deploy this environment?"
+msgstr ""
+
+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 ""
+
+msgid "Are you sure you want to remove %{group_name}?"
+msgstr ""
+
+msgid "Are you sure you want to remove the attachment?"
+msgstr ""
+
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
+msgid "Are you sure you want to remove this identity?"
+msgstr ""
+
+msgid "Are you sure you want to reset registration token?"
+msgstr ""
+
+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 ""
+
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
+msgstr ""
+
+msgid "Are you sure you want to revoke this nickname?"
+msgstr ""
+
+msgid "Are you sure you want to stop this environment?"
+msgstr ""
+
+msgid "Are you sure you want to unlock %{path_lock_path}?"
+msgstr ""
+
+msgid "Are you sure you want to unsubscribe from the %{type}: %{link_to_noteable_text}?"
+msgstr ""
+
+msgid "Are you sure?"
+msgstr ""
+
+msgid "Are you sure? All commits that were signed with this GPG key will be unverified."
+msgstr ""
+
+msgid "Are you sure? Removing this GPG key does not affect already signed commits."
+msgstr ""
+
+msgid "Are you sure? The device will be signed out of GitLab."
+msgstr ""
+
+msgid "Are you sure? This will invalidate your registered applications and U2F devices."
+msgstr ""
+
+msgid "Arrange charts"
+msgstr ""
+
+msgid "Artifact"
+msgstr ""
+
+msgid "Artifact ID"
+msgstr ""
+
+msgid "Artifact could not be deleted."
+msgstr ""
+
+msgid "Artifact was successfully deleted."
+msgstr ""
+
+msgid "Artifacts"
+msgstr ""
+
+msgid "As U2F devices are only supported by a few browsers, we require that you set up a two-factor authentication app before a U2F device. That way you'll always be able to log in - even when you're using an unsupported browser."
+msgstr ""
+
+msgid "AsanaService|%{user} pushed to branch %{branch} of %{project_name} ( %{commit_url} ):"
+msgstr ""
+
+msgid "AsanaService|Asana - Teamwork without email"
+msgstr ""
+
+msgid "AsanaService|Comma-separated list of branches which will be automatically inspected. Leave blank to include all branches."
+msgstr ""
+
+msgid "AsanaService|User Personal Access Token. User must have access to task, all comments will be attributed to this user."
+msgstr ""
+
+msgid "Ascending"
+msgstr ""
+
+msgid "Ask your group maintainer to set up a group Runner."
+msgstr ""
+
+msgid "Assertion consumer service URL"
+msgstr ""
+
+msgid "Assets"
+msgstr ""
+
+msgid "Assets:"
+msgstr ""
+
+msgid "Assign"
+msgstr ""
+
+msgid "Assign custom color like #FF0000"
+msgstr ""
+
+msgid "Assign epic"
+msgstr ""
+
+msgid "Assign labels"
+msgstr ""
+
+msgid "Assign milestone"
+msgstr ""
+
+msgid "Assign some issues to this milestone."
+msgstr ""
+
+msgid "Assign to"
+msgstr ""
+
+msgid "Assign yourself to these issues"
+msgstr ""
+
+msgid "Assign yourself to this issue"
+msgstr ""
+
+msgid "Assigned %{assignee_users_sentence}."
+msgstr ""
+
+msgid "Assigned Issues"
+msgstr ""
+
+msgid "Assigned Merge Requests"
+msgstr ""
+
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
+msgid "Assigned to me"
+msgstr ""
+
+msgid "Assignee"
+msgid_plural "%d Assignees"
+msgstr[0] ""
+msgstr[1] ""
+
+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 ""
+
+msgid "Assigns %{assignee_users_sentence}."
+msgstr ""
+
+msgid "At least one approval from a code owner is required to change files matching the respective CODEOWNER rules."
+msgstr ""
+
+msgid "At least one logging option is required to be enabled"
+msgstr ""
+
+msgid "At least one of group_id or project_id must be specified"
+msgstr ""
+
+msgid "At risk"
+msgstr ""
+
+msgid "Attach a file"
+msgstr ""
+
+msgid "Attach a file by drag &amp; drop or %{upload_link}"
+msgstr ""
+
+msgid "Attaching a file"
+msgid_plural "Attaching %d files"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Attaching the file failed."
+msgstr ""
+
+msgid "Audit Events"
+msgstr ""
+
+msgid "Audit Events is a way to keep track of important events that happened in GitLab."
+msgstr ""
+
+msgid "AuditEvents|(removed)"
+msgstr ""
+
+msgid "AuditEvents|Action"
+msgstr ""
+
+msgid "AuditEvents|At"
+msgstr ""
+
+msgid "AuditEvents|Target"
+msgstr ""
+
+msgid "AuditLogs|(removed)"
+msgstr ""
+
+msgid "AuditLogs|Action"
+msgstr ""
+
+msgid "AuditLogs|Author"
+msgstr ""
+
+msgid "AuditLogs|Date"
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
+msgid "AuditLogs|IP Address"
+msgstr ""
+
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
+msgid "AuditLogs|Object"
+msgstr ""
+
+msgid "AuditLogs|Project Events"
+msgstr ""
+
+msgid "AuditLogs|Target"
+msgstr ""
+
+msgid "AuditLogs|User Events"
+msgstr ""
+
+msgid "Aug"
+msgstr ""
+
+msgid "August"
+msgstr ""
+
+msgid "Authenticate"
+msgstr ""
+
+msgid "Authenticate with GitHub"
+msgstr ""
+
+msgid "Authenticating"
+msgstr ""
+
+msgid "Authentication Failure"
+msgstr ""
+
+msgid "Authentication Log"
+msgstr ""
+
+msgid "Authentication failed: %{error_message}"
+msgstr ""
+
+msgid "Authentication log"
+msgstr ""
+
+msgid "Authentication method"
+msgstr ""
+
+msgid "Authentication method updated"
+msgstr ""
+
+msgid "Authentication via U2F device failed."
+msgstr ""
+
+msgid "Author"
+msgstr ""
+
+msgid "Authored %{timeago} by %{author}"
+msgstr ""
+
+msgid "Authorization code:"
+msgstr ""
+
+msgid "Authorization key"
+msgstr ""
+
+msgid "Authorization was granted by entering your username and password in the application."
+msgstr ""
+
+msgid "Authorize"
+msgstr ""
+
+msgid "Authorize %{link_to_client} to use your account?"
+msgstr ""
+
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
+msgid "Authorized %{new_chat_name}"
+msgstr ""
+
+msgid "Authorized At"
+msgstr ""
+
+msgid "Authorized applications (%{size})"
+msgstr ""
+
+msgid "Authors: %{authors}"
+msgstr ""
+
+msgid "Auto DevOps"
+msgstr ""
+
+msgid "Auto DevOps enabled"
+msgstr ""
+
+msgid "Auto DevOps, runners and job artifacts"
+msgstr ""
+
+msgid "Auto stop successfully canceled."
+msgstr ""
+
+msgid "Auto-cancel redundant, pending pipelines"
+msgstr ""
+
+msgid "Auto-close referenced issues on default branch"
+msgstr ""
+
+msgid "AutoDevOps|Auto DevOps"
+msgstr ""
+
+msgid "AutoDevOps|Auto DevOps can automatically build, test, and deploy applications based on predefined continuous integration and delivery configuration. %{auto_devops_start}Learn more about Auto DevOps%{auto_devops_end} or use our %{quickstart_start}quick start guide%{quickstart_end} to get started right away."
+msgstr ""
+
+msgid "AutoDevOps|Auto DevOps documentation"
+msgstr ""
+
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
+msgid "AutoDevOps|Enable in settings"
+msgstr ""
+
+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 ""
+
+msgid "AutoDevOps|The Auto DevOps pipeline has been enabled and will be used if no alternative CI configuration file is found. %{more_information_link}"
+msgstr ""
+
+msgid "Autocomplete"
+msgstr ""
+
+msgid "Autocomplete description"
+msgstr ""
+
+msgid "Autocomplete hint"
+msgstr ""
+
+msgid "Autocomplete usage hint"
+msgstr ""
+
+msgid "Automatic certificate management using %{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end}"
+msgstr ""
+
+msgid "Automatic certificate management using Let's Encrypt"
+msgstr ""
+
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
+msgid "Automatically marked as default internal user"
+msgstr ""
+
+msgid "Automatically resolved"
+msgstr ""
+
+msgid "Automatically update this project's branches and tags from the upstream repository every hour."
+msgstr ""
+
+msgid "Autosave|Note"
+msgstr ""
+
+msgid "Available"
+msgstr ""
+
+msgid "Available for dependency and container scanning"
+msgstr ""
+
+msgid "Available group Runners: %{runners}"
+msgstr ""
+
+msgid "Available shared Runners:"
+msgstr ""
+
+msgid "Available specific runners"
+msgstr ""
+
+msgid "Avatar for %{assigneeName}"
+msgstr ""
+
+msgid "Avatar for %{name}"
+msgstr ""
+
+msgid "Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Average per day: %{average}"
+msgstr ""
+
+msgid "Back to page %{number}"
+msgstr ""
+
+msgid "Background Color"
+msgstr ""
+
+msgid "Background Jobs"
+msgstr ""
+
+msgid "Background color"
+msgstr ""
+
+msgid "Badges"
+msgstr ""
+
+msgid "Badges|A new badge was added."
+msgstr ""
+
+msgid "Badges|Add badge"
+msgstr ""
+
+msgid "Badges|Adding the badge failed, please check the entered URLs and try again."
+msgstr ""
+
+msgid "Badges|Badge image URL"
+msgstr ""
+
+msgid "Badges|Badge image preview"
+msgstr ""
+
+msgid "Badges|Delete badge"
+msgstr ""
+
+msgid "Badges|Delete badge?"
+msgstr ""
+
+msgid "Badges|Deleting the badge failed, please try again."
+msgstr ""
+
+msgid "Badges|Group Badge"
+msgstr ""
+
+msgid "Badges|Link"
+msgstr ""
+
+msgid "Badges|Name"
+msgstr ""
+
+msgid "Badges|No badge image"
+msgstr ""
+
+msgid "Badges|No image to preview"
+msgstr ""
+
+msgid "Badges|Please fill in a valid URL"
+msgstr ""
+
+msgid "Badges|Project Badge"
+msgstr ""
+
+msgid "Badges|Reload badge image"
+msgstr ""
+
+msgid "Badges|Save changes"
+msgstr ""
+
+msgid "Badges|Saving the badge failed, please check the entered URLs and try again."
+msgstr ""
+
+msgid "Badges|The %{docsLinkStart}variables%{docsLinkEnd} GitLab supports: %{placeholders}"
+msgstr ""
+
+msgid "Badges|The badge was deleted."
+msgstr ""
+
+msgid "Badges|The badge was saved."
+msgstr ""
+
+msgid "Badges|This group has no badges"
+msgstr ""
+
+msgid "Badges|This project has no badges"
+msgstr ""
+
+msgid "Badges|You are going to delete this badge. Deleted badges <strong>cannot</strong> be restored."
+msgstr ""
+
+msgid "Badges|Your badges"
+msgstr ""
+
+msgid "Badges|e.g. %{exampleUrl}"
+msgstr ""
+
+msgid "Badge|New"
+msgstr ""
+
+msgid "Balsamiq file could not be loaded."
+msgstr ""
+
+msgid "BambooService|A continuous integration and build server"
+msgstr ""
+
+msgid "BambooService|A user with API access, if applicable"
+msgstr ""
+
+msgid "BambooService|Atlassian Bamboo CI"
+msgstr ""
+
+msgid "BambooService|Bamboo build plan key like KEY"
+msgstr ""
+
+msgid "BambooService|Bamboo root URL like https://bamboo.example.com"
+msgstr ""
+
+msgid "BambooService|You must set up automatic revision labeling and a repository trigger in Bamboo."
+msgstr ""
+
+msgid "BatchComments|Delete all pending comments"
+msgstr ""
+
+msgid "BatchComments|Discard review?"
+msgstr ""
+
+msgid "BatchComments|You're about to discard your review which will delete all of your pending comments. The deleted comments %{strong_start}cannot%{strong_end} be restored."
+msgstr ""
+
+msgid "Be careful. Changing the project's namespace can have unintended side effects."
+msgstr ""
+
+msgid "Be careful. Renaming a project's repository can have unintended side effects."
+msgstr ""
+
+msgid "Begin with the selected commit"
+msgstr ""
+
+msgid "Below are examples of regex for existing tools:"
+msgstr ""
+
+msgid "Below are the fingerprints for the current instance SSH host keys."
+msgstr ""
+
+msgid "Below you will find all the groups that are public."
+msgstr ""
+
+msgid "Billing"
+msgstr ""
+
+msgid "BillingPlans|%{group_name} is currently using the %{plan_name} plan."
+msgstr ""
+
+msgid "BillingPlans|@%{user_name} you are currently using the %{plan_name} plan."
+msgstr ""
+
+msgid "BillingPlans|Congratulations, your new trial is activated"
+msgstr ""
+
+msgid "BillingPlans|If you would like to downgrade your plan please contact %{support_link_start}Customer Support%{support_link_end}."
+msgstr ""
+
+msgid "BillingPlans|Learn more about each plan by reading our %{faq_link}, or start a free 30-day trial of GitLab.com Gold."
+msgstr ""
+
+msgid "BillingPlans|Learn more about each plan by visiting our %{pricing_page_link}."
+msgstr ""
+
+msgid "BillingPlans|Manage plan"
+msgstr ""
+
+msgid "BillingPlans|Pricing page"
+msgstr ""
+
+msgid "BillingPlans|See all %{plan_name} features"
+msgstr ""
+
+msgid "BillingPlans|This group uses the plan associated with its parent group."
+msgstr ""
+
+msgid "BillingPlans|To manage the plan for this group, visit the billing section of %{parent_billing_page_link}."
+msgstr ""
+
+msgid "BillingPlans|Your GitLab.com %{plan} trial will <strong>expire after %{expiration_date}</strong>. You can retain access to the %{plan} features by upgrading below."
+msgstr ""
+
+msgid "BillingPlans|Your GitLab.com trial expired on %{expiration_date}. You can restore access to the features at any time by upgrading below."
+msgstr ""
+
+msgid "BillingPlans|billed annually at %{price_per_year}"
+msgstr ""
+
+msgid "BillingPlans|frequently asked questions"
+msgstr ""
+
+msgid "BillingPlans|monthly"
+msgstr ""
+
+msgid "BillingPlans|per user"
+msgstr ""
+
+msgid "BillingPlan|Upgrade"
+msgstr ""
+
+msgid "Bitbucket Server Import"
+msgstr ""
+
+msgid "Bitbucket import"
+msgstr ""
+
+msgid "Blocked"
+msgstr ""
+
+msgid "Blocked issue"
+msgstr ""
+
+msgid "Blocks"
+msgstr ""
+
+msgid "Blog"
+msgstr ""
+
+msgid "Blue helpers indicate an action to be taken."
+msgstr ""
+
+msgid "Board name"
+msgstr ""
+
+msgid "Board scope"
+msgstr ""
+
+msgid "Board scope affects which issues are displayed for anyone who visits this board"
+msgstr ""
+
+msgid "BoardBlankState|Add default lists"
+msgstr ""
+
+msgid "BoardBlankState|Add the following default lists to your Issue Board with one click:"
+msgstr ""
+
+msgid "BoardBlankState|Nevermind, I'll use my own"
+msgstr ""
+
+msgid "BoardBlankState|Starting out with the default set of lists will get you right on the way to making the most of your board."
+msgstr ""
+
+msgid "Boards"
+msgstr ""
+
+msgid "Boards and Board Lists"
+msgstr ""
+
+msgid "Boards|Collapse"
+msgstr ""
+
+msgid "Boards|Edit board"
+msgstr ""
+
+msgid "Boards|Expand"
+msgstr ""
+
+msgid "Boards|View scope"
+msgstr ""
+
+msgid "Branch"
+msgstr ""
+
+msgid "Branch %{branchName} was not found in this project's repository."
+msgstr ""
+
+msgid "Branch <strong>%{branch_name}</strong> was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}"
+msgstr ""
+
+msgid "Branch has changed"
+msgstr ""
+
+msgid "Branch is already taken"
+msgstr ""
+
+msgid "Branch name"
+msgstr ""
+
+msgid "Branch not loaded - %{branchId}"
+msgstr ""
+
+msgid "Branch prefix"
+msgstr ""
+
+msgid "BranchSwitcherPlaceholder|Search branches"
+msgstr ""
+
+msgid "BranchSwitcherTitle|Switch branch"
+msgstr ""
+
+msgid "Branches"
+msgstr ""
+
+msgid "Branches|Active"
+msgstr ""
+
+msgid "Branches|Active branches"
+msgstr ""
+
+msgid "Branches|All"
+msgstr ""
+
+msgid "Branches|Cant find HEAD commit for this branch"
+msgstr ""
+
+msgid "Branches|Compare"
+msgstr ""
+
+msgid "Branches|Delete all branches that are merged into '%{default_branch}'"
+msgstr ""
+
+msgid "Branches|Delete branch"
+msgstr ""
+
+msgid "Branches|Delete merged branches"
+msgstr ""
+
+msgid "Branches|Delete protected branch"
+msgstr ""
+
+msgid "Branches|Delete protected branch '%{branch_name}'?"
+msgstr ""
+
+msgid "Branches|Deleting the '%{branch_name}' branch cannot be undone. Are you sure?"
+msgstr ""
+
+msgid "Branches|Deleting the merged branches cannot be undone. Are you sure?"
+msgstr ""
+
+msgid "Branches|Filter by branch name"
+msgstr ""
+
+msgid "Branches|Merged into %{default_branch}"
+msgstr ""
+
+msgid "Branches|New branch"
+msgstr ""
+
+msgid "Branches|No branches to show"
+msgstr ""
+
+msgid "Branches|Once you confirm and press %{delete_protected_branch}, it cannot be undone or recovered."
+msgstr ""
+
+msgid "Branches|Only a project maintainer or owner can delete a protected branch"
+msgstr ""
+
+msgid "Branches|Overview"
+msgstr ""
+
+msgid "Branches|Protected branches can be managed in %{project_settings_link}."
+msgstr ""
+
+msgid "Branches|Show active branches"
+msgstr ""
+
+msgid "Branches|Show all branches"
+msgstr ""
+
+msgid "Branches|Show more active branches"
+msgstr ""
+
+msgid "Branches|Show more stale branches"
+msgstr ""
+
+msgid "Branches|Show overview of the branches"
+msgstr ""
+
+msgid "Branches|Show stale branches"
+msgstr ""
+
+msgid "Branches|Sort by"
+msgstr ""
+
+msgid "Branches|Stale"
+msgstr ""
+
+msgid "Branches|Stale branches"
+msgstr ""
+
+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 ""
+
+msgid "Branches|This branch hasn’t been merged into %{default_branch}."
+msgstr ""
+
+msgid "Branches|To avoid data loss, consider merging this branch before deleting it."
+msgstr ""
+
+msgid "Branches|To confirm, type %{branch_name_confirmation}:"
+msgstr ""
+
+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|You’re about to permanently delete the protected branch %{branch_name}."
+msgstr ""
+
+msgid "Branches|diverged from upstream"
+msgstr ""
+
+msgid "Branches|merged"
+msgstr ""
+
+msgid "Branches|project settings"
+msgstr ""
+
+msgid "Branches|protected"
+msgstr ""
+
+msgid "Broadcast Message was successfully created."
+msgstr ""
+
+msgid "Broadcast Message was successfully updated."
+msgstr ""
+
+msgid "Browse Directory"
+msgstr ""
+
+msgid "Browse File"
+msgstr ""
+
+msgid "Browse Files"
+msgstr ""
+
+msgid "Browse artifacts"
+msgstr ""
+
+msgid "Browse files"
+msgstr ""
+
+msgid "BuildArtifacts|An error occurred while fetching the artifacts"
+msgstr ""
+
+msgid "BuildArtifacts|Loading artifacts"
+msgstr ""
+
+msgid "Built-in"
+msgstr ""
+
+msgid "Bulk request concurrency"
+msgstr ""
+
+msgid "Burndown chart"
+msgstr ""
+
+msgid "BurndownChartLabel|Open issue weight"
+msgstr ""
+
+msgid "BurndownChartLabel|Open issues"
+msgstr ""
+
+msgid "Burnup chart"
+msgstr ""
+
+msgid "Business"
+msgstr ""
+
+msgid "Business metrics (Custom)"
+msgstr ""
+
+msgid "Buy License"
+msgstr ""
+
+msgid "Buy more Pipeline minutes"
+msgstr ""
+
+msgid "By %{user_name}"
+msgstr ""
+
+msgid "By default GitLab sends emails in HTML and plain text formats so mail clients can choose what format to use. Disable this option if you only want to send emails in plain text format."
+msgstr ""
+
+msgid "By default, all projects and groups will use the global notifications setting."
+msgstr ""
+
+msgid "ByAuthor|by"
+msgstr ""
+
+msgid "CHANGELOG"
+msgstr ""
+
+msgid "CI / CD"
+msgstr ""
+
+msgid "CI / CD Analytics"
+msgstr ""
+
+msgid "CI / CD Settings"
+msgstr ""
+
+msgid "CI Lint"
+msgstr ""
+
+msgid "CI settings"
+msgstr ""
+
+msgid "CI variables"
+msgstr ""
+
+msgid "CI will run using the credentials assigned above."
+msgstr ""
+
+msgid "CI/CD"
+msgstr ""
+
+msgid "CI/CD configuration"
+msgstr ""
+
+msgid "CI/CD for external repo"
+msgstr ""
+
+msgid "CI/CD settings"
+msgstr ""
+
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
+msgid "CICD|Auto DevOps"
+msgstr ""
+
+msgid "CICD|Automatic deployment to staging, manual deployment to production"
+msgstr ""
+
+msgid "CICD|Continuous deployment to production"
+msgstr ""
+
+msgid "CICD|Continuous deployment to production using timed incremental rollout"
+msgstr ""
+
+msgid "CICD|Default to Auto DevOps pipeline"
+msgstr ""
+
+msgid "CICD|Default to Auto DevOps pipeline for all projects"
+msgstr ""
+
+msgid "CICD|Deployment strategy"
+msgstr ""
+
+msgid "CICD|Jobs"
+msgstr ""
+
+msgid "CICD|The Auto DevOps pipeline will run if no alternative CI configuration file is found."
+msgstr ""
+
+msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
+msgstr ""
+
+msgid "CICD|group enabled"
+msgstr ""
+
+msgid "CICD|instance enabled"
+msgstr ""
+
+msgid "CLOSED"
+msgstr ""
+
+msgid "CLOSED (MOVED)"
+msgstr ""
+
+msgid "CONTRIBUTING"
+msgstr ""
+
+msgid "CPU"
+msgstr ""
+
+msgid "Callback URL"
+msgstr ""
+
+msgid "Can be manually deployed to"
+msgstr ""
+
+msgid "Can override approvers and approvals required per merge request"
+msgstr ""
+
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
+msgid "Can't find HEAD commit for this branch"
+msgstr ""
+
+msgid "Can't find variable: ZiteReader"
+msgstr ""
+
+msgid "Can't load mermaid module: %{err}"
+msgstr ""
+
+msgid "Can't remove group members without group managed account"
+msgstr ""
+
+msgid "Can't scan the code?"
+msgstr ""
+
+msgid "Can't update snippet: %{err}"
+msgstr ""
+
+msgid "Canary"
+msgstr ""
+
+msgid "Canary Deployments is a popular CI strategy, where a small portion of the fleet is updated to the new version of your application."
+msgstr ""
+
+msgid "Cancel"
+msgstr ""
+
+msgid "Cancel running"
+msgstr ""
+
+msgid "Cancel this job"
+msgstr ""
+
+msgid "Canceled deployment to"
+msgstr ""
+
+msgid "Cancelling Preview"
+msgstr ""
+
+msgid "Cannot be merged automatically"
+msgstr ""
+
+msgid "Cannot create the abuse report. The user has been deleted."
+msgstr ""
+
+msgid "Cannot create the abuse report. This user has been blocked."
+msgstr ""
+
+msgid "Cannot have multiple Jira imports running at the same time"
+msgstr ""
+
+msgid "Cannot import because issues are not available in this project."
+msgstr ""
+
+msgid "Cannot make epic confidential if it contains not-confidential issues"
+msgstr ""
+
+msgid "Cannot make epic confidential if it contains not-confidential sub-epics"
+msgstr ""
+
+msgid "Cannot merge"
+msgstr ""
+
+msgid "Cannot modify managed Kubernetes cluster"
+msgstr ""
+
+msgid "Cannot modify provider during creation"
+msgstr ""
+
+msgid "Cannot promote issue because it does not belong to a group."
+msgstr ""
+
+msgid "Cannot promote issue due to insufficient permissions."
+msgstr ""
+
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
+msgstr ""
+
+msgid "Cannot set confidential epic for not-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 ""
+
+msgid "Cannot skip two factor authentication setup"
+msgstr ""
+
+msgid "Capacity threshold"
+msgstr ""
+
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
+msgid "Certificate"
+msgstr ""
+
+msgid "Certificate (PEM)"
+msgstr ""
+
+msgid "Certificate Issuer"
+msgstr ""
+
+msgid "Certificate Subject"
+msgstr ""
+
+msgid "Change assignee"
+msgstr ""
+
+msgid "Change assignee(s)"
+msgstr ""
+
+msgid "Change assignee(s)."
+msgstr ""
+
+msgid "Change branches"
+msgstr ""
+
+msgid "Change label"
+msgstr ""
+
+msgid "Change milestone"
+msgstr ""
+
+msgid "Change path"
+msgstr ""
+
+msgid "Change permissions"
+msgstr ""
+
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
+msgid "Change template"
+msgstr ""
+
+msgid "Change this value to influence how frequently the GitLab UI polls for updates."
+msgstr ""
+
+msgid "Change title"
+msgstr ""
+
+msgid "Change your password"
+msgstr ""
+
+msgid "Change your password or recover your current one"
+msgstr ""
+
+msgid "ChangeTypeActionLabel|Pick into branch"
+msgstr ""
+
+msgid "ChangeTypeActionLabel|Revert in branch"
+msgstr ""
+
+msgid "ChangeTypeAction|Cherry-pick"
+msgstr ""
+
+msgid "ChangeTypeAction|Revert"
+msgstr ""
+
+msgid "ChangeTypeAction|This will create a new commit in order to revert the existing changes."
+msgstr ""
+
+msgid "Changed assignee(s)."
+msgstr ""
+
+msgid "Changed the title to \"%{title_param}\"."
+msgstr ""
+
+msgid "Changes"
+msgstr ""
+
+msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
+msgstr ""
+
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
+msgid "Changes are unknown"
+msgstr ""
+
+msgid "Changes suppressed. Click to show."
+msgstr ""
+
+msgid "Changes the title to \"%{title_param}\"."
+msgstr ""
+
+msgid "Changes won't take place until the index is %{link_start}recreated%{link_end}."
+msgstr ""
+
+msgid "Changing a Release tag is only supported via Releases API. %{linkStart}More information%{linkEnd}"
+msgstr ""
+
+msgid "Changing group path can have unintended side effects."
+msgstr ""
+
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
+msgid "Charts"
+msgstr ""
+
+msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
+msgstr ""
+
+msgid "Chat"
+msgstr ""
+
+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 ""
+
+msgid "ChatMessage|Commit"
+msgstr ""
+
+msgid "ChatMessage|Failed job"
+msgstr ""
+
+msgid "ChatMessage|Failed stage"
+msgstr ""
+
+msgid "ChatMessage|Invalid CI config YAML file"
+msgstr ""
+
+msgid "ChatMessage|Pipeline #%{pipeline_id} %{humanized_status} in %{duration}"
+msgstr ""
+
+msgid "ChatMessage|Pipeline %{pipeline_link} of %{ref_type} %{ref_link} by %{user_combined_name} %{humanized_status}"
+msgstr ""
+
+msgid "ChatMessage|Tag"
+msgstr ""
+
+msgid "ChatMessage|and [%{count} more](%{pipeline_failed_jobs_url})"
+msgstr ""
+
+msgid "ChatMessage|has failed"
+msgstr ""
+
+msgid "ChatMessage|has passed"
+msgstr ""
+
+msgid "ChatMessage|has passed with warnings"
+msgstr ""
+
+msgid "ChatMessage|in %{duration}"
+msgstr ""
+
+msgid "ChatMessage|in %{project_link}"
+msgstr ""
+
+msgid "Check again"
+msgstr ""
+
+msgid "Check feature availability on namespace plan"
+msgstr ""
+
+msgid "Check the %{docs_link_start}documentation%{docs_link_end}."
+msgstr ""
+
+msgid "Check your .gitlab-ci.yml"
+msgstr ""
+
+msgid "Check your Docker images for known vulnerabilities."
+msgstr ""
+
+msgid "Checking %{text} availability…"
+msgstr ""
+
+msgid "Checking approval status"
+msgstr ""
+
+msgid "Checking branch availability..."
+msgstr ""
+
+msgid "Checking group path availability..."
+msgstr ""
+
+msgid "Checking username availability..."
+msgstr ""
+
+msgid "Checkout"
+msgstr ""
+
+msgid "Checkout|$%{selectedPlanPrice} per user per year"
+msgstr ""
+
+msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
+msgstr ""
+
+msgid "Checkout|%{name}'s GitLab subscription"
+msgstr ""
+
+msgid "Checkout|%{selectedPlanText} plan"
+msgstr ""
+
+msgid "Checkout|%{startDate} - %{endDate}"
+msgstr ""
+
+msgid "Checkout|(x%{numberOfUsers})"
+msgstr ""
+
+msgid "Checkout|Billing address"
+msgstr ""
+
+msgid "Checkout|Checkout"
+msgstr ""
+
+msgid "Checkout|City"
+msgstr ""
+
+msgid "Checkout|Confirm purchase"
+msgstr ""
+
+msgid "Checkout|Confirming..."
+msgstr ""
+
+msgid "Checkout|Continue to billing"
+msgstr ""
+
+msgid "Checkout|Continue to payment"
+msgstr ""
+
+msgid "Checkout|Country"
+msgstr ""
+
+msgid "Checkout|Create a new group"
+msgstr ""
+
+msgid "Checkout|Credit card form failed to load. Please try again."
+msgstr ""
+
+msgid "Checkout|Credit card form failed to load: %{message}"
+msgstr ""
+
+msgid "Checkout|Edit"
+msgstr ""
+
+msgid "Checkout|Exp %{expirationMonth}/%{expirationYear}"
+msgstr ""
+
+msgid "Checkout|Failed to confirm your order! Please try again."
+msgstr ""
+
+msgid "Checkout|Failed to confirm your order: %{message}. Please try again."
+msgstr ""
+
+msgid "Checkout|Failed to load countries. Please try again."
+msgstr ""
+
+msgid "Checkout|Failed to load states. Please try again."
+msgstr ""
+
+msgid "Checkout|Failed to register credit card. Please try again."
+msgstr ""
+
+msgid "Checkout|GitLab group"
+msgstr ""
+
+msgid "Checkout|GitLab plan"
+msgstr ""
+
+msgid "Checkout|Group"
+msgstr ""
+
+msgid "Checkout|Name of company or organization using GitLab"
+msgstr ""
+
+msgid "Checkout|Need more users? Purchase GitLab for your %{company}."
+msgstr ""
+
+msgid "Checkout|Number of users"
+msgstr ""
+
+msgid "Checkout|Payment method"
+msgstr ""
+
+msgid "Checkout|Please select a country"
+msgstr ""
+
+msgid "Checkout|Please select a state"
+msgstr ""
+
+msgid "Checkout|Select"
+msgstr ""
+
+msgid "Checkout|State"
+msgstr ""
+
+msgid "Checkout|Street address"
+msgstr ""
+
+msgid "Checkout|Submitting the credit card form failed with code %{errorCode}: %{errorMessage}"
+msgstr ""
+
+msgid "Checkout|Subscription details"
+msgstr ""
+
+msgid "Checkout|Subtotal"
+msgstr ""
+
+msgid "Checkout|Tax"
+msgstr ""
+
+msgid "Checkout|Total"
+msgstr ""
+
+msgid "Checkout|Users"
+msgstr ""
+
+msgid "Checkout|You'll create your new group after checkout"
+msgstr ""
+
+msgid "Checkout|Your organization"
+msgstr ""
+
+msgid "Checkout|Your subscription will be applied to this group"
+msgstr ""
+
+msgid "Checkout|Zip code"
+msgstr ""
+
+msgid "Checkout|company or team"
+msgstr ""
+
+msgid "Cherry-pick this commit"
+msgstr ""
+
+msgid "Cherry-pick this merge request"
+msgstr ""
+
+msgid "Child"
+msgstr ""
+
+msgid "Child epic does not exist."
+msgstr ""
+
+msgid "Child epic doesn't exist."
+msgstr ""
+
+msgid "Choose <strong>Create archive</strong> and wait for archiving to complete."
+msgstr ""
+
+msgid "Choose <strong>Next</strong> at the bottom of the page."
+msgstr ""
+
+msgid "Choose a branch/tag (e.g. %{master}) or enter a commit (e.g. %{sha}) to see what's changed or to create a merge request."
+msgstr ""
+
+msgid "Choose a file"
+msgstr ""
+
+msgid "Choose a group"
+msgstr ""
+
+msgid "Choose a role permission"
+msgstr ""
+
+msgid "Choose a template"
+msgstr ""
+
+msgid "Choose a template..."
+msgstr ""
+
+msgid "Choose a type..."
+msgstr ""
+
+msgid "Choose any color."
+msgstr ""
+
+msgid "Choose between <code>clone</code> or <code>fetch</code> to get the recent application code"
+msgstr ""
+
+msgid "Choose file…"
+msgstr ""
+
+msgid "Choose the top-level group for your repository imports."
+msgstr ""
+
+msgid "Choose visibility level, enable/disable project features (issues, repository, wiki, snippets) and set permissions."
+msgstr ""
+
+msgid "Choose what content you want to see on a group’s overview page"
+msgstr ""
+
+msgid "Choose which groups you wish to synchronize to this secondary node"
+msgstr ""
+
+msgid "Choose which repositories you want to connect and run CI/CD pipelines."
+msgstr ""
+
+msgid "Choose which shards you wish to synchronize to this secondary node"
+msgstr ""
+
+msgid "Choose your framework"
+msgstr ""
+
+msgid "CiStatusLabel|canceled"
+msgstr ""
+
+msgid "CiStatusLabel|created"
+msgstr ""
+
+msgid "CiStatusLabel|delayed"
+msgstr ""
+
+msgid "CiStatusLabel|failed"
+msgstr ""
+
+msgid "CiStatusLabel|manual action"
+msgstr ""
+
+msgid "CiStatusLabel|passed"
+msgstr ""
+
+msgid "CiStatusLabel|passed with warnings"
+msgstr ""
+
+msgid "CiStatusLabel|pending"
+msgstr ""
+
+msgid "CiStatusLabel|preparing"
+msgstr ""
+
+msgid "CiStatusLabel|skipped"
+msgstr ""
+
+msgid "CiStatusLabel|waiting for delayed job"
+msgstr ""
+
+msgid "CiStatusLabel|waiting for manual action"
+msgstr ""
+
+msgid "CiStatusLabel|waiting for resource"
+msgstr ""
+
+msgid "CiStatusText|blocked"
+msgstr ""
+
+msgid "CiStatusText|canceled"
+msgstr ""
+
+msgid "CiStatusText|created"
+msgstr ""
+
+msgid "CiStatusText|delayed"
+msgstr ""
+
+msgid "CiStatusText|failed"
+msgstr ""
+
+msgid "CiStatusText|manual"
+msgstr ""
+
+msgid "CiStatusText|passed"
+msgstr ""
+
+msgid "CiStatusText|pending"
+msgstr ""
+
+msgid "CiStatusText|preparing"
+msgstr ""
+
+msgid "CiStatusText|skipped"
+msgstr ""
+
+msgid "CiStatusText|waiting"
+msgstr ""
+
+msgid "CiStatus|running"
+msgstr ""
+
+msgid "CiVariables|Cannot use Masked Variable with current value"
+msgstr ""
+
+msgid "CiVariables|Environments"
+msgstr ""
+
+msgid "CiVariables|Input variable key"
+msgstr ""
+
+msgid "CiVariables|Input variable value"
+msgstr ""
+
+msgid "CiVariables|Key"
+msgstr ""
+
+msgid "CiVariables|Masked"
+msgstr ""
+
+msgid "CiVariables|Protected"
+msgstr ""
+
+msgid "CiVariables|Remove variable row"
+msgstr ""
+
+msgid "CiVariables|Scope"
+msgstr ""
+
+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 ""
+
+msgid "CiVariables|Type"
+msgstr ""
+
+msgid "CiVariables|Value"
+msgstr ""
+
+msgid "CiVariables|Variables"
+msgstr ""
+
+msgid "CiVariable|* (All environments)"
+msgstr ""
+
+msgid "CiVariable|All environments"
+msgstr ""
+
+msgid "CiVariable|Create wildcard"
+msgstr ""
+
+msgid "CiVariable|Error occurred while saving variables"
+msgstr ""
+
+msgid "CiVariable|Masked"
+msgstr ""
+
+msgid "CiVariable|New environment"
+msgstr ""
+
+msgid "CiVariable|Protected"
+msgstr ""
+
+msgid "CiVariable|Search environments"
+msgstr ""
+
+msgid "CiVariable|Toggle masked"
+msgstr ""
+
+msgid "CiVariable|Toggle protected"
+msgstr ""
+
+msgid "CiVariable|Validation failed"
+msgstr ""
+
+msgid "Class"
+msgstr ""
+
+msgid "Classification Label (optional)"
+msgstr ""
+
+msgid "ClassificationLabelUnavailable|is unavailable: %{reason}"
+msgstr ""
+
+msgid "Clear"
+msgstr ""
+
+msgid "Clear chart filters"
+msgstr ""
+
+msgid "Clear due date"
+msgstr ""
+
+msgid "Clear input"
+msgstr ""
+
+msgid "Clear recent searches"
+msgstr ""
+
+msgid "Clear search"
+msgstr ""
+
+msgid "Clear search input"
+msgstr ""
+
+msgid "Clear start date"
+msgstr ""
+
+msgid "Clear templates search input"
+msgstr ""
+
+msgid "Clear weight"
+msgstr ""
+
+msgid "Cleared weight."
+msgstr ""
+
+msgid "Clears weight."
+msgstr ""
+
+msgid "Click any <strong>project name</strong> in the project list below to navigate to the project milestone."
+msgstr ""
+
+msgid "Click the <strong>Download</strong> button and wait for downloading to complete."
+msgstr ""
+
+msgid "Click the <strong>Promote</strong> button in the top right corner to promote it to a group milestone."
+msgstr ""
+
+msgid "Click the <strong>Select none</strong> button on the right, since we only need \"Google Code Project Hosting\"."
+msgstr ""
+
+msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
+msgstr ""
+
+msgid "Click to expand it."
+msgstr ""
+
+msgid "Click to expand text"
+msgstr ""
+
+msgid "Client authentication certificate"
+msgstr ""
+
+msgid "Client authentication key"
+msgstr ""
+
+msgid "Client authentication key password"
+msgstr ""
+
+msgid "Clients"
+msgstr ""
+
+msgid "Clone"
+msgstr ""
+
+msgid "Clone repository"
+msgstr ""
+
+msgid "Clone with %{http_label}"
+msgstr ""
+
+msgid "Clone with %{protocol}"
+msgstr ""
+
+msgid "Clone with KRB5"
+msgstr ""
+
+msgid "Clone with SSH"
+msgstr ""
+
+msgid "Close"
+msgstr ""
+
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
+msgid "Close %{tabname}"
+msgstr ""
+
+msgid "Close epic"
+msgstr ""
+
+msgid "Close milestone"
+msgstr ""
+
+msgid "Close sidebar"
+msgstr ""
+
+msgid "Close this %{quick_action_target}"
+msgstr ""
+
+msgid "Closed"
+msgstr ""
+
+msgid "Closed issues"
+msgstr ""
+
+msgid "Closed this %{quick_action_target}."
+msgstr ""
+
+msgid "Closed: %{closedIssuesCount}"
+msgstr ""
+
+msgid "Closes this %{quick_action_target}."
+msgstr ""
+
+msgid "Cluster"
+msgstr ""
+
+msgid "Cluster Health"
+msgstr ""
+
+msgid "Cluster cache cleared."
+msgstr ""
+
+msgid "Cluster does not exist"
+msgstr ""
+
+msgid "Cluster level"
+msgstr ""
+
+msgid "ClusterIntegration| %{custom_domain_start}More information%{custom_domain_end}."
+msgstr ""
+
+msgid "ClusterIntegration| This will permanently delete the following resources: <ul> <li>All installed applications and related resources</li> <li>The <code>gitlab-managed-apps</code> namespace</li> <li>Any project namespaces</li> <li><code>clusterroles</code></li> <li><code>clusterrolebindings</code></li> </ul>"
+msgstr ""
+
+msgid "ClusterIntegration| can be used instead of a custom domain."
+msgstr ""
+
+msgid "ClusterIntegration| is the default environment scope for this cluster. This means that all jobs, regardless of their environment, will use this cluster. %{environment_scope_start}More information%{environment_scope_end}"
+msgstr ""
+
+msgid "ClusterIntegration|%{appList} was successfully installed on your Kubernetes cluster"
+msgstr ""
+
+msgid "ClusterIntegration|%{external_ip}.nip.io"
+msgstr ""
+
+msgid "ClusterIntegration|%{title} uninstalled successfully."
+msgstr ""
+
+msgid "ClusterIntegration|%{title} updated successfully."
+msgstr ""
+
+msgid "ClusterIntegration|A cluster management project can be used to run deployment jobs with Kubernetes <code>cluster-admin</code> privileges."
+msgstr ""
+
+msgid "ClusterIntegration|A service token scoped to %{code}kube-system%{end_code} with %{code}cluster-admin%{end_code} privileges."
+msgstr ""
+
+msgid "ClusterIntegration|API URL"
+msgstr ""
+
+msgid "ClusterIntegration|API URL should be a valid http/https url."
+msgstr ""
+
+msgid "ClusterIntegration|Add Kubernetes cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Add a Kubernetes cluster integration"
+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 ""
+
+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 ""
+
+msgid "ClusterIntegration|Adding an integration to your group will share the cluster across all your projects."
+msgstr ""
+
+msgid "ClusterIntegration|Adding an integration will share the cluster across all projects."
+msgstr ""
+
+msgid "ClusterIntegration|Advanced options on this Kubernetes cluster’s integration"
+msgstr ""
+
+msgid "ClusterIntegration|All data not committed to GitLab will be deleted and cannot be restored."
+msgstr ""
+
+msgid "ClusterIntegration|All data will be deleted and cannot be restored."
+msgstr ""
+
+msgid "ClusterIntegration|Allow GitLab to manage namespace and service accounts for this cluster."
+msgstr ""
+
+msgid "ClusterIntegration|Allow GitLab to manage namespace and service accounts for this cluster. %{startLink}More information%{endLink}"
+msgstr ""
+
+msgid "ClusterIntegration|Alternatively"
+msgstr ""
+
+msgid "ClusterIntegration|Amazon EKS"
+msgstr ""
+
+msgid "ClusterIntegration|An error occurred when trying to contact the Google Cloud API. Please try again later."
+msgstr ""
+
+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 ""
+
+msgid "ClusterIntegration|An error occurred while trying to fetch zone machine types: %{error}"
+msgstr ""
+
+msgid "ClusterIntegration|Any running pipelines will be canceled."
+msgstr ""
+
+msgid "ClusterIntegration|Apply for credit"
+msgstr ""
+
+msgid "ClusterIntegration|Authenticate with AWS"
+msgstr ""
+
+msgid "ClusterIntegration|Authenticate with Amazon Web Services"
+msgstr ""
+
+msgid "ClusterIntegration|Base domain"
+msgstr ""
+
+msgid "ClusterIntegration|Blocking mode"
+msgstr ""
+
+msgid "ClusterIntegration|CA Certificate"
+msgstr ""
+
+msgid "ClusterIntegration|Cert-Manager"
+msgstr ""
+
+msgid "ClusterIntegration|Cert-Manager is a native Kubernetes certificate management controller that helps with issuing certificates. Installing Cert-Manager on your cluster will issue a certificate by %{letsEncrypt} and ensure that certificates are valid and up-to-date."
+msgstr ""
+
+msgid "ClusterIntegration|Certificate Authority bundle (PEM format)"
+msgstr ""
+
+msgid "ClusterIntegration|Choose the %{startLink}security group %{externalLinkIcon} %{endLink} to apply to the EKS-managed Elastic Network Interfaces that are created in your worker node subnets."
+msgstr ""
+
+msgid "ClusterIntegration|Choose the %{startLink}subnets %{externalLinkIcon} %{endLink} in your VPC where your worker nodes will run."
+msgstr ""
+
+msgid "ClusterIntegration|Choose the worker node %{startLink}instance type %{externalLinkIcon} %{endLink}."
+msgstr ""
+
+msgid "ClusterIntegration|Choose which applications to install on your Kubernetes cluster. Helm Tiller is required to install any of the following applications."
+msgstr ""
+
+msgid "ClusterIntegration|Choose which of your environments will use this cluster."
+msgstr ""
+
+msgid "ClusterIntegration|Clear cluster cache"
+msgstr ""
+
+msgid "ClusterIntegration|Clear the local cache of namespace and service accounts. 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 ""
+
+msgid "ClusterIntegration|Cloud Run"
+msgstr ""
+
+msgid "ClusterIntegration|Cluster being created"
+msgstr ""
+
+msgid "ClusterIntegration|Cluster management project (alpha)"
+msgstr ""
+
+msgid "ClusterIntegration|Cluster name is required."
+msgstr ""
+
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
+msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
+msgstr ""
+
+msgid "ClusterIntegration|Copy API URL"
+msgstr ""
+
+msgid "ClusterIntegration|Copy CA Certificate"
+msgstr ""
+
+msgid "ClusterIntegration|Copy Ingress Endpoint"
+msgstr ""
+
+msgid "ClusterIntegration|Copy Jupyter Hostname"
+msgstr ""
+
+msgid "ClusterIntegration|Copy Knative Endpoint"
+msgstr ""
+
+msgid "ClusterIntegration|Copy Kubernetes cluster name"
+msgstr ""
+
+msgid "ClusterIntegration|Could not load IAM roles"
+msgstr ""
+
+msgid "ClusterIntegration|Could not load Key Pairs"
+msgstr ""
+
+msgid "ClusterIntegration|Could not load VPCs for the selected region"
+msgstr ""
+
+msgid "ClusterIntegration|Could not load instance types"
+msgstr ""
+
+msgid "ClusterIntegration|Could not load networks"
+msgstr ""
+
+msgid "ClusterIntegration|Could not load regions from your AWS account"
+msgstr ""
+
+msgid "ClusterIntegration|Could not load security groups for the selected VPC"
+msgstr ""
+
+msgid "ClusterIntegration|Could not load subnets for the selected VPC"
+msgstr ""
+
+msgid "ClusterIntegration|Could not load subnetworks"
+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 ""
+
+msgid "ClusterIntegration|Create new cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Create new cluster on EKS"
+msgstr ""
+
+msgid "ClusterIntegration|Create new cluster on GKE"
+msgstr ""
+
+msgid "ClusterIntegration|Creating Kubernetes cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Crossplane"
+msgstr ""
+
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgstr ""
+
+msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
+msgstr ""
+
+msgid "ClusterIntegration|Did you know?"
+msgstr ""
+
+msgid "ClusterIntegration|Elastic Kubernetes Service"
+msgstr ""
+
+msgid "ClusterIntegration|Elastic Stack"
+msgstr ""
+
+msgid "ClusterIntegration|Enable Cloud Run for Anthos"
+msgstr ""
+
+msgid "ClusterIntegration|Enable or disable GitLab's connection to your Kubernetes cluster."
+msgstr ""
+
+msgid "ClusterIntegration|Enable this setting if using role-based access control (RBAC)."
+msgstr ""
+
+msgid "ClusterIntegration|Enabled stack"
+msgstr ""
+
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
+msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Enter the details for your Kubernetes cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Environment scope"
+msgstr ""
+
+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 ""
+
+msgid "ClusterIntegration|Failed to configure EKS provider: %{message}"
+msgstr ""
+
+msgid "ClusterIntegration|Failed to configure Google Kubernetes Engine Cluster: %{message}"
+msgstr ""
+
+msgid "ClusterIntegration|Failed to fetch CloudFormation stack: %{message}"
+msgstr ""
+
+msgid "ClusterIntegration|Failed to request to Google Cloud Platform: %{message}"
+msgstr ""
+
+msgid "ClusterIntegration|Failed to run Kubeclient: %{message}"
+msgstr ""
+
+msgid "ClusterIntegration|Fetching machine types"
+msgstr ""
+
+msgid "ClusterIntegration|Fetching projects"
+msgstr ""
+
+msgid "ClusterIntegration|Fetching zones"
+msgstr ""
+
+msgid "ClusterIntegration|Fluentd"
+msgstr ""
+
+msgid "ClusterIntegration|Fluentd is an open source data collector, which lets you unify the data collection and consumption for a better use and understanding of data. It requires at least one of the following logs to be successfully installed."
+msgstr ""
+
+msgid "ClusterIntegration|GitLab Integration"
+msgstr ""
+
+msgid "ClusterIntegration|GitLab Runner"
+msgstr ""
+
+msgid "ClusterIntegration|GitLab Runner connects to the repository and executes CI/CD jobs, pushing results back and deploying applications to production."
+msgstr ""
+
+msgid "ClusterIntegration|GitLab-managed cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Gitlab Integration"
+msgstr ""
+
+msgid "ClusterIntegration|Global default"
+msgstr ""
+
+msgid "ClusterIntegration|Google Cloud Platform project"
+msgstr ""
+
+msgid "ClusterIntegration|Google GKE"
+msgstr ""
+
+msgid "ClusterIntegration|Google Kubernetes Engine"
+msgstr ""
+
+msgid "ClusterIntegration|Google Kubernetes Engine project"
+msgstr ""
+
+msgid "ClusterIntegration|Group cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Helm Tiller"
+msgstr ""
+
+msgid "ClusterIntegration|Helm release failed to install"
+msgstr ""
+
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgstr ""
+
+msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
+msgstr ""
+
+msgid "ClusterIntegration|If you do not wish to delete all associated GitLab resources, you can simply remove the integration."
+msgstr ""
+
+msgid "ClusterIntegration|In order to view the health of your cluster, you must first install Prometheus in the Applications tab."
+msgstr ""
+
+msgid "ClusterIntegration|Ingress"
+msgstr ""
+
+msgid "ClusterIntegration|Ingress Endpoint"
+msgstr ""
+
+msgid "ClusterIntegration|Ingress gives you a way to route requests to services based on the request host or path, centralizing a number of services into a single entrypoint."
+msgstr ""
+
+msgid "ClusterIntegration|Installing Ingress may incur additional costs. Learn more about %{pricingLink}."
+msgstr ""
+
+msgid "ClusterIntegration|Instance cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Instance type"
+msgstr ""
+
+msgid "ClusterIntegration|Integrate Kubernetes cluster automation"
+msgstr ""
+
+msgid "ClusterIntegration|Issuer Email"
+msgstr ""
+
+msgid "ClusterIntegration|Issuers represent a certificate authority. You must provide an email address for your Issuer. "
+msgstr ""
+
+msgid "ClusterIntegration|Jupyter Hostname"
+msgstr ""
+
+msgid "ClusterIntegration|JupyterHub"
+msgstr ""
+
+msgid "ClusterIntegration|JupyterHub, a multi-user Hub, spawns, manages, and proxies multiple instances of the single-user Jupyter notebook server. JupyterHub can be used to serve notebooks to a class of students, a corporate data science group, or a scientific research group."
+msgstr ""
+
+msgid "ClusterIntegration|Key pair name"
+msgstr ""
+
+msgid "ClusterIntegration|Knative"
+msgstr ""
+
+msgid "ClusterIntegration|Knative Domain Name:"
+msgstr ""
+
+msgid "ClusterIntegration|Knative Endpoint:"
+msgstr ""
+
+msgid "ClusterIntegration|Knative domain name was updated successfully."
+msgstr ""
+
+msgid "ClusterIntegration|Knative extends Kubernetes to provide a set of middleware components that are essential to build modern, source-centric, and container-based applications that can run anywhere: on premises, in the cloud, or even in a third-party data center."
+msgstr ""
+
+msgid "ClusterIntegration|Kubernetes cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Kubernetes cluster is being created..."
+msgstr ""
+
+msgid "ClusterIntegration|Kubernetes cluster name"
+msgstr ""
+
+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 ""
+
+msgid "ClusterIntegration|Kubernetes clusters can be used to deploy applications and to provide Review Apps for this project"
+msgstr ""
+
+msgid "ClusterIntegration|Kubernetes version"
+msgstr ""
+
+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 ""
+
+msgid "ClusterIntegration|Learn more about %{help_link_start}zones%{help_link_end}."
+msgstr ""
+
+msgid "ClusterIntegration|Learn more about %{startLink}Regions %{externalLinkIcon}%{endLink}."
+msgstr ""
+
+msgid "ClusterIntegration|Learn more about Kubernetes"
+msgstr ""
+
+msgid "ClusterIntegration|Learn more about group Kubernetes clusters"
+msgstr ""
+
+msgid "ClusterIntegration|Learn more about instance Kubernetes clusters"
+msgstr ""
+
+msgid "ClusterIntegration|Let's Encrypt"
+msgstr ""
+
+msgid "ClusterIntegration|Loading IAM Roles"
+msgstr ""
+
+msgid "ClusterIntegration|Loading Key Pairs"
+msgstr ""
+
+msgid "ClusterIntegration|Loading Regions"
+msgstr ""
+
+msgid "ClusterIntegration|Loading VPCs"
+msgstr ""
+
+msgid "ClusterIntegration|Loading instance types"
+msgstr ""
+
+msgid "ClusterIntegration|Loading networks"
+msgstr ""
+
+msgid "ClusterIntegration|Loading security groups"
+msgstr ""
+
+msgid "ClusterIntegration|Loading subnets"
+msgstr ""
+
+msgid "ClusterIntegration|Loading subnetworks"
+msgstr ""
+
+msgid "ClusterIntegration|Logging mode"
+msgstr ""
+
+msgid "ClusterIntegration|Machine type"
+msgstr ""
+
+msgid "ClusterIntegration|Make sure your account %{link_to_requirements} to create Kubernetes clusters"
+msgstr ""
+
+msgid "ClusterIntegration|Manage your Kubernetes cluster by visiting %{provider_link}"
+msgstr ""
+
+msgid "ClusterIntegration|No IAM Roles found"
+msgstr ""
+
+msgid "ClusterIntegration|No Key Pairs found"
+msgstr ""
+
+msgid "ClusterIntegration|No VPCs found"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No instance type found"
+msgstr ""
+
+msgid "ClusterIntegration|No machine types matched your search"
+msgstr ""
+
+msgid "ClusterIntegration|No networks found"
+msgstr ""
+
+msgid "ClusterIntegration|No projects found"
+msgstr ""
+
+msgid "ClusterIntegration|No projects matched your search"
+msgstr ""
+
+msgid "ClusterIntegration|No region found"
+msgstr ""
+
+msgid "ClusterIntegration|No security group found"
+msgstr ""
+
+msgid "ClusterIntegration|No subnet found"
+msgstr ""
+
+msgid "ClusterIntegration|No subnetworks found"
+msgstr ""
+
+msgid "ClusterIntegration|No zones matched your search"
+msgstr ""
+
+msgid "ClusterIntegration|Number of nodes"
+msgstr ""
+
+msgid "ClusterIntegration|Number of nodes must be a numerical value."
+msgstr ""
+
+msgid "ClusterIntegration|Please enter access information for your Kubernetes cluster. If you need help, you can read our %{link_to_help_page} on Kubernetes"
+msgstr ""
+
+msgid "ClusterIntegration|Please make sure that your Google account meets the following requirements:"
+msgstr ""
+
+msgid "ClusterIntegration|Point a wildcard DNS to this generated endpoint in order to access your application after it has been deployed."
+msgstr ""
+
+msgid "ClusterIntegration|Project cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Project namespace (optional, unique)"
+msgstr ""
+
+msgid "ClusterIntegration|Project namespace prefix (optional, unique)"
+msgstr ""
+
+msgid "ClusterIntegration|Prometheus"
+msgstr ""
+
+msgid "ClusterIntegration|Prometheus is an open-source monitoring system with %{gitlabIntegrationLink} to monitor deployed applications."
+msgstr ""
+
+msgid "ClusterIntegration|Provider details"
+msgstr ""
+
+msgid "ClusterIntegration|Provision Role ARN"
+msgstr ""
+
+msgid "ClusterIntegration|RBAC-enabled cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Read our %{link_start}help page%{link_end} on Kubernetes cluster integration."
+msgstr ""
+
+msgid "ClusterIntegration|Real-time web application monitoring, logging and access control. %{linkStart}More information%{linkEnd}"
+msgstr ""
+
+msgid "ClusterIntegration|Region"
+msgstr ""
+
+msgid "ClusterIntegration|Remove Kubernetes cluster integration"
+msgstr ""
+
+msgid "ClusterIntegration|Remove integration"
+msgstr ""
+
+msgid "ClusterIntegration|Remove integration and resources"
+msgstr ""
+
+msgid "ClusterIntegration|Remove integration and resources?"
+msgstr ""
+
+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 ""
+
+msgid "ClusterIntegration|Removes cluster from project but keeps associated resources"
+msgstr ""
+
+msgid "ClusterIntegration|Replace this with your own hostname if you want. If you do so, point hostname to Ingress IP Address from above."
+msgstr ""
+
+msgid "ClusterIntegration|Request to begin installing failed"
+msgstr ""
+
+msgid "ClusterIntegration|Request to begin uninstalling failed"
+msgstr ""
+
+msgid "ClusterIntegration|SIEM Hostname"
+msgstr ""
+
+msgid "ClusterIntegration|SIEM Port"
+msgstr ""
+
+msgid "ClusterIntegration|SIEM Protocol"
+msgstr ""
+
+msgid "ClusterIntegration|Save changes"
+msgstr ""
+
+msgid "ClusterIntegration|Search IAM Roles"
+msgstr ""
+
+msgid "ClusterIntegration|Search Key Pairs"
+msgstr ""
+
+msgid "ClusterIntegration|Search VPCs"
+msgstr ""
+
+msgid "ClusterIntegration|Search domains"
+msgstr ""
+
+msgid "ClusterIntegration|Search instance types"
+msgstr ""
+
+msgid "ClusterIntegration|Search machine types"
+msgstr ""
+
+msgid "ClusterIntegration|Search networks"
+msgstr ""
+
+msgid "ClusterIntegration|Search projects"
+msgstr ""
+
+msgid "ClusterIntegration|Search regions"
+msgstr ""
+
+msgid "ClusterIntegration|Search security groups"
+msgstr ""
+
+msgid "ClusterIntegration|Search subnets"
+msgstr ""
+
+msgid "ClusterIntegration|Search subnetworks"
+msgstr ""
+
+msgid "ClusterIntegration|Search zones"
+msgstr ""
+
+msgid "ClusterIntegration|Security group"
+msgstr ""
+
+msgid "ClusterIntegration|See and edit the details for your Kubernetes cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Select a VPC to choose a security group"
+msgstr ""
+
+msgid "ClusterIntegration|Select a VPC to choose a subnet"
+msgstr ""
+
+msgid "ClusterIntegration|Select a VPC to use for your EKS Cluster resources. To use a new VPC, first create one on %{startLink}Amazon Web Services %{externalLinkIcon} %{endLink}."
+msgstr ""
+
+msgid "ClusterIntegration|Select a network to choose a subnetwork"
+msgstr ""
+
+msgid "ClusterIntegration|Select a region to choose a Key Pair"
+msgstr ""
+
+msgid "ClusterIntegration|Select a region to choose a VPC"
+msgstr ""
+
+msgid "ClusterIntegration|Select a stack to install Crossplane."
+msgstr ""
+
+msgid "ClusterIntegration|Select a zone to choose a network"
+msgstr ""
+
+msgid "ClusterIntegration|Select existing domain or use new"
+msgstr ""
+
+msgid "ClusterIntegration|Select machine type"
+msgstr ""
+
+msgid "ClusterIntegration|Select project"
+msgstr ""
+
+msgid "ClusterIntegration|Select project and zone to choose machine type"
+msgstr ""
+
+msgid "ClusterIntegration|Select project to choose zone"
+msgstr ""
+
+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 %{startLink}Amazon Web Services %{externalLinkIcon} %{endLink}."
+msgstr ""
+
+msgid "ClusterIntegration|Select zone"
+msgstr ""
+
+msgid "ClusterIntegration|Select zone to choose machine type"
+msgstr ""
+
+msgid "ClusterIntegration|Send Cilium Logs"
+msgstr ""
+
+msgid "ClusterIntegration|Send ModSecurity Logs"
+msgstr ""
+
+msgid "ClusterIntegration|Service Token"
+msgstr ""
+
+msgid "ClusterIntegration|Service role"
+msgstr ""
+
+msgid "ClusterIntegration|Service token is required."
+msgstr ""
+
+msgid "ClusterIntegration|Set a prefix for your namespaces. If not set, defaults to your project path. If modified, existing environments will use their current namespaces until the cluster cache is cleared."
+msgstr ""
+
+msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
+msgstr ""
+
+msgid "ClusterIntegration|Something went wrong on our end."
+msgstr ""
+
+msgid "ClusterIntegration|Something went wrong while creating your Kubernetes cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Something went wrong while installing %{title}"
+msgstr ""
+
+msgid "ClusterIntegration|Something went wrong while trying to save your settings. Please try again."
+msgstr ""
+
+msgid "ClusterIntegration|Something went wrong while uninstalling %{title}"
+msgstr ""
+
+msgid "ClusterIntegration|Something went wrong while updating Knative domain name."
+msgstr ""
+
+msgid "ClusterIntegration|Specifying a domain will allow you to use Auto Review Apps and Auto Deploy stages for %{auto_devops_start}Auto DevOps%{auto_devops_end}. The domain should have a wildcard DNS configured matching the domain."
+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 ""
+
+msgid "ClusterIntegration|The Kubernetes certificate used to authenticate to the cluster."
+msgstr ""
+
+msgid "ClusterIntegration|The URL used to access the Kubernetes API."
+msgstr ""
+
+msgid "ClusterIntegration|The associated IP and all deployed services will be deleted and cannot be restored. Uninstalling Knative will also remove Istio from your cluster. This will not effect any other applications."
+msgstr ""
+
+msgid "ClusterIntegration|The associated Tiller pod, the %{gitlabManagedAppsNamespace} namespace, and all of its resources will be deleted and cannot be restored."
+msgstr ""
+
+msgid "ClusterIntegration|The associated load balancer and IP will be deleted and cannot be restored."
+msgstr ""
+
+msgid "ClusterIntegration|The associated private key will be deleted and cannot be restored."
+msgstr ""
+
+msgid "ClusterIntegration|The elastic stack collects logs from all pods in your cluster"
+msgstr ""
+
+msgid "ClusterIntegration|The endpoint is in the process of being assigned. Please check your Kubernetes cluster or Quotas on Google Kubernetes Engine if it takes a long time."
+msgstr ""
+
+msgid "ClusterIntegration|The namespace associated with your project. This will be used for deploy boards, logs, and Web terminals."
+msgstr ""
+
+msgid "ClusterIntegration|There was a problem authenticating with your cluster. Please ensure your CA Certificate and Token are valid."
+msgstr ""
+
+msgid "ClusterIntegration|This account must have permissions to create a Kubernetes cluster in the %{link_to_container_project} specified below"
+msgstr ""
+
+msgid "ClusterIntegration|This option will allow you to install applications on RBAC clusters."
+msgstr ""
+
+msgid "ClusterIntegration|To access your application after deployment, point a wildcard DNS to the Knative Endpoint."
+msgstr ""
+
+msgid "ClusterIntegration|To remove your integration and resources, type %{clusterName} to confirm:"
+msgstr ""
+
+msgid "ClusterIntegration|To remove your integration, type %{clusterName} to confirm:"
+msgstr ""
+
+msgid "ClusterIntegration|Toggle Kubernetes cluster"
+msgstr ""
+
+msgid "ClusterIntegration|Uninstall %{appTitle}"
+msgstr ""
+
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
+msgid "ClusterIntegration|Update failed. Please check the logs and try again."
+msgstr ""
+
+msgid "ClusterIntegration|Use %{query}"
+msgstr ""
+
+msgid "ClusterIntegration|Uses the Cloud Run, Istio, and HTTP Load Balancing addons for this cluster."
+msgstr ""
+
+msgid "ClusterIntegration|VPC"
+msgstr ""
+
+msgid "ClusterIntegration|Validating project billing status"
+msgstr ""
+
+msgid "ClusterIntegration|We could not verify that one of your projects on GCP has billing enabled. Please try again."
+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 ""
+
+msgid "ClusterIntegration|You are about to remove your cluster integration and all GitLab-created resources associated with this cluster."
+msgstr ""
+
+msgid "ClusterIntegration|You are about to remove your cluster integration."
+msgstr ""
+
+msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
+msgstr ""
+
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
+msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
+msgstr ""
+
+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 ""
+
+msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
+msgstr ""
+
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
+msgid "ClusterIntegration|You should select at least two subnets"
+msgstr ""
+
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
+msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
+msgstr ""
+
+msgid "ClusterIntegration|Your cluster API is unreachable. Please ensure your API URL is correct."
+msgstr ""
+
+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 %{startLink}Amazon Web Services %{externalLinkIcon} %{endLink}."
+msgstr ""
+
+msgid "ClusterIntegration|Zone"
+msgstr ""
+
+msgid "ClusterIntegration|access to Google Kubernetes Engine"
+msgstr ""
+
+msgid "ClusterIntegration|documentation"
+msgstr ""
+
+msgid "ClusterIntegration|installed via %{installed_via}"
+msgstr ""
+
+msgid "ClusterIntegration|meets the requirements"
+msgstr ""
+
+msgid "ClusterIntegration|pricing"
+msgstr ""
+
+msgid "ClusterIntegration|sign up"
+msgstr ""
+
+msgid "ClusterIntergation|Select a VPC"
+msgstr ""
+
+msgid "ClusterIntergation|Select a network"
+msgstr ""
+
+msgid "ClusterIntergation|Select a region"
+msgstr ""
+
+msgid "ClusterIntergation|Select a security group"
+msgstr ""
+
+msgid "ClusterIntergation|Select a subnet"
+msgstr ""
+
+msgid "ClusterIntergation|Select a subnetwork"
+msgstr ""
+
+msgid "ClusterIntergation|Select an instance type"
+msgstr ""
+
+msgid "ClusterIntergation|Select key pair"
+msgstr ""
+
+msgid "ClusterIntergation|Select service role"
+msgstr ""
+
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
+msgid "Code"
+msgstr ""
+
+msgid "Code Owners"
+msgstr ""
+
+msgid "Code Owners to the merge request changes."
+msgstr ""
+
+msgid "Code Quality"
+msgstr ""
+
+msgid "Code Review"
+msgstr ""
+
+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 ""
+
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
+msgid "Code owner approval is required"
+msgstr ""
+
+msgid "Code owners"
+msgstr ""
+
+msgid "CodeOwner|Pattern"
+msgstr ""
+
+msgid "Cohorts"
+msgstr ""
+
+msgid "Cohorts|Inactive users"
+msgstr ""
+
+msgid "Cohorts|Month %{month_index}"
+msgstr ""
+
+msgid "Cohorts|New users"
+msgstr ""
+
+msgid "Cohorts|Registration month"
+msgstr ""
+
+msgid "Cohorts|Returning users"
+msgstr ""
+
+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 ""
+
+msgid "Collapse approvers"
+msgstr ""
+
+msgid "Collapse child epics"
+msgstr ""
+
+msgid "Collapse replies"
+msgstr ""
+
+msgid "Collapse sidebar"
+msgstr ""
+
+msgid "Collector hostname"
+msgstr ""
+
+msgid "ComboSearch is not defined"
+msgstr ""
+
+msgid "Coming soon"
+msgstr ""
+
+msgid "Command"
+msgstr ""
+
+msgid "Command line instructions"
+msgstr ""
+
+msgid "Commands applied"
+msgstr ""
+
+msgid "Commands did not apply"
+msgstr ""
+
+msgid "Comment"
+msgstr ""
+
+msgid "Comment & close %{noteable_name}"
+msgstr ""
+
+msgid "Comment & reopen %{noteable_name}"
+msgstr ""
+
+msgid "Comment & resolve thread"
+msgstr ""
+
+msgid "Comment & unresolve thread"
+msgstr ""
+
+msgid "Comment '%{label}' position"
+msgstr ""
+
+msgid "Comment form position"
+msgstr ""
+
+msgid "Comment is being updated"
+msgstr ""
+
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
+msgid "Comment/Reply (quoting selected text)"
+msgstr ""
+
+msgid "Comments"
+msgstr ""
+
+msgid "Commit"
+msgid_plural "Commits"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Commit %{commit_id}"
+msgstr ""
+
+msgid "Commit (when editing commit message)"
+msgstr ""
+
+msgid "Commit Message"
+msgstr ""
+
+msgid "Commit deleted"
+msgstr ""
+
+msgid "Commit message"
+msgstr ""
+
+msgid "Commit message (optional)"
+msgstr ""
+
+msgid "Commit statistics for %{ref} %{start_time} - %{end_time}"
+msgstr ""
+
+msgid "Commit to %{branchName} branch"
+msgstr ""
+
+msgid "CommitBoxTitle|Commit"
+msgstr ""
+
+msgid "CommitMessage|Add %{file_name}"
+msgstr ""
+
+msgid "CommitWidget|authored"
+msgstr ""
+
+msgid "Commits"
+msgstr ""
+
+msgid "Commits feed"
+msgstr ""
+
+msgid "Commits per day hour (UTC)"
+msgstr ""
+
+msgid "Commits per day of month"
+msgstr ""
+
+msgid "Commits per weekday"
+msgstr ""
+
+msgid "Commits to"
+msgstr ""
+
+msgid "Commits|An error occurred while fetching merge requests data."
+msgstr ""
+
+msgid "Commits|History"
+msgstr ""
+
+msgid "Commits|No related merge requests found"
+msgstr ""
+
+msgid "Committed by"
+msgstr ""
+
+msgid "Commit…"
+msgstr ""
+
+msgid "Company"
+msgstr ""
+
+msgid "Company name"
+msgstr ""
+
+msgid "Compare"
+msgstr ""
+
+msgid "Compare Git revisions"
+msgstr ""
+
+msgid "Compare Revisions"
+msgstr ""
+
+msgid "Compare changes"
+msgstr ""
+
+msgid "Compare changes with the last commit"
+msgstr ""
+
+msgid "Compare changes with the merge request target branch"
+msgstr ""
+
+msgid "Compare with previous version"
+msgstr ""
+
+msgid "CompareBranches|%{source_branch} and %{target_branch} are the same."
+msgstr ""
+
+msgid "CompareBranches|Compare"
+msgstr ""
+
+msgid "CompareBranches|Source"
+msgstr ""
+
+msgid "CompareBranches|Target"
+msgstr ""
+
+msgid "CompareBranches|There isn't anything to compare."
+msgstr ""
+
+msgid "Complete"
+msgstr ""
+
+msgid "Compliance"
+msgstr ""
+
+msgid "Compliance Dashboard"
+msgstr ""
+
+msgid "Compliance framework (optional)"
+msgstr ""
+
+msgid "ComplianceFramework|GDPR"
+msgstr ""
+
+msgid "ComplianceFramework|GDPR - General Data Protection Regulation"
+msgstr ""
+
+msgid "ComplianceFramework|HIPAA"
+msgstr ""
+
+msgid "ComplianceFramework|HIPAA - Health Insurance Portability and Accountability Act"
+msgstr ""
+
+msgid "ComplianceFramework|PCI-DSS"
+msgstr ""
+
+msgid "ComplianceFramework|PCI-DSS - Payment Card Industry-Data Security Standard"
+msgstr ""
+
+msgid "ComplianceFramework|SOC 2"
+msgstr ""
+
+msgid "ComplianceFramework|SOC 2 - Service Organization Control 2"
+msgstr ""
+
+msgid "ComplianceFramework|SOX"
+msgstr ""
+
+msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
+msgstr ""
+
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
+msgstr ""
+
+msgid "Confidential"
+msgstr ""
+
+msgid "Confidentiality"
+msgstr ""
+
+msgid "Configuration"
+msgstr ""
+
+msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
+msgstr ""
+
+msgid "Configure Gitaly timeouts."
+msgstr ""
+
+msgid "Configure Let's Encrypt"
+msgstr ""
+
+msgid "Configure Prometheus"
+msgstr ""
+
+msgid "Configure Tracing"
+msgstr ""
+
+msgid "Configure a <code>.gitlab-webide.yml</code> file in the <code>.gitlab</code> directory to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
+msgstr ""
+
+msgid "Configure automatic git checks and housekeeping on repositories."
+msgstr ""
+
+msgid "Configure existing installation"
+msgstr ""
+
+msgid "Configure limit for issues created per minute by web and API requests."
+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 ""
+
+msgid "Configure repository mirroring."
+msgstr ""
+
+msgid "Configure storage path settings."
+msgstr ""
+
+msgid "Configure the %{link} integration."
+msgstr ""
+
+msgid "Configure the way a user creates a new account."
+msgstr ""
+
+msgid "Confirm"
+msgstr ""
+
+msgid "Confirmation email sent to %{email}"
+msgstr ""
+
+msgid "Confirmation required"
+msgstr ""
+
+msgid "Congratulations! You have enabled Two-factor Authentication!"
+msgstr ""
+
+msgid "Connect"
+msgstr ""
+
+msgid "Connect all repositories"
+msgstr ""
+
+msgid "Connect repositories from GitHub"
+msgstr ""
+
+msgid "Connect your external repositories, and CI/CD pipelines will run for new commits. A GitLab project will be created with only CI/CD features enabled."
+msgstr ""
+
+msgid "Connected"
+msgstr ""
+
+msgid "Connecting"
+msgstr ""
+
+msgid "Connecting to terminal sync service"
+msgstr ""
+
+msgid "Connecting..."
+msgstr ""
+
+msgid "Connection failed"
+msgstr ""
+
+msgid "Connection failure"
+msgstr ""
+
+msgid "Connection timed out"
+msgstr ""
+
+msgid "Contact sales to upgrade"
+msgstr ""
+
+msgid "Contact support"
+msgstr ""
+
+msgid "Container Registry"
+msgstr ""
+
+msgid "Container Registry tag expiration policy"
+msgstr ""
+
+msgid "Container Scanning"
+msgstr ""
+
+msgid "Container does not exist"
+msgstr ""
+
+msgid "Container registry images"
+msgstr ""
+
+msgid "Container registry is not enabled on this GitLab instance. Ask an administrator to enable it in order for Auto DevOps to work."
+msgstr ""
+
+msgid "Container repositories sync capacity"
+msgstr ""
+
+msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
+msgstr ""
+
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{imageName} tags"
+msgstr ""
+
+msgid "ContainerRegistry|%{title} was successfully scheduled for deletion"
+msgstr ""
+
+msgid "ContainerRegistry|Automatically remove extra images that aren't designed to be kept."
+msgstr ""
+
+msgid "ContainerRegistry|Build an image"
+msgstr ""
+
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
+msgid "ContainerRegistry|Compressed Size"
+msgstr ""
+
+msgid "ContainerRegistry|Container Registry"
+msgstr ""
+
+msgid "ContainerRegistry|Container Registry tag expiration and retention policy is disabled"
+msgstr ""
+
+msgid "ContainerRegistry|Copy build command"
+msgstr ""
+
+msgid "ContainerRegistry|Copy login command"
+msgstr ""
+
+msgid "ContainerRegistry|Copy push command"
+msgstr ""
+
+msgid "ContainerRegistry|Docker connection error"
+msgstr ""
+
+msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration interval:"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy successfully saved."
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy:"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration schedule:"
+msgstr ""
+
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
+msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
+msgstr ""
+
+msgid "ContainerRegistry|Image ID"
+msgstr ""
+
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
+msgid "ContainerRegistry|Keep and protect the images that matter most."
+msgstr ""
+
+msgid "ContainerRegistry|Last Updated"
+msgstr ""
+
+msgid "ContainerRegistry|Login"
+msgstr ""
+
+msgid "ContainerRegistry|Missing or insufficient permission, delete button disabled"
+msgstr ""
+
+msgid "ContainerRegistry|Number of tags to retain:"
+msgstr ""
+
+msgid "ContainerRegistry|Please contact your administrator."
+msgstr ""
+
+msgid "ContainerRegistry|Push an image"
+msgstr ""
+
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
+msgstr ""
+
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Remember to run %{docLinkStart}garbage collection%{docLinkEnd} to remove the stale data from storage."
+msgstr ""
+
+msgid "ContainerRegistry|Remove repository"
+msgstr ""
+
+msgid "ContainerRegistry|Remove selected tags"
+msgstr ""
+
+msgid "ContainerRegistry|Remove tag"
+msgid_plural "ContainerRegistry|Remove tags"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
+msgstr ""
+
+msgid "ContainerRegistry|Something went wrong while fetching the repository list."
+msgstr ""
+
+msgid "ContainerRegistry|Something went wrong while fetching the tags list."
+msgstr ""
+
+msgid "ContainerRegistry|Something went wrong while marking the tag for deletion."
+msgstr ""
+
+msgid "ContainerRegistry|Something went wrong while marking the tags for deletion."
+msgstr ""
+
+msgid "ContainerRegistry|Something went wrong while scheduling %{title} for deletion. Please try again."
+msgstr ""
+
+msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
+msgstr ""
+
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
+msgid "ContainerRegistry|Tag"
+msgstr ""
+
+msgid "ContainerRegistry|Tag expiration policy"
+msgstr ""
+
+msgid "ContainerRegistry|Tag expiration policy is designed to:"
+msgstr ""
+
+msgid "ContainerRegistry|Tag successfully marked for deletion."
+msgstr ""
+
+msgid "ContainerRegistry|Tags successfully marked for deletion."
+msgstr ""
+
+msgid "ContainerRegistry|Tags with names matching this regex pattern will %{italicStart}be preserved:%{italicEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Tags with names matching this regex pattern will %{italicStart}expire:%{italicEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|The Container Registry tag expiration and retention policies for this project have not been enabled."
+msgstr ""
+
+msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
+msgstr ""
+
+msgid "ContainerRegistry|The value of this input should be less than 255 characters"
+msgstr ""
+
+msgid "ContainerRegistry|There are no container images available in this group"
+msgstr ""
+
+msgid "ContainerRegistry|There are no container images stored for this project"
+msgstr ""
+
+msgid "ContainerRegistry|There was an error during the deletion of this image repository, please try again."
+msgstr ""
+
+msgid "ContainerRegistry|This image has no active tags"
+msgstr ""
+
+msgid "ContainerRegistry|This image repository is scheduled for deletion"
+msgstr ""
+
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgstr ""
+
+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 ""
+
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+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 ""
+
+msgid "ContainerRegistry|You are about to remove repository %{title}. Once you confirm, this repository will be permanently deleted."
+msgstr ""
+
+msgid "ContainerRegistry|You can add an image to this registry with the following commands:"
+msgstr ""
+
+msgid "Contains %{count} blobs of images (%{size})"
+msgstr ""
+
+msgid "Contents of .gitlab-ci.yml"
+msgstr ""
+
+msgid "Continue"
+msgstr ""
+
+msgid "Continue to the next step"
+msgstr ""
+
+msgid "Continuous Integration and Deployment"
+msgstr ""
+
+msgid "Contribute to GitLab"
+msgstr ""
+
+msgid "Contribution"
+msgstr ""
+
+msgid "Contribution Analytics"
+msgstr ""
+
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgstr ""
+
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
+msgstr ""
+
+msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
+msgstr ""
+
+msgid "ContributionAnalytics|Contribution analytics for issues, merge requests and push events since %{start_date}"
+msgstr ""
+
+msgid "ContributionAnalytics|Issues"
+msgstr ""
+
+msgid "ContributionAnalytics|Last 3 months"
+msgstr ""
+
+msgid "ContributionAnalytics|Last month"
+msgstr ""
+
+msgid "ContributionAnalytics|Last week"
+msgstr ""
+
+msgid "ContributionAnalytics|Merge Requests"
+msgstr ""
+
+msgid "ContributionAnalytics|No issues for the selected time period."
+msgstr ""
+
+msgid "ContributionAnalytics|No merge requests for the selected time period."
+msgstr ""
+
+msgid "ContributionAnalytics|No pushes for the selected time period."
+msgstr ""
+
+msgid "Contributions for <strong>%{calendar_date}</strong>"
+msgstr ""
+
+msgid "Contributions per group member"
+msgstr ""
+
+msgid "Contributors"
+msgstr ""
+
+msgid "Control emails linked to your account"
+msgstr ""
+
+msgid "Control the display of third party offers."
+msgstr ""
+
+msgid "Control the maximum concurrency of LFS/attachment backfill for this secondary node"
+msgstr ""
+
+msgid "Control the maximum concurrency of container repository operations for this Geo node"
+msgstr ""
+
+msgid "Control the maximum concurrency of repository backfill for this secondary node"
+msgstr ""
+
+msgid "Control the maximum concurrency of verification operations for this Geo node"
+msgstr ""
+
+msgid "Control the minimum interval in days that a repository should be reverified for this primary node"
+msgstr ""
+
+msgid "Cookie domain"
+msgstr ""
+
+msgid "Copied"
+msgstr ""
+
+msgid "Copied labels and milestone from %{source_issuable_reference}."
+msgstr ""
+
+msgid "Copy"
+msgstr ""
+
+msgid "Copy %{field}"
+msgstr ""
+
+msgid "Copy %{http_label} clone URL"
+msgstr ""
+
+msgid "Copy %{protocol} clone URL"
+msgstr ""
+
+msgid "Copy %{proxy_url}"
+msgstr ""
+
+msgid "Copy %{type}"
+msgstr ""
+
+msgid "Copy Account ID to clipboard"
+msgstr ""
+
+msgid "Copy External ID to clipboard"
+msgstr ""
+
+msgid "Copy ID"
+msgstr ""
+
+msgid "Copy KRB5 clone URL"
+msgstr ""
+
+msgid "Copy SSH clone URL"
+msgstr ""
+
+msgid "Copy SSH public key"
+msgstr ""
+
+msgid "Copy URL"
+msgstr ""
+
+msgid "Copy branch name"
+msgstr ""
+
+msgid "Copy command"
+msgstr ""
+
+msgid "Copy commands"
+msgstr ""
+
+msgid "Copy commit SHA"
+msgstr ""
+
+msgid "Copy environment"
+msgstr ""
+
+msgid "Copy evidence SHA"
+msgstr ""
+
+msgid "Copy file contents"
+msgstr ""
+
+msgid "Copy file path"
+msgstr ""
+
+msgid "Copy key"
+msgstr ""
+
+msgid "Copy labels and milestone from %{source_issuable_reference}."
+msgstr ""
+
+msgid "Copy labels and milestone from other issue or merge request in this project"
+msgstr ""
+
+msgid "Copy link"
+msgstr ""
+
+msgid "Copy link to chart"
+msgstr ""
+
+msgid "Copy reference"
+msgstr ""
+
+msgid "Copy secret"
+msgstr ""
+
+msgid "Copy token"
+msgstr ""
+
+msgid "Copy trigger token"
+msgstr ""
+
+msgid "Copy value"
+msgstr ""
+
+msgid "Could not add admins as members"
+msgstr ""
+
+msgid "Could not authorize chat nickname. Try again!"
+msgstr ""
+
+msgid "Could not change HEAD: branch '%{branch}' does not exist"
+msgstr ""
+
+msgid "Could not connect to FogBugz, check your URL"
+msgstr ""
+
+msgid "Could not connect to Sentry. Refresh the page to try again."
+msgstr ""
+
+msgid "Could not connect to Web IDE file mirror service."
+msgstr ""
+
+msgid "Could not create Wiki Repository at this time. Please try again later."
+msgstr ""
+
+msgid "Could not create environment"
+msgstr ""
+
+msgid "Could not create group"
+msgstr ""
+
+msgid "Could not create project"
+msgstr ""
+
+msgid "Could not delete %{design}. Please try again."
+msgstr ""
+
+msgid "Could not delete chat nickname %{chat_name}."
+msgstr ""
+
+msgid "Could not find design."
+msgstr ""
+
+msgid "Could not remove the trigger."
+msgstr ""
+
+msgid "Could not restore the group"
+msgstr ""
+
+msgid "Could not revoke impersonation token %{token_name}."
+msgstr ""
+
+msgid "Could not revoke personal access token %{personal_access_token_name}."
+msgstr ""
+
+msgid "Could not revoke project access token %{project_access_token_name}."
+msgstr ""
+
+msgid "Could not save group ID"
+msgstr ""
+
+msgid "Could not save project ID"
+msgstr ""
+
+msgid "Could not save prometheus manual configuration"
+msgstr ""
+
+msgid "Could not update the LDAP settings"
+msgstr ""
+
+msgid "Could not upload your designs as one or more files uploaded are not supported."
+msgstr ""
+
+msgid "Country"
+msgstr ""
+
+msgid "Coverage"
+msgstr ""
+
+msgid "Create"
+msgstr ""
+
+msgid "Create %{environment}"
+msgstr ""
+
+msgid "Create %{type}"
+msgstr ""
+
+msgid "Create New Directory"
+msgstr ""
+
+msgid "Create New Domain"
+msgstr ""
+
+msgid "Create Project"
+msgstr ""
+
+msgid "Create a GitLab account first, and then connect it to your %{label} account."
+msgstr ""
+
+msgid "Create a Mattermost team for this group"
+msgstr ""
+
+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 ""
+
+msgid "Create a new branch"
+msgstr ""
+
+msgid "Create a new deploy key for this project"
+msgstr ""
+
+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 ""
+
+msgid "Create a new repository"
+msgstr ""
+
+msgid "Create a personal access token on your account to pull or push via %{protocol}."
+msgstr ""
+
+msgid "Create an account using:"
+msgstr ""
+
+msgid "Create an issue. Issues are created for each alert triggered."
+msgstr ""
+
+msgid "Create and provide your GitHub %{link_start}Personal Access Token%{link_end}. You will need to select the <code>repo</code> scope, so we can display a list of your public and private repositories which are available to import."
+msgstr ""
+
+msgid "Create board"
+msgstr ""
+
+msgid "Create branch"
+msgstr ""
+
+msgid "Create commit"
+msgstr ""
+
+msgid "Create confidential merge request"
+msgstr ""
+
+msgid "Create confidential merge request and branch"
+msgstr ""
+
+msgid "Create directory"
+msgstr ""
+
+msgid "Create empty repository"
+msgstr ""
+
+msgid "Create epic"
+msgstr ""
+
+msgid "Create file"
+msgstr ""
+
+msgid "Create group"
+msgstr ""
+
+msgid "Create group label"
+msgstr ""
+
+msgid "Create issue"
+msgstr ""
+
+msgid "Create iteration"
+msgstr ""
+
+msgid "Create lists from labels. Issues with that label appear in that list."
+msgstr ""
+
+msgid "Create merge request"
+msgstr ""
+
+msgid "Create merge request and branch"
+msgstr ""
+
+msgid "Create milestone"
+msgstr ""
+
+msgid "Create new"
+msgstr ""
+
+msgid "Create new board"
+msgstr ""
+
+msgid "Create new branch"
+msgstr ""
+
+msgid "Create new directory"
+msgstr ""
+
+msgid "Create new file"
+msgstr ""
+
+msgid "Create new file or directory"
+msgstr ""
+
+msgid "Create new label"
+msgstr ""
+
+msgid "Create new..."
+msgstr ""
+
+msgid "Create project"
+msgstr ""
+
+msgid "Create project label"
+msgstr ""
+
+msgid "Create requirement"
+msgstr ""
+
+msgid "Create snippet"
+msgstr ""
+
+msgid "Create wildcard: %{searchTerm}"
+msgstr ""
+
+msgid "Create your first page"
+msgstr ""
+
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
+msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
+msgstr ""
+
+msgid "CreateGroup|You don’t have permission to create groups."
+msgstr ""
+
+msgid "CreateTag|Tag"
+msgstr ""
+
+msgid "CreateTokenToCloneLink|create a personal access token"
+msgstr ""
+
+msgid "Created"
+msgstr ""
+
+msgid "Created %{timestamp}"
+msgstr ""
+
+msgid "Created At"
+msgstr ""
+
+msgid "Created On"
+msgstr ""
+
+msgid "Created a branch and a merge request to resolve this issue."
+msgstr ""
+
+msgid "Created branch '%{branch_name}' and a merge request to resolve this issue."
+msgstr ""
+
+msgid "Created by me"
+msgstr ""
+
+msgid "Created date"
+msgstr ""
+
+msgid "Created issue %{issueLink}"
+msgstr ""
+
+msgid "Created issue %{issueLink} at %{projectLink}"
+msgstr ""
+
+msgid "Created merge request %{mergeRequestLink}"
+msgstr ""
+
+msgid "Created merge request %{mergeRequestLink} at %{projectLink}"
+msgstr ""
+
+msgid "Created on"
+msgstr ""
+
+msgid "Created on:"
+msgstr ""
+
+msgid "Creates a branch and a merge request to resolve this issue."
+msgstr ""
+
+msgid "Creates branch '%{branch_name}' and a merge request to resolve this issue."
+msgstr ""
+
+msgid "Creating epic"
+msgstr ""
+
+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 ""
+
+msgid "Credentials"
+msgstr ""
+
+msgid "CredentialsInventory|No credentials found"
+msgstr ""
+
+msgid "CredentialsInventory|Personal Access Tokens"
+msgstr ""
+
+msgid "CredentialsInventory|SSH Keys"
+msgstr ""
+
+msgid "Critical vulnerabilities present"
+msgstr ""
+
+msgid "Cron Timezone"
+msgstr ""
+
+msgid "Crossplane"
+msgstr ""
+
+msgid "Current Branch"
+msgstr ""
+
+msgid "Current Plan"
+msgstr ""
+
+msgid "Current Project"
+msgstr ""
+
+msgid "Current node"
+msgstr ""
+
+msgid "Current node must be the primary node or you will be locking yourself out"
+msgstr ""
+
+msgid "Current password"
+msgstr ""
+
+msgid "Current vulnerabilities count"
+msgstr ""
+
+msgid "CurrentUser|Buy CI minutes"
+msgstr ""
+
+msgid "CurrentUser|Profile"
+msgstr ""
+
+msgid "CurrentUser|Settings"
+msgstr ""
+
+msgid "CurrentUser|Start a Gold trial"
+msgstr ""
+
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
+msgid "Custom CI configuration path"
+msgstr ""
+
+msgid "Custom Git clone URL for HTTP(S)"
+msgstr ""
+
+msgid "Custom hostname (for private commit emails)"
+msgstr ""
+
+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 %{notification_link}."
+msgstr ""
+
+msgid "Custom project templates"
+msgstr ""
+
+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 ""
+
+msgid "Custom range"
+msgstr ""
+
+msgid "Custom range (UTC)"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Add a stage"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Add stage"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Editing stage"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Enter a name for the stage"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Name"
+msgstr ""
+
+msgid "CustomCycleAnalytics|New stage"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Please select a start event first"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Select start event"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Select stop event"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Stage name already exists"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Start event"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Start event changed, please select a valid stop event"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Start event label"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Stop event"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Stop event label"
+msgstr ""
+
+msgid "CustomCycleAnalytics|Update stage"
+msgstr ""
+
+msgid "Customer Portal"
+msgstr ""
+
+msgid "Customize colors"
+msgstr ""
+
+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 how Google Code 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 ""
+
+msgid "Customize language and region related settings."
+msgstr ""
+
+msgid "Customize name"
+msgstr ""
+
+msgid "Customize your pipeline configuration, view your pipeline status and coverage report."
+msgstr ""
+
+msgid "Customize your pipeline configuration."
+msgstr ""
+
+msgid "Cycle Time"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Issue closed"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Issue created"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Issue first added to a board"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Issue first associated with a milestone"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Issue first associated with a milestone or issue first added to a board"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Issue first mentioned in a commit"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Issue label was added"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Issue label was removed"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Issue last edited"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Merge request closed"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Merge request created"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Merge request first deployed to production"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Merge request label was added"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Merge request label was removed"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Merge request last build finish time"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Merge request last build start time"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Merge request last edited"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Merge request merged"
+msgstr ""
+
+msgid "CycleAnalyticsStage|Code"
+msgstr ""
+
+msgid "CycleAnalyticsStage|Issue"
+msgstr ""
+
+msgid "CycleAnalyticsStage|Plan"
+msgstr ""
+
+msgid "CycleAnalyticsStage|Review"
+msgstr ""
+
+msgid "CycleAnalyticsStage|Staging"
+msgstr ""
+
+msgid "CycleAnalyticsStage|Test"
+msgstr ""
+
+msgid "CycleAnalyticsStage|Total"
+msgstr ""
+
+msgid "CycleAnalyticsStage|is not available for the selected group"
+msgstr ""
+
+msgid "CycleAnalyticsStage|should be under a group"
+msgstr ""
+
+msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
+msgstr ""
+
+msgid "CycleAnalytics|%{stageCount} stages selected"
+msgstr ""
+
+msgid "CycleAnalytics|All stages"
+msgstr ""
+
+msgid "CycleAnalytics|Date"
+msgstr ""
+
+msgid "CycleAnalytics|Days to completion"
+msgstr ""
+
+msgid "CycleAnalytics|Display chart filters"
+msgstr ""
+
+msgid "CycleAnalytics|No stages selected"
+msgstr ""
+
+msgid "CycleAnalytics|Number of tasks"
+msgstr ""
+
+msgid "CycleAnalytics|Only %{maxLabels} labels can be selected at this time"
+msgstr ""
+
+msgid "CycleAnalytics|Project selected"
+msgid_plural "CycleAnalytics|%d projects selected"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "CycleAnalytics|Select labels"
+msgstr ""
+
+msgid "CycleAnalytics|Show"
+msgstr ""
+
+msgid "CycleAnalytics|Showing %{subjectFilterText} and %{selectedLabelsCount} labels"
+msgstr ""
+
+msgid "CycleAnalytics|Showing data for group '%{groupName}' and %{selectedProjectCount} projects from %{startDate} to %{endDate}"
+msgstr ""
+
+msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{startDate} to %{endDate}"
+msgstr ""
+
+msgid "CycleAnalytics|Stages"
+msgstr ""
+
+msgid "CycleAnalytics|Tasks by type"
+msgstr ""
+
+msgid "CycleAnalytics|The given date range is larger than 180 days"
+msgstr ""
+
+msgid "CycleAnalytics|Total days to completion"
+msgstr ""
+
+msgid "CycleAnalytics|Type of work"
+msgstr ""
+
+msgid "CycleAnalytics|group dropdown filter"
+msgstr ""
+
+msgid "CycleAnalytics|not allowed for the given start event"
+msgstr ""
+
+msgid "CycleAnalytics|project dropdown filter"
+msgstr ""
+
+msgid "CycleAnalytics|stage dropdown"
+msgstr ""
+
+msgid "DAG"
+msgstr ""
+
+msgid "DNS"
+msgstr ""
+
+msgid "Dashboard"
+msgstr ""
+
+msgid "DashboardProjects|All"
+msgstr ""
+
+msgid "DashboardProjects|Personal"
+msgstr ""
+
+msgid "DashboardProjects|Trending"
+msgstr ""
+
+msgid "Dashboards"
+msgstr ""
+
+msgid "Dashboard|%{firstProject} and %{secondProject}"
+msgstr ""
+
+msgid "Dashboard|%{firstProject}, %{rest}, and %{secondProject}"
+msgstr ""
+
+msgid "Dashboard|Unable to add %{invalidProjects}. This dashboard is available for public projects, and private projects in groups with a Silver plan."
+msgstr ""
+
+msgid "Data is still calculating..."
+msgstr ""
+
+msgid "Date"
+msgstr ""
+
+msgid "Date picker"
+msgstr ""
+
+msgid "Date range cannot exceed %{maxDateRange} days."
+msgstr ""
+
+msgid "Day of month"
+msgstr ""
+
+msgid "DayTitle|F"
+msgstr ""
+
+msgid "DayTitle|M"
+msgstr ""
+
+msgid "DayTitle|S"
+msgstr ""
+
+msgid "DayTitle|W"
+msgstr ""
+
+msgid "Days"
+msgstr ""
+
+msgid "Days to merge"
+msgstr ""
+
+msgid "Debug"
+msgstr ""
+
+msgid "Dec"
+msgstr ""
+
+msgid "December"
+msgstr ""
+
+msgid "Decline"
+msgstr ""
+
+msgid "Decline and sign out"
+msgstr ""
+
+msgid "Default Branch"
+msgstr ""
+
+msgid "Default CI configuration path"
+msgstr ""
+
+msgid "Default artifacts expiration"
+msgstr ""
+
+msgid "Default branch"
+msgstr ""
+
+msgid "Default branch and protected branches"
+msgstr ""
+
+msgid "Default classification label"
+msgstr ""
+
+msgid "Default dashboard"
+msgstr ""
+
+msgid "Default deletion adjourned period"
+msgstr ""
+
+msgid "Default description template for issues"
+msgstr ""
+
+msgid "Default description template for merge requests"
+msgstr ""
+
+msgid "Default first day of the week"
+msgstr ""
+
+msgid "Default first day of the week in calendars and date pickers."
+msgstr ""
+
+msgid "Default issue template"
+msgstr ""
+
+msgid "Default project deletion protection"
+msgstr ""
+
+msgid "Default projects limit"
+msgstr ""
+
+msgid "Default stages"
+msgstr ""
+
+msgid "Default: Directly import the Google Code email address or username"
+msgstr ""
+
+msgid "Default: Map a FogBugz account ID to a full name"
+msgstr ""
+
+msgid "Define a custom pattern with cron syntax"
+msgstr ""
+
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
+msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
+msgstr ""
+
+msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise 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 it's timer finishes."
+msgstr ""
+
+msgid "DelayedJobs|Start now"
+msgstr ""
+
+msgid "DelayedJobs|Unschedule"
+msgstr ""
+
+msgid "DelayedJobs|delayed"
+msgstr ""
+
+msgid "Delete"
+msgstr ""
+
+msgid "Delete Comment"
+msgstr ""
+
+msgid "Delete Package"
+msgstr ""
+
+msgid "Delete Snippet"
+msgstr ""
+
+msgid "Delete artifacts"
+msgstr ""
+
+msgid "Delete board"
+msgstr ""
+
+msgid "Delete comment"
+msgstr ""
+
+msgid "Delete domain"
+msgstr ""
+
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
+msgid "Delete license"
+msgstr ""
+
+msgid "Delete list"
+msgstr ""
+
+msgid "Delete pipeline"
+msgstr ""
+
+msgid "Delete project"
+msgstr ""
+
+msgid "Delete serverless domain?"
+msgstr ""
+
+msgid "Delete snippet"
+msgstr ""
+
+msgid "Delete snippet?"
+msgstr ""
+
+msgid "Delete source branch"
+msgstr ""
+
+msgid "Delete this attachment"
+msgstr ""
+
+msgid "Delete variable"
+msgstr ""
+
+msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
+msgstr ""
+
+msgid "DeleteProject|Failed to remove project snippets. Please try again or contact administrator."
+msgstr ""
+
+msgid "DeleteProject|Failed to remove some tags in project container registry. Please try again or contact administrator."
+msgstr ""
+
+msgid "DeleteProject|Failed to remove wiki repository. Please try again or contact administrator."
+msgstr ""
+
+msgid "DeleteProject|Failed to restore project repository. Please contact the administrator."
+msgstr ""
+
+msgid "DeleteProject|Failed to restore wiki repository. Please contact the administrator."
+msgstr ""
+
+msgid "Deleted"
+msgstr ""
+
+msgid "Deleted chat nickname: %{chat_name}!"
+msgstr ""
+
+msgid "Deleted in this version"
+msgstr ""
+
+msgid "Deleting"
+msgstr ""
+
+msgid "Deleting the license failed."
+msgstr ""
+
+msgid "Deleting the license failed. The license was not found."
+msgstr ""
+
+msgid "Deleting the license failed. You are not permitted to perform this action."
+msgstr ""
+
+msgid "Deletion pending. This project will be removed on %{date}. Repository and other project resources are read-only."
+msgstr ""
+
+msgid "Denied authorization of chat nickname %{user_name}."
+msgstr ""
+
+msgid "Deny"
+msgstr ""
+
+msgid "Dependencies"
+msgstr ""
+
+msgid "Dependencies help page link"
+msgstr ""
+
+msgid "Dependencies|%d additional vulnerability not shown"
+msgid_plural "Dependencies|%d additional vulnerabilities not shown"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Dependencies|%d vulnerability detected"
+msgid_plural "Dependencies|%d vulnerabilities detected"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Dependencies|%{remainingLicensesCount} more"
+msgstr ""
+
+msgid "Dependencies|All"
+msgstr ""
+
+msgid "Dependencies|Based on the %{linkStart}latest successful%{linkEnd} scan"
+msgstr ""
+
+msgid "Dependencies|Component"
+msgstr ""
+
+msgid "Dependencies|Component name"
+msgstr ""
+
+msgid "Dependencies|Export as JSON"
+msgstr ""
+
+msgid "Dependencies|Job failed to generate the dependency list"
+msgstr ""
+
+msgid "Dependencies|License"
+msgstr ""
+
+msgid "Dependencies|Location"
+msgstr ""
+
+msgid "Dependencies|Packager"
+msgstr ""
+
+msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
+msgstr ""
+
+msgid "Dependencies|Toggle vulnerability list"
+msgstr ""
+
+msgid "Dependencies|Unsupported file(s) detected"
+msgstr ""
+
+msgid "Dependencies|Vulnerable components"
+msgstr ""
+
+msgid "Dependency List"
+msgstr ""
+
+msgid "Dependency List has no entries"
+msgstr ""
+
+msgid "Dependency Proxy"
+msgstr ""
+
+msgid "Dependency Scanning"
+msgstr ""
+
+msgid "Dependency proxy"
+msgstr ""
+
+msgid "Dependency proxy URL"
+msgstr ""
+
+msgid "Dependency proxy feature is limited to public groups for now."
+msgstr ""
+
+msgid "DependencyProxy|Toggle Dependency Proxy"
+msgstr ""
+
+msgid "Depends on %d merge request being merged"
+msgid_plural "Depends on %d merge requests being merged"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Depends on <strong>%d closed</strong> merge request."
+msgid_plural "Depends on <strong>%d closed</strong> merge requests."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Deploy"
+msgid_plural "Deploys"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Deploy Keys"
+msgstr ""
+
+msgid "Deploy key was successfully updated."
+msgstr ""
+
+msgid "Deploy keys allow read-only or read-write (if enabled) access to your repository. Deploy keys can be used for CI, staging or production servers. You can create a deploy key or add an existing one."
+msgstr ""
+
+msgid "Deploy progress not found. To see pods, ensure your environment matches %{linkStart}deploy board criteria%{linkEnd}."
+msgstr ""
+
+msgid "Deploy to..."
+msgstr ""
+
+msgid "DeployBoard|Matching on the %{appLabel} label has been removed for deploy boards. To see all instances on your board, you must update your chart and redeploy."
+msgstr ""
+
+msgid "DeployKeys|+%{count} others"
+msgstr ""
+
+msgid "DeployKeys|Current project"
+msgstr ""
+
+msgid "DeployKeys|Deploy key"
+msgstr ""
+
+msgid "DeployKeys|Enabled deploy keys"
+msgstr ""
+
+msgid "DeployKeys|Error enabling deploy key"
+msgstr ""
+
+msgid "DeployKeys|Error getting deploy keys"
+msgstr ""
+
+msgid "DeployKeys|Error removing deploy key"
+msgstr ""
+
+msgid "DeployKeys|Expand %{count} other projects"
+msgstr ""
+
+msgid "DeployKeys|Loading deploy keys"
+msgstr ""
+
+msgid "DeployKeys|No deploy keys found. Create one with the form above."
+msgstr ""
+
+msgid "DeployKeys|Privately accessible deploy keys"
+msgstr ""
+
+msgid "DeployKeys|Project usage"
+msgstr ""
+
+msgid "DeployKeys|Publicly accessible deploy keys"
+msgstr ""
+
+msgid "DeployKeys|Read access only"
+msgstr ""
+
+msgid "DeployKeys|Write access allowed"
+msgstr ""
+
+msgid "DeployKeys|You are going to remove this deploy key. Are you sure?"
+msgstr ""
+
+msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
+msgstr ""
+
+msgid "DeployTokens|Add a deploy token"
+msgstr ""
+
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
+msgid "DeployTokens|Allows read-only access to the registry images"
+msgstr ""
+
+msgid "DeployTokens|Allows read-only access to the repository"
+msgstr ""
+
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
+msgid "DeployTokens|Allows write access to the registry images"
+msgstr ""
+
+msgid "DeployTokens|Copy deploy token"
+msgstr ""
+
+msgid "DeployTokens|Copy username"
+msgstr ""
+
+msgid "DeployTokens|Create deploy token"
+msgstr ""
+
+msgid "DeployTokens|Created"
+msgstr ""
+
+msgid "DeployTokens|Default format is \"gitlab+deploy-token-{n}\". Enter custom username if you want to change it."
+msgstr ""
+
+msgid "DeployTokens|Deploy Tokens"
+msgstr ""
+
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
+msgstr ""
+
+msgid "DeployTokens|Expires"
+msgstr ""
+
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
+msgstr ""
+
+msgid "DeployTokens|Name"
+msgstr ""
+
+msgid "DeployTokens|Pick a name for the application, and we'll give you a unique deploy token."
+msgstr ""
+
+msgid "DeployTokens|Revoke"
+msgstr ""
+
+msgid "DeployTokens|Revoke %{b_start}%{name}%{b_end}?"
+msgstr ""
+
+msgid "DeployTokens|Revoke %{name}"
+msgstr ""
+
+msgid "DeployTokens|Scopes"
+msgstr ""
+
+msgid "DeployTokens|This %{entity_type} has no active Deploy Tokens."
+msgstr ""
+
+msgid "DeployTokens|This action cannot be undone."
+msgstr ""
+
+msgid "DeployTokens|Use this token as a password. Make sure you save it - you won't be able to access it again."
+msgstr ""
+
+msgid "DeployTokens|Use this username as a login."
+msgstr ""
+
+msgid "DeployTokens|Username"
+msgstr ""
+
+msgid "DeployTokens|You are about to revoke %{b_start}%{name}%{b_end}."
+msgstr ""
+
+msgid "DeployTokens|Your New Deploy Token"
+msgstr ""
+
+msgid "DeployTokens|Your new group deploy token has been created."
+msgstr ""
+
+msgid "DeployTokens|Your new project deploy token has been created."
+msgstr ""
+
+msgid "Deployed"
+msgstr ""
+
+msgid "Deployed to"
+msgstr ""
+
+msgid "Deploying to"
+msgstr ""
+
+msgid "Deployment Frequency"
+msgstr ""
+
+msgid "Deployment|API"
+msgstr ""
+
+msgid "Deployment|This deployment was created using the API"
+msgstr ""
+
+msgid "Deployment|canceled"
+msgstr ""
+
+msgid "Deployment|created"
+msgstr ""
+
+msgid "Deployment|failed"
+msgstr ""
+
+msgid "Deployment|running"
+msgstr ""
+
+msgid "Deployment|success"
+msgstr ""
+
+msgid "Deprioritize label"
+msgstr ""
+
+msgid "Descending"
+msgstr ""
+
+msgid "Describe the goal of the changes and what reviewers should be aware of."
+msgstr ""
+
+msgid "Describe the requirement here"
+msgstr ""
+
+msgid "Description"
+msgstr ""
+
+msgid "Description parsed with %{link_start}GitLab Flavored Markdown%{link_end}"
+msgstr ""
+
+msgid "Description templates allow you to define context-specific templates for issue and merge request description fields for your project."
+msgstr ""
+
+msgid "Description:"
+msgstr ""
+
+msgid "Descriptive label"
+msgstr ""
+
+msgid "Deselect all"
+msgstr ""
+
+msgid "Design Management files and data"
+msgstr ""
+
+msgid "DesignManagement|%{current_design} of %{designs_count}"
+msgstr ""
+
+msgid "DesignManagement|%{filename} did not change."
+msgstr ""
+
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgstr ""
+
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
+msgstr ""
+
+msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
+msgstr ""
+
+msgid "DesignManagement|Are you sure you want to delete the selected designs?"
+msgstr ""
+
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
+msgid "DesignManagement|Cancel comment confirmation"
+msgstr ""
+
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
+msgid "DesignManagement|Could not add a new comment. Please try again."
+msgstr ""
+
+msgid "DesignManagement|Could not create new discussion. Please try again."
+msgstr ""
+
+msgid "DesignManagement|Could not update discussion. Please try again."
+msgstr ""
+
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
+msgid "DesignManagement|Delete"
+msgstr ""
+
+msgid "DesignManagement|Delete designs confirmation"
+msgstr ""
+
+msgid "DesignManagement|Delete selected"
+msgstr ""
+
+msgid "DesignManagement|Deselect all"
+msgstr ""
+
+msgid "DesignManagement|Discard comment"
+msgstr ""
+
+msgid "DesignManagement|Error uploading a new design. Please try again."
+msgstr ""
+
+msgid "DesignManagement|Go back to designs"
+msgstr ""
+
+msgid "DesignManagement|Go to next design"
+msgstr ""
+
+msgid "DesignManagement|Go to previous design"
+msgstr ""
+
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
+msgid "DesignManagement|Keep comment"
+msgstr ""
+
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
+msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
+msgstr ""
+
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
+msgid "DesignManagement|Select all"
+msgstr ""
+
+msgid "DesignManagement|The maximum number of designs allowed to be uploaded is %{upload_limit}. Please try again."
+msgstr ""
+
+msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
+msgstr ""
+
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
+msgid "DesignManagement|Upload skipped."
+msgstr ""
+
+msgid "DesignManagement|and %{moreCount} more."
+msgstr ""
+
+msgid "Designs"
+msgstr ""
+
+msgid "Destroy"
+msgstr ""
+
+msgid "Detail"
+msgstr ""
+
+msgid "Details"
+msgstr ""
+
+msgid "Details (default)"
+msgstr ""
+
+msgid "Detect host keys"
+msgstr ""
+
+msgid "DevOps Score"
+msgstr ""
+
+msgid "Diff content limits"
+msgstr ""
+
+msgid "Diff limits"
+msgstr ""
+
+msgid "Difference between start date and now"
+msgstr ""
+
+msgid "DiffsCompareBaseBranch|(HEAD)"
+msgstr ""
+
+msgid "DiffsCompareBaseBranch|(base)"
+msgstr ""
+
+msgid "Diffs|No file name available"
+msgstr ""
+
+msgid "Diffs|Show unchanged lines"
+msgstr ""
+
+msgid "Diffs|Something went wrong while fetching diff lines."
+msgstr ""
+
+msgid "Direction"
+msgstr ""
+
+msgid "Directory name"
+msgstr ""
+
+msgid "Disable"
+msgstr ""
+
+msgid "Disable for this project"
+msgstr ""
+
+msgid "Disable group Runners"
+msgstr ""
+
+msgid "Disable public access to Pages sites"
+msgstr ""
+
+msgid "Disable shared Runners"
+msgstr ""
+
+msgid "Disable two-factor authentication"
+msgstr ""
+
+msgid "Disabled"
+msgstr ""
+
+msgid "Disabled mirrors can only be enabled by instance owners. It is recommended that you delete them."
+msgstr ""
+
+msgid "Discard all changes"
+msgstr ""
+
+msgid "Discard all changes?"
+msgstr ""
+
+msgid "Discard changes"
+msgstr ""
+
+msgid "Discard changes to %{path}?"
+msgstr ""
+
+msgid "Discard draft"
+msgstr ""
+
+msgid "Discard review"
+msgstr ""
+
+msgid "DiscordService|Discord Notifications"
+msgstr ""
+
+msgid "DiscordService|Receive event notifications in Discord"
+msgstr ""
+
+msgid "Discover GitLab Geo"
+msgstr ""
+
+msgid "Discover projects, groups and snippets. Share your projects with others"
+msgstr ""
+
+msgid "Discover|Check your application for security vulnerabilities that may lead to unauthorized access, data leaks, and denial of services."
+msgstr ""
+
+msgid "Discover|For code that's already live in production, our dashboards give you an easy way to prioritize any issues that are found, empowering your team to ship quickly and securely."
+msgstr ""
+
+msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
+msgstr ""
+
+msgid "Discover|Give feedback for this page"
+msgstr ""
+
+msgid "Discover|Security capabilities, integrated into your development lifecycle"
+msgstr ""
+
+msgid "Discover|See the other features of the %{linkStart}gold plan%{linkEnd}"
+msgstr ""
+
+msgid "Discover|Start a free trial"
+msgstr ""
+
+msgid "Discover|Upgrade now"
+msgstr ""
+
+msgid "Discuss a specific suggestion or question"
+msgstr ""
+
+msgid "Discuss a specific suggestion or question that needs to be resolved"
+msgstr ""
+
+msgid "Discuss a specific suggestion or question that needs to be resolved."
+msgstr ""
+
+msgid "Discuss a specific suggestion or question."
+msgstr ""
+
+msgid "Discussion"
+msgstr ""
+
+msgid "Discussion to reply to cannot be found"
+msgstr ""
+
+msgid "Disk Usage"
+msgstr ""
+
+msgid "Dismiss"
+msgstr ""
+
+msgid "Dismiss %d selected vulnerability as"
+msgid_plural "Dismiss %d selected vulnerabilities as"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Dismiss DevOps Score introduction"
+msgstr ""
+
+msgid "Dismiss Merge Request promotion"
+msgstr ""
+
+msgid "Dismiss Selected"
+msgstr ""
+
+msgid "Dismiss Value Stream Analytics introduction box"
+msgstr ""
+
+msgid "Dismiss trial promotion"
+msgstr ""
+
+msgid "Dismissable"
+msgstr ""
+
+msgid "Dismissed"
+msgstr ""
+
+msgid "Dismissed at %{projectLink}"
+msgstr ""
+
+msgid "Dismissed on pipeline %{pipelineLink}"
+msgstr ""
+
+msgid "Dismissed on pipeline %{pipelineLink} at %{projectLink}"
+msgstr ""
+
+msgid "Display name"
+msgstr ""
+
+msgid "Display rendered file"
+msgstr ""
+
+msgid "Display source"
+msgstr ""
+
+msgid "Do not display offers from third parties within GitLab"
+msgstr ""
+
+msgid "Do you want to customize how Google Code email addresses and usernames are imported into GitLab?"
+msgstr ""
+
+msgid "Dockerfile"
+msgstr ""
+
+msgid "Documentation"
+msgstr ""
+
+msgid "Documentation for popular identity providers"
+msgstr ""
+
+msgid "Doing"
+msgstr ""
+
+msgid "Domain"
+msgstr ""
+
+msgid "Domain cannot be deleted while associated to one or more clusters."
+msgstr ""
+
+msgid "Domain verification is an essential security measure for public GitLab sites. Users are required to demonstrate they control a domain before it is enabled"
+msgstr ""
+
+msgid "Domain was successfully created."
+msgstr ""
+
+msgid "Domain was successfully deleted."
+msgstr ""
+
+msgid "Domain was successfully updated."
+msgstr ""
+
+msgid "Don't have an account yet?"
+msgstr ""
+
+msgid "Don't include description in commit message"
+msgstr ""
+
+msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
+msgstr ""
+
+msgid "Don't show again"
+msgstr ""
+
+msgid "Don't worry, you can access this tour by clicking on the help icon in the top right corner and choose <strong>Learn GitLab</strong>."
+msgstr ""
+
+msgid "Done"
+msgstr ""
+
+msgid "Download"
+msgstr ""
+
+msgid "Download %{format}"
+msgstr ""
+
+msgid "Download %{format}:"
+msgstr ""
+
+msgid "Download CSV"
+msgstr ""
+
+msgid "Download artifacts"
+msgstr ""
+
+msgid "Download as"
+msgstr ""
+
+msgid "Download asset"
+msgstr ""
+
+msgid "Download codes"
+msgstr ""
+
+msgid "Download evidence JSON"
+msgstr ""
+
+msgid "Download export"
+msgstr ""
+
+msgid "Download image"
+msgstr ""
+
+msgid "Download license"
+msgstr ""
+
+msgid "Download raw data (.csv)"
+msgstr ""
+
+msgid "Download source code"
+msgstr ""
+
+msgid "Download this directory"
+msgstr ""
+
+msgid "DownloadCommit|Email Patches"
+msgstr ""
+
+msgid "DownloadCommit|Plain Diff"
+msgstr ""
+
+msgid "DownloadSource|Download"
+msgstr ""
+
+msgid "Downstream"
+msgstr ""
+
+msgid "Downvotes"
+msgstr ""
+
+msgid "Drop your designs to start your upload."
+msgstr ""
+
+msgid "Due Date"
+msgstr ""
+
+msgid "Due date"
+msgstr ""
+
+msgid "Duration"
+msgstr ""
+
+msgid "Duration for the last 30 commits"
+msgstr ""
+
+msgid "During this process, you’ll be asked for URLs from GitLab’s side. Use the URLs shown below."
+msgstr ""
+
+msgid "Dynamic Application Security Testing (DAST)"
+msgstr ""
+
+msgid "Each Runner can be in one of the following states and/or belong to one of the following types:"
+msgstr ""
+
+msgid "Each Runner can be in one of the following states:"
+msgstr ""
+
+msgid "Edit"
+msgstr ""
+
+msgid "Edit %{issuable}"
+msgstr ""
+
+msgid "Edit %{name}"
+msgstr ""
+
+msgid "Edit Comment"
+msgstr ""
+
+msgid "Edit Deploy Key"
+msgstr ""
+
+msgid "Edit Geo Node"
+msgstr ""
+
+msgid "Edit Group Hook"
+msgstr ""
+
+msgid "Edit Label"
+msgstr ""
+
+msgid "Edit Milestone"
+msgstr ""
+
+msgid "Edit Password"
+msgstr ""
+
+msgid "Edit Pipeline Schedule %{id}"
+msgstr ""
+
+msgid "Edit Release"
+msgstr ""
+
+msgid "Edit Snippet"
+msgstr ""
+
+msgid "Edit System Hook"
+msgstr ""
+
+msgid "Edit application"
+msgstr ""
+
+msgid "Edit board"
+msgstr ""
+
+msgid "Edit comment"
+msgstr ""
+
+msgid "Edit dashboard"
+msgstr ""
+
+msgid "Edit description"
+msgstr ""
+
+msgid "Edit environment"
+msgstr ""
+
+msgid "Edit file"
+msgstr ""
+
+msgid "Edit files in the editor and commit changes here"
+msgstr ""
+
+msgid "Edit group: %{group_name}"
+msgstr ""
+
+msgid "Edit identity for %{user_name}"
+msgstr ""
+
+msgid "Edit issues"
+msgstr ""
+
+msgid "Edit public deploy key"
+msgstr ""
+
+msgid "Edit stage"
+msgstr ""
+
+msgid "Edit this release"
+msgstr ""
+
+msgid "Edit wiki page"
+msgstr ""
+
+msgid "Edit your most recent comment in a thread (from an empty textarea)"
+msgstr ""
+
+msgid "Edited %{timeago}"
+msgstr ""
+
+msgid "Editing"
+msgstr ""
+
+msgid "Elasticsearch"
+msgstr ""
+
+msgid "Elasticsearch AWS IAM credentials"
+msgstr ""
+
+msgid "Elasticsearch indexing restrictions"
+msgstr ""
+
+msgid "Elasticsearch indexing started"
+msgstr ""
+
+msgid "Elasticsearch integration. Elasticsearch AWS IAM."
+msgstr ""
+
+msgid "Elasticsearch returned status code: %{status_code}"
+msgstr ""
+
+msgid "Elastic|None. Select namespaces to index."
+msgstr ""
+
+msgid "Elastic|None. Select projects to index."
+msgstr ""
+
+msgid "Email"
+msgstr ""
+
+msgid "Email address"
+msgstr ""
+
+msgid "Email could not be sent"
+msgstr ""
+
+msgid "Email display name"
+msgstr ""
+
+msgid "Email not verified. Please verify your email in Salesforce."
+msgstr ""
+
+msgid "Email patch"
+msgstr ""
+
+msgid "Email restrictions"
+msgstr ""
+
+msgid "Email restrictions for sign-ups"
+msgstr ""
+
+msgid "Email sent"
+msgstr ""
+
+msgid "Email the pipelines status to a list of recipients."
+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 ""
+
+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 ""
+
+msgid "EmailError|We couldn't figure out what the email is for. Please create your issue or comment through the web interface."
+msgstr ""
+
+msgid "EmailError|We couldn't figure out what the email is in reply to. Please create your comment through the web interface."
+msgstr ""
+
+msgid "EmailError|We couldn't figure out what user corresponds to the email. Please create your comment through the web interface."
+msgstr ""
+
+msgid "EmailError|We couldn't find the project. Please check if there's any typo."
+msgstr ""
+
+msgid "EmailError|You are not allowed to perform this action. If you believe this is in error, contact a staff member."
+msgstr ""
+
+msgid "EmailError|Your account has been blocked. If you believe this is in error, contact a staff member."
+msgstr ""
+
+msgid "EmailToken|reset it"
+msgstr ""
+
+msgid "EmailToken|resetting..."
+msgstr ""
+
+msgid "Emails"
+msgstr ""
+
+msgid "Emails sent from Service Desk will have this name"
+msgstr ""
+
+msgid "Emails separated by comma"
+msgstr ""
+
+msgid "EmailsOnPushService|Disable code diffs"
+msgstr ""
+
+msgid "EmailsOnPushService|Don't include possibly sensitive code diffs in notification body."
+msgstr ""
+
+msgid "EmailsOnPushService|Email the commits and diff of each push to a list of recipients."
+msgstr ""
+
+msgid "EmailsOnPushService|Emails on push"
+msgstr ""
+
+msgid "EmailsOnPushService|Emails separated by whitespace"
+msgstr ""
+
+msgid "EmailsOnPushService|Send from committer"
+msgstr ""
+
+msgid "EmailsOnPushService|Send notifications from the committer's email address if the domain is part of the domain GitLab is running on (e.g. %{domains})."
+msgstr ""
+
+msgid "Embed"
+msgstr ""
+
+msgid "Empty file"
+msgstr ""
+
+msgid "Enable"
+msgstr ""
+
+msgid "Enable Auto DevOps"
+msgstr ""
+
+msgid "Enable HTML emails"
+msgstr ""
+
+msgid "Enable Incident Management inbound alert limit"
+msgstr ""
+
+msgid "Enable PlantUML"
+msgstr ""
+
+msgid "Enable Pseudonymizer data collection"
+msgstr ""
+
+msgid "Enable SAML authentication for this group"
+msgstr ""
+
+msgid "Enable Seat Link"
+msgstr ""
+
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
+msgid "Enable access to Grafana"
+msgstr ""
+
+msgid "Enable access to the Performance Bar for a given group."
+msgstr ""
+
+msgid "Enable and configure Grafana."
+msgstr ""
+
+msgid "Enable and configure Prometheus metrics."
+msgstr ""
+
+msgid "Enable classification control using an external service"
+msgstr ""
+
+msgid "Enable container expiration and retention policies for projects created earlier than GitLab 12.7."
+msgstr ""
+
+msgid "Enable email restrictions for sign ups"
+msgstr ""
+
+msgid "Enable error tracking"
+msgstr ""
+
+msgid "Enable feature to choose access level"
+msgstr ""
+
+msgid "Enable for this project"
+msgstr ""
+
+msgid "Enable group Runners"
+msgstr ""
+
+msgid "Enable header and footer in emails"
+msgstr ""
+
+msgid "Enable integration"
+msgstr ""
+
+msgid "Enable maintenance mode"
+msgstr ""
+
+msgid "Enable mirror configuration"
+msgstr ""
+
+msgid "Enable or disable Seat Link."
+msgstr ""
+
+msgid "Enable or disable keyboard shortcuts"
+msgstr ""
+
+msgid "Enable or disable the Pseudonymizer data collection."
+msgstr ""
+
+msgid "Enable or disable version check and usage ping."
+msgstr ""
+
+msgid "Enable protected paths rate limit"
+msgstr ""
+
+msgid "Enable proxy"
+msgstr ""
+
+msgid "Enable reCAPTCHA or Akismet and set IP limits. For reCAPTCHA, we currently only support %{recaptcha_v2_link_start}v2%{recaptcha_v2_link_end}"
+msgstr ""
+
+msgid "Enable shared Runners"
+msgstr ""
+
+msgid "Enable snowplow tracking"
+msgstr ""
+
+msgid "Enable two-factor authentication"
+msgstr ""
+
+msgid "Enable usage ping"
+msgstr ""
+
+msgid "Enable usage ping to get an overview of how you are using GitLab from a feature perspective."
+msgstr ""
+
+msgid "Enable/disable your service desk. %{link_start}Learn more about service desk%{link_end}."
+msgstr ""
+
+msgid "EnableReviewApp|%{stepStart}Step 1%{stepEnd}. Ensure you have Kubernetes set up and have a base domain for your %{linkStart}cluster%{linkEnd}."
+msgstr ""
+
+msgid "EnableReviewApp|%{stepStart}Step 2%{stepEnd}. Copy the following snippet:"
+msgstr ""
+
+msgid "EnableReviewApp|%{stepStart}Step 3%{stepEnd}. Add it to the project %{linkStart}gitlab-ci.yml%{linkEnd} file."
+msgstr ""
+
+msgid "EnableReviewApp|Close"
+msgstr ""
+
+msgid "EnableReviewApp|Copy snippet text"
+msgstr ""
+
+msgid "Enabled"
+msgstr ""
+
+msgid "Enabled Git access protocols"
+msgstr ""
+
+msgid "Enabled sources for code import during project creation. OmniAuth must be configured for GitHub"
+msgstr ""
+
+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 ""
+
+msgid "Encountered an error while rendering: %{err}"
+msgstr ""
+
+msgid "End date"
+msgstr ""
+
+msgid "Ends at (UTC)"
+msgstr ""
+
+msgid "Enforce DNS rebinding attack protection"
+msgstr ""
+
+msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
+msgstr ""
+
+msgid "Ensure your %{linkStart}environment is part of the deploy stage%{linkEnd} of your CI pipeline to track deployments to your cluster."
+msgstr ""
+
+msgid "Enter 2FA for Admin Mode"
+msgstr ""
+
+msgid "Enter Admin Mode"
+msgstr ""
+
+msgid "Enter IP address range"
+msgstr ""
+
+msgid "Enter a number"
+msgstr ""
+
+msgid "Enter a whole number between 0 and 100"
+msgstr ""
+
+msgid "Enter at least three characters to search"
+msgstr ""
+
+msgid "Enter board name"
+msgstr ""
+
+msgid "Enter domain"
+msgstr ""
+
+msgid "Enter in your Bitbucket Server URL and personal access token below"
+msgstr ""
+
+msgid "Enter in your Phabricator Server URL and personal access token below"
+msgstr ""
+
+msgid "Enter merge request URLs"
+msgstr ""
+
+msgid "Enter new %{field_title}"
+msgstr ""
+
+msgid "Enter new AWS Secret Access Key"
+msgstr ""
+
+msgid "Enter number of issues"
+msgstr ""
+
+msgid "Enter one or more user ID separated by commas"
+msgstr ""
+
+msgid "Enter the code from the two-factor app on your mobile device. If you've lost your device, you may enter one of your recovery codes."
+msgstr ""
+
+msgid "Enter the issue description"
+msgstr ""
+
+msgid "Enter the issue title"
+msgstr ""
+
+msgid "Enter the merge request description"
+msgstr ""
+
+msgid "Enter the merge request title"
+msgstr ""
+
+msgid "Enter the name of your application, and we'll return a unique %{type}."
+msgstr ""
+
+msgid "Enter your password to approve"
+msgstr ""
+
+msgid "Environment"
+msgstr ""
+
+msgid "Environment does not have deployments"
+msgstr ""
+
+msgid "Environment scope"
+msgstr ""
+
+msgid "Environment variables are applied to environments via the runner. They can be protected by only exposing them to protected branches or tags. Additionally, they can be masked so they are hidden in job logs, though they must match certain regexp requirements to do so. You can use environment variables for passwords, secret keys, or whatever you want."
+msgstr ""
+
+msgid "Environment variables are configured by your administrator to be %{link_start}protected%{link_end} by default"
+msgstr ""
+
+msgid "Environment:"
+msgstr ""
+
+msgid "EnvironmentDashboard|API"
+msgstr ""
+
+msgid "EnvironmentDashboard|Created through the Deployment API"
+msgstr ""
+
+msgid "EnvironmentDashboard|You are looking at the last updated environment"
+msgstr ""
+
+msgid "Environments"
+msgstr ""
+
+msgid "Environments Dashboard"
+msgstr ""
+
+msgid "Environments allow you to track deployments of your application %{link_to_read_more}."
+msgstr ""
+
+msgid "Environments in %{name}"
+msgstr ""
+
+msgid "EnvironmentsDashboard|Add a project to the dashboard"
+msgstr ""
+
+msgid "EnvironmentsDashboard|Add projects"
+msgstr ""
+
+msgid "EnvironmentsDashboard|Environments Dashboard"
+msgstr ""
+
+msgid "EnvironmentsDashboard|Job: %{job}"
+msgstr ""
+
+msgid "EnvironmentsDashboard|More actions"
+msgstr ""
+
+msgid "EnvironmentsDashboard|More information"
+msgstr ""
+
+msgid "EnvironmentsDashboard|Remove"
+msgstr ""
+
+msgid "EnvironmentsDashboard|The environments dashboard provides a summary of each project's environments' status, including pipeline and alert statuses."
+msgstr ""
+
+msgid "EnvironmentsDashboard|This dashboard displays a maximum of 7 projects and 3 environments per project. %{readMoreLink}"
+msgstr ""
+
+msgid "Environments|An error occurred while canceling the auto stop, please try again"
+msgstr ""
+
+msgid "Environments|An error occurred while deleting the environment. Check if the environment stopped; if not, stop it and try again."
+msgstr ""
+
+msgid "Environments|An error occurred while fetching the environments."
+msgstr ""
+
+msgid "Environments|An error occurred while making the request."
+msgstr ""
+
+msgid "Environments|An error occurred while re-deploying the environment, please try again"
+msgstr ""
+
+msgid "Environments|An error occurred while rolling back the environment, please try again"
+msgstr ""
+
+msgid "Environments|An error occurred while stopping the environment, please try again"
+msgstr ""
+
+msgid "Environments|Are you sure you want to stop this environment?"
+msgstr ""
+
+msgid "Environments|Auto stop in"
+msgstr ""
+
+msgid "Environments|Auto stops %{auto_stop_time}"
+msgstr ""
+
+msgid "Environments|Commit"
+msgstr ""
+
+msgid "Environments|Currently showing %{fetched} results."
+msgstr ""
+
+msgid "Environments|Currently showing all results."
+msgstr ""
+
+msgid "Environments|Delete"
+msgstr ""
+
+msgid "Environments|Delete environment"
+msgstr ""
+
+msgid "Environments|Deleting the '%{environmentName}' environment cannot be undone. Do you want to delete it anyway?"
+msgstr ""
+
+msgid "Environments|Deploy to..."
+msgstr ""
+
+msgid "Environments|Deployment"
+msgstr ""
+
+msgid "Environments|Enable review app"
+msgstr ""
+
+msgid "Environments|Environment"
+msgstr ""
+
+msgid "Environments|Environments"
+msgstr ""
+
+msgid "Environments|Environments are places where code gets deployed, such as staging or production."
+msgstr ""
+
+msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
+msgstr ""
+
+msgid "Environments|Job"
+msgstr ""
+
+msgid "Environments|Learn about environments"
+msgstr ""
+
+msgid "Environments|Learn more about stopping environments"
+msgstr ""
+
+msgid "Environments|Logs from %{start} to %{end}."
+msgstr ""
+
+msgid "Environments|New environment"
+msgstr ""
+
+msgid "Environments|No deployed environments"
+msgstr ""
+
+msgid "Environments|No deployments yet"
+msgstr ""
+
+msgid "Environments|No pod selected"
+msgstr ""
+
+msgid "Environments|No pods to display"
+msgstr ""
+
+msgid "Environments|Note that this action will stop the environment, but it will %{emphasisStart}not%{emphasisEnd} have an effect on any existing deployment due to no “stop environment action†being defined in the %{ciConfigLinkStart}.gitlab-ci.yml%{ciConfigLinkEnd} file."
+msgstr ""
+
+msgid "Environments|Note that this action will stop the environment, but it will %{emphasis_start}not%{emphasis_end} have an effect on any existing deployment due to no “stop environment action†being defined in the %{ci_config_link_start}.gitlab-ci.yml%{ci_config_link_end} file."
+msgstr ""
+
+msgid "Environments|Open live environment"
+msgstr ""
+
+msgid "Environments|Pod name"
+msgstr ""
+
+msgid "Environments|Re-deploy"
+msgstr ""
+
+msgid "Environments|Re-deploy environment %{environment_name}?"
+msgstr ""
+
+msgid "Environments|Re-deploy environment %{name}?"
+msgstr ""
+
+msgid "Environments|Re-deploy to environment"
+msgstr ""
+
+msgid "Environments|Read more about environments"
+msgstr ""
+
+msgid "Environments|Rollback"
+msgstr ""
+
+msgid "Environments|Rollback environment"
+msgstr ""
+
+msgid "Environments|Rollback environment %{environment_name}?"
+msgstr ""
+
+msgid "Environments|Rollback environment %{name}?"
+msgstr ""
+
+msgid "Environments|Select environment"
+msgstr ""
+
+msgid "Environments|Select pod"
+msgstr ""
+
+msgid "Environments|Show all"
+msgstr ""
+
+msgid "Environments|Stop"
+msgstr ""
+
+msgid "Environments|Stop environment"
+msgstr ""
+
+msgid "Environments|Stopping"
+msgstr ""
+
+msgid "Environments|There was an error fetching the logs. Please try again."
+msgstr ""
+
+msgid "Environments|This action will relaunch the job for commit %{commit_id}, putting the environment in a previous version. Are you sure you want to continue?"
+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 ""
+
+msgid "Environments|This action will run the job defined by %{environment_name} for commit %{commit_id}, 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 ""
+
+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 ""
+
+msgid "Environments|Updated"
+msgstr ""
+
+msgid "Environments|You don't have any environments right now"
+msgstr ""
+
+msgid "Environments|protected"
+msgstr ""
+
+msgid "Epic"
+msgstr ""
+
+msgid "Epic cannot be found."
+msgstr ""
+
+msgid "Epic events"
+msgstr ""
+
+msgid "Epics"
+msgstr ""
+
+msgid "Epics Roadmap"
+msgstr ""
+
+msgid "Epics and Issues"
+msgstr ""
+
+msgid "Epics let you manage your portfolio of projects more efficiently and with less effort"
+msgstr ""
+
+msgid "Epics, Issues, and Merge Requests"
+msgstr ""
+
+msgid "Epics|Add a new epic"
+msgstr ""
+
+msgid "Epics|Add an existing epic"
+msgstr ""
+
+msgid "Epics|An error occurred while saving the %{epicDateType} date"
+msgstr ""
+
+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 ""
+
+msgid "Epics|How can I solve this?"
+msgstr ""
+
+msgid "Epics|More information"
+msgstr ""
+
+msgid "Epics|Remove epic"
+msgstr ""
+
+msgid "Epics|Remove issue"
+msgstr ""
+
+msgid "Epics|Show more"
+msgstr ""
+
+msgid "Epics|Something went wrong while assigning issue to epic."
+msgstr ""
+
+msgid "Epics|Something went wrong while creating child epics."
+msgstr ""
+
+msgid "Epics|Something went wrong while creating issue."
+msgstr ""
+
+msgid "Epics|Something went wrong while fetching child epics."
+msgstr ""
+
+msgid "Epics|Something went wrong while fetching group epics."
+msgstr ""
+
+msgid "Epics|Something went wrong while moving item."
+msgstr ""
+
+msgid "Epics|Something went wrong while ordering item."
+msgstr ""
+
+msgid "Epics|Something went wrong while removing issue from epic."
+msgstr ""
+
+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 ""
+
+msgid "Epics|This will also remove any descendents of %{bStart}%{targetEpicTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}. Are you sure?"
+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 ""
+
+msgid "Epics|due"
+msgstr ""
+
+msgid "Epics|start"
+msgstr ""
+
+msgid "Error"
+msgstr ""
+
+msgid "Error Details"
+msgstr ""
+
+msgid "Error Tracking"
+msgstr ""
+
+msgid "Error creating epic"
+msgstr ""
+
+msgid "Error creating label."
+msgstr ""
+
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
+msgstr ""
+
+msgid "Error deleting project. Check logs for error details."
+msgstr ""
+
+msgid "Error fetching diverging counts for branches. Please try again."
+msgstr ""
+
+msgid "Error fetching forked projects. Please try again."
+msgstr ""
+
+msgid "Error fetching labels."
+msgstr ""
+
+msgid "Error fetching network graph."
+msgstr ""
+
+msgid "Error fetching payload data."
+msgstr ""
+
+msgid "Error fetching projects"
+msgstr ""
+
+msgid "Error fetching refs"
+msgstr ""
+
+msgid "Error fetching the dependency list. Please check your network connection and try again."
+msgstr ""
+
+msgid "Error loading branch data. Please try again."
+msgstr ""
+
+msgid "Error loading branches."
+msgstr ""
+
+msgid "Error loading burndown chart data"
+msgstr ""
+
+msgid "Error loading countries data."
+msgstr ""
+
+msgid "Error loading file viewer."
+msgstr ""
+
+msgid "Error loading last commit."
+msgstr ""
+
+msgid "Error loading markdown preview"
+msgstr ""
+
+msgid "Error loading merge requests."
+msgstr ""
+
+msgid "Error loading milestone tab"
+msgstr ""
+
+msgid "Error loading project data. Please try again."
+msgstr ""
+
+msgid "Error loading template types."
+msgstr ""
+
+msgid "Error loading template."
+msgstr ""
+
+msgid "Error loading viewer"
+msgstr ""
+
+msgid "Error occurred when fetching sidebar data"
+msgstr ""
+
+msgid "Error occurred when saving assignees"
+msgstr ""
+
+msgid "Error occurred when toggling the notification subscription"
+msgstr ""
+
+msgid "Error occurred while updating the issue status"
+msgstr ""
+
+msgid "Error occurred while updating the issue weight"
+msgstr ""
+
+msgid "Error occurred. A blocked user cannot be deactivated"
+msgstr ""
+
+msgid "Error occurred. A blocked user must be unblocked to be activated"
+msgstr ""
+
+msgid "Error occurred. User was not blocked"
+msgstr ""
+
+msgid "Error occurred. User was not confirmed"
+msgstr ""
+
+msgid "Error occurred. User was not unblocked"
+msgstr ""
+
+msgid "Error occurred. User was not unlocked"
+msgstr ""
+
+msgid "Error rendering markdown preview"
+msgstr ""
+
+msgid "Error saving label update."
+msgstr ""
+
+msgid "Error setting up editor. Please try again."
+msgstr ""
+
+msgid "Error updating %{issuableType}"
+msgstr ""
+
+msgid "Error updating status for all to-do items."
+msgstr ""
+
+msgid "Error updating status of to-do item."
+msgstr ""
+
+msgid "Error updating the snippet"
+msgstr ""
+
+msgid "Error uploading file"
+msgstr ""
+
+msgid "Error uploading file: %{stripped}"
+msgstr ""
+
+msgid "Error while loading the merge request. Please try again."
+msgstr ""
+
+msgid "Error while loading the project data. Please try again."
+msgstr ""
+
+msgid "Error while migrating %{upload_id}: %{error_message}"
+msgstr ""
+
+msgid "Error with Akismet. Please check the logs for more info."
+msgstr ""
+
+msgid "ErrorTracking|Active"
+msgstr ""
+
+msgid "ErrorTracking|After adding your Auth Token, use the 'Connect' button to load projects"
+msgstr ""
+
+msgid "ErrorTracking|Auth Token"
+msgstr ""
+
+msgid "ErrorTracking|Click 'Connect' to re-establish the connection to Sentry and activate the dropdown."
+msgstr ""
+
+msgid "ErrorTracking|Connection has failed. Re-check Auth Token and try again."
+msgstr ""
+
+msgid "ErrorTracking|If you self-host Sentry, enter the full URL of your Sentry instance. If you're using Sentry's hosted solution, enter https://sentry.io"
+msgstr ""
+
+msgid "ErrorTracking|No projects available"
+msgstr ""
+
+msgid "ErrorTracking|Select project"
+msgstr ""
+
+msgid "ErrorTracking|To enable project selection, enter a valid Auth Token"
+msgstr ""
+
+msgid "Errors"
+msgstr ""
+
+msgid "Errors:"
+msgstr ""
+
+msgid "Estimate"
+msgstr ""
+
+msgid "Estimated"
+msgstr ""
+
+msgid "EventFilterBy|Filter by all"
+msgstr ""
+
+msgid "EventFilterBy|Filter by comments"
+msgstr ""
+
+msgid "EventFilterBy|Filter by epic events"
+msgstr ""
+
+msgid "EventFilterBy|Filter by issue events"
+msgstr ""
+
+msgid "EventFilterBy|Filter by merge events"
+msgstr ""
+
+msgid "EventFilterBy|Filter by push events"
+msgstr ""
+
+msgid "EventFilterBy|Filter by team"
+msgstr ""
+
+msgid "EventFilterBy|Filter by wiki"
+msgstr ""
+
+msgid "Events"
+msgstr ""
+
+msgid "Events in %{group_name}"
+msgstr ""
+
+msgid "Events in %{project_path}"
+msgstr ""
+
+msgid "Every %{action} attempt has failed: %{job_error_message}. Please try again."
+msgstr ""
+
+msgid "Every day"
+msgstr ""
+
+msgid "Every day (at %{time})"
+msgstr ""
+
+msgid "Every month"
+msgstr ""
+
+msgid "Every month (Day %{day} at %{time})"
+msgstr ""
+
+msgid "Every three months"
+msgstr ""
+
+msgid "Every two weeks"
+msgstr ""
+
+msgid "Every week"
+msgstr ""
+
+msgid "Every week (%{weekday} at %{time})"
+msgstr ""
+
+msgid "Everyone"
+msgstr ""
+
+msgid "Everyone With Access"
+msgstr ""
+
+msgid "Everyone can contribute"
+msgstr ""
+
+msgid "Everything on your to-do list is marked as done."
+msgstr ""
+
+msgid "Everything you need to create a GitLab Pages site using Gatsby."
+msgstr ""
+
+msgid "Everything you need to create a GitLab Pages site using GitBook."
+msgstr ""
+
+msgid "Everything you need to create a GitLab Pages site using Hexo."
+msgstr ""
+
+msgid "Everything you need to create a GitLab Pages site using Hugo."
+msgstr ""
+
+msgid "Everything you need to create a GitLab Pages site using Jekyll."
+msgstr ""
+
+msgid "Everything you need to create a GitLab Pages site using plain HTML."
+msgstr ""
+
+msgid "Evidence collection"
+msgstr ""
+
+msgid "Exactly one of %{attributes} is required"
+msgstr ""
+
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
+msgid "Example: @sub\\.company\\.com$"
+msgstr ""
+
+msgid "Example: Usage = single query. (Requested) / (Capacity) = multiple queries combined into a formula."
+msgstr ""
+
+msgid "Except policy:"
+msgstr ""
+
+msgid "Excluding merge commits. Limited to %{limit} commits."
+msgstr ""
+
+msgid "Excluding merge commits. Limited to 6,000 commits."
+msgstr ""
+
+msgid "Existing members and groups"
+msgstr ""
+
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
+msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
+msgstr ""
+
+msgid "Existing shares"
+msgstr ""
+
+msgid "Existing sign in methods may be removed"
+msgstr ""
+
+msgid "Expand"
+msgstr ""
+
+msgid "Expand all"
+msgstr ""
+
+msgid "Expand approvers"
+msgstr ""
+
+msgid "Expand child epics"
+msgstr ""
+
+msgid "Expand down"
+msgstr ""
+
+msgid "Expand dropdown"
+msgstr ""
+
+msgid "Expand sidebar"
+msgstr ""
+
+msgid "Expand up"
+msgstr ""
+
+msgid "Experienced"
+msgstr ""
+
+msgid "Expiration"
+msgstr ""
+
+msgid "Expiration date"
+msgstr ""
+
+msgid "Expiration policy for the Container Registry is a perfect solution for keeping the Registry space down while still enjoying the full power of GitLab CI/CD."
+msgstr ""
+
+msgid "Expired"
+msgstr ""
+
+msgid "Expired %{expiredOn}"
+msgstr ""
+
+msgid "Expired:"
+msgstr ""
+
+msgid "Expires"
+msgstr ""
+
+msgid "Expires at"
+msgstr ""
+
+msgid "Expires in %{expires_at}"
+msgstr ""
+
+msgid "Expires on"
+msgstr ""
+
+msgid "Expires:"
+msgstr ""
+
+msgid "Explain the problem. If appropriate, provide a link to the relevant issue or comment."
+msgstr ""
+
+msgid "Explore"
+msgstr ""
+
+msgid "Explore GitLab"
+msgstr ""
+
+msgid "Explore Groups"
+msgstr ""
+
+msgid "Explore groups"
+msgstr ""
+
+msgid "Explore projects"
+msgstr ""
+
+msgid "Explore public groups"
+msgstr ""
+
+msgid "Export as CSV"
+msgstr ""
+
+msgid "Export group"
+msgstr ""
+
+msgid "Export issues"
+msgstr ""
+
+msgid "Export project"
+msgstr ""
+
+msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
+msgstr ""
+
+msgid "Export this project with all its related data in order to move your project to a new GitLab instance. Once the export is finished, you can import the file from the \"New Project\" page."
+msgstr ""
+
+msgid "Export variable to pipelines running on protected branches and tags only."
+msgstr ""
+
+msgid "External Classification Policy Authorization"
+msgstr ""
+
+msgid "External ID"
+msgstr ""
+
+msgid "External URL"
+msgstr ""
+
+msgid "External Wiki"
+msgstr ""
+
+msgid "External authentication"
+msgstr ""
+
+msgid "External authorization denied access to this project"
+msgstr ""
+
+msgid "External authorization request timeout"
+msgstr ""
+
+msgid "External storage URL"
+msgstr ""
+
+msgid "External storage authentication token"
+msgstr ""
+
+msgid "ExternalAuthorizationService|Classification label"
+msgstr ""
+
+msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
+msgstr ""
+
+msgid "ExternalWikiService|External Wiki"
+msgstr ""
+
+msgid "ExternalWikiService|Replaces the link to the internal wiki with a link to an external wiki."
+msgstr ""
+
+msgid "ExternalWikiService|The URL of the external Wiki"
+msgstr ""
+
+msgid "Facebook"
+msgstr ""
+
+msgid "Failed"
+msgstr ""
+
+msgid "Failed Jobs"
+msgstr ""
+
+msgid "Failed to add a Zoom meeting"
+msgstr ""
+
+msgid "Failed to apply commands."
+msgstr ""
+
+msgid "Failed to assign a user because no user was found."
+msgstr ""
+
+msgid "Failed to cancel auto stop because failed to update the environment."
+msgstr ""
+
+msgid "Failed to cancel auto stop because the environment is not set as auto stop."
+msgstr ""
+
+msgid "Failed to cancel auto stop because you do not have permission to update the environment."
+msgstr ""
+
+msgid "Failed to change the owner"
+msgstr ""
+
+msgid "Failed to check related branches."
+msgstr ""
+
+msgid "Failed to create Merge Request. Please try again."
+msgstr ""
+
+msgid "Failed to create a branch for this issue. Please try again."
+msgstr ""
+
+msgid "Failed to create import label for jira import."
+msgstr ""
+
+msgid "Failed to create repository"
+msgstr ""
+
+msgid "Failed to create resources"
+msgstr ""
+
+msgid "Failed to create wiki"
+msgstr ""
+
+msgid "Failed to delete board. Please try again."
+msgstr ""
+
+msgid "Failed to deploy to"
+msgstr ""
+
+msgid "Failed to enqueue the rebase operation, possibly due to a long-lived transaction. Try again later."
+msgstr ""
+
+msgid "Failed to find import label for Jira import."
+msgstr ""
+
+msgid "Failed to get ref."
+msgstr ""
+
+msgid "Failed to install."
+msgstr ""
+
+msgid "Failed to load emoji list."
+msgstr ""
+
+msgid "Failed to load error details from Sentry."
+msgstr ""
+
+msgid "Failed to load errors from Sentry. Error message: %{errorMessage}"
+msgstr ""
+
+msgid "Failed to load group activity metrics. Please try again."
+msgstr ""
+
+msgid "Failed to load groups & users."
+msgstr ""
+
+msgid "Failed to load labels. Please try again."
+msgstr ""
+
+msgid "Failed to load milestones. Please try again."
+msgstr ""
+
+msgid "Failed to load related branches"
+msgstr ""
+
+msgid "Failed to load stacktrace."
+msgstr ""
+
+msgid "Failed to mark this issue as a duplicate because referenced issue was not found."
+msgstr ""
+
+msgid "Failed to move this issue because label was not found."
+msgstr ""
+
+msgid "Failed to move this issue because only a single label can be provided."
+msgstr ""
+
+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 ""
+
+msgid "Failed to protect the branch"
+msgstr ""
+
+msgid "Failed to protect the environment"
+msgstr ""
+
+msgid "Failed to publish issue on status page."
+msgstr ""
+
+msgid "Failed to remove a Zoom meeting"
+msgstr ""
+
+msgid "Failed to remove issue from board, please try again."
+msgstr ""
+
+msgid "Failed to remove mirror."
+msgstr ""
+
+msgid "Failed to remove the pipeline schedule"
+msgstr ""
+
+msgid "Failed to remove user identity."
+msgstr ""
+
+msgid "Failed to remove user key."
+msgstr ""
+
+msgid "Failed to reset key. Please try again."
+msgstr ""
+
+msgid "Failed to save merge conflicts resolutions. Please try again!"
+msgstr ""
+
+msgid "Failed to save new settings"
+msgstr ""
+
+msgid "Failed to save preferences (%{error_message})."
+msgstr ""
+
+msgid "Failed to save preferences."
+msgstr ""
+
+msgid "Failed to set due date because the date format is invalid."
+msgstr ""
+
+msgid "Failed to signing using smartcard authentication"
+msgstr ""
+
+msgid "Failed to update branch!"
+msgstr ""
+
+msgid "Failed to update environment!"
+msgstr ""
+
+msgid "Failed to update issue status"
+msgstr ""
+
+msgid "Failed to update issues, please try again."
+msgstr ""
+
+msgid "Failed to update tag!"
+msgstr ""
+
+msgid "Failed to update."
+msgstr ""
+
+msgid "Failed to upgrade."
+msgstr ""
+
+msgid "Failed to upload object map file"
+msgstr ""
+
+msgid "Failed to verify domain ownership"
+msgstr ""
+
+msgid "Failure"
+msgstr ""
+
+msgid "False positive"
+msgstr ""
+
+msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
+msgstr ""
+
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
+msgstr ""
+
+msgid "Fast-forward merge without a merge commit"
+msgstr ""
+
+msgid "Faster as it re-uses the project workspace (falling back to clone if it doesn't exist)"
+msgstr ""
+
+msgid "Faster releases. Better code. Less pain."
+msgstr ""
+
+msgid "Favicon was successfully removed."
+msgstr ""
+
+msgid "Feature Flags"
+msgstr ""
+
+msgid "Feature flag was not removed."
+msgstr ""
+
+msgid "Feature flag was successfully removed."
+msgstr ""
+
+msgid "FeatureFlags|* (All Environments)"
+msgstr ""
+
+msgid "FeatureFlags|* (All environments)"
+msgstr ""
+
+msgid "FeatureFlags|API URL"
+msgstr ""
+
+msgid "FeatureFlags|Active"
+msgstr ""
+
+msgid "FeatureFlags|Add strategy"
+msgstr ""
+
+msgid "FeatureFlags|All users"
+msgstr ""
+
+msgid "FeatureFlags|Configure"
+msgstr ""
+
+msgid "FeatureFlags|Configure feature flags"
+msgstr ""
+
+msgid "FeatureFlags|Create feature flag"
+msgstr ""
+
+msgid "FeatureFlags|Delete %{name}?"
+msgstr ""
+
+msgid "FeatureFlags|Delete feature flag"
+msgstr ""
+
+msgid "FeatureFlags|Description"
+msgstr ""
+
+msgid "FeatureFlags|Edit Feature Flag"
+msgstr ""
+
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
+msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
+msgstr ""
+
+msgid "FeatureFlags|Environment Spec"
+msgstr ""
+
+msgid "FeatureFlags|Environment Specs"
+msgstr ""
+
+msgid "FeatureFlags|Feature Flag"
+msgstr ""
+
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
+msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
+msgstr ""
+
+msgid "FeatureFlags|Feature Flag has no strategies"
+msgstr ""
+
+msgid "FeatureFlags|Feature Flags"
+msgstr ""
+
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
+msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
+msgstr ""
+
+msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
+msgstr ""
+
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
+msgid "FeatureFlags|Get started with feature flags"
+msgstr ""
+
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
+msgid "FeatureFlags|ID"
+msgstr ""
+
+msgid "FeatureFlags|Inactive"
+msgstr ""
+
+msgid "FeatureFlags|Inactive flag for %{scope}"
+msgstr ""
+
+msgid "FeatureFlags|Include additional user IDs"
+msgstr ""
+
+msgid "FeatureFlags|Install a %{docs_link_anchored_start}compatible client library%{docs_link_anchored_end} and specify the API URL, application name, and instance ID during the configuration setup. %{docs_link_start}More Information%{docs_link_end}"
+msgstr ""
+
+msgid "FeatureFlags|Instance ID"
+msgstr ""
+
+msgid "FeatureFlags|List details"
+msgstr ""
+
+msgid "FeatureFlags|Loading feature flags"
+msgstr ""
+
+msgid "FeatureFlags|More information"
+msgstr ""
+
+msgid "FeatureFlags|Name"
+msgstr ""
+
+msgid "FeatureFlags|New"
+msgstr ""
+
+msgid "FeatureFlags|New Feature Flag"
+msgstr ""
+
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|New feature flag"
+msgstr ""
+
+msgid "FeatureFlags|New list"
+msgstr ""
+
+msgid "FeatureFlags|Percent rollout (logged in users)"
+msgstr ""
+
+msgid "FeatureFlags|Percent rollout must be a whole number between 0 and 100"
+msgstr ""
+
+msgid "FeatureFlags|Protected"
+msgstr ""
+
+msgid "FeatureFlags|Remove"
+msgstr ""
+
+msgid "FeatureFlags|Rollout Percentage"
+msgstr ""
+
+msgid "FeatureFlags|Rollout Strategy"
+msgstr ""
+
+msgid "FeatureFlags|Status"
+msgstr ""
+
+msgid "FeatureFlags|Strategies"
+msgstr ""
+
+msgid "FeatureFlags|Target environments"
+msgstr ""
+
+msgid "FeatureFlags|There are no active feature flags"
+msgstr ""
+
+msgid "FeatureFlags|There are no inactive feature flags"
+msgstr ""
+
+msgid "FeatureFlags|There was an error fetching the feature flags."
+msgstr ""
+
+msgid "FeatureFlags|Try again in a few moments or contact your support team."
+msgstr ""
+
+msgid "FeatureFlags|User IDs"
+msgstr ""
+
+msgid "FeatureFlag|Delete strategy"
+msgstr ""
+
+msgid "FeatureFlag|Percentage"
+msgstr ""
+
+msgid "FeatureFlag|Type"
+msgstr ""
+
+msgid "FeatureFlag|User IDs"
+msgstr ""
+
+msgid "Feb"
+msgstr ""
+
+msgid "February"
+msgstr ""
+
+msgid "Fetching incoming email"
+msgstr ""
+
+msgid "Fetching licenses failed."
+msgstr ""
+
+msgid "Fetching licenses failed. The request endpoint was not found."
+msgstr ""
+
+msgid "Fetching licenses failed. You are not permitted to perform this action."
+msgstr ""
+
+msgid "File"
+msgstr ""
+
+msgid "File Hooks"
+msgstr ""
+
+msgid "File Hooks (%{count})"
+msgstr ""
+
+msgid "File added"
+msgstr ""
+
+msgid "File browser"
+msgstr ""
+
+msgid "File deleted"
+msgstr ""
+
+msgid "File format is no longer supported"
+msgstr ""
+
+msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
+msgstr ""
+
+msgid "File mode changed from %{a_mode} to %{b_mode}"
+msgstr ""
+
+msgid "File moved"
+msgstr ""
+
+msgid "File name"
+msgstr ""
+
+msgid "File renamed with no changes."
+msgstr ""
+
+msgid "File sync capacity"
+msgstr ""
+
+msgid "File templates"
+msgstr ""
+
+msgid "File upload error."
+msgstr ""
+
+msgid "Files"
+msgstr ""
+
+msgid "Files breadcrumb"
+msgstr ""
+
+msgid "Files, directories, and submodules in the path %{path} for commit reference %{ref}"
+msgstr ""
+
+msgid "Fill in the fields below, turn on <strong>%{enable_label}</strong>, and press <strong>%{save_changes}</strong>"
+msgstr ""
+
+msgid "Filter"
+msgstr ""
+
+msgid "Filter by %{issuable_type} that are currently closed."
+msgstr ""
+
+msgid "Filter by %{issuable_type} that are currently opened."
+msgstr ""
+
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
+msgid "Filter by commit message"
+msgstr ""
+
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
+msgid "Filter by milestone name"
+msgstr ""
+
+msgid "Filter by name"
+msgstr ""
+
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
+msgid "Filter by status"
+msgstr ""
+
+msgid "Filter by two-factor authentication"
+msgstr ""
+
+msgid "Filter by user"
+msgstr ""
+
+msgid "Filter pipelines"
+msgstr ""
+
+msgid "Filter projects"
+msgstr ""
+
+msgid "Filter results"
+msgstr ""
+
+msgid "Filter results by group"
+msgstr ""
+
+msgid "Filter results by project"
+msgstr ""
+
+msgid "Filter results..."
+msgstr ""
+
+msgid "Filter your projects by name"
+msgstr ""
+
+msgid "Filter..."
+msgstr ""
+
+msgid "Find by path"
+msgstr ""
+
+msgid "Find existing members by name"
+msgstr ""
+
+msgid "Find file"
+msgstr ""
+
+msgid "Find the downloaded ZIP file and decompress it."
+msgstr ""
+
+msgid "Find the newly extracted <code>Takeout/Google Code Project Hosting/GoogleCodeProjectHosting.json</code> file."
+msgstr ""
+
+msgid "Fingerprint"
+msgstr ""
+
+msgid "Fingerprints"
+msgstr ""
+
+msgid "Finish editing this message first!"
+msgstr ""
+
+msgid "Finish review"
+msgstr ""
+
+msgid "Finish setting up your dedicated account for <strong>%{group_name}</strong>."
+msgstr ""
+
+msgid "Finished"
+msgstr ""
+
+msgid "First Name is too long (maximum is %{max_length} characters)."
+msgstr ""
+
+msgid "First Seen"
+msgstr ""
+
+msgid "First day of the week"
+msgstr ""
+
+msgid "First name"
+msgstr ""
+
+msgid "First seen"
+msgstr ""
+
+msgid "Fixed date"
+msgstr ""
+
+msgid "Fixed due date"
+msgstr ""
+
+msgid "Fixed start date"
+msgstr ""
+
+msgid "Fixed:"
+msgstr ""
+
+msgid "Flags"
+msgstr ""
+
+msgid "FlowdockService|Flowdock Git source token"
+msgstr ""
+
+msgid "FlowdockService|Flowdock is a collaboration web app for technical teams."
+msgstr ""
+
+msgid "FogBugz Email"
+msgstr ""
+
+msgid "FogBugz Import"
+msgstr ""
+
+msgid "FogBugz Password"
+msgstr ""
+
+msgid "FogBugz URL"
+msgstr ""
+
+msgid "FogBugz import"
+msgstr ""
+
+msgid "Folder/%{name}"
+msgstr ""
+
+msgid "Follow the steps below to export your Google Code project data."
+msgstr ""
+
+msgid "Font Color"
+msgstr ""
+
+msgid "Footer message"
+msgstr ""
+
+msgid "For each Jira issue successfully imported, we'll create a new GitLab issue with the following data:"
+msgstr ""
+
+msgid "For internal projects, any logged in user can view pipelines and access job details (output logs and artifacts)"
+msgstr ""
+
+msgid "For more info, read the documentation."
+msgstr ""
+
+msgid "For more information, go to the "
+msgstr ""
+
+msgid "For more information, please review %{link_start_tag}Jaeger's configuration doc%{link_end_tag}"
+msgstr ""
+
+msgid "For more information, see the File Hooks documentation."
+msgstr ""
+
+msgid "For more information, see the documentation on %{deactivating_usage_ping_link_start}deactivating the usage ping%{deactivating_usage_ping_link_end}."
+msgstr ""
+
+msgid "For more information, see the documentation on %{link_start}disabling Seat Link%{link_end}."
+msgstr ""
+
+msgid "For private projects, any member (guest or higher) can view pipelines and access job details (output logs and artifacts)"
+msgstr ""
+
+msgid "For public projects, anyone can view pipelines and access job details (output logs and artifacts)"
+msgstr ""
+
+msgid "Forgot your password?"
+msgstr ""
+
+msgid "Fork"
+msgstr ""
+
+msgid "Fork Error!"
+msgstr ""
+
+msgid "Fork project"
+msgstr ""
+
+msgid "Fork project?"
+msgstr ""
+
+msgid "ForkedFromProjectPath|Forked from"
+msgstr ""
+
+msgid "ForkedFromProjectPath|Forked from an inaccessible project"
+msgstr ""
+
+msgid "Forking in progress"
+msgstr ""
+
+msgid "Forks"
+msgstr ""
+
+msgid "Format"
+msgstr ""
+
+msgid "Format: %{dateFormat}"
+msgstr ""
+
+msgid "Forward external support email address to"
+msgstr ""
+
+msgid "Found errors in your %{gitlab_ci_yml}:"
+msgstr ""
+
+msgid "Found errors in your .gitlab-ci.yml:"
+msgstr ""
+
+msgid "Free Trial"
+msgstr ""
+
+msgid "Free Trial of GitLab.com Gold"
+msgstr ""
+
+msgid "Frequency"
+msgstr ""
+
+msgid "Friday"
+msgstr ""
+
+msgid "From"
+msgstr ""
+
+msgid "From %{providerTitle}"
+msgstr ""
+
+msgid "From <code>%{source_title}</code> into"
+msgstr ""
+
+msgid "From Bitbucket"
+msgstr ""
+
+msgid "From Bitbucket Server"
+msgstr ""
+
+msgid "From FogBugz"
+msgstr ""
+
+msgid "From GitLab.com"
+msgstr ""
+
+msgid "From Google Code"
+msgstr ""
+
+msgid "From issue creation until deploy to production"
+msgstr ""
+
+msgid "From merge request merge until deploy to production"
+msgstr ""
+
+msgid "From the Kubernetes cluster details view, install Runner from the applications list"
+msgstr ""
+
+msgid "Full name"
+msgstr ""
+
+msgid "GPG Key ID:"
+msgstr ""
+
+msgid "GPG Keys"
+msgstr ""
+
+msgid "GPG keys allow you to verify signed commits."
+msgstr ""
+
+msgid "GPG signature (loading...)"
+msgstr ""
+
+msgid "General"
+msgstr ""
+
+msgid "General Settings"
+msgstr ""
+
+msgid "General pipelines"
+msgstr ""
+
+msgid "Generate a default set of labels"
+msgstr ""
+
+msgid "Generate key"
+msgstr ""
+
+msgid "Generate new export"
+msgstr ""
+
+msgid "Geo"
+msgstr ""
+
+msgid "Geo Nodes"
+msgstr ""
+
+msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
+msgstr ""
+
+msgid "Geo Replication"
+msgstr ""
+
+msgid "Geo Settings"
+msgstr ""
+
+msgid "Geo allows you to replicate your GitLab instance to other geographical locations."
+msgstr ""
+
+msgid "GeoNodeStatusEvent|%{timeAgoStr} (%{pendingEvents} events)"
+msgstr ""
+
+msgid "GeoNodeSyncStatus|Node is failing or broken."
+msgstr ""
+
+msgid "GeoNodeSyncStatus|Node is slow, overloaded, or it just recovered after an outage."
+msgstr ""
+
+msgid "GeoNodes|Attachments"
+msgstr ""
+
+msgid "GeoNodes|Checksummed"
+msgstr ""
+
+msgid "GeoNodes|Consult Geo troubleshooting information"
+msgstr ""
+
+msgid "GeoNodes|Container repositories"
+msgstr ""
+
+msgid "GeoNodes|Data replication lag"
+msgstr ""
+
+msgid "GeoNodes|Design repositories"
+msgstr ""
+
+msgid "GeoNodes|Does not match the primary storage configuration"
+msgstr ""
+
+msgid "GeoNodes|Failed"
+msgstr ""
+
+msgid "GeoNodes|Full"
+msgstr ""
+
+msgid "GeoNodes|GitLab version"
+msgstr ""
+
+msgid "GeoNodes|GitLab version does not match the primary node version"
+msgstr ""
+
+msgid "GeoNodes|Health status"
+msgstr ""
+
+msgid "GeoNodes|Internal URL"
+msgstr ""
+
+msgid "GeoNodes|Job artifacts"
+msgstr ""
+
+msgid "GeoNodes|LFS objects"
+msgstr ""
+
+msgid "GeoNodes|Last event ID processed by cursor"
+msgstr ""
+
+msgid "GeoNodes|Last event ID seen from primary"
+msgstr ""
+
+msgid "GeoNodes|Learn more about Geo node statuses"
+msgstr ""
+
+msgid "GeoNodes|Loading nodes"
+msgstr ""
+
+msgid "GeoNodes|New node"
+msgstr ""
+
+msgid "GeoNodes|Node Authentication was successfully repaired."
+msgstr ""
+
+msgid "GeoNodes|Node URL"
+msgstr ""
+
+msgid "GeoNodes|Node was successfully removed."
+msgstr ""
+
+msgid "GeoNodes|Node's status was updated %{timeAgo}."
+msgstr ""
+
+msgid "GeoNodes|Not checksummed"
+msgstr ""
+
+msgid "GeoNodes|Pausing replication stops the sync process. Are you sure?"
+msgstr ""
+
+msgid "GeoNodes|Removing a Geo primary node stops the synchronization to all nodes. Are you sure?"
+msgstr ""
+
+msgid "GeoNodes|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
+msgstr ""
+
+msgid "GeoNodes|Replicated data is verified with the %{nodeText} using checksums"
+msgstr ""
+
+msgid "GeoNodes|Replication slot WAL"
+msgstr ""
+
+msgid "GeoNodes|Replication slots"
+msgstr ""
+
+msgid "GeoNodes|Repositories"
+msgstr ""
+
+msgid "GeoNodes|Repository checksum progress"
+msgstr ""
+
+msgid "GeoNodes|Repository verification progress"
+msgstr ""
+
+msgid "GeoNodes|Selective (%{syncLabel})"
+msgstr ""
+
+msgid "GeoNodes|Selective synchronization"
+msgstr ""
+
+msgid "GeoNodes|Something went wrong while changing node status"
+msgstr ""
+
+msgid "GeoNodes|Something went wrong while fetching nodes"
+msgstr ""
+
+msgid "GeoNodes|Something went wrong while removing node"
+msgstr ""
+
+msgid "GeoNodes|Something went wrong while repairing node"
+msgstr ""
+
+msgid "GeoNodes|Storage config"
+msgstr ""
+
+msgid "GeoNodes|Sync settings"
+msgstr ""
+
+msgid "GeoNodes|Unused slots"
+msgstr ""
+
+msgid "GeoNodes|Unverified"
+msgstr ""
+
+msgid "GeoNodes|Updated %{timeAgo}"
+msgstr ""
+
+msgid "GeoNodes|Used slots"
+msgstr ""
+
+msgid "GeoNodes|Verified"
+msgstr ""
+
+msgid "GeoNodes|Wiki checksum progress"
+msgstr ""
+
+msgid "GeoNodes|Wiki verification progress"
+msgstr ""
+
+msgid "GeoNodes|Wikis"
+msgstr ""
+
+msgid "GeoNodes|With %{geo} you can install a special read-only and replicated instance anywhere. Before you add nodes, follow the %{instructions} in the exact order they appear."
+msgstr ""
+
+msgid "GeoNodes|You have configured Geo nodes using an insecure HTTP connection. We recommend the use of HTTPS."
+msgstr ""
+
+msgid "GeoNodes|primary node"
+msgstr ""
+
+msgid "GeoNodes|secondary nodes"
+msgstr ""
+
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
+msgid "Geo|%{name} is scheduled for forced re-download"
+msgstr ""
+
+msgid "Geo|%{name} is scheduled for re-sync"
+msgstr ""
+
+msgid "Geo|%{name} is scheduled for re-verify"
+msgstr ""
+
+msgid "Geo|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 ""
+
+msgid "Geo|All %{replicable_name}"
+msgstr ""
+
+msgid "Geo|All projects"
+msgstr ""
+
+msgid "Geo|All projects are being scheduled for resync"
+msgstr ""
+
+msgid "Geo|All projects are being scheduled for reverify"
+msgstr ""
+
+msgid "Geo|Could not remove tracking entry for an existing project."
+msgstr ""
+
+msgid "Geo|Could not remove tracking entry for an existing upload."
+msgstr ""
+
+msgid "Geo|Failed"
+msgstr ""
+
+msgid "Geo|Filter by status"
+msgstr ""
+
+msgid "Geo|Geo Status"
+msgstr ""
+
+msgid "Geo|In progress"
+msgstr ""
+
+msgid "Geo|In sync"
+msgstr ""
+
+msgid "Geo|Last repository check run"
+msgstr ""
+
+msgid "Geo|Last successful sync"
+msgstr ""
+
+msgid "Geo|Last sync attempt"
+msgstr ""
+
+msgid "Geo|Last time verified"
+msgstr ""
+
+msgid "Geo|Never"
+msgstr ""
+
+msgid "Geo|Next sync scheduled at"
+msgstr ""
+
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
+msgid "Geo|Not synced yet"
+msgstr ""
+
+msgid "Geo|Pending synchronization"
+msgstr ""
+
+msgid "Geo|Pending verification"
+msgstr ""
+
+msgid "Geo|Please refer to Geo Troubleshooting."
+msgstr ""
+
+msgid "Geo|Project"
+msgstr ""
+
+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 ""
+
+msgid "Geo|Projects in certain groups"
+msgstr ""
+
+msgid "Geo|Projects in certain storage shards"
+msgstr ""
+
+msgid "Geo|Redownload"
+msgstr ""
+
+msgid "Geo|Remove"
+msgstr ""
+
+msgid "Geo|Remove entry"
+msgstr ""
+
+msgid "Geo|Remove tracking database entry"
+msgstr ""
+
+msgid "Geo|Resync"
+msgstr ""
+
+msgid "Geo|Resync all"
+msgstr ""
+
+msgid "Geo|Retry count"
+msgstr ""
+
+msgid "Geo|Reverify"
+msgstr ""
+
+msgid "Geo|Reverify all"
+msgstr ""
+
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
+msgid "Geo|Status"
+msgstr ""
+
+msgid "Geo|Synced"
+msgstr ""
+
+msgid "Geo|Synced at"
+msgstr ""
+
+msgid "Geo|Synchronization failed - %{error}"
+msgstr ""
+
+msgid "Geo|The database is currently %{db_lag} behind the primary node."
+msgstr ""
+
+msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgstr ""
+
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
+msgid "Geo|Tracking database entry will be removed. Are you sure?"
+msgstr ""
+
+msgid "Geo|Tracking entry for project (%{project_id}) was successfully removed."
+msgstr ""
+
+msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
+msgstr ""
+
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
+msgid "Geo|Unknown state"
+msgstr ""
+
+msgid "Geo|Verification failed - %{error}"
+msgstr ""
+
+msgid "Geo|Waiting for scheduler"
+msgstr ""
+
+msgid "Geo|You are on a secondary, <b>read-only</b> Geo node. If you want to make changes, you must visit this page on the %{primary_node}."
+msgstr ""
+
+msgid "Geo|You are on a secondary, <b>read-only</b> Geo node. You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
+msgstr ""
+
+msgid "Geo|misconfigured"
+msgstr ""
+
+msgid "Geo|primary"
+msgstr ""
+
+msgid "Geo|secondary"
+msgstr ""
+
+msgid "Get a free instance review"
+msgstr ""
+
+msgid "Get started"
+msgstr ""
+
+msgid "Get started with error tracking"
+msgstr ""
+
+msgid "Get started with performance monitoring"
+msgstr ""
+
+msgid "Get started!"
+msgstr ""
+
+msgid "Getting started with releases"
+msgstr ""
+
+msgid "Git"
+msgstr ""
+
+msgid "Git LFS is not enabled on this GitLab server, contact your admin."
+msgstr ""
+
+msgid "Git LFS objects will be synced in pull mirrors if LFS is %{docs_link_start}enabled for the project%{docs_link_end}. They will <strong>not</strong> be synced in push mirrors."
+msgstr ""
+
+msgid "Git global setup"
+msgstr ""
+
+msgid "Git repository URL"
+msgstr ""
+
+msgid "Git revision"
+msgstr ""
+
+msgid "Git shallow clone"
+msgstr ""
+
+msgid "Git strategy for pipelines"
+msgstr ""
+
+msgid "Git version"
+msgstr ""
+
+msgid "GitHub API rate limit exceeded. Try again after %{reset_time}"
+msgstr ""
+
+msgid "GitHub import"
+msgstr ""
+
+msgid "GitLab / Unsubscribe"
+msgstr ""
+
+msgid "GitLab Enterprise Edition %{plan}"
+msgstr ""
+
+msgid "GitLab Group Runners can execute code for all the projects in this group."
+msgstr ""
+
+msgid "GitLab Import"
+msgstr ""
+
+msgid "GitLab Issue"
+msgstr ""
+
+msgid "GitLab Shared Runners execute code of different projects on the same Runner unless you configure GitLab Runner Autoscale with MaxBuilds 1 (which it is on GitLab.com)."
+msgstr ""
+
+msgid "GitLab Support Bot"
+msgstr ""
+
+msgid "GitLab Team Member"
+msgstr ""
+
+msgid "GitLab User"
+msgstr ""
+
+msgid "GitLab allows you to continue using your license even if you exceed the number of seats you purchased. You will be required to pay for these seats when you renew your license."
+msgstr ""
+
+msgid "GitLab commit"
+msgstr ""
+
+msgid "GitLab for Slack"
+msgstr ""
+
+msgid "GitLab is a single application for the entire software development lifecycle. From project planning and source code management to CI/CD, monitoring, and security."
+msgstr ""
+
+msgid "GitLab is obtaining a Let's Encrypt SSL certificate for this domain. This process can take some time. Please try again later."
+msgstr ""
+
+msgid "GitLab is undergoing maintenance and is operating in a read-only mode."
+msgstr ""
+
+msgid "GitLab member or Email address"
+msgstr ""
+
+msgid "GitLab metadata URL"
+msgstr ""
+
+msgid "GitLab project export"
+msgstr ""
+
+msgid "GitLab restart is required to apply changes."
+msgstr ""
+
+msgid "GitLab single sign on URL"
+msgstr ""
+
+msgid "GitLab uses %{jaeger_link} to monitor distributed systems."
+msgstr ""
+
+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 import"
+msgstr ""
+
+msgid "GitLabPagesDomains|Retry"
+msgstr ""
+
+msgid "GitLabPages|%{domain} is not verified. To learn how to verify ownership, visit your %{link_start}domain details%{link_end}."
+msgstr ""
+
+msgid "GitLabPages|Access Control is enabled for this Pages website; only authorized users will be able to access it. To make your website publicly available, navigate to your project's %{strong_start}Settings > General > Visibility%{strong_end} and select %{strong_start}Everyone%{strong_end} in pages section. Read the %{link_start}documentation%{link_end} for more information."
+msgstr ""
+
+msgid "GitLabPages|Access pages"
+msgstr ""
+
+msgid "GitLabPages|Are you sure?"
+msgstr ""
+
+msgid "GitLabPages|Certificate: %{subject}"
+msgstr ""
+
+msgid "GitLabPages|Configure pages"
+msgstr ""
+
+msgid "GitLabPages|Domains"
+msgstr ""
+
+msgid "GitLabPages|Edit"
+msgstr ""
+
+msgid "GitLabPages|Expired"
+msgstr ""
+
+msgid "GitLabPages|Force HTTPS (requires valid certificates)"
+msgstr ""
+
+msgid "GitLabPages|GitLab Pages are disabled for this project. You can enable them on your project's %{strong_start}Settings > General > Visibility%{strong_end} page."
+msgstr ""
+
+msgid "GitLabPages|It may take up to 30 minutes before the site is available after the first deployment."
+msgstr ""
+
+msgid "GitLabPages|Learn how to upload your static site and have it served by GitLab by following the %{link_start}documentation on GitLab Pages%{link_end}."
+msgstr ""
+
+msgid "GitLabPages|Learn more."
+msgstr ""
+
+msgid "GitLabPages|Maximum size of pages (MB)"
+msgstr ""
+
+msgid "GitLabPages|New Domain"
+msgstr ""
+
+msgid "GitLabPages|Only project maintainers can remove pages"
+msgstr ""
+
+msgid "GitLabPages|Pages"
+msgstr ""
+
+msgid "GitLabPages|Remove"
+msgstr ""
+
+msgid "GitLabPages|Remove pages"
+msgstr ""
+
+msgid "GitLabPages|Removing pages will prevent them from being exposed to the outside world."
+msgstr ""
+
+msgid "GitLabPages|Save"
+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 ""
+
+msgid "GitLabPages|Support for domains and certificates is disabled. Ask your system's administrator to enable it."
+msgstr ""
+
+msgid "GitLabPages|The total size of deployed static content will be limited to this size. 0 for unlimited. Leave empty to inherit the global value."
+msgstr ""
+
+msgid "GitLabPages|Unverified"
+msgstr ""
+
+msgid "GitLabPages|Verified"
+msgstr ""
+
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with sub-subdomains. This means that if your username/groupname contains a dot it will not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages will continue to work provided you don't redirect HTTP to HTTPS."
+msgstr ""
+
+msgid "GitLabPages|With GitLab Pages you can host your static websites on GitLab. Combined with the power of GitLab CI and the help of GitLab Runner you can deploy static pages for your individual projects, your user or your group."
+msgstr ""
+
+msgid "GitLabPages|Your pages are served under:"
+msgstr ""
+
+msgid "Gitaly"
+msgstr ""
+
+msgid "Gitaly Servers"
+msgstr ""
+
+msgid "Gitaly|Address"
+msgstr ""
+
+msgid "Gitea Host URL"
+msgstr ""
+
+msgid "Gitea Import"
+msgstr ""
+
+msgid "Gitlab Pages"
+msgstr ""
+
+msgid "Given access %{time_ago}"
+msgstr ""
+
+msgid "Given epic is already related to this epic."
+msgstr ""
+
+msgid "Global Shortcuts"
+msgstr ""
+
+msgid "Global notification settings"
+msgstr ""
+
+msgid "Go Back"
+msgstr ""
+
+msgid "Go Micro is a framework for micro service development."
+msgstr ""
+
+msgid "Go back"
+msgstr ""
+
+msgid "Go back (while searching for files)"
+msgstr ""
+
+msgid "Go back to %{startTag}Open issues%{endTag} and select some issues to add to your board."
+msgstr ""
+
+msgid "Go full screen"
+msgstr ""
+
+msgid "Go to %{link_to_google_takeout}."
+msgstr ""
+
+msgid "Go to Pipelines"
+msgstr ""
+
+msgid "Go to Webhooks"
+msgstr ""
+
+msgid "Go to commits"
+msgstr ""
+
+msgid "Go to definition"
+msgstr ""
+
+msgid "Go to environments"
+msgstr ""
+
+msgid "Go to file"
+msgstr ""
+
+msgid "Go to file permalink (while viewing a file)"
+msgstr ""
+
+msgid "Go to files"
+msgstr ""
+
+msgid "Go to find file"
+msgstr ""
+
+msgid "Go to issue boards"
+msgstr ""
+
+msgid "Go to issues"
+msgstr ""
+
+msgid "Go to jobs"
+msgstr ""
+
+msgid "Go to kubernetes"
+msgstr ""
+
+msgid "Go to merge requests"
+msgstr ""
+
+msgid "Go to metrics"
+msgstr ""
+
+msgid "Go to parent"
+msgstr ""
+
+msgid "Go to project"
+msgstr ""
+
+msgid "Go to releases"
+msgstr ""
+
+msgid "Go to repository charts"
+msgstr ""
+
+msgid "Go to repository graph"
+msgstr ""
+
+msgid "Go to snippets"
+msgstr ""
+
+msgid "Go to the activity feed"
+msgstr ""
+
+msgid "Go to the milestone list"
+msgstr ""
+
+msgid "Go to the project's activity feed"
+msgstr ""
+
+msgid "Go to the project's overview page"
+msgstr ""
+
+msgid "Go to wiki"
+msgstr ""
+
+msgid "Go to your To-Do list"
+msgstr ""
+
+msgid "Go to your fork"
+msgstr ""
+
+msgid "Go to your groups"
+msgstr ""
+
+msgid "Go to your issues"
+msgstr ""
+
+msgid "Go to your merge requests"
+msgstr ""
+
+msgid "Go to your projects"
+msgstr ""
+
+msgid "Go to your snippets"
+msgstr ""
+
+msgid "Golden Tanuki"
+msgstr ""
+
+msgid "Google Cloud Platform"
+msgstr ""
+
+msgid "Google Code import"
+msgstr ""
+
+msgid "Google Takeout"
+msgstr ""
+
+msgid "Google authentication is not %{link_start}properly configured%{link_end}. Ask your GitLab administrator if you want to use this service."
+msgstr ""
+
+msgid "Got it"
+msgstr ""
+
+msgid "Got it!"
+msgstr ""
+
+msgid "Grafana URL"
+msgstr ""
+
+msgid "GrafanaIntegration|API Token"
+msgstr ""
+
+msgid "GrafanaIntegration|Active"
+msgstr ""
+
+msgid "GrafanaIntegration|Embed Grafana charts in GitLab issues."
+msgstr ""
+
+msgid "GrafanaIntegration|Enter the Grafana API Token."
+msgstr ""
+
+msgid "GrafanaIntegration|Enter the base URL of the Grafana instance."
+msgstr ""
+
+msgid "GrafanaIntegration|Grafana Authentication"
+msgstr ""
+
+msgid "GrafanaIntegration|Grafana URL"
+msgstr ""
+
+msgid "Grant access"
+msgstr ""
+
+msgid "Graph"
+msgstr ""
+
+msgid "Gravatar"
+msgstr ""
+
+msgid "Gravatar enabled"
+msgstr ""
+
+msgid "Group"
+msgstr ""
+
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
+msgid "Group %{group_name} was scheduled for deletion."
+msgstr ""
+
+msgid "Group %{group_name} was successfully created."
+msgstr ""
+
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
+msgid "Group Audit Events"
+msgstr ""
+
+msgid "Group CI/CD settings"
+msgstr ""
+
+msgid "Group Git LFS status:"
+msgstr ""
+
+msgid "Group Hooks"
+msgstr ""
+
+msgid "Group ID"
+msgstr ""
+
+msgid "Group ID: %{group_id}"
+msgstr ""
+
+msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
+msgstr ""
+
+msgid "Group Runners"
+msgstr ""
+
+msgid "Group SAML must be enabled to test"
+msgstr ""
+
+msgid "Group URL"
+msgstr ""
+
+msgid "Group avatar"
+msgstr ""
+
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
+msgid "Group description"
+msgstr ""
+
+msgid "Group description (optional)"
+msgstr ""
+
+msgid "Group details"
+msgstr ""
+
+msgid "Group export could not be started."
+msgstr ""
+
+msgid "Group export error"
+msgstr ""
+
+msgid "Group export link has expired. Please generate a new export from your group settings."
+msgstr ""
+
+msgid "Group export started. A download link will be sent by email and made available on this page."
+msgstr ""
+
+msgid "Group has been already marked for deletion"
+msgstr ""
+
+msgid "Group has not been marked for deletion"
+msgstr ""
+
+msgid "Group info:"
+msgstr ""
+
+msgid "Group maintainers can register group runners in the %{link}"
+msgstr ""
+
+msgid "Group members"
+msgstr ""
+
+msgid "Group milestone"
+msgstr ""
+
+msgid "Group name"
+msgstr ""
+
+msgid "Group name (your organization)"
+msgstr ""
+
+msgid "Group overview"
+msgstr ""
+
+msgid "Group overview content"
+msgstr ""
+
+msgid "Group path is already taken. Suggestions: "
+msgstr ""
+
+msgid "Group path is available."
+msgstr ""
+
+msgid "Group pipeline minutes were successfully reset."
+msgstr ""
+
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
+msgid "Group requires separate account"
+msgstr ""
+
+msgid "Group variables (inherited)"
+msgstr ""
+
+msgid "Group was exported"
+msgstr ""
+
+msgid "Group was successfully updated."
+msgstr ""
+
+msgid "Group: %{group_name}"
+msgstr ""
+
+msgid "Group: %{name}"
+msgstr ""
+
+msgid "GroupActivityMetrics|New Members created"
+msgstr ""
+
+msgid "GroupActivyMetrics|Issues created"
+msgstr ""
+
+msgid "GroupActivyMetrics|Merge Requests created"
+msgstr ""
+
+msgid "GroupActivyMetrics|Recent activity (last 90 days)"
+msgstr ""
+
+msgid "GroupRoadmap|%{dateWord} – No end date"
+msgstr ""
+
+msgid "GroupRoadmap|%{startDateInWords} – %{endDateInWords}"
+msgstr ""
+
+msgid "GroupRoadmap|No start date – %{dateWord}"
+msgstr ""
+
+msgid "GroupRoadmap|Something went wrong while fetching epics"
+msgstr ""
+
+msgid "GroupRoadmap|Something went wrong while fetching milestones"
+msgstr ""
+
+msgid "GroupRoadmap|Sorry, no epics matched your search"
+msgstr ""
+
+msgid "GroupRoadmap|The roadmap shows the progress of your epics along a timeline"
+msgstr ""
+
+msgid "GroupRoadmap|To view the roadmap, add a start or due date to one of the %{linkStart}child epics%{linkEnd}."
+msgstr ""
+
+msgid "GroupRoadmap|To view the roadmap, add a start or due date to one of your epics in this group or its subgroups; from %{startDate} to %{endDate}."
+msgstr ""
+
+msgid "GroupRoadmap|To widen your search, change or remove filters; from %{startDate} to %{endDate}."
+msgstr ""
+
+msgid "GroupSAML|Certificate fingerprint"
+msgstr ""
+
+msgid "GroupSAML|Configuration"
+msgstr ""
+
+msgid "GroupSAML|Copy SAML Response XML"
+msgstr ""
+
+msgid "GroupSAML|Enable SAML authentication for this group."
+msgstr ""
+
+msgid "GroupSAML|Enforce SSO-only authentication for this group."
+msgstr ""
+
+msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
+msgstr ""
+
+msgid "GroupSAML|Enforced SSO"
+msgstr ""
+
+msgid "GroupSAML|Generate a SCIM token"
+msgstr ""
+
+msgid "GroupSAML|Generate a SCIM token to set up your System for Cross-Domain Identity Management."
+msgstr ""
+
+msgid "GroupSAML|Identity"
+msgstr ""
+
+msgid "GroupSAML|Identity provider single sign on URL"
+msgstr ""
+
+msgid "GroupSAML|Make sure you save this token — you won't be able to access it again."
+msgstr ""
+
+msgid "GroupSAML|Manage your group’s membership while adding another level of security with SAML."
+msgstr ""
+
+msgid "GroupSAML|Members"
+msgstr ""
+
+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 ""
+
+msgid "GroupSAML|NameID Format"
+msgstr ""
+
+msgid "GroupSAML|Prohibit outer forks"
+msgstr ""
+
+msgid "GroupSAML|Prohibit outer forks for this group."
+msgstr ""
+
+msgid "GroupSAML|SAML Response Output"
+msgstr ""
+
+msgid "GroupSAML|SAML Response XML"
+msgstr ""
+
+msgid "GroupSAML|SAML Single Sign On"
+msgstr ""
+
+msgid "GroupSAML|SAML Single Sign On Settings"
+msgstr ""
+
+msgid "GroupSAML|SCIM API endpoint URL"
+msgstr ""
+
+msgid "GroupSAML|SCIM Token"
+msgstr ""
+
+msgid "GroupSAML|SHA1 fingerprint of the SAML token signing certificate. Get this from your identity provider, where it can also be called \"Thumbprint\"."
+msgstr ""
+
+msgid "GroupSAML|The SCIM token is now hidden. To see the value of the token again, you need to "
+msgstr ""
+
+msgid "GroupSAML|To be able to enable enforced SSO, you first need to enable SAML authentication."
+msgstr ""
+
+msgid "GroupSAML|To be able to enable group managed accounts, you first need to enable enforced SSO."
+msgstr ""
+
+msgid "GroupSAML|To be able to prohibit outer forks, you first need to enforce dedicate group managed accounts."
+msgstr ""
+
+msgid "GroupSAML|Toggle SAML authentication"
+msgstr ""
+
+msgid "GroupSAML|Valid SAML Response"
+msgstr ""
+
+msgid "GroupSAML|With group managed accounts enabled, all the users without a group managed account will be excluded from the group."
+msgstr ""
+
+msgid "GroupSAML|With prohibit outer forks flag enabled group members will be able to fork project only inside your group."
+msgstr ""
+
+msgid "GroupSAML|Your SCIM token"
+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\""
+msgstr ""
+
+msgid "GroupSAML|should be a random persistent ID, emails are discouraged"
+msgstr ""
+
+msgid "GroupSettings|Apply integration settings to all Projects"
+msgstr ""
+
+msgid "GroupSettings|Auto DevOps pipeline was updated for the group"
+msgstr ""
+
+msgid "GroupSettings|Badges"
+msgstr ""
+
+msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
+msgstr ""
+
+msgid "GroupSettings|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 ""
+
+msgid "GroupSettings|Change group path"
+msgstr ""
+
+msgid "GroupSettings|Changing group path can have unintended side effects."
+msgstr ""
+
+msgid "GroupSettings|Custom project templates"
+msgstr ""
+
+msgid "GroupSettings|Customize your group badges."
+msgstr ""
+
+msgid "GroupSettings|Default to Auto DevOps pipeline for all projects within this group"
+msgstr ""
+
+msgid "GroupSettings|Disable email notifications"
+msgstr ""
+
+msgid "GroupSettings|Disable group mentions"
+msgstr ""
+
+msgid "GroupSettings|Export group"
+msgstr ""
+
+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 ""
+
+msgid "GroupSettings|Integrations configured here will automatically apply to all projects in this group."
+msgstr ""
+
+msgid "GroupSettings|Learn more about badges."
+msgstr ""
+
+msgid "GroupSettings|Learn more about group-level project templates."
+msgstr ""
+
+msgid "GroupSettings|New runners registration token has been generated!"
+msgstr ""
+
+msgid "GroupSettings|Pipeline settings was updated for the group"
+msgstr ""
+
+msgid "GroupSettings|Please choose a group path with no special characters."
+msgstr ""
+
+msgid "GroupSettings|Prevent sharing a project within %{group} with other groups"
+msgstr ""
+
+msgid "GroupSettings|Select a sub-group as the custom project template source for this group."
+msgstr ""
+
+msgid "GroupSettings|The Auto DevOps pipeline will run if no alternative CI configuration file is found."
+msgstr ""
+
+msgid "GroupSettings|There was a problem updating Auto DevOps pipeline: %{error_messages}."
+msgstr ""
+
+msgid "GroupSettings|There was a problem updating the pipeline settings: %{error_messages}."
+msgstr ""
+
+msgid "GroupSettings|This setting is applied on %{ancestor_group} and has been overridden on this subgroup."
+msgstr ""
+
+msgid "GroupSettings|This setting is applied on %{ancestor_group}. To share projects in this group with another group, ask the owner to override the setting or %{remove_ancestor_share_with_group_lock}."
+msgstr ""
+
+msgid "GroupSettings|This setting is applied on %{ancestor_group}. You can override the setting or %{remove_ancestor_share_with_group_lock}."
+msgstr ""
+
+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 ""
+
+msgid "GroupSettings|This setting will override user notification preferences for all members of the group, subgroups, and projects."
+msgstr ""
+
+msgid "GroupSettings|This setting will prevent group members from being notified if the group is mentioned."
+msgstr ""
+
+msgid "GroupSettings|Transfer group"
+msgstr ""
+
+msgid "GroupSettings|You can only transfer the group to a group you manage."
+msgstr ""
+
+msgid "GroupSettings|You will need to update your local repositories to point to the new location."
+msgstr ""
+
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
+msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
+msgstr ""
+
+msgid "GroupSettings|cannot change when group contains projects with NPM packages"
+msgstr ""
+
+msgid "GroupSettings|remove the share with group lock from %{ancestor_group_name}"
+msgstr ""
+
+msgid "Groups"
+msgstr ""
+
+msgid "Groups (%{count})"
+msgstr ""
+
+msgid "Groups (%{groups})"
+msgstr ""
+
+msgid "Groups can also be nested by creating %{subgroup_docs_link_start}subgroups%{subgroup_docs_link_end}."
+msgstr ""
+
+msgid "Groups to synchronize"
+msgstr ""
+
+msgid "Groups with access to %{strong_start}%{group_name}%{strong_end}"
+msgstr ""
+
+msgid "Groups with access to <strong>%{project_name}</strong>"
+msgstr ""
+
+msgid "GroupsDropdown|Frequently visited"
+msgstr ""
+
+msgid "GroupsDropdown|Groups you visit often will appear here"
+msgstr ""
+
+msgid "GroupsDropdown|Loading groups"
+msgstr ""
+
+msgid "GroupsDropdown|Search your groups"
+msgstr ""
+
+msgid "GroupsDropdown|Something went wrong on our end."
+msgstr ""
+
+msgid "GroupsDropdown|Sorry, no groups matched your search"
+msgstr ""
+
+msgid "GroupsDropdown|This feature requires browser localStorage support"
+msgstr ""
+
+msgid "GroupsEmptyState|A group is a collection of several projects."
+msgstr ""
+
+msgid "GroupsEmptyState|If you organize your projects under a group, it works like a folder."
+msgstr ""
+
+msgid "GroupsEmptyState|No groups found"
+msgstr ""
+
+msgid "GroupsEmptyState|You can manage your group member’s permissions and access to each project in the group."
+msgstr ""
+
+msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
+msgstr ""
+
+msgid "GroupsTree|Create a project in this group."
+msgstr ""
+
+msgid "GroupsTree|Create a subgroup in this group."
+msgstr ""
+
+msgid "GroupsTree|Edit group"
+msgstr ""
+
+msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
+msgstr ""
+
+msgid "GroupsTree|Leave this group"
+msgstr ""
+
+msgid "GroupsTree|Loading groups"
+msgstr ""
+
+msgid "GroupsTree|No groups matched your search"
+msgstr ""
+
+msgid "GroupsTree|No groups or projects matched your search"
+msgstr ""
+
+msgid "GroupsTree|Search by name"
+msgstr ""
+
+msgid "Guideline"
+msgstr ""
+
+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 ""
+
+msgid "Hashed Storage must be enabled to use Geo"
+msgstr ""
+
+msgid "Hashed repository storage paths"
+msgstr ""
+
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
+msgid "Have your users email"
+msgstr ""
+
+msgid "Header logo was successfully removed."
+msgstr ""
+
+msgid "Header message"
+msgstr ""
+
+msgid "Headings"
+msgstr ""
+
+msgid "Health"
+msgstr ""
+
+msgid "Health Check"
+msgstr ""
+
+msgid "Health information can be retrieved from the following endpoints. More information is available"
+msgstr ""
+
+msgid "HealthCheck|Access token is"
+msgstr ""
+
+msgid "HealthCheck|Healthy"
+msgstr ""
+
+msgid "HealthCheck|No Health Problems Detected"
+msgstr ""
+
+msgid "HealthCheck|Unhealthy"
+msgstr ""
+
+msgid "Hello there"
+msgstr ""
+
+msgid "Help"
+msgstr ""
+
+msgid "Help page"
+msgstr ""
+
+msgid "Help page text and support page url."
+msgstr ""
+
+msgid "Helps prevent bots from brute-force attacks."
+msgstr ""
+
+msgid "Helps prevent bots from creating accounts."
+msgstr ""
+
+msgid "Helps reduce alert volume (e.g. if creating too many issues)"
+msgstr ""
+
+msgid "Helps reduce request volume for protected paths"
+msgstr ""
+
+msgid "Here you will find recent merge request activity"
+msgstr ""
+
+msgid "Hi %{username}!"
+msgstr ""
+
+msgid "Hide archived projects"
+msgstr ""
+
+msgid "Hide chart"
+msgid_plural "Hide charts"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Hide file browser"
+msgstr ""
+
+msgid "Hide group projects"
+msgstr ""
+
+msgid "Hide host keys manual input"
+msgstr ""
+
+msgid "Hide marketing-related entries from help"
+msgstr ""
+
+msgid "Hide payload"
+msgstr ""
+
+msgid "Hide shared projects"
+msgstr ""
+
+msgid "Hide stage"
+msgstr ""
+
+msgid "Hide value"
+msgid_plural "Hide values"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Hide values"
+msgstr ""
+
+msgid "Hiding all labels"
+msgstr ""
+
+msgid "High or unknown vulnerabilities present"
+msgstr ""
+
+msgid "Highest number of requests per minute for each raw path, default to 300. To disable throttling set to 0."
+msgstr ""
+
+msgid "Highest role:"
+msgstr ""
+
+msgid "History"
+msgstr ""
+
+msgid "History of authentications"
+msgstr ""
+
+msgid "Homepage"
+msgstr ""
+
+msgid "Hook execution failed. Ensure the group has a project with commits."
+msgstr ""
+
+msgid "Hook was successfully created."
+msgstr ""
+
+msgid "Hook was successfully updated."
+msgstr ""
+
+msgid "Hostname"
+msgstr ""
+
+msgid "Hour (UTC)"
+msgstr ""
+
+msgid "Housekeeping"
+msgstr ""
+
+msgid "Housekeeping successfully started"
+msgstr ""
+
+msgid "Housekeeping, export, path, transfer, remove, archive."
+msgstr ""
+
+msgid "How it works"
+msgstr ""
+
+msgid "How many days need to pass between marking entity for deletion and actual removing it."
+msgstr ""
+
+msgid "How many replicas each Elasticsearch shard has."
+msgstr ""
+
+msgid "How many shards to split the Elasticsearch index over."
+msgstr ""
+
+msgid "How many users will be evaluating the trial?"
+msgstr ""
+
+msgid "However, you are already a member of this %{member_source}. Sign in using a different account to accept the invitation."
+msgstr ""
+
+msgid "I accept the %{terms_link_start}Terms of Service and Privacy Policy%{terms_link_end}"
+msgstr ""
+
+msgid "I accept the %{terms_link}"
+msgstr ""
+
+msgid "I accept the|Terms of Service and Privacy Policy"
+msgstr ""
+
+msgid "I forgot my password"
+msgstr ""
+
+msgid "I have read and agree to the Let's Encrypt %{link_start}Terms of Service%{link_end} (PDF)"
+msgstr ""
+
+msgid "I'd like to receive updates via email about GitLab"
+msgstr ""
+
+msgid "ID"
+msgstr ""
+
+msgid "ID:"
+msgstr ""
+
+msgid "IDE|Allow live previews of JavaScript projects in the Web IDE using CodeSandbox Live Preview."
+msgstr ""
+
+msgid "IDE|Back"
+msgstr ""
+
+msgid "IDE|Commit"
+msgstr ""
+
+msgid "IDE|Commit to %{branchName} branch"
+msgstr ""
+
+msgid "IDE|Edit"
+msgstr ""
+
+msgid "IDE|Get started with Live Preview"
+msgstr ""
+
+msgid "IDE|Go to project"
+msgstr ""
+
+msgid "IDE|Live Preview"
+msgstr ""
+
+msgid "IDE|Preview your web application using Web IDE client-side evaluation."
+msgstr ""
+
+msgid "IDE|Refresh preview"
+msgstr ""
+
+msgid "IDE|Review"
+msgstr ""
+
+msgid "IDE|Successful commit"
+msgstr ""
+
+msgid "IDE|This option is disabled because you are not allowed to create merge requests in this project."
+msgstr ""
+
+msgid "IDE|This option is disabled because you don't have write permissions for the current branch."
+msgstr ""
+
+msgid "INFO: Your SSH key has expired. Please generate a new key."
+msgstr ""
+
+msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
+msgstr ""
+
+msgid "IP Address"
+msgstr ""
+
+msgid "IP subnet restriction only allowed for top-level groups"
+msgstr ""
+
+msgid "Identifier"
+msgstr ""
+
+msgid "Identifiers"
+msgstr ""
+
+msgid "Identities"
+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 any job surpasses this timeout threshold, it will be marked as failed. Human readable time input language is accepted like \"1 hour\". Values without specification represent seconds."
+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 ""
+
+msgid "If checked, group owners can manage LDAP group links and LDAP member overrides"
+msgstr ""
+
+msgid "If checked, new group memberships and permissions can only be added via LDAP synchronization"
+msgstr ""
+
+msgid "If disabled, a diverged local branch will not be automatically updated with commits from its remote counterpart, to prevent local data loss. If the default branch (%{default_branch}) has diverged and cannot be updated, mirroring will fail. Other diverged branches are silently ignored."
+msgstr ""
+
+msgid "If disabled, only admins will be able to configure repository mirroring."
+msgstr ""
+
+msgid "If disabled, the access level will depend on the user's permissions in the project."
+msgstr ""
+
+msgid "If enabled"
+msgstr ""
+
+msgid "If enabled, access to projects will be validated on an external service using their classification label."
+msgstr ""
+
+msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
+msgstr ""
+
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
+msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
+msgstr ""
+
+msgid "If this was a mistake you can leave the %{source_type}."
+msgstr ""
+
+msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
+msgstr ""
+
+msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
+msgstr ""
+
+msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
+msgstr ""
+
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
+msgid "If your HTTP repository is not publicly accessible, add your credentials."
+msgstr ""
+
+msgid "Iglu registry URL (optional)"
+msgstr ""
+
+msgid "Ignore"
+msgstr ""
+
+msgid "Ignored"
+msgstr ""
+
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
+msgstr ""
+
+msgid "ImageDiffViewer|2-up"
+msgstr ""
+
+msgid "ImageDiffViewer|Onion skin"
+msgstr ""
+
+msgid "ImageDiffViewer|Swipe"
+msgstr ""
+
+msgid "ImageViewerDimensions|H"
+msgstr ""
+
+msgid "ImageViewerDimensions|W"
+msgstr ""
+
+msgid "Impersonation Tokens"
+msgstr ""
+
+msgid "Impersonation has been disabled"
+msgstr ""
+
+msgid "Import"
+msgstr ""
+
+msgid "Import CSV"
+msgstr ""
+
+msgid "Import Projects from Gitea"
+msgstr ""
+
+msgid "Import all compatible projects"
+msgstr ""
+
+msgid "Import all compatible repositories"
+msgstr ""
+
+msgid "Import all projects"
+msgstr ""
+
+msgid "Import all repositories"
+msgstr ""
+
+msgid "Import an exported GitLab project"
+msgstr ""
+
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
+msgid "Import from"
+msgstr ""
+
+msgid "Import from Jira"
+msgstr ""
+
+msgid "Import in progress"
+msgstr ""
+
+msgid "Import in progress. Refresh page to see newly added issues."
+msgstr ""
+
+msgid "Import issues"
+msgstr ""
+
+msgid "Import members"
+msgstr ""
+
+msgid "Import members from another project"
+msgstr ""
+
+msgid "Import multiple repositories by uploading a manifest file."
+msgstr ""
+
+msgid "Import project"
+msgstr ""
+
+msgid "Import project members"
+msgstr ""
+
+msgid "Import projects from Bitbucket"
+msgstr ""
+
+msgid "Import projects from Bitbucket Server"
+msgstr ""
+
+msgid "Import projects from FogBugz"
+msgstr ""
+
+msgid "Import projects from GitLab.com"
+msgstr ""
+
+msgid "Import projects from Google Code"
+msgstr ""
+
+msgid "Import repositories from Bitbucket Server"
+msgstr ""
+
+msgid "Import repositories from GitHub"
+msgstr ""
+
+msgid "Import repository"
+msgstr ""
+
+msgid "Import started by: %{importInitiator}"
+msgstr ""
+
+msgid "Import tasks"
+msgstr ""
+
+msgid "Import tasks from Phabricator into issues"
+msgstr ""
+
+msgid "Import timed out. Import took longer than %{import_jobs_expiration} seconds"
+msgstr ""
+
+msgid "Import/Export illustration"
+msgstr ""
+
+msgid "ImportButtons|Connect repositories from"
+msgstr ""
+
+msgid "ImportProjects|Blocked import URL: %{message}"
+msgstr ""
+
+msgid "ImportProjects|Error importing repository %{project_safe_import_url} into %{project_full_path} - %{message}"
+msgstr ""
+
+msgid "ImportProjects|Importing the project failed"
+msgstr ""
+
+msgid "ImportProjects|Requesting your %{provider} repositories failed"
+msgstr ""
+
+msgid "ImportProjects|Select the projects you want to import"
+msgstr ""
+
+msgid "ImportProjects|The remote data could not be imported."
+msgstr ""
+
+msgid "ImportProjects|The repository could not be created."
+msgstr ""
+
+msgid "ImportProjects|Update of imported projects with realtime changes failed"
+msgstr ""
+
+msgid "Improve Issue boards"
+msgstr ""
+
+msgid "Improve Issue boards with GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "In %{time_to_now}"
+msgstr ""
+
+msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
+msgstr ""
+
+msgid "In order to gather accurate feature usage data, it can take 1 to 2 weeks to see your index."
+msgstr ""
+
+msgid "In order to personalize your experience with GitLab<br>we would like to know a bit more about you."
+msgstr ""
+
+msgid "In order to tailor your experience with GitLab we<br>would like to know a bit more about you."
+msgstr ""
+
+msgid "In progress"
+msgstr ""
+
+msgid "In the next step, you'll be able to select the projects you want to import."
+msgstr ""
+
+msgid "Incident Management Limits"
+msgstr ""
+
+msgid "Incidents"
+msgstr ""
+
+msgid "Include a Terms of Service agreement and Privacy Policy that all users must accept."
+msgstr ""
+
+msgid "Include author name in notification email body"
+msgstr ""
+
+msgid "Include description in commit message"
+msgstr ""
+
+msgid "Include merge request description"
+msgstr ""
+
+msgid "Include the username in the URL if required: <code>https://username@gitlab.company.com/group/project.git</code>."
+msgstr ""
+
+msgid "Includes LFS objects. It can be overridden per group, or per project. 0 for unlimited."
+msgstr ""
+
+msgid "Includes an MVC structure to help you get started."
+msgstr ""
+
+msgid "Includes an MVC structure, Gemfile, Rakefile, along with many others, to help you get started."
+msgstr ""
+
+msgid "Includes an MVC structure, mvnw and pom.xml to help you get started."
+msgstr ""
+
+msgid "Includes repository storage, wiki storage, LFS objects, build artifacts and packages. 0 for unlimited."
+msgstr ""
+
+msgid "Incoming email"
+msgstr ""
+
+msgid "Incoming!"
+msgstr ""
+
+msgid "Incompatible Project"
+msgstr ""
+
+msgid "Incompatible options set!"
+msgstr ""
+
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
+msgid "Index all projects"
+msgstr ""
+
+msgid "Indicates whether this runner can pick jobs without tags"
+msgstr ""
+
+msgid "Inform users without uploaded SSH keys that they can't push over SSH until one is added"
+msgstr ""
+
+msgid "Information about additional Pages templates and how to install them can be found in our %{pages_getting_started_guide}."
+msgstr ""
+
+msgid "Inherited:"
+msgstr ""
+
+msgid "Inline"
+msgstr ""
+
+msgid "Input host keys manually"
+msgstr ""
+
+msgid "Input your repository URL"
+msgstr ""
+
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
+msgid "Insert a quote"
+msgstr ""
+
+msgid "Insert an image"
+msgstr ""
+
+msgid "Insert code"
+msgstr ""
+
+msgid "Insert inline code"
+msgstr ""
+
+msgid "Insert suggestion"
+msgstr ""
+
+msgid "Insights"
+msgstr ""
+
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Install"
+msgstr ""
+
+msgid "Install GitLab Runner"
+msgstr ""
+
+msgid "Install Runner on Kubernetes"
+msgstr ""
+
+msgid "Install a soft token authenticator like %{free_otp_link} or Google Authenticator from your application repository and use that app to scan this QR code. More information is available in the %{help_link_start}documentation%{help_link_end}."
+msgstr ""
+
+msgid "Install on clusters"
+msgstr ""
+
+msgid "Installed"
+msgstr ""
+
+msgid "Installing"
+msgstr ""
+
+msgid "Instance"
+msgid_plural "Instances"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Instance Statistics visibility"
+msgstr ""
+
+msgid "Instance administrators group already exists"
+msgstr ""
+
+msgid "Instance does not support multiple Kubernetes clusters"
+msgstr ""
+
+msgid "Instance license"
+msgstr ""
+
+msgid "Integration"
+msgstr ""
+
+msgid "Integration Settings"
+msgstr ""
+
+msgid "Integrations"
+msgstr ""
+
+msgid "Integrations allow you to integrate GitLab with other applications"
+msgstr ""
+
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "Interested parties can even contribute by pushing commits if they want to."
+msgstr ""
+
+msgid "Internal"
+msgstr ""
+
+msgid "Internal - The group and any internal projects can be viewed by any logged in user."
+msgstr ""
+
+msgid "Internal - The project can be accessed by any logged in user."
+msgstr ""
+
+msgid "Internal URL (optional)"
+msgstr ""
+
+msgid "Internal users"
+msgstr ""
+
+msgid "Interval Pattern"
+msgstr ""
+
+msgid "Introducing Value Stream Analytics"
+msgstr ""
+
+msgid "Introducing Your DevOps Score"
+msgstr ""
+
+msgid "Invalid Git ref"
+msgstr ""
+
+msgid "Invalid Insights config file detected"
+msgstr ""
+
+msgid "Invalid Login or password"
+msgstr ""
+
+msgid "Invalid URL"
+msgstr ""
+
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
+msgid "Invalid cursor value provided"
+msgstr ""
+
+msgid "Invalid date"
+msgstr ""
+
+msgid "Invalid date format. Please use UTC format as YYYY-MM-DD"
+msgstr ""
+
+msgid "Invalid date range"
+msgstr ""
+
+msgid "Invalid feature"
+msgstr ""
+
+msgid "Invalid field"
+msgstr ""
+
+msgid "Invalid file format with specified file type"
+msgstr ""
+
+msgid "Invalid file."
+msgstr ""
+
+msgid "Invalid import params"
+msgstr ""
+
+msgid "Invalid input, please avoid emojis"
+msgstr ""
+
+msgid "Invalid login or password"
+msgstr ""
+
+msgid "Invalid pin code"
+msgstr ""
+
+msgid "Invalid pod_name"
+msgstr ""
+
+msgid "Invalid query"
+msgstr ""
+
+msgid "Invalid repository path"
+msgstr ""
+
+msgid "Invalid search parameter"
+msgstr ""
+
+msgid "Invalid server response"
+msgstr ""
+
+msgid "Invalid start or end time format"
+msgstr ""
+
+msgid "Invalid status"
+msgstr ""
+
+msgid "Invalid two-factor code."
+msgstr ""
+
+msgid "Invitation"
+msgstr ""
+
+msgid "Invite"
+msgstr ""
+
+msgid "Invite \"%{trimmed}\" by email"
+msgstr ""
+
+msgid "Invite Members"
+msgstr ""
+
+msgid "Invite group"
+msgstr ""
+
+msgid "Invite member"
+msgstr ""
+
+msgid "Invocations"
+msgstr ""
+
+msgid "Is blocked by"
+msgstr ""
+
+msgid "Is this GitLab trial for your company?"
+msgstr ""
+
+msgid "Is using license seat:"
+msgstr ""
+
+msgid "Is using seat"
+msgstr ""
+
+msgid "IssuableStatus|Closed"
+msgstr ""
+
+msgid "IssuableStatus|Closed (%{link})"
+msgstr ""
+
+msgid "IssuableStatus|duplicated"
+msgstr ""
+
+msgid "IssuableStatus|moved"
+msgstr ""
+
+msgid "IssuableStatus|promoted"
+msgstr ""
+
+msgid "Issue"
+msgstr ""
+
+msgid "Issue %{issue_reference} has already been added to epic %{epic_reference}."
+msgstr ""
+
+msgid "Issue Boards"
+msgstr ""
+
+msgid "Issue already promoted to epic."
+msgstr ""
+
+msgid "Issue cannot be found."
+msgstr ""
+
+msgid "Issue events"
+msgstr ""
+
+msgid "Issue first depoloyed to production"
+msgstr ""
+
+msgid "Issue label"
+msgstr ""
+
+msgid "Issue or Merge Request ID is required"
+msgstr ""
+
+msgid "Issue published on status page."
+msgstr ""
+
+msgid "Issue template (optional)"
+msgstr ""
+
+msgid "Issue update failed"
+msgstr ""
+
+msgid "Issue was closed by %{name} %{reason}"
+msgstr ""
+
+msgid "Issue weight"
+msgstr ""
+
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
+msgid "IssueBoards|Board"
+msgstr ""
+
+msgid "IssueBoards|Boards"
+msgstr ""
+
+msgid "IssueBoards|Create new board"
+msgstr ""
+
+msgid "IssueBoards|Delete board"
+msgstr ""
+
+msgid "IssueBoards|No matching boards found"
+msgstr ""
+
+msgid "IssueBoards|Some of your boards are hidden, activate a license to see them again."
+msgstr ""
+
+msgid "IssueBoards|Switch board"
+msgstr ""
+
+msgid "IssueTracker|Bugzilla issue tracker"
+msgstr ""
+
+msgid "IssueTracker|Custom issue tracker"
+msgstr ""
+
+msgid "IssueTracker|GitLab issue tracker"
+msgstr ""
+
+msgid "IssueTracker|Redmine issue tracker"
+msgstr ""
+
+msgid "IssueTracker|YouTrack issue tracker"
+msgstr ""
+
+msgid "Issues"
+msgstr ""
+
+msgid "Issues Analytics"
+msgstr ""
+
+msgid "Issues Rate Limits"
+msgstr ""
+
+msgid "Issues and Merge Requests"
+msgstr ""
+
+msgid "Issues can be bugs, tasks or ideas to be discussed. Also, issues are searchable and filterable."
+msgstr ""
+
+msgid "Issues closed"
+msgstr ""
+
+msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
+msgstr ""
+
+msgid "Issues successfully imported with the label"
+msgstr ""
+
+msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
+msgstr ""
+
+msgid "Issues, merge requests, pushes, and comments."
+msgstr ""
+
+msgid "IssuesAnalytics|After you begin creating issues for your projects, we can start tracking and displaying metrics for them"
+msgstr ""
+
+msgid "IssuesAnalytics|Avg/Month:"
+msgstr ""
+
+msgid "IssuesAnalytics|Issues opened"
+msgstr ""
+
+msgid "IssuesAnalytics|Issues opened per month"
+msgstr ""
+
+msgid "IssuesAnalytics|Last 12 months"
+msgstr ""
+
+msgid "IssuesAnalytics|Sorry, your filter produced no results"
+msgstr ""
+
+msgid "IssuesAnalytics|There are no issues for the projects in your group"
+msgstr ""
+
+msgid "IssuesAnalytics|To widen your search, change or remove filters in the filter bar above"
+msgstr ""
+
+msgid "IssuesAnalytics|Total:"
+msgstr ""
+
+msgid "Issue|Title"
+msgstr ""
+
+msgid "It must have a header row and at least two columns: the first column is the issue title and the second column is the issue description. The separator is automatically detected."
+msgstr ""
+
+msgid "It seems like the Dependency Scanning job ran successfully, but no dependencies have been detected in your project."
+msgstr ""
+
+msgid "It's you"
+msgstr ""
+
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "Jaeger URL"
+msgstr ""
+
+msgid "Jaeger tracing"
+msgstr ""
+
+msgid "Jan"
+msgstr ""
+
+msgid "January"
+msgstr ""
+
+msgid "Jira import is already running."
+msgstr ""
+
+msgid "Jira integration not configured."
+msgstr ""
+
+msgid "Jira project: %{importProject}"
+msgstr ""
+
+msgid "Jira service not configured."
+msgstr ""
+
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
+msgstr ""
+
+msgid "JiraService|Events for %{noteable_model_name} are disabled."
+msgstr ""
+
+msgid "JiraService|If different from Web URL"
+msgstr ""
+
+msgid "JiraService|Jira API URL"
+msgstr ""
+
+msgid "JiraService|Jira comments will be created when an issue gets referenced in a commit."
+msgstr ""
+
+msgid "JiraService|Jira comments will be created when an issue gets referenced in a merge request."
+msgstr ""
+
+msgid "JiraService|Jira issue tracker"
+msgstr ""
+
+msgid "JiraService|Password or API token"
+msgstr ""
+
+msgid "JiraService|Transition ID(s)"
+msgstr ""
+
+msgid "JiraService|Use , or ; to separate multiple transition IDs"
+msgstr ""
+
+msgid "JiraService|Use a password for server version and an API token for cloud version"
+msgstr ""
+
+msgid "JiraService|Use a username for server version and an email for cloud version"
+msgstr ""
+
+msgid "JiraService|Username or Email"
+msgstr ""
+
+msgid "JiraService|Web URL"
+msgstr ""
+
+msgid "JiraService|transition ids can have only numbers which can be split with , or ;"
+msgstr ""
+
+msgid "Job"
+msgstr ""
+
+msgid "Job Failed #%{build_id}"
+msgstr ""
+
+msgid "Job ID"
+msgstr ""
+
+msgid "Job has been erased"
+msgstr ""
+
+msgid "Job has been successfully erased!"
+msgstr ""
+
+msgid "Job has wrong arguments format."
+msgstr ""
+
+msgid "Job is missing the `model_type` argument."
+msgstr ""
+
+msgid "Job is stuck. Check runners."
+msgstr ""
+
+msgid "Job logs and artifacts"
+msgstr ""
+
+msgid "Job to create self-monitoring project is in progress"
+msgstr ""
+
+msgid "Job to delete self-monitoring project is in progress"
+msgstr ""
+
+msgid "Job was retried"
+msgstr ""
+
+msgid "Jobs"
+msgstr ""
+
+msgid "Job|Browse"
+msgstr ""
+
+msgid "Job|Complete Raw"
+msgstr ""
+
+msgid "Job|Download"
+msgstr ""
+
+msgid "Job|Erase job log"
+msgstr ""
+
+msgid "Job|Job artifacts"
+msgstr ""
+
+msgid "Job|Job has been erased"
+msgstr ""
+
+msgid "Job|Job has been erased by"
+msgstr ""
+
+msgid "Job|Keep"
+msgstr ""
+
+msgid "Job|Pipeline"
+msgstr ""
+
+msgid "Job|Scroll to bottom"
+msgstr ""
+
+msgid "Job|Scroll to top"
+msgstr ""
+
+msgid "Job|Show complete raw"
+msgstr ""
+
+msgid "Job|The artifacts were removed"
+msgstr ""
+
+msgid "Job|The artifacts will be removed"
+msgstr ""
+
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
+msgid "Job|This job failed because the necessary resources were not successfully created."
+msgstr ""
+
+msgid "Job|This job is stuck because the project doesn't have any runners online assigned to it."
+msgstr ""
+
+msgid "Job|for"
+msgstr ""
+
+msgid "Job|into"
+msgstr ""
+
+msgid "Job|with"
+msgstr ""
+
+msgid "Join Zoom meeting"
+msgstr ""
+
+msgid "Jul"
+msgstr ""
+
+msgid "July"
+msgstr ""
+
+msgid "Jump to first unresolved thread"
+msgstr ""
+
+msgid "Jump to next unresolved thread"
+msgstr ""
+
+msgid "Jun"
+msgstr ""
+
+msgid "June"
+msgstr ""
+
+msgid "Just me"
+msgstr ""
+
+msgid "Keep divergent refs"
+msgstr ""
+
+msgid "Key"
+msgstr ""
+
+msgid "Key (PEM)"
+msgstr ""
+
+msgid "Key: %{key}"
+msgstr ""
+
+msgid "Keyboard Shortcuts"
+msgstr ""
+
+msgid "Keyboard shortcuts"
+msgstr ""
+
+msgid "Kubernetes"
+msgstr ""
+
+msgid "Kubernetes API returned status code: %{error_code}"
+msgstr ""
+
+msgid "Kubernetes Cluster"
+msgstr ""
+
+msgid "Kubernetes Clusters"
+msgstr ""
+
+msgid "Kubernetes cluster"
+msgstr ""
+
+msgid "Kubernetes cluster creation time exceeds timeout; %{timeout}"
+msgstr ""
+
+msgid "Kubernetes cluster integration and resources are being removed."
+msgstr ""
+
+msgid "Kubernetes cluster integration was successfully removed."
+msgstr ""
+
+msgid "Kubernetes cluster was successfully updated."
+msgstr ""
+
+msgid "Kubernetes deployment not found"
+msgstr ""
+
+msgid "Kubernetes error: %{error_code}"
+msgstr ""
+
+msgid "Kubernetes popover"
+msgstr ""
+
+msgid "LDAP"
+msgstr ""
+
+msgid "LDAP settings"
+msgstr ""
+
+msgid "LDAP settings updated"
+msgstr ""
+
+msgid "LDAP sync in progress. This could take a few minutes. Refresh the page to see the changes."
+msgstr ""
+
+msgid "LFS"
+msgstr ""
+
+msgid "LFS objects"
+msgstr ""
+
+msgid "LFSStatus|Disabled"
+msgstr ""
+
+msgid "LFSStatus|Enabled"
+msgstr ""
+
+msgid "LICENSE"
+msgstr ""
+
+msgid "Label"
+msgstr ""
+
+msgid "Label actions dropdown"
+msgstr ""
+
+msgid "Label lists show all issues with the selected label."
+msgstr ""
+
+msgid "Label was created"
+msgstr ""
+
+msgid "Label was removed"
+msgstr ""
+
+msgid "Label was successfully updated."
+msgstr ""
+
+msgid "LabelSelect|%{firstLabelName} +%{remainingLabelCount} more"
+msgstr ""
+
+msgid "LabelSelect|%{labelsString}, and %{remainingLabelCount} more"
+msgstr ""
+
+msgid "LabelSelect|Labels"
+msgstr ""
+
+msgid "Labels"
+msgstr ""
+
+msgid "Labels can be applied to %{features}. Group labels are available for any project within the group."
+msgstr ""
+
+msgid "Labels can be applied to issues and merge requests to categorize them."
+msgstr ""
+
+msgid "Labels can be applied to issues and merge requests."
+msgstr ""
+
+msgid "Labels|<span>Promote label</span> %{labelTitle} <span>to Group Label?</span>"
+msgstr ""
+
+msgid "Labels|Promote Label"
+msgstr ""
+
+msgid "Labels|Promoting %{labelTitle} will make it available for all projects inside %{groupName}. Existing project labels with the same title will be merged. If a group label with the same title exists, it will also be merged. This action cannot be reversed."
+msgstr ""
+
+msgid "Labels|and %{count} more"
+msgstr ""
+
+msgid "Language"
+msgstr ""
+
+msgid "Large File Storage"
+msgstr ""
+
+msgid "Last %d day"
+msgid_plural "Last %d days"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Last %{days} days"
+msgstr ""
+
+msgid "Last Accessed On"
+msgstr ""
+
+msgid "Last Name is too long (maximum is %{max_length} characters)."
+msgstr ""
+
+msgid "Last Pipeline"
+msgstr ""
+
+msgid "Last Seen"
+msgstr ""
+
+msgid "Last accessed on"
+msgstr ""
+
+msgid "Last activity"
+msgstr ""
+
+msgid "Last commit"
+msgstr ""
+
+msgid "Last contact"
+msgstr ""
+
+msgid "Last edited %{date}"
+msgstr ""
+
+msgid "Last edited by %{name}"
+msgstr ""
+
+msgid "Last name"
+msgstr ""
+
+msgid "Last reply by"
+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 ""
+
+msgid "Last successful sync"
+msgstr ""
+
+msgid "Last successful update"
+msgstr ""
+
+msgid "Last time verified"
+msgstr ""
+
+msgid "Last update"
+msgstr ""
+
+msgid "Last update attempt"
+msgstr ""
+
+msgid "Last updated"
+msgstr ""
+
+msgid "Last used"
+msgstr ""
+
+msgid "Last used on:"
+msgstr ""
+
+msgid "LastCommit|authored"
+msgstr ""
+
+msgid "LastPushEvent|You pushed to"
+msgstr ""
+
+msgid "LastPushEvent|at"
+msgstr ""
+
+msgid "Latest changes"
+msgstr ""
+
+msgid "Latest pipeline for the most recent commit on this branch"
+msgstr ""
+
+msgid "Lead"
+msgstr ""
+
+msgid "Lead Time"
+msgstr ""
+
+msgid "Learn GitLab"
+msgstr ""
+
+msgid "Learn More"
+msgstr ""
+
+msgid "Learn how to %{link_start}contribute to the built-in templates%{link_end}"
+msgstr ""
+
+msgid "Learn how to %{no_packages_link_start}publish and share your packages%{no_packages_link_end} with GitLab."
+msgstr ""
+
+msgid "Learn how to enable synchronization"
+msgstr ""
+
+msgid "Learn more"
+msgstr ""
+
+msgid "Learn more about Auto DevOps"
+msgstr ""
+
+msgid "Learn more about Kubernetes"
+msgstr ""
+
+msgid "Learn more about License-Check"
+msgstr ""
+
+msgid "Learn more about Vulnerability-Check"
+msgstr ""
+
+msgid "Learn more about Web Terminal"
+msgstr ""
+
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
+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 approvals."
+msgstr ""
+
+msgid "Learn more about custom project templates"
+msgstr ""
+
+msgid "Learn more about deploying to a cluster"
+msgstr ""
+
+msgid "Learn more about group-level project templates"
+msgstr ""
+
+msgid "Learn more about signing commits"
+msgstr ""
+
+msgid "Learn more about the dependency list"
+msgstr ""
+
+msgid "Learn more in the"
+msgstr ""
+
+msgid "Learn more in the|pipeline schedules documentation"
+msgstr ""
+
+msgid "Leave"
+msgstr ""
+
+msgid "Leave Admin Mode"
+msgstr ""
+
+msgid "Leave blank for no limit. Once set, existing personal access tokens may be revoked."
+msgstr ""
+
+msgid "Leave edit mode? All unsaved changes will be lost."
+msgstr ""
+
+msgid "Leave group"
+msgstr ""
+
+msgid "Leave project"
+msgstr ""
+
+msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
+msgstr ""
+
+msgid "Leave zen mode"
+msgstr ""
+
+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 ""
+
+msgid "License"
+msgstr ""
+
+msgid "License Compliance"
+msgstr ""
+
+msgid "License History"
+msgstr ""
+
+msgid "License-Check"
+msgstr ""
+
+msgid "LicenseCompliance|Add a license"
+msgstr ""
+
+msgid "LicenseCompliance|Add license and related policy"
+msgstr ""
+
+msgid "LicenseCompliance|Allow"
+msgstr ""
+
+msgid "LicenseCompliance|Allowed"
+msgstr ""
+
+msgid "LicenseCompliance|Cancel"
+msgstr ""
+
+msgid "LicenseCompliance|Denied"
+msgstr ""
+
+msgid "LicenseCompliance|Deny"
+msgstr ""
+
+msgid "LicenseCompliance|License"
+msgstr ""
+
+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] ""
+
+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] ""
+
+msgid "LicenseCompliance|License Compliance detected %d new license"
+msgid_plural "LicenseCompliance|License Compliance detected %d new licenses"
+msgstr[0] ""
+msgstr[1] ""
+
+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] ""
+
+msgid "LicenseCompliance|License Compliance detected no licenses for the source branch only"
+msgstr ""
+
+msgid "LicenseCompliance|License Compliance detected no new licenses"
+msgstr ""
+
+msgid "LicenseCompliance|License details"
+msgstr ""
+
+msgid "LicenseCompliance|License name"
+msgstr ""
+
+msgid "LicenseCompliance|License review"
+msgstr ""
+
+msgid "LicenseCompliance|Packages"
+msgstr ""
+
+msgid "LicenseCompliance|Remove license"
+msgstr ""
+
+msgid "LicenseCompliance|Remove license?"
+msgstr ""
+
+msgid "LicenseCompliance|Submit"
+msgstr ""
+
+msgid "LicenseCompliance|There are currently no approved or blacklisted licenses in this project."
+msgstr ""
+
+msgid "LicenseCompliance|There are currently no approved or blacklisted licenses that match in this project."
+msgstr ""
+
+msgid "LicenseCompliance|This license already exists in this project."
+msgstr ""
+
+msgid "LicenseCompliance|URL"
+msgstr ""
+
+msgid "LicenseCompliance|You are about to remove the license, %{name}, from this project."
+msgstr ""
+
+msgid "LicenseManagement|Allowed"
+msgstr ""
+
+msgid "LicenseManagement|Denied"
+msgstr ""
+
+msgid "LicenseManagement|Uncategorized"
+msgstr ""
+
+msgid "Licensed Features"
+msgstr ""
+
+msgid "Licensed to"
+msgstr ""
+
+msgid "Licenses"
+msgstr ""
+
+msgid "Licenses|%{remainingComponentsCount} more"
+msgstr ""
+
+msgid "Licenses|Component"
+msgstr ""
+
+msgid "Licenses|Components"
+msgstr ""
+
+msgid "Licenses|Detected in Project"
+msgstr ""
+
+msgid "Licenses|Detected licenses that are out-of-compliance with the project's assigned policies"
+msgstr ""
+
+msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
+msgstr ""
+
+msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
+msgstr ""
+
+msgid "Licenses|Learn more about license compliance"
+msgstr ""
+
+msgid "Licenses|License Compliance"
+msgstr ""
+
+msgid "Licenses|Name"
+msgstr ""
+
+msgid "Licenses|Policies"
+msgstr ""
+
+msgid "Licenses|Policy"
+msgstr ""
+
+msgid "Licenses|Policy violation: denied"
+msgstr ""
+
+msgid "Licenses|Specified policies in this project"
+msgstr ""
+
+msgid "Licenses|The license list details information about the licenses used within your project."
+msgstr ""
+
+msgid "Licenses|View license details for your project"
+msgstr ""
+
+msgid "License|Buy license"
+msgstr ""
+
+msgid "License|License"
+msgstr ""
+
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
+msgid "License|You can restore access to the Gold features at any time by upgrading."
+msgstr ""
+
+msgid "License|You can start a free trial of GitLab Ultimate without any obligation or payment details."
+msgstr ""
+
+msgid "License|You do not have a license."
+msgstr ""
+
+msgid "License|Your License"
+msgstr ""
+
+msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
+msgstr ""
+
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
+msgid "Limit display of time tracking units to hours."
+msgstr ""
+
+msgid "Limit namespaces and projects that can be indexed"
+msgstr ""
+
+msgid "Limited to showing %d event at most"
+msgid_plural "Limited to showing %d events at most"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Line changes"
+msgstr ""
+
+msgid "Link Prometheus monitoring to GitLab."
+msgstr ""
+
+msgid "Link copied"
+msgstr ""
+
+msgid "Link title"
+msgstr ""
+
+msgid "Link title is required"
+msgstr ""
+
+msgid "Linked emails (%{email_count})"
+msgstr ""
+
+msgid "Linked issues"
+msgstr ""
+
+msgid "LinkedIn"
+msgstr ""
+
+msgid "LinkedPipelines|%{counterLabel} more downstream pipelines"
+msgstr ""
+
+msgid "Links"
+msgstr ""
+
+msgid "List"
+msgstr ""
+
+msgid "List Your Gitea Repositories"
+msgstr ""
+
+msgid "List available repositories"
+msgstr ""
+
+msgid "List of IPs and CIDRs of allowed secondary nodes. Comma-separated, e.g. \"1.1.1.1, 2.2.2.0/24\""
+msgstr ""
+
+msgid "List settings"
+msgstr ""
+
+msgid "List the merge requests that must be merged before this one."
+msgstr ""
+
+msgid "List view"
+msgstr ""
+
+msgid "List your Bitbucket Server repositories"
+msgstr ""
+
+msgid "Live preview"
+msgstr ""
+
+msgid "Loading"
+msgstr ""
+
+msgid "Loading contribution stats for group members"
+msgstr ""
+
+msgid "Loading files, directories, and submodules in the path %{path} for commit reference %{ref}"
+msgstr ""
+
+msgid "Loading functions timed out. Please reload the page to try again."
+msgstr ""
+
+msgid "Loading issues"
+msgstr ""
+
+msgid "Loading snippet"
+msgstr ""
+
+msgid "Loading the GitLab IDE..."
+msgstr ""
+
+msgid "Loading..."
+msgstr ""
+
+msgid "Loading…"
+msgstr ""
+
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
+msgid "Localization"
+msgstr ""
+
+msgid "Location"
+msgstr ""
+
+msgid "Lock"
+msgstr ""
+
+msgid "Lock %{issuableDisplayName}"
+msgstr ""
+
+msgid "Lock memberships to LDAP synchronization"
+msgstr ""
+
+msgid "Lock not found"
+msgstr ""
+
+msgid "Lock the discussion"
+msgstr ""
+
+msgid "Lock this %{issuableDisplayName}? Only <strong>project members</strong> will be able to comment."
+msgstr ""
+
+msgid "Lock to current projects"
+msgstr ""
+
+msgid "Locked"
+msgstr ""
+
+msgid "Locked Files"
+msgstr ""
+
+msgid "Locked by %{fileLockUserName}"
+msgstr ""
+
+msgid "Locked the discussion."
+msgstr ""
+
+msgid "Locked to current projects"
+msgstr ""
+
+msgid "Locks give the ability to lock specific file or folder."
+msgstr ""
+
+msgid "Locks the discussion."
+msgstr ""
+
+msgid "Login with smartcard"
+msgstr ""
+
+msgid "Logo was successfully removed."
+msgstr ""
+
+msgid "Logs"
+msgstr ""
+
+msgid "Logs|To see the logs, deploy your code to an environment."
+msgstr ""
+
+msgid "Low vulnerabilities present"
+msgstr ""
+
+msgid "MB"
+msgstr ""
+
+msgid "MD5"
+msgstr ""
+
+msgid "MERGED"
+msgstr ""
+
+msgid "MR widget|Take a look at our %{beginnerLinkStart}Beginner's Guide to Continuous Integration%{beginnerLinkEnd} and our %{exampleLinkStart}examples of GitLab CI/CD%{exampleLinkEnd} to see all the cool stuff you can do with it."
+msgstr ""
+
+msgid "MR widget|The pipeline will now run automatically every time you commit code. Pipelines are useful for deploying static web pages, detecting vulnerabilities in dependencies, static or dynamic application security testing (SAST and DAST), and so much more!"
+msgstr ""
+
+msgid "MRApprovals|Approvals"
+msgstr ""
+
+msgid "MRApprovals|Approved by"
+msgstr ""
+
+msgid "MRApprovals|Approvers"
+msgstr ""
+
+msgid "MRDiff|Show changes only"
+msgstr ""
+
+msgid "MRDiff|Show full file"
+msgstr ""
+
+msgid "Made this issue confidential."
+msgstr ""
+
+msgid "Maintenance mode"
+msgstr ""
+
+msgid "Make and review changes in the browser with the Web IDE"
+msgstr ""
+
+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 ""
+
+msgid "Make issue confidential"
+msgstr ""
+
+msgid "Make sure you save it - you won't be able to access it again."
+msgstr ""
+
+msgid "Make sure you're logged into the account that owns the projects you'd like to import."
+msgstr ""
+
+msgid "Make this epic confidential"
+msgstr ""
+
+msgid "Makes this issue confidential."
+msgstr ""
+
+msgid "Manage"
+msgstr ""
+
+msgid "Manage Web IDE features"
+msgstr ""
+
+msgid "Manage access"
+msgstr ""
+
+msgid "Manage all notifications"
+msgstr ""
+
+msgid "Manage applications that can use GitLab as an OAuth provider, and applications that you've authorized to use your account."
+msgstr ""
+
+msgid "Manage applications that you've authorized to use your account."
+msgstr ""
+
+msgid "Manage group labels"
+msgstr ""
+
+msgid "Manage labels"
+msgstr ""
+
+msgid "Manage milestones"
+msgstr ""
+
+msgid "Manage project labels"
+msgstr ""
+
+msgid "Manage two-factor authentication"
+msgstr ""
+
+msgid "Manage your license"
+msgstr ""
+
+msgid "Managed Account"
+msgstr ""
+
+msgid "Manifest"
+msgstr ""
+
+msgid "Manifest file import"
+msgstr ""
+
+msgid "Manual job"
+msgstr ""
+
+msgid "ManualOrdering|Couldn't save the order of the issues"
+msgstr ""
+
+msgid "Map a FogBugz account ID to a GitLab user"
+msgstr ""
+
+msgid "Map a Google Code user to a GitLab user"
+msgstr ""
+
+msgid "Map a Google Code user to a full email address"
+msgstr ""
+
+msgid "Map a Google Code user to a full name"
+msgstr ""
+
+msgid "Mar"
+msgstr ""
+
+msgid "March"
+msgstr ""
+
+msgid "Mark To Do as done"
+msgstr ""
+
+msgid "Mark as done"
+msgstr ""
+
+msgid "Mark as resolved"
+msgstr ""
+
+msgid "Mark this issue as a duplicate of another issue"
+msgstr ""
+
+msgid "Mark this issue as related to another issue"
+msgstr ""
+
+msgid "Markdown"
+msgstr ""
+
+msgid "Markdown enabled"
+msgstr ""
+
+msgid "Markdown is supported"
+msgstr ""
+
+msgid "Marked To Do as done."
+msgstr ""
+
+msgid "Marked this %{noun} as Work In Progress."
+msgstr ""
+
+msgid "Marked this issue as a duplicate of %{duplicate_param}."
+msgstr ""
+
+msgid "Marked this issue as related to %{issue_ref}."
+msgstr ""
+
+msgid "Marks To Do as done."
+msgstr ""
+
+msgid "Marks this %{noun} as Work In Progress."
+msgstr ""
+
+msgid "Marks this issue as a duplicate of %{duplicate_reference}."
+msgstr ""
+
+msgid "Marks this issue as related to %{issue_ref}."
+msgstr ""
+
+msgid "Mask variable"
+msgstr ""
+
+msgid "Match not found; try refining your search query."
+msgstr ""
+
+msgid "MattermostService|Add to Mattermost"
+msgstr ""
+
+msgid "MattermostService|Command trigger word"
+msgstr ""
+
+msgid "MattermostService|Fill in the word that works best for your team."
+msgstr ""
+
+msgid "MattermostService|Request URL"
+msgstr ""
+
+msgid "MattermostService|Request method"
+msgstr ""
+
+msgid "MattermostService|Response icon"
+msgstr ""
+
+msgid "MattermostService|Response username"
+msgstr ""
+
+msgid "MattermostService|See list of available commands in Mattermost after setting up this service, by entering"
+msgstr ""
+
+msgid "MattermostService|Suggestions:"
+msgstr ""
+
+msgid "MattermostService|This service allows users to perform common operations on this project by entering slash commands in Mattermost."
+msgstr ""
+
+msgid "Maven Metadata"
+msgstr ""
+
+msgid "Max access level"
+msgstr ""
+
+msgid "Max seats used"
+msgstr ""
+
+msgid "Maximum Users:"
+msgstr ""
+
+msgid "Maximum allowable lifetime for personal access token (days)"
+msgstr ""
+
+msgid "Maximum artifacts size (MB)"
+msgstr ""
+
+msgid "Maximum attachment size (MB)"
+msgstr ""
+
+msgid "Maximum bulk request size (MiB)"
+msgstr ""
+
+msgid "Maximum capacity"
+msgstr ""
+
+msgid "Maximum concurrency of Elasticsearch bulk requests per indexing operation."
+msgstr ""
+
+msgid "Maximum delay (Minutes)"
+msgstr ""
+
+msgid "Maximum duration of a session."
+msgstr ""
+
+msgid "Maximum field length"
+msgstr ""
+
+msgid "Maximum job timeout"
+msgstr ""
+
+msgid "Maximum job timeout has a value which could not be accepted"
+msgstr ""
+
+msgid "Maximum lifetime allowable for Personal Access Tokens is active, your expire date must be set before %{maximum_allowable_date}."
+msgstr ""
+
+msgid "Maximum namespace storage (MB)"
+msgstr ""
+
+msgid "Maximum number of %{name} (%{count}) exceeded"
+msgstr ""
+
+msgid "Maximum number of comments exceeded"
+msgstr ""
+
+msgid "Maximum number of mirrors that can be synchronizing at the same time."
+msgstr ""
+
+msgid "Maximum number of projects."
+msgstr ""
+
+msgid "Maximum page reached"
+msgstr ""
+
+msgid "Maximum push size (MB)"
+msgstr ""
+
+msgid "Maximum size limit for a single commit."
+msgstr ""
+
+msgid "Maximum size limit for each repository."
+msgstr ""
+
+msgid "Maximum size of Elasticsearch bulk indexing requests."
+msgstr ""
+
+msgid "Maximum size of individual attachments in comments."
+msgstr ""
+
+msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
+msgstr ""
+
+msgid "May"
+msgstr ""
+
+msgid "Measured in bytes of code. Excludes generated and vendored code."
+msgstr ""
+
+msgid "Median"
+msgstr ""
+
+msgid "Medium vulnerabilities present"
+msgstr ""
+
+msgid "Member lock"
+msgstr ""
+
+msgid "Member since %{date}"
+msgstr ""
+
+msgid "Members"
+msgstr ""
+
+msgid "Members can be added by project <i>Maintainers</i> or <i>Owners</i>"
+msgstr ""
+
+msgid "Members of <strong>%{project_name}</strong>"
+msgstr ""
+
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
+msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
+msgstr ""
+
+msgid "Members with pending access to %{strong_start}%{group_name}%{strong_end}"
+msgstr ""
+
+msgid "Memory Usage"
+msgstr ""
+
+msgid "Merge"
+msgstr ""
+
+msgid "Merge (when the pipeline succeeds)"
+msgstr ""
+
+msgid "Merge Request"
+msgstr ""
+
+msgid "Merge Request Approvals"
+msgstr ""
+
+msgid "Merge Request Commits"
+msgstr ""
+
+msgid "Merge Requests"
+msgstr ""
+
+msgid "Merge Requests created"
+msgstr ""
+
+msgid "Merge Requests in Review"
+msgstr ""
+
+msgid "Merge automatically (%{strategy})"
+msgstr ""
+
+msgid "Merge commit message"
+msgstr ""
+
+msgid "Merge events"
+msgstr ""
+
+msgid "Merge immediately"
+msgstr ""
+
+msgid "Merge in progress"
+msgstr ""
+
+msgid "Merge options"
+msgstr ""
+
+msgid "Merge request"
+msgstr ""
+
+msgid "Merge request %{iid} authored by %{authorName}"
+msgstr ""
+
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
+msgid "Merge request approvals"
+msgstr ""
+
+msgid "Merge request approvals allow you to set the number of necessary approvals and predefine a list of approvers that will need to approve every merge request in a project."
+msgstr ""
+
+msgid "Merge request dependencies"
+msgstr ""
+
+msgid "Merge requests"
+msgstr ""
+
+msgid "Merge requests approvals"
+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 when pipeline succeeds"
+msgstr ""
+
+msgid "MergeConflict|Commit to source branch"
+msgstr ""
+
+msgid "MergeConflict|Committing..."
+msgstr ""
+
+msgid "MergeConflict|HEAD//our changes"
+msgstr ""
+
+msgid "MergeConflict|Use ours"
+msgstr ""
+
+msgid "MergeConflict|Use theirs"
+msgstr ""
+
+msgid "MergeConflict|conflict"
+msgstr ""
+
+msgid "MergeConflict|conflicts"
+msgstr ""
+
+msgid "MergeConflict|origin//their changes"
+msgstr ""
+
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
+msgid "MergeRequests|Add a reply"
+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."
+msgstr ""
+
+msgid "MergeRequests|Jump to next unresolved thread"
+msgstr ""
+
+msgid "MergeRequests|Reply..."
+msgstr ""
+
+msgid "MergeRequests|Resolve this thread in a new issue"
+msgstr ""
+
+msgid "MergeRequests|Saving the comment failed"
+msgstr ""
+
+msgid "MergeRequests|Squash task canceled: another squash is already in progress."
+msgstr ""
+
+msgid "MergeRequests|Thread stays resolved"
+msgstr ""
+
+msgid "MergeRequests|Thread stays unresolved"
+msgstr ""
+
+msgid "MergeRequests|Thread will be resolved"
+msgstr ""
+
+msgid "MergeRequests|Thread will be unresolved"
+msgstr ""
+
+msgid "MergeRequests|Toggle comments for this file"
+msgstr ""
+
+msgid "MergeRequests|View file @ %{commitId}"
+msgstr ""
+
+msgid "MergeRequests|View replaced file @ %{commitId}"
+msgstr ""
+
+msgid "MergeRequests|commented on commit %{commitLink}"
+msgstr ""
+
+msgid "MergeRequests|started a thread"
+msgstr ""
+
+msgid "MergeRequests|started a thread on %{linkStart}an old version of the diff%{linkEnd}"
+msgstr ""
+
+msgid "MergeRequests|started a thread on %{linkStart}the diff%{linkEnd}"
+msgstr ""
+
+msgid "MergeRequests|started a thread on an outdated change in commit %{linkStart}%{commitDisplay}%{linkEnd}"
+msgstr ""
+
+msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
+msgstr ""
+
+msgid "MergeRequest|Compare %{target} and %{source}"
+msgstr ""
+
+msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
+msgstr ""
+
+msgid "MergeRequest|Error loading full diff. Please try again."
+msgstr ""
+
+msgid "MergeRequest|No files found"
+msgstr ""
+
+msgid "MergeRequest|Search files (%{modifier_key}P)"
+msgstr ""
+
+msgid "Merged"
+msgstr ""
+
+msgid "Merged MRs"
+msgstr ""
+
+msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
+msgstr ""
+
+msgid "Merged this merge request."
+msgstr ""
+
+msgid "Merges this merge request immediately."
+msgstr ""
+
+msgid "Merges this merge request when the pipeline succeeds."
+msgstr ""
+
+msgid "Merging immediately isn't recommended as it may negatively impact the existing merge train. Read the %{docsLinkStart}documentation%{docsLinkEnd} for more information."
+msgstr ""
+
+msgid "Messages"
+msgstr ""
+
+msgid "Method"
+msgstr ""
+
+msgid "Metric was successfully added."
+msgstr ""
+
+msgid "Metric was successfully updated."
+msgstr ""
+
+msgid "Metric:"
+msgstr ""
+
+msgid "MetricChart|Please select a metric"
+msgstr ""
+
+msgid "MetricChart|Selected"
+msgstr ""
+
+msgid "Metrics"
+msgstr ""
+
+msgid "Metrics - Grafana"
+msgstr ""
+
+msgid "Metrics - Prometheus"
+msgstr ""
+
+msgid "Metrics Dashboard"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
+msgstr ""
+
+msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
+msgstr ""
+
+msgid "Metrics::Dashboard::Annotation|Annotation has not been deleted"
+msgstr ""
+
+msgid "Metrics::Dashboard::Annotation|Annotation must belong to a cluster or an environment"
+msgstr ""
+
+msgid "Metrics::Dashboard::Annotation|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::Dashboard::Annotation|You are not authorized to create annotation for selected cluster"
+msgstr ""
+
+msgid "Metrics::Dashboard::Annotation|You are not authorized to create annotation for selected environment"
+msgstr ""
+
+msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
+msgstr ""
+
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
+msgid "Metrics|Add metric"
+msgstr ""
+
+msgid "Metrics|Avg"
+msgstr ""
+
+msgid "Metrics|Check out the CI/CD documentation on deploying to an environment"
+msgstr ""
+
+msgid "Metrics|Create custom dashboard %{fileName}"
+msgstr ""
+
+msgid "Metrics|Create metric"
+msgstr ""
+
+msgid "Metrics|Delete metric"
+msgstr ""
+
+msgid "Metrics|Delete metric?"
+msgstr ""
+
+msgid "Metrics|Duplicate"
+msgstr ""
+
+msgid "Metrics|Duplicate dashboard"
+msgstr ""
+
+msgid "Metrics|Duplicating..."
+msgstr ""
+
+msgid "Metrics|Edit metric"
+msgid_plural "Metrics|Edit metrics"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Metrics|Expand panel"
+msgstr ""
+
+msgid "Metrics|For grouping similar metrics"
+msgstr ""
+
+msgid "Metrics|Go back (Esc)"
+msgstr ""
+
+msgid "Metrics|Invalid time range, please verify."
+msgstr ""
+
+msgid "Metrics|Label of the y-axis (usually the unit). The x-axis always represents time."
+msgstr ""
+
+msgid "Metrics|Legend label (optional)"
+msgstr ""
+
+msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
+msgstr ""
+
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
+msgid "Metrics|Max"
+msgstr ""
+
+msgid "Metrics|Must be a valid PromQL query."
+msgstr ""
+
+msgid "Metrics|New metric"
+msgstr ""
+
+msgid "Metrics|PromQL query is valid"
+msgstr ""
+
+msgid "Metrics|Prometheus Query Documentation"
+msgstr ""
+
+msgid "Metrics|Refresh dashboard"
+msgstr ""
+
+msgid "Metrics|Star dashboard"
+msgstr ""
+
+msgid "Metrics|There was an error creating the dashboard."
+msgstr ""
+
+msgid "Metrics|There was an error creating the dashboard. %{error}"
+msgstr ""
+
+msgid "Metrics|There was an error fetching annotations. Please try again."
+msgstr ""
+
+msgid "Metrics|There was an error fetching the environments data, please try again"
+msgstr ""
+
+msgid "Metrics|There was an error getting annotations information."
+msgstr ""
+
+msgid "Metrics|There was an error getting deployment information."
+msgstr ""
+
+msgid "Metrics|There was an error getting environments information."
+msgstr ""
+
+msgid "Metrics|There was an error trying to validate your query"
+msgstr ""
+
+msgid "Metrics|There was an error while retrieving metrics"
+msgstr ""
+
+msgid "Metrics|There was an error while retrieving metrics. %{message}"
+msgstr ""
+
+msgid "Metrics|Unexpected deployment data response from prometheus endpoint"
+msgstr ""
+
+msgid "Metrics|Unit label"
+msgstr ""
+
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
+msgid "Metrics|Used as a title for the chart"
+msgstr ""
+
+msgid "Metrics|Used if the query returns a single series. If it returns multiple series, their legend labels will be picked up from the response."
+msgstr ""
+
+msgid "Metrics|Validating query"
+msgstr ""
+
+msgid "Metrics|Values"
+msgstr ""
+
+msgid "Metrics|View logs"
+msgstr ""
+
+msgid "Metrics|Y-axis label"
+msgstr ""
+
+msgid "Metrics|You can save a copy of this dashboard to your repository so it can be customized. Select a file name and branch to save it."
+msgstr ""
+
+msgid "Metrics|You're about to permanently delete this metric. This cannot be undone."
+msgstr ""
+
+msgid "Metrics|e.g. HTTP requests"
+msgstr ""
+
+msgid "Metrics|e.g. Requests/second"
+msgstr ""
+
+msgid "Metrics|e.g. Throughput"
+msgstr ""
+
+msgid "Metrics|e.g. rate(http_requests_total[5m])"
+msgstr ""
+
+msgid "Metrics|e.g. req/sec"
+msgstr ""
+
+msgid "Microsoft Azure"
+msgstr ""
+
+msgid "Middleman project with Static Site Editor support"
+msgstr ""
+
+msgid "Migrated %{success_count}/%{total_count} files."
+msgstr ""
+
+msgid "Migration successful."
+msgstr ""
+
+msgid "Milestone"
+msgid_plural "Milestones"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Milestone lists not available with your current license"
+msgstr ""
+
+msgid "Milestone lists show all issues from the selected milestone."
+msgstr ""
+
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
+msgid "Milestones"
+msgstr ""
+
+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 ""
+
+msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
+msgstr ""
+
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
+msgid "Milestones|Delete milestone"
+msgstr ""
+
+msgid "Milestones|Delete milestone %{milestoneTitle}?"
+msgstr ""
+
+msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
+msgstr ""
+
+msgid "Milestones|Group Milestone"
+msgstr ""
+
+msgid "Milestones|Milestone %{milestoneTitle} was not found"
+msgstr ""
+
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
+msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
+msgstr ""
+
+msgid "Milestones|Promote Milestone"
+msgstr ""
+
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
+msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
+msgstr ""
+
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
+msgid "Milestones|This action cannot be reversed."
+msgstr ""
+
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
+msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
+msgstr ""
+
+msgid "Minimum length is %{minimum_password_length} characters"
+msgstr ""
+
+msgid "Minimum length is %{minimum_password_length} characters."
+msgstr ""
+
+msgid "Minimum password length (number of characters)"
+msgstr ""
+
+msgid "Minutes"
+msgstr ""
+
+msgid "Mirror direction"
+msgstr ""
+
+msgid "Mirror repository"
+msgstr ""
+
+msgid "Mirror settings are only available to GitLab administrators."
+msgstr ""
+
+msgid "Mirror user"
+msgstr ""
+
+msgid "Mirrored branches will have this prefix. If you enabled 'Only mirror protected branches' you need to include this prefix on protected branches in this project or nothing will be mirrored."
+msgstr ""
+
+msgid "Mirrored repositories"
+msgstr ""
+
+msgid "Mirroring repositories"
+msgstr ""
+
+msgid "Mirroring settings were successfully updated."
+msgstr ""
+
+msgid "Mirroring settings were successfully updated. The project is being updated."
+msgstr ""
+
+msgid "Mirroring was successfully disabled."
+msgstr ""
+
+msgid "Mirroring will only be available if the feature is included in the plan of the selected group or user."
+msgstr ""
+
+msgid "Missing commit signatures endpoint!"
+msgstr ""
+
+msgid "MissingSSHKeyWarningLink|Add SSH key"
+msgstr ""
+
+msgid "MissingSSHKeyWarningLink|Don't show again"
+msgstr ""
+
+msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
+msgstr ""
+
+msgid "ModalButton|Add projects"
+msgstr ""
+
+msgid "Modal|Cancel"
+msgstr ""
+
+msgid "Modal|Close"
+msgstr ""
+
+msgid "Modified"
+msgstr ""
+
+msgid "Modified in this version"
+msgstr ""
+
+msgid "Modify commit message"
+msgstr ""
+
+msgid "Modify commit messages"
+msgstr ""
+
+msgid "Modify merge commit"
+msgstr ""
+
+msgid "Monday"
+msgstr ""
+
+msgid "Monitor your errors by integrating with Sentry."
+msgstr ""
+
+msgid "Monitoring"
+msgstr ""
+
+msgid "Months"
+msgstr ""
+
+msgid "More"
+msgstr ""
+
+msgid "More Information"
+msgstr ""
+
+msgid "More Slack commands"
+msgstr ""
+
+msgid "More actions"
+msgstr ""
+
+msgid "More details"
+msgstr ""
+
+msgid "More info"
+msgstr ""
+
+msgid "More information"
+msgstr ""
+
+msgid "More information and share feedback"
+msgstr ""
+
+msgid "More information is available|here"
+msgstr ""
+
+msgid "More than %{number_commits_distance} commits different with %{default_branch}"
+msgstr ""
+
+msgid "Most stars"
+msgstr ""
+
+msgid "Mount point %{mounted_as} not found in %{model_class}."
+msgstr ""
+
+msgid "Move"
+msgstr ""
+
+msgid "Move issue"
+msgstr ""
+
+msgid "Move issue from one column of the board to another"
+msgstr ""
+
+msgid "Move selection down"
+msgstr ""
+
+msgid "Move selection up"
+msgstr ""
+
+msgid "Move this issue to another project."
+msgstr ""
+
+msgid "MoveIssue|Cannot move issue due to insufficient permissions!"
+msgstr ""
+
+msgid "MoveIssue|Cannot move issue to project it originates from!"
+msgstr ""
+
+msgid "Moved issue to %{label} column in the board."
+msgstr ""
+
+msgid "Moved this issue to %{path_to_project}."
+msgstr ""
+
+msgid "Moves issue to %{label} column in the board."
+msgstr ""
+
+msgid "Moves this issue to %{path_to_project}."
+msgstr ""
+
+msgid "MrDeploymentActions|Deploy"
+msgstr ""
+
+msgid "MrDeploymentActions|Re-deploy"
+msgstr ""
+
+msgid "MrDeploymentActions|Stop environment"
+msgstr ""
+
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
+msgid "Multiple issue boards"
+msgstr ""
+
+msgid "Multiple model types found: %{model_types}"
+msgstr ""
+
+msgid "Multiple uploaders found: %{uploader_types}"
+msgstr ""
+
+msgid "My Awesome Group"
+msgstr ""
+
+msgid "My company or team"
+msgstr ""
+
+msgid "My-Reaction"
+msgstr ""
+
+msgid "Name"
+msgstr ""
+
+msgid "Name has already been taken"
+msgstr ""
+
+msgid "Name new label"
+msgstr ""
+
+msgid "Name:"
+msgstr ""
+
+msgid "Namespace is empty"
+msgstr ""
+
+msgid "Namespaces to index"
+msgstr ""
+
+msgid "Naming, topics, avatar"
+msgstr ""
+
+msgid "Naming, visibility"
+msgstr ""
+
+msgid "Navigate to the project to close the milestone."
+msgstr ""
+
+msgid "Nav|Help"
+msgstr ""
+
+msgid "Nav|Home"
+msgstr ""
+
+msgid "Nav|Sign In / Register"
+msgstr ""
+
+msgid "Nav|Sign out and sign in with a different account"
+msgstr ""
+
+msgid "Need help?"
+msgstr ""
+
+msgid "Needs attention"
+msgstr ""
+
+msgid "Network"
+msgstr ""
+
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
+msgid "Never"
+msgstr ""
+
+msgid "New"
+msgstr ""
+
+msgid "New Application"
+msgstr ""
+
+msgid "New Environment"
+msgstr ""
+
+msgid "New Geo Node"
+msgstr ""
+
+msgid "New Group"
+msgstr ""
+
+msgid "New Group Name"
+msgstr ""
+
+msgid "New Identity"
+msgstr ""
+
+msgid "New Issue"
+msgid_plural "New Issues"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "New Iteration"
+msgstr ""
+
+msgid "New Jira import"
+msgstr ""
+
+msgid "New Label"
+msgstr ""
+
+msgid "New Milestone"
+msgstr ""
+
+msgid "New Pages Domain"
+msgstr ""
+
+msgid "New Password"
+msgstr ""
+
+msgid "New Pipeline Schedule"
+msgstr ""
+
+msgid "New Project"
+msgstr ""
+
+msgid "New Snippet"
+msgstr ""
+
+msgid "New branch"
+msgstr ""
+
+msgid "New branch unavailable"
+msgstr ""
+
+msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
+msgstr ""
+
+msgid "New deploy key"
+msgstr ""
+
+msgid "New directory"
+msgstr ""
+
+msgid "New environment"
+msgstr ""
+
+msgid "New epic"
+msgstr ""
+
+msgid "New epic title"
+msgstr ""
+
+msgid "New file"
+msgstr ""
+
+msgid "New group"
+msgstr ""
+
+msgid "New health check access token has been generated!"
+msgstr ""
+
+msgid "New identity"
+msgstr ""
+
+msgid "New issue"
+msgstr ""
+
+msgid "New issue title"
+msgstr ""
+
+msgid "New iteration created"
+msgstr ""
+
+msgid "New label"
+msgstr ""
+
+msgid "New merge request"
+msgstr ""
+
+msgid "New milestone"
+msgstr ""
+
+msgid "New password"
+msgstr ""
+
+msgid "New pipelines will cancel older, pending pipelines on the same branch"
+msgstr ""
+
+msgid "New project"
+msgstr ""
+
+msgid "New release"
+msgstr ""
+
+msgid "New requirement"
+msgstr ""
+
+msgid "New runners registration token has been generated!"
+msgstr ""
+
+msgid "New schedule"
+msgstr ""
+
+msgid "New snippet"
+msgstr ""
+
+msgid "New subgroup"
+msgstr ""
+
+msgid "New tag"
+msgstr ""
+
+msgid "New users set to external"
+msgstr ""
+
+msgid "New! Suggest changes directly"
+msgstr ""
+
+msgid "New..."
+msgstr ""
+
+msgid "Newest first"
+msgstr ""
+
+msgid "Newly registered users will by default be external"
+msgstr ""
+
+msgid "Next"
+msgstr ""
+
+msgid "Next commit"
+msgstr ""
+
+msgid "Next file in diff"
+msgstr ""
+
+msgid "Next unresolved discussion"
+msgstr ""
+
+msgid "Nickname"
+msgstr ""
+
+msgid "No"
+msgstr ""
+
+msgid "No %{header} for this request."
+msgstr ""
+
+msgid "No %{providerTitle} repositories found"
+msgstr ""
+
+msgid "No Epic"
+msgstr ""
+
+msgid "No Scopes"
+msgstr ""
+
+msgid "No Tag"
+msgstr ""
+
+msgid "No active admin user found"
+msgstr ""
+
+msgid "No activities found"
+msgstr ""
+
+msgid "No application_settings found"
+msgstr ""
+
+msgid "No approvers"
+msgstr ""
+
+msgid "No authentication methods configured."
+msgstr ""
+
+msgid "No available namespaces to fork the project."
+msgstr ""
+
+msgid "No branches found"
+msgstr ""
+
+msgid "No changes"
+msgstr ""
+
+msgid "No changes between %{ref_start}%{source_branch}%{ref_end} and %{ref_start}%{target_branch}%{ref_end}"
+msgstr ""
+
+msgid "No child epics match applied filters"
+msgstr ""
+
+msgid "No connection could be made to a Gitaly Server, please check your logs!"
+msgstr ""
+
+msgid "No containers available"
+msgstr ""
+
+msgid "No contributions"
+msgstr ""
+
+msgid "No contributions were found"
+msgstr ""
+
+msgid "No credit card required."
+msgstr ""
+
+msgid "No data found"
+msgstr ""
+
+msgid "No data to display"
+msgstr ""
+
+msgid "No deployments found"
+msgstr ""
+
+msgid "No due date"
+msgstr ""
+
+msgid "No endpoint provided"
+msgstr ""
+
+msgid "No errors to display."
+msgstr ""
+
+msgid "No estimate or time spent"
+msgstr ""
+
+msgid "No file chosen"
+msgstr ""
+
+msgid "No file hooks found."
+msgstr ""
+
+msgid "No file selected"
+msgstr ""
+
+msgid "No files"
+msgstr ""
+
+msgid "No files found."
+msgstr ""
+
+msgid "No forks are available to you."
+msgstr ""
+
+msgid "No grouping"
+msgstr ""
+
+msgid "No job log"
+msgstr ""
+
+msgid "No jobs to show"
+msgstr ""
+
+msgid "No label"
+msgstr ""
+
+msgid "No labels with such name or description"
+msgstr ""
+
+msgid "No license. All rights reserved"
+msgstr ""
+
+msgid "No licenses found."
+msgstr ""
+
+msgid "No matches found"
+msgstr ""
+
+msgid "No matching labels"
+msgstr ""
+
+msgid "No matching results"
+msgstr ""
+
+msgid "No merge requests found"
+msgstr ""
+
+msgid "No messages were logged"
+msgstr ""
+
+msgid "No milestone"
+msgstr ""
+
+msgid "No milestones to show"
+msgstr ""
+
+msgid "No other labels with such name or description"
+msgstr ""
+
+msgid "No parent group"
+msgstr ""
+
+msgid "No pods available"
+msgstr ""
+
+msgid "No policy matches this license"
+msgstr ""
+
+msgid "No preview for this file type"
+msgstr ""
+
+msgid "No prioritized labels with such name or description"
+msgstr ""
+
+msgid "No public groups"
+msgstr ""
+
+msgid "No related merge requests found."
+msgstr ""
+
+msgid "No repository"
+msgstr ""
+
+msgid "No required pipeline"
+msgstr ""
+
+msgid "No runners found"
+msgstr ""
+
+msgid "No schedules"
+msgstr ""
+
+msgid "No starrers matched your search"
+msgstr ""
+
+msgid "No start date"
+msgstr ""
+
+msgid "No template"
+msgstr ""
+
+msgid "No test coverage"
+msgstr ""
+
+msgid "No thanks, don't show this again"
+msgstr ""
+
+msgid "No vulnerabilities present"
+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, directly import the existing email addresses and usernames."
+msgstr ""
+
+msgid "No, not interested right now"
+msgstr ""
+
+msgid "No. of commits"
+msgstr ""
+
+msgid "Nobody has starred this repository yet"
+msgstr ""
+
+msgid "Node was successfully created."
+msgstr ""
+
+msgid "Node was successfully updated."
+msgstr ""
+
+msgid "Nodes"
+msgstr ""
+
+msgid "Non-admin users can sign in with read-only access and make read-only API requests."
+msgstr ""
+
+msgid "None"
+msgstr ""
+
+msgid "Not Implemented"
+msgstr ""
+
+msgid "Not all data has been processed yet, the accuracy of the chart for the selected timeframe is limited."
+msgstr ""
+
+msgid "Not available"
+msgstr ""
+
+msgid "Not available for private projects"
+msgstr ""
+
+msgid "Not available for protected branches"
+msgstr ""
+
+msgid "Not confidential"
+msgstr ""
+
+msgid "Not enough data"
+msgstr ""
+
+msgid "Not found."
+msgstr ""
+
+msgid "Not helpful"
+msgstr ""
+
+msgid "Not now"
+msgstr ""
+
+msgid "Not ready yet. Try again later."
+msgstr ""
+
+msgid "Not started"
+msgstr ""
+
+msgid "Not-confidential epic cannot be assigned to a confidential parent epic"
+msgstr ""
+
+msgid "Note"
+msgstr ""
+
+msgid "Note parameters are invalid: %{errors}"
+msgstr ""
+
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
+msgid "Note that 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 ""
+
+msgid "Note: As an administrator you may like to configure %{github_integration_link}, which will allow login via GitHub and allow connecting repositories without generating a Personal Access Token."
+msgstr ""
+
+msgid "Note: As an administrator you may like to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
+msgstr ""
+
+msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow connecting repositories without generating a Personal Access Token."
+msgstr ""
+
+msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
+msgstr ""
+
+msgid "NoteForm|Note"
+msgstr ""
+
+msgid "Notes|Are you sure you want to cancel creating this comment?"
+msgstr ""
+
+msgid "Notes|Collapse replies"
+msgstr ""
+
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
+msgid "Notes|Show all activity"
+msgstr ""
+
+msgid "Notes|Show comments only"
+msgstr ""
+
+msgid "Notes|Show history only"
+msgstr ""
+
+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 ""
+
+msgid "Nothing found…"
+msgstr ""
+
+msgid "Nothing to preview."
+msgstr ""
+
+msgid "Nothing to synchronize"
+msgstr ""
+
+msgid "Notification events"
+msgstr ""
+
+msgid "Notification setting"
+msgstr ""
+
+msgid "Notification setting - %{notification_title}"
+msgstr ""
+
+msgid "Notification settings saved"
+msgstr ""
+
+msgid "NotificationEvent|Close issue"
+msgstr ""
+
+msgid "NotificationEvent|Close merge request"
+msgstr ""
+
+msgid "NotificationEvent|Failed pipeline"
+msgstr ""
+
+msgid "NotificationEvent|Fixed pipeline"
+msgstr ""
+
+msgid "NotificationEvent|Merge merge request"
+msgstr ""
+
+msgid "NotificationEvent|New epic"
+msgstr ""
+
+msgid "NotificationEvent|New issue"
+msgstr ""
+
+msgid "NotificationEvent|New merge request"
+msgstr ""
+
+msgid "NotificationEvent|New note"
+msgstr ""
+
+msgid "NotificationEvent|New release"
+msgstr ""
+
+msgid "NotificationEvent|Reassign issue"
+msgstr ""
+
+msgid "NotificationEvent|Reassign merge request"
+msgstr ""
+
+msgid "NotificationEvent|Reopen issue"
+msgstr ""
+
+msgid "NotificationEvent|Successful pipeline"
+msgstr ""
+
+msgid "NotificationLevel|Custom"
+msgstr ""
+
+msgid "NotificationLevel|Disabled"
+msgstr ""
+
+msgid "NotificationLevel|Global"
+msgstr ""
+
+msgid "NotificationLevel|On mention"
+msgstr ""
+
+msgid "NotificationLevel|Participate"
+msgstr ""
+
+msgid "NotificationLevel|Watch"
+msgstr ""
+
+msgid "NotificationSetting|Custom"
+msgstr ""
+
+msgid "Notifications"
+msgstr ""
+
+msgid "Notifications have been disabled by the project or group owner"
+msgstr ""
+
+msgid "Notifications off"
+msgstr ""
+
+msgid "Notifications on"
+msgstr ""
+
+msgid "Nov"
+msgstr ""
+
+msgid "November"
+msgstr ""
+
+msgid "Novice"
+msgstr ""
+
+msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
+msgstr ""
+
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
+msgid "Number of %{itemTitle}"
+msgstr ""
+
+msgid "Number of Elasticsearch replicas"
+msgstr ""
+
+msgid "Number of Elasticsearch shards"
+msgstr ""
+
+msgid "Number of LOCs per commit"
+msgstr ""
+
+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 ""
+
+msgid "Number of changes (branches or tags) in a single push to determine whether webhooks and services will be fired or not. Webhooks and services won't be submitted if it surpasses that value."
+msgstr ""
+
+msgid "Number of commits"
+msgstr ""
+
+msgid "Number of commits per MR"
+msgstr ""
+
+msgid "Number of employees"
+msgstr ""
+
+msgid "Number of files touched"
+msgstr ""
+
+msgid "OK"
+msgstr ""
+
+msgid "Object Storage replication"
+msgstr ""
+
+msgid "Object does not exist on the server or you don't have permissions to access it"
+msgstr ""
+
+msgid "Oct"
+msgstr ""
+
+msgid "October"
+msgstr ""
+
+msgid "OfSearchInADropdown|Filter"
+msgstr ""
+
+msgid "Oh no!"
+msgstr ""
+
+msgid "Ok let's go"
+msgstr ""
+
+msgid "Oldest first"
+msgstr ""
+
+msgid "OmniAuth"
+msgstr ""
+
+msgid "Omnibus Protected Paths throttle is active, and takes priority over these settings. From 12.4, Omnibus throttle is deprecated and will be removed in a future release. Please read the %{relative_url_link_start}Migrating Protected Paths documentation%{relative_url_link_end}."
+msgstr ""
+
+msgid "On track"
+msgstr ""
+
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
+msgid "Onboarding"
+msgstr ""
+
+msgid "Once imported, repositories can be mirrored over SSH. Read more %{link_start}here%{link_end}."
+msgstr ""
+
+msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
+msgstr ""
+
+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 ""
+
+msgid "Once you confirm and press \"Reduce project visibility\":"
+msgstr ""
+
+msgid "One more item"
+msgid_plural "%d more items"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "One or more groups that you don't have access to."
+msgstr ""
+
+msgid "One or more of you personal access tokens were revoked"
+msgstr ""
+
+msgid "One or more of your Bitbucket projects cannot be imported into GitLab directly because they use Subversion or Mercurial for version control, rather than Git."
+msgstr ""
+
+msgid "One or more of your Google Code projects cannot be imported into GitLab directly because they use Subversion or Mercurial for version control, rather than Git."
+msgstr ""
+
+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 ""
+
+msgid "One or more of your personal access tokens will expire in %{days_to_expire} days or less."
+msgstr ""
+
+msgid "Only 'Reporter' roles and above on tiers Premium / Silver and above can see Value Stream Analytics."
+msgstr ""
+
+msgid "Only 1 appearances row can exist"
+msgstr ""
+
+msgid "Only Issue ID or Merge Request ID is required"
+msgstr ""
+
+msgid "Only Project Members"
+msgstr ""
+
+msgid "Only active this projects shows up in the search and on the dashboard."
+msgstr ""
+
+msgid "Only admins"
+msgstr ""
+
+msgid "Only admins can delete project"
+msgstr ""
+
+msgid "Only mirror protected branches"
+msgstr ""
+
+msgid "Only policy:"
+msgstr ""
+
+msgid "Only proceed if you trust %{idp_url} to control your GitLab account sign in."
+msgstr ""
+
+msgid "Only project members can comment."
+msgstr ""
+
+msgid "Only project members will be imported. Group members will be skipped."
+msgstr ""
+
+msgid "Only verified users with an email address in any of these domains can be added to the group."
+msgstr ""
+
+msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
+msgstr ""
+
+msgid "Oops, are you sure?"
+msgstr ""
+
+msgid "Open"
+msgstr ""
+
+msgid "Open Selection"
+msgstr ""
+
+msgid "Open comment type dropdown"
+msgstr ""
+
+msgid "Open errors"
+msgstr ""
+
+msgid "Open in Xcode"
+msgstr ""
+
+msgid "Open issues"
+msgstr ""
+
+msgid "Open projects"
+msgstr ""
+
+msgid "Open raw"
+msgstr ""
+
+msgid "Open sidebar"
+msgstr ""
+
+msgid "Open: %{openIssuesCount}"
+msgstr ""
+
+msgid "Open: %{open} • Closed: %{closed}"
+msgstr ""
+
+msgid "Opened"
+msgstr ""
+
+msgid "Opened MRs"
+msgstr ""
+
+msgid "Opened issues"
+msgstr ""
+
+msgid "OpenedNDaysAgo|Opened"
+msgstr ""
+
+msgid "Opens in a new window"
+msgstr ""
+
+msgid "Operation failed. Check pod logs for %{pod_name} for more details."
+msgstr ""
+
+msgid "Operation not allowed"
+msgstr ""
+
+msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
+msgstr ""
+
+msgid "Operations"
+msgstr ""
+
+msgid "Operations Dashboard"
+msgstr ""
+
+msgid "Operations Settings"
+msgstr ""
+
+msgid "OperationsDashboard|Add a project to the dashboard"
+msgstr ""
+
+msgid "OperationsDashboard|Add projects"
+msgstr ""
+
+msgid "OperationsDashboard|More information"
+msgstr ""
+
+msgid "OperationsDashboard|Operations Dashboard"
+msgstr ""
+
+msgid "OperationsDashboard|The operations dashboard provides a summary of each project's operational health, including pipeline and alert statuses."
+msgstr ""
+
+msgid "Optional"
+msgstr ""
+
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
+msgstr ""
+
+msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
+msgstr ""
+
+msgid "Optionally, you can %{link_to_customize} how Google Code email addresses and usernames are imported into GitLab."
+msgstr ""
+
+msgid "Options"
+msgstr ""
+
+msgid "Or you can choose one of the suggested colors below"
+msgstr ""
+
+msgid "Origin"
+msgstr ""
+
+msgid "Other Labels"
+msgstr ""
+
+msgid "Other information"
+msgstr ""
+
+msgid "Other merge requests block this MR"
+msgstr ""
+
+msgid "Other visibility settings have been disabled by the administrator."
+msgstr ""
+
+msgid "Out-of-compliance with this project's policies and should be removed"
+msgstr ""
+
+msgid "Outbound requests"
+msgstr ""
+
+msgid "OutdatedBrowser|From May 2020 GitLab no longer supports Internet Explorer 11."
+msgstr ""
+
+msgid "OutdatedBrowser|GitLab may not work properly, because you are using an outdated web browser."
+msgstr ""
+
+msgid "OutdatedBrowser|Please install a %{browser_link_start}supported web browser%{browser_link_end} for a better experience."
+msgstr ""
+
+msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
+msgstr ""
+
+msgid "Outdent"
+msgstr ""
+
+msgid "Overridden"
+msgstr ""
+
+msgid "Overview"
+msgstr ""
+
+msgid "Overwrite diverged branches"
+msgstr ""
+
+msgid "Owned by anyone"
+msgstr ""
+
+msgid "Owned by me"
+msgstr ""
+
+msgid "Owner"
+msgstr ""
+
+msgid "Package Files"
+msgstr ""
+
+msgid "Package Registry"
+msgstr ""
+
+msgid "Package already exists"
+msgstr ""
+
+msgid "Package deleted successfully"
+msgstr ""
+
+msgid "Package information"
+msgstr ""
+
+msgid "Package recipe already exists"
+msgstr ""
+
+msgid "Package type must be Conan"
+msgstr ""
+
+msgid "Package type must be Maven"
+msgstr ""
+
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
+msgid "Package was removed"
+msgstr ""
+
+msgid "PackageRegistry|Add Conan Remote"
+msgstr ""
+
+msgid "PackageRegistry|Add NuGet Source"
+msgstr ""
+
+msgid "PackageRegistry|Conan"
+msgstr ""
+
+msgid "PackageRegistry|Conan Command"
+msgstr ""
+
+msgid "PackageRegistry|Copy .pypirc content"
+msgstr ""
+
+msgid "PackageRegistry|Copy Conan Command"
+msgstr ""
+
+msgid "PackageRegistry|Copy Conan Setup Command"
+msgstr ""
+
+msgid "PackageRegistry|Copy Maven XML"
+msgstr ""
+
+msgid "PackageRegistry|Copy Maven command"
+msgstr ""
+
+msgid "PackageRegistry|Copy Maven registry XML"
+msgstr ""
+
+msgid "PackageRegistry|Copy NuGet Command"
+msgstr ""
+
+msgid "PackageRegistry|Copy NuGet Setup Command"
+msgstr ""
+
+msgid "PackageRegistry|Copy Pip command"
+msgstr ""
+
+msgid "PackageRegistry|Copy and paste this inside your %{codeStart}pom.xml%{codeEnd} %{codeStart}dependencies%{codeEnd} block."
+msgstr ""
+
+msgid "PackageRegistry|Copy npm command"
+msgstr ""
+
+msgid "PackageRegistry|Copy npm setup command"
+msgstr ""
+
+msgid "PackageRegistry|Copy yarn command"
+msgstr ""
+
+msgid "PackageRegistry|Copy yarn setup command"
+msgstr ""
+
+msgid "PackageRegistry|Delete Package Version"
+msgstr ""
+
+msgid "PackageRegistry|Delete package"
+msgstr ""
+
+msgid "PackageRegistry|Filter by name"
+msgstr ""
+
+msgid "PackageRegistry|For more information on the Conan registry, %{linkStart}see the documentation%{linkEnd}."
+msgstr ""
+
+msgid "PackageRegistry|For more information on the Maven registry, %{linkStart}see the documentation%{linkEnd}."
+msgstr ""
+
+msgid "PackageRegistry|For more information on the NuGet registry, %{linkStart}see the documentation%{linkEnd}."
+msgstr ""
+
+msgid "PackageRegistry|For more information on the PyPi registry, %{linkStart}see the documentation%{linkEnd}."
+msgstr ""
+
+msgid "PackageRegistry|If you haven't already done so, you will need to add the below to your %{codeStart}.pypirc%{codeEnd} file."
+msgstr ""
+
+msgid "PackageRegistry|If you haven't already done so, you will need to add the below to your %{codeStart}pom.xml%{codeEnd} file."
+msgstr ""
+
+msgid "PackageRegistry|Installation"
+msgstr ""
+
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
+msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
+msgstr ""
+
+msgid "PackageRegistry|Manually Published"
+msgstr ""
+
+msgid "PackageRegistry|Maven"
+msgstr ""
+
+msgid "PackageRegistry|Maven Command"
+msgstr ""
+
+msgid "PackageRegistry|Maven XML"
+msgstr ""
+
+msgid "PackageRegistry|NPM"
+msgstr ""
+
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
+msgid "PackageRegistry|NuGet"
+msgstr ""
+
+msgid "PackageRegistry|NuGet Command"
+msgstr ""
+
+msgid "PackageRegistry|Pip Command"
+msgstr ""
+
+msgid "PackageRegistry|Pipeline %{linkStart}%{linkEnd} triggered %{timestamp} by %{author}"
+msgstr ""
+
+msgid "PackageRegistry|Published to the repository at %{timestamp}"
+msgstr ""
+
+msgid "PackageRegistry|PyPi"
+msgstr ""
+
+msgid "PackageRegistry|Registry Setup"
+msgstr ""
+
+msgid "PackageRegistry|Remove package"
+msgstr ""
+
+msgid "PackageRegistry|Sorry, your filter produced no results"
+msgstr ""
+
+msgid "PackageRegistry|There are no %{packageType} packages yet"
+msgstr ""
+
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
+msgid "PackageRegistry|There are no packages yet"
+msgstr ""
+
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
+msgid "PackageRegistry|There was a problem fetching the details for this package."
+msgstr ""
+
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
+msgid "PackageRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
+msgid "PackageRegistry|Unable to load package"
+msgstr ""
+
+msgid "PackageRegistry|Upcoming package managers"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
+msgstr ""
+
+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 ""
+
+msgid "PackageRegistry|published by %{author}"
+msgstr ""
+
+msgid "PackageRegistry|yarn"
+msgstr ""
+
+msgid "PackageType|Conan"
+msgstr ""
+
+msgid "PackageType|Maven"
+msgstr ""
+
+msgid "PackageType|NPM"
+msgstr ""
+
+msgid "PackageType|NuGet"
+msgstr ""
+
+msgid "PackageType|PyPi"
+msgstr ""
+
+msgid "Packages"
+msgstr ""
+
+msgid "Packages & Registries"
+msgstr ""
+
+msgid "Page not found"
+msgstr ""
+
+msgid "Page was successfully deleted"
+msgstr ""
+
+msgid "Pages"
+msgstr ""
+
+msgid "Pages Domain"
+msgstr ""
+
+msgid "Pages getting started guide"
+msgstr ""
+
+msgid "Pagination|Go to first page"
+msgstr ""
+
+msgid "Pagination|Go to last page"
+msgstr ""
+
+msgid "Pagination|Go to next page"
+msgstr ""
+
+msgid "Pagination|Go to previous page"
+msgstr ""
+
+msgid "Pagination|Last »"
+msgstr ""
+
+msgid "Pagination|Next"
+msgstr ""
+
+msgid "Pagination|Prev"
+msgstr ""
+
+msgid "Pagination|« First"
+msgstr ""
+
+msgid "Parameter"
+msgstr ""
+
+msgid "Parameter \"job_id\" cannot exceed length of %{job_id_max_size}"
+msgstr ""
+
+msgid "Parent"
+msgstr ""
+
+msgid "Parent epic doesn't exist."
+msgstr ""
+
+msgid "Parent epic is not present."
+msgstr ""
+
+msgid "Part of merge request changes"
+msgstr ""
+
+msgid "Partial token for reference only"
+msgstr ""
+
+msgid "Participants"
+msgstr ""
+
+msgid "Passed"
+msgstr ""
+
+msgid "Password"
+msgstr ""
+
+msgid "Password (optional)"
+msgstr ""
+
+msgid "Password Policy Guidelines"
+msgstr ""
+
+msgid "Password authentication is unavailable."
+msgstr ""
+
+msgid "Password confirmation"
+msgstr ""
+
+msgid "Password successfully changed"
+msgstr ""
+
+msgid "Password was successfully updated. Please login with it"
+msgstr ""
+
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
+msgid "Past due"
+msgstr ""
+
+msgid "Paste a machine public key here. Read more about how to generate it"
+msgstr ""
+
+msgid "Paste a machine public key here. Read more about how to generate it %{link_start}here%{link_end}"
+msgstr ""
+
+msgid "Paste epic link"
+msgstr ""
+
+msgid "Paste issue link"
+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'. Don't use your private SSH key."
+msgstr ""
+
+msgid "Patch to apply"
+msgstr ""
+
+msgid "Path"
+msgstr ""
+
+msgid "Path:"
+msgstr ""
+
+msgid "Paths can contain wildcards, like */welcome"
+msgstr ""
+
+msgid "Pause"
+msgstr ""
+
+msgid "Pause replication"
+msgstr ""
+
+msgid "Paused Runners don't accept new jobs"
+msgstr ""
+
+msgid "Pending"
+msgstr ""
+
+msgid "People without permission will never get a notification and won't be able to comment."
+msgstr ""
+
+msgid "People without permission will never get a notification."
+msgstr ""
+
+msgid "Percent rollout (logged in users)"
+msgstr ""
+
+msgid "Percentage"
+msgstr ""
+
+msgid "Perform advanced options such as changing path, transferring, exporting, or removing the group."
+msgstr ""
+
+msgid "Perform common operations on GitLab project"
+msgstr ""
+
+msgid "Performance optimization"
+msgstr ""
+
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
+msgid "PerformanceBar|Download"
+msgstr ""
+
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
+msgid "PerformanceBar|Frontend resources"
+msgstr ""
+
+msgid "PerformanceBar|Gitaly calls"
+msgstr ""
+
+msgid "PerformanceBar|Redis calls"
+msgstr ""
+
+msgid "PerformanceBar|Rugged calls"
+msgstr ""
+
+msgid "PerformanceBar|SQL queries"
+msgstr ""
+
+msgid "PerformanceBar|trace"
+msgstr ""
+
+msgid "Permissions"
+msgstr ""
+
+msgid "Permissions, LFS, 2FA"
+msgstr ""
+
+msgid "Personal Access Token"
+msgstr ""
+
+msgid "Personal project creation is not allowed. Please contact your administrator with questions"
+msgstr ""
+
+msgid "Phabricator Server Import"
+msgstr ""
+
+msgid "Phabricator Server URL"
+msgstr ""
+
+msgid "Phabricator Tasks"
+msgstr ""
+
+msgid "Pick a name"
+msgstr ""
+
+msgid "Pin code"
+msgstr ""
+
+msgid "Pipeline"
+msgstr ""
+
+msgid "Pipeline %{label}"
+msgstr ""
+
+msgid "Pipeline %{label} for \"%{dataTitle}\""
+msgstr ""
+
+msgid "Pipeline Schedule"
+msgstr ""
+
+msgid "Pipeline Schedules"
+msgstr ""
+
+msgid "Pipeline minutes quota"
+msgstr ""
+
+msgid "Pipeline subscriptions"
+msgstr ""
+
+msgid "Pipeline triggers"
+msgstr ""
+
+msgid "Pipeline: %{status}"
+msgstr ""
+
+msgid "PipelineCharts|CI / CD Analytics"
+msgstr ""
+
+msgid "PipelineCharts|Failed:"
+msgstr ""
+
+msgid "PipelineCharts|Overall statistics"
+msgstr ""
+
+msgid "PipelineCharts|Success ratio:"
+msgstr ""
+
+msgid "PipelineCharts|Successful:"
+msgstr ""
+
+msgid "PipelineCharts|Total:"
+msgstr ""
+
+msgid "PipelineSchedules|Activated"
+msgstr ""
+
+msgid "PipelineSchedules|Active"
+msgstr ""
+
+msgid "PipelineSchedules|All"
+msgstr ""
+
+msgid "PipelineSchedules|Inactive"
+msgstr ""
+
+msgid "PipelineSchedules|Next Run"
+msgstr ""
+
+msgid "PipelineSchedules|None"
+msgstr ""
+
+msgid "PipelineSchedules|Provide a short description for this pipeline"
+msgstr ""
+
+msgid "PipelineSchedules|Take ownership"
+msgstr ""
+
+msgid "PipelineSchedules|Target"
+msgstr ""
+
+msgid "PipelineSchedules|Variables"
+msgstr ""
+
+msgid "PipelineSheduleIntervalPattern|Custom"
+msgstr ""
+
+msgid "PipelineStatusTooltip|Pipeline: %{ciStatus}"
+msgstr ""
+
+msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
+msgstr ""
+
+msgid "Pipelines"
+msgstr ""
+
+msgid "Pipelines charts"
+msgstr ""
+
+msgid "Pipelines emails"
+msgstr ""
+
+msgid "Pipelines for last month (%{oneMonthAgo} - %{today})"
+msgstr ""
+
+msgid "Pipelines for last week (%{oneWeekAgo} - %{today})"
+msgstr ""
+
+msgid "Pipelines for last year"
+msgstr ""
+
+msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
+msgstr ""
+
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
+msgid "Pipelines settings for '%{project_name}' were successfully updated."
+msgstr ""
+
+msgid "Pipelines|API"
+msgstr ""
+
+msgid "Pipelines|Build with confidence"
+msgstr ""
+
+msgid "Pipelines|CI Lint"
+msgstr ""
+
+msgid "Pipelines|Child pipeline"
+msgstr ""
+
+msgid "Pipelines|Clear Runner Caches"
+msgstr ""
+
+msgid "Pipelines|Continuous Integration can help catch bugs by running your tests automatically, while Continuous Deployment can help you deliver code to your product environment."
+msgstr ""
+
+msgid "Pipelines|Get started with Pipelines"
+msgstr ""
+
+msgid "Pipelines|Group %{namespace_name} has %{percentage}%% or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "Pipelines|Group %{namespace_name} has exceeded its pipeline minutes quota. Unless you buy additional pipeline minutes, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "Pipelines|Loading Pipelines"
+msgstr ""
+
+msgid "Pipelines|Project cache successfully reset."
+msgstr ""
+
+msgid "Pipelines|Run Pipeline"
+msgstr ""
+
+msgid "Pipelines|Something went wrong while cleaning runners cache."
+msgstr ""
+
+msgid "Pipelines|There are currently no %{scope} pipelines."
+msgstr ""
+
+msgid "Pipelines|There are currently no pipelines."
+msgstr ""
+
+msgid "Pipelines|There was an error fetching the pipelines. Try again in a few moments or contact your support team."
+msgstr ""
+
+msgid "Pipelines|This is a child pipeline within the parent pipeline"
+msgstr ""
+
+msgid "Pipelines|This project is not currently set up to run pipelines."
+msgstr ""
+
+msgid "Pipelines|parent"
+msgstr ""
+
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
+msgid "Pipeline|Commit"
+msgstr ""
+
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
+msgstr ""
+
+msgid "Pipeline|Coverage"
+msgstr ""
+
+msgid "Pipeline|Created"
+msgstr ""
+
+msgid "Pipeline|Date"
+msgstr ""
+
+msgid "Pipeline|Detached merge request pipeline"
+msgstr ""
+
+msgid "Pipeline|Duration"
+msgstr ""
+
+msgid "Pipeline|Existing branch name or tag"
+msgstr ""
+
+msgid "Pipeline|Failed"
+msgstr ""
+
+msgid "Pipeline|Key"
+msgstr ""
+
+msgid "Pipeline|Manual"
+msgstr ""
+
+msgid "Pipeline|Merge train pipeline"
+msgstr ""
+
+msgid "Pipeline|Merged result pipeline"
+msgstr ""
+
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
+msgid "Pipeline|Pipeline"
+msgstr ""
+
+msgid "Pipeline|Pipelines"
+msgstr ""
+
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
+msgid "Pipeline|Run Pipeline"
+msgstr ""
+
+msgid "Pipeline|Run for"
+msgstr ""
+
+msgid "Pipeline|Running"
+msgstr ""
+
+msgid "Pipeline|Search branches"
+msgstr ""
+
+msgid "Pipeline|Skipped"
+msgstr ""
+
+msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
+msgstr ""
+
+msgid "Pipeline|Stages"
+msgstr ""
+
+msgid "Pipeline|Status"
+msgstr ""
+
+msgid "Pipeline|Stop pipeline"
+msgstr ""
+
+msgid "Pipeline|Stop pipeline #%{pipelineId}?"
+msgstr ""
+
+msgid "Pipeline|Trigger author"
+msgstr ""
+
+msgid "Pipeline|Triggerer"
+msgstr ""
+
+msgid "Pipeline|Value"
+msgstr ""
+
+msgid "Pipeline|Variables"
+msgstr ""
+
+msgid "Pipeline|You’re about to stop pipeline %{pipelineId}."
+msgstr ""
+
+msgid "Pipeline|for"
+msgstr ""
+
+msgid "Pipeline|on"
+msgstr ""
+
+msgid "Pipeline|with stage"
+msgstr ""
+
+msgid "Pipeline|with stages"
+msgstr ""
+
+msgid "PivotalTrackerService|Comma-separated list of branches which will be automatically inspected. Leave blank to include all branches."
+msgstr ""
+
+msgid "PivotalTrackerService|Pivotal Tracker API token."
+msgstr ""
+
+msgid "PivotalTrackerService|Project Management Software (Source Commits Endpoint)"
+msgstr ""
+
+msgid "Plain diff"
+msgstr ""
+
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
+msgid "PlantUML"
+msgstr ""
+
+msgid "Play"
+msgstr ""
+
+msgid "Play all manual"
+msgstr ""
+
+msgid "Please %{link_to_register} or %{link_to_sign_in} to comment"
+msgstr ""
+
+msgid "Please %{startTagRegister}register%{endRegisterTag} or %{startTagSignIn}sign in%{endSignInTag} to reply"
+msgstr ""
+
+msgid "Please accept the Terms of Service before continuing."
+msgstr ""
+
+msgid "Please add a comment in the text area above"
+msgstr ""
+
+msgid "Please add a list to your board first"
+msgstr ""
+
+msgid "Please check the configuration file for this chart"
+msgstr ""
+
+msgid "Please check the configuration file to ensure that a collection of charts has been declared."
+msgstr ""
+
+msgid "Please check the configuration file to ensure that it is available and the YAML is valid"
+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 ""
+
+msgid "Please choose a group URL with no special characters."
+msgstr ""
+
+msgid "Please complete your profile with email address"
+msgstr ""
+
+msgid "Please convert them to %{link_to_git}, and go through the %{link_to_import_flow} again."
+msgstr ""
+
+msgid "Please convert them to Git on Google Code, and go through the %{link_to_import_flow} again."
+msgstr ""
+
+msgid "Please create a password for your new account."
+msgstr ""
+
+msgid "Please create a username with only alphanumeric characters."
+msgstr ""
+
+msgid "Please create an index before enabling indexing"
+msgstr ""
+
+msgid "Please enable and migrate to hashed storage to avoid security issues and ensure data integrity. %{migrate_link}"
+msgstr ""
+
+msgid "Please ensure your account's %{account_link_start}recovery settings%{account_link_end} are up to date."
+msgstr ""
+
+msgid "Please enter a non-negative number"
+msgstr ""
+
+msgid "Please enter a number greater than %{number} (from the project settings)"
+msgstr ""
+
+msgid "Please enter a valid number"
+msgstr ""
+
+msgid "Please enter or upload a license."
+msgstr ""
+
+msgid "Please fill in a descriptive name for your group."
+msgstr ""
+
+msgid "Please follow the %{link_start}Let's Encrypt troubleshooting instructions%{link_end} to re-obtain your Let's Encrypt certificate."
+msgstr ""
+
+msgid "Please follow the Let's Encrypt troubleshooting instructions to re-obtain your Let's Encrypt certificate: %{docs_url}."
+msgstr ""
+
+msgid "Please migrate all existing projects to hashed storage to avoid security issues and ensure data integrity. %{migrate_link}"
+msgstr ""
+
+msgid "Please note that this application is not provided by GitLab and you should verify its authenticity before allowing access."
+msgstr ""
+
+msgid "Please provide a name"
+msgstr ""
+
+msgid "Please provide a valid URL"
+msgstr ""
+
+msgid "Please provide a valid email address."
+msgstr ""
+
+msgid "Please refer to <a href=\"%{docs_url}\">%{docs_url}</a>"
+msgstr ""
+
+msgid "Please retype the email address."
+msgstr ""
+
+msgid "Please select"
+msgstr ""
+
+msgid "Please select a Jira project"
+msgstr ""
+
+msgid "Please select a country"
+msgstr ""
+
+msgid "Please select a file"
+msgstr ""
+
+msgid "Please select a group."
+msgstr ""
+
+msgid "Please select a valid target branch"
+msgstr ""
+
+msgid "Please select and add a member"
+msgstr ""
+
+msgid "Please select at least one filter to see results"
+msgstr ""
+
+msgid "Please set a new password before proceeding."
+msgstr ""
+
+msgid "Please solve the reCAPTCHA"
+msgstr ""
+
+msgid "Please try again"
+msgstr ""
+
+msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
+msgstr ""
+
+msgid "Please upgrade PostgreSQL to version 9.6 or greater. The status of the replication cannot be determined reliably with the current version."
+msgstr ""
+
+msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
+msgstr ""
+
+msgid "Please wait a moment, this page will automatically refresh when ready."
+msgstr ""
+
+msgid "Please wait while we connect to your repository. Refresh at will."
+msgstr ""
+
+msgid "Please wait while we import the repository for you. Refresh at will."
+msgstr ""
+
+msgid "Plugins directory is deprecated and will be removed in 14.0. Please move this file into /file_hooks directory."
+msgstr ""
+
+msgid "Pod does not exist"
+msgstr ""
+
+msgid "Pod not found"
+msgstr ""
+
+msgid "Pods in use"
+msgstr ""
+
+msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
+msgstr ""
+
+msgid "Pre-defined push rules."
+msgstr ""
+
+msgid "Preferences"
+msgstr ""
+
+msgid "Preferences saved."
+msgstr ""
+
+msgid "Preferences|Behavior"
+msgstr ""
+
+msgid "Preferences|Choose between fixed (max. 1280px) and fluid (%{percentage}) application layout."
+msgstr ""
+
+msgid "Preferences|Choose what content you want to see on a project’s overview page."
+msgstr ""
+
+msgid "Preferences|Customize integrations with third party services."
+msgstr ""
+
+msgid "Preferences|Customize the appearance of the application header and navigation sidebar."
+msgstr ""
+
+msgid "Preferences|Default dashboard"
+msgstr ""
+
+msgid "Preferences|Display time in 24-hour format"
+msgstr ""
+
+msgid "Preferences|Enable integrated code intelligence on code views"
+msgstr ""
+
+msgid "Preferences|For example: 30 mins ago."
+msgstr ""
+
+msgid "Preferences|Integrations"
+msgstr ""
+
+msgid "Preferences|Layout width"
+msgstr ""
+
+msgid "Preferences|Must be a number between %{min} and %{max}"
+msgstr ""
+
+msgid "Preferences|Navigation theme"
+msgstr ""
+
+msgid "Preferences|Project overview content"
+msgstr ""
+
+msgid "Preferences|Render whitespace characters in the Web IDE"
+msgstr ""
+
+msgid "Preferences|Show whitespace changes in diffs"
+msgstr ""
+
+msgid "Preferences|Sourcegraph"
+msgstr ""
+
+msgid "Preferences|Syntax highlighting theme"
+msgstr ""
+
+msgid "Preferences|Tab width"
+msgstr ""
+
+msgid "Preferences|These settings will update how dates and times are displayed for you."
+msgstr ""
+
+msgid "Preferences|This feature is experimental and translations are not complete yet"
+msgstr ""
+
+msgid "Preferences|This setting allows you to customize the appearance of the syntax."
+msgstr ""
+
+msgid "Preferences|This setting allows you to customize the behavior of the system layout and default views."
+msgstr ""
+
+msgid "Preferences|Time display"
+msgstr ""
+
+msgid "Preferences|Time format"
+msgstr ""
+
+msgid "Preferences|Time preferences"
+msgstr ""
+
+msgid "Preferences|Use relative times"
+msgstr ""
+
+msgid "Press %{key}-C to copy"
+msgstr ""
+
+msgid "Prev"
+msgstr ""
+
+msgid "Prevent adding new members to project membership within this group"
+msgstr ""
+
+msgid "Prevent approval of merge requests by merge request author"
+msgstr ""
+
+msgid "Prevent approval of merge requests by merge request committers"
+msgstr ""
+
+msgid "Prevent environment from auto-stopping"
+msgstr ""
+
+msgid "Prevent users from changing their profile name"
+msgstr ""
+
+msgid "Prevent users from modifying merge request approvers list"
+msgstr ""
+
+msgid "Prevent users from performing write operations on GitLab while performing maintenance."
+msgstr ""
+
+msgid "Preview"
+msgstr ""
+
+msgid "Preview Markdown"
+msgstr ""
+
+msgid "Preview changes"
+msgstr ""
+
+msgid "Preview payload"
+msgstr ""
+
+msgid "Previous Artifacts"
+msgstr ""
+
+msgid "Previous commit"
+msgstr ""
+
+msgid "Previous file in diff"
+msgstr ""
+
+msgid "Previous unresolved discussion"
+msgstr ""
+
+msgid "Primary"
+msgstr ""
+
+msgid "Prioritize"
+msgstr ""
+
+msgid "Prioritize label"
+msgstr ""
+
+msgid "Prioritized Labels"
+msgstr ""
+
+msgid "Prioritized label"
+msgstr ""
+
+msgid "Private"
+msgstr ""
+
+msgid "Private - 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 "Private - The group and its projects can only be viewed by members."
+msgstr ""
+
+msgid "Private group(s)"
+msgstr ""
+
+msgid "Private profile"
+msgstr ""
+
+msgid "Private projects Minutes cost factor"
+msgstr ""
+
+msgid "Private projects can be created in your personal namespace with:"
+msgstr ""
+
+msgid "Proceed"
+msgstr ""
+
+msgid "Productivity"
+msgstr ""
+
+msgid "Productivity Analytics"
+msgstr ""
+
+msgid "Productivity analytics can help identify the problems that are delaying your team"
+msgstr ""
+
+msgid "ProductivityAanalytics|Merge requests"
+msgstr ""
+
+msgid "ProductivityAanalytics|is earlier than the allowed minimum date"
+msgstr ""
+
+msgid "ProductivityAnalytics|Ascending"
+msgstr ""
+
+msgid "ProductivityAnalytics|Days"
+msgstr ""
+
+msgid "ProductivityAnalytics|Days to merge"
+msgstr ""
+
+msgid "ProductivityAnalytics|Descending"
+msgstr ""
+
+msgid "ProductivityAnalytics|Hours"
+msgstr ""
+
+msgid "ProductivityAnalytics|List"
+msgstr ""
+
+msgid "ProductivityAnalytics|Merge Requests"
+msgstr ""
+
+msgid "ProductivityAnalytics|Merge date"
+msgstr ""
+
+msgid "ProductivityAnalytics|Merge requests"
+msgstr ""
+
+msgid "ProductivityAnalytics|Time to merge"
+msgstr ""
+
+msgid "ProductivityAnalytics|Trendline"
+msgstr ""
+
+msgid "ProductivityAnalytics|is earlier than the given merged at after date"
+msgstr ""
+
+msgid "Profile"
+msgstr ""
+
+msgid "Profile Settings"
+msgstr ""
+
+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 ""
+
+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 ""
+
+msgid "Profiles|@username"
+msgstr ""
+
+msgid "Profiles|Account scheduled for removal."
+msgstr ""
+
+msgid "Profiles|Activate signin with one of the following services"
+msgstr ""
+
+msgid "Profiles|Active"
+msgstr ""
+
+msgid "Profiles|Add key"
+msgstr ""
+
+msgid "Profiles|Add status emoji"
+msgstr ""
+
+msgid "Profiles|Avatar cropper"
+msgstr ""
+
+msgid "Profiles|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Profiles|Bio"
+msgstr ""
+
+msgid "Profiles|Change username"
+msgstr ""
+
+msgid "Profiles|Changing your username can have unintended side effects."
+msgstr ""
+
+msgid "Profiles|Choose file..."
+msgstr ""
+
+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 ""
+
+msgid "Profiles|Clear status"
+msgstr ""
+
+msgid "Profiles|Click on icon to activate signin with one of the following services"
+msgstr ""
+
+msgid "Profiles|Commit email"
+msgstr ""
+
+msgid "Profiles|Connect"
+msgstr ""
+
+msgid "Profiles|Connected Accounts"
+msgstr ""
+
+msgid "Profiles|Current path: %{path}"
+msgstr ""
+
+msgid "Profiles|Current status"
+msgstr ""
+
+msgid "Profiles|Default notification email"
+msgstr ""
+
+msgid "Profiles|Delete Account"
+msgstr ""
+
+msgid "Profiles|Delete account"
+msgstr ""
+
+msgid "Profiles|Delete your account?"
+msgstr ""
+
+msgid "Profiles|Deleting an account has the following effects:"
+msgstr ""
+
+msgid "Profiles|Disconnect"
+msgstr ""
+
+msgid "Profiles|Do not show on profile"
+msgstr ""
+
+msgid "Profiles|Don't display activity-related personal information on your profiles"
+msgstr ""
+
+msgid "Profiles|Edit Profile"
+msgstr ""
+
+msgid "Profiles|Enter your name, so people you know can recognize you"
+msgstr ""
+
+msgid "Profiles|Expires at"
+msgstr ""
+
+msgid "Profiles|Expires:"
+msgstr ""
+
+msgid "Profiles|Feed token was successfully reset"
+msgstr ""
+
+msgid "Profiles|Full name"
+msgstr ""
+
+msgid "Profiles|Give your individual key a title"
+msgstr ""
+
+msgid "Profiles|Include private contributions on my profile"
+msgstr ""
+
+msgid "Profiles|Incoming email token was successfully reset"
+msgstr ""
+
+msgid "Profiles|Increase your account's security by enabling Two-Factor Authentication (2FA)"
+msgstr ""
+
+msgid "Profiles|Invalid password"
+msgstr ""
+
+msgid "Profiles|Invalid username"
+msgstr ""
+
+msgid "Profiles|Key"
+msgstr ""
+
+msgid "Profiles|Last used:"
+msgstr ""
+
+msgid "Profiles|Learn more"
+msgstr ""
+
+msgid "Profiles|Location"
+msgstr ""
+
+msgid "Profiles|Made a private contribution"
+msgstr ""
+
+msgid "Profiles|Main settings"
+msgstr ""
+
+msgid "Profiles|No file chosen"
+msgstr ""
+
+msgid "Profiles|Notification email"
+msgstr ""
+
+msgid "Profiles|Organization"
+msgstr ""
+
+msgid "Profiles|Path"
+msgstr ""
+
+msgid "Profiles|Position and size your new avatar"
+msgstr ""
+
+msgid "Profiles|Primary email"
+msgstr ""
+
+msgid "Profiles|Private contributions"
+msgstr ""
+
+msgid "Profiles|Profile was successfully updated"
+msgstr ""
+
+msgid "Profiles|Public Avatar"
+msgstr ""
+
+msgid "Profiles|Public email"
+msgstr ""
+
+msgid "Profiles|Remove avatar"
+msgstr ""
+
+msgid "Profiles|Set new profile picture"
+msgstr ""
+
+msgid "Profiles|Social sign-in"
+msgstr ""
+
+msgid "Profiles|Some options are unavailable for LDAP accounts"
+msgstr ""
+
+msgid "Profiles|Static object token was successfully reset"
+msgstr ""
+
+msgid "Profiles|Tell us about yourself in fewer than 250 characters"
+msgstr ""
+
+msgid "Profiles|The ability to update your name has been disabled by your administrator."
+msgstr ""
+
+msgid "Profiles|The maximum file size allowed is 200KB."
+msgstr ""
+
+msgid "Profiles|This doesn't look like a public SSH key, are you sure you want to add it?"
+msgstr ""
+
+msgid "Profiles|This email will be displayed on your public profile"
+msgstr ""
+
+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 ""
+
+msgid "Profiles|This emoji and message will appear on your profile and throughout the interface."
+msgstr ""
+
+msgid "Profiles|This information will appear on your profile"
+msgstr ""
+
+msgid "Profiles|Time settings"
+msgstr ""
+
+msgid "Profiles|Two-Factor Authentication"
+msgstr ""
+
+msgid "Profiles|Type your %{confirmationValue} to confirm:"
+msgstr ""
+
+msgid "Profiles|Typically starts with \"ssh-ed25519 …\" or \"ssh-rsa …\""
+msgstr ""
+
+msgid "Profiles|Update profile settings"
+msgstr ""
+
+msgid "Profiles|Update username"
+msgstr ""
+
+msgid "Profiles|Upload new avatar"
+msgstr ""
+
+msgid "Profiles|Use a private email - %{email}"
+msgstr ""
+
+msgid "Profiles|User ID"
+msgstr ""
+
+msgid "Profiles|Username change failed - %{message}"
+msgstr ""
+
+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|What's your status?"
+msgstr ""
+
+msgid "Profiles|Who you represent or work for"
+msgstr ""
+
+msgid "Profiles|You can change your avatar here"
+msgstr ""
+
+msgid "Profiles|You can change your avatar here or remove the current avatar to revert to %{gravatar_link}"
+msgstr ""
+
+msgid "Profiles|You can set your current timezone here"
+msgstr ""
+
+msgid "Profiles|You can upload your avatar here"
+msgstr ""
+
+msgid "Profiles|You can upload your avatar here or change it at %{gravatar_link}"
+msgstr ""
+
+msgid "Profiles|You don't have access to delete this user."
+msgstr ""
+
+msgid "Profiles|You must transfer ownership or delete these groups before you can delete your account."
+msgstr ""
+
+msgid "Profiles|Your LinkedIn profile name from linkedin.com/in/profilename"
+msgstr ""
+
+msgid "Profiles|Your account is currently an owner in these groups:"
+msgstr ""
+
+msgid "Profiles|Your email address was automatically set based on your %{provider_label} account"
+msgstr ""
+
+msgid "Profiles|Your key has expired"
+msgstr ""
+
+msgid "Profiles|Your location was automatically set based on your %{provider_label} account"
+msgstr ""
+
+msgid "Profiles|Your name was automatically set based on your %{provider_label} account, so people you know can recognize you"
+msgstr ""
+
+msgid "Profiles|Your status"
+msgstr ""
+
+msgid "Profiles|e.g. My MacBook key"
+msgstr ""
+
+msgid "Profiles|username"
+msgstr ""
+
+msgid "Profiles|website.com"
+msgstr ""
+
+msgid "Profiles|your account"
+msgstr ""
+
+msgid "Profile|%{job_title} at %{organization}"
+msgstr ""
+
+msgid "Profiling - Performance bar"
+msgstr ""
+
+msgid "Programming languages used in this repository"
+msgstr ""
+
+msgid "Progress"
+msgstr ""
+
+msgid "Project"
+msgstr ""
+
+msgid "Project \"%{name}\" is no longer available. Select another project to continue."
+msgstr ""
+
+msgid "Project %{project_repo} could not be found"
+msgstr ""
+
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
+msgid "Project '%{project_name}' is being imported."
+msgstr ""
+
+msgid "Project '%{project_name}' is in the process of being deleted."
+msgstr ""
+
+msgid "Project '%{project_name}' is restored."
+msgstr ""
+
+msgid "Project '%{project_name}' queued for deletion."
+msgstr ""
+
+msgid "Project '%{project_name}' was successfully created."
+msgstr ""
+
+msgid "Project '%{project_name}' was successfully updated."
+msgstr ""
+
+msgid "Project '%{project_name}' will be deleted on %{date}"
+msgstr ""
+
+msgid "Project Access Tokens"
+msgstr ""
+
+msgid "Project Audit Events"
+msgstr ""
+
+msgid "Project Badges"
+msgstr ""
+
+msgid "Project Files"
+msgstr ""
+
+msgid "Project ID"
+msgstr ""
+
+msgid "Project URL"
+msgstr ""
+
+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 ""
+
+msgid "Project already deleted"
+msgstr ""
+
+msgid "Project and wiki repositories"
+msgstr ""
+
+msgid "Project avatar"
+msgstr ""
+
+msgid "Project cannot be shared with the group it is in or one of its ancestors."
+msgstr ""
+
+msgid "Project clone URL"
+msgstr ""
+
+msgid "Project configuration, including services"
+msgstr ""
+
+msgid "Project description (optional)"
+msgstr ""
+
+msgid "Project details"
+msgstr ""
+
+msgid "Project does not exist or you don't have permission to perform this action"
+msgstr ""
+
+msgid "Project export could not be deleted."
+msgstr ""
+
+msgid "Project export enabled"
+msgstr ""
+
+msgid "Project export has been deleted."
+msgstr ""
+
+msgid "Project export link has expired. Please generate a new export from your project settings."
+msgstr ""
+
+msgid "Project export started. A download link will be sent by email and made available on this page."
+msgstr ""
+
+msgid "Project has too many %{label_for_message} to search"
+msgstr ""
+
+msgid "Project members"
+msgstr ""
+
+msgid "Project milestone"
+msgstr ""
+
+msgid "Project name"
+msgstr ""
+
+msgid "Project name suffix"
+msgstr ""
+
+msgid "Project name suffix is a user-defined string which will be appended to the project path, and will form the Service Desk email address."
+msgstr ""
+
+msgid "Project order will not be saved as local storage is not available."
+msgstr ""
+
+msgid "Project overview"
+msgstr ""
+
+msgid "Project path"
+msgstr ""
+
+msgid "Project scanning help page"
+msgstr ""
+
+msgid "Project security status"
+msgstr ""
+
+msgid "Project security status help page"
+msgstr ""
+
+msgid "Project slug"
+msgstr ""
+
+msgid "Project uploads"
+msgstr ""
+
+msgid "Project visibility level will be changed to match namespace rules when transferring to a group."
+msgstr ""
+
+msgid "Project: %{name}"
+msgstr ""
+
+msgid "ProjectActivityRSS|Subscribe"
+msgstr ""
+
+msgid "ProjectCreationLevel|Allowed to create projects"
+msgstr ""
+
+msgid "ProjectCreationLevel|Default project creation protection"
+msgstr ""
+
+msgid "ProjectCreationLevel|Developers + Maintainers"
+msgstr ""
+
+msgid "ProjectCreationLevel|Maintainers"
+msgstr ""
+
+msgid "ProjectCreationLevel|No one"
+msgstr ""
+
+msgid "ProjectFileTree|Name"
+msgstr ""
+
+msgid "ProjectLastActivity|Never"
+msgstr ""
+
+msgid "ProjectLifecycle|Stage"
+msgstr ""
+
+msgid "ProjectOverview|Fork"
+msgstr ""
+
+msgid "ProjectOverview|Forks"
+msgstr ""
+
+msgid "ProjectOverview|Go to your fork"
+msgstr ""
+
+msgid "ProjectOverview|Star"
+msgstr ""
+
+msgid "ProjectOverview|Starrer"
+msgstr ""
+
+msgid "ProjectOverview|Starrers"
+msgstr ""
+
+msgid "ProjectOverview|Unstar"
+msgstr ""
+
+msgid "ProjectOverview|You have reached your project limit"
+msgstr ""
+
+msgid "ProjectOverview|You must sign in to star a project"
+msgstr ""
+
+msgid "ProjectPage|Project ID: %{project_id}"
+msgstr ""
+
+msgid "ProjectSelect| or group"
+msgstr ""
+
+msgid "ProjectSelect|Search for project"
+msgstr ""
+
+msgid "ProjectService|%{service_title}: status off"
+msgstr ""
+
+msgid "ProjectService|%{service_title}: status on"
+msgstr ""
+
+msgid "ProjectService|Comment"
+msgstr ""
+
+msgid "ProjectService|Comment will be posted on each event"
+msgstr ""
+
+msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
+msgstr ""
+
+msgid "ProjectService|To set up this service:"
+msgstr ""
+
+msgid "ProjectSettings|Additional merge request capabilities that influence how and when merges will be performed"
+msgstr ""
+
+msgid "ProjectSettings|All discussions must be resolved"
+msgstr ""
+
+msgid "ProjectSettings|Allow users to make copies of your repository to a new project"
+msgstr ""
+
+msgid "ProjectSettings|Allow users to request access"
+msgstr ""
+
+msgid "ProjectSettings|Automatically resolve merge request diff discussions when they become outdated"
+msgstr ""
+
+msgid "ProjectSettings|Badges"
+msgstr ""
+
+msgid "ProjectSettings|Build, test, and deploy your changes"
+msgstr ""
+
+msgid "ProjectSettings|Choose your merge method, merge options, merge checks, and merge suggestions."
+msgstr ""
+
+msgid "ProjectSettings|Choose your merge method, merge options, merge checks, merge suggestions, and set up a default description template for merge requests."
+msgstr ""
+
+msgid "ProjectSettings|Contact an admin to change this setting."
+msgstr ""
+
+msgid "ProjectSettings|Container registry"
+msgstr ""
+
+msgid "ProjectSettings|Customize your project badges."
+msgstr ""
+
+msgid "ProjectSettings|Disable email notifications"
+msgstr ""
+
+msgid "ProjectSettings|Enable 'Delete source branch' option by default"
+msgstr ""
+
+msgid "ProjectSettings|Every merge creates a merge commit"
+msgstr ""
+
+msgid "ProjectSettings|Every project can have its own space to store its Docker images"
+msgstr ""
+
+msgid "ProjectSettings|Every project can have its own space to store its packages"
+msgstr ""
+
+msgid "ProjectSettings|Everyone"
+msgstr ""
+
+msgid "ProjectSettings|Existing merge requests and protected branches are not affected"
+msgstr ""
+
+msgid "ProjectSettings|Failed to protect the tag"
+msgstr ""
+
+msgid "ProjectSettings|Failed to update tag!"
+msgstr ""
+
+msgid "ProjectSettings|Fast-forward merge"
+msgstr ""
+
+msgid "ProjectSettings|Fast-forward merges only"
+msgstr ""
+
+msgid "ProjectSettings|Forks"
+msgstr ""
+
+msgid "ProjectSettings|Git Large File Storage"
+msgstr ""
+
+msgid "ProjectSettings|Internal"
+msgstr ""
+
+msgid "ProjectSettings|Issues"
+msgstr ""
+
+msgid "ProjectSettings|LFS objects from this repository are still available to forks. %{linkStart}How do I remove them?%{linkEnd}"
+msgstr ""
+
+msgid "ProjectSettings|Learn more about badges."
+msgstr ""
+
+msgid "ProjectSettings|Lightweight issue tracking system for this project"
+msgstr ""
+
+msgid "ProjectSettings|Manages large files such as audio, video, and graphics files"
+msgstr ""
+
+msgid "ProjectSettings|Merge checks"
+msgstr ""
+
+msgid "ProjectSettings|Merge commit"
+msgstr ""
+
+msgid "ProjectSettings|Merge commit with semi-linear history"
+msgstr ""
+
+msgid "ProjectSettings|Merge method"
+msgstr ""
+
+msgid "ProjectSettings|Merge options"
+msgstr ""
+
+msgid "ProjectSettings|Merge pipelines will try to validate the post-merge result prior to merging"
+msgstr ""
+
+msgid "ProjectSettings|Merge requests"
+msgstr ""
+
+msgid "ProjectSettings|Merge suggestions"
+msgstr ""
+
+msgid "ProjectSettings|No merge commits are created"
+msgstr ""
+
+msgid "ProjectSettings|Note: the container registry is always visible when a project is public"
+msgstr ""
+
+msgid "ProjectSettings|Only signed commits can be pushed to this repository."
+msgstr ""
+
+msgid "ProjectSettings|Packages"
+msgstr ""
+
+msgid "ProjectSettings|Pages"
+msgstr ""
+
+msgid "ProjectSettings|Pages for project documentation"
+msgstr ""
+
+msgid "ProjectSettings|Pipelines"
+msgstr ""
+
+msgid "ProjectSettings|Pipelines must succeed"
+msgstr ""
+
+msgid "ProjectSettings|Pipelines need to be configured to enable this feature."
+msgstr ""
+
+msgid "ProjectSettings|Private"
+msgstr ""
+
+msgid "ProjectSettings|Project visibility"
+msgstr ""
+
+msgid "ProjectSettings|Public"
+msgstr ""
+
+msgid "ProjectSettings|Repository"
+msgstr ""
+
+msgid "ProjectSettings|Share code pastes with others out of Git repository"
+msgstr ""
+
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
+msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
+msgstr ""
+
+msgid "ProjectSettings|Snippets"
+msgstr ""
+
+msgid "ProjectSettings|Submit changes to be merged upstream"
+msgstr ""
+
+msgid "ProjectSettings|The commit message used to apply merge request suggestions"
+msgstr ""
+
+msgid "ProjectSettings|The variables GitLab supports:"
+msgstr ""
+
+msgid "ProjectSettings|These checks must pass before merge requests can be merged"
+msgstr ""
+
+msgid "ProjectSettings|This setting is applied on the server level and can be overridden by an admin."
+msgstr ""
+
+msgid "ProjectSettings|This setting is applied on the server level but has been overridden for this project."
+msgstr ""
+
+msgid "ProjectSettings|This setting will be applied to all projects unless overridden by an admin."
+msgstr ""
+
+msgid "ProjectSettings|This setting will override user notification preferences for all project members."
+msgstr ""
+
+msgid "ProjectSettings|This will dictate the commit history when you merge a merge request"
+msgstr ""
+
+msgid "ProjectSettings|Users can only push commits to this repository that were committed with one of their own verified emails."
+msgstr ""
+
+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 ""
+
+msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
+msgstr ""
+
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
+msgid "ProjectSettings|Wiki"
+msgstr ""
+
+msgid "ProjectSettings|With GitLab Pages you can host your static websites on GitLab"
+msgstr ""
+
+msgid "ProjectSettings|With Metrics Dashboard you can visualize this project performance metrics"
+msgstr ""
+
+msgid "ProjectTemplates|.NET Core"
+msgstr ""
+
+msgid "ProjectTemplates|Android"
+msgstr ""
+
+msgid "ProjectTemplates|GitLab Cluster Management"
+msgstr ""
+
+msgid "ProjectTemplates|Go Micro"
+msgstr ""
+
+msgid "ProjectTemplates|HIPAA Audit Protocol"
+msgstr ""
+
+msgid "ProjectTemplates|Netlify/GitBook"
+msgstr ""
+
+msgid "ProjectTemplates|Netlify/Hexo"
+msgstr ""
+
+msgid "ProjectTemplates|Netlify/Hugo"
+msgstr ""
+
+msgid "ProjectTemplates|Netlify/Jekyll"
+msgstr ""
+
+msgid "ProjectTemplates|Netlify/Plain HTML"
+msgstr ""
+
+msgid "ProjectTemplates|NodeJS Express"
+msgstr ""
+
+msgid "ProjectTemplates|Pages/Gatsby"
+msgstr ""
+
+msgid "ProjectTemplates|Pages/GitBook"
+msgstr ""
+
+msgid "ProjectTemplates|Pages/Hexo"
+msgstr ""
+
+msgid "ProjectTemplates|Pages/Hugo"
+msgstr ""
+
+msgid "ProjectTemplates|Pages/Jekyll"
+msgstr ""
+
+msgid "ProjectTemplates|Pages/Plain HTML"
+msgstr ""
+
+msgid "ProjectTemplates|Ruby on Rails"
+msgstr ""
+
+msgid "ProjectTemplates|SalesforceDX"
+msgstr ""
+
+msgid "ProjectTemplates|Serverless Framework/JS"
+msgstr ""
+
+msgid "ProjectTemplates|Spring"
+msgstr ""
+
+msgid "ProjectTemplates|Static Site Editor/Middleman"
+msgstr ""
+
+msgid "ProjectTemplates|iOS (Swift)"
+msgstr ""
+
+msgid "Projects"
+msgstr ""
+
+msgid "Projects (%{count})"
+msgstr ""
+
+msgid "Projects Successfully Retrieved"
+msgstr ""
+
+msgid "Projects are graded based on the highest severity vulnerability present"
+msgstr ""
+
+msgid "Projects shared with %{group_name}"
+msgstr ""
+
+msgid "Projects that belong to a group are prefixed with the group namespace. Existing projects may be moved into a group."
+msgstr ""
+
+msgid "Projects to index"
+msgstr ""
+
+msgid "Projects with critical vulnerabilities"
+msgstr ""
+
+msgid "Projects with high or unknown vulnerabilities"
+msgstr ""
+
+msgid "Projects with low vulnerabilities"
+msgstr ""
+
+msgid "Projects with medium vulnerabilities"
+msgstr ""
+
+msgid "Projects with no vulnerabilities and security scanning enabled"
+msgstr ""
+
+msgid "Projects with write access"
+msgstr ""
+
+msgid "ProjectsDropdown|Frequently visited"
+msgstr ""
+
+msgid "ProjectsDropdown|Loading projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Projects you visit often will appear here"
+msgstr ""
+
+msgid "ProjectsDropdown|Search your projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Something went wrong on our end."
+msgstr ""
+
+msgid "ProjectsDropdown|Sorry, no projects matched your search"
+msgstr ""
+
+msgid "ProjectsDropdown|This feature requires browser localStorage support"
+msgstr ""
+
+msgid "ProjectsNew|Allows you to immediately clone this project’s repository. Skip this if you plan to push up an existing repository."
+msgstr ""
+
+msgid "ProjectsNew|Blank"
+msgstr ""
+
+msgid "ProjectsNew|Blank project"
+msgstr ""
+
+msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
+msgstr ""
+
+msgid "ProjectsNew|Create"
+msgstr ""
+
+msgid "ProjectsNew|Create from template"
+msgstr ""
+
+msgid "ProjectsNew|Creating project & repository."
+msgstr ""
+
+msgid "ProjectsNew|Description format"
+msgstr ""
+
+msgid "ProjectsNew|Import"
+msgstr ""
+
+msgid "ProjectsNew|Import project"
+msgstr ""
+
+msgid "ProjectsNew|Initialize repository with a README"
+msgstr ""
+
+msgid "ProjectsNew|No import options available"
+msgstr ""
+
+msgid "ProjectsNew|Please wait a moment, this page will automatically refresh when ready."
+msgstr ""
+
+msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
+msgstr ""
+
+msgid "ProjectsNew|Template"
+msgstr ""
+
+msgid "ProjectsNew|Visibility Level"
+msgstr ""
+
+msgid "ProjectsNew|Want to house several dependent projects under the same namespace? %{link_start}Create a group.%{link_end}"
+msgstr ""
+
+msgid "Prometheus"
+msgstr ""
+
+msgid "PrometheusAlerts|%{count} alerts applied"
+msgstr ""
+
+msgid "PrometheusAlerts|%{firingCount} firing"
+msgstr ""
+
+msgid "PrometheusAlerts|Add alert"
+msgstr ""
+
+msgid "PrometheusAlerts|Edit alert"
+msgstr ""
+
+msgid "PrometheusAlerts|Error creating alert"
+msgstr ""
+
+msgid "PrometheusAlerts|Error deleting alert"
+msgstr ""
+
+msgid "PrometheusAlerts|Error fetching alert"
+msgstr ""
+
+msgid "PrometheusAlerts|Error saving alert"
+msgstr ""
+
+msgid "PrometheusAlerts|Firing: %{alerts}"
+msgstr ""
+
+msgid "PrometheusAlerts|Firing: %{alert}"
+msgstr ""
+
+msgid "PrometheusAlerts|Operator"
+msgstr ""
+
+msgid "PrometheusAlerts|Select query"
+msgstr ""
+
+msgid "PrometheusAlerts|Threshold"
+msgstr ""
+
+msgid "PrometheusService|%{exporters} with %{metrics} were found"
+msgstr ""
+
+msgid "PrometheusService|<p class=\"text-tertiary\">No <a href=\"%{docsUrl}\">common metrics</a> were found</p>"
+msgstr ""
+
+msgid "PrometheusService|Active"
+msgstr ""
+
+msgid "PrometheusService|Auto configuration"
+msgstr ""
+
+msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
+msgstr ""
+
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
+msgid "PrometheusService|Common metrics"
+msgstr ""
+
+msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
+msgstr ""
+
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
+msgid "PrometheusService|Custom metrics"
+msgstr ""
+
+msgid "PrometheusService|Custom metrics require Prometheus installed on a cluster with environment scope \"*\" OR a manually configured Prometheus to be available."
+msgstr ""
+
+msgid "PrometheusService|Enable Prometheus to define custom metrics, using either option above"
+msgstr ""
+
+msgid "PrometheusService|Finding and configuring metrics..."
+msgstr ""
+
+msgid "PrometheusService|Finding custom metrics..."
+msgstr ""
+
+msgid "PrometheusService|Install Prometheus on clusters"
+msgstr ""
+
+msgid "PrometheusService|Manage clusters"
+msgstr ""
+
+msgid "PrometheusService|Manual configuration"
+msgstr ""
+
+msgid "PrometheusService|Metrics"
+msgstr ""
+
+msgid "PrometheusService|Missing environment variable"
+msgstr ""
+
+msgid "PrometheusService|More information"
+msgstr ""
+
+msgid "PrometheusService|New metric"
+msgstr ""
+
+msgid "PrometheusService|No custom metrics have been created. Create one using the button above"
+msgstr ""
+
+msgid "PrometheusService|Prometheus API Base URL, like http://prometheus.example.com/"
+msgstr ""
+
+msgid "PrometheusService|Prometheus is being automatically managed on your clusters"
+msgstr ""
+
+msgid "PrometheusService|Select the Active checkbox to override the Auto Configuration with custom settings. If unchecked, Auto Configuration settings are used."
+msgstr ""
+
+msgid "PrometheusService|These metrics will only be monitored after your first deployment to an environment"
+msgstr ""
+
+msgid "PrometheusService|Time-series monitoring service"
+msgstr ""
+
+msgid "PrometheusService|To enable the installation of Prometheus on your clusters, deactivate the manual configuration below"
+msgstr ""
+
+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 has been deprecated."
+msgstr ""
+
+msgid "Promote"
+msgstr ""
+
+msgid "Promote confidential issue to a non-confidential epic"
+msgstr ""
+
+msgid "Promote issue to an epic"
+msgstr ""
+
+msgid "Promote these project milestones into a group milestone."
+msgstr ""
+
+msgid "Promote to group label"
+msgstr ""
+
+msgid "PromoteMilestone|Only project milestones can be promoted."
+msgstr ""
+
+msgid "PromoteMilestone|Project does not belong to a group."
+msgstr ""
+
+msgid "PromoteMilestone|Promotion failed - %{message}"
+msgstr ""
+
+msgid "Promoted confidential issue to a non-confidential epic. Information in this issue is no longer confidential as epics are public to group members."
+msgstr ""
+
+msgid "Promoted issue to an epic."
+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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
+msgid "Promotions|Don't show me this again"
+msgstr ""
+
+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 ""
+
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Learn more"
+msgstr ""
+
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
+msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
+msgstr ""
+
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
+msgid "Promotions|This feature is locked."
+msgstr ""
+
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
+msgid "Promotions|Upgrade plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
+msgid "Promotions|Weighting your issue"
+msgstr ""
+
+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 ""
+
+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 ""
+
+msgid "Prompt users to upload SSH keys"
+msgstr ""
+
+msgid "Protect variable"
+msgstr ""
+
+msgid "Protected"
+msgstr ""
+
+msgid "Protected Branch"
+msgstr ""
+
+msgid "Protected Environment"
+msgstr ""
+
+msgid "Protected Environments"
+msgstr ""
+
+msgid "Protected Paths"
+msgstr ""
+
+msgid "Protected Tag"
+msgstr ""
+
+msgid "Protected branches"
+msgstr ""
+
+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 ""
+
+msgid "ProtectedBranch|Allowed to merge"
+msgstr ""
+
+msgid "ProtectedBranch|Allowed to merge:"
+msgstr ""
+
+msgid "ProtectedBranch|Allowed to push"
+msgstr ""
+
+msgid "ProtectedBranch|Allowed to push:"
+msgstr ""
+
+msgid "ProtectedBranch|Branch"
+msgstr ""
+
+msgid "ProtectedBranch|Code owner approval"
+msgstr ""
+
+msgid "ProtectedBranch|Protect"
+msgstr ""
+
+msgid "ProtectedBranch|Protect a branch"
+msgstr ""
+
+msgid "ProtectedBranch|Protected branch (%{protected_branches_count})"
+msgstr ""
+
+msgid "ProtectedBranch|Pushes that change filenames matched by the CODEOWNERS file will be rejected"
+msgstr ""
+
+msgid "ProtectedBranch|Require approval from code owners:"
+msgstr ""
+
+msgid "ProtectedBranch|There are currently no protected branches, protect a branch with the form above."
+msgstr ""
+
+msgid "ProtectedBranch|Toggle code owner approval"
+msgstr ""
+
+msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
+msgstr ""
+
+msgid "ProtectedEnvironment|Allowed to deploy"
+msgstr ""
+
+msgid "ProtectedEnvironment|Environment"
+msgstr ""
+
+msgid "ProtectedEnvironment|Protect"
+msgstr ""
+
+msgid "ProtectedEnvironment|Protect an environment"
+msgstr ""
+
+msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
+msgstr ""
+
+msgid "ProtectedEnvironment|Protecting an environment restricts the users who can execute deployments."
+msgstr ""
+
+msgid "ProtectedEnvironment|Select an environment"
+msgstr ""
+
+msgid "ProtectedEnvironment|Select users"
+msgstr ""
+
+msgid "ProtectedEnvironment|Select users to deploy and manage Feature Flag settings"
+msgstr ""
+
+msgid "ProtectedEnvironment|There are currently no protected environments, protect an environment with the form above."
+msgstr ""
+
+msgid "ProtectedEnvironment|Unprotect"
+msgstr ""
+
+msgid "ProtectedEnvironment|Your environment can't be unprotected"
+msgstr ""
+
+msgid "ProtectedEnvironment|Your environment has been protected."
+msgstr ""
+
+msgid "ProtectedEnvironment|Your environment has been unprotected"
+msgstr ""
+
+msgid "Protip:"
+msgstr ""
+
+msgid "Protocol"
+msgstr ""
+
+msgid "Provider"
+msgstr ""
+
+msgid "Pseudonymizer data collection"
+msgstr ""
+
+msgid "Public"
+msgstr ""
+
+msgid "Public - The group and any public projects can be viewed without any authentication."
+msgstr ""
+
+msgid "Public - The project can be accessed without any authentication."
+msgstr ""
+
+msgid "Public deploy keys (%{deploy_keys_count})"
+msgstr ""
+
+msgid "Public pipelines"
+msgstr ""
+
+msgid "Public projects Minutes cost factor"
+msgstr ""
+
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
+msgid "Pull"
+msgstr ""
+
+msgid "Pull requests from fork are not supported"
+msgstr ""
+
+msgid "Puma is running with a thread count above 1 and the Rugged service is enabled. This may decrease performance in some environments. See our %{link_start}documentation%{link_end} for details of this issue."
+msgstr ""
+
+msgid "Purchase more minutes"
+msgstr ""
+
+msgid "Push"
+msgstr ""
+
+msgid "Push Rule updated successfully."
+msgstr ""
+
+msgid "Push Rules"
+msgstr ""
+
+msgid "Push Rules updated successfully."
+msgstr ""
+
+msgid "Push an existing Git repository"
+msgstr ""
+
+msgid "Push an existing folder"
+msgstr ""
+
+msgid "Push events"
+msgstr ""
+
+msgid "Push project from command line"
+msgstr ""
+
+msgid "Push to create a project"
+msgstr ""
+
+msgid "PushRule|Committer restriction"
+msgstr ""
+
+msgid "Pushed"
+msgstr ""
+
+msgid "Pushes"
+msgstr ""
+
+msgid "PushoverService|%{user_name} deleted branch \"%{ref}\"."
+msgstr ""
+
+msgid "PushoverService|%{user_name} push to branch \"%{ref}\"."
+msgstr ""
+
+msgid "PushoverService|%{user_name} pushed new branch \"%{ref}\"."
+msgstr ""
+
+msgid "PushoverService|High Priority"
+msgstr ""
+
+msgid "PushoverService|Leave blank for all active devices"
+msgstr ""
+
+msgid "PushoverService|Low Priority"
+msgstr ""
+
+msgid "PushoverService|Lowest Priority"
+msgstr ""
+
+msgid "PushoverService|Normal Priority"
+msgstr ""
+
+msgid "PushoverService|Pushover makes it easy to get real-time notifications on your Android device, iPhone, iPad, and Desktop."
+msgstr ""
+
+msgid "PushoverService|See project %{project_full_name}"
+msgstr ""
+
+msgid "PushoverService|Total commits count: %{total_commits_count}"
+msgstr ""
+
+msgid "PushoverService|Your application key"
+msgstr ""
+
+msgid "PushoverService|Your user key"
+msgstr ""
+
+msgid "Quarters"
+msgstr ""
+
+msgid "Query"
+msgstr ""
+
+msgid "Query cannot be processed"
+msgstr ""
+
+msgid "Query is valid"
+msgstr ""
+
+msgid "Queued"
+msgstr ""
+
+msgid "Quick actions"
+msgstr ""
+
+msgid "Quick actions can be used in the issues description and comment boxes."
+msgstr ""
+
+msgid "Quick range"
+msgstr ""
+
+msgid "README"
+msgstr ""
+
+msgid "Raw blob request rate limit per minute"
+msgstr ""
+
+msgid "Re-authentication period expired or never requested. Please try again"
+msgstr ""
+
+msgid "Re-authentication required"
+msgstr ""
+
+msgid "Re-verification interval"
+msgstr ""
+
+msgid "Read more"
+msgstr ""
+
+msgid "Read more about environments"
+msgstr ""
+
+msgid "Read more about project permissions <strong>%{link_to_help}</strong>"
+msgstr ""
+
+msgid "Read more about related issues"
+msgstr ""
+
+msgid "Real-time features"
+msgstr ""
+
+msgid "Rebase"
+msgstr ""
+
+msgid "Rebase in progress"
+msgstr ""
+
+msgid "Receive alerts from manually configured Prometheus servers."
+msgstr ""
+
+msgid "Receive notifications about your own activity"
+msgstr ""
+
+msgid "Recent"
+msgstr ""
+
+msgid "Recent Activity"
+msgstr ""
+
+msgid "Recent Project Activity"
+msgstr ""
+
+msgid "Recent Searches Service is unavailable"
+msgstr ""
+
+msgid "Recent searches"
+msgstr ""
+
+msgid "Recipe"
+msgstr ""
+
+msgid "Recover hidden stage"
+msgstr ""
+
+msgid "Recovery Codes"
+msgstr ""
+
+msgid "Redirect to SAML provider to test configuration"
+msgstr ""
+
+msgid "Reduce project visibility"
+msgstr ""
+
+msgid "Reduce this project’s visibility?"
+msgstr ""
+
+msgid "Reference:"
+msgstr ""
+
+msgid "Refresh"
+msgstr ""
+
+msgid "Refreshing in a second to show the updated status..."
+msgid_plural "Refreshing in %d seconds to show the updated status..."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Regenerate export"
+msgstr ""
+
+msgid "Regenerate instance ID"
+msgstr ""
+
+msgid "Regenerate key"
+msgstr ""
+
+msgid "Regenerate recovery codes"
+msgstr ""
+
+msgid "Regenerating the instance ID can break integration depending on the client you are using."
+msgstr ""
+
+msgid "Regex pattern"
+msgstr ""
+
+msgid "Region that Elasticsearch is configured"
+msgstr ""
+
+msgid "Register"
+msgstr ""
+
+msgid "Register / Sign In"
+msgstr ""
+
+msgid "Register Two-Factor Authenticator"
+msgstr ""
+
+msgid "Register U2F device"
+msgstr ""
+
+msgid "Register Universal Two-Factor (U2F) Device"
+msgstr ""
+
+msgid "Register for GitLab"
+msgstr ""
+
+msgid "Register now"
+msgstr ""
+
+msgid "Register with two-factor app"
+msgstr ""
+
+msgid "Registration"
+msgstr ""
+
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
+msgid "Related Deployed Jobs"
+msgstr ""
+
+msgid "Related Issues"
+msgstr ""
+
+msgid "Related Jobs"
+msgstr ""
+
+msgid "Related Merge Requests"
+msgstr ""
+
+msgid "Related Merged Requests"
+msgstr ""
+
+msgid "Related merge requests"
+msgstr ""
+
+msgid "Relates to"
+msgstr ""
+
+msgid "Release"
+msgid_plural "Releases"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Release assets"
+msgstr ""
+
+msgid "Release assets documentation"
+msgstr ""
+
+msgid "Release does not have the same project as the milestone"
+msgstr ""
+
+msgid "Release notes"
+msgstr ""
+
+msgid "Release notes:"
+msgstr ""
+
+msgid "Release title"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
+msgid "Releases"
+msgstr ""
+
+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 ""
+
+msgid "Releases are based on Git tags. We recommend tags that use semantic versioning, for example %{codeStart}v1.0%{codeEnd}, %{codeStart}v2.0-pre%{codeEnd}."
+msgstr ""
+
+msgid "Releases documentation"
+msgstr ""
+
+msgid "Release|Something went wrong while getting the release details"
+msgstr ""
+
+msgid "Release|Something went wrong while saving the release details"
+msgstr ""
+
+msgid "Remediated: needs review"
+msgstr ""
+
+msgid "Remediations"
+msgstr ""
+
+msgid "Remember me"
+msgstr ""
+
+msgid "Remind later"
+msgstr ""
+
+msgid "Remote object has no absolute path."
+msgstr ""
+
+msgid "Remove"
+msgstr ""
+
+msgid "Remove %{displayReference}"
+msgstr ""
+
+msgid "Remove Runner"
+msgstr ""
+
+msgid "Remove Zoom meeting"
+msgstr ""
+
+msgid "Remove all approvals in a merge request when new commits are pushed to its source branch"
+msgstr ""
+
+msgid "Remove all or specific assignee(s)"
+msgstr ""
+
+msgid "Remove all or specific label(s)"
+msgstr ""
+
+msgid "Remove approvers"
+msgstr ""
+
+msgid "Remove approvers?"
+msgstr ""
+
+msgid "Remove asset link"
+msgstr ""
+
+msgid "Remove assignee"
+msgstr ""
+
+msgid "Remove avatar"
+msgstr ""
+
+msgid "Remove card"
+msgstr ""
+
+msgid "Remove child epic from an epic"
+msgstr ""
+
+msgid "Remove description history"
+msgstr ""
+
+msgid "Remove due date"
+msgstr ""
+
+msgid "Remove fork relationship"
+msgstr ""
+
+msgid "Remove from board"
+msgstr ""
+
+msgid "Remove from epic"
+msgstr ""
+
+msgid "Remove group"
+msgstr ""
+
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
+msgid "Remove limit"
+msgstr ""
+
+msgid "Remove milestone"
+msgstr ""
+
+msgid "Remove node"
+msgstr ""
+
+msgid "Remove parent epic from an epic"
+msgstr ""
+
+msgid "Remove primary node"
+msgstr ""
+
+msgid "Remove priority"
+msgstr ""
+
+msgid "Remove project"
+msgstr ""
+
+msgid "Remove secondary node"
+msgstr ""
+
+msgid "Remove spent time"
+msgstr ""
+
+msgid "Remove stage"
+msgstr ""
+
+msgid "Remove time estimate"
+msgstr ""
+
+msgid "Removed"
+msgstr ""
+
+msgid "Removed %{assignee_text} %{assignee_references}."
+msgstr ""
+
+msgid "Removed %{epic_ref} from child epics."
+msgstr ""
+
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
+msgid "Removed %{label_references} %{label_text}."
+msgstr ""
+
+msgid "Removed %{milestone_reference} milestone."
+msgstr ""
+
+msgid "Removed %{type} with id %{id}"
+msgstr ""
+
+msgid "Removed all labels."
+msgstr ""
+
+msgid "Removed an issue from an epic."
+msgstr ""
+
+msgid "Removed group can not be restored!"
+msgstr ""
+
+msgid "Removed parent epic %{epic_ref}."
+msgstr ""
+
+msgid "Removed projects cannot be restored!"
+msgstr ""
+
+msgid "Removed spent time."
+msgstr ""
+
+msgid "Removed the due date."
+msgstr ""
+
+msgid "Removed time estimate."
+msgstr ""
+
+msgid "Removes %{assignee_text} %{assignee_references}."
+msgstr ""
+
+msgid "Removes %{epic_ref} from child epics."
+msgstr ""
+
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
+msgid "Removes %{label_references} %{label_text}."
+msgstr ""
+
+msgid "Removes %{milestone_reference} milestone."
+msgstr ""
+
+msgid "Removes all labels."
+msgstr ""
+
+msgid "Removes an issue from an epic."
+msgstr ""
+
+msgid "Removes parent epic %{epic_ref}."
+msgstr ""
+
+msgid "Removes spent time."
+msgstr ""
+
+msgid "Removes the due date."
+msgstr ""
+
+msgid "Removes time estimate."
+msgstr ""
+
+msgid "Removing a project places it into a read-only state until %{date}, at which point the project will be permanantly removed. Are you ABSOLUTELY sure?"
+msgstr ""
+
+msgid "Removing a project places it into a read-only state until %{date}, at which point the project will be permanently removed."
+msgstr ""
+
+msgid "Removing license…"
+msgstr ""
+
+msgid "Removing the project will delete its repository and all related resources including issues, merge requests etc."
+msgstr ""
+
+msgid "Removing this group also removes all child projects, including archived projects, and their resources."
+msgstr ""
+
+msgid "Rename file"
+msgstr ""
+
+msgid "Rename folder"
+msgstr ""
+
+msgid "Rename/Move"
+msgstr ""
+
+msgid "Reopen"
+msgstr ""
+
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
+msgid "Reopen epic"
+msgstr ""
+
+msgid "Reopen milestone"
+msgstr ""
+
+msgid "Reopen this %{quick_action_target}"
+msgstr ""
+
+msgid "Reopened this %{quick_action_target}."
+msgstr ""
+
+msgid "Reopens this %{quick_action_target}."
+msgstr ""
+
+msgid "Repair authentication"
+msgstr ""
+
+msgid "Replace"
+msgstr ""
+
+msgid "Replace all label(s)"
+msgstr ""
+
+msgid "Replaced all labels with %{label_references} %{label_text}."
+msgstr ""
+
+msgid "Replaces the clone URL root."
+msgstr ""
+
+msgid "Replication"
+msgstr ""
+
+msgid "Reply by email"
+msgstr ""
+
+msgid "Reply to comment"
+msgstr ""
+
+msgid "Reply to this email directly or %{view_it_on_gitlab}."
+msgstr ""
+
+msgid "Reply..."
+msgstr ""
+
+msgid "Repo by URL"
+msgstr ""
+
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
+msgstr ""
+
+msgid "Report abuse to admin"
+msgstr ""
+
+msgid "Reported %{timeAgo} by %{reportedBy}"
+msgstr ""
+
+msgid "Reported Resource Changes: %{addNum} to add, %{changeNum} to change, %{deleteNum} to delete"
+msgstr ""
+
+msgid "Reporter"
+msgstr ""
+
+msgid "Reporting"
+msgstr ""
+
+msgid "Reports|%{combinedString} and %{resolvedString}"
+msgstr ""
+
+msgid "Reports|Accessibility scanning detected %d issue for the source branch only"
+msgid_plural "Reports|Accessibility scanning detected %d issues for the source branch only"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Reports|Accessibility scanning detected no issues for the source branch only"
+msgstr ""
+
+msgid "Reports|Accessibility scanning failed loading results"
+msgstr ""
+
+msgid "Reports|Accessibility scanning results are being parsed"
+msgstr ""
+
+msgid "Reports|Actions"
+msgstr ""
+
+msgid "Reports|An error occured while loading report"
+msgstr ""
+
+msgid "Reports|An error occurred while loading %{name} results"
+msgstr ""
+
+msgid "Reports|Class"
+msgstr ""
+
+msgid "Reports|Classname"
+msgstr ""
+
+msgid "Reports|Execution time"
+msgstr ""
+
+msgid "Reports|Failure"
+msgstr ""
+
+msgid "Reports|Metrics reports are loading"
+msgstr ""
+
+msgid "Reports|Metrics reports changed on %{numberOfChanges} %{pointsString}"
+msgstr ""
+
+msgid "Reports|Metrics reports did not change"
+msgstr ""
+
+msgid "Reports|Metrics reports failed loading results"
+msgstr ""
+
+msgid "Reports|Severity"
+msgstr ""
+
+msgid "Reports|System output"
+msgstr ""
+
+msgid "Reports|Test summary"
+msgstr ""
+
+msgid "Reports|Test summary failed loading results"
+msgstr ""
+
+msgid "Reports|Test summary results are being parsed"
+msgstr ""
+
+msgid "Reports|Vulnerability"
+msgstr ""
+
+msgid "Reports|no changed test results"
+msgstr ""
+
+msgid "Repository"
+msgstr ""
+
+msgid "Repository Analytics"
+msgstr ""
+
+msgid "Repository Graph"
+msgstr ""
+
+msgid "Repository Settings"
+msgstr ""
+
+msgid "Repository URL"
+msgstr ""
+
+msgid "Repository check"
+msgstr ""
+
+msgid "Repository check was triggered."
+msgstr ""
+
+msgid "Repository cleanup"
+msgstr ""
+
+msgid "Repository cleanup has started. You will receive an email once the cleanup operation is complete."
+msgstr ""
+
+msgid "Repository has no locks."
+msgstr ""
+
+msgid "Repository maintenance"
+msgstr ""
+
+msgid "Repository mirroring"
+msgstr ""
+
+msgid "Repository static objects"
+msgstr ""
+
+msgid "Repository storage"
+msgstr ""
+
+msgid "Repository sync capacity"
+msgstr ""
+
+msgid "Repository: %{counter_repositories} / Wikis: %{counter_wikis} / Build Artifacts: %{counter_build_artifacts} / LFS: %{counter_lfs_objects}"
+msgstr ""
+
+msgid "RepositorySettingsAccessLevel|Select"
+msgstr ""
+
+msgid "Request Access"
+msgstr ""
+
+msgid "Request Headers"
+msgstr ""
+
+msgid "Request parameter %{param} is missing."
+msgstr ""
+
+msgid "Request to link SAML account must be authorized"
+msgstr ""
+
+msgid "Requested %{time_ago}"
+msgstr ""
+
+msgid "Requested design version does not exist."
+msgstr ""
+
+msgid "Requested states are invalid"
+msgstr ""
+
+msgid "Requests"
+msgstr ""
+
+msgid "Requests Profiles"
+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 ""
+
+msgid "Require all users in this group to setup Two-factor authentication"
+msgstr ""
+
+msgid "Require all users to accept Terms of Service and Privacy Policy when they access GitLab."
+msgstr ""
+
+msgid "Require user password to approve"
+msgstr ""
+
+msgid "Require users to prove ownership of custom domains"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
+msgid "Requirement"
+msgstr ""
+
+msgid "Requirement %{reference} has been added"
+msgstr ""
+
+msgid "Requirement %{reference} has been archived"
+msgstr ""
+
+msgid "Requirement %{reference} has been reopened"
+msgstr ""
+
+msgid "Requirement %{reference} has been updated"
+msgstr ""
+
+msgid "Requirement title cannot have more than %{limit} characters."
+msgstr ""
+
+msgid "Requirements"
+msgstr ""
+
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
+msgstr ""
+
+msgid "Requires approval from %{names}."
+msgid_plural "Requires %{count} more approvals from %{names}."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Requires approval."
+msgid_plural "Requires %d more approvals."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Requires values to meet regular expression requirements."
+msgstr ""
+
+msgid "Resend confirmation email"
+msgstr ""
+
+msgid "Resend invite"
+msgstr ""
+
+msgid "Resend it"
+msgstr ""
+
+msgid "Reset authorization key"
+msgstr ""
+
+msgid "Reset authorization key?"
+msgstr ""
+
+msgid "Reset health check access token"
+msgstr ""
+
+msgid "Reset key"
+msgstr ""
+
+msgid "Reset runners registration token"
+msgstr ""
+
+msgid "Reset template"
+msgstr ""
+
+msgid "Resetting the authorization key for this project will require updating the authorization key in every alert source it is enabled in."
+msgstr ""
+
+msgid "Resetting the authorization key will invalidate the previous key. Existing alert configurations will need to be updated with the new key."
+msgstr ""
+
+msgid "Resolve"
+msgstr ""
+
+msgid "Resolve all threads in new issue"
+msgstr ""
+
+msgid "Resolve conflicts on source branch"
+msgstr ""
+
+msgid "Resolve thread"
+msgstr ""
+
+msgid "Resolved"
+msgstr ""
+
+msgid "Resolved 1 discussion."
+msgstr ""
+
+msgid "Resolved all discussions."
+msgstr ""
+
+msgid "Resolved by"
+msgstr ""
+
+msgid "Resolved by %{name}"
+msgstr ""
+
+msgid "Resolved by %{resolvedByName}"
+msgstr ""
+
+msgid "Resolves IP addresses once and uses them to submit requests"
+msgstr ""
+
+msgid "Response"
+msgstr ""
+
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
+msgid "Response didn't include `service_desk_address`"
+msgstr ""
+
+msgid "Response metrics (AWS ELB)"
+msgstr ""
+
+msgid "Response metrics (Custom)"
+msgstr ""
+
+msgid "Response metrics (HA Proxy)"
+msgstr ""
+
+msgid "Response metrics (NGINX Ingress VTS)"
+msgstr ""
+
+msgid "Response metrics (NGINX Ingress)"
+msgstr ""
+
+msgid "Response metrics (NGINX)"
+msgstr ""
+
+msgid "Restart Terminal"
+msgstr ""
+
+msgid "Restore group"
+msgstr ""
+
+msgid "Restore project"
+msgstr ""
+
+msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
+msgstr ""
+
+msgid "Restoring the project will prevent the project from being removed on this date and restore people's ability to make changes to it."
+msgstr ""
+
+msgid "Restrict access by IP address"
+msgstr ""
+
+msgid "Restrict membership by email"
+msgstr ""
+
+msgid "Restricts sign-ups for email addresses that match the given regex. See the %{supported_syntax_link_start}supported syntax%{supported_syntax_link_end} for more information."
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Resume replication"
+msgstr ""
+
+msgid "Resync"
+msgstr ""
+
+msgid "Resync all"
+msgstr ""
+
+msgid "Resync all %{replicableType}"
+msgstr ""
+
+msgid "Retry"
+msgstr ""
+
+msgid "Retry this job"
+msgstr ""
+
+msgid "Retry this job in order to create the necessary resources."
+msgstr ""
+
+msgid "Retry update"
+msgstr ""
+
+msgid "Retry verification"
+msgstr ""
+
+msgid "Reveal value"
+msgid_plural "Reveal values"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Reveal values"
+msgstr ""
+
+msgid "Revert this commit"
+msgstr ""
+
+msgid "Revert this merge request"
+msgstr ""
+
+msgid "Review"
+msgstr ""
+
+msgid "Review App|View app"
+msgstr ""
+
+msgid "Review App|View latest app"
+msgstr ""
+
+msgid "Review the process for configuring service providers in your identity provider — in this case, GitLab is the \"service provider\" or \"relying party\"."
+msgstr ""
+
+msgid "Review time"
+msgstr ""
+
+msgid "Review time is defined as the time it takes from first comment until merged."
+msgstr ""
+
+msgid "ReviewApp|Enable Review App"
+msgstr ""
+
+msgid "Reviewing"
+msgstr ""
+
+msgid "Reviewing (merge request !%{mergeRequestId})"
+msgstr ""
+
+msgid "Revoke"
+msgstr ""
+
+msgid "Revoked impersonation token %{token_name}!"
+msgstr ""
+
+msgid "Revoked personal access token %{personal_access_token_name}!"
+msgstr ""
+
+msgid "Revoked project access token %{project_access_token_name}!"
+msgstr ""
+
+msgid "RightSidebar|adding a"
+msgstr ""
+
+msgid "RightSidebar|deleting the"
+msgstr ""
+
+msgid "Roadmap"
+msgstr ""
+
+msgid "Role"
+msgstr ""
+
+msgid "Rollback"
+msgstr ""
+
+msgid "Rook"
+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 ""
+
+msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
+msgstr ""
+
+msgid "Run CI/CD pipelines for external repositories"
+msgstr ""
+
+msgid "Run housekeeping"
+msgstr ""
+
+msgid "Run tests against your code live using the Web Terminal"
+msgstr ""
+
+msgid "Run untagged jobs"
+msgstr ""
+
+msgid "Runner cannot be assigned to other projects"
+msgstr ""
+
+msgid "Runner runs jobs from all unassigned projects"
+msgstr ""
+
+msgid "Runner runs jobs from all unassigned projects in its group"
+msgstr ""
+
+msgid "Runner runs jobs from assigned projects"
+msgstr ""
+
+msgid "Runner token"
+msgstr ""
+
+msgid "Runner tokens"
+msgstr ""
+
+msgid "Runner was not updated."
+msgstr ""
+
+msgid "Runner was successfully updated."
+msgstr ""
+
+msgid "Runner will not receive any new jobs"
+msgstr ""
+
+msgid "Runners"
+msgstr ""
+
+msgid "Runners API"
+msgstr ""
+
+msgid "Runners activated for this project"
+msgstr ""
+
+msgid "Runners are processes that pick up and execute jobs for GitLab. Here you can register and see your Runners for this project."
+msgstr ""
+
+msgid "Runners can be placed on separate users, servers, and even on your local machine."
+msgstr ""
+
+msgid "Runners can be placed on separate users, servers, even on your local machine."
+msgstr ""
+
+msgid "Runners currently online: %{active_runners_count}"
+msgstr ""
+
+msgid "Runners page."
+msgstr ""
+
+msgid "Runners|You have used %{quotaUsed} out of %{quotaLimit} of your shared Runners pipeline minutes."
+msgstr ""
+
+msgid "Running"
+msgstr ""
+
+msgid "Running…"
+msgstr ""
+
+msgid "Runs a number of housekeeping tasks within the current repository, such as compressing file revisions and removing unreachable objects."
+msgstr ""
+
+msgid "SAML SSO"
+msgstr ""
+
+msgid "SAML SSO for %{group_name}"
+msgstr ""
+
+msgid "SAML discovery tokens"
+msgstr ""
+
+msgid "SAML for %{group_name}"
+msgstr ""
+
+msgid "SHA256"
+msgstr ""
+
+msgid "SSH Key"
+msgstr ""
+
+msgid "SSH Keys"
+msgstr ""
+
+msgid "SSH host key fingerprints"
+msgstr ""
+
+msgid "SSH host keys"
+msgstr ""
+
+msgid "SSH host keys are not available on this system. Please use <code>ssh-keyscan</code> command or contact your GitLab administrator for more information."
+msgstr ""
+
+msgid "SSH keys allow you to establish a secure connection between your computer and GitLab."
+msgstr ""
+
+msgid "SSH public key"
+msgstr ""
+
+msgid "SSL Verification:"
+msgstr ""
+
+msgid "Saturday"
+msgstr ""
+
+msgid "Save"
+msgstr ""
+
+msgid "Save Changes"
+msgstr ""
+
+msgid "Save anyway"
+msgstr ""
+
+msgid "Save application"
+msgstr ""
+
+msgid "Save changes"
+msgstr ""
+
+msgid "Save changes before testing"
+msgstr ""
+
+msgid "Save comment"
+msgstr ""
+
+msgid "Save expiration policy"
+msgstr ""
+
+msgid "Save password"
+msgstr ""
+
+msgid "Save pipeline schedule"
+msgstr ""
+
+msgid "Save template"
+msgstr ""
+
+msgid "Save variables"
+msgstr ""
+
+msgid "Saving"
+msgstr ""
+
+msgid "Saving project."
+msgstr ""
+
+msgid "Schedule a new pipeline"
+msgstr ""
+
+msgid "Scheduled"
+msgstr ""
+
+msgid "Scheduled to merge this merge request (%{strategy})."
+msgstr ""
+
+msgid "Scheduled to merge this merge request when the pipeline succeeds."
+msgstr ""
+
+msgid "Schedules"
+msgstr ""
+
+msgid "Schedules to merge this merge request (%{strategy})."
+msgstr ""
+
+msgid "Scheduling"
+msgstr ""
+
+msgid "Scheduling Pipelines"
+msgstr ""
+
+msgid "Scope"
+msgstr ""
+
+msgid "Scope not supported with disabled 'users_search' feature!"
+msgstr ""
+
+msgid "Scoped issue boards"
+msgstr ""
+
+msgid "Scopes"
+msgstr ""
+
+msgid "Scopes can't be blank"
+msgstr ""
+
+msgid "Scroll down"
+msgstr ""
+
+msgid "Scroll down to <strong>Google Code Project Hosting</strong> and enable the switch on the right."
+msgstr ""
+
+msgid "Scroll left"
+msgstr ""
+
+msgid "Scroll right"
+msgstr ""
+
+msgid "Scroll to bottom"
+msgstr ""
+
+msgid "Scroll to top"
+msgstr ""
+
+msgid "Scroll up"
+msgstr ""
+
+msgid "Search"
+msgstr ""
+
+msgid "Search Button"
+msgstr ""
+
+msgid "Search Milestones"
+msgstr ""
+
+msgid "Search an environment spec"
+msgstr ""
+
+msgid "Search authors"
+msgstr ""
+
+msgid "Search branches"
+msgstr ""
+
+msgid "Search branches and tags"
+msgstr ""
+
+msgid "Search by author"
+msgstr ""
+
+msgid "Search files"
+msgstr ""
+
+msgid "Search for a LDAP group"
+msgstr ""
+
+msgid "Search for a group"
+msgstr ""
+
+msgid "Search for a user"
+msgstr ""
+
+msgid "Search for projects, issues, etc."
+msgstr ""
+
+msgid "Search for this text"
+msgstr ""
+
+msgid "Search forks"
+msgstr ""
+
+msgid "Search groups"
+msgstr ""
+
+msgid "Search merge requests"
+msgstr ""
+
+msgid "Search milestones"
+msgstr ""
+
+msgid "Search or filter results..."
+msgstr ""
+
+msgid "Search or filter results…"
+msgstr ""
+
+msgid "Search or jump to…"
+msgstr ""
+
+msgid "Search project"
+msgstr ""
+
+msgid "Search projects"
+msgstr ""
+
+msgid "Search projects..."
+msgstr ""
+
+msgid "Search requirements"
+msgstr ""
+
+msgid "Search users"
+msgstr ""
+
+msgid "Search users or groups"
+msgstr ""
+
+msgid "Search your project dependencies for their licenses and apply policies."
+msgstr ""
+
+msgid "Search your projects"
+msgstr ""
+
+msgid "SearchAutocomplete|All GitLab"
+msgstr ""
+
+msgid "SearchAutocomplete|Issues I've created"
+msgstr ""
+
+msgid "SearchAutocomplete|Issues assigned to me"
+msgstr ""
+
+msgid "SearchAutocomplete|Merge requests I've created"
+msgstr ""
+
+msgid "SearchAutocomplete|Merge requests assigned to me"
+msgstr ""
+
+msgid "SearchAutocomplete|in all GitLab"
+msgstr ""
+
+msgid "SearchAutocomplete|in group %{groupName}"
+msgstr ""
+
+msgid "SearchAutocomplete|in project %{projectName}"
+msgstr ""
+
+msgid "SearchCodeResults|in"
+msgstr ""
+
+msgid "SearchCodeResults|of %{link_to_project}"
+msgstr ""
+
+msgid "SearchResults|Showing %{count} %{scope} for%{term_element}"
+msgstr ""
+
+msgid "SearchResults|Showing %{count} %{scope} for%{term_element} in your personal and project snippets"
+msgstr ""
+
+msgid "SearchResults|Showing %{from} - %{to} of %{count} %{scope} for%{term_element}"
+msgstr ""
+
+msgid "SearchResults|Showing %{from} - %{to} of %{count} %{scope} for%{term_element} in your personal and project snippets"
+msgstr ""
+
+msgid "SearchResults|We couldn't find any %{scope} matching %{term}"
+msgstr ""
+
+msgid "SearchResults|code result"
+msgid_plural "SearchResults|code results"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "SearchResults|comment"
+msgid_plural "SearchResults|comments"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "SearchResults|commit"
+msgid_plural "SearchResults|commits"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "SearchResults|issue"
+msgid_plural "SearchResults|issues"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "SearchResults|merge request"
+msgid_plural "SearchResults|merge requests"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "SearchResults|milestone"
+msgid_plural "SearchResults|milestones"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "SearchResults|project"
+msgid_plural "SearchResults|projects"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "SearchResults|snippet"
+msgid_plural "SearchResults|snippets"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "SearchResults|user"
+msgid_plural "SearchResults|users"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "SearchResults|wiki result"
+msgid_plural "SearchResults|wiki results"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Searching by both author and message is currently not supported."
+msgstr ""
+
+msgid "Seat Link"
+msgstr ""
+
+msgid "Seat Link is disabled, and cannot be configured through this form."
+msgstr ""
+
+msgid "Seats currently in use"
+msgstr ""
+
+msgid "Seats in license"
+msgstr ""
+
+msgid "Secondary"
+msgstr ""
+
+msgid "Secret"
+msgstr ""
+
+msgid "Secret Detection"
+msgstr ""
+
+msgid "Security"
+msgstr ""
+
+msgid "Security & Compliance"
+msgstr ""
+
+msgid "Security Configuration"
+msgstr ""
+
+msgid "Security Dashboard"
+msgstr ""
+
+msgid "Security dashboard"
+msgstr ""
+
+msgid "Security report is out of date. Please update your branch with the latest changes from the target branch (%{targetBranchName})"
+msgstr ""
+
+msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
+msgstr ""
+
+msgid "SecurityConfiguration|Enabled"
+msgstr ""
+
+msgid "SecurityConfiguration|Feature documentation for %{featureName}"
+msgstr ""
+
+msgid "SecurityConfiguration|Not yet enabled"
+msgstr ""
+
+msgid "SecurityConfiguration|Security Control"
+msgstr ""
+
+msgid "SecurityConfiguration|Status"
+msgstr ""
+
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
+msgid "SecurityReports|%{firstProject} and %{secondProject}"
+msgstr ""
+
+msgid "SecurityReports|%{firstProject}, %{secondProject}, and %{rest}"
+msgstr ""
+
+msgid "SecurityReports|Add a project to your dashboard"
+msgstr ""
+
+msgid "SecurityReports|Add or remove projects from your dashboard"
+msgstr ""
+
+msgid "SecurityReports|Add projects"
+msgstr ""
+
+msgid "SecurityReports|Comment added to '%{vulnerabilityName}'"
+msgstr ""
+
+msgid "SecurityReports|Comment deleted on '%{vulnerabilityName}'"
+msgstr ""
+
+msgid "SecurityReports|Comment edited on '%{vulnerabilityName}'"
+msgstr ""
+
+msgid "SecurityReports|Create issue"
+msgstr ""
+
+msgid "SecurityReports|Dismiss Selected"
+msgstr ""
+
+msgid "SecurityReports|Dismiss vulnerability"
+msgstr ""
+
+msgid "SecurityReports|Dismissed '%{vulnerabilityName}'"
+msgstr ""
+
+msgid "SecurityReports|Dismissed '%{vulnerabilityName}'. Turn off the hide dismissed toggle to view."
+msgstr ""
+
+msgid "SecurityReports|Each vulnerability now has a unique page that can be directly linked to, shared, referenced, and tracked as the single source of truth. Vulnerability occurrences also persist across scanner runs, which improves tracking and visibility and reduces duplicates between scans."
+msgstr ""
+
+msgid "SecurityReports|Edit dashboard"
+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 ""
+
+msgid "SecurityReports|Error fetching the vulnerability counts. Please check your network connection and try again."
+msgstr ""
+
+msgid "SecurityReports|Error fetching the vulnerability list. Please check your network connection and try again."
+msgstr ""
+
+msgid "SecurityReports|False positive"
+msgstr ""
+
+msgid "SecurityReports|Hide dismissed"
+msgstr ""
+
+msgid "SecurityReports|Introducing standalone vulnerabilities"
+msgstr ""
+
+msgid "SecurityReports|Issue Created"
+msgstr ""
+
+msgid "SecurityReports|Learn More"
+msgstr ""
+
+msgid "SecurityReports|Learn more about setting up your dashboard"
+msgstr ""
+
+msgid "SecurityReports|Load more vulnerabilities"
+msgstr ""
+
+msgid "SecurityReports|Monitor vulnerabilities in your code"
+msgstr ""
+
+msgid "SecurityReports|More info"
+msgstr ""
+
+msgid "SecurityReports|More information"
+msgstr ""
+
+msgid "SecurityReports|No vulnerabilities found for dashboard"
+msgstr ""
+
+msgid "SecurityReports|No vulnerabilities found for this group"
+msgstr ""
+
+msgid "SecurityReports|No vulnerabilities found for this pipeline"
+msgstr ""
+
+msgid "SecurityReports|No vulnerabilities found for this project"
+msgstr ""
+
+msgid "SecurityReports|Oops, something doesn't seem right."
+msgstr ""
+
+msgid "SecurityReports|Pipeline %{pipelineLink} triggered %{timeago} by %{user}"
+msgstr ""
+
+msgid "SecurityReports|Project"
+msgstr ""
+
+msgid "SecurityReports|Projects added"
+msgstr ""
+
+msgid "SecurityReports|Remove project from dashboard"
+msgstr ""
+
+msgid "SecurityReports|Report type"
+msgstr ""
+
+msgid "SecurityReports|Return to dashboard"
+msgstr ""
+
+msgid "SecurityReports|Security Dashboard"
+msgstr ""
+
+msgid "SecurityReports|Security reports can only be accessed by authorized users."
+msgstr ""
+
+msgid "SecurityReports|Select a project to add by using the project search field above."
+msgstr ""
+
+msgid "SecurityReports|Select a reason"
+msgstr ""
+
+msgid "SecurityReports|Severity"
+msgstr ""
+
+msgid "SecurityReports|Status"
+msgstr ""
+
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
+msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
+msgstr ""
+
+msgid "SecurityReports|The security dashboard displays the latest security report. Use it to find and fix vulnerabilities."
+msgstr ""
+
+msgid "SecurityReports|There was an error adding the comment."
+msgstr ""
+
+msgid "SecurityReports|There was an error creating the issue."
+msgstr ""
+
+msgid "SecurityReports|There was an error creating the merge request."
+msgstr ""
+
+msgid "SecurityReports|There was an error deleting the comment."
+msgstr ""
+
+msgid "SecurityReports|There was an error dismissing the vulnerabilities."
+msgstr ""
+
+msgid "SecurityReports|There was an error dismissing the vulnerability."
+msgstr ""
+
+msgid "SecurityReports|There was an error reverting the dismissal."
+msgstr ""
+
+msgid "SecurityReports|There was an error reverting this dismissal."
+msgstr ""
+
+msgid "SecurityReports|There was an error while generating the report."
+msgstr ""
+
+msgid "SecurityReports|Unable to add %{invalidProjects}"
+msgstr ""
+
+msgid "SecurityReports|Undo dismiss"
+msgstr ""
+
+msgid "SecurityReports|While it's rare to have no vulnerabilities for your group, it can happen. In any event, we ask that you double check your settings to make sure you've set up your dashboard correctly."
+msgstr ""
+
+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 ""
+
+msgid "SecurityReports|While it's rare to have no vulnerabilities for your project, it can happen. In any event, we ask that you double check your settings to make sure you've set up your dashboard correctly."
+msgstr ""
+
+msgid "SecurityReports|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 "SecurityReports|Won't fix / Accept risk"
+msgstr ""
+
+msgid "SecurityReports|You do not have sufficient permissions to access this report"
+msgstr ""
+
+msgid "SecurityReports|You must sign in as an authorized user to see this report"
+msgstr ""
+
+msgid "SecurityReports|[No reason]"
+msgstr ""
+
+msgid "See GitLab's %{password_policy_guidelines}"
+msgstr ""
+
+msgid "See metrics"
+msgstr ""
+
+msgid "See the affected projects in the GitLab admin panel"
+msgstr ""
+
+msgid "See what's new at GitLab"
+msgstr ""
+
+msgid "Select"
+msgstr ""
+
+msgid "Select Archive Format"
+msgstr ""
+
+msgid "Select Git revision"
+msgstr ""
+
+msgid "Select GitLab project to link with your Slack team"
+msgstr ""
+
+msgid "Select Page"
+msgstr ""
+
+msgid "Select Stack"
+msgstr ""
+
+msgid "Select a file from the left sidebar to begin editing. Afterwards, you'll be able to commit your changes."
+msgstr ""
+
+msgid "Select a group to invite"
+msgstr ""
+
+msgid "Select a label"
+msgstr ""
+
+msgid "Select a namespace to fork the project"
+msgstr ""
+
+msgid "Select a new namespace"
+msgstr ""
+
+msgid "Select a project"
+msgstr ""
+
+msgid "Select a project to read Insights configuration file"
+msgstr ""
+
+msgid "Select a reason"
+msgstr ""
+
+msgid "Select a repository"
+msgstr ""
+
+msgid "Select a template repository"
+msgstr ""
+
+msgid "Select a template type"
+msgstr ""
+
+msgid "Select a timezone"
+msgstr ""
+
+msgid "Select all"
+msgstr ""
+
+msgid "Select an existing Kubernetes cluster or create a new one"
+msgstr ""
+
+msgid "Select assignee"
+msgstr ""
+
+msgid "Select branch"
+msgstr ""
+
+msgid "Select branch/tag"
+msgstr ""
+
+msgid "Select due date"
+msgstr ""
+
+msgid "Select group or project"
+msgstr ""
+
+msgid "Select groups to replicate"
+msgstr ""
+
+msgid "Select health status"
+msgstr ""
+
+msgid "Select labels"
+msgstr ""
+
+msgid "Select merge moment"
+msgstr ""
+
+msgid "Select milestone"
+msgstr ""
+
+msgid "Select private project"
+msgstr ""
+
+msgid "Select project"
+msgstr ""
+
+msgid "Select project and zone to choose machine type"
+msgstr ""
+
+msgid "Select project to choose zone"
+msgstr ""
+
+msgid "Select projects"
+msgstr ""
+
+msgid "Select projects you want to import."
+msgstr ""
+
+msgid "Select required regulatory standard"
+msgstr ""
+
+msgid "Select shards to replicate"
+msgstr ""
+
+msgid "Select source branch"
+msgstr ""
+
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
+msgid "Select strategy activation method"
+msgstr ""
+
+msgid "Select subscription"
+msgstr ""
+
+msgid "Select target branch"
+msgstr ""
+
+msgid "Select the branch you want to set as the default for this project. All merge requests and commits will automatically be made against this branch unless you specify a different one."
+msgstr ""
+
+msgid "Select the configured storage available for new repositories to be placed on."
+msgstr ""
+
+msgid "Select the custom project template source group."
+msgstr ""
+
+msgid "Select timeframe"
+msgstr ""
+
+msgid "Select user"
+msgstr ""
+
+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 "Selecting a GitLab user will add a link to the GitLab user in the descriptions of issues and comments (e.g. \"By <a href=\"#\">@johnsmith</a>\"). It will also associate and/or assign these issues and comments with the selected user."
+msgstr ""
+
+msgid "Selective synchronization"
+msgstr ""
+
+msgid "Self monitoring project does not exist"
+msgstr ""
+
+msgid "Self-monitoring project does not exist. Please check logs for any error messages"
+msgstr ""
+
+msgid "Self-monitoring project has been successfully deleted"
+msgstr ""
+
+msgid "Self-monitoring project was not deleted. Please check logs for any error messages"
+msgstr ""
+
+msgid "SelfMonitoring|Disable self monitoring?"
+msgstr ""
+
+msgid "SelfMonitoring|Disabling this feature will delete the self monitoring project. Are you sure you want to delete the project?"
+msgstr ""
+
+msgid "SelfMonitoring|Enable or disable instance self monitoring"
+msgstr ""
+
+msgid "SelfMonitoring|Enabling this feature creates a %{projectLinkStart}project%{projectLinkEnd} that can be used to monitor the health of your instance."
+msgstr ""
+
+msgid "SelfMonitoring|Enabling this feature creates a project that can be used to monitor the health of your instance."
+msgstr ""
+
+msgid "SelfMonitoring|Self monitoring"
+msgstr ""
+
+msgid "SelfMonitoring|Self monitoring project has been successfully created."
+msgstr ""
+
+msgid "SelfMonitoring|Self monitoring project has been successfully deleted."
+msgstr ""
+
+msgid "Send a separate email notification to Developers."
+msgstr ""
+
+msgid "Send confirmation email"
+msgstr ""
+
+msgid "Send email"
+msgstr ""
+
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
+msgid "Send report"
+msgstr ""
+
+msgid "Send usage data"
+msgstr ""
+
+msgid "Sentry API URL"
+msgstr ""
+
+msgid "Sentry event"
+msgstr ""
+
+msgid "Sep"
+msgstr ""
+
+msgid "Separate topics with commas."
+msgstr ""
+
+msgid "September"
+msgstr ""
+
+msgid "SeriesFinalConjunction|and"
+msgstr ""
+
+msgid "Serve repository static objects (e.g. archives, blobs, ...) from an external storage (e.g. a CDN)."
+msgstr ""
+
+msgid "Server supports batch API only, please update your Git LFS client to version 1.0.1 and up."
+msgstr ""
+
+msgid "Server version"
+msgstr ""
+
+msgid "Serverless"
+msgstr ""
+
+msgid "Serverless domain"
+msgstr ""
+
+msgid "ServerlessDetails|Function invocation metrics require Prometheus to be installed first."
+msgstr ""
+
+msgid "ServerlessDetails|Install Prometheus"
+msgstr ""
+
+msgid "ServerlessDetails|Invocation metrics loading or not available at this time."
+msgstr ""
+
+msgid "ServerlessDetails|Invocations"
+msgstr ""
+
+msgid "ServerlessDetails|Kubernetes Pods"
+msgstr ""
+
+msgid "ServerlessDetails|More information"
+msgstr ""
+
+msgid "ServerlessDetails|No pods loaded at this time."
+msgstr ""
+
+msgid "ServerlessDetails|Number of Kubernetes pods in use over time based on necessity."
+msgstr ""
+
+msgid "ServerlessDetails|pod in use"
+msgstr ""
+
+msgid "ServerlessDetails|pods in use"
+msgstr ""
+
+msgid "ServerlessURL|Copy URL"
+msgstr ""
+
+msgid "Serverless| In order to start using functions as a service, you must first install Knative on your Kubernetes cluster."
+msgstr ""
+
+msgid "Serverless|Getting started with serverless"
+msgstr ""
+
+msgid "Serverless|Help shape the future of Serverless at GitLab"
+msgstr ""
+
+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 ""
+
+msgid "Serverless|Install Knative"
+msgstr ""
+
+msgid "Serverless|Learn more about Serverless"
+msgstr ""
+
+msgid "Serverless|No functions available"
+msgstr ""
+
+msgid "Serverless|Sign up for First Look"
+msgstr ""
+
+msgid "Serverless|The deploy job has not finished."
+msgstr ""
+
+msgid "Serverless|The functions listed in the %{startTag}serverless.yml%{endTag} file don't match the namespace of your cluster."
+msgstr ""
+
+msgid "Serverless|There is currently no function data available from Knative. This could be for a variety of reasons including:"
+msgstr ""
+
+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 ""
+
+msgid "Serverless|Your %{startTag}.gitlab-ci.yml%{endTag} file is not properly configured."
+msgstr ""
+
+msgid "Serverless|Your repository does not have a corresponding %{startTag}serverless.yml%{endTag} file."
+msgstr ""
+
+msgid "Service"
+msgstr ""
+
+msgid "Service Desk"
+msgstr ""
+
+msgid "Service Desk is enabled but not yet active"
+msgstr ""
+
+msgid "Service Desk is off"
+msgstr ""
+
+msgid "Service Desk is on"
+msgstr ""
+
+msgid "Service Templates"
+msgstr ""
+
+msgid "Service URL"
+msgstr ""
+
+msgid "Session duration (minutes)"
+msgstr ""
+
+msgid "Set %{epic_ref} as the parent epic."
+msgstr ""
+
+msgid "Set a default template for issue descriptions."
+msgstr ""
+
+msgid "Set a number of approvals required, the approvers and other approval settings."
+msgstr ""
+
+msgid "Set a password on your account to pull or push via %{protocol}."
+msgstr ""
+
+msgid "Set a template repository for projects in this group"
+msgstr ""
+
+msgid "Set an instance-wide domain that will be available to all clusters when installing Knative."
+msgstr ""
+
+msgid "Set default and restrict visibility levels. Configure import sources and git access protocol."
+msgstr ""
+
+msgid "Set due date"
+msgstr ""
+
+msgid "Set instance-wide template repository"
+msgstr ""
+
+msgid "Set iteration"
+msgstr ""
+
+msgid "Set max session time for web terminal."
+msgstr ""
+
+msgid "Set milestone"
+msgstr ""
+
+msgid "Set new password"
+msgstr ""
+
+msgid "Set notification email for abuse reports."
+msgstr ""
+
+msgid "Set parent epic to an epic"
+msgstr ""
+
+msgid "Set projects and maximum size limits, session duration, user options, and check feature availability for namespace plan."
+msgstr ""
+
+msgid "Set requirements for a user to sign-in. Enable mandatory two-factor authentication."
+msgstr ""
+
+msgid "Set target branch"
+msgstr ""
+
+msgid "Set target branch to %{branch_name}."
+msgstr ""
+
+msgid "Set the default expiration time for each job's artifacts. 0 for unlimited. The default unit is in seconds, but you can define an alternative. For example: <code>4 mins 2 sec</code>, <code>2h42min</code>."
+msgstr ""
+
+msgid "Set the due date to %{due_date}."
+msgstr ""
+
+msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
+msgstr ""
+
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
+msgid "Set the maximum file size for each job's artifacts"
+msgstr ""
+
+msgid "Set the maximum number of pipeline minutes that a group can use on shared Runners per month. 0 for unlimited."
+msgstr ""
+
+msgid "Set the milestone to %{milestone_reference}."
+msgstr ""
+
+msgid "Set time estimate"
+msgstr ""
+
+msgid "Set time estimate to %{time_estimate}."
+msgstr ""
+
+msgid "Set up CI/CD"
+msgstr ""
+
+msgid "Set up Jira Integration"
+msgstr ""
+
+msgid "Set up a %{type} Runner automatically"
+msgstr ""
+
+msgid "Set up a %{type} Runner manually"
+msgstr ""
+
+msgid "Set up assertions/attributes/claims (email, first_name, last_name) and NameID according to %{docsLinkStart}the documentation %{icon}%{docsLinkEnd}"
+msgstr ""
+
+msgid "Set up new U2F device"
+msgstr ""
+
+msgid "Set up new password"
+msgstr ""
+
+msgid "Set up pipeline subscriptions for this project."
+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 ""
+
+msgid "Set weight"
+msgstr ""
+
+msgid "Set weight to %{weight}."
+msgstr ""
+
+msgid "SetPasswordToCloneLink|set a password"
+msgstr ""
+
+msgid "SetStatusModal|Add status emoji"
+msgstr ""
+
+msgid "SetStatusModal|Clear status"
+msgstr ""
+
+msgid "SetStatusModal|Edit status"
+msgstr ""
+
+msgid "SetStatusModal|Remove status"
+msgstr ""
+
+msgid "SetStatusModal|Set a status"
+msgstr ""
+
+msgid "SetStatusModal|Set status"
+msgstr ""
+
+msgid "SetStatusModal|Sorry, we weren't able to set your status. Please try again later."
+msgstr ""
+
+msgid "SetStatusModal|What's your status?"
+msgstr ""
+
+msgid "Sets %{epic_ref} as parent epic."
+msgstr ""
+
+msgid "Sets target branch to %{branch_name}."
+msgstr ""
+
+msgid "Sets the due date to %{due_date}."
+msgstr ""
+
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
+msgid "Sets the milestone to %{milestone_reference}."
+msgstr ""
+
+msgid "Sets time estimate to %{time_estimate}."
+msgstr ""
+
+msgid "Sets weight to %{weight}."
+msgstr ""
+
+msgid "Settings"
+msgstr ""
+
+msgid "Settings related to the use and experience of using GitLab's Package Registry."
+msgstr ""
+
+msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
+msgstr ""
+
+msgid "Severity"
+msgstr ""
+
+msgid "Shards (%{shards})"
+msgstr ""
+
+msgid "Shards to synchronize"
+msgstr ""
+
+msgid "Share"
+msgstr ""
+
+msgid "Share the <strong>%{sso_label}</strong> with members so they can sign in to your group through your identity provider"
+msgstr ""
+
+msgid "Shared Runners"
+msgstr ""
+
+msgid "Shared projects"
+msgstr ""
+
+msgid "Shared runners help link"
+msgstr ""
+
+msgid "SharedRunnersMinutesSettings|By resetting the pipeline minutes for this namespace, the currently used minutes will be set to zero."
+msgstr ""
+
+msgid "SharedRunnersMinutesSettings|Reset pipeline minutes"
+msgstr ""
+
+msgid "SharedRunnersMinutesSettings|Reset used pipeline minutes"
+msgstr ""
+
+msgid "Sherlock Transactions"
+msgstr ""
+
+msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
+msgstr ""
+
+msgid "Show all activity"
+msgstr ""
+
+msgid "Show all members"
+msgstr ""
+
+msgid "Show all requirements."
+msgstr ""
+
+msgid "Show archived projects"
+msgstr ""
+
+msgid "Show archived projects only"
+msgstr ""
+
+msgid "Show command"
+msgstr ""
+
+msgid "Show comments"
+msgstr ""
+
+msgid "Show comments only"
+msgstr ""
+
+msgid "Show commit description"
+msgstr ""
+
+msgid "Show complete raw log"
+msgstr ""
+
+msgid "Show file browser"
+msgstr ""
+
+msgid "Show file contents"
+msgstr ""
+
+msgid "Show latest version"
+msgstr ""
+
+msgid "Show me everything"
+msgstr ""
+
+msgid "Show me how"
+msgstr ""
+
+msgid "Show me more advanced stuff"
+msgstr ""
+
+msgid "Show only direct members"
+msgstr ""
+
+msgid "Show only inherited members"
+msgstr ""
+
+msgid "Show parent pages"
+msgstr ""
+
+msgid "Show parent subgroups"
+msgstr ""
+
+msgid "Show whitespace changes"
+msgstr ""
+
+msgid "Showing %d event"
+msgid_plural "Showing %d events"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Showing %{limit} of %{total_count} issues. "
+msgstr ""
+
+msgid "Showing %{pageSize} of %{total} issues"
+msgstr ""
+
+msgid "Showing Latest Version"
+msgstr ""
+
+msgid "Showing Version #%{versionNumber}"
+msgstr ""
+
+msgid "Showing all issues"
+msgstr ""
+
+msgid "Showing all labels"
+msgstr ""
+
+msgid "Showing last %{size} of log -"
+msgstr ""
+
+msgid "Side-by-side"
+msgstr ""
+
+msgid "Sidebar|Assign health status"
+msgstr ""
+
+msgid "Sidebar|Change weight"
+msgstr ""
+
+msgid "Sidebar|Health status"
+msgstr ""
+
+msgid "Sidebar|No status"
+msgstr ""
+
+msgid "Sidebar|None"
+msgstr ""
+
+msgid "Sidebar|Only numeral characters allowed"
+msgstr ""
+
+msgid "Sidebar|Weight"
+msgstr ""
+
+msgid "Sign in"
+msgstr ""
+
+msgid "Sign in / Register"
+msgstr ""
+
+msgid "Sign in to \"%{group_name}\""
+msgstr ""
+
+msgid "Sign in using smart card"
+msgstr ""
+
+msgid "Sign in via 2FA code"
+msgstr ""
+
+msgid "Sign in with Single Sign-On"
+msgstr ""
+
+msgid "Sign in with smart card"
+msgstr ""
+
+msgid "Sign out"
+msgstr ""
+
+msgid "Sign out & Register"
+msgstr ""
+
+msgid "Sign up"
+msgstr ""
+
+msgid "Sign up was successful! Please confirm your email to sign in."
+msgstr ""
+
+msgid "Sign-in restrictions"
+msgstr ""
+
+msgid "Sign-up restrictions"
+msgstr ""
+
+msgid "SignUp|First Name is too long (maximum is %{max_length} characters)."
+msgstr ""
+
+msgid "SignUp|Last Name is too long (maximum is %{max_length} characters)."
+msgstr ""
+
+msgid "SignUp|Name is too long (maximum is %{max_length} characters)."
+msgstr ""
+
+msgid "SignUp|Username is too long (maximum is %{max_length} characters)."
+msgstr ""
+
+msgid "Signed in"
+msgstr ""
+
+msgid "Signed in with %{authentication} authentication"
+msgstr ""
+
+msgid "Signing in using %{label} has been disabled"
+msgstr ""
+
+msgid "Signing in using your %{label} account without a pre-existing GitLab account is not allowed."
+msgstr ""
+
+msgid "Similar issues"
+msgstr ""
+
+msgid "Single or combined queries"
+msgstr ""
+
+msgid "Size"
+msgstr ""
+
+msgid "Size and domain settings for static websites"
+msgstr ""
+
+msgid "Size limit per repository (MB)"
+msgstr ""
+
+msgid "Size settings for static websites"
+msgstr ""
+
+msgid "Skip outdated deployment jobs"
+msgstr ""
+
+msgid "Skip this for now"
+msgstr ""
+
+msgid "Skipped"
+msgstr ""
+
+msgid "Slack application"
+msgstr ""
+
+msgid "Slack channels (e.g. general, development)"
+msgstr ""
+
+msgid "Slack integration allows you to interact with GitLab via slash commands in a chat window."
+msgstr ""
+
+msgid "SlackIntegration|%{webhooks_link_start}Add an incoming webhook%{webhooks_link_end} in your Slack team. The default channel can be overridden for each event."
+msgstr ""
+
+msgid "SlackIntegration|<strong>Note:</strong> Usernames and private channels are not supported."
+msgstr ""
+
+msgid "SlackIntegration|Paste the <strong>Webhook URL</strong> into the field below."
+msgstr ""
+
+msgid "SlackIntegration|Select events below to enable notifications. The <strong>Slack channel names</strong> and <strong>Slack username</strong> fields are optional."
+msgstr ""
+
+msgid "SlackIntegration|This service send notifications about projects' events to Slack channels. To set up this service:"
+msgstr ""
+
+msgid "SlackService|2. Paste the <strong>Token</strong> into the field below"
+msgstr ""
+
+msgid "SlackService|3. Select the <strong>Active</strong> checkbox, press <strong>Save changes</strong> and start using GitLab inside Slack!"
+msgstr ""
+
+msgid "SlackService|Fill in the word that works best for your team."
+msgstr ""
+
+msgid "SlackService|See list of available commands in Slack after setting up this service, by entering"
+msgstr ""
+
+msgid "SlackService|This service allows users to perform common operations on this project by entering slash commands in Slack."
+msgstr ""
+
+msgid "Slower but makes sure the project workspace is pristine as it clones the repository from scratch for every job"
+msgstr ""
+
+msgid "Smartcard"
+msgstr ""
+
+msgid "Smartcard authentication failed: client certificate header is missing."
+msgstr ""
+
+msgid "Snippets"
+msgstr ""
+
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
+msgid "SnippetsEmptyState|Code snippets"
+msgstr ""
+
+msgid "SnippetsEmptyState|Documentation"
+msgstr ""
+
+msgid "SnippetsEmptyState|New snippet"
+msgstr ""
+
+msgid "SnippetsEmptyState|No snippets found"
+msgstr ""
+
+msgid "SnippetsEmptyState|Store, share, and embed small pieces of code and text."
+msgstr ""
+
+msgid "SnippetsEmptyState|There are no snippets to show."
+msgstr ""
+
+msgid "Snippets|Description (optional)"
+msgstr ""
+
+msgid "Snippets|File"
+msgstr ""
+
+msgid "Snippets|Give your file a name to add code highlighting, e.g. example.rb for Ruby"
+msgstr ""
+
+msgid "Snippets|Optionally add a description about what your snippet does or how to use it..."
+msgstr ""
+
+msgid "Snippets|Optionally add a description about what your snippet does or how to use it…"
+msgstr ""
+
+msgid "Snowplow"
+msgstr ""
+
+msgid "Solution"
+msgstr ""
+
+msgid "Some child epics may be hidden due to applied filters"
+msgstr ""
+
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
+msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
+msgstr ""
+
+msgid "Some of the designs you tried uploading did not change:"
+msgstr ""
+
+msgid "Some of your epics may not be visible. A roadmap is limited to the first 1,000 epics, in your selected sort order."
+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 ""
+
+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 ""
+
+msgid "Something went wrong on our end"
+msgstr ""
+
+msgid "Something went wrong on our end."
+msgstr ""
+
+msgid "Something went wrong on our end. Please try again!"
+msgstr ""
+
+msgid "Something went wrong on our end. Please try again."
+msgstr ""
+
+msgid "Something went wrong trying to change the confidentiality of this issue"
+msgstr ""
+
+msgid "Something went wrong trying to change the locked state of this %{issuableDisplayName}"
+msgstr ""
+
+msgid "Something went wrong when toggling the button"
+msgstr ""
+
+msgid "Something went wrong while adding your award. Please try again."
+msgstr ""
+
+msgid "Something went wrong while applying the suggestion. Please try again."
+msgstr ""
+
+msgid "Something went wrong while archiving a requirement."
+msgstr ""
+
+msgid "Something went wrong while closing the %{issuable}. Please try again later"
+msgstr ""
+
+msgid "Something went wrong while creating a requirement."
+msgstr ""
+
+msgid "Something went wrong while deleting description changes. Please try again."
+msgstr ""
+
+msgid "Something went wrong while deleting the package."
+msgstr ""
+
+msgid "Something went wrong while deleting the source branch. Please try again."
+msgstr ""
+
+msgid "Something went wrong while deleting your note. Please try again."
+msgstr ""
+
+msgid "Something went wrong while deploying this environment. Please try again."
+msgstr ""
+
+msgid "Something went wrong while editing your comment. Please try again."
+msgstr ""
+
+msgid "Something went wrong while fetching %{listType} list"
+msgstr ""
+
+msgid "Something went wrong while fetching comments. Please try again."
+msgstr ""
+
+msgid "Something went wrong while fetching description changes. Please try again."
+msgstr ""
+
+msgid "Something went wrong while fetching group member contributions"
+msgstr ""
+
+msgid "Something went wrong while fetching latest comments."
+msgstr ""
+
+msgid "Something went wrong while fetching projects"
+msgstr ""
+
+msgid "Something went wrong while fetching projects."
+msgstr ""
+
+msgid "Something went wrong while fetching related merge requests."
+msgstr ""
+
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
+msgid "Something went wrong while fetching requirements list."
+msgstr ""
+
+msgid "Something went wrong while fetching the environments for this merge request. Please try again."
+msgstr ""
+
+msgid "Something went wrong while fetching the package."
+msgstr ""
+
+msgid "Something went wrong while fetching the packages list."
+msgstr ""
+
+msgid "Something went wrong while initializing the OpenAPI viewer"
+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 reopening a requirement."
+msgstr ""
+
+msgid "Something went wrong while reopening the %{issuable}. Please try again later"
+msgstr ""
+
+msgid "Something went wrong while resolving this discussion. Please try again."
+msgstr ""
+
+msgid "Something went wrong while stopping this environment. Please try again."
+msgstr ""
+
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
+msgid "Something went wrong while updating a requirement."
+msgstr ""
+
+msgid "Something went wrong while updating your list settings"
+msgstr ""
+
+msgid "Something went wrong with your automatic subscription renewal"
+msgstr ""
+
+msgid "Something went wrong, unable to add %{project} to dashboard"
+msgstr ""
+
+msgid "Something went wrong, unable to add projects to dashboard"
+msgstr ""
+
+msgid "Something went wrong, unable to get projects"
+msgstr ""
+
+msgid "Something went wrong, unable to remove project"
+msgstr ""
+
+msgid "Something went wrong, unable to search projects"
+msgstr ""
+
+msgid "Something went wrong. Please try again."
+msgstr ""
+
+msgid "Something went wrong. Try again later."
+msgstr ""
+
+msgid "Sorry, no epics matched your search"
+msgstr ""
+
+msgid "Sorry, no projects matched your search"
+msgstr ""
+
+msgid "Sorry, you have exceeded the maximum browsable page number. Please use the API to explore further."
+msgstr ""
+
+msgid "Sorry, your filter produced no results"
+msgstr ""
+
+msgid "Sort by"
+msgstr ""
+
+msgid "Sort direction"
+msgstr ""
+
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
+msgid "SortOptions|Access level, ascending"
+msgstr ""
+
+msgid "SortOptions|Access level, descending"
+msgstr ""
+
+msgid "SortOptions|Created date"
+msgstr ""
+
+msgid "SortOptions|Due date"
+msgstr ""
+
+msgid "SortOptions|Due later"
+msgstr ""
+
+msgid "SortOptions|Due soon"
+msgstr ""
+
+msgid "SortOptions|Expired date"
+msgstr ""
+
+msgid "SortOptions|Label priority"
+msgstr ""
+
+msgid "SortOptions|Largest group"
+msgstr ""
+
+msgid "SortOptions|Largest repository"
+msgstr ""
+
+msgid "SortOptions|Last Contact"
+msgstr ""
+
+msgid "SortOptions|Last created"
+msgstr ""
+
+msgid "SortOptions|Last joined"
+msgstr ""
+
+msgid "SortOptions|Last updated"
+msgstr ""
+
+msgid "SortOptions|Least popular"
+msgstr ""
+
+msgid "SortOptions|Less weight"
+msgstr ""
+
+msgid "SortOptions|Manual"
+msgstr ""
+
+msgid "SortOptions|Milestone due date"
+msgstr ""
+
+msgid "SortOptions|Milestone due later"
+msgstr ""
+
+msgid "SortOptions|Milestone due soon"
+msgstr ""
+
+msgid "SortOptions|More weight"
+msgstr ""
+
+msgid "SortOptions|Most popular"
+msgstr ""
+
+msgid "SortOptions|Most stars"
+msgstr ""
+
+msgid "SortOptions|Name"
+msgstr ""
+
+msgid "SortOptions|Name, ascending"
+msgstr ""
+
+msgid "SortOptions|Name, descending"
+msgstr ""
+
+msgid "SortOptions|Oldest created"
+msgstr ""
+
+msgid "SortOptions|Oldest joined"
+msgstr ""
+
+msgid "SortOptions|Oldest last activity"
+msgstr ""
+
+msgid "SortOptions|Oldest sign in"
+msgstr ""
+
+msgid "SortOptions|Oldest starred"
+msgstr ""
+
+msgid "SortOptions|Oldest updated"
+msgstr ""
+
+msgid "SortOptions|Popularity"
+msgstr ""
+
+msgid "SortOptions|Priority"
+msgstr ""
+
+msgid "SortOptions|Project"
+msgstr ""
+
+msgid "SortOptions|Recent last activity"
+msgstr ""
+
+msgid "SortOptions|Recent sign in"
+msgstr ""
+
+msgid "SortOptions|Recently starred"
+msgstr ""
+
+msgid "SortOptions|Size"
+msgstr ""
+
+msgid "SortOptions|Sort by:"
+msgstr ""
+
+msgid "SortOptions|Sort direction"
+msgstr ""
+
+msgid "SortOptions|Stars"
+msgstr ""
+
+msgid "SortOptions|Start date"
+msgstr ""
+
+msgid "SortOptions|Start later"
+msgstr ""
+
+msgid "SortOptions|Start soon"
+msgstr ""
+
+msgid "SortOptions|Type"
+msgstr ""
+
+msgid "SortOptions|Version"
+msgstr ""
+
+msgid "SortOptions|Weight"
+msgstr ""
+
+msgid "Source"
+msgstr ""
+
+msgid "Source (branch or tag)"
+msgstr ""
+
+msgid "Source code"
+msgstr ""
+
+msgid "Source is not available"
+msgstr ""
+
+msgid "Source project cannot be found."
+msgstr ""
+
+msgid "Sourcegraph"
+msgstr ""
+
+msgid "SourcegraphAdmin|Block on private and internal projects"
+msgstr ""
+
+msgid "SourcegraphAdmin|Configure the URL to a Sourcegraph instance which can read your GitLab projects."
+msgstr ""
+
+msgid "SourcegraphAdmin|Enable Sourcegraph"
+msgstr ""
+
+msgid "SourcegraphAdmin|Enable code intelligence powered by %{link_start}Sourcegraph%{link_end} on your GitLab instance's code views and merge requests."
+msgstr ""
+
+msgid "SourcegraphAdmin|If checked, only public projects will have code intelligence and communicate with Sourcegraph."
+msgstr ""
+
+msgid "SourcegraphAdmin|More information"
+msgstr ""
+
+msgid "SourcegraphAdmin|Save changes"
+msgstr ""
+
+msgid "SourcegraphAdmin|Sourcegraph URL"
+msgstr ""
+
+msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgstr ""
+
+msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
+msgstr ""
+
+msgid "SourcegraphPreferences|This feature is experimental and limited to public projects."
+msgstr ""
+
+msgid "SourcegraphPreferences|This feature is experimental."
+msgstr ""
+
+msgid "SourcegraphPreferences|Uses %{link_start}Sourcegraph.com%{link_end}."
+msgstr ""
+
+msgid "SourcegraphPreferences|Uses a custom %{link_start}Sourcegraph instance%{link_end}."
+msgstr ""
+
+msgid "Spam Logs"
+msgstr ""
+
+msgid "Spam and Anti-bot Protection"
+msgstr ""
+
+msgid "Spam log successfully submitted as ham."
+msgstr ""
+
+msgid "Specific Runners"
+msgstr ""
+
+msgid "Specified URL cannot be used: \"%{reason}\""
+msgstr ""
+
+msgid "Specify an e-mail address regex pattern to identify default internal users."
+msgstr ""
+
+msgid "Specify the following URL during the Runner setup:"
+msgstr ""
+
+msgid "Speed up your DevOps<br>with GitLab"
+msgstr ""
+
+msgid "Squash commit message"
+msgstr ""
+
+msgid "Squash commits"
+msgstr ""
+
+msgid "Stack trace"
+msgstr ""
+
+msgid "Stage"
+msgstr ""
+
+msgid "Stage & Commit"
+msgstr ""
+
+msgid "Stage data updated"
+msgstr ""
+
+msgid "Stage removed"
+msgstr ""
+
+msgid "Standard"
+msgstr ""
+
+msgid "Star a label to make it a priority label. Order the prioritized labels to change their relative priority, by dragging."
+msgstr ""
+
+msgid "Star labels to start sorting by priority"
+msgstr ""
+
+msgid "Star toggle failed. Try again later."
+msgstr ""
+
+msgid "StarProject|Star"
+msgstr ""
+
+msgid "Starred Projects"
+msgstr ""
+
+msgid "Starred Projects' Activity"
+msgstr ""
+
+msgid "Starred projects"
+msgstr ""
+
+msgid "StarredProjectsEmptyState|Visit a project page and press on a star icon. Then, you can find the project on this page."
+msgstr ""
+
+msgid "StarredProjectsEmptyState|You don't have starred projects yet."
+msgstr ""
+
+msgid "Starrers"
+msgstr ""
+
+msgid "Stars"
+msgstr ""
+
+msgid "Start Date"
+msgstr ""
+
+msgid "Start Web Terminal"
+msgstr ""
+
+msgid "Start a %{new_merge_request} with these changes"
+msgstr ""
+
+msgid "Start a Free Gold Trial"
+msgstr ""
+
+msgid "Start a new discussion..."
+msgstr ""
+
+msgid "Start a new merge request"
+msgstr ""
+
+msgid "Start a review"
+msgstr ""
+
+msgid "Start and due date"
+msgstr ""
+
+msgid "Start by choosing a group to see how your team is spending time. You can then drill down to the project level."
+msgstr ""
+
+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 ""
+
+msgid "Start date"
+msgstr ""
+
+msgid "Start merge train"
+msgstr ""
+
+msgid "Start merge train when pipeline succeeds"
+msgstr ""
+
+msgid "Start search"
+msgstr ""
+
+msgid "Start the Runner!"
+msgstr ""
+
+msgid "Start thread"
+msgstr ""
+
+msgid "Start thread & close %{noteable_name}"
+msgstr ""
+
+msgid "Start thread & reopen %{noteable_name}"
+msgstr ""
+
+msgid "Start your Free Gold Trial"
+msgstr ""
+
+msgid "Start your free trial"
+msgstr ""
+
+msgid "Start your trial"
+msgstr ""
+
+msgid "Started"
+msgstr ""
+
+msgid "Started %{startsIn}"
+msgstr ""
+
+msgid "Started asynchronous removal of all repository check states."
+msgstr ""
+
+msgid "Started:"
+msgstr ""
+
+msgid "Starting..."
+msgstr ""
+
+msgid "Starts %{startsIn}"
+msgstr ""
+
+msgid "Starts at (UTC)"
+msgstr ""
+
+msgid "State your message to activate"
+msgstr ""
+
+msgid "Static Application Security Testing (SAST)"
+msgstr ""
+
+msgid "StaticSiteEditor|An error occurred while submitting your changes."
+msgstr ""
+
+msgid "StaticSiteEditor|Branch could not be created."
+msgstr ""
+
+msgid "StaticSiteEditor|Could not commit the content changes."
+msgstr ""
+
+msgid "StaticSiteEditor|Could not create merge request."
+msgstr ""
+
+msgid "StaticSiteEditor|Incompatible file content"
+msgstr ""
+
+msgid "StaticSiteEditor|Return to site"
+msgstr ""
+
+msgid "StaticSiteEditor|Static site editor"
+msgstr ""
+
+msgid "StaticSiteEditor|Success!"
+msgstr ""
+
+msgid "StaticSiteEditor|Summary of changes"
+msgstr ""
+
+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 ""
+
+msgid "StaticSiteEditor|Update %{sourcePath} file"
+msgstr ""
+
+msgid "StaticSiteEditor|View documentation"
+msgstr ""
+
+msgid "StaticSiteEditor|View merge request"
+msgstr ""
+
+msgid "StaticSiteEditor|You added a commit:"
+msgstr ""
+
+msgid "StaticSiteEditor|You created a merge request:"
+msgstr ""
+
+msgid "StaticSiteEditor|You created a new branch:"
+msgstr ""
+
+msgid "StaticSiteEditor|Your changes have been submitted and a merge request has been created. The changes won’t be visible on the site until the merge request has been accepted."
+msgstr ""
+
+msgid "Statistics"
+msgstr ""
+
+msgid "Status"
+msgstr ""
+
+msgid "Status:"
+msgstr ""
+
+msgid "Status: %{title}"
+msgstr ""
+
+msgid "StatusPage|AWS Secret access key"
+msgstr ""
+
+msgid "StatusPage|AWS access key ID"
+msgstr ""
+
+msgid "StatusPage|AWS documentation"
+msgstr ""
+
+msgid "StatusPage|AWS region"
+msgstr ""
+
+msgid "StatusPage|Active"
+msgstr ""
+
+msgid "StatusPage|Bucket %{docsLink}"
+msgstr ""
+
+msgid "StatusPage|Configure file storage settings to link issues in this project to an external status page."
+msgstr ""
+
+msgid "StatusPage|For help with configuration, visit %{docsLink}"
+msgstr ""
+
+msgid "StatusPage|S3 Bucket name"
+msgstr ""
+
+msgid "StatusPage|Status page"
+msgstr ""
+
+msgid "StatusPage|Status page URL"
+msgstr ""
+
+msgid "StatusPage|Status page frontend documentation"
+msgstr ""
+
+msgid "StatusPage|To publish incidents to an external status page, GitLab will store a JSON file in your Amazon S3 account in a location accessible to your external status page service. Make sure to also set up %{docsLink}"
+msgstr ""
+
+msgid "StatusPage|configuration documentation"
+msgstr ""
+
+msgid "StatusPage|your status page frontend."
+msgstr ""
+
+msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
+msgstr ""
+
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
+msgid "Stop Terminal"
+msgstr ""
+
+msgid "Stop impersonation"
+msgstr ""
+
+msgid "Stop this environment"
+msgstr ""
+
+msgid "Stopped"
+msgstr ""
+
+msgid "Stopping..."
+msgstr ""
+
+msgid "Storage"
+msgstr ""
+
+msgid "Storage nodes for new repositories"
+msgstr ""
+
+msgid "Storage:"
+msgstr ""
+
+msgid "StorageSize|Unknown"
+msgstr ""
+
+msgid "Subgroup milestone"
+msgstr ""
+
+msgid "Subgroup overview"
+msgstr ""
+
+msgid "SubgroupCreationLevel|Allowed to create subgroups"
+msgstr ""
+
+msgid "SubgroupCreationlevel|Allowed to create subgroups"
+msgstr ""
+
+msgid "SubgroupCreationlevel|Maintainers"
+msgstr ""
+
+msgid "SubgroupCreationlevel|Owners"
+msgstr ""
+
+msgid "Subgroups"
+msgstr ""
+
+msgid "Subgroups and projects"
+msgstr ""
+
+msgid "Subject Key Identifier:"
+msgstr ""
+
+msgid "Subkeys"
+msgstr ""
+
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
+msgid "Submit Changes"
+msgstr ""
+
+msgid "Submit a review"
+msgstr ""
+
+msgid "Submit as spam"
+msgstr ""
+
+msgid "Submit feedback"
+msgstr ""
+
+msgid "Submit issue"
+msgstr ""
+
+msgid "Submit review"
+msgstr ""
+
+msgid "Submit search"
+msgstr ""
+
+msgid "Submit the current review."
+msgstr ""
+
+msgid "Submitted the current review."
+msgstr ""
+
+msgid "Subscribe"
+msgstr ""
+
+msgid "Subscribe at group level"
+msgstr ""
+
+msgid "Subscribe at project level"
+msgstr ""
+
+msgid "Subscribe to RSS feed"
+msgstr ""
+
+msgid "Subscribe to calendar"
+msgstr ""
+
+msgid "Subscribed"
+msgstr ""
+
+msgid "Subscribed to this %{quick_action_target}."
+msgstr ""
+
+msgid "Subscribes to this %{quick_action_target}."
+msgstr ""
+
+msgid "Subscription"
+msgstr ""
+
+msgid "Subscription deletion failed."
+msgstr ""
+
+msgid "Subscription successfully applied to \"%{group_name}\""
+msgstr ""
+
+msgid "Subscription successfully created."
+msgstr ""
+
+msgid "Subscription successfully deleted."
+msgstr ""
+
+msgid "SubscriptionTable|Billing"
+msgstr ""
+
+msgid "SubscriptionTable|Free"
+msgstr ""
+
+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 ""
+
+msgid "SubscriptionTable|Last invoice"
+msgstr ""
+
+msgid "SubscriptionTable|Loading subscriptions"
+msgstr ""
+
+msgid "SubscriptionTable|Manage"
+msgstr ""
+
+msgid "SubscriptionTable|Max seats used"
+msgstr ""
+
+msgid "SubscriptionTable|Next invoice"
+msgstr ""
+
+msgid "SubscriptionTable|Seats currently in use"
+msgstr ""
+
+msgid "SubscriptionTable|Seats in subscription"
+msgstr ""
+
+msgid "SubscriptionTable|Seats owed"
+msgstr ""
+
+msgid "SubscriptionTable|Subscription end date"
+msgstr ""
+
+msgid "SubscriptionTable|Subscription start date"
+msgstr ""
+
+msgid "SubscriptionTable|This is the last time the GitLab.com team was in contact with you to settle any outstanding balances."
+msgstr ""
+
+msgid "SubscriptionTable|This is the maximum number of users that have existed at the same time since this subscription started."
+msgstr ""
+
+msgid "SubscriptionTable|This is the next date when the GitLab.com team is scheduled to get in contact with you to settle any outstanding balances."
+msgstr ""
+
+msgid "SubscriptionTable|This is the number of seats you will be required to purchase if you update to a paid plan."
+msgstr ""
+
+msgid "SubscriptionTable|Trial"
+msgstr ""
+
+msgid "SubscriptionTable|Trial end date"
+msgstr ""
+
+msgid "SubscriptionTable|Trial start date"
+msgstr ""
+
+msgid "SubscriptionTable|Upgrade"
+msgstr ""
+
+msgid "SubscriptionTable|Usage"
+msgstr ""
+
+msgid "SubscriptionTable|Usage count is performed once a day at 12:00 PM."
+msgstr ""
+
+msgid "Subscriptions"
+msgstr ""
+
+msgid "Subtracted"
+msgstr ""
+
+msgid "Subtracts"
+msgstr ""
+
+msgid "Succeeded"
+msgstr ""
+
+msgid "Successfully activated"
+msgstr ""
+
+msgid "Successfully blocked"
+msgstr ""
+
+msgid "Successfully confirmed"
+msgstr ""
+
+msgid "Successfully deactivated"
+msgstr ""
+
+msgid "Successfully deleted U2F device."
+msgstr ""
+
+msgid "Successfully removed email."
+msgstr ""
+
+msgid "Successfully scheduled a pipeline to run. Go to the %{pipelines_link_start}Pipelines page%{pipelines_link_end} for details."
+msgstr ""
+
+msgid "Successfully unblocked"
+msgstr ""
+
+msgid "Successfully unlocked"
+msgstr ""
+
+msgid "Successfully verified domain ownership"
+msgstr ""
+
+msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
+msgstr ""
+
+msgid "Suggested Solutions"
+msgstr ""
+
+msgid "Suggested change"
+msgstr ""
+
+msgid "Suggested solutions help link"
+msgstr ""
+
+msgid "SuggestedColors|Bright green"
+msgstr ""
+
+msgid "SuggestedColors|Dark grayish cyan"
+msgstr ""
+
+msgid "SuggestedColors|Dark moderate blue"
+msgstr ""
+
+msgid "SuggestedColors|Dark moderate orange"
+msgstr ""
+
+msgid "SuggestedColors|Dark moderate pink"
+msgstr ""
+
+msgid "SuggestedColors|Dark moderate violet"
+msgstr ""
+
+msgid "SuggestedColors|Feijoa"
+msgstr ""
+
+msgid "SuggestedColors|Lime green"
+msgstr ""
+
+msgid "SuggestedColors|Moderate blue"
+msgstr ""
+
+msgid "SuggestedColors|Pure red"
+msgstr ""
+
+msgid "SuggestedColors|Slightly desaturated blue"
+msgstr ""
+
+msgid "SuggestedColors|Slightly desaturated green"
+msgstr ""
+
+msgid "SuggestedColors|Soft orange"
+msgstr ""
+
+msgid "SuggestedColors|Soft red"
+msgstr ""
+
+msgid "SuggestedColors|Strong pink"
+msgstr ""
+
+msgid "SuggestedColors|Strong red"
+msgstr ""
+
+msgid "SuggestedColors|Strong yellow"
+msgstr ""
+
+msgid "SuggestedColors|UA blue"
+msgstr ""
+
+msgid "SuggestedColors|Very dark desaturated blue"
+msgstr ""
+
+msgid "SuggestedColors|Very dark lime green"
+msgstr ""
+
+msgid "SuggestedColors|Very pale orange"
+msgstr ""
+
+msgid "Suggestions:"
+msgstr ""
+
+msgid "Suite"
+msgstr ""
+
+msgid "Summary"
+msgstr ""
+
+msgid "Sunday"
+msgstr ""
+
+msgid "Support"
+msgstr ""
+
+msgid "Support for custom certificates is disabled. Ask your system's administrator to enable it."
+msgstr ""
+
+msgid "Support page URL"
+msgstr ""
+
+msgid "Survey Response"
+msgstr ""
+
+msgid "Switch branch/tag"
+msgstr ""
+
+msgid "Switch to GitLab Next"
+msgstr ""
+
+msgid "Switch to the source to copy the file contents"
+msgstr ""
+
+msgid "Sync information"
+msgstr ""
+
+msgid "Synced"
+msgstr ""
+
+msgid "Synchronization disabled"
+msgstr ""
+
+msgid "Synchronization of container repositories is disabled."
+msgstr ""
+
+msgid "System"
+msgstr ""
+
+msgid "System Hooks"
+msgstr ""
+
+msgid "System Info"
+msgstr ""
+
+msgid "System default (%{default})"
+msgstr ""
+
+msgid "System header and footer"
+msgstr ""
+
+msgid "System hook was successfully updated."
+msgstr ""
+
+msgid "System metrics (Custom)"
+msgstr ""
+
+msgid "System metrics (Kubernetes)"
+msgstr ""
+
+msgid "Table of Contents"
+msgstr ""
+
+msgid "Tag"
+msgstr ""
+
+msgid "Tag list:"
+msgstr ""
+
+msgid "Tag name"
+msgstr ""
+
+msgid "Tag this commit."
+msgstr ""
+
+msgid "Tagged this commit to %{tag_name} with \"%{message}\"."
+msgstr ""
+
+msgid "Tagged this commit to %{tag_name}."
+msgstr ""
+
+msgid "Tags"
+msgstr ""
+
+msgid "Tags feed"
+msgstr ""
+
+msgid "Tags this commit to %{tag_name} with \"%{message}\"."
+msgstr ""
+
+msgid "Tags this commit to %{tag_name}."
+msgstr ""
+
+msgid "Tags:"
+msgstr ""
+
+msgid "TagsPage|Browse commits"
+msgstr ""
+
+msgid "TagsPage|Browse files"
+msgstr ""
+
+msgid "TagsPage|Can't find HEAD commit for this tag"
+msgstr ""
+
+msgid "TagsPage|Cancel"
+msgstr ""
+
+msgid "TagsPage|Create tag"
+msgstr ""
+
+msgid "TagsPage|Delete tag"
+msgstr ""
+
+msgid "TagsPage|Deleting the %{tag_name} tag cannot be undone. Are you sure?"
+msgstr ""
+
+msgid "TagsPage|Edit release notes"
+msgstr ""
+
+msgid "TagsPage|Existing branch name, tag, or commit SHA"
+msgstr ""
+
+msgid "TagsPage|Filter by tag name"
+msgstr ""
+
+msgid "TagsPage|New Tag"
+msgstr ""
+
+msgid "TagsPage|New tag"
+msgstr ""
+
+msgid "TagsPage|Optionally, add a message to the tag. Leaving this blank creates a %{link_start}lightweight tag.%{link_end}"
+msgstr ""
+
+msgid "TagsPage|Optionally, create a public Release of your project, based on this tag. Release notes are displayed on the %{releases_page_link_start}Releases%{link_end} page. %{docs_link_start}More information%{link_end}"
+msgstr ""
+
+msgid "TagsPage|Release notes"
+msgstr ""
+
+msgid "TagsPage|Repository has no tags yet."
+msgstr ""
+
+msgid "TagsPage|Sort by"
+msgstr ""
+
+msgid "TagsPage|Tags"
+msgstr ""
+
+msgid "TagsPage|Tags give the ability to mark specific points in history as being important"
+msgstr ""
+
+msgid "TagsPage|This tag has no release notes."
+msgstr ""
+
+msgid "TagsPage|Use git tag command to add a new one:"
+msgstr ""
+
+msgid "TagsPage|Write your release notes or drag files here…"
+msgstr ""
+
+msgid "TagsPage|protected"
+msgstr ""
+
+msgid "Target Branch"
+msgstr ""
+
+msgid "Target Path"
+msgstr ""
+
+msgid "Target branch"
+msgstr ""
+
+msgid "Target-Branch"
+msgstr ""
+
+msgid "Team"
+msgstr ""
+
+msgid "Team domain"
+msgstr ""
+
+msgid "Telephone number"
+msgstr ""
+
+msgid "Telephone number (Optional)"
+msgstr ""
+
+msgid "Template"
+msgstr ""
+
+msgid "Template to append to all Service Desk issues"
+msgstr ""
+
+msgid "Template was successfully saved."
+msgstr ""
+
+msgid "Templates"
+msgstr ""
+
+msgid "Terminal"
+msgstr ""
+
+msgid "Terminal for environment"
+msgstr ""
+
+msgid "Terminal sync service is running"
+msgstr ""
+
+msgid "Terms of Service Agreement and Privacy Policy"
+msgstr ""
+
+msgid "Terms of Service and Privacy Policy"
+msgstr ""
+
+msgid "Test"
+msgstr ""
+
+msgid "Test coverage parsing"
+msgstr ""
+
+msgid "Test coverage: %d hit"
+msgid_plural "Test coverage: %d hits"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Test failed."
+msgstr ""
+
+msgid "Test settings and save changes"
+msgstr ""
+
+msgid "TestHooks|Ensure one of your projects has merge requests."
+msgstr ""
+
+msgid "TestHooks|Ensure the project has CI jobs."
+msgstr ""
+
+msgid "TestHooks|Ensure the project has CI pipelines."
+msgstr ""
+
+msgid "TestHooks|Ensure the project has at least one commit."
+msgstr ""
+
+msgid "TestHooks|Ensure the project has issues."
+msgstr ""
+
+msgid "TestHooks|Ensure the project has merge requests."
+msgstr ""
+
+msgid "TestHooks|Ensure the project has notes."
+msgstr ""
+
+msgid "TestHooks|Ensure the wiki is enabled and has pages."
+msgstr ""
+
+msgid "TestReports|%{count} errors"
+msgstr ""
+
+msgid "TestReports|%{count} failures"
+msgstr ""
+
+msgid "TestReports|%{count} jobs"
+msgstr ""
+
+msgid "TestReports|%{rate}%{sign} success rate"
+msgstr ""
+
+msgid "TestReports|Test suites"
+msgstr ""
+
+msgid "TestReports|Tests"
+msgstr ""
+
+msgid "TestReports|There are no test cases to display."
+msgstr ""
+
+msgid "TestReports|There are no test suites to show."
+msgstr ""
+
+msgid "TestReports|There are no tests to show."
+msgstr ""
+
+msgid "TestReports|There was an error fetching the test reports."
+msgstr ""
+
+msgid "Tests"
+msgstr ""
+
+msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
+msgstr ""
+
+msgid "Thank you for your feedback!"
+msgstr ""
+
+msgid "Thank you for your report. A GitLab administrator will look into it shortly."
+msgstr ""
+
+msgid "Thanks for your purchase!"
+msgstr ""
+
+msgid "Thanks! Don't show me this again"
+msgstr ""
+
+msgid "That's it, well done!%{celebrate}"
+msgstr ""
+
+msgid "The \"%{group_path}\" group allows you to sign in with your Single Sign-On Account"
+msgstr ""
+
+msgid "The \"Require approval from CODEOWNERS\" setting was moved to %{banner_link_start}Protected Branches%{banner_link_end}"
+msgstr ""
+
+msgid "The %{link_start}true-up model%{link_end} allows having more users, and additional users will incur a retroactive charge on renewal."
+msgstr ""
+
+msgid "The %{true_up_link_start}true-up model%{link_end} has a retroactive charge for these users at the next renewal. If you want to update your license sooner to prevent this, %{support_link_start}please contact our Support team%{link_end}."
+msgstr ""
+
+msgid "The %{type} contains the following error:"
+msgid_plural "The %{type} contains the following errors:"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "The Advanced Global 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 "The CSV export will be created in the background. Once finished, it will be sent to <strong>%{email}</strong> in an attachment."
+msgstr ""
+
+msgid "The Git LFS objects will <strong>not</strong> be synced."
+msgstr ""
+
+msgid "The Issue Tracker is the place to add things that need to be improved or solved in a project"
+msgstr ""
+
+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 ""
+
+msgid "The Prometheus server responded with \"bad request\". Please check your queries are correct and are supported in your Prometheus version. %{documentationLink}"
+msgstr ""
+
+msgid "The URL defined on the primary node that secondary nodes should use to contact it. Defaults to URL"
+msgstr ""
+
+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 ""
+
+msgid "The X509 Certificate to use when mutual TLS is required to communicate with the external authorization service. If left blank, the server certificate is still validated when accessing over HTTPS."
+msgstr ""
+
+msgid "The amount of seconds after which a request to get a secondary node status will time out."
+msgstr ""
+
+msgid "The application will be used where the client secret can be kept confidential. Native mobile apps and Single Page Apps are considered non-confidential."
+msgstr ""
+
+msgid "The associated issue #%{issueId} has been closed as the error is now resolved."
+msgstr ""
+
+msgid "The branch for this project has no active pipeline configuration."
+msgstr ""
+
+msgid "The branch or tag does not exist"
+msgstr ""
+
+msgid "The character highlighter helps you keep the subject line to %{titleLength} characters and wrap the body at %{bodyLength} so they are readable in git."
+msgstr ""
+
+msgid "The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request."
+msgstr ""
+
+msgid "The collection of events added to the data gathered for that stage."
+msgstr ""
+
+msgid "The commit does not exist"
+msgstr ""
+
+msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
+msgstr ""
+
+msgid "The content of this page is not encoded in UTF-8. Edits can only be made via the Git repository."
+msgstr ""
+
+msgid "The contents of this group, its subgroups and projects will be permanently removed after %{deletion_adjourned_period} days on %{date}. After this point, your data cannot be recovered."
+msgstr ""
+
+msgid "The current issue"
+msgstr ""
+
+msgid "The data source is connected, but there is no data to display. %{documentationLink}"
+msgstr ""
+
+msgid "The default CI configuration path for new projects."
+msgstr ""
+
+msgid "The dependency list details information about the components used within your project."
+msgstr ""
+
+msgid "The deployment of this job to %{environmentLink} did not succeed."
+msgstr ""
+
+msgid "The designs you tried uploading did not change."
+msgstr ""
+
+msgid "The directory has been successfully created."
+msgstr ""
+
+msgid "The domain you entered is misformatted."
+msgstr ""
+
+msgid "The domain you entered is not allowed."
+msgstr ""
+
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
+msgid "The entered user map is not a valid JSON user map."
+msgstr ""
+
+msgid "The errors we encountered were:"
+msgstr ""
+
+msgid "The file has been successfully created."
+msgstr ""
+
+msgid "The file has been successfully deleted."
+msgstr ""
+
+msgid "The file name should have a .yml extension"
+msgstr ""
+
+msgid "The following items will NOT be exported:"
+msgstr ""
+
+msgid "The following items will be exported:"
+msgstr ""
+
+msgid "The following personal access token: %{token_names} was revoked, because a new policy to expire personal access tokens were set."
+msgid_plural "The following personal access tokens: %{token_names} were revoked, because a new policy to expire personal access tokens were set."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "The fork relationship has been removed."
+msgstr ""
+
+msgid "The global settings require you to enable Two-Factor Authentication for your account."
+msgstr ""
+
+msgid "The group and any internal projects can be viewed by any logged in user."
+msgstr ""
+
+msgid "The group and any public projects can be viewed without any authentication."
+msgstr ""
+
+msgid "The group and its projects can only be viewed by members."
+msgstr ""
+
+msgid "The group can be fully restored"
+msgstr ""
+
+msgid "The group export can be downloaded from:"
+msgstr ""
+
+msgid "The group has already been shared with this group"
+msgstr ""
+
+msgid "The group settings for %{group_links} require you to enable Two-Factor Authentication for your account. You can %{leave_group_links}."
+msgstr ""
+
+msgid "The group will be placed in 'pending removal' state"
+msgstr ""
+
+msgid "The import will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
+msgstr ""
+
+msgid "The invitation could not be accepted."
+msgstr ""
+
+msgid "The invitation could not be declined."
+msgstr ""
+
+msgid "The invitation has already been accepted."
+msgstr ""
+
+msgid "The invitation was successfully resent."
+msgstr ""
+
+msgid "The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage."
+msgstr ""
+
+msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
+msgstr ""
+
+msgid "The license was removed. GitLab has fallen back on the previous license."
+msgstr ""
+
+msgid "The license was removed. GitLab now no longer has a valid license."
+msgstr ""
+
+msgid "The license was successfully uploaded and is now active. You can see the details below."
+msgstr ""
+
+msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
+msgstr ""
+
+msgid "The maximum file size allowed is %{size}."
+msgstr ""
+
+msgid "The maximum file size allowed is 200KB."
+msgstr ""
+
+msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally."
+msgstr ""
+
+msgid "The merge conflicts for this merge request have already been resolved."
+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 name \"%{name}\" is already taken in this directory."
+msgstr ""
+
+msgid "The number of changes to be fetched from GitLab when cloning a repository. This can speed up Pipelines execution. Keep empty or set to 0 to disable shallow clone by default and make GitLab CI fetch all branches and tags each time."
+msgstr ""
+
+msgid "The number of times an upload record could not find its file"
+msgstr ""
+
+msgid "The one place for your designs"
+msgstr ""
+
+msgid "The passphrase required to decrypt the private key. This is optional and the value is encrypted at rest."
+msgstr ""
+
+msgid "The path to the CI configuration file. Defaults to <code>.gitlab-ci.yml</code>"
+msgstr ""
+
+msgid "The phase of the development lifecycle."
+msgstr ""
+
+msgid "The pipeline has been deleted"
+msgstr ""
+
+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 ""
+
+msgid "The planning stage shows the time from the previous step to pushing your first commit. This time will be added automatically once you push your first commit."
+msgstr ""
+
+msgid "The private key to use when a client certificate is provided. This value is encrypted at rest."
+msgstr ""
+
+msgid "The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle."
+msgstr ""
+
+msgid "The project can be accessed by any logged in user."
+msgstr ""
+
+msgid "The project can be accessed by any user who is logged in."
+msgstr ""
+
+msgid "The project can be accessed by anyone, regardless of authentication."
+msgstr ""
+
+msgid "The project can be accessed without any authentication."
+msgstr ""
+
+msgid "The project is accessible only by members of the project. Access must be granted explicitly to each user."
+msgstr ""
+
+msgid "The project is still being deleted. Please try again later."
+msgstr ""
+
+msgid "The project was successfully forked."
+msgstr ""
+
+msgid "The project was successfully imported."
+msgstr ""
+
+msgid "The pseudonymizer data collection is disabled. When enabled, 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 "The remote mirror took to long to complete."
+msgstr ""
+
+msgid "The remote repository is being updated..."
+msgstr ""
+
+msgid "The repository can be commited to, and issues, comments and other entities can be created."
+msgstr ""
+
+msgid "The repository for this project does not exist."
+msgstr ""
+
+msgid "The repository for this project is empty"
+msgstr ""
+
+msgid "The repository is being updated..."
+msgstr ""
+
+msgid "The repository must be accessible over <code>http://</code>, <code>https://</code> or <code>git://</code>."
+msgstr ""
+
+msgid "The repository must be accessible over <code>http://</code>, <code>https://</code>, <code>ssh://</code> or <code>git://</code>."
+msgstr ""
+
+msgid "The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request."
+msgstr ""
+
+msgid "The roadmap shows the progress of your epics along a timeline"
+msgstr ""
+
+msgid "The schedule time must be in the future!"
+msgstr ""
+
+msgid "The snippet can be accessed without any authentication."
+msgstr ""
+
+msgid "The snippet is visible only to me."
+msgstr ""
+
+msgid "The snippet is visible only to project members."
+msgstr ""
+
+msgid "The snippet is visible to any logged in user."
+msgstr ""
+
+msgid "The specified tab is invalid, please select another"
+msgstr ""
+
+msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
+msgstr ""
+
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
+msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
+msgstr ""
+
+msgid "The time taken by each data entry gathered by that stage."
+msgstr ""
+
+msgid "The total stage shows the time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle."
+msgstr ""
+
+msgid "The unique identifier for the Geo node. Must match %{geoNodeName} if it is set in gitlab.rb, otherwise it must match %{externalUrl} with a trailing slash"
+msgstr ""
+
+msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
+msgstr ""
+
+msgid "The uploaded file is not a valid Google Takeout archive."
+msgstr ""
+
+msgid "The usage ping is disabled, and cannot be configured through this form."
+msgstr ""
+
+msgid "The user is being deleted."
+msgstr ""
+
+msgid "The user map has been saved. Continue by selecting the projects you want to import."
+msgstr ""
+
+msgid "The user map is a JSON document mapping the Google Code users that participated on your projects to the way their email addresses and usernames will be imported into GitLab. You can change this by changing the value on the right hand side of <code>:</code>. Be sure to preserve the surrounding double quotes, other punctuation and the email address or username on the left hand side."
+msgstr ""
+
+msgid "The user map is a mapping of the FogBugz users that participated on your projects to the way their email address and usernames will be imported into GitLab. You can change this by populating the table below."
+msgstr ""
+
+msgid "The user you are trying to deactivate has been active in the past %{minimum_inactive_days} days and cannot be deactivated"
+msgstr ""
+
+msgid "The user-facing URL of the Geo node"
+msgstr ""
+
+msgid "The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6."
+msgstr ""
+
+msgid "The vulnerability is no longer detected. Verify the vulnerability has been fixed or removed before changing its status."
+msgstr ""
+
+msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
+msgstr ""
+
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
+msgid "There are no GPG keys associated with this account."
+msgstr ""
+
+msgid "There are no GPG keys with access to your account."
+msgstr ""
+
+msgid "There are no SSH keys associated with this account."
+msgstr ""
+
+msgid "There are no SSH keys with access to your account."
+msgstr ""
+
+msgid "There are no archived projects yet"
+msgstr ""
+
+msgid "There are no archived requirements"
+msgstr ""
+
+msgid "There are no changes"
+msgstr ""
+
+msgid "There are no charts configured for this page"
+msgstr ""
+
+msgid "There are no closed issues"
+msgstr ""
+
+msgid "There are no closed merge requests"
+msgstr ""
+
+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 ""
+
+msgid "There are no issues to show."
+msgstr ""
+
+msgid "There are no labels yet"
+msgstr ""
+
+msgid "There are no matching files"
+msgstr ""
+
+msgid "There are no open issues"
+msgstr ""
+
+msgid "There are no open merge requests"
+msgstr ""
+
+msgid "There are no open requirements"
+msgstr ""
+
+msgid "There are no packages yet"
+msgstr ""
+
+msgid "There are no projects shared with this group yet"
+msgstr ""
+
+msgid "There are no variables yet."
+msgstr ""
+
+msgid "There is a limit of %{ci_project_subscriptions_limit} subscriptions from or to a project."
+msgstr ""
+
+msgid "There is already a repository with that name on disk"
+msgstr ""
+
+msgid "There is no data available. Please change your selection."
+msgstr ""
+
+msgid "There was a problem communicating with your device."
+msgstr ""
+
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
+msgid "There was a problem refreshing the data, please try again"
+msgstr ""
+
+msgid "There was a problem saving your custom stage, please try again"
+msgstr ""
+
+msgid "There was a problem sending the confirmation email"
+msgstr ""
+
+msgid "There was an error %{message} todo."
+msgstr ""
+
+msgid "There was an error adding a To Do."
+msgstr ""
+
+msgid "There was an error creating the dashboard, branch name is invalid."
+msgstr ""
+
+msgid "There was an error creating the dashboard, branch named: %{branch} already exists."
+msgstr ""
+
+msgid "There was an error creating the issue"
+msgstr ""
+
+msgid "There was an error deleting the To Do."
+msgstr ""
+
+msgid "There was an error fetching configuration for charts"
+msgstr ""
+
+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 ""
+
+msgid "There was an error fetching label data for the selected group"
+msgstr ""
+
+msgid "There was an error fetching median data for stages"
+msgstr ""
+
+msgid "There was an error fetching the %{replicableType}"
+msgstr ""
+
+msgid "There was an error fetching the Node's Groups"
+msgstr ""
+
+msgid "There was an error fetching the environments information."
+msgstr ""
+
+msgid "There was an error fetching the top labels for the selected group"
+msgstr ""
+
+msgid "There was an error fetching the variables."
+msgstr ""
+
+msgid "There was an error fetching value stream analytics stages."
+msgstr ""
+
+msgid "There was an error gathering the chart data"
+msgstr ""
+
+msgid "There was an error getting the epic participants."
+msgstr ""
+
+msgid "There was an error importing the Jira project."
+msgstr ""
+
+msgid "There was an error loading users activity calendar."
+msgstr ""
+
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
+msgid "There was an error removing the e-mail."
+msgstr ""
+
+msgid "There was an error removing your custom stage, please try again"
+msgstr ""
+
+msgid "There was an error resetting group pipeline minutes."
+msgstr ""
+
+msgid "There was an error resetting user pipeline minutes."
+msgstr ""
+
+msgid "There was an error saving this Geo Node."
+msgstr ""
+
+msgid "There was an error saving your changes."
+msgstr ""
+
+msgid "There was an error saving your notification settings."
+msgstr ""
+
+msgid "There was an error subscribing to this label."
+msgstr ""
+
+msgid "There was an error syncing project %{name}"
+msgstr ""
+
+msgid "There was an error syncing the %{replicableType}"
+msgstr ""
+
+msgid "There was an error trying to validate your query"
+msgstr ""
+
+msgid "There was an error updating the dashboard, branch name is invalid."
+msgstr ""
+
+msgid "There was an error updating the dashboard, branch named: %{branch} already exists."
+msgstr ""
+
+msgid "There was an error updating the stage order. Please try reloading the page."
+msgstr ""
+
+msgid "There was an error when reseting email token."
+msgstr ""
+
+msgid "There was an error when subscribing to this label."
+msgstr ""
+
+msgid "There was an error when unsubscribing from this label."
+msgstr ""
+
+msgid "There was an error while fetching value stream analytics data."
+msgstr ""
+
+msgid "There was an error while fetching value stream analytics duration data."
+msgstr ""
+
+msgid "There was an error while fetching value stream analytics duration median data."
+msgstr ""
+
+msgid "There was an error while fetching value stream analytics recent activity data."
+msgstr ""
+
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
+msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
+msgstr ""
+
+msgid "These existing issues have a similar title. It might be better to comment there instead of creating another similar issue."
+msgstr ""
+
+msgid "These variables are configured in the parent group settings, and will be active in the current project in addition to the project variables."
+msgstr ""
+
+msgid "They can be managed using the %{link}."
+msgstr ""
+
+msgid "Third Party Advisory Link"
+msgstr ""
+
+msgid "Third party offers"
+msgstr ""
+
+msgid "This %{issuableDisplayName} is locked. Only project members can comment."
+msgstr ""
+
+msgid "This %{issuable} is locked. Only <strong>project members</strong> can comment."
+msgstr ""
+
+msgid "This %{viewer} could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
+msgid "This GitLab instance does not provide any shared Runners yet. Instance administrators can register shared Runners in the admin area."
+msgstr ""
+
+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 ""
+
+msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
+msgstr ""
+
+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 ""
+
+msgid "This also resolves the discussion"
+msgstr ""
+
+msgid "This application was created by %{link_to_owner}."
+msgstr ""
+
+msgid "This application will be able to:"
+msgstr ""
+
+msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of 15MB. %{written_count} of %{issues_count} issues have been included. Consider re-exporting with a narrower selection of issues."
+msgstr ""
+
+msgid "This block is self-referential"
+msgstr ""
+
+msgid "This board's scope is reduced"
+msgstr ""
+
+msgid "This branch has changed since you started editing. Would you like to create a new branch?"
+msgstr ""
+
+msgid "This chart could not be displayed"
+msgstr ""
+
+msgid "This comment has changed since you started editing, please review the %{startTag}updated comment%{endTag} to ensure information is not lost."
+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 ""
+
+msgid "This commit was signed with a <strong>verified</strong> signature and the committer email is verified to belong to the same user."
+msgstr ""
+
+msgid "This commit was signed with a different user's verified signature."
+msgstr ""
+
+msgid "This commit was signed with a verified signature, but the committer email is <strong>not verified</strong> to belong to the same user."
+msgstr ""
+
+msgid "This commit was signed with an <strong>unverified</strong> signature."
+msgstr ""
+
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
+msgid "This date is after the due date, so this epic won't appear in the roadmap."
+msgstr ""
+
+msgid "This date is before the start date, so this epic won't appear in the roadmap."
+msgstr ""
+
+msgid "This device has already been registered with us."
+msgstr ""
+
+msgid "This device has not been registered with us."
+msgstr ""
+
+msgid "This diff is collapsed."
+msgstr ""
+
+msgid "This diff was suppressed by a .gitattributes entry."
+msgstr ""
+
+msgid "This directory"
+msgstr ""
+
+msgid "This domain is not verified. You will need to verify ownership before access is enabled."
+msgstr ""
+
+msgid "This endpoint has been requested too many times. Try again later."
+msgstr ""
+
+msgid "This environment has no deployments yet."
+msgstr ""
+
+msgid "This environment is being deployed"
+msgstr ""
+
+msgid "This environment is being re-deployed"
+msgstr ""
+
+msgid "This epic already has the maximum number of child epics."
+msgstr ""
+
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
+msgid "This epic does not exist or you don't have sufficient permission."
+msgstr ""
+
+msgid "This feature requires local storage to be enabled"
+msgstr ""
+
+msgid "This field is required."
+msgstr ""
+
+msgid "This group"
+msgstr ""
+
+msgid "This group cannot be invited to a project inside a group with enforced SSO"
+msgstr ""
+
+msgid "This group does not provide any group Runners yet."
+msgstr ""
+
+msgid "This group has been scheduled for permanent removal on %{date}"
+msgstr ""
+
+msgid "This group, including all subgroups, projects and git repositories, will only be reachable from the specified IP address range. Multiple addresses are supported with comma delimiters.<br>Example: <code>192.168.0.0/24,192.168.1.0/24</code>. %{read_more_link}."
+msgstr ""
+
+msgid "This group, its subgroups and projects has been scheduled for removal on %{date}."
+msgstr ""
+
+msgid "This group, its subgroups and projects will be removed on %{date} since its parent group '%{parent_group_name}'' has been scheduled for removal."
+msgstr ""
+
+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 Work in Progress"
+msgstr ""
+
+msgid "This is a confidential issue."
+msgstr ""
+
+msgid "This is a delayed job to run in %{remainingTime}"
+msgstr ""
+
+msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
+msgstr ""
+
+msgid "This is a security log of important events involving your account."
+msgstr ""
+
+msgid "This is the author's first Merge Request to this project."
+msgstr ""
+
+msgid "This is the highest peak of users on your installation since the license started."
+msgstr ""
+
+msgid "This is the maximum number of users that have existed at the same time since the license started. This is the minimum number of seats you will need to buy when you renew your license."
+msgstr ""
+
+msgid "This is the number of currently active users on your installation, and this is the minimum number you need to purchase when you renew your license."
+msgstr ""
+
+msgid "This is your current session"
+msgstr ""
+
+msgid "This issue is %{confidentialLinkStart}confidential%{linkEnd} and %{lockedLinkStart}locked%{linkEnd}."
+msgstr ""
+
+msgid "This issue is confidential"
+msgstr ""
+
+msgid "This issue is currently blocked by the following issues: %{issues}."
+msgstr ""
+
+msgid "This issue is in a child epic of the filtered epic"
+msgstr ""
+
+msgid "This issue is locked."
+msgstr ""
+
+msgid "This job depends on other jobs with expired/erased artifacts: %{invalid_dependencies}"
+msgstr ""
+
+msgid "This job depends on upstream jobs that need to succeed in order for this job to be triggered"
+msgstr ""
+
+msgid "This job does not have a trace."
+msgstr ""
+
+msgid "This job has been canceled"
+msgstr ""
+
+msgid "This job has been skipped"
+msgstr ""
+
+msgid "This job has not been triggered yet"
+msgstr ""
+
+msgid "This job has not started yet"
+msgstr ""
+
+msgid "This job is an out-of-date deployment to %{environmentLink} using cluster %{clusterNameOrLink} and namespace %{kubernetesNamespace}."
+msgstr ""
+
+msgid "This job is an out-of-date deployment to %{environmentLink} using cluster %{clusterNameOrLink} and namespace %{kubernetesNamespace}. View the %{deploymentLink}."
+msgstr ""
+
+msgid "This job is an out-of-date deployment to %{environmentLink} using cluster %{clusterNameOrLink}."
+msgstr ""
+
+msgid "This job is an out-of-date deployment to %{environmentLink} using cluster %{clusterNameOrLink}. View the %{deploymentLink}."
+msgstr ""
+
+msgid "This job is an out-of-date deployment to %{environmentLink}."
+msgstr ""
+
+msgid "This job is an out-of-date deployment to %{environmentLink}. View the %{deploymentLink}."
+msgstr ""
+
+msgid "This job is archived. Only the complete pipeline can be retried."
+msgstr ""
+
+msgid "This job is creating a deployment to %{environmentLink} using cluster %{clusterNameOrLink} and namespace %{kubernetesNamespace}."
+msgstr ""
+
+msgid "This job is creating a deployment to %{environmentLink} using cluster %{clusterNameOrLink} and namespace %{kubernetesNamespace}. This will overwrite the %{deploymentLink}."
+msgstr ""
+
+msgid "This job is creating a deployment to %{environmentLink} using cluster %{clusterNameOrLink}."
+msgstr ""
+
+msgid "This job is creating a deployment to %{environmentLink} using cluster %{clusterNameOrLink}. This will overwrite the %{deploymentLink}."
+msgstr ""
+
+msgid "This job is creating a deployment to %{environmentLink}."
+msgstr ""
+
+msgid "This job is creating a deployment to %{environmentLink}. This will overwrite the %{deploymentLink}."
+msgstr ""
+
+msgid "This job is deployed to %{environmentLink} using cluster %{clusterNameOrLink} and namespace %{kubernetesNamespace}."
+msgstr ""
+
+msgid "This job is deployed to %{environmentLink} using cluster %{clusterNameOrLink}."
+msgstr ""
+
+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 ""
+
+msgid "This job is performing tasks that must complete before it can start"
+msgstr ""
+
+msgid "This job is preparing to start"
+msgstr ""
+
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
+msgstr ""
+
+msgid "This job is stuck because you don't have any active runners that can run this job."
+msgstr ""
+
+msgid "This job is waiting for resource: "
+msgstr ""
+
+msgid "This job requires a manual action"
+msgstr ""
+
+msgid "This job requires manual intervention to start. Before starting this job, you can add variables below for last-minute configuration changes."
+msgstr ""
+
+msgid "This job will automatically run after its timer finishes. Often they are used for incremental roll-out deploys to production environments. When unscheduled it converts into a manual action."
+msgstr ""
+
+msgid "This license has already expired."
+msgstr ""
+
+msgid "This may expose confidential information as the selected fork is in another namespace that can have other members."
+msgstr ""
+
+msgid "This means you can not push code until you create an empty repository or import existing one."
+msgstr ""
+
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
+msgid "This merge request is locked."
+msgstr ""
+
+msgid "This namespace has already been taken! Please choose another one."
+msgstr ""
+
+msgid "This only applies to repository indexing operations."
+msgstr ""
+
+msgid "This option is only available on GitLab.com"
+msgstr ""
+
+msgid "This page is unavailable because you are not allowed to read information across multiple projects."
+msgstr ""
+
+msgid "This page will be removed in a future release."
+msgstr ""
+
+msgid "This pipeline makes use of a predefined CI/CD configuration enabled by %{strongStart}Auto DevOps.%{strongEnd}"
+msgstr ""
+
+msgid "This pipeline makes use of a predefined CI/CD configuration enabled by <b>Auto DevOps.</b>"
+msgstr ""
+
+msgid "This pipeline triggered a child pipeline"
+msgstr ""
+
+msgid "This pipeline was triggered by a parent pipeline"
+msgstr ""
+
+msgid "This project"
+msgstr ""
+
+msgid "This project does not belong to a group and can therefore not make use of group Runners."
+msgstr ""
+
+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 ""
+
+msgid "This project does not have a wiki homepage yet"
+msgstr ""
+
+msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
+msgstr ""
+
+msgid "This project has no active access tokens."
+msgstr ""
+
+msgid "This project is archived and cannot be commented on."
+msgstr ""
+
+msgid "This project path either does not exist or you do not have access."
+msgstr ""
+
+msgid "This project will be removed on %{date}"
+msgstr ""
+
+msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
+msgstr ""
+
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
+msgid "This repository"
+msgstr ""
+
+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 ""
+
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
+msgid "This runner will only run on pipelines triggered on protected branches"
+msgstr ""
+
+msgid "This setting can be overridden in each project."
+msgstr ""
+
+msgid "This setting will update the hostname that is used to generate private commit emails. %{learn_more}"
+msgstr ""
+
+msgid "This subscription is for"
+msgstr ""
+
+msgid "This timeout will take precedence when lower than project-defined timeout and accepts a human readable time input language like \"1 hour\". Values without specification represent seconds."
+msgstr ""
+
+msgid "This user cannot be unlocked manually from GitLab"
+msgstr ""
+
+msgid "This user has no active %{type}."
+msgstr ""
+
+msgid "This user has no identities"
+msgstr ""
+
+msgid "This 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 ""
+
+msgid "This variable can not be masked."
+msgstr ""
+
+msgid "This variable does not match the expected pattern."
+msgstr ""
+
+msgid "This will help us personalize your onboarding experience."
+msgstr ""
+
+msgid "This will redirect you to an external sign in page."
+msgstr ""
+
+msgid "This will remove the fork relationship between this project and %{fork_source}."
+msgstr ""
+
+msgid "This will remove the fork relationship between this project and other projects in the fork network."
+msgstr ""
+
+msgid "Those emails automatically become issues (with the comments becoming the email conversation) listed here."
+msgstr ""
+
+msgid "Thread to reply to cannot be found"
+msgstr ""
+
+msgid "Threat Monitoring"
+msgstr ""
+
+msgid "ThreatMonitoring|Anomalous Requests"
+msgstr ""
+
+msgid "ThreatMonitoring|Application firewall not detected"
+msgstr ""
+
+msgid "ThreatMonitoring|Container Network Policies are not installed or have been disabled. To view this data, ensure your Network Policies are installed and enabled for your cluster."
+msgstr ""
+
+msgid "ThreatMonitoring|Container Network Policy"
+msgstr ""
+
+msgid "ThreatMonitoring|Container NetworkPolicies not detected"
+msgstr ""
+
+msgid "ThreatMonitoring|Dropped Packets"
+msgstr ""
+
+msgid "ThreatMonitoring|Environment"
+msgstr ""
+
+msgid "ThreatMonitoring|No environments detected"
+msgstr ""
+
+msgid "ThreatMonitoring|Operations Per Second"
+msgstr ""
+
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
+msgid "ThreatMonitoring|Packet Activity"
+msgstr ""
+
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
+msgid "ThreatMonitoring|Requests"
+msgstr ""
+
+msgid "ThreatMonitoring|Show last"
+msgstr ""
+
+msgid "ThreatMonitoring|Something went wrong, unable to fetch environments"
+msgstr ""
+
+msgid "ThreatMonitoring|Something went wrong, unable to fetch statistics"
+msgstr ""
+
+msgid "ThreatMonitoring|The firewall is not installed or has been disabled. To view this data, ensure the web application firewall is installed and enabled for your cluster."
+msgstr ""
+
+msgid "ThreatMonitoring|The graph below is an overview of traffic coming to your application as tracked by the Web Application Firewall (WAF). View the docs for instructions on how to access the WAF logs to see what type of malicious traffic is trying to access your app. The docs link is also accessible by clicking the \"?\" icon next to the title below."
+msgstr ""
+
+msgid "ThreatMonitoring|Threat Monitoring"
+msgstr ""
+
+msgid "ThreatMonitoring|Threat Monitoring help page link"
+msgstr ""
+
+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."
+msgstr ""
+
+msgid "ThreatMonitoring|Total Packets"
+msgstr ""
+
+msgid "ThreatMonitoring|Total Requests"
+msgstr ""
+
+msgid "ThreatMonitoring|View documentation"
+msgstr ""
+
+msgid "ThreatMonitoring|Web Application Firewall"
+msgstr ""
+
+msgid "ThreatMonitoring|While it's rare to have no traffic coming to your application, it can happen. In any event, we ask that you double check your settings to make sure you've set up the WAF correctly."
+msgstr ""
+
+msgid "Thursday"
+msgstr ""
+
+msgid "Time"
+msgstr ""
+
+msgid "Time based: Yes"
+msgstr ""
+
+msgid "Time before an issue gets scheduled"
+msgstr ""
+
+msgid "Time before an issue starts implementation"
+msgstr ""
+
+msgid "Time before enforced"
+msgstr ""
+
+msgid "Time between merge request creation and merge/close"
+msgstr ""
+
+msgid "Time estimate"
+msgstr ""
+
+msgid "Time from first comment to last commit"
+msgstr ""
+
+msgid "Time from first commit until first comment"
+msgstr ""
+
+msgid "Time from last commit to merge"
+msgstr ""
+
+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 ""
+
+msgid "Time of import: %{importTime}"
+msgstr ""
+
+msgid "Time remaining"
+msgstr ""
+
+msgid "Time spent"
+msgstr ""
+
+msgid "Time to merge"
+msgstr ""
+
+msgid "Time to subtract exceeds the total time spent"
+msgstr ""
+
+msgid "Time tracking"
+msgstr ""
+
+msgid "Time until first merge request"
+msgstr ""
+
+msgid "TimeTrackingEstimated|Est"
+msgstr ""
+
+msgid "TimeTracking|%{startTag}Spent: %{endTag}%{timeSpentHumanReadable}"
+msgstr ""
+
+msgid "TimeTracking|Estimated:"
+msgstr ""
+
+msgid "TimeTracking|Over by %{timeRemainingHumanReadable}"
+msgstr ""
+
+msgid "TimeTracking|Spent"
+msgstr ""
+
+msgid "TimeTracking|Time remaining: %{timeRemainingHumanReadable}"
+msgstr ""
+
+msgid "Timeago|%s days ago"
+msgstr ""
+
+msgid "Timeago|%s days remaining"
+msgstr ""
+
+msgid "Timeago|%s hours ago"
+msgstr ""
+
+msgid "Timeago|%s hours remaining"
+msgstr ""
+
+msgid "Timeago|%s minutes ago"
+msgstr ""
+
+msgid "Timeago|%s minutes remaining"
+msgstr ""
+
+msgid "Timeago|%s months ago"
+msgstr ""
+
+msgid "Timeago|%s months remaining"
+msgstr ""
+
+msgid "Timeago|%s seconds remaining"
+msgstr ""
+
+msgid "Timeago|%s weeks ago"
+msgstr ""
+
+msgid "Timeago|%s weeks remaining"
+msgstr ""
+
+msgid "Timeago|%s years ago"
+msgstr ""
+
+msgid "Timeago|%s years remaining"
+msgstr ""
+
+msgid "Timeago|1 day ago"
+msgstr ""
+
+msgid "Timeago|1 day remaining"
+msgstr ""
+
+msgid "Timeago|1 hour ago"
+msgstr ""
+
+msgid "Timeago|1 hour remaining"
+msgstr ""
+
+msgid "Timeago|1 minute ago"
+msgstr ""
+
+msgid "Timeago|1 minute remaining"
+msgstr ""
+
+msgid "Timeago|1 month ago"
+msgstr ""
+
+msgid "Timeago|1 month remaining"
+msgstr ""
+
+msgid "Timeago|1 week ago"
+msgstr ""
+
+msgid "Timeago|1 week remaining"
+msgstr ""
+
+msgid "Timeago|1 year ago"
+msgstr ""
+
+msgid "Timeago|1 year remaining"
+msgstr ""
+
+msgid "Timeago|Past due"
+msgstr ""
+
+msgid "Timeago|in %s days"
+msgstr ""
+
+msgid "Timeago|in %s hours"
+msgstr ""
+
+msgid "Timeago|in %s minutes"
+msgstr ""
+
+msgid "Timeago|in %s months"
+msgstr ""
+
+msgid "Timeago|in %s seconds"
+msgstr ""
+
+msgid "Timeago|in %s weeks"
+msgstr ""
+
+msgid "Timeago|in %s years"
+msgstr ""
+
+msgid "Timeago|in 1 day"
+msgstr ""
+
+msgid "Timeago|in 1 hour"
+msgstr ""
+
+msgid "Timeago|in 1 minute"
+msgstr ""
+
+msgid "Timeago|in 1 month"
+msgstr ""
+
+msgid "Timeago|in 1 week"
+msgstr ""
+
+msgid "Timeago|in 1 year"
+msgstr ""
+
+msgid "Timeago|just now"
+msgstr ""
+
+msgid "Timeago|right now"
+msgstr ""
+
+msgid "Timeout"
+msgstr ""
+
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
+msgid "Time|hr"
+msgid_plural "Time|hrs"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Time|min"
+msgid_plural "Time|mins"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Time|s"
+msgstr ""
+
+msgid "Tip:"
+msgstr ""
+
+msgid "Title"
+msgstr ""
+
+msgid "Title:"
+msgstr ""
+
+msgid "Titles and Descriptions"
+msgstr ""
+
+msgid "To"
+msgstr ""
+
+msgid "To %{link_to_help} of your domain, add the above key to a TXT record within to your DNS configuration."
+msgstr ""
+
+msgid "To Do"
+msgstr ""
+
+msgid "To GitLab"
+msgstr ""
+
+msgid "To access this domain create a new DNS record"
+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 ""
+
+msgid "To add the entry manually, provide the following details to the application on your phone."
+msgstr ""
+
+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>repo</code> scope, so we can display a list of your public and private repositories which are available to connect."
+msgstr ""
+
+msgid "To connect GitHub repositories, you first need to authorize GitLab to access the list of your GitHub repositories."
+msgstr ""
+
+msgid "To connect GitHub repositories, you first need to authorize GitLab to access the list of your GitHub repositories:"
+msgstr ""
+
+msgid "To connect an SVN repository, check out %{svn_link}."
+msgstr ""
+
+msgid "To define internal users, first enable new users set to external"
+msgstr ""
+
+msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
+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 ""
+
+msgid "To get started, link this page to your Jaeger server, or find out how to %{link_start_tag}install Jaeger%{link_end_tag}"
+msgstr ""
+
+msgid "To get started, please enter your Gitea Host URL and a %{link_to_personal_token}."
+msgstr ""
+
+msgid "To help improve GitLab and its user experience, GitLab will periodically collect usage information."
+msgstr ""
+
+msgid "To help improve GitLab, we would like to periodically collect usage information. This can be changed at any time in %{settings_link_start}Settings%{link_end}. %{info_link_start}More Information%{link_end}"
+msgstr ""
+
+msgid "To import an SVN repository, check out %{svn_link}."
+msgstr ""
+
+msgid "To keep this project going, create a new issue"
+msgstr ""
+
+msgid "To keep this project going, create a new merge request"
+msgstr ""
+
+msgid "To link Sentry to GitLab, enter your Sentry URL and Auth Token."
+msgstr ""
+
+msgid "To move or copy an entire GitLab project from another GitLab installation to this one, navigate to the original project's settings page, generate an export file, and upload it here."
+msgstr ""
+
+msgid "To only use CI/CD features for an external repository, choose <strong>CI/CD for external repo</strong>."
+msgstr ""
+
+msgid "To open Jaeger and easily view tracing from GitLab, link the %{link} page to your server"
+msgstr ""
+
+msgid "To preserve performance only <strong>%{display_size} of %{real_size}</strong> files are displayed."
+msgstr ""
+
+msgid "To protect this issue's confidentiality, %{forkLink} and set the fork's visibility to private."
+msgstr ""
+
+msgid "To protect this issue's confidentiality, a private fork of this project was selected."
+msgstr ""
+
+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 ""
+
+msgid "To see all the user's personal access tokens you must impersonate them first."
+msgstr ""
+
+msgid "To see this project's operational details, %{linkStart}upgrade its group plan to Silver%{linkEnd}. You can also remove the project from the dashboard."
+msgstr ""
+
+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 ""
+
+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:"
+msgstr ""
+
+msgid "To simplify the billing process, GitLab will collect user counts in order to prorate charges for user growth throughout the year using a quarterly reconciliation process."
+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."
+msgstr ""
+
+msgid "To start serving your jobs you can add Runners to your group"
+msgstr ""
+
+msgid "To start serving your jobs you can either add specific Runners to your project or use shared Runners"
+msgstr ""
+
+msgid "To this GitLab instance"
+msgstr ""
+
+msgid "To view the roadmap, add a start or due date to one of your epics in this group or its subgroups. In the months view, only epics in the past month, current month, and next 5 months are shown."
+msgstr ""
+
+msgid "To widen your search, change or remove filters above"
+msgstr ""
+
+msgid "To widen your search, change or remove filters."
+msgstr ""
+
+msgid "To-Do List"
+msgstr ""
+
+msgid "To-do item successfully marked as done."
+msgstr ""
+
+msgid "Today"
+msgstr ""
+
+msgid "Toggle Markdown preview"
+msgstr ""
+
+msgid "Toggle Sidebar"
+msgstr ""
+
+msgid "Toggle all threads"
+msgstr ""
+
+msgid "Toggle backtrace"
+msgstr ""
+
+msgid "Toggle collapse"
+msgstr ""
+
+msgid "Toggle comments for this file"
+msgstr ""
+
+msgid "Toggle commit description"
+msgstr ""
+
+msgid "Toggle commit list"
+msgstr ""
+
+msgid "Toggle dropdown"
+msgstr ""
+
+msgid "Toggle emoji award"
+msgstr ""
+
+msgid "Toggle navigation"
+msgstr ""
+
+msgid "Toggle project"
+msgstr ""
+
+msgid "Toggle sidebar"
+msgstr ""
+
+msgid "Toggle the Performance Bar"
+msgstr ""
+
+msgid "Toggle this dialog"
+msgstr ""
+
+msgid "Toggle thread"
+msgstr ""
+
+msgid "ToggleButton|Toggle Status: OFF"
+msgstr ""
+
+msgid "ToggleButton|Toggle Status: ON"
+msgstr ""
+
+msgid "Toggled :%{name}: emoji award."
+msgstr ""
+
+msgid "Toggles :%{name}: emoji award."
+msgstr ""
+
+msgid "Tomorrow"
+msgstr ""
+
+msgid "Too many changes to show."
+msgstr ""
+
+msgid "Too many namespaces enabled. You will need to manage them via the console or the API."
+msgstr ""
+
+msgid "Too many projects enabled. You will need to manage them via the console or the API."
+msgstr ""
+
+msgid "Topics (optional)"
+msgstr ""
+
+msgid "Total"
+msgstr ""
+
+msgid "Total Contributions"
+msgstr ""
+
+msgid "Total artifacts size: %{total_size}"
+msgstr ""
+
+msgid "Total issues"
+msgstr ""
+
+msgid "Total test time for all commits/merges"
+msgstr ""
+
+msgid "Total weight"
+msgstr ""
+
+msgid "Total: %{total}"
+msgstr ""
+
+msgid "Trace"
+msgstr ""
+
+msgid "Tracing"
+msgstr ""
+
+msgid "Track groups of issues that share a theme, across projects and milestones"
+msgstr ""
+
+msgid "Track time with quick actions"
+msgstr ""
+
+msgid "Track your GitLab projects with GitLab for Slack."
+msgstr ""
+
+msgid "Track your project with Audit Events."
+msgstr ""
+
+msgid "Transfer ownership"
+msgstr ""
+
+msgid "Transfer project"
+msgstr ""
+
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
+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 ""
+
+msgid "TransferGroup|Database is not supported."
+msgstr ""
+
+msgid "TransferGroup|Group contains projects with NPM packages."
+msgstr ""
+
+msgid "TransferGroup|Group is already a root group."
+msgstr ""
+
+msgid "TransferGroup|Group is already associated to the parent group."
+msgstr ""
+
+msgid "TransferGroup|The parent group already has a subgroup with the same path."
+msgstr ""
+
+msgid "TransferGroup|Transfer failed: %{error_message}"
+msgstr ""
+
+msgid "TransferGroup|You don't have enough permissions."
+msgstr ""
+
+msgid "TransferProject|Cannot move project"
+msgstr ""
+
+msgid "TransferProject|Please select a new namespace for your project."
+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"
+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 "Tree view"
+msgstr ""
+
+msgid "Trending"
+msgstr ""
+
+msgid "Trials|Go back to GitLab"
+msgstr ""
+
+msgid "Trials|Skip Trial (Continue with Free Account)"
+msgstr ""
+
+msgid "Trials|You can always resume this process by selecting your avatar and choosing 'Start a Gold trial'"
+msgstr ""
+
+msgid "Trials|You won't get a free trial right now but you can always resume this process by clicking on your avatar and choosing 'Start a free trial'"
+msgstr ""
+
+msgid "Trigger"
+msgstr ""
+
+msgid "Trigger pipelines for mirror updates"
+msgstr ""
+
+msgid "Trigger pipelines when branches or tags are updated from the upstream repository. Depending on the activity of the upstream repository, this may greatly increase the load on your CI runners. Only enable this if you know they can handle the load."
+msgstr ""
+
+msgid "Trigger removed."
+msgstr ""
+
+msgid "Trigger this manual action"
+msgstr ""
+
+msgid "Trigger token:"
+msgstr ""
+
+msgid "Trigger variables:"
+msgstr ""
+
+msgid "Trigger was created successfully."
+msgstr ""
+
+msgid "Trigger was successfully updated."
+msgstr ""
+
+msgid "Triggerer"
+msgstr ""
+
+msgid "Triggers can force a specific branch or tag to get rebuilt with an API call. These tokens will impersonate their associated user including their access to projects and their project permissions."
+msgstr ""
+
+msgid "Troubleshoot and monitor your application with tracing"
+msgstr ""
+
+msgid "Try again"
+msgstr ""
+
+msgid "Try again?"
+msgstr ""
+
+msgid "Try all GitLab has to offer for 30 days."
+msgstr ""
+
+msgid "Try changing or removing filters."
+msgstr ""
+
+msgid "Try to fork again"
+msgstr ""
+
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
+msgid "Try using a different search term to find the file you are looking for."
+msgstr ""
+
+msgid "Trying to communicate with your device. Plug it in (if you haven't already) and press the button on the device now."
+msgstr ""
+
+msgid "Tuesday"
+msgstr ""
+
+msgid "Turn Off"
+msgstr ""
+
+msgid "Turn On"
+msgstr ""
+
+msgid "Turn on Service Desk"
+msgstr ""
+
+msgid "Twitter"
+msgstr ""
+
+msgid "Two-Factor Authentication"
+msgstr ""
+
+msgid "Two-Factor Authentication code"
+msgstr ""
+
+msgid "Two-factor Authentication"
+msgstr ""
+
+msgid "Two-factor Authentication Recovery codes"
+msgstr ""
+
+msgid "Two-factor Authentication has been disabled for this user"
+msgstr ""
+
+msgid "Two-factor authentication"
+msgstr ""
+
+msgid "Type"
+msgstr ""
+
+msgid "Type/State"
+msgstr ""
+
+msgid "U2F Devices (%{length})"
+msgstr ""
+
+msgid "U2F only works with HTTPS-enabled websites. Contact your administrator for more details."
+msgstr ""
+
+msgid "URL"
+msgstr ""
+
+msgid "URL is required"
+msgstr ""
+
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgstr ""
+
+msgid "URL of the external Spam Check endpoint"
+msgstr ""
+
+msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
+msgstr ""
+
+msgid "URL or request ID"
+msgstr ""
+
+msgid "UTC"
+msgstr ""
+
+msgid "Unable to apply suggestions to a deleted line."
+msgstr ""
+
+msgid "Unable to build Slack link."
+msgstr ""
+
+msgid "Unable to collect CPU info"
+msgstr ""
+
+msgid "Unable to collect memory info"
+msgstr ""
+
+msgid "Unable to connect to Elasticsearch"
+msgstr ""
+
+msgid "Unable to connect to Prometheus server"
+msgstr ""
+
+msgid "Unable to connect to server: %{error}"
+msgstr ""
+
+msgid "Unable to connect to the Jira instance. Please check your Jira integration configuration."
+msgstr ""
+
+msgid "Unable to convert Kubernetes logs encoding to UTF-8"
+msgstr ""
+
+msgid "Unable to fetch unscanned projects"
+msgstr ""
+
+msgid "Unable to fetch vulnerable projects"
+msgstr ""
+
+msgid "Unable to find Jira project to import data from."
+msgstr ""
+
+msgid "Unable to generate new instance ID"
+msgstr ""
+
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
+msgid "Unable to load the diff"
+msgstr ""
+
+msgid "Unable to load the diff. %{button_try_again}"
+msgstr ""
+
+msgid "Unable to load the merge request widget. Try reloading the page."
+msgstr ""
+
+msgid "Unable to process group import file"
+msgstr ""
+
+msgid "Unable to resolve"
+msgstr ""
+
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
+msgid "Unable to save your changes. Please try again."
+msgstr ""
+
+msgid "Unable to schedule a pipeline to run immediately"
+msgstr ""
+
+msgid "Unable to sign you in to the group with SAML due to \"%{reason}\""
+msgstr ""
+
+msgid "Unable to update label prioritization at this time"
+msgstr ""
+
+msgid "Unable to update this epic at this time."
+msgstr ""
+
+msgid "Unable to update this issue at this time."
+msgstr ""
+
+msgid "Unarchive project"
+msgstr ""
+
+msgid "Unarchiving the project will restore people's ability to make changes to it. The repository can be committed to, and issues, comments, and other entities can be created. %{strong_start}Once active, this project shows up in the search and on the dashboard.%{strong_end}"
+msgstr ""
+
+msgid "Unblock"
+msgstr ""
+
+msgid "Undo"
+msgstr ""
+
+msgid "Undo Ignore"
+msgstr ""
+
+msgid "Undo ignore"
+msgstr ""
+
+msgid "Unfortunately, your email message to GitLab could not be processed."
+msgstr ""
+
+msgid "Uninstall"
+msgstr ""
+
+msgid "Uninstalling"
+msgstr ""
+
+msgid "Units|ms"
+msgstr ""
+
+msgid "Units|s"
+msgstr ""
+
+msgid "Unknown"
+msgstr ""
+
+msgid "Unknown Error"
+msgstr ""
+
+msgid "Unknown cache key"
+msgstr ""
+
+msgid "Unknown encryption strategy: %{encrypted_strategy}!"
+msgstr ""
+
+msgid "Unknown format"
+msgstr ""
+
+msgid "Unknown response text"
+msgstr ""
+
+msgid "Unlimited"
+msgstr ""
+
+msgid "Unlock"
+msgstr ""
+
+msgid "Unlock the discussion"
+msgstr ""
+
+msgid "Unlock this %{issuableDisplayName}? <strong>Everyone</strong> will be able to comment."
+msgstr ""
+
+msgid "Unlocked"
+msgstr ""
+
+msgid "Unlocked the discussion."
+msgstr ""
+
+msgid "Unlocks the discussion."
+msgstr ""
+
+msgid "Unmarked this %{noun} as Work In Progress."
+msgstr ""
+
+msgid "Unmarks this %{noun} as Work In Progress."
+msgstr ""
+
+msgid "Unreachable"
+msgstr ""
+
+msgid "Unresolve"
+msgstr ""
+
+msgid "Unresolve thread"
+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 "UnscannedProjects|Default branch scanning by project"
+msgstr ""
+
+msgid "UnscannedProjects|Out of date"
+msgstr ""
+
+msgid "UnscannedProjects|Project scanning"
+msgstr ""
+
+msgid "UnscannedProjects|Untested"
+msgstr ""
+
+msgid "UnscannedProjects|Your projects are up do date! Nice job!"
+msgstr ""
+
+msgid "Unschedule job"
+msgstr ""
+
+msgid "Unstar"
+msgstr ""
+
+msgid "Unsubscribe"
+msgstr ""
+
+msgid "Unsubscribe at group level"
+msgstr ""
+
+msgid "Unsubscribe at project level"
+msgstr ""
+
+msgid "Unsubscribe from %{type}"
+msgstr ""
+
+msgid "Unsubscribed from this %{quick_action_target}."
+msgstr ""
+
+msgid "Unsubscribes from this %{quick_action_target}."
+msgstr ""
+
+msgid "Until"
+msgstr ""
+
+msgid "Until that time, the project can be restored."
+msgstr ""
+
+msgid "Unverified"
+msgstr ""
+
+msgid "Up to date"
+msgstr ""
+
+msgid "Upcoming"
+msgstr ""
+
+msgid "Upcoming Release"
+msgstr ""
+
+msgid "Update"
+msgstr ""
+
+msgid "Update all"
+msgstr ""
+
+msgid "Update approval rule"
+msgstr ""
+
+msgid "Update failed"
+msgstr ""
+
+msgid "Update failed. Please try again."
+msgstr ""
+
+msgid "Update it"
+msgstr ""
+
+msgid "Update now"
+msgstr ""
+
+msgid "Update variable"
+msgstr ""
+
+msgid "Update your bookmarked URLs as filtered/sorted branches URL has been changed."
+msgstr ""
+
+msgid "Update your group name, description, avatar, and visibility."
+msgstr ""
+
+msgid "Update your project name, topics, description and avatar."
+msgstr ""
+
+msgid "UpdateProject|Cannot rename project because it contains container registry tags!"
+msgstr ""
+
+msgid "UpdateProject|Could not set the default branch"
+msgstr ""
+
+msgid "UpdateProject|New visibility level not allowed!"
+msgstr ""
+
+msgid "UpdateProject|Project could not be updated!"
+msgstr ""
+
+msgid "UpdateRepositoryStorage|Error moving repository storage for %{project_full_path} - %{message}"
+msgstr ""
+
+msgid "UpdateRepositoryStorage|Failed to verify %{type} repository checksum from %{old} to %{new}"
+msgstr ""
+
+msgid "UpdateRepositoryStorage|Timeout waiting for %{type} repository pushes"
+msgstr ""
+
+msgid "Updated"
+msgstr ""
+
+msgid "Updated %{updated_at} by %{updated_by}"
+msgstr ""
+
+msgid "Updated at"
+msgstr ""
+
+msgid "Updated to"
+msgstr ""
+
+msgid "Updating"
+msgstr ""
+
+msgid "Upgrade plan to unlock Canary Deployments feature"
+msgstr ""
+
+msgid "Upgrade your plan to activate Advanced Global Search."
+msgstr ""
+
+msgid "Upgrade your plan to activate Audit Events."
+msgstr ""
+
+msgid "Upgrade your plan to activate Group Webhooks."
+msgstr ""
+
+msgid "Upgrade your plan to improve Issue boards."
+msgstr ""
+
+msgid "Upgrade your plan to improve Merge Requests."
+msgstr ""
+
+msgid "Upload <code>GoogleCodeProjectHosting.json</code> here:"
+msgstr ""
+
+msgid "Upload CSV file"
+msgstr ""
+
+msgid "Upload New File"
+msgstr ""
+
+msgid "Upload New License"
+msgstr ""
+
+msgid "Upload a certificate for your domain with all intermediates"
+msgstr ""
+
+msgid "Upload a private key for your certificate"
+msgstr ""
+
+msgid "Upload file"
+msgstr ""
+
+msgid "Upload object map"
+msgstr ""
+
+msgid "UploadLink|click to upload"
+msgstr ""
+
+msgid "Uploaded on"
+msgstr ""
+
+msgid "Uploaded:"
+msgstr ""
+
+msgid "Uploading changes to terminal"
+msgstr ""
+
+msgid "Uploads"
+msgstr ""
+
+msgid "Upon performing this action, the contents of this group, its subgroup and projects will be permanently removed after %{deletion_adjourned_period} days on <strong>%{date}</strong>. Until that time:"
+msgstr ""
+
+msgid "Upstream"
+msgstr ""
+
+msgid "Uptime"
+msgstr ""
+
+msgid "Upvotes"
+msgstr ""
+
+msgid "Usage"
+msgstr ""
+
+msgid "Usage ping is not enabled"
+msgstr ""
+
+msgid "Usage statistics"
+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|Artifacts"
+msgstr ""
+
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
+msgid "UsageQuota|Buy additional minutes"
+msgstr ""
+
+msgid "UsageQuota|Current period usage"
+msgstr ""
+
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
+msgid "UsageQuota|LFS Storage"
+msgstr ""
+
+msgid "UsageQuota|Packages"
+msgstr ""
+
+msgid "UsageQuota|Pipelines"
+msgstr ""
+
+msgid "UsageQuota|Repositories"
+msgstr ""
+
+msgid "UsageQuota|Repository"
+msgstr ""
+
+msgid "UsageQuota|Storage"
+msgstr ""
+
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
+msgid "UsageQuota|This namespace has no projects which use shared runners"
+msgstr ""
+
+msgid "UsageQuota|Unlimited"
+msgstr ""
+
+msgid "UsageQuota|Usage"
+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 resources across your projects"
+msgstr ""
+
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
+msgid "UsageQuota|Usage since"
+msgstr ""
+
+msgid "UsageQuota|Wiki"
+msgstr ""
+
+msgid "UsageQuota|Wikis"
+msgstr ""
+
+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 <code>%{native_redirect_uri}</code> for local tests"
+msgstr ""
+
+msgid "Use Service Desk to connect with your users (e.g. to offer customer support) through email right inside GitLab"
+msgstr ""
+
+msgid "Use a hardware device to add the second factor of authentication."
+msgstr ""
+
+msgid "Use an one time password authenticator on your mobile device or computer to enable two-factor authentication (2FA)."
+msgstr ""
+
+msgid "Use custom color #FF0000"
+msgstr ""
+
+msgid "Use group milestones to manage issues from multiple projects in the same milestone."
+msgstr ""
+
+msgid "Use hashed storage"
+msgstr ""
+
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
+msgstr ""
+
+msgid "Use one line per URI"
+msgstr ""
+
+msgid "Use template"
+msgstr ""
+
+msgid "Use the following registration token during setup:"
+msgstr ""
+
+msgid "Use your global notification setting"
+msgstr ""
+
+msgid "Use your smart card to authenticate with the LDAP server."
+msgstr ""
+
+msgid "Used by members to sign in to your group in GitLab"
+msgstr ""
+
+msgid "Used programming language"
+msgstr ""
+
+msgid "Used to help configure your identity provider"
+msgstr ""
+
+msgid "User"
+msgstr ""
+
+msgid "User %{current_user_username} has started impersonating %{username}"
+msgstr ""
+
+msgid "User %{username} was successfully removed."
+msgstr ""
+
+msgid "User Cohorts are only shown when the %{usage_ping_link_start}usage ping%{usage_ping_link_end} is enabled."
+msgstr ""
+
+msgid "User IDs"
+msgstr ""
+
+msgid "User OAuth applications"
+msgstr ""
+
+msgid "User Settings"
+msgstr ""
+
+msgid "User and IP Rate Limits"
+msgstr ""
+
+msgid "User identity was successfully created."
+msgstr ""
+
+msgid "User identity was successfully removed."
+msgstr ""
+
+msgid "User identity was successfully updated."
+msgstr ""
+
+msgid "User is not allowed to resolve thread"
+msgstr ""
+
+msgid "User key was successfully removed."
+msgstr ""
+
+msgid "User map"
+msgstr ""
+
+msgid "User pipeline minutes were successfully reset."
+msgstr ""
+
+msgid "User restrictions"
+msgstr ""
+
+msgid "User was successfully created."
+msgstr ""
+
+msgid "User was successfully removed from group and any subresources."
+msgstr ""
+
+msgid "User was successfully removed from project."
+msgstr ""
+
+msgid "User was successfully updated."
+msgstr ""
+
+msgid "UserOnboardingTour|%{activeTour}/%{totalTours}"
+msgstr ""
+
+msgid "UserOnboardingTour|%{completed}/%{total} steps completed"
+msgstr ""
+
+msgid "UserOnboardingTour|%{emphasisStart}Well done!%{emphasisEnd}%{lineBreak}%{lineBreak}That's it for our guided tour, congratulations for making it all the way to the end!%{lineBreak}%{lineBreak}We hope this gave you a good overview of GitLab and how it can help you. We'll now show you how to create your own project and invite your colleagues."
+msgstr ""
+
+msgid "UserOnboardingTour|Adding other members to a project is done through Project Settings. Click on %{emphasisStart}Settings%{emphasisEnd}."
+msgstr ""
+
+msgid "UserOnboardingTour|Alright, that's it for Commits. Let's take a look at the %{emphasisStart}Branches%{emphasisEnd}."
+msgstr ""
+
+msgid "UserOnboardingTour|Awesome! Now click on %{emphasisStart}Members%{emphasisEnd}."
+msgstr ""
+
+msgid "UserOnboardingTour|Click on one of the %{emphasisStart}Compare%{emphasisEnd} buttons to compare a branch to master."
+msgstr ""
+
+msgid "UserOnboardingTour|Click on one of the %{emphasisStart}pipeline IDs%{emphasisEnd} to see the details of a pipeline."
+msgstr ""
+
+msgid "UserOnboardingTour|Click to open the latest commit to see its details."
+msgstr ""
+
+msgid "UserOnboardingTour|Close 'Learn GitLab'"
+msgstr ""
+
+msgid "UserOnboardingTour|Commits are shown in chronological order and can be filtered by the commit message or by the branch."
+msgstr ""
+
+msgid "UserOnboardingTour|Create a project"
+msgstr ""
+
+msgid "UserOnboardingTour|Exit 'Learn GitLab'"
+msgstr ""
+
+msgid "UserOnboardingTour|Got it"
+msgstr ""
+
+msgid "UserOnboardingTour|Great job! %{clapHands} We hope the tour was helpful and that you learned how to use GitLab.%{lineBreak}%{lineBreak}We'd love to get your feedback on this tour.%{lineBreak}%{lineBreak}%{emphasisStart}How helpful would you say this guided tour was?%{emphasisEnd}%{lineBreak}%{lineBreak}"
+msgstr ""
+
+msgid "UserOnboardingTour|Guided GitLab Tour"
+msgstr ""
+
+msgid "UserOnboardingTour|Here you can compare the changes of this branch to another one. Changes are divided by files so that it's easier to see what was changed where."
+msgstr ""
+
+msgid "UserOnboardingTour|Here you can create a project from scratch, start with a template or import a repository from other platforms. Whatever you choose, we'll guide you through the process.%{lineBreak}%{lineBreak}Fill in your new project information and click on %{emphasisStart}Create Project%{emphasisEnd} to progress to the next step."
+msgstr ""
+
+msgid "UserOnboardingTour|Here you can see the breakdown of the pipelines: its stages and jobs in each of the stages and their status.%{lineBreak}%{lineBreak}Our CI/CD pipelines are quite complex, most of our users have fewer and simpler pipelines."
+msgstr ""
+
+msgid "UserOnboardingTour|Here you can see the current members of the project (just you at the moment) and invite new members.%{lineBreak}%{lineBreak}You can invite multiple members at once (existing GitLab users or invite by email) and you can also set their roles and permissions.%{lineBreak}%{lineBreak}Add a few members and click on %{emphasisStart}Add to project%{emphasisEnd} to complete this step."
+msgstr ""
+
+msgid "UserOnboardingTour|Here you can see what changes were made with this commit, on what branch and if there's a related merge request. The status of the pipeline will also show up if CI/CD is set up.%{lineBreak}%{lineBreak}You can also comment on the lines of code that were changed and start a discussion with your colleagues!"
+msgstr ""
+
+msgid "UserOnboardingTour|Here's an overview of branches in the %{emphasisStart}%{projectName}%{emphasisEnd} project. They're split into Active and Stale.%{lineBreak}%{lineBreak}From here, you can create a new merge request from a branch, or compare the branch to any other branch in the project. By default, it will compare it to the master branch."
+msgstr ""
+
+msgid "UserOnboardingTour|Invite colleagues"
+msgstr ""
+
+msgid "UserOnboardingTour|Issues are great for communicating and keeping track of progress in GitLab. These are all issues that are open in the %{emphasisStart}%{projectName}%{emphasisEnd}.%{lineBreak}%{lineBreak}You can help us improve GitLab by contributing work to issues that are labeled <span class=\"badge color-label accept-mr-label\">Accepting merge requests</span>.%{lineBreak}%{lineBreak}This list can be filtered by labels, milestones, assignees, authors... We'll show you how it looks when the list is filtered by a label."
+msgstr ""
+
+msgid "UserOnboardingTour|Learn GitLab"
+msgstr ""
+
+msgid "UserOnboardingTour|Let's take a closer look at a merge request. Click on the title of one."
+msgstr ""
+
+msgid "UserOnboardingTour|Let's take a closer look at all the commits. Click on %{emphasisStart}Commits%{emphasisEnd}."
+msgstr ""
+
+msgid "UserOnboardingTour|Let's take a closer look at the repository of this project. Click on %{emphasisStart}Repository%{emphasisEnd}."
+msgstr ""
+
+msgid "UserOnboardingTour|No thanks"
+msgstr ""
+
+msgid "UserOnboardingTour|Ok, let's go"
+msgstr ""
+
+msgid "UserOnboardingTour|Ok, show me"
+msgstr ""
+
+msgid "UserOnboardingTour|Open one of the issues by clicking on its title."
+msgstr ""
+
+msgid "UserOnboardingTour|Restart this step"
+msgstr ""
+
+msgid "UserOnboardingTour|Skip this step"
+msgstr ""
+
+msgid "UserOnboardingTour|Sweet! Your project was created and is ready to be used.%{lineBreak}%{lineBreak}You can start adding files to the repository or clone it. One last thing we want to show you is how to invite your colleagues to your new project."
+msgstr ""
+
+msgid "UserOnboardingTour|Take a look. Here's a nifty menu for quickly creating issues, merge requests, snippets, projects and groups. Click on it and select \"New project\" from the \"GitLab\" section to get started."
+msgstr ""
+
+msgid "UserOnboardingTour|Thanks for taking the guided tour. Remember, if you want to go through it again, you can start %{emphasisStart}Learn GitLab%{emphasisEnd} in the help menu on the top right."
+msgstr ""
+
+msgid "UserOnboardingTour|Thanks for the feedback! %{thumbsUp}"
+msgstr ""
+
+msgid "UserOnboardingTour|That's it for issues. Let'st take a look at %{emphasisStart}Merge Requests%{emphasisEnd}."
+msgstr ""
+
+msgid "UserOnboardingTour|That's it for merge requests. Now for the final part of this guided tour - the %{emphasisStart}CI/CD%{emphasisEnd}."
+msgstr ""
+
+msgid "UserOnboardingTour|That's it for the Repository. Let's take a look at the %{emphasisStart}Issues%{emphasisEnd}."
+msgstr ""
+
+msgid "UserOnboardingTour|The structure of this page is very similar to issues. Status, description, discussion and the sidebar are all here.%{lineBreak}%{lineBreak}But take a look below the description and you'll notice that there's more information about the merge request, the CI/CD pipeline and the options for approving it.%{lineBreak}%{lineBreak}Alongside the discussion you can also see more information about commits in this merge request, the status of pipelines and review all changes that were made."
+msgstr ""
+
+msgid "UserOnboardingTour|There's a lot of information here but don't worry, we'll go through it.%{lineBreak}%{lineBreak}On the top you can see the status of the issue and when it was opened and by whom. Directly below it is the issue description and below that are other %{emphasisStart}related issues%{emphasisEnd} and %{emphasisStart}merge requests%{emphasisEnd} (if any). Then below that is the %{emphasisStart}discussion%{emphasisEnd}, that's where most of the communication happens.%{lineBreak}%{lineBreak}On the right, there's a sidebar where you can view/change the %{emphasisStart}assignee, milestone, due date, labels, weight%{emphasisEnd}, etc."
+msgstr ""
+
+msgid "UserOnboardingTour|These are all the CI/CD pipelines we have for our %{emphasisStart}%{projectName}%{emphasisEnd} project.%{lineBreak}%{lineBreak}Here you can see the status of each pipeline, for what commit it's running for, its stages and the status for them."
+msgstr ""
+
+msgid "UserOnboardingTour|These are all the issues that are available for community contributions. Let's take a closer look at one of them."
+msgstr ""
+
+msgid "UserOnboardingTour|This is an overview of all merge requests in this project. Similarly to the issues overview it can be filtered down by things like labels, milestones, authors, assignees, etc."
+msgstr ""
+
+msgid "UserOnboardingTour|This is the repository for the %{emphasisStart}%{projectName}%{emphasisEnd} project. All our code is stored here. Feel free to explore and take a closer look at folders and files.%{lineBreak}%{lineBreak}Above the file structure you can see the latest commit, who the author is and the status of the CI/CD pipeline.%{lineBreak}%{lineBreak}If you scroll down below the file structure, you'll find the Readme of this project. This is defined in the README.md file at the root of the repository."
+msgstr ""
+
+msgid "UserOnboardingTour|Welcome to the project overview of the %{emphasisStart}%{projectName}%{emphasisEnd} project. This is the project that we use to work on GitLab. At first, a project seems like a simple repository, but at GitLab, a project is so much more.%{lineBreak}%{lineBreak}You can create projects for hosting your codebase, use it as an issue tracker, collaborate on code, and continuously build, test, and deploy your app with built-in GitLab CI/CD."
+msgstr ""
+
+msgid "UserProfile|Activity"
+msgstr ""
+
+msgid "UserProfile|Already reported for abuse"
+msgstr ""
+
+msgid "UserProfile|Blocked user"
+msgstr ""
+
+msgid "UserProfile|Contributed projects"
+msgstr ""
+
+msgid "UserProfile|Edit profile"
+msgstr ""
+
+msgid "UserProfile|Explore public groups to find projects to contribute to."
+msgstr ""
+
+msgid "UserProfile|Groups"
+msgstr ""
+
+msgid "UserProfile|Groups are the best way to manage projects and members."
+msgstr ""
+
+msgid "UserProfile|Join or create a group to start contributing by commenting on issues or submitting merge requests!"
+msgstr ""
+
+msgid "UserProfile|Most Recent Activity"
+msgstr ""
+
+msgid "UserProfile|No snippets found."
+msgstr ""
+
+msgid "UserProfile|Overview"
+msgstr ""
+
+msgid "UserProfile|Personal projects"
+msgstr ""
+
+msgid "UserProfile|Report abuse"
+msgstr ""
+
+msgid "UserProfile|Snippets"
+msgstr ""
+
+msgid "UserProfile|Snippets in GitLab can either be private, internal, or public."
+msgstr ""
+
+msgid "UserProfile|Star projects to track their progress and show your appreciation."
+msgstr ""
+
+msgid "UserProfile|Starred projects"
+msgstr ""
+
+msgid "UserProfile|Subscribe"
+msgstr ""
+
+msgid "UserProfile|This user doesn't have any personal projects"
+msgstr ""
+
+msgid "UserProfile|This user has a private profile"
+msgstr ""
+
+msgid "UserProfile|This user hasn't contributed to any projects"
+msgstr ""
+
+msgid "UserProfile|This user hasn't starred any projects"
+msgstr ""
+
+msgid "UserProfile|This user is blocked"
+msgstr ""
+
+msgid "UserProfile|View all"
+msgstr ""
+
+msgid "UserProfile|View user in admin area"
+msgstr ""
+
+msgid "UserProfile|You can create a group for several dependent projects."
+msgstr ""
+
+msgid "UserProfile|You haven't created any personal projects."
+msgstr ""
+
+msgid "UserProfile|You haven't created any snippets."
+msgstr ""
+
+msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
+msgstr ""
+
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
+msgid "Username (optional)"
+msgstr ""
+
+msgid "Username is already taken."
+msgstr ""
+
+msgid "Username is available."
+msgstr ""
+
+msgid "Username is too long (maximum is %{max_length} characters)."
+msgstr ""
+
+msgid "Username or email"
+msgstr ""
+
+msgid "Users"
+msgstr ""
+
+msgid "Users in License:"
+msgstr ""
+
+msgid "Users or groups set as approvers in the project's or merge request's settings."
+msgstr ""
+
+msgid "Users outside of license"
+msgstr ""
+
+msgid "Users over License:"
+msgstr ""
+
+msgid "Users requesting access to"
+msgstr ""
+
+msgid "Users were successfully added."
+msgstr ""
+
+msgid "Users with a Guest role or those who don't belong to any projects or groups don't count towards seats in use."
+msgstr ""
+
+msgid "UsersSelect|%{name} + %{length} more"
+msgstr ""
+
+msgid "UsersSelect|Any User"
+msgstr ""
+
+msgid "UsersSelect|Assignee"
+msgstr ""
+
+msgid "UsersSelect|No assignee - %{openingTag} assign yourself %{closingTag}"
+msgstr ""
+
+msgid "UsersSelect|Unassigned"
+msgstr ""
+
+msgid "Using %{code_start}::%{code_end} denotes a %{link_start}scoped label set%{link_end}"
+msgstr ""
+
+msgid "Using required encryption strategy when encrypted field is missing!"
+msgstr ""
+
+msgid "Valid from"
+msgstr ""
+
+msgid "Validate"
+msgstr ""
+
+msgid "Validate your GitLab CI configuration file"
+msgstr ""
+
+msgid "Validations failed."
+msgstr ""
+
+msgid "Validity"
+msgstr ""
+
+msgid "Value"
+msgstr ""
+
+msgid "Value Stream"
+msgstr ""
+
+msgid "Value Stream Analytics"
+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 "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
+msgstr ""
+
+msgid "Variable will be masked in job logs."
+msgstr ""
+
+msgid "Variables"
+msgstr ""
+
+msgid "Various container registry settings."
+msgstr ""
+
+msgid "Various email settings."
+msgstr ""
+
+msgid "Various localization settings."
+msgstr ""
+
+msgid "Various settings that affect GitLab performance."
+msgstr ""
+
+msgid "Verification capacity"
+msgstr ""
+
+msgid "Verification information"
+msgstr ""
+
+msgid "Verification status"
+msgstr ""
+
+msgid "Verified"
+msgstr ""
+
+msgid "Verify SAML Configuration"
+msgstr ""
+
+msgid "Verify configuration"
+msgstr ""
+
+msgid "Version"
+msgstr ""
+
+msgid "Versions"
+msgstr ""
+
+msgid "Very helpful"
+msgstr ""
+
+msgid "View Documentation"
+msgstr ""
+
+msgid "View all issues"
+msgstr ""
+
+msgid "View blame prior to this change"
+msgstr ""
+
+msgid "View chart"
+msgid_plural "View charts"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "View dependency details for your project"
+msgstr ""
+
+msgid "View deployment"
+msgstr ""
+
+msgid "View details"
+msgstr ""
+
+msgid "View details: %{details_url}"
+msgstr ""
+
+msgid "View documentation"
+msgstr ""
+
+msgid "View eligible approvers"
+msgstr ""
+
+msgid "View epics list"
+msgstr ""
+
+msgid "View exposed artifact"
+msgid_plural "View %d exposed artifacts"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "View file @ "
+msgstr ""
+
+msgid "View file @ %{commitSha}"
+msgstr ""
+
+msgid "View full dashboard"
+msgstr ""
+
+msgid "View full log"
+msgstr ""
+
+msgid "View group labels"
+msgstr ""
+
+msgid "View incident issues."
+msgstr ""
+
+msgid "View issue"
+msgstr ""
+
+msgid "View issues"
+msgstr ""
+
+msgid "View it on GitLab"
+msgstr ""
+
+msgid "View job"
+msgstr ""
+
+msgid "View job log"
+msgstr ""
+
+msgid "View jobs"
+msgstr ""
+
+msgid "View labels"
+msgstr ""
+
+msgid "View log"
+msgstr ""
+
+msgid "View open merge request"
+msgstr ""
+
+msgid "View performance dashboard."
+msgstr ""
+
+msgid "View project"
+msgstr ""
+
+msgid "View project labels"
+msgstr ""
+
+msgid "View replaced file @ "
+msgstr ""
+
+msgid "View supported languages and frameworks"
+msgstr ""
+
+msgid "View the documentation"
+msgstr ""
+
+msgid "View the latest successful deployment to this environment"
+msgstr ""
+
+msgid "View the performance dashboard at"
+msgstr ""
+
+msgid "View users statistics"
+msgstr ""
+
+msgid "Viewing commit"
+msgstr ""
+
+msgid "Visibility"
+msgstr ""
+
+msgid "Visibility and access controls"
+msgstr ""
+
+msgid "Visibility level"
+msgstr ""
+
+msgid "Visibility level:"
+msgstr ""
+
+msgid "Visibility settings have been disabled by the administrator."
+msgstr ""
+
+msgid "Visibility, project features, permissions"
+msgstr ""
+
+msgid "Visibility:"
+msgstr ""
+
+msgid "VisibilityLevel|Internal"
+msgstr ""
+
+msgid "VisibilityLevel|Private"
+msgstr ""
+
+msgid "VisibilityLevel|Public"
+msgstr ""
+
+msgid "VisibilityLevel|Unknown"
+msgstr ""
+
+msgid "VisualReviewApp|%{stepStart}Step 1%{stepEnd}. Copy the following script:"
+msgstr ""
+
+msgid "VisualReviewApp|%{stepStart}Step 2%{stepEnd}. Add it to the %{headTags} tags of every page of your application, ensuring the merge request ID is set or not set as required. "
+msgstr ""
+
+msgid "VisualReviewApp|%{stepStart}Step 3%{stepEnd}. If not previously %{linkStart}configured%{linkEnd} by a developer, enter the merge request ID for the review when prompted. The ID of this merge request is %{stepStart}%{mrId}%{stepStart}."
+msgstr ""
+
+msgid "VisualReviewApp|%{stepStart}Step 4%{stepEnd}. Leave feedback in the Review App."
+msgstr ""
+
+msgid "VisualReviewApp|Cancel"
+msgstr ""
+
+msgid "VisualReviewApp|Copy merge request ID"
+msgstr ""
+
+msgid "VisualReviewApp|Copy script"
+msgstr ""
+
+msgid "VisualReviewApp|Enable Visual Reviews"
+msgstr ""
+
+msgid "VisualReviewApp|Follow the steps below to enable Visual Reviews inside your application."
+msgstr ""
+
+msgid "VisualReviewApp|No review app found or available."
+msgstr ""
+
+msgid "VisualReviewApp|Open review app"
+msgstr ""
+
+msgid "VisualReviewApp|Review"
+msgstr ""
+
+msgid "VisualReviewApp|Steps 1 and 2 (and sometimes 3) are performed once by the developer before requesting feedback. Steps 3 (if necessary), 4 is performed by the reviewer each time they perform a review."
+msgstr ""
+
+msgid "Vulnerabilities"
+msgstr ""
+
+msgid "Vulnerabilities over time"
+msgstr ""
+
+msgid "Vulnerability remediated. Review before resolving."
+msgstr ""
+
+msgid "Vulnerability resolved in %{branch}"
+msgstr ""
+
+msgid "Vulnerability resolved in the default branch"
+msgstr ""
+
+msgid "Vulnerability-Check"
+msgstr ""
+
+msgid "VulnerabilityChart|%{formattedStartDate} to today"
+msgstr ""
+
+msgid "VulnerabilityChart|Severity"
+msgstr ""
+
+msgid "VulnerabilityManagement|A true-positive and will fix"
+msgstr ""
+
+msgid "VulnerabilityManagement|Change status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Confirm"
+msgstr ""
+
+msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
+msgstr ""
+
+msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
+msgstr ""
+
+msgid "VulnerabilityManagement|Dismiss"
+msgstr ""
+
+msgid "VulnerabilityManagement|Dismissed %{timeago} by %{user}"
+msgstr ""
+
+msgid "VulnerabilityManagement|Resolved"
+msgstr ""
+
+msgid "VulnerabilityManagement|Resolved %{timeago} by %{user}"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while trying to retrieve the vulnerability history. Please try again later."
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while trying to save the comment. Please try again later."
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong, could not create an issue."
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong, could not get user."
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
+msgstr ""
+
+msgid "VulnerabilityManagement|Verified as fixed or mitigated"
+msgstr ""
+
+msgid "VulnerabilityManagement|Will not fix or a false-positive"
+msgstr ""
+
+msgid "VulnerabilityStatusTypes|All"
+msgstr ""
+
+msgid "VulnerabilityStatusTypes|Confirmed"
+msgstr ""
+
+msgid "VulnerabilityStatusTypes|Detected"
+msgstr ""
+
+msgid "VulnerabilityStatusTypes|Dismissed"
+msgstr ""
+
+msgid "VulnerabilityStatusTypes|Resolved"
+msgstr ""
+
+msgid "Vulnerability|%{scannerName} (version %{scannerVersion})"
+msgstr ""
+
+msgid "Vulnerability|Class"
+msgstr ""
+
+msgid "Vulnerability|Description"
+msgstr ""
+
+msgid "Vulnerability|Evidence"
+msgstr ""
+
+msgid "Vulnerability|File"
+msgstr ""
+
+msgid "Vulnerability|Identifiers"
+msgstr ""
+
+msgid "Vulnerability|Image"
+msgstr ""
+
+msgid "Vulnerability|Instances"
+msgstr ""
+
+msgid "Vulnerability|Links"
+msgstr ""
+
+msgid "Vulnerability|Method"
+msgstr ""
+
+msgid "Vulnerability|Namespace"
+msgstr ""
+
+msgid "Vulnerability|Project"
+msgstr ""
+
+msgid "Vulnerability|Scanner Provider"
+msgstr ""
+
+msgid "Vulnerability|Scanner Type"
+msgstr ""
+
+msgid "Vulnerability|Severity"
+msgstr ""
+
+msgid "Vulnerability|Status"
+msgstr ""
+
+msgid "WIP"
+msgstr ""
+
+msgid "Wait for the file to load to copy its contents"
+msgstr ""
+
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
+msgid "Waiting for performance data"
+msgstr ""
+
+msgid "Want to see the data? Please ask an administrator for access."
+msgstr ""
+
+msgid "Warning:"
+msgstr ""
+
+msgid "Warning: Displaying this diagram might cause performance issues on this page."
+msgstr ""
+
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
+msgid "We could not determine the path to remove the epic"
+msgstr ""
+
+msgid "We could not determine the path to remove the issue"
+msgstr ""
+
+msgid "We couldn't reach the Prometheus server. Either the server no longer exists or the configuration details need updating."
+msgstr ""
+
+msgid "We created a short guided tour that will help you learn the basics of GitLab and how it will help you be better at your job. It should only take a couple of minutes. You will be guided by two types of helpers, best recognized by their color."
+msgstr ""
+
+msgid "We detected potential spam in the %{humanized_resource_name}. Please solve the reCAPTCHA to proceed."
+msgstr ""
+
+msgid "We don't have enough data to show this stage."
+msgstr ""
+
+msgid "We have found the following errors:"
+msgstr ""
+
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
+msgstr ""
+
+msgid "We sent you an email with reset password instructions"
+msgstr ""
+
+msgid "We tried to automatically renew your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} on %{expires_on} but something went wrong so your subscription was downgraded to the free plan. Don't worry, your data is safe. We suggest you check your payment method and get in touch with our support team (%{support_link}). They'll gladly help with your subscription renewal."
+msgstr ""
+
+msgid "We want to be sure it is you, please confirm you are not a robot."
+msgstr ""
+
+msgid "We will automatically renew your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} on %{strong}%{expires_on}%{strong_close}. There's nothing that you need to do, we'll let you know when the renewal is complete. Need more seats, a higher plan or just want to review your payment method?"
+msgstr ""
+
+msgid "We've found no vulnerabilities"
+msgstr ""
+
+msgid "Web IDE"
+msgstr ""
+
+msgid "Web Terminal"
+msgstr ""
+
+msgid "Web terminal"
+msgstr ""
+
+msgid "WebIDE|Merge request"
+msgstr ""
+
+msgid "Webhook"
+msgstr ""
+
+msgid "Webhook Logs"
+msgstr ""
+
+msgid "Webhook Settings"
+msgstr ""
+
+msgid "Webhooks"
+msgstr ""
+
+msgid "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 "Webhooks have moved. They can now be found under the Settings menu."
+msgstr ""
+
+msgid "Wednesday"
+msgstr ""
+
+msgid "Weekday"
+msgstr ""
+
+msgid "Weeks"
+msgstr ""
+
+msgid "Weight"
+msgstr ""
+
+msgid "Weight %{weight}"
+msgstr ""
+
+msgid "Welcome back! Your account had been deactivated due to inactivity but is now reactivated."
+msgstr ""
+
+msgid "Welcome to GitLab"
+msgstr ""
+
+msgid "Welcome to GitLab %{name}!"
+msgstr ""
+
+msgid "Welcome to GitLab, %{first_name}!"
+msgstr ""
+
+msgid "Welcome to GitLab.com<br>@%{name}!"
+msgstr ""
+
+msgid "Welcome to the Guided GitLab Tour"
+msgstr ""
+
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
+msgid "Welcome to your Issue Board!"
+msgstr ""
+
+msgid "What are you searching for?"
+msgstr ""
+
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
+msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
+msgstr ""
+
+msgid "When a runner is locked, it cannot be assigned to other projects"
+msgstr ""
+
+msgid "When enabled, any user visiting %{host} will be able to create an account."
+msgstr ""
+
+msgid "When enabled, if an NPM package isn't found in the GitLab Registry, we will attempt to pull from the global NPM registry."
+msgstr ""
+
+msgid "When enabled, users cannot use GitLab until the terms have been accepted."
+msgstr ""
+
+msgid "When leaving the URL blank, classification labels can still be specified without disabling cross project features or performing external authorization checks."
+msgstr ""
+
+msgid "When this merge request is accepted"
+msgid_plural "When these merge requests are accepted"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "When using the <code>http://</code> or <code>https://</code> protocols, please provide the exact URL to the repository. HTTP redirects will not be followed."
+msgstr ""
+
+msgid "When:"
+msgstr ""
+
+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 "White helpers give contextual information."
+msgstr ""
+
+msgid "Who can be an approver?"
+msgstr ""
+
+msgid "Who can see this group?"
+msgstr ""
+
+msgid "Who will be able to see this group?"
+msgstr ""
+
+msgid "Who will be using GitLab?"
+msgstr ""
+
+msgid "Who will be using this GitLab subscription?"
+msgstr ""
+
+msgid "Who will be using this GitLab trial?"
+msgstr ""
+
+msgid "Wiki"
+msgstr ""
+
+msgid "Wiki was successfully updated."
+msgstr ""
+
+msgid "WikiClone|Clone your wiki"
+msgstr ""
+
+msgid "WikiClone|Git Access"
+msgstr ""
+
+msgid "WikiClone|Install Gollum"
+msgstr ""
+
+msgid "WikiClone|Start Gollum and edit locally"
+msgstr ""
+
+msgid "WikiEditPageTip|Tip: You can move this page by adding the path to the beginning of the title."
+msgstr ""
+
+msgid "WikiEdit|There is already a page with the same title in that path."
+msgstr ""
+
+msgid "WikiEmptyIssueMessage|Suggest wiki improvement"
+msgstr ""
+
+msgid "WikiEmptyIssueMessage|You must be a project member in order to add wiki pages. If you have suggestions for how to improve the wiki for this project, consider opening an issue in the %{issues_link}."
+msgstr ""
+
+msgid "WikiEmptyIssueMessage|issue tracker"
+msgstr ""
+
+msgid "WikiEmpty|A wiki is where you can store all the details about your project. This can include why you've created it, its principles, how to use it, and so on."
+msgstr ""
+
+msgid "WikiEmpty|Create your first page"
+msgstr ""
+
+msgid "WikiEmpty|Suggest wiki improvement"
+msgstr ""
+
+msgid "WikiEmpty|The wiki lets you write documentation for your project"
+msgstr ""
+
+msgid "WikiEmpty|This project has no wiki pages"
+msgstr ""
+
+msgid "WikiEmpty|You must be a project member in order to add wiki pages."
+msgstr ""
+
+msgid "WikiHistoricalPage|This is an old version of this page."
+msgstr ""
+
+msgid "WikiHistoricalPage|You can view the %{most_recent_link} or browse the %{history_link}."
+msgstr ""
+
+msgid "WikiHistoricalPage|history"
+msgstr ""
+
+msgid "WikiHistoricalPage|most recent version"
+msgstr ""
+
+msgid "WikiMarkdownDocs|More examples are in the %{docs_link}"
+msgstr ""
+
+msgid "WikiMarkdownDocs|documentation"
+msgstr ""
+
+msgid "WikiMarkdownTip|To link to a (new) page, simply type <code class=\"js-markup-link-example\">%{link_example}</code>"
+msgstr ""
+
+msgid "WikiNewPageTip|Tip: You can specify the full path for the new file. We will automatically create any missing directories."
+msgstr ""
+
+msgid "WikiPageConfirmDelete|Are you sure you want to delete this page?"
+msgstr ""
+
+msgid "WikiPageConfirmDelete|Delete page"
+msgstr ""
+
+msgid "WikiPageConfirmDelete|Delete page %{pageTitle}?"
+msgstr ""
+
+msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{page_link} and make sure your changes will not unintentionally remove theirs."
+msgstr ""
+
+msgid "WikiPageConflictMessage|the page"
+msgstr ""
+
+msgid "WikiPageCreate|Create %{pageTitle}"
+msgstr ""
+
+msgid "WikiPageEdit|Update %{pageTitle}"
+msgstr ""
+
+msgid "WikiPage|Write your content or drag files here…"
+msgstr ""
+
+msgid "Wiki|Create New Page"
+msgstr ""
+
+msgid "Wiki|Create page"
+msgstr ""
+
+msgid "Wiki|Created date"
+msgstr ""
+
+msgid "Wiki|Edit Page"
+msgstr ""
+
+msgid "Wiki|New page"
+msgstr ""
+
+msgid "Wiki|Page history"
+msgstr ""
+
+msgid "Wiki|Page title"
+msgstr ""
+
+msgid "Wiki|Page version"
+msgstr ""
+
+msgid "Wiki|Pages"
+msgstr ""
+
+msgid "Wiki|Title"
+msgstr ""
+
+msgid "Wiki|View All Pages"
+msgstr ""
+
+msgid "Wiki|Wiki Pages"
+msgstr ""
+
+msgid "Will be created"
+msgstr ""
+
+msgid "Will deploy to"
+msgstr ""
+
+msgid "With requirements, you can set criteria to check your products against."
+msgstr ""
+
+msgid "Withdraw Access Request"
+msgstr ""
+
+msgid "Won't fix / Accept risk"
+msgstr ""
+
+msgid "Work in progress (open and unassigned)"
+msgstr ""
+
+msgid "Work in progress Limit"
+msgstr ""
+
+msgid "Write"
+msgstr ""
+
+msgid "Write a comment or drag your files here…"
+msgstr ""
+
+msgid "Write a comment…"
+msgstr ""
+
+msgid "Write access allowed"
+msgstr ""
+
+msgid "Write milestone description..."
+msgstr ""
+
+msgid "Write your release notes or drag your files here…"
+msgstr ""
+
+msgid "Wrong extern UID provided. Make sure Auth0 is configured correctly."
+msgstr ""
+
+msgid "Yes"
+msgstr ""
+
+msgid "Yes or No"
+msgstr ""
+
+msgid "Yes, add it"
+msgstr ""
+
+msgid "Yes, close issue"
+msgstr ""
+
+msgid "Yes, let me map Google Code users to full names or GitLab users."
+msgstr ""
+
+msgid "Yesterday"
+msgstr ""
+
+msgid "You"
+msgstr ""
+
+msgid "You are about to delete %{domain} from your instance. This domain will no longer be available to any Knative application."
+msgstr ""
+
+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 ""
+
+msgid "You are an admin, which means granting access to <strong>%{client_name}</strong> will allow them to interact with GitLab as an admin as well. Proceed with caution."
+msgstr ""
+
+msgid "You are attempting to delete a file that has been previously updated."
+msgstr ""
+
+msgid "You are attempting to update a file that has changed since you started editing it."
+msgstr ""
+
+msgid "You are connected to the Prometheus server, but there is currently no data to display."
+msgstr ""
+
+msgid "You are going to remove %{group_name}, this will also remove all of its subgroups and projects. Removed groups CANNOT be restored! Are you ABSOLUTELY sure?"
+msgstr ""
+
+msgid "You are going to remove %{project_full_name}. Removed project CANNOT be restored! Are you ABSOLUTELY sure?"
+msgstr ""
+
+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 owner. Are you ABSOLUTELY sure?"
+msgstr ""
+
+msgid "You are not allowed to push into this branch. Create another branch or open a merge request."
+msgstr ""
+
+msgid "You are not allowed to unlink your primary login account"
+msgstr ""
+
+msgid "You are not authorized to perform this action"
+msgstr ""
+
+msgid "You are now impersonating %{username}"
+msgstr ""
+
+msgid "You are on a read-only GitLab instance."
+msgstr ""
+
+msgid "You are receiving this message because you are a GitLab administrator for %{url}."
+msgstr ""
+
+msgid "You are trying to upload something other than an image. Please upload a .png, .jpg, .jpeg, .gif, .bmp, .tiff or .ico."
+msgstr ""
+
+msgid "You can %{linkStart}view the blob%{linkEnd} instead."
+msgstr ""
+
+msgid "You can also create a project from the command line."
+msgstr ""
+
+msgid "You can also press &#8984;-Enter"
+msgstr ""
+
+msgid "You can also press Ctrl-Enter"
+msgstr ""
+
+msgid "You can also star a label to make it a priority label."
+msgstr ""
+
+msgid "You can also test your %{gitlab_ci_yml} in %{lint_link_start}CI Lint%{lint_link_end}"
+msgstr ""
+
+msgid "You can also upload existing files from your computer using the instructions below."
+msgstr ""
+
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
+msgid "You can always edit this later"
+msgstr ""
+
+msgid "You can apply your Trial to your Personal account or create a New Group."
+msgstr ""
+
+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 Personal Access Tokens settings %{pat_link}"
+msgstr ""
+
+msgid "You can create new ones at your %{pat_link_start}Personal Access Tokens%{pat_link_end} settings"
+msgstr ""
+
+msgid "You can create new ones at your Personal Access Tokens settings %{pat_link}"
+msgstr ""
+
+msgid "You can easily contribute to them by requesting to join these groups."
+msgstr ""
+
+msgid "You can easily install a Runner on a Kubernetes cluster. %{link_to_help_page}"
+msgstr ""
+
+msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
+msgstr ""
+
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
+msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
+msgstr ""
+
+msgid "You can invite a new member to <strong>%{project_name}</strong> or invite another group."
+msgstr ""
+
+msgid "You can invite a new member to <strong>%{project_name}</strong>."
+msgstr ""
+
+msgid "You can invite another group to <strong>%{project_name}</strong>."
+msgstr ""
+
+msgid "You can move around the graph by using the arrow keys."
+msgstr ""
+
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
+msgid "You can now export your security dashboard to a CSV report."
+msgstr ""
+
+msgid "You can now submit a merge request to get this change into the original branch."
+msgstr ""
+
+msgid "You can now submit a merge request to get this change into the original project."
+msgstr ""
+
+msgid "You can only add files when you are on a branch"
+msgstr ""
+
+msgid "You can only edit files when you are on a branch"
+msgstr ""
+
+msgid "You can only merge once the items above are resolved."
+msgstr ""
+
+msgid "You can only merge once this merge request is approved."
+msgstr ""
+
+msgid "You can only transfer the project to namespaces you manage."
+msgstr ""
+
+msgid "You can only upload one design when dropping onto an existing design."
+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 ""
+
+msgid "You can see your chat accounts."
+msgstr ""
+
+msgid "You can set up as many Runners as you need to run your jobs."
+msgstr ""
+
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
+msgstr ""
+
+msgid "You can specify notification level per group or per project."
+msgstr ""
+
+msgid "You can test your .gitlab-ci.yml in %{linkStart}CI Lint%{linkEnd}."
+msgstr ""
+
+msgid "You can try again using %{begin_link}basic search%{end_link}"
+msgstr ""
+
+msgid "You cannot access the raw file. Please wait a minute."
+msgstr ""
+
+msgid "You cannot impersonate a blocked user"
+msgstr ""
+
+msgid "You cannot impersonate a user who cannot log in"
+msgstr ""
+
+msgid "You cannot impersonate an internal user"
+msgstr ""
+
+msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
+msgstr ""
+
+msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
+msgstr ""
+
+msgid "You cannot write to this read-only GitLab instance."
+msgstr ""
+
+msgid "You could not create a new trigger."
+msgstr ""
+
+msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} so it was downgraded to the free plan."
+msgstr ""
+
+msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
+msgstr ""
+
+msgid "You do not have an active license"
+msgstr ""
+
+msgid "You do not have any subscriptions yet"
+msgstr ""
+
+msgid "You do not have permission to leave this %{namespaceType}."
+msgstr ""
+
+msgid "You do not have permission to run the Web Terminal. Please contact a project administrator."
+msgstr ""
+
+msgid "You do not have permissions to run the import."
+msgstr ""
+
+msgid "You do not have the correct permissions to override the settings from the LDAP group sync."
+msgstr ""
+
+msgid "You don't have any U2F devices registered yet."
+msgstr ""
+
+msgid "You don't have any active chat names."
+msgstr ""
+
+msgid "You don't have any applications"
+msgstr ""
+
+msgid "You don't have any authorized applications"
+msgstr ""
+
+msgid "You don't have any deployments right now."
+msgstr ""
+
+msgid "You don't have any open merge requests"
+msgstr ""
+
+msgid "You don't have any projects available."
+msgstr ""
+
+msgid "You don't have any recent searches"
+msgstr ""
+
+msgid "You don't have sufficient permission to perform this action."
+msgstr ""
+
+msgid "You don’t have access to Productivity Analytics in this group"
+msgstr ""
+
+msgid "You don’t have access to Value Stream Analytics for this group"
+msgstr ""
+
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
+msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
+msgstr ""
+
+msgid "You have been granted %{access_level} access to the %{source_name} %{source_type}."
+msgstr ""
+
+msgid "You have been granted %{member_human_access} access to %{label}."
+msgstr ""
+
+msgid "You have been unsubscribed from this thread."
+msgstr ""
+
+msgid "You have declined the invitation to join %{label}."
+msgstr ""
+
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
+msgstr ""
+
+msgid "You have no permissions"
+msgstr ""
+
+msgid "You have not added any approvers. Start by adding users or groups."
+msgstr ""
+
+msgid "You have reached your project limit"
+msgstr ""
+
+msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
+msgstr ""
+
+msgid "You haven't added any issues to your project yet"
+msgstr ""
+
+msgid "You haven't selected any issues yet"
+msgstr ""
+
+msgid "You left the \"%{membershipable_human_name}\" %{source_type}."
+msgstr ""
+
+msgid "You may also add variables that are made available to the running application by prepending the variable key with <code>K8S_SECRET_</code>."
+msgstr ""
+
+msgid "You may close the milestone now."
+msgstr ""
+
+msgid "You must accept our Terms of Service and privacy policy in order to register an account"
+msgstr ""
+
+msgid "You must disassociate %{domain} from all clusters it is attached to before deletion."
+msgstr ""
+
+msgid "You must have maintainer access to force delete a lock"
+msgstr ""
+
+msgid "You must have permission to create a project in a namespace before forking."
+msgstr ""
+
+msgid "You must provide a valid current password"
+msgstr ""
+
+msgid "You must provide your current password in order to change it."
+msgstr ""
+
+msgid "You must select a stack for configuring your cloud provider. Learn more about"
+msgstr ""
+
+msgid "You must set up incoming email before it becomes active."
+msgstr ""
+
+msgid "You must upload a file with the same file name when dropping onto an existing design."
+msgstr ""
+
+msgid "You need a different license to enable FileLocks feature"
+msgstr ""
+
+msgid "You need git-lfs version %{min_git_lfs_version} (or greater) to continue. Please visit https://git-lfs.github.com"
+msgstr ""
+
+msgid "You need permission."
+msgstr ""
+
+msgid "You need to be logged in."
+msgstr ""
+
+msgid "You need to register a two-factor authentication app before you can set up a U2F device."
+msgstr ""
+
+msgid "You need to set terms to be enforced"
+msgstr ""
+
+msgid "You need to specify both an Access Token and a Host URL."
+msgstr ""
+
+msgid "You need to upload a GitLab project export archive (ending in .gz)."
+msgstr ""
+
+msgid "You need to upload a Google Takeout archive."
+msgstr ""
+
+msgid "You reached %{usage_in_percent} of %{namespace_name}'s capacity (%{used_storage} of %{storage_limit})"
+msgstr ""
+
+msgid "You tried to fork %{link_to_the_project} but it failed for the following reason:"
+msgstr ""
+
+msgid "You will be removed from existing projects/groups"
+msgstr ""
+
+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 ""
+
+msgid "You will first need to set up Jira Integration to use this feature."
+msgstr ""
+
+msgid "You will lose all changes you've made to this file. This action cannot be undone."
+msgstr ""
+
+msgid "You will lose all uncommitted changes you've made in this project. This action cannot be undone."
+msgstr ""
+
+msgid "You will need to update your local repositories to point to the new location."
+msgstr ""
+
+msgid "You will not get any notifications via email"
+msgstr ""
+
+msgid "You will only receive notifications for the events you choose"
+msgstr ""
+
+msgid "You will only receive notifications for threads you have participated in"
+msgstr ""
+
+msgid "You will receive notifications for any activity"
+msgstr ""
+
+msgid "You will receive notifications only for comments in which you were @mentioned"
+msgstr ""
+
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
+msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
+msgstr ""
+
+msgid "You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
+msgstr ""
+
+msgid "You'll be signed out from your current account automatically."
+msgstr ""
+
+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 ""
+
+msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
+msgstr ""
+
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
+
+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 ""
+
+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 ""
+
+msgid "You're only seeing %{startTag}other activity%{endTag} in the feed. To add a comment, switch to one of the following options."
+msgstr ""
+
+msgid "You're receiving this email because of your account on %{host}."
+msgstr ""
+
+msgid "You're receiving this email because of your account on %{host}. %{manage_notifications_link} &middot; %{help_link}"
+msgstr ""
+
+msgid "You're receiving this email because of your activity on %{host}."
+msgstr ""
+
+msgid "You're receiving this email because you have been assigned an item on %{host}."
+msgstr ""
+
+msgid "You're receiving this email because you have been mentioned on %{host}."
+msgstr ""
+
+msgid "You've already enabled two-factor authentication using one time password authenticators. In order to register a different device, you must first disable two-factor authentication."
+msgstr ""
+
+msgid "YouTube"
+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}."
+msgstr ""
+
+msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+msgstr ""
+
+msgid "Your CSV export has started. It will be emailed to %{email} when complete."
+msgstr ""
+
+msgid "Your CSV export of %{issues_count} from project %{project_link} has been added to this email as an attachment."
+msgstr ""
+
+msgid "Your CSV export of %{written_count} from project %{project_name} (%{project_url}) has been added to this email as an attachment."
+msgstr ""
+
+msgid "Your Commit Email will be used for web based operations, such as edits and merges."
+msgstr ""
+
+msgid "Your Default Notification Email will be used for account notifications if a %{openingTag}group-specific email address%{closingTag} is not set."
+msgstr ""
+
+msgid "Your DevOps Score gives an overview of how you are using GitLab from a feature perspective. View how you compare with other organizations, discover features you are not using, and learn best practices through blog posts and white papers."
+msgstr ""
+
+msgid "Your GPG keys (%{count})"
+msgstr ""
+
+msgid "Your GitLab group"
+msgstr ""
+
+msgid "Your Gitlab Gold trial will last 30 days after which point you can keep your free Gitlab account forever. We just need some additional information to activate your trial."
+msgstr ""
+
+msgid "Your Groups"
+msgstr ""
+
+msgid "Your License"
+msgstr ""
+
+msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
+msgstr ""
+
+msgid "Your Primary Email will be used for avatar detection."
+msgstr ""
+
+msgid "Your Projects (default)"
+msgstr ""
+
+msgid "Your Projects' Activity"
+msgstr ""
+
+msgid "Your Public Email will be displayed on your public profile."
+msgstr ""
+
+msgid "Your SSH keys (%{count})"
+msgstr ""
+
+msgid "Your To-Do List"
+msgstr ""
+
+msgid "Your U2F device did not send a valid JSON response."
+msgstr ""
+
+msgid "Your U2F device needs to be set up. Plug it in (if not already) and click the button on the left."
+msgstr ""
+
+msgid "Your U2F device was registered!"
+msgstr ""
+
+msgid "Your access request to the %{source_type} has been withdrawn."
+msgstr ""
+
+msgid "Your account has been deactivated by your administrator. Please log back in to reactivate your account."
+msgstr ""
+
+msgid "Your account is locked."
+msgstr ""
+
+msgid "Your account uses dedicated credentials for the \"%{group_name}\" group and can only be updated through SSO."
+msgstr ""
+
+msgid "Your applications (%{size})"
+msgstr ""
+
+msgid "Your authorized applications"
+msgstr ""
+
+msgid "Your browser doesn't support U2F. Please use Google Chrome desktop (version 41 or newer)."
+msgstr ""
+
+msgid "Your changes can be committed to %{branch_name} because a merge request is open."
+msgstr ""
+
+msgid "Your changes have been committed. Commit %{commitId} %{commitStats}"
+msgstr ""
+
+msgid "Your changes have been saved"
+msgstr ""
+
+msgid "Your changes have been successfully committed."
+msgstr ""
+
+msgid "Your comment could not be submitted because %{error}"
+msgstr ""
+
+msgid "Your comment could not be submitted! Please check your network connection and try again."
+msgstr ""
+
+msgid "Your comment could not be updated! Please check your network connection and try again."
+msgstr ""
+
+msgid "Your comment will be discarded."
+msgstr ""
+
+msgid "Your custom stage '%{title}' was created"
+msgstr ""
+
+msgid "Your dashboard has been copied. You can %{web_ide_link_start}edit it here%{web_ide_link_end}."
+msgstr ""
+
+msgid "Your dashboard has been updated. You can %{web_ide_link_start}edit it here%{web_ide_link_end}."
+msgstr ""
+
+msgid "Your deployment services will be broken, you will need to manually fix the services after renaming."
+msgstr ""
+
+msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
+msgstr ""
+
+msgid "Your first project"
+msgstr ""
+
+msgid "Your groups"
+msgstr ""
+
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
+msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
+msgstr ""
+
+msgid "Your issues will be imported in the background. Once finished, you'll get a confirmation email."
+msgstr ""
+
+msgid "Your license is valid from"
+msgstr ""
+
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
+msgid "Your message here"
+msgstr ""
+
+msgid "Your name"
+msgstr ""
+
+msgid "Your new %{type}"
+msgstr ""
+
+msgid "Your new SCIM token"
+msgstr ""
+
+msgid "Your new personal access token has been created."
+msgstr ""
+
+msgid "Your new project access token has been created."
+msgstr ""
+
+msgid "Your password isn't required to view this page. If a password or any other personal details are requested, please contact your administrator to report abuse."
+msgstr ""
+
+msgid "Your password reset token has expired."
+msgstr ""
+
+msgid "Your profile"
+msgstr ""
+
+msgid "Your project limit is %{limit} projects! Please contact your administrator to increase it"
+msgstr ""
+
+msgid "Your projects"
+msgstr ""
+
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
+msgid "Your request for access has been queued for review."
+msgstr ""
+
+msgid "Your response has been recorded."
+msgstr ""
+
+msgid "Your search didn't match any commits."
+msgstr ""
+
+msgid "Your subscription expired!"
+msgstr ""
+
+msgid "Your subscription has been downgraded"
+msgstr ""
+
+msgid "Your subscription will automatically renew in %{remaining_days}"
+msgstr ""
+
+msgid "Your subscription will expire in %{remaining_days}"
+msgstr ""
+
+msgid "Zoom meeting added"
+msgstr ""
+
+msgid "Zoom meeting removed"
+msgstr ""
+
+msgid "[No reason]"
+msgstr ""
+
+msgid "a deleted user"
+msgstr ""
+
+msgid "a design"
+msgstr ""
+
+msgid "about 1 hour"
+msgid_plural "about %d hours"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "activated"
+msgstr ""
+
+msgid "added %{created_at_timeago}"
+msgstr ""
+
+msgid "added a Zoom call to this issue"
+msgstr ""
+
+msgid "ago"
+msgstr ""
+
+msgid "alert"
+msgstr ""
+
+msgid "allowed to fail"
+msgstr ""
+
+msgid "already being used for another group or project %{timebox_name}."
+msgstr ""
+
+msgid "already has a \"created\" issue link"
+msgstr ""
+
+msgid "already shared with this group"
+msgstr ""
+
+msgid "among other things"
+msgstr ""
+
+msgid "any-approver for the merge request already exists"
+msgstr ""
+
+msgid "any-approver for the project already exists"
+msgstr ""
+
+msgid "archived"
+msgstr ""
+
+msgid "assign yourself"
+msgstr ""
+
+msgid "at risk"
+msgstr ""
+
+msgid "attach a new file"
+msgstr ""
+
+msgid "authored"
+msgstr ""
+
+msgid "blocks"
+msgstr ""
+
+msgid "branch name"
+msgstr ""
+
+msgid "build pipeline reference mismatch"
+msgstr ""
+
+msgid "by"
+msgstr ""
+
+msgid "by %{user}"
+msgstr ""
+
+msgid "cannot be changed if a personal project has container registry tags."
+msgstr ""
+
+msgid "cannot be enabled unless all domains have TLS certificates"
+msgstr ""
+
+msgid "cannot be modified"
+msgstr ""
+
+msgid "cannot block others"
+msgstr ""
+
+msgid "cannot include leading slash or directory traversal."
+msgstr ""
+
+msgid "cannot itself be blocked"
+msgstr ""
+
+msgid "cannot merge"
+msgstr ""
+
+msgid "ciReport|%{linkStartTag}Learn more about Container Scanning %{linkEndTag}"
+msgstr ""
+
+msgid "ciReport|%{linkStartTag}Learn more about DAST %{linkEndTag}"
+msgstr ""
+
+msgid "ciReport|%{linkStartTag}Learn more about Dependency Scanning %{linkEndTag}"
+msgstr ""
+
+msgid "ciReport|%{linkStartTag}Learn more about SAST %{linkEndTag}"
+msgstr ""
+
+msgid "ciReport|%{linkStartTag}Learn more about Secret Scanning %{linkEndTag}"
+msgstr ""
+
+msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
+msgstr ""
+
+msgid "ciReport|%{remainingPackagesCount} more"
+msgstr ""
+
+msgid "ciReport|%{reportType} %{status} detected %{dismissedCount} dismissed vulnerability"
+msgid_plural "ciReport|%{reportType} %{status} detected %{dismissedCount} dismissed vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ciReport|%{reportType} %{status} detected %{dismissedCount} dismissed vulnerability for the source branch only"
+msgid_plural "ciReport|%{reportType} %{status} detected %{dismissedCount} dismissed vulnerabilities for the source branch only"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ciReport|%{reportType} %{status} detected %{fixedCount} fixed vulnerability"
+msgid_plural "ciReport|%{reportType} %{status} detected %{fixedCount} fixed vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ciReport|%{reportType} %{status} detected %{fixedCount} fixed, and %{dismissedCount} dismissed vulnerabilities"
+msgstr ""
+
+msgid "ciReport|%{reportType} %{status} detected %{newCount} new vulnerability"
+msgid_plural "ciReport|%{reportType} %{status} detected %{newCount} new vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ciReport|%{reportType} %{status} detected %{newCount} new, %{fixedCount} fixed, and %{dismissedCount} dismissed vulnerabilities"
+msgstr ""
+
+msgid "ciReport|%{reportType} %{status} detected %{newCount} new, and %{dismissedCount} dismissed vulnerabilities"
+msgstr ""
+
+msgid "ciReport|%{reportType} %{status} detected %{newCount} new, and %{dismissedCount} dismissed vulnerabilities for the source branch only"
+msgstr ""
+
+msgid "ciReport|%{reportType} %{status} detected %{newCount} new, and %{fixedCount} fixed vulnerabilities"
+msgstr ""
+
+msgid "ciReport|%{reportType} %{status} detected %{newCount} vulnerability for the source branch only"
+msgid_plural "ciReport|%{reportType} %{status} detected %{newCount} vulnerabilities for the source branch only"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ciReport|%{reportType} %{status} detected no new vulnerabilities"
+msgstr ""
+
+msgid "ciReport|%{reportType} %{status} detected no vulnerabilities"
+msgstr ""
+
+msgid "ciReport|%{reportType} %{status} detected no vulnerabilities for the source branch only"
+msgstr ""
+
+msgid "ciReport|%{reportType} is loading"
+msgstr ""
+
+msgid "ciReport|%{reportType}: Loading resulted in an error"
+msgstr ""
+
+msgid "ciReport|(errors when loading results)"
+msgstr ""
+
+msgid "ciReport|(is loading)"
+msgstr ""
+
+msgid "ciReport|(is loading, errors when loading results)"
+msgstr ""
+
+msgid "ciReport|All projects"
+msgstr ""
+
+msgid "ciReport|All report types"
+msgstr ""
+
+msgid "ciReport|All severities"
+msgstr ""
+
+msgid "ciReport|Automatically apply the patch in a new branch"
+msgstr ""
+
+msgid "ciReport|Base pipeline codequality artifact not found"
+msgstr ""
+
+msgid "ciReport|Code quality"
+msgstr ""
+
+msgid "ciReport|Container Scanning"
+msgstr ""
+
+msgid "ciReport|Container scanning"
+msgstr ""
+
+msgid "ciReport|Container scanning detects known vulnerabilities in your docker images."
+msgstr ""
+
+msgid "ciReport|Create a merge request to implement this solution, or download and apply the patch manually."
+msgstr ""
+
+msgid "ciReport|Create issue"
+msgstr ""
+
+msgid "ciReport|DAST"
+msgstr ""
+
+msgid "ciReport|Dependency Scanning"
+msgstr ""
+
+msgid "ciReport|Dependency Scanning detects known vulnerabilities in your source code's dependencies."
+msgstr ""
+
+msgid "ciReport|Dependency scanning"
+msgstr ""
+
+msgid "ciReport|Download patch to resolve"
+msgstr ""
+
+msgid "ciReport|Download the patch to apply it manually"
+msgstr ""
+
+msgid "ciReport|Dynamic Application Security Testing (DAST) detects known vulnerabilities in your web application."
+msgstr ""
+
+msgid "ciReport|Failed to load %{reportName} report"
+msgstr ""
+
+msgid "ciReport|Fixed"
+msgstr ""
+
+msgid "ciReport|Fixed:"
+msgstr ""
+
+msgid "ciReport|Found %{issuesWithCount}"
+msgstr ""
+
+msgid "ciReport|Investigate this vulnerability by creating an issue"
+msgstr ""
+
+msgid "ciReport|Learn more about interacting with security reports"
+msgstr ""
+
+msgid "ciReport|Loading %{reportName} report"
+msgstr ""
+
+msgid "ciReport|Manage licenses"
+msgstr ""
+
+msgid "ciReport|New"
+msgstr ""
+
+msgid "ciReport|No changes to code quality"
+msgstr ""
+
+msgid "ciReport|No changes to performance metrics"
+msgstr ""
+
+msgid "ciReport|No code quality issues found"
+msgstr ""
+
+msgid "ciReport|Performance metrics"
+msgstr ""
+
+msgid "ciReport|Resolve with merge request"
+msgstr ""
+
+msgid "ciReport|SAST"
+msgstr ""
+
+msgid "ciReport|Secret Detection"
+msgstr ""
+
+msgid "ciReport|Secret scanning"
+msgstr ""
+
+msgid "ciReport|Secret scanning detects secrets and credentials vulnerabilities in your source code."
+msgstr ""
+
+msgid "ciReport|Security scanning"
+msgstr ""
+
+msgid "ciReport|Security scanning failed loading any results"
+msgstr ""
+
+msgid "ciReport|Solution"
+msgstr ""
+
+msgid "ciReport|Static Application Security Testing (SAST) detects known vulnerabilities in your source code."
+msgstr ""
+
+msgid "ciReport|There was an error creating the issue. Please try again."
+msgstr ""
+
+msgid "ciReport|There was an error creating the merge request. Please try again."
+msgstr ""
+
+msgid "ciReport|There was an error dismissing the vulnerability. Please try again."
+msgstr ""
+
+msgid "ciReport|There was an error fetching the codequality report."
+msgstr ""
+
+msgid "ciReport|There was an error reverting the dismissal. Please try again."
+msgstr ""
+
+msgid "ciReport|Used by %{packagesString}"
+msgid_plural "ciReport|Used by %{packagesString}, and %{lastPackage}"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ciReport|View full report"
+msgstr ""
+
+msgid "closed issue"
+msgstr ""
+
+msgid "comment"
+msgstr ""
+
+msgid "commented on %{link_to_project}"
+msgstr ""
+
+msgid "commit %{commit_id}"
+msgstr ""
+
+msgid "committed"
+msgstr ""
+
+msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
+msgstr ""
+
+msgid "confidentiality|You are going to turn on the confidentiality. This means that only team members with <strong>at least Reporter access</strong> are able to see and leave comments on the issue."
+msgstr ""
+
+msgid "connecting"
+msgstr ""
+
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
+msgid "container_name cannot be larger than %{max_length} chars"
+msgstr ""
+
+msgid "could not read private key, is the passphrase correct?"
+msgstr ""
+
+msgid "created"
+msgstr ""
+
+msgid "created %{timeAgo}"
+msgstr ""
+
+msgid "customize"
+msgstr ""
+
+msgid "date must not be after 9999-12-31"
+msgstr ""
+
+msgid "day"
+msgid_plural "days"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "default branch"
+msgstr ""
+
+msgid "deleted"
+msgstr ""
+
+msgid "deploy"
+msgstr ""
+
+msgid "design"
+msgstr ""
+
+msgid "designs"
+msgstr ""
+
+msgid "detached"
+msgstr ""
+
+msgid "disabled"
+msgstr ""
+
+msgid "does not have a supported extension. Only %{extension_list} are supported"
+msgstr ""
+
+msgid "done"
+msgstr ""
+
+msgid "download it"
+msgstr ""
+
+msgid "draft"
+msgid_plural "drafts"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "e.g. %{token}"
+msgstr ""
+
+msgid "element is not a hierarchy"
+msgstr ""
+
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
+msgstr ""
+
+msgid "enabled"
+msgstr ""
+
+msgid "encrypted: needs to be a :required, :optional or :migrating!"
+msgstr ""
+
+msgid "entries cannot be larger than 255 characters"
+msgstr ""
+
+msgid "entries cannot be nil"
+msgstr ""
+
+msgid "entries cannot contain HTML tags"
+msgstr ""
+
+msgid "error"
+msgstr ""
+
+msgid "error code:"
+msgstr ""
+
+msgid "estimateCommand|%{slash_command} will update the estimated time with the latest command."
+msgstr ""
+
+msgid "exceeds the limit of %{bytes} bytes"
+msgstr ""
+
+msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
+msgstr ""
+
+msgid "expired on %{timebox_due_date}"
+msgstr ""
+
+msgid "expires on %{timebox_due_date}"
+msgstr ""
+
+msgid "external_url"
+msgstr ""
+
+msgid "failed"
+msgstr ""
+
+msgid "failed to dismiss associated finding(id=%{finding_id}): %{message}"
+msgstr ""
+
+msgid "file"
+msgid_plural "files"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "finding is not found or is already attached to a vulnerability"
+msgstr ""
+
+msgid "for %{link_to_merge_request} with %{link_to_merge_request_source_branch}"
+msgstr ""
+
+msgid "for %{link_to_merge_request} with %{link_to_merge_request_source_branch} into %{link_to_merge_request_target_branch}"
+msgstr ""
+
+msgid "for %{link_to_pipeline_ref}"
+msgstr ""
+
+msgid "for %{ref}"
+msgstr ""
+
+msgid "for this project"
+msgstr ""
+
+msgid "fork this project"
+msgstr ""
+
+msgid "from"
+msgstr ""
+
+msgid "geo_node_name"
+msgstr ""
+
+msgid "group"
+msgstr ""
+
+msgid "groups"
+msgstr ""
+
+msgid "has already been linked to another vulnerability"
+msgstr ""
+
+msgid "has already been taken"
+msgstr ""
+
+msgid "help"
+msgstr ""
+
+msgid "here"
+msgstr ""
+
+msgid "https://your-bitbucket-server"
+msgstr ""
+
+msgid "image"
+msgstr ""
+
+msgid "image diff"
+msgstr ""
+
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
+msgid "import flow"
+msgstr ""
+
+msgid "importing"
+msgstr ""
+
+msgid "in group %{link_to_group}"
+msgstr ""
+
+msgid "in project %{link_to_project}"
+msgstr ""
+
+msgid "index"
+msgstr ""
+
+msgid "instance completed"
+msgid_plural "instances completed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "invalid milestone state `%{state}`"
+msgstr ""
+
+msgid "is"
+msgstr ""
+
+msgid "is already associated to a GitLab Issue. New issue will not be associated."
+msgstr ""
+
+msgid "is an invalid IP address range"
+msgstr ""
+
+msgid "is blocked by"
+msgstr ""
+
+msgid "is enabled."
+msgstr ""
+
+msgid "is invalid because there is downstream lock"
+msgstr ""
+
+msgid "is invalid because there is upstream lock"
+msgstr ""
+
+msgid "is not"
+msgstr ""
+
+msgid "is not a descendant of the Group owning the template"
+msgstr ""
+
+msgid "is not a valid X509 certificate."
+msgstr ""
+
+msgid "is not allowed. Try again with a different email address, or contact your GitLab admin."
+msgstr ""
+
+msgid "is not an email you own"
+msgstr ""
+
+msgid "is not in the group enforcing Group Managed Account"
+msgstr ""
+
+msgid "is read only"
+msgstr ""
+
+msgid "is too long (%{current_value}). The maximum size is %{max_size}."
+msgstr ""
+
+msgid "is too long (maximum is 100 entries)"
+msgstr ""
+
+msgid "is too long (maximum is 1000 entries)"
+msgstr ""
+
+msgid "issue"
+msgstr ""
+
+msgid "issues at risk"
+msgstr ""
+
+msgid "issues need attention"
+msgstr ""
+
+msgid "issues on track"
+msgstr ""
+
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
+msgid "it is stored externally"
+msgstr ""
+
+msgid "it is stored in LFS"
+msgstr ""
+
+msgid "it is too large"
+msgstr ""
+
+msgid "jigsaw is not defined"
+msgstr ""
+
+msgid "jira.issue.description.content"
+msgstr ""
+
+msgid "jira.issue.summary"
+msgstr ""
+
+msgid "latest"
+msgstr ""
+
+msgid "latest deployment"
+msgstr ""
+
+msgid "latest version"
+msgstr ""
+
+msgid "leave %{group_name}"
+msgstr ""
+
+msgid "less than a minute"
+msgstr ""
+
+msgid "level: %{level}"
+msgstr ""
+
+msgid "limit of %{project_limit} reached"
+msgstr ""
+
+msgid "load it anyway"
+msgstr ""
+
+msgid "locked by %{path_lock_user_name} %{created_at}"
+msgstr ""
+
+msgid "log in"
+msgstr ""
+
+msgid "manual"
+msgstr ""
+
+msgid "math|The math in this entry is taking too long to render and may not be displayed as expected. For performance reasons, math blocks are also limited to %{maxChars} characters. Consider splitting up large formulae, splitting math blocks among multiple entries, or using an image instead."
+msgstr ""
+
+msgid "math|There was an error rendering this math block"
+msgstr ""
+
+msgid "merge request"
+msgid_plural "merge requests"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "merged %{time_ago}"
+msgstr ""
+
+msgid "missing"
+msgstr ""
+
+msgid "most recent deployment"
+msgstr ""
+
+msgid "mrWidgetCommitsAdded|%{commitCount} and %{mergeCommitCount} will be added to %{targetBranch}."
+msgstr ""
+
+msgid "mrWidgetCommitsAdded|%{commitCount} will be added to %{targetBranch}."
+msgstr ""
+
+msgid "mrWidgetCommitsAdded|1 merge commit"
+msgstr ""
+
+msgid "mrWidgetNothingToMerge|Currently there are no changes in this merge request's source branch. Please push new commits or use a different branch."
+msgstr ""
+
+msgid "mrWidgetNothingToMerge|Interested parties can even contribute by pushing commits if they want to."
+msgstr ""
+
+msgid "mrWidgetNothingToMerge|Merge requests are a place to propose changes you have made to a project and discuss those changes with others."
+msgstr ""
+
+msgid "mrWidget| Please restore it or use a different %{missingBranchName} branch"
+msgstr ""
+
+msgid "mrWidget|%{link_start}Learn more about resolving conflicts%{link_end}"
+msgstr ""
+
+msgid "mrWidget|%{metricsLinkStart} Memory %{metricsLinkEnd} usage %{emphasisStart} decreased %{emphasisEnd} from %{memoryFrom}MB to %{memoryTo}MB"
+msgstr ""
+
+msgid "mrWidget|%{metricsLinkStart} Memory %{metricsLinkEnd} usage %{emphasisStart} increased %{emphasisEnd} from %{memoryFrom}MB to %{memoryTo}MB"
+msgstr ""
+
+msgid "mrWidget|%{metricsLinkStart} Memory %{metricsLinkEnd} usage is %{emphasisStart} unchanged %{emphasisEnd} at %{memoryFrom}MB"
+msgstr ""
+
+msgid "mrWidget|%{prefixToLinkStart}No pipeline%{prefixToLinkEnd} %{addPipelineLinkStart}Add the .gitlab-ci.yml file%{addPipelineLinkEnd} to create one."
+msgstr ""
+
+msgid "mrWidget|Added to the merge train by"
+msgstr ""
+
+msgid "mrWidget|Allows commits from members who can merge to the target branch"
+msgstr ""
+
+msgid "mrWidget|An error occurred while removing your approval."
+msgstr ""
+
+msgid "mrWidget|An error occurred while retrieving approval data for this merge request."
+msgstr ""
+
+msgid "mrWidget|An error occurred while submitting your approval."
+msgstr ""
+
+msgid "mrWidget|Approval password is invalid."
+msgstr ""
+
+msgid "mrWidget|Approve"
+msgstr ""
+
+msgid "mrWidget|Approve additionally"
+msgstr ""
+
+msgid "mrWidget|Approved by"
+msgstr ""
+
+msgid "mrWidget|Are you adding technical debt or code vulnerabilities?"
+msgstr ""
+
+msgid "mrWidget|Cancel automatic merge"
+msgstr ""
+
+msgid "mrWidget|Check out branch"
+msgstr ""
+
+msgid "mrWidget|Checking ability to merge automatically…"
+msgstr ""
+
+msgid "mrWidget|Cherry-pick"
+msgstr ""
+
+msgid "mrWidget|Cherry-pick this merge request in a new merge request"
+msgstr ""
+
+msgid "mrWidget|Closed"
+msgstr ""
+
+msgid "mrWidget|Closed by"
+msgstr ""
+
+msgid "mrWidget|Closes"
+msgstr ""
+
+msgid "mrWidget|Create an issue to resolve them later"
+msgstr ""
+
+msgid "mrWidget|Delete source branch"
+msgstr ""
+
+msgid "mrWidget|Deployment statistics are not available currently"
+msgstr ""
+
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
+msgstr ""
+
+msgid "mrWidget|Did not close"
+msgstr ""
+
+msgid "mrWidget|Email patches"
+msgstr ""
+
+msgid "mrWidget|Failed to load deployment statistics"
+msgstr ""
+
+msgid "mrWidget|Fast-forward merge is not possible. To merge this request, first rebase locally."
+msgstr ""
+
+msgid "mrWidget|Fork merge requests do not create merge request pipelines which validate a post merge result"
+msgstr ""
+
+msgid "mrWidget|If the %{branch} branch exists in your local repository, you can merge this merge request manually using the"
+msgstr ""
+
+msgid "mrWidget|If the %{missingBranchName} branch exists in your local repository, you can merge this merge request manually using the command line"
+msgstr ""
+
+msgid "mrWidget|In the merge train at position %{mergeTrainPosition}"
+msgstr ""
+
+msgid "mrWidget|Loading deployment statistics"
+msgstr ""
+
+msgid "mrWidget|Mentions"
+msgstr ""
+
+msgid "mrWidget|Merge"
+msgstr ""
+
+msgid "mrWidget|Merge failed."
+msgstr ""
+
+msgid "mrWidget|Merge failed: %{mergeError}. Please try again."
+msgstr ""
+
+msgid "mrWidget|Merge locally"
+msgstr ""
+
+msgid "mrWidget|Merge request approved."
+msgstr ""
+
+msgid "mrWidget|Merged by"
+msgstr ""
+
+msgid "mrWidget|More information"
+msgstr ""
+
+msgid "mrWidget|No approval required"
+msgstr ""
+
+msgid "mrWidget|No approval required; you can still approve"
+msgstr ""
+
+msgid "mrWidget|Open in Web IDE"
+msgstr ""
+
+msgid "mrWidget|Pipeline blocked. The pipeline for this merge request requires a manual action to proceed"
+msgstr ""
+
+msgid "mrWidget|Plain diff"
+msgstr ""
+
+msgid "mrWidget|Ready to be merged automatically. Ask someone with write access to this repository to merge this request"
+msgstr ""
+
+msgid "mrWidget|Refresh"
+msgstr ""
+
+msgid "mrWidget|Refresh now"
+msgstr ""
+
+msgid "mrWidget|Refreshing now"
+msgstr ""
+
+msgid "mrWidget|Remove from merge train"
+msgstr ""
+
+msgid "mrWidget|Request to merge"
+msgstr ""
+
+msgid "mrWidget|Resolve WIP status"
+msgstr ""
+
+msgid "mrWidget|Resolve conflicts"
+msgstr ""
+
+msgid "mrWidget|Resolve these conflicts or ask someone with write access to this repository to merge it locally"
+msgstr ""
+
+msgid "mrWidget|Revert"
+msgstr ""
+
+msgid "mrWidget|Revert this merge request in a new merge request"
+msgstr ""
+
+msgid "mrWidget|Revoke approval"
+msgstr ""
+
+msgid "mrWidget|Set by"
+msgstr ""
+
+msgid "mrWidget|The changes were merged into"
+msgstr ""
+
+msgid "mrWidget|The changes were not merged into"
+msgstr ""
+
+msgid "mrWidget|The changes will be merged into"
+msgstr ""
+
+msgid "mrWidget|The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure"
+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 ""
+
+msgid "mrWidget|The source branch is %{commitsBehindLinkStart}%{commitsBehind}%{commitsBehindLinkEnd} the target branch"
+msgstr ""
+
+msgid "mrWidget|The source branch is being deleted"
+msgstr ""
+
+msgid "mrWidget|The source branch will be deleted"
+msgstr ""
+
+msgid "mrWidget|The source branch will not be deleted"
+msgstr ""
+
+msgid "mrWidget|There are merge conflicts"
+msgstr ""
+
+msgid "mrWidget|There are unresolved threads. Please resolve these threads"
+msgstr ""
+
+msgid "mrWidget|This feature merges changes from the target branch to the source branch. You cannot use this feature since the source branch is protected."
+msgstr ""
+
+msgid "mrWidget|This merge request failed to be merged automatically"
+msgstr ""
+
+msgid "mrWidget|This merge request is in the process of being merged"
+msgstr ""
+
+msgid "mrWidget|This merge request will be added to the merge train when pipeline %{linkStart}#%{pipelineId}%{linkEnd} succeeds."
+msgstr ""
+
+msgid "mrWidget|This merge request will start a merge train when pipeline %{linkStart}#%{pipelineId}%{linkEnd} succeeds."
+msgstr ""
+
+msgid "mrWidget|This project is archived, write access has been disabled"
+msgstr ""
+
+msgid "mrWidget|To approve this merge request, please enter your password. This project requires all approvals to be authenticated."
+msgstr ""
+
+msgid "mrWidget|When this merge request is ready, remove the WIP: prefix from the title to allow it to be merged"
+msgstr ""
+
+msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
+msgstr ""
+
+msgid "mrWidget|You can delete the source branch now"
+msgstr ""
+
+msgid "mrWidget|You can merge this merge request manually using the"
+msgstr ""
+
+msgid "mrWidget|Your password"
+msgstr ""
+
+msgid "mrWidget|branch does not exist."
+msgstr ""
+
+msgid "mrWidget|command line"
+msgstr ""
+
+msgid "mrWidget|into"
+msgstr ""
+
+msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
+msgstr ""
+
+msgid "mrWidget|to be merged automatically when the pipeline succeeds"
+msgstr ""
+
+msgid "mrWidget|to start a merge train when the pipeline succeeds"
+msgstr ""
+
+msgid "must be greater than start date"
+msgstr ""
+
+msgid "my-awesome-group"
+msgstr ""
+
+msgid "n/a"
+msgstr ""
+
+msgid "need attention"
+msgstr ""
+
+msgid "needs to be between 10 minutes and 1 month"
+msgstr ""
+
+msgid "never expires"
+msgstr ""
+
+msgid "new merge request"
+msgstr ""
+
+msgid "no contributions"
+msgstr ""
+
+msgid "no expiration"
+msgstr ""
+
+msgid "no one can merge"
+msgstr ""
+
+msgid "none"
+msgstr ""
+
+msgid "not found"
+msgstr ""
+
+msgid "notification emails"
+msgstr ""
+
+msgid "nounSeries|%{firstItem} and %{lastItem}"
+msgstr ""
+
+msgid "nounSeries|%{item}, %{nextItem}"
+msgstr ""
+
+msgid "nounSeries|%{item}, and %{lastItem}"
+msgstr ""
+
+msgid "on track"
+msgstr ""
+
+msgid "open issue"
+msgstr ""
+
+msgid "opened %{timeAgoString} by %{user}"
+msgstr ""
+
+msgid "opened %{timeAgo}"
+msgstr ""
+
+msgid "or"
+msgstr ""
+
+msgid "out of %d total test"
+msgid_plural "out of %d total tests"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "parent"
+msgid_plural "parents"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "password"
+msgstr ""
+
+msgid "pending comment"
+msgstr ""
+
+msgid "pending removal"
+msgstr ""
+
+msgid "per day"
+msgstr ""
+
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
+msgid "pipeline"
+msgstr ""
+
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
+msgid "pod_name cannot be larger than %{max_length} chars"
+msgstr ""
+
+msgid "point"
+msgid_plural "points"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "private"
+msgstr ""
+
+msgid "private key does not match certificate."
+msgstr ""
+
+msgid "processing"
+msgstr ""
+
+msgid "project"
+msgid_plural "projects"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
+msgid "project avatar"
+msgstr ""
+
+msgid "projects"
+msgstr ""
+
+msgid "push to your repository, create pipelines, create issues or add comments. To reduce storage capacity, delete unused repositories, artifacts, wikis, issues, and pipelines."
+msgstr ""
+
+msgid "quick actions"
+msgstr ""
+
+msgid "register"
+msgstr ""
+
+msgid "relates to"
+msgstr ""
+
+msgid "released %{time}"
+msgstr ""
+
+msgid "remaining"
+msgstr ""
+
+msgid "remove"
+msgstr ""
+
+msgid "remove due date"
+msgstr ""
+
+msgid "remove weight"
+msgstr ""
+
+msgid "removed a Zoom call from this issue"
+msgstr ""
+
+msgid "rendered diff"
+msgstr ""
+
+msgid "reply"
+msgid_plural "replies"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "reset it."
+msgstr ""
+
+msgid "resolved the corresponding error and closed the issue."
+msgstr ""
+
+msgid "revised"
+msgstr ""
+
+msgid "score"
+msgstr ""
+
+msgid "security Reports|There was an error creating the merge request"
+msgstr ""
+
+msgid "settings saved, but not activated"
+msgstr ""
+
+msgid "severity|Critical"
+msgstr ""
+
+msgid "severity|High"
+msgstr ""
+
+msgid "severity|Info"
+msgstr ""
+
+msgid "severity|Low"
+msgstr ""
+
+msgid "severity|Medium"
+msgstr ""
+
+msgid "severity|None"
+msgstr ""
+
+msgid "severity|Unknown"
+msgstr ""
+
+msgid "should be greater than or equal to %{access} inherited membership from group %{group_name}"
+msgstr ""
+
+msgid "show %{count} more"
+msgstr ""
+
+msgid "show fewer"
+msgstr ""
+
+msgid "show less"
+msgstr ""
+
+msgid "sign in"
+msgstr ""
+
+msgid "sort:"
+msgstr ""
+
+msgid "source"
+msgstr ""
+
+msgid "source diff"
+msgstr ""
+
+msgid "specified top is not part of the tree"
+msgstr ""
+
+msgid "spendCommand|%{slash_command} will update the sum of the time spent."
+msgstr ""
+
+msgid "started"
+msgstr ""
+
+msgid "started a discussion on %{design_link}"
+msgstr ""
+
+msgid "started on %{timebox_start_date}"
+msgstr ""
+
+msgid "starts on %{timebox_start_date}"
+msgstr ""
+
+msgid "stuck"
+msgstr ""
+
+msgid "success"
+msgstr ""
+
+msgid "suggestPipeline|1/2: Choose a template"
+msgstr ""
+
+msgid "suggestPipeline|2/2: Commit your changes"
+msgstr ""
+
+msgid "suggestPipeline|Commit the changes and your pipeline will automatically run for the first time."
+msgstr ""
+
+msgid "suggestPipeline|We recommend the %{boldStart}Code Quality%{boldEnd} template, which will add a report widget to your Merge Requests. This way you’ll learn about code quality degradations much sooner. %{footerStart} Goodbye technical debt! %{footerEnd}"
+msgstr ""
+
+msgid "syntax is correct"
+msgstr ""
+
+msgid "syntax is incorrect"
+msgstr ""
+
+msgid "tag name"
+msgstr ""
+
+msgid "the following issue(s)"
+msgstr ""
+
+msgid "this document"
+msgstr ""
+
+msgid "to help your contributors communicate effectively!"
+msgstr ""
+
+msgid "to list"
+msgstr ""
+
+msgid "toggle collapse"
+msgstr ""
+
+msgid "toggle dropdown"
+msgstr ""
+
+msgid "triggered"
+msgstr ""
+
+msgid "unicode domains should use IDNA encoding"
+msgstr ""
+
+msgid "updated"
+msgstr ""
+
+msgid "updated %{timeAgo}"
+msgstr ""
+
+msgid "updated %{time_ago}"
+msgstr ""
+
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
+msgid "user avatar"
+msgstr ""
+
+msgid "username"
+msgstr ""
+
+msgid "uses Kubernetes clusters to deploy your code!"
+msgstr ""
+
+msgid "verify ownership"
+msgstr ""
+
+msgid "version %{versionIndex}"
+msgstr ""
+
+msgid "via %{closed_via}"
+msgstr ""
+
+msgid "via merge request %{link}"
+msgstr ""
+
+msgid "view it on GitLab"
+msgstr ""
+
+msgid "view the blob"
+msgstr ""
+
+msgid "view the source"
+msgstr ""
+
+msgid "vulnerability|Add a comment"
+msgstr ""
+
+msgid "vulnerability|Add a comment or reason for dismissal"
+msgstr ""
+
+msgid "vulnerability|Add comment"
+msgstr ""
+
+msgid "vulnerability|Add comment & dismiss"
+msgstr ""
+
+msgid "vulnerability|Dismiss vulnerability"
+msgstr ""
+
+msgid "vulnerability|Save comment"
+msgstr ""
+
+msgid "vulnerability|Undo dismiss"
+msgstr ""
+
+msgid "vulnerability|dismissed"
+msgstr ""
+
+msgid "wiki page"
+msgstr ""
+
+msgid "will be released %{time}"
+msgstr ""
+
+msgid "with %{additions} additions, %{deletions} deletions."
+msgstr ""
+
+msgid "with expiry changing from %{old_expiry} to %{new_expiry}"
+msgstr ""
+
+msgid "with expiry remaining unchanged at %{old_expiry}"
+msgstr ""
+
+msgid "yaml invalid"
+msgstr ""
+
diff --git a/locale/it/gitlab.po b/locale/it/gitlab.po
index d7bd6b7ed4d..b20be7d591f 100644
--- a/locale/it/gitlab.po
+++ b/locale/it/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: it\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:13\n"
+"PO-Revision-Date: 2020-06-08 15:14\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] "%d commento"
msgstr[1] "%d commenti"
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] "%d commit"
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] "%d contribution"
msgstr[1] "%d contribution"
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] "%d altro commento"
msgstr[1] "Altri %d commenti"
+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] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr "%{commit_author_link} fatto %{commit_timeago}"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr "%{filePath} eliminato"
msgid "%{firstLabel} +%{labelCount} more"
msgstr "%{firstLabel} + %{labelCount} più"
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr "I %{group_docs_link_start}Gruppi%{group_docs_link_end} consentono di ges
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr "%{label_for_message} non disponibile"
@@ -370,12 +438,21 @@ msgstr "%{loadingIcon} Partito"
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr "%{lock_path} è bloccato dall'utente GitLab %{lock_user_id}"
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr "%{mrText}, questo issue verrà chiuso automaticamente."
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr "Avatar di %{name}"
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr "(%{mrCount} mergiati)"
@@ -782,6 +874,9 @@ msgstr "404 | Si prega di contattare il proprio amministratore GitLab se credi s
msgid "8 hours"
msgstr "8 ore"
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr "Token di accesso"
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr "Attivo"
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr "Attività"
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|Unknown"
+msgstr ""
+
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr "Confermi di voler resettare il token di controllo di stato?"
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr "Ago"
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr "Documentazione Auto DevOps"
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr "Attiva in impostazioni"
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr "Disponibile"
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr "CI / CD"
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr "Helm Tiller"
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr "Tag"
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr "Creare un token di accesso sul tuo account per eseguire pull o push tram
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr "Timezone del Cron"
-msgid "Cron syntax"
-msgstr "Sintassi Cron"
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr "Definisci un patter personalizzato mediante la sintassi cron"
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr "Dettagli"
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,14 +8991,14 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
-msgstr "Ogni giorno (alle 4 del mattino)"
+msgid "Every day (at %{time})"
+msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
-msgstr "Ogni primo giorno del mese (alle 4 del mattino)"
+msgid "Every month (Day %{day} at %{time})"
+msgstr ""
msgid "Every three months"
msgstr ""
@@ -8627,8 +9009,8 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
-msgstr "Ogni settimana (Di domenica alle 4 del mattino)"
+msgid "Every week (%{weekday} at %{time})"
+msgstr ""
msgid "Everyone"
msgstr ""
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr "Files"
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr "Filtra per messaggio di commit"
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr "Dalla creazione di un issue fino al rilascio in produzione"
msgid "From merge request merge until deploy to production"
msgstr "Dalla richiesta di merge fino effettua il merge fino al rilascio in produzione"
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr "Cronologia"
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr "Gen"
msgid "January"
msgstr "Gennaio"
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr "Giugno"
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr "Leggi di più su"
@@ -12232,6 +12887,9 @@ msgstr "Abbandona il progetto"
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr "Richieste di merge"
@@ -12965,6 +13629,9 @@ msgstr "Richiesta di merge"
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr "Messaggi"
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] "Nuovo Issue"
msgstr[1] "Nuovi Issues"
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr "Nuovo Issue"
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr "Nov"
msgid "November"
msgstr "Novembre"
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr "Solo i membri del progetto possono commentare."
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr "Si apre in una nuova finestra"
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr "Proprietario"
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr "Pipeline per l'ultimo anno"
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr "Pipeline|Specifica i valori delle variabili da utilizzare in questa esecuzione. I valori specificati nel %{settings_link} verranno utilizzati come predefiniti."
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr "Preferenze"
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr "Il Progetto '%{project_name}' è stato aggiornato con successo."
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,8 +16955,8 @@ msgstr "L'esportazione del progetto è stata eliminata."
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr "Il link d'esportazione del progetto è scaduto. Genera una nuova esportazione dalle impostazioni del tuo progetto."
-msgid "Project export started. A download link will be sent by email."
-msgstr "Esportazione del progetto iniziata. Un link di download sarà inviato via email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
+msgstr ""
msgid "Project has too many %{label_for_message} to search"
msgstr ""
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr "Pubblico - il gruppo e tutti i progetti pubblici possono essere visualiz
msgid "Public - The project can be accessed without any authentication."
msgstr "Public - Chiunque può accedere a questo progetto senza alcuna autenticazione."
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr "Attività di Rilascio Correlate"
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr "Richiedi accesso"
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr "Chiavi SSH"
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr "Seleziona formato d'archivio"
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr "Seleziona una branch di destinazione"
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] "Visualizza %d evento"
msgstr[1] "Visualizza %d eventi"
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr "Snippet"
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr "Ordina per"
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr "Cambia branch/tag"
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr "L'insieme di eventi aggiunti ai dati raccolti per quello stadio."
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr "Lo stadio di pre-rilascio mostra il tempo che trascorre da una MR (Richiesta di Merge) completata al suo rilascio in ambiente di produzione. Questa informazione sarà disponibile dal tuo primo rilascio in produzione"
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr "Lo stadio di test mostra il tempo che ogni Pipeline impiega per essere eseguita in ogni Richiesta di Merge correlata. L'informazione sarà disponibile automaticamente quando la tua prima Pipeline avrà finito d'esser eseguita."
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ 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"
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr "adesso"
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] "hr"
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr "Tempo totale di test per tutti i commits/merges"
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr "Carica un nuovo file"
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr "clicca per caricare"
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr "Non ci sono sufficienti dati da mostrare su questo stadio"
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr "Ritira richiesta d'accesso"
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr "Riceverai notifiche per ogni attività"
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr "Riceverai notifiche solo per i commenti ai quale sei stato menzionato"
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr "Non sarai in grado di eseguire pull o push di codice tramite %{protocol} fino a che %{set_password_link} nel tuo account."
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr "Il tuo nome"
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr "fa"
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/ja/gitlab.po b/locale/ja/gitlab.po
index defe692b907..8bced41477f 100644
--- a/locale/ja/gitlab.po
+++ b/locale/ja/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: ja\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 22:46\n"
+"PO-Revision-Date: 2020-06-08 16:58\n"
msgid " %{start} to %{end}"
msgstr " %{start} ã‹ã‚‰ %{end} "
@@ -69,6 +69,14 @@ msgstr "「%{path}ã€ã¯ã€Œ%{ref}ã€ã«å­˜åœ¨ã—ã¾ã›ã‚“ã§ã—ãŸ"
msgid "%d URL scanned"
msgid_plural "%d URLs scanned"
+msgstr[0] "%d 件ã®ã‚¹ã‚­ãƒ£ãƒ³ã•ã‚ŒãŸ URL"
+
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgid "%d changed file"
@@ -77,7 +85,7 @@ msgstr[0] "%d 個ã®å¤‰æ›´ã•ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«"
msgid "%d child epic"
msgid_plural "%d child epics"
-msgstr[0] ""
+msgstr[0] "%d 件ã®å­ã‚¨ãƒ”ック"
msgid "%d code quality issue"
msgid_plural "%d code quality issues"
@@ -87,13 +95,17 @@ msgid "%d comment"
msgid_plural "%d comments"
msgstr[0] "%d 件ã®ã‚³ãƒ¡ãƒ³ãƒˆ"
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] "%d個ã®ã‚³ãƒŸãƒƒãƒˆ"
msgid "%d commit behind"
msgid_plural "%d commits behind"
-msgstr[0] "%d個ã®ã‚³ãƒŸãƒƒãƒˆå¾…ã¡"
+msgstr[0] "%d個ã®ã‚³ãƒŸãƒƒãƒˆé…ã‚Œ"
msgid "%d commit,"
msgid_plural "%d commits,"
@@ -106,9 +118,13 @@ msgid "%d contribution"
msgid_plural "%d contributions"
msgstr[0] "貢献 %d件"
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+
msgid "%d error"
msgid_plural "%d errors"
-msgstr[0] ""
+msgstr[0] "%d 件ã®ã‚¨ãƒ©ãƒ¼"
msgid "%d exporter"
msgid_plural "%d exporters"
@@ -116,7 +132,7 @@ msgstr[0] "%d exporter"
msgid "%d failed"
msgid_plural "%d failed"
-msgstr[0] ""
+msgstr[0] "%d 件ã®å¤±æ•—"
msgid "%d fixed test result"
msgid_plural "%d fixed test results"
@@ -162,6 +178,10 @@ msgid "%d more comment"
msgid_plural "%d more comments"
msgstr[0] "%d 件以上ã®ã‚³ãƒ¡ãƒ³ãƒˆ"
+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] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] "%d件ã®ãƒ—ロジェクト"
@@ -186,6 +206,14 @@ msgid "%d unresolved thread"
msgid_plural "%d unresolved threads"
msgstr[0] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -206,6 +234,9 @@ msgstr "%{commit_author_link} ㌠%{commit_timeago} ã«ã‚³ãƒŸãƒƒãƒˆã—ã¾ã—ãŸ"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} コア"
@@ -279,6 +310,9 @@ msgstr "%{filePath} ãŒå‰Šé™¤ã•ã‚Œã¾ã—ãŸ"
msgid "%{firstLabel} +%{labelCount} more"
msgstr "%{firstLabel} +%{labelCount} ã®è©³ç´°"
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr "%{global_id} 㯠%{expected_type} ã«ã¨ã£ã¦æœ‰åŠ¹ãªIDã§ã¯ã‚ã‚Šã¾ã›ã‚“。"
@@ -288,6 +322,9 @@ msgstr "%{group_docs_link_start}グループ%{group_docs_link_end}を使用ã™ã‚
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr "%{group_name} ã¯ã‚°ãƒ«ãƒ¼ãƒ—管ç†ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’使用ã—ã¾ã™ã€‚ %{group_name} ã«ã‚ˆã£ã¦ç®¡ç†ã•ã‚Œã‚‹æ–°ã—ã„GitLabアカウントを作æˆã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr "%{icon}ã“ã®è­°è«–ã« %{usersTag} 人を追加ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚注æ„ã—ã¦é€²ã‚ã¦ãã ã•ã„。"
@@ -300,6 +337,30 @@ msgstr "%{issuesSize} 件ã®èª²é¡Œ"
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr "%{label_for_message} ã¯åˆ©ç”¨ä¸å¯"
@@ -333,12 +394,21 @@ msgstr "%{loadingIcon} 開始"
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr "%{lock_path} ã¯GitLab ユーザー %{lock_user_id} ã«ã‚ˆã£ã¦ãƒ­ãƒƒã‚¯ã•ã‚Œã¦ã„ã¾ã™"
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr "%{mergeLength}/%{usersLength} 人ãŒãƒžãƒ¼ã‚¸ã§ãã¾ã™"
msgid "%{mrText}, this issue will be closed automatically."
msgstr "%{mrText} ã€ã“ã®èª²é¡Œã¯è‡ªå‹•çš„ã«ã‚¯ãƒ­ãƒ¼ã‚ºã—ã¾ã™ã€‚"
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -354,9 +424,15 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr "%{name}ã®ã‚¢ãƒã‚¿ãƒ¼"
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
-msgstr[0] ""
+msgstr[0] "%{no_of_days} æ—¥"
msgid "%{number_commits_behind} commits behind %{default_branch}, %{number_commits_ahead} commits ahead"
msgstr "%{default_branch} ã‹ã‚‰ %{number_commits_behind} コミットé…ã‚Œã¦ã„ã¦ã€ %{number_commits_ahead} コミット進んã§ã„ã¾ã™ã€‚"
@@ -392,6 +468,12 @@ msgid "%{releases} release"
msgid_plural "%{releases} releases"
msgstr[0] "%{releases} リリース"
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -485,7 +567,7 @@ msgid "%{title} changes"
msgstr "%{title} ã®å¤‰æ›´"
msgid "%{token}..."
-msgstr ""
+msgstr "%{token}..."
msgid "%{totalWeight} total weight"
msgstr ""
@@ -521,7 +603,7 @@ msgid "'%{level}' is not a valid visibility level"
msgstr "'%{level}' ã¯æœ‰åŠ¹ãªå¯è¦–レベルã§ã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "'%{name}' stage already exists"
-msgstr ""
+msgstr "'%{name}'ステージã¯ã™ã§ã«ã‚ã‚Šã¾ã™"
msgid "'%{source}' is not a import source"
msgstr "'%{source}' ã¯ã‚¤ãƒ³ãƒãƒ¼ãƒˆã‚½ãƒ¼ã‚¹ã§ã¯ã‚ã‚Šã¾ã›ã‚“。"
@@ -533,6 +615,9 @@ msgid "(%d closed)"
msgid_plural "(%d closed)"
msgstr[0] "(%d 個ã®ã‚¯ãƒ­ãƒ¼ã‚º)"
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr "(%{mrCount} 個ã®ãƒžãƒ¼ã‚¸æ¸ˆã¿)"
@@ -552,7 +637,7 @@ msgid "(removed)"
msgstr "(除去ã—ã¾ã—ãŸ)"
msgid "(revoked)"
-msgstr ""
+msgstr "(失効)"
msgid "*"
msgstr "*"
@@ -571,10 +656,10 @@ msgstr "+ %{numberOfHiddenAssignees} 以上"
msgid "+%d more"
msgid_plural "+%d more"
-msgstr[0] ""
+msgstr[0] "%d 以上"
msgid "+%{approvers} more approvers"
-msgstr ""
+msgstr "%{approvers} 人以上ã®æ‰¿èªè€…"
msgid "+%{tags} more"
msgstr ""
@@ -719,6 +804,9 @@ msgstr "ã“ã®ãƒšãƒ¼ã‚¸ãŒæ­£ã—ããªã„å ´åˆã€GitLab 管ç†è€…ã«é€£çµ¡ã—ã
msgid "8 hours"
msgstr "8 時間"
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr "1 時間未満"
@@ -749,6 +837,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr "<strong>%{group_name}</strong> グループã®ãƒ¡ãƒ³ãƒãƒ¼"
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr "ソースブランãƒã‚’<strong>削除</strong>"
@@ -758,6 +849,9 @@ msgstr "「Runnerã€ã¯ã‚¸ãƒ§ãƒ–を実行ã™ã‚‹ãƒ—ロセスã§ã™ã€‚å¿…è¦ãªæ•°
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr "ä»»æ„ã®.NET Coreプロジェクト用ã«ã‚«ã‚¹ã‚¿ãƒžã‚¤ã‚ºå¯èƒ½ãªã€.NET Coreコンソールアプリケーションテンプレート"
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr "GitLab ã®ä»£ã‚ã‚Šã« Netlify for CI/CD を使用ã—ã¦ã„ã‚‹ GitBook サイトã§ã™ãŒã€GitLab ã«ã¯ãªã„優れãŸæ©Ÿèƒ½ã‚‚å‚™ãˆã¦ã„ã¾ã™ã€‚"
@@ -789,13 +883,16 @@ msgid "A deleted user"
msgstr "削除ã•ã‚ŒãŸãƒ¦ãƒ¼ã‚¶ãƒ¼"
msgid "A file with '%{file_name}' already exists in %{branch} branch"
-msgstr ""
+msgstr "ファイル '%{file_name}' ã¯æ—¢ã« %{branch} ブランãƒã«å­˜åœ¨ã—ã¾ã™"
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr "フォークã¯ãƒ—ロジェクトã®ã‚³ãƒ”ーã§ã™ã€‚<br />リãƒã‚¸ãƒˆãƒªã‚’フォークã™ã‚‹ã¨ã€å…ƒã®ãƒ—ロジェクトã«å½±éŸ¿ã‚’与ãˆãšã«å¤‰æ›´ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
-msgid "A group represents your organization in GitLab."
-msgstr "グループã¯GitLabã§ã®çµ„織を表ã—ã¾ã™ã€‚"
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
+msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
msgstr "ãŸã ã¡ã«ä¸æ­£åˆ©ç”¨å¯¾å¿œãƒãƒ¼ãƒ ãƒ¡ãƒ³ãƒãƒ¼ã§ã„ãŸã ã„ãŸãƒ¬ãƒãƒ¼ãƒˆã‚’æ‹èª­ã—å‚考ã«ã•ã›ã¦ã„ãŸã ãã¾ã™ã€‚"
@@ -825,10 +922,10 @@ msgid "A plain HTML site that uses Netlify for CI/CD instead of GitLab, but stil
msgstr "GitLab ã®ä»£ã‚ã‚Šã« Netlify for CI/CD を使用ã—ã¦ã„るプレーン HTML サイトã§ã™ãŒã€GitLab ã«ã¯ãªã„優れãŸæ©Ÿèƒ½ã‚‚å‚™ãˆã¦ã„ã¾ã™ã€‚"
msgid "A project boilerplate for Salesforce App development with Salesforce Developer tools."
-msgstr ""
+msgstr "Salesforce Developerツールを使用ã—ãŸ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 "アメリカåˆè¡†å›½ä¿å¥ç¦ç¥‰çœãŒç™ºè¡Œã—ãŸHIPAA監査プロトコルã®å„監査照会ã®èª²é¡Œã‚’å«ã‚€ãƒ—ロジェクト"
msgid "A project is where you house your files (repository), plan your work (issues), and publish your documentation (wiki), %{among_other_things_link}."
msgstr "プロジェクトã¨ã¯ãƒ•ã‚¡ã‚¤ãƒ«ã‚’æ ¼ç´(リãƒã‚¸ãƒˆãƒª) ã—ã€è¨ˆç”»ã‚’ç«‹ã¦(課題)ã€ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã‚’公開(wiki) ã™ã‚‹å ´æ‰€ã§ã™ã€‚ %{among_other_things_link}"
@@ -845,20 +942,20 @@ msgstr "ジョブã®ãƒ­ã‚°ã‹ã‚‰ãƒ†ã‚¹ãƒˆã‚«ãƒãƒ¬ãƒƒã‚¸ã®çµæžœã‚’見ã¤ã‘ã‚‹
msgid "A secure token that identifies an external storage request."
msgstr "外部ストレージリクエストを識別ã™ã‚‹ã€ã‚»ã‚­ãƒ¥ã‚¢ãƒˆãƒ¼ã‚¯ãƒ³"
-msgid "A subscription will 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."
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
msgstr ""
+msgid "A subscription will 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 "サブスクライブã—ãŸãƒ—ロジェクト㮠%{default_branch_docs} ã§æ–°ã—ã„ã‚¿ã‚°ã®ãƒ‘イプラインãŒæ­£å¸¸ã«å®Œäº†ã™ã‚‹ã¨ã€ã‚µãƒ–スクリプションã«ã‚ˆã£ã¦ã€ã“ã®ãƒ—ロジェクトã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆãƒ–ランãƒã§æ–°ã—ã„パイプラインをトリガーã—ã¾ã™ã€‚"
+
msgid "A terraform report was generated in your pipelines."
-msgstr ""
+msgstr "パイプラインã®ä¸­ã§terraformリãƒãƒ¼ãƒˆãŒç”Ÿæˆã•ã‚Œã¾ã—ãŸã€‚"
msgid "A user with write access to the source branch selected this option"
msgstr "ã“ã®ã‚ªãƒ—ションをé¸æŠžã—ãŸã‚½ãƒ¼ã‚¹ãƒ–ランãƒã¸ã®æ›¸ãè¾¼ã¿ã‚’許å¯ã•ã‚ŒãŸãƒ¦ãƒ¼ã‚¶ãƒ¼"
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
-msgstr ""
-
-msgid "API Help"
-msgstr "API ヘルプ"
+msgstr "アクションãŒå¿…è¦ï¼šGitLab Pagesã®ãƒ‰ãƒ¡ã‚¤ãƒ³ '%{domain}'ã¸ã®Let's Encrypt証明書ã®å–得中ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸ"
msgid "API Token"
msgstr "API トークン"
@@ -903,10 +1000,7 @@ msgid "Accept terms"
msgstr "利用è¦ç´„ã«åŒæ„ã™ã‚‹"
msgid "Acceptable for use in this project"
-msgstr ""
-
-msgid "Accepted MR"
-msgstr "承èªã•ã‚ŒãŸãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆ"
+msgstr "ã“ã®ãƒ—ロジェクトã¯ä½¿ç”¨å¯èƒ½"
msgid "Access Tokens"
msgstr "アクセス トークン"
@@ -927,7 +1021,7 @@ msgid "Access to '%{classification_label}' not allowed"
msgstr "'%{classification_label}'ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
msgid "Access to Pages websites are controlled based on the user's membership to a given project. By checking this box, users will be required to be logged in to have access to all Pages websites in your instance."
-msgstr ""
+msgstr "Pages ã® Webサイトã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ã¯ã€ãƒ—ロジェクトã§ä¸Žãˆã‚‰ã‚ŒãŸãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ãƒ¡ãƒ³ãƒãƒ¼ã‚·ãƒƒãƒ—ã«æˆ»ã¥ã„ã¦ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ«ã•ã‚Œã¾ã™ã€‚ã“ã®ãƒœãƒƒã‚¯ã‚¹ã‚’ãƒã‚§ãƒƒã‚¯ã—ãŸå ´åˆã€ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ã‚ãªãŸã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹å†…ã® Pages Webサイトã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ãŸã‚ã«ã€ãƒ­ã‚°ã‚¤ãƒ³ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚ "
msgid "AccessDropdown|Groups"
msgstr "グループ"
@@ -998,20 +1092,14 @@ msgstr "é™çš„オブジェクトトークンã¯ã€ (アーカイブã€ãƒ–ロブã
msgid "AccessTokens|reset it"
msgstr "リセット"
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
-msgstr ""
+msgstr "詳ã—ã見る"
msgid "AccessibilityReport|Message: %{message}"
msgstr ""
msgid "AccessibilityReport|New"
-msgstr ""
+msgstr " æ–°ã—ã„"
msgid "AccessibilityReport|The accessibility scanning found an error of the following type: %{code}"
msgstr ""
@@ -1040,8 +1128,8 @@ msgstr "サービスデスクを有効ã«ã™ã‚‹"
msgid "Active"
msgstr "有効"
-msgid "Active %{type} Tokens (%{token_length})"
-msgstr "有効 %{type} トークン(%{token_length})"
+msgid "Active %{type} (%{token_length})"
+msgstr ""
msgid "Active Sessions"
msgstr "アクティブ セッション"
@@ -1049,6 +1137,9 @@ msgstr "アクティブ セッション"
msgid "Active Users:"
msgstr "アクティブユーザー"
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr "アクティビティー"
@@ -1092,8 +1183,8 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr "Zoom ミーティングを追加"
-msgid "Add a %{type} token"
-msgstr "%{type} ã®ãƒˆãƒ¼ã‚¯ãƒ³ã‚’追加"
+msgid "Add a %{type}"
+msgstr ""
msgid "Add a GPG key"
msgstr "GPGキーを追加"
@@ -1107,6 +1198,9 @@ msgstr "Todoを追加"
msgid "Add a bullet list"
msgstr "箇æ¡æ›¸ãリストを追加"
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr "ã“ã® %{noteableDisplayName} ã¸ä¸€èˆ¬çš„ãªã‚³ãƒ¡ãƒ³ãƒˆã‚’追加。"
@@ -1116,9 +1210,15 @@ msgstr "ã“ã® %{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 "ã‚ãªãŸã® Wiki ã«ãƒ—ロジェクトã«é–¢ã™ã‚‹æƒ…報をå«ã‚€ãƒ›ãƒ¼ãƒ ãƒšãƒ¼ã‚¸ã‚’追加ã™ã‚‹ã¨ã€GitLab ã¯ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®ä»£ã‚ã‚Šã«ãれをã“ã“ã«è¡¨ç¤ºã—ã¾ã™ã€‚"
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr "リンクを追加"
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr "番å·ä»˜ãリストを追加"
@@ -1134,8 +1234,11 @@ msgstr "ã™ã¹ã¦ã®ãƒ¡ãƒ¼ãƒ«ã«è¡¨ç¤ºã™ã‚‹ãƒ†ã‚­ã‚¹ãƒˆã‚’追加ã—ã¾ã™ã€‚ ã
msgid "Add an SSH key"
msgstr "SSH éµã‚’追加"
-msgid "Add an existing issue to the epic."
-msgstr "エピックã«æ—¢å­˜ã®èª²é¡Œã‚’追加"
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
+msgstr ""
msgid "Add an issue"
msgstr "課題追加"
@@ -1156,13 +1259,13 @@ msgid "Add comment now"
msgstr "コメントã™ã‚‹"
msgid "Add domain"
-msgstr ""
+msgstr "ドメインを追加"
msgid "Add email address"
msgstr "メールアドレス追加"
msgid "Add environment"
-msgstr ""
+msgstr "環境ã®è¿½åŠ "
msgid "Add header and footer to emails. Please note that color settings will only be applied within the application interface"
msgstr "メールã«ãƒ˜ãƒƒãƒ€ãƒ¼ã¨ãƒ•ãƒƒã‚¿ãƒ¼ã‚’追加ã—ã¾ã™ã€‚色設定ã¯ã‚¢ãƒ—リケーションインターフェース内ã§ã®ã¿é©ç”¨ã•ã‚Œã¾ã™ã€‚"
@@ -1200,6 +1303,9 @@ msgstr "リアクションã®è¿½åŠ "
msgid "Add request manually"
msgstr "リクエストを手動ã§è¿½åŠ ã—ã¾ã™"
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr "システムフックã®è¿½åŠ "
@@ -1228,7 +1334,7 @@ msgid "Add users to group"
msgstr "ユーザーをグループã¸è¿½åŠ "
msgid "Add variable"
-msgstr ""
+msgstr "変数ã®è¿½åŠ "
msgid "Add webhook"
msgstr "Webhook ã®è¿½åŠ "
@@ -1290,18 +1396,18 @@ msgstr "Zoom ミーティングを追加"
msgid "Adds an issue to an epic."
msgstr "課題をエピックã«è¿½åŠ ã€‚"
-msgid "Adjust your filters/search criteria above."
-msgstr "上記ã®ãƒ•ã‚£ãƒ«ã‚¿ãƒ¼/検索æ¡ä»¶ã‚’調整ã—ã¾ã™ã€‚"
+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 ""
msgid "Admin Area"
msgstr "管ç†è€…エリア"
+msgid "Admin Note"
+msgstr ""
+
msgid "Admin Overview"
msgstr "管ç†è€…用概è¦"
-msgid "Admin Section"
-msgstr "管ç†ã‚»ã‚¯ã‚·ãƒ§ãƒ³"
-
msgid "Admin mode already enabled"
msgstr "管ç†è€…モードã¯æ—¢ã«æœ‰åŠ¹ã§ã™"
@@ -1315,34 +1421,34 @@ msgid "Admin notes"
msgstr "管ç†è€…メモ"
msgid "AdminArea|Active users"
-msgstr ""
+msgstr " アクティブãªãƒ¦ãƒ¼ã‚¶ãƒ¼"
msgid "AdminArea|Billable users"
-msgstr ""
+msgstr "請求ã®å¯èƒ½ãªãƒ¦ãƒ¼ã‚¶ãƒ¼"
msgid "AdminArea|Blocked users"
msgstr ""
msgid "AdminArea|Bots"
-msgstr ""
+msgstr "ボット"
msgid "AdminArea|Developer"
-msgstr ""
+msgstr "開発者"
msgid "AdminArea|Guest"
-msgstr ""
+msgstr "ゲスト"
msgid "AdminArea|Included Free in license"
msgstr ""
msgid "AdminArea|Maintainer"
-msgstr ""
+msgstr "メンテナー"
msgid "AdminArea|Owner"
-msgstr ""
+msgstr "オーナー"
msgid "AdminArea|Reporter"
-msgstr ""
+msgstr "レãƒãƒ¼ã‚¿ãƒ¼"
msgid "AdminArea|Stop all jobs"
msgstr "å…¨ã¦ã®ã‚¸ãƒ§ãƒ–ã‚’åœæ­¢"
@@ -1357,10 +1463,10 @@ msgid "AdminArea|Stopping jobs failed"
msgstr "ジョブã®åœæ­¢ã«å¤±æ•—ã—ã¾ã—ãŸ"
msgid "AdminArea|Total users"
-msgstr ""
+msgstr "全ユーザー"
msgid "AdminArea|Users statistics"
-msgstr ""
+msgstr "ユーザー統計"
msgid "AdminArea|Users with highest role"
msgstr ""
@@ -1396,7 +1502,7 @@ msgid "AdminSettings|Auto DevOps domain"
msgstr "Auto DevOps ドメイン"
msgid "AdminSettings|Elasticsearch, PlantUML, Slack application, Third party offers, Snowplow, Amazon EKS have moved to Settings > General."
-msgstr ""
+msgstr "Elasticsearchã€PlantUMLã€Slackアプリケーションã€ã‚µãƒ¼ãƒ‰ãƒ‘ーティã®ã‚ªãƒ•ã‚¡ãƒ¼ã€Snowplowã€Amazon EKS 㯠設定 > 全般 ã«ç§»å‹•ã—ã¾ã—ãŸã€‚"
msgid "AdminSettings|Enable shared runners for new projects"
msgstr "æ–°ã—ã„プロジェクトã§å…±æœ‰ Runner を有効ã«ã™ã‚‹"
@@ -1405,7 +1511,7 @@ msgid "AdminSettings|Environment variables are protected by default"
msgstr "環境変数ã¯ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§ä¿è­·ã•ã‚Œã¦ã„ã¾ã™"
msgid "AdminSettings|Go to General Settings"
-msgstr ""
+msgstr "一般設定ã«ç§»å‹•"
msgid "AdminSettings|Integrations configured here will automatically apply to all projects on this instance."
msgstr ""
@@ -1429,7 +1535,7 @@ msgid "AdminSettings|Set an instance-wide auto included %{link_start}pipeline co
msgstr "インスタンス全体ã«è‡ªå‹•èª­ã¿è¾¼ã¿ã•ã‚Œã‚‹ %{link_start}パイプライン設定%{link_end} を設定ã—ã¾ã™ã€‚ã“ã®ãƒ‘イプライン設定ã¯ãƒ—ロジェクト独自ã®è¨­å®šã®å¾Œã«å®Ÿè¡Œã•ã‚Œã¾ã™ã€‚"
msgid "AdminSettings|Some settings have moved"
-msgstr ""
+msgstr "一部ã®è¨­å®šã¯ç§»å‹•ã—ã¾ã—ãŸ"
msgid "AdminSettings|Specify a domain to use by default for every project's Auto Review Apps and Auto Deploy stages."
msgstr "ã™ã¹ã¦ã®ãƒ—ロジェクトã®Auto Review AppsãŠã‚ˆã³Auto Deployステージã§ä½¿ç”¨ã™ã‚‹ã€ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒ‰ãƒ¡ã‚¤ãƒ³ã‚’指定ã—ã¾ã™ã€‚"
@@ -1504,7 +1610,7 @@ msgid "AdminUsers|Deactivate User %{username}?"
msgstr "ユーザー %{username} ã‚’éžã‚¢ã‚¯ãƒ†ã‚£ãƒ–ã«ã—ã¾ã™ã‹?"
msgid "AdminUsers|Deactivate user"
-msgstr ""
+msgstr "ユーザーを無効ã«ã™ã‚‹"
msgid "AdminUsers|Deactivated"
msgstr "無効ã«ã—ã¾ã—ãŸ"
@@ -1549,7 +1655,7 @@ msgid "AdminUsers|Personal projects, group and user history will be left intact"
msgstr "個人プロジェクトã€ã‚°ãƒ«ãƒ¼ãƒ—ã€ã¨ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®å±¥æ­´ã¯ãã®ã¾ã¾æ®‹ã‚Šã¾ã™"
msgid "AdminUsers|Reactivating a user will:"
-msgstr ""
+msgstr "ユーザーã®å†æœ‰åŠ¹åŒ–:"
msgid "AdminUsers|Restore user access to the account, including web, Git and API."
msgstr "Web, Git, APIã‚’å«ã‚€ã€ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¸ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚¢ã‚¯ã‚»ã‚¹ã‚’復元ã—ã¾ã™ã€‚"
@@ -1600,19 +1706,19 @@ 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 %{strong_start}block user%{strong_end} feature instead. Once you %{strong_start}Delete user%{strong_end}, it cannot be undone or recovered."
-msgstr ""
+msgstr "ã‚ãªãŸã¯ãƒ¦ãƒ¼ã‚¶ãƒ¼ %{username} を完全ã«å‰Šé™¤ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚ã“ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã«ãƒªãƒ³ã‚¯ã—ã¦ã„ã‚‹ã€èª²é¡Œã€ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã€ãŠã‚ˆã³ã‚°ãƒ«ãƒ¼ãƒ—ã¯ã€ã‚·ã‚¹ãƒ†ãƒ å…¨ä½“ã®ã€Œå¹½éœŠãƒ¦ãƒ¼ã‚¶ãƒ¼ã€ã«è»¢é€ã•ã‚Œã¾ã™ã€‚データã®æ失をé¿ã‘ã‚‹ãŸã‚ã«ã€å‰Šé™¤ã®ä»£ã‚ã‚Šã«%{strong_end} ユーザーã®ãƒ–ロック機能%{strong_start}を使用ã™ã‚‹ã“ã¨ã‚’検討ã—ã¦ãã ã•ã„。%{strong_end}] ユーザーã®å‰Šé™¤ %{strong_start}を実行ã—ãŸå¾Œã§ã€å…ƒã«æˆ»ã™ã“ã¨ã¯ã§ãã¾ã›ã‚“。ã¾ãŸå¾©å…ƒã‚‚ã§ãã¾ã›ã‚“。"
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 %{strong_start}block user%{strong_end} feature instead. Once you %{strong_start}Delete user%{strong_end}, it cannot be undone or recovered."
msgstr ""
msgid "Administration"
-msgstr ""
+msgstr "管ç†"
msgid "Advanced"
msgstr "高度ãªè¨­å®š"
msgid "Advanced Settings"
-msgstr ""
+msgstr "高度ãªè¨­å®š"
msgid "Advanced permissions, Large File Storage and Two-Factor authentication settings."
msgstr "高度ãªæ¨©é™ã€ãƒ©ãƒ¼ã‚¸ãƒ•ã‚¡ã‚¤ãƒ«ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã€2è¦ç´ èªè¨¼ã®è¨­å®š"
@@ -1626,62 +1732,116 @@ msgstr "パスワードã®æ›´æ–°ã«æˆåŠŸã™ã‚‹ã¨ã€ãƒ­ã‚°ã‚¤ãƒ³ç”»é¢ã«ãƒªãƒ€
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr "パスワードを正常ã«æ›´æ–°ã—ãŸå¾Œã€ãƒ­ã‚°ã‚¤ãƒ³ãƒšãƒ¼ã‚¸ã«ãƒªãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆã•ã‚Œã‚‹ã®ã§ã€ãã“ã§æ–°ã—ã„パスワードã§ãƒ­ã‚°ã‚¤ãƒ³ã§ãã¾ã™ã€‚"
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] "アラート"
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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 ""
+
msgid "AlertManagement|End time"
+msgstr "終了時間"
+
+msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|High"
msgstr ""
-msgid "AlertManagement|Events"
+msgid "AlertManagement|Info"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1690,17 +1850,35 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
-msgstr "アラートをå—ä¿¡ã™ã‚‹ãŸã‚ã®ã€ã“ã®ã‚¨ãƒ³ãƒ‰ãƒã‚¤ãƒ³ãƒˆã®è¨­å®šã® %{linkStart} 詳細をã¿ã‚‹ %{linkEnd}"
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
+msgstr ""
+
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
-msgstr "アラートソースã¯ã€ãã‚Œãžã‚Œæ¬¡ã®URLã¨èªè¨¼ã‚­ãƒ¼ã‚’使用ã—ã¦èªè¨¼ã—ã¦ãã ã•ã„。"
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
+msgstr ""
msgid "Alerts"
msgstr "アラート"
@@ -1718,7 +1896,7 @@ msgid "All %{replicableType} are being scheduled for %{action}"
msgstr ""
msgid "All (default)"
-msgstr ""
+msgstr "å…¨ã¦(デフォルト)"
msgid "All Members"
msgstr "ã™ã¹ã¦ã®ãƒ¡ãƒ³ãƒãƒ¼"
@@ -1730,13 +1908,13 @@ msgid "All changes are committed"
msgstr "ã™ã¹ã¦ã®å¤‰æ›´ãŒã‚³ãƒŸãƒƒãƒˆã•ã‚Œã¦ã„ã¾ã™"
msgid "All default stages are currently visible"
-msgstr ""
+msgstr "ç¾åœ¨ã€ã™ã¹ã¦ã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã‚¹ãƒ†ãƒ¼ã‚¸ã‚’表示ã—ã¦ã„ã¾ã™"
msgid "All email addresses will be used to identify your commits."
msgstr "ã™ã¹ã¦ã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã¯ã‚ãªãŸã®ã‚³ãƒŸãƒƒãƒˆã‚’識別ã™ã‚‹ãŸã‚ã«ä½¿ç”¨ã•ã‚Œã¾ã™ã€‚"
msgid "All environments"
-msgstr ""
+msgstr "ã™ã¹ã¦ã®ç’°å¢ƒ"
msgid "All features are enabled for blank projects, from templates, or when importing, but you can disable them afterward in the project settings."
msgstr "空ã®ãƒ—ロジェクトã€ãƒ†ãƒ³ãƒ—レートã‹ã‚‰ã€ã¾ãŸã¯ã‚¤ãƒ³ãƒãƒ¼ãƒˆæ™‚ã«ã™ã¹ã¦ã®æ©Ÿèƒ½ãŒæœ‰åŠ¹ã«ãªã£ã¦ã„ã¾ã™ãŒã€å¾Œã§ãƒ—ロジェクト設定ã§ç„¡åŠ¹ã«ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
@@ -1790,7 +1968,7 @@ msgid "Allow owners to manage default branch protection per group"
msgstr ""
msgid "Allow owners to manually add users outside of LDAP"
-msgstr ""
+msgstr "オーナーãŒLDAPã¨é–¢ä¿‚ãªãユーザーを手動ã§è¿½åŠ ã§ãるよã†ã«ã™ã‚‹"
msgid "Allow projects within this group to use Git LFS"
msgstr "ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—内ã®ãƒ—ロジェクト㫠Git LFS を使用ã§ãるよã†ã«ã™ã‚‹"
@@ -1873,6 +2051,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr "アプリケーション㮠%{link_to_client} ãŒã‚ãªãŸã® 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 ""
+
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 "GitLab ユーザフィールドãŒç©ºã®å ´åˆã€ã™ã¹ã¦ã®å•é¡Œã¨ã‚³ãƒ¡ãƒ³ãƒˆã®èª¬æ˜Žã« FogBugz ユーザã®ãƒ•ãƒ«ãƒãƒ¼ãƒ  (例ãˆã°ã€By John Smith)を追加ã—ã¾ã™ã€‚ã¾ãŸã€ã“れらã®å•é¡Œã‚„コメントをプロジェクト作æˆè€…ã«é–¢é€£ä»˜ã‘ã‚‹ã‹ã€ã¾ãŸã¯å‰²ã‚Šå½“ã¦ã¾ã™ã€‚"
@@ -1934,7 +2115,7 @@ msgid "An error occurred while deleting the comment"
msgstr "コメントã®å‰Šé™¤ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "An error occurred while deleting the pipeline."
-msgstr ""
+msgstr "パイプラインã®å‰Šé™¤ã®éš›ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "An error occurred while detecting host keys"
msgstr "ホストキーã®æ¤œå‡ºä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
@@ -1997,7 +2178,7 @@ msgid "An error occurred while fetching the job log."
msgstr "ã“ã®ã‚¸ãƒ§ãƒ–ã®ãƒ­ã‚°ã‚’フェッãƒã™ã‚‹é–“ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "An error occurred while fetching the job trace."
-msgstr ""
+msgstr "ジョブトレースã®å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "An error occurred while fetching the job."
msgstr "ã“ã®ã‚¸ãƒ§ãƒ–ã®å–å¾—ã§ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
@@ -2006,7 +2187,7 @@ msgid "An error occurred while fetching the jobs."
msgstr "ジョブã®å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "An error occurred while fetching the latest pipeline."
-msgstr ""
+msgstr "最新ã®ãƒ‘イプラインã®å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "An error occurred while fetching the pipeline."
msgstr "パイプラインã®å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
@@ -2021,7 +2202,7 @@ msgid "An error occurred while generating a username. Please try again."
msgstr "ユーザーåã®ç”Ÿæˆä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
msgid "An error occurred while getting files for - %{branchId}"
-msgstr ""
+msgstr "%{branchId} ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
msgid "An error occurred while getting projects"
msgstr "プロジェクトã®å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
@@ -2033,14 +2214,11 @@ msgid "An error occurred while initializing path locks"
msgstr "パスロックã®åˆæœŸåŒ–中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
msgid "An error occurred while loading all the files."
-msgstr ""
+msgstr "ã™ã¹ã¦ã®ãƒ•ã‚¡ã‚¤ãƒ«ã®èª­è¾¼ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "An error occurred while loading chart data"
msgstr "グラフデータã®èª­ã¿è¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr "コミットシグãƒãƒãƒ£ã®èª­è¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
@@ -2054,12 +2232,15 @@ msgid "An error occurred while loading filenames"
msgstr "ファイルåã®èª­ã¿è¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
msgid "An error occurred while loading group members."
-msgstr ""
+msgstr "グループメンãƒãƒ¼ã®èª­ã¿è¾¼ã‚€é–“ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ."
msgid "An error occurred while loading issues"
msgstr "課題ã®èª­ã¿è¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
msgid "An error occurred while loading merge requests."
+msgstr "マージリクエストã®ãƒ­ãƒ¼ãƒ‰ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
+
+msgid "An error occurred while loading milestones"
msgstr ""
msgid "An error occurred while loading terraform report"
@@ -2072,25 +2253,25 @@ msgid "An error occurred while loading the file"
msgstr "ファイルã®èª­ã¿è¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
msgid "An error occurred while loading the file content."
-msgstr ""
+msgstr "ファイルã®å†…容を読込中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "An error occurred while loading the file."
-msgstr ""
+msgstr "ファイルã®ãƒ­ãƒ¼ãƒ‰ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "An error occurred while loading the file. Please try again later."
msgstr ""
msgid "An error occurred while loading the merge request changes."
-msgstr ""
+msgstr "マージリクエストã®å¤‰æ›´ã‚’読込中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "An error occurred while loading the merge request version data."
-msgstr ""
+msgstr "マージリクエストã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を読込中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "An error occurred while loading the merge request."
-msgstr ""
+msgstr "マージリクエストã®ãƒ­ãƒ¼ãƒ‰ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "An error occurred while loading the pipelines jobs."
-msgstr ""
+msgstr "パイプラインジョブã®ãƒ­ãƒ¼ãƒ‰ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "An error occurred while loading the subscription details."
msgstr "サブスクリプションã®è©³ç´°ã‚’ロード中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
@@ -2137,6 +2318,9 @@ msgstr "承èªè¨­å®šã®ä¿å­˜ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr "テンプレートã®ä¿å­˜ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚テンプレートãŒå­˜åœ¨ã™ã‚‹ã‹ç¢ºèªã—ã¦ãã ã•ã„。"
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr "通知ã®è³¼èª­ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
@@ -2173,9 +2357,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr "課題ã¯ã€ãƒ—ロジェクトã§è­°è«–ã™ã‚‹å¿…è¦ãŒã‚ã‚‹ãƒã‚°ã€todoã€ã¾ãŸã¯æ©Ÿèƒ½ãƒªã‚¯ã‚¨ã‚¹ãƒˆã§ã‚ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚ãã®ä¸Šã€èª²é¡Œã¯æ¤œç´¢ã§ãã€ãƒ•ã‚£ãƒ«ã‚¿ã§ãã¾ã™ã€‚"
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr "プロジェクト環境ã®ç¢ºèªä¸­ã«äºˆæœŸã—ãªã„エラーãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
@@ -2191,6 +2381,9 @@ msgstr "Web ターミナルã®èµ·å‹•ä¸­ã«äºˆæœŸã—ãªã„エラーãŒç™ºç”Ÿã—ã
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr "Web ターミナルã®åœæ­¢ä¸­ã«äºˆæœŸã—ãªã„エラーãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr "アクセス解æž"
@@ -2200,6 +2393,9 @@ msgstr "Webアプリケーションã®ãƒ¬ãƒ“ューãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’分æžã—ã¾
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2224,12 +2420,6 @@ msgstr "ä»»æ„ã®"
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr "ä»»æ„ã®ãƒ©ãƒ™ãƒ«"
-
-msgid "Any Milestone"
-msgstr "ä»»æ„ã®ãƒžã‚¤ãƒ«ã‚¹ãƒˆãƒ¼ãƒ³"
-
msgid "Any branch"
msgstr ""
@@ -2239,9 +2429,15 @@ msgstr "資格ã®ã‚るユーザー"
msgid "Any encrypted tokens"
msgstr "æš—å·åŒ–済ã¿ãƒˆãƒ¼ã‚¯ãƒ³"
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr "ã“ã®ãƒ—ロジェクトã®é–‹ç™ºè€…ã¾ãŸã¯ãれ以上ã®æ¨©é™ã‚’æŒã¤ãƒ¡ãƒ³ãƒãƒ¼ã€‚"
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr "ä»»æ„ã®ãƒãƒ¼ãƒ ã‚¹ãƒšãƒ¼ã‚¹"
@@ -2305,6 +2501,9 @@ msgstr "ラベルをé©ç”¨"
msgid "Apply a template"
msgstr "テンプレートをé©ç”¨"
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr "æ案をé©ç”¨"
@@ -2358,7 +2557,7 @@ msgid "ApprovalRule|Name"
msgstr "åå‰"
msgid "ApprovalRule|No. approvals required"
-msgstr "ã„ã„ãˆã€‚承èªãŒå¿…è¦ã§ã™ã€‚"
+msgstr "å¿…è¦ãªæ‰¿èªã®æ•°"
msgid "ApprovalRule|Rule name"
msgstr "ルールå"
@@ -2369,12 +2568,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr "例:QAã€ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ãªã©"
-msgid "Approvals"
-msgstr "承èª"
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr "承èªã™ã‚‹"
@@ -2384,17 +2577,23 @@ msgstr "マージリクエストを承èªã™ã‚‹"
msgid "Approve the current merge request."
msgstr "ç¾åœ¨ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’承èªã™ã‚‹ã€‚"
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr "ç¾åœ¨ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã¯æ‰¿èªæ¸ˆã§ã™ã€‚"
-msgid "Approver"
+msgid "Approved-By"
msgstr ""
+msgid "Approver"
+msgstr "承èªè€…"
+
msgid "Approvers"
-msgstr ""
+msgstr "承èªè€…"
msgid "Apr"
msgstr "4月"
@@ -2424,7 +2623,7 @@ 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}"
-msgstr ""
+msgstr "プロジェクトをアーカイブã«ã™ã‚‹ã¨ã€ãƒ—ロジェクトã¯å®Œå…¨ã«èª­ã¿å–り専用ã«ãªã‚Šã¾ã™ã€‚ ã¾ãŸã€ãƒ€ãƒƒã‚·ãƒ¥ãƒœãƒ¼ãƒ‰ã‹ã‚‰è¡¨ç¤ºã•ã‚Œãšã€æ¤œç´¢ã§ã‚‚表示ã•ã‚Œã¾ã›ã‚“。 %{strong_start}ã“ã®ãƒªãƒã‚¸ãƒˆãƒªã«ã¯ã‚³ãƒŸãƒƒãƒˆã§ãã¾ã›ã‚“ã—ã€èª²é¡Œã‚„コメントã¾ãŸä»–ã®ã‚¨ãƒ³ãƒ†ã‚£ãƒ†ã‚£ã‚’作æˆã§ãã¾ã›ã‚“。 %{strong_end}"
msgid "Are you setting up GitLab for a company?"
msgstr "ä¼æ¥­å‘ã‘ã« GitLab をセットアップã—ã¦ã„ã¾ã™ã‹ï¼Ÿ"
@@ -2463,7 +2662,7 @@ msgid "Are you sure you want to delete this pipeline schedule?"
msgstr "ã“ã®ãƒ‘イプラインスケジュールを削除ã—ã¾ã™ã‹ï¼Ÿ"
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 "ã“ã®ãƒ‘イプラインを削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿã“ã‚Œã«ã‚ˆã‚Šã€ã™ã¹ã¦ã®ãƒ‘イプラインキャッシュãŒæœŸé™åˆ‡ã‚Œã«ãªã‚Šã€ãƒ“ルドã€ãƒ­ã‚°ã€ã‚¢ãƒ¼ãƒ†ã‚£ãƒ•ã‚¡ã‚¯ãƒˆã€ãƒˆãƒªã‚¬ãƒ¼ãªã©ã®é–¢é€£ã‚ªãƒ–ジェクトãŒã™ã¹ã¦å‰Šé™¤ã•ã‚Œã¾ã™ã€‚ã“ã®ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã¯å…ƒã«æˆ»ã›ã¾ã›ã‚“。"
msgid "Are you sure you want to deploy this environment?"
msgstr ""
@@ -2481,7 +2680,7 @@ msgid "Are you sure you want to lose your issue information?"
msgstr "本当ã«èª²é¡Œæƒ…報を削除ã—ã¾ã™ã‹?"
msgid "Are you sure you want to merge immediately?"
-msgstr ""
+msgstr "本当ã«ã™ãã«ãƒžãƒ¼ã‚¸ã—ã¾ã™ã‹ï¼Ÿ"
msgid "Are you sure you want to permanently delete this license?"
msgstr "ã“ã®ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã‚’完全ã«å‰Šé™¤ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
@@ -2498,6 +2697,9 @@ msgstr "ã“ã® %{group_name} を削除ã—ã¦ã‚ˆã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
msgid "Are you sure you want to remove the attachment?"
msgstr "添付ファイルを削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr "ã“ã® ID を削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
@@ -2510,8 +2712,8 @@ msgstr "本当ã«SCIMトークンをリセットã—ã¦ã‚ˆã‚ã—ã„ã§ã™ã‹ï¼Ÿæ–
msgid "Are you sure you want to reset the health check token?"
msgstr "本当ã«ãƒ˜ãƒ«ã‚¹ãƒã‚§ãƒƒã‚¯ãƒˆãƒ¼ã‚¯ãƒ³ã‚’リセットã—ã¾ã™ã‹ï¼Ÿ"
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
-msgstr "本当ã«ã€ã“ã® %{type} トークンを無効ã«ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹? ã“ã®æ“作ã¯å…ƒã«æˆ»ã™ã“ã¨ãŒã§ãã¾ã›ã‚“。"
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
+msgstr ""
msgid "Are you sure you want to revoke this nickname?"
msgstr "ã“ã®ãƒ‹ãƒƒã‚¯ãƒãƒ¼ãƒ ã‚’å–り消ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
@@ -2535,13 +2737,13 @@ msgid "Are you sure? Removing this GPG key does not affect already signed commit
msgstr "本当ã«ã‚ˆã‚ã—ã„ã§ã™ã‹ï¼Ÿã“ã®GPGキーを削除ã—ã¦ã‚‚ã€ã™ã§ã«ç½²åã•ã‚Œã¦ã„るコミットã«ã¯å½±éŸ¿ã—ã¾ã›ã‚“。"
msgid "Are you sure? The device will be signed out of GitLab."
-msgstr ""
+msgstr "よã‚ã—ã„ã§ã™ã‹ï¼Ÿãã®ãƒ‡ãƒã‚¤ã‚¹ã¯GitLabã‹ã‚‰ã‚µã‚¤ãƒ³ã‚¢ã‚¦ãƒˆã•ã‚Œã¾ã™ã€‚"
msgid "Are you sure? This will invalidate your registered applications and U2F devices."
msgstr "本当ã«å®Ÿè¡Œã—ã¾ã™ã‹? ã“ã‚Œã¯ç™»éŒ²ã•ã‚ŒãŸã‚¢ãƒ—リケーション㨠U2Fデãƒã‚¤ã‚¹ã‚’無効ã«ã—ã¾ã™ã€‚"
msgid "Arrange charts"
-msgstr ""
+msgstr "ãƒãƒ£ãƒ¼ãƒˆã®ã‚¢ãƒ¬ãƒ³ã‚¸"
msgid "Artifact"
msgstr "アーティファクト"
@@ -2616,7 +2818,7 @@ msgid "Assign yourself to this issue"
msgstr "ã“ã®èª²é¡Œã‚’自分ã«å‰²ã‚Šå½“ã¦ã¾ã™"
msgid "Assigned %{assignee_users_sentence}."
-msgstr ""
+msgstr "%{assignee_users_sentence} を割り当ã¦ã¾ã—ãŸã€‚"
msgid "Assigned Issues"
msgstr "割り当ã¦ã‚‰ã‚ŒãŸèª²é¡Œ"
@@ -2624,12 +2826,15 @@ msgstr "割り当ã¦ã‚‰ã‚ŒãŸèª²é¡Œ"
msgid "Assigned Merge Requests"
msgstr "割り当ã¦ã‚‰ã‚ŒãŸãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆ"
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr "自分ã«å‰²ã‚Šå½“ã¦ã‚‹"
msgid "Assignee"
msgid_plural "%d Assignees"
-msgstr[0] ""
+msgstr[0] "%d 人ã®æ‹…当者"
msgid "Assignee lists not available with your current license"
msgstr "ç¾åœ¨ã®ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã§ã¯æ‹…当者リストを利用ã§ãã¾ã›ã‚“"
@@ -2641,7 +2846,7 @@ msgid "Assignee(s)"
msgstr "担当者"
msgid "Assigns %{assignee_users_sentence}."
-msgstr ""
+msgstr "%{assignee_users_sentence} を割り当ã¦ã¾ã™ã€‚"
msgid "At least one approval from a code owner is required to change files matching the respective CODEOWNER rules."
msgstr "ãã‚Œãžã‚Œã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’変更ã™ã‚‹ã«ã¯ã€CODEOWNERã®ãƒ«ãƒ¼ãƒ«ã«ä¸€è‡´ã™ã‚‹ã€å°‘ãªãã¨ã‚‚1åã®ã‚³ãƒ¼ãƒ‰æ‰€æœ‰è€…ã‹ã‚‰ã®æ‰¿èªãŒå¿…è¦ã§ã™ã€‚"
@@ -2653,7 +2858,7 @@ msgid "At least one of group_id or project_id must be specified"
msgstr "group_id ã¾ãŸã¯ project_id ã‚’1ã¤ä»¥ä¸ŠæŒ‡å®šã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™"
msgid "At risk"
-msgstr ""
+msgstr "å±é™º"
msgid "Attach a file"
msgstr "ファイルを添付"
@@ -2681,7 +2886,7 @@ msgid "AuditEvents|Action"
msgstr "アクション"
msgid "AuditEvents|At"
-msgstr ""
+msgstr "日時"
msgid "AuditEvents|Target"
msgstr "ターゲット"
@@ -2698,15 +2903,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr "8月"
@@ -2764,6 +2987,9 @@ msgstr "承èªã™ã‚‹"
msgid "Authorize %{link_to_client} to use your account?"
msgstr "ã‚ãªãŸã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã« %{link_to_client} を承èªã—ã¾ã™ã‹ï¼Ÿ"
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr "%{new_chat_name} ãŒæ‰¿èªã•ã‚Œã¾ã—ãŸ"
@@ -2785,9 +3011,6 @@ msgstr "Auto DevOps ãŒæœ‰åŠ¹ã§ã™"
msgid "Auto DevOps, runners and job artifacts"
msgstr "Auto DevOps, Runner,ãŠã‚ˆã³æˆæžœç‰©"
-msgid "Auto License Compliance"
-msgstr "自動ライセンスコンプライアンス"
-
msgid "Auto stop successfully canceled."
msgstr "自動åœæ­¢æ©Ÿèƒ½ã‚’正常ã«ã‚­ãƒ£ãƒ³ã‚»ãƒ«ã—ã¾ã—ãŸã€‚"
@@ -2795,17 +3018,20 @@ msgid "Auto-cancel redundant, pending pipelines"
msgstr "冗長・ä¿ç•™ä¸­ã®ãƒ‘イプラインを自動キャンセル"
msgid "Auto-close referenced issues on default branch"
-msgstr ""
+msgstr "デフォルトã®ãƒ–ランãƒã§å‚ç…§ã•ã‚Œã¦ã„る課題を自動的ã«çµ‚了ã—ã¾ã™ã€‚"
msgid "AutoDevOps|Auto DevOps"
msgstr "Auto DevOps"
msgid "AutoDevOps|Auto DevOps can automatically build, test, and deploy applications based on predefined continuous integration and delivery configuration. %{auto_devops_start}Learn more about Auto DevOps%{auto_devops_end} or use our %{quickstart_start}quick start guide%{quickstart_end} to get started right away."
-msgstr ""
+msgstr "Auto DevOps ã¯ã‚らã‹ã˜ã‚定義ã•ã‚ŒãŸç¶™ç¶šçš„インテグレーションã¨ãƒ‡ãƒªãƒãƒªãƒ¼ã®è¨­å®šã«åŸºã¥ã„ã¦ã€ã‚¢ãƒ—リケーションを自動的ã«ãƒ“ルドã€ãƒ†ã‚¹ãƒˆã€ãƒ‡ãƒ—ロイã—ã¾ã™ã€‚ %{auto_devops_start}Auto DevOps ã®è©³ç´°%{auto_devops_end} ã‚’å‚ç…§ã—ã¦ãã ã•ã„。ã¾ãŸã¯%{quickstart_start} クイックスタートガイド %{quickstart_end} ã§æ­£ã—ã„方法を学ã³ã¾ã—ょã†ã€‚"
msgid "AutoDevOps|Auto DevOps documentation"
msgstr "Auto DevOps ドキュメント"
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr "設定を有効ã«ã™ã‚‹"
@@ -2831,11 +3057,14 @@ msgid "Autocomplete usage hint"
msgstr "オートコンプリート使用方法ã®ãƒ’ント"
msgid "Automatic certificate management using %{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end}"
-msgstr ""
+msgstr "%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end} を用ã„ã¦è‡ªå‹•çš„ã«è¨¼æ˜Žæ›¸ã‚’管ç†"
msgid "Automatic certificate management using Let's Encrypt"
msgstr "Let's Encryptを用ã„ãŸè‡ªå‹•è¨¼æ˜Žæ›¸ç®¡ç†"
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr "自動的ã«ã€ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®å†…部ユーザーã¨ã—ã¦ãƒžãƒ¼ã‚¯ã—ã¾ã—ãŸã€‚"
@@ -2851,6 +3080,9 @@ msgstr "注æ„"
msgid "Available"
msgstr "利用å¯èƒ½"
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr "利用å¯èƒ½ãªã‚°ãƒ«ãƒ¼ãƒ— Runner:%{runners}"
@@ -3011,7 +3243,7 @@ msgid "Below are examples of regex for existing tools:"
msgstr "以下ã®ã‚‚ã®ã¯ã€æ—¢å­˜ã®æ­£è¦è¡¨ç¾ãƒ„ールã®ä¾‹ã§ã™:"
msgid "Below are the fingerprints for the current instance SSH host keys."
-msgstr ""
+msgstr "ç¾åœ¨ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã®SSHホストキーã®ãƒ•ã‚£ãƒ³ã‚¬ãƒ¼ãƒ—リントã§ã™ã€‚"
msgid "Below you will find all the groups that are public."
msgstr "以下ã«å…¬é–‹ã•ã‚Œã¦ã„る全グループを表示ã—ã¾ã™ã€‚"
@@ -3059,7 +3291,7 @@ msgid "BillingPlans|Your GitLab.com trial expired on %{expiration_date}. You can
msgstr "GitLab.com ã®è©¦ç”¨ç‰ˆã¯ %{expiration_date} ã«æœŸé™åˆ‡ã‚Œã«ãªã‚Šã¾ã—ãŸã€‚ 以下ã®ã‚¢ãƒƒãƒ—グレードã«ã‚ˆã‚Šã€ã„ã¤ã§ã‚‚ゴールド機能ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ã‚’復元ã§ãã¾ã™ã€‚"
msgid "BillingPlans|billed annually at %{price_per_year}"
-msgstr ""
+msgstr "å¹´é¡%{price_per_year} 請求ã•ã‚Œã¾ã™"
msgid "BillingPlans|frequently asked questions"
msgstr "FAQ 集"
@@ -3086,7 +3318,7 @@ msgid "Blocked issue"
msgstr ""
msgid "Blocks"
-msgstr ""
+msgstr "ブロック"
msgid "Blog"
msgstr "ブログ"
@@ -3101,7 +3333,7 @@ msgid "Board scope"
msgstr "ボードスコープ"
msgid "Board scope affects which issues are displayed for anyone who visits this board"
-msgstr ""
+msgstr "ボードã®ç¯„囲ã¯ã€ã“ã®ãƒœãƒ¼ãƒ‰ã«ã‚¢ã‚¯ã‚»ã‚¹ã—ãŸä»»æ„ã®äººã«è¡¨ç¤ºã•ã‚Œã‚‹ã€èª²é¡Œã«å½±éŸ¿ã—ã¾ã™"
msgid "BoardBlankState|Add default lists"
msgstr "デフォルトリストを追加"
@@ -3110,7 +3342,7 @@ msgid "BoardBlankState|Add the following default lists to your Issue Board with
msgstr "1クリックã§èª²é¡Œãƒœãƒ¼ãƒ‰ã«ä»¥ä¸‹ã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆãƒªã‚¹ãƒˆã‚’追加ã—ã¾ã™ã€‚"
msgid "BoardBlankState|Nevermind, I'll use my own"
-msgstr ""
+msgstr "æ°—ã«ã—ãªã„ã€è‡ªåˆ†ã®ã‚‚ã®ã‚’使用ã—ã¾ã™"
msgid "BoardBlankState|Starting out with the default set of lists will get you right on the way to making the most of your board."
msgstr "デフォルトã®ãƒªã‚¹ãƒˆã‚»ãƒƒãƒˆã‹ã‚‰å§‹ã‚ã‚‹ã¨ã€ãƒœãƒ¼ãƒ‰ã‚’最大é™ã«æ´»ç”¨ã™ã‚‹ãŸã‚ã®æ­£ã—ã„æ–¹ã§åˆ©ç”¨ã§ãã¾ã™ã€‚"
@@ -3122,16 +3354,16 @@ msgid "Boards and Board Lists"
msgstr ""
msgid "Boards|Collapse"
-msgstr ""
+msgstr "折りãŸãŸã¿"
msgid "Boards|Edit board"
msgstr "ボードを編集"
msgid "Boards|Expand"
-msgstr ""
+msgstr "å…¨ã¦è¡¨ç¤º"
msgid "Boards|View scope"
-msgstr ""
+msgstr "スコープ表示"
msgid "Branch"
msgstr "ブランãƒ"
@@ -3302,7 +3534,7 @@ msgid "Browse Files"
msgstr "ファイルを表示"
msgid "Browse artifacts"
-msgstr ""
+msgstr "アーティファクトをブラウズã™ã‚‹"
msgid "Browse files"
msgstr "ファイルを表示"
@@ -3328,23 +3560,23 @@ msgstr "課題ã®é‡ã¿ã‚’é–‹ã"
msgid "BurndownChartLabel|Open issues"
msgstr "未解決ã®èª²é¡Œ"
+msgid "Burnup chart"
+msgstr ""
+
msgid "Business"
msgstr "ビジãƒã‚¹"
msgid "Business metrics (Custom)"
msgstr "ビジãƒã‚¹ãƒ¡ãƒˆãƒªã‚¯ã‚¹ï¼ˆã‚«ã‚¹ã‚¿ãƒ ï¼‰"
-msgid "Buy EE"
-msgstr "EE版を購入"
-
-msgid "Buy GitLab Enterprise Edition"
-msgstr "GitLabエンタープライズエディションを購入"
+msgid "Buy License"
+msgstr ""
msgid "Buy more Pipeline minutes"
msgstr ""
msgid "By %{user_name}"
-msgstr ""
+msgstr "%{user_name} ã«ã‚ˆã‚‹"
msgid "By default GitLab sends emails in HTML and plain text formats so mail clients can choose what format to use. Disable this option if you only want to send emails in plain text format."
msgstr "デフォルトã§ã¯ã€GitLabã¯HTMLå½¢å¼ã¨ãƒ—レーンテキスト形å¼ã®ä¸¡ãƒ•ã‚©ãƒ¼ãƒžãƒƒãƒˆã®ãƒ¡ãƒ¼ãƒ«ã‚’é€ä¿¡ã—ã¾ã™ã€‚ãã®ãŸã‚ã€ãƒ¡ãƒ¼ãƒ«ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆã¯ã©ã¡ã‚‰ã®ãƒ•ã‚©ãƒ¼ãƒžãƒƒãƒˆã‚’表示ã™ã‚‹ã‹ã‚’é¸ã¹ã¾ã™ã€‚ã‚‚ã—プレーンテキスト形å¼ã ã‘ã§ãƒ¡ãƒ¼ãƒ«ã‚’é€ä¿¡ã—ãŸã„å ´åˆã¯ã€ã“ã®ã‚ªãƒ—ションを無効ã«ã—ã¾ã™"
@@ -3361,8 +3593,8 @@ msgstr "変更履歴"
msgid "CI / CD"
msgstr "CI / CD"
-msgid "CI / CD Charts"
-msgstr "CI / CD ãƒãƒ£ãƒ¼ãƒˆ"
+msgid "CI / CD Analytics"
+msgstr ""
msgid "CI / CD Settings"
msgstr "CI / CD 設定"
@@ -3370,6 +3602,9 @@ msgstr "CI / CD 設定"
msgid "CI Lint"
msgstr "CI Lint"
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr "CI 変数"
@@ -3388,6 +3623,9 @@ msgstr "外部リãƒã‚¸ãƒˆãƒªç”¨ CI/CD"
msgid "CI/CD settings"
msgstr "CI/CD 設定"
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr "Auto DevOps"
@@ -3416,10 +3654,7 @@ msgid "CICD|The Auto DevOps pipeline will run if no alternative CI configuration
msgstr "ãã®ä»–ã« CI 設定ファイルãŒè¦‹ã¤ã‹ã‚‰ãªã„å ´åˆã€Auto DevOps パイプラインãŒå®Ÿè¡Œã•ã‚Œã¾ã™ã€‚"
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
-msgstr ""
-
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
+msgstr "ã‚ãªãŸã®ãƒ‡ãƒ—ロイ戦略を動作ã•ã›ã‚‹ã«ã¯ã€%{base_domain_link_start} ベースドメイン %{link_end} ã‚’ %{kubernetes_cluster_link_start} Kubernetesクラスター %{link_end} ã«è¿½åŠ ã—ã¦ãã ã•ã„。"
msgid "CICD|group enabled"
msgstr "グループã¯æœ‰åŠ¹ã§ã™"
@@ -3428,10 +3663,10 @@ msgid "CICD|instance enabled"
msgstr "インスタンスãŒæœ‰åŠ¹"
msgid "CLOSED"
-msgstr ""
+msgstr "クローズ"
msgid "CLOSED (MOVED)"
-msgstr ""
+msgstr "完了(移動済ã¿)"
msgid "CONTRIBUTING"
msgstr "CONTRIBUTING"
@@ -3448,6 +3683,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr "マージリクエストã”ã¨ã«å¿…è¦ãªæ‰¿èªè€…ã¨æ‰¿èªã‚’上書ãã§ãã¾ã™"
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr "ã“ã®ãƒ–ランãƒã«ã¯ HEAD コミットãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
@@ -3461,7 +3702,7 @@ msgid "Can't remove group members without group managed account"
msgstr "グループ管ç†ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒãªã„ã¨ã‚°ãƒ«ãƒ¼ãƒ—メンãƒãƒ¼ã¯å‰Šé™¤ã§ãã¾ã›ã‚“"
msgid "Can't scan the code?"
-msgstr ""
+msgstr "コードをスキャンã§ãã¾ã™ã‹ï¼Ÿ"
msgid "Can't update snippet: %{err}"
msgstr ""
@@ -3497,10 +3738,10 @@ msgid "Cannot create the abuse report. This user has been blocked."
msgstr "ä¸æ­£ä½¿ç”¨ãƒ¬ãƒãƒ¼ãƒˆã‚’作æˆã§ãã¾ã›ã‚“。ã“ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ãƒ–ロックã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "Cannot have multiple Jira imports running at the same time"
-msgstr ""
+msgstr "複数ã®Jiraインãƒãƒ¼ãƒˆã‚’åŒæ™‚ã«å®Ÿè¡Œã§ãã¾ã›ã‚“"
msgid "Cannot import because issues are not available in this project."
-msgstr ""
+msgstr "ã“ã®ãƒ—ロジェクトã«ã¯èª²é¡ŒãŒãªã„ãŸã‚ã€ã‚¤ãƒ³ãƒãƒ¼ãƒˆã§ãã¾ã›ã‚“。"
msgid "Cannot make epic confidential if it contains not-confidential issues"
msgstr ""
@@ -3515,19 +3756,19 @@ msgid "Cannot modify managed Kubernetes cluster"
msgstr "管ç†ä¸‹ã® Kubernetes クラスターを変更ã§ãã¾ã›ã‚“"
msgid "Cannot modify provider during creation"
-msgstr ""
+msgstr "作æˆä¸­ã¯ãƒ—ロãƒã‚¤ãƒ€ãƒ¼ã‚’修正・変更ã§ãã¾ã›ã‚“"
msgid "Cannot promote issue because it does not belong to a group."
-msgstr ""
+msgstr "グループã«æ‰€å±žã—ã¦ã„ãªã„ãŸã‚ã€èª²é¡Œã‚’プロモートã§ãã¾ã›ã‚“。"
msgid "Cannot promote issue due to insufficient permissions."
-msgstr ""
+msgstr "権é™ãŒä¸å分ãªãŸã‚ã€èª²é¡Œã‚’プロモートã§ãã¾ã›ã‚“。"
-msgid "Cannot refer to a group milestone by an internal id!"
-msgstr "内部IDã§ã‚°ãƒ«ãƒ¼ãƒ—マイルストーンをå‚ç…§ã§ãã¾ã›ã‚“。"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
+msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
-msgstr ""
+msgstr "公開ã®èª²é¡Œã®ãŸã‚ã€ã‚¨ãƒ”ックを機密ã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
msgid "Cannot show preview. For previews on sketch files, they must have the file format introduced by Sketch version 43 and above."
msgstr "プレビューを表示ã§ãã¾ã›ã‚“。Sketch ファイルをプレビューã™ã‚‹ã«ã¯ã€Sketch ãƒãƒ¼ã‚¸ãƒ§ãƒ³43以é™ã§å°Žå…¥ã•ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«å½¢å¼ãŒå¿…è¦ã§ã™ã€‚"
@@ -3538,6 +3779,9 @@ msgstr "2è¦ç´ èªè¨¼ã®è¨­å®šã‚’スキップã§ãã¾ã›ã‚“"
msgid "Capacity threshold"
msgstr "キャパシティ判定ã®ã—ãã„値"
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr "証明書"
@@ -3545,7 +3789,7 @@ msgid "Certificate (PEM)"
msgstr "証明書 (PEM)"
msgid "Certificate Issuer"
-msgstr ""
+msgstr "証明書発行者"
msgid "Certificate Subject"
msgstr ""
@@ -3574,6 +3818,12 @@ msgstr "パスを変更"
msgid "Change permissions"
msgstr "アクセス権é™ã‚’変更"
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr "テンプレートを変更"
@@ -3608,7 +3858,7 @@ msgid "Changed assignee(s)."
msgstr "担当者を変更ã—ã¾ã—ãŸã€‚"
msgid "Changed the title to \"%{title_param}\"."
-msgstr ""
+msgstr "タイトルを \"%{title_param}\" ã«å¤‰æ›´ã—ã¾ã—ãŸã€‚"
msgid "Changes"
msgstr "変更"
@@ -3616,6 +3866,9 @@ msgstr "変更"
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr "<b>source</b>リビジョンãŒ<b>target</b>リビジョン内ã«å–ã‚Šè¾¼ã¾ã‚Œã¦ã„るよã†ãªå¤‰æ›´ã¨ã—ã¦è¡¨ç¤ºã•ã‚Œã¾ã™"
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3626,19 +3879,22 @@ msgid "Changes the title to \"%{title_param}\"."
msgstr "タイトルを \"%{title_param}\" ã«å¤‰æ›´ã—ã¾ã™ã€‚"
msgid "Changes won't take place until the index is %{link_start}recreated%{link_end}."
-msgstr ""
+msgstr "インデックス㌠%{link_start} å†ç”Ÿæˆã•ã‚Œã‚‹ %{link_end}ã¾ã§å¤‰æ›´ã¯è¡Œã‚ã‚Œã¾ã›ã‚“。"
msgid "Changing a Release tag is only supported via Releases API. %{linkStart}More information%{linkEnd}"
-msgstr ""
+msgstr "リリースタグã®å¤‰æ›´ã¯ã€ãƒªãƒªãƒ¼ã‚¹APIを介ã—ã¦ã®ã¿ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¾ã™ã€‚ %{linkStart} 詳細%{linkEnd}"
msgid "Changing group path can have unintended side effects."
msgstr "グループã®ãƒ‘スを変更ã™ã‚‹ã¨ã€æ„図ã—ãªã„副作用ãŒç™ºç”Ÿã™ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚"
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
-msgstr ""
+msgstr "グラフを表示ã§ãã¾ã›ã‚“。データリクエストãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ãŸãŸã‚ã§ã™ã€‚%{documentationLink}"
msgid "Chat"
msgstr "ãƒãƒ£ãƒƒãƒˆ"
@@ -3662,7 +3918,7 @@ msgid "ChatMessage|Invalid CI config YAML file"
msgstr "CIã®è¨­å®šç”¨ã®YAMLファイルãŒç„¡åŠ¹ã§ã™ã€‚"
msgid "ChatMessage|Pipeline #%{pipeline_id} %{humanized_status} in %{duration}"
-msgstr ""
+msgstr "パイプライン#%{pipeline_id} %{duration} 㮠%{humanized_status}"
msgid "ChatMessage|Pipeline %{pipeline_link} of %{ref_type} %{ref_link} by %{user_combined_name} %{humanized_status}"
msgstr ""
@@ -3677,10 +3933,10 @@ msgid "ChatMessage|has failed"
msgstr "ã¯å¤±æ•—ã—ã¾ã—ãŸ"
msgid "ChatMessage|has passed"
-msgstr ""
+msgstr "åˆæ ¼ã—ã¾ã—ãŸ"
msgid "ChatMessage|has passed with warnings"
-msgstr ""
+msgstr "ã¯è­¦å‘Šä»˜ãã§åˆæ ¼"
msgid "ChatMessage|in %{duration}"
msgstr "%{duration} 中"
@@ -3692,7 +3948,7 @@ msgid "Check again"
msgstr "å†ãƒã‚§ãƒƒã‚¯"
msgid "Check feature availability on namespace plan"
-msgstr ""
+msgstr "åå‰ç©ºé–“ã®è¨ˆç”»ã§æ©Ÿèƒ½ãŒåˆ©ç”¨ã§ãã‚‹ã‹ãƒã‚§ãƒƒã‚¯ã™ã‚‹"
msgid "Check the %{docs_link_start}documentation%{docs_link_end}."
msgstr "%{docs_link_start}ドキュメント%{docs_link_end}を確èª"
@@ -3719,7 +3975,7 @@ msgid "Checking username availability..."
msgstr "ユーザーåãŒåˆ©ç”¨å¯èƒ½ã‹ç¢ºèªã—ã¦ã„ã¾ã™..."
msgid "Checkout"
-msgstr ""
+msgstr "Checkout"
msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr ""
@@ -3728,52 +3984,43 @@ msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
msgstr ""
msgid "Checkout|%{name}'s GitLab subscription"
-msgstr ""
+msgstr "%{name} 㮠GitLab サブスクリプション"
msgid "Checkout|%{selectedPlanText} plan"
-msgstr ""
+msgstr "%{selectedPlanText} プラン"
msgid "Checkout|%{startDate} - %{endDate}"
-msgstr ""
+msgstr "%{startDate} ã‹ã‚‰ %{endDate} ã¾ã§"
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr "1. ã‚ãªãŸã®ãƒ—ロフィール"
-
-msgid "Checkout|2. Checkout"
-msgstr "2. ãƒã‚§ãƒƒã‚¯ã‚¢ã‚¦ãƒˆ"
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
-msgstr ""
+msgstr "請求先ä½æ‰€"
msgid "Checkout|Checkout"
msgstr "ãƒã‚§ãƒƒã‚¯ã‚¢ã‚¦ãƒˆ"
msgid "Checkout|City"
-msgstr ""
+msgstr "市"
msgid "Checkout|Confirm purchase"
-msgstr ""
+msgstr "購入を確èª"
msgid "Checkout|Confirming..."
-msgstr ""
+msgstr "確èªã—ã¦ã„ã¾ã™..."
msgid "Checkout|Continue to billing"
-msgstr ""
+msgstr "請求ã«ç¶šã"
msgid "Checkout|Continue to payment"
msgstr ""
msgid "Checkout|Country"
-msgstr ""
+msgstr "国"
msgid "Checkout|Create a new group"
-msgstr ""
+msgstr "æ–°ã—ã„グループを作æˆ"
msgid "Checkout|Credit card form failed to load. Please try again."
msgstr ""
@@ -3782,13 +4029,13 @@ msgid "Checkout|Credit card form failed to load: %{message}"
msgstr ""
msgid "Checkout|Edit"
-msgstr ""
+msgstr "編集"
msgid "Checkout|Exp %{expirationMonth}/%{expirationYear}"
msgstr ""
msgid "Checkout|Failed to confirm your order! Please try again."
-msgstr ""
+msgstr "注文ã®ç¢ºèªã«å¤±æ•—ã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
msgid "Checkout|Failed to confirm your order: %{message}. Please try again."
msgstr ""
@@ -3800,25 +4047,25 @@ msgid "Checkout|Failed to load states. Please try again."
msgstr ""
msgid "Checkout|Failed to register credit card. Please try again."
-msgstr ""
+msgstr "クレジットカードã®ç™»éŒ²ã«å¤±æ•—ã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
msgid "Checkout|GitLab group"
-msgstr ""
+msgstr "GitLab グループ"
msgid "Checkout|GitLab plan"
-msgstr ""
+msgstr "GitLabプラン"
msgid "Checkout|Group"
-msgstr ""
+msgstr "グループ"
msgid "Checkout|Name of company or organization using GitLab"
-msgstr ""
+msgstr "GitLab を使用ã—ã¦ã„る会社åã¾ãŸã¯çµ„ç¹”å"
msgid "Checkout|Need more users? Purchase GitLab for your %{company}."
-msgstr ""
+msgstr "ã‚‚ã£ã¨å¤šãã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒå¿…è¦ã§ã™ã‹ï¼Ÿ %{company} ã¯GitLabを購入ã—ã¾ã™ã‹?"
msgid "Checkout|Number of users"
-msgstr ""
+msgstr "ユーザー数"
msgid "Checkout|Payment method"
msgstr ""
@@ -3842,25 +4089,25 @@ msgid "Checkout|Submitting the credit card form failed with code %{errorCode}: %
msgstr ""
msgid "Checkout|Subscription details"
-msgstr ""
+msgstr "サブスクリプションã®è©³ç´°"
msgid "Checkout|Subtotal"
-msgstr ""
+msgstr "å°è¨ˆ"
msgid "Checkout|Tax"
-msgstr ""
+msgstr "税"
msgid "Checkout|Total"
-msgstr ""
+msgstr "åˆè¨ˆ"
msgid "Checkout|Users"
-msgstr ""
+msgstr "ユーザー"
msgid "Checkout|You'll create your new group after checkout"
msgstr ""
msgid "Checkout|Your organization"
-msgstr ""
+msgstr "組織"
msgid "Checkout|Your subscription will be applied to this group"
msgstr ""
@@ -3869,7 +4116,7 @@ msgid "Checkout|Zip code"
msgstr ""
msgid "Checkout|company or team"
-msgstr ""
+msgstr "会社ã¾ãŸã¯ãƒãƒ¼ãƒ "
msgid "Cherry-pick this commit"
msgstr "ã“ã®ã‚³ãƒŸãƒƒãƒˆã‚’ãƒã‚§ãƒªãƒ¼ãƒ”ック"
@@ -3878,7 +4125,7 @@ msgid "Cherry-pick this merge request"
msgstr "ã“ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’ãƒã‚§ãƒªãƒ¼ãƒ”ック"
msgid "Child"
-msgstr ""
+msgstr "å­"
msgid "Child epic does not exist."
msgstr "å­ã‚¨ãƒ”ックã¯å­˜åœ¨ã—ã¾ã›ã‚“。"
@@ -3926,7 +4173,7 @@ msgid "Choose the top-level group for your repository imports."
msgstr "インãƒãƒ¼ãƒˆãƒªãƒã‚¸ãƒˆãƒªã®ãƒˆãƒƒãƒ—レベルã®ã‚°ãƒ«ãƒ¼ãƒ—ã‚’é¸æŠžã—ã¦ãã ã•ã„。"
msgid "Choose visibility level, enable/disable project features (issues, repository, wiki, snippets) and set permissions."
-msgstr ""
+msgstr "表示レベルã€ãƒ—ロジェクト機能(課題ã€ãƒªãƒã‚¸ãƒˆãƒªã€Wikiã€ã‚¹ãƒ‹ãƒšãƒƒãƒˆ) ã®æœ‰åŠ¹/無効や権é™ã®è¨­å®š"
msgid "Choose what content you want to see on a group’s overview page"
msgstr "グループã®æ¦‚è¦ãƒšãƒ¼ã‚¸ã«è¡¨ç¤ºã—ãŸã„コンテンツをé¸æŠžã—ã¦ãã ã•ã„"
@@ -3980,7 +4227,7 @@ msgid "CiStatusLabel|waiting for manual action"
msgstr "手動実行待ã¡"
msgid "CiStatusLabel|waiting for resource"
-msgstr ""
+msgstr "リソース待ã¡"
msgid "CiStatusText|blocked"
msgstr "ブロック"
@@ -4013,7 +4260,7 @@ msgid "CiStatusText|skipped"
msgstr "スキップ済ã¿"
msgid "CiStatusText|waiting"
-msgstr ""
+msgstr "å¾…ã¡"
msgid "CiStatus|running"
msgstr "実行中"
@@ -4046,7 +4293,7 @@ msgid "CiVariables|Scope"
msgstr "スコープ"
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 ""
+msgstr "ã“ã®å®Ÿè¡Œã§ä½¿ç”¨ã•ã‚Œã‚‹å¤‰æ•°ã®å€¤ã‚’指定ã—ã¾ã™ã€‚%{linkStart} CI/CD 設定 %{linkEnd} ã§æŒ‡å®šã•ã‚ŒãŸå€¤ã¯ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã¨ã—ã¦ä½¿ç”¨ã§ãã¾ã™ã€‚"
msgid "CiVariables|State"
msgstr "状態"
@@ -4096,9 +4343,6 @@ msgstr "検証ã«å¤±æ•—ã—ã¾ã—ãŸ"
msgid "Class"
msgstr "クラス"
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr "分類ラベル (オプション)"
@@ -4111,11 +4355,14 @@ msgstr "クリア"
msgid "Clear chart filters"
msgstr "ãƒãƒ£ãƒ¼ãƒˆãƒ•ã‚£ãƒ«ã‚¿ãƒ¼ã‚’解除"
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr "入力をクリア"
msgid "Clear recent searches"
-msgstr ""
+msgstr "最近検索をクリアー"
msgid "Clear search"
msgstr "検索をクリア"
@@ -4123,6 +4370,9 @@ msgstr "検索をクリア"
msgid "Clear search input"
msgstr "検索欄ã®æ¶ˆåŽ»"
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr "テンプレート検索入力をクリア"
@@ -4150,9 +4400,6 @@ msgstr "å³ã®<strong>Select none</strong>ボタンをクリックã—ã¦ãã ã
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr "下ã®ãƒœã‚¿ãƒ³ã‚’クリックã™ã‚‹ã¨ã€Kubernetesã®ãƒšãƒ¼ã‚¸ã«é·ç§»ã—ã€ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãƒ—ロセスを開始ã—ã¾ã™"
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr "クリックã—ã¦å±•é–‹ã€‚"
@@ -4192,9 +4439,12 @@ msgstr "SSH ã§ã‚¯ãƒ­ãƒ¼ãƒ³"
msgid "Close"
msgstr "クローズã™ã‚‹"
-msgid "Close %{tabname}"
+msgid "Close %{display_issuable_type}"
msgstr ""
+msgid "Close %{tabname}"
+msgstr "%{tabname} ã‚’é–‰ã˜ã‚‹"
+
msgid "Close epic"
msgstr "エピックを閉ã˜ã‚‹"
@@ -4205,7 +4455,7 @@ msgid "Close sidebar"
msgstr "サイドãƒãƒ¼ã‚’é–‰ã˜ã‚‹"
msgid "Close this %{quick_action_target}"
-msgstr ""
+msgstr "ã“ã® %{quick_action_target} ã‚’é–‰ã˜ã‚‹"
msgid "Closed"
msgstr "クローズ"
@@ -4214,22 +4464,22 @@ msgid "Closed issues"
msgstr "クローズã—ãŸèª²é¡Œ"
msgid "Closed this %{quick_action_target}."
-msgstr ""
+msgstr "%{quick_action_target} ã‚’é–‰ã˜ãŸã€‚"
msgid "Closed: %{closedIssuesCount}"
-msgstr ""
+msgstr "é–‰ã˜ãŸä»¶æ•°: %{closedIssuesCount} "
msgid "Closes this %{quick_action_target}."
-msgstr ""
+msgstr "ã“ã® %{quick_action_target} ã‚’é–‰ã˜ã‚‹ã€‚"
msgid "Cluster"
msgstr ""
msgid "Cluster Health"
-msgstr ""
+msgstr "クラスターã®å¥åº·çŠ¶æ…‹"
msgid "Cluster cache cleared."
-msgstr ""
+msgstr "クラスターã®ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’削除ã—ã¾ã—ãŸ"
msgid "Cluster does not exist"
msgstr ""
@@ -4241,7 +4491,7 @@ msgid "ClusterIntegration| %{custom_domain_start}More information%{custom_domain
msgstr "%{custom_domain_start} 詳細情報 %{custom_domain_end}"
msgid "ClusterIntegration| This will permanently delete the following resources: <ul> <li>All installed applications and related resources</li> <li>The <code>gitlab-managed-apps</code> namespace</li> <li>Any project namespaces</li> <li><code>clusterroles</code></li> <li><code>clusterrolebindings</code></li> </ul>"
-msgstr ""
+msgstr "ã“ã‚Œã«ã‚ˆã‚Šã€æ¬¡ã®ãƒªã‚½ãƒ¼ã‚¹ã¯å®Œå…¨ã«å‰Šé™¤ã•ã‚Œã¾ã™ <ul> <li>インストールã•ã‚Œã¦ã„ã‚‹ã™ã¹ã¦ã®ã‚¢ãƒ—リケーションã¨é–¢é€£ã—ãŸãƒªã‚½ãƒ¼ã‚¹</li> <li> <code>gitlab-managed-apps</code> åå‰ç©ºé–“</li> <li>ä»»æ„ã®ãƒ—ロジェクトåå‰ç©ºé–“</li> <li><code>clusterroles</code></li> <li><code>clusterrolebindings</code></li> </ul>"
msgid "ClusterIntegration| can be used instead of a custom domain."
msgstr "カスタムドメインã®ä»£ã‚ã‚Šã«ä½¿ç”¨ã§ãã¾ã™ã€‚"
@@ -4262,7 +4512,7 @@ msgid "ClusterIntegration|%{title} updated successfully."
msgstr "%{title} ã¯æ­£å¸¸ã«æ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚"
msgid "ClusterIntegration|A cluster management project can be used to run deployment jobs with Kubernetes <code>cluster-admin</code> privileges."
-msgstr ""
+msgstr "クラスター管ç†ãƒ—ロジェクトを使用ã—ã¦ã€Kubernetes <code> cluster-admin </code>特権ã§å±•é–‹ã‚¸ãƒ§ãƒ–を実行ã§ãã¾ã™ã€‚"
msgid "ClusterIntegration|A service token scoped to %{code}kube-system%{end_code} with %{code}cluster-admin%{end_code} privileges."
msgstr "サービス・トークンã¯ã€ %{code}cluster-admin%{end_code} 特権をæŒã¤ %{code}kube-system%{end_code} スコープã§ã™ã€‚"
@@ -4295,7 +4545,7 @@ msgid "ClusterIntegration|Advanced options on this Kubernetes cluster’s integr
msgstr ""
msgid "ClusterIntegration|All data not committed to GitLab will be deleted and cannot be restored."
-msgstr ""
+msgstr "GitLab ã«ã‚³ãƒŸãƒƒãƒˆã—ã¦ã„ãªã„å…¨ã¦ã®ãƒ‡ãƒ¼ã‚¿ã‚’削除ã—ã¾ã™ã€‚ã“ã‚Œã¯å¾©å…ƒã§ãã¾ã›ã‚“。"
msgid "ClusterIntegration|All data will be deleted and cannot be restored."
msgstr "ã™ã¹ã¦ã®ãƒ‡ãƒ¼ã‚¿ã‚’削除ã—ã€å¾©å…ƒã§ãã¾ã›ã‚“。"
@@ -4304,7 +4554,7 @@ msgid "ClusterIntegration|Allow GitLab to manage namespace and service accounts
msgstr "ã“ã®ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã®åå‰ç©ºé–“ã¨ã‚µãƒ¼ãƒ“スアカウントã®ç®¡ç†ã‚’GitLabã«è¨±å¯ã™ã‚‹ã€‚"
msgid "ClusterIntegration|Allow GitLab to manage namespace and service accounts for this cluster. %{startLink}More information%{endLink}"
-msgstr ""
+msgstr "GitLab ãŒã“ã®ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã®åå‰ç©ºé–“ã¨ã‚µãƒ¼ãƒ“スアカウントを管ç†ã§ãるよã†ã«ã—ã¾ã™ã€‚ %{startLink}詳細ã¯ã“ã¡ã‚‰%{endLink}"
msgid "ClusterIntegration|Alternatively"
msgstr "ã‚ã‚‹ã„ã¯"
@@ -4331,10 +4581,10 @@ msgid "ClusterIntegration|Apply for credit"
msgstr "クレジットをé©ç”¨"
msgid "ClusterIntegration|Authenticate with AWS"
-msgstr ""
+msgstr "AWSã§èªè¨¼ã™ã‚‹"
msgid "ClusterIntegration|Authenticate with Amazon Web Services"
-msgstr ""
+msgstr "Amazon Web Servicesã§èªè¨¼ã™ã‚‹"
msgid "ClusterIntegration|Base domain"
msgstr "ベースドメイン"
@@ -4355,13 +4605,13 @@ msgid "ClusterIntegration|Certificate Authority bundle (PEM format)"
msgstr "èªè¨¼å±€ãƒãƒ³ãƒ‰ãƒ« (PEMå½¢å¼)"
msgid "ClusterIntegration|Choose the %{startLink}security group %{externalLinkIcon} %{endLink} to apply to the EKS-managed Elastic Network Interfaces that are created in your worker node subnets."
-msgstr ""
+msgstr "%{startLink}セキュリティグループ%{externalLinkIcon}%{endLink}ã‚’é¸æŠžã—ã¦ã€ãƒ¯ãƒ¼ã‚«ãƒ¼ãƒŽãƒ¼ãƒ‰ã‚µãƒ–ãƒãƒƒãƒˆã§ä½œæˆã•ã‚ŒãŸEKS管ç†ã®Elastic Network Interfacesã«é©ç”¨ã—ã¾ã™ã€‚"
msgid "ClusterIntegration|Choose the %{startLink}subnets %{externalLinkIcon} %{endLink} in your VPC where your worker nodes will run."
-msgstr ""
+msgstr "ワーカーノードãŒå®Ÿè¡Œã•ã‚Œã‚‹VPCã§%{startLink} サブãƒãƒƒãƒˆ%{externalLinkIcon} %{endLink}ã‚’é¸æŠžã—ã¾ã™ã€‚"
msgid "ClusterIntegration|Choose the worker node %{startLink}instance type %{externalLinkIcon} %{endLink}."
-msgstr ""
+msgstr "ワーカーノード%{startLink}インスタンスタイプ%{externalLinkIcon} %{endLink}ã‚’é¸æŠžã—ã¾ã™ã€‚"
msgid "ClusterIntegration|Choose which applications to install on your Kubernetes cluster. Helm Tiller is required to install any of the following applications."
msgstr "Kubernetes クラスタã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã™ã‚‹ã‚¢ãƒ—リケーションをé¸æŠžã—ã¾ã™ã€‚ Helm Tiller ã¯ã€æ¬¡ã®ã‚¢ãƒ—リケーションã®ã„ãšã‚Œã‹ã‚’インストールã™ã‚‹ã®ã«å¿…è¦ã§ã™ã€‚"
@@ -4370,23 +4620,26 @@ msgid "ClusterIntegration|Choose which of your environments will use this cluste
msgstr "ã“ã®ã‚¯ãƒ©ã‚¹ã‚¿ã‚’使用ã™ã‚‹ç’°å¢ƒã‚’é¸æŠžã—ã¦ãã ã•ã„。"
msgid "ClusterIntegration|Clear cluster cache"
-msgstr ""
+msgstr "クラスターã®ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’削除"
msgid "ClusterIntegration|Clear the local cache of namespace and service accounts. 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 ""
+msgstr "åå‰ç©ºé–“ãŠã‚ˆã³ã‚µãƒ¼ãƒ“スアカウントã®ãƒ­ãƒ¼ã‚«ãƒ«ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’クリアã—ã¾ã™ã€‚ã“ã‚Œã¯ã‚¤ãƒ³ãƒ†ã‚°ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãŒåŒæœŸã•ã‚Œã¦ã„ãªã„å ´åˆã«å¿…è¦ã§ã™ã€‚キャッシュã¯ã€ãƒãƒ¼ãƒ ã‚¹ãƒšãƒ¼ã‚¹ãŠã‚ˆã³ã‚µãƒ¼ãƒ“スアカウントを必è¦ã¨ã™ã‚‹æ¬¡å›žã®CIジョブ中ã«å†ä½œæˆã•ã‚Œã¾ã™ã€‚"
msgid "ClusterIntegration|Cloud Run"
-msgstr ""
+msgstr "Cloud Run"
msgid "ClusterIntegration|Cluster being created"
msgstr ""
msgid "ClusterIntegration|Cluster management project (alpha)"
-msgstr ""
+msgstr "クラスター管ç†ãƒ—ロジェクト(アルファ)"
msgid "ClusterIntegration|Cluster name is required."
msgstr "クラスターåãŒå¿…è¦ã§ã™ã€‚"
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr "クラスタã¯ã€ç’°å¢ƒã‚¹ã‚³ãƒ¼ãƒ—ãŒä¸€è‡´ã™ã‚‹æœ€ã‚‚è¿‘ã„先祖をé¸æŠžã™ã‚‹ã“ã¨ã«ã‚ˆã£ã¦åˆ©ç”¨ã•ã‚Œã¾ã™ã€‚ ãŸã¨ãˆã°ã€ãƒ—ロジェクトクラスタã¯ã‚°ãƒ«ãƒ¼ãƒ—クラスタを上書ãã—ã¾ã™ã€‚"
@@ -4397,76 +4650,73 @@ msgid "ClusterIntegration|Copy CA Certificate"
msgstr "CA 証明書をコピー"
msgid "ClusterIntegration|Copy Ingress Endpoint"
-msgstr ""
+msgstr "Ingress ã®ã‚¨ãƒ³ãƒ‰ãƒã‚¤ãƒ³ãƒˆã‚’コピー"
msgid "ClusterIntegration|Copy Jupyter Hostname"
-msgstr ""
+msgstr "Jupyter ã®ãƒ›ã‚¹ãƒˆåをコピー"
msgid "ClusterIntegration|Copy Knative Endpoint"
-msgstr ""
+msgstr "Knative ã®ã‚¨ãƒ³ãƒ‰ãƒã‚¤ãƒ³ãƒˆã‚’コピー"
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr "Kubernetes クラスターåをコピー"
-msgid "ClusterIntegration|Copy Service Token"
-msgstr "サービストークンをコピー"
-
msgid "ClusterIntegration|Could not load IAM roles"
-msgstr ""
+msgstr "IAM ロールをロードã§ãã¾ã›ã‚“ã§ã—ãŸ"
msgid "ClusterIntegration|Could not load Key Pairs"
-msgstr ""
+msgstr "キーペアをロードã§ãã¾ã›ã‚“ã§ã—ãŸ"
msgid "ClusterIntegration|Could not load VPCs for the selected region"
-msgstr ""
+msgstr "é¸æŠžã—ãŸãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã® VPC をロードã§ãã¾ã›ã‚“ã§ã—ãŸ"
msgid "ClusterIntegration|Could not load instance types"
-msgstr ""
+msgstr "インスタンスタイプをロードã§ãã¾ã›ã‚“ã§ã—ãŸ"
msgid "ClusterIntegration|Could not load networks"
-msgstr ""
+msgstr "ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚’ロードã§ãã¾ã›ã‚“ã§ã—ãŸ"
msgid "ClusterIntegration|Could not load regions from your AWS account"
-msgstr ""
+msgstr "ã‚ãªãŸã®AWSアカウントã‹ã‚‰ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ロードã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
msgid "ClusterIntegration|Could not load security groups for the selected VPC"
-msgstr ""
+msgstr "é¸æŠžã—㟠VPC ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ã‚°ãƒ«ãƒ¼ãƒ—をロードã§ãã¾ã›ã‚“ã§ã—ãŸ"
msgid "ClusterIntegration|Could not load subnets for the selected VPC"
-msgstr ""
+msgstr "é¸æŠžã—㟠VPC ã®ã‚µãƒ–ãƒãƒƒãƒˆã‚’ロードã§ãã¾ã›ã‚“ã§ã—ãŸ"
msgid "ClusterIntegration|Could not load subnetworks"
-msgstr ""
+msgstr "サブãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚’ロードã§ãã¾ã›ã‚“ã§ã—ãŸ"
msgid "ClusterIntegration|Create Kubernetes cluster"
msgstr "Kubernetes クラスターを作æˆ"
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 ""
+msgstr "上記ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¨å¤–部IDを使用ã—ã¦ã€%{startAwsLink} Amazon Web Services%{externalLinkIcon}%{endLink}ã«ãƒ—ロビジョニングロールを作æˆã—ã¾ã™ã€‚ %{startMoreInfoLink}詳細情報%{endLink}"
msgid "ClusterIntegration|Create cluster on"
-msgstr ""
+msgstr "クラスターを作æˆ"
msgid "ClusterIntegration|Create new cluster"
-msgstr ""
+msgstr "æ–°ã—ã„クラスターを作æˆ"
msgid "ClusterIntegration|Create new cluster on EKS"
-msgstr ""
+msgstr "EKS 上ã«æ–°ã—ã„クラスターを作æˆ"
msgid "ClusterIntegration|Create new cluster on GKE"
-msgstr ""
+msgstr "GKE 上ã«æ–°ã—ã„クラスターを作æˆ"
msgid "ClusterIntegration|Creating Kubernetes cluster"
-msgstr ""
+msgstr "Kubernetesクラスターã®ä½œæˆ"
msgid "ClusterIntegration|Crossplane"
-msgstr ""
+msgstr "Crossplane"
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
-msgstr ""
+msgstr "削除中ã«ã“ã®ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã«ã‚¢ã‚¿ãƒƒãƒã•ã‚ŒãŸã™ã¹ã¦ã®GitLabリソースを削除ã—ã¾ã™"
msgid "ClusterIntegration|Did you know?"
msgstr "ã”存知ã§ã™ã‹ï¼Ÿ"
@@ -4475,7 +4725,7 @@ msgid "ClusterIntegration|Elastic Kubernetes Service"
msgstr "Elastic Kubernetes サービス"
msgid "ClusterIntegration|Elastic Stack"
-msgstr ""
+msgstr "Elastic Stack"
msgid "ClusterIntegration|Enable Cloud Run for Anthos"
msgstr ""
@@ -4487,6 +4737,9 @@ msgid "ClusterIntegration|Enable this setting if using role-based access control
msgstr "役割ベースã®ã‚¢ã‚¯ã‚»ã‚¹åˆ¶å¾¡ (RBAC) を使ã†å ´åˆã€ã“ã®è¨­å®šã‚’有効ã«ã—ã¾ã™ã€‚"
msgid "ClusterIntegration|Enabled stack"
+msgstr "有効化ã•ã‚ŒãŸã‚¹ã‚¿ãƒƒã‚¯"
+
+msgid "ClusterIntegration|Enter new Service Token"
msgstr ""
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
@@ -4502,13 +4755,13 @@ msgid "ClusterIntegration|Every new Google Cloud Platform (GCP) account receives
msgstr "Google Cloud Platform (GCP) ã®ã™ã¹ã¦ã®æ–°è¦ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã«ã¯ã€300ドル分ã®ã‚¯ãƒ¬ã‚¸ãƒƒãƒˆãŒä»˜ä¸Žã•ã‚Œã¾ã™ %{sign_up_link} 。ã¾ãŸã€Google ã¨ã®ãƒ‘ートナーシップã«ã‚ˆã‚Šã€Google Kubernetes Engine 㨠GitLab ã®ã‚¤ãƒ³ãƒ†ã‚°ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã‚’開始ã™ã‚‹ãŸã‚ã«ã€æ–°è¦ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãƒ»æ—¢å­˜ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’å•ã‚ãšã€GCP アカウントã«è¿½åŠ ã®200ドル分ã®ã‚¯ãƒ¬ã‚¸ãƒƒãƒˆã‚’æä¾›ã—ã¾ã™ã€‚"
msgid "ClusterIntegration|Failed to configure EKS provider: %{message}"
-msgstr ""
+msgstr "EKS プロãƒã‚¤ãƒ€ãƒ¼ã®è¨­å®šã«å¤±æ•—ã—ã¾ã—ãŸ: %{message}"
msgid "ClusterIntegration|Failed to configure Google Kubernetes Engine Cluster: %{message}"
msgstr "Google Kubernetes Engine ã®ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ %{message} ã®è¨­å®šã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
msgid "ClusterIntegration|Failed to fetch CloudFormation stack: %{message}"
-msgstr ""
+msgstr "CloudFormation スタックã®å–å¾—ã«å¤±æ•—ã—ã¾ã—ãŸ: %{message}"
msgid "ClusterIntegration|Failed to request to Google Cloud Platform: %{message}"
msgstr "Google Cloud Platform ã¸ã®è¦æ±‚ %{message} ã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
@@ -4544,7 +4797,7 @@ msgid "ClusterIntegration|GitLab-managed cluster"
msgstr "GitLabマãƒãƒ¼ã‚¸ãƒ‰ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼"
msgid "ClusterIntegration|Gitlab Integration"
-msgstr ""
+msgstr "GitLab çµ±åˆ"
msgid "ClusterIntegration|Global default"
msgstr ""
@@ -4567,17 +4820,17 @@ msgstr "グループクラスター"
msgid "ClusterIntegration|Helm Tiller"
msgstr "Helm Tiller"
+msgid "ClusterIntegration|Helm release failed to install"
+msgstr ""
+
msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr "Helm ã¯ã€Kubernetes アプリケーションã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã¨ç®¡ç†ã‚’簡略化ã—ã¾ã™ã€‚Helm Tiller ã¯ã‚ãªãŸã®Kubernetes クラスタã®å†…部ã§å®Ÿè¡Œã—ã€ã‚ãªãŸã®ãƒãƒ£ãƒ¼ãƒˆã®ãƒªãƒªãƒ¼ã‚¹ã‚’管ç†ã—ã¾ã™ã€‚"
-msgid "ClusterIntegration|Hide"
-msgstr "éžè¡¨ç¤º"
-
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
msgstr "ã‚ãªãŸãŒè¤‡æ•°ã®ã‚¯ãƒ©ã‚¹ã‚¿ã‚’セットアップ㗠Auto DevOps を使用ã—ã¦ã„ã‚‹å ´åˆã€%{help_link_start}最åˆã«ã“ã¡ã‚‰ã‚’ãŠèª­ã¿ãã ã•ã„%{help_link_end} 。"
msgid "ClusterIntegration|If you do not wish to delete all associated GitLab resources, you can simply remove the integration."
-msgstr ""
+msgstr "関連ã™ã‚‹ã™ã¹ã¦ã®GitLabリソースを削除ã—ãŸããªã„å ´åˆã¯ã€å˜ã«çµ±åˆã‚’削除ã§ãã¾ã™ã€‚"
msgid "ClusterIntegration|In order to view the health of your cluster, you must first install Prometheus in the Applications tab."
msgstr ""
@@ -4598,7 +4851,7 @@ msgid "ClusterIntegration|Instance cluster"
msgstr "インスタンスクラスター"
msgid "ClusterIntegration|Instance type"
-msgstr ""
+msgstr "インスタンスタイプ"
msgid "ClusterIntegration|Integrate Kubernetes cluster automation"
msgstr "Kubernetes クラスターを自動統åˆ"
@@ -4640,13 +4893,13 @@ msgid "ClusterIntegration|Kubernetes cluster"
msgstr "Kubernetes クラスター"
msgid "ClusterIntegration|Kubernetes cluster is being created..."
-msgstr ""
+msgstr "Kubernetesクラスターを作æˆã—ã¦ã„ã¾ã™..."
msgid "ClusterIntegration|Kubernetes cluster name"
msgstr "Kubernetes クラスターå"
msgid "ClusterIntegration|Kubernetes cluster was successfully created."
-msgstr ""
+msgstr "Kubernetes クラスターãŒæ­£å¸¸ã«ä½œæˆã•ã‚Œã¾ã—ãŸã€‚"
msgid "ClusterIntegration|Kubernetes clusters allow you to use review apps, deploy your applications, run your pipelines, and much more in an easy way."
msgstr "Kubernetes クラスター㯠Review Apps ã®ä½¿ç”¨ã€ã‚¢ãƒ—リケーションã®ãƒ‡ãƒ—ロイã€ãƒ‘イプラインã®å®Ÿè¡Œã‚„より簡å˜ãªå‡¦ç†ã‚’è¡Œã†è¨±å¯ã‚’求ã‚ã¦ã„ã¾ã™ã€‚"
@@ -4667,7 +4920,7 @@ msgid "ClusterIntegration|Learn more about %{help_link_start}zones%{help_link_en
msgstr "%{help_link_start}ゾーン%{help_link_end}ã®è©³ç´°ã€‚"
msgid "ClusterIntegration|Learn more about %{startLink}Regions %{externalLinkIcon}%{endLink}."
-msgstr ""
+msgstr "詳細ã«ã¤ã„ã¦ã¯%{startLink} リージョン%{externalLinkIcon}%{endLink}ã‚’å‚ç…§ã—ã¦ãã ã•ã„。"
msgid "ClusterIntegration|Learn more about Kubernetes"
msgstr "Kubernetes ã®è©³ç´°"
@@ -4694,19 +4947,19 @@ msgid "ClusterIntegration|Loading VPCs"
msgstr "VPC をロード"
msgid "ClusterIntegration|Loading instance types"
-msgstr ""
+msgstr "インスタンスタイプã®ãƒ­ãƒ¼ãƒ‰"
msgid "ClusterIntegration|Loading networks"
-msgstr ""
+msgstr "ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã®ãƒ­ãƒ¼ãƒ‰ä¸­"
msgid "ClusterIntegration|Loading security groups"
-msgstr ""
+msgstr "セキュリティグループをロード"
msgid "ClusterIntegration|Loading subnets"
-msgstr ""
+msgstr "サブãƒãƒƒãƒˆã‚’ロード"
msgid "ClusterIntegration|Loading subnetworks"
-msgstr ""
+msgstr "サブãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã®ãƒ­ãƒ¼ãƒ‰ä¸­"
msgid "ClusterIntegration|Logging mode"
msgstr ""
@@ -4718,25 +4971,31 @@ msgid "ClusterIntegration|Make sure your account %{link_to_requirements} to crea
msgstr "Kubernetes クラスター を作æˆã™ã‚‹ã«ã¯ã€ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã® %{link_to_requirements} を確èªã—ã¦ãã ã•ã„"
msgid "ClusterIntegration|Manage your Kubernetes cluster by visiting %{provider_link}"
-msgstr ""
+msgstr "%{provider_link} ã«ã‚¢ã‚¯ã‚»ã‚¹ã—㦠Kubernetes クラスターを管ç†"
msgid "ClusterIntegration|No IAM Roles found"
msgstr "IAM ロールãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
msgid "ClusterIntegration|No Key Pairs found"
-msgstr ""
+msgstr "キーペアãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
msgid "ClusterIntegration|No VPCs found"
+msgstr "VPCãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+msgid "ClusterIntegration|No deployment cluster found for this job"
msgstr ""
-msgid "ClusterIntegration|No instance type found"
+msgid "ClusterIntegration|No deployment found for this job"
msgstr ""
+msgid "ClusterIntegration|No instance type found"
+msgstr "インスタンスタイプãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
msgid "ClusterIntegration|No machine types matched your search"
msgstr "検索æ¡ä»¶ã«ä¸€è‡´ã™ã‚‹ãƒžã‚·ãƒ³ã‚¿ã‚¤ãƒ—ã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "ClusterIntegration|No networks found"
-msgstr ""
+msgstr "ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
msgid "ClusterIntegration|No projects found"
msgstr "プロジェクトãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
@@ -4745,16 +5004,16 @@ msgid "ClusterIntegration|No projects matched your search"
msgstr "検索æ¡ä»¶ã«ä¸€è‡´ã™ã‚‹ãƒ—ロジェクトã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "ClusterIntegration|No region found"
-msgstr ""
+msgstr "リージョンãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
msgid "ClusterIntegration|No security group found"
-msgstr ""
+msgstr "セキュリティグループãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
msgid "ClusterIntegration|No subnet found"
-msgstr ""
+msgstr "サブãƒãƒƒãƒˆãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
msgid "ClusterIntegration|No subnetworks found"
-msgstr ""
+msgstr "サブãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
msgid "ClusterIntegration|No zones matched your search"
msgstr "検索æ¡ä»¶ã«ä¸€è‡´ã™ã‚‹ã‚¾ãƒ¼ãƒ³ã¯ã‚ã‚Šã¾ã›ã‚“"
@@ -4781,7 +5040,7 @@ msgid "ClusterIntegration|Project namespace (optional, unique)"
msgstr "プロジェクトã®åå‰ç©ºé–“ (çœç•¥å¯èƒ½ã€ä¸€æ„)"
msgid "ClusterIntegration|Project namespace prefix (optional, unique)"
-msgstr ""
+msgstr "プロジェクトã®åå‰ç©ºé–“ã®ãƒ—レフィックス (オプションã€ãƒ¦ãƒ‹ãƒ¼ã‚¯)"
msgid "ClusterIntegration|Prometheus"
msgstr "Prometheus"
@@ -4793,7 +5052,7 @@ msgid "ClusterIntegration|Provider details"
msgstr ""
msgid "ClusterIntegration|Provision Role ARN"
-msgstr ""
+msgstr "プロビジョニングロールARN"
msgid "ClusterIntegration|RBAC-enabled cluster"
msgstr "RBAC 有効クラスター"
@@ -4814,19 +5073,19 @@ msgid "ClusterIntegration|Remove integration"
msgstr "çµ±åˆã‚’削除"
msgid "ClusterIntegration|Remove integration and resources"
-msgstr ""
+msgstr "インテグレーションã¨ãƒªã‚½ãƒ¼ã‚¹ã‚’削除"
msgid "ClusterIntegration|Remove integration and resources?"
-msgstr ""
+msgstr "インテグレーションã¨ãƒªã‚½ãƒ¼ã‚¹ã‚’削除?"
msgid "ClusterIntegration|Remove integration?"
-msgstr ""
+msgstr "çµ±åˆã‚’削除?"
msgid "ClusterIntegration|Remove this Kubernetes cluster's configuration from this project. This will not delete your actual Kubernetes cluster."
msgstr "プロジェクトã‹ã‚‰ Kubernetes クラスターã®è¨­å®šã‚’削除ã—ã¾ã™ã€‚ãªãŠã€å®Ÿéš›ã® Kubernetes クラスターã¯å‰Šé™¤ã•ã‚Œã¾ã›ã‚“。"
msgid "ClusterIntegration|Removes cluster from project but keeps associated resources"
-msgstr ""
+msgstr "プロジェクトã‹ã‚‰ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã‚’削除ã—ã¾ã™ãŒã€é–¢é€£ã™ã‚‹ãƒªã‚½ãƒ¼ã‚¹ã¯ä¿æŒã•ã‚Œã¾ã™"
msgid "ClusterIntegration|Replace this with your own hostname if you want. If you do so, point hostname to Ingress IP Address from above."
msgstr "å¿…è¦ã«å¿œã˜ã¦ã“れをã‚ãªãŸã®ãƒ›ã‚¹ãƒˆåã«ç½®ãæ›ãˆã¾ã™ã€‚ãã†ã™ã‚‹å ´åˆã€hostname ã¯ä¸Šã® Ingress IP アドレスを指ã—ã¾ã™ã€‚"
@@ -4862,13 +5121,13 @@ msgid "ClusterIntegration|Search domains"
msgstr ""
msgid "ClusterIntegration|Search instance types"
-msgstr ""
+msgstr "インスタンスタイプを検索"
msgid "ClusterIntegration|Search machine types"
msgstr "マシンタイプã®æ¤œç´¢"
msgid "ClusterIntegration|Search networks"
-msgstr ""
+msgstr "ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã®æ¤œç´¢"
msgid "ClusterIntegration|Search projects"
msgstr "プロジェクトã®æ¤œç´¢"
@@ -4883,7 +5142,7 @@ msgid "ClusterIntegration|Search subnets"
msgstr "サブãƒãƒƒãƒˆã‚’検索"
msgid "ClusterIntegration|Search subnetworks"
-msgstr ""
+msgstr "サブãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã®æ¤œç´¢"
msgid "ClusterIntegration|Search zones"
msgstr "ゾーンを検索"
@@ -4901,10 +5160,10 @@ msgid "ClusterIntegration|Select a VPC to choose a subnet"
msgstr "VPC ã‚’é¸æŠžã—ã¦ã‚µãƒ–ãƒãƒƒãƒˆã‚’é¸æŠž"
msgid "ClusterIntegration|Select a VPC to use for your EKS Cluster resources. To use a new VPC, first create one on %{startLink}Amazon Web Services %{externalLinkIcon} %{endLink}."
-msgstr ""
+msgstr "EKSクラスターリソースã«ä½¿ç”¨ã™ã‚‹VPCã‚’é¸æŠžã—ã¾ã™ã€‚ æ–°ã—ã„VPCを使用ã™ã‚‹ã«ã¯ã€ã¾ãš%{startLink} Amazon Web Services%{externalLinkIcon}%{endLink}ã§ä½œæˆã—ã¾ã™ã€‚"
msgid "ClusterIntegration|Select a network to choose a subnetwork"
-msgstr ""
+msgstr "ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚’é¸æŠžã—ã¦ã‚µãƒ–ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚’é¸æŠž"
msgid "ClusterIntegration|Select a region to choose a Key Pair"
msgstr "リージョンをé¸æŠžã—ã¦ã‚­ãƒ¼ãƒšã‚¢ã‚’é¸æŠž"
@@ -4913,10 +5172,10 @@ msgid "ClusterIntegration|Select a region to choose a VPC"
msgstr "リージョンをé¸æŠžã—ã¦VPCã‚’é¸æŠž"
msgid "ClusterIntegration|Select a stack to install Crossplane."
-msgstr ""
+msgstr "スタックをé¸æŠžã—㦠Crossplane をインストールã—ã¾ã™ã€‚"
msgid "ClusterIntegration|Select a zone to choose a network"
-msgstr ""
+msgstr "ゾーンをé¸æŠžã—ã¦ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚’é¸æŠž"
msgid "ClusterIntegration|Select existing domain or use new"
msgstr ""
@@ -4934,7 +5193,7 @@ msgid "ClusterIntegration|Select project to choose zone"
msgstr "プロジェクトをé¸æŠžã—ã¦ã‚¾ãƒ¼ãƒ³ã‚’é¸æŠž"
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 %{startLink}Amazon Web Services %{externalLinkIcon} %{endLink}."
-msgstr ""
+msgstr "EC2ノードã®ä½œæˆã«ä½¿ç”¨ã•ã‚Œã‚‹ã‚­ãƒ¼ãƒšã‚¢åã‚’é¸æŠžã—ã¾ã™ã€‚ æ–°ã—ã„キーペアåを使用ã™ã‚‹ã«ã¯ã€ã¾ãš%{startLink} Amazon Web Services%{externalLinkIcon}%{endLink}ã§ã‚­ãƒ¼ãƒšã‚¢ã‚’作æˆã—ã¾ã™ã€‚"
msgid "ClusterIntegration|Select zone"
msgstr "ゾーンをé¸æŠž"
@@ -4952,25 +5211,22 @@ msgid "ClusterIntegration|Service Token"
msgstr "サービストークン"
msgid "ClusterIntegration|Service role"
-msgstr ""
+msgstr "サービスロール"
msgid "ClusterIntegration|Service token is required."
msgstr "サービストークンãŒå¿…è¦ã§ã™ã€‚"
msgid "ClusterIntegration|Set a prefix for your namespaces. If not set, defaults to your project path. If modified, existing environments will use their current namespaces until the cluster cache is cleared."
-msgstr ""
+msgstr "åå‰ç©ºé–“ã®ãƒ—レフィックスを設定ã—ã¾ã™ã€‚設定ã•ã‚Œã¦ã„ãªã„å ´åˆã€ãƒ—ロジェクトパスãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã«ãªã‚Šã¾ã™ã€‚変更ã•ã‚ŒãŸå ´åˆã€æ—¢å­˜ã®ç’°å¢ƒã¯ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã‚­ãƒ£ãƒƒã‚·ãƒ¥ãŒã‚¯ãƒªã‚¢ã•ã‚Œã‚‹ã¾ã§ã€ç¾åœ¨ã®åå‰ç©ºé–“を使用ã—ã¾ã™ã€‚"
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr "表示"
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr "å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "ClusterIntegration|Something went wrong while creating your Kubernetes cluster"
-msgstr ""
+msgstr "Kubernetes クラスターã®ä½œæˆä¸­ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸ"
msgid "ClusterIntegration|Something went wrong while installing %{title}"
msgstr "%{title} ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ä¸­ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸ"
@@ -5009,10 +5265,10 @@ msgid "ClusterIntegration|The associated load balancer and IP will be deleted an
msgstr "関連ã™ã‚‹ãƒ­ãƒ¼ãƒ‰ãƒãƒ©ãƒ³ã‚µãƒ¼ã¨IPã¯å‰Šé™¤ã•ã‚Œã€å¾©å…ƒã§ãã¾ã›ã‚“。"
msgid "ClusterIntegration|The associated private key will be deleted and cannot be restored."
-msgstr ""
+msgstr "ç´ä»˜ã‘られãŸç§˜å¯†ã‚­ãƒ¼ã¯å‰Šé™¤ã•ã‚Œã€å¾©å…ƒã§ãã¾ã›ã‚“。"
msgid "ClusterIntegration|The elastic stack collects logs from all pods in your cluster"
-msgstr ""
+msgstr "Elastic Stackã¯ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼å†…ã®ã™ã¹ã¦ã®ãƒãƒƒãƒ‰ã‹ã‚‰ãƒ­ã‚°ã‚’åŽé›†ã—ã¾ã™"
msgid "ClusterIntegration|The endpoint is in the process of being assigned. Please check your Kubernetes cluster or Quotas on Google Kubernetes Engine if it takes a long time."
msgstr "ã“ã®ã‚¨ãƒ³ãƒ‰ãƒã‚¤ãƒ³ãƒˆã¯å‰²ã‚Šå½“ã¦ãƒ—ロセス実施中ã§ã™ã€‚ã‚‚ã—処ç†æ™‚é–“ãŒé•·ã„å ´åˆã€ã‚ãªãŸã®Kubernetesクラスタã¾ãŸã¯Google Kubernetes Engineã®ã‚¯ã‚©ãƒ¼ã‚¿ã‚’確èªã—ã¦ãã ã•ã„。"
@@ -5033,10 +5289,10 @@ msgid "ClusterIntegration|To access your application after deployment, point a w
msgstr "デプロイ後ã«ã‚¢ãƒ—リケーションã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã«ã¯ã€ãƒ¯ã‚¤ãƒ«ãƒ‰ã‚«ãƒ¼ãƒ‰ DNS ã‚’ Knative エンドãƒã‚¤ãƒ³ãƒˆã«æŒ‡å®šã—ã¾ã™ã€‚"
msgid "ClusterIntegration|To remove your integration and resources, type %{clusterName} to confirm:"
-msgstr ""
+msgstr "インテグレーションã¨ãƒªã‚½ãƒ¼ã‚¹ã‚’削除ã™ã‚‹ã«ã¯ã€ %{clusterName} を入力ã—ã¦ç¢ºèªã—ã¦ãã ã•ã„。"
msgid "ClusterIntegration|To remove your integration, type %{clusterName} to confirm:"
-msgstr ""
+msgstr "インテグレーションを削除ã™ã‚‹ã«ã¯ã€ %{clusterName} を入力ã—ã¦ç¢ºèªã—ã¦ãã ã•ã„。"
msgid "ClusterIntegration|Toggle Kubernetes cluster"
msgstr "Kubernetes クラスターを切り替ãˆ"
@@ -5044,6 +5300,9 @@ msgstr "Kubernetes クラスターを切り替ãˆ"
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr "%{appTitle} をアンインストール"
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr "æ›´æ–°ã«å¤±æ•—ã—ã¾ã—ãŸã€‚ログを確èªã—ã¦ã‚‚ã†ä¸€åº¦è©¦ã—ã¦ãã ã•ã„。"
@@ -5066,14 +5325,17 @@ msgid "ClusterIntegration|With a Kubernetes cluster associated to this project,
msgstr "ã“ã®ãƒ—ロジェクト㫠Kubernetes クラスターを関連付ã‘ã‚‹ã“ã¨ã§ã€Review Apps ã®ä½¿ç”¨ã€ã‚¢ãƒ—リケーションã®ãƒ‡ãƒ—ロイã€ãƒ‘イプラインã®å®Ÿè¡Œãªã©ã‚’ç°¡å˜ã«è¡Œã†ã“ã¨ãŒã§ãã¾ã™ã€‚"
msgid "ClusterIntegration|You are about to remove your cluster integration and all GitLab-created resources associated with this cluster."
-msgstr ""
+msgstr "クラスター統åˆã¨ã€ã“ã®ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã«é–¢é€£ä»˜ã‘られã¦ã„ã‚‹ GitLab ãŒä½œæˆã—ãŸã™ã¹ã¦ã®ãƒªã‚½ãƒ¼ã‚¹ã‚’削除ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚"
msgid "ClusterIntegration|You are about to remove your cluster integration."
-msgstr ""
+msgstr "クラスターインテグレーションを削除ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚"
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr "クラスターã‹ã‚‰ %{appTitle} をアンインストールã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚"
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr "次ã®ã‚¢ãƒ—リケーションをインストールã™ã‚‹å‰ã«ã€Helm Tiller をインストールã—ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“"
@@ -5083,9 +5345,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr "Knative をインストールã™ã‚‹ã«ã¯ã€RBAC 対応ã®ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ãŒå¿…è¦ã§ã™ã€‚"
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr "アカウント㫠%{link_to_kubernetes_engine} ãŒå¿…è¦ã§ã™ã€‚"
@@ -5120,7 +5388,7 @@ msgid "ClusterIntergation|Select a VPC"
msgstr "VPCã‚’é¸æŠž"
msgid "ClusterIntergation|Select a network"
-msgstr ""
+msgstr "ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚’é¸æŠž"
msgid "ClusterIntergation|Select a region"
msgstr "リージョンã®é¸æŠž"
@@ -5132,7 +5400,7 @@ msgid "ClusterIntergation|Select a subnet"
msgstr "サブãƒãƒƒãƒˆã‚’é¸æŠž"
msgid "ClusterIntergation|Select a subnetwork"
-msgstr ""
+msgstr "サブãƒãƒƒãƒˆã‚’é¸æŠž"
msgid "ClusterIntergation|Select an instance type"
msgstr "インスタンスタイプをé¸æŠž"
@@ -5141,6 +5409,9 @@ msgid "ClusterIntergation|Select key pair"
msgstr "キーペアをé¸æŠž"
msgid "ClusterIntergation|Select service role"
+msgstr "サービスロールをé¸æŠž"
+
+msgid "Clusters|An error occurred while loading clusters"
msgstr ""
msgid "Code"
@@ -5161,6 +5432,9 @@ msgstr "コードレビュー"
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr "コードオーナーã®æ‰¿èªãŒå¿…è¦ã§ã™"
@@ -5177,7 +5451,7 @@ msgid "Cohorts|Inactive users"
msgstr "アクティブã§ã¯ãªã„ユーザー"
msgid "Cohorts|Month %{month_index}"
-msgstr "%{month_index} 月 "
+msgstr "%{month_index} ヶ月目"
msgid "Cohorts|New users"
msgstr "æ–°è¦ãƒ¦ãƒ¼ã‚¶ãƒ¼"
@@ -5195,11 +5469,14 @@ msgid "Collapse"
msgstr "折りãŸãŸã‚€"
msgid "Collapse approvers"
-msgstr ""
+msgstr "承èªè€…ã‚’éžè¡¨ç¤ºã«ã™ã‚‹"
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr "サイドãƒãƒ¼ã‚’éš ã™"
@@ -5209,6 +5486,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr "ComboSearch ãŒå®šç¾©ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr "コマンド"
@@ -5245,6 +5525,9 @@ msgstr "コメントフォームã®ä½ç½®"
msgid "Comment is being updated"
msgstr "コメントãŒæ›´æ–°ã•ã‚Œã¦ã„ã¾ã™"
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr "コメント/返信 (é¸æŠžã—ãŸãƒ†ã‚­ã‚¹ãƒˆã‚’引用ã—ã¾ã™)"
@@ -5271,7 +5554,7 @@ msgid "Commit message"
msgstr "コミットメッセージ"
msgid "Commit message (optional)"
-msgstr ""
+msgstr "コミットメッセージ (オプション)"
msgid "Commit statistics for %{ref} %{start_time} - %{end_time}"
msgstr "%{start_time} ã‹ã‚‰ %{end_time} ã¾ã§ã® %{ref} ブランãƒã®çµ±è¨ˆ"
@@ -5405,7 +5688,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5429,14 +5715,11 @@ msgstr "Let's Encryptを設定"
msgid "Configure Prometheus"
msgstr "Prometheusã®è¨­å®š"
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr "トレースã®æ§‹æˆ"
msgid "Configure a <code>.gitlab-webide.yml</code> file in the <code>.gitlab</code> directory to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
-msgstr ""
+msgstr "Webターミナルã®ä½¿ç”¨ã‚’開始ã™ã‚‹ã«ã¯ã€ <code>.gitlab</code> ディレクトリ㮠<code>.gitlab-webide.yml</code> ファイルを設定ã—ã¾ã™ã€‚ 詳細ã¯%{helpStart}ã“ã¡ã‚‰%{helpEnd}ã§ã™ã€‚"
msgid "Configure automatic git checks and housekeeping on repositories."
msgstr "リãƒã‚¸ãƒˆãƒªã«å¯¾ã—ã¦è‡ªå‹•å®Ÿè¡Œã™ã‚‹ Git ãƒã‚§ãƒƒã‚¯ã¨ãƒã‚¦ã‚¹ã‚­ãƒ¼ãƒ”ングを設定ã—ã¾ã™ã€‚"
@@ -5457,7 +5740,7 @@ msgid "Configure paths to be protected by Rack Attack."
msgstr ""
msgid "Configure repository mirroring."
-msgstr ""
+msgstr "リãƒã‚¸ãƒˆãƒªã®ãƒŸãƒ©ãƒ¼ãƒªãƒ³ã‚°ã‚’設定ã—ã¾ã™ã€‚"
msgid "Configure storage path settings."
msgstr "ストレージパス設定を構æˆã—ã¾ã™ã€‚"
@@ -5465,9 +5748,6 @@ msgstr "ストレージパス設定を構æˆã—ã¾ã™ã€‚"
msgid "Configure the %{link} integration."
msgstr "%{link} ã®çµ±åˆã‚’設定ã—ã¾ã™ 。"
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr "ユーザーãŒæ–°ã—ã„アカウントを作æˆã™ã‚‹æ–¹æ³•ã‚’設定ã—ã¾ã™ã€‚"
@@ -5514,25 +5794,19 @@ msgid "Connection failure"
msgstr "接続ã«å¤±æ•—ã—ã¾ã—ãŸ"
msgid "Connection timed out"
-msgstr ""
-
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr "%{namespace_name} グループã®ã‚ªãƒ¼ãƒŠãƒ¼ã«é€£çµ¡ã—ã¦ã€ãƒ—ランをアップグレードã—ã¦ãã ã•ã„。"
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr "オーナー㮠%{link_start}%{owner_name}%{link_end} ã«é€£çµ¡ã—ã¦ã€è¨ˆç”»ã‚’æ›´æ–°ã—ã¦ãã ã•ã„。"
+msgstr "接続タイムアウト"
msgid "Contact sales to upgrade"
msgstr "アップグレードã®å•ã„åˆã‚ã›"
-msgid "Contact your Administrator to upgrade your license."
-msgstr "システム管ç†è€…ã«é€£çµ¡ã—ã¦ã€ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã‚’アップグレードã—ã¦ãã ã•ã„。"
+msgid "Contact support"
+msgstr ""
msgid "Container Registry"
msgstr "コンテナレジストリ"
msgid "Container Registry tag expiration policy"
-msgstr ""
+msgstr "コンテナレジストリタグã®æœ‰åŠ¹æœŸé™ãƒãƒªã‚·ãƒ¼"
msgid "Container Scanning"
msgstr "コンテナã®ã‚¹ã‚­ãƒ£ãƒ³"
@@ -5544,7 +5818,7 @@ msgid "Container registry images"
msgstr "コンテナレジストリã®ã‚¤ãƒ¡ãƒ¼ã‚¸"
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 "コンテナレジストリã¯ã€ã“ã® GitLab インスタンスã§æœ‰åŠ¹ã«ãªã£ã¦ã„ã¾ã›ã‚“。 AutoDevOps ãŒæ©Ÿèƒ½ã™ã‚‹ãŸã‚ã«ã¯ã€ç®¡ç†è€…ã«æœ‰åŠ¹ã«ã™ã‚‹ã‚ˆã†ä¾é ¼ã—ã¦ãã ã•ã„。"
msgid "Container repositories sync capacity"
msgstr ""
@@ -5552,6 +5826,14 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5559,11 +5841,14 @@ msgid "ContainerRegistry|%{title} was successfully scheduled for deletion"
msgstr ""
msgid "ContainerRegistry|Automatically remove extra images that aren't designed to be kept."
-msgstr ""
+msgstr "ä¿å­˜ã™ã‚‹ã‚ˆã†ã«è¨­è¨ˆã•ã‚Œã¦ã„ãªã„ã€è¿½åŠ ã®ã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’自動的ã«å‰Šé™¤ã—ã¾ã™ã€‚"
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5586,32 +5871,44 @@ msgid "ContainerRegistry|Docker connection error"
msgstr "Docker接続エラー"
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
-msgstr ""
+msgstr "Docker tagã®æœ‰åŠ¹æœŸé™ãƒãƒªã‚·ãƒ¼ã¯ %{toggleStatus}"
+
+msgid "ContainerRegistry|Expiration interval:"
+msgstr "有効期é™:"
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
+msgstr "有効期é™ãƒãƒªã‚·ãƒ¼ãŒæ­£å¸¸ã«ä¿å­˜ã•ã‚Œã¾ã—ãŸã€‚"
+
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
msgstr ""
msgid "ContainerRegistry|Expiration policy:"
-msgstr ""
+msgstr "有効期é™ãƒãƒªã‚·ãƒ¼:"
msgid "ContainerRegistry|Expiration schedule:"
+msgstr "有効期é™ã‚¹ã‚±ã‚¸ãƒ¥ãƒ¼ãƒ«:"
+
+msgid "ContainerRegistry|Filter by name"
msgstr ""
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
-msgstr ""
+msgstr "ã¾ã ãƒ­ã‚°ã‚¤ãƒ³ã—ã¦ã„ãªã„å ´åˆã€GitLab ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼åã¨ãƒ‘スワードを使用ã—ã¦ã‚³ãƒ³ãƒ†ãƒŠãƒ¬ã‚¸ã‚¹ãƒˆãƒªã‚’èªè¨¼ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚ %{twofaDocLinkStart} 2è¦ç´ èªè¨¼ã‚’ %{twofaDocLinkEnd} 有効ã«ã—ã¦ã„ã‚‹å ´åˆã¯ã€ãƒ‘スワードã®ä»£ã‚ã‚Šã« %{personalAccessTokensDocLinkStart} パーソナルアクセストークン%{personalAccessTokensDocLinkEnd} 使用ã—ã¾ã™ã€‚"
msgid "ContainerRegistry|Image ID"
msgstr "イメージID"
-msgid "ContainerRegistry|Keep and protect the images that matter most."
+msgid "ContainerRegistry|Image Repositories"
msgstr ""
+msgid "ContainerRegistry|Keep and protect the images that matter most."
+msgstr "é‡è¦ãªç”»åƒã‚’ä¿æŒãŠã‚ˆã³ä¿è­·ã—ã¾ã™ã€‚"
+
msgid "ContainerRegistry|Last Updated"
msgstr "最終更新日"
@@ -5622,7 +5919,7 @@ msgid "ContainerRegistry|Missing or insufficient permission, delete button disab
msgstr ""
msgid "ContainerRegistry|Number of tags to retain:"
-msgstr ""
+msgstr "ä¿æŒã™ã‚‹ã‚¿ã‚°ã®æ•°:"
msgid "ContainerRegistry|Please contact your administrator."
msgstr ""
@@ -5630,10 +5927,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr "クイックスタート"
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5652,11 +5946,8 @@ msgid "ContainerRegistry|Remove tag"
msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] "ã‚¿ã‚°ã®å‰Šé™¤"
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
-msgstr ""
+msgstr "有効期é™ãƒãƒªã‚·ãƒ¼ã®å–得中ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "ContainerRegistry|Something went wrong while fetching the repository list."
msgstr ""
@@ -5674,13 +5965,16 @@ msgid "ContainerRegistry|Something went wrong while scheduling %{title} for dele
msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
+msgstr "有効期é™ãƒãƒªã‚·ãƒ¼ã®æ›´æ–°ä¸­ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
+
+msgid "ContainerRegistry|Sorry, your filter produced no results."
msgstr ""
msgid "ContainerRegistry|Tag"
msgstr "ã‚¿ã‚°"
msgid "ContainerRegistry|Tag expiration policy"
-msgstr ""
+msgstr "ã‚¿ã‚°ã®æœ‰åŠ¹æœŸé™ãƒãƒªã‚·ãƒ¼"
msgid "ContainerRegistry|Tag expiration policy is designed to:"
msgstr ""
@@ -5701,16 +5995,10 @@ msgid "ContainerRegistry|The Container Registry tag expiration and retention pol
msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
+msgstr "ã“ã®ç”»åƒã«é–¢é€£ã™ã‚‹æœ€å¾Œã®ã‚¿ã‚°ãŒæœ€è¿‘削除ã•ã‚Œã¾ã—ãŸã€‚ã“ã®ç©ºã®ç”»åƒã¨ãã‚Œã«é–¢é€£ã—ãŸãƒ‡ãƒ¼ã‚¿ã¯ã€é€šå¸¸ã®ã‚¬ãƒ™ãƒ¼ã‚¸ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ãƒ—ロセスã®ä¸€éƒ¨ã¨ã—ã¦è‡ªå‹•çš„ã«å‰Šé™¤ã•ã‚Œã¾ã™ã€‚質å•ãŒã‚ã‚‹å ´åˆã¯ã€ç®¡ç†è€…ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。"
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
-msgstr ""
+msgstr "ã“ã®å…¥åŠ›å€¤ã®æ–‡å­—æ•°ã¯255未満ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“"
msgid "ContainerRegistry|There are no container images available in this group"
msgstr "ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«ã¯åˆ©ç”¨ã§ãるコンテナイメージãŒã‚ã‚Šã¾ã›ã‚“"
@@ -5727,16 +6015,19 @@ msgstr "ã“ã®ã‚¤ãƒ¡ãƒ¼ã‚¸ã«ã¯æœ‰åŠ¹ãªã‚¿ã‚°ãŒã‚ã‚Šã¾ã›ã‚“"
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
msgstr ""
-msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgstr "コンテナレジストリã§ã€å„プロジェクトã¯Dockerイメージを格ç´ã™ã‚‹å ´æ‰€ã‚’æŒã¦ã¾ã™ã€‚%{docLinkStart} 詳細ã¯ã“ã¡ã‚‰ %{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 "コンテナレジストリを使用ã™ã‚‹ã¨ã€ã™ã¹ã¦ã®ãƒ—ロジェクトã«Dockerイメージをä¿å­˜ã™ã‚‹ãŸã‚ã®ç‹¬è‡ªã®ã‚¹ãƒšãƒ¼ã‚¹ã‚’確ä¿ã§ãã¾ã™ã€‚ ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã®ãƒ—ロジェクトã®1ã¤ã«å°‘ãªãã¨ã‚‚1ã¤ã®Dockerイメージをプッシュã—ã¦ã€ã“ã“ã«è¡¨ç¤ºã—ã¾ã™ã€‚ %{docLinkStart}詳細情報%{docLinkEnd}"
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5749,10 +6040,10 @@ 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 "次ã®ã‚³ãƒžãƒ³ãƒ‰ã‚’使用ã—ã¦ã€ã“ã®ãƒ¬ã‚¸ã‚¹ãƒˆãƒªã«ã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’追加ã§ãã¾ã™ï¼š"
msgid "Contains %{count} blobs of images (%{size})"
-msgstr ""
+msgstr "%{count} 個ã®ã‚¤ãƒ¡ãƒ¼ã‚¸ãŒå«ã¾ã‚Œã¦ã„ã¾ã™(%{size})"
msgid "Contents of .gitlab-ci.yml"
msgstr ".gitlab-ci.yml ã®å†…容"
@@ -5775,20 +6066,20 @@ msgstr "貢献度"
msgid "Contribution Analytics"
msgstr "貢献度分æž"
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
-msgstr ""
-
msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgstr "<strong>%{created_count}</strong> 件を作æˆã€<strong>%{closed_count}</strong>件をクローズã—ã¾ã—ãŸã€‚"
+
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
-msgstr ""
+msgstr "<strong>%{pushes}</strong>回ã®ãƒ—ッシュã€<strong>%{commits}</strong>回以上ã®ã‚³ãƒŸãƒƒãƒˆãŒè²¢çŒ®è€…<strong>%{people}</strong>ã«ã‚ˆã£ã¦è¡Œã‚ã‚Œã¾ã—ãŸã€‚"
msgid "ContributionAnalytics|Contribution analytics for issues, merge requests and push events since %{start_date}"
-msgstr ""
+msgstr "%{start_date} 以é™ã®ã€èª²é¡Œã€ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã€ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã€ プッシュã«ã¤ã„ã¦ã®è²¢çŒ®åº¦åˆ†æž"
msgid "ContributionAnalytics|Issues"
-msgstr ""
+msgstr "課題"
msgid "ContributionAnalytics|Last 3 months"
msgstr "éŽåŽ»3ã‹æœˆ"
@@ -5797,19 +6088,19 @@ msgid "ContributionAnalytics|Last month"
msgstr "先月"
msgid "ContributionAnalytics|Last week"
-msgstr ""
+msgstr "先週"
msgid "ContributionAnalytics|Merge Requests"
-msgstr ""
+msgstr "マージリクエスト"
msgid "ContributionAnalytics|No issues for the selected time period."
-msgstr ""
+msgstr "é¸æŠžã•ã‚ŒãŸæœŸé–“内ã«èª²é¡Œã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "ContributionAnalytics|No merge requests for the selected time period."
-msgstr ""
+msgstr "é¸æŠžã•ã‚ŒãŸæœŸé–“内ã«ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã¯ã‚ã‚Šã¾ã›ã‚“。"
msgid "ContributionAnalytics|No pushes for the selected time period."
-msgstr ""
+msgstr "é¸æŠžã•ã‚ŒãŸæœŸé–“内ã«ãƒ—ッシュã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "Contributions for <strong>%{calendar_date}</strong>"
msgstr "<strong>%{calendar_date}</strong>ã®è²¢çŒ®"
@@ -5821,7 +6112,7 @@ msgid "Contributors"
msgstr "貢献者"
msgid "Control emails linked to your account"
-msgstr ""
+msgstr "アカウントã«ç´ã¥ãメールã®ç®¡ç†"
msgid "Control the display of third party offers."
msgstr "サードパーティã®ã‚ªãƒ•ã‚¡ãƒ¼ã®è¡¨ç¤ºã‚’管ç†ã—ã¾ã™ã€‚"
@@ -5854,7 +6145,7 @@ msgid "Copy"
msgstr "コピー"
msgid "Copy %{field}"
-msgstr ""
+msgstr "%{field} をコピー"
msgid "Copy %{http_label} clone URL"
msgstr "%{http_label} クローン URL をコピー"
@@ -5865,6 +6156,9 @@ msgstr "%{protocol} クローン URL をコピー"
msgid "Copy %{proxy_url}"
msgstr "%{proxy_url} をコピー"
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr "クリップボードã«ã‚¢ã‚«ã‚¦ãƒ³ãƒˆ ID をコピー"
@@ -5899,7 +6193,7 @@ msgid "Copy commit SHA"
msgstr "コミットã®SHAをコピー"
msgid "Copy environment"
-msgstr ""
+msgstr "環境をコピー"
msgid "Copy evidence SHA"
msgstr ""
@@ -5910,9 +6204,6 @@ msgstr "ファイルã®å†…容をコピー"
msgid "Copy file path"
msgstr "ファイルã®ãƒ‘スをコピー"
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -5928,9 +6219,6 @@ msgstr "リンクをコピー"
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr "個人ã®ã‚¢ã‚¯ã‚»ã‚¹ãƒˆãƒ¼ã‚¯ãƒ³ã‚’コピー"
-
msgid "Copy reference"
msgstr "å‚ç…§ã®ã‚³ãƒ”ー"
@@ -5962,7 +6250,7 @@ msgid "Could not connect to Sentry. Refresh the page to try again."
msgstr ""
msgid "Could not connect to Web IDE file mirror service."
-msgstr ""
+msgstr "Web IDE ã®ãƒ•ã‚¡ã‚¤ãƒ«ãƒŸãƒ©ãƒ¼ã‚µãƒ¼ãƒ“スã«æŽ¥ç¶šã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
msgid "Could not create Wiki Repository at this time. Please try again later."
msgstr "Wikiリãƒã‚¸ãƒˆãƒªã‚’作æˆã§ãã¾ã›ã‚“ã§ã—ãŸã€‚後ã§ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
@@ -5977,7 +6265,7 @@ msgid "Could not create project"
msgstr "プロジェクトを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ"
msgid "Could not delete %{design}. Please try again."
-msgstr ""
+msgstr "%{design} を削除ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。"
msgid "Could not delete chat nickname %{chat_name}."
msgstr "ãƒãƒ£ãƒƒãƒˆã®ãƒ‹ãƒƒã‚¯ãƒãƒ¼ãƒ  %{chat_name} を削除ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
@@ -5992,16 +6280,16 @@ msgid "Could not restore the group"
msgstr "グループをリストアã§ãã¾ã›ã‚“ã§ã—ãŸ"
msgid "Could not revoke impersonation token %{token_name}."
-msgstr ""
+msgstr "代ç†ãƒˆãƒ¼ã‚¯ãƒ³ %{token_name} を無効ã«ã§ãã¾ã›ã‚“。"
msgid "Could not revoke personal access token %{personal_access_token_name}."
msgstr "個人ã®ã‚¢ã‚¯ã‚»ã‚¹ãƒˆãƒ¼ã‚¯ãƒ³ %{personal_access_token_name} を無効ã«ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
msgid "Could not revoke project access token %{project_access_token_name}."
-msgstr ""
+msgstr "プロジェクトアクセストークン %{project_access_token_name} を無効ã«ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
msgid "Could not save group ID"
-msgstr ""
+msgstr "グループIDã‚’ä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸ"
msgid "Could not save project ID"
msgstr "プロジェクトIDã‚’ä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸ"
@@ -6027,7 +6315,7 @@ msgstr "作æˆ"
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6037,7 +6325,7 @@ msgid "Create New Domain"
msgstr "æ–°ã—ã„ドメインを作æˆ"
msgid "Create Project"
-msgstr ""
+msgstr "プロジェクトを作æˆ"
msgid "Create a GitLab account first, and then connect it to your %{label} account."
msgstr "ã¯ã˜ã‚ã«GitLabアカウントを作æˆã—ã€ãã®å¾Œ %{label} ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã«æŽ¥ç¶šã—ã¾ã™ã€‚"
@@ -6045,9 +6333,6 @@ msgstr "ã¯ã˜ã‚ã«GitLabアカウントを作æˆã—ã€ãã®å¾Œ %{label} ã®ã‚
msgid "Create a Mattermost team for this group"
msgstr "ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã® Mattermost ãƒãƒ¼ãƒ ã‚’作æˆã—ã¾ã™"
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr "é »ç¹ã«ä½¿ç”¨ã™ã‚‹ã‚¢ãƒƒãƒ—ストリームイメージをä¿å­˜ã™ã‚‹ãŸã‚ã€ãƒ­ãƒ¼ã‚«ãƒ«ãƒ—ロキシを作æˆã—ã¾ã™ã€‚ %{link_start}ä¾å­˜é–¢ä¿‚プロキシã«ã¤ã„ã¦ã¯ã“ã¡ã‚‰ã‚’å‚ç…§ã—ã¦ãã ã•ã„%{link_end}。"
@@ -6066,9 +6351,6 @@ msgstr "ã¾ã ãƒ•ã‚¡ã‚¤ãƒ«ãŒãªã„ãŸã‚ã€æ–°ã—ã„ファイルを作æˆã—ã¾
msgid "Create a new issue"
msgstr "課題ã®æ–°è¦ä½œæˆ"
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr "æ–°ã—ã„リãƒã‚¸ãƒˆãƒªã‚’作æˆ"
@@ -6076,16 +6358,13 @@ msgid "Create a personal access token on your account to pull or push via %{prot
msgstr "%{protocol} ã§ãƒ—ッシュやプルã™ã‚‹ãŸã‚ã®ã‚ãªãŸå€‹äººç”¨ã‚¢ã‚¯ã‚»ã‚¹ãƒˆãƒ¼ã‚¯ãƒ³ã‚’作æˆ"
msgid "Create an account using:"
-msgstr ""
-
-msgid "Create an issue"
-msgstr "課題を作æˆ"
+msgstr "アカウントを作æˆã™ã‚‹ã€‚ãã®æ–¹æ³•:"
msgid "Create an issue. Issues are created for each alert triggered."
msgstr "課題を作æˆã™ã‚‹ã€‚課題ã¯ç™ºç”Ÿã—ãŸå„アラート毎ã«ä½œæˆã•ã‚Œã¾ã™ã€‚"
msgid "Create and provide your GitHub %{link_start}Personal Access Token%{link_end}. You will need to select the <code>repo</code> scope, so we can display a list of your public and private repositories which are available to import."
-msgstr ""
+msgstr "GitHub ã®%{link_start}Personal Access Token%{link_end} を作æˆã—ã¦ã€æä¾›ã—ã¦ãã ã•ã„。<code>repo</code> スコープをé¸æŠžã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚ã“ã‚Œã«ã‚ˆã‚Šã‚¤ãƒ³ãƒãƒ¼ãƒˆã§ãる公開ã¾ãŸã¯éžå…¬é–‹ãƒªãƒã‚¸ãƒˆãƒªã®ä¸€è¦§ã‚’表示ã§ãã¾ã™ã€‚"
msgid "Create board"
msgstr "ボードを作æˆ"
@@ -6123,6 +6402,9 @@ msgstr "グループラベルを作æˆ"
msgid "Create issue"
msgstr "課題ã®ä½œæˆ"
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr "ラベルã‹ã‚‰ãƒªã‚¹ãƒˆã‚’作æˆã€‚ãã®ãƒ©ãƒ™ãƒ«ã®èª²é¡ŒãŒãƒªã‚¹ãƒˆã«è¡¨ç¤ºã•ã‚Œã¾ã™ã€‚"
@@ -6135,6 +6417,9 @@ msgstr "マージリクエストã¨ãƒ–ランãƒã‚’作æˆ"
msgid "Create milestone"
msgstr "マイルストーンを作æˆ"
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr "æ–°ã—ã„ボードを作æˆ"
@@ -6163,7 +6448,7 @@ msgid "Create project label"
msgstr "プロジェクトラベルを作æˆ"
msgid "Create requirement"
-msgstr ""
+msgstr "è¦æ±‚事項を作æˆ"
msgid "Create snippet"
msgstr ""
@@ -6174,6 +6459,12 @@ msgstr ""
msgid "Create your first page"
msgstr "最åˆã®ãƒšãƒ¼ã‚¸ã‚’作æˆã™ã‚‹"
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr "ã‚ãªãŸã¯ã€ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«ã‚µãƒ–グループを作æˆã™ã‚‹æ¨©é™ãŒã‚ã‚Šã¾ã›ã‚“。"
@@ -6196,17 +6487,20 @@ msgid "Created At"
msgstr "作æˆæ—¥"
msgid "Created On"
-msgstr ""
+msgstr "作æˆæ—¥æ™‚"
msgid "Created a branch and a merge request to resolve this issue."
-msgstr ""
+msgstr "ブランãƒã‚’作æˆã—マージリクエストを作æˆã—ã¾ã—ãŸã€‚ã“ã‚Œã§ã“ã®èª²é¡Œã‚’解決ã§ãã¾ã™ã€‚"
msgid "Created branch '%{branch_name}' and a merge request to resolve this issue."
-msgstr ""
+msgstr "'%{branch_name}' ブランãƒã‚’作æˆã—マージリクエストを作æˆã—ã¾ã—ãŸã€‚ã“ã‚Œã§ã“ã®èª²é¡Œã‚’解決ã§ãã¾ã™ã€‚"
msgid "Created by me"
msgstr "自分ãŒä½œæˆ"
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr "作æˆã—ãŸèª²é¡Œ %{issueLink}"
@@ -6214,7 +6508,7 @@ msgid "Created issue %{issueLink} at %{projectLink}"
msgstr "%{projectLink} ã«èª²é¡Œ %{issueLink} を作æˆã—ã¾ã—ãŸ"
msgid "Created merge request %{mergeRequestLink}"
-msgstr ""
+msgstr "作æˆã—ãŸãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆ %{mergeRequestLink}"
msgid "Created merge request %{mergeRequestLink} at %{projectLink}"
msgstr "%{projectLink} ã«ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆ %{mergeRequestLink} を作æˆã—ã¾ã—ãŸ"
@@ -6226,16 +6520,16 @@ msgid "Created on:"
msgstr "作æˆæ—¥æ™‚:"
msgid "Creates a branch and a merge request to resolve this issue."
-msgstr ""
+msgstr "ブランãƒã‚’作æˆã—マージリクエストを作æˆã—ã¦ã€ã“ã®èª²é¡Œã‚’解決ã—ã¾ã™ã€‚"
msgid "Creates branch '%{branch_name}' and a merge request to resolve this issue."
-msgstr ""
+msgstr "'%{branch_name}' ブランãƒã‚’作æˆã—マージリクエストを作æˆã—ã€ã“ã®èª²é¡Œã‚’解決ã—ã¾ã™ã€‚"
msgid "Creating epic"
msgstr "エピックを作æˆã—ã¦ã„ã¾ã™"
msgid "Creating graphs uses the data from the Prometheus server. If this takes a long time, ensure that data is available."
-msgstr ""
+msgstr "グラフを作æˆã™ã‚‹ã«ã¯ã€Prometheusサーãƒãƒ¼ã‹ã‚‰ã®ãƒ‡ãƒ¼ã‚¿ã‚’使用ã—ã¾ã™ã€‚ã“ã‚Œã«æ™‚é–“ãŒã‹ã‹ã‚‹å ´åˆã¯ã€ãƒ‡ãƒ¼ã‚¿ãŒåˆ©ç”¨ã§ãã‚‹ã‹ã©ã†ã‹ã‚’確èªã—ã¦ãã ã•ã„。"
msgid "Creation date"
msgstr "作æˆæ—¥æ™‚"
@@ -6258,11 +6552,8 @@ msgstr "é‡å¤§ãªè„†å¼±æ€§ã®å­˜åœ¨"
msgid "Cron Timezone"
msgstr "Cron ã®ã‚¿ã‚¤ãƒ ã‚¾ãƒ¼ãƒ³"
-msgid "Cron syntax"
-msgstr "Cron ã®æ§‹æ–‡"
-
msgid "Crossplane"
-msgstr ""
+msgstr "Crossplane"
msgid "Current Branch"
msgstr "ç¾åœ¨ã®ãƒ–ランãƒ"
@@ -6297,6 +6588,9 @@ msgstr "設定"
msgid "CurrentUser|Start a Gold trial"
msgstr "Gold試用版を開始"
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr "カスタムCIã®è¨­å®šãƒ‘ス"
@@ -6319,6 +6613,9 @@ msgid "Custom project templates have not been set up for groups that you are a m
msgstr "カスタムプロジェクトテンプレートã¯ã€ã‚ãªãŸãŒãƒ¡ãƒ³ãƒãƒ¼ã«ãªã£ã¦ã„るグループã«ã¯è¨­å®šã•ã‚Œã¦ã„ã¾ã›ã‚“。ãれらã¯ã‚°ãƒ«ãƒ¼ãƒ—ã®è¨­å®šãƒšãƒ¼ã‚¸ã‹ã‚‰æœ‰åŠ¹ã«ãªã‚Šã¾ã™ã€‚グループã®ã‚ªãƒ¼ãƒŠãƒ¼ã¾ãŸã¯ãƒ¡ãƒ³ãƒ†ãƒŠãƒ¼ã«é€£çµ¡ã—ã¦ã€ã‚«ã‚¹ã‚¿ãƒ ãƒ—ロジェクトテンプレートを設定ã—ã¦ãã ã•ã„。"
msgid "Custom range"
+msgstr "カスタム範囲"
+
+msgid "Custom range (UTC)"
msgstr ""
msgid "CustomCycleAnalytics|Add a stage"
@@ -6331,31 +6628,31 @@ msgid "CustomCycleAnalytics|Editing stage"
msgstr "ステージã®ç·¨é›†"
msgid "CustomCycleAnalytics|Enter a name for the stage"
-msgstr ""
+msgstr "ステージã®åå‰ã‚’入力ã—ã¦ãã ã•ã„"
msgid "CustomCycleAnalytics|Name"
msgstr "åå‰"
msgid "CustomCycleAnalytics|New stage"
-msgstr ""
+msgstr "新ステージ"
msgid "CustomCycleAnalytics|Please select a start event first"
-msgstr ""
+msgstr "開始イベントを先ã«é¸æŠžã—ã¦ãã ã•ã„。"
msgid "CustomCycleAnalytics|Select start event"
-msgstr ""
+msgstr "開始イベントをé¸æŠžã—ã¦ãã ã•ã„。"
msgid "CustomCycleAnalytics|Select stop event"
-msgstr ""
+msgstr "åœæ­¢ã‚¤ãƒ™ãƒ³ãƒˆã‚’é¸æŠžã—ã¦ãã ã•ã„。"
msgid "CustomCycleAnalytics|Stage name already exists"
-msgstr ""
+msgstr "ãã®ã‚¹ãƒ†ãƒ¼ã‚¸åã¯æ—¢ã«å­˜åœ¨ã—ã¦ã„ã¾ã™"
msgid "CustomCycleAnalytics|Start event"
msgstr "開始イベント"
msgid "CustomCycleAnalytics|Start event changed, please select a valid stop event"
-msgstr ""
+msgstr "開始イベントãŒå¤‰æ›´ã•ã‚Œã¾ã—ãŸã€‚有効ãªåœæ­¢ã‚¤ãƒ™ãƒ³ãƒˆã‚’é¸æŠžã—ã¦ãã ã•ã„。"
msgid "CustomCycleAnalytics|Start event label"
msgstr "開始イベントã®ãƒ©ãƒ™ãƒ«"
@@ -6369,6 +6666,9 @@ msgstr "åœæ­¢ã‚¤ãƒ™ãƒ³ãƒˆã®ãƒ©ãƒ™ãƒ«"
msgid "CustomCycleAnalytics|Update stage"
msgstr "ステージã®æ›´æ–°"
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr "カスタムカラー"
@@ -6391,6 +6691,9 @@ msgid "Customize your pipeline configuration, view your pipeline status and cove
msgstr "Runner トークンã«ã‚¢ã‚¯ã‚»ã‚¹ã—ã€ãƒ‘イプラインã®è¨­å®šã‚’カスタマイズã€ãã—ã¦ãƒ‘イプラインã®çŠ¶æ…‹ã¨ã‚«ãƒãƒ¬ãƒƒã‚¸ãƒ¬ãƒãƒ¼ãƒˆã‚’閲覧ã—ã¾ã™ã€‚"
msgid "Customize your pipeline configuration."
+msgstr "パイプライン設定をカスタマイズ"
+
+msgid "Cycle Time"
msgstr ""
msgid "CycleAnalyticsEvent|Issue closed"
@@ -6409,7 +6712,7 @@ msgid "CycleAnalyticsEvent|Issue first associated with a milestone or issue firs
msgstr "最åˆã«ãƒžã‚¤ãƒ«ã‚¹ãƒˆãƒ¼ãƒ³ã«é–¢é€£ã¥ã‘られãŸèª²é¡Œã€ã¾ãŸã¯æœ€åˆã«ãƒœãƒ¼ãƒ‰ã«åŠ ãˆã‚‰ã‚ŒãŸèª²é¡Œ"
msgid "CycleAnalyticsEvent|Issue first mentioned in a commit"
-msgstr ""
+msgstr "コミットã§æœ€åˆã«è¨€åŠã•ã‚ŒãŸèª²é¡Œ"
msgid "CycleAnalyticsEvent|Issue label was added"
msgstr "追加ã•ã‚ŒãŸèª²é¡Œãƒ©ãƒ™ãƒ«"
@@ -6436,16 +6739,16 @@ msgid "CycleAnalyticsEvent|Merge request label was removed"
msgstr ""
msgid "CycleAnalyticsEvent|Merge request last build finish time"
-msgstr ""
+msgstr "マージリクエストã®æœ€å¾Œã®ãƒ“ルド完了時刻"
msgid "CycleAnalyticsEvent|Merge request last build start time"
msgstr "最後ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã®ãƒ“ルド開始時刻"
msgid "CycleAnalyticsEvent|Merge request last edited"
-msgstr ""
+msgstr "マージリクエストã®æœ€çµ‚編集"
msgid "CycleAnalyticsEvent|Merge request merged"
-msgstr ""
+msgstr "マージ済ã¿ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆ"
msgid "CycleAnalyticsStage|Code"
msgstr "コード"
@@ -6466,86 +6769,86 @@ msgid "CycleAnalyticsStage|Test"
msgstr "テスト"
msgid "CycleAnalyticsStage|Total"
-msgstr ""
+msgstr "åˆè¨ˆ"
msgid "CycleAnalyticsStage|is not available for the selected group"
-msgstr ""
+msgstr "ã¯é¸æŠžã•ã‚ŒãŸã‚°ãƒ«ãƒ¼ãƒ—ã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“"
msgid "CycleAnalyticsStage|should be under a group"
-msgstr ""
+msgstr "グループã®ä¸‹ã«ã‚ã‚‹ã¹ãã§ã™"
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
+msgstr "%{stageCount} ステージãŒé¸æŠžã•ã‚Œã¾ã—ãŸ"
msgid "CycleAnalytics|All stages"
-msgstr ""
+msgstr "全ステージ"
msgid "CycleAnalytics|Date"
-msgstr ""
+msgstr "日付"
msgid "CycleAnalytics|Days to completion"
-msgstr ""
+msgstr "完了ã¾ã§ã®æ—¥æ•°"
msgid "CycleAnalytics|Display chart filters"
-msgstr ""
+msgstr "ãƒãƒ£ãƒ¼ãƒˆãƒ•ã‚£ãƒ«ã‚¿ãƒ¼ã®è¡¨ç¤º"
msgid "CycleAnalytics|No stages selected"
-msgstr ""
+msgstr "ステージã¯é¸æŠžã•ã‚Œã¦ã„ã¾ã›ã‚“"
msgid "CycleAnalytics|Number of tasks"
-msgstr ""
+msgstr "タスク数"
msgid "CycleAnalytics|Only %{maxLabels} labels can be selected at this time"
msgstr ""
msgid "CycleAnalytics|Project selected"
msgid_plural "CycleAnalytics|%d projects selected"
-msgstr[0] ""
+msgstr[0] "%d個ã®ãƒ—ロジェクトãŒé¸æŠžã•ã‚Œã¾ã—ãŸ"
msgid "CycleAnalytics|Select labels"
-msgstr ""
+msgstr "ラベルをé¸æŠž"
msgid "CycleAnalytics|Show"
-msgstr ""
+msgstr "表示"
msgid "CycleAnalytics|Showing %{subjectFilterText} and %{selectedLabelsCount} labels"
-msgstr ""
+msgstr "%{subjectFilterText} 㨠%{selectedLabelsCount} ラベルを表示"
msgid "CycleAnalytics|Showing data for group '%{groupName}' and %{selectedProjectCount} projects from %{startDate} to %{endDate}"
-msgstr ""
+msgstr "'%{groupName}' グループ㨠%{selectedProjectCount} プロジェクト㮠%{startDate} ã‹ã‚‰ %{endDate} ã¾ã§ã®ãƒ‡ãƒ¼ã‚¿ã‚’表示"
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{startDate} to %{endDate}"
-msgstr ""
+msgstr "'%{groupName}' グループ㮠%{startDate} ã‹ã‚‰%{endDate} ã¾ã§ã®ãƒ‡ãƒ¼ã‚¿ã‚’表示"
msgid "CycleAnalytics|Stages"
-msgstr ""
+msgstr "ステージ"
msgid "CycleAnalytics|Tasks by type"
-msgstr ""
+msgstr "タイプ別ã®ã‚¿ã‚¹ã‚¯"
msgid "CycleAnalytics|The given date range is larger than 180 days"
-msgstr ""
+msgstr "指定ã•ã‚ŒãŸæ—¥ä»˜ã®ç¯„囲ãŒ180日を超ãˆã¦ã„ã¾ã™ã€‚"
msgid "CycleAnalytics|Total days to completion"
-msgstr ""
+msgstr "完了ã¾ã§ã®æ—¥æ•°åˆè¨ˆ"
msgid "CycleAnalytics|Type of work"
msgstr ""
msgid "CycleAnalytics|group dropdown filter"
-msgstr ""
+msgstr "グループドロップダウンフィルター"
msgid "CycleAnalytics|not allowed for the given start event"
-msgstr ""
+msgstr "指定ã•ã‚ŒãŸé–‹å§‹ã‚¤ãƒ™ãƒ³ãƒˆã«ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
msgid "CycleAnalytics|project dropdown filter"
-msgstr ""
+msgstr "プロジェクトドロップダウンフィルター"
msgid "CycleAnalytics|stage dropdown"
-msgstr ""
+msgstr "ステージドロップダウン"
msgid "DAG"
msgstr ""
@@ -6572,22 +6875,22 @@ msgid "Dashboard|%{firstProject} and %{secondProject}"
msgstr "%{firstProject} 㨠%{secondProject}"
msgid "Dashboard|%{firstProject}, %{rest}, and %{secondProject}"
-msgstr ""
+msgstr "%{firstProject}, %{rest}, 㨠%{secondProject}"
msgid "Dashboard|Unable to add %{invalidProjects}. This dashboard is available for public projects, and private projects in groups with a Silver plan."
-msgstr ""
+msgstr "%{invalidProjects} を追加ã§ãã¾ã›ã‚“。ダッシュボードãŒåˆ©ç”¨ã§ãã‚‹ã®ã¯ã€å…¬é–‹ãƒ—ロジェクトã¨ã€æœ‰æ–™ã‚³ãƒ¼ã‚¹ã® Silverプランã®ãƒ—ライベートプロジェクトã ã‘ã§ã™ã€‚"
msgid "Data is still calculating..."
msgstr "データã¯ã¾ã è¨ˆç®—中ã§ã™..."
msgid "Date"
-msgstr ""
+msgstr "日付"
msgid "Date picker"
msgstr "日付é¸æŠž"
msgid "Date range cannot exceed %{maxDateRange} days."
-msgstr ""
+msgstr "日付範囲㯠%{maxDateRange} 日を超ãˆã‚‰ã‚Œã¾ã›ã‚“。"
msgid "Day of month"
msgstr ""
@@ -6605,10 +6908,10 @@ msgid "DayTitle|W"
msgstr "æ°´"
msgid "Days"
-msgstr ""
+msgstr "æ—¥"
msgid "Days to merge"
-msgstr ""
+msgstr "マージã¾ã§ã®æ—¥æ•°"
msgid "Debug"
msgstr "デãƒãƒƒã‚°"
@@ -6629,7 +6932,7 @@ msgid "Default Branch"
msgstr "デフォルトブランãƒ"
msgid "Default CI configuration path"
-msgstr ""
+msgstr "デフォルトã®CI設定パス"
msgid "Default artifacts expiration"
msgstr "デフォルトã®ã‚¢ãƒ¼ãƒ†ã‚£ãƒ•ã‚¡ã‚¯ãƒˆã®æœ‰åŠ¹æœŸé™"
@@ -6638,19 +6941,22 @@ msgid "Default branch"
msgstr "デフォルトブランãƒ"
msgid "Default branch and protected branches"
-msgstr ""
+msgstr "デフォルトブランãƒã¨ä¿è­·ã•ã‚ŒãŸãƒ–ランãƒ"
msgid "Default classification label"
msgstr "デフォルト分類ラベル"
-msgid "Default deletion adjourned period"
+msgid "Default dashboard"
msgstr ""
+msgid "Default deletion adjourned period"
+msgstr "デフォルトã®å‰Šé™¤çŒ¶äºˆæœŸé–“"
+
msgid "Default description template for issues"
msgstr "課題ã®ã€ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®èª¬æ˜Žãƒ†ãƒ³ãƒ—レート"
msgid "Default description template for merge requests"
-msgstr ""
+msgstr "マージリクエストã®ã€ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®èª¬æ˜Žãƒ†ãƒ³ãƒ—レート"
msgid "Default first day of the week"
msgstr "週ã®å§‹ã¾ã‚Šã®æ›œæ—¥ (デフォルト)"
@@ -6662,7 +6968,7 @@ msgid "Default issue template"
msgstr "デフォルトã®èª²é¡Œãƒ†ãƒ³ãƒ—レート"
msgid "Default project deletion protection"
-msgstr ""
+msgstr "プロジェクトã®å‰Šé™¤ä¿è­·è¨­å®šï¼ˆãƒ‡ãƒ•ã‚©ãƒ«ãƒˆï¼‰"
msgid "Default projects limit"
msgstr ""
@@ -6679,6 +6985,9 @@ msgstr "デフォルト:FogBugz ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆIDをフルãƒãƒ¼ãƒ ã«ãƒžãƒ
msgid "Define a custom pattern with cron syntax"
msgstr "Cron 構文ã§ã‚«ã‚¹ã‚¿ãƒ ãªãƒ‘ターンを指定ã™ã‚‹"
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr "デプロイステージã®ç’°å¢ƒã‚’ <code>.gitlab-ci.yml</code> ã§å®šç¾©ã—ã¦ã€ãƒ‡ãƒ—ロイを追跡ã—ã¾ã™ã€‚"
@@ -6701,7 +7010,7 @@ msgid "Delete"
msgstr "削除"
msgid "Delete Comment"
-msgstr ""
+msgstr "コメントを削除"
msgid "Delete Package"
msgstr "パッケージを削除"
@@ -6710,10 +7019,10 @@ msgid "Delete Snippet"
msgstr "スニペットを削除"
msgid "Delete artifacts"
-msgstr ""
+msgstr "アーãƒãƒ•ã‚¡ã‚¯ãƒˆã‚’削除"
msgid "Delete board"
-msgstr ""
+msgstr "ボードã®å‰Šé™¤"
msgid "Delete comment"
msgstr "コメントを削除"
@@ -6721,6 +7030,12 @@ msgstr "コメントを削除"
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr "ライセンスを削除"
@@ -6728,19 +7043,19 @@ msgid "Delete list"
msgstr "リストを削除ã™ã‚‹"
msgid "Delete pipeline"
-msgstr ""
+msgstr "パイプラインã®å‰Šé™¤"
msgid "Delete project"
-msgstr ""
+msgstr "プロジェクトã®å‰Šé™¤"
msgid "Delete serverless domain?"
msgstr ""
msgid "Delete snippet"
-msgstr ""
+msgstr "スニペットã®å‰Šé™¤"
msgid "Delete snippet?"
-msgstr ""
+msgstr "スニペットを削除?"
msgid "Delete source branch"
msgstr "ソースブランãƒã‚’削除"
@@ -6776,7 +7091,7 @@ msgid "Deleted chat nickname: %{chat_name}!"
msgstr "ãƒãƒ£ãƒƒãƒˆãƒ‹ãƒƒã‚¯ãƒãƒ¼ãƒ ã‚’削除ã—ã¾ã—ãŸï¼š %{chat_name}ï¼"
msgid "Deleted in this version"
-msgstr ""
+msgstr "ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§å‰Šé™¤ã•ã‚ŒãŸæ©Ÿèƒ½"
msgid "Deleting"
msgstr ""
@@ -6791,7 +7106,7 @@ msgid "Deleting the license failed. You are not permitted to perform this action
msgstr "ライセンスã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸã€‚ã‚ãªãŸã¯ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã®å‰Šé™¤ã‚’許å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“。"
msgid "Deletion pending. This project will be removed on %{date}. Repository and other project resources are read-only."
-msgstr ""
+msgstr "削除ã¯ä¿ç•™ã•ã‚Œã¦ã„ã¾ã™ã€‚ã“ã®ãƒ—ロジェクト㯠%{date} ã«å‰Šé™¤ã•ã‚Œã¾ã™ã€‚リãƒã‚¸ãƒˆãƒªåŠã³ãã®ä»–ã®ãƒ—ロジェクトリソースã¯èª­ã¿å–り専用ã§ã™ã€‚"
msgid "Denied authorization of chat nickname %{user_name}."
msgstr "ãƒãƒ£ãƒƒãƒˆãƒ‹ãƒƒã‚¯ãƒãƒ¼ãƒ  %{user_name} ã®æ‰¿èªã‚’æ‹’å¦ã—ã¾ã—ãŸã€‚"
@@ -6803,25 +7118,21 @@ msgid "Dependencies"
msgstr "ä¾å­˜é–¢ä¿‚"
msgid "Dependencies help page link"
-msgstr ""
+msgstr "ä¾å­˜é–¢ä¿‚ã®ãƒ˜ãƒ«ãƒ—ページリンク"
msgid "Dependencies|%d additional vulnerability not shown"
msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
msgid "Dependencies|%{remainingLicensesCount} more"
-msgstr ""
+msgstr "%{remainingLicensesCount} 件以上"
msgid "Dependencies|All"
-msgstr ""
+msgstr "ã™ã¹ã¦"
msgid "Dependencies|Based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
@@ -6836,10 +7147,10 @@ msgid "Dependencies|Export as JSON"
msgstr "JSONエクスãƒãƒ¼ãƒˆ"
msgid "Dependencies|Job failed to generate the dependency list"
-msgstr ""
+msgstr "ä¾å­˜é–¢ä¿‚リストã®ç”Ÿæˆã«å¤±æ•—ã—ã¾ã—ãŸ"
msgid "Dependencies|License"
-msgstr ""
+msgstr "ライセンス"
msgid "Dependencies|Location"
msgstr "ロケーション"
@@ -6847,26 +7158,17 @@ msgstr "ロケーション"
msgid "Dependencies|Packager"
msgstr "パッケージャー"
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
-msgstr ""
+msgstr "%{codeStartTag}ä¾å­˜é–¢ä¿‚スキャニング%{codeEndTag}ジョブã«å¤±æ•—ã—ä¾å­˜é–¢ä¿‚リストを生æˆã§ãã¾ã›ã‚“。ジョブãŒæ­£ã—ã実行ã•ã‚Œã¦ã„ã‚‹ã‹ç¢ºèªã—ãŸä¸Šã§ãƒ‘イプラインをå†å®Ÿè¡Œã—ã¦ãã ã•ã„。"
msgid "Dependencies|Toggle vulnerability list"
msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
-msgstr ""
-
-msgid "Dependencies|Version"
-msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³"
+msgstr "サãƒãƒ¼ãƒˆã•ã‚Œãªã„ファイルãŒæ¤œå‡ºã•ã‚Œã¾ã—ãŸ"
msgid "Dependencies|Vulnerable components"
-msgstr ""
+msgstr "脆弱ãªã‚³ãƒ³ãƒãƒ¼ãƒãƒ³ãƒˆ"
msgid "Dependency List"
msgstr "ä¾å­˜é–¢ä¿‚リスト"
@@ -6887,7 +7189,7 @@ msgid "Dependency proxy URL"
msgstr "ä¾å­˜é–¢ä¿‚プロキシURL"
msgid "Dependency proxy feature is limited to public groups for now."
-msgstr ""
+msgstr "ä¾å­˜é–¢ä¿‚プロキシ機能ã¯ã€ç¾åœ¨å…¬é–‹ã‚°ãƒ«ãƒ¼ãƒ—ã«åˆ¶é™ã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "DependencyProxy|Toggle Dependency Proxy"
msgstr "ä¾å­˜é–¢ä¿‚プロキシã®åˆ‡ã‚Šæ›¿ãˆ"
@@ -6914,13 +7216,13 @@ msgid "Deploy keys allow read-only or read-write (if enabled) access to your rep
msgstr ""
msgid "Deploy progress not found. To see pods, ensure your environment matches %{linkStart}deploy board criteria%{linkEnd}."
-msgstr ""
+msgstr "デプロイã®é€²è¡ŒçŠ¶æ³ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。 ãƒãƒƒãƒ‰ã‚’表示ã™ã‚‹ã«ã¯ã€ã”使用ã®ç’°å¢ƒãŒ%{linkStart}デプロイボードã®åŸºæº–%{linkEnd}ã¨ä¸€è‡´ã—ã¦ã„ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。"
msgid "Deploy to..."
msgstr ""
msgid "DeployBoard|Matching on the %{appLabel} label has been removed for deploy boards. To see all instances on your board, you must update your chart and redeploy."
-msgstr ""
+msgstr "%{appLabel} ラベルã¯ãƒ‡ãƒ—ロイボードã‹ã‚‰å‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚ボード上ã®ã™ã¹ã¦ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã‚’見るãŸã‚ã«ã¯ã€ãƒãƒ£ãƒ¼ãƒˆã‚’æ›´æ–°ã—ã¦å†è¡¨ç¤ºã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "DeployKeys|+%{count} others"
msgstr "+ %{count} プロジェクト"
@@ -6976,20 +7278,26 @@ msgstr "アクティブãªãƒ‡ãƒ—ロイトークン (%{active_tokens})"
msgid "DeployTokens|Add a deploy token"
msgstr "デプロイトークンを追加"
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr "レジストリイメージã¸ã®èª­ã¿å–り専用アクセスを許å¯ã™ã‚‹"
msgid "DeployTokens|Allows read-only access to the repository"
msgstr "リãƒã‚¸ãƒˆãƒªã¸ã®èª­ã¿å–り専用アクセスを許å¯ã™ã‚‹"
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
msgid "DeployTokens|Copy deploy token"
-msgstr ""
+msgstr "デプロイトークンをコピー"
msgid "DeployTokens|Copy username"
-msgstr ""
+msgstr "ユーザーåをコピー"
msgid "DeployTokens|Create deploy token"
msgstr "デプロイトークンを作æˆ"
@@ -6998,18 +7306,18 @@ msgid "DeployTokens|Created"
msgstr "作æˆæ—¥"
msgid "DeployTokens|Default format is \"gitlab+deploy-token-{n}\". Enter custom username if you want to change it."
-msgstr ""
+msgstr "デフォルトã®ãƒ•ã‚©ãƒ¼ãƒžãƒƒãƒˆã¯ \"gitlab+deploy-token-{n}\" ã§ã™ã€‚変更ã—ãŸã„å ´åˆã€ã‚«ã‚¹ã‚¿ãƒ ãƒ¦ãƒ¼ã‚¶ãƒ¼åを入力ã—ã¾ã™ã€‚"
msgid "DeployTokens|Deploy Tokens"
msgstr "デプロイトークン"
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr "有効期é™"
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7070,25 +7378,25 @@ msgid "Deployment Frequency"
msgstr ""
msgid "Deployment|API"
-msgstr ""
+msgstr "API"
msgid "Deployment|This deployment was created using the API"
-msgstr ""
+msgstr "ã“ã®ãƒ‡ãƒ—ロイã¯APIを使用ã—ã¦ä½œæˆã•ã‚Œã¾ã—ãŸ"
msgid "Deployment|canceled"
-msgstr ""
+msgstr "キャンセルã•ã‚Œã¾ã—ãŸã€‚"
msgid "Deployment|created"
-msgstr ""
+msgstr "作æˆæ¸ˆã¿"
msgid "Deployment|failed"
-msgstr ""
+msgstr "失敗ã—ã¾ã—ãŸ"
msgid "Deployment|running"
-msgstr ""
+msgstr "実行中"
msgid "Deployment|success"
-msgstr ""
+msgstr "æˆåŠŸ"
msgid "Deprioritize label"
msgstr "éžå„ªå…ˆãƒ©ãƒ™ãƒ«"
@@ -7097,7 +7405,7 @@ msgid "Descending"
msgstr "é™é †"
msgid "Describe the goal of the changes and what reviewers should be aware of."
-msgstr ""
+msgstr "変更ã®ç›®çš„ã¨ãƒ¬ãƒ“ュアーãŒçŸ¥ã£ã¦ãŠãã¹ãã“ã¨ã‚’説明ã—ã¦ä¸‹ã•ã„。"
msgid "Describe the requirement here"
msgstr ""
@@ -7106,7 +7414,7 @@ msgid "Description"
msgstr "説明"
msgid "Description parsed with %{link_start}GitLab Flavored Markdown%{link_end}"
-msgstr ""
+msgstr "%{link_start} GitLab風ã®ãƒžãƒ¼ã‚¯ãƒ€ã‚¦ãƒ³ %{link_end} ã§ãƒ‘ースã—ãŸèª¬æ˜Ž"
msgid "Description templates allow you to define context-specific templates for issue and merge request description fields for your project."
msgstr "Description テンプレートを使用ã™ã‚‹ã¨ã€ãƒ—ロジェクトã®èª²é¡ŒãŠã‚ˆã³ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆèª¬æ˜Žã«å¯¾ã™ã‚‹ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆå›ºæœ‰ã®ãƒ†ãƒ³ãƒ—レートを定義ã§ãã¾ã™ã€‚"
@@ -7115,13 +7423,13 @@ msgid "Description:"
msgstr "説明:"
msgid "Descriptive label"
-msgstr ""
+msgstr "説明ラベル"
msgid "Deselect all"
msgstr "é¸æŠžã‚’ã™ã¹ã¦è§£é™¤"
msgid "Design Management files and data"
-msgstr ""
+msgstr "デザインマãƒã‚¸ãƒ¡ãƒ³ãƒˆãƒ•ã‚¡ã‚¤ãƒ«ã¨ãƒ‡ãƒ¼ã‚¿"
msgid "DesignManagement|%{current_design} of %{designs_count}"
msgstr "%{designs_count} / %{current_design}"
@@ -7129,47 +7437,65 @@ msgstr "%{designs_count} / %{current_design}"
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
-msgstr ""
-
msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgstr "åŒã˜ãƒ•ã‚¡ã‚¤ãƒ«åã§è¨­è¨ˆã™ã‚‹ã¨ã€æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ãƒ•ã‚¡ã‚¤ãƒ«ã«ç½®ãæ›ãˆã‚‰ã‚Œã¾ã™ã€‚"
+
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
-msgstr ""
+msgstr "本当ã«ã“ã®ã‚³ãƒ¡ãƒ³ãƒˆã®ä½œæˆã‚’キャンセルã—ã¾ã™ã‹ï¼Ÿ"
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
+msgstr "é¸æŠžã—ãŸãƒ‡ã‚¶ã‚¤ãƒ³ã‚’削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
+
+msgid "DesignManagement|Cancel changes"
msgstr ""
msgid "DesignManagement|Cancel comment confirmation"
+msgstr "コメントã®èªè¨¼ã‚’削除"
+
+msgid "DesignManagement|Cancel comment update confirmation"
msgstr ""
-msgid "DesignManagement|Could not add a new comment. Please try again."
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
msgstr ""
-msgid "DesignManagement|Could not create new discussion. Please try again."
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
msgstr ""
+msgid "DesignManagement|Could not add a new comment. Please try again."
+msgstr "æ–°ã—ã„コメントを追加ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
+
+msgid "DesignManagement|Could not create new discussion. Please try again."
+msgstr "æ–°ã—ã„ディスカッションを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
+
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
-msgid "DesignManagement|Delete"
+msgid "DesignManagement|Could not update note. Please try again."
msgstr ""
+msgid "DesignManagement|Delete"
+msgstr "削除"
+
msgid "DesignManagement|Delete designs confirmation"
-msgstr ""
+msgstr "デザインã®èªè¨¼ã‚’削除"
msgid "DesignManagement|Delete selected"
-msgstr ""
+msgstr "é¸æŠžå¯¾è±¡ã‚’削除"
msgid "DesignManagement|Deselect all"
-msgstr ""
+msgstr "å…¨ã¦é¸æŠžã‚’解除"
msgid "DesignManagement|Discard comment"
-msgstr ""
+msgstr "コメントã®ç ´æ£„"
msgid "DesignManagement|Error uploading a new design. Please try again."
-msgstr ""
+msgstr "æ–°ã—ã„デザインã®ã‚¢ãƒƒãƒ—ロード中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„."
msgid "DesignManagement|Go back to designs"
msgstr "å…ƒã®ãƒ‡ã‚¶ã‚¤ãƒ³ã¸"
@@ -7180,21 +7506,42 @@ msgstr "次ã®ãƒ‡ã‚¶ã‚¤ãƒ³ã¸"
msgid "DesignManagement|Go to previous design"
msgstr "å‰ã®ãƒ‡ã‚¶ã‚¤ãƒ³ã¸"
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
+msgstr "コメントã®ç¶­æŒ"
+
+msgid "DesignManagement|Learn more about resolving comments"
msgstr ""
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
+msgstr "è¦æ±‚ã•ã‚ŒãŸãƒ‡ã‚¶ã‚¤ãƒ³ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯å­˜åœ¨ã—ã¾ã›ã‚“。代ã‚ã‚Šã«æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’表示ã—ã¦ã„ã¾ã™"
+
+msgid "DesignManagement|Resolve thread"
msgstr ""
-msgid "DesignManagement|Select all"
+msgid "DesignManagement|Resolved Comments"
msgstr ""
-msgid "DesignManagement|The maximum number of designs allowed to be uploaded is %{upload_limit}. Please try again."
+msgid "DesignManagement|Save comment"
msgstr ""
+msgid "DesignManagement|Select all"
+msgstr "å…¨é¸æŠž"
+
+msgid "DesignManagement|The maximum number of designs allowed to be uploaded is %{upload_limit}. Please try again."
+msgstr "デザインã¯æœ€å¤§ã§ %{upload_limit} ã¾ã§ã‚¢ãƒƒãƒ—ロードã§ãã¾ã™ã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
+
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7207,6 +7554,9 @@ msgstr "デザイン"
msgid "Destroy"
msgstr "破棄"
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr "詳細"
@@ -7217,7 +7567,7 @@ msgid "Detect host keys"
msgstr "ホストキーã®æ¤œå‡º"
msgid "DevOps Score"
-msgstr ""
+msgstr "DevOps スコア"
msgid "Diff content limits"
msgstr "差分コンテンツã®åˆ¶é™"
@@ -7226,19 +7576,19 @@ msgid "Diff limits"
msgstr "Diff ã®åˆ¶é™"
msgid "Difference between start date and now"
-msgstr ""
+msgstr "開始日ã¨ç¾åœ¨ã®é•ã„"
msgid "DiffsCompareBaseBranch|(HEAD)"
-msgstr ""
+msgstr "(HEAD)"
msgid "DiffsCompareBaseBranch|(base)"
-msgstr ""
+msgstr "(ベース)"
msgid "Diffs|No file name available"
msgstr "使用å¯èƒ½ãªãƒ•ã‚¡ã‚¤ãƒ«åãŒã‚ã‚Šã¾ã›ã‚“"
msgid "Diffs|Show unchanged lines"
-msgstr ""
+msgstr "変更ã•ã‚Œã¦ã„ãªã„行を表示"
msgid "Diffs|Something went wrong while fetching diff lines."
msgstr "diff 行をå–得中ã«ä½•ã‹å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
@@ -7259,7 +7609,7 @@ msgid "Disable group Runners"
msgstr "グループ Runner を無効ã«ã™ã‚‹"
msgid "Disable public access to Pages sites"
-msgstr ""
+msgstr "Pages サイトã¸ã®å…¬é–‹ã‚¢ã‚¯ã‚»ã‚¹ã‚’無効ã«ã™ã‚‹"
msgid "Disable shared Runners"
msgstr "共有 Runner を無効化"
@@ -7277,7 +7627,7 @@ msgid "Discard all changes"
msgstr "ã™ã¹ã¦ã®å¤‰æ›´ã‚’破棄"
msgid "Discard all changes?"
-msgstr ""
+msgstr "ã™ã¹ã¦ã®å¤‰æ›´ã‚’破棄?"
msgid "Discard changes"
msgstr "変更を破棄ã™ã‚‹"
@@ -7295,7 +7645,7 @@ msgid "DiscordService|Discord Notifications"
msgstr "Discord 通知"
msgid "DiscordService|Receive event notifications in Discord"
-msgstr ""
+msgstr "Discordã§ã‚¤ãƒ™ãƒ³ãƒˆé€šçŸ¥ã‚’å—ã‘ã‚‹"
msgid "Discover GitLab Geo"
msgstr "GitLab Geo ã«ã¤ã„ã¦"
@@ -7334,19 +7684,19 @@ msgid "Discuss a specific suggestion or question that needs to be resolved"
msgstr "解決ãŒå¿…è¦ãªã€å…·ä½“çš„ãªæ案や質å•ã«ã¤ã„ã¦è­°è«–ã™ã‚‹ã€‚"
msgid "Discuss a specific suggestion or question that needs to be resolved."
-msgstr ""
+msgstr "解決ãŒå¿…è¦ãªã€å…·ä½“çš„ãªæ案や質å•ã«ã¤ã„ã¦è­°è«–ã™ã‚‹ã€‚"
msgid "Discuss a specific suggestion or question."
-msgstr ""
+msgstr "具体的ãªæ案や質å•ã«ã¤ã„ã¦è­°è«–ã—ã¾ã™ã€‚"
msgid "Discussion"
msgstr "検討"
msgid "Discussion to reply to cannot be found"
-msgstr ""
+msgstr "返信先ã®ãƒ‡ã‚£ã‚¹ã‚«ãƒƒã‚·ãƒ§ãƒ³ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
msgid "Disk Usage"
-msgstr ""
+msgstr "ディスク使用é‡"
msgid "Dismiss"
msgstr "解除"
@@ -7356,7 +7706,7 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgid "Dismiss DevOps Score introduction"
-msgstr ""
+msgstr "DevOpsスコアã®ç´¹ä»‹ã‚’é–‰ã˜ã‚‹"
msgid "Dismiss Merge Request promotion"
msgstr "マージリクエストã®æ˜‡æ ¼ã‚’å´ä¸‹ã—ã¾ã™"
@@ -7365,7 +7715,7 @@ msgid "Dismiss Selected"
msgstr ""
msgid "Dismiss Value Stream Analytics introduction box"
-msgstr ""
+msgstr "ãƒãƒªãƒ¥ãƒ¼ã‚¹ãƒˆãƒªãƒ¼ãƒ åˆ†æžã®ç´¹ä»‹ã‚’é–‰ã˜ã‚‹"
msgid "Dismiss trial promotion"
msgstr "トライアルプロモーションを閉ã˜ã‚‹"
@@ -7374,10 +7724,10 @@ msgid "Dismissable"
msgstr ""
msgid "Dismissed"
-msgstr ""
+msgstr "ã‚„ã‚ã‚‹"
msgid "Dismissed at %{projectLink}"
-msgstr ""
+msgstr "%{projectLink} ã§ç„¡è¦–ã—ã¾ã—ãŸ"
msgid "Dismissed on pipeline %{pipelineLink}"
msgstr ""
@@ -7395,7 +7745,7 @@ msgid "Display source"
msgstr ""
msgid "Do not display offers from third parties within GitLab"
-msgstr ""
+msgstr "GitLab 内ã®ã‚µãƒ¼ãƒ‰ãƒ‘ーティã‹ã‚‰ã®ã‚ªãƒ•ã‚¡ãƒ¼ã‚’表示ã—ãªã„"
msgid "Do you want to customize how Google Code email addresses and usernames are imported into GitLab?"
msgstr "Google コードã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã¨ãƒ¦ãƒ¼ã‚¶ãƒ¼åã‚’ GitLab ã«ã‚¤ãƒ³ãƒãƒ¼ãƒˆã™ã‚‹æ–¹æ³•ã‚’カスタマイズã—ã¾ã™ã‹ï¼Ÿ"
@@ -7404,7 +7754,7 @@ msgid "Dockerfile"
msgstr "Dockerfile"
msgid "Documentation"
-msgstr ""
+msgstr "文書"
msgid "Documentation for popular identity providers"
msgstr "一般的㪠ID プロãƒã‚¤ãƒ€ã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆ"
@@ -7419,7 +7769,7 @@ msgid "Domain cannot be deleted while associated to one or more clusters."
msgstr ""
msgid "Domain verification is an essential security measure for public GitLab sites. Users are required to demonstrate they control a domain before it is enabled"
-msgstr ""
+msgstr "ドメイン検証ã¯ã€å…¬é–‹ã—ã¦ã„ã‚‹ GitLab サイトã«ã¨ã£ã¦ä¸å¯æ¬ ãªã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£å¯¾ç­–ã§ã™ã€‚ユーザーã¯ã€ãƒ‰ãƒ¡ã‚¤ãƒ³ãŒæœ‰åŠ¹ã«ãªã‚‹å‰ã«ãƒ‰ãƒ¡ã‚¤ãƒ³ã‚’制御ã—ã¦ã„ã‚‹ã“ã¨ã‚’示ã™å¿…è¦ãŒã‚ã‚Šã¾ã™"
msgid "Domain was successfully created."
msgstr ""
@@ -7431,16 +7781,19 @@ msgid "Domain was successfully updated."
msgstr ""
msgid "Don't have an account yet?"
+msgstr "ã¾ã ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’ãŠæŒã¡ã§ãªã„ã§ã™ã‹ï¼Ÿ"
+
+msgid "Don't include description in commit message"
msgstr ""
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
-msgstr ""
+msgstr "-----BEGIN PGP PUBLIC KEY BLOCK----- ã§å§‹ã¾ã‚‹å…¬é–‹éƒ¨åˆ†ã‚’貼り付ã‘ã¦ãã ã•ã„。 GPG キーã®ç§˜å¯†éƒ¨åˆ†ã‚’貼り付ã‘ãªã„ã§ä¸‹ã•ã„。"
msgid "Don't show again"
msgstr "次回ã‹ã‚‰è¡¨ç¤ºã—ãªã„"
msgid "Don't worry, you can access this tour by clicking on the help icon in the top right corner and choose <strong>Learn GitLab</strong>."
-msgstr ""
+msgstr "心é…ã—ãªã„ã§ãã ã•ã„。å³ä¸Šã«ã‚るヘルプアイコンをクリックã—ã¦ã€ã“ã®ãƒ„アーã«ã‚¢ã‚¯ã‚»ã‚¹ã—〠<strong> GitLabを学㶠</strong>ã‚’é¸æŠžã—ã¦ãã ã•ã„。"
msgid "Done"
msgstr "完了"
@@ -7449,19 +7802,19 @@ msgid "Download"
msgstr "ダウンロード"
msgid "Download %{format}"
-msgstr ""
+msgstr "%{format} をダウンロード"
msgid "Download %{format}:"
-msgstr ""
+msgstr "%{format} をダウンロード:"
msgid "Download CSV"
-msgstr ""
+msgstr "CSV をダウンロード"
msgid "Download artifacts"
msgstr "æˆæžœç‰©ã®ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰"
msgid "Download as"
-msgstr ""
+msgstr "別åã§ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰"
msgid "Download asset"
msgstr "アセットをダウンロード"
@@ -7470,17 +7823,20 @@ msgid "Download codes"
msgstr "コードをダウンロード"
msgid "Download evidence JSON"
-msgstr ""
+msgstr "証拠JSONã®ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰"
msgid "Download export"
msgstr "エクスãƒãƒ¼ãƒˆã‚’ダウンロード"
msgid "Download image"
-msgstr ""
+msgstr "イメージをダウンロード"
msgid "Download license"
msgstr "ライセンスをダウンロード"
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr "ソースコードをダウンロード"
@@ -7505,20 +7861,23 @@ msgstr "イマイãƒ"
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr "期é™"
msgid "Duration"
-msgstr ""
+msgstr "期間"
msgid "Duration for the last 30 commits"
-msgstr ""
+msgstr "最新30コミットã®æœŸé–“"
msgid "During this process, you’ll be asked for URLs from GitLab’s side. Use the URLs shown below."
msgstr "ã“ã®ãƒ—ロセスã®é€”中ã§ã€GitLab å´ã‹ã‚‰ã® URL ã‚’èžã‹ã‚Œã‚‹ã®ã§ã€æ¬¡ã® URL を使用ã—ã¦ãã ã•ã„。"
msgid "Dynamic Application Security Testing (DAST)"
-msgstr ""
+msgstr "動的アプリケーションセキュリティテスト (DAST)"
msgid "Each Runner can be in one of the following states and/or belong to one of the following types:"
msgstr ""
@@ -7530,22 +7889,22 @@ msgid "Edit"
msgstr "編集"
msgid "Edit %{issuable}"
-msgstr ""
+msgstr "%{issuable} を編集"
msgid "Edit %{name}"
msgstr "%{name} を編集"
msgid "Edit Comment"
-msgstr ""
+msgstr "コメントを編集"
msgid "Edit Deploy Key"
msgstr "デプロイキーã®ç·¨é›†"
msgid "Edit Geo Node"
-msgstr ""
+msgstr "ジオノードを編集"
msgid "Edit Group Hook"
-msgstr ""
+msgstr "グループフックを編集"
msgid "Edit Label"
msgstr "ラベルã®ç·¨é›†"
@@ -7560,28 +7919,28 @@ msgid "Edit Pipeline Schedule %{id}"
msgstr "パイプラインスケジュール %{id} を編集"
msgid "Edit Release"
-msgstr ""
+msgstr "リリースを編集"
msgid "Edit Snippet"
msgstr "スニペットを編集"
msgid "Edit System Hook"
-msgstr ""
+msgstr "システムフックを編集"
msgid "Edit application"
msgstr "アプリケーションã®ç·¨é›†"
msgid "Edit board"
-msgstr ""
+msgstr "ボードを編集"
msgid "Edit comment"
msgstr "コメントを編集"
msgid "Edit dashboard"
-msgstr ""
+msgstr "ダッシュボードを編集"
msgid "Edit description"
-msgstr ""
+msgstr "説明を編集"
msgid "Edit environment"
msgstr "環境を編集"
@@ -7605,13 +7964,13 @@ msgid "Edit public deploy key"
msgstr "公開デプロイキーã®ç·¨é›†"
msgid "Edit stage"
-msgstr ""
+msgstr "ステージã®ç·¨é›†"
msgid "Edit this release"
-msgstr ""
+msgstr "ã“ã®ãƒªãƒªãƒ¼ã‚¹ã‚’編集ã—ã¾ã™ã€‚"
msgid "Edit wiki page"
-msgstr ""
+msgstr "Wikiページã®ç·¨é›†"
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr "スレッド内ã®æœ€æ–°ã®ã‚ãªãŸã®ã‚³ãƒ¡ãƒ³ãƒˆã‚’編集 (空ã®ãƒ†ã‚­ã‚¹ãƒˆé ˜åŸŸã‹ã‚‰)"
@@ -7652,6 +8011,9 @@ msgstr "メール"
msgid "Email address"
msgstr "メールアドレス"
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7667,6 +8029,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr "パイプラインã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’å—信者ã®ãƒªã‚¹ãƒˆã«Eメールã§é€šçŸ¥ã—ã¾ã™ã€‚"
@@ -7716,7 +8081,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 "ãã‚Œãžã‚Œã®ãƒ—ッシュã®ã‚³ãƒŸãƒƒãƒˆã¨å·®åˆ†ã‚’å—信者ã®ãƒªã‚¹ãƒˆã«ãƒ¡ãƒ¼ãƒ«ã§é€ä¿¡ã—ã¾ã™ã€‚"
msgid "EmailsOnPushService|Emails on push"
msgstr "プッシュ時ã®Eメール"
@@ -7746,7 +8111,7 @@ msgid "Enable HTML emails"
msgstr "HTML メールã®æœ‰åŠ¹åŒ–"
msgid "Enable Incident Management inbound alert limit"
-msgstr ""
+msgstr "インシデント管ç†ã‚¤ãƒ³ãƒã‚¦ãƒ³ãƒ‰ã‚¢ãƒ©ãƒ¼ãƒˆåˆ¶é™ã‚’有効ã«ã™ã‚‹"
msgid "Enable PlantUML"
msgstr "PlantUML を有効化"
@@ -7760,6 +8125,9 @@ msgstr "ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã® SAML èªè¨¼ã‚’有効ã«ã™ã‚‹"
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7769,9 +8137,6 @@ msgstr "指定グループã®ãƒ‘フォーマンスãƒãƒ¼ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ã‚’有
msgid "Enable and configure Grafana."
msgstr "Grafana を有効ã«ã—ã¦æ§‹æˆã™ã‚‹ã€‚"
-msgid "Enable and configure InfluxDB metrics."
-msgstr "InfluxDB ã®ãƒ¡ãƒˆãƒªã‚¯ã‚¹ã‚’有効ã«ã—ã¦è¨­å®šã™ã‚‹ã€‚"
-
msgid "Enable and configure Prometheus metrics."
msgstr "Prometheus ã®ãƒ¡ãƒˆãƒªã‚¯ã‚¹ã‚’有効ã«ã—ã¦è¨­å®šã™ã‚‹ã€‚"
@@ -7788,7 +8153,7 @@ msgid "Enable error tracking"
msgstr "エラートラッキングを有効ã«ã™ã‚‹"
msgid "Enable feature to choose access level"
-msgstr ""
+msgstr "アクセスレベルをé¸æŠžã™ã‚‹æ©Ÿèƒ½ã‚’有効ã«ã™ã‚‹"
msgid "Enable for this project"
msgstr "ã“ã®ãƒ—ロジェクトã§ã¯æœ‰åŠ¹ã«ã™ã‚‹"
@@ -7799,6 +8164,9 @@ msgstr "グループ Runner を有効ã«ã™ã‚‹"
msgid "Enable header and footer in emails"
msgstr "メールã®ãƒ˜ãƒƒãƒ€ãƒ¼ã¨ãƒ•ãƒƒã‚¿ãƒ¼ã‚’有効ã«ã™ã‚‹"
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -7818,19 +8186,19 @@ msgid "Enable or disable version check and usage ping."
msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãƒã‚§ãƒƒã‚¯ã¨ä½¿ç”¨çŠ¶æ³ã® ping を有効ã«ã™ã‚‹ã€‚"
msgid "Enable protected paths rate limit"
-msgstr ""
+msgstr "ä¿è­·ã•ã‚ŒãŸãƒ‘スã®ãƒ¬ãƒ¼ãƒˆåˆ¶é™ã‚’有効ã«ã™ã‚‹"
msgid "Enable proxy"
msgstr "プロキシを有効ã«ã™ã‚‹"
msgid "Enable reCAPTCHA or Akismet and set IP limits. For reCAPTCHA, we currently only support %{recaptcha_v2_link_start}v2%{recaptcha_v2_link_end}"
-msgstr ""
+msgstr "reCAPTCHA ã¾ãŸã¯ Akismet を有効ã«ã—ã¦ã€IP制é™ã‚’設定ã—ã¾ã™ã€‚ reCAPTCHA ã«ã¤ã„ã¦ã¯ã€ç¾åœ¨ %{recaptcha_v2_link_start} v2 %{recaptcha_v2_link_end} ã®ã¿ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã™ã€‚"
msgid "Enable shared Runners"
msgstr "共有 Runner を有効化"
msgid "Enable snowplow tracking"
-msgstr ""
+msgstr "スノープロウトラッキングを有効ã«ã™ã‚‹"
msgid "Enable two-factor authentication"
msgstr "2è¦ç´ èªè¨¼ã‚’有効ã«ã™ã‚‹"
@@ -7863,7 +8231,7 @@ msgid "Enabled"
msgstr "有効"
msgid "Enabled Git access protocols"
-msgstr ""
+msgstr "有効ãªGitアクセスプロトコル"
msgid "Enabled sources for code import during project creation. OmniAuth must be configured for GitHub"
msgstr "プロジェクト作æˆä¸­ã®ã‚³ãƒ¼ãƒ‰ã‚¤ãƒ³ãƒãƒ¼ãƒˆã«æœ‰åŠ¹ãªã‚½ãƒ¼ã‚¹ã€‚ OmniAuth 㯠GitHub 用ã«è¨­å®šã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™"
@@ -7881,25 +8249,25 @@ msgid "Ends at (UTC)"
msgstr "終了時刻 (UTC)"
msgid "Enforce DNS rebinding attack protection"
-msgstr ""
+msgstr "DNSå†ãƒã‚¤ãƒ³ãƒ‰æ”»æ’ƒã«å¯¾ã™ã‚‹ä¿è­·ã‚’強化ã™ã‚‹"
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
-msgstr ""
+msgstr "GitLab サーãƒãƒ¼ã‹ã‚‰ Prometheus サーãƒãƒ¼ã¸ã®æŽ¥ç¶šãŒåˆ©ç”¨ã§ãã‚‹ã“ã¨ã‚’確èªã—ã¾ã™ã€‚"
msgid "Ensure your %{linkStart}environment is part of the deploy stage%{linkEnd} of your CI pipeline to track deployments to your cluster."
-msgstr ""
+msgstr "%{linkStart}環境ãŒCIパイプラインã®ãƒ‡ãƒ—ロイステージã®ä¸€éƒ¨ %{linkEnd}ã§ã‚ã‚‹ã“ã¨ã‚’確èªã—ã¦ã€ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã¸ã®ãƒ‡ãƒ—ロイを追跡ã—ã¾ã™ã€‚"
msgid "Enter 2FA for Admin Mode"
msgstr ""
msgid "Enter Admin Mode"
-msgstr ""
+msgstr "管ç†è€…モードã«ã—ã¾ã™"
msgid "Enter IP address range"
-msgstr ""
+msgstr "IPアドレスã®ç¯„囲を入力"
msgid "Enter a number"
-msgstr ""
+msgstr "数値ã®å…¥åŠ›"
msgid "Enter a whole number between 0 and 100"
msgstr ""
@@ -7908,22 +8276,25 @@ msgid "Enter at least three characters to search"
msgstr "å°‘ãªãã¨ã‚‚3文字以上ã§æ¤œç´¢ã—ã¦ãã ã•ã„"
msgid "Enter board name"
-msgstr ""
+msgstr "ボードåを入力"
msgid "Enter domain"
-msgstr ""
+msgstr "ドメインを入力"
msgid "Enter in your Bitbucket Server URL and personal access token below"
msgstr "ã‚ãªãŸã® Bitbucket Server ã® URL ã¨ä»¥ä¸‹ã®å€‹äººã‚¢ã‚¯ã‚»ã‚¹ãƒˆãƒ¼ã‚¯ãƒ³ã‚’入力ã—ã¦ãã ã•ã„"
msgid "Enter in your Phabricator Server URL and personal access token below"
-msgstr ""
+msgstr "ã‚ãªãŸã® Phabricator サーãƒãƒ¼ã®URLã¨ãƒ‘ーソナルアクセストークンを入力ã—ã¦ãã ã•ã„"
msgid "Enter merge request URLs"
+msgstr "マージリクエストã®URLを入力"
+
+msgid "Enter new %{field_title}"
msgstr ""
msgid "Enter new AWS Secret Access Key"
-msgstr ""
+msgstr "æ–°ã—ã„AWSシークレットアクセスキーを入力ã—ã¾ã™"
msgid "Enter number of issues"
msgstr ""
@@ -7946,11 +8317,11 @@ msgstr "マージリクエストã®èª¬æ˜Žã‚’入力ã—ã¦ãã ã•ã„"
msgid "Enter the merge request title"
msgstr "マージリクエストã®ã‚¿ã‚¤ãƒˆãƒ«ã‚’入力ã—ã¦ãã ã•ã„"
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
-msgstr ""
+msgid "Enter your password to approve"
+msgstr "承èªã™ã‚‹ã«ã¯ãƒ‘スワードを入力ã—ã¦ãã ã•ã„"
msgid "Environment"
msgstr "環境"
@@ -7962,7 +8333,7 @@ msgid "Environment scope"
msgstr ""
msgid "Environment variables are applied to environments via the runner. They can be protected by only exposing them to protected branches or tags. Additionally, they can be masked so they are hidden in job logs, though they must match certain regexp requirements to do so. You can use environment variables for passwords, secret keys, or whatever you want."
-msgstr ""
+msgstr "環境変数㯠Runner を介ã—ã¦ç’°å¢ƒã«é©ç”¨ã•ã‚Œã¾ã™ã€‚ä¿è­·ã•ã‚ŒãŸãƒ–ランãƒã‚„ã‚¿ã‚°ã«ãれらを公開ã™ã‚‹ã ã‘ã§ä¿è­·ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ã•ã‚‰ã«ã€ãƒžã‚¹ã‚¯ã•ã‚Œã¦ã„ã‚‹ãŸã‚ã€ã‚¸ãƒ§ãƒ–ログã«ã¯è¡¨ç¤ºã•ã‚Œã¾ã›ã‚“ãŒã€æ­£è¦è¡¨ç¾ã®è¦ä»¶ã‚’満ãŸã™å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚ã‚ãªãŸã¯ãƒ‘スワードã€ç§˜å¯†éµã€ã¾ãŸã¯ã‚ãªãŸãŒæœ›ã‚€ã‚‚ã®ãªã‚‰ä½•ã§ã‚‚環境変数を使ã†ã“ã¨ãŒã§ãã¾ã™ã€‚"
msgid "Environment variables are configured by your administrator to be %{link_start}protected%{link_end} by default"
msgstr "環境変数ã¯ã€ç®¡ç†è€…ã«ã‚ˆã£ã¦ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆãŒ %{link_start}ä¿è­·%{link_end} ã«è¨­å®šã•ã‚Œã¦ã„ã¾ã™ã€‚"
@@ -7971,13 +8342,13 @@ msgid "Environment:"
msgstr "環境:"
msgid "EnvironmentDashboard|API"
-msgstr ""
+msgstr "API"
msgid "EnvironmentDashboard|Created through the Deployment API"
-msgstr ""
+msgstr "Deployment APIを使用ã—ã¦ä½œæˆ"
msgid "EnvironmentDashboard|You are looking at the last updated environment"
-msgstr ""
+msgstr "æ›´æ–°ã•ã‚ŒãŸæœ€æ–°ã®ç’°å¢ƒã‚’表示ã—ã¦ã„ã¾ã™ã€‚"
msgid "Environments"
msgstr "環境"
@@ -7989,7 +8360,7 @@ msgid "Environments allow you to track deployments of your application %{link_to
msgstr "環境ã¯ã‚¢ãƒ—リケーションã®ãƒ‡ãƒ—ロイを追加ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ %{link_to_read_more}"
msgid "Environments in %{name}"
-msgstr ""
+msgstr "%{name} 環境"
msgid "EnvironmentsDashboard|Add a project to the dashboard"
msgstr "ダッシュボードã«ãƒ—ロジェクトを追加"
@@ -8006,7 +8377,7 @@ msgstr "ジョブ: %{job}"
msgid "EnvironmentsDashboard|More actions"
msgstr "追加ã®ã‚¢ã‚¯ã‚·ãƒ§ãƒ³"
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8016,10 +8387,10 @@ msgid "EnvironmentsDashboard|The environments dashboard provides a summary of ea
msgstr "環境情報ダッシュボードã¯å„プロジェクトã®ç’°å¢ƒæƒ…å ±(パイプラインやアラート状態å«ã‚€) を表示ã—ã¾ã™ã€‚"
msgid "EnvironmentsDashboard|This dashboard displays a maximum of 7 projects and 3 environments per project. %{readMoreLink}"
-msgstr ""
+msgstr "ã“ã®ãƒ€ãƒƒã‚·ãƒ¥ãƒœãƒ¼ãƒ‰ã«ã¯ã€æœ€å¤§ã§7ã¤ã®ãƒ—ロジェクトã¨ã€ãƒ—ロジェクトã”ã¨ã«æœ€å¤§ã§3ã¤ã®ç’°å¢ƒã‚’表示ã§ãã¾ã™ã€‚ 詳細ã«ã¤ã„ã¦ã¯ã“ã¡ã‚‰ã‚’å‚ç…§ã—ã¦ãã ã•ã„。%{readMoreLink}"
msgid "Environments|An error occurred while canceling the auto stop, please try again"
-msgstr ""
+msgstr "Auto stopã®ã‚­ãƒ£ãƒ³ã‚»ãƒ«ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„"
msgid "Environments|An error occurred while deleting the environment. Check if the environment stopped; if not, stop it and try again."
msgstr ""
@@ -8085,13 +8456,13 @@ msgid "Environments|Environments are places where code gets deployed, such as st
msgstr "環境ã¨ã¯ã€staging ã‚„ production ã¨ã„ã£ãŸã‚³ãƒ¼ãƒ‰ã‚’デプロイã™ã‚‹å…ˆã§ã™ã€‚"
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
-msgstr ""
+msgstr "クラスターã«Elastic Stackをインストールã—ã¦ã€å…¨æ–‡æ¤œç´¢ç­‰ã®é«˜åº¦ãªæ‹¡å¼µã‚¯ã‚¨ãƒªæ©Ÿèƒ½ã‚’有効ã«ã—ã¾ã™ã€‚"
msgid "Environments|Job"
msgstr "ジョブ"
msgid "Environments|Learn about environments"
-msgstr ""
+msgstr "環境ã®è©³ç´°ã«ã¤ã„ã¦å­¦ã¶"
msgid "Environments|Learn more about stopping environments"
msgstr "環境ã®åœæ­¢ã«ã¤ã„ã¦"
@@ -8103,7 +8474,7 @@ msgid "Environments|New environment"
msgstr "æ–°ã—ã„環境"
msgid "Environments|No deployed environments"
-msgstr ""
+msgstr "デプロイã•ã‚ŒãŸç’°å¢ƒã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "Environments|No deployments yet"
msgstr "未デプロイ"
@@ -8112,7 +8483,7 @@ msgid "Environments|No pod selected"
msgstr ""
msgid "Environments|No pods to display"
-msgstr ""
+msgstr "表示ã™ã‚‹ãƒãƒƒãƒ‰ã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "Environments|Note that this action will stop the environment, but it will %{emphasisStart}not%{emphasisEnd} have an effect on any existing deployment due to no “stop environment action†being defined in the %{ciConfigLinkStart}.gitlab-ci.yml%{ciConfigLinkEnd} file."
msgstr "ã“ã®ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã¯ç’°å¢ƒã‚’åœæ­¢ã™ã‚‹ã“ã¨ã«æ³¨æ„ã—ã¦ãã ã•ã„。ã—ã‹ã—ã€%{ciConfigLinkStart}.gitlab-ci.yml%{ciConfigLinkEnd} ファイルã§å®šç¾©ã•ã‚Œã¦ã„ã‚‹ã€ç’°å¢ƒåœæ­¢ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ä»¥å¤–ã«ã‚ˆã‚‹ã€ã‚らゆる既存ã®ãƒ‡ãƒ—ロイメントã«å½±éŸ¿ã‚’ %{emphasisStart}与ãˆã¾ã›ã‚“%{emphasisEnd}。"
@@ -8181,7 +8552,7 @@ msgid "Environments|This action will relaunch the job for commit %{linkStart}%{c
msgstr "ã“ã®ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã¯ã‚³ãƒŸãƒƒãƒˆ %{linkStart}%{commitId}%{linkEnd} ã®ã‚¸ãƒ§ãƒ–ã‚’å†èµ·å‹•ã—ã€ç’°å¢ƒã‚’以å‰ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«ã—ã¾ã™ã€‚本当ã«ç¶šã‘ã¾ã™ã‹ï¼Ÿ"
msgid "Environments|This action will run the job defined by %{environment_name} for commit %{commit_id}, 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 "ã“ã®ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã¯ã€ã‚³ãƒŸãƒƒãƒˆ %{commit_id}ã«å¯¾ã—㦠%{environment_name} ã§å®šç¾©ã•ã‚ŒãŸã‚¸ãƒ§ãƒ–を実行ã—ã€ç’°å¢ƒã‚’以å‰ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«ã—ã¾ã™ã€‚アプリケーションã®æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’å†ãƒ‡ãƒ—ロイã™ã‚‹ã“ã¨ã§å…ƒã«æˆ»ã™ã“ã¨ãŒã§ãã¾ã™ã€‚続行ã—ã¾ã™ã‹ï¼Ÿ"
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 "ã“ã®ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã¯ã€ã‚³ãƒŸãƒƒãƒˆ %{linkStart}%{commitId}%{linkEnd} ã«å¯¾ã—㦠%{name} ã§å®šç¾©ã•ã‚ŒãŸã‚¸ãƒ§ãƒ–を実行ã—ã¦ã€ç’°å¢ƒã‚’å‰ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«ã—ã¾ã™ã€‚アプリケーションã®æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’å†ãƒ‡ãƒ—ロイã™ã‚‹ã“ã¨ã§ revert ã§ãã¾ã™ã€‚続ã‘ã¾ã™ã‹ï¼Ÿ"
@@ -8199,10 +8570,10 @@ msgid "Epic"
msgstr "エピック"
msgid "Epic cannot be found."
-msgstr ""
+msgstr "エピックãŒã‚ã‚Šã¾ã›ã‚“。"
msgid "Epic events"
-msgstr ""
+msgstr "エピックイベント"
msgid "Epics"
msgstr "エピック"
@@ -8211,7 +8582,7 @@ msgid "Epics Roadmap"
msgstr "エピック ロードマップ"
msgid "Epics and Issues"
-msgstr ""
+msgstr "エピックã¨èª²é¡Œ"
msgid "Epics let you manage your portfolio of projects more efficiently and with less effort"
msgstr "エピックを使用ã™ã‚‹ã¨ã€ãƒ—ロジェクトã®ãƒãƒ¼ãƒˆãƒ•ã‚©ãƒªã‚ªã‚’より効率的ã‹ã¤å°‘ãªã„労力ã§ç®¡ç†ã§ãã¾ã™"
@@ -8219,10 +8590,10 @@ msgstr "エピックを使用ã™ã‚‹ã¨ã€ãƒ—ロジェクトã®ãƒãƒ¼ãƒˆãƒ•ã‚©ãƒª
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
-msgstr "エピックを追加"
+msgid "Epics|Add a new epic"
+msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8232,13 +8603,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 ""
-
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr "æ–°ã—ã„エピックを作æˆ"
+msgstr "本当㫠%{bStart}%{parentEpicTitle}%{bEnd} ã‹ã‚‰ %{bStart}%{targetIssueTitle}%{bEnd} を削除ã—ã¾ã™ã‹ï¼Ÿ"
msgid "Epics|How can I solve this?"
msgstr "ã©ã†ã™ã‚Œã°è§£æ±ºã§ãã¾ã™ã‹ï¼Ÿ"
@@ -8250,34 +8615,34 @@ msgid "Epics|Remove epic"
msgstr "エピックを削除"
msgid "Epics|Remove issue"
-msgstr ""
+msgstr "課題ã®å‰Šé™¤"
msgid "Epics|Show more"
-msgstr ""
+msgstr "詳細を見る"
msgid "Epics|Something went wrong while assigning issue to epic."
-msgstr ""
+msgstr "課題をエピックã«å‰²ã‚Šå½“ã¦ä¸­ã«ä½•ã‹å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "Epics|Something went wrong while creating child epics."
-msgstr ""
+msgstr "å­ã‚¨ãƒ”ック作æˆä¸­ã«ä½•ã‹å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "Epics|Something went wrong while creating issue."
msgstr ""
msgid "Epics|Something went wrong while fetching child epics."
-msgstr ""
+msgstr "å­ã‚¨ãƒ”ックå–得中ã«ä½•ã‹å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "Epics|Something went wrong while fetching group epics."
-msgstr ""
+msgstr "グループエピックã®å–得中ã«ä½•ã‹å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "Epics|Something went wrong while moving item."
msgstr ""
msgid "Epics|Something went wrong while ordering item."
-msgstr ""
+msgstr "アイテムを並ã¹ã¦ã„ã‚‹é–“ã«ä½•ã‹å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "Epics|Something went wrong while removing issue from epic."
-msgstr ""
+msgstr "エピックã‹ã‚‰èª²é¡Œã‚’削除ã—ã¦ã‚‹é–“ã«ä½•ã‹å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
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 "ã“れらã®æ—¥ä»˜ã¯ã€ã‚ãªãŸã®ã‚¨ãƒ”ックãŒãƒ­ãƒ¼ãƒ‰ãƒžãƒƒãƒ—ã«ã©ã®ã‚ˆã†ã«è¡¨ç¤ºã•ã‚Œã‚‹ã‹ã«å½±éŸ¿ã—ã¾ã™ã€‚マイルストーンã®æ—¥ä»˜ã¯ã€ã‚¨ãƒ”ックã®èª²é¡Œã«å‰²ã‚Šå½“ã¦ã‚‰ã‚ŒãŸãƒžã‚¤ãƒ«ã‚¹ãƒˆãƒ¼ãƒ³ã«ç”±æ¥ã—ã¾ã™ã€‚日付を修正ã™ã‚‹ã“ã¨ã‚‚ã€å®Œå…¨ã«å‰Šé™¤ã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚"
@@ -8298,7 +8663,7 @@ msgid "Error"
msgstr "エラー"
msgid "Error Details"
-msgstr ""
+msgstr "エラーã®è©³ç´°"
msgid "Error Tracking"
msgstr "エラートラッキング"
@@ -8309,18 +8674,27 @@ msgstr "エピックã®ä½œæˆä¸­ã«ã‚¨ãƒ©ãƒ¼"
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr "%{issuableType} ã®å‰Šé™¤ã‚¨ãƒ©ãƒ¼"
+msgid "Error creating new iteration"
+msgstr ""
-msgid "Error deleting project. Check logs for error details."
+msgid "Error creating repository for snippet with id %{snippet_id}"
msgstr ""
-msgid "Error fetching diverging counts for branches. Please try again."
+msgid "Error creating the snippet"
msgstr ""
-msgid "Error fetching forked projects. Please try again."
+msgid "Error deleting %{issuableType}"
msgstr ""
+msgid "Error deleting project. Check logs for error details."
+msgstr "プロジェクトã®å‰Šé™¤ã§ã‚¨ãƒ©ãƒ¼ãŒã‚ã‚Šã¾ã™ã€‚エラーã®è©³ç´°ã«ã¤ã„ã¦ã¯ãƒ­ã‚°ã‚’確èªã—ã¦ãã ã•ã„。"
+
+msgid "Error fetching diverging counts for branches. Please try again."
+msgstr "ブランãƒã®åˆ†å²ã‚«ã‚¦ãƒ³ãƒˆå–å¾—ã«å¤±æ•—ã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
+
+msgid "Error fetching forked projects. Please try again."
+msgstr "フォークã—ãŸãƒ—ロジェクトã®ãƒ•ã‚§ãƒƒãƒã‚¨ãƒ©ãƒ¼ã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
+
msgid "Error fetching labels."
msgstr "ラベルã®å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
@@ -8337,7 +8711,7 @@ msgid "Error fetching refs"
msgstr "å‚ç…§ã®å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿ"
msgid "Error fetching the dependency list. Please check your network connection and try again."
-msgstr ""
+msgstr "ä¾å­˜é–¢ä¿‚リストãŒå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯æŽ¥ç¶šçŠ¶æ³ã‚’確èªã—ã¦å†è©¦è¡Œã—ã¦ãã ã•ã„。"
msgid "Error loading branch data. Please try again."
msgstr "ブランムデータã®èª­ã¿è¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
@@ -8346,10 +8720,10 @@ msgid "Error loading branches."
msgstr "ブランãƒã®ãƒ­ãƒ¼ãƒ‰ã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
msgid "Error loading burndown chart data"
-msgstr ""
+msgstr "ãƒãƒ¼ãƒ³ãƒ€ã‚¦ãƒ³ãƒãƒ£ãƒ¼ãƒˆãƒ‡ãƒ¼ã‚¿ã®èª­ã¿è¾¼ã¿ã‚¨ãƒ©ãƒ¼"
msgid "Error loading countries data."
-msgstr ""
+msgstr "国データã®èª­ã¿è¾¼ã¿ã‚¨ãƒ©ãƒ¼ã€‚"
msgid "Error loading file viewer."
msgstr "ファイルビューワーã®èª­ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
@@ -8382,7 +8756,7 @@ msgid "Error occurred when fetching sidebar data"
msgstr "サイドãƒãƒ¼ãƒ‡ãƒ¼ã‚¿ã®å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "Error occurred when saving assignees"
-msgstr ""
+msgstr "担当者ã®ä¿å­˜ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
msgid "Error occurred when toggling the notification subscription"
msgstr "通知購読ã®åˆ‡ã‚Šæ›¿ãˆã§ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
@@ -8391,13 +8765,13 @@ msgid "Error occurred while updating the issue status"
msgstr ""
msgid "Error occurred while updating the issue weight"
-msgstr ""
+msgstr "課題ã®ã‚¦ã‚¨ã‚¤ãƒˆæ›´æ–°æ™‚ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
msgid "Error occurred. A blocked user cannot be deactivated"
-msgstr ""
+msgstr "エラーãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ブロックã•ã‚ŒãŸãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’無効ã«ã§ãã¾ã›ã‚“。"
msgid "Error occurred. A blocked user must be unblocked to be activated"
-msgstr ""
+msgstr "エラーãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ブロックã•ã‚ŒãŸãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ã€ã‚¢ã‚¯ãƒ†ã‚£ãƒ–化ã™ã‚‹ãŸã‚ã«ãƒ–ロックを解除ã—ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“"
msgid "Error occurred. User was not blocked"
msgstr "エラーãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ユーザーã¯ãƒ–ロックã•ã‚Œã¾ã›ã‚“ã§ã—ãŸ"
@@ -8414,59 +8788,59 @@ msgstr "エラーãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ユーザーã¯ãƒ­ãƒƒã‚¯è§£é™¤ã•ã‚Œã¾
msgid "Error rendering markdown preview"
msgstr "Markdownプレビューã®ãƒ¬ãƒ³ãƒ€ãƒªãƒ³ã‚°ã‚¨ãƒ©ãƒ¼"
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr "ラベルã®æ›´æ–°ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "Error setting up editor. Please try again."
-msgstr ""
+msgstr "エディタã®ã‚»ãƒƒãƒˆã‚¢ãƒƒãƒ—中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
msgid "Error updating %{issuableType}"
msgstr "%{issuableType} ã®æ›´æ–°ä¸­ã‚¨ãƒ©ãƒ¼"
msgid "Error updating status for all to-do items."
-msgstr ""
+msgstr "ã™ã¹ã¦ã®TODOé …ç›®ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹æ›´æ–°ã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
msgid "Error updating status of to-do item."
+msgstr "To-doé …ç›®ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã®æ›´æ–°ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
+
+msgid "Error updating the snippet"
msgstr ""
msgid "Error uploading file"
msgstr "ファイルアップロードエラー"
msgid "Error uploading file: %{stripped}"
-msgstr ""
+msgstr "ファイルã®ã‚¢ãƒƒãƒ—ロードã«å¤±æ•—ã—ã¾ã—ãŸ: %{stripped} "
msgid "Error while loading the merge request. Please try again."
msgstr "マージリクエストã®èª­ã¿è¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
msgid "Error while loading the project data. Please try again."
-msgstr ""
+msgstr "プロジェクトデータã®èª­ã¿è¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚å†è©¦è¡Œã—ã¦ãã ã•ã„。"
msgid "Error while migrating %{upload_id}: %{error_message}"
-msgstr ""
+msgstr "%{upload_id} ã®ç§»è¡Œä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %{error_message}"
msgid "Error with Akismet. Please check the logs for more info."
msgstr "Akismet ã§ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚詳細ã«ã¤ã„ã¦ã¯ãƒ­ã‚°ã‚’確èªã—ã¦ãã ã•ã„。"
msgid "ErrorTracking|Active"
-msgstr ""
+msgstr "アクティブ"
msgid "ErrorTracking|After adding your Auth Token, use the 'Connect' button to load projects"
-msgstr ""
+msgstr "ã‚ãªãŸãŒèªè¨¼ãƒˆãƒ¼ã‚¯ãƒ³ã‚’追加ã—ãŸå¾Œã«ã€æŽ¥ç¶š ボタンを使用ã—ã¦ãƒ—ロジェクトを読ã¿è¾¼ã¿ã¾ã™"
msgid "ErrorTracking|Auth Token"
msgstr "èªè¨¼ãƒˆãƒ¼ã‚¯ãƒ³"
msgid "ErrorTracking|Click 'Connect' to re-establish the connection to Sentry and activate the dropdown."
-msgstr ""
+msgstr "'接続' をクリックã—㦠Sentry ã¸ã®æŽ¥ç¶šã‚’å†ç¢ºç«‹ã—ã€ãƒ‰ãƒ­ãƒƒãƒ—ダウンを有効ã«ã—ã¾ã™"
msgid "ErrorTracking|Connection has failed. Re-check Auth Token and try again."
msgstr "接続ã«å¤±æ•—ã—ã¾ã—ãŸã€‚èªè¨¼ãƒˆãƒ¼ã‚¯ãƒ³ã‚’å†ç¢ºèªã—ã¦ã€ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
msgid "ErrorTracking|If you self-host Sentry, enter the full URL of your Sentry instance. If you're using Sentry's hosted solution, enter https://sentry.io"
-msgstr ""
+msgstr "Sentry をセルフホストã™ã‚‹å ´åˆã¯ã€ã‚ãªãŸã® Sentry インスタンスã®å®Œå…¨ãªURLを入力ã—ã¾ã™ã€‚ Sentry ã®ãƒ›ã‚¹ãƒˆåž‹ã‚½ãƒªãƒ¥ãƒ¼ã‚·ãƒ§ãƒ³ã‚’使用ã—ã¦ã„ã‚‹å ´åˆã¯ã€ https://sentry.io ã¨å…¥åŠ›ã—ã¾ã™ã€‚"
msgid "ErrorTracking|No projects available"
msgstr "利用ã§ãるプロジェクトã¯ã‚ã‚Šã¾ã›ã‚“"
@@ -8483,12 +8857,12 @@ msgstr "エラー"
msgid "Errors:"
msgstr ""
+msgid "Estimate"
+msgstr ""
+
msgid "Estimated"
msgstr "見ç©"
-msgid "Event Actions"
-msgstr ""
-
msgid "EventFilterBy|Filter by all"
msgstr "ã™ã¹ã¦"
@@ -8496,7 +8870,7 @@ msgid "EventFilterBy|Filter by comments"
msgstr "コメントã§ãƒ•ã‚£ãƒ«ã‚¿ãƒ¼"
msgid "EventFilterBy|Filter by epic events"
-msgstr ""
+msgstr "エピックイベントã§ãƒ•ã‚£ãƒ«ã‚¿ãƒ¼"
msgid "EventFilterBy|Filter by issue events"
msgstr "課題イベントã§ãƒ•ã‚£ãƒ«ã‚¿ãƒ¼"
@@ -8526,40 +8900,40 @@ msgid "Every %{action} attempt has failed: %{job_error_message}. Please try agai
msgstr "ã™ã¹ã¦ã® %{action} ãŒå¤±æ•—ã—ã¾ã—ãŸï¼š %{job_error_message}。もã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
msgid "Every day"
-msgstr ""
+msgstr "毎日"
-msgid "Every day (at 4:00am)"
-msgstr "毎日 (åˆå‰4:00)"
+msgid "Every day (at %{time})"
+msgstr ""
msgid "Every month"
-msgstr ""
+msgstr "毎月"
-msgid "Every month (on the 1st at 4:00am)"
-msgstr "毎月 (1æ—¥ã®åˆå‰4:00)"
+msgid "Every month (Day %{day} at %{time})"
+msgstr ""
msgid "Every three months"
-msgstr ""
+msgstr "3ヶ月毎"
msgid "Every two weeks"
-msgstr ""
+msgstr "隔週"
msgid "Every week"
-msgstr ""
+msgstr "毎週"
-msgid "Every week (Sundays at 4:00am)"
-msgstr "毎週 (日曜日ã®åˆå‰4:00)"
+msgid "Every week (%{weekday} at %{time})"
+msgstr ""
msgid "Everyone"
msgstr "全員"
msgid "Everyone With Access"
-msgstr ""
+msgstr "アクセスã§ãる人ã™ã¹ã¦"
msgid "Everyone can contribute"
msgstr "全員ãŒè²¢çŒ®ã§ãã¾ã™"
msgid "Everything on your to-do list is marked as done."
-msgstr ""
+msgstr "ã‚ãªãŸã®To Doリストã®é …ç›®ã™ã¹ã¦ãŒå®Œäº†ã¨ã—ã¦ãƒžãƒ¼ã‚¯ã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "Everything you need to create a GitLab Pages site using Gatsby."
msgstr ""
@@ -8580,29 +8954,35 @@ msgid "Everything you need to create a GitLab Pages site using plain HTML."
msgstr "プレーンHTML を使ã£ã¦ GitLab Pages サイトを作æˆã™ã‚‹ãŸã‚ã«å¿…è¦ãªã‚‚ã®ã™ã¹ã¦ã€‚"
msgid "Evidence collection"
-msgstr ""
+msgstr "証拠集ã‚"
msgid "Exactly one of %{attributes} is required"
msgstr ""
-msgid "Example: @sub\\.company\\.com$"
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
msgstr ""
+msgid "Example: @sub\\.company\\.com$"
+msgstr "例: @sub\\.company\\.com$"
+
msgid "Example: Usage = single query. (Requested) / (Capacity) = multiple queries combined into a formula."
-msgstr ""
+msgstr "例: Usage = å˜ä¸€ã‚¯ã‚¨ãƒªã€‚ (Requested) / (Capacity) = å¼ã‚’構æˆã™ã‚‹è¤‡æ•°ã‚¯ã‚¨ãƒªã€‚"
msgid "Except policy:"
msgstr "除外ãƒãƒªã‚·ãƒ¼:"
msgid "Excluding merge commits. Limited to %{limit} commits."
-msgstr ""
+msgstr "マージコミットを除外ã—ã¦ã„ã¾ã™ã€‚%{limit} 件ã®ã‚³ãƒŸãƒƒãƒˆã«åˆ¶é™ã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "Excluding merge commits. Limited to 6,000 commits."
-msgstr ""
+msgstr "マージコミットを除外ã—ã¦ã„ã¾ã™ã€‚ 6,000件ã®ã‚³ãƒŸãƒƒãƒˆã«åˆ¶é™ã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "Existing members and groups"
msgstr "既存ã®ãƒ¡ãƒ³ãƒãƒ¼ã¨ã‚°ãƒ«ãƒ¼ãƒ—"
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8625,19 +9005,22 @@ msgid "Expand child epics"
msgstr ""
msgid "Expand down"
-msgstr ""
+msgstr "ドロップダウンã®å±•é–‹"
msgid "Expand dropdown"
-msgstr ""
+msgstr "ドロップダウンã®å±•é–‹"
msgid "Expand sidebar"
msgstr "サイドãƒãƒ¼ã‚’é–‹ã"
msgid "Expand up"
+msgstr "ã™ã¹ã¦å±•é–‹"
+
+msgid "Experienced"
msgstr ""
msgid "Expiration"
-msgstr ""
+msgstr "有効期é™"
msgid "Expiration date"
msgstr "有効期é™"
@@ -8651,18 +9034,24 @@ msgstr "有効期é™åˆ‡ã‚Œ"
msgid "Expired %{expiredOn}"
msgstr "%{expiredOn} ã«æœŸé™åˆ‡ã‚Œ"
-msgid "Expires"
+msgid "Expired:"
msgstr ""
+msgid "Expires"
+msgstr "有効期é™"
+
msgid "Expires at"
-msgstr ""
+msgstr "有効期é™æ—¥"
msgid "Expires in %{expires_at}"
msgstr "%{expires_at} ã§æœŸé™åˆ‡ã‚Œ"
-msgid "Expires:"
+msgid "Expires on"
msgstr ""
+msgid "Expires:"
+msgstr "有効期é™:"
+
msgid "Explain the problem. If appropriate, provide a link to the relevant issue or comment."
msgstr "å•é¡Œã‚’説明ã—ã¦ãã ã•ã„。必è¦ã«å¿œã˜ã¦ã€è©²å½“ã™ã‚‹èª²é¡Œã¾ãŸã¯ã‚³ãƒ¡ãƒ³ãƒˆã¸ã®ãƒªãƒ³ã‚¯ã‚’æä¾›ã—ã¦ãã ã•ã„。"
@@ -8709,7 +9098,7 @@ msgid "External Classification Policy Authorization"
msgstr "外部分類èªè¨¼ãƒãƒªã‚·ãƒ¼"
msgid "External ID"
-msgstr ""
+msgstr "外部ID"
msgid "External URL"
msgstr "外部 URL"
@@ -8727,10 +9116,10 @@ msgid "External authorization request timeout"
msgstr "外部èªè¨¼å‡¦ç†ãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ã¾ã—ãŸ"
msgid "External storage URL"
-msgstr ""
+msgstr "外部ストレージã®URL"
msgid "External storage authentication token"
-msgstr ""
+msgstr "外部ストレージã®èªè¨¼ãƒˆãƒ¼ã‚¯ãƒ³"
msgid "ExternalAuthorizationService|Classification label"
msgstr "分類ラベル"
@@ -8738,18 +9127,6 @@ msgstr "分類ラベル"
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr "ラベルãŒåˆ†é¡žã•ã‚Œã¦ã„ãªã„ã¨ãã¯ã€`%{default_label}` ãŒæ—¢å®šã®ãƒ©ãƒ™ãƒ«ã¨ã—ã¦ä½¿ç”¨ã•ã‚Œã¾ã™ã€‚"
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr "既存ã®å¤–部ダッシュボードã«ç›´æŽ¥ãƒªãƒ³ã‚¯ã—ã¦ã„ã‚‹ã€ãƒ¡ãƒˆãƒªã‚¯ã‚¹ãƒ€ãƒƒã‚·ãƒ¥ãƒœãƒ¼ãƒ‰ã«ãƒœã‚¿ãƒ³ã‚’追加ã™ã‚‹ã€‚"
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr "ã‚ãªãŸãŒãƒªãƒ³ã‚¯ã—ãŸã„ã€ãƒ€ãƒƒã‚·ãƒ¥ãƒœãƒ¼ãƒ‰ã®URLを入力ã—ã¦ãã ã•ã„"
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr "外部ã®ãƒ€ãƒƒã‚·ãƒ¥ãƒœãƒ¼ãƒ‰"
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr "完全ãªã€ãƒ€ãƒƒã‚·ãƒ¥ãƒœãƒ¼ãƒ‰URL"
-
msgid "ExternalWikiService|External Wiki"
msgstr "外部Wiki"
@@ -8769,22 +9146,22 @@ msgid "Failed Jobs"
msgstr "失敗ã—ãŸã‚¸ãƒ§ãƒ–"
msgid "Failed to add a Zoom meeting"
-msgstr ""
+msgstr "Zoom ミーティングã®è¿½åŠ ã«å¤±æ•—ã—ã¾ã—ãŸ"
msgid "Failed to apply commands."
-msgstr ""
+msgstr "コマンドã®é©ç”¨ã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
msgid "Failed to assign a user because no user was found."
-msgstr ""
+msgstr "ユーザーã®å‰²ã‚Šå½“ã¦ã«å¤±æ•—ã—ã¾ã—ãŸã€‚見ã¤ã‹ã‚‰ãªã‹ã£ãŸã‹ã‚‰ã§ã™ã€‚"
msgid "Failed to cancel auto stop because failed to update the environment."
-msgstr ""
+msgstr "自動åœæ­¢ã‚’キャンセルã§ãã¾ã›ã‚“ã§ã—ãŸã€‚環境ã®æ›´æ–°ã«å¤±æ•—ã—ãŸãŸã‚ã§ã™ã€‚"
msgid "Failed to cancel auto stop because the environment is not set as auto stop."
-msgstr ""
+msgstr "自動åœæ­¢ã‚’キャンセルã§ãã¾ã›ã‚“ã§ã—ãŸã€‚環境ãŒè‡ªå‹•åœæ­¢ã¨ã—ã¦è¨­å®šã•ã‚Œã¦ã„ãªã„ã‹ã‚‰ã§ã™ã€‚"
msgid "Failed to cancel auto stop because you do not have permission to update the environment."
-msgstr ""
+msgstr "自動åœæ­¢ã‚’キャンセルã§ãã¾ã›ã‚“ã§ã—ãŸã€‚環境を更新ã™ã‚‹æ¨©é™ãŒãªã„ã‹ã‚‰ã§ã™ã€‚"
msgid "Failed to change the owner"
msgstr "オーナーを変更ã§ãã¾ã›ã‚“ã§ã—ãŸ"
@@ -8811,13 +9188,13 @@ msgid "Failed to create wiki"
msgstr ""
msgid "Failed to delete board. Please try again."
-msgstr ""
+msgstr "ボードを削除ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ãŠè©¦ã—下ã•ã„。"
msgid "Failed to deploy to"
msgstr "デプロイã«å¤±æ•—ã—ã¾ã—ãŸ"
msgid "Failed to enqueue the rebase operation, possibly due to a long-lived transaction. Try again later."
-msgstr ""
+msgstr "ãŠãらã長期間ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãŒåŽŸå› ã§ã€rebaseæ“作をキューã«ç™»éŒ²ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã‚ã¨ã§ã‚‚ã†ä¸€åº¦è©¦ã—ã¦ã¿ã¦ãã ã•ã„。"
msgid "Failed to find import label for Jira import."
msgstr ""
@@ -8832,16 +9209,16 @@ msgid "Failed to load emoji list."
msgstr "絵文字リストã®ãƒ­ãƒ¼ãƒ‰ã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
msgid "Failed to load error details from Sentry."
-msgstr ""
+msgstr "Sentry ã‹ã‚‰ã®ã‚¨ãƒ©ãƒ¼è©³ç´°ã®èª­ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ."
msgid "Failed to load errors from Sentry. Error message: %{errorMessage}"
-msgstr ""
+msgstr "Sentryã‹ã‚‰ã®ã‚¨ãƒ©ãƒ¼èª­ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸã€‚エラーメッセージ: %{errorMessage}"
msgid "Failed to load group activity metrics. Please try again."
msgstr ""
msgid "Failed to load groups & users."
-msgstr ""
+msgstr "グループã¨ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®èª­ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ"
msgid "Failed to load labels. Please try again."
msgstr ""
@@ -8850,34 +9227,37 @@ msgid "Failed to load milestones. Please try again."
msgstr ""
msgid "Failed to load related branches"
-msgstr ""
+msgstr "関連ã™ã‚‹ãƒ–ランãƒã®èª­ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ"
msgid "Failed to load stacktrace."
-msgstr ""
+msgstr "スタックトレースã®ãƒ­ãƒ¼ãƒ‰ã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
msgid "Failed to mark this issue as a duplicate because referenced issue was not found."
-msgstr ""
+msgstr "å‚ç…§ã•ã‚ŒãŸèª²é¡ŒãŒè¦‹ã¤ã‹ã‚‰ãªã„ãŸã‚ã€ã“ã®èª²é¡Œã‚’複製ã¨ã—ã¦ãƒžãƒ¼ã‚¯ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
msgid "Failed to move this issue because label was not found."
-msgstr ""
+msgstr "ラベルãŒè¦‹ã¤ã‹ã‚‰ãªã‹ã£ãŸã®ã§ã€ã“ã®èª²é¡Œã®ç§»å‹•ã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
msgid "Failed to move this issue because only a single label can be provided."
-msgstr ""
+msgstr "課題ã®ç§»å‹•ã«å¤±æ•—ã—ã¾ã—ãŸã€‚一ã¤ã®ãƒ©ãƒ™ãƒ«ã—ã‹ä»˜ä¸Žã§ããªã„ãŸã‚ã§ã™ã€‚"
msgid "Failed to move this issue because target project doesn't exist."
-msgstr ""
+msgstr "ターゲットã®ãƒ—ロジェクトãŒå­˜åœ¨ã—ãªã„ã®ã§ã€ã“ã®èª²é¡Œã‚’移動ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
msgid "Failed to promote label due to internal error. Please contact administrators."
msgstr "内部エラーã®ãŸã‚ã€ãƒ©ãƒ™ãƒ«ã‚’昇格ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚管ç†è€…ã«å•ã„åˆã‚ã›ã¦ãã ã•ã„。"
msgid "Failed to protect the branch"
-msgstr ""
+msgstr "ã“ã®ãƒ–ランãƒã‚’ä¿è­·ã§ãã¾ã›ã‚“ã§ã—ãŸ"
msgid "Failed to protect the environment"
+msgstr "ã“ã®ç’°å¢ƒã‚’ä¿è­·ã§ãã¾ã›ã‚“ã§ã—ãŸ"
+
+msgid "Failed to publish issue on status page."
msgstr ""
msgid "Failed to remove a Zoom meeting"
-msgstr ""
+msgstr "Zoom ミーティングã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸ"
msgid "Failed to remove issue from board, please try again."
msgstr "ボードã®èª²é¡Œã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸã€‚ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
@@ -8910,7 +9290,7 @@ msgid "Failed to save preferences."
msgstr "設定をä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
msgid "Failed to set due date because the date format is invalid."
-msgstr ""
+msgstr "日付ã®ãƒ•ã‚©ãƒ¼ãƒžãƒƒãƒˆãŒç„¡åŠ¹ãªãŸã‚ã€æœŸæ—¥ã®è¨­å®šã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
msgid "Failed to signing using smartcard authentication"
msgstr "スマートカードèªè¨¼ã‚’使用ã—ã¦ã®ç½²åã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
@@ -8919,10 +9299,10 @@ msgid "Failed to update branch!"
msgstr "ブランãƒã®æ›´æ–°ã«å¤±æ•—ã—ã¾ã—ãŸ"
msgid "Failed to update environment!"
-msgstr ""
+msgstr "環境ã®æ›´æ–°ã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
msgid "Failed to update issue status"
-msgstr ""
+msgstr "課題ã®çŠ¶æ…‹ã®æ›´æ–°ã«å¤±æ•—ã—ã¾ã—ãŸ"
msgid "Failed to update issues, please try again."
msgstr "課題ã®æ›´æ–°ã«å¤±æ•—ã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
@@ -8949,19 +9329,19 @@ msgid "False positive"
msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
-msgstr ""
+msgstr "æ—©é€ã‚Šãƒžãƒ¼ã‚¸ã¯ã§ãã¾ã›ã‚“。ソースブランãƒã‚’%{targetBranch} ã«rebaseã—ã¦ã€ã“ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’マージã§ãるよã†ã«ã—ã¦ãã ã•ã„。"
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
-msgstr ""
+msgstr "マージコミットã®ãªã„æ—©é€ã‚Šãƒžãƒ¼ã‚¸"
msgid "Faster as it re-uses the project workspace (falling back to clone if it doesn't exist)"
msgstr "プロジェクトワークスペースをå†åˆ©ç”¨ã™ã‚‹ã‚ˆã†ã«é«˜é€ŸåŒ–(存在ã—ãªã„å ´åˆã¯ã€ã‚¯ãƒ­ãƒ¼ãƒ³ã‚’è¡Œã†)"
msgid "Faster releases. Better code. Less pain."
-msgstr ""
+msgstr "より速ã„リリース。より良ã„コード。å•é¡Œã®æ¸›å°‘"
msgid "Favicon was successfully removed."
msgstr "Faviconã¯æ­£å¸¸ã«å‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚"
@@ -8991,7 +9371,7 @@ msgid "FeatureFlags|Add strategy"
msgstr ""
msgid "FeatureFlags|All users"
-msgstr ""
+msgstr "ã™ã¹ã¦ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼"
msgid "FeatureFlags|Configure"
msgstr "設定"
@@ -9014,6 +9394,12 @@ msgstr "説明"
msgid "FeatureFlags|Edit Feature Flag"
msgstr "機能フラグを編集"
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9026,65 +9412,86 @@ msgstr "環境スペック"
msgid "FeatureFlags|Feature Flag"
msgstr "機能フラグ"
-msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
+msgid "FeatureFlags|Feature Flag User List Details"
msgstr ""
+msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
+msgstr "機能フラグã®å‹•ä½œã¯ã€ã‚¿ãƒ¼ã‚²ãƒƒãƒˆç’°å¢ƒã®çŠ¶æ³ã‚’定義ã™ã‚‹ãŸã‚ã®ä¸€é€£ã®ãƒ«ãƒ¼ãƒ«ã‚’作æˆã™ã‚‹ã“ã¨ã§æ§‹ç¯‰ã§ãã¾ã™ã€‚ %{boldStart}å…¨ã¦ã®ç’°å¢ƒ%{boldEnd} ã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒ¯ã‚¤ãƒ«ãƒ‰ã‚«ãƒ¼ãƒ‰ãƒ«ãƒ¼ãƒ« %{codeStart}*%{codeEnd} ãŒè¨­å®šã•ã‚Œã¦ãŠã‚Šã€ä»¥ä¸‹ã®ç’°å¢ƒä»•æ§˜ã‚’é¸æŠžã—ã¦ã€å¿…è¦ãªæ•°ã®ãƒ«ãƒ¼ãƒ«ãŒè¿½åŠ ã§ãã¾ã™ã€‚å„ルールã®å‹•ä½œã‚’切り替ãˆã¦ %{boldStart}アクティブ%{boldEnd} ã¾ãŸã¯ %{boldStart}éžã‚¢ã‚¯ãƒ†ã‚£ãƒ–%{boldEnd}ã«è¨­å®šã§ãã¾ã™ã€‚"
+
msgid "FeatureFlags|Feature Flag has no strategies"
msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr "機能フラグ"
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr "機能フラグ%{name} ãŒã€å‰Šé™¤ã•ã‚Œã¾ã™ã€‚本当ã«å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ"
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
+msgstr "機能フラグを有効ã«ã™ã‚‹ã¨ã€ç‰¹å®šã®æ©Ÿèƒ½ã¸ã®å‹•çš„切り替ãˆã«ã‚ˆã£ã¦ã‚³ãƒ¼ãƒ‰ã«ç•°ãªã‚‹ãƒ•ãƒ¬ãƒ¼ãƒãƒ¼ã‚’設定ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
+
+msgid "FeatureFlags|Flag becomes read only soon"
msgstr ""
msgid "FeatureFlags|Get started with feature flags"
+msgstr "機能フラグを使ã„ã¯ã˜ã‚ã‚‹"
+
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
msgstr ""
msgid "FeatureFlags|ID"
-msgstr ""
+msgstr "ID"
msgid "FeatureFlags|Inactive"
msgstr "無効"
msgid "FeatureFlags|Inactive flag for %{scope}"
-msgstr ""
+msgstr "%{scope} ã®éžã‚¢ã‚¯ãƒ†ã‚£ãƒ–フラグ"
msgid "FeatureFlags|Include additional user IDs"
-msgstr ""
+msgstr "追加ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼IDã‚’å«ã‚ã‚‹"
msgid "FeatureFlags|Install a %{docs_link_anchored_start}compatible client library%{docs_link_anchored_end} and specify the API URL, application name, and instance ID during the configuration setup. %{docs_link_start}More Information%{docs_link_end}"
-msgstr ""
+msgstr "%{docs_link_anchored_start}互æ›æ€§ã®ã‚るクライアントライブラリ%{docs_link_anchored_end}をインストールã—ã€æ§‹æˆã®ã‚»ãƒƒãƒˆã‚¢ãƒƒãƒ—中ã«API URLã€ã‚¢ãƒ—リケーションåã€ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹IDを指定ã—ã¾ã™ã€‚%{docs_link_start}詳細ãªæƒ…å ±%{docs_link_end}"
msgid "FeatureFlags|Instance ID"
msgstr "インスタンス ID"
-msgid "FeatureFlags|Loading feature flags"
+msgid "FeatureFlags|List details"
msgstr ""
+msgid "FeatureFlags|Loading feature flags"
+msgstr "機能フラグを読ã¿è¾¼ã‚“ã§ã„ã¾ã™"
+
msgid "FeatureFlags|More information"
-msgstr ""
+msgstr "詳細情報"
msgid "FeatureFlags|Name"
msgstr "åå‰"
msgid "FeatureFlags|New"
-msgstr ""
+msgstr "æ–°è¦"
msgid "FeatureFlags|New Feature Flag"
msgstr "æ–°ã—ã„機能フラグ"
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
+msgstr "æ–°ã—ã„機能フラグ"
+
+msgid "FeatureFlags|New list"
msgstr ""
msgid "FeatureFlags|Percent rollout (logged in users)"
-msgstr ""
+msgstr "ロールアウト率(対ログインユーザー)"
msgid "FeatureFlags|Percent rollout must be a whole number between 0 and 100"
-msgstr ""
+msgstr "ロールアウト率ã¯0〜100ã®æ•´æ•°ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“"
msgid "FeatureFlags|Protected"
msgstr "ä¿è­·ã•ã‚Œã¦ã„ã¾ã™"
@@ -9093,7 +9500,7 @@ msgid "FeatureFlags|Remove"
msgstr "削除"
msgid "FeatureFlags|Rollout Percentage"
-msgstr ""
+msgstr "ロールアウトパーセント"
msgid "FeatureFlags|Rollout Strategy"
msgstr "ロールアウト戦略"
@@ -9102,16 +9509,16 @@ msgid "FeatureFlags|Status"
msgstr "ステータス"
msgid "FeatureFlags|Strategies"
-msgstr ""
+msgstr "戦略"
msgid "FeatureFlags|Target environments"
msgstr "ターゲット環境"
msgid "FeatureFlags|There are no active feature flags"
-msgstr ""
+msgstr "有効ãªæ©Ÿèƒ½ãƒ•ãƒ©ã‚°ã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "FeatureFlags|There are no inactive feature flags"
-msgstr ""
+msgstr "無効ãªæ©Ÿèƒ½ãƒ•ãƒ©ã‚°ã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "FeatureFlags|There was an error fetching the feature flags."
msgstr "機能フラグã®å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
@@ -9141,7 +9548,7 @@ msgid "February"
msgstr "2月"
msgid "Fetching incoming email"
-msgstr ""
+msgstr "å—信メールをå–å¾—"
msgid "Fetching licenses failed."
msgstr "ライセンスã®å–得を失敗ã—ã¾ã—ãŸã€‚"
@@ -9156,10 +9563,10 @@ msgid "File"
msgstr ""
msgid "File Hooks"
-msgstr ""
+msgstr "ファイルフック"
msgid "File Hooks (%{count})"
-msgstr ""
+msgstr "ファイルフック (%{count})"
msgid "File added"
msgstr "ファイルã®è¿½åŠ "
@@ -9170,9 +9577,12 @@ msgstr "ファイルブラウザー"
msgid "File deleted"
msgstr "ファイルを削除ã—ã¾ã—ãŸ"
-msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
+msgid "File format is no longer supported"
msgstr ""
+msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
+msgstr "ファイルフックã¯ã‚·ã‚¹ãƒ†ãƒ ãƒ•ãƒƒã‚¯ã¨ä¼¼ã¦ã„ã¾ã™ã€‚ã—ã‹ã—ファイルフックã¯ã€URLã«ãƒ‡ãƒ¼ã‚¿ã‚’é€ä¿¡ã™ã‚‹ã®ã§ã¯ãªãファイルã¨ã—ã¦å®Ÿè¡Œã—ã¾ã™ã€‚"
+
msgid "File mode changed from %{a_mode} to %{b_mode}"
msgstr "ファイルã®ãƒ¢ãƒ¼ãƒ‰ã‚’ %{a_mode} ã‹ã‚‰ %{b_mode} ã«å¤‰æ›´"
@@ -9180,10 +9590,13 @@ msgid "File moved"
msgstr "ファイルを移動ã—ã¾ã—ãŸã€‚"
msgid "File name"
+msgstr "ファイルå"
+
+msgid "File renamed with no changes."
msgstr ""
msgid "File sync capacity"
-msgstr ""
+msgstr "ファイルåŒæœŸå®¹é‡"
msgid "File templates"
msgstr "ファイルテンプレート"
@@ -9191,9 +9604,6 @@ msgstr "ファイルテンプレート"
msgid "File upload error."
msgstr "ファイルアップロードエラー"
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr "ファイル"
@@ -9201,7 +9611,7 @@ msgid "Files breadcrumb"
msgstr "ファイルã®ãƒ‘ンããšãƒªã‚¹ãƒˆ"
msgid "Files, directories, and submodules in the path %{path} for commit reference %{ref}"
-msgstr ""
+msgstr "パス %{path} 内ã®ãƒ•ã‚¡ã‚¤ãƒ«ã€ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã€ãŠã‚ˆã³ã‚µãƒ–モジュールã®ã‚³ãƒŸãƒƒãƒˆå‚ç…§ %{ref}"
msgid "Fill in the fields below, turn on <strong>%{enable_label}</strong>, and press <strong>%{save_changes}</strong>"
msgstr "下記項目ã«å¿…è¦äº‹é …を入力ã—〠<strong>%{enable_label}</strong>をオンã«ã—ã¦ã€ <strong>%{save_changes}</strong>を押ã—ã¦ãã ã•ã„。"
@@ -9209,24 +9619,45 @@ msgstr "下記項目ã«å¿…è¦äº‹é …を入力ã—〠<strong>%{enable_label}</stro
msgid "Filter"
msgstr "フィルター"
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr "ã‚ãªãŸãŒæœ€è¿‘é–‰ã˜ãŸ %{issuable_type} ã§ãƒ•ã‚£ãƒ«ã‚¿ãƒ¼"
msgid "Filter by %{issuable_type} that are currently opened."
msgstr "ã‚ãªãŸãŒæœ€è¿‘é–‹ã„㟠%{issuable_type} ã§ãƒ•ã‚£ãƒ«ã‚¿ãƒ¼"
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr "コミットメッセージã§çµžã‚Šè¾¼ã¿"
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr "マイルストーンåã§çµžã‚Šè¾¼ã‚€"
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9234,10 +9665,13 @@ msgid "Filter by two-factor authentication"
msgstr "2è¦ç´ èªè¨¼ã§çµžã‚Šè¾¼ã¿"
msgid "Filter by user"
+msgstr "ユーザーã§ãƒ•ã‚£ãƒ«ã‚¿ãƒ¼"
+
+msgid "Filter pipelines"
msgstr ""
msgid "Filter projects"
-msgstr ""
+msgstr "プロジェクトã®ãƒ•ã‚£ãƒ«ã‚¿ãƒ¼"
msgid "Filter results"
msgstr ""
@@ -9252,7 +9686,7 @@ msgid "Filter results..."
msgstr ""
msgid "Filter your projects by name"
-msgstr ""
+msgstr "åå‰ã§ã‚ãªãŸã®ãƒ—ロジェクトをフィルタ"
msgid "Filter..."
msgstr "フィルター..."
@@ -9270,7 +9704,7 @@ msgid "Find the downloaded ZIP file and decompress it."
msgstr "ダウンロードã—㟠ZIP ファイルを展開ã—ã¾ã™ã€‚"
msgid "Find the newly extracted <code>Takeout/Google Code Project Hosting/GoogleCodeProjectHosting.json</code> file."
-msgstr ""
+msgstr "æ–°ã—ã抽出ã•ã‚ŒãŸ <code>テイクアウト/ Googleコードプロジェクトホスティング/ GoogleCodeProjectHosting.json</code> ファイルを探ã—ã¾ã™ã€‚"
msgid "Fingerprint"
msgstr "フィンガープリント"
@@ -9279,7 +9713,7 @@ msgid "Fingerprints"
msgstr "フィンガープリント"
msgid "Finish editing this message first!"
-msgstr ""
+msgstr "å…ˆã«ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®ç·¨é›†ã‚’終ãˆã¦ãã ã•ã„。"
msgid "Finish review"
msgstr "レビューを完了ã™ã‚‹"
@@ -9291,31 +9725,31 @@ msgid "Finished"
msgstr "完了"
msgid "First Name is too long (maximum is %{max_length} characters)."
-msgstr ""
+msgstr "åãŒé•·ã™ãŽã¾ã™(最大 %{max_length} 文字)。"
msgid "First Seen"
-msgstr ""
+msgstr "最åˆã«è¦‹ãŸ"
msgid "First day of the week"
msgstr "一週間ã®é–‹å§‹æ›œæ—¥"
msgid "First name"
-msgstr ""
+msgstr "åå‰"
msgid "First seen"
-msgstr ""
+msgstr "最åˆã«è¦‹ãŸ"
msgid "Fixed date"
-msgstr "日付を修正"
+msgstr "日付を固定"
msgid "Fixed due date"
-msgstr "期日を修正"
+msgstr "固定ã•ã‚ŒãŸçµ‚了日"
msgid "Fixed start date"
-msgstr "修正開始日"
+msgstr "固定ã•ã‚ŒãŸé–‹å§‹æ—¥"
msgid "Fixed:"
-msgstr "修正:"
+msgstr "固定:"
msgid "Flags"
msgstr ""
@@ -9342,7 +9776,7 @@ msgid "FogBugz import"
msgstr "FogBugz ã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆ"
msgid "Folder/%{name}"
-msgstr ""
+msgstr "フォルダ/%{name}"
msgid "Follow the steps below to export your Google Code project data."
msgstr "Google コードã®ãƒ—ロジェクトデータをエクスãƒãƒ¼ãƒˆã™ã‚‹ã«ã¯ã€ä»¥ä¸‹ã®æ‰‹é †ã«å¾“ã£ã¦ãã ã•ã„。"
@@ -9369,7 +9803,7 @@ msgid "For more information, please review %{link_start_tag}Jaeger's configurati
msgstr "詳細ã«ã¤ã„ã¦ã¯ã€ %{link_start_tag}aeger'sã®æ§‹æˆãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆ%{link_end_tag} ã‚’å‚ç…§ã—ã¦ãã ã•ã„。"
msgid "For more information, see the File Hooks documentation."
-msgstr ""
+msgstr "詳ã—ã„情報ã¯ã€ãƒ•ã‚¡ã‚¤ãƒ«ãƒ•ãƒƒã‚¯ã®æ–‡æ›¸ã‚’ã”覧ãã ã•ã„"
msgid "For more information, see the documentation on %{deactivating_usage_ping_link_start}deactivating the usage ping%{deactivating_usage_ping_link_end}."
msgstr "詳細ã«ã¤ã„ã¦ã¯ %{deactivating_usage_ping_link_start}ping ã®ä½¿ç”¨ã®ç„¡åŠ¹åŒ–%{deactivating_usage_ping_link_end} ã«ã¤ã„ã¦ã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã‚’å‚ç…§ã—ã¦ãã ã•ã„"
@@ -9396,13 +9830,13 @@ msgid "Fork project"
msgstr "プロジェクトをフォーク"
msgid "Fork project?"
-msgstr ""
+msgstr "プロジェクトをフォーク?"
msgid "ForkedFromProjectPath|Forked from"
msgstr "フォーク元"
msgid "ForkedFromProjectPath|Forked from an inaccessible project"
-msgstr ""
+msgstr "アクセスã§ããªã„プロジェクトã‹ã‚‰ã®ãƒ•ã‚©ãƒ¼ã‚¯"
msgid "Forking in progress"
msgstr "フォーク中ã§ã™"
@@ -9414,13 +9848,13 @@ msgid "Format"
msgstr "フォーマット"
msgid "Format: %{dateFormat}"
-msgstr ""
+msgstr "フォーマット:%{dateFormat}"
msgid "Forward external support email address to"
-msgstr ""
+msgstr "外部サãƒãƒ¼ãƒˆã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’転é€"
msgid "Found errors in your %{gitlab_ci_yml}:"
-msgstr ""
+msgstr "%{gitlab_ci_yml} ã«ã‚¨ãƒ©ãƒ¼ãŒã‚ã‚Šã¾ã™"
msgid "Found errors in your .gitlab-ci.yml:"
msgstr ".gitlab-ci.yml ã«ã‚¨ãƒ©ãƒ¼ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸ:"
@@ -9432,7 +9866,7 @@ msgid "Free Trial of GitLab.com Gold"
msgstr "GitLab.com Gold プランã®ç„¡å„Ÿè©¦ç”¨"
msgid "Frequency"
-msgstr ""
+msgstr "頻度"
msgid "Friday"
msgstr "金曜日"
@@ -9441,10 +9875,10 @@ msgid "From"
msgstr ""
msgid "From %{providerTitle}"
-msgstr ""
+msgstr "%{providerTitle} ã‹ã‚‰"
msgid "From <code>%{source_title}</code> into"
-msgstr ""
+msgstr "<code>%{source_title}</code> ã‹ã‚‰"
msgid "From Bitbucket"
msgstr "Bitbucket ã‹ã‚‰"
@@ -9467,9 +9901,6 @@ msgstr "課題ãŒç™»éŒ²ã•ã‚Œã¦ã‹ã‚‰ãƒ—ロダクションã«ãƒ‡ãƒ—ロイã•ã‚Œ
msgid "From merge request merge until deploy to production"
msgstr "マージリクエストãŒãƒžãƒ¼ã‚¸ã•ã‚Œã¦ã‹ã‚‰ãƒ—ロダクションã«ãƒ‡ãƒ—ロイã•ã‚Œã‚‹ã¾ã§"
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr "Kubernetes クラスターã®è©³ç´°ç”»é¢ã‚’介ã—ã¦ã€ã‚¢ãƒ—リケーションリストã‹ã‚‰ Runner をインストールã—ã¾ã™ã€‚"
@@ -9483,7 +9914,7 @@ msgid "GPG Keys"
msgstr "GPG キー"
msgid "GPG keys allow you to verify signed commits."
-msgstr ""
+msgstr "GPG éµã‚’使用ã™ã‚‹ã“ã¨ã§ã€ç½²å済ã¿ã‚³ãƒŸãƒƒãƒˆã‚’検証ã§ãã¾ã™"
msgid "GPG signature (loading...)"
msgstr "GPG ã‚·ã‚°ãƒãƒãƒ£ (読ã¿è¾¼ã¿ä¸­...)"
@@ -9509,23 +9940,23 @@ msgstr "æ–°ã—ㄠエクスãƒãƒ¼ãƒˆã‚’生æˆ"
msgid "Geo"
msgstr "Geo"
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr "Geo ノード"
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
-msgid "Geo Settings"
+msgid "Geo Replication"
msgstr ""
+msgid "Geo Settings"
+msgstr "Geo設定"
+
msgid "Geo allows you to replicate your GitLab instance to other geographical locations."
msgstr "Geo ã¯ã€GitLab インスタンスを他ã®åœ°ç†çš„ãªå ´æ‰€ã«è¤‡è£½ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
msgid "GeoNodeStatusEvent|%{timeAgoStr} (%{pendingEvents} events)"
-msgstr ""
+msgstr "%{timeAgoStr}(%{pendingEvents} イベント)"
msgid "GeoNodeSyncStatus|Node is failing or broken."
msgstr "ノードãŒæ•…éšœã—ã¦ã„ã‚‹ã‹å£Šã‚Œã¦ã„ã¾ã™ã€‚"
@@ -9534,7 +9965,7 @@ msgid "GeoNodeSyncStatus|Node is slow, overloaded, or it just recovered after an
msgstr "ノードãŒé…延ã€éŽè² è·ãŒã‹ã‹ã£ã¦ã„ã‚‹ã€ã¾ãŸã¯åœæ­¢ã‹ã‚‰ã®å›žå¾©ç›´å¾Œã§ã™ã€‚"
msgid "GeoNodes|Attachments"
-msgstr ""
+msgstr "添付ファイル"
msgid "GeoNodes|Checksummed"
msgstr "ãƒã‚§ãƒƒã‚¯ã‚µãƒ "
@@ -9543,13 +9974,13 @@ msgid "GeoNodes|Consult Geo troubleshooting information"
msgstr ""
msgid "GeoNodes|Container repositories"
-msgstr ""
+msgstr "コンテナリãƒã‚¸ãƒˆãƒª"
msgid "GeoNodes|Data replication lag"
msgstr "データ レプリケーションã®é…延"
msgid "GeoNodes|Design repositories"
-msgstr ""
+msgstr "リãƒã‚¸ãƒˆãƒªã®ãƒ‡ã‚¶ã‚¤ãƒ³"
msgid "GeoNodes|Does not match the primary storage configuration"
msgstr "プライマリストレージ構æˆã¨ä¸€è‡´ã—ã¾ã›ã‚“"
@@ -9573,10 +10004,10 @@ msgid "GeoNodes|Internal URL"
msgstr "内部 URL"
msgid "GeoNodes|Job artifacts"
-msgstr ""
+msgstr "ジョブアーティファクト"
msgid "GeoNodes|LFS objects"
-msgstr ""
+msgstr "LFS オブジェクト"
msgid "GeoNodes|Last event ID processed by cursor"
msgstr "カーソルã§å‡¦ç†ã•ã‚ŒãŸæœ€çµ‚イベント ID"
@@ -9585,7 +10016,7 @@ msgid "GeoNodes|Last event ID seen from primary"
msgstr "プライマリãŒå–å¾—ã—ãŸæœ€çµ‚イベント ID"
msgid "GeoNodes|Learn more about Geo node statuses"
-msgstr ""
+msgstr "ジオノードステータスã®è©³ç´°"
msgid "GeoNodes|Loading nodes"
msgstr "ノードã®èª­ã¿è¾¼ã¿ä¸­"
@@ -9597,7 +10028,7 @@ msgid "GeoNodes|Node Authentication was successfully repaired."
msgstr "èªè¨¼ãƒŽãƒ¼ãƒ‰ã®ä¿®å¾©ã«æˆåŠŸã—ã¾ã—ãŸã€‚"
msgid "GeoNodes|Node URL"
-msgstr ""
+msgstr "ノードURL"
msgid "GeoNodes|Node was successfully removed."
msgstr "ノードã®å‰Šé™¤ã«æˆåŠŸã—ã¾ã—ãŸã€‚"
@@ -9609,13 +10040,13 @@ msgid "GeoNodes|Not checksummed"
msgstr "ãƒã‚§ãƒƒã‚¯ã‚µãƒ ãªã—"
msgid "GeoNodes|Pausing replication stops the sync process. Are you sure?"
-msgstr ""
+msgstr "レプリケーションを一時åœæ­¢ã™ã‚‹ã¨ã€åŒæœŸãƒ—ロセスãŒåœæ­¢ã—ã¾ã™ã€‚本当ã«å®Ÿè¡Œã—ã¾ã™ã‹?"
msgid "GeoNodes|Removing a Geo primary node stops the synchronization to all nodes. Are you sure?"
-msgstr ""
+msgstr "Geoプライマリノードを削除ã™ã‚‹ã¨ã€ã™ã¹ã¦ã®ãƒŽãƒ¼ãƒ‰ã®åŒæœŸãŒåœæ­¢ã—ã¾ã™ã€‚本当ã«å‰Šé™¤ã—ã¾ã™ã‹?"
msgid "GeoNodes|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
-msgstr ""
+msgstr "Geoセカンダリノードを削除ã™ã‚‹ã¨ã€ã™ã¹ã¦ã®ãƒŽãƒ¼ãƒ‰ã®åŒæœŸãŒåœæ­¢ã—ã¾ã™ã€‚本当ã«å‰Šé™¤ã—ã¾ã™ã‹?"
msgid "GeoNodes|Replicated data is verified with the %{nodeText} using checksums"
msgstr ""
@@ -9695,6 +10126,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr "%{name} ã¯å¼·åˆ¶çš„ã«å†ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã•ã‚Œã‚‹äºˆå®šã§ã™"
@@ -9702,12 +10139,12 @@ msgid "Geo|%{name} is scheduled for re-sync"
msgstr "%{name} ã¯å†åŒæœŸãŒäºˆå®šã•ã‚Œã¦ã„ã¾ã™"
msgid "Geo|%{name} is scheduled for re-verify"
-msgstr ""
+msgstr "%{name} ã¯å†æ¤œè¨¼ãŒäºˆå®šã•ã‚Œã¦ã„ã¾ã™"
-msgid "Geo|All"
-msgstr "ã™ã¹ã¦"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9753,28 +10190,34 @@ msgid "Geo|Last time verified"
msgstr "å‰å›žã®ç¢ºèªæ—¥æ™‚"
msgid "Geo|Never"
-msgstr "決ã—ã¦"
+msgstr "未確èª"
msgid "Geo|Next sync scheduled at"
+msgstr "次回ã®åŒæœŸäºˆå®šæ—¥æ™‚"
+
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
msgstr ""
msgid "Geo|Not synced yet"
msgstr "ã¾ã åŒæœŸã—ã¦ã„ã¾ã›ã‚“。"
msgid "Geo|Pending synchronization"
-msgstr ""
+msgstr "åŒæœŸã®ãƒšãƒ³ãƒ‡ã‚£ãƒ³ã‚°"
msgid "Geo|Pending verification"
-msgstr ""
+msgstr "確èªã‚’ä¿ç•™ä¸­"
msgid "Geo|Please refer to Geo Troubleshooting."
-msgstr ""
+msgstr "Geo ã®ãƒˆãƒ©ãƒ–ルシューティングをå‚ç…§ã—ã¦ãã ã•ã„。"
msgid "Geo|Project"
msgstr "プロジェクト"
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 ""
+msgstr "プロジェクト (ID: %{project_id}) ã¯ãƒ—ライマリã«å­˜åœ¨ã—ã¾ã›ã‚“。ã“ã®ã‚¨ãƒ³ãƒˆãƒªã‚’削除ã—ã¦ã‚‚ã€ãƒ‡ã‚£ã‚¹ã‚¯ä¸Šã®ãƒ‡ãƒ¼ã‚¿ã¯å‰Šé™¤ã•ã‚Œãªã„ã®ã§å®‰å…¨ã§ã™ã€‚"
msgid "Geo|Projects in certain groups"
msgstr "特定グループã®ãƒ—ロジェクト"
@@ -9804,11 +10247,14 @@ msgid "Geo|Retry count"
msgstr "リトライ回数"
msgid "Geo|Reverify"
-msgstr ""
+msgstr "å†æ¤œè¨¼"
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr "状態"
@@ -9822,9 +10268,12 @@ msgid "Geo|Synchronization failed - %{error}"
msgstr "åŒæœŸã«å¤±æ•—ã—ã¾ã—㟠- %{error}"
msgid "Geo|The database is currently %{db_lag} behind the primary node."
-msgstr ""
+msgstr "データベースã¯ç¾åœ¨ãƒ—ライマリーノードã®å¾Œã‚ã« %{db_lag} ã§ã™ã€‚"
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
+msgstr "ノードã¯ç¾åœ¨ã€ãƒ—ライマリノードã®å¾Œã‚ã« %{minutes_behind} ã§ã™ã€‚"
+
+msgid "Geo|There are no %{replicable_type} to show"
msgstr ""
msgid "Geo|Tracking database entry will be removed. Are you sure?"
@@ -9834,6 +10283,12 @@ msgid "Geo|Tracking entry for project (%{project_id}) was successfully removed."
msgstr "プロジェクト(%{project_id})ã®ãƒˆãƒ©ãƒƒã‚­ãƒ³ã‚°ã‚¨ãƒ³ãƒˆãƒªãŒæ­£å¸¸ã«å‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚"
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
+msgstr "アップロード (%{type}/%{id}) ã®ãŸã‚ã®ãƒˆãƒ©ãƒƒã‚­ãƒ³ã‚°ã‚¨ãƒ³ãƒˆãƒªãŒæ­£å¸¸ã«å‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚"
+
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
msgstr ""
msgid "Geo|Unknown state"
@@ -9870,10 +10325,10 @@ msgid "Get started with error tracking"
msgstr "エラー追跡を開始"
msgid "Get started with performance monitoring"
-msgstr ""
+msgstr "パフォーマンスモニタリングã—ãªãŒã‚‰å§‹ã‚ã‚‹"
msgid "Get started!"
-msgstr ""
+msgstr "始ã‚ã¾ã—ょã†"
msgid "Getting started with releases"
msgstr "リリースã®é–‹å§‹"
@@ -9897,7 +10352,7 @@ msgid "Git revision"
msgstr "Git リビジョン"
msgid "Git shallow clone"
-msgstr ""
+msgstr "Git シャロークローン"
msgid "Git strategy for pipelines"
msgstr "パイプラインã®Git戦略"
@@ -9906,13 +10361,13 @@ msgid "Git version"
msgstr "Git ãƒãƒ¼ã‚¸ãƒ§ãƒ³"
msgid "GitHub API rate limit exceeded. Try again after %{reset_time}"
-msgstr ""
+msgstr "GitHub APIã®åˆ¶é™ã‚’超ãˆã¾ã—ãŸã€‚ %{reset_time} 後ã«å†è©¦è¡Œã—ã¦ãã ã•ã„"
msgid "GitHub import"
msgstr "GitHub インãƒãƒ¼ãƒˆ"
msgid "GitLab / Unsubscribe"
-msgstr ""
+msgstr "GitLab / 購読解除"
msgid "GitLab Enterprise Edition %{plan}"
msgstr "GitLab エンタープライズエディション %{plan}"
@@ -9924,7 +10379,7 @@ msgid "GitLab Import"
msgstr "GitLab インãƒãƒ¼ãƒˆ"
msgid "GitLab Issue"
-msgstr ""
+msgstr "GitLab 課題"
msgid "GitLab Shared Runners execute code of different projects on the same Runner unless you configure GitLab Runner Autoscale with MaxBuilds 1 (which it is on GitLab.com)."
msgstr "GitLab Shared Runnerã¯ã€GitLab Runnerã®ã‚ªãƒ¼ãƒˆã‚¹ã‚±ãƒ¼ãƒ«è¨­å®šã§MaxBuildsã‚’1 (GitLab.com上ã§ã¯ã“ã®è¨­å®š)ã—ãªã„é™ã‚Šã€åŒã˜Runnerã§åˆ¥ã®ãƒ—ロジェクトã®ã‚³ãƒ¼ãƒ‰ã‚’実行ã—ã¾ã™ã€‚"
@@ -9942,22 +10397,22 @@ msgid "GitLab allows you to continue using your license even if you exceed the n
msgstr "GitLabã§ã¯ã€è³¼å…¥ã—ãŸã‚·ãƒ¼ãƒˆæ•°ã‚’超ãˆã¦ã‚‚ライセンスを使用ã—続ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ライセンス更新時ã«ã€ã“れらã®ã‚·ãƒ¼ãƒˆã®æ–™é‡‘を支払ã†å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "GitLab commit"
-msgstr ""
+msgstr "GitLab ã®ã‚³ãƒŸãƒƒãƒˆ"
msgid "GitLab for Slack"
-msgstr ""
+msgstr "GitLab for Slack"
msgid "GitLab is a single application for the entire software development lifecycle. From project planning and source code management to CI/CD, monitoring, and security."
msgstr ""
msgid "GitLab is obtaining a Let's Encrypt SSL certificate for this domain. This process can take some time. Please try again later."
-msgstr ""
+msgstr "GitLab ã¯ã€ã“ã®ãƒ‰ãƒ¡ã‚¤ãƒ³ã® Let's Encrypt ã® SSL 証明書をå–å¾—ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚ã“ã®ãƒ—ロセスã«ã¯æ™‚é–“ãŒã‹ã‹ã‚‹å ´åˆãŒã‚ã‚Šã¾ã™ã€‚後ã§ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
msgid "GitLab is undergoing maintenance and is operating in a read-only mode."
msgstr ""
msgid "GitLab member or Email address"
-msgstr ""
+msgstr "GitLabメンãƒãƒ¼ã¾ãŸã¯ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹"
msgid "GitLab metadata URL"
msgstr "GitLab メタデータ URL"
@@ -9972,7 +10427,7 @@ msgid "GitLab single sign on URL"
msgstr "GitLab シングルサインオン㮠URL"
msgid "GitLab uses %{jaeger_link} to monitor distributed systems."
-msgstr ""
+msgstr "GitLab 㯠%{jaeger_link} を使ã£ã¦åˆ†æ•£ã‚·ã‚¹ãƒ†ãƒ ã‚’モニタリングã—ã¾ã™ã€‚"
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ã¯ã€ã‚ãªãŸãŒè¨­å®šã—ãŸã‚ªãƒ–ジェクトストレージディレクトリã«ã‚¢ãƒƒãƒ—ロードã™ã‚‹ Gitlabデータベースã®åŒ¿å化ã—ãŸCSVを生æˆã™ã‚‹ã‚¸ãƒ§ãƒ–ã‚’ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ã§å®Ÿè¡Œã—ã¾ã™ã€‚"
@@ -9984,94 +10439,94 @@ msgid "GitLabPagesDomains|Retry"
msgstr ""
msgid "GitLabPages|%{domain} is not verified. To learn how to verify ownership, visit your %{link_start}domain details%{link_end}."
-msgstr ""
+msgstr "%{domain}ã¯æ¤œè¨¼ã•ã‚Œã¦ã„ã¾ã›ã‚“。 所有権を確èªã™ã‚‹æ–¹æ³•ã«ã¤ã„ã¦ã¯ã€%{link_start}ドメインã®è©³ç´°%{link_end}ã‚’ã”覧ãã ã•ã„。"
msgid "GitLabPages|Access Control is enabled for this Pages website; only authorized users will be able to access it. To make your website publicly available, navigate to your project's %{strong_start}Settings > General > Visibility%{strong_end} and select %{strong_start}Everyone%{strong_end} in pages section. Read the %{link_start}documentation%{link_end} for more information."
msgstr ""
msgid "GitLabPages|Access pages"
-msgstr ""
+msgstr "ページã¸ã‚¢ã‚¯ã‚»ã‚¹"
msgid "GitLabPages|Are you sure?"
-msgstr ""
+msgstr "よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
msgid "GitLabPages|Certificate: %{subject}"
msgstr ""
msgid "GitLabPages|Configure pages"
-msgstr ""
+msgstr "ページを設定"
msgid "GitLabPages|Domains"
-msgstr ""
+msgstr "ドメイン"
msgid "GitLabPages|Edit"
-msgstr ""
+msgstr "編集"
msgid "GitLabPages|Expired"
-msgstr ""
+msgstr "期é™åˆ‡ã‚Œ"
msgid "GitLabPages|Force HTTPS (requires valid certificates)"
-msgstr ""
+msgstr "HTTPSを強制 (有効ãªè¨¼æ˜Žæ›¸ãŒå¿…è¦)"
msgid "GitLabPages|GitLab Pages are disabled for this project. You can enable them on your project's %{strong_start}Settings > General > Visibility%{strong_end} page."
-msgstr ""
+msgstr "GitLab Pagesã¯ã“ã®ãƒ—ロジェクトã§ã¯ç„¡åŠ¹ã«ãªã£ã¦ã„ã¾ã™ã€‚ プロジェクトã®%{strong_start} 設定> 全般> å¯è¦–性%{strong_end}ページã§æœ‰åŠ¹ã«ã§ãã¾ã™ã€‚"
msgid "GitLabPages|It may take up to 30 minutes before the site is available after the first deployment."
msgstr "最åˆã®ãƒ‡ãƒ—ロイ後ã€ã‚µã‚¤ãƒˆãŒåˆ©ç”¨å¯èƒ½ã«ãªã‚‹ã¾ã§ã«æœ€å¤§ã§30分ã‹ã‹ã‚‹å ´åˆãŒã‚ã‚Šã¾ã™ã€‚"
msgid "GitLabPages|Learn how to upload your static site and have it served by GitLab by following the %{link_start}documentation on GitLab Pages%{link_end}."
-msgstr ""
+msgstr "é™çš„サイトをアップロードã—ã€GitLab ã§ãƒ›ã‚¹ãƒˆã™ã‚‹ã«ã¯ %{link_start} GitLab Pages ã®æ–‡æ›¸%{link_end} ã«å¾“ã£ã¦å­¦ã‚“ã§ãã ã•ã„。"
msgid "GitLabPages|Learn more."
-msgstr ""
+msgstr "詳ã—ã見る。"
msgid "GitLabPages|Maximum size of pages (MB)"
-msgstr ""
+msgstr "GitLabPagesã®ãƒšãƒ¼ã‚¸ã®æœ€å¤§ã‚µã‚¤ã‚ºï¼ˆMB)"
msgid "GitLabPages|New Domain"
-msgstr ""
+msgstr "新ドメイン"
msgid "GitLabPages|Only project maintainers can remove pages"
-msgstr ""
+msgstr "プロジェクトã®ãƒ¡ãƒ³ãƒ†ãƒŠãƒ¼ã ã‘ãŒãƒšãƒ¼ã‚¸ã‚’削除ã§ãã¾ã™"
msgid "GitLabPages|Pages"
-msgstr ""
+msgstr "ページ"
msgid "GitLabPages|Remove"
-msgstr ""
+msgstr "削除"
msgid "GitLabPages|Remove pages"
-msgstr ""
+msgstr "ページã®å‰Šé™¤"
msgid "GitLabPages|Removing pages will prevent them from being exposed to the outside world."
-msgstr ""
+msgstr "ページを削除ã™ã‚‹ã¨ã€ãƒšãƒ¼ã‚¸ãŒå¤–部ã«å…¬é–‹ã•ã‚Œãªããªã‚Šã¾ã™ã€‚"
msgid "GitLabPages|Save"
-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 ""
msgid "GitLabPages|Support for domains and certificates is disabled. Ask your system's administrator to enable it."
-msgstr ""
+msgstr "ドメインã¨è¨¼æ˜Žæ›¸ã®ã‚µãƒãƒ¼ãƒˆãŒç„¡åŠ¹ã§ã™ã€‚有効ã«ã™ã‚‹ã«ã¯ã‚·ã‚¹ãƒ†ãƒ ç®¡ç†è€…ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。"
msgid "GitLabPages|The total size of deployed static content will be limited to this size. 0 for unlimited. Leave empty to inherit the global value."
-msgstr ""
+msgstr "デプロイã—ãŸé™çš„コンテンツã®å…¨ã‚µã‚¤ã‚ºã¯ã“ã®ã‚µã‚¤ã‚ºä»¥ä¸‹ã«åˆ¶é™ã•ã‚Œã¾ã™ã€‚無制é™ã®å ´åˆã¯0を指定ã—ã¦ãã ã•ã„。グローãƒãƒ«å€¤ã‚’継承ã™ã‚‹å ´åˆã¯ç©ºã®ã¾ã¾ã«ã—ã¾ã™ã€‚"
msgid "GitLabPages|Unverified"
-msgstr ""
+msgstr "未確èª"
msgid "GitLabPages|Verified"
-msgstr ""
+msgstr "確èªæ¸ˆ"
msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with sub-subdomains. This means that if your username/groupname contains a dot it will not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages will continue to work provided you don't redirect HTTP to HTTPS."
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static websites on GitLab. Combined with the power of GitLab CI and the help of GitLab Runner you can deploy static pages for your individual projects, your user or your group."
-msgstr ""
+msgstr "GitLab Pagesを使用ã†ã¨ã€GitLab ã§é™çš„Webサイトをホストã§ãã¾ã™ã€‚ GitLab CIã®ãƒ‘ワーã¨GitLab Runner ã®ãƒ˜ãƒ«ãƒ—を組ã¿åˆã‚ã›ã¦ã€å€‹äººã®ãƒ—ロジェクトã€ã‚ãªãŸã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã€ã¾ãŸã¯ã‚°ãƒ«ãƒ¼ãƒ—ã®é™çš„ページをデプロイã§ãã¾ã™ã€‚"
msgid "GitLabPages|Your pages are served under:"
-msgstr ""
+msgstr "ã‚ãªãŸã®ãƒšãƒ¼ã‚¸ã¯ä»¥ä¸‹ã§æä¾›ã•ã‚Œã¾ã™ :"
msgid "Gitaly"
msgstr "Gitaly"
@@ -10088,20 +10543,17 @@ msgstr "Gitea ホスト㮠URL"
msgid "Gitea Import"
msgstr "Gitea インãƒãƒ¼ãƒˆ"
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
-msgstr ""
+msgstr "Gitlab Pages"
msgid "Given access %{time_ago}"
msgstr "%{time_ago} ã«ã‚¢ã‚¯ã‚»ã‚¹è¨±å¯"
msgid "Given epic is already related to this epic."
-msgstr ""
+msgstr "指定ã•ã‚ŒãŸã‚¨ãƒ”ックã¯ã™ã§ã«ã“ã®ã‚¨ãƒ”ックã¨é–¢é€£ã—ã¦ã„ã¾ã™ã€‚"
msgid "Global Shortcuts"
-msgstr ""
+msgstr "グローãƒãƒ« ショートカット"
msgid "Global notification settings"
msgstr "グローãƒãƒ«é€šçŸ¥è¨­å®š"
@@ -10116,17 +10568,14 @@ msgid "Go back"
msgstr "å‰ã«æˆ»ã‚‹"
msgid "Go back (while searching for files)"
-msgstr ""
+msgstr "戻る(ファイルã®æ¤œç´¢ä¸­)"
msgid "Go back to %{startTag}Open issues%{endTag} and select some issues to add to your board."
-msgstr ""
+msgstr "%{startTag} オープンãªèª²é¡Œ %{endTag} ã«æˆ»ã£ã¦ã€èª²é¡Œã‚’é¸æŠžã—ã¦ãƒœãƒ¼ãƒ‰ã«è¿½åŠ ã—ã¾ã™ã€‚"
msgid "Go full screen"
msgstr "全画é¢è¡¨ç¤º"
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr "%{link_to_google_takeout} ã«ç§»å‹•ã—ã¾ã™ã€‚"
@@ -10137,100 +10586,100 @@ msgid "Go to Webhooks"
msgstr ""
msgid "Go to commits"
-msgstr ""
+msgstr "コミットã¸ç§»å‹•"
msgid "Go to definition"
msgstr ""
msgid "Go to environments"
-msgstr ""
+msgstr "環境ã«ç§»å‹•ã™ã‚‹"
msgid "Go to file"
-msgstr ""
+msgstr "ファイルã«ç§»å‹•"
msgid "Go to file permalink (while viewing a file)"
-msgstr ""
+msgstr "ファイルパーマリンクã«ç§»å‹•ï¼ˆãƒ•ã‚¡ã‚¤ãƒ«è¡¨ç¤ºä¸­ï¼‰"
msgid "Go to files"
-msgstr ""
+msgstr "ファイルã«ç§»å‹•"
msgid "Go to find file"
-msgstr ""
+msgstr "ファイルã®æ¤œç´¢ã«ç§»å‹•"
msgid "Go to issue boards"
-msgstr ""
+msgstr "課題ボードã¸ç§»å‹•"
msgid "Go to issues"
-msgstr ""
+msgstr "課題ã¸ç§»å‹•"
msgid "Go to jobs"
-msgstr ""
+msgstr "ジョブã¸"
msgid "Go to kubernetes"
-msgstr ""
+msgstr "kubernetes ã¸"
msgid "Go to merge requests"
-msgstr ""
+msgstr "マージリクエストã¸ç§»å‹•"
msgid "Go to metrics"
-msgstr ""
+msgstr "メトリクスã¸"
msgid "Go to parent"
-msgstr ""
+msgstr "親ã«ç§»å‹•"
msgid "Go to project"
msgstr "プロジェクトã«ç§»å‹•"
msgid "Go to releases"
-msgstr ""
+msgstr "リリースã¸ç§»å‹•"
msgid "Go to repository charts"
-msgstr ""
+msgstr "リãƒã‚¸ãƒˆãƒªãƒãƒ£ãƒ¼ãƒˆã¸ç§»å‹•"
msgid "Go to repository graph"
-msgstr ""
+msgstr "リãƒã‚¸ãƒˆãƒªã‚°ãƒ©ãƒ•ã«ç§»å‹•"
msgid "Go to snippets"
-msgstr ""
+msgstr "スニペットã¸ç§»å‹•"
msgid "Go to the activity feed"
-msgstr ""
+msgstr "アクティビティーフィードã«ç§»å‹•"
msgid "Go to the milestone list"
-msgstr ""
+msgstr "マイルストーンã®ãƒªã‚¹ãƒˆã«ç§»å‹•"
msgid "Go to the project's activity feed"
-msgstr ""
+msgstr "プロジェクトã®ã‚¢ã‚¯ãƒ†ã‚£ãƒ“ティーフィードã«ç§»å‹•ã—ã¾ã™"
msgid "Go to the project's overview page"
-msgstr ""
+msgstr "プロジェクトã®æ¦‚è¦ãƒšãƒ¼ã‚¸ã¸ç§»å‹•"
msgid "Go to wiki"
-msgstr ""
+msgstr "Wiki ã«ç§»å‹•"
msgid "Go to your To-Do list"
-msgstr ""
+msgstr "To-Doリストã«ç§»å‹•"
msgid "Go to your fork"
msgstr "自分ã®ãƒ•ã‚©ãƒ¼ã‚¯ã¸ç§»å‹•"
msgid "Go to your groups"
-msgstr ""
+msgstr "ã‚ãªãŸã®ã‚°ãƒ«ãƒ¼ãƒ—ã¸ç§»å‹•"
msgid "Go to your issues"
-msgstr ""
+msgstr "ã‚ãªãŸã®èª²é¡Œã¸ç§»å‹•"
msgid "Go to your merge requests"
-msgstr ""
+msgstr "マージリクエストã¸ç§»å‹•"
msgid "Go to your projects"
-msgstr ""
+msgstr "ã‚ãªãŸã®ãƒ—ロジェクトã¸ç§»å‹•"
msgid "Go to your snippets"
-msgstr ""
+msgstr "ã‚ãªãŸã®ã‚¹ãƒ‹ãƒšãƒƒãƒˆã¸ç§»å‹•"
msgid "Golden Tanuki"
-msgstr ""
+msgstr "ゴールデンタヌキ"
msgid "Google Cloud Platform"
msgstr ""
@@ -10242,7 +10691,7 @@ msgid "Google Takeout"
msgstr "Google テイクアウト"
msgid "Google authentication is not %{link_start}properly configured%{link_end}. Ask your GitLab administrator if you want to use this service."
-msgstr ""
+msgstr "Google èªè¨¼ãŒ %{link_start} é©åˆ‡ã«è¨­å®šã•ã‚Œã¦ã„ã¾ã›ã‚“。%{link_end} ã“ã®ã‚µãƒ¼ãƒ“スを使用ã™ã‚‹ãªã‚‰ GitLab ã®ç®¡ç†è€…ã«å°‹ã­ã¦ãã ã•ã„。"
msgid "Got it"
msgstr ""
@@ -10251,16 +10700,16 @@ msgid "Got it!"
msgstr "入手ã—ã¾ã—ょã†ï¼"
msgid "Grafana URL"
-msgstr ""
+msgstr "Grafana ã® URL"
msgid "GrafanaIntegration|API Token"
msgstr "APIトークン"
msgid "GrafanaIntegration|Active"
-msgstr ""
+msgstr "アクティブ"
msgid "GrafanaIntegration|Embed Grafana charts in GitLab issues."
-msgstr ""
+msgstr "GitLab ã®èª²é¡Œã« Grafana ãƒãƒ£ãƒ¼ãƒˆã‚’埋ã‚è¾¼ã¿ã¾ã™ã€‚"
msgid "GrafanaIntegration|Enter the Grafana API Token."
msgstr "Grafana API トークンを入力。"
@@ -10281,7 +10730,7 @@ msgid "Graph"
msgstr "グラフ"
msgid "Gravatar"
-msgstr ""
+msgstr "Gravatar"
msgid "Gravatar enabled"
msgstr "Gravatar を有効化"
@@ -10289,12 +10738,21 @@ msgstr "Gravatar を有効化"
msgid "Group"
msgstr "グループ"
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr "グループ %{group_name} ã¯å‰Šé™¤äºˆå®šã—ã¾ã—ãŸã€‚"
msgid "Group %{group_name} was successfully created."
msgstr "'%{group_name}' グループã¯æ­£å¸¸ã«ä½œæˆã•ã‚Œã¾ã—ãŸã€‚"
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10314,7 +10772,7 @@ msgid "Group ID: %{group_id}"
msgstr "グループID:%{group_id}"
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
-msgstr ""
+msgstr "グループ管ç†ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’有効ã«ã™ã‚‹å‰ã«ã€ã‚°ãƒ«ãƒ¼ãƒ—所有者ãŒSAMLã§ã‚µã‚¤ãƒ³ã‚¤ãƒ³ã—ã¦ã„ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™"
msgid "Group Runners"
msgstr "グループ Runner"
@@ -10328,6 +10786,12 @@ msgstr "グループ URL"
msgid "Group avatar"
msgstr "グループアãƒã‚¿ãƒ¼"
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr "グループã®èª¬æ˜Ž"
@@ -10340,17 +10804,20 @@ msgstr "グループã®è©³ç´°"
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
-msgstr ""
+msgstr "グループã¯å‰Šé™¤å¯¾è±¡ã¨ã—ã¦ãƒžãƒ¼ã‚¯ãŒã¤ã„ã¦ã„ã¾ã™"
msgid "Group has not been marked for deletion"
-msgstr ""
+msgstr "グループã¯å‰Šé™¤å¯¾è±¡ã¨ã—ã¦ãƒžãƒ¼ã‚¯ãŒã¤ã„ã¦ã„ã¾ã›ã‚“"
msgid "Group info:"
msgstr "グループ情報:"
@@ -10359,33 +10826,42 @@ msgid "Group maintainers can register group runners in the %{link}"
msgstr "グループ Maintainer 㯠%{link} ã§ã‚°ãƒ«ãƒ¼ãƒ— Runner を登録ã§ãã¾ã™ã€‚"
msgid "Group members"
+msgstr "グループã®ãƒ¡ãƒ³ãƒãƒ¼"
+
+msgid "Group milestone"
msgstr ""
msgid "Group name"
msgstr "グループå"
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
-msgstr ""
+msgstr "グループã®æ¦‚è¦"
msgid "Group overview content"
msgstr "グループ概è¦ã‚³ãƒ³ãƒ†ãƒ³ãƒ„"
msgid "Group path is already taken. Suggestions: "
-msgstr ""
+msgstr "ãã®ã‚°ãƒ«ãƒ¼ãƒ—パスã¯æ—¢ã«ä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™ã€‚ã“ã¡ã‚‰ã‚’æ案ã—ã¾ã™ã€‚: "
msgid "Group path is available."
-msgstr ""
+msgstr "ãã®ã‚°ãƒ«ãƒ¼ãƒ—パスã¯åˆ©ç”¨å¯èƒ½ã§ã™ã€‚"
msgid "Group pipeline minutes were successfully reset."
+msgstr "グループã®ãƒ‘イプライン時間ãŒæ­£å¸¸ã«ãƒªã‚»ãƒƒãƒˆã•ã‚Œã¾ã—ãŸã€‚"
+
+msgid "Group project URLs are prefixed with the group namespace"
msgstr ""
msgid "Group requires separate account"
-msgstr ""
+msgstr "グループã«ã¯åˆ¥ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒå¿…è¦ã§ã™"
msgid "Group variables (inherited)"
+msgstr "グループ変数(継承)"
+
+msgid "Group was exported"
msgstr ""
msgid "Group was successfully updated."
@@ -10395,10 +10871,10 @@ msgid "Group: %{group_name}"
msgstr "グループ:%{group_name}"
msgid "Group: %{name}"
-msgstr ""
+msgstr "グループ: %{name}"
msgid "GroupActivityMetrics|New Members created"
-msgstr ""
+msgstr "æ–°ã—ã作æˆã•ã‚ŒãŸãƒ¡ãƒ³ãƒãƒ¼"
msgid "GroupActivyMetrics|Issues created"
msgstr ""
@@ -10443,10 +10919,10 @@ msgid "GroupSAML|Certificate fingerprint"
msgstr "証明書ã®ãƒ•ã‚£ãƒ³ã‚¬ãƒ¼ãƒ—リント"
msgid "GroupSAML|Configuration"
-msgstr ""
+msgstr "設定"
msgid "GroupSAML|Copy SAML Response XML"
-msgstr ""
+msgstr "SAMLレスãƒãƒ³ã‚¹XMLã®ã‚³ãƒ”ー"
msgid "GroupSAML|Enable SAML authentication for this group."
msgstr "ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã® SAML èªè¨¼ã‚’有効ã«ã™ã‚‹."
@@ -10454,9 +10930,6 @@ msgstr "ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã® SAML èªè¨¼ã‚’有効ã«ã™ã‚‹."
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr "ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«SSOã®ã¿ã®èªè¨¼ã‚’強制ã™ã‚‹."
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr "ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—専用ã®ã‚°ãƒ«ãƒ¼ãƒ—管ç†ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’ユーザーã«è¨­å®šã™ã‚‹ã€‚"
@@ -10470,7 +10943,7 @@ msgid "GroupSAML|Generate a SCIM token to set up your System for Cross-Domain Id
msgstr "クロスドメインã®ID管ç†ç”¨ã«ã‚·ã‚¹ãƒ†ãƒ ã‚’設定ã™ã‚‹ãŸã‚ã®SCIMトークンを生æˆã—ã¾ã™ã€‚"
msgid "GroupSAML|Identity"
-msgstr ""
+msgstr "識別å­"
msgid "GroupSAML|Identity provider single sign on URL"
msgstr "アイデンティティプロãƒã‚¤ãƒ€ã®ã‚·ãƒ³ã‚°ãƒ«ã‚µã‚¤ãƒ³ã‚ªãƒ³ URL"
@@ -10482,16 +10955,16 @@ msgid "GroupSAML|Manage your group’s membership while adding another level of
msgstr "グループã®ãƒ¡ãƒ³ãƒãƒ¼ã‚·ãƒƒãƒ—を管ç†ã—ãªãŒã‚‰ã€SAML ã§åˆ¥ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ãƒ¬ãƒ™ãƒ«ã‚’追加ã—ã¾ã™ã€‚"
msgid "GroupSAML|Members"
-msgstr ""
+msgstr "メンãƒãƒ¼"
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 "メンãƒãƒ¼ãŒã‚°ãƒ«ãƒ¼ãƒ—ã«ã‚µã‚¤ãƒ³ã‚¤ãƒ³ã™ã‚‹ã¨ã€ã“ã“ã«ãƒ•ã‚©ãƒ¯ãƒ¼ãƒ‰ã•ã‚Œã¾ã™ã€‚ã“ã‚Œã¯IDプロãƒã‚¤ãƒ€ãƒ¼ã‹ã‚‰å–å¾—ã§ãã¾ã™ã€‚IDプロãƒã‚¤ãƒ€ãƒ¼ã¯\"SSO Service Location\"ã€\"SAML Token Issuance Endpoint\"ã€\"SAML 2.0/W-Federation URL\"ãªã©ã¨ã‚‚呼ã°ã‚Œã¾ã™ã€‚"
msgid "GroupSAML|NameID"
-msgstr ""
+msgstr "NameID"
msgid "GroupSAML|NameID Format"
-msgstr ""
+msgstr "NameID ã®å½¢å¼"
msgid "GroupSAML|Prohibit outer forks"
msgstr ""
@@ -10500,10 +10973,10 @@ msgid "GroupSAML|Prohibit outer forks for this group."
msgstr ""
msgid "GroupSAML|SAML Response Output"
-msgstr ""
+msgstr "SAMLレスãƒãƒ³ã‚¹å‡ºåŠ›"
msgid "GroupSAML|SAML Response XML"
-msgstr ""
+msgstr "SAMLレスãƒãƒ³ã‚¹XML"
msgid "GroupSAML|SAML Single Sign On"
msgstr "SAML シングルサインオン"
@@ -10536,7 +11009,7 @@ msgid "GroupSAML|Toggle SAML authentication"
msgstr "SAMLèªè¨¼ã‚’切り替ãˆ"
msgid "GroupSAML|Valid SAML Response"
-msgstr ""
+msgstr "妥当ãªSAMLレスãƒãƒ³ã‚¹"
msgid "GroupSAML|With group managed accounts enabled, all the users without a group managed account will be excluded from the group."
msgstr "グループ管ç†ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’有効ã«ã™ã‚‹ã¨ã€ã‚°ãƒ«ãƒ¼ãƒ—管ç†ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’æŒãŸãªã„ã™ã¹ã¦ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã‹ã‚‰é™¤å¤–ã•ã‚Œã¾ã™ã€‚"
@@ -10554,28 +11027,28 @@ msgid "GroupSAML|should be \"persistent\""
msgstr ""
msgid "GroupSAML|should be a random persistent ID, emails are discouraged"
-msgstr ""
+msgstr "ランダムãªæ°¸ç¶šçš„IDã§ã‚ã‚‹å¿…è¦ãŒã‚ã‚Šã€ãƒ¡ãƒ¼ãƒ«ã¯æŽ¨å¥¨ã•ã‚Œã¾ã›ã‚“"
msgid "GroupSettings|Apply integration settings to all Projects"
msgstr ""
msgid "GroupSettings|Auto DevOps pipeline was updated for the group"
-msgstr ""
+msgstr "Auto DevOps パイプラインãŒã‚°ãƒ«ãƒ¼ãƒ—用ã«æ›´æ–°ã•ã‚Œã¾ã—ãŸ"
msgid "GroupSettings|Badges"
msgstr "ãƒãƒƒã‚¸"
msgid "GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}."
-msgstr ""
+msgstr "注æ„ã—ã¦ãã ã•ã„。グループã®è¦ªã‚’変更ã™ã‚‹ã¨ã€æ„図ã—ã¦ã„ãªã‹ã£ãŸ %{side_effects_link_start} 副作用 %{side_effects_link_end}ãŒç™ºç”Ÿã™ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "GroupSettings|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 ""
+msgstr "コンテナレジストリã«Dockerイメージをå«ã‚€ãƒ—ロジェクトãŒã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã®ä¸‹ã«ã‚ã‚‹ãŸã‚ã€ãƒ‘スを更新ã§ãã¾ã›ã‚“。 最åˆã«ãƒ—ロジェクトã‹ã‚‰ã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’削除ã—ã¦ã€ã‚‚ã†ä¸€åº¦è©¦ã—ã¦ãã ã•ã„。"
msgid "GroupSettings|Change group path"
-msgstr ""
+msgstr "グループã®ãƒ‘スã®å¤‰æ›´"
msgid "GroupSettings|Changing group path can have unintended side effects."
-msgstr ""
+msgstr "グループã®ãƒ‘スを変更ã™ã‚‹ã¨ã€æ„図ã—ãªã„副作用ãŒç™ºç”Ÿã™ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "GroupSettings|Custom project templates"
msgstr "カスタムプロジェクトテンプレート"
@@ -10584,19 +11057,19 @@ msgid "GroupSettings|Customize your group badges."
msgstr "グループãƒãƒƒã‚¸ã®ã‚«ã‚¹ã‚¿ãƒžã‚¤ã‚º"
msgid "GroupSettings|Default to Auto DevOps pipeline for all projects within this group"
-msgstr ""
+msgstr "ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—内ã®ã™ã¹ã¦ã®ãƒ—ロジェクトã«å¯¾ã—ã¦ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã® Auto DevOps パイプライン"
msgid "GroupSettings|Disable email notifications"
-msgstr ""
+msgstr "メール通知を無効ã«ã™ã‚‹"
msgid "GroupSettings|Disable group mentions"
-msgstr ""
+msgstr "グループã®ãƒ¡ãƒ³ã‚·ãƒ§ãƒ³ã‚’無効ã«ã™ã‚‹"
msgid "GroupSettings|Export group"
msgstr ""
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 ""
+msgstr "親グループã®å¯è¦–性ãŒã‚°ãƒ«ãƒ¼ãƒ—ã®ç¾åœ¨ã®å¯è¦–性より低ã„å ´åˆã€ã‚µãƒ–グループã¨ãƒ—ロジェクトã®å¯è¦–性レベルã¯ã€æ–°ã—ã„親グループã®å¯è¦–性ã«ä¸€è‡´ã™ã‚‹ã‚ˆã†ã«å¤‰æ›´ã•ã‚Œã¾ã™ã€‚"
msgid "GroupSettings|Integrations configured here will automatically apply to all projects in this group."
msgstr ""
@@ -10605,16 +11078,16 @@ msgid "GroupSettings|Learn more about badges."
msgstr "ãƒãƒƒã‚¸ã®è©³ç´°ã€‚"
msgid "GroupSettings|Learn more about group-level project templates."
-msgstr ""
+msgstr "グループレベルã®ãƒ—ロジェクトテンプレートã®è©³ç´°."
msgid "GroupSettings|New runners registration token has been generated!"
-msgstr ""
+msgstr "æ–°ã—ã„ランナー登録トークンを生æˆã—ã¾ã—ãŸï¼"
msgid "GroupSettings|Pipeline settings was updated for the group"
-msgstr ""
+msgstr "グループã®ãƒ‘イプライン設定ãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸ"
msgid "GroupSettings|Please choose a group path with no special characters."
-msgstr ""
+msgstr "特殊文字ã®ãªã„グループパスをé¸æŠžã—ã¦ãã ã•ã„。"
msgid "GroupSettings|Prevent sharing a project within %{group} with other groups"
msgstr "%{group} 内ã®ãƒ—ロジェクトを他ã®ã‚°ãƒ«ãƒ¼ãƒ—ã¨å…±æœ‰ã—ãªã„よã†ã«ã™ã‚‹"
@@ -10629,7 +11102,7 @@ msgid "GroupSettings|There was a problem updating Auto DevOps pipeline: %{error_
msgstr "Auto DevOps パイプラインã®æ›´æ–°ä¸­ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸï¼š %{error_messages} 。"
msgid "GroupSettings|There was a problem updating the pipeline settings: %{error_messages}."
-msgstr ""
+msgstr "パイプライン設定ã®æ›´æ–°ä¸­ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸï¼š %{error_messages} 。"
msgid "GroupSettings|This setting is applied on %{ancestor_group} and has been overridden on this subgroup."
msgstr "ã“ã®è¨­å®šã¯ %{ancestor_group} ã«é©ç”¨ã•ã‚Œã€ã‚µãƒ–グループã§ä¸Šæ›¸ãã•ã‚Œã¾ã™ã€‚"
@@ -10644,25 +11117,28 @@ msgid "GroupSettings|This setting will be applied to all subgroups unless overri
msgstr "ã“ã®è¨­å®šã¯ã‚°ãƒ«ãƒ¼ãƒ—オーナーã«ã‚ˆã£ã¦ä¸Šæ›¸ãã•ã‚Œãªã„é™ã‚Šã€ã™ã¹ã¦ã®ã‚µãƒ–グループã«é©ç”¨ã•ã‚Œã¾ã™ã€‚プロジェクトã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ—¢ã«ã‚るグループã¯ã€æ‰‹å‹•ã§å‰Šé™¤ã—ãªã„é™ã‚Šå¼•ã続ãアクセスã§ãã¾ã™ã€‚"
msgid "GroupSettings|This setting will override user notification preferences for all members of the group, subgroups, and projects."
-msgstr ""
+msgstr "ã“ã®è¨­å®šã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—ã€ã‚µãƒ–グループã€ãŠã‚ˆã³ãƒ—ロジェクトã®ã™ã¹ã¦ã®ãƒ¡ãƒ³ãƒãƒ¼ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼é€šçŸ¥è¨­å®šã‚’上書ãã—ã¾ã™ã€‚"
msgid "GroupSettings|This setting will prevent group members from being notified if the group is mentioned."
-msgstr ""
+msgstr "ã“ã‚Œã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—ãŒè¨€åŠã•ã‚ŒãŸå ´åˆã«ã‚°ãƒ«ãƒ¼ãƒ—メンãƒãƒ¼ã«é€šçŸ¥ã—ãªã„よã†ã«è¨­å®šã—ã¾ã™ã€‚"
msgid "GroupSettings|Transfer group"
-msgstr ""
+msgstr "グループã®è»¢é€"
msgid "GroupSettings|You can only transfer the group to a group you manage."
-msgstr ""
+msgstr "ã‚ãªãŸãŒç®¡ç†ã§ãるグループã«ã®ã¿ã€ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—を転é€ã§ãã¾ã™ã€‚"
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
+msgstr "ローカルリãƒã‚¸ãƒˆãƒªãŒæ–°ã—ã„場所を示ã™ã‚ˆã†ã«æ›´æ–°ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
+
+msgid "GroupSettings|cannot be changed by you"
msgstr ""
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr "親グループã®ã€Œã‚°ãƒ«ãƒ¼ãƒ—ã¨ã®ãƒ­ãƒƒã‚¯ã‚’共有ã€ãŒæœ‰åŠ¹ã«ãªã£ã¦ã„ã‚‹å ´åˆã€è¦ªã‚°ãƒ«ãƒ¼ãƒ—ã®ã‚ªãƒ¼ãƒŠãƒ¼ä»¥å¤–ã¯ç„¡åŠ¹ã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。"
msgid "GroupSettings|cannot change when group contains projects with NPM packages"
-msgstr ""
+msgstr "グループã«NPMパッケージをå«ã‚€ãƒ—ロジェクトãŒå«ã¾ã‚Œã‚‹å ´åˆã¯å¤‰æ›´ã§ãã¾ã›ã‚“"
msgid "GroupSettings|remove the share with group lock from %{ancestor_group_name}"
msgstr "グループã®ãƒ­ãƒƒã‚¯ã‚’ %{ancestor_group_name} ã®å…±æœ‰ã‹ã‚‰å‰Šé™¤"
@@ -10683,7 +11159,7 @@ msgid "Groups to synchronize"
msgstr ""
msgid "Groups with access to %{strong_start}%{group_name}%{strong_end}"
-msgstr ""
+msgstr "%{strong_start}%{group_name}%{strong_end} ã¸ã‚¢ã‚¯ã‚»ã‚¹ã§ãるグループ"
msgid "Groups with access to <strong>%{project_name}</strong>"
msgstr "<strong>%{project_name}</strong>ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹æ¨©ã‚’æŒã¤ã‚°ãƒ«ãƒ¼ãƒ—"
@@ -10752,7 +11228,7 @@ msgid "GroupsTree|Search by name"
msgstr "åå‰ã§æ¤œç´¢"
msgid "Guideline"
-msgstr ""
+msgstr "ガイドライン"
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 Git over HTTPã«ã¯ 'api' スコープã®ãƒ‘ーソナルアクセストークンを使用ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚\\n %{profile_personal_access_tokens_url} ã§ç”Ÿæˆã§ãã¾ã™"
@@ -10761,6 +11237,9 @@ msgid "Hashed Storage must be enabled to use Geo"
msgstr ""
msgid "Hashed repository storage paths"
+msgstr "リãƒã‚¸ãƒˆãƒªã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ãƒ‘スã®ãƒãƒƒã‚·ãƒ¥"
+
+msgid "Hashed storage can't be disabled anymore for new projects"
msgstr ""
msgid "Have your users email"
@@ -10772,6 +11251,9 @@ msgstr "ヘッダーロゴã¯æ­£å¸¸ã«å‰Šé™¤ã—ã¾ã—ãŸã€‚"
msgid "Header message"
msgstr "ヘッダーメッセージ"
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10806,22 +11288,22 @@ msgid "Help page text and support page url."
msgstr "ヘルプページテキストã¨ã‚µãƒãƒ¼ãƒˆãƒšãƒ¼ã‚¸URL。"
msgid "Helps prevent bots from brute-force attacks."
-msgstr ""
+msgstr "ボットãŒãƒ–ルートフォース攻撃を防ãã®ã«å½¹ç«‹ã¡ã¾ã™ã€‚"
msgid "Helps prevent bots from creating accounts."
-msgstr ""
+msgstr "ボットãŒã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’作æˆã§ããªã„よã†ã«ã—ã¾ã™ã€‚"
msgid "Helps reduce alert volume (e.g. if creating too many issues)"
-msgstr ""
+msgstr "アラートã®é‡ã‚’減らã™ã®ã«å½¹ç«‹ã¡ã¾ã™(例:作æˆã™ã‚‹èª²é¡ŒãŒå¤šã™ãŽã‚‹å ´åˆ)"
msgid "Helps reduce request volume for protected paths"
-msgstr ""
+msgstr "ä¿è­·ã•ã‚ŒãŸãƒ‘スã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆé‡ã‚’減らã™ã®ã«å½¹ç«‹ã¡ã¾ã™"
msgid "Here you will find recent merge request activity"
msgstr ""
msgid "Hi %{username}!"
-msgstr ""
+msgstr "よã†ã“ã%{username}!"
msgid "Hide archived projects"
msgstr "アーカイブã—ãŸãƒ—ロジェクトをéžè¡¨ç¤ºã«"
@@ -10849,7 +11331,7 @@ msgid "Hide shared projects"
msgstr "共有プロジェクトをéžè¡¨ç¤ºã«"
msgid "Hide stage"
-msgstr ""
+msgstr "ステージをéžè¡¨ç¤º"
msgid "Hide value"
msgid_plural "Hide values"
@@ -10859,13 +11341,13 @@ msgid "Hide values"
msgstr "éžè¡¨ç¤º"
msgid "Hiding all labels"
-msgstr ""
+msgstr "ã™ã¹ã¦ã®ãƒ©ãƒ™ãƒ«ã‚’éš ã™"
msgid "High or unknown vulnerabilities present"
msgstr ""
msgid "Highest number of requests per minute for each raw path, default to 300. To disable throttling set to 0."
-msgstr ""
+msgstr "å„rawパスã®1分ã‚ãŸã‚Šã®æœ€å¤§ãƒªã‚¯ã‚¨ã‚¹ãƒˆæ•°ã€‚デフォルトã¯300ã§ã™ã€‚スロットルを無効ã«ã™ã‚‹ã«ã¯0ã«è¨­å®šã—ã¾ã™ã€‚"
msgid "Highest role:"
msgstr "最高ä½:"
@@ -10876,15 +11358,21 @@ msgstr "履歴"
msgid "History of authentications"
msgstr "èªè¨¼å±¥æ­´"
-msgid "Hook execution failed. Ensure the group has a project with commits."
+msgid "Homepage"
msgstr ""
+msgid "Hook execution failed. Ensure the group has a project with commits."
+msgstr "フックã®å®Ÿè¡Œã«å¤±æ•—ã—ã¾ã—ãŸã€‚グループã«ã‚³ãƒŸãƒƒãƒˆã®ã‚るプロジェクトãŒã‚ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。"
+
msgid "Hook was successfully created."
msgstr "フックã¯æ­£å¸¸ã«ä½œæˆã•ã‚Œã¾ã—ãŸã€‚"
msgid "Hook was successfully updated."
msgstr "フックã¯æ­£å¸¸ã«æ›´æ–°ã—ã¾ã—ãŸã€‚"
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -10898,7 +11386,7 @@ msgid "Housekeeping, export, path, transfer, remove, archive."
msgstr "ãƒã‚¦ã‚¹ã‚­ãƒ¼ãƒ”ングã€ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã€ãƒ‘スã€è»¢é€ã€å‰Šé™¤ã€ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–。"
msgid "How it works"
-msgstr ""
+msgstr "仕組ã¿"
msgid "How many days need to pass between marking entity for deletion and actual removing it."
msgstr ""
@@ -10910,13 +11398,13 @@ msgid "How many shards to split the Elasticsearch index over."
msgstr "Elasticseachã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚’分割ã™ã‚‹ã‚·ãƒ£ãƒ¼ãƒ‰æ•°"
msgid "How many users will be evaluating the trial?"
-msgstr ""
+msgstr "トライアルを評価ã™ã‚‹ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ä½•äººã§ã™ã‹ï¼Ÿ"
msgid "However, you are already a member of this %{member_source}. Sign in using a different account to accept the invitation."
msgstr "ã—ã‹ã—ã€ã‚ãªãŸã¯ã™ã§ã«ã“ã® %{member_source} ã®ãƒ¡ãƒ³ãƒãƒ¼ã§ã™ã€‚招待をå—ã‘入れるã«ã¯ã€åˆ¥ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’使用ã—ã¦ã‚µã‚¤ãƒ³ã‚¤ãƒ³ã—ã¦ãã ã•ã„。"
msgid "I accept the %{terms_link_start}Terms of Service and Privacy Policy%{terms_link_end}"
-msgstr ""
+msgstr "%{terms_link_start} 利用è¦ç´„ã¨ãƒ—ライãƒã‚·ãƒ¼ãƒãƒªã‚·ãƒ¼ %{terms_link_end} ã«åŒæ„ã—ã¾ã™ã€‚"
msgid "I accept the %{terms_link}"
msgstr "%{terms_link} ã«åŒæ„ã™ã‚‹"
@@ -10928,16 +11416,16 @@ msgid "I forgot my password"
msgstr "パスワードを忘れã¾ã—ãŸ"
msgid "I have read and agree to the Let's Encrypt %{link_start}Terms of Service%{link_end} (PDF)"
-msgstr ""
+msgstr "Let's Encryptã® %{link_start} 利用è¦ç´„ %{link_end} (PDF) を読ã¿ã€åŒæ„ã—ã¾ã—ãŸã€‚"
msgid "I'd like to receive updates via email about GitLab"
-msgstr ""
+msgstr "GitLabã«ã¤ã„ã¦ã®æœ€æ–°æƒ…報をメールã§å—ã‘å–ã‚ŠãŸã„"
msgid "ID"
msgstr "ID"
msgid "ID:"
-msgstr ""
+msgstr "ID:"
msgid "IDE|Allow live previews of JavaScript projects in the Web IDE using CodeSandbox Live Preview."
msgstr ""
@@ -10973,7 +11461,7 @@ msgid "IDE|Review"
msgstr "レビュー"
msgid "IDE|Successful commit"
-msgstr ""
+msgstr "コミットã«æˆåŠŸ"
msgid "IDE|This option is disabled because you are not allowed to create merge requests in this project."
msgstr ""
@@ -10991,13 +11479,13 @@ msgid "IP Address"
msgstr "IP アドレス"
msgid "IP subnet restriction only allowed for top-level groups"
-msgstr ""
+msgstr "IPサブãƒãƒƒãƒˆåˆ¶é™ã¯æœ€ä¸Šä½ã‚°ãƒ«ãƒ¼ãƒ—ã«ã®ã¿è¨±å¯ã•ã‚Œã¾ã™"
msgid "Identifier"
msgstr "識別å­"
msgid "Identifiers"
-msgstr ""
+msgstr "識別å­"
msgid "Identities"
msgstr "ID"
@@ -11006,22 +11494,22 @@ msgid "If any indexed field exceeds this limit it will be truncated to this numb
msgstr ""
msgid "If any job surpasses this timeout threshold, it will be marked as failed. Human readable time input language is accepted like \"1 hour\". Values without specification represent seconds."
-msgstr ""
+msgstr "ã„ãšã‚Œã‹ã®ã‚¸ãƒ§ãƒ–ãŒã“ã®ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆé–¾å€¤ã‚’超ãˆã‚‹ã¨ã€å¤±æ•—ã¨ã—ã¦ãƒžãƒ¼ã‚¯ã—ã¾ã™ã€‚人間ãŒèª­ã‚る時間ã¨ã—ã¦\"1 hour\"ã®ã‚ˆã†ã«å…¥åŠ›ã§ãã¾ã™ã€‚å˜ä½æŒ‡å®šãªã—ã®å€¤ã¯ç§’ã¨ã—ã¦æ‰±ã„ã¾ã™ã€‚"
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 ""
msgid "If checked, group owners can manage LDAP group links and LDAP member overrides"
-msgstr ""
+msgstr "ãƒã‚§ãƒƒã‚¯ã™ã‚‹ã¨ã€ã‚°ãƒ«ãƒ¼ãƒ—オーナー㯠LDAP グループリンク㨠LDAP メンãƒãƒ¼ã®ã‚ªãƒ¼ãƒãƒ¼ãƒ©ã‚¤ãƒ‰ã‚’管ç†ã§ãã¾ã™ã€‚"
msgid "If checked, new group memberships and permissions can only be added via LDAP synchronization"
-msgstr ""
+msgstr "ãƒã‚§ãƒƒã‚¯ã—ãŸå ´åˆã€æ–°ã—ã„グループメンãƒãƒ¼ã‚·ãƒƒãƒ—ã¨ãƒ‘ーミッションをLDAPåŒæœŸã‚’使用ã—ãŸå ´åˆã ã‘追加ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚"
msgid "If disabled, a diverged local branch will not be automatically updated with commits from its remote counterpart, to prevent local data loss. If the default branch (%{default_branch}) has diverged and cannot be updated, mirroring will fail. Other diverged branches are silently ignored."
-msgstr ""
+msgstr "無効ã«ã™ã‚‹ã¨ã€åˆ†å²ã—ãŸãƒ­ãƒ¼ã‚«ãƒ«ãƒ–ランãƒã¯ã€ãƒ­ãƒ¼ã‚«ãƒ«ã®ãƒ‡ãƒ¼ã‚¿æ失を防ããŸã‚ã«ã€ãƒªãƒ¢ãƒ¼ãƒˆã®å¯¾å¿œã™ã‚‹ãƒ–ランãƒã‹ã‚‰ã®ã‚³ãƒŸãƒƒãƒˆã§è‡ªå‹•çš„ã«æ›´æ–°ã•ã‚Œã¾ã›ã‚“。デフォルトã®ãƒ–ランム(%{default_branch}) ãŒåˆ†å²ã—ã¦æ›´æ–°ã§ããªã„å ´åˆã€ãƒŸãƒ©ãƒ¼ãƒªãƒ³ã‚°ã¯å¤±æ•—ã—ã¾ã™ã€‚ä»–ã®åˆ†ã‹ã‚ŒãŸãƒ–ランãƒã¯ãã®ã¾ã¾ç„¡è¦–ã•ã‚Œã¾ã™ã€‚"
msgid "If disabled, only admins will be able to configure repository mirroring."
-msgstr ""
+msgstr "無効ã«ã™ã‚‹ã¨ã€ç®¡ç†è€…ã®ã¿ãŒãƒªãƒã‚¸ãƒˆãƒªãƒŸãƒ©ãƒ¼ãƒªãƒ³ã‚°ã‚’設定ã§ãã¾ã™ã€‚"
msgid "If disabled, the access level will depend on the user's permissions in the project."
msgstr "無効ã«ã™ã‚‹ã¨ã€ã‚¢ã‚¯ã‚»ã‚¹ãƒ¬ãƒ™ãƒ«ã¯ãã®ãƒ—ロジェクトã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®æ¨©é™ã«ä¾å­˜ã—ã¾ã™ã€‚"
@@ -11035,16 +11523,22 @@ msgstr "有効ã«è¨­å®šã—ãŸå ´åˆã€å¤–部サービスã‹ã‚‰ãƒ—ロジェクト
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
-msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
msgstr ""
+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} ã§ãã¾ã™ã€‚"
+
msgid "If this was a mistake you can leave the %{source_type}."
msgstr "ã“ã‚ŒãŒé–“é•ã„ã ã£ãŸå ´åˆã¯ %{source_type} ã‚’ãã®ã¾ã¾ã«ã§ãã¾ã™ã€‚"
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr "GitHub を使用ã—ã¦ã„ã‚‹å ´åˆã€GitHub 上ã®ã‚³ãƒŸãƒƒãƒˆã‚„プルリクエストã‹ã‚‰ãƒ‘イプラインã®çŠ¶æ…‹ã‚’確èªã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚%{more_info_link}"
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11053,19 +11547,28 @@ msgstr "リカãƒãƒªãƒ¼ã‚³ãƒ¼ãƒ‰ã‚’紛失ã—ãŸå ´åˆã¯ã€æ–°ã—ã„リカãƒãƒª
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
-msgid "If your HTTP repository is not publicly accessible, add your credentials."
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
msgstr ""
-msgid "Iglu registry URL (optional)"
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
msgstr ""
+msgid "If your HTTP repository is not publicly accessible, add your credentials."
+msgstr "HTTPリãƒã‚¸ãƒˆãƒªã®ã‚¢ã‚¯ã‚»ã‚¹ãŒåˆ¶é™ã•ã‚Œã¦ã„ã‚‹å ´åˆã€èªè¨¼æƒ…報を追加ã—ã¦ãã ã•ã„。"
+
+msgid "Iglu registry URL (optional)"
+msgstr "IgluレジストリーURL(オプション)"
+
msgid "Ignore"
-msgstr ""
+msgstr "無視ã™ã‚‹"
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11078,20 +11581,20 @@ msgid "ImageDiffViewer|Swipe"
msgstr "スワイプ"
msgid "ImageViewerDimensions|H"
-msgstr ""
+msgstr "高ã•"
msgid "ImageViewerDimensions|W"
+msgstr "å¹…"
+
+msgid "Impersonation Tokens"
msgstr ""
msgid "Impersonation has been disabled"
-msgstr ""
+msgstr "代ç†ã¯ç„¡åŠ¹ã«ãªã£ã¦ã„ã¾ã™"
msgid "Import"
msgstr "インãƒãƒ¼ãƒˆ"
-msgid "Import %{status}"
-msgstr ""
-
msgid "Import CSV"
msgstr "CSV ã®å–ã‚Šè¾¼ã¿"
@@ -11101,6 +11604,9 @@ msgstr "Gitea ã‹ã‚‰ãƒ—ロジェクトã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆ"
msgid "Import all compatible projects"
msgstr "å…¨ã¦ã®äº’æ›æ€§ã®ã‚るプロジェクトã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆ"
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr "全プロジェクトã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆ"
@@ -11110,6 +11616,9 @@ msgstr "ã™ã¹ã¦ã®ãƒªãƒã‚¸ãƒˆãƒªã‚’インãƒãƒ¼ãƒˆ"
msgid "Import an exported GitLab project"
msgstr "エクスãƒãƒ¼ãƒˆã—㟠GItLab プロジェクトã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆ"
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11119,12 +11628,12 @@ msgstr ""
msgid "Import in progress"
msgstr "インãƒãƒ¼ãƒˆä¸­ã§ã™"
+msgid "Import in progress. Refresh page to see newly added issues."
+msgstr ""
+
msgid "Import issues"
msgstr "課題ã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆ"
-msgid "Import issues from Jira"
-msgstr ""
-
msgid "Import members"
msgstr "メンãƒãƒ¼ã‚’インãƒãƒ¼ãƒˆ"
@@ -11215,12 +11724,12 @@ msgstr "GitLab エンタープライズエディションを使用ã™ã‚‹ã¨ã€èª
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr "GitLab エンタープライズエディションã§ã¯ã€ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã¨ã‚«ã‚¹ã‚¿ãƒžãƒ¼ã‚µãƒãƒ¼ãƒˆã‚’改善"
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
-msgstr "GitLab エンタープライズエディションを使用ã™ã‚‹ã¨ã€èª²é¡Œç®¡ç†æ©Ÿèƒ½ãŒå¼·åŒ–ã•ã‚Œã€èª²é¡Œã«ã‚¦ã‚§ã‚¤ãƒˆã‚’設定ã§ãã¾ã™ã€‚"
-
msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr "GitLab エンタープライズエディションを使用ã™ã‚‹ã¨ã€æ¤œç´¢æ©Ÿèƒ½ãŒå¼·åŒ–ã•ã‚Œã€é«˜åº¦ãªã‚°ãƒ­ãƒ¼ãƒãƒ«æ¤œç´¢ãŒå¯èƒ½ã«ãªã‚Šã¾ã™ã€‚"
+msgid "In %{time_to_now}"
+msgstr ""
+
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
msgstr "インスタンスレベルã®åˆ†æžã‚’å¯èƒ½ã«ã™ã‚‹ãŸã‚ã«ã€æœ‰åŠ¹ã«ã™ã‚‹ãŸã‚ã«ç®¡ç†è€…ã«ä¾é ¼ã—ã¦ãã ã•ã„ %{usage_ping_link_start}ping ã®ä½¿ç”¨%{usage_ping_link_end}。"
@@ -11231,7 +11740,7 @@ msgid "In order to personalize your experience with GitLab<br>we would like to k
msgstr ""
msgid "In order to tailor your experience with GitLab we<br>would like to know a bit more about you."
-msgstr ""
+msgstr "GitLabã§ã®çµŒé¨“を調整ã™ã‚‹ãŸã‚ã«ã€<br>ã‚‚ã†å°‘ã—ã‚ãªãŸã«ã¤ã„ã¦çŸ¥ã‚ŠãŸã„ã§ã™ã€‚"
msgid "In progress"
msgstr ""
@@ -11240,7 +11749,7 @@ msgid "In the next step, you'll be able to select the projects you want to impor
msgstr "次ã®ã‚¹ãƒ†ãƒƒãƒ—ã§ã¯ã€ã‚¤ãƒ³ãƒãƒ¼ãƒˆã™ã‚‹ãƒ—ロジェクトをé¸æŠžã—ã¾ã™ã€‚"
msgid "Incident Management Limits"
-msgstr ""
+msgstr "インシデント管ç†åˆ¶é™"
msgid "Incidents"
msgstr "インシデント"
@@ -11251,6 +11760,9 @@ msgstr "ã™ã¹ã¦ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒåŒæ„ã—ãªã‘ã‚Œã°ãªã‚‰ãªã„利用è¦ç´„
msgid "Include author name in notification email body"
msgstr "通知メールã®æœ¬æ–‡ã«ä½œæˆè€…ã®åå‰ã‚’å«ã‚ã‚‹"
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr "マージリクエストã®èª¬æ˜Žã‚’å«ã‚ã‚‹"
@@ -11273,7 +11785,7 @@ msgid "Includes repository storage, wiki storage, LFS objects, build artifacts a
msgstr ""
msgid "Incoming email"
-msgstr ""
+msgstr "å—信メール"
msgid "Incoming!"
msgstr ""
@@ -11284,9 +11796,15 @@ msgstr "互æ›æ€§ã®ãªã„プロジェクト"
msgid "Incompatible options set!"
msgstr "互æ›æ€§ã®ãªã„オプションãŒã‚»ãƒƒãƒˆã•ã‚Œã¦ã„ã¾ã™ã€‚"
-msgid "Index all projects"
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
msgstr ""
+msgid "Index all projects"
+msgstr "全プロジェクトインデックス"
+
msgid "Indicates whether this runner can pick jobs without tags"
msgstr "ã“ã®ãƒ©ãƒ³ãƒŠãƒ¼ãŒã‚¿ã‚°ã®ãªã„ジョブをé¸æŠžã§ãã‚‹ã‹ã©ã†ã‹ã‚’示ã—ã¾ã™ã€‚"
@@ -11308,21 +11826,39 @@ msgstr "ホストキーã®ãƒžãƒ‹ãƒ¥ã‚¢ãƒ«å…¥åŠ›"
msgid "Input your repository URL"
msgstr "リãƒã‚¸ãƒˆãƒªã® URL を入力ã—ã¦ãã ã•ã„"
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr "コードを挿入"
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr "候補を挿入ã™ã‚‹"
msgid "Insights"
+msgstr "洞察"
+
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
msgstr ""
-msgid "Install"
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
msgstr ""
+msgid "Install"
+msgstr "インストール"
+
msgid "Install GitLab Runner"
msgstr "GitLab Runner ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«"
@@ -11330,16 +11866,16 @@ msgid "Install Runner on Kubernetes"
msgstr "Kubernetes 㫠Runner をインストール"
msgid "Install a soft token authenticator like %{free_otp_link} or Google Authenticator from your application repository and use that app to scan this QR code. More information is available in the %{help_link_start}documentation%{help_link_end}."
-msgstr ""
+msgstr "アプリケーションリãƒã‚¸ãƒˆãƒªã‹ã‚‰ %{free_otp_link} ã‚„Google èªè¨¼ãªã©ã®ã‚½ãƒ•ãƒˆèªè¨¼ãƒˆãƒ¼ã‚¯ãƒ³ã‚’インストールã—ã€ãれを使ã£ã¦ã“ã®QRコードをスキャンã—ã¾ã™ã€‚より詳ã—ã„情報㯠%{help_link_start} 文書 %{help_link_end} ã‚’å‚ç…§ã—ã¦ãã ã•ã„。"
msgid "Install on clusters"
-msgstr ""
+msgstr "クラスタ上ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã™ã‚‹"
msgid "Installed"
-msgstr ""
+msgstr "インストール済ã¿"
msgid "Installing"
-msgstr ""
+msgstr "インストール中"
msgid "Instance"
msgid_plural "Instances"
@@ -11349,13 +11885,13 @@ msgid "Instance Statistics visibility"
msgstr "インスタンス統計ã®å¯è¦–性"
msgid "Instance administrators group already exists"
-msgstr ""
+msgstr "インスタンス管ç†è€…グループã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™"
msgid "Instance does not support multiple Kubernetes clusters"
msgstr "インスタンスã¯ãƒžãƒ«ãƒ Kubernetes クラスターをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“"
msgid "Instance license"
-msgstr ""
+msgstr "インスタンス ã®ãƒ©ã‚¤ã‚»ãƒ³ã‚¹"
msgid "Integration"
msgstr ""
@@ -11369,6 +11905,30 @@ msgstr "インテグレーション"
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr "貢献をã—ãŸã„関係者ã¯ã€ã‚³ãƒŸãƒƒãƒˆã‚’プッシュã™ã‚‹ã“ã¨ã§è²¢çŒ®ã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚"
@@ -11382,7 +11942,7 @@ msgid "Internal - The project can be accessed by any logged in user."
msgstr "内部 - プロジェクトã¯ã€ãƒ­ã‚°ã‚¤ãƒ³ã—ã¦ã„ã‚‹ã™ã¹ã¦ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã™ã€‚"
msgid "Internal URL (optional)"
-msgstr ""
+msgstr "内部URL(オプション)"
msgid "Internal users"
msgstr "内部ユーザー"
@@ -11391,7 +11951,7 @@ msgid "Interval Pattern"
msgstr "é–“éš”ã®ãƒ‘ターン"
msgid "Introducing Value Stream Analytics"
-msgstr ""
+msgstr "ãƒãƒªãƒ¥ãƒ¼ã‚¹ãƒˆãƒªãƒ¼ãƒ åˆ†æžã®ç´¹ä»‹"
msgid "Introducing Your DevOps Score"
msgstr ""
@@ -11408,6 +11968,12 @@ msgstr "ログインIDã¾ãŸã¯ãƒ‘スワードãŒç„¡åŠ¹ã§ã™ã€‚"
msgid "Invalid URL"
msgstr "無効㪠URL"
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11442,6 +12008,9 @@ msgid "Invalid login or password"
msgstr "ログインIDã¾ãŸã¯ãƒ‘スワードãŒç„¡åŠ¹ã§ã™ã€‚"
msgid "Invalid pin code"
+msgstr "PIN コードãŒé–“é•ã£ã¦ã„ã¾ã™ã€‚"
+
+msgid "Invalid pod_name"
msgstr ""
msgid "Invalid query"
@@ -11450,10 +12019,16 @@ msgstr "無効ãªã‚¯ã‚¨ãƒªãƒ¼"
msgid "Invalid repository path"
msgstr "リãƒã‚¸ãƒˆãƒªãƒ‘スãŒç„¡åŠ¹ã§ã™"
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr "無効ãªã‚µãƒ¼ãƒãƒ¼å¿œç­”"
msgid "Invalid start or end time format"
+msgstr "開始時刻ã¾ãŸã¯çµ‚了時刻ã®ãƒ•ã‚©ãƒ¼ãƒžãƒƒãƒˆãŒç„¡åŠ¹ã§ã™ã€‚"
+
+msgid "Invalid status"
msgstr ""
msgid "Invalid two-factor code."
@@ -11468,6 +12043,9 @@ msgstr "招待"
msgid "Invite \"%{trimmed}\" by email"
msgstr "メール㧠\"%{trimmed}\" を招待"
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr "グループã«æ‹›å¾…ã™ã‚‹"
@@ -11475,7 +12053,7 @@ msgid "Invite member"
msgstr "メンãƒãƒ¼ã‚’招待ã™ã‚‹"
msgid "Invocations"
-msgstr ""
+msgstr "呼ã³å‡ºã—"
msgid "Is blocked by"
msgstr ""
@@ -11508,7 +12086,7 @@ msgid "Issue"
msgstr "課題"
msgid "Issue %{issue_reference} has already been added to epic %{epic_reference}."
-msgstr ""
+msgstr "課題 %{issue_reference} をエピック %{epic_reference} ã«è¿½åŠ ã—ã¾ã—ãŸã€‚"
msgid "Issue Boards"
msgstr "課題ボード"
@@ -11531,6 +12109,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr "課題テンプレート(オプション)"
@@ -11538,11 +12119,38 @@ msgid "Issue update failed"
msgstr "課題ã®æ›´æ–°ã«å¤±æ•—ã—ã¾ã—ãŸ"
msgid "Issue was closed by %{name} %{reason}"
-msgstr ""
+msgstr "課題㯠%{name} ã«ã‚ˆã£ã¦ã‚¯ãƒ­ãƒ¼ã‚ºã•ã‚Œã¾ã—㟠%{reason}"
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr "ボード"
@@ -11565,25 +12173,25 @@ msgid "IssueBoards|Switch board"
msgstr "ボードを切り替ãˆã‚‹"
msgid "IssueTracker|Bugzilla issue tracker"
-msgstr ""
+msgstr "Bugzilla課題トラッカー"
msgid "IssueTracker|Custom issue tracker"
-msgstr ""
+msgstr "カスタム課題トラッカー"
msgid "IssueTracker|GitLab issue tracker"
-msgstr ""
+msgstr "GitLab 課題トラッカー"
msgid "IssueTracker|Redmine issue tracker"
-msgstr ""
+msgstr "Redmine 課題トラッカー"
msgid "IssueTracker|YouTrack issue tracker"
-msgstr ""
+msgstr "YouTrack 課題トラッカー"
msgid "Issues"
msgstr "課題"
msgid "Issues Analytics"
-msgstr ""
+msgstr "課題分æž"
msgid "Issues Rate Limits"
msgstr ""
@@ -11600,6 +12208,9 @@ msgstr "クローズã—ãŸèª²é¡Œ"
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr "コメントã®ã‚る課題ã€å·®åˆ†ã¨ã‚³ãƒ¡ãƒ³ãƒˆã€ãƒ©ãƒ™ãƒ«ã€ãƒžã‚¤ãƒ«ã‚¹ãƒˆãƒ¼ãƒ³ã€ã‚¹ãƒ‹ãƒšãƒƒãƒˆã€ãã®ä»–ã®ãƒ—ロジェクトエンティティã¨é–¢é€£ã—ãŸãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆ"
@@ -11610,13 +12221,13 @@ msgid "IssuesAnalytics|After you begin creating issues for your projects, we can
msgstr "プロジェクトã®èª²é¡Œã®ä½œæˆã‚’開始ã—ãŸã‚‰ã€ãƒ—ロジェクトã®ãƒ¡ãƒˆãƒªã‚¯ã‚¹ã‚’追跡ã—ã¦è¡¨ç¤ºã§ãã¾ã™ã€‚"
msgid "IssuesAnalytics|Avg/Month:"
-msgstr ""
+msgstr "月平å‡:"
msgid "IssuesAnalytics|Issues opened"
-msgstr ""
+msgstr "未解決ã®èª²é¡Œ"
msgid "IssuesAnalytics|Issues opened per month"
-msgstr ""
+msgstr "未解決ã®èª²é¡Œæ•°/月"
msgid "IssuesAnalytics|Last 12 months"
msgstr "éŽåŽ»12ヶ月間"
@@ -11631,10 +12242,10 @@ msgid "IssuesAnalytics|To widen your search, change or remove filters in the fil
msgstr "検索を拡大ã™ã‚‹ã«ã¯ã€ä¸Šè¨˜ã®ãƒ•ã‚£ãƒ«ã‚¿ãƒãƒ¼ã§ãƒ•ã‚£ãƒ«ã‚¿ã‚’変更ã¾ãŸã¯å‰Šé™¤ã—ã¾ã™"
msgid "IssuesAnalytics|Total:"
-msgstr ""
+msgstr "åˆè¨ˆ:"
msgid "Issue|Title"
-msgstr ""
+msgstr "タイトル"
msgid "It must have a header row and at least two columns: the first column is the issue title and the second column is the issue description. The separator is automatically detected."
msgstr "ヘッダー行ã¨å°‘ãªãã¨ã‚‚2ã¤ã®åˆ—ãŒå¿…è¦ã§ã™ã€‚最åˆã®åˆ—ã¯èª²é¡Œã®ã‚¿ã‚¤ãƒˆãƒ«ã€2番目ã®åˆ—ã¯èª²é¡Œã®èª¬æ˜Žã§ã™ã€‚区切り文字ã¯è‡ªå‹•çš„ã«æ¤œå‡ºã•ã‚Œã¾ã™ã€‚"
@@ -11645,6 +12256,30 @@ msgstr ""
msgid "It's you"
msgstr "ã‚ãªãŸã§ã™"
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr "Jaeger URL"
@@ -11657,19 +12292,22 @@ msgstr "1月"
msgid "January"
msgstr "1月"
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11682,10 +12320,10 @@ msgid "JiraService|Jira API URL"
msgstr "JIRA APIã®URL"
msgid "JiraService|Jira comments will be created when an issue gets referenced in a commit."
-msgstr ""
+msgstr "課題ãŒã‚³ãƒŸãƒƒãƒˆã§å‚ç…§ã•ã‚Œã‚‹ã¨ JiraコメントãŒä½œæˆã•ã‚Œã¾ã™ã€‚"
msgid "JiraService|Jira comments will be created when an issue gets referenced in a merge request."
-msgstr ""
+msgstr "課題ãŒãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã§å‚ç…§ã•ã‚Œã‚‹ã¨ Jira コメントãŒä½œæˆã•ã‚Œã¾ã™ã€‚"
msgid "JiraService|Jira issue tracker"
msgstr "Jira 課題トラッカー"
@@ -11742,7 +12380,7 @@ msgid "Job logs and artifacts"
msgstr ""
msgid "Job to create self-monitoring project is in progress"
-msgstr ""
+msgstr "自己監視プロジェクトを作æˆã™ã‚‹ã‚¸ãƒ§ãƒ–ã¯å®Ÿè¡Œä¸­ã§ã™"
msgid "Job to delete self-monitoring project is in progress"
msgstr ""
@@ -11795,6 +12433,9 @@ msgstr "アーティファクトã¯å‰Šé™¤ã•ã‚Œã¾ã—ãŸ"
msgid "Job|The artifacts will be removed"
msgstr "æˆæžœç‰©ã¯å‰Šé™¤ã•ã‚Œã¾ã™"
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr "ã“ã®ã‚¸ãƒ§ãƒ–ã¯å¤±æ•—ã—ã¾ã—ãŸã€‚å¿…è¦ãªãƒªã‚½ãƒ¼ã‚¹ãŒæ­£å¸¸ã«ä½œæˆã§ããªã‹ã£ãŸãŸã‚ã§ã™ã€‚"
@@ -11802,16 +12443,16 @@ msgid "Job|This job is stuck because the project doesn't have any runners online
msgstr "プロジェクトã«ã‚ªãƒ³ãƒ©ã‚¤ãƒ³ã® Runner ãŒå‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ãªã„ãŸã‚ã€ã‚¸ãƒ§ãƒ–ã¯åœæ­¢ã—ã¦ã„ã¾ã™ã€‚"
msgid "Job|for"
-msgstr ""
+msgstr "対象"
msgid "Job|into"
-msgstr ""
+msgstr "ターゲット:"
msgid "Job|with"
-msgstr ""
+msgstr "ソースブランãƒ:"
msgid "Join Zoom meeting"
-msgstr ""
+msgstr "Zoom ミーティングã«å‚加ã™ã‚‹"
msgid "Jul"
msgstr "7月"
@@ -11834,6 +12475,9 @@ msgstr "6月"
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr "キー"
@@ -11841,10 +12485,10 @@ msgid "Key (PEM)"
msgstr "キー (PEM)"
msgid "Key: %{key}"
-msgstr ""
+msgstr "キー: %{key}"
msgid "Keyboard Shortcuts"
-msgstr ""
+msgstr "キーボード ショートカット"
msgid "Keyboard shortcuts"
msgstr ""
@@ -11853,7 +12497,7 @@ msgid "Kubernetes"
msgstr "Kubernetes"
msgid "Kubernetes API returned status code: %{error_code}"
-msgstr ""
+msgstr "Kubernetes API ã‹ã‚‰ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚³ãƒ¼ãƒ‰ %{error_code} ãŒè¿”ã•ã‚Œã¾ã—ãŸã€‚"
msgid "Kubernetes Cluster"
msgstr "Kubernetes クラスター"
@@ -11868,7 +12512,7 @@ msgid "Kubernetes cluster creation time exceeds timeout; %{timeout}"
msgstr "Kubernetes クラスターã®ä½œæˆä¸­ã«ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ã¾ã—ãŸ:%{timeout}"
msgid "Kubernetes cluster integration and resources are being removed."
-msgstr ""
+msgstr "Kubernetesクラスターã®çµ±åˆã¨ãƒªã‚½ãƒ¼ã‚¹ã¯å‰Šé™¤ã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "Kubernetes cluster integration was successfully removed."
msgstr "Kubernetes クラスターã®çµ±åˆã¯æ­£å¸¸ã«å‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚"
@@ -11877,13 +12521,13 @@ msgid "Kubernetes cluster was successfully updated."
msgstr "Kubernetes クラスターã¯æ­£å¸¸ã«æ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚"
msgid "Kubernetes deployment not found"
-msgstr ""
+msgstr "リソース deployment ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚"
msgid "Kubernetes error: %{error_code}"
-msgstr ""
+msgstr "Kubernetesエラー: %{error_code}"
msgid "Kubernetes popover"
-msgstr ""
+msgstr "Kubernetes ãƒãƒƒãƒ—オーãƒãƒ¼"
msgid "LDAP"
msgstr "LDAP"
@@ -11895,7 +12539,7 @@ msgid "LDAP settings updated"
msgstr ""
msgid "LDAP sync in progress. This could take a few minutes. Refresh the page to see the changes."
-msgstr ""
+msgstr "LDAP åŒæœŸãŒé€²è¡Œä¸­ã§ã™ã€‚ã“ã‚Œã«ã¯æ•°åˆ†ã‹ã‹ã‚‹ã“ã¨ãŒã‚ã‚Šã¾ã™ã€‚ページを更新ã—ã¦å¤‰æ›´å†…容を確èªã—ã¦ãã ã•ã„。"
msgid "LFS"
msgstr "LFS"
@@ -11931,10 +12575,10 @@ msgid "Label was successfully updated."
msgstr "ラベルã¯æ­£å¸¸ã«æ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚"
msgid "LabelSelect|%{firstLabelName} +%{remainingLabelCount} more"
-msgstr ""
+msgstr "%{firstLabelName} +%{remainingLabelCount} 件以上"
msgid "LabelSelect|%{labelsString}, and %{remainingLabelCount} more"
-msgstr ""
+msgstr "%{labelsString}ã€ä»– %{remainingLabelCount} 件以上"
msgid "LabelSelect|Labels"
msgstr "ラベル"
@@ -11961,7 +12605,7 @@ msgid "Labels|Promoting %{labelTitle} will make it available for all projects in
msgstr ""
msgid "Labels|and %{count} more"
-msgstr ""
+msgstr "%{count} 以上"
msgid "Language"
msgstr "言語"
@@ -11974,19 +12618,19 @@ msgid_plural "Last %d days"
msgstr[0] "éŽåŽ»%d日間"
msgid "Last %{days} days"
-msgstr ""
+msgstr "éŽåŽ»%{days} 日間"
msgid "Last Accessed On"
-msgstr ""
+msgstr "最終アクセス"
msgid "Last Name is too long (maximum is %{max_length} characters)."
-msgstr ""
+msgstr "姓ãŒé•·ã™ãŽã¾ã™(最大 %{max_length} 文字)。"
msgid "Last Pipeline"
msgstr "最新パイプライン"
msgid "Last Seen"
-msgstr ""
+msgstr "最終閲覧"
msgid "Last accessed on"
msgstr "最終アクセス"
@@ -12007,31 +12651,34 @@ msgid "Last edited by %{name}"
msgstr "最終編集者 %{name}"
msgid "Last name"
-msgstr ""
+msgstr "姓"
msgid "Last reply by"
msgstr "最後ã®è¿”ä¿¡"
-msgid "Last repository check run"
+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 "最終閲覧"
msgid "Last successful sync"
-msgstr ""
+msgstr "最後ã«æˆåŠŸã—ãŸåŒæœŸ"
msgid "Last successful update"
-msgstr ""
+msgstr "最後ã®æˆåŠŸã—ãŸæ›´æ–°"
msgid "Last time verified"
-msgstr ""
+msgstr "å‰å›žã®ç¢ºèªæ—¥æ™‚"
msgid "Last update"
msgstr "最終更新"
msgid "Last update attempt"
-msgstr ""
+msgstr "最後ã®æ›´æ–°ã®è©¦è¡Œ"
msgid "Last updated"
msgstr "最終更新"
@@ -12055,7 +12702,7 @@ msgid "Latest changes"
msgstr "最新ã®å¤‰æ›´"
msgid "Latest pipeline for the most recent commit on this branch"
-msgstr ""
+msgstr "ã“ã®ãƒ–ランãƒã§ã®ç›´è¿‘ã®ã‚³ãƒŸãƒƒãƒˆã®æœ€æ–°ã®ãƒ‘イプライン"
msgid "Lead"
msgstr "リード"
@@ -12064,10 +12711,10 @@ msgid "Lead Time"
msgstr ""
msgid "Learn GitLab"
-msgstr ""
+msgstr "GitLab ã‚’å­¦ã¶"
msgid "Learn More"
-msgstr ""
+msgstr "詳ã—ã見る"
msgid "Learn how to %{link_start}contribute to the built-in templates%{link_end}"
msgstr "%{link_start} ビルトインã®ãƒ†ãƒ³ãƒ—レートã«è²¢çŒ® %{link_end}ã™ã‚‹æ–¹æ³•ã‚’å­¦ã¶"
@@ -12088,17 +12735,20 @@ msgid "Learn more about Kubernetes"
msgstr "Kubernetes ã®è©³ç´°"
msgid "Learn more about License-Check"
-msgstr ""
+msgstr "ライセンスãƒã‚§ãƒƒã‚¯ã®è©³ç´°ã«ã¤ã„ã¦"
msgid "Learn more about Vulnerability-Check"
-msgstr ""
+msgstr "脆弱性ãƒã‚§ãƒƒã‚¯ã®è©³ç´°ã«ã¤ã„ã¦"
msgid "Learn more about Web Terminal"
msgstr "Web Terminalã®è©³ç´°"
-msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
+msgid "Learn more about X.509 signed commits"
msgstr ""
+msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
+msgstr "%{docs_link_start}GitLab Pages 文書%{docs_link_end}ã«å¾“ã£ã¦ã€ã“ã®ãƒ—ロジェクトã¸ã®è¨¼æ˜Žæ›¸ã®è¿½åŠ ã«ã¤ã„ã¦å­¦ã¶ã€‚"
+
msgid "Learn more about approvals."
msgstr "承èªã®è©³ç´°"
@@ -12106,7 +12756,7 @@ msgid "Learn more about custom project templates"
msgstr "カスタムプロジェクトテンプレートã®è©³ç´°"
msgid "Learn more about deploying to a cluster"
-msgstr ""
+msgstr "クラスターã¸ã®ãƒ‡ãƒ—ロイã®è©³ç´°ã«ã¤ã„ã¦"
msgid "Learn more about group-level project templates"
msgstr "グループレベルプロジェクトテンプレートã®è©³ç´°"
@@ -12115,10 +12765,7 @@ msgid "Learn more about signing commits"
msgstr "コミットã¸ã®ç½²åã®è©³ç´°"
msgid "Learn more about the dependency list"
-msgstr ""
-
-msgid "Learn more about x509 signed commits"
-msgstr ""
+msgstr "ä¾å­˜é–¢ä¿‚リストã®è©³ç´°ã«ã¤ã„ã¦"
msgid "Learn more in the"
msgstr "詳ã—ã見る:"
@@ -12130,7 +12777,7 @@ msgid "Leave"
msgstr "離れる"
msgid "Leave Admin Mode"
-msgstr ""
+msgstr "管ç†è€…モードを終ãˆã‚‹"
msgid "Leave blank for no limit. Once set, existing personal access tokens may be revoked."
msgstr ""
@@ -12147,23 +12794,29 @@ msgstr "プロジェクトを離脱"
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr "\"ファイルタイプ\"ã¨\"デリãƒãƒªãƒ¼æ–¹æ³•\"オプションをデフォルト値ã®ã¾ã¾ã«ã—ã¾ã™ã€‚"
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr "Let's Encryptã¯example.comã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’å—ã‘付ã‘ã¾ã›ã‚“"
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ã¯ã€Webサイトã§HTTPS (SSL/TLS) を有効ã«ã™ã‚‹ãŸã‚ã«ãƒ‡ã‚¸ã‚¿ãƒ«è¨¼æ˜Žæ›¸ã‚’発行ã™ã‚‹ã€ç„¡æ–™ã®è‡ªå‹•åŒ–ã•ã‚ŒãŸã‚ªãƒ¼ãƒ—ンãªèªè¨¼å±€ (CA) ã§ã™ã€‚ %{docs_link_start} GitLab Pages ã®æ–‡æ›¸ %{docs_link_end} ã«å¾“ã£ã¦ã€Let's Encryptã®è¨­å®šã®è©³ç´°ã‚’学んã§ãã ã•ã„。"
msgid "License"
msgstr "ライセンス"
msgid "License Compliance"
+msgstr "ライセンスコンプライアンス"
+
+msgid "License History"
msgstr ""
msgid "License-Check"
msgstr "ライセンス ãƒã‚§ãƒƒã‚¯"
msgid "LicenseCompliance|Add a license"
-msgstr ""
+msgstr "ライセンスを追加"
msgid "LicenseCompliance|Add license and related policy"
msgstr ""
@@ -12175,7 +12828,7 @@ msgid "LicenseCompliance|Allowed"
msgstr ""
msgid "LicenseCompliance|Cancel"
-msgstr ""
+msgstr "キャンセル"
msgid "LicenseCompliance|Denied"
msgstr ""
@@ -12183,14 +12836,8 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
-msgstr ""
-
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
+msgstr "ライセンス"
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"
@@ -12198,57 +12845,57 @@ msgstr[0] ""
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[0] "ã“ã®ã‚½ãƒ¼ã‚¹ãƒ–ランãƒã§ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã‚’ %d 件検出ã—ã¾ã—ãŸã€‚"
msgid "LicenseCompliance|License Compliance detected %d new license"
msgid_plural "LicenseCompliance|License Compliance detected %d new licenses"
-msgstr[0] ""
+msgstr[0] "%d æ–°ã—ã„ライセンスを検出ã—ã¾ã—ãŸ"
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] ""
msgid "LicenseCompliance|License Compliance detected no licenses for the source branch only"
-msgstr ""
+msgstr "ã“ã®ã‚½ãƒ¼ã‚¹ãƒ–ランãƒã§ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã‚’検出ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
msgid "LicenseCompliance|License Compliance detected no new licenses"
-msgstr ""
+msgstr "æ–°ã—ã„ライセンスを検出ã—ã¾ã›ã‚“ã§ã—ãŸ"
msgid "LicenseCompliance|License details"
-msgstr ""
+msgstr "ライセンス詳細"
msgid "LicenseCompliance|License name"
-msgstr ""
+msgstr "ライセンスå"
msgid "LicenseCompliance|License review"
msgstr ""
msgid "LicenseCompliance|Packages"
-msgstr ""
+msgstr "パッケージ"
msgid "LicenseCompliance|Remove license"
-msgstr ""
+msgstr "ライセンスを削除"
msgid "LicenseCompliance|Remove license?"
-msgstr ""
+msgstr "ライセンスを削除ã—ã¾ã™ã‹?"
msgid "LicenseCompliance|Submit"
-msgstr ""
+msgstr "é€ä¿¡"
msgid "LicenseCompliance|There are currently no approved or blacklisted licenses in this project."
-msgstr ""
+msgstr "ã“ã®ãƒ—ロジェクトã«æ‰¿èªæ¸ˆã¿ãŠã‚ˆã³ãƒ–ラックリストã«ç™»éŒ²ã•ã‚ŒãŸãƒ©ã‚¤ã‚»ãƒ³ã‚¹ ã¯ã‚ã‚Šã¾ã›ã‚“。"
msgid "LicenseCompliance|There are currently no approved or blacklisted licenses that match in this project."
-msgstr ""
+msgstr "ã“ã®ãƒ—ロジェクトã«æ‰¿èªæ¸ˆã¿ã¾ãŸã¯ãƒ–ラックリストã«ç™»éŒ²ã•ã‚ŒãŸãƒ©ã‚¤ã‚»ãƒ³ã‚¹ ã¯ã‚ã‚Šã¾ã›ã‚“。"
msgid "LicenseCompliance|This license already exists in this project."
-msgstr ""
+msgstr "ã“ã®ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã¯ã™ã§ã«ã“ã®ãƒ—ロジェクトã«å­˜åœ¨ã—ã¾ã™ã€‚"
msgid "LicenseCompliance|URL"
-msgstr ""
+msgstr "URL"
msgid "LicenseCompliance|You are about to remove the license, %{name}, from this project."
-msgstr ""
+msgstr "ã“ã®ãƒ—ロジェクトã‹ã‚‰ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ %{name} を削除ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚"
msgid "LicenseManagement|Allowed"
msgstr ""
@@ -12269,13 +12916,13 @@ msgid "Licenses"
msgstr "ライセンス"
msgid "Licenses|%{remainingComponentsCount} more"
-msgstr ""
+msgstr "残コンãƒãƒ¼ãƒãƒ³ãƒˆæ•° %{remainingComponentsCount} 以上"
msgid "Licenses|Component"
-msgstr ""
+msgstr "コンãƒãƒ¼ãƒãƒ³ãƒˆ"
msgid "Licenses|Components"
-msgstr ""
+msgstr "コンãƒãƒ¼ãƒãƒ³ãƒˆ"
msgid "Licenses|Detected in Project"
msgstr ""
@@ -12287,16 +12934,16 @@ msgid "Licenses|Displays licenses detected in the project, based on the %{linkSt
msgstr ""
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
-msgstr ""
+msgstr "ライセンスリストãŒå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯æŽ¥ç¶šçŠ¶æ³ã‚’確èªã—ã¦å†è©¦è¡Œã—ã¦ãã ã•ã„。"
msgid "Licenses|Learn more about license compliance"
-msgstr ""
+msgstr "ライセンスコンプライアンスã®è©³ç´°ã«ã¤ã„ã¦"
msgid "Licenses|License Compliance"
-msgstr ""
+msgstr "ライセンスコンプライアンス"
msgid "Licenses|Name"
-msgstr ""
+msgstr "åå‰"
msgid "Licenses|Policies"
msgstr ""
@@ -12311,41 +12958,47 @@ msgid "Licenses|Specified policies in this project"
msgstr ""
msgid "Licenses|The license list details information about the licenses used within your project."
-msgstr ""
+msgstr "ライセンスリストã«ã¯ãƒ—ロジェクト内ã§ä½¿ç”¨ã•ã‚Œã¦ã„るライセンスã«é–¢ã™ã‚‹è©³ç´°æƒ…å ±ãŒè¨˜è¼‰ã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "Licenses|View license details for your project"
-msgstr ""
+msgstr "プロジェクトã®ãƒ©ã‚¤ã‚»ãƒ³ã‚¹è©³ç´°ã‚’表示"
msgid "License|Buy license"
msgstr "ライセンスを購入"
msgid "License|License"
+msgstr "ライセンス"
+
+msgid "License|Licensed user count exceeded"
msgstr ""
msgid "License|You can restore access to the Gold features at any time by upgrading."
-msgstr ""
+msgstr "アップグレードã«ã‚ˆã‚Šã€ã„ã¤ã§ã‚‚Gold機能ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ã‚’復元ã§ãã¾ã™ã€‚"
msgid "License|You can start a free trial of GitLab Ultimate without any obligation or payment details."
-msgstr ""
+msgstr "GitLab Ultimateã®ç„¡æ–™ãƒˆãƒ©ã‚¤ã‚¢ãƒ«ã¯ã€ç¾©å‹™ã‚„支払ã„ã®è©³ç´°ãªã—ã§é–‹å§‹ã§ãã¾ã™ã€‚"
msgid "License|You do not have a license."
-msgstr ""
+msgstr "ライセンスãŒã‚ã‚Šã¾ã›ã‚“。"
msgid "License|Your License"
-msgstr ""
+msgstr "ã‚ãªãŸã®ãƒ©ã‚¤ã‚»ãƒ³ã‚¹"
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
+msgstr "GitLab Ultimateã®ç„¡æ–™ãƒˆãƒ©ã‚¤ã‚¢ãƒ«ã¯%{trial_ends_on} ã§æœŸé™åˆ‡ã‚Œã«ãªã‚Šã¾ã—ãŸã€‚"
+
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
msgstr ""
msgid "Limit display of time tracking units to hours."
msgstr ""
msgid "Limit namespaces and projects that can be indexed"
-msgstr ""
+msgstr "インデックスã§ãã‚‹åå‰ç©ºé–“ã¨ãƒ—ロジェクトを制é™ã™ã‚‹"
msgid "Limited to showing %d event at most"
msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
+msgstr[0] "イベント表示数を最大 %d 個ã«åˆ¶é™"
msgid "Line changes"
msgstr ""
@@ -12354,7 +13007,7 @@ msgid "Link Prometheus monitoring to GitLab."
msgstr ""
msgid "Link copied"
-msgstr ""
+msgstr "リンクをコピーã—ã¾ã—ãŸ"
msgid "Link title"
msgstr ""
@@ -12363,10 +13016,10 @@ msgid "Link title is required"
msgstr ""
msgid "Linked emails (%{email_count})"
-msgstr ""
+msgstr "リンクã•ã‚ŒãŸãƒ¡ãƒ¼ãƒ« (%{email_count})"
msgid "Linked issues"
-msgstr ""
+msgstr "リンクã•ã‚ŒãŸèª²é¡Œ"
msgid "LinkedIn"
msgstr "LinkedIn"
@@ -12375,7 +13028,7 @@ msgid "LinkedPipelines|%{counterLabel} more downstream pipelines"
msgstr ""
msgid "Links"
-msgstr ""
+msgstr "リンク"
msgid "List"
msgstr "リスト"
@@ -12393,7 +13046,7 @@ msgid "List settings"
msgstr ""
msgid "List the merge requests that must be merged before this one."
-msgstr ""
+msgstr "ã“ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’マージã™ã‚‹å‰ã«ãƒžãƒ¼ã‚¸ã™ã‚‹å¿…è¦ãŒã‚るマージリクエストをリストアップã—ã¾ã™ã€‚"
msgid "List view"
msgstr "一覧表示"
@@ -12411,16 +13064,16 @@ msgid "Loading contribution stats for group members"
msgstr "グループメンãƒãƒ¼ã®è²¢çŒ®åº¦æƒ…報を読ã¿è¾¼ã¿ä¸­"
msgid "Loading files, directories, and submodules in the path %{path} for commit reference %{ref}"
-msgstr ""
+msgstr "コミットå‚ç…§ %{ref} 㮠パス %{path} ã«ãŠã‘るファイルã€ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã€ãŠã‚ˆã³ã‚µãƒ–モジュールを読ã¿è¾¼ã‚“ã§ã„ã¾ã™"
msgid "Loading functions timed out. Please reload the page to try again."
-msgstr ""
+msgstr "ロード機能ãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã€ãƒšãƒ¼ã‚¸ã‚’リロードã—ã¦ãã ã•ã„。"
msgid "Loading issues"
msgstr "課題ã®ãƒ­ãƒ¼ãƒ‰"
msgid "Loading snippet"
-msgstr ""
+msgstr "スニペットã®ãƒ­ãƒ¼ãƒ‰ä¸­"
msgid "Loading the GitLab IDE..."
msgstr "GitLab IDE ã®èª­ã¿è¾¼ã¿ä¸­..."
@@ -12431,6 +13084,9 @@ msgstr "読ã¿è¾¼ã¿ä¸­..."
msgid "Loading…"
msgstr "読ã¿è¾¼ã¿ä¸­â€¦"
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr "ローカライズ"
@@ -12441,7 +13097,7 @@ msgid "Lock"
msgstr "ロック"
msgid "Lock %{issuableDisplayName}"
-msgstr "ロック %{issuableDisplayName}"
+msgstr "%{issuableDisplayName} をロック"
msgid "Lock memberships to LDAP synchronization"
msgstr "メンãƒãƒ¼ã‚·ãƒƒãƒ—ã‚’LDAPåŒæœŸã«é™å®š"
@@ -12477,7 +13133,7 @@ msgid "Locks give the ability to lock specific file or folder."
msgstr "ロックã¯ã€ç‰¹å®šã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚„フォルダをロックã™ã‚‹æ©Ÿèƒ½ã‚’æä¾›ã—ã¾ã™ã€‚"
msgid "Locks the discussion."
-msgstr ""
+msgstr " ディスカッションをロックã™ã‚‹."
msgid "Login with smartcard"
msgstr "スマートカードã§ãƒ­ã‚°ã‚¤ãƒ³ã™ã‚‹"
@@ -12489,7 +13145,7 @@ msgid "Logs"
msgstr "ログ"
msgid "Logs|To see the logs, deploy your code to an environment."
-msgstr ""
+msgstr "ログを表示ã™ã‚‹ã«ã¯ã€ã‚³ãƒ¼ãƒ‰ã‚’環境ã«ãƒ‡ãƒ—ロイã—ã¾ã™ã€‚"
msgid "Low vulnerabilities present"
msgstr "å¼±ã„脆弱性ã®å­˜åœ¨"
@@ -12545,12 +13201,12 @@ msgstr "ã“ã‚Œã¯å¿…ãšä¿å­˜ã—ã¦ãã ã•ã„。二度ã¨ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr "インãƒãƒ¼ãƒˆã™ã‚‹ãƒ—ロジェクトを所有ã™ã‚‹ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã§ãƒ­ã‚°ã‚¤ãƒ³ã—ã¦ã„ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。"
+msgid "Make this epic confidential"
+msgstr ""
+
msgid "Makes this issue confidential."
msgstr "課題をéžå…¬é–‹ã«è¨­å®šã™ã‚‹ã€‚"
-msgid "Malformed string"
-msgstr "ä¸æ­£ãªãƒ•ã‚©ãƒ¼ãƒžãƒƒãƒˆã®æ–‡å­—列"
-
msgid "Manage"
msgstr "管ç†"
@@ -12575,6 +13231,9 @@ msgstr "グループラベルã®ç®¡ç†"
msgid "Manage labels"
msgstr "ラベルを管ç†"
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr "プロジェクトラベルã®ç®¡ç†"
@@ -12626,9 +13285,6 @@ msgstr "完了ã«ã™ã‚‹"
msgid "Mark as resolved"
msgstr "解決済ã«ã™ã‚‹"
-msgid "Mark comment as resolved"
-msgstr "コメントを解決済ã¿ã¨ã—ã¦ãƒžãƒ¼ã‚¯"
-
msgid "Mark this issue as a duplicate of another issue"
msgstr "ã“ã®èª²é¡Œã‚’別ã®èª²é¡Œã¨é‡è¤‡ã—ã¦ã„ã‚‹ã¨ãƒžãƒ¼ã‚¯ã™ã‚‹"
@@ -12638,9 +13294,6 @@ msgstr "ã“ã®èª²é¡Œã‚’別ã®èª²é¡Œã«é–¢é€£ã—ã¦ã„ã‚‹ã¨ãƒžãƒ¼ã‚¯ã™ã‚‹"
msgid "Markdown"
msgstr "Markdown"
-msgid "Markdown Help"
-msgstr "Markdown ヘルプ"
-
msgid "Markdown enabled"
msgstr "マークダウンを使用ã§ãã¾ã™"
@@ -12663,13 +13316,13 @@ msgid "Marks To Do as done."
msgstr "Todo を完了ã«ã™ã‚‹."
msgid "Marks this %{noun} as Work In Progress."
-msgstr ""
+msgstr "ã“ã® %{noun} を作業中ã¨ãƒžãƒ¼ã‚¯ã—ã¾ã™ã€‚"
msgid "Marks this issue as a duplicate of %{duplicate_reference}."
msgstr "ã“ã®èª²é¡Œã‚’ %{duplicate_reference} ã¨é‡è¤‡ã—ã¦ã„ã‚‹ã¨ãƒžãƒ¼ã‚¯ã™ã‚‹ã€‚"
msgid "Marks this issue as related to %{issue_ref}."
-msgstr ""
+msgstr "ã“ã®èª²é¡Œã‚’ %{issue_ref} ã«é–¢é€£ã—ã¦ã„ã‚‹ã¨ãƒžãƒ¼ã‚¯ã™ã‚‹ã€‚"
msgid "Mask variable"
msgstr ""
@@ -12702,7 +13355,7 @@ msgid "MattermostService|See list of available commands in Mattermost after sett
msgstr "ã“ã®ã‚µãƒ¼ãƒ“スを設定ã—ãŸå¾Œã«Mattermost上ã§ä½¿ç”¨ã§ãるコマンドã®ãƒªã‚¹ãƒˆã‚’表示ã™ã‚‹ã«ã¯ã€æ¬¡ã‚’入力ã—ã¾ã™ã€‚"
msgid "MattermostService|Suggestions:"
-msgstr ""
+msgstr "æ案:"
msgid "MattermostService|This service allows users to perform common operations on this project by entering slash commands in Mattermost."
msgstr "ã“ã®ã‚µãƒ¼ãƒ“スã«ã‚ˆã‚Šã€ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯Mattermostã«ã‚¹ãƒ©ãƒƒã‚·ãƒ¥ã‚³ãƒžãƒ³ãƒ‰ã‚’入力ã—ã¦ã€ã“ã®ãƒ—ロジェクト上ã®ä¸€èˆ¬çš„ãªæ“作ãŒå®Ÿè¡Œã§ãã¾ã™ã€‚"
@@ -12720,7 +13373,7 @@ msgid "Maximum Users:"
msgstr ""
msgid "Maximum allowable lifetime for personal access token (days)"
-msgstr ""
+msgstr "パーソナルアクセストークンã®æœ€é•·è¨±å®¹å¯¿å‘½(日数)"
msgid "Maximum artifacts size (MB)"
msgstr "アーティファクトサイズã®ä¸Šé™ (MB)"
@@ -12753,7 +13406,7 @@ msgid "Maximum job timeout has a value which could not be accepted"
msgstr "最大ジョブタイムアウトã«ã¯å—ã‘入れられãªã„値ãŒæŒ‡å®šã•ã‚Œã¦ã„ã¾ã™"
msgid "Maximum lifetime allowable for Personal Access Tokens is active, your expire date must be set before %{maximum_allowable_date}."
-msgstr ""
+msgstr "パーソナルアクセストークンã®æœ€é•·æœ‰åŠ¹æœŸé–“設定ãŒæœ‰åŠ¹ã§ã™ã€‚有効期é™ã¯ %{maximum_allowable_date} よりå‰ã«è¨­å®šã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "Maximum namespace storage (MB)"
msgstr ""
@@ -12795,7 +13448,7 @@ msgid "May"
msgstr "5月"
msgid "Measured in bytes of code. Excludes generated and vendored code."
-msgstr ""
+msgstr "測定ã—ãŸã‚³ãƒ¼ãƒ‰ã®ãƒã‚¤ãƒˆæ•°ã€‚自動生æˆã‚³ãƒ¼ãƒ‰ã¨ãƒ™ãƒ³ãƒ€ãƒ¼ã‚³ãƒ¼ãƒ‰ã‚’除外ã—ã¾ã™ã€‚"
msgid "Median"
msgstr "中央値"
@@ -12818,23 +13471,23 @@ msgstr "プロジェクト毎ã®<i>メンテナー</i>ã¾ãŸã¯<i>オーナー</
msgid "Members of <strong>%{project_name}</strong>"
msgstr "<strong>%{project_name}</strong>ã®ãƒ¡ãƒ³ãƒãƒ¼"
-msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
+msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
+msgstr "%{strong_start}%{group_name}%{strong_end} ã¸ã‚¢ã‚¯ã‚»ã‚¹ã§ãるメンãƒãƒ¼"
+
msgid "Members with pending access to %{strong_start}%{group_name}%{strong_end}"
-msgstr ""
+msgstr "%{strong_start}%{group_name}%{strong_end} ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒä¿ç•™ã•ã‚Œã¦ã„るメンãƒãƒ¼"
msgid "Memory Usage"
msgstr "メモリ使用é‡"
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
-msgstr ""
+msgstr "マージ"
msgid "Merge (when the pipeline succeeds)"
-msgstr ""
+msgstr "パイプラインãŒæˆåŠŸã—ãŸã¨ãã«ãƒžãƒ¼ã‚¸"
msgid "Merge Request"
msgstr "マージリクエスト"
@@ -12842,6 +13495,9 @@ msgstr "マージリクエスト"
msgid "Merge Request Approvals"
msgstr "マージリクエスト承èª"
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr "マージリクエスト"
@@ -12849,7 +13505,7 @@ msgid "Merge Requests created"
msgstr "作æˆã•ã‚ŒãŸãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆ"
msgid "Merge Requests in Review"
-msgstr ""
+msgstr "レビュー中ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆ"
msgid "Merge automatically (%{strategy})"
msgstr ""
@@ -12867,12 +13523,15 @@ msgid "Merge in progress"
msgstr "進行中ã®ãƒžãƒ¼ã‚¸"
msgid "Merge options"
-msgstr ""
+msgstr "マージオプション"
msgid "Merge request"
msgstr "マージリクエスト"
msgid "Merge request %{iid} authored by %{authorName}"
+msgstr "マージリクエスト %{iid} ㌠%{authorName}ã«ã‚ˆã£ã¦ä½œæˆã•ã‚Œã¾ã—ãŸ"
+
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
msgstr ""
msgid "Merge request approvals"
@@ -12882,7 +13541,7 @@ msgid "Merge request approvals allow you to set the number of necessary approval
msgstr ""
msgid "Merge request dependencies"
-msgstr ""
+msgstr "マージリクエストã®ä¾å­˜é–¢ä¿‚"
msgid "Merge requests"
msgstr "マージリクエスト"
@@ -12894,7 +13553,7 @@ msgid "Merge requests are a place to propose changes you've made to a project an
msgstr "マージリクエストã¨ã¯ã€ãƒ—ロジェクトã«åŠ ãˆãŸå¤‰æ›´ã‚’æ示ã—ã€ãã®å¤‰æ›´ã«ã¤ã„ã¦ä»–ã®ãƒ¡ãƒ³ãƒãƒ¼ã¨è©±ã—åˆã†ãŸã‚ã®å ´æ‰€ã§ã™"
msgid "Merge requests are read-only in a secondary Geo node"
-msgstr ""
+msgstr "マージリクエストã¯ã‚»ã‚«ãƒ³ãƒ€ãƒªã‚¸ã‚ªãƒŽãƒ¼ãƒ‰ã§ã¯èª­ã¿å–り専用ã§ã™"
msgid "Merge when pipeline succeeds"
msgstr "パイプラインãŒæˆåŠŸã—ãŸã¨ãã«ãƒžãƒ¼ã‚¸"
@@ -12923,9 +13582,18 @@ msgstr "競åˆ"
msgid "MergeConflict|origin//their changes"
msgstr "origin //相手ã®å¤‰æ›´"
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 "下書ãコメントã®ä¿å­˜ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
@@ -12939,7 +13607,7 @@ msgid "MergeRequests|Reply..."
msgstr "返信..."
msgid "MergeRequests|Resolve this thread in a new issue"
-msgstr ""
+msgstr "æ–°ã—ã„課題ã§ã“ã®ã‚¹ãƒ¬ãƒƒãƒ‰ã‚’解決ã™ã‚‹"
msgid "MergeRequests|Saving the comment failed"
msgstr "コメントã®ä¿å­˜ã«å¤±æ•—ã—ã¾ã—ãŸ"
@@ -12948,16 +13616,16 @@ msgid "MergeRequests|Squash task canceled: another squash is already in progress
msgstr "スカッシュタスクãŒå–り消ã•ã‚Œã¾ã—ãŸã€‚別ã®ã‚¹ã‚«ãƒƒã‚·ãƒ¥ãŒæ—¢ã«é€²è¡Œä¸­ã§ã™ã€‚"
msgid "MergeRequests|Thread stays resolved"
-msgstr ""
+msgstr "スレッドã¯è§£æ±ºæ¸ˆã¿ã®ã¾ã¾ã§ã™"
msgid "MergeRequests|Thread stays unresolved"
-msgstr ""
+msgstr "スレッドã¯æœªè§£æ±ºã®ã¾ã¾ã§ã™ã€‚"
msgid "MergeRequests|Thread will be resolved"
-msgstr ""
+msgstr "スレッドを解決ã—ã¾ã™"
msgid "MergeRequests|Thread will be unresolved"
-msgstr ""
+msgstr "スレッドを未解決ã«ã—ã¾ã™"
msgid "MergeRequests|Toggle comments for this file"
msgstr "ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã®ã‚³ãƒ¡ãƒ³ãƒˆã‚’切り替ãˆã¾ã™"
@@ -12966,27 +13634,27 @@ msgid "MergeRequests|View file @ %{commitId}"
msgstr "%{commitId} ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’表示"
msgid "MergeRequests|View replaced file @ %{commitId}"
-msgstr ""
+msgstr "%{commitId} ã§ç½®æ›ã•ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«ã‚’表示"
msgid "MergeRequests|commented on commit %{commitLink}"
msgstr "コミット %{commitLink} ã«ã¤ã„ã¦ã‚³ãƒ¡ãƒ³ãƒˆã•ã‚Œã¾ã—ãŸ"
msgid "MergeRequests|started a thread"
-msgstr ""
+msgstr "スレッドを開始ã—ã¾ã—ãŸ"
msgid "MergeRequests|started a thread on %{linkStart}an old version of the diff%{linkEnd}"
-msgstr ""
+msgstr "%{linkStart}å¤ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®å·®åˆ†%{linkEnd} ã«ã¤ã„ã¦ã‚¹ãƒ¬ãƒƒãƒ‰ãŒé–‹å§‹ã•ã‚Œã¾ã—ãŸ"
msgid "MergeRequests|started a thread on %{linkStart}the diff%{linkEnd}"
-msgstr ""
+msgstr "%{linkStart}差分%{linkEnd} ã«ã¤ã„ã¦ã‚¹ãƒ¬ãƒƒãƒ‰ã‚’開始ã—ã¾ã—ãŸ"
msgid "MergeRequests|started a thread on an outdated change in commit %{linkStart}%{commitDisplay}%{linkEnd}"
-msgstr ""
+msgstr "コミット %{linkStart}%{commitDisplay}%{linkEnd} ã®å¤ã„変更ã§ã‚¹ãƒ¬ãƒƒãƒ‰ã‚’開始ã—ã¾ã—ãŸ"
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
-msgstr ""
+msgstr "コミット %{linkStart}%{commitDisplay}%{linkEnd} ã®ã‚¹ãƒ¬ãƒƒãƒ‰ã‚’開始ã—ã¾ã—ãŸ"
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13004,6 +13672,9 @@ msgstr ""
msgid "Merged"
msgstr "マージ済ã¿"
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr "マージã—ãŸãƒ–ランãƒã¯å‰Šé™¤ä¸­ã§ã™ã€‚ã“ã‚Œã¯ãƒ–ランãƒã®æ•°ã«ã‚ˆã£ã¦ã¯æ™‚é–“ãŒã‹ã‹ã‚‹ã“ã¨ãŒã‚ã‚Šã¾ã™ã€‚進æ—を確èªã™ã‚‹ã«ã¯ã€ãƒšãƒ¼ã‚¸ã‚’æ›´æ–°ã—ã¦ãã ã•ã„。"
@@ -13014,7 +13685,7 @@ msgid "Merges this merge request immediately."
msgstr ""
msgid "Merges this merge request when the pipeline succeeds."
-msgstr ""
+msgstr "パイプラインãŒæˆåŠŸã—ãŸã¨ãã«ã“ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’マージã—ã¾ã™ã€‚"
msgid "Merging immediately isn't recommended as it may negatively impact the existing merge train. Read the %{docsLinkStart}documentation%{docsLinkEnd} for more information."
msgstr ""
@@ -13023,10 +13694,7 @@ msgid "Messages"
msgstr "メッセージ"
msgid "Method"
-msgstr ""
-
-msgid "Method:"
-msgstr ""
+msgstr "メソッド"
msgid "Metric was successfully added."
msgstr "メトリクスã¯æ­£å¸¸ã«è¿½åŠ ã•ã‚Œã¾ã—ãŸã€‚"
@@ -13038,32 +13706,35 @@ msgid "Metric:"
msgstr ""
msgid "MetricChart|Please select a metric"
-msgstr ""
+msgstr "メトリクスをé¸æŠžã—ã¦ãã ã•ã„"
msgid "MetricChart|Selected"
-msgstr ""
+msgstr "é¸æŠžæ¸ˆ"
msgid "Metrics"
msgstr "メトリクス"
msgid "Metrics - Grafana"
-msgstr ""
-
-msgid "Metrics - Influx"
-msgstr "メトリクス - Influx"
+msgstr "メトリクス - Grafana"
msgid "Metrics - Prometheus"
msgstr "メトリクス - Prometheus"
msgid "Metrics Dashboard"
+msgstr "メトリクスダッシュボード"
+
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
msgstr ""
msgid "Metrics and profiling"
msgstr "メトリクスã¨ãƒ—ロファイリング"
-msgid "Metrics for environment"
-msgstr "環境ã®ãƒ¡ãƒˆãƒªã‚¯ã‚¹"
-
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -13085,17 +13756,38 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr "メトリクスを追加"
msgid "Metrics|Avg"
-msgstr ""
+msgstr "å¹³å‡"
msgid "Metrics|Check out the CI/CD documentation on deploying to an environment"
msgstr "環境ã¸ã®ãƒ‡ãƒ—ロイã«ã¤ã„ã¦ã¯ã€CI / CD ã®æ–‡æ›¸ã‚’å‚ç…§ã—ã¦ãã ã•ã„。"
msgid "Metrics|Create custom dashboard %{fileName}"
-msgstr ""
+msgstr "カスタムダッシュボード %{fileName} を作æˆ"
msgid "Metrics|Create metric"
msgstr "メトリクスを作æˆ"
@@ -13107,17 +13799,17 @@ msgid "Metrics|Delete metric?"
msgstr "メトリクスを削除?"
msgid "Metrics|Duplicate"
-msgstr ""
+msgstr "複製"
msgid "Metrics|Duplicate dashboard"
-msgstr ""
+msgstr "ダッシュボードを複製"
msgid "Metrics|Duplicating..."
-msgstr ""
+msgstr "複製..."
msgid "Metrics|Edit metric"
msgid_plural "Metrics|Edit metrics"
-msgstr[0] ""
+msgstr[0] "メトリクスを編集"
msgid "Metrics|Expand panel"
msgstr ""
@@ -13132,17 +13824,23 @@ msgid "Metrics|Invalid time range, please verify."
msgstr ""
msgid "Metrics|Label of the y-axis (usually the unit). The x-axis always represents time."
-msgstr ""
+msgstr "y軸ã®ãƒ©ãƒ™ãƒ«(通常ã¯å˜ä½)。 x軸ã¯å¸¸ã«æ™‚間を表ã—ã¾ã™ã€‚"
msgid "Metrics|Legend label (optional)"
msgstr "汎用ラベル(オプション)"
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
+msgstr "リンクã«ç„¡åŠ¹ãªæ™‚間範囲ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚リンクを確èªã—ã€ãƒªã‚¯ã‚¨ã‚¹ãƒˆã—ãŸæ™‚間範囲を確èªã—ã¦ãã ã•ã„。"
+
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
msgstr ""
-msgid "Metrics|Max"
+msgid "Metrics|Manage chart links"
msgstr ""
+msgid "Metrics|Max"
+msgstr "最大"
+
msgid "Metrics|Must be a valid PromQL query."
msgstr "有効㪠PromQL クエリã§ã‚ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
@@ -13150,7 +13848,7 @@ msgid "Metrics|New metric"
msgstr "æ–°è¦ãƒ¡ãƒˆãƒªã‚¯ã‚¹"
msgid "Metrics|PromQL query is valid"
-msgstr ""
+msgstr "PromQLクエリã¯æœ‰åŠ¹ã§ã™"
msgid "Metrics|Prometheus Query Documentation"
msgstr "Prometheus クエリã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆ"
@@ -13158,11 +13856,14 @@ msgstr "Prometheus クエリã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆ"
msgid "Metrics|Refresh dashboard"
msgstr ""
-msgid "Metrics|There was an error creating the dashboard."
+msgid "Metrics|Star dashboard"
msgstr ""
+msgid "Metrics|There was an error creating the dashboard."
+msgstr "ダッシュボードを作æˆä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
+
msgid "Metrics|There was an error creating the dashboard. %{error}"
-msgstr ""
+msgstr "ダッシュボードを作æˆä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚: %{error}"
msgid "Metrics|There was an error fetching annotations. Please try again."
msgstr ""
@@ -13186,7 +13887,7 @@ msgid "Metrics|There was an error while retrieving metrics"
msgstr "メトリクスã®å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
msgid "Metrics|There was an error while retrieving metrics. %{message}"
-msgstr ""
+msgstr "メトリクスã®å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚%{message}"
msgid "Metrics|Unexpected deployment data response from prometheus endpoint"
msgstr ""
@@ -13194,6 +13895,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr "ユニットラベル"
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr "ãƒãƒ£ãƒ¼ãƒˆã®ã‚¿ã‚¤ãƒˆãƒ«ã¨ã—ã¦ä½¿ç”¨ã•ã‚Œã¾ã™"
@@ -13201,7 +13905,7 @@ msgid "Metrics|Used if the query returns a single series. If it returns multiple
msgstr "クエリãŒå˜ä¸€ã®ç³»åˆ—ã‚’è¿”ã™ã¨ãã«ä½¿ç”¨ã•ã‚Œã¾ã™ã€‚複数ã®ç³»åˆ—ãŒè¿”ã•ã‚ŒãŸå ´åˆã€æ±Žç”¨ãƒ©ãƒ™ãƒ«ã¯ãã®å¿œç­”ã‹ã‚‰å–å¾—ã—ã¾ã™ã€‚"
msgid "Metrics|Validating query"
-msgstr ""
+msgstr "クエリã®æ¤œè¨¼"
msgid "Metrics|Values"
msgstr ""
@@ -13213,7 +13917,7 @@ msgid "Metrics|Y-axis label"
msgstr "Y軸ラベル"
msgid "Metrics|You can save a copy of this dashboard to your repository so it can be customized. Select a file name and branch to save it."
-msgstr ""
+msgstr "ã“ã®ãƒ€ãƒƒã‚·ãƒ¥ãƒœãƒ¼ãƒ‰ã‚’ã‚ãªãŸã®ãƒªãƒã‚¸ãƒˆãƒªã«ã‚³ãƒ”ーã—ã¦ã€ã‚«ã‚¹ã‚¿ãƒžã‚¤ã‚ºã§ãるよã†ã«ã—ã¾ã™ã€‚ã“れをä¿å­˜ã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«åã¨ãƒ–ランãƒã‚’é¸æŠžã—ã¦ãã ã•ã„。"
msgid "Metrics|You're about to permanently delete this metric. This cannot be undone."
msgstr "ã“ã®ãƒ¡ãƒˆãƒªã‚¯ã‚¹ã‚’完全ã«å‰Šé™¤ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚ã“ã®æ“作ã¯ã€å…ƒã«æˆ»ã›ã¾ã›ã‚“。"
@@ -13234,7 +13938,7 @@ msgid "Metrics|e.g. req/sec"
msgstr "例:リクエスト毎秒"
msgid "Microsoft Azure"
-msgstr ""
+msgstr "Microsoft Azure"
msgid "Middleman project with Static Site Editor support"
msgstr ""
@@ -13255,6 +13959,63 @@ msgstr "ç¾åœ¨ã®ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã§ã¯ マイルストーンリストを利用ã
msgid "Milestone lists show all issues from the selected milestone."
msgstr "マイルストーンリストã«ã¯ã€é¸æŠžã—ãŸãƒžã‚¤ãƒ«ã‚¹ãƒˆãƒ¼ãƒ³ã®ã™ã¹ã¦ã®èª²é¡Œã‚’表示ã—ã¾ã™ã€‚"
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr "マイルストーン"
@@ -13264,6 +14025,12 @@ msgstr "ã‚ãªãŸã¯ã€ãƒžã‚¤ãƒ«ã‚¹ãƒˆãƒ¼ãƒ³ %{milestoneTitle} を永久ã«å‰Šé™
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr "ã‚ãªãŸã¯ã€ãƒžã‚¤ãƒ«ã‚¹ãƒˆãƒ¼ãƒ³ %{milestoneTitle} を永久ã«å‰Šé™¤ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚ã“ã®ãƒžã‚¤ãƒ«ã‚¹ãƒˆãƒ¼ãƒ³ã¯ç¾åœ¨ã€èª²é¡Œã¾ãŸã¯ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã§ä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã›ã‚“。"
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr "マイルストーンã®å‰Šé™¤"
@@ -13273,21 +14040,39 @@ msgstr "マイルストーン %{milestoneTitle} を削除ã—ã¾ã™ã‹ï¼Ÿ"
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr "マイルストーン %{milestoneTitle} ã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸ"
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr "マイルストーン %{milestoneTitle} ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr "%{milestoneTitle} をグループマイルストーンã«æ˜‡æ ¼ã—ã¾ã™ã‹ï¼Ÿ"
msgid "Milestones|Promote Milestone"
msgstr "マイルストーンã®æ˜‡æ ¼"
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr "%{milestoneTitle} を昇格ã™ã‚‹ã¨ã€ %{groupName} 内ã®ã™ã¹ã¦ã®ãƒ—ロジェクトã§ä½¿ç”¨ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚åŒã˜ã‚¿ã‚¤ãƒˆãƒ«ã‚’æŒã¤æ—¢å­˜ã®ãƒ—ロジェクトマイルストーンãŒãƒžãƒ¼ã‚¸ã•ã‚Œã¾ã™ã€‚"
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr "ã“ã®æ“作ã¯å…ƒã«æˆ»ã›ã¾ã›ã‚“。"
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr "より多ãã®ãƒŸãƒ©ãƒ¼ã‚’優先的ã«ã‚¹ã‚±ã‚¸ãƒ¥ãƒ¼ãƒ«ã™ã‚‹å‰ã«ä½¿ç”¨å¯èƒ½ã«ãªã‚‹ãŸã‚ã®æœ€å°å®¹é‡ã€‚"
@@ -13304,7 +14089,7 @@ msgid "Minutes"
msgstr "分"
msgid "Mirror direction"
-msgstr ""
+msgstr "ミラーã®æ–¹å‘"
msgid "Mirror repository"
msgstr "ミラーリãƒã‚¸ãƒˆãƒª"
@@ -13313,16 +14098,16 @@ msgid "Mirror settings are only available to GitLab administrators."
msgstr ""
msgid "Mirror user"
-msgstr ""
+msgstr "ミラーã®ãƒ¦ãƒ¼ã‚¶ãƒ¼"
msgid "Mirrored branches will have this prefix. If you enabled 'Only mirror protected branches' you need to include this prefix on protected branches in this project or nothing will be mirrored."
-msgstr ""
+msgstr "ミラー化ã•ã‚ŒãŸãƒ–ランãƒã«ã¯ã“ã®ãƒ—レフィックスãŒä»˜ãã¾ã™ã€‚ 「ä¿è­·ã•ã‚ŒãŸãƒ–ランãƒã®ã¿ã‚’ミラーリングã™ã‚‹ã€ã‚’有効ã«ã—ãŸå ´åˆã€ã“ã®ãƒ—ロジェクトã®ä¿è­·ã•ã‚ŒãŸãƒ–ランãƒã«ã‚‚ã“ã®ãƒ—レフィックスãŒãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。ãã†ã§ãªã„ã¨ã€ä½•ã‚‚ミラーリングã§ãã¾ã›ã‚“。"
msgid "Mirrored repositories"
-msgstr ""
+msgstr "ミラーã•ã‚ŒãŸãƒªãƒã‚¸ãƒˆãƒª"
msgid "Mirroring repositories"
-msgstr ""
+msgstr "ミラーã—ã¦ã„るリãƒã‚¸ãƒˆãƒª"
msgid "Mirroring settings were successfully updated."
msgstr "ミラーリングã®è¨­å®šã‚’æ­£ã—ãä¿å­˜ã—ã¾ã—ãŸã€‚"
@@ -13348,6 +14133,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr "キャンセル"
@@ -13358,7 +14146,7 @@ msgid "Modified"
msgstr ""
msgid "Modified in this version"
-msgstr ""
+msgstr "ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§å¤‰æ›´ã•ã‚ŒãŸæ©Ÿèƒ½"
msgid "Modify commit message"
msgstr "コミットメッセージã®ä¿®æ•´"
@@ -13373,7 +14161,7 @@ msgid "Monday"
msgstr "月曜日"
msgid "Monitor your errors by integrating with Sentry."
-msgstr ""
+msgstr "Sentry ã¨çµ±åˆã—ã¦ã‚¨ãƒ©ãƒ¼ã‚’モニターã™ã‚‹ã€‚"
msgid "Monitoring"
msgstr "監視"
@@ -13385,7 +14173,7 @@ msgid "More"
msgstr "ã•ã‚‰ã«è¡¨ç¤º"
msgid "More Information"
-msgstr ""
+msgstr "詳細"
msgid "More Slack commands"
msgstr "ãã®ä»–ã®Slackコマンド"
@@ -13403,7 +14191,7 @@ msgid "More information"
msgstr "詳ã—ã„情報"
msgid "More information and share feedback"
-msgstr ""
+msgstr "より詳細ãªæƒ…å ±ã¨ãƒ•ã‚£ãƒ¼ãƒ‰ãƒãƒƒã‚¯ã®å…±æœ‰"
msgid "More information is available|here"
msgstr "ã“ã“ã‚’å‚ç…§"
@@ -13427,13 +14215,13 @@ msgid "Move issue from one column of the board to another"
msgstr "ボードã®ã‚るカラムã‹ã‚‰åˆ¥ã®ã‚«ãƒ©ãƒ ã¸èª²é¡Œã‚’移動"
msgid "Move selection down"
-msgstr ""
+msgstr "é¸æŠžã‚’下ã¸ç§»å‹•"
msgid "Move selection up"
-msgstr ""
+msgstr "é¸æŠžã‚’上ã¸ç§»å‹•"
msgid "Move this issue to another project."
-msgstr ""
+msgstr "課題を別ã®ãƒ—ロジェクトã«ç§»å‹•ã™ã‚‹"
msgid "MoveIssue|Cannot move issue due to insufficient permissions!"
msgstr "権é™ãŒä¸å分ãªãŸã‚ã€èª²é¡Œã‚’移動ã§ãã¾ã›ã‚“。"
@@ -13442,10 +14230,10 @@ msgid "MoveIssue|Cannot move issue to project it originates from!"
msgstr "発行元ã®ãƒ—ロジェクトã«èª²é¡Œã‚’移動ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。"
msgid "Moved issue to %{label} column in the board."
-msgstr ""
+msgstr "課題ã¯ãƒœãƒ¼ãƒ‰ã® %{label} 列ã«ç§»å‹•ã—ãŸã€‚"
msgid "Moved this issue to %{path_to_project}."
-msgstr ""
+msgstr "課題㯠%{path_to_project} ã«ç§»å‹•ã—ãŸã€‚"
msgid "Moves issue to %{label} column in the board."
msgstr "課題をボード㮠%{label} 列ã«ç§»å‹•ã—ã¾ã™ã€‚"
@@ -13462,6 +14250,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr "マルãƒèª²é¡Œãƒœãƒ¼ãƒ‰"
@@ -13471,11 +14262,14 @@ msgstr "複数ã®ãƒ¢ãƒ‡ãƒ«ã‚¿ã‚¤ãƒ—ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸ: %{model_types}"
msgid "Multiple uploaders found: %{uploader_types}"
msgstr "複数ã®ã‚¢ãƒƒãƒ—ローダーãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸ: %{uploader_types}"
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
msgid "My-Reaction"
-msgstr ""
+msgstr "自分ã®ãƒªã‚¢ã‚¯ã‚·ãƒ§ãƒ³"
msgid "Name"
msgstr "åå‰"
@@ -13483,9 +14277,6 @@ msgstr "åå‰"
msgid "Name has already been taken"
msgstr "ãã®åå‰ã¯æ—¢ã«ä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™ã€‚"
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr "æ–°ã—ã„ラベルã«åå‰ã‚’ã¤ã‘ã‚‹"
@@ -13495,9 +14286,6 @@ msgstr "åå‰:"
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr "インデックス作æˆã™ã‚‹åå‰ç©ºé–“"
@@ -13508,7 +14296,7 @@ msgid "Naming, visibility"
msgstr ""
msgid "Navigate to the project to close the milestone."
-msgstr ""
+msgstr "プロジェクトã«ç§»å‹•ã—ã¦ã€ãƒžã‚¤ãƒ«ã‚¹ãƒˆãƒ¼ãƒ³ã‚’é–‰ã˜ã‚‹ã€‚"
msgid "Nav|Help"
msgstr "ヘルプ"
@@ -13531,6 +14319,54 @@ msgstr ""
msgid "Network"
msgstr "ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯"
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr "ã—ãªã„"
@@ -13544,13 +14380,13 @@ msgid "New Environment"
msgstr "æ–°ã—ã„環境"
msgid "New Geo Node"
-msgstr ""
+msgstr "新ジオノード"
msgid "New Group"
msgstr "æ–°ã—ã„グループ"
msgid "New Group Name"
-msgstr ""
+msgstr "æ–°ã—ã„グループå"
msgid "New Identity"
msgstr "æ–°ã—ã„ ID"
@@ -13559,9 +14395,12 @@ msgid "New Issue"
msgid_plural "New Issues"
msgstr[0] "æ–°è¦èª²é¡Œ"
-msgid "New Jira import"
+msgid "New Iteration"
msgstr ""
+msgid "New Jira import"
+msgstr "æ–°ã—ã„ Jira インãƒãƒ¼ãƒˆ"
+
msgid "New Label"
msgstr "æ–°ã—ã„ラベル"
@@ -13578,7 +14417,7 @@ msgid "New Pipeline Schedule"
msgstr "æ–°è¦ãƒ‘イプラインスケジュール"
msgid "New Project"
-msgstr ""
+msgstr "æ–°è¦ãƒ—ロジェクト"
msgid "New Snippet"
msgstr "æ–°è¦ã‚¹ãƒ‹ãƒšãƒƒãƒˆ"
@@ -13590,7 +14429,7 @@ msgid "New branch unavailable"
msgstr "æ–°ã—ã„ブランãƒã¯åˆ©ç”¨ã§ãã¾ã›ã‚“"
msgid "New changes were added. %{linkStart}Reload the page to review them%{linkEnd}"
-msgstr ""
+msgstr "æ–°ã—ã„変更ãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸã€‚%{linkStart}ページをリロードã—ã¦ãƒ¬ãƒ“ューã—ã¦ãã ã•ã„%{linkEnd}"
msgid "New deploy key"
msgstr "æ–°ã—ã„デプロイキー"
@@ -13605,7 +14444,7 @@ msgid "New epic"
msgstr "æ–°ã—ã„エピック"
msgid "New epic title"
-msgstr ""
+msgstr "æ–°è¦ã‚¨ãƒ”ックã®ã‚¿ã‚¤ãƒˆãƒ«"
msgid "New file"
msgstr "æ–°è¦ãƒ•ã‚¡ã‚¤ãƒ«"
@@ -13625,6 +14464,9 @@ msgstr "æ–°è¦èª²é¡Œ"
msgid "New issue title"
msgstr "æ–°ã—ã„課題ã®ã‚¿ã‚¤ãƒˆãƒ«"
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr "æ–°ã—ã„ラベル"
@@ -13644,10 +14486,10 @@ msgid "New project"
msgstr "æ–°è¦ãƒ—ロジェクト"
msgid "New release"
-msgstr ""
+msgstr "æ–°ã—ã„リリース"
msgid "New requirement"
-msgstr ""
+msgstr "æ–°ã—ã„è¦æ±‚事項"
msgid "New runners registration token has been generated!"
msgstr "æ–°ã—ã„ランナー登録トークンを生æˆã—ã¾ã—ãŸï¼"
@@ -13668,13 +14510,13 @@ msgid "New users set to external"
msgstr "æ–°è¦ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’外部ユーザーã«è¨­å®š"
msgid "New! Suggest changes directly"
-msgstr ""
+msgstr "æ–°æ©Ÿèƒ½ï¼ å¤‰æ›´ã‚’ç›´æŽ¥æ案"
msgid "New..."
msgstr "æ–°è¦...\t"
msgid "Newest first"
-msgstr ""
+msgstr "æ–°ã—ã„é †"
msgid "Newly registered users will by default be external"
msgstr "æ–°ã—ã登録ã•ã‚ŒãŸãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§å¤–部ユーザーã«ãªã‚Šã¾ã™"
@@ -13682,6 +14524,9 @@ msgstr "æ–°ã—ã登録ã•ã‚ŒãŸãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§å¤–部ユーザ
msgid "Next"
msgstr "Next"
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13695,22 +14540,13 @@ msgid "No"
msgstr "ã„ã„ãˆ"
msgid "No %{header} for this request."
-msgstr ""
+msgstr "ã“ã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆã® %{header} ãŒã‚ã‚Šã¾ã›ã‚“。"
msgid "No %{providerTitle} repositories found"
-msgstr ""
-
-msgid "No %{replicableType} match this filter"
-msgstr ""
+msgstr "リãƒã‚¸ãƒˆãƒªã® %{providerTitle} ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
msgid "No Epic"
-msgstr ""
-
-msgid "No Label"
-msgstr "ラベルãŒã‚ã‚Šã¾ã›ã‚“"
-
-msgid "No Milestone"
-msgstr "マイルストーンãªã—"
+msgstr "Epicã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "No Scopes"
msgstr ""
@@ -13719,22 +14555,22 @@ msgid "No Tag"
msgstr "ã‚¿ã‚°ãªã—"
msgid "No active admin user found"
-msgstr ""
+msgstr "アクティブãªç®¡ç†ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
msgid "No activities found"
msgstr "アクティビティã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "No application_settings found"
-msgstr ""
+msgstr "application_settings ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
msgid "No approvers"
-msgstr ""
+msgstr "承èªè€…ãŒã„ã¾ã›ã‚“"
msgid "No authentication methods configured."
-msgstr ""
+msgstr "èªè¨¼æ–¹æ³•ãŒè¨­å®šã•ã‚Œã¦ã„ã¾ã›ã‚“。"
msgid "No available namespaces to fork the project."
-msgstr ""
+msgstr "プロジェクトをフォークã™ã‚‹åå‰ç©ºé–“ãŒ1個もã‚ã‚Šã¾ã›ã‚“。"
msgid "No branches found"
msgstr "ブランãƒãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。"
@@ -13746,13 +14582,13 @@ msgid "No changes between %{ref_start}%{source_branch}%{ref_end} and %{ref_start
msgstr "%{ref_start}%{source_branch}%{ref_end} 㨠%{ref_start}%{target_branch}%{ref_end} ã®é–“ã«å¤‰æ›´ãŒã‚ã‚Šã¾ã›ã‚“。"
msgid "No child epics match applied filters"
-msgstr ""
+msgstr "é©ç”¨ã•ã‚ŒãŸãƒ•ã‚£ãƒ«ã‚¿ãƒ¼ã¨ä¸€è‡´ã™ã‚‹å­ã‚¨ãƒ”ックã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "No connection could be made to a Gitaly Server, please check your logs!"
msgstr "Gitaly サーãƒãƒ¼ã«æŽ¥ç¶šã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ログを確èªã—ã¦ãã ã•ã„ï¼"
msgid "No containers available"
-msgstr ""
+msgstr "コンテナãŒã‚ã‚Šã¾ã›ã‚“"
msgid "No contributions"
msgstr "貢献ãªã—"
@@ -13764,19 +14600,19 @@ msgid "No credit card required."
msgstr "クレジット カードã¯å¿…è¦ã‚ã‚Šã¾ã›ã‚“"
msgid "No data found"
-msgstr ""
+msgstr "データãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
msgid "No data to display"
-msgstr ""
+msgstr "表示ã™ã‚‹ãƒ‡ãƒ¼ã‚¿ã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "No deployments found"
-msgstr ""
+msgstr "デプロイãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
msgid "No due date"
msgstr "期é™ãªã—"
msgid "No endpoint provided"
-msgstr ""
+msgstr "エンドãƒã‚¤ãƒ³ãƒˆãŒã‚ã‚Šã¾ã›ã‚“"
msgid "No errors to display."
msgstr "表示ã§ãるエラーã¯ã‚ã‚Šã¾ã›ã‚“。"
@@ -13788,7 +14624,7 @@ msgid "No file chosen"
msgstr "ファイルãŒé¸æŠžã•ã‚Œã¦ã„ã¾ã›ã‚“"
msgid "No file hooks found."
-msgstr ""
+msgstr "ファイルフックã¯ã‚ã‚Šã¾ã›ã‚“。"
msgid "No file selected"
msgstr "ファイルãŒé¸æŠžã•ã‚Œã¦ã„ã¾ã›ã‚“"
@@ -13800,12 +14636,18 @@ msgid "No files found."
msgstr "ファイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。"
msgid "No forks are available to you."
+msgstr "ã‚ãªãŸãŒåˆ©ç”¨å¯èƒ½ãªãƒ•ã‚©ãƒ¼ã‚¯ã¯ã‚ã‚Šã¾ã›ã‚“。"
+
+msgid "No grouping"
msgstr ""
msgid "No job log"
-msgstr ""
+msgstr "ジョブログãŒã‚ã‚Šã¾ã›ã‚“"
msgid "No jobs to show"
+msgstr "表示ã™ã‚‹ã‚¸ãƒ§ãƒ–ãŒã‚ã‚Šã¾ã›ã‚“"
+
+msgid "No label"
msgstr ""
msgid "No labels with such name or description"
@@ -13818,10 +14660,10 @@ msgid "No licenses found."
msgstr "ライセンスãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。"
msgid "No matches found"
-msgstr ""
+msgstr "一致ã™ã‚‹é …ç›®ãŒã‚ã‚Šã¾ã›ã‚“"
msgid "No matching labels"
-msgstr ""
+msgstr "一致ã™ã‚‹ãƒ©ãƒ™ãƒ«ãŒã‚ã‚Šã¾ã›ã‚“"
msgid "No matching results"
msgstr "一致ã™ã‚‹çµæžœãŒã‚ã‚Šã¾ã›ã‚“"
@@ -13832,6 +14674,9 @@ msgstr "マージリクエストã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
msgid "No messages were logged"
msgstr "メッセージã¯è¨˜éŒ²ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr "表示ã™ã‚‹ãƒžã‚¤ãƒ«ã‚¹ãƒˆãƒ¼ãƒ³ãŒã‚ã‚Šã¾ã›ã‚“"
@@ -13842,7 +14687,7 @@ msgid "No parent group"
msgstr "親グループã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "No pods available"
-msgstr ""
+msgstr "利用å¯èƒ½ãªãƒãƒƒãƒ‰ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
msgid "No policy matches this license"
msgstr ""
@@ -13851,7 +14696,7 @@ msgid "No preview for this file type"
msgstr "ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚¿ã‚¤ãƒ—ã¯ãƒ—レビューã—ã¾ã›ã‚“"
msgid "No prioritized labels with such name or description"
-msgstr ""
+msgstr "ãã®åå‰ã¾ãŸã¯ãã®èª¬æ˜Žã‚’ã‚‚ã£ãŸã€å„ªå…ˆãƒ©ãƒ™ãƒ«ã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "No public groups"
msgstr "パブリック グループãŒã‚ã‚Šã¾ã›ã‚“"
@@ -13863,7 +14708,7 @@ msgid "No repository"
msgstr "リãƒã‚¸ãƒˆãƒªãŒã‚ã‚Šã¾ã›ã‚“"
msgid "No required pipeline"
-msgstr ""
+msgstr "必須パイプラインãªã—"
msgid "No runners found"
msgstr "Runner ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
@@ -13872,13 +14717,13 @@ msgid "No schedules"
msgstr "スケジュールãªã—"
msgid "No starrers matched your search"
-msgstr ""
+msgstr "ã‚ãªãŸã®æ¤œç´¢ã«ãƒžãƒƒãƒã—ãŸãŠæ°—ã«å…¥ã‚Šã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "No start date"
msgstr "開始日ãªã—"
msgid "No template"
-msgstr ""
+msgstr "テンプレートãŒã‚ã‚Šã¾ã›ã‚“"
msgid "No test coverage"
msgstr ""
@@ -13887,10 +14732,10 @@ msgid "No thanks, don't show this again"
msgstr ""
msgid "No vulnerabilities present"
-msgstr ""
+msgstr "脆弱性ã¯ç™ºè¦‹ã•ã‚Œã¾ã›ã‚“ã§ã—ãŸã€‚"
msgid "No webhooks found, add one in the form above."
-msgstr ""
+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 ""
@@ -13899,13 +14744,13 @@ msgid "No, directly import the existing email addresses and usernames."
msgstr "ã„ã„ãˆã€æ—¢å­˜ã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã¨ãƒ¦ãƒ¼ã‚¶ãƒ¼åを直接インãƒãƒ¼ãƒˆã—ã¾ã™ã€‚"
msgid "No, not interested right now"
-msgstr ""
+msgstr "ã„ã„ãˆã€ä»Šã¯èˆˆå‘³ãŒã‚ã‚Šã¾ã›ã‚“"
msgid "No. of commits"
msgstr ""
msgid "Nobody has starred this repository yet"
-msgstr ""
+msgstr "誰もã¾ã ã“ã®ãƒªãƒã‚¸ãƒˆãƒªã«ã‚¹ã‚¿ãƒ¼ã‚’付ã‘ã¦ã„ã¾ã›ã‚“"
msgid "Node was successfully created."
msgstr "ノードを正常ã«ä½œæˆã—ã¾ã—ãŸã€‚"
@@ -13917,16 +14762,16 @@ msgid "Nodes"
msgstr "ノード"
msgid "Non-admin users can sign in with read-only access and make read-only API requests."
-msgstr ""
+msgstr "管ç†è€…ã§ã¯ãªã„ユーザーã¯ã€èª­ã¿å–り専用アクセスã§ã‚µã‚¤ãƒ³ã‚¤ãƒ³ã—ã¦ã€èª­ã¿å–り専用APIをリクエストã§ãã¾ã™ã€‚"
msgid "None"
msgstr "ãªã—"
msgid "Not Implemented"
-msgstr ""
+msgstr "未実装"
msgid "Not all data has been processed yet, the accuracy of the chart for the selected timeframe is limited."
-msgstr ""
+msgstr "ã™ã¹ã¦ã®ãƒ‡ãƒ¼ã‚¿ãŒã¾ã å‡¦ç†ã§ãã¦ã„ã¾ã›ã‚“。ãã®ãŸã‚ã€é¸æŠžã—ãŸæ™‚間範囲ã®ãƒãƒ£ãƒ¼ãƒˆã®ç²¾åº¦ã¯åˆ¶é™ã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "Not available"
msgstr "利用ã§ãã¾ã›ã‚“"
@@ -13947,7 +14792,7 @@ msgid "Not found."
msgstr "見ã¤ã‹ã‚Šã¾ã›ã‚“。"
msgid "Not helpful"
-msgstr ""
+msgstr "å½¹ã«ç«‹ã¡ã¾ã›ã‚“"
msgid "Not now"
msgstr "後ã§"
@@ -13959,14 +14804,17 @@ msgid "Not started"
msgstr "開始ã•ã‚Œã¦ã„ã¾ã›ã‚“"
msgid "Not-confidential epic cannot be assigned to a confidential parent epic"
-msgstr ""
+msgstr "éžæ©Ÿå¯†ã®ã‚¨ãƒ”ックを機密ã®è¦ªã‚¨ãƒ”ックã«å‰²ã‚Šå½“ã¦ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
msgid "Note"
-msgstr ""
+msgstr "注æ„事項"
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 "ã“ã®æ‹›å¾…メール㯠%{mail_to_invite_email} å®›ã«é€ä¿¡ã—ã¾ã—ãŸãŒã€ã‚ãªãŸã¯ %{link_to_current_user} ã¨ã—ã¦ãŠã‚Šã€ãã®Eメールアドレス㯠%{mail_to_current_user} ã§ã™ã€‚"
@@ -13991,6 +14839,9 @@ msgstr "本当ã«ã“ã®ã‚³ãƒ¡ãƒ³ãƒˆã®ä½œæˆã‚’キャンセルã—ã¾ã™ã‹ï¼Ÿ"
msgid "Notes|Collapse replies"
msgstr "返信を折りãŸãŸã‚€"
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr "ã™ã¹ã¦ã®ã‚¢ã‚¯ãƒ†ã‚£ãƒ“ティを表示"
@@ -14052,7 +14903,7 @@ msgid "NotificationEvent|New note"
msgstr "æ–°è¦ãƒŽãƒ¼ãƒˆ"
msgid "NotificationEvent|New release"
-msgstr ""
+msgstr "新リリース"
msgid "NotificationEvent|Reassign issue"
msgstr "課題ã®æ‹…当者を変更"
@@ -14091,7 +14942,7 @@ msgid "Notifications"
msgstr "通知"
msgid "Notifications have been disabled by the project or group owner"
-msgstr ""
+msgstr "プロジェクトã¾ãŸã¯ã‚°ãƒ«ãƒ¼ãƒ—ã®æ‰€æœ‰è€…ã«ã‚ˆã£ã¦é€šçŸ¥ãŒç„¡åŠ¹ã«ã•ã‚Œã¾ã—ãŸ"
msgid "Notifications off"
msgstr "通知オフ"
@@ -14105,7 +14956,13 @@ msgstr "11月"
msgid "November"
msgstr "11月"
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
+msgstr "最上部ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆãƒŠãƒ“ゲーションタブã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãるよã†ã«ãªã‚Šã€è¦‹ã¤ã‘ã‚„ã™ããªã‚Šã¾ã—ãŸã€‚"
+
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
msgid "Number of %{itemTitle}"
@@ -14118,31 +14975,31 @@ msgid "Number of Elasticsearch shards"
msgstr "Elasticsearchã®ã‚·ãƒ£ãƒ¼ãƒ‰ã®æ•°"
msgid "Number of LOCs per commit"
-msgstr ""
+msgstr "コミットã”ã¨ã®LOCæ•°"
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 ""
+msgstr "1回ã®ãƒ—ッシュã§ã®å¤‰æ›´ï¼ˆãƒ–ランãƒã¾ãŸã¯ã‚¿ã‚°ï¼‰ã®æ•°ã€‚å˜ä¸€ã®ãƒ—ッシュイベントã¾ãŸã¯ãƒãƒ«ã‚¯ãƒ—ッシュイベントã®ã©ã¡ã‚‰ã‚’作æˆã™ã‚‹ã‹ã‚’決定ã™ã‚‹ãŸã‚ã«ä½¿ç”¨ã—ã¾ã™ã€‚ã“ã®å€¤ã‚’超ãˆã‚‹ã¨ãƒãƒ«ã‚¯ãƒ—ッシュイベントを作æˆã—ã¾ã™ã€‚"
msgid "Number of changes (branches or tags) in a single push to determine whether webhooks and services will be fired or not. Webhooks and services won't be submitted if it surpasses that value."
-msgstr ""
+msgstr "1回ã®ãƒ—ッシュã§ã®å¤‰æ›´ï¼ˆãƒ–ランãƒã¾ãŸã¯ã‚¿ã‚°ï¼‰ã®æ•°ã€‚Webhook ãŠã‚ˆã³ã‚µãƒ¼ãƒ“スãŒèµ·å‹•ã•ã‚Œã‚‹ã‹ã©ã†ã‹ã‚’決定ã™ã‚‹ãŸã‚ã«ä½¿ç”¨ã—ã¾ã™ã€‚ ã“ã®å€¤ã‚’超ãˆã‚‹ã¨ Webhook やサービスã«é€ä¿¡ã•ã‚Œã¾ã›ã‚“。"
msgid "Number of commits"
msgstr "コミット数"
msgid "Number of commits per MR"
-msgstr ""
+msgstr "MRã‚ãŸã‚Šã®ã‚³ãƒŸãƒƒãƒˆæ•°"
msgid "Number of employees"
-msgstr ""
+msgstr "従業員数"
msgid "Number of files touched"
-msgstr ""
+msgstr "æ“作ã—ãŸãƒ•ã‚¡ã‚¤ãƒ«æ•°"
msgid "OK"
msgstr "OK"
msgid "Object Storage replication"
-msgstr ""
+msgstr "オブジェクトストレージã®ãƒ¬ãƒ—リケーション"
msgid "Object does not exist on the server or you don't have permissions to access it"
msgstr "オブジェクトãŒã‚µãƒ¼ãƒãƒ¼ã«å­˜åœ¨ã—ã¾ã›ã‚“ã€ã¾ãŸã¯ã€ãã‚Œã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹æ¨©é™ãŒã‚ã‚Šã¾ã›ã‚“"
@@ -14157,16 +15014,16 @@ msgid "OfSearchInADropdown|Filter"
msgstr "フィルター"
msgid "Oh no!"
-msgstr ""
+msgstr "ãŠã£ã¨!"
msgid "Ok let's go"
-msgstr ""
+msgstr "ã•ã‚ã€å§‹ã‚よã†"
msgid "Oldest first"
-msgstr ""
+msgstr "å¤ã„é †"
msgid "OmniAuth"
-msgstr ""
+msgstr "OmniAuth"
msgid "Omnibus Protected Paths throttle is active, and takes priority over these settings. From 12.4, Omnibus throttle is deprecated and will be removed in a future release. Please read the %{relative_url_link_start}Migrating Protected Paths documentation%{relative_url_link_end}."
msgstr ""
@@ -14174,18 +15031,24 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr "オンボーディング"
msgid "Once imported, repositories can be mirrored over SSH. Read more %{link_start}here%{link_end}."
-msgstr ""
+msgstr "インãƒãƒ¼ãƒˆã™ã‚‹ã¨ã€ãƒªãƒã‚¸ãƒˆãƒªã¯SSHã«ã‚ˆã‚ŠãƒŸãƒ©ãƒ¼ãƒªãƒ³ã‚°ã§ãã¾ã™ã€‚詳細㯠%{link_start}ã“ã¡ã‚‰%{link_end} ã‚’ã”覧ãã ã•ã„。"
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr "一度削除ã™ã‚‹ã¨ã€forkã®é–¢ä¿‚ã‚’å…ƒã«æˆ»ã™ã“ã¨ã¯ã§ããªããªã‚Šã¾ã™ã€‚ã¾ãŸã€ã‚ãªãŸã¯ãã®ã‚½ãƒ¼ã‚¹ã¸ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’é€ä¿¡ã§ããªããªã‚Šã¾ã™ã€‚"
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 "エクスãƒãƒ¼ãƒˆã•ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«ã®æº–å‚™ãŒã§ããŸã‚‰ã€ã‚ãªãŸã¯ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ãƒªãƒ³ã‚¯ä»˜ãã®é€šçŸ¥ãƒ¡ãƒ¼ãƒ«ã‚’å—ã‘å–ã‚Œã¾ã™ã€‚ã¾ãŸã¯ã“ã®ãƒšãƒ¼ã‚¸ã‹ã‚‰ãれをダウンロードã§ãã¾ã™ã€‚"
@@ -14197,10 +15060,10 @@ msgid_plural "%d more items"
msgstr[0] "ãã®ä»–ã®ã‚¢ã‚¤ãƒ†ãƒ ã®ä»¶æ•° %d"
msgid "One or more groups that you don't have access to."
-msgstr ""
+msgstr "アクセスã§ããªã„1ã¤ã¾ãŸã¯è¤‡æ•°ã®ã‚°ãƒ«ãƒ¼ãƒ—"
msgid "One or more of you personal access tokens were revoked"
-msgstr ""
+msgstr "一ã¤ä»¥ä¸Šã®ãƒ‘ーソナルアクセストークンを失効ã•ã›ã¾ã—ãŸ"
msgid "One or more of your Bitbucket projects cannot be imported into GitLab directly because they use Subversion or Mercurial for version control, rather than Git."
msgstr "1ã¤ä»¥ä¸Šã® Bitbucket プロジェクトを GitLab ã«ç›´æŽ¥ã‚¤ãƒ³ãƒãƒ¼ãƒˆã§ãã¾ã›ã‚“。ãƒãƒ¼ã‚¸ãƒ§ãƒ³ç®¡ç†ã«ã€Git ã§ã¯ãªãã€Subversion ã‚„ Mercurial を使用ã—ã¦ã„ã‚‹ã‹ã‚‰ã§ã™ã€‚"
@@ -14209,13 +15072,13 @@ msgid "One or more of your Google Code projects cannot be imported into GitLab d
msgstr "1ã¤ä»¥ä¸Šã® Google コードプロジェクトを GitLab ã«ç›´æŽ¥ã‚¤ãƒ³ãƒãƒ¼ãƒˆã§ãã¾ã›ã‚“。ãƒãƒ¼ã‚¸ãƒ§ãƒ³ç®¡ç†ã«ã€Git ã§ã¯ãªãã€Subversion ã‚„ Mercurial を使用ã—ã¦ã„ã‚‹ã‹ã‚‰ã§ã™ã€‚"
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 ""
+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 / Silver and above can see Value Stream Analytics."
-msgstr ""
+msgstr "ãƒãƒªãƒ¥ãƒ¼ã‚¹ãƒˆãƒªãƒ¼ãƒ åˆ†æžã‚’表示ã§ãã‚‹ã®ã¯ã€ãƒ—レミアム/シルãƒãƒ¼ä»¥ä¸Šã®éšŽå±¤ã®ã€Œãƒ¬ãƒãƒ¼ã‚¿ãƒ¼ã€ä»¥ä¸Šã®ãƒ­ãƒ¼ãƒ«ã®ã¿ã§ã™ã€‚"
msgid "Only 1 appearances row can exist"
msgstr ""
@@ -14224,7 +15087,7 @@ msgid "Only Issue ID or Merge Request ID is required"
msgstr ""
msgid "Only Project Members"
-msgstr ""
+msgstr "プロジェクトメンãƒãƒ¼ã®ã¿"
msgid "Only active this projects shows up in the search and on the dashboard."
msgstr ""
@@ -14233,10 +15096,10 @@ msgid "Only admins"
msgstr "管ç†è€…ã®ã¿"
msgid "Only admins can delete project"
-msgstr ""
+msgstr "管ç†è€…ã ã‘ãŒãƒ—ロジェクトを削除ã§ãã¾ã™"
msgid "Only mirror protected branches"
-msgstr ""
+msgstr "ä¿è­·ã•ã‚ŒãŸãƒ–ランãƒã®ã¿ãƒŸãƒ©ãƒ¼"
msgid "Only policy:"
msgstr "ãƒãƒªã‚·ãƒ¼ã®ã¿:"
@@ -14250,38 +15113,38 @@ msgstr "プロジェクトメンãƒãƒ¼ã®ã¿ã‚³ãƒ¡ãƒ³ãƒˆã§ãã¾ã™"
msgid "Only project members will be imported. Group members will be skipped."
msgstr "プロジェクトメンãƒãƒ¼ã®ã¿ãŒã‚¤ãƒ³ãƒãƒ¼ãƒˆã•ã‚Œã¾ã™ã€‚グループメンãƒãƒ¼ã¯ã‚¹ã‚­ãƒƒãƒ—ã•ã‚Œã¾ã™ã€‚"
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
-msgstr ""
+msgstr "生産性分æžã‚’表示ã§ãã‚‹ã®ã¯ã€ãƒ—レミアム/シルãƒãƒ¼ä»¥ä¸Šã®éšŽå±¤ã®ãƒ¬ãƒãƒ¼ã‚¿ãƒ¼ä»¥ä¸Šå½¹å‰²ã®ã¿ã§ã™ã€‚"
msgid "Oops, are you sure?"
msgstr "ãã‚Œã¯ã€æœ¬å½“ã§ã™ã‹ï¼Ÿ"
msgid "Open"
-msgstr "é–‹ã"
+msgstr "未解決(Open)"
msgid "Open Selection"
-msgstr ""
+msgstr "é¸æŠžæ¸ˆã¿ã®ã‚‚ã®ã‚’é–‹ã"
msgid "Open comment type dropdown"
msgstr "コメントタイプドロップダウンを開ã"
msgid "Open errors"
-msgstr ""
+msgstr "エラーを開ã"
msgid "Open in Xcode"
msgstr "Xcode ã§é–‹ã"
msgid "Open issues"
-msgstr ""
+msgstr "課題を開ã"
msgid "Open projects"
msgstr "プロジェクトを開ã"
msgid "Open raw"
-msgstr ""
+msgstr "ãã®ã¾ã¾é–‹ã"
msgid "Open sidebar"
msgstr "サイドãƒãƒ¼ã‚’é–‹ã"
@@ -14290,13 +15153,13 @@ msgid "Open: %{openIssuesCount}"
msgstr ""
msgid "Open: %{open} • Closed: %{closed}"
-msgstr ""
+msgstr "オープン: %{open} •クローズ: %{closed}"
msgid "Opened"
msgstr "オープン"
-msgid "Opened MR"
-msgstr "オープン中ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆ"
+msgid "Opened MRs"
+msgstr ""
msgid "Opened issues"
msgstr "オープン中ã®èª²é¡Œ"
@@ -14308,16 +15171,19 @@ msgid "Opens in a new window"
msgstr "æ–°è¦ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã§é–‹ã"
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
+msgstr "æ“作ã«å¤±æ•—ã—ã¾ã—ãŸã€‚ pod log ã® %{pod_name} ã§è©³ç´°ã‚’確èªã—ã¦ãã ã•ã„。"
+
+msgid "Operation not allowed"
msgstr ""
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
-msgstr ""
+msgstr "æ“作ãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ã¾ã—ãŸã€‚ pod log ã® %{pod_name} ã§è©³ç´°ã‚’確èªã—ã¦ãã ã•ã„。"
msgid "Operations"
msgstr "é‹ç”¨"
msgid "Operations Dashboard"
-msgstr ""
+msgstr "オペレーションダッシュボード"
msgid "Operations Settings"
msgstr "æ“作設定"
@@ -14340,7 +15206,7 @@ msgstr "オペレーションダッシュボードã¯å„プロジェクトé‹ç”¨
msgid "Optional"
msgstr "オプション"
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14356,7 +15222,7 @@ msgid "Or you can choose one of the suggested colors below"
msgstr "ã¾ãŸã¯ã€ä¸‹è¨˜ã®ã„ãšã‚Œã‹ã®è‰²ã‚’é¸æŠžã§ãã¾ã™"
msgid "Origin"
-msgstr ""
+msgstr "Origin"
msgid "Other Labels"
msgstr "ãã®ä»–ã®ãƒ©ãƒ™ãƒ«"
@@ -14368,7 +15234,7 @@ msgid "Other merge requests block this MR"
msgstr "ä»–ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã¯ã“ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’ブロックã—ã¾ã™"
msgid "Other visibility settings have been disabled by the administrator."
-msgstr ""
+msgstr "管ç†è€…ã«ã‚ˆã£ã¦ãã®ä»–ã®è¡¨ç¤ºè¨­å®šãŒç„¡åŠ¹ã«ã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "Out-of-compliance with this project's policies and should be removed"
msgstr ""
@@ -14388,6 +15254,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14398,7 +15267,7 @@ msgid "Overwrite diverged branches"
msgstr "分å²ã—ãŸãƒ–ランãƒã®ä¸Šæ›¸ã"
msgid "Owned by anyone"
-msgstr ""
+msgstr "誰ã‹ãŒæ‰€æœ‰"
msgid "Owned by me"
msgstr "ç§ãŒæ‰€æœ‰"
@@ -14406,25 +15275,34 @@ msgstr "ç§ãŒæ‰€æœ‰"
msgid "Owner"
msgstr "オーナー"
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr "パッケージレジストリ"
msgid "Package already exists"
-msgstr ""
+msgstr "パッケージã¯ã™ã§ã«ã‚ã‚Šã¾ã™"
msgid "Package deleted successfully"
-msgstr ""
+msgstr "パッケージã¯æ­£å¸¸ã«å‰Šé™¤ã•ã‚Œã¾ã—ãŸ"
msgid "Package information"
msgstr "パッケージ情報"
msgid "Package recipe already exists"
-msgstr ""
+msgstr "パッケージã®ãƒ¬ã‚·ãƒ”ã¯æ—¢ã«å­˜åœ¨ã—ã¦ã„ã¾ã™"
msgid "Package type must be Conan"
-msgstr ""
+msgstr "パッケージタイプ㌠Conan ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“"
msgid "Package type must be Maven"
+msgstr "パッケージタイプ㌠Maven ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“"
+
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
msgstr ""
msgid "Package was removed"
@@ -14437,34 +15315,34 @@ msgid "PackageRegistry|Add NuGet Source"
msgstr ""
msgid "PackageRegistry|Conan"
-msgstr ""
+msgstr "Conan"
msgid "PackageRegistry|Conan Command"
-msgstr ""
+msgstr "Conan コマンド"
msgid "PackageRegistry|Copy .pypirc content"
msgstr ""
msgid "PackageRegistry|Copy Conan Command"
-msgstr ""
+msgstr "Conan コマンドをコピー"
msgid "PackageRegistry|Copy Conan Setup Command"
-msgstr ""
+msgstr "Conan セットアップコマンドをコピー"
msgid "PackageRegistry|Copy Maven XML"
-msgstr ""
+msgstr "Maven XMLをコピー"
msgid "PackageRegistry|Copy Maven command"
-msgstr ""
+msgstr "Maven コマンドをコピー"
msgid "PackageRegistry|Copy Maven registry XML"
-msgstr ""
+msgstr "Maven レジストリ XMLをコピー"
msgid "PackageRegistry|Copy NuGet Command"
-msgstr ""
+msgstr "NuGet コマンドをコピー"
msgid "PackageRegistry|Copy NuGet Setup Command"
-msgstr ""
+msgstr "NuGet セットアップコマンドをコピー"
msgid "PackageRegistry|Copy Pip command"
msgstr ""
@@ -14473,22 +15351,22 @@ msgid "PackageRegistry|Copy and paste this inside your %{codeStart}pom.xml%{code
msgstr ""
msgid "PackageRegistry|Copy npm command"
-msgstr ""
+msgstr "npm コマンドをコピー"
msgid "PackageRegistry|Copy npm setup command"
-msgstr ""
+msgstr "npm セットアップコマンドをコピー"
msgid "PackageRegistry|Copy yarn command"
-msgstr ""
+msgstr "Yarn コマンドをコピー"
msgid "PackageRegistry|Copy yarn setup command"
-msgstr ""
+msgstr "Yarn 設定コマンドã®ã‚³ãƒ”ー"
msgid "PackageRegistry|Delete Package Version"
-msgstr ""
+msgstr "パッケージãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®å‰Šé™¤"
msgid "PackageRegistry|Delete package"
-msgstr ""
+msgstr "パッケージã®å‰Šé™¤"
msgid "PackageRegistry|Filter by name"
msgstr ""
@@ -14497,46 +15375,52 @@ msgid "PackageRegistry|For more information on the Conan registry, %{linkStart}s
msgstr ""
msgid "PackageRegistry|For more information on the Maven registry, %{linkStart}see the documentation%{linkEnd}."
-msgstr ""
+msgstr "Mavenã®ãƒ¬ã‚¸ã‚¹ãƒˆãƒªã®è©³ç´°ã«ã¤ã„ã¦ã¯ã€ %{linkStart}文書をå‚ç…§%{linkEnd}。"
msgid "PackageRegistry|For more information on the NuGet registry, %{linkStart}see the documentation%{linkEnd}."
msgstr ""
msgid "PackageRegistry|For more information on the PyPi registry, %{linkStart}see the documentation%{linkEnd}."
-msgstr ""
+msgstr "Pypiã®ãƒ¬ã‚¸ã‚¹ãƒˆãƒªã®è©³ç´°ã«ã¤ã„ã¦ã¯ã€ %{linkStart}ドキュメントをå‚ç…§%{linkEnd}。"
msgid "PackageRegistry|If you haven't already done so, you will need to add the below to your %{codeStart}.pypirc%{codeEnd} file."
msgstr ""
msgid "PackageRegistry|If you haven't already done so, you will need to add the below to your %{codeStart}pom.xml%{codeEnd} file."
-msgstr ""
+msgstr "ã¾ã è¡Œã£ã¦ã„ãªã„å ´åˆã¯ã€ %{codeStart}pom.xml%{codeEnd} ファイルã«ä»¥ä¸‹ã‚’追加ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "PackageRegistry|Installation"
+msgstr "インストール"
+
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
msgstr ""
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
-msgstr ""
+msgstr "GitLabã§%{noPackagesLinkStart}ã‚ãªãŸã®ãƒ‘ッケージを公開ã—共有%{noPackagesLinkEnd}ã™ã‚‹æ–¹æ³•ã‚’å­¦ã¶ã€‚"
msgid "PackageRegistry|Manually Published"
msgstr ""
msgid "PackageRegistry|Maven"
-msgstr ""
+msgstr "Maven"
msgid "PackageRegistry|Maven Command"
-msgstr ""
+msgstr "Maven コマンド"
msgid "PackageRegistry|Maven XML"
-msgstr ""
+msgstr "Maven XML"
msgid "PackageRegistry|NPM"
+msgstr "NPM"
+
+msgid "PackageRegistry|No upcoming issues"
msgstr ""
msgid "PackageRegistry|NuGet"
-msgstr ""
+msgstr "NuGet"
msgid "PackageRegistry|NuGet Command"
-msgstr ""
+msgstr "NuGet コマンド"
msgid "PackageRegistry|Pip Command"
msgstr ""
@@ -14551,10 +15435,10 @@ msgid "PackageRegistry|PyPi"
msgstr ""
msgid "PackageRegistry|Registry Setup"
-msgstr ""
+msgstr "レジストリ設定"
msgid "PackageRegistry|Remove package"
-msgstr ""
+msgstr "パッケージを削除"
msgid "PackageRegistry|Sorry, your filter produced no results"
msgstr ""
@@ -14562,47 +15446,62 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
+msgstr "パッケージã¯ã¾ã ã‚ã‚Šã¾ã›ã‚“"
+
+msgid "PackageRegistry|There are no upcoming issues to display."
msgstr ""
msgid "PackageRegistry|There was a problem fetching the details for this package."
+msgstr "ã“ã®ãƒ‘ッケージã®è©³ç´°ã®å–得中ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
+
+msgid "PackageRegistry|This NuGet package has no dependencies."
msgstr ""
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
+msgstr "パッケージを読ã¿è¾¼ã‚ã¾ã›ã‚“"
+
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
-msgstr ""
+msgstr "èªè¨¼ãƒˆãƒ¼ã‚¯ãƒ³ã‚’使用ã—ã¦èªè¨¼ã‚’設定ã™ã‚‹å¿…è¦ãŒã‚ã‚‹å ´åˆã‚‚ã‚ã‚Šã¾ã™ã€‚ %{linkStart}詳細ã«ã¤ã„ã¦ã¯ã€æ–‡æ›¸ %{linkEnd} ã‚’å‚ç…§ã—ã¦ãã ã•ã„。"
msgid "PackageRegistry|npm"
-msgstr ""
+msgstr "npm"
msgid "PackageRegistry|published by %{author}"
msgstr ""
msgid "PackageRegistry|yarn"
-msgstr ""
+msgstr "yarn"
msgid "PackageType|Conan"
-msgstr ""
+msgstr "Conan"
msgid "PackageType|Maven"
-msgstr ""
+msgstr "Maven"
msgid "PackageType|NPM"
-msgstr ""
+msgstr "NPM"
msgid "PackageType|NuGet"
-msgstr ""
+msgstr "NuGet"
msgid "PackageType|PyPi"
msgstr ""
@@ -14610,6 +15509,9 @@ msgstr ""
msgid "Packages"
msgstr "パッケージ"
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr "ページãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
@@ -14626,16 +15528,16 @@ msgid "Pages getting started guide"
msgstr "Pages 入門ガイド"
msgid "Pagination|Go to first page"
-msgstr ""
+msgstr "最åˆã®ãƒšãƒ¼ã‚¸ã¸"
msgid "Pagination|Go to last page"
-msgstr ""
+msgstr "最後ã®ãƒšãƒ¼ã‚¸ã¸"
msgid "Pagination|Go to next page"
-msgstr ""
+msgstr "次ã®ãƒšãƒ¼ã‚¸ã¸"
msgid "Pagination|Go to previous page"
-msgstr ""
+msgstr "å‰ã®ãƒšãƒ¼ã‚¸ã¸"
msgid "Pagination|Last »"
msgstr "最後 »"
@@ -14653,16 +15555,16 @@ msgid "Parameter"
msgstr "パラメーター"
msgid "Parameter \"job_id\" cannot exceed length of %{job_id_max_size}"
-msgstr ""
+msgstr "パラメーター \"job_id\"㯠%{job_id_max_size} 長を超ãˆã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
msgid "Parent"
-msgstr ""
+msgstr "親"
msgid "Parent epic doesn't exist."
-msgstr ""
+msgstr "親 epic ãŒã‚ã‚Šã¾ã›ã‚“。"
msgid "Parent epic is not present."
-msgstr ""
+msgstr "親エピックãŒã‚ã‚Šã¾ã›ã‚“。"
msgid "Part of merge request changes"
msgstr "マージリクエストã§ã®å¤‰æ›´ç®‡æ‰€"
@@ -14671,7 +15573,7 @@ msgid "Partial token for reference only"
msgstr ""
msgid "Participants"
-msgstr ""
+msgstr "å‚加者"
msgid "Passed"
msgstr ""
@@ -14683,7 +15585,7 @@ msgid "Password (optional)"
msgstr "パスワード (オプション)"
msgid "Password Policy Guidelines"
-msgstr ""
+msgstr "パスワードãƒãƒªã‚·ãƒ¼ã®ã‚¬ã‚¤ãƒ‰ãƒ©ã‚¤ãƒ³"
msgid "Password authentication is unavailable."
msgstr "パスワードèªè¨¼ã¯ã”利用ã§ãã¾ã›ã‚“。"
@@ -14697,11 +15599,14 @@ msgstr "パスワードãŒæ­£å¸¸ã«å¤‰æ›´ã•ã‚Œã¾ã—ãŸ"
msgid "Password was successfully updated. Please login with it"
msgstr "パスワードã¯æ­£å¸¸ã«æ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚æ–°ã—ã„パスワードã§ãƒ­ã‚°ã‚¤ãƒ³ã—ãªãŠã—ã¦ãã ã•ã„。"
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr "期é™åˆ‡ã‚Œ"
msgid "Paste a machine public key here. Read more about how to generate it"
-msgstr ""
+msgstr "マシンã®å…¬é–‹éµã‚’ã“ã“ã«è²¼ã‚Šä»˜ã‘ã¾ã™ã€‚生æˆæ–¹æ³•ã«ã¤ã„ã¦ã¯ã“ã¡ã‚‰ã‚’確èªã—ã¦ä¸‹ã•ã„。"
msgid "Paste a machine public key here. Read more about how to generate it %{link_start}here%{link_end}"
msgstr "マシンã®å…¬é–‹éµã‚’ã“ã“ã«è²¼ã‚Šä»˜ã‘ã¾ã™ã€‚生æˆæ–¹æ³•ã«ã¤ã„ã¦ã¯%{link_start}ã“ã¡ã‚‰%{link_end}を確èªã—ã¦ä¸‹ã•ã„。"
@@ -14713,6 +15618,9 @@ msgid "Paste issue link"
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'. Don't use your private SSH key."
+msgstr "ã‚ãªãŸã® SSH 公開éµã‚’貼り付ã‘ã¾ã™ã€‚ã“ã®éµã¯é€šå¸¸ã€ãƒ•ã‚¡ã‚¤ãƒ«~/.ssh/id_ed25519.pub' ã¾ãŸã¯ '~/.ssh/id_rsa.pub' 内ã«ã‚ã‚Šã€'ssh-ed25519' ã¾ãŸã¯ 'ssh-rsa' ã¨ã„ã†æ–‡å­—列ã‹ã‚‰å§‹ã¾ã‚Šã¾ã™ã€‚SSH ã®ç§˜å¯†éµã‚’使用ã—ãªã„よã†ã«ã—ã¦ãã ã•ã„。"
+
+msgid "Patch to apply"
msgstr ""
msgid "Path"
@@ -14722,7 +15630,7 @@ msgid "Path:"
msgstr "パス:"
msgid "Paths can contain wildcards, like */welcome"
-msgstr ""
+msgstr "パスã«ã¯ã€*/welcomeã®ã‚ˆã†ãªãƒ¯ã‚¤ãƒ«ãƒ‰ã‚«ãƒ¼ãƒ‰ã‚’å«ã‚ã‚‹ã“ã¨ãŒã§ãã¾ã™"
msgid "Pause"
msgstr "åœæ­¢"
@@ -14740,7 +15648,7 @@ msgid "People without permission will never get a notification and won't be able
msgstr "権é™ã®ãªã„ユーザーã¯ä¸€åˆ‡é€šçŸ¥ã‚’å—ã‘ã‚‹ã“ã¨ãŒãªãã€ã¾ãŸã‚³ãƒ¡ãƒ³ãƒˆã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã›ã‚“。"
msgid "People without permission will never get a notification."
-msgstr ""
+msgstr "権é™ã®ãªã„人ã«ã¯é€šçŸ¥ã—ã¾ã›ã‚“。"
msgid "Percent rollout (logged in users)"
msgstr ""
@@ -14752,38 +15660,41 @@ msgid "Perform advanced options such as changing path, transferring, exporting,
msgstr ""
msgid "Perform common operations on GitLab project"
-msgstr ""
+msgstr "GitLabプロジェクトã§ä¸€èˆ¬çš„ãªæ“作を実施"
msgid "Performance optimization"
msgstr "パフォーマンスã®æœ€é©åŒ–"
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
+msgstr "ダウンロード"
+
+msgid "PerformanceBar|Elasticsearch calls"
msgstr ""
msgid "PerformanceBar|Frontend resources"
-msgstr ""
+msgstr "フロントエンドリソース"
msgid "PerformanceBar|Gitaly calls"
msgstr "Gitalyリクエスト"
msgid "PerformanceBar|Redis calls"
-msgstr ""
+msgstr "Redis呼ã³å‡ºã—"
msgid "PerformanceBar|Rugged calls"
-msgstr ""
+msgstr "Rugged呼ã³å‡ºã—"
msgid "PerformanceBar|SQL queries"
-msgstr ""
+msgstr "SQLクエリ"
msgid "PerformanceBar|trace"
-msgstr ""
+msgstr "トレース"
msgid "Permissions"
msgstr "権é™"
-msgid "Permissions Help"
-msgstr "権é™ã®ãƒ˜ãƒ«ãƒ—"
-
msgid "Permissions, LFS, 2FA"
msgstr "パーミッションã€LFSã€2FA"
@@ -14805,9 +15716,6 @@ msgstr "Phabricatorタスク"
msgid "Pick a name"
msgstr "åå‰ã‚’é¸æŠž"
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr "PINコード"
@@ -14815,10 +15723,10 @@ msgid "Pipeline"
msgstr "パイプライン"
msgid "Pipeline %{label}"
-msgstr ""
+msgstr "パイプライン %{label}"
msgid "Pipeline %{label} for \"%{dataTitle}\""
-msgstr ""
+msgstr "%{dataTitle} ã®ãƒ‘イプライン %{label}"
msgid "Pipeline Schedule"
msgstr "パイプラインスケジュール"
@@ -14830,13 +15738,13 @@ msgid "Pipeline minutes quota"
msgstr ""
msgid "Pipeline subscriptions"
-msgstr ""
+msgstr "パイプラインã®ã‚µãƒ–スクリプション"
msgid "Pipeline triggers"
msgstr "パイプラインã®ãƒˆãƒªã‚¬ãƒ¼"
msgid "Pipeline: %{status}"
-msgstr ""
+msgstr "パイプライン: %{status}"
msgid "PipelineCharts|CI / CD Analytics"
msgstr ""
@@ -14890,7 +15798,7 @@ msgid "PipelineSheduleIntervalPattern|Custom"
msgstr "カスタム"
msgid "PipelineStatusTooltip|Pipeline: %{ciStatus}"
-msgstr ""
+msgstr "パイプライン: %{ciStatus}"
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr "パイプライン:%{ci_status}"
@@ -14914,6 +15822,9 @@ msgid "Pipelines for last year"
msgstr "昨年ã®ãƒ‘イプライン"
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
+msgstr "マージリクエストã®ãƒ‘イプラインãŒæ§‹æˆã•ã‚Œã¾ã—ãŸã€‚デタッãƒã•ã‚ŒãŸãƒ‘イプラインã¯ã€ãƒžãƒ¼ã‚¸çµæžœã«å¯¾ã—ã¦ã§ã¯ãªãã€ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã®ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã§å®Ÿè¡Œã•ã‚Œã¾ã™ã€‚詳細ã«ã¤ã„ã¦ã¯ã€ãƒžãƒ¼ã‚¸çµæžœã®ãƒ‘イプラインã®æ–‡æ›¸ã‚’ã”覧ãã ã•ã„。"
+
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
msgstr ""
msgid "Pipelines settings for '%{project_name}' were successfully updated."
@@ -14929,7 +15840,7 @@ msgid "Pipelines|CI Lint"
msgstr "CI Lint"
msgid "Pipelines|Child pipeline"
-msgstr ""
+msgstr "å­ãƒ‘イプライン"
msgid "Pipelines|Clear Runner Caches"
msgstr "Runner ã®ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’削除"
@@ -14968,23 +15879,32 @@ msgid "Pipelines|There was an error fetching the pipelines. Try again in a few m
msgstr "パイプラインをフェッãƒã™ã‚‹éš›ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã—ã°ã‚‰ãã—ã¦ã‹ã‚‰ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ã„ãŸã ãã‹ã€ã‚µãƒãƒ¼ãƒˆãƒãƒ¼ãƒ ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。"
msgid "Pipelines|This is a child pipeline within the parent pipeline"
-msgstr ""
+msgstr "ã“ã‚Œã¯è¦ªãƒ‘イプライン内ã«ã‚ã‚‹å­ãƒ‘イプラインã§ã™"
msgid "Pipelines|This project is not currently set up to run pipelines."
msgstr "ã“ã®ãƒ—ロジェクトã¯ç¾åœ¨ãƒ‘イプラインを実行ã™ã‚‹ã‚ˆã†ã«è¨­å®šã•ã‚Œã¦ã„ã¾ã›ã‚“。"
msgid "Pipelines|parent"
+msgstr "親"
+
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
msgstr ""
msgid "Pipeline|Commit"
msgstr "コミット"
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr "ã‚«ãƒãƒ¬ãƒƒã‚¸"
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -14997,13 +15917,28 @@ msgstr "期間"
msgid "Pipeline|Existing branch name or tag"
msgstr "既存ã®ãƒ–ランãƒåã¾ãŸã¯tag"
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
+msgstr "キー"
+
+msgid "Pipeline|Manual"
msgstr ""
msgid "Pipeline|Merge train pipeline"
-msgstr ""
+msgstr "マージトレインパイプライン"
msgid "Pipeline|Merged result pipeline"
+msgstr "マージçµæžœãƒ‘イプライン"
+
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
msgstr ""
msgid "Pipeline|Pipeline"
@@ -15012,15 +15947,24 @@ msgstr "パイプライン"
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr "パイプラインを実行"
msgid "Pipeline|Run for"
msgstr "実行対象"
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr "ブランãƒã®æ¤œç´¢"
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr "ã“ã®å®Ÿè¡Œã§ä½¿ç”¨ã•ã‚Œã‚‹å¤‰æ•°ã®å€¤ã‚’指定ã—ã¾ã™ã€‚ %{settings_link} ã§æŒ‡å®šã•ã‚ŒãŸå€¤ãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§ä½¿ç”¨ã•ã‚Œã¾ã™ã€‚"
@@ -15036,11 +15980,14 @@ msgstr "パイプラインã®åœæ­¢"
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr "#%{pipelineId} パイプラインをåœæ­¢ã—ã¾ã™ã‹ï¼Ÿ"
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr "トリガー"
msgid "Pipeline|Value"
-msgstr ""
+msgstr "値"
msgid "Pipeline|Variables"
msgstr "変数"
@@ -15072,6 +16019,12 @@ msgstr "プロジェクト管ç†ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢(ソースコミットエンãƒ
msgid "Plain diff"
msgstr "テキスト差分"
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr "PlantUML"
@@ -15079,13 +16032,13 @@ msgid "Play"
msgstr "実行"
msgid "Play all manual"
-msgstr ""
+msgstr "ã™ã¹ã¦ã®ãƒžãƒ‹ãƒ¥ã‚¢ãƒ«ã‚¸ãƒ§ãƒ–を実行"
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 "続ã‘ã‚‹å‰ã«ã€åˆ©ç”¨è¦ç´„ã«åŒæ„ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
@@ -15106,13 +16059,13 @@ msgid "Please check the configuration file to ensure that it is available and th
msgstr "設定ファイルをãƒã‚§ãƒƒã‚¯ã—ã¦ã€ãã‚ŒãŒä½¿ç”¨å¯èƒ½ã§ã‹ã¤ã€YAMLãŒæœ‰åŠ¹ã§ã‚ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„"
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 group URL with no special characters."
msgstr ""
msgid "Please complete your profile with email address"
-msgstr ""
+msgstr "ã‚ãªãŸã®ãƒ—ロフィールã«ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’記入ã—ã¦ã€ãƒ—ロファイルを完了ã—ã¦ãã ã•ã„"
msgid "Please convert them to %{link_to_git}, and go through the %{link_to_import_flow} again."
msgstr "ãれらを %{link_to_git} ã«å¤‰æ›ã—ã¦ã€å†ã³ %{link_to_import_flow} ã‚’è¡Œã£ã¦ãã ã•ã„。"
@@ -15165,11 +16118,14 @@ msgstr "ã“ã®ã‚¢ãƒ—リケーション㯠GitLab ãŒæä¾›ã—ã¦ã„ã¾ã›ã‚“。ã
msgid "Please provide a name"
msgstr "åå‰ã‚’入力ã—ã¦ãã ã•ã„"
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr "有効ãªãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’入力ã—ã¦ãã ã•ã„"
msgid "Please refer to <a href=\"%{docs_url}\">%{docs_url}</a>"
-msgstr ""
+msgstr "<a href=\"%{docs_url}\">%{docs_url}</a>ã‚’å‚ç…§ã—ã¦ãã ã•ã„"
msgid "Please retype the email address."
msgstr "メールアドレスをå†åº¦å…¥åŠ›ã—ã¦ãã ã•ã„。"
@@ -15208,13 +16164,13 @@ msgid "Please try again"
msgstr "ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„"
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
-msgstr ""
+msgstr "続行ã™ã‚‹ã«ã¯ %{phrase_code} を入力ã—ã¦ãã ã•ã„。キャンセルã™ã‚‹å ´åˆã¯ã“ã®ãƒ¢ãƒ¼ãƒ€ãƒ«ã‚’é–‰ã˜ã¦ãã ã•ã„。"
msgid "Please upgrade PostgreSQL to version 9.6 or greater. The status of the replication cannot be determined reliably with the current version."
msgstr "PostgreSQLã‚’ãƒãƒ¼ã‚¸ãƒ§ãƒ³9.6以é™ã«ã‚¢ãƒƒãƒ—グレードã—ã¦ãã ã•ã„。ç¾åœ¨ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ã€ãƒ¬ãƒ—リケーションã®çŠ¶æ…‹ã‚’確実ã«åˆ¤æ–­ã§ãã¾ã›ã‚“。"
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 "少々ãŠå¾…ã¡ãã ã•ã„。準備ãŒæ•´ã„次第ã“ã®ãƒšãƒ¼ã‚¸ã¯è‡ªå‹•çš„ã«æ›´æ–°ã•ã‚Œã¾ã™ã€‚"
@@ -15232,7 +16188,7 @@ msgid "Pod does not exist"
msgstr ""
msgid "Pod not found"
-msgstr ""
+msgstr "ãƒãƒƒãƒ‰ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
msgid "Pods in use"
msgstr "使用中ã®ãƒãƒƒãƒ‰"
@@ -15240,6 +16196,9 @@ msgstr "使用中ã®ãƒãƒƒãƒ‰"
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr "基本設定"
@@ -15250,34 +16209,34 @@ msgid "Preferences|Behavior"
msgstr "挙動"
msgid "Preferences|Choose between fixed (max. 1280px) and fluid (%{percentage}) application layout."
-msgstr ""
+msgstr "固定(最大1280ピクセル)ã¾ãŸã¯æµå‹•çš„(%{percentage})ã®ã„ãšã‚Œã‹ã®ã‚¢ãƒ—リケーションレイアウトをé¸æŠžã—ã¦ãã ã•ã„。"
msgid "Preferences|Choose what content you want to see on a project’s overview page."
-msgstr ""
+msgstr "プロジェクトã®æ¦‚è¦ãƒšãƒ¼ã‚¸ã«è¡¨ç¤ºã—ãŸã„コンテンツをé¸æŠžã—ã¾ã™ã€‚"
msgid "Preferences|Customize integrations with third party services."
-msgstr ""
+msgstr "サードパーティã®ã‚µãƒ¼ãƒ“スã¨ã®çµ±åˆã‚’カスタマイズ"
msgid "Preferences|Customize the appearance of the application header and navigation sidebar."
-msgstr ""
+msgstr "アプリケーションヘッダーã¨ãƒŠãƒ“ゲーションサイドãƒãƒ¼ã®å¤–観をカスタマイズã—ã¾ã™ã€‚"
msgid "Preferences|Default dashboard"
-msgstr ""
+msgstr "デフォルトダッシュボード"
msgid "Preferences|Display time in 24-hour format"
msgstr "時間を24時間形å¼ã§è¡¨ç¤ºã™ã‚‹"
msgid "Preferences|Enable integrated code intelligence on code views"
-msgstr ""
+msgstr "コードビューã§çµ±åˆã‚³ãƒ¼ãƒ‰ã‚¤ãƒ³ãƒ†ãƒªã‚¸ã‚§ãƒ³ã‚¹ã‚’有効ã«ã™ã‚‹"
msgid "Preferences|For example: 30 mins ago."
msgstr "例: 30分å‰"
msgid "Preferences|Integrations"
-msgstr ""
+msgstr "çµ±åˆ"
msgid "Preferences|Layout width"
-msgstr ""
+msgstr "レイアウトã®å¹…"
msgid "Preferences|Must be a number between %{min} and %{max}"
msgstr ""
@@ -15286,19 +16245,19 @@ msgid "Preferences|Navigation theme"
msgstr "ナビゲーションテーマ"
msgid "Preferences|Project overview content"
-msgstr ""
+msgstr "プロジェクト概è¦ã®å†…容"
msgid "Preferences|Render whitespace characters in the Web IDE"
-msgstr ""
+msgstr "Web IDEã§ç©ºç™½æ–‡å­—をレンダリング"
msgid "Preferences|Show whitespace changes in diffs"
-msgstr ""
+msgstr "空白をå«ã‚ãŸå·®åˆ†ã‚’表示"
msgid "Preferences|Sourcegraph"
-msgstr ""
+msgstr "Sourcegraph"
msgid "Preferences|Syntax highlighting theme"
-msgstr ""
+msgstr "シンタックスãƒã‚¤ãƒ©ã‚¤ãƒˆã®ãƒ†ãƒ¼ãƒž"
msgid "Preferences|Tab width"
msgstr ""
@@ -15310,10 +16269,10 @@ msgid "Preferences|This feature is experimental and translations are not complet
msgstr "ã“ã®æ©Ÿèƒ½ã¯å®Ÿé¨“çš„ãªã‚‚ã®ã§ã™ã€‚ã¾ãŸç¿»è¨³ã¯ã¾ã å®Œäº†ã—ã¦ã„ã¾ã›ã‚“"
msgid "Preferences|This setting allows you to customize the appearance of the syntax."
-msgstr ""
+msgstr "ã“ã®è¨­å®šã«ã‚ˆã‚Šã€æ§‹æ–‡ã®å¤–観をカスタマイズã§ãã¾ã™ã€‚"
msgid "Preferences|This setting allows you to customize the behavior of the system layout and default views."
-msgstr ""
+msgstr "ã“ã®è¨­å®šã«ã‚ˆã‚Šã€ã‚·ã‚¹ãƒ†ãƒ ãƒ¬ã‚¤ã‚¢ã‚¦ãƒˆã¨ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆãƒ“ューã®å‹•ä½œã‚’カスタマイズã§ãã¾ã™ã€‚"
msgid "Preferences|Time display"
msgstr "時間表示"
@@ -15330,6 +16289,9 @@ msgstr "相対時間を使用"
msgid "Press %{key}-C to copy"
msgstr "%{key} + C を押ã—ã¦ã‚³ãƒ”ーã™ã‚‹"
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15343,7 +16305,7 @@ msgid "Prevent environment from auto-stopping"
msgstr ""
msgid "Prevent users from changing their profile name"
-msgstr ""
+msgstr "ユーザーãŒãƒ—ロファイルåを変更ã§ããªã„よã†ã«è¨­å®šã™ã‚‹"
msgid "Prevent users from modifying merge request approvers list"
msgstr ""
@@ -15366,6 +16328,9 @@ msgstr "データ部ã®ãƒ—レビュー"
msgid "Previous Artifacts"
msgstr "å‰å›žã®æˆæžœç‰©"
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15400,7 +16365,7 @@ msgid "Private group(s)"
msgstr "éžå…¬é–‹ã‚°ãƒ«ãƒ¼ãƒ—"
msgid "Private profile"
-msgstr ""
+msgstr "éžå…¬é–‹ãƒ—ロフィール"
msgid "Private projects Minutes cost factor"
msgstr ""
@@ -15418,28 +16383,28 @@ msgid "Productivity Analytics"
msgstr "生産性分æž"
msgid "Productivity analytics can help identify the problems that are delaying your team"
-msgstr ""
+msgstr "生産性分æžã¯ã€ãƒãƒ¼ãƒ ãŒé…れるã•ã›ã¦ã„ã‚‹å•é¡Œã‚’特定ã™ã‚‹ãŸã‚ã«å½¹ç«‹ã¡ã¾ã™"
msgid "ProductivityAanalytics|Merge requests"
-msgstr ""
+msgstr "マージリクエスト"
msgid "ProductivityAanalytics|is earlier than the allowed minimum date"
-msgstr ""
+msgstr "許å¯ã•ã‚Œã¦ã„る最å°æ—¥æ•°ã‚ˆã‚Šã‚‚æ—©ã„"
msgid "ProductivityAnalytics|Ascending"
msgstr "昇順"
msgid "ProductivityAnalytics|Days"
-msgstr ""
+msgstr "æ—¥"
msgid "ProductivityAnalytics|Days to merge"
-msgstr ""
+msgstr "マージã™ã‚‹æ—¥"
msgid "ProductivityAnalytics|Descending"
msgstr "é™é †"
msgid "ProductivityAnalytics|Hours"
-msgstr ""
+msgstr "時間"
msgid "ProductivityAnalytics|List"
msgstr "リスト"
@@ -15448,10 +16413,10 @@ msgid "ProductivityAnalytics|Merge Requests"
msgstr "マージリクエスト"
msgid "ProductivityAnalytics|Merge date"
-msgstr ""
+msgstr "マージ日付"
msgid "ProductivityAnalytics|Merge requests"
-msgstr ""
+msgstr "マージリクエスト"
msgid "ProductivityAnalytics|Time to merge"
msgstr ""
@@ -15517,13 +16482,13 @@ msgid "Profiles|Choose to show contributions of private projects on your public
msgstr "プロジェクトã€ãƒªãƒã‚¸ãƒˆãƒªã¾ãŸã¯çµ„織情報ãªã—ã§ã€å…¬é–‹ãƒ—ロファイルã«éžå…¬é–‹ãƒ—ロジェクトã®æŠ•ç¨¿ã‚’表示ã™ã‚‹ã“ã¨ã‚’é¸æŠžã—ã¾ã™"
msgid "Profiles|City, country"
-msgstr ""
+msgstr "国ã€éƒ½é“府県"
msgid "Profiles|Clear status"
msgstr "ステータスをクリア"
msgid "Profiles|Click on icon to activate signin with one of the following services"
-msgstr ""
+msgstr "次ã®ã‚µãƒ¼ãƒ“スã®ä¸­ã‹ã‚‰ä¸€ã¤ã‚’é¸ã‚“ã§ã‚µã‚¤ãƒ³ã‚¤ãƒ³ã‚’開始ã—ã¦ãã ã•ã„"
msgid "Profiles|Commit email"
msgstr "コミットメール"
@@ -15585,9 +16550,6 @@ msgstr "フルãƒãƒ¼ãƒ "
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr "プロフィールã«å€‹äººçš„ãªã‚³ãƒ³ãƒˆãƒªãƒ“ューションをå«ã‚ã‚‹"
@@ -15633,14 +16595,11 @@ msgstr "組織"
msgid "Profiles|Path"
msgstr "パス"
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr "ã‚ãªãŸã®æ–°ã—ã„ã‚¢ãƒã‚¿ãƒ¼ã®ä½ç½®ã¨ã‚µã‚¤ã‚º"
msgid "Profiles|Primary email"
-msgstr ""
+msgstr "主ã«ä½¿ç”¨ã™ã‚‹ãƒ¡ãƒ¼ãƒ«"
msgid "Profiles|Private contributions"
msgstr "éžå…¬é–‹ã®è²¢çŒ®"
@@ -15667,13 +16626,13 @@ msgid "Profiles|Some options are unavailable for LDAP accounts"
msgstr "ã„ãã¤ã‹ã®ã‚ªãƒ—ションã¯LDAPアカウントã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“。"
msgid "Profiles|Static object token was successfully reset"
-msgstr ""
+msgstr "スタティックオブジェクトトークンを正常ã«ãƒªã‚»ãƒƒãƒˆã§ãã¾ã—ãŸ"
msgid "Profiles|Tell us about yourself in fewer than 250 characters"
msgstr "250文字未満ã§è‡ªå·±ç´¹ä»‹ã—ã¦ãã ã•ã„"
msgid "Profiles|The ability to update your name has been disabled by your administrator."
-msgstr ""
+msgstr "ã‚ãªãŸã®åå‰ã‚’æ›´æ–°ã™ã‚‹æ©Ÿèƒ½ã¯ã€ç®¡ç†è€…ã«ã‚ˆã£ã¦ç„¡åŠ¹ã«ã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "Profiles|The maximum file size allowed is 200KB."
msgstr "許å¯ã•ã‚Œã‚‹æœ€å¤§ãƒ•ã‚¡ã‚¤ãƒ«ã‚µã‚¤ã‚ºã¯200KBã§ã™ã€‚"
@@ -15685,7 +16644,7 @@ msgid "Profiles|This email will be displayed on your public profile"
msgstr "ã“ã®ãƒ¡ãƒ¼ãƒ«ã‚’ã‚ãªãŸã®å…¬é–‹ãƒ—ロフィールã«è¡¨ç¤ºã—ã¾ã™"
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 ""
+msgstr "ã“ã®é›»å­ãƒ¡ãƒ¼ãƒ«ã¯ã€ç·¨é›†ã‚„マージãªã©ã®Webベースã®æ“作ã«ä½¿ç”¨ã•ã‚Œã¾ã™ã€‚ %{commit_email_link_start} 詳細ã¯ã“ã¡ã‚‰ %{commit_email_link_end}"
msgid "Profiles|This emoji and message will appear on your profile and throughout the interface."
msgstr "ã“ã®çµµæ–‡å­—ã¨ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’ã‚ãªãŸã®ãƒ—ロフィールã¨ã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ã‚§ãƒ¼ã‚¹å…¨ä½“ã«è¡¨ç¤ºã—ã¾ã™ã€‚"
@@ -15694,7 +16653,7 @@ msgid "Profiles|This information will appear on your profile"
msgstr "ã“ã®æƒ…報をプロフィールã«è¡¨ç¤ºã—ã¾ã™"
msgid "Profiles|Time settings"
-msgstr ""
+msgstr "時間ã®è¨­å®š"
msgid "Profiles|Two-Factor Authentication"
msgstr "2è¦ç´ èªè¨¼"
@@ -15703,7 +16662,7 @@ msgid "Profiles|Type your %{confirmationValue} to confirm:"
msgstr "確èªã®ãŸã‚ %{confirmationValue} を入力ã—ã¦ãã ã•ã„:"
msgid "Profiles|Typically starts with \"ssh-ed25519 …\" or \"ssh-rsa …\""
-msgstr ""
+msgstr "典型的ã«ã¯ \"ssh-ed25519 …\"ã¾ãŸã¯ \"ssh-rsa …\"ã§å§‹ã¾ã‚Šã¾ã™"
msgid "Profiles|Update profile settings"
msgstr "プロファイル設定を更新"
@@ -15715,10 +16674,10 @@ msgid "Profiles|Upload new avatar"
msgstr "æ–°ã—ã„ã‚¢ãƒã‚¿ãƒ¼ã‚’アップロード"
msgid "Profiles|Use a private email - %{email}"
-msgstr ""
+msgstr "プライベートメールを使用ã™ã‚‹ - %{email}"
msgid "Profiles|User ID"
-msgstr ""
+msgstr "ユーザーID"
msgid "Profiles|Username change failed - %{message}"
msgstr "ユーザーåã®å¤‰æ›´ã«å¤±æ•—ã—ã¾ã—㟠- %{message}"
@@ -15733,7 +16692,7 @@ msgid "Profiles|What's your status?"
msgstr "ã‚ãªãŸã¯ã©ã‚“ãªã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã§ã™ã‹ï¼Ÿ"
msgid "Profiles|Who you represent or work for"
-msgstr ""
+msgstr "代表者ã¾ãŸã¯é›‡ç”¨è€…"
msgid "Profiles|You can change your avatar here"
msgstr "ã‚ãªãŸã®ã‚¢ãƒã‚¿ãƒ¼ã‚’変更ã§ãã¾ã™"
@@ -15742,7 +16701,7 @@ msgid "Profiles|You can change your avatar here or remove the current avatar to
msgstr "ã‚ãªãŸã®ã‚¢ãƒã‚¿ãƒ¼ã‚’変更ã™ã‚‹ã‹ã€ç¾åœ¨ã®ã‚¢ãƒã‚¿ãƒ¼ã‚’削除ã—㦠%{gravatar_link} ã«æˆ»ã›ã¾ã™ã€‚"
msgid "Profiles|You can set your current timezone here"
-msgstr ""
+msgstr "ç¾åœ¨ã®ã‚¿ã‚¤ãƒ ã‚¾ãƒ¼ãƒ³ã‚’ã“ã“ã§è¨­å®šã§ãã¾ã™"
msgid "Profiles|You can upload your avatar here"
msgstr "ã‚ãªãŸã®ã‚¢ãƒã‚¿ãƒ¼ã‚’アップロードã§ãã¾ã™"
@@ -15780,12 +16739,6 @@ msgstr "ã‚ãªãŸã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹"
msgid "Profiles|e.g. My MacBook key"
msgstr "例:MacBook ã®ã‚­ãƒ¼"
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr "ユーザーå"
@@ -15811,19 +16764,22 @@ msgid "Project"
msgstr "プロジェクト"
msgid "Project \"%{name}\" is no longer available. Select another project to continue."
-msgstr ""
+msgstr "プロジェクト \"%{name}\" ã¯åˆ©ç”¨ã§ããªããªã‚Šã¾ã—ãŸã€‚続ã‘ã‚‹ã«ã¯åˆ¥ã®ãƒ—ロジェクトをé¸æŠžã—ã¦ãã ã•ã„。"
msgid "Project %{project_repo} could not be found"
+msgstr "%{project_repo} プロジェクトã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
+
+msgid "Project & Group can not be assigned at the same time"
msgstr ""
msgid "Project '%{project_name}' is being imported."
-msgstr ""
+msgstr "'%{project_name}' プロジェクトã¯ã‚¤ãƒ³ãƒãƒ¼ãƒˆä¸­ã§ã™ã€‚"
msgid "Project '%{project_name}' is in the process of being deleted."
msgstr "プロジェクト '%{project_name}' ã¯å‰Šé™¤ä¸­ã§ã™ã€‚"
msgid "Project '%{project_name}' is restored."
-msgstr ""
+msgstr "'%{project_name}' プロジェクトを復元ã—ã¾ã—ãŸã€‚"
msgid "Project '%{project_name}' queued for deletion."
msgstr "'%{project_name}' プロジェクトã¯å‰Šé™¤å‡¦ç†å¾…ã¡ã§ã™ã€‚"
@@ -15835,6 +16791,9 @@ msgid "Project '%{project_name}' was successfully updated."
msgstr "'%{project_name}' プロジェクトã¯æ­£å¸¸ã«æ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚"
msgid "Project '%{project_name}' will be deleted on %{date}"
+msgstr "'%{project_name}' プロジェクトã¯%{date} ã«å‰Šé™¤ã—ã¾ã™ã€‚"
+
+msgid "Project Access Tokens"
msgstr ""
msgid "Project Audit Events"
@@ -15859,31 +16818,34 @@ msgid "Project already deleted"
msgstr "プロジェクトã¯æ—¢ã«å‰Šé™¤ã•ã‚Œã¦ã„ã¾ã™"
msgid "Project and wiki repositories"
-msgstr ""
+msgstr "プロジェクトã¨wikiã®ãƒªãƒã‚¸ãƒˆãƒª"
msgid "Project avatar"
msgstr "プロジェクトアãƒã‚¿ãƒ¼"
msgid "Project cannot be shared with the group it is in or one of its ancestors."
+msgstr "プロジェクトã¯ã€æ‰€å±žã™ã‚‹ã‚°ãƒ«ãƒ¼ãƒ—ã¾ãŸã¯ãã®å…ˆç¥–ã®1ã¤ã¨å…±æœ‰ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。"
+
+msgid "Project clone URL"
msgstr ""
msgid "Project configuration, including services"
-msgstr ""
+msgstr "プロジェクト構æˆ(サービスå«ã‚€)"
msgid "Project description (optional)"
-msgstr ""
+msgstr "プロジェクトã®èª¬æ˜Ž(オプション)"
msgid "Project details"
msgstr "プロジェクトã®è©³ç´°"
msgid "Project does not exist or you don't have permission to perform this action"
-msgstr ""
+msgstr "プロジェクトãŒå­˜åœ¨ã—ã¾ã›ã‚“。ã¾ãŸã¯ã€ã“ã®ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã‚’実行ã™ã‚‹æ¨©é™ãŒã‚ã‚Šã¾ã›ã‚“"
msgid "Project export could not be deleted."
msgstr "プロジェクトã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã‚’削除ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
msgid "Project export enabled"
-msgstr ""
+msgstr "プロジェクトã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã¯æœ‰åŠ¹"
msgid "Project export has been deleted."
msgstr "プロジェクトã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã‚’削除ã—ã¾ã—ãŸã€‚"
@@ -15891,15 +16853,18 @@ msgstr "プロジェクトã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã‚’削除ã—ã¾ã—ãŸã€‚"
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr "プロジェクトã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆãƒªãƒ³ã‚¯ã¯æœŸé™åˆ‡ã‚Œã«ãªã‚Šã¾ã—ãŸã€‚プロジェクト設定ã«ã¦æ–°ã—ãエクスãƒãƒ¼ãƒˆãƒªãƒ³ã‚¯ã‚’作æˆã—ã¦ãã ã•ã„。"
-msgid "Project export started. A download link will be sent by email."
-msgstr "プロジェクトã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã‚’開始ã—ã¾ã—ãŸã€‚ダウンロードã®ãƒªãƒ³ã‚¯ã¯ãƒ¡ãƒ¼ãƒ«ã§é€ä¿¡ã—ã¾ã™"
+msgid "Project export started. A download link will be sent by email and made available on this page."
+msgstr ""
msgid "Project has too many %{label_for_message} to search"
-msgstr ""
+msgstr "プロジェクトã¯%{label_for_message} ãŒå¤šã™ãŽã¦æ¤œç´¢ã§ãã¾ã›ã‚“"
msgid "Project members"
msgstr "プロジェクトメンãƒãƒ¼"
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr "プロジェクトå"
@@ -15922,10 +16887,10 @@ msgid "Project scanning help page"
msgstr ""
msgid "Project security status"
-msgstr ""
+msgstr "プロジェクトã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£çŠ¶æ…‹"
msgid "Project security status help page"
-msgstr ""
+msgstr "プロジェクトã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£çŠ¶æ…‹ã®ãƒ˜ãƒ«ãƒ—ページ"
msgid "Project slug"
msgstr ""
@@ -15937,7 +16902,7 @@ msgid "Project visibility level will be changed to match namespace rules when tr
msgstr "プロジェクトをグループã«è»¢é€ã—ãŸå ´åˆã€ãƒ—ロジェクトã®å¯è¦–性レベルãŒåå‰ç©ºé–“ã®ãƒ«ãƒ¼ãƒ«ã«åˆã‚ã›ã¦å¤‰æ›´ã•ã‚Œã¾ã™ã€‚"
msgid "Project: %{name}"
-msgstr ""
+msgstr "プロジェクト: %{name}"
msgid "ProjectActivityRSS|Subscribe"
msgstr "講読"
@@ -15985,7 +16950,7 @@ msgid "ProjectOverview|Starrers"
msgstr ""
msgid "ProjectOverview|Unstar"
-msgstr ""
+msgstr "ãŠæ°—ã«ã„ã‚Šã‹ã‚‰å¤–ã™"
msgid "ProjectOverview|You have reached your project limit"
msgstr "プロジェクトã®ä½œæˆåˆ¶é™ã«é”ã—ã¾ã—ãŸ"
@@ -16009,76 +16974,73 @@ msgid "ProjectService|%{service_title}: status on"
msgstr ""
msgid "ProjectService|Comment"
-msgstr ""
+msgstr "コメント"
msgid "ProjectService|Comment will be posted on each event"
-msgstr ""
-
-msgid "ProjectService|Last edit"
-msgstr ""
+msgstr "コメントã¯å„イベントã”ã¨ã«æŠ•ç¨¿ã•ã‚Œã¾ã™"
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
-msgstr ""
+msgstr "GitLabプロジェクト㮠%{project_name} ã§ä¸€èˆ¬çš„ãªæ“作を実行"
msgid "ProjectService|To set up this service:"
-msgstr ""
+msgstr "ã“ã®ã‚µãƒ¼ãƒ“スを設定ã™ã‚‹ã«ã¯:"
msgid "ProjectSettings|Additional merge request capabilities that influence how and when merges will be performed"
msgstr "マージをã„ã¤ã©ã®ã‚ˆã†ã«è¡Œã†ã‹ã«å½±éŸ¿ã‚’与ãˆã‚‹ã€è¿½åŠ ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆæ©Ÿèƒ½"
msgid "ProjectSettings|All discussions must be resolved"
-msgstr ""
+msgstr "ã™ã¹ã¦ã®ãƒ‡ã‚£ã‚¹ã‚«ãƒƒã‚·ãƒ§ãƒ³ãŒè§£æ±ºã—ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。"
msgid "ProjectSettings|Allow users to make copies of your repository to a new project"
-msgstr ""
+msgstr "ユーザーã«ã“ã®ãƒªãƒã‚¸ãƒˆãƒªã‚’コピーã—ã¦æ–°ã—ã„プロジェクトを作æˆã•ã›ã‚‹ã“ã¨ã‚’許å¯ã™ã‚‹"
msgid "ProjectSettings|Allow users to request access"
-msgstr ""
+msgstr "ユーザーãŒã‚¢ã‚¯ã‚»ã‚¹ã‚’リクエストã§ãるよã†ã«ã™ã‚‹"
msgid "ProjectSettings|Automatically resolve merge request diff discussions when they become outdated"
-msgstr ""
+msgstr "期é™åˆ‡ã‚Œã«ãªã£ãŸã¨ãã«ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã®å·®åˆ†ãƒ‡ã‚£ã‚¹ã‚«ãƒƒã‚·ãƒ§ãƒ³ã‚’自動的ã«è§£æ±ºã—ã¾ã™ã€‚"
msgid "ProjectSettings|Badges"
msgstr "ãƒãƒƒã‚¸"
msgid "ProjectSettings|Build, test, and deploy your changes"
-msgstr ""
+msgstr "変更をビルドã€ãƒ†ã‚¹ãƒˆã€ãƒ‡ãƒ—ロイã™ã‚‹"
msgid "ProjectSettings|Choose your merge method, merge options, merge checks, and merge suggestions."
-msgstr ""
+msgstr "マージã®æ–¹æ³•ã€ãƒžãƒ¼ã‚¸ã‚ªãƒ—ションã€ãƒžãƒ¼ã‚¸ãƒã‚§ãƒƒã‚¯ãŠã‚ˆã³ãƒžãƒ¼ã‚¸æ案をé¸æŠžã—ã¾ã™ã€‚"
msgid "ProjectSettings|Choose your merge method, merge options, merge checks, merge suggestions, and set up a default description template for merge requests."
-msgstr ""
+msgstr "マージ方法ã€ãƒžãƒ¼ã‚¸ã‚ªãƒ—ションã€ãƒžãƒ¼ã‚¸ãƒã‚§ãƒƒã‚¯ãŠã‚ˆã³ãƒžãƒ¼ã‚¸æ案をé¸æŠžã—ã€ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®èª¬æ˜Žãƒ†ãƒ³ãƒ—レートを設定ã—ã¾ã™ã€‚"
msgid "ProjectSettings|Contact an admin to change this setting."
msgstr "ã“ã®è¨­å®šã‚’変更ã™ã‚‹ã«ã¯ç®¡ç†è€…ã«é€£çµ¡ã—ã¦ãã ã•ã„。"
msgid "ProjectSettings|Container registry"
-msgstr ""
+msgstr "コンテナレジストリ"
msgid "ProjectSettings|Customize your project badges."
msgstr "ã‚ãªãŸã®ãƒ—ロジェクトãƒãƒƒã‚¸ã®ã‚«ã‚¹ã‚¿ãƒžã‚¤ã‚º"
msgid "ProjectSettings|Disable email notifications"
-msgstr ""
+msgstr "メール通知を無効ã«ã™ã‚‹"
msgid "ProjectSettings|Enable 'Delete source branch' option by default"
-msgstr ""
+msgstr "ソースブランãƒã®å‰Šé™¤ã®ã‚ªãƒ—ションをデフォルトã§æœ‰åŠ¹ã«ã™ã‚‹"
msgid "ProjectSettings|Every merge creates a merge commit"
msgstr "マージã”ã¨ã«ãƒžãƒ¼ã‚¸ã‚³ãƒŸãƒƒãƒˆãŒä½œæˆã•ã‚Œã¾ã™"
msgid "ProjectSettings|Every project can have its own space to store its Docker images"
-msgstr ""
+msgstr "ãã‚Œãžã‚Œã®ãƒ—ロジェクトã¯ã€Dockerイメージをä¿å­˜ã™ã‚‹ãŸã‚ã®å„自ã§ã‚¹ãƒšãƒ¼ã‚¹ã‚’æŒã¤ã“ã¨ãŒã§ãã¾ã™"
msgid "ProjectSettings|Every project can have its own space to store its packages"
-msgstr ""
+msgstr "ãã‚Œãžã‚Œã®ãƒ—ロジェクトã¯ã€ãƒ‘ッケージをä¿å­˜ã™ã‚‹ãŸã‚ã®ç‹¬è‡ªã®ã‚¹ãƒšãƒ¼ã‚¹ã‚’æŒã¤ã“ã¨ãŒã§ãã¾ã™"
msgid "ProjectSettings|Everyone"
-msgstr ""
+msgstr "全員"
msgid "ProjectSettings|Existing merge requests and protected branches are not affected"
-msgstr ""
+msgstr "既存ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã¨ä¿è­·ã•ã‚ŒãŸãƒ–ランãƒã¯å½±éŸ¿ã‚’å—ã‘ã¾ã›ã‚“"
msgid "ProjectSettings|Failed to protect the tag"
msgstr "tagã®ä¿è­·ã«å¤±æ•—ã—ã¾ã—ãŸ"
@@ -16093,16 +17055,16 @@ msgid "ProjectSettings|Fast-forward merges only"
msgstr "æ—©é€ã‚Šãƒžãƒ¼ã‚¸ã®ã¿"
msgid "ProjectSettings|Forks"
-msgstr ""
+msgstr "フォーク"
msgid "ProjectSettings|Git Large File Storage"
-msgstr ""
+msgstr "Git Large File Storage"
msgid "ProjectSettings|Internal"
-msgstr ""
+msgstr "内部"
msgid "ProjectSettings|Issues"
-msgstr ""
+msgstr "課題"
msgid "ProjectSettings|LFS objects from this repository are still available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
@@ -16111,94 +17073,97 @@ msgid "ProjectSettings|Learn more about badges."
msgstr "ãƒãƒƒã‚¸ã®è©³ç´°ã€‚"
msgid "ProjectSettings|Lightweight issue tracking system for this project"
-msgstr ""
+msgstr "ã“ã®ãƒ—ロジェクトã®è»½é‡ã®èª²é¡Œè¿½è·¡ã‚·ã‚¹ãƒ†ãƒ "
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files"
-msgstr ""
+msgstr "オーディオã€ãƒ“デオã€ã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯ã‚¹ãƒ•ã‚¡ã‚¤ãƒ«ãªã©ã®å¤§ããªãƒ•ã‚¡ã‚¤ãƒ«ã‚’管ç†ã—ã¾ã™"
msgid "ProjectSettings|Merge checks"
-msgstr ""
+msgstr "マージãƒã‚§ãƒƒã‚¯"
msgid "ProjectSettings|Merge commit"
-msgstr ""
+msgstr "マージコミット"
msgid "ProjectSettings|Merge commit with semi-linear history"
msgstr ""
msgid "ProjectSettings|Merge method"
-msgstr ""
+msgstr "マージ方法"
msgid "ProjectSettings|Merge options"
-msgstr ""
+msgstr "マージオプション"
msgid "ProjectSettings|Merge pipelines will try to validate the post-merge result prior to merging"
-msgstr ""
+msgstr "マージパイプラインã¯ãƒžãƒ¼ã‚¸ã‚’実行ã™ã‚‹å‰ã«ã€ãƒžãƒ¼ã‚¸ã®çµæžœã®æ¤œè¨¼ã‚’試ã¿ã¾ã™"
msgid "ProjectSettings|Merge requests"
-msgstr ""
+msgstr "マージリクエスト"
msgid "ProjectSettings|Merge suggestions"
-msgstr ""
+msgstr "マージæ案"
msgid "ProjectSettings|No merge commits are created"
-msgstr ""
+msgstr "マージコミットã¯ä½œæˆã•ã‚Œã¦ã„ã¾ã›ã‚“"
msgid "ProjectSettings|Note: the container registry is always visible when a project is public"
-msgstr ""
+msgstr "注:プロジェクトãŒå…¬é–‹ã®å ´åˆã€ã‚³ãƒ³ãƒ†ãƒŠãƒ¬ã‚¸ã‚¹ãƒˆãƒªã¯å¸¸ã«è¡¨ç¤ºã•ã‚Œã¾ã™"
msgid "ProjectSettings|Only signed commits can be pushed to this repository."
msgstr "ã“ã®ãƒªãƒã‚¸ãƒˆãƒªã«ã¯ç½²åã•ã‚ŒãŸã‚³ãƒŸãƒƒãƒˆã®ã¿ãƒ—ッシュã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
msgid "ProjectSettings|Packages"
-msgstr ""
+msgstr "パッケージ"
msgid "ProjectSettings|Pages"
-msgstr ""
+msgstr "ページ"
msgid "ProjectSettings|Pages for project documentation"
-msgstr ""
+msgstr "プロジェクト文書ã®ãƒšãƒ¼ã‚¸"
msgid "ProjectSettings|Pipelines"
-msgstr ""
+msgstr "パイプライン"
msgid "ProjectSettings|Pipelines must succeed"
msgstr "パイプラインã¯æˆåŠŸã—ãªã‘ã‚Œã°ãªã‚‰ãªã„"
msgid "ProjectSettings|Pipelines need to be configured to enable this feature."
-msgstr ""
+msgstr "ã“ã®æ©Ÿèƒ½ã‚’有効ã«ã™ã‚‹ã«ã¯ã€ãƒ‘イプラインを設定ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "ProjectSettings|Private"
-msgstr ""
+msgstr "éžå…¬é–‹"
msgid "ProjectSettings|Project visibility"
-msgstr ""
+msgstr "プロジェクトã®å¯è¦–性"
msgid "ProjectSettings|Public"
-msgstr ""
+msgstr "公開"
msgid "ProjectSettings|Repository"
-msgstr ""
+msgstr "リãƒã‚¸ãƒˆãƒª"
msgid "ProjectSettings|Share code pastes with others out of Git repository"
+msgstr "Gitリãƒã‚¸ãƒˆãƒªã‹ã‚‰ä»–ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¨ã‚³ãƒ¼ãƒ‰ãƒšãƒ¼ã‚¹ãƒˆã‚’共有ã™ã‚‹"
+
+msgid "ProjectSettings|Show default award emojis"
msgstr ""
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr "コマンドラインã‹ã‚‰ãƒ—ッシュã™ã‚‹ã¨ãã€ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’作æˆã¾ãŸã¯è¡¨ç¤ºã™ã‚‹ãŸã‚ã®ãƒªãƒ³ã‚¯ã‚’表示"
msgid "ProjectSettings|Snippets"
-msgstr ""
+msgstr "スニペット"
msgid "ProjectSettings|Submit changes to be merged upstream"
-msgstr ""
+msgstr "upstreamã«ãƒžãƒ¼ã‚¸ã™ã‚‹å¤‰æ›´ã‚’é€ä¿¡"
msgid "ProjectSettings|The commit message used to apply merge request suggestions"
-msgstr ""
+msgstr "マージリクエストæ案ã«é©ç”¨ã™ã‚‹ãŸã‚ã«ä½¿ç”¨ã™ã‚‹ã‚³ãƒŸãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸"
msgid "ProjectSettings|The variables GitLab supports:"
-msgstr ""
+msgstr "GitLab ã¯æ¬¡ã®å¤‰æ•°ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã™:"
msgid "ProjectSettings|These checks must pass before merge requests can be merged"
-msgstr ""
+msgstr "マージリクエストをマージã™ã‚‹å‰ã«ã€ã“れらã®ãƒã‚§ãƒƒã‚¯ã«åˆæ ¼ã—ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。"
msgid "ProjectSettings|This setting is applied on the server level and can be overridden by an admin."
msgstr "ã“ã®è¨­å®šã¯ã‚µãƒ¼ãƒãƒ¼ãƒ¬ãƒ™ãƒ«ã§é©ç”¨ã•ã‚Œã¦ãŠã‚Šã€ç®¡ç†è€…ãŒä¸Šæ›¸ãã§ãã¾ã™ã€‚"
@@ -16210,7 +17175,7 @@ msgid "ProjectSettings|This setting will be applied to all projects unless overr
msgstr "ã“ã®è¨­å®šã¯ã€ç®¡ç†è€…ãŒä¸Šæ›¸ãã—ãªã„å ´åˆã€ã™ã¹ã¦ã®ãƒ—ロジェクトã«é©ç”¨ã•ã‚Œã¾ã™ã€‚"
msgid "ProjectSettings|This setting will override user notification preferences for all project members."
-msgstr ""
+msgstr "ã“ã®è¨­å®šã¯ã€ã™ã¹ã¦ã®ãƒ—ロジェクトメンãƒãƒ¼ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼é€šçŸ¥è¨­å®šã‚’上書ãã—ã¾ã™ã€‚"
msgid "ProjectSettings|This will dictate the commit history when you merge a merge request"
msgstr "マージリクエストをマージã™ã‚‹ã¨ãã«ã‚³ãƒŸãƒƒãƒˆå±¥æ­´ã‚’記録ã—ã¾ã™"
@@ -16219,7 +17184,7 @@ msgid "ProjectSettings|Users can only push commits to this repository that were
msgstr "ユーザã¯æ¤œè¨¼æ¸ˆã¿ãƒ¡ãƒ¼ãƒ«ã®ã„ãšã‚Œã‹ã«ã‚ˆã‚‹ã‚³ãƒŸãƒƒãƒˆã—ãŸã€ã“ã®ãƒªãƒã‚¸ãƒˆãƒªã«ã‚³ãƒŸãƒƒãƒˆã‚’プッシュã§ãã¾ã™ã€‚"
msgid "ProjectSettings|View and edit files in this project"
-msgstr ""
+msgstr "ã“ã®ãƒ—ロジェクトã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’表示ãŠã‚ˆã³ç·¨é›†ã™ã‚‹"
msgid "ProjectSettings|View and edit files in this project. Non-project members will only have read access"
msgstr ""
@@ -16227,11 +17192,14 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr "競åˆãŒç™ºç”Ÿã—ãŸã¨ãã€ãƒ¦ãƒ¼ã‚¶ãƒ¼ã«ã¯ãƒªãƒ™ãƒ¼ã‚¹ã™ã‚‹ã‚ªãƒ—ションãŒä¸Žãˆã‚‰ã‚Œã¾ã™"
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr "Wiki"
msgid "ProjectSettings|With GitLab Pages you can host your static websites on GitLab"
-msgstr ""
+msgstr "GitLab Pagesを使用ã™ã‚‹ã¨ã€GitLab 上ã«é™çš„ãªWebサイトをホストã§ãã¾ã™"
msgid "ProjectSettings|With Metrics Dashboard you can visualize this project performance metrics"
msgstr ""
@@ -16291,10 +17259,10 @@ msgid "ProjectTemplates|Ruby on Rails"
msgstr "Ruby on Rails"
msgid "ProjectTemplates|SalesforceDX"
-msgstr ""
+msgstr "SalesforceDX"
msgid "ProjectTemplates|Serverless Framework/JS"
-msgstr ""
+msgstr "Serverless Framework / JS"
msgid "ProjectTemplates|Spring"
msgstr "Spring"
@@ -16309,13 +17277,13 @@ msgid "Projects"
msgstr "プロジェクト"
msgid "Projects (%{count})"
-msgstr ""
+msgstr "プロジェクト(%{count})"
msgid "Projects Successfully Retrieved"
msgstr "正常ã«å–å¾—ã—ãŸãƒ—ロジェクト"
msgid "Projects are graded based on the highest severity vulnerability present"
-msgstr ""
+msgstr "プロジェクトã¯ã€å­˜åœ¨ã™ã‚‹æœ€ã‚‚é‡è¦åº¦ã®é«˜ã„脆弱性ã«åŸºã¥ã„ã¦è©•ä¾¡ã•ã‚Œã¾ã™"
msgid "Projects shared with %{group_name}"
msgstr "%{group_name} グループã§å…±æœ‰ã•ã‚ŒãŸãƒ—ロジェクト"
@@ -16327,19 +17295,19 @@ msgid "Projects to index"
msgstr ""
msgid "Projects with critical vulnerabilities"
-msgstr ""
+msgstr "致命的ãªè„†å¼±æ€§ã®ã‚るプロジェクト"
msgid "Projects with high or unknown vulnerabilities"
-msgstr ""
+msgstr "高ã„脆弱性ãŒã‚ã‚‹ã¾ãŸã¯è„†å¼±æ€§ãŒä¸æ˜Žãªãƒ—ロジェクト"
msgid "Projects with low vulnerabilities"
-msgstr ""
+msgstr "低ã„脆弱性ã®ã‚るプロジェクト"
msgid "Projects with medium vulnerabilities"
-msgstr ""
+msgstr "中程度ã®è„†å¼±æ€§ã®ã‚るプロジェクト"
msgid "Projects with no vulnerabilities and security scanning enabled"
-msgstr ""
+msgstr "既知ã®è„†å¼±æ€§ãŒãªã„ã€ã¾ãŸã¯ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ã‚¹ã‚­ãƒ£ãƒ³ãŒæœ‰åŠ¹ã«ãªã£ã¦ã„ãªã„プロジェクト"
msgid "Projects with write access"
msgstr "書ãè¾¼ã¿æ¨©é™ã®ã‚るプロジェクト"
@@ -16366,58 +17334,61 @@ msgid "ProjectsDropdown|This feature requires browser localStorage support"
msgstr "ã“ã®æ©Ÿèƒ½ã«ã¯ãƒ–ラウザー㫠localStorage サãƒãƒ¼ãƒˆãŒå¿…è¦ã§ã™"
msgid "ProjectsNew|Allows you to immediately clone this project’s repository. Skip this if you plan to push up an existing repository."
-msgstr ""
+msgstr "ã“ã®ãƒ—ロジェクトã®ãƒªãƒã‚¸ãƒˆãƒªã®ã‚¯ãƒ­ãƒ¼ãƒ³ã‚’ã™ãã«ä½œæˆã§ãã¾ã™ã€‚既存ã®ãƒªãƒã‚¸ãƒˆãƒªã‚’プッシュã™ã‚‹å ´åˆã¯ã€ã“れをスキップã—ã¦ãã ã•ã„。"
msgid "ProjectsNew|Blank"
-msgstr ""
+msgstr "空"
msgid "ProjectsNew|Blank project"
-msgstr ""
+msgstr "空ã®ãƒ—ロジェクト"
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
+msgstr "管ç†è€…ã«é€£çµ¡ã—ã¦ã€ãƒ—ロジェクトをインãƒãƒ¼ãƒˆã™ã‚‹ãŸã‚ã®ã‚ªãƒ—ションを有効ã«ã—ã¦ãã ã•ã„。"
+
+msgid "ProjectsNew|Create"
msgstr ""
msgid "ProjectsNew|Create from template"
-msgstr ""
+msgstr "テンプレートã‹ã‚‰ä½œæˆ"
msgid "ProjectsNew|Creating project & repository."
-msgstr ""
+msgstr "プロジェクトã¨ãƒªãƒã‚¸ãƒˆãƒªã®ä½œæˆã€‚"
msgid "ProjectsNew|Description format"
-msgstr ""
+msgstr "説明フォーマット"
msgid "ProjectsNew|Import"
-msgstr ""
+msgstr "インãƒãƒ¼ãƒˆ"
msgid "ProjectsNew|Import project"
-msgstr ""
+msgstr "プロジェクトã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆ"
msgid "ProjectsNew|Initialize repository with a README"
-msgstr ""
+msgstr "リãƒã‚¸ãƒˆãƒªã‚’åˆæœŸåŒ–ã—READMEファイルを生æˆã™ã‚‹"
msgid "ProjectsNew|No import options available"
-msgstr ""
+msgstr "利用å¯èƒ½ãªã‚¤ãƒ³ãƒãƒ¼ãƒˆã‚ªãƒ—ションã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "ProjectsNew|Please wait a moment, this page will automatically refresh when ready."
-msgstr ""
+msgstr "少々ãŠå¾…ã¡ãã ã•ã„。準備ãŒæ•´ã„次第ã“ã®ãƒšãƒ¼ã‚¸ã¯è‡ªå‹•çš„ã«æ›´æ–°ã•ã‚Œã¾ã™ã€‚"
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
-msgstr ""
+msgstr "プロジェクトã®èª¬æ˜Ž%{tag_start}(オプション)%{tag_end}"
msgid "ProjectsNew|Template"
-msgstr ""
+msgstr "テンプレート"
msgid "ProjectsNew|Visibility Level"
-msgstr ""
+msgstr "å¯è¦–レベル"
msgid "ProjectsNew|Want to house several dependent projects under the same namespace? %{link_start}Create a group.%{link_end}"
-msgstr ""
+msgstr "åŒã˜åå‰ç©ºé–“ã®ä¸‹ã«ã„ãã¤ã‹ã®ä¾å­˜ãƒ—ロジェクトをåŽå®¹ã—ãŸã„ã§ã™ã‹ï¼Ÿ %{link_start}グループを作æˆã—ã¾ã™ã€‚%{link_end}"
msgid "Prometheus"
msgstr ""
msgid "PrometheusAlerts|%{count} alerts applied"
-msgstr ""
+msgstr "%{count} 件ã®ã‚¢ãƒ©ãƒ¼ãƒˆãŒé©ç”¨ã•ã‚Œã¾ã—ãŸ"
msgid "PrometheusAlerts|%{firingCount} firing"
msgstr ""
@@ -16470,17 +17441,23 @@ msgstr "自動設定"
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr "プロジェクト環境を監視ã™ã‚‹ãŸã‚ã€ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã« Prometheus を自動的ã«ãƒ‡ãƒ—ロイã—設定ã™ã‚‹"
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr "共通メトリクス"
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr "共通メトリクスã¯ã€ä¸€èˆ¬çš„ãªã‚¨ã‚¯ã‚¹ãƒãƒ¼ã‚¿ã‹ã‚‰ã®ãƒ¡ãƒˆãƒªã‚¯ã‚¹ã®ãƒ©ã‚¤ãƒ–ラリã«åŸºã¥ã„ã¦ã€è‡ªå‹•çš„ã«ç›£è¦–ã•ã‚Œã¾ã™ã€‚"
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr "カスタムメトリクス"
msgid "PrometheusService|Custom metrics require Prometheus installed on a cluster with environment scope \"*\" OR a manually configured Prometheus to be available."
-msgstr ""
+msgstr "カスタムメトリックを使用ã™ã‚‹ã«ã¯ã€ç’°å¢ƒã‚¹ã‚³ãƒ¼ãƒ—ãŒ\"*\"ã®ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚ŒãŸPrometheusã¾ãŸã¯æ‰‹å‹•ã§æ§‹æˆã•ã‚ŒãŸPrometheusãŒä½¿ç”¨å¯èƒ½ã§ã‚ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "PrometheusService|Enable Prometheus to define custom metrics, using either option above"
msgstr "上記ã®ã„ãšã‚Œã‹ã®ã‚ªãƒ—ションを使用ã—ã¦ã€ã‚«ã‚¹ã‚¿ãƒ ãƒ¡ãƒˆãƒªã‚¯ã‚¹ã‚’定義ã§ãるよã†ã«Prometheusを有効ã«ã™ã‚‹"
@@ -16513,7 +17490,7 @@ msgid "PrometheusService|New metric"
msgstr "æ–°è¦ãƒ¡ãƒˆãƒªã‚¯ã‚¹"
msgid "PrometheusService|No custom metrics have been created. Create one using the button above"
-msgstr ""
+msgstr "カスタムメトリックã¯ä½œæˆã•ã‚Œã¦ã„ã¾ã›ã‚“。 上ã®ãƒœã‚¿ãƒ³ã‚’使用ã—ã¦ä½œæˆã—ã¦ãã ã•ã„"
msgid "PrometheusService|Prometheus API Base URL, like http://prometheus.example.com/"
msgstr "Prometheus API ã®ãƒ™ãƒ¼ã‚¹ URLã€ä¾‹:http://prometheus.example.com/"
@@ -16546,14 +17523,11 @@ msgid "Promote confidential issue to a non-confidential epic"
msgstr ""
msgid "Promote issue to an epic"
-msgstr ""
+msgstr "課題をエピックã«æ˜‡æ ¼"
msgid "Promote these project milestones into a group milestone."
msgstr "ã“れらã®ãƒ—ロジェクトマイルストーンをグループマイルストーンã«æ˜‡æ ¼ã™ã‚‹"
-msgid "Promote to Group Milestone"
-msgstr "グループマイルストーンã«æ˜‡æ ¼"
-
msgid "Promote to group label"
msgstr "グループラベルã¸æ˜‡æ ¼"
@@ -16572,28 +17546,82 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr "次回ã‹ã‚‰ã¯ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’表示ã—ãªã„"
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 "エピックを使用ã™ã‚‹ã¨ã€ãƒ—ロジェクトやマイルストーンをã¾ãŸãŒã‚‹å…±é€šãƒ†ãƒ¼ãƒžã®èª²é¡Œã‚°ãƒ«ãƒ¼ãƒ—を追跡ã§ãã€ãƒ—ロジェクトã®ãƒãƒ¼ãƒˆãƒ•ã‚©ãƒªã‚ªã‚’より効率的ã«ç°¡å˜ã«ç®¡ç†ã§ãã¾ã™ã€‚"
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr "詳ã—ã見る"
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
+msgstr "%{subscription_link_start}ブロンズプラン%{subscription_link_end}ã®ä»–ã®æ©Ÿèƒ½ã‚’ã”覧ãã ã•ã„"
+
+msgid "Promotions|Start GitLab Ultimate trial"
msgstr ""
msgid "Promotions|This feature is locked."
msgstr "ã“ã®æ©Ÿèƒ½ã¯ãƒ­ãƒƒã‚¯ã•ã‚Œã¦ã„ã¾ã™ã€‚"
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr "プランをアップグレード"
-msgid "Promotions|Weighting your issue"
+msgid "Promotions|Upgrade your plan"
msgstr ""
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
+msgid "Promotions|Weighting your issue"
+msgstr "課題ã®é‡ã¿ä»˜ã‘"
+
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 "多ãã®èª²é¡ŒãŒã‚ã‚‹å ´åˆã€å…¨ä½“を把æ¡ã™ã‚‹ã®ã¯å›°é›£ã§ã™ã€‚ 課題ã«é‡ã¿ã‚’付ã‘ã‚‹ã“ã¨ã§ã€ãã‚Œãžã‚Œã®åŠ´åŠ›ã€ã‚³ã‚¹ãƒˆã€å¿…è¦ãªæ™‚é–“ã€ã¾ãŸã¯ä¾¡å€¤ã‚’よりよã把æ¡ã§ãã€ãれらをよりé©åˆ‡ã«ç®¡ç†ã§ãã¾ã™ã€‚"
+
+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 ""
msgid "Prompt users to upload SSH keys"
@@ -16615,61 +17643,61 @@ msgid "Protected Environments"
msgstr "ä¿è­·ã•ã‚ŒãŸç’°å¢ƒ"
msgid "Protected Paths"
-msgstr ""
+msgstr "ä¿è­·æ¸ˆã¿ã®ãƒ‘ス"
msgid "Protected Tag"
-msgstr ""
+msgstr "ä¿è­·æ¸ˆã¿ã®tag"
msgid "Protected branches"
-msgstr ""
+msgstr "ä¿è­·ã•ã‚ŒãŸãƒ–ランãƒ"
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 ""
+msgstr "%{code_tag_start} *-stable%{code_tag_end}ã¾ãŸã¯%{code_tag_start} production / *%{code_tag_end}ãªã©ã®%{wildcards_link_start} ワイルドカード%{wildcards_link_end}をサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã™"
msgid "ProtectedBranch|Allowed to merge"
-msgstr ""
+msgstr "マージを許å¯"
msgid "ProtectedBranch|Allowed to merge:"
-msgstr ""
+msgstr "マージを許å¯:"
msgid "ProtectedBranch|Allowed to push"
-msgstr ""
+msgstr "プッシュを許å¯"
msgid "ProtectedBranch|Allowed to push:"
-msgstr ""
+msgstr "プッシュを許å¯:"
msgid "ProtectedBranch|Branch"
-msgstr ""
+msgstr "ブランãƒ"
msgid "ProtectedBranch|Code owner approval"
-msgstr ""
+msgstr "コードオーナーã®æ‰¿èª"
msgid "ProtectedBranch|Protect"
-msgstr ""
+msgstr "ä¿è­·"
msgid "ProtectedBranch|Protect a branch"
-msgstr ""
+msgstr "ブランãƒã‚’ä¿è­·"
msgid "ProtectedBranch|Protected branch (%{protected_branches_count})"
-msgstr ""
+msgstr "ä¿è­·ã•ã‚ŒãŸãƒ–ランム(%{protected_branches_count})"
msgid "ProtectedBranch|Pushes that change filenames matched by the CODEOWNERS file will be rejected"
-msgstr ""
+msgstr "CODEOWNERSファイルã¨ä¸€è‡´ã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«åを変更ã™ã‚‹ãƒ—ッシュã¯æ‹’å¦ã•ã‚Œã¾ã™"
msgid "ProtectedBranch|Require approval from code owners:"
-msgstr ""
+msgstr "コード所有者ã®æ‰¿èªãŒå¿…è¦ï¼š"
msgid "ProtectedBranch|There are currently no protected branches, protect a branch with the form above."
-msgstr ""
+msgstr "ç¾åœ¨ä¿è­·ã•ã‚ŒãŸãƒ–ランãƒãŒã‚ã‚Šã¾ã›ã‚“。上ã®ãƒ•ã‚©ãƒ¼ãƒ ã§ãƒ–ランãƒã‚’ä¿è­·ã—ã¦ãã ã•ã„。"
msgid "ProtectedBranch|Toggle code owner approval"
-msgstr ""
+msgstr "コード所有者ã®æ‰¿èªã®åˆ‡ã‚Šæ›¿ãˆ"
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
-msgstr ""
+msgstr "%{environment_name} ã¯é–‹ç™ºè€…権é™ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒæ›¸ãè¾¼ã¿å¯èƒ½ã«ãªã‚Šã¾ã™ã€‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
msgid "ProtectedEnvironment|Allowed to deploy"
-msgstr ""
+msgstr "デプロイ許å¯"
msgid "ProtectedEnvironment|Environment"
msgstr "環境"
@@ -16690,10 +17718,10 @@ msgid "ProtectedEnvironment|Select an environment"
msgstr "環境をé¸æŠž"
msgid "ProtectedEnvironment|Select users"
-msgstr ""
+msgstr "ユーザーã®é¸æŠž"
msgid "ProtectedEnvironment|Select users to deploy and manage Feature Flag settings"
-msgstr ""
+msgstr "ユーザーをé¸æŠžã—ã¦ã€æ©Ÿèƒ½ãƒ•ãƒ©ã‚°è¨­å®šã‚’表示ã€ç®¡ç†ã—ã¾ã™ã€‚"
msgid "ProtectedEnvironment|There are currently no protected environments, protect an environment with the form above."
msgstr "ç¾åœ¨ä¿è­·ã•ã‚ŒãŸç’°å¢ƒã¯ã‚ã‚Šã¾ã›ã‚“。上ã®ãƒ•ã‚©ãƒ¼ãƒ ã§ç’°å¢ƒã‚’ä¿è­·ã—ã¦ãã ã•ã„。"
@@ -16731,11 +17759,8 @@ msgstr "公開- グループãŠã‚ˆã³å…¬é–‹ãƒ—ロジェクトã¯èªè¨¼ç„¡ã—ã§é
msgid "Public - The project can be accessed without any authentication."
msgstr "公開 - プロジェクトã¯èªè¨¼ç„¡ã—ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã™"
-msgid "Public Access Help"
-msgstr "公開アクセスã®ãƒ˜ãƒ«ãƒ—"
-
msgid "Public deploy keys (%{deploy_keys_count})"
-msgstr ""
+msgstr "公開デプロイキー (%{deploy_keys_count})"
msgid "Public pipelines"
msgstr "公開パイプライン"
@@ -16743,6 +17768,12 @@ msgstr "公開パイプライン"
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr "プル"
@@ -16759,19 +17790,19 @@ msgid "Push"
msgstr "プッシュ"
msgid "Push Rule updated successfully."
-msgstr ""
+msgstr "プッシュルールã¯æ­£å¸¸ã«æ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚"
msgid "Push Rules"
msgstr "プッシュルール"
msgid "Push Rules updated successfully."
-msgstr ""
+msgstr "プッシュルールã¯æ­£å¸¸ã«æ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚"
msgid "Push an existing Git repository"
-msgstr ""
+msgstr "既存ã®Gitリãƒã‚¸ãƒˆãƒªã¸ãƒ—ッシュ"
msgid "Push an existing folder"
-msgstr ""
+msgstr "既存ã®ãƒ•ã‚©ãƒ«ãƒ€ã‚’プッシュ"
msgid "Push events"
msgstr "プッシュイベント"
@@ -16792,43 +17823,43 @@ msgid "Pushes"
msgstr "プッシュ"
msgid "PushoverService|%{user_name} deleted branch \"%{ref}\"."
-msgstr ""
+msgstr "%{user_name} ãŒãƒ–ランム\"%{ref}\"を削除ã—ã¾ã—ãŸã€‚"
msgid "PushoverService|%{user_name} push to branch \"%{ref}\"."
-msgstr ""
+msgstr "%{user_name} ãŒãƒ–ランム\"%{ref}\"ã«ãƒ—ッシュã—ã¾ã™ã€‚"
msgid "PushoverService|%{user_name} pushed new branch \"%{ref}\"."
-msgstr ""
+msgstr "%{user_name} ãŒæ–°ã—ã„ブランム\"%{ref}\"をプッシュã—ã¾ã—ãŸã€‚"
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|Pushover makes it easy to get real-time notifications on your Android device, iPhone, iPad, and Desktop."
-msgstr ""
+msgstr "Pushover ã«ã‚ˆã£ã¦ã€ç°¡å˜ã«ã€ã‚ãªãŸã® Android デãƒã‚¤ã‚¹ã€iPhoneã€iPadã€ãã‚Œã«ãƒ‡ã‚¹ã‚¯ãƒˆãƒƒãƒ—ã«ãƒªã‚¢ãƒ«ã‚¿ã‚¤ãƒ é€šçŸ¥ã‚’é€ä¿¡ã§ãã¾ã™ã€‚"
msgid "PushoverService|See project %{project_full_name}"
-msgstr ""
+msgstr "%{project_full_name} プロジェクトをå‚ç…§"
msgid "PushoverService|Total commits count: %{total_commits_count}"
-msgstr ""
+msgstr "ç·ã‚³ãƒŸãƒƒãƒˆæ•°ï¼š %{total_commits_count}"
msgid "PushoverService|Your application key"
-msgstr ""
+msgstr "ã‚ãªãŸã®ã‚¢ãƒ—リケーションキー"
msgid "PushoverService|Your user key"
-msgstr ""
+msgstr "ã‚ãªãŸã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚­ãƒ¼"
msgid "Quarters"
msgstr "クォーター"
@@ -16837,14 +17868,17 @@ msgid "Query"
msgstr "クエリ"
msgid "Query cannot be processed"
-msgstr ""
+msgstr "クエリーを処ç†ã§ãã¾ã›ã‚“"
msgid "Query is valid"
-msgstr ""
+msgstr "クエリーã¯æœ‰åŠ¹ã§ã™"
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr "クイックアクションã¯èª²é¡Œã®èª¬æ˜Žã¨ã‚³ãƒ¡ãƒ³ãƒˆæ¬„ã§ä½¿ç”¨ã§ãã¾ã™ã€‚"
@@ -16854,17 +17888,14 @@ msgstr ""
msgid "README"
msgstr "README"
-msgid "Rake Tasks Help"
-msgstr "Rakeタスクã®ãƒ˜ãƒ«ãƒ—"
-
msgid "Raw blob request rate limit per minute"
msgstr ""
msgid "Re-authentication period expired or never requested. Please try again"
-msgstr ""
+msgstr "å†èªè¨¼æœŸé–“ãŒæº€äº†ã—ãŸã‹ã€ãƒªã‚¯ã‚¨ã‚¹ãƒˆã•ã‚Œã¾ã›ã‚“ã§ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„"
msgid "Re-authentication required"
-msgstr ""
+msgstr "å†èªè¨¼ãŒå¿…è¦ã§ã™"
msgid "Re-verification interval"
msgstr ""
@@ -16879,23 +17910,20 @@ msgid "Read more about project permissions <strong>%{link_to_help}</strong>"
msgstr "プロジェクトã®æ¨©é™ã«ã¤ã„ã¦ã¯ <strong>%{link_to_help}</strong> ã‚’å‚ç…§"
msgid "Read more about related issues"
-msgstr ""
+msgstr "関連ã™ã‚‹èª²é¡Œã«ã¤ã„ã¦ã‚‚ã£ã¨èª­ã‚€"
msgid "Real-time features"
msgstr "リアルタイム機能"
msgid "Rebase"
-msgstr ""
+msgstr "Rebase"
msgid "Rebase in progress"
-msgstr ""
+msgstr "進行中㮠Rebase"
msgid "Receive alerts from manually configured Prometheus servers."
msgstr "手動ã§è¨­å®šã—ãŸPrometheusサーãƒãƒ¼ã‹ã‚‰ã‚¢ãƒ©ãƒ¼ãƒˆã‚’å—ã‘å–る。"
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr "自身ã®ã‚¢ã‚¯ãƒ†ã‚£ãƒ“ティーã«é–¢ã™ã‚‹é€šçŸ¥ã‚’å—ä¿¡ã™ã‚‹"
@@ -16915,7 +17943,7 @@ msgid "Recent searches"
msgstr "最近ã®æ¤œç´¢"
msgid "Recipe"
-msgstr ""
+msgstr "レシピ"
msgid "Recover hidden stage"
msgstr ""
@@ -16927,10 +17955,10 @@ msgid "Redirect to SAML provider to test configuration"
msgstr "設定ã®ãƒ†ã‚¹ãƒˆã‚’実施ã™ã‚‹SAMLプロãƒã‚¤ãƒ€ã¸ãƒªãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆ"
msgid "Reduce project visibility"
-msgstr ""
+msgstr "プロジェクトã®å…¬é–‹ç¯„囲を狭ã‚ã‚‹"
msgid "Reduce this project’s visibility?"
-msgstr ""
+msgstr "ã“ã®ãƒ—ロジェクトã®å…¬é–‹ç¯„囲を狭ã‚ã¾ã™ã‹?"
msgid "Reference:"
msgstr "å‚ç…§:"
@@ -16946,7 +17974,7 @@ msgid "Regenerate export"
msgstr ""
msgid "Regenerate instance ID"
-msgstr ""
+msgstr "インスタンスIDã‚’å†ç”Ÿæˆ"
msgid "Regenerate key"
msgstr "éµã‚’å†ç”Ÿæˆã™ã‚‹"
@@ -16955,13 +17983,13 @@ msgid "Regenerate recovery codes"
msgstr "リカãƒãƒªãƒ¼ã‚³ãƒ¼ãƒ‰ã®å†ç™ºè¡Œ"
msgid "Regenerating the instance ID can break integration depending on the client you are using."
-msgstr ""
+msgstr "インスタンスIDã‚’å†ç”Ÿæˆã™ã‚‹ã¨ã€ä½¿ç”¨ã—ã¦ã„るクライアントã«ã‚ˆã£ã¦ã¯çµ±åˆãŒä¸­æ–­ã•ã‚Œã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™"
msgid "Regex pattern"
msgstr "æ­£è¦è¡¨ç¾ãƒ‘ターン"
msgid "Region that Elasticsearch is configured"
-msgstr ""
+msgstr "ElasticsearchãŒè¨­å®šã•ã‚Œã¦ã„る地域"
msgid "Register"
msgstr "登録"
@@ -16979,10 +18007,10 @@ msgid "Register Universal Two-Factor (U2F) Device"
msgstr "ユニãƒãƒ¼ã‚µãƒ«ãª2è¦ç´ èªè¨¼ãƒ‡ãƒã‚¤ã‚¹ã‚’登録ã™ã‚‹"
msgid "Register for GitLab"
-msgstr ""
+msgstr "GitLab ã«ç™»éŒ²ã™ã‚‹"
msgid "Register now"
-msgstr ""
+msgstr "今ã™ã登録"
msgid "Register with two-factor app"
msgstr "2è¦ç´ èªè¨¼ã‚¢ãƒ—リã§ç™»éŒ²"
@@ -16990,6 +18018,21 @@ msgstr "2è¦ç´ èªè¨¼ã‚¢ãƒ—リã§ç™»éŒ²"
msgid "Registration"
msgstr "登録"
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr "関連ã™ã‚‹ãƒ‡ãƒ—ロイ済ジョブ"
@@ -17013,10 +18056,10 @@ msgstr ""
msgid "Release"
msgid_plural "Releases"
-msgstr[0] ""
+msgstr[0] "リリース"
msgid "Release assets"
-msgstr ""
+msgstr "アセットをリリース"
msgid "Release assets documentation"
msgstr ""
@@ -17025,19 +18068,31 @@ msgid "Release does not have the same project as the milestone"
msgstr ""
msgid "Release notes"
-msgstr ""
+msgstr "リリースノート"
msgid "Release notes:"
-msgstr ""
+msgstr "リリースノート:"
msgid "Release title"
+msgstr "リリース タイトル"
+
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
msgstr ""
msgid "Releases"
msgstr "リリース"
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 ""
+msgstr "リリースã¯Gitã‚¿ã‚°ã«åŸºã¥ã„ã¦ãŠã‚Šã€ãƒ—ロジェクトã®é–‹ç™ºå±¥æ­´ã®ç‰¹å®šã®æ™‚点ã®æƒ…報を記録ã—ã¾ã™ã€‚変更ã®ç¨®é¡žã«é–¢ã™ã‚‹æƒ…報をå«ã‚ã‚‹ã“ã¨ãŒã§ãã€ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã®ã‚³ãƒ³ãƒ‘イル済ã¿ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãªã©ã®ãƒã‚¤ãƒŠãƒªã‚’æä¾›ã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚"
msgid "Releases are based on Git tags. We recommend tags that use semantic versioning, for example %{codeStart}v1.0%{codeEnd}, %{codeStart}v2.0-pre%{codeEnd}."
msgstr ""
@@ -17046,97 +18101,106 @@ msgid "Releases documentation"
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 "Remediated: needs review"
msgstr ""
-msgid "Remember me"
+msgid "Remediations"
msgstr ""
+msgid "Remember me"
+msgstr "ログイン情報を記憶ã™ã‚‹"
+
msgid "Remind later"
msgstr "後ã§é€šçŸ¥"
msgid "Remote object has no absolute path."
-msgstr ""
+msgstr "remoteオブジェクトã«çµ¶å¯¾ãƒ‘スãŒã‚ã‚Šã¾ã›ã‚“。"
msgid "Remove"
msgstr "削除"
msgid "Remove %{displayReference}"
-msgstr ""
+msgstr "%{displayReference} を削除"
msgid "Remove Runner"
msgstr "Runner を削除"
msgid "Remove Zoom meeting"
-msgstr ""
+msgstr "Zoom ミーティングを削除"
msgid "Remove all approvals in a merge request when new commits are pushed to its source branch"
msgstr "æ–°ã—ã„コミットãŒã‚½ãƒ¼ã‚¹ãƒ–ランãƒã«ãƒ—ッシュã•ã‚ŒãŸã¨ãã«ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã®ã™ã¹ã¦ã®æ‰¿èªã‚’削除ã™ã‚‹"
msgid "Remove all or specific assignee(s)"
-msgstr ""
+msgstr "ã™ã¹ã¦ã®æ‹…当者ã¾ãŸã¯ç‰¹å®šã®æ‹…当者を削除"
msgid "Remove all or specific label(s)"
-msgstr ""
+msgstr "ã™ã¹ã¦ã®ãƒ©ãƒ™ãƒ«ã¾ãŸã¯ç‰¹å®šã®ãƒ©ãƒ™ãƒ«ã‚’削除ã™ã‚‹"
msgid "Remove approvers"
-msgstr ""
+msgstr "承èªè€…を削除"
msgid "Remove approvers?"
-msgstr ""
+msgstr "承èªè€…を削除?"
msgid "Remove asset link"
msgstr ""
msgid "Remove assignee"
-msgstr ""
+msgstr "担当者ã®å‰Šé™¤"
msgid "Remove avatar"
msgstr "ã‚¢ãƒã‚¿ãƒ¼ã‚’削除"
msgid "Remove card"
-msgstr ""
+msgstr "カードã®å‰Šé™¤"
msgid "Remove child epic from an epic"
-msgstr ""
+msgstr "エピックã‹ã‚‰å­ã‚¨ãƒ”ックを削除"
msgid "Remove description history"
msgstr ""
msgid "Remove due date"
-msgstr ""
+msgstr "期日を削除"
msgid "Remove fork relationship"
-msgstr ""
+msgstr "フォークã®é–¢ä¿‚を削除"
msgid "Remove from board"
-msgstr ""
+msgstr "ボードã‹ã‚‰å‰Šé™¤"
msgid "Remove from epic"
-msgstr ""
+msgstr "エピックã‹ã‚‰å‰Šé™¤"
msgid "Remove group"
msgstr "グループを削除"
-msgid "Remove limit"
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
msgstr ""
+msgid "Remove limit"
+msgstr "制é™ã®è§£é™¤"
+
msgid "Remove milestone"
msgstr "マイルストーンを削除"
msgid "Remove node"
-msgstr ""
+msgstr "ノードを削除"
msgid "Remove parent epic from an epic"
-msgstr ""
+msgstr "エピックã‹ã‚‰è¦ªã‚¨ãƒ”ックを削除"
msgid "Remove primary node"
-msgstr ""
+msgstr "プライマリノードã®å‰Šé™¤"
msgid "Remove priority"
msgstr "優先度を削除"
@@ -17145,13 +18209,13 @@ msgid "Remove project"
msgstr "プロジェクトを削除"
msgid "Remove secondary node"
-msgstr ""
+msgstr "セカンダリノードã®å‰Šé™¤"
msgid "Remove spent time"
msgstr "作業時間ã®å‰Šé™¤"
msgid "Remove stage"
-msgstr ""
+msgstr "ステージã®å‰Šé™¤"
msgid "Remove time estimate"
msgstr "見ç©æ™‚間を削除"
@@ -17160,31 +18224,34 @@ msgid "Removed"
msgstr "除去ã—ã¾ã—ãŸ"
msgid "Removed %{assignee_text} %{assignee_references}."
-msgstr ""
+msgstr "%{assignee_text} %{assignee_references} を削除ã—ã¾ã—ãŸã€‚"
msgid "Removed %{epic_ref} from child epics."
+msgstr "å­ã‚¨ãƒ”ックã‹ã‚‰ %{epic_ref} を削除ã—ã¾ã—ãŸã€‚"
+
+msgid "Removed %{iteration_reference} iteration."
msgstr ""
msgid "Removed %{label_references} %{label_text}."
-msgstr ""
+msgstr "%{label_references} %{label_text} を削除ã—ã¾ã—ãŸã€‚"
msgid "Removed %{milestone_reference} milestone."
-msgstr ""
+msgstr "%{milestone_reference} マイルストーンを削除ã—ã¾ã—ãŸã€‚"
msgid "Removed %{type} with id %{id}"
msgstr "Id %{id} 㮠%{type} を削除"
msgid "Removed all labels."
-msgstr ""
+msgstr "ã™ã¹ã¦ã®ãƒ©ãƒ™ãƒ«ã‚’削除済ã¿"
msgid "Removed an issue from an epic."
-msgstr ""
+msgstr "課題をエピックã‹ã‚‰å‰Šé™¤ã—ã¾ã—ãŸã€‚"
msgid "Removed group can not be restored!"
msgstr "削除ã•ã‚ŒãŸã‚°ãƒ«ãƒ¼ãƒ—ã¯ãƒ¬ã‚¹ãƒˆã‚¢ã§ãã¾ã›ã‚“ï¼"
msgid "Removed parent epic %{epic_ref}."
-msgstr ""
+msgstr "親エピック %{epic_ref} を削除ã—ã¾ã—ãŸã€‚"
msgid "Removed projects cannot be restored!"
msgstr "削除ã•ã‚ŒãŸãƒ—ロジェクトã¯å¾©å…ƒã§ãã¾ã›ã‚“ï¼"
@@ -17196,16 +18263,19 @@ msgid "Removed the due date."
msgstr "期日を削除ã—ã¾ã—ãŸã€‚"
msgid "Removed time estimate."
-msgstr ""
+msgstr "見ç©æ™‚間を削除ã—ã¾ã—ãŸã€‚"
msgid "Removes %{assignee_text} %{assignee_references}."
-msgstr ""
+msgstr "%{assignee_text} %{assignee_references} を削除"
msgid "Removes %{epic_ref} from child epics."
+msgstr "å­ã‚¨ãƒ”ックã‹ã‚‰ %{epic_ref} を削除"
+
+msgid "Removes %{iteration_reference} iteration."
msgstr ""
msgid "Removes %{label_references} %{label_text}."
-msgstr ""
+msgstr "%{label_references} %{label_text} を削除ã—ã¾ã™ã€‚"
msgid "Removes %{milestone_reference} milestone."
msgstr "%{milestone_reference} マイルストーンを削除"
@@ -17214,10 +18284,10 @@ msgid "Removes all labels."
msgstr "ã™ã¹ã¦ã®ãƒ©ãƒ™ãƒ«ã‚’削除"
msgid "Removes an issue from an epic."
-msgstr ""
+msgstr "エピックã‹ã‚‰èª²é¡Œã‚’削除"
msgid "Removes parent epic %{epic_ref}."
-msgstr ""
+msgstr "親エピック %{epic_ref} を削除ã—ã¾ã™ã€‚"
msgid "Removes spent time."
msgstr "作業時間を削除ã—ã¾ã™ã€‚"
@@ -17229,13 +18299,13 @@ msgid "Removes time estimate."
msgstr "見ç©æ™‚間を削除."
msgid "Removing a project places it into a read-only state until %{date}, at which point the project will be permanantly removed. Are you ABSOLUTELY sure?"
-msgstr ""
+msgstr "プロジェクトを削除ã™ã‚‹ã¨ã€ãƒ—ロジェクト㯠%{date} ã¾ã§èª­ã¿å–り専用状態ã«ãªã‚Šã€ãã®æœŸæ—¥ã§ãƒ—ロジェクトã¯å®Œå…¨ã«å‰Šé™¤ã•ã‚Œã¾ã™ã€‚本当ã«ã‚ˆã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
msgid "Removing a project places it into a read-only state until %{date}, at which point the project will be permanently removed."
-msgstr ""
+msgstr "プロジェクトを削除ã™ã‚‹ã¨ã€ãƒ—ロジェクト㯠%{date} ã¾ã§èª­ã¿å–り専用状態ã«ãªã‚Šã€ãã®æœŸæ—¥ã§ãƒ—ロジェクトã¯å®Œå…¨ã«å‰Šé™¤ã•ã‚Œã¾ã™ã€‚"
msgid "Removing license…"
-msgstr ""
+msgstr "ライセンスã®å‰Šé™¤ä¸­..."
msgid "Removing the project will delete its repository and all related resources including issues, merge requests etc."
msgstr "プロジェクトを除去ã™ã‚‹ã¨ã€ãã®ãƒªãƒã‚¸ãƒˆãƒªã¨ã€èª²é¡Œã€ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆãªã©ã‚’å«ã‚€ã™ã¹ã¦ã®é–¢é€£ãƒªã‚½ãƒ¼ã‚¹ãŒå‰Šé™¤ã•ã‚Œã¾ã™"
@@ -17255,20 +18325,23 @@ msgstr ""
msgid "Reopen"
msgstr ""
-msgid "Reopen epic"
+msgid "Reopen %{display_issuable_type}"
msgstr ""
+msgid "Reopen epic"
+msgstr "エピックã®å†é–‹"
+
msgid "Reopen milestone"
msgstr "マイルストーンをå†é–‹"
msgid "Reopen this %{quick_action_target}"
-msgstr ""
+msgstr "ã“ã® %{quick_action_target} ã‚’å†ã³é–‹ã"
msgid "Reopened this %{quick_action_target}."
-msgstr ""
+msgstr "ã“ã® %{quick_action_target} ã‚’å†ã³é–‹ã„ãŸã€‚"
msgid "Reopens this %{quick_action_target}."
-msgstr ""
+msgstr "ã“ã® %{quick_action_target} ã‚’å†ã³é–‹ã。"
msgid "Repair authentication"
msgstr "èªè¨¼ã®ä¿®å¾©"
@@ -17283,10 +18356,13 @@ msgid "Replaced all labels with %{label_references} %{label_text}."
msgstr ""
msgid "Replaces the clone URL root."
+msgstr "クローンURLã®ãƒ«ãƒ¼ãƒˆã‚’ç½®ãæ›ãˆã‚‹ã€‚"
+
+msgid "Replication"
msgstr ""
msgid "Reply by email"
-msgstr ""
+msgstr "メールã¸ã®è¿”ä¿¡"
msgid "Reply to comment"
msgstr "コメントã«è¿”ä¿¡"
@@ -17300,7 +18376,10 @@ msgstr ""
msgid "Repo by URL"
msgstr "リãƒã‚¸ãƒˆãƒª URL"
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17356,7 +18435,7 @@ msgid "Reports|Failure"
msgstr "失敗"
msgid "Reports|Metrics reports are loading"
-msgstr ""
+msgstr "メトリクスレãƒãƒ¼ãƒˆã®èª­ã¿è¾¼ã¿ä¸­"
msgid "Reports|Metrics reports changed on %{numberOfChanges} %{pointsString}"
msgstr "メトリクスレãƒãƒ¼ãƒˆã¯ %{numberOfChanges}%{pointsString} 変更ã•ã‚Œã¾ã—ãŸ"
@@ -17365,7 +18444,7 @@ msgid "Reports|Metrics reports did not change"
msgstr "メトリクスレãƒãƒ¼ãƒˆã¯å¤‰æ›´ã•ã‚Œã¾ã›ã‚“ã§ã—ãŸã€‚"
msgid "Reports|Metrics reports failed loading results"
-msgstr ""
+msgstr "メトリクスレãƒãƒ¼ãƒˆã§çµæžœã®èª­ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ"
msgid "Reports|Severity"
msgstr ""
@@ -17374,28 +18453,28 @@ msgid "Reports|System output"
msgstr "システム出力"
msgid "Reports|Test summary"
-msgstr ""
+msgstr "テストã®è¦ç´„"
msgid "Reports|Test summary failed loading results"
-msgstr ""
+msgstr "テストè¦ç´„ã®çµæžœã®ãƒ­ãƒ¼ãƒ‰ã«å¤±æ•—"
msgid "Reports|Test summary results are being parsed"
-msgstr ""
+msgstr "テストè¦ç´„ã®çµæžœã¯ãƒ‘ースã•ã‚Œã¦ã„ã¾ã™"
msgid "Reports|Vulnerability"
msgstr "脆弱性"
msgid "Reports|no changed test results"
-msgstr ""
+msgstr "テストçµæžœã«å¤‰æ›´ã‚ã‚Šã¾ã›ã‚“。"
msgid "Repository"
msgstr "リãƒã‚¸ãƒˆãƒª"
msgid "Repository Analytics"
-msgstr ""
+msgstr "リãƒã‚¸ãƒˆãƒªã®åˆ†æž"
msgid "Repository Graph"
-msgstr ""
+msgstr "リãƒã‚¸ãƒˆãƒªã®ã‚°ãƒ©ãƒ•"
msgid "Repository Settings"
msgstr "リãƒã‚¸ãƒˆãƒªã®è¨­å®š"
@@ -17403,9 +18482,12 @@ msgstr "リãƒã‚¸ãƒˆãƒªã®è¨­å®š"
msgid "Repository URL"
msgstr "リãƒã‚¸ãƒˆãƒª URL"
-msgid "Repository check was triggered."
+msgid "Repository check"
msgstr ""
+msgid "Repository check was triggered."
+msgstr "リãƒã‚¸ãƒˆãƒªãƒã‚§ãƒƒã‚¯ã‚’自動的ã«é–‹å§‹ã—ã¾ã—ãŸã€‚"
+
msgid "Repository cleanup"
msgstr "リãƒã‚¸ãƒˆãƒªã®ã‚¯ãƒªãƒ¼ãƒ³ã‚¢ãƒƒãƒ—"
@@ -17419,16 +18501,16 @@ msgid "Repository maintenance"
msgstr "リãƒã‚¸ãƒˆãƒªã®ä¿å®ˆ"
msgid "Repository mirroring"
-msgstr ""
+msgstr "リãƒã‚¸ãƒˆãƒªã®ãƒŸãƒ©ãƒ¼ãƒªãƒ³ã‚°"
msgid "Repository static objects"
-msgstr ""
+msgstr "リãƒã‚¸ãƒˆãƒªé™çš„オブジェクト"
msgid "Repository storage"
msgstr "リãƒã‚¸ãƒˆãƒªã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸"
msgid "Repository sync capacity"
-msgstr ""
+msgstr "リãƒã‚¸ãƒˆãƒªåŒæœŸå®¹é‡"
msgid "Repository: %{counter_repositories} / Wikis: %{counter_wikis} / Build Artifacts: %{counter_build_artifacts} / LFS: %{counter_lfs_objects}"
msgstr ""
@@ -17439,11 +18521,14 @@ msgstr "é¸æŠž"
msgid "Request Access"
msgstr "アクセス権é™ã‚’リクエストã™ã‚‹"
-msgid "Request parameter %{param} is missing."
+msgid "Request Headers"
msgstr ""
+msgid "Request parameter %{param} is missing."
+msgstr "必須パラメーター %{param} ãŒã‚ã‚Šã¾ã›ã‚“。"
+
msgid "Request to link SAML account must be authorized"
-msgstr ""
+msgstr "SAMLアカウントをリンクã™ã‚‹ãƒªã‚¯ã‚¨ã‚¹ãƒˆã¯æ‰¿èªã•ã‚Œã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™"
msgid "Requested %{time_ago}"
msgstr "%{time_ago} ã«ãƒªã‚¯ã‚¨ã‚¹ãƒˆ"
@@ -17454,10 +18539,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17470,54 +18558,57 @@ msgid "Require user password to approve"
msgstr "承èªã®ãŸã‚ã«ãƒ¦ãƒ¼ã‚¶ãƒ¼ãƒ‘スワードをè¦æ±‚"
msgid "Require users to prove ownership of custom domains"
+msgstr "ユーザーã«ã‚«ã‚¹ã‚¿ãƒ ãƒ‰ãƒ¡ã‚¤ãƒ³ã®æ‰€æœ‰ã‚’証明ã™ã‚‹ã“ã¨ã‚’è¦æ±‚ã™ã‚‹"
+
+msgid "Required approvals (%{approvals_given} given)"
msgstr ""
-msgid "Requirement"
+msgid "Required approvals (%{approvals_given} given, you've approved)"
msgstr ""
+msgid "Requirement"
+msgstr "è¦æ±‚事項"
+
msgid "Requirement %{reference} has been added"
-msgstr ""
+msgstr "è¦ä»¶ã® %{reference} ãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸ"
msgid "Requirement %{reference} has been archived"
-msgstr ""
+msgstr "è¦ä»¶ã® %{reference} ㌠アーカイブã•ã‚Œã¾ã—ãŸ"
msgid "Requirement %{reference} has been reopened"
-msgstr ""
+msgstr "è¦ä»¶ã® %{reference} ãŒå†ã‚ªãƒ¼ãƒ—ンã•ã‚Œã¾ã—ãŸ"
msgid "Requirement %{reference} has been updated"
-msgstr ""
+msgstr "è¦ä»¶ã® %{reference} ãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸ"
msgid "Requirement title cannot have more than %{limit} characters."
msgstr ""
msgid "Requirements"
-msgstr ""
+msgstr "è¦æ±‚事項"
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
msgid_plural "Requires %{count} more approvals from %{names}."
-msgstr[0] ""
+msgstr[0] "%{names} ã‹ã‚‰ã® %{count} 件以上ã®æ‰¿èªãŒå¿…è¦ã§ã™ã€‚"
msgid "Requires approval."
msgid_plural "Requires %d more approvals."
msgstr[0] "もㆠ%d 件ã®æ‰¿èªãŒå¿…è¦ã§ã™ã€‚"
msgid "Requires values to meet regular expression requirements."
-msgstr ""
+msgstr "æ­£è¦è¡¨ç¾ã®æ¡ä»¶ã‚’満ãŸã™å€¤ãŒå¿…è¦ã§ã™ã€‚"
msgid "Resend confirmation email"
-msgstr ""
+msgstr "確èªãƒ¡ãƒ¼ãƒ«ã®å†é€ä¿¡"
msgid "Resend invite"
msgstr "招待をå†é€ä¿¡"
msgid "Resend it"
-msgstr ""
+msgstr "å†é€ã™ã‚‹"
msgid "Reset authorization key"
msgstr "èªè¨¼ã‚­ãƒ¼ã‚’リセット"
@@ -17535,25 +18626,25 @@ msgid "Reset runners registration token"
msgstr "Runner 登録トークンをリセット"
msgid "Reset template"
-msgstr ""
+msgstr "テンプレートã®ãƒªã‚»ãƒƒãƒˆ"
msgid "Resetting the authorization key for this project will require updating the authorization key in every alert source it is enabled in."
-msgstr ""
+msgstr "ã“ã®ãƒ—ロジェクトã®èªè¨¼ã‚­ãƒ¼ã‚’リセットã™ã‚‹ã«ã¯ã€æœ‰åŠ¹ã«ãªã£ã¦ã„ã‚‹ã™ã¹ã¦ã®ã‚¢ãƒ©ãƒ¼ãƒˆã‚½ãƒ¼ã‚¹ã§èªè¨¼ã‚­ãƒ¼ã‚’æ›´æ–°ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "Resetting the authorization key will invalidate the previous key. Existing alert configurations will need to be updated with the new key."
-msgstr ""
+msgstr "èªè¨¼ã‚­ãƒ¼ã‚’リセットã™ã‚‹ã¨ã€ä»Šã¾ã§ã®ã‚­ãƒ¼ã¯ç„¡åŠ¹ã«ãªã‚Šã¾ã™ã€‚既存ã®ã‚¢ãƒ©ãƒ¼ãƒˆè¨­å®šã¯æ–°ã—ã„キーã§æ›´æ–°ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "Resolve"
-msgstr ""
+msgstr "解決ã™ã‚‹"
msgid "Resolve all threads in new issue"
-msgstr ""
+msgstr "æ–°ã—ã„課題ã®ã™ã¹ã¦ã®ã‚¹ãƒ¬ãƒƒãƒ‰ã‚’解決ã™ã‚‹"
msgid "Resolve conflicts on source branch"
msgstr "ソースブランãƒã§ã®ç«¶åˆã‚’解決ã™ã‚‹"
msgid "Resolve thread"
-msgstr ""
+msgstr "スレッドを解決ã—ã¾ã™ã€‚"
msgid "Resolved"
msgstr "解決済ã¿"
@@ -17564,6 +18655,9 @@ msgstr "1件ã®æ¤œè¨Žã‚’解決ã—ã¾ã—ãŸã€‚"
msgid "Resolved all discussions."
msgstr "ã™ã¹ã¦ã®æ¤œè¨Žã‚’解決ã—ã¾ã—ãŸã€‚"
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr "%{name} ã«ã‚ˆã£ã¦è§£æ±º"
@@ -17571,11 +18665,17 @@ msgid "Resolved by %{resolvedByName}"
msgstr "%{resolvedByName} ã«ã‚ˆã£ã¦è§£æ±º"
msgid "Resolves IP addresses once and uses them to submit requests"
-msgstr ""
+msgstr "IPアドレスを一度解決ã—ã¦ã€ãれを使ã£ã¦ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’é€ä¿¡ã—ã¾ã™"
msgid "Response"
msgstr "レスãƒãƒ³ã‚¹"
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr "応答㫠`service_desk_address`ã¯å«ã¾ã‚Œã¦ã„ã¾ã›ã‚“ã§ã—ãŸ"
@@ -17601,10 +18701,10 @@ msgid "Restart Terminal"
msgstr "ターミナルをå†èµ·å‹•"
msgid "Restore group"
-msgstr ""
+msgstr "グループをレストア"
msgid "Restore project"
-msgstr ""
+msgstr "プロジェクトを復元ã™ã‚‹"
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -17613,10 +18713,10 @@ msgid "Restoring the project will prevent the project from being removed on this
msgstr ""
msgid "Restrict access by IP address"
-msgstr ""
+msgstr "IPアドレスã«ã‚ˆã‚‹ã‚¢ã‚¯ã‚»ã‚¹åˆ¶é™"
msgid "Restrict membership by email"
-msgstr ""
+msgstr "メールã§ãƒ¡ãƒ³ãƒãƒ¼ã‚’制é™ã™ã‚‹"
msgid "Restricts sign-ups for email addresses that match the given regex. See the %{supported_syntax_link_start}supported syntax%{supported_syntax_link_end} for more information."
msgstr ""
@@ -17628,7 +18728,7 @@ msgid "Resume replication"
msgstr "レプリケーションã®å†é–‹"
msgid "Resync"
-msgstr ""
+msgstr "å†åŒæœŸ"
msgid "Resync all"
msgstr ""
@@ -17646,7 +18746,7 @@ msgid "Retry this job in order to create the necessary resources."
msgstr "å¿…è¦ãªãƒªã‚½ãƒ¼ã‚¹ã‚’作æˆã™ã‚‹ãŸã‚ã«ã“ã®ã‚¸ãƒ§ãƒ–ã‚’å†è©¦è¡Œã—ã¦ãã ã•ã„。"
msgid "Retry update"
-msgstr ""
+msgstr "å†æ›´æ–°"
msgid "Retry verification"
msgstr "検証をå†è©¦è¡Œã—ã¦ãã ã•ã„"
@@ -17668,10 +18768,10 @@ msgid "Review"
msgstr "レビュー"
msgid "Review App|View app"
-msgstr ""
+msgstr "アプリを表示"
msgid "Review App|View latest app"
-msgstr ""
+msgstr "最新ã®ã‚¢ãƒ—リを表示"
msgid "Review the process for configuring service providers in your identity provider — in this case, GitLab is the \"service provider\" or \"relying party\"."
msgstr "ã‚ãªãŸã® ID プロãƒã‚¤ãƒ€ãƒ¼ã®ã‚µãƒ¼ãƒ“スプロãƒã‚¤ãƒ€ãƒ¼ã‚’構æˆã™ã‚‹ãŸã‚ã®ãƒ—ロセスを確èªã—ã¾ã™ã€‚ ã“ã®ä¾‹ã§ã¯ã€GitLab ã¯ã€Œã‚µãƒ¼ãƒ“スプロãƒã‚¤ãƒ€ãƒ¼ã€ã¾ãŸã¯ã€Œè¨¼æ˜Žæ›¸åˆ©ç”¨è€…ã€ã€‚"
@@ -17692,35 +18792,38 @@ msgid "Reviewing (merge request !%{mergeRequestId})"
msgstr "レビュー中 (マージリクエスト !%{mergeRequestId})"
msgid "Revoke"
-msgstr ""
+msgstr "失効"
msgid "Revoked impersonation token %{token_name}!"
-msgstr ""
+msgstr "代ç†ãƒˆãƒ¼ã‚¯ãƒ³ %{token_name} を無効ã«ã—ã¾ã—ãŸã€‚"
msgid "Revoked personal access token %{personal_access_token_name}!"
-msgstr ""
+msgstr "パーソナルアクセストークン㮠%{personal_access_token_name} を無効ã«ã—ã¾ã—ãŸã€‚"
msgid "Revoked project access token %{project_access_token_name}!"
-msgstr ""
+msgstr "プロジェクトã®ã‚¢ã‚¯ã‚»ã‚¹ãƒˆãƒ¼ã‚¯ãƒ³ %{project_access_token_name} を無効ã«ã—ã¾ã—ãŸã€‚"
msgid "RightSidebar|adding a"
-msgstr ""
+msgstr "追加中"
msgid "RightSidebar|deleting the"
-msgstr ""
+msgstr "削除中"
msgid "Roadmap"
msgstr "ロードマップ"
msgid "Role"
-msgstr ""
+msgstr "役割"
msgid "Rollback"
-msgstr ""
+msgstr "ロールãƒãƒƒã‚¯"
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17728,13 +18831,13 @@ msgid "Run CI/CD pipelines for external repositories"
msgstr "外部リãƒã‚¸ãƒˆãƒªç”¨ CI/CD パイプラインを実行"
msgid "Run housekeeping"
-msgstr ""
+msgstr "ãƒã‚¦ã‚¹ã‚­ãƒ¼ãƒ”ングを実行"
msgid "Run tests against your code live using the Web Terminal"
-msgstr ""
+msgstr "Webターミナルを使用ã—ã¦ãƒ†ã‚¹ãƒˆã‚’実行"
msgid "Run untagged jobs"
-msgstr ""
+msgstr "ã‚¿ã‚°ã®ãªã„ジョブã®å®Ÿè¡Œ"
msgid "Runner cannot be assigned to other projects"
msgstr "Runnerã‚’ä»–ã®ãƒ—ロジェクトã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¾ã›ã‚“"
@@ -17773,7 +18876,7 @@ msgid "Runners activated for this project"
msgstr "ã“ã®ãƒ—ロジェクト用ã«Runnerをアクティブ化"
msgid "Runners are processes that pick up and execute jobs for GitLab. Here you can register and see your Runners for this project."
-msgstr ""
+msgstr "Runner ã¯ã€GitLab ã®ã‚¸ãƒ§ãƒ–ã‚’å–å¾—ã—ã¦å®Ÿè¡Œã™ã‚‹ãƒ—ロセスã§ã™ã€‚ã“ã“ã§ã€ã“ã®ãƒ—ロジェクト㮠Runner を登録ã—ã¦ç¢ºèªã§ãã¾ã™ã€‚"
msgid "Runners can be placed on separate users, servers, and even on your local machine."
msgstr "Runner ã¯åˆ¥ã€…ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã€ã‚µãƒ¼ãƒãƒ¼ã€ã•ã‚‰ã«ã¯ã‚ãªãŸã®ãƒ­ãƒ¼ã‚«ãƒ«ãƒžã‚·ãƒ¼ãƒ³ã«ã‚‚é…ç½®ã§ãã¾ã™ã€‚"
@@ -17784,14 +18887,11 @@ msgstr "Runnerã¯åˆ¥ã€…ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã€ã‚µãƒ¼ãƒãƒ¼ã€ã•ã‚‰ã«ã¯ã‚ãªãŸã®
msgid "Runners currently online: %{active_runners_count}"
msgstr "ç¾åœ¨ã‚ªãƒ³ãƒ©ã‚¤ãƒ³ã®Runner: %{active_runners_count}"
-msgid "Runners page"
-msgstr "Runner ã®ãƒšãƒ¼ã‚¸"
-
msgid "Runners page."
msgstr "Runner ã®ãƒšãƒ¼ã‚¸ã€‚"
msgid "Runners|You have used %{quotaUsed} out of %{quotaLimit} of your shared Runners pipeline minutes."
-msgstr ""
+msgstr "Runners |共有ランナーパイプラインã®%{quotaLimit} ã®ã†ã¡%{quotaUsed} を使用ã—ã¾ã—ãŸã€‚"
msgid "Running"
msgstr "稼åƒä¸­"
@@ -17815,7 +18915,7 @@ msgid "SAML for %{group_name}"
msgstr "%{group_name} 用ã®SAML"
msgid "SHA256"
-msgstr ""
+msgstr "SHA256"
msgid "SSH Key"
msgstr "SSH éµ"
@@ -17823,26 +18923,23 @@ msgstr "SSH éµ"
msgid "SSH Keys"
msgstr "SSH éµ"
-msgid "SSH Keys Help"
-msgstr "SSHéµã®ãƒ˜ãƒ«ãƒ—"
-
msgid "SSH host key fingerprints"
-msgstr ""
+msgstr "SSH ホストéµã®ãƒ•ã‚£ãƒ³ã‚¬ãƒ¼ãƒ—リント"
msgid "SSH host keys"
msgstr "SSH ホストキー"
msgid "SSH host keys are not available on this system. Please use <code>ssh-keyscan</code> command or contact your GitLab administrator for more information."
-msgstr ""
+msgstr "ã“ã®ã‚·ã‚¹ãƒ†ãƒ ã§ã¯ SSH ホストéµã¯ä½¿ç”¨ã§ãã¾ã›ã‚“。 <code>ssh-keyscan</code> コマンドを使用ã™ã‚‹ã‹ã€GitLab ã®ç®¡ç†è€…ã«è©³ç´°ã‚’ãŠå•ã„åˆã‚ã›ãã ã•ã„。"
msgid "SSH keys allow you to establish a secure connection between your computer and GitLab."
-msgstr ""
+msgstr "SSH éµã‚’使用ã™ã‚‹ã¨ã€ã‚³ãƒ³ãƒ”ュータã¨GitLabã®é–“を安全ã«æŽ¥ç¶šã§ãã¾ã™ã€‚"
msgid "SSH public key"
msgstr "SSH 公開éµ"
msgid "SSL Verification:"
-msgstr ""
+msgstr "SSL ã®æ¤œè¨¼:"
msgid "Saturday"
msgstr "土曜日"
@@ -17869,7 +18966,7 @@ msgid "Save comment"
msgstr "コメントをä¿å­˜"
msgid "Save expiration policy"
-msgstr ""
+msgstr "有効期é™ãƒãƒªã‚·ãƒ¼ã®ä¿å­˜"
msgid "Save password"
msgstr "パスワードをä¿å­˜"
@@ -17878,13 +18975,13 @@ msgid "Save pipeline schedule"
msgstr "パイプラインスケジュールをä¿å­˜"
msgid "Save template"
-msgstr ""
+msgstr "テンプレートをä¿å­˜"
msgid "Save variables"
msgstr "変数をä¿å­˜ã™ã‚‹"
msgid "Saving"
-msgstr ""
+msgstr "ä¿å­˜ä¸­"
msgid "Saving project."
msgstr "プロジェクトをä¿å­˜"
@@ -17899,7 +18996,7 @@ msgid "Scheduled to merge this merge request (%{strategy})."
msgstr ""
msgid "Scheduled to merge this merge request when the pipeline succeeds."
-msgstr ""
+msgstr "パイプラインãŒæˆåŠŸã—ãŸã¨ãã«ã“ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’マージã™ã‚‹ã‚ˆã†ã«ã‚¹ã‚±ã‚¸ãƒ¥ãƒ¼ãƒ«ã—ã¾ã—ãŸ"
msgid "Schedules"
msgstr "スケジュール"
@@ -17923,22 +19020,22 @@ msgid "Scoped issue boards"
msgstr "スコープ付課題ボード"
msgid "Scopes"
-msgstr ""
+msgstr "スコープ"
msgid "Scopes can't be blank"
msgstr ""
msgid "Scroll down"
-msgstr ""
+msgstr "下ã¸ã‚¹ã‚¯ãƒ­ãƒ¼ãƒ«"
msgid "Scroll down to <strong>Google Code Project Hosting</strong> and enable the switch on the right."
msgstr "<strong>Google Code Project Hosting</strong> ã«ã‚¹ã‚¯ãƒ­ãƒ¼ãƒ«ã—ã€å³å´ã®ã‚¹ã‚¤ãƒƒãƒã‚’有効ã«ã—ã¾ã™ã€‚"
msgid "Scroll left"
-msgstr ""
+msgstr "å·¦ã¸ã‚¹ã‚¯ãƒ­ãƒ¼ãƒ«"
msgid "Scroll right"
-msgstr ""
+msgstr "å³ã¸ã‚¹ã‚¯ãƒ­ãƒ¼ãƒ«"
msgid "Scroll to bottom"
msgstr "最下部ã«ã‚¹ã‚¯ãƒ­ãƒ¼ãƒ«"
@@ -17947,17 +19044,23 @@ msgid "Scroll to top"
msgstr "最上部ã«ã‚¹ã‚¯ãƒ­ãƒ¼ãƒ«"
msgid "Scroll up"
-msgstr ""
+msgstr "上ã¸ã‚¹ã‚¯ãƒ­ãƒ¼ãƒ«"
msgid "Search"
msgstr "検索"
msgid "Search Button"
+msgstr "検索ボタン"
+
+msgid "Search Milestones"
msgstr ""
msgid "Search an environment spec"
msgstr "環境スペックを検索"
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr "ブランãƒã‚’検索"
@@ -17983,7 +19086,7 @@ msgid "Search for projects, issues, etc."
msgstr "プロジェクトや課題ãªã©ã‚’検索ã™ã‚‹ã€‚"
msgid "Search for this text"
-msgstr ""
+msgstr "ã“ã®ãƒ†ã‚­ã‚¹ãƒˆã‚’検索"
msgid "Search forks"
msgstr "フォークを検索ã™ã‚‹"
@@ -18015,6 +19118,9 @@ msgstr "プロジェクトを検索"
msgid "Search projects..."
msgstr "プロジェクトを検索..."
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr "ユーザーを検索"
@@ -18045,11 +19151,11 @@ msgstr "自身ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚ŒãŸãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆ"
msgid "SearchAutocomplete|in all GitLab"
msgstr "å…¨ã¦ã® GitLab 中ã§"
-msgid "SearchAutocomplete|in this group"
-msgstr "グループ内ã§"
+msgid "SearchAutocomplete|in group %{groupName}"
+msgstr ""
-msgid "SearchAutocomplete|in this project"
-msgstr "ã“ã®ãƒ—ロジェクト内ã§"
+msgid "SearchAutocomplete|in project %{projectName}"
+msgstr ""
msgid "SearchCodeResults|in"
msgstr ""
@@ -18064,53 +19170,53 @@ msgid "SearchResults|Showing %{count} %{scope} for%{term_element} in your person
msgstr ""
msgid "SearchResults|Showing %{from} - %{to} of %{count} %{scope} for%{term_element}"
-msgstr ""
+msgstr "%{from} ã‹ã‚‰ %{to} ã¾ã§ã®%{term_element}ã®%{count}%{scope} を表示ã—ã¦ã„ã¾ã™"
msgid "SearchResults|Showing %{from} - %{to} of %{count} %{scope} for%{term_element} in your personal and project snippets"
msgstr ""
msgid "SearchResults|We couldn't find any %{scope} matching %{term}"
-msgstr ""
+msgstr "%{term} ã«ä¸€è‡´ã™ã‚‹ %{scope} ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
msgid "SearchResults|code result"
msgid_plural "SearchResults|code results"
-msgstr[0] ""
+msgstr[0] "コードçµæžœ"
msgid "SearchResults|comment"
msgid_plural "SearchResults|comments"
-msgstr[0] ""
+msgstr[0] "コメント"
msgid "SearchResults|commit"
msgid_plural "SearchResults|commits"
-msgstr[0] ""
+msgstr[0] "コミット"
msgid "SearchResults|issue"
msgid_plural "SearchResults|issues"
-msgstr[0] ""
+msgstr[0] "課題"
msgid "SearchResults|merge request"
msgid_plural "SearchResults|merge requests"
-msgstr[0] ""
+msgstr[0] "マージリクエスト"
msgid "SearchResults|milestone"
msgid_plural "SearchResults|milestones"
-msgstr[0] ""
+msgstr[0] "マイルストーン"
msgid "SearchResults|project"
msgid_plural "SearchResults|projects"
-msgstr[0] ""
+msgstr[0] "プロジェクト"
msgid "SearchResults|snippet"
msgid_plural "SearchResults|snippets"
-msgstr[0] ""
+msgstr[0] "スニペット"
msgid "SearchResults|user"
msgid_plural "SearchResults|users"
-msgstr[0] ""
+msgstr[0] "ユーザー"
msgid "SearchResults|wiki result"
msgid_plural "SearchResults|wiki results"
-msgstr[0] ""
+msgstr[0] "Wikiã®çµæžœ"
msgid "Searching by both author and message is currently not supported."
msgstr ""
@@ -18122,29 +19228,32 @@ msgid "Seat Link is disabled, and cannot be configured through this form."
msgstr ""
msgid "Seats currently in use"
-msgstr ""
+msgstr "ç¾åœ¨ä½¿ç”¨ä¸­ã®ã‚·ãƒ¼ãƒˆ"
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
+msgstr "秘密"
+
+msgid "Secret Detection"
msgstr ""
msgid "Security"
msgstr "セキュリティ"
msgid "Security & Compliance"
-msgstr ""
+msgstr "セキュリティã¨ã‚³ãƒ³ãƒ—ライアンス"
msgid "Security Configuration"
-msgstr ""
+msgstr "セキュリティ設定"
msgid "Security Dashboard"
msgstr "セキュリティダッシュボード"
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr "セキュリティダッシュボード"
@@ -18154,22 +19263,22 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
-msgstr ""
+msgstr " %{featureName} ã®æ©Ÿèƒ½æ–‡æ›¸"
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
+msgstr "状態"
+
+msgid "SecurityConfiguration|Testing & Compliance"
msgstr ""
msgid "SecurityReports|%{firstProject} and %{secondProject}"
@@ -18307,6 +19416,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18371,7 +19483,7 @@ msgid "SecurityReports|[No reason]"
msgstr ""
msgid "See GitLab's %{password_policy_guidelines}"
-msgstr ""
+msgstr "GitLabã®%{password_policy_guidelines} ã‚’å‚ç…§"
msgid "See metrics"
msgstr "メトリクスをå‚ç…§"
@@ -18388,6 +19500,9 @@ msgstr "é¸æŠž"
msgid "Select Archive Format"
msgstr "アーカイブã®ãƒ•ã‚©ãƒ¼ãƒžãƒƒãƒˆã‚’é¸æŠž"
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr "Slackãƒãƒ¼ãƒ ã¨ãƒªãƒ³ã‚¯ã™ã‚‹ GitLab ã®ãƒ—ロジェクトをé¸æŠžã—ã¾ã™"
@@ -18398,13 +19513,13 @@ msgid "Select Stack"
msgstr "スタックã®é¸æŠž"
msgid "Select a file from the left sidebar to begin editing. Afterwards, you'll be able to commit your changes."
-msgstr ""
+msgstr "å·¦å´ã®ã‚µã‚¤ãƒ‰ãƒãƒ¼ã‹ã‚‰ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠžã—ã¦ç·¨é›†ã‚’開始ã—ã¾ã™ã€‚ãã®å¾Œã€å¤‰æ›´ã‚’コミットã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
msgid "Select a group to invite"
msgstr "招待ã™ã‚‹ãŸã‚ã®ã‚°ãƒ«ãƒ¼ãƒ—ã‚’é¸æŠžã™ã‚‹"
msgid "Select a label"
-msgstr ""
+msgstr "ラベルをé¸æŠž"
msgid "Select a namespace to fork the project"
msgstr "プロジェクトをフォークã™ã‚‹åå‰ç©ºé–“ã‚’é¸æŠžã—ã¦ãã ã•ã„"
@@ -18413,7 +19528,7 @@ msgid "Select a new namespace"
msgstr "æ–°ã—ã„åå‰ç©ºé–“ã‚’é¸æŠž"
msgid "Select a project"
-msgstr ""
+msgstr "プロジェクトã®é¸æŠž"
msgid "Select a project to read Insights configuration file"
msgstr "Insights構æˆãƒ•ã‚¡ã‚¤ãƒ«ã‚’読むプロジェクトをé¸æŠžã—ã¦ãã ã•ã„"
@@ -18428,26 +19543,32 @@ msgid "Select a template repository"
msgstr "テンプレートリãƒã‚¸ãƒˆãƒªã‚’é¸æŠž"
msgid "Select a template type"
-msgstr ""
+msgstr "テンプレートタイプをé¸æŠž"
msgid "Select a timezone"
msgstr "タイムゾーンをé¸æŠž"
msgid "Select all"
-msgstr ""
+msgstr "ã™ã¹ã¦é¸æŠž"
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr "既存㮠Kubernetes クラスターをé¸æŠžã™ã‚‹ã‹ã€æ–°ã—ã„ã‚‚ã®ã‚’作æˆ"
-msgid "Select branch"
+msgid "Select assignee"
msgstr ""
+msgid "Select branch"
+msgstr "ブランãƒã®é¸æŠž"
+
msgid "Select branch/tag"
msgstr "ブランãƒãƒ»ã‚¿ã‚°é¸æŠž"
-msgid "Select group or project"
+msgid "Select due date"
msgstr ""
+msgid "Select group or project"
+msgstr "グループã¾ãŸã¯ãƒ—ロジェクトをé¸æŠž"
+
msgid "Select groups to replicate"
msgstr ""
@@ -18455,16 +19576,16 @@ msgid "Select health status"
msgstr ""
msgid "Select labels"
-msgstr ""
+msgstr "ラベルをé¸æŠž"
msgid "Select merge moment"
msgstr ""
msgid "Select milestone"
-msgstr ""
+msgstr "マイルストーンをé¸æŠž"
msgid "Select private project"
-msgstr ""
+msgstr "éžå…¬é–‹ãƒ—ロジェクトã®é¸æŠž"
msgid "Select project"
msgstr "プロジェクトã®é¸æŠž"
@@ -18476,7 +19597,7 @@ msgid "Select project to choose zone"
msgstr "プロジェクトをé¸æŠžã—ã¦ã‚¾ãƒ¼ãƒ³ã‚’é¸æŠž"
msgid "Select projects"
-msgstr ""
+msgstr "プロジェクトã®é¸æŠž"
msgid "Select projects you want to import."
msgstr "インãƒãƒ¼ãƒˆå¯¾è±¡ã®ãƒ—ロジェクトをé¸æŠžã—ã¾ã™ã€‚"
@@ -18490,9 +19611,18 @@ msgstr ""
msgid "Select source branch"
msgstr "ソースブランãƒã‚’é¸æŠž"
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr "ターゲットブランãƒã‚’é¸æŠž"
@@ -18509,7 +19639,7 @@ msgid "Select timeframe"
msgstr ""
msgid "Select user"
-msgstr ""
+msgstr "ユーザをé¸æŠž"
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 "é¸æŠžã—ãŸãƒ¬ãƒ™ãƒ«ã¯ã€ç®¡ç†è€…以外ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒã‚°ãƒ«ãƒ¼ãƒ—ã€ãƒ—ロジェクトã€ã¾ãŸã¯ã‚¹ãƒ‹ãƒšãƒƒãƒˆã«ä½¿ç”¨ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。公開レベルãŒåˆ¶é™ã•ã‚Œã¦ã„ã‚‹å ´åˆã€ãƒ¦ãƒ¼ã‚¶ãƒ¼ãƒ—ロファイルã¯ãƒ­ã‚°ã‚¤ãƒ³ãƒ¦ãƒ¼ã‚¶ãƒ¼ã«ã®ã¿è¡¨ç¤ºã•ã‚Œã¾ã™ã€‚"
@@ -18521,61 +19651,67 @@ msgid "Selective synchronization"
msgstr ""
msgid "Self monitoring project does not exist"
-msgstr ""
+msgstr "自己監視プロジェクトã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "Self-monitoring project does not exist. Please check logs for any error messages"
-msgstr ""
+msgstr "自己監視プロジェクトã¯å­˜åœ¨ã—ã¾ã›ã‚“。ログを調ã¹ã‚¨ãƒ©ãƒ¼ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’確èªã—ã¦ãã ã•ã„"
msgid "Self-monitoring project has been successfully deleted"
-msgstr ""
+msgstr "自己監視プロジェクトãŒæ­£å¸¸ã«å‰Šé™¤ã•ã‚Œã¾ã—ãŸ"
msgid "Self-monitoring project was not deleted. Please check logs for any error messages"
-msgstr ""
+msgstr "自己監視プロジェクトã¯å‰Šé™¤ã•ã‚Œã¾ã›ã‚“ã§ã—ãŸã€‚ログを調ã¹ã‚¨ãƒ©ãƒ¼ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’確èªã—ã¦ãã ã•ã„"
msgid "SelfMonitoring|Disable self monitoring?"
-msgstr ""
+msgstr "自己監視を無効ã«ã—ã¾ã™ã‹ï¼Ÿ"
msgid "SelfMonitoring|Disabling this feature will delete the self monitoring project. Are you sure you want to delete the project?"
-msgstr ""
+msgstr "ã“ã®æ©Ÿèƒ½ã‚’無効ã«ã™ã‚‹ã¨ã€è‡ªå·±ç›£è¦–プロジェクトãŒå‰Šé™¤ã•ã‚Œã¾ã™ã€‚プロジェクトを削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
msgid "SelfMonitoring|Enable or disable instance self monitoring"
-msgstr ""
+msgstr "インスタンスã®è‡ªå·±ç›£è¦–を有効ã¾ãŸã¯ç„¡åŠ¹ã«ã™ã‚‹"
msgid "SelfMonitoring|Enabling this feature creates a %{projectLinkStart}project%{projectLinkEnd} that can be used to monitor the health of your instance."
-msgstr ""
+msgstr "ã“ã®æ©Ÿèƒ½ã‚’有効ã«ã™ã‚‹ã¨ã€ã‚ãªãŸã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã®å¥å…¨æ€§ã‚’監視ã™ã‚‹ãŸã‚ã«ä½¿ç”¨ã§ãã‚‹ %{projectLinkStart}プロジェクト%{projectLinkEnd} ãŒä½œæˆã•ã‚Œã¾ã™ã€‚"
msgid "SelfMonitoring|Enabling this feature creates a project that can be used to monitor the health of your instance."
-msgstr ""
+msgstr "ã“ã®æ©Ÿèƒ½ã‚’有効ã«ã™ã‚‹ã¨ã€ã‚ãªãŸã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã®å¥å…¨æ€§ã‚’監視ã™ã‚‹ãŸã‚ã«ä½¿ç”¨ã§ãるプロジェクトãŒä½œæˆã•ã‚Œã¾ã™ã€‚"
msgid "SelfMonitoring|Self monitoring"
-msgstr ""
+msgstr "自己監視"
msgid "SelfMonitoring|Self monitoring project has been successfully created."
-msgstr ""
+msgstr "自己監視プロジェクトãŒæ­£å¸¸ã«ä½œæˆã•ã‚Œã¾ã—ãŸ."
msgid "SelfMonitoring|Self monitoring project has been successfully deleted."
-msgstr ""
+msgstr "自己監視プロジェクトãŒæ­£å¸¸ã«å‰Šé™¤ã•ã‚Œã¾ã—ãŸ."
msgid "Send a separate email notification to Developers."
-msgstr ""
+msgstr "開発者毎ã«ãƒ¡ãƒ¼ãƒ«é€šçŸ¥ã‚’é€ä¿¡ã™ã‚‹"
msgid "Send confirmation email"
-msgstr ""
+msgstr "確èªãƒ¡ãƒ¼ãƒ«ã®é€ä¿¡"
msgid "Send email"
msgstr "メールをé€ä¿¡"
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr "レãƒãƒ¼ãƒˆã‚’é€ä¿¡"
msgid "Send usage data"
-msgstr ""
+msgstr "使用方法データã®é€ä¿¡"
msgid "Sentry API URL"
msgstr "Sentry API URL"
msgid "Sentry event"
-msgstr ""
+msgstr "Sentryイベント"
msgid "Sep"
msgstr "9月"
@@ -18623,7 +19759,7 @@ msgid "ServerlessDetails|More information"
msgstr "詳細情報"
msgid "ServerlessDetails|No pods loaded at this time."
-msgstr ""
+msgstr "ç¾æ™‚点ã§ã¯ãƒãƒƒãƒ‰ã¯ãƒ­ãƒ¼ãƒ‰ã•ã‚Œã¦ã„ã¾ã›ã‚“。"
msgid "ServerlessDetails|Number of Kubernetes pods in use over time based on necessity."
msgstr "å¿…è¦ã«å¿œã˜ã¦é•·æ™‚間使用中ã¨ãªã‚‹Kubernetesãƒãƒƒãƒ‰æ•°ã€‚"
@@ -18635,7 +19771,7 @@ msgid "ServerlessDetails|pods in use"
msgstr "使用中ã®ãƒãƒƒãƒ‰"
msgid "ServerlessURL|Copy URL"
-msgstr ""
+msgstr "URLをコピー"
msgid "Serverless| In order to start using functions as a service, you must first install Knative on your Kubernetes cluster."
msgstr "サービスã¨ã—ã¦functionã®ä½¿ç”¨ã‚’開始ã™ã‚‹ã«ã¯ã€ã¾ãšKubernetesクラスターã«Knativeをインストールã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
@@ -18644,10 +19780,10 @@ msgid "Serverless|Getting started with serverless"
msgstr "Serverless を始ã‚よã†"
msgid "Serverless|Help shape the future of Serverless at GitLab"
-msgstr ""
+msgstr "GitLab 㧠Serverless ã®æœªæ¥ã‚’形作る手助ã‘"
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 ""
+msgstr "上記ã®ã©ã‚Œã‚‚当ã¦ã¯ã¾ã‚‰ãªã„ã¨æ€ã‚れる場åˆã¯ã€functionデータãŒä½¿ç”¨å¯èƒ½ã«ãªã‚‹éŽç¨‹ã«å•é¡ŒãŒã‚ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚ã‚ã¨ã§ã‚‚ã†ä¸€åº¦ç¢ºèªã—ã¦ãã ã•ã„。"
msgid "Serverless|Install Knative"
msgstr "Knativeã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«"
@@ -18662,10 +19798,10 @@ msgid "Serverless|Sign up for First Look"
msgstr ""
msgid "Serverless|The deploy job has not finished."
-msgstr ""
+msgstr "デプロイジョブãŒå®Œäº†ã—ã¦ã„ã¾ã›ã‚“。"
msgid "Serverless|The functions listed in the %{startTag}serverless.yml%{endTag} file don't match the namespace of your cluster."
-msgstr ""
+msgstr "%{startTag}serverless.yml%{endTag} ファイルã«ãƒªã‚¹ãƒˆã•ã‚Œã¦ã„る関数・機能ãŒã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã®åå‰ç©ºé–“ã¨ä¸€è‡´ã—ã¾ã›ã‚“。"
msgid "Serverless|There is currently no function data available from Knative. This could be for a variety of reasons including:"
msgstr "ç¾åœ¨ Knative ã‹ã‚‰å…¥æ‰‹å¯èƒ½ãªæ©Ÿèƒ½ãƒ‡ãƒ¼ã‚¿ã¯ã‚ã‚Šã¾ã›ã‚“。ã“ã‚Œã¯ã„ãã¤ã‹ç†ç”±ãŒè€ƒãˆã‚‰ã‚Œã¾ã™:"
@@ -18677,22 +19813,22 @@ msgid "Serverless|Your %{startTag}.gitlab-ci.yml%{endTag} file is not properly c
msgstr ""
msgid "Serverless|Your repository does not have a corresponding %{startTag}serverless.yml%{endTag} file."
-msgstr ""
+msgstr "リãƒã‚¸ãƒˆãƒªã«ã€å¯¾å¿œã™ã‚‹ %{startTag}serverless.yml%{endTag} ファイルãŒã‚ã‚Šã¾ã›ã‚“。"
msgid "Service"
-msgstr ""
+msgstr "サービス"
msgid "Service Desk"
msgstr "サービスデスク"
msgid "Service Desk is enabled but not yet active"
-msgstr ""
+msgstr "サービスデスクã¯æœ‰åŠ¹ã§ã™ã€‚ã—ã‹ã—アクティブã§ã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "Service Desk is off"
-msgstr ""
+msgstr "サービスデスクã¯ã‚ªãƒ•ã§ã™"
msgid "Service Desk is on"
-msgstr ""
+msgstr "サービスデスクã¯ã‚ªãƒ³ã§ã™"
msgid "Service Templates"
msgstr "サービス テンプレート"
@@ -18704,19 +19840,19 @@ msgid "Session duration (minutes)"
msgstr "セッション期間 (分)"
msgid "Set %{epic_ref} as the parent epic."
-msgstr ""
+msgstr "%{epic_ref} を親エピックã¨ã—ã¦è¨­å®šã—ã¾ã—㟠。"
msgid "Set a default template for issue descriptions."
-msgstr ""
+msgstr "課題説明ã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆãƒ†ãƒ³ãƒ—レートを設定ã—ã¾ã™ã€‚"
msgid "Set a number of approvals required, the approvers and other approval settings."
-msgstr ""
+msgstr "å¿…è¦ãªæ‰¿èªæ•°ã€æ‰¿èªè€…ã€ãã®ä»–ã®æ‰¿èªè¨­å®šã‚’設定ã—ã¾ã™ã€‚"
msgid "Set a password on your account to pull or push via %{protocol}."
msgstr "%{protocol} プロコトル経由ã§ãƒ—ルã€ãƒ—ッシュã™ã‚‹ãŸã‚ã«ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®ãƒ‘スワードを設定。"
msgid "Set a template repository for projects in this group"
-msgstr ""
+msgstr "ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã®ãƒ—ロジェクトã®ã€ãƒ†ãƒ³ãƒ—レートリãƒã‚¸ãƒˆãƒªã‚’設定ã™ã‚‹"
msgid "Set an instance-wide domain that will be available to all clusters when installing Knative."
msgstr ""
@@ -18725,16 +19861,19 @@ msgid "Set default and restrict visibility levels. Configure import sources and
msgstr "デフォルトを設定ã—ã€å¯è¦–性レベルを制é™ã—ã¾ã™ã€‚インãƒãƒ¼ãƒˆã‚½ãƒ¼ã‚¹ã¨ git アクセスプロトコルを設定ã—ã¾ã™ã€‚"
msgid "Set due date"
-msgstr ""
+msgstr "期é™ã®è¨­å®š"
msgid "Set instance-wide template repository"
msgstr "インスタンス全体レベルã®ãƒ†ãƒ³ãƒ—レートリãƒã‚¸ãƒˆãƒªã‚’設定ã—ã¾ã™ã€‚"
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr "ウェブターミナルã®æœ€å¤§ã‚»ãƒƒã‚·ãƒ§ãƒ³ã‚¿ã‚¤ãƒ ã‚’設定ã™ã‚‹ã€‚"
msgid "Set milestone"
-msgstr ""
+msgstr "マイルストーンã®è¨­å®š"
msgid "Set new password"
msgstr "æ–°ã—ã„パスワードを設定"
@@ -18743,7 +19882,7 @@ msgid "Set notification email for abuse reports."
msgstr "迷惑行為レãƒãƒ¼ãƒˆã®é€šçŸ¥ãƒ¡ãƒ¼ãƒ«ã‚’設定ã™ã‚‹ã€‚"
msgid "Set parent epic to an epic"
-msgstr ""
+msgstr "親エピックをエピックã«è¨­å®š"
msgid "Set projects and maximum size limits, session duration, user options, and check feature availability for namespace plan."
msgstr ""
@@ -18752,18 +19891,21 @@ msgid "Set requirements for a user to sign-in. Enable mandatory two-factor authe
msgstr "ユーザーãŒã‚µã‚¤ãƒ³ã‚¤ãƒ³ã™ã‚‹ãŸã‚ã®è¦ä»¶ã‚’設定ã—ã¾ã™ã€‚å¿…é ˆã®äºŒè¦ç´ èªè¨¼ã‚’有効ã«ã—ã¾ã™ã€‚"
msgid "Set target branch"
-msgstr ""
+msgstr "ターゲットブランãƒã‚’設定"
msgid "Set target branch to %{branch_name}."
-msgstr ""
+msgstr "ターゲットブランãƒã‚’ %{branch_name} ã«è¨­å®šã—ã¾ã—ãŸã€‚"
msgid "Set the default expiration time for each job's artifacts. 0 for unlimited. The default unit is in seconds, but you can define an alternative. For example: <code>4 mins 2 sec</code>, <code>2h42min</code>."
-msgstr ""
+msgstr "å„ジョブã®ã‚¢ãƒ¼ãƒ†ã‚£ãƒ•ã‚¡ã‚¯ãƒˆã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®æœ‰åŠ¹æœŸé™ã‚’設定ã—ã¾ã™ã€‚ 無制é™ã®å ´åˆã¯0。 デフォルトã®å˜ä½ã¯ç§’ã§ã™ãŒã€ä»£ã‚ã‚Šã®ã‚‚ã®ã‚’定義ã§ãã¾ã™ã€‚ 例:<code>4分2秒</code>ã€<code>2時間42分</code>"
msgid "Set the due date to %{due_date}."
-msgstr ""
+msgstr "期日を %{due_date} ã«è¨­å®šã€‚"
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
+msgstr "ジョブãŒæœŸé™åˆ‡ã‚Œã¨ãªã‚‹æœŸé–“を設定ã—ã¾ã™ã€‚設定ã•ã‚ŒãŸæ™‚間を経éŽã™ã‚‹ã¨ã‚¸ãƒ§ãƒ–ã¯ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–ã•ã‚Œã€å†è©¦è¡Œã§ããªããªã‚Šã¾ã™ã€‚ジョブã®æœŸé™ã‚’無期é™ã«ã™ã‚‹å ´åˆã€ç©ºã®ã¾ã¾ã«ã—ã¦ãã ã•ã„。ã“れらã¯1日以上ã§æŒ‡å®šã—ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。例ãˆã°ã€<code>15 days</code>〠<code>1 month</code>〠<code>2 years</code> ãªã©ã€‚"
+
+msgid "Set the iteration to %{iteration_reference}."
msgstr ""
msgid "Set the maximum file size for each job's artifacts"
@@ -18773,13 +19915,13 @@ msgid "Set the maximum number of pipeline minutes that a group can use on shared
msgstr "グループãŒ1ヶ月間ã«å…±æœ‰ãƒ©ãƒ³ãƒŠãƒ¼ã§ä½¿ç”¨ã§ãã‚‹ã®ãƒ‘イプラインã®æœ€å¤§æ™‚間(分)を設定ã—ã¾ã™ã€‚無制é™ã«ã™ã‚‹å ´åˆã¯0を指定ã—ã¾ã™ã€‚"
msgid "Set the milestone to %{milestone_reference}."
-msgstr ""
+msgstr "マイルストーンを %{milestone_reference} ã«è¨­å®šã€‚"
msgid "Set time estimate"
msgstr "見ç©æ™‚é–“ã®è¨­å®š"
msgid "Set time estimate to %{time_estimate}."
-msgstr ""
+msgstr "見ç©æ™‚é–“ã‚’ %{time_estimate} ã«è¨­å®šã€‚"
msgid "Set up CI/CD"
msgstr "CI/CD を設定"
@@ -18788,13 +19930,13 @@ msgid "Set up Jira Integration"
msgstr ""
msgid "Set up a %{type} Runner automatically"
-msgstr ""
+msgstr "%{type} ã® Runner ã®è‡ªå‹•ã‚»ãƒƒãƒˆã‚¢ãƒƒãƒ—"
msgid "Set up a %{type} Runner manually"
-msgstr ""
+msgstr "%{type} ã®Runnerã®ãƒžãƒ‹ãƒ¥ã‚¢ãƒ«ã‚»ãƒƒãƒˆã‚¢ãƒƒãƒ—"
msgid "Set up assertions/attributes/claims (email, first_name, last_name) and NameID according to %{docsLinkStart}the documentation %{icon}%{docsLinkEnd}"
-msgstr ""
+msgstr "%{docsLinkStart}文書%{icon}%{docsLinkEnd}ã«å¾“ã£ã¦ã€ã‚¢ã‚µãƒ¼ã‚·ãƒ§ãƒ³/属性/資格情報 (email, first_name, last_name)ãŠã‚ˆã³NameIDを設定ã—ã¦ãã ã•ã„"
msgid "Set up new U2F device"
msgstr "æ–°ã—ã„U2Fデãƒã‚¤ã‚¹ã‚’セットアップ"
@@ -18803,7 +19945,7 @@ msgid "Set up new password"
msgstr "æ–°ã—ã„パスワードを設定"
msgid "Set up pipeline subscriptions for this project."
-msgstr ""
+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 "プロジェクトを設定ã—ã¦ã€åˆ¥ã®ãƒªãƒã‚¸ãƒˆãƒªã¨ã®é–“ã§å¤‰æ›´ã‚’自動的ã«ãƒ—ッシュ/プルã™ã‚‹ã€‚ブランãƒã€ã‚¿ã‚°ã€ãŠã‚ˆã³ã‚³ãƒŸãƒƒãƒˆã¯è‡ªå‹•çš„ã«åŒæœŸã—ã¾ã™ã€‚"
@@ -18812,7 +19954,7 @@ msgid "Set weight"
msgstr "ウェイトを設定"
msgid "Set weight to %{weight}."
-msgstr ""
+msgstr "ウェイトを %{weight} ã«è¨­å®š"
msgid "SetPasswordToCloneLink|set a password"
msgstr "パスワードを設定"
@@ -18842,14 +19984,17 @@ msgid "SetStatusModal|What's your status?"
msgstr "ã‚ãªãŸã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã¯ï¼Ÿ"
msgid "Sets %{epic_ref} as parent epic."
-msgstr ""
+msgstr "%{epic_ref} を親エピックã¨ã—ã¦è¨­å®šã—ã¾ã™ 。"
msgid "Sets target branch to %{branch_name}."
-msgstr ""
+msgstr "ターゲットブランãƒã‚’ %{branch_name} ã«è¨­å®šã€‚"
msgid "Sets the due date to %{due_date}."
msgstr "期日を %{due_date} ã«è¨­å®š 。"
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr "マイルストーンを %{milestone_reference} ã«è¨­å®šã€‚"
@@ -18868,7 +20013,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -18905,15 +20050,15 @@ msgid "Sherlock Transactions"
msgstr "シャーロックトランザクション"
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
-msgstr ""
-
-msgid "Show all %{issuable_type}."
-msgstr ""
+msgstr "ã‚ãªãŸã®æºå¸¯é›»è©±ã‚’紛失ã—ãŸã‚Šãƒ¯ãƒ³ã‚¿ã‚¤ãƒ ãƒ‘スワードを紛失ã—ãŸå ´åˆã€ã“れらã®å›žå¾©ã‚³ãƒ¼ãƒ‰ã‚’ãã‚Œãžã‚Œï¼‘回ãšã¤ä½¿ç”¨ã—ã¦ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®ã‚¢ã‚¯ã‚»ã‚¹ã‚’回復ã§ãã¾ã™ã€‚安全ãªå ´æ‰€ã«ä¿å­˜ã—ã¦ãã ã•ã„。ãã†ã—ãªã„ã¨ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¸ã®ã‚¢ã‚¯ã‚»ã‚¹æ¨©ã‚’%{b_start} 失ã„ã¾ã™ã€‚%{b_end}"
msgid "Show all activity"
msgstr "ã™ã¹ã¦ã®ã‚¢ã‚¯ãƒ†ã‚£ãƒ“ティを表示"
msgid "Show all members"
+msgstr "å…¨ã¦ã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’表示"
+
+msgid "Show all requirements."
msgstr ""
msgid "Show archived projects"
@@ -18926,13 +20071,13 @@ msgid "Show command"
msgstr "コマンドを表示"
msgid "Show comments"
-msgstr ""
+msgstr "コメントã®è¡¨ç¤º"
msgid "Show comments only"
msgstr "コメントã®ã¿è¡¨ç¤º"
msgid "Show commit description"
-msgstr ""
+msgstr "コミットã®èª¬æ˜Žã‚’表示"
msgid "Show complete raw log"
msgstr "完全ãªç”Ÿãƒ­ã‚°ã‚’表示ã™ã‚‹"
@@ -18940,17 +20085,26 @@ msgstr "完全ãªç”Ÿãƒ­ã‚°ã‚’表示ã™ã‚‹"
msgid "Show file browser"
msgstr "ファイルブラウザを表示"
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr "最新ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’表示"
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
-msgid "Show only direct members"
+msgid "Show me more advanced stuff"
msgstr ""
+msgid "Show only direct members"
+msgstr "直接ã®ãƒ¡ãƒ³ãƒãƒ¼ã®ã¿è¡¨ç¤º"
+
msgid "Show only inherited members"
-msgstr ""
+msgstr "継承メンãƒãƒ¼ã®ã¿ã‚’表示"
msgid "Show parent pages"
msgstr "親ページを表示"
@@ -18965,26 +20119,33 @@ msgid "Showing %d event"
msgid_plural "Showing %d events"
msgstr[0] "%d ã®ã‚¤ãƒ™ãƒ³ãƒˆã‚’表示中"
-msgid "Showing %{limit} of %{total_count} issues. "
+msgid "Showing %{count} of %{total} projects"
msgstr ""
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+
+msgid "Showing %{limit} of %{total_count} issues. "
+msgstr "%{total_count} 件中 %{limit} ã®èª²é¡Œã‚’表示. "
+
msgid "Showing %{pageSize} of %{total} issues"
-msgstr ""
+msgstr "%{total} 件中 %{pageSize} ã®èª²é¡Œã‚’表示"
msgid "Showing Latest Version"
-msgstr ""
+msgstr "最新ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’表示"
msgid "Showing Version #%{versionNumber}"
-msgstr ""
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ç•ªå·#%{versionNumber} を表示"
msgid "Showing all issues"
-msgstr ""
+msgstr "ã™ã¹ã¦ã®èª²é¡Œã‚’表示"
msgid "Showing all labels"
-msgstr ""
+msgstr "ã™ã¹ã¦ã®ãƒ©ãƒ™ãƒ«ã‚’表示"
msgid "Showing last %{size} of log -"
-msgstr ""
+msgstr "ログã®ç›´è¿‘ã®éƒ¨åˆ† (%{size} サイズ) を表示"
msgid "Side-by-side"
msgstr "並列"
@@ -19017,7 +20178,7 @@ msgid "Sign in / Register"
msgstr "サインイン / 登録"
msgid "Sign in to \"%{group_name}\""
-msgstr ""
+msgstr "\"%{group_name}\" ã«ã‚µã‚¤ãƒ³ã‚¤ãƒ³ã—ã¾ã™"
msgid "Sign in using smart card"
msgstr "スマートカードを使ã£ã¦ã‚µã‚¤ãƒ³ã‚¤ãƒ³"
@@ -19038,7 +20199,7 @@ msgid "Sign out & Register"
msgstr "ログアウト&登録"
msgid "Sign up"
-msgstr ""
+msgstr "サインアップ"
msgid "Sign up was successful! Please confirm your email to sign in."
msgstr "登録ã¯æˆåŠŸã—ã¾ã—ãŸï¼ メールアドレスを確èªã—ã¦ã‚µã‚¤ãƒ³ã‚¤ãƒ³ã—ã¦ãã ã•ã„。"
@@ -19050,10 +20211,10 @@ msgid "Sign-up restrictions"
msgstr "サインアップã®åˆ¶é™"
msgid "SignUp|First Name is too long (maximum is %{max_length} characters)."
-msgstr ""
+msgstr "åãŒé•·ã™ãŽã¾ã™ï¼ˆæœ€å¤§ %{max_length} 文字)。"
msgid "SignUp|Last Name is too long (maximum is %{max_length} characters)."
-msgstr ""
+msgstr "姓ãŒé•·ã™ãŽã¾ã™ï¼ˆæœ€å¤§ %{max_length} 文字)。"
msgid "SignUp|Name is too long (maximum is %{max_length} characters)."
msgstr "åå‰ãŒé•·ã™ãŽã¾ã™(最大 %{max_length} 文字)"
@@ -19062,22 +20223,22 @@ msgid "SignUp|Username is too long (maximum is %{max_length} characters)."
msgstr "ユーザーåãŒé•·ã™ãŽã¾ã™(最大 %{max_length} 文字)"
msgid "Signed in"
-msgstr ""
+msgstr "サインイン済ã¿"
msgid "Signed in with %{authentication} authentication"
msgstr "%{authentication} èªè¨¼ã§ã‚µã‚¤ãƒ³ã‚¤ãƒ³"
msgid "Signing in using %{label} has been disabled"
-msgstr ""
+msgstr "%{label} を用ã„ãŸã‚µã‚¤ãƒ³ã‚¤ãƒ³ã¯ç„¡åŠ¹ã«ãªã£ã¦ã„ã¾ã™"
msgid "Signing in using your %{label} account without a pre-existing GitLab account is not allowed."
-msgstr ""
+msgstr "既存ã®GitLabアカウントを使用ã›ãšã«%{label} アカウントを使用ã—ã¦ã‚µã‚¤ãƒ³ã‚¤ãƒ³ã™ã‚‹ã“ã¨ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“。"
msgid "Similar issues"
msgstr "é¡žä¼¼ã®èª²é¡Œ"
msgid "Single or combined queries"
-msgstr ""
+msgstr "å˜ä¸€ã¾ãŸã¯è¤‡åˆã®ã‚¯ã‚¨ãƒªãƒ¼"
msgid "Size"
msgstr "サイズ"
@@ -19089,16 +20250,16 @@ msgid "Size limit per repository (MB)"
msgstr "リãƒã‚¸ãƒˆãƒªæ¯Žã®ã‚µã‚¤ã‚ºåˆ¶é™ (MB)"
msgid "Size settings for static websites"
-msgstr ""
+msgstr "é™çš„ãªã‚¦ã‚§ãƒ–サイトã®ã‚µã‚¤ã‚ºè¨­å®š"
msgid "Skip outdated deployment jobs"
msgstr ""
msgid "Skip this for now"
-msgstr ""
+msgstr "今ã¯ã‚¹ã‚­ãƒƒãƒ—ã™ã‚‹"
msgid "Skipped"
-msgstr ""
+msgstr "スキップã—ã¾ã—ãŸ"
msgid "Slack application"
msgstr "Slack アプリケーション"
@@ -19107,13 +20268,13 @@ msgid "Slack channels (e.g. general, development)"
msgstr ""
msgid "Slack integration allows you to interact with GitLab via slash commands in a chat window."
-msgstr ""
+msgstr "Slackçµ±åˆã§ã¯ã€Slackã®ãƒãƒ£ãƒƒãƒˆã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‹ã‚‰ slash コマンドを介ã—㦠GitLab ã¨ã‚„ã‚Šã¨ã‚Šã§ãã¾ã™ã€‚"
msgid "SlackIntegration|%{webhooks_link_start}Add an incoming webhook%{webhooks_link_end} in your Slack team. The default channel can be overridden for each event."
-msgstr ""
+msgstr "Slackãƒãƒ¼ãƒ ã« %{webhooks_link_start}incoming webhookを追加 %{webhooks_link_end} ã—ã¾ã™ã€‚デフォルトã®ãƒãƒ£ãƒãƒ«ã¯ã€ãã‚Œãžã‚Œã®ã‚¤ãƒ™ãƒ³ãƒˆã§ã‚ªãƒ¼ãƒãƒ¼ãƒ©ã‚¤ãƒ‰ã§ãã¾ã™ã€‚"
msgid "SlackIntegration|<strong>Note:</strong> Usernames and private channels are not supported."
-msgstr ""
+msgstr "<strong> 注: </strong> ユーザーåã¨ãƒ—ライベートãƒãƒ£ãƒãƒ«ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。"
msgid "SlackIntegration|Paste the <strong>Webhook URL</strong> into the field below."
msgstr ""
@@ -19125,19 +20286,19 @@ msgid "SlackIntegration|This service send notifications about projects' events t
msgstr ""
msgid "SlackService|2. Paste the <strong>Token</strong> into the field below"
-msgstr ""
+msgstr "2. <strong>トークン</strong> を下ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã«è²¼ã‚Šä»˜ã‘ã¾ã™"
msgid "SlackService|3. Select the <strong>Active</strong> checkbox, press <strong>Save changes</strong> and start using GitLab inside Slack!"
-msgstr ""
+msgstr "3. <strong>アクティブãª</strong> ãƒã‚§ãƒƒã‚¯ãƒœãƒƒã‚¯ã‚¹ã‚’é¸æŠžã—〠<strong>変更をä¿å­˜</strong> を押ã—ã¦ã€Slack内ã§GitLabã®ä½¿ç”¨ã‚’開始ã—ã¾ã™ï¼"
msgid "SlackService|Fill in the word that works best for your team."
-msgstr ""
+msgstr "ãƒãƒ¼ãƒ ã«æœ€é©ãªãƒ¯ãƒ¼ãƒ‰ã‚’入力ã—ã¦ãã ã•ã„。"
msgid "SlackService|See list of available commands in Slack after setting up this service, by entering"
-msgstr ""
+msgstr "ã“ã®ã‚µãƒ¼ãƒ“スを設定ã—ãŸå¾Œã« Slack 上ã§ä½¿ç”¨ã§ãるコマンドã®ãƒªã‚¹ãƒˆã‚’表示ã™ã‚‹ã«ã¯ã€æ¬¡ã‚’入力ã—ã¾ã™ã€‚"
msgid "SlackService|This service allows users to perform common operations on this project by entering slash commands in Slack."
-msgstr ""
+msgstr "ã“ã®ã‚µãƒ¼ãƒ“スã«ã‚ˆã‚Šã€ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ Slack ã«ã‚¹ãƒ©ãƒƒã‚·ãƒ¥ã‚³ãƒžãƒ³ãƒ‰ã‚’入力ã—ã¦ã€ã“ã®ãƒ—ロジェクト上ã®ä¸€èˆ¬çš„ãªæ“作ãŒå®Ÿè¡Œã§ãã¾ã™ã€‚"
msgid "Slower but makes sure the project workspace is pristine as it clones the repository from scratch for every job"
msgstr "é…ããªã‚Šã¾ã™ãŒã€ãƒ—ロジェクトã®ä½œæ¥­é ˜åŸŸã¯ã€ã™ã¹ã¦ã®ã‚¸ãƒ§ãƒ–ã®ãŸã‚ã«ã‚¼ãƒ­ã‹ã‚‰ãƒªãƒã‚¸ãƒˆãƒªã‚’クローンã™ã‚‹ã®ã§ã€ã‚¯ãƒªã‚¢ãªçŠ¶æ…‹ã«ãªã‚Šã¾ã™"
@@ -19151,6 +20312,9 @@ msgstr "スマートカードèªè¨¼ã«å¤±æ•—:クライアント証明書ヘッ
msgid "Snippets"
msgstr "スニペット"
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19164,7 +20328,7 @@ msgid "SnippetsEmptyState|No snippets found"
msgstr "スニペットãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
msgid "SnippetsEmptyState|Store, share, and embed small pieces of code and text."
-msgstr ""
+msgstr "コードスニペットã¨ãƒ†ã‚­ã‚¹ãƒˆã‚’ä¿å­˜ã€å…±æœ‰ã€åŸ‹ã‚è¾¼ã¿ã€‚"
msgid "SnippetsEmptyState|There are no snippets to show."
msgstr "表示ã™ã‚‹ã‚¹ãƒ‹ãƒšãƒƒãƒˆã¯ã‚ã‚Šã¾ã›ã‚“。"
@@ -19185,11 +20349,17 @@ msgid "Snippets|Optionally add a description about what your snippet does or how
msgstr ""
msgid "Snowplow"
+msgstr "Snowplow"
+
+msgid "Solution"
msgstr ""
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr "一部ã®ãƒ¡ãƒ¼ãƒ«ã‚µãƒ¼ãƒãƒ¼ã¯ã€ãƒ¡ãƒ¼ãƒ«é€ä¿¡è€…åã®ä¸Šæ›¸ãをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。ã“ã®ã‚ªãƒ—ションを有効ã«ã™ã‚‹ã¨ã€ä»£ã‚ã‚Šã«ãƒ¡ãƒ¼ãƒ«æœ¬æ–‡ã«èª²é¡Œã€ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã€ã¾ãŸã¯ã‚³ãƒ¡ãƒ³ãƒˆã®ä½œæˆè€…ã®åå‰ã‚’å«ã‚ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
@@ -19197,10 +20367,10 @@ msgid "Some of the designs you tried uploading did not change:"
msgstr ""
msgid "Some of your epics may not be visible. A roadmap is limited to the first 1,000 epics, in your selected sort order."
-msgstr ""
+msgstr "エピックã®ä¸€éƒ¨ãŒè¡¨ç¤ºã•ã‚Œãªã„ã“ã¨ãŒã‚ã‚Šã¾ã™ã€‚ロードマップã¯ã€ã‚ãªãŸãŒé¸æŠžã—ãŸã‚½ãƒ¼ãƒˆé †ã§æœ€åˆã®1,000エピックã ã‘ã«é™å®šã•ã‚Œã¾ã™ã€‚"
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 "ã‚ãªãŸã®ç·¨é›†ã¨åŒæ™‚ã«èª°ã‹ãŒã“ã® %{issueType} を編集ã—ãŸãŸã‚ã€èª¬æ˜ŽãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ç·¨é›†ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
@@ -19248,19 +20418,19 @@ msgid "Something went wrong while deleting description changes. Please try again
msgstr ""
msgid "Something went wrong while deleting the package."
-msgstr ""
+msgstr "パッケージを削除ã™ã‚‹éš›ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "Something went wrong while deleting the source branch. Please try again."
msgstr "ソースブランãƒã®å‰Šé™¤ä¸­ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
msgid "Something went wrong while deleting your note. Please try again."
-msgstr ""
+msgstr "注釈を削除ã™ã‚‹éš›ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
msgid "Something went wrong while deploying this environment. Please try again."
msgstr ""
msgid "Something went wrong while editing your comment. Please try again."
-msgstr ""
+msgstr "コメントを編集ã™ã‚‹é–“ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
msgid "Something went wrong while fetching %{listType} list"
msgstr "%{listType} ã®ãƒªã‚¹ãƒˆå–得中ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸ"
@@ -19269,7 +20439,7 @@ msgid "Something went wrong while fetching comments. Please try again."
msgstr "コメントã®å–得中ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。"
msgid "Something went wrong while fetching description changes. Please try again."
-msgstr ""
+msgstr "説明変更ã®å–得中ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。"
msgid "Something went wrong while fetching group member contributions"
msgstr "グループメンãƒãƒ¼ã®è²¢çŒ®åº¦ã‚’å–得中ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸ"
@@ -19278,7 +20448,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 ""
@@ -19286,6 +20456,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr "マージリクエストã«é–¢é€£ã™ã‚‹ãƒ•ã‚§ãƒƒãƒä¸­ã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19293,25 +20466,25 @@ msgid "Something went wrong while fetching the environments for this merge reque
msgstr "ã“ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã®ç’°å¢ƒã‚’å–得中ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。"
msgid "Something went wrong while fetching the package."
-msgstr ""
+msgstr "パッケージをå–å¾—ã™ã‚‹éš›ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "Something went wrong while fetching the packages list."
-msgstr ""
+msgstr "パッケージリストをå–å¾—ã™ã‚‹éš›ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "Something went wrong while initializing the OpenAPI viewer"
-msgstr ""
+msgstr "OpenAPI ビューアã®åˆæœŸåŒ–中ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸ"
msgid "Something went wrong while merging this merge request. Please try again."
msgstr "ã“ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã®ãƒžãƒ¼ã‚¸ä¸­ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
msgid "Something went wrong while moving issues."
-msgstr ""
+msgstr "課題を移動ã™ã‚‹éš›ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
msgid "Something went wrong while performing the action."
-msgstr ""
+msgstr "アクションã«å®Ÿæ–½ä¸­ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "Something went wrong while reopening a requirement."
msgstr ""
@@ -19323,13 +20496,16 @@ msgid "Something went wrong while resolving this discussion. Please try again."
msgstr "ã“ã®æ¤œè¨Žã‚’解決ã—ã¦ã„ã‚‹ã¨ãã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
msgid "Something went wrong while stopping this environment. Please try again."
+msgstr "ã“ã®ç’°å¢ƒã®åœæ­¢ä¸­ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
+
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
msgstr ""
msgid "Something went wrong while updating a requirement."
msgstr ""
msgid "Something went wrong while updating your list settings"
-msgstr ""
+msgstr "リスト設定を更新ã™ã‚‹é–“ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸ"
msgid "Something went wrong with your automatic subscription renewal"
msgstr ""
@@ -19338,28 +20514,28 @@ msgid "Something went wrong, unable to add %{project} to dashboard"
msgstr "å•é¡ŒãŒç™ºç”Ÿã—ã¦ã€ãƒ€ãƒƒã‚·ãƒ¥ãƒœãƒ¼ãƒ‰ã« %{project} を追加ã§ãã¾ã›ã‚“"
msgid "Something went wrong, unable to add projects to dashboard"
-msgstr ""
+msgstr "å•é¡ŒãŒç™ºç”Ÿã—ã¦ã€ãƒ€ãƒƒã‚·ãƒ¥ãƒœãƒ¼ãƒ‰ã«ãƒ—ロジェクトを追加ã§ãã¾ã›ã‚“"
msgid "Something went wrong, unable to get projects"
-msgstr ""
+msgstr "å•é¡ŒãŒç™ºç”Ÿã—ã¦ã€ãƒ—ロジェクトをå–å¾—ã§ãã¾ã›ã‚“。"
msgid "Something went wrong, unable to remove project"
-msgstr ""
+msgstr "å•é¡ŒãŒç™ºç”Ÿã—ã¦ã€ãƒ—ロジェクトを削除ã§ãã¾ã›ã‚“。"
msgid "Something went wrong, unable to search projects"
-msgstr ""
+msgstr "å•é¡ŒãŒç™ºç”Ÿã—ã¦ã€ãƒ—ロジェクトを検索ã§ãã¾ã›ã‚“。"
msgid "Something went wrong. Please try again."
msgstr "å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚å†è©¦è¡Œã—ã¦ãã ã•ã„。"
msgid "Something went wrong. Try again later."
-msgstr ""
+msgstr "ä¸æ˜Žãªã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚ã¨ã§ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。"
msgid "Sorry, no epics matched your search"
msgstr "申ã—訳ã‚ã‚Šã¾ã›ã‚“ã€æ¤œç´¢ã«ä¸€è‡´ã™ã‚‹ã‚¨ãƒ”ックã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "Sorry, no projects matched your search"
-msgstr ""
+msgstr "検索æ¡ä»¶ã«ä¸€è‡´ã™ã‚‹ãƒ—ロジェクトã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚"
msgid "Sorry, you have exceeded the maximum browsable page number. Please use the API to explore further."
msgstr ""
@@ -19373,6 +20549,12 @@ msgstr "並ã¹æ›¿ãˆ"
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr "アクセスレベル昇順"
@@ -19392,7 +20574,7 @@ msgid "SortOptions|Due soon"
msgstr "期é™ã®è¿‘ã„é †"
msgid "SortOptions|Expired date"
-msgstr ""
+msgstr "有効期é™"
msgid "SortOptions|Label priority"
msgstr "ラベルã®å„ªå…ˆåº¦é †"
@@ -19404,7 +20586,7 @@ msgid "SortOptions|Largest repository"
msgstr "リãƒã‚¸ãƒˆãƒªã®å¤§ãã„é †"
msgid "SortOptions|Last Contact"
-msgstr ""
+msgstr "最後ã«å‚加ã—ãŸé †"
msgid "SortOptions|Last created"
msgstr "最新作æˆé †"
@@ -19458,7 +20640,7 @@ msgid "SortOptions|Oldest joined"
msgstr "å‚加ã—ãŸé †"
msgid "SortOptions|Oldest last activity"
-msgstr ""
+msgstr "最å¤ã®æœ€æ–°ã‚¢ã‚¯ãƒ†ã‚£ãƒ“ティ"
msgid "SortOptions|Oldest sign in"
msgstr "サインイン順"
@@ -19476,7 +20658,7 @@ msgid "SortOptions|Priority"
msgstr "優先度順"
msgid "SortOptions|Project"
-msgstr ""
+msgstr "プロジェクト"
msgid "SortOptions|Recent last activity"
msgstr "最近ã®æœ€æ–°ã‚¢ã‚¯ãƒ†ã‚£ãƒ“ティ"
@@ -19488,13 +20670,16 @@ msgid "SortOptions|Recently starred"
msgstr "ãŠæ°—ã«ã„ã‚Šã§æ–°ã—ã„é †"
msgid "SortOptions|Size"
+msgstr "サイズ"
+
+msgid "SortOptions|Sort by:"
msgstr ""
msgid "SortOptions|Sort direction"
-msgstr ""
+msgstr "ソート順"
msgid "SortOptions|Stars"
-msgstr ""
+msgstr "ãŠæ°—ã«ã„ã‚Š"
msgid "SortOptions|Start date"
msgstr "開始日ã®é †"
@@ -19506,10 +20691,10 @@ msgid "SortOptions|Start soon"
msgstr "æ–°ã—ã„é †"
msgid "SortOptions|Type"
-msgstr ""
+msgstr "タイプ"
msgid "SortOptions|Version"
-msgstr ""
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³"
msgid "SortOptions|Weight"
msgstr "ウエイト"
@@ -19530,49 +20715,49 @@ msgid "Source project cannot be found."
msgstr "ソースプロジェクトãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。"
msgid "Sourcegraph"
-msgstr ""
+msgstr "Sourcegraph"
msgid "SourcegraphAdmin|Block on private and internal projects"
-msgstr ""
+msgstr "プライベートãŠã‚ˆã³å†…部プロジェクトã®ãƒ–ロック"
msgid "SourcegraphAdmin|Configure the URL to a Sourcegraph instance which can read your GitLab projects."
-msgstr ""
+msgstr "GitLab ã®ãƒ—ロジェクトを読ã¿å–ã‚‹ã“ã¨ãŒã§ãã‚‹ Sourcegraph インスタンスã¸ã®URLを設定ã—ã¾ã™ã€‚"
msgid "SourcegraphAdmin|Enable Sourcegraph"
-msgstr ""
+msgstr "Sourcegraphを有効ã«ã™ã‚‹"
msgid "SourcegraphAdmin|Enable code intelligence powered by %{link_start}Sourcegraph%{link_end} on your GitLab instance's code views and merge requests."
-msgstr ""
+msgstr "GitLab インスタンスã®ã‚³ãƒ¼ãƒ‰ãƒ“ューã¨ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã§ %{link_start}Sourcegraph%{link_end} ã®ã‚³ãƒ¼ãƒ‰ã‚¤ãƒ³ãƒ†ãƒªã‚¸ã‚§ãƒ³ã‚¹ã‚’有効ã«ã—ã¾ã™ã€‚"
msgid "SourcegraphAdmin|If checked, only public projects will have code intelligence and communicate with Sourcegraph."
-msgstr ""
+msgstr "ãƒã‚§ãƒƒã‚¯ã—ãŸå ´åˆã€å…¬é–‹ãƒ—ロジェクトã ã‘ãŒã‚³ãƒ¼ãƒ‰ã‚¤ãƒ³ãƒ†ãƒªã‚¸ã‚§ãƒ³ã‚¹ã‚’使用ã§ãã€Sourcegraph ã¨é€šä¿¡ã§ãã¾ã™ã€‚"
msgid "SourcegraphAdmin|More information"
-msgstr ""
+msgstr "詳細情報"
msgid "SourcegraphAdmin|Save changes"
-msgstr ""
+msgstr "変更をä¿å­˜"
msgid "SourcegraphAdmin|Sourcegraph URL"
-msgstr ""
+msgstr "Sourcegraph URL"
msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
-msgstr ""
+msgstr "例: https://sourcegraph.example.com"
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
-msgstr ""
+msgstr "ã“ã®æ©Ÿèƒ½ã¯å®Ÿé¨“çš„ã§ã‚ã‚Šã€ç¾åœ¨ã¯ç‰¹å®šã®ãƒ—ロジェクトã®ã¿ã«é™å®šã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "SourcegraphPreferences|This feature is experimental and limited to public projects."
-msgstr ""
+msgstr "ã“ã®æ©Ÿèƒ½ã¯å®Ÿé¨“çš„ã§ã‚ã‚Šã€å…¬é–‹ãƒ—ロジェクトã®ã¿ã«é™å®šã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "SourcegraphPreferences|This feature is experimental."
-msgstr ""
+msgstr "ã“ã®æ©Ÿèƒ½ã¯å®Ÿé¨“çš„ã§ã™ã€‚"
msgid "SourcegraphPreferences|Uses %{link_start}Sourcegraph.com%{link_end}."
-msgstr ""
+msgstr "%{link_start}Sourcegraph.com%{link_end}を使用ã—ã¾ã™ã€‚"
msgid "SourcegraphPreferences|Uses a custom %{link_start}Sourcegraph instance%{link_end}."
-msgstr ""
+msgstr "カスタム %{link_start}Sourcegraph インスタンス%{link_end} を使用ã—ã¾ã™ã€‚"
msgid "Spam Logs"
msgstr "スパム ログ"
@@ -19587,7 +20772,7 @@ msgid "Specific Runners"
msgstr "特定㮠Runner"
msgid "Specified URL cannot be used: \"%{reason}\""
-msgstr ""
+msgstr "指定ã®URLã¯ä½¿ç”¨ã§ãã¾ã›ã‚“: \"%{reason}\""
msgid "Specify an e-mail address regex pattern to identify default internal users."
msgstr "メールアドレスã®æ­£è¦è¡¨ç¾ãƒ‘ターンを指定ã—ã¦ã€ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®å†…部ユーザーを区別ã—ã¾ã™ã€‚"
@@ -19599,13 +20784,13 @@ msgid "Speed up your DevOps<br>with GitLab"
msgstr ""
msgid "Squash commit message"
-msgstr ""
+msgstr "コミットメッセージをスカッシュ"
msgid "Squash commits"
msgstr "コミットを1ã¤ã«ã¾ã¨ã‚ã‚‹"
msgid "Stack trace"
-msgstr ""
+msgstr "スタックトレース"
msgid "Stage"
msgstr "ステージ"
@@ -19614,10 +20799,10 @@ msgid "Stage & Commit"
msgstr "ステージ&コミット"
msgid "Stage data updated"
-msgstr ""
+msgstr "ステージデータã®æ›´æ–°"
msgid "Stage removed"
-msgstr ""
+msgstr "削除ãšã¿ã‚¹ãƒ†ãƒ¼ã‚¸"
msgid "Standard"
msgstr ""
@@ -19626,10 +20811,10 @@ msgid "Star a label to make it a priority label. Order the prioritized labels to
msgstr "優先ラベルã«ã™ã‚‹ã«ã¯ã€ãƒ©ãƒ™ãƒ«ã«ã‚¹ã‚¿ãƒ¼ã‚’付ã‘ã¾ã™ã€‚ドラッグã—ã¦ã€å„ªå…ˆé †ä½ã‚’並ã¹æ›¿ãˆã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
msgid "Star labels to start sorting by priority"
-msgstr ""
+msgstr "ラベルをãŠæ°—ã«ã„ã‚Šã«ã—ã¦ã‚½ãƒ¼ãƒˆã®å„ªå…ˆé †ä½ã‚’ã¤ã‘ã‚‹"
msgid "Star toggle failed. Try again later."
-msgstr ""
+msgstr "ãŠæ°—ã«å…¥ã‚Šã®åˆ‡ã‚Šæ›¿ãˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。"
msgid "StarProject|Star"
msgstr "スターを付ã‘ã‚‹"
@@ -19655,8 +20840,8 @@ msgstr "ãŠæ°—ã«ã„ã‚Š"
msgid "Stars"
msgstr "スター"
-msgid "Start GitLab Ultimate trial"
-msgstr "GitLab Ultimateトライアルを始ã‚ã¾ã—ょã†"
+msgid "Start Date"
+msgstr ""
msgid "Start Web Terminal"
msgstr "Webターミナルã®èµ·å‹•"
@@ -19665,10 +20850,10 @@ msgid "Start a %{new_merge_request} with these changes"
msgstr "ã“ã®å¤‰æ›´ã§ %{new_merge_request} を作æˆã™ã‚‹"
msgid "Start a Free Gold Trial"
-msgstr ""
+msgstr "ç„¡æ–™ã®ã‚´ãƒ¼ãƒ«ãƒ‰è©¦ç”¨ç‰ˆã‚’開始ã™ã‚‹"
msgid "Start a new discussion..."
-msgstr ""
+msgstr "æ–°ã—ã議論を開始"
msgid "Start a new merge request"
msgstr "æ–°ã—ã„マージリクエストを開始ã™ã‚‹"
@@ -19680,61 +20865,64 @@ msgid "Start and due date"
msgstr "開始日ã¨çµ‚了日"
msgid "Start by choosing a group to see how your team is spending time. You can then drill down to the project level."
-msgstr ""
+msgstr "グループをé¸æŠžã—ã¦ã€ãƒãƒ¼ãƒ ãŒã©ã®ã‚ˆã†ã«æ™‚間を費やã—ã¦ã„ã‚‹ã‹ã‚’確èªã™ã‚‹ã¨ã“ã‚ã‹ã‚‰å§‹ã‚ã¾ã—ょã†ã€‚ãã®å¾Œã€ãƒ—ロジェクトレベルã«ãƒ‰ãƒªãƒ«ãƒ€ã‚¦ãƒ³ã—ã¾ã™ã€‚"
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 "クリーンアップ開始"
msgid "Start date"
msgstr "開始日"
msgid "Start merge train"
-msgstr ""
+msgstr "マージトレインを開始"
msgid "Start merge train when pipeline succeeds"
-msgstr ""
+msgstr "パイプラインãŒæˆåŠŸã—ãŸã¨ãã«ãƒžãƒ¼ã‚¸ãƒˆãƒ¬ã‚¤ãƒ³ã‚’開始"
msgid "Start search"
-msgstr ""
+msgstr "検索開始"
msgid "Start the Runner!"
msgstr "Runner ã‚’èµ·å‹•!"
msgid "Start thread"
-msgstr ""
+msgstr "スレッドを開始ã—ã¾ã™ã€‚"
msgid "Start thread & close %{noteable_name}"
-msgstr ""
+msgstr "スレッドã®é–‹å§‹ã¨ã‚¯ãƒ­ãƒ¼ã‚º %{noteable_name}"
msgid "Start thread & reopen %{noteable_name}"
-msgstr ""
+msgstr "スレッドã®é–‹å§‹ã¨ %{noteable_name} ã®å†é–‹"
msgid "Start your Free Gold Trial"
-msgstr ""
+msgstr "ç„¡æ–™ã®ã‚´ãƒ¼ãƒ«ãƒ‰è©¦ç”¨ç‰ˆã‚’開始ã™ã‚‹"
msgid "Start your free trial"
-msgstr ""
+msgstr "無料トライアルを開始"
msgid "Start your trial"
-msgstr ""
+msgstr "試用を開始"
msgid "Started"
msgstr "開始済ã¿"
msgid "Started %{startsIn}"
-msgstr ""
+msgstr "%{startsIn} を開始ã—ã¾ã—ãŸ"
msgid "Started asynchronous removal of all repository check states."
+msgstr "ã™ã¹ã¦ã®ãƒªãƒã‚¸ãƒˆãƒªãƒã‚§ãƒƒã‚¯çŠ¶æ…‹ã®éžåŒæœŸå‰Šé™¤ã‚’開始ã—ã¾ã—ãŸã€‚"
+
+msgid "Started:"
msgstr ""
msgid "Starting..."
msgstr "開始中..."
msgid "Starts %{startsIn}"
-msgstr ""
+msgstr "%{startsIn} を開始ã—ã¾ã™"
msgid "Starts at (UTC)"
msgstr "開始時刻 (UTC)"
@@ -19743,7 +20931,7 @@ msgid "State your message to activate"
msgstr "メッセージを有効ã«ã™ã‚‹"
msgid "Static Application Security Testing (SAST)"
-msgstr ""
+msgstr "é™çš„アプリケーションセキュリティテスト (SAST)"
msgid "StaticSiteEditor|An error occurred while submitting your changes."
msgstr ""
@@ -19797,7 +20985,7 @@ msgid "StaticSiteEditor|Your changes have been submitted and a merge request has
msgstr ""
msgid "Statistics"
-msgstr ""
+msgstr "統計"
msgid "Status"
msgstr "状態"
@@ -19854,6 +21042,9 @@ msgid "StatusPage|your status page frontend."
msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
+msgstr "Prometheus を設定ã™ã‚‹äº‹ã§ã‚ãªãŸã®ç’°å¢ƒã®ãƒ‘フォーマンスã¨å¥å…¨æ€§ã®æœ€æ–°çŠ¶æ…‹ã‚’å–得出æ¥ã¾ã™ã€‚"
+
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
msgstr ""
msgid "Stop Terminal"
@@ -19883,20 +21074,23 @@ msgstr "ストレージ:"
msgid "StorageSize|Unknown"
msgstr "ä¸æ˜Ž"
-msgid "Subgroup overview"
+msgid "Subgroup milestone"
msgstr ""
+msgid "Subgroup overview"
+msgstr "サブグループã®æ¦‚è¦"
+
msgid "SubgroupCreationLevel|Allowed to create subgroups"
-msgstr ""
+msgstr "サブグループã®ä½œæˆã‚’許å¯"
msgid "SubgroupCreationlevel|Allowed to create subgroups"
-msgstr ""
+msgstr "サブグループã®ä½œæˆã‚’許å¯"
msgid "SubgroupCreationlevel|Maintainers"
-msgstr ""
+msgstr "メンテナー"
msgid "SubgroupCreationlevel|Owners"
-msgstr ""
+msgstr "オーナー"
msgid "Subgroups"
msgstr "サブグループ"
@@ -19910,11 +21104,14 @@ msgstr ""
msgid "Subkeys"
msgstr "サブキー"
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
msgid "Submit a review"
-msgstr ""
+msgstr "レビューをé€ä¿¡"
msgid "Submit as spam"
msgstr "スパムã¨ã—ã¦å ±å‘Š"
@@ -19923,7 +21120,7 @@ msgid "Submit feedback"
msgstr "フィードãƒãƒƒã‚¯ã‚’é€ä¿¡"
msgid "Submit issue"
-msgstr ""
+msgstr "課題ã®é€ä¿¡"
msgid "Submit review"
msgstr "レビューをé€ä¿¡"
@@ -19932,10 +21129,10 @@ msgid "Submit search"
msgstr "検索ã®æ出"
msgid "Submit the current review."
-msgstr ""
+msgstr "ç¾åœ¨ã®ãƒ¬ãƒ“ューをé€ä¿¡"
msgid "Submitted the current review."
-msgstr ""
+msgstr "ç¾åœ¨ã®ãƒ¬ãƒ“ューをé€ä¿¡ã—ã¾ã—ãŸ"
msgid "Subscribe"
msgstr "購読ã™ã‚‹"
@@ -19953,52 +21150,52 @@ msgid "Subscribe to calendar"
msgstr "カレンダーã«ç™»éŒ²"
msgid "Subscribed"
-msgstr ""
+msgstr "購読中"
msgid "Subscribed to this %{quick_action_target}."
-msgstr ""
+msgstr "ã“ã® %{quick_action_target} を購読ã—ã¾ã—ãŸã€‚"
msgid "Subscribes to this %{quick_action_target}."
-msgstr ""
+msgstr "ã“ã® %{quick_action_target} を購読ã—ã¾ã™ã€‚"
msgid "Subscription"
msgstr "サブスクリプション"
msgid "Subscription deletion failed."
-msgstr ""
+msgstr "サブスクリプションã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
msgid "Subscription successfully applied to \"%{group_name}\""
msgstr ""
msgid "Subscription successfully created."
-msgstr ""
+msgstr "サブスクリプションã®ä½œæˆã«æˆåŠŸã—ã¾ã—ãŸã€‚"
msgid "Subscription successfully deleted."
-msgstr ""
+msgstr "サブスクリプションã®å‰Šé™¤ã«æˆåŠŸã—ã¾ã—ãŸã€‚"
msgid "SubscriptionTable|Billing"
-msgstr ""
+msgstr "支払ã„"
msgid "SubscriptionTable|Free"
-msgstr ""
+msgstr "ç„¡æ–™"
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 ""
+msgstr "GitLabã§ã¯ã€è³¼å…¥ã—ãŸã‚·ãƒ¼ãƒˆæ•°ã‚’超ãˆã¦ã‚‚ã€å¼•ã続ãサブスクリプションを使用ã§ãã¾ã™ã€‚ã“れらã®ã‚·ãƒ¼ãƒˆã¯æ›´æ–°æ™‚ã«æ”¯æ‰•ã†å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "SubscriptionTable|Last invoice"
-msgstr ""
+msgstr "å‰ã®è«‹æ±‚書"
msgid "SubscriptionTable|Loading subscriptions"
-msgstr ""
+msgstr "サブスクリプションを読ã¿è¾¼ã¿ä¸­"
msgid "SubscriptionTable|Manage"
-msgstr ""
+msgstr "管ç†"
msgid "SubscriptionTable|Max seats used"
-msgstr ""
+msgstr "使用å¯èƒ½ãªã‚·ãƒ¼ãƒˆæ•°"
msgid "SubscriptionTable|Next invoice"
-msgstr ""
+msgstr "次ã®è«‹æ±‚書"
msgid "SubscriptionTable|Seats currently in use"
msgstr "ç¾åœ¨ä½¿ç”¨ä¸­ã®ã‚·ãƒ¼ãƒˆæ•°"
@@ -20043,10 +21240,10 @@ msgid "SubscriptionTable|Usage"
msgstr "使用方法"
msgid "SubscriptionTable|Usage count is performed once a day at 12:00 PM."
-msgstr ""
+msgstr "使用数ã®ã‚«ã‚¦ãƒ³ãƒˆã¯1æ—¥1回ã€åˆå¾Œ12:00ã«å®Ÿè¡Œã•ã‚Œã¾ã™ã€‚"
msgid "Subscriptions"
-msgstr ""
+msgstr "サブスクリプション"
msgid "Subtracted"
msgstr ""
@@ -20058,7 +21255,7 @@ msgid "Succeeded"
msgstr ""
msgid "Successfully activated"
-msgstr ""
+msgstr "有効化ã«æˆåŠŸã—ã¾ã—ãŸ"
msgid "Successfully blocked"
msgstr "正常ã«ãƒ–ロックã•ã‚Œã¾ã—ãŸ"
@@ -20067,10 +21264,10 @@ msgid "Successfully confirmed"
msgstr "確èªã«æˆåŠŸã—ã¾ã—ãŸ"
msgid "Successfully deactivated"
-msgstr ""
+msgstr "無効化ã«æˆåŠŸã—ã¾ã—ãŸ"
msgid "Successfully deleted U2F device."
-msgstr ""
+msgstr "U2Fデãƒã‚¤ã‚¹ã‚’削除ã—ã¾ã—ãŸã€‚"
msgid "Successfully removed email."
msgstr "メールを削除ã—ã¾ã—ãŸã€‚"
@@ -20088,82 +21285,88 @@ msgid "Successfully verified domain ownership"
msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
+msgstr "ã™ãã«é©ç”¨ã•ã‚Œã‚‹ã‚³ãƒ¼ãƒ‰å¤‰æ›´ã‚’1クリックã§æ案ã—ã¦ã¿ã‚ˆã†ï¼"
+
+msgid "Suggested Solutions"
msgstr ""
msgid "Suggested change"
+msgstr "変更ã®æ案"
+
+msgid "Suggested solutions help link"
msgstr ""
msgid "SuggestedColors|Bright green"
msgstr "ブライトグリーン"
msgid "SuggestedColors|Dark grayish cyan"
-msgstr ""
+msgstr "ç°é’ç·‘"
msgid "SuggestedColors|Dark moderate blue"
-msgstr ""
+msgstr "æš—è—色"
msgid "SuggestedColors|Dark moderate orange"
-msgstr ""
+msgstr "薄茶色"
msgid "SuggestedColors|Dark moderate pink"
-msgstr ""
+msgstr "暗赤紫"
msgid "SuggestedColors|Dark moderate violet"
-msgstr ""
+msgstr "藤色"
msgid "SuggestedColors|Feijoa"
-msgstr ""
+msgstr "明黄緑"
msgid "SuggestedColors|Lime green"
msgstr "ライムグリーン"
msgid "SuggestedColors|Moderate blue"
-msgstr ""
+msgstr "è—色"
msgid "SuggestedColors|Pure red"
-msgstr ""
+msgstr "紅色"
msgid "SuggestedColors|Slightly desaturated blue"
-msgstr ""
+msgstr "ç°è—色"
msgid "SuggestedColors|Slightly desaturated green"
-msgstr ""
+msgstr "ç°ç·‘色"
msgid "SuggestedColors|Soft orange"
-msgstr ""
+msgstr "薄橙色"
msgid "SuggestedColors|Soft red"
-msgstr ""
+msgstr "薄紅色"
msgid "SuggestedColors|Strong pink"
-msgstr ""
+msgstr "赤紫色"
msgid "SuggestedColors|Strong red"
-msgstr ""
+msgstr "赤"
msgid "SuggestedColors|Strong yellow"
-msgstr ""
+msgstr "黄色"
msgid "SuggestedColors|UA blue"
-msgstr ""
+msgstr "明é’色"
msgid "SuggestedColors|Very dark desaturated blue"
-msgstr ""
+msgstr "æš—è—色"
msgid "SuggestedColors|Very dark lime green"
-msgstr ""
+msgstr "暗黄緑色"
msgid "SuggestedColors|Very pale orange"
-msgstr ""
+msgstr "æ·¡æ©™"
msgid "Suggestions:"
-msgstr ""
+msgstr "æ案:"
msgid "Suite"
-msgstr ""
+msgstr "スイート"
msgid "Summary"
-msgstr ""
+msgstr "概è¦"
msgid "Sunday"
msgstr "日曜日"
@@ -20177,6 +21380,9 @@ msgstr "カスタム証明書ã®ã‚µãƒãƒ¼ãƒˆã¯ç„¡åŠ¹ã§ã™ã€‚有効ã«ã™ã‚‹ã«
msgid "Support page URL"
msgstr "サãƒãƒ¼ãƒˆãƒšãƒ¼ã‚¸URL"
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr "ブランãƒãƒ»ã‚¿ã‚°åˆ‡ã‚Šæ›¿ãˆ"
@@ -20184,7 +21390,7 @@ msgid "Switch to GitLab Next"
msgstr "GitLab Nextã«åˆ‡ã‚Šæ›¿ãˆã‚‹"
msgid "Switch to the source to copy the file contents"
-msgstr ""
+msgstr "ソースã«åˆ‡ã‚Šæ›¿ãˆã€ãƒ•ã‚¡ã‚¤ãƒ«ã®å†…容をコピーã—ã¾ã™"
msgid "Sync information"
msgstr "åŒæœŸæƒ…å ±"
@@ -20204,29 +21410,26 @@ msgstr "システム"
msgid "System Hooks"
msgstr "システムフック"
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr "システム情報"
msgid "System default (%{default})"
-msgstr ""
+msgstr "システムã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆ (%{default})"
msgid "System header and footer"
msgstr "システムヘッダーã¨ãƒ•ãƒƒã‚¿ãƒ¼"
msgid "System hook was successfully updated."
-msgstr ""
+msgstr "システムフックã¯æ­£å¸¸ã«æ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚"
msgid "System metrics (Custom)"
msgstr "システムメトリクス(カスタム)"
msgid "System metrics (Kubernetes)"
-msgstr ""
+msgstr "システムメトリクス (Kubernetes)"
msgid "Table of Contents"
-msgstr ""
+msgstr "目次"
msgid "Tag"
msgstr "ã‚¿ã‚°"
@@ -20235,16 +21438,16 @@ msgid "Tag list:"
msgstr "タグ一覧:"
msgid "Tag name"
-msgstr ""
+msgstr "ã‚¿ã‚°å"
msgid "Tag this commit."
-msgstr ""
+msgstr "コミットã«ã‚¿ã‚°ã‚’付ã‘ã¾ã™ã€‚"
msgid "Tagged this commit to %{tag_name} with \"%{message}\"."
-msgstr ""
+msgstr "コミット㫠\"%{message}\" ã¨å…±ã« %{tag_name} タグを付ã‘ã¾ã—ãŸã€‚"
msgid "Tagged this commit to %{tag_name}."
-msgstr ""
+msgstr "ã“ã®ã‚³ãƒŸãƒƒãƒˆã« %{tag_name} タグを付ã‘ã¾ã—ãŸã€‚"
msgid "Tags"
msgstr "ã‚¿ã‚°"
@@ -20253,10 +21456,10 @@ msgid "Tags feed"
msgstr "タグフィード"
msgid "Tags this commit to %{tag_name} with \"%{message}\"."
-msgstr ""
+msgstr "コミット㫠\"%{message}\" ã¨å…±ã« %{tag_name} タグを付ã‘ã¾ã™ã€‚"
msgid "Tags this commit to %{tag_name}."
-msgstr ""
+msgstr "ã“ã®ã‚³ãƒŸãƒƒãƒˆã« %{tag_name} タグを付ã‘ã¾ã™ 。"
msgid "Tags:"
msgstr "ã‚¿ã‚°:"
@@ -20298,7 +21501,7 @@ msgid "TagsPage|New tag"
msgstr "æ–°ã—ã„ã‚¿ã‚°"
msgid "TagsPage|Optionally, add a message to the tag. Leaving this blank creates a %{link_start}lightweight tag.%{link_end}"
-msgstr ""
+msgstr "オプションã¨ã—ã¦ã€ã‚¿ã‚°ã«ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’追加ã—ã¾ã™ã€‚空白ã®ã¾ã¾ã«ã™ã‚‹ã¨ã€%{link_start}軽é‡ã‚¿ã‚°%{link_end}ãŒä½œæˆã•ã‚Œã¾ã™ã€‚"
msgid "TagsPage|Optionally, create a public Release of your project, based on this tag. Release notes are displayed on the %{releases_page_link_start}Releases%{link_end} page. %{docs_link_start}More information%{link_end}"
msgstr ""
@@ -20334,13 +21537,13 @@ msgid "Target Branch"
msgstr "ターゲットブランãƒ"
msgid "Target Path"
-msgstr ""
+msgstr "対象パス"
msgid "Target branch"
msgstr "ターゲットブランãƒ"
msgid "Target-Branch"
-msgstr ""
+msgstr "ターゲットブランãƒ"
msgid "Team"
msgstr "ãƒãƒ¼ãƒ "
@@ -20349,19 +21552,19 @@ msgid "Team domain"
msgstr "ãƒãƒ¼ãƒ ãƒ‰ãƒ¡ã‚¤ãƒ³"
msgid "Telephone number"
-msgstr ""
+msgstr "電話番å·"
msgid "Telephone number (Optional)"
-msgstr ""
+msgstr "é›»è©±ç•ªå· (オプション)"
msgid "Template"
msgstr "テンプレート"
msgid "Template to append to all Service Desk issues"
-msgstr ""
+msgstr "å…¨ã¦ã®ã‚µãƒ¼ãƒ“スデスク課題ã«è¿½åŠ ã™ã‚‹ãƒ†ãƒ³ãƒ—レート"
msgid "Template was successfully saved."
-msgstr ""
+msgstr "テンプレートã®ä¿å­˜ã«æˆåŠŸã—ã¾ã—ãŸã€‚"
msgid "Templates"
msgstr "テンプレート"
@@ -20373,7 +21576,7 @@ msgid "Terminal for environment"
msgstr "環境ターミナル"
msgid "Terminal sync service is running"
-msgstr ""
+msgstr "端末ã®åŒæœŸã‚µãƒ¼ãƒ“スãŒå®Ÿè¡Œã•ã‚Œã¦ã„ã¾ã™"
msgid "Terms of Service Agreement and Privacy Policy"
msgstr "利用è¦ç´„ã¨ãƒ—ライãƒã‚·ãƒ¼ãƒãƒªã‚·ãƒ¼"
@@ -20382,7 +21585,7 @@ msgid "Terms of Service and Privacy Policy"
msgstr "利用è¦ç´„ã¨ãƒ—ライãƒã‚·ãƒ¼ãƒãƒªã‚·ãƒ¼"
msgid "Test"
-msgstr ""
+msgstr "テスト"
msgid "Test coverage parsing"
msgstr "テストカãƒãƒ¬ãƒƒã‚¸è§£æž"
@@ -20422,39 +21625,42 @@ msgid "TestHooks|Ensure the wiki is enabled and has pages."
msgstr "ã“ã®wikiãŒæœ‰åŠ¹ã§ã€ãƒšãƒ¼ã‚¸ãŒã‚ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。"
msgid "TestReports|%{count} errors"
-msgstr ""
+msgstr "%{count} 件ã®ã‚¨ãƒ©ãƒ¼"
msgid "TestReports|%{count} failures"
-msgstr ""
+msgstr "%{count} 件ã®å¤±æ•—"
msgid "TestReports|%{count} jobs"
-msgstr ""
+msgstr "%{count} 件ã®ã‚¸ãƒ§ãƒ–"
msgid "TestReports|%{rate}%{sign} success rate"
-msgstr ""
+msgstr "%{rate}%{sign} æˆåŠŸçŽ‡"
msgid "TestReports|Test suites"
-msgstr ""
+msgstr "テストスイート"
msgid "TestReports|Tests"
-msgstr ""
+msgstr "テスト"
msgid "TestReports|There are no test cases to display."
-msgstr ""
+msgstr "表示ã™ã‚‹ãƒ†ã‚¹ãƒˆã‚±ãƒ¼ã‚¹ã¯ã‚ã‚Šã¾ã›ã‚“。"
msgid "TestReports|There are no test suites to show."
-msgstr ""
+msgstr "表示ã™ã‚‹ãƒ†ã‚¹ãƒˆã‚¹ã‚¤ãƒ¼ãƒˆã¯ã‚ã‚Šã¾ã›ã‚“。"
msgid "TestReports|There are no tests to show."
-msgstr ""
+msgstr "表示ã™ã‚‹ãƒ†ã‚¹ãƒˆã¯ã‚ã‚Šã¾ã›ã‚“。"
msgid "TestReports|There was an error fetching the test reports."
-msgstr ""
+msgstr "テストレãƒãƒ¼ãƒˆã‚’å–å¾—ã™ã‚‹é–“ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "Tests"
-msgstr ""
+msgstr "テスト"
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
+msgstr "無料トライアルライセンスã«ãŠç”³ã—è¾¼ã¿ã„ãŸã ãã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™ã€‚手順ã¯ç™»éŒ²ã•ã‚ŒãŸãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã«é€ä¿¡ã•ã‚Œã¾ã™ã€‚"
+
+msgid "Thank you for your feedback!"
msgstr ""
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
@@ -20473,7 +21679,7 @@ msgid "The \"%{group_path}\" group allows you to sign in with your Single Sign-O
msgstr "ã“ã® %{group_path} グループã§ã€ã‚ãªãŸã¯ã‚·ãƒ³ã‚°ãƒ«ã‚µã‚¤ãƒ³ã‚ªãƒ³ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã§ã‚µã‚¤ãƒ³ã‚¤ãƒ³ã§ãã¾ã™ã€‚"
msgid "The \"Require approval from CODEOWNERS\" setting was moved to %{banner_link_start}Protected Branches%{banner_link_end}"
-msgstr ""
+msgstr "\"CODEOWNERSã‹ã‚‰ã®æ‰¿èªãŒå¿…è¦\" 設定ã¯%{banner_link_start}ä¿è­·ã•ã‚ŒãŸãƒ–ランãƒ%{banner_link_end}ã«ç§»å‹•ã—ã¾ã—ãŸ"
msgid "The %{link_start}true-up model%{link_end} allows having more users, and additional users will incur a retroactive charge on renewal."
msgstr ""
@@ -20483,7 +21689,7 @@ msgstr ""
msgid "The %{type} contains the following error:"
msgid_plural "The %{type} contains the following errors:"
-msgstr[0] ""
+msgstr[0] "%{type} ã«æ¬¡ã®ã‚¨ãƒ©ãƒ¼ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "The Advanced Global 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 "GitLab ã®é«˜åº¦ãªã‚°ãƒ­ãƒ¼ãƒãƒ«æ¤œç´¢ã¯ã€æ™‚間を節約ã§ãる強力ãªæ¤œç´¢ã‚µãƒ¼ãƒ“スã§ã™ã€‚é‡è¤‡ã—ãŸã‚³ãƒ¼ãƒ‰ã®ä½œæˆã‚’ã—ã¦æ™‚間を無駄ã«ã™ã‚‹ã“ã¨ãªãã€è‡ªèº«ã®ãƒ—ロジェクトã®åŠ©ã‘ã¨ãªã‚‹å¤–ã®ãƒãƒ¼ãƒ ã®ã‚³ãƒ¼ãƒ‰ã‚’検索ã™ã‚‹ã“ã¨ãŒã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚"
@@ -20501,13 +21707,13 @@ msgid "The Issue Tracker is the place to add things that need to be improved or
msgstr "課題トラッカーã¯ã€ãƒ—ロジェクトを改善ã—ãŸã‚Šè§£æ±ºã—ãŸã‚Šã™ã‚‹ãŸã‚ã«å¿…è¦ãªæƒ…報を追加ã™ã‚‹å ´æ‰€ã§ã™ã€‚ã“ã®ãƒ—ロジェクトã«èª²é¡Œã‚’作æˆã™ã‚‹ãŸã‚ã«ã¯ã€ãƒ¦ãƒ¼ã‚¶ãƒ¼ç™»éŒ²ã¾ãŸã¯ã‚µã‚¤ãƒ³ã‚¤ãƒ³ã—ã¦ãã ã•ã„。"
msgid "The Prometheus server responded with \"bad request\". Please check your queries are correct and are supported in your Prometheus version. %{documentationLink}"
-msgstr ""
+msgstr "Prometheusサーãƒãƒ¼ã¯ã€Œæ‚ªã„リクエストã€ã¨å¿œç­”ã—ã¾ã—ãŸã€‚クエリãŒæ­£ã—ãã‚ãªãŸã®Prometheusã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。 %{documentationLink}"
msgid "The URL defined on the primary node that secondary nodes should use to contact it. Defaults to URL"
msgstr ""
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 ""
+msgstr "Elasticsearchã¸ã®æŽ¥ç¶šã«ä½¿ç”¨ã™ã‚‹URL。クラスタリングをサãƒãƒ¼ãƒˆã™ã‚‹ã«ã¯ã€ã‚³ãƒ³ãƒžåŒºåˆ‡ã‚Šãƒªã‚¹ãƒˆã‚’使用ã—ã¾ã™(例: http://localhost:9200, http://localhost:9201)。"
msgid "The X509 Certificate to use when mutual TLS is required to communicate with the external authorization service. If left blank, the server certificate is still validated when accessing over HTTPS."
msgstr "外部èªè¨¼ã‚µãƒ¼ãƒ“スã¨ã®é€šä¿¡ã«ç›¸äº’ TLS ãŒå¿…è¦ãªå ´åˆã«ä½¿ç”¨ã™ã‚‹ X509 証明書。空白ã®ã¾ã¾ã«ã™ã‚‹ã¨ã€HTTPS 経由ã§ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã¨ãã«ã‚µãƒ¼ãƒè¨¼æ˜Žæ›¸ã®æ¤œè¨¼ãŒè¡Œã‚ã‚Œã¾ã™ã€‚"
@@ -20525,7 +21731,7 @@ msgid "The branch for this project has no active pipeline configuration."
msgstr "ã“ã®ãƒ—ロジェクトã®ã“ã®ãƒ–ランãƒã«ã‚¢ã‚¯ãƒ†ã‚£ãƒ–ãªãƒ‘イプライン設定ãŒã‚ã‚Šã¾ã›ã‚“。"
msgid "The branch or tag does not exist"
-msgstr ""
+msgstr "ブランãƒã¾ãŸã¯ã‚¿ã‚°ã¯å­˜åœ¨ã—ã¾ã›ã‚“"
msgid "The character highlighter helps you keep the subject line to %{titleLength} characters and wrap the body at %{bodyLength} so they are readable in git."
msgstr "キャラクターãƒã‚¤ãƒ©ã‚¤ã‚¿ãƒ¼ã¯ã€ä»¶åã‚’ %{titleLength} 文字ã«ã€æœ¬æ–‡ã‚’ %{bodyLength} 文字ã«ã¾ã¨ã‚ã€gitã§èª­ã‚るよã†ã«ã—ã¾ã™ã€‚"
@@ -20537,10 +21743,7 @@ msgid "The collection of events added to the data gathered for that stage."
msgstr "ã“ã®ã‚¹ãƒ†ãƒ¼ã‚¸ã§è¨ˆæ¸¬ãƒ‡ãƒ¼ã‚¿ã«è¿½åŠ ã•ã‚ŒãŸã‚¤ãƒ™ãƒ³ãƒˆãƒªã‚¹ãƒˆ"
msgid "The commit does not exist"
-msgstr ""
-
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
+msgstr "コミットãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。"
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr "コãƒã‚¯ã‚·ãƒ§ãƒ³ã¯ %{timeout} ã§ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ã¾ã™ã€‚タイムアウトã™ã‚‹ãƒªãƒã‚¸ãƒˆãƒªã§ã¯ã€clone/push を組ã¿åˆã‚ã›ã¦ä½¿ç”¨ã—ã¦ãã ã•ã„。"
@@ -20552,16 +21755,16 @@ msgid "The contents of this group, its subgroups and projects will be permanentl
msgstr ""
msgid "The current issue"
-msgstr ""
+msgstr "ç¾åœ¨ã®èª²é¡Œ"
msgid "The data source is connected, but there is no data to display. %{documentationLink}"
-msgstr ""
+msgstr "データソースã«ã¯æŽ¥ç¶šã§ãã¦ã„ã¾ã™ãŒã€è¡¨ç¤ºã™ã‚‹ãƒ‡ãƒ¼ã‚¿ã¯ã‚ã‚Šã¾ã›ã‚“。 %{documentationLink}"
msgid "The default CI configuration path for new projects."
msgstr ""
msgid "The dependency list details information about the components used within your project."
-msgstr ""
+msgstr "ä¾å­˜é–¢ä¿‚リストã«ã¯ãƒ—ロジェクト内ã§ä½¿ç”¨ã•ã‚Œã¦ã„るコンãƒãƒ¼ãƒãƒ³ãƒˆã«é–¢ã™ã‚‹è©³ç´°æƒ…å ±ãŒè¨˜è¼‰ã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "The deployment of this job to %{environmentLink} did not succeed."
msgstr "ã“ã®ã‚¸ãƒ§ãƒ–ã® %{environmentLink} ã¸ã®ãƒ‡ãƒ—ロイã¯æˆåŠŸã—ã¾ã›ã‚“ã§ã—ãŸã€‚"
@@ -20573,28 +21776,34 @@ msgid "The directory has been successfully created."
msgstr "ディレクトリã®ä½œæˆã«æˆåŠŸã—ã¾ã—ãŸ"
msgid "The domain you entered is misformatted."
-msgstr ""
+msgstr "ã‚ãªãŸãŒå…¥åŠ›ã—ãŸãƒ‰ãƒ¡ã‚¤ãƒ³ã¯å½¢å¼ãŒé–“é•ã£ã¦ã„ã¾ã™ã€‚"
msgid "The domain you entered is not allowed."
+msgstr "ã‚ãªãŸãŒå…¥åŠ›ã—ãŸãƒ‰ãƒ¡ã‚¤ãƒ³ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“。"
+
+msgid "The download link will expire in 24 hours."
msgstr ""
msgid "The entered user map is not a valid JSON user map."
msgstr "入力ã•ã‚ŒãŸãƒ¦ãƒ¼ã‚¶ãƒ¼ãƒžãƒƒãƒ—ã¯ã€æœ‰åŠ¹ãªJSONユーザーマップã§ã¯ã‚ã‚Šã¾ã›ã‚“。"
-msgid "The file has been successfully created."
+msgid "The errors we encountered were:"
msgstr ""
+msgid "The file has been successfully created."
+msgstr "ファイルã¯æ­£å¸¸ã«ä½œæˆã•ã‚Œã¾ã—ãŸã€‚"
+
msgid "The file has been successfully deleted."
-msgstr ""
+msgstr "ファイルã¯æ­£å¸¸ã«å‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚"
msgid "The file name should have a .yml extension"
msgstr ""
msgid "The following items will NOT be exported:"
-msgstr ""
+msgstr "次ã®ã‚¢ã‚¤ãƒ†ãƒ ã¯ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã§ãã¾ã›ã‚“。"
msgid "The following items will be exported:"
-msgstr ""
+msgstr "次ã®ã‚¢ã‚¤ãƒ†ãƒ ã¯ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã—ã¾ã™ã€‚"
msgid "The following personal access token: %{token_names} was revoked, because a new policy to expire personal access tokens were set."
msgid_plural "The following personal access tokens: %{token_names} were revoked, because a new policy to expire personal access tokens were set."
@@ -20604,20 +21813,23 @@ msgid "The fork relationship has been removed."
msgstr "フォークã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãŒå‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚"
msgid "The global settings require you to enable Two-Factor Authentication for your account."
-msgstr ""
+msgstr "グローãƒãƒ«è¨­å®šã§ã¯ã€è‡ªåˆ†ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã«å¯¾ã—ã¦2è¦ç´ èªè¨¼ã‚’有効ã«ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "The group and any internal projects can be viewed by any logged in user."
-msgstr ""
+msgstr "グループã¨å†…部プロジェクトã¯ã™ã¹ã¦ã€ãƒ­ã‚°ã‚¤ãƒ³ã—ã¦ã„るユーザーãªã‚‰èª°ã§ã‚‚見るã“ã¨ãŒã§ãã¾ã™ã€‚"
msgid "The group and any public projects can be viewed without any authentication."
-msgstr ""
+msgstr "グループãŠã‚ˆã³å…¬é–‹ãƒ—ロジェクトã¯èªè¨¼ç„¡ã—ã§é–²è¦§ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
msgid "The group and its projects can only be viewed by members."
-msgstr ""
+msgstr "グループã¨ãã®ãƒ—ロジェクトã¯ãƒ¡ãƒ³ãƒãƒ¼ã®ã¿ãŒé–²è¦§ã§ãã¾ã™"
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20634,13 +21846,13 @@ msgid "The invitation could not be accepted."
msgstr ""
msgid "The invitation could not be declined."
-msgstr ""
+msgstr "招待を辞退ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
msgid "The invitation has already been accepted."
msgstr ""
msgid "The invitation was successfully resent."
-msgstr ""
+msgstr "招待をå†é€ã—ã¾ã—ãŸã€‚"
msgid "The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage."
msgstr "課題ステージã§ã¯ã€èª²é¡ŒãŒç™»éŒ²ã•ã‚Œã¦ã‹ã‚‰ãƒžã‚¤ãƒ«ã‚¹ãƒˆãƒ¼ãƒ³ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã‚‹ã‹ã€èª²é¡Œãƒœãƒ¼ãƒ‰ã®ãƒªã‚¹ãƒˆã«è¿½åŠ ã•ã‚Œã‚‹ã¾ã§ã®æ™‚é–“ãŒè¡¨ç¤ºã•ã‚Œã¾ã™ã€‚ã“ã®ãƒªã‚¹ãƒˆã«è¡¨ç¤ºã™ã‚‹ã«ã¯èª²é¡Œã‚’最åˆã«ä½œæˆã—ã¦ãã ã•ã„。"
@@ -20652,7 +21864,7 @@ msgid "The license was removed. GitLab has fallen back on the previous license."
msgstr "ライセンスãŒå‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚ GitLab ã¯ä»¥å‰ã®ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã«æˆ»ã‚Šã¾ã—ãŸã€‚"
msgid "The license was removed. GitLab now no longer has a valid license."
-msgstr ""
+msgstr "ライセンスãŒå‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚ GitLab ã¯ç¾åœ¨ã€æœ‰åŠ¹ãªãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã‚’æŒã£ã¦ã„ã¾ã›ã‚“。"
msgid "The license was successfully uploaded and is now active. You can see the details below."
msgstr "ライセンスã¯æ­£å¸¸ã«ã‚¢ãƒƒãƒ—ロードã•ã‚Œã€ã‚¢ã‚¯ãƒ†ã‚£ãƒ–ã«ãªã‚Šã¾ã—ãŸã€‚ã‚ãªãŸã¯ã€è©³ç´°ãŒè¦‹ã‚Œã¾ã™ã€‚"
@@ -20676,13 +21888,13 @@ msgid "The merge conflicts for this merge request have already been resolved. Pl
msgstr "ã“ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã«å¯¾ã™ã‚‹ãƒžãƒ¼ã‚¸ã®ç«¶åˆã¯ã™ã§ã«è§£æ±ºã•ã‚Œã¦ã„ã¾ã™ã€‚マージリクエストã«æˆ»ã£ã¦ãã ã•ã„。"
msgid "The merge request can now be merged."
-msgstr ""
+msgstr "ã“ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã¯ä»Šã€ãƒžãƒ¼ã‚¸ã§ãã¾ã™ã€‚"
msgid "The name \"%{name}\" is already taken in this directory."
-msgstr ""
+msgstr "ã“ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«ã¯ã€ \"%{name}\" ã¨ã„ã†åå‰ãŒã™ã§ã«ä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "The number of changes to be fetched from GitLab when cloning a repository. This can speed up Pipelines execution. Keep empty or set to 0 to disable shallow clone by default and make GitLab CI fetch all branches and tags each time."
-msgstr ""
+msgstr "リãƒã‚¸ãƒˆãƒªã‚’クローンã™ã‚‹ã¨ãã« GitLab ã‹ã‚‰å–å¾—ã•ã‚Œã‚‹å¤‰æ›´ã®æ•°ã€‚ã“ã‚Œã«ã‚ˆã‚Šãƒ‘イプラインã®å®Ÿè¡Œé€Ÿåº¦ã‚’上ã’ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚空ã®ã¾ã¾ã«ã™ã‚‹ã‹ã€0 ã«è¨­å®šã—ã¦ã€ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§ã‚·ãƒ£ãƒ­ãƒ¼ã‚¯ãƒ­ãƒ¼ãƒ³ã‚’無効ã«ã—ã€GitLab CI ã«æ¯Žå›žã™ã¹ã¦ã®ãƒ–ランãƒã¨ã‚¿ã‚°ã‚’å–å¾—ã•ã›ã¾ã™ã€‚"
msgid "The number of times an upload record could not find its file"
msgstr "アップロードレコードãŒãƒ•ã‚¡ã‚¤ãƒ«ã‚’見ã¤ã‘られãªã‹ã£ãŸå›žæ•°"
@@ -20694,13 +21906,13 @@ msgid "The passphrase required to decrypt the private key. This is optional and
msgstr "秘密éµã®å¾©å·ã«å¿…è¦ã¨ãªã‚‹ãƒ‘スフレーズ。ã“ã‚Œã¯ã‚ªãƒ—ションã§ã€å€¤ã¯æš—å·åŒ–ã—ã¦ä¿å­˜ã•ã‚Œã¾ã™ã€‚"
msgid "The path to the CI configuration file. Defaults to <code>.gitlab-ci.yml</code>"
-msgstr ""
+msgstr "CI 設定ファイルã¸ã®ãƒ‘ス。デフォルト㯠<code>.gitlab-ci.yml</code>"
msgid "The phase of the development lifecycle."
msgstr "開発ライフサイクルã®æ®µéšŽ"
msgid "The pipeline has been deleted"
-msgstr ""
+msgstr "パイプラインã¯å‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚"
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 "パイプラインスケジュールã¯æŒ‡å®šã®ãƒ–ランãƒã¾ãŸã¯ã‚¿ã‚°ã«å¯¾ã—ã¦è‡ªå‹•çš„ã«ãƒ‘イプラインを実行ã—ã¾ã™ã€‚計画済ã¿ãƒ‘イプラインã¯ãれらã®ç´ä»˜ã‘られãŸãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ãƒ—ロジェクトã¨åŒã˜æ¨©é™ã‚’継承ã—ã¾ã™ã€‚"
@@ -20736,7 +21948,7 @@ msgid "The project was successfully forked."
msgstr "プロジェクトã¯æ­£å¸¸ã«ãƒ•ã‚©ãƒ¼ã‚¯ã•ã‚Œã¾ã—ãŸã€‚"
msgid "The project was successfully imported."
-msgstr ""
+msgstr "プロジェクトを正常ã«ã‚¤ãƒ³ãƒãƒ¼ãƒˆã§ãã¾ã—ãŸã€‚"
msgid "The pseudonymizer data collection is disabled. When enabled, 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 ã¯ã€ã‚ãªãŸãŒè¨­å®šã—ãŸã‚ªãƒ–ジェクトストレージディレクトリã«ã‚¢ãƒƒãƒ—ロードã™ã‚‹ GitLab データベースã®åŒ¿å化ã—㟠CSV を生æˆã™ã‚‹ã‚¸ãƒ§ãƒ–ã‚’ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ã§å®Ÿè¡Œã—ã¾ã™ã€‚"
@@ -20748,7 +21960,7 @@ msgid "The remote repository is being updated..."
msgstr "リモートリãƒã‚¸ãƒˆãƒªã¯ç¾åœ¨ã€æ›´æ–°ä¸­ã§ã™ã€‚"
msgid "The repository can be commited to, and issues, comments and other entities can be created."
-msgstr ""
+msgstr "ã“ã®ãƒªãƒã‚¸ãƒˆãƒªã«ã¯ã‚³ãƒŸãƒƒãƒˆã€èª²é¡Œã€ã‚³ãƒ¡ãƒ³ãƒˆã€ãã®ä»–ã®ã‚¨ãƒ³ãƒ†ã‚£ãƒ†ã‚£ã‚’作æˆã§ãã¾ã™ã€‚"
msgid "The repository for this project does not exist."
msgstr "ã“ã®ãƒ—ロジェクトã«ãƒªãƒã‚¸ãƒˆãƒªã¯ã‚ã‚Šã¾ã›ã‚“。"
@@ -20763,7 +21975,7 @@ msgid "The repository must be accessible over <code>http://</code>, <code>https:
msgstr "リãƒã‚¸ãƒˆãƒªã«ã¯ã€<code>http://</code>〠<code>https://</code> ã¾ãŸã¯ <code>git://</code>ã§æŽ¥ç¶šã§ããªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。"
msgid "The repository must be accessible over <code>http://</code>, <code>https://</code>, <code>ssh://</code> or <code>git://</code>."
-msgstr ""
+msgstr "リãƒã‚¸ãƒˆãƒªã¯ <code>http://</code>ã€<code>https://</code>ã€<code>ssh://</code>ã€<code>git://</code>ã®ã„ãšã‚Œã‹ã§ã‚¢ã‚¯ã‚»ã‚¹ã§ãã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request."
msgstr "レビューステージã¨ã¯ã€ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’作æˆã—ã¦ã‹ã‚‰ãƒžãƒ¼ã‚¸ã™ã‚‹ã¾ã§ã®æ™‚é–“ã§ã™ã€‚ã“ã®ãƒ‡ãƒ¼ã‚¿ã¯æœ€åˆã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆãŒãƒžãƒ¼ã‚¸ã•ã‚ŒãŸã¨ãã«è‡ªå‹•çš„ã«è¿½åŠ ã•ã‚Œã¾ã™ã€‚"
@@ -20778,7 +21990,7 @@ msgid "The snippet can be accessed without any authentication."
msgstr "ã“ã®ã‚¹ãƒ‹ãƒšãƒƒãƒˆã¯èªè¨¼ç„¡ã—ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã™"
msgid "The snippet is visible only to me."
-msgstr ""
+msgstr "スニペットã¯ç§ã ã‘ãŒè¦‹ãˆã¾ã™ã€‚"
msgid "The snippet is visible only to project members."
msgstr "スニペットã¯ãƒ—ロジェクトメンãƒãƒ¼ã ã‘ãŒè¦‹ã‚Œã¾ã™ã€‚"
@@ -20787,11 +21999,14 @@ msgid "The snippet is visible to any logged in user."
msgstr "スニペットã¯ã€ãƒ­ã‚°ã‚¤ãƒ³ã—ã¦ã„ã‚‹ã™ã¹ã¦ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒè¦‹ã‚Œã¾ã™ã€‚"
msgid "The specified tab is invalid, please select another"
-msgstr ""
+msgstr "指定ã—ãŸã‚¿ãƒ–ã¯ç„¡åŠ¹ã§ã™ã€‚別ã®ã‚¿ãƒ–ã‚’é¸æŠžã—ã¦ãã ã•ã„"
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr "ステージングステージã§ã¯ã€ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆãŒãƒžãƒ¼ã‚¸ã•ã‚Œã¦ã‹ã‚‰ã‚³ãƒ¼ãƒ‰ãŒãƒ—ロダクション環境ã«ãƒ‡ãƒ—ロイã•ã‚Œã‚‹ã¾ã§ã®æ™‚é–“ãŒè¡¨ç¤ºã•ã‚Œã¾ã™ã€‚ã“ã®ãƒ‡ãƒ¼ã‚¿ã¯æœ€åˆã«ãƒ—ロダクションã«ãƒ‡ãƒ—ロイã—ãŸã¨ãã«è‡ªå‹•çš„ã«è¿½åŠ ã•ã‚Œã¾ã™ã€‚"
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr "テスティングステージã§ã¯ã€GitLab CI ãŒé–¢é€£ã™ã‚‹ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã®å„パイプラインを実行ã™ã‚‹æ™‚é–“ãŒè¡¨ç¤ºã•ã‚Œã¾ã™ã€‚ã“ã®ãƒ‡ãƒ¼ã‚¿ã¯æœ€åˆã®ãƒ‘イプラインãŒå®Œäº†ã—ãŸã¨ãã«è‡ªå‹•çš„ã«è¿½åŠ ã•ã‚Œã¾ã™ã€‚"
@@ -20817,7 +22032,7 @@ msgid "The user is being deleted."
msgstr "ユーザーを削除中ã§ã™ã€‚"
msgid "The user map has been saved. Continue by selecting the projects you want to import."
-msgstr ""
+msgstr "ユーザーマップをä¿å­˜ã—ã¾ã—ãŸã€‚インãƒãƒ¼ãƒˆå¯¾è±¡ã®ãƒ—ロジェクトをé¸æŠžã—ã¦ç¶šã‘ã¦ãã ã•ã„。"
msgid "The user map is a JSON document mapping the Google Code users that participated on your projects to the way their email addresses and usernames will be imported into GitLab. You can change this by changing the value on the right hand side of <code>:</code>. Be sure to preserve the surrounding double quotes, other punctuation and the email address or username on the left hand side."
msgstr "ユーザーマップã¯ã€ã‚ãªãŸã®ãƒ—ロジェクトã«å‚加ã—㟠Google コードã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã¨ãƒ¦ãƒ¼ã‚¶ãƒ¼åã‚’ GitLab ã«ã‚¤ãƒ³ãƒãƒ¼ãƒˆã™ã‚‹ã¨ãã«ãƒžãƒƒãƒ”ングã™ã‚‹ JSON ファイルã§ã™ã€‚ã“れを変更ã™ã‚‹ã«ã¯ã€ <code>:</code> ã®å³å´ã®å€¤ã‚’変更ã—ã¾ã™ã€‚å·¦å´ã®äºŒé‡å¼•ç”¨ç¬¦ã€ãã®ä»–ã®å¥èª­ç‚¹ã€ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã¾ãŸã¯ãƒ¦ãƒ¼ã‚¶ãƒ¼åãŒä¿å­˜ã•ã‚Œã¾ã™ã€‚"
@@ -20829,7 +22044,7 @@ msgid "The user you are trying to deactivate has been active in the past %{minim
msgstr ""
msgid "The user-facing URL of the Geo node"
-msgstr ""
+msgstr "ジオノードã®ãƒ¦ãƒ¼ã‚¶ãƒ¼å‘ã‘ã®URL。"
msgid "The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6."
msgstr "得られãŸä¸€é€£ã®ãƒ‡ãƒ¼ã‚¿ã‚’å°ã•ã„é †ã«ä¸¦ã¹ãŸã¨ãã«ä¸­å¤®ã«ä½ç½®ã™ã‚‹å€¤ã€‚例ãˆã°ã€3, 5, 9 ã®ä¸­å¤®å€¤ã¯ 5。3, 5, 7, 8 ã®ä¸­å¤®å€¤ã¯ (5+7)/2 = 6。"
@@ -20840,11 +22055,14 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
-msgid "There are no GPG keys associated with this account."
+msgid "There are no %{replicableTypeName} to show"
msgstr ""
+msgid "There are no GPG keys associated with this account."
+msgstr "ã“ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã«ç´ä»˜ã„ã¦ã„ã‚‹ GPG éµã¯ã‚ã‚Šã¾ã›ã‚“"
+
msgid "There are no GPG keys with access to your account."
-msgstr ""
+msgstr "ã‚ãªãŸã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ãŸã‚ã® GPG éµãŒã‚ã‚Šã¾ã›ã‚“"
msgid "There are no SSH keys associated with this account."
msgstr "ã“ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã«ç´ä»˜ã„ã¦ã„ã‚‹SSH éµã¯ã‚ã‚Šã¾ã›ã‚“"
@@ -20862,7 +22080,7 @@ msgid "There are no changes"
msgstr ""
msgid "There are no charts configured for this page"
-msgstr ""
+msgstr "ã“ã®ãƒšãƒ¼ã‚¸ã«è¨­å®šã—ã¦ã„ã‚‹ãƒãƒ£ãƒ¼ãƒˆã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "There are no closed issues"
msgstr "クローズã•ã‚ŒãŸèª²é¡Œã¯ã‚ã‚Šã¾ã›ã‚“"
@@ -20877,13 +22095,13 @@ msgid "There are no issues to show"
msgstr "表示ã™ã‚‹èª²é¡ŒãŒã‚ã‚Šã¾ã›ã‚“"
msgid "There are no issues to show."
-msgstr ""
+msgstr "表示ã™ã‚‹èª²é¡ŒãŒã‚ã‚Šã¾ã›ã‚“."
msgid "There are no labels yet"
msgstr "ã¾ã ãƒ©ãƒ™ãƒ«ãŒã‚ã‚Šã¾ã›ã‚“"
msgid "There are no matching files"
-msgstr ""
+msgstr "一致ã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ãŒã‚ã‚Šã¾ã›ã‚“。"
msgid "There are no open issues"
msgstr "オープン中ã®èª²é¡Œã¯ã‚ã‚Šã¾ã›ã‚“"
@@ -20892,7 +22110,7 @@ msgid "There are no open merge requests"
msgstr "オープン中ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "There are no open requirements"
-msgstr ""
+msgstr "オープン中ã®è¦æ±‚事項ã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "There are no packages yet"
msgstr "ã¾ã ãƒ‘ッケージãŒã‚ã‚Šã¾ã›ã‚“。"
@@ -20907,28 +22125,37 @@ msgid "There is a limit of %{ci_project_subscriptions_limit} subscriptions from
msgstr ""
msgid "There is already a repository with that name on disk"
-msgstr ""
+msgstr "ãã®åå‰ã®ãƒªãƒã‚¸ãƒˆãƒªã¯ã™ã§ã«ãƒ‡ã‚£ã‚¹ã‚¯ä¸Šã«ã‚ã‚Šã¾ã™"
msgid "There is no data available. Please change your selection."
-msgstr ""
+msgstr "利用ã§ãるデータã¯ã‚ã‚Šã¾ã›ã‚“。é¸æŠžã—ç›´ã—ã¦ãã ã•ã„。"
msgid "There was a problem communicating with your device."
+msgstr "ã‚ãªãŸã®ãƒ‡ãƒã‚¤ã‚¹ã¨ã®é–“ã«é€šä¿¡éšœå®³ãŒç™ºç”Ÿã—ã¦ã„ã¾ã™ã€‚"
+
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
msgstr ""
msgid "There was a problem refreshing the data, please try again"
msgstr ""
msgid "There was a problem saving your custom stage, please try again"
-msgstr ""
+msgstr "ã‚ãªãŸã®ã‚«ã‚¹ã‚¿ãƒ ã‚¹ãƒ†ãƒ¼ã‚¸ã‚’ä¿å­˜ã™ã‚‹éš›ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
msgid "There was a problem sending the confirmation email"
-msgstr ""
+msgstr "確èªãƒ¡ãƒ¼ãƒ«ã®é€ä¿¡ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "There was an error %{message} todo."
-msgstr ""
+msgstr "Todoã® %{message} ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "There was an error adding a To Do."
-msgstr ""
+msgstr "To Doã®è¿½åŠ ã§ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "There was an error creating the dashboard, branch name is invalid."
msgstr ""
@@ -20937,22 +22164,22 @@ msgid "There was an error creating the dashboard, branch named: %{branch} alread
msgstr ""
msgid "There was an error creating the issue"
-msgstr ""
+msgstr "課題ã®ä½œæˆä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
msgid "There was an error deleting the To Do."
-msgstr ""
+msgstr "To Doã®å‰Šé™¤ã§ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "There was an error fetching configuration for charts"
-msgstr ""
+msgstr "ãƒãƒ£ãƒ¼ãƒˆè¨­å®šã®å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
msgid "There was an error fetching data for the selected stage"
-msgstr ""
+msgstr "é¸æŠžã—ãŸã‚¹ãƒ†ãƒ¼ã‚¸ã®ãƒ‡ãƒ¼ã‚¿ã‚’å–å¾—ã™ã‚‹é–“ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "There was an error fetching data for the tasks by type chart"
msgstr ""
msgid "There was an error fetching label data for the selected group"
-msgstr ""
+msgstr "é¸æŠžã—ãŸã‚°ãƒ«ãƒ¼ãƒ—ã®ãƒ©ãƒ™ãƒ«ãƒ‡ãƒ¼ã‚¿ã‚’å–å¾—ã™ã‚‹é–“ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "There was an error fetching median data for stages"
msgstr ""
@@ -20973,10 +22200,10 @@ msgid "There was an error fetching the variables."
msgstr ""
msgid "There was an error fetching value stream analytics stages."
-msgstr ""
+msgstr "ãƒãƒªãƒ¥ãƒ¼ã‚¹ãƒˆãƒªãƒ¼ãƒ åˆ†æžã‚¹ãƒ†ãƒ¼ã‚¸ã‚’å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "There was an error gathering the chart data"
-msgstr ""
+msgstr "ãƒãƒ£ãƒ¼ãƒˆãƒ‡ãƒ¼ã‚¿ã‚’åŽé›†ã™ã‚‹é–“ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
msgid "There was an error getting the epic participants."
msgstr ""
@@ -20987,17 +22214,20 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr "ユーザーã®ã‚¢ã‚¯ãƒ†ã‚£ãƒ“ティカレンダーã®èª­ã¿è¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr "メールã®å‰Šé™¤ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "There was an error removing your custom stage, please try again"
-msgstr ""
+msgstr "ã‚ãªãŸã®ã‚«ã‚¹ã‚¿ãƒ ã‚¹ãƒ†ãƒ¼ã‚¸ã‚’削除ã™ã‚‹éš›ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
msgid "There was an error resetting group pipeline minutes."
-msgstr ""
+msgstr "グループã®ãƒ‘イプライン時間ã®ãƒªã‚»ãƒƒãƒˆä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "There was an error resetting user pipeline minutes."
-msgstr ""
+msgstr "ユーザーã®ãƒ‘イプライン時間ã®ãƒªã‚»ãƒƒãƒˆä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "There was an error saving this Geo Node."
msgstr ""
@@ -21018,7 +22248,7 @@ msgid "There was an error syncing the %{replicableType}"
msgstr ""
msgid "There was an error trying to validate your query"
-msgstr ""
+msgstr "クエリを検証ã™ã‚‹é–“ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
msgid "There was an error updating the dashboard, branch name is invalid."
msgstr ""
@@ -21039,15 +22269,18 @@ msgid "There was an error when unsubscribing from this label."
msgstr "ラベルã®è³¼èª­è§£é™¤ã™ã‚‹ã¨ãã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "There was an error while fetching value stream analytics data."
-msgstr ""
+msgstr "ãƒãƒªãƒ¥ãƒ¼ã‚¹ãƒˆãƒªãƒ¼ãƒ åˆ†æžãƒ‡ãƒ¼ã‚¿ã‚’å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "There was an error while fetching value stream analytics duration data."
-msgstr ""
+msgstr "ãƒãƒªãƒ¥ãƒ¼ã‚¹ãƒˆãƒªãƒ¼ãƒ åˆ†æžã®æœŸé–“データをå–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "There was an error while fetching value stream analytics duration median data."
-msgstr ""
+msgstr "ãƒãƒªãƒ¥ãƒ¼ã‚¹ãƒˆãƒªãƒ¼ãƒ åˆ†æžã®æœŸé–“中間データをå–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "There was an error while fetching value stream analytics recent activity data."
+msgstr "ãƒãƒªãƒ¥ãƒ¼ã‚¹ãƒˆãƒªãƒ¼ãƒ åˆ†æžã®æœ€è¿‘ã®ã‚¢ã‚¯ãƒ†ã‚£ãƒ“ティデータをå–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
+
+msgid "There was an error while fetching value stream analytics time summary data."
msgstr ""
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
@@ -21057,7 +22290,7 @@ msgid "These existing issues have a similar title. It might be better to comment
msgstr "既存ã®èª²é¡Œã«åŒæ§˜ã®ã‚¿ã‚¤ãƒˆãƒ«ãŒã‚ã‚Šã¾ã™ã€‚別ã®ä¼¼ãŸã‚ˆã†ãªèª²é¡Œã‚’作æˆã™ã‚‹ã‚ˆã‚Šã€ãã“ã«ã‚³ãƒ¡ãƒ³ãƒˆã™ã‚‹æ–¹ãŒè‰¯ã„ã§ã™ã€‚"
msgid "These variables are configured in the parent group settings, and will be active in the current project in addition to the project variables."
-msgstr ""
+msgstr "ã“れらã®å¤‰æ•°ã¯ã€è¦ªã‚°ãƒ«ãƒ¼ãƒ—設定ã§æ§‹æˆã•ã‚Œã€ãƒ—ロジェクト変数ã«åŠ ãˆã¦ç¾åœ¨ã®ãƒ—ロジェクトã§ã‚¢ã‚¯ãƒ†ã‚£ãƒ–ã«ãªã‚Šã¾ã™ã€‚"
msgid "They can be managed using the %{link}."
msgstr "%{link}を使用ã—ã¦ãれらを管ç†ã§ãã¾ã™ã€‚"
@@ -21069,7 +22302,7 @@ msgid "Third party offers"
msgstr "サードパーティã®ã‚¢ãƒ—リã®ç”³ã—出"
msgid "This %{issuableDisplayName} is locked. Only project members can comment."
-msgstr ""
+msgstr "ã“ã® %{issuableDisplayName} ã¯ãƒ­ãƒƒã‚¯ã•ã‚Œã¦ã„ã¾ã™ã€‚プロジェクトメンãƒãƒ¼ ã ã‘ãŒã‚³ãƒ¡ãƒ³ãƒˆã§ãã¾ã™ã€‚"
msgid "This %{issuable} is locked. Only <strong>project members</strong> can comment."
msgstr "ã“ã® %{issuable} ã¯ãƒ­ãƒƒã‚¯ã•ã‚Œã¦ã„ã¾ã™ã€‚<strong>プロジェクトメンãƒãƒ¼</strong> ã ã‘ãŒã‚³ãƒ¡ãƒ³ãƒˆã§ãã¾ã™ã€‚"
@@ -21099,7 +22332,7 @@ msgid "This application was created by %{link_to_owner}."
msgstr "ã“ã®ã‚¢ãƒ—リケーション㯠%{link_to_owner} ã«ã‚ˆã£ã¦ä½œæˆã•ã‚Œã¾ã—ãŸã€‚"
msgid "This application will be able to:"
-msgstr ""
+msgstr "ã“ã®ã‚¢ãƒ—リケーションã¯æ¬¡ã®ã“ã¨ãŒã§ãã¾ã™:"
msgid "This attachment has been truncated to avoid exceeding the maximum allowed attachment size of 15MB. %{written_count} of %{issues_count} issues have been included. Consider re-exporting with a narrower selection of issues."
msgstr ""
@@ -21117,7 +22350,7 @@ msgid "This chart could not be displayed"
msgstr "ã“ã®ãƒãƒ£ãƒ¼ãƒˆã¯è¡¨ç¤ºã§ãã¾ã›ã‚“"
msgid "This comment has changed since you started editing, please 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} ã®ä¸€éƒ¨ã§ã™ã€‚ã“ã®ã‚³ãƒ¡ãƒ³ãƒˆã¯ã€ãã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã®ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã§ä½œæˆã—ã¾ã™ã€‚"
@@ -21134,6 +22367,9 @@ msgstr "ã“ã®ã‚³ãƒŸãƒƒãƒˆã¯æ¤œè¨¼æ¸ˆã¿ã®ç½²åã§ã‚µã‚¤ãƒ³ã•ã‚Œã¦ã„ã¾ã™
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr "ã“ã®ã‚³ãƒŸãƒƒãƒˆã¯<strong>検証ã•ã‚Œã¦ã„ãªã„</strong> ç½²åã§ã‚µã‚¤ãƒ³ã•ã‚Œã¦ã„ã¾ã™ã€‚"
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr "ã“ã®æ—¥ä»˜ã¯æœŸæ—¥ã‚ˆã‚Šå¾Œã§ã™ã€‚ãã®ãŸã‚ã“ã®ã‚¨ãƒ”ックをロードマップã«è¡¨ç¤ºã—ã¾ã›ã‚“。"
@@ -21159,7 +22395,7 @@ msgid "This domain is not verified. You will need to verify ownership before acc
msgstr "ã“ã®ãƒ‰ãƒ¡ã‚¤ãƒ³ã¯æ¤œè¨¼ã•ã‚Œã¦ã„ã¾ã›ã‚“。ã‚ãªãŸã¯ã‚¢ã‚¯ã‚»ã‚¹ã‚’有効ã«ã™ã‚‹å‰ã«æ‰€æœ‰æ¨©ã‚’確èªã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "This endpoint has been requested too many times. Try again later."
-msgstr ""
+msgstr "ã“ã®ã‚¨ãƒ³ãƒ‰ãƒã‚¤ãƒ³ãƒˆã¯ä½•åº¦ã‚‚リクエストã•ã‚Œã¦ã„ã¾ã™ã€‚ã‚‚ã†ä¸€åº¦ã‚ã¨ã§ãŠè©¦ã—ãã ã•ã„。"
msgid "This environment has no deployments yet."
msgstr "ã“ã®ç’°å¢ƒã¯ã¾ã ãƒ‡ãƒ—ロイã—ã¦ã„ã¾ã›ã‚“。"
@@ -21173,9 +22409,12 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
-msgid "This epic does not exist or you don't have sufficient permission."
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
msgstr ""
+msgid "This epic does not exist or you don't have sufficient permission."
+msgstr "ã“ã®ã‚¨ãƒ”ックã¯å­˜åœ¨ã—ãªã„ã‹ã€ã‚ãªãŸã«å分ãªæ¨©é™ãŒã‚ã‚Šã¾ã›ã‚“。"
+
msgid "This feature requires local storage to be enabled"
msgstr ""
@@ -21195,7 +22434,7 @@ msgid "This group has been scheduled for permanent removal on %{date}"
msgstr ""
msgid "This group, including all subgroups, projects and git repositories, will only be reachable from the specified IP address range. Multiple addresses are supported with comma delimiters.<br>Example: <code>192.168.0.0/24,192.168.1.0/24</code>. %{read_more_link}."
-msgstr ""
+msgstr "ã™ã¹ã¦ã®ã‚µãƒ–グループã€ãƒ—ロジェクトã€gitリãƒã‚¸ãƒˆãƒªã‚’å«ã‚€ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã¯ã€æŒ‡å®šã•ã‚ŒãŸIPアドレス範囲ã‹ã‚‰ã®ã¿åˆ°é”ã§ãã¾ã™ã€‚コンマã§åŒºåˆ‡ã‚‹ã“ã¨ã§è¤‡æ•°ã®ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’指定ã§ãã¾ã™ã€‚<br>例: <code>192.168.0.0/24,192.168.1.0/24</code> %{read_more_link}。"
msgid "This group, its subgroups and projects has been scheduled for removal on %{date}."
msgstr ""
@@ -21204,10 +22443,10 @@ msgid "This group, its subgroups and projects will be removed on %{date} since i
msgstr ""
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 ""
+msgstr "ã“ã‚Œã¯ã€ä»¥å‰ã«å‰Šé™¤ã•ã‚ŒãŸãƒ¦ãƒ¼ã‚¶ãƒ¼ã«ã‚ˆã£ã¦ä½œæˆã•ã‚ŒãŸã™ã¹ã¦ã®å•é¡Œã‚’ä¿æŒã™ã‚‹ãŸã‚ã«ä½œæˆã•ã‚ŒãŸã€ã€Œã‚´ãƒ¼ã‚¹ãƒˆãƒ¦ãƒ¼ã‚¶ãƒ¼ã€ã§ã™ã€‚ã“ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯å‰Šé™¤ã§ãã¾ã›ã‚“。"
msgid "This is a Work in Progress"
-msgstr ""
+msgstr "ã“ã‚Œã¯ä½œæ¥­ä¸­(WIP) ã§ã™ã€‚"
msgid "This is a confidential issue."
msgstr "ã“ã‚Œã¯éžå…¬é–‹ã®èª²é¡Œã§ã™ã€‚"
@@ -21216,10 +22455,7 @@ msgid "This is a delayed job to run in %{remainingTime}"
msgstr "ã“れ㯠%{remainingTime} ã«å®Ÿè¡Œã•ã‚Œã‚‹é…延ジョブã§ã™"
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
-msgstr ""
-
-msgid "This is a primary node"
-msgstr ""
+msgstr "ã“ã‚Œã¯ã‚ãªãŸã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã«ãƒ­ã‚°ã‚¤ãƒ³ã—ãŸãƒ‡ãƒã‚¤ã‚¹ã®ä¸€è¦§ã§ã™ã€‚覚ãˆã®ãªã„セッションã¯å‰Šé™¤ã—ã¦ãã ã•ã„。"
msgid "This is a security log of important events involving your account."
msgstr "ã“ã‚Œã¯ã‚ãªãŸã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã«é–¢ã‚ã‚‹é‡è¦ãªã‚¤ãƒ™ãƒ³ãƒˆã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ãƒ­ã‚°ã§ã™ã€‚"
@@ -21231,7 +22467,7 @@ msgid "This is the highest peak of users on your installation since the license
msgstr ""
msgid "This is the maximum number of users that have existed at the same time since the license started. This is the minimum number of seats you will need to buy when you renew your license."
-msgstr ""
+msgstr "ã“ã‚Œã¯ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ãŒé–‹å§‹ã•ã‚Œã¦ã‹ã‚‰åŒæ™‚ã«å­˜åœ¨ã—ãŸãƒ¦ãƒ¼ã‚¶ãƒ¼ã®æœ€å¤§æ•°ã§ã™ã€‚ã“ã‚Œã¯ã€æ¬¡å›žãƒ©ã‚¤ã‚»ãƒ³ã‚¹æ›´æ–°æ™‚ã«è³¼å…¥ã™ã‚‹å¿…è¦ãŒã‚る最å°ã®ã‚·ãƒ¼ãƒˆæ•°ã§ã™ã€‚"
msgid "This is the number of currently active users on your installation, and this is the minimum number you need to purchase when you renew your license."
msgstr ""
@@ -21240,13 +22476,13 @@ msgid "This is your current session"
msgstr "ã“ã‚Œã¯ã‚ãªãŸã®ç¾åœ¨ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã§ã™"
msgid "This issue is %{confidentialLinkStart}confidential%{linkEnd} and %{lockedLinkStart}locked%{linkEnd}."
-msgstr ""
+msgstr "ã“ã®èª²é¡Œã¯ %{confidentialLinkStart} 機密 %{linkEnd} ã§ã‚り〠%{lockedLinkStart}ロック%{linkEnd}ã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "This issue is confidential"
msgstr "ã“ã®èª²é¡Œã¯éžå…¬é–‹è¨­å®šã§ã™"
msgid "This issue is currently blocked by the following issues: %{issues}."
-msgstr ""
+msgstr "ã“ã®èª²é¡Œã¯ç¾åœ¨ã€æ¬¡ã®èª²é¡Œã«ã‚ˆã£ã¦ãƒ–ロックã•ã‚Œã¦ã„ã¾ã™ã€‚: %{issues}"
msgid "This issue is in a child epic of the filtered epic"
msgstr ""
@@ -21255,7 +22491,7 @@ msgid "This issue is locked."
msgstr "ã“ã®èª²é¡Œã¯ãƒ­ãƒƒã‚¯ã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "This job depends on other jobs with expired/erased artifacts: %{invalid_dependencies}"
-msgstr ""
+msgstr "ã“ã®ã‚¸ãƒ§ãƒ–ã¯ã€æœŸé™åˆ‡ã‚Œ/消去済ã¿ã®ã‚¢ãƒ¼ãƒ†ã‚£ãƒ•ã‚¡ã‚¯ãƒˆã‚’æŒã¤ä»–ã®ã‚¸ãƒ§ãƒ–ã«ä¾å­˜ã—ã¦ã„ã¾ã™ï¼š%{invalid_dependencies}"
msgid "This job depends on upstream jobs that need to succeed in order for this job to be triggered"
msgstr "ã“ã®ã‚¸ãƒ§ãƒ–ã¯ã€å‰å·¥ç¨‹ã®ã‚¸ãƒ§ãƒ–ãŒæ­£å¸¸çµ‚了ã™ã‚‹ã“ã¨ã§å®Ÿè¡Œã•ã‚Œã¾ã™"
@@ -21282,19 +22518,19 @@ 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} using cluster %{clusterNameOrLink}."
-msgstr ""
+msgstr "ã“ã®ã‚¸ãƒ§ãƒ–ã¯ã€ %{environmentLink} ã¸ã®ãƒ‡ãƒ—ロイã§ã™ãŒæœ€æ–°ã§ã¯ã‚ã‚Šã¾ã›ã‚“。ãã®éš›ã¯ %{clusterNameOrLink} クラスタを使用ã—ã¦ã¾ã™ã€‚"
msgid "This job is an out-of-date deployment to %{environmentLink} using cluster %{clusterNameOrLink}. View the %{deploymentLink}."
msgstr ""
msgid "This job is an out-of-date deployment to %{environmentLink}."
-msgstr ""
+msgstr "ã“ã®ã‚¸ãƒ§ãƒ–ã¯ã€ %{environmentLink} ã¸ã®ãƒ‡ãƒ—ロイã§ã™ãŒã€æœ€æ–°ã§ã¯ã‚ã‚Šã¾ã›ã‚“。"
msgid "This job is an out-of-date deployment to %{environmentLink}. View the %{deploymentLink}."
-msgstr ""
+msgstr "ã“ã®ã‚¸ãƒ§ãƒ–ã¯ã€ %{environmentLink} ã¸ã®ãƒ‡ãƒ—ロイã§ã™ãŒæœ€æ–°ã§ã¯ã‚ã‚Šã¾ã›ã‚“。%{deploymentLink} ã‚’å‚ç…§ã—ã¦ãã ã•ã„。"
msgid "This job is archived. Only the complete pipeline can be retried."
-msgstr ""
+msgstr "ã“ã®ã‚¸ãƒ§ãƒ–ã¯ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–ã•ã‚Œã¾ã—ãŸã€‚完了ã—ãŸãƒ‘イプラインã®ã¿å†è©¦è¡Œã§ãã¾ã™ã€‚"
msgid "This job is creating a deployment to %{environmentLink} using cluster %{clusterNameOrLink} and namespace %{kubernetesNamespace}."
msgstr ""
@@ -21306,22 +22542,22 @@ msgid "This job is creating a deployment to %{environmentLink} using cluster %{c
msgstr ""
msgid "This job is creating a deployment to %{environmentLink} using cluster %{clusterNameOrLink}. This will overwrite the %{deploymentLink}."
-msgstr ""
+msgstr "ã“ã®ã‚¸ãƒ§ãƒ–㯠%{environmentLink} ã¸ã®ãƒ‡ãƒ—ロイを作æˆã—ã¾ã™ãŒã€%{clusterNameOrLink} クラスタを使用ã—ã¾ã™ã€‚ã¾ãŸã€ã“れ㯠%{deploymentLink} を上書ãã—ã¾ã™ã€‚"
msgid "This job is creating a deployment to %{environmentLink}."
-msgstr ""
+msgstr "ã“ã®ã‚¸ãƒ§ãƒ–ã¯ã€ %{environmentLink} ã¸ã®ãƒ‡ãƒ—ロイを作æˆã—ã¾ã™ã€‚"
msgid "This job is creating a deployment to %{environmentLink}. This will overwrite the %{deploymentLink}."
-msgstr ""
+msgstr "ã“ã®ã‚¸ãƒ§ãƒ–㯠%{environmentLink} ã¸ã®ãƒ‡ãƒ—ロイを作æˆã—ã¾ã™ã€‚ã¾ãŸã€ã“れ㯠%{deploymentLink} を上書ãã—ã¾ã™ã€‚"
msgid "This job is deployed to %{environmentLink} using cluster %{clusterNameOrLink} and namespace %{kubernetesNamespace}."
msgstr ""
msgid "This job is deployed to %{environmentLink} using cluster %{clusterNameOrLink}."
-msgstr ""
+msgstr "ã“ã®ã‚¸ãƒ§ãƒ–ã¯ã€ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼%{clusterNameOrLink} を使用ã—ã¦%{environmentLink} ã«ãƒ‡ãƒ—ロイã•ã‚Œã¾ã™ã€‚"
msgid "This job is deployed to %{environmentLink}."
-msgstr ""
+msgstr "ã“ã®ã‚¸ãƒ§ãƒ–ã¯ã€ %{environmentLink} ã¸ã®ãƒ‡ãƒ—ロイã—ã¾ã™ã€‚"
msgid "This job is in pending state and is waiting to be picked by a runner"
msgstr "ã“ã®ã‚¸ãƒ§ãƒ–ã¯ä¿ç•™ä¸­ã§ Runner ãŒå‹•ä½œã™ã‚‹ã®ã‚’å¾…ã£ã¦ã„ã¾ã™ã€‚"
@@ -21332,14 +22568,14 @@ msgstr "ã“ã®ã‚¸ãƒ§ãƒ–ã¯ã€é–‹å§‹ã™ã‚‹å‰ã«å®Œäº†ã—ãªã‘ã‚Œã°ãªã‚‰ãªã„
msgid "This job is preparing to start"
msgstr "ã“ã®ã‚¸ãƒ§ãƒ–ã¯å§‹ã‚る準備をã—ã¦ã„ã¾ã™"
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
-msgstr "ã“れらã®ã‚¿ã‚°ãŒå‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„るアクティブ㪠Runner ãŒã‚ªãƒ³ãƒ©ã‚¤ãƒ³ã«ãªã£ã¦ã„ãªã„ãŸã‚ã€ã“ã®ã‚¸ãƒ§ãƒ–ã¯åœæ­¢ã—ã¦ã„ã¾ã™ã€‚"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
+msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
msgstr "ã“ã®ã‚¸ãƒ§ãƒ–を実行ã§ãるアクティブ㪠Runner ãŒãªã„ãŸã‚ã€ã“ã®ã‚¸ãƒ§ãƒ–ã¯åœæ­¢ã—ã¦ã„ã¾ã™ã€‚"
msgid "This job is waiting for resource: "
-msgstr ""
+msgstr "ã“ã®ã‚¸ãƒ§ãƒ–ã¯æ¬¡ã®ãƒªã‚½ãƒ¼ã‚¹ã‚’å¾…ã£ã¦ã„ã¾ã™: "
msgid "This job requires a manual action"
msgstr "ã“ã®ã‚¸ãƒ§ãƒ–ã¯æ‰‹å‹•ã«ã‚ˆã‚‹å®Ÿè¡Œã‚’求ã‚ã¦ã„ã¾ã™"
@@ -21354,11 +22590,14 @@ msgid "This license has already expired."
msgstr ""
msgid "This may expose confidential information as the selected fork is in another namespace that can have other members."
-msgstr ""
+msgstr "é¸æŠžã—ãŸãƒ•ã‚©ãƒ¼ã‚¯ã¯ä»–ã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’æŒã¤ã“ã¨ãŒã§ãる別ã®åå‰ç©ºé–“ã«ã‚ã‚‹ãŸã‚ã€ã“ã‚Œã«ã‚ˆã‚Šæ©Ÿå¯†æƒ…å ±ãŒå…¬é–‹ã•ã‚Œã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr "空リãƒã‚¸ãƒˆãƒªã‚’作æˆã¾ãŸã¯æ—¢å­˜ãƒªãƒã‚¸ãƒˆãƒªã‚’インãƒãƒ¼ãƒˆã‚’ã—ãªã‘ã‚Œã°ã€ã‚³ãƒ¼ãƒ‰ã®ãƒ—ッシュã¯ã§ãã¾ã›ã‚“。"
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr "ã“ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã¯ãƒ­ãƒƒã‚¯ã•ã‚Œã¦ã„ã¾ã™ã€‚"
@@ -21369,7 +22608,7 @@ msgid "This only applies to repository indexing operations."
msgstr ""
msgid "This option is only available on GitLab.com"
-msgstr ""
+msgstr "ã“ã®ã‚ªãƒ—ション㯠GitLab.com ã§ã®ã¿åˆ©ç”¨å¯èƒ½ã§ã™"
msgid "This page is unavailable because you are not allowed to read information across multiple projects."
msgstr "複数ã®ãƒ—ロジェクト間ã§èª­ã¿è¾¼ã¿ãŒè¨±å¯ã•ã‚Œã¦ã„ãªã„ãŸã‚ã€ã“ã®ãƒšãƒ¼ã‚¸ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“。"
@@ -21384,10 +22623,10 @@ msgid "This pipeline makes use of a predefined CI/CD configuration enabled by <b
msgstr "ã“ã®ãƒ‘イプラインã¯ã€<b>Auto DevOps</b>ã«ã‚ˆã£ã¦æœ‰åŠ¹åŒ–ã•ã‚ŒãŸå®šç¾©æ¸ˆã¿ã®CI/CD構æˆã‚’利用ã—ã¾ã™ã€‚"
msgid "This pipeline triggered a child pipeline"
-msgstr ""
+msgstr "å­ãƒ‘イプラインãŒãƒˆãƒªã‚¬ãƒ¼ã—ãŸãƒ‘イプライン"
msgid "This pipeline was triggered by a parent pipeline"
-msgstr ""
+msgstr "ã“ã®ãƒ‘イプラインã¯è¦ªãƒ‘イプラインãŒãƒˆãƒªã‚¬ãƒ¼ã—ã¾ã—ãŸ"
msgid "This project"
msgstr "プロジェクト"
@@ -21395,12 +22634,18 @@ msgstr "プロジェクト"
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr "ã“ã®ãƒ—ロジェクトã¯ã‚°ãƒ«ãƒ¼ãƒ—ã«æ‰€å±žã—ã¦ã„ãªã„ãŸã‚ã€ã‚°ãƒ«ãƒ¼ãƒ— Runner を利用ã§ãã¾ã›ã‚“。"
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr "ã“ã®ãƒ—ロジェクトã¯ã¾ã Wikiã®ãƒ›ãƒ¼ãƒ ãƒšãƒ¼ã‚¸ãŒã‚ã‚Šã¾ã›ã‚“。"
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr "ã“ã®ãƒ—ロジェクトã§ã¯èª²é‡‘ãŒæœ‰åŠ¹ã«ãªã£ã¦ã„ã¾ã›ã‚“。クラスターを作æˆã™ã‚‹ã«ã¯ã€<a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\"> 課金を有効<i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> ã«ã—ã¦å†åº¦ãŠè©¦ã—ãã ã•ã„。"
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr "ã“ã®ãƒ—ロジェクトã¯ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–ã•ã‚Œã¦ãŠã‚Šã€ã‚³ãƒ¡ãƒ³ãƒˆã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。"
@@ -21413,10 +22658,22 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr "リãƒã‚¸ãƒˆãƒª"
+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 "ã“ã®ãƒªãƒã‚¸ãƒˆãƒªã¯ç¾åœ¨ç©ºã§ã™ã€‚ æ–°ã—ã„ファイルãŒãƒ–ランãƒã«ãƒ—ッシュã•ã‚ŒãŸå¾Œã€æ–°ã—ã„Auto DevOpsパイプラインãŒä½œæˆã•ã‚Œã¾ã™ã€‚"
+
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
msgstr ""
msgid "This runner will only run on pipelines triggered on protected branches"
@@ -21437,7 +22694,7 @@ msgstr "ã“ã®ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã¯ã€ãƒ—ロジェクトã§å®šç¾©ã•ã‚ŒãŸã‚¿ã‚¤
msgid "This user cannot be unlocked manually from GitLab"
msgstr "ã“ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ GitLab ã‹ã‚‰ãƒžãƒ‹ãƒ¥ã‚¢ãƒ«æ“作ã§ãƒ­ãƒƒã‚¯ã‚’解除ã§ãã¾ã›ã‚“"
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21446,9 +22703,6 @@ msgstr "ã“ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã«ã¯ ID ãŒã‚ã‚Šã¾ã›ã‚“"
msgid "This 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 "ã“ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ã€æ–°ã—ã作æˆã•ã‚ŒãŸãƒ–ランãƒã‚„既存ã®ãƒ–ランãƒã¸ã®æ–°è¦ã‚³ãƒŸãƒƒãƒˆãªã©ã®ã‚ˆã†ã«ã€æ›´æ–°ã®çµæžœã§ã‚るアクティビティーフィード内ã®ã™ã¹ã¦ã®ã‚¤ãƒ™ãƒ³ãƒˆã®ä½œæˆè€…ã«ãªã‚Šã¾ã™ã€‚"
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr "ã“ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ã€æ–°ã—ã作æˆã•ã‚ŒãŸãƒ–ランãƒã‚„既存ã®ãƒ–ランãƒã¸ã®æ–°è¦ã‚³ãƒŸãƒƒãƒˆãªã©ã®ã‚ˆã†ã«ã€æ›´æ–°ã®çµæžœã§ã‚るアクティビティーフィード内ã®ã™ã¹ã¦ã®ã‚¤ãƒ™ãƒ³ãƒˆã®ä½œæˆè€…ã«ãªã‚Šã¾ã™ã€‚作æˆæ™‚ã¾ãŸã¯å†ã³æ‹…当を割り当ã¦ãŸéš›ã«ã€ãã®ãƒŸãƒ©ãƒ¼ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’ã‚ãªãŸã«å‰²ã‚Šå½“ã¦ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
-
msgid "This variable can not be masked."
msgstr ""
@@ -21462,10 +22716,10 @@ msgid "This will redirect you to an external sign in page."
msgstr "外部ã®ã‚µã‚¤ãƒ³ã‚¤ãƒ³ãƒšãƒ¼ã‚¸ã«ãƒªãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆã—ã¾ã™ã€‚"
msgid "This will remove the fork relationship between this project and %{fork_source}."
-msgstr ""
+msgstr "ã“ã®æ“作ã¯ã€ã“ã®ãƒ—ロジェクト㨠%{fork_source} é–“ã®ãƒ•ã‚©ãƒ¼ã‚¯é–¢ä¿‚を削除ã—ã¾ã™ã€‚"
msgid "This will remove the fork relationship between this project and other projects in the fork network."
-msgstr ""
+msgstr "ã“ã®æ“作ã¯ã€ã“ã®ãƒ—ロジェクトã¨ãƒ•ã‚©ãƒ¼ã‚¯ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯å†…ã®ä»–ã®ãƒ—ロジェクトã®é–“ã®ãƒ•ã‚©ãƒ¼ã‚¯é–¢ä¿‚を削除ã—ã¾ã™ã€‚"
msgid "Those emails automatically become issues (with the comments becoming the email conversation) listed here."
msgstr "ã“ã“ã«ãƒªã‚¹ãƒˆã‚¢ãƒƒãƒ—ã•ã‚Œã¦ã„ã‚‹ã“れらã®ãƒ¡ãƒ¼ãƒ«ã¯è‡ªå‹•çš„ã«èª²é¡Œã«ãªã‚Šã¾ã™ã€‚(メールã®ã‚„ã‚Šå–ã‚Šã¯èª²é¡Œã®ã‚³ãƒ¡ãƒ³ãƒˆã«ãªã‚Šã¾ã™ï¼‰"
@@ -21474,7 +22728,7 @@ msgid "Thread to reply to cannot be found"
msgstr ""
msgid "Threat Monitoring"
-msgstr ""
+msgstr "è„…å¨ç›£è¦–"
msgid "ThreatMonitoring|Anomalous Requests"
msgstr ""
@@ -21495,7 +22749,7 @@ msgid "ThreatMonitoring|Dropped Packets"
msgstr ""
msgid "ThreatMonitoring|Environment"
-msgstr ""
+msgstr "環境"
msgid "ThreatMonitoring|No environments detected"
msgstr ""
@@ -21503,9 +22757,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21513,7 +22773,7 @@ msgid "ThreatMonitoring|Show last"
msgstr ""
msgid "ThreatMonitoring|Something went wrong, unable to fetch environments"
-msgstr ""
+msgstr "å•é¡ŒãŒç™ºç”Ÿã—ãŸãŸã‚ã€ç’°å¢ƒã‚’å–å¾—ã§ãã¾ã›ã‚“"
msgid "ThreatMonitoring|Something went wrong, unable to fetch statistics"
msgstr ""
@@ -21528,7 +22788,7 @@ msgid "ThreatMonitoring|Threat Monitoring"
msgstr "è„…å¨ç›£è¦–"
msgid "ThreatMonitoring|Threat Monitoring help page link"
-msgstr ""
+msgstr "è„…å¨ç›£è¦–ã®ãƒ˜ãƒ«ãƒ—ページリンク"
msgid "ThreatMonitoring|Time"
msgstr ""
@@ -21555,10 +22815,10 @@ msgid "Thursday"
msgstr "木曜日"
msgid "Time"
-msgstr ""
+msgstr "時間"
msgid "Time based: Yes"
-msgstr ""
+msgstr "時間ベース: ã‚ã‚Š"
msgid "Time before an issue gets scheduled"
msgstr "課題ãŒè¨ˆç”»ã•ã‚Œã‚‹ã¾ã§ã®æ™‚é–“"
@@ -21567,7 +22827,7 @@ msgid "Time before an issue starts implementation"
msgstr "課題ã®å®Ÿè£…ãŒé–‹å§‹ã•ã‚Œã‚‹ã¾ã§ã®æ™‚é–“"
msgid "Time before enforced"
-msgstr ""
+msgstr "実施å‰ã®æ™‚é–“"
msgid "Time between merge request creation and merge/close"
msgstr "マージリクエストãŒä½œæˆã•ã‚Œã¦ã‹ã‚‰ãƒžãƒ¼ã‚¸ã¾ãŸã¯ã‚¯ãƒ­ãƒ¼ã‚ºã•ã‚Œã‚‹ã¾ã§ã®æ™‚é–“"
@@ -21576,13 +22836,13 @@ msgid "Time estimate"
msgstr "見ç©æ™‚é–“"
msgid "Time from first comment to last commit"
-msgstr ""
+msgstr "最åˆã®ã‚³ãƒ¡ãƒ³ãƒˆã‹ã‚‰ç›´å‰ã®ã‚³ãƒŸãƒƒãƒˆã¾ã§ã®æ™‚é–“"
msgid "Time from first commit until first comment"
-msgstr ""
+msgstr "最åˆã®ã‚³ãƒŸãƒƒãƒˆã‹ã‚‰æœ€åˆã®ã‚³ãƒ¡ãƒ³ãƒˆã¾ã§ã®æ™‚é–“"
msgid "Time from last commit to merge"
-msgstr ""
+msgstr "ç›´å‰ã®ã‚³ãƒŸãƒƒãƒˆã‹ã‚‰ãƒžãƒ¼ã‚¸ã¾ã§ã®æ™‚é–“"
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 "外部サービスã‹ã‚‰ã®å¿œç­”時間(秒å˜ä½ï¼‰ã‚’設定ã—ã¾ã™ã€‚設定時間内ã«å¿œç­”ãŒç„¡ã„å ´åˆã€ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•ã‚Œã¾ã™ã€‚"
@@ -21612,7 +22872,7 @@ msgid "TimeTrackingEstimated|Est"
msgstr "Est"
msgid "TimeTracking|%{startTag}Spent: %{endTag}%{timeSpentHumanReadable}"
-msgstr ""
+msgstr "%{startTag}経éŽæ™‚é–“:%{endTag}%{timeSpentHumanReadable}"
msgid "TimeTracking|Estimated:"
msgstr "見ç©ã‚‚り時間:"
@@ -21624,7 +22884,7 @@ msgid "TimeTracking|Spent"
msgstr "経éŽæ™‚é–“"
msgid "TimeTracking|Time remaining: %{timeRemainingHumanReadable}"
-msgstr ""
+msgstr "残り時間: %{timeRemainingHumanReadable}"
msgid "Timeago|%s days ago"
msgstr "%sæ—¥å‰"
@@ -21752,6 +23012,9 @@ msgstr "今"
msgid "Timeout"
msgstr "タイムアウト"
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] "時間"
@@ -21779,28 +23042,28 @@ msgid "To"
msgstr ""
msgid "To %{link_to_help} of your domain, add the above key to a TXT record within to your DNS configuration."
-msgstr ""
+msgstr "ドメイン㮠%{link_to_help} ã«ã€DNSã®TXTレコードã«ä¸Šè¨˜ã®ã‚­ãƒ¼ã‚’追加ã—ã¦ãã ã•ã„。"
msgid "To Do"
-msgstr ""
+msgstr "To Do"
msgid "To GitLab"
msgstr "GitLab ã¸"
msgid "To access this domain create a new DNS record"
-msgstr ""
+msgstr "ã“ã®ãƒ‰ãƒ¡ã‚¤ãƒ³ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã«ã¯ã€æ–°ã—ã„DNSレコードを作æˆã—ã¦ãã ã•ã„"
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 "SSH キーを追加ã™ã‚‹ã«ã¯ã€%{generate_link_start}キーを生æˆã™ã‚‹%{link_end} ã¾ãŸã¯%{existing_link_start}既存ã®ã‚­ãƒ¼ã‚’使用ã™ã‚‹%{link_end}ã®ã©ã¡ã‚‰ã‹ãŒå¿…è¦ã§ã™ã€‚"
msgid "To add the entry manually, provide the following details to the application on your phone."
-msgstr ""
+msgstr "エントリーを手動ã§è¿½åŠ ã™ã‚‹ã«ã¯ã€ã‚¹ãƒžãƒ¼ãƒˆãƒ•ã‚©ãƒ³ã®ã‚¢ãƒ—リケーションã«æ¬¡ã®è©³ç´°ã‚’入力ã—ã¦ãã ã•ã„"
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>repo</code> scope, so we can display a list of your public and private repositories which are available to connect."
msgstr "GitHub リãƒã‚¸ãƒˆãƒªã«æŽ¥ç¶šã™ã‚‹ãŸã‚ã« %{personal_access_token_link} を使用ã§ãã¾ã™ã€‚個人用アクセストークンを作æˆã™ã‚‹ã«ã¯<code>リãƒã‚¸ãƒˆãƒª</code> スコープをé¸æŠžã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚ã“ã‚Œã«ã‚ˆã‚ŠæŽ¥ç¶šã§ãる公開・éžå…¬é–‹ãƒªãƒã‚¸ãƒˆãƒªã®ä¸€è¦§ã‚’表示ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
msgid "To connect GitHub repositories, you first need to authorize GitLab to access the list of your GitHub repositories."
-msgstr ""
+msgstr "GitHubリãƒã‚¸ãƒˆãƒªã«æŽ¥ç¶šã™ã‚‹ã«ã¯ã€æ¬¡ã®GitHubã®ãƒªã‚¹ãƒˆã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ãŸã‚ã®GitLabã®èªè¨¼ãŒå¿…è¦ã§ã™."
msgid "To connect GitHub repositories, you first need to authorize GitLab to access the list of your GitHub repositories:"
msgstr "GitHub リãƒã‚¸ãƒˆãƒªã«æŽ¥ç¶šã™ã‚‹ã«ã¯ã€GitLab ãŒã‚ãªãŸã® GitHub リãƒã‚¸ãƒˆãƒªä¸€è¦§ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã“ã¨ã‚’許å¯ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™:"
@@ -21812,22 +23075,28 @@ msgid "To define internal users, first enable new users set to external"
msgstr "内部ユーザーを定義ã™ã‚‹ãŸã‚ã«ã¯ã€å…ˆã«æ–°è¦ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’外部ユーザーã«è¨­å®šã§ãるよã†ã«ã—ã¾ã™ã€‚"
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
+msgstr "ユーザー世代を有効化ã—ã¦è¡¨ç¤ºã™ã‚‹ã«ã¯ã€ %{application_settings_link_start}アプリケーション設定%{application_settings_link_end} ã«ã‚¢ã‚¯ã‚»ã‚¹ã—ã¦ãã ã•ã„"
+
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
msgstr ""
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 "ã¯ã˜ã‚ã« FogBugz ã® URL ã¨ãƒ­ã‚°ã‚¤ãƒ³æƒ…報を入力ã—ã¦ãã ã•ã„。次ã®ã‚¹ãƒ†ãƒƒãƒ—ã§ã¯ã€ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’マップã—ã¦ã€ã‚¤ãƒ³ãƒãƒ¼ãƒˆã™ã‚‹ãƒ—ロジェクトをé¸æŠžã—ã¾ã™ã€‚"
msgid "To get started, link this page to your Jaeger server, or find out how to %{link_start_tag}install Jaeger%{link_end_tag}"
-msgstr ""
+msgstr "ã¯ã˜ã‚ã«ã€Jaeger サーãƒãƒ¼ã«ã“ã®ãƒšãƒ¼ã‚¸ã‚’リンクã™ã‚‹ã‹ã€%{link_start_tag}Jaeger ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«%{link_end_tag}方法を確èªã—ã¾ã™"
msgid "To get started, please enter your Gitea Host URL and a %{link_to_personal_token}."
msgstr "開始ã™ã‚‹ã«ã¯ã€Gitea Host ã® URL 㨠%{link_to_personal_token} を入力ã—ã¦ãã ã•ã„。"
msgid "To help improve GitLab and its user experience, GitLab will periodically collect usage information."
-msgstr ""
+msgstr "GitLab ã®æ”¹å–„㨠GitLab ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚¨ã‚¯ã‚¹ãƒšãƒªã‚¨ãƒ³ã‚¹ã‚’å‘上ã•ã›ã‚‹ãŸã‚ã€GitLab ã¯å®šæœŸçš„ã«ä½¿ç”¨çŠ¶æ³æƒ…報をåŽé›†ã—ã¾ã™ã€‚"
msgid "To help improve GitLab, we would like to periodically collect usage information. This can be changed at any time in %{settings_link_start}Settings%{link_end}. %{info_link_start}More Information%{link_end}"
-msgstr ""
+msgstr "GitLab を改善ã™ã‚‹ãŸã‚ã«ã€å®šæœŸçš„ã«ä½¿ç”¨æƒ…報をåŽé›†ã—ãŸã„ã¨è€ƒãˆã¦ã„ã¾ã™ã€‚ã“れ㯠%{settings_link_start}設定%{link_end}ã§ã„ã¤ã§ã‚‚変更ã§ãã¾ã™ã€‚ %{info_link_start}詳細ã¯ã“ã¡ã‚‰ã§ã™ã€‚%{link_end}"
msgid "To import an SVN repository, check out %{svn_link}."
msgstr "SVN リãƒã‚¸ãƒˆãƒªã‚’インãƒãƒ¼ãƒˆã™ã‚‹ã«ã¯ã€%{svn_link} ã‚’ã”確èªãã ã•ã„。"
@@ -21848,40 +23117,40 @@ msgid "To only use CI/CD features for an external repository, choose <strong>CI/
msgstr "外部リãƒã‚¸ãƒˆãƒªã«ã®ã¿ CI/CD ã®æ©Ÿèƒ½ã‚’使用ã™ã‚‹ã«ã¯ã€<strong>外部リãƒã‚¸ãƒˆãƒªç”¨ CI/CD</strong>ã‚’é¸æŠžã—ã¦ãã ã•ã„。"
msgid "To open Jaeger and easily view tracing from GitLab, link the %{link} page to your server"
-msgstr ""
+msgstr "Jaeger ã‚’é–‹ãã€GitLab ã‹ã‚‰ç°¡å˜ã«ãƒˆãƒ¬ãƒ¼ã‚·ãƒ³ã‚°ã‚’表示ã™ã‚‹ã«ã¯ã€ %{link} ページをサーãƒãƒ¼ã«ãƒªãƒ³ã‚¯ã—ã¾ã™"
msgid "To preserve performance only <strong>%{display_size} of %{real_size}</strong> files are displayed."
-msgstr ""
+msgstr "パフォーマンス維æŒã®ãŸã‚〠<strong>%{real_size} 個中 %{display_size} 個</strong> ã®ãƒ•ã‚¡ã‚¤ãƒ«ã®ã¿ãŒè¡¨ç¤ºã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "To protect this issue's confidentiality, %{forkLink} and set the fork's visibility to private."
-msgstr ""
+msgstr "ã“ã®èª²é¡Œã®æ©Ÿå¯†æ€§ã‚’ä¿è­·ã™ã‚‹ãŸã‚ã«ã€%{forkLink} ã¨ãƒ•ã‚©ãƒ¼ã‚¯ã®å¯è¦–性をプライベートã«è¨­å®šã—ã¾ã™ã€‚"
msgid "To protect this issue's confidentiality, a private fork of this project was selected."
-msgstr ""
+msgstr "ã“ã®èª²é¡Œã®æ©Ÿå¯†æ€§ã‚’ä¿è­·ã™ã‚‹ãŸã‚ã«ã€ã“ã®ãƒ—ロジェクトã®ãƒ—ライベートフォークãŒé¸æŠžã•ã‚Œã¾ã—ãŸã€‚"
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 ""
+msgstr "手動ã§è¨­å®šã•ã‚ŒãŸPrometheus サービスã‹ã‚‰ã‚¢ãƒ©ãƒ¼ãƒˆã‚’å—ä¿¡ã™ã‚‹ã«ã¯ã€æ¬¡ã®URLã¨èªè¨¼ã‚­ãƒ¼ã‚’ Prometheus webhook ã®è¨­å®šãƒ•ã‚¡ã‚¤ãƒ«ã«è¿½åŠ ã—ã¦ãã ã•ã„。GitLab ã«ã‚¢ãƒ©ãƒ¼ãƒˆã‚’é€ä¿¡ã™ã‚‹ãŸã‚ã® %{linkEnd} Prometheusã®è¨­å®š %{linkStart} ã®è©³ç´°ã‚’ã”覧ãã ã•ã„。"
msgid "To see all the user's personal access tokens you must impersonate them first."
-msgstr ""
+msgstr "ユーザーã®å€‹äººã‚¢ã‚¯ã‚»ã‚¹ãƒˆãƒ¼ã‚¯ãƒ³ã‚’見るã«ã¯ã€å¿…ãšä»£ç”¨æ©Ÿèƒ½ã‚’使ã†å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "To see this project's operational details, %{linkStart}upgrade its group plan to Silver%{linkEnd}. You can also remove the project from the dashboard."
-msgstr ""
+msgstr "ã“ã®ãƒ—ロジェクトã®é‹ç”¨ä¸Šã®è©³ç´°ã‚’確èªã™ã‚‹ã«ã¯ã€ %{linkStart}グループプランをSilverã¸ã‚¢ãƒƒãƒ—グレード%{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 ""
+msgstr "ã“ã®ãƒ—ロジェクトã®é‹ç”¨ä¸Šã®è©³ç´°ã‚’確èªã™ã‚‹ã«ã¯ã€ %{groupName} グループã®ã‚ªãƒ¼ãƒŠãƒ¼ã«é€£çµ¡ã‚’ã¨ã£ã¦ãƒ—ランをアップグレードã—ã¦ãã ã•ã„。ダッシュボードã‹ã‚‰ãƒ—ロジェクトを削除ã§ãã¾ã™ã€‚"
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 "Azureã€Oktaã€Oneloginã€Ping Identyã€ã¾ãŸã¯ã‚«ã‚¹ã‚¿ãƒ  SAML 2.0 プロãƒã‚¤ãƒ€ãƒ¼ãªã©ã® ID プロãƒã‚¤ãƒ€ãƒ¼ã‚’利用ã—ã¦ã€ã‚ãªãŸã®ã‚°ãƒ«ãƒ¼ãƒ—ã® SAML èªè¨¼ã‚’設定ã™ã‚‹ã«ã¯:"
msgid "To set up this service:"
-msgstr ""
+msgstr "ã“ã®ã‚µãƒ¼ãƒ“スをセットアップã™ã‚‹ãŸã‚:"
msgid "To simplify the billing process, GitLab will collect user counts in order to prorate charges for user growth throughout the year using a quarterly reconciliation process."
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."
-msgstr ""
+msgstr "所属ã™ã‚‹ã‚°ãƒ«ãƒ¼ãƒ—ã®ãƒ—ロジェクトã”ã¨ã®é€šçŸ¥ãƒ¬ãƒ™ãƒ«ã‚’指定ã™ã‚‹ã«ã¯ã€ãƒ—ロジェクトページã«ã‚¢ã‚¯ã‚»ã‚¹ã—ã€ãã“ã§é€šçŸ¥ãƒ¬ãƒ™ãƒ«ã‚’変更ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "To start serving your jobs you can add Runners to your group"
msgstr "ジョブを開始ã™ã‚‹ãŸã‚ã€ã‚°ãƒ«ãƒ¼ãƒ—ã« Runner を追加ã§ãã¾ã™"
@@ -21905,7 +23174,7 @@ msgid "To-Do List"
msgstr "To-Do リスト"
msgid "To-do item successfully marked as done."
-msgstr ""
+msgstr "Todo ã‚’ 完了ã¨ãƒžãƒ¼ã‚¯ã—ã¾ã—ãŸã€‚"
msgid "Today"
msgstr "今日"
@@ -21923,17 +23192,20 @@ msgid "Toggle backtrace"
msgstr "ãƒãƒƒã‚¯ãƒˆãƒ¬ãƒ¼ã‚¹ã‚’切り替ãˆ"
msgid "Toggle collapse"
-msgstr ""
+msgstr "表示・éžè¡¨ç¤ºåˆ‡ã‚Šæ›¿ãˆ"
msgid "Toggle comments for this file"
-msgstr ""
+msgstr "ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã®ã‚³ãƒ¡ãƒ³ãƒˆã®åˆ‡ã‚Šæ›¿ãˆ"
msgid "Toggle commit description"
-msgstr ""
+msgstr "コミットã®èª¬æ˜Žã®åˆ‡ã‚Šæ›¿ãˆ"
msgid "Toggle commit list"
msgstr "コミットリストを切り替ãˆ"
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr "絵文字賞をå—賞"
@@ -21950,10 +23222,10 @@ msgid "Toggle the Performance Bar"
msgstr "パフォーマンスãƒãƒ¼ã®åˆ‡ã‚Šæ›¿ãˆ"
msgid "Toggle this dialog"
-msgstr ""
+msgstr "ダイアログを切り替ãˆ"
msgid "Toggle thread"
-msgstr ""
+msgstr "スレッドã®åˆ‡ã‚Šæ›¿ãˆ"
msgid "ToggleButton|Toggle Status: OFF"
msgstr "切り替ãˆçŠ¶æ…‹:オフ"
@@ -21989,16 +23261,10 @@ msgid "Total Contributions"
msgstr "ç·è²¢çŒ®åº¦"
msgid "Total artifacts size: %{total_size}"
-msgstr ""
-
-msgid "Total cores (vCPUs)"
-msgstr ""
+msgstr "アーティファクトã®ã‚µã‚¤ã‚º(åˆè¨ˆ): %{total_size}"
msgid "Total issues"
-msgstr ""
-
-msgid "Total memory (GB)"
-msgstr ""
+msgstr "全課題"
msgid "Total test time for all commits/merges"
msgstr "ã™ã¹ã¦ã®ã‚³ãƒŸãƒƒãƒˆ/マージã®åˆè¨ˆãƒ†ã‚¹ãƒˆæ™‚é–“"
@@ -22015,9 +23281,6 @@ msgstr ""
msgid "Tracing"
msgstr "追跡"
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr "プロジェクトãŠã‚ˆã³ãƒžã‚¤ãƒ«ã‚¹ãƒˆãƒ¼ãƒ³å…¨ä½“ã§ã€ãƒ†ãƒ¼ãƒžã‚’共有ã™ã‚‹èª²é¡Œã®ã‚°ãƒ«ãƒ¼ãƒ—を追跡"
@@ -22028,7 +23291,7 @@ msgid "Track your GitLab projects with GitLab for Slack."
msgstr ""
msgid "Track your project with Audit Events."
-msgstr ""
+msgstr "監査イベントã§ã‚ãªãŸã®ãƒ—ロジェクトを追跡ã—ã¾ã™ã€‚"
msgid "Transfer ownership"
msgstr ""
@@ -22036,6 +23299,9 @@ msgstr ""
msgid "Transfer project"
msgstr "プロジェクトを転é€"
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22046,7 +23312,7 @@ msgid "TransferGroup|Group contains projects with NPM packages."
msgstr ""
msgid "TransferGroup|Group is already a root group."
-msgstr ""
+msgstr "グループã¯ã™ã§ã«ãƒ«ãƒ¼ãƒˆã‚°ãƒ«ãƒ¼ãƒ—ã§ã™ã€‚"
msgid "TransferGroup|Group is already associated to the parent group."
msgstr "Groupã¯ã™ã§ã«è¦ªã‚°ãƒ«ãƒ¼ãƒ—ã«é–¢é€£ä»˜ã‘ã§ãã¦ã„ã¾ã™ã€‚"
@@ -22067,7 +23333,7 @@ msgid "TransferProject|Please select a new namespace for your project."
msgstr "プロジェクトã®æ–°ã—ã„åå‰ç©ºé–“ã‚’é¸æŠžã—ã¦ãã ã•ã„。"
msgid "TransferProject|Project cannot be transferred, because tags are present in its container registry"
-msgstr ""
+msgstr "コンテナレジストリ内㫠tag ãŒå­˜åœ¨ã™ã‚‹ãŸã‚ã€ãƒ—ロジェクトを転é€ã§ãã¾ã›ã‚“。"
msgid "TransferProject|Project with same name or path in target namespace already exists"
msgstr "移動先ã®åå‰ç©ºé–“ã«ã€åŒã˜åå‰ã¾ãŸã¯åŒã˜ãƒ‘スをæŒã¤ãƒ—ロジェクトãŒæ—¢ã«å­˜åœ¨ã—ã¾ã™"
@@ -22097,13 +23363,13 @@ msgid "Trials|You won't get a free trial right now but you can always resume thi
msgstr ""
msgid "Trigger"
-msgstr ""
+msgstr "トリガー"
msgid "Trigger pipelines for mirror updates"
msgstr "ミラー更新ã®ãŸã‚ã®ã€ãƒ‘イプライントリガー"
msgid "Trigger pipelines when branches or tags are updated from the upstream repository. Depending on the activity of the upstream repository, this may greatly increase the load on your CI runners. Only enable this if you know they can handle the load."
-msgstr ""
+msgstr "ブランãƒã¾ãŸã¯ã‚¿ã‚°ãŒã‚¢ãƒƒãƒ—ストリームリãƒã‚¸ãƒˆãƒªã‹ã‚‰æ›´æ–°ã•ã‚ŒãŸã¨ãã«ãƒ‘イプラインをトリガã—ã¾ã™ã€‚アップストリームリãƒã‚¸ãƒˆãƒªã®ã‚¢ã‚¯ãƒ†ã‚£ãƒ“ティã«ã‚ˆã£ã¦ã¯ã€ã“ã‚Œã«ã‚ˆã‚ŠCI runnerã®è² è·ãŒå¤§å¹…ã«å¢—加ã™ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚è² è·ã‚’処ç†ã§ãã‚‹ã“ã¨ãŒã‚ã‹ã£ã¦ã„ã‚‹å ´åˆã«ã®ã¿ã€ã“れを有効ã«ã—ã¦ãã ã•ã„。"
msgid "Trigger removed."
msgstr "トリガーを除去ã—ã¾ã—ãŸã€‚"
@@ -22127,7 +23393,7 @@ msgid "Triggerer"
msgstr "トリガー"
msgid "Triggers can force a specific branch or tag to get rebuilt with an API call. These tokens will impersonate their associated user including their access to projects and their project permissions."
-msgstr ""
+msgstr "トリガーã¯ã€ç‰¹å®šã®ãƒ–ランãƒã¾ãŸã¯ã‚¿ã‚°ã‚’ API 呼ã³å‡ºã—ã§å¼·åˆ¶çš„ã«å†æ§‹ç¯‰ã•ã›ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ã“れらã®ãƒˆãƒ¼ã‚¯ãƒ³ã¯ã€ãƒ—ロジェクトã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ã‚„プロジェクトã®ã‚¢ã‚¯ã‚»ã‚¹æ¨©ãªã©ã€é–¢é€£ã™ã‚‹ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’å½è£…ã—ã¾ã™ã€‚"
msgid "Troubleshoot and monitor your application with tracing"
msgstr "追跡ã§ã‚¢ãƒ—リケーションをトラブルシューティングãŠã‚ˆã³ç›£è¦–ã™ã‚‹"
@@ -22147,20 +23413,23 @@ msgstr ""
msgid "Try to fork again"
msgstr "ã‚‚ã†ä¸€åº¦ãƒ•ã‚©ãƒ¼ã‚¯ã™ã‚‹"
-msgid "Try using a different search term to find the file you are looking for."
+msgid "Try to keep the first line under 52 characters and the others under 72."
msgstr ""
+msgid "Try using a different search term to find the file you are looking for."
+msgstr "別ã®ç”¨èªžã§æ¤œç´¢ã—ã¦ã€æŽ¢ã—ã¦ã„るファイルを見ã¤ã‘ã¦ãã ã•ã„。"
+
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 "デãƒã‚¤ã‚¹ã¨é€šä¿¡ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚(ã¾ã æº–å‚™ã§ãã¦ã„ãªã„å ´åˆã¯) デãƒã‚¤ã‚¹ã‚’接続ã—ã¦ã€ãƒœã‚¿ãƒ³ã‚’押ã—ã¾ã™ã€‚"
msgid "Tuesday"
msgstr "ç«æ›œæ—¥"
msgid "Turn Off"
-msgstr ""
+msgstr "無効"
msgid "Turn On"
-msgstr ""
+msgstr "有効"
msgid "Turn on Service Desk"
msgstr "サービスデスクを有効ã«ã™ã‚‹"
@@ -22175,13 +23444,13 @@ msgid "Two-Factor Authentication code"
msgstr ""
msgid "Two-factor Authentication"
-msgstr ""
+msgstr "2è¦ç´ èªè¨¼"
msgid "Two-factor Authentication Recovery codes"
-msgstr ""
+msgstr "2è¦ç´ èªè¨¼ã®å›žå¾©ã‚³ãƒ¼ãƒ‰"
msgid "Two-factor Authentication has been disabled for this user"
-msgstr ""
+msgstr "ã“ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®2è¦ç´ èªè¨¼ãŒç„¡åŠ¹ã«ãªã‚Šã¾ã—ãŸã€‚"
msgid "Two-factor authentication"
msgstr "2è¦ç´ èªè¨¼"
@@ -22193,10 +23462,10 @@ msgid "Type/State"
msgstr ""
msgid "U2F Devices (%{length})"
-msgstr ""
+msgstr "2è¦ç´ èªè¨¼ãƒ‡ãƒã‚¤ã‚¹ (%{length})"
msgid "U2F only works with HTTPS-enabled websites. Contact your administrator for more details."
-msgstr ""
+msgstr "2è¦ç´ èªè¨¼ã¯HTTPSãŒæœ‰åŠ¹ãªWebサイトã§ã®ã¿å‹•ä½œã—ã¾ã™ã€‚詳細ã«ã¤ã„ã¦ã¯ç®¡ç†è€…ã«é€£çµ¡ã—ã¦ãã ã•ã„。"
msgid "URL"
msgstr "URL"
@@ -22204,38 +23473,41 @@ msgstr "URL"
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
-msgstr ""
+msgstr "(アーカイブãªã©ã®)リãƒã‚¸ãƒˆãƒªã®é™çš„オブジェクトをä¿ç®¡ã™ã‚‹å¤–部ストレージã®URL"
msgid "URL or request ID"
msgstr ""
-msgid "Unable to apply suggestions to a deleted line."
+msgid "UTC"
msgstr ""
+msgid "Unable to apply suggestions to a deleted line."
+msgstr "削除ã•ã‚ŒãŸè¡Œã«ã¯æ案をé©ç”¨ã§ãã¾ã›ã‚“。"
+
msgid "Unable to build Slack link."
-msgstr ""
+msgstr "Slackã®ãƒªãƒ³ã‚¯ã‚’構築ã§ããªã„"
msgid "Unable to collect CPU info"
-msgstr ""
+msgstr "CPU ã®æƒ…報をåŽé›†ã§ããªã„"
msgid "Unable to collect memory info"
-msgstr ""
+msgstr "メモリ情報をåŽé›†ã§ããªã„"
msgid "Unable to connect to Elasticsearch"
msgstr ""
msgid "Unable to connect to Prometheus server"
-msgstr ""
+msgstr "Prometheus サーãƒãƒ¼ã«æŽ¥ç¶šã§ãã¾ã›ã‚“"
msgid "Unable to connect to server: %{error}"
-msgstr ""
+msgstr "サーãƒãƒ¼ã«æŽ¥ç¶šã§ãã¾ã›ã‚“ã§ã—ãŸ: %{error}"
msgid "Unable to connect to the Jira instance. Please check your Jira integration configuration."
msgstr ""
@@ -22247,12 +23519,15 @@ msgid "Unable to fetch unscanned projects"
msgstr ""
msgid "Unable to fetch vulnerable projects"
-msgstr ""
+msgstr "脆弱ãªãƒ—ロジェクトã¯å–å¾—ã§ãã¾ã›ã‚“"
msgid "Unable to find Jira project to import data from."
msgstr ""
msgid "Unable to generate new instance ID"
+msgstr "æ–°ã—ã„インスタンスIDを生æˆã§ãã¾ã›ã‚“"
+
+msgid "Unable to load file contents. Try again later."
msgstr ""
msgid "Unable to load the diff"
@@ -22262,14 +23537,20 @@ msgid "Unable to load the diff. %{button_try_again}"
msgstr "差分を読ã¿è¾¼ã‚€ã“ã¨ãŒã§ãã¾ã›ã‚“。%{button_try_again}"
msgid "Unable to load the merge request widget. Try reloading the page."
+msgstr "マージリクエストウィジェットをロードã§ãã¾ã›ã‚“。ページをå†èª­ã¿è¾¼ã¿ã—ã¦ãã ã•ã„。"
+
+msgid "Unable to process group import file"
msgstr ""
msgid "Unable to resolve"
msgstr "解決ä¸å¯"
-msgid "Unable to save your changes. Please try again."
+msgid "Unable to save iteration. Please try again"
msgstr ""
+msgid "Unable to save your changes. Please try again."
+msgstr "変更をä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
+
msgid "Unable to schedule a pipeline to run immediately"
msgstr "パイプラインを今ã™ã実行ã™ã‚‹ã‚ˆã†ã«ã‚¹ã‚±ã‚¸ãƒ¥ãƒ¼ãƒ«ã§ãã¾ã›ã‚“"
@@ -22289,7 +23570,7 @@ msgid "Unarchive project"
msgstr "プロジェクトã®ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–解除"
msgid "Unarchiving the project will restore people's ability to make changes to it. The repository can be committed to, and issues, comments, and other entities can be created. %{strong_start}Once active, this project shows up in the search and on the dashboard.%{strong_end}"
-msgstr ""
+msgstr "ã“ã®ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–化ã—ãŸãƒ—ロジェクトを解除ã™ã‚‹ã¨ã€ã“ã®ãƒ—ロジェクトã«å¤‰æ›´ã‚’加ãˆã‚‰ã‚Œã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã™ã€‚リãƒã‚¸ãƒˆãƒªã¯ã‚³ãƒŸãƒƒãƒˆã§ãるよã†ã«ãªã‚Šã€èª²é¡Œã€ã‚³ãƒ¡ãƒ³ãƒˆã€ãã®ä»–ã®ã‚¨ãƒ³ãƒ†ã‚£ãƒ†ã‚£ã‚’作æˆã§ãã¾ã™ã€‚ %{strong_start}ã“ã®ãƒ—ロジェクトをアクティブ化ãŒçµ‚ã‚‹ã¨ã€ã“ã®ãƒ—ロジェクトã¯æ¤œç´¢ã¨ãƒ€ãƒƒã‚·ãƒ¥ãƒœãƒ¼ãƒ‰ã«è¡¨ç¤ºã•ã‚Œã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã™ã€‚%{strong_end}"
msgid "Unblock"
msgstr "ブロック解除"
@@ -22304,13 +23585,13 @@ msgid "Undo ignore"
msgstr ""
msgid "Unfortunately, your email message to GitLab could not be processed."
-msgstr ""
+msgstr "残念ãªãŒã‚‰ã€GitLab ã¸ã®ãƒ¡ãƒ¼ãƒ«å‡¦ç†ã¯ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
msgid "Uninstall"
-msgstr ""
+msgstr "アンインストール·"
msgid "Uninstalling"
-msgstr ""
+msgstr "アンインストール中"
msgid "Units|ms"
msgstr ""
@@ -22322,7 +23603,7 @@ msgid "Unknown"
msgstr "ä¸æ˜Ž"
msgid "Unknown Error"
-msgstr ""
+msgstr "ä¸æ˜Žãªã‚¨ãƒ©ãƒ¼"
msgid "Unknown cache key"
msgstr ""
@@ -22343,25 +23624,25 @@ msgid "Unlock"
msgstr "アンロック"
msgid "Unlock the discussion"
-msgstr ""
+msgstr "ディスカッションã®ãƒ­ãƒƒã‚¯ã‚’解除ã™ã‚‹"
msgid "Unlock this %{issuableDisplayName}? <strong>Everyone</strong> will be able to comment."
msgstr "%{issuableDisplayName} ã®ãƒ­ãƒƒã‚¯ã‚’解除ã—ã¾ã™ã‹ï¼Ÿ <strong>全員</strong>ãŒã‚³ãƒ¡ãƒ³ãƒˆã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚"
msgid "Unlocked"
-msgstr "アンロック済ã¿"
+msgstr "未ロック"
msgid "Unlocked the discussion."
-msgstr ""
+msgstr "ディスカッションã®ãƒ­ãƒƒã‚¯ã‚’解除ã—ãŸ"
msgid "Unlocks the discussion."
-msgstr ""
+msgstr "ディスカッションã®ãƒ­ãƒƒã‚¯ã‚’解除ã™ã‚‹."
msgid "Unmarked this %{noun} as Work In Progress."
-msgstr ""
+msgstr "ã“ã® %{noun} を作業中マークを解除ã—ã¾ã—ãŸã€‚"
msgid "Unmarks this %{noun} as Work In Progress."
-msgstr ""
+msgstr "ã“ã® %{noun} を作業中マークを解除ã—ã¾ã—ãŸã€‚"
msgid "Unreachable"
msgstr ""
@@ -22370,7 +23651,7 @@ msgid "Unresolve"
msgstr ""
msgid "Unresolve thread"
-msgstr ""
+msgstr "スレッドを未解決ã«ã™ã‚‹"
msgid "Unresolved"
msgstr ""
@@ -22448,19 +23729,19 @@ msgid "Update"
msgstr "アップデート"
msgid "Update all"
-msgstr ""
+msgstr "å…¨ã¦æ›´æ–°"
msgid "Update approval rule"
-msgstr ""
+msgstr "承èªãƒ«ãƒ¼ãƒ«ã®æ›´æ–°"
msgid "Update failed"
msgstr "更新失敗"
msgid "Update failed. Please try again."
-msgstr ""
+msgstr "æ›´æ–°ã«å¤±æ•—ã—ã¾ã—ãŸã€‚後ã§ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„"
msgid "Update it"
-msgstr ""
+msgstr "æ›´æ–°!"
msgid "Update now"
msgstr "今ã™ãæ›´æ–°"
@@ -22478,16 +23759,16 @@ msgid "Update your project name, topics, description and avatar."
msgstr "プロジェクトåã€ãƒˆãƒ”ックã€èª¬æ˜Žã€ãã‚Œã«ã‚¢ãƒã‚¿ãƒ¼ã‚’æ›´æ–°ã—ã¦ãã ã•ã„。"
msgid "UpdateProject|Cannot rename project because it contains container registry tags!"
-msgstr ""
+msgstr "プロジェクトåを変更ã§ãã¾ã›ã‚“。プロジェクトã«ã‚³ãƒ³ãƒ†ãƒŠãƒ¬ã‚¸ã‚¹ãƒˆãƒªã‚¿ã‚°ãŒå«ã¾ã‚Œã¦ã„ã‚‹ã‹ã‚‰ã§ã™ã€‚"
msgid "UpdateProject|Could not set the default branch"
-msgstr ""
+msgstr "デフォルトã®ãƒ–ランãƒã‚’設定ã§ãã¾ã›ã‚“"
msgid "UpdateProject|New visibility level not allowed!"
-msgstr ""
+msgstr "æ–°ã—ã„å¯è¦–性レベルã¯è¨±å¯ã•ã‚Œã¾ã›ã‚“ï¼"
msgid "UpdateProject|Project could not be updated!"
-msgstr ""
+msgstr "プロジェクトを更新ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
msgid "UpdateRepositoryStorage|Error moving repository storage for %{project_full_path} - %{message}"
msgstr ""
@@ -22514,19 +23795,13 @@ msgid "Updating"
msgstr "更新中"
msgid "Upgrade plan to unlock Canary Deployments feature"
-msgstr ""
-
-msgid "Upgrade your plan"
-msgstr "プランをアップグレードã™ã‚‹"
+msgstr "カナリアデプロイ機能を実行ã§ãるよã†ã«ã™ã‚‹ãŸã‚ã«ãƒ—ランをアップグレード"
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr "高度ãªã‚°ãƒ­ãƒ¼ãƒãƒ«æ¤œç´¢ã‚’有効ã«ã™ã‚‹ãŸã‚ã«ãƒ—ランをアップグレードã—ã¾ã™ã€‚"
msgid "Upgrade your plan to activate Audit Events."
-msgstr ""
-
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr "貢献分æžã‚’有効ã«ã™ã‚‹ãŸã‚ã«ã€ãƒ—ランをアップグレードã—ã¾ã™ã€‚"
+msgstr "監査イベントを有効ã«ã™ã‚‹ãŸã‚ã«ã€ãƒ—ランをアップグレード"
msgid "Upgrade your plan to activate Group Webhooks."
msgstr "グループ ウェブフックを有効ã«ã™ã‚‹ãŸã‚ã«ã€ãƒ—ランをアップグレード"
@@ -22535,7 +23810,7 @@ msgid "Upgrade your plan to improve Issue boards."
msgstr "課題ボードã®æ©Ÿèƒ½ã‚’強化ã™ã‚‹ãŸã‚ã«ã€ãƒ—ランをアップグレード"
msgid "Upgrade your plan to improve Merge Requests."
-msgstr ""
+msgstr "マージリクエストã®æ©Ÿèƒ½ã‚’強化ã™ã‚‹ãŸã‚ã«ã€ãƒ—ランをアップグレード"
msgid "Upload <code>GoogleCodeProjectHosting.json</code> here:"
msgstr "<code>GoogleCodeProjectHosting.json</code> をアップロードã—ã¾ã™:"
@@ -22546,9 +23821,12 @@ msgstr "CSVファイルã®ã‚¢ãƒƒãƒ—ロード"
msgid "Upload New File"
msgstr "æ–°è¦ãƒ•ã‚¡ã‚¤ãƒ«ã‚’アップロード"
-msgid "Upload a certificate for your domain with all intermediates"
+msgid "Upload New License"
msgstr ""
+msgid "Upload a certificate for your domain with all intermediates"
+msgstr "ドメインã®è¨¼æ˜Žæ›¸ã¨ä¸­é–“証明書をアップロード"
+
msgid "Upload a private key for your certificate"
msgstr ""
@@ -22564,6 +23842,9 @@ msgstr "クリックã—ã¦ã‚¢ãƒƒãƒ—ロード"
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22588,24 +23869,27 @@ msgstr "使ã„æ–¹"
msgid "Usage ping is not enabled"
msgstr "ping ã®ä½¿ç”¨ãŒæœ‰åŠ¹ã«ãªã£ã¦ã„ã¾ã›ã‚“"
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr "使用状æ³ã®çµ±è¨ˆ"
msgid "UsageQuota|%{help_link_start}Shared runners%{help_link_end} are disabled, so there are no limits set on pipeline usage"
-msgstr ""
+msgstr "%{help_link_start}共有 Runner%{help_link_end} ã¯ç„¡åŠ¹ã«ãªã£ã¦ã„ã‚‹ãŸã‚ã€ãƒ‘イプラインã®ä½¿ç”¨ã«åˆ¶é™ã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "UsageQuota|Artifacts"
msgstr "æˆæžœç‰©"
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr "追加分ã®è³¼å…¥"
msgid "UsageQuota|Current period usage"
msgstr "ç¾åœ¨ã®ä½¿ç”¨çŠ¶æ³"
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr "LFSストレージ"
@@ -22615,12 +23899,18 @@ msgstr "パッケージ"
msgid "UsageQuota|Pipelines"
msgstr "パイプライン"
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr "リãƒã‚¸ãƒˆãƒª"
msgid "UsageQuota|Storage"
msgstr "ストレージ"
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr "ã“ã®ãƒãƒ¼ãƒ ã‚¹ãƒšãƒ¼ã‚¹ã«ã¯ã€å…±æœ‰ãƒ©ãƒ³ãƒŠãƒ¼ã‚’使用ã™ã‚‹ãƒ—ロジェクトã¯ã‚ã‚Šã¾ã›ã‚“。"
@@ -22634,17 +23924,23 @@ msgid "UsageQuota|Usage Quotas"
msgstr ""
msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group"
-msgstr ""
+msgstr "%{strong_start}%{group_name}%{strong_end} グループã®ãƒ—ロジェクト全体ã§ã®ã‚°ãƒ«ãƒ¼ãƒ—リソースã®ä½¿ç”¨çŽ‡"
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr "Wiki"
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr "%{link_start} スコープã®ãƒ©ãƒ™ãƒ«ã‚»ãƒƒãƒˆ%{link_end} を作æˆã™ã‚‹ã«ã¯ã€ %{code_start}::%{code_end} を使用ã—ã¾ã™ï¼ˆä¾‹ï¼š %{code_start}priority::1%{code_end})。"
@@ -22667,9 +23963,9 @@ msgid "Use group milestones to manage issues from multiple projects in the same
msgstr "グループマイルストーンを使用ã—ã¦ã€åŒã˜ãƒžã‚¤ãƒ«ã‚¹ãƒˆãƒ¼ãƒ³å†…ã®è¤‡æ•°ã®ãƒ—ロジェクトã®èª²é¡Œã‚’管ç†ã—ã¾ã™ã€‚"
msgid "Use hashed storage"
-msgstr ""
+msgstr "ãƒãƒƒã‚·ãƒ¥ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚’使ã†"
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22697,13 +23993,13 @@ msgid "Used to help configure your identity provider"
msgstr "アイデンティティ プロãƒã‚¤ãƒ€ãƒ¼ã‚’設定ã™ã‚‹ã®ã«ä½¿ç”¨ã—ã¾ã™"
msgid "User"
-msgstr ""
+msgstr "ユーザー"
msgid "User %{current_user_username} has started impersonating %{username}"
-msgstr ""
+msgstr "ユーザー %{current_user_username} ㌠アカウント%{username} ã®ä»£ç”¨ã‚’開始ã—ã¾ã—ãŸ"
msgid "User %{username} was successfully removed."
-msgstr ""
+msgstr "ユーザー %{username} を正常ã«å‰Šé™¤ã—ã¾ã—ãŸã€‚"
msgid "User Cohorts are only shown when the %{usage_ping_link_start}usage ping%{usage_ping_link_end} is enabled."
msgstr "ユーザー世代㯠%{usage_ping_link_start} ping ã®ä½¿ç”¨ %{usage_ping_link_end} ãŒæœ‰åŠ¹ãªå ´åˆã«ã®ã¿è¡¨ç¤ºã•ã‚Œã¾ã™ã€‚"
@@ -22733,7 +24029,7 @@ msgid "User is not allowed to resolve thread"
msgstr ""
msgid "User key was successfully removed."
-msgstr ""
+msgstr "ユーザーキーを正常ã«å‰Šé™¤ã—ã¾ã—ãŸã€‚"
msgid "User map"
msgstr "ユーザーマップ"
@@ -22742,118 +24038,115 @@ msgid "User pipeline minutes were successfully reset."
msgstr "ユーザーã®ãƒ‘イプライン時間ãŒæ­£å¸¸ã«ãƒªã‚»ãƒƒãƒˆã•ã‚Œã¾ã—ãŸã€‚"
msgid "User restrictions"
-msgstr ""
-
-msgid "User settings"
-msgstr "ユーザー設定"
+msgstr "ユーザーã®åˆ¶é™"
msgid "User was successfully created."
msgstr "ユーザーã¯æ­£å¸¸ã«ä½œæˆã•ã‚Œã¾ã—ãŸã€‚"
msgid "User was successfully removed from group and any subresources."
-msgstr ""
+msgstr "ユーザーã¯ã‚°ãƒ«ãƒ¼ãƒ—ã¨ã™ã¹ã¦ã®ã‚µãƒ–リソースã‹ã‚‰æ­£å¸¸ã«å‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚"
msgid "User was successfully removed from project."
-msgstr ""
+msgstr "ユーザーã¯æ­£å¸¸ã«ãƒ—ロジェクトã‹ã‚‰å‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚"
msgid "User was successfully updated."
-msgstr ""
+msgstr "ユーザーを正常ã«æ›´æ–°ã—ã¾ã—ãŸã€‚"
msgid "UserOnboardingTour|%{activeTour}/%{totalTours}"
msgstr "%{activeTour}/%{totalTours}"
msgid "UserOnboardingTour|%{completed}/%{total} steps completed"
-msgstr ""
+msgstr "%{total} ステップ中 %{completed} ステップ完了"
msgid "UserOnboardingTour|%{emphasisStart}Well done!%{emphasisEnd}%{lineBreak}%{lineBreak}That's it for our guided tour, congratulations for making it all the way to the end!%{lineBreak}%{lineBreak}We hope this gave you a good overview of GitLab and how it can help you. We'll now show you how to create your own project and invite your colleagues."
-msgstr ""
+msgstr "%{emphasisStart}よãã§ãã¾ã—ãŸï¼%{emphasisEnd}%{lineBreak}%{lineBreak}ã“ã‚Œã§ã‚¬ã‚¤ãƒ‰ãƒ„アーã¯çµ‚了ã§ã™ã€‚最後ã¾ã§å®Œäº†ã—ã¾ã—ãŸã€‚ãŠã‚ã§ã¨ã†ã”ã–ã„ã¾ã™ï¼%{lineBreak}%{lineBreak}ã“れ㧠GitLab ã®æ¦‚è¦ã¨ã©ã†æ´»ç”¨ã™ã‚‹ã‹ç†è§£ã§ããŸã¨æ€ã„ã¾ã™ã€‚ã“ã‚Œã‹ã‚‰ã‚ãªãŸè‡ªèº«ã®ãƒ—ロジェクトを作æˆã—ã€åŒåƒšã‚’招待ã™ã‚‹æ–¹æ³•ã‚’紹介ã—ã¾ã™ã€‚"
msgid "UserOnboardingTour|Adding other members to a project is done through Project Settings. Click on %{emphasisStart}Settings%{emphasisEnd}."
-msgstr ""
+msgstr "プロジェクト設定ã‹ã‚‰ä»–ã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’プロジェクトã«è¿½åŠ ã§ãã¾ã™ã€‚%{emphasisStart}設定%{emphasisEnd}をクリックã—ã¦ãã ã•ã„。"
msgid "UserOnboardingTour|Alright, that's it for Commits. Let's take a look at the %{emphasisStart}Branches%{emphasisEnd}."
-msgstr ""
+msgstr "ãã†ã€ã“ã‚ŒãŒã‚³ãƒŸãƒƒãƒˆã§ã™ã€‚ %{emphasisStart}ブランãƒ%{emphasisEnd}を見ã¦ã¿ã¾ã—ょã†ã€‚"
msgid "UserOnboardingTour|Awesome! Now click on %{emphasisStart}Members%{emphasisEnd}."
-msgstr ""
+msgstr "ã™ã°ã‚‰ã—ã„ï¼ç¶šã„ã¦%{emphasisStart}メンãƒãƒ¼%{emphasisEnd}をクリック。"
msgid "UserOnboardingTour|Click on one of the %{emphasisStart}Compare%{emphasisEnd} buttons to compare a branch to master."
-msgstr ""
+msgstr "ä»»æ„ã®ãƒ–ランãƒã‚’ master ブランãƒã¨æ¯”較ã™ã‚‹ã«ã¯ã€ã„ãšã‚Œã‹ã® %{emphasisStart} 比較%{emphasisEnd} ボタンをクリックã—ã¾ã™ã€‚"
msgid "UserOnboardingTour|Click on one of the %{emphasisStart}pipeline IDs%{emphasisEnd} to see the details of a pipeline."
-msgstr ""
+msgstr "パイプラインã®è©³ç´°ã‚’表示ã™ã‚‹ã«ã¯ã€ %{emphasisStart}パイプラインID%{emphasisEnd} ã„ãšã‚Œã‹ã‚’クリックã—ã¾ã™ã€‚"
msgid "UserOnboardingTour|Click to open the latest commit to see its details."
-msgstr ""
+msgstr "最新ã®ã‚³ãƒŸãƒƒãƒˆã‚’é–‹ã„ã¦è©³ç´°ã‚’確èªã™ã‚‹ã«ã¯ã‚¯ãƒªãƒƒã‚¯ã—ã¾ã™ã€‚"
msgid "UserOnboardingTour|Close 'Learn GitLab'"
-msgstr ""
+msgstr "'GitLabã«ã¤ã„ã¦å­¦ã¶' を終了"
msgid "UserOnboardingTour|Commits are shown in chronological order and can be filtered by the commit message or by the branch."
-msgstr ""
+msgstr "コミットã¯æ™‚系列ã§è¡¨ç¤ºã•ã‚Œã€ã‚³ãƒŸãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã¾ãŸã¯ãƒ–ランãƒã§ãƒ•ã‚£ãƒ«ã‚¿ãƒªãƒ³ã‚°ã§ãã¾ã™ã€‚"
msgid "UserOnboardingTour|Create a project"
-msgstr ""
+msgstr "プロジェクトを作æˆã™ã‚‹"
msgid "UserOnboardingTour|Exit 'Learn GitLab'"
msgstr "'GitLabã«ã¤ã„ã¦å­¦ã¶' を終了"
msgid "UserOnboardingTour|Got it"
-msgstr ""
+msgstr "了解"
msgid "UserOnboardingTour|Great job! %{clapHands} We hope the tour was helpful and that you learned how to use GitLab.%{lineBreak}%{lineBreak}We'd love to get your feedback on this tour.%{lineBreak}%{lineBreak}%{emphasisStart}How helpful would you say this guided tour was?%{emphasisEnd}%{lineBreak}%{lineBreak}"
-msgstr ""
+msgstr "よãã§ãã¾ã—ãŸï¼ %{clapHands} ã“ã®ãƒ„アーãŒå‚考ã«ãªã‚Šã€GitLab ã®ä½¿ã„方を学ã¹ã‚Œã°å¹¸ã„ã§ã™ã€‚%{lineBreak}%{lineBreak}ã“ã®ãƒ„アーã«é–¢ã™ã‚‹ãƒ•ã‚£ãƒ¼ãƒ‰ãƒãƒƒã‚¯ã‚’ãŠå¾…ã¡ã—ã¦ãŠã‚Šã¾ã™ã€‚%{lineBreak}%{lineBreak}%{emphasisStart}ã“ã®ã‚¬ã‚¤ãƒ‰ä»˜ãツアーã¯ã©ã®ç¨‹åº¦å½¹ã«ç«‹ã¡ã¾ã—ãŸã‹ï¼Ÿ%{emphasisEnd}%{lineBreak}%{lineBreak}"
msgid "UserOnboardingTour|Guided GitLab Tour"
-msgstr ""
+msgstr "ガイド付ãGitLabツアー"
msgid "UserOnboardingTour|Here you can compare the changes of this branch to another one. Changes are divided by files so that it's easier to see what was changed where."
-msgstr ""
+msgstr "ã“ã®ãƒ–ランãƒã®å¤‰æ›´ã‚’ä»–ã®ãƒ–ランãƒã¨æ¯”較ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚変更ã¯ãƒ•ã‚¡ã‚¤ãƒ«ã«ã‚ˆã£ã¦åˆ†å‰²ã•ã‚Œã‚‹ãŸã‚ã€å¤‰æ›´å†…容ãŒã©ã“ã§å¤‰æ›´ã•ã‚ŒãŸã‹ãŒåˆ†ã‹ã‚Šã‚„ã™ããªã‚Šã¾ã™ã€‚"
msgid "UserOnboardingTour|Here you can create a project from scratch, start with a template or import a repository from other platforms. Whatever you choose, we'll guide you through the process.%{lineBreak}%{lineBreak}Fill in your new project information and click on %{emphasisStart}Create Project%{emphasisEnd} to progress to the next step."
-msgstr ""
+msgstr "ã“ã“ã§ã¯ã€ãƒ—ロジェクトを最åˆã‹ã‚‰ä½œæˆã™ã‚‹ã€ãƒ†ãƒ³ãƒ—レートã‹ã‚‰å§‹ã‚ã‚‹ã€ã¾ãŸã¯ä»–ã®ãƒ—ラットフォームã‹ã‚‰ãƒªãƒã‚¸ãƒˆãƒªã‚’インãƒãƒ¼ãƒˆã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ã©ã®æ–¹æ³•ã§å§‹ã‚ã¦ã‚‚ã€é€²è¡ŒçŠ¶æ³ã‚’ãŠçŸ¥ã‚‰ã›ã—ã¾ã™ã€‚%{lineBreak}%{lineBreak} æ–°ã—ã„プロジェクトã®æƒ…報を入力ã—ã¦ã€ %{emphasisStart}プロジェクトを作æˆ%{emphasisEnd} をクリックã—ã¦æ¬¡ã®ã‚¹ãƒ†ãƒƒãƒ—ã«é€²ã¿ã¾ã™ã€‚"
msgid "UserOnboardingTour|Here you can see the breakdown of the pipelines: its stages and jobs in each of the stages and their status.%{lineBreak}%{lineBreak}Our CI/CD pipelines are quite complex, most of our users have fewer and simpler pipelines."
-msgstr ""
+msgstr "ã“ã“ã§ãƒ‘イプラインã®ä¸­èº«ã‚’見るã“ã¨ãŒã§ãã¾ã™ã€‚ステージã¨ã€å„ステージã®ã‚¸ãƒ§ãƒ–ã€ãã—ã¦ãれらã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã§ã™ã€‚%{lineBreak}%{lineBreak}ç§ãŸã¡ã®CI/CDパイプラインã¯éžå¸¸ã«è¤‡é›‘ã§ã™ã€‚ユーザーã®ã»ã¨ã‚“ã©ã¯ã‚ˆã‚Šå°‘ãªãã€ã‚ˆã‚Šå˜ç´”ãªãƒ‘イプラインを使ã£ã¦ã„ã¾ã™ã€‚"
msgid "UserOnboardingTour|Here you can see the current members of the project (just you at the moment) and invite new members.%{lineBreak}%{lineBreak}You can invite multiple members at once (existing GitLab users or invite by email) and you can also set their roles and permissions.%{lineBreak}%{lineBreak}Add a few members and click on %{emphasisStart}Add to project%{emphasisEnd} to complete this step."
-msgstr ""
+msgstr "ã“ã“ã§ã¯ã€ãƒ—ロジェクトã®ç¾åœ¨ã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’確èªã—ã¦(ç¾æ™‚点ã§ã¯ã‚ãªãŸã ã‘)ã€æ–°ã—ã„メンãƒãƒ¼ã‚’招待ã§ãã¾ã™ã€‚%{lineBreak}%{lineBreak}一度ã«è¤‡æ•°ã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’招待ã§ãã¾ã™(既存㮠GitLab ユーザーã®æ‹›å¾…ã¾ãŸã¯ãƒ¡ãƒ¼ãƒ«ã§ã®æ‹›å¾…)ã—ã€ã¾ãŸãƒ¡ãƒ³ãƒãƒ¼ã®å½¹å‰²ã¨æ¨©é™ã‚’設定ã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚%{lineBreak}%{lineBreak}数人ã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’追加ã—〠%{emphasisStart}プロジェクトã«è¿½åŠ %{emphasisEnd} をクリックã—ã¦ã“ã®ã‚¹ãƒ†ãƒƒãƒ—を完了ã—ã¾ã™ã€‚"
msgid "UserOnboardingTour|Here you can see what changes were made with this commit, on what branch and if there's a related merge request. The status of the pipeline will also show up if CI/CD is set up.%{lineBreak}%{lineBreak}You can also comment on the lines of code that were changed and start a discussion with your colleagues!"
-msgstr ""
+msgstr "ã“ã“ã§ã¯ã€ã“ã®ã‚³ãƒŸãƒƒãƒˆã§ã©ã®ã‚ˆã†ãªå¤‰æ›´ãŒè¡Œã‚ã‚ŒãŸã®ã‹ã€ã©ã®ãƒ–ランãƒã§ã€ãã—ã¦é–¢é€£ã™ã‚‹ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆãŒã‚ã‚‹ã®ã‹ã‚’確èªã§ãã¾ã™ã€‚CI/CDãŒè¨­å®šã•ã‚Œã¦ã„ã‚‹å ´åˆã¯ã€ãƒ‘イプラインã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚‚表示ã•ã‚Œã¾ã™ã€‚%{lineBreak}%{lineBreak}変更ã•ã‚ŒãŸã‚³ãƒ¼ãƒ‰ã«ã‚³ãƒ¡ãƒ³ãƒˆã—ã¦ã€åŒåƒšã¨ãƒ‡ã‚£ã‚¹ã‚«ãƒƒã‚·ãƒ§ãƒ³ã‚’始ã‚ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚"
msgid "UserOnboardingTour|Here's an overview of branches in the %{emphasisStart}%{projectName}%{emphasisEnd} project. They're split into Active and Stale.%{lineBreak}%{lineBreak}From here, you can create a new merge request from a branch, or compare the branch to any other branch in the project. By default, it will compare it to the master branch."
-msgstr ""
+msgstr "ã“れ㯠%{emphasisStart}%{projectName}%{emphasisEnd} プロジェクトã®ãƒ–ランãƒã®æ¦‚è¦ã§ã™ã€‚アクティブブランãƒã¨å¤ã„ブランãƒã«åˆ†ã‘られã¾ã™ã€‚%{lineBreak}%{lineBreak}ã“ã“ã‹ã‚‰ã€ãƒ–ランãƒã‹ã‚‰æ–°ã—ã„マージリクエストを作æˆã§ãã¾ã™ã€‚ã¾ãŸã€ãã®ãƒ–ランãƒã‚’プロジェクト内ã®ä»–ã®ãƒ–ランãƒã¨æ¯”較ã§ãã¾ã™ã€‚デフォルトã§ã¯ã€ãれをマスターブランãƒã¨æ¯”較ã—ã¾ã™ã€‚"
msgid "UserOnboardingTour|Invite colleagues"
msgstr "招待ã™ã‚‹"
msgid "UserOnboardingTour|Issues are great for communicating and keeping track of progress in GitLab. These are all issues that are open in the %{emphasisStart}%{projectName}%{emphasisEnd}.%{lineBreak}%{lineBreak}You can help us improve GitLab by contributing work to issues that are labeled <span class=\"badge color-label accept-mr-label\">Accepting merge requests</span>.%{lineBreak}%{lineBreak}This list can be filtered by labels, milestones, assignees, authors... We'll show you how it looks when the list is filtered by a label."
-msgstr ""
+msgstr "課題ã¯ã€GitLab 上ã§ã‚³ãƒŸãƒ¥ãƒ‹ã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã‚’å–ã‚Šã€é€²è¡ŒçŠ¶æ³ã‚’追跡ã™ã‚‹ã®ã«æœ€é©ãªæ©Ÿèƒ½ã§ã™ã€‚ã“れらã¯ã™ã¹ã¦ %{emphasisStart}%{projectName}%{emphasisEnd} ã®æœªè§£æ±ºã®èª²é¡Œã§ã™ã€‚%{lineBreak}%{lineBreak} <span class=\"badge color-label accept-mr-label\">マージリクエストã®æ‰¿èª</span> ã¨ã„ã†ãƒ©ãƒ™ãƒ«ã®ä»˜ã„ãŸèª²é¡Œã«ä½œæ¥­ã‚’貢献ã™ã‚‹ã“ã¨ã§ã€GitLab 本体ã®æ”¹å–„ã«ã”å”力ã„ãŸã ã‘ã¾ã™ã€‚%{lineBreak}%{lineBreak}ã“ã®ãƒªã‚¹ãƒˆã¯ãƒ©ãƒ™ãƒ«ã€ãƒžã‚¤ãƒ«ã‚¹ãƒˆãƒ¼ãƒ³ã€æ‹…当者ã€ä½œæˆè€…ãªã©ã§çµžã‚Šè¾¼ã‚€ã“ã¨ãŒã§ãã¾ã™ã€‚リストãŒãƒ©ãƒ™ãƒ«ã§çµžã‚Šè¾¼ã¾ã‚ŒãŸã¨ãã®æ§˜å­ã‚’紹介ã—ã¾ã™ã€‚"
msgid "UserOnboardingTour|Learn GitLab"
msgstr "GitLabã«ã¤ã„ã¦å­¦ã¶"
msgid "UserOnboardingTour|Let's take a closer look at a merge request. Click on the title of one."
-msgstr ""
+msgstr "マージリクエストを詳ã—ã見ã¦ã¿ã¾ã—ょã†ã€‚マージリクエストã®ã‚¿ã‚¤ãƒˆãƒ«ã‚’クリックã—ã¦ãã ã•ã„。"
msgid "UserOnboardingTour|Let's take a closer look at all the commits. Click on %{emphasisStart}Commits%{emphasisEnd}."
-msgstr ""
+msgstr "ã™ã¹ã¦ã®ã‚³ãƒŸãƒƒãƒˆã‚’詳ã—ã見ã¦ã¿ã¾ã—ょã†ã€‚ %{emphasisStart}コミット%{emphasisEnd}をクリックã—ã¦ãã ã•ã„。"
msgid "UserOnboardingTour|Let's take a closer look at the repository of this project. Click on %{emphasisStart}Repository%{emphasisEnd}."
-msgstr ""
+msgstr "ã“ã®ãƒ—ロジェクトã®ãƒªãƒã‚¸ãƒˆãƒªã‚’詳ã—ã見ã¦ã¿ã¾ã—ょã†ã€‚ %{emphasisStart}リãƒã‚¸ãƒˆãƒª%{emphasisEnd}をクリックã—ã¦ãã ã•ã„。"
msgid "UserOnboardingTour|No thanks"
-msgstr ""
+msgstr "ã„ã„ãˆã€ä¸è¦ã§ã™"
msgid "UserOnboardingTour|Ok, let's go"
-msgstr ""
+msgstr "OKã€ã‚„ã‚Šã¾ã—ょã†"
msgid "UserOnboardingTour|Ok, show me"
-msgstr ""
+msgstr "ã¯ã„ã€è¦‹ã›ã¦ãã ã•ã„"
msgid "UserOnboardingTour|Open one of the issues by clicking on its title."
-msgstr ""
+msgstr "タイトルをクリックã—ã¦èª²é¡Œã‚’é–‹ãã¾ã™ã€‚"
msgid "UserOnboardingTour|Restart this step"
msgstr "ã“ã®ã‚¹ãƒ†ãƒƒãƒ—ã‚’å†é–‹"
@@ -22862,46 +24155,46 @@ msgid "UserOnboardingTour|Skip this step"
msgstr "ã“ã®ã‚¹ãƒ†ãƒƒãƒ—をスキップ"
msgid "UserOnboardingTour|Sweet! Your project was created and is ready to be used.%{lineBreak}%{lineBreak}You can start adding files to the repository or clone it. One last thing we want to show you is how to invite your colleagues to your new project."
-msgstr ""
+msgstr "ã„ã„ã§ã™ã­ï¼ãƒ—ロジェクトãŒä½œæˆã•ã‚Œã€åˆ©ç”¨ã§ãるよã†ã«ãªã‚Šã¾ã—ãŸã€‚%{lineBreak}%{lineBreak}リãƒã‚¸ãƒˆãƒªã«ãƒ•ã‚¡ã‚¤ãƒ«ã‚’追加ã§ãã¾ã™ã€‚ã¾ãŸã€ã‚¯ãƒ­ãƒ¼ãƒ³ã§ãã¾ã™ã€‚最後ã«ãŠè¦‹ã›ã—ãŸã„ã®ã¯ã€åŒåƒšã‚’æ–°ã—ã„プロジェクトã«æ‹›å¾…ã™ã‚‹æ–¹æ³•ã§ã™ã€‚"
msgid "UserOnboardingTour|Take a look. Here's a nifty menu for quickly creating issues, merge requests, snippets, projects and groups. Click on it and select \"New project\" from the \"GitLab\" section to get started."
msgstr "ã“れを見ã¦ãã ã•ã„。課題ã€ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã€ã‚¹ãƒ‹ãƒšãƒƒãƒˆã€ãƒ—ロジェクトã€ãŠã‚ˆã³ã‚°ãƒ«ãƒ¼ãƒ—ã‚’ã™ã°ã‚„ã作æˆã™ã‚‹ãŸã‚ã®ä¾¿åˆ©ãªãƒ¡ãƒ‹ãƒ¥ãƒ¼ãŒã‚ã‚Šã¾ã™ã€‚ãれをクリックã—ã¦ã€ã€ŒGitLabã€ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã‹ã‚‰ã€ŒNew projectã€ã‚’é¸æŠžã—ã¦é–‹å§‹ã—ã¾ã™ã€‚"
msgid "UserOnboardingTour|Thanks for taking the guided tour. Remember, if you want to go through it again, you can start %{emphasisStart}Learn GitLab%{emphasisEnd} in the help menu on the top right."
-msgstr ""
+msgstr "ガイド付ãツアーをã”利用ã„ãŸã ãã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™ã€‚ã‚ãªãŸãŒå†ã³ãƒ„アーã«å‚加ã—ãŸã„ãªã‚‰ã€å³ä¸Šã®ãƒ˜ãƒ«ãƒ—メニュー㮠%{emphasisStart} GitLab を学㶠%{emphasisEnd} ã‹ã‚‰å§‹ã‚られã¾ã™ã€‚"
msgid "UserOnboardingTour|Thanks for the feedback! %{thumbsUp}"
-msgstr ""
+msgstr "フィードãƒãƒƒã‚¯ã‚’ã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™ï¼ %{thumbsUp}"
msgid "UserOnboardingTour|That's it for issues. Let'st take a look at %{emphasisStart}Merge Requests%{emphasisEnd}."
-msgstr ""
+msgstr "ã“ã‚ŒãŒèª²é¡Œã§ã™ã€‚%{emphasisStart} マージリクエスト %{emphasisEnd}を見ã¦ã¿ã¾ã—ょã†ã€‚"
msgid "UserOnboardingTour|That's it for merge requests. Now for the final part of this guided tour - the %{emphasisStart}CI/CD%{emphasisEnd}."
-msgstr ""
+msgstr "ã“ã‚ŒãŒãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã§ã™ã€‚ãã—ã¦ã“ã‚ŒãŒã‚¬ã‚¤ãƒ‰ä»˜ãツアーã®æœ€å¾Œã®éƒ¨åˆ†ã§ã™ã€‚ %{emphasisStart}CI/CD%{emphasisEnd}"
msgid "UserOnboardingTour|That's it for the Repository. Let's take a look at the %{emphasisStart}Issues%{emphasisEnd}."
-msgstr ""
+msgstr "ã“ã‚ŒãŒãƒªãƒã‚¸ãƒˆãƒªã§ã™ã€‚%{emphasisStart} 課題 %{emphasisEnd} を見ã¦ã¿ã¾ã—ょã†ã€‚"
msgid "UserOnboardingTour|The structure of this page is very similar to issues. Status, description, discussion and the sidebar are all here.%{lineBreak}%{lineBreak}But take a look below the description and you'll notice that there's more information about the merge request, the CI/CD pipeline and the options for approving it.%{lineBreak}%{lineBreak}Alongside the discussion you can also see more information about commits in this merge request, the status of pipelines and review all changes that were made."
-msgstr ""
+msgstr "ã“ã®ãƒšãƒ¼ã‚¸ã®æ§‹é€ ã¯ã€èª²é¡Œã¨éžå¸¸ã«ã‚ˆãä¼¼ã¦ã„ã¾ã™ã€‚ステータスã€èª¬æ˜Žã€ãƒ‡ã‚£ã‚¹ã‚«ãƒƒã‚·ãƒ§ãƒ³ã€ã‚µã‚¤ãƒ‰ãƒãƒ¼ãŒã™ã¹ã¦ã‚ã‚Šã¾ã™ã€‚%{lineBreak}%{lineBreak}ã—ã‹ã—ã€ä¸‹ã®èª¬æ˜Žã‚’読むã¨ã€ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã€CI/CD パイプラインã€ãŠã‚ˆã³ãã‚Œã®æ‰¿èªã‚ªãƒ—ションã«ã¤ã„ã¦ã®è©³ã—ã„情報ãŒã‚ã‚‹ã“ã¨ãŒã‚ã‹ã‚Šã¾ã™ã€‚%{lineBreak}%{lineBreak}以下ã§ã¯ã€ãƒ‡ã‚£ã‚¹ã‚«ãƒƒã‚·ãƒ§ãƒ³ã¨ä¸¦è¡Œã—ã¦ã€ã“ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã®ã‚³ãƒŸãƒƒãƒˆã€ãƒ‘イプラインã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã€ãŠã‚ˆã³è¡Œã‚ã‚ŒãŸã™ã¹ã¦ã®å¤‰æ›´ã®ãƒ¬ãƒ“ューã«ã¤ã„ã¦ã‚‚確èªã§ãã¾ã™ã€‚"
msgid "UserOnboardingTour|There's a lot of information here but don't worry, we'll go through it.%{lineBreak}%{lineBreak}On the top you can see the status of the issue and when it was opened and by whom. Directly below it is the issue description and below that are other %{emphasisStart}related issues%{emphasisEnd} and %{emphasisStart}merge requests%{emphasisEnd} (if any). Then below that is the %{emphasisStart}discussion%{emphasisEnd}, that's where most of the communication happens.%{lineBreak}%{lineBreak}On the right, there's a sidebar where you can view/change the %{emphasisStart}assignee, milestone, due date, labels, weight%{emphasisEnd}, etc."
-msgstr ""
+msgstr "ã“ã“ã«ã¯ãŸãã•ã‚“ã®æƒ…å ±ãŒã‚ã‚Šã¾ã™ãŒã€å¿ƒé…ã—ãªã„ã§ãã ã•ã„。%{lineBreak}%{lineBreak}一番上ã«ã¯ã€èª²é¡Œã®çŠ¶æ…‹ã‚„ã„ã¤èª°ãŒã‚ªãƒ¼ãƒ—ンã—ãŸã®ã‹ãŒç¢ºèªã§ãã¾ã™ã€‚ãã®ã™ã下ã«ã¯èª²é¡Œã®èª¬æ˜ŽãŒã‚ã‚Šã€ãã®ä¸‹ã«ã¯ä»–ã® %{emphasisStart}関連ã™ã‚‹èª²é¡Œ%{emphasisEnd} 㨠%{emphasisStart}マージリクエスト%{emphasisEnd} (ã‚ã‚‹å ´åˆ)ãŒã‚ã‚Šã¾ã™ã€‚ãã‚Œã‹ã‚‰ãã®ä¸‹ã« %{emphasisStart}ディスカッション%{emphasisEnd}ãŒã‚ã‚Šã€ã“ã‚Œã¯ã‚³ãƒŸãƒ¥ãƒ‹ã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã®å¤§éƒ¨åˆ†ãŒèµ·ã“ã‚‹ã¨ã“ã‚ã§ã™ã€‚%{lineBreak}%{lineBreak}å³å´ã«ã¯ã€ %{emphasisStart}ã€æ‹…当者ã€ãƒžã‚¤ãƒ«ã‚¹ãƒˆãƒ¼ãƒ³ã€æœŸæ—¥ã€ãƒ©ãƒ™ãƒ«ã€ã‚¦ã‚§ã‚¤ãƒˆ%{emphasisEnd}ãªã©ã‚’表示/変更ã™ã‚‹ã‚µã‚¤ãƒ‰ãƒãƒ¼ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "UserOnboardingTour|These are all the CI/CD pipelines we have for our %{emphasisStart}%{projectName}%{emphasisEnd} project.%{lineBreak}%{lineBreak}Here you can see the status of each pipeline, for what commit it's running for, its stages and the status for them."
-msgstr ""
+msgstr "ã“ã‚Œã¯ã€ %{emphasisStart}%{projectName}%{emphasisEnd} プロジェクト用ã®ã™ã¹ã¦ã®CI/CDパイプラインã§ã™ã€‚%{lineBreak}%{lineBreak}ã“ã“ã§ã¯ã€å„パイプラインã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã€å®Ÿè¡Œä¸­ã®ã‚³ãƒŸãƒƒãƒˆã€ã‚¹ãƒ†ãƒ¼ã‚¸ã€ãŠã‚ˆã³ãれらã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’確èªã§ãã¾ã™ã€‚"
msgid "UserOnboardingTour|These are all the issues that are available for community contributions. Let's take a closer look at one of them."
-msgstr ""
+msgstr "コミュニティã®è²¢çŒ®ã«åˆ©ç”¨ã§ãる課題ã§ã™ã€‚ãã®ã†ã¡ã®1ã¤ã‚’見ã¦ã¿ã¾ã—ょã†ã€‚"
msgid "UserOnboardingTour|This is an overview of all merge requests in this project. Similarly to the issues overview it can be filtered down by things like labels, milestones, authors, assignees, etc."
-msgstr ""
+msgstr "ã“ã‚Œã¯ã€ã“ã®ãƒ—ロジェクトã®ã™ã¹ã¦ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã®ä¸€è¦§ã§ã™ã€‚課題ã®ä¸€è¦§ã¨åŒã˜æ§˜ã«ã€ãƒ©ãƒ™ãƒ«ã€ãƒžã‚¤ãƒ«ã‚¹ãƒˆãƒ¼ãƒ³ã€ä½œæˆè€…ã€æ‹…当者ãªã©ã§çµžã‚Šè¾¼ã‚€ã“ã¨ãŒã§ãã¾ã™ã€‚"
msgid "UserOnboardingTour|This is the repository for the %{emphasisStart}%{projectName}%{emphasisEnd} project. All our code is stored here. Feel free to explore and take a closer look at folders and files.%{lineBreak}%{lineBreak}Above the file structure you can see the latest commit, who the author is and the status of the CI/CD pipeline.%{lineBreak}%{lineBreak}If you scroll down below the file structure, you'll find the Readme of this project. This is defined in the README.md file at the root of the repository."
-msgstr ""
+msgstr "ã“れ㯠%{emphasisStart}%{projectName}%{emphasisEnd} プロジェクトã®ãƒªãƒã‚¸ãƒˆãƒªã§ã™ã€‚ã™ã¹ã¦ã®ã‚³ãƒ¼ãƒ‰ã¯ã“ã“ã«æ ¼ç´ã•ã‚Œã¦ã„ã¾ã™ã€‚気軽ã«æŽ¢ç´¢ã—ã¦ã€ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã¨ãƒ•ã‚¡ã‚¤ãƒ«ã‚’確èªã§ãã¾ã™ã€‚%{lineBreak}%{lineBreak}ファイル構造ã®ä¸Šã«ã€æœ€æ–°ã®ã‚³ãƒŸãƒƒãƒˆã€ä½œæˆè€…ãŒèª°ã§ã‚ã‚‹ã‹ã€ãŠã‚ˆã³CI/CD パイプラインã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’確èªã§ãã¾ã™ã€‚%{lineBreak}%{lineBreak}ファイル構造ã®ã‚ˆã‚Šä¸‹ã«ã‚¹ã‚¯ãƒ­ãƒ¼ãƒ«ã™ã‚‹ã¨ã€ã“ã®ãƒ—ロジェクトã®Readmeを確èªã§ãã¾ã™ã€‚ã“ã‚Œã¯ãƒªãƒã‚¸ãƒˆãƒªã®ãƒ«ãƒ¼ãƒˆã«ã‚ã‚‹README.md ファイルã§ã™ã€‚"
msgid "UserOnboardingTour|Welcome to the project overview of the %{emphasisStart}%{projectName}%{emphasisEnd} project. This is the project that we use to work on GitLab. At first, a project seems like a simple repository, but at GitLab, a project is so much more.%{lineBreak}%{lineBreak}You can create projects for hosting your codebase, use it as an issue tracker, collaborate on code, and continuously build, test, and deploy your app with built-in GitLab CI/CD."
-msgstr ""
+msgstr "%{emphasisStart}%{projectName}%{emphasisEnd} プロジェクトã®ãƒ—ロジェクト概è¦ã¸ã‚ˆã†ã“ã。ã“ã‚Œã¯ç§ãŸã¡ãŒGitLabã«å–り組むãŸã‚ã®ãƒ—ロジェクトã§ã™ã€‚最åˆã«ã€ãƒ—ロジェクトã¯å˜ç´”ãªãƒªãƒã‚¸ãƒˆãƒªã®ã‚ˆã†ã«è¦‹ãˆã¾ã™ãŒã€GitLab ã«ã¨ã£ã¦ãƒ—ロジェクトã¯ãã‚Œã ã‘ã§ã¯ã‚ã‚Šã¾ã›ã‚“。%{lineBreak}%{lineBreak}コードベースをホスティングã™ã‚‹ãŸã‚ã®ãƒ—ロジェクトを作æˆã—ã€ãれを課題トラッカーã¨ã—ã¦ä½¿ç”¨ã—ã€ã‚³ãƒ¼ãƒ‰ã‚’コラボレートã—ã€ã•ã‚‰ã«GitLab CI/CD を組ã¿è¾¼ã‚“ã§ã‚¢ãƒ—リを継続的ã«æ§‹ç¯‰ã€ãƒ†ã‚¹ãƒˆã€ãŠã‚ˆã³å±•é–‹ã§ãã¾ã™ã€‚"
msgid "UserProfile|Activity"
msgstr "アクティビティ"
@@ -22910,7 +24203,7 @@ msgid "UserProfile|Already reported for abuse"
msgstr "æ—¢ã«å ±å‘Šã•ã‚ŒãŸä¸æ­£è¡Œç‚º"
msgid "UserProfile|Blocked user"
-msgstr ""
+msgstr "ブロックã•ã‚ŒãŸãƒ¦ãƒ¼ã‚¶ãƒ¼"
msgid "UserProfile|Contributed projects"
msgstr "貢献ã—ãŸãƒ—ロジェクト"
@@ -22952,10 +24245,10 @@ msgid "UserProfile|Snippets in GitLab can either be private, internal, or public
msgstr "GitLab ã®ã‚¹ãƒ‹ãƒšãƒƒãƒˆã¯ã€éžå…¬é–‹ã€å†…部ã€ã¾ãŸã¯å…¬é–‹ã«ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
msgid "UserProfile|Star projects to track their progress and show your appreciation."
-msgstr ""
+msgstr "プロジェクトをãŠæ°—ã«ã„り登録ã—ã¦ã€é€²æ—を追跡ã—ã€æ„Ÿè¬ã®æ°—æŒã¡ã‚’示ã—ã¾ã™ã€‚"
msgid "UserProfile|Starred projects"
-msgstr ""
+msgstr "ãŠæ°—ã«å…¥ã‚Šãƒ—ロジェクト"
msgid "UserProfile|Subscribe"
msgstr "購読"
@@ -22973,7 +24266,7 @@ msgid "UserProfile|This user hasn't starred any projects"
msgstr "ã“ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ã©ã®ãƒ—ロジェクトもãŠæ°—ã«ã„ã‚Šã«ã—ã¦ã„ã¾ã›ã‚“。"
msgid "UserProfile|This user is blocked"
-msgstr ""
+msgstr "ã“ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ãƒ–ロックã•ã‚Œã¦ã„ã¾ã™"
msgid "UserProfile|View all"
msgstr "ã™ã¹ã¦è¡¨ç¤º"
@@ -22993,6 +24286,12 @@ msgstr "スニペットを作æˆã—ã¦ã„ã¾ã›ã‚“。"
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr "プロジェクトã¯å…¬é–‹ã€å†…部公開ã€ã‚ã‚‹ã„ã¯éžå…¬é–‹ã‚’é¸æŠžã§ãã¾ã™ã€‚"
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr "ユーザå (オプション)"
@@ -23003,10 +24302,10 @@ msgid "Username is available."
msgstr "ãã®ãƒ¦ãƒ¼ã‚¶ãƒ¼åã¯ä½¿ç”¨å¯èƒ½ã§ã™ã€‚"
msgid "Username is too long (maximum is %{max_length} characters)."
-msgstr ""
+msgstr "ユーザーåãŒé•·ã™ãŽã¾ã™ï¼(最大 %{max_length} 文字)"
msgid "Username or email"
-msgstr ""
+msgstr "ユーザーåã¾ãŸã¯ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹"
msgid "Users"
msgstr "ユーザー"
@@ -23015,10 +24314,10 @@ msgid "Users in License:"
msgstr ""
msgid "Users or groups set as approvers in the project's or merge request's settings."
-msgstr ""
+msgstr "プロジェクトã®è¨­å®šã¾ãŸã¯ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã®è¨­å®šã§æ‰¿èªè€…ã¨ã—ã¦è¨­å®šã•ã‚ŒãŸãƒ¦ãƒ¼ã‚¶ãƒ¼ã¾ãŸã¯ã‚°ãƒ«ãƒ¼ãƒ—。"
msgid "Users outside of license"
-msgstr ""
+msgstr "ライセンスã•ã‚Œã¦ã„ãªã„ユーザー"
msgid "Users over License:"
msgstr ""
@@ -23033,7 +24332,7 @@ msgid "Users with a Guest role or those who don't belong to any projects or grou
msgstr "ゲストロールをæŒã¤ãƒ¦ãƒ¼ã‚¶ã€ã¾ãŸã¯ãƒ—ロジェクトやグループã«å±žã—ã¦ã„ãªã„ユーザã¯ã€ä½¿ç”¨ä¸­ã®ã‚·ãƒ¼ãƒˆã«ã‚«ã‚¦ãƒ³ãƒˆã•ã‚Œã¾ã›ã‚“。"
msgid "UsersSelect|%{name} + %{length} more"
-msgstr ""
+msgstr "%{name} + %{length} 以上"
msgid "UsersSelect|Any User"
msgstr "ä»»æ„ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼"
@@ -23053,6 +24352,9 @@ msgstr "%{code_start}::%{code_end} を使ã£ã¦ã€ %{link_start} ラベルセッ
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr "æš—å·åŒ–フィールドãŒãªã„å ´åˆã€å¿…è¦ãªæš—å·åŒ–戦略を使用ã™ã‚‹!"
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr "検証"
@@ -23072,22 +24374,25 @@ msgid "Value Stream"
msgstr ""
msgid "Value Stream Analytics"
-msgstr ""
+msgstr "ãƒãƒªãƒ¥ãƒ¼ã‚¹ãƒˆãƒªãƒ¼ãƒ åˆ†æž"
msgid "Value Stream Analytics can help you determine your team’s velocity"
-msgstr ""
+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 "ValueStreamAnalytics|%{days}d"
msgstr ""
-msgid "Var"
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
msgstr ""
msgid "Variables"
-msgstr ""
+msgstr "変数"
msgid "Various container registry settings."
msgstr "å„種コンテナレジストリã®è¨­å®šã€‚"
@@ -23096,7 +24401,7 @@ msgid "Various email settings."
msgstr "å„種メール設定。"
msgid "Various localization settings."
-msgstr ""
+msgstr "地域設定"
msgid "Various settings that affect GitLab performance."
msgstr "GitLab ã®ãƒ‘フォーマンスã«å½±éŸ¿ã™ã‚‹å„種設定。"
@@ -23108,67 +24413,73 @@ msgid "Verification information"
msgstr "検証情報"
msgid "Verification status"
-msgstr ""
+msgstr "検証ステータス"
msgid "Verified"
msgstr "検証済ã¿"
msgid "Verify SAML Configuration"
-msgstr ""
+msgstr "SAML構æˆã®ç¢ºèª"
msgid "Verify configuration"
-msgstr ""
+msgstr "設定ã®ç¢ºèª"
msgid "Version"
msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³"
-msgid "Very helpful"
+msgid "Versions"
msgstr ""
+msgid "Very helpful"
+msgstr "ã¨ã¦ã‚‚å½¹ã«ç«‹ã¡ã¾ã™"
+
msgid "View Documentation"
-msgstr ""
+msgstr "文書ã®è¡¨ç¤º"
msgid "View all issues"
-msgstr ""
+msgstr "ã™ã¹ã¦ã®èª²é¡Œã‚’表示"
msgid "View blame prior to this change"
-msgstr ""
+msgstr "ã“ã®å¤‰æ›´å‰ã® blame を表示"
msgid "View chart"
msgid_plural "View charts"
msgstr[0] ""
msgid "View dependency details for your project"
-msgstr ""
+msgstr "プロジェクトä¾å­˜é–¢ä¿‚ã®è©³ç´°è¡¨ç¤º"
msgid "View deployment"
-msgstr ""
+msgstr "デプロイを表示"
msgid "View details"
msgstr ""
msgid "View details: %{details_url}"
-msgstr ""
+msgstr "詳細を見る: %{details_url}"
msgid "View documentation"
msgstr "ドキュメントã®è¡¨ç¤º"
msgid "View eligible approvers"
-msgstr ""
+msgstr "資格ã®ã‚る承èªè€…を表示"
msgid "View epics list"
msgstr "エピックリストを表示"
msgid "View exposed artifact"
msgid_plural "View %d exposed artifacts"
-msgstr[0] ""
+msgstr[0] "%d 件ã®å…¬é–‹ã•ã‚ŒãŸã‚¢ãƒ¼ãƒ†ã‚£ãƒ•ã‚¡ã‚¯ãƒˆã‚’表示"
msgid "View file @ "
msgstr "ファイルを表示 @ "
-msgid "View full dashboard"
+msgid "View file @ %{commitSha}"
msgstr ""
+msgid "View full dashboard"
+msgstr "ダッシュボードã®ãƒ•ãƒ«è¡¨ç¤º"
+
msgid "View full log"
msgstr ""
@@ -23179,7 +24490,7 @@ msgid "View incident issues."
msgstr ""
msgid "View issue"
-msgstr ""
+msgstr "課題を表示"
msgid "View issues"
msgstr ""
@@ -23188,10 +24499,10 @@ msgid "View it on GitLab"
msgstr "GitLab ã§è¡¨ç¤º"
msgid "View job"
-msgstr ""
+msgstr "ジョブ表示"
msgid "View job log"
-msgstr ""
+msgstr "ジョブ log ã®è¡¨ç¤º"
msgid "View jobs"
msgstr "ジョブを表示"
@@ -23209,7 +24520,7 @@ msgid "View performance dashboard."
msgstr ""
msgid "View project"
-msgstr ""
+msgstr "プロジェクトを表示"
msgid "View project labels"
msgstr "プロジェクトラベルを表示"
@@ -23229,9 +24540,12 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
-msgid "Viewing commit"
+msgid "View users statistics"
msgstr ""
+msgid "Viewing commit"
+msgstr "コミットを表示中"
+
msgid "Visibility"
msgstr "公開範囲"
@@ -23245,10 +24559,10 @@ msgid "Visibility level:"
msgstr "å¯è¦–性レベル:"
msgid "Visibility settings have been disabled by the administrator."
-msgstr ""
+msgstr "管ç†è€…ã«ã‚ˆã£ã¦è¡¨ç¤ºè¨­å®šãŒç„¡åŠ¹ã«ã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "Visibility, project features, permissions"
-msgstr ""
+msgstr "å¯è¦–性ã€ãƒ—ロジェクトã®æ©Ÿèƒ½ã€æ¨©é™"
msgid "Visibility:"
msgstr "公開範囲:"
@@ -23269,34 +24583,34 @@ msgid "VisualReviewApp|%{stepStart}Step 1%{stepEnd}. Copy the following script:"
msgstr "%{stepStart}ステップ1%{stepEnd} 次ã®ã‚¹ã‚¯ãƒªãƒ—トをコピーã—ã¾ã™:"
msgid "VisualReviewApp|%{stepStart}Step 2%{stepEnd}. Add it to the %{headTags} tags of every page of your application, ensuring the merge request ID is set or not set as required. "
-msgstr ""
+msgstr "%{stepStart}ステップ2%{stepEnd}。アプリケーションã®ã™ã¹ã¦ã®ãƒšãƒ¼ã‚¸ã® %{headTags} ã‚¿ã‚°ã«è¿½åŠ ã—ã€å¿…è¦ã«å¿œã˜ã¦ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆIDãŒè¨­å®šã•ã‚Œã¦ã„ã‚‹ã‹ã©ã†ã‹ã‚’確èªã—ã¾ã™ã€‚ "
msgid "VisualReviewApp|%{stepStart}Step 3%{stepEnd}. If not previously %{linkStart}configured%{linkEnd} by a developer, enter the merge request ID for the review when prompted. The ID of this merge request is %{stepStart}%{mrId}%{stepStart}."
-msgstr ""
+msgstr "%{stepStart}ステップ3%{stepEnd}。以å‰ã«é–‹ç™ºè€…ã«ã‚ˆã£ã¦ %{linkStart} æ§‹æˆ %{linkEnd} ã•ã‚Œã¦ã„ãªã‹ã£ãŸå ´åˆã€ã“ã®ãƒ¬ãƒ“ューã®ãŸã‚ã«ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆIDを入力ã—ã¾ã™ã€‚ã“ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆID㯠%{stepStart}%{mrId}%{stepStart}ã§ã™ã€‚"
msgid "VisualReviewApp|%{stepStart}Step 4%{stepEnd}. Leave feedback in the Review App."
-msgstr ""
+msgstr "%{stepStart} ステップ4%{stepEnd} 。レビューアプリã§ãƒ•ã‚£ãƒ¼ãƒ‰ãƒãƒƒã‚¯ã‚’残ã—ã¾ã™ã€‚"
msgid "VisualReviewApp|Cancel"
msgstr ""
msgid "VisualReviewApp|Copy merge request ID"
-msgstr ""
+msgstr "マージリクエストIDã®ã‚³ãƒ”ー"
msgid "VisualReviewApp|Copy script"
-msgstr ""
+msgstr "スクリプトをコピー"
msgid "VisualReviewApp|Enable Visual Reviews"
-msgstr ""
+msgstr "ビジュアルレビューを有効化"
msgid "VisualReviewApp|Follow the steps below to enable Visual Reviews inside your application."
-msgstr ""
+msgstr "以下ã®æ‰‹é †ã«å¾“ã£ã¦ã€ã‚¢ãƒ—リケーション内ã§ãƒ“ジュアルレビューを有効ã«ã—ã¾ã™ã€‚"
msgid "VisualReviewApp|No review app found or available."
msgstr ""
msgid "VisualReviewApp|Open review app"
-msgstr ""
+msgstr "レビューアプリを開ã"
msgid "VisualReviewApp|Review"
msgstr "レビュー"
@@ -23305,13 +24619,10 @@ msgid "VisualReviewApp|Steps 1 and 2 (and sometimes 3) are performed once by the
msgstr ""
msgid "Vulnerabilities"
-msgstr ""
+msgstr "脆弱性"
msgid "Vulnerabilities over time"
-msgstr ""
-
-msgid "Vulnerability List"
-msgstr ""
+msgstr "長期ã«ã‚ãŸã‚‹è„†å¼±æ€§"
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23323,13 +24634,13 @@ msgid "Vulnerability resolved in the default branch"
msgstr ""
msgid "Vulnerability-Check"
-msgstr ""
+msgstr "脆弱性ãƒã‚§ãƒƒã‚¯"
msgid "VulnerabilityChart|%{formattedStartDate} to today"
-msgstr ""
+msgstr "%{formattedStartDate} ã‹ã‚‰ä»Šæ—¥ã¾ã§"
msgid "VulnerabilityChart|Severity"
-msgstr ""
+msgstr "é‡è¦åº¦"
msgid "VulnerabilityManagement|A true-positive and will fix"
msgstr ""
@@ -23343,9 +24654,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23401,7 +24709,7 @@ msgid "VulnerabilityStatusTypes|Resolved"
msgstr ""
msgid "Vulnerability|%{scannerName} (version %{scannerVersion})"
-msgstr ""
+msgstr "%{scannerName} (ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %{scannerVersion})"
msgid "Vulnerability|Class"
msgstr "クラス"
@@ -23437,10 +24745,10 @@ msgid "Vulnerability|Project"
msgstr "プロジェクト"
msgid "Vulnerability|Scanner Provider"
-msgstr ""
+msgstr "スキャナープロãƒã‚¤ãƒ€ãƒ¼"
msgid "Vulnerability|Scanner Type"
-msgstr ""
+msgstr "スキャナータイプ"
msgid "Vulnerability|Severity"
msgstr "é‡è¦åº¦"
@@ -23449,23 +24757,29 @@ msgid "Vulnerability|Status"
msgstr ""
msgid "WIP"
-msgstr ""
+msgstr "作業中(WIP)"
msgid "Wait for the file to load to copy its contents"
+msgstr "ファイルをロードã—ã€ãã®å†…容をコピーã—ã¦ã„ã¾ã™ã€‚ãŠå¾…ã¡ãã ã•ã„。"
+
+msgid "Waiting for merge (open and assigned)"
msgstr ""
msgid "Waiting for performance data"
-msgstr ""
+msgstr "パフォーマンスデータ待ã¡"
msgid "Want to see the data? Please ask an administrator for access."
msgstr "ã“ã®ãƒ‡ãƒ¼ã‚¿ã‚’å‚ç…§ã—ãŸã„ã§ã™ã‹ï¼Ÿã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã«ã¯ç®¡ç†è€…ã«å•ã„åˆã‚ã›ã¦ãã ã•ã„。"
msgid "Warning:"
-msgstr ""
+msgstr "警告:"
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr "エピックを削除ã™ã‚‹ãƒ‘スを特定ã§ãã¾ã›ã‚“ã§ã—ãŸ"
@@ -23473,10 +24787,10 @@ msgid "We could not determine the path to remove the issue"
msgstr "課題を削除ã™ã‚‹ãŸã‚ã®ãƒ‘スを特定ã§ãã¾ã›ã‚“ã§ã—ãŸ"
msgid "We couldn't reach the Prometheus server. Either the server no longer exists or the configuration details need updating."
-msgstr ""
+msgstr "Prometheusサーãƒãƒ¼ã«åˆ°é”ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚サーãƒãƒ¼ãŒå­˜åœ¨ã—ãªã„ã‹ã€è¨­å®šã®è©³ç´°ã‚’æ›´æ–°ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "We created a short guided tour that will help you learn the basics of GitLab and how it will help you be better at your job. It should only take a couple of minutes. You will be guided by two types of helpers, best recognized by their color."
-msgstr ""
+msgstr "GitLabã®åŸºæœ¬ã‚’å­¦ã¶ã®ã«å½¹ç«‹ã¤çŸ­ã„ツアーを作æˆã—ã¾ã—ãŸã€‚ã“ã‚ŒãŒã©ã®ã‚ˆã†ã«ã‚ãªãŸã®ä»•äº‹ã‚’改善ã§ãã‚‹ã‹ã‚’説明ã—ã¾ã™ã€‚ã“ã®ãƒ„アーã¯æ•°åˆ†ã—ã‹ã‹ã‹ã‚Šã¾ã›ã‚“。ã‚ãªãŸ2種類ã®ãƒ˜ãƒ«ãƒ‘ーã«ã‚ˆã£ã¦å°Žã‹ã‚Œã‚‹ã§ã—ょã†ã€‚ヘルパーã¯è‰²ã§å‘¼ã°ã‚Œã¾ã™ã€‚"
msgid "We detected potential spam in the %{humanized_resource_name}. Please solve the reCAPTCHA to proceed."
msgstr "%{humanized_resource_name} ã«ã‚¹ãƒ‘ムãŒã‚ã‚‹å¯èƒ½æ€§ã‚’検出ã—ã¾ã—ãŸã€‚続行ã™ã‚‹ã«ã¯ reCAPTCHA を実行ã—ã¦ãã ã•ã„。"
@@ -23485,16 +24799,22 @@ msgid "We don't have enough data to show this stage."
msgstr "データä¸è¶³ã®ãŸã‚ã€ã“ã®ã‚¹ãƒ†ãƒ¼ã‚¸ã®è¡¨ç¤ºã¯ã§ãã¾ã›ã‚“。"
msgid "We have found the following errors:"
+msgstr "次ã®ã‚¨ãƒ©ãƒ¼ãŒã‚ã‚Šã¾ã—ãŸã€‚:"
+
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
msgstr "パスワードリセット方法ã«ã¤ã„ã¦ãƒ¡ãƒ¼ãƒ«ã‚’é€ä¿¡ã—ã¾ã—ãŸ"
msgid "We tried to automatically renew your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} on %{expires_on} but something went wrong so your subscription was downgraded to the free plan. Don't worry, your data is safe. We suggest you check your payment method and get in touch with our support team (%{support_link}). They'll gladly help with your subscription renewal."
-msgstr ""
+msgstr "%{expires_on}ã«%{strong}%{namespace_name}%{strong_close}ã¸ã®%{strong}%{plan_name}%{strong_close}サブスクリプションを自動的ã«æ›´æ–°ã—よã†ã¨ã—ã¾ã—ãŸãŒã€å•é¡ŒãŒç™ºç”Ÿã—ãŸãŸã‚ã€ã‚µãƒ–スクリプションã¯ç„¡æ–™ãƒ—ランã«ãƒ€ã‚¦ãƒ³ã‚°ãƒ¬ãƒ¼ãƒ‰ã•ã‚Œã¾ã—ãŸã€‚心é…ã—ãªã„ã§ãã ã•ã„ã€ã‚ãªãŸã®ãƒ‡ãƒ¼ã‚¿ã¯å®‰å…¨ã§ã™ã€‚ãŠæ”¯æ‰•ã„方法を確èªã—ã€ã‚µãƒãƒ¼ãƒˆãƒãƒ¼ãƒ ï¼ˆ%{support_link})ã«é€£çµ¡ã™ã‚‹ã“ã¨ã‚’ãŠå‹§ã‚ã—ã¾ã™ã€‚彼らã¯ã‚ãªãŸã®ã‚µãƒ–スクリプションã®æ›´æ–°ã‚’喜んã§ãŠæ‰‹ä¼ã„ã—ã¾ã™ã€‚"
msgid "We want to be sure it is you, please confirm you are not a robot."
msgstr "本人確èªã®ãŸã‚ã€ã‚ãªãŸãŒãƒ­ãƒœãƒƒãƒˆã§ãªã„ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。"
@@ -23503,7 +24823,7 @@ msgid "We will automatically renew your %{strong}%{plan_name}%{strong_close} sub
msgstr ""
msgid "We've found no vulnerabilities"
-msgstr ""
+msgstr "脆弱性ã¯ç™ºè¦‹ã•ã‚Œã¾ã›ã‚“ã§ã—ãŸ"
msgid "Web IDE"
msgstr "Web IDE"
@@ -23529,14 +24849,11 @@ msgstr ""
msgid "Webhooks"
msgstr "Webhooks"
-msgid "Webhooks Help"
-msgstr "Webhooks ã®ãƒ˜ãƒ«ãƒ—"
-
msgid "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ã¯ã€ä¾‹ãˆã°æ–°ã—ã„コードãŒãƒ—ッシュã•ã‚ŒãŸã‚Šã€æ–°ã—ã„課題ãŒä½œæˆã•ã‚ŒãŸå ´åˆã«ã€URL を呼ã³ã ã™ã“ã¨ãŒã§ãã¾ã™ã€‚プッシュã€èª²é¡Œã¾ãŸã¯ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã®ã‚ˆã†ãªã‚¤ãƒ™ãƒ³ãƒˆã‹ã‚‰ã©ã®ã‚¤ãƒ™ãƒ³ãƒˆã‚’監視ã™ã‚‹ã‹Webhookを設定ã§ãã¾ã™ã€‚グループウェブフックã¯ã‚°ãƒ«ãƒ¼ãƒ—内ã®ã™ã¹ã¦ã®ãƒ—ロジェクトã«é©ç”¨ã•ã‚Œã€ã‚°ãƒ«ãƒ¼ãƒ—全体ã§Webhookを標準化ã™ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚"
msgid "Webhooks have moved. They can now be found under the Settings menu."
-msgstr ""
+msgstr "Webhook ã¯è¨­å®šãƒ¡ãƒ‹ãƒ¥ãƒ¼ã«ç§»å‹•ã—ã¾ã—ãŸã€‚"
msgid "Wednesday"
msgstr "水曜日"
@@ -23554,13 +24871,13 @@ msgid "Weight %{weight}"
msgstr "ウェイト %{weight}"
msgid "Welcome back! Your account had been deactivated due to inactivity but is now reactivated."
-msgstr ""
+msgstr "ãŠã‹ãˆã‚Šãªã•ã„。ã“ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¯åˆ©ç”¨ã•ã‚Œã¦ã„ãªã‹ã£ãŸãŸã‚無効化ã•ã‚Œã¦ã„ã¾ã—ãŸãŒã€æœ‰åŠ¹åŒ–ã•ã‚Œã¾ã—ãŸã€‚"
msgid "Welcome to GitLab"
-msgstr ""
+msgstr "GitLab ã¸ã‚ˆã†ã“ã"
msgid "Welcome to GitLab %{name}!"
-msgstr ""
+msgstr "%{name} ã•ã‚“ GitLab ã¸ã‚ˆã†ã“ãï¼"
msgid "Welcome to GitLab, %{first_name}!"
msgstr ""
@@ -23569,12 +24886,21 @@ msgid "Welcome to GitLab.com<br>@%{name}!"
msgstr ""
msgid "Welcome to the Guided GitLab Tour"
+msgstr "GitLab ツアーã¸ã‚ˆã†ã“ã"
+
+msgid "Welcome to the guided GitLab tour"
msgstr ""
msgid "Welcome to your Issue Board!"
-msgstr ""
+msgstr "課題ボードã¸ã‚ˆã†ã“ã"
msgid "What are you searching for?"
+msgstr "何を探ã—ã¾ã™ã‹?"
+
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
msgstr ""
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
@@ -23597,25 +24923,22 @@ msgstr "URL を空白ã®ã¾ã¾ã«ã™ã‚‹ã¨ã€ãƒ—ロジェクト間ã®æ©Ÿèƒ½ã‚’ç„
msgid "When this merge request is accepted"
msgid_plural "When these merge requests are accepted"
-msgstr[0] ""
+msgstr[0] "マージリクエストãŒæ‰¿èªã•ã‚ŒãŸã¨ã"
msgid "When using the <code>http://</code> or <code>https://</code> protocols, please provide the exact URL to the repository. HTTP redirects will not be followed."
-msgstr ""
+msgstr "<code>http://</code> ã¾ãŸã¯ <code>https://</code> プロトコルを使用ã™ã‚‹å ´åˆã€ãƒªãƒã‚¸ãƒˆãƒªã®æ­£ç¢ºãªURLを指定ã—ã¦ãã ã•ã„。 HTTPリダイレクトã¯è¿½è·¡ã•ã‚Œã¾ã›ã‚“。"
msgid "When:"
msgstr ""
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 ""
+msgstr "脆弱性ãŒãªã„事ã¯ç¨€ã§ã™ãŒã€èµ·ã“ã‚Šå¾—ã¾ã™ã€‚ã„ãšã‚Œã«ã—ã¦ã‚‚ã€ãƒ€ãƒƒã‚·ãƒ¥ãƒœãƒ¼ãƒ‰ãŒæ­£ã—ã設定ã•ã‚Œã¦ã„ã‚‹ã“ã¨ã‚’確èªã™ã‚‹ãŸã‚ã«ã€è¨­å®šã‚’å†ç¢ºèªã—ã¦ãã ã•ã„。"
msgid "White helpers give contextual information."
-msgstr ""
-
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
+msgstr "ホワイトヘルパーã¯æ–‡è„ˆæƒ…報を与ãˆã¾ã™ã€‚"
msgid "Who can be an approver?"
-msgstr ""
+msgstr "誰ãŒæ‰¿èªè€…ã«ãªã‚‹ã“ã¨ãŒã§ãã¾ã™ã‹ï¼Ÿ"
msgid "Who can see this group?"
msgstr "誰ãŒã“ã®ã‚°ãƒ«ãƒ¼ãƒ—を見れã¾ã™ã‹ï¼Ÿ"
@@ -23647,9 +24970,6 @@ msgstr "Git アクセス"
msgid "WikiClone|Install Gollum"
msgstr "Gollum をインストール"
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr "GFM 機能をローカルã§ãƒ¬ãƒ³ãƒ€ãƒªãƒ³ã‚°ã™ã‚‹ã«ã¯ %{markdown} をインストールã—ã¦ãã ã•ã„。"
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr "Gollum ã‚’èµ·å‹•ã—ã¦ãƒ­ãƒ¼ã‚«ãƒ«ã§ç·¨é›†ã™ã‚‹"
@@ -23726,16 +25046,16 @@ msgid "WikiPageConflictMessage|the page"
msgstr "ページ"
msgid "WikiPageCreate|Create %{pageTitle}"
-msgstr ""
+msgstr "%{pageTitle} を作æˆ"
msgid "WikiPageEdit|Update %{pageTitle}"
-msgstr ""
+msgstr "%{pageTitle} ã‚’æ›´æ–°"
msgid "WikiPage|Write your content or drag files here…"
msgstr "ã“ã“ã«ãƒ†ã‚­ã‚¹ãƒˆã‚’記入ã™ã‚‹ã‹ã€ãƒ•ã‚¡ã‚¤ãƒ«ã‚’ドラッグã—ã¦ãã ã•ã„。"
msgid "Wiki|Create New Page"
-msgstr ""
+msgstr "æ–°ã—ã„ページを作æˆ"
msgid "Wiki|Create page"
msgstr "ページを作æˆ"
@@ -23753,7 +25073,7 @@ msgid "Wiki|Page history"
msgstr "ページã®å±¥æ­´"
msgid "Wiki|Page title"
-msgstr ""
+msgstr "ページタイトル"
msgid "Wiki|Page version"
msgstr "ページã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³"
@@ -23770,11 +25090,14 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr "Wikiページ"
-msgid "Will deploy to"
+msgid "Will be created"
msgstr ""
-msgid "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 "貢献分æžã‚’使用ã™ã‚‹ã¨ã€ã‚ãªãŸã®çµ„ç¹”ã¨ãã®ãƒ¡ãƒ³ãƒã®èª²é¡Œã€ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆãŠã‚ˆã³ãƒ—ッシュイベントã®æ¦‚è¦ã‚’見るã“ã¨ãŒã§ãã¾ã™ã€‚"
+msgid "Will deploy to"
+msgstr "次ã®å ´æ‰€ã«ãƒ‡ãƒ—ロイã—ã¾ã™"
+
+msgid "With requirements, you can set criteria to check your products against."
+msgstr ""
msgid "Withdraw Access Request"
msgstr "アクセスリクエストをå–り消ã™"
@@ -23782,11 +25105,11 @@ msgstr "アクセスリクエストをå–り消ã™"
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
-msgstr "ワークフローã®ãƒ˜ãƒ«ãƒ—"
+msgid "Work in progress Limit"
+msgstr ""
msgid "Write"
msgstr ""
@@ -23795,7 +25118,7 @@ msgid "Write a comment or drag your files here…"
msgstr "コメントを書ãã‹ã€ã“ã“ã«ãƒ•ã‚¡ã‚¤ãƒ«ã‚’ドラッグ…"
msgid "Write a comment…"
-msgstr ""
+msgstr "コメントを書ã..."
msgid "Write access allowed"
msgstr "書ãè¾¼ã¿ã‚¢ã‚¯ã‚»ã‚¹ã‚’許å¯"
@@ -23804,7 +25127,7 @@ msgid "Write milestone description..."
msgstr "マイルストーンã®èª¬æ˜Žã‚’書ã..."
msgid "Write your release notes or drag your files here…"
-msgstr ""
+msgstr "リリースノートを書ãã‹ã€ã“ã“ã«ãƒ•ã‚¡ã‚¤ãƒ«ã‚’ドラッグ"
msgid "Wrong extern UID provided. Make sure Auth0 is configured correctly."
msgstr "é–“é•ã£ãŸå¤–部UIDãŒæŒ‡å®šã•ã‚Œã¾ã—ãŸã€‚ Auth0ãŒæ­£ã—ã設定ã•ã‚Œã¦ã„ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。"
@@ -23819,7 +25142,7 @@ msgid "Yes, add it"
msgstr "ã¯ã„ã€è¿½åŠ ã—ã¾ã™"
msgid "Yes, close issue"
-msgstr ""
+msgstr "ã¯ã„ã€èª²é¡Œã‚’é–‰ã˜ã¾ã™"
msgid "Yes, let me map Google Code users to full names or GitLab users."
msgstr "ã¯ã„ã€Googleコードã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’フルãƒãƒ¼ãƒ ã¾ãŸã¯GitLab ユーザーã«å¯¾å¿œã•ã›ã¦ãã ã•ã„。"
@@ -23846,7 +25169,7 @@ msgid "You are attempting to update a file that has changed since you started ed
msgstr "編集ã—ãŸãƒ•ã‚¡ã‚¤ãƒ«ã‚’æ›´æ–°ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚"
msgid "You are connected to the Prometheus server, but there is currently no data to display."
-msgstr ""
+msgstr "Prometheusサーãƒãƒ¼ã«æŽ¥ç¶šã§ãã¾ã—ãŸãŒã€ç¾åœ¨è¡¨ç¤ºã§ãるデータã¯ã‚ã‚Šã¾ã›ã‚“。"
msgid "You are going to remove %{group_name}, this will also remove all of its subgroups and projects. Removed groups CANNOT be restored! Are you ABSOLUTELY sure?"
msgstr "%{group_name} を削除ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚ã“ã‚Œã¯ã€ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—é…下ã®ã‚µãƒ–グループã¨ãƒ—ロジェクトもã™ã¹ã¦å‰Šé™¤ã•ã‚Œã¾ã™ã€‚一度削除ã•ã‚ŒãŸã‚°ãƒ«ãƒ¼ãƒ—を復元ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。本当ã«ã‚ˆã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
@@ -23855,7 +25178,7 @@ msgid "You are going to remove %{project_full_name}. Removed project CANNOT be r
msgstr "%{project_full_name} プロジェクトを削除ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚削除ã•ã‚ŒãŸãƒ—ロジェクトã¯çµ¶å¯¾ã«å…ƒã«ã¯æˆ»ã›ã¾ã›ã‚“ï¼æœ¬å½“ã«ã‚ˆã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
msgid "You are going to remove the fork relationship from %{project_full_name}. Are you ABSOLUTELY sure?"
-msgstr ""
+msgstr "%{project_full_name} プロジェクトã¨ã®ãƒ•ã‚©ãƒ¼ã‚¯ã®é–¢ä¿‚を削除ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚本当ã«ã‚ˆã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
msgid "You are going to transfer %{project_full_name} to another owner. Are you ABSOLUTELY sure?"
msgstr "%{project_full_name} を別ã®ã‚ªãƒ¼ãƒŠãƒ¼ã«å§”è­²ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚本当ã«ã‚ˆã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
@@ -23864,13 +25187,13 @@ msgid "You are not allowed to push into this branch. Create another branch or op
msgstr ""
msgid "You are not allowed to unlink your primary login account"
-msgstr ""
+msgstr "プライマリログインアカウントã®ãƒªãƒ³ã‚¯ã‚’解除ã™ã‚‹ã“ã¨ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
msgid "You are not authorized to perform this action"
-msgstr ""
+msgstr "ã“ã®æ“作を実行ã™ã‚‹æ¨©é™ã‚’ã‚‚ã£ã¦ã„ã¾ã›ã‚“。"
msgid "You are now impersonating %{username}"
-msgstr ""
+msgstr "ã‚ãªãŸã¯ %{username} アカウントを代用ã—ã¦ã„ã¾ã™ã€‚"
msgid "You are on a read-only GitLab instance."
msgstr "読ã¿å–り専用 GitLab インスタンスをå‚照中ã§ã™ã€‚"
@@ -23902,23 +25225,26 @@ msgstr "%{lint_link_start}CI Lint%{lint_link_end}㧠%{gitlab_ci_yml} をテスã
msgid "You can also upload existing files from your computer using the instructions below."
msgstr "以下ã®æ‰‹é †ã«ãã£ã¦ã€ã‚ãªãŸã®ã‚³ãƒ³ãƒ”ューター上ã®æ—¢å­˜ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’アップロードã§ãã¾ã™ã€‚"
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
msgid "You can apply your Trial to your Personal account or create a New Group."
-msgstr ""
+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 "%{pat_link_start}パーソナルアクセストークン%{pat_link_end} ã®è¨­å®šã§æ–°ã—ã„ã‚‚ã®ã‚’作æˆã§ãã€ã¾ãŸã€ç¢ºèªã§ãã¾ã™"
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 ""
+msgstr "%{pat_link_start}パーソナルアクセストークン%{pat_link_end} ã®è¨­å®šã§æ–°ã—ã„ã‚‚ã®ã‚’作æˆã§ãã¾ã™"
msgid "You can create new ones at your Personal Access Tokens settings %{pat_link}"
-msgstr ""
+msgstr "パーソナルアクセストークンã®è¨­å®š%{pat_link} ã§æ–°ã—ã„ã‚‚ã®ã‚’作æˆã§ãã¾ã™"
msgid "You can easily contribute to them by requesting to join these groups."
msgstr "ã“れらã®ã‚°ãƒ«ãƒ¼ãƒ—ã¸ã®å‚加をリクエストã™ã‚‹ã“ã¨ã§ã€ç°¡å˜ã«è²¢çŒ®ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
@@ -23927,6 +25253,9 @@ msgid "You can easily install a Runner on a Kubernetes cluster. %{link_to_help_p
msgstr "Kubernetes クラスター㫠Runner ã‚’ç°¡å˜ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã§ãã¾ã™ã€‚%{link_to_help_page}"
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
+msgstr "グラフã®åˆ—をクリックã—ã¦ã€ãƒžãƒ¼ã‚¸æ—¥ã§ãƒ•ã‚£ãƒ«ã‚¿ãƒªãƒ³ã‚°ã§ãã¾ã™ã€‚"
+
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
msgstr ""
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
@@ -23944,14 +25273,17 @@ msgstr "ä»–ã®ã‚°ãƒ«ãƒ¼ãƒ—ã‚’<strong>%{project_name} </strong>ã«æ‹›å¾…ã§ãã¾
msgid "You can move around the graph by using the arrow keys."
msgstr "矢å°ã‚­ãƒ¼ã‚’使用ã—ã¦ã‚°ãƒ©ãƒ•ã‚’移動ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
msgid "You can now submit a merge request to get this change into the original branch."
-msgstr ""
+msgstr "ã“ã®å¤‰æ›´ã‚’å…ƒã®ãƒ–ランãƒã«å映ã•ã›ã‚‹ãŸã‚ã«ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’é€ä¿¡ã§ãるよã†ã«ãªã‚Šã¾ã—ãŸã€‚"
msgid "You can now submit a merge request to get this change into the original project."
-msgstr ""
+msgstr "ã“ã®å¤‰æ›´ã‚’å…ƒã®ãƒ—ロジェクトã«å映ã•ã›ã‚‹ãŸã‚ã«ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’é€ä¿¡ã§ãるよã†ã«ãªã‚Šã¾ã—ãŸã€‚"
msgid "You can only add files when you are on a branch"
msgstr "ファイルを追加ã™ã‚‹ã«ã¯ã€ã©ã“ã‹ã®ãƒ–ランãƒã«ã„ãªã‘ã‚Œã°ã„ã‘ã¾ã›ã‚“"
@@ -23960,10 +25292,10 @@ msgid "You can only edit files when you are on a branch"
msgstr "ファイルを編集ã™ã‚‹ã«ã¯ã€ã©ã“ã‹ã®ãƒ–ランãƒã«ã„ãªã‘ã‚Œã°ã„ã‘ã¾ã›ã‚“"
msgid "You can only merge once the items above are resolved."
-msgstr ""
+msgstr "上ã®é …ç›®ãŒè§£æ±ºã•ã‚ŒãŸå¾Œã«ã®ã¿ãƒžãƒ¼ã‚¸ã§ãã¾ã™."
msgid "You can only merge once this merge request is approved."
-msgstr ""
+msgstr "ã“ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆãŒæ‰¿èªã•ã‚ŒãŸå¾Œã«ã ã‘ã€ãƒžãƒ¼ã‚¸ãŒã§ãã¾ã™ã€‚"
msgid "You can only transfer the project to namespaces you manage."
msgstr "プロジェクトã¯è‡ªåˆ†ãŒç®¡ç†ã™ã‚‹åå‰ç©ºé–“ã«ã®ã¿è»¢é€ã§ãã¾ã™ã€‚"
@@ -23972,40 +25304,40 @@ msgid "You can only upload one design when dropping onto an existing design."
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 ""
+msgstr "対話モードã§ã¯ã€%{use_ours} ボタンã¾ãŸã¯%{use_theirs} ボタンã§ã®é¸æŠžã¨ã€ãã®ä»–ファイルã®ç›´æŽ¥ç·¨é›†ã§ç«¶åˆã‚’解決ã§ãã¾ã™ã€‚ãã‚Œã‹ã‚‰ã“れらã®å¤‰æ›´ã‚’ %{branch_name} ã«ã‚³ãƒŸãƒƒãƒˆã—ã¾ã™ã€‚"
msgid "You can see your chat accounts."
-msgstr ""
+msgstr "ãƒãƒ£ãƒƒãƒˆã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’見るã“ã¨ãŒã§ãã¾ã™"
msgid "You can set up as many Runners as you need to run your jobs."
-msgstr ""
+msgstr "ジョブを実行ã™ã‚‹ãŸã‚ã«å¿…è¦ãªæ•°ã®Runnerをセットアップã§ãã¾ã™ã€‚"
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 ""
+msgstr "グループã”ã¨ã¾ãŸã¯ãƒ—ロジェクトã”ã¨ã«é€šçŸ¥ãƒ¬ãƒ™ãƒ«ã‚’設定ã§ãã¾ã™ã€‚"
msgid "You can test your .gitlab-ci.yml in %{linkStart}CI Lint%{linkEnd}."
msgstr "%{linkStart} CI Lint %{linkEnd} ã§.gitlab-ci.ymlをテストã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
msgid "You can try again using %{begin_link}basic search%{end_link}"
-msgstr ""
+msgstr "%{begin_link} 検索 %{end_link} を使用ã—ã¦å†ã³å®Ÿè¡Œã§ãã¾ã™"
msgid "You cannot access the raw file. Please wait a minute."
-msgstr ""
+msgstr "ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã«ç›´æŽ¥ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“。ã—ã°ã‚‰ããŠå¾…ã¡ãã ã•ã„。"
msgid "You cannot impersonate a blocked user"
-msgstr ""
+msgstr "ブロックã•ã‚ŒãŸãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’代用ã§ãã¾ã›ã‚“"
msgid "You cannot impersonate a user who cannot log in"
-msgstr ""
+msgstr "ログインã§ããªã„ユーザーを代用ã§ãã¾ã›ã‚“"
msgid "You cannot impersonate an internal user"
-msgstr ""
+msgstr "内部ユーザーを代用ã§ãã¾ã›ã‚“"
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
-msgstr ""
+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} を使用ã—ã¦ãã ã•ã„。"
@@ -24017,16 +25349,19 @@ msgid "You could not create a new trigger."
msgstr "æ–°ã—ã„トリガーを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} so it was downgraded to the free plan."
-msgstr ""
+msgstr "ã‚ãªãŸã¯%{strong}%{namespace_name}%{strong_close}ã¸ã®%{strong}%{plan_name}%{strong_close}サブスクリプションを更新ã—ã¾ã›ã‚“ã§ã—ãŸã€‚ãã®ãŸã‚ã€å½“サブスクリプションã¯ç„¡æ–™ãƒ—ランã«ãƒ€ã‚¦ãƒ³ã‚°ãƒ¬ãƒ¼ãƒ‰ã•ã‚Œã¾ã—ãŸã€‚"
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr "ã‚ãªãŸã«ã¯ã‚µãƒ–スクリプションãŒã‚ã‚Šã¾ã›ã‚“"
msgid "You do not have permission to leave this %{namespaceType}."
-msgstr ""
+msgstr "ã‚ãªãŸã¯ã“ã® %{namespaceType} を離れる許å¯ã‚’å¾—ã¦ã„ã¾ã›ã‚“。"
msgid "You do not have permission to run the Web Terminal. Please contact a project administrator."
msgstr "Web ターミナルを実行ã™ã‚‹æ¨©é™ãŒã‚ã‚Šã¾ã›ã‚“。プロジェクト管ç†è€…ã«é€£çµ¡ã—ã¦ãã ã•ã„。"
@@ -24038,10 +25373,10 @@ msgid "You do not have the correct permissions to override the settings from the
msgstr "LDAP グループã®åŒæœŸã®è¨­å®šã‚’上書ãã™ã‚‹ãŸã‚ã®é©åˆ‡ãªæ¨©é™ãŒã‚ã‚Šã¾ã›ã‚“。"
msgid "You don't have any U2F devices registered yet."
-msgstr ""
+msgstr "ã‚ãªãŸã¯ã¾ã 2è¦ç´ èªè¨¼ãƒ‡ãƒã‚¤ã‚¹ã‚’登録ã—ã¦ã„ã¾ã›ã‚“。"
msgid "You don't have any active chat names."
-msgstr ""
+msgstr "アクティブãªãƒãƒ£ãƒƒãƒˆåãŒã‚ã‚Šã¾ã›ã‚“。"
msgid "You don't have any applications"
msgstr "アプリケーションãŒã‚ã‚Šã¾ã›ã‚“"
@@ -24056,18 +25391,21 @@ msgid "You don't have any open merge requests"
msgstr ""
msgid "You don't have any projects available."
-msgstr ""
+msgstr "利用å¯èƒ½ãªãƒ—ロジェクトã¯ã¾ã ã‚ã‚Šã¾ã›ã‚“"
msgid "You don't have any recent searches"
-msgstr ""
+msgstr "最近ã®æ¤œç´¢ãŒã‚ã‚Šã¾ã›ã‚“。"
msgid "You don't have sufficient permission to perform this action."
-msgstr ""
+msgstr "ã“ã®ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã‚’実行ã™ã‚‹ãŸã‚ã®å分ãªæ¨©é™ãŒã‚ã‚Šã¾ã›ã‚“"
msgid "You don’t have access to Productivity Analytics in this group"
-msgstr ""
+msgstr "ã‚ãªãŸã¯ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã®ç”Ÿç”£æ€§åˆ†æžã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“"
msgid "You don’t have access to Value Stream Analytics for this group"
+msgstr "ã‚ãªãŸã¯ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã®ãƒãƒªãƒ¥ãƒ¼ã‚¹ãƒˆãƒªãƒ¼ãƒ åˆ†æžã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹æ¨©é™ãŒã‚ã‚Šã¾ã›ã‚“。"
+
+msgid "You have a license that activates at a future date. Please see the License History table below."
msgstr ""
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
@@ -24085,7 +25423,7 @@ msgstr "ã‚ãªãŸã¯ã“ã®ã‚¹ãƒ¬ãƒƒãƒ‰ã‹ã‚‰è„±é€€ã—ã¾ã—ãŸã€‚"
msgid "You have declined the invitation to join %{label}."
msgstr "%{label} ã¸ã®å‚加ã®æ‹›å¾…を辞退ã—ã¾ã—ãŸã€‚"
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24101,19 +25439,19 @@ msgid "You have successfully purchased a %{plan} plan subscription for %{seats}.
msgstr ""
msgid "You haven't added any issues to your project yet"
-msgstr ""
+msgstr "ã‚ãªãŸã¯ã¾ã ãƒ—ロジェクトã«èª²é¡Œã‚’追加ã—ã¦ã„ã¾ã›ã‚“"
msgid "You haven't selected any issues yet"
-msgstr ""
+msgstr "ã‚ãªãŸã¯ã¾ã èª²é¡Œã‚’é¸æŠžã—ã¦ã„ã¾ã›ã‚“。"
msgid "You left the \"%{membershipable_human_name}\" %{source_type}."
-msgstr ""
+msgstr "ã‚ãªãŸã¯ \"%{membershipable_human_name}\"%{source_type} を残ã—ã¾ã—ãŸã€‚"
msgid "You may also add variables that are made available to the running application by prepending the variable key with <code>K8S_SECRET_</code>."
msgstr "変数åã®å‰ã« <code>K8S_SECRET_</code>を指定ã™ã‚‹ã“ã¨ã§ã€å®Ÿè¡Œä¸­ã®ã‚¢ãƒ—リケーションã§ä½¿ç”¨ã™ã‚‹å¤‰æ•°ã‚’追加ã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚"
msgid "You may close the milestone now."
-msgstr ""
+msgstr "マイルストーンを終了ã§ãã¾ã™ã€‚"
msgid "You must accept our Terms of Service and privacy policy in order to register an account"
msgstr "アカウントを登録ã™ã‚‹ã«ã¯ã€åˆ©ç”¨è¦ç´„ã¨ãƒ—ライãƒã‚·ãƒ¼ãƒãƒªã‚·ãƒ¼ã«åŒæ„ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™"
@@ -24137,7 +25475,7 @@ msgid "You must select a stack for configuring your cloud provider. Learn more a
msgstr ""
msgid "You must set up incoming email before it becomes active."
-msgstr ""
+msgstr "アクティブã«ãªã‚‹å‰ã«ã€ãƒ¡ãƒ¼ãƒ«å—ä¿¡ã®è¨­å®šã‚’ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "You must upload a file with the same file name when dropping onto an existing design."
msgstr ""
@@ -24178,6 +25516,9 @@ msgstr "%{link_to_the_project} ã®ãƒ•ã‚©ãƒ¼ã‚¯ã¯ã€æ¬¡ã®ç†ç”±ã§å¤±æ•—ã—ã¾ã
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24205,6 +25546,9 @@ msgstr "å…¨ã¦ã®ã‚¢ã‚¯ãƒ†ã‚£ãƒ“ティーを通知ã—ã¾ã™"
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr "ã‚ãªãŸãŒ @mentioned ã§ã‚³ãƒ¡ãƒ³ãƒˆã•ã‚ŒãŸæ™‚ã®ã¿é€šçŸ¥ã—ã¾ã™"
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr "%{set_password_link} ã§ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®ãƒ‘スワードãŒã‚»ãƒƒãƒˆã•ã‚Œã¦ã„ãªã„ã®ã§ã€ãƒ—ロジェクト㫠%{protocol} ã§ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã‚’プッシュã€ãƒ—ルã§ãã¾ã›ã‚“"
@@ -24221,11 +25565,17 @@ msgid "You're about to reduce the visibility of the project %{strong_start}%{pro
msgstr "%{strong_start}%{group_name}%{strong_end} 内ã®%{strong_start}%{project_name}%{strong_end} プロジェクトã®å…¬é–‹ç¯„囲を低下ã•ã›ã‚ˆã†ã¨ã—ã¦ã„ã¾ã™ã€‚"
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
+msgstr "%{strong_start}%{project_name}%{strong_end} プロジェクトã®å…¬é–‹ç¯„囲を狭ã‚よã†ã¨ã—ã¦ã„ã¾ã™ã€‚"
+
+msgid "You're at the first 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."
+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 "ã‚ãªãŸã¯ã“ã®ãƒ—ロジェクト内ã®ãƒ•ã‚¡ã‚¤ãƒ«ã®ç›´æŽ¥çš„㪠%{tag_start} 編集 %{tag_end} を許å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“。ã“ã®ãƒ—ロジェクトをフォークã—ã€ãã“ã§å¤‰æ›´ã‚’è¡Œã„ã€ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’é€ä¿¡ã—ã¦ãã ã•ã„。"
+
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 "ã“ã®ãƒ—ロジェクトを直接変更ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。変更を加ãˆã‚‹ã“ã¨ãŒã§ãるプロジェクトã®ãƒ•ã‚©ãƒ¼ã‚¯ãŒä½œæˆã•ã‚ŒãŸã®ã§ã€ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’é€ä¿¡ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
@@ -24242,28 +25592,31 @@ msgid "You're receiving this email because of your account on %{host}. %{manage_
msgstr "ã“ã®ãƒ¡ãƒ¼ãƒ«ã¯ %{host} ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆå®›ã«é€ä¿¡ã•ã‚Œã¾ã—ãŸã€‚ %{manage_notifications_link}&middot;%{help_link}"
msgid "You're receiving this email because of your activity on %{host}."
-msgstr ""
+msgstr "%{host} ã§ã®ã‚¢ã‚¯ãƒ†ã‚£ãƒ“ティーã®ãŸã‚ã€ã“ã®ãƒ¡ãƒ¼ãƒ«ã‚’å—ä¿¡ã—ã¦ã„ã¾ã™ã€‚"
msgid "You're receiving this email because you have been assigned an item on %{host}."
-msgstr ""
+msgstr "%{host} ã§ã®ã‚ãªãŸã¸ã®ã‚¢ã‚¤ãƒ†ãƒ å‰²ã‚Šå½“ã¦ã®ãŸã‚ã€ã“ã®ãƒ¡ãƒ¼ãƒ«ã‚’å—ä¿¡ã—ã¦ã„ã¾ã™ã€‚"
msgid "You're receiving this email because you have been mentioned on %{host}."
-msgstr ""
+msgstr "%{host} ã«ã¦ã‚ãªãŸãŒè¨€åŠã•ã‚ŒãŸãŸã‚ã€ã“ã®ãƒ¡ãƒ¼ãƒ«ã‚’å—ä¿¡ã—ã¦ã„ã¾ã™ã€‚"
msgid "You've already enabled two-factor authentication using one time password authenticators. In order to register a different device, you must first disable two-factor authentication."
-msgstr ""
+msgstr "ワンタイムパスワードèªè¨¼ã‚’使用ã—ãŸ2è¦ç´ èªè¨¼ã¯æ—¢ã«æœ‰åŠ¹ã«ãªã£ã¦ã„ã¾ã™ã€‚別ã®ãƒ‡ãƒã‚¤ã‚¹ã‚’登録ã™ã‚‹ã«ã¯ã€ã¾ãš2è¦ç´ èªè¨¼ã‚’無効ã«ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "YouTube"
msgstr "YouTube"
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
msgstr ""
msgid "Your CSV export has started. It will be emailed to %{email} when complete."
-msgstr ""
+msgstr "CSV エクスãƒãƒ¼ãƒˆã‚’開始ã—ã¾ã—ãŸã€‚完了後ã«ã€%{email} ã«ãƒ¡ãƒ¼ãƒ«ã§é€ä¿¡ã—ã¾ã™ã€‚"
msgid "Your CSV export of %{issues_count} from project %{project_link} has been added to this email as an attachment."
msgstr ""
@@ -24272,13 +25625,13 @@ msgid "Your CSV export of %{written_count} from project %{project_name} (%{proje
msgstr ""
msgid "Your Commit Email will be used for web based operations, such as edits and merges."
-msgstr ""
+msgstr "ã“ã®ã‚³ãƒŸãƒƒãƒˆãƒ¡ãƒ¼ãƒ«ã¯ã€ç·¨é›†ã‚„マージãªã©ã®Webベースã®æ“作ã«ä½¿ç”¨ã—ã¾ã™ã€‚"
msgid "Your Default Notification Email will be used for account notifications if a %{openingTag}group-specific email address%{closingTag} is not set."
-msgstr ""
+msgstr "%{openingTag}グループã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹%{closingTag} ãŒè¨­å®šã•ã‚Œã¦ã„ãªã„å ´åˆã€ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®é€šçŸ¥ãƒ¡ãƒ¼ãƒ«ã‚’アカウントã®é€šçŸ¥ã«ä½¿ç”¨ã—ã¾ã™ã€‚"
msgid "Your DevOps Score gives an overview of how you are using GitLab from a feature perspective. View how you compare with other organizations, discover features you are not using, and learn best practices through blog posts and white papers."
-msgstr ""
+msgstr "DevOps Scoreã«ã¯ã€æ©Ÿèƒ½ã®è¦³ç‚¹ã‹ã‚‰ GitLab ã‚’ã©ã®ã‚ˆã†ã«ä½¿ç”¨ã—ã¦ã„ã‚‹ã‹ã®æ¦‚è¦ãŒè¨˜è¼‰ã•ã‚Œã¦ã„ã¾ã™ã€‚ä»–ã®çµ„ç¹”ã¨ã®æ¯”較ã€ä½¿ç”¨ã—ã¦ã„ãªã„機能ã®ç™ºè¦‹ã€ãƒ–ログã®æŠ•ç¨¿ã‚„ホワイトペーパーを通ã˜ã¦ãƒ™ã‚¹ãƒˆãƒ—ラクティスを学ã¶ã“ã¨ãŒã§ãã¾ã™ã€‚"
msgid "Your GPG keys (%{count})"
msgstr "GPG éµ (%{count})"
@@ -24292,14 +25645,14 @@ msgstr ""
msgid "Your Groups"
msgstr "所属グループ"
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
-msgstr ""
+msgstr "パーソナルアクセストークン㯠%{days_to_expire} æ—¥ã§æœŸé™ãŒåˆ‡ã‚Œã¾ã™"
msgid "Your Primary Email will be used for avatar detection."
-msgstr ""
+msgstr "メインã®ãƒ¡ãƒ¼ãƒ«ã¯ã‚¢ãƒã‚¿ãƒ¼ã®æ¤œå‡ºã«ä½¿ç”¨ã•ã‚Œã¾ã™ã€‚"
msgid "Your Projects (default)"
msgstr "プロジェクト(デフォルト)"
@@ -24308,13 +25661,13 @@ msgid "Your Projects' Activity"
msgstr "プロジェクトã®æ´»å‹•"
msgid "Your Public Email will be displayed on your public profile."
-msgstr ""
+msgstr "公開メールをã‚ãªãŸã®å…¬é–‹ãƒ—ロフィールã«è¡¨ç¤ºã—ã¾ã™ã€‚"
msgid "Your SSH keys (%{count})"
msgstr "SSH éµ (%{count})"
msgid "Your To-Do List"
-msgstr ""
+msgstr "ã‚ãªãŸã®To Doリスト"
msgid "Your U2F device did not send a valid JSON response."
msgstr "ã‚ãªãŸã®U2Fデãƒã‚¤ã‚¹ã¯ã€æœ‰åŠ¹ãªJSON応答をé€ä¿¡ã—ã¾ã›ã‚“ã§ã—ãŸã€‚"
@@ -24329,10 +25682,10 @@ msgid "Your access request to the %{source_type} has been withdrawn."
msgstr "%{source_type} ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹è¦æ±‚ã¯å–り消ã•ã‚Œã¾ã—ãŸã€‚"
msgid "Your account has been deactivated by your administrator. Please log back in to reactivate your account."
-msgstr ""
+msgstr "ã“ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¯ç®¡ç†è€…ã«ã‚ˆã‚Šç„¡åŠ¹ã«ã•ã‚Œã¾ã—ãŸã€‚å†åº¦ãƒ­ã‚°ã‚¤ãƒ³ã—ã¦ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’有効ã«ã—ã¦ãã ã•ã„。"
msgid "Your account is locked."
-msgstr ""
+msgstr "ã‚ãªãŸã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒãƒ­ãƒƒã‚¯ã•ã‚Œã¾ã—ãŸã€‚"
msgid "Your account uses dedicated credentials for the \"%{group_name}\" group and can only be updated through SSO."
msgstr "ã‚ãªãŸã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¯ \"%{group_name}\"グループã«å°‚用ã®èªè¨¼æƒ…報を使用ã—ã¦ãŠã‚Šã€SSOを通ã˜ã¦ã®ã¿æ›´æ–°ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
@@ -24344,7 +25697,7 @@ msgid "Your authorized applications"
msgstr "承èªã•ã‚ŒãŸã‚¢ãƒ—リケーション"
msgid "Your browser doesn't support U2F. Please use Google Chrome desktop (version 41 or newer)."
-msgstr ""
+msgstr "ã‚ãªãŸã®ãƒ–ラウザã¯U2Fをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。 Google Chromeデスクトップ (ãƒãƒ¼ã‚¸ãƒ§ãƒ³41以é™) を使用ã—ã¦ãã ã•ã„。"
msgid "Your changes can be committed to %{branch_name} because a merge request is open."
msgstr "マージリクエストãŒé–‹ã„ã¦ã„ã‚‹ãŸã‚ã€å¤‰æ›´ã¯ %{branch_name} ã«ã‚³ãƒŸãƒƒãƒˆã§ãã¾ã™ã€‚"
@@ -24353,22 +25706,22 @@ msgid "Your changes have been committed. Commit %{commitId} %{commitStats}"
msgstr "ã™ã§ã«å¤‰æ›´ã‚’コミット済ã¿ã§ã™ã€‚コミット %{commitId} %{commitStats} "
msgid "Your changes have been saved"
-msgstr ""
+msgstr "変更ãŒä¿å­˜ã•ã‚Œã¾ã—ãŸã€‚"
msgid "Your changes have been successfully committed."
-msgstr ""
+msgstr "変更ã¯æ­£å¸¸ã«ã‚³ãƒŸãƒƒãƒˆã•ã‚Œã¾ã—ãŸã€‚"
msgid "Your comment could not be submitted because %{error}"
-msgstr ""
+msgstr "コメントをé€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚: %{error}"
msgid "Your comment could not be submitted! Please check your network connection and try again."
-msgstr ""
+msgstr "ã‚ãªãŸã®ã‚³ãƒ¡ãƒ³ãƒˆã¯é€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯æŽ¥ç¶šã‚’確èªã—ã¦ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
msgid "Your comment could not be updated! Please check your network connection and try again."
-msgstr ""
+msgstr "ã‚ãªãŸã®ã‚³ãƒ¡ãƒ³ãƒˆã¯æ›´æ–°ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯æŽ¥ç¶šã‚’確èªã—ã¦ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
msgid "Your comment will be discarded."
-msgstr ""
+msgstr "コメントã¯ç ´æ£„ã•ã‚Œã¾ã™ã€‚"
msgid "Your custom stage '%{title}' was created"
msgstr ""
@@ -24380,46 +25733,61 @@ msgid "Your dashboard has been updated. You can %{web_ide_link_start}edit it her
msgstr ""
msgid "Your deployment services will be broken, you will need to manually fix the services after renaming."
-msgstr ""
+msgstr "デプロイサービスãŒå£Šã‚Œã‚‹ã“ã¨ãŒã‚ã‚Šã¾ã™ã€‚åå‰ã‚’変更ã—ãŸå¾Œã§æ‰‹å‹•ã§ã‚µãƒ¼ãƒ“スを修正ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
+msgstr "ã‚ãªãŸã®ãƒ‡ãƒã‚¤ã‚¹ã¯æ­£å¸¸ã«è¨­å®šã•ã‚Œã¾ã—ãŸã€‚åå‰ã‚’付ã‘ã¦GitLabサーãƒãƒ¼ã«ç™»éŒ²ã—ã¾ã™ã€‚"
+
+msgid "Your first project"
msgstr ""
msgid "Your groups"
msgstr "所属グループ"
-msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
+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 ""
-msgid "Your issues will be imported in the background. Once finished, you'll get a confirmation email."
+msgid "Your instance is approaching its licensed user count"
msgstr ""
+msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
+msgstr "ã‚ãªãŸã®èª²é¡Œã‚’インãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã™ã€‚終了ã™ã‚‹ã¨ã€ç¢ºèªãƒ¡ãƒ¼ãƒ«ãŒå±Šãã¾ã™ã€‚"
+
+msgid "Your issues will be imported in the background. Once finished, you'll get a confirmation email."
+msgstr "ã‚ãªãŸã®èª²é¡Œã‚’ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰å‡¦ç†ã§ã‚¤ãƒ³ãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã™ã€‚終了ã™ã‚‹ã¨ã€ç¢ºèªãƒ¡ãƒ¼ãƒ«ãŒå±Šãã¾ã™ã€‚"
+
msgid "Your license is valid from"
msgstr ""
-msgid "Your message here"
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
msgstr ""
+msgid "Your message here"
+msgstr "メッセージを入力ã—ã¦ãã ã•ã„。"
+
msgid "Your name"
msgstr "åå‰"
-msgid "Your new SCIM token"
+msgid "Your new %{type}"
msgstr ""
+msgid "Your new SCIM token"
+msgstr "æ–°ã—ã„ SCIM トークン"
+
msgid "Your new personal access token has been created."
msgstr "æ–°ã—ã„パーソナルアクセストークンãŒä½œæˆã•ã‚Œã¾ã—ãŸã€‚"
msgid "Your new project access token has been created."
-msgstr ""
+msgstr "æ–°ã—ã„プロジェクトã®ã‚¢ã‚¯ã‚»ã‚¹ãƒˆãƒ¼ã‚¯ãƒ³ãŒä½œæˆã•ã‚Œã¾ã—ãŸã€‚"
msgid "Your password isn't required to view this page. If a password or any other personal details are requested, please contact your administrator to report abuse."
-msgstr ""
+msgstr "ã“ã®ãƒšãƒ¼ã‚¸ã®è¡¨ç¤ºã«ãƒ‘スワードã¯æ±‚ã‚られã¦ã„ã¾ã›ã‚“。ã“ã®ãƒšãƒ¼ã‚¸ã«ãƒ‘スワードã¾ãŸã¯ãã®ä»–ã®æƒ…報を有効ã«ã™ã‚‹å ´åˆã€ç®¡ç†è€…ã«é€£çµ¡ã—ã¦ãã ã•ã„。"
msgid "Your password reset token has expired."
msgstr "パスワードリセットトークンã¯æœ‰åŠ¹æœŸé™åˆ‡ã‚Œã§ã™ã€‚"
msgid "Your profile"
-msgstr ""
+msgstr "ã‚ãªãŸã®ãƒ—ロフィール"
msgid "Your project limit is %{limit} projects! Please contact your administrator to increase it"
msgstr "ã‚ãªãŸã®ãƒ—ロジェクト数㯠%{limit} 以下ã«åˆ¶é™ã•ã‚Œã¦ã„ã¾ã™ã€‚ã“ã®ä¸Šé™ã‚’増やã™ã«ã¯ã‚ãªãŸã®ç®¡ç†è€…ã«é€£çµ¡ã—ã¦ãã ã•ã„"
@@ -24427,20 +25795,26 @@ msgstr "ã‚ãªãŸã®ãƒ—ロジェクト数㯠%{limit} 以下ã«åˆ¶é™ã•ã‚Œã¦ã
msgid "Your projects"
msgstr "ã‚ãªãŸã®ãƒ—ロジェクト"
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr "アクセスã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆã¯å¯©æŸ»å¾…ã¡ã§ã™ã€‚"
-msgid "Your search didn't match any commits."
+msgid "Your response has been recorded."
msgstr ""
+msgid "Your search didn't match any commits."
+msgstr "ã©ã®ã‚³ãƒŸãƒƒãƒˆã«ã‚‚一致ã—ã¾ã›ã‚“ã§ã—ãŸã€‚"
+
msgid "Your subscription expired!"
-msgstr ""
+msgstr "サブスクリプションã®æœ‰åŠ¹æœŸé™ãŒåˆ‡ã‚Œã¾ã—ãŸï¼"
msgid "Your subscription has been downgraded"
msgstr "サブスクリプションã®ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã‚’完了ã—ã¾ã—ãŸã€‚"
msgid "Your subscription will automatically renew in %{remaining_days}"
-msgstr ""
+msgstr "ã‚ãªãŸã®ã‚µãƒ–スクリプションã¯å¾Œ%{remaining_days}ã§è‡ªå‹•çš„ã«æ›´æ–°ã•ã‚Œã¾ã™ã€‚"
msgid "Your subscription will expire in %{remaining_days}"
msgstr ""
@@ -24452,30 +25826,33 @@ msgid "Zoom meeting removed"
msgstr "Zoom ミーティングを削除ã—ã¾ã—ãŸ"
msgid "[No reason]"
-msgstr ""
+msgstr "[ç†ç”±ã¯ã‚ã‚Šã¾ã›ã‚“]"
msgid "a deleted user"
msgstr "削除ã•ã‚ŒãŸãƒ¦ãƒ¼ã‚¶ãƒ¼"
msgid "a design"
-msgstr ""
+msgstr "デザイン"
msgid "about 1 hour"
msgid_plural "about %d hours"
-msgstr[0] ""
+msgstr[0] "約 %d 時間"
msgid "activated"
msgstr ""
msgid "added %{created_at_timeago}"
-msgstr ""
+msgstr "%{created_at_timeago} を追加ã—ã¾ã—ãŸ"
msgid "added a Zoom call to this issue"
-msgstr ""
+msgstr "ã“ã®èª²é¡Œã«ã‚ºãƒ¼ãƒ ã‚³ãƒ¼ãƒ«ã‚’追加ã—ã¾ã—ãŸ"
msgid "ago"
msgstr "å‰"
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr "失敗å¯èƒ½"
@@ -24518,9 +25895,12 @@ msgstr ""
msgid "branch name"
msgstr "ブランãƒå"
-msgid "by"
+msgid "build pipeline reference mismatch"
msgstr ""
+msgid "by"
+msgstr "by"
+
msgid "by %{user}"
msgstr ""
@@ -24568,62 +25948,62 @@ msgstr "他 %{remainingPackagesCount} 件"
msgid "ciReport|%{reportType} %{status} detected %{dismissedCount} dismissed vulnerability"
msgid_plural "ciReport|%{reportType} %{status} detected %{dismissedCount} dismissed vulnerabilities"
-msgstr[0] ""
+msgstr[0] "%{reportType} %{status} 㯠%{dismissedCount} 件ã®ç„¡è¦–ã•ã‚ŒãŸè„†å¼±æ€§ã‚’検出ã—ã¾ã—ãŸ"
msgid "ciReport|%{reportType} %{status} detected %{dismissedCount} dismissed vulnerability for the source branch only"
msgid_plural "ciReport|%{reportType} %{status} detected %{dismissedCount} dismissed vulnerabilities for the source branch only"
-msgstr[0] ""
+msgstr[0] "%{reportType}%{status} ã¯ã‚½ãƒ¼ã‚¹ãƒ–ランãƒã«ã®ã¿%{dismissedCount} 件ã®ç„¡è¦–ã•ã‚ŒãŸè„†å¼±æ€§ã‚’検出ã—ã¾ã—ãŸ"
msgid "ciReport|%{reportType} %{status} detected %{fixedCount} fixed vulnerability"
msgid_plural "ciReport|%{reportType} %{status} detected %{fixedCount} fixed vulnerabilities"
-msgstr[0] ""
+msgstr[0] "%{reportType} %{status} ã¯%{fixedCount} 件ã®ä¿®æ­£ã•ã‚ŒãŸè„†å¼±æ€§ã‚’検出ã—ã¾ã—ãŸ"
msgid "ciReport|%{reportType} %{status} detected %{fixedCount} fixed, and %{dismissedCount} dismissed vulnerabilities"
-msgstr ""
+msgstr "%{reportType}%{status} ã¯%{fixedCount} 件ã®ä¿®æ­£ã¨%{dismissedCount} 件ã®ç„¡è¦–ã•ã‚ŒãŸè„†å¼±æ€§ã‚’検出ã—ã¾ã—ãŸ"
msgid "ciReport|%{reportType} %{status} detected %{newCount} new vulnerability"
msgid_plural "ciReport|%{reportType} %{status} detected %{newCount} new vulnerabilities"
-msgstr[0] ""
+msgstr[0] "%{reportType} %{status} ã¯æ–°ãŸã« %{newCount} 件ã®è„†å¼±æ€§ã‚’検出ã—ã¾ã—ãŸ"
msgid "ciReport|%{reportType} %{status} detected %{newCount} new, %{fixedCount} fixed, and %{dismissedCount} dismissed vulnerabilities"
-msgstr ""
+msgstr "%{reportType}%{status} ã¯æ–°ãŸã«%{newCount} 件ã®è„†å¼±æ€§ã€ãŠã‚ˆã³%{fixedCount} 件ã®ä¿®æ­£ã€%{dismissedCount} 件ã®ç„¡è¦–ã•ã‚ŒãŸè„†å¼±æ€§ã‚’検出ã—ã¾ã—ãŸ"
msgid "ciReport|%{reportType} %{status} detected %{newCount} new, and %{dismissedCount} dismissed vulnerabilities"
-msgstr ""
+msgstr "%{reportType}%{status} ã¯æ–°ãŸã«%{newCount} 件ã®è„†å¼±æ€§ãŒã€%{dismissedCount} 件ã®è„†å¼±æ€§ãŒå´ä¸‹ã•ã‚Œã¾ã—ãŸã€‚"
msgid "ciReport|%{reportType} %{status} detected %{newCount} new, and %{dismissedCount} dismissed vulnerabilities for the source branch only"
-msgstr ""
+msgstr "%{reportType} %{status} ã¯ã‚½ãƒ¼ã‚¹ãƒ–ランãƒã«ã®ã¿ã€æ–°ãŸã«%{newCount} 件ã®è„†å¼±æ€§ã‚’検出ã—ã€%{dismissedCount} 件ã®ç„¡è¦–ã•ã‚ŒãŸè„†å¼±æ€§ãŒæ¤œå‡ºã•ã‚Œã¾ã—ãŸ"
msgid "ciReport|%{reportType} %{status} detected %{newCount} new, and %{fixedCount} fixed vulnerabilities"
-msgstr ""
+msgstr "%{reportType} %{status} ã§æ–°ãŸã«%{newCount} 件ã®è„†å¼±æ€§ã¨ã€ %{fixedCount} 件ã®ä¿®æ­£ã•ã‚ŒãŸè„†å¼±æ€§ã‚’検出ã•ã‚Œã¾ã—ãŸ"
msgid "ciReport|%{reportType} %{status} detected %{newCount} vulnerability for the source branch only"
msgid_plural "ciReport|%{reportType} %{status} detected %{newCount} vulnerabilities for the source branch only"
-msgstr[0] ""
+msgstr[0] "%{reportType} %{status} ã¯ã‚½ãƒ¼ã‚¹ãƒ–ランãƒã«ã®ã¿ã€ %{newCount} 件ã®è„†å¼±æ€§ã‚’検出ã—ã¾ã—ãŸ"
msgid "ciReport|%{reportType} %{status} detected no new vulnerabilities"
-msgstr ""
+msgstr "%{reportType} %{status} ã¯æ–°ã—ã„脆弱性を検出ã—ã¾ã›ã‚“ã§ã—ãŸ"
msgid "ciReport|%{reportType} %{status} detected no vulnerabilities"
-msgstr ""
+msgstr "%{reportType} %{status} ã¯è„†å¼±æ€§ã‚’検出ã—ã¾ã›ã‚“ã§ã—ãŸ"
msgid "ciReport|%{reportType} %{status} detected no vulnerabilities for the source branch only"
-msgstr ""
+msgstr "%{reportType} %{status} ã¯ã€ã‚½ãƒ¼ã‚¹ãƒ–ランãƒã«ã®ã¿è„†å¼±æ€§ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
msgid "ciReport|%{reportType} is loading"
-msgstr ""
+msgstr "%{reportType} を読ã¿è¾¼ã¿ä¸­"
msgid "ciReport|%{reportType}: Loading resulted in an error"
msgstr "%{reportType}:読ã¿è¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
msgid "ciReport|(errors when loading results)"
-msgstr ""
+msgstr "(çµæžœãƒ­ãƒ¼ãƒ‰æ™‚ã®ã‚¨ãƒ©ãƒ¼)"
msgid "ciReport|(is loading)"
-msgstr ""
+msgstr "(ロード中)"
msgid "ciReport|(is loading, errors when loading results)"
-msgstr ""
+msgstr "(ロード中ã€çµæžœãƒ­ãƒ¼ãƒ‰æ™‚ã®ã‚¨ãƒ©ãƒ¼)"
msgid "ciReport|All projects"
msgstr "ã™ã¹ã¦ã®ãƒ—ロジェクト"
@@ -24682,6 +26062,9 @@ msgstr "動的アプリケーションセキュリティテスト (DAST) ã¯ã€ã
msgid "ciReport|Failed to load %{reportName} report"
msgstr "%{reportName} レãƒãƒ¼ãƒˆã®èª­ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ"
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr "修正済ã¿:"
@@ -24700,6 +26083,9 @@ msgstr "%{reportName} レãƒãƒ¼ãƒˆã‚’読ã¿è¾¼ã‚“ã§ã„ã¾ã™"
msgid "ciReport|Manage licenses"
msgstr "ライセンスã®ç®¡ç†"
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr "コードå“質ã«å¤‰æ›´ã¯ã‚ã‚Šã¾ã›ã‚“"
@@ -24718,11 +26104,14 @@ msgstr "マージリクエストã§è§£æ±º"
msgid "ciReport|SAST"
msgstr "SAST"
-msgid "ciReport|Secret scanning"
+msgid "ciReport|Secret Detection"
msgstr ""
+msgid "ciReport|Secret scanning"
+msgstr "シークレットスキャン"
+
msgid "ciReport|Secret scanning detects secrets and credentials vulnerabilities in your source code."
-msgstr ""
+msgstr "シークレットスキャンã¯ã€ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã®ç§˜å¯†ã¨èªè¨¼æƒ…å ±ã®è„†å¼±æ€§ã‚’検出ã—ã¾ã™ã€‚"
msgid "ciReport|Security scanning"
msgstr "セキュリティスキャン"
@@ -24753,11 +26142,14 @@ msgstr "無視ã®å–り消ã—中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦
msgid "ciReport|Used by %{packagesString}"
msgid_plural "ciReport|Used by %{packagesString}, and %{lastPackage}"
-msgstr[0] ""
+msgstr[0] "%{packagesString}ã€%{lastPackage} ã«ä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "ciReport|View full report"
msgstr "レãƒãƒ¼ãƒˆå…¨ä½“を見る"
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr "コメント"
@@ -24767,6 +26159,9 @@ msgstr "%{link_to_project} ã«ã¤ã„ã¦ã‚³ãƒ¡ãƒ³ãƒˆã—ã¾ã—ãŸ"
msgid "commit %{commit_id}"
msgstr "コミット %{commit_id}"
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr "ã‚ãªãŸã¯å…¬é–‹è¨­å®šã«å¤‰æ›´ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚ã“ã‚Œã¯<strong>ã™ã¹ã¦ã®äºº</strong> ãŒé–²è¦§å¯èƒ½ã«ãªã‚Šã€èª²é¡Œã«å¯¾ã—ã¦ã‚³ãƒ¡ãƒ³ãƒˆã‚’残ã™ã“ã¨ãŒã§ãるよã†ã«ãªã‚‹ã“ã¨ã‚’æ„味ã—ã¾ã™ã€‚"
@@ -24776,6 +26171,9 @@ msgstr "ã‚ãªãŸã¯å…¬é–‹è¨­å®šã«å¤‰æ›´ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚ã“ã‚Œã¯
msgid "connecting"
msgstr "接続中"
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr "container_name ã« %{max_length} 以上ã®æ–‡å­—列を付与ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。"
@@ -24808,41 +26206,47 @@ msgid "deploy"
msgstr "デプロイ"
msgid "design"
-msgstr ""
+msgstr "デザイン"
msgid "designs"
-msgstr ""
+msgstr "デザイン"
msgid "detached"
-msgstr ""
+msgstr "デタッãƒ"
msgid "disabled"
msgstr "無効"
msgid "does not have a supported extension. Only %{extension_list} are supported"
-msgstr ""
+msgstr "サãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã‚‹æ‹¡å¼µå­ã§ã¯ã‚ã‚Šã¾ã›ã‚“。 %{extension_list} ã®æ‹¡å¼µå­ã ã‘ãŒã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã™"
msgid "done"
msgstr "完了"
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] "ドラフト"
msgid "e.g. %{token}"
-msgstr ""
+msgstr "例 %{token}"
msgid "element is not a hierarchy"
msgstr "è¦ç´ ã¯éšŽå±¤ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
-msgstr "メールアドレス %{email} 㯠許å¯ãƒ‰ãƒ¡ã‚¤ãƒ³ã® %{email_domain} ã¨ä¸€è‡´ã—ã¾ã›ã‚“"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
+msgstr ""
msgid "enabled"
msgstr "有効"
msgid "encrypted: needs to be a :required, :optional or :migrating!"
-msgstr ""
+msgstr "encrypted: 㯠:required, :optional, :migratingã®ã„ãšã‚Œã‹ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。"
msgid "entries cannot be larger than 255 characters"
msgstr "エントリーã¯255文字を超ãˆã‚‰ã‚Œã¾ã›ã‚“。"
@@ -24863,16 +26267,16 @@ msgid "estimateCommand|%{slash_command} will update the estimated time with the
msgstr "%{slash_command} コマンドã§è¦‹ç©æ™‚é–“ã‚’æ›´æ–°ã§ãã¾ã™ã€‚"
msgid "exceeds the limit of %{bytes} bytes"
-msgstr ""
+msgstr "ãƒã‚¤ãƒˆæ•°ã®åˆ¶é™ (%{bytes}) を超ãˆã¦ã„ã¾ã™"
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
-msgstr "%{milestone_due_date} ã«æœŸé™åˆ‡ã‚Œ"
+msgid "expired on %{timebox_due_date}"
+msgstr ""
-msgid "expires on %{milestone_due_date}"
-msgstr "%{milestone_due_date} ã«æœŸé™åˆ‡ã‚Œ"
+msgid "expires on %{timebox_due_date}"
+msgstr ""
msgid "external_url"
msgstr ""
@@ -24881,26 +26285,26 @@ msgid "failed"
msgstr "失敗ã—ã¾ã—ãŸ"
msgid "failed to dismiss associated finding(id=%{finding_id}): %{message}"
-msgstr ""
+msgstr "関連付ã‘られãŸæ¤œå‡ºçµæžœã‚’破棄ã§ãã¾ã›ã‚“ã§ã—ãŸ(id =%{finding_id}): %{message}"
msgid "file"
msgid_plural "files"
-msgstr[0] ""
+msgstr[0] "ファイル"
msgid "finding is not found or is already attached to a vulnerability"
-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} ã®å ´åˆ"
msgid "for %{link_to_merge_request} with %{link_to_merge_request_source_branch} into %{link_to_merge_request_target_branch}"
-msgstr ""
+msgstr "%{link_to_merge_request_source_branch} ã¨%{link_to_merge_request_target_branch} を組ã¿åˆã‚ã›ãŸ%{link_to_merge_request} ã®å ´åˆ"
msgid "for %{link_to_pipeline_ref}"
-msgstr ""
+msgstr "%{link_to_pipeline_ref} ã®å ´åˆ"
msgid "for %{ref}"
-msgstr ""
+msgstr "%{ref} ã®å ´åˆ"
msgid "for this project"
msgstr "ã“ã®ãƒ—ロジェクトã§ã¯"
@@ -24918,13 +26322,13 @@ msgid "group"
msgstr "グループ"
msgid "groups"
-msgstr ""
+msgstr "グループ"
msgid "has already been linked to another vulnerability"
-msgstr ""
+msgstr "ã™ã§ã«åˆ¥ã®è„†å¼±æ€§ã«ãƒªãƒ³ã‚¯ã—ã¦ã„ã¾ã™"
msgid "has already been taken"
-msgstr ""
+msgstr "ã¯æ—¢ã«ä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "help"
msgstr "ヘルプ"
@@ -24935,7 +26339,16 @@ msgstr "ã“ã“"
msgid "https://your-bitbucket-server"
msgstr "https://your-bitbucket-server"
+msgid "image"
+msgstr ""
+
msgid "image diff"
+msgstr "ç”»åƒã®å·®åˆ†"
+
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
msgstr ""
msgid "import flow"
@@ -24970,7 +26383,7 @@ msgid "is an invalid IP address range"
msgstr ""
msgid "is blocked by"
-msgstr ""
+msgstr "ã«ã‚ˆã£ã¦ãƒ–ロックã•ã‚Œã¦ã„ã¾ã™"
msgid "is enabled."
msgstr "有効ã«ãªã‚Šã¾ã—ãŸ"
@@ -24999,6 +26412,9 @@ msgstr "ã‚ãªãŸãŒæ‰€æœ‰ã™ã‚‹ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr "é•·ã™ãŽã¾ã™(%{current_value})。最大サイズ㯠%{max_size} ã§ã™ã€‚"
@@ -25020,6 +26436,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr "外部ã«ä¿å­˜ã•ã‚Œã¦ã„ã¾ã™"
@@ -25033,10 +26455,10 @@ msgid "jigsaw is not defined"
msgstr "jigsaw ãŒæœªå®šç¾©ã§ã™"
msgid "jira.issue.description.content"
-msgstr ""
+msgstr "jira.issue.description.content"
msgid "jira.issue.summary"
-msgstr ""
+msgstr "jira.issue.summary"
msgid "latest"
msgstr "最新"
@@ -25051,14 +26473,17 @@ msgid "leave %{group_name}"
msgstr "%{group_name} を離れる"
msgid "less than a minute"
-msgstr ""
+msgstr "1分未満"
msgid "level: %{level}"
-msgstr ""
+msgstr "レベル: %{level}"
msgid "limit of %{project_limit} reached"
msgstr "%{project_limit} ã®åˆ¶é™ã«é”ã—ã¾ã—ãŸ"
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr "%{path_lock_user_name} ã«ã‚ˆã£ã¦ %{created_at} ã«ãƒ­ãƒƒã‚¯ã•ã‚Œã¦ã„ã¾ã™ã€‚"
@@ -25085,7 +26510,7 @@ msgid "missing"
msgstr "見ã¤ã‹ã‚Šã¾ã›ã‚“"
msgid "most recent deployment"
-msgstr ""
+msgstr "最新ã®ãƒ‡ãƒ—ロイ"
msgid "mrWidgetCommitsAdded|%{commitCount} and %{mergeCommitCount} will be added to %{targetBranch}."
msgstr "%{commitCount} 㨠%{mergeCommitCount} ã‚’ %{targetBranch} ã«è¿½åŠ ã™ã‚‹ã€‚"
@@ -25151,7 +26576,7 @@ msgid "mrWidget|Approved by"
msgstr "承èªè€…"
msgid "mrWidget|Are you adding technical debt or code vulnerabilities?"
-msgstr ""
+msgstr "技術的ãªè² å‚µã‚„脆弱性を追加ã—ã¦ã„ã¾ã™ã‹ï¼Ÿ"
msgid "mrWidget|Cancel automatic merge"
msgstr "自動マージã®ã‚­ãƒ£ãƒ³ã‚»ãƒ«"
@@ -25186,7 +26611,7 @@ msgstr "ソースブランãƒã‚’削除"
msgid "mrWidget|Deployment statistics are not available currently"
msgstr "デプロイ統計ã¯ç¾åœ¨åˆ©ç”¨ã§ãã¾ã›ã‚“"
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25211,7 +26636,7 @@ msgid "mrWidget|If the %{missingBranchName} branch exists in your local reposito
msgstr "%{missingBranchName} ブランãƒãŒãƒ­ãƒ¼ã‚«ãƒ«ãƒªãƒã‚¸ãƒˆãƒªã«å­˜åœ¨ã™ã‚‹å ´åˆã¯ã€ã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³ã‚’使用ã—ã¦ã“ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’手動ã§ãƒžãƒ¼ã‚¸ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
msgid "mrWidget|In the merge train at position %{mergeTrainPosition}"
-msgstr ""
+msgstr "ä½ç½®%{mergeTrainPosition} ã®ãƒžãƒ¼ã‚¸ãƒˆãƒ¬ã‚¤ãƒ³å†…"
msgid "mrWidget|Loading deployment statistics"
msgstr "デプロイ統計を読ã¿è¾¼ã¿ä¸­"
@@ -25289,7 +26714,7 @@ msgid "mrWidget|Revert this merge request in a new merge request"
msgstr "æ–°ã—ã„マージリクエストã§ã“ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’リãƒãƒ¼ãƒˆã™ã‚‹"
msgid "mrWidget|Revoke approval"
-msgstr ""
+msgstr "承èªã‚’å–り消ã™"
msgid "mrWidget|Set by"
msgstr "設定者"
@@ -25366,9 +26791,6 @@ msgstr "ã“ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’手動ã§ãƒžãƒ¼ã‚¸ã§ãã¾ã™"
msgid "mrWidget|Your password"
msgstr "パスワード"
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr "作æˆã™ã‚‹æ–¹æ³•ã®ã‚¯ã‚¤ãƒƒã‚¯ã‚¬ã‚¤ãƒ‰"
-
msgid "mrWidget|branch does not exist."
msgstr "ブランãƒãŒå­˜åœ¨ã—ã¾ã›ã‚“。"
@@ -25376,16 +26798,7 @@ msgid "mrWidget|command line"
msgstr "コマンド ライン"
msgid "mrWidget|into"
-msgstr ""
-
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr "ãŸã£ãŸ1分ã§å …牢ã«ã€‚"
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
+msgstr "→"
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr "パイプラインãŒæˆåŠŸã—ãŸã¨ãã«ãƒžãƒ¼ã‚¸ãƒˆãƒ¬ã‚¤ãƒ³ã«è¿½åŠ ã•ã‚Œã‚‹"
@@ -25399,6 +26812,9 @@ msgstr "パイプラインãŒæˆåŠŸã—ãŸã¨ãã«ãƒžãƒ¼ã‚¸ãƒˆãƒ¬ã‚¤ãƒ³ã‚’開始
msgid "must be greater than start date"
msgstr "開始日より後ã«ã—ã¦ãã ã•ã„。"
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr "利用ä¸å¯"
@@ -25406,10 +26822,10 @@ msgid "need attention"
msgstr ""
msgid "needs to be between 10 minutes and 1 month"
-msgstr ""
+msgstr "10分ã‹ã‚‰1ヶ月ã¾ã§ã®é–“ã«ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™"
msgid "never expires"
-msgstr ""
+msgstr "無期é™"
msgid "new merge request"
msgstr "æ–°è¦ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆ"
@@ -25418,7 +26834,7 @@ msgid "no contributions"
msgstr "貢献ãªã—"
msgid "no expiration"
-msgstr ""
+msgstr "有効期é™ãªã—"
msgid "no one can merge"
msgstr "誰もマージã§ãã¾ã›ã‚“"
@@ -25433,17 +26849,20 @@ msgid "notification emails"
msgstr "メール通知"
msgid "nounSeries|%{firstItem} and %{lastItem}"
-msgstr ""
+msgstr "%{firstItem} 㨠%{lastItem}"
msgid "nounSeries|%{item}, %{nextItem}"
-msgstr ""
+msgstr "%{item} 〠%{nextItem}"
msgid "nounSeries|%{item}, and %{lastItem}"
-msgstr ""
+msgstr "%{item} ãれ㫠%{lastItem}"
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr "%{user} ㌠%{timeAgoString} を開始ã—ã¾ã—ãŸã€‚"
@@ -25451,7 +26870,7 @@ msgid "opened %{timeAgo}"
msgstr ""
msgid "or"
-msgstr ""
+msgstr "ã¾ãŸã¯"
msgid "out of %d total test"
msgid_plural "out of %d total tests"
@@ -25471,11 +26890,20 @@ msgid "pending removal"
msgstr ""
msgid "per day"
+msgstr "1æ—¥ã‚ãŸã‚Š"
+
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
msgstr ""
msgid "pipeline"
msgstr "パイプライン"
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr "pod_name ã« %{max_length} 以上ã®æ–‡å­—列を付与ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。"
@@ -25496,11 +26924,17 @@ msgid "project"
msgid_plural "projects"
msgstr[0] "プロジェクト"
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr "プロジェクトアãƒã‚¿ãƒ¼"
msgid "projects"
-msgstr ""
+msgstr "プロジェクト"
msgid "push to your repository, create pipelines, create issues or add comments. To reduce storage capacity, delete unused repositories, artifacts, wikis, issues, and pipelines."
msgstr ""
@@ -25543,6 +26977,9 @@ msgid "reset it."
msgstr "リセットã—ã¾ã™ã€‚"
msgid "resolved the corresponding error and closed the issue."
+msgstr "対応ã™ã‚‹ã‚¨ãƒ©ãƒ¼ã‚’解決ã—ã€èª²é¡Œã‚’完了ã—ã¾ã—ãŸã€‚"
+
+msgid "revised"
msgstr ""
msgid "score"
@@ -25570,7 +27007,7 @@ msgid "severity|Medium"
msgstr "中"
msgid "severity|None"
-msgstr ""
+msgstr "ãªã—"
msgid "severity|Unknown"
msgstr "ä¸æ˜Ž"
@@ -25585,7 +27022,7 @@ msgid "show fewer"
msgstr ""
msgid "show less"
-msgstr ""
+msgstr "表示を減らã™"
msgid "sign in"
msgstr "サインイン"
@@ -25611,11 +27048,11 @@ msgstr "開始"
msgid "started a discussion on %{design_link}"
msgstr "%{design_link} ã§ãƒ‡ã‚£ã‚¹ã‚«ãƒƒã‚·ãƒ§ãƒ³ã‚’始ã‚ã¾ã—ãŸ"
-msgid "started on %{milestone_start_date}"
-msgstr "%{milestone_start_date} ã«é–‹å§‹ã—ã¾ã—ãŸ"
+msgid "started on %{timebox_start_date}"
+msgstr ""
-msgid "starts on %{milestone_start_date}"
-msgstr "%{milestone_start_date} ã«é–‹å§‹"
+msgid "starts on %{timebox_start_date}"
+msgstr ""
msgid "stuck"
msgstr "スタック"
@@ -25642,7 +27079,7 @@ msgid "syntax is incorrect"
msgstr "構文ãŒé–“é•ã£ã¦ã„ã¾ã™ã€‚"
msgid "tag name"
-msgstr ""
+msgstr "ã‚¿ã‚°å"
msgid "the following issue(s)"
msgstr ""
@@ -25654,19 +27091,19 @@ msgid "to help your contributors communicate effectively!"
msgstr "コントリビュータã®ã‚³ãƒŸãƒ¥ãƒ‹ã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã‚’効率化ã™ã‚‹ï¼"
msgid "to list"
-msgstr ""
+msgstr "リストã¸"
msgid "toggle collapse"
-msgstr ""
+msgstr "表示・éžè¡¨ç¤ºåˆ‡ã‚Šæ›¿ãˆ"
msgid "toggle dropdown"
-msgstr ""
+msgstr "ドロップダウンã®åˆ‡æ›¿"
msgid "triggered"
-msgstr ""
+msgstr "トリガーã•ã‚ŒãŸ"
msgid "unicode domains should use IDNA encoding"
-msgstr ""
+msgstr "Unicodeドメインã«ã¯IDNAエンコーディングを使用ã—ã¦ãã ã•ã„"
msgid "updated"
msgstr "æ›´æ–°ã•ã‚ŒãŸ"
@@ -25677,9 +27114,15 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr "%{time_ago} ã«æ›´æ–°"
-msgid "user avatar"
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
msgstr ""
+msgid "user avatar"
+msgstr "ユーザーã®ã‚¢ãƒã‚¿ãƒ¼"
+
msgid "username"
msgstr "ユーザーå"
@@ -25687,10 +27130,10 @@ msgid "uses Kubernetes clusters to deploy your code!"
msgstr "コードをデプロイã™ã‚‹ãŸã‚ã« Kubernetes クラスターを使用ã™ã‚‹ã€‚"
msgid "verify ownership"
-msgstr ""
+msgstr "所有者を確èªã™ã‚‹"
msgid "version %{versionIndex}"
-msgstr ""
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %{versionIndex}"
msgid "via %{closed_via}"
msgstr "%{closed_via} ã«ã‚ˆã‚Š"
@@ -25704,14 +27147,17 @@ msgstr "GitLab ã§è¦‹ã‚‹"
msgid "view the blob"
msgstr "blobを表示"
-msgid "vulnerability|Add a comment"
+msgid "view the source"
msgstr ""
+msgid "vulnerability|Add a comment"
+msgstr "コメントを追加"
+
msgid "vulnerability|Add a comment or reason for dismissal"
msgstr "å´ä¸‹ã®ã‚³ãƒ¡ãƒ³ãƒˆã¾ãŸã¯ç†ç”±ã‚’記入"
msgid "vulnerability|Add comment"
-msgstr ""
+msgstr "コメントを追加"
msgid "vulnerability|Add comment & dismiss"
msgstr "コメントを追加ã—ã¦å´ä¸‹"
@@ -25729,6 +27175,9 @@ msgid "vulnerability|dismissed"
msgstr "å´ä¸‹ã•ã‚Œã¾ã—ãŸ"
msgid "wiki page"
+msgstr "wiki ページ"
+
+msgid "will be released %{time}"
msgstr ""
msgid "with %{additions} additions, %{deletions} deletions."
diff --git a/locale/ka_GE/gitlab.po b/locale/ka_GE/gitlab.po
index 09b11bfb9e9..915d43f81f8 100644
--- a/locale/ka_GE/gitlab.po
+++ b/locale/ka_GE/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: ka\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:12\n"
+"PO-Revision-Date: 2020-06-08 15:17\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,13 +8991,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8627,7 +9009,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] ""
msgstr[1] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/ko/gitlab.po b/locale/ko/gitlab.po
index 1bc537934f5..3190c685718 100644
--- a/locale/ko/gitlab.po
+++ b/locale/ko/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: ko\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:11\n"
+"PO-Revision-Date: 2020-06-08 15:17\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -71,6 +71,14 @@ msgid "%d URL scanned"
msgid_plural "%d URLs scanned"
msgstr[0] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -87,6 +95,10 @@ msgid "%d comment"
msgid_plural "%d comments"
msgstr[0] "%dê°œì˜ ëŒ“ê¸€"
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] "%dê°œì˜ ì»¤ë°‹"
@@ -106,6 +118,10 @@ msgid "%d contribution"
msgid_plural "%d contributions"
msgstr[0] "%d 기여"
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -162,6 +178,10 @@ msgid "%d more comment"
msgid_plural "%d more comments"
msgstr[0] "%d 댓글 ë” ë³´ê¸°"
+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] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] "%d 프로ì íŠ¸"
@@ -186,6 +206,14 @@ msgid "%d unresolved thread"
msgid_plural "%d unresolved threads"
msgstr[0] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -206,6 +234,9 @@ msgstr "%{commit_timeago} ì— %{commit_author_link} ë‹˜ì´ ì»¤ë°‹í•˜ì˜€ìŠµë‹ˆë‹¤
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} 코어"
@@ -279,6 +310,9 @@ msgstr "%{filePath} ì‚­ì œë¨"
msgid "%{firstLabel} +%{labelCount} more"
msgstr "%{firstLabel} +%{labelCount} ë”보기"
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -288,6 +322,9 @@ msgstr "%{group_docs_link_start}그룹%{group_docs_link_end}ì„ ì‚¬ìš©í•˜ë©´ ì—¬
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr "%{group_name}ì€ ê·¸ë£¹ 관리 ê³„ì •ì„ ì‚¬ìš© 합니다. %{group_name}를 관리 í•  새 GitLab ê³„ì •ì„ ë§Œë“¤ì–´ì•¼ 합니다."
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -300,6 +337,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr "%{label_for_message} 사용할 수 ì—†ìŒ"
@@ -333,12 +394,21 @@ msgstr "%{loadingIcon} 시작ë¨"
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr "%{lock_path} 경로는 GitLab User %{lock_user_id} ì— ì˜í•´ 잠겼습니다."
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr "%{mergeLength}/%{usersLength} 머지 가능"
msgid "%{mrText}, this issue will be closed automatically."
msgstr "%{mrText}, ì´ ì´ìŠˆëŠ” ìžë™ìœ¼ë¡œ í´ë¡œì¦ˆ ë©ë‹ˆë‹¤."
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -354,6 +424,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr "%{name} ì˜ ì•„ë°”íƒ€"
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -392,6 +468,12 @@ msgid "%{releases} release"
msgid_plural "%{releases} releases"
msgstr[0] "%{releases} 릴리즈"
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -533,6 +615,9 @@ msgid "(%d closed)"
msgid_plural "(%d closed)"
msgstr[0] "(%d 마ê°)"
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr "(%{mrCount} 병합)"
@@ -719,6 +804,9 @@ msgstr "ì´ê²ƒì´ ì‹¤ìˆ˜ì— ì˜í•œ 것ì´ë¼ê³  ìƒê°í•œë‹¤ë©´ GitLab 관리ìž
msgid "8 hours"
msgstr "8 시간"
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -749,6 +837,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr "<strong>%{group_name}</strong> 그룹 멤버"
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr "소스 브랜치 <strong>삭제</strong>"
@@ -758,6 +849,9 @@ msgstr "'러너(Runner)'는 ìž‘ì—…ì„ ì‹¤í–‰í•˜ëŠ” 프로세스입니다. í•„ìš”
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ".NET 코어 콘솔 ì‘ìš© 프로그램 템플릿, 모든 .NET 코어 프로ì íŠ¸ì— 맞게 ì‚¬ìš©ìž ì •ì˜ ê°€ëŠ¥"
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -794,7 +888,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr "í¬í¬ëŠ” 프로ì íŠ¸ì˜ 사본입니다.<br />저장소를 í¬í¬í•˜ë©´ ì›ëž˜ 프로ì íŠ¸ì— ì˜í–¥ì„주지 ì•Šê³  변경할 수 있습니다."
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -845,6 +942,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -857,9 +957,6 @@ msgstr "소스 ë¸Œëžœì¹˜ì— ëŒ€í•œ 쓰기 ê¶Œí•œì´ ìžˆëŠ” 사용ìžê°€ ì´ ì˜µì
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr "API ë„움ë§"
-
msgid "API Token"
msgstr "API 토í°"
@@ -905,9 +1002,6 @@ msgstr "약관ë™ì˜"
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr "승ì¸ëœ MR"
-
msgid "Access Tokens"
msgstr "액세스 토í°"
@@ -998,12 +1092,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr "재설정"
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1040,8 +1128,8 @@ msgstr "서비스 ë°ìŠ¤í¬ 활성화"
msgid "Active"
msgstr "활성"
-msgid "Active %{type} Tokens (%{token_length})"
-msgstr "활성 %{type} í† í° (%{token_length})"
+msgid "Active %{type} (%{token_length})"
+msgstr ""
msgid "Active Sessions"
msgstr "í™œì„±í™”ëœ ì„¸ì…˜"
@@ -1049,6 +1137,9 @@ msgstr "í™œì„±í™”ëœ ì„¸ì…˜"
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr "활ë™"
@@ -1092,8 +1183,8 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
-msgstr "%{type} í† í° ì¶”ê°€"
+msgid "Add a %{type}"
+msgstr ""
msgid "Add a GPG key"
msgstr "GPG 키 추가"
@@ -1107,6 +1198,9 @@ msgstr "í• ì¼ ì¶”ê°€"
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr "ì´ %{noteableDisplayName} ì— ì¼ë°˜ì ì¸ 코멘트를 추가 합니다."
@@ -1116,9 +1210,15 @@ msgstr "ì´ %{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 "프로ì íŠ¸ì— 관한 ì •ë³´ê°€ 담긴 홈페ì´ì§€ë¥¼ wikiì— ì¶”ê°€í•˜ë©´ GitLabì´ ë©”ì‹œì§€ 대신 ì—¬ê¸°ì— í‘œì‹œ 합니다."
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr "ë§í¬ 추가"
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr "번호 매기기 ëª©ë¡ ì¶”ê°€"
@@ -1134,7 +1234,10 @@ msgstr "모든 ì´ë©”ì¼ì— í‘œì‹œë  í…스트를 추가합니다. %{character_
msgid "Add an SSH key"
msgstr "SSH 키 추가"
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1200,6 +1303,9 @@ msgstr "ë°˜ì‘ ì¶”ê°€"
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1290,18 +1396,18 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr "ê´€ë¦¬ìž ì˜ì—­"
+msgid "Admin Note"
+msgstr ""
+
msgid "Admin Overview"
msgstr "ê´€ë¦¬ìž ê°œìš”"
-msgid "Admin Section"
-msgstr "ê´€ë¦¬ìž ì„¹ì…˜"
-
msgid "Admin mode already enabled"
msgstr ""
@@ -1626,62 +1732,116 @@ msgstr "비밀번호가 성공ì ìœ¼ë¡œ ë³€ê²½ëœ ë’¤ì— ë¡œê·¸ì¸ í™”ë©´ìœ¼ë¡œ
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr "비밀번호 ì—…ë°ì´íŠ¸ì— 성공하면, 새 비밀번호로 ë¡œê·¸ì¸ í•  수있는 ë¡œê·¸ì¸ íŽ˜ì´ì§€ë¡œ 리디렉션 ë©ë‹ˆë‹¤."
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] "알림"
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1690,16 +1850,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1873,6 +2051,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr "%{link_to_client} ì´ë¼ëŠ” ì‘ìš© í”„ë¡œê·¸ëž¨ì´ 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 ""
+
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 "비어 있는 GitLab User 필드는 FogBugzì˜ ì‚¬ìš©ìž ì „ì²´ ì´ë¦„ (예 : By í™ ê¸¸ë™)ì„ ì´ìŠˆ ë° ì»¤ë§¨íŠ¸ì˜ ì„¤ëª…ìœ¼ë¡œ 추가 합니다. ë˜í•œ ì´ ì´ìŠˆì™€ 커맨트를 프로ì íŠ¸ 작성ìžì— 알리고 할당 í•  것입니다."
@@ -2038,9 +2219,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr "차트 ë°ì´í„°ë¥¼ ë¡œë“œí•˜ë˜ ë„중 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤."
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr "커밋 시그너ì³ë¥¼ 불러오는 ë„ì¤‘ì— ì—러가 ë°œìƒí–ˆìŠµë‹ˆë‹¤."
@@ -2062,6 +2240,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2137,6 +2318,9 @@ msgstr "ìŠ¹ì¸ ì„¤ì •ì„ ì €ìž¥í•˜ëŠ” ë™ì•ˆ 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤"
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr "ì•Œë¦¼ì„ êµ¬ë…하는 ì¤‘ì— ì˜¤ë¥˜ê°€ ë°œìƒí–ˆìŠµë‹ˆë‹¤."
@@ -2173,9 +2357,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr "프로ì íŠ¸ í™˜ê²½ì„ í™•ì¸í•˜ë˜ ë„중 예ìƒì¹˜ ì•Šì€ ì˜¤ë¥˜ê°€ ë°œìƒí–ˆìŠµë‹ˆë‹¤."
@@ -2191,6 +2381,9 @@ msgstr "웹 터미ë„ì„ ì‹œìž‘í•˜ë˜ ë„중 예ìƒì¹˜ ì•Šì€ ì˜¤ë¥˜ê°€ ë°œìƒí–
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr "웹 터미ë„ì˜ ìž‘ë™ì„ ë©ˆì¶”ë˜ ë„중 예ìƒì¹˜ ì•Šì€ ì˜¤ë¥˜ê°€ ë°œìƒí–ˆìŠµë‹ˆë‹¤."
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr "분ì„"
@@ -2200,6 +2393,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2224,12 +2420,6 @@ msgstr "Any"
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr "모든 ë¼ë²¨"
-
-msgid "Any Milestone"
-msgstr "ìž„ì˜ì˜ 마ì¼ìŠ¤í†¤"
-
msgid "Any branch"
msgstr ""
@@ -2239,9 +2429,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr "ìž„ì˜ì˜ 네임스페ì´ìŠ¤"
@@ -2305,6 +2501,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr "제안 ì ìš©"
@@ -2369,12 +2568,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr "승ì¸"
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr "승ì¸"
@@ -2384,12 +2577,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2498,6 +2697,9 @@ msgstr "ì •ë§ë¡œ %{group_name}(ì„)를 ì‚­ì œ 하시겠습니까?"
msgid "Are you sure you want to remove the attachment?"
msgstr "첨부 파ì¼ì´ 지워집니다. ê³„ì† í•˜ì‹œê² ìŠµë‹ˆê¹Œ?"
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr "ì •ë§ë¡œ 해당 í•­ëª©ì„ ì‚­ì œí•˜ì‹œê² ìŠµë‹ˆê¹Œ?"
@@ -2510,7 +2712,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr "헬스 ì²´í¬ í† í°ì„ 초기화 하시겠습니까?"
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2624,6 +2826,9 @@ msgstr "í• ë‹¹ëœ ì´ìŠˆ"
msgid "Assigned Merge Requests"
msgstr "í• ë‹¹ëœ ë¨¸ì§€ 리퀘스트(MR)"
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr "나ì—게 할당 ë¨"
@@ -2698,15 +2903,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr "8ì›”"
@@ -2764,6 +2987,9 @@ msgstr "권한 부여"
msgid "Authorize %{link_to_client} to use your account?"
msgstr "%{link_to_client} ì„ ë‚´ 계정으로 ì¸ì¦í•˜ì‹œê² ì–´ìš”?"
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2785,9 +3011,6 @@ msgstr "ìžë™ DevOps 활성화ë¨"
msgid "Auto DevOps, runners and job artifacts"
msgstr "ìžë™ DevOps, Runner ìž‘ì—… artifacts"
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2806,6 +3029,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr "Auto DevOps 문서"
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr "활성화하기"
@@ -2836,6 +3062,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr "기본 내부 사용ìžë¡œ ìžë™ 표시"
@@ -2851,6 +3080,9 @@ msgstr ""
msgid "Available"
msgstr "ì´ìš© 가능"
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr "사용 가능한 그룹 러너: %{runners}"
@@ -3236,7 +3468,7 @@ msgid "Branches|Show more active branches"
msgstr "í™œì„±ëœ ë¸Œëžœì¹˜ ë” ë³´ê¸°"
msgid "Branches|Show more stale branches"
-msgstr "ì•ˆì •í™”ëœ ë¸Œëžœì¹˜ ë” ë³´ê¸°"
+msgstr "ì˜¤ëž˜ëœ ë¸Œëžœì¹˜ ë” ë³´ê¸°"
msgid "Branches|Show overview of the branches"
msgstr "브랜치 개요 보기"
@@ -3248,7 +3480,7 @@ msgid "Branches|Sort by"
msgstr "다ìŒìœ¼ë¡œ 정렬하기"
msgid "Branches|Stale"
-msgstr "안정"
+msgstr "오래ë¨"
msgid "Branches|Stale branches"
msgstr "ì•ˆì •í™”ëœ ë¸Œëžœì¹˜"
@@ -3328,17 +3560,17 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
+msgid "Burnup chart"
+msgstr ""
+
msgid "Business"
msgstr "비즈니스"
msgid "Business metrics (Custom)"
msgstr "비즈니스 지표 (ì‚¬ìš©ìž ì •ì˜)"
-msgid "Buy EE"
-msgstr "EE 구입"
-
-msgid "Buy GitLab Enterprise Edition"
-msgstr "GitLab Enterprise Edition 구입"
+msgid "Buy License"
+msgstr ""
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -3361,8 +3593,8 @@ msgstr "변경 로그"
msgid "CI / CD"
msgstr "CI / CD"
-msgid "CI / CD Charts"
-msgstr "CI/CD 차트"
+msgid "CI / CD Analytics"
+msgstr ""
msgid "CI / CD Settings"
msgstr "CI/CD 설정"
@@ -3370,6 +3602,9 @@ msgstr "CI/CD 설정"
msgid "CI Lint"
msgstr "CI 린트"
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3388,6 +3623,9 @@ msgstr "외부 저장소용 CI/CD"
msgid "CI/CD settings"
msgstr "CI/CD 설정"
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr "Auto DevOps"
@@ -3418,9 +3656,6 @@ msgstr "대체 CI 구성 파ì¼ì´ì—†ëŠ” 경우 Auto DevOps 파ì´í”„ë¼ì¸ì´ ì
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3448,6 +3683,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr "승ì¸ìžë¥¼ ë®ì–´ì“¸ 수 있으며, 매 머지 리퀘스트 마다 승ì¸ì´ 필요합니다."
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr "ì´ ë¸Œëžœì¹˜ì—ì„œ HEAD ì»¤ë°‹ì„ ì°¾ì„ ìˆ˜ 없습니다."
@@ -3523,7 +3764,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3538,6 +3779,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr "ì¸ì¦ì„œ"
@@ -3574,6 +3818,12 @@ msgstr "경로 변경"
msgid "Change permissions"
msgstr "권한 변경"
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr "템플릿 변경"
@@ -3616,6 +3866,9 @@ msgstr "변경사항"
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr "변경 ì‚¬í•­ì€ <b>source</b> ë¦¬ë¹„ì „ì´ <b>target</b> ë¦¬ë¹„ì „ì— ë¨¸ì§€ëœ ê²ƒì²˜ëŸ¼ 표시ë©ë‹ˆë‹¤."
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3634,6 +3887,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3739,15 +3995,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4096,9 +4343,6 @@ msgstr "유효성 검사 실패"
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4111,6 +4355,9 @@ msgstr "지우기"
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr "입력 지우기"
@@ -4123,6 +4370,9 @@ msgstr "검색 지우기"
msgid "Clear search input"
msgstr "검색 입력 지우기"
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4150,9 +4400,6 @@ msgstr "ì˜¤ë¥¸ìª½ì˜ <strong>ì„ íƒ ì—†ìŒ</strong> ë²„íŠ¼ì„ í´ë¦­ 하십시ì˜
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr "Kubernetes 페ì´ì§€ë¡œ ì´ë™í•˜ì—¬ 설치 프로세스를 시작하려면 아래 ë²„íŠ¼ì„ í´ë¦­í•˜ì‹­ì‹œì˜¤."
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr "í´ë¦­í•˜ì—¬ 확장하십시오."
@@ -4192,6 +4439,9 @@ msgstr "SSH로 clone"
msgid "Close"
msgstr "닫기"
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4387,6 +4637,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4408,9 +4661,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr "Kubernetes í´ëŸ¬ìŠ¤í„° ì´ë¦„ 복사"
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4462,7 +4712,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4489,6 +4739,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4567,12 +4820,12 @@ msgstr "그룹 í´ëŸ¬ìŠ¤í„°"
msgid "ClusterIntegration|Helm Tiller"
msgstr "Helm Tiller"
+msgid "ClusterIntegration|Helm release failed to install"
+msgstr ""
+
msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr "Helmì€ Kubernetes ì‘ìš© 프로그램 설치 ë° ê´€ë¦¬ë¥¼ 간소화 합니다. Tiller는 Kubernetes Cluster 내부ì—ì„œ 실행ë˜ë©° ì°¨íŠ¸ì˜ ë¦´ë¦¬ìŠ¤ë¥¼ 관리합니다."
-msgid "ClusterIntegration|Hide"
-msgstr "숨기기"
-
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
msgstr ""
@@ -4729,6 +4982,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -4963,9 +5222,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr "표시"
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr "문제가 ë°œìƒí–ˆìŠµë‹ˆë‹¤."
@@ -5044,6 +5300,9 @@ msgstr "Kubernetes í´ëŸ¬ìŠ¤í„° 토글"
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5074,6 +5333,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5083,9 +5345,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr "ë‹¹ì‹ ì˜ ê³„ì •ì€ %{link_to_kubernetes_engine} ì´ ìžˆì–´ì•¼ 합니다."
@@ -5143,6 +5411,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr "코드"
@@ -5161,6 +5432,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr "코드 ì†Œìœ ìž ìŠ¹ì¸ì´ 필요합니다."
@@ -5200,6 +5474,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr "사ì´ë“œ ë°” 축소"
@@ -5209,6 +5486,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5245,6 +5525,9 @@ msgstr "댓글 ì–‘ì‹ ìœ„ì¹˜"
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5405,7 +5688,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5429,9 +5715,6 @@ msgstr "Let's Encrypt 설정"
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr "ì¶”ì  êµ¬ì„±"
@@ -5465,9 +5748,6 @@ msgstr "저장 경로 ì„¤ì •ì„ êµ¬ì„± 합니다."
msgid "Configure the %{link} integration."
msgstr "%{link} ì—°ë™ êµ¬ì„±"
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr "사용ìžê°€ 새로운 ê³„ì •ì„ ë§Œë“œëŠ” ë°©ë²•ì„ ì„¤ì •í•©ë‹ˆë‹¤."
@@ -5516,17 +5796,11 @@ msgstr "연결 실패"
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr "í”Œëžœì„ ì—…ê·¸ë ˆì´ë“œí•˜ë ¤ë©´ %{namespace_name} ê·¸ë£¹ì˜ ì†Œìœ ìžì—게 문ì˜í•˜ì„¸ìš”."
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr "í”Œëžœì„ ì—…ê·¸ë ˆì´ë“œ 하려면 ì†Œìœ ìž %{link_start}%{owner_name}%{link_end} ì—게 문ì˜í•˜ì„¸ìš”."
-
msgid "Contact sales to upgrade"
msgstr "업그레ì´ë“œ 위해 ì˜ì—…íŒ€ì— ë¬¸ì˜"
-msgid "Contact your Administrator to upgrade your license."
-msgstr "관리ìžì—게 문ì˜í•˜ì—¬ ë‚˜ì˜ ë¼ì´ì„¼ìŠ¤ë¥¼ 업그레ì´ë“œí•˜ì„¸ìš”."
+msgid "Contact support"
+msgstr ""
msgid "Container Registry"
msgstr "컨테ì´ë„ˆ 레지스트리"
@@ -5552,6 +5826,14 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5564,6 +5846,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5588,27 +5873,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5630,10 +5927,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5652,9 +5946,6 @@ msgid "ContainerRegistry|Remove tag"
msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5676,6 +5967,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr "태그"
@@ -5703,12 +5997,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5727,7 +6015,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5736,7 +6027,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5775,10 +6066,10 @@ msgstr "기여"
msgid "Contribution Analytics"
msgstr "ê¸°ì—¬ë„ ë¶„ì„"
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5865,6 +6156,9 @@ msgstr "%{protocol} í´ë¡  URL 복사"
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5910,9 +6204,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -5928,9 +6219,6 @@ msgstr "ë§í¬ 복사"
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6027,7 +6315,7 @@ msgstr "만들기"
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6045,9 +6333,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6066,9 +6351,6 @@ msgstr ""
msgid "Create a new issue"
msgstr "새 ì´ìŠˆ 만들기"
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr "새 저장소 만들기"
@@ -6078,9 +6360,6 @@ msgstr "%{protocol}ì„ (를) 통해 Pull 하거나 Push í•  ê°œì¸ ì•¡ì„¸ìŠ¤ 토
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr "ì´ìŠˆë¥¼ ìƒì„±. íŠ¸ë¦¬ê±°ëœ ê° ê²½ê³ ì— ëŒ€í•œ ì´ìŠˆê°€ ìƒì„±ë©ë‹ˆë‹¤."
@@ -6123,6 +6402,9 @@ msgstr "새로운 그룹 ë¼ë²¨"
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr "ë¼ë²¨ë¡œë¶€í„° 목ë¡ì„ ìƒì„±í•©ë‹ˆë‹¤. ì´ìŠˆì™€ 함께 ë¼ë²¨ì´ 목ë¡ì— 표시ë©ë‹ˆë‹¤."
@@ -6135,6 +6417,9 @@ msgstr "머지 리퀘스트(MR) ë° ë¸Œëžœì¹˜ ìƒì„±"
msgid "Create milestone"
msgstr "마ì¼ìŠ¤í†¤ 만들기"
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr "새 보드 만들기"
@@ -6174,6 +6459,12 @@ msgstr ""
msgid "Create your first page"
msgstr "첫 페ì´ì§€ 만들기"
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6207,6 +6498,9 @@ msgstr ""
msgid "Created by me"
msgstr "ë‚˜ì— ì˜í•´ ìƒì„±ë¨"
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6258,9 +6552,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr "Cron 시간대"
-msgid "Cron syntax"
-msgstr "í¬ë¡  구문"
-
msgid "Crossplane"
msgstr ""
@@ -6297,6 +6588,9 @@ msgstr "설정"
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6321,6 +6615,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6369,6 +6666,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr "ìƒ‰ìƒ ë§žì¶¤í™”"
@@ -6393,6 +6693,9 @@ msgstr "파ì´í”„ë¼ì¸ ì„¤ì •ì„ ë³€ê²½í•˜ê³ , ë‚˜ì˜ íŒŒì´í”„ë¼ì¸ìƒíƒœì™€
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6643,6 +6946,9 @@ msgstr ""
msgid "Default classification label"
msgstr "기본 분류 ë¼ë²¨"
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6679,6 +6985,9 @@ msgstr "기본: FogBugz 계정 ID를 풀네임으로 매핑"
msgid "Define a custom pattern with cron syntax"
msgstr "cron êµ¬ë¬¸ì„ ì‚¬ìš©í•˜ì—¬ ì‚¬ìš©ìž ì •ì˜ íŒ¨í„´ ì •ì˜"
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6721,6 +7030,12 @@ msgstr "댓글 삭제"
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr "ë¼ì´ì„¼ìŠ¤ ì‚­ì œ"
@@ -6809,10 +7124,6 @@ msgid "Dependencies|%d additional vulnerability not shown"
msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6847,12 +7158,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6862,9 +7167,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -6976,12 +7278,18 @@ msgstr "활성 ë°°í¬ í† í° (%{active_tokens})"
msgid "DeployTokens|Add a deploy token"
msgstr "ë°°í¬ í† í° ì¶”ê°€"
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr "레지스트리 ì´ë¯¸ì§€ì— 대한 ì½ê¸° ì „ìš© 액세스 허용"
msgid "DeployTokens|Allows read-only access to the repository"
msgstr "ì €ìž¥ì†Œì— ëŒ€í•œ ì½ê¸° ì „ìš© 액세스 허용"
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7003,13 +7311,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr "ë°°í¬ í† í°"
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr "만료"
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7129,10 +7437,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7141,9 +7449,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7153,6 +7476,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7180,12 +7506,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7195,6 +7536,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7207,6 +7554,9 @@ msgstr "ë””ìžì¸"
msgid "Destroy"
msgstr "제거"
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr "ìƒì„¸"
@@ -7433,6 +7783,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7481,6 +7834,9 @@ msgstr "ì´ë¯¸ì§€ 다운로드"
msgid "Download license"
msgstr "ë¼ì´ì„¼ìŠ¤ 다운로드"
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr "소스 코드 다운로드"
@@ -7505,6 +7861,9 @@ msgstr "비추천"
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr "마ê°ì¼"
@@ -7652,6 +8011,9 @@ msgstr "ì´ë©”ì¼"
msgid "Email address"
msgstr "ì´ë©”ì¼ ì£¼ì†Œ"
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7667,6 +8029,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7760,6 +8125,9 @@ msgstr "ì´ ê·¸ë£¹ì— SAML ì¸ì¦ 사용"
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7769,9 +8137,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr "InfluxDB 매트릭스를 활성화하고 구성합니다."
-
msgid "Enable and configure Prometheus metrics."
msgstr "Prometheus 매트릭스를 활성화하고 구성합니다."
@@ -7799,6 +8164,9 @@ msgstr "그룹 Runner 사용"
msgid "Enable header and footer in emails"
msgstr "ë©”ì¼ ë¨¸ë¦¬ë§ ë° ê¼¬ë¦¬ë§ ì‚¬ìš©"
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -7922,6 +8290,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -7946,10 +8317,10 @@ msgstr "머지 리퀘스트(MR) ì„¤ëª…ì„ ìž…ë ¥ 해주세요"
msgid "Enter the merge request title"
msgstr "머지 리퀘스트(MR) ì œëª©ì„ ìž…ë ¥ 해주세요"
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8006,7 +8377,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr "추가 작업"
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8219,10 +8590,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8234,12 +8605,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr "ì´ê²ƒì„ 어떻게 í•´ê²°í•  수 있습니까?"
@@ -8309,7 +8674,16 @@ msgstr "ì—í”½ì„ ë§Œë“œëŠ” 중 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤."
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8414,9 +8788,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr "ë ˆì´ë¸” 갱신 중 오류 ë°œìƒ"
@@ -8432,6 +8803,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8483,12 +8857,12 @@ msgstr "오류"
msgid "Errors:"
msgstr ""
+msgid "Estimate"
+msgstr ""
+
msgid "Estimated"
msgstr "예ìƒ"
-msgid "Event Actions"
-msgstr ""
-
msgid "EventFilterBy|Filter by all"
msgstr "모든 ê°’ì„ ê¸°ì¤€ìœ¼ë¡œ í•„í„°"
@@ -8528,14 +8902,14 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
-msgstr "ë§¤ì¼ (오전 4ì‹œì—)"
+msgid "Every day (at %{time})"
+msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
-msgstr "매월 (1ì¼ ì˜¤ì „ 4ì‹œ)"
+msgid "Every month (Day %{day} at %{time})"
+msgstr ""
msgid "Every three months"
msgstr ""
@@ -8546,8 +8920,8 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
-msgstr "매주 (ì¼ìš”ì¼ ì˜¤ì „ 4ì‹œì—)"
+msgid "Every week (%{weekday} at %{time})"
+msgstr ""
msgid "Everyone"
msgstr "모ë‘"
@@ -8585,6 +8959,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8603,6 +8980,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8636,6 +9016,9 @@ msgstr "사ì´ë“œë°” 확장"
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8651,6 +9034,9 @@ msgstr "만료ë¨"
msgid "Expired %{expiredOn}"
msgstr "%{expiredOn}ì— ë§Œë£Œë¨"
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8660,6 +9046,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8738,18 +9127,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8876,6 +9253,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -8951,7 +9331,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9014,6 +9394,12 @@ msgstr "설명"
msgid "FeatureFlags|Edit Feature Flag"
msgstr "Feature 플래그 수정"
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9026,6 +9412,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr "Feature 플래그"
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9035,15 +9424,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9062,6 +9460,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr "ì¸ìŠ¤í„´ìŠ¤ ID"
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9077,9 +9478,15 @@ msgstr "새로운"
msgid "FeatureFlags|New Feature Flag"
msgstr "새로운 Feature 플래그"
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9170,6 +9577,9 @@ msgstr "íŒŒì¼ íƒìƒ‰ê¸°"
msgid "File deleted"
msgstr "íŒŒì¼ ì‚­ì œë¨"
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9182,6 +9592,9 @@ msgstr "íŒŒì¼ ì´ë™ë¨"
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9191,9 +9604,6 @@ msgstr "íŒŒì¼ í…œí”Œë¦¿"
msgid "File upload error."
msgstr "íŒŒì¼ ì—…ë¡œë“œ 오류"
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr "파ì¼"
@@ -9209,24 +9619,45 @@ msgstr ""
msgid "Filter"
msgstr "í•„í„°"
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr "커밋 메시지로 필터"
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9236,6 +9667,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9467,9 +9901,6 @@ msgstr "ì´ìŠˆ ìƒì„±ì—ì„œ 프로ë•ì…˜ ë°°í¬ê¹Œì§€"
msgid "From merge request merge until deploy to production"
msgstr "머지 리퀘스트(MR) 머지ì—ì„œ 프로ë•ì…˜ í™˜ê²½ì— ë°°í¬ê¹Œì§€"
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr "Kubernetes í´ëŸ¬ìŠ¤í„° 세부사항 ë³´ê¸°ì˜ ì• í”Œë¦¬ì¼€ì´ì…˜ 목ë¡ì—ì„œ Runner를 설치하십시오."
@@ -9509,15 +9940,15 @@ msgstr ""
msgid "Geo"
msgstr "Geo"
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr "Geo 노드"
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9695,6 +10126,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9704,10 +10141,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
-msgstr "Geo| ì „ì²´"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9758,6 +10195,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9809,6 +10252,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr "ìƒíƒœ"
@@ -9827,6 +10273,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9836,6 +10285,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr "ì•Œ 수 없는 ìƒíƒœ"
@@ -10088,9 +10543,6 @@ msgstr "Gitea 호스트 URL"
msgid "Gitea Import"
msgstr "Gitea 가져오기"
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10124,9 +10576,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr "ì´ë™"
-
msgid "Go to %{link_to_google_takeout}."
msgstr "%{link_to_google_takeout}ë¡œ ì´ë™í•˜ì‹­ì‹œì˜¤."
@@ -10289,12 +10738,21 @@ msgstr ""
msgid "Group"
msgstr "그룹"
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10328,6 +10786,12 @@ msgstr "그룹 URL"
msgid "Group avatar"
msgstr "그룹 아바타"
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr "그룹 설명"
@@ -10340,10 +10804,13 @@ msgstr "그룹 세부 정보"
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10361,10 +10828,13 @@ msgstr "그룹 관리ìžëŠ” grouo runners를 여기서 ë“±ë¡ í•  수 있습니ë
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr "그룹명"
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10382,12 +10852,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10454,9 +10930,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10658,6 +11131,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr "부모 ê·¸ë£¹ì˜ \"그룹 lock 공유\" ê°€ 사용 가능하ë„ë¡ ì„¤ì •ë˜ì–´ìžˆìœ¼ë©´, 부모 ê·¸ë£¹ì˜ ì†Œìœ ìžë¥¼ ì œì™¸í•˜ê³ ëˆ„êµ¬ë„ ì‚¬ìš©í•˜ì§€ ì•Šë„ë¡ ì„¤ì •í•  수 없습니다."
@@ -10763,6 +11239,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr "사용ìžì—게 ì´ë©”ì¼ ë°œì‹ "
@@ -10772,6 +11251,9 @@ msgstr ""
msgid "Header message"
msgstr "머릿글 메시지"
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10876,6 +11358,9 @@ msgstr "ì´ë ¥"
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10885,6 +11370,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11035,6 +11523,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11044,7 +11535,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11053,6 +11547,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11065,7 +11565,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11083,15 +11586,15 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
+msgid "Impersonation Tokens"
+msgstr ""
+
msgid "Impersonation has been disabled"
msgstr ""
msgid "Import"
msgstr "가져오기"
-msgid "Import %{status}"
-msgstr ""
-
msgid "Import CSV"
msgstr "CSV 가져오기"
@@ -11101,6 +11604,9 @@ msgstr "Giteaì—ì„œ 프로ì íŠ¸ 가져오기"
msgid "Import all compatible projects"
msgstr "호환ë˜ëŠ” 모든 프로ì íŠ¸ 가져오기"
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr "모든 프로ì íŠ¸ 가져오기"
@@ -11110,6 +11616,9 @@ msgstr "모든 저장소 가져오기"
msgid "Import an exported GitLab project"
msgstr "내보낸 GitLab 프로ì íŠ¸ 가져오기"
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11119,12 +11628,12 @@ msgstr ""
msgid "Import in progress"
msgstr "가져오기 진행중"
+msgid "Import in progress. Refresh page to see newly added issues."
+msgstr ""
+
msgid "Import issues"
msgstr "ì´ìŠˆ 가져오기"
-msgid "Import issues from Jira"
-msgstr ""
-
msgid "Import members"
msgstr "멤버 가져오기"
@@ -11215,12 +11724,12 @@ msgstr "GitLab Enterprise Editionì„ í†µí•´ ì´ìŠˆ 보드를 í–¥ìƒ ì‹œí‚µë‹ˆë‹¤
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
-msgstr "ì´ìŠˆ 가중치와 GitLab Enterprise Editionì„ í†µí•´ ì´ìŠˆ 관리를 í–¥ìƒ ì‹œí‚¤ì„¸ìš”."
-
msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr "고급 Global 검색과 GitLab Enterprise Edition ì„ í†µí•´ ê²€ìƒ‰ê¸°ëŠ¥ì„ í–¥ìƒì‹œí‚¤ì„¸ìš”."
+msgid "In %{time_to_now}"
+msgstr ""
+
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
msgstr ""
@@ -11251,6 +11760,9 @@ msgstr "모든 사용ìžê°€ 수ë½í•´ì•¼ 하는 서비스 약관 ë° ê°œì¸ ì •ë
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11284,6 +11796,12 @@ msgstr "호환ë˜ì§€ 않는 프로ì íŠ¸"
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11308,18 +11826,36 @@ msgstr "호스트 키를 수ë™ìœ¼ë¡œ ìž…ë ¥"
msgid "Input your repository URL"
msgstr "저장소 URLì„ ìž…ë ¥ 하세요"
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11369,6 +11905,30 @@ msgstr "ì—°ë™"
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr "관심있는 íŒŒí‹°ë“¤ì€ ì›í•˜ëŠ” ê³³ì— ì»¤ë°‹ì„ í‘¸ì‹œí•¨ìœ¼ë¡œì¨ ê¸°ì—¬í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤."
@@ -11408,6 +11968,12 @@ msgstr ""
msgid "Invalid URL"
msgstr "유효하지 ì•Šì€ URL"
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11444,18 +12010,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11468,6 +12043,9 @@ msgstr "초대"
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr "그룹 초대"
@@ -11531,6 +12109,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11543,6 +12124,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr "보드"
@@ -11600,6 +12208,9 @@ msgstr "ì´ìŠˆ 닫힘"
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11645,6 +12256,30 @@ msgstr ""
msgid "It's you"
msgstr "바로 너"
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11657,19 +12292,22 @@ msgstr "1ì›”"
msgid "January"
msgstr "1ì›”"
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
+msgstr ""
+
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira integration not configured."
+msgid "JiraService| on branch %{branch_link}"
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11795,6 +12433,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11834,6 +12475,9 @@ msgstr "6ì›”"
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12012,6 +12656,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12096,6 +12743,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr "Web Terminalì— ëŒ€í•˜ì—¬ ë” ìžì„¸ížˆ 알아보기"
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12117,9 +12767,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr "ë” ìžì„¸ížˆ 알아보기"
@@ -12147,6 +12794,9 @@ msgstr "프로ì íŠ¸ì—ì„œ 나가기"
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12159,6 +12809,9 @@ msgstr "ë¼ì´ì„¼ìŠ¤"
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12183,15 +12836,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12322,6 +12969,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12337,6 +12987,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12431,6 +13084,9 @@ msgstr "불러오는 중…"
msgid "Loading…"
msgstr "로딩 중…"
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr "현지화"
@@ -12545,10 +13201,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12575,6 +13231,9 @@ msgstr "그룹 ë ˆì´ë¸” 관리"
msgid "Manage labels"
msgstr "ë ˆì´ë¸” 관리"
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr "프로ì íŠ¸ ë¼ë²¨ 관리"
@@ -12626,9 +13285,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12638,9 +13294,6 @@ msgstr ""
msgid "Markdown"
msgstr "Markdown"
-msgid "Markdown Help"
-msgstr "Markdown ë„움ë§"
-
msgid "Markdown enabled"
msgstr "마í¬ë‹¤ìš´ 활성화ë¨"
@@ -12818,6 +13471,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12827,9 +13483,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12842,6 +13495,9 @@ msgstr "머지 리퀘스트(MR)"
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr "머지 리퀘스트(MR)"
@@ -12875,6 +13531,9 @@ msgstr "머지 리퀘스트(MR)"
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr "머지 리퀘스트(MR) 승ì¸"
@@ -12923,9 +13582,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
msgstr "MergeRequests | 답장 추가"
+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 ""
@@ -12986,7 +13654,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13004,6 +13672,9 @@ msgstr ""
msgid "Merged"
msgstr "머지ë¨"
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13025,9 +13696,6 @@ msgstr "메시지"
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13049,19 +13717,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr "측정 - Influx"
-
msgid "Metrics - Prometheus"
msgstr "측정 - Prometheus"
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13085,6 +13756,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13140,6 +13832,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13158,6 +13856,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13194,6 +13895,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13255,6 +13959,63 @@ msgstr "현재 ë¼ì´ì„¼ìŠ¤ì—서는 마ì¼ìŠ¤í†¤ 목ë¡ì„ 사용할 수 없습
msgid "Milestone lists show all issues from the selected milestone."
msgstr "마ì¼ìŠ¤í†¤ 목ë¡ì—는 ì„ íƒí•œ 마ì¼ìŠ¤í†¤ì˜ 모든 문제가 표시ë©ë‹ˆë‹¤."
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr "마ì¼ìŠ¤í†¤"
@@ -13264,6 +14025,12 @@ msgstr "마ì¼ìŠ¤í†¤ %{milestoneTitle}(ì„)를 ì˜êµ¬ížˆ 삭제하고 %{issuesWi
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr "마ì¼ìŠ¤í†¤ %{milestoneTitle}ì„ ì˜êµ¬ì ìœ¼ë¡œ 삭제하려고 합니다. ì´ ë§ˆì¼ìŠ¤í†¤ì€ ì–´ë– í•œ ì´ìŠˆ ë˜ëŠ” 머지 리퀘스트(MR)ì—ì„œë„ ì‚¬ìš©ë˜ì§€ 않습니다."
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr "마ì¼ìŠ¤í†¤ ì‚­ì œ"
@@ -13273,21 +14040,39 @@ msgstr "마ì¼ìŠ¤í†¤ ì‚­ì œ %{milestoneTitle}?"
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr "마ì¼ìŠ¤í†¤ì„ 삭제하지 못했습니다 %{milestoneTitle}"
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr "마ì¼ìŠ¤í†¤ %{milestoneTitle}를 ì°¾ì„ ìˆ˜ 없습니다"
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr "%{milestoneTitle} ì„(를) 그룹 마ì¼ìŠ¤í†¤ìœ¼ë¡œ 승격하시겠습니까?"
msgid "Milestones|Promote Milestone"
msgstr "마ì¼ìŠ¤í†¤ 승격"
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr "ì´ ë™ìž‘ì€ ë˜ëŒë¦´ 수 없습니다."
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13348,6 +14133,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr "취소"
@@ -13462,6 +14250,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr "여러 ì´ìŠˆ ë³´ë“œ"
@@ -13471,6 +14262,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13483,9 +14277,6 @@ msgstr "ì´ë¦„"
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr "새 ë¼ë²¨ ì´ë¦„ 지정"
@@ -13495,9 +14286,6 @@ msgstr "ì´ë¦„:"
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13531,6 +14319,54 @@ msgstr ""
msgid "Network"
msgstr "네트워í¬"
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr "절대 아님"
@@ -13559,6 +14395,9 @@ msgid "New Issue"
msgid_plural "New Issues"
msgstr[0] "새 ì´ìŠˆ"
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13625,6 +14464,9 @@ msgstr "새 ì´ìŠˆ"
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr "새 ë¼ë²¨"
@@ -13682,6 +14524,9 @@ msgstr ""
msgid "Next"
msgstr "다ìŒ"
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13700,18 +14545,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr "ë¼ë²¨ ì—†ìŒ"
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13802,12 +14638,18 @@ msgstr "파ì¼ì„ ì°¾ì„ ìˆ˜ 없습니다."
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr "그런 ì´ë¦„ ë˜ëŠ” 설명ì´ìžˆëŠ” ë ˆì´ë¸”ì´ ì—†ìŠµë‹ˆë‹¤."
@@ -13832,6 +14674,9 @@ msgstr "머지 리퀘스트(MR)를 ì°¾ì„ ìˆ˜ 없습니다."
msgid "No messages were logged"
msgstr "메시지가 기ë¡ë˜ì§€ 않았습니다."
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -13967,6 +14812,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -13991,6 +14839,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr "모든 í™œë™ ë³´ê¸°"
@@ -14105,9 +14956,15 @@ msgstr "11ì›”"
msgid "November"
msgstr "11ì›”"
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14174,6 +15031,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14183,9 +15049,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14250,7 +15113,7 @@ msgstr "프로ì íŠ¸ 구성ì›ë§Œ ëŒ“ê¸€ì„ ë‹¬ 수 있습니다."
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14295,8 +15158,8 @@ msgstr ""
msgid "Opened"
msgstr "열림"
-msgid "Opened MR"
-msgstr "열린 MR"
+msgid "Opened MRs"
+msgstr ""
msgid "Opened issues"
msgstr "열린 ì´ìŠˆ"
@@ -14310,6 +15173,9 @@ msgstr "새 창으로 열기"
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14340,7 +15206,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14388,6 +15254,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14406,6 +15275,9 @@ msgstr ""
msgid "Owner"
msgstr "소유ìž"
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14427,6 +15299,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr "패키지가 제거ë˜ì—ˆìŠµë‹ˆë‹¤."
@@ -14514,6 +15392,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14532,6 +15413,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14562,22 +15446,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14610,6 +15509,9 @@ msgstr ""
msgid "Packages"
msgstr "패키지"
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14697,6 +15599,9 @@ msgstr "비밀번호가 성공ì ìœ¼ë¡œ 변경ë˜ì—ˆìŠµë‹ˆë‹¤."
msgid "Password was successfully updated. Please login with it"
msgstr "비밀번호가 성공ì ìœ¼ë¡œ ì—…ë°ì´íŠ¸ë˜ì—ˆìŠµë‹ˆë‹¤. 새 비밀번호로 로그ì¸í•´ì£¼ì„¸ìš”."
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14715,6 +15620,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14757,9 +15665,15 @@ msgstr ""
msgid "Performance optimization"
msgstr "성능 최ì í™”"
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14781,9 +15695,6 @@ msgstr ""
msgid "Permissions"
msgstr "권한"
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14805,9 +15716,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -14916,6 +15824,9 @@ msgstr "ì§€ë‚œí•´ì˜ íŒŒì´í”„ë¼ì¸"
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -14976,15 +15887,24 @@ msgstr "ì´ í”„ë¡œì íŠ¸ëŠ” 현재 파ì´í”„ë¼ì¸ì„ 실행하ë„ë¡ ì„¤ì •ë˜ì
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -14997,30 +15917,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr "파ì´í”„ë¼ì¸ 실행"
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr "브랜치 검색"
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15036,6 +15980,9 @@ msgstr "파ì´í”„ë¼ì¸ 중지"
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr "#%{pipelineId} 파ì´í”„ë¼ì¸ì„ 중지하시겠습니까?"
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15072,6 +16019,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr "PlantUML"
@@ -15165,6 +16118,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15240,6 +16196,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr "환경 설정"
@@ -15330,6 +16289,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15366,6 +16328,9 @@ msgstr "페ì´ë¡œë“œ 미리보기"
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15585,9 +16550,6 @@ msgstr "ì´ë¦„"
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr "ë‚´ í”„ë¡œí•„ì— ë¹„ë°€ 기여 í¬í•¨"
@@ -15633,9 +16595,6 @@ msgstr "ì¡°ì§"
msgid "Profiles|Path"
msgstr "경로"
-msgid "Profiles|Personal Access"
-msgstr "ê°œì¸ ì—‘ì„¸ìŠ¤"
-
msgid "Profiles|Position and size your new avatar"
msgstr "새 아바타 위치 ë° í¬ê¸° ì¡°ì ˆ"
@@ -15780,12 +16739,6 @@ msgstr "ë‚˜ì˜ ìƒíƒœ"
msgid "Profiles|e.g. My MacBook key"
msgstr "예: 내 MacBook 키"
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15816,6 +16769,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15837,6 +16793,9 @@ msgstr "'%{project_name}'프로ì íŠ¸ê°€ 성공ì ìœ¼ë¡œ ì—…ë°ì´íŠ¸ë˜ì—ˆìŠµë‹
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15867,6 +16826,9 @@ msgstr "프로ì íŠ¸ 아바타"
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15891,8 +16853,8 @@ msgstr "프로ì íŠ¸ 내보내기가 ì‚­ì œë˜ì—ˆìŠµë‹ˆë‹¤."
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr "프로ì íŠ¸ 내보내기 ë§í¬ê°€ 만료ë˜ì—ˆìŠµë‹ˆë‹¤. 프로ì íŠ¸ 설정ì—ì„œ 새 내보내기를 ìƒì„±í•˜ì‹­ì‹œì˜¤."
-msgid "Project export started. A download link will be sent by email."
-msgstr "프로ì íŠ¸ 내보내기가 시작ë˜ì—ˆìŠµë‹ˆë‹¤. 다운로드 ë§í¬ëŠ” ì´ë©”ì¼ë¡œ 전송ë©ë‹ˆë‹¤."
+msgid "Project export started. A download link will be sent by email and made available on this page."
+msgstr ""
msgid "Project has too many %{label_for_message} to search"
msgstr ""
@@ -15900,6 +16862,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr "프로ì íŠ¸ ì´ë¦„"
@@ -16014,9 +16979,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16182,6 +17144,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16227,6 +17192,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16377,6 +17345,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16470,12 +17441,18 @@ msgstr "ìžë™ 설정"
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr "프로ì íŠ¸ í™˜ê²½ì„ ëª¨ë‹ˆí„°ë§í•˜ê¸° 위해 ë‹¹ì‹ ì˜ í´ëŸ¬ìŠ¤í„°ì— Prometheus를 ìžë™ìœ¼ë¡œ ë°°í¬í•˜ê³  설정하십시오."
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr "공통 메트릭스"
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16551,9 +17528,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr "프로ì íŠ¸ 마ì¼ìŠ¤í†¤ì„ 그룹 마ì¼ìŠ¤í†¤ìœ¼ë¡œ 승격합니다."
-msgid "Promote to Group Milestone"
-msgstr "그룹 마ì¼ìŠ¤í†¤ìœ¼ë¡œ 승격"
-
msgid "Promote to group label"
msgstr "그룹 ë¼ë²¨ë¡œ 승격"
@@ -16572,30 +17546,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr "다시 표시하지 않습니다."
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr "ì´ ê¸°ëŠ¥ì€ ìž ê²¨ìžˆìŠµë‹ˆë‹¤."
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr "업그레ì´ë“œ 플랜"
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16731,9 +17759,6 @@ msgstr "공개 - ì´ ê·¸ë£¹ê³¼ 모든 공개 프로ì íŠ¸ë“¤ì€ ì–´ë–¤ ì¸ì¦ ì—
msgid "Public - The project can be accessed without any authentication."
msgstr "공개 - ì´ í”„ë¡œì íŠ¸ëŠ” ì–´ë–¤ ì¸ì¦ ì—†ì´ë„ 접근할 수 있습니다."
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16743,6 +17768,12 @@ msgstr "공용 파ì´í”„ ë¼ì¸"
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr "Pull"
@@ -16845,6 +17876,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr "Quick actionì€ ì´ìŠˆ 설명ì´ë‚˜ 댓글 박스ì—ì„œ 사용 가능합니다."
@@ -16854,9 +17888,6 @@ msgstr ""
msgid "README"
msgstr "README"
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16893,9 +17924,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -16990,6 +18018,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr "관련 ë°°í¬ ëœ ìž‘ì—…"
@@ -17033,6 +18076,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17054,6 +18109,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17123,6 +18181,12 @@ msgstr ""
msgid "Remove group"
msgstr "그룹 제거"
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17165,6 +18229,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17204,6 +18271,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17255,6 +18325,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr "ì—픽 다시 열기"
@@ -17285,6 +18358,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17300,7 +18376,10 @@ msgstr ""
msgid "Repo by URL"
msgstr "저장소 URL"
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17403,6 +18482,9 @@ msgstr "저장소 설정"
msgid "Repository URL"
msgstr "저장소 URL"
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17439,6 +18521,9 @@ msgstr ""
msgid "Request Access"
msgstr "액세스 요청"
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17454,10 +18539,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17472,6 +18560,12 @@ msgstr "승ì¸í•˜ë ¤ë©´ ì‚¬ìš©ìž ë¹„ë°€ë²ˆí˜¸ê°€ 필요합니다."
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17493,10 +18587,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17564,6 +18655,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17576,6 +18670,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17721,6 +18821,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17784,9 +18887,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr "Runners 페ì´ì§€"
-
msgid "Runners page."
msgstr "Runners 페ì´ì§€."
@@ -17823,9 +18923,6 @@ msgstr ""
msgid "SSH Keys"
msgstr "SSH 키"
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -17955,9 +19052,15 @@ msgstr "검색"
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr "브랜치 검색"
@@ -18015,6 +19118,9 @@ msgstr "프로ì íŠ¸ 검색"
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr "ì‚¬ìš©ìž ê²€ìƒ‰"
@@ -18045,10 +19151,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18127,9 +19233,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr "비밀"
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr "보안"
@@ -18142,9 +19254,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr "보안 대시보드"
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18154,24 +19263,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18307,6 +19416,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18388,6 +19500,9 @@ msgstr "ì„ íƒ"
msgid "Select Archive Format"
msgstr "ì•„ì¹´ì´ë¸Œ í¬ë§· ì„ íƒ"
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18439,12 +19554,18 @@ msgstr "ëª¨ë‘ ì„ íƒ"
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr "기존 Kubernetes í´ëŸ¬ìŠ¤í„°ë¥¼ ì„ íƒí•˜ê±°ë‚˜ 새로 만듭니다."
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr "브랜치/태그 ì„ íƒ"
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18490,9 +19611,18 @@ msgstr ""
msgid "Select source branch"
msgstr "소스 브랜치 ì„ íƒ"
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr "ëŒ€ìƒ ë¸Œëžœì¹˜ ì„ íƒ"
@@ -18565,6 +19695,12 @@ msgstr ""
msgid "Send email"
msgstr "ì´ë©”ì¼ ì „ì†¡"
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18730,6 +19866,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr "웹 터미ë„ì˜ ìµœëŒ€ 세션 ì‹œê°„ì„ ì„¤ì •í•©ë‹ˆë‹¤."
@@ -18766,6 +19905,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18850,6 +19992,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18868,7 +20013,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -18907,15 +20052,15 @@ msgstr "ì…œë¡ íŠ¸ëžœì ì…˜"
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr "휴대í°ì„ 분실하거나 ì¼íšŒìš© ë¹„ë°€ë²ˆí˜¸ì— ì ‘ê·¼í•˜ì§€ 못하는 경우 ë‹¤ìŒ ë³µêµ¬ 코드를 한번씩 사용하여 ë‚´ ê³„ì •ì— ë‹¤ì‹œ 접근할 수 있습니다. 복구 코드를 안전한 ê³³ì— ë³´ê´€í•´ì£¼ì„¸ìš”. 그렇지 않으면 ê³„ì •ì— ì ‘ê·¼í•  수 %{b_start}없게%{b_end} ë©ë‹ˆë‹¤."
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -18940,12 +20085,21 @@ msgstr "완료 로그 표시"
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr "최신 버전 보기"
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -18965,6 +20119,13 @@ msgid "Showing %d event"
msgid_plural "Showing %d events"
msgstr[0] "%d ê°œì˜ ì´ë²¤íŠ¸ 표시 중"
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19151,6 +20312,9 @@ msgstr "스마트카드 ì¸ì¦ 실패: í´ë¼ì´ì–¸íŠ¸ ì¸ì¦ì„œ í—¤ë”ê°€ 잘ëª
msgid "Snippets"
msgstr "스니펫"
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19187,9 +20351,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19286,6 +20456,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19325,6 +20498,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19373,6 +20549,12 @@ msgstr "다ìŒìœ¼ë¡œ ì •ë ¬"
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr "권한 레벨, 오름차순"
@@ -19490,6 +20672,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19655,7 +20840,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19730,6 +20915,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19856,6 +21044,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr "í„°ë¯¸ë„ ì¤‘ì§€"
@@ -19883,6 +21074,9 @@ msgstr "저장소:"
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -19910,6 +21104,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20090,9 +21287,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20177,6 +21380,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr "스위치 브랜치/태그"
@@ -20204,9 +21410,6 @@ msgstr ""
msgid "System Hooks"
msgstr "시스템 훅"
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr "시스템 정보"
@@ -20457,6 +21660,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20539,9 +21745,6 @@ msgstr "해당 단계ì—ì„œ 수집 ëœ ë°ì´í„°ê°€ ì´ë²¤íŠ¸ 모ìŒì— 추가ë
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20578,9 +21781,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20618,6 +21827,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20792,6 +22004,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr "Staging 단계ì—서는 MR 머지과 프로ë•ì…˜ í™˜ê²½ì— ì½”ë“œ ë°°í¬ ì‚¬ì´ì˜ ì‹œê°„ì„ ë³´ì—¬ì¤ë‹ˆë‹¤. ë°ì´í„°ë¥¼ Production í™˜ê²½ì— ì²˜ìŒ ë°°í¬í•˜ë©´ ë°ì´í„°ê°€ ìžë™ìœ¼ë¡œ 추가ë©ë‹ˆë‹¤."
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr "테스트 단계ì—서는 GitLab CIê°€ 관련 머지 리퀘스트(MR)ì„ ìœ„í•´ 모든 파ì´í”„ë¼ì¸ì„ 실행하는 ë° ê±¸ë¦¬ëŠ” ì‹œê°„ì„ ë³´ì—¬ì¤ë‹ˆë‹¤. 첫 번째 파ì´í”„ë¼ì¸ ì‹¤í–‰ì´ ì™„ë£Œë˜ë©´ ë°ì´í„°ê°€ ìžë™ìœ¼ë¡œ 추가ë©ë‹ˆë‹¤."
@@ -20840,6 +22055,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -20915,6 +22133,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -20987,6 +22214,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr "ì‚¬ìš©ìž í™œë™ ìº˜ë¦°ë”를 로딩하는 ì¤‘ì— ì˜¤ë¥˜ê°€ ë°œìƒí•˜ì˜€ìŠµë‹ˆë‹¤."
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21050,6 +22280,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21134,6 +22367,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr "ì´ ë‚ ì§œëŠ” 마ê°ì¼ ì´í›„ì´ë¯€ë¡œ ì´ ì—í”½ì€ ë¡œë“œë§µì— ë‚˜íƒ€ë‚˜ì§€ 않습니다."
@@ -21173,6 +22409,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21218,9 +22457,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21332,7 +22568,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21359,6 +22595,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr "즉, 빈 저장소를 만들거나 기존 저장소를 가져올 때까지 코드를 Push 할 수 없습니다."
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr "ì´ ë¨¸ì§€ 리퀘스트(MR)는 잠겨있습니다."
@@ -21395,12 +22634,18 @@ msgstr "ì´ í”„ë¡œì íŠ¸"
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21413,12 +22658,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr "ì´ ì €ìž¥ì†Œ"
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21437,7 +22694,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21446,9 +22703,6 @@ msgstr "ì´ ì‚¬ìš©ìžëŠ” ì‹ ì›ì´ 없습니다."
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21503,9 +22757,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21752,6 +23012,9 @@ msgstr "지금"
msgid "Timeout"
msgstr "시간 초과"
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] "시간"
@@ -21814,6 +23077,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -21934,6 +23203,9 @@ msgstr "커밋 설명 토글"
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -21991,15 +23263,9 @@ msgstr "ì´ ê¸°ì—¬ë„"
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr "모든 커밋 / ë¨¸ì§€ì˜ ì´ í…ŒìŠ¤íŠ¸ 시간"
@@ -22015,9 +23281,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22036,6 +23299,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22147,6 +23413,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22204,10 +23473,10 @@ msgstr "URL"
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22216,6 +23485,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22255,6 +23527,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22264,9 +23539,15 @@ msgstr "ì°¨ì´ì ì„ ì½ì–´ë“¤ì¼ 수 없습니다. %{button_try_again}"
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22516,18 +23797,12 @@ msgstr "ì—…ë°ì´íŠ¸ì¤‘..."
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr "고급 글로벌 ê²€ìƒ‰ì„ í™œì„±í™”í•˜ê¸° 위해 í”Œëžœì„ ì—…ê·¸ë ˆì´ë“œí•˜ì„¸ìš”."
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr "ì°¸ì—¬ë„ ë¶„ì„ì„ í™œì„±í™”í•˜ê¸° 위해 í”Œëžœì„ ì—…ê·¸ë ˆì´ë“œí•˜ì„¸ìš”."
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22546,6 +23821,9 @@ msgstr "CSV íŒŒì¼ ì—…ë¡œë“œ"
msgid "Upload New File"
msgstr "새 íŒŒì¼ ì—…ë¡œë“œ"
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22564,6 +23842,9 @@ msgstr "업로드하려면 í´ë¦­í•˜ì‹­ì‹œì˜¤."
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr "터미ë„ì— ë³€ê²½ 사항 업로드 중"
@@ -22588,9 +23869,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr "ping ì‚¬ìš©ì´ í™œì„±í™” ë˜ì§€ 않았습니다."
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr "사용 통계"
@@ -22600,12 +23878,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22615,12 +23899,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22639,12 +23929,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22669,7 +23965,7 @@ msgstr "그룹 마ì¼ìŠ¤í†¤ì„ 사용하시면 여러 프로ì íŠ¸ì˜ ì´ìŠˆë“¤ì
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22744,9 +24040,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -22993,6 +24286,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23053,6 +24352,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23080,7 +24382,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23122,6 +24427,9 @@ msgstr ""
msgid "Version"
msgstr "버전"
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23166,6 +24474,9 @@ msgstr[0] ""
msgid "View file @ "
msgstr "파ì¼ë³´ê¸° @ "
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23229,6 +24540,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23310,9 +24624,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23343,9 +24654,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23454,6 +24762,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23466,6 +24777,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23487,7 +24801,13 @@ msgstr "ì´ ë‹¨ê³„ë¥¼ ë³´ì—¬ì£¼ê¸°ì— ì¶©ë¶„í•œ ë°ì´í„°ê°€ 없습니다."
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23529,9 +24849,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23571,12 +24888,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23611,9 +24937,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23647,9 +24970,6 @@ msgstr "Git ì ‘ê·¼"
msgid "WikiClone|Install Gollum"
msgstr "Gollum 설치"
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr "GFMì´ ë¡œì»¬ì—ì„œ ë Œë”ë§ ë˜ë„ë¡ %{markdown} 설치를 추천합니다."
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr "Gollumì„ ì‹œìž‘í•˜ê³  로컬 편집"
@@ -23770,10 +25090,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr "위키 페ì´ì§€"
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23782,10 +25105,10 @@ msgstr "액세스 요청 철회"
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -23902,6 +25225,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -23929,6 +25255,9 @@ msgstr "Kubernetes í´ëŸ¬ìŠ¤í„°ì— Runner를 쉽게 설치할 수 있습니다.
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -23944,6 +25273,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr "화살표 키를 사용하여 그래프를 움ì§ì¼ 수 있습니다."
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24022,6 +25354,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24070,6 +25405,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24085,7 +25423,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24178,6 +25516,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24205,6 +25546,9 @@ msgstr "모든 활ë™ì— 대한 ì•Œë¦¼ì„ ë°›ê²Œë©ë‹ˆë‹¤."
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr "ë‹¹ì‹ ì€ ë‹¹ì‹ ì´ @mentioned í•œ ì½”ë©˜íŠ¸ì— ëŒ€í•´ì„œë§Œ 통지를 받게ë©ë‹ˆë‹¤."
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr "ë‹¹ì‹ ì˜ ê³„ì •ì— %{set_password_link} ì„ í•˜ê¸° ì „ì—는 %{protocol} í”„ë¡œí† ì½œì„ í†µí•´ 프로ì íŠ¸ 코드를 Pull 하거나 Push í•  수 없습니다"
@@ -24223,6 +25567,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24256,7 +25606,10 @@ msgstr ""
msgid "YouTube"
msgstr "YouTube"
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24292,7 +25645,7 @@ msgstr ""
msgid "Your Groups"
msgstr "ë‚˜ì˜ ê·¸ë£¹"
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24385,9 +25738,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr "ë‹¹ì‹ ì˜ ê·¸ë£¹"
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24397,12 +25759,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr "ê·€í•˜ì˜ ì´ë¦„"
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24427,9 +25795,15 @@ msgstr ""
msgid "Your projects"
msgstr "ë‚´ 프로ì íŠ¸"
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24476,6 +25850,9 @@ msgstr ""
msgid "ago"
msgstr "ì „"
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24518,6 +25895,9 @@ msgstr ""
msgid "branch name"
msgstr "브랜치 ì´ë¦„"
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr "by"
@@ -24682,6 +26062,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24700,6 +26083,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24718,6 +26104,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr "SAST"
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24758,6 +26147,9 @@ msgstr[0] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24767,6 +26159,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24776,6 +26171,9 @@ msgstr ""
msgid "connecting"
msgstr "연결중"
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24825,6 +26223,9 @@ msgstr ""
msgid "done"
msgstr "완료"
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24835,7 +26236,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24868,10 +26272,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -24935,9 +26339,18 @@ msgstr "여기"
msgid "https://your-bitbucket-server"
msgstr "https://나ì˜-bitbucket-server"
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -24999,6 +26412,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25020,6 +26436,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25059,6 +26481,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25186,7 +26611,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr "ë°°í¬ í†µê³„ëŠ” ì•„ì§ ì‚¬ìš©í•  수 없습니다."
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25366,9 +26791,6 @@ msgstr "ì´ ë¨¸ì§€ 리퀘스트(MR)를 수ë™ìœ¼ë¡œ 머지할 수 있습니다."
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr "브랜치가 존재하지 않습니다."
@@ -25378,15 +26800,6 @@ msgstr "명령줄"
msgid "mrWidget|into"
msgstr "로"
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25399,6 +26812,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr "해당 ì—†ìŒ"
@@ -25444,6 +26860,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25473,9 +26892,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25496,6 +26924,12 @@ msgid "project"
msgid_plural "projects"
msgstr[0] "프로ì íŠ¸"
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25545,6 +26979,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25611,10 +27048,10 @@ msgstr "시작ë¨"
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25677,6 +27114,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr "ì‚¬ìš©ìž ì•„ë°”íƒ€"
@@ -25704,6 +27147,9 @@ msgstr "GitLabì—ì„œ 보기"
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25731,6 +27177,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr "%{additions} ê°œì˜ ì¶”ê°€, %{deletions} ê°œì˜ ì‚­ì œê°€ 있습니다."
diff --git a/locale/ku_TR/gitlab.po b/locale/ku_TR/gitlab.po
index 22c00156333..382100972bc 100644
--- a/locale/ku_TR/gitlab.po
+++ b/locale/ku_TR/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: ku\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:13\n"
+"PO-Revision-Date: 2020-06-08 15:17\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,13 +8991,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8627,7 +9009,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] ""
msgstr[1] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/mn_MN/gitlab.po b/locale/mn_MN/gitlab.po
index 3a745563dcd..fff5b0d9572 100644
--- a/locale/mn_MN/gitlab.po
+++ b/locale/mn_MN/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: mn\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:11\n"
+"PO-Revision-Date: 2020-06-08 15:18\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,13 +8991,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8627,7 +9009,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] ""
msgstr[1] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/nb_NO/gitlab.po b/locale/nb_NO/gitlab.po
index ca5cac0c94e..8088638cc5d 100644
--- a/locale/nb_NO/gitlab.po
+++ b/locale/nb_NO/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: nb\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:33\n"
+"PO-Revision-Date: 2020-06-08 15:13\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,13 +8991,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8627,7 +9009,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] ""
msgstr[1] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/nl_NL/gitlab.po b/locale/nl_NL/gitlab.po
index 97baedb5c41..f9b88574940 100644
--- a/locale/nl_NL/gitlab.po
+++ b/locale/nl_NL/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: nl\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:35\n"
+"PO-Revision-Date: 2020-06-08 15:18\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] "%d commit"
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr "%{commit_author_link} schreef %{commit_timeago}"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr "%{filePath} verwijderd"
msgid "%{firstLabel} +%{labelCount} more"
msgstr "%{firstLabel} +%{labelCount} meer"
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr "%{group_docs_link_start}Groepen%{group_docs_link_end} stellen u in staat
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr "%{loadingIcon} Gestart"
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr "%{lock_path} is vergrendeld door GitLab Gebruiker %{lock_user_id}"
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr "%{name};'s avatar"
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr "Voorwaarden accepteren"
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr "Toegangstokens"
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr "Actief"
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr "Activiteit"
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr "CI / CD"
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,13 +8991,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8627,7 +9009,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] "Nieuwe issue"
msgstr[1] "Nieuwe issues"
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/pa_IN/gitlab.po b/locale/pa_IN/gitlab.po
index 1b1d8f9bd99..eaca07a86a9 100644
--- a/locale/pa_IN/gitlab.po
+++ b/locale/pa_IN/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: pa-IN\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:35\n"
+"PO-Revision-Date: 2020-06-08 15:18\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,13 +8991,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8627,7 +9009,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] ""
msgstr[1] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/pl_PL/gitlab.po b/locale/pl_PL/gitlab.po
index b63db54190f..4287b3ba770 100644
--- a/locale/pl_PL/gitlab.po
+++ b/locale/pl_PL/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: pl\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:35\n"
+"PO-Revision-Date: 2020-06-08 15:19\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -80,6 +80,20 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -108,6 +122,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -139,6 +160,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -237,6 +265,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+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[3] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -279,6 +314,20 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -305,6 +354,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -390,6 +442,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -399,6 +454,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -411,6 +469,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -444,12 +526,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -465,6 +556,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -509,6 +606,12 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -668,6 +771,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -908,6 +1014,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -938,6 +1047,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -947,6 +1059,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -983,7 +1098,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -1034,6 +1152,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -1046,9 +1167,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -1094,9 +1212,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1187,12 +1302,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1229,7 +1338,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1238,6 +1347,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1284,7 +1396,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1299,6 +1411,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1308,9 +1423,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1326,7 +1447,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1392,6 +1516,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1482,16 +1609,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1818,6 +1945,15 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
@@ -1825,58 +1961,103 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
+msgstr ""
+
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1885,16 +2066,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -2068,6 +2267,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2233,9 +2435,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr "Wystąpił błąd podczas ładowania danych wykresu"
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2257,6 +2456,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2332,6 +2534,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2368,9 +2573,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2386,6 +2597,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2395,6 +2609,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2419,12 +2636,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2434,9 +2645,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2500,6 +2717,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2576,12 +2796,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2591,12 +2805,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2705,6 +2925,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2717,7 +2940,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2831,6 +3054,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2911,15 +3137,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2977,6 +3221,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2998,9 +3245,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -3019,6 +3263,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -3049,6 +3296,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -3064,6 +3314,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3541,16 +3794,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3574,7 +3827,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3583,6 +3836,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3601,6 +3857,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3631,9 +3890,6 @@ msgstr "Proces Automatyczny DevOps zostanie uruchomiony, jeśli nie zostanie zna
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3661,6 +3917,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3736,7 +3998,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3751,6 +4013,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3787,6 +4052,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3829,6 +4100,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3847,6 +4121,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3952,15 +4229,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4309,9 +4577,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4324,6 +4589,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4336,6 +4604,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4363,9 +4634,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4405,6 +4673,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4600,6 +4871,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4621,9 +4895,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4675,7 +4946,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4702,6 +4973,9 @@ msgstr "Włącz to ustawienie, jeśli używasz kontroli dostępu opartej na roli
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4780,12 +5054,12 @@ msgstr "Klaster grupowy"
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
+msgid "ClusterIntegration|Helm release failed to install"
+msgstr ""
+
msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr "Helm usprawnia instalację i zarządzanie aplikacjami Kubernetes. Tiller uruchamia się wewnątrz Klastra Kubernetes i zarządza publikacjami Twoich wykresów."
-msgid "ClusterIntegration|Hide"
-msgstr ""
-
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
msgstr "Jeśli konfigurujesz wiele klastrów i używasz Auto DevOps, %{help_link_start}zapoznaj się najpierw z tym%{help_link_end}."
@@ -4942,6 +5216,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5176,9 +5456,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5257,6 +5534,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5287,6 +5567,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5296,9 +5579,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5356,6 +5645,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5374,6 +5666,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5413,6 +5708,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5422,6 +5720,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5458,6 +5759,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5621,7 +5925,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5645,9 +5952,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5681,9 +5985,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5732,16 +6033,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5768,6 +6063,20 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5780,6 +6089,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5804,27 +6116,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5846,10 +6170,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5871,9 +6192,6 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5895,6 +6213,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5922,12 +6243,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5946,7 +6261,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5955,7 +6273,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5994,10 +6312,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -6084,6 +6402,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -6129,9 +6450,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6147,9 +6465,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6246,7 +6561,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6264,9 +6579,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6285,9 +6597,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6297,9 +6606,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6342,6 +6648,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6354,6 +6663,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6393,6 +6705,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6426,6 +6744,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6477,9 +6798,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6516,6 +6834,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6540,6 +6861,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6588,6 +6912,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6612,6 +6939,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6865,6 +7195,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6901,6 +7234,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6943,6 +7279,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -7034,13 +7376,6 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -7078,12 +7413,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -7093,9 +7422,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7216,12 +7542,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7243,13 +7575,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7369,10 +7701,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7381,9 +7713,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7393,6 +7740,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7420,12 +7770,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7435,6 +7800,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7447,6 +7818,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7676,6 +8050,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7724,6 +8101,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7748,6 +8128,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7895,6 +8278,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7910,6 +8296,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -8003,6 +8392,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -8012,9 +8404,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -8042,6 +8431,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8165,6 +8557,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8189,10 +8584,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8249,7 +8644,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8462,10 +8857,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8477,12 +8872,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8552,7 +8941,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8657,9 +9055,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8675,6 +9070,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8726,10 +9124,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8771,13 +9169,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8789,7 +9187,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8828,6 +9226,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8846,6 +9247,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8879,6 +9283,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8894,6 +9301,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8903,6 +9313,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8981,18 +9394,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -9119,6 +9520,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9194,7 +9598,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9257,6 +9661,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9269,6 +9679,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9278,15 +9691,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9305,6 +9727,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9320,9 +9745,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9413,6 +9844,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9425,6 +9859,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9434,9 +9871,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9452,24 +9886,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9479,6 +9934,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9710,9 +10168,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9752,15 +10207,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9938,6 +10393,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9947,10 +10408,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -10001,6 +10462,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -10052,6 +10519,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -10070,6 +10540,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -10079,6 +10552,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10331,9 +10810,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10367,9 +10843,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10532,12 +11005,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10571,6 +11053,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10583,10 +11071,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10604,10 +11095,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10625,12 +11119,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10697,9 +11197,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10901,6 +11398,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -11006,6 +11506,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -11015,6 +11518,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -11125,6 +11631,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -11134,6 +11643,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11284,6 +11796,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11293,7 +11808,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11302,6 +11820,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11314,7 +11838,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11332,13 +11859,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11350,6 +11877,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11359,6 +11889,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11368,10 +11901,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11464,10 +11997,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11500,6 +12033,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11533,6 +12069,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11557,18 +12099,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11621,6 +12181,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11660,6 +12244,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11696,18 +12286,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11720,6 +12319,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11783,6 +12385,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11795,6 +12400,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11852,6 +12484,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11897,6 +12532,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11909,19 +12568,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -12047,6 +12709,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -12086,6 +12751,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12267,6 +12935,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12351,6 +13022,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12372,9 +13046,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12402,6 +13073,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12414,6 +13088,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12438,15 +13115,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12589,6 +13260,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12604,6 +13278,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12701,6 +13378,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12815,10 +13495,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12845,6 +13525,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12896,9 +13579,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12908,9 +13588,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -13088,6 +13765,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -13097,9 +13777,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -13112,6 +13789,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -13145,6 +13825,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13193,9 +13876,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13256,7 +13948,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13274,6 +13966,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13295,9 +13990,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13319,19 +14011,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13355,6 +14050,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13413,6 +14129,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13431,6 +14153,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13467,6 +14192,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13531,6 +14259,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13540,6 +14325,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13549,21 +14340,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13624,6 +14433,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13738,6 +14550,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13747,6 +14562,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13759,9 +14577,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13771,9 +14586,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13807,6 +14619,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13838,6 +14698,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13904,6 +14767,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13961,6 +14827,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13979,18 +14848,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -14081,12 +14941,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -14111,6 +14977,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14246,6 +15115,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14270,6 +15142,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14384,9 +15259,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14453,6 +15334,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14462,9 +15352,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14532,7 +15419,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14577,7 +15464,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14592,6 +15479,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14622,7 +15512,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14670,6 +15560,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14688,6 +15581,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14709,6 +15605,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14796,6 +15698,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14814,6 +15719,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14844,22 +15752,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14892,6 +15815,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14979,6 +15905,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14997,6 +15926,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -15039,9 +15971,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -15063,9 +16001,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -15087,9 +16022,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15198,6 +16130,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15258,15 +16193,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15279,30 +16223,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15318,6 +16286,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15354,6 +16325,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15447,6 +16424,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15522,6 +16502,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15612,6 +16595,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15648,6 +16634,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15867,9 +16856,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15915,9 +16901,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -16062,12 +17045,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -16098,6 +17075,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -16119,6 +17099,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -16149,6 +17132,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -16173,7 +17159,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -16182,6 +17168,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16296,9 +17285,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16464,6 +17450,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16509,6 +17498,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16659,6 +17651,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16752,12 +17747,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16833,9 +17834,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16854,30 +17852,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -17013,9 +18065,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -17025,6 +18074,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -17127,6 +18182,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -17136,9 +18194,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -17175,9 +18230,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17275,6 +18327,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17321,6 +18388,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17342,6 +18421,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17411,6 +18493,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17453,6 +18541,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17492,6 +18583,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17543,6 +18637,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17573,6 +18670,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17588,7 +18688,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17694,6 +18797,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17730,6 +18836,9 @@ msgstr "Wybierz"
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17745,10 +18854,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
msgstr "Profile Żądań"
-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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17763,6 +18875,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17784,10 +18902,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17861,6 +18976,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17873,6 +18991,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -18021,6 +19145,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -18084,9 +19211,6 @@ msgstr "Robotnicy mogÄ… być przydzielani do oddzielnych użytkowników, serwerÃ
msgid "Runners currently online: %{active_runners_count}"
msgstr "Liczba Robotników online: %{active_runners_count}"
-msgid "Runners page"
-msgstr "Strona Robotników"
-
msgid "Runners page."
msgstr "Strona Robotników."
@@ -18123,9 +19247,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18255,9 +19376,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18315,6 +19442,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18345,10 +19475,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18457,9 +19587,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18472,9 +19608,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18484,24 +19617,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18637,6 +19770,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18718,6 +19854,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18769,12 +19908,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18820,9 +19965,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18895,6 +20049,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -19060,6 +20220,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -19096,6 +20259,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -19180,6 +20346,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -19198,7 +20367,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19237,15 +20406,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19270,12 +20439,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19298,6 +20476,16 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19484,6 +20672,9 @@ msgstr "Uwierzytelnianie karty inteligentnej nie powiodło się: brakuje nagłó
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19520,9 +20711,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19619,6 +20816,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19658,6 +20858,9 @@ msgstr "Coś poszło nie tak podczas rozwiązywania tej dyskusji. Spróbuj ponow
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19706,6 +20909,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19823,6 +21032,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19988,7 +21200,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -20063,6 +21275,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -20189,6 +21404,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -20216,6 +21434,9 @@ msgstr "Przechowywanie:"
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20243,6 +21464,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20423,9 +21647,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20510,6 +21740,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20537,9 +21770,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20793,6 +22023,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20878,9 +22111,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr "Połączenie upłynie po %{timeout}. W przypadku repozytoriów, którym zajmuje to dłużej, użyj kombinacji klonuj/pchnij."
@@ -20917,9 +22147,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20960,6 +22196,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -21134,6 +22373,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -21182,6 +22424,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21257,6 +22502,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21329,6 +22583,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21392,6 +22649,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21476,6 +22736,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21515,6 +22778,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21674,7 +22937,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21701,6 +22964,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21737,12 +23003,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21755,12 +23027,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21779,7 +23063,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21788,9 +23072,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21845,9 +23126,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -22094,6 +23381,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -22162,6 +23452,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22282,6 +23578,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22339,15 +23638,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22363,9 +23656,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22384,6 +23674,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22495,6 +23788,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22552,10 +23848,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22564,6 +23860,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22603,6 +23902,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22612,9 +23914,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22864,18 +24172,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22894,6 +24196,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22912,6 +24217,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22936,9 +24244,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22948,12 +24253,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22963,12 +24274,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22987,12 +24304,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -23017,7 +24340,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -23092,9 +24415,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23341,6 +24661,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23401,6 +24727,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23428,7 +24757,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23470,6 +24802,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23520,6 +24855,9 @@ msgstr[3] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23583,6 +24921,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23664,9 +25005,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23697,9 +25035,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23808,6 +25143,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23820,6 +25158,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23841,7 +25182,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23883,9 +25230,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23925,12 +25269,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23968,9 +25321,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -24004,9 +25354,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -24127,10 +25474,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -24139,10 +25489,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24259,6 +25609,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24286,6 +25639,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24301,6 +25657,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24379,6 +25738,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24427,6 +25789,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24442,7 +25807,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24535,6 +25900,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24562,6 +25930,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24580,6 +25951,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24613,7 +25990,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24649,7 +26029,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24742,9 +26122,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24754,12 +26143,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24784,9 +26179,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24836,6 +26237,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24878,6 +26282,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -25057,6 +26464,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -25075,6 +26485,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -25093,6 +26506,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -25136,6 +26552,9 @@ msgstr[3] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -25145,6 +26564,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -25154,6 +26576,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25206,6 +26631,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -25219,7 +26647,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -25252,10 +26683,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25322,9 +26753,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25389,6 +26829,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25410,6 +26853,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25449,6 +26898,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25579,7 +27031,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25759,9 +27211,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25771,15 +27220,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25792,6 +27232,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25837,6 +27280,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25872,9 +27318,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25901,6 +27356,12 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25953,6 +27414,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -26019,10 +27483,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -26085,6 +27549,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -26112,6 +27582,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -26139,6 +27612,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/pt_BR/gitlab.po b/locale/pt_BR/gitlab.po
index 156cac9c516..6ed3f217797 100644
--- a/locale/pt_BR/gitlab.po
+++ b/locale/pt_BR/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: pt-BR\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:33\n"
+"PO-Revision-Date: 2020-06-08 15:09\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] "%d comentário"
msgstr[1] "%d comentários"
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] "%d commit"
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] "%d contribuição"
msgstr[1] "%d contribuições"
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] "mais %d comentário"
msgstr[1] "mais %d comentários"
+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] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr "%{commit_author_link} fez commit %{commit_timeago}"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} núcleos"
@@ -316,6 +354,9 @@ msgstr "%{filePath} excluído"
msgid "%{firstLabel} +%{labelCount} more"
msgstr "%{firstLabel} +%{labelCount} mais"
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr "%{group_docs_link_start}Grupos%{group_docs_link_end} permitem que você
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr "%{group_name} usa contas gerenciadas por grupo. Você precisa criar uma nova conta do GitLab que será gerenciada por %{group_name}."
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr "%{icon}Você está prestes a adicionar %{usersTag} pessoas à discussão. Prossiga com cuidado."
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr "%{label_for_message} indisponível"
@@ -370,12 +438,21 @@ msgstr "%{loadingIcon} Iniciado"
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr "%{lock_path} está bloqueado pelo usuário do GitLab %{lock_user_id}"
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr "%{mrText}, essa issue foi fechada automaticamente."
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr "Avatar de %{name}"
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] "(%d fechado)"
msgstr[1] "(%d fechados)"
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr "(%{mrCount} merges realizados)"
@@ -782,6 +874,9 @@ msgstr "Por favor, contacte o administrador do GitLab se você acha que isso é
msgid "8 hours"
msgstr "8 horas"
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr "Membros do grupo <strong>%{group_name}</strong>"
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr "<strong>Apagar</strong> branch de origem"
@@ -821,6 +919,9 @@ msgstr "'Runner' é um processo que executa uma tarefa. Você pode configurar qu
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"
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr "Um site Gitbook que usa Netlify para CI/CD em vez do Gitlab, mas ainda com todas as outras ótimas funcionalidades do Gitlab."
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr "Um fork é uma cópia de um projeto.<br />Fork de um repositório permite que você faça alterações sem afetar o projeto original."
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr "Um token seguro que identifica uma requisição de armazenamento externo."
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr "Um usuário com permissão de escrita no branch de origem selecionou est
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr "Ajuda da API"
-
msgid "API Token"
msgstr "Token da API"
@@ -968,9 +1072,6 @@ msgstr "Aceitar os temos"
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr "MR aceito"
-
msgid "Access Tokens"
msgstr "Tokens de acesso"
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr "redefini-lo"
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,8 +1198,8 @@ msgstr "Ativar Central de Serviços"
msgid "Active"
msgstr "Ativo"
-msgid "Active %{type} Tokens (%{token_length})"
-msgstr "Tokens %{type} ativo (%{token_length})"
+msgid "Active %{type} (%{token_length})"
+msgstr ""
msgid "Active Sessions"
msgstr "Sessões ativas"
@@ -1112,6 +1207,9 @@ msgstr "Sessões ativas"
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr "Atividade"
@@ -1156,8 +1254,8 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
-msgstr "Adicione um token %{type}"
+msgid "Add a %{type}"
+msgstr ""
msgid "Add a GPG key"
msgstr "Adicionar chave GPG"
@@ -1171,6 +1269,9 @@ msgstr "Adicionar um afazer"
msgid "Add a bullet list"
msgstr "Adicionar uma lista de marcadores"
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr "Adicionar um comentário geral para este %{noteableDisplayName}."
@@ -1180,9 +1281,15 @@ msgstr "Adicionar um comentário geral para este %{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 "Adicione uma homepage ao seu wiki que contenha informações sobre o seu projeto e o GitLab irá exibi-lo aqui ao invés desta mensagem."
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr "Adicionar um link"
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr "Adicionar uma lista numerada"
@@ -1198,7 +1305,10 @@ msgstr "Coloque um texto adicional para aparecer em todas as comunicações por
msgid "Add an SSH key"
msgstr "Adicionar chave SSH"
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr "Adicionar reação"
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,18 +1467,18 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr "Ãrea do Administrador"
+msgid "Admin Note"
+msgstr ""
+
msgid "Admin Overview"
msgstr "Visão Geral do Administrador"
-msgid "Admin Section"
-msgstr "Seção de Admin"
-
msgid "Admin mode already enabled"
msgstr ""
@@ -1690,63 +1803,117 @@ msgstr "Após uma atualização de senha bem-sucedida, você será redirecionado
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr "Após uma atualização de senha bem sucedida, você será redirecionado para a página de login onde você pode entrar com sua nova senha."
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] "Alerta"
msgstr[1] "Alertas"
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Low"
+msgstr ""
+
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|Unknown"
+msgstr ""
+
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr "Um aplicativo chamado %{link_to_client} está solicitando acesso à sua conta do 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 ""
+
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 "Um campo vazio do usuário do GitLab adicionará o nome completo do usuário do FogBugz (por exemplo, \"Por John Smith\") na descrição de todos os issues e comentários. Ele também irá associar e/ou atribuir essas issues e comentários ao criador do projeto."
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr "Ocorreu um erro ao carregar os dados do gráfico"
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr "Erro ao carregar as assinaturas de commit"
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr "Ocorreu um erro ao salvar as configurações de aprovação"
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr "Ocorreu um erro ao inscrever às notificações."
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr "Um issue pode ser um bug, um afazer ou uma solicitação de recurso que precisa ser discutida em um projeto. Além disso, os issues são pesquisáveis e filtráveis."
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr "Um erro inesperado ocorreu enquanto verificava o ambiente de projeto."
@@ -2256,6 +2453,9 @@ msgstr "Ocorreu um erro inesperado ao iniciar o terminal da web."
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 ""
+
msgid "Analytics"
msgstr "Telemetria"
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr "Qualquer um"
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr "Qualquer etiqueta"
-
-msgid "Any Milestone"
-msgstr "Qualquer marco"
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr "Qualquer tokens criptografados"
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr "Qualquer namespace"
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr "Aplicar sugestão"
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr "por exemplo, QA, segurança, etc."
-msgid "Approvals"
-msgstr "Aprovações"
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr "Você tem certeza que quer remover %{group_name}?"
msgid "Are you sure you want to remove the attachment?"
msgstr "Você deseja mesmo remover o anexo?"
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr "Você tem certeza de que deseja excluir este item?"
@@ -2579,8 +2788,8 @@ msgstr "Tem certeza de que deseja redefinir o token SCIM? O provisionamento SCIM
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 revoke this %{type} Token? This action cannot be undone."
-msgstr "Tem certeza de que deseja revogar este Token %{type}? Essa ação não pode ser desfeita."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
+msgstr ""
msgid "Are you sure you want to revoke this nickname?"
msgstr ""
@@ -2693,6 +2902,9 @@ msgstr "Problemas Atribuídos"
msgid "Assigned Merge Requests"
msgstr "Merge requests com responsável"
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr "Atribuído a mim"
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr "Ago"
@@ -2835,6 +3065,9 @@ msgstr "Autorizar"
msgid "Authorize %{link_to_client} to use your account?"
msgstr "Autorizar %{link_to_client} usar sua conta?"
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr "%{new_chat_name} autorizado"
@@ -2856,9 +3089,6 @@ msgstr "Auto DevOps ativo"
msgid "Auto DevOps, runners and job artifacts"
msgstr "Auto DevOps, runners e artefatos de tarefas"
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr "Documentação de auto DevOps"
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr "Habilitar nas configurações"
@@ -2907,6 +3140,9 @@ msgstr "Gerenciamento automático de certificado usando %{lets_encrypt_link_star
msgid "Automatic certificate management using Let's Encrypt"
msgstr "Gerenciamento automático de certificado usando Let's Encrypt"
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr "Marcado automaticamente como interno de usuário padrão"
@@ -2922,6 +3158,9 @@ msgstr "Nota"
msgid "Available"
msgstr "Disponível"
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr "Runners de grupo disponíveis: %{runners}"
@@ -3399,17 +3638,17 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
+msgid "Burnup chart"
+msgstr ""
+
msgid "Business"
msgstr "Negócios"
msgid "Business metrics (Custom)"
msgstr "Métricas de negócios (personalizadas)"
-msgid "Buy EE"
-msgstr "Comprar EE"
-
-msgid "Buy GitLab Enterprise Edition"
-msgstr "Comprar GitLab Edição Enterprise"
+msgid "Buy License"
+msgstr ""
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -3432,8 +3671,8 @@ msgstr "CHANGELOG"
msgid "CI / CD"
msgstr "CI / CD"
-msgid "CI / CD Charts"
-msgstr "Gráficos CI / CD"
+msgid "CI / CD Analytics"
+msgstr ""
msgid "CI / CD Settings"
msgstr "Configurações de CI / CD"
@@ -3441,6 +3680,9 @@ msgstr "Configurações de CI / CD"
msgid "CI Lint"
msgstr "Checar syntaxe de CI"
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr "Variáveis de CI"
@@ -3459,6 +3701,9 @@ msgstr "CI/CD para um repositório externo"
msgid "CI/CD settings"
msgstr "Configurações de CI/CD"
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr "Auto DevOps"
@@ -3489,9 +3734,6 @@ msgstr "O pipeline de Auto DevOps será executado se nenhum arquivo de configura
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr "grupo habilitado"
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr "Pode substituir aprovadores e aprovações necessárias por merge request"
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr "Não é possível encontrar o commit HEAD para este branch"
@@ -3594,8 +3842,8 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
-msgstr "Não é possível se referir a um marco de grupo por um Id interno!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
+msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
msgstr ""
@@ -3609,6 +3857,9 @@ msgstr "Não é possível ignorar a configuração de autenticação de dois fat
msgid "Capacity threshold"
msgstr "Limite de capacidade"
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr "Certificado"
@@ -3645,6 +3896,12 @@ msgstr "Alterar caminho"
msgid "Change permissions"
msgstr "Alterar permissões"
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr "Mudar modelo"
@@ -3687,6 +3944,9 @@ msgstr "Alterações"
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr "Mudanças serão mostradas se revisão de <b>origem</b> tiver sofrido merge na revisão <b>alvo</b>."
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr "Falha na validação"
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr "Etiqueta de Classificação (opcional)"
@@ -4182,6 +4433,9 @@ msgstr "Limpar"
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr "Limpar entrada"
@@ -4194,6 +4448,9 @@ msgstr "Limpar Pesquisa"
msgid "Clear search input"
msgstr "Limpar campo de pesquisa"
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr "Clique no botão à direita <strong>Selecionar nenhum</strong>, uma vez
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr "Clique no botão abaixo para iniciar o processo de instalação navegando para a página do Kubernetes"
-msgid "Click the image where you'd like to start a new discussion"
-msgstr "Clique na imagem onde você gostaria de iniciar uma nova discussão"
-
msgid "Click to expand it."
msgstr "Clique para expandir."
@@ -4263,6 +4517,9 @@ msgstr "Clonar com SSH"
msgid "Close"
msgstr "Fechar"
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr "Fechar %{tabname}"
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr "O nome do cluster é obrigatório."
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr "Clusters são utilizados selecionando o ancestral mais próximo de um ambiente de escopo correspondente. Por exemplo, projeto de clusters vai substituir grupo de clusters."
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr "Copiar nome do cluster Kubernetes"
-msgid "ClusterIntegration|Copy Service Token"
-msgstr "Copiar Token de Serviço"
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr "Habilite esta configuração se estiver usando o controle de acesso base
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,12 +4898,12 @@ msgstr "Cluster de grupo"
msgid "ClusterIntegration|Helm Tiller"
msgstr "Helm Tiller"
+msgid "ClusterIntegration|Helm release failed to install"
+msgstr ""
+
msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr "Helm simplifica a instalação e o gerenciamento de aplicativos do Kubernetes. O Tiller é executado dentro do seu Kubernetes Cluster e gerencia os lançamentos de seus gráficos."
-msgid "ClusterIntegration|Hide"
-msgstr "Ocultar"
-
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
msgstr "Se você está configurando múltiplos clusters e você está usando auto DevOps, %{help_link_start}leia isso primeiro%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr "Mostrar"
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr "Alguma coisa deu errado do nosso lado."
@@ -5115,6 +5378,9 @@ msgstr "Alternar cluster Kubernetes"
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr "Desinstalar %{appTitle}"
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr "Você deve primeiro instalar o Helm Tiller antes de instalar os aplicativos abaixo"
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr "Sua conta precisa de %{link_to_kubernetes_engine}"
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr "Código"
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr "A aprovação do proprietário do código é obrigatória"
@@ -5271,6 +5552,9 @@ msgstr "Recolher aprovadores"
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr "Minimizar barra lateral"
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr "ComboSearch não está definido"
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr "Comando"
@@ -5316,6 +5603,9 @@ msgstr "Posição do formulário de comentários"
msgid "Comment is being updated"
msgstr "O comentário está sendo atualizado"
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr "Comentar/Responder (citando o texto selecionado)"
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr "Configurar Let's Encrypt"
msgid "Configure Prometheus"
msgstr "Configurar Prometheus"
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr "Configurar rastreamento"
@@ -5537,9 +5827,6 @@ msgstr "Definir configurações do caminho de armazenamento."
msgid "Configure the %{link} integration."
msgstr "Configure a integração de %{link}."
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr "Configurar a forma como o usuário cria uma nova conta."
@@ -5588,17 +5875,11 @@ msgstr "Falha na conexão"
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr "Entre em contato com um proprietário do grupo %{namespace_name} para atualizar o plano."
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr "Entre em contato com o proprietário %{link_start}%{owner_name}%{link_end} para atualizar o plano."
-
msgid "Contact sales to upgrade"
msgstr "Entre em contato com o departamento de vendas para atualizar"
-msgid "Contact your Administrator to upgrade your license."
-msgstr "Entre em contato com seu administrador para atualizar sua licença."
+msgid "Contact support"
+msgstr ""
msgid "Container Registry"
msgstr "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr "Início rápido"
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr "Tag"
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr "Contribuições"
msgid "Contribution Analytics"
msgstr "Análise de contribuição"
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr "Copiar URL de Clone do %{protocol}"
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr "Copiar link"
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr "Criar"
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr "Crie uma conta do GitLab primeiro e em seguida conecte-a à sua conta %{
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr "Criar uma nova issue"
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr "Criar um novo repositório"
@@ -6151,9 +6442,6 @@ msgstr "Crie um token de acesso pessoal na sua conta para dar pull ou push via %
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr "Crie um issue. Os Issues são criados para cada alerta acionado."
@@ -6196,6 +6484,9 @@ msgstr "Criar etiqueta de grupo"
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr "Criar lista a partir de etiquetas. Issues com etiquetas aparecem nestas listas."
@@ -6208,6 +6499,9 @@ msgstr "Abrir merge request e criar branch"
msgid "Create milestone"
msgstr "Criar marco"
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr "Crie sua primeira página"
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr "Você não tem permissão para criar um subgrupo neste grupo."
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr "Criado por mim"
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr "Fuso horário do cron"
-msgid "Cron syntax"
-msgstr "Sintaxe do cron"
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr "Configurações"
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr "Modelos de projeto personalizados não foram configurados para grupos do
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr "Adicionar um estágio"
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr "Personalizar cores"
@@ -6466,6 +6775,9 @@ msgstr "Personalize a sua configuração, visualize o status da pipeline e relat
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr "Etiqueta de classificação padrão"
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr "Padrão: Mapeie uma ID de conta do FogBugz para um nome completo"
msgid "Define a custom pattern with cron syntax"
msgstr "Defina um padrão personalizado utilizando a sintaxe do cron"
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr "Excluir comentário"
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr "Excluir licença"
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr "Localização"
msgid "Dependencies|Packager"
msgstr "Empacotador"
-msgid "Dependencies|Safe"
-msgstr "Segura"
-
-msgid "Dependencies|Status"
-msgstr "Status"
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr "A tarefa %{codeStartTag}dependency_scanning%{codeEndTag} falhou e não pode gerar a lista. Certifique-se de que a tarefa esteja funcionando corretamente e execute o pipeline novamente."
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr "Arquivo(s) não suportado(s) detectado(s)"
-msgid "Dependencies|Version"
-msgstr "Versão"
-
msgid "Dependencies|Vulnerable components"
msgstr "Componentes vulneráveis"
@@ -7056,12 +7366,18 @@ msgstr "Tokens de deploy ativos (%{active_tokens})"
msgid "DeployTokens|Add a deploy token"
msgstr "Adicionar um token de deploy"
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr "Permite acesso somente-leitura às imagens do registry"
msgid "DeployTokens|Allows read-only access to the repository"
msgstr "Permite acesso somente-leitura ao repositório"
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr "Tokens de deploy"
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr "Expira"
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,21 +7525,36 @@ msgstr "%{current_design} de %{designs_count}"
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
-msgstr "Adicionar designs"
-
msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr "Adicionar um design com o mesmo nome de arquivo substitui o arquivo por uma nova versão."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
+msgstr ""
+
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr "Ir para o próximo design"
msgid "DesignManagement|Go to previous design"
msgstr "Ir para o design anterior"
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr "A versão de design solicitada não existe. Mostrando a versão mais recente como alternativa"
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr "Designs"
msgid "Destroy"
msgstr "Destruir"
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr "Detalhes"
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr "Não cole a parte privada da chave GPG. Cole a parte pública que começa com '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
@@ -7562,6 +7923,9 @@ msgstr "Baixar imagem"
msgid "Download license"
msgstr "Baixar licença"
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr "Baixar código-fonte"
@@ -7586,6 +7950,9 @@ msgstr "Votos negativos"
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr "Validade"
@@ -7733,6 +8100,9 @@ msgstr "E-mail"
msgid "Email address"
msgstr "Endereço de e-mail"
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr "Ativar autenticação SAML para esse grupo"
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr "Habilitar acesso ao Grafana"
@@ -7850,9 +8226,6 @@ msgstr "Ativa o acesso à barra de desempenho para um determinado grupo."
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr "Habilitar e configurar métricas InfluxDB."
-
msgid "Enable and configure Prometheus metrics."
msgstr "Ativar e configurar métricas do Prometheus."
@@ -7880,6 +8253,9 @@ msgstr "Ativar grupo de runners"
msgid "Enable header and footer in emails"
msgstr "Ativar cabeçalho e rodapé em e-mails"
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr "Digite a descrição do merge request"
msgid "Enter the merge request title"
msgstr "Digite o título do merge request"
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr "Tarefa: %{job}"
msgid "EnvironmentsDashboard|More actions"
msgstr "Mais ações"
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,11 +8679,11 @@ msgstr "Epics permitem gerenciar seu portfólio de projetos de forma mais eficie
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
-msgstr "Adicionar um épico"
+msgid "Epics|Add a new epic"
+msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
-msgstr "Adicionar um épico existente como um épico filho."
+msgid "Epics|Add an existing epic"
+msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
msgstr "Ocorreu um erro ao salvar a data de %{epicDateType}"
@@ -8315,12 +8694,6 @@ msgstr ""
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}?"
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr "Crie um épico dentro deste grupo e adicione-o como um épico filho."
-
-msgid "Epics|Create new epic"
-msgstr "Criar novo épico"
-
msgid "Epics|How can I solve this?"
msgstr "Como posso resolver isso?"
@@ -8390,8 +8763,17 @@ msgstr "Erro ao criar epic"
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr "Erro ao excluir %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
+msgstr ""
msgid "Error deleting project. Check logs for error details."
msgstr ""
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr "Erro ao renderizar a pré-visualização do markdown"
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr "Erro ao salvar alteração de etiqueta."
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr "Erro ao enviar o arquivo"
@@ -8564,12 +8946,12 @@ msgstr "Erros"
msgid "Errors:"
msgstr ""
+msgid "Estimate"
+msgstr ""
+
msgid "Estimated"
msgstr "Estimativa"
-msgid "Event Actions"
-msgstr ""
-
msgid "EventFilterBy|Filter by all"
msgstr "Filtrar por tudo"
@@ -8609,14 +8991,14 @@ msgstr "Cada tentativa de %{action} falhou: %{job_error_message}. Por favor, ten
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
-msgstr "Todos os dias (às 4:00)"
+msgid "Every day (at %{time})"
+msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
-msgstr "Todos os meses (no dia primeiro às 4:00)"
+msgid "Every month (Day %{day} at %{time})"
+msgstr ""
msgid "Every three months"
msgstr ""
@@ -8627,8 +9009,8 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
-msgstr "Toda semana (domingos às 4:00)"
+msgid "Every week (%{weekday} at %{time})"
+msgstr ""
msgid "Everyone"
msgstr "Todos"
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr "Membros e grupos existentes"
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr "Expandir barra lateral"
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr "Expirado"
msgid "Expired %{expiredOn}"
msgstr "Expirou %{expiredOn}"
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr "Expira"
@@ -8741,6 +9135,9 @@ msgstr "Expira em"
msgid "Expires in %{expires_at}"
msgstr "Expira em %{expires_at}"
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr "Etiqueta de classificação"
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr "Quando nenhum etiqueta de classificação está definida, a etiqueta padrão `%{default_label}` será usada."
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr "Adicione um botão ao dashboard de métricas vinculado diretamente aos seus dashboards externos existentes."
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr "Digite a URL do dashboard ao qual você deseja vincular"
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr "Dashboard externo"
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr "URL completa de dashboard"
-
msgid "ExternalWikiService|External Wiki"
msgstr "Wiki externo"
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr "Descrição"
msgid "FeatureFlags|Edit Feature Flag"
msgstr "Editar feature flag"
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr "Especificações do Ambiente"
msgid "FeatureFlags|Feature Flag"
msgstr "Feature flag"
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr "O comportamento de Feature flag é feito ao criar uma série de regras para definir o status de ambientes alvo. Um regra padrão de curinga %{codeStart}*%{codeEnd} para %{boldStart}Todos os Ambientes%{boldEnd} e você poderá adicionar quantas regras você precisar, escolhendo as especificações de ambiente abaixo. Você pode alternar o comportamento para cada uma de suas regras para configurá-los como %{boldStart}Ativo%{boldEnd} ou %{boldStart}Inativo%{boldEnd}."
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr "Feature flags"
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr "A feature flag %{name} será removido. Você tem certeza?"
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr "Feature flags permitem que você configure o seu código em diferentes versões alterando dinamicamente determinada funcionalidade."
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr "Começar a usar feature flags"
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr "Instale uma %{docs_link_anchored_start}biblioteca de cliente compatível
msgid "FeatureFlags|Instance ID"
msgstr "ID da instância"
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr "Carregando feature flags"
@@ -9158,9 +9567,15 @@ msgstr "Novo"
msgid "FeatureFlags|New Feature Flag"
msgstr "Nova feature flag"
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr "Nova feature flag"
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr "Porcentagem de rollout (usuários logados)"
@@ -9251,6 +9666,9 @@ msgstr "Navegador de arquivos"
msgid "File deleted"
msgstr "Arquivo excluído"
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr "Arquivo movido"
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr "Modelos de arquivos"
msgid "File upload error."
msgstr "Erro ao enviar arquivo."
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr "Arquivos"
@@ -9290,24 +9708,45 @@ msgstr "Preencha nos campos abaixo, ative o <strong>%{enable_label}</strong> e p
msgid "Filter"
msgstr "Filtro"
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr "Filtrar por %{issuable_type} que estão atualmente fechados."
msgid "Filter by %{issuable_type} that are currently opened."
msgstr "Filtrar por %{issuable_type} que estão atualmente abertos."
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr "Filtrar por mensagem de commit"
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr "Filtrar por nome de marco"
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr "Filtrar por autenticação de dois fatores"
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ 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"
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr "Na visualização de detalhes do cluster do Kubernetes, instale o Runner pela lista de aplicativos"
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr "Geo"
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr "Nós do Geo"
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr "%{name} está agendado para forçar download novamente"
@@ -9785,10 +10230,10 @@ msgstr "%{name} está agendado para re-sincronização"
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
-msgstr "Todos"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr "Nunca"
msgid "Geo|Next sync scheduled at"
msgstr "Próxima sincronização programada às"
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr "Ainda não sincronizado"
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr "Status"
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr "O registro de rastreamento do projeto (%{project_id}) foi removido com Ã
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr "Estado desconhecido"
@@ -10169,9 +10632,6 @@ msgstr "URL do host do Gitea"
msgid "Gitea Import"
msgstr "Importação do Gitea"
-msgid "Gitlab CI/CD"
-msgstr "GitLab CI/CD"
-
msgid "Gitlab Pages"
msgstr "GitLab Pages"
@@ -10205,9 +10665,6 @@ msgstr "Volte para %{startTag}Issues abertos%{endTag} e selecione alguns issues
msgid "Go full screen"
msgstr "Tela cheia"
-msgid "Go to"
-msgstr "Ir para"
-
msgid "Go to %{link_to_google_takeout}."
msgstr "Ir para %{link_to_google_takeout}."
@@ -10370,12 +10827,21 @@ msgstr "Gravatar habilitado"
msgid "Group"
msgstr "Grupo"
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr "O grupo %{group_name} foi agendado para exclusão."
msgid "Group %{group_name} was successfully created."
msgstr "O grupo %{group_name} foi criado com sucesso."
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr "URL do grupo"
msgid "Group avatar"
msgstr "Avatar do grupo"
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr "Descrição do grupo"
@@ -10421,10 +10893,13 @@ msgstr "Detalhes do grupo"
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr "Os mantenedores podem registrar grupos de runners em %{link}"
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr "Nome do grupo"
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr "Os minutos do pipeline do grupo foram redefinidos com sucesso."
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr "O grupo foi atualizado com sucesso."
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr "não pode ser desativado quando a configuração \"Travar compartilhamento de grupo\" está ativada, a não ser pelo dono do grupo pai"
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr "Tem o e-mail de seus usuários"
@@ -10853,6 +11340,9 @@ msgstr "O logo do cabeçalho foi removido com sucesso."
msgid "Header message"
msgstr "Mensagem de cabeçalho"
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr "Histórico"
msgid "History of authentications"
msgstr "Histórico de autenticações"
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr "A execução do hook falhou. Certifique-se de que o grupo tenha um projeto com commits."
@@ -10968,6 +11461,9 @@ msgstr "O Hook foi criado com sucesso."
msgid "Hook was successfully updated."
msgstr "O Hook foi atualizado com sucesso."
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr "Se ativado, o acesso aos projetos será validado em um serviço externo
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr "Se estiver usando o GitHub, você verá os status do pipeline no GitHub para seus commits e pull requests. %{more_info_link}"
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,15 +11677,15 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
+msgid "Impersonation Tokens"
+msgstr ""
+
msgid "Impersonation has been disabled"
msgstr ""
msgid "Import"
msgstr "Importar"
-msgid "Import %{status}"
-msgstr ""
-
msgid "Import CSV"
msgstr "Importar CSV"
@@ -11184,6 +11695,9 @@ msgstr "Importar projetos do Gitea"
msgid "Import all compatible projects"
msgstr "Importar todos os projetos compatíveis"
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr "Importar todos os projetos"
@@ -11193,6 +11707,9 @@ msgstr "Importar todos repositórios"
msgid "Import an exported GitLab project"
msgstr "Importar um projeto GitLab exportado"
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,12 +11719,12 @@ msgstr ""
msgid "Import in progress"
msgstr "Importação em andamento"
+msgid "Import in progress. Refresh page to see newly added issues."
+msgstr ""
+
msgid "Import issues"
msgstr "Importar issues"
-msgid "Import issues from Jira"
-msgstr ""
-
msgid "Import members"
msgstr "Importar membros"
@@ -11298,12 +11815,12 @@ msgstr "Melhore os painéis com GitLab Enterprise Edition."
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
-msgstr "Melhore o gerenciamento de issues com o peso de issues e GitLab Enterprise Edition."
-
msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr "Melhore a pesquisa com Advanced Global Search e GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
+msgstr ""
+
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
msgstr "Para ativar a análise no nível da instância, peça a um administrador para ativar o %{usage_ping_link_start}dados de uso%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr "Inclua um contrato de Termos de Serviço e uma Política de Privacidade
msgid "Include author name in notification email body"
msgstr "Incluir o nome do autor no corpo do e-mail de notificação"
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr "Incluir a descrição do merge request"
@@ -11367,6 +11887,12 @@ msgstr "Projeto Incompatível"
msgid "Incompatible options set!"
msgstr "Opções incompatíveis definidas!"
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr "Indexar todos os projetos"
@@ -11391,18 +11917,36 @@ msgstr "Insira as chaves do host manualmente"
msgid "Input your repository URL"
msgstr "Insira seu URL do repositório"
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr "Inserir uma citação"
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr "Inserir código"
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr "Inserir sugestão"
msgid "Insights"
msgstr "Insights"
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr "Instalar"
@@ -11453,6 +11997,30 @@ msgstr "Integrações"
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr "As partes interessadas podem até contribuir enviando commits, caso queiram."
@@ -11492,6 +12060,12 @@ msgstr "Login ou senha inválidos"
msgid "Invalid URL"
msgstr "URL inválida"
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr "Código PIN inválido"
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr "Caminho de repositório inválido"
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr "Código de dois fatores inválido."
@@ -11552,6 +12135,9 @@ msgstr "Convidar"
msgid "Invite \"%{trimmed}\" by email"
msgstr "Convidar \"%{trimmed}\" por e-mail"
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr "Convidar grupo"
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr "Modelo de issue (opcional)"
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr "Painel"
@@ -11684,6 +12300,9 @@ msgstr "Issues fechadas"
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+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"
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr "É você"
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr "URL Jaeger"
@@ -11741,19 +12384,22 @@ msgstr "Jan"
msgid "January"
msgstr "Janeiro"
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr "Os artefatos foram removidos"
msgid "Job|The artifacts will be removed"
msgstr "Os artefatos serão removidos"
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr "Esta tarefa falhou porque os recursos necessários não foram criados com sucesso."
@@ -11918,6 +12567,9 @@ msgstr "Junho"
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
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 ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr "Saiba mais sobre o Terminal Web"
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr "Saiba mais sobre assinar commits"
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr "Saiba mais em"
@@ -12232,6 +12887,9 @@ msgstr "Sair do projeto"
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr "Deixe as opções \"Tipo de arquivo\" e \"Método de entrega\" em seus valores padrão."
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr "O Let's Encrypt não aceita e-mails de example.com"
@@ -12244,6 +12902,9 @@ msgstr "Licença"
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr "Limita a exibição de unidades de acompanhamento de tempo a horas."
@@ -12521,6 +13182,9 @@ msgstr "Carregando..."
msgid "Loading…"
msgstr "Carregando…"
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr "Localização"
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr "Certifique-se de que você está conectado à conta que possui os projetos que você deseja importar."
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr "Gerenciar etiquetas de grupo"
msgid "Manage labels"
msgstr "Gerenciar etiquetas"
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr "Gerenciar etiquetas de projetos"
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr "Marcar comentário como resolvido"
-
msgid "Mark this issue as a duplicate of another issue"
msgstr "Marcar esta issue como uma duplicata de outra issue"
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr "Markdown"
-msgid "Markdown Help"
-msgstr "Ajuda do Markdown"
-
msgid "Markdown enabled"
msgstr "Markdown habilitado"
@@ -12908,6 +13569,9 @@ msgstr "Os membros podem ser adicionados pelos <i>mantenedores</i> ou <i>proprie
msgid "Members of <strong>%{project_name}</strong>"
msgstr "Membros de <strong>%{project_name}</strong>"
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr "Merge Request"
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr "Merge Requests"
@@ -12965,6 +13629,9 @@ msgstr "Merge requests"
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr "Aprovações de merge request"
@@ -13013,9 +13680,18 @@ msgstr "conflitos"
msgid "MergeConflict|origin//their changes"
msgstr "origin//alterações deles"
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
msgstr "Adicionar uma resposta"
+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."
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr "Merge realizado"
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr "Branches com merge realizado estão sendo excluídas. Isso pode levar algum tempo dependendo do número de branches. Por favor, atualize a página para ver as alterações."
@@ -13115,9 +13794,6 @@ msgstr "Mensagens"
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr "A métrica foi adicionada com sucesso."
@@ -13139,21 +13815,24 @@ msgstr "Métricas"
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr "Métricas - Influx"
-
msgid "Metrics - Prometheus"
msgstr "Métricas - Prometheus"
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
-msgstr "Métricas e perfis"
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
msgstr ""
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
+msgstr "Métricas e perfis"
+
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr "Adicionar métrica"
@@ -13231,6 +13931,12 @@ msgstr "Rótulo de legenda (opcional)"
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr "Documentação de consulta do Prometheus"
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr "Resposta de dados de implantação inesperada da outra ponta do promethe
msgid "Metrics|Unit label"
msgstr "Rótulo de unidade"
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr "Usado como um título para o gráfico"
@@ -13347,6 +14059,63 @@ 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 "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr "Marcos"
@@ -13356,6 +14125,12 @@ msgstr "Você está prestes a excluir permanentemente o marco %{milestoneTitle}
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."
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr "Excluir marco"
@@ -13365,21 +14140,39 @@ msgstr "Excluir marco %{milestoneTitle}?"
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr "Falha ao excluir marco %{milestoneTitle}"
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr "Marco %{milestoneTitle} não foi encontrado"
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr "Promover %{milestoneTitle} para marco de grupo?"
msgid "Milestones|Promote Milestone"
msgstr "Promover Marco"
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr "Promover %{milestoneTitle} irá disponibilizá-lo para todos os projetos dentro de %{groupName}. Os milestones de projeto existentes com o mesmo título serão mesclados."
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr "Essa ação não pode ser revertida."
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr "Capacidade mínima para estar disponível antes de agendar mais espelhos preventivamente."
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr "Cancelar"
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr "Múltiplos painéis"
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr "Nome"
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr "Nome da nova etiqueta"
@@ -13587,9 +14386,6 @@ msgstr "Nome:"
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr "Rede"
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr "Nunca"
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] "Nova Issue"
msgstr[1] "Novas Issues"
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr "Nova issue"
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr "Nova etiqueta"
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr "Next"
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr "Sem etiqueta"
-
-msgid "No Milestone"
-msgstr "Nenhum marco"
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr "Nenhum arquivo encontrado."
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr "Sem etiquetas com esse nome ou descrição"
@@ -13925,6 +14775,9 @@ msgstr "Nenhum merge requests encontrado"
msgid "No messages were logged"
msgstr "Nenhuma mensagem foi registrada"
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr "Sem marcos para mostrar"
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr "Você tem certeza que quer cancelar a criação deste comentário?"
msgid "Notes|Collapse replies"
msgstr "Recolher respostas"
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr "Exibir todas as atividades"
@@ -14198,9 +15057,15 @@ msgstr "Nov"
msgid "November"
msgstr "Novembro"
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr "Começando"
@@ -14276,9 +15150,6 @@ msgstr "Uma vez importados, os repositórios podem ser espelhados por SSH. Leia
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr "Uma vez removido, o relacionamento do fork não pode ser restaurando e você não poderá mais enviar merge requests para o repositório original."
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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."
@@ -14344,8 +15215,8 @@ msgstr "Somente membros do projeto podem comentar."
msgid "Only project members will be imported. Group members will be skipped."
msgstr "Apenas membros do projeto serão importados. Membros do grupo serão ignorados."
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
-msgstr "Somente usuários com um endereço de e-mail neste domínio podem ser adicionados ao grupo.<br>Exemplo:<code>gitlab.com</code>. Alguns domínios comuns não são permitidos. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
+msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
msgstr ""
@@ -14389,8 +15260,8 @@ msgstr ""
msgid "Opened"
msgstr "Aberto"
-msgid "Opened MR"
-msgstr "MR Aberto"
+msgid "Opened MRs"
+msgstr ""
msgid "Opened issues"
msgstr "Issues abertas"
@@ -14404,6 +15275,9 @@ msgstr "Abrir em nova janela"
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr "O painel de operações fornece um resumo da integridade operacional de
msgid "Optional"
msgstr "Opcional"
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr "Possuído por mim"
msgid "Owner"
msgstr "Proprietário"
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr "O pacote foi removido"
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr "Pacotes"
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr "Página não encontrada"
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr "Atrasado"
@@ -14809,6 +15722,9 @@ msgstr "Colar link de issue"
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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr "Otimização de performance"
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr "rastro"
msgid "Permissions"
msgstr "Permissões"
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr "Permissões, LFS, 2FA"
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr "Escolha um nome"
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr "Pipelines para o último ano"
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr "Este projeto não está atualmente configurado para executar pipelines."
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr "Commit"
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr "Duração"
msgid "Pipeline|Existing branch name or tag"
msgstr "Nome de branch ou tag existente"
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr "Pipeline"
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr "Executar Pipeline"
msgid "Pipeline|Run for"
msgstr "Executar para"
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr "Pesquisar branches"
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr "Especifique valores de variáveis ​​a serem usados ​​nesta execução. Os valores especificados em %{settings_link} serão usados ​​por padrão."
@@ -15130,6 +16082,9 @@ msgstr "Parar pipeline"
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr "Parar pipeline #%{pipelineId}?"
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr "Diff simples"
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr "PlantUML"
@@ -15259,6 +16220,9 @@ msgstr "Por favor, note que esse aplicativo não é fornecido pelo GitLab e vocÃ
msgid "Please provide a name"
msgstr "Por favor, forneça um nome"
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr "Preferências"
@@ -15424,6 +16391,9 @@ msgstr "Usar tempos relativos"
msgid "Press %{key}-C to copy"
msgstr "Pressione %{key}-C para copiar"
+msgid "Prev"
+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"
@@ -15460,6 +16430,9 @@ msgstr "Pré-visualização de carga"
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr "Nome completo"
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr "Incluir contribuições privadas no meu perfil"
@@ -15727,9 +16697,6 @@ msgstr "Organização"
msgid "Profiles|Path"
msgstr "Caminho"
-msgid "Profiles|Personal Access"
-msgstr "Acesso pessoal"
-
msgid "Profiles|Position and size your new avatar"
msgstr "Posicione e dimensione seu novo avatar"
@@ -15874,12 +16841,6 @@ msgstr "Seu status"
msgid "Profiles|e.g. My MacBook key"
msgstr "por exemplo, Chave do meu MacBook"
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr "acesso pessoal"
-
msgid "Profiles|username"
msgstr "nome de usuário"
@@ -15910,6 +16871,9 @@ msgstr "O projeto \"%{name}\" não está mais disponível. Selecione um outro pr
msgid "Project %{project_repo} could not be found"
msgstr "O projeto %{project_repo} não pôde ser encontrado"
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr "O projeto '%{project_name}' está sendo importado."
@@ -15931,6 +16895,9 @@ msgstr "Projeto '%{project_name}' atualizado com sucesso."
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr "Imagem do projeto"
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr "Configuração do projeto, incluindo serviços"
@@ -15985,8 +16955,8 @@ msgstr "Exportação do projeto excluída."
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr "O link para a exportação do projeto expirou. Favor gerar uma nova exportação a partir das configurações do projeto."
-msgid "Project export started. A download link will be sent by email."
-msgstr "Exportação do projeto iniciada. Um link para baixá-la será enviado por email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
+msgstr ""
msgid "Project has too many %{label_for_message} to search"
msgstr ""
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr "Membros do projeto"
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr "Nome do projeto"
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr "Última edição"
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr "Execute operações comuns no projeto GitLab: %{project_name}"
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr "Mostrar link para criar/ver merge request ao fazer push da linha de comando"
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr "Quando conflitos surgem, o usuários tem a opção de fazer rebase"
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr "Projeto em branco"
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr "Contate um administrador para habilitar opções para importar seu projeto."
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr "Configuração automática"
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr "Fazer deploy automático e configurar o Prometheus nos seus clusters para monitorar o ambiente do seu projeto"
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr "Métricas comuns"
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr "Métricas comuns são monitoradas automaticamente com base em uma biblioteca de métricas de exportadores populares."
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr "Métricas personalizadas"
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr "Promova esses marcos de projeto em um marco de grupo."
-msgid "Promote to Group Milestone"
-msgstr "Promover para Marco de Grupo"
-
msgid "Promote to group label"
msgstr "Promover para etiqueta de grupo"
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr "Não me mostre isso novamente"
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 "Epics permitem que você gerencie seu portfólio de projetos com mais eficiência e com menos esforço rastreando grupos de issues que compartilham um tema, entre projetos e marcos."
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr "Esse recurso está bloqueado."
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr "Aprimorar plano"
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr "Público - O grupo e seus projetos podem ser visualizados por todos sem
msgid "Public - The project can be accessed without any authentication."
msgstr "Público - O projeto pode ser acessado sem nenhuma autenticação."
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr "Pipelines públicos"
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr "Pull"
@@ -16939,6 +17978,9 @@ msgstr "A consulta é válida"
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr "Ações rápidas podem ser usadas nas descrições das issues e nas caixas de comentário."
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr "README"
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr "Registre-se com aplicativo de dois fatores"
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr "Tarefas Implantadas Relacionadas"
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr "Versões"
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr "Remover grupo"
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr "Remove %{epic_ref} de épicos filhos."
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr "Reabrir epic"
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr "Repositório por URL"
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr "Configurações do Repositório"
msgid "Repository URL"
msgstr "URL do repositório"
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr "Selecionar"
msgid "Request Access"
msgstr "Solicitar acesso"
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
msgstr "Solicita Perfis"
-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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr "Exigir senha do usuário para aprovar"
msgid "Require users to prove ownership of custom domains"
msgstr "Exigir que os usuários comprovem a propriedade de domínios personalizados"
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr "Resolvido por %{name}"
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr "Resposta"
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr "A resposta não incluiu `service_desk_address`"
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr "Executores podem ser alocados em usuários separados, servidores, até m
msgid "Runners currently online: %{active_runners_count}"
msgstr "Executores online no momento: %{active_runners_count}"
-msgid "Runners page"
-msgstr "Página de runners"
-
msgid "Runners page."
msgstr "Página de runners."
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr "Chaves SSH"
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr "Pesquisar"
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr "Pesquisar branches"
@@ -18115,6 +19226,9 @@ msgstr "Pesquisar projetos"
msgid "Search projects..."
msgstr "Pesquisar projetos..."
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr "Procurar usuários"
@@ -18145,11 +19259,11 @@ msgstr "Merge requests atribuídas a mim"
msgid "SearchAutocomplete|in all GitLab"
msgstr "em todo o GitLab"
-msgid "SearchAutocomplete|in this group"
-msgstr "neste grupo"
+msgid "SearchAutocomplete|in group %{groupName}"
+msgstr ""
-msgid "SearchAutocomplete|in this project"
-msgstr "neste projeto"
+msgid "SearchAutocomplete|in project %{projectName}"
+msgstr ""
msgid "SearchCodeResults|in"
msgstr ""
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr "Secreto"
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr "Segurança"
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr "Painel de segurança"
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr "Selecionar"
msgid "Select Archive Format"
msgstr "Selecionar Formato do Arquivo"
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr "Selecione o projeto GitLab para vincular com sua equipe Slack"
@@ -18549,12 +19672,18 @@ msgstr "Selecionar todos"
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr "Selecione um cluster existente do Kubernetes ou crie um novo"
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr "Selecionar o branch/tag"
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr "Selecionar grupo ou projeto"
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr "Selecionar branch de origem"
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr "Selecionar branch de destino"
@@ -18675,6 +19813,12 @@ msgstr "Enviar e-mail de confirmação"
msgid "Send email"
msgstr "Enviar e-mail"
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr "Enviar relatório"
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr "Definir repositório de modelos para toda a instância"
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr "Defina o tempo máximo da sessão para o terminal da web."
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr "Transações de Sherlock"
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr "Mostrar todas as atividades"
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr "Mostrar projetos arquivados"
@@ -19050,12 +20203,21 @@ msgstr "Visualizar raw log completo"
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr "Mostrar a versão mais recente"
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] "Mostrando %d evento"
msgstr[1] "Mostrando %d eventos"
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr "A autenticação do cartão inteligente falhou: o cabeçalho do certific
msgid "Snippets"
msgstr "Snippets"
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr "Algo deu errado ao resolver essa discussão. Por favor, tente novamente.
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr "Ordenar por"
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr "Nível de acesso, ascendente"
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,8 +20960,8 @@ msgstr ""
msgid "Stars"
msgstr "Favoritos"
-msgid "Start GitLab Ultimate trial"
-msgstr "Iniciar avaliação do GitLab Ultimate"
+msgid "Start Date"
+msgstr ""
msgid "Start Web Terminal"
msgstr "Iniciar Terminal Web"
@@ -19841,6 +21035,9 @@ msgstr "Iniciado %{startsIn}"
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr "Iniciando..."
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr "Parar terminal"
@@ -19994,6 +21194,9 @@ msgstr "Armazenamento:"
msgid "StorageSize|Unknown"
msgstr "Desconhecido"
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr "Subchaves"
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr "Verde claro"
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr "URL da página de suporte"
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr "Trocar branch/tag"
@@ -20315,9 +21530,6 @@ msgstr "Sistema"
msgid "System Hooks"
msgstr "Hooks do sistema"
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr "Informações do Sistema"
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr "A coleção de eventos adicionados aos dados coletados para essa etapa."
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr "A conexão expirará após %{timeout}. Para repositórios que demoram mais tempo, use a combinação clone/push."
@@ -20691,9 +21903,15 @@ msgstr "O domínio que você digitou está mal formatado."
msgid "The domain you entered is not allowed."
msgstr "O domínio que você digitou não é permitido."
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr "A etapa de homologação mostra o tempo entre o aceite da solicitação de incorporação e a implantação do código no ambiente de produção. Os dados serão automaticamente adicionados depois que você implantar em produção pela primeira vez."
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr "A etapa de testes mostra o tempo que o GitLab CI leva para executar cada pipeline para a solicitação de incorporação associada. Os dados serão automaticamente adicionados após a conclusão do primeiro pipeline."
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr "Houve um problema de comunicação com o seu dispositivo."
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr "Erro ao carregar calendário de atividades."
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr "Essa data é posterior à data de vencimento, portanto, esse épico não será exibido no planejamento."
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr "Esta tarefa foi atrasada para executar em %{remainingTime}"
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr "Esta é uma lista de dispositivos com os quais você logou em sua conta. Revogue qualquer sessão que você não reconheça."
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr "Este é um registro de segurança de eventos importantes envolvendo a sua conta."
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr "Isto significa que você não pode entregar código até que crie um repositório vazio ou importe um existente."
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr "Esse merge request está bloqueado."
@@ -21509,12 +22757,18 @@ msgstr "Este projeto"
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr "Este projeto não pertence a um grupo e, portanto, não pode usar os Runners do 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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr "Este projeto ainda não tem uma página inicial na wiki"
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr "Este projeto não possui faturamento ativado. Para criar um cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">ative o faturamento <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> e tente novamente."
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr "Este repositório"
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+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"
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr "Esse usuário não tem identidades"
msgid "This 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 "Esse usuário será o autor de todos os eventos no feed de atividades que são o resultado de uma atualização, como novos branches sendo criados ou novos commits sendo enviados para os branches existentes."
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr "Esse usuário será o autor de todos os eventos no feed de atividades que são o resultado de uma atualização, como novos branches sendo criados ou novos commits sendo enviados para os branches existentes. Na criação ou na redistribuição, você só pode se atribuir para ser o usuário espelho."
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr "agora mesmo"
msgid "Timeout"
msgstr "Tempo limite"
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] "h"
@@ -21930,6 +23202,12 @@ msgstr "Para definir usuários internos, primeiro ative os novos usuários defin
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr "Para habilitá-lo e ver coortes de usuários, visite %{application_settings_link_start}configurações do aplicativo%{application_settings_link_end}."
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 login abaixo. Nas próximas etapas, você poderá associar usuários e selecionar os projetos que deseja importar."
@@ -22050,6 +23328,9 @@ msgstr "Alternar descrição de commit"
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr "Alternar prêmio de emoji"
@@ -22107,15 +23388,9 @@ msgstr "Contribuições totais"
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr "Tempo de teste total para todos os commits/merges"
@@ -22131,9 +23406,6 @@ msgstr "Rastreamento"
msgid "Tracing"
msgstr "Rastreamento"
-msgid "Track activity with Contribution Analytics."
-msgstr "Acompanhe atividades com a Análise de Contribuições."
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr "Acompanhe grupos de issues que compartilhem um tema, em projetos e marcos"
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr "Transferir projeto"
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr "Tente realizar o fork novamente"
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr "URL"
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr "Não é possível carregar o diff. %{button_try_again}"
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr "Atualizando"
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr "Aprimore seu plano"
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr "Aprimore seu plano para ativar a Pesquisa Global Avançada."
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr "Aprimore seu plano para ativar a Análise de Contribuição."
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr "Aprimore seu plano para ativar os Webhooks de Grupo."
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr "Enviar Novo Arquivo"
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr "clique para fazer upload"
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr "Uso"
msgid "Usage ping is not enabled"
msgstr "Dados de uso não está habilitado"
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr "Estatísticas de uso"
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr "Comprar minutos adicionais"
msgid "UsageQuota|Current period usage"
msgstr "Uso do período atual"
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr "Pipelines"
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr "Uso de recursos de grupo entre os projetos no grupo %{strong_start}%{gro
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr "Uso desde"
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr "Use marcos de grupo para gerenciar issues de vários projetos no mesmo m
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr "Configurações do usuário"
-
msgid "User was successfully created."
msgstr "Usuário criado com sucesso."
@@ -23109,6 +24411,12 @@ msgstr "Você não criou nenhum snippet."
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr "Seus projetos podem estar disponíveis publicamente, internamente ou privadamente, à sua escolha."
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr "Validar"
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr "Versão"
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr "Muito útil"
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr "Ver arquivo @ "
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr "Vendo commit"
@@ -23428,9 +24751,6 @@ msgstr "Vulnerabilidades"
msgid "Vulnerabilities over time"
msgstr "Vulnerabilidades ao longo do tempo"
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr "Esta etapa não possui dados suficientes para exibição."
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr "Webhooks"
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 "Webhooks permitem que você acione um URL se, por exemplo, um novo código for feito push ou se uma nova issue for criada. Você pode configurar os webhooks para interagir com eventos específicos como pushes, issues ou merge requests. Webhooks de grupos serão aplicados para todos os projetos em um grupo, permitindo que você padronize o funcionamento em todo o grupo."
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr "Bem-vindo ao Visita Guiada ao GitLab"
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr "Auxiliares brancos fornecem informações contextuais."
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr "Acesso Git"
msgid "WikiClone|Install Gollum"
msgstr "Instalar Gollum"
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr "É recomendado instalar %{markdown} para que as funções GFM sejam renderizadas localmente:"
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr "Inicie o Gollum e edite localmente"
@@ -23889,11 +25218,14 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr "Páginas Wiki"
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "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 a análise de contribuições, você pode ter uma visão geral da atividade de issues, solicitações de merge e eventos de push da sua organização e de seus membros."
+msgid "With requirements, you can set criteria to check your products against."
+msgstr ""
msgid "Withdraw Access Request"
msgstr "Remover Requisição de Acesso"
@@ -23901,10 +25233,10 @@ msgstr "Remover Requisição de Acesso"
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr "Você pode instalar facilmente um Runner em um cluster Kubernetes. %{lin
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr "Você pode mover o gráfico usando as setas do teclado."
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr "Você ainda não tem nenhuma inscrição"
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr "Você recebeu acesso %{access_level} ao %{source_link} %{source_type}."
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr "Você tentou criar o fork %{link_to_the_project}, mas ocorreu uma falha
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr "Você será notificado sobre qualquer atividade"
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr "Você será notificado apenas sobre comentários que te @mencionam"
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr "Você não poderá fazer pull ou push via %{protocol} até que %{set_password_link} para sua conta"
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr "YouTube"
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr "Seus Grupos"
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr "Seus grupos"
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr "Sua mensagem aqui"
msgid "Your name"
msgstr "Seu nome"
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr "Seus projetos"
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr "atrás"
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr "nome da branch"
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr "por"
@@ -24807,6 +26196,9 @@ msgstr "O Teste de Segurança de Aplicativos Dinâmicos (DAST) detecta vulnerabi
msgid "ciReport|Failed to load %{reportName} report"
msgstr "Falha ao carregar o relatório %{reportName}"
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr "Corrigido:"
@@ -24825,6 +26217,9 @@ msgstr "Carregando relatório %{reportName}"
msgid "ciReport|Manage licenses"
msgstr "Gerenciar licenças"
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr "Sem mudanças na qualidade do código"
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr "SAST"
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] "Usado por %{packagesString} e %{lastPackage}"
msgid "ciReport|View full report"
msgstr "Visualizar relatório completo"
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr "Você está prestes a desligar a confidencialidade. Isso significa que <strong>todos</strong> serão capazes de ver e deixar comentários nesse issue."
@@ -24902,6 +26306,9 @@ msgstr "Você está prestes a ligar a confidencialidade. Isso significa que apen
msgid "connecting"
msgstr "conectando"
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr "concluído"
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] "rascunho"
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr "aqui"
msgid "https://your-bitbucket-server"
msgstr "https://seu-servidor-do-bitbucket"
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr "fluxo de importação"
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr "bloqueador por %{path_lock_user_name} %{created_at}"
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr "Estatísticas de deploy não estão disponíveis atualmente"
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr "Você pode fazer merge manualmente usando o"
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr "branch não existe."
@@ -25509,15 +26940,6 @@ msgstr "linha de comando"
msgid "mrWidget|into"
msgstr "para"
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr "n/a"
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] "projeto"
msgstr[1] "projetos"
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr "iniciado"
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr "ver no GitLab"
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr "com %{additions} adições, %{deletions} remoções."
diff --git a/locale/pt_PT/gitlab.po b/locale/pt_PT/gitlab.po
index 6d8adc88d26..caf20f4ea9e 100644
--- a/locale/pt_PT/gitlab.po
+++ b/locale/pt_PT/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: pt-PT\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:35\n"
+"PO-Revision-Date: 2020-06-08 15:19\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] "%d comentário"
msgstr[1] "%d comentários"
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] "%d envio"
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] "%d contribuição"
msgstr[1] "%d contribuições"
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] "mais %d comentário"
msgstr[1] "mais %d comentários"
+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] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr "%{commit_author_link} autorizou %{commit_timeago}"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr "%{filePath} apagado"
msgid "%{firstLabel} +%{labelCount} more"
msgstr "mais %{firstLabel} +%{labelCount}"
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr "%{group_docs_link_start}Grupos%{group_docs_link_end} permitem-te gerir e
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr "%{group_name} usa contas de gestão de grupo. Precisas de criar uma nova conta no GitLab que será gerida por %{group_name}."
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr "%{label_for_message} indisponível"
@@ -370,12 +438,21 @@ msgstr "%{loadingIcon} Iniciado"
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr "%{lock_path} está bloqueado pelo Utilizador do GitLab %{lock_user_id}"
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr "%{mrText}, este problema será encerrado automaticamente."
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr "Avatar de %{name}"
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] "(%d fechado)"
msgstr[1] "(%d fechados)"
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr "(%{mrCount} mesclado)"
@@ -782,6 +874,9 @@ msgstr "Por favor, contacta o teu administrador do GitLab se pensas que isto é
msgid "8 hours"
msgstr "8 horas"
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr "Membros do grupo <strong>%{group_name}</strong>"
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr "<strong>Apagar</strong> o ramo de origem"
@@ -821,6 +919,9 @@ msgstr "Um 'Executador' é um processo que executa um trabalho. Podes configurar
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr "Um .NET Core de um modelo da aplicação de consola, personalizável para qualquer projeto .NET Core"
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr "Um site GitBook que usa o Netlify para CI/CD, em vez do GitLab, mas ainda com todos os outros ótimos recursos do GitLab."
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr "Um fork é uma cópia de um projeto.<br />Bifurcação de um repositório permite que faças alterações sem afetar o projeto original."
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr "Um utilizador com permissão de escrita ao ramo de origem selecionado pa
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr "Ajuda da API"
-
msgid "API Token"
msgstr "Token API"
@@ -968,9 +1072,6 @@ msgstr "Aceitar os termos"
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr "PM aceitado"
-
msgid "Access Tokens"
msgstr "Tokens de Acesso"
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr "redefini-lo"
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,8 +1198,8 @@ msgstr "Ativar Central de Serviços"
msgid "Active"
msgstr "Ativo"
-msgid "Active %{type} Tokens (%{token_length})"
-msgstr "Ativar %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
+msgstr ""
msgid "Active Sessions"
msgstr "Sessões Ativas"
@@ -1112,6 +1207,9 @@ msgstr "Sessões Ativas"
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr "Atividade"
@@ -1156,8 +1254,8 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
-msgstr "Adicionar um token %{type}"
+msgid "Add a %{type}"
+msgstr ""
msgid "Add a GPG key"
msgstr "Adicionar uma chave GPG"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr "Adicionar uma lista de marcadores"
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr "Adicionar um comentário geral para este %{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 "Adiciona uma página inicial à tua wiki que confoi informações sobre o teu projeto e o GitLab irá exibi-lo aqui, ao invés desta mensagem."
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr "Adicionar um link"
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr "Adicionar uma lista numerada"
@@ -1198,7 +1305,10 @@ msgstr "Adiciona um texto adicional para aparecer em todas as comunicações por
msgid "Add an SSH key"
msgstr "Adicionar uma chave SSH"
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr "Adicionar reação"
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,18 +1467,18 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr "Ãrea de Administração"
+msgid "Admin Note"
+msgstr ""
+
msgid "Admin Overview"
msgstr "Visão Geral do Administrador"
-msgid "Admin Section"
-msgstr "Secção de Administração"
-
msgid "Admin mode already enabled"
msgstr ""
@@ -1690,63 +1803,117 @@ msgstr "Após uma atualização de palavra-passe bem-sucedida, serás redirecion
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr "Após uma atualização bem-sucedida da palavra-passe, serás redirecionado para a página de início de sessão, onde poderás iniciar a sessão com a nova palavra-passe."
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] "Alerta"
msgstr[1] "Alertas"
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
+msgstr ""
+
+msgid "AlertManagement|View issue"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr "Uma aplicação chamada %{link_to_client} está a pedir acesso à tua conta do 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 ""
+
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 "Um campo vazio do Utilizador do GitLab adicionará o nome completo do utilizador do FogBugz (por exemplo, \"Por John Smith\") na descrição de todos os problemas e comentários. Ele também irá associar e/ou atribuir estes problemas e comentários ao criador do projeto."
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr "Ocorreu um erro ao carregar os dados do gráfico"
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr "Ocorreu um erro ao carregar as assinaturas de envio"
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr "Ocorreu um erro ao guardar as definições de aprovação"
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr "Ocorreu um erro ao assinar as notificações."
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr "Um problema pode ser uma falha (bug), um \"todo\" ou um pedido de recurso que precisa de ser discutido num projeto. Além disso, os problemas são pesquisáveis e filtráveis."
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr "Ocorreu um erro inesperado ao verificar o ambiente do projeto."
@@ -2256,6 +2453,9 @@ msgstr "Ocorreu um erro inesperado ao iniciar o Terminal Web."
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr "Ocorreu um erro inesperado ao parar o Terminal Web."
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr "Estatísticas"
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr "Qualquer"
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr "Qualquer Rótulo"
-
-msgid "Any Milestone"
-msgstr "Qualquer Objetivo"
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr "Quaisquer tokens encriptados"
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr "Qualquer espaço de nome"
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr "Aplicar sugestão"
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr "por exemplo, Controlo de Qualidade, Segurança, etc."
-msgid "Approvals"
-msgstr "Aprovações"
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr "Tens a certeza de que queres remover %{group_name}?"
msgid "Are you sure you want to remove the attachment?"
msgstr "Tens a certeza de que desejas remover o anexo?"
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr "Tens a certeza de que queres remover esta identidade?"
@@ -2579,8 +2788,8 @@ msgstr "Tens a certeza de que desejas repor o token SCIM? O aprovisionamento de
msgid "Are you sure you want to reset the health check token?"
msgstr "Tens a certeza de que queres reiniciar o token de verificação de saúde?"
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
-msgstr "Tens a certeza de que desejas revogar este Token %{type}? Esta ação não pode ser desfeita."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
+msgstr ""
msgid "Are you sure you want to revoke this nickname?"
msgstr "Tens a certeza de que desejas revogar este apelido?"
@@ -2693,6 +2902,9 @@ msgstr "Problemas Atribuídos"
msgid "Assigned Merge Requests"
msgstr "Pedidos de Mesclagem Atribuídos"
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr "Atribuído a mim"
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr "ago"
@@ -2835,6 +3065,9 @@ msgstr "Autorizar"
msgid "Authorize %{link_to_client} to use your account?"
msgstr "Autorizar %{link_to_client} a usar a tua conta?"
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr "Autorizado %{new_chat_name}"
@@ -2856,9 +3089,6 @@ msgstr "Auto DevOps ativado"
msgid "Auto DevOps, runners and job artifacts"
msgstr "Auto DevOps, artefacto de executadores e trabalho"
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr "Documentação do Auto DevOps"
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr "Ativar nas definições"
@@ -2907,6 +3140,9 @@ msgstr "Gestão automática de certificados ao usar %{lets_encrypt_link_start}Va
msgid "Automatic certificate management using Let's Encrypt"
msgstr "Gestão automática de certificados ao usar Vamos Criptografar"
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr "Marcado, automaticamente, como utilizador interno padrão"
@@ -2922,6 +3158,9 @@ msgstr "Nota"
msgid "Available"
msgstr "Disponível"
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr "Executadores de grupo, disponíveis: %{runners}}"
@@ -3399,17 +3638,17 @@ msgstr "Abrir peso do problema"
msgid "BurndownChartLabel|Open issues"
msgstr "Abrir problemas"
+msgid "Burnup chart"
+msgstr ""
+
msgid "Business"
msgstr "Negócios"
msgid "Business metrics (Custom)"
msgstr "Métricas de negócio (Personalizado)"
-msgid "Buy EE"
-msgstr "Comprar EE"
-
-msgid "Buy GitLab Enterprise Edition"
-msgstr "Comprar o GitLab Enterprise Edition"
+msgid "Buy License"
+msgstr ""
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -3432,8 +3671,8 @@ msgstr "CHANGELOG"
msgid "CI / CD"
msgstr "CI / CD"
-msgid "CI / CD Charts"
-msgstr "Gráficos de CI / CD"
+msgid "CI / CD Analytics"
+msgstr ""
msgid "CI / CD Settings"
msgstr "Definições de CI / CD"
@@ -3441,6 +3680,9 @@ msgstr "Definições de CI / CD"
msgid "CI Lint"
msgstr "CI Lint"
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr "Variáveis de CI"
@@ -3459,6 +3701,9 @@ msgstr "CI/CD para um repositório externo"
msgid "CI/CD settings"
msgstr "Definições de CI/CD"
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr "Auto DevOps"
@@ -3489,9 +3734,6 @@ msgstr "A pipeline de Auto DevOps será executada, se nenhum ficheiro de configu
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr "grupo ativado"
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr "Pode substituir aprovadores e aprovações requeridas por pedido de mesclagem"
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr "Não é possível encontrar o envio HEAD para este ramo"
@@ -3594,8 +3842,8 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
-msgstr "Não é possível referir um objetivo de grupo por um id interno!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
+msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
msgstr ""
@@ -3609,6 +3857,9 @@ msgstr "Não é possível ignorar a configuração de autenticação de dois fat
msgid "Capacity threshold"
msgstr "Limite de capacidade"
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr "Certificado"
@@ -3645,6 +3896,12 @@ msgstr "Alterar caminho"
msgid "Change permissions"
msgstr "Alterar permissões"
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr "Alterar modelo"
@@ -3687,6 +3944,9 @@ msgstr "Alterações"
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr "As alterações são mostradas como se a revisão de <b>origem</b> estivesse a ser mesclada na revisão de <b>destino</b>."
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr "Falha na validação"
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr "Etiqueta de classificação (opcional)"
@@ -4182,6 +4433,9 @@ msgstr "Limpar"
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr "Limpar entrada"
@@ -4194,6 +4448,9 @@ msgstr "Limpar Pesquisa"
msgid "Clear search input"
msgstr "Limpar entradas de pesquisa"
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr "Limpar entrada de pesquisa de modelos"
@@ -4221,9 +4478,6 @@ msgstr "Clica no botão <strong>Selecionar nenhum</strong> à direita, pois, só
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr "Clica no botão abaixo para começar o processo de instalação ao navegar para a página do Kubernetes"
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr "Clica para expandir."
@@ -4263,6 +4517,9 @@ msgstr "Clonar com SSH"
msgid "Close"
msgstr "Fechar"
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr "O nome do cluster é obrigatório."
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr "Os clusters são utilizados ao selecionar o antepassado mais próximo com um contexto de ambiente correspondente. Por exemplo, os clusters de projeto substituirão os clusters de grupo."
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr "Copiar o nome do cluster de Kubernetes"
-msgid "ClusterIntegration|Copy Service Token"
-msgstr "Copiar Token de Serviço"
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr "Ativar esta definição, se ao usar o controlo de acesso baseado em funÃ
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,12 +4898,12 @@ msgstr "Cluster de grupo"
msgid "ClusterIntegration|Helm Tiller"
msgstr "Helm Tiller"
+msgid "ClusterIntegration|Helm release failed to install"
+msgstr ""
+
msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr "O Helm simplifica a instalação e a gestão de aplicações do Kubernetes. O Tiller é executado dentro do Kubernetes Cluster e gerência os lançamentos dos teus gráficos."
-msgid "ClusterIntegration|Hide"
-msgstr "Ocultar"
-
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
msgstr "Se estás a configurar múltiplos clusters e estás a usar o Auto DevOps, %{help_link_start}lê isto primeiro%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr "Mostrar"
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr "Ocorreu um erro do nosso lado."
@@ -5115,6 +5378,9 @@ msgstr "Alternar cluster do Kubernetes"
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr "Desinstalar %{appTitle}"
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr "Atualização falhou. Por favor, verifica os registos e tenta novamente."
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr "Configurar Prometheus"
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr "Criar etiqueta do grupo"
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr "Criar objetivo"
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr "Modelos de projeto personalizados não foram configurados para grupos do
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr "Endereço de email"
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,13 +8991,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8627,7 +9009,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr "Erro ao enviar o ficheiro."
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr "Filtrar por nome de objetivo"
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr "Gitlab CI/CD"
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr "Os responsáveis do grupo podem registar executadores de grupo no %{link
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr "Histórico de autenticações"
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr "Os membros podem ser adicionados ao projeto <i>Responsáveis</i> ou <i>P
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ 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 "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr "Objetivos"
@@ -13356,6 +14125,12 @@ msgstr "Estás prestes a apagar, permanentemente, o objetivo%{milestoneTitle} e
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr "Estás prestes a apagar, permanentemente, o objetivo %{milestoneTitle}. Este objetivo não é, atualmente, usado em nenhum problema ou pedidos de mesclagem."
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr "Apagar objetivo"
@@ -13365,21 +14140,39 @@ msgstr "Apagar objetivo %{milestoneTitle}?"
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr "Falha ao apagar o objetivo %{milestoneTitle}"
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr "O objetivo %{milestoneTitle} não foi encontrado"
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr "Promover %{milestoneTitle} para objetivo de grupo?"
msgid "Milestones|Promote Milestone"
msgstr "Promover Objetivo"
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr "Esta ação não pode ser revertida."
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] ""
msgstr[1] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr "Nenhum objetivo para mostrar"
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr "Promove estes objetivos de projeto num objetivo de grupo."
-msgid "Promote to Group Milestone"
-msgstr "Promover para Objetivo de Grupo"
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 "Os épicos permitem que gerencies o teu portefólio de projetos com mais eficiência e com menos esforço ao localizar grupos de problemas que compartilham um tema, entre projetos e objetivos."
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr "Solicitar que os utilizadores enviem chaves SSH"
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr "Receber notificações sobre a tua própria atividade"
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr "Página URL de suporte"
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr "A fase de preparação mostra o tempo entre a mesclagem do PM e a implementação do código no ambiente de produção. Os dados serão adicionados, automaticamente, quando implantares na produção pela primeira vez."
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr "Este é um registo de segurança de eventos importantes que envolvem a tua conta."
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr "Acompanhar grupos de problemas que compartilham um tema, através de projetos e objetivos"
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr "A atualizar"
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr "Enviar ficheiro CSV"
msgid "Upload New File"
msgstr "Enviar Novo Ficheiro"
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr "Enviar um certificado para o teu domínio com todos os intermediários"
@@ -22680,6 +23967,9 @@ msgstr "clica para enviar"
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr "Utiliza o grupo de objetivos para gerir problemas de vários projetos no
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr "Não criaste nenhum fragmento."
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr "Também podes testar o teu %{gitlab_ci_yml} em %{lint_link_start}CI Lint
msgid "You can also upload existing files from your computer using the instructions below."
msgstr "Também podes enviar ficheiros existentes do teu computador ao usar as instruções abaixo."
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr "Podes convidar outro grupo para <strong>%{project_name}</strong>."
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr "atrás"
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr "permissão para falhar"
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr "nome do ramo"
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr "dispensado"
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/ro_RO/gitlab.po b/locale/ro_RO/gitlab.po
index 1c75c655d1d..9dbd275e389 100644
--- a/locale/ro_RO/gitlab.po
+++ b/locale/ro_RO/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: ro\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:10\n"
+"PO-Revision-Date: 2020-06-08 15:07\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -77,6 +77,18 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -101,6 +113,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -128,6 +146,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -212,6 +236,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+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] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -248,6 +278,18 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -272,6 +314,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -353,6 +398,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -362,6 +410,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -374,6 +425,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -407,12 +482,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -428,6 +512,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -470,6 +560,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -623,6 +719,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -845,6 +944,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -875,6 +977,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -884,6 +989,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -920,7 +1028,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -971,6 +1082,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -983,9 +1097,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -1031,9 +1142,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1124,12 +1232,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1166,7 +1268,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1175,6 +1277,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1220,7 +1325,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1235,6 +1340,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1244,9 +1352,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1262,7 +1376,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1328,6 +1445,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1418,16 +1538,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1754,64 +1874,118 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1820,16 +1994,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|Unknown"
+msgstr ""
+
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -2003,6 +2195,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2168,9 +2363,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2192,6 +2384,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2267,6 +2462,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2303,9 +2501,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2321,6 +2525,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2330,6 +2537,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2354,12 +2564,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2369,9 +2573,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2435,6 +2645,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2507,12 +2720,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2522,12 +2729,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2636,6 +2849,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2648,7 +2864,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2762,6 +2978,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2840,15 +3059,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2906,6 +3143,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2927,9 +3167,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2948,6 +3185,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2978,6 +3218,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2993,6 +3236,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3470,16 +3716,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3503,7 +3749,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3512,6 +3758,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3530,6 +3779,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3560,9 +3812,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3590,6 +3839,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3665,7 +3920,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3680,6 +3935,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3716,6 +3974,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3758,6 +4022,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3776,6 +4043,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3881,15 +4151,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4238,9 +4499,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4253,6 +4511,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4265,6 +4526,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4292,9 +4556,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4334,6 +4595,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4529,6 +4793,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4550,9 +4817,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4604,7 +4868,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4631,6 +4895,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4709,10 +4976,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4871,6 +5138,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5105,9 +5378,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5186,6 +5456,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5216,6 +5489,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5225,9 +5501,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5285,6 +5567,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5303,6 +5588,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5342,6 +5630,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5351,6 +5642,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5387,6 +5681,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5549,7 +5846,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5573,9 +5873,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5609,9 +5906,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5660,16 +5954,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5696,6 +5984,18 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5708,6 +6008,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5732,27 +6035,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5774,10 +6089,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5798,9 +6110,6 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5822,6 +6131,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5849,12 +6161,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5873,7 +6179,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5882,7 +6191,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5921,10 +6230,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -6011,6 +6320,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -6056,9 +6368,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6074,9 +6383,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6173,7 +6479,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6191,9 +6497,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6212,9 +6515,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6224,9 +6524,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6269,6 +6566,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6281,6 +6581,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6320,6 +6623,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6353,6 +6662,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6404,9 +6716,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6443,6 +6752,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6467,6 +6779,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6515,6 +6830,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6539,6 +6857,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6791,6 +7112,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6827,6 +7151,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6869,6 +7196,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6959,12 +7292,6 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -7001,12 +7328,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -7016,9 +7337,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7136,12 +7454,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7163,13 +7487,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7289,10 +7613,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7301,9 +7625,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7313,6 +7652,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7340,12 +7682,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7355,6 +7712,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7367,6 +7730,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7595,6 +7961,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7643,6 +8012,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7667,6 +8039,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7814,6 +8189,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7829,6 +8207,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7922,6 +8303,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7931,9 +8315,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7961,6 +8342,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8084,6 +8468,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8108,10 +8495,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8168,7 +8555,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8381,10 +8768,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8396,12 +8783,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8471,7 +8852,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8576,9 +8966,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8594,6 +8981,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8645,10 +9035,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8690,13 +9080,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8708,7 +9098,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8747,6 +9137,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8765,6 +9158,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8798,6 +9194,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8813,6 +9212,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8822,6 +9224,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8900,18 +9305,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -9038,6 +9431,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9113,7 +9509,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9176,6 +9572,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9188,6 +9590,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9197,15 +9602,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9224,6 +9638,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9239,9 +9656,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9332,6 +9755,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9344,6 +9770,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9353,9 +9782,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9371,24 +9797,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9398,6 +9845,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9629,9 +10079,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9671,15 +10118,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9857,6 +10304,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9866,10 +10319,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9920,6 +10373,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9971,6 +10430,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9989,6 +10451,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9998,6 +10463,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10250,9 +10721,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10286,9 +10754,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10451,12 +10916,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10490,6 +10964,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10502,10 +10982,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10523,10 +11006,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10544,12 +11030,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10616,9 +11108,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10820,6 +11309,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10925,6 +11417,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10934,6 +11429,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -11042,6 +11540,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -11051,6 +11552,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11201,6 +11705,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11210,7 +11717,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11219,6 +11729,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11231,7 +11747,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11249,13 +11768,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11267,6 +11786,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11276,6 +11798,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11285,10 +11810,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11381,10 +11906,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11417,6 +11942,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11450,6 +11978,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11474,18 +12008,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11537,6 +12089,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11576,6 +12152,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11612,18 +12194,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11636,6 +12227,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11699,6 +12293,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11711,6 +12308,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11768,6 +12392,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11813,6 +12440,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11825,19 +12476,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11963,6 +12617,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -12002,6 +12659,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12182,6 +12842,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12266,6 +12929,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12287,9 +12953,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12317,6 +12980,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12329,6 +12995,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12353,15 +13022,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12500,6 +13163,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12515,6 +13181,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12611,6 +13280,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12725,10 +13397,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12755,6 +13427,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12806,9 +13481,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12818,9 +13490,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12998,6 +13667,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -13007,9 +13679,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -13022,6 +13691,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -13055,6 +13727,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13103,9 +13778,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13166,7 +13850,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13184,6 +13868,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13205,9 +13892,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13229,19 +13913,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13265,6 +13952,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13322,6 +14030,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13340,6 +14054,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13376,6 +14093,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13439,6 +14159,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13448,6 +14225,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13457,21 +14240,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13532,6 +14333,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13646,6 +14450,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13655,6 +14462,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13667,9 +14477,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13679,9 +14486,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13715,6 +14519,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13745,6 +14597,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13811,6 +14666,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13868,6 +14726,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13886,18 +14747,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13988,12 +14840,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -14018,6 +14876,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14153,6 +15014,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14177,6 +15041,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14291,9 +15158,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14360,6 +15233,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14369,9 +15251,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14438,7 +15317,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14483,7 +15362,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14498,6 +15377,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14528,7 +15410,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14576,6 +15458,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14594,6 +15479,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14615,6 +15503,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14702,6 +15596,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14720,6 +15617,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14750,22 +15650,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14798,6 +15713,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14885,6 +15803,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14903,6 +15824,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14945,9 +15869,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14969,9 +15899,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14993,9 +15920,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15104,6 +16028,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15164,15 +16091,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15185,30 +16121,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15224,6 +16184,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15260,6 +16223,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15353,6 +16322,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15428,6 +16400,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15518,6 +16493,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15554,6 +16532,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15773,9 +16754,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15821,9 +16799,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15968,12 +16943,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -16004,6 +16973,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -16025,6 +16997,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -16055,6 +17030,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -16079,7 +17057,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -16088,6 +17066,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16202,9 +17183,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16370,6 +17348,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16415,6 +17396,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16565,6 +17549,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16658,12 +17645,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16739,9 +17732,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16760,30 +17750,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16919,9 +17963,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16931,6 +17972,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -17033,6 +18080,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -17042,9 +18092,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -17081,9 +18128,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17180,6 +18224,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17225,6 +18284,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17246,6 +18317,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17315,6 +18389,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17357,6 +18437,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17396,6 +18479,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17447,6 +18533,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17477,6 +18566,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17492,7 +18584,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17597,6 +18692,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17633,6 +18731,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17648,10 +18749,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17666,6 +18770,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17687,10 +18797,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17762,6 +18869,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17774,6 +18884,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17921,6 +19037,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17984,9 +19103,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -18023,9 +19139,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18155,9 +19268,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18215,6 +19334,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18245,10 +19367,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18347,9 +19469,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18362,9 +19490,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18374,24 +19499,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18527,6 +19652,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18608,6 +19736,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18659,12 +19790,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18710,9 +19847,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18785,6 +19931,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18950,6 +20102,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18986,6 +20141,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -19070,6 +20228,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -19088,7 +20249,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19127,15 +20288,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19160,12 +20321,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19187,6 +20357,15 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19373,6 +20552,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19409,9 +20591,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19508,6 +20696,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19547,6 +20738,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19595,6 +20789,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19712,6 +20912,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19877,7 +21080,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19952,6 +21155,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -20078,6 +21284,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -20105,6 +21314,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20132,6 +21344,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20312,9 +21527,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20399,6 +21620,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20426,9 +21650,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20681,6 +21902,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20765,9 +21989,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20804,9 +22025,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20846,6 +22073,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -21020,6 +22250,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -21068,6 +22301,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21143,6 +22379,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21215,6 +22460,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21278,6 +22526,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21362,6 +22613,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21401,6 +22655,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21446,9 +22703,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21560,7 +22814,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21587,6 +22841,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21623,12 +22880,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21641,12 +22904,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21665,7 +22940,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21674,9 +22949,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21731,9 +23003,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21980,6 +23258,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -22046,6 +23327,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22166,6 +23453,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22223,15 +23513,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22247,9 +23531,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22268,6 +23549,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22379,6 +23663,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22436,10 +23723,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22448,6 +23735,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22487,6 +23777,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22496,9 +23789,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22748,18 +24047,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22778,6 +24071,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22796,6 +24092,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22820,9 +24119,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22832,12 +24128,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22847,12 +24149,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22871,12 +24179,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22901,7 +24215,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22976,9 +24290,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23225,6 +24536,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23285,6 +24602,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23312,7 +24632,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23354,6 +24677,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23402,6 +24728,9 @@ msgstr[2] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23465,6 +24794,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23546,9 +24878,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23579,9 +24908,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23690,6 +25016,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23702,6 +25031,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23723,7 +25055,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23765,9 +25103,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23807,12 +25142,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23849,9 +25193,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23885,9 +25226,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -24008,10 +25346,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -24020,10 +25361,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24140,6 +25481,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24167,6 +25511,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24182,6 +25529,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24260,6 +25610,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24308,6 +25661,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24323,7 +25679,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24416,6 +25772,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24443,6 +25802,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24461,6 +25823,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24494,7 +25862,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24530,7 +25901,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24623,9 +25994,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24635,12 +26015,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24665,9 +26051,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24716,6 +26108,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24758,6 +26153,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24932,6 +26330,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24950,6 +26351,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24968,6 +26372,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -25010,6 +26417,9 @@ msgstr[2] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -25019,6 +26429,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -25028,6 +26441,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25079,6 +26495,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -25091,7 +26510,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -25124,10 +26546,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25193,9 +26615,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25259,6 +26690,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25280,6 +26714,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25319,6 +26759,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25448,7 +26891,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25628,9 +27071,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25640,15 +27080,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25661,6 +27092,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25706,6 +27140,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25739,9 +27176,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25766,6 +27212,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25817,6 +27269,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25883,10 +27338,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25949,6 +27404,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25976,6 +27437,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -26003,6 +27467,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/ru/gitlab.po b/locale/ru/gitlab.po
index 41ab1cab863..af2077a89d0 100644
--- a/locale/ru/gitlab.po
+++ b/locale/ru/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: ru\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 22:46\n"
+"PO-Revision-Date: 2020-06-08 15:19\n"
msgid " %{start} to %{end}"
msgstr " %{start} по %{end}"
@@ -80,6 +80,20 @@ msgstr[1] "%dURL проÑканировано"
msgstr[2] "%d URL проÑканировано"
msgstr[3] "%d URL проÑканировано"
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] "%d измененный файл"
@@ -108,6 +122,13 @@ msgstr[1] "%d комментариÑ"
msgstr[2] "%d комментариев"
msgstr[3] "%d комментариев"
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] "%d коммит"
@@ -139,6 +160,13 @@ msgstr[1] "%d вклада"
msgstr[2] "%d вкладов"
msgstr[3] "%d вкладов"
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] "%d ошибка"
@@ -237,6 +265,13 @@ msgstr[1] "еще %d комментариÑ"
msgstr[2] "еще %d комментариев"
msgstr[3] "еще %d комментариев"
+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[3] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] "%d проект"
@@ -274,6 +309,20 @@ msgstr[3] "%d тегов"
msgid "%d unresolved thread"
msgid_plural "%d unresolved threads"
+msgstr[0] "%d Ð½ÐµÑ€ÐµÑˆÑ‘Ð½Ð½Ð°Ñ Ñ‚ÐµÐ¼Ð°"
+msgstr[1] "%d нерешённые темы"
+msgstr[2] "%d нерешённых тем"
+msgstr[3] "%d нерешённых тем"
+
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -305,6 +354,9 @@ msgstr "%{commit_author_link} Ñоздал %{commit_timeago}"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr "Завершено %{completedWeight} из %{totalWeight} приоритета"
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} Ñдер"
@@ -352,10 +404,10 @@ msgstr[3] "%{count} учаÑтников"
msgid "%{count} pending comment"
msgid_plural "%{count} pending comments"
-msgstr[0] "%{count} комментарий в ожидании"
-msgstr[1] "%{count} комментариев в ожидании"
-msgstr[2] "%{count} комментариев в ожидании"
-msgstr[3] "%{count} комментарии в ожидании"
+msgstr[0] "%{count} ожидающий комментарий"
+msgstr[1] "%{count} ожидающих комментариÑ"
+msgstr[2] "%{count} ожидающих комментариев"
+msgstr[3] "%{count} ожидающих комментариев"
msgid "%{count} related %{pluralized_subject}: %{links}"
msgstr "%{count} ÑвÑзанный %{pluralized_subject}: %{links}"
@@ -390,6 +442,9 @@ msgstr "%{filePath} удален"
msgid "%{firstLabel} +%{labelCount} more"
msgstr "%{firstLabel} + ещё %{labelCount}"
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr "%{global_id} не ÑвлÑетÑÑ Ð´Ð¾Ð¿ÑƒÑтимым ID Ð´Ð»Ñ %{expected_type}."
@@ -399,6 +454,9 @@ msgstr "%{group_docs_link_start}Группы%{group_docs_link_end} позволÑ
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr "%{group_name} иÑпользует управлÑемые групповые аккаунты. Вам нужно Ñоздать новый аккаунт GitLab, который будет управлÑÑ‚ÑŒÑÑ %{group_name}."
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr "%{icon} Ð’Ñ‹ ÑобираетеÑÑŒ добавить %{usersTag} людей к обÑуждению. Будьте оÑторожны."
@@ -411,6 +469,30 @@ msgstr "%{issuesSize} обÑуждений"
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr "%{issuesSize} обÑуждение Ñ Ð»Ð¸Ð¼Ð¸Ñ‚Ð¾Ð¼ в %{maxIssueCount}"
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr "%{label_for_message} недоÑтупно"
@@ -427,7 +509,7 @@ msgid "%{lineOneStart}Drag and drop to upload your designs%{lineOneEnd} or %{lin
msgstr "%{lineOneStart}Перетащите, чтобы загрузить Ñвои дизайны%{lineOneEnd} или %{linkStart}нажмите, чтобы загрузить%{linkEnd}."
msgid "%{link_start}Learn more%{link_end} about what information is shared with GitLab Inc."
-msgstr ""
+msgstr "%{link_start}Узнайте больше%{link_end} о том, ÐºÐ°ÐºÐ°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¿ÐµÑ€ÐµÐ´Ð°ÐµÑ‚ÑÑ GitLab Inc."
msgid "%{link_start}Read more%{link_end} about role permissions"
msgstr "%{link_start}Подробнее%{link_end} о ролевом доÑтупе"
@@ -444,15 +526,24 @@ msgstr "%{loadingIcon} Запущена"
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr "%{lock_path} заблокирован пользователем GitLab %{lock_user_id}"
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr "%{mergeLength}/%{usersLength} можно объединить"
msgid "%{mrText}, this issue will be closed automatically."
msgstr "%{mrText}, Ñто обÑуждение будет закрыто автоматичеÑки."
-msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
msgstr ""
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
+msgstr "%{namespace_name} теперь в режиме только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ. Ð’Ñ‹ не можете: %{base_message}"
+
msgid "%{name} contained %{resultsString}"
msgstr "%{name} Ñодержал %{resultsString}"
@@ -465,12 +556,18 @@ msgstr "%{name} запланирован на %{action}"
msgid "%{name}'s avatar"
msgstr "Ðватар Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ %{name}"
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "%{no_of_days} день"
+msgstr[1] "%{no_of_days} днÑ"
+msgstr[2] "%{no_of_days} дней"
+msgstr[3] "%{no_of_days} дней"
msgid "%{number_commits_behind} commits behind %{default_branch}, %{number_commits_ahead} commits ahead"
msgstr "на %{number_commits_behind} коммитов позади %{default_branch}, на %{number_commits_ahead} коммитов впереди"
@@ -509,12 +606,18 @@ msgstr[1] "%{releases} релиза"
msgstr[2] "%{releases} релизов"
msgstr[3] "%{releases} релизов"
-msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
+msgid "%{remaining_approvals} left"
msgstr ""
-msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Enabled"
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
msgstr ""
+msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
+msgstr "%{screenreaderOnlyStart}Ð¡Ð¾Ñ‡ÐµÑ‚Ð°Ð½Ð¸Ñ ÐºÐ»Ð°Ð²Ð¸Ñˆ%{screenreaderOnlyEnd} отключены"
+
+msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Enabled"
+msgstr "%{screenreaderOnlyStart}Ð¡Ð¾Ñ‡ÐµÑ‚Ð°Ð½Ð¸Ñ ÐºÐ»Ð°Ð²Ð¸Ñˆ%{screenreaderOnlyEnd} включены"
+
msgid "%{service_title} %{message}."
msgstr "%{service_title} %{message}."
@@ -534,19 +637,19 @@ msgid "%{spammable_titlecase} was submitted to Akismet successfully."
msgstr "%{spammable_titlecase} было уÑпешно отправлено в Akismet."
msgid "%{spanStart}at line%{spanEnd} %{errorLine}%{errorColumn}"
-msgstr ""
+msgstr "%{spanStart}в Ñтроке%{spanEnd} %{errorLine}%{errorColumn}"
msgid "%{spanStart}in%{spanEnd} %{errorFn}"
-msgstr ""
+msgstr "%{spanStart}в%{spanEnd} %{errorFn}"
msgid "%{start} to %{end}"
-msgstr ""
+msgstr "%{start} по %{end}"
msgid "%{state} epics"
msgstr "%{state} цели"
msgid "%{strongStart}Note:%{strongEnd} Once a custom stage has been added you can re-order stages by dragging them into the desired position."
-msgstr ""
+msgstr "%{strongStart}Примечание:%{strongEnd} ПоÑле Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒÑкого Ñтапа вы можете изменить порÑдок Ñтапов, перетаÑÐºÐ¸Ð²Ð°Ñ Ð¸Ñ… в нужное положение."
msgid "%{strong_start}%{branch_count}%{strong_end} Branch"
msgid_plural "%{strong_start}%{branch_count}%{strong_end} Branches"
@@ -563,17 +666,17 @@ msgstr[2] "%{strong_start}%{commit_count}%{strong_end} Коммитов"
msgstr[3] "%{strong_start}%{commit_count}%{strong_end} Коммитов"
msgid "%{strong_start}%{human_size}%{strong_end} Files"
-msgstr "%{strong_start}%{human_size}%{strong_end} файлов"
+msgstr "%{strong_start}%{human_size}%{strong_end} Файлов"
msgid "%{strong_start}%{human_size}%{strong_end} Storage"
-msgstr ""
+msgstr "%{strong_start}%{human_size}%{strong_end} в Хранилище"
msgid "%{strong_start}%{release_count}%{strong_end} Release"
msgid_plural "%{strong_start}%{release_count}%{strong_end} Releases"
-msgstr[0] "%{strong_start}%{release_count}%{strong_end} релиз"
-msgstr[1] "%{strong_start}%{release_count}%{strong_end} релиза"
-msgstr[2] "%{strong_start}%{release_count}%{strong_end} релизов"
-msgstr[3] "%{strong_start}%{release_count}%{strong_end} релизов"
+msgstr[0] "%{strong_start}%{release_count}%{strong_end} Релиз"
+msgstr[1] "%{strong_start}%{release_count}%{strong_end} Релиза"
+msgstr[2] "%{strong_start}%{release_count}%{strong_end} Релизов"
+msgstr[3] "%{strong_start}%{release_count}%{strong_end} Релизов"
msgid "%{strong_start}%{tag_count}%{strong_end} Tag"
msgid_plural "%{strong_start}%{tag_count}%{strong_end} Tags"
@@ -608,7 +711,7 @@ msgid "%{text} is available"
msgstr "%{text} доÑтупен"
msgid "%{timebox_name} should belong either to a project or a group."
-msgstr ""
+msgstr "%{timebox_name} должен принадлежать проекту или группе"
msgid "%{title} %{operator} %{threshold}"
msgstr "%{title} %{operator} %{threshold}"
@@ -629,7 +732,7 @@ msgid "%{total} open issues"
msgstr "%{total} открытых задач"
msgid "%{usage_ping_link_start}Learn more%{usage_ping_link_end} about what information is shared with GitLab Inc."
-msgstr ""
+msgstr "%{usage_ping_link_start}Узнайте больше%{usage_ping_link_end} о том, ÐºÐ°ÐºÐ°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¿ÐµÑ€ÐµÐ´Ð°ÐµÑ‚ÑÑ GitLab Inc."
msgid "%{userName} (cannot merge)"
msgstr "%{userName}(не может выполнÑÑ‚ÑŒ ÑлиÑние)"
@@ -647,7 +750,7 @@ msgid "%{value} s"
msgstr "%{value} Ñ"
msgid "%{verb} %{time_spent_value} spent time."
-msgstr ""
+msgstr "%{verb} %{time_spent_value} потраченного времени."
msgid "'%{level}' is not a valid visibility level"
msgstr ""
@@ -656,10 +759,10 @@ msgid "'%{name}' stage already exists"
msgstr "Этап '%{name}' уже ÑущеÑтвует"
msgid "'%{source}' is not a import source"
-msgstr ""
+msgstr "'%{source}' не ÑвлÑетÑÑ Ð¸Ñточником импорта"
msgid "'%{template_name}' is unknown or invalid"
-msgstr ""
+msgstr "'%{template_name}' неизвеÑтен или указан неверно"
msgid "(%d closed)"
msgid_plural "(%d closed)"
@@ -668,6 +771,9 @@ msgstr[1] "(%d закрыто)"
msgstr[2] "(%d закрыто)"
msgstr[3] "(%d закрыто)"
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr "(%{mrCount} объединено)"
@@ -908,6 +1014,9 @@ msgstr "ПожалуйÑта ÑвÑжитеÑÑŒ Ñ Ð²Ð°ÑˆÐ¸Ð¼ админиÑÑ‚Ñ€
msgid "8 hours"
msgstr "8 чаÑов"
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr "< 1 чаÑа"
@@ -915,13 +1024,13 @@ msgid "<code>\"johnsmith@example.com\": \"@johnsmith\"</code> will add \"By <a h
msgstr "<code>\"johnsmith@example.com\": \"@johnsmith\"</code> добавил \"<a href=\"#\">@johnsmith</a>\" По вÑем вопроÑам и комментариÑм, изначально Ñозданным johnsmith@example.com, и уÑтановил <a href=\"#\">@johnsmith</a> в качеÑтве правопреемника по вÑем задачам первоначально назначен johnsmith@example.com."
msgid "<code>\"johnsmith@example.com\": \"John Smith\"</code> will add \"By John Smith\" to all issues and comments originally created by johnsmith@example.com."
-msgstr ""
+msgstr "<code>\"johnsmith@example.com\": \"John Smith\"</code> добавит \"От John Smith\" ко вÑем обÑуждениÑм и комментариÑм, Ñозданным johnsmith@example.com."
msgid "<code>\"johnsmith@example.com\": \"johnsm...@example.com\"</code> will add \"By johnsm...@example.com\" to all issues and comments originally created by johnsmith@example.com. The email address or username is masked to ensure the user's privacy."
-msgstr ""
+msgstr "<code>\"johnsmith@example.com\": \"johnsm...@example.com\"</code> добавит \"От johnsm...@example.com\" ко вÑем обÑуждениÑм и комментариÑм, Ñозданным пользователем johnsmith@example.com. Почтовый Ð°Ð´Ñ€ÐµÑ Ð¸ Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ ÑкрываютÑÑ Ð´Ð»Ñ Ð¾Ð±ÐµÑÐ¿ÐµÑ‡ÐµÐ½Ð¸Ñ ÐºÐ¾Ð½Ñ„Ð¸Ð´ÐµÐ½Ñ†Ð¸Ð°Ð»ÑŒÐ½Ð¾Ñти."
msgid "<code>\"johnsmith@example.com\": \"johnsmith@example.com\"</code> will add \"By <a href=\"#\">johnsmith@example.com</a>\" to all issues and comments originally created by johnsmith@example.com. By default, the email address or username is masked to ensure the user's privacy. Use this option if you want to show the full email address."
-msgstr ""
+msgstr "<code>\"johnsmith@example.com\": \"johnsmith@example.com\"</code> добавит \"От <a href=\"#\">johnsmith@example.com</a>\" ко вÑем обÑуждениÑм и комментариÑм, Ñозданным johnsmith@example.com. По умолчанию Ð°Ð´Ñ€ÐµÑ Ð¿Ð¾Ñ‡Ñ‚Ñ‹ и Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ ÑкрываютÑÑ Ð´Ð»Ñ Ð¾Ð±ÐµÑÐ¿ÐµÑ‡ÐµÐ½Ð¸Ñ ÐºÐ¾Ð½Ñ„Ð¸Ð´ÐµÐ½Ñ†Ð¸Ð°Ð»ÑŒÐ½Ð¾Ñти. ИÑпользуйте Ñту опцию, еÑли хотите показывать полный Ð°Ð´Ñ€ÐµÑ Ñлектронной почты."
msgid "<namespace / project>"
msgstr ""
@@ -933,11 +1042,14 @@ msgid "<no scopes selected>"
msgstr "<no scopes selected>"
msgid "<project name>"
-msgstr ""
+msgstr "<название проекта>"
msgid "<strong>%{group_name}</strong> group members"
msgstr "<strong>%{group_name}</strong> учаÑтников группы"
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr "<strong>УдалÑет</strong> иÑходную ветку"
@@ -947,6 +1059,9 @@ msgstr "«Runner» - Ñто процеÑÑ, который выполнÑет Ñ
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr "Шаблон конÑольного Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ .NET Core, наÑтраиваемый Ð´Ð»Ñ Ð»ÑŽÐ±Ð¾Ð³Ð¾ проекта .NET Core"
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr "Сайт GitBook, который иÑпользует Netlify Ð´Ð»Ñ CI/CD вмеÑто GitLab, но вÑÑ‘ ещё Ñ Ð´Ñ€ÑƒÐ³Ð¸Ð¼Ð¸ замечательными возможноÑÑ‚Ñми GitLab."
@@ -966,10 +1081,10 @@ msgid "A Let's Encrypt account will be configured for this GitLab installation u
msgstr "Ð£Ñ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ Let's Encrypt будет наÑтроена Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ уÑтановки GitLab Ñ Ð¸Ñпользованием адреÑа вашей Ñлектронной почты. Ð’Ñ‹ получите Ñлектронное пиÑьмо Ñ Ð¿Ñ€ÐµÐ´ÑƒÐ¿Ñ€ÐµÐ¶Ð´ÐµÐ½Ð¸ÐµÐ¼ об иÑтечении Ñрока дейÑÑ‚Ð²Ð¸Ñ Ñертификатов."
msgid "A basic page and serverless function that uses AWS Lambda, AWS API Gateway, and GitLab Pages"
-msgstr ""
+msgstr "ОÑÐ½Ð¾Ð²Ð½Ð°Ñ Ñтраница и беÑÑÐµÑ€Ð²ÐµÑ€Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ, иÑпользующие AWS Lambda, AWS API Gateway, и GitLab Pages"
msgid "A complete DevOps platform"
-msgstr ""
+msgstr "КомплекÑÐ½Ð°Ñ DevOps-платформа"
msgid "A default branch cannot be chosen for an empty project."
msgstr "Ð”Ð»Ñ Ð¿ÑƒÑтого проекта Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð±Ñ€Ð°Ñ‚ÑŒ ветку по умолчанию."
@@ -978,19 +1093,22 @@ msgid "A deleted user"
msgstr "Удаленный пользователь"
msgid "A file with '%{file_name}' already exists in %{branch} branch"
-msgstr ""
+msgstr "Файл '%{file_name}' уже ÑущеÑтвует в ветке %{branch}"
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr "Ответвление - Ñто ÐºÐ¾Ð¿Ð¸Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°.<br />Ответвление Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»Ñет вноÑить изменениÑ, не влиÑÑ Ð½Ð° иÑходный проект."
-msgid "A group represents your organization in GitLab."
-msgstr "Группа предÑтавлÑет вашу организацию в GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
-msgid "A member of the abuse team will review your report as soon as possible."
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
+msgid "A member of the abuse team will review your report as soon as possible."
+msgstr "УчаÑтник команды по борьбе Ñ Ð½Ð°Ñ€ÑƒÑˆÐµÐ½Ð¸Ñми раÑÑмотрит ваш отчет при первой возможноÑти."
+
msgid "A merge request approval is required when a security report contains a new vulnerability of high, critical, or unknown severity."
-msgstr ""
+msgstr "Утверждение запроÑа на ÑлиÑние необходимо, когда отчет о безопаÑноÑти Ñодержит какую-либо новую уÑзвимоÑÑ‚ÑŒ выÑокой, критичеÑкой или неизвеÑтной ÑерьезноÑти."
msgid "A merge request approval is required when the license compliance report contains a blacklisted license."
msgstr "Утверждение запроÑа на ÑлиÑние требуетÑÑ, когда отчёт о комплаенÑе лицензий отноÑитÑÑ Ðº лицензии, включённой в чёрный ÑпиÑок."
@@ -999,10 +1117,10 @@ msgid "A new Auto DevOps pipeline has been created, go to %{pipelines_link_start
msgstr "ÐÐ¾Ð²Ð°Ñ ÑÐ±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ Auto DevOps Ñоздана, обратитеÑÑŒ к %{pipelines_link_start}Ñтранице, поÑвÑщенной Сборочным линиÑм%{pipelines_link_end} за подробноÑÑ‚Ñми"
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 "Ðовый релиз %{tag} Ð´Ð»Ñ %{name} опубликован. ПоÑетите Ñтраницу %{release_link_start}Релизов%{release_link_end}, чтобы узнать больше."
msgid "A new Release %{tag} for %{name} was published. Visit the Releases page to read more about it:"
-msgstr ""
+msgstr "Ðовый релиз %{tag} Ð´Ð»Ñ %{name} опубликован. ПоÑетите Ñтраницу Релизов, чтобы узнать больше:"
msgid "A new branch will be created in your fork and a new merge request will be started."
msgstr "Ð’ вашем ответвлении будет Ñоздана Ð½Ð¾Ð²Ð°Ñ Ð²ÐµÑ‚ÐºÐ° и запущен новый Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° ÑлиÑние."
@@ -1029,25 +1147,25 @@ msgid "A ready-to-go template for use with iOS Swift apps."
msgstr "Готовый шаблон Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñми iOS Swift."
msgid "A regular expression that will be used to find the test coverage output in the job log. Leave blank to disable"
-msgstr ""
+msgstr "РегулÑрное выражение, которое будет иÑпользоватьÑÑ Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка результатов Ð¿Ð¾ÐºÑ€Ñ‹Ñ‚Ð¸Ñ Ñ‚ÐµÑтами в логах заданиÑ. ОÑтавьте пуÑтым Ð´Ð»Ñ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ"
msgid "A secure token that identifies an external storage request."
msgstr "Токен безопаÑноÑти, который идентифицирует Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð²Ð½ÐµÑˆÐ½ÐµÐ³Ð¾ хранилища."
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
msgid "A terraform report was generated in your pipelines."
-msgstr ""
+msgstr "Отчёт Terraform был Ñгенерирован в ваших Ñборочных линиÑÑ…."
msgid "A user with write access to the source branch selected this option"
msgstr "Пользователь Ñ Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸ÐµÐ¼ на запиÑÑŒ в ветку иÑточника выбрал Ñтот вариант"
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
-msgstr ""
-
-msgid "API Help"
-msgstr "Справка по API"
+msgstr "ТРЕБУЕТСЯ ДЕЙСТВИЕ: Что-то пошло не так при получении Ñертификата Let's Encrypt Ð´Ð»Ñ Ð´Ð¾Ð¼ÐµÐ½Ð° GitLab Pages '%{domain}'"
msgid "API Token"
msgstr "API токен"
@@ -1094,11 +1212,8 @@ msgstr "ПринÑÑ‚ÑŒ уÑловиÑ"
msgid "Acceptable for use in this project"
msgstr "Разрешены к иÑпользованию в Ñтом проекте"
-msgid "Accepted MR"
-msgstr "ПринÑтый Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° ÑлиÑние"
-
msgid "Access Tokens"
-msgstr "Токены ДоÑтупа"
+msgstr "Токены доÑтупа"
msgid "Access denied for your LDAP account."
msgstr "ДоÑтуп запрещен Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ¹ учетной запиÑи LDAP."
@@ -1187,12 +1302,6 @@ msgstr "Ваш токен ÑтатичеÑких объектов иÑпольз
msgid "AccessTokens|reset it"
msgstr "ÑброÑить"
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr "Узнать больше"
@@ -1203,7 +1312,7 @@ msgid "AccessibilityReport|New"
msgstr "Ðовый"
msgid "AccessibilityReport|The accessibility scanning found an error of the following type: %{code}"
-msgstr ""
+msgstr "При Ñканировании доÑтупноÑти обнаружена ошибка типа %{code}"
msgid "Account"
msgstr "Ð£Ñ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ"
@@ -1218,7 +1327,7 @@ msgid "Account: %{account}"
msgstr "Ðккаунт: %{account}"
msgid "Action to take when receiving an alert."
-msgstr "ДейÑтвиÑ, предпринимаемые при получении предупреждениÑ."
+msgstr "ДейÑтвиÑ, предпринимаемые при получении оповещениÑ."
msgid "Activate"
msgstr "Ðктивировать"
@@ -1229,8 +1338,8 @@ msgstr "Ðктивировать Ñлужбу поддержки"
msgid "Active"
msgstr "Ðктивный"
-msgid "Active %{type} Tokens (%{token_length})"
-msgstr "Ðктивные токены %{type} (%{token_length})"
+msgid "Active %{type} (%{token_length})"
+msgstr ""
msgid "Active Sessions"
msgstr "Ðктивные ÑеÑÑии"
@@ -1238,6 +1347,9 @@ msgstr "Ðктивные ÑеÑÑии"
msgid "Active Users:"
msgstr "Ðктивные пользователи:"
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr "ÐктивноÑÑ‚ÑŒ"
@@ -1284,8 +1396,8 @@ msgstr "Добавить переменную"
msgid "Add Zoom meeting"
msgstr "ПриÑоединитьÑÑ Ðº вÑтрече в Zoom"
-msgid "Add a %{type} token"
-msgstr "Добавить токен %{type}"
+msgid "Add a %{type}"
+msgstr ""
msgid "Add a GPG key"
msgstr "Добавить ключ GPG"
@@ -1299,6 +1411,9 @@ msgstr "Добавить в ÑпиÑок задач"
msgid "Add a bullet list"
msgstr "Добавить маркированный ÑпиÑок"
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr "Добавить общий комментарий Ð´Ð»Ñ Ñтого %{noteableDisplayName}."
@@ -1308,9 +1423,15 @@ msgstr "Добавить общий комментарий к Ñтому %{notea
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr "Добавьте домашнюю Ñтраницу в Ñвою Wiki, в которой ÑодержитÑÑ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ вашем проекте, и GitLab отобразит ее здеÑÑŒ вмеÑто Ñтого ÑообщениÑ."
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr "Добавить ÑÑылку"
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr "Добавить нумерованный ÑпиÑок"
@@ -1326,8 +1447,11 @@ msgstr "Добавить дополнительный текÑÑ‚, который
msgid "Add an SSH key"
msgstr "Добавить SSH ключ"
-msgid "Add an existing issue to the epic."
-msgstr "Добавить ÑущеÑтвующее обÑуждение в цель."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
+msgstr ""
msgid "Add an issue"
msgstr "Добавить обÑуждение"
@@ -1392,6 +1516,9 @@ msgstr "Добавить реакцию"
msgid "Add request manually"
msgstr "Добавить Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð²Ñ€ÑƒÑ‡Ð½ÑƒÑŽ"
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr "Добавить ÑиÑтемный обработчик"
@@ -1482,18 +1609,18 @@ msgstr "ДобавлÑет вÑтречу в Zoom"
msgid "Adds an issue to an epic."
msgstr "К цели добавлÑетÑÑ Ð·Ð°Ð´Ð°Ñ‡Ð°."
-msgid "Adjust your filters/search criteria above."
-msgstr "ÐаÑтройте фильтры / критерии поиÑка выше."
+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 ""
msgid "Admin Area"
msgstr "Ðдмин панель"
+msgid "Admin Note"
+msgstr ""
+
msgid "Admin Overview"
msgstr "Обзор ÐдминиÑтратора"
-msgid "Admin Section"
-msgstr "Раздел ÐдминиÑтрированиÑ"
-
msgid "Admin mode already enabled"
msgstr "Режим админиÑтратора уже включен"
@@ -1519,7 +1646,7 @@ msgid "AdminArea|Bots"
msgstr "Боты"
msgid "AdminArea|Developer"
-msgstr ""
+msgstr "Developer"
msgid "AdminArea|Guest"
msgstr ""
@@ -1534,7 +1661,7 @@ msgid "AdminArea|Owner"
msgstr ""
msgid "AdminArea|Reporter"
-msgstr ""
+msgstr "Reporter"
msgid "AdminArea|Stop all jobs"
msgstr "ОÑтановить вÑе заданиÑ"
@@ -1624,7 +1751,7 @@ msgid "AdminSettings|Some settings have moved"
msgstr "Ðекоторые наÑтройки были перемещены"
msgid "AdminSettings|Specify a domain to use by default for every project's Auto Review Apps and Auto Deploy stages."
-msgstr "Укажите домен, который будет иÑпользоватьÑÑ Ð¿Ð¾ умолчанию Ð´Ð»Ñ Ð²Ñех проектов в Auto Review приложениÑÑ… и ÑтадиÑÑ… Auto Deploy."
+msgstr "Укажите домен, который будет иÑпользоватьÑÑ Ð¿Ð¾ умолчанию в приложениÑÑ… Auto Review, а также на Ñтапе автоматичеÑкого Ñ€Ð°Ð·Ð²ÐµÑ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ из проектов."
msgid "AdminSettings|The required pipeline configuration can be selected from the %{code_start}gitlab-ci%{code_end} directory inside of the configured %{link_start}instance template repository%{link_end} or from GitLab provided configurations."
msgstr "Ð¢Ñ€ÐµÐ±ÑƒÐµÐ¼Ð°Ñ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ñборки может быть выбрана из каталога %{code_start}gitlab-ci%{code_end} внутри %{link_start}Ñконфигурированного хранилища ÑкземплÑров шаблонов%{link_end} или из предоÑтавленных GitLab конфигурации."
@@ -1818,90 +1945,162 @@ msgstr "ПоÑле уÑпешного Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð²Ñ‹ бÑ
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr "ПоÑле уÑпешного Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð²Ñ‹ будете перенаправлены на Ñтраницу входа, где вы можете войти Ñ Ð½Ð¾Ð²Ñ‹Ð¼ паролем."
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
-msgstr[0] "Предупреждение"
-msgstr[1] "Предупреждений"
-msgstr[2] "Предупреждений"
-msgstr[3] "Предупреждений"
+msgstr[0] "Оповещение"
+msgstr[1] "ОповещениÑ"
+msgstr[2] "Оповещений"
+msgstr[3] "Оповещений"
-msgid "Alert Details"
+msgid "AlertManagement|Acknowledged"
+msgstr "Прочитано"
+
+msgid "AlertManagement|Alert"
+msgstr "Оповещение"
+
+msgid "AlertManagement|Alert detail"
msgstr ""
-msgid "AlertManagement|Acknowledged"
+msgid "AlertManagement|Alert details"
msgstr ""
-msgid "AlertManagement|Alert"
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
msgstr ""
msgid "AlertManagement|Authorize external service"
+msgstr "Ðвторизовать внешнюю Ñлужбу"
+
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
msgstr ""
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 "Выводите ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¾Ñ‚ вÑех Ñвоих инÑтрументов мониторинга непоÑредÑтвенно в Gitlab. УпроÑтите раÑÑмотрение оповещений и их превращение в инциденты."
+
+msgid "AlertManagement|Edit"
msgstr ""
msgid "AlertManagement|End time"
-msgstr ""
+msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð¾ÐºÐ¾Ð½Ñ‡Ð°Ð½Ð¸Ñ"
+
+msgid "AlertManagement|Events"
+msgstr "СобытиÑ"
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|High"
msgstr ""
-msgid "AlertManagement|Events"
+msgid "AlertManagement|Info"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
+msgstr "Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ"
+
+msgid "AlertManagement|No alert data to display."
msgstr ""
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
-msgstr ""
+msgstr "Ðет оповещений Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ. ЕÑли, по-вашему, вы видите Ñто Ñообщение по ошибке, обновите Ñтраницу."
msgid "AlertManagement|No alerts to display."
+msgstr "Ðет оповещений Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ."
+
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
msgstr ""
msgid "AlertManagement|Overview"
+msgstr "Обзор"
+
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
msgstr ""
msgid "AlertManagement|Resolved"
+msgstr "Обработано"
+
+msgid "AlertManagement|Service"
msgstr ""
msgid "AlertManagement|Severity"
-msgstr ""
+msgstr "СерьёзноÑÑ‚ÑŒ"
msgid "AlertManagement|Start time"
-msgstr ""
-
-msgid "AlertManagement|Start time:"
-msgstr ""
+msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð½Ð°Ñ‡Ð°Ð»Ð°"
msgid "AlertManagement|Status"
-msgstr ""
+msgstr "СоÑтоÑние"
msgid "AlertManagement|Surface alerts in GitLab"
+msgstr "Вывод оповещений в GitLab"
+
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
msgstr ""
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
+msgstr "Произошла ошибка при отображении оповещений. Проверьте наÑтройки конечной точки, чтобы убедитьÑÑ, что Ð¾Ð¿Ð¾Ð²ÐµÑ‰ÐµÐ½Ð¸Ñ Ð¿Ð¾ÐºÐ°Ð·Ñ‹Ð²Ð°ÑŽÑ‚ÑÑ."
+
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
msgstr ""
msgid "AlertManagement|Triggered"
+msgstr "Получено"
+
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
-msgstr "%{linkStart}Узнайте подробнее%{linkEnd} о наÑтройке Ñтой конечной точки Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¾Ð¿Ð¾Ð²ÐµÑ‰ÐµÐ½Ð¸Ð¹."
+msgid "AlertManagement|View issue"
+msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
-msgstr "Каждый иÑточник оповещений должен быть авторизован Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ Ñледующего URL и ключа авторизации."
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
+msgstr ""
msgid "Alerts"
msgstr "ОповещениÑ"
msgid "Alerts endpoint"
-msgstr "ÐšÐ¾Ð½ÐµÑ‡Ð½Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° оповещений"
+msgstr "Точка Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¾Ð¿Ð¾Ð²ÐµÑ‰ÐµÐ½Ð¸Ð¹"
msgid "Algorithm"
msgstr "Ðлгоритм"
@@ -1961,7 +2160,7 @@ msgid "All security scans are enabled because %{linkStart}Auto DevOps%{linkEnd}
msgstr ""
msgid "All threads resolved"
-msgstr ""
+msgstr "Ð’Ñе темы решены"
msgid "All users"
msgstr "Ð’Ñе пользователи"
@@ -1970,7 +2169,7 @@ msgid "All users must have a name."
msgstr "У вÑех пользователей должно быть имÑ."
msgid "Allow \"%{group_name}\" to sign you in"
-msgstr ""
+msgstr "Разрешить %{group_name} Ð²Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñать"
msgid "Allow commits from members who can merge to the target branch."
msgstr "Разрешить коммиты от учаÑтников, которые могут выполнÑÑ‚ÑŒ ÑлиÑние Ñ Ñ†ÐµÐ»ÐµÐ²Ð¾Ð¹ веткой."
@@ -1979,7 +2178,7 @@ msgid "Allow group owners to manage LDAP-related settings"
msgstr "Разрешить владельцам групп управлÑÑ‚ÑŒ наÑтройками, ÑвÑзанными Ñ LDAP"
msgid "Allow only the selected protocols to be used for Git access."
-msgstr ""
+msgstr "Разрешить иÑпользовать только выбранные протоколы Ð´Ð»Ñ Ð´Ð¾Ñтупа к Git."
msgid "Allow owners to manage default branch protection per group"
msgstr ""
@@ -1988,7 +2187,7 @@ msgid "Allow owners to manually add users outside of LDAP"
msgstr "Разрешить владельцам вручную добавлÑÑ‚ÑŒ пользователей вне LDAP"
msgid "Allow projects within this group to use Git LFS"
-msgstr ""
+msgstr "Разрешить проектам в Ñтой группе иÑпользовать Git LFS"
msgid "Allow public access to pipelines and job details, including output logs and artifacts"
msgstr ""
@@ -2063,14 +2262,17 @@ msgid "Amount of time (in hours) that users are allowed to skip forced configura
msgstr "Ð’Ñ€ÐµÐ¼Ñ (в чаÑах), на которое пользователÑм позволено пропуÑкать принудительную наÑтройку двухфакторной аутентификации"
msgid "An alert has been triggered in %{project_path}."
-msgstr "Предупреждение было вызвано в %{project_path}."
+msgstr "Оповещение было вызвано в %{project_path}."
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr "Приложение под названием %{link_to_client} запрашивает доÑтуп к вашей учетной запиÑи GitLab."
-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."
+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 "ПуÑтое значение в поле Пользователь Gitlab добавит полное Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ FogBugz (напр., \"От Ивана Кузнецова\") в опиÑание вÑех обÑуждений и комментариев, а также ÑвÑжет и/или назначит Ñти обÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð¸ комментарии Ñ Ñоздателем проекта."
+
msgid "An error has occurred"
msgstr "Произошла ошибка"
@@ -2117,7 +2319,7 @@ msgid "An error occurred while checking group path"
msgstr "Произошла ошибка при проверке пути группы"
msgid "An error occurred while committing your changes."
-msgstr ""
+msgstr "Произошла ошибка во Ð²Ñ€ÐµÐ¼Ñ Ñ„Ð¸ÐºÑации изменений."
msgid "An error occurred while decoding the file."
msgstr "Произошла ошибка при декодировании файла."
@@ -2138,7 +2340,7 @@ msgid "An error occurred while disabling Service Desk."
msgstr "Произошла ошибка при отключении Ñлужбы поддержки."
msgid "An error occurred while dismissing the alert. Refresh the page and try again."
-msgstr "При отключении Ð¿Ñ€ÐµÐ´ÑƒÐ¿Ñ€ÐµÐ¶Ð´ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ð¸Ð·Ð¾ÑˆÐ»Ð° ошибка. Обновите Ñтраницу и повторите попытку."
+msgstr "При отклонении Ð¾Ð¿Ð¾Ð²ÐµÑ‰ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ð¸Ð·Ð¾ÑˆÐ»Ð° ошибка. Обновите Ñтраницу и повторите попытку."
msgid "An error occurred while dismissing the feature highlight. Refresh the page and try dismissing again."
msgstr "Произошла ошибка при отключении ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¾ функции. Обновите Ñтраницу и повторите попытку."
@@ -2168,7 +2370,7 @@ msgid "An error occurred while fetching markdown preview"
msgstr "Произошла ошибка при предварительном проÑмотре markdown"
msgid "An error occurred while fetching pending comments"
-msgstr ""
+msgstr "Во Ð²Ñ€ÐµÐ¼Ñ Ð¸Ð·Ð²Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ Ð¾Ð¶Ð¸Ð´Ð°ÑŽÑ‰Ð¸Ñ… комментариев произошла ошибка"
msgid "An error occurred while fetching projects autocomplete."
msgstr ""
@@ -2177,19 +2379,19 @@ msgid "An error occurred while fetching sidebar data"
msgstr "Произошла ошибка при получении денег данных Ð´Ð»Ñ Ð±Ð¾ÐºÐ¾Ð²Ð¾Ð¹ панели"
msgid "An error occurred while fetching terraform reports."
-msgstr ""
+msgstr "Произошла ошибка при получении отчётов Terraform."
msgid "An error occurred while fetching the Service Desk address."
-msgstr ""
+msgstr "Произошла ошибка при получении адреÑа Службы поддержки."
msgid "An error occurred while fetching the board lists. Please try again."
msgstr "Произошла ошибка при получении ÑпиÑка панелей управлениÑ. ПожалуйÑта, попробуйте ещё раз."
msgid "An error occurred while fetching the builds."
-msgstr ""
+msgstr "Произошла ошибка при получении Ñборок."
msgid "An error occurred while fetching the job log."
-msgstr ""
+msgstr "Произошла ошибка при получении журнала заданий."
msgid "An error occurred while fetching the job trace."
msgstr "Произошла ошибка при извлечении траÑÑировки заданиÑ."
@@ -2233,9 +2435,6 @@ msgstr "Произошла ошибка при загрузке вÑех файÐ
msgid "An error occurred while loading chart data"
msgstr "Произошла ошибка при загрузке данных диаграммы "
-msgid "An error occurred while loading clusters"
-msgstr "Произошла ошибка при загрузке клаÑтеров"
-
msgid "An error occurred while loading commit signatures"
msgstr "Произошла ошибка при загрузке подпиÑей коммита"
@@ -2257,6 +2456,9 @@ msgstr "Произошла ошибка при загрузке обÑужден
msgid "An error occurred while loading merge requests."
msgstr "Произошла ошибка при загрузке запроÑов на ÑлиÑние."
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr "Произошла ошибка при загрузке отчёта Terraform"
@@ -2288,13 +2490,13 @@ msgid "An error occurred while loading the pipelines jobs."
msgstr ""
msgid "An error occurred while loading the subscription details."
-msgstr ""
+msgstr "Произошла ошибка при загрузке Ñведений о подпиÑке."
msgid "An error occurred while making the request."
msgstr "Произошла ошибка при выполнении запроÑа."
msgid "An error occurred while moving the issue."
-msgstr ""
+msgstr "Произошла ошибка при перемещении обÑуждениÑ."
msgid "An error occurred while parsing recent searches"
msgstr ""
@@ -2332,9 +2534,12 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr "Произошла ошибка во Ð²Ñ€ÐµÐ¼Ñ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½Ð°. ПожалуйÑта, проверьте, ÑущеÑтвует ли шаблон."
-msgid "An error occurred while subscribing to notifications."
+msgid "An error occurred while searching for milestones"
msgstr ""
+msgid "An error occurred while subscribing to notifications."
+msgstr "При подпиÑке на ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ð¸Ð·Ð¾ÑˆÐ»Ð° ошибка."
+
msgid "An error occurred while triggering the job."
msgstr "Произошла ошибка при запуÑке заданиÑ."
@@ -2342,7 +2547,7 @@ msgid "An error occurred while trying to run a new pipeline for this Merge Reque
msgstr ""
msgid "An error occurred while unsubscribing to notifications."
-msgstr ""
+msgstr "При отпиÑке от уведомлений произошла ошибка."
msgid "An error occurred while updating approvers"
msgstr ""
@@ -2368,9 +2573,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr "Домен Serverless ÑƒÑ€Ð¾Ð²Ð½Ñ ÑкземплÑра уже ÑущеÑтвует."
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr "Ðа обÑуждение может выноÑитÑÑ Ð±Ð°Ð³, задача или Ð·Ð°Ð¿Ñ€Ð¾Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° быть раÑÑмотрена в проекте. Кроме того, обÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð´Ð¾Ñтупны Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка и фильтрации."
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr "Произошла Ð½ÐµÐ¿Ñ€ÐµÐ´Ð²Ð¸Ð´ÐµÐ½Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° при проверке Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°."
@@ -2386,6 +2597,9 @@ msgstr "Произошла Ð½ÐµÐ¿Ñ€ÐµÐ´Ð²Ð¸Ð´ÐµÐ½Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° при за
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr "Произошла Ð½ÐµÐ¿Ñ€ÐµÐ´Ð²Ð¸Ð´ÐµÐ½Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° при оÑтановке Web Terminal."
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr "Ðналитика"
@@ -2395,6 +2609,9 @@ msgstr "Проанализировать рецензируемую верÑию
msgid "Analyze your dependencies for known vulnerabilities."
msgstr "Ðнализируйте ваши завиÑимоÑти на предмет извеÑтных уÑзвимоÑтей."
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr "Ðнализируйте ваш иÑходный код на предмет извеÑтных уÑзвимоÑтей."
@@ -2408,7 +2625,7 @@ msgid "Another action is currently in progress"
msgstr "Другое дейÑтвие уже в процеÑÑе"
msgid "Another issue tracker is already in use. Only one issue tracker service can be active at a time"
-msgstr ""
+msgstr "Ð”Ñ€ÑƒÐ³Ð°Ñ ÑиÑтема ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»Ñ Ð¾Ð±Ñуждений уже иÑпользуетÑÑ. Только одна Ñ‚Ð°ÐºÐ°Ñ ÑиÑтема может быть активна одновременно."
msgid "Anti-spam verification"
msgstr "Ðнти-Ñпам проверка"
@@ -2419,12 +2636,6 @@ msgstr "Любой"
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr "Ð›ÑŽÐ±Ð°Ñ ÐœÐµÑ‚ÐºÐ°"
-
-msgid "Any Milestone"
-msgstr "Любой Ñтап"
-
msgid "Any branch"
msgstr "Ð›ÑŽÐ±Ð°Ñ Ð²ÐµÑ‚ÐºÐ°"
@@ -2434,9 +2645,15 @@ msgstr "Любой подходÑщий пользователь"
msgid "Any encrypted tokens"
msgstr "Любые зашифрованные токены"
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr "Любой учаÑтник проекта Ñ Ð¿Ñ€Ð°Ð²Ð°Ð¼Ð¸ Разработчика или более выÑокими."
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr "Любое проÑтранÑтво имен"
@@ -2456,7 +2673,7 @@ msgid "Appearance was successfully updated."
msgstr "Внешний вид уÑпешно изменен."
msgid "Append the comment with %{shrug}"
-msgstr ""
+msgstr "Добавить комментарий Ñ %{shrug}"
msgid "Append the comment with %{tableflip}"
msgstr "Добавить комментарий Ñ %{tableflip}"
@@ -2500,6 +2717,9 @@ msgstr "Применить метку"
msgid "Apply a template"
msgstr "Применение шаблона"
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr "Применить предложение"
@@ -2516,10 +2736,10 @@ msgid "Applying command"
msgstr "Применение команды"
msgid "Applying command to %{commandDescription}"
-msgstr ""
+msgstr "Применение команды к %{commandDescription}"
msgid "Applying multiple commands"
-msgstr ""
+msgstr "Применение неÑкольких команд"
msgid "Applying suggestion"
msgstr "Применение предложениÑ"
@@ -2576,12 +2796,6 @@ msgstr "Ð¦ÐµÐ»ÐµÐ²Ð°Ñ Ð²ÐµÑ‚ÐºÐ°"
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr "например, QA, Security и т. д."
-msgid "Approvals"
-msgstr "СоглаÑованиÑ"
-
-msgid "Approvals (you've approved)"
-msgstr "Ð£Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ (ваши)"
-
msgid "Approve"
msgstr "Одобрить"
@@ -2591,12 +2805,18 @@ msgstr "Утвердить Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° ÑлиÑние"
msgid "Approve the current merge request."
msgstr "Утвердить текущий Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° ÑлиÑние."
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr "Утверждено: "
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr "Утверждающий"
@@ -2661,7 +2881,7 @@ msgid "Are you sure you want to delete this board?"
msgstr "Ð’Ñ‹ уверены, что дейÑтвительно хотите удалить Ñту доÑку?"
msgid "Are you sure you want to delete this device? This action cannot be undone."
-msgstr ""
+msgstr "Ð’Ñ‹ уверены, что хотите удалить Ñто уÑтройÑтво? Это дейÑтвие не может быть отменено."
msgid "Are you sure you want to delete this list?"
msgstr "Ð’Ñ‹ уверены, что вы хотите удалить Ñтот ÑпиÑок?"
@@ -2685,13 +2905,13 @@ msgid "Are you sure you want to lose unsaved changes?"
msgstr "Ð’Ñ‹ уверены, что вы хотите потерÑÑ‚ÑŒ не Ñохранённые изменениÑ?"
msgid "Are you sure you want to lose your issue information?"
-msgstr ""
+msgstr "Ð’Ñ‹ уверены, что хотите потерÑÑ‚ÑŒ информацию об обÑуждении?"
msgid "Are you sure you want to merge immediately?"
msgstr ""
msgid "Are you sure you want to permanently delete this license?"
-msgstr ""
+msgstr "Ð’Ñ‹ дейÑтвительно хотите безвозвратно удалить Ñту лицензию?"
msgid "Are you sure you want to re-deploy this environment?"
msgstr ""
@@ -2703,6 +2923,9 @@ msgid "Are you sure you want to remove %{group_name}?"
msgstr "Вы уверены, что вы хотите удалить %{group_name}?"
msgid "Are you sure you want to remove the attachment?"
+msgstr "Ð’Ñ‹ дейÑтвительно хотите удалить вложение?"
+
+msgid "Are you sure you want to remove the license?"
msgstr ""
msgid "Are you sure you want to remove this identity?"
@@ -2717,8 +2940,8 @@ msgstr "Ð’Ñ‹ уверены, что хотите ÑброÑить токен SCI
msgid "Are you sure you want to reset the health check token?"
msgstr "Ð’Ñ‹ уверены, что хотите ÑброÑить Ñтот токен проверки работоÑпоÑобноÑти?"
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
-msgstr "Ð’Ñ‹ уверены, что хотите отозвать Ñтот %{type} токен? Это дейÑтвие не может быть отменено."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
+msgstr ""
msgid "Are you sure you want to revoke this nickname?"
msgstr "Ð’Ñ‹ уверены, что хотите отменить Ñтот ник?"
@@ -2730,7 +2953,7 @@ msgid "Are you sure you want to unlock %{path_lock_path}?"
msgstr "Вы уверены, что вы хотите разблокировать %{path_lock_path}?"
msgid "Are you sure you want to unsubscribe from the %{type}: %{link_to_noteable_text}?"
-msgstr ""
+msgstr "Ð’Ñ‹ дейÑтвительно хотите отпиÑатьÑÑ Ð¾Ñ‚ %{type}: %{link_to_noteable_text}?"
msgid "Are you sure?"
msgstr "Вы уверены?"
@@ -2796,7 +3019,7 @@ msgid "Assets:"
msgstr "РеÑурÑÑ‹:"
msgid "Assign"
-msgstr ""
+msgstr "Ðазначить"
msgid "Assign custom color like #FF0000"
msgstr "Ðазначьте пользовательÑкий цвет, например #FF0000"
@@ -2817,10 +3040,10 @@ msgid "Assign to"
msgstr "Ðазначить"
msgid "Assign yourself to these issues"
-msgstr ""
+msgstr "ВзÑÑ‚ÑŒ на ÑÐµÐ±Ñ Ñти обÑуждениÑ"
msgid "Assign yourself to this issue"
-msgstr ""
+msgstr "ВзÑÑ‚ÑŒ на ÑÐµÐ±Ñ Ñто обÑуждение"
msgid "Assigned %{assignee_users_sentence}."
msgstr "Ðазначены %{assignee_users_sentence}."
@@ -2831,6 +3054,9 @@ msgstr "Ðазначенные обÑуждениÑ"
msgid "Assigned Merge Requests"
msgstr "Ðазначенные запроÑÑ‹ на ÑлиÑние"
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr "Ðазначить мне"
@@ -2842,10 +3068,10 @@ msgstr[2] "%d Ðазначенных"
msgstr[3] "%d Ðазначенных"
msgid "Assignee lists not available with your current license"
-msgstr ""
+msgstr "СпиÑки назначенных не доÑтупны Ñ Ð²Ð°ÑˆÐµÐ¹ текущей лицензией"
msgid "Assignee lists show all issues assigned to the selected user."
-msgstr ""
+msgstr "СпиÑки иÑполнителей показывают вÑе обÑуждениÑ, назначенные выбранному пользователю."
msgid "Assignee(s)"
msgstr "ОтветÑтвенный(ные)"
@@ -2863,7 +3089,7 @@ msgid "At least one of group_id or project_id must be specified"
msgstr ""
msgid "At risk"
-msgstr ""
+msgstr "Под угрозой"
msgid "Attach a file"
msgstr "Прикрепить файл"
@@ -2882,13 +3108,13 @@ msgid "Attaching the file failed."
msgstr "Ðе удалоÑÑŒ прикрепить файл."
msgid "Audit Events"
-msgstr ""
+msgstr "Ðудит Ñобытий"
msgid "Audit Events is a way to keep track of important events that happened in GitLab."
msgstr ""
msgid "AuditEvents|(removed)"
-msgstr ""
+msgstr "(удалено)"
msgid "AuditEvents|Action"
msgstr "ДейÑтвие"
@@ -2911,15 +3137,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr "Ðвг."
@@ -2966,7 +3210,7 @@ msgid "Authorization code:"
msgstr "Код авторизации:"
msgid "Authorization key"
-msgstr ""
+msgstr "Ключ авторизации"
msgid "Authorization was granted by entering your username and password in the application."
msgstr ""
@@ -2977,6 +3221,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr "ÐвторизуйтеÑÑŒ %{link_to_client} Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð²Ð°ÑˆÐµÐ¹ учетной запиÑи?"
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr "Ðвторизован %{new_chat_name}"
@@ -2998,14 +3245,11 @@ msgstr "Auto DevOps включен"
msgid "Auto DevOps, runners and job artifacts"
msgstr "ÐвтоматичеÑкий DevOps, обработчики и артефакты заданий"
-msgid "Auto License Compliance"
-msgstr "ÐвтоматичеÑÐºÐ°Ñ Ñлужба комплаенÑа лицензий"
-
msgid "Auto stop successfully canceled."
-msgstr ""
+msgstr "ÐвтоматичеÑÐºÐ°Ñ Ð¾Ñтановка уÑпешно отменена."
msgid "Auto-cancel redundant, pending pipelines"
-msgstr ""
+msgstr "ÐвтоматичеÑÐºÐ°Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ð° избыточных, ожидающих Ñборочных линий"
msgid "Auto-close referenced issues on default branch"
msgstr ""
@@ -3019,6 +3263,9 @@ msgstr "ÐвтоматичеÑкий DevOps может автоматичеÑкÐ
msgid "AutoDevOps|Auto DevOps documentation"
msgstr "Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ Ð¿Ð¾ Auto DevOps"
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr "Включить в наÑтройках"
@@ -3049,6 +3296,9 @@ msgstr "ÐвтоматичеÑкое управление Ñертификата
msgid "Automatic certificate management using Let's Encrypt"
msgstr "ÐвтоматичеÑкое управление Ñертификатами Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ Let's Encrypt"
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -3064,6 +3314,9 @@ msgstr "Заметка"
msgid "Available"
msgstr "ДоÑтупен"
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr "ДоÑÑ‚ÑƒÐ¿Ð½Ð°Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð° runner'ов: %{runners}"
@@ -3203,13 +3456,13 @@ msgid "BambooService|You must set up automatic revision labeling and a repositor
msgstr "Ð’Ñ‹ должны наÑтроить автоматичеÑкое приÑвоение меток ревизиÑм и триггер Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸Ñ Ð² ÑервиÑе Bamboo."
msgid "BatchComments|Delete all pending comments"
-msgstr "Удалить вÑе находÑщиеÑÑ Ð½Ð° раÑÑмотрении комментарии"
+msgstr "Удалить вÑе ожидающие комментарии"
msgid "BatchComments|Discard review?"
msgstr "Закрыть отзыв без ÑохранениÑ?"
msgid "BatchComments|You're about to discard your review which will delete all of your pending comments. The deleted comments %{strong_start}cannot%{strong_end} be restored."
-msgstr ""
+msgstr "Ð’Ñ‹ ÑобираетеÑÑŒ отменить рецензию, что приведет к удалению вÑех ожидающих комментариев. Удалённые комментарии %{strong_start}невозможно%{strong_end} воÑÑтановить."
msgid "Be careful. Changing the project's namespace can have unintended side effects."
msgstr "Будьте оÑторожны. Изменение пути проекта может вызвать нежелательные побочные Ñффекты."
@@ -3541,20 +3794,20 @@ msgstr "Открыть приоритет задачи"
msgid "BurndownChartLabel|Open issues"
msgstr "Открыть обÑуждениÑ"
+msgid "Burnup chart"
+msgstr ""
+
msgid "Business"
msgstr "БизнеÑ"
msgid "Business metrics (Custom)"
-msgstr ""
+msgstr "БизнеÑ-метрики (наÑтраиваемые)"
-msgid "Buy EE"
-msgstr "Купить EE"
-
-msgid "Buy GitLab Enterprise Edition"
-msgstr "Купить верÑию GitLab Enterprise"
+msgid "Buy License"
+msgstr ""
msgid "Buy more Pipeline minutes"
-msgstr ""
+msgstr "Купить минут Ð´Ð»Ñ CI"
msgid "By %{user_name}"
msgstr "От %{user_name}"
@@ -3574,8 +3827,8 @@ msgstr "CHANGELOG"
msgid "CI / CD"
msgstr "CI / CD"
-msgid "CI / CD Charts"
-msgstr "Графики CI / CD"
+msgid "CI / CD Analytics"
+msgstr ""
msgid "CI / CD Settings"
msgstr "ÐаÑтройки CI / CD"
@@ -3583,6 +3836,9 @@ msgstr "ÐаÑтройки CI / CD"
msgid "CI Lint"
msgstr "CI Lint"
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr "Переменные CI"
@@ -3601,6 +3857,9 @@ msgstr "CI/CD Ð´Ð»Ñ Ð²Ð½ÐµÑˆÐ½ÐµÐ³Ð¾ репозиториÑ"
msgid "CI/CD settings"
msgstr "ÐаÑтройки CI/CD"
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr "ÐвтоматичеÑкий DevOps"
@@ -3631,9 +3890,6 @@ msgstr "Сборка Auto DevOps будет запущена, еÑли не бу
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr "Ð’Ñ‹ должны добавить %{base_domain_link_start}базовый домен%{link_end} в Ñвой %{kubernetes_cluster_link_start}Kubernetes клаÑтер%{link_end} Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы ваша ÑÑ‚Ñ€Ð°Ñ‚ÐµÐ³Ð¸Ñ Ñ€Ð°Ð·Ð²ÐµÑ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ð°Ð»Ð°."
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr "Ð”Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы ÑÑ‚Ñ€Ð°Ñ‚ÐµÐ³Ð¸Ñ Ñ€Ð°Ð·Ð²ÐµÑ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾ работала, необходимо добавить в Ñтот проект %{kubernetes_cluster_link_start}интеграцию клаÑтера Kubernetes%{link_end} Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼."
-
msgid "CICD|group enabled"
msgstr "группа включена"
@@ -3661,11 +3917,17 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr "Ðевозможно найти HEAD-коммит Ñтой ветки"
msgid "Can't find variable: ZiteReader"
-msgstr ""
+msgstr "Ðе удаётÑÑ Ð½Ð°Ð¹Ñ‚Ð¸ переменную: ZiteReader"
msgid "Can't load mermaid module: %{err}"
msgstr "Ðе удалоÑÑŒ загрузить Mermaid-модуль: %{err}"
@@ -3710,7 +3972,7 @@ msgid "Cannot create the abuse report. This user has been blocked."
msgstr ""
msgid "Cannot have multiple Jira imports running at the same time"
-msgstr ""
+msgstr "Ðевозможно проводить одновременно неÑколько импортов из Jira"
msgid "Cannot import because issues are not available in this project."
msgstr "Ðе удаётÑÑ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ, потому что обÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð½Ðµ доÑтупны в Ñтом проекте."
@@ -3736,7 +3998,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3751,6 +4013,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr "Сертификат"
@@ -3767,10 +4032,10 @@ msgid "Change assignee"
msgstr "Изменить иÑполнителÑ"
msgid "Change assignee(s)"
-msgstr ""
+msgstr "Изменить иÑполнителÑ(ей)"
msgid "Change assignee(s)."
-msgstr ""
+msgstr "Изменить иÑполнителÑ(ей)."
msgid "Change branches"
msgstr "Сменить ветки"
@@ -3787,6 +4052,12 @@ msgstr "Изменить путь"
msgid "Change permissions"
msgstr "Изменить разрешениÑ"
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr "Изменить шаблон"
@@ -3829,6 +4100,9 @@ msgstr "ИзменениÑ"
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr "Показаны Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÐºÐ°Ðº будто произошло ÑлиÑние ревизии кода <b>иÑточника</b> Ñ <b>целевой</b> ревизией кода."
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3847,6 +4121,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr "Изменение пути группы может иметь побочные Ñффекты."
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3952,15 +4229,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr "Платёжный адреÑ"
@@ -4115,7 +4383,7 @@ msgid "Choose a group"
msgstr "Выберите группу"
msgid "Choose a role permission"
-msgstr "Выберите разрешение роли"
+msgstr "Выберите роль"
msgid "Choose a template"
msgstr "Выберите шаблон"
@@ -4309,9 +4577,6 @@ msgstr "Проверка не удалаÑÑŒ"
msgid "Class"
msgstr "КлаÑÑ"
-msgid "Class:"
-msgstr "КлаÑÑ:"
-
msgid "Classification Label (optional)"
msgstr "Метка клаÑÑификации (опционально)"
@@ -4324,9 +4589,12 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
-msgid "Clear input"
+msgid "Clear due date"
msgstr ""
+msgid "Clear input"
+msgstr "ОчиÑтить ввод"
+
msgid "Clear recent searches"
msgstr "ОчиÑтить поÑледние запроÑÑ‹"
@@ -4336,6 +4604,9 @@ msgstr "ОчиÑтить поиÑк"
msgid "Clear search input"
msgstr "ОчиÑтить Ñтроку поиÑка"
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr "ОчиÑтить шаблоны ввода данных Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка"
@@ -4363,9 +4634,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr "Ðажмите кнопку ниже, чтобы начать процеÑÑ ÑƒÑтановки, Ð¿ÐµÑ€ÐµÐ¹Ð´Ñ Ð½Ð° Ñтраницу Kubernetes"
-msgid "Click the image where you'd like to start a new discussion"
-msgstr "Ðажмите на тот образ, где вы хотите начать новую диÑкуÑÑию"
-
msgid "Click to expand it."
msgstr "Ðажмите, чтобы развернуть."
@@ -4373,10 +4641,10 @@ msgid "Click to expand text"
msgstr "Ðажмите, чтобы раÑкрыть текÑÑ‚"
msgid "Client authentication certificate"
-msgstr ""
+msgstr "Сертификат аутентификации клиента"
msgid "Client authentication key"
-msgstr ""
+msgstr "Ключ аутентификации клиента"
msgid "Client authentication key password"
msgstr ""
@@ -4405,14 +4673,17 @@ msgstr "Клонировать Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ SSH"
msgid "Close"
msgstr "Закрыть"
-msgid "Close %{tabname}"
+msgid "Close %{display_issuable_type}"
msgstr ""
+msgid "Close %{tabname}"
+msgstr "Закрыть %{tabname}"
+
msgid "Close epic"
msgstr "Завершить цель"
msgid "Close milestone"
-msgstr ""
+msgstr "Закрыть Ñтап"
msgid "Close sidebar"
msgstr ""
@@ -4436,7 +4707,7 @@ msgid "Closes this %{quick_action_target}."
msgstr ""
msgid "Cluster"
-msgstr ""
+msgstr "КлаÑтер"
msgid "Cluster Health"
msgstr ""
@@ -4538,7 +4809,7 @@ msgid "ClusterIntegration|An error occurred while trying to fetch zone machine t
msgstr "Произошла ошибка при попытке извлечь типы машин облаÑти: %{error}"
msgid "ClusterIntegration|Any running pipelines will be canceled."
-msgstr ""
+msgstr "Любые запущенные Ñборочные линии будут отменены."
msgid "ClusterIntegration|Apply for credit"
msgstr "Подать заÑвку на кредит"
@@ -4600,6 +4871,9 @@ msgstr "Проект ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ ÐºÐ»Ð°Ñтером (alpha)"
msgid "ClusterIntegration|Cluster name is required."
msgstr "ТребуетÑÑ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ðµ клаÑтера."
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr "КлаÑтеры иÑпользуютÑÑ Ð¿ÑƒÑ‚Ñ‘Ð¼ выбора ближайшего предка Ñ Ð¿Ð¾Ð´Ñ…Ð¾Ð´Ñщей облаÑтью видимоÑти Ñреды. Ðапример, клаÑтеры проектов будут переопределÑÑ‚ÑŒ клаÑтеры групп."
@@ -4621,9 +4895,6 @@ msgstr "Скопировать точку Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Knative"
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr "Скопировать Ð¸Ð¼Ñ ÐºÐ»Ð°Ñтера Kubernetes"
-msgid "ClusterIntegration|Copy Service Token"
-msgstr "Скопировать токен ÑервиÑа"
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr "Ðе удалоÑÑŒ загрузить IAM роли"
@@ -4675,7 +4946,7 @@ msgstr "СоздаетÑÑ ÐºÐ»Ð°Ñтер Kubernetes"
msgid "ClusterIntegration|Crossplane"
msgstr "Crossplane"
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4702,6 +4973,9 @@ msgstr "Включите Ñтот параметр, еÑли иÑпользуеÑ
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr "Введите параметры Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ клаÑтера Amazon EKS Kubernetes"
@@ -4780,12 +5054,12 @@ msgstr "КлаÑтер группы"
msgid "ClusterIntegration|Helm Tiller"
msgstr "Helm Tiller"
+msgid "ClusterIntegration|Helm release failed to install"
+msgstr ""
+
msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr "Приложение Helm упрощает уÑтановку и управление приложениÑми Kubernetes. Приложение Tiller запуÑкаетÑÑ Ð²Ð½ÑƒÑ‚Ñ€Ð¸ вашего клаÑтера Kubernetes и управлÑет релизами ваших реÑурÑов."
-msgid "ClusterIntegration|Hide"
-msgstr "Скрыть"
-
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
msgstr "ЕÑли вы наÑтраиваете неÑколько клаÑтеров и вы иÑпользуете Auto DevOps, %{help_link_start}прочтите Ñто%{help_link_end}."
@@ -4919,7 +5193,7 @@ msgid "ClusterIntegration|Loading subnets"
msgstr "Загрузка подÑетей"
msgid "ClusterIntegration|Loading subnetworks"
-msgstr ""
+msgstr "Загрузка подÑетей"
msgid "ClusterIntegration|Logging mode"
msgstr ""
@@ -4942,6 +5216,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr "Ðе найдены VPC"
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -4967,7 +5247,7 @@ msgid "ClusterIntegration|No subnet found"
msgstr "ПодÑети не найдены"
msgid "ClusterIntegration|No subnetworks found"
-msgstr ""
+msgstr "ПодÑети не найдены"
msgid "ClusterIntegration|No zones matched your search"
msgstr "Ðет зон, ÑоответÑтвующих вашему поиÑковому запроÑу"
@@ -5057,7 +5337,7 @@ msgid "ClusterIntegration|SIEM Port"
msgstr ""
msgid "ClusterIntegration|SIEM Protocol"
-msgstr ""
+msgstr "Протокол SIEM"
msgid "ClusterIntegration|Save changes"
msgstr "Сохранить изменениÑ"
@@ -5176,9 +5456,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr "Показать"
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr " У Ð½Ð°Ñ Ñ‡Ñ‚Ð¾-то пошло не так."
@@ -5257,6 +5534,9 @@ msgstr "Переключить клаÑтер Kubernetes"
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr "Удалить %{appTitle}"
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr "Обновление не удалоÑÑŒ. ПожалуйÑта, проверьте журналы и попытайтеÑÑŒ Ñнова."
@@ -5287,6 +5567,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr "Ð’Ñ‹ ÑобираетеÑÑŒ удалить %{appTitle} из вашего клаÑтера."
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr "Перед уÑтановкой приложений ниже вы должны уÑтановить Helm Tiller"
@@ -5296,7 +5579,13 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr "Ð”Ð»Ñ ÑƒÑтановки Knative необходимо иметь клаÑтер Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ¾Ð¹ RBAC."
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
+msgstr "Ðеобходимо выбрать как минимум две подÑети"
+
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
msgstr ""
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
@@ -5345,7 +5634,7 @@ msgid "ClusterIntergation|Select a subnet"
msgstr "Выберите подÑеть"
msgid "ClusterIntergation|Select a subnetwork"
-msgstr ""
+msgstr "Выберите подÑеть"
msgid "ClusterIntergation|Select an instance type"
msgstr ""
@@ -5356,6 +5645,9 @@ msgstr "Выберите пару ключей"
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr "Код"
@@ -5372,6 +5664,9 @@ msgid "Code Review"
msgstr ""
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 "Ðналитика Ð ÐµÑ†ÐµÐ½Ð·Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°ÐµÑ‚ ÑпиÑок открытых запроÑов на ÑлиÑние, которые находÑÑ‚ÑÑ Ð½Ð° Ñтадии проверки кода. Ð’ наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ проекта и/или фильтров отÑутÑтвуют рецензируемые запроÑÑ‹ на ÑлиÑние."
+
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
msgstr ""
msgid "Code owner approval is required"
@@ -5413,6 +5708,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr "Свернуть дочерние цели"
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr "Свернуть панель"
@@ -5422,6 +5720,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr "ComboSearch не определен"
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5438,10 +5739,10 @@ msgid "Comment"
msgstr "Комментарий"
msgid "Comment & close %{noteable_name}"
-msgstr ""
+msgstr "Комментировать и закрыть %{noteable_name}"
msgid "Comment & reopen %{noteable_name}"
-msgstr ""
+msgstr "Комментировать и переоткрыть %{noteable_name}"
msgid "Comment & resolve thread"
msgstr ""
@@ -5458,6 +5759,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr "Комментарий/Ответ (цитирование выделенного текÑта)"
@@ -5475,10 +5779,10 @@ msgid "Commit %{commit_id}"
msgstr "Коммит %{commit_id}"
msgid "Commit (when editing commit message)"
-msgstr ""
+msgstr "Коммит (при редактировании опиÑÐ°Ð½Ð¸Ñ ÐºÐ¾Ð¼Ð¼Ð¸Ñ‚Ð°)"
msgid "Commit Message"
-msgstr "ОпиÑание Коммита"
+msgstr "ОпиÑание коммита"
msgid "Commit deleted"
msgstr "Коммит удален"
@@ -5487,7 +5791,7 @@ msgid "Commit message"
msgstr "ОпиÑание коммита"
msgid "Commit message (optional)"
-msgstr ""
+msgstr "ОпиÑание коммита (необÑзательно)"
msgid "Commit statistics for %{ref} %{start_time} - %{end_time}"
msgstr "СтатиÑтика коммитов Ð´Ð»Ñ %{ref} в период Ñ %{start_time} по %{end_time}"
@@ -5592,13 +5896,13 @@ msgid "Compliance framework (optional)"
msgstr "Фреймворк комплаенÑа (необÑзательно)"
msgid "ComplianceFramework|GDPR"
-msgstr ""
+msgstr "GDPR"
msgid "ComplianceFramework|GDPR - General Data Protection Regulation"
msgstr "GDPR - общий регламент по защите данных"
msgid "ComplianceFramework|HIPAA"
-msgstr ""
+msgstr "HIPAA"
msgid "ComplianceFramework|HIPAA - Health Insurance Portability and Accountability Act"
msgstr "HIPAA - акт о мобильноÑти и подотчётноÑти медицинÑкого ÑтрахованиÑ"
@@ -5616,12 +5920,15 @@ msgid "ComplianceFramework|SOC 2 - Service Organization Control 2"
msgstr "SOC 2 - Service Organization Control 2"
msgid "ComplianceFramework|SOX"
-msgstr ""
+msgstr "SOX"
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr "SOX - акт Сарбейнза - ОкÑли"
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5645,9 +5952,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr "ÐаÑтройте безопаÑноÑÑ‚ÑŒ %{wordBreakOpportunity}и комплаенÑ"
-
msgid "Configure Tracing"
msgstr ""
@@ -5667,7 +5971,7 @@ 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 "ÐаÑтройте Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð½Ð° количеÑтво входÑщих предупреждений, которые могут быть отправлены в проект."
+msgstr "ÐаÑтройте Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð½Ð° количеÑтво входÑщих оповещений, которые могут быть отправлены в проект."
msgid "Configure paths to be protected by Rack Attack."
msgstr ""
@@ -5681,9 +5985,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5732,16 +6033,10 @@ msgstr "Ошибка подключениÑ"
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr "СвÑжитеÑÑŒ Ñ Ð²Ð»Ð°Ð´ÐµÐ»ÑŒÑ†ÐµÐ¼ группы %{namespace_name} чтобы обновить тарифный план."
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr "СвÑзатьÑÑ Ñ Ð²Ð»Ð°Ð´ÐµÐ»ÑŒÑ†ÐµÐ¼ %{link_start}%{owner_name}%{link_end} чтобы обновить тарифный план."
-
msgid "Contact sales to upgrade"
msgstr "СвÑзатьÑÑ Ñ Ð¾Ñ‚Ð´ÐµÐ»Ð¾Ð¼ продаж Ð´Ð»Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ"
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5757,7 +6052,7 @@ msgid "Container does not exist"
msgstr "Контейнер не ÑущеÑтвует"
msgid "Container registry images"
-msgstr "Образы Docker Registry"
+msgstr "Образы рееÑтра контейнеров"
msgid "Container registry is not enabled on this GitLab instance. Ask an administrator to enable it in order for Auto DevOps to work."
msgstr ""
@@ -5768,6 +6063,20 @@ msgstr "Объем Ñинхронизации рееÑтра контейнерÐ
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr "%{imageName} тегов"
@@ -5780,6 +6089,9 @@ msgstr "ÐвтоматичеÑки удалÑÑ‚ÑŒ лишние образы, нÐ
msgid "ContainerRegistry|Build an image"
msgstr "Собрать образ"
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr "Сжатый размер"
@@ -5804,27 +6116,39 @@ msgstr "Ошибка Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Docker"
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
-msgstr "Редактировать наÑтройки"
-
msgid "ContainerRegistry|Expiration interval:"
msgstr "Интервал иÑтечениÑ:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr "Политика иÑÑ‚ÐµÑ‡ÐµÐ½Ð¸Ñ ÑƒÑпешно Ñохранена."
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr "Политика иÑтечениÑ:"
msgid "ContainerRegistry|Expiration schedule:"
msgstr "РаÑпиÑание иÑтечениÑ:"
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr "ID образа"
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr "СохранÑÑ‚ÑŒ и защищать образы, которые имеют наибольшее значение."
@@ -5841,22 +6165,19 @@ msgid "ContainerRegistry|Number of tags to retain:"
msgstr "КоличеÑтво тегов Ð´Ð»Ñ ÑохранениÑ:"
msgid "ContainerRegistry|Please contact your administrator."
-msgstr ""
+msgstr "ПожалуйÑта, ÑвÑжитеÑÑŒ Ñ Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñтратором."
msgid "ContainerRegistry|Push an image"
msgstr "Отправить образ"
-msgid "ContainerRegistry|Quick Start"
-msgstr "БыÑтрый Ñтарт"
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
-msgstr ""
+msgstr "ПоддерживаютÑÑ Ñ€ÐµÐ³ÑƒÐ»Ñрные выражениÑ, такие как %{codeStart}.*-test%{codeEnd} или %{codeStart}dev-.*%{codeEnd}. Чтобы выбрать вÑе теги, иÑпользуйте %{codeStart}.*%{codeEnd}"
msgid "ContainerRegistry|Remember to run %{docLinkStart}garbage collection%{docLinkEnd} to remove the stale data from storage."
-msgstr ""
+msgstr "Ðе забудьте запуÑтить %{docLinkStart}Ñборку муÑора%{docLinkEnd}, чтобы удалить уÑтаревшие данные из хранилища."
msgid "ContainerRegistry|Remove repository"
msgstr "Удалить репозиторий"
@@ -5871,23 +6192,20 @@ msgstr[1] "Удалить тега"
msgstr[2] "Удалить тегов"
msgstr[3] "Удалить тегов"
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr "Политика ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð±Ñ‹Ð»Ð° включена"
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr "Что-то пошло не так при извлечении политики иÑтечениÑ."
msgid "ContainerRegistry|Something went wrong while fetching the repository list."
-msgstr ""
+msgstr "Что-то пошло не так при извлечении ÑпиÑка репозиториев."
msgid "ContainerRegistry|Something went wrong while fetching the tags list."
msgstr "Что-то пошло не так при извлечении ÑпиÑка тегов."
msgid "ContainerRegistry|Something went wrong while marking the tag for deletion."
-msgstr ""
+msgstr "Что-то пошло не так при отметке тега к удалению."
msgid "ContainerRegistry|Something went wrong while marking the tags for deletion."
-msgstr ""
+msgstr "Что-то пошло не так при отметке тегов к удалению."
msgid "ContainerRegistry|Something went wrong while scheduling %{title} for deletion. Please try again."
msgstr ""
@@ -5895,6 +6213,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr "Что-то пошло не так во Ð²Ñ€ÐµÐ¼Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»Ð¸Ñ‚Ð¸ÐºÐ¸ иÑтечениÑ."
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr "Тег"
@@ -5914,20 +6235,14 @@ msgid "ContainerRegistry|Tags with names matching this regex pattern will %{ital
msgstr ""
msgid "ContainerRegistry|Tags with names matching this regex pattern will %{italicStart}expire:%{italicEnd}"
-msgstr ""
+msgstr "Теги Ñ Ð¸Ð¼ÐµÐ½Ð°Ð¼Ð¸, ÑоответÑтвующими Ñтому регулÑрному выражению, будут %{italicStart}проÑрочены:%{italicEnd}"
msgid "ContainerRegistry|The Container Registry tag expiration and retention policies for this project have not been enabled."
-msgstr ""
+msgstr "Политика иÑÑ‚ÐµÑ‡ÐµÐ½Ð¸Ñ Ñрока дейÑÑ‚Ð²Ð¸Ñ Ð¸ Ñрока Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ñ‚ÐµÐ³Ð¾Ð² РееÑтра Контейнеров данного проекта не задавалаÑÑŒ."
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr "ПоÑледний тег, ÑвÑзанный Ñ Ñтим образом недавно был удалён. Этот пуÑтой образ и любые ÑвÑзанные Ñ Ð½Ð¸Ð¼ данные будут автоматичеÑки удалены в ходе регулÑрной Ñборки муÑора. ЕÑли у Ð²Ð°Ñ ÐµÑÑ‚ÑŒ вопроÑÑ‹, ÑвÑжитеÑÑŒ Ñо Ñвоим админиÑтратором."
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5944,10 +6259,13 @@ msgid "ContainerRegistry|This image has no active tags"
msgstr "Этот образ не имеет активных тегов"
msgid "ContainerRegistry|This image repository is scheduled for deletion"
+msgstr "Запланировано удаление Ñтого хранилища образов"
+
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
-msgstr "Мы не можем подключитьÑÑ Ðº Docker, что может быть вызвано проблемой Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ или путём вашего проекта. %{docLinkStart}ÐŸÐ¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ%{docLinkEnd}"
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
msgstr "С рееÑтром контейнеров каждый проект может иметь Ñвое меÑто Ð´Ð»Ñ Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ñвоих Docker образов. %{docLinkStart}ÐŸÐ¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ%{docLinkEnd}"
@@ -5955,8 +6273,8 @@ msgstr "С рееÑтром контейнеров каждый проект мÐ
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
-msgstr "С помощью РееÑтра Docker Контейнеров, интегрированного в GitLab, каждый проект может иметь Ñвое ÑобÑтвенное проÑтранÑтво Ð´Ð»Ñ Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ñвоих Docker образов. %{docLinkStart}ÐŸÐ¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
msgstr "Ð’Ñ‹ ÑобираетеÑÑŒ удалить %{item} тегов. Ð’Ñ‹ уверены?"
@@ -5994,10 +6312,10 @@ msgstr "УчаÑтие"
msgid "Contribution Analytics"
msgstr "Ðналитика вкладов"
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -6040,7 +6358,7 @@ msgid "Contributors"
msgstr "УчаÑтники"
msgid "Control emails linked to your account"
-msgstr ""
+msgstr "Управление адреÑами Ñлектронной почты, ÑвÑзанными Ñ Ð²Ð°ÑˆÐµÐ¹ учетной запиÑью"
msgid "Control the display of third party offers."
msgstr ""
@@ -6058,7 +6376,7 @@ msgid "Control the maximum concurrency of verification operations for this Geo n
msgstr ""
msgid "Control the minimum interval in days that a repository should be reverified for this primary node"
-msgstr ""
+msgstr "Задайте минимальный интервал в днÑÑ…, поÑле которого репозиторий должен быть перепроверен Ð´Ð»Ñ Ñтого оÑновного узла"
msgid "Cookie domain"
msgstr ""
@@ -6084,6 +6402,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr "Копировать %{proxy_url}"
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -6106,7 +6427,7 @@ msgid "Copy URL"
msgstr ""
msgid "Copy branch name"
-msgstr ""
+msgstr "Копировать Ð¸Ð¼Ñ Ð²ÐµÑ‚ÐºÐ¸"
msgid "Copy command"
msgstr ""
@@ -6115,7 +6436,7 @@ msgid "Copy commands"
msgstr ""
msgid "Copy commit SHA"
-msgstr ""
+msgstr "Копировать SHA-Ñумму коммита"
msgid "Copy environment"
msgstr ""
@@ -6129,11 +6450,8 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
-msgstr ""
+msgstr "Скопировать ключ"
msgid "Copy labels and milestone from %{source_issuable_reference}."
msgstr "Копировать метки и Ñтап из %{source_issuable_reference}."
@@ -6147,9 +6465,6 @@ msgstr "Копировать ÑÑылку"
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6157,7 +6472,7 @@ msgid "Copy secret"
msgstr ""
msgid "Copy token"
-msgstr ""
+msgstr "Копировать токен"
msgid "Copy trigger token"
msgstr ""
@@ -6178,7 +6493,7 @@ msgid "Could not connect to FogBugz, check your URL"
msgstr ""
msgid "Could not connect to Sentry. Refresh the page to try again."
-msgstr ""
+msgstr "Ðе удалоÑÑŒ подключитьÑÑ Ðº Sentry. Обновите Ñтраницу, чтобы повторить попытку."
msgid "Could not connect to Web IDE file mirror service."
msgstr ""
@@ -6244,9 +6559,9 @@ msgid "Create"
msgstr "Создать"
msgid "Create %{environment}"
-msgstr ""
+msgstr "Создать %{environment}"
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6264,9 +6579,6 @@ msgstr "Сначала Ñоздайте учетную запиÑÑŒ GitLab, а Ð
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6277,7 +6589,7 @@ msgid "Create a new branch"
msgstr "Создать новую ветку"
msgid "Create a new deploy key for this project"
-msgstr ""
+msgstr "Создать новый ключ Ñ€Ð°Ð·Ð²Ñ‘Ñ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ Ñтого проекта."
msgid "Create a new file as there are no files yet. Afterwards, you'll be able to commit your changes."
msgstr "Создайте новый файл, поÑкольку еще нет файлов. ПоÑле Ñтого вы Ñможете зафикÑировать Ñвои изменениÑ."
@@ -6285,9 +6597,6 @@ msgstr "Создайте новый файл, поÑкольку еще нет Ñ
msgid "Create a new issue"
msgstr "Создать новое обÑуждение"
-msgid "Create a new issue and add it to the epic."
-msgstr "Создать новое обÑуждение и добавить его в цель."
-
msgid "Create a new repository"
msgstr "Создать новый репозиторий"
@@ -6297,11 +6606,8 @@ msgstr "Создать личный токен на аккаунте Ð´Ð»Ñ Ð¿Ð¾
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues 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>repo</code> scope, so we can display a list of your public and private repositories which are available to import."
msgstr ""
@@ -6342,6 +6648,9 @@ msgstr "Создать метку группы"
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr "Создать ÑпиÑок из меток. ОбÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ñ Ñтой меткой поÑвлÑÑŽÑ‚ÑÑ Ð² Ñтом ÑпиÑке."
@@ -6352,6 +6661,9 @@ msgid "Create merge request and branch"
msgstr "Создать Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° ÑлиÑние и ветку"
msgid "Create milestone"
+msgstr "Создать Ñтап"
+
+msgid "Create new"
msgstr ""
msgid "Create new board"
@@ -6385,7 +6697,7 @@ msgid "Create requirement"
msgstr "Создать требование"
msgid "Create snippet"
-msgstr ""
+msgstr "Создать Ñниппет"
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -6393,6 +6705,12 @@ msgstr ""
msgid "Create your first page"
msgstr "Создайте вашу первую Ñтраницу"
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr "У Ð²Ð°Ñ Ð½ÐµÑ‚ прав на Ñоздание подгруппы в Ñтой группе."
@@ -6426,6 +6744,9 @@ msgstr ""
msgid "Created by me"
msgstr "Создано мной"
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6477,9 +6798,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr "Ð’Ñ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð·Ð¾Ð½Ð° Cron"
-msgid "Cron syntax"
-msgstr "СинтакÑÐ¸Ñ Cron"
-
msgid "Crossplane"
msgstr ""
@@ -6516,9 +6834,12 @@ msgstr "ÐаÑтройки"
msgid "CurrentUser|Start a Gold trial"
msgstr "Ðачать пробный период Gold"
-msgid "Custom CI configuration path"
+msgid "CurrentUser|Upgrade"
msgstr ""
+msgid "Custom CI configuration path"
+msgstr "ПользовательÑкий путь конфигурации CI"
+
msgid "Custom Git clone URL for HTTP(S)"
msgstr ""
@@ -6540,23 +6861,26 @@ msgstr "ПользовательÑкие шаблоны проекта не бы
msgid "Custom range"
msgstr ""
-msgid "CustomCycleAnalytics|Add a stage"
+msgid "Custom range (UTC)"
msgstr ""
+msgid "CustomCycleAnalytics|Add a stage"
+msgstr "Добавить Ñтап"
+
msgid "CustomCycleAnalytics|Add stage"
-msgstr ""
+msgstr "Добавить Ñтап"
msgid "CustomCycleAnalytics|Editing stage"
-msgstr ""
+msgstr "Редактиование Ñтапа"
msgid "CustomCycleAnalytics|Enter a name for the stage"
-msgstr ""
+msgstr "Введите название Ñтапа"
msgid "CustomCycleAnalytics|Name"
msgstr ""
msgid "CustomCycleAnalytics|New stage"
-msgstr ""
+msgstr "Ðовый Ñтап"
msgid "CustomCycleAnalytics|Please select a start event first"
msgstr ""
@@ -6568,7 +6892,7 @@ msgid "CustomCycleAnalytics|Select stop event"
msgstr ""
msgid "CustomCycleAnalytics|Stage name already exists"
-msgstr ""
+msgstr "Ð˜Ð¼Ñ Ñтапа уже ÑущеÑтвует"
msgid "CustomCycleAnalytics|Start event"
msgstr ""
@@ -6586,6 +6910,9 @@ msgid "CustomCycleAnalytics|Stop event label"
msgstr "Метка конечного ÑобытиÑ"
msgid "CustomCycleAnalytics|Update stage"
+msgstr "Обновить Ñтап"
+
+msgid "Customer Portal"
msgstr ""
msgid "Customize colors"
@@ -6612,6 +6939,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6622,7 +6952,7 @@ msgid "CycleAnalyticsEvent|Issue first added to a board"
msgstr ""
msgid "CycleAnalyticsEvent|Issue first associated with a milestone"
-msgstr ""
+msgstr "ОбÑуждение, первым добавленное в Ñтап"
msgid "CycleAnalyticsEvent|Issue first associated with a milestone or issue first added to a board"
msgstr "Задача первоначально ÑвÑÐ·Ð°Ð½Ð½Ð°Ñ Ñ Ñтапом или другой задаче впервые добавлена на доÑку"
@@ -6685,22 +7015,22 @@ msgid "CycleAnalyticsStage|Test"
msgstr "ТеÑтирование"
msgid "CycleAnalyticsStage|Total"
-msgstr ""
+msgstr "Ð’Ñего"
msgid "CycleAnalyticsStage|is not available for the selected group"
-msgstr ""
+msgstr "недоÑтупно Ð´Ð»Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð¾Ð¹ группы"
msgid "CycleAnalyticsStage|should be under a group"
-msgstr ""
+msgstr "должен быть в группе"
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr "%{selectedLabelsCount} выбрано (макÑимум — %{maxLabels})"
msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
+msgstr "%{stageCount} Ñтапов выбрано"
msgid "CycleAnalytics|All stages"
-msgstr "Ð’Ñе Ñтадии"
+msgstr "Ð’Ñе Ñтапы"
msgid "CycleAnalytics|Date"
msgstr ""
@@ -6712,13 +7042,13 @@ msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|No stages selected"
-msgstr ""
+msgstr "Этапы не выбраны"
msgid "CycleAnalytics|Number of tasks"
msgstr ""
msgid "CycleAnalytics|Only %{maxLabels} labels can be selected at this time"
-msgstr ""
+msgstr "Ð’ наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð¼Ð¾Ð³ÑƒÑ‚ быть выбраны только %{maxLabels} меток"
msgid "CycleAnalytics|Project selected"
msgid_plural "CycleAnalytics|%d projects selected"
@@ -6743,7 +7073,7 @@ msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{startDate} to
msgstr ""
msgid "CycleAnalytics|Stages"
-msgstr "Стадии"
+msgstr "Этапы"
msgid "CycleAnalytics|Tasks by type"
msgstr ""
@@ -6767,7 +7097,7 @@ msgid "CycleAnalytics|project dropdown filter"
msgstr "Выпадающий фильтр проекта"
msgid "CycleAnalytics|stage dropdown"
-msgstr "Выпадающий ÑпиÑок Ñтадий"
+msgstr "Выпадающий ÑпиÑок Ñтапов"
msgid "DAG"
msgstr ""
@@ -6803,7 +7133,7 @@ msgid "Data is still calculating..."
msgstr "Данные вÑе еще вычиÑлÑÑŽÑ‚ÑÑ..."
msgid "Date"
-msgstr ""
+msgstr "Дата"
msgid "Date picker"
msgstr ""
@@ -6865,11 +7195,14 @@ msgstr "Ветвь по умолчанию и защищенные ветки"
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
msgid "Default description template for issues"
-msgstr ""
+msgstr "Шаблон опиÑÐ°Ð½Ð¸Ñ Ð¾Ð±Ñуждений по умолчанию."
msgid "Default description template for merge requests"
msgstr "Шаблон опиÑÐ°Ð½Ð¸Ñ Ð¿Ð¾ умолчанию Ð´Ð»Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñов на ÑлиÑние"
@@ -6881,7 +7214,7 @@ msgid "Default first day of the week in calendars and date pickers."
msgstr ""
msgid "Default issue template"
-msgstr ""
+msgstr "Шаблон обÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð¿Ð¾ умолчанию"
msgid "Default project deletion protection"
msgstr ""
@@ -6890,7 +7223,7 @@ msgid "Default projects limit"
msgstr ""
msgid "Default stages"
-msgstr ""
+msgstr "Этапы по умолчанию"
msgid "Default: Directly import the Google Code email address or username"
msgstr ""
@@ -6901,6 +7234,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr "Определить наÑтраиваемый шаблон Ñ ÑинтакÑиÑом cron"
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr "Обозначьте Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ Ð½Ð° Ñтапе(ах) Ñ€Ð°Ð·Ð²Ñ‘Ñ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð² <code>.gitlab-ci.yml</code> Ð´Ð»Ñ Ð¾Ñ‚ÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ñ€Ð°Ð·Ð²Ñ‘Ñ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð·Ð´ÐµÑÑŒ."
@@ -6943,6 +7279,12 @@ msgstr "Удалить комментарий"
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr "Удалить лицензию"
@@ -7001,7 +7343,7 @@ msgid "Deleted in this version"
msgstr "Удалено в Ñтой верÑии"
msgid "Deleting"
-msgstr ""
+msgstr "Идет удаление"
msgid "Deleting the license failed."
msgstr ""
@@ -7019,7 +7361,7 @@ msgid "Denied authorization of chat nickname %{user_name}."
msgstr "Отказано в авторизации под чат никнеймом %{user_name}."
msgid "Deny"
-msgstr ""
+msgstr "Отклонить"
msgid "Dependencies"
msgstr ""
@@ -7034,13 +7376,6 @@ msgstr[1] "%d дополнительных уÑзвимоÑти не показÐ
msgstr[2] "%d дополнительных уÑзвимоÑтей не показано"
msgstr[3] "%d дополнительных уÑзвимоÑтей не показано"
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] "%d уÑзвимоÑÑ‚ÑŒ"
-msgstr[1] "%d уÑзвимоÑти"
-msgstr[2] "%d уÑзвимоÑтей"
-msgstr[3] "%d уÑзвимоÑтей"
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -7055,7 +7390,7 @@ msgid "Dependencies|All"
msgstr "Ð’Ñе"
msgid "Dependencies|Based on the %{linkStart}latest successful%{linkEnd} scan"
-msgstr ""
+msgstr "Ðа оÑновании %{linkStart}поÑледнего уÑпешного%{linkEnd} ÑканированиÑ"
msgid "Dependencies|Component"
msgstr ""
@@ -7078,12 +7413,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr "Упаковщик"
-msgid "Dependencies|Safe"
-msgstr "БезопаÑно"
-
-msgid "Dependencies|Status"
-msgstr "СтатуÑ"
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr "Произошел Ñбой Ð·Ð°Ð´Ð°Ð½Ð¸Ñ %{codeStartTag}dependency_scanning%{codeEndTag} и не получилоÑÑŒ Ñгенерировать ÑпиÑок. ПожалуйÑта, убедитеÑÑŒ, что задание работает правильно и Ñнова запуÑтите Ñборку."
@@ -7093,9 +7422,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr "Обнаружен(ы) неподдерживаемый файл(ы)"
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr "УÑзвимые компоненты"
@@ -7145,13 +7471,13 @@ msgstr[2] "Развертываний"
msgstr[3] "РазвертываниÑ"
msgid "Deploy Keys"
-msgstr "Ключи РазвертываниÑ"
+msgstr "Ключи развёртываниÑ"
msgid "Deploy key was successfully updated."
msgstr "Ключ Ñ€Ð°Ð·Ð²ÐµÑ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ ÑƒÑпешно обновлен."
msgid "Deploy keys allow read-only or read-write (if enabled) access to your repository. Deploy keys can be used for CI, staging or production servers. You can create a deploy key or add an existing one."
-msgstr ""
+msgstr "Ключи Ñ€Ð°Ð·Ð²Ñ‘Ñ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»ÑÑŽÑ‚ получить доÑтуп к вашему репозиторию как в режиме только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ, так и чтениÑ-запиÑи (еÑли разрешено). Они могут быть иÑпользованы Ð´Ð»Ñ Ð½ÐµÐ¿Ñ€ÐµÑ€Ñ‹Ð²Ð½Ð¾Ð¹ интеграции, Ñтейдж- и продакшн-Ñерверов. Можете Ñоздать новый ключ Ñ€Ð°Ð·Ð²Ñ‘Ñ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð¸Ð»Ð¸ добавить ÑущеÑтвующий."
msgid "Deploy progress not found. To see pods, ensure your environment matches %{linkStart}deploy board criteria%{linkEnd}."
msgstr "ПрогреÑÑ Ñ€Ð°Ð·Ð²ÐµÑ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ найден. Чтобы увидеть поды, убедитеÑÑŒ, что ваша Ñреда ÑоответÑтвует %{linkStart}критериÑм уÑтановки таблицы%{linkEnd}."
@@ -7216,12 +7542,18 @@ msgstr "Ðктивные токены Ñ€Ð°Ð·Ð²ÐµÑ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ (%{active_token
msgid "DeployTokens|Add a deploy token"
msgstr "Создать токен развертываниÑ"
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr "Разрешает доÑтуп только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ðº региÑтру образов"
msgid "DeployTokens|Allows read-only access to the repository"
msgstr "Разрешает доÑтуп только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ðº репозиторию"
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7243,13 +7575,13 @@ msgstr "Формат по умолчанию \"gitlab+deploy-token-{n}\". Вве
msgid "DeployTokens|Deploy Tokens"
msgstr "Токены развертываниÑ"
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr "ИÑтекает"
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7271,7 +7603,7 @@ msgid "DeployTokens|Scopes"
msgstr "ОблаÑти"
msgid "DeployTokens|This %{entity_type} has no active Deploy Tokens."
-msgstr ""
+msgstr "%{entity_type} не имеет токенов развертываниÑ."
msgid "DeployTokens|This action cannot be undone."
msgstr "Это дейÑтвие Ð½ÐµÐ»ÑŒÐ·Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ."
@@ -7286,13 +7618,13 @@ msgid "DeployTokens|Username"
msgstr "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ"
msgid "DeployTokens|You are about to revoke %{b_start}%{name}%{b_end}."
-msgstr ""
+msgstr "Ð’Ñ‹ ÑобираетеÑÑŒ отозвать %{b_start}%{name}%{b_end}."
msgid "DeployTokens|Your New Deploy Token"
msgstr "Ваш Ðовый Токен РазвертываниÑ"
msgid "DeployTokens|Your new group deploy token has been created."
-msgstr ""
+msgstr "Создан новый токен Ñ€Ð°Ð·Ð²ÐµÑ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ñ‹."
msgid "DeployTokens|Your new project deploy token has been created."
msgstr "Создан новый токен Ð´Ð»Ñ Ñ€Ð°Ð·Ð²ÐµÑ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°."
@@ -7361,7 +7693,7 @@ msgid "Deselect all"
msgstr ""
msgid "Design Management files and data"
-msgstr ""
+msgstr "Данные и файлы ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð¸Ð·Ð°Ð¹Ð½Ð°Ð¼Ð¸"
msgid "DesignManagement|%{current_design} of %{designs_count}"
msgstr "%{current_design} из %{designs_count}"
@@ -7369,19 +7701,34 @@ msgstr "%{current_design} из %{designs_count}"
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
-msgstr "Добавить проект"
-
msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr "Добавление Ñтруктуры Ñ Ñ‚ÐµÐ¼ же именем файла заменÑет файл в новой верÑии."
-msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
+msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
+msgstr "Ð’Ñ‹ дейÑтвительно хотите отменить Ñоздание Ñтого комментариÑ?"
+
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr "Вы уверены, что хотите удалить выбранные дизайны?"
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
+msgstr "Отменить подтверждение комментариÑ"
+
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
msgstr ""
msgid "DesignManagement|Could not add a new comment. Please try again."
@@ -7393,6 +7740,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr "Удалить"
@@ -7420,12 +7770,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7433,6 +7798,12 @@ msgid "DesignManagement|The maximum number of designs allowed to be uploaded is
msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
+msgstr "Чтобы включить управление дизайном, вы должны %{requirements_link_start}ÑоответÑтвовать требованиÑм%{requirements_link_end}. ЕÑли вам нужна помощь, обратитеÑÑŒ за помощью в нашу %{support_link_start}Ñлужбу поддержки%{support_link_end}."
+
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
msgstr ""
msgid "DesignManagement|Upload skipped."
@@ -7445,6 +7816,9 @@ msgid "Designs"
msgstr "Дизайны"
msgid "Destroy"
+msgstr "Уничтожить"
+
+msgid "Detail"
msgstr ""
msgid "Details"
@@ -7514,7 +7888,7 @@ msgid "Disabled mirrors can only be enabled by instance owners. It is recommende
msgstr "Отключенные зеркала могут быть включены только владельцами ÑкземплÑров. РекомендуетÑÑ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ их."
msgid "Discard all changes"
-msgstr ""
+msgstr "Отменить вÑе изменениÑ"
msgid "Discard all changes?"
msgstr ""
@@ -7544,19 +7918,19 @@ msgid "Discover projects, groups and snippets. Share your projects with others"
msgstr "ИÑÑледуйте проекты, группы и Ñниппеты. ПоделитеÑÑŒ вашими проектами Ñ Ð´Ñ€ÑƒÐ³Ð¸Ð¼Ð¸ людьми"
msgid "Discover|Check your application for security vulnerabilities that may lead to unauthorized access, data leaks, and denial of services."
-msgstr ""
+msgstr "Проверьте ваше приложение на наличие уÑзвимоÑтей, которые могут привеÑти к неÑанкционированному доÑтупу, утечкам данных и отказам в обÑлуживании."
msgid "Discover|For code that's already live in production, our dashboards give you an easy way to prioritize any issues that are found, empowering your team to ship quickly and securely."
-msgstr ""
+msgstr "Ð”Ð»Ñ ÐºÐ¾Ð´Ð°, который уже находитÑÑ Ð² производÑтве, наши панели инÑтрументов предлагают проÑтой ÑпоÑоб приоритезировать вÑе найденные проблемы, Ð´ÐµÐ»Ð°Ñ Ð²Ð°ÑˆÑƒ команду ÑпоÑобной выдавать результат быÑтро и безопаÑно."
msgid "Discover|GitLab will perform static and dynamic tests on the code of your application, looking for known flaws and report them in the merge request so you can fix them before merging."
-msgstr ""
+msgstr "GitLab выполнит ÑтатичеÑкие и динамичеÑкие теÑÑ‚Ñ‹ в коде вашего Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð² поиÑке извеÑтных дефектов и Ñообщит о них в запроÑе на ÑлиÑние, так чтобы вы могли иÑправить их перед завершением запроÑа."
msgid "Discover|Give feedback for this page"
msgstr ""
msgid "Discover|Security capabilities, integrated into your development lifecycle"
-msgstr ""
+msgstr "СредÑтва безопаÑноÑти, интегрированные в жизненный цикл вашей разработки"
msgid "Discover|See the other features of the %{linkStart}gold plan%{linkEnd}"
msgstr "Узнайте о других возможноÑÑ‚ÑÑ… %{linkStart}тарифного плана Gold%{linkEnd}"
@@ -7676,6 +8050,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr "Ðе вÑтавлÑйте закрытую чаÑÑ‚ÑŒ ключа GPG. Ð’Ñтавьте открытую чаÑÑ‚ÑŒ, начинающуюÑÑ Ð½Ð° «----- BEGIN PGP PUBLIC KEY BLOCK -----»."
@@ -7724,6 +8101,9 @@ msgstr "Загрузить изображение"
msgid "Download license"
msgstr "Скачать лицензию"
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr "Скачать иÑходный код"
@@ -7748,6 +8128,9 @@ msgstr "ГолоÑа \"против\""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr "Дата завершениÑ"
@@ -7776,7 +8159,7 @@ msgid "Edit %{issuable}"
msgstr "Редактировать %{issuable}"
msgid "Edit %{name}"
-msgstr ""
+msgstr "Редактировать %{name}"
msgid "Edit Comment"
msgstr ""
@@ -7785,7 +8168,7 @@ msgid "Edit Deploy Key"
msgstr ""
msgid "Edit Geo Node"
-msgstr ""
+msgstr "Редактировать узел Geo"
msgid "Edit Group Hook"
msgstr ""
@@ -7794,7 +8177,7 @@ msgid "Edit Label"
msgstr "Редактировать метку"
msgid "Edit Milestone"
-msgstr ""
+msgstr "Изменить Ñтап"
msgid "Edit Password"
msgstr "Изменить пароль"
@@ -7848,7 +8231,7 @@ msgid "Edit public deploy key"
msgstr ""
msgid "Edit stage"
-msgstr ""
+msgstr "Редактировать Ñтап"
msgid "Edit this release"
msgstr ""
@@ -7895,9 +8278,12 @@ msgstr "Ð­Ð»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð°Ñ Ð¿Ð¾Ñ‡Ñ‚Ð°"
msgid "Email address"
msgstr ""
-msgid "Email display name"
+msgid "Email could not be sent"
msgstr ""
+msgid "Email display name"
+msgstr "Отображаемое Ð¸Ð¼Ñ Ð´Ð»Ñ Ñл. почты"
+
msgid "Email not verified. Please verify your email in Salesforce."
msgstr "Ð­Ð»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð°Ñ Ð¿Ð¾Ñ‡Ñ‚Ð° не подтверждена. ПожалуйÑта, подтвердите ваш Ð°Ð´Ñ€ÐµÑ Ñлектронной почты в Salesforce."
@@ -7910,6 +8296,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr "ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñ€ÐµÐ³Ð¸Ñтрации по Ñлектронной почте"
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr "Отправить по Ñлектронной почте Ñообщение о ÑтатуÑе Ñборочной ÑпиÑку получателей."
@@ -7944,10 +8333,10 @@ msgid "EmailToken|resetting..."
msgstr "ÑброÑ..."
msgid "Emails"
-msgstr "ÐдреÑа Ñлектронной почты"
+msgstr "ÐдреÑа Ñл. почты"
msgid "Emails sent from Service Desk will have this name"
-msgstr ""
+msgstr "ПиÑьма, отправленные Ñлужбой поддержки будут иметь Ñто имÑ"
msgid "Emails separated by comma"
msgstr "Электронные адреÑа разделенные запÑтой"
@@ -7977,7 +8366,7 @@ msgid "Embed"
msgstr "Ð’Ñтроить"
msgid "Empty file"
-msgstr ""
+msgstr "ПуÑтой файл"
msgid "Enable"
msgstr "Включить"
@@ -7989,7 +8378,7 @@ msgid "Enable HTML emails"
msgstr ""
msgid "Enable Incident Management inbound alert limit"
-msgstr ""
+msgstr "Включить ограничение на количеÑтво входÑщих оповещений в Управлении инцидентами"
msgid "Enable PlantUML"
msgstr ""
@@ -8003,6 +8392,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr "Включить доÑтуп к Grafana"
@@ -8012,9 +8404,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr "Включить и наÑтроить Grafana."
-msgid "Enable and configure InfluxDB metrics."
-msgstr "Включить и наÑтроить метрики InfluxDB."
-
msgid "Enable and configure Prometheus metrics."
msgstr "Включить и наÑтроить метрики Prometheus."
@@ -8028,7 +8417,7 @@ msgid "Enable email restrictions for sign ups"
msgstr "Включить Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñ€ÐµÐ³Ð¸Ñтрации по Ñлектронной почте"
msgid "Enable error tracking"
-msgstr ""
+msgstr "Включить отÑлеживание ошибок"
msgid "Enable feature to choose access level"
msgstr "Включить функцию выбора ÑƒÑ€Ð¾Ð²Ð½Ñ Ð´Ð¾Ñтупа"
@@ -8042,6 +8431,9 @@ msgstr "Включить групповые обработчики заданиÐ
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8073,7 +8465,7 @@ msgid "Enable shared Runners"
msgstr ""
msgid "Enable snowplow tracking"
-msgstr ""
+msgstr "Включить отÑлеживание Snowplow"
msgid "Enable two-factor authentication"
msgstr "Включить двухфакторную аутентификацию"
@@ -8088,19 +8480,19 @@ msgid "Enable/disable your service desk. %{link_start}Learn more about service d
msgstr "Включить/отключить Ñлужбу поддержки. %{link_start}Узнайте больше о Ñлужбе поддержки%{link_end}."
msgid "EnableReviewApp|%{stepStart}Step 1%{stepEnd}. Ensure you have Kubernetes set up and have a base domain for your %{linkStart}cluster%{linkEnd}."
-msgstr ""
+msgstr "%{stepStart}Шаг 1%{stepEnd}. УбедитеÑÑŒ, что Kubernetes наÑтроен и имеет базовый домен Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ %{linkStart}клаÑтера%{linkEnd}."
msgid "EnableReviewApp|%{stepStart}Step 2%{stepEnd}. Copy the following snippet:"
-msgstr ""
+msgstr "%{stepStart}Шаг 2%{stepEnd}. Скопируйте Ñледующий Ñниппет:"
msgid "EnableReviewApp|%{stepStart}Step 3%{stepEnd}. Add it to the project %{linkStart}gitlab-ci.yml%{linkEnd} file."
-msgstr ""
+msgstr "%{stepStart}Шаг 3%{stepEnd}. Добавьте его в файл %{linkStart}gitlab-ci.yml%{linkEnd} проекта."
msgid "EnableReviewApp|Close"
-msgstr ""
+msgstr "Закрыть"
msgid "EnableReviewApp|Copy snippet text"
-msgstr ""
+msgstr "Скопировать текÑÑ‚ Ñниппета"
msgid "Enabled"
msgstr "Включено"
@@ -8115,7 +8507,7 @@ msgid "Enabling this will only make licensed EE features available to projects i
msgstr ""
msgid "Encountered an error while rendering: %{err}"
-msgstr ""
+msgstr "Произошла ошибка во Ð²Ñ€ÐµÐ¼Ñ Ñ€ÐµÐ½Ð´ÐµÑ€Ð¸Ð½Ð³Ð°: %{err}"
msgid "End date"
msgstr ""
@@ -8130,7 +8522,7 @@ msgid "Ensure connectivity is available from the GitLab server to the Prometheus
msgstr ""
msgid "Ensure your %{linkStart}environment is part of the deploy stage%{linkEnd} of your CI pipeline to track deployments to your cluster."
-msgstr "УбедитеÑÑŒ, что ваша Ñреда %{linkStart}ÑвлÑетÑÑ Ñ‡Ð°Ñтью Ñтадии развёртываниÑ%{linkEnd} Ñборочной линии CI Ð´Ð»Ñ Ð¾Ñ‚ÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ñ€Ð°Ð·Ð²Ñ‘Ñ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð² ваш клаÑтер."
+msgstr "УбедитеÑÑŒ, что ваша Ñреда %{linkStart}ÑвлÑетÑÑ Ñ‡Ð°Ñтью Ñтапа развёртываниÑ%{linkEnd} Ñборочной линии CI Ð´Ð»Ñ Ð¾Ñ‚ÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ñ€Ð°Ð·Ð²Ñ‘Ñ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð² ваш клаÑтер."
msgid "Enter 2FA for Admin Mode"
msgstr ""
@@ -8165,6 +8557,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr "Введите URL запроÑа на ÑлиÑние"
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8175,7 +8570,7 @@ msgid "Enter one or more user ID separated by commas"
msgstr ""
msgid "Enter the code from the two-factor app on your mobile device. If you've lost your device, you may enter one of your recovery codes."
-msgstr ""
+msgstr "Введите код из Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð´Ð²ÑƒÑ…Ñ„Ð°ÐºÑ‚Ð¾Ñ€Ð½Ð¾Ð¹ аутентификации Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ мобильного уÑтройÑтва. ЕÑли вы потерÑли Ñвоё уÑтройÑтво, можете ввеÑти один из кодов воÑÑтановлениÑ."
msgid "Enter the issue description"
msgstr "Введите опиÑание обÑуждениÑ"
@@ -8189,12 +8584,12 @@ msgstr ""
msgid "Enter the merge request title"
msgstr "Введите заголовок запроÑа на ÑлиÑние"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
+msgstr ""
+
msgid "Enter your password to approve"
msgstr "Ð”Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶ÐµÐ½Ð¸Ñ Ð²Ð²ÐµÐ´Ð¸Ñ‚Ðµ Ñвой пароль"
-msgid "Enter zen mode"
-msgstr ""
-
msgid "Environment"
msgstr "Окружение"
@@ -8249,20 +8644,20 @@ msgstr "Задание: %{job}"
msgid "EnvironmentsDashboard|More actions"
msgstr "Дополнительные дейÑтвиÑ"
-msgid "EnvironmentsDashboard|Read more."
-msgstr "Прочитать больше."
+msgid "EnvironmentsDashboard|More information"
+msgstr ""
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 "Панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñредами предоÑтавлÑет Ñводку ÑоÑтоÑÐ½Ð¸Ñ Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ð¹ каждого проекта, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ ÑтатуÑÑ‹ Ñборочной линии и оповещений."
msgid "EnvironmentsDashboard|This dashboard displays a maximum of 7 projects and 3 environments per project. %{readMoreLink}"
msgstr ""
msgid "Environments|An error occurred while canceling the auto stop, please try again"
-msgstr ""
+msgstr "Произошла ошибка при отмене автооÑтановки, пожалуйÑта, попробуйте ещё раз"
msgid "Environments|An error occurred while deleting the environment. Check if the environment stopped; if not, stop it and try again."
msgstr ""
@@ -8283,7 +8678,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 "Ð’Ñ‹ уверены, что хотите оÑтановить Ñто окружение?"
msgid "Environments|Auto stop in"
msgstr ""
@@ -8298,7 +8693,7 @@ msgid "Environments|Currently showing %{fetched} results."
msgstr ""
msgid "Environments|Currently showing all results."
-msgstr ""
+msgstr "Ð’ наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð¾ÐºÐ°Ð·Ð°Ð½Ñ‹ вÑе результаты."
msgid "Environments|Delete"
msgstr ""
@@ -8340,7 +8735,7 @@ msgid "Environments|Learn more about stopping environments"
msgstr ""
msgid "Environments|Logs from %{start} to %{end}."
-msgstr ""
+msgstr "Журналы Ñ %{start} по %{end}."
msgid "Environments|New environment"
msgstr "Ðовое окружение"
@@ -8418,16 +8813,16 @@ msgid "Environments|There was an error fetching the logs. Please try again."
msgstr "Произошла ошибка при извлечении журналов. ПожалуйÑта, попробуйте ещё раз."
msgid "Environments|This action will relaunch the job for commit %{commit_id}, putting the environment in a previous version. Are you sure you want to continue?"
-msgstr ""
+msgstr "Это дейÑтвие перезапуÑтит задание Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¼Ð¸Ñ‚Ð° %{commit_id}, вернув окружение в предыдущую верÑию. Ð’Ñ‹ уверены, что хотите продолжить?"
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 "Это дейÑтвие перезапуÑтит задание Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¼Ð¸Ñ‚Ð° %{linkStart}%{commitId}%{linkEnd}, вернув окружение в предыдущую верÑию. Ð’Ñ‹ уверены что хотите продолжить?"
msgid "Environments|This action will run the job defined by %{environment_name} for commit %{commit_id}, 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 "Это дейÑтвие запуÑтит задание, определенное в %{environment_name} Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¼Ð¸Ñ‚Ð° %{commit_id}, Ð¿ÐµÑ€ÐµÐ²ÐµÐ´Ñ Ñто окружение в предыдущую верÑию. Ð’Ñ‹ можете обратить Ñтот Ñффект, повторно развернув поÑледнюю верÑию Ñвоего приложениÑ. Ð’Ñ‹ уверены, что хотите продолжить?"
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 "Это дейÑтвие запуÑтит задание, определённое %{name} Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¼Ð¸Ñ‚Ð° %{linkStart}%{commitId}%{linkEnd}, Ð¿ÐµÑ€ÐµÐ²ÐµÐ´Ñ Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ðµ в предыдущую верÑию. Ð’Ñ‹ можете обратить Ñтот Ñффект, повторно развернув поÑледнюю верÑию Ñвоего приложениÑ. Ð’Ñ‹ дейÑтвительно хотите продолжить?"
msgid "Environments|Updated"
msgstr "Обновлено"
@@ -8436,7 +8831,7 @@ msgid "Environments|You don't have any environments right now"
msgstr "У Ð²Ð°Ñ Ð½ÐµÑ‚ ни одного Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ Ð½Ð° данный момент"
msgid "Environments|protected"
-msgstr "защищенное"
+msgstr "защищённое"
msgid "Epic"
msgstr "Цель"
@@ -8462,11 +8857,11 @@ msgstr "Цели позволÑÑ‚ вам управлÑÑ‚ÑŒ портфелем Ð
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
-msgstr "Добавить цель"
+msgid "Epics|Add a new epic"
+msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
-msgstr "Добавить ÑущеÑтвующую цель как дочернюю."
+msgid "Epics|Add an existing epic"
+msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
msgstr "Произошла ошибка при Ñохранении %{epicDateType} даты"
@@ -8477,12 +8872,6 @@ msgstr "Произошла ошибка при обновлении меток."
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr "Создать новую цель"
-
msgid "Epics|How can I solve this?"
msgstr "Как Ñ Ð¼Ð¾Ð³Ñƒ Ñто иÑправить?"
@@ -8552,8 +8941,17 @@ msgstr "Ошибка ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñ†ÐµÐ»Ð¸"
msgid "Error creating label."
msgstr "Ошибка при Ñоздании метки."
-msgid "Error deleting %{issuableType}"
-msgstr "Ошибка ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
+msgstr ""
msgid "Error deleting project. Check logs for error details."
msgstr "Ошибка при удалении проекта. Проверьте журналы Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð¾Ñтей об ошибке."
@@ -8657,9 +9055,6 @@ msgstr "Произошла ошибка. Пользователь не был р
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr "Ошибка при обновлении метки."
@@ -8675,6 +9070,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8709,7 +9107,7 @@ msgid "ErrorTracking|Connection has failed. Re-check Auth Token and try again."
msgstr "Ошибка подключениÑ. Перепроверьте токен аутентификации и повторите попытку."
msgid "ErrorTracking|If you self-host Sentry, enter the full URL of your Sentry instance. If you're using Sentry's hosted solution, enter https://sentry.io"
-msgstr ""
+msgstr "ЕÑли вы размещаете Sentry ÑамоÑтоÑтельно, введите полный URL-Ð°Ð´Ñ€ÐµÑ Ð²Ð°ÑˆÐµÐ³Ð¾ ÑкземплÑра Sentry. ЕÑли вы иÑпользуете решение на инфраÑтруктуре Sentry, введите https://sentry.io"
msgid "ErrorTracking|No projects available"
msgstr "Ðет доÑтупных проектов"
@@ -8726,10 +9124,10 @@ msgstr "Ошибки"
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8771,14 +9169,14 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
-msgstr "Ежедневно (в 4:00)"
+msgid "Every day (at %{time})"
+msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
-msgstr "ЕжемеÑÑчно (каждое 1-е чиÑло в 4:00)"
+msgid "Every month (Day %{day} at %{time})"
+msgstr ""
msgid "Every three months"
msgstr ""
@@ -8789,8 +9187,8 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
-msgstr "Еженедельно (по воÑкреÑениÑм в 4:00)"
+msgid "Every week (%{weekday} at %{time})"
+msgstr ""
msgid "Everyone"
msgstr "Ð’Ñе"
@@ -8828,6 +9226,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8838,14 +9239,17 @@ msgid "Except policy:"
msgstr "За иÑключением политики:"
msgid "Excluding merge commits. Limited to %{limit} commits."
-msgstr ""
+msgstr "ИÑÐºÐ»ÑŽÑ‡Ð°Ñ ÐºÐ¾Ð¼Ð¼Ð¸Ñ‚Ñ‹-ÑлиÑниÑ. Ограничено до %{limit} коммитов."
msgid "Excluding merge commits. Limited to 6,000 commits."
-msgstr ""
+msgstr "ИÑÐºÐ»ÑŽÑ‡Ð°Ñ ÐºÐ¾Ð¼Ð¼Ð¸Ñ‚Ñ‹-ÑлиÑниÑ. Ограничено до 6000 коммитов."
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8868,15 +9272,18 @@ msgid "Expand child epics"
msgstr "Развернуть дочерние цели"
msgid "Expand down"
-msgstr ""
+msgstr "Развернуть вниз"
msgid "Expand dropdown"
-msgstr ""
+msgstr "Развернуть раÑкрывающийÑÑ ÑпиÑок"
msgid "Expand sidebar"
msgstr "Развернуть боковую панель"
msgid "Expand up"
+msgstr "Развернуть вверх"
+
+msgid "Experienced"
msgstr ""
msgid "Expiration"
@@ -8894,6 +9301,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr "ИÑтек %{expiredOn}"
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8903,6 +9313,9 @@ msgstr "ИÑтекает"
msgid "Expires in %{expires_at}"
msgstr "ИÑтекает в %{expires_at}"
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8981,18 +9394,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr "Введите URL панели инÑтрументов, на которую вы хотите ÑÑылатьÑÑ"
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr "ВнешнÑÑ Ð¿Ð°Ð½ÐµÐ»ÑŒ инÑтрументов"
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr "Полный URL панели инÑтрументов"
-
msgid "ExternalWikiService|External Wiki"
msgstr "ВнешнÑÑ Wiki"
@@ -9021,13 +9422,13 @@ msgid "Failed to assign a user because no user was found."
msgstr "Ðе удалоÑÑŒ назначить пользователÑ, так как пользовать не найден."
msgid "Failed to cancel auto stop because failed to update the environment."
-msgstr ""
+msgstr "Ðе удалоÑÑŒ отменить автоматичеÑкую оÑтановку, поÑкольку не удалоÑÑŒ обновить окружение."
msgid "Failed to cancel auto stop because the environment is not set as auto stop."
-msgstr ""
+msgstr "Ðе удалоÑÑŒ отменить автоматичеÑкую оÑтановку, поÑкольку окружение не наÑтроено как автоматичеÑки оÑтанавливаемое."
msgid "Failed to cancel auto stop because you do not have permission to update the environment."
-msgstr ""
+msgstr "Ðе удалоÑÑŒ отменить автоматичеÑкую оÑтановку, поÑкольку у Ð²Ð°Ñ Ð½ÐµÑ‚ Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð½Ð° обновление окружениÑ."
msgid "Failed to change the owner"
msgstr "Ðе удалоÑÑŒ изменить владельца"
@@ -9081,7 +9482,7 @@ msgid "Failed to load errors from Sentry. Error message: %{errorMessage}"
msgstr ""
msgid "Failed to load group activity metrics. Please try again."
-msgstr ""
+msgstr "Ðе удалоÑÑŒ загрузить метрики активноÑти группы. ПожалуйÑта, попробуйте ещё раз."
msgid "Failed to load groups & users."
msgstr "Ðе удалоÑÑŒ загрузить группы и пользователей."
@@ -9090,7 +9491,7 @@ msgid "Failed to load labels. Please try again."
msgstr ""
msgid "Failed to load milestones. Please try again."
-msgstr ""
+msgstr "Ðе удалоÑÑŒ загрузить Ñтапы. ПожалуйÑта, попробуйте еще раз."
msgid "Failed to load related branches"
msgstr ""
@@ -9119,6 +9520,9 @@ msgstr "Ðе удалоÑÑŒ защитить ветку"
msgid "Failed to protect the environment"
msgstr "Ðе удалоÑÑŒ защитить окружение"
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9180,7 +9584,7 @@ msgid "Failed to upgrade."
msgstr ""
msgid "Failed to upload object map file"
-msgstr ""
+msgstr "Ðе удалоÑÑŒ загрузить файл карты объектов"
msgid "Failed to verify domain ownership"
msgstr ""
@@ -9194,8 +9598,8 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
-msgstr "БыÑтрое ÑлиÑние невозможно. ПеренеÑите ветку иÑточника в целевую ветку или объедините целевую ветку Ñ Ð¸Ñходной веткой, чтобы Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° ÑлиÑние был удовлетворен."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
+msgstr ""
msgid "Fast-forward merge without a merge commit"
msgstr ""
@@ -9257,6 +9661,12 @@ msgstr "ОпиÑание"
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9269,6 +9679,9 @@ msgstr "ХарактериÑтики окружений"
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9278,15 +9691,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr "Функциональные опции"
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9305,6 +9727,9 @@ msgstr "УÑтановите %{docs_link_anchored_start}ÑовмеÑтимую Ð
msgid "FeatureFlags|Instance ID"
msgstr "ID ÑкземплÑра"
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr "Загрузка Функциональных опций"
@@ -9320,9 +9745,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr "Ðовый переключатель функциональной опции"
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr "Процент Ñ€Ð°Ð·Ð²ÐµÑ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ (авторизованные пользователи)"
@@ -9396,7 +9827,7 @@ msgid "Fetching licenses failed. You are not permitted to perform this action."
msgstr "Ðе удалоÑÑŒ открыть лицензию. У Ð²Ð°Ñ Ð½ÐµÑ‚ прав на выполнение Ñтого дейÑтвиÑ."
msgid "File"
-msgstr ""
+msgstr "Файл"
msgid "File Hooks"
msgstr ""
@@ -9413,6 +9844,9 @@ msgstr "Файловый менеджер"
msgid "File deleted"
msgstr "Файл удалён"
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9425,6 +9859,9 @@ msgstr "Файл перемещен"
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9434,9 +9871,6 @@ msgstr "Шаблоны файлов"
msgid "File upload error."
msgstr "Ошибка загрузки файла."
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr "Файлы"
@@ -9452,24 +9886,45 @@ msgstr ""
msgid "Filter"
msgstr "Фильтр"
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr "Фильтр по комментариÑми к коммитам"
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr "Фильтр по названию Ñтапа"
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9479,6 +9934,9 @@ msgstr "Фильтр по двухфакторной аутентификациÐ
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9504,7 +9962,7 @@ msgid "Find by path"
msgstr "ПоиÑк по пути"
msgid "Find existing members by name"
-msgstr "Ðайти ÑущеÑтвующих учаÑтников по имени"
+msgstr "ПоиÑк текущих учаÑтников"
msgid "Find file"
msgstr "Ðайти файл"
@@ -9561,7 +10019,7 @@ msgid "Fixed:"
msgstr ""
msgid "Flags"
-msgstr ""
+msgstr "Флаги"
msgid "FlowdockService|Flowdock Git source token"
msgstr "Токен иÑточника Flowdock Git"
@@ -9597,10 +10055,10 @@ msgid "Footer message"
msgstr ""
msgid "For each Jira issue successfully imported, we'll create a new GitLab issue with the following data:"
-msgstr ""
+msgstr "Ð”Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ импортированной из Jira задачи мы в GitLab Ñоздадим новое обÑуждение, Ñодержащее Ñледующие данные:"
msgid "For internal projects, any logged in user can view pipelines and access job details (output logs and artifacts)"
-msgstr "Во внутренних проектах любой зарегиÑтрированный пользователь может проÑматривать конвейеры и получать доÑтуп к заданиÑм (логам и артефактам)"
+msgstr "Во внутренних проектах: любой зарегиÑтрированный пользователь может проÑматривать Ñборочные линии и получать доÑтуп к заданиÑм (логам и артефактам)"
msgid "For more info, read the documentation."
msgstr "Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации читайте документацию."
@@ -9609,7 +10067,7 @@ msgid "For more information, go to the "
msgstr ""
msgid "For more information, please review %{link_start_tag}Jaeger's configuration doc%{link_end_tag}"
-msgstr ""
+msgstr "Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации, пожалуйÑта, ознакомьтеÑÑŒ Ñ %{link_start_tag}документацией по наÑтройке Jaeger%{link_end_tag}"
msgid "For more information, see the File Hooks documentation."
msgstr ""
@@ -9618,19 +10076,19 @@ msgid "For more information, see the documentation on %{deactivating_usage_ping_
msgstr ""
msgid "For more information, see the documentation on %{link_start}disabling Seat Link%{link_end}."
-msgstr ""
+msgstr "Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации обратитеÑÑŒ к документации по %{link_start}отключению Seat Link%{link_end}."
msgid "For private projects, any member (guest or higher) can view pipelines and access job details (output logs and artifacts)"
-msgstr "Ð’ чаÑтных проектах любой пользователь (ГоÑÑ‚ÑŒ и выше) может проÑматривать конвейеры и получать доÑтуп к заданиÑм (логам и артефактам)"
+msgstr "Ð’ чаÑтных проектах: любой пользователь (гоÑÑ‚ÑŒ или выше) может проÑматривать Ñборочные линии и получать доÑтуп к заданиÑм (логам и артефактам)"
msgid "For public projects, anyone can view pipelines and access job details (output logs and artifacts)"
-msgstr ""
+msgstr "Ð’ публичных проектах: любой пользователь может проÑматривать Ñборочные линии и получать доÑтуп к заданиÑм (логам и артефактам)"
msgid "Forgot your password?"
msgstr "Забыли пароль?"
msgid "Fork"
-msgstr ""
+msgstr "Ответвление"
msgid "Fork Error!"
msgstr ""
@@ -9651,7 +10109,7 @@ msgid "Forking in progress"
msgstr "ВыполнÑетÑÑ Ð¾Ñ‚Ð²ÐµÑ‚Ð²Ð»ÐµÐ½Ð¸Ðµ"
msgid "Forks"
-msgstr ""
+msgstr "ОтветвлениÑ"
msgid "Format"
msgstr "Формат"
@@ -9702,7 +10160,7 @@ msgid "From GitLab.com"
msgstr ""
msgid "From Google Code"
-msgstr ""
+msgstr "Из Google Code"
msgid "From issue creation until deploy to production"
msgstr "От ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¾Ð±ÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð´Ð¾ Ñ€Ð°Ð·Ð²ÐµÑ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ñ€ÐµÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ð¸ в рабочей Ñреде"
@@ -9710,9 +10168,6 @@ msgstr "От ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¾Ð±ÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð´Ð¾ развертывани
msgid "From merge request merge until deploy to production"
msgstr "От запроÑа на ÑлиÑние до Ñ€Ð°Ð·Ð²ÐµÑ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð² рабочей Ñреде"
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9738,7 +10193,7 @@ msgid "General Settings"
msgstr "ОÑновные ÐаÑтройки"
msgid "General pipelines"
-msgstr ""
+msgstr "Сборочные линии"
msgid "Generate a default set of labels"
msgstr "Создать Ñтандартный набор меток"
@@ -9750,22 +10205,22 @@ msgid "Generate new export"
msgstr "Создать новый ÑкÑпорт"
msgid "Geo"
-msgstr ""
-
-msgid "Geo Designs"
-msgstr ""
+msgstr "Geo"
msgid "Geo Nodes"
-msgstr ""
+msgstr "Узлы Geo"
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
+msgstr "ÐÐµÐ»ÑŒÐ·Ñ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ оÑновной узел, еÑли еÑÑ‚ÑŒ вторичные"
+
+msgid "Geo Replication"
msgstr ""
msgid "Geo Settings"
-msgstr ""
+msgstr "ÐаÑтройки Geo"
msgid "Geo allows you to replicate your GitLab instance to other geographical locations."
-msgstr ""
+msgstr "Geo позволÑет вам реплицировать ÑкземплÑÑ€ GitLab в различных географичеÑких положениÑÑ…."
msgid "GeoNodeStatusEvent|%{timeAgoStr} (%{pendingEvents} events)"
msgstr "%{timeAgoStr}(%{pendingEvents} ÑобытиÑ)"
@@ -9774,40 +10229,40 @@ msgid "GeoNodeSyncStatus|Node is failing or broken."
msgstr ""
msgid "GeoNodeSyncStatus|Node is slow, overloaded, or it just recovered after an outage."
-msgstr ""
+msgstr "Узел функционирует медленно, перегружен или только что воÑÑтановлен поÑле ÑбоÑ."
msgid "GeoNodes|Attachments"
-msgstr ""
+msgstr "ВложениÑ"
msgid "GeoNodes|Checksummed"
msgstr ""
msgid "GeoNodes|Consult Geo troubleshooting information"
-msgstr ""
+msgstr "ОбратитеÑÑŒ к информации по уÑтранению неиÑправноÑтей Geo"
msgid "GeoNodes|Container repositories"
msgstr "Репозитории контейнеров"
msgid "GeoNodes|Data replication lag"
-msgstr ""
+msgstr "Задержка репликации данных"
msgid "GeoNodes|Design repositories"
msgstr "Репозитории дизайнов"
msgid "GeoNodes|Does not match the primary storage configuration"
-msgstr ""
+msgstr "Ðе ÑоответÑтвует конфигурации оÑновного хранилища"
msgid "GeoNodes|Failed"
-msgstr ""
+msgstr "Ðе удалоÑÑŒ"
msgid "GeoNodes|Full"
msgstr ""
msgid "GeoNodes|GitLab version"
-msgstr ""
+msgstr "ВерÑÐ¸Ñ GitLab"
msgid "GeoNodes|GitLab version does not match the primary node version"
-msgstr ""
+msgstr "ВерÑÐ¸Ñ GitLab не ÑоответÑтвует верÑии оÑновного узла"
msgid "GeoNodes|Health status"
msgstr ""
@@ -9828,7 +10283,7 @@ msgid "GeoNodes|Last event ID seen from primary"
msgstr ""
msgid "GeoNodes|Learn more about Geo node statuses"
-msgstr ""
+msgstr "Узнайте больше о ÑоÑтоÑниÑÑ… узлов Geo"
msgid "GeoNodes|Loading nodes"
msgstr ""
@@ -9837,37 +10292,37 @@ msgid "GeoNodes|New node"
msgstr "Ðовый узел"
msgid "GeoNodes|Node Authentication was successfully repaired."
-msgstr ""
+msgstr "ÐÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ ÑƒÐ·Ð»Ð° уÑпешно воÑÑтановлена."
msgid "GeoNodes|Node URL"
-msgstr ""
+msgstr "URL узла"
msgid "GeoNodes|Node was successfully removed."
-msgstr ""
+msgstr "Узел уÑпешно удалён."
msgid "GeoNodes|Node's status was updated %{timeAgo}."
-msgstr ""
+msgstr "СоÑтоÑние узла было обновлено %{timeAgo}."
msgid "GeoNodes|Not checksummed"
msgstr ""
msgid "GeoNodes|Pausing replication stops the sync process. Are you sure?"
-msgstr ""
+msgstr "ПриоÑтановка репликации прекращает процеÑÑ Ñинхронизации. Ð’Ñ‹ уверены?"
msgid "GeoNodes|Removing a Geo primary node stops the synchronization to all nodes. Are you sure?"
-msgstr ""
+msgstr "Удаление оÑновного узла Geo оÑтановит Ñинхронизацию вÑех узлов. Ð’Ñ‹ уверены?"
msgid "GeoNodes|Removing a Geo secondary node stops the synchronization to that node. Are you sure?"
-msgstr ""
+msgstr "Удаление вторичного узла Geo оÑтановит Ñинхронизацию Ñ Ñтим узлом. Ð’Ñ‹ уверены?"
msgid "GeoNodes|Replicated data is verified with the %{nodeText} using checksums"
-msgstr ""
+msgstr "Реплицированные данные ÑверÑÑŽÑ‚ÑÑ Ñ %{nodeText} при помощи контрольных Ñумм"
msgid "GeoNodes|Replication slot WAL"
msgstr ""
msgid "GeoNodes|Replication slots"
-msgstr ""
+msgstr "Слоты репликации"
msgid "GeoNodes|Repositories"
msgstr "Репозитории"
@@ -9876,46 +10331,46 @@ msgid "GeoNodes|Repository checksum progress"
msgstr ""
msgid "GeoNodes|Repository verification progress"
-msgstr ""
+msgstr "Ход Ñверки репозиториÑ"
msgid "GeoNodes|Selective (%{syncLabel})"
msgstr ""
msgid "GeoNodes|Selective synchronization"
-msgstr ""
+msgstr "Ð’Ñ‹Ð±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ ÑинхронизациÑ"
msgid "GeoNodes|Something went wrong while changing node status"
-msgstr ""
+msgstr "Что-то пошло не так при изменении ÑоÑтоÑÐ½Ð¸Ñ ÑƒÐ·Ð»Ð°"
msgid "GeoNodes|Something went wrong while fetching nodes"
-msgstr ""
+msgstr "Что-то пошло не так при выборке узлов"
msgid "GeoNodes|Something went wrong while removing node"
-msgstr ""
+msgstr "Что-то пошло не так при удалении узла"
msgid "GeoNodes|Something went wrong while repairing node"
-msgstr ""
+msgstr "Что-то пошло не так при воÑÑтановлении узла"
msgid "GeoNodes|Storage config"
-msgstr ""
+msgstr "ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°"
msgid "GeoNodes|Sync settings"
-msgstr ""
+msgstr "ÐаÑтройки Ñинхронизации"
msgid "GeoNodes|Unused slots"
-msgstr ""
+msgstr "ÐеиÑпользуемые Ñлоты"
msgid "GeoNodes|Unverified"
-msgstr ""
+msgstr "Ðепроверенные"
msgid "GeoNodes|Updated %{timeAgo}"
-msgstr ""
+msgstr "Обновлено %{timeAgo}"
msgid "GeoNodes|Used slots"
-msgstr ""
+msgstr "ИÑпользуемые Ñлоты"
msgid "GeoNodes|Verified"
-msgstr ""
+msgstr "Проверенные"
msgid "GeoNodes|Wiki checksum progress"
msgstr ""
@@ -9924,18 +10379,24 @@ msgid "GeoNodes|Wiki verification progress"
msgstr ""
msgid "GeoNodes|Wikis"
-msgstr ""
+msgstr "Вики"
msgid "GeoNodes|With %{geo} you can install a special read-only and replicated instance anywhere. Before you add nodes, follow the %{instructions} in the exact order they appear."
msgstr "С %{geo} вы можете уÑтановить Ñпециальный реплицированный, доÑтупный только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ ÑкземплÑÑ€ в любом меÑте. Прежде чем добавлÑÑ‚ÑŒ узлы, Ñледуйте %{instructions} в том порÑдке, в котором они поÑвлÑÑŽÑ‚ÑÑ."
msgid "GeoNodes|You have configured Geo nodes using an insecure HTTP connection. We recommend the use of HTTPS."
-msgstr ""
+msgstr "Ð’Ñ‹ наÑтроили узлы Geo, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð½ÐµÐ±ÐµÐ·Ð¾Ð¿Ð°Ñное HTTP-Ñоединение. Мы рекомендуем иÑпользовать HTTPS."
msgid "GeoNodes|primary node"
-msgstr ""
+msgstr "оÑновной узел"
msgid "GeoNodes|secondary nodes"
+msgstr "вторичные узлы"
+
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
msgstr ""
msgid "Geo|%{name} is scheduled for forced re-download"
@@ -9947,20 +10408,20 @@ msgstr "%{name} запланирован Ð´Ð»Ñ Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€Ð½Ð¾Ð¹ ÑинхроÐ
msgid "Geo|%{name} is scheduled for re-verify"
msgstr "%{name} запланирован Ð´Ð»Ñ Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€Ð½Ð¾Ð³Ð¾ подтверждениÑ"
-msgid "Geo|All"
-msgstr "Ð’Ñе"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
msgstr "Ð’Ñе проекты"
msgid "Geo|All projects are being scheduled for resync"
-msgstr ""
+msgstr "Запланирована Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€Ð½Ð°Ñ ÑÐ¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð²Ñех проектов"
msgid "Geo|All projects are being scheduled for reverify"
-msgstr ""
+msgstr "Ð”Ð»Ñ Ð²Ñех проектов запланирована Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€Ð½Ð°Ñ Ñверка"
msgid "Geo|Could not remove tracking entry for an existing project."
msgstr "Ðе удалоÑÑŒ удалить запиÑÑŒ отÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ ÑущеÑтвующего проекта."
@@ -9969,38 +10430,44 @@ msgid "Geo|Could not remove tracking entry for an existing upload."
msgstr "Ðе удалоÑÑŒ удалить запиÑÑŒ отÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ ÑущеÑтвующей загрузки."
msgid "Geo|Failed"
-msgstr ""
+msgstr "Ðе удалоÑÑŒ"
msgid "Geo|Filter by status"
-msgstr ""
+msgstr "Фильтр по ÑоÑтоÑнию"
msgid "Geo|Geo Status"
msgstr "Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Geo"
msgid "Geo|In progress"
-msgstr ""
+msgstr "Ð’ процеÑÑе"
msgid "Geo|In sync"
-msgstr ""
+msgstr "Синхронизировано"
msgid "Geo|Last repository check run"
msgstr "ПоÑледний запуÑк проверки репозиториÑ"
msgid "Geo|Last successful sync"
-msgstr ""
+msgstr "ПоÑледнÑÑ ÑƒÑÐ¿ÐµÑˆÐ½Ð°Ñ ÑинхронизациÑ"
msgid "Geo|Last sync attempt"
-msgstr ""
+msgstr "ПоÑледнÑÑ Ð¿Ð¾Ð¿Ñ‹Ñ‚ÐºÐ° Ñинхронизации"
msgid "Geo|Last time verified"
-msgstr ""
+msgstr "ПоÑледний раз проверено"
msgid "Geo|Never"
-msgstr ""
+msgstr "Ðикогда"
msgid "Geo|Next sync scheduled at"
msgstr "Ð¡Ð»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ ÑÐ¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð·Ð°Ð¿Ð»Ð°Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð° на"
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr "Ðе Ñинхронизировано"
@@ -10020,7 +10487,7 @@ msgid "Geo|Project (ID: %{project_id}) no longer exists on the primary. It is sa
msgstr "Проект (ID: %{project_id}) больше не ÑущеÑтвует на первичном узле. Удалить Ñту запиÑÑŒ безопаÑно, так как Ñто не удалит никакие данные на диÑке."
msgid "Geo|Projects in certain groups"
-msgstr ""
+msgstr "Проекты в определенных группах"
msgid "Geo|Projects in certain storage shards"
msgstr ""
@@ -10032,24 +10499,27 @@ msgid "Geo|Remove"
msgstr "Удалить"
msgid "Geo|Remove entry"
-msgstr ""
+msgstr "Убрать запиÑÑŒ"
msgid "Geo|Remove tracking database entry"
-msgstr ""
+msgstr "Удалить запиÑÑŒ базы данных отÑлеживаниÑ"
msgid "Geo|Resync"
-msgstr "ПереÑинхронизировать"
+msgstr "РеÑинхронизировать"
msgid "Geo|Resync all"
-msgstr ""
+msgstr "РеÑинхронизировать вÑе"
msgid "Geo|Retry count"
msgstr "КоличеÑтво повторных попыток"
msgid "Geo|Reverify"
-msgstr "Повторить проверку"
+msgstr "Сверить"
msgid "Geo|Reverify all"
+msgstr "Cверить вÑе"
+
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
msgstr ""
msgid "Geo|Status"
@@ -10070,15 +10540,24 @@ msgstr "Ð’ наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð±Ð°Ð·Ð° данных отÑтает о
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr "Узел в наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð¾Ñ‚Ñтает от оÑновного узла на %{minutes_behind}."
-msgid "Geo|Tracking database entry will be removed. Are you sure?"
+msgid "Geo|There are no %{replicable_type} to show"
msgstr ""
+msgid "Geo|Tracking database entry will be removed. Are you sure?"
+msgstr "ЗапиÑÑŒ базы данных отÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚ удалена. Ð’Ñ‹ уверены?"
+
msgid "Geo|Tracking entry for project (%{project_id}) was successfully removed."
msgstr "ЗапиÑÑŒ отÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð° (%{project_id}) была уÑпешно удалена."
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr "ЗапиÑÑŒ отÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ (%{type}/%{id}) была уÑпешно удалена."
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr "ÐеизвеÑтное ÑоÑтоÑние"
@@ -10089,10 +10568,10 @@ msgid "Geo|Waiting for scheduler"
msgstr "Ожидание планировщика"
msgid "Geo|You are on a secondary, <b>read-only</b> Geo node. If you want to make changes, you must visit this page on the %{primary_node}."
-msgstr ""
+msgstr "Ð’Ñ‹ находитеÑÑŒ на вторичном узле Geo в режиме <b>только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ</b>. ЕÑли вы хотите внеÑти изменениÑ, вы должны зайти на Ñту же Ñтраницу на %{primary_node}."
msgid "Geo|You are on a secondary, <b>read-only</b> Geo node. You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
-msgstr ""
+msgstr "Ð’Ñ‹ находитеÑÑŒ на вторичном, доÑтупном <b>только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ</b>, узле Geo. Ð’Ñ‹ можете оÑущеÑтвлÑÑ‚ÑŒ ограниченное количеÑтво изменений и дейÑтвий на данной Ñтранице."
msgid "Geo|misconfigured"
msgstr "наÑтроен неверно"
@@ -10140,10 +10619,10 @@ msgid "Git revision"
msgstr "Ð ÐµÐ²Ð¸Ð·Ð¸Ñ git"
msgid "Git shallow clone"
-msgstr ""
+msgstr "ПоверхноÑтное клонирование Git"
msgid "Git strategy for pipelines"
-msgstr ""
+msgstr "Команда Git Ð´Ð»Ñ Ñборочных линий"
msgid "Git version"
msgstr "ВерÑÐ¸Ñ Git"
@@ -10155,7 +10634,7 @@ msgid "GitHub import"
msgstr "Импорт из GitHub"
msgid "GitLab / Unsubscribe"
-msgstr ""
+msgstr "GitLab / ОтпиÑатьÑÑ"
msgid "GitLab Enterprise Edition %{plan}"
msgstr ""
@@ -10176,7 +10655,7 @@ msgid "GitLab Support Bot"
msgstr ""
msgid "GitLab Team Member"
-msgstr ""
+msgstr "Член команды GitLab"
msgid "GitLab User"
msgstr "Пользователь GitLab"
@@ -10185,7 +10664,7 @@ msgid "GitLab allows you to continue using your license even if you exceed the n
msgstr "GitLab позволÑет продолжить иÑпользование лицензии, даже еÑли вы превыÑили количеÑтво меÑÑ‚, которые вы приобрели. Ð’Ñ‹ должны будете оплатить Ñти меÑта при продлении лицензии."
msgid "GitLab commit"
-msgstr ""
+msgstr "Коммит GitLab"
msgid "GitLab for Slack"
msgstr "GitLab Ð´Ð»Ñ Slack"
@@ -10200,7 +10679,7 @@ msgid "GitLab is undergoing maintenance and is operating in a read-only mode."
msgstr ""
msgid "GitLab member or Email address"
-msgstr ""
+msgstr "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ GitLab или Ð°Ð´Ñ€ÐµÑ Ñлектронной почты"
msgid "GitLab metadata URL"
msgstr ""
@@ -10331,9 +10810,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr "Gitlab Pages"
@@ -10367,9 +10843,6 @@ msgstr ""
msgid "Go full screen"
msgstr "Ðа веÑÑŒ Ñкран"
-msgid "Go to"
-msgstr "Перейти к"
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10479,10 +10952,10 @@ msgid "Google Cloud Platform"
msgstr ""
msgid "Google Code import"
-msgstr ""
+msgstr "Импорт из Google Code"
msgid "Google Takeout"
-msgstr ""
+msgstr "Google Takeout"
msgid "Google authentication is not %{link_start}properly configured%{link_end}. Ask your GitLab administrator if you want to use this service."
msgstr ""
@@ -10532,12 +11005,21 @@ msgstr "Gravatar включён"
msgid "Group"
msgstr "Группа"
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr "Группа %{group_name} была запланирована Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ."
msgid "Group %{group_name} was successfully created."
msgstr "Группа %{group_name} уÑпешно Ñоздана."
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10551,7 +11033,7 @@ msgid "Group Hooks"
msgstr ""
msgid "Group ID"
-msgstr ""
+msgstr "ID группы"
msgid "Group ID: %{group_id}"
msgstr ""
@@ -10571,6 +11053,12 @@ msgstr "URL группы"
msgid "Group avatar"
msgstr "Ðватар группы"
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr "ОпиÑание группы"
@@ -10583,10 +11071,13 @@ msgstr "Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ группе"
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10604,10 +11095,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr "Ðазвание группы"
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10625,12 +11119,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr "Минуты групповой Ñборочной линии уÑпешно Ñброшены."
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr "Группа была уÑпешно обновлена."
@@ -10650,22 +11150,22 @@ msgid "GroupActivyMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivyMetrics|Recent activity (last 90 days)"
-msgstr ""
+msgstr "ÐедавнÑÑ Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚ÑŒ (за поÑледние 90 дней)"
msgid "GroupRoadmap|%{dateWord} – No end date"
-msgstr ""
+msgstr "%{dateWord} – Без конечной даты"
msgid "GroupRoadmap|%{startDateInWords} – %{endDateInWords}"
-msgstr ""
+msgstr "%{startDateInWords} – %{endDateInWords}"
msgid "GroupRoadmap|No start date – %{dateWord}"
-msgstr ""
+msgstr "Без начальной даты – %{dateWord}"
msgid "GroupRoadmap|Something went wrong while fetching epics"
msgstr "Что-то пошло не так при извлечении целей"
msgid "GroupRoadmap|Something went wrong while fetching milestones"
-msgstr ""
+msgstr "Что-то пошло не так при получении Ñтапов"
msgid "GroupRoadmap|Sorry, no epics matched your search"
msgstr "К Ñожалению, по вашему запроÑу цели не найдены"
@@ -10697,9 +11197,6 @@ msgstr "Включить аутентификацию SAML Ð´Ð»Ñ Ñтой грÑ
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr "Принудительно иÑпользовать SSO-аутентификацию Ð´Ð»Ñ Ñтой группы."
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10800,7 +11297,7 @@ msgid "GroupSAML|should be a random persistent ID, emails are discouraged"
msgstr ""
msgid "GroupSettings|Apply integration settings to all Projects"
-msgstr ""
+msgstr "Применить наÑтройки интеграции ко вÑем проектам"
msgid "GroupSettings|Auto DevOps pipeline was updated for the group"
msgstr "Ð”Ð»Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ñ‹ была обновлена ÑÐ±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑкого DevOps"
@@ -10842,7 +11339,7 @@ msgid "GroupSettings|If the parent group's visibility is lower than the group cu
msgstr "ЕÑли видимоÑÑ‚ÑŒ родительÑкой группы ниже текущей видимоÑти группы, уровни видимоÑти Ð´Ð»Ñ Ð¿Ð¾Ð´Ð³Ñ€ÑƒÐ¿Ð¿ и проектов будут изменены на ÑоответÑтвие видимоÑти новой родительÑкой группы."
msgid "GroupSettings|Integrations configured here will automatically apply to all projects in this group."
-msgstr ""
+msgstr "Сконфигурированные здеÑÑŒ интеграции будут автоматичеÑки применены ко вÑем проектам данной группы."
msgid "GroupSettings|Learn more about badges."
msgstr "Узнать больше о значках."
@@ -10901,6 +11398,9 @@ msgstr "Ð’Ñ‹ можете перенеÑти Ñту группу только в
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr "Вам нужно будет обновить ваши локальные репозитории, чтобы указать новое меÑтоположение."
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr "не может быть отменена до тех пор пока группа \"ПоделитьÑÑ Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð¾Ð²Ð¾Ð¹ блокировкой\" включена, за иÑключением владельца группы родителÑ"
@@ -10935,7 +11435,7 @@ msgid "GroupsDropdown|Frequently visited"
msgstr "ЧаÑто поÑещаемые"
msgid "GroupsDropdown|Groups you visit often will appear here"
-msgstr ""
+msgstr "Группы, которые вы чаÑто поÑещаете, поÑвÑÑ‚ÑÑ Ð·Ð´ÐµÑÑŒ"
msgid "GroupsDropdown|Loading groups"
msgstr ""
@@ -11001,11 +11501,14 @@ msgid "HTTP Basic: Access denied\\nYou must use a personal access token with 'ap
msgstr "HTTP Basic: доÑтуп запрещен\\nÐ’Ñ‹ должны иÑпользовать личный токен Ñ Ð´Ð¾Ñтупом к «api» Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Git через HTTP.\\nÐ’Ñ‹ можете Ñоздать его на %{profile_personal_access_tokens_url}"
msgid "Hashed Storage must be enabled to use Geo"
-msgstr ""
+msgstr "Ð¥Ñшированное хранилище должно быть включено Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Geo"
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -11015,6 +11518,9 @@ msgstr "Логотип заголовка был уÑпешно удален."
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -11037,7 +11543,7 @@ msgid "HealthCheck|Unhealthy"
msgstr "ÐеÑтабильный"
msgid "Hello there"
-msgstr ""
+msgstr "Привет"
msgid "Help"
msgstr "Помощь"
@@ -11055,13 +11561,13 @@ msgid "Helps prevent bots from creating accounts."
msgstr ""
msgid "Helps reduce alert volume (e.g. if creating too many issues)"
-msgstr ""
+msgstr "Помогает уменьшить объем оповещений (напр., еÑли ÑоздаетÑÑ Ñлишком много обÑуждений)"
msgid "Helps reduce request volume for protected paths"
msgstr ""
msgid "Here you will find recent merge request activity"
-msgstr ""
+msgstr "ЗдеÑÑŒ вы найдёте недавнюю активноÑÑ‚ÑŒ, ÑвÑзанную Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñами на ÑлиÑние"
msgid "Hi %{username}!"
msgstr ""
@@ -11095,7 +11601,7 @@ msgid "Hide shared projects"
msgstr ""
msgid "Hide stage"
-msgstr ""
+msgstr "Скрыть Ñтап"
msgid "Hide value"
msgid_plural "Hide values"
@@ -11125,6 +11631,9 @@ msgstr "ИÑториÑ"
msgid "History of authentications"
msgstr "ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¹"
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr "Ðе удалоÑÑŒ выполнить обработчик. УбедитеÑÑŒ, что группа имеет проект Ñ ÐºÐ¾Ð¼Ð¼Ð¸Ñ‚Ð°Ð¼Ð¸."
@@ -11134,6 +11643,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11231,16 +11743,16 @@ msgid "IDE|This option is disabled because you don't have write permissions for
msgstr ""
msgid "INFO: Your SSH key has expired. Please generate a new key."
-msgstr ""
+msgstr "ИÐФОРМÐЦИЯ: Срок дейÑÑ‚Ð²Ð¸Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ SSH-ключа иÑтёк. ПожалуйÑта, Ñоздайте новый."
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
-msgstr ""
+msgstr "ИÐФОРМÐЦИЯ: Срок дейÑÑ‚Ð²Ð¸Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ SSH-ключа иÑтекает. ПожалуйÑта, Ñоздайте новый."
msgid "IP Address"
-msgstr ""
+msgstr "IP-адреÑ"
msgid "IP subnet restriction only allowed for top-level groups"
-msgstr ""
+msgstr "ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾ IP-подÑетÑм разрешены только Ð´Ð»Ñ Ð³Ñ€ÑƒÐ¿Ð¿ верхнего уровнÑ"
msgid "Identifier"
msgstr "Идентификатор"
@@ -11252,13 +11764,13 @@ msgid "Identities"
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 ""
+msgstr "ЕÑли длина какого-либо индекÑированного Ð¿Ð¾Ð»Ñ Ð¿Ñ€ÐµÐ²Ñ‹ÑˆÐ°ÐµÑ‚ Ñтот порог, оно будет обрезано до ÑоответÑтвующего количеÑтва Ñимволов, а оÑтавшаÑÑÑ Ñ‡Ð°ÑÑ‚ÑŒ будет иÑключена из индекÑÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸ поиÑка. Ðе отноÑитÑÑ Ðº репозиторию и индекÑированию в вики. УÑтановка Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð² 0 означает неограниченную длину."
msgid "If any job surpasses this timeout threshold, it will be marked as failed. Human readable time input language is accepted like \"1 hour\". Values without specification represent seconds."
-msgstr ""
+msgstr "ЕÑли какое-либо задание превышает порог выделенного времени, оно помечаетÑÑ ÐºÐ°Ðº невыполненное. Ð’Ñ€ÐµÐ¼Ñ Ð²Ð²Ð¾Ð´Ð¸Ñ‚ÑÑ Ð² человекочитаемом формате: например, \"1 hour\". ЕÑли единица времени не указано, Ð²Ñ€ÐµÐ¼Ñ Ð¿Ñ€Ð¸Ð½Ð¸Ð¼Ð°ÐµÑ‚ÑÑ Ð² Ñекундах."
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 ""
+msgstr "ЕÑли пуÑто, уÑтановить разрешенное Ð²Ñ€ÐµÐ¼Ñ ÑущеÑÑ‚Ð²Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ€Ð°Ð²Ð½Ñ‹Ð¼ %{instance_level_policy_in_words}, как определено админиÑтратором ÑкземплÑра. ПоÑле уÑтановки, ÑущеÑтвующие токены пользователей данной группы могут быть отозваны."
msgid "If checked, group owners can manage LDAP group links and LDAP member overrides"
msgstr "ЕÑли отмечено, владельцы групп могут управлÑÑ‚ÑŒ ÑÑылками на группы LDAP и переопределÑÑ‚ÑŒ пользователей LDAP"
@@ -11282,6 +11794,9 @@ msgid "If enabled, access to projects will be validated on an external service u
msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
+msgstr "ЕÑли включено ÑовмеÑтно Ñ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰ÐµÐ¼ объектов, GitLab будет обрабатывать репликацию хранилища объектов Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ Geo"
+
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
msgstr ""
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
@@ -11291,15 +11806,24 @@ msgid "If this was a mistake you can leave the %{source_type}."
msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
+msgstr "ЕÑли вы иÑпользуете GitHub, вы увидите ÑтатуÑÑ‹ Ñборочных линии в GitHub Ð´Ð»Ñ Ñвоих коммитов и запроÑов на ÑлиÑние. %{more_info_link}"
+
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
msgstr "ЕÑли вы потерÑете Ñвои коды воÑÑтановлениÑ, вы можете Ñоздать новые, Ð°Ð½Ð½ÑƒÐ»Ð¸Ñ€ÑƒÑ Ð²Ñе предыдущие коды."
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
+msgstr "ЕÑли вы израÑходуете 100%% ёмкоÑти хранилища, то не Ñможете: %{base_message}"
+
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
msgstr ""
msgid "If your HTTP repository is not publicly accessible, add your credentials."
@@ -11314,8 +11838,11 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
-msgstr "Изображение: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
+msgstr ""
msgid "ImageDiffViewer|2-up"
msgstr ""
@@ -11332,15 +11859,15 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
+msgid "Impersonation Tokens"
+msgstr ""
+
msgid "Impersonation has been disabled"
msgstr "ПерÑÐ¾Ð½Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð°"
msgid "Import"
msgstr "Импортировать"
-msgid "Import %{status}"
-msgstr ""
-
msgid "Import CSV"
msgstr ""
@@ -11350,6 +11877,9 @@ msgstr "Импорт проектов из Gitea"
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11359,21 +11889,24 @@ msgstr "Импортировать вÑе репозитории"
msgid "Import an exported GitLab project"
msgstr "Импортировать ÑкÑпортированный проект GitLab"
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
msgid "Import from Jira"
-msgstr ""
+msgstr "Импортировать из Jira"
msgid "Import in progress"
msgstr "ВыполнÑетÑÑ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚"
+msgid "Import in progress. Refresh page to see newly added issues."
+msgstr ""
+
msgid "Import issues"
msgstr "Импорт обÑуждений"
-msgid "Import issues from Jira"
-msgstr ""
-
msgid "Import members"
msgstr "Импорт учаÑтников"
@@ -11414,7 +11947,7 @@ msgid "Import repository"
msgstr "Импорт репозиториÑ"
msgid "Import started by: %{importInitiator}"
-msgstr ""
+msgstr "Импорт запущен: %{importInitiator}"
msgid "Import tasks"
msgstr ""
@@ -11464,12 +11997,12 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
-msgstr "Улучшить управление обÑуждениÑми Ñ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾Ñтью Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚Ð° обÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸ помощи GitLab Enterprise Edition."
-
msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr "Улучшить поиÑк при помощи РаÑширенного Глобального ПоиÑка в верÑии GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
+msgstr ""
+
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
msgstr ""
@@ -11477,7 +12010,7 @@ msgid "In order to gather accurate feature usage data, it can take 1 to 2 weeks
msgstr ""
msgid "In order to personalize your experience with GitLab<br>we would like to know a bit more about you."
-msgstr ""
+msgstr "Ð”Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы адаптировать ваш опыт работы Ñ GitLab<br>, мы хотели бы узнать о Ð²Ð°Ñ Ð½ÐµÐ¼Ð½Ð¾Ð³Ð¾ больше."
msgid "In order to tailor your experience with GitLab we<br>would like to know a bit more about you."
msgstr ""
@@ -11489,7 +12022,7 @@ msgid "In the next step, you'll be able to select the projects you want to impor
msgstr ""
msgid "Incident Management Limits"
-msgstr ""
+msgstr "Лимиты, ÑвÑзанные Ñ Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸ÐµÐ¼ инцидентами"
msgid "Incidents"
msgstr "Инциденты"
@@ -11500,6 +12033,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr "Включать Ð¸Ð¼Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð° в текÑте ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¿Ð¾ Ñлектронной почте"
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11533,6 +12069,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11557,10 +12099,22 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr "Ð’Ñтавить цитату"
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
+msgstr "Ð’Ñтавить код"
+
+msgid "Insert inline code"
msgstr ""
msgid "Insert suggestion"
@@ -11569,6 +12123,12 @@ msgstr ""
msgid "Insights"
msgstr "СтатиÑтика (Insights)"
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr "УÑтановить"
@@ -11610,7 +12170,7 @@ msgid "Instance license"
msgstr "Ð›Ð¸Ñ†ÐµÐ½Ð·Ð¸Ñ ÑкземплÑра"
msgid "Integration"
-msgstr ""
+msgstr "ИнтеграциÑ"
msgid "Integration Settings"
msgstr ""
@@ -11621,6 +12181,30 @@ msgstr "Интеграции"
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr "Желающие могут внеÑти Ñвой вклад, отправив коммит, еÑли захотÑÑ‚."
@@ -11643,7 +12227,7 @@ msgid "Interval Pattern"
msgstr "Шаблон интервала"
msgid "Introducing Value Stream Analytics"
-msgstr ""
+msgstr "ПредÑтавлÑем Ðналитику потока ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñ†ÐµÐ½Ð½Ð¾Ñти"
msgid "Introducing Your DevOps Score"
msgstr ""
@@ -11660,6 +12244,12 @@ msgstr "Ðеверный логин или пароль"
msgid "Invalid URL"
msgstr "ÐедопуÑÑ‚Ð¸Ð¼Ð°Ñ ÑÑылка"
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11679,7 +12269,7 @@ msgid "Invalid field"
msgstr "Ðеверно заполнено поле"
msgid "Invalid file format with specified file type"
-msgstr ""
+msgstr "Ðеверный формат Ð´Ð»Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð½Ð¾Ð³Ð¾ типа файла"
msgid "Invalid file."
msgstr "ÐедопуÑтимый файл."
@@ -11696,18 +12286,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr "Ðеверный пин-код"
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr "Ðеверный ответ Ñервера"
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11720,6 +12319,9 @@ msgstr "Приглашение"
msgid "Invite \"%{trimmed}\" by email"
msgstr "ПриглаÑить \"%{trimmed}\" по Ñлектронной почте"
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr "ПриглаÑить группу"
@@ -11763,7 +12365,7 @@ msgid "Issue %{issue_reference} has already been added to epic %{epic_reference}
msgstr "ОбÑуждение %{issue_reference} уже было добавлено к цели %{epic_reference}."
msgid "Issue Boards"
-msgstr "ДоÑки ОбÑуждений"
+msgstr "ДоÑки обÑуждений"
msgid "Issue already promoted to epic."
msgstr "ОбÑуждение уже было продвинуто до цели."
@@ -11783,6 +12385,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr "Шаблон обÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ (необÑзательно)"
@@ -11795,6 +12400,33 @@ msgstr "ОбÑуждение было закрыто %{name} %{reason}"
msgid "Issue weight"
msgstr "Приоритет обÑуждениÑ"
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr "ДоÑка"
@@ -11852,6 +12484,9 @@ msgstr "ОбÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ñ‹"
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr "ОбÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ñ ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ñми, запроÑÑ‹ на ÑлиÑние Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñми и комментариÑми, метками, Ñтапами, Ñниппетами и другими объектами проекта"
@@ -11859,7 +12494,7 @@ msgid "Issues, merge requests, pushes, and comments."
msgstr "ОбÑуждениÑ, запроÑÑ‹ на ÑлиÑниÑ, отправки изменений и комментарии."
msgid "IssuesAnalytics|After you begin creating issues for your projects, we can start tracking and displaying metrics for them"
-msgstr ""
+msgstr "ПоÑле того как вы начнёте Ñоздавать обÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð² Ñвоих проектах, мы Ñможем начать отÑлеживание и отображение метрик Ð´Ð»Ñ Ð½Ð¸Ñ…"
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
@@ -11892,9 +12527,33 @@ msgid "It must have a header row and at least two columns: the first column is t
msgstr "Он должен иметь Ñтроку заголовка и по крайней мере две колонки: первый Ñтолбец ÑвлÑетÑÑ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ¾Ð¼ обÑуждениÑ, а второй Ñтолбец - опиÑание обÑуждениÑ. Разделитель автоматичеÑки обнаружен."
msgid "It seems like the Dependency Scanning job ran successfully, but no dependencies have been detected in your project."
-msgstr ""
+msgstr "Похоже, работа по Ñканированию завиÑимоÑтей завершилаÑÑŒ уÑпешно, но в вашем проекте не было обнаружено никаких завиÑимоÑтей."
msgid "It's you"
+msgstr "Это вы"
+
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
msgstr ""
msgid "Jaeger URL"
@@ -11909,19 +12568,22 @@ msgstr "Янв."
msgid "January"
msgstr "Январь"
-msgid "Jira Issue Import"
-msgstr ""
+msgid "Jira import is already running."
+msgstr "Импорт из Jira уже выполнÑетÑÑ."
-msgid "Jira import feature is disabled."
-msgstr ""
+msgid "Jira integration not configured."
+msgstr "Ð˜Ð½Ñ‚ÐµÐ³Ñ€Ð°Ñ†Ð¸Ñ Ñ Jira не наÑтроена."
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
+msgstr "Проект Jira: %{importProject}"
+
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira integration not configured."
+msgid "JiraService| on branch %{branch_link}"
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11934,7 +12596,7 @@ msgid "JiraService|Jira API URL"
msgstr "Jira API URL"
msgid "JiraService|Jira comments will be created when an issue gets referenced in a commit."
-msgstr ""
+msgstr "Комментарии Jira ÑоздаютÑÑ, когда в коммитах кто-нибудь ÑÑылаетÑÑ Ð½Ð° обÑуждениÑ."
msgid "JiraService|Jira comments will be created when an issue gets referenced in a merge request."
msgstr ""
@@ -11973,7 +12635,7 @@ msgid "Job Failed #%{build_id}"
msgstr "Ошибка Ð·Ð°Ð´Ð°Ð½Ð¸Ñ #%{build_id}"
msgid "Job ID"
-msgstr ""
+msgstr "ID заданиÑ"
msgid "Job has been erased"
msgstr "Фоновое задание было удалено"
@@ -12047,6 +12709,9 @@ msgstr "Ðртефакты Ð·Ð°Ð´Ð°Ð½Ð¸Ñ Ð±Ñ‹Ð»Ð¸ удалены"
msgid "Job|The artifacts will be removed"
msgstr "Ðртефакты будут удалены"
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr "Это задание не выполнено, поÑкольку необходимые реÑурÑÑ‹ не были уÑпешно Ñозданы."
@@ -12084,10 +12749,13 @@ msgid "June"
msgstr "Июнь"
msgid "Just me"
+msgstr "Только Ñ"
+
+msgid "Keep divergent refs"
msgstr ""
msgid "Key"
-msgstr ""
+msgstr "Ключ"
msgid "Key (PEM)"
msgstr ""
@@ -12120,7 +12788,7 @@ msgid "Kubernetes cluster creation time exceeds timeout; %{timeout}"
msgstr "Ð’Ñ€ÐµÐ¼Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÐºÐ»Ð°Ñтера Kubernetes превышает Ð²Ñ€ÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ; %{timeout}"
msgid "Kubernetes cluster integration and resources are being removed."
-msgstr ""
+msgstr "Ð˜Ð½Ñ‚ÐµÐ³Ñ€Ð°Ñ†Ð¸Ñ ÐºÐ»Ð°Ñтера Kubernetes и реÑурÑÑ‹ удалÑÑŽÑ‚ÑÑ."
msgid "Kubernetes cluster integration was successfully removed."
msgstr "Ð˜Ð½Ñ‚ÐµÐ³Ñ€Ð°Ñ†Ð¸Ñ ÐºÐ»Ð°Ñтера Kubernetes была уÑпешно удалена."
@@ -12162,7 +12830,7 @@ msgid "LFSStatus|Enabled"
msgstr "Включено"
msgid "LICENSE"
-msgstr ""
+msgstr "ЛИЦЕÐЗИЯ"
msgid "Label"
msgstr "Метка"
@@ -12267,6 +12935,9 @@ msgstr "ФамилиÑ"
msgid "Last reply by"
msgstr "ПоÑледний ответ от"
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12310,7 +12981,7 @@ msgid "Latest changes"
msgstr "ПоÑледние изменениÑ"
msgid "Latest pipeline for the most recent commit on this branch"
-msgstr ""
+msgstr "ПоÑледнÑÑ ÑÐ±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ Ð´Ð»Ñ Ñамого Ñвежего коммита в Ñтой ветке"
msgid "Lead"
msgstr ""
@@ -12331,7 +13002,7 @@ msgid "Learn how to %{no_packages_link_start}publish and share your packages%{no
msgstr "Узнайте, как %{no_packages_link_start}опубликовать и делитьÑÑ Ñвоими пакетами%{no_packages_link_end} Ñ GitLab."
msgid "Learn how to enable synchronization"
-msgstr ""
+msgstr "Узнайте, как включить Ñинхронизацию"
msgid "Learn more"
msgstr "Подробнее"
@@ -12351,6 +13022,9 @@ msgstr "Узнайте больше о Vulnerability-Check"
msgid "Learn more about Web Terminal"
msgstr "Узнайте больше о Web Terminal"
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12367,14 +13041,11 @@ msgid "Learn more about group-level project templates"
msgstr "Узнать больше о шаблонах проекта группового уровнÑ"
msgid "Learn more about signing commits"
-msgstr ""
+msgstr "Узнайте больше о подпиÑывании коммитов"
msgid "Learn more about the dependency list"
msgstr "Узнайте больше о ÑпиÑке завиÑимоÑтей"
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr "Узнайте больше в"
@@ -12388,7 +13059,7 @@ msgid "Leave Admin Mode"
msgstr "Выйти из режима админиÑтратора"
msgid "Leave blank for no limit. Once set, existing personal access tokens may be revoked."
-msgstr ""
+msgstr "ОÑтавьте пуÑтым, чтобы ÑнÑÑ‚ÑŒ ограничениÑ. ПоÑле уÑтановки ÑущеÑтвующие личные токены доÑтупа могут быть отозваны."
msgid "Leave edit mode? All unsaved changes will be lost."
msgstr "Выйти из режима редактированиÑ? Ð’Ñе неÑохраненные Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð±ÑƒÐ´ÑƒÑ‚ потерÑны."
@@ -12402,6 +13073,9 @@ msgstr "Покинуть проект"
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12414,6 +13088,9 @@ msgstr "ЛицензиÑ"
msgid "License Compliance"
msgstr "Служба комплаенÑа лицензий"
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12438,15 +13115,9 @@ msgstr "Запрещено"
msgid "LicenseCompliance|Deny"
msgstr "Запретить"
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr "ЗдеÑÑŒ вы можете разрешить или запрещать лицензии в Ñтом проекте. ИÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ %{ci} или %{license}, вы можете проÑматировать, еÑÑ‚ÑŒ ли здеÑÑŒ лицензии Ñ Ð½ÐµÐ¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð½Ñ‹Ð¼ ÑтатуÑом, а затем разрешить или запретить их в запроÑе на ÑлиÑние."
-
msgid "LicenseCompliance|License"
msgstr "ЛицензиÑ"
-msgid "LicenseCompliance|License Compliance"
-msgstr "Служба комплаенÑа лицензий"
-
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] "Служба комплаенÑа лицензий обнаружила %d лицензию и нарушение только Ð´Ð»Ñ Ð¸Ñходной ветки; необходимо утверждение"
@@ -12524,7 +13195,7 @@ msgid "LicenseManagement|Denied"
msgstr "Запрещено"
msgid "LicenseManagement|Uncategorized"
-msgstr ""
+msgstr "Без категории"
msgid "Licensed Features"
msgstr ""
@@ -12551,7 +13222,7 @@ msgid "Licenses|Detected licenses that are out-of-compliance with the project's
msgstr "Обнаружены лицензии Ñ Ð½ÐµÐ¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð½Ñ‹Ð¼ ÑтатуÑом комплаенÑа и политик проекта"
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
-msgstr ""
+msgstr "Показывает лицензии, обнаруженные в проекте при %{linkStart}поÑледнем уÑпешном%{linkEnd} Ñканировании"
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
@@ -12572,7 +13243,7 @@ msgid "Licenses|Policy"
msgstr ""
msgid "Licenses|Policy violation: denied"
-msgstr ""
+msgstr "Ðарушение политики: отказано"
msgid "Licenses|Specified policies in this project"
msgstr ""
@@ -12589,6 +13260,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12604,6 +13278,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr "Ограничить отображение единицы времени отÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð´Ð¾ чаÑов."
@@ -12645,7 +13322,7 @@ msgid "LinkedPipelines|%{counterLabel} more downstream pipelines"
msgstr ""
msgid "Links"
-msgstr ""
+msgstr "СÑылки"
msgid "List"
msgstr "СпиÑок"
@@ -12701,6 +13378,9 @@ msgstr "Загрузка..."
msgid "Loading…"
msgstr "Загрузка…"
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr "ЛокализациÑ"
@@ -12759,7 +13439,7 @@ msgid "Logs"
msgstr "Журналы"
msgid "Logs|To see the logs, deploy your code to an environment."
-msgstr ""
+msgstr "Чтобы проÑмотреть журналы, разверните Ñвой код в окружение."
msgid "Low vulnerabilities present"
msgstr ""
@@ -12774,7 +13454,7 @@ msgid "MERGED"
msgstr "СЛИТО"
msgid "MR widget|Take a look at our %{beginnerLinkStart}Beginner's Guide to Continuous Integration%{beginnerLinkEnd} and our %{exampleLinkStart}examples of GitLab CI/CD%{exampleLinkEnd} to see all the cool stuff you can do with it."
-msgstr ""
+msgstr "ВзглÑните на наше %{beginnerLinkStart}РуководÑтво по Ðепрерывной интеграции Ð´Ð»Ñ Ð½Ð°Ñ‡Ð¸Ð½Ð°ÑŽÑ‰Ð¸Ñ…%{beginnerLinkEnd} и %{exampleLinkStart}примеры по GitLab CI/CD%{exampleLinkEnd}, чтобы узнать обо вÑех крутых вещах, которые вы можете Ñделать Ñ ÐµÑ‘ помощью."
msgid "MR widget|The pipeline will now run automatically every time you commit code. Pipelines are useful for deploying static web pages, detecting vulnerabilities in dependencies, static or dynamic application security testing (SAST and DAST), and so much more!"
msgstr "Теперь ÑÐ±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚ автоматичеÑки запуÑкатьÑÑ, когда вы фикÑируете код. Сборочные линии полезны Ð´Ð»Ñ Ñ€Ð°Ð·Ð²ÐµÑ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ ÑтатичеÑких веб-Ñтраниц, Ð¾Ð±Ð½Ð°Ñ€ÑƒÐ¶ÐµÐ½Ð¸Ñ ÑƒÑзвимоÑтей в завиÑимоÑÑ‚ÑÑ…, ÑтатичеÑкого или динамичеÑкого теÑÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð±ÐµÐ·Ð¾Ð¿Ð°ÑноÑти (SAST и DAST) и многого другого!"
@@ -12804,7 +13484,7 @@ msgid "Make and review changes in the browser with the Web IDE"
msgstr "ВнеÑите и проÑмотрите Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² браузере Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ Web IDE"
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 ""
+msgstr "Сделайте вÑех в Ñвоей команде более производительными незавиÑимо от меÑтоположениÑ. GitLab Geo Ñоздаёт доÑтупные только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ð·ÐµÑ€ÐºÐ°Ð»Ð° вашего ÑкземплÑра GitLab так, чтобы Ñократить времÑ, необходимое Ð´Ð»Ñ ÐºÐ»Ð¾Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸ ÑÐºÐ°Ñ‡Ð¸Ð²Ð°Ð½Ð¸Ñ Ð±Ð¾Ð»ÑŒÑˆÐ¸Ñ… репозиториев."
msgid "Make issue confidential"
msgstr ""
@@ -12815,10 +13495,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12845,6 +13525,9 @@ msgstr "Управление метками группы"
msgid "Manage labels"
msgstr "Управление метками"
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr "Управление метками проекта"
@@ -12896,9 +13579,6 @@ msgstr "Отметить как выполнено"
msgid "Mark as resolved"
msgstr "Отметить как решенное"
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12908,9 +13588,6 @@ msgstr ""
msgid "Markdown"
msgstr "Markdown"
-msgid "Markdown Help"
-msgstr "Справка по Markdown"
-
msgid "Markdown enabled"
msgstr "Включен режим Markdown"
@@ -12999,7 +13676,7 @@ msgid "Maximum attachment size (MB)"
msgstr "МакÑимальный размер Ð²Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ (Мбайт)"
msgid "Maximum bulk request size (MiB)"
-msgstr ""
+msgstr "МакÑимальный размер маÑÑового запроÑа (МиБ)"
msgid "Maximum capacity"
msgstr ""
@@ -13011,10 +13688,10 @@ msgid "Maximum delay (Minutes)"
msgstr "МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð·Ð°Ð´ÐµÑ€Ð¶ÐºÐ° (в минутах)"
msgid "Maximum duration of a session."
-msgstr ""
+msgstr "МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾ÑÑ‚ÑŒ ÑеÑÑии."
msgid "Maximum field length"
-msgstr ""
+msgstr "МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° полÑ"
msgid "Maximum job timeout"
msgstr ""
@@ -13047,16 +13724,16 @@ msgid "Maximum push size (MB)"
msgstr "МакÑимальный размер отправки (Мбайт)"
msgid "Maximum size limit for a single commit."
-msgstr ""
+msgstr "МакÑимальный размер отдельного коммита."
msgid "Maximum size limit for each repository."
-msgstr ""
+msgstr "МакÑимальный размер на каждый репозиторий."
msgid "Maximum size of Elasticsearch bulk indexing requests."
msgstr ""
msgid "Maximum size of individual attachments in comments."
-msgstr ""
+msgstr "МакÑимальный размер отдельных вложений в комментариÑÑ…."
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr "МакÑимальное Ð²Ñ€ÐµÐ¼Ñ Ð¼ÐµÐ¶Ð´Ñƒ обновлениÑми, которое может иметь зеркало при Ñинхронизации по раÑпиÑанию."
@@ -13088,6 +13765,9 @@ msgstr "УчаÑтники могут быть добавлены в проекÑ
msgid "Members of <strong>%{project_name}</strong>"
msgstr "УчаÑтники <strong>%{project_name}</strong>"
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -13097,9 +13777,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -13112,6 +13789,9 @@ msgstr "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° ÑлиÑние"
msgid "Merge Request Approvals"
msgstr "ÐŸÐ¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñов на ÑлиÑние"
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr "ЗапроÑÑ‹ на ÑлиÑние"
@@ -13145,9 +13825,12 @@ msgstr "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° ÑлиÑние"
msgid "Merge request %{iid} authored by %{authorName}"
msgstr "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° ÑлиÑние %{iid}, Ñозданный %{authorName}"
-msgid "Merge request approvals"
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
msgstr ""
+msgid "Merge request approvals"
+msgstr "Подтверждение запроÑов на ÑлиÑние"
+
msgid "Merge request approvals allow you to set the number of necessary approvals and predefine a list of approvers that will need to approve every merge request in a project."
msgstr ""
@@ -13164,7 +13847,7 @@ msgid "Merge requests are a place to propose changes you've made to a project an
msgstr "ЗапроÑÑ‹ на ÑлиÑние- Ñто меÑто, где можно предлагать Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð²Ð½Ð¾Ñимые в проект, и обÑуждать Ñти Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñ Ð´Ñ€ÑƒÐ³Ð¸Ð¼Ð¸"
msgid "Merge requests are read-only in a secondary Geo node"
-msgstr ""
+msgstr "ЗапроÑÑ‹ на ÑлиÑние доÑтупны только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ð²Ð¾ вторичных узлах Geo"
msgid "Merge when pipeline succeeds"
msgstr "Объединить при уÑпешном выполнении Ñборочной линии"
@@ -13193,9 +13876,18 @@ msgstr "Конфликты"
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13209,7 +13901,7 @@ msgid "MergeRequests|Reply..."
msgstr "Ответить..."
msgid "MergeRequests|Resolve this thread in a new issue"
-msgstr ""
+msgstr "Решить Ñту тему в новом обÑуждении"
msgid "MergeRequests|Saving the comment failed"
msgstr ""
@@ -13236,7 +13928,7 @@ msgid "MergeRequests|View file @ %{commitId}"
msgstr "ПроÑмотр файла @ %{commitId}"
msgid "MergeRequests|View replaced file @ %{commitId}"
-msgstr ""
+msgstr "ПроÑмотр заменÑемого файла @ %{commitId}"
msgid "MergeRequests|commented on commit %{commitLink}"
msgstr "прокомментировано в коммите%{commitLink}"
@@ -13251,12 +13943,12 @@ msgid "MergeRequests|started a thread on %{linkStart}the diff%{linkEnd}"
msgstr ""
msgid "MergeRequests|started a thread on an outdated change in commit %{linkStart}%{commitDisplay}%{linkEnd}"
-msgstr ""
+msgstr "начал тему про уÑтаревшие Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² коммите %{linkStart}%{commitDisplay}%{linkEnd}"
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
-msgstr ""
+msgstr "начал тему про коммит %{linkStart}%{commitDisplay}%{linkEnd}"
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13269,11 +13961,14 @@ msgid "MergeRequest|No files found"
msgstr ""
msgid "MergeRequest|Search files (%{modifier_key}P)"
-msgstr ""
+msgstr "ПоиÑк файлов (%{modifier_key}P)"
msgid "Merged"
msgstr "Слито"
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr "Объединенные ветви удалÑÑŽÑ‚ÑÑ. Это может занÑÑ‚ÑŒ некоторое Ð²Ñ€ÐµÐ¼Ñ Ð² завиÑимоÑти от количеÑтва ветвей. ПожалуйÑта, обновите Ñтраницу, чтобы увидеть изменениÑ."
@@ -13295,9 +13990,6 @@ msgstr "СообщениÑ"
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr "Метрика была уÑпешно добавлена."
@@ -13305,7 +13997,7 @@ msgid "Metric was successfully updated."
msgstr "Метрика была уÑпешно обновлена."
msgid "Metric:"
-msgstr ""
+msgstr "Метрика:"
msgid "MetricChart|Please select a metric"
msgstr "ПожалуйÑта, выберите метрику"
@@ -13317,10 +14009,7 @@ msgid "Metrics"
msgstr "Метрики"
msgid "Metrics - Grafana"
-msgstr ""
-
-msgid "Metrics - Influx"
-msgstr "Метрики - Influx"
+msgstr "Метрики - Grafana"
msgid "Metrics - Prometheus"
msgstr "Метрики - Prometheus"
@@ -13328,31 +14017,58 @@ msgstr "Метрики - Prometheus"
msgid "Metrics Dashboard"
msgstr "Панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¼ÐµÑ‚Ñ€Ð¸ÐºÐ°Ð¼Ð¸"
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
msgid "Metrics and profiling"
msgstr "Метрики и профилирование"
-msgid "Metrics for environment"
-msgstr "Метрики Ð´Ð»Ñ Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ"
-
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
-msgstr ""
+msgstr "ÐÐ½Ð½Ð¾Ñ‚Ð°Ñ†Ð¸Ñ Ð½Ðµ может принадлежать одновременно клаÑтеру и окружению"
msgid "Metrics::Dashboard::Annotation|Annotation has not been deleted"
-msgstr ""
+msgstr "ÐÐ½Ð½Ð¾Ñ‚Ð°Ñ†Ð¸Ñ Ð½Ðµ была удалена"
msgid "Metrics::Dashboard::Annotation|Annotation must belong to a cluster or an environment"
-msgstr ""
+msgstr "ÐÐ½Ð½Ð¾Ñ‚Ð°Ñ†Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° принадлежать клаÑтеру или окружению"
msgid "Metrics::Dashboard::Annotation|Dashboard with requested path can not be found"
-msgstr ""
+msgstr "Ðевозможно найти Панель Ñ Ð·Ð°Ð¿Ñ€Ð¾ÑˆÐµÐ½Ð½Ñ‹Ð¼ путём"
msgid "Metrics::Dashboard::Annotation|You are not authorized to create annotation for selected cluster"
-msgstr ""
+msgstr "Ð’Ñ‹ не уполномочены Ñоздавать аннотации Ð´Ð»Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð¾Ð³Ð¾ клаÑтера"
msgid "Metrics::Dashboard::Annotation|You are not authorized to create annotation for selected environment"
-msgstr ""
+msgstr "Ð’Ñ‹ не уполномочены Ñоздавать аннотации Ð´Ð»Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð¾Ð³Ð¾ окружениÑ"
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
+msgstr "У Ð²Ð°Ñ Ð½ÐµÑ‚ права на удаление Ñтой аннотации"
+
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
msgstr ""
msgid "Metrics|Add metric"
@@ -13377,42 +14093,48 @@ msgid "Metrics|Delete metric?"
msgstr "Удалить метрику?"
msgid "Metrics|Duplicate"
-msgstr ""
+msgstr "Дублировать"
msgid "Metrics|Duplicate dashboard"
msgstr "Дублировать панель управлениÑ"
msgid "Metrics|Duplicating..."
-msgstr ""
+msgstr "Дублирование..."
msgid "Metrics|Edit metric"
msgid_plural "Metrics|Edit metrics"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "Редактировать метрику"
+msgstr[1] "Редактировать метрики"
+msgstr[2] "Редактировать метрики"
+msgstr[3] "Редактировать метрики"
msgid "Metrics|Expand panel"
-msgstr ""
+msgstr "Развернуть панель"
msgid "Metrics|For grouping similar metrics"
-msgstr ""
+msgstr "Ð”Ð»Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð¸Ñ€Ð¾Ð²ÐºÐ¸ похожих метрик"
msgid "Metrics|Go back (Esc)"
msgstr ""
msgid "Metrics|Invalid time range, please verify."
-msgstr ""
+msgstr "ÐедопуÑтимый промежуток времени, пожалуйÑта, проверьте его."
msgid "Metrics|Label of the y-axis (usually the unit). The x-axis always represents time."
msgstr "Метка оÑи Y (обычно Ñто единица измерениÑ). ОÑÑŒ X вÑегда предÑтавлÑет времÑ."
msgid "Metrics|Legend label (optional)"
-msgstr ""
+msgstr "Метка легенды (необÑзательно)"
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr "МакÑ"
@@ -13426,11 +14148,14 @@ msgid "Metrics|PromQL query is valid"
msgstr "Ð—Ð°Ð¿Ñ€Ð¾Ñ PromQL дейÑтвителен"
msgid "Metrics|Prometheus Query Documentation"
-msgstr ""
+msgstr "Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ Ð¿Ð¾ запроÑам Prometheus"
msgid "Metrics|Refresh dashboard"
msgstr "Обновить панель управлениÑ"
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr "Произошла ошибка при Ñоздании панели управлениÑ"
@@ -13438,10 +14163,10 @@ msgid "Metrics|There was an error creating the dashboard. %{error}"
msgstr "Произошла ошибка при Ñоздании панели управлениÑ. %{error}"
msgid "Metrics|There was an error fetching annotations. Please try again."
-msgstr ""
+msgstr "Произошла ошибка при извлечении аннотаций. ПожалуйÑта, попробуйте ещё раз."
msgid "Metrics|There was an error fetching the environments data, please try again"
-msgstr ""
+msgstr "Произошла ошибка при извлечении данных окружениÑ, пожалуйÑта, попробуйте ещё раз"
msgid "Metrics|There was an error getting annotations information."
msgstr "Произошла ошибка при получении информации об аннотациÑÑ…."
@@ -13450,16 +14175,16 @@ msgid "Metrics|There was an error getting deployment information."
msgstr "Произошла ошибка при получении Ñведений о развёртывании."
msgid "Metrics|There was an error getting environments information."
-msgstr ""
+msgstr "Произошла ошибка при получении информации об окружениÑÑ…."
msgid "Metrics|There was an error trying to validate your query"
msgstr "Произошла ошибка при попытке проверить ваш запроÑ"
msgid "Metrics|There was an error while retrieving metrics"
-msgstr ""
+msgstr "Произошла ошибка при получении метрик"
msgid "Metrics|There was an error while retrieving metrics. %{message}"
-msgstr ""
+msgstr "Произошла ошибка при получении метрик. %{message}"
msgid "Metrics|Unexpected deployment data response from prometheus endpoint"
msgstr "Ðеожиданные данные Ñ€Ð°Ð·Ð²Ñ‘Ñ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð² ответе от точки Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Prometheus"
@@ -13467,9 +14192,12 @@ msgstr "Ðеожиданные данные Ñ€Ð°Ð·Ð²Ñ‘Ñ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð² отв
msgid "Metrics|Unit label"
msgstr ""
-msgid "Metrics|Used as a title for the chart"
+msgid "Metrics|Unstar dashboard"
msgstr ""
+msgid "Metrics|Used as a title for the chart"
+msgstr "ИÑпользуетÑÑ ÐºÐ°Ðº заголовок Ð´Ð»Ñ Ð´Ð¸Ð°Ð³Ñ€Ð°Ð¼Ð¼Ñ‹"
+
msgid "Metrics|Used if the query returns a single series. If it returns multiple series, their legend labels will be picked up from the response."
msgstr ""
@@ -13480,10 +14208,10 @@ msgid "Metrics|Values"
msgstr ""
msgid "Metrics|View logs"
-msgstr ""
+msgstr "ПроÑмотр журналов"
msgid "Metrics|Y-axis label"
-msgstr ""
+msgstr "ПодпиÑÑŒ оÑи Y"
msgid "Metrics|You can save a copy of this dashboard to your repository so it can be customized. Select a file name and branch to save it."
msgstr ""
@@ -13531,6 +14259,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr "Этапы"
@@ -13540,6 +14325,12 @@ msgstr "Ð’Ñ‹ ÑобираетеÑÑŒ окончательно удалить ÑÑ‚
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr "Ð’Ñ‹ ÑобираетеÑÑŒ безвозвратно удалить Ñтап %{milestoneTitle}. Этот Ñтап в наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð½Ðµ иÑпользуетÑÑ Ð½Ð¸ в обÑуждениÑÑ…, ни в запроÑах на ÑлиÑние."
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr "Удалить Ñтап"
@@ -13549,21 +14340,39 @@ msgstr "Удалить Ñтап %{milestoneTitle}?"
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr "Ðе удалоÑÑŒ удалить Ñтап %{milestoneTitle}"
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr "Этап %{milestoneTitle} не найден"
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr "ПовыÑить %{milestoneTitle} до группового Ñтапа?"
msgid "Milestones|Promote Milestone"
msgstr "ПовыÑить Ñтап"
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr "Повышение ÑƒÑ€Ð¾Ð²Ð½Ñ %{milestoneTitle} Ñделает его доÑтупным Ð´Ð»Ñ Ð²Ñех проектов внутри %{groupName}. СущеÑтвующие Ñтапы проекта Ñ Ñ‚Ð°ÐºÐ¸Ð¼ же заголовком будут объединены."
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr "Это дейÑтвие не может быть отменено."
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13586,7 +14395,7 @@ msgid "Mirror repository"
msgstr "Зеркалировать репозиторий"
msgid "Mirror settings are only available to GitLab administrators."
-msgstr ""
+msgstr "ÐаÑтройки Ð·ÐµÑ€ÐºÐ°Ð»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð¾Ñтупны только админиÑтраторам GitLab."
msgid "Mirror user"
msgstr ""
@@ -13613,7 +14422,7 @@ msgid "Mirroring will only be available if the feature is included in the plan o
msgstr ""
msgid "Missing commit signatures endpoint!"
-msgstr ""
+msgstr "ОтÑутÑтвует точка Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñей коммитов!"
msgid "MissingSSHKeyWarningLink|Add SSH key"
msgstr "Добавить ключ SSH"
@@ -13624,6 +14433,9 @@ msgstr "Больше не показывать"
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr "Ð’Ñ‹ не Ñможете отправлÑÑ‚ÑŒ или получать код проекта Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ SSH, пока не добавите ключ SSH в ваш профиль"
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr "Отмена"
@@ -13637,7 +14449,7 @@ msgid "Modified in this version"
msgstr "Изменено в Ñтой верÑии"
msgid "Modify commit message"
-msgstr ""
+msgstr "Изменить опиÑание коммита"
msgid "Modify commit messages"
msgstr "Изменить опиÑÐ°Ð½Ð¸Ñ ÐºÐ¾Ð¼Ð¼Ð¸Ñ‚Ð°"
@@ -13738,6 +14550,9 @@ msgstr "Развернуть повторно"
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13747,6 +14562,9 @@ msgstr "Ðайдено неÑколько типов моделей: %{model_typ
msgid "Multiple uploaders found: %{uploader_types}"
msgstr "Ðайдено неÑколько загрузчиков: %{uploader_types}"
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr "ÐœÐ¾Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ Ð¸Ð»Ð¸ команда"
@@ -13759,9 +14577,6 @@ msgstr "ИмÑ"
msgid "Name has already been taken"
msgstr "Ð˜Ð¼Ñ ÑƒÐ¶Ðµ занÑто"
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr "Ðазвать новую метку"
@@ -13771,9 +14586,6 @@ msgstr "Ðаименование:"
msgid "Namespace is empty"
msgstr "ПроÑтранÑтво имён пуÑто"
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13807,6 +14619,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr "Ðикогда"
@@ -13820,7 +14680,7 @@ msgid "New Environment"
msgstr "Ðовое окружение"
msgid "New Geo Node"
-msgstr ""
+msgstr "Ðовый узел Geo"
msgid "New Group"
msgstr "ÐÐ¾Ð²Ð°Ñ Ð“Ñ€ÑƒÐ¿Ð¿Ð°"
@@ -13838,9 +14698,12 @@ msgstr[1] "Ðовых ОбÑуждениÑ"
msgstr[2] "Ðовых ОбÑуждений"
msgstr[3] "Ðовые ОбÑуждениÑ"
-msgid "New Jira import"
+msgid "New Iteration"
msgstr ""
+msgid "New Jira import"
+msgstr "Ðовый импорт из Jira"
+
msgid "New Label"
msgstr "ÐÐ¾Ð²Ð°Ñ Ð¼ÐµÑ‚ÐºÐ°"
@@ -13904,6 +14767,9 @@ msgstr "Ðовое обÑуждение"
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr "ÐÐ¾Ð²Ð°Ñ Ð¼ÐµÑ‚ÐºÐ°"
@@ -13917,7 +14783,7 @@ msgid "New password"
msgstr "Ðовый пароль"
msgid "New pipelines will cancel older, pending pipelines on the same branch"
-msgstr ""
+msgstr "Ðовые Ñборочные линии будут отключать более Ñтарые или находÑщиеÑÑ Ð² ожидании Ñборочные линии в рамках одной ветки."
msgid "New project"
msgstr "Ðовый проект"
@@ -13961,6 +14827,9 @@ msgstr ""
msgid "Next"
msgstr "Next"
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13979,18 +14848,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr "Ðет цели"
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr "Ðет Ñтапа"
-
msgid "No Scopes"
msgstr ""
@@ -14055,7 +14915,7 @@ msgid "No due date"
msgstr "Дата Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð½Ðµ указана"
msgid "No endpoint provided"
-msgstr ""
+msgstr "Точка Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð½Ðµ предоÑтавлена"
msgid "No errors to display."
msgstr ""
@@ -14081,12 +14941,18 @@ msgstr "Файлы не найдены."
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr "Ðет заданий Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ"
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr "Ðет меток Ñ Ñ‚Ð°ÐºÐ¸Ð¼ наименованием или опиÑанием"
@@ -14111,6 +14977,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr "Ðет Ñтапов Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ"
@@ -14160,7 +15029,7 @@ msgid "No template"
msgstr ""
msgid "No test coverage"
-msgstr ""
+msgstr "Без Ð¿Ð¾ÐºÑ€Ñ‹Ñ‚Ð¸Ñ Ñ‚ÐµÑтами"
msgid "No thanks, don't show this again"
msgstr ""
@@ -14172,7 +15041,7 @@ 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 ""
+msgstr "Ðе беÑпокойтеÑÑŒ, вы вÑÑ‘ ещё можете иÑпользовать вÑе функции %{strong}%{plan_name}%{strong_close}. У Ð²Ð°Ñ Ð¾ÑталоÑÑŒ %{remaining_days} Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð»ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки."
msgid "No, directly import the existing email addresses and usernames."
msgstr ""
@@ -14246,6 +15115,9 @@ msgstr "Заметка"
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14270,6 +15142,9 @@ msgstr "Ð’Ñ‹ уверены, что вы хотите отменить ÑоздÐ
msgid "Notes|Collapse replies"
msgstr "Свернуть ответы"
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14384,9 +15259,15 @@ msgstr "ÐоÑб."
msgid "November"
msgstr "ÐоÑбрь"
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14397,7 +15278,7 @@ msgid "Number of Elasticsearch shards"
msgstr ""
msgid "Number of LOCs per commit"
-msgstr ""
+msgstr "КоличеÑтво Ñтрок кода (LOC) на коммит"
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 ""
@@ -14406,7 +15287,7 @@ msgid "Number of changes (branches or tags) in a single push to determine whethe
msgstr "КоличеÑтво изменений (веток или тегов) в одной отправке, которое определÑет, будут ли запущены веб-обработчики и Ñлужбы. Веб-обработчики и Ñлужбы не будут выполнÑÑ‚ÑŒÑÑ, еÑли Ñто значение будет превышено."
msgid "Number of commits"
-msgstr ""
+msgstr "КоличеÑтво коммитов"
msgid "Number of commits per MR"
msgstr ""
@@ -14436,7 +15317,7 @@ msgid "OfSearchInADropdown|Filter"
msgstr "Фильтр"
msgid "Oh no!"
-msgstr ""
+msgstr "О, нет!"
msgid "Ok let's go"
msgstr ""
@@ -14451,6 +15332,15 @@ msgid "Omnibus Protected Paths throttle is active, and takes priority over these
msgstr ""
msgid "On track"
+msgstr "По плану"
+
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
msgstr ""
msgid "Onboarding"
@@ -14462,9 +15352,6 @@ msgstr "ПоÑле импорта, репозитории могут зеркаÐ
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr "ПоÑле удалениÑ, ÑвÑзь Ð¾Ñ‚Ð²ÐµÑ‚Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ðµ может быть воÑÑтановлена, и вы больше не Ñможете отправлÑÑ‚ÑŒ запроÑÑ‹ на ÑлиÑние в иÑточник."
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 "ПоÑле того, как ÑкÑпортируемый файл будет готов, вы получите уведомление по Ñлектронной почте Ñ ÑÑылкой Ð´Ð»Ñ ÑкачиваниÑ, или вы Ñможете Ñкачать его Ñ Ñтой Ñтраницы."
@@ -14532,7 +15419,7 @@ msgstr "Только учаÑтники проекта могут оÑтавлÑ
msgid "Only project members will be imported. Group members will be skipped."
msgstr "Будут импортированы только учаÑтники проекта. УчаÑтники группы будут пропущены."
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14577,7 +15464,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14592,6 +15479,9 @@ msgstr "ОткроетÑÑ Ð² новом окне"
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr "ÐžÐ¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ð½Ðµ удалаÑÑŒ. Проверьте журналы пода Ð´Ð»Ñ %{pod_name} Ð´Ð»Ñ Ð±Ð¾Ð»ÐµÐµ подробной информации."
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¸ иÑтекло. Проверьте журналы пода %{pod_name} Ð´Ð»Ñ Ð±Ð¾Ð»ÐµÐµ подробной информации."
@@ -14617,12 +15507,12 @@ msgid "OperationsDashboard|Operations Dashboard"
msgstr "Панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñми"
msgid "OperationsDashboard|The operations dashboard provides a summary of each project's operational health, including pipeline and alert statuses."
-msgstr "Панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñми Ñодержит Ñводку о работоÑпоÑобноÑти каждого проекта, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ ÑоÑтоÑÐ½Ð¸Ñ ÐºÐ¾Ð½Ð²ÐµÐ¹ÐµÑ€Ð° и предупреждений."
+msgstr "ÐžÐ¿ÐµÑ€Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð°Ñ Ð¿Ð°Ð½ÐµÐ»ÑŒ предоÑтавлÑет Ñводку оперативного ÑоÑтоÑÐ½Ð¸Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ проекта, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ ÑтатуÑÑ‹ Ñборочной линии и предупреждений."
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14670,6 +15560,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14688,9 +15581,12 @@ msgstr "Принадлежащие мне"
msgid "Owner"
msgstr "Владелец"
-msgid "Package Registry"
+msgid "Package Files"
msgstr ""
+msgid "Package Registry"
+msgstr "РееÑÑ‚Ñ€ пакетов"
+
msgid "Package already exists"
msgstr ""
@@ -14709,6 +15605,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr "Пакет был удален"
@@ -14716,43 +15618,43 @@ msgid "PackageRegistry|Add Conan Remote"
msgstr ""
msgid "PackageRegistry|Add NuGet Source"
-msgstr ""
+msgstr "Добавить иÑточник NuGet"
msgid "PackageRegistry|Conan"
-msgstr ""
+msgstr "Conan"
msgid "PackageRegistry|Conan Command"
-msgstr ""
+msgstr "Команда Conan"
msgid "PackageRegistry|Copy .pypirc content"
-msgstr ""
+msgstr "Копировать Ñодержимое .pypirc"
msgid "PackageRegistry|Copy Conan Command"
-msgstr ""
+msgstr "Копировать команду Conan"
msgid "PackageRegistry|Copy Conan Setup Command"
-msgstr ""
+msgstr "Копировать команду наÑтройки Conan"
msgid "PackageRegistry|Copy Maven XML"
-msgstr ""
+msgstr "Копировать XML Ð´Ð»Ñ Maven"
msgid "PackageRegistry|Copy Maven command"
-msgstr ""
+msgstr "Копировать команду Maven"
msgid "PackageRegistry|Copy Maven registry XML"
-msgstr ""
+msgstr "Копировать XML Ð´Ð»Ñ Ñ€ÐµÐµÑтра Maven"
msgid "PackageRegistry|Copy NuGet Command"
-msgstr ""
+msgstr "Копировать команду NuGet"
msgid "PackageRegistry|Copy NuGet Setup Command"
-msgstr ""
+msgstr "Копировать команду наÑтройки NuGet"
msgid "PackageRegistry|Copy Pip command"
-msgstr ""
+msgstr "Копировать команду pip"
msgid "PackageRegistry|Copy and paste this inside your %{codeStart}pom.xml%{codeEnd} %{codeStart}dependencies%{codeEnd} block."
-msgstr ""
+msgstr "Скопируйте Ñто и вÑтавьте в блок %{codeStart}dependencies%{codeEnd} вашего %{codeStart}pom.xml%{codeEnd}."
msgid "PackageRegistry|Copy npm command"
msgstr "Копировать команду npm"
@@ -14770,25 +15672,25 @@ msgid "PackageRegistry|Delete Package Version"
msgstr "Удалить верÑию пакета"
msgid "PackageRegistry|Delete package"
-msgstr ""
+msgstr "Удалить пакет"
msgid "PackageRegistry|Filter by name"
-msgstr ""
+msgstr "Фильтровать по имени"
msgid "PackageRegistry|For more information on the Conan registry, %{linkStart}see the documentation%{linkEnd}."
-msgstr ""
+msgstr "Чтобы узнать больше о рееÑтре Conan, %{linkStart}Ñмотрите документацию%{linkEnd}."
msgid "PackageRegistry|For more information on the Maven registry, %{linkStart}see the documentation%{linkEnd}."
-msgstr ""
+msgstr "Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации о рееÑтре Maven %{linkStart}Ñмотрите документацию%{linkEnd}."
msgid "PackageRegistry|For more information on the NuGet registry, %{linkStart}see the documentation%{linkEnd}."
-msgstr ""
+msgstr "Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации о рееÑтре NuGet %{linkStart}Ñмотрите документацию%{linkEnd}."
msgid "PackageRegistry|For more information on the PyPi registry, %{linkStart}see the documentation%{linkEnd}."
-msgstr ""
+msgstr "Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации о рееÑтре PyPi %{linkStart}Ñмотрите документацию%{linkEnd}."
msgid "PackageRegistry|If you haven't already done so, you will need to add the below to your %{codeStart}.pypirc%{codeEnd} file."
-msgstr ""
+msgstr "ЕÑли вы еще не Ñделали Ñтого, вам нужно будет добавить нижераÑположенное в Ñвой файл %{codeStart}.pypirc%{codeEnd}."
msgid "PackageRegistry|If you haven't already done so, you will need to add the below to your %{codeStart}pom.xml%{codeEnd} file."
msgstr ""
@@ -14796,41 +15698,47 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr "УÑтановка"
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
msgid "PackageRegistry|Manually Published"
-msgstr ""
+msgstr "Опубликовано вручную"
msgid "PackageRegistry|Maven"
-msgstr ""
+msgstr "Maven"
msgid "PackageRegistry|Maven Command"
-msgstr ""
+msgstr "Команда Maven"
msgid "PackageRegistry|Maven XML"
-msgstr ""
+msgstr "XML Maven"
msgid "PackageRegistry|NPM"
+msgstr "NPM"
+
+msgid "PackageRegistry|No upcoming issues"
msgstr ""
msgid "PackageRegistry|NuGet"
-msgstr ""
+msgstr "NuGet"
msgid "PackageRegistry|NuGet Command"
-msgstr ""
+msgstr "Команда NuGet"
msgid "PackageRegistry|Pip Command"
-msgstr ""
+msgstr "Команда pip"
msgid "PackageRegistry|Pipeline %{linkStart}%{linkEnd} triggered %{timestamp} by %{author}"
-msgstr ""
+msgstr "Ð¡Ð±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ %{linkStart}%{linkEnd}, Ð²Ñ‹Ð·Ð²Ð°Ð½Ð½Ð°Ñ %{author} %{timestamp}"
msgid "PackageRegistry|Published to the repository at %{timestamp}"
-msgstr ""
+msgstr "Опубликовано в репозиторий %{timestamp}"
msgid "PackageRegistry|PyPi"
-msgstr ""
+msgstr "PyPi"
msgid "PackageRegistry|Registry Setup"
msgstr "ÐаÑтройка рееÑтра"
@@ -14839,32 +15747,47 @@ msgid "PackageRegistry|Remove package"
msgstr "Удалить пакет"
msgid "PackageRegistry|Sorry, your filter produced no results"
-msgstr ""
+msgstr "Извините, ваш фильтр иÑключил вÑе результаты"
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr "Пока что нет пакетов"
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr "Ðе удалоÑÑŒ получить ÑÐ²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾Ð± Ñтом пакете."
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
+msgstr "Чтобы раÑширить результаты поиÑка, измените или удалите фильтры выше."
+
+msgid "PackageRegistry|Unable to fetch package version information."
msgstr ""
msgid "PackageRegistry|Unable to load package"
msgstr "Ðевозможно загрузить пакет"
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
-msgstr "Ð’Ñ‹ ÑобираетеÑÑŒ удалить верÑию %{boldStart}%{version}%{boldEnd} %{boldStart}%{name}%{boldEnd}. Ð’Ñ‹ уверены?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
-msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
+msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
+msgstr "Вам также может понадобитьÑÑ Ð½Ð°Ñтроить аутентификацию Ñ Ð¸Ñпользованием токена. %{linkStart}Смотрите документацию%{linkEnd}, чтобы узнать больше."
+
msgid "PackageRegistry|npm"
msgstr "npm"
@@ -14892,6 +15815,9 @@ msgstr ""
msgid "Packages"
msgstr "Пакеты"
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14971,7 +15897,7 @@ msgid "Password authentication is unavailable."
msgstr "ÐÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð¿Ð¾ паролю недоÑтупна."
msgid "Password confirmation"
-msgstr ""
+msgstr "Подтверждение паролÑ"
msgid "Password successfully changed"
msgstr ""
@@ -14979,6 +15905,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14997,9 +15926,12 @@ 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'. Don't use your private SSH key."
msgstr "Ð’Ñтавьте ваш открытый ключ SSH, который обычно ÑодержитÑÑ Ð² файле '~/.ssh/id_ed25519.pub' или '~/.ssh/id_rsa.pub' и начинаетÑÑ Ñ 'ssh-ed25519' или 'ssh-rsa'. Ðе иÑпользуйте ваш закрытый ключ SSH."
-msgid "Path"
+msgid "Patch to apply"
msgstr ""
+msgid "Path"
+msgstr "Путь"
+
msgid "Path:"
msgstr "Путь:"
@@ -15034,14 +15966,20 @@ msgid "Perform advanced options such as changing path, transferring, exporting,
msgstr ""
msgid "Perform common operations on GitLab project"
-msgstr ""
+msgstr "ВыполнÑйте обычные дейÑÑ‚Ð²Ð¸Ñ Ð½Ð°Ð´ проектом GitLab"
msgid "Performance optimization"
msgstr "ÐžÐ¿Ñ‚Ð¸Ð¼Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¿Ñ€Ð¾Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ñти"
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr "Скачать"
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -15063,9 +16001,6 @@ msgstr ""
msgid "Permissions"
msgstr "Права доÑтупа"
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr "РазрешениÑ, LFS, 2FA"
@@ -15087,9 +16022,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr "Выберите Ð¸Ð¼Ñ Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ, и мы предоÑтавим вам уникальный %{type} токен."
-
msgid "Pin code"
msgstr "Пин-код"
@@ -15109,19 +16041,19 @@ msgid "Pipeline Schedules"
msgstr "РаÑпиÑÐ°Ð½Ð¸Ñ Ð¡Ð±Ð¾Ñ€Ð¾Ñ‡Ð½Ñ‹Ñ… Линий"
msgid "Pipeline minutes quota"
-msgstr "Квота иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñборочных линий в минутах"
+msgstr "Квота иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ CI в минутах"
msgid "Pipeline subscriptions"
msgstr ""
msgid "Pipeline triggers"
-msgstr ""
+msgstr "Триггеры Ñборки"
msgid "Pipeline: %{status}"
msgstr "Ð¡Ð±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ:%{status}"
msgid "PipelineCharts|CI / CD Analytics"
-msgstr ""
+msgstr "Ðналитика CI / CD"
msgid "PipelineCharts|Failed:"
msgstr "Ðеудача:"
@@ -15172,7 +16104,7 @@ msgid "PipelineSheduleIntervalPattern|Custom"
msgstr "ÐаÑтраиваемый"
msgid "PipelineStatusTooltip|Pipeline: %{ciStatus}"
-msgstr ""
+msgstr "Ð¡Ð±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ: %{ciStatus}"
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr "Ð¡Ð±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ:%{ci_status}"
@@ -15187,10 +16119,10 @@ msgid "Pipelines emails"
msgstr ""
msgid "Pipelines for last month (%{oneMonthAgo} - %{today})"
-msgstr ""
+msgstr "Сборочные линии за поÑледний меÑÑц (%{oneMonthAgo} - %{today})"
msgid "Pipelines for last week (%{oneWeekAgo} - %{today})"
-msgstr ""
+msgstr "Сборочные линии за поÑледнюю неделю (%{oneWeekAgo} - %{today})"
msgid "Pipelines for last year"
msgstr "Сборочные линии за поÑледний год"
@@ -15198,6 +16130,9 @@ msgstr "Сборочные линии за поÑледний год"
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr "ÐаÑтройки Ñборочных линий Ð´Ð»Ñ '%{project_name}' были уÑпешно обновлены."
@@ -15223,10 +16158,10 @@ msgid "Pipelines|Get started with Pipelines"
msgstr "Ðачало работы Ñо Ñборочными линиÑми"
msgid "Pipelines|Group %{namespace_name} has %{percentage}%% or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
-msgstr ""
+msgstr "У группы %{namespace_name} оÑталоÑÑŒ %{percentage}%% или менее минут на Shared Runner Pipeline. Как только они закончатÑÑ, новые Ð·Ð°Ð´Ð°Ð½Ð¸Ñ Ð¸ Ñборочные линии проектов Ñтой группы переÑтанут выполнÑÑ‚ÑŒÑÑ."
msgid "Pipelines|Group %{namespace_name} has exceeded its pipeline minutes quota. Unless you buy additional pipeline minutes, no new jobs or pipelines in its projects will run."
-msgstr ""
+msgstr "Группа %{namespace_name} превыÑила квоту минут CI. Ð—Ð°Ð´Ð°Ð½Ð¸Ñ Ð½Ðµ будут запуÑкатьÑÑ, еÑли вы не купите дополнительные минуты."
msgid "Pipelines|Loading Pipelines"
msgstr "ЗагружаютÑÑ Ñборочные линии"
@@ -15258,15 +16193,24 @@ msgstr "Этот проект в наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð½Ðµ наÑтро
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr "Покрытие"
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15279,38 +16223,62 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr "Ð˜Ð¼Ñ ÑущеÑтвующей ветки или метки"
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr "Ð¡Ð±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ Ñ†ÐµÐ¿Ð¾Ñ‡ÐºÐ¸ ÑлиÑний"
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr "ЗапуÑтить Ñборочную линию"
msgid "Pipeline|Run for"
msgstr "ЗапуÑтить длÑ"
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr "ПоиÑк веток"
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr "Укажите Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ñ‹Ñ…, которые будут иÑпользоватьÑÑ Ð² Ñтом запуÑке. ЗначениÑ, указанные в %{settings_link} будут иÑпользоватьÑÑ Ð¿Ð¾ умолчанию."
msgid "Pipeline|Stages"
-msgstr "Стадии"
+msgstr "Этапы"
msgid "Pipeline|Status"
-msgstr ""
+msgstr "СтатуÑ"
msgid "Pipeline|Stop pipeline"
msgstr "ОÑтановить Ñборочную линию"
@@ -15318,6 +16286,9 @@ msgstr "ОÑтановить Ñборочную линию"
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr "ОÑтановить Ñборочную линию #%{pipelineId}?"
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15337,10 +16308,10 @@ msgid "Pipeline|on"
msgstr ""
msgid "Pipeline|with stage"
-msgstr "Ñо Ñтадией"
+msgstr "Ñ Ñтапом"
msgid "Pipeline|with stages"
-msgstr "Ñо ÑтадиÑми"
+msgstr "Ñ Ñтапами"
msgid "PivotalTrackerService|Comma-separated list of branches which will be automatically inspected. Leave blank to include all branches."
msgstr "Разделенный запÑтыми ÑпиÑок ветвей, которые будут автоматичеÑки проверÑÑ‚ÑŒÑÑ. ОÑтавьте пуÑтым, чтобы включить вÑе ветви."
@@ -15354,6 +16325,12 @@ msgstr ""
msgid "Plain diff"
msgstr "ПроÑтое отличие"
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr "PlantUML"
@@ -15447,6 +16424,9 @@ msgstr ""
msgid "Please provide a name"
msgstr "ПожалуйÑта, укажите имÑ"
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15460,7 +16440,7 @@ msgid "Please select"
msgstr ""
msgid "Please select a Jira project"
-msgstr ""
+msgstr "ПожалуйÑта, выберите проект Jira"
msgid "Please select a country"
msgstr ""
@@ -15490,7 +16470,7 @@ msgid "Please try again"
msgstr "ПожалуйÑта, попробуйте ещё раз"
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
-msgstr ""
+msgstr "ПожалуйÑта, введите %{phrase_code} чтобы продолжить, или закройте Ñто окно Ð´Ð»Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ñ‹."
msgid "Please upgrade PostgreSQL to version 9.6 or greater. The status of the replication cannot be determined reliably with the current version."
msgstr "ПожалуйÑта, обновите PostgreSQL до верÑии 9.6 или выше. Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ñ€ÐµÐ¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ð¸ не может быть определен надежно Ñ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ¹ верÑией."
@@ -15522,6 +16502,9 @@ msgstr "ИÑпользуемые поды"
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr "ПредпочтениÑ"
@@ -15612,6 +16595,9 @@ msgstr "ИÑпользовать отноÑительное времÑ"
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr "Запретить добавление новых учаÑтников в проектах Ñтой группы"
@@ -15648,6 +16634,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15867,9 +16856,6 @@ msgstr "Полное имÑ"
msgid "Profiles|Give your individual key a title"
msgstr "Укажите заголовок ключа"
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr "Включить вклад в приватные проекты в мой профиль"
@@ -15915,9 +16901,6 @@ msgstr "ОрганизациÑ"
msgid "Profiles|Path"
msgstr "Путь"
-msgid "Profiles|Personal Access"
-msgstr "Личный доÑтуп"
-
msgid "Profiles|Position and size your new avatar"
msgstr "Положение и размер вашего нового аватара"
@@ -16062,12 +17045,6 @@ msgstr "Ваш ÑтатуÑ"
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr "перÑональный"
-
msgid "Profiles|username"
msgstr "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ"
@@ -16098,6 +17075,9 @@ msgstr "Проект \"%{name}\" больше недоÑтупен. Чтобы Ð
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -16119,6 +17099,9 @@ msgstr "Проект '%{project_name}' уÑпешно обновлен."
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -16149,6 +17132,9 @@ msgstr "Ðватар проекта"
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr "ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ñлужбы"
@@ -16173,8 +17159,8 @@ msgstr "ЭкÑпорт проекта удален."
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr "ИÑтек Ñрок дейÑÑ‚Ð²Ð¸Ñ ÑÑылки на проект. Создайте новый ÑкÑпорт в ваших наÑтройках проекта."
-msgid "Project export started. A download link will be sent by email."
-msgstr "Ðачат ÑкÑпорт проекта. СÑылка Ð´Ð»Ñ ÑÐºÐ°Ñ‡Ð¸Ð²Ð°Ð½Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚ отправлена по Ñлектронной почте."
+msgid "Project export started. A download link will be sent by email and made available on this page."
+msgstr ""
msgid "Project has too many %{label_for_message} to search"
msgstr "Проект имеет Ñлишком много %{label_for_message} Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка"
@@ -16182,6 +17168,9 @@ msgstr "Проект имеет Ñлишком много %{label_for_message} Ð
msgid "Project members"
msgstr "УчаÑтники проекта"
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr "Ð˜Ð¼Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°"
@@ -16231,7 +17220,7 @@ msgid "ProjectCreationLevel|Default project creation protection"
msgstr ""
msgid "ProjectCreationLevel|Developers + Maintainers"
-msgstr ""
+msgstr "Developer'ы и Maintainer'ы"
msgid "ProjectCreationLevel|Maintainers"
msgstr ""
@@ -16296,9 +17285,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16464,6 +17450,9 @@ msgstr "Репозиторий"
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr "ДелитеÑÑŒ фрагментами кода Ñ Ð´Ñ€ÑƒÐ³Ð¸Ð¼Ð¸ за пределами Git-репозиториÑ"
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr "Показать ÑÑылку Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ / проÑмотра запроÑа на ÑлиÑние при отправке из командной Ñтроки"
@@ -16509,6 +17498,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr "Когда возникают конфликты, пользователю предоÑтавлÑетÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ÑŒ объединить изменениÑ, Ñделанные в одной ветке, Ñ Ð´Ñ€ÑƒÐ³Ð¾Ð¹ веткой"
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr "Wiki"
@@ -16659,6 +17651,9 @@ msgstr "Ðовый проект"
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr "СвÑжитеÑÑŒ Ñ Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñтратором, чтобы включить параметры импорта вашего проекта."
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr "Создать из шаблона"
@@ -16696,13 +17691,13 @@ msgid "ProjectsNew|Want to house several dependent projects under the same names
msgstr "Хотите размеÑтить неÑколько взаимоÑвÑзанных проектов в одном отдельном меÑте? %{link_start}Создать группу.%{link_end}"
msgid "Prometheus"
-msgstr ""
+msgstr "Prometheus"
msgid "PrometheusAlerts|%{count} alerts applied"
-msgstr ""
+msgstr "%{count} оповещений применено"
msgid "PrometheusAlerts|%{firingCount} firing"
-msgstr ""
+msgstr "%{firingCount} горÑщих"
msgid "PrometheusAlerts|Add alert"
msgstr "Добавить оповещение"
@@ -16717,25 +17712,25 @@ msgid "PrometheusAlerts|Error deleting alert"
msgstr "Ошибка ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð¾Ð¿Ð¾Ð²ÐµÑ‰ÐµÐ½Ð¸Ñ"
msgid "PrometheusAlerts|Error fetching alert"
-msgstr ""
+msgstr "Ошибка Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¾Ð¿Ð¾Ð²ÐµÑ‰ÐµÐ½Ð¸Ñ"
msgid "PrometheusAlerts|Error saving alert"
-msgstr ""
+msgstr "Ошибка ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¾Ð¿Ð¾Ð²ÐµÑ‰ÐµÐ½Ð¸Ñ"
msgid "PrometheusAlerts|Firing: %{alerts}"
-msgstr ""
+msgstr "ГорÑщие: %{alerts}"
msgid "PrometheusAlerts|Firing: %{alert}"
-msgstr ""
+msgstr "ГорÑщее: %{alert}"
msgid "PrometheusAlerts|Operator"
-msgstr ""
+msgstr "Оператор"
msgid "PrometheusAlerts|Select query"
msgstr "Выберите запроÑ"
msgid "PrometheusAlerts|Threshold"
-msgstr ""
+msgstr "Порог ÑрабатываниÑ"
msgid "PrometheusService|%{exporters} with %{metrics} were found"
msgstr "Были найдены %{exporters} Ñ %{metrics}"
@@ -16752,17 +17747,23 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
-msgid "PrometheusService|Common metrics"
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
msgstr ""
+msgid "PrometheusService|Common metrics"
+msgstr "Общие метрики"
+
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
+msgstr "Общие метрики ÑобираютÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки на оÑнове популÑрных библиотек метрик."
+
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
msgstr ""
msgid "PrometheusService|Custom metrics"
msgstr "ÐаÑтраиваемые метрики"
msgid "PrometheusService|Custom metrics require Prometheus installed on a cluster with environment scope \"*\" OR a manually configured Prometheus to be available."
-msgstr "ПользовательÑкие метрики требуют, чтобы Prometheus был уÑтановлен в клаÑтер Ñ Ð¾Ð±Ð»Ð°Ñтью дейÑÑ‚Ð²Ð¸Ñ Ñреды \"*\" ИЛИ наÑтроенной вручную, чтобы Prometheus был доÑтупен."
+msgstr "ПользовательÑкие метрики требуют, чтобы Prometheus был уÑтановлен в клаÑтер Ñ Ð¾Ð±Ð»Ð°Ñтью дейÑÑ‚Ð²Ð¸Ñ Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ \"*\" ИЛИ чтобы был доÑтупен наÑтроенный вручную Prometheus."
msgid "PrometheusService|Enable Prometheus to define custom metrics, using either option above"
msgstr "Включите Prometheus Ð´Ð»Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒÑких метрик, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð»ÑŽÐ±ÑƒÑŽ из указанных выше опций"
@@ -16771,7 +17772,7 @@ msgid "PrometheusService|Finding and configuring metrics..."
msgstr "Определение и наÑтройка метрик..."
msgid "PrometheusService|Finding custom metrics..."
-msgstr ""
+msgstr "ПоиÑк наÑтраиваемых метрик..."
msgid "PrometheusService|Install Prometheus on clusters"
msgstr "УÑтановить Prometheus на клаÑтеры"
@@ -16792,10 +17793,10 @@ msgid "PrometheusService|More information"
msgstr "Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ"
msgid "PrometheusService|New metric"
-msgstr ""
+msgstr "ÐÐ¾Ð²Ð°Ñ Ð¼ÐµÑ‚Ñ€Ð¸ÐºÐ°"
msgid "PrometheusService|No custom metrics have been created. Create one using the button above"
-msgstr ""
+msgstr "Ðе Ñоздано ни одной наÑтраиваемой метрики. Создайте её, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ ÐºÐ½Ð¾Ð¿ÐºÑƒ выше"
msgid "PrometheusService|Prometheus API Base URL, like http://prometheus.example.com/"
msgstr "Базовый Ð°Ð´Ñ€ÐµÑ Prometheus API, например http://prometheus.example.com/"
@@ -16833,9 +17834,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr "ПовыÑить до Группового Этапа"
-
msgid "Promote to group label"
msgstr "ПовыÑить до групповой метки"
@@ -16854,30 +17852,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 "Цели позволÑÑŽÑ‚ управлÑÑ‚ÑŒ портфелем проектов более Ñффективно и Ñ Ð¼ÐµÐ½ÑŒÑˆÐ¸Ð¼Ð¸ уÑилиÑми, отÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ñ Ð¾Ð±ÑŠÐµÐ´Ð¸Ð½Ñ‘Ð½Ð½Ñ‹Ðµ общей тематикой группы обÑуждений из различных проектов и Ñтапов."
+
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
msgstr ""
msgid "Promotions|Learn more"
msgstr "Узнать больше"
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr "Обозначить приоритет обÑуждениÑ"
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 "При большом количеÑтве обÑуждений Ñложно оценить общую картину. Добавив приоритет к вашим обÑуждениÑм, вы можете получить лучшее предÑтавление о затрачиваемых уÑилиÑÑ…, времени, ÑтоимоÑти или значимоÑти каждого из них и, таким образом, лучше ими управлÑÑ‚ÑŒ."
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr "Предлагать пользователÑм загружать ключи SSH"
@@ -16894,7 +17946,7 @@ msgid "Protected Environment"
msgstr ""
msgid "Protected Environments"
-msgstr ""
+msgstr "Защищённые окружениÑ"
msgid "Protected Paths"
msgstr ""
@@ -16903,7 +17955,7 @@ msgid "Protected Tag"
msgstr "Ð—Ð°Ñ‰Ð¸Ñ‰ÐµÐ½Ð½Ð°Ñ Ð¼ÐµÑ‚ÐºÐ°"
msgid "Protected branches"
-msgstr "Защищенные ветви"
+msgstr "Защищённые ветви"
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 ""
@@ -16966,7 +18018,7 @@ msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_coun
msgstr ""
msgid "ProtectedEnvironment|Protecting an environment restricts the users who can execute deployments."
-msgstr "Защищённое окружение ограничивает пользователей, которые могут выполнÑÑ‚ÑŒ развёртываниÑ."
+msgstr "Защищённое окружение ограничивает ÑпиÑок пользователей, которые могут выполнÑÑ‚ÑŒ развёртываниÑ."
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -17013,9 +18065,6 @@ msgstr "Публичный - Группу и включённые в неё пр
msgid "Public - The project can be accessed without any authentication."
msgstr "Публичный - ДоÑтуп к проекту возможен без какой-либо проверки подлинноÑти."
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr "Публичные ключи Ñ€Ð°Ð·Ð²ÐµÑ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ (%{deploy_keys_count})"
@@ -17025,6 +18074,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr "Получить"
@@ -17044,7 +18099,7 @@ msgid "Push Rule updated successfully."
msgstr ""
msgid "Push Rules"
-msgstr ""
+msgstr "Правила отправки"
msgid "Push Rules updated successfully."
msgstr ""
@@ -17127,6 +18182,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr "БыÑтрые дейÑÑ‚Ð²Ð¸Ñ Ð¼Ð¾Ð³ÑƒÑ‚ иÑпользоватьÑÑ Ð² опиÑании обÑуждений и комментариÑÑ…."
@@ -17136,9 +18194,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr "Помощь по Rake задачам"
-
msgid "Raw blob request rate limit per minute"
msgstr "Ограничение количеÑтва запроÑов на бинарные данные в минуту"
@@ -17155,7 +18210,7 @@ msgid "Read more"
msgstr "Подробнее"
msgid "Read more about environments"
-msgstr "Подробнее о окружении"
+msgstr "Подробнее об окружениÑÑ…"
msgid "Read more about project permissions <strong>%{link_to_help}</strong>"
msgstr ""
@@ -17175,9 +18230,6 @@ msgstr "Перемещение в процеÑÑе"
msgid "Receive alerts from manually configured Prometheus servers."
msgstr "Получать Ð¾Ð¿Ð¾Ð²ÐµÑ‰ÐµÐ½Ð¸Ñ Ð¾Ñ‚ наÑтроенных вручную Ñерверов Prometheus."
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr "Получать ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¾ Ñвоей деÑтельноÑти"
@@ -17200,7 +18252,7 @@ msgid "Recipe"
msgstr ""
msgid "Recover hidden stage"
-msgstr ""
+msgstr "ВоÑÑтановить Ñкрытый Ñтап"
msgid "Recovery Codes"
msgstr "Коды воÑÑтановлениÑ"
@@ -17275,6 +18327,21 @@ msgstr "РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð¿Ñ€Ð¸ помощи приложениÑ"
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr "СвÑзанные Ð—Ð°Ð´Ð°Ð½Ð¸Ñ Ð Ð°Ð·Ð²ÐµÑ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ"
@@ -17321,6 +18388,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr "Релизы"
@@ -17342,6 +18421,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr "Запомнить менÑ"
@@ -17382,7 +18464,7 @@ msgid "Remove asset link"
msgstr ""
msgid "Remove assignee"
-msgstr ""
+msgstr "Удалить иÑполнителÑ"
msgid "Remove avatar"
msgstr "Удалить аватар"
@@ -17411,11 +18493,17 @@ msgstr "Удалить из цели"
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
msgid "Remove milestone"
-msgstr ""
+msgstr "Удалить Ñтап"
msgid "Remove node"
msgstr ""
@@ -17439,7 +18527,7 @@ msgid "Remove spent time"
msgstr "Удалить потраченное времÑ"
msgid "Remove stage"
-msgstr ""
+msgstr "Удалить Ñтап"
msgid "Remove time estimate"
msgstr ""
@@ -17448,16 +18536,19 @@ msgid "Removed"
msgstr ""
msgid "Removed %{assignee_text} %{assignee_references}."
-msgstr ""
+msgstr "Удалено %{assignee_text}%{assignee_references}."
msgid "Removed %{epic_ref} from child epics."
msgstr "Из дочерних целей удалена %{epic_ref}"
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
msgid "Removed %{milestone_reference} milestone."
-msgstr ""
+msgstr "Удалён Ñтап %{milestone_reference}."
msgid "Removed %{type} with id %{id}"
msgstr "Удалено %{type} Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€Ð¾Ð¼ %{id}"
@@ -17487,11 +18578,14 @@ msgid "Removed time estimate."
msgstr ""
msgid "Removes %{assignee_text} %{assignee_references}."
-msgstr ""
+msgstr "УдалÑет %{assignee_text}%{assignee_references}."
msgid "Removes %{epic_ref} from child epics."
msgstr "Удалить %{epic_ref} у дочерних целей."
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17517,10 +18611,10 @@ msgid "Removes time estimate."
msgstr ""
msgid "Removing a project places it into a read-only state until %{date}, at which point the project will be permanantly removed. Are you ABSOLUTELY sure?"
-msgstr ""
+msgstr "Удаление проекта Ñделает его доÑтупным только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ð´Ð¾ %{date}, поÑле чего проект будет окончательно удалён. Ð’Ñ‹ ÐБСОЛЮТÐО уверены?"
msgid "Removing a project places it into a read-only state until %{date}, at which point the project will be permanently removed."
-msgstr ""
+msgstr "Удаление проекта Ñделает его доÑтупным только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ð´Ð¾ %{date}, поÑле чего проект будет окончательно удалён."
msgid "Removing license…"
msgstr "Удаление лицензии…"
@@ -17529,7 +18623,7 @@ msgid "Removing the project will delete its repository and all related resources
msgstr "Удаление проекта удалит его репозиторий и вÑе ÑвÑзанные реÑурÑÑ‹, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ð¾Ð±ÑуждениÑ, запроÑÑ‹ на ÑлиÑние и Ñ‚. д."
msgid "Removing this group also removes all child projects, including archived projects, and their resources."
-msgstr ""
+msgstr "Удаление Ñтой группы также приведет к удалению вÑех дочерних проектов, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ð°Ñ€Ñ…Ð¸Ð²Ð½Ñ‹Ðµ, а также их реÑурÑов."
msgid "Rename file"
msgstr ""
@@ -17541,6 +18635,9 @@ msgid "Rename/Move"
msgstr ""
msgid "Reopen"
+msgstr "Открыть заново"
+
+msgid "Reopen %{display_issuable_type}"
msgstr ""
msgid "Reopen epic"
@@ -17573,11 +18670,14 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
msgid "Reply to comment"
-msgstr ""
+msgstr "Ответить на комментарий"
msgid "Reply to this email directly or %{view_it_on_gitlab}."
msgstr ""
@@ -17588,20 +18688,23 @@ msgstr ""
msgid "Repo by URL"
msgstr "Репозиторий по URL"
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
msgstr ""
msgid "Reported %{timeAgo} by %{reportedBy}"
-msgstr ""
+msgstr "Сообщил %{reportedBy} %{timeAgo}"
msgid "Reported Resource Changes: %{addNum} to add, %{changeNum} to change, %{deleteNum} to delete"
-msgstr ""
+msgstr "СпиÑок изменений реÑурÑов: %{addNum} к добавлению, %{changeNum} к изменению, %{deleteNum} к удалению"
msgid "Reporter"
-msgstr ""
+msgstr "Reporter"
msgid "Reporting"
msgstr ""
@@ -17626,7 +18729,7 @@ msgid "Reports|Accessibility scanning results are being parsed"
msgstr ""
msgid "Reports|Actions"
-msgstr ""
+msgstr "ДейÑтвиÑ"
msgid "Reports|An error occured while loading report"
msgstr ""
@@ -17647,16 +18750,16 @@ msgid "Reports|Failure"
msgstr "Отказ"
msgid "Reports|Metrics reports are loading"
-msgstr ""
+msgstr "Отчеты по метрикам загружаютÑÑ"
msgid "Reports|Metrics reports changed on %{numberOfChanges} %{pointsString}"
msgstr ""
msgid "Reports|Metrics reports did not change"
-msgstr ""
+msgstr "Отчеты о метриках не изменилиÑÑŒ"
msgid "Reports|Metrics reports failed loading results"
-msgstr ""
+msgstr "Отчетам о метриках не удалоÑÑŒ загрузить результаты"
msgid "Reports|Severity"
msgstr ""
@@ -17694,11 +18797,14 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
msgid "Repository cleanup"
-msgstr ""
+msgstr "ОчиÑтка репозиториÑ"
msgid "Repository cleanup has started. You will receive an email once the cleanup operation is complete."
msgstr "ОчиÑтка Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸Ñ Ð½Ð°Ñ‡Ð°Ð»Ð°ÑÑŒ. Ð’Ñ‹ получите пиÑьмо поÑле ее завершениÑ."
@@ -17730,6 +18836,9 @@ msgstr ""
msgid "Request Access"
msgstr "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð´Ð¾Ñтупа"
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17745,11 +18854,14 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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 "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 all users in this group to setup Two-factor authentication"
msgstr "Требовать от вÑех пользователей в группе наÑтроить двух-факторную аутентификацию"
@@ -17763,6 +18875,12 @@ msgstr "Требовать пароль Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ‚
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr "Требование"
@@ -17784,11 +18902,8 @@ msgstr "Заголовок Ñ‚Ñ€ÐµÐ±Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ может Ñодержат
msgid "Requirements"
msgstr "ТребованиÑ"
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr "Ð¢Ñ€ÐµÐ±Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»ÑÑŽÑ‚ вам Ñоздавать критерии, чтобы проверÑÑ‚ÑŒ Ñвои продукты по ним."
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
-msgstr "Ð¢Ñ€ÐµÐ±Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¼Ð¾Ð³ÑƒÑ‚ быть оÑнованы на пользователÑÑ…, заинтереÑованных Ñторонах, ПО или на чём угодно, что вы Ñчитаете важным отÑлеживать."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
+msgstr ""
msgid "Requires approval from %{names}."
msgid_plural "Requires %{count} more approvals from %{names}."
@@ -17835,13 +18950,13 @@ msgid "Reset template"
msgstr ""
msgid "Resetting the authorization key for this project will require updating the authorization key in every alert source it is enabled in."
-msgstr ""
+msgstr "Ð¡Ð±Ñ€Ð¾Ñ ÐºÐ»ÑŽÑ‡Ð° авторизации Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ проекта потребует Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ñтого ключа в каждом иÑточнике оповещений, в котором он задейÑтвован."
msgid "Resetting the authorization key will invalidate the previous key. Existing alert configurations will need to be updated with the new key."
-msgstr ""
+msgstr "Ð¡Ð±Ñ€Ð¾Ñ ÐºÐ»ÑŽÑ‡Ð° авторизации Ñделает недейÑтвительным предыдущий ключ. СущеÑтвующие наÑтройки уведомлений необходимо будет обновить Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ нового ключа."
msgid "Resolve"
-msgstr ""
+msgstr "Разрешить"
msgid "Resolve all threads in new issue"
msgstr ""
@@ -17861,6 +18976,9 @@ msgstr "Закрыть диÑкуÑÑию."
msgid "Resolved all discussions."
msgstr "Закрыть вÑе диÑкуÑÑии."
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17873,6 +18991,12 @@ msgstr ""
msgid "Response"
msgstr "Ответ"
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr "Ответ не включает `service_desk_address`"
@@ -17886,7 +19010,7 @@ msgid "Response metrics (HA Proxy)"
msgstr "Метрики откликов (HA Proxy)"
msgid "Response metrics (NGINX Ingress VTS)"
-msgstr "Метрики ответов (NGINX Ingress VTS)"
+msgstr "Метрики откликов (NGINX Ingress VTS)"
msgid "Response metrics (NGINX Ingress)"
msgstr "Метрики откликов (NGINX Ingress)"
@@ -17925,13 +19049,13 @@ msgid "Resume replication"
msgstr "Возобновить репликацию"
msgid "Resync"
-msgstr ""
+msgstr "РеÑинхронизировать"
msgid "Resync all"
-msgstr ""
+msgstr "РеÑинхронизировать вÑе"
msgid "Resync all %{replicableType}"
-msgstr ""
+msgstr "РеÑинхронизировать вÑе %{replicableType}"
msgid "Retry"
msgstr "Повторить"
@@ -18021,6 +19145,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -18073,7 +19200,7 @@ msgid "Runners activated for this project"
msgstr "Обработчики заданий активированы Ð´Ð»Ñ Ñтого проекта"
msgid "Runners are processes that pick up and execute jobs for GitLab. Here you can register and see your Runners for this project."
-msgstr ""
+msgstr "Runner'Ñ‹ — Ñто процеÑÑÑ‹, которые подбирают и выполнÑÑŽÑ‚ Ð·Ð°Ð´Ð°Ð½Ð¸Ñ Ð´Ð»Ñ GitLab. ЗдеÑÑŒ вы можете зарегиÑтрировать и увидеть Ñвои Runner'Ñ‹ Ð´Ð»Ñ Ñтого проекта."
msgid "Runners can be placed on separate users, servers, and even on your local machine."
msgstr "Обработчики заданий могут запуÑкатьÑÑ Ñƒ отдельных пользователей, Ñерверах и даже на вашей локальной машине."
@@ -18084,9 +19211,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -18097,7 +19221,7 @@ msgid "Running"
msgstr "ВыполнÑетÑÑ"
msgid "Running…"
-msgstr ""
+msgstr "ВыполнÑетÑÑ…"
msgid "Runs a number of housekeeping tasks within the current repository, such as compressing file revisions and removing unreachable objects."
msgstr "ЗапуÑкает Ñ€Ñд Ñлужебных задач в текущем репозитории, таких как Ñжатие верÑий файлов и удаление недоÑтупных объектов."
@@ -18123,9 +19247,6 @@ msgstr "Ключ SSH"
msgid "SSH Keys"
msgstr "Ключи SSH"
-msgid "SSH Keys Help"
-msgstr "Справка по ключам SSH"
-
msgid "SSH host key fingerprints"
msgstr "Отпечатки ключа SSH хоÑта"
@@ -18142,7 +19263,7 @@ msgid "SSH public key"
msgstr "Открытый ключ SSH"
msgid "SSL Verification:"
-msgstr ""
+msgstr "Ð’ÐµÑ€Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð¿Ð¾ SSL:"
msgid "Saturday"
msgstr "Суббота"
@@ -18214,7 +19335,7 @@ msgid "Scheduling Pipelines"
msgstr "Планирование Сборочных Линий"
msgid "Scope"
-msgstr ""
+msgstr "ОблаÑÑ‚ÑŒ"
msgid "Scope not supported with disabled 'users_search' feature!"
msgstr ""
@@ -18255,9 +19376,15 @@ msgstr "ПоиÑк"
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18315,6 +19442,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr "ПоиÑк пользователей"
@@ -18345,11 +19475,11 @@ msgstr "ЗапроÑÑ‹ на ÑлиÑниÑ, на которые Ñ Ð½Ð°Ð·Ð½Ð°Ñ‡Ð
msgid "SearchAutocomplete|in all GitLab"
msgstr "во вÑех GitLab"
-msgid "SearchAutocomplete|in this group"
-msgstr "в Ñтой группе"
+msgid "SearchAutocomplete|in group %{groupName}"
+msgstr ""
-msgid "SearchAutocomplete|in this project"
-msgstr "в Ñтом проекте"
+msgid "SearchAutocomplete|in project %{projectName}"
+msgstr ""
msgid "SearchCodeResults|in"
msgstr "в"
@@ -18388,10 +19518,10 @@ msgstr[3] ""
msgid "SearchResults|commit"
msgid_plural "SearchResults|commits"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "коммит"
+msgstr[1] "коммита"
+msgstr[2] "коммитов"
+msgstr[3] "коммитов"
msgid "SearchResults|issue"
msgid_plural "SearchResults|issues"
@@ -18409,10 +19539,10 @@ msgstr[3] ""
msgid "SearchResults|milestone"
msgid_plural "SearchResults|milestones"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "Ñтап"
+msgstr[1] "Ñтапа"
+msgstr[2] "Ñтапов"
+msgstr[3] "Ñтапов"
msgid "SearchResults|project"
msgid_plural "SearchResults|projects"
@@ -18457,9 +19587,15 @@ msgstr "МеÑта в наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð¸ÑпользуютÑÑ"
msgid "Seats in license"
msgstr "МеÑÑ‚ в лицензии"
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr "БезопаÑноÑÑ‚ÑŒ"
@@ -18472,9 +19608,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr "Панель безопаÑноÑти"
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr "Панель безопаÑноÑти"
@@ -18482,26 +19615,26 @@ msgid "Security report is out of date. Please update your branch with the latest
msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
-msgstr ""
+msgstr "Отчет о безопаÑноÑти уÑтарел. ЗапуÑтите %{newPipelineLinkStart}новую Ñборочную линию%{newPipelineLinkEnd} в целевой ветке (%{targetBranchName})"
-msgid "SecurityConfiguration|Configured"
-msgstr "ÐаÑтроено"
-
-msgid "SecurityConfiguration|Feature"
-msgstr "ФункциÑ"
+msgid "SecurityConfiguration|Enabled"
+msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
-msgstr "Пока не наÑтроено"
+msgid "SecurityConfiguration|Not yet enabled"
+msgstr ""
-msgid "SecurityConfiguration|Secure features"
-msgstr "Функции безопаÑноÑти"
+msgid "SecurityConfiguration|Security Control"
+msgstr ""
msgid "SecurityConfiguration|Status"
msgstr "СтатуÑ"
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18542,7 +19675,7 @@ msgid "SecurityReports|Dismissed '%{vulnerabilityName}'. Turn off the hide dismi
msgstr ""
msgid "SecurityReports|Each vulnerability now has a unique page that can be directly linked to, shared, referenced, and tracked as the single source of truth. Vulnerability occurrences also persist across scanner runs, which improves tracking and visibility and reduces duplicates between scans."
-msgstr ""
+msgstr "Теперь ÐºÐ°Ð¶Ð´Ð°Ñ ÑƒÑзвимоÑÑ‚ÑŒ получила уникальную Ñтраницу, на которую можно ÑÑылатьÑÑ Ð½Ð°Ð¿Ñ€Ñмую, делитьÑÑ ÐµÑŽ, и отÑлеживать её как единый иÑточник иÑтины. Случаи Ð²Ð¾Ð·Ð½Ð¸ÐºÐ½Ð¾Ð²ÐµÐ½Ð¸Ñ ÑƒÑзвимоÑти также ÑохранÑÑŽÑ‚ÑÑ Ð¼ÐµÐ¶Ð´Ñƒ запуÑками Ñканера, что делает их отÑлеживание более ÑÑным, а также уменьшает количеÑтво дублирующих запиÑей от повторных Ñканирований."
msgid "SecurityReports|Edit dashboard"
msgstr ""
@@ -18593,7 +19726,7 @@ msgid "SecurityReports|No vulnerabilities found for this group"
msgstr ""
msgid "SecurityReports|No vulnerabilities found for this pipeline"
-msgstr ""
+msgstr "Ð”Ð»Ñ Ñтой Ñборочной линии не найдено никаких уÑзвимоÑтей"
msgid "SecurityReports|No vulnerabilities found for this project"
msgstr ""
@@ -18637,6 +19770,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18710,7 +19846,7 @@ msgid "See the affected projects in the GitLab admin panel"
msgstr "ПоÑмотреть затрагиваемые проекты в панели админиÑтратора GitLab"
msgid "See what's new at GitLab"
-msgstr ""
+msgstr "ПоÑмотрите, что нового в Gitlab"
msgid "Select"
msgstr ""
@@ -18718,6 +19854,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr "Выбрать формат архива"
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18740,7 +19879,7 @@ msgid "Select a namespace to fork the project"
msgstr ""
msgid "Select a new namespace"
-msgstr ""
+msgstr "Выберите новое проÑтранÑтво имен"
msgid "Select a project"
msgstr ""
@@ -18769,12 +19908,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr "Выбрать ÑущеÑтвующий клаÑтер Kubernetes или Ñоздать новый"
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr "Выбрать ветку/тег"
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr "Выберите группу или проект"
@@ -18791,7 +19936,7 @@ msgid "Select merge moment"
msgstr ""
msgid "Select milestone"
-msgstr ""
+msgstr "Выбрать Ñтап"
msgid "Select private project"
msgstr ""
@@ -18820,9 +19965,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr "Выбор целевой ветки"
@@ -18895,6 +20049,12 @@ msgstr "Отправить пиÑьмо Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸ÐµÐ¼"
msgid "Send email"
msgstr "Отправить Ñлектронное пиÑьмо"
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18941,7 +20101,7 @@ msgid "ServerlessDetails|Install Prometheus"
msgstr "УÑтановить Prometheus"
msgid "ServerlessDetails|Invocation metrics loading or not available at this time."
-msgstr "Метрики вызовов загружаютÑÑ Ð¸Ð»Ð¸ недоÑтупны в наÑтоÑщее времÑ."
+msgstr "Метрики вызовов в наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð·Ð°Ð³Ñ€ÑƒÐ¶Ð°ÑŽÑ‚ÑÑ Ð¸Ð»Ð¸ недоÑтупны."
msgid "ServerlessDetails|Invocations"
msgstr "Вызовы"
@@ -19013,7 +20173,7 @@ msgid "Service"
msgstr ""
msgid "Service Desk"
-msgstr ""
+msgstr "Служба поддержки"
msgid "Service Desk is enabled but not yet active"
msgstr ""
@@ -19037,7 +20197,7 @@ msgid "Set %{epic_ref} as the parent epic."
msgstr "УÑтановить %{epic_ref} в качеÑтве родительÑкой цели."
msgid "Set a default template for issue descriptions."
-msgstr ""
+msgstr "УÑтановите шаблон по умолчанию Ð´Ð»Ñ Ð¾Ð¿Ð¸Ñаний обÑуждений."
msgid "Set a number of approvals required, the approvers and other approval settings."
msgstr "Задайте количеÑтво необходимых ÑоглаÑований, ÑоглаÑующих и другие параметры."
@@ -19060,6 +20220,9 @@ msgstr "УÑтановить дату завершениÑ"
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr "УÑтановить макÑимальное Ð²Ñ€ÐµÐ¼Ñ ÑеанÑа Ð´Ð»Ñ Ð²ÐµÐ±-терминала."
@@ -19096,6 +20259,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -19115,7 +20281,7 @@ msgid "Set up CI/CD"
msgstr "ÐаÑтройка CI/CD"
msgid "Set up Jira Integration"
-msgstr ""
+msgstr "ÐаÑтроить интеграцию Ñ Jira"
msgid "Set up a %{type} Runner automatically"
msgstr ""
@@ -19180,6 +20346,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr "УÑтанавливает дату Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ %{due_date}."
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr "УÑтанавить Ñтап %{milestone_reference}."
@@ -19198,7 +20367,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19237,13 +20406,13 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr "ЕÑли вы когда-нибудь потерÑете Ñвой телефон или доÑтуп к вашему одноразовому паролю, каждый из Ñтих кодов воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ‚ быть иÑпользован один раз, чтобы воÑÑтановить доÑтуп к вашей учетной запиÑи. ПожалуйÑта, храните их в надежном меÑте, или вы %{b_start}можете%{b_end} потерÑÑ‚ÑŒ доÑтуп к вашему аккаунту."
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
+msgstr "Показывать вÑех учаÑтников"
+
+msgid "Show all requirements."
msgstr ""
msgid "Show archived projects"
@@ -19262,7 +20431,7 @@ msgid "Show comments only"
msgstr "Показать только комментарии"
msgid "Show commit description"
-msgstr ""
+msgstr "Показать опиÑание коммита"
msgid "Show complete raw log"
msgstr ""
@@ -19270,17 +20439,26 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr "Показать поÑледнюю верÑию"
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
-msgid "Show only direct members"
+msgid "Show me more advanced stuff"
msgstr ""
+msgid "Show only direct members"
+msgstr "Показывать только непоÑредÑтвенных учаÑтников"
+
msgid "Show only inherited members"
-msgstr ""
+msgstr "Показывать только коÑвенных учаÑтников"
msgid "Show parent pages"
msgstr "Показать родительÑкие Ñтраницы"
@@ -19298,6 +20476,16 @@ msgstr[1] "Показано %d ÑобытиÑ"
msgstr[2] "Показано %d Ñобытий"
msgstr[3] "Показано %d Ñобытий"
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19413,7 +20601,7 @@ msgid "Single or combined queries"
msgstr "Одиночные или комбинированные запроÑÑ‹"
msgid "Size"
-msgstr ""
+msgstr "Размер"
msgid "Size and domain settings for static websites"
msgstr "ÐаÑтройки размера и доменных имён Ð´Ð»Ñ ÑтатичеÑких веб-Ñайтов"
@@ -19422,7 +20610,7 @@ msgid "Size limit per repository (MB)"
msgstr "Лимит размера на репозиторий (Мбайт)"
msgid "Size settings for static websites"
-msgstr ""
+msgstr "ÐаÑтройки размера Ð´Ð»Ñ ÑтатичеÑких веб-Ñайтов"
msgid "Skip outdated deployment jobs"
msgstr "ПропуÑтить уÑтаревшие Ð·Ð°Ð´Ð°Ð½Ð¸Ñ Ñ€Ð°Ð·Ð²Ñ‘Ñ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ"
@@ -19446,7 +20634,7 @@ msgid "SlackIntegration|%{webhooks_link_start}Add an incoming webhook%{webhooks_
msgstr ""
msgid "SlackIntegration|<strong>Note:</strong> Usernames and private channels are not supported."
-msgstr ""
+msgstr "<strong>Примечание:</strong> Имена пользователей и чаÑтные каналы не поддерживаютÑÑ."
msgid "SlackIntegration|Paste the <strong>Webhook URL</strong> into the field below."
msgstr "Ð’Ñтавьте <strong>URL веб-обработчика</strong> в поле ниже."
@@ -19473,7 +20661,7 @@ msgid "SlackService|This service allows users to perform common operations on th
msgstr ""
msgid "Slower but makes sure the project workspace is pristine as it clones the repository from scratch for every job"
-msgstr ""
+msgstr "Медленнее, но гарантирует, что Ñ€Ð°Ð±Ð¾Ñ‡Ð°Ñ Ð¾Ð±Ð»Ð°ÑÑ‚ÑŒ проекта оÑтаётÑÑ Ð½ÐµÑ‚Ñ€Ð¾Ð½ÑƒÑ‚Ð¾Ð¹, Ñ‚.к. репозиторий клонируетÑÑ Ñ Ð½ÑƒÐ»Ñ Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ заданиÑ"
msgid "Smartcard"
msgstr ""
@@ -19484,6 +20672,9 @@ msgstr ""
msgid "Snippets"
msgstr "Сниппеты"
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19520,9 +20711,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19619,6 +20816,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr "Что-то пошло не так при получении ÑвÑзанных запроÑов на ÑлиÑние."
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr "Что-то пошло не так при извлечении ÑпиÑка требований."
@@ -19658,6 +20858,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr "Что-то пошло не так при обновлении требованиÑ."
@@ -19706,6 +20909,12 @@ msgstr "Сортировка"
msgid "Sort direction"
msgstr "ПорÑдок Ñортировки"
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr "Уровень доÑтупа, по возраÑтанию"
@@ -19773,7 +20982,7 @@ msgid "SortOptions|Most popular"
msgstr "Ðаиболее популÑрный"
msgid "SortOptions|Most stars"
-msgstr "по рейтингу"
+msgstr "По рейтингу"
msgid "SortOptions|Name"
msgstr "По алфавиту"
@@ -19823,6 +21032,9 @@ msgstr "Сначала недавно избранные"
msgid "SortOptions|Size"
msgstr "Размер"
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr "Ðаправление Ñортировки"
@@ -19941,16 +21153,16 @@ msgid "Stack trace"
msgstr ""
msgid "Stage"
-msgstr ""
+msgstr "Этап"
msgid "Stage & Commit"
msgstr ""
msgid "Stage data updated"
-msgstr ""
+msgstr "Данные Ñтапа обновлены"
msgid "Stage removed"
-msgstr ""
+msgstr "Этап удалён"
msgid "Standard"
msgstr ""
@@ -19988,7 +21200,7 @@ msgstr ""
msgid "Stars"
msgstr "В избранное"
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -20019,7 +21231,7 @@ msgid "Start by choosing a group to start exploring the merge requests in that g
msgstr "Ðачните Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° группы, чтобы проÑмотреть ÑпиÑок отноÑÑщихÑÑ Ðº ней запроÑов на ÑлиÑние, который вы затем Ñможете отфильтровать по проектам, меткам, Ñтапам и авторам."
msgid "Start cleanup"
-msgstr ""
+msgstr "Ðачать очиÑтку"
msgid "Start date"
msgstr "Дата начала"
@@ -20063,6 +21275,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -20085,7 +21300,7 @@ msgid "StaticSiteEditor|Branch could not be created."
msgstr ""
msgid "StaticSiteEditor|Could not commit the content changes."
-msgstr ""
+msgstr "Ðевозможно зафикÑировать Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÐºÐ¾Ð½Ñ‚ÐµÐ½Ñ‚Ð°."
msgid "StaticSiteEditor|Could not create merge request."
msgstr ""
@@ -20118,7 +21333,7 @@ msgid "StaticSiteEditor|View merge request"
msgstr ""
msgid "StaticSiteEditor|You added a commit:"
-msgstr ""
+msgstr "Вы добавили коммит:"
msgid "StaticSiteEditor|You created a merge request:"
msgstr ""
@@ -20178,7 +21393,7 @@ msgid "StatusPage|Status page frontend documentation"
msgstr ""
msgid "StatusPage|To publish incidents to an external status page, GitLab will store a JSON file in your Amazon S3 account in a location accessible to your external status page service. Make sure to also set up %{docsLink}"
-msgstr ""
+msgstr "Чтобы публиковать инциденты на внешней Ñтранице ÑоÑтоÑниÑ, GitLab будет хранить JSON-файл в вашем аккаунте Amazon S3, раÑположенный так, чтобы быть доÑтупным Ð´Ð»Ñ Ñлужбы, обеÑпечивающей работу Ñтраницы ÑоÑтоÑниÑ. УбедитеÑÑŒ также, что вы наÑтроили %{docsLink}"
msgid "StatusPage|configuration documentation"
msgstr ""
@@ -20189,6 +21404,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr "Будьте в курÑе производительноÑти и работоÑпоÑобноÑти вашего Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ наÑтройки Prometheus Ð´Ð»Ñ Ð¼Ð¾Ð½Ð¸Ñ‚Ð¾Ñ€Ð¸Ð½Ð³Ð° ваших развёртываний."
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -20196,13 +21414,13 @@ msgid "Stop impersonation"
msgstr ""
msgid "Stop this environment"
-msgstr "ОÑтановить Ñту Ñреду"
+msgstr "ОÑтановить Ñто окружение"
msgid "Stopped"
msgstr "ОÑтановлено"
msgid "Stopping..."
-msgstr ""
+msgstr "ОÑтанавливаетÑÑ..."
msgid "Storage"
msgstr "Хранилище"
@@ -20216,6 +21434,9 @@ msgstr "Хранилище:"
msgid "StorageSize|Unknown"
msgstr "ÐеизвеÑтный"
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20243,6 +21464,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20423,9 +21647,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr "Предложенные изменениÑ"
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr "Ярко-зеленый"
@@ -20510,6 +21740,9 @@ msgstr "Поддержка пользовательÑких Ñертификат
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr "Переключить ветка/тег"
@@ -20523,7 +21756,7 @@ msgid "Sync information"
msgstr ""
msgid "Synced"
-msgstr ""
+msgstr "Синхронизировано"
msgid "Synchronization disabled"
msgstr ""
@@ -20537,9 +21770,6 @@ msgstr "СиÑтема"
msgid "System Hooks"
msgstr "СиÑтемные Обработчики"
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr "Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ ÑиÑтеме"
@@ -20553,10 +21783,10 @@ msgid "System hook was successfully updated."
msgstr ""
msgid "System metrics (Custom)"
-msgstr ""
+msgstr "СиÑтемные метрики (наÑтраиваемые)"
msgid "System metrics (Kubernetes)"
-msgstr ""
+msgstr "СиÑтемные метрики (Kubernetes)"
msgid "Table of Contents"
msgstr ""
@@ -20634,7 +21864,7 @@ msgid "TagsPage|Optionally, add a message to the tag. Leaving this blank creates
msgstr "При желании, добавьте Ñообщение к метке. ЕÑли оÑтавить его пуÑтым, будет Ñоздана %{link_start}легковеÑÐ½Ð°Ñ Ð¼ÐµÑ‚ÐºÐ°.%{link_end}"
msgid "TagsPage|Optionally, create a public Release of your project, based on this tag. Release notes are displayed on the %{releases_page_link_start}Releases%{link_end} page. %{docs_link_start}More information%{link_end}"
-msgstr ""
+msgstr "По желанию Ñоздайте публичный Релиз вашего проекта на оÑнове Ñтого тега. ÐŸÑ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ðº релизу отображаютÑÑ Ð½Ð° Ñтранице %{releases_page_link_start}Релизов%{link_end}. %{docs_link_start}Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ%{link_end}"
msgid "TagsPage|Release notes"
msgstr "Заметки к релизу"
@@ -20658,7 +21888,7 @@ msgid "TagsPage|Use git tag command to add a new one:"
msgstr "ИÑпользуйте команду git tag, чтобы добавить новый тег:"
msgid "TagsPage|Write your release notes or drag files here…"
-msgstr ""
+msgstr "Ðапишите заметки к релизу или перетащите Ñюда файлы…"
msgid "TagsPage|protected"
msgstr "защищенный"
@@ -20691,10 +21921,10 @@ msgid "Template"
msgstr "Шаблон"
msgid "Template to append to all Service Desk issues"
-msgstr ""
+msgstr "Шаблон Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ ÐºÐ¾ вÑем обÑуждениÑм Ñлужбы поддержки"
msgid "Template was successfully saved."
-msgstr ""
+msgstr "Шаблон был уÑпешно Ñохранен."
msgid "Templates"
msgstr "Шаблоны"
@@ -20709,16 +21939,16 @@ msgid "Terminal sync service is running"
msgstr ""
msgid "Terms of Service Agreement and Privacy Policy"
-msgstr ""
+msgstr "СоглаÑие Ñ Ð£ÑловиÑми иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸ Политика конфиденциальноÑти"
msgid "Terms of Service and Privacy Policy"
-msgstr ""
+msgstr "УÑÐ»Ð¾Ð²Ð¸Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸ Политика конфиденциальноÑти"
msgid "Test"
-msgstr ""
+msgstr "ТеÑÑ‚"
msgid "Test coverage parsing"
-msgstr ""
+msgstr "Обработка Ð¿Ð¾ÐºÑ€Ñ‹Ñ‚Ð¸Ñ Ñ‚ÐµÑтами"
msgid "Test coverage: %d hit"
msgid_plural "Test coverage: %d hits"
@@ -20728,7 +21958,7 @@ msgstr[2] ""
msgstr[3] ""
msgid "Test failed."
-msgstr ""
+msgstr "ТеÑÑ‚ не пройден."
msgid "Test settings and save changes"
msgstr "Проверьте наÑтройки и Ñохраните изменениÑ"
@@ -20758,7 +21988,7 @@ msgid "TestHooks|Ensure the wiki is enabled and has pages."
msgstr "УбедитеÑÑŒ, что wiki включена и имеет Ñтраницы."
msgid "TestReports|%{count} errors"
-msgstr ""
+msgstr "%{count} ошибок"
msgid "TestReports|%{count} failures"
msgstr "%{count} Ñбоев"
@@ -20767,7 +21997,7 @@ msgid "TestReports|%{count} jobs"
msgstr "%{count} заданий"
msgid "TestReports|%{rate}%{sign} success rate"
-msgstr ""
+msgstr "%{rate}%{sign} показатель уÑпешноÑти"
msgid "TestReports|Test suites"
msgstr "Ðаборы теÑтов"
@@ -20788,22 +22018,25 @@ msgid "TestReports|There was an error fetching the test reports."
msgstr "При извлечении отчетов о теÑтировании произошла ошибка."
msgid "Tests"
-msgstr ""
+msgstr "ТеÑÑ‚Ñ‹"
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
+msgstr "СпаÑибо, что подпиÑалиÑÑŒ на беÑплатный пробный период. Ð’Ñкоре мы отправим дополнительные инÑтрукции на ваш почтовый Ñщик."
+
+msgid "Thank you for your feedback!"
msgstr ""
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr "СпаÑибо за ваш отчет. ÐдминиÑтратор GitLab Ñкоро раÑÑмотрит его."
msgid "Thanks for your purchase!"
-msgstr ""
+msgstr "СпаÑибо за покупку!"
msgid "Thanks! Don't show me this again"
-msgstr ""
+msgstr "СпаÑибо! Больше не показывать"
msgid "That's it, well done!%{celebrate}"
-msgstr ""
+msgstr "Вот и вÑÑ‘, Ð¾Ñ‚Ð»Ð¸Ñ‡Ð½Ð°Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ð°!%{celebrate}"
msgid "The \"%{group_path}\" group allows you to sign in with your Single Sign-On Account"
msgstr "Группа \"%{group_path}\" позволÑет вам войти в ÑиÑтему Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ учетной запиÑи единого входа"
@@ -20828,7 +22061,7 @@ msgid "The Advanced Global Search in GitLab is a powerful search service that sa
msgstr "РаÑширенный глобальный поиÑк в GitLab - Ñто Ñерьезный инÑтрумент который ÑохранÑет ваше времÑ. ВмеÑто ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð´ÑƒÐ±Ð»Ð¸Ñ€ÑƒÑŽÑ‰ÐµÐ³Ð¾ кода и траты времени, вы можете иÑкать код внутри других команд, который поможет вам в вашем проекте."
msgid "The CSV export will be created in the background. Once finished, it will be sent to <strong>%{email}</strong> in an attachment."
-msgstr ""
+msgstr "ЭкÑпорт в CSV будет произведён в фоновом режиме. По завершении результат будет отправлен на <strong>%{email}</strong> во вложении."
msgid "The Git LFS objects will <strong>not</strong> be synced."
msgstr ""
@@ -20837,19 +22070,19 @@ msgid "The Issue Tracker is the place to add things that need to be improved or
msgstr "Трекер обÑуждений - Ñто меÑто, где можно добавить вещи, которые необходимо улучшить или решить в проекте"
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 ""
+msgstr "Трекер обÑуждений - Ñто меÑто, где можно обÑудить то, что необходимо улучшить или иÑправить в проекте. Можете зарегиÑтрироватьÑÑ Ð¸Ð»Ð¸ войти в ÑиÑтему, поÑле чего Ñоздавать обÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñтого проекта."
msgid "The Prometheus server responded with \"bad request\". Please check your queries are correct and are supported in your Prometheus version. %{documentationLink}"
-msgstr ""
+msgstr "Сервер Prometheus ответил Ñ Ñ€ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ð¾Ð¼ \"bad request\". ПожалуйÑта, убедитеÑÑŒ, что запроÑÑ‹ верны и поддерживаютÑÑ Ð² вашей верÑии Prometheus. %{documentationLink}"
msgid "The URL defined on the primary node that secondary nodes should use to contact it. Defaults to URL"
msgstr ""
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 ""
+msgstr "URL, иÑпользуемый Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº Elasticsearch. ИÑпользуйте ÑпиÑок разделÑемых запÑтыми адреÑов Ð´Ð»Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ¸ клаÑтеризации (напр., \"http://localhost:9200, http://localhost:9201\")."
msgid "The X509 Certificate to use when mutual TLS is required to communicate with the external authorization service. If left blank, the server certificate is still validated when accessing over HTTPS."
-msgstr ""
+msgstr "Сертификат X509, иÑпользуемый в том Ñлучае, когда Ð´Ð»Ñ ÑвÑзи Ñ Ð²Ð½ÐµÑˆÐ½ÐµÐ¹ Ñлужбой авторизации требуетÑÑ Ð²Ð·Ð°Ð¸Ð¼Ð½Ð°Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ° подлинноÑти TLS. ЕÑли оÑтавить пуÑтым, Ñертификат Ñервера вÑе еще будет проверÑÑ‚ÑŒÑÑ Ð¿Ñ€Ð¸ доÑтупе через HTTPS."
msgid "The amount of seconds after which a request to get a secondary node status will time out."
msgstr "КоличеÑтво Ñекунд, поÑле которых Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° получение ÑтатуÑа вторичного узла будет отключен."
@@ -20876,10 +22109,7 @@ msgid "The collection of events added to the data gathered for that stage."
msgstr "ÐšÐ¾Ð»Ð»ÐµÐºÑ†Ð¸Ñ Ñобытий добавленных в данные Ñобранные Ð´Ð»Ñ Ñтого Ñтапа."
msgid "The commit does not exist"
-msgstr ""
-
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
+msgstr "Этот коммит не ÑущеÑтвует"
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr "Соединение будет отключено через %{timeout}. Ð”Ð»Ñ Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸ÐµÐ², требующих больше времени, иÑпользуйте комбинацию clone/push."
@@ -20894,13 +22124,13 @@ msgid "The current issue"
msgstr ""
msgid "The data source is connected, but there is no data to display. %{documentationLink}"
-msgstr ""
+msgstr "ИÑточник данных подключен, но нет данных Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ. %{documentationLink}"
msgid "The default CI configuration path for new projects."
msgstr ""
msgid "The dependency list details information about the components used within your project."
-msgstr ""
+msgstr "СпиÑок завиÑимоÑтей Ñодержит подробную информацию о компонентах, которые иÑпользуютÑÑ Ð² Вашем проекте."
msgid "The deployment of this job to %{environmentLink} did not succeed."
msgstr "Задание Ñ€Ð°Ð·Ð²Ñ‘Ñ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð½Ð° %{environmentLink} не удалоÑÑŒ."
@@ -20912,22 +22142,28 @@ msgid "The directory has been successfully created."
msgstr "Каталог уÑпешно Ñоздан."
msgid "The domain you entered is misformatted."
-msgstr ""
+msgstr "Введённый вами домен имеет неверный формат."
msgid "The domain you entered is not allowed."
+msgstr "Введённый вами домен запрещён."
+
+msgid "The download link will expire in 24 hours."
msgstr ""
msgid "The entered user map is not a valid JSON user map."
msgstr ""
-msgid "The file has been successfully created."
+msgid "The errors we encountered were:"
msgstr ""
+msgid "The file has been successfully created."
+msgstr "Файл уÑпешно Ñоздан."
+
msgid "The file has been successfully deleted."
msgstr "Файл был уÑпешно удален."
msgid "The file name should have a .yml extension"
-msgstr ""
+msgstr "Файл должен иметь раÑширение .yml"
msgid "The following items will NOT be exported:"
msgstr "Следующие Ñлементы ÐЕ будут ÑкÑпортированы:"
@@ -20937,10 +22173,10 @@ msgstr "Следующие предметы будут ÑкÑпортироваÐ
msgid "The following personal access token: %{token_names} was revoked, because a new policy to expire personal access tokens were set."
msgid_plural "The following personal access tokens: %{token_names} were revoked, because a new policy to expire personal access tokens were set."
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "Следующий перÑональный токен доÑтупа: %{token_names} аннулирован, поÑкольку была задана Ð½Ð¾Ð²Ð°Ñ Ð¿Ð¾Ð»Ð¸Ñ‚Ð¸ÐºÐ° в отношении Ñрока дейÑÑ‚Ð²Ð¸Ñ Ð¿ÐµÑ€Ñональных токенов доÑтупа."
+msgstr[1] "Следующие перÑональные токены доÑтупа: %{token_names} аннулированы, поÑкольку была задана Ð½Ð¾Ð²Ð°Ñ Ð¿Ð¾Ð»Ð¸Ñ‚Ð¸ÐºÐ° в отношении Ñрока дейÑÑ‚Ð²Ð¸Ñ Ð¿ÐµÑ€Ñональных токенов доÑтупа."
+msgstr[2] "Следующие перÑональные токены доÑтупа: %{token_names} аннулированы, поÑкольку была задана Ð½Ð¾Ð²Ð°Ñ Ð¿Ð¾Ð»Ð¸Ñ‚Ð¸ÐºÐ° в отношении Ñрока дейÑÑ‚Ð²Ð¸Ñ Ð¿ÐµÑ€Ñональных токенов доÑтупа."
+msgstr[3] "Следующие перÑональные токены доÑтупа: %{token_names} аннулированы, поÑкольку была задана Ð½Ð¾Ð²Ð°Ñ Ð¿Ð¾Ð»Ð¸Ñ‚Ð¸ÐºÐ° в отношении Ñрока дейÑÑ‚Ð²Ð¸Ñ Ð¿ÐµÑ€Ñональных токенов доÑтупа."
msgid "The fork relationship has been removed."
msgstr "СвÑзь Ñ Ð¾Ñ‚Ð²ÐµÑ‚Ð²Ð»ÐµÐ½Ð¸ÐµÐ¼ удалена."
@@ -20958,6 +22194,9 @@ msgid "The group and its projects can only be viewed by members."
msgstr "Группу и ее проекты могут проÑматривать только учаÑтники."
msgid "The group can be fully restored"
+msgstr "Эта группа может быть полноÑтью воÑÑтановлена"
+
+msgid "The group export can be downloaded from:"
msgstr ""
msgid "The group has already been shared with this group"
@@ -20967,7 +22206,7 @@ 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 removal' state"
-msgstr ""
+msgstr "Эта группа будет помещена в ÑоÑтоÑние 'Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ'"
msgid "The import will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr "Импорт будет отключен поÑле %{timeout}. Ð”Ð»Ñ Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸ÐµÐ², которые импортируютÑÑ Ð·Ð° большее времÑ, иÑпользуйте комбинацию команд clone/push."
@@ -20985,10 +22224,10 @@ msgid "The invitation was successfully resent."
msgstr "Приглашение было уÑпешно отправлено."
msgid "The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage."
-msgstr "Ð¡Ñ‚Ð°Ð´Ð¸Ñ Ð¾Ð±ÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð¿Ð¾ÐºÐ°Ð·Ñ‹Ð²Ð°ÐµÑ‚ времÑ, которое потребуетÑÑ Ñ Ð¼Ð¾Ð¼ÐµÐ½Ñ‚Ð° ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¾Ð±ÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð´Ð¾ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¾Ð±Ñуждению вехи, или Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±ÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð½Ð° вашу доÑку задач. Ðачните Ñоздавать обÑуждениÑ, чтобы увидеть ÑÐ²ÐµÐ´ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñтой Ñтадии."
+msgstr "Ð¡Ñ‚Ð°Ð´Ð¸Ñ Ð¾Ð±ÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð¿Ð¾ÐºÐ°Ð·Ñ‹Ð²Ð°ÐµÑ‚ времÑ, которое прошло Ñ Ð¼Ð¾Ð¼ÐµÐ½Ñ‚Ð° ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¾Ð±ÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð´Ð¾ Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¾Ð±ÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð² какой-либо из Ñтапов или Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±ÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð½Ð° ДоÑку обÑуждений. Ðачните Ñоздавать обÑуждениÑ, чтобы увидеть ÑÐ²ÐµÐ´ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñтой Ñтадии."
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
-msgstr ""
+msgstr "Лицензионный ключ недейÑтвителен. УдоÑтоверьтеÑÑŒ, что он Ñовпадает Ñ Ñ‚ÐµÐ¼, что вы получили от GitLab Inc."
msgid "The license was removed. GitLab has fallen back on the previous license."
msgstr "Ð›Ð¸Ñ†ÐµÐ½Ð·Ð¸Ñ Ð±Ñ‹Ð»Ð° удалена. GitLab вернулÑÑ Ð½Ð°Ð·Ð°Ð´ на предыдущую лицензию."
@@ -21021,22 +22260,22 @@ msgid "The merge request can now be merged."
msgstr ""
msgid "The name \"%{name}\" is already taken in this directory."
-msgstr ""
+msgstr "Ð˜Ð¼Ñ \"%{name}\" уже занÑто в Ñтом каталоге."
msgid "The number of changes to be fetched from GitLab when cloning a repository. This can speed up Pipelines execution. Keep empty or set to 0 to disable shallow clone by default and make GitLab CI fetch all branches and tags each time."
-msgstr ""
+msgstr "КоличеÑтво изменений, которые необходимо извлечь из GitLab при клонировании репозиториÑ. Это может уÑкорить выполнение конвейеров. ОÑтавьте пуÑтым или уÑтановите значение на 0, чтобы отключить поверхноÑтное клонирование по умолчанию, и заÑтавить GitLab CI клонировать вÑе ветки и теги каждый раз."
msgid "The number of times an upload record could not find its file"
-msgstr ""
+msgstr "Сколько раз Ð·Ð°Ð³Ñ€ÑƒÐ¶Ð°ÐµÐ¼Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ не могла найти Ñвой файл"
msgid "The one place for your designs"
-msgstr ""
+msgstr "Единое меÑто Ð´Ð»Ñ Ð²Ð°ÑˆÐ¸Ñ… дизайнов"
msgid "The passphrase required to decrypt the private key. This is optional and the value is encrypted at rest."
-msgstr ""
+msgstr "Пароль, необходимый Ð´Ð»Ñ Ñ€Ð°Ñшифровки закрытого ключа. Он не ÑвлÑетÑÑ Ð½ÐµÐ¾Ð±Ñзательным, а значение будет зашифровано в ÑоÑтоÑнии покоÑ."
msgid "The path to the CI configuration file. Defaults to <code>.gitlab-ci.yml</code>"
-msgstr ""
+msgstr "Путь к файлу конфигурации CI. По умолчанию Ñто <code>.gitlab-ci.yml</code>"
msgid "The phase of the development lifecycle."
msgstr "Фаза жизненного цикла разработки."
@@ -21051,7 +22290,7 @@ msgid "The planning stage shows the time from the previous step to pushing your
msgstr "Этап Ð¿Ð»Ð°Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾ÐºÐ°Ð·Ñ‹Ð²Ð°ÐµÑ‚ Ð²Ñ€ÐµÐ¼Ñ Ð¾Ñ‚ предыдущего шага до отправки первого коммита. ДобавлÑетÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки, как только отправите Ñвой первый коммит."
msgid "The private key to use when a client certificate is provided. This value is encrypted at rest."
-msgstr ""
+msgstr "Закрытый ключ, иÑпользуемый при предоÑтавлении клиентÑкого Ñертификата. Он будет зашифрован в ÑоÑтоÑнии покоÑ."
msgid "The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle."
msgstr "ПроизводÑтвенный Ñтап показывает общее Ð²Ñ€ÐµÐ¼Ñ Ð¼ÐµÐ¶Ð´Ñƒ Ñозданием обÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð¸ развертыванием кода в продуктивной Ñреде. Данные будут автоматичеÑки добавлены поÑле полного Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð¸Ð´ÐµÐ¸."
@@ -21084,13 +22323,13 @@ msgid "The pseudonymizer data collection is disabled. When enabled, GitLab will
msgstr ""
msgid "The remote mirror took to long to complete."
-msgstr ""
+msgstr "Удаленное зеркалирование занÑло Ñлишком много времени."
msgid "The remote repository is being updated..."
msgstr "Удаленный репозиторий обновлÑетÑÑ..."
msgid "The repository can be commited to, and issues, comments and other entities can be created."
-msgstr ""
+msgstr "Ð’ репозиторий можно вноÑить коммиты, а также Ñоздавать в нём обÑуждениÑ, комментарии и прочие ÑущноÑти."
msgid "The repository for this project does not exist."
msgstr "Репозиторий Ð´Ð»Ñ Ñтого проекта не ÑущеÑтвует."
@@ -21132,10 +22371,13 @@ msgid "The specified tab is invalid, please select another"
msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
-msgstr "Этап поÑтановки показывает Ð²Ñ€ÐµÐ¼Ñ Ð¼ÐµÐ¶Ð´Ñƒ ÑлиÑнием \"MR\" и развертыванием кода в производÑтвенной Ñреде. Данные будут автоматичеÑки добавлены поÑле Ñ€Ð°Ð·Ð²ÐµÑ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð² производÑтве первый раз."
+msgstr "Этап поÑтановки показывает Ð²Ñ€ÐµÐ¼Ñ Ð¼ÐµÐ¶Ð´Ñƒ уÑпешным выполнением запроÑа на ÑлиÑние и развертыванием кода в производÑтвенном окружении. Данные будут автоматичеÑки добавлены поÑле первого Ñ€Ð°Ð·Ð²ÐµÑ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð² продакшн."
+
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
-msgstr "Этап теÑÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾ÐºÐ°Ð·Ñ‹Ð²Ð°ÐµÑ‚ времÑ, которое GitLab CI занимает Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑка каждой Ñборочной линии Ð´Ð»Ñ ÑоответÑтвующего запроÑа на ÑлиÑние. Данные будут автоматичеÑки добавлены поÑле Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ вашей первой Ñборочной линии."
+msgstr "Этап теÑÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾ÐºÐ°Ð·Ñ‹Ð²Ð°ÐµÑ‚ времÑ, которое требуетÑÑ GitLab CI Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑка вÑех Ñборочных линий, ÑвÑзанных Ñ ÑоответÑтвующим запроÑом на ÑлиÑние. Данные будут автоматичеÑки добавлены поÑле Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ вашей первой Ñборочной линии."
msgid "The time taken by each data entry gathered by that stage."
msgstr "ВремÑ, затраченное каждым Ñлементом, Ñобранным на Ñтом Ñтапе."
@@ -21144,7 +22386,7 @@ msgid "The total stage shows the time it takes between creating an issue and dep
msgstr ""
msgid "The unique identifier for the Geo node. Must match %{geoNodeName} if it is set in gitlab.rb, otherwise it must match %{externalUrl} with a trailing slash"
-msgstr ""
+msgstr "Уникальный идентификатор узла Geo. Должен ÑоответÑтвовать %{geoNodeName}, еÑли таковой задан в gitlab.rb, иначе он должен ÑоответÑтвовать %{externalUrl} Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐ°ÑŽÑ‰ÐµÐ¹ коÑой чертой"
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."
@@ -21171,7 +22413,7 @@ msgid "The user you are trying to deactivate has been active in the past %{minim
msgstr ""
msgid "The user-facing URL of the Geo node"
-msgstr ""
+msgstr "Обращенный к пользователю URL-Ð°Ð´Ñ€ÐµÑ ÑƒÐ·Ð»Ð° Geo"
msgid "The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6."
msgstr "Среднее значение в Ñ€Ñду. Пример: между 3, 5, 9, Ñреднее 5, между 3, 5, 7, 8, Ñреднее (5+7)/2 = 6."
@@ -21182,6 +22424,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr "Ðет ключей GPG, ÑвÑзанных Ñ Ñтой учетной запиÑью."
@@ -21257,11 +22502,20 @@ msgstr "Ðет доÑтупных данных. ПожалуйÑта, измен
msgid "There was a problem communicating with your device."
msgstr "Произошла ошибка ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ Ð²Ð°ÑˆÐ¸Ð¼ уÑтройÑтвом."
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
msgid "There was a problem saving your custom stage, please try again"
-msgstr ""
+msgstr "Произошла ошибка при Ñохранении пользовательÑкого Ñтапа, пожалуйÑта, попробуйте ещё раз"
msgid "There was a problem sending the confirmation email"
msgstr "Произошла ошибка при отправке пиÑьма Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸ÐµÐ¼"
@@ -21288,7 +22542,7 @@ msgid "There was an error fetching configuration for charts"
msgstr "Произошла ошибка при загрузке конфигурации Ð´Ð»Ñ Ð´Ð¸Ð°Ð³Ñ€Ð°Ð¼Ð¼"
msgid "There was an error fetching data for the selected stage"
-msgstr ""
+msgstr "Произошла ошибка при получении данных Ð´Ð»Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð¾Ð³Ð¾ Ñтапа"
msgid "There was an error fetching data for the tasks by type chart"
msgstr ""
@@ -21297,7 +22551,7 @@ msgid "There was an error fetching label data for the selected group"
msgstr "Произошла ошибка при получении данных метки Ð´Ð»Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð¾Ð¹ группы"
msgid "There was an error fetching median data for stages"
-msgstr ""
+msgstr "Произошла ошибка при получении медианных данных по Ñтапам"
msgid "There was an error fetching the %{replicableType}"
msgstr ""
@@ -21312,7 +22566,7 @@ msgid "There was an error fetching the top labels for the selected group"
msgstr ""
msgid "There was an error fetching the variables."
-msgstr ""
+msgstr "Произошла ошибка при извлечении переменных."
msgid "There was an error fetching value stream analytics stages."
msgstr ""
@@ -21324,16 +22578,19 @@ msgid "There was an error getting the epic participants."
msgstr "Произошла ошибка при получении учаÑтников цели."
msgid "There was an error importing the Jira project."
-msgstr ""
+msgstr "При импорте проекта Jira произошла ошибка."
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr "Произошла ошибка при удалении Ñлектронной почты."
msgid "There was an error removing your custom stage, please try again"
-msgstr ""
+msgstr "Произошла ошибка при удалении пользовательÑкого Ñтапа, пожалуйÑта, попробуйте ещё раз"
msgid "There was an error resetting group pipeline minutes."
msgstr "Произошла ошибка при ÑброÑе минут Ñборочной линии группы."
@@ -21342,7 +22599,7 @@ msgid "There was an error resetting user pipeline minutes."
msgstr "Произошла ошибка при ÑброÑе минут пользовательÑкой Ñборочной линии."
msgid "There was an error saving this Geo Node."
-msgstr ""
+msgstr "Ошибка при Ñохранении Ñтого узла Geo."
msgid "There was an error saving your changes."
msgstr "Произошла ошибка при Ñохранении ваших изменений."
@@ -21392,6 +22649,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21423,7 +22683,7 @@ msgid "This GitLab instance does not provide any shared Runners yet. Instance ad
msgstr "Этот ÑкземплÑÑ€ GitLab пока не предоÑтавлÑет никаких общих обработчиков заданий. ÐдминиÑтраторы ÑкземплÑров могут региÑтрировать общие обработчики заданий в Ñекции админиÑтрированиÑ."
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 ""
+msgstr "Этот ÑкземплÑÑ€ GitLab лицензирован на уровне %{insufficient_license}. Geo доÑтупен только тем пользователÑм, у которых еÑÑ‚ÑŒ по крайней мере Premium-лицензиÑ."
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr ""
@@ -21462,18 +22722,21 @@ msgid "This comment has changed since you started editing, please review the %{s
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 "Данный коммит ÑвлÑетÑÑ Ñ‡Ð°Ñтью запроÑа на ÑлиÑние %{link_to_merge_request}. Комментарии, Ñозданные здеÑÑŒ, будут Ñозданы в контекÑте Ñтого запроÑа."
msgid "This commit was signed with a <strong>verified</strong> signature and the committer email is verified to belong to the same user."
-msgstr ""
+msgstr "Это коммит был подпиÑан <strong>верифицированной</strong> подпиÑью и коммитер подтвердил, что Ð°Ð´Ñ€ÐµÑ Ð¿Ð¾Ñ‡Ñ‚Ñ‹ принадлежит ему."
msgid "This commit was signed with a different user's verified signature."
-msgstr ""
+msgstr "Этот коммит был подпиÑан верифицированной подпиÑью другого пользователÑ."
msgid "This commit was signed with a verified signature, but the committer email is <strong>not verified</strong> to belong to the same user."
-msgstr ""
+msgstr "Этот коммит был подпиÑан верифицированной подпиÑью, но <strong>не подтверждена</strong> принадлежноÑÑ‚ÑŒ Ñлектронной почты коммитеру."
msgid "This commit was signed with an <strong>unverified</strong> signature."
+msgstr "Этот коммит был подпиÑан <strong>непроверенной</strong> подпиÑью."
+
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
msgstr ""
msgid "This date is after the due date, so this epic won't appear in the roadmap."
@@ -21515,6 +22778,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr "Эта цель уже имеет макÑимально возможное количеÑтво дочерних целей."
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr "Этой цели не ÑущеÑтвует, или у Ð²Ð°Ñ Ð½ÐµÐ´Ð¾Ñтаточно прав."
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr "Это ÑпиÑок уÑтройÑтв, c которых вошли в вашу учетную запиÑÑŒ. Отмените вÑе ÑеанÑÑ‹, которые вы не раÑпознаете."
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr "Это журнал безопаÑноÑти важных Ñобытий, ÑвÑзанных Ñ Ð²Ð°ÑˆÐµÐ¹ учетной запиÑью."
@@ -21674,7 +22937,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21701,6 +22964,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr "Это означает, что вы не можете отправить код, пока не Ñоздадите пуÑтой репозиторий или не импортируете ÑущеÑтвующий."
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° ÑлиÑние заблокирован."
@@ -21737,12 +23003,18 @@ msgstr "Этот проект"
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr "Этот проект не отноÑитÑÑ Ð½Ð¸ к какой группе и поÑтому не может иÑпользовать групповые обработчики заданий."
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21755,12 +23027,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr "Этот репозиторий"
+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 "Этот репозиторий в наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð¿ÑƒÑÑ‚. ÐÐ¾Ð²Ð°Ñ ÑÐ±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ Auto DevOps будет Ñоздана поÑле того, как новый файл будет помещен в ветку."
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21779,17 +23063,14 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
msgstr ""
msgid "This 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 ""
-
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
+msgstr "Этот пользователь будет автором вÑех Ñобытий в ленте активноÑти, которые ÑвлÑÑŽÑ‚ÑÑ Ñ€ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ð¾Ð¼ обновлениÑ, например, Ñоздание новых веток или новые коммиты, отправлÑемые в ÑущеÑтвующие ветки."
msgid "This variable can not be masked."
msgstr ""
@@ -21845,9 +23126,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21864,7 +23151,7 @@ msgid "ThreatMonitoring|The firewall is not installed or has been disabled. To v
msgstr ""
msgid "ThreatMonitoring|The graph below is an overview of traffic coming to your application as tracked by the Web Application Firewall (WAF). View the docs for instructions on how to access the WAF logs to see what type of malicious traffic is trying to access your app. The docs link is also accessible by clicking the \"?\" icon next to the title below."
-msgstr ""
+msgstr "ÐŸÑ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ð°Ñ Ð½Ð¸Ð¶Ðµ диаграмма — Ñто обзор входÑщего трафика вашего Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð² том виде, в котором его отÑлеживает Web Application Firewall (WAF). ОбратитеÑÑŒ к документации, чтобы узнать, как получить доÑтуп к журналам WAF и увидеть, какой тип вредоноÑного трафика пытаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡Ð¸Ñ‚ÑŒ доÑтуп к приложению. СÑылка на документацию также доÑтупна по щелчку на иконке \"?\" Ñ€Ñдом Ñ Ð½Ð¸Ð¶ÐµÑ€Ð°Ñположенным заголовком."
msgid "ThreatMonitoring|Threat Monitoring"
msgstr ""
@@ -21918,13 +23205,13 @@ msgid "Time estimate"
msgstr ""
msgid "Time from first comment to last commit"
-msgstr ""
+msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð¾Ñ‚ первого ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ñ Ð´Ð¾ поÑледнего коммита"
msgid "Time from first commit until first comment"
-msgstr ""
+msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð¾Ñ‚ первого коммита до первого комментариÑ"
msgid "Time from last commit to merge"
-msgstr ""
+msgstr "Ð’Ñ€ÐµÐ¼Ñ Ñ Ð¿Ð¾Ñледнего коммита до ÑлиÑниÑ"
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 ""
@@ -21942,10 +23229,10 @@ msgid "Time to merge"
msgstr ""
msgid "Time to subtract exceeds the total time spent"
-msgstr ""
+msgstr "Ð’Ñ‹Ñ‡Ð¸Ñ‚Ð°ÐµÐ¼Ð°Ñ Ð´Ð»Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾ÑÑ‚ÑŒ превышает вÑÑ‘ затраченное времÑ"
msgid "Time tracking"
-msgstr ""
+msgstr "Учёт времени"
msgid "Time until first merge request"
msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð´Ð¾ первого запроÑа на ÑлиÑние"
@@ -21954,7 +23241,7 @@ msgid "TimeTrackingEstimated|Est"
msgstr "Оцен."
msgid "TimeTracking|%{startTag}Spent: %{endTag}%{timeSpentHumanReadable}"
-msgstr ""
+msgstr "%{startTag}Затрачено: %{endTag}%{timeSpentHumanReadable}"
msgid "TimeTracking|Estimated:"
msgstr "Запланировано:"
@@ -22092,6 +23379,9 @@ msgid "Timeago|right now"
msgstr "прÑмо ÑейчаÑ"
msgid "Timeout"
+msgstr "Таймаут"
+
+msgid "Timeout connecting to the Google API. Please try again."
msgstr ""
msgid "Time|hr"
@@ -22162,6 +23452,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22208,7 +23504,7 @@ msgid "To protect this issue's confidentiality, a private fork of this project w
msgstr ""
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 ""
+msgstr "Чтобы получать ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¾Ñ‚ наÑтроенных вручную Ñлужб Prometheus, добавьте Ñледующий URL и ключ авторизации в файл конфигурации веб-обработчика Prometheus. Узнайте подробнее о %{linkStart}наÑтройке Prometheus%{linkEnd} Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸ уведомлений в GitLab."
msgid "To see all the user's personal access tokens you must impersonate them first."
msgstr ""
@@ -22282,6 +23578,9 @@ msgstr "Переключить опиÑание коммита"
msgid "Toggle commit list"
msgstr "Открыть или закрыть ÑпиÑок коммитов"
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22328,7 +23627,7 @@ msgid "Too many projects enabled. You will need to manage them via the console o
msgstr "Слишком много проектов включено. Ð”Ð»Ñ ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸Ð¼Ð¸ вам потребуетÑÑ ÐºÐ¾Ð½Ñоль или API."
msgid "Topics (optional)"
-msgstr ""
+msgstr "Темы (необÑзательно)"
msgid "Total"
msgstr ""
@@ -22339,15 +23638,9 @@ msgstr "Общий вклад"
msgid "Total artifacts size: %{total_size}"
msgstr "Общий размер артефактов: %{total_size}"
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr "Общее Ð²Ñ€ÐµÐ¼Ñ Ñ‚ÐµÑÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ„Ð¸ÐºÑаций/ÑлиÑний"
@@ -22363,14 +23656,11 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
-msgstr ""
+msgstr "Следите за обÑуждениÑми, Ñгруппированными по темам, Ñразу из неÑкольких проектов и Ñтапов"
msgid "Track time with quick actions"
-msgstr ""
+msgstr "ОтÑлеживайте Ð²Ñ€ÐµÐ¼Ñ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ быÑтрых дейÑтвий"
msgid "Track your GitLab projects with GitLab for Slack."
msgstr ""
@@ -22382,7 +23672,10 @@ msgid "Transfer ownership"
msgstr ""
msgid "Transfer project"
-msgstr "ÐŸÐµÑ€ÐµÐ½Ð¾Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°"
+msgstr "ПеренеÑти проект"
+
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
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 "Ðевозможно обновить путь поÑкольку в Ñтой группе еÑÑ‚ÑŒ проекты, Ñодержащие образы Docker в Ñвоих рееÑтрах контейнеров. ПожалуйÑта, Ñначала удалите образы из Ñвоих проектов, а затем попробуйте Ñнова."
@@ -22445,7 +23738,7 @@ msgid "Trials|You won't get a free trial right now but you can always resume thi
msgstr "Ð’Ñ‹ не получите беÑплатный пробный период прÑмо ÑейчаÑ, но вы вÑегда можете продолжить Ñтот процеÑÑ, нажав на Ñвой аватар и выбрав \"Ðачать беÑплатный пробный период\""
msgid "Trigger"
-msgstr ""
+msgstr "СобытиÑ"
msgid "Trigger pipelines for mirror updates"
msgstr ""
@@ -22495,6 +23788,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr "Попробуйте изменить поиÑковый запроÑ, чтобы найти нужный файл."
@@ -22547,15 +23843,15 @@ msgid "U2F only works with HTTPS-enabled websites. Contact your administrator fo
msgstr ""
msgid "URL"
-msgstr ""
+msgstr "URL"
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22564,6 +23860,9 @@ msgstr "URL внешнего хранилища, которое будет обÑ
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22586,7 +23885,7 @@ msgid "Unable to connect to server: %{error}"
msgstr "Ðевозможно подключитьÑÑ Ðº Ñерверу:%{error}"
msgid "Unable to connect to the Jira instance. Please check your Jira integration configuration."
-msgstr ""
+msgstr "Ðевозможно подключитьÑÑ Ðº ÑкземплÑру Jira. ПожалуйÑта, проверьте наÑтройки интеграции Ñ Jira."
msgid "Unable to convert Kubernetes logs encoding to UTF-8"
msgstr ""
@@ -22598,11 +23897,14 @@ msgid "Unable to fetch vulnerable projects"
msgstr ""
msgid "Unable to find Jira project to import data from."
-msgstr ""
+msgstr "Ðе удалоÑÑŒ найти проект Jira, из которого должны быть импортированы данные."
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr "Ðе удалоÑÑŒ загрузить отличиÑ"
@@ -22612,9 +23914,15 @@ msgstr "Ðе удаетÑÑ Ð·Ð°Ð³Ñ€ÑƒÐ·Ð¸Ñ‚ÑŒ отличиÑ. %{button_try_agai
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr "Ðевозможно решить"
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22637,7 +23945,7 @@ msgid "Unarchive project"
msgstr "ВоÑÑтановить проект"
msgid "Unarchiving the project will restore people's ability to make changes to it. The repository can be committed to, and issues, comments, and other entities can be created. %{strong_start}Once active, this project shows up in the search and on the dashboard.%{strong_end}"
-msgstr ""
+msgstr "Разархивирование проекта вернёт людÑм возможноÑÑ‚ÑŒ вноÑить в него изменениÑ. Ð’ репозиторий можно будет отправлÑÑ‚ÑŒ коммиты, а также поÑвитÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ÑŒ Ñоздавать обÑуждениÑ, комментарии и другие ÑущноÑти. %{strong_start}ПоÑле активации Ñтот проект поÑвитÑÑ Ð² поиÑке и на панели инÑтрументов.%{strong_end}"
msgid "Unblock"
msgstr ""
@@ -22661,10 +23969,10 @@ msgid "Uninstalling"
msgstr "Удаление"
msgid "Units|ms"
-msgstr ""
+msgstr "мÑ"
msgid "Units|s"
-msgstr ""
+msgstr "Ñ"
msgid "Unknown"
msgstr ""
@@ -22757,22 +24065,22 @@ msgid "Unstar"
msgstr "Убрать из избранного"
msgid "Unsubscribe"
-msgstr ""
+msgstr "ОтпиÑатьÑÑ"
msgid "Unsubscribe at group level"
-msgstr ""
+msgstr "ОтпиÑатьÑÑ Ð½Ð° уровне группы"
msgid "Unsubscribe at project level"
-msgstr ""
+msgstr "ОтпиÑатьÑÑ Ð½Ð° уровне проекта"
msgid "Unsubscribe from %{type}"
-msgstr ""
+msgstr "ОтпиÑатьÑÑ Ð¾Ñ‚ %{type}"
msgid "Unsubscribed from this %{quick_action_target}."
-msgstr ""
+msgstr "Отменена подпиÑка на %{quick_action_target}."
msgid "Unsubscribes from this %{quick_action_target}."
-msgstr ""
+msgstr "ОтменÑет подпиÑку от на %{quick_action_target}."
msgid "Until"
msgstr ""
@@ -22802,7 +24110,7 @@ msgid "Update approval rule"
msgstr "Обновить правило утверждениÑ"
msgid "Update failed"
-msgstr ""
+msgstr "Обновление не удалоÑÑŒ"
msgid "Update failed. Please try again."
msgstr "Обновление не удалоÑÑŒ. Попробуйте ещё раз."
@@ -22864,18 +24172,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr "ОбновитеÑÑŒ на более выÑокий тарифный план, чтобы иÑпользовать развёртывание Canary"
-msgid "Upgrade your plan"
-msgstr "Улучшите Ñвой план"
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr "Обновите Вашу подпиÑку, чтобы активировать раÑширенный глобальный поиÑк."
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr "Улучшите Ñвой тарифный план, чтобы иÑпользовать веб-обработчики на уровне группы."
@@ -22894,6 +24196,9 @@ msgstr ""
msgid "Upload New File"
msgstr "Загрузить новый файл"
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22904,7 +24209,7 @@ msgid "Upload file"
msgstr "Загрузить файл"
msgid "Upload object map"
-msgstr ""
+msgstr "Загрузить карту объектов"
msgid "UploadLink|click to upload"
msgstr "кликните Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸"
@@ -22912,6 +24217,9 @@ msgstr "кликните Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸"
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22936,9 +24244,6 @@ msgstr "Ð¡ÐµÐ¹Ñ‡Ð°Ñ Ð¸ÑпользуетÑÑ"
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr "Справка по квотам иÑпользованиÑ"
-
msgid "Usage statistics"
msgstr "СтатиÑтика иÑпользованиÑ"
@@ -22948,12 +24253,18 @@ msgstr "%{help_link_start}Общие Runner'Ñ‹%{help_link_end} отключенÑ
msgid "UsageQuota|Artifacts"
msgstr "Ðртефакты"
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr "Купить дополнительные минуты"
msgid "UsageQuota|Current period usage"
msgstr "Текущий период иÑпользованиÑ"
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr "Хранилище LFS"
@@ -22963,12 +24274,18 @@ msgstr "Пакеты"
msgid "UsageQuota|Pipelines"
msgstr "Сборочные линии"
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr "Репозиторий"
msgid "UsageQuota|Storage"
msgstr "Хранилище"
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr "Ð’ Ñтом проÑтранÑтве имен нет проектов, которые иÑпользуют общие обработчики заданий"
@@ -22987,12 +24304,18 @@ msgstr "ИÑпользование групповых реÑурÑов по пр
msgid "UsageQuota|Usage of resources across your projects"
msgstr "ИÑпользование реÑурÑов в ваших проектах"
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr "ИÑпользование Ñ"
msgid "UsageQuota|Wiki"
msgstr "Wiki"
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr "ИÑпользуйте %{code_start}::%{code_end}, чтобы Ñоздать %{link_start}набор Ñелективных меток%{link_end} (например, %{code_start}priority::1%{code_end})"
@@ -23017,7 +24340,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -23045,7 +24368,7 @@ msgid "Used to help configure your identity provider"
msgstr "ИÑпользуетÑÑ Ð´Ð»Ñ Ð½Ð°Ñтройки вашего провайдера идентификации"
msgid "User"
-msgstr ""
+msgstr "Пользователь"
msgid "User %{current_user_username} has started impersonating %{username}"
msgstr "Пользователь %{current_user_username} начал выдавать ÑÐµÐ±Ñ Ð·Ð° %{username}"
@@ -23092,9 +24415,6 @@ msgstr "Минуты пользовательÑкой Ñборочной линÐ
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23114,31 +24434,31 @@ msgid "UserOnboardingTour|%{completed}/%{total} steps completed"
msgstr "%{completed}/%{total} шагов завершено"
msgid "UserOnboardingTour|%{emphasisStart}Well done!%{emphasisEnd}%{lineBreak}%{lineBreak}That's it for our guided tour, congratulations for making it all the way to the end!%{lineBreak}%{lineBreak}We hope this gave you a good overview of GitLab and how it can help you. We'll now show you how to create your own project and invite your colleagues."
-msgstr ""
+msgstr "%{emphasisStart}Браво!%{emphasisEnd}%{lineBreak}%{lineBreak}Это конец нашего обучающего курÑа, поздравлÑем Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸ÐµÐ¼!%{lineBreak}%{lineBreak}Мы надеемÑÑ, что ÐºÑƒÑ€Ñ Ð´Ð°Ð» вам хороший обзор GitLab и Ñможет вам помочь. Ð¡ÐµÐ¹Ñ‡Ð°Ñ Ð¼Ñ‹ покажем вам, как Ñоздать ÑобÑтвенный проект и приглаÑить коллег."
msgid "UserOnboardingTour|Adding other members to a project is done through Project Settings. Click on %{emphasisStart}Settings%{emphasisEnd}."
msgstr "Добавление других учаÑтников в проект оÑущеÑтвлÑетÑÑ Ñ‡ÐµÑ€ÐµÐ· ÐаÑтройки проекта. Ðажмите %{emphasisStart}ÐаÑтройки%{emphasisEnd}."
msgid "UserOnboardingTour|Alright, that's it for Commits. Let's take a look at the %{emphasisStart}Branches%{emphasisEnd}."
-msgstr ""
+msgstr "Отлично, вот и вÑÑ‘ про Коммиты. Давайте взглÑнем на %{emphasisStart}Ветки%{emphasisEnd}."
msgid "UserOnboardingTour|Awesome! Now click on %{emphasisStart}Members%{emphasisEnd}."
msgstr "ПотрÑÑающе! Теперь нажмите на %{emphasisStart}учаÑтников%{emphasisEnd}."
msgid "UserOnboardingTour|Click on one of the %{emphasisStart}Compare%{emphasisEnd} buttons to compare a branch to master."
-msgstr ""
+msgstr "Ðажмите одну из кнопок %{emphasisStart}Сравнить%{emphasisEnd}, чтобы Ñравнить ÑоответÑтвующую ветку Ñ Ð²ÐµÑ‚ÐºÐ¾Ð¹ master."
msgid "UserOnboardingTour|Click on one of the %{emphasisStart}pipeline IDs%{emphasisEnd} to see the details of a pipeline."
-msgstr ""
+msgstr "Ðажмите на один из %{emphasisStart}идентификаторов Ñборочных линий%{emphasisEnd}, чтобы увидеть подробную информацию о ней."
msgid "UserOnboardingTour|Click to open the latest commit to see its details."
-msgstr ""
+msgstr "Ðажмите, чтобы открыть поÑледний коммит и узнать о нём подробнее."
msgid "UserOnboardingTour|Close 'Learn GitLab'"
msgstr "Закрыть 'Изучить GitLab'"
msgid "UserOnboardingTour|Commits are shown in chronological order and can be filtered by the commit message or by the branch."
-msgstr ""
+msgstr "Коммиты отображаютÑÑ Ð² хронологичеÑком порÑдке и могут быть отфильтрованы по Ñообщению коммита или по ветке."
msgid "UserOnboardingTour|Create a project"
msgstr "Создайте проект"
@@ -23147,25 +24467,25 @@ msgid "UserOnboardingTour|Exit 'Learn GitLab'"
msgstr "Выйти из 'Изучить GitLab'"
msgid "UserOnboardingTour|Got it"
-msgstr ""
+msgstr "ЯÑно"
msgid "UserOnboardingTour|Great job! %{clapHands} We hope the tour was helpful and that you learned how to use GitLab.%{lineBreak}%{lineBreak}We'd love to get your feedback on this tour.%{lineBreak}%{lineBreak}%{emphasisStart}How helpful would you say this guided tour was?%{emphasisEnd}%{lineBreak}%{lineBreak}"
-msgstr ""
+msgstr "ÐžÑ‚Ð»Ð¸Ñ‡Ð½Ð°Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ð°! %{clapHands} ÐадеемÑÑ, что тур был полезен и вы узнали, как иÑпользовать GitLab.%{lineBreak}%{lineBreak}Мы были бы рады узнать ваше мнение о нём.%{lineBreak}%{lineBreak}%{emphasisStart}ÐаÑколько полезным, по-вашему, был Ñтот тур?%{emphasisEnd}%{lineBreak}%{lineBreak}"
msgid "UserOnboardingTour|Guided GitLab Tour"
msgstr "ЭкÑкурÑÐ¸Ñ Ð¿Ð¾ GitLab"
msgid "UserOnboardingTour|Here you can compare the changes of this branch to another one. Changes are divided by files so that it's easier to see what was changed where."
-msgstr ""
+msgstr "ЗдеÑÑŒ вы можете Ñравнить Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñтой ветки Ñ Ð»ÑŽÐ±Ð¾Ð¹ другой. Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ð´ÐµÐ»ÐµÐ½Ñ‹ по файлам, чтобы было легче увидеть, что и где было изменено."
msgid "UserOnboardingTour|Here you can create a project from scratch, start with a template or import a repository from other platforms. Whatever you choose, we'll guide you through the process.%{lineBreak}%{lineBreak}Fill in your new project information and click on %{emphasisStart}Create Project%{emphasisEnd} to progress to the next step."
msgstr "ЗдеÑÑŒ вы можете Ñоздать проект Ñ Ð½ÑƒÐ»Ñ, начать Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½Ð° или импортировать репозиторий Ñ Ð´Ñ€ÑƒÐ³Ð¸Ñ… платформ. Что бы вы ни выбрали, мы будем Ñопровождать Ð²Ð°Ñ Ð² течение вÑего процеÑÑа.%{lineBreak}%{lineBreak}Заполните информацию о вашем новом проекте и нажмите %{emphasisStart}Создать проект%{emphasisEnd} Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ð° к Ñледующему шагу."
msgid "UserOnboardingTour|Here you can see the breakdown of the pipelines: its stages and jobs in each of the stages and their status.%{lineBreak}%{lineBreak}Our CI/CD pipelines are quite complex, most of our users have fewer and simpler pipelines."
-msgstr "ЗдеÑÑŒ вы можете видеть разбивку Ñборочных линий: Ñтадии, Ð·Ð°Ð´Ð°Ð½Ð¸Ñ Ð½Ð° каждой из Ñтадий, а также их ÑоÑтоÑние.%{lineBreak}%{lineBreak}Ðаши ÑобÑтвенные Ñборочные линии CI/CD довольно Ñложны, у большинÑтва наших пользователей их меньше и они проще."
+msgstr "ЗдеÑÑŒ вы можете видеть разбивку Ñборочных линий: Ñтапы, Ð·Ð°Ð´Ð°Ð½Ð¸Ñ Ð½Ð° каждом из Ñтапов, а также их ÑоÑтоÑние.%{lineBreak}%{lineBreak}Ðаши ÑобÑтвенные Ñборочные линии CI/CD довольно Ñложны, у большинÑтва наших пользователей их меньше и они проще."
msgid "UserOnboardingTour|Here you can see the current members of the project (just you at the moment) and invite new members.%{lineBreak}%{lineBreak}You can invite multiple members at once (existing GitLab users or invite by email) and you can also set their roles and permissions.%{lineBreak}%{lineBreak}Add a few members and click on %{emphasisStart}Add to project%{emphasisEnd} to complete this step."
-msgstr ""
+msgstr "ЗдеÑÑŒ вы можете увидеть текущих учаÑтников проекта (в данный момент Ñто только вы) и приглаÑить новых.%{lineBreak}%{lineBreak}Можете приглаÑить Ñразу неÑкольких учаÑтников (ÑущеÑтвующих пользователей GitLab или отправкой Ð¿Ñ€Ð¸Ð³Ð»Ð°ÑˆÐµÐ½Ð¸Ñ Ð¿Ð¾ Ñлектронной почте), а также задать им роли и права в проекте.%{lineBreak}%{lineBreak}Добавьте неÑкольких учаÑтников и нажмите на %{emphasisStart}Добавить в проект%{emphasisEnd}, чтобы завершить Ñтот шаг."
msgid "UserOnboardingTour|Here you can see what changes were made with this commit, on what branch and if there's a related merge request. The status of the pipeline will also show up if CI/CD is set up.%{lineBreak}%{lineBreak}You can also comment on the lines of code that were changed and start a discussion with your colleagues!"
msgstr "ЗдеÑÑŒ вы можете увидеть какие Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñодержит Ñтот коммит, в какой ветке, и еÑÑ‚ÑŒ ли ÑвÑзанные Ñ Ð½Ð¸Ð¼ запроÑÑ‹ на ÑлиÑние. СоÑтоÑние Ñборочной линии также будет отображатьÑÑ, еÑли наÑтроены CI/CD. %{lineBreak}%{lineBreak} Ещё вы можете прокомментировать Ñтроки кода, которые были изменены, и начать диÑкуÑÑию Ñо Ñвоими коллегами!"
@@ -23180,16 +24500,16 @@ msgid "UserOnboardingTour|Issues are great for communicating and keeping track o
msgstr "ОбÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð² GitLab отлично подходÑÑ‚ Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¼ÑƒÐ½Ð¸ÐºÐ°Ñ†Ð¸Ð¸ и отÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¿Ñ€Ð¾Ð³Ñ€ÐµÑÑа. Перед вами вÑе обÑуждениÑ, открытые в %{emphasisStart}%{projectName}%{emphasisEnd}.%{lineBreak}%{lineBreak}Ð’Ñ‹ можете помочь нам улучшить GitLab, принÑв учаÑтие в работе над обÑуждениÑми Ñ Ð¼ÐµÑ‚ÐºÐ¾Ð¹ <span class=\"badge color-label accept-mr-label\">Accepting merge requests</span> (принимаютÑÑ Ð·Ð°Ð¿Ñ€Ð¾ÑÑ‹ на ÑлиÑние).%{lineBreak}%{lineBreak}Этот ÑпиÑок может быть отфильтрован по меткам, Ñтапам, иÑпонителÑм, авторам... Мы покажем вам, как выглÑдит отфильтрованный по метке ÑпиÑок."
msgid "UserOnboardingTour|Learn GitLab"
-msgstr ""
+msgstr "Изучить GitLab"
msgid "UserOnboardingTour|Let's take a closer look at a merge request. Click on the title of one."
-msgstr ""
+msgstr "Давайте подробнее раÑÑмотрим Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° ÑлиÑние. Ðажмите на заголовок одного из них."
msgid "UserOnboardingTour|Let's take a closer look at all the commits. Click on %{emphasisStart}Commits%{emphasisEnd}."
-msgstr ""
+msgstr "Давайте подробнее раÑÑмотрим вÑе коммиты. Ðажмите на %{emphasisStart}Коммиты%{emphasisEnd}."
msgid "UserOnboardingTour|Let's take a closer look at the repository of this project. Click on %{emphasisStart}Repository%{emphasisEnd}."
-msgstr ""
+msgstr "Давайте подробнее раÑÑмотрим репозиторий Ñтого проекта. Ðажмите на %{emphasisStart}Репозиторий%{emphasisEnd}."
msgid "UserOnboardingTour|No thanks"
msgstr "Ðет, ÑпаÑибо"
@@ -23198,55 +24518,55 @@ msgid "UserOnboardingTour|Ok, let's go"
msgstr "Хорошо, поехали"
msgid "UserOnboardingTour|Ok, show me"
-msgstr ""
+msgstr "Ладно, покажите мне"
msgid "UserOnboardingTour|Open one of the issues by clicking on its title."
-msgstr ""
+msgstr "Откройте одно из обÑуждений, нажав на его заголовок."
msgid "UserOnboardingTour|Restart this step"
-msgstr ""
+msgstr "ПерезапуÑтить Ñтого шаг"
msgid "UserOnboardingTour|Skip this step"
-msgstr ""
+msgstr "ПропуÑтить Ñтот шаг"
msgid "UserOnboardingTour|Sweet! Your project was created and is ready to be used.%{lineBreak}%{lineBreak}You can start adding files to the repository or clone it. One last thing we want to show you is how to invite your colleagues to your new project."
-msgstr ""
+msgstr "ПрекраÑно! Ваш проект Ñоздан и готов к иÑпользованию.%{lineBreak}%{lineBreak}Ð’Ñ‹ можете начать, добавив файлы в репозиторий или Ñклонировав его. Одна поÑледнÑÑ Ð²ÐµÑ‰ÑŒ, которую мы хотим вам показать — Ñто как приглаÑить коллег в Ñвой новый проект."
msgid "UserOnboardingTour|Take a look. Here's a nifty menu for quickly creating issues, merge requests, snippets, projects and groups. Click on it and select \"New project\" from the \"GitLab\" section to get started."
msgstr "ВзглÑните. Вот отличное меню Ð´Ð»Ñ Ð±Ñ‹Ñтрого ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¾Ð±Ñуждений, запроÑов на ÑлиÑние, Ñниппетов, проектов и групп. Ðажмите на него и выберите «Ðовый проект» в разделе «GitLab», чтобы начать."
msgid "UserOnboardingTour|Thanks for taking the guided tour. Remember, if you want to go through it again, you can start %{emphasisStart}Learn GitLab%{emphasisEnd} in the help menu on the top right."
-msgstr ""
+msgstr "СпаÑибо за то, что воÑпользовалиÑÑŒ нашей ÑкÑкурÑией. Помните, еÑли вы захотите её повторить, запуÑтите %{emphasisStart}Изучить GitLab%{emphasisEnd} в меню помощи в правом верхнем углу."
msgid "UserOnboardingTour|Thanks for the feedback! %{thumbsUp}"
msgstr "СпаÑибо за отзыв! %{thumbsUp}"
msgid "UserOnboardingTour|That's it for issues. Let'st take a look at %{emphasisStart}Merge Requests%{emphasisEnd}."
-msgstr ""
+msgstr "Вот и вÑÑ‘ про обÑуждениÑ. Давайте раÑÑмотрим %{emphasisStart}ЗапроÑÑ‹ на ÑлиÑние%{emphasisEnd}."
msgid "UserOnboardingTour|That's it for merge requests. Now for the final part of this guided tour - the %{emphasisStart}CI/CD%{emphasisEnd}."
-msgstr ""
+msgstr "Это вÑÑ‘ про запроÑÑ‹ на ÑлиÑние. Ð’ финальной чаÑти ÑкÑкурÑии Ð²Ð°Ñ Ð¶Ð´ÑƒÑ‚ %{emphasisStart}CI/CD%{emphasisEnd}."
msgid "UserOnboardingTour|That's it for the Repository. Let's take a look at the %{emphasisStart}Issues%{emphasisEnd}."
-msgstr ""
+msgstr "Вот и вÑÑ‘ про Репозиторий. Давайте раÑÑмотрим %{emphasisStart}ОбÑуждениÑ%{emphasisEnd}."
msgid "UserOnboardingTour|The structure of this page is very similar to issues. Status, description, discussion and the sidebar are all here.%{lineBreak}%{lineBreak}But take a look below the description and you'll notice that there's more information about the merge request, the CI/CD pipeline and the options for approving it.%{lineBreak}%{lineBreak}Alongside the discussion you can also see more information about commits in this merge request, the status of pipelines and review all changes that were made."
-msgstr ""
+msgstr "Структура Ñтой Ñтраницы очень напоминает обÑуждениÑ. СоÑтоÑние, опиÑание, диÑкуÑÑÐ¸Ñ Ð¸ Ð±Ð¾ÐºÐ¾Ð²Ð°Ñ Ð¿Ð°Ð½ÐµÐ»ÑŒ — вÑÑ‘ на меÑте.%{lineBreak}%{lineBreak} Ðо поÑмотрите ниже опиÑÐ°Ð½Ð¸Ñ Ð¸ вы заметите, что там приÑутÑтвует Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ запроÑе на ÑлиÑние, о Ñборочной линии CI/CD, а также ÑредÑтва Ð´Ð»Ñ ÑƒÑ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñа.%{lineBreak}%{lineBreak}Сбоку от диÑкуÑÑии вы также можете увидеть больше Ñведений о коммитах данного запроÑа на ÑлиÑние, о ÑоÑтоÑнии Ñборочных линий, а ещё проÑмотреть вÑе внеÑённые изменениÑ."
msgid "UserOnboardingTour|There's a lot of information here but don't worry, we'll go through it.%{lineBreak}%{lineBreak}On the top you can see the status of the issue and when it was opened and by whom. Directly below it is the issue description and below that are other %{emphasisStart}related issues%{emphasisEnd} and %{emphasisStart}merge requests%{emphasisEnd} (if any). Then below that is the %{emphasisStart}discussion%{emphasisEnd}, that's where most of the communication happens.%{lineBreak}%{lineBreak}On the right, there's a sidebar where you can view/change the %{emphasisStart}assignee, milestone, due date, labels, weight%{emphasisEnd}, etc."
msgstr "Информации много, но не волнуйтеÑÑŒ, мы через Ñто пройдем.%{lineBreak}%{lineBreak}Вверху вы можете видеть ÑоÑтоÑние обÑуждениÑ, когда оно было открыто и кем. ÐепоÑредÑтвенно под ним раÑположено опиÑание обÑуждениÑ, а еще ниже — другие %{emphasisStart}ÑвÑзанные обÑуждениÑ%{emphasisEnd} и %{emphasisStart}запроÑÑ‹ на ÑлиÑние%{emphasisEnd} (при наличии). Далее находитÑÑ %{emphasisStart}диÑкуÑÑиÑ%{emphasisEnd}, где проиÑходит Ð±Ð¾Ð»ÑŒÑˆÐ°Ñ Ñ‡Ð°ÑÑ‚ÑŒ общениÑ.%{lineBreak}%{lineBreak}Справа — Ð±Ð¾ÐºÐ¾Ð²Ð°Ñ Ð¿Ð°Ð½ÐµÐ»ÑŒ, где вы можете проÑмотреть / изменить %{emphasisStart}назначенных иÑполнителей, Ñтап, Ñрок выполнениÑ, метки, приоритет%{emphasisEnd} и Ñ‚. д."
msgid "UserOnboardingTour|These are all the CI/CD pipelines we have for our %{emphasisStart}%{projectName}%{emphasisEnd} project.%{lineBreak}%{lineBreak}Here you can see the status of each pipeline, for what commit it's running for, its stages and the status for them."
-msgstr ""
+msgstr "Перед вами вÑе Ñборочные линии CI/CD, которые еÑÑ‚ÑŒ у Ð½Ð°Ñ Ð² проекте %{emphasisStart}%{projectName}%{emphasisEnd}.%{lineBreak}%{lineBreak}ЗдеÑÑŒ вы можете увидеть ÑоÑтоÑние каждой Ñборочной линии, Ð´Ð»Ñ ÐºÐ°ÐºÐ¾Ð³Ð¾ коммита она выполнÑетÑÑ, её Ñтапы и их ÑоÑтоÑние."
msgid "UserOnboardingTour|These are all the issues that are available for community contributions. Let's take a closer look at one of them."
-msgstr ""
+msgstr "Это — вÑе обÑуждениÑ, принимающие вклад от учаÑтников ÑообщеÑтва. Давайте раÑÑмотрим одно из них."
msgid "UserOnboardingTour|This is an overview of all merge requests in this project. Similarly to the issues overview it can be filtered down by things like labels, milestones, authors, assignees, etc."
msgstr "Это обзор вÑех запроÑов на ÑлиÑние в Ñтом проекте. Подобно обзору обÑуждений, их можно отфильтровать по меткам, Ñтапам, авторам, назначенным иÑполнителÑм, и Ñ‚. д."
msgid "UserOnboardingTour|This is the repository for the %{emphasisStart}%{projectName}%{emphasisEnd} project. All our code is stored here. Feel free to explore and take a closer look at folders and files.%{lineBreak}%{lineBreak}Above the file structure you can see the latest commit, who the author is and the status of the CI/CD pipeline.%{lineBreak}%{lineBreak}If you scroll down below the file structure, you'll find the Readme of this project. This is defined in the README.md file at the root of the repository."
-msgstr ""
+msgstr "Это репозиторий проекта %{emphasisStart}%{projectName}%{emphasisEnd}. ВеÑÑŒ наш код хранитÑÑ Ð·Ð´ÐµÑÑŒ. Ðе ÑтеÑнÑйтеÑÑŒ иÑÑледовать и раÑÑматривать папки и файлы.%{lineBreak}%{lineBreak}Ðад Ñтруктурой файлов вы можете увидеть поÑледний коммит, его автора и ÑоÑтоÑние ÑоответÑтвующей Ñборочной линии CI/CD.%{lineBreak}%{lineBreak}ЕÑли вы пролиÑтаете Ñтраницу ниже Ñтруктуры файлов, то обнаружите раздел \"Прочти менÑ\" проекта. Он определен в файле README.md в корне репозиториÑ."
msgid "UserOnboardingTour|Welcome to the project overview of the %{emphasisStart}%{projectName}%{emphasisEnd} project. This is the project that we use to work on GitLab. At first, a project seems like a simple repository, but at GitLab, a project is so much more.%{lineBreak}%{lineBreak}You can create projects for hosting your codebase, use it as an issue tracker, collaborate on code, and continuously build, test, and deploy your app with built-in GitLab CI/CD."
msgstr "Добро пожаловать в обзор проекта %{emphasisStart}%{projectName}%{emphasisEnd}. Это проект, над которым мы работает в GitLab. Сперва проект выглÑдит как обычный репозиторий, но проект в GitLab — Ñто нечто большее.%{lineBreak}%{lineBreak}Ð’Ñ‹ можете Ñоздавать проекты Ð´Ð»Ñ Ñ€Ð°Ð·Ð¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ñвоей кодовой базы, иÑпользовать его в качеÑтве багтрекера и трекера задач, ÑовмеÑтно работать над кодом, а так же непрерывно Ñобирать, теÑтировать и развертывать Ñвои Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸ помощи ÑредÑтв CI/CD, вÑтроенных в GitLab."
@@ -23341,6 +24661,12 @@ msgstr "Ð’Ñ‹ не Ñоздали ни одного Ñниппета."
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr "Ðа ваш выбор проекты могут быть публичными, внутренними или личными."
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ (необÑзательно)"
@@ -23401,6 +24727,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23428,14 +24757,17 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
msgstr ""
msgid "Variables"
-msgstr ""
+msgstr "Переменные"
msgid "Various container registry settings."
msgstr ""
@@ -23462,14 +24794,17 @@ msgid "Verified"
msgstr "Подтверждена"
msgid "Verify SAML Configuration"
-msgstr ""
+msgstr "Проверить наÑтройки SAML"
msgid "Verify configuration"
-msgstr ""
+msgstr "Проверить наÑтройки"
msgid "Version"
msgstr "ВерÑиÑ"
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23520,6 +24855,9 @@ msgstr[3] "ПроÑмотреть %d опубликованных артефак
msgid "View file @ "
msgstr "ПроÑмотр файла @ "
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr "Показать вÑÑŽ панель"
@@ -23530,7 +24868,7 @@ msgid "View group labels"
msgstr "ПроÑмотр меток группы"
msgid "View incident issues."
-msgstr ""
+msgstr "Показать обÑуждениÑ-инциденты"
msgid "View issue"
msgstr ""
@@ -23583,9 +24921,12 @@ msgstr "ПроÑмотр поÑледнего уÑпешного развёртÑ
msgid "View the performance dashboard at"
msgstr ""
-msgid "Viewing commit"
+msgid "View users statistics"
msgstr ""
+msgid "Viewing commit"
+msgstr "ПроÑмотр коммита"
+
msgid "Visibility"
msgstr "ВидимоÑÑ‚ÑŒ"
@@ -23632,7 +24973,7 @@ msgid "VisualReviewApp|%{stepStart}Step 4%{stepEnd}. Leave feedback in the Revie
msgstr ""
msgid "VisualReviewApp|Cancel"
-msgstr ""
+msgstr "Отмена"
msgid "VisualReviewApp|Copy merge request ID"
msgstr "Скопировать ID запроÑа на ÑлиÑние"
@@ -23664,9 +25005,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23697,9 +25035,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23808,6 +25143,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23815,11 +25153,14 @@ msgid "Want to see the data? Please ask an administrator for access."
msgstr "Хотите увидеть данные? ОбратитеÑÑŒ к админиÑтратору за доÑтупом."
msgid "Warning:"
-msgstr ""
+msgstr "Предупреждение:"
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr "Мы не Ñмогли раÑпознать путь Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ñ†ÐµÐ»Ð¸"
@@ -23841,8 +25182,14 @@ msgstr "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¿Ð¾ Ñтапу отÑутÑтвует."
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
-msgstr "Мы получили ответ от вашего уÑтройÑтва U2F. Ð’Ñ‹ прошли проверку подлинноÑти."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
+msgstr ""
msgid "We sent you an email with reset password instructions"
msgstr ""
@@ -23883,9 +25230,6 @@ msgstr "ÐаÑтройки веб-обработчика"
msgid "Webhooks"
msgstr "Веб-обработчики"
-msgid "Webhooks Help"
-msgstr "Справка по веб-обработчикам"
-
msgid "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 "Веб-обработчики позволÑÑŽÑ‚ вам вызывать Ð°Ð´Ñ€ÐµÑ URL еÑли, например, отправлен новый код или Ñоздано новое обÑуждение. Ð’Ñ‹ можете наÑтроить веб-обработчики так, чтобы они реагировали на определённые ÑобытиÑ, такие как отправки кода, обÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ запроÑÑ‹ на ÑлиÑние. Групповые веб-обработчики применÑÑŽÑ‚ÑÑ ÐºÐ¾ вÑем проектам в группе и позволÑÑŽÑ‚ вам Ñтандартизовать функциональноÑÑ‚ÑŒ веб-обработчиков Ð´Ð»Ñ Ð²Ñей вашей группы."
@@ -23896,7 +25240,7 @@ msgid "Wednesday"
msgstr "Среда"
msgid "Weekday"
-msgstr ""
+msgstr "День недели"
msgid "Weeks"
msgstr ""
@@ -23923,6 +25267,9 @@ msgid "Welcome to GitLab.com<br>@%{name}!"
msgstr "Добро пожаловать в GitLab.com<br>@%{name}!"
msgid "Welcome to the Guided GitLab Tour"
+msgstr "Добро пожаловать на ÑкÑкурÑию по GitLab"
+
+msgid "Welcome to the guided GitLab tour"
msgstr ""
msgid "Welcome to your Issue Board!"
@@ -23931,6 +25278,12 @@ msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23968,9 +25321,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr "Белые подÑказки дают контекÑтную информацию."
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -24004,9 +25354,6 @@ msgstr "ДоÑтуп через Git"
msgid "WikiClone|Install Gollum"
msgstr "УÑтановка Gollum"
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr "РекомендуетÑÑ ÑƒÑтановить %{markdown}, чтобы возможноÑти GFM отображалиÑÑŒ локально:"
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr "ЗапуÑтите Gollum и редактируете локально"
@@ -24035,7 +25382,7 @@ msgid "WikiEmpty|Suggest wiki improvement"
msgstr "Предложить улучшение Wiki"
msgid "WikiEmpty|The wiki lets you write documentation for your project"
-msgstr ""
+msgstr "Вики позволÑет пиÑать документацию Ð´Ð»Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°"
msgid "WikiEmpty|This project has no wiki pages"
msgstr ""
@@ -24080,7 +25427,7 @@ msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Pl
msgstr "Кто-то редактирует Ñтраницу одновременно Ñ Ð²Ð°Ð¼Ð¸. ПожалуйÑта проверьте %{page_link} и убедитеÑÑŒ, что внеÑенные Вами Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½Ðµ затрут чужие."
msgid "WikiPageConflictMessage|the page"
-msgstr "WikiСтраницаСообщениÑПриКонфликте | Ñтраницы"
+msgstr "Ñтраница"
msgid "WikiPageCreate|Create %{pageTitle}"
msgstr ""
@@ -24089,7 +25436,7 @@ msgid "WikiPageEdit|Update %{pageTitle}"
msgstr ""
msgid "WikiPage|Write your content or drag files here…"
-msgstr ""
+msgstr "Ðапишите что-нибудь или перетащите Ñюда файлы…"
msgid "Wiki|Create New Page"
msgstr "Создать новую Ñтраницу"
@@ -24127,10 +25474,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr "Страницы Wiki"
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -24139,20 +25489,20 @@ msgstr "Отменить Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð´Ð¾Ñтупа"
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
-msgstr ""
+msgstr "Правка"
msgid "Write a comment or drag your files here…"
-msgstr ""
+msgstr "Ðапишите комментарий или перетащите Ñюда файлы..."
msgid "Write a comment…"
-msgstr ""
+msgstr "Ðапишите комментарий…"
msgid "Write access allowed"
msgstr "ДоÑтуп к запиÑи разрешен"
@@ -24173,7 +25523,7 @@ msgid "Yes or No"
msgstr ""
msgid "Yes, add it"
-msgstr ""
+msgstr "Да, добавить"
msgid "Yes, close issue"
msgstr ""
@@ -24185,7 +25535,7 @@ msgid "Yesterday"
msgstr "Вчера"
msgid "You"
-msgstr ""
+msgstr "Ð’Ñ‹"
msgid "You are about to delete %{domain} from your instance. This domain will no longer be available to any Knative application."
msgstr ""
@@ -24259,6 +25609,9 @@ msgstr "Вы также можете проверить ваш %{gitlab_ci_yml}
msgid "You can also upload existing files from your computer using the instructions below."
msgstr "Ð’Ñ‹ также можете загрузить ÑущеÑтвующие файлы Ñ ÐºÐ¾Ð¼Ð¿ÑŒÑŽÑ‚ÐµÑ€Ð°, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð¿Ñ€Ð¸Ð²ÐµÐ´Ñ‘Ð½Ð½Ñ‹Ðµ ниже инÑтрукции."
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24286,6 +25639,9 @@ msgstr "Ð’Ñ‹ можете легко уÑтановить Runner в клаÑте
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24301,6 +25657,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr "Ð’Ñ‹ можете перемещатьÑÑ Ð¿Ð¾ диаграмме Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ клавиш Ñо Ñтрелками."
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24329,10 +25688,10 @@ msgid "You can only upload one design when dropping onto an existing design."
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 ""
+msgstr "Ð’Ñ‹ можете разрешить конфликт ÑлиÑниÑ, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð»Ð¸Ð±Ð¾ интерактивный режим, выбрав кнопки %{use_ours} или %{use_theirs}, либо отредактировав файлы напрÑмую. Примите Ñти Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² %{branch_name}"
msgid "You can see your chat accounts."
-msgstr ""
+msgstr "Ð’Ñ‹ можете проÑмотреть ваши аккаунты чата."
msgid "You can set up as many Runners as you need to run your jobs."
msgstr ""
@@ -24365,7 +25724,7 @@ msgid "You cannot play this scheduled pipeline at the moment. Please wait a minu
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
-msgstr ""
+msgstr "Ð’Ñ‹ не можете вноÑить Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð²Ð¾ вторичный ÑкземплÑÑ€ GitLab Geo, доÑтупный только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ. ВмеÑто него, пожалуйÑта, иÑпользуйте %{link_to_primary_node}."
msgid "You cannot write to this read-only GitLab instance."
msgstr "Ð’Ñ‹ не можете запиÑывать на Ñтот ÑкземплÑÑ€ \"только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ\" клаÑтера GitLab."
@@ -24379,6 +25738,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24427,6 +25789,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24442,7 +25807,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24470,7 +25835,7 @@ msgid "You may also add variables that are made available to the running applica
msgstr ""
msgid "You may close the milestone now."
-msgstr ""
+msgstr "Теперь вы можете закрыть Ñтап."
msgid "You must accept our Terms of Service and privacy policy in order to register an account"
msgstr ""
@@ -24535,14 +25900,17 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
-msgid "You will first need to set up Jira Integration to use this feature."
+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 ""
+msgid "You will first need to set up Jira Integration to use this feature."
+msgstr "Ð”Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñтой возможноÑти необходимо предварительно наÑтроить интеграцию Ñ Jira."
+
msgid "You will lose all changes you've made to this file. This action cannot be undone."
msgstr ""
msgid "You will lose all uncommitted changes you've made in this project. This action cannot be undone."
-msgstr ""
+msgstr "Ð’Ñ‹ потерÑете вÑе незафикÑированные изменениÑ, Ñделанные вами в Ñтом проекте. Это дейÑтвие не может быть отменено."
msgid "You will need to update your local repositories to point to the new location."
msgstr "Вам нужно будет обновить ваши локальные репозитории, чтобы указать новое меÑтоположение."
@@ -24562,6 +25930,9 @@ msgstr "Ð’Ñ‹ будете получать ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¾ любых
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr "Ð’Ñ‹ будете получать ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸ÐµÐ², в которых вы были @упомÑнуты"
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr "Ð’Ñ‹ не Ñможете получать и отправлÑÑ‚ÑŒ код в данный проект через %{protocol} пока не %{set_password_link} в вашей учетной запиÑи"
@@ -24580,6 +25951,12 @@ msgstr "Ð’Ñ‹ ÑобираетеÑÑŒ уменьшить облаÑÑ‚ÑŒ видим
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24613,7 +25990,10 @@ msgstr "Вы уже включили двухфакторную аутентиф
msgid "YouTube"
msgstr "YouTube"
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24632,7 +26012,7 @@ msgid "Your Commit Email will be used for web based operations, such as edits an
msgstr "Ваш Ð°Ð´Ñ€ÐµÑ Ñлектронной почты Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¼Ð¸Ñ‚Ð¾Ð² будет иÑпользоватьÑÑ Ð´Ð»Ñ Ð²ÐµÐ±-операций, таких как редактирование и ÑлиÑние."
msgid "Your Default Notification Email will be used for account notifications if a %{openingTag}group-specific email address%{closingTag} is not set."
-msgstr ""
+msgstr "Ваша почта Ð´Ð»Ñ ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ð¹ по умолчанию будет иÑпользоватьÑÑ Ð´Ð»Ñ ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ð¹ учетной запиÑи, еÑли не уÑтановлен Ð°Ð´Ñ€ÐµÑ %{openingTag}Ñлектронной почты Ð´Ð»Ñ ÐºÐ¾Ð½ÐºÑ€ÐµÑ‚Ð½Ð¾Ð¹ группы%{closingTag}."
msgid "Your DevOps Score gives an overview of how you are using GitLab from a feature perspective. View how you compare with other organizations, discover features you are not using, and learn best practices through blog posts and white papers."
msgstr ""
@@ -24649,14 +26029,14 @@ msgstr "Ваша пробный период GitLab Gold продлитÑÑ 30 Ð
msgid "Your Groups"
msgstr "Ваши Группы"
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
msgstr ""
msgid "Your Primary Email will be used for avatar detection."
-msgstr "Ваш оÑновной email будет иÑпользоватьÑÑ Ð´Ð»Ñ Ð¾Ð±Ð½Ð°Ñ€ÑƒÐ¶ÐµÐ½Ð¸Ñ Ð°Ð²Ð°Ñ‚Ð°Ñ€Ð°."
+msgstr "Ваша оÑÐ½Ð¾Ð²Ð½Ð°Ñ Ð¿Ð¾Ñ‡Ñ‚Ð° будет иÑпользоватьÑÑ Ð´Ð»Ñ Ð¾Ð±Ð½Ð°Ñ€ÑƒÐ¶ÐµÐ½Ð¸Ñ Ð°Ð²Ð°Ñ‚Ð°Ñ€Ð°."
msgid "Your Projects (default)"
msgstr "Ваши проекты (по умолчанию)"
@@ -24665,7 +26045,7 @@ msgid "Your Projects' Activity"
msgstr "ÐктивноÑÑ‚ÑŒ ваших проектов"
msgid "Your Public Email will be displayed on your public profile."
-msgstr "Ваш публичный email будет отображатьÑÑ Ð² вашем профиле."
+msgstr "Ваша Ð¿ÑƒÐ±Ð»Ð¸Ñ‡Ð½Ð°Ñ Ð¿Ð¾Ñ‡Ñ‚Ð° будет отображатьÑÑ Ð² вашем профиле."
msgid "Your SSH keys (%{count})"
msgstr "Ваши ключи SSH (%{count})"
@@ -24704,7 +26084,7 @@ msgid "Your browser doesn't support U2F. Please use Google Chrome desktop (versi
msgstr "Ваш браузер не поддерживает U2F. ПожалуйÑта, иÑпользуйте Google Chrome Desktop (верÑÐ¸Ñ 41 или новее)."
msgid "Your changes can be committed to %{branch_name} because a merge request is open."
-msgstr ""
+msgstr "Ваши Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð³ÑƒÑ‚ быть зафикÑированы в ветке %{branch_name}, так как открыт Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° ÑлиÑние."
msgid "Your changes have been committed. Commit %{commitId} %{commitStats}"
msgstr "Ваши Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð±Ñ‹Ð»Ð¸ зафикÑированы. Коммит %{commitId} %{commitStats}"
@@ -24742,9 +26122,18 @@ msgstr "Ваши Ñлужбы Ñ€Ð°Ð·Ð²Ñ‘Ñ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ ÑломаютÑÑ, и
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr "Ваше уÑтройÑтво было уÑпешно наÑтроено! Дайте ему Ð¸Ð¼Ñ Ð¸ зарегиÑтрируйте его на Ñервере GitLab."
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr "Ваши группы"
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24752,6 +26141,9 @@ msgid "Your issues will be imported in the background. Once finished, you'll get
msgstr ""
msgid "Your license is valid from"
+msgstr "Ваша Ð»Ð¸Ñ†ÐµÐ½Ð·Ð¸Ñ Ð´ÐµÐ¹Ñтвительна Ñ"
+
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
msgstr ""
msgid "Your message here"
@@ -24760,6 +26152,9 @@ msgstr ""
msgid "Your name"
msgstr "Ваше имÑ"
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr "Ваш новый токен SCIM"
@@ -24784,12 +26179,18 @@ msgstr "Ваш лимит проектов - %{limit} проектов! Пожа
msgid "Your projects"
msgstr "Ваши проекты"
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr "Ваш Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° доÑтуп был поÑтавлен в очередь на проверку."
-msgid "Your search didn't match any commits."
+msgid "Your response has been recorded."
msgstr ""
+msgid "Your search didn't match any commits."
+msgstr "По вашему запроÑу не найдено ни одного коммита."
+
msgid "Your subscription expired!"
msgstr ""
@@ -24834,6 +26235,9 @@ msgid "added a Zoom call to this issue"
msgstr ""
msgid "ago"
+msgstr "назад"
+
+msgid "alert"
msgstr ""
msgid "allowed to fail"
@@ -24861,10 +26265,10 @@ msgid "archived"
msgstr ""
msgid "assign yourself"
-msgstr ""
+msgstr "назначить ÑебÑ"
msgid "at risk"
-msgstr ""
+msgstr "под угрозой"
msgid "attach a new file"
msgstr ""
@@ -24878,6 +26282,9 @@ msgstr ""
msgid "branch name"
msgstr "Ð¸Ð¼Ñ Ð²ÐµÑ‚Ð²Ð¸"
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -25057,6 +26464,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -25075,17 +26485,20 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
msgid "ciReport|No changes to performance metrics"
-msgstr ""
+msgstr "Ðет изменений в метриках производительноÑти"
msgid "ciReport|No code quality issues found"
msgstr ""
msgid "ciReport|Performance metrics"
-msgstr ""
+msgstr "Метрики производительноÑти"
msgid "ciReport|Resolve with merge request"
msgstr ""
@@ -25093,6 +26506,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -25136,6 +26552,9 @@ msgstr[3] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr "комментарий"
@@ -25143,6 +26562,9 @@ msgid "commented on %{link_to_project}"
msgstr ""
msgid "commit %{commit_id}"
+msgstr "коммит %{commit_id}"
+
+msgid "committed"
msgstr ""
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
@@ -25154,9 +26576,12 @@ msgstr ""
msgid "connecting"
msgstr "подключение"
-msgid "container_name cannot be larger than %{max_length} chars"
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
+msgid "container_name cannot be larger than %{max_length} chars"
+msgstr "поле container_name не может быть больше, чем %{max_length} Ñимволов"
+
msgid "could not read private key, is the passphrase correct?"
msgstr ""
@@ -25206,6 +26631,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] "черновик"
@@ -25219,7 +26647,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr "Ñлемент не ÑвлÑетÑÑ Ð¸ÐµÑ€Ð°Ñ€Ñ…Ð¸ÐµÐ¹"
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -25252,11 +26683,11 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
-msgstr "иÑтек %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
+msgstr ""
-msgid "expires on %{milestone_due_date}"
-msgstr "иÑтекает %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
+msgstr ""
msgid "external_url"
msgstr ""
@@ -25269,10 +26700,10 @@ msgstr ""
msgid "file"
msgid_plural "files"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "файл"
+msgstr[1] "файла"
+msgstr[2] "файлов"
+msgstr[3] "файлов"
msgid "finding is not found or is already attached to a vulnerability"
msgstr ""
@@ -25299,7 +26730,7 @@ msgid "from"
msgstr ""
msgid "geo_node_name"
-msgstr ""
+msgstr "geo_node_name"
msgid "group"
msgstr ""
@@ -25317,14 +26748,23 @@ msgid "help"
msgstr "помощь"
msgid "here"
-msgstr ""
+msgstr "здеÑÑŒ"
msgid "https://your-bitbucket-server"
msgstr "https://ваш-bitbucket-server"
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr "Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¾Ð±Ñ€Ð°Ð·Ð°"
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25389,6 +26829,9 @@ msgstr "не Ñ Ñлектронной почты, которой вы владÐ
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25399,15 +26842,21 @@ msgid "is too long (maximum is 1000 entries)"
msgstr ""
msgid "issue"
-msgstr ""
+msgstr "обÑуждение"
msgid "issues at risk"
msgstr ""
msgid "issues need attention"
-msgstr ""
+msgstr "обÑуждений требуют вниманиÑ"
msgid "issues on track"
+msgstr "обÑуждений по плану"
+
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
msgstr ""
msgid "it is stored externally"
@@ -25423,10 +26872,10 @@ msgid "jigsaw is not defined"
msgstr ""
msgid "jira.issue.description.content"
-msgstr ""
+msgstr "jira.issue.description.content"
msgid "jira.issue.summary"
-msgstr ""
+msgstr "jira.issue.summary"
msgid "latest"
msgstr "поÑледние"
@@ -25449,6 +26898,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25490,10 +26942,10 @@ msgid "mrWidgetCommitsAdded|1 merge commit"
msgstr "1 коммит cлиÑниÑ"
msgid "mrWidgetNothingToMerge|Currently there are no changes in this merge request's source branch. Please push new commits or use a different branch."
-msgstr ""
+msgstr "Ð’ наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² иÑходной ветке запроÑа на ÑлиÑние отÑутÑтвуют. ПожалуйÑта, отправьте (push) новые коммиты или иÑпользуйте другую ветку."
msgid "mrWidgetNothingToMerge|Interested parties can even contribute by pushing commits if they want to."
-msgstr ""
+msgstr "ЗаинтереÑованные Ñтороны даже могут вноÑить Ñвой вклад при желании, отпралÑÑ (push) коммиты."
msgid "mrWidgetNothingToMerge|Merge requests are a place to propose changes you have made to a project and discuss those changes with others."
msgstr ""
@@ -25520,7 +26972,7 @@ msgid "mrWidget|Added to the merge train by"
msgstr "Добавлено в цепочку ÑлиÑниÑ"
msgid "mrWidget|Allows commits from members who can merge to the target branch"
-msgstr ""
+msgstr "ПозволÑет выполнÑÑ‚ÑŒ коммиты учаÑтникам, которые могут выполнÑÑ‚ÑŒ ÑлиÑние Ñ Ñ†ÐµÐ»ÐµÐ²Ð¾Ð¹ веткой"
msgid "mrWidget|An error occurred while removing your approval."
msgstr "произошла ошибка при удалении вашего подтверждениÑ."
@@ -25579,7 +27031,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr "Ðа данный момент ÑтатиÑтика Ñ€Ð°Ð·Ð²Ñ‘Ñ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð½ÐµÐ´Ð¾Ñтупна"
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25697,7 +27149,7 @@ msgid "mrWidget|The changes will be merged into"
msgstr "Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð±ÑƒÐ´ÑƒÑ‚ Ñлиты в"
msgid "mrWidget|The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure"
-msgstr ""
+msgstr "Ð¡Ð±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ Ð´Ð»Ñ Ñтого запроÑа на ÑлиÑние завершилаÑÑŒ Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ¾Ð¹. ПожалуйÑта повторите задание или отправьте новый коммит чтобы иÑправить ошибку"
msgid "mrWidget|The source branch HEAD has recently changed. Please reload the page and review the changes before merging"
msgstr "СÑылка HEAD иÑходной ветви недавно изменилаÑÑŒ. ПожалуйÑта, обновите Ñтраницу и проÑмотрите Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿ÐµÑ€ÐµÐ´ ÑлиÑнием"
@@ -25759,9 +27211,6 @@ msgstr "Ð’Ñ‹ можете выполнить Ñтот Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° ÑлиÑ
msgid "mrWidget|Your password"
msgstr "Ваш пароль"
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr "ветка не ÑущеÑтвует."
@@ -25771,15 +27220,6 @@ msgstr "командную Ñтроку"
msgid "mrWidget|into"
msgstr "в"
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr "будет добавлен в цепочку ÑлиÑÐ½Ð¸Ñ Ð¿Ñ€Ð¸ уÑпешном выполнении Ñборочной линии"
@@ -25792,6 +27232,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr "н/д"
@@ -25835,6 +27278,9 @@ msgid "nounSeries|%{item}, and %{lastItem}"
msgstr "%{item}, и %{lastItem}"
msgid "on track"
+msgstr "по плану"
+
+msgid "open issue"
msgstr ""
msgid "opened %{timeAgoString} by %{user}"
@@ -25844,7 +27290,7 @@ msgid "opened %{timeAgo}"
msgstr ""
msgid "or"
-msgstr ""
+msgstr "или"
msgid "out of %d total test"
msgid_plural "out of %d total tests"
@@ -25864,7 +27310,7 @@ msgid "password"
msgstr "пароль"
msgid "pending comment"
-msgstr ""
+msgstr "ожидающий комментарий"
msgid "pending removal"
msgstr ""
@@ -25872,9 +27318,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr "pod_name не может быть больше, чем %{max_length} Ñимволов"
@@ -25901,11 +27356,17 @@ msgstr[1] "проектов"
msgstr[2] "проектов"
msgstr[3] "проектов"
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr "логотип проекта"
msgid "projects"
-msgstr ""
+msgstr "проекты"
msgid "push to your repository, create pipelines, create issues or add comments. To reduce storage capacity, delete unused repositories, artifacts, wikis, issues, and pipelines."
msgstr ""
@@ -25917,7 +27378,7 @@ msgid "register"
msgstr ""
msgid "relates to"
-msgstr ""
+msgstr "отноÑитÑÑ Ðº"
msgid "released %{time}"
msgstr ""
@@ -25942,10 +27403,10 @@ msgstr "отображенное отличие"
msgid "reply"
msgid_plural "replies"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "ответ"
+msgstr[1] "ответа"
+msgstr[2] "ответов"
+msgstr[3] "ответов"
msgid "reset it."
msgstr "ÑброÑить."
@@ -25953,6 +27414,9 @@ msgstr "ÑброÑить."
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr "Ñчёт"
@@ -25960,7 +27424,7 @@ msgid "security Reports|There was an error creating the merge request"
msgstr ""
msgid "settings saved, but not activated"
-msgstr ""
+msgstr "наÑтройки Ñохранены, но не применены"
msgid "severity|Critical"
msgstr "КритичеÑкий"
@@ -26019,11 +27483,11 @@ msgstr "запущено"
msgid "started a discussion on %{design_link}"
msgstr "начата диÑкуÑÑÐ¸Ñ Ð¿Ð¾ %{design_link}"
-msgid "started on %{milestone_start_date}"
-msgstr "началоÑÑŒ Ñ %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
+msgstr ""
-msgid "starts on %{milestone_start_date}"
-msgstr "начинаетÑÑ Ñ %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
+msgstr ""
msgid "stuck"
msgstr "заÑÑ‚Ñ€Ñл"
@@ -26032,13 +27496,13 @@ msgid "success"
msgstr "уÑпешно"
msgid "suggestPipeline|1/2: Choose a template"
-msgstr ""
+msgstr "1/2: Выберите шаблон"
msgid "suggestPipeline|2/2: Commit your changes"
-msgstr ""
+msgstr "2/2: ЗафикÑируйте изменениÑ"
msgid "suggestPipeline|Commit the changes and your pipeline will automatically run for the first time."
-msgstr ""
+msgstr "ЗафикÑируйте Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¸ ÑÐ±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки запуÑтитÑÑ Ð² первый раз."
msgid "suggestPipeline|We recommend the %{boldStart}Code Quality%{boldEnd} template, which will add a report widget to your Merge Requests. This way you’ll learn about code quality degradations much sooner. %{footerStart} Goodbye technical debt! %{footerEnd}"
msgstr ""
@@ -26065,7 +27529,7 @@ msgid "to list"
msgstr "к ÑпиÑку"
msgid "toggle collapse"
-msgstr ""
+msgstr "Ñвернуть/развернуть"
msgid "toggle dropdown"
msgstr ""
@@ -26074,7 +27538,7 @@ msgid "triggered"
msgstr "запущено"
msgid "unicode domains should use IDNA encoding"
-msgstr ""
+msgstr "домены, запиÑанные юникодом, должны иÑпользовать IDNA-кодировку"
msgid "updated"
msgstr "обновлено"
@@ -26085,6 +27549,12 @@ msgstr "обновлено %{timeAgo}"
msgid "updated %{time_ago}"
msgstr "обновлено %{time_ago}"
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr "аватар пользователÑ"
@@ -26112,6 +27582,9 @@ msgstr "проÑмотреть Ñто на GitLab"
msgid "view the blob"
msgstr "проÑмотреть бинарные данные"
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -26139,6 +27612,9 @@ msgstr "отклонено"
msgid "wiki page"
msgstr "wiki-Ñтраница"
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr "Ñ %{additions} добавлениÑми, %{deletions} удалениÑми."
diff --git a/locale/sk_SK/gitlab.po b/locale/sk_SK/gitlab.po
index 57ed9829c0c..f2be261bd5f 100644
--- a/locale/sk_SK/gitlab.po
+++ b/locale/sk_SK/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: sk\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:35\n"
+"PO-Revision-Date: 2020-06-08 15:19\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -80,6 +80,20 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -108,6 +122,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -139,6 +160,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -237,6 +265,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+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[3] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -279,6 +314,20 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -305,6 +354,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -390,6 +442,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -399,6 +454,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -411,6 +469,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -444,12 +526,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -465,6 +556,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -509,6 +606,12 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -668,6 +771,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -908,6 +1014,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -938,6 +1047,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -947,6 +1059,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -983,7 +1098,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -1034,6 +1152,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -1046,9 +1167,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -1094,9 +1212,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1187,12 +1302,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1229,7 +1338,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1238,6 +1347,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1284,7 +1396,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1299,6 +1411,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1308,9 +1423,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1326,7 +1447,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1392,6 +1516,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1482,16 +1609,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1818,6 +1945,15 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
@@ -1825,58 +1961,103 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
+msgstr ""
+
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1885,16 +2066,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -2068,6 +2267,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2233,9 +2435,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2257,6 +2456,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2332,6 +2534,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2368,9 +2573,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2386,6 +2597,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2395,6 +2609,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2419,12 +2636,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2434,9 +2645,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2500,6 +2717,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2576,12 +2796,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2591,12 +2805,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2705,6 +2925,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2717,7 +2940,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2831,6 +3054,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2911,15 +3137,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2977,6 +3221,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2998,9 +3245,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -3019,6 +3263,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -3049,6 +3296,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -3064,6 +3314,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3541,16 +3794,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3574,7 +3827,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3583,6 +3836,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3601,6 +3857,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3631,9 +3890,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3661,6 +3917,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3736,7 +3998,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3751,6 +4013,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3787,6 +4052,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3829,6 +4100,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3847,6 +4121,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3952,15 +4229,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4309,9 +4577,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4324,6 +4589,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4336,6 +4604,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4363,9 +4634,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4405,6 +4673,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4600,6 +4871,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4621,9 +4895,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4675,7 +4946,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4702,6 +4973,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4780,10 +5054,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4942,6 +5216,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5176,9 +5456,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5257,6 +5534,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5287,6 +5567,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5296,9 +5579,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5356,6 +5645,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5374,6 +5666,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5413,6 +5708,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5422,6 +5720,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5458,6 +5759,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5621,7 +5925,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5645,9 +5952,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5681,9 +5985,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5732,16 +6033,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5768,6 +6063,20 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5780,6 +6089,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5804,27 +6116,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5846,10 +6170,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5871,9 +6192,6 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5895,6 +6213,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5922,12 +6243,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5946,7 +6261,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5955,7 +6273,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5994,10 +6312,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -6084,6 +6402,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -6129,9 +6450,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6147,9 +6465,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6246,7 +6561,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6264,9 +6579,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6285,9 +6597,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6297,9 +6606,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6342,6 +6648,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6354,6 +6663,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6393,6 +6705,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6426,6 +6744,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6477,9 +6798,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6516,6 +6834,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6540,6 +6861,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6588,6 +6912,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6612,6 +6939,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6865,6 +7195,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6901,6 +7234,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6943,6 +7279,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -7034,13 +7376,6 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -7078,12 +7413,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -7093,9 +7422,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7216,12 +7542,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7243,13 +7575,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7369,10 +7701,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7381,9 +7713,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7393,6 +7740,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7420,12 +7770,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7435,6 +7800,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7447,6 +7818,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7676,6 +8050,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7724,6 +8101,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7748,6 +8128,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7895,6 +8278,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7910,6 +8296,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -8003,6 +8392,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -8012,9 +8404,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -8042,6 +8431,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8165,6 +8557,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8189,10 +8584,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8249,7 +8644,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8462,10 +8857,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8477,12 +8872,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8552,7 +8941,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8657,9 +9055,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8675,6 +9070,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8726,10 +9124,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8771,13 +9169,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8789,7 +9187,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8828,6 +9226,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8846,6 +9247,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8879,6 +9283,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8894,6 +9301,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8903,6 +9313,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8981,18 +9394,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -9119,6 +9520,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9194,7 +9598,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9257,6 +9661,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9269,6 +9679,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9278,15 +9691,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9305,6 +9727,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9320,9 +9745,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9413,6 +9844,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9425,6 +9859,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9434,9 +9871,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9452,24 +9886,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9479,6 +9934,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9710,9 +10168,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9752,15 +10207,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9938,6 +10393,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9947,10 +10408,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -10001,6 +10462,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -10052,6 +10519,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -10070,6 +10540,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -10079,6 +10552,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10331,9 +10810,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10367,9 +10843,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10532,12 +11005,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10571,6 +11053,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10583,10 +11071,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10604,10 +11095,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10625,12 +11119,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10697,9 +11197,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10901,6 +11398,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -11006,6 +11506,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -11015,6 +11518,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -11125,6 +11631,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -11134,6 +11643,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11284,6 +11796,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11293,7 +11808,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11302,6 +11820,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11314,7 +11838,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11332,13 +11859,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11350,6 +11877,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11359,6 +11889,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11368,10 +11901,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11464,10 +11997,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11500,6 +12033,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11533,6 +12069,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11557,18 +12099,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11621,6 +12181,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11660,6 +12244,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11696,18 +12286,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11720,6 +12319,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11783,6 +12385,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11795,6 +12400,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11852,6 +12484,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11897,6 +12532,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11909,19 +12568,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -12047,6 +12709,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -12086,6 +12751,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12267,6 +12935,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12351,6 +13022,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12372,9 +13046,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12402,6 +13073,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12414,6 +13088,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12438,15 +13115,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12589,6 +13260,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12604,6 +13278,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12701,6 +13378,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12815,10 +13495,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12845,6 +13525,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12896,9 +13579,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12908,9 +13588,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -13088,6 +13765,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -13097,9 +13777,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -13112,6 +13789,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -13145,6 +13825,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13193,9 +13876,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13256,7 +13948,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13274,6 +13966,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13295,9 +13990,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13319,19 +14011,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13355,6 +14050,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13413,6 +14129,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13431,6 +14153,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13467,6 +14192,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13531,6 +14259,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13540,6 +14325,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13549,21 +14340,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13624,6 +14433,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13738,6 +14550,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13747,6 +14562,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13759,9 +14577,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13771,9 +14586,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13807,6 +14619,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13838,6 +14698,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13904,6 +14767,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13961,6 +14827,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13979,18 +14848,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -14081,12 +14941,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -14111,6 +14977,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14246,6 +15115,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14270,6 +15142,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14384,9 +15259,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14453,6 +15334,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14462,9 +15352,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14532,7 +15419,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14577,7 +15464,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14592,6 +15479,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14622,7 +15512,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14670,6 +15560,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14688,6 +15581,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14709,6 +15605,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14796,6 +15698,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14814,6 +15719,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14844,22 +15752,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14892,6 +15815,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14979,6 +15905,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14997,6 +15926,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -15039,9 +15971,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -15063,9 +16001,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -15087,9 +16022,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15198,6 +16130,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15258,15 +16193,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15279,30 +16223,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15318,6 +16286,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15354,6 +16325,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15447,6 +16424,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15522,6 +16502,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15612,6 +16595,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15648,6 +16634,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15867,9 +16856,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15915,9 +16901,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -16062,12 +17045,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -16098,6 +17075,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -16119,6 +17099,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -16149,6 +17132,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -16173,7 +17159,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -16182,6 +17168,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16296,9 +17285,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16464,6 +17450,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16509,6 +17498,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16659,6 +17651,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16752,12 +17747,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16833,9 +17834,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16854,30 +17852,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -17013,9 +18065,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -17025,6 +18074,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -17127,6 +18182,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -17136,9 +18194,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -17175,9 +18230,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17275,6 +18327,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17321,6 +18388,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17342,6 +18421,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17411,6 +18493,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17453,6 +18541,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17492,6 +18583,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17543,6 +18637,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17573,6 +18670,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17588,7 +18688,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17694,6 +18797,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17730,6 +18836,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17745,10 +18854,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17763,6 +18875,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17784,10 +18902,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17861,6 +18976,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17873,6 +18991,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -18021,6 +19145,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -18084,9 +19211,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -18123,9 +19247,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18255,9 +19376,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18315,6 +19442,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18345,10 +19475,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18457,9 +19587,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18472,9 +19608,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18484,24 +19617,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18637,6 +19770,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18718,6 +19854,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18769,12 +19908,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18820,9 +19965,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18895,6 +20049,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -19060,6 +20220,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -19096,6 +20259,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -19180,6 +20346,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -19198,7 +20367,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19237,15 +20406,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19270,12 +20439,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19298,6 +20476,16 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19484,6 +20672,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19520,9 +20711,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19619,6 +20816,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19658,6 +20858,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19706,6 +20909,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19823,6 +21032,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19988,7 +21200,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -20063,6 +21275,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -20189,6 +21404,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -20216,6 +21434,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20243,6 +21464,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20423,9 +21647,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20510,6 +21740,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20537,9 +21770,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20793,6 +22023,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20878,9 +22111,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20917,9 +22147,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20960,6 +22196,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -21134,6 +22373,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -21182,6 +22424,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21257,6 +22502,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21329,6 +22583,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21392,6 +22649,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21476,6 +22736,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21515,6 +22778,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21674,7 +22937,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21701,6 +22964,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21737,12 +23003,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21755,12 +23027,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21779,7 +23063,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21788,9 +23072,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21845,9 +23126,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -22094,6 +23381,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -22162,6 +23452,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22282,6 +23578,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22339,15 +23638,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22363,9 +23656,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22384,6 +23674,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22495,6 +23788,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22552,10 +23848,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22564,6 +23860,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22603,6 +23902,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22612,9 +23914,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22864,18 +24172,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22894,6 +24196,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22912,6 +24217,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22936,9 +24244,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22948,12 +24253,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22963,12 +24274,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22987,12 +24304,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -23017,7 +24340,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -23092,9 +24415,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23341,6 +24661,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23401,6 +24727,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23428,7 +24757,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23470,6 +24802,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23520,6 +24855,9 @@ msgstr[3] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23583,6 +24921,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23664,9 +25005,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23697,9 +25035,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23808,6 +25143,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23820,6 +25158,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23841,7 +25182,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23883,9 +25230,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23925,12 +25269,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23968,9 +25321,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -24004,9 +25354,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -24127,10 +25474,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -24139,10 +25489,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24259,6 +25609,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24286,6 +25639,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24301,6 +25657,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24379,6 +25738,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24427,6 +25789,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24442,7 +25807,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24535,6 +25900,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24562,6 +25930,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24580,6 +25951,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24613,7 +25990,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24649,7 +26029,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24742,9 +26122,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24754,12 +26143,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24784,9 +26179,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24836,6 +26237,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24878,6 +26282,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -25057,6 +26464,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -25075,6 +26485,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -25093,6 +26506,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -25136,6 +26552,9 @@ msgstr[3] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -25145,6 +26564,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -25154,6 +26576,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25206,6 +26631,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -25219,7 +26647,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -25252,10 +26683,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25322,9 +26753,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25389,6 +26829,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25410,6 +26853,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25449,6 +26898,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25579,7 +27031,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25759,9 +27211,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25771,15 +27220,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25792,6 +27232,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25837,6 +27280,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25872,9 +27318,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25901,6 +27356,12 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25953,6 +27414,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -26019,10 +27483,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -26085,6 +27549,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -26112,6 +27582,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -26139,6 +27612,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/sl_SI/gitlab.po b/locale/sl_SI/gitlab.po
index 283b8912e67..26c53b6ac9a 100644
--- a/locale/sl_SI/gitlab.po
+++ b/locale/sl_SI/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: sl\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:34\n"
+"PO-Revision-Date: 2020-06-08 15:19\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -80,6 +80,20 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -108,6 +122,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -139,6 +160,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -237,6 +265,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+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[3] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -279,6 +314,20 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -305,6 +354,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -390,6 +442,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -399,6 +454,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -411,6 +469,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -444,12 +526,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -465,6 +556,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -509,6 +606,12 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -668,6 +771,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -908,6 +1014,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -938,6 +1047,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -947,6 +1059,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -983,7 +1098,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -1034,6 +1152,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -1046,9 +1167,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -1094,9 +1212,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1187,12 +1302,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1229,7 +1338,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1238,6 +1347,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1284,7 +1396,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1299,6 +1411,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1308,9 +1423,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1326,7 +1447,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1392,6 +1516,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1482,16 +1609,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1818,6 +1945,15 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
@@ -1825,58 +1961,103 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
+msgstr ""
+
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1885,16 +2066,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -2068,6 +2267,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2233,9 +2435,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2257,6 +2456,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2332,6 +2534,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2368,9 +2573,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2386,6 +2597,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2395,6 +2609,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2419,12 +2636,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2434,9 +2645,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2500,6 +2717,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2576,12 +2796,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2591,12 +2805,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2705,6 +2925,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2717,7 +2940,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2831,6 +3054,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2911,15 +3137,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2977,6 +3221,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2998,9 +3245,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -3019,6 +3263,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -3049,6 +3296,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -3064,6 +3314,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3541,16 +3794,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3574,7 +3827,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3583,6 +3836,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3601,6 +3857,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3631,9 +3890,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3661,6 +3917,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3736,7 +3998,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3751,6 +4013,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3787,6 +4052,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3829,6 +4100,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3847,6 +4121,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3952,15 +4229,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4309,9 +4577,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4324,6 +4589,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4336,6 +4604,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4363,9 +4634,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4405,6 +4673,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4600,6 +4871,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4621,9 +4895,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4675,7 +4946,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4702,6 +4973,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4780,10 +5054,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4942,6 +5216,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5176,9 +5456,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5257,6 +5534,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5287,6 +5567,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5296,9 +5579,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5356,6 +5645,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5374,6 +5666,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5413,6 +5708,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5422,6 +5720,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5458,6 +5759,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5621,7 +5925,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5645,9 +5952,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5681,9 +5985,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5732,16 +6033,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5768,6 +6063,20 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5780,6 +6089,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5804,27 +6116,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5846,10 +6170,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5871,9 +6192,6 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5895,6 +6213,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5922,12 +6243,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5946,7 +6261,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5955,7 +6273,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5994,10 +6312,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -6084,6 +6402,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -6129,9 +6450,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6147,9 +6465,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6246,7 +6561,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6264,9 +6579,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6285,9 +6597,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6297,9 +6606,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6342,6 +6648,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6354,6 +6663,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6393,6 +6705,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6426,6 +6744,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6477,9 +6798,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6516,6 +6834,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6540,6 +6861,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6588,6 +6912,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6612,6 +6939,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6865,6 +7195,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6901,6 +7234,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6943,6 +7279,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -7034,13 +7376,6 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -7078,12 +7413,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -7093,9 +7422,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7216,12 +7542,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7243,13 +7575,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7369,10 +7701,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7381,9 +7713,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7393,6 +7740,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7420,12 +7770,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7435,6 +7800,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7447,6 +7818,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7676,6 +8050,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7724,6 +8101,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7748,6 +8128,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7895,6 +8278,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7910,6 +8296,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -8003,6 +8392,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -8012,9 +8404,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -8042,6 +8431,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8165,6 +8557,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8189,10 +8584,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8249,7 +8644,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8462,10 +8857,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8477,12 +8872,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8552,7 +8941,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8657,9 +9055,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8675,6 +9070,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8726,10 +9124,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8771,13 +9169,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8789,7 +9187,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8828,6 +9226,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8846,6 +9247,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8879,6 +9283,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8894,6 +9301,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8903,6 +9313,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8981,18 +9394,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -9119,6 +9520,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9194,7 +9598,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9257,6 +9661,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9269,6 +9679,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9278,15 +9691,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9305,6 +9727,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9320,9 +9745,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9413,6 +9844,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9425,6 +9859,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9434,9 +9871,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9452,24 +9886,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9479,6 +9934,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9710,9 +10168,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9752,15 +10207,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9938,6 +10393,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9947,10 +10408,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -10001,6 +10462,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -10052,6 +10519,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -10070,6 +10540,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -10079,6 +10552,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10331,9 +10810,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10367,9 +10843,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10532,12 +11005,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10571,6 +11053,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10583,10 +11071,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10604,10 +11095,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10625,12 +11119,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10697,9 +11197,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10901,6 +11398,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -11006,6 +11506,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -11015,6 +11518,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -11125,6 +11631,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -11134,6 +11643,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11284,6 +11796,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11293,7 +11808,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11302,6 +11820,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11314,7 +11838,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11332,13 +11859,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11350,6 +11877,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11359,6 +11889,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11368,10 +11901,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11464,10 +11997,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11500,6 +12033,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11533,6 +12069,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11557,18 +12099,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11621,6 +12181,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11660,6 +12244,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11696,18 +12286,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11720,6 +12319,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11783,6 +12385,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11795,6 +12400,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11852,6 +12484,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11897,6 +12532,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11909,19 +12568,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -12047,6 +12709,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -12086,6 +12751,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12267,6 +12935,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12351,6 +13022,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12372,9 +13046,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12402,6 +13073,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12414,6 +13088,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12438,15 +13115,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12589,6 +13260,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12604,6 +13278,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12701,6 +13378,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12815,10 +13495,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12845,6 +13525,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12896,9 +13579,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12908,9 +13588,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -13088,6 +13765,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -13097,9 +13777,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -13112,6 +13789,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -13145,6 +13825,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13193,9 +13876,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13256,7 +13948,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13274,6 +13966,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13295,9 +13990,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13319,19 +14011,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13355,6 +14050,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13413,6 +14129,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13431,6 +14153,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13467,6 +14192,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13531,6 +14259,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13540,6 +14325,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13549,21 +14340,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13624,6 +14433,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13738,6 +14550,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13747,6 +14562,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13759,9 +14577,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13771,9 +14586,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13807,6 +14619,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13838,6 +14698,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13904,6 +14767,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13961,6 +14827,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13979,18 +14848,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -14081,12 +14941,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -14111,6 +14977,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14246,6 +15115,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14270,6 +15142,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14384,9 +15259,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14453,6 +15334,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14462,9 +15352,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14532,7 +15419,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14577,7 +15464,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14592,6 +15479,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14622,7 +15512,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14670,6 +15560,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14688,6 +15581,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14709,6 +15605,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14796,6 +15698,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14814,6 +15719,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14844,22 +15752,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14892,6 +15815,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14979,6 +15905,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14997,6 +15926,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -15039,9 +15971,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -15063,9 +16001,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -15087,9 +16022,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15198,6 +16130,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15258,15 +16193,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15279,30 +16223,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15318,6 +16286,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15354,6 +16325,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15447,6 +16424,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15522,6 +16502,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15612,6 +16595,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15648,6 +16634,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15867,9 +16856,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15915,9 +16901,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -16062,12 +17045,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -16098,6 +17075,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -16119,6 +17099,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -16149,6 +17132,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -16173,7 +17159,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -16182,6 +17168,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16296,9 +17285,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16464,6 +17450,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16509,6 +17498,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16659,6 +17651,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16752,12 +17747,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16833,9 +17834,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16854,30 +17852,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -17013,9 +18065,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -17025,6 +18074,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -17127,6 +18182,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -17136,9 +18194,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -17175,9 +18230,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17275,6 +18327,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17321,6 +18388,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17342,6 +18421,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17411,6 +18493,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17453,6 +18541,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17492,6 +18583,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17543,6 +18637,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17573,6 +18670,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17588,7 +18688,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17694,6 +18797,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17730,6 +18836,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17745,10 +18854,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17763,6 +18875,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17784,10 +18902,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17861,6 +18976,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17873,6 +18991,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -18021,6 +19145,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -18084,9 +19211,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -18123,9 +19247,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18255,9 +19376,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18315,6 +19442,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18345,10 +19475,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18457,9 +19587,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18472,9 +19608,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18484,24 +19617,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18637,6 +19770,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18718,6 +19854,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18769,12 +19908,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18820,9 +19965,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18895,6 +20049,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -19060,6 +20220,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -19096,6 +20259,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -19180,6 +20346,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -19198,7 +20367,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19237,15 +20406,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19270,12 +20439,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19298,6 +20476,16 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19484,6 +20672,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19520,9 +20711,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19619,6 +20816,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19658,6 +20858,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19706,6 +20909,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19823,6 +21032,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19988,7 +21200,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -20063,6 +21275,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -20189,6 +21404,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -20216,6 +21434,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20243,6 +21464,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20423,9 +21647,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20510,6 +21740,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20537,9 +21770,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20793,6 +22023,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20878,9 +22111,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20917,9 +22147,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20960,6 +22196,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -21134,6 +22373,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -21182,6 +22424,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21257,6 +22502,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21329,6 +22583,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21392,6 +22649,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21476,6 +22736,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21515,6 +22778,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21674,7 +22937,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21701,6 +22964,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21737,12 +23003,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21755,12 +23027,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21779,7 +23063,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21788,9 +23072,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21845,9 +23126,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -22094,6 +23381,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -22162,6 +23452,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22282,6 +23578,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22339,15 +23638,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22363,9 +23656,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22384,6 +23674,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22495,6 +23788,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22552,10 +23848,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22564,6 +23860,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22603,6 +23902,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22612,9 +23914,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22864,18 +24172,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22894,6 +24196,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22912,6 +24217,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22936,9 +24244,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22948,12 +24253,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22963,12 +24274,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22987,12 +24304,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -23017,7 +24340,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -23092,9 +24415,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23341,6 +24661,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23401,6 +24727,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23428,7 +24757,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23470,6 +24802,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23520,6 +24855,9 @@ msgstr[3] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23583,6 +24921,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23664,9 +25005,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23697,9 +25035,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23808,6 +25143,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23820,6 +25158,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23841,7 +25182,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23883,9 +25230,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23925,12 +25269,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23968,9 +25321,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -24004,9 +25354,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -24127,10 +25474,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -24139,10 +25489,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24259,6 +25609,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24286,6 +25639,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24301,6 +25657,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24379,6 +25738,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24427,6 +25789,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24442,7 +25807,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24535,6 +25900,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24562,6 +25930,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24580,6 +25951,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24613,7 +25990,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24649,7 +26029,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24742,9 +26122,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24754,12 +26143,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24784,9 +26179,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24836,6 +26237,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24878,6 +26282,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -25057,6 +26464,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -25075,6 +26485,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -25093,6 +26506,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -25136,6 +26552,9 @@ msgstr[3] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -25145,6 +26564,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -25154,6 +26576,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25206,6 +26631,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -25219,7 +26647,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -25252,10 +26683,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25322,9 +26753,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25389,6 +26829,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25410,6 +26853,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25449,6 +26898,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25579,7 +27031,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25759,9 +27211,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25771,15 +27220,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25792,6 +27232,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25837,6 +27280,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25872,9 +27318,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25901,6 +27356,12 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25953,6 +27414,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -26019,10 +27483,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -26085,6 +27549,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -26112,6 +27582,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -26139,6 +27612,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/sq_AL/gitlab.po b/locale/sq_AL/gitlab.po
index 0aac7350673..79f7b5a1c5a 100644
--- a/locale/sq_AL/gitlab.po
+++ b/locale/sq_AL/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: sq\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:36\n"
+"PO-Revision-Date: 2020-06-08 15:19\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,13 +8991,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8627,7 +9009,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] ""
msgstr[1] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/sr_CS/gitlab.po b/locale/sr_CS/gitlab.po
index b50e11c7485..ee9f5a37b3b 100644
--- a/locale/sr_CS/gitlab.po
+++ b/locale/sr_CS/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: sr-CS\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:34\n"
+"PO-Revision-Date: 2020-06-08 15:13\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -77,6 +77,18 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -101,6 +113,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -128,12 +146,18 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "%d error"
-msgid_plural "%d errors"
+msgid "%d day"
+msgid_plural "%d days"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d error"
+msgid_plural "%d errors"
+msgstr[0] "%d greška"
+msgstr[1] "%d greške"
+msgstr[2] "%d grešaka"
+
msgid "%d exporter"
msgid_plural "%d exporters"
msgstr[0] ""
@@ -212,6 +236,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+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] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -248,6 +278,18 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -272,6 +314,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -353,6 +398,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -362,6 +410,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -374,6 +425,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -407,12 +482,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -428,6 +512,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -470,6 +560,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -623,6 +719,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -845,6 +944,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -875,6 +977,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -884,6 +989,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -920,7 +1028,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -971,6 +1082,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -983,9 +1097,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -1031,9 +1142,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1124,12 +1232,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1166,7 +1268,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1175,6 +1277,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1220,7 +1325,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1235,6 +1340,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1244,9 +1352,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1262,7 +1376,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1328,6 +1445,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1418,16 +1538,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1754,64 +1874,118 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
+msgstr ""
+
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1820,16 +1994,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -2003,6 +2195,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2168,9 +2363,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2192,6 +2384,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2267,6 +2462,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2303,9 +2501,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2321,6 +2525,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2330,6 +2537,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2354,12 +2564,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2369,9 +2573,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2435,6 +2645,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2507,12 +2720,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2522,12 +2729,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2636,6 +2849,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2648,7 +2864,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2762,6 +2978,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2840,15 +3059,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2906,6 +3143,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2927,9 +3167,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2948,6 +3185,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2978,6 +3218,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2993,6 +3236,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3470,16 +3716,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3503,7 +3749,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3512,6 +3758,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3530,6 +3779,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3560,9 +3812,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3590,6 +3839,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3665,7 +3920,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3680,6 +3935,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3716,6 +3974,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3758,6 +4022,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3776,6 +4043,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3881,15 +4151,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4238,9 +4499,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4253,6 +4511,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4265,6 +4526,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4292,9 +4556,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4334,6 +4595,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4529,6 +4793,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4550,9 +4817,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4604,7 +4868,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4631,6 +4895,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4709,10 +4976,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4871,6 +5138,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5105,9 +5378,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5186,6 +5456,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5216,6 +5489,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5225,9 +5501,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5285,6 +5567,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5303,6 +5588,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5342,6 +5630,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5351,6 +5642,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5387,6 +5681,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5549,7 +5846,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5573,9 +5873,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5609,9 +5906,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5660,16 +5954,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5696,6 +5984,18 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5708,6 +6008,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5732,27 +6035,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5774,10 +6089,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5798,9 +6110,6 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5822,6 +6131,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5849,12 +6161,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5873,7 +6179,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5882,7 +6191,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5921,10 +6230,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -6011,6 +6320,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -6056,9 +6368,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6074,9 +6383,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6173,7 +6479,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6191,9 +6497,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6212,9 +6515,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6224,9 +6524,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6269,6 +6566,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6281,6 +6581,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6320,6 +6623,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6353,6 +6662,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6404,9 +6716,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6443,6 +6752,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6467,6 +6779,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6515,6 +6830,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6539,6 +6857,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6791,6 +7112,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6827,6 +7151,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6869,6 +7196,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6959,12 +7292,6 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -7001,12 +7328,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -7016,9 +7337,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7136,12 +7454,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7163,13 +7487,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7289,10 +7613,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7301,9 +7625,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7313,6 +7652,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7340,12 +7682,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7355,6 +7712,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7367,6 +7730,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7595,6 +7961,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7643,6 +8012,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7667,6 +8039,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7814,6 +8189,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7829,6 +8207,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7922,6 +8303,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7931,9 +8315,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7961,6 +8342,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8084,6 +8468,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8108,10 +8495,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8168,7 +8555,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8381,10 +8768,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8396,12 +8783,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8471,7 +8852,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8576,9 +8966,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8594,6 +8981,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8645,10 +9035,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8690,13 +9080,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8708,7 +9098,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8747,6 +9137,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8765,6 +9158,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8798,6 +9194,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8813,6 +9212,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8822,6 +9224,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8900,18 +9305,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -9038,6 +9431,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9113,7 +9509,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9176,6 +9572,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9188,6 +9590,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9197,15 +9602,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9224,6 +9638,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9239,9 +9656,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9332,6 +9755,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9344,6 +9770,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9353,9 +9782,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9371,24 +9797,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9398,6 +9845,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9629,9 +10079,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9671,15 +10118,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9857,6 +10304,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9866,10 +10319,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9920,6 +10373,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9971,6 +10430,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9989,6 +10451,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9998,6 +10463,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10250,9 +10721,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10286,9 +10754,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10451,12 +10916,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10490,6 +10964,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10502,10 +10982,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10523,10 +11006,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10544,12 +11030,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10616,9 +11108,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10820,6 +11309,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10925,6 +11417,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10934,6 +11429,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -11042,6 +11540,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -11051,6 +11552,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11201,6 +11705,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11210,7 +11717,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11219,6 +11729,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11231,7 +11747,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11249,13 +11768,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11267,6 +11786,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11276,6 +11798,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11285,10 +11810,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11381,10 +11906,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11417,6 +11942,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11450,6 +11978,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11474,18 +12008,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11537,6 +12089,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11576,6 +12152,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11612,18 +12194,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11636,6 +12227,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11699,6 +12293,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11711,6 +12308,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11768,6 +12392,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11813,6 +12440,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11825,19 +12476,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
+msgstr ""
+
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira integration not configured."
+msgid "JiraService| on branch %{branch_link}"
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11963,6 +12617,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -12002,6 +12659,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12182,6 +12842,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12266,6 +12929,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12287,9 +12953,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12317,6 +12980,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12329,6 +12995,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12353,15 +13022,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12500,6 +13163,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12515,6 +13181,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12611,6 +13280,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12725,10 +13397,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12755,6 +13427,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12806,9 +13481,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12818,9 +13490,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12998,6 +13667,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -13007,9 +13679,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -13022,6 +13691,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -13055,6 +13727,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13103,9 +13778,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13166,7 +13850,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13184,6 +13868,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13205,9 +13892,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13229,19 +13913,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13265,6 +13952,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13322,6 +14030,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13340,6 +14054,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13376,6 +14093,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13439,6 +14159,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13448,6 +14225,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13457,21 +14240,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13532,6 +14333,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13646,6 +14450,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13655,6 +14462,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13667,9 +14477,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13679,9 +14486,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13715,6 +14519,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13745,6 +14597,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13811,6 +14666,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13868,6 +14726,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13886,18 +14747,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13988,12 +14840,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -14018,6 +14876,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14153,6 +15014,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14177,6 +15041,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14291,9 +15158,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14360,6 +15233,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14369,9 +15251,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14438,7 +15317,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14483,7 +15362,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14498,6 +15377,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14528,7 +15410,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14576,6 +15458,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14594,6 +15479,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14615,6 +15503,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14702,6 +15596,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14720,6 +15617,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14750,22 +15650,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14798,6 +15713,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14885,6 +15803,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14903,6 +15824,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14945,9 +15869,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14969,9 +15899,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14993,9 +15920,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15104,6 +16028,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15164,15 +16091,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15185,30 +16121,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15224,6 +16184,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15260,6 +16223,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15353,6 +16322,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15428,6 +16400,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15518,6 +16493,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15554,6 +16532,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15773,9 +16754,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15821,9 +16799,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15968,12 +16943,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -16004,6 +16973,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -16025,6 +16997,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -16055,6 +17030,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -16079,7 +17057,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -16088,6 +17066,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16202,9 +17183,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16370,6 +17348,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16415,6 +17396,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16565,6 +17549,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16658,12 +17645,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16739,9 +17732,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16760,30 +17750,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16919,9 +17963,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16931,6 +17972,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -17033,6 +18080,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -17042,9 +18092,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -17081,9 +18128,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17180,6 +18224,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17225,6 +18284,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17246,6 +18317,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17315,6 +18389,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17357,6 +18437,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17396,6 +18479,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17447,6 +18533,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17477,6 +18566,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17492,7 +18584,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17597,6 +18692,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17633,6 +18731,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17648,10 +18749,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17666,6 +18770,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17687,10 +18797,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17762,6 +18869,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17774,6 +18884,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17921,6 +19037,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17984,9 +19103,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -18023,9 +19139,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18155,9 +19268,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18215,6 +19334,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18245,10 +19367,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18347,9 +19469,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18362,9 +19490,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18374,24 +19499,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18527,6 +19652,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18608,6 +19736,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18659,12 +19790,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18710,9 +19847,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18785,6 +19931,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18950,6 +20102,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18986,6 +20141,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -19070,6 +20228,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -19088,7 +20249,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19127,15 +20288,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19160,12 +20321,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19187,6 +20357,15 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19373,6 +20552,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19409,9 +20591,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19508,6 +20696,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19547,6 +20738,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19595,6 +20789,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19712,6 +20912,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19877,7 +21080,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19952,6 +21155,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -20078,6 +21284,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -20105,6 +21314,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20132,6 +21344,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20312,9 +21527,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20399,6 +21620,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20426,9 +21650,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20681,6 +21902,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20765,9 +21989,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20804,9 +22025,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20846,6 +22073,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -21020,6 +22250,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -21068,6 +22301,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21143,6 +22379,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21215,6 +22460,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21278,6 +22526,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21362,6 +22613,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21401,6 +22655,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21446,9 +22703,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21560,7 +22814,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21587,6 +22841,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21623,12 +22880,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21641,12 +22904,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21665,7 +22940,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21674,9 +22949,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21731,9 +23003,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21980,6 +23258,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -22046,6 +23327,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22166,6 +23453,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22223,15 +23513,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22247,9 +23531,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22268,6 +23549,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22379,6 +23663,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22436,10 +23723,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22448,6 +23735,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22487,6 +23777,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22496,9 +23789,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22748,18 +24047,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22778,6 +24071,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22796,6 +24092,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22820,9 +24119,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22832,12 +24128,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22847,12 +24149,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22871,12 +24179,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22901,7 +24215,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22976,9 +24290,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23225,6 +24536,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23285,6 +24602,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23312,7 +24632,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23354,6 +24677,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23402,6 +24728,9 @@ msgstr[2] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23465,6 +24794,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23546,9 +24878,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23579,9 +24908,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23690,6 +25016,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23702,6 +25031,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23723,7 +25055,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23765,9 +25103,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23807,12 +25142,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23849,9 +25193,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23885,9 +25226,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -24008,10 +25346,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -24020,10 +25361,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24140,6 +25481,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24167,6 +25511,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24182,6 +25529,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24260,6 +25610,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24308,6 +25661,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24323,7 +25679,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24416,6 +25772,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24443,6 +25802,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24461,6 +25823,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24494,7 +25862,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24530,7 +25901,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24623,9 +25994,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24635,12 +26015,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24665,9 +26051,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24716,6 +26108,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24758,6 +26153,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24932,6 +26330,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24950,6 +26351,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24968,6 +26372,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -25010,6 +26417,9 @@ msgstr[2] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -25019,6 +26429,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -25028,6 +26441,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25079,6 +26495,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -25091,7 +26510,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -25124,10 +26546,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25193,9 +26615,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25259,6 +26690,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25280,6 +26714,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25319,6 +26759,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25448,7 +26891,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25628,9 +27071,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25640,15 +27080,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25661,6 +27092,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25706,6 +27140,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25739,9 +27176,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25766,6 +27212,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25817,6 +27269,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25883,10 +27338,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25949,6 +27404,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25976,6 +27437,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -26003,6 +27467,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/sr_SP/gitlab.po b/locale/sr_SP/gitlab.po
index b856d8a60ea..3718b435c89 100644
--- a/locale/sr_SP/gitlab.po
+++ b/locale/sr_SP/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: sr\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:36\n"
+"PO-Revision-Date: 2020-06-08 15:17\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -77,6 +77,18 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -101,6 +113,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -128,6 +146,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -212,6 +236,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+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] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -248,6 +278,18 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -272,6 +314,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -353,6 +398,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -362,6 +410,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -374,6 +425,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -407,12 +482,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -428,6 +512,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -470,6 +560,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -623,6 +719,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -845,6 +944,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -875,6 +977,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -884,6 +989,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -920,7 +1028,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -971,6 +1082,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -983,9 +1097,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -1031,9 +1142,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1124,12 +1232,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1166,7 +1268,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1175,6 +1277,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1220,7 +1325,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1235,6 +1340,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1244,9 +1352,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1262,7 +1376,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1328,6 +1445,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1418,16 +1538,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1754,64 +1874,118 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1820,16 +1994,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|Unknown"
+msgstr ""
+
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -2003,6 +2195,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2168,9 +2363,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2192,6 +2384,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2267,6 +2462,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2303,9 +2501,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2321,6 +2525,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2330,6 +2537,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2354,12 +2564,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2369,9 +2573,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2435,6 +2645,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2507,12 +2720,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2522,12 +2729,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2636,6 +2849,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2648,7 +2864,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2762,6 +2978,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2840,15 +3059,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2906,6 +3143,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2927,9 +3167,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2948,6 +3185,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2978,6 +3218,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2993,6 +3236,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3470,16 +3716,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3503,7 +3749,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3512,6 +3758,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3530,6 +3779,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3560,9 +3812,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3590,6 +3839,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3665,7 +3920,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3680,6 +3935,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3716,6 +3974,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3758,6 +4022,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3776,6 +4043,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3881,15 +4151,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4238,9 +4499,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4253,6 +4511,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4265,6 +4526,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4292,9 +4556,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4334,6 +4595,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4529,6 +4793,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4550,9 +4817,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4604,7 +4868,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4631,6 +4895,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4709,10 +4976,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4871,6 +5138,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5105,9 +5378,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5186,6 +5456,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5216,6 +5489,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5225,9 +5501,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5285,6 +5567,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5303,6 +5588,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5342,6 +5630,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5351,6 +5642,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5387,6 +5681,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5549,7 +5846,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5573,9 +5873,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5609,9 +5906,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5660,16 +5954,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5696,6 +5984,18 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5708,6 +6008,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5732,27 +6035,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5774,10 +6089,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5798,9 +6110,6 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5822,6 +6131,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5849,12 +6161,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5873,7 +6179,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5882,7 +6191,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5921,10 +6230,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -6011,6 +6320,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -6056,9 +6368,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6074,9 +6383,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6173,7 +6479,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6191,9 +6497,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6212,9 +6515,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6224,9 +6524,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6269,6 +6566,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6281,6 +6581,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6320,6 +6623,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6353,6 +6662,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6404,9 +6716,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6443,6 +6752,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6467,6 +6779,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6515,6 +6830,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6539,6 +6857,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6791,6 +7112,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6827,6 +7151,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6869,6 +7196,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6959,12 +7292,6 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -7001,12 +7328,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -7016,9 +7337,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7136,12 +7454,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7163,13 +7487,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7289,10 +7613,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7301,9 +7625,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7313,6 +7652,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7340,12 +7682,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7355,6 +7712,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7367,6 +7730,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7595,6 +7961,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7643,6 +8012,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7667,6 +8039,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7814,6 +8189,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7829,6 +8207,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7922,6 +8303,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7931,9 +8315,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7961,6 +8342,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8084,6 +8468,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8108,10 +8495,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8168,7 +8555,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8381,10 +8768,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8396,12 +8783,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8471,7 +8852,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8576,9 +8966,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8594,6 +8981,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8645,10 +9035,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8690,13 +9080,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8708,7 +9098,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8747,6 +9137,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8765,6 +9158,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8798,6 +9194,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8813,6 +9212,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8822,6 +9224,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8900,18 +9305,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -9038,6 +9431,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9113,7 +9509,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9176,6 +9572,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9188,6 +9590,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9197,15 +9602,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9224,6 +9638,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9239,9 +9656,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9332,6 +9755,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9344,6 +9770,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9353,9 +9782,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9371,24 +9797,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9398,6 +9845,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9629,9 +10079,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9671,15 +10118,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9857,6 +10304,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9866,10 +10319,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9920,6 +10373,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9971,6 +10430,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9989,6 +10451,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9998,6 +10463,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10250,9 +10721,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10286,9 +10754,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10451,12 +10916,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10490,6 +10964,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10502,10 +10982,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10523,10 +11006,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10544,12 +11030,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10616,9 +11108,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10820,6 +11309,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10925,6 +11417,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10934,6 +11429,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -11042,6 +11540,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -11051,6 +11552,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11201,6 +11705,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11210,7 +11717,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11219,6 +11729,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11231,7 +11747,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11249,13 +11768,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11267,6 +11786,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11276,6 +11798,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11285,10 +11810,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11381,10 +11906,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11417,6 +11942,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11450,6 +11978,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11474,18 +12008,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11537,6 +12089,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11576,6 +12152,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11612,18 +12194,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11636,6 +12227,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11699,6 +12293,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11711,6 +12308,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11768,6 +12392,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11813,6 +12440,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11825,19 +12476,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11963,6 +12617,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -12002,6 +12659,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12182,6 +12842,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12266,6 +12929,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12287,9 +12953,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12317,6 +12980,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12329,6 +12995,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12353,15 +13022,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12500,6 +13163,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12515,6 +13181,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12611,6 +13280,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12725,10 +13397,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12755,6 +13427,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12806,9 +13481,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12818,9 +13490,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12998,6 +13667,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -13007,9 +13679,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -13022,6 +13691,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -13055,6 +13727,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13103,9 +13778,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13166,7 +13850,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13184,6 +13868,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13205,9 +13892,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13229,19 +13913,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13265,6 +13952,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13322,6 +14030,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13340,6 +14054,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13376,6 +14093,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13439,6 +14159,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13448,6 +14225,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13457,21 +14240,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13532,6 +14333,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13646,6 +14450,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13655,6 +14462,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13667,9 +14477,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13679,9 +14486,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13715,6 +14519,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13745,6 +14597,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13811,6 +14666,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13868,6 +14726,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13886,18 +14747,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13988,12 +14840,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -14018,6 +14876,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14153,6 +15014,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14177,6 +15041,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14291,9 +15158,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14360,6 +15233,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14369,9 +15251,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14438,7 +15317,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14483,7 +15362,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14498,6 +15377,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14528,7 +15410,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14576,6 +15458,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14594,6 +15479,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14615,6 +15503,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14702,6 +15596,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14720,6 +15617,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14750,22 +15650,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14798,6 +15713,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14885,6 +15803,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14903,6 +15824,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14945,9 +15869,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14969,9 +15899,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14993,9 +15920,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15104,6 +16028,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15164,15 +16091,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15185,30 +16121,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15224,6 +16184,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15260,6 +16223,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15353,6 +16322,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15428,6 +16400,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15518,6 +16493,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15554,6 +16532,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15773,9 +16754,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15821,9 +16799,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15968,12 +16943,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -16004,6 +16973,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -16025,6 +16997,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -16055,6 +17030,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -16079,7 +17057,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -16088,6 +17066,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16202,9 +17183,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16370,6 +17348,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16415,6 +17396,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16565,6 +17549,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16658,12 +17645,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16739,9 +17732,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16760,30 +17750,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16919,9 +17963,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16931,6 +17972,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -17033,6 +18080,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -17042,9 +18092,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -17081,9 +18128,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17180,6 +18224,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17225,6 +18284,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17246,6 +18317,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17315,6 +18389,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17357,6 +18437,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17396,6 +18479,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17447,6 +18533,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17477,6 +18566,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17492,7 +18584,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17597,6 +18692,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17633,6 +18731,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17648,10 +18749,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17666,6 +18770,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17687,10 +18797,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17762,6 +18869,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17774,6 +18884,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17921,6 +19037,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17984,9 +19103,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -18023,9 +19139,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18155,9 +19268,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18215,6 +19334,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18245,10 +19367,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18347,9 +19469,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18362,9 +19490,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18374,24 +19499,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18527,6 +19652,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18608,6 +19736,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18659,12 +19790,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18710,9 +19847,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18785,6 +19931,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18950,6 +20102,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18986,6 +20141,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -19070,6 +20228,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -19088,7 +20249,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19127,15 +20288,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19160,12 +20321,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19187,6 +20357,15 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19373,6 +20552,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19409,9 +20591,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19508,6 +20696,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19547,6 +20738,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19595,6 +20789,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19712,6 +20912,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19877,7 +21080,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19952,6 +21155,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -20078,6 +21284,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -20105,6 +21314,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20132,6 +21344,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20312,9 +21527,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20399,6 +21620,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20426,9 +21650,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20681,6 +21902,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20765,9 +21989,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20804,9 +22025,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20846,6 +22073,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -21020,6 +22250,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -21068,6 +22301,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21143,6 +22379,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21215,6 +22460,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21278,6 +22526,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21362,6 +22613,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21401,6 +22655,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21446,9 +22703,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21560,7 +22814,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21587,6 +22841,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21623,12 +22880,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21641,12 +22904,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21665,7 +22940,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21674,9 +22949,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21731,9 +23003,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21980,6 +23258,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -22046,6 +23327,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22166,6 +23453,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22223,15 +23513,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22247,9 +23531,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22268,6 +23549,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22379,6 +23663,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22436,10 +23723,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22448,6 +23735,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22487,6 +23777,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22496,9 +23789,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22748,18 +24047,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22778,6 +24071,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22796,6 +24092,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22820,9 +24119,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22832,12 +24128,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22847,12 +24149,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22871,12 +24179,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22901,7 +24215,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22976,9 +24290,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23225,6 +24536,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23285,6 +24602,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23312,7 +24632,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23354,6 +24677,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23402,6 +24728,9 @@ msgstr[2] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23465,6 +24794,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23546,9 +24878,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23579,9 +24908,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23690,6 +25016,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23702,6 +25031,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23723,7 +25055,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23765,9 +25103,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23807,12 +25142,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23849,9 +25193,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23885,9 +25226,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -24008,10 +25346,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -24020,10 +25361,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24140,6 +25481,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24167,6 +25511,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24182,6 +25529,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24260,6 +25610,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24308,6 +25661,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24323,7 +25679,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24416,6 +25772,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24443,6 +25802,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24461,6 +25823,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24494,7 +25862,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24530,7 +25901,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24623,9 +25994,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24635,12 +26015,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24665,9 +26051,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24716,6 +26108,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24758,6 +26153,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24932,6 +26330,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24950,6 +26351,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24968,6 +26372,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -25010,6 +26417,9 @@ msgstr[2] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -25019,6 +26429,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -25028,6 +26441,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25079,6 +26495,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -25091,7 +26510,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -25124,10 +26546,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25193,9 +26615,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25259,6 +26690,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25280,6 +26714,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25319,6 +26759,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25448,7 +26891,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25628,9 +27071,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25640,15 +27080,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25661,6 +27092,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25706,6 +27140,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25739,9 +27176,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25766,6 +27212,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25817,6 +27269,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25883,10 +27338,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25949,6 +27404,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25976,6 +27437,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -26003,6 +27467,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/sv_SE/gitlab.po b/locale/sv_SE/gitlab.po
index 144b97410e8..0cb313ec7b9 100644
--- a/locale/sv_SE/gitlab.po
+++ b/locale/sv_SE/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: sv-SE\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:36\n"
+"PO-Revision-Date: 2020-06-08 15:14\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,13 +8991,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8627,7 +9009,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] ""
msgstr[1] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/sw_KE/gitlab.po b/locale/sw_KE/gitlab.po
index 1a6b5db2c39..dc8caef887f 100644
--- a/locale/sw_KE/gitlab.po
+++ b/locale/sw_KE/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: sw\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:33\n"
+"PO-Revision-Date: 2020-06-08 15:13\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,13 +8991,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8627,7 +9009,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] ""
msgstr[1] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/tr_TR/gitlab.po b/locale/tr_TR/gitlab.po
index 5473bc15651..224144637ca 100644
--- a/locale/tr_TR/gitlab.po
+++ b/locale/tr_TR/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: tr\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:36\n"
+"PO-Revision-Date: 2020-06-08 15:11\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -49,7 +49,7 @@ msgstr[1] " %d noktasında bozuldu"
msgid " improved on %d point"
msgid_plural " improved on %d points"
msgstr[0] " %d noktasında geliştirildi"
-msgstr[1] " %d noktalasında geliştirildi"
+msgstr[1] " %d noktasında geliştirildi"
msgid " or "
msgstr " veya "
@@ -71,29 +71,44 @@ msgstr ""
msgid "%d URL scanned"
msgid_plural "%d URLs scanned"
+msgstr[0] "%d URL tarandı"
+msgstr[1] "%d URL tarandı"
+
+msgid "%d approver"
+msgid_plural "%d approvers"
msgstr[0] ""
msgstr[1] ""
-msgid "%d changed file"
-msgid_plural "%d changed files"
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d changed file"
+msgid_plural "%d changed files"
+msgstr[0] "%d dosya deÄŸiÅŸtirildi"
+msgstr[1] "%d dosya deÄŸiÅŸtirildi"
+
msgid "%d child epic"
msgid_plural "%d child epics"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d alt epik"
+msgstr[1] "%d alt epik"
msgid "%d code quality issue"
msgid_plural "%d code quality issues"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d kod kalitesi sorunu"
+msgstr[1] "%d kod kalitesi sorunu"
msgid "%d comment"
msgid_plural "%d comments"
msgstr[0] "%d yorum"
msgstr[1] "%d yorum"
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] "%d iÅŸlem"
@@ -117,11 +132,16 @@ msgid_plural "%d contributions"
msgstr[0] "%d katkı"
msgstr[1] "%d katkı"
-msgid "%d error"
-msgid_plural "%d errors"
+msgid "%d day"
+msgid_plural "%d days"
msgstr[0] ""
msgstr[1] ""
+msgid "%d error"
+msgid_plural "%d errors"
+msgstr[0] "%d hata"
+msgstr[1] "%d hata"
+
msgid "%d exporter"
msgid_plural "%d exporters"
msgstr[0] "%d dışa aktaran"
@@ -129,8 +149,8 @@ msgstr[1] "%d dışa aktaran"
msgid "%d failed"
msgid_plural "%d failed"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d başarısız"
+msgstr[1] "%d başarısız"
msgid "%d fixed test result"
msgid_plural "%d fixed test results"
@@ -139,8 +159,8 @@ msgstr[1] "%d sabit test sonucu"
msgid "%d group selected"
msgid_plural "%d groups selected"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d grup seçildi"
+msgstr[1] "%d grup seçildi"
msgid "%d inaccessible merge request"
msgid_plural "%d inaccessible merge requests"
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] "%d yorum daha"
msgstr[1] "%d yorum daha"
+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] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] "%d proje"
@@ -214,6 +239,16 @@ msgstr[1] "%d etiket"
msgid "%d unresolved thread"
msgid_plural "%d unresolved threads"
+msgstr[0] "%d çözümlenmemiş konu"
+msgstr[1] "%d çözümlenmemiş konu"
+
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
msgstr[0] ""
msgstr[1] ""
@@ -239,6 +274,9 @@ msgstr "%{commit_author_link} %{commit_timeago} yazdı"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} çekirdek"
@@ -260,7 +298,7 @@ msgid "%{count} more"
msgstr "%{count} daha"
msgid "%{count} more assignees"
-msgstr "%{count} daha fazla atanan"
+msgstr "%{count} vekil daha"
msgid "%{count} more release"
msgid_plural "%{count} more releases"
@@ -316,6 +354,9 @@ msgstr "%{filePath} silindi"
msgid "%{firstLabel} +%{labelCount} more"
msgstr "%{firstLabel} +%{labelCount} daha"
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr "%{issuesSize} sorun"
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr "%{label_for_message} kullanılamaz"
@@ -370,12 +438,21 @@ msgstr "%{loadingIcon} Başladı"
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr "%{lock_path} dizini %{lock_user_id} GitLab kullanıcısı tarafından kilitlendi"
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr "%{mergeLength}/%{usersLength} birleÅŸtirebilir"
msgid "%{mrText}, this issue will be closed automatically."
msgstr "%{mrText}, bu sorun otomatik olarak kapatılacaktır."
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,10 +468,16 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr "%{name} kullanıcısının profil resmi"
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{no_of_days} gün"
+msgstr[1] "%{no_of_days} gün"
msgid "%{number_commits_behind} commits behind %{default_branch}, %{number_commits_ahead} commits ahead"
msgstr ""
@@ -403,10 +486,10 @@ msgid "%{openOrClose} %{noteable}"
msgstr "%{openOrClose} %{noteable}"
msgid "%{openedEpics} open, %{closedEpics} closed"
-msgstr ""
+msgstr "%{openedEpics} açık, %{closedEpics} kapalı"
msgid "%{openedIssues} open, %{closedIssues} closed"
-msgstr ""
+msgstr "%{openedIssues} açık, %{closedIssues} kapalı"
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -418,10 +501,10 @@ msgid "%{percent}%{percentSymbol} complete"
msgstr "%{percentSymbol}%{percent} tamamlandı"
msgid "%{placeholder} is not a valid color scheme"
-msgstr ""
+msgstr "%{placeholder} geçerli bir renk düzeni değil"
msgid "%{placeholder} is not a valid theme"
-msgstr ""
+msgstr "%{placeholder} geçerli bir tema değil"
msgid "%{primary} (%{secondary})"
msgstr "%{primary} (%{secondary})"
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] "%{releases} sürüm"
msgstr[1] "%{releases} sürüm"
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -438,7 +527,7 @@ msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Enabled"
msgstr ""
msgid "%{service_title} %{message}."
-msgstr ""
+msgstr "%{service_title} %{message}."
msgid "%{size} GiB"
msgstr "%{size} GiB"
@@ -484,12 +573,12 @@ msgid "%{strong_start}%{human_size}%{strong_end} Files"
msgstr "%{strong_start}%{human_size}%{strong_end} Dosya"
msgid "%{strong_start}%{human_size}%{strong_end} Storage"
-msgstr ""
+msgstr "%{strong_start}%{human_size}%{strong_end} Depolama"
msgid "%{strong_start}%{release_count}%{strong_end} Release"
msgid_plural "%{strong_start}%{release_count}%{strong_end} Releases"
-msgstr[0] "%{strong_start}%{release_count}%{strong_end} Sürümü"
-msgstr[1] "%{strong_start}%{release_count}%{strong_end} Sürümleri"
+msgstr[0] "%{strong_start}%{release_count}%{strong_end} Sürüm"
+msgstr[1] "%{strong_start}%{release_count}%{strong_end} Sürüm"
msgid "%{strong_start}%{tag_count}%{strong_end} Tag"
msgid_plural "%{strong_start}%{tag_count}%{strong_end} Tags"
@@ -503,10 +592,10 @@ msgid "%{tags} tag per image name"
msgstr ""
msgid "%{tags} tags per image name"
-msgstr ""
+msgstr "her resim adı için %{tags} etiket"
msgid "%{tag}-%{evidence}-%{filename}"
-msgstr ""
+msgstr "%{tag}-%{evidence}-%{filename}"
msgid "%{template_project_id} is unknown or invalid"
msgstr "%{template_project_id} bilinmiyor ya da geçersiz"
@@ -529,7 +618,7 @@ msgid "%{title} changes"
msgstr "%{title} deÄŸiÅŸiklik"
msgid "%{token}..."
-msgstr ""
+msgstr "%{token}..."
msgid "%{totalWeight} total weight"
msgstr "%{totalWeight} toplam ağırlık"
@@ -556,7 +645,7 @@ msgid "%{username}'s avatar"
msgstr "%{username} kullanıcısının profil resmi"
msgid "%{value} s"
-msgstr ""
+msgstr "%{value} s"
msgid "%{verb} %{time_spent_value} spent time."
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] "(%d kapandı)"
msgstr[1] "(%d kapandı)"
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr "(%{mrCount} birleÅŸtirildi)"
@@ -597,10 +689,10 @@ msgid "(removed)"
msgstr "(silindi)"
msgid "(revoked)"
-msgstr ""
+msgstr "(iptal edildi)"
msgid "*"
-msgstr ""
+msgstr "*"
msgid "+ %{amount} more"
msgstr "%{amount} tane daha"
@@ -612,7 +704,7 @@ msgid "+ %{moreCount} more"
msgstr "+ %{moreCount} daha fazla"
msgid "+ %{numberOfHiddenAssignees} more"
-msgstr ""
+msgstr "+ %{numberOfHiddenAssignees} daha"
msgid "+%d more"
msgid_plural "+%d more"
@@ -620,7 +712,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "+%{approvers} more approvers"
-msgstr ""
+msgstr "+%{approvers} onaylayan daha"
msgid "+%{tags} more"
msgstr ""
@@ -704,7 +796,7 @@ msgstr[0] "1 dakika"
msgstr[1] "%d dakika"
msgid "1 month"
-msgstr ""
+msgstr "1 ay"
msgid "1 open issue"
msgid_plural "%{issues} open issues"
@@ -750,7 +842,7 @@ msgid "2FA"
msgstr "2FA"
msgid "2FADevice|Registered On"
-msgstr ""
+msgstr "Kayıtlı"
msgid "3 days"
msgstr "3 gün"
@@ -782,6 +874,9 @@ msgstr "Lütfen bunun bir hata olduğunu düşünüyorsanız, GitLab yöneticini
msgid "8 hours"
msgstr "8 saat"
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr "< 1 saat"
@@ -807,11 +902,14 @@ msgid "<no scopes selected>"
msgstr "<hiçbir kapsam seçilmedi>"
msgid "<project name>"
-msgstr ""
+msgstr "<proje adı>"
msgid "<strong>%{group_name}</strong> group members"
msgstr "<strong>%{group_name}</strong> grup üyeleri"
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr "Kaynak dalı <strong>siler</strong>"
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -906,13 +1010,16 @@ msgid "A regular expression that will be used to find the test coverage output i
msgstr ""
msgid "A secure token that identifies an external storage request."
+msgstr "Harici depolama isteğini tanımlayan güvenli bir erişim anahtarı."
+
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
msgstr ""
msgid "A subscription will 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 ""
msgid "A terraform report was generated in your pipelines."
-msgstr ""
+msgstr "İş hattınızda yeni bir terraform raporu oluşturuldu."
msgid "A user with write access to the source branch selected this option"
msgstr "Bu dala yazma yetkisi olan kullanıcı bu seçeneği seçti"
@@ -920,9 +1027,6 @@ msgstr "Bu dala yazma yetkisi olan kullanıcı bu seçeneği seçti"
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr "API Yardımı"
-
msgid "API Token"
msgstr "API Erişim Anahtarı"
@@ -936,7 +1040,7 @@ msgid "AWS Secret Access Key"
msgstr "AWS Gizli Erişim Anahtarı"
msgid "AWS Secret Access Key. Only required if not using role instance credentials"
-msgstr ""
+msgstr "AWS Gizli Erişim Anahtarı. Yalnızca rol örneği kimlik bilgileri kullanılmıyorsa gereklidir"
msgid "Abort"
msgstr "Ä°ptal"
@@ -966,10 +1070,7 @@ msgid "Accept terms"
msgstr "Şartları kabul et"
msgid "Acceptable for use in this project"
-msgstr ""
-
-msgid "Accepted MR"
-msgstr "Kabul edilen MR"
+msgstr "Bu projede kullanım için kabul edilebilir"
msgid "Access Tokens"
msgstr "Erişim Anahtarları"
@@ -1008,7 +1109,7 @@ msgid "AccessTokens|Are you sure?"
msgstr "Emin misiniz?"
msgid "AccessTokens|Are you sure? Any RSS or calendar URLs currently in use will stop working."
-msgstr ""
+msgstr "Emin misiniz? Şu anda kullanımda olan RSS veya takvim URL'leri çalışmayı durduracaktır."
msgid "AccessTokens|Are you sure? Any issue email addresses currently in use will stop working."
msgstr ""
@@ -1023,7 +1124,7 @@ msgid "AccessTokens|Incoming email token"
msgstr "Gelen e-posta erişim anahtarı"
msgid "AccessTokens|It cannot be used to access any other data."
-msgstr ""
+msgstr "Başka hiçbir veriye erişmek için kullanılamaz."
msgid "AccessTokens|Keep this token secret. Anyone who gets ahold of it can access repository static objects as if they were you. You should %{reset_link_start}reset it%{reset_link_end} if that ever happens."
msgstr ""
@@ -1044,7 +1145,7 @@ msgid "AccessTokens|They are the only accepted password when you have Two-Factor
msgstr ""
msgid "AccessTokens|You can also use personal access tokens to authenticate against Git over HTTP."
-msgstr ""
+msgstr "Git üzerinden HTTP üzerinden kimlik doğrulaması yapmak için kişisel erişim anahtarlarını da kullanabilirsiniz."
msgid "AccessTokens|You can generate a personal access token for each application you use that needs access to the GitLab API."
msgstr "GitLab API'sine erişmesi gereken, kullandığınız her uygulama için kişisel bir erişim anahtarı oluşturabilirsiniz."
@@ -1061,20 +1162,14 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr "sıfırla"
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
-msgstr ""
+msgstr "Daha fazlasını öğren"
msgid "AccessibilityReport|Message: %{message}"
-msgstr ""
+msgstr "Mesaj: %{message}"
msgid "AccessibilityReport|New"
-msgstr ""
+msgstr "Yeni"
msgid "AccessibilityReport|The accessibility scanning found an error of the following type: %{code}"
msgstr ""
@@ -1103,13 +1198,16 @@ msgstr "Servis Masasını Etkinleştir"
msgid "Active"
msgstr "Etkin"
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
msgstr "Etkin Oturumlar"
msgid "Active Users:"
+msgstr "Etkin Kullanıcılar:"
+
+msgid "Active users"
msgstr ""
msgid "Activity"
@@ -1156,8 +1254,8 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr "Zoom toplantısı ekle"
-msgid "Add a %{type} token"
-msgstr "Bir %{type} erişim anahtarı ekle"
+msgid "Add a %{type}"
+msgstr ""
msgid "Add a GPG key"
msgstr "Bir GPG anahtarı ekle"
@@ -1171,6 +1269,9 @@ msgstr "Yapılacaklar listesi ekle"
msgid "Add a bullet list"
msgstr "Madde iÅŸareti listesi ekle"
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr "Bu %{noteableDisplayName} için genel bir yorum ekle."
@@ -1180,9 +1281,15 @@ msgstr "Buna %{noteable_name} genel bir yorum ekle."
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr "Wiki'nize projeniz hakkında bilgi içeren bir ana sayfa ekleyin. GitLab bu mesaj yerine onu burada görüntüleyecektir."
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr "Bağlantı ekle"
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr "Numaralı liste ekle"
@@ -1198,14 +1305,17 @@ msgstr "Tüm e-posta iletişiminde görünecek ek metin ekleyin. %{character_lim
msgid "Add an SSH key"
msgstr "Bir SSH anahtarı ekle"
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
msgstr "Bir sorun ekle"
msgid "Add another link"
-msgstr ""
+msgstr "Başka bir bağlantı ekle"
msgid "Add approval rule"
msgstr "Onay kuralı ekle"
@@ -1214,7 +1324,7 @@ msgid "Add bold text"
msgstr "Kalın metin ekle"
msgid "Add child epic to an epic"
-msgstr ""
+msgstr "Bir epiÄŸe alt epik ekle"
msgid "Add comment now"
msgstr "Åžimdi yorum ekle"
@@ -1226,7 +1336,7 @@ msgid "Add email address"
msgstr "E-posta adresi ekle"
msgid "Add environment"
-msgstr ""
+msgstr "Ortam ekle"
msgid "Add header and footer to emails. Please note that color settings will only be applied within the application interface"
msgstr "E-postalar için üstbilgi ve altbilgi ekleyin. Renk ayarları sadece uygulama arabirimi içinde uygulanacak unutmayın"
@@ -1262,10 +1372,13 @@ msgid "Add reaction"
msgstr "Tepki ekle"
msgid "Add request manually"
+msgstr "Ä°steÄŸi elle ekle"
+
+msgid "Add strikethrough text"
msgstr ""
msgid "Add system hook"
-msgstr ""
+msgstr "Sistem kancası ekle"
msgid "Add to Slack"
msgstr "Slack'e ekle"
@@ -1292,7 +1405,7 @@ msgid "Add users to group"
msgstr "Kullanıcıları gruba ekle"
msgid "Add variable"
-msgstr ""
+msgstr "DeÄŸiÅŸken ekle"
msgid "Add webhook"
msgstr "Web kancası ekle"
@@ -1307,22 +1420,22 @@ msgid "Added"
msgstr "Eklendi"
msgid "Added %{epic_ref} as a child epic."
-msgstr ""
+msgstr "%{epic_ref} alt epik olarak eklendi."
msgid "Added %{label_references} %{label_text}."
-msgstr ""
+msgstr "%{label_references} %{label_text} eklendi."
msgid "Added a To Do."
msgstr "Yapılacaklar listesi eklendi."
msgid "Added an issue to an epic."
-msgstr ""
+msgstr "EpiÄŸe bir sorun eklendi."
msgid "Added at"
msgstr "Tarihinde eklendi"
msgid "Added for this merge request"
-msgstr ""
+msgstr "Bu birleştirme talebi için eklendi"
msgid "Added in this version"
msgstr "Bu sürümde eklendi"
@@ -1352,20 +1465,20 @@ msgid "Adds a Zoom meeting"
msgstr "Zoom toplantısı ekler"
msgid "Adds an issue to an epic."
-msgstr ""
+msgstr "EpiÄŸe bir sorun ekler."
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr "Yönetici alanı"
+msgid "Admin Note"
+msgstr ""
+
msgid "Admin Overview"
msgstr "Yönetim Genel Bakış"
-msgid "Admin Section"
-msgstr "Yönetici Bölümü"
-
msgid "Admin mode already enabled"
msgstr "Yönetici modu zaten etkin"
@@ -1379,31 +1492,31 @@ msgid "Admin notes"
msgstr "Yönetici notları"
msgid "AdminArea|Active users"
-msgstr ""
+msgstr "Etkin kullanıcılar"
msgid "AdminArea|Billable users"
-msgstr ""
+msgstr "Faturalandırılabilir kullanıcılar"
msgid "AdminArea|Blocked users"
-msgstr ""
+msgstr "Engellenen kullanıcılar"
msgid "AdminArea|Bots"
-msgstr ""
+msgstr "Botlar"
msgid "AdminArea|Developer"
-msgstr ""
+msgstr "GeliÅŸtirici"
msgid "AdminArea|Guest"
-msgstr ""
+msgstr "Misafir"
msgid "AdminArea|Included Free in license"
-msgstr ""
+msgstr "Lisansa ücretsiz dahildir"
msgid "AdminArea|Maintainer"
-msgstr ""
+msgstr "Sorumlu"
msgid "AdminArea|Owner"
-msgstr ""
+msgstr "Sahibi"
msgid "AdminArea|Reporter"
msgstr ""
@@ -1421,10 +1534,10 @@ msgid "AdminArea|Stopping jobs failed"
msgstr "İşleri durdurma başarısız oldu"
msgid "AdminArea|Total users"
-msgstr ""
+msgstr "Toplam kullanıcı"
msgid "AdminArea|Users statistics"
-msgstr ""
+msgstr "Kullanıcı istatistikleri"
msgid "AdminArea|Users with highest role"
msgstr ""
@@ -1478,10 +1591,10 @@ msgid "AdminSettings|No required pipeline"
msgstr "Gerekli iş hattı yok"
msgid "AdminSettings|Required pipeline configuration"
-msgstr ""
+msgstr "Gerekli iş hattı yapılandırması"
msgid "AdminSettings|Select a pipeline configuration file"
-msgstr ""
+msgstr "Bir iş hattı yapılandırma dosyası seçin"
msgid "AdminSettings|Select a template"
msgstr "Bir şablon seçin"
@@ -1493,7 +1606,7 @@ msgid "AdminSettings|Set an instance-wide auto included %{link_start}pipeline co
msgstr ""
msgid "AdminSettings|Some settings have moved"
-msgstr ""
+msgstr "Bazı ayarlar taşındı"
msgid "AdminSettings|Specify a domain to use by default for every project's Auto Review Apps and Auto Deploy stages."
msgstr "Her projenin Otomatik İnceleme Uygulamaları ve Otomatik Dağıtma aşamaları için varsayılan olarak kullanılacak bir etki alanı belirleyin."
@@ -1631,10 +1744,10 @@ msgid "AdminUsers|Sort by"
msgstr "Buna göre sırala"
msgid "AdminUsers|The user will be logged out"
-msgstr ""
+msgstr "Kullanıcının oturumu kapatılacak"
msgid "AdminUsers|The user will not be able to access git repositories"
-msgstr ""
+msgstr "Kullanıcı git depolarına erişemeyecek"
msgid "AdminUsers|The user will not be able to access the API"
msgstr "Kullanıcı API'ye erişemeyecek"
@@ -1670,13 +1783,13 @@ msgid "AdminUsers|You are about to permanently delete the user %{username}. This
msgstr ""
msgid "Administration"
-msgstr ""
+msgstr "Yönetim"
msgid "Advanced"
msgstr "GeliÅŸmiÅŸ"
msgid "Advanced Settings"
-msgstr ""
+msgstr "GeliÅŸmiÅŸ Ayarlar"
msgid "Advanced permissions, Large File Storage and Two-Factor authentication settings."
msgstr "Gelişmiş izinler, Büyük Dosya Depolama ve İki Adımlı Kimlik Doğrulama ayarları."
@@ -1690,42 +1803,84 @@ msgstr "Başarılı bir şifre güncellemesinden sonra giriş ekranına yönlend
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr "Başarılı bir şifre güncellemesinden sonra, yeni şifrenizle giriş yapabileceğiniz giriş sayfasına yönlendirileceksiniz."
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] "Uyarı"
msgstr[1] "Uyarı"
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
+msgstr "Uyarı"
+
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
msgstr ""
msgid "AlertManagement|Authorize external service"
msgstr ""
-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."
+msgid "AlertManagement|Create issue"
msgstr ""
-msgid "AlertManagement|End time"
+msgid "AlertManagement|Critical"
+msgstr ""
+
+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|End time:"
+msgid "AlertManagement|Edit"
msgstr ""
+msgid "AlertManagement|End time"
+msgstr "Bitiş zamanı"
+
msgid "AlertManagement|Events"
+msgstr "Olaylar"
+
+msgid "AlertManagement|High"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|Info"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Low"
+msgstr ""
+
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
+msgstr "Daha fazla bilgi"
+
+msgid "AlertManagement|No alert data to display."
msgstr ""
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
@@ -1734,37 +1889,67 @@ msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
+msgstr "Genel Bakış"
+
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
msgstr ""
msgid "AlertManagement|Resolved"
+msgstr "Çözülmüş"
+
+msgid "AlertManagement|Service"
msgstr ""
msgid "AlertManagement|Severity"
-msgstr ""
+msgstr "Önem Derecesi"
msgid "AlertManagement|Start time"
+msgstr "Başlangıç zamanı"
+
+msgid "AlertManagement|Status"
+msgstr "Durum"
+
+msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
msgstr ""
-msgid "AlertManagement|Status"
+msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
-msgid "AlertManagement|Surface alerts in GitLab"
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
msgstr ""
-msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
+msgid "AlertManagement|Tool"
msgstr ""
msgid "AlertManagement|Triggered"
+msgstr "Tetiklenenler"
+
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
+msgstr ""
+
+msgid "AlertManagement|View issue"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1783,7 +1968,7 @@ msgid "All %{replicableType} are being scheduled for %{action}"
msgstr ""
msgid "All (default)"
-msgstr ""
+msgstr "Tümü (varsayılan)"
msgid "All Members"
msgstr "Tüm Kullanıcılar"
@@ -1795,13 +1980,13 @@ msgid "All changes are committed"
msgstr "Tüm değişiklikler işlendi"
msgid "All default stages are currently visible"
-msgstr ""
+msgstr "Tüm varsayılan aşamalar şu anda görünür"
msgid "All email addresses will be used to identify your commits."
msgstr "Tüm e-posta adresleri işlemlerinizi tanımlamak için kullanılacaktır."
msgid "All environments"
-msgstr ""
+msgstr "Tüm ortamlar"
msgid "All features are enabled for blank projects, from templates, or when importing, but you can disable them afterward in the project settings."
msgstr "Tüm özellikler şablonlardan veya içe aktarırken boş projeler için etkindir, ancak daha sonra proje ayarlarında bunları devre dışı bırakabilirsiniz."
@@ -1819,7 +2004,7 @@ msgid "All merge conflicts were resolved. The merge request can now be merged."
msgstr ""
msgid "All merge request dependencies have been merged"
-msgstr ""
+msgstr "Tüm birleştirme isteği bağımlılıkları birleştirildi"
msgid "All paths are relative to the GitLab URL. Do not include %{relative_url_link_start}relative URL%{relative_url_link_end}."
msgstr ""
@@ -1831,7 +2016,7 @@ msgid "All security scans are enabled because %{linkStart}Auto DevOps%{linkEnd}
msgstr ""
msgid "All threads resolved"
-msgstr ""
+msgstr "Tüm konular çözüldü"
msgid "All users"
msgstr "Tüm kullanıcılar"
@@ -1867,7 +2052,7 @@ msgid "Allow rendering of PlantUML diagrams in Asciidoc documents."
msgstr ""
msgid "Allow repository mirroring to be configured by project maintainers"
-msgstr ""
+msgstr "Depo yansıtılmasının proje sahipleri tarafından yapılandırılmasına izin ver"
msgid "Allow requests to the local network from hooks and services."
msgstr "Yerel aÄŸa kanca ve servislerden gelen isteklere izin ver."
@@ -1885,13 +2070,13 @@ msgid "Allow this secondary node to replicate content on Object Storage"
msgstr ""
msgid "Allow users to dismiss the broadcast message"
-msgstr ""
+msgstr "Kullanıcıların yayın mesajını kapatmalarına izin ver"
msgid "Allow users to register any application to use GitLab as an OAuth provider"
msgstr ""
msgid "Allow users to request access (if visibility is public or internal)"
-msgstr ""
+msgstr "Kullanıcıların erişim isteğinde bulunmalarına izin ver (görünürlük genel veya dahili ise)"
msgid "Allowed email domain restriction only permitted for top-level groups"
msgstr ""
@@ -1933,11 +2118,14 @@ msgid "Amount of time (in hours) that users are allowed to skip forced configura
msgstr ""
msgid "An alert has been triggered in %{project_path}."
-msgstr ""
+msgstr "%{project_path} dizininde bir alarm tetiklendi."
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr "%{link_to_client} adlı uygulama, GitLab hesabınıza erişim talep ediyor."
+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 ""
@@ -1963,7 +2151,7 @@ msgid "An error occurred fetching the dropdown data."
msgstr ""
msgid "An error occurred fetching the project authors."
-msgstr ""
+msgstr "Proje yazarları alınırken bir hata oluştu."
msgid "An error occurred previewing the blob"
msgstr "Blob datanın öngösteriminde, bir hata meydana geldi"
@@ -2026,7 +2214,7 @@ msgid "An error occurred while fetching exposed artifacts."
msgstr ""
msgid "An error occurred while fetching folder content."
-msgstr ""
+msgstr "Klasör içeriği alınırken bir hata oluştu."
msgid "An error occurred while fetching issues."
msgstr "Sorunlar alınırken bir hata oluştu."
@@ -2047,7 +2235,7 @@ msgid "An error occurred while fetching sidebar data"
msgstr "Kenar çubuğu verileri getirilirken bir hata oluştu"
msgid "An error occurred while fetching terraform reports."
-msgstr ""
+msgstr "Terraform raporu alınırken bir hata oluştu."
msgid "An error occurred while fetching the Service Desk address."
msgstr ""
@@ -2080,10 +2268,10 @@ 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."
msgid "An error occurred while fetching this tab."
-msgstr ""
+msgstr "Bu sekme alınırken bir hata oluştu."
msgid "An error occurred while generating a username. Please try again."
-msgstr ""
+msgstr "Kullanıcı adı oluştururken bir hata oluştu. Lütfen tekrar deneyin."
msgid "An error occurred while getting files for - %{branchId}"
msgstr ""
@@ -2103,9 +2291,6 @@ msgstr "Tüm dosyalar yüklenirken bir hata oluştu."
msgid "An error occurred while loading chart data"
msgstr "Tablo verileri alınırken bir hata oluştu"
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr "İşlem imzaları yüklenirken bir hata oluştu"
@@ -2119,16 +2304,19 @@ msgid "An error occurred while loading filenames"
msgstr "Dosya isimleri yüklenirken bir hata oluştu"
msgid "An error occurred while loading group members."
-msgstr ""
+msgstr "Grup üyeleri yüklenirken bir hata oluştu."
msgid "An error occurred while loading issues"
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 milestones"
msgstr ""
msgid "An error occurred while loading terraform report"
-msgstr ""
+msgstr "Terraform raporu yüklenirken bir hata oluştu"
msgid "An error occurred while loading the data. Please try again."
msgstr "Veriler yüklenirken bir hata oluştu. Lütfen tekrar deneyin."
@@ -2143,7 +2331,7 @@ msgid "An error occurred while loading the file."
msgstr "Dosya yüklenirken bir hata oluştu."
msgid "An error occurred while loading the file. Please try again later."
-msgstr ""
+msgstr "Dosya yüklenirken bir hata oluştu. Lütfen daha sonra tekrar deneyin."
msgid "An error occurred while loading the merge request changes."
msgstr "Birleştirme isteği değişiklikleri yüklenirken bir hata oluştu."
@@ -2170,7 +2358,7 @@ msgid "An error occurred while parsing recent searches"
msgstr "Son aramalar ayrıştırılırken bir hata oluştu"
msgid "An error occurred while parsing the file."
-msgstr ""
+msgstr "Dosyayı ayrıştırırken bir hata oluştu."
msgid "An error occurred while removing epics."
msgstr "Epikler kaldırılırken bir hata oluştu."
@@ -2194,7 +2382,7 @@ msgid "An error occurred while saving LDAP override status. Please try again."
msgstr ""
msgid "An error occurred while saving assignees"
-msgstr "Atanmış kişiler kaydedilirken bir hata oluştu"
+msgstr "Vekiller kaydedilirken bir hata oluÅŸtu"
msgid "An error occurred while saving the approval settings"
msgstr "Onay ayarları kaydedilirken bir hata oluştu"
@@ -2202,6 +2390,9 @@ msgstr "Onay ayarları kaydedilirken bir hata oluştu"
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr "Bildirimlere abone olunurken bir hata oluÅŸtu."
@@ -2221,7 +2412,7 @@ msgid "An error occurred while updating the comment"
msgstr "Yorum güncellenirken bir hata oluştu"
msgid "An error occurred while validating group path"
-msgstr ""
+msgstr "Grup yolu doğrulanırken bir hata oluştu"
msgid "An error occurred while validating username"
msgstr "Kullanıcı adı doğrulanırken bir hata oluştu"
@@ -2238,14 +2429,20 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr "Proje ortamı kontrol edilirken beklenmeyen bir hata oluştu."
msgid "An unexpected error occurred while checking the project runners."
-msgstr ""
+msgstr "Proje çalıştırıcıları kontrol edilirken beklenmeyen bir hata oluştu."
msgid "An unexpected error occurred while communicating with the Web Terminal."
msgstr "Web Terminali ile iletiÅŸim kurulurken beklenmeyen bir hata oluÅŸtu."
@@ -2256,15 +2453,21 @@ msgstr "Web Terminali başlatılırken beklenmeyen bir hata oluştu."
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr "Web Terminali durdurulurken beklenmeyen bir hata oluÅŸtu."
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr "Analizler"
msgid "Analyze a review version of your web application."
-msgstr ""
+msgstr "Web uygulamanızın inceleme sürümünü analiz edin."
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2275,7 +2478,7 @@ msgid "Anonymous"
msgstr "Anonim"
msgid "Another action is currently in progress"
-msgstr ""
+msgstr "Devam eden baÅŸka bir iÅŸlem var"
msgid "Another issue tracker is already in use. Only one issue tracker service can be active at a time"
msgstr ""
@@ -2287,26 +2490,26 @@ msgid "Any"
msgstr "Herhangi"
msgid "Any Author"
-msgstr ""
-
-msgid "Any Label"
-msgstr "Herhangi bir etiket"
-
-msgid "Any Milestone"
-msgstr ""
+msgstr "Herhangi yazar"
msgid "Any branch"
-msgstr ""
+msgstr "Herhangi dal"
msgid "Any eligible user"
msgstr "Herhangi bir uygun kullanıcı"
msgid "Any encrypted tokens"
+msgstr "Herhangi şifreli erişim anahtarları"
+
+msgid "Any label"
msgstr ""
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr "Herhangi isim alanı"
@@ -2370,6 +2573,9 @@ msgstr "Etiket uygula"
msgid "Apply a template"
msgstr "Bir ÅŸablon uygula"
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr "Öneriyi uygula"
@@ -2433,17 +2639,11 @@ msgid "ApprovalRule|Rule name"
msgstr "Kural adı"
msgid "ApprovalRule|Target branch"
-msgstr ""
+msgstr "Hedef dal"
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr "örneğin. QA, Güvenlik vb."
-msgid "Approvals"
-msgstr "Onaylar"
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr "Onayla"
@@ -2453,17 +2653,23 @@ msgstr "Bir birleÅŸtirme talebini onayla"
msgid "Approve the current merge request."
msgstr "Geçerli birleştirme talebini onayla."
-msgid "Approved by: "
+msgid "Approved"
msgstr ""
+msgid "Approved by: "
+msgstr "Onaylayan: "
+
msgid "Approved the current merge request."
msgstr "Geçerli birleştirme talebi onaylandı."
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr "Onaylayıcı"
msgid "Approvers"
-msgstr ""
+msgstr "Onaylayanlar"
msgid "Apr"
msgstr "Nis"
@@ -2472,7 +2678,7 @@ msgid "April"
msgstr "Nisan"
msgid "Archive"
-msgstr ""
+msgstr "ArÅŸiv"
msgid "Archive jobs"
msgstr "ArÅŸiv iÅŸleri"
@@ -2481,10 +2687,10 @@ msgid "Archive project"
msgstr "Projeyi arÅŸivle"
msgid "Archived"
-msgstr ""
+msgstr "ArÅŸivlenmiÅŸ"
msgid "Archived project! Repository and other project resources are read only"
-msgstr ""
+msgstr "Arşivlenmiş proje! Depo ve diğer proje kaynakları sadece okunabilir özelliğe sahiptir"
msgid "Archived project! Repository and other project resources are read-only"
msgstr "Proje arşivlendi! Depo ve diğer proje kaynakları sadece okunur"
@@ -2496,7 +2702,7 @@ msgid "Archiving the project will make it entirely read only. It is hidden from
msgstr ""
msgid "Are you setting up GitLab for a company?"
-msgstr ""
+msgstr "GitLab'ı bir şirket için mi kuruyorsunuz?"
msgid "Are you sure that you want to archive this project?"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr "%{group_name} grubunu silmek istediÄŸinizden emin misiniz?"
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr "Bu kimliği kaldırmak istediğinizden emin misiniz?"
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr "Sağlık kontrolü erişim anahtarını sıfırlamak istediğinizden emin misiniz?"
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,13 +2902,16 @@ msgstr "Atanan sorunlar"
msgid "Assigned Merge Requests"
msgstr "Atanan Karşılaştırma İstekleri"
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr "Bana atanan"
msgid "Assignee"
msgid_plural "%d Assignees"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Vekil"
+msgstr[1] "%d Vekil"
msgid "Assignee lists not available with your current license"
msgstr "Atanan listeleri mevcut lisansınızla birlikte kullanılamıyor"
@@ -2708,7 +2920,7 @@ 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 "Atanan(lar)"
+msgstr "Vekil(ler)"
msgid "Assigns %{assignee_users_sentence}."
msgstr ""
@@ -2749,7 +2961,7 @@ msgid "AuditEvents|(removed)"
msgstr "(kaldırıldı)"
msgid "AuditEvents|Action"
-msgstr ""
+msgstr "Ä°ÅŸlem"
msgid "AuditEvents|At"
msgstr ""
@@ -2767,15 +2979,33 @@ msgid "AuditLogs|Author"
msgstr ""
msgid "AuditLogs|Date"
+msgstr "Tarih"
+
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
msgstr ""
msgid "AuditLogs|IP Address"
+msgstr "IP Adresi"
+
+msgid "AuditLogs|No matching %{type} found."
msgstr ""
msgid "AuditLogs|Object"
+msgstr "Nesne"
+
+msgid "AuditLogs|Project Events"
msgstr ""
msgid "AuditLogs|Target"
+msgstr "Hedef"
+
+msgid "AuditLogs|User Events"
msgstr ""
msgid "Aug"
@@ -2794,7 +3024,7 @@ msgid "Authenticating"
msgstr "Kimlik doğrulanıyor"
msgid "Authentication Failure"
-msgstr ""
+msgstr "Kimlik Doğrulaması Başarısız"
msgid "Authentication Log"
msgstr "Kimlik Doğrulama Günlüğü"
@@ -2818,7 +3048,7 @@ msgid "Author"
msgstr "Yazar"
msgid "Authored %{timeago} by %{author}"
-msgstr ""
+msgstr "%{author} tarafından %{timeago} yazıldı"
msgid "Authorization code:"
msgstr "Yetkilendirme kodu:"
@@ -2835,6 +3065,9 @@ msgstr "Yetki Ver"
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr "%{new_chat_name} yetkilendirildi"
@@ -2856,9 +3089,6 @@ msgstr "Auto DevOps etkinleÅŸtirildi"
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr "Otomatik DevOps belgeleri"
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr "Ayarlardan etkinleÅŸtirin"
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr "Let's Encrypt kullanarak otomatik sertifika yönetimi"
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr "Otomatik olarak varsayılan kullanıcı olarak işaretlendi"
@@ -2922,6 +3158,9 @@ msgstr "Not"
msgid "Available"
msgstr "Kullanılabilir"
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -2944,7 +3183,7 @@ msgid "Average per day: %{average}"
msgstr "Günlük ortalama: %{average}"
msgid "Back to page %{number}"
-msgstr ""
+msgstr "%{number} sayfasına geri dön"
msgid "Background Color"
msgstr "Arkaplan Rengi"
@@ -3154,7 +3393,7 @@ msgid "Blocked"
msgstr "EngellenmiÅŸ"
msgid "Blocked issue"
-msgstr ""
+msgstr "Engellenen sorun"
msgid "Blocks"
msgstr ""
@@ -3316,7 +3555,7 @@ msgid "Branches|Show stale branches"
msgstr "Eskimiş dalları göster"
msgid "Branches|Sort by"
-msgstr "Sıralama"
+msgstr "Göre sırala"
msgid "Branches|Stale"
msgstr "EskimiÅŸ"
@@ -3397,6 +3636,9 @@ msgid "BurndownChartLabel|Open issue weight"
msgstr ""
msgid "BurndownChartLabel|Open issues"
+msgstr "Açık sorunlar"
+
+msgid "Burnup chart"
msgstr ""
msgid "Business"
@@ -3405,11 +3647,8 @@ msgstr "Ä°ÅŸ"
msgid "Business metrics (Custom)"
msgstr "İş metrikleri (Özel)"
-msgid "Buy EE"
-msgstr "EE satın al"
-
-msgid "Buy GitLab Enterprise Edition"
-msgstr "Gitlab Kurumsal Sürümünü satın alın"
+msgid "Buy License"
+msgstr ""
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -3424,7 +3663,7 @@ msgid "By default, all projects and groups will use the global notifications set
msgstr "Varsayılan olarak, tüm projeler ve gruplar genel bildirimler ayarını kullanacaktır."
msgid "ByAuthor|by"
-msgstr "tarafından:"
+msgstr "tarafından"
msgid "CHANGELOG"
msgstr "DEĞİŞİKLİKGÜNLÜĞÜ"
@@ -3432,8 +3671,8 @@ msgstr "DEĞİŞİKLİKGÜNLÜĞÜ"
msgid "CI / CD"
msgstr "CI/CD"
-msgid "CI / CD Charts"
-msgstr "CI / CD Çizelgeleri"
+msgid "CI / CD Analytics"
+msgstr ""
msgid "CI / CD Settings"
msgstr "CI / CD Ayarları"
@@ -3441,6 +3680,9 @@ msgstr "CI / CD Ayarları"
msgid "CI Lint"
msgstr "CI Lint"
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr "CI deÄŸiÅŸkenleri"
@@ -3459,6 +3701,9 @@ msgstr "CI/CD için harici depo"
msgid "CI/CD settings"
msgstr "CI / CD ayarları"
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr "Otomatik DevOps"
@@ -3489,9 +3734,6 @@ msgstr "Alternatif CI yapılandırma dosyası bulunmazsa, Otomatik DevOps iş ha
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr "grup etkinleÅŸtirildi"
@@ -3499,7 +3741,7 @@ msgid "CICD|instance enabled"
msgstr "örnek etkinleştirildi"
msgid "CLOSED"
-msgstr ""
+msgstr "KAPATILDI"
msgid "CLOSED (MOVED)"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr "Birleştirme isteği için gereken onaylayıcıları ve onayları geçersiz kılabilir"
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr "Bu dal için HEAD işlemi bulunamadı"
@@ -3532,7 +3780,7 @@ msgid "Can't remove group members without group managed account"
msgstr ""
msgid "Can't scan the code?"
-msgstr ""
+msgstr "Kodu tarayamıyor musun?"
msgid "Can't update snippet: %{err}"
msgstr ""
@@ -3547,7 +3795,7 @@ msgid "Cancel"
msgstr "Ä°ptal"
msgid "Cancel running"
-msgstr ""
+msgstr "Çalışmayı iptal et"
msgid "Cancel this job"
msgstr "Bu iÅŸi iptal et"
@@ -3571,7 +3819,7 @@ msgid "Cannot have multiple Jira imports running at the same time"
msgstr ""
msgid "Cannot import because issues are not available in this project."
-msgstr ""
+msgstr "Bu projede sorunlar bulunmadığı için içe aktarılamıyor."
msgid "Cannot make epic confidential if it contains not-confidential issues"
msgstr ""
@@ -3580,7 +3828,7 @@ msgid "Cannot make epic confidential if it contains not-confidential sub-epics"
msgstr ""
msgid "Cannot merge"
-msgstr ""
+msgstr "BirleÅŸtirilemez"
msgid "Cannot modify managed Kubernetes cluster"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr "Kapasite eÅŸiÄŸi"
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr "Sertifika"
@@ -3619,16 +3870,16 @@ msgid "Certificate Issuer"
msgstr ""
msgid "Certificate Subject"
-msgstr ""
+msgstr "Sertifika Konusu"
msgid "Change assignee"
-msgstr ""
+msgstr "Vekil deÄŸiÅŸtir"
msgid "Change assignee(s)"
-msgstr ""
+msgstr "Vekil(ler)i deÄŸiÅŸtir"
msgid "Change assignee(s)."
-msgstr ""
+msgstr "Vekil(ler)i deÄŸiÅŸtir."
msgid "Change branches"
msgstr "Dalları değiştir"
@@ -3645,6 +3896,12 @@ msgstr "Yolu deÄŸiÅŸtir"
msgid "Change permissions"
msgstr "Ä°zinleri deÄŸiÅŸtir"
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr "Åžablonu deÄŸiÅŸtir"
@@ -3676,7 +3933,7 @@ msgid "ChangeTypeAction|This will create a new commit in order to revert the exi
msgstr ""
msgid "Changed assignee(s)."
-msgstr ""
+msgstr "Vekil(ler) deÄŸiÅŸtirildi."
msgid "Changed the title to \"%{title_param}\"."
msgstr ""
@@ -3687,9 +3944,12 @@ msgstr "DeÄŸiÅŸiklikler"
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
-msgid "Changes are unknown"
+msgid "Changes are still tracked. Useful for cluster/index migrations."
msgstr ""
+msgid "Changes are unknown"
+msgstr "DeÄŸiÅŸiklikler bilinmiyor"
+
msgid "Changes suppressed. Click to show."
msgstr "Değişiklikler bastırıldı. Göstermek için tıkla."
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3802,7 +4065,7 @@ msgid "Checkout|%{name}'s GitLab subscription"
msgstr ""
msgid "Checkout|%{selectedPlanText} plan"
-msgstr ""
+msgstr "%{selectedPlanText} planı"
msgid "Checkout|%{startDate} - %{endDate}"
msgstr ""
@@ -3810,17 +4073,8 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr "1. Profiliniz"
-
-msgid "Checkout|2. Checkout"
-msgstr "2. Ödeme"
-
-msgid "Checkout|3. Your GitLab group"
-msgstr "3. GitLab grubunuz"
-
msgid "Checkout|Billing address"
-msgstr ""
+msgstr "Fatura adresi"
msgid "Checkout|Checkout"
msgstr "Ödeme"
@@ -4093,7 +4347,7 @@ msgid "CiVariables|Cannot use Masked Variable with current value"
msgstr ""
msgid "CiVariables|Environments"
-msgstr ""
+msgstr "Ortamlar"
msgid "CiVariables|Input variable key"
msgstr "Değişken anahtarını girin"
@@ -4167,9 +4421,6 @@ msgstr "Doğrulama başarısız"
msgid "Class"
msgstr "Sınıf"
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr "Sınıflandırma Etiketi (isteğe bağlı)"
@@ -4182,6 +4433,9 @@ msgstr "Temizle"
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr "GiriÅŸi temizle"
@@ -4194,6 +4448,9 @@ msgstr "Aramayı temizle"
msgid "Clear search input"
msgstr "Arama giriÅŸini temizle"
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr "Şablonları arama girişini temizle"
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr "Genişletmek için tıklayın."
@@ -4263,6 +4517,9 @@ msgstr "SSH ile klonla"
msgid "Close"
msgstr "Kapat"
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr "%{tabname} sekmesini kapat"
@@ -4288,13 +4545,13 @@ msgid "Closed this %{quick_action_target}."
msgstr "%{quick_action_target} kapatıldı."
msgid "Closed: %{closedIssuesCount}"
-msgstr ""
+msgstr "Kapatıldı: %{closedIssuesCount}"
msgid "Closes this %{quick_action_target}."
msgstr "%{quick_action_target} bunu kapatır."
msgid "Cluster"
-msgstr ""
+msgstr "Küme"
msgid "Cluster Health"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr "Küme ismi gerekli."
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr "Kubernetes küme adını kopyala"
-msgid "ClusterIntegration|Copy Service Token"
-msgstr "Hizmet erişim anahtarını kopyala"
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr "Rol tabanlı erişim kontrolü (RBAC) kullanıyorsanız bu ayarı etkinl
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4618,7 +4878,7 @@ msgid "ClusterIntegration|Gitlab Integration"
msgstr ""
msgid "ClusterIntegration|Global default"
-msgstr ""
+msgstr "Genel varsayılan"
msgid "ClusterIntegration|Google Cloud Platform project"
msgstr "Google Cloud Platform projesi"
@@ -4638,12 +4898,12 @@ msgstr "Grup kümesi"
msgid "ClusterIntegration|Helm Tiller"
msgstr "Helm Tiller"
+msgid "ClusterIntegration|Helm release failed to install"
+msgstr ""
+
msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr "Helm, Kubernetes uygulamalarını kurmayı ve yönetmeyi kolaylaştırır. Tiller, Kubernetes kümelerinizin içinde çalışır ve grafiklerinizin sürümlerini yönetir."
-msgid "ClusterIntegration|Hide"
-msgstr "Gizle"
-
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
msgstr "Birden fazla küme oluşturuyorsanız ve Otomatik DevOps kullanıyorsanız, %{help_link_start}ilk önce bunu okuyunuz %{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -4861,7 +5127,7 @@ msgid "ClusterIntegration|Prometheus is an open-source monitoring system with %{
msgstr ""
msgid "ClusterIntegration|Provider details"
-msgstr ""
+msgstr "Sağlayıcı ayrıntıları"
msgid "ClusterIntegration|Provision Role ARN"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr "Göster"
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr "Kod sahibi onayı gerekiyor"
@@ -5271,6 +5552,9 @@ msgstr "Onaylananları daralt"
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr "Kenar çubuğunu daralt"
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5314,6 +5601,9 @@ msgid "Comment form position"
msgstr "Yorum formu konumu"
msgid "Comment is being updated"
+msgstr "Yorum güncelleniyor"
+
+msgid "Comment on lines %{startLine} to %{endLine}"
msgstr ""
msgid "Comment/Reply (quoting selected text)"
@@ -5388,7 +5678,7 @@ msgid "Commits|No related merge requests found"
msgstr "İlgili birleştirme isteği bulunamadı"
msgid "Committed by"
-msgstr ""
+msgstr "Ä°ÅŸleyen:"
msgid "Commit…"
msgstr ""
@@ -5477,14 +5767,17 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
msgstr ""
msgid "Confidentiality"
-msgstr ""
+msgstr "Gizlilik"
msgid "Configuration"
msgstr ""
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr "Depolama dizini ayarlarını yapılandırın."
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr "Bağlantı zaman aşımına uğradı"
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr "Yükseltmek için satıcı ile iletişim kurun"
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr "Etiket"
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr "Katkı"
msgid "Contribution Analytics"
msgstr "Katkı Analizi"
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
-msgstr ""
-
msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgstr "<strong>%{created_count}</strong> oluşturuldu, <strong>%{closed_count}</strong> kapatıldı."
+
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5861,16 +6161,16 @@ msgid "ContributionAnalytics|Contribution analytics for issues, merge requests a
msgstr ""
msgid "ContributionAnalytics|Issues"
-msgstr ""
+msgstr "Sorunlar"
msgid "ContributionAnalytics|Last 3 months"
-msgstr ""
+msgstr "Son 3 ay"
msgid "ContributionAnalytics|Last month"
-msgstr ""
+msgstr "Geçen ay"
msgid "ContributionAnalytics|Last week"
-msgstr ""
+msgstr "Geçen hafta"
msgid "ContributionAnalytics|Merge Requests"
msgstr ""
@@ -5938,6 +6238,9 @@ msgstr "%{protocol} klon URL'sini kopyala"
msgid "Copy %{proxy_url}"
msgstr "%{proxy_url} kopyala"
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,11 +6286,8 @@ msgstr "Dosya içeriğini kopyala"
msgid "Copy file path"
msgstr "Dosya yolunu kopyala"
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
-msgstr ""
+msgstr "Anahtarı kopyala"
msgid "Copy labels and milestone from %{source_issuable_reference}."
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr "Bağlantıyı kopyala"
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6017,7 +6314,7 @@ msgid "Copy trigger token"
msgstr ""
msgid "Copy value"
-msgstr ""
+msgstr "DeÄŸeri kopyala"
msgid "Could not add admins as members"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr "OluÅŸtur"
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr "Yeni bir sorun oluÅŸtur"
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr "Yeni bir depo oluÅŸtur"
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr "Grup etiketi oluÅŸtur"
msgid "Create issue"
msgstr "Sorun kaydı oluştur"
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr "BirleÅŸtirme isteÄŸi ve dal oluÅŸtur"
msgid "Create milestone"
msgstr "Dönüm noktası oluştur"
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr "Yeni pano oluÅŸtur"
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr "İlk sayfanızı oluşturun"
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr "Ben oluÅŸturdum"
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6344,7 +6644,7 @@ msgid "Current Plan"
msgstr "Mevcut Plan"
msgid "Current Project"
-msgstr ""
+msgstr "Mevcut Proje"
msgid "Current node"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr "Ayarlar"
msgid "CurrentUser|Start a Gold trial"
msgstr "Altın denemesini başlat"
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr "Özel renkler"
@@ -6466,9 +6775,12 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
-msgid "CycleAnalyticsEvent|Issue closed"
+msgid "Cycle Time"
msgstr ""
+msgid "CycleAnalyticsEvent|Issue closed"
+msgstr "Sorun kapatıldı"
+
msgid "CycleAnalyticsEvent|Issue created"
msgstr ""
@@ -6491,10 +6803,10 @@ msgid "CycleAnalyticsEvent|Issue label was removed"
msgstr ""
msgid "CycleAnalyticsEvent|Issue last edited"
-msgstr ""
+msgstr "Sorun en son düzenlendi"
msgid "CycleAnalyticsEvent|Merge request closed"
-msgstr ""
+msgstr "Birleştirme talebi kapatıldı"
msgid "CycleAnalyticsEvent|Merge request created"
msgstr ""
@@ -6515,7 +6827,7 @@ msgid "CycleAnalyticsEvent|Merge request last build start time"
msgstr ""
msgid "CycleAnalyticsEvent|Merge request last edited"
-msgstr ""
+msgstr "Birleştirme talebi en son düzenlendi"
msgid "CycleAnalyticsEvent|Merge request merged"
msgstr ""
@@ -6664,7 +6976,7 @@ msgid "Date range cannot exceed %{maxDateRange} days."
msgstr ""
msgid "Day of month"
-msgstr ""
+msgstr "Ayın günü"
msgid "DayTitle|F"
msgstr ""
@@ -6709,12 +7021,15 @@ msgid "Default artifacts expiration"
msgstr ""
msgid "Default branch"
-msgstr ""
+msgstr "Varsayılan dal"
msgid "Default branch and protected branches"
msgstr ""
msgid "Default classification label"
+msgstr "Varsayılan sınıflandırma etiketi"
+
+msgid "Default dashboard"
msgstr ""
msgid "Default deletion adjourned period"
@@ -6736,13 +7051,13 @@ msgid "Default issue template"
msgstr "Varsayılan sorun şablonu"
msgid "Default project deletion protection"
-msgstr ""
+msgstr "Varsayılan proje silme koruması"
msgid "Default projects limit"
-msgstr ""
+msgstr "Varsayılan proje limiti"
msgid "Default stages"
-msgstr ""
+msgstr "Varsayılan aşamalar"
msgid "Default: Directly import the Google Code email address or username"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6763,10 +7081,10 @@ msgid "DelayedJobs|Are you sure you want to run %{job_name} immediately? This jo
msgstr ""
msgid "DelayedJobs|Start now"
-msgstr ""
+msgstr "Åžimdi baÅŸla"
msgid "DelayedJobs|Unschedule"
-msgstr ""
+msgstr "Zamanlamayı kaldır"
msgid "DelayedJobs|delayed"
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr "Yorumu sil"
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr "Lisansı sil"
@@ -6823,7 +7147,7 @@ msgid "Delete this attachment"
msgstr "Bu eki sil"
msgid "Delete variable"
-msgstr ""
+msgstr "DeÄŸiÅŸkeni sil"
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr ""
@@ -6853,7 +7177,7 @@ msgid "Deleted in this version"
msgstr ""
msgid "Deleting"
-msgstr ""
+msgstr "Siliniyor"
msgid "Deleting the license failed."
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -6976,8 +7286,8 @@ msgstr[1] ""
msgid "Depends on <strong>%d closed</strong> merge request."
msgid_plural "Depends on <strong>%d closed</strong> merge requests."
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "<strong>%d kapanan</strong> birleştirme isteğine bağlıdır."
+msgstr[1] "<strong>%d kapanan</strong> birleştirme isteğine bağlıdır."
msgid "Deploy"
msgid_plural "Deploys"
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr "Dağıtıcı belirteci ekleyin"
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr "Kayıt defteri resimlerine salt okunur erişim sağlar"
msgid "DeployTokens|Allows read-only access to the repository"
msgstr "Kayıt defteri görüntülerine salt okunur erişimi sağlar"
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr "Dağıtıcı Belirteci"
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7165,7 +7481,7 @@ msgid "Deployment|failed"
msgstr ""
msgid "Deployment|running"
-msgstr ""
+msgstr "çalışıyor"
msgid "Deployment|success"
msgstr ""
@@ -7209,21 +7525,36 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
-msgstr "Tasarım ekle"
-
msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
+msgstr ""
+
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr "Sil"
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr "İstenen tasarım sürümü mevcut değil. Bunun yerine en son sürüm gösteriliyor"
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr "Tasarımlar"
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr "Ayrıntılar"
@@ -7405,7 +7763,7 @@ msgid "Discover|Start a free trial"
msgstr ""
msgid "Discover|Upgrade now"
-msgstr ""
+msgstr "Şimdi yükselt"
msgid "Discuss a specific suggestion or question"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr "Resmi indir"
msgid "Download license"
msgstr "Lisansı indir"
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr "Kaynak kodu indir"
@@ -7586,9 +7950,12 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
-msgid "Due date"
+msgid "Due Date"
msgstr ""
+msgid "Due date"
+msgstr "BitiÅŸ tarihi"
+
msgid "Duration"
msgstr ""
@@ -7698,10 +8065,10 @@ msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
msgid "Edited %{timeago}"
-msgstr ""
+msgstr "%{timeago} düzenlendi"
msgid "Editing"
-msgstr ""
+msgstr "Düzenleme"
msgid "Elasticsearch"
msgstr "Esnek arama"
@@ -7733,6 +8100,9 @@ msgstr "E-posta"
msgid "Email address"
msgstr "E-posta adresi"
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr "E-postalarda üstbilgi ve altbilgiyi etkinleştir"
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -7890,7 +8266,7 @@ msgid "Enable or disable Seat Link."
msgstr ""
msgid "Enable or disable keyboard shortcuts"
-msgstr ""
+msgstr "Klavye kısayollarını etkinleştir veya devre dışı bırak"
msgid "Enable or disable the Pseudonymizer data collection."
msgstr ""
@@ -7935,13 +8311,13 @@ msgid "EnableReviewApp|%{stepStart}Step 3%{stepEnd}. Add it to the project %{lin
msgstr ""
msgid "EnableReviewApp|Close"
-msgstr ""
+msgstr "Kapat"
msgid "EnableReviewApp|Copy snippet text"
msgstr ""
msgid "Enabled"
-msgstr "EtkinleÅŸtirildi"
+msgstr "Etkin"
msgid "Enabled Git access protocols"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr "Birleştirme isteği açıklamasını girin"
msgid "Enter the merge request title"
msgstr "Birleştirme isteğinin başlığını girin"
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8064,7 +8443,7 @@ msgid "Environments"
msgstr ""
msgid "Environments Dashboard"
-msgstr ""
+msgstr "Ortam Gösterge Panosu"
msgid "Environments allow you to track deployments of your application %{link_to_read_more}."
msgstr ""
@@ -8087,11 +8466,11 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
-msgstr ""
+msgstr "Kaldır"
msgid "EnvironmentsDashboard|The environments dashboard provides a summary of each project's environments' status, including pipeline and alert statuses."
msgstr ""
@@ -8139,10 +8518,10 @@ msgid "Environments|Currently showing all results."
msgstr ""
msgid "Environments|Delete"
-msgstr ""
+msgstr "Sil"
msgid "Environments|Delete environment"
-msgstr ""
+msgstr "Ortamı sil"
msgid "Environments|Deleting the '%{environmentName}' environment cannot be undone. Do you want to delete it anyway?"
msgstr ""
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8424,7 +8806,7 @@ msgid "Error loading branch data. Please try again."
msgstr "Dal verileri yüklenirken hata oluştu. Lütfen tekrar deneyin."
msgid "Error loading branches."
-msgstr ""
+msgstr "Dallar yüklenirken hata oluştu."
msgid "Error loading burndown chart data"
msgstr ""
@@ -8463,7 +8845,7 @@ msgid "Error occurred when fetching sidebar data"
msgstr ""
msgid "Error occurred when saving assignees"
-msgstr ""
+msgstr "Vekiller kaydedilirken bir hata oluÅŸtu"
msgid "Error occurred when toggling the notification subscription"
msgstr "Bildirim aboneliÄŸini deÄŸiÅŸtirirken bir sorun meydana geldi"
@@ -8493,10 +8875,7 @@ msgid "Error occurred. User was not unlocked"
msgstr ""
msgid "Error rendering markdown preview"
-msgstr "Marka oluşturma önizlemesi yapılırken hata oluştu"
-
-msgid "Error rendering query"
-msgstr ""
+msgstr "Biçimlendirme önizlemesi oluşturulurken hata oluştu"
msgid "Error saving label update."
msgstr "Etiket güncellenirken sorun oluştu."
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,14 +8991,14 @@ msgstr ""
msgid "Every day"
msgstr "Her gün"
-msgid "Every day (at 4:00am)"
-msgstr "Her gün (saat 4: 00'da)"
+msgid "Every day (at %{time})"
+msgstr ""
msgid "Every month"
msgstr "Her ay"
-msgid "Every month (on the 1st at 4:00am)"
-msgstr "Her ay (sabah saat 4: 00'de)"
+msgid "Every month (Day %{day} at %{time})"
+msgstr ""
msgid "Every three months"
msgstr "Her üç ayda bir"
@@ -8627,8 +9009,8 @@ msgstr "Her iki haftada bir"
msgid "Every week"
msgstr "Her hafta"
-msgid "Every week (Sundays at 4:00am)"
-msgstr "Her hafta (Pazar günleri saat 4:00)"
+msgid "Every week (%{weekday} at %{time})"
+msgstr ""
msgid "Everyone"
msgstr ""
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr "Birleştirme işlemleri hariç tutuluyor. 6,000 işlem ile sınırlı."
msgid "Existing members and groups"
msgstr "Mevcut üyeler ve gruplar"
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr "Kenar çubuğunu genişlet"
msgid "Expand up"
msgstr "Yukarı doğru genişlet"
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr "Süre sonu"
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr "Sınıflandırma etiketi"
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8931,7 +9316,7 @@ msgid "Failed to load milestones. Please try again."
msgstr ""
msgid "Failed to load related branches"
-msgstr ""
+msgstr "İlgili dalların yüklenmesi başarısız oldu"
msgid "Failed to load stacktrace."
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9057,7 +9445,7 @@ msgid "Feature flag was successfully removed."
msgstr ""
msgid "FeatureFlags|* (All Environments)"
-msgstr ""
+msgstr "* (Tüm Ortamlar)"
msgid "FeatureFlags|* (All environments)"
msgstr "* (Tüm ortamlar)"
@@ -9095,6 +9483,12 @@ msgstr "Açıklama"
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr "Özellik Bayrağı"
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr "Özellik Bayrakları"
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr "Özellik bayrağı %{name} kaldırılacak. Emin misiniz?"
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr "Özellik bayraklarını kullanmaya başlayın"
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr "Kimlik"
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr "Yeni"
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr "Yeni özellik bayrağı"
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9186,7 +9601,7 @@ msgid "FeatureFlags|Strategies"
msgstr ""
msgid "FeatureFlags|Target environments"
-msgstr ""
+msgstr "Hedef ortamlar"
msgid "FeatureFlags|There are no active feature flags"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr "Dosya silindi"
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr "Dosya adı"
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr "Dosya şablonları"
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr "Dosyalar"
@@ -9290,38 +9708,62 @@ msgstr ""
msgid "Filter"
msgstr "Süzgeç"
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr "Kapalı olan %{issuable_type} türüne göre süz."
msgid "Filter by %{issuable_type} that are currently opened."
msgstr "Açık olan %{issuable_type} türüne göre süz."
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr "İşlem mesajına göre süz"
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr "Dönüm noktası adına göre süz"
msgid "Filter by name"
+msgstr "İsme göre filtrele"
+
+msgid "Filter by requirements that are currently archived."
msgstr ""
-msgid "Filter by status"
+msgid "Filter by requirements that are currently opened."
msgstr ""
+msgid "Filter by status"
+msgstr "Duruma göre filtrele"
+
msgid "Filter by two-factor authentication"
msgstr "İki adımlı kimlik doğrulamasına göre süz"
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr "Projeleri filtrele"
msgid "Filter results"
-msgstr ""
+msgstr "Sonuçları filtrele"
msgid "Filter results by group"
msgstr "Sonuçları gruba göre süz"
@@ -9330,7 +9772,7 @@ msgid "Filter results by project"
msgstr "Projeye göre sonuçları süz"
msgid "Filter results..."
-msgstr ""
+msgstr "Sonuçları filtrele..."
msgid "Filter your projects by name"
msgstr "Projelerinizi isme göre filtreleyin"
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr "CoÄŸrafi"
-msgid "Geo Designs"
-msgstr "Coğrafi Tasarımlar"
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr "CoÄŸrafi Ayarlar"
@@ -9747,7 +10186,7 @@ msgid "GeoNodes|Unverified"
msgstr ""
msgid "GeoNodes|Updated %{timeAgo}"
-msgstr ""
+msgstr "%{timeAgo} güncellendi"
msgid "GeoNodes|Used slots"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9810,7 +10255,7 @@ msgid "Geo|Failed"
msgstr ""
msgid "Geo|Filter by status"
-msgstr ""
+msgstr "Duruma göre filtrele"
msgid "Geo|Geo Status"
msgstr "CoÄŸrafi Durum"
@@ -9839,6 +10284,12 @@ msgstr "Asla"
msgid "Geo|Next sync scheduled at"
msgstr "Sonraki senkronizasyon planlandı"
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr "Durum"
@@ -9908,6 +10362,9 @@ 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|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,9 +10374,15 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
-msgid "Geo|Unknown state"
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
msgstr ""
+msgid "Geo|Unknown state"
+msgstr "Bilinmeyen konum"
+
msgid "Geo|Verification failed - %{error}"
msgstr ""
@@ -10005,7 +10468,7 @@ msgid "GitLab Import"
msgstr "GitLab içe aktarma"
msgid "GitLab Issue"
-msgstr ""
+msgstr "GitLab Sorunu"
msgid "GitLab Shared Runners execute code of different projects on the same Runner unless you configure GitLab Runner Autoscale with MaxBuilds 1 (which it is on GitLab.com)."
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr "Gitea içe aktarma"
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr "GitLab Sayfaları"
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr "Tam ekrana git"
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10269,19 +10726,19 @@ msgid "Go to repository charts"
msgstr ""
msgid "Go to repository graph"
-msgstr ""
+msgstr "Depo grafiÄŸine git"
msgid "Go to snippets"
msgstr "Parçacıklara git"
msgid "Go to the activity feed"
-msgstr ""
+msgstr "Etkinlik akışına gidin"
msgid "Go to the milestone list"
-msgstr ""
+msgstr "Dönüm noktası listesine gidin"
msgid "Go to the project's activity feed"
-msgstr ""
+msgstr "Projenin etkinlik akışına gidin"
msgid "Go to the project's overview page"
msgstr "Projenin genel bakış sayfasına git"
@@ -10296,13 +10753,13 @@ msgid "Go to your fork"
msgstr "Çatalınıza gidin"
msgid "Go to your groups"
-msgstr ""
+msgstr "Gruplarınıza gidin"
msgid "Go to your issues"
-msgstr ""
+msgstr "Sorunlarınıza gidin"
msgid "Go to your merge requests"
-msgstr ""
+msgstr "BirleÅŸtirme isteklerinize gidin"
msgid "Go to your projects"
msgstr "Projelerinize gidin"
@@ -10370,12 +10827,21 @@ msgstr "Gravatar etkinleÅŸtirildi"
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr "Grup profil resmi"
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr "Grubun açıklaması"
@@ -10421,10 +10893,13 @@ msgstr "Grup ayrıntıları"
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr "Grup sorumluları, grup çalıştırıcılarını %{link} içinde kayded
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr "Grup iş hattı kayıtları başarıyla sıfırlandı."
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr "Grup başarıyla güncellendi."
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr "Geçmiş"
msgid "History of authentications"
msgstr "Kimlik doğrulama geçmişi"
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr "Kanca başarıyla güncellendi."
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,15 +11677,15 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
+msgid "Impersonation Tokens"
+msgstr ""
+
msgid "Impersonation has been disabled"
msgstr ""
msgid "Import"
msgstr "İçe Aktar"
-msgid "Import %{status}"
-msgstr ""
-
msgid "Import CSV"
msgstr "CSV'yi içe aktar"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr "Tüm projeleri içe aktar"
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,12 +11719,12 @@ msgstr ""
msgid "Import in progress"
msgstr "İçe aktarma devam ediyor"
+msgid "Import in progress. Refresh page to see newly added issues."
+msgstr ""
+
msgid "Import issues"
msgstr "İçe aktarma sorunları"
-msgid "Import issues from Jira"
-msgstr ""
-
msgid "Import members"
msgstr ""
@@ -11298,10 +11815,10 @@ msgstr "GitLab Kurumsal Sürüm ile sorun panolarını iyileştirin."
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr "Birleştirme isteği açıklamasını dahil et"
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr "Tüm projeleri dizinle"
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr "Bir alıntı ekle"
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr "Kod ekle"
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr "Öneri ekle"
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr "Entegrasyonlar"
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr "Geçersiz giriş ya da şifre"
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr "Geçersiz giriş ya da şifre"
msgid "Invalid pin code"
msgstr "Geçersiz pin kodu"
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr "Geçersiz depo yolu"
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr "Geçersiz iki adımlı doğrulama kodu."
@@ -11552,6 +12135,9 @@ msgstr "Davet et"
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr "Grup davet et"
@@ -11574,10 +12160,10 @@ msgid "Is using seat"
msgstr ""
msgid "IssuableStatus|Closed"
-msgstr ""
+msgstr "Kapatıldı"
msgid "IssuableStatus|Closed (%{link})"
-msgstr ""
+msgstr "Kapatıldı (%{link})"
msgid "IssuableStatus|duplicated"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11622,11 +12211,38 @@ msgid "Issue update failed"
msgstr ""
msgid "Issue was closed by %{name} %{reason}"
-msgstr ""
+msgstr "Sorun, %{name} %{reason} tarafından kapatıldı"
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr "Pano"
@@ -11684,6 +12300,9 @@ msgstr "Sorunlar kapalı"
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11697,7 +12316,7 @@ msgid "IssuesAnalytics|Avg/Month:"
msgstr "Ortalama/Ay:"
msgid "IssuesAnalytics|Issues opened"
-msgstr ""
+msgstr "Sorun açıldı"
msgid "IssuesAnalytics|Issues opened per month"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr "Bu sensin"
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr "Oca"
msgid "January"
msgstr "Ocak"
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11865,10 +12511,10 @@ msgid "Job|Pipeline"
msgstr ""
msgid "Job|Scroll to bottom"
-msgstr ""
+msgstr "En alta kaydır"
msgid "Job|Scroll to top"
-msgstr ""
+msgstr "En üste kaydır"
msgid "Job|Show complete raw"
msgstr ""
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr "Haziran"
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -11928,10 +12580,10 @@ msgid "Key: %{key}"
msgstr ""
msgid "Keyboard Shortcuts"
-msgstr ""
+msgstr "Klavye Kısayolları"
msgid "Keyboard shortcuts"
-msgstr ""
+msgstr "Klavye kısayolları"
msgid "Kubernetes"
msgstr ""
@@ -12086,15 +12738,18 @@ msgid "Last contact"
msgstr ""
msgid "Last edited %{date}"
-msgstr ""
+msgstr "Son düzenleme: %{date}"
msgid "Last edited by %{name}"
-msgstr ""
+msgstr "En son %{name} tarafından düzenlendi"
msgid "Last name"
msgstr "Soyadı"
msgid "Last reply by"
+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"
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr "\"Dosya türü\" ve \"Teslim yöntemi\" seçeneklerini varsayılan değerlerinde bırakın."
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr "Lisans"
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr "Lisans"
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr "Yükleniyor..."
msgid "Loading…"
msgstr "Yükleniyor…"
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr "YerelleÅŸtirme"
@@ -12555,7 +13219,7 @@ msgid "Locked Files"
msgstr "Kilitli Dosyalar"
msgid "Locked by %{fileLockUserName}"
-msgstr ""
+msgstr "%{fileLockUserName} tarafından kilitlendi"
msgid "Locked the discussion."
msgstr "Tartışma kilitlendi."
@@ -12591,7 +13255,7 @@ msgid "MD5"
msgstr ""
msgid "MERGED"
-msgstr ""
+msgstr "BÄ°RLEÅžTÄ°RÄ°LDÄ°"
msgid "MR widget|Take a look at our %{beginnerLinkStart}Beginner's Guide to Continuous Integration%{beginnerLinkEnd} and our %{exampleLinkStart}examples of GitLab CI/CD%{exampleLinkEnd} to see all the cool stuff you can do with it."
msgstr ""
@@ -12603,7 +13267,7 @@ msgid "MRApprovals|Approvals"
msgstr ""
msgid "MRApprovals|Approved by"
-msgstr ""
+msgstr "Onaylayan:"
msgid "MRApprovals|Approvers"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr "Grup etiketlerini yönet"
msgid "Manage labels"
msgstr "Etiketleri yönet"
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr "Proje etiketlerini yönet"
@@ -12716,9 +13383,6 @@ msgstr "Bitti olarak iÅŸaretle"
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12726,16 +13390,13 @@ msgid "Mark this issue as related to another issue"
msgstr ""
msgid "Markdown"
-msgstr ""
-
-msgid "Markdown Help"
-msgstr ""
+msgstr "Biçimlendirme"
msgid "Markdown enabled"
-msgstr ""
+msgstr "Biçimlendirme etkin"
msgid "Markdown is supported"
-msgstr ""
+msgstr "Biçimlendirme desteklenmektedir"
msgid "Marked To Do as done."
msgstr "Yapılacaklar yapıldı olarak işaretlendi."
@@ -12908,6 +13569,9 @@ msgstr "Üyeler, <i>Sorumlu</i> veya <i>Sahipleri</i> tarafından eklenebilir"
msgid "Members of <strong>%{project_name}</strong>"
msgstr "<strong>%{project_name}</strong> projesinin üyeleri"
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr "BirleÅŸtirme Ä°steÄŸi"
msgid "Merge Request Approvals"
msgstr "Birleştirme İsteği Onayları"
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr "BirleÅŸtirme Ä°stekleri"
@@ -12957,7 +13621,7 @@ msgid "Merge in progress"
msgstr "BirleÅŸtirme devam ediyor"
msgid "Merge options"
-msgstr ""
+msgstr "Birleştirme seçenekleri"
msgid "Merge request"
msgstr "BirleÅŸtirme isteÄŸi"
@@ -12965,6 +13629,9 @@ msgstr "BirleÅŸtirme isteÄŸi"
msgid "Merge request %{iid} authored by %{authorName}"
msgstr "%{iid} birleştirme talebi %{authorName} tarafından oluşturuldu"
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr "Birleştirme isteği onayları"
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
msgstr "Bir yanıt ekle"
+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."
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,11 +13770,14 @@ msgstr ""
msgid "Merged"
msgstr "BirleÅŸtirildi"
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
msgid "Merged this merge request."
-msgstr ""
+msgstr "Bu birleÅŸtirme isteÄŸi birleÅŸtirildi."
msgid "Merges this merge request immediately."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr "Mesajlar"
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr "Metrikler"
msgid "Metrics - Grafana"
msgstr "Metrikler - Grafana"
-msgid "Metrics - Influx"
-msgstr "Metrikler - Influx"
-
msgid "Metrics - Prometheus"
msgstr "Metrikler - Prometheus"
msgid "Metrics Dashboard"
msgstr "Metrikler Gösterge Panosu"
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr "Metrik ekle"
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr "Birim etiketi"
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr "Grafik için başlık olarak kullanılır"
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr "Dönüm Noktaları"
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr "Dönüm noktasını sil"
@@ -13365,21 +14140,39 @@ msgstr "%{milestoneTitle} adındaki dönüm noktasını silmek istiyor musunuz?"
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr "Ä°ptal"
@@ -13504,7 +14300,7 @@ msgid "More than %{number_commits_distance} commits different with %{default_bra
msgstr ""
msgid "Most stars"
-msgstr "Popüler olan"
+msgstr "Popüler Olanlar"
msgid "Mount point %{mounted_as} not found in %{model_class}."
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr "Çoklu sorun panoları"
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr "Yeni etiketi adlandır"
@@ -13587,9 +14386,6 @@ msgstr "Ä°sim:"
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] "Yeni Sorun"
msgstr[1] "Yeni Sorunlar"
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13716,6 +14563,9 @@ msgid "New issue"
msgstr "Yeni sorun"
msgid "New issue title"
+msgstr "Yeni sorun başlığı"
+
+msgid "New iteration created"
msgstr ""
msgid "New label"
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr "Etiket yok"
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13830,7 +14674,7 @@ msgid "No available namespaces to fork the project."
msgstr ""
msgid "No branches found"
-msgstr ""
+msgstr "Dal bulunamadı"
msgid "No changes"
msgstr ""
@@ -13854,7 +14698,7 @@ msgid "No contributions were found"
msgstr "Hiçbir katkı bulunamadı"
msgid "No credit card required."
-msgstr ""
+msgstr "Kredi kartı gerektirmez."
msgid "No data found"
msgstr ""
@@ -13866,7 +14710,7 @@ msgid "No deployments found"
msgstr ""
msgid "No due date"
-msgstr ""
+msgstr "BitiÅŸ tarihi yok"
msgid "No endpoint provided"
msgstr ""
@@ -13875,7 +14719,7 @@ msgid "No errors to display."
msgstr ""
msgid "No estimate or time spent"
-msgstr ""
+msgstr "Tahmini ya da harcanan zaman yok"
msgid "No file chosen"
msgstr "Seçili dosya yok"
@@ -13895,12 +14739,18 @@ msgstr "Dosya bulunamadı."
msgid "No forks are available to you."
msgstr "Kullanabileceğiniz çatal yok."
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr "Birleştirme isteği bulunamadı"
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr "Gösterilecek dönüm noktası yok"
@@ -14031,7 +14884,7 @@ msgid "Not available for protected branches"
msgstr ""
msgid "Not confidential"
-msgstr ""
+msgstr "Gizli deÄŸil"
msgid "Not enough data"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr "Bu yorumu oluşturmayı iptal etmek istediğinizden emin misiniz?"
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr "Tüm etkinlikleri göster"
@@ -14198,9 +15057,15 @@ msgstr "Kas"
msgid "November"
msgstr "Kasım"
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14256,7 +15121,7 @@ msgid "Ok let's go"
msgstr ""
msgid "Oldest first"
-msgstr ""
+msgstr "Önce en eski"
msgid "OmniAuth"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 "Dışa aktarılan dosya hazır olduğunda, indirme bağlantısına sahip bir bildirim e-postası alacaksınız veya bu sayfadan indirebilirsiniz."
@@ -14344,7 +15215,7 @@ msgstr "Sadece proje üyeleri yorum yapabilir."
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14384,19 +15255,19 @@ msgid "Open: %{openIssuesCount}"
msgstr ""
msgid "Open: %{open} • Closed: %{closed}"
-msgstr ""
+msgstr "Açık: %{open} • Kapalı: %{closed}"
msgid "Opened"
msgstr "Açıldı"
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
msgstr "Açılan sorunlar"
msgid "OpenedNDaysAgo|Opened"
-msgstr ""
+msgstr "Açıldı"
msgid "Opens in a new window"
msgstr ""
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14585,7 +15471,7 @@ msgid "PackageRegistry|Delete package"
msgstr ""
msgid "PackageRegistry|Filter by name"
-msgstr ""
+msgstr "İsme göre filtrele"
msgid "PackageRegistry|For more information on the Conan registry, %{linkStart}see the documentation%{linkEnd}."
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr "Paketler"
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr "Şifre başarıyla değiştirildi"
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr "Yol"
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr "Ä°ndir"
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15002,7 +15918,7 @@ msgid "Pipelines for last month (%{oneMonthAgo} - %{today})"
msgstr ""
msgid "Pipelines for last week (%{oneWeekAgo} - %{today})"
-msgstr ""
+msgstr "Geçen haftaki iş hatları (%{oneWeekAgo} - %{today})"
msgid "Pipelines for last year"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr "'%{project_name}' için iş hattı ayarları başarıyla güncellendi."
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr "Ä°ÅŸlem"
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr "Dalları ara"
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15227,7 +16188,7 @@ msgid "Please enable and migrate to hashed storage to avoid security issues and
msgstr ""
msgid "Please ensure your account's %{account_link_start}recovery settings%{account_link_end} are up to date."
-msgstr ""
+msgstr "Lütfen hesabınızın %{account_link_start}kurtarma ayarlarının%{account_link_end} güncel olduğundan emin olun."
msgid "Please enter a non-negative number"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr "Tercihler"
@@ -15424,6 +16391,9 @@ msgstr "Göreceli zamanları kullan"
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15449,7 +16419,7 @@ msgid "Preview"
msgstr "Önizleme"
msgid "Preview Markdown"
-msgstr ""
+msgstr "Biçimlendirme Önizlemesi"
msgid "Preview changes"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr "Önizleme yükü"
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15662,7 +16635,7 @@ msgid "Profiles|Edit Profile"
msgstr "Profili Düzenle"
msgid "Profiles|Enter your name, so people you know can recognize you"
-msgstr "Adınızı girin, böylece tanıdığınız kişiler sizi tanıyabilir"
+msgstr "Adınızı girin, böylece insanlar sizi tanıyabilir"
msgid "Profiles|Expires at"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr "Tam isim"
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr "KiÅŸiselleÅŸtirme"
-
msgid "Profiles|Include private contributions on my profile"
msgstr "Profilime özel katkıları ekle"
@@ -15701,7 +16671,7 @@ msgid "Profiles|Key"
msgstr "Anahtar"
msgid "Profiles|Last used:"
-msgstr ""
+msgstr "Son kullanılan:"
msgid "Profiles|Learn more"
msgstr "Daha fazla bilgi edin"
@@ -15727,9 +16697,6 @@ msgstr "Organizasyon"
msgid "Profiles|Path"
msgstr "Yol"
-msgid "Profiles|Personal Access"
-msgstr "KiÅŸisel EriÅŸim"
-
msgid "Profiles|Position and size your new avatar"
msgstr "Yeni profil resminizi konumlandırın ve boyutlandırın"
@@ -15874,12 +16841,6 @@ msgstr "Durumunuz"
msgid "Profiles|e.g. My MacBook key"
msgstr "Örneğin. MacBook anahtarım"
-msgid "Profiles|impersonation"
-msgstr "kiÅŸisellleÅŸtirme"
-
-msgid "Profiles|personal access"
-msgstr "kiÅŸisel eriÅŸim"
-
msgid "Profiles|username"
msgstr "kullanıcıadı"
@@ -15890,10 +16851,10 @@ msgid "Profiles|your account"
msgstr "hesabınız"
msgid "Profile|%{job_title} at %{organization}"
-msgstr ""
+msgstr "%{organization} kurumunda %{job_title}"
msgid "Profiling - Performance bar"
-msgstr ""
+msgstr "Profil oluşturma - Performans çubuğu"
msgid "Programming languages used in this repository"
msgstr "Bu depoda kullanılan programlama dilleri"
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr "'%{project_name}' projesi başarıyla güncellendi."
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr "'%{project_name}' projesi %{date} tarihinde silinecek"
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr "Proje profil resmi"
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr "Hizmetler dahil olmak üzere proje yapılandırması"
@@ -15985,8 +16955,8 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
-msgstr "Proje dışa aktarma başladı. Bir indirme bağlantısı e-posta ile gönderilecektir."
+msgid "Project export started. A download link will be sent by email and made available on this page."
+msgstr ""
msgid "Project has too many %{label_for_message} to search"
msgstr ""
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr "Proje üyeleri"
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr "Proje adı"
@@ -16097,7 +17070,7 @@ msgid "ProjectSelect|Search for project"
msgstr ""
msgid "ProjectService|%{service_title}: status off"
-msgstr ""
+msgstr "%{service_title}: durum kapalı"
msgid "ProjectService|%{service_title}: status on"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr "Yorum"
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr "Son düzenleme"
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr "Depo"
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr "Viki"
@@ -16471,6 +17447,9 @@ msgstr "BoÅŸ proje"
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr "Åžablondan oluÅŸtur"
@@ -16508,7 +17487,7 @@ msgid "ProjectsNew|Want to house several dependent projects under the same names
msgstr "Aynı isim alanı altında birkaç bağımlı projeye ev sahipliği yapmak ister misiniz? %{link_start}Bir grup oluşturun.%{link_end}"
msgid "Prometheus"
-msgstr ""
+msgstr "Prometheus"
msgid "PrometheusAlerts|%{count} alerts applied"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr "Grup etiketini tanıtın"
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16715,7 +17751,7 @@ msgid "Protected Tag"
msgstr ""
msgid "Protected branches"
-msgstr ""
+msgstr "Korunan dallar"
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 ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr "BENÄ°OKU"
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr "Kendi etkinliğiniz ile ilgili bildirim alın"
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr "Sürümler"
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr "Beni hatırla"
@@ -17175,7 +18241,7 @@ msgid "Remove all approvals in a merge request when new commits are pushed to it
msgstr "Yeni işlemler kaynak dalına aktarıldığında birleştirme isteğindeki tüm onayları kaldır"
msgid "Remove all or specific assignee(s)"
-msgstr ""
+msgstr "Tümünü veya özel vekil(ler)i kaldır"
msgid "Remove all or specific label(s)"
msgstr "Tüm veya belirli etiketleri kaldır"
@@ -17205,7 +18271,7 @@ msgid "Remove description history"
msgstr ""
msgid "Remove due date"
-msgstr ""
+msgstr "Bitiş tarihini kaldır"
msgid "Remove fork relationship"
msgstr "Çatal ilişkisini kaldır"
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17289,7 +18364,7 @@ msgid "Removed spent time."
msgstr ""
msgid "Removed the due date."
-msgstr ""
+msgstr "Bitiş tarihi kaldırıldı."
msgid "Removed time estimate."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17319,7 +18397,7 @@ msgid "Removes spent time."
msgstr ""
msgid "Removes the due date."
-msgstr ""
+msgstr "Bitiş tarihini kaldırır."
msgid "Removes time estimate."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17361,7 +18442,7 @@ msgid "Reopen this %{quick_action_target}"
msgstr ""
msgid "Reopened this %{quick_action_target}."
-msgstr ""
+msgstr "Bu %{quick_action_target} yeniden açıldı."
msgid "Reopens this %{quick_action_target}."
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,14 +18480,17 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
msgstr ""
-msgid "Report abuse to admin"
+msgid "Report abuse"
msgstr ""
+msgid "Report abuse to admin"
+msgstr "Kötüye kullanımı yöneticiye bildir"
+
msgid "Reported %{timeAgo} by %{reportedBy}"
-msgstr ""
+msgstr "%{reportedBy} tarafından %{timeAgo} bildirildi"
msgid "Reported Resource Changes: %{addNum} to add, %{changeNum} to change, %{deleteNum} to delete"
msgstr ""
@@ -17459,7 +18546,7 @@ msgid "Reports|Metrics reports changed on %{numberOfChanges} %{pointsString}"
msgstr ""
msgid "Reports|Metrics reports did not change"
-msgstr ""
+msgstr "Metriklerin raporları değişmedi"
msgid "Reports|Metrics reports failed loading results"
msgstr ""
@@ -17492,7 +18579,7 @@ msgid "Repository Analytics"
msgstr ""
msgid "Repository Graph"
-msgstr ""
+msgstr "Depo GrafiÄŸi"
msgid "Repository Settings"
msgstr "Depo Ayarları"
@@ -17500,6 +18587,9 @@ msgstr "Depo Ayarları"
msgid "Repository URL"
msgstr "Depo URL'si"
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17543,7 +18636,7 @@ msgid "Request to link SAML account must be authorized"
msgstr ""
msgid "Requested %{time_ago}"
-msgstr ""
+msgstr "%{time_ago} istendi"
msgid "Requested design version does not exist."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
msgstr "Profil Ä°stekleri"
-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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr "Onaylamak için kullanıcı şifresi iste"
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,11 +18762,14 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
-msgid "Resolved by %{name}"
+msgid "Resolved by"
msgstr ""
+msgid "Resolved by %{name}"
+msgstr "%{name} tarafından çözüldü"
+
msgid "Resolved by %{resolvedByName}"
-msgstr ""
+msgstr "%{resolvedByName} tarafından çözüldü"
msgid "Resolves IP addresses once and uses them to submit requests"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr "SSH Anahtarları"
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18029,25 +19134,25 @@ msgid "Scopes can't be blank"
msgstr ""
msgid "Scroll down"
-msgstr ""
+msgstr "Aşağı kaydır"
msgid "Scroll down to <strong>Google Code Project Hosting</strong> and enable the switch on the right."
msgstr ""
msgid "Scroll left"
-msgstr ""
+msgstr "Sola kaydır"
msgid "Scroll right"
-msgstr ""
+msgstr "Sağa kaydır"
msgid "Scroll to bottom"
-msgstr ""
+msgstr "En alta kaydır"
msgid "Scroll to top"
-msgstr ""
+msgstr "En üste kaydır"
msgid "Scroll up"
-msgstr ""
+msgstr "Yukarı kaydır"
msgid "Search"
msgstr "Ara"
@@ -18055,9 +19160,15 @@ msgstr "Ara"
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr "Ortam özelliklerini ara"
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr "Dalları ara"
@@ -18115,6 +19226,9 @@ msgstr "Projeleri ara"
msgid "Search projects..."
msgstr "Projeleri ara..."
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr "Kullanıcıları ara"
@@ -18145,11 +19259,11 @@ msgstr "Bana atanan istekleri birleÅŸtir"
msgid "SearchAutocomplete|in all GitLab"
msgstr "Tüm GitLab'da"
-msgid "SearchAutocomplete|in this group"
-msgstr "Bu grupta"
+msgid "SearchAutocomplete|in group %{groupName}"
+msgstr ""
-msgid "SearchAutocomplete|in this project"
-msgstr "Bu projede"
+msgid "SearchAutocomplete|in project %{projectName}"
+msgstr ""
msgid "SearchCodeResults|in"
msgstr ""
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr "Güvenlik Yapılandırması"
msgid "Security Dashboard"
msgstr "Güvenlik Kontrol Panosu"
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr "Güvenlik gösterge panosu"
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr "Yapılandırılan"
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr "Durum"
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18307,7 +19424,7 @@ msgid "SecurityReports|Comment edited on '%{vulnerabilityName}'"
msgstr ""
msgid "SecurityReports|Create issue"
-msgstr ""
+msgstr "Sorun oluÅŸtur"
msgid "SecurityReports|Dismiss Selected"
msgstr ""
@@ -18382,7 +19499,7 @@ msgid "SecurityReports|Oops, something doesn't seem right."
msgstr ""
msgid "SecurityReports|Pipeline %{pipelineLink} triggered %{timeago} by %{user}"
-msgstr ""
+msgstr "%{user} tarafından %{timeago} %{pipelineLink} iş hattı tetiklendi"
msgid "SecurityReports|Project"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18490,7 +19610,7 @@ msgid "See the affected projects in the GitLab admin panel"
msgstr ""
msgid "See what's new at GitLab"
-msgstr ""
+msgstr "GitLab'daki yenilikleri görün"
msgid "Select"
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18517,7 +19640,7 @@ msgid "Select a label"
msgstr ""
msgid "Select a namespace to fork the project"
-msgstr ""
+msgstr "Projeyi çatallamak için bir isim alanı seçin"
msgid "Select a new namespace"
msgstr "Yeni bir isim alanı seçin"
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18589,7 +19718,7 @@ msgid "Select projects"
msgstr "Projeleri seç"
msgid "Select projects you want to import."
-msgstr ""
+msgstr "İçe aktarmak istediğiniz projeleri seçin."
msgid "Select required regulatory standard"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr "Hedef dalı seç"
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18835,11 +19979,14 @@ msgid "Set default and restrict visibility levels. Configure import sources and
msgstr "Varsayılanı ayarlayın ve görünürlük seviyelerini sınırlayın. İçe aktarma kaynaklarını ve git erişim protokolünü yapılandırın."
msgid "Set due date"
-msgstr ""
+msgstr "Bitiş tarihi ayarlayın"
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr "Web terminali için en yüksek oturum süresini ayarlayın."
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,13 +20170,13 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
+msgstr "Tüm üyeleri göster"
+
+msgid "Show all requirements."
msgstr ""
msgid "Show archived projects"
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] "%d etkinliği gösteriliyor"
msgstr[1] "%d etkinlikleri gösteriliyor"
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr "%{limit} / %{total_count} sorun gösteriliyor. "
@@ -19101,25 +20271,25 @@ msgid "Side-by-side"
msgstr ""
msgid "Sidebar|Assign health status"
-msgstr ""
+msgstr "Sağlık durumu ata"
msgid "Sidebar|Change weight"
-msgstr ""
+msgstr "Ağırlığı değiştir"
msgid "Sidebar|Health status"
-msgstr ""
+msgstr "Sağlık durumu"
msgid "Sidebar|No status"
-msgstr ""
+msgstr "Durum yok"
msgid "Sidebar|None"
-msgstr ""
+msgstr "Yok"
msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
+msgstr "Yalnızca sayısal karakterlere izin verilir"
msgid "Sidebar|Weight"
-msgstr ""
+msgstr "Ağırlık"
msgid "Sign in"
msgstr "Oturum aç"
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr "Parçacıklar"
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr "Şuna göre sırala"
msgid "Sort direction"
msgstr "Sıralama yönü"
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr "EriÅŸim seviyesi, artan"
@@ -19494,7 +20685,7 @@ msgid "SortOptions|Created date"
msgstr "OluÅŸturulma tarihi"
msgid "SortOptions|Due date"
-msgstr "Son tarih"
+msgstr "BitiÅŸ tarihi"
msgid "SortOptions|Due later"
msgstr "Daha sonra"
@@ -19587,7 +20778,7 @@ msgid "SortOptions|Priority"
msgstr "Öncelik"
msgid "SortOptions|Project"
-msgstr ""
+msgstr "Proje"
msgid "SortOptions|Recent last activity"
msgstr "Son etkinlik"
@@ -19596,13 +20787,16 @@ msgid "SortOptions|Recent sign in"
msgstr "Son giriÅŸ"
msgid "SortOptions|Recently starred"
-msgstr ""
+msgstr "Yakınlarda yıldızlanan"
msgid "SortOptions|Size"
+msgstr "Boyut"
+
+msgid "SortOptions|Sort by:"
msgstr ""
msgid "SortOptions|Sort direction"
-msgstr ""
+msgstr "Sıralama yönü"
msgid "SortOptions|Stars"
msgstr "Yıldızlar"
@@ -19617,10 +20811,10 @@ msgid "SortOptions|Start soon"
msgstr "Yakında başlat"
msgid "SortOptions|Type"
-msgstr ""
+msgstr "Tür"
msgid "SortOptions|Version"
-msgstr ""
+msgstr "Sürüm"
msgid "SortOptions|Weight"
msgstr "Ağırlık"
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr "Yıldızlar"
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19788,7 +20982,7 @@ msgid "Start a review"
msgstr "Ä°nceleme baÅŸlat"
msgid "Start and due date"
-msgstr ""
+msgstr "Başlangıç ve bitiş tarihi"
msgid "Start by choosing a group to see how your team is spending time. You can then drill down to the project level."
msgstr ""
@@ -19809,7 +21003,7 @@ msgid "Start merge train when pipeline succeeds"
msgstr ""
msgid "Start search"
-msgstr ""
+msgstr "Aramayı başlat"
msgid "Start the Runner!"
msgstr ""
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr "Başlatılıyor..."
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19992,6 +21192,9 @@ msgid "Storage:"
msgstr ""
msgid "StorageSize|Unknown"
+msgstr "Bilinmeyen"
+
+msgid "Subgroup milestone"
msgstr ""
msgid "Subgroup overview"
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr "Parlak yeÅŸil"
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr "Destek sayfası URL'si"
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr "Dal/etiketi deÄŸiÅŸtir"
@@ -20315,9 +21530,6 @@ msgstr "Sistem"
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20534,7 +21746,7 @@ msgid "TestHooks|Ensure the wiki is enabled and has pages."
msgstr ""
msgid "TestReports|%{count} errors"
-msgstr ""
+msgstr "%{count} hata"
msgid "TestReports|%{count} failures"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20632,7 +21847,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 "Hata giderildiği için, ilgili #%{issueId} sorunu kapatıldı."
msgid "The branch for this project has no active pipeline configuration."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20790,7 +22011,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 "Birleştirme isteği artık birleştirilebilir."
msgid "The name \"%{name}\" is already taken in this directory."
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -20979,7 +22206,7 @@ msgid "There are no charts configured for this page"
msgstr ""
msgid "There are no closed issues"
-msgstr ""
+msgstr "Kapatılan sorun yok"
msgid "There are no closed merge requests"
msgstr "Kapalı bir birleştirme isteği yok"
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr "Kullanıcı etkinlik takvimi yüklenirken bir hata oluştu."
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21330,10 +22578,7 @@ msgid "This is a delayed job to run in %{remainingTime}"
msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
-msgstr "Bu, hesabınıza giriş yaptığınız cihazların listesidir. Tanımadığınız veya bilmediğiniz tüm oturumları kapatın."
-
-msgid "This is a primary node"
-msgstr ""
+msgstr "Bu, hesabınıza giriş yaptığınız cihazların listesidir. Tanımadığınız veya bilmediğiniz tüm oturumları sonlandırın."
msgid "This is a security log of important events involving your account."
msgstr "Bu, hesabınızla ilgili önemli olayların bir güvenlik günlüğüdür."
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr "Bu birleÅŸtirme isteÄŸi kilitlendi."
@@ -21509,12 +22757,18 @@ msgstr "Bu proje"
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr "Bu depo"
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr "Bu kullanıcının kimliği yok"
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr "hemen ÅŸimdi"
msgid "Timeout"
msgstr "Zaman aşımı"
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] "saat"
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22027,7 +23305,7 @@ msgid "Today"
msgstr "Bugün"
msgid "Toggle Markdown preview"
-msgstr "Markdown önizlemesini aç/kapat"
+msgstr "Biçimlendirme önizlemesini aç/kapat"
msgid "Toggle Sidebar"
msgstr "Kenar çubuğunu değiştir"
@@ -22050,6 +23328,9 @@ msgstr "İşlem açıklamasını göster"
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22063,10 +23344,10 @@ msgid "Toggle sidebar"
msgstr "Kenar çubuğunu göster/gizle"
msgid "Toggle the Performance Bar"
-msgstr ""
+msgstr "Performans Çubuğunu aç/kapat"
msgid "Toggle this dialog"
-msgstr ""
+msgstr "Bu iletişim kutusunu aç/kapat"
msgid "Toggle thread"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr "Toplam Katkı"
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22147,11 +23419,14 @@ msgid "Track your project with Audit Events."
msgstr ""
msgid "Transfer ownership"
-msgstr ""
+msgstr "SahipliÄŸi aktar"
msgid "Transfer project"
msgstr "Projeyi aktar"
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr "Tekrar çatallamayı dene"
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22273,7 +23551,7 @@ msgid "Tuesday"
msgstr ""
msgid "Turn Off"
-msgstr ""
+msgstr "Kapat"
msgid "Turn On"
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22438,19 +23728,19 @@ msgid "Unknown"
msgstr "Bilinmeyen"
msgid "Unknown Error"
-msgstr ""
+msgstr "Bilinmeyen Hata"
msgid "Unknown cache key"
-msgstr ""
+msgstr "Bilinmeyen önbellek anahtarı"
msgid "Unknown encryption strategy: %{encrypted_strategy}!"
-msgstr ""
+msgstr "Bilinmeyen ÅŸifreleme stratejisi: %{encrypted_strategy}!"
msgid "Unknown format"
-msgstr ""
+msgstr "Bilinmeyen biçim"
msgid "Unknown response text"
-msgstr ""
+msgstr "Bilinmeyen yanıt metni"
msgid "Unlimited"
msgstr "Sınırsız"
@@ -22621,10 +23911,10 @@ msgid "Updated %{updated_at} by %{updated_by}"
msgstr "%{updated_by} tarafından %{updated_at} zamanında güncellendi"
msgid "Updated at"
-msgstr ""
+msgstr "Güncellendi:"
msgid "Updated to"
-msgstr ""
+msgstr "Güncellendi:"
msgid "Updating"
msgstr "Güncelleniyor"
@@ -22632,18 +23922,12 @@ msgstr "Güncelleniyor"
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr "Gelişmiş Genel aramayı etkinleştirmek için planınızı yükseltin."
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr "Yeni Dosya Yükle"
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr "yüklemek için tıklayın"
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr "Kullanım istatistikleri"
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr "Ek dakika satın al"
msgid "UsageQuota|Current period usage"
msgstr "Mevcut dönem kullanımı"
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr "LFS Depolama"
@@ -22731,12 +24024,18 @@ msgstr "Paketler"
msgid "UsageQuota|Pipelines"
msgstr "İş hatları"
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr "Depo"
msgid "UsageQuota|Storage"
msgstr "Depolama"
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr "Bu isim alanının paylaşılan çalıştırıcıları kullanan projeleri yok"
@@ -22755,12 +24054,18 @@ msgstr "Grup kaynaklarının gruptaki projeler arasında %{strong_start}%{group_
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr "Kullanım tarihi:"
msgid "UsageQuota|Wiki"
msgstr "Viki"
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr "Kullanıcı iş hattı kayıtları başarıyla sıfırlandı."
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr "Kullanıcı ayarları"
-
msgid "User was successfully created."
msgstr ""
@@ -22879,7 +24181,7 @@ msgid "UserOnboardingTour|%{activeTour}/%{totalTours}"
msgstr ""
msgid "UserOnboardingTour|%{completed}/%{total} steps completed"
-msgstr ""
+msgstr "%{completed}/%{total} adım tamamlandı"
msgid "UserOnboardingTour|%{emphasisStart}Well done!%{emphasisEnd}%{lineBreak}%{lineBreak}That's it for our guided tour, congratulations for making it all the way to the end!%{lineBreak}%{lineBreak}We hope this gave you a good overview of GitLab and how it can help you. We'll now show you how to create your own project and invite your colleagues."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr "Herhangi bir parçacık oluşturmadınız."
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr "Projeleriniz istediğiniz gibi; genel ve dahili olarak yada gizli olarak kullanılabilir."
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23155,10 +24463,10 @@ msgid "UsersSelect|Any User"
msgstr ""
msgid "UsersSelect|Assignee"
-msgstr ""
+msgstr "Vekil"
msgid "UsersSelect|No assignee - %{openingTag} assign yourself %{closingTag}"
-msgstr ""
+msgstr "Vekil yok - %{openingTag} kendinizi atayın %{closingTag}"
msgid "UsersSelect|Unassigned"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr "Sürüm"
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr "Dosyayı görüntüle @ "
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23459,10 +24779,7 @@ msgid "VulnerabilityManagement|Confirm"
msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
-msgstr ""
-
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
+msgstr "%{user} tarafından %{timeago} onaylandı"
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23471,13 +24788,13 @@ msgid "VulnerabilityManagement|Dismiss"
msgstr ""
msgid "VulnerabilityManagement|Dismissed %{timeago} by %{user}"
-msgstr ""
+msgstr "%{user} tarafından %{timeago} reddedildi"
msgid "VulnerabilityManagement|Resolved"
msgstr ""
msgid "VulnerabilityManagement|Resolved %{timeago} by %{user}"
-msgstr ""
+msgstr "%{user} tarafından %{timeago} çözüldü"
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23660,7 +24986,7 @@ msgid "Wednesday"
msgstr ""
msgid "Weekday"
-msgstr ""
+msgstr "Hafta içi"
msgid "Weeks"
msgstr "Haftalar"
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23743,7 +25075,7 @@ msgid "Who will be able to see this group?"
msgstr ""
msgid "Who will be using GitLab?"
-msgstr ""
+msgstr "GitLab'ı kimler kullanacak?"
msgid "Who will be using this GitLab subscription?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr "Git EriÅŸimi"
msgid "WikiClone|Install Gollum"
msgstr "Gollum'u yükleyin"
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr "Gollum'u başlat ve yerel olarak düzenle"
@@ -23884,15 +25213,18 @@ msgid "Wiki|Title"
msgstr "Başlık"
msgid "Wiki|View All Pages"
-msgstr ""
+msgstr "Tüm Sayfaları Görüntüle"
msgid "Wiki|Wiki Pages"
msgstr "Viki Sayfaları"
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr "Herhangi bir etkinlik için bildirim alacaksınız"
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr "Yalnızca sizden @bahsedilen yorumlar için bildirim alacaksınız"
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr "YouTube"
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24403,7 +25765,7 @@ msgid "Your GPG keys (%{count})"
msgstr ""
msgid "Your GitLab group"
-msgstr ""
+msgstr "Gitlab grubunuz"
msgid "Your Gitlab Gold trial will last 30 days after which point you can keep your free Gitlab account forever. We just need some additional information to activate your trial."
msgstr ""
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr "Gruplarınız"
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24451,7 +25813,7 @@ msgid "Your account has been deactivated by your administrator. Please log back
msgstr ""
msgid "Your account is locked."
-msgstr ""
+msgstr "Hesabınız kilitlendi."
msgid "Your account uses dedicated credentials for the \"%{group_name}\" group and can only be updated through SSO."
msgstr ""
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr "Gruplarınız"
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr "Adınız"
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24538,7 +25915,7 @@ msgid "Your password reset token has expired."
msgstr ""
msgid "Your profile"
-msgstr ""
+msgstr "Profiliniz"
msgid "Your project limit is %{limit} projects! Please contact your administrator to increase it"
msgstr ""
@@ -24546,14 +25923,20 @@ msgstr ""
msgid "Your projects"
msgstr "Projeleriniz"
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
msgid "Your subscription expired!"
-msgstr ""
+msgstr "AboneliÄŸiniz sona erdi!"
msgid "Your subscription has been downgraded"
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr "önce"
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24621,13 +26007,13 @@ msgid "archived"
msgstr "arÅŸivlenmiÅŸ"
msgid "assign yourself"
-msgstr ""
+msgstr "kendinizi atayın"
msgid "at risk"
msgstr ""
msgid "attach a new file"
-msgstr ""
+msgstr "yeni bir dosya ekle"
msgid "authored"
msgstr "yazdı"
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr "dal adı"
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr "tarafından"
@@ -24663,7 +26052,7 @@ msgid "cannot itself be blocked"
msgstr ""
msgid "cannot merge"
-msgstr ""
+msgstr "birleÅŸtirilemez"
msgid "ciReport|%{linkStartTag}Learn more about Container Scanning %{linkEndTag}"
msgstr ""
@@ -24754,7 +26143,7 @@ msgid "ciReport|All projects"
msgstr "Tüm projeler"
msgid "ciReport|All report types"
-msgstr ""
+msgstr "Tüm rapor türleri"
msgid "ciReport|All severities"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr "%{reportName} raporu yüklenemedi"
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr "Düzeltildi:"
@@ -24825,6 +26217,9 @@ msgstr "%{reportName} raporu yükleniyor"
msgid "ciReport|Manage licenses"
msgstr "Lisansları yönet"
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr "Kod kalitesinde deÄŸiÅŸiklik yok"
@@ -24841,6 +26236,9 @@ msgid "ciReport|Resolve with merge request"
msgstr ""
msgid "ciReport|SAST"
+msgstr "SAST"
+
+msgid "ciReport|Secret Detection"
msgstr ""
msgid "ciReport|Secret scanning"
@@ -24884,6 +26282,9 @@ msgstr[1] "%{packagesString} ve %{lastPackage} tarafından kullanıldı"
msgid "ciReport|View full report"
msgstr "Raporun tamamını görüntüle"
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr "Yorumladı: %{link_to_project}"
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr "bağlanılıyor"
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24912,7 +26319,7 @@ msgid "created"
msgstr "oluÅŸturdu:"
msgid "created %{timeAgo}"
-msgstr ""
+msgstr "%{timeAgo} oluÅŸturuldu"
msgid "customize"
msgstr "özelleştir"
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr "tamamlandı"
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24973,13 +26386,13 @@ msgid "encrypted: needs to be a :required, :optional or :migrating!"
msgstr ""
msgid "entries cannot be larger than 255 characters"
-msgstr ""
+msgstr "giriÅŸler 255 karakterden uzun olamaz"
msgid "entries cannot be nil"
-msgstr ""
+msgstr "giriÅŸler boÅŸ olamaz"
msgid "entries cannot contain HTML tags"
-msgstr ""
+msgstr "girişler HTML etiketleri içeremez"
msgid "error"
msgstr "hata"
@@ -24996,25 +26409,25 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
msgstr ""
msgid "failed"
-msgstr ""
+msgstr "başarısız"
msgid "failed to dismiss associated finding(id=%{finding_id}): %{message}"
msgstr ""
msgid "file"
msgid_plural "files"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "dosya"
+msgstr[1] "dosya"
msgid "finding is not found or is already attached to a vulnerability"
msgstr ""
@@ -25053,10 +26466,10 @@ msgid "has already been linked to another vulnerability"
msgstr ""
msgid "has already been taken"
-msgstr ""
+msgstr "zaten alındı"
msgid "help"
-msgstr ""
+msgstr "yardım"
msgid "here"
msgstr "burada"
@@ -25064,7 +26477,16 @@ msgstr "burada"
msgid "https://your-bitbucket-server"
msgstr "https://sizin-bitbucket-sunucunuz"
+msgid "image"
+msgstr ""
+
msgid "image diff"
+msgstr "resim deÄŸiÅŸikliÄŸi"
+
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
msgstr ""
msgid "import flow"
@@ -25080,12 +26502,12 @@ msgid "in project %{link_to_project}"
msgstr ""
msgid "index"
-msgstr ""
+msgstr "dizin"
msgid "instance completed"
msgid_plural "instances completed"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "örnek tamamlandı"
+msgstr[1] "örnek tamamlandı"
msgid "invalid milestone state `%{state}`"
msgstr ""
@@ -25103,7 +26525,7 @@ msgid "is blocked by"
msgstr ""
msgid "is enabled."
-msgstr ""
+msgstr "etkinleÅŸtirildi."
msgid "is invalid because there is downstream lock"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25139,7 +26564,7 @@ msgid "is too long (maximum is 1000 entries)"
msgstr "çok uzun (en fazla 1000 giriş)"
msgid "issue"
-msgstr ""
+msgstr "sorun"
msgid "issues at risk"
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25169,7 +26600,7 @@ msgid "jira.issue.summary"
msgstr ""
msgid "latest"
-msgstr ""
+msgstr "en son"
msgid "latest deployment"
msgstr "son dağıtım"
@@ -25178,10 +26609,10 @@ msgid "latest version"
msgstr "son sürüm"
msgid "leave %{group_name}"
-msgstr ""
+msgstr "%{group_name} ayrıl"
msgid "less than a minute"
-msgstr ""
+msgstr "1 dakikadan az"
msgid "level: %{level}"
msgstr ""
@@ -25189,11 +26620,14 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr "%{path_lock_user_name} tarafından kilitlendi %{created_at}"
msgid "log in"
-msgstr ""
+msgstr "oturum aç"
msgid "manual"
msgstr ""
@@ -25210,10 +26644,10 @@ msgstr[0] "birleÅŸtirme isteÄŸi"
msgstr[1] "birleÅŸtirme isteÄŸi"
msgid "merged %{time_ago}"
-msgstr ""
+msgstr "%{time_ago} birleÅŸtirildi"
msgid "missing"
-msgstr ""
+msgstr "eksik"
msgid "most recent deployment"
msgstr ""
@@ -25225,7 +26659,7 @@ msgid "mrWidgetCommitsAdded|%{commitCount} will be added to %{targetBranch}."
msgstr ""
msgid "mrWidgetCommitsAdded|1 merge commit"
-msgstr ""
+msgstr "1 iÅŸlemi birleÅŸtir"
msgid "mrWidgetNothingToMerge|Currently there are no changes in this merge request's source branch. Please push new commits or use a different branch."
msgstr ""
@@ -25279,7 +26713,7 @@ msgid "mrWidget|Approve additionally"
msgstr "Ek olarak onayla"
msgid "mrWidget|Approved by"
-msgstr "Onaylandı"
+msgstr "Onaylayan:"
msgid "mrWidget|Are you adding technical debt or code vulnerabilities?"
msgstr ""
@@ -25303,7 +26737,7 @@ msgid "mrWidget|Closed"
msgstr "Kapalı"
msgid "mrWidget|Closed by"
-msgstr "Tarafından kapatıldı"
+msgstr "Kapatan:"
msgid "mrWidget|Closes"
msgstr ""
@@ -25312,12 +26746,12 @@ msgid "mrWidget|Create an issue to resolve them later"
msgstr ""
msgid "mrWidget|Delete source branch"
-msgstr ""
+msgstr "Kaynak dalı sil"
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25363,19 +26797,19 @@ msgid "mrWidget|Merge locally"
msgstr "Yerel olarak birleÅŸtir"
msgid "mrWidget|Merge request approved."
-msgstr ""
+msgstr "Birleştirme talebi onaylandı."
msgid "mrWidget|Merged by"
-msgstr "BirleÅŸtiren"
+msgstr "BirleÅŸtiren:"
msgid "mrWidget|More information"
msgstr "Daha fazla bilgi"
msgid "mrWidget|No approval required"
-msgstr ""
+msgstr "Onay gerekli deÄŸil"
msgid "mrWidget|No approval required; you can still approve"
-msgstr ""
+msgstr "Onay gerekli deÄŸil; hala onaylayabilirsiniz"
msgid "mrWidget|Open in Web IDE"
msgstr "Web IDE'de aç"
@@ -25399,16 +26833,16 @@ msgid "mrWidget|Refreshing now"
msgstr "Åžimdi yenileniyor"
msgid "mrWidget|Remove from merge train"
-msgstr ""
+msgstr "Birleştirme treninden kaldır"
msgid "mrWidget|Request to merge"
msgstr "BirleÅŸtirme isteÄŸi"
msgid "mrWidget|Resolve WIP status"
-msgstr ""
+msgstr "WIP durumunu çöz"
msgid "mrWidget|Resolve conflicts"
-msgstr ""
+msgstr "Çakışmaları çöz"
msgid "mrWidget|Resolve these conflicts or ask someone with write access to this repository to merge it locally"
msgstr ""
@@ -25423,7 +26857,7 @@ msgid "mrWidget|Revoke approval"
msgstr "Onayı iptal et"
msgid "mrWidget|Set by"
-msgstr ""
+msgstr "Ayarlayan:"
msgid "mrWidget|The changes were merged into"
msgstr ""
@@ -25441,25 +26875,25 @@ msgid "mrWidget|The source branch HEAD has recently changed. Please reload the p
msgstr ""
msgid "mrWidget|The source branch has been deleted"
-msgstr ""
+msgstr "Kaynak dal silindi"
msgid "mrWidget|The source branch is %{commitsBehindLinkStart}%{commitsBehind}%{commitsBehindLinkEnd} the target branch"
msgstr ""
msgid "mrWidget|The source branch is being deleted"
-msgstr ""
+msgstr "Kaynak dal siliniyor"
msgid "mrWidget|The source branch will be deleted"
-msgstr ""
+msgstr "Kaynak dal silinecek"
msgid "mrWidget|The source branch will not be deleted"
-msgstr ""
+msgstr "Kaynak dal silinmeyecek"
msgid "mrWidget|There are merge conflicts"
-msgstr ""
+msgstr "Birleştirme çakışmaları var"
msgid "mrWidget|There are unresolved threads. Please resolve these threads"
-msgstr ""
+msgstr "Çözümlenmemiş konular var. Lütfen bu konuları çözün"
msgid "mrWidget|This feature merges changes from the target branch to the source branch. You cannot use this feature since the source branch is protected."
msgstr ""
@@ -25489,7 +26923,7 @@ msgid "mrWidget|You are not allowed to edit this project directly. Please fork t
msgstr ""
msgid "mrWidget|You can delete the source branch now"
-msgstr ""
+msgstr "Kaynak dalı şimdi silebilirsiniz"
msgid "mrWidget|You can merge this merge request manually using the"
msgstr ""
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr "Åžifreniz"
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr "dal mevcut deÄŸil."
@@ -25509,15 +26940,6 @@ msgstr "komut satırı"
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,9 +26952,12 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
-msgid "n/a"
+msgid "my-awesome-group"
msgstr ""
+msgid "n/a"
+msgstr "yok"
+
msgid "need attention"
msgstr ""
@@ -25546,7 +26971,7 @@ msgid "new merge request"
msgstr "yeni birleÅŸtirme isteÄŸi"
msgid "no contributions"
-msgstr ""
+msgstr "hiç katkı yok"
msgid "no expiration"
msgstr ""
@@ -25558,7 +26983,7 @@ msgid "none"
msgstr "yok"
msgid "not found"
-msgstr ""
+msgstr "bulunamadı"
msgid "notification emails"
msgstr "bildirim e-postaları"
@@ -25575,14 +27000,17 @@ msgstr ""
msgid "on track"
msgstr ""
-msgid "opened %{timeAgoString} by %{user}"
+msgid "open issue"
msgstr ""
+msgid "opened %{timeAgoString} by %{user}"
+msgstr "%{user} tarafından %{timeAgoString} açıldı"
+
msgid "opened %{timeAgo}"
-msgstr ""
+msgstr "%{timeAgo} açıldı"
msgid "or"
-msgstr ""
+msgstr "veya"
msgid "out of %d total test"
msgid_plural "out of %d total tests"
@@ -25598,15 +27026,24 @@ msgid "password"
msgstr "ÅŸifre"
msgid "pending comment"
-msgstr ""
+msgstr "yorum bekliyor"
msgid "pending removal"
-msgstr ""
+msgstr "kaldırılmayı bekliyor"
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
+msgstr "iş hattı"
+
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
msgid "pod_name cannot be larger than %{max_length} chars"
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] "proje"
msgstr[1] "proje"
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr "proje profil resmi"
@@ -25641,10 +27084,10 @@ msgid "push to your repository, create pipelines, create issues or add comments.
msgstr ""
msgid "quick actions"
-msgstr ""
+msgstr "hızlı işlemler"
msgid "register"
-msgstr ""
+msgstr "kayıt ol"
msgid "relates to"
msgstr ""
@@ -25653,13 +27096,13 @@ msgid "released %{time}"
msgstr ""
msgid "remaining"
-msgstr ""
+msgstr "kalan"
msgid "remove"
msgstr "kaldır"
msgid "remove due date"
-msgstr ""
+msgstr "bitiş tarihini kaldır"
msgid "remove weight"
msgstr ""
@@ -25679,10 +27122,13 @@ msgid "reset it."
msgstr ""
msgid "resolved the corresponding error and closed the issue."
+msgstr "ilgili hatayı çözdü ve sorunu kapattı."
+
+msgid "revised"
msgstr ""
msgid "score"
-msgstr ""
+msgstr "puan"
msgid "security Reports|There was an error creating the merge request"
msgstr ""
@@ -25691,25 +27137,25 @@ msgid "settings saved, but not activated"
msgstr ""
msgid "severity|Critical"
-msgstr ""
+msgstr "Kritik"
msgid "severity|High"
-msgstr ""
+msgstr "Yüksek"
msgid "severity|Info"
-msgstr ""
+msgstr "Bilgi"
msgid "severity|Low"
-msgstr ""
+msgstr "Düşük"
msgid "severity|Medium"
-msgstr ""
+msgstr "Orta"
msgid "severity|None"
msgstr ""
msgid "severity|Unknown"
-msgstr ""
+msgstr "Bilinmeyen"
msgid "should be greater than or equal to %{access} inherited membership from group %{group_name}"
msgstr ""
@@ -25721,19 +27167,19 @@ msgid "show fewer"
msgstr "daha az göster"
msgid "show less"
-msgstr ""
+msgstr "daha az göster"
msgid "sign in"
msgstr "oturum aç"
msgid "sort:"
-msgstr ""
+msgstr "sırala:"
msgid "source"
msgstr "kaynak"
msgid "source diff"
-msgstr ""
+msgstr "kaynak deÄŸiÅŸiklik"
msgid "specified top is not part of the tree"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr "başladı"
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25778,7 +27224,7 @@ msgid "syntax is incorrect"
msgstr ""
msgid "tag name"
-msgstr ""
+msgstr "etiket adı"
msgid "the following issue(s)"
msgstr ""
@@ -25793,13 +27239,13 @@ msgid "to list"
msgstr ""
msgid "toggle collapse"
-msgstr ""
+msgstr "daraltmayı aç/kapat"
msgid "toggle dropdown"
-msgstr ""
+msgstr "açılır listeyi aç/kapat"
msgid "triggered"
-msgstr ""
+msgstr "tetiklendi"
msgid "unicode domains should use IDNA encoding"
msgstr ""
@@ -25808,9 +27254,15 @@ msgid "updated"
msgstr "güncellendi"
msgid "updated %{timeAgo}"
-msgstr ""
+msgstr "%{timeAgo} güncellendi"
msgid "updated %{time_ago}"
+msgstr "%{time_ago} güncellendi"
+
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
msgstr ""
msgid "user avatar"
@@ -25823,13 +27275,13 @@ msgid "uses Kubernetes clusters to deploy your code!"
msgstr ""
msgid "verify ownership"
-msgstr ""
+msgstr "sahipliÄŸi doÄŸrula"
msgid "version %{versionIndex}"
-msgstr ""
+msgstr "sürüm %{versionIndex}"
msgid "via %{closed_via}"
-msgstr ""
+msgstr "%{closed_via} aracılığıyla"
msgid "via merge request %{link}"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr "GitLab'da görüntüle"
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25847,24 +27302,27 @@ msgid "vulnerability|Add a comment or reason for dismissal"
msgstr ""
msgid "vulnerability|Add comment"
-msgstr ""
+msgstr "Yorum ekle"
msgid "vulnerability|Add comment & dismiss"
-msgstr ""
+msgstr "Yorum ekle ve reddet"
msgid "vulnerability|Dismiss vulnerability"
-msgstr ""
+msgstr "Güvenlik açığını kapat"
msgid "vulnerability|Save comment"
-msgstr ""
+msgstr "Yorumu kaydet"
msgid "vulnerability|Undo dismiss"
msgstr ""
msgid "vulnerability|dismissed"
-msgstr ""
+msgstr "güvenlik açığı kapatıldı"
msgid "wiki page"
+msgstr "viki sayfası"
+
+msgid "will be released %{time}"
msgstr ""
msgid "with %{additions} additions, %{deletions} deletions."
@@ -25877,5 +27335,5 @@ msgid "with expiry remaining unchanged at %{old_expiry}"
msgstr ""
msgid "yaml invalid"
-msgstr ""
+msgstr "yaml geçersiz"
diff --git a/locale/uk/gitlab.po b/locale/uk/gitlab.po
index e09df16fe38..badb6ef33cd 100644
--- a/locale/uk/gitlab.po
+++ b/locale/uk/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: uk\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:36\n"
+"PO-Revision-Date: 2020-06-08 16:58\n"
msgid " %{start} to %{end}"
msgstr "%{start} до %{end}"
@@ -21,7 +21,7 @@ msgid " (from %{timeoutSource})"
msgstr " (з %{timeoutSource})"
msgid " Collected %{time}"
-msgstr ""
+msgstr " Зібрано %{time}"
msgid " Please sign in."
msgstr " Будь лаÑка, увійдіть."
@@ -68,13 +68,27 @@ msgid " or <&epic id>"
msgstr " або <&epic id>"
msgid " or references (e.g. path/to/project!merge_request_id)"
-msgstr " або поÑÐ¸Ð»Ð°Ð½Ð½Ñ (напр. шлÑÑ…/до/проекту!id_запиту_на_злиттÑ)"
+msgstr " або поÑÐ¸Ð»Ð°Ð½Ð½Ñ (напр. шлÑÑ…/до/проєкту!id_запиту_на_злиттÑ)"
msgid "\"%{path}\" did not exist on \"%{ref}\""
msgstr "\"%{path}\" не Ñ–Ñнував у \"%{ref}\""
msgid "%d URL scanned"
msgid_plural "%d URLs scanned"
+msgstr[0] "%d URL-адреÑу відÑкановано"
+msgstr[1] "%d URL-адреÑи відÑкановано"
+msgstr[2] "%d URL-Ð°Ð´Ñ€ÐµÑ Ð²Ñ–Ð´Ñкановано"
+msgstr[3] "%d URL-Ð°Ð´Ñ€ÐµÑ Ð²Ñ–Ð´Ñкановано"
+
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -108,6 +122,13 @@ msgstr[1] "%d коментарі"
msgstr[2] "%d коментарів"
msgstr[3] "%d коментарів"
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] "%d коміт"
@@ -139,6 +160,13 @@ msgstr[1] "%d внеÑки"
msgstr[2] "%d внеÑків"
msgstr[3] "%d внеÑків"
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] "%d помилка"
@@ -237,6 +265,13 @@ msgstr[1] "ще %d коментарі"
msgstr[2] "ще %d коментарів"
msgstr[3] "ще %d коментарів"
+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[3] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] "%d проєкт"
@@ -279,6 +314,20 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] "%d вразливіÑÑ‚ÑŒ відхилено"
@@ -305,6 +354,9 @@ msgstr "%{commit_author_link} закомітив %{commit_timeago}"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} Ñдер"
@@ -390,6 +442,9 @@ msgstr "%{filePath} видалено"
msgid "%{firstLabel} +%{labelCount} more"
msgstr "%{firstLabel} +%{labelCount} більше"
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr "%{global_id} не Ñ” дійÑним ідентифікатором на %{expected_type}."
@@ -399,6 +454,9 @@ msgstr "%{group_docs_link_start}Групи%{group_docs_link_end} дозволÑÑ
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr "%{group_name} викориÑтовує облікові запиÑи керовані групою. Вам необхідно Ñтворити новий обліковий Ð·Ð°Ð¿Ð¸Ñ GitLab, Ñкий буде керуватиÑÑ %{group_name}."
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr "%{icon}Ви збираєтеÑÑŒ додати %{usersTag} людей до обговореннÑ. Будьте обережні."
@@ -411,6 +469,30 @@ msgstr "%{issuesSize} задач"
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr "%{issuesSize} задач з обмеженнÑм %{maxIssueCount}"
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr "%{label_for_message} недоÑтупний"
@@ -424,10 +506,10 @@ msgid "%{level_name} is not allowed since the fork source project has lower visi
msgstr "%{level_name} не допуÑкаєтьÑÑ, оÑкільки проєкт-джерело цього форку має нижчу видиміÑÑ‚ÑŒ."
msgid "%{lineOneStart}Drag and drop to upload your designs%{lineOneEnd} or %{linkStart}click to upload%{linkEnd}."
-msgstr ""
+msgstr "%{lineOneStart}ПеретÑгуйте дизайни%{lineOneEnd} або %{linkStart}, щоб завантажити%{linkEnd}."
msgid "%{link_start}Learn more%{link_end} about what information is shared with GitLab Inc."
-msgstr ""
+msgstr "%{link_start}ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ%{link_end} про те, Ñка Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ”Ñ‚ÑŒÑÑ GitLab Inc."
msgid "%{link_start}Read more%{link_end} about role permissions"
msgstr "%{link_start}Читати більше%{link_end} про дозволи ролей"
@@ -444,15 +526,24 @@ msgstr "%{loadingIcon} Початок"
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr "%{lock_path} заблоковано кориÑтувачем GitLab %{lock_user_id}"
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr "%{mergeLength}/%{usersLength} можуть виконувати злиттÑ"
msgid "%{mrText}, this issue will be closed automatically."
msgstr "%{mrText}, Ñ†Ñ Ð·Ð°Ð´Ð°Ñ‡Ð° буде закрита автоматично."
-msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
msgstr ""
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
+msgstr "%{namespace_name} тепер лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ. Ви не можете: %{base_message}"
+
msgid "%{name} contained %{resultsString}"
msgstr "%{name} міÑтить %{resultsString}"
@@ -460,17 +551,23 @@ msgid "%{name} found %{resultsString}"
msgstr "%{name} знайдено %{resultsString}"
msgid "%{name} is scheduled for %{action}"
-msgstr ""
+msgstr "%{name} заплановано на %{action}"
msgid "%{name}'s avatar"
msgstr "Ðватар %{name}"
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "%{no_of_days} день"
+msgstr[1] "%{no_of_days} дні"
+msgstr[2] "%{no_of_days} днів"
+msgstr[3] "%{no_of_days} днів"
msgid "%{number_commits_behind} commits behind %{default_branch}, %{number_commits_ahead} commits ahead"
msgstr "на %{number_commits_behind} комітів позаду %{default_branch}, на %{number_commits_ahead} комітів попереду"
@@ -497,7 +594,7 @@ msgid "%{placeholder} is not a valid color scheme"
msgstr "%{placeholder} не Ñ” дійÑною кольоровою Ñхемою"
msgid "%{placeholder} is not a valid theme"
-msgstr ""
+msgstr "%{placeholder} не є коректною темою"
msgid "%{primary} (%{secondary})"
msgstr "%{primary} (%{secondary})"
@@ -509,14 +606,20 @@ msgstr[1] "%{releases} реліза"
msgstr[2] "%{releases} релізів"
msgstr[3] "%{releases} релізів"
-msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
+msgid "%{remaining_approvals} left"
msgstr ""
-msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Enabled"
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
msgstr ""
+msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
+msgstr "%{screenreaderOnlyStart}ГарÑчі клавіші%{screenreaderOnlyEnd} Вимкнено"
+
+msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Enabled"
+msgstr "%{screenreaderOnlyStart}ГарÑчі клавіші%{screenreaderOnlyEnd} Увімкнено"
+
msgid "%{service_title} %{message}."
-msgstr ""
+msgstr "%{service_title} %{message}."
msgid "%{size} GiB"
msgstr "%{size} GiB"
@@ -608,7 +711,7 @@ msgid "%{text} is available"
msgstr "%{text} доÑтупний"
msgid "%{timebox_name} should belong either to a project or a group."
-msgstr ""
+msgstr "%{timebox_name} повинен належати до проєкту або до групи."
msgid "%{title} %{operator} %{threshold}"
msgstr "%{title} %{operator} %{threshold}"
@@ -668,6 +771,9 @@ msgstr[1] "(%d закриті)"
msgstr[2] "(%d закритих)"
msgstr[3] "(%d закритих)"
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr "(%{mrCount} злито)"
@@ -687,7 +793,7 @@ msgid "(removed)"
msgstr "(видалено)"
msgid "(revoked)"
-msgstr ""
+msgstr "(відкликано)"
msgid "*"
msgstr "*"
@@ -908,6 +1014,9 @@ msgstr "Будь лаÑка, звернітьÑÑ Ð´Ð¾ адмініÑтратоÑ
msgid "8 hours"
msgstr "8 годин"
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr "< 1 години"
@@ -938,6 +1047,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr "<strong>%{group_name}</strong> кориÑтувачі групи"
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr "<strong>ВидалÑÑ”</strong> гілку-джерело"
@@ -947,6 +1059,9 @@ msgstr "'Runner' — це процеÑ, Ñкий виконує завданнÑ
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr "Шаблон конÑольного заÑтоÑунку .NET Core, Ñкий налаштовуєтьÑÑ Ð´Ð»Ñ Ð±ÑƒÐ´ÑŒ-Ñкого проєкту .NET Core"
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr "Сайт GitBook, Ñкий викориÑтовує Netlify Ð´Ð»Ñ CI/CD заміÑÑ‚ÑŒ GitLab, але вÑе ще з уÑіма іншими чудовими функціÑми GitLab."
@@ -969,10 +1084,10 @@ msgid "A basic page and serverless function that uses AWS Lambda, AWS API Gatewa
msgstr "Базова Ñторінка та Serverless функціÑ, що викориÑтовує AWS Lambda, AWS API Gateway та GitLab Pages"
msgid "A complete DevOps platform"
-msgstr ""
+msgstr "Повноцінна DevOps платформа "
msgid "A default branch cannot be chosen for an empty project."
-msgstr "Гілку за замовчуваннÑм не може бути обрано Ð´Ð»Ñ Ð¿Ð¾Ñ€Ð¾Ð¶Ð½ÑŒÐ¾Ð³Ð¾ проекту."
+msgstr "Ðе можна обирати уÑтавну гілку Ð´Ð»Ñ Ð¿Ð¾Ñ€Ð¾Ð¶Ð½ÑŒÐ¾Ð³Ð¾ проєкту."
msgid "A deleted user"
msgstr "Видалений кориÑтувач"
@@ -981,9 +1096,12 @@ msgid "A file with '%{file_name}' already exists in %{branch} branch"
msgstr "Файл з '%{file_name}' вже Ñ–Ñнує в гілці %{branch}"
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
-msgstr "Форк - це ÐºÐ¾Ð¿Ñ–Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñƒ.<br />Форк репозиторію дозволÑÑ” вноÑити зміни без впливу на оригінальний проект."
+msgstr "Форк - це ÐºÐ¾Ð¿Ñ–Ñ Ð¿Ñ€Ð¾Ñ”ÐºÑ‚Ñƒ.<br />Форк репозиторію дозволÑÑ” вноÑити зміни без впливу на оригінальний проєкт."
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -1034,6 +1152,9 @@ msgstr "РегулÑрний вираз, Ñкий буде викориÑтовÑ
msgid "A secure token that identifies an external storage request."
msgstr "Секретний токен Ñкий ідентфікує запити до зовнішнього Ñховища."
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -1044,10 +1165,7 @@ msgid "A user with write access to the source branch selected this option"
msgstr "КориÑтувач із правом запиÑу в гілку-джерело вибрав цей варіант"
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
-msgstr ""
-
-msgid "API Help"
-msgstr "Довідка API"
+msgstr "ÐЕОБХІДÐРДІЯ: ЩоÑÑŒ пішло не так при отриманні Ñертифікату Let's Encrypt Ð´Ð»Ñ Ð´Ð¾Ð¼ÐµÐ½Ñƒ GitLab Pages '%{domain}'"
msgid "API Token"
msgstr "API-токен"
@@ -1094,9 +1212,6 @@ msgstr "ПрийнÑти умови"
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr "ЗаÑтоÑований запит на злиттÑ"
-
msgid "Access Tokens"
msgstr "Токени доÑтупу"
@@ -1179,7 +1294,7 @@ msgid "AccessTokens|Your feed token is used to authenticate you when your RSS re
msgstr "Ваш токен доÑтупу до каналів викориÑтовуєтьÑÑ Ð´Ð»Ñ Ð°Ð²Ñ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ—, коли ваш переглÑдач RSS завантажує перÑоналізований канал RSS або коли ваша програма-календар завантажує перÑоналізований календар. Цей токен додаєтьÑÑ Ð´Ð¾ URL-Ð°Ð´Ñ€ÐµÑ ÐºÐ°Ð½Ð°Ð»Ñ–Ð²."
msgid "AccessTokens|Your incoming email token is used to authenticate 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 is used to authenticate you when repository static objects (e.g. archives, blobs, ...) are being served from an external storage."
msgstr "Ваш токен Ñтатичних об’єктів викориÑтовуєтьÑÑ Ð´Ð»Ñ Ð°Ð²Ñ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ— коли Ñтатичні об’єкти репозиторію (напр. архіви, бінарні дані Ñ– Ñ‚. д.) зберігаютьÑÑ Ñƒ зовнішньому Ñховищі."
@@ -1187,20 +1302,14 @@ msgstr "Ваш токен Ñтатичних об’єктів викориÑÑ‚Ð
msgid "AccessTokens|reset it"
msgstr "перегенерувати його"
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr "ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ"
msgid "AccessibilityReport|Message: %{message}"
-msgstr ""
+msgstr "ПовідомленнÑ: %{message}"
msgid "AccessibilityReport|New"
-msgstr ""
+msgstr "Ðовий"
msgid "AccessibilityReport|The accessibility scanning found an error of the following type: %{code}"
msgstr ""
@@ -1229,8 +1338,8 @@ msgstr "Ðктивувати Службу підтримки"
msgid "Active"
msgstr "Ðктивний"
-msgid "Active %{type} Tokens (%{token_length})"
-msgstr "Ðктивні %{type} токени (%{token_length})"
+msgid "Active %{type} (%{token_length})"
+msgstr ""
msgid "Active Sessions"
msgstr "Ðктивні ÑеÑÑ–Ñ—"
@@ -1238,6 +1347,9 @@ msgstr "Ðктивні ÑеÑÑ–Ñ—"
msgid "Active Users:"
msgstr "Ðктивні кориÑтувачі:"
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr "ÐктивніÑÑ‚ÑŒ"
@@ -1284,8 +1396,8 @@ msgstr "Додати змінну"
msgid "Add Zoom meeting"
msgstr "Додати Zoom-зуÑтріч"
-msgid "Add a %{type} token"
-msgstr "Додати %{type} токен"
+msgid "Add a %{type}"
+msgstr ""
msgid "Add a GPG key"
msgstr "Додати GPG ключ"
@@ -1299,6 +1411,9 @@ msgstr "Додати нагадуваннÑ"
msgid "Add a bullet list"
msgstr "Додати ненумерований ÑпиÑок"
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr "Додайте загальний коментар до цього %{noteableDisplayName}."
@@ -1306,11 +1421,17 @@ msgid "Add a general comment to this %{noteable_name}."
msgstr "Додайте загальний коментар до цього %{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 "Додати домашню Ñторінку в вікі, Ñка міÑтить інформацію про ваш проект, Ñ– GitLab відображатиме його тут заміÑÑ‚ÑŒ цього повідомленнÑ."
+msgstr "Додати домашню Ñторінку в вікі, Ñка міÑтить інформацію про ваш проєкт, Ñ– GitLab відображатиме його тут заміÑÑ‚ÑŒ цього повідомленнÑ."
+
+msgid "Add a line"
+msgstr ""
msgid "Add a link"
msgstr "Додати поÑиланнÑ"
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr "Додати нумерований ÑпиÑок"
@@ -1326,8 +1447,11 @@ msgstr "Створіть додатковий текÑÑ‚, Ñкий буде пр
msgid "Add an SSH key"
msgstr "Додати SSH ключ"
-msgid "Add an existing issue to the epic."
-msgstr "Додати Ñ–Ñнуючу задачу до епіку."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
+msgstr ""
msgid "Add an issue"
msgstr "Додати задачу"
@@ -1392,6 +1516,9 @@ msgstr "Додати реакцію"
msgid "Add request manually"
msgstr "Додати запит вручну"
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr "Додати ÑиÑтемний хук"
@@ -1450,13 +1577,13 @@ msgid "Added at"
msgstr "Додано"
msgid "Added for this merge request"
-msgstr ""
+msgstr "Додано до цього запиту на злиттÑ"
msgid "Added in this version"
msgstr "Додано в цій верÑÑ–Ñ—"
msgid "Adding new applications is disabled in your GitLab instance. Please contact your GitLab administrator to get the permission"
-msgstr "Ð”Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ Ð½Ð¾Ð²Ð¸Ñ… проектів Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ інÑтанÑу GitLab заборонено. ЗвернітьÑÑ Ð´Ð¾ Ñвого адмініÑтратора GitLab, щоб отримати дозвіл"
+msgstr "Ð”Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ Ð½Ð¾Ð²Ð¸Ñ… проєктів Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ інÑтанÑу GitLab заборонено. ЗвернітьÑÑ Ð´Ð¾ Ñвого адмініÑтратора GitLab, щоб отримати дозвіл"
msgid "Additional minutes"
msgstr "Додаткові хвилини"
@@ -1482,18 +1609,18 @@ msgstr "Додає Zoom-зуÑтріч"
msgid "Adds an issue to an epic."
msgstr "Додає задачу до епіку."
-msgid "Adjust your filters/search criteria above."
-msgstr "Відрегулюйте при потребі фільтри/критерії пошуку вище."
+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 ""
msgid "Admin Area"
msgstr "ОблаÑÑ‚ÑŒ адмініÑтратора"
+msgid "Admin Note"
+msgstr ""
+
msgid "Admin Overview"
msgstr "ОглÑд адмініÑтратора"
-msgid "Admin Section"
-msgstr "Розділ ÐдмініÑтруваннÑ"
-
msgid "Admin mode already enabled"
msgstr "Режим адмініÑтратора вже ввімкнено"
@@ -1525,7 +1652,7 @@ msgid "AdminArea|Guest"
msgstr "ГіÑÑ‚ÑŒ"
msgid "AdminArea|Included Free in license"
-msgstr ""
+msgstr "Безкоштовно включені в ліцензію"
msgid "AdminArea|Maintainer"
msgstr "Керівник"
@@ -1582,7 +1709,7 @@ msgid "AdminProjects|Delete project"
msgstr "Видалити проект"
msgid "AdminSettings|Apply integration settings to all Projects"
-msgstr ""
+msgstr "ЗаÑтоÑувати Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ–Ð½Ñ‚ÐµÐ³Ñ€Ð°Ñ†Ñ–Ñ— до вÑÑ–Ñ… проєктів"
msgid "AdminSettings|Auto DevOps domain"
msgstr "Домен Auto DevOps"
@@ -1600,7 +1727,7 @@ msgid "AdminSettings|Go to General Settings"
msgstr "Перейти до загальних налаштувань"
msgid "AdminSettings|Integrations configured here will automatically apply to all projects on this instance."
-msgstr ""
+msgstr "Інтеграції, налаштовані тут, будуть автоматично заÑтоÑовуватиÑÑ Ð´Ð¾ вÑÑ–Ñ… проєктів у цьому інÑтанÑÑ–."
msgid "AdminSettings|No required pipeline"
msgstr "ВідÑутній обов’Ñзковий конвеєр"
@@ -1615,13 +1742,13 @@ msgid "AdminSettings|Select a template"
msgstr "Виберіть шаблон"
msgid "AdminSettings|Service template allows you to set default values for integrations"
-msgstr ""
+msgstr "Шаблон Ñлужби дозволÑÑ” вÑтановити Ð´Ð»Ñ Ñ–Ð½Ñ‚ÐµÐ³Ñ€Ð°Ñ†Ñ–Ð¹ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð° замовчуваннÑм"
msgid "AdminSettings|Set an instance-wide auto included %{link_start}pipeline configuration%{link_end}. This pipeline configuration will be run after the project's own configuration."
msgstr "Задати автоматичну %{link_start}конфігурацію контейнера%{link_end} Ð´Ð»Ñ Ñ–Ð½ÑтанÑу. Ð¦Ñ ÐºÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ ÐºÐ¾Ð½Ñ‚ÐµÐ¹Ð½ÐµÑ€Ñƒ буде запуÑкатиÑÑ Ð¿Ñ–ÑÐ»Ñ Ð²Ð»Ð°Ñної конфігурації проекту."
msgid "AdminSettings|Some settings have moved"
-msgstr ""
+msgstr "ДеÑкі Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÐ¼Ñ–Ñ‰ÐµÐ½Ð¾"
msgid "AdminSettings|Specify a domain to use by default for every project's Auto Review Apps and Auto Deploy stages."
msgstr "Вкажіть домен, Ñкий буде викориÑтовуватиÑÑ Ð² проекті за замовчуваннÑм Ð´Ð»Ñ Ñтадій Auto Review Apps Ñ– Auto Deploy."
@@ -1735,10 +1862,10 @@ msgid "AdminUsers|Owned groups will be left"
msgstr "Групи, що Ñ” у влаÑноÑÑ‚Ñ– буде збережено"
msgid "AdminUsers|Personal projects will be left"
-msgstr ""
+msgstr "ПерÑональні проєкти буде збережено"
msgid "AdminUsers|Personal projects, group and user history will be left intact"
-msgstr ""
+msgstr "ПерÑональні проєкти, групи, та Ñ–Ñторію кориÑтувача буде залишено без змін"
msgid "AdminUsers|Reactivating a user will:"
msgstr "Повторна Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ ÐºÐ¾Ñ€Ð¸Ñтувача зробить:"
@@ -1818,6 +1945,15 @@ msgstr "ПіÑÐ»Ñ ÑƒÑпішного Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð²Ð¸ пеÑ
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr "ПіÑÐ»Ñ ÑƒÑпішного Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ð°Ñ€Ð¾Ð»ÑŽ ви будете перенаправлені на Ñторінку входу, де ви зможете увійти з новим паролем."
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] "ПопередженнÑ"
@@ -1825,77 +1961,140 @@ msgstr[1] "ПопередженнÑ"
msgstr[2] "Попереджень"
msgstr[3] "Попереджень"
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
+msgstr "ПопередженнÑ"
+
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
msgstr ""
msgid "AlertManagement|Authorize external service"
msgstr ""
-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."
+msgid "AlertManagement|Create issue"
msgstr ""
-msgid "AlertManagement|End time"
+msgid "AlertManagement|Critical"
+msgstr ""
+
+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|End time:"
+msgid "AlertManagement|Edit"
msgstr ""
+msgid "AlertManagement|End time"
+msgstr "Ð§Ð°Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ"
+
msgid "AlertManagement|Events"
+msgstr "Події"
+
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
+msgstr "Детальніше"
+
+msgid "AlertManagement|No alert data to display."
msgstr ""
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
-msgstr ""
+msgstr "Ðемає повідомлень Ð´Ð»Ñ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ. Якщо ви вважаєте, що бачите це Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¾Ð²Ð¾, оновіть Ñторінку."
msgid "AlertManagement|No alerts to display."
+msgstr "Ðемає попереджень Ð´Ð»Ñ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ."
+
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
msgstr ""
msgid "AlertManagement|Overview"
+msgstr "ОглÑд"
+
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
msgstr ""
msgid "AlertManagement|Resolved"
+msgstr "Вирішено"
+
+msgid "AlertManagement|Service"
msgstr ""
msgid "AlertManagement|Severity"
-msgstr ""
+msgstr "Рівень"
msgid "AlertManagement|Start time"
+msgstr "Ð§Ð°Ñ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ"
+
+msgid "AlertManagement|Status"
+msgstr "СтатуÑ"
+
+msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
msgstr ""
-msgid "AlertManagement|Status"
+msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
-msgid "AlertManagement|Surface alerts in GitLab"
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
msgstr ""
-msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
+msgid "AlertManagement|Tool"
msgstr ""
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
-msgstr "%{linkStart}ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ%{linkEnd} про Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ†Ñ–Ñ”Ñ— кінцевої точки Ð´Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð¶ÐµÐ½ÑŒ."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
+msgstr ""
+
+msgid "AlertManagement|View issue"
+msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
-msgstr "Кожне джерело попереджень повинно бути авторизоване за допомогою наÑтупної URL-адреÑи та ключа авторизації."
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
+msgstr ""
msgid "Alerts"
msgstr "ПопередженнÑ"
@@ -1910,7 +2109,7 @@ msgid "All"
msgstr "Ð’ÑÑ–"
msgid "All %{replicableType} are being scheduled for %{action}"
-msgstr ""
+msgstr "Ð’ÑÑ– %{replicableType} заплановано на %{action}"
msgid "All (default)"
msgstr "Ð’ÑÑ– (за замовчуваннÑм)"
@@ -1925,7 +2124,7 @@ msgid "All changes are committed"
msgstr "Ð’ÑÑ– зміни закомічені"
msgid "All default stages are currently visible"
-msgstr ""
+msgstr "Ðаразі відображаютьÑÑ Ð²ÑÑ– Ñтадії за замовчуваннÑм"
msgid "All email addresses will be used to identify your commits."
msgstr "Ð’ÑÑ– адреÑи електронної пошти будуть викориÑтовуватиÑÑ Ð´Ð»Ñ Ñ–Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ— ваших комітів."
@@ -1937,7 +2136,7 @@ msgid "All features are enabled for blank projects, from templates, or when impo
msgstr "Ð’ÑÑ– функції Ð´Ð»Ñ Ð½Ð¾Ð²Ð¸Ñ… проектів берутьÑÑ Ñ–Ð· шаблонів або під Ñ‡Ð°Ñ Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ, але ви можете вимикати Ñ—Ñ… пізніше в налаштуваннÑÑ… проекту."
msgid "All groups and projects"
-msgstr ""
+msgstr "Ð’ÑÑ– групи та проєкти"
msgid "All issues for this milestone are closed."
msgstr "Ð’ÑÑ– задачі в цьому етапі закриті."
@@ -1955,13 +2154,13 @@ msgid "All paths are relative to the GitLab URL. Do not include %{relative_url_l
msgstr "Ð’ÑÑ– шлÑхи Ñ” відноÑними до URL-адреÑи GitLab. Ðе включайте %{relative_url_link_start}відноÑну URL-адреÑу%{relative_url_link_end}."
msgid "All projects"
-msgstr ""
+msgstr "Ð’ÑÑ– проєкти"
msgid "All security scans are enabled because %{linkStart}Auto DevOps%{linkEnd} is enabled on this project"
msgstr "Ð’ÑÑ– ÑÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð±ÐµÐ·Ð¿ÐµÐºÐ¸ увімкнені, тому що %{linkStart}Auto DevOps%{linkEnd} увімкнено в цьому проєкті"
msgid "All threads resolved"
-msgstr ""
+msgstr "УÑÑ– Ð¾Ð±Ð³Ð¾Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð²Ð¸Ñ€Ñ–ÑˆÐµÐ½Ð¾"
msgid "All users"
msgstr "Ð’ÑÑ– кориÑтувачі"
@@ -1982,10 +2181,10 @@ msgid "Allow only the selected protocols to be used for Git access."
msgstr "Дозволити викориÑÑ‚Ð°Ð½Ð½Ñ Ñ‚Ñ–Ð»ÑŒÐºÐ¸ вибраних протоколів Ð´Ð»Ñ Ð´Ð¾Ñтупу до Git."
msgid "Allow owners to manage default branch protection per group"
-msgstr ""
+msgstr "Дозволити влаÑникам керувати захиÑтом гілок за замовчуваннÑм Ð´Ð»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ñ— групи"
msgid "Allow owners to manually add users outside of LDAP"
-msgstr ""
+msgstr "Дозволити влаÑникам вручну додавати кориÑтувачів за межами LDAP"
msgid "Allow projects within this group to use Git LFS"
msgstr "Дозволити проектам в цій групі викориÑтовувати Git LFS"
@@ -2015,7 +2214,7 @@ msgid "Allow this secondary node to replicate content on Object Storage"
msgstr ""
msgid "Allow users to dismiss the broadcast message"
-msgstr ""
+msgstr "Дозволити кориÑтувачам відхилÑти повідомленнÑ"
msgid "Allow users to register any application to use GitLab as an OAuth provider"
msgstr "Дозволити кориÑтувачам реєÑтрувати будь-Ñкі заÑтоÑунки Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ GitLab Ñк провайдера OAuth"
@@ -2045,7 +2244,7 @@ msgid "Alternate support URL for help page and help dropdown"
msgstr "Ðльтернативна URL-адреÑа Ñлужби підтримки Ð´Ð»Ñ Ñторінки довідки та випадаючого меню"
msgid "Alternatively, you can convert your account to a managed account by the %{group_name} group."
-msgstr ""
+msgstr "Крім того, ви можете перетворити Ñвій акаунт в акаунт, керований групою %{group_name}."
msgid "Amazon EKS"
msgstr "Amazon EKS"
@@ -2068,6 +2267,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr "Додаток під назвою %{link_to_client} запитує доÑтуп до вашого 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 ""
+
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 "Порожнє поле Gitlab-кориÑтувача буде заповнено іменем кориÑтувача з FogBugz (наприклад \"John Smith\") в опиÑÑ– вÑÑ–Ñ… задач та коментарів. Крім того ці задачі та коментарі будуть аÑоційовані з та/або призначені на автора проекту."
@@ -2093,7 +2295,7 @@ msgid "An error occurred fetching the dropdown data."
msgstr "Помилка при отриманні даних Ð´Ð»Ñ Ð²Ð¸Ð¿Ð°Ð´Ð°ÑŽÑ‡Ð¾Ð³Ð¾ ÑпиÑку."
msgid "An error occurred fetching the project authors."
-msgstr ""
+msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° під Ñ‡Ð°Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ñ–Ð² проєкту."
msgid "An error occurred previewing the blob"
msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° під Ñ‡Ð°Ñ Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð½ÑŒÐ¾Ð³Ð¾ переглÑду об'єкта"
@@ -2111,7 +2313,7 @@ msgid "An error occurred when updating the issue weight"
msgstr "Збій під Ñ‡Ð°Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð²Ð°Ð³Ð¸ задачі"
msgid "An error occurred while adding formatted title for epic"
-msgstr ""
+msgstr "Помилка під Ñ‡Ð°Ñ Ð´Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ Ð²Ñ–Ð´Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð¾Ð²Ð°Ð½Ð¾Ð³Ð¾ заголовка Ð´Ð»Ñ ÐµÐ¿Ñ–ÐºÐ°"
msgid "An error occurred while checking group path"
msgstr "Помилка при перевірці шлÑху групи"
@@ -2120,7 +2322,7 @@ msgid "An error occurred while committing your changes."
msgstr "Помилка при коміті ваших змін."
msgid "An error occurred while decoding the file."
-msgstr ""
+msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° під Ñ‡Ð°Ñ Ð´ÐµÐºÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ."
msgid "An error occurred while deleting the approvers group"
msgstr "Помилка при видаленні групи затверджуючих оÑіб"
@@ -2233,9 +2435,6 @@ msgstr "Помилка при завантаженні вÑÑ–Ñ… файлів."
msgid "An error occurred while loading chart data"
msgstr "Виникла помилка під Ñ‡Ð°Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… діаграми"
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr "ТрапилаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при завантаженні підпиÑів комітів"
@@ -2257,9 +2456,12 @@ msgstr "Помилка при завантаженні задач"
msgid "An error occurred while loading merge requests."
msgstr "Помилка при завантаженні результатів злиттÑ."
-msgid "An error occurred while loading terraform report"
+msgid "An error occurred while loading milestones"
msgstr ""
+msgid "An error occurred while loading terraform report"
+msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° під Ñ‡Ð°Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ€ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ñ–Ð² Terraform"
+
msgid "An error occurred while loading the data. Please try again."
msgstr "Під Ñ‡Ð°Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… ÑталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°. Будь лаÑка, Ñпробуйте ще раз."
@@ -2273,7 +2475,7 @@ msgid "An error occurred while loading the file."
msgstr "Помилка при завантаженні файлу."
msgid "An error occurred while loading the file. Please try again later."
-msgstr ""
+msgstr "Помилка при завантаженні файлу. Будь лаÑка, Ñпробуйте ще раз пізніше."
msgid "An error occurred while loading the merge request changes."
msgstr "Помилка при завантаженні змін запиту на злиттÑ."
@@ -2300,7 +2502,7 @@ msgid "An error occurred while parsing recent searches"
msgstr "Помилка при обробці Ñ–Ñторії пошуків"
msgid "An error occurred while parsing the file."
-msgstr ""
+msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при обробці файлу."
msgid "An error occurred while removing epics."
msgstr "Помилка при видаленні епіків."
@@ -2332,6 +2534,9 @@ msgstr "Помилка під Ñ‡Ð°Ñ Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½ÑŒ
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr "Під Ñ‡Ð°Ñ Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½Ñƒ ÑталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°. Будь лаÑка, перевірте, чи такий шаблон Ñ–Ñнує."
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr "Помилка при підпиÑці на ÑповіщеннÑ."
@@ -2360,17 +2565,23 @@ msgid "An error occurred. Please try again."
msgstr "СталаÑÑŒ помилка. Спробуйте ще раз."
msgid "An error ocurred while loading your content. Please try again."
-msgstr ""
+msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° під Ñ‡Ð°Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ контенту. Будь лаÑка, Ñпробуйте ще раз."
msgid "An example project for managing Kubernetes clusters integrated with GitLab."
-msgstr ""
+msgstr "Приклад проєкту Ð´Ð»Ñ ÑƒÐ¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ ÐºÐ»Ð°Ñтерами Kubernetes, інтегрованими з GitLab."
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr "Задача може опиÑувати помилку, бути нагадуваннÑм або опиÑом нової функціональноÑÑ‚Ñ– Ð´Ð»Ñ Ð¾Ð±Ð³Ð¾Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð² проекті. Крім того задачі можна шукати та фільтрувати."
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr "Ðеочікувана помилка при перевірці Ñередовища проекту."
@@ -2386,6 +2597,9 @@ msgstr "Ðеочікувана помилка при запуÑку Веб-теÑ
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr "Ðеочікувана помилка при зупинці Веб-терміналу."
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr "Ðналітика"
@@ -2395,6 +2609,9 @@ msgstr "Проаналізуйте верÑÑ–ÑŽ Ð´Ð»Ñ Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð½ÑŒÐ¾Ð³Ð¾
msgid "Analyze your dependencies for known vulnerabilities."
msgstr "Проаналізуйте ваші залежноÑÑ‚Ñ– на предмет відомих вразливоÑтей."
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr "Проаналізуйте ваш вихідний код на предмет відомих вразливоÑтей."
@@ -2405,7 +2622,7 @@ msgid "Anonymous"
msgstr "Ðнонімно"
msgid "Another action is currently in progress"
-msgstr ""
+msgstr "Ð’ даний момент виконуєтьÑÑ Ñ‰Ðµ одна діÑ"
msgid "Another issue tracker is already in use. Only one issue tracker service can be active at a time"
msgstr ""
@@ -2417,13 +2634,7 @@ msgid "Any"
msgstr "Будь-Ñкий"
msgid "Any Author"
-msgstr ""
-
-msgid "Any Label"
-msgstr "Будь-Ñка мітка"
-
-msgid "Any Milestone"
-msgstr "Будь-Ñкий етап"
+msgstr "Будь-Ñкий автор"
msgid "Any branch"
msgstr "Будь-Ñка гілка"
@@ -2434,9 +2645,15 @@ msgstr "Будь-Ñкий кориÑтувач з необхідним доÑÑ‚Ñ
msgid "Any encrypted tokens"
msgstr "Будь-Ñкі зашифровані токени"
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr "Будь-Ñкий учаÑник з рівнем доÑтупу Розробник або вище до цього проєкту."
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr "Будь-Ñкий проÑÑ‚Ñ–Ñ€ імен"
@@ -2471,7 +2688,7 @@ msgid "Application settings saved successfully"
msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°ÑтоÑунку уÑпішно збережено"
msgid "Application settings update failed"
-msgstr ""
+msgstr "ÐžÐ½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½ÑŒ програми не вдалоÑÑ"
msgid "Application uninstalled but failed to destroy: %{error_message}"
msgstr "ЗаÑтоÑунок видалено, але не вдалоÑÑ Ð·Ð½Ð¸Ñ‰Ð¸Ñ‚Ð¸: %{error_message}"
@@ -2500,6 +2717,9 @@ msgstr "ЗаÑтоÑувати мітку"
msgid "Apply a template"
msgstr "ЗаÑтоÑувати шаблон"
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr "ЗаÑтоÑувати пропозицію"
@@ -2571,17 +2791,11 @@ msgid "ApprovalRule|Rule name"
msgstr "Ð†Ð¼â€™Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»Ð°"
msgid "ApprovalRule|Target branch"
-msgstr ""
+msgstr "Цільова гілка"
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr "наприклад QA, безпека і т. д."
-msgid "Approvals"
-msgstr "ЗатвердженнÑ"
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr "Затвердити"
@@ -2591,17 +2805,23 @@ msgstr "Затвердити запит на злиттÑ"
msgid "Approve the current merge request."
msgstr "Затвердити поточний запит на злиттÑ."
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr "Затверджено кориÑтувачем: "
msgid "Approved the current merge request."
msgstr "Затверджено поточний запит на злиттÑ."
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr "Затверджуюча оÑоба"
msgid "Approvers"
-msgstr ""
+msgstr "Затверджуючі оÑоби"
msgid "Apr"
msgstr "квіт."
@@ -2616,7 +2836,7 @@ msgid "Archive jobs"
msgstr "Ðрхівувати завданнÑ"
msgid "Archive project"
-msgstr "Ðрхівувати проект"
+msgstr "Ðрхівувати проєкт"
msgid "Archived"
msgstr "Заархівовано"
@@ -2628,7 +2848,7 @@ msgid "Archived project! Repository and other project resources are read-only"
msgstr "Ðрхівований проект! Репозиторій та інші реÑурÑи проекту доÑтупні лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ"
msgid "Archived projects"
-msgstr ""
+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}"
msgstr "ÐÑ€Ñ…Ñ–Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ñ”ÐºÑ‚Ñƒ зробить його доÑтупним лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ. Він буде прихований з панелі ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ñ– не відображатиметьÑÑ Ð² пошуках. %{strong_start}Ð’ репозиторій не можна буде комітити, Ñ– не можливо буде Ñтворити жодних задач, коментарів чи інших об'єктів.%{strong_end}"
@@ -2646,10 +2866,10 @@ msgid "Are you sure you want to cancel editing this comment?"
msgstr "Ви впевнені, що хочете ÑкаÑувати Ñ€ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ коментарÑ?"
msgid "Are you sure you want to close this blocked issue?"
-msgstr ""
+msgstr "Ви впевнені, що хочете закрити цю заблоковану задачу?"
msgid "Are you sure you want to delete %{name}?"
-msgstr ""
+msgstr "Ви впевнені, що хочете видалити %{name}?"
msgid "Are you sure you want to delete these artifacts?"
msgstr "Ви впевнені, що бажаєте видалити ці артефакти?"
@@ -2676,7 +2896,7 @@ msgid "Are you sure you want to deploy this environment?"
msgstr ""
msgid "Are you sure you want to discard this comment?"
-msgstr ""
+msgstr "Ви впевнені, що хочете видалити цей коментар?"
msgid "Are you sure you want to erase this build?"
msgstr "Ви впевнені, що хочете видалити цей білд?"
@@ -2705,6 +2925,9 @@ msgstr "Ви впевнені, що хочете видалити %{group_name}?
msgid "Are you sure you want to remove the attachment?"
msgstr "Ви впевнені, що бажаєте видалити вкладеннÑ?"
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr "Ви впевнені, що хочете видалити цю ідентифікацію?"
@@ -2717,8 +2940,8 @@ msgstr "Ви впевнені, що хочете Ñкинути токен SCIM?
msgid "Are you sure you want to reset the health check token?"
msgstr "Ви впевнені, що Ви хочете перегенерувати цей ключ перевірки працездатноÑÑ‚Ñ–?"
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
-msgstr "Ви впевнені, що бажаєте видалити цей %{type} токен? Ð¦Ñ Ð´Ñ–Ñ Ð½Ðµ може бути ÑкаÑована."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
+msgstr ""
msgid "Are you sure you want to revoke this nickname?"
msgstr "Ви впевнені, що хочете ÑкаÑувати цей пÑевдонім?"
@@ -2831,6 +3054,9 @@ msgstr "Призначені задачі"
msgid "Assigned Merge Requests"
msgstr "Призначені запити на злиттÑ"
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr "Призначено мені"
@@ -2863,7 +3089,7 @@ msgid "At least one of group_id or project_id must be specified"
msgstr "Треба зазначити принаймні group_id або project_id"
msgid "At risk"
-msgstr ""
+msgstr "З ризиком"
msgid "Attach a file"
msgstr "Прикріпити файл"
@@ -2900,24 +3126,42 @@ msgid "AuditEvents|Target"
msgstr "Ціль"
msgid "AuditLogs|(removed)"
-msgstr ""
+msgstr "(видалено)"
msgid "AuditLogs|Action"
-msgstr ""
+msgstr "ДіÑ"
msgid "AuditLogs|Author"
-msgstr ""
+msgstr "Ðвтор"
msgid "AuditLogs|Date"
+msgstr "Дата"
+
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
msgstr ""
msgid "AuditLogs|IP Address"
+msgstr "IP-адреÑа"
+
+msgid "AuditLogs|No matching %{type} found."
msgstr ""
msgid "AuditLogs|Object"
+msgstr "Об'єкт"
+
+msgid "AuditLogs|Project Events"
msgstr ""
msgid "AuditLogs|Target"
+msgstr "Ціль"
+
+msgid "AuditLogs|User Events"
msgstr ""
msgid "Aug"
@@ -2936,7 +3180,7 @@ msgid "Authenticating"
msgstr "ÐвтентифікаціÑ"
msgid "Authentication Failure"
-msgstr ""
+msgstr "Помилка автентифікації"
msgid "Authentication Log"
msgstr "Журнал автентифікації"
@@ -2977,6 +3221,9 @@ msgstr "ÐвторизаціÑ"
msgid "Authorize %{link_to_client} to use your account?"
msgstr "ÐвторизуватиÑÑ %{link_to_client} викориÑтовуючи ваш аккаунт?"
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr "Ðвторизовано %{new_chat_name}"
@@ -2998,9 +3245,6 @@ msgstr "Auto DevOps увімкнено"
msgid "Auto DevOps, runners and job artifacts"
msgstr "Auto DevOps, runner'и і артефакти завдань"
-msgid "Auto License Compliance"
-msgstr "Ðвтоматична відповідніÑÑ‚ÑŒ ліцензіÑм"
-
msgid "Auto stop successfully canceled."
msgstr "Ðвтозупинка уÑпішно ÑкаÑована."
@@ -3014,11 +3258,14 @@ msgid "AutoDevOps|Auto DevOps"
msgstr "Auto DevOps"
msgid "AutoDevOps|Auto DevOps can automatically build, test, and deploy applications based on predefined continuous integration and delivery configuration. %{auto_devops_start}Learn more about Auto DevOps%{auto_devops_end} or use our %{quickstart_start}quick start guide%{quickstart_end} to get started right away."
-msgstr ""
+msgstr "Auto DevOps може автоматично збирати, теÑтувати Ñ– розгортати заÑтоÑунки на оÑнові заздалегідь визначених налаштувань безперервної інтеграції та розгортаннÑ. %{auto_devops_start}ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про Auto DevOps%{auto_devops_end} або ÑкориÑтайтеÑÑ Ð½Ð°ÑˆÐ¸Ð¼ %{quickstart_start}коротким поÑібником%{quickstart_end} щоб відразу ж приÑтупити до роботи."
msgid "AutoDevOps|Auto DevOps documentation"
msgstr "Auto DevOps документації"
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr "Включити в налаштуваннÑÑ…"
@@ -3049,6 +3296,9 @@ msgstr "Ðвтоматичне ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ñертифікатами зÐ
msgid "Automatic certificate management using Let's Encrypt"
msgstr "Ðвтоматичне ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ñертифікатами за допомогою Let's Encrypt"
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr "Ðвтоматично позначено Ñк внутрішній кориÑтувач за замовчуваннÑм"
@@ -3064,6 +3314,9 @@ msgstr "Примітка"
msgid "Available"
msgstr "ДоÑтупно"
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr "ДоÑтупні групові Runner'и: %{runners}"
@@ -3086,7 +3339,7 @@ msgid "Average per day: %{average}"
msgstr "Ð’ Ñередньому за день: %{average}"
msgid "Back to page %{number}"
-msgstr ""
+msgstr "Ðазад до Ñторінки %{number}"
msgid "Background Color"
msgstr "Колір фону"
@@ -3143,7 +3396,7 @@ msgid "Badges|Please fill in a valid URL"
msgstr "Будь лаÑка, введіть дійÑну URL-адреÑу"
msgid "Badges|Project Badge"
-msgstr "Значок проекту"
+msgstr "Значок проєкту"
msgid "Badges|Reload badge image"
msgstr "Оновити Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð·Ð½Ð°Ñ‡ÐºÐ°"
@@ -3541,17 +3794,17 @@ msgstr "Відкрити вагу задачі"
msgid "BurndownChartLabel|Open issues"
msgstr "Відкриті задачі"
+msgid "Burnup chart"
+msgstr ""
+
msgid "Business"
msgstr "БізнеÑ"
msgid "Business metrics (Custom)"
msgstr "Ð‘Ñ–Ð·Ð½ÐµÑ Ð¼ÐµÑ‚Ñ€Ð¸ÐºÐ¸ (ВлаÑні)"
-msgid "Buy EE"
-msgstr "Купити ЕЕ"
-
-msgid "Buy GitLab Enterprise Edition"
-msgstr "Купити GitLab Enterprise Edition"
+msgid "Buy License"
+msgstr ""
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -3563,7 +3816,7 @@ msgid "By default GitLab sends emails in HTML and plain text formats so mail cli
msgstr "За замовчуваннÑм GitLab відправлÑÑ” електронні лиÑти в форматі HTML та у звичайному текÑтовому форматі, щоб поштові клієнти могли вибирати Ñкий з форматів викориÑтовувати. Вимкніть це налаштуваннÑ, Ñкщо ви хочете відправлÑти лиÑти лише у звичайному текÑтовому форматі."
msgid "By default, all projects and groups will use the global notifications setting."
-msgstr ""
+msgstr "За замовчуваннÑм уÑÑ– проєкти та групи будуть викориÑтовувати глобальні Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñповіщень."
msgid "ByAuthor|by"
msgstr "від"
@@ -3574,8 +3827,8 @@ msgstr "СпиÑок змін (CHANGELOG)"
msgid "CI / CD"
msgstr "CI / CD"
-msgid "CI / CD Charts"
-msgstr "СтатиÑтика CI / CD"
+msgid "CI / CD Analytics"
+msgstr ""
msgid "CI / CD Settings"
msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ CI/CD"
@@ -3583,6 +3836,9 @@ msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ CI/CD"
msgid "CI Lint"
msgstr "Перевірка CI конфігурації"
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr "Змінні CI"
@@ -3601,6 +3857,9 @@ msgstr "CI/CD Ð´Ð»Ñ Ð·Ð¾Ð²Ð½Ñ–ÑˆÐ½ÑŒÐ¾Ð³Ð¾ репозиторіÑ"
msgid "CI/CD settings"
msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ CI/CD"
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr "Auto DevOps"
@@ -3631,9 +3890,6 @@ msgstr "Конвеєр Auto DevOps буде запущено, Ñкщо не бу
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr "Ви повинні додати %{base_domain_link_start}базовий домен%{link_end} до вашого %{kubernetes_cluster_link_start}Kubernetes клаÑтера%{link_end} щоб ваша ÑÑ‚Ñ€Ð°Ñ‚ÐµÐ³Ñ–Ñ Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ð½Ñ Ñ„ÑƒÐ½ÐºÑ†Ñ–Ð¾Ð½ÑƒÐ²Ð°Ð»Ð°."
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr "Ви повинні додати %{kubernetes_cluster_link_start}клаÑтерну інтеграцію Kubernetes%{link_end} до цього проекту з доменом Ð´Ð»Ñ ÐºÐ¾Ñ€ÐµÐºÑ‚Ð½Ð¾Ñ— роботи Ñтратегії розгортаннÑ."
-
msgid "CICD|group enabled"
msgstr "група увімкнена"
@@ -3661,6 +3917,12 @@ msgstr "Можна вручну розгорнути на"
msgid "Can override approvers and approvals required per merge request"
msgstr "Можна змінювати необхідні Ð·Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ñ‚Ð° затверджуючих оÑіб Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñ‚Ñ–Ð² на злиттÑ"
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr "Ðе можу знайти HEAD-коміт Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— гілки"
@@ -3677,7 +3939,7 @@ msgid "Can't scan the code?"
msgstr "Ðеможливо Ñканувати код?"
msgid "Can't update snippet: %{err}"
-msgstr ""
+msgstr "Ðеможливо оновити Ñніпет: %{err}"
msgid "Canary"
msgstr "Canary"
@@ -3713,10 +3975,10 @@ msgid "Cannot have multiple Jira imports running at the same time"
msgstr ""
msgid "Cannot import because issues are not available in this project."
-msgstr ""
+msgstr "Ðе вдаєтьÑÑ Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ñ‚Ð¸, тому що задачі не доÑтупні в цьому проєкті."
msgid "Cannot make epic confidential if it contains not-confidential issues"
-msgstr ""
+msgstr "Ðе можна зробити епік конфіденційним, Ñкщо він міÑтить неконфіденційні задачі"
msgid "Cannot make epic confidential if it contains not-confidential sub-epics"
msgstr ""
@@ -3728,19 +3990,19 @@ msgid "Cannot modify managed Kubernetes cluster"
msgstr "Ðеможливо змінити керований клаÑтер Kubernetes"
msgid "Cannot modify provider during creation"
-msgstr ""
+msgstr "Ðеможливо змінити провайдера в процеÑÑ– ÑтвореннÑ."
msgid "Cannot promote issue because it does not belong to a group."
-msgstr ""
+msgstr "Ðеможливо переміÑтити задачу, тому що вона не належить групі."
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
-msgstr "Ðеможливо поÑилатиÑÑ Ð½Ð° груповий етап через внутрішній ідентифікатор!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
+msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
-msgstr ""
+msgstr "Ðе можна додати конфіденційний епік Ð´Ð»Ñ Ð½ÐµÐºÐ¾Ð½Ñ„Ñ–Ð´ÐµÐ½Ñ†Ñ–Ð¹Ð½Ð¾Ñ— задачі"
msgid "Cannot show preview. For previews on sketch files, they must have the file format introduced by Sketch version 43 and above."
msgstr "Ðеможливо показати попередній переглÑд. Ð”Ð»Ñ Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð½ÑŒÐ¾Ð³Ð¾ переглÑду файлів Sketch, вони повинні мати формат, введений верÑією 43 або вище."
@@ -3751,6 +4013,9 @@ msgstr "Ðеможливо пропуÑтити Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð²Ð¾Ñ
msgid "Capacity threshold"
msgstr "Поріг пропуÑкної здатноÑÑ‚Ñ–"
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr "Сертифікат"
@@ -3787,6 +4052,12 @@ msgstr "Змінити шлÑÑ…"
msgid "Change permissions"
msgstr "Змінити права доÑтупу"
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr "Змінити шаблон"
@@ -3829,9 +4100,12 @@ msgstr "Зміни"
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr "Зміни відображаютьÑÑ Ñ‚Ð°Ðº, ніби <b>редакціÑ-джерело</b> була злита в <b>цільову редакцію</b>."
-msgid "Changes are unknown"
+msgid "Changes are still tracked. Useful for cluster/index migrations."
msgstr ""
+msgid "Changes are unknown"
+msgstr "Зміни невідомі"
+
msgid "Changes suppressed. Click to show."
msgstr "Зміни приховано. ÐатиÑніть щоб показати."
@@ -3847,6 +4121,9 @@ msgstr "Зміна тегу релізу підтримуєтьÑÑ Ð»Ð¸ÑˆÐµ чÐ
msgid "Changing group path can have unintended side effects."
msgstr "Зміна шлÑху групи може мати небажані побічні ефекти."
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3938,7 +4215,7 @@ msgid "Checkout|$%{selectedPlanPrice} per user per year"
msgstr "$%{selectedPlanPrice} на кориÑтувача на рік"
msgid "Checkout|%{cardType} ending in %{lastFourDigits}"
-msgstr ""
+msgstr "%{cardType} закінчуєтьÑÑ Ð½Ð° %{lastFourDigits}"
msgid "Checkout|%{name}'s GitLab subscription"
msgstr "ПідпиÑка GitLab Ð´Ð»Ñ %{name}"
@@ -3952,15 +4229,6 @@ msgstr "%{startDate} - %{endDate}"
msgid "Checkout|(x%{numberOfUsers})"
msgstr "(x%{numberOfUsers})"
-msgid "Checkout|1. Your profile"
-msgstr "1. Ваш профіль"
-
-msgid "Checkout|2. Checkout"
-msgstr "2. ÐžÑ„Ð¾Ñ€Ð¼Ð»ÐµÐ½Ð½Ñ Ð·Ð°Ð¼Ð¾Ð²Ð»ÐµÐ½Ð½Ñ"
-
-msgid "Checkout|3. Your GitLab group"
-msgstr "3. Ваша група GitLab"
-
msgid "Checkout|Billing address"
msgstr ""
@@ -3971,7 +4239,7 @@ msgid "Checkout|City"
msgstr "МіÑто"
msgid "Checkout|Confirm purchase"
-msgstr ""
+msgstr "Підтвердити покупку"
msgid "Checkout|Confirming..."
msgstr "ПідтвердженнÑ..."
@@ -3989,10 +4257,10 @@ msgid "Checkout|Create a new group"
msgstr "Створити нову групу"
msgid "Checkout|Credit card form failed to load. Please try again."
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ форму кредитної картки. Будь лаÑка, Ñпробуйте ще раз."
msgid "Checkout|Credit card form failed to load: %{message}"
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ форму кредитної картки: %{message}"
msgid "Checkout|Edit"
msgstr "Редагувати"
@@ -4001,19 +4269,19 @@ msgid "Checkout|Exp %{expirationMonth}/%{expirationYear}"
msgstr ""
msgid "Checkout|Failed to confirm your order! Please try again."
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸ ваше замовленнÑ! Будь лаÑка, Ñпробуйте ще раз."
msgid "Checkout|Failed to confirm your order: %{message}. Please try again."
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸ ваше замовленнÑ: %{message}. Будь лаÑка, Ñпробуйте ще раз."
msgid "Checkout|Failed to load countries. Please try again."
-msgstr ""
+msgstr "Помилка при завантаженні країн. Будь лаÑка, Ñпробуйте ще раз."
msgid "Checkout|Failed to load states. Please try again."
msgstr ""
msgid "Checkout|Failed to register credit card. Please try again."
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ð·Ð°Ñ€ÐµÑ”Ñтрувати кредитну картку. Будь лаÑка, Ñпробуйте ще раз."
msgid "Checkout|GitLab group"
msgstr "Група GitLab"
@@ -4037,7 +4305,7 @@ msgid "Checkout|Payment method"
msgstr "СпоÑіб оплати"
msgid "Checkout|Please select a country"
-msgstr ""
+msgstr "Будь лаÑка, виберіть країну"
msgid "Checkout|Please select a state"
msgstr ""
@@ -4052,7 +4320,7 @@ msgid "Checkout|Street address"
msgstr ""
msgid "Checkout|Submitting the credit card form failed with code %{errorCode}: %{errorMessage}"
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ð²Ñ–Ð´Ð¿Ñ€Ð°Ð²Ð¸Ñ‚Ð¸ форму кредитної картки з кодом %{errorCode}: %{errorMessage}"
msgid "Checkout|Subscription details"
msgstr "Деталі підпиÑки"
@@ -4076,7 +4344,7 @@ msgid "Checkout|Your organization"
msgstr "Ваша організаціÑ"
msgid "Checkout|Your subscription will be applied to this group"
-msgstr ""
+msgstr "Ваша підпиÑка буде заÑтоÑована до цієї групи"
msgid "Checkout|Zip code"
msgstr "Поштовий індекÑ"
@@ -4145,13 +4413,13 @@ msgid "Choose what content you want to see on a group’s overview page"
msgstr "Вибрати вміÑÑ‚ оглÑдової Ñторінки групи"
msgid "Choose which groups you wish to synchronize to this secondary node"
-msgstr ""
+msgstr "Виберіть, Ñкі групи ви хочете Ñинхронізувати з вторинним вузлом."
msgid "Choose which repositories you want to connect and run CI/CD pipelines."
msgstr "Виберіть, Ñкі репозиторії ви хочете підключити Ñ– запуÑтити конвеєри CI/CD."
msgid "Choose which shards you wish to synchronize to this secondary node"
-msgstr ""
+msgstr "Виберіть, Ñкі Ñегменти ви хочете Ñинхронізувати з цим вторинним вузлом."
msgid "Choose your framework"
msgstr ""
@@ -4309,9 +4577,6 @@ msgstr "Перевірка невдала"
msgid "Class"
msgstr "КлаÑ"
-msgid "Class:"
-msgstr "КлаÑ:"
-
msgid "Classification Label (optional)"
msgstr "Мітка клаÑифікації (необов'Ñзково)"
@@ -4324,6 +4589,9 @@ msgstr "ОчиÑтити"
msgid "Clear chart filters"
msgstr "ОчиÑтити фільтри графіків"
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr "ОчиÑтити ввід"
@@ -4336,6 +4604,9 @@ msgstr "ОчиÑтити пошук"
msgid "Clear search input"
msgstr "ОчиÑтити поле вводу"
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr "ОчиÑтити поле вводу Ð´Ð»Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ шаблонів"
@@ -4363,9 +4634,6 @@ msgstr "ÐатиÑніть кнопку <strong>Обрати нічого</stron
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr "ÐатиÑніть кнопку нижче, щоб розпочати Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð²ÑтановленнÑ, перейшовши на Ñторінку Kubernetes"
-msgid "Click the image where you'd like to start a new discussion"
-msgstr "ÐатиÑніть на зображеннÑ, де ви хочете почати нове обговореннÑ"
-
msgid "Click to expand it."
msgstr "ÐатиÑніть, щоб розгорнути його."
@@ -4394,7 +4662,7 @@ msgid "Clone with %{http_label}"
msgstr "Клонувати з %{http_label}"
msgid "Clone with %{protocol}"
-msgstr ""
+msgstr "Клонувати з %{protocol}"
msgid "Clone with KRB5"
msgstr "Клонувати з KRB5"
@@ -4405,6 +4673,9 @@ msgstr "Клонувати з SSH"
msgid "Close"
msgstr "Закрити"
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr "Закрити %{tabname}"
@@ -4430,7 +4701,7 @@ msgid "Closed this %{quick_action_target}."
msgstr "Закрито %{quick_action_target}."
msgid "Closed: %{closedIssuesCount}"
-msgstr ""
+msgstr "Закрито: %{closedIssuesCount}"
msgid "Closes this %{quick_action_target}."
msgstr "Закриває %{quick_action_target}."
@@ -4445,7 +4716,7 @@ msgid "Cluster cache cleared."
msgstr "Кеш клаÑтера очищено."
msgid "Cluster does not exist"
-msgstr ""
+msgstr "КлаÑтер не Ñ–Ñнує"
msgid "Cluster level"
msgstr "Рівень клаÑтера"
@@ -4553,7 +4824,7 @@ msgid "ClusterIntegration|Base domain"
msgstr "ОÑновний домен"
msgid "ClusterIntegration|Blocking mode"
-msgstr ""
+msgstr "Режим блокуваннÑ"
msgid "ClusterIntegration|CA Certificate"
msgstr "Сертифікат центру Ñертифікації"
@@ -4600,6 +4871,9 @@ msgstr "Проєкт ÑƒÐ¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ ÐºÐ»Ð°Ñтером (альфа)"
msgid "ClusterIntegration|Cluster name is required."
msgstr "Ім'Ñ ÐºÐ»Ð°Ñтера Ñ” обов'Ñзковим."
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr "КлаÑтери викориÑтовуютьÑÑ ÑˆÐ»Ñхом вибору найближчого предка з підходÑщою доÑтупніÑÑ‚ÑŽ Ð´Ð»Ñ Ñередовищ. Ðаприклад проєктні клаÑтери перекривають групові клаÑтери."
@@ -4621,9 +4895,6 @@ msgstr "Скопіювати кінцеву точку Knative"
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr "Скопіювати Ñ–Ð¼â€™Ñ Kubernetes-клаÑтера"
-msgid "ClusterIntegration|Copy Service Token"
-msgstr "Скопіювати токен ÑервіÑа"
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr "Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ ролі IAM"
@@ -4675,7 +4946,7 @@ msgstr "Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Kubernetes-клаÑтера"
msgid "ClusterIntegration|Crossplane"
msgstr "Crossplane"
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4702,6 +4973,9 @@ msgstr "Увімкніть цей параметр, Ñкщо викориÑтоÐ
msgid "ClusterIntegration|Enabled stack"
msgstr "Увімкнений Ñтек"
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr "Введіть параметри вашого Amazon EKS Kubernetes-клаÑтера"
@@ -4739,7 +5013,7 @@ msgid "ClusterIntegration|Fetching zones"
msgstr "ÐžÑ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð·Ð¾Ð½"
msgid "ClusterIntegration|Fluentd"
-msgstr ""
+msgstr "Fluentd"
msgid "ClusterIntegration|Fluentd is an open source data collector, which lets you unify the data collection and consumption for a better use and understanding of data. It requires at least one of the following logs to be successfully installed."
msgstr ""
@@ -4780,12 +5054,12 @@ msgstr "КлаÑтер групи"
msgid "ClusterIntegration|Helm Tiller"
msgstr "Helm Tiller"
+msgid "ClusterIntegration|Helm release failed to install"
+msgstr ""
+
msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr "Helm Ñпрощує вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ñ‚Ð° ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°ÑтоÑунками Kubernetes. Tiller працює вÑередині вашого клаÑтеру Kubernetes Ñ– керує релізами charts."
-msgid "ClusterIntegration|Hide"
-msgstr "Приховати"
-
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
msgstr "Якщо ви налаштовуєте декілька клаÑтерів Ñ– викориÑтовуєте Auto DevOps, %{help_link_start}прочитайте Ð´Ð»Ñ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ це%{help_link_end}."
@@ -4942,6 +5216,12 @@ msgstr "Ðе знайдено пар ключів"
msgid "ClusterIntegration|No VPCs found"
msgstr "Ðе знайдено VPC"
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr "Ðе знайдено жодного типу інÑтанÑу"
@@ -5027,7 +5307,7 @@ msgid "ClusterIntegration|Remove integration"
msgstr "Видалити інтеграцію"
msgid "ClusterIntegration|Remove integration and resources"
-msgstr ""
+msgstr "Видалити інтеграцію та реÑурÑи"
msgid "ClusterIntegration|Remove integration and resources?"
msgstr "Видалити інтеграцію та реÑурÑи?"
@@ -5051,13 +5331,13 @@ msgid "ClusterIntegration|Request to begin uninstalling failed"
msgstr "Запит про початок Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð½Ðµ виконано"
msgid "ClusterIntegration|SIEM Hostname"
-msgstr ""
+msgstr "Ð†Ð¼â€™Ñ Ñ…Ð¾Ñта SIEM"
msgid "ClusterIntegration|SIEM Port"
-msgstr ""
+msgstr "SIEM порт"
msgid "ClusterIntegration|SIEM Protocol"
-msgstr ""
+msgstr "Протокол SIEM"
msgid "ClusterIntegration|Save changes"
msgstr "Зберегти зміни"
@@ -5072,7 +5352,7 @@ msgid "ClusterIntegration|Search VPCs"
msgstr "Пошук VPC"
msgid "ClusterIntegration|Search domains"
-msgstr ""
+msgstr "Пошук доменів"
msgid "ClusterIntegration|Search instance types"
msgstr "Пошуки типів інÑтанÑів"
@@ -5132,7 +5412,7 @@ msgid "ClusterIntegration|Select a zone to choose a network"
msgstr "Виберіть зону Ð´Ð»Ñ Ð²Ð¸Ð±Ð¾Ñ€Ñƒ мережі"
msgid "ClusterIntegration|Select existing domain or use new"
-msgstr ""
+msgstr "Виберіть Ñ–Ñнуючий домен або викориÑтайте новий"
msgid "ClusterIntegration|Select machine type"
msgstr "Вибрати тип машин"
@@ -5176,9 +5456,6 @@ msgstr "Ð’Ñтановіть Ð¿Ñ€ÐµÑ„Ñ–ÐºÑ Ð´Ð»Ñ Ð²Ð°ÑˆÐ¸Ñ… проÑторів
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr "Показати"
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr "ЩоÑÑŒ пішло не так з нашого боку."
@@ -5189,7 +5466,7 @@ msgid "ClusterIntegration|Something went wrong while installing %{title}"
msgstr "Під Ñ‡Ð°Ñ Ð²ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ %{title} ÑталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°"
msgid "ClusterIntegration|Something went wrong while trying to save your settings. Please try again."
-msgstr ""
+msgstr "ЩоÑÑŒ пішло не так під Ñ‡Ð°Ñ Ñпроби зберегти ваші налаштуваннÑ. Будь лаÑка, Ñпробуйте ще раз."
msgid "ClusterIntegration|Something went wrong while uninstalling %{title}"
msgstr "Під Ñ‡Ð°Ñ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ %{title} ÑталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°"
@@ -5257,11 +5534,14 @@ msgstr "Увімкнути/вимкнути Kubernetes-клаÑтер"
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr "Видалити %{appTitle}"
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr "Ðе вдалоÑÑ Ð¾Ð½Ð¾Ð²Ð¸Ñ‚Ð¸. Перевірте журнал та Ñпробуйте ще раз."
msgid "ClusterIntegration|Use %{query}"
-msgstr ""
+msgstr "ВикориÑтовувати %{query}"
msgid "ClusterIntegration|Uses the Cloud Run, Istio, and HTTP Load Balancing addons for this cluster."
msgstr "ВикориÑтовує Ñ€Ð¾Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð½Ñ Ð´Ð»Ñ Cloud Run, Istio та HTTP баланÑувальник Ð½Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ клаÑтеру."
@@ -5276,7 +5556,7 @@ msgid "ClusterIntegration|We could not verify that one of your projects on GCP h
msgstr "Ми не змогли перевірити, що один із ваших проектів в GCP має ввімкнений білінг. Будь лаÑка, Ñпробуйте ще раз."
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 "За допомогою підключеного до цього проєкту Kubernetes-клаÑтера, ви можете викориÑтовувати Review Apps, розгортати ваші проекти, запуÑкати конвеєри збірки тощо."
msgid "ClusterIntegration|You are about to remove your cluster integration and all GitLab-created resources associated with this cluster."
msgstr "Ви збираєтеÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ інтеграцію вашого клаÑтера та вÑÑ– реÑурÑи пов'Ñзані з цим клаÑтером, Ñкі були Ñтворені GitLab."
@@ -5287,6 +5567,9 @@ msgstr "Ви збираєтеÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ інтеграцію з ваÑ
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr "Ви збираєтеÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ %{appTitle} зі Ñвого клаÑтера."
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr "Перед вÑтановленнÑм заÑтоÑунків нижче, необхідно вÑтановити Helm Tiller"
@@ -5296,9 +5579,15 @@ msgstr "Щоб Ñтворити новий клаÑтер EKS ви повиннÑ
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr "Ви повинні мати клаÑтер з підтримкою RBAC, щоб вÑтановити Knative."
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr "Ваш обліковий Ð·Ð°Ð¿Ð¸Ñ Ð¿Ð¾Ð²Ð¸Ð½ÐµÐ½ мати %{link_to_kubernetes_engine}"
@@ -5356,6 +5645,9 @@ msgstr "Вибрати пару ключів"
msgid "ClusterIntergation|Select service role"
msgstr "Вибрати Ñлужбову роль"
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr "Код"
@@ -5369,11 +5661,14 @@ msgid "Code Quality"
msgstr "ЯкіÑÑ‚ÑŒ коду"
msgid "Code Review"
-msgstr ""
+msgstr "Перевірка коду"
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr "Потрібне Ð·Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð²Ð»Ð°Ñником коду"
@@ -5399,10 +5694,10 @@ msgid "Cohorts|Registration month"
msgstr "МіÑÑць реєÑтрації"
msgid "Cohorts|Returning users"
-msgstr ""
+msgstr "КориÑтувачі, що повернулиÑÑ"
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 ""
+msgstr "Когорти кориÑтувачів показано за оÑтанні %{months_included} міÑÑці. Лише Ñ‚Ñ– кориÑтувачі, Ñкі мали активніÑÑ‚ÑŒ відображаютьÑÑ Ð² колонці \"Ðові кориÑтувачі\"; неактивні кориÑтувачі підраховуютьÑÑ Ð¾ÐºÑ€ÐµÐ¼Ð¾."
msgid "Collapse"
msgstr "Згорнути"
@@ -5413,6 +5708,9 @@ msgstr "Згорнути ÑпиÑок затверджуючих оÑіб"
msgid "Collapse child epics"
msgstr "Згорнути дочірні епіки"
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr "Згорнути панель"
@@ -5422,6 +5720,9 @@ msgstr "Ім'Ñ Ñ…Ð¾Ñта колектора"
msgid "ComboSearch is not defined"
msgstr "ComboSearch не визначено"
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr "Команда"
@@ -5458,6 +5759,9 @@ msgstr "Ð Ð¾Ð·Ñ‚Ð°ÑˆÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð¾Ñ€Ð¼Ð¸ коментарÑ"
msgid "Comment is being updated"
msgstr "Коментар в процеÑÑ– оновленнÑ"
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr "Коментувати/відповіÑти (цитуючи виділений текÑÑ‚)"
@@ -5592,13 +5896,13 @@ msgid "Compliance framework (optional)"
msgstr ""
msgid "ComplianceFramework|GDPR"
-msgstr ""
+msgstr "GDPR"
msgid "ComplianceFramework|GDPR - General Data Protection Regulation"
msgstr ""
msgid "ComplianceFramework|HIPAA"
-msgstr ""
+msgstr "HIPAA"
msgid "ComplianceFramework|HIPAA - Health Insurance Portability and Accountability Act"
msgstr ""
@@ -5621,7 +5925,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5645,9 +5952,6 @@ msgstr "Ðалаштувати Let's Encrypt"
msgid "Configure Prometheus"
msgstr "Ðалаштувати Prometheus"
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr "Ðалаштувати безпеку %{wordBreakOpportunity}та відповідніÑÑ‚ÑŒ"
-
msgid "Configure Tracing"
msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð’Ñ–Ð´ÑтеженнÑ"
@@ -5670,7 +5974,7 @@ msgid "Configure limits on the number of inbound alerts able to be sent to a pro
msgstr "Ðалаштувати Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ ÐºÑ–Ð»ÑŒÐºÐ¾ÑÑ‚Ñ– вхідних попереджень, Ñкі можна надіÑлати у проект."
msgid "Configure paths to be protected by Rack Attack."
-msgstr ""
+msgstr "Ðалаштуйте шлÑхи Ð´Ð»Ñ Ð·Ð°Ñ…Ð¸Ñту від атак Rack Attack."
msgid "Configure repository mirroring."
msgstr "Ðалаштувати Ð²Ñ–Ð´Ð´Ð·ÐµÑ€ÐºÐ°Ð»ÐµÐ½Ð½Ñ Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ñ–Ñ—Ð²."
@@ -5681,9 +5985,6 @@ msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÑˆÐ»Ñху Ñховища."
msgid "Configure the %{link} integration."
msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ–Ð½Ñ‚ÐµÐ³Ñ€Ð°Ñ†Ñ–Ñ— з %{link}."
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr "Ðалаштувати ÑпоÑіб ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ¾Ñ€Ð¸Ñтувачем нового облікового запиÑу."
@@ -5732,17 +6033,11 @@ msgstr "Помилка з’єднаннÑ"
msgid "Connection timed out"
msgstr "Минув Ñ‡Ð°Ñ Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ"
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr "ЗвернітьÑÑ Ð´Ð¾ влаÑника групи %{namespace_name} Ð´Ð»Ñ Ð¿Ñ–Ð´Ð²Ð¸Ñ‰ÐµÐ½Ð½Ñ Ð¿Ð»Ð°Ð½Ñƒ."
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr "ЗвернітьÑÑ Ð´Ð¾ влаÑника %{link_start}%{owner_name}%{link_end} Ð´Ð»Ñ Ð¿Ñ–Ð´Ð²Ð¸Ñ‰ÐµÐ½Ð½Ñ Ð¿Ð»Ð°Ð½Ñƒ."
-
msgid "Contact sales to upgrade"
msgstr "ЗвернітьÑÑ Ð´Ð¾ відділу продажів Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ñƒ на вищий тарифний план"
-msgid "Contact your Administrator to upgrade your license."
-msgstr "ЗвернітьÑÑ Ð´Ð¾ вашого адмініÑтратора Ð´Ð»Ñ Ð¿Ñ–Ð´Ð²Ð¸Ñ‰ÐµÐ½Ð½Ñ Ð»Ñ–Ñ†ÐµÐ½Ð·Ñ–Ñ—."
+msgid "Contact support"
+msgstr ""
msgid "Container Registry"
msgstr "РеєÑÑ‚Ñ€ Контейнерів"
@@ -5754,13 +6049,13 @@ msgid "Container Scanning"
msgstr "Ð¡ÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ¾Ð½Ñ‚ÐµÐ¹Ð½ÐµÑ€Ð°"
msgid "Container does not exist"
-msgstr ""
+msgstr "Контейнер не Ñ–Ñнує"
msgid "Container registry images"
msgstr "Образи в реєÑтрі контейнерів"
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 "РеєÑÑ‚Ñ€ контейнерів не включений у даний інÑÑ‚Ð°Ð½Ñ GitLab. ПопроÑÑ–Ñ‚ÑŒ адмініÑтратора включити його Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, щоб Auto DevOps працював."
msgid "Container repositories sync capacity"
msgstr ""
@@ -5768,16 +6063,33 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "ContainerRegistry|%{imageName} tags"
-msgstr ""
+msgstr "%{imageName} тегів"
msgid "ContainerRegistry|%{title} was successfully scheduled for deletion"
msgstr ""
msgid "ContainerRegistry|Automatically remove extra images that aren't designed to be kept."
-msgstr ""
+msgstr "Ðвтоматично видалÑти зайві образи, не призначені Ð´Ð»Ñ Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ."
msgid "ContainerRegistry|Build an image"
+msgstr "Створити образ"
+
+msgid "ContainerRegistry|CLI Commands"
msgstr ""
msgid "ContainerRegistry|Compressed Size"
@@ -5804,19 +6116,28 @@ msgstr "Помилка Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Docker"
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
+msgstr "Термін дії:"
+
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr "Політика щодо терміну дії уÑпішно збережена."
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr "Політика завершеннÑ:"
msgid "ContainerRegistry|Expiration schedule:"
+msgstr "Розклад завершеннÑ:"
+
+msgid "ContainerRegistry|Filter by name"
msgstr ""
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
@@ -5825,9 +6146,12 @@ msgstr "Якщо ви ще не виконали вхід вам необхідÐ
msgid "ContainerRegistry|Image ID"
msgstr "Ідентифікатор образу"
-msgid "ContainerRegistry|Keep and protect the images that matter most."
+msgid "ContainerRegistry|Image Repositories"
msgstr ""
+msgid "ContainerRegistry|Keep and protect the images that matter most."
+msgstr "Зберігати Ñ– захищати образи, Ñкі мають найбільше значеннÑ."
+
msgid "ContainerRegistry|Last Updated"
msgstr "ВоÑтаннє оновлено"
@@ -5835,28 +6159,25 @@ msgid "ContainerRegistry|Login"
msgstr "Увійти"
msgid "ContainerRegistry|Missing or insufficient permission, delete button disabled"
-msgstr ""
+msgstr "Ðе виÑтачає прав доÑтупу, кнопка Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð²Ð¸Ð¼ÐºÐ½ÐµÐ½Ð°"
msgid "ContainerRegistry|Number of tags to retain:"
-msgstr ""
+msgstr "КількіÑÑ‚ÑŒ тегів Ð´Ð»Ñ Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ:"
msgid "ContainerRegistry|Please contact your administrator."
-msgstr ""
+msgstr "Будь лаÑка, зв'ÑжітьÑÑ Ð· адмініÑтратором."
msgid "ContainerRegistry|Push an image"
-msgstr ""
-
-msgid "ContainerRegistry|Quick Start"
-msgstr "Швидкий Ñтарт"
+msgstr "Відправити образ"
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
-msgstr ""
+msgstr "ПідтримуютьÑÑ Ñ€ÐµÐ³ÑƒÐ»Ñрні вирази, такі Ñк %{codeStart}.*-test%{codeEnd} або %{codeStart}dev-.*%{codeEnd}. Щоб вибрати вÑÑ– теги, викориÑтайте %{codeStart}.*%{codeEnd}"
msgid "ContainerRegistry|Remember to run %{docLinkStart}garbage collection%{docLinkEnd} to remove the stale data from storage."
-msgstr ""
+msgstr "Ðе забудьте запуÑтити %{docLinkStart}збірку ÑміттÑ%{docLinkEnd}, щоб видалити заÑтарілі дані зі Ñховища."
msgid "ContainerRegistry|Remove repository"
msgstr "Видалити репозиторій"
@@ -5871,17 +6192,14 @@ msgstr[1] "Видалити теги"
msgstr[2] "Видалити тегів"
msgstr[3] "Видалити тегів"
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
msgid "ContainerRegistry|Something went wrong while fetching the repository list."
-msgstr ""
+msgstr "ЩоÑÑŒ пішло не так при отриманні ÑпиÑку репозиторіїв."
msgid "ContainerRegistry|Something went wrong while fetching the tags list."
-msgstr ""
+msgstr "ЩоÑÑŒ пішло не так при отриманні ÑпиÑку тегів."
msgid "ContainerRegistry|Something went wrong while marking the tag for deletion."
msgstr ""
@@ -5895,6 +6213,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr "Тег"
@@ -5922,12 +6243,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr "ОÑтанній тег Ñкий відноÑивÑÑ Ð´Ð¾ цього образу нещодавно було видалено. Цей порожній образ та вÑÑ– пов’Ñзані дані будуть автоматично видалені під Ñ‡Ð°Ñ Ñ€ÐµÐ³ÑƒÐ»Ñрного \"збору ÑміттÑ\". Якщо у Ð²Ð°Ñ Ñ” питаннÑ, звернітьÑÑ Ð´Ð¾ Ñвого адмініÑтратора."
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5946,8 +6261,11 @@ msgstr "Образ не має активних тегів"
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
-msgstr "У Ð½Ð°Ñ Ð²Ð¸Ð½Ð¸ÐºÐ»Ð¸ проблеми при з’єднанні з Docker, що може бути Ñпричинено помилкою пов’Ñзаною із іменем проекту або шлÑхом. %{docLinkStart}ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
msgstr "За допомогою РеєÑтру контейнерів, кожен проект може мати влаÑний проÑÑ‚Ñ–Ñ€ Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð¾Ð±Ñ€Ð°Ð·Ñ–Ð² Docker. %{docLinkStart}ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ%{docLinkEnd}"
@@ -5955,17 +6273,17 @@ msgstr "За допомогою РеєÑтру контейнерів, кожеÐ
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 "За допомогою РеєÑтру Контейнерів кожен проект може мати влаÑний проÑÑ‚Ñ–Ñ€ Ð´Ð»Ñ Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Docker-образів. РозміÑÑ‚Ñ–Ñ‚ÑŒ хоча б один Docker-образ у ÑкомуÑÑŒ із проектів групи щоб його тут побачити. %{docLinkStart}Детальніше%{docLinkEnd}"
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
-msgstr "За допомогою РеєÑтру контейнерів інтегрованому у Gitlab, кожен проект може мати влаÑний проÑÑ‚Ñ–Ñ€ Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð¾Ð±Ñ€Ð°Ð·Ñ–Ð² Docker. %{docLinkStart}ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
-msgstr ""
+msgstr "Ви збираєтеÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ %{item} тегів. Ви впевнені?"
msgid "ContainerRegistry|You are about to remove %{item}. Are you sure?"
-msgstr ""
+msgstr "Ви збираєтеÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ %{item}. Ви впевнені?"
msgid "ContainerRegistry|You are about to remove repository %{title}. Once you confirm, this repository will be permanently deleted."
-msgstr ""
+msgstr "Ви збираєтеÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ репозиторій %{title}. ПіÑÐ»Ñ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ñ†ÐµÐ¹ репозиторій буде оÑтаточно видалено."
msgid "ContainerRegistry|You can add an image to this registry with the following commands:"
msgstr "Ви можете додати образ до цього реєÑтру за допомогою наÑтупних команд:"
@@ -5994,10 +6312,10 @@ msgstr "ВнеÑок"
msgid "Contribution Analytics"
msgstr "Ðналітика внеÑків"
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
-msgstr ""
-
msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgstr "<strong>%{created_count}</strong> Ñтворено, <strong>%{closed_count}</strong> закрито."
+
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -6022,13 +6340,13 @@ msgid "ContributionAnalytics|Merge Requests"
msgstr "Запити на злиттÑ"
msgid "ContributionAnalytics|No issues for the selected time period."
-msgstr ""
+msgstr "Ðемає задач за обраний період."
msgid "ContributionAnalytics|No merge requests for the selected time period."
-msgstr ""
+msgstr "Ðемає запитів на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð·Ð° обраний період."
msgid "ContributionAnalytics|No pushes for the selected time period."
-msgstr ""
+msgstr "Ðемає відправлень за обраний період."
msgid "Contributions for <strong>%{calendar_date}</strong>"
msgstr "ВнеÑки за <strong>%{calendar_date}</strong>"
@@ -6046,7 +6364,7 @@ msgid "Control the display of third party offers."
msgstr "Керувати відображеннÑм Ñторонніх пропозицій."
msgid "Control the maximum concurrency of LFS/attachment backfill for this secondary node"
-msgstr ""
+msgstr "Керувати макÑимальною кількіÑÑ‚ÑŽ потоків фонового Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ LFS/вкладень Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ вторинного вузла."
msgid "Control the maximum concurrency of container repository operations for this Geo node"
msgstr ""
@@ -6084,6 +6402,9 @@ msgstr "Скопіювати URL Ð´Ð»Ñ ÐºÐ»Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ñ‡ÐµÑ€ÐµÐ· %{protoc
msgid "Copy %{proxy_url}"
msgstr "Скопіювати %{proxy_url}"
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr "Скопіювати ідентифікатор облікового запиÑу в буфер обміну"
@@ -6129,9 +6450,6 @@ msgstr "Скопіювати вміÑÑ‚ файлу"
msgid "Copy file path"
msgstr "Скопіювати шлÑÑ… до файлу"
-msgid "Copy impersonation token"
-msgstr "Скопіювати токен імітуваннÑ"
-
msgid "Copy key"
msgstr "Копіювати ключ"
@@ -6145,10 +6463,7 @@ msgid "Copy link"
msgstr "Скопіювати поÑиланнÑ"
msgid "Copy link to chart"
-msgstr ""
-
-msgid "Copy personal access token"
-msgstr "Скопіювати перÑональний токен доÑтупу"
+msgstr "Копіювати поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° графік"
msgid "Copy reference"
msgstr "Скопіювати поÑиланнÑ"
@@ -6178,7 +6493,7 @@ msgid "Could not connect to FogBugz, check your URL"
msgstr "Ðе можливо зв’ÑзатиÑÑ Ñ–Ð· FogBugz, перевірте URL-адреÑу"
msgid "Could not connect to Sentry. Refresh the page to try again."
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡Ð¸Ñ‚Ð¸ÑÑ Ð´Ð¾ Sentry. Оновіть Ñторінку, щоб повторити Ñпробу."
msgid "Could not connect to Web IDE file mirror service."
msgstr "Ðе вдалоÑÑ Ð·â€™Ñ”Ð´Ð½Ð°Ñ‚Ð¸ÑÑ Ñ–Ð· ÑервіÑом Ð²Ñ–Ð´Ð´Ð·ÐµÑ€ÐºÐ°Ð»ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² Веб-IDE."
@@ -6187,7 +6502,7 @@ msgid "Could not create Wiki Repository at this time. Please try again later."
msgstr "Ðаразі не вдалоÑÑ Ñтворити репозиторій вікі. Спробуйте, будь лаÑка, знову пізніше."
msgid "Could not create environment"
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ñтворити Ñередовище"
msgid "Could not create group"
msgstr "Ðе вдалоÑÑ Ñтворити групу"
@@ -6202,7 +6517,7 @@ msgid "Could not delete chat nickname %{chat_name}."
msgstr "Ðе вдалоÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ пÑевдонім Ð´Ð»Ñ Ñ‡Ð°Ñ‚Ñƒ %{chat_name}."
msgid "Could not find design."
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ дизайн."
msgid "Could not remove the trigger."
msgstr "Ðе вдалоÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ тригер."
@@ -6217,10 +6532,10 @@ msgid "Could not revoke personal access token %{personal_access_token_name}."
msgstr "Ðеможливо відкликати перÑональний токен доÑтупу %{personal_access_token_name}."
msgid "Could not revoke project access token %{project_access_token_name}."
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÐ»Ð¸ÐºÐ°Ñ‚Ð¸ токен доÑтупу до проєкту %{project_access_token_name}."
msgid "Could not save group ID"
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ ID групи."
msgid "Could not save project ID"
msgstr "Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ ідентифікатор проекту"
@@ -6229,10 +6544,10 @@ msgid "Could not save prometheus manual configuration"
msgstr "Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ ручні Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Prometheus"
msgid "Could not update the LDAP settings"
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ð¾Ð½Ð¾Ð²Ð¸Ñ‚Ð¸ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ LDAP."
msgid "Could not upload your designs as one or more files uploaded are not supported."
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ ваші дизайни, оÑкільки один або кілька файлів, що завантажуютьÑÑ, не підтримуютьÑÑ."
msgid "Country"
msgstr "Країна"
@@ -6244,10 +6559,10 @@ msgid "Create"
msgstr "Створити"
msgid "Create %{environment}"
-msgstr ""
+msgstr "Створити %{environment}"
-msgid "Create %{type} token"
-msgstr "Створити %{type} токен"
+msgid "Create %{type}"
+msgstr ""
msgid "Create New Directory"
msgstr "Створити новий каталог"
@@ -6264,9 +6579,6 @@ msgstr "Спочатку Ñтворіть обліковий Ð·Ð°Ð¿Ð¸Ñ GitLab,
msgid "Create a Mattermost team for this group"
msgstr "Створити команду в Mattermost Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— групи"
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr "Створити локальний прокÑÑ– залежноÑтей Ð´Ð»Ñ Ñ‡Ð°Ñто викориÑтовуваних образів. %{link_start}ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ%{link_end} про прокÑÑ– залежноÑтей."
@@ -6277,7 +6589,7 @@ msgid "Create a new branch"
msgstr "Створити нову гілку"
msgid "Create a new deploy key for this project"
-msgstr ""
+msgstr "Створити новий ключ Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ проєкту"
msgid "Create a new file as there are no files yet. Afterwards, you'll be able to commit your changes."
msgstr "Створіть новий файл, тому що наразі немає жодного файлу. Пізніше ви зможете закомітити ваші зміни."
@@ -6285,9 +6597,6 @@ msgstr "Створіть новий файл, тому що наразі немÐ
msgid "Create a new issue"
msgstr "Створити нову задачу"
-msgid "Create a new issue and add it to the epic."
-msgstr "Створити нову задачу і додати її до епіку."
-
msgid "Create a new repository"
msgstr "Створити новий репозиторій"
@@ -6297,9 +6606,6 @@ msgstr "Створіть токен доÑтупу Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ аккаÑ
msgid "Create an account using:"
msgstr "Створити обліковий Ð·Ð°Ð¿Ð¸Ñ Ð·Ð° допомогою:"
-msgid "Create an issue"
-msgstr "Створити задачу"
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr "Створити задачу. Задачі будуть Ñтворені Ð´Ð»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ попередженнÑ."
@@ -6342,6 +6648,9 @@ msgstr "Створити мітку групи"
msgid "Create issue"
msgstr "Створити задачу"
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr "Створити ÑпиÑок на оÑнові міток. Ð’ ньому будуть задачі з такими мітками."
@@ -6354,6 +6663,9 @@ msgstr "Створити запит на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ñ‚Ð° гілку"
msgid "Create milestone"
msgstr "Створити етап"
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr "Створіть нову дошку"
@@ -6382,17 +6694,23 @@ msgid "Create project label"
msgstr "Створити мітку проекту"
msgid "Create requirement"
-msgstr ""
+msgstr "Створити вимогу"
msgid "Create snippet"
-msgstr ""
+msgstr "Створити Ñніпет"
msgid "Create wildcard: %{searchTerm}"
-msgstr ""
+msgstr "Створити шаблон: %{searchTerm}"
msgid "Create your first page"
msgstr "Створити вашу першу Ñторінку"
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr "У Ð²Ð°Ñ Ð½ÐµÐ¼Ð°Ñ” дозволу Ñтворювати підгрупу в цій групі."
@@ -6409,7 +6727,7 @@ msgid "Created"
msgstr "Створено"
msgid "Created %{timestamp}"
-msgstr ""
+msgstr "Створено %{timestamp}"
msgid "Created At"
msgstr "Створено в"
@@ -6426,6 +6744,9 @@ msgstr "Створено гілку \"%{branch_name}\" та запит на зл
msgid "Created by me"
msgstr "Створено мною"
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr "Створено задачу %{issueLink}"
@@ -6463,10 +6784,10 @@ msgid "Credentials"
msgstr "Облікові дані"
msgid "CredentialsInventory|No credentials found"
-msgstr ""
+msgstr "Облікові дані не знайдено"
msgid "CredentialsInventory|Personal Access Tokens"
-msgstr ""
+msgstr "ОÑобиÑÑ‚Ñ– токени доÑтупу"
msgid "CredentialsInventory|SSH Keys"
msgstr ""
@@ -6477,9 +6798,6 @@ msgstr "ПриÑутні критичні вразливоÑÑ‚Ñ–"
msgid "Cron Timezone"
msgstr "ЧаÑовий поÑÑ Cron"
-msgid "Cron syntax"
-msgstr "СинтакÑÐ¸Ñ Cron"
-
msgid "Crossplane"
msgstr "Crossplane"
@@ -6496,7 +6814,7 @@ msgid "Current node"
msgstr "Поточний вузол"
msgid "Current node must be the primary node or you will be locking yourself out"
-msgstr ""
+msgstr "Поточний вузол повинен бути оÑновним, інакше ви будете заблоковані."
msgid "Current password"
msgstr "Поточний пароль"
@@ -6516,6 +6834,9 @@ msgstr "ÐалаштуваннÑ"
msgid "CurrentUser|Start a Gold trial"
msgstr "Розпочати пробну верÑÑ–ÑŽ Gold"
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr "КориÑтувацький шлÑÑ… до конфігурації CI"
@@ -6540,6 +6861,9 @@ msgstr "ВлаÑні шаблони проектів не налаштовані
msgid "Custom range"
msgstr "КориÑтувацький діапазон"
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr "Додати Ñтадію"
@@ -6588,6 +6912,9 @@ msgstr "Мітка завершальної події"
msgid "CustomCycleAnalytics|Update stage"
msgstr "Оновити Ñтадію"
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ¾Ð»ÑŒÐ¾Ñ€Ñ–Ð²"
@@ -6612,6 +6939,9 @@ msgstr "Ðалаштуйте конфігурацію конвеєра, пере
msgid "Customize your pipeline configuration."
msgstr "Ðалаштувати конфігурацію конвеєра."
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr "Задачу закрито"
@@ -6649,10 +6979,10 @@ msgid "CycleAnalyticsEvent|Merge request first deployed to production"
msgstr "Перший запит на злиттÑ, розгорутий на production"
msgid "CycleAnalyticsEvent|Merge request label was added"
-msgstr ""
+msgstr "Мітка запиту на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð±ÑƒÐ»Ð° додана"
msgid "CycleAnalyticsEvent|Merge request label was removed"
-msgstr ""
+msgstr "Мітка запиту на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð±ÑƒÐ»Ð° видалена"
msgid "CycleAnalyticsEvent|Merge request last build finish time"
msgstr "ОÑтанній Ñ‡Ð°Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ð·Ð±Ñ–Ñ€ÐºÐ¸ Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñ‚Ñƒ на злиттÑ"
@@ -6694,7 +7024,7 @@ msgid "CycleAnalyticsStage|should be under a group"
msgstr "має бути в групі"
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
-msgstr ""
+msgstr "%{selectedLabelsCount} вибрано (%{maxLabels} max)"
msgid "CycleAnalytics|%{stageCount} stages selected"
msgstr "Вибрано %{stageCount} Ñтадій"
@@ -6709,23 +7039,23 @@ msgid "CycleAnalytics|Days to completion"
msgstr "Днів до завершеннÑ"
msgid "CycleAnalytics|Display chart filters"
-msgstr ""
+msgstr "Ð’Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ñ„Ñ–Ð»ÑŒÑ‚Ñ€Ñ–Ð² графіків"
msgid "CycleAnalytics|No stages selected"
msgstr "Жодної Ñтадії не вибрано"
msgid "CycleAnalytics|Number of tasks"
-msgstr ""
+msgstr "КількіÑÑ‚ÑŒ задач"
msgid "CycleAnalytics|Only %{maxLabels} labels can be selected at this time"
-msgstr ""
+msgstr "Ðа даний момент лише %{maxLabels} міток може бути вибрано"
msgid "CycleAnalytics|Project selected"
msgid_plural "CycleAnalytics|%d projects selected"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "Проєкт вибрано"
+msgstr[1] "%d проєкти вибрано"
+msgstr[2] "%d проєктів вибрано"
+msgstr[3] "%d проєктів вибрано"
msgid "CycleAnalytics|Select labels"
msgstr "Вибрати мітки"
@@ -6734,22 +7064,22 @@ msgid "CycleAnalytics|Show"
msgstr "Показати"
msgid "CycleAnalytics|Showing %{subjectFilterText} and %{selectedLabelsCount} labels"
-msgstr ""
+msgstr "Показано %{subjectFilterText} і %{selectedLabelsCount} міток"
msgid "CycleAnalytics|Showing data for group '%{groupName}' and %{selectedProjectCount} projects from %{startDate} to %{endDate}"
-msgstr ""
+msgstr "Показано дані по групі '%{groupName}' і %{selectedProjectCount} проєктам від %{startDate} до %{endDate}"
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{startDate} to %{endDate}"
-msgstr ""
+msgstr "Показано дані по групі '%{groupName}' від %{startDate} до %{endDate}"
msgid "CycleAnalytics|Stages"
msgstr "Стадії"
msgid "CycleAnalytics|Tasks by type"
-msgstr ""
+msgstr "Ð—Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð·Ð° типом"
msgid "CycleAnalytics|The given date range is larger than 180 days"
-msgstr ""
+msgstr "Даний діапазон чаÑу перевищує 180 днів"
msgid "CycleAnalytics|Total days to completion"
msgstr "Загальна кількіÑÑ‚ÑŒ днів до завершеннÑ"
@@ -6770,7 +7100,7 @@ msgid "CycleAnalytics|stage dropdown"
msgstr "Випадаючий ÑпиÑок Ñтадій"
msgid "DAG"
-msgstr ""
+msgstr "DAG"
msgid "DNS"
msgstr "DNS"
@@ -6809,7 +7139,7 @@ msgid "Date picker"
msgstr "Вибір дати"
msgid "Date range cannot exceed %{maxDateRange} days."
-msgstr ""
+msgstr "Діапазон дат не може перевищувати %{maxDateRange} днів.\n"
msgid "Day of month"
msgstr "День міÑÑцÑ"
@@ -6865,6 +7195,9 @@ msgstr "Гілка за замовчуваннÑм Ñ– захищені гілкÐ
msgid "Default classification label"
msgstr "Мітка клаÑифікації за замовчуваннÑм"
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6887,7 +7220,7 @@ msgid "Default project deletion protection"
msgstr "ЗахиÑÑ‚ від Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñƒ за замовчуваннÑм"
msgid "Default projects limit"
-msgstr ""
+msgstr "Ліміт проєктів за замовчуваннÑм"
msgid "Default stages"
msgstr ""
@@ -6901,6 +7234,9 @@ msgstr "По замовчуванню: викориÑтовувати ідент
msgid "Define a custom pattern with cron syntax"
msgstr "Визначте влаÑний шаблон за допомогою ÑинтакÑиÑу cron"
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr "Визначте Ñередовища на Ñтадії Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ñƒ <code>.gitlab-ci.yml</code> щоб відÑтежувати Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ñ‚ÑƒÑ‚."
@@ -6941,6 +7277,12 @@ msgid "Delete comment"
msgstr "Видалити коментар"
msgid "Delete domain"
+msgstr "Видалити домен"
+
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
msgstr ""
msgid "Delete license"
@@ -6971,13 +7313,13 @@ msgid "Delete this attachment"
msgstr "Видалити це вкладеннÑ"
msgid "Delete variable"
-msgstr ""
+msgstr "Видалити змінну"
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr "Помилка при видаленні репозиторію проекту. Будь лаÑка, Ñпробуйте знову, або зв'ÑжітьÑÑ Ñ–Ð· адмініÑтратором."
msgid "DeleteProject|Failed to remove project snippets. Please try again or contact administrator."
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ Ñніпети проєкту. Будь лаÑка, Ñпробуйте ще раз або зв'ÑжітьÑÑ Ð· адмініÑтратором."
msgid "DeleteProject|Failed to remove some tags in project container registry. Please try again or contact administrator."
msgstr "Помилка при видаленні деÑких тегів в реєÑтрі контейнерів проекту. Будь лаÑка, Ñпробуйте знову, або зв'ÑжітьÑÑ Ñ–Ð· адмініÑтратором."
@@ -7001,7 +7343,7 @@ msgid "Deleted in this version"
msgstr "Видалено в цій верÑÑ–Ñ—"
msgid "Deleting"
-msgstr ""
+msgstr "ВидаленнÑ"
msgid "Deleting the license failed."
msgstr "Ðе вдалоÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ ліцензію."
@@ -7034,13 +7376,6 @@ msgstr[1] "%d додаткові вразливоÑÑ‚Ñ– не відображаÑ
msgstr[2] "%d додаткових вразливоÑтей не відображаютьÑÑ"
msgstr[3] "%d додаткових вразливоÑтей не відображаютьÑÑ"
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] "%d вразливіÑÑ‚ÑŒ"
-msgstr[1] "%d вразливоÑÑ‚Ñ–"
-msgstr[2] "%d вразливоÑтей"
-msgstr[3] "%d вразливоÑтей"
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] "виÑвлено %d вразливіÑÑ‚ÑŒ"
@@ -7078,12 +7413,6 @@ msgstr "РозташуваннÑ"
msgid "Dependencies|Packager"
msgstr "Пакувальник"
-msgid "Dependencies|Safe"
-msgstr "Безпечно"
-
-msgid "Dependencies|Status"
-msgstr "СтатуÑ"
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr "Ð—Ð°Ð²Ð´Ð°Ð½Ð½Ñ %{codeStartTag}dependency_scanning%{codeEndTag} закінчилоÑÑ Ð½ÐµÑƒÑпішно Ñ– неможе згенерувати ÑпиÑок. Будь лаÑка, переконайтеÑÑ, що Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð²Ð¸ÐºÐ¾Ñ€ÑƒÑ”Ñ‚ÑŒÑÑ Ð½Ð°Ð»ÐµÐ¶Ð½Ð¸Ð¼ чином Ñ– перезапуÑÑ‚Ñ–Ñ‚ÑŒ конвеєр."
@@ -7093,9 +7422,6 @@ msgstr "Увімкнути/вимкнути ÑпиÑок вразливоÑтеÐ
msgid "Dependencies|Unsupported file(s) detected"
msgstr "ВиÑвлено непідтимувані файли"
-msgid "Dependencies|Version"
-msgstr "ВерÑÑ–Ñ"
-
msgid "Dependencies|Vulnerable components"
msgstr "Вразливі компоненти"
@@ -7103,7 +7429,7 @@ msgid "Dependency List"
msgstr "СпиÑок залежноÑтей"
msgid "Dependency List has no entries"
-msgstr ""
+msgstr "У ÑпиÑку залежноÑтей немає запиÑів"
msgid "Dependency Proxy"
msgstr "ПрокÑÑ– залежноÑтей"
@@ -7216,12 +7542,18 @@ msgstr "Ðктивні токени Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ (%{active_tokens})"
msgid "DeployTokens|Add a deploy token"
msgstr "Додати токен розгортаннÑ"
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr "ДозволÑÑ” доÑтуп лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð´Ð¾ реєÑтру образів"
msgid "DeployTokens|Allows read-only access to the repository"
msgstr "ДозволÑÑ” доÑтуп лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð´Ð¾ репозиторіÑ"
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7243,13 +7575,13 @@ msgstr "Стандартним форматом є \"gitlab+deploy-token-{n}\".
msgid "DeployTokens|Deploy Tokens"
msgstr "Токени РозгортаннÑ"
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr "Термін дії"
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7307,7 +7639,7 @@ msgid "Deploying to"
msgstr "Ð Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ð´Ð¾"
msgid "Deployment Frequency"
-msgstr ""
+msgstr "ЧаÑтота РозгортаннÑ"
msgid "Deployment|API"
msgstr "API"
@@ -7340,7 +7672,7 @@ msgid "Describe the goal of the changes and what reviewers should be aware of."
msgstr ""
msgid "Describe the requirement here"
-msgstr ""
+msgstr "Опишіть вимогу тут"
msgid "Description"
msgstr "ОпиÑ"
@@ -7369,21 +7701,36 @@ msgstr "%{current_design} з %{designs_count}"
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
-msgstr "Додати дизайни"
-
msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr "Ð”Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ Ð´Ð¸Ð·Ð°Ð¹Ð½Ñƒ із тим же ім’Ñм файлу замінює цей файл новою верÑією."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
+msgstr ""
+
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr "Ви впевнені, що хочете видалити вибрані дизайни?"
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr "СкаÑувати Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ñ"
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7393,6 +7740,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr "Видалити"
@@ -7420,12 +7770,27 @@ msgstr "Перейти до наÑтупного дизайну"
msgid "DesignManagement|Go to previous design"
msgstr "Перейти до попереднього дизайну"
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr "Залишити коментар"
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr "Бажана верÑÑ–Ñ Ð´Ð¸Ð·Ð°Ð¹Ð½Ñƒ не Ñ–Ñнує. ЗаміÑÑ‚ÑŒ неї відображаєтьÑÑ Ð¾ÑтаннÑ"
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr "Виділити уÑÑ–"
@@ -7435,6 +7800,12 @@ msgstr "МакÑимальна кількіÑÑ‚ÑŒ дизайнів, Ñкі моÐ
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7447,6 +7818,9 @@ msgstr "Дизайни"
msgid "Destroy"
msgstr "Знищити"
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr "Деталі"
@@ -7562,7 +7936,7 @@ msgid "Discover|See the other features of the %{linkStart}gold plan%{linkEnd}"
msgstr ""
msgid "Discover|Start a free trial"
-msgstr ""
+msgstr "Розпочати безкоштовну пробну верÑÑ–ÑŽ"
msgid "Discover|Upgrade now"
msgstr "Оновити зараз"
@@ -7605,7 +7979,7 @@ msgid "Dismiss Merge Request promotion"
msgstr "Видалити Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ запит на злиттÑ"
msgid "Dismiss Selected"
-msgstr ""
+msgstr "Відхилити вибране"
msgid "Dismiss Value Stream Analytics introduction box"
msgstr ""
@@ -7665,17 +8039,20 @@ msgid "Domain verification is an essential security measure for public GitLab si
msgstr "ÐŸÑ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð´Ð¾Ð¼ÐµÐ½Ñƒ Ñ” важливою мірою безпеки Ð´Ð»Ñ Ð¿ÑƒÐ±Ð»Ñ–Ñ‡Ð½Ð¸Ñ… Ñайтів GitLab. КориÑтувачі повинні показати, що вони керують доменом, перш ніж його буде увімкнено"
msgid "Domain was successfully created."
-msgstr ""
+msgstr "Домен уÑпішно Ñтворено."
msgid "Domain was successfully deleted."
-msgstr ""
+msgstr "Домен уÑпішно видалено."
msgid "Domain was successfully updated."
-msgstr ""
+msgstr "Домен уÑпішно оновлено. "
msgid "Don't have an account yet?"
msgstr "Ще не зареєÑтровані?"
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr "Ðе вÑтавлÑйте приватну чаÑтину GPG ключа. Ð’Ñтавте публічну чаÑтину, Ñка починаєтьÑÑ Ñ–Ð· \"-----BEGIN PGP PUBLIC KEY BLOCK-----\"."
@@ -7724,6 +8101,9 @@ msgstr "Завантажити зображеннÑ"
msgid "Download license"
msgstr "Завантажити ліцензію"
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr "Завантажити вихідний код"
@@ -7748,6 +8128,9 @@ msgstr "Дизлайки"
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr "Запланована дата завершеннÑ"
@@ -7860,7 +8243,7 @@ msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr "Редагувати ваш оÑтанній коментар в обговоренні (в порожньому текÑтовому полі)"
msgid "Edited %{timeago}"
-msgstr ""
+msgstr "Відредаговано %{timeago}"
msgid "Editing"
msgstr "РедагуваннÑ"
@@ -7895,6 +8278,9 @@ msgstr "Електронна пошта"
msgid "Email address"
msgstr "ÐдреÑа електронної пошти"
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7910,6 +8296,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr "ÐадіÑлати ÑÑ‚Ð°Ñ‚ÑƒÑ ÐºÐ¾Ð½Ð²ÐµÑ”Ñ€Ð° по електронній пошті ÑпиÑку отримувачів."
@@ -8003,6 +8392,9 @@ msgstr "Увімкнути автентифікацію SAML Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— гÑ
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr "Увімкнути доÑтуп до Grafana"
@@ -8012,9 +8404,6 @@ msgstr "Увімкнути доÑтуп до панелі продуктивно
msgid "Enable and configure Grafana."
msgstr "Включити і налаштувати Grafana."
-msgid "Enable and configure InfluxDB metrics."
-msgstr "Включити і налаштувати метрики InfluxDB."
-
msgid "Enable and configure Prometheus metrics."
msgstr "Включити і налаштувати метрики Prometheus."
@@ -8025,7 +8414,7 @@ msgid "Enable container expiration and retention policies for projects created e
msgstr ""
msgid "Enable email restrictions for sign ups"
-msgstr ""
+msgstr "Увімкнути Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ñ€ÐµÑ”Ñтрації за електронною поштою."
msgid "Enable error tracking"
msgstr "Увімкнути відÑÑ‚ÐµÐ¶ÐµÐ½Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº"
@@ -8042,9 +8431,12 @@ msgstr "Увімкнути групові Runner'и"
msgid "Enable header and footer in emails"
msgstr "Увімкнути заголовок та футер в електронних лиÑтах"
-msgid "Enable maintenance mode"
+msgid "Enable integration"
msgstr ""
+msgid "Enable maintenance mode"
+msgstr "Увімкнути режим обÑлуговуваннÑ"
+
msgid "Enable mirror configuration"
msgstr "Увімкнути Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ñ–Ð´Ð´Ð·ÐµÑ€ÐºÐ°Ð»ÐµÐ½Ð½Ñ"
@@ -8052,7 +8444,7 @@ msgid "Enable or disable Seat Link."
msgstr ""
msgid "Enable or disable keyboard shortcuts"
-msgstr ""
+msgstr "Увімкнути або вимкнути гарÑчі клавіші"
msgid "Enable or disable the Pseudonymizer data collection."
msgstr "Увімкнути чи вимкнути збір даних Ð´Ð»Ñ Pseudonymizer."
@@ -8097,10 +8489,10 @@ msgid "EnableReviewApp|%{stepStart}Step 3%{stepEnd}. Add it to the project %{lin
msgstr ""
msgid "EnableReviewApp|Close"
-msgstr ""
+msgstr "Закрити"
msgid "EnableReviewApp|Copy snippet text"
-msgstr ""
+msgstr "Скопіювати текÑÑ‚ Ñніпета"
msgid "Enabled"
msgstr "Увімкнено"
@@ -8145,7 +8537,7 @@ msgid "Enter a number"
msgstr "Введіть номер"
msgid "Enter a whole number between 0 and 100"
-msgstr ""
+msgstr "Введіть ціле чиÑло від 0 до 100"
msgid "Enter at least three characters to search"
msgstr "Введіть щонайменше 3 Ñимволи Ð´Ð»Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ"
@@ -8165,14 +8557,17 @@ msgstr "Введіть URL-адреÑу вашого Ñервера Phabricator
msgid "Enter merge request URLs"
msgstr "Введіть URL-адреÑи запиту на злиттÑ"
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
msgid "Enter number of issues"
-msgstr ""
+msgstr "Введіть кількіÑÑ‚ÑŒ задач"
msgid "Enter one or more user ID separated by commas"
-msgstr ""
+msgstr "Введіть одного або декілька ID кориÑтувачів, відокремених комами."
msgid "Enter the code from the two-factor app on your mobile device. If you've lost your device, you may enter one of your recovery codes."
msgstr ""
@@ -8189,12 +8584,12 @@ msgstr "Введіть Ð¾Ð¿Ð¸Ñ Ð·Ð°Ð¿Ð¸Ñ‚Ñƒ на злиттÑ"
msgid "Enter the merge request title"
msgstr "Введіть назву запиту на злиттÑ"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
+msgstr ""
+
msgid "Enter your password to approve"
msgstr "Введіть пароль Ð´Ð»Ñ Ð·Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ"
-msgid "Enter zen mode"
-msgstr "Увійти у режим Дзен"
-
msgid "Environment"
msgstr "Середовище"
@@ -8249,8 +8644,8 @@ msgstr "ЗавданнÑ: %{job}"
msgid "EnvironmentsDashboard|More actions"
msgstr "Додаткові дії"
-msgid "EnvironmentsDashboard|Read more."
-msgstr "Читати більше."
+msgid "EnvironmentsDashboard|More information"
+msgstr ""
msgid "EnvironmentsDashboard|Remove"
msgstr "Видалити"
@@ -8340,7 +8735,7 @@ msgid "Environments|Learn more about stopping environments"
msgstr "ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про зупинку Ñередовищ"
msgid "Environments|Logs from %{start} to %{end}."
-msgstr ""
+msgstr "Логи від %{start} до %{end}."
msgid "Environments|New environment"
msgstr "Ðове Ñередовище"
@@ -8397,10 +8792,10 @@ msgid "Environments|Rollback environment %{name}?"
msgstr "Відкотити Ñередовище %{name}?"
msgid "Environments|Select environment"
-msgstr ""
+msgstr "Оберіть Ñередовище"
msgid "Environments|Select pod"
-msgstr ""
+msgstr "Виберіть pod"
msgid "Environments|Show all"
msgstr "Показати вÑÑ–"
@@ -8460,29 +8855,23 @@ msgid "Epics let you manage your portfolio of projects more efficiently and with
msgstr "Епіки дозволÑÑŽÑ‚ÑŒ керувати вашим портфелем проектів ефективніше та з меншими зуÑиллÑми"
msgid "Epics, Issues, and Merge Requests"
-msgstr ""
+msgstr "Епіки, Задачі та Запити на злиттÑ"
-msgid "Epics|Add an epic"
-msgstr "Додати епік"
+msgid "Epics|Add a new epic"
+msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
-msgstr "Додати Ñ–Ñнуючий епік Ñк дочірній."
+msgid "Epics|Add an existing epic"
+msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при збереженні дати %{epicDateType}"
msgid "Epics|An error occurred while updating labels."
-msgstr ""
+msgstr "Помилка під Ñ‡Ð°Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¼Ñ–Ñ‚Ð¾Ðº."
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr "Ви впевнені, що хочете видалити %{bStart}%{targetIssueTitle}%{bEnd} із %{bStart}%{parentEpicTitle}%{bEnd}?"
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr "Створити епік в цій групі Ñ– додати його Ñк дочірній."
-
-msgid "Epics|Create new epic"
-msgstr "Створити новий епік"
-
msgid "Epics|How can I solve this?"
msgstr "Як Ñ Ð¼Ð¾Ð¶Ñƒ це вирішити?"
@@ -8505,7 +8894,7 @@ msgid "Epics|Something went wrong while creating child epics."
msgstr "ЩоÑÑŒ пішло не так при Ñтворенні дочірніх епіків."
msgid "Epics|Something went wrong while creating issue."
-msgstr ""
+msgstr "ЩоÑÑŒ пішло не так при Ñтворенні задачі."
msgid "Epics|Something went wrong while fetching child epics."
msgstr "ЩоÑÑŒ пішло не так при отриманні дочірніх епіків."
@@ -8550,14 +8939,23 @@ msgid "Error creating epic"
msgstr "Помилка при Ñтворенні епіку"
msgid "Error creating label."
+msgstr "Помилка при Ñтворенні мітки."
+
+msgid "Error creating new iteration"
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr "Помилка при видаленні %{issuableType}"
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
-msgid "Error deleting project. Check logs for error details."
+msgid "Error creating the snippet"
msgstr ""
+msgid "Error deleting %{issuableType}"
+msgstr ""
+
+msgid "Error deleting project. Check logs for error details."
+msgstr "Помилка при видаленні проєкту. Перевірте журнали Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð¸Ñ†ÑŒ про помилку."
+
msgid "Error fetching diverging counts for branches. Please try again."
msgstr "Помилка при отриманні кількоÑÑ‚Ñ– розбіжноÑтей Ð´Ð»Ñ Ð³Ñ–Ð»Ð¾Ðº. Будь лаÑка, Ñпробуйте знову."
@@ -8571,7 +8969,7 @@ msgid "Error fetching network graph."
msgstr "Помилка при отриманні графа мережі."
msgid "Error fetching payload data."
-msgstr ""
+msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при отриманні даних."
msgid "Error fetching projects"
msgstr "Помилка Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ–Ð²"
@@ -8631,7 +9029,7 @@ msgid "Error occurred when toggling the notification subscription"
msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° під Ñ‡Ð°Ñ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð¿Ñ–Ð´Ð¿Ð¸Ñки на ÑповіщеннÑ"
msgid "Error occurred while updating the issue status"
-msgstr ""
+msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° під Ñ‡Ð°Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ ÑтатуÑу задачі"
msgid "Error occurred while updating the issue weight"
msgstr "Помилка при оновленні ваги задачі"
@@ -8657,9 +9055,6 @@ msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°. КориÑтувач не був розб
msgid "Error rendering markdown preview"
msgstr "Помилка при попередньому переглÑді markdown"
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr "Помилка при збереженні мітки."
@@ -8675,6 +9070,9 @@ msgstr "Помилка при оновленні ÑтатуÑа Ð´Ð»Ñ Ð²ÑÑ–Ñ…
msgid "Error updating status of to-do item."
msgstr "Помилка при оновленні ÑтатуÑа нагадуваннÑ."
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr "Помилка Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ"
@@ -8724,14 +9122,14 @@ msgid "Errors"
msgstr "Помилки"
msgid "Errors:"
+msgstr "Помилки:"
+
+msgid "Estimate"
msgstr ""
msgid "Estimated"
msgstr "За оцінками"
-msgid "Event Actions"
-msgstr ""
-
msgid "EventFilterBy|Filter by all"
msgstr "Фільтрувати по вÑім"
@@ -8754,16 +9152,16 @@ msgid "EventFilterBy|Filter by team"
msgstr "Фільтрувати по команді"
msgid "EventFilterBy|Filter by wiki"
-msgstr ""
+msgstr "Фільтр по вікі"
msgid "Events"
msgstr "Події"
msgid "Events in %{group_name}"
-msgstr ""
+msgstr "Події в %{group_name}"
msgid "Events in %{project_path}"
-msgstr ""
+msgstr "Події в %{project_path}"
msgid "Every %{action} attempt has failed: %{job_error_message}. Please try again."
msgstr "УÑÑ– Ñпроби %{action} закінчилиÑÑ Ð½ÐµÐ²Ð´Ð°Ñ‡ÐµÑŽ: %{job_error_message}. Будь лаÑка, Ñпробуйте знову."
@@ -8771,14 +9169,14 @@ msgstr "УÑÑ– Ñпроби %{action} закінчилиÑÑ Ð½ÐµÐ²Ð´Ð°Ñ‡ÐµÑŽ: %
msgid "Every day"
msgstr "ЩоднÑ"
-msgid "Every day (at 4:00am)"
-msgstr "Кожен день (в 4:00 ранку)"
+msgid "Every day (at %{time})"
+msgstr ""
msgid "Every month"
msgstr "ЩоміÑÑцÑ"
-msgid "Every month (on the 1st at 4:00am)"
-msgstr "Кожен міÑÑць (1-го чиÑла о 4:00 ранку)"
+msgid "Every month (Day %{day} at %{time})"
+msgstr ""
msgid "Every three months"
msgstr "Кожні 3 міÑÑці"
@@ -8789,8 +9187,8 @@ msgstr "Кожні 2 тижні"
msgid "Every week"
msgstr "ЩотижнÑ"
-msgid "Every week (Sundays at 4:00am)"
-msgstr "Ð©Ð¾Ñ‚Ð¸Ð¶Ð½Ñ (в неділю о 4:00 ранку)"
+msgid "Every week (%{weekday} at %{time})"
+msgstr ""
msgid "Everyone"
msgstr "Будь-хто"
@@ -8805,7 +9203,7 @@ msgid "Everything on your to-do list is marked as done."
msgstr "Ð’Ñе у вашому ÑпиÑку нагадувань відмічено виконаним."
msgid "Everything you need to create a GitLab Pages site using Gatsby."
-msgstr ""
+msgstr "Ð’Ñе, що потрібно Ð´Ð»Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñайту на GitLab Pages за допомогою Gatsby."
msgid "Everything you need to create a GitLab Pages site using GitBook."
msgstr "Ð’Ñе, що потрібно Ð´Ð»Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñайту на GitLab Pages за допомогою GitBook."
@@ -8826,6 +9224,9 @@ msgid "Evidence collection"
msgstr ""
msgid "Exactly one of %{attributes} is required"
+msgstr "Потрібен лише один з %{attributes}"
+
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
msgstr ""
msgid "Example: @sub\\.company\\.com$"
@@ -8846,14 +9247,17 @@ msgstr "Без комітів злиттÑ. Обмежено 6000 комітів
msgid "Existing members and groups"
msgstr "ІÑнуючі учаÑники та групи"
-msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
+msgid "Existing projects may be moved into a group"
msgstr ""
+msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
+msgstr "ІÑнуючі проєкти зможуть викориÑтовувати політику Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ñ‚ÐµÑ€Ð¼Ñ–Ð½Ñƒ дії. Ðе вмикайте цю функцію при викориÑтанні зовнішнього Container Registry, оÑкільки Ñ–Ñнує екÑплуатаційний ризик, Ñкщо в одному проєкті Ñ–Ñнує багато образів."
+
msgid "Existing shares"
msgstr ""
msgid "Existing sign in methods may be removed"
-msgstr ""
+msgstr "ІÑнуючі методи входу можуть бути видалені."
msgid "Expand"
msgstr "Розгорнути"
@@ -8865,7 +9269,7 @@ msgid "Expand approvers"
msgstr "Розгорнути ÑпиÑок затверджуючих оÑіб"
msgid "Expand child epics"
-msgstr ""
+msgstr "Розгорнути дочірні епіки"
msgid "Expand down"
msgstr "Розгорнути вниз"
@@ -8879,6 +9283,9 @@ msgstr "Розгорніть бічну панель"
msgid "Expand up"
msgstr "Розгорнути вгору"
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr "Термін дії"
@@ -8886,7 +9293,7 @@ msgid "Expiration date"
msgstr "Термін дії"
msgid "Expiration policy for the Container Registry is a perfect solution for keeping the Registry space down while still enjoying the full power of GitLab CI/CD."
-msgstr ""
+msgstr "Політика Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ñ‚ÐµÑ€Ð¼Ñ–Ð½Ñƒ дії Ð´Ð»Ñ Container Registry - це ідеальне Ñ€Ñ–ÑˆÐµÐ½Ð½Ñ Ð´Ð»Ñ ÐµÐºÐ¾Ð½Ð¾Ð¼Ñ–Ñ— проÑтору в РеєÑтрі при цьому зі збереженнÑм вÑієї потужноÑÑ‚Ñ– GitLab CI/CD. "
msgid "Expired"
msgstr "Термін дії закінчивÑÑ"
@@ -8894,6 +9301,9 @@ msgstr "Термін дії закінчивÑÑ"
msgid "Expired %{expiredOn}"
msgstr "Минув(-ло) %{expiredOn}"
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr "ЗакінчуєтьÑÑ"
@@ -8903,6 +9313,9 @@ msgstr "ДійÑний до"
msgid "Expires in %{expires_at}"
msgstr "ЗакінчуєтьÑÑ %{expires_at}"
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8931,7 +9344,7 @@ msgid "Export as CSV"
msgstr "ЕкÑпортувати Ñк CSV"
msgid "Export group"
-msgstr ""
+msgstr "ЕкÑпортувати групу"
msgid "Export issues"
msgstr "ЕкÑпортувати задачі"
@@ -8940,7 +9353,7 @@ msgid "Export project"
msgstr "ЕкÑпорт проекту"
msgid "Export this group with all related data to a new GitLab instance. Once complete, you can import the data file from the \"New Group\" page."
-msgstr ""
+msgstr "ЕкÑпортуйте цю групу з уÑіма відповідними даними в новий екземплÑÑ€ GitLab. ПіÑÐ»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ð²Ð¸ зможете імпортувати файл даних зі Ñторінки \"Ðова Група\"."
msgid "Export this project with all its related data in order to move your project to a new GitLab instance. Once the export is finished, you can import the file from the \"New Project\" page."
msgstr "ЕкÑпортувати цей проект з уÑіма пов'Ñзаними даними Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, щоб переміÑтити його на новий інÑÑ‚Ð°Ð½Ñ GitLab. ПіÑÐ»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ ÐµÐºÑпорту ви зможете імпортувати файл на Ñторінці \"Ðовий проект\"."
@@ -8981,18 +9394,6 @@ msgstr "Мітка клаÑифікації"
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr "Якщо клаÑифікаційну мітку не вÑтановлено, викориÑтовуватиметьÑÑ Ñтандартна мітка `%{default_label}`."
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr "Додати кнопку до панелі метрик, що вказує безпоÑередньо на вашу Ñ–Ñнуючу зовнішню панель."
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr "Введіть URL-адреÑу панелі на Ñку ви хочете поÑлатиÑÑ"
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr "Ð—Ð¾Ð²Ð½Ñ–ÑˆÐ½Ñ Ð¿Ð°Ð½ÐµÐ»ÑŒ керуваннÑ"
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr "Повна URL-адреÑа панелі керуваннÑ"
-
msgid "ExternalWikiService|External Wiki"
msgstr "Ð—Ð¾Ð²Ð½Ñ–ÑˆÐ½Ñ Ð²Ñ–ÐºÑ–"
@@ -9045,13 +9446,13 @@ msgid "Failed to create import label for jira import."
msgstr ""
msgid "Failed to create repository"
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ñтворити репозиторій"
msgid "Failed to create resources"
msgstr "Ðе вдалоÑÑ Ñтворити реÑурÑ"
msgid "Failed to create wiki"
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ñтворити вікі"
msgid "Failed to delete board. Please try again."
msgstr "Ðе вдалоÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ дошку. Будь лаÑка, Ñпробуйте знову."
@@ -9063,7 +9464,7 @@ msgid "Failed to enqueue the rebase operation, possibly due to a long-lived tran
msgstr "Ðе вдалоÑÑ Ð²ÐºÐ»ÑŽÑ‡Ð¸Ñ‚Ð¸ rebase в чергу, можливо через довгоживучу транзакцію. Спробуйте знову через деÑкий чаÑ."
msgid "Failed to find import label for Jira import."
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ мітку Ð´Ð»Ñ Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚Ñƒ ÑиÑтеми Jira."
msgid "Failed to get ref."
msgstr "Ðе вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ ref."
@@ -9087,7 +9488,7 @@ msgid "Failed to load groups & users."
msgstr "Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ групи та кориÑтувачів."
msgid "Failed to load labels. Please try again."
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ мітки. Будь лаÑка, Ñпробуйте ще раз."
msgid "Failed to load milestones. Please try again."
msgstr ""
@@ -9119,6 +9520,9 @@ msgstr "Ðе вдалоÑÑ Ð·Ñ€Ð¾Ð±Ð¸Ñ‚Ð¸ гілку захищеною"
msgid "Failed to protect the environment"
msgstr "Ðе вдалоÑÑ Ð·Ñ€Ð¾Ð±Ð¸Ñ‚Ð¸ Ñередовище захищеним"
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr "Ðе вдалоÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ Zoom-зуÑтріч"
@@ -9194,8 +9598,8 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
-msgstr "Fast-forward Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð½ÐµÐ¼Ð¾Ð¶Ð»Ð¸Ð²Ðµ. Виконайте rebase з початкової гілки у цільовій або злийте цільову гілку у початкову Ð´Ð»Ñ Ð¾Ð±â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ запиту на злиттÑ."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
+msgstr ""
msgid "Fast-forward merge without a merge commit"
msgstr "Fast-forward Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð±ÐµÐ· окремого коміту злиттÑ"
@@ -9257,6 +9661,12 @@ msgstr "ОпиÑ"
msgid "FeatureFlags|Edit Feature Flag"
msgstr "Редагувати перемикач функції"
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9269,6 +9679,9 @@ msgstr "Специфікації Ñередовищ"
msgid "FeatureFlags|Feature Flag"
msgstr "Перемикач функції"
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr "Поведінка перемикачів функцій будуєтьÑÑ ÑˆÐ»Ñхом ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð½Ð°Ð±Ð¾Ñ€Ñƒ правил Ð´Ð»Ñ Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñтану цільових Ñередовищ. Ð”Ð»Ñ %{boldStart}вÑÑ–Ñ… Ñередовищ%{boldEnd} вÑтановлено правило за замовчуваннÑм %{codeStart}*%{codeEnd}, але ви можете додавати необхідні правила шлÑхом вибору нижче Ñпецифікацій Ñередовищ. Ви можете умімкнути або вимкнути певну поведінку Ð´Ð»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ із ваших правил зробивши його %{boldStart}Ðктивним%{boldEnd} або %{boldStart}Ðеактивним%{boldEnd}."
@@ -9278,15 +9691,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr "Перемикачі функцій"
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr "Перемикач функції %{name} буде видалено. Ви впевнені?"
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr "Перемикачі функцій дозволÑÑŽÑ‚ÑŒ налаштовувати ваш код по-різному за допомогою динамічного ÑƒÐ²Ñ–Ð¼ÐºÐ½ÐµÐ½Ð½Ñ Ñ‡Ð¸ Ð²Ð¸Ð¼ÐºÐ½ÐµÐ½Ð½Ñ Ð¿ÐµÐ²Ð½Ð¾Ñ— функціональноÑÑ‚Ñ–."
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr "Розпочати роботу з перемикачами функцій"
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr "Ідентифікатор"
@@ -9305,6 +9727,9 @@ msgstr "Ð’Ñтановіть %{docs_link_anchored_start}ÑуміÑну клієÐ
msgid "FeatureFlags|Instance ID"
msgstr "Ідентифікатор ІнÑтанÑу"
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr "Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð¿ÐµÑ€ÐµÐ¼Ð¸ÐºÐ°Ñ‡Ñ–Ð² функцій"
@@ -9320,9 +9745,15 @@ msgstr "Ðовий"
msgid "FeatureFlags|New Feature Flag"
msgstr "Ðовий перемикач функції"
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr "Ðовий перемикач функції"
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr "Процент Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ (за кориÑтувачами, що здійÑнили вхід)"
@@ -9369,10 +9800,10 @@ msgid "FeatureFlag|Delete strategy"
msgstr ""
msgid "FeatureFlag|Percentage"
-msgstr ""
+msgstr "ВідÑоток"
msgid "FeatureFlag|Type"
-msgstr ""
+msgstr "Тип"
msgid "FeatureFlag|User IDs"
msgstr ""
@@ -9413,6 +9844,9 @@ msgstr "Файловий менеджер"
msgid "File deleted"
msgstr "Файл видалено"
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9425,6 +9859,9 @@ msgstr "Файл переміщено"
msgid "File name"
msgstr "Ім'Ñ Ñ„Ð°Ð¹Ð»Ñƒ"
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9434,9 +9871,6 @@ msgstr "Шаблони файлів"
msgid "File upload error."
msgstr "Помилка Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ."
-msgid "File:"
-msgstr "Файл:"
-
msgid "Files"
msgstr "Файли"
@@ -9452,36 +9886,60 @@ msgstr "Заповніть Ð¿Ð¾Ð»Ñ Ð½Ð¸Ð¶Ñ‡Ðµ, увімкніть <strong>%{ena
msgid "Filter"
msgstr "Фільтр"
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr "Фільтрувати закриті за %{issuable_type}."
msgid "Filter by %{issuable_type} that are currently opened."
msgstr "Фільтрувати відкриті за %{issuable_type}."
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr "Фільтрувати за повідомленнÑм Ð´Ð»Ñ ÐºÐ¾Ð¼Ñ–Ñ‚Ñƒ"
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr "Фільтрувати за назвою етапу"
msgid "Filter by name"
msgstr ""
-msgid "Filter by status"
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
msgstr ""
+msgid "Filter by status"
+msgstr "Фільтрувати за ÑтатуÑом"
+
msgid "Filter by two-factor authentication"
msgstr "Фільтрувати за двофакторною автентифікацією"
msgid "Filter by user"
msgstr "Сортувати по кориÑтувачах"
-msgid "Filter projects"
+msgid "Filter pipelines"
msgstr ""
+msgid "Filter projects"
+msgstr "Фільтрувати проєкти"
+
msgid "Filter results"
msgstr ""
@@ -9534,7 +9992,7 @@ msgid "Finished"
msgstr "Завершено"
msgid "First Name is too long (maximum is %{max_length} characters)."
-msgstr ""
+msgstr "Ім'Ñ Ð·Ð°Ð½Ð°Ð´Ñ‚Ð¾ довге (макÑимум — %{max_length} знаків)."
msgid "First Seen"
msgstr ""
@@ -9687,7 +10145,7 @@ msgid "From %{providerTitle}"
msgstr "З %{providerTitle}"
msgid "From <code>%{source_title}</code> into"
-msgstr ""
+msgstr "Від <code>%{source_title}</code> до"
msgid "From Bitbucket"
msgstr "З Bitbucket"
@@ -9710,9 +10168,6 @@ msgstr "З моменту ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð·Ð°Ð´Ð°Ñ‡Ñ– до розгортаÐ
msgid "From merge request merge until deploy to production"
msgstr "Від Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ð·Ð°Ð¿Ð¸Ñ‚Ñƒ на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð´Ð¾ Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ð½Ð° production"
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr "Із Ñторінки деталей Kubernetes-клаÑтера, вÑтановіть runner зі ÑпиÑку заÑтоÑунків"
@@ -9752,15 +10207,15 @@ msgstr "Створити новий екÑпорт"
msgid "Geo"
msgstr "Geo"
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr "Гео-Вузли"
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9933,9 +10388,15 @@ msgid "GeoNodes|You have configured Geo nodes using an insecure HTTP connection.
msgstr "Ви налаштували Geo-вузли через незахищене HTTP-з’єднаннÑ. Ми рекомендуємо викориÑтовувати HTTPS."
msgid "GeoNodes|primary node"
-msgstr ""
+msgstr "оÑновний вузол"
msgid "GeoNodes|secondary nodes"
+msgstr "вторинні вузли"
+
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
msgstr ""
msgid "Geo|%{name} is scheduled for forced re-download"
@@ -9947,14 +10408,14 @@ msgstr "%{name} заплановано Ð´Ð»Ñ Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€Ð½Ð¾Ñ— ÑинхронÑ
msgid "Geo|%{name} is scheduled for re-verify"
msgstr "%{name} заплановано Ð´Ð»Ñ Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€Ð½Ð¾Ñ— перевірки"
-msgid "Geo|All"
-msgstr "Ð’ÑÑ–"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
-msgstr ""
+msgstr "Ð’ÑÑ– проєкти"
msgid "Geo|All projects are being scheduled for resync"
msgstr ""
@@ -9972,13 +10433,13 @@ msgid "Geo|Failed"
msgstr "Ðевдало"
msgid "Geo|Filter by status"
-msgstr ""
+msgstr "Фільтр за ÑтатуÑом"
msgid "Geo|Geo Status"
msgstr "Geo ÑтатуÑ"
msgid "Geo|In progress"
-msgstr ""
+msgstr "Ð’ процеÑÑ–"
msgid "Geo|In sync"
msgstr "Синхронізовано"
@@ -10001,6 +10462,12 @@ msgstr "Ðіколи"
msgid "Geo|Next sync scheduled at"
msgstr "ÐаÑтупна ÑÐ¸Ð½Ñ…Ñ€Ð¾Ð½Ñ–Ð·Ð°Ñ†Ñ–Ñ Ð·Ð°Ð¿Ð»Ð°Ð½Ð¾Ð²Ð°Ð½Ð° на"
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr "Ðе Ñинхронізовано"
@@ -10032,7 +10499,7 @@ msgid "Geo|Remove"
msgstr "Видалити"
msgid "Geo|Remove entry"
-msgstr ""
+msgstr "Видалити запиÑ"
msgid "Geo|Remove tracking database entry"
msgstr ""
@@ -10052,6 +10519,9 @@ msgstr "Повторно перевірити"
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr "СтатуÑ"
@@ -10070,6 +10540,9 @@ msgstr "База даних зараз %{db_lag} позаду оÑновного
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr "Вузол зараз %{minutes_behind} позаду оÑновного вузла."
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -10079,6 +10552,12 @@ msgstr "Ð—Ð°Ð¿Ð¸Ñ Ð²Ñ–Ð´ÑÑ‚ÐµÐ¶ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñƒ (%{project_id})
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr "Ð—Ð°Ð¿Ð¸Ñ Ð²Ñ–Ð´ÑÑ‚ÐµÐ¶ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ (%{type}/%{id}) було уÑпішно видалено."
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr "Ðевідомий Ñтан"
@@ -10173,10 +10652,10 @@ msgid "GitLab Shared Runners execute code of different projects on the same Runn
msgstr "Загальні Runner'и GitLab виконують код Ð´Ð»Ñ Ñ€Ñ–Ð·Ð½Ð¸Ñ… проектів на одному Ñ– тому ж Runner, Ñкщо ви не налаштуєте автоматичне маÑÑˆÑ‚Ð°Ð±ÑƒÐ²Ð°Ð½Ð½Ñ GitLab Runner’ів за допомогою MaxBuilds 1 (Ñк зроблено на GitLab.com)."
msgid "GitLab Support Bot"
-msgstr ""
+msgstr "Бот Підтримки GitLab"
msgid "GitLab Team Member"
-msgstr ""
+msgstr "УчаÑник команди GitLab"
msgid "GitLab User"
msgstr "GitLab КориÑтувач"
@@ -10197,7 +10676,7 @@ msgid "GitLab is obtaining a Let's Encrypt SSL certificate for this domain. This
msgstr "GitLab отримує SSL-Ñертифікат Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ домену від Let's Encrypt. Це може зайнÑти деÑкий чаÑ. Будь лаÑка, Ñпробуйте знову пізніше."
msgid "GitLab is undergoing maintenance and is operating in a read-only mode."
-msgstr ""
+msgstr "GitLab проходить технічне обÑÐ»ÑƒÐ³Ð¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñ– працює лише в режимі читаннÑ."
msgid "GitLab member or Email address"
msgstr "УчаÑник GitLab або адреÑа електронної пошти"
@@ -10209,7 +10688,7 @@ msgid "GitLab project export"
msgstr "ЕкÑпорт проекту GitLab"
msgid "GitLab restart is required to apply changes."
-msgstr ""
+msgstr "Ðеобхідно перезавантажити GitLab Ð´Ð»Ñ Ð·Ð°ÑтоÑÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð¼Ñ–Ð½."
msgid "GitLab single sign on URL"
msgstr "URL єдиного входу GitLab"
@@ -10224,7 +10703,7 @@ msgid "GitLab.com import"
msgstr "Імпорт з GitLab.com"
msgid "GitLabPagesDomains|Retry"
-msgstr ""
+msgstr "Повторити Ñпробу"
msgid "GitLabPages|%{domain} is not verified. To learn how to verify ownership, visit your %{link_start}domain details%{link_end}."
msgstr "%{domain} не підтведжено. Щоб дізнатиÑÑ Ñк підтвердити його належніÑÑ‚ÑŒ, переглÑньте вашу %{link_start}інформацію про домен%{link_end}."
@@ -10269,7 +10748,7 @@ msgid "GitLabPages|Learn more."
msgstr "ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ."
msgid "GitLabPages|Maximum size of pages (MB)"
-msgstr ""
+msgstr "МакÑимальний розмір Ñторінок (МБ)"
msgid "GitLabPages|New Domain"
msgstr "Ðовий домен"
@@ -10331,9 +10810,6 @@ msgstr "URL-адреÑа хоÑту Gitea"
msgid "Gitea Import"
msgstr "Імпорт з Gitea"
-msgid "Gitlab CI/CD"
-msgstr "Gitlab CI/CD"
-
msgid "Gitlab Pages"
msgstr "Gitlab Pages"
@@ -10367,9 +10843,6 @@ msgstr "ПовернутиÑÑ Ð´Ð¾ %{startTag}Відкритих задач%{en
msgid "Go full screen"
msgstr "Ðа повний екран"
-msgid "Go to"
-msgstr "Перейти до"
-
msgid "Go to %{link_to_google_takeout}."
msgstr "Перейти до %{link_to_google_takeout}."
@@ -10377,13 +10850,13 @@ msgid "Go to Pipelines"
msgstr "Перейти до конвеєрів"
msgid "Go to Webhooks"
-msgstr ""
+msgstr "Перейти до Веб-хуків"
msgid "Go to commits"
msgstr "Перейти до комітів"
msgid "Go to definition"
-msgstr ""
+msgstr "Перейти до визначеннÑ"
msgid "Go to environments"
msgstr "Перейти до Ñередовищ"
@@ -10485,7 +10958,7 @@ msgid "Google Takeout"
msgstr "Google Takeout"
msgid "Google authentication is not %{link_start}properly configured%{link_end}. Ask your GitLab administrator if you want to use this service."
-msgstr ""
+msgstr "ÐÐ²Ñ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ Google не %{link_start}налаштована належним чином%{link_end}. ЗвернітьÑÑ Ð´Ð¾ вашого адмініÑтратора GitLab Ñкщо хочете викориÑтовувати цю Ñлужбу. "
msgid "Got it"
msgstr "Зрозуміло"
@@ -10532,12 +11005,21 @@ msgstr "Gravatar увімкнено"
msgid "Group"
msgstr "Група"
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr "Групу %{group_name} було призначено Ð´Ð»Ñ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ."
msgid "Group %{group_name} was successfully created."
msgstr "Групу %{group_name} уÑпішно Ñтворено."
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10571,6 +11053,12 @@ msgstr "URL-адреÑа групи"
msgid "Group avatar"
msgstr "Ðватар групи"
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr "ÐžÐ¿Ð¸Ñ Ð³Ñ€ÑƒÐ¿Ð¸"
@@ -10581,12 +11069,15 @@ msgid "Group details"
msgstr "Деталі групи"
msgid "Group export could not be started."
+msgstr "Ðе вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити екÑпорт групи."
+
+msgid "Group export error"
msgstr ""
msgid "Group export link has expired. Please generate a new export from your group settings."
-msgstr ""
+msgstr "ЗакінчивÑÑ Ñ‚ÐµÑ€Ð¼Ñ–Ð½ дії поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° екÑпорт групи. Будь лаÑка, згенеруйте новий екÑпорт в налаштуваннÑÑ… групи."
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10604,10 +11095,13 @@ msgstr "Керівники групи можуть зареєÑтрувати г
msgid "Group members"
msgstr "КориÑтувачі групи"
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr "Ðазва групи"
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10625,12 +11119,18 @@ msgstr "ШлÑÑ… групи доÑтупний."
msgid "Group pipeline minutes were successfully reset."
msgstr "Групові хвилини Ð´Ð»Ñ ÐºÐ¾Ð½Ð²ÐµÑ”Ñ€Ñ–Ð² уÑпішно обнулено."
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr "Змінні групи (уÑпадковані)"
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr "Групу уÑпішно оновлено."
@@ -10697,9 +11197,6 @@ msgstr "Увімкнути автентифікацію через SAML Ð´Ð»Ñ Ñ
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr "Зробити обов'Ñзковою SSO автентифікацію Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— групи."
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr "Зробити обов'Ñзковою SSO автентифікацію Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— групи."
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr "Зобов'Ñзати кориÑтувачів Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— групи мати окремі облікові запиÑи керовані нею."
@@ -10901,6 +11398,9 @@ msgstr "Ви можете перенеÑти цю групу тільки в гÑ
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr "Вам необхідно обновити Ñвої локальні репозиторії з тим, щоб вони вказували на нове розміщеннÑ."
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr "не може бути ÑкаÑовано поки \"Ð‘Ð»Ð¾ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ñпільного доÑтупу з іншими групами\" активне на батьківÑькій групі, за винÑтком влаÑника батьківÑької групи"
@@ -10917,16 +11417,16 @@ msgid "Groups (%{count})"
msgstr "Групи (%{count})"
msgid "Groups (%{groups})"
-msgstr ""
+msgstr "Групи (%{groups})"
msgid "Groups can also be nested by creating %{subgroup_docs_link_start}subgroups%{subgroup_docs_link_end}."
msgstr "Групи також можуть бути вкладеними при викориÑтанні %{subgroup_docs_link_start}підгруп%{subgroup_docs_link_end}."
msgid "Groups to synchronize"
-msgstr ""
+msgstr "Групи Ð´Ð»Ñ Ñинхронізації"
msgid "Groups with access to %{strong_start}%{group_name}%{strong_end}"
-msgstr ""
+msgstr "Групи з доÑтупом до %{strong_start}%{group_name}%{strong_end}"
msgid "Groups with access to <strong>%{project_name}</strong>"
msgstr "Групи з доÑтупом до <strong>%{project_name}</strong>"
@@ -10989,7 +11489,7 @@ msgid "GroupsTree|No groups matched your search"
msgstr "Жодна группа не задовольнÑÑ” параметрам вашого запиту"
msgid "GroupsTree|No groups or projects matched your search"
-msgstr "Жодна группа чи проект не задовольнÑÑ” параметрам вашого запиту"
+msgstr ""
msgid "GroupsTree|Search by name"
msgstr "Пошук за іменем"
@@ -11006,6 +11506,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr "Хешовані шлÑхи Ð´Ð»Ñ Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ñ–Ñ—Ð²"
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr "Електронна пошта Ð´Ð»Ñ Ð·Ð²ÐµÑ€Ñ‚Ð°Ð½ÑŒ кориÑтувачів"
@@ -11015,6 +11518,9 @@ msgstr "Логотип в заголовку уÑпішно видалено."
msgid "Header message"
msgstr "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ°"
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr "Здоров'Ñ"
@@ -11125,6 +11631,9 @@ msgstr "ІÑторіÑ"
msgid "History of authentications"
msgstr "ІÑÑ‚Ð¾Ñ€Ñ–Ñ Ð°Ð²Ñ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ð¹"
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr "Ðевдале Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ñ…ÑƒÐºÐ°. ПереконайтеÑÑ, що Ñ†Ñ Ð³Ñ€ÑƒÐ¿Ð° має проект із комітами."
@@ -11134,9 +11643,12 @@ msgstr "Хук уÑпішно Ñтворено."
msgid "Hook was successfully updated."
msgstr "Хук уÑпішно оновлено."
-msgid "Hour (UTC)"
+msgid "Hostname"
msgstr ""
+msgid "Hour (UTC)"
+msgstr "Година (UTC)"
+
msgid "Housekeeping"
msgstr "ОчищеннÑ"
@@ -11225,7 +11737,7 @@ msgid "IDE|Successful commit"
msgstr "УÑпішний коміт"
msgid "IDE|This option is disabled because you are not allowed to create merge requests in this project."
-msgstr ""
+msgstr "Ð¦Ñ Ð¾Ð¿Ñ†Ñ–Ñ Ð²Ð¸Ð¼ÐºÐ½ÐµÐ½Ð°, тому що ви не можете Ñтворювати запити на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð² цьому проєкті."
msgid "IDE|This option is disabled because you don't have write permissions for the current branch."
msgstr ""
@@ -11284,6 +11796,9 @@ msgstr "Якщо це дозволено, доÑтуп до проектів бÑ
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
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}."
@@ -11293,7 +11808,10 @@ msgstr "Якщо це була помилка, ви можете залишитÐ
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr "При викориÑтанні GitHub, ви побачите ÑтатуÑи конвеєрів Ð´Ð»Ñ ÐºÐ¾Ð¼Ñ–Ñ‚Ñ–Ð² Ñ– запитів на злиттÑ. %{more_info_link}"
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11302,6 +11820,12 @@ msgstr "Якщо ви втратите коди відновленнÑ, ви мÐ
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr "Якщо ваш HTTP-репозиторій не Ñ” загальнодоÑтупним, додайте Ñвої облікові дані."
@@ -11314,8 +11838,11 @@ msgstr "Iгнорувати"
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
-msgstr "Образ: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
+msgstr ""
msgid "ImageDiffViewer|2-up"
msgstr "2 поруч"
@@ -11332,15 +11859,15 @@ msgstr "Ð’"
msgid "ImageViewerDimensions|W"
msgstr "Ш"
+msgid "Impersonation Tokens"
+msgstr ""
+
msgid "Impersonation has been disabled"
msgstr "Ð†Ð¼Ñ–Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð±ÑƒÐ»Ð¾ вимкнено"
msgid "Import"
msgstr "Імпорт"
-msgid "Import %{status}"
-msgstr ""
-
msgid "Import CSV"
msgstr "Імпортувати CSV"
@@ -11350,6 +11877,9 @@ msgstr "Імпортувати проекти з Gitea"
msgid "Import all compatible projects"
msgstr "Імпорт вÑÑ–Ñ… ÑуміÑних проектів"
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr "Імпортувати вÑÑ– проекти"
@@ -11359,21 +11889,24 @@ msgstr "Імпорт вÑÑ–Ñ… репозиторіїв"
msgid "Import an exported GitLab project"
msgstr "Імпортувати екÑпортований проект GitLab"
-msgid "Import from"
+msgid "Import failed due to a GitHub error: %{original}"
msgstr ""
+msgid "Import from"
+msgstr "Імпортувати з"
+
msgid "Import from Jira"
-msgstr ""
+msgstr "Імпортувати з Jira"
msgid "Import in progress"
msgstr "Імпорт триває"
+msgid "Import in progress. Refresh page to see newly added issues."
+msgstr ""
+
msgid "Import issues"
msgstr "Імпорт задач"
-msgid "Import issues from Jira"
-msgstr ""
-
msgid "Import members"
msgstr "Імпортувати учаÑників"
@@ -11464,12 +11997,12 @@ msgstr "Покращити дошки обговорень за допомого
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr "Покращити запити на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ñ‚Ð° підтримку кориÑтувачів за допомогою GitLab Enterprise Edition."
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
-msgstr "Покращити ÑƒÐ¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ Ð·Ð°Ð´Ð°Ñ‡Ð°Ð¼Ð¸ з можливіÑÑ‚ÑŽ Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð²Ð°Ð³Ð¸ задач за допомогою GitLab Enterprise Edition."
-
msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr "Покращити пошук за допомогою розширеного глобального пошук в верÑÑ–Ñ— GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
+msgstr ""
+
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
msgstr "Щоб увімкнути ÑтатиÑтику на рівні інÑтанÑа, звернітьÑÑ Ð´Ð¾ адмініÑтратора, щоб увімкнути %{usage_ping_link_start}дані про викориÑтаннÑ%{usage_ping_link_end}."
@@ -11483,7 +12016,7 @@ msgid "In order to tailor your experience with GitLab we<br>would like to know a
msgstr "Ð”Ð»Ñ Ñ‚Ð¾Ð³Ð¾, щоб адаптувати GitLab до Ð²Ð°Ñ Ð½Ð°Ð¼<br>потрібно більше про Ð²Ð°Ñ Ð´Ñ–Ð·Ð½Ð°Ñ‚Ð¸ÑÑ."
msgid "In progress"
-msgstr ""
+msgstr "Ð’ процеÑÑ–"
msgid "In the next step, you'll be able to select the projects you want to import."
msgstr "Ðа наÑтупному кроці ви зможете вибрати проекти, Ñкі хочете імпортувати."
@@ -11500,6 +12033,9 @@ msgstr "Включити угоду про Ð½Ð°Ð´Ð°Ð½Ð½Ñ Ð¿Ð¾Ñлуг та пр
msgid "Include author name in notification email body"
msgstr "Вказати ім'Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð° в тілі ÑÐ¿Ð¾Ð²Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð¿Ð¾ електронній пошті"
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr "Додайте Ð¾Ð¿Ð¸Ñ Ð·Ð°Ð¿Ð¸Ñ‚Ñƒ на злиттÑ"
@@ -11533,6 +12069,12 @@ msgstr "ÐеÑуміÑний проект"
msgid "Incompatible options set!"
msgstr "Ð’Ñтановлено неÑуміÑні параметри!"
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr "ІндекÑувати вÑÑ– проекти"
@@ -11557,18 +12099,36 @@ msgstr "Введіть ключі хоÑта вручну"
msgid "Input your repository URL"
msgstr "Введіть ваш URL репозиторію"
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr "Ð’Ñтавити цитату"
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr "Ð’Ñтавити код"
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr "Додати пропозицію"
msgid "Insights"
msgstr "СтатиÑтика (Insights)"
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr "Ð’Ñтановити"
@@ -11613,7 +12173,7 @@ msgid "Integration"
msgstr "ІнтеграціÑ"
msgid "Integration Settings"
-msgstr ""
+msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð†Ð½Ñ‚ÐµÐ³Ñ€Ð°Ñ†Ñ–Ñ—"
msgid "Integrations"
msgstr "Інтеграції"
@@ -11621,6 +12181,30 @@ msgstr "Інтеграції"
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr "Зацікавлені Ñторони за бажаннÑм можуть навіть робити внеÑки шлÑхом Ð²Ñ–Ð´Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ ÐºÐ¾Ð¼Ñ–Ñ‚Ñ–Ð²."
@@ -11660,6 +12244,12 @@ msgstr "Ðеправильний логін або пароль"
msgid "Invalid URL"
msgstr "ÐедійÑна URL адреÑа"
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11696,18 +12286,27 @@ msgstr "Ðеправильний логін або пароль"
msgid "Invalid pin code"
msgstr "Ðеправильний PIN-код"
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr "Ðеправильний запит"
msgid "Invalid repository path"
msgstr "Ðеправильний шлÑÑ… до репозиторію"
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr "Ðеправильна відповідь від Ñервера"
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr "ÐедійÑний двофакторний код підтвердженнÑ."
@@ -11720,6 +12319,9 @@ msgstr "ЗапрошеннÑ"
msgid "Invite \"%{trimmed}\" by email"
msgstr "ЗапроÑити \"%{trimmed}\" за електронною поштою"
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr "ЗапроÑити групу"
@@ -11778,11 +12380,14 @@ msgid "Issue first depoloyed to production"
msgstr ""
msgid "Issue label"
-msgstr ""
+msgstr "Мітка задачі"
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr "Шаблон задачі (необов’Ñзково)"
@@ -11795,6 +12400,33 @@ msgstr "Задачу було закрито %{name} %{reason}"
msgid "Issue weight"
msgstr "Вага задачі"
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr "Дошка"
@@ -11852,6 +12484,9 @@ msgstr "Задачі закриті"
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr "Задачі з коментарÑми, запити на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð· порівнÑннÑми (diff) та коментарÑми, мітки, етапи, Ñніпети та інші об'єкти в проекті"
@@ -11897,6 +12532,30 @@ msgstr ""
msgid "It's you"
msgstr "Це ви"
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr "URL-адреÑа Jaeger"
@@ -11909,19 +12568,22 @@ msgstr "Ñіч."
msgid "January"
msgstr "Ñічень"
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -12047,6 +12709,9 @@ msgstr "Ðртефакти були видалені"
msgid "Job|The artifacts will be removed"
msgstr "Ðртефакти будуть видалені"
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr "Ð—Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐ¸Ð»Ð¾ÑÑ Ð½ÐµÐ²Ð´Ð°Ð»Ð¾ тому що необхідні реÑурÑи не було уÑпішно Ñтворені."
@@ -12086,6 +12751,9 @@ msgstr "червень"
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr "Ключ"
@@ -12235,7 +12903,7 @@ msgid "Last Accessed On"
msgstr ""
msgid "Last Name is too long (maximum is %{max_length} characters)."
-msgstr ""
+msgstr "Прізвище занадто довге (макÑимум — %{max_length} знаків)."
msgid "Last Pipeline"
msgstr "ОÑтанній Конвеєр"
@@ -12267,6 +12935,9 @@ msgstr "Прізвище"
msgid "Last reply by"
msgstr "ОÑÑ‚Ð°Ð½Ð½Ñ Ð²Ñ–Ð´Ð¿Ð¾Ð²Ñ–Ð´ÑŒ від"
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12274,7 +12945,7 @@ msgid "Last seen"
msgstr "ОÑÑ‚Ð°Ð½Ð½Ñ Ð°ÐºÑ‚Ð¸Ð²Ð½Ñ–ÑÑ‚ÑŒ"
msgid "Last successful sync"
-msgstr ""
+msgstr "ОÑÑ‚Ð°Ð½Ð½Ñ ÑƒÑпішна ÑинхронізаціÑ"
msgid "Last successful update"
msgstr "ОÑтаннє уÑпішне оновленнÑ"
@@ -12351,6 +13022,9 @@ msgstr "ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про Vulnerability-Check"
msgid "Learn more about Web Terminal"
msgstr "ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про Веб-термінал"
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr "ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про Ð´Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ Ñертифікатів до проекту перейшовши до %{docs_link_start}документації по GitLab Pages%{docs_link_end}."
@@ -12372,9 +13046,6 @@ msgstr "Докладніше про підпиÑÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ¾Ð¼Ñ–Ñ‚Ñ–Ð²"
msgid "Learn more about the dependency list"
msgstr "Докладніше про ÑпиÑок залежноÑтей"
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr "ДізнайтеÑÑŒ більше"
@@ -12402,6 +13073,9 @@ msgstr "Залишити проект"
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr "Залиште параметри \"Тип файлу\" та \"Метод доÑтавки\" із значеннÑми по замовчуванню."
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr "Let's Encrypt не приймає Ð°Ð´Ñ€ÐµÑ ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾Ñ— пошти з example.com"
@@ -12414,6 +13088,9 @@ msgstr "ЛіцензіÑ"
msgid "License Compliance"
msgstr "ВідповідніÑÑ‚ÑŒ ліцензіÑм"
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr "License-Check"
@@ -12424,10 +13101,10 @@ msgid "LicenseCompliance|Add license and related policy"
msgstr ""
msgid "LicenseCompliance|Allow"
-msgstr ""
+msgstr "Дозволити"
msgid "LicenseCompliance|Allowed"
-msgstr ""
+msgstr "Дозволено"
msgid "LicenseCompliance|Cancel"
msgstr "СкаÑувати"
@@ -12438,15 +13115,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr "ЛіцензіÑ"
-msgid "LicenseCompliance|License Compliance"
-msgstr "ВідповідніÑÑ‚ÑŒ ЛіцензіÑм"
-
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] ""
@@ -12518,7 +13189,7 @@ msgid "LicenseCompliance|You are about to remove the license, %{name}, from this
msgstr "Ви збираєтеÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ ліцензію %{name} із цього проекту."
msgid "LicenseManagement|Allowed"
-msgstr ""
+msgstr "Дозволено"
msgid "LicenseManagement|Denied"
msgstr ""
@@ -12589,6 +13260,9 @@ msgstr "Придбати ліцензію"
msgid "License|License"
msgstr "ЛіцензіÑ"
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr "Ви можете відновити доÑтуп до фунціональноÑÑ‚Ñ– Gold в будь-Ñкий Ñ‡Ð°Ñ ÑˆÐ»Ñхом переходу на відповідний тарифний план."
@@ -12604,6 +13278,9 @@ msgstr "Ваша ліцензіÑ"
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr "Ваш безкоштовний пробний період GitLab Ultimate завершено %{trial_ends_on}."
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr "Обмежити Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð¾Ð´Ð¸Ð½Ð¸Ñ†ÑŒ відÑÑ‚ÐµÐ¶ÐµÐ½Ð½Ñ Ñ‡Ð°Ñу до годин."
@@ -12618,7 +13295,7 @@ msgstr[2] "Показ обмежено тільки %d подіÑми"
msgstr[3] "Показ обмежено тільки %d подіÑми"
msgid "Line changes"
-msgstr ""
+msgstr "Зміни Ñ€Ñдка"
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -12627,7 +13304,7 @@ msgid "Link copied"
msgstr "ПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Ñкопійовано"
msgid "Link title"
-msgstr ""
+msgstr "Заголовок поÑиланнÑ"
msgid "Link title is required"
msgstr ""
@@ -12701,11 +13378,14 @@ msgstr "ЗавантаженнÑ..."
msgid "Loading…"
msgstr "ЗавантаженнÑ…"
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr "Регіональні налаштуваннÑ"
msgid "Location"
-msgstr ""
+msgstr "РозташуваннÑ"
msgid "Lock"
msgstr "Блокувати"
@@ -12815,12 +13495,12 @@ msgstr "ПереконайтеÑÑ, що ви його зберегли, бо в
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr "ПереконайтеÑÑ, що ви ввійшли за допомогою облікового запиÑу, Ñкому належать проекти, що потрібно імпортувати."
+msgid "Make this epic confidential"
+msgstr ""
+
msgid "Makes this issue confidential."
msgstr "Робить цю задачу конфіденційною."
-msgid "Malformed string"
-msgstr ""
-
msgid "Manage"
msgstr "Керувати"
@@ -12845,6 +13525,9 @@ msgstr "ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¼Ñ–Ñ‚ÐºÐ°Ð¼Ð¸ групи"
msgid "Manage labels"
msgstr "Керувати мітками"
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr "ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¼Ñ–Ñ‚ÐºÐ°Ð¼Ð¸ проекту"
@@ -12896,9 +13579,6 @@ msgstr "Відмітити Ñк виконано"
msgid "Mark as resolved"
msgstr "Позначити Ñк вирішене"
-msgid "Mark comment as resolved"
-msgstr "Позначити коментар Ñк вирішений"
-
msgid "Mark this issue as a duplicate of another issue"
msgstr "Позначити задачу Ñк дублікат іншої"
@@ -12908,9 +13588,6 @@ msgstr "Позначити задачу Ñк пов’Ñзану з іншою"
msgid "Markdown"
msgstr "Markdown"
-msgid "Markdown Help"
-msgstr "Довідка по Markdown"
-
msgid "Markdown enabled"
msgstr "Markdown увімкнено"
@@ -12987,7 +13664,7 @@ msgid "Max seats used"
msgstr "МакÑимальна кількіÑÑ‚ÑŒ викориÑтаних міÑць"
msgid "Maximum Users:"
-msgstr ""
+msgstr "МакÑимальна КількіÑÑ‚ÑŒ КориÑтувачів:"
msgid "Maximum allowable lifetime for personal access token (days)"
msgstr ""
@@ -13088,6 +13765,9 @@ msgstr "УчаÑники можуть будуть додані <i>КерівнÐ
msgid "Members of <strong>%{project_name}</strong>"
msgstr "УчаÑники <strong>%{project_name}</strong>"
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr "УчаÑники із доÑтупом до %{strong_start}%{group_name}%{strong_end}"
@@ -13097,9 +13777,6 @@ msgstr "УчаÑники, що очікують отримати доÑтуп д
msgid "Memory Usage"
msgstr "ВикориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼â€™ÑÑ‚Ñ–"
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr "ЗлиттÑ"
@@ -13112,6 +13789,9 @@ msgstr "Запит на злиттÑ"
msgid "Merge Request Approvals"
msgstr "Ð—Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð·Ð°Ð¿Ð¸Ñ‚Ñƒ на злиттÑ"
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr "Запити на злиттÑ"
@@ -13145,6 +13825,9 @@ msgstr "Запит на злиттÑ"
msgid "Merge request %{iid} authored by %{authorName}"
msgstr "Запит на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ %{iid} від %{authorName}"
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr "Ð—Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð·Ð°Ð¿Ð¸Ñ‚Ñ–Ð² на злиттÑ"
@@ -13193,9 +13876,18 @@ msgstr "конфлікти"
msgid "MergeConflict|origin//their changes"
msgstr "Зміни між origin та їхнім"
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 "Виникла помилка під Ñ‡Ð°Ñ Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ñ‡ÐµÑ€Ð½ÐµÑ‚ÐºÐ¸ коментарÑ."
@@ -13256,7 +13948,7 @@ msgstr "розпочато Ð¾Ð±Ð³Ð¾Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð·Ð°Ñтарілої змінÐ
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr "розпочато Ð¾Ð±Ð³Ð¾Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ¾Ð¼Ñ–Ñ‚Ñƒ %{linkStart}%{commitDisplay}%{linkEnd}"
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13274,6 +13966,9 @@ msgstr ""
msgid "Merged"
msgstr "Злито"
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr "Злиті гілки в процеÑÑ– видаленнÑ. Це може зайнÑти деÑкий Ñ‡Ð°Ñ Ð² залежноÑÑ‚Ñ– від Ñ—Ñ… кількоÑÑ‚Ñ–. Будь лаÑка, оновіть Ñторінку, щоб побачити зміни."
@@ -13295,9 +13990,6 @@ msgstr "ПовідомленнÑ"
msgid "Method"
msgstr "Метод"
-msgid "Method:"
-msgstr "Метод:"
-
msgid "Metric was successfully added."
msgstr "Метрику уÑпішно додано."
@@ -13319,21 +14011,24 @@ msgstr "Метрики"
msgid "Metrics - Grafana"
msgstr "Метрики - Grafana"
-msgid "Metrics - Influx"
-msgstr "Метрики - Influx"
-
msgid "Metrics - Prometheus"
msgstr "Метрики - Prometheus"
msgid "Metrics Dashboard"
msgstr "Панель метрик"
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
msgid "Metrics and profiling"
msgstr "Метрики та профілюваннÑ"
-msgid "Metrics for environment"
-msgstr "Метрики Ð´Ð»Ñ Ñередовища"
-
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -13355,6 +14050,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr "Додати метрику"
@@ -13413,6 +14129,12 @@ msgstr "Заголовок легенди (необов’Ñзковий)"
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr "МакÑ"
@@ -13431,6 +14153,9 @@ msgstr "Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ñ–Ñ Ð¿Ð¾ запитам Prometheus"
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13467,6 +14192,9 @@ msgstr "Ðеочікувана відповідь про розгортаннÑ
msgid "Metrics|Unit label"
msgstr "Одиниці вимірюваннÑ"
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr "ВикориÑтовуєтьÑÑ Ñк заголовок графіка"
@@ -13474,7 +14202,7 @@ msgid "Metrics|Used if the query returns a single series. If it returns multiple
msgstr "ВикориÑтовуєтьÑÑ, Ñкщо запит повертає єдину поÑлідовніÑÑ‚ÑŒ. Якщо ж він повертає декілька, Ñ—Ñ… назви берутьÑÑ Ñ–Ð· відповіді."
msgid "Metrics|Validating query"
-msgstr ""
+msgstr "Перевірка запиту"
msgid "Metrics|Values"
msgstr "ЗначеннÑ"
@@ -13531,6 +14259,63 @@ msgstr "СпиÑки етапів не доÑтупні з вашою поточ
msgid "Milestone lists show all issues from the selected milestone."
msgstr "У ÑпиÑках етапу відображаютьÑÑ Ð²ÑÑ– задачі Ð´Ð»Ñ Ð²Ð¸Ð±Ñ€Ð°Ð½Ð¾Ð³Ð¾ етапу."
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr "Етапи"
@@ -13540,6 +14325,12 @@ msgstr "Ви збираєтеÑÑ Ð¾Ñтаточно видалити етап %
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr "Ви збираєтеÑÑ Ð¾Ñтаточно видалити етап %{milestoneTitle}. Ðаразі цей етап не викориÑтовуєтьÑÑ Ð² жодних задачах або запитах на злиттÑ."
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr "Видалити етап"
@@ -13549,21 +14340,39 @@ msgstr "Видалити етап %{milestoneTitle}?"
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr "Ðе вдалоÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ етап %{milestoneTitle}"
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr "Етап %{milestoneTitle} не знайдено"
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr "ПеренеÑти %{milestoneTitle} на рівень групи?"
msgid "Milestones|Promote Milestone"
msgstr "ПеренеÑти етап"
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr "ПеренеÑÐµÐ½Ð½Ñ %{milestoneTitle} на рівень групи зробить його доÑтупним Ð´Ð»Ñ Ð²ÑÑ–Ñ… проектів в групі %{groupName}. ІÑнуючі проектні етапи з такими ж заголовками будуть об'єднані."
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr "Цю дію не можна ÑкаÑувати."
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr "Мінімальна доÑтупна пропуÑкна здатніÑÑ‚ÑŒ необхідна Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑку попередньої Ñинхронізації дзеркал."
@@ -13619,11 +14428,14 @@ msgid "MissingSSHKeyWarningLink|Add SSH key"
msgstr ""
msgid "MissingSSHKeyWarningLink|Don't show again"
-msgstr ""
+msgstr "Більше не показувати"
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr "СкаÑувати"
@@ -13679,7 +14491,7 @@ msgid "More information"
msgstr "Детальніше"
msgid "More information and share feedback"
-msgstr ""
+msgstr "Ðадати більше інформації Ñ– поділитиÑÑ Ð²Ñ–Ð´Ð³ÑƒÐºÐ¾Ð¼"
msgid "More information is available|here"
msgstr "тут"
@@ -13738,6 +14550,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr "Кілька дошок обговореннÑ"
@@ -13747,6 +14562,9 @@ msgstr "Знайдено декілька типів моделей: %{model_typ
msgid "Multiple uploaders found: %{uploader_types}"
msgstr "Знайдено декілька завантажувачів: %{uploader_types}"
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13759,9 +14577,6 @@ msgstr "Ім’Ñ"
msgid "Name has already been taken"
msgstr "Ð†Ð¼â€™Ñ Ð²Ð¶Ðµ викориÑтовуєтьÑÑ"
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr "Ðазвіть нову мітку"
@@ -13771,9 +14586,6 @@ msgstr "Ім’Ñ:"
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr "ПроÑÑ‚Ñ–Ñ€ імен: %{namespace}"
-
msgid "Namespaces to index"
msgstr "ПроÑтори імен Ð´Ð»Ñ Ñ–Ð½Ð´ÐµÐºÑуваннÑ"
@@ -13802,11 +14614,59 @@ msgid "Need help?"
msgstr "Потрібна допомога?"
msgid "Needs attention"
-msgstr ""
+msgstr "Потребує уваги"
msgid "Network"
msgstr "Мережа"
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr "Ðіколи"
@@ -13838,6 +14698,9 @@ msgstr[1] "Ðові задачі"
msgstr[2] "Ðових задач"
msgstr[3] "Ðових задач"
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13857,7 +14720,7 @@ msgid "New Pipeline Schedule"
msgstr "Ðовий розклад Конвеєра"
msgid "New Project"
-msgstr "Ðовий Проект"
+msgstr ""
msgid "New Snippet"
msgstr "Ðовий Ñніпет"
@@ -13904,6 +14767,9 @@ msgstr "Ðова задача"
msgid "New issue title"
msgstr "Ðазва нової задачі"
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr "Ðова мітка"
@@ -13920,13 +14786,13 @@ msgid "New pipelines will cancel older, pending pipelines on the same branch"
msgstr "Ðові конвеєри ÑкаÑують Ñтарі, що очікують на тій же гілці"
msgid "New project"
-msgstr "Ðовий проект"
+msgstr ""
msgid "New release"
msgstr "Ðовий реліз"
msgid "New requirement"
-msgstr ""
+msgstr "Ðова вимога"
msgid "New runners registration token has been generated!"
msgstr "Згенеровано новий реєÑтраційний токен runner-ів!"
@@ -13961,6 +14827,9 @@ msgstr "За замовчуваннÑм щойно зареєÑтровані к
msgid "Next"
msgstr "Далі"
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13979,18 +14848,9 @@ msgstr "ВідÑутній %{header} у цьому запиті."
msgid "No %{providerTitle} repositories found"
msgstr "Ðе знайдено репозиторіїв %{providerTitle}"
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr "Ðемає епіка"
-msgid "No Label"
-msgstr "Без Мітки"
-
-msgid "No Milestone"
-msgstr "Етап відÑутній"
-
msgid "No Scopes"
msgstr ""
@@ -14055,7 +14915,7 @@ msgid "No due date"
msgstr "Ðемає"
msgid "No endpoint provided"
-msgstr ""
+msgstr "ВідÑÑƒÑ‚Ð½Ñ Ñ‚Ð¾Ñ‡ÐºÐ° підключеннÑ"
msgid "No errors to display."
msgstr "Ðемає помилок Ð´Ð»Ñ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ."
@@ -14081,12 +14941,18 @@ msgstr "Ðе знайдено жодного файлу."
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr "Ðемає журналу завданнÑ"
msgid "No jobs to show"
msgstr "Ðемає завдань Ð´Ð»Ñ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ"
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr "Ðемає міток з таким іменем або опиÑом"
@@ -14097,10 +14963,10 @@ msgid "No licenses found."
msgstr "Ðе знайдено ліцензій."
msgid "No matches found"
-msgstr ""
+msgstr "Збігів не знайдено"
msgid "No matching labels"
-msgstr ""
+msgstr "Ðемає відповідних міток"
msgid "No matching results"
msgstr "Ðемає відповідних результатів"
@@ -14111,6 +14977,9 @@ msgstr "Ðе знайдено жодного запиту на злиттÑ"
msgid "No messages were logged"
msgstr "Ðемає повідомлень у журналі"
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr "Ðемає етапів Ð´Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ñƒ"
@@ -14163,7 +15032,7 @@ msgid "No test coverage"
msgstr ""
msgid "No thanks, don't show this again"
-msgstr ""
+msgstr "ÐÑ–, дÑкую, більше не показуйте мені цього"
msgid "No vulnerabilities present"
msgstr "ВразливоÑÑ‚Ñ– відÑутні"
@@ -14246,6 +15115,9 @@ msgstr "Примітка"
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 "Зауважте, що це Ð·Ð°Ð¿Ñ€Ð¾ÑˆÐµÐ½Ð½Ñ Ð±ÑƒÐ»Ð¾ надіÑлано на %{mail_to_invite_email}, але ви увійшли Ñк %{link_to_current_user} з електронною поштою %{mail_to_current_user}."
@@ -14270,6 +15142,9 @@ msgstr "Ви впевнені, що хочете ÑкаÑувати цей коÐ
msgid "Notes|Collapse replies"
msgstr "Згорнути відповіді"
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr "Показати вÑÑŽ активніÑÑ‚ÑŒ"
@@ -14283,7 +15158,7 @@ msgid "Notes|This comment has changed since you started editing, please review t
msgstr "Цей коментар було змінено піÑÐ»Ñ Ñ‚Ð¾Ð³Ð¾, Ñк ви його почали редагувати. Будь лаÑка, переглÑньте %{open_link}оновлений коментар%{close_link}, щоб переконатиÑÑ Ð² тому, що інформацію не було втрачено"
msgid "Nothing found…"
-msgstr ""
+msgstr "Ðічого не знайдено…"
msgid "Nothing to preview."
msgstr "Дані Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду відÑутні."
@@ -14384,11 +15259,17 @@ msgstr "лиÑÑ‚."
msgid "November"
msgstr "лиÑтопад"
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
+msgstr "Тепер ви можете отримати доÑтуп до навігаційних вкладок запиту на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð²Ð³Ð¾Ñ€Ñ–, де Ñ—Ñ… легше знайти."
+
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
msgstr ""
msgid "Number of %{itemTitle}"
-msgstr ""
+msgstr "КількіÑÑ‚ÑŒ %{itemTitle}"
msgid "Number of Elasticsearch replicas"
msgstr "КількіÑÑ‚ÑŒ реплік Elasticsearch"
@@ -14412,7 +15293,7 @@ msgid "Number of commits per MR"
msgstr "КількіÑÑ‚ÑŒ комітів на запит на злиттÑ"
msgid "Number of employees"
-msgstr ""
+msgstr "КількіÑÑ‚ÑŒ Ñпівробітників"
msgid "Number of files touched"
msgstr "КількіÑÑ‚ÑŒ змінених файлів"
@@ -14436,7 +15317,7 @@ msgid "OfSearchInADropdown|Filter"
msgstr "Фільтр"
msgid "Oh no!"
-msgstr ""
+msgstr "О ні!"
msgid "Ok let's go"
msgstr "Гаразд, уперед"
@@ -14453,6 +15334,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr "ОзнайомленнÑ"
@@ -14462,14 +15352,11 @@ msgstr "ПіÑÐ»Ñ Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚Ñƒ, репозиторії можуть бути
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr "ПіÑÐ»Ñ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð·Ð²â€™Ñзок форку не може бути відновлений Ñ– ви більше не зможете відправлÑти запити на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ñƒ вихідний проект."
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 "ПіÑÐ»Ñ Ñ‚Ð¾Ð³Ð¾, Ñк екÑпортований файл буде готовий, ви отримаєте ÑÐ¿Ð¾Ð²Ñ–Ñ‰ÐµÐ½Ð½Ñ ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾ÑŽ поштою із поÑиланнÑм Ð´Ð»Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð°Ð±Ð¾ можете завантажити його з цієї Ñторінки."
msgid "Once you confirm and press \"Reduce project visibility\":"
-msgstr ""
+msgstr "ПіÑÐ»Ñ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ñ‚Ð° натиÑÐ½ÐµÐ½Ð½Ñ \"Зменшити видиміÑÑ‚ÑŒ проєкту\":"
msgid "One more item"
msgid_plural "%d more items"
@@ -14482,7 +15369,7 @@ msgid "One or more groups that you don't have access to."
msgstr "Одна або декілька груп, до Ñких ви не маєте доÑтупу."
msgid "One or more of you personal access tokens were revoked"
-msgstr ""
+msgstr "Один або декілька ваших токенів оÑобиÑтого доÑтупу були анульовані"
msgid "One or more of your Bitbucket projects cannot be imported into GitLab directly because they use Subversion or Mercurial for version control, rather than Git."
msgstr "Один або декілька ваших проектів Bitbucket не можна імпортувати безпоÑередньо в GitLab, оÑкільки вони викориÑтовують Subversion або Mercurial Ð´Ð»Ñ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŽ верÑій заміÑÑ‚ÑŒ Git."
@@ -14494,7 +15381,7 @@ msgid "One or more of your dependency files are not supported, and the dependenc
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 / Silver and above can see Value Stream Analytics."
msgstr ""
@@ -14532,8 +15419,8 @@ msgstr "Тільки учаÑники проекту можуть залишат
msgid "Only project members will be imported. Group members will be skipped."
msgstr "Лише учаÑника проекту будуть імпортовані. УчаÑники групи будуть пропущені."
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
-msgstr "Тільки кориÑтувачі із адреÑою електронної пошти з цього домену можуть бути додані в групу.<br>Ðаприклад: <code>gitlab.com</code>. ДеÑків загальні домени викориÑтовувати заборонено. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
+msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
msgstr "Лише \"Репортер\" та більш виÑокі ролі на рівнÑÑ… Premium / Silver та вище можуть переглÑдати аналітику продуктивноÑÑ‚Ñ–."
@@ -14577,8 +15464,8 @@ msgstr ""
msgid "Opened"
msgstr "Відкрито"
-msgid "Opened MR"
-msgstr "Відкритий запит на злиттÑ"
+msgid "Opened MRs"
+msgstr ""
msgid "Opened issues"
msgstr "Відкриті задачі"
@@ -14592,6 +15479,9 @@ msgstr "ВідкриваєтьÑÑ Ñƒ новому вікні"
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr "ÐžÐ¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐ¸Ð»Ð°ÑÑ Ð½ÐµÐ²Ð´Ð°Ð»Ð¾. Перевірте журнал pod'а %{pod_name} Ð´Ð»Ñ Ð±Ñ–Ð»ÑŒÑˆ детальної інформації."
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr "ÐžÐ¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð¿ÐµÑ€ÐµÐ²Ð¸Ñ‰Ð¸Ð»Ð° ліміт очікуваннÑ. Перевірте журнал pod'а %{pod_name} Ð´Ð»Ñ Ð±Ñ–Ð»ÑŒÑˆ детальної інформації."
@@ -14622,7 +15512,7 @@ msgstr "Панель ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñми міÑтить ін
msgid "Optional"
msgstr "Ðеобов'Ñзково"
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14670,6 +15560,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14688,6 +15581,9 @@ msgstr "Ті, що належать мені"
msgid "Owner"
msgstr "ВлаÑник"
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14709,6 +15605,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr "Пакет був видалений"
@@ -14791,11 +15693,14 @@ msgid "PackageRegistry|If you haven't already done so, you will need to add the
msgstr ""
msgid "PackageRegistry|If you haven't already done so, you will need to add the below to your %{codeStart}pom.xml%{codeEnd} file."
-msgstr ""
+msgstr "Якщо ви ще не зробили цього, вам потрібно буде додати розміщене нижче в Ñвій файл %{codeStart}pom.xml%{codeEnd}."
msgid "PackageRegistry|Installation"
msgstr "Ð’ÑтановленнÑ"
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr "ДізнайтеÑÑ Ñк %{noPackagesLinkStart}публікувати та ділитиÑÑ Ð²Ð°ÑˆÐ¸Ð¼Ð¸ пакетами%{noPackagesLinkEnd} через GitLab."
@@ -14814,6 +15719,9 @@ msgstr "Maven XML"
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14830,7 +15738,7 @@ msgid "PackageRegistry|Published to the repository at %{timestamp}"
msgstr ""
msgid "PackageRegistry|PyPi"
-msgstr ""
+msgstr "PyPi"
msgid "PackageRegistry|Registry Setup"
msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ€ÐµÑ”Ñтру"
@@ -14844,23 +15752,38 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr "Пакетів ще немає"
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr "Виникла проблема при отриманні інформації про цей пакет."
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr "Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ пакет"
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
-msgstr "Ви збираєтеÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ <b>%{packageName}</b>, Ñ– Ñ†Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ñ” незворотньою. Ви впевнені?"
+msgid "PackageRegistry|Upcoming package managers"
+msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
-msgstr "Ви збираєтеÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ верÑÑ–ÑŽ %{boldStart}%{version}%{boldEnd} %{boldStart}%{name}%{boldEnd}. Ви впевнені?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
+msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
msgstr ""
@@ -14869,7 +15792,7 @@ msgid "PackageRegistry|npm"
msgstr "npm"
msgid "PackageRegistry|published by %{author}"
-msgstr ""
+msgstr "опубліковано %{author}"
msgid "PackageRegistry|yarn"
msgstr "yarn"
@@ -14887,11 +15810,14 @@ msgid "PackageType|NuGet"
msgstr "NuGet"
msgid "PackageType|PyPi"
-msgstr ""
+msgstr "PyPi"
msgid "Packages"
msgstr "Пакети"
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr "Сторінку не знайдено"
@@ -14950,7 +15876,7 @@ msgid "Part of merge request changes"
msgstr "ЧаÑтина змін у запиті на злиттÑ"
msgid "Partial token for reference only"
-msgstr ""
+msgstr "ЧаÑтковий токен тільки Ð´Ð»Ñ Ð¿Ð¾ÑиланнÑ"
msgid "Participants"
msgstr "УчаÑники"
@@ -14979,6 +15905,9 @@ msgstr "Пароль змінено уÑпішно"
msgid "Password was successfully updated. Please login with it"
msgstr "Пароль уÑпішно оновлено. Будь лаÑка, увійдіть за допомогою нього"
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr "ПроÑтрочені"
@@ -14997,6 +15926,9 @@ 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'. Don't use your private SSH key."
msgstr "Ð’Ñтавте Ñвій публічний ключ SSH, Ñкий зазвичай знаходитьÑÑ Ñƒ файлі \"~/.ssh/id_ed25519.pub\" або \"~/.ssh/id_rsa.pub\" Ñ– починаєтьÑÑ Ñ–Ð· \"ssh-ed25519\" або \"ssh-rsa\". Ðе викориÑтовуйте Ñвій приватний ключ."
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr "ШлÑÑ…"
@@ -15004,7 +15936,7 @@ msgid "Path:"
msgstr "ШлÑÑ…:"
msgid "Paths can contain wildcards, like */welcome"
-msgstr ""
+msgstr "ШлÑхи можуть міÑтити шаблони, наприклад */welcome"
msgid "Pause"
msgstr "Призупинити"
@@ -15039,9 +15971,15 @@ msgstr "Виконати звичайні операції на проекті G
msgid "Performance optimization"
msgstr "ÐžÐ¿Ñ‚Ð¸Ð¼Ñ–Ð·Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾Ð´ÑƒÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚Ñ–"
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr "Завантажити"
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -15063,9 +16001,6 @@ msgstr "лог"
msgid "Permissions"
msgstr "Права доÑтупу"
-msgid "Permissions Help"
-msgstr "Довідка по дозволам"
-
msgid "Permissions, LFS, 2FA"
msgstr "Дозволи, LFS, 2FA"
@@ -15087,9 +16022,6 @@ msgstr "Задачі Phabricator"
msgid "Pick a name"
msgstr "Виберіть ім'Ñ"
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr "Виберіть назву заÑтоÑунку Ñ– ми надамо вам унікальний %{type} токен."
-
msgid "Pin code"
msgstr "PIN-код"
@@ -15112,7 +16044,7 @@ msgid "Pipeline minutes quota"
msgstr "Квота хвилин Ð´Ð»Ñ ÐºÐ¾Ð½Ð²ÐµÑ”Ñ€Ñ–Ð²"
msgid "Pipeline subscriptions"
-msgstr ""
+msgstr "ПідпиÑки на конвеєр"
msgid "Pipeline triggers"
msgstr "Тригери конвеєру"
@@ -15121,7 +16053,7 @@ msgid "Pipeline: %{status}"
msgstr "Конвеєр: %{status}"
msgid "PipelineCharts|CI / CD Analytics"
-msgstr ""
+msgstr "CI / CD аналітика"
msgid "PipelineCharts|Failed:"
msgstr "Ðевдалі:"
@@ -15187,10 +16119,10 @@ msgid "Pipelines emails"
msgstr "Електронні лиÑти конвеєрів"
msgid "Pipelines for last month (%{oneMonthAgo} - %{today})"
-msgstr ""
+msgstr "Конвеєри за оÑтанній міÑÑць (%{oneMonthAgo} - %{today})"
msgid "Pipelines for last week (%{oneWeekAgo} - %{today})"
-msgstr ""
+msgstr "Конвеєри за оÑтанній тиждень (%{oneWeekAgo} - %{today})"
msgid "Pipelines for last year"
msgstr "Конвеєри за оÑтанній рік"
@@ -15198,6 +16130,9 @@ msgstr "Конвеєри за оÑтанній рік"
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr "Конвеєри Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñ‚Ñ–Ð² на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð½Ð°Ð»Ð°ÑˆÑ‚Ð¾Ð²Ð°Ð½Ð¾. Відділений конвеєр виконуєтьÑÑ Ð² контекÑÑ‚Ñ– запиту на злиттÑ, але не в контекÑÑ‚Ñ– результату злиттÑ. ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ в документації про конвеєери Ð´Ð»Ñ Ñ€ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ñ–Ð² злиттÑ."
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ¾Ð½Ð²ÐµÑ”Ñ€Ñ–Ð² Ð´Ð»Ñ \"%{project_name}\" уÑпішно оновлено."
@@ -15217,7 +16152,7 @@ msgid "Pipelines|Clear Runner Caches"
msgstr "ОчиÑтити кеш Runner'ів"
msgid "Pipelines|Continuous Integration can help catch bugs by running your tests automatically, while Continuous Deployment can help you deliver code to your product environment."
-msgstr "Безперервно Ñ–Ð½Ñ‚ÐµÐ³Ñ€Ð°Ñ†Ñ–Ñ Ð´Ð¾Ð¿Ð¾Ð¼Ð°Ð³Ð°Ñ” знаходити помилки шлÑхом автоматичного запуÑку теÑтів, а безперервне Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ â€” вÑтановлювати код на цільове Ñеридовище."
+msgstr "Безперервна Ñ–Ð½Ñ‚ÐµÐ³Ñ€Ð°Ñ†Ñ–Ñ Ð´Ð¾Ð¿Ð¾Ð¼Ð°Ð³Ð°Ñ” знаходити помилки шлÑхом автоматичного запуÑку теÑтів, а безперервне Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ â€” вÑтановлювати код на цільове Ñередовище."
msgid "Pipelines|Get started with Pipelines"
msgstr "Розпочати роботу з Конвеєрами"
@@ -15258,15 +16193,24 @@ msgstr "Цей проект в даний Ñ‡Ð°Ñ Ð½Ðµ налаштований Ð
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr "Коміт"
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
-msgstr "Ðе вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ ÑÑ‚Ð°Ñ‚ÑƒÑ ÐºÐ¾Ð½Ð²ÐµÑ”Ñ€Ð°. Ð”Ð»Ñ ÑƒÑÑƒÐ½ÐµÐ½Ð½Ñ Ð½ÐµÐ¿Ð¾Ð»Ð°Ð´Ð¾Ðº, прочитайте %{linkStart}документацію%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
+msgstr ""
msgid "Pipeline|Coverage"
msgstr "ПокриттÑ"
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr "Дата"
@@ -15279,30 +16223,54 @@ msgstr "ТриваліÑÑ‚ÑŒ"
msgid "Pipeline|Existing branch name or tag"
msgstr "ІÑнуюче Ñ–Ð¼â€™Ñ Ð³Ñ–Ð»ÐºÐ¸ або тег"
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr "Ключ"
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr "Конвеєр ланцюжка змін"
msgid "Pipeline|Merged result pipeline"
msgstr "Конвеєр результату злиттÑ"
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr "Конвеєр"
msgid "Pipeline|Pipelines"
msgstr "Конвеєр"
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr "ЗапуÑтити Конвеєр"
msgid "Pipeline|Run for"
msgstr "ЗапуÑтити длÑ"
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr "Пошук гілки"
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr "Вкажіть Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð¼Ñ–Ð½Ð½Ð¸Ñ…, Ñкі будуть викориÑтані в цьому запуÑку. Інакше будуть викориÑтані значеннÑ, вказані в %{settings_link}."
@@ -15318,6 +16286,9 @@ msgstr "Зупинити конвеєр"
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr "Зупинити конвеєр #%{pipelineId}?"
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr "Запущено"
@@ -15354,6 +16325,12 @@ msgstr "Програмне Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿
msgid "Plain diff"
msgstr "ПроÑте порівнÑннÑ"
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr "PlantUML"
@@ -15409,7 +16386,7 @@ msgid "Please create a username with only alphanumeric characters."
msgstr "Будь лаÑка, Ñтворіть ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача лише із буквено-цифрових Ñимволів."
msgid "Please create an index before enabling indexing"
-msgstr ""
+msgstr "Будь лаÑка, Ñтворіть індекÑ, перш ніж увімкнути індекÑуваннÑ"
msgid "Please enable and migrate to hashed storage to avoid security issues and ensure data integrity. %{migrate_link}"
msgstr "Будь лаÑка, активуйте Ñ– мігруйте на хешоване Ñховище, щоб уникнути проблем із безпекою та забезпечити ціліÑніÑÑ‚ÑŒ даних. %{migrate_link}"
@@ -15447,6 +16424,9 @@ msgstr "Зверніть увагу, що Ñ†Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð° не Ñ” чаÑÑ‚
msgid "Please provide a name"
msgstr "Будь лаÑка, задайте ім’Ñ"
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr "Будь лаÑка, вкажіть дійÑну e-mail адреÑу."
@@ -15522,6 +16502,9 @@ msgstr "Pod’и у викориÑтанні"
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr "ÐалаштуваннÑ"
@@ -15612,6 +16595,9 @@ msgstr "ВикориÑтовувати відноÑний чаÑ"
msgid "Press %{key}-C to copy"
msgstr "ÐатиÑніть %{key}-C, щоб Ñкопіювати"
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr "Заборонити Ð´Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ Ð½Ð¾Ð²Ð¸Ñ… учаÑників до членÑтва в цій групі"
@@ -15625,7 +16611,7 @@ msgid "Prevent environment from auto-stopping"
msgstr ""
msgid "Prevent users from changing their profile name"
-msgstr ""
+msgstr "Заборонити кориÑтувачам змінювати ім'Ñ Ñвого профілю"
msgid "Prevent users from modifying merge request approvers list"
msgstr ""
@@ -15648,6 +16634,9 @@ msgstr "Попередній переглÑд кориÑного навантаÐ
msgid "Previous Artifacts"
msgstr "Попередні артефакти"
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15867,9 +16856,6 @@ msgstr "Повне ім'Ñ"
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr "ІмітуваннÑ"
-
msgid "Profiles|Include private contributions on my profile"
msgstr "Включити приватні внеÑки до мого профілю"
@@ -15915,9 +16901,6 @@ msgstr "ОрганізаціÑ"
msgid "Profiles|Path"
msgstr "ШлÑÑ…"
-msgid "Profiles|Personal Access"
-msgstr "ПерÑональний доÑтуп"
-
msgid "Profiles|Position and size your new avatar"
msgstr "Спозиціонуйте ваш аватар та задайте його розмір"
@@ -16062,12 +17045,6 @@ msgstr "Ваш ÑтатуÑ"
msgid "Profiles|e.g. My MacBook key"
msgstr "наприклад, мій ключ MacBook"
-msgid "Profiles|impersonation"
-msgstr "ІмітуваннÑ"
-
-msgid "Profiles|personal access"
-msgstr "перÑональний доÑтуп"
-
msgid "Profiles|username"
msgstr "ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача"
@@ -16078,7 +17055,7 @@ msgid "Profiles|your account"
msgstr "ваш обліковий запиÑ"
msgid "Profile|%{job_title} at %{organization}"
-msgstr ""
+msgstr "%{job_title} в %{organization}"
msgid "Profiling - Performance bar"
msgstr "ÐŸÑ€Ð¾Ñ„Ñ–Ð»ÑŽÐ²Ð°Ð½Ð½Ñ - панель продуктивноÑÑ‚Ñ–"
@@ -16098,6 +17075,9 @@ msgstr "Проект \"%{name}\" більше не доÑтупний. Щоб п
msgid "Project %{project_repo} could not be found"
msgstr "Проект %{project_repo} не знайдено"
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr "Проект \"%{project_name}\" імпортуєтьÑÑ."
@@ -16119,6 +17099,9 @@ msgstr "Проект '%{project_name}' уÑпішно оновлено."
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr "Проєкт \"%{project_name}\" буде видалено %{date}"
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -16149,6 +17132,9 @@ msgstr "Ðватар проекту"
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr "Проект не може бути Ñпільним із групою в Ñку він входить або з одним з Ñ—Ñ— предків."
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñƒ включно із ÑервіÑами"
@@ -16171,10 +17157,10 @@ msgid "Project export has been deleted."
msgstr "ЕкÑпорт проекту видалений."
msgid "Project export link has expired. Please generate a new export from your project settings."
-msgstr "ЗакінчивÑÑ Ñ‚ÐµÑ€Ð¼Ñ–Ð½ дії поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° проект. Створіть новий екÑпорт в ваших наÑтройках проекту."
+msgstr "ЗакінчивÑÑ Ñ‚ÐµÑ€Ð¼Ñ–Ð½ дії поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° проєкт. Створіть новий екÑпорт в ваших налаштуваннÑÑ… проєкту."
-msgid "Project export started. A download link will be sent by email."
-msgstr "Розпочато екÑпорт проекту. ПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð´Ð»Ñ ÑÐºÐ°Ñ‡ÑƒÐ²Ð°Ð½Ð½Ñ Ð±ÑƒÐ´Ðµ надіÑлана електронною поштою."
+msgid "Project export started. A download link will be sent by email and made available on this page."
+msgstr ""
msgid "Project has too many %{label_for_message} to search"
msgstr "Ð’ проекті занадто багато %{label_for_message} Ð´Ð»Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ"
@@ -16182,6 +17168,9 @@ msgstr "Ð’ проекті занадто багато %{label_for_message} длÑ
msgid "Project members"
msgstr "УчаÑники проекту"
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr "Ðазва проекту"
@@ -16296,9 +17285,6 @@ msgstr "Коментар"
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr "ОÑтанні зміни"
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr "Виконати звичайні операції на проекті GitLab: %{project_name}"
@@ -16464,6 +17450,9 @@ msgstr "Репозиторій"
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr "ДілітьÑÑ Ñ„Ñ€Ð°Ð³Ð¼ÐµÐ½Ñ‚Ð°Ð¼Ð¸ коду з іншими за межами репозиторію Git"
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr "Показувати поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð´Ð»Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ‡Ð¸ переглÑду запиту на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð¿Ñ€Ð¸ відправці із командного Ñ€Ñдка"
@@ -16509,6 +17498,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr "Коли з’ÑвлÑÑŽÑ‚ÑŒÑÑ ÐºÐ¾Ð½Ñ„Ð»Ñ–ÐºÑ‚Ð¸, кориÑтувачу даєтьÑÑ Ð¼Ð¾Ð¶Ð»Ð¸Ð²Ñ–ÑÑ‚ÑŒ виконати rebase"
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr "Вікі"
@@ -16659,6 +17651,9 @@ msgstr "ПуÑтий проект"
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr "ЗвернітьÑÑ Ð´Ð¾ адмініÑтратора Ð´Ð»Ñ Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ— варіантів імпорту Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ проекту."
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr "Створити із шаблону"
@@ -16696,7 +17691,7 @@ msgid "ProjectsNew|Want to house several dependent projects under the same names
msgstr "Хочете розміÑтити декілька залежних проектів в одному проÑторі імен? %{link_start}Створіть групу.%{link_end}"
msgid "Prometheus"
-msgstr ""
+msgstr "Prometheus"
msgid "PrometheusAlerts|%{count} alerts applied"
msgstr "%{count} попереджень заÑтоÑовано"
@@ -16752,12 +17747,18 @@ msgstr "Ðвтоматична конфігураціÑ"
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr "Ðвтоматично розгортайте та налаштовуйте Prometheus на ваші клаÑтери Ð´Ð»Ñ Ð¼Ð¾Ð½Ñ–Ñ‚Ð¾Ñ€Ð¸Ð½Ð³Ñƒ Ñередовищ проекту"
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr "Загальні метрики"
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr "Загальні метрики автоматично збираютьÑÑ Ð½Ð° оÑнові набору метрик від популÑрних екÑпортерів."
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr "ВлаÑні метрики"
@@ -16833,9 +17834,6 @@ msgstr "Перетворити задачу на епік"
msgid "Promote these project milestones into a group milestone."
msgstr "ПеренеÑти ці проектні етапи на рівень групи."
-msgid "Promote to Group Milestone"
-msgstr "ПеренеÑти Етап на рівень групи"
-
msgid "Promote to group label"
msgstr "ПеренеÑти мітку на рівень групи"
@@ -16854,30 +17852,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr "Більше не показувати це"
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 "Епіки дозволÑÑŽÑ‚ÑŒ вам більш ефективно та з меншими зуÑиллÑми керувати портфелÑми проектів, відÑлідковуючи групи Ñпоріднених задач у етапах та проектах."
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr "ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ"
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr "ПереглÑнути інші можливоÑÑ‚Ñ– в %{subscription_link_start}плані bronze%{subscription_link_end}"
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr "Ð¦Ñ Ñ„ÑƒÐ½ÐºÑ†Ñ–Ñ Ð·Ð°Ð±Ð»Ð¾ÐºÐ¾Ð²Ð°Ð½Ð°."
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr "Перейти на вищий тарифний план"
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr "ÐÐ°Ð´Ð°Ð½Ð½Ñ Ð²Ð°Ð³Ð¸ вашій задачі"
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 "Якщо у Ð²Ð°Ñ Ð±Ð°Ð³Ð°Ñ‚Ð¾ задач, важко зрозуміти загальну картину. Додаючи вагу до Ñвоїх задач, ви матимете краще уÑÐ²Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ цінніÑÑ‚ÑŒ кожної з них а також необхідні зуÑиллÑ, кошти та чаÑ. Таким чином ними краще керувати."
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr "Пропонувати кориÑтувачам завантажувати Ñвої ключі SSH"
@@ -16996,7 +18048,7 @@ msgid "Protip:"
msgstr "Підказка:"
msgid "Protocol"
-msgstr ""
+msgstr "Протокол"
msgid "Provider"
msgstr "ПоÑтачальник"
@@ -17013,9 +18065,6 @@ msgstr "Публічна — група та вÑÑ– публічні проекÑ
msgid "Public - The project can be accessed without any authentication."
msgstr "Публічний — проект может переглÑдатиÑÑ Ð±ÐµÐ· автентифікації."
-msgid "Public Access Help"
-msgstr "Довідка по публічному доÑтупу"
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr "Публічні ключі Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ (%{deploy_keys_count})"
@@ -17025,6 +18074,12 @@ msgstr "Публічні конвеєри"
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr "Отримати (pull)"
@@ -17127,6 +18182,9 @@ msgstr "Запит є правильним"
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr "Швидкі дії можна викориÑтовувати в опиÑах задач Ñ– коментарÑÑ…."
@@ -17136,9 +18194,6 @@ msgstr "Швидкий діапазон"
msgid "README"
msgstr "ІнÑÑ‚Ñ€ÑƒÐºÑ†Ñ–Ñ (README)"
-msgid "Rake Tasks Help"
-msgstr "Довідка по завданнÑм Rake"
-
msgid "Raw blob request rate limit per minute"
msgstr "Ліміт чаÑтоти запиту бінарних даних на хвилину"
@@ -17175,9 +18230,6 @@ msgstr "ВідбуваєтьÑÑ rebase"
msgid "Receive alerts from manually configured Prometheus servers."
msgstr "Отримувати Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð¶ÐµÐ½Ð½Ñ Ð²Ñ–Ð´ налаштованого вручну Ñервера Prometheus."
-msgid "Receive alerts on GitLab from any source"
-msgstr "Отримувати ÑÐ¿Ð¾Ð²Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð² GitLab із будь-Ñкого джерела"
-
msgid "Receive notifications about your own activity"
msgstr "Отримувати ÑÐ¿Ð¾Ð²Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ влаÑну активніÑÑ‚ÑŒ"
@@ -17275,6 +18327,21 @@ msgstr "ЗареєÑтрувати за допомогою двофакторнÐ
msgid "Registration"
msgstr "РеєÑтраціÑ"
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr "Пов’Ñзані розгорнуті Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ (Jobs)"
@@ -17294,7 +18361,7 @@ msgid "Related merge requests"
msgstr "Пов'Ñзані запити на злиттÑ"
msgid "Relates to"
-msgstr ""
+msgstr "ВідноÑитьÑÑ Ð´Ð¾"
msgid "Release"
msgid_plural "Releases"
@@ -17321,11 +18388,23 @@ msgstr "ÐžÐ¿Ð¸Ñ Ñ€ÐµÐ»Ñ–Ð·Ñƒ:"
msgid "Release title"
msgstr "Ðазва релізу"
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr "Релізи"
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 ""
+msgstr "Релізи базуютьÑÑ Ð½Ð° тегах Git та відзначають певні точки в Ñ–Ñторії розвитку проєкту. Вони можуть міÑтити інформацію про тип змін а також можуть надати бінарні файли, наприкад, Ñкладені верÑÑ–Ñ— програмного забезпеченнÑ."
msgid "Releases are based on Git tags. We recommend tags that use semantic versioning, for example %{codeStart}v1.0%{codeEnd}, %{codeStart}v2.0-pre%{codeEnd}."
msgstr ""
@@ -17342,6 +18421,9 @@ msgstr "Проблема при збереженні деталей релізу
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr "Запам'Ñтати мене"
@@ -17379,7 +18461,7 @@ msgid "Remove approvers?"
msgstr "Видалити затверджуючих оÑіб?"
msgid "Remove asset link"
-msgstr ""
+msgstr "Видалити поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° реÑурÑ"
msgid "Remove assignee"
msgstr "Видалити виконавцÑ"
@@ -17411,6 +18493,12 @@ msgstr "Видалити із епіка"
msgid "Remove group"
msgstr "Видалити групу"
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17418,13 +18506,13 @@ msgid "Remove milestone"
msgstr "Видалити етап"
msgid "Remove node"
-msgstr ""
+msgstr "Видалити вузол"
msgid "Remove parent epic from an epic"
msgstr "Видалити батьківÑький епік із епіка"
msgid "Remove primary node"
-msgstr ""
+msgstr "Видалити оÑновний вузол"
msgid "Remove priority"
msgstr "Видалити пріоритет"
@@ -17433,7 +18521,7 @@ msgid "Remove project"
msgstr "Видалити проект"
msgid "Remove secondary node"
-msgstr ""
+msgstr "Видалити вторинний вузол"
msgid "Remove spent time"
msgstr "Видалити витрачений чаÑ"
@@ -17453,6 +18541,9 @@ msgstr "Видалено %{assignee_text} %{assignee_references}."
msgid "Removed %{epic_ref} from child epics."
msgstr "Видалено %{epic_ref} із підепіків."
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr "Видалено %{label_references} %{label_text}."
@@ -17492,6 +18583,9 @@ msgstr "ВидалÑÑ” %{assignee_text} %{assignee_references}."
msgid "Removes %{epic_ref} from child epics."
msgstr "ВидалÑÑ” %{epic_ref} з дочірних епіків."
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr "ВидалÑÑ” %{label_references} %{label_text}."
@@ -17517,10 +18611,10 @@ msgid "Removes time estimate."
msgstr "ВидалÑÑ” запланований чаÑ."
msgid "Removing a project places it into a read-only state until %{date}, at which point the project will be permanantly removed. Are you ABSOLUTELY sure?"
-msgstr ""
+msgstr "Ð’Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ñ”ÐºÑ‚Ñƒ зробить його доÑтупним лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð´Ð¾ %{date}, піÑÐ»Ñ Ñ‡Ð¾Ð³Ð¾ проєкт буде оÑтаточно видалений. Ви ÐБСОЛЮТÐО впевнені?"
msgid "Removing a project places it into a read-only state until %{date}, at which point the project will be permanently removed."
-msgstr ""
+msgstr "Ð’Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ñ”ÐºÑ‚Ñƒ зробить його доÑтупним лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð´Ð¾ %{date}, піÑÐ»Ñ Ñ‡Ð¾Ð³Ð¾ проєкт буде оÑтаточно видалений."
msgid "Removing license…"
msgstr "Ð’Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð»Ñ–Ñ†ÐµÐ½Ð·Ñ–Ñ—â€¦"
@@ -17543,6 +18637,9 @@ msgstr "Перейменувати/ПереміÑтити"
msgid "Reopen"
msgstr "Повторне відкриттÑ"
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr "Повторне Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ ÐµÐ¿Ñ–ÐºÑƒ"
@@ -17573,6 +18670,9 @@ msgstr "Замінено вÑÑ– мітки з %{label_references} %{label_text}.
msgid "Replaces the clone URL root."
msgstr "Замінює кореневу URL-адреÑу Ð´Ð»Ñ ÐºÐ»Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ."
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr "ВідповіÑти по електнонній пошті"
@@ -17588,7 +18688,10 @@ msgstr "ВідповіÑти..."
msgid "Repo by URL"
msgstr "Репозиторії по URL"
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17694,6 +18797,9 @@ msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ñ–ÑŽ"
msgid "Repository URL"
msgstr "URL репозиторіÑ"
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr "Перевірку репозиторію запущено."
@@ -17730,9 +18836,12 @@ msgstr "Вибрати"
msgid "Request Access"
msgstr "Запит доÑтупу"
-msgid "Request parameter %{param} is missing."
+msgid "Request Headers"
msgstr ""
+msgid "Request parameter %{param} is missing."
+msgstr "Параметр запиту %{param} відÑутній."
+
msgid "Request to link SAML account must be authorized"
msgstr "Запит на зв’ÑÐ·ÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу SAML повинен бути авторизований"
@@ -17745,11 +18854,14 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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 "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 all users in this group to setup Two-factor authentication"
msgstr "Вимагати від вÑÑ–Ñ… кориÑтувачів цієї групи налаштувати двофакторну автентифікацію"
@@ -17763,31 +18875,34 @@ msgstr "Вимагати пароль кориÑтувача Ð´Ð»Ñ Ð·Ð°Ñ‚Ð²ÐµÑ€
msgid "Require users to prove ownership of custom domains"
msgstr "Вимагати від кориÑтувачів Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð¿Ñ€Ð°Ð²Ð° влаÑноÑÑ‚Ñ– на влаÑні домени"
-msgid "Requirement"
+msgid "Required approvals (%{approvals_given} given)"
msgstr ""
-msgid "Requirement %{reference} has been added"
+msgid "Required approvals (%{approvals_given} given, you've approved)"
msgstr ""
+msgid "Requirement"
+msgstr "Вимога"
+
+msgid "Requirement %{reference} has been added"
+msgstr "Вимогу %{reference} було додано"
+
msgid "Requirement %{reference} has been archived"
-msgstr ""
+msgstr "Вимога %{reference} була архівована"
msgid "Requirement %{reference} has been reopened"
msgstr ""
msgid "Requirement %{reference} has been updated"
-msgstr ""
+msgstr "Вимогу %{reference} було оновлено"
msgid "Requirement title cannot have more than %{limit} characters."
-msgstr ""
+msgstr "Заголовок вимоги не може міÑтити більше %{limit} знаків."
msgid "Requirements"
-msgstr ""
-
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
+msgstr "Вимоги"
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17861,6 +18976,9 @@ msgstr "Завершено 1 обговореннÑ."
msgid "Resolved all discussions."
msgstr "Ð’ÑÑ– Ð¾Ð±Ð³Ð¾Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¾."
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr "Вирішено %{name}"
@@ -17873,6 +18991,12 @@ msgstr "Визначає IP-адреÑи один раз Ñ– викориÑтов
msgid "Response"
msgstr "Відповідь"
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr "Відповідь не міÑтила \"service_desk_address\""
@@ -17907,7 +19031,7 @@ msgid "Restoring the group will prevent the group, its subgroups and projects fr
msgstr ""
msgid "Restoring the project will prevent the project from being removed on this date and restore people's ability to make changes to it."
-msgstr ""
+msgstr "Ð’Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ñ”ÐºÑ‚Ñƒ запобіжить його видаленню в зазначений Ñ‡Ð°Ñ Ñ– поверне людÑм можливіÑÑ‚ÑŒ вноÑити до нього зміни."
msgid "Restrict access by IP address"
msgstr "Обмежити доÑтуп за IP адреÑою"
@@ -18021,6 +19145,9 @@ msgstr "Відкотити"
msgid "Rook"
msgstr "Rook"
+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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -18084,9 +19211,6 @@ msgstr "Runner'и можуть бути вÑтановлені на окремі
msgid "Runners currently online: %{active_runners_count}"
msgstr "ДоÑтупні Runner'и: %{active_runners_count}"
-msgid "Runners page"
-msgstr "Сторінка Runner'ів"
-
msgid "Runners page."
msgstr "Сторінка Runner'ів."
@@ -18123,9 +19247,6 @@ msgstr "SSH ключ"
msgid "SSH Keys"
msgstr "Ключі SSH"
-msgid "SSH Keys Help"
-msgstr "Допомога по SSH ключам"
-
msgid "SSH host key fingerprints"
msgstr "Відбитки SSH-ключа хоÑта"
@@ -18255,9 +19376,15 @@ msgstr "Пошук"
msgid "Search Button"
msgstr "Кнопка пошуку"
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr "Пошук Ñпецифікації Ñередовища"
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr "Пошук у гілках"
@@ -18315,6 +19442,9 @@ msgstr "Пошук проектів"
msgid "Search projects..."
msgstr "Пошук проектів..."
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr "Пошук кориÑтувачів"
@@ -18345,11 +19475,11 @@ msgstr "Запити на злиттÑ, призначені мені"
msgid "SearchAutocomplete|in all GitLab"
msgstr "по вÑьому GitLab"
-msgid "SearchAutocomplete|in this group"
-msgstr "в цій групі"
+msgid "SearchAutocomplete|in group %{groupName}"
+msgstr ""
-msgid "SearchAutocomplete|in this project"
-msgstr "в цьому проекті"
+msgid "SearchAutocomplete|in project %{projectName}"
+msgstr ""
msgid "SearchCodeResults|in"
msgstr "в"
@@ -18457,9 +19587,15 @@ msgstr "МіÑцÑ, Ñкі зараз викориÑтовуютьÑÑ"
msgid "Seats in license"
msgstr "КількіÑÑ‚ÑŒ міÑць у ліцензії"
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr "Секрет"
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr "Безпека"
@@ -18467,14 +19603,11 @@ msgid "Security & Compliance"
msgstr "Безпека та відповідніÑÑ‚ÑŒ"
msgid "Security Configuration"
-msgstr ""
+msgstr "ÐšÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ Ð‘ÐµÐ·Ð¿ÐµÐºÐ¸"
msgid "Security Dashboard"
msgstr "Панель безпеки"
-msgid "Security configuration help link"
-msgstr "ПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° довідку Ð´Ð»Ñ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½ÑŒ безпеки"
-
msgid "Security dashboard"
msgstr "Панель безпеки"
@@ -18484,24 +19617,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr "Ðалаштовано"
-
-msgid "SecurityConfiguration|Feature"
-msgstr "ФункціÑ"
+msgid "SecurityConfiguration|Enabled"
+msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
-msgstr "Ще не налаштовано"
+msgid "SecurityConfiguration|Not yet enabled"
+msgstr ""
-msgid "SecurityConfiguration|Secure features"
-msgstr "Безпечні функції"
+msgid "SecurityConfiguration|Security Control"
+msgstr ""
msgid "SecurityConfiguration|Status"
msgstr "Стан"
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18515,7 +19648,7 @@ msgid "SecurityReports|Add or remove projects from your dashboard"
msgstr ""
msgid "SecurityReports|Add projects"
-msgstr ""
+msgstr "Додати проєкти"
msgid "SecurityReports|Comment added to '%{vulnerabilityName}'"
msgstr ""
@@ -18527,13 +19660,13 @@ msgid "SecurityReports|Comment edited on '%{vulnerabilityName}'"
msgstr ""
msgid "SecurityReports|Create issue"
-msgstr ""
+msgstr "Створити задачу"
msgid "SecurityReports|Dismiss Selected"
msgstr ""
msgid "SecurityReports|Dismiss vulnerability"
-msgstr ""
+msgstr "Відхилити вразливіÑÑ‚ÑŒ"
msgid "SecurityReports|Dismissed '%{vulnerabilityName}'"
msgstr ""
@@ -18545,7 +19678,7 @@ msgid "SecurityReports|Each vulnerability now has a unique page that can be dire
msgstr ""
msgid "SecurityReports|Edit dashboard"
-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 ""
@@ -18566,10 +19699,10 @@ msgid "SecurityReports|Introducing standalone vulnerabilities"
msgstr ""
msgid "SecurityReports|Issue Created"
-msgstr ""
+msgstr "Задача Ñтворена"
msgid "SecurityReports|Learn More"
-msgstr ""
+msgstr "ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ"
msgid "SecurityReports|Learn more about setting up your dashboard"
msgstr ""
@@ -18581,10 +19714,10 @@ msgid "SecurityReports|Monitor vulnerabilities in your code"
msgstr ""
msgid "SecurityReports|More info"
-msgstr ""
+msgstr "Детальніше"
msgid "SecurityReports|More information"
-msgstr ""
+msgstr "Детальніше"
msgid "SecurityReports|No vulnerabilities found for dashboard"
msgstr ""
@@ -18605,16 +19738,16 @@ msgid "SecurityReports|Pipeline %{pipelineLink} triggered %{timeago} by %{user}"
msgstr ""
msgid "SecurityReports|Project"
-msgstr ""
+msgstr "Проєкт"
msgid "SecurityReports|Projects added"
-msgstr ""
+msgstr "Додані проєкти"
msgid "SecurityReports|Remove project from dashboard"
msgstr ""
msgid "SecurityReports|Report type"
-msgstr ""
+msgstr "Тип звіту"
msgid "SecurityReports|Return to dashboard"
msgstr ""
@@ -18632,9 +19765,12 @@ msgid "SecurityReports|Select a reason"
msgstr ""
msgid "SecurityReports|Severity"
-msgstr ""
+msgstr "Рівень"
msgid "SecurityReports|Status"
+msgstr "СтатуÑ"
+
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
msgstr ""
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
@@ -18718,6 +19854,9 @@ msgstr "Вибрати"
msgid "Select Archive Format"
msgstr "Виберіть формат архіву"
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr "Виберіть проект GitLab Ð´Ð»Ñ Ð·Ð²â€™ÑÐ·ÑƒÐ²Ð°Ð½Ð½Ñ Ñ–Ð· вашою командою Slack"
@@ -18769,12 +19908,18 @@ msgstr "Вибрати вÑе"
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr "Виберіть Ñ–Ñнуючий клаÑтер Kubernetes або Ñтворіть новий"
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr "Виберіть гілку"
msgid "Select branch/tag"
msgstr "Виберіть гілку або тег"
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr "Вибрати групу чи проект"
@@ -18820,9 +19965,18 @@ msgstr ""
msgid "Select source branch"
msgstr "Виберіть гілку-джерело"
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr "Вибір цільової гілки"
@@ -18848,7 +20002,7 @@ msgid "Selecting a GitLab user will add a link to the GitLab user in the descrip
msgstr "При виборі кориÑтувача Gitlab поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° нього буде додане до опиÑу задачі та коментарів (напр. \"<a href=\"#\"> @johnsmith</a>\"). Також це призведе до аÑоціації та/або Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ†Ð¸Ñ… задач та коментарів на вибраного кориÑтувача."
msgid "Selective synchronization"
-msgstr ""
+msgstr "Вибіркова ÑинхронізаціÑ"
msgid "Self monitoring project does not exist"
msgstr ""
@@ -18895,6 +20049,12 @@ msgstr "ВідіÑлати Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾ÑŽ пÐ
msgid "Send email"
msgstr "ÐадіÑлати лиÑта"
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr "ÐадіÑлати звіт"
@@ -19060,6 +20220,9 @@ msgstr "Ð’Ñтановити дату завершеннÑ"
msgid "Set instance-wide template repository"
msgstr "Ð’Ñтановити репозиторій шаблонів Ð´Ð»Ñ Ð²Ñього інÑтанÑу"
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr "МакÑимальний термін дії ÑеÑÑ–Ñ— Ð´Ð»Ñ Ð²ÐµÐ±-терміналу."
@@ -19096,6 +20259,9 @@ msgstr "Ð’Ñтановити заплановану дату завершеннÑ
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr "Ð’Ñтановіть триваліÑÑ‚ÑŒ, протÑгом Ñкої Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð±ÑƒÐ´ÑƒÑ‚ÑŒ вважатиÑÑ Ð·Ð°Ñтарілими. Як тільки пройде цей чаÑ, вони будуть заархівовані Ñ– більше не зможуть бути повтореними. Залиште порожнім, щоб Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð½Ñ–ÐºÐ¾Ð»Ð¸ не заÑтарівали. Має бути не менше 1 днÑ, наприклад: <code>15 днів</code>, <code>1 міÑÑць</code>, <code>2 роки</code>."
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr "Ð’Ñтановити макÑимальний розмір файлу Ð´Ð»Ñ Ð°Ñ€Ñ‚ÐµÑ„Ð°ÐºÑ‚Ñ–Ð² кожного завданнÑ"
@@ -19180,6 +20346,9 @@ msgstr "Ð’Ñтановлює цільову гілку %{branch_name}."
msgid "Sets the due date to %{due_date}."
msgstr "Ð’Ñтановлює заплановану дату Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ %{due_date}."
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr "Ð’Ñтановлює етап %{milestone_reference}."
@@ -19198,8 +20367,8 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
-msgstr "Рівень: %{severity}"
+msgid "Severity"
+msgstr ""
msgid "Shards (%{shards})"
msgstr ""
@@ -19237,15 +20406,15 @@ msgstr "Sherlock транзакції"
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr "Якщо ви коли-небудь втратите телефон або доÑтуп до Ñвоїх одноразових паролів, кожен із цих кодів Ð²Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¼Ð¾Ð¶Ðµ бути викориÑтаний один раз Ð´Ð»Ñ Ð²Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð´Ð¾Ñтупу до вашого облікового запиÑу. Будь лаÑка, зберігайте Ñ—Ñ… в надійному міÑці, інакше ви %{b_start}втратите%{b_end} доÑтуп до вашого облікового запиÑу."
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr "Показати вÑÑŽ активніÑÑ‚ÑŒ"
msgid "Show all members"
msgstr "Показати вÑÑ–Ñ… учаÑників"
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr "Показати архівовані проекти"
@@ -19270,15 +20439,24 @@ msgstr "Показати повний неформатований журнал"
msgid "Show file browser"
msgstr "Показати файловий менеджер"
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr "Показати оÑтанню верÑÑ–ÑŽ"
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
-msgid "Show only direct members"
+msgid "Show me more advanced stuff"
msgstr ""
+msgid "Show only direct members"
+msgstr "Показувати лише безпоÑередніх учаÑників"
+
msgid "Show only inherited members"
msgstr ""
@@ -19298,9 +20476,19 @@ msgstr[1] "Показано %d події"
msgstr[2] "Показано %d подій"
msgstr[3] "Показано %d подій"
-msgid "Showing %{limit} of %{total_count} issues. "
+msgid "Showing %{count} of %{total} projects"
msgstr ""
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "Showing %{limit} of %{total_count} issues. "
+msgstr "Показано %{limit} з %{total_count} задач. "
+
msgid "Showing %{pageSize} of %{total} issues"
msgstr "Показано %{pageSize} із %{total} задач"
@@ -19484,6 +20672,9 @@ msgstr "Ðе вдалоÑÑ Ð°Ð²Ñ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÑƒÐ²Ð°Ñ‚Ð¸ Ñмарт-карту
msgid "Snippets"
msgstr "Сніпети"
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19520,9 +20711,15 @@ msgstr ""
msgid "Snowplow"
msgstr "Snowplow"
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr "ДеÑкі Ñервери електронної пошти не підтримують Ð¿ÐµÑ€ÐµÐ²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ–Ð¼ÐµÐ½Ñ– відправника. Увімкніть це налаштуваннÑ, щоб включати Ñ–Ð¼â€™Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð° задачі, запиту на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð°Ð±Ð¾ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ñ Ð² тіло повідомленнÑ."
@@ -19619,6 +20816,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr "Помилка при отриманні пов’Ñзаних запитів на злиттÑ."
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19658,9 +20858,12 @@ msgstr "Помилка при завершенні обговореннÑ. БуÐ
msgid "Something went wrong while stopping this environment. Please try again."
msgstr "Проблема при зупинці Ñередовища. Будь лаÑка, Ñпробуйте знову."
-msgid "Something went wrong while updating a requirement."
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
msgstr ""
+msgid "Something went wrong while updating a requirement."
+msgstr "ЩоÑÑŒ пішо не так під Ñ‡Ð°Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð²Ð¸Ð¼Ð¾Ð³Ð¸."
+
msgid "Something went wrong while updating your list settings"
msgstr ""
@@ -19706,6 +20909,12 @@ msgstr "Сортувати за"
msgid "Sort direction"
msgstr "ПорÑдок ÑортуваннÑ"
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr "Рівень доÑтупу, в порÑдку зроÑтаннÑ"
@@ -19809,7 +21018,7 @@ msgid "SortOptions|Priority"
msgstr "Пріоритет"
msgid "SortOptions|Project"
-msgstr "Проект"
+msgstr "Проєкт"
msgid "SortOptions|Recent last activity"
msgstr "Ðайновіша оÑÑ‚Ð°Ð½Ð½Ñ Ð°ÐºÑ‚Ð¸Ð²Ð½Ñ–ÑÑ‚ÑŒ"
@@ -19823,6 +21032,9 @@ msgstr "Ðещодавно в обраних"
msgid "SortOptions|Size"
msgstr "Розмір"
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr "ÐапрÑмок ÑортуваннÑ"
@@ -19860,7 +21072,7 @@ msgid "Source is not available"
msgstr "Джерело недоÑтупне"
msgid "Source project cannot be found."
-msgstr "Проект-джерело не знайдено."
+msgstr "Проєкт-джерело не знайдено."
msgid "Sourcegraph"
msgstr "Sourcegraph"
@@ -19920,7 +21132,7 @@ msgid "Specific Runners"
msgstr "Спеціальні Runner’и"
msgid "Specified URL cannot be used: \"%{reason}\""
-msgstr ""
+msgstr "Вказана URL-адреÑа не може бути викориÑтана: \"%{reason}\""
msgid "Specify an e-mail address regex pattern to identify default internal users."
msgstr "Вкажіть шаблон адреÑи електронної пошти у виглÑді регулÑрного виразу Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, щоб автоматично визначати внутрішніх кориÑтувачів."
@@ -19988,8 +21200,8 @@ msgstr "Додали в обране"
msgid "Stars"
msgstr "У обраному"
-msgid "Start GitLab Ultimate trial"
-msgstr "Перейти на пробну верÑÑ–ÑŽ GitLab Ultimate"
+msgid "Start Date"
+msgstr ""
msgid "Start Web Terminal"
msgstr "ЗапуÑтити Веб-Термінал"
@@ -20063,6 +21275,9 @@ msgstr "Запущено %{startsIn}"
msgid "Started asynchronous removal of all repository check states."
msgstr "ÐÑинхронне Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ ÑƒÑÑ–Ñ… Ñтанів перевірок репозиторіїв запущено."
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr "ЗапуÑк..."
@@ -20139,7 +21354,7 @@ msgid "Status:"
msgstr "СтатуÑ:"
msgid "Status: %{title}"
-msgstr ""
+msgstr "СтатуÑ: %{title}"
msgid "StatusPage|AWS Secret access key"
msgstr ""
@@ -20189,6 +21404,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr "Будьте в курÑÑ– продуктивноÑÑ‚Ñ– та Ñтану вашого Ñередовища шлÑхом Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Prometheus Ð´Ð»Ñ Ð¼Ð¾Ð½Ñ–Ñ‚Ð¾Ñ€Ð¸Ð½Ð³Ñƒ ваших розгортань."
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr "Зупинити термінал"
@@ -20216,6 +21434,9 @@ msgstr "Сховище:"
msgid "StorageSize|Unknown"
msgstr "Ðевідомо"
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr "ОглÑд підгрупи"
@@ -20235,7 +21456,7 @@ msgid "Subgroups"
msgstr "Підгрупи"
msgid "Subgroups and projects"
-msgstr "Підгрупи та проекти"
+msgstr "Підгрупи та проєкти"
msgid "Subject Key Identifier:"
msgstr ""
@@ -20243,6 +21464,9 @@ msgstr ""
msgid "Subkeys"
msgstr "Підключі"
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20423,9 +21647,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr "Пропонована зміна"
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr "ЯÑкраво-зелений"
@@ -20510,6 +21740,9 @@ msgstr "Підтримку кориÑтувацьких Ñертифікатів
msgid "Support page URL"
msgstr "URL-адреÑа Ñторінки підтримки"
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr "Перейти в гілку/тег"
@@ -20537,9 +21770,6 @@ msgstr "СиÑтемні"
msgid "System Hooks"
msgstr "СиÑтемні хуки"
-msgid "System Hooks Help"
-msgstr "Допомога по ÑиÑтемним хукам"
-
msgid "System Info"
msgstr "Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ ÑиÑтему"
@@ -20694,7 +21924,7 @@ msgid "Template to append to all Service Desk issues"
msgstr "Шаблон Ð´Ð»Ñ Ð´Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ Ð´Ð¾ вÑÑ–Ñ… задач Service Desk"
msgid "Template was successfully saved."
-msgstr ""
+msgstr "Шаблон уÑпішно збережено."
msgid "Templates"
msgstr "Шаблони"
@@ -20793,17 +22023,20 @@ msgstr "ТеÑти"
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr "ДÑкуємо, що зареєÑтрувалиÑÑŒ на безкоштовну пробну верÑÑ–ÑŽ! Ðезабаром ви отримаєте додаткові вказівки у поштовій Ñкриньці."
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr "ДÑкуємо за ваш звіт. ÐдмініÑтратор GitLab розглÑне це Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð½Ð°Ð¹Ð±Ð»Ð¸Ð¶Ñ‡Ð¸Ð¼ чаÑом."
msgid "Thanks for your purchase!"
-msgstr ""
+msgstr "ДÑкуємо за покупку!"
msgid "Thanks! Don't show me this again"
msgstr "ДÑкую! Більше не показувати це повідомленнÑ"
msgid "That's it, well done!%{celebrate}"
-msgstr ""
+msgstr "Це вÑе, хороша робота!%{celebrate}"
msgid "The \"%{group_path}\" group allows you to sign in with your Single Sign-On Account"
msgstr "Група \"%{group_path}\" дозволÑÑ” увійти за допомогою облікового запиÑу єдиного входу"
@@ -20878,9 +22111,6 @@ msgstr "ÐšÐ¾Ð»ÐµÐºÑ†Ñ–Ñ Ð¿Ð¾Ð´Ñ–Ð¹ додана до даних, зібрани
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr "Стан конфігурацій в таблиці нижче ÑтоÑуєтьÑÑ Ð»Ð¸ÑˆÐµ гілки за замовчуваннÑм Ñ– базуєтьÑÑ Ð½Ð° %{linkStart}оÑтанньому конвеєрі%{linkEnd}. ПіÑÐ»Ñ Ñ‚Ð¾Ð³Ð¾, Ñк ви налаштуєте ÑÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð³Ñ–Ð»ÐºÐ¸ за замовчуваннÑм, вÑÑ– наÑтупні Ñтворені гілки включатимуть це ÑкануваннÑ."
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr "Ð—â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð±ÑƒÐ´Ðµ припинено піÑÐ»Ñ %{timeout}. Ð”Ð»Ñ Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ñ–Ñ—Ð², Ñким потрібно більше чаÑу, викориÑтовуйте комбінацію clone/push."
@@ -20891,10 +22121,10 @@ msgid "The contents of this group, its subgroups and projects will be permanentl
msgstr ""
msgid "The current issue"
-msgstr ""
+msgstr "Поточна задача"
msgid "The data source is connected, but there is no data to display. %{documentationLink}"
-msgstr ""
+msgstr "Джерело даних підключено, але даних Ð´Ð»Ñ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð½ÐµÐ¼Ð°Ñ”. %{documentationLink}"
msgid "The default CI configuration path for new projects."
msgstr "ШлÑÑ… конфігурації CI за замовчуваннÑм Ð´Ð»Ñ Ð½Ð¾Ð²Ð¸Ñ… проєктів."
@@ -20917,9 +22147,15 @@ msgstr "Введений вами домен неправильно відфор
msgid "The domain you entered is not allowed."
msgstr "Введений вами домен Ñ” недопуÑтимим."
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr "Введена мапа кориÑтувачів не Ñ” корректною мапою кориÑтувачів JSON."
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr "Файл уÑпішно Ñтворено."
@@ -20958,6 +22194,9 @@ msgid "The group and its projects can only be viewed by members."
msgstr "Ð¦Ñ Ð³Ñ€ÑƒÐ¿Ð° та Ñ—Ñ— проекти видимі тільки Ð´Ð»Ñ ÑƒÑ‡Ð°Ñників."
msgid "The group can be fully restored"
+msgstr "Цю групу можна повніÑÑ‚ÑŽ відновити"
+
+msgid "The group export can be downloaded from:"
msgstr ""
msgid "The group has already been shared with this group"
@@ -21134,6 +22373,9 @@ msgstr "Вказана вкладка недійÑна. Будь лаÑка, вÐ
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr "Ð¡Ñ‚Ð°Ð´Ñ–Ñ Staging показує Ñ‡Ð°Ñ Ð¼Ñ–Ð¶ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ð·Ð°Ð¿Ð¸Ñ‚Ñƒ на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ñ‚Ð° розгортаннÑм коду у production. Дані автоматично додаютьÑÑ Ð¿Ñ–ÑÐ»Ñ Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ñƒ production вперше."
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr "Ð¡Ñ‚Ð°Ð´Ñ–Ñ Ð¢ÐµÑÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾ÐºÐ°Ð·ÑƒÑ” чаÑ, Ñкий GitLab CI витрачає Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ конвеєра Ð´Ð»Ñ Ð²Ñ–Ð´Ð¿Ð¾Ð²Ñ–Ð´Ð½Ð¾Ð³Ð¾ запиту злиттÑ. Дані будуть автоматично додані піÑÐ»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ð¿ÐµÑ€ÑˆÐ¾Ð³Ð¾ конвеєра."
@@ -21182,6 +22424,9 @@ msgstr "ВразливіÑÑ‚ÑŒ більше не виÑвлÑєтьÑÑ. ПерÐ
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr "ВразливіÑÑ‚ÑŒ більше не виÑвлÑєтьÑÑ. Перевірте, що цю вразливіÑÑ‚ÑŒ виправлено перед тим, Ñк змінювати ÑтатуÑ."
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr "Ðемає GPG ключів, пов’Ñзаних із цим обліковим запиÑом."
@@ -21198,7 +22443,7 @@ msgid "There are no archived projects yet"
msgstr "Ðаразі немає жодного архівованого проекту"
msgid "There are no archived requirements"
-msgstr ""
+msgstr "Ðемає жодних архівних вимог"
msgid "There are no changes"
msgstr ""
@@ -21234,13 +22479,13 @@ msgid "There are no open merge requests"
msgstr "Відкритих запитів на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð½ÐµÐ¼Ð°Ñ”"
msgid "There are no open requirements"
-msgstr ""
+msgstr "Відкриті вимоги відÑутні"
msgid "There are no packages yet"
msgstr "Ðаразі пакети відÑутні"
msgid "There are no projects shared with this group yet"
-msgstr "Ще немає Ñпільних проектів з цією групою"
+msgstr ""
msgid "There are no variables yet."
msgstr ""
@@ -21257,6 +22502,15 @@ msgstr "Даних немає. Будь лаÑка, змініть Ñвій ви
msgid "There was a problem communicating with your device."
msgstr "Проблема Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð´Ð¾ вашого приÑтрою."
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21329,6 +22583,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr "Помилка при завантаженні ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ñ Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚Ñ– кориÑтувачів."
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr "Помилка при видаленні адреÑи електронної пошти."
@@ -21392,6 +22649,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° з reCAPTCHA. Будь лаÑка, пройдіть reCAPTCHA знову."
@@ -21476,6 +22736,9 @@ msgstr "Цей коміт підпиÑано перевіреним підпиÑ
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr "Цей коміт підпиÑано <strong>неперевіреним</strong> підпиÑом."
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr "Ð¦Ñ Ð´Ð°Ñ‚Ð° наÑтупає пізніше дати закінченнÑ, тому цей епік не буде відображатиÑÑ Ð² плані-графіку."
@@ -21515,6 +22778,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr "Цей епік не Ñ–Ñнує або у Ð²Ð°Ñ Ð½ÐµÐ¼Ð°Ñ” доÑтатніх дозволів."
@@ -21560,9 +22826,6 @@ msgstr "Це завданнÑ, відкладено на %{remainingTime}"
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr "Це ÑпиÑок приÑтроїв, з котрих заходили в Ваш аккаунт. Завершіть будь-Ñкі підозрілі ÑеанÑи."
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr "Це журнал безпеки, Ñкий міÑтить уÑÑ– важливі події пов’Ñзані із вашим обліковим запиÑом."
@@ -21674,14 +22937,14 @@ msgstr "Це Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð²Ð¸ÐºÐ¾Ð½ÑƒÑ” кроки, Ñкі повинні Ð
msgid "This job is preparing to start"
msgstr "Це Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð³Ð¾Ñ‚ÑƒÑ”Ñ‚ÑŒÑÑ Ð´Ð¾ запуÑку"
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
-msgstr "Це Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð·Ð°Ð±Ð»Ð¾ÐºÐ¾Ð²Ð°Ð½Ðµ, тому що немає жодних runner'ів з будь Ñким із цих тегів:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
+msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
msgstr "Це Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð·Ð°Ð±Ð»Ð¾ÐºÐ¾Ð²Ð°Ð½Ðµ, тому що немає активних runner'ів, Ñкі могли б його виконати."
msgid "This job is waiting for resource: "
-msgstr ""
+msgstr "Це Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð¾Ñ‡Ñ–ÐºÑƒÑ” на реÑурÑ: "
msgid "This job requires a manual action"
msgstr "Ð—Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð²Ð¸Ð¼Ð°Ð³Ð°Ñ” ручних дій"
@@ -21701,6 +22964,9 @@ msgstr "Це може розкрити конфіденційну інформа
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr "Це означає, що ви не можете відправлÑти код, поки не Ñтворите порожній репозиторій або не імпортуєте Ñ–Ñнуючий."
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr "Цей запит на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð·Ð°Ð±Ð»Ð¾ÐºÐ¾Ð²Ð°Ð½Ð¾."
@@ -21732,17 +22998,23 @@ msgid "This pipeline was triggered by a parent pipeline"
msgstr ""
msgid "This project"
-msgstr "Цей проект"
+msgstr "Цей проєкт"
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr "Цей проект не входить до жодної групи Ñ– тому не може викориÑтовувати групові Runner’и."
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr "Ð”Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ проекту немає домашньої Ñторінки вікі"
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr "Ð”Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ проекту вимкнено білінг. Щоб Ñтворити клаÑтер, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">увімкніть білінг <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> Ñ– Ñпробуйте знову."
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr "Цей проект заархівовано і його не можна коментувати."
@@ -21755,12 +23027,24 @@ msgstr "Цей проєкт буде видалено %{date}"
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr "Цей репозиторій"
+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 "Ðаразі цей репозиторій Ñ” порожнім. Ðовий конвеєр Auto DevOps буде Ñтворено піÑÐ»Ñ Ñ‚Ð¾Ð³Ð¾, Ñк новий файл буде відправлено в ÑкуÑÑŒ гілку."
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr "Цей runner буде виконуватиÑÑ Ñ‚Ñ–Ð»ÑŒÐºÐ¸ на тих конвеєрах, Ñкі Ñпрацьовують на захищених гілках"
@@ -21779,8 +23063,8 @@ msgstr "Цей Ñ‡Ð°Ñ Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð¼Ð°Ñ‚Ð¸Ð¼Ðµ перевагу у ра
msgid "This user cannot be unlocked manually from GitLab"
msgstr "Цей кориÑтувач не може бути розблокований вручну в GitLab"
-msgid "This user has no active %{type} Tokens."
-msgstr "У кориÑтувача немає активних %{type} токенів."
+msgid "This user has no active %{type}."
+msgstr ""
msgid "This user has no identities"
msgstr "Цей кориÑтувач не має ідентифікацій"
@@ -21788,9 +23072,6 @@ msgstr "Цей кориÑтувач не має ідентифікацій"
msgid "This 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 "Цей кориÑтувач буде автором вÑÑ–Ñ… подій в Ñтрічці активноÑÑ‚Ñ–, Ñка генеруєтьÑÑ Ð½Ð° оÑнові оновлень, таких Ñк ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð½Ð¾Ð²Ð¸Ñ… гілок чи нових комітів, Ñкі відправлÑтимутьÑÑ Ð² Ñ–Ñнуючі гілки."
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr "Цей кориÑтувач буде автором вÑÑ–Ñ… подій в каналі активноÑÑ‚Ñ–, Ñкі Ñ” результатом оновленнÑ, наприклад ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð½Ð¾Ð²Ð¸Ñ… гілок або Ð²Ñ–Ð´Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð½Ð¾Ð²Ð¸Ñ… комітів до Ñ–Ñнуючих гілок. При Ñтворенні або перепризначенні ви зможете призначити лише Ñебе кориÑтувачем Ð´Ð»Ñ Ð²Ñ–Ð´Ð´Ð·ÐµÑ€ÐºÐ°Ð»ÐµÐ½Ð½Ñ."
-
msgid "This variable can not be masked."
msgstr ""
@@ -21816,7 +23097,7 @@ msgid "Thread to reply to cannot be found"
msgstr ""
msgid "Threat Monitoring"
-msgstr ""
+msgstr "Моніторинг Загроз"
msgid "ThreatMonitoring|Anomalous Requests"
msgstr ""
@@ -21837,7 +23118,7 @@ msgid "ThreatMonitoring|Dropped Packets"
msgstr ""
msgid "ThreatMonitoring|Environment"
-msgstr ""
+msgstr "Середовище"
msgid "ThreatMonitoring|No environments detected"
msgstr ""
@@ -21845,9 +23126,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -22094,6 +23381,9 @@ msgstr "зараз"
msgid "Timeout"
msgstr "Ð§Ð°Ñ Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ"
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] "година"
@@ -22162,6 +23452,12 @@ msgstr "Ð”Ð»Ñ Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ–Ñ… кориÑтувачіÐ
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr "Щоб увімкнути це Ñ– побачити Когорти КориÑтувачів, перейдіть в %{application_settings_link_start}Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°ÑтоÑунку%{application_settings_link_end}."
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 "Ð”Ð»Ñ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ введіть URL-адреÑу FogBugz та параметри входу нижче. Далі ви зможете перенеÑти кориÑтувачів та вибрати проекти Ð´Ð»Ñ Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚Ñƒ."
@@ -22181,7 +23477,7 @@ msgid "To import an SVN repository, check out %{svn_link}."
msgstr "Ð”Ð»Ñ Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ SVN-репозиторію, переглÑньте %{svn_link}."
msgid "To keep this project going, create a new issue"
-msgstr "Ð”Ð»Ñ Ñ€Ð¾Ð·Ð²Ð¸Ñ‚ÐºÑƒ цього проекту Ñтворіть нову задачу"
+msgstr "Ð”Ð»Ñ Ñ€Ð¾Ð·Ð²Ð¸Ñ‚ÐºÑƒ цього проєкту Ñтворіть нову задачу"
msgid "To keep this project going, create a new merge request"
msgstr "Ð”Ð»Ñ Ñ€Ð¾Ð·Ð²Ð¸Ñ‚ÐºÑƒ цього проекту Ñтворіть новий запит на злиттÑ"
@@ -22282,6 +23578,9 @@ msgstr "Перемкнути Ð¾Ð¿Ð¸Ñ ÐºÐ¾Ð¼Ñ–Ñ‚Ñ–Ð²"
msgid "Toggle commit list"
msgstr "Відкрити або закрити ÑпиÑок комітів"
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr "Увімкнути/вимкнути Ñмайлики-нагороди"
@@ -22328,7 +23627,7 @@ msgid "Too many projects enabled. You will need to manage them via the console o
msgstr ""
msgid "Topics (optional)"
-msgstr ""
+msgstr "Теми (додатково)"
msgid "Total"
msgstr "Ð’Ñього"
@@ -22339,15 +23638,9 @@ msgstr "Загальна кількіÑÑ‚ÑŒ внеÑків"
msgid "Total artifacts size: %{total_size}"
msgstr "Загальний розмір артефактів: %{total_size}"
-msgid "Total cores (vCPUs)"
-msgstr "Ð’Ñього Ñдер (vCPU)"
-
msgid "Total issues"
msgstr "Ð’Ñього задач"
-msgid "Total memory (GB)"
-msgstr "Ð’Ñього пам'ÑÑ‚Ñ– (ГБ)"
-
msgid "Total test time for all commits/merges"
msgstr "Загальний чаÑ, щоб перевірити вÑÑ– коміти/злиттÑ"
@@ -22363,9 +23656,6 @@ msgstr "Лог"
msgid "Tracing"
msgstr "ВідÑтеженнÑ"
-msgid "Track activity with Contribution Analytics."
-msgstr "ВідÑтежувати активніÑÑ‚ÑŒ за допомогою аналітики учаÑників."
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr "ВідÑтежуйте групи задач зі Ñпільною темою з різних проектів та етапів"
@@ -22384,6 +23674,9 @@ msgstr ""
msgid "Transfer project"
msgstr "ПеренеÑти проект"
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 "Ðе вдалоÑÑ Ð·Ð¼Ñ–Ð½Ð¸Ñ‚Ð¸ шлÑÑ… тому що в цій групі Ñ” проекти із образами Docker у Ñвоїх РеєÑтрах контейнерів. Будь лаÑка, Ñпочатку видаліть ці образи з ваших проектів Ñ– Ñпробуйте знову."
@@ -22495,6 +23788,9 @@ msgstr ""
msgid "Try to fork again"
msgstr "Спробувати зробити форк знову"
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr "Спробуйте викориÑтовувати інші Ñлова Ð´Ð»Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ щоб знайти необхідний вам файл."
@@ -22538,7 +23834,7 @@ msgid "Type"
msgstr "Тип"
msgid "Type/State"
-msgstr ""
+msgstr "Тип/Стан"
msgid "U2F Devices (%{length})"
msgstr "U2F приÑтрої (%{length})"
@@ -22552,10 +23848,10 @@ msgstr "URL"
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22564,6 +23860,9 @@ msgstr "URL-адреÑа зовнішнього Ñховища, де зберіÐ
msgid "URL or request ID"
msgstr "URL або ідентифікатор запиту"
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr "Ðеможливо заÑтоÑувати пропозиції до видаленого Ñ€Ñдка."
@@ -22603,6 +23902,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr "Ðе вдалоÑÑ Ñтворити новий ідентифікатор інÑтанÑу"
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22610,11 +23912,17 @@ msgid "Unable to load the diff. %{button_try_again}"
msgstr "Ðеможливо завантажити порівнÑÐ½Ð½Ñ (diff). %{button_try_again}"
msgid "Unable to load the merge request widget. Try reloading the page."
+msgstr "Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ віджет запиту на злиттÑ. Спробуйте перезавантажити Ñторінку."
+
+msgid "Unable to process group import file"
msgstr ""
msgid "Unable to resolve"
msgstr "Ðе вдалоÑÑ Ð²Ð¸Ñ€Ñ–ÑˆÐ¸Ñ‚Ð¸"
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr "Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ ваші зміни. Будь лаÑка, Ñпробуйте знову."
@@ -22634,7 +23942,7 @@ msgid "Unable to update this issue at this time."
msgstr "Ðе вдалоÑÑ Ð¾Ð½Ð¾Ð²Ð¸Ñ‚Ð¸ цю задачу зараз."
msgid "Unarchive project"
-msgstr "Розархівувати проект"
+msgstr "Розархівувати проєкт"
msgid "Unarchiving the project will restore people's ability to make changes to it. The repository can be committed to, and issues, comments, and other entities can be created. %{strong_start}Once active, this project shows up in the search and on the dashboard.%{strong_end}"
msgstr ""
@@ -22724,10 +24032,10 @@ msgid "Unresolved"
msgstr ""
msgid "UnscannedProjects|15 or more days"
-msgstr ""
+msgstr "15 або більше днів"
msgid "UnscannedProjects|30 or more days"
-msgstr ""
+msgstr "30 або більше днів"
msgid "UnscannedProjects|5 or more days"
msgstr ""
@@ -22864,18 +24172,12 @@ msgstr "ОновленнÑ"
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr "Перейдіть на вищий тарифний план, щоб отримати доÑтуп до функціональноÑÑ‚Ñ– Canary Deployments"
-msgid "Upgrade your plan"
-msgstr "Перейти на вищий тарифний план"
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr "Перейдіть на вищий тарифний план щоб активувати Покращений Глобальний Пошук."
msgid "Upgrade your plan to activate Audit Events."
msgstr "Оновіть Ñвій план Ð´Ð»Ñ Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ— подій аудиту."
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr "Перейдіть на вищий тарифний план Ð´Ð»Ñ Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ— Ðналітики учаÑників."
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr "Перейдіть на вищий тарифний план щоб активувати групові веб-хуки."
@@ -22894,6 +24196,9 @@ msgstr "Завантажити CSV файл"
msgid "Upload New File"
msgstr "ÐадіÑлати новий файл"
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr "Завантажити Ñертифікат Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ домену з уÑіма проміжними"
@@ -22912,6 +24217,9 @@ msgstr "ÐатиÑніть, щоб надіÑлати"
msgid "Uploaded on"
msgstr "Завантажено на"
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr "Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð·Ð¼Ñ–Ð½ до терміналу"
@@ -22936,9 +24244,6 @@ msgstr "ВикориÑтано"
msgid "Usage ping is not enabled"
msgstr "Збір даних про викориÑÑ‚Ð°Ð½Ð½Ñ Ð²Ð¸Ð¼ÐºÐ½ÐµÐ½Ð¾"
-msgid "Usage quotas help link"
-msgstr "ПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° довідку по квотам на викориÑтаннÑ"
-
msgid "Usage statistics"
msgstr "СтатиÑтика викориÑтаннÑ"
@@ -22948,12 +24253,18 @@ msgstr "%{help_link_start}Загальні runner'и%{help_link_end} вимкнÐ
msgid "UsageQuota|Artifacts"
msgstr "Ðртефакти"
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr "Купити додаткові хвилини"
msgid "UsageQuota|Current period usage"
msgstr "ВикориÑÑ‚Ð°Ð½Ð½Ñ Ð·Ð° поточний період"
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr "Сховище LFS"
@@ -22963,12 +24274,18 @@ msgstr "Пакети"
msgid "UsageQuota|Pipelines"
msgstr "Конвеєри"
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr "Репозиторій"
msgid "UsageQuota|Storage"
msgstr "Сховище"
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr "Цей проÑÑ‚Ñ–Ñ€ імен не міÑтить проектів, що викориÑтовують загальні runner'и"
@@ -22987,12 +24304,18 @@ msgstr "ВикориÑÑ‚Ð°Ð½Ð½Ñ Ð³Ñ€ÑƒÐ¿Ð¾Ð²Ð¸Ñ… реÑурÑів у проек
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr "ВикориÑÑ‚Ð°Ð½Ð½Ñ Ð²Ñ–Ð´"
msgid "UsageQuota|Wiki"
msgstr "Вікі"
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr "ВикориÑтовуйте %{code_start}::%{code_end} Ð´Ð»Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ %{link_start}набору Ñелективних міток%{link_end} (напр. %{code_start}priority::1%{code_end})"
@@ -23017,7 +24340,7 @@ msgstr "ВикориÑтовуйте групові етапи, щоб керуÐ
msgid "Use hashed storage"
msgstr "ВикориÑтовувати хешоване Ñховище"
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -23090,10 +24413,7 @@ msgid "User pipeline minutes were successfully reset."
msgstr "КориÑтувацькі хвилини Ð´Ð»Ñ ÐºÐ¾Ð½Ð²ÐµÑ”Ñ€Ñ–Ð² уÑпішно обнулено."
msgid "User restrictions"
-msgstr ""
-
-msgid "User settings"
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ¾Ñ€Ð¸Ñтувача"
+msgstr "ÐžÐ±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ ÐºÐ¾Ñ€Ð¸Ñтувача"
msgid "User was successfully created."
msgstr "КориÑтувача було уÑпішно Ñтворено."
@@ -23141,7 +24461,7 @@ msgid "UserOnboardingTour|Commits are shown in chronological order and can be fi
msgstr "Коміти відображаютьÑÑ Ð² хронологічному порÑдку та можуть бути відфільтровані за повідомленнÑм коміту та за гілкою."
msgid "UserOnboardingTour|Create a project"
-msgstr "Створити проект"
+msgstr "Створити проєкт"
msgid "UserOnboardingTour|Exit 'Learn GitLab'"
msgstr "Вийти з \"ДізнатиÑÑ Ð¿Ñ€Ð¾ GitLab\""
@@ -23303,7 +24623,7 @@ msgid "UserProfile|Star projects to track their progress and show your appreciat
msgstr "Додавайте проекти в обране, щоб Ñлідкувати за ними та показати Ñвій інтереÑ."
msgid "UserProfile|Starred projects"
-msgstr "Обрані проекти"
+msgstr "Обрані проєкти"
msgid "UserProfile|Subscribe"
msgstr "ПідпиÑатиÑÑ"
@@ -23341,6 +24661,12 @@ msgstr "Ви ще не Ñтворили жодних Ñніпетів."
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr "За вашим вибором ваші проекти можуть бути доÑтупні публічно, внутрішньо або приватно."
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr "Ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача (необов'Ñзково)"
@@ -23401,6 +24727,9 @@ msgstr "ВикориÑÑ‚Ð°Ð½Ð½Ñ %{code_start}::%{code_end} вказує на %{
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr "ВикориÑтовуєтьÑÑ Ð¾Ð±Ð¾Ð²â€™Ñзкова ÑÑ‚Ñ€Ð°Ñ‚ÐµÐ³Ñ–Ñ ÑˆÐ¸Ñ„Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¸ відÑутньому полі Ð´Ð»Ñ Ð·Ð°ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¾Ð³Ð¾ значеннÑ!"
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr "Перевірити"
@@ -23428,7 +24757,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23470,6 +24802,9 @@ msgstr "Перевірити конфігурацію"
msgid "Version"
msgstr "ВерÑÑ–Ñ"
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr "Дуже кориÑна"
@@ -23520,6 +24855,9 @@ msgstr[3] "ПереглÑнути %d опублікованих артефакт
msgid "View file @ "
msgstr "ПереглÑд файла @ "
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr "ПереглÑнути повну панель керуваннÑ"
@@ -23536,7 +24874,7 @@ msgid "View issue"
msgstr "ПереглÑнути задачу"
msgid "View issues"
-msgstr ""
+msgstr "ПроглÑнути задачі"
msgid "View it on GitLab"
msgstr "ПереглÑнути це на GitLab"
@@ -23583,6 +24921,9 @@ msgstr "ПереглÑнути оÑтаннє уÑпішне розгортанÐ
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr "ПереглÑд коміту"
@@ -23664,9 +25005,6 @@ msgstr "ВразливоÑÑ‚Ñ–"
msgid "Vulnerabilities over time"
msgstr "ВразливоÑÑ‚Ñ– в чаÑÑ–"
-msgid "Vulnerability List"
-msgstr "СпиÑок вразливоÑтей"
-
msgid "Vulnerability remediated. Review before resolving."
msgstr "ВразливіÑÑ‚ÑŒ виправлено. ПереглÑньте перед вирішеннÑм."
@@ -23697,9 +25035,6 @@ msgstr "Підтвердити"
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr "Підтверджено %{timeago} кориÑтувачем %{user}"
-msgid "VulnerabilityManagement|Create issue"
-msgstr "Створити задачу"
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr "ВиÑвлено %{timeago} в контейнері %{pipelineLink}"
@@ -23808,6 +25143,9 @@ msgstr "WIP (в процеÑÑ–)"
msgid "Wait for the file to load to copy its contents"
msgstr "Зачекайте Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ Ð´Ð»Ñ ÐºÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ð¹Ð¾Ð³Ð¾ вміÑту"
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr "ÐžÑ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… про продуктивніÑÑ‚ÑŒ"
@@ -23820,6 +25158,9 @@ msgstr "Увага:"
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr "Ми не змогли визначити шлÑÑ… до Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ ÐµÐ¿Ñ–ÐºÑƒ"
@@ -23827,7 +25168,7 @@ msgid "We could not determine the path to remove the issue"
msgstr "Ми не змогли визначити шлÑÑ… до Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð·Ð°Ð´Ð°Ñ‡Ñ–"
msgid "We couldn't reach the Prometheus server. Either the server no longer exists or the configuration details need updating."
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ð¿Ñ–Ð´ÐºÑŽÑ‡Ð¸Ñ‚Ð¸ÑÑ Ð´Ð¾ Ñервера Prometheus. Ðбо Ñервер більше не Ñ–Ñнує, або необхідно оновити деталі конфігурації."
msgid "We created a short guided tour that will help you learn the basics of GitLab and how it will help you be better at your job. It should only take a couple of minutes. You will be guided by two types of helpers, best recognized by their color."
msgstr "Ми Ñтворили невелику екÑкурÑÑ–ÑŽ, Ñка допоможе розібратиÑÑ Ñ–Ð· базовими понÑÑ‚Ñ‚Ñми GitLab Ñ– те, Ñк він допоможе вам у роботі. Це займе вÑього декілька хвилин. Слідуйте за двома типами вказівників, що відрізнÑÑŽÑ‚ÑŒÑÑ Ð·Ð° кольором."
@@ -23841,8 +25182,14 @@ msgstr "Ми не маємо доÑтатньо даних Ð´Ð»Ñ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°
msgid "We have found the following errors:"
msgstr "Ми виÑвили наÑтупні помилки:"
-msgid "We heard back from your U2F device. You have been authenticated."
-msgstr "Ми отримали відповідь від вашого приÑтрою U2F. Ви пройшли автентифікацію."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
+msgstr ""
msgid "We sent you an email with reset password instructions"
msgstr "Ми надіÑлали вам Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ð¾ електронній пошті з інÑтрукціÑми по відновленню паролю"
@@ -23869,7 +25216,7 @@ msgid "Web terminal"
msgstr "Веб-термінал"
msgid "WebIDE|Merge request"
-msgstr ""
+msgstr "Запит на злиттÑ"
msgid "Webhook"
msgstr "Вебхук"
@@ -23883,9 +25230,6 @@ msgstr ""
msgid "Webhooks"
msgstr "Веб-хуки"
-msgid "Webhooks Help"
-msgstr "Допомога по веб-хукам"
-
msgid "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 "Веб-хук дозволÑÑ” вам викликати URL Ñкщо, наприклад, був відправлений новий код або Ñтворено нову задачу. Ви можете налаштувати його так, щоб він реагував на певні події (відправки коду, задачі або запити на злиттÑ). Групові веб-хуки заÑтоÑовуютьÑÑ Ð´Ð¾ вÑÑ–Ñ… проектів в групі Ñ– дозволÑÑŽÑ‚ÑŒ вам Ñтандартизувати Ñ—Ñ… Ð´Ð»Ñ Ð²Ñієї вашої групи."
@@ -23917,20 +25261,29 @@ msgid "Welcome to GitLab %{name}!"
msgstr "ЛаÑкаво проÑимо до GitLab %{name}!"
msgid "Welcome to GitLab, %{first_name}!"
-msgstr ""
+msgstr "ЛаÑкаво проÑимо до GitLab, %{first_name}!"
msgid "Welcome to GitLab.com<br>@%{name}!"
-msgstr ""
+msgstr "ЛаÑкаво проÑимо до GitLab.com<br>@%{name}!"
msgid "Welcome to the Guided GitLab Tour"
msgstr "ЛаÑкаво проÑимо на екÑкурÑÑ–ÑŽ по GitLab"
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr "ЛаÑкаво проÑимо до дошки Ð¾Ð±Ð³Ð¾Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð·Ð°Ð´Ð°Ñ‡!"
msgid "What are you searching for?"
msgstr "Що ви шукаєте?"
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23968,9 +25321,6 @@ msgstr "Хоча й рідко, але можливо не мати вразли
msgid "White helpers give contextual information."
msgstr "Білі вказівники дають контекÑтну інформацію."
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr "ВнеÑти до білого ÑпиÑку щоб дозволити запити до локальної мережі із хуків та ÑервіÑів"
-
msgid "Who can be an approver?"
msgstr "Хто може затверджувати?"
@@ -24004,9 +25354,6 @@ msgstr "Git доÑтуп"
msgid "WikiClone|Install Gollum"
msgstr "Ð’Ñтановити Gollum"
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr "РекомендуєтьÑÑ Ð²Ñтановити %{markdown}, з тим щоб GFM функції візуалізувалиÑÑ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ð¾:"
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr "ЗапуÑÑ‚Ñ–Ñ‚ÑŒ Gollum Ñ– редагуйте локально"
@@ -24038,7 +25385,7 @@ msgid "WikiEmpty|The wiki lets you write documentation for your project"
msgstr "Вікі дозволÑÑŽÑ‚ÑŒ пиÑати документацію Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ проекту"
msgid "WikiEmpty|This project has no wiki pages"
-msgstr "Цей проект не має вікі Ñторінок"
+msgstr "Цей проєкт не має вікі Ñторінок"
msgid "WikiEmpty|You must be a project member in order to add wiki pages."
msgstr "Ви повинні бути учаÑником проекту Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, щоб додавати вікі Ñторінки."
@@ -24127,11 +25474,14 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr "Вікі-Ñторінки"
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr "Розгорне на"
-msgid "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 "З аналітикою контриб’юторів ви може вивчати активніÑÑ‚ÑŒ в задачах, запитах на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ñ– подій відправки коду Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ñ— організації Ñ– Ñ—Ñ— учаÑників."
+msgid "With requirements, you can set criteria to check your products against."
+msgstr ""
msgid "Withdraw Access Request"
msgstr "СкаÑувати запит доÑтупу"
@@ -24139,11 +25489,11 @@ msgstr "СкаÑувати запит доÑтупу"
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
-msgstr "Довідка по робочому процеÑу"
+msgid "Work in progress Limit"
+msgstr ""
msgid "Write"
msgstr "ÐапиÑати"
@@ -24224,7 +25574,7 @@ msgid "You are not allowed to unlink your primary login account"
msgstr "Вам не дозволÑєтьÑÑ Ð²Ñ–Ð´Ð²â€™Ñзувати Ñвій оÑновний обліковій Ð·Ð°Ð¿Ð¸Ñ Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ñƒ"
msgid "You are not authorized to perform this action"
-msgstr ""
+msgstr "У Ð²Ð°Ñ Ð½ÐµÐ¼Ð°Ñ” повноважень на Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¾Ñ— дії"
msgid "You are now impersonating %{username}"
msgstr "Зараз ви імітуєте %{username}"
@@ -24236,7 +25586,7 @@ msgid "You are receiving this message because you are a GitLab administrator for
msgstr "Ви отримуєте це повідомленнÑ, бо ви Ñ” адмініÑтратором GitLab Ð´Ð»Ñ %{url}."
msgid "You are trying to upload something other than an image. Please upload a .png, .jpg, .jpeg, .gif, .bmp, .tiff or .ico."
-msgstr ""
+msgstr "Ви намагаєтеÑÑŒ завантажити щоÑÑŒ, що не Ñ” зображеннÑм. Будь лаÑка, завантажте файл .png, .jpg, .jpeg, .gif, .bmp, .tiff або .ico."
msgid "You can %{linkStart}view the blob%{linkEnd} instead."
msgstr "ЗаміÑÑ‚ÑŒ цього ви можете %{linkStart}переглÑнути бінарні дані%{linkEnd}."
@@ -24259,9 +25609,12 @@ msgstr "Ви також можете протеÑтувати ваш %{gitlab_ci
msgid "You can also upload existing files from your computer using the instructions below."
msgstr "Також ви можете завантажувати файли з вашого комп'ютера за допомогою нижченаведених інÑтрукцій."
-msgid "You can always edit this later"
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
msgstr ""
+msgid "You can always edit this later"
+msgstr "Ви завжди можете відредагувати це пізніше"
+
msgid "You can apply your Trial to your Personal account or create a New Group."
msgstr "Ви можете заÑтоÑувати пробну верÑÑ–ÑŽ до ОÑобиÑтого облікового запиÑу або Ñтворити Ðову Групу."
@@ -24286,6 +25639,9 @@ msgstr "Ви можете легко вÑтановити Runner на клаÑÑ‚
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr "Ви можете фільтрувати за \"днÑми до злиттÑ\", натиÑнувши на колонки в таблиці."
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24301,6 +25657,9 @@ msgstr "Ви можете запроÑити нову групу до <strong>%{
msgid "You can move around the graph by using the arrow keys."
msgstr "Ви можете переÑуватиÑÑ Ð¿Ð¾ графу за допомогою клавіш зі Ñтрілками."
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24379,6 +25738,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr "У Ð²Ð°Ñ Ñ‰Ðµ немає підпиÑок"
@@ -24427,6 +25789,9 @@ msgstr "У Ð²Ð°Ñ Ð½Ðµ має доÑтупу до Ðналітики ПродуÐ
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr "Вам надано %{access_level} доÑтуп до %{source_link} %{source_type}."
@@ -24442,7 +25807,7 @@ msgstr "Ви відпиÑані від цього обговореннÑ."
msgid "You have declined the invitation to join %{label}."
msgstr "Ви відхилили Ð·Ð°Ð¿Ñ€Ð¾ÑˆÐµÐ½Ð½Ñ Ð¿Ñ€Ð¸Ñ”Ð´Ð½Ð°Ñ‚Ð¸ÑÑ Ð´Ð¾ %{label}."
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24535,6 +25900,9 @@ msgstr "Ви намагалиÑÑ Ñтворити Ð²Ñ–Ð´Ð³Ð°Ð»ÑƒÐ¶ÐµÐ½Ð½Ñ (Ñ„Ð
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24562,6 +25930,9 @@ msgstr "Ви будете отримувати Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ Ð
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr "Ви будете отримувати Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ‚Ñ–Ð»ÑŒÐºÐ¸ Ð´Ð»Ñ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ñ–Ð², в Ñких ви були @згадані"
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr "Ви не зможете відправлÑти та отримувати код проекту через %{protocol} поки не %{set_password_link} Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ облікового запиÑу"
@@ -24580,6 +25951,12 @@ msgstr "Ви збираєтеÑÑ Ð·Ð¼ÐµÐ½ÑˆÐ¸Ñ‚Ð¸ видиміÑÑ‚ÑŒ проєк
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr "Ви збираєтеÑÑ Ð·Ð¼ÐµÐ½ÑˆÐ¸Ñ‚Ð¸ видиміÑÑ‚ÑŒ проєкту %{strong_start}%{project_name}%{strong_end}."
+msgid "You're at the first commit"
+msgstr ""
+
+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 "Вам не дозволено %{tag_start}редагувати%{tag_end} файли в цьому проекті. Будь лаÑка, зробіть форк цього проекту, внеÑÑ–Ñ‚ÑŒ туди Ñвої зміни Ñ– Ñтворіть запит на злиттÑ."
@@ -24613,7 +25990,10 @@ msgstr "Ви уже увімкнули двофакторну автентифі
msgid "YouTube"
msgstr "YouTube"
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24641,7 +26021,7 @@ msgid "Your GPG keys (%{count})"
msgstr "Ваші ключі GPG (%{count})"
msgid "Your GitLab group"
-msgstr ""
+msgstr "Ваша група GitLab"
msgid "Your Gitlab Gold trial will last 30 days after which point you can keep your free Gitlab account forever. We just need some additional information to activate your trial."
msgstr ""
@@ -24649,8 +26029,8 @@ msgstr ""
msgid "Your Groups"
msgstr "Ваші групи"
-msgid "Your New Personal Access Token"
-msgstr "Ваш новий перÑональний токен доÑтупу"
+msgid "Your License"
+msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
msgstr "Термін дії вашого перÑонального токену доÑтупу закінчитьÑÑ Ñ‡ÐµÑ€ÐµÐ· %{days_to_expire} днів або менше"
@@ -24659,7 +26039,7 @@ msgid "Your Primary Email will be used for avatar detection."
msgstr "Ваша оÑновна адреÑа електронної пошти буде викориÑтовуватиÑÑ Ð´Ð»Ñ Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð°Ð²Ð°Ñ‚Ð°Ñ€Ñƒ."
msgid "Your Projects (default)"
-msgstr "Ваші проекти (за замовчуваннÑм)"
+msgstr "Ваші проєкти (за замовчуваннÑм)"
msgid "Your Projects' Activity"
msgstr "ÐктивніÑÑ‚ÑŒ ваших проектів"
@@ -24731,10 +26111,10 @@ msgid "Your custom stage '%{title}' was created"
msgstr ""
msgid "Your dashboard has been copied. You can %{web_ide_link_start}edit it here%{web_ide_link_end}."
-msgstr ""
+msgstr "Ваша панель ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð±ÑƒÐ»Ð° Ñкопійована. Ви можете %{web_ide_link_start}відредагувати Ñ—Ñ— тут%{web_ide_link_end}."
msgid "Your dashboard has been updated. You can %{web_ide_link_start}edit it here%{web_ide_link_end}."
-msgstr ""
+msgstr "Ваша панель ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð±ÑƒÐ»Ð° оновлена. Ви можете %{web_ide_link_start}відредагувати Ñ—Ñ— тут%{web_ide_link_end}."
msgid "Your deployment services will be broken, you will need to manually fix the services after renaming."
msgstr "Ваші ÑервіÑи Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ð±ÑƒÐ´ÑƒÑ‚ÑŒ порушені, вам необхідно буде вручну Ñ—Ñ… виправити піÑÐ»Ñ Ð¿ÐµÑ€ÐµÐ¹Ð¼ÐµÐ½ÑƒÐ²Ð°Ð½Ð½Ñ."
@@ -24742,9 +26122,18 @@ msgstr "Ваші ÑервіÑи Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ð±ÑƒÐ´ÑƒÑ‚ÑŒ поруше
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr "Ваш приÑтрій уÑпішно налаштовано! Дайте йому ім'Ñ Ñ‚Ð° зареєÑтруйте його на Ñервері GitLab."
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr "Ваші групи"
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr "Ваші задачі імпортуютьÑÑ. ПіÑÐ»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ð²Ð¸ отримаєте Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ð¾ електронній пошті із підтвердженнÑм."
@@ -24754,12 +26143,18 @@ msgstr "Ваші задачі будуть імпортовані в фоні. Ð
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr "Ваше Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ‚ÑƒÑ‚"
msgid "Your name"
msgstr "Ваше ім'Ñ"
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr "Ваш новий токен SCIM"
@@ -24782,16 +26177,22 @@ msgid "Your project limit is %{limit} projects! Please contact your administrato
msgstr "Ваш ліміт проектів Ñкладає %{limit}! Будь лаÑка, звернітьÑÑ Ð´Ð¾ адмініÑтратора, щоб його збільшити"
msgid "Your projects"
-msgstr "Ваші проекти"
+msgstr "Ваші проєкти"
+
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
msgid "Your request for access has been queued for review."
msgstr "Ваш запит на Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð¾Ñтупу поÑтавлено в чергу Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ¸."
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
msgid "Your subscription expired!"
-msgstr ""
+msgstr "Термін дії вашої підпиÑки закінчивÑÑ!"
msgid "Your subscription has been downgraded"
msgstr ""
@@ -24809,7 +26210,7 @@ msgid "Zoom meeting removed"
msgstr "Zoom-зуÑтріч видалено"
msgid "[No reason]"
-msgstr ""
+msgstr "[Без причини]"
msgid "a deleted user"
msgstr "видалений кориÑтувач"
@@ -24825,7 +26226,7 @@ msgstr[2] "близько %d годин"
msgstr[3] "близько %d годин"
msgid "activated"
-msgstr ""
+msgstr "активований"
msgid "added %{created_at_timeago}"
msgstr "додано %{created_at_timeago}"
@@ -24836,6 +26237,9 @@ msgstr "додано дзвінок Zoom до цієї задачі"
msgid "ago"
msgstr "тому"
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr "невдача дозволена"
@@ -24878,6 +26282,9 @@ msgstr ""
msgid "branch name"
msgstr "ім'Ñ Ð³Ñ–Ð»ÐºÐ¸"
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr "від"
@@ -25057,11 +26464,14 @@ msgstr "Динамічне теÑÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð±ÐµÐ·Ð¿ÐµÐºÐ¸ заÑтоÑунÐ
msgid "ciReport|Failed to load %{reportName} report"
msgstr "Помилка при завантаженні звіту %{reportName}"
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr "Виправлено:"
msgid "ciReport|Found %{issuesWithCount}"
-msgstr ""
+msgstr "Знайдено %{issuesWithCount}"
msgid "ciReport|Investigate this vulnerability by creating an issue"
msgstr "ДоÑлідити цю вразливіÑÑ‚ÑŒ, Ñтворивши задачу"
@@ -25075,6 +26485,9 @@ msgstr "Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð·Ð²Ñ–Ñ‚Ñƒ %{reportName}"
msgid "ciReport|Manage licenses"
msgstr "ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð»Ñ–Ñ†ÐµÐ½Ð·Ñ–Ñми"
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr "Ðемає змін у ÑкоÑÑ‚Ñ– коду"
@@ -25093,6 +26506,9 @@ msgstr "Вирішити за допомогою запиту на злиттÑ"
msgid "ciReport|SAST"
msgstr "SAST"
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -25136,6 +26552,9 @@ msgstr[3] "ВикориÑтовуєтьÑÑ %{packagesString} Ñ– %{lastPackage}"
msgid "ciReport|View full report"
msgstr "ПереглÑнути повний звіт"
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr "коментар"
@@ -25145,6 +26564,9 @@ msgstr "прокоментовано в %{link_to_project}"
msgid "commit %{commit_id}"
msgstr "коміт %{commit_id}"
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr "Ви вимикаєте конфіденційніÑÑ‚ÑŒ. Це означає, що <strong>будь-хто</strong> зможе бачити Ñ– залишати коментарі Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— задачі."
@@ -25154,6 +26576,9 @@ msgstr "Ви вмикаєте конфіденційніÑÑ‚ÑŒ. Це означÐ
msgid "connecting"
msgstr "з'єднаннÑ"
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr "container_name не може бути довше %{max_length} Ñимволів"
@@ -25201,11 +26626,14 @@ msgid "disabled"
msgstr "вимкнено"
msgid "does not have a supported extension. Only %{extension_list} are supported"
-msgstr ""
+msgstr "не підтримує розширеннÑ. ПідтримуютьÑÑ Ð»Ð¸ÑˆÐµ %{extension_list}"
msgid "done"
msgstr "готово"
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] "чернетка"
@@ -25219,8 +26647,11 @@ msgstr "напр. %{token}"
msgid "element is not a hierarchy"
msgstr "елемент відÑутній в ієрархії"
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
-msgstr "адреÑа електронної пошти \"%{email}\" не відповідає дозволеному домену \"%{email_domain}\""
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
+msgstr ""
msgid "enabled"
msgstr "увімкнено"
@@ -25252,11 +26683,11 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
-msgstr "закінчено %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
+msgstr ""
-msgid "expires on %{milestone_due_date}"
-msgstr "закінчуєтьÑÑ %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
+msgstr ""
msgid "external_url"
msgstr ""
@@ -25290,7 +26721,7 @@ msgid "for %{ref}"
msgstr "Ð´Ð»Ñ %{ref}"
msgid "for this project"
-msgstr "Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ проекту"
+msgstr "Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ проєкту"
msgid "fork this project"
msgstr "зробити форк цього проєкту"
@@ -25305,7 +26736,7 @@ msgid "group"
msgstr "група"
msgid "groups"
-msgstr ""
+msgstr "групи"
msgid "has already been linked to another vulnerability"
msgstr "було прив’Ñзано до іншої вразливоÑÑ‚Ñ–"
@@ -25322,9 +26753,18 @@ msgstr "тут"
msgid "https://your-bitbucket-server"
msgstr "https://your-bitbucket-server"
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr "Ñ€Ñ–Ð·Ð½Ð¸Ñ†Ñ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ"
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr "процедура імпорту"
@@ -25381,7 +26821,7 @@ msgid "is not a valid X509 certificate."
msgstr "не відповідний Ñертифікат X509."
msgid "is not allowed. Try again with a different email address, or contact your GitLab admin."
-msgstr ""
+msgstr "не дозволено. Спробуйте ще раз з іншою адреÑою електронної пошти або зв'ÑжітьÑÑ Ð· адмініÑтратором GitLab."
msgid "is not an email you own"
msgstr "не Ñ” адреÑою електронної пошти, Ñкою ви володієте"
@@ -25389,6 +26829,9 @@ msgstr "не Ñ” адреÑою електронної пошти, Ñкою ви
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr "Ñ” занадто довгим (%{current_value}). МакÑимальний розмір Ñкладає %{max_size}."
@@ -25410,6 +26853,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr "зберігаєтьÑÑ Ð·Ð¾Ð²Ð½Ñ–"
@@ -25417,7 +26866,7 @@ msgid "it is stored in LFS"
msgstr "зберігаєтьÑÑ Ð² LFS"
msgid "it is too large"
-msgstr "він є завеликим"
+msgstr ""
msgid "jigsaw is not defined"
msgstr "jigsaw не визначено"
@@ -25441,7 +26890,7 @@ msgid "leave %{group_name}"
msgstr "залишити %{group_name}"
msgid "less than a minute"
-msgstr ""
+msgstr "менше хвилини"
msgid "level: %{level}"
msgstr "рівень: %{level}"
@@ -25449,6 +26898,9 @@ msgstr "рівень: %{level}"
msgid "limit of %{project_limit} reached"
msgstr "доÑÑгнуто ліміт %{project_limit}"
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr "заблоковано %{path_lock_user_name} %{created_at}"
@@ -25472,7 +26924,7 @@ msgstr[2] "запитів на злиттÑ"
msgstr[3] "запитів на злиттÑ"
msgid "merged %{time_ago}"
-msgstr ""
+msgstr "об’єднано %{time_ago}"
msgid "missing"
msgstr "відÑутні"
@@ -25579,7 +27031,7 @@ msgstr "Видалити гілку-джерело"
msgid "mrWidget|Deployment statistics are not available currently"
msgstr "СтатиÑтика Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ð½Ð°Ñ€Ð°Ð·Ñ– недоÑтупна"
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25748,7 +27200,7 @@ msgid "mrWidget|When this merge request is ready, remove the WIP: prefix from th
msgstr "Коли цей запит на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð±ÑƒÐ´Ðµ готовий, видаліть Ð¿Ñ€ÐµÑ„Ñ–ÐºÑ \"WIP:\" із заголовку, щоб можна було виконати злиттÑ"
msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
-msgstr "Ви не можете безпоÑередньо редагувати цей проект. Будь лаÑка, зробіть форк, щоб внеÑти зміни."
+msgstr "Ви не можете безпоÑередньо редагувати цей проєкт. Будь лаÑка, зробіть форк, щоб внеÑти зміни."
msgid "mrWidget|You can delete the source branch now"
msgstr "Тепер ви можете видалити гілку-джерело"
@@ -25759,9 +27211,6 @@ msgstr "Ви можете прийнÑти цей запит на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð
msgid "mrWidget|Your password"
msgstr "Ваш пароль"
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr "гілка не Ñ–Ñнує."
@@ -25771,15 +27220,6 @@ msgstr "командного Ñ€Ñдка"
msgid "mrWidget|into"
msgstr "в"
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr "буде додано до ланцюжка змін піÑÐ»Ñ ÑƒÑпішного Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ ÐºÐ¾Ð½Ð²ÐµÑ”Ñ€Ð°"
@@ -25792,6 +27232,9 @@ msgstr "Ñтворити ланцюжок змін піÑÐ»Ñ ÑƒÑпішного
msgid "must be greater than start date"
msgstr "повинна бути пізніша за дату початку"
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr "н/д"
@@ -25837,6 +27280,9 @@ msgstr "%{item}, Ñ– %{lastItem}"
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr "відкрито %{timeAgoString} %{user}"
@@ -25870,11 +27316,20 @@ msgid "pending removal"
msgstr "очікуєтьÑÑ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ"
msgid "per day"
+msgstr "за день"
+
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
msgstr ""
msgid "pipeline"
msgstr "конвеєр"
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr "pod_name не може бути довше %{max_length} Ñимволів"
@@ -25896,16 +27351,22 @@ msgstr "в процеÑÑ–"
msgid "project"
msgid_plural "projects"
-msgstr[0] "проект"
-msgstr[1] "проекти"
-msgstr[2] "проектів"
-msgstr[3] "проектів"
+msgstr[0] "проєкт"
+msgstr[1] "проєкти"
+msgstr[2] "проєктів"
+msgstr[3] "проєктів"
+
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
msgid "project avatar"
-msgstr "аватар проекту"
+msgstr "аватар проєкту"
msgid "projects"
-msgstr ""
+msgstr "проєкти"
msgid "push to your repository, create pipelines, create issues or add comments. To reduce storage capacity, delete unused repositories, artifacts, wikis, issues, and pipelines."
msgstr ""
@@ -25953,6 +27414,9 @@ msgstr "Ñкинути його."
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr "результат"
@@ -25960,7 +27424,7 @@ msgid "security Reports|There was an error creating the merge request"
msgstr "помилка при Ñтворенні запиту на злиттÑ"
msgid "settings saved, but not activated"
-msgstr ""
+msgstr "Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð¾, але не активовано"
msgid "severity|Critical"
msgstr "Критичний"
@@ -26019,11 +27483,11 @@ msgstr "розпочато"
msgid "started a discussion on %{design_link}"
msgstr "розпочато Ð¾Ð±Ð³Ð¾Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ %{design_link}"
-msgid "started on %{milestone_start_date}"
-msgstr "розпочато %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
+msgstr ""
-msgid "starts on %{milestone_start_date}"
-msgstr "розпочинаєтьÑÑ %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
+msgstr ""
msgid "stuck"
msgstr "заблоковано"
@@ -26085,6 +27549,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr "оновлено %{time_ago}"
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr "аватар кориÑтувача"
@@ -26112,6 +27582,9 @@ msgstr "переглÑнути це на GitLab"
msgid "view the blob"
msgstr "переглÑнути бінарні дані"
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -26139,6 +27612,9 @@ msgstr "відхилено"
msgid "wiki page"
msgstr "вікі-Ñторінка"
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr "з %{additions} додаваннÑми Ñ– %{deletions} видаленнÑми."
diff --git a/locale/ur_PK/gitlab.po b/locale/ur_PK/gitlab.po
index 40304c3ba3b..2af74f66d3e 100644
--- a/locale/ur_PK/gitlab.po
+++ b/locale/ur_PK/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: ur-PK\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:37\n"
+"PO-Revision-Date: 2020-06-08 15:08\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,13 +8991,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8627,7 +9009,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] ""
msgstr[1] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/uz_UZ/gitlab.po b/locale/uz_UZ/gitlab.po
index 3694bf80831..01b1e2e76eb 100644
--- a/locale/uz_UZ/gitlab.po
+++ b/locale/uz_UZ/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: uz\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:33\n"
+"PO-Revision-Date: 2020-06-08 15:12\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -74,6 +74,16 @@ msgid_plural "%d URLs scanned"
msgstr[0] ""
msgstr[1] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -94,6 +104,11 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -117,6 +132,11 @@ msgid_plural "%d contributions"
msgstr[0] ""
msgstr[1] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -187,6 +207,11 @@ msgid_plural "%d more comments"
msgstr[0] ""
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] ""
+msgstr[1] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -217,6 +242,16 @@ msgid_plural "%d unresolved threads"
msgstr[0] ""
msgstr[1] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -239,6 +274,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -316,6 +354,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -325,6 +366,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -337,6 +381,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -370,12 +438,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -391,6 +468,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -431,6 +514,12 @@ msgid_plural "%{releases} releases"
msgstr[0] ""
msgstr[1] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -578,6 +667,9 @@ msgid_plural "(%d closed)"
msgstr[0] ""
msgstr[1] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -782,6 +874,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -812,6 +907,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -821,6 +919,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -857,7 +958,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -908,6 +1012,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -920,9 +1027,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -968,9 +1072,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -1061,12 +1162,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1103,7 +1198,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1112,6 +1207,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1156,7 +1254,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1171,6 +1269,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1180,9 +1281,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1198,7 +1305,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1264,6 +1374,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1354,16 +1467,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1690,63 +1803,117 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
msgstr[1] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1755,16 +1922,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1938,6 +2123,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2103,9 +2291,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2127,6 +2312,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2202,6 +2390,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2238,9 +2429,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2256,6 +2453,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2265,6 +2465,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2289,12 +2492,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2304,9 +2501,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2370,6 +2573,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2438,12 +2644,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2453,12 +2653,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2567,6 +2773,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2579,7 +2788,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2693,6 +2902,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2769,15 +2981,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2835,6 +3065,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2856,9 +3089,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2877,6 +3107,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2907,6 +3140,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2922,6 +3158,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3399,16 +3638,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3432,7 +3671,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3441,6 +3680,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3459,6 +3701,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3489,9 +3734,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3519,6 +3761,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3594,7 +3842,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3609,6 +3857,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3645,6 +3896,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3687,6 +3944,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3705,6 +3965,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3810,15 +4073,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4167,9 +4421,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4182,6 +4433,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4194,6 +4448,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4221,9 +4478,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4263,6 +4517,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4458,6 +4715,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4479,9 +4739,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4533,7 +4790,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4560,6 +4817,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4638,10 +4898,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4800,6 +5060,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -5034,9 +5300,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5115,6 +5378,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5145,6 +5411,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5154,9 +5423,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5214,6 +5489,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5232,6 +5510,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5271,6 +5552,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5280,6 +5564,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5316,6 +5603,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5477,7 +5767,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5501,9 +5794,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5537,9 +5827,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5588,16 +5875,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5624,6 +5905,16 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5636,6 +5927,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5660,27 +5954,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5702,10 +6008,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5725,9 +6028,6 @@ msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
msgstr[1] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5749,6 +6049,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5776,12 +6079,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5800,7 +6097,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5809,7 +6109,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5848,10 +6148,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5938,6 +6238,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5983,9 +6286,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -6001,9 +6301,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6100,7 +6397,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6118,9 +6415,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6139,9 +6433,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6151,9 +6442,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6196,6 +6484,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6208,6 +6499,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6247,6 +6541,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6280,6 +6580,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6331,9 +6634,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6370,6 +6670,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6394,6 +6697,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6442,6 +6748,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6466,6 +6775,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6717,6 +7029,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6753,6 +7068,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6795,6 +7113,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6884,11 +7208,6 @@ msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
msgstr[1] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6924,12 +7243,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6939,9 +7252,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -7056,12 +7366,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7083,13 +7399,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7209,10 +7525,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7221,9 +7537,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7233,6 +7564,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7260,12 +7594,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7275,6 +7624,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7287,6 +7642,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7514,6 +7872,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7562,6 +7923,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7586,6 +7950,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7733,6 +8100,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7748,6 +8118,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7841,6 +8214,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7850,9 +8226,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7880,6 +8253,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -8003,6 +8379,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -8027,10 +8406,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8087,7 +8466,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8300,10 +8679,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8315,12 +8694,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8390,7 +8763,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8495,9 +8877,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8513,6 +8892,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8564,10 +8946,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8609,13 +8991,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8627,7 +9009,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8666,6 +9048,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8684,6 +9069,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8717,6 +9105,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8732,6 +9123,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8741,6 +9135,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8819,18 +9216,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8957,6 +9342,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -9032,7 +9420,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9095,6 +9483,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9107,6 +9501,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9116,15 +9513,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9143,6 +9549,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9158,9 +9567,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9251,6 +9666,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9263,6 +9681,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9272,9 +9693,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9290,24 +9708,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9317,6 +9756,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9548,9 +9990,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9590,15 +10029,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9776,6 +10215,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9785,10 +10230,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9839,6 +10284,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9890,6 +10341,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9908,6 +10362,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9917,6 +10374,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10169,9 +10632,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10205,9 +10665,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10370,12 +10827,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10409,6 +10875,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10421,10 +10893,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10442,10 +10917,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10463,12 +10941,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10535,9 +11019,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10739,6 +11220,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10844,6 +11328,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10853,6 +11340,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10959,6 +11449,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10968,6 +11461,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11118,6 +11614,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11127,7 +11626,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11136,6 +11638,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11148,7 +11656,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11166,13 +11677,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11184,6 +11695,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11193,6 +11707,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11202,10 +11719,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11298,10 +11815,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11334,6 +11851,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11367,6 +11887,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11391,18 +11917,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11453,6 +11997,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11492,6 +12060,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11528,18 +12102,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11552,6 +12135,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11615,6 +12201,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11627,6 +12216,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11684,6 +12300,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11729,6 +12348,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11741,19 +12384,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11879,6 +12525,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11918,6 +12567,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12097,6 +12749,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12181,6 +12836,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12202,9 +12860,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12232,6 +12887,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12244,6 +12902,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12268,15 +12929,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12411,6 +13066,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12426,6 +13084,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12521,6 +13182,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12635,10 +13299,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12665,6 +13329,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12716,9 +13383,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12728,9 +13392,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12908,6 +13569,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12917,9 +13581,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12932,6 +13593,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12965,6 +13629,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -13013,9 +13680,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -13076,7 +13752,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13094,6 +13770,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13115,9 +13794,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13139,19 +13815,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13175,6 +13854,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13231,6 +13931,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13249,6 +13955,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13285,6 +13994,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13347,6 +14059,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13356,6 +14125,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13365,21 +14140,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13440,6 +14233,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13554,6 +14350,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13563,6 +14362,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13575,9 +14377,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13587,9 +14386,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13623,6 +14419,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13652,6 +14496,9 @@ msgid_plural "New Issues"
msgstr[0] ""
msgstr[1] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13718,6 +14565,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13775,6 +14625,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13793,18 +14646,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13895,12 +14739,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13925,6 +14775,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -14060,6 +14913,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -14084,6 +14940,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14198,9 +15057,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14267,6 +15132,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14276,9 +15150,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14344,7 +15215,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14389,7 +15260,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14404,6 +15275,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14434,7 +15308,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14482,6 +15356,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14500,6 +15377,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14521,6 +15401,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14608,6 +15494,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14626,6 +15515,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14656,22 +15548,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14704,6 +15611,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14791,6 +15701,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14809,6 +15722,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14851,9 +15767,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14875,9 +15797,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14899,9 +15818,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -15010,6 +15926,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -15070,15 +15989,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -15091,30 +16019,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15130,6 +16082,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15166,6 +16121,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15259,6 +16220,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15334,6 +16298,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15424,6 +16391,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15460,6 +16430,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15679,9 +16652,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15727,9 +16697,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15874,12 +16841,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15910,6 +16871,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15931,6 +16895,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15961,6 +16928,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15985,7 +16955,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15994,6 +16964,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16108,9 +17081,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16276,6 +17246,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16321,6 +17294,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16471,6 +17447,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16564,12 +17543,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16645,9 +17630,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16666,30 +17648,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16825,9 +17861,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16837,6 +17870,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16939,6 +17978,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16948,9 +17990,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16987,9 +18026,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -17085,6 +18121,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17129,6 +18180,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17150,6 +18213,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17219,6 +18285,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17261,6 +18333,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17300,6 +18375,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17351,6 +18429,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17381,6 +18462,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17396,7 +18480,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17500,6 +18587,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17536,6 +18626,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17551,10 +18644,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17569,6 +18665,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17590,10 +18692,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17663,6 +18762,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17675,6 +18777,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17821,6 +18929,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17884,9 +18995,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17923,9 +19031,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -18055,9 +19160,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18115,6 +19226,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18145,10 +19259,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18237,9 +19351,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18252,9 +19372,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18264,24 +19381,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18417,6 +19534,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18498,6 +19618,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18549,12 +19672,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18600,9 +19729,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18675,6 +19813,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18840,6 +19984,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18876,6 +20023,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18960,6 +20110,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18978,7 +20131,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -19017,15 +20170,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -19050,12 +20203,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -19076,6 +20238,14 @@ msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19262,6 +20432,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19298,9 +20471,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19397,6 +20576,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19436,6 +20618,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19484,6 +20669,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19601,6 +20792,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19766,7 +20960,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19841,6 +21035,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19967,6 +21164,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19994,6 +21194,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -20021,6 +21224,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20201,9 +21407,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20288,6 +21500,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20315,9 +21530,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20569,6 +21781,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20652,9 +21867,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20691,9 +21903,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20732,6 +21950,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20906,6 +22127,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20954,6 +22178,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -21029,6 +22256,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -21101,6 +22337,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21164,6 +22403,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21248,6 +22490,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21287,6 +22532,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21332,9 +22580,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21446,7 +22691,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21473,6 +22718,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21509,12 +22757,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21527,12 +22781,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21551,7 +22817,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21560,9 +22826,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21617,9 +22880,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21866,6 +23135,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21930,6 +23202,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -22050,6 +23328,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -22107,15 +23388,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22131,9 +23406,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22152,6 +23424,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22263,6 +23538,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22320,10 +23598,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22332,6 +23610,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22371,6 +23652,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22380,9 +23664,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22632,18 +23922,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22662,6 +23946,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22680,6 +23967,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22704,9 +23994,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22716,12 +24003,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22731,12 +24024,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22755,12 +24054,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22785,7 +24090,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22860,9 +24165,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -23109,6 +24411,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23169,6 +24477,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23196,7 +24507,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23238,6 +24552,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23284,6 +24601,9 @@ msgstr[1] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23347,6 +24667,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23428,9 +24751,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23461,9 +24781,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23572,6 +24889,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23584,6 +24904,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23605,7 +24928,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23647,9 +24976,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23689,12 +25015,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23730,9 +25065,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23766,9 +25098,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23889,10 +25218,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23901,10 +25233,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -24021,6 +25353,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -24048,6 +25383,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -24063,6 +25401,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24141,6 +25482,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24189,6 +25533,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24204,7 +25551,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24297,6 +25644,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24324,6 +25674,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24342,6 +25695,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24375,7 +25734,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24411,7 +25773,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24504,9 +25866,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24516,12 +25887,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24546,9 +25923,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24596,6 +25979,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24638,6 +26024,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24807,6 +26196,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24825,6 +26217,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24843,6 +26238,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24884,6 +26282,9 @@ msgstr[1] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24893,6 +26294,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24902,6 +26306,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24952,6 +26359,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24963,7 +26373,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24996,10 +26409,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -25064,9 +26477,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -25129,6 +26551,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25150,6 +26575,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25189,6 +26620,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25317,7 +26751,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25497,9 +26931,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25509,15 +26940,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25530,6 +26952,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25575,6 +27000,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25606,9 +27034,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25631,6 +27068,12 @@ msgid_plural "projects"
msgstr[0] ""
msgstr[1] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25681,6 +27124,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25747,10 +27193,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25813,6 +27259,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25840,6 +27292,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25867,6 +27322,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/vi_VN/gitlab.po b/locale/vi_VN/gitlab.po
index a2c51f338f0..deaca86ee6a 100644
--- a/locale/vi_VN/gitlab.po
+++ b/locale/vi_VN/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: vi\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:34\n"
+"PO-Revision-Date: 2020-06-08 15:08\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -71,6 +71,14 @@ msgid "%d URL scanned"
msgid_plural "%d URLs scanned"
msgstr[0] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -87,6 +95,10 @@ msgid "%d comment"
msgid_plural "%d comments"
msgstr[0] ""
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] ""
@@ -106,6 +118,10 @@ msgid "%d contribution"
msgid_plural "%d contributions"
msgstr[0] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -162,6 +178,10 @@ msgid "%d more comment"
msgid_plural "%d more comments"
msgstr[0] ""
+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] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -186,6 +206,14 @@ msgid "%d unresolved thread"
msgid_plural "%d unresolved threads"
msgstr[0] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -206,6 +234,9 @@ msgstr ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -279,6 +310,9 @@ msgstr ""
msgid "%{firstLabel} +%{labelCount} more"
msgstr ""
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -288,6 +322,9 @@ msgstr ""
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -300,6 +337,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -333,12 +394,21 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -354,6 +424,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr ""
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -392,6 +468,12 @@ msgid "%{releases} release"
msgid_plural "%{releases} releases"
msgstr[0] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -533,6 +615,9 @@ msgid "(%d closed)"
msgid_plural "(%d closed)"
msgstr[0] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -719,6 +804,9 @@ msgstr ""
msgid "8 hours"
msgstr ""
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -749,6 +837,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr ""
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr ""
@@ -758,6 +849,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -794,7 +888,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -845,6 +942,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -857,9 +957,6 @@ msgstr ""
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -905,9 +1002,6 @@ msgstr ""
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr ""
@@ -998,12 +1092,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1040,7 +1128,7 @@ msgstr ""
msgid "Active"
msgstr ""
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1049,6 +1137,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr ""
@@ -1092,7 +1183,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1107,6 +1198,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1116,9 +1210,15 @@ msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
msgstr ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr ""
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1134,7 +1234,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1200,6 +1303,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1290,16 +1396,16 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr ""
-msgid "Admin Overview"
+msgid "Admin Note"
msgstr ""
-msgid "Admin Section"
+msgid "Admin Overview"
msgstr ""
msgid "Admin mode already enabled"
@@ -1626,62 +1732,116 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Low"
+msgstr ""
+
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1690,16 +1850,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertManagement|Unknown"
+msgstr ""
+
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
+
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1873,6 +2051,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2038,9 +2219,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr ""
@@ -2062,6 +2240,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2137,6 +2318,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr ""
@@ -2173,9 +2357,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2191,6 +2381,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2200,6 +2393,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2224,12 +2420,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2239,9 +2429,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2305,6 +2501,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2369,12 +2568,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2384,12 +2577,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2498,6 +2697,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2510,7 +2712,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2624,6 +2826,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2698,15 +2903,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -2764,6 +2987,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2785,9 +3011,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2806,6 +3029,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2836,6 +3062,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2851,6 +3080,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3328,16 +3560,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3361,7 +3593,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3370,6 +3602,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3388,6 +3623,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3418,9 +3656,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3448,6 +3683,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3523,7 +3764,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3538,6 +3779,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3574,6 +3818,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3616,6 +3866,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3634,6 +3887,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3739,15 +3995,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4096,9 +4343,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4111,6 +4355,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4123,6 +4370,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4150,9 +4400,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4192,6 +4439,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4387,6 +4637,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4408,9 +4661,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4462,7 +4712,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4489,6 +4739,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4567,10 +4820,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4729,6 +4982,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -4963,9 +5222,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5044,6 +5300,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5074,6 +5333,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5083,9 +5345,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5143,6 +5411,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5161,6 +5432,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5200,6 +5474,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5209,6 +5486,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5245,6 +5525,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5405,7 +5688,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5429,9 +5715,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5465,9 +5748,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5516,16 +5796,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5552,6 +5826,14 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5564,6 +5846,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5588,27 +5873,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5630,10 +5927,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5652,9 +5946,6 @@ msgid "ContainerRegistry|Remove tag"
msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5676,6 +5967,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5703,12 +5997,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5727,7 +6015,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5736,7 +6027,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5775,10 +6066,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5865,6 +6156,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5910,9 +6204,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -5928,9 +6219,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6027,7 +6315,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6045,9 +6333,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6066,9 +6351,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6078,9 +6360,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6123,6 +6402,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6135,6 +6417,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6174,6 +6459,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6207,6 +6498,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6258,9 +6552,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6297,6 +6588,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6321,6 +6615,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6369,6 +6666,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6393,6 +6693,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6643,6 +6946,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6679,6 +6985,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6721,6 +7030,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6809,10 +7124,6 @@ msgid "Dependencies|%d additional vulnerability not shown"
msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6847,12 +7158,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6862,9 +7167,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -6976,12 +7278,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7003,13 +7311,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7129,10 +7437,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7141,9 +7449,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7153,6 +7476,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7180,12 +7506,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7195,6 +7536,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7207,6 +7554,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7433,6 +7783,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7481,6 +7834,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7505,6 +7861,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7652,6 +8011,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7667,6 +8029,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7760,6 +8125,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7769,9 +8137,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7799,6 +8164,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -7922,6 +8290,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -7946,10 +8317,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8006,7 +8377,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8219,10 +8590,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8234,12 +8605,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8309,7 +8674,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8414,9 +8788,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8432,6 +8803,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8483,10 +8857,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8528,13 +8902,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8546,7 +8920,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8585,6 +8959,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8603,6 +8980,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8636,6 +9016,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8651,6 +9034,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8660,6 +9046,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8738,18 +9127,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8876,6 +9253,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -8951,7 +9331,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9014,6 +9394,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9026,6 +9412,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9035,15 +9424,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9062,6 +9460,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9077,9 +9478,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9170,6 +9577,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9182,6 +9592,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9191,9 +9604,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9209,24 +9619,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9236,6 +9667,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9467,9 +9901,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9509,15 +9940,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9695,6 +10126,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9704,10 +10141,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9758,6 +10195,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9809,6 +10252,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9827,6 +10273,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9836,6 +10285,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10088,9 +10543,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10124,9 +10576,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10289,12 +10738,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10328,6 +10786,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10340,10 +10804,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10361,10 +10828,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10382,12 +10852,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10454,9 +10930,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10658,6 +11131,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10763,6 +11239,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10772,6 +11251,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10876,6 +11358,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10885,6 +11370,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11035,6 +11523,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11044,7 +11535,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11053,6 +11547,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11065,7 +11565,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11083,13 +11586,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11101,6 +11604,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11110,6 +11616,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11119,10 +11628,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11215,10 +11724,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11251,6 +11760,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11284,6 +11796,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11308,18 +11826,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11369,6 +11905,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11408,6 +11968,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11444,18 +12010,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11468,6 +12043,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11531,6 +12109,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11543,6 +12124,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11600,6 +12208,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11645,6 +12256,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11657,19 +12292,22 @@ msgstr ""
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11795,6 +12433,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11834,6 +12475,9 @@ msgstr ""
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12012,6 +12656,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12096,6 +12743,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12117,9 +12767,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12147,6 +12794,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12159,6 +12809,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12183,15 +12836,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12322,6 +12969,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12337,6 +12987,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12431,6 +13084,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12545,10 +13201,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12575,6 +13231,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12626,9 +13285,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12638,9 +13294,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12818,6 +13471,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12827,9 +13483,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12842,6 +13495,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12875,6 +13531,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -12923,9 +13582,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -12986,7 +13654,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13004,6 +13672,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13025,9 +13696,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13049,19 +13717,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13085,6 +13756,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13140,6 +13832,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13158,6 +13856,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13194,6 +13895,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13255,6 +13959,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13264,6 +14025,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13273,21 +14040,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13348,6 +14133,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13462,6 +14250,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13471,6 +14262,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13483,9 +14277,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13495,9 +14286,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13531,6 +14319,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13559,6 +14395,9 @@ msgid "New Issue"
msgid_plural "New Issues"
msgstr[0] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13625,6 +14464,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13682,6 +14524,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13700,18 +14545,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13802,12 +14638,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13832,6 +14674,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -13967,6 +14812,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -13991,6 +14839,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14105,9 +14956,15 @@ msgstr ""
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14174,6 +15031,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14183,9 +15049,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14250,7 +15113,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14295,7 +15158,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14310,6 +15173,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14340,7 +15206,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14388,6 +15254,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14406,6 +15275,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14427,6 +15299,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14514,6 +15392,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14532,6 +15413,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14562,22 +15446,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14610,6 +15509,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14697,6 +15599,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14715,6 +15620,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14757,9 +15665,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14781,9 +15695,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14805,9 +15716,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -14916,6 +15824,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -14976,15 +15887,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -14997,30 +15917,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15036,6 +15980,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15072,6 +16019,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15165,6 +16118,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15240,6 +16196,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15330,6 +16289,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15366,6 +16328,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15585,9 +16550,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15633,9 +16595,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15780,12 +16739,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15816,6 +16769,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15837,6 +16793,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15867,6 +16826,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15891,7 +16853,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15900,6 +16862,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16014,9 +16979,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16182,6 +17144,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16227,6 +17192,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16377,6 +17345,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16470,12 +17441,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16551,9 +17528,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16572,30 +17546,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16731,9 +17759,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16743,6 +17768,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16845,6 +17876,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16854,9 +17888,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16893,9 +17924,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -16990,6 +18018,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17033,6 +18076,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17054,6 +18109,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17123,6 +18181,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17165,6 +18229,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17204,6 +18271,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17255,6 +18325,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17285,6 +18358,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17300,7 +18376,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17403,6 +18482,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17439,6 +18521,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17454,10 +18539,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17472,6 +18560,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17493,10 +18587,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17564,6 +18655,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17576,6 +18670,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17721,6 +18821,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17784,9 +18887,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17823,9 +18923,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -17955,9 +19052,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18015,6 +19118,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18045,10 +19151,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18127,9 +19233,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18142,9 +19254,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18154,24 +19263,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18307,6 +19416,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18388,6 +19500,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18439,12 +19554,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18490,9 +19611,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18565,6 +19695,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18730,6 +19866,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18766,6 +19905,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18850,6 +19992,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18868,7 +20013,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -18907,15 +20052,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -18940,12 +20085,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -18965,6 +20119,13 @@ msgid "Showing %d event"
msgid_plural "Showing %d events"
msgstr[0] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19151,6 +20312,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19187,9 +20351,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19286,6 +20456,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19325,6 +20498,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19373,6 +20549,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19490,6 +20672,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19655,7 +20840,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19730,6 +20915,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19856,6 +21044,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19883,6 +21074,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -19910,6 +21104,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20090,9 +21287,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20177,6 +21380,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20204,9 +21410,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20457,6 +21660,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20539,9 +21745,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20578,9 +21781,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20618,6 +21827,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20792,6 +22004,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20840,6 +22055,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -20915,6 +22133,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -20987,6 +22214,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21050,6 +22280,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21134,6 +22367,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21173,6 +22409,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21218,9 +22457,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21332,7 +22568,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21359,6 +22595,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21395,12 +22634,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21413,12 +22658,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21437,7 +22694,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21446,9 +22703,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21503,9 +22757,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21752,6 +23012,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21814,6 +23077,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -21934,6 +23203,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -21991,15 +23263,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22015,9 +23281,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22036,6 +23299,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22147,6 +23413,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22204,10 +23473,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22216,6 +23485,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22255,6 +23527,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22264,9 +23539,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22516,18 +23797,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22546,6 +23821,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22564,6 +23842,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22588,9 +23869,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22600,12 +23878,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22615,12 +23899,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22639,12 +23929,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22669,7 +23965,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22744,9 +24040,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -22993,6 +24286,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23053,6 +24352,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23080,7 +24382,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23122,6 +24427,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23166,6 +24474,9 @@ msgstr[0] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23229,6 +24540,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23310,9 +24624,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23343,9 +24654,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23454,6 +24762,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23466,6 +24777,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23487,7 +24801,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23529,9 +24849,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23571,12 +24888,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23611,9 +24937,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23647,9 +24970,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23770,10 +25090,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23782,10 +25105,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -23902,6 +25225,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -23929,6 +25255,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -23944,6 +25273,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24022,6 +25354,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24070,6 +25405,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24085,7 +25423,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24178,6 +25516,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24205,6 +25546,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24223,6 +25567,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24256,7 +25606,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24292,7 +25645,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24385,9 +25738,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24397,12 +25759,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24427,9 +25795,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24476,6 +25850,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24518,6 +25895,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24682,6 +26062,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24700,6 +26083,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24718,6 +26104,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24758,6 +26147,9 @@ msgstr[0] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24767,6 +26159,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24776,6 +26171,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24825,6 +26223,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24835,7 +26236,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24868,10 +26272,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -24935,9 +26339,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -24999,6 +26412,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25020,6 +26436,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25059,6 +26481,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25186,7 +26611,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25366,9 +26791,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25378,15 +26800,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25399,6 +26812,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25444,6 +26860,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25473,9 +26892,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25496,6 +26924,12 @@ msgid "project"
msgid_plural "projects"
msgstr[0] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25545,6 +26979,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25611,10 +27048,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25677,6 +27114,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25704,6 +27147,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25731,6 +27177,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/zh_CN/gitlab.po b/locale/zh_CN/gitlab.po
index 2e5f39c0ff4..d64092020ab 100644
--- a/locale/zh_CN/gitlab.po
+++ b/locale/zh_CN/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: zh-CN\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:36\n"
+"PO-Revision-Date: 2020-06-08 15:08\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -71,6 +71,14 @@ msgid "%d URL scanned"
msgid_plural "%d URLs scanned"
msgstr[0] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -87,6 +95,10 @@ msgid "%d comment"
msgid_plural "%d comments"
msgstr[0] "%dæ¡è¯„论"
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] "%d 次æ交"
@@ -106,6 +118,10 @@ msgid "%d contribution"
msgid_plural "%d contributions"
msgstr[0] "%d个贡献"
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -120,7 +136,7 @@ msgstr[0] ""
msgid "%d fixed test result"
msgid_plural "%d fixed test results"
-msgstr[0] "%d 个确定的测试结果"
+msgstr[0] "%d个修å¤çš„测试结果"
msgid "%d group selected"
msgid_plural "%d groups selected"
@@ -162,6 +178,10 @@ msgid "%d more comment"
msgid_plural "%d more comments"
msgstr[0] "%d个更多评论"
+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] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] "%d个项目"
@@ -186,6 +206,14 @@ msgid "%d unresolved thread"
msgid_plural "%d unresolved threads"
msgstr[0] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -206,6 +234,9 @@ msgstr "ç”± %{commit_author_link} æ交于 %{commit_timeago}"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores}个核心"
@@ -279,6 +310,9 @@ msgstr "%{filePath} 已删除"
msgid "%{firstLabel} +%{labelCount} more"
msgstr "%{firstLabel} +%{labelCount} 更多"
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr "%{global_id}ä¸æ˜¯ä¸€ä¸ª%{expected_type}的有效ID。"
@@ -288,6 +322,9 @@ msgstr "%{group_docs_link_start}群组%{group_docs_link_end} å…许您管ç†ã€å
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr "%{group_name}使用由群组托管å¸æˆ·ã€‚您需è¦åˆ›å»ºä¸€ä¸ªæ–°çš„GitLabå¸æˆ·ï¼Œè¯¥å¸æˆ·å°†é€šè¿‡%{group_name}组æ¥ç®¡ç†ã€‚"
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr "%{icon} å³å°†åœ¨è®¨è®ºä¸­æ·»åŠ  %{usersTag} 个人, 请仔细检查。"
@@ -300,6 +337,30 @@ msgstr "%{issuesSize}个议题"
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr "%{issuesSize}个议题,上é™ä¸º%{maxIssueCount}"
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr "%{label_for_message}ä¸å¯ç”¨"
@@ -333,12 +394,21 @@ msgstr "%{loadingIcon} 已开始"
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr "%{lock_path} 被GitLab用户 %{lock_user_id} é”定"
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr "%{mergeLength}/%{usersLength} å¯ä»¥åˆå¹¶"
msgid "%{mrText}, this issue will be closed automatically."
msgstr "%{mrText},此议题将自动关闭。"
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -354,6 +424,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr "%{name} 的头åƒ"
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -392,6 +468,12 @@ msgid "%{releases} release"
msgid_plural "%{releases} releases"
msgstr[0] "%{releases}个å‘布"
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -533,6 +615,9 @@ msgid "(%d closed)"
msgid_plural "(%d closed)"
msgstr[0] "(%d 已关闭)"
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr "(%{mrCount} å·²åˆå¹¶)"
@@ -619,7 +704,7 @@ msgstr[0] "%d天"
msgid "1 closed issue"
msgid_plural "%{issues} closed issues"
-msgstr[0] "%{issues}个已关闭的议题"
+msgstr[0] "%{issues}个关闭的议题"
msgid "1 closed merge request"
msgid_plural "%{merge_requests} closed merge requests"
@@ -650,7 +735,7 @@ msgstr ""
msgid "1 open issue"
msgid_plural "%{issues} open issues"
-msgstr[0] "%{issues}个未关闭的问题"
+msgstr[0] "%{issues}个开放的议题"
msgid "1 open merge request"
msgid_plural "%{merge_requests} open merge requests"
@@ -719,6 +804,9 @@ msgstr "如果您觉得这是一个错误的æ示信æ¯ï¼Œè¯·è”系您的 GitLa
msgid "8 hours"
msgstr "8å°æ—¶"
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr "< 1å°æ—¶"
@@ -749,6 +837,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr "<strong>%{group_name}</strong> 群组æˆå‘˜"
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr "<strong>删除</strong>æºåˆ†æ”¯"
@@ -758,6 +849,9 @@ msgstr "Runner是一个执行任务的进程。您å¯ä»¥æ ¹æ®éœ€è¦é…置任æ„
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ".NET Core控制å°åº”用程åºæ¨¡æ¿ï¼Œå¯é’ˆå¯¹ä»»ä½•.NET Core项目进行自定义"
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr "一个GitBook站点,它使用NetLifyæ¥ä»£æ›¿Gitlabçš„CI/CD,但ä»ç„¶å…·æœ‰æ‰€æœ‰å…¶ä»–主è¦çš„Gitlab功能。"
@@ -794,7 +888,10 @@ msgstr "文件å为%{file_name}的文件已ç»å­˜åœ¨äºŽ%{branch}分支中"
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr "派生是项目的副本。<br />仓库的派生å…许您在ä¸å½±å“原始项目的情况下进行更改。"
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -845,6 +942,9 @@ msgstr "用于在作业日志中查找匹é…测试覆盖率输出的正则表达
msgid "A secure token that identifies an external storage request."
msgstr "一个用于识别外部储存的请求安全令牌。"
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -857,9 +957,6 @@ msgstr "具有对æºåˆ†æ”¯çš„写入æƒé™çš„用户选择了此选项"
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr "API帮助"
-
msgid "API Token"
msgstr "API令牌"
@@ -905,9 +1002,6 @@ msgstr "接å—æ¡æ¬¾"
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr "接å—åˆå¹¶è¯·æ±‚"
-
msgid "Access Tokens"
msgstr "访问令牌"
@@ -998,12 +1092,6 @@ msgstr "您的é™æ€å¯¹è±¡ä»¤ç‰Œç”¨äºŽä»Žå¤–部存储存å–é™æ€å¯¹è±¡ï¼ˆä¾‹å¦‚
msgid "AccessTokens|reset it"
msgstr "é‡ç½®ä»¤ç‰Œ"
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1040,8 +1128,8 @@ msgstr "å¯ç”¨æœåŠ¡å°"
msgid "Active"
msgstr "å¯ç”¨"
-msgid "Active %{type} Tokens (%{token_length})"
-msgstr "活动的 %{type} 令牌 (%{token_length})"
+msgid "Active %{type} (%{token_length})"
+msgstr ""
msgid "Active Sessions"
msgstr "活动会è¯"
@@ -1049,6 +1137,9 @@ msgstr "活动会è¯"
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr "动æ€"
@@ -1092,8 +1183,8 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr "添加 Zoom 会议"
-msgid "Add a %{type} token"
-msgstr "增加一个 %{type} 令牌"
+msgid "Add a %{type}"
+msgstr ""
msgid "Add a GPG key"
msgstr "添加GPG密钥"
@@ -1107,6 +1198,9 @@ msgstr "添加一个待办事项"
msgid "Add a bullet list"
msgstr "添加一个符å·åˆ—表"
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr "添加一般评论 %{noteableDisplayName}。"
@@ -1116,9 +1210,15 @@ msgstr "添加一般评论 %{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 "在wiki中添加一个主页,其中包å«æœ‰å…³é¡¹ç›®çš„ä¿¡æ¯ï¼ŒGitLab将在此处显示该主页,而ä¸æ˜¯æ­¤æ¶ˆæ¯ã€‚"
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr "添加链接"
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr "添加编å·åˆ—表"
@@ -1134,8 +1234,11 @@ msgstr "添加包å«åœ¨æ‰€æœ‰ç”µå­é‚®ä»¶ä¸­çš„附加文本。 长度ä¸è¶…过%{
msgid "Add an SSH key"
msgstr "添加SSH密钥"
-msgid "Add an existing issue to the epic."
-msgstr "将现有议题添加到å²è¯—中。"
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
+msgstr ""
msgid "Add an issue"
msgstr "添加一个议题"
@@ -1200,6 +1303,9 @@ msgstr "添加回应"
msgid "Add request manually"
msgstr "手动添加请求"
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr "添加系统钩å­"
@@ -1290,18 +1396,18 @@ msgstr "添加一个Zoom会议"
msgid "Adds an issue to an epic."
msgstr "将议题添加到å²è¯—。"
-msgid "Adjust your filters/search criteria above."
-msgstr "调整您的过滤器/æœç´¢æ¡ä»¶ã€‚"
+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 ""
msgid "Admin Area"
msgstr "管ç†ä¸­å¿ƒ"
+msgid "Admin Note"
+msgstr ""
+
msgid "Admin Overview"
msgstr "管ç†æ¦‚览"
-msgid "Admin Section"
-msgstr "管ç†éƒ¨åˆ†"
-
msgid "Admin mode already enabled"
msgstr "管ç†å‘˜æ¨¡å¼å·²å¯ç”¨"
@@ -1528,7 +1634,7 @@ msgid "AdminUsers|External"
msgstr "外部"
msgid "AdminUsers|Is using seat"
-msgstr "正在使用许å¯åº§ä½"
+msgstr "正在使用许å¯å¸­ä½"
msgid "AdminUsers|It's you!"
msgstr "自己ï¼"
@@ -1626,62 +1732,116 @@ msgstr "密ç æ›´æ–°æˆåŠŸåŽï¼Œæ‚¨å°†è¢«é‡å®šå‘到登录页é¢ã€‚"
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr "密ç æ›´æ–°æˆåŠŸåŽï¼Œæ‚¨å°†è¢«é‡å®šå‘到登录页é¢ï¼Œæ‚¨å¯ä»¥ä½¿ç”¨æ–°å¯†ç é‡æ–°ç™»å½•ã€‚"
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] "警报"
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
+msgstr ""
+
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1690,17 +1850,35 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
-msgstr "%{linkStart}了解更多%{linkEnd}有关接收报警端点é…ç½®"
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
+msgstr ""
+
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
-msgstr "æ¯ä¸ªè­¦å‘Šæºå¿…须使用以下网å€å’ŒæŽˆæƒå¯†é’¥è¿›è¡ŒæŽˆæƒã€‚"
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
+msgstr ""
msgid "Alerts"
msgstr "警报"
@@ -1873,6 +2051,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr "应用%{link_to_client}请求访问您的 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 ""
+
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 "空GitLab用户字段将在所有问题和注释的æ述中添加FogBugz用户的全å(例如“By John Smithâ€ï¼‰ã€‚它还将与项目创建者关è”å’Œ/或分é…这些问题和评论。"
@@ -2038,9 +2219,6 @@ msgstr "加载所有文件时å‘生错误。"
msgid "An error occurred while loading chart data"
msgstr "加载图表数æ®æ—¶å‘生错误"
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr "加载æ交签åæ—¶å‘生错误"
@@ -2062,6 +2240,9 @@ msgstr "加载议题时å‘生错误。"
msgid "An error occurred while loading merge requests."
msgstr "加载åˆå¹¶è¯·æ±‚æ—¶å‘生错误。"
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2137,6 +2318,9 @@ msgstr "ä¿å­˜æ ¸å‡†è®¾ç½®æ—¶å‘生错误"
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr "ä¿å­˜æ¨¡æ¿æ—¶å‡ºé”™ã€‚请检查模æ¿æ˜¯å¦å­˜åœ¨ã€‚"
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr "订阅通知时å‘生错误。"
@@ -2173,9 +2357,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr "议题å¯ä»¥æ˜¯éœ€è¦åœ¨é¡¹ç›®ä¸­è®¨è®ºçš„缺陷,待办事项或功能请求。此外,议题是å¯æœç´¢å’Œå¯è¿‡æ»¤çš„。"
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr "检查项目环境时å‘生æ„外错误。"
@@ -2191,6 +2381,9 @@ msgstr "å¯åŠ¨Web终端时å‘生æ„外错误。"
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr "åœæ­¢Web终端时å‘生æ„外错误。"
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr "分æž"
@@ -2200,6 +2393,9 @@ msgstr "分æžWeb应用程åºçš„审阅版本。"
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2224,12 +2420,6 @@ msgstr "任何"
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr "任何标记"
-
-msgid "Any Milestone"
-msgstr "任何里程碑"
-
msgid "Any branch"
msgstr ""
@@ -2239,9 +2429,15 @@ msgstr "任何符åˆæ¡ä»¶çš„用户"
msgid "Any encrypted tokens"
msgstr "任何加密的令牌"
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr "任何具有开å‘者或更高æƒé™çš„项目æˆå‘˜ã€‚"
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr "任何命å空间"
@@ -2305,6 +2501,9 @@ msgstr "应用标记"
msgid "Apply a template"
msgstr "应用模æ¿"
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr "应用建议"
@@ -2369,12 +2568,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr "例如质é‡ä¿è¯ã€å®‰å…¨ç­‰ç­‰ã€‚"
-msgid "Approvals"
-msgstr "核准"
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr "批准"
@@ -2384,12 +2577,18 @@ msgstr "批准åˆå¹¶è¯·æ±‚"
msgid "Approve the current merge request."
msgstr "批准当å‰åˆå¹¶è¯·æ±‚。"
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr "批准了当å‰çš„åˆå¹¶è¯·æ±‚。"
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr "审批人"
@@ -2498,6 +2697,9 @@ msgstr "确定移除群组 %{group_name} å—?"
msgid "Are you sure you want to remove the attachment?"
msgstr "您确定è¦åˆ é™¤æ­¤é™„件?"
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr "您确定è¦åˆ é™¤è¿™ä¸ªèº«ä»½æ ‡è¯†å—?"
@@ -2510,8 +2712,8 @@ msgstr "您确定è¦é‡ç½®SCIM令牌å—?在完æˆæ–°ä»¤ç‰Œæ›´æ–°ä¹‹å‰ï¼ŒSCIMé
msgid "Are you sure you want to reset the health check token?"
msgstr "确定è¦é‡ç½®è¿è¡ŒçŠ¶å†µæ£€æŸ¥ä»¤ç‰Œå—?"
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
-msgstr "确定è¦æ’¤é”€æ­¤%{type}令牌å—?此æ“作ä¸å¯é€†ã€‚"
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
+msgstr ""
msgid "Are you sure you want to revoke this nickname?"
msgstr "您确定è¦å–消此昵称?"
@@ -2624,6 +2826,9 @@ msgstr "已分é…议题"
msgid "Assigned Merge Requests"
msgstr "已分é…åˆå¹¶è¯·æ±‚"
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr "已分派给我"
@@ -2698,15 +2903,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr "8月"
@@ -2764,6 +2987,9 @@ msgstr "授æƒ"
msgid "Authorize %{link_to_client} to use your account?"
msgstr "æŽˆæƒ %{link_to_client} 使用您的å¸æˆ·ï¼Ÿ"
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr "已授æƒç»™ %{new_chat_name}"
@@ -2785,9 +3011,6 @@ msgstr "å¯ç”¨Auto DevOps"
msgid "Auto DevOps, runners and job artifacts"
msgstr "Auto DevOps, runnersåŠä½œä¸šäº§ç‰©"
-msgid "Auto License Compliance"
-msgstr "自动许å¯åˆè§„"
-
msgid "Auto stop successfully canceled."
msgstr "自动åœæ­¢å·²æˆåŠŸå–消。"
@@ -2806,6 +3029,9 @@ msgstr "Auto DevOpså¯åŸºäºŽé¢„定义的æŒç»­é›†æˆå’Œäº¤ä»˜é…置自动构建ï
msgid "AutoDevOps|Auto DevOps documentation"
msgstr "DevOps 自动化文档"
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr "在设置中å¯ç”¨"
@@ -2836,6 +3062,9 @@ msgstr "使用%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end}自
msgid "Automatic certificate management using Let's Encrypt"
msgstr "使用Let's Encrypt自动管ç†è¯ä¹¦"
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr "自动标记为默认内部用户"
@@ -2851,6 +3080,9 @@ msgstr "注æ„"
msgid "Available"
msgstr "å¯ç”¨çš„"
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr "å¯ç”¨çš„群组 Runner: %{runners}"
@@ -3328,17 +3560,17 @@ msgstr "未解决议题æƒé‡"
msgid "BurndownChartLabel|Open issues"
msgstr "未解决议题"
+msgid "Burnup chart"
+msgstr ""
+
msgid "Business"
msgstr "商业"
msgid "Business metrics (Custom)"
msgstr "业务指标(自定义)"
-msgid "Buy EE"
-msgstr "è´­ä¹°ä¼ä¸šç‰ˆ"
-
-msgid "Buy GitLab Enterprise Edition"
-msgstr "è´­ä¹°GitLabä¼ä¸šç‰ˆ"
+msgid "Buy License"
+msgstr ""
msgid "Buy more Pipeline minutes"
msgstr ""
@@ -3361,8 +3593,8 @@ msgstr "更新日志"
msgid "CI / CD"
msgstr "CI / CD"
-msgid "CI / CD Charts"
-msgstr "CI/CD 统计图"
+msgid "CI / CD Analytics"
+msgstr ""
msgid "CI / CD Settings"
msgstr "CI/CD 设置"
@@ -3370,6 +3602,9 @@ msgstr "CI/CD 设置"
msgid "CI Lint"
msgstr "CI Lint"
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr "CI å˜é‡"
@@ -3388,6 +3623,9 @@ msgstr "为外部仓库设置的CI/CD"
msgid "CI/CD settings"
msgstr "CI/CD 设置"
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr "Auto DevOps"
@@ -3418,9 +3656,6 @@ msgstr "在未找到备用CIé…置文件时使用Auto DevOpsæµæ°´çº¿ã€‚"
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr "您必须将 %{base_domain_link_start}基本域%{link_end} 添加到 %{kubernetes_cluster_link_start}Kubernetes群集%{link_end} ,æ‰èƒ½ä½¿æ‚¨çš„部署策略正常工作。"
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr "您必须添加一个%{kubernetes_cluster_link_start}Kubernetes集群集æˆ%{link_end}到此项目,以便您的部署策略正常工作。"
-
msgid "CICD|group enabled"
msgstr "群组已å¯ç”¨"
@@ -3448,6 +3683,12 @@ msgstr "å¯ä»¥æ‰‹åŠ¨éƒ¨ç½²åˆ°"
msgid "Can override approvers and approvals required per merge request"
msgstr "å¯ä»¥è¦†ç›–æ¯ä¸ªåˆå¹¶è¯·æ±‚所需的核准人和核准信æ¯"
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr "无法找到此分支的 HEAD æ交"
@@ -3523,8 +3764,8 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
-msgstr "无法通过内部ID引用群组里程碑ï¼"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
+msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
msgstr ""
@@ -3538,6 +3779,9 @@ msgstr "无法跳过åŒé‡è®¤è¯è®¾ç½®"
msgid "Capacity threshold"
msgstr "容é‡é˜ˆå€¼"
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr "è¯ä¹¦"
@@ -3574,6 +3818,12 @@ msgstr "更改路径"
msgid "Change permissions"
msgstr "更改æƒé™"
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr "更改模æ¿"
@@ -3616,6 +3866,9 @@ msgstr "å˜æ›´"
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr "差异显示方å¼ä¾<b>æº</b>版本åˆå¹¶åˆ°<b>目标</b>版本的形å¼ã€‚"
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3634,6 +3887,9 @@ msgstr "åªå¯ä»¥é€šè¿‡Releases API更改å‘布标签。 %{linkStart}更多信æ
msgid "Changing group path can have unintended side effects."
msgstr "更改群组路径å¯èƒ½ä¼šæœ‰æ„想ä¸åˆ°çš„副作用。"
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3739,15 +3995,6 @@ msgstr "%{startDate} - %{endDate}"
msgid "Checkout|(x%{numberOfUsers})"
msgstr "(x%{numberOfUsers})"
-msgid "Checkout|1. Your profile"
-msgstr "1. 您的个人资料"
-
-msgid "Checkout|2. Checkout"
-msgstr "2. 支付"
-
-msgid "Checkout|3. Your GitLab group"
-msgstr "3. 您的GitLab群组"
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4096,9 +4343,6 @@ msgstr "验è¯å¤±è´¥"
msgid "Class"
msgstr "类别"
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr "分类标签(å¯é€‰)"
@@ -4111,6 +4355,9 @@ msgstr "清除"
msgid "Clear chart filters"
msgstr "清除图表过滤器"
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr "清除输入"
@@ -4123,6 +4370,9 @@ msgstr "清除æœç´¢"
msgid "Clear search input"
msgstr "清除æœç´¢è¾“å…¥"
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr "清除模æ¿æœç´¢è¾“å…¥"
@@ -4150,9 +4400,6 @@ msgstr "请点击å³è¾¹çš„ <strong>æ— </strong> 按钮,因为我们åªéœ€è¦â€
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr "点击下é¢çš„按钮转到Kubernetes页é¢å¼€å§‹å®‰è£…过程"
-msgid "Click the image where you'd like to start a new discussion"
-msgstr "å•å‡»æ‚¨è¦å¼€å§‹æ–°è®¨è®ºçš„图åƒ"
-
msgid "Click to expand it."
msgstr "点击以展开。"
@@ -4192,6 +4439,9 @@ msgstr "使用 SSH 克隆"
msgid "Close"
msgstr "关闭"
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr "关闭%{tabname}"
@@ -4387,6 +4637,9 @@ msgstr "集群管ç†é¡¹ç›®(alpha)"
msgid "ClusterIntegration|Cluster name is required."
msgstr "群集å称为必填项。"
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr "层级中最低且匹é…环境范围的集群将会被使用。例如,项目群集将优先于群组群集。"
@@ -4408,9 +4661,6 @@ msgstr "å¤åˆ¶Knative Endpoint"
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr "å¤åˆ¶Kubernetes集群å称"
-msgid "ClusterIntegration|Copy Service Token"
-msgstr "å¤åˆ¶æœåŠ¡ä»¤ç‰Œ"
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr "无法加载IAM角色"
@@ -4462,8 +4712,8 @@ msgstr "正在创建 Kubernetes 集群"
msgid "ClusterIntegration|Crossplane"
msgstr "Crossplane"
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
-msgstr "Crossplane支æŒä½¿ç”¨%{kubectl}或%{gitlabIntegrationLink}从您选择的云æœåŠ¡ä¸­ä»¥å£°æ˜Žæ–¹å¼æ供托管æœåŠ¡ã€‚ Crossplaneè¿è¡Œåœ¨æ‚¨çš„Kubernetes集群内部,并支æŒåº”用程åºå®¹å™¨ä¸Žå®ƒä»¬ä¾èµ–的云æœåŠ¡ä¹‹é—´çš„安全连接和密ç ç®¡ç†ã€‚"
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
msgstr "移除过程中删除此集群中的所有GitLab资æº"
@@ -4489,6 +4739,9 @@ msgstr "如果使用基于角色的访问控制(RBAC),请å¯ç”¨æ­¤è®¾ç½®ã€
msgid "ClusterIntegration|Enabled stack"
msgstr "å·²å¯ç”¨çš„æ ˆ"
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr "输入Amazon EKS Kubernetes集群的详细信æ¯"
@@ -4567,12 +4820,12 @@ msgstr "群组级集群"
msgid "ClusterIntegration|Helm Tiller"
msgstr "Helm Tiller"
+msgid "ClusterIntegration|Helm release failed to install"
+msgstr ""
+
msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr "Helm简化了Kubernetes应用程åºçš„安装和管ç†ã€‚ Tiller在您的Kubernetes集群内部è¿è¡Œï¼Œå¹¶ç®¡ç†å›¾è¡¨çš„å‘布。"
-msgid "ClusterIntegration|Hide"
-msgstr "éšè—"
-
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
msgstr "如果您正在设置多个群集并使用Auto DevOps,请%{help_link_start}先查阅此处%{help_link_end}。"
@@ -4729,6 +4982,12 @@ msgstr "没有找到密钥对"
msgid "ClusterIntegration|No VPCs found"
msgstr "找ä¸åˆ°VPC"
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr "找ä¸åˆ°å®žä¾‹ç±»åž‹"
@@ -4963,9 +5222,6 @@ msgstr "设置å称空间的å‰ç¼€ã€‚如未设置,则默认为项目路径。
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr "显示"
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr "å‘生了内部错误"
@@ -5044,6 +5300,9 @@ msgstr "开关Kubernetes 集群"
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr "å¸è½½ %{appTitle}"
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr "更新失败。请检查日志,然åŽé‡è¯•ã€‚"
@@ -5074,6 +5333,9 @@ msgstr "å³å°†åˆ é™¤é›†ç¾¤é›†æˆã€‚"
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr "您å³å°†ä»Žæ‚¨çš„集群中å¸è½½ %{appTitle}。"
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr "在安装以下应用程åºä¹‹å‰ï¼Œå¿…须先安装Helm Tiller"
@@ -5083,9 +5345,15 @@ msgstr "您必须授予对组织的AWS资æºçš„访问æƒé™ï¼Œæ‰èƒ½åˆ›å»ºæ–°çš„
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr "您必须具有已å¯ç”¨RBAC的群集æ‰èƒ½å®‰è£…Knative。"
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr "您的å¸æˆ·å¿…须有æƒé™%{link_to_kubernetes_engine}"
@@ -5143,6 +5411,9 @@ msgstr "选择密钥对"
msgid "ClusterIntergation|Select service role"
msgstr "选择æœåŠ¡è§’色"
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr "代ç "
@@ -5161,6 +5432,9 @@ msgstr "代ç è¯„审"
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr "代ç æ‰€æœ‰è€…的核准是必需的"
@@ -5200,6 +5474,9 @@ msgstr "折å æ ¸å‡†äºº"
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr "收起侧边æ "
@@ -5209,6 +5486,9 @@ msgstr "Collector主机å"
msgid "ComboSearch is not defined"
msgstr "ComboSearch未定义"
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr "命令"
@@ -5245,6 +5525,9 @@ msgstr "评论框ä½ç½®"
msgid "Comment is being updated"
msgstr "评论正在更新"
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr "评论/å›žå¤ (引用选定的文本)"
@@ -5405,8 +5688,11 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
-msgstr "置信度: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
+msgstr ""
msgid "Confidential"
msgstr "ç§å¯†"
@@ -5429,9 +5715,6 @@ msgstr "é…ç½®Let's Encrypt"
msgid "Configure Prometheus"
msgstr "é…ç½®Promethes"
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr "é…置安全%{wordBreakOpportunity}与åˆè§„"
-
msgid "Configure Tracing"
msgstr "é…置跟踪"
@@ -5465,9 +5748,6 @@ msgstr "é…置存储路径设置。"
msgid "Configure the %{link} integration."
msgstr "é…ç½® %{link} 集æˆã€‚"
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr "é…置用户创建新å¸æˆ·çš„æ–¹å¼ã€‚"
@@ -5516,17 +5796,11 @@ msgstr "连接失败"
msgid "Connection timed out"
msgstr "连接超时"
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr "请è”ç³» %{namespace_name} 群组的所有者以å‡çº§è®¡åˆ’。"
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr "请è”系所有者 %{link_start}%{owner_name}%{link_end} 以å‡çº§è®¡åˆ’。"
-
msgid "Contact sales to upgrade"
msgstr "è”系销售人员进行å‡çº§"
-msgid "Contact your Administrator to upgrade your license."
-msgstr "请与管ç†å‘˜è”系以å‡çº§è®¸å¯è¯ã€‚"
+msgid "Contact support"
+msgstr ""
msgid "Container Registry"
msgstr "容器镜åƒåº“"
@@ -5552,6 +5826,14 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5564,6 +5846,9 @@ msgstr "自动删除计划ä¸ä¿ç•™çš„多余镜åƒã€‚"
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5588,27 +5873,39 @@ msgstr "Docker连接错误"
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr "Docker标签过期策略为%{toggleStatus}"
-msgid "ContainerRegistry|Edit Settings"
-msgstr ""
-
msgid "ContainerRegistry|Expiration interval:"
msgstr "过期间隔:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr "æˆåŠŸä¿å­˜è¿‡æœŸç­–略。"
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr "过期策略:"
msgid "ContainerRegistry|Expiration schedule:"
msgstr "过期计划:"
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr "如果您尚未登录,您需è¦ä½¿ç”¨æ‚¨çš„GitLab用户å和密ç æ¥è¿›è¡Œèº«ä»½è®¤è¯ã€‚如果您å¯ç”¨ %{twofaDocLinkStart}åŒé‡èº«ä»½éªŒè¯%{twofaDocLinkEnd} ,请使用%{personalAccessTokensDocLinkStart}个人访问令牌%{personalAccessTokensDocLinkEnd}而ä¸æ˜¯å¯†ç ã€‚"
msgid "ContainerRegistry|Image ID"
msgstr "é•œåƒID"
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr "ä¿ç•™å’Œä¿æŠ¤æœ€é‡è¦çš„é•œåƒã€‚"
@@ -5630,10 +5927,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr "快速入门"
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5652,9 +5946,6 @@ msgid "ContainerRegistry|Remove tag"
msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] "删除标签"
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr "获å–到期政策时出了错。"
@@ -5676,6 +5967,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr "更新到期政策时出了错。"
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr "标签"
@@ -5703,12 +5997,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr "与此镜åƒç›¸å…³çš„最åŽä¸€ä¸ªæ ‡ç­¾æœ€è¿‘已被删除。空镜åƒå’Œæ‰€æœ‰ç›¸å…³æ•°æ®å°†ä½œä¸ºå¸¸è§„垃圾收集过程的一部分自动清除。如有任何疑问,请与管ç†å‘˜è”系。"
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr "此输入的值应å°äºŽ255个字符"
@@ -5727,8 +6015,11 @@ msgstr "此镜åƒæ²¡æœ‰æ´»åŠ¨çš„标签"
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
-msgstr "当å‰æ— æ³•è¿žæŽ¥åˆ°Docker。原因å¯èƒ½æ˜¯é¡¹ç›®å称或路径的问题。 %{docLinkStart}更多信æ¯%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
msgstr "在容器镜åƒåº“中,æ¯ä¸ªé¡¹ç›®éƒ½æœ‰è‡ªå·±çš„空间æ¥å­˜å‚¨å®¹å™¨é•œåƒã€‚ %{docLinkStart}更多信æ¯%{docLinkEnd}"
@@ -5736,8 +6027,8 @@ msgstr "在容器镜åƒåº“中,æ¯ä¸ªé¡¹ç›®éƒ½æœ‰è‡ªå·±çš„空间æ¥å­˜å‚¨å®¹å™¨
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 "使用容器镜åƒåº“,æ¯ä¸ªé¡¹ç›®éƒ½å¯ä»¥æœ‰è‡ªå·±çš„空间æ¥å­˜å‚¨å…¶Dockeré•œåƒã€‚å‘此群组中的项目推é€è‡³å°‘一个Docker映åƒåŽï¼Œé•œåƒå°†ä¼šåœ¨æ­¤å¤„显示。 %{docLinkStart}更多信æ¯%{docLinkEnd}"
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
-msgstr "通过GitLab集æˆçš„Docker容器镜åƒåº“,æ¯ä¸ªé¡¹ç›®éƒ½æœ‰è‡ªå·±çš„空间æ¥å­˜å‚¨å®¹å™¨é•œåƒã€‚ %{docLinkStart}更多信æ¯%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
msgstr ""
@@ -5775,12 +6066,12 @@ msgstr "贡献"
msgid "Contribution Analytics"
msgstr "贡献度分æž"
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
-msgstr "已创建<strong>%{created_count}</strong> 个,已接å—<strong>%{accepted_count}</strong> 个。"
-
msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr "已创建<strong>%{created_count}</strong> 个,已关闭<strong>%{closed_count}</strong>个。"
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
+msgstr ""
+
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
msgstr "<strong>%{pushes}</strong>次推é€ï¼Œå«æ¥è‡ª<strong>%{people}</strong>ä½è´¡çŒ®è€…çš„<strong>%{commits}</strong>次以上æ交。"
@@ -5865,6 +6156,9 @@ msgstr "å¤åˆ¶ %{protocol} 克隆URL"
msgid "Copy %{proxy_url}"
msgstr "å¤åˆ¶%{proxy_url}"
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr "å°†å¸æˆ·IDå¤åˆ¶åˆ°å‰ªè´´æ¿"
@@ -5910,9 +6204,6 @@ msgstr "å¤åˆ¶æ–‡ä»¶å†…容"
msgid "Copy file path"
msgstr "å¤åˆ¶æ–‡ä»¶è·¯å¾„"
-msgid "Copy impersonation token"
-msgstr "å¤åˆ¶èº«ä»½æ¨¡æ‹Ÿä»¤ç‰Œ "
-
msgid "Copy key"
msgstr ""
@@ -5928,9 +6219,6 @@ msgstr "å¤åˆ¶é“¾æŽ¥"
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr "å¤åˆ¶ä¸ªäººè®¿é—®ä»¤ç‰Œ"
-
msgid "Copy reference"
msgstr "å¤åˆ¶å‚ç…§"
@@ -6027,8 +6315,8 @@ msgstr "创建"
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
-msgstr "创建%{type}令牌"
+msgid "Create %{type}"
+msgstr ""
msgid "Create New Directory"
msgstr "创建新目录"
@@ -6045,9 +6333,6 @@ msgstr "请先创建一个GitLabå¸æˆ·ï¼Œç„¶åŽå°†å…¶è¿žæŽ¥åˆ°æ‚¨çš„ %{label} å¸
msgid "Create a Mattermost team for this group"
msgstr "为这个群组创建一个Mattermost团队"
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr "创建本地代ç†ï¼Œç”¨äºŽå­˜å‚¨é¢‘ç¹ä½¿ç”¨çš„上游镜åƒã€‚ %{link_start}了解更多%{link_end} 关于ä¾èµ–代ç†çš„内容。"
@@ -6066,9 +6351,6 @@ msgstr "当å‰æ— æ–‡ä»¶ã€‚请先创建一个新文件。然åŽæ‚¨å°†èƒ½å¤Ÿæ交
msgid "Create a new issue"
msgstr "创建新议题"
-msgid "Create a new issue and add it to the epic."
-msgstr "创建一个新议题并将其添加到å²è¯—中。"
-
msgid "Create a new repository"
msgstr "创建一个新仓库"
@@ -6078,9 +6360,6 @@ msgstr "在å¸æˆ·ä¸Šåˆ›å»ºä¸ªäººè®¿é—®ä»¤ç‰Œï¼Œä»¥é€šè¿‡ %{protocol} æ¥æ‹‰å–æˆ
msgid "Create an account using:"
msgstr "使用以下方å¼åˆ›å»ºå¸æˆ·ï¼š"
-msgid "Create an issue"
-msgstr "创建议题"
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr "创建一个议题。为已触å‘çš„æ¯ä¸ªè­¦æŠ¥åˆ›å»ºè®®é¢˜ã€‚"
@@ -6123,6 +6402,9 @@ msgstr "创建群组标记"
msgid "Create issue"
msgstr "创建议题"
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr "从标记创建列表,å«æœ‰è¯¥æ ‡è®°çš„议题将出现在相应的列中。"
@@ -6135,6 +6417,9 @@ msgstr "创建åˆå¹¶è¯·æ±‚åŠåˆ†æ”¯"
msgid "Create milestone"
msgstr "创建里程碑"
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr "新建看æ¿"
@@ -6174,6 +6459,12 @@ msgstr ""
msgid "Create your first page"
msgstr "创建您的第一个页é¢"
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr "您无æƒåœ¨æ­¤ç¾¤ç»„中创建å­ç¾¤ç»„。"
@@ -6207,6 +6498,9 @@ msgstr "创建了分支“%{branch_name}â€å’Œåˆå¹¶è¯·æ±‚以解决此议题。"
msgid "Created by me"
msgstr "由我创建"
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr "创建议题 %{issueLink}"
@@ -6258,9 +6552,6 @@ msgstr "存在严é‡æ¼æ´ž"
msgid "Cron Timezone"
msgstr "Cron 时区"
-msgid "Cron syntax"
-msgstr "Cron 语法"
-
msgid "Crossplane"
msgstr "Crossplane"
@@ -6297,6 +6588,9 @@ msgstr "设置"
msgid "CurrentUser|Start a Gold trial"
msgstr "开始试用金牌计划"
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr "自定义CIé…置路径"
@@ -6321,6 +6615,9 @@ msgstr "尚未为您所属的群组设置自定义项目模æ¿ã€‚请在群组的
msgid "Custom range"
msgstr "自定义范围"
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr "添加新阶段"
@@ -6369,6 +6666,9 @@ msgstr "åœæ­¢äº‹ä»¶æ ‡è®°"
msgid "CustomCycleAnalytics|Update stage"
msgstr "更新阶段"
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr "自定义颜色"
@@ -6393,6 +6693,9 @@ msgstr "自定义æµæ°´çº¿é…置,查看æµæ°´çº¿çŠ¶æ€å’Œè¦†ç›–率报告。"
msgid "Customize your pipeline configuration."
msgstr "自定义您的æµæ°´çº¿é…置。"
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr "议题关闭"
@@ -6643,6 +6946,9 @@ msgstr "默认分支和å—ä¿æŠ¤çš„分支"
msgid "Default classification label"
msgstr "默认分类标记"
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr "默认删除延时"
@@ -6679,6 +6985,9 @@ msgstr "默认:将FogBugzå¸æˆ·ID映射为全å"
msgid "Define a custom pattern with cron syntax"
msgstr "使用 Cron 语法定义自定义模å¼"
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr "在<code>.githab-ci.yml</code>çš„ deploy 阶段中定义 environment æ¥è·Ÿè¸ªéƒ¨ç½²ã€‚"
@@ -6721,6 +7030,12 @@ msgstr "删除评论"
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr "删除许å¯è¯"
@@ -6809,10 +7124,6 @@ msgid "Dependencies|%d additional vulnerability not shown"
msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] "%d个其它æ¼æ´žæœªæ˜¾ç¤º"
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] "%d个æ¼æ´ž"
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6847,12 +7158,6 @@ msgstr "ä½ç½®"
msgid "Dependencies|Packager"
msgstr "打包程åº"
-msgid "Dependencies|Safe"
-msgstr "安全"
-
-msgid "Dependencies|Status"
-msgstr "状æ€"
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr "%{codeStartTag}dependency_scanning%{codeEndTag} 作业失败,无法生æˆåˆ—表。请确ä¿ä½œä¸šæ­£å¸¸è¿è¡Œå¹¶é‡å¯æµæ°´çº¿ã€‚"
@@ -6862,9 +7167,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr "检测到ä¸æ”¯æŒçš„文件"
-msgid "Dependencies|Version"
-msgstr "版本"
-
msgid "Dependencies|Vulnerable components"
msgstr "有æ¼æ´žçš„组件"
@@ -6976,12 +7278,18 @@ msgstr "å¯ç”¨éƒ¨ç½²ä»¤ç‰Œï¼ˆ%{active_tokens})"
msgid "DeployTokens|Add a deploy token"
msgstr "添加一个部署令牌"
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr "å…许对容器镜åƒåº“é•œåƒè¿›è¡Œåªè¯»è®¿é—®"
msgid "DeployTokens|Allows read-only access to the repository"
msgstr "å…许对仓库进行åªè¯»è®¿é—®"
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7003,13 +7311,13 @@ msgstr "默认格å¼ä¸ºâ€œgitlab+deploy-token-{n}â€ã€‚如果è¦æ›´æ”¹è¯·è¾“å…¥è
msgid "DeployTokens|Deploy Tokens"
msgstr "部署令牌"
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr "到期"
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7129,21 +7437,36 @@ msgstr "%{current_design}/%{designs_count}"
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
-msgstr "添加设计"
-
msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr "添加具有相åŒæ–‡ä»¶å的设计会替æ¢ä¸ºæ–°ç‰ˆæœ¬çš„文件。"
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
+msgstr ""
+
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
msgstr "确定è¦å–消创建此评论å—?"
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr "确定è¦åˆ é™¤é€‰ä¸­çš„设计å—?"
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr "å–消评论确认"
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr "无法添加新评论。请å†è¯•ä¸€æ¬¡."
@@ -7153,6 +7476,9 @@ msgstr "无法创建新讨论。请å†è¯•ä¸€é。"
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr "删除"
@@ -7180,12 +7506,27 @@ msgstr "转到下一个设计"
msgid "DesignManagement|Go to previous design"
msgstr "转到上一个设计"
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr "ä¿ç•™è¯„论"
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr "请求的设计版本ä¸å­˜åœ¨ã€‚显示最新版本"
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr "选择全部"
@@ -7195,6 +7536,12 @@ msgstr "å…许上传的设计最大数é‡ä¸º %{upload_limit}。请å†è¯•ä¸€æ¬¡ã€
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7207,6 +7554,9 @@ msgstr "设计"
msgid "Destroy"
msgstr "删除"
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr "详情"
@@ -7433,6 +7783,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr "还没有账户?"
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr "ä¸è¦æŠŠGPG密钥中的ç§é’¥éƒ¨åˆ†è´´è¿‡æ¥ï¼Œè¯·åªç²˜è´´å…¬é’¥éƒ¨åˆ†ï¼Œå…¶å¼€å§‹äºŽ '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
@@ -7481,6 +7834,9 @@ msgstr "下载图片"
msgid "Download license"
msgstr "下载许å¯è¯"
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr "下载æºä»£ç "
@@ -7505,6 +7861,9 @@ msgstr "踩"
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr "截止日期"
@@ -7652,6 +8011,9 @@ msgstr "电å­é‚®ä»¶"
msgid "Email address"
msgstr "电å­é‚®ä»¶åœ°å€"
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7667,6 +8029,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr "å°†æµæ°´çº¿çŠ¶æ€é€šè¿‡ç”µå­é‚®ä»¶å‘é€ç»™å¤šä¸ªæ”¶ä»¶äººã€‚"
@@ -7760,6 +8125,9 @@ msgstr "为此群组å¯ç”¨ SAML 身份验è¯"
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr "å…许访问Grafana"
@@ -7769,9 +8137,6 @@ msgstr "为特定群组å¯ç”¨æ€§èƒ½æ çš„访问æƒé™ã€‚"
msgid "Enable and configure Grafana."
msgstr "å¯ç”¨å¹¶é…ç½®Grafana。"
-msgid "Enable and configure InfluxDB metrics."
-msgstr "å¯ç”¨å¹¶é…ç½®InfluxDB指标。"
-
msgid "Enable and configure Prometheus metrics."
msgstr "å¯ç”¨å¹¶é…ç½®Prometheus指标。"
@@ -7799,6 +8164,9 @@ msgstr "å¯ç”¨ç¾¤ç»„Runner"
msgid "Enable header and footer in emails"
msgstr "在电å­é‚®ä»¶ä¸­å¯ç”¨é¡µçœ‰å’Œé¡µè„š"
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -7922,6 +8290,9 @@ msgstr "在下é¢è¾“入您的Phabricator Server URL和个人访问令牌"
msgid "Enter merge request URLs"
msgstr "输入åˆå¹¶è¯·æ±‚网å€"
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr "输入新的AWS Secret Access密钥"
@@ -7946,12 +8317,12 @@ msgstr "输入åˆå¹¶è¯·æ±‚说明"
msgid "Enter the merge request title"
msgstr "输入åˆå¹¶è¯·æ±‚标题"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
+msgstr ""
+
msgid "Enter your password to approve"
msgstr "输入批准密ç "
-msgid "Enter zen mode"
-msgstr "进入禅模å¼"
-
msgid "Environment"
msgstr "环境"
@@ -8006,8 +8377,8 @@ msgstr "作业:%{job}"
msgid "EnvironmentsDashboard|More actions"
msgstr "更多æ“作"
-msgid "EnvironmentsDashboard|Read more."
-msgstr "了解更多。"
+msgid "EnvironmentsDashboard|More information"
+msgstr ""
msgid "EnvironmentsDashboard|Remove"
msgstr "删除"
@@ -8219,11 +8590,11 @@ msgstr "有效利用å²è¯—,您的产å“线管ç†ä¼šå˜å¾—æ›´è½»æ¾é«˜æ•ˆ"
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
-msgstr "添加一个å²è¯—"
+msgid "Epics|Add a new epic"
+msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
-msgstr "添加一个现有的å²è¯—作为å­å²è¯—。"
+msgid "Epics|Add an existing epic"
+msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
msgstr "ä¿å­˜ %{epicDateType} 日期时å‘生错误"
@@ -8234,12 +8605,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr "确定è¦ä»Ž%{bStart}%{parentEpicTitle}%{bEnd}删除%{bStart}%{targetIssueTitle}%{bEnd}å—?"
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr "在当å‰ç¾¤ç»„创建å²è¯—,并将其作为å­å²è¯—添加到当å‰å²è¯—。"
-
-msgid "Epics|Create new epic"
-msgstr "创建新å²è¯—"
-
msgid "Epics|How can I solve this?"
msgstr "我该如何解决该问题?"
@@ -8309,8 +8674,17 @@ msgstr "创建 å²è¯— 时出错"
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
-msgstr "删除 %{issuableType} 时出错"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
+msgstr ""
msgid "Error deleting project. Check logs for error details."
msgstr "删除项目时出错。请检查错误详细信æ¯ã€‚"
@@ -8414,9 +8788,6 @@ msgstr "å‘生了错误。用户未解除é”定"
msgid "Error rendering markdown preview"
msgstr "渲染Markdown预览时出错"
-msgid "Error rendering query"
-msgstr "错误渲染查询"
-
msgid "Error saving label update."
msgstr "ä¿å­˜æ ‡è®°æ›´æ–°æ—¶å‡ºé”™ã€‚"
@@ -8432,6 +8803,9 @@ msgstr "更新所有待办事项状æ€æ—¶å‡ºé”™ã€‚"
msgid "Error updating status of to-do item."
msgstr "更新待办事项状æ€æ—¶å‡ºé”™ã€‚"
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr "上传文件时出错"
@@ -8483,12 +8857,12 @@ msgstr "错误"
msgid "Errors:"
msgstr ""
+msgid "Estimate"
+msgstr ""
+
msgid "Estimated"
msgstr "预计"
-msgid "Event Actions"
-msgstr "事件动作"
-
msgid "EventFilterBy|Filter by all"
msgstr "全部"
@@ -8528,14 +8902,14 @@ msgstr "所有 %{action} å°è¯•éƒ½å·²å¤±è´¥ï¼š %{job_error_message}。请å†è¯•ä
msgid "Every day"
msgstr "æ¯å¤©"
-msgid "Every day (at 4:00am)"
-msgstr "æ¯æ—¥æ‰§è¡Œï¼ˆå‡Œæ™¨ 4 点)"
+msgid "Every day (at %{time})"
+msgstr ""
msgid "Every month"
msgstr "æ¯æœˆ"
-msgid "Every month (on the 1st at 4:00am)"
-msgstr "æ¯æœˆæ‰§è¡Œï¼ˆæ¯æœˆ 1 日凌晨 4 点)"
+msgid "Every month (Day %{day} at %{time})"
+msgstr ""
msgid "Every three months"
msgstr "æ¯ä¸‰ä¸ªæœˆ"
@@ -8546,8 +8920,8 @@ msgstr "æ¯ä¸¤å‘¨"
msgid "Every week"
msgstr "æ¯å‘¨"
-msgid "Every week (Sundays at 4:00am)"
-msgstr "æ¯å‘¨æ‰§è¡Œï¼ˆå‘¨æ—¥å‡Œæ™¨ 4 点)"
+msgid "Every week (%{weekday} at %{time})"
+msgstr ""
msgid "Everyone"
msgstr "所有人"
@@ -8585,6 +8959,9 @@ msgstr "凭è¯é›†"
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr "示例: @sub\\.company\\.com$"
@@ -8603,6 +8980,9 @@ msgstr "ä¸åŒ…括åˆå¹¶æ交。仅é™6,000次æ交。"
msgid "Existing members and groups"
msgstr "当å‰æˆå‘˜å’Œç¾¤ç»„"
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8636,6 +9016,9 @@ msgstr "展开侧边æ "
msgid "Expand up"
msgstr "å‘上展开"
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr "过期时间"
@@ -8651,6 +9034,9 @@ msgstr "已过期"
msgid "Expired %{expiredOn}"
msgstr "已在 %{expiredOn} 过期"
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr "到期"
@@ -8660,6 +9046,9 @@ msgstr "到期时间"
msgid "Expires in %{expires_at}"
msgstr "在 %{expires_at} 过期"
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8738,18 +9127,6 @@ msgstr "分类标签"
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr "未设置分类标签的时候,将使用默认的分类标签`%{default_label}`。"
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr "å‘指标仪表æ¿æ·»åŠ ä¸€ä¸ªæŒ‰é’®ï¼Œç›´æŽ¥é“¾æŽ¥åˆ°æ‚¨çŽ°æœ‰çš„外部仪表æ¿ã€‚"
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr "输入您想è¦é“¾æŽ¥åˆ°ä»ªè¡¨ç›˜çš„ URL"
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr "外部仪表æ¿"
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr "完整的仪表盘URL"
-
msgid "ExternalWikiService|External Wiki"
msgstr "外部 Wiki"
@@ -8876,6 +9253,9 @@ msgstr "ä¿æŠ¤åˆ†æ”¯å¤±è´¥"
msgid "Failed to protect the environment"
msgstr "ä¿æŠ¤çŽ¯å¢ƒå¤±è´¥"
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr "无法删除Zoom会议"
@@ -8951,8 +9331,8 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
-msgstr "无法进行快进åˆå¹¶ã€‚请将æºåˆ†æ”¯åœ¨ç›®æ ‡åˆ†æ”¯ä¸Šå˜åŸºï¼Œæˆ–将目标分支与æºåˆ†æ”¯åˆå¹¶ï¼Œä»¥ä½¿è¯¥åˆå¹¶è¯·æ±‚å¯è¢«åˆå¹¶ã€‚"
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
+msgstr ""
msgid "Fast-forward merge without a merge commit"
msgstr "æ— åˆå¹¶æ交的快进å¼åˆå¹¶"
@@ -9014,6 +9394,12 @@ msgstr "æè¿°"
msgid "FeatureFlags|Edit Feature Flag"
msgstr "编辑功能标志"
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9026,6 +9412,9 @@ msgstr "环境规格"
msgid "FeatureFlags|Feature Flag"
msgstr "功能标志"
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr "功能标记是通过创建一组规则æ¥å®šä¹‰ç›®æ ‡çŽ¯å¢ƒçš„状æ€æ¥æž„建的行为。默认的规则%{codeStart} *%{codeEnd}用于%{boldStart}所有环境%{boldEnd},您å¯ä»¥é€šè¿‡ä¸‹é¢çš„环境规范添加任æ„æ•°é‡çš„规则。您å¯ä»¥åˆ‡æ¢æ¯ä¸ªè§„则的行为以设置它们%{boldStart}å¯ç”¨%{boldEnd}或%{boldStart}ç¦ç”¨%{boldEnd}。"
@@ -9035,15 +9424,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr "功能标志"
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr "功能标志 %{name} 将被删除。您确定å—?"
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr "功能标志å…许通过动æ€åˆ‡æ¢æŸäº›åŠŸèƒ½ä½¿åº”用呈现ä¸åŒç‰¹æ€§ã€‚"
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr "功能标志入门"
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr "ID"
@@ -9062,6 +9460,9 @@ msgstr "安装%{docs_link_anchored_start}兼容的客户端库%{docs_link_anchor
msgid "FeatureFlags|Instance ID"
msgstr "实例ID"
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr "加载功能标志"
@@ -9077,9 +9478,15 @@ msgstr "新建"
msgid "FeatureFlags|New Feature Flag"
msgstr "新建功能标志"
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr "新建功能标志"
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr "百分比上线(登录用户)"
@@ -9170,6 +9577,9 @@ msgstr "文件æµè§ˆ"
msgid "File deleted"
msgstr "文件已删除"
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr "文件钩å­ç±»ä¼¼äºŽç³»ç»Ÿé’©å­ï¼Œä½†ä½œä¸ºæ–‡ä»¶æ‰§è¡Œï¼Œè€Œä¸æ˜¯å‘URLå‘é€æ•°æ®ã€‚"
@@ -9182,6 +9592,9 @@ msgstr "文件已移动"
msgid "File name"
msgstr "文件å称"
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9191,9 +9604,6 @@ msgstr "文件模æ¿"
msgid "File upload error."
msgstr "文件上传错误。"
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr "文件"
@@ -9209,24 +9619,45 @@ msgstr "填写下é¢çš„字段,å¯ç”¨<strong>%{enable_label}</strong>,然åŽç
msgid "Filter"
msgstr "筛选器"
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr "过滤器%{issuable_type}当å‰å…³é—­ã€‚"
msgid "Filter by %{issuable_type} that are currently opened."
msgstr "过滤器%{issuable_type}当å‰å¼€å¯ã€‚"
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr "按æ交消æ¯è¿‡æ»¤"
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr "按里程碑å称过滤"
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9236,6 +9667,9 @@ msgstr "按åŒé‡è®¤è¯è¿‡æ»¤"
msgid "Filter by user"
msgstr "按用户筛选"
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr "筛选项目"
@@ -9467,9 +9901,6 @@ msgstr "从创建议题到部署至生产环境"
msgid "From merge request merge until deploy to production"
msgstr "从åˆå¹¶è¯·æ±‚被åˆå¹¶åŽåˆ°éƒ¨ç½²è‡³ç”Ÿäº§çŽ¯å¢ƒ"
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr "在Kubernetes集群详细信æ¯è§†å›¾ä¸­ï¼Œä»Žåº”用程åºåˆ—表中安装Runner"
@@ -9509,15 +9940,15 @@ msgstr "生æˆæ–°çš„导出"
msgid "Geo"
msgstr "Geo"
-msgid "Geo Designs"
-msgstr "Geo设计"
-
msgid "Geo Nodes"
msgstr "Geo 节点"
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr "Geo设置"
@@ -9695,6 +10126,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr "%{name} 计划强制é‡æ–°ä¸‹è½½"
@@ -9704,10 +10141,10 @@ msgstr "%{name} 已计划é‡æ–°åŒæ­¥"
msgid "Geo|%{name} is scheduled for re-verify"
msgstr "%{name}已计划é‡æ–°éªŒè¯"
-msgid "Geo|All"
-msgstr "全部"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9758,6 +10195,12 @@ msgstr "从ä¸"
msgid "Geo|Next sync scheduled at"
msgstr "下一次åŒæ­¥å®‰æŽ’在"
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr "尚未åŒæ­¥"
@@ -9809,6 +10252,9 @@ msgstr "é‡æ–°æ ¡éªŒ"
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr "状æ€"
@@ -9827,6 +10273,9 @@ msgstr "æ•°æ®åº“当å‰è½åŽäºŽä¸»èŠ‚点%{db_lag}。"
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr "当å‰èŠ‚点è½åŽäºŽä¸»èŠ‚点%{minutes_behind}。"
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9836,6 +10285,12 @@ msgstr "å·²æˆåŠŸåˆ é™¤é¡¹ç›® (%{project_id}) 的跟踪项。"
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr "上传 (%{type}/%{id}) 跟踪æ¡ç›®å·²æˆåŠŸåˆ é™¤ã€‚"
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr "未知状æ€"
@@ -10088,9 +10543,6 @@ msgstr "Gitea 主机地å€"
msgid "Gitea Import"
msgstr "从Gitea导入"
-msgid "Gitlab CI/CD"
-msgstr "GitLab CI/CD"
-
msgid "Gitlab Pages"
msgstr "GitLab Pages"
@@ -10124,9 +10576,6 @@ msgstr "返回%{startTag}å¼€å¯çš„议题%{endTag}并选择è¦æ·»åŠ åˆ°çœ‹æ¿çš„è
msgid "Go full screen"
msgstr "å…¨å±æ¨¡å¼"
-msgid "Go to"
-msgstr "转到"
-
msgid "Go to %{link_to_google_takeout}."
msgstr "转至 %{link_to_google_takeout}。"
@@ -10289,12 +10738,21 @@ msgstr "å¯ç”¨ Gravatar"
msgid "Group"
msgstr "群组"
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr "群组%{group_name}已安排删除。"
msgid "Group %{group_name} was successfully created."
msgstr "群组 %{group_name} å·²æˆåŠŸåˆ›å»ºã€‚"
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10328,6 +10786,12 @@ msgstr "群组URL"
msgid "Group avatar"
msgstr "群组头åƒ"
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr "群组æè¿°"
@@ -10340,10 +10804,13 @@ msgstr "群组详细信æ¯"
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10361,10 +10828,13 @@ msgstr "群组维护者å¯ä»¥åœ¨é€šè¿‡ %{link} 注册群组级 Runner"
msgid "Group members"
msgstr "群组æˆå‘˜"
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr "群组å称"
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10382,12 +10852,18 @@ msgstr "群组路径å¯ç”¨ã€‚"
msgid "Group pipeline minutes were successfully reset."
msgstr "群组æµæ°´çº¿åˆ†é’Ÿæ•°å·²æˆåŠŸé‡ç½®ã€‚"
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr "群组å˜é‡ (继承)"
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr "群组已æˆåŠŸæ›´æ–°ã€‚"
@@ -10454,9 +10930,6 @@ msgstr "为此群组å¯ç”¨SAML身份验è¯ã€‚"
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr "为此群组强制执行仅SSO身份验è¯ã€‚"
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr "ä»…å…许具有SSO身份的æˆå‘˜åŠ å…¥æ­¤ç¾¤ç»„"
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr "强制用户为该群组设置专用的由群组托管å¸æˆ·ã€‚"
@@ -10658,6 +11131,9 @@ msgstr "您åªèƒ½å°†å½“å‰ç¾¤ç»„转移到您管ç†ä¸‹çš„群组。"
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr "您需è¦æ›´æ–°æœ¬åœ°ä»“库以指å‘æ–°ä½ç½®ã€‚"
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr "无法ç¦ç”¨çˆ¶ç»„的“共享群组é”â€ï¼Œåªæœ‰çˆ¶ç¾¤ç»„的所有者æ‰å¯ä»¥æ“作ï¼"
@@ -10763,6 +11239,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr "哈希仓库存储路径"
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr "请让用户å‘é€ç”µå­é‚®ä»¶è‡³"
@@ -10772,6 +11251,9 @@ msgstr "标题徽标已æˆåŠŸåˆ é™¤ã€‚"
msgid "Header message"
msgstr "页头消æ¯"
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10876,6 +11358,9 @@ msgstr "历å²"
msgid "History of authentications"
msgstr "身份验è¯çš„历å²"
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr "Hook 执行失败。确ä¿ç¾¤ç»„有一个包å«æ交的项目。"
@@ -10885,6 +11370,9 @@ msgstr "Hook å·²æˆåŠŸåˆ›å»ºã€‚"
msgid "Hook was successfully updated."
msgstr "é’©å­å·²æˆåŠŸæ›´æ–°ã€‚"
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11035,6 +11523,9 @@ msgstr "如果å¯ç”¨ï¼Œåˆ™ä½¿ç”¨å¤–部æœåŠ¡ä¸Šçš„分类标签æ¥éªŒè¯å¯¹é¡¹ç›®
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
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}。"
@@ -11044,8 +11535,11 @@ msgstr "如果这是一个错误,你å¯ä»¥é€€å‡º%{source_type}。"
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr "如使用 GitHub,GitHubçš„æ交(commits)和拉å–请求(pull request) 页é¢å°†æ˜¾ç¤ºæµæ°´çº¿çŠ¶æ€ã€‚ %{more_info_link}"
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
-msgstr "如果您认为这å¯èƒ½æ˜¯ä¸€ä¸ªé”™è¯¯ï¼Œè¯·å‚阅%{linkStart}GEO故障排除%{linkEnd}文档以了解更多信æ¯ã€‚"
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
+msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
msgstr "如果您丢失了æ¢å¤ç ï¼Œæ‚¨å¯ä»¥ç”Ÿæˆæ–°çš„æ¢å¤ç ï¼Œæ‰€æœ‰ä»¥å‰çš„æ¢å¤ç å°†å¤±æ•ˆã€‚"
@@ -11053,6 +11547,12 @@ msgstr "如果您丢失了æ¢å¤ç ï¼Œæ‚¨å¯ä»¥ç”Ÿæˆæ–°çš„æ¢å¤ç ï¼Œæ‰€æœ‰ä»¥
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr "如果您的HTTP仓库无法公开访问,需在地å€ä¸­æ·»åŠ å‡­æ®ã€‚"
@@ -11065,8 +11565,11 @@ msgstr "忽略"
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
-msgstr "é•œåƒ: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
+msgstr ""
msgid "ImageDiffViewer|2-up"
msgstr "并列(2-up)"
@@ -11083,15 +11586,15 @@ msgstr "高"
msgid "ImageViewerDimensions|W"
msgstr "宽"
+msgid "Impersonation Tokens"
+msgstr ""
+
msgid "Impersonation has been disabled"
msgstr "身份模拟已被ç¦ç”¨"
msgid "Import"
msgstr "导入"
-msgid "Import %{status}"
-msgstr ""
-
msgid "Import CSV"
msgstr "导入CSV"
@@ -11101,6 +11604,9 @@ msgstr "从Gitea导入项目"
msgid "Import all compatible projects"
msgstr "导入所有兼容的项目"
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr "导入所有项目"
@@ -11110,6 +11616,9 @@ msgstr "导入所有仓库"
msgid "Import an exported GitLab project"
msgstr "导入一个从GitLab导出的项目"
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11119,12 +11628,12 @@ msgstr ""
msgid "Import in progress"
msgstr "正在导入"
+msgid "Import in progress. Refresh page to see newly added issues."
+msgstr ""
+
msgid "Import issues"
msgstr "导入议题"
-msgid "Import issues from Jira"
-msgstr ""
-
msgid "Import members"
msgstr "导入æˆå‘˜"
@@ -11215,12 +11724,12 @@ msgstr "使用 GitLab ä¼ä¸šç‰ˆçš„增强议题看æ¿ã€‚"
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr "使用GitLab Enterprise Edition以获得增强的åˆå¹¶è¯·æ±‚功能和官方客户支æŒã€‚"
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
-msgstr "使用GitLab ä¼ä¸šç‰ˆè®®é¢˜æƒé‡å¸¦æ¥çš„增强议题管ç†åŠŸèƒ½ã€‚"
-
msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr "使用GitLabä¼ä¸šç‰ˆå…¨å±€æœç´¢å¸¦æ¥çš„增强æœç´¢åŠŸèƒ½"
+msgid "In %{time_to_now}"
+msgstr ""
+
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
msgstr "è¦å¯ç”¨å®žä¾‹çº§åˆ†æžï¼Œè¯·è¦æ±‚管ç†å‘˜å¯ç”¨ %{usage_ping_link_start}使用情况检测(usage ping)%{usage_ping_link_end}。"
@@ -11251,6 +11760,9 @@ msgstr "包括所有用户必须接å—çš„æœåŠ¡æ¡æ¬¾å议和éšç§æ”¿ç­–。"
msgid "Include author name in notification email body"
msgstr "在通知电å­é‚®ä»¶æ­£æ–‡ä¸­åŒ…å«ä½œè€…姓å"
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr "包å«åˆå¹¶è¯·æ±‚æè¿°"
@@ -11284,6 +11796,12 @@ msgstr "ä¸å…¼å®¹çš„项目"
msgid "Incompatible options set!"
msgstr "设置了ä¸å…¼å®¹çš„选项ï¼"
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr "索引所有项目"
@@ -11308,18 +11826,36 @@ msgstr "手动输入主机密钥"
msgid "Input your repository URL"
msgstr "输入您的仓库URL"
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr "æ’入引用"
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr "æ’入代ç "
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr "æ’入建议"
msgid "Insights"
msgstr "洞察"
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr "安装"
@@ -11369,6 +11905,30 @@ msgstr "集æˆ"
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr "用户å¯ä»¥é€šè¿‡æŽ¨é€æ交æ¥å¯¹é¡¹ç›®ä½œå‡ºè´¡çŒ®ã€‚"
@@ -11408,6 +11968,12 @@ msgstr "登录å或密ç æ— æ•ˆ"
msgid "Invalid URL"
msgstr "无效的网å€"
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11444,18 +12010,27 @@ msgstr "登录å或密ç æ— æ•ˆ"
msgid "Invalid pin code"
msgstr "无效的 pin ç "
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr "无效的查询"
msgid "Invalid repository path"
msgstr "无效的仓库路径"
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr "无效的æœåŠ¡å™¨å“应"
msgid "Invalid start or end time format"
msgstr "无效的开始时间或结æŸæ—¶é—´æ ¼å¼"
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr "无效的åŒé‡è®¤è¯ç ã€‚"
@@ -11468,6 +12043,9 @@ msgstr "邀请"
msgid "Invite \"%{trimmed}\" by email"
msgstr "通过电å­é‚®ä»¶é‚€è¯·â€œ%{trimmed}â€"
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr "邀请群组"
@@ -11531,6 +12109,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr "è®®é¢˜æ¨¡æ¿ (å¯é€‰)"
@@ -11543,6 +12124,33 @@ msgstr "议题由%{name}以%{reason}原因关闭"
msgid "Issue weight"
msgstr "议题æƒé‡"
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr "看æ¿"
@@ -11600,6 +12208,9 @@ msgstr "关闭议题"
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr "默认分支中的åˆå¹¶è¯·æ±‚å’Œæ交引用的议题将自动关闭"
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr "议题评论,åˆå¹¶è¯·æ±‚的差异和评论,标记,里程碑,代ç ç‰‡æ®µå’Œå…¶ä»–项目实体"
@@ -11645,6 +12256,30 @@ msgstr ""
msgid "It's you"
msgstr "你自己"
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr "Jaeger 地å€"
@@ -11657,19 +12292,22 @@ msgstr "1月"
msgid "January"
msgstr "1月"
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11795,6 +12433,9 @@ msgstr "作业产物已被删除"
msgid "Job|The artifacts will be removed"
msgstr "产物将被删除"
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr "此作业已失败, 因为未æˆåŠŸåˆ›å»ºå¿…è¦çš„资æºã€‚"
@@ -11834,6 +12475,9 @@ msgstr "6月"
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr "é”®"
@@ -11877,7 +12521,7 @@ msgid "Kubernetes cluster was successfully updated."
msgstr "Kubernetes集群已æˆåŠŸæ›´æ–°ã€‚"
msgid "Kubernetes deployment not found"
-msgstr "找ä¸åˆ°Kubinetes部署"
+msgstr "找ä¸åˆ°Kubernetes部署"
msgid "Kubernetes error: %{error_code}"
msgstr "Kubinentes 错误: %{error_code}"
@@ -12012,6 +12656,9 @@ msgstr "姓"
msgid "Last reply by"
msgstr "最åŽå›žå¤æ¥è‡ªäºŽ"
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr "上次仓库检查"
@@ -12096,6 +12743,9 @@ msgstr "进一步了解有关æ¼æ´žæ£€æŸ¥(Vulnerability-Check)çš„ä¿¡æ¯"
msgid "Learn more about Web Terminal"
msgstr "了解更多关于 Web 终端"
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr "通过%{docs_link_start}GitLab Pages上的文档%{docs_link_end}了解更多关于å‘项目添加è¯ä¹¦çš„ä¿¡æ¯ã€‚"
@@ -12117,9 +12767,6 @@ msgstr "了解更多有关签åæ交的详细信æ¯"
msgid "Learn more about the dependency list"
msgstr "了解更多关于ä¾èµ–列表的信æ¯"
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr "了解更多"
@@ -12147,6 +12794,9 @@ msgstr "退出项目"
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr "使用默认值设定 \"文件类型\" 和 \"交付方法\""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr "Let's Encryptä¸æŽ¥å—example.com的电å­é‚®ä»¶"
@@ -12159,6 +12809,9 @@ msgstr "许å¯è¯"
msgid "License Compliance"
msgstr "许å¯è¯åˆè§„"
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr "许å¯è¯æ£€æŸ¥"
@@ -12183,15 +12836,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr "许å¯è¯"
-msgid "LicenseCompliance|License Compliance"
-msgstr "许å¯è¯åˆè§„性"
-
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] ""
@@ -12322,6 +12969,9 @@ msgstr "购买许å¯è¯"
msgid "License|License"
msgstr "许å¯è¯"
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr "您éšæ—¶å¯ä»¥é€šè¿‡å‡çº§è®¡åˆ’æ¥æ¢å¤å¯¹é‡‘牌功能的访问æƒé™ã€‚"
@@ -12337,6 +12987,9 @@ msgstr "您的许å¯è¯"
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr "您的GitLab Ultimateå…费试用将在%{trial_ends_on}到期。"
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr "é™åˆ¶æ—¶é—´è·Ÿè¸ªå•ä½æ˜¾ç¤ºåˆ°å°æ—¶ã€‚"
@@ -12431,6 +13084,9 @@ msgstr "正在加载..."
msgid "Loading…"
msgstr "正在加载..."
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr "本地化"
@@ -12545,12 +13201,12 @@ msgstr "请确ä¿å¦¥å–„ä¿å­˜å®ƒ - 您无法å†æ¬¡è®¿é—®å®ƒçš„内容。"
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr "ç¡®ä¿æ‚¨å·²ç™»å½•åˆ°æ¬²å¯¼å…¥é¡¹ç›®æ‰€æœ‰è€…çš„å¸æˆ·ã€‚"
+msgid "Make this epic confidential"
+msgstr ""
+
msgid "Makes this issue confidential."
msgstr "将此议题设置为ç§å¯†."
-msgid "Malformed string"
-msgstr "字符串格å¼é”™è¯¯"
-
msgid "Manage"
msgstr "管ç†"
@@ -12575,6 +13231,9 @@ msgstr "管ç†ç¾¤ç»„标记"
msgid "Manage labels"
msgstr "管ç†æ ‡è®°"
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr "管ç†é¡¹ç›®æ ‡è®°"
@@ -12626,9 +13285,6 @@ msgstr "标记为已完æˆ"
msgid "Mark as resolved"
msgstr "标记为已解决"
-msgid "Mark comment as resolved"
-msgstr "将评论标记为已解决"
-
msgid "Mark this issue as a duplicate of another issue"
msgstr "将此议题标记为å¦ä¸€ä¸ªè®®é¢˜çš„é‡å¤"
@@ -12638,9 +13294,6 @@ msgstr "将此议题标记为与å¦ä¸€ä¸ªè®®é¢˜çš„相关"
msgid "Markdown"
msgstr "Markdown"
-msgid "Markdown Help"
-msgstr "Markdown帮助"
-
msgid "Markdown enabled"
msgstr "支æŒMarkdownæ ¼å¼"
@@ -12818,6 +13471,9 @@ msgstr "项目 <i>维护者</i> 或 <i>所有者</i>å¯ä»¥æ·»åŠ æˆå‘˜"
msgid "Members of <strong>%{project_name}</strong>"
msgstr "<strong>%{project_name}</strong>çš„æˆå‘˜"
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr "有æƒè®¿é—®%{strong_start}%{group_name}%{strong_end}çš„æˆå‘˜"
@@ -12827,9 +13483,6 @@ msgstr "申请访问%{strong_start}%{group_name}%{strong_end}待定的æˆå‘˜"
msgid "Memory Usage"
msgstr "内存使用情况"
-msgid "Memory limit exceeded while rendering template"
-msgstr "渲染模æ¿æ—¶è¶…出了内存é™åˆ¶"
-
msgid "Merge"
msgstr "åˆå¹¶"
@@ -12842,6 +13495,9 @@ msgstr "åˆå¹¶è¯·æ±‚"
msgid "Merge Request Approvals"
msgstr "åˆå¹¶è¯·æ±‚核准"
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr "åˆå¹¶è¯·æ±‚"
@@ -12875,6 +13531,9 @@ msgstr "åˆå¹¶è¯·æ±‚"
msgid "Merge request %{iid} authored by %{authorName}"
msgstr "åˆå¹¶è¯·æ±‚%{iid} 作者: %{authorName}"
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr "åˆå¹¶è¯·æ±‚批准"
@@ -12923,9 +13582,18 @@ msgstr "冲çª"
msgid "MergeConflict|origin//their changes"
msgstr "æ¥æº//他们的更改"
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 "ä¿å­˜è¯„论è‰ç¨¿æ—¶å‘生错误。"
@@ -12986,7 +13654,7 @@ msgstr "å¼€å¯æœ‰å…³%{linkStart}%{commitDisplay}%{linkEnd}中较旧的å˜æ›´çš„è
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr "å¼€å¯æœ‰å…³æ交%{linkStart}%{commitDisplay}%{linkEnd}çš„è¯é¢˜"
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13004,6 +13672,9 @@ msgstr ""
msgid "Merged"
msgstr "å·²åˆå¹¶"
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr "å·²åˆå¹¶åˆ†æ”¯æ­£åœ¨è¢«åˆ é™¤ã€‚该æ“作å¯èƒ½éœ€è¦ä¸€äº›æ—¶é—´ï¼Œå…·ä½“å–决于分支的数é‡ã€‚请刷新页é¢ä»¥æŸ¥çœ‹æ›´æ–°ã€‚"
@@ -13025,9 +13696,6 @@ msgstr "消æ¯"
msgid "Method"
msgstr "方法"
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr "指标已æˆåŠŸæ·»åŠ ã€‚"
@@ -13049,21 +13717,24 @@ msgstr "指标"
msgid "Metrics - Grafana"
msgstr "指标 - Grafana"
-msgid "Metrics - Influx"
-msgstr "指标 - Influx"
-
msgid "Metrics - Prometheus"
msgstr "指标 - Prometheus"
msgid "Metrics Dashboard"
msgstr "指标仪表æ¿"
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
msgid "Metrics and profiling"
msgstr "指标与分æž"
-msgid "Metrics for environment"
-msgstr "环境指标"
-
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
@@ -13085,6 +13756,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr "添加指标"
@@ -13140,6 +13832,12 @@ msgstr "图例标签(å¯é€‰ï¼‰"
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr "链接包å«ä¸€ä¸ªæ— æ•ˆçš„时间窗å£ï¼Œè¯·éªŒè¯é“¾æŽ¥ä»¥æŸ¥çœ‹è¯·æ±‚的时间范围。"
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr "最大值"
@@ -13158,6 +13856,9 @@ msgstr "Prometheus查询文档"
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr "创建仪表æ¿æ—¶å‡ºé”™ã€‚"
@@ -13194,6 +13895,9 @@ msgstr "æ¥è‡ªPrometheus终端节点的æ„外部署数æ®å“应"
msgid "Metrics|Unit label"
msgstr "å•ä½æ ‡ç­¾"
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr "用作图表的标题"
@@ -13255,6 +13959,63 @@ msgstr "当å‰è®¸å¯è¯æ— æ³•ä½¿ç”¨é‡Œç¨‹ç¢‘列表"
msgid "Milestone lists show all issues from the selected milestone."
msgstr "里程碑列表显示所选里程碑的所有议题。"
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr "里程碑"
@@ -13264,6 +14025,12 @@ msgstr "您å³å°†æ°¸ä¹…删除里程碑 %{milestoneTitle} 并将其从 %{issuesWi
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr "您å³å°†æ°¸ä¹…删除里程碑 %{milestoneTitle}。此里程碑当å‰æœªç”¨äºŽä»»ä½•è®®é¢˜æˆ–åˆå¹¶è¯·æ±‚。"
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr "删除里程碑"
@@ -13273,21 +14040,39 @@ msgstr "删除里程碑 %{milestoneTitle}?"
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr "删除里程碑 %{milestoneTitle}失败"
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr "未找到里程碑 %{milestoneTitle}"
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr "å°† %{milestoneTitle} å‡çº§ä¸ºç¾¤ç»„里程碑?"
msgid "Milestones|Promote Milestone"
msgstr "å‡çº§é‡Œç¨‹ç¢‘"
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr "æå‡%{milestoneTitle}åŽï¼Œè¯¥é‡Œç¨‹ç¢‘å°†å¯ç”¨äºŽ%{groupName}群组内的所有项目。如果现有项目里程碑具有相åŒæ ‡é¢˜ï¼Œè¿™äº›é¡¹ç›®é‡Œç¨‹ç¢‘被åˆå¹¶å…¥ç¾¤ç»„里程碑。"
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr "该æ“作无法撤销。"
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr "在我们预先安排更多镜åƒä¹‹å‰å¯ç”¨çš„最å°å®¹é‡ã€‚"
@@ -13348,6 +14133,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr "å–消"
@@ -13462,6 +14250,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr "多é‡è®®é¢˜çœ‹æ¿"
@@ -13471,6 +14262,9 @@ msgstr "找到多个模型类型: %{model_types}"
msgid "Multiple uploaders found: %{uploader_types}"
msgstr "找到多个上传器: %{uploader_types}"
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13483,9 +14277,6 @@ msgstr "å称"
msgid "Name has already been taken"
msgstr "å称已被使用"
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr "命å新标记"
@@ -13495,9 +14286,6 @@ msgstr "å称:"
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr "命å空间: %{namespace}"
-
msgid "Namespaces to index"
msgstr "è¦ç´¢å¼•çš„命å空间"
@@ -13531,11 +14319,59 @@ msgstr ""
msgid "Network"
msgstr "网络"
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr "从ä¸"
msgid "New"
-msgstr "新增事项"
+msgstr "新增"
msgid "New Application"
msgstr "新建应用"
@@ -13559,6 +14395,9 @@ msgid "New Issue"
msgid_plural "New Issues"
msgstr[0] "新建议题"
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13625,6 +14464,9 @@ msgstr "新建议题"
msgid "New issue title"
msgstr "新议题标题"
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr "新建标记"
@@ -13682,6 +14524,9 @@ msgstr "默认情况下,新注册的用户将是外部用户"
msgid "Next"
msgstr "预览版"
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13700,18 +14545,9 @@ msgstr "此请求没有%{header}。"
msgid "No %{providerTitle} repositories found"
msgstr "找ä¸åˆ°%{providerTitle}的仓库"
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr "æ— å²è¯—"
-msgid "No Label"
-msgstr "无标记"
-
-msgid "No Milestone"
-msgstr "无里程碑"
-
msgid "No Scopes"
msgstr "无范围"
@@ -13802,12 +14638,18 @@ msgstr "未找到文件。"
msgid "No forks are available to you."
msgstr "没有您å¯ç”¨çš„派生。"
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr "没有作业日志"
msgid "No jobs to show"
msgstr "没有è¦æ˜¾ç¤ºçš„作业"
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr "没有具有此类å称或æ述的标记"
@@ -13832,6 +14674,9 @@ msgstr "找ä¸åˆ°åˆå¹¶è¯·æ±‚"
msgid "No messages were logged"
msgstr "未记录任何消æ¯"
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr "没有è¦æ˜¾ç¤ºçš„里程碑"
@@ -13967,6 +14812,9 @@ msgstr "备注"
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 "请注æ„,此邀请已å‘é€è‡³%{mail_to_invite_email},但您当å‰ä½¿ç”¨ç”µå­é‚®ä»¶%{mail_to_current_user}以%{link_to_current_user} 登录。"
@@ -13991,6 +14839,9 @@ msgstr "确定è¦å–消此评论å—?"
msgid "Notes|Collapse replies"
msgstr "收起回å¤"
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr "显示所有活动"
@@ -14105,9 +14956,15 @@ msgstr "11月"
msgid "November"
msgstr "11月"
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr "现在您å¯ä»¥åœ¨é¡¶éƒ¨è®¿é—®åˆå¹¶è¯·æ±‚的导航标签,它们更容易找到。"
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14174,6 +15031,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr "新手上路"
@@ -14183,9 +15049,6 @@ msgstr "仓库导入åŽï¼Œå¯ä»¥é€šè¿‡SSH进行镜åƒã€‚点击%{link_start}æ­¤å¤
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr "删除åŽå°†æ— æ³•æ¢å¤æ´¾ç”Ÿå…³ç³»ï¼Œæ‚¨å°†æ— æ³•å†å‘æºé¡¹ç›®å‘é€åˆå¹¶è¯·æ±‚。"
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 "导出的文件准备就绪åŽï¼Œæ‚¨å°†æ”¶åˆ°å¸¦æœ‰ä¸‹è½½é“¾æŽ¥çš„通知电å­é‚®ä»¶ï¼Œæˆ–者您å¯ä»¥ä»Žæ­¤é¡µé¢ä¸‹è½½ã€‚"
@@ -14250,8 +15113,8 @@ msgstr "åªæœ‰é¡¹ç›®æˆå‘˜å¯ä»¥å‘表评论。"
msgid "Only project members will be imported. Group members will be skipped."
msgstr "仅导入项目æˆå‘˜ã€‚群组æˆå‘˜å°†è¢«è·³è¿‡ã€‚"
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
-msgstr "åªæœ‰ç”¨æˆ·çš„电å­é‚®ä»¶åœ°å€å…·æœ‰æ­¤åŸŸåæ‰å¯ä»¥æ·»åŠ åˆ°ç¾¤ç»„。<br>例如: <code>girlab.com</code>。ç¦æ­¢ä½¿ç”¨æŸäº›å¸¸è§åŸŸå。 %{read_more_link}。"
+msgid "Only verified users with an email address in any of these domains can be added to the group."
+msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
msgstr "åªæœ‰â€œé«˜çº§â€æˆ–“银牌â€åŠä»¥ä¸Šçº§åˆ«ä¸­çš„“Reporterâ€åŠä»¥ä¸Šè§’色å¯ä»¥æŸ¥çœ‹æ•ˆçŽ‡åˆ†æžã€‚"
@@ -14295,8 +15158,8 @@ msgstr "打开: %{open} • 关闭: %{closed}"
msgid "Opened"
msgstr "已打开"
-msgid "Opened MR"
-msgstr "å¼€å¯çš„åˆå¹¶è¯·æ±‚"
+msgid "Opened MRs"
+msgstr ""
msgid "Opened issues"
msgstr "å¼€å¯çš„议题"
@@ -14310,6 +15173,9 @@ msgstr "打开一个新窗å£"
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr "æ“作失败。请检查 Pod 日志 %{pod_name} 了解更多信æ¯ã€‚"
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr "æ“作超时。请检查 Pod 日志 %{pod_name} 了解更多信æ¯ã€‚"
@@ -14340,8 +15206,8 @@ msgstr "è¿ç»´ä»ªè¡¨æ¿æä¾›æ¯ä¸ªé¡¹ç›®çš„è¿è¡ŒçŠ¶å†µçš„摘è¦ï¼ŒåŒ…括æµæ°´
msgid "Optional"
msgstr "å¯é€‰"
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
-msgstr "å¯é€‰å‚数“å˜é‡â€å¿…须是键和值的数组。例如:[key1,value1,key2,value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
+msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr "您å¯ä»¥é€‰æ‹© %{link_to_customize} FogBugz的电å­é‚®ä»¶åœ°å€å’Œç”¨æˆ·å如何被导入到GitLab。"
@@ -14388,6 +15254,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14406,6 +15275,9 @@ msgstr "拥有者为我"
msgid "Owner"
msgstr "所有者"
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14427,6 +15299,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr "包已被删除"
@@ -14514,6 +15392,9 @@ msgstr "如果尚未é…置,需è¦å°†ä»¥ä¸‹å†…容添加到%{codeStart}pom.xml%{
msgid "PackageRegistry|Installation"
msgstr "安装"
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr "了解GitLab如何%{noPackagesLinkStart}å‘布和共享您的软件包%{noPackagesLinkEnd}。"
@@ -14532,6 +15413,9 @@ msgstr "Maven XML"
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14562,23 +15446,38 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr "当å‰æ— è½¯ä»¶åŒ…"
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr "获å–此软件包的详细信æ¯æ—¶å‡ºçŽ°é—®é¢˜ã€‚"
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr "无法加载软件包"
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
-msgstr "您将è¦åˆ é™¤<b>%{packageName}</b>,此æ“作ä¸å¯é€†ï¼Œç¡®å®šç»§ç»­å—?"
+msgid "PackageRegistry|Upcoming package managers"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
+msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
-msgstr "å³å°†åˆ é™¤%{boldStart}%{name}%{boldEnd}çš„%{boldStart}%{version}%{boldEnd}版本,确定继续å—?"
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
+msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
msgstr ""
@@ -14610,6 +15509,9 @@ msgstr ""
msgid "Packages"
msgstr "软件包"
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr "找ä¸åˆ°é¡µé¢"
@@ -14697,6 +15599,9 @@ msgstr "密ç ä¿®æ”¹æˆåŠŸ"
msgid "Password was successfully updated. Please login with it"
msgstr "密ç æ›´æ–°æˆåŠŸã€‚请登录"
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr "逾期"
@@ -14715,6 +15620,9 @@ 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'. Don't use your private SSH key."
msgstr "粘贴您的SSH公钥,通常包å«åœ¨æ–‡ä»¶'~/.ssh/id_ed25519.pub'或'~/.ssh/id_rsa.pub' 中,并以“ssh-ed25519â€æˆ–“ssh-rsaâ€å¼€å¤´ã€‚请ä¸è¦ä½¿ç”¨æ‚¨çš„SSHç§é’¥ã€‚"
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr "路径"
@@ -14757,9 +15665,15 @@ msgstr "在GitLab项目上执行常è§æ“作"
msgid "Performance optimization"
msgstr "性能优化"
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr "下载"
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr "å‰ç«¯èµ„æº"
@@ -14781,9 +15695,6 @@ msgstr "跟踪"
msgid "Permissions"
msgstr "æƒé™"
-msgid "Permissions Help"
-msgstr "æƒé™å¸®åŠ©"
-
msgid "Permissions, LFS, 2FA"
msgstr "æƒé™ï¼ŒLFS,2FA"
@@ -14805,9 +15716,6 @@ msgstr "Phabricator任务"
msgid "Pick a name"
msgstr "选择一个å称"
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr "请为应用程åºé€‰æ‹©ä¸€ä¸ªå称,以便生æˆå”¯ä¸€çš„%{type}令牌。"
-
msgid "Pin code"
msgstr "Pinç "
@@ -14916,6 +15824,9 @@ msgstr "去年的æµæ°´çº¿"
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr "åˆå¹¶è¯·æ±‚çš„æµæ°´çº¿å·²é…置。游离的æµæ°´çº¿è¿è¡ŒäºŽåˆå¹¶è¯·æ±‚环境,而éžåˆå¹¶ç»“果。更多内容请å‚阅关于åˆå¹¶ç»“果的æµæ°´çº¿æ–‡æ¡£ã€‚"
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr "“%{project_name}â€çš„æµæ°´çº¿è®¾ç½®å·²æˆåŠŸæ›´æ–°ã€‚"
@@ -14976,15 +15887,24 @@ msgstr "此项目当å‰æœªé…ç½®è¿è¡Œæµæ°´çº¿ã€‚"
msgid "Pipelines|parent"
msgstr "父级"
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr "æ交"
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
-msgstr "无法获å–æµæ°´çº¿çŠ¶æ€ã€‚有关故障排除步骤,请å‚阅 %{linkStart}文档%{linkEnd}。"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
+msgstr ""
msgid "Pipeline|Coverage"
msgstr "覆盖率"
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -14997,30 +15917,54 @@ msgstr "时长"
msgid "Pipeline|Existing branch name or tag"
msgstr "现有分支å称或者标签"
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr "é”®"
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr "åˆå¹¶é˜Ÿåˆ—æµæ°´çº¿"
msgid "Pipeline|Merged result pipeline"
msgstr "åˆå¹¶ç»“æžœæµæ°´çº¿"
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr "æµæ°´çº¿"
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr "è¿è¡Œæµæ°´çº¿"
msgid "Pipeline|Run for"
msgstr "è¿è¡ŒäºŽ"
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr "æœç´¢åˆ†æ”¯"
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr "指定è¦åœ¨æ­¤æ¬¡è¿è¡Œä¸­ä½¿ç”¨çš„å˜é‡å€¼ã€‚默认情况下将使用 %{settings_link} 中指定的值。"
@@ -15036,6 +15980,9 @@ msgstr "åœæ­¢æµæ°´çº¿"
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr "åœæ­¢æµæ°´çº¿ï¼ƒ%{pipelineId}å—?"
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr "触å‘者"
@@ -15072,6 +16019,12 @@ msgstr "项目管ç†è½¯ä»¶ (æºæ交端点)"
msgid "Plain diff"
msgstr "文本差异"
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr "PlantUML"
@@ -15165,6 +16118,9 @@ msgstr "请注æ„,GitLabä¸æ供此应用程åºï¼Œæ‚¨åº”该在å…许访问之
msgid "Please provide a name"
msgstr "请æä¾›å称"
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr "请æ供有效的电å­é‚®ä»¶åœ°å€ã€‚"
@@ -15240,6 +16196,9 @@ msgstr "正在使用的Pod"
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr "å好设置"
@@ -15330,6 +16289,9 @@ msgstr "使用相对时间"
msgid "Press %{key}-C to copy"
msgstr "按 %{key}-C å¤åˆ¶"
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr "ç¦æ­¢å‘当å‰ç¾¤ç»„中的项目添加新æˆå‘˜"
@@ -15366,6 +16328,9 @@ msgstr "预览上传数æ®"
msgid "Previous Artifacts"
msgstr "å‰ä¸€ä¸ªäº§ç‰©"
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15585,9 +16550,6 @@ msgstr "å…¨å"
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr "身份模拟"
-
msgid "Profiles|Include private contributions on my profile"
msgstr "在个人资料中包å«éžå…¬å¼€è´¡çŒ®"
@@ -15633,9 +16595,6 @@ msgstr "组织"
msgid "Profiles|Path"
msgstr "路径"
-msgid "Profiles|Personal Access"
-msgstr "个人访问"
-
msgid "Profiles|Position and size your new avatar"
msgstr "您新头åƒçš„ä½ç½®å’Œå¤§å°"
@@ -15780,12 +16739,6 @@ msgstr "您当å‰çš„状æ€ï¼Ÿ"
msgid "Profiles|e.g. My MacBook key"
msgstr "例如: My MacBook Key"
-msgid "Profiles|impersonation"
-msgstr "身份模拟"
-
-msgid "Profiles|personal access"
-msgstr "个人访问"
-
msgid "Profiles|username"
msgstr "用户å"
@@ -15816,6 +16769,9 @@ msgstr "项目“%{name}â€ä¸å†å¯ç”¨ã€‚选择å¦ä¸€ä¸ªé¡¹ç›®ä»¥ç»§ç»­ã€‚"
msgid "Project %{project_repo} could not be found"
msgstr "无法找到项目 %{project_repo}"
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr "正在导入项目 \"%{project_name}\"。"
@@ -15837,6 +16793,9 @@ msgstr "项目 '%{project_name}' 已更新完æˆã€‚"
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr "项目%{project_name}将于%{date}被删除"
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15867,6 +16826,9 @@ msgstr "项目头åƒ"
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr "项目ä¸èƒ½åˆ†äº«ç»™å½“å‰æ‰€åœ¨çš„群组或其任一级父群组。"
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr "项目é…ç½®, 包括æœåŠ¡"
@@ -15891,8 +16853,8 @@ msgstr "项目导出已被删除。"
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr "项目导出链接已过期。请从项目设置中é‡æ–°ç”Ÿæˆé¡¹ç›®å¯¼å‡ºã€‚"
-msgid "Project export started. A download link will be sent by email."
-msgstr "项目导出已开始。下载链接将通过电å­é‚®ä»¶å‘é€ã€‚"
+msgid "Project export started. A download link will be sent by email and made available on this page."
+msgstr ""
msgid "Project has too many %{label_for_message} to search"
msgstr "项目有太多个 %{label_for_message} è¦æœç´¢"
@@ -15900,6 +16862,9 @@ msgstr "项目有太多个 %{label_for_message} è¦æœç´¢"
msgid "Project members"
msgstr "项目æˆå‘˜"
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr "项目å称"
@@ -16014,9 +16979,6 @@ msgstr "评论"
msgid "ProjectService|Comment will be posted on each event"
msgstr "评论将å‘布在æ¯ä¸ªäº‹ä»¶ä¸Š"
-msgid "ProjectService|Last edit"
-msgstr "上次编辑"
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr "在GitLab项目上执行常è§æ“作: %{project_name}"
@@ -16182,6 +17144,9 @@ msgstr "仓库"
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr "在Git仓库中与其他人分享代ç "
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr "从命令行推é€æ—¶æ˜¾ç¤ºåˆ›å»º/查看åˆå¹¶è¯·æ±‚的链接"
@@ -16227,6 +17192,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr "当出现冲çªæ—¶ï¼Œç”¨æˆ·å¯ä»¥é€‰æ‹©rebase"
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr "Wiki"
@@ -16377,6 +17345,9 @@ msgstr "空白项目"
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr "è”系管ç†å‘˜å¯ç”¨å¯¼å…¥é¡¹ç›®çš„选项。"
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr "从模æ¿åˆ›å»º"
@@ -16470,12 +17441,18 @@ msgstr "自动é…ç½®"
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr "自动部署和é…ç½®Prometheus到集群æ¥ç›‘测项目的环境"
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr "常用指标"
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr "常用指标会根æ®åº”用广泛的导出器指标库自动监控。"
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr "自定义指标"
@@ -16551,9 +17528,6 @@ msgstr "将议题æå‡ä¸ºå²è¯—"
msgid "Promote these project milestones into a group milestone."
msgstr "将这些项目里程碑å‡çº§ä¸ºç¾¤ç»„里程碑。"
-msgid "Promote to Group Milestone"
-msgstr "å‡çº§åˆ°ç¾¤ç»„里程碑"
-
msgid "Promote to group label"
msgstr "å‡çº§åˆ°ç¾¤ç»„标记"
@@ -16572,30 +17546,84 @@ msgstr "将机密问题æå‡ä¸ºéžæœºå¯†å²è¯—。由于å²è¯—对群组æˆå‘˜å…¬
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr "ä¸å†æ˜¾ç¤º"
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 "Epic 让您å¯ä»¥é€šè¿‡è¿½è¸ªè·¨é¡¹ç›®å’Œé‡Œç¨‹ç¢‘共享主题的问题组,更有效地管ç†é¡¹ç›®ç»„åˆã€‚"
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr "了解更多"
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr "查看%{subscription_link_start}铜牌计划%{subscription_link_end}中的其他功能"
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr "此功能已é”定"
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr "å‡çº§è®¢é˜…计划"
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr "使您的议题分出轻é‡"
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 "当议题数目很多时,很难得到一个整体情况。 通过给议题添加æƒé‡ï¼Œå¯ä»¥æ›´å¥½åœ°äº†è§£å·¥ä½œé‡ã€ æˆæœ¬ã€æ‰€éœ€æ—¶é—´æˆ–æ¯ä¸ªè®®é¢˜çš„价值,从而更好地进行管ç†ã€‚"
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr "æ示用户上传SSH密钥"
@@ -16731,9 +17759,6 @@ msgstr "公开 - 群组和任何公开项目å¯ä»¥å¼€æ”¾æŸ¥çœ‹ï¼Œæ— éœ€èº«ä»½éªŒ
msgid "Public - The project can be accessed without any authentication."
msgstr "公开 - 无需任何身份验è¯å³å¯è®¿é—®è¯¥é¡¹ç›®ã€‚"
-msgid "Public Access Help"
-msgstr "公开访问帮助"
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr "公共部署密钥(%{deploy_keys_count})"
@@ -16743,6 +17768,12 @@ msgstr "公开æµæ°´çº¿"
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr "拉å–"
@@ -16845,6 +17876,9 @@ msgstr "查询有效"
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr "快速æ“作å¯ç”¨äºŽè®®é¢˜æ述和评论框。"
@@ -16854,9 +17888,6 @@ msgstr "å¿«æ·èŒƒå›´"
msgid "README"
msgstr "自述文件"
-msgid "Rake Tasks Help"
-msgstr "Rake任务帮助"
-
msgid "Raw blob request rate limit per minute"
msgstr "æ¯åˆ†é’ŸåŽŸå§‹Blob请求速率é™åˆ¶"
@@ -16893,9 +17924,6 @@ msgstr "Rebase正在进行中"
msgid "Receive alerts from manually configured Prometheus servers."
msgstr "从手动é…置的 Prometheus æœåŠ¡å™¨æŽ¥æ”¶è­¦æŠ¥ã€‚"
-msgid "Receive alerts on GitLab from any source"
-msgstr "在GitLab上é¢æŽ¥å—æ¥è‡ªä»»ä½•æ¥æºçš„警告"
-
msgid "Receive notifications about your own activity"
msgstr "接收关于您自己活动的通知"
@@ -16990,6 +18018,21 @@ msgstr "使用åŒé‡è®¤è¯åº”用注册"
msgid "Registration"
msgstr "注册"
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr "相关的部署作业"
@@ -17033,6 +18076,18 @@ msgstr "å‘布说明:"
msgid "Release title"
msgstr "å‘布标题"
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr "å‘布"
@@ -17054,6 +18109,9 @@ msgstr "ä¿å­˜å‘布详细信æ¯æ—¶å‡ºé”™"
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr "è®°ä½è´¦å·"
@@ -17123,6 +18181,12 @@ msgstr "从å²è¯—中移除"
msgid "Remove group"
msgstr "删除群组"
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17165,6 +18229,9 @@ msgstr "已删除%{assignee_text}%{assignee_references}。"
msgid "Removed %{epic_ref} from child epics."
msgstr "已从å­å²è¯—中删除%{epic_ref}。"
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr "已删除%{label_references}%{label_text}。"
@@ -17204,6 +18271,9 @@ msgstr "移除%{assignee_text} %{assignee_references}。"
msgid "Removes %{epic_ref} from child epics."
msgstr "从å­å²è¯—中删除%{epic_ref}。"
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr "删除%{label_references}%{label_text}."
@@ -17255,6 +18325,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr "é‡æ–°å¼€å¯å²è¯—"
@@ -17285,6 +18358,9 @@ msgstr "已将所有标记替æ¢ä¸º%{label_references}%{label_text}。"
msgid "Replaces the clone URL root."
msgstr "替æ¢å…‹éš†URL根地å€ã€‚"
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr "通过电å­é‚®ä»¶å›žå¤"
@@ -17300,8 +18376,11 @@ msgstr "回å¤..."
msgid "Repo by URL"
msgstr "从 URL 导入仓库"
-msgid "Report Type: %{report_type}"
-msgstr "报告类型: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
+msgstr ""
msgid "Report abuse to admin"
msgstr "å‘管ç†å‘˜æŠ¥å‘Šæ»¥ç”¨è¡Œä¸º"
@@ -17403,6 +18482,9 @@ msgstr "仓库设置"
msgid "Repository URL"
msgstr "仓库地å€"
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr "已触å‘仓库检查。"
@@ -17439,6 +18521,9 @@ msgstr "选择"
msgid "Request Access"
msgstr "申请æƒé™"
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr "请求å‚æ•°%{param}缺失。"
@@ -17454,11 +18539,14 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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 "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 all users in this group to setup Two-factor authentication"
msgstr "è¦æ±‚此群组中的所有用户都å¯ç”¨åŒé‡è®¤è¯"
@@ -17472,6 +18560,12 @@ msgstr "需è¦ç”¨æˆ·å¯†ç æ‰èƒ½æ‰¹å‡†"
msgid "Require users to prove ownership of custom domains"
msgstr "è¦æ±‚用户è¯æ˜Žè‡ªå®šä¹‰åŸŸçš„所有æƒ"
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17493,10 +18587,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17564,6 +18655,9 @@ msgstr "已解决 1 个讨论。"
msgid "Resolved all discussions."
msgstr "已解决所有讨论。"
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr "由%{name}解决"
@@ -17576,6 +18670,12 @@ msgstr "解æžä¸€æ¬¡IP地å€å¹¶ä½¿ç”¨å®ƒä»¬æ交请求"
msgid "Response"
msgstr "å“应"
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr "å“应ä¸åŒ…括`service_desk_address`"
@@ -17721,6 +18821,9 @@ msgstr "回滚"
msgid "Rook"
msgstr "Rook"
+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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17784,9 +18887,6 @@ msgstr "Runnerå¯ä»¥æ”¾åœ¨ä¸åŒçš„用户ã€æœåŠ¡å™¨ï¼Œç”šè‡³æœ¬åœ°æœºå™¨ä¸Šã€‚
msgid "Runners currently online: %{active_runners_count}"
msgstr "当å‰åœ¨çº¿Runner: %{active_runners_count}"
-msgid "Runners page"
-msgstr "Runner页é¢"
-
msgid "Runners page."
msgstr "Runner页é¢."
@@ -17823,9 +18923,6 @@ msgstr "SSH密钥"
msgid "SSH Keys"
msgstr "SSH密钥"
-msgid "SSH Keys Help"
-msgstr "SSH密钥帮助"
-
msgid "SSH host key fingerprints"
msgstr "SSH主机密钥指纹"
@@ -17955,9 +19052,15 @@ msgstr "æœç´¢"
msgid "Search Button"
msgstr "æœç´¢æŒ‰é’®"
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr "æœç´¢çŽ¯å¢ƒè§„范"
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr "æœç´¢åˆ†æ”¯"
@@ -18015,6 +19118,9 @@ msgstr "æœç´¢é¡¹ç›®"
msgid "Search projects..."
msgstr "æœç´¢é¡¹ç›®..."
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr "æœç´¢ç”¨æˆ·"
@@ -18045,11 +19151,11 @@ msgstr "分é…给我的åˆå¹¶è¯·æ±‚"
msgid "SearchAutocomplete|in all GitLab"
msgstr "在整个 GitLab"
-msgid "SearchAutocomplete|in this group"
-msgstr "在此群组"
+msgid "SearchAutocomplete|in group %{groupName}"
+msgstr ""
-msgid "SearchAutocomplete|in this project"
-msgstr "在此项目"
+msgid "SearchAutocomplete|in project %{projectName}"
+msgstr ""
msgid "SearchCodeResults|in"
msgstr "于"
@@ -18127,9 +19233,15 @@ msgstr "当å‰æ­£åœ¨ä½¿ç”¨çš„用户数é‡"
msgid "Seats in license"
msgstr "许å¯è¯ç”¨æˆ·æ•°é‡"
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr "密ç "
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr "安全"
@@ -18142,9 +19254,6 @@ msgstr "安全é…ç½®"
msgid "Security Dashboard"
msgstr "安全仪表æ¿"
-msgid "Security configuration help link"
-msgstr "安全é…置帮助链接"
-
msgid "Security dashboard"
msgstr "安全仪表盘"
@@ -18154,24 +19263,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr "å·²é…ç½®"
-
-msgid "SecurityConfiguration|Feature"
-msgstr "功能"
+msgid "SecurityConfiguration|Enabled"
+msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
-msgstr "尚未é…ç½®"
+msgid "SecurityConfiguration|Not yet enabled"
+msgstr ""
-msgid "SecurityConfiguration|Secure features"
-msgstr "安全功能"
+msgid "SecurityConfiguration|Security Control"
+msgstr ""
msgid "SecurityConfiguration|Status"
msgstr "状æ€"
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18307,6 +19416,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18388,6 +19500,9 @@ msgstr "选择"
msgid "Select Archive Format"
msgstr "选择下载格å¼"
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr "选择GitLab项目连接你的Slack团队"
@@ -18439,12 +19554,18 @@ msgstr "选择全部"
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr "选择一个既有的Kubernetes集群或者创建一个新的"
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr "选择分支"
msgid "Select branch/tag"
msgstr "选择分支/标签"
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr "选择群组或项目"
@@ -18490,9 +19611,18 @@ msgstr ""
msgid "Select source branch"
msgstr "选择æºåˆ†æ”¯"
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr "选择目标分支"
@@ -18565,6 +19695,12 @@ msgstr "å‘é€ç¡®è®¤é‚®ä»¶"
msgid "Send email"
msgstr "å‘é€ç”µå­é‚®ä»¶"
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr "å‘é€æŠ¥å‘Š"
@@ -18730,6 +19866,9 @@ msgstr "设置截止日期"
msgid "Set instance-wide template repository"
msgstr "设置实例范围的模æ¿ä»“库"
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr "为Web终端设置最长会è¯æ—¶é—´ã€‚"
@@ -18766,6 +19905,9 @@ msgstr "设置到期日期为%{due_date}。"
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr "设置作业的过期时间。一旦逾期,作业将被归档并且ä¸èƒ½é‡è¯•ã€‚留空则永ä¸è¿‡æœŸã€‚必须设置为 1 天以上,例如: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>。"
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr "设置æ¯ä¸ªä½œä¸šçš„产物文件的最大大å°"
@@ -18850,6 +19992,9 @@ msgstr "设置目标分支为%{branch_name}。"
msgid "Sets the due date to %{due_date}."
msgstr "将截止日期设置为 %{due_date}。"
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr "将里程碑设置为 %{milestone_reference}。"
@@ -18860,7 +20005,7 @@ msgid "Sets weight to %{weight}."
msgstr "å°†æƒé‡è®¾ç½®ä¸º %{weight}。"
msgid "Settings"
-msgstr "用户设置"
+msgstr "设置"
msgid "Settings related to the use and experience of using GitLab's Package Registry."
msgstr ""
@@ -18868,8 +20013,8 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
-msgstr "严é‡ç¨‹åº¦: %{severity}"
+msgid "Severity"
+msgstr ""
msgid "Shards (%{shards})"
msgstr ""
@@ -18907,15 +20052,15 @@ msgstr "Sherlock事物"
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr "如果您一旦丢失手机或无法访问一次性密ç å¯†ä¿ï¼Œæ‚¨å¯ä»¥ä½¿ç”¨æ¢å¤ç æ¥é‡æ–°èŽ·å¾—您的å¸æˆ·è®¿é—®æƒé™ã€‚æ¯ä¸ªæ¢å¤ç ä»…å¯ä½¿ç”¨ä¸€æ¬¡ã€‚请将它们ä¿å­˜åœ¨å®‰å…¨çš„地方,å¦åˆ™ä¸¢å¤±åŽä½ %{b_start}å°†%{b_end}无法访问您的å¸æˆ·ã€‚"
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr "显示所有活动"
msgid "Show all members"
msgstr "显示所有æˆå‘˜"
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr "显示已归档的项目"
@@ -18940,12 +20085,21 @@ msgstr "显示完整的原始日志"
msgid "Show file browser"
msgstr "显示文件æµè§ˆå™¨"
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr "显示最新版本"
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr "åªæ˜¾ç¤ºç›´æŽ¥æˆå‘˜"
@@ -18965,6 +20119,13 @@ msgid "Showing %d event"
msgid_plural "Showing %d events"
msgstr[0] "显示 %d 个事件"
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr "显示%{total_count}个议题中的%{limit}项. "
@@ -19151,6 +20312,9 @@ msgstr "智能å¡èº«ä»½éªŒè¯å¤±è´¥ï¼šç¼ºå°‘客户端è¯ä¹¦æŠ¥å¤´ã€‚"
msgid "Snippets"
msgstr "代ç ç‰‡æ®µ"
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19187,9 +20351,15 @@ msgstr ""
msgid "Snowplow"
msgstr "Snowplow"
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr "æŸäº›ç”µå­é‚®ä»¶æœåŠ¡å™¨ä¸æ”¯æŒè¦†ç›–电å­é‚®ä»¶çš„å‘件人å称。å¯ç”¨æ­¤é€‰é¡¹å¯ä»¥åœ¨ç”µå­é‚®ä»¶æ­£æ–‡ä¸­åŒ…å«è®®é¢˜çš„作者姓åã€åˆå¹¶è¯·æ±‚或评论。"
@@ -19286,6 +20456,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr "获å–相关的åˆå¹¶è¯·æ±‚时出错了。"
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19325,6 +20498,9 @@ msgstr "解决当å‰è®¨è®ºæ—¶å‡ºé”™ï¼Œè¯·é‡è¯•ã€‚"
msgid "Something went wrong while stopping this environment. Please try again."
msgstr "åœæ­¢çŽ¯å¢ƒæ—¶å‡ºé”™ã€‚请é‡è¯•ã€‚"
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19373,6 +20549,12 @@ msgstr "排åº"
msgid "Sort direction"
msgstr "排åºæ–¹å‘"
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr "访问级别,å‡åºæŽ’列"
@@ -19490,6 +20672,9 @@ msgstr "最近星标"
msgid "SortOptions|Size"
msgstr "大å°"
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr "排åºæ–¹å‘"
@@ -19655,8 +20840,8 @@ msgstr "星标用户"
msgid "Stars"
msgstr "星标"
-msgid "Start GitLab Ultimate trial"
-msgstr "å¯åŠ¨GitLab Ultimate试用"
+msgid "Start Date"
+msgstr ""
msgid "Start Web Terminal"
msgstr "å¯åŠ¨Web终端"
@@ -19730,6 +20915,9 @@ msgstr "已开始 %{startsIn}"
msgid "Started asynchronous removal of all repository check states."
msgstr "已开始所有仓库检查状æ€çš„异步删除。"
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr "正在å¯åŠ¨..."
@@ -19856,6 +21044,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr "通过é…ç½®Prometheusæ¥ç›‘控你的部署,了解环境的性能和å¥åº·åº¦çš„最新状æ€ã€‚"
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr "åœæ­¢ç»ˆç«¯"
@@ -19883,6 +21074,9 @@ msgstr "存储:"
msgid "StorageSize|Unknown"
msgstr "未知"
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr "å­ç¾¤ç»„概览"
@@ -19910,6 +21104,9 @@ msgstr ""
msgid "Subkeys"
msgstr "å­å¯†é’¥"
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20090,9 +21287,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr "å¯ä»¥ä¸€é”®åº”用的建议代ç æ›´æ”¹åŠŸèƒ½ã€‚试试看ï¼"
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr "å˜æ›´å»ºè®®"
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr "亮绿色"
@@ -20177,6 +21380,9 @@ msgstr "对自定义è¯ä¹¦çš„支æŒå·²ç¦ç”¨ã€‚请è”系系统管ç†å‘˜æ¥å¯ç”¨
msgid "Support page URL"
msgstr "支æŒé¡µé¢ç½‘å€"
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr "切æ¢åˆ†æ”¯/标签"
@@ -20204,9 +21410,6 @@ msgstr "系统"
msgid "System Hooks"
msgstr "系统钩å­"
-msgid "System Hooks Help"
-msgstr "系统钩å­å¸®åŠ©"
-
msgid "System Info"
msgstr "系统信æ¯"
@@ -20457,6 +21660,9 @@ msgstr "测试"
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr "感谢您注册å…费试用版ï¼éšåŽæ‚¨å°†æ”¶åˆ°æœ‰å…³å®‰è£…使用指å—的邮件。"
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr "感谢您的报告。 GitLab管ç†å‘˜å°†å°½å¿«è¿›è¡Œè°ƒæŸ¥ã€‚"
@@ -20539,9 +21745,6 @@ msgstr "与该阶段相关的事件集åˆã€‚"
msgid "The commit does not exist"
msgstr "æ­¤æ交ä¸å­˜åœ¨"
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr "下表的é…置状æ€ä»…适用于默认分支,并且基于%{linkStart}最新的æµæ°´çº¿%{linkEnd}。为默认分支é…置了扫æåŽï¼Œæ‚¨åˆ›å»ºçš„所有åŽç»­åŠŸèƒ½åˆ†æ”¯éƒ½å°†åŒ…å«è¯¥æ‰«æ。"
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr "该连接将在 %{timeout}åŽè¶…时。如仓库导入耗时超过该时间,请使用克隆/推é€ç»„åˆã€‚"
@@ -20578,9 +21781,15 @@ msgstr "您输入的域åæ ¼å¼é”™è¯¯ã€‚"
msgid "The domain you entered is not allowed."
msgstr "您输入的域åä¸è¢«å…许。"
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr "输入的用户映射ä¸æ˜¯æœ‰æ•ˆçš„JSON用户映射。"
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr "文件已æˆåŠŸåˆ›å»ºã€‚"
@@ -20618,6 +21827,9 @@ msgstr "群组åŠå…¶é¡¹ç›®åªèƒ½ç”±æˆå‘˜æŸ¥çœ‹ã€‚"
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr "该群组已与此群组共享"
@@ -20792,6 +22004,9 @@ msgstr "指定标签页无效,请选择å¦ä¸€ä¸ª"
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr "预å‘布阶段概述了从åˆå¹¶è¯·æ±‚被åˆå¹¶åˆ°éƒ¨ç½²è‡³ç”Ÿäº§çŽ¯å¢ƒçš„总时间。首次部署到生产环境åŽï¼Œæ•°æ®å°†è‡ªåŠ¨æ·»åŠ åˆ°æ­¤å¤„。"
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr "测试阶段概述了 GitLab CI 为相关åˆå¹¶è¯·æ±‚è¿è¡Œæ¯ä¸ªæµæ°´çº¿æ‰€éœ€çš„时间。当第一个æµæ°´çº¿è¿è¡Œå®ŒæˆåŽï¼Œæ•°æ®å°†è‡ªåŠ¨æ·»åŠ åˆ°æ­¤å¤„。"
@@ -20840,6 +22055,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr "没有与此账户关è”çš„GPG密钥。"
@@ -20915,6 +22133,15 @@ msgstr "没有å¯ç”¨æ•°æ®ã€‚请更改选择。"
msgid "There was a problem communicating with your device."
msgstr "与您的设备通信时出现问题。"
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -20987,6 +22214,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr "加载用户活动日历时出错。"
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr "删除电å­é‚®ä»¶æ—¶å‡ºé”™ã€‚"
@@ -21050,6 +22280,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr "reCAPTCHA 验è¯é”™è¯¯ã€‚请å†æ¬¡éªŒè¯ reCAPTCHA。"
@@ -21134,6 +22367,9 @@ msgstr "æ­¤æ交已使用ç»è¿‡éªŒè¯çš„ç­¾å进行签å,但<strong>未验è
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr "æ­¤æ交使用 <strong>未ç»éªŒè¯çš„</strong> ç­¾å进行签å。"
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr "此日期在截止日期之åŽï¼Œå› æ­¤è¯¥ å²è¯— ä¸ä¼šå‡ºçŽ°åœ¨è·¯çº¿å›¾ä¸­ã€‚"
@@ -21173,6 +22409,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr "æ­¤å²è¯—çš„å­å²è¯—数目已达最大值。"
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr "æ­¤å²è¯—ä¸å­˜åœ¨æˆ–者您没有足够的æƒé™ã€‚"
@@ -21207,7 +22446,7 @@ msgid "This is a \"Ghost User\", created to hold all issues authored by users th
msgstr "此用户为“幽çµç”¨æˆ·â€ï¼Œç”¨äºŽæŒæœ‰è¢«åˆ é™¤ç”¨æˆ·çš„所有议题。该用户无法被删除。"
msgid "This is a Work in Progress"
-msgstr "这是一个正在进行中的工作"
+msgstr "当å‰å¤„于工作进行中"
msgid "This is a confidential issue."
msgstr "当å‰è®®é¢˜ä¸ºç§å¯†è®®é¢˜ã€‚"
@@ -21218,9 +22457,6 @@ msgstr "这是一个将在%{remainingTime}åŽè¿è¡Œçš„延时作业。"
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr "这是已登录到您å¸æˆ·çš„设备列表。您å¯ä»¥åˆ é™¤ä»»ä½•æ‚¨æ— æ³•è¯†åˆ«çš„会è¯ã€‚"
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr "这是一个涉åŠæ‚¨çš„å¸æˆ·é‡è¦äº‹ä»¶çš„安全日志。"
@@ -21332,8 +22568,8 @@ msgstr "此作业正在处ç†ä½œä¸šå¯åŠ¨å‰å¿…须完æˆçš„任务"
msgid "This job is preparing to start"
msgstr "此作业正准备开始"
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
-msgstr "此作业已阻塞,因为您未分é…任何具有这些标签的å¯ç”¨Runner:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
+msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
msgstr "由于您没有任何å¯ä»¥è¿è¡Œæ­¤ä½œä¸šçš„å¯ç”¨Runner,因此作业阻塞了。"
@@ -21359,6 +22595,9 @@ msgstr "æ­¤æ“作å¯èƒ½ä¼šæ³„æ¼æœºå¯†ä¿¡æ¯ï¼Œå› ä¸ºé€‰å®šçš„派生ä½äºŽå¦ä¸€
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr "在创建一个空的仓库或导入现有仓库之å‰ï¼Œå°†æ— æ³•æŽ¨é€ä»£ç ã€‚"
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr "æ­¤åˆå¹¶è¯·æ±‚å·²é”定。"
@@ -21395,12 +22634,18 @@ msgstr "当å‰é¡¹ç›®"
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr "该项目ä¸å±žäºŽä»»ä½•ç¾¤ç»„,因此ä¸èƒ½ä½¿ç”¨ç¾¤ç»„Runner。"
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr "该项目尚无wiki主页"
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr "此项目未å¯ç”¨è´¦å•ã€‚è¦åˆ›å»ºç¾¤é›†ï¼Œè¯· <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">å¯ç”¨è´¦å• <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> 并é‡è¯•ã€‚"
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr "此项目已存档,无法添加评论。"
@@ -21413,12 +22658,24 @@ msgstr "此项目将于%{date}被删除"
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr "当å‰ä»“库"
+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 "此仓库目å‰ä¸ºç©ºã€‚将新文件推é€åˆ°åˆ†æ”¯åŽï¼Œå°†åˆ›å»ºæ–°çš„Auto DevOpsæµæ°´çº¿ã€‚"
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr "æ­¤Runner仅在å—ä¿æŠ¤åˆ†æ”¯ä¸Šè§¦å‘çš„æµæ°´çº¿ä¸Šè¿è¡Œ"
@@ -21437,8 +22694,8 @@ msgstr "当低于项目定义的超时时,此超时将优先,并å¯æŽ¥å—英
msgid "This user cannot be unlocked manually from GitLab"
msgstr "无法从GitLab手动解ç¦æ­¤ç”¨æˆ·"
-msgid "This user has no active %{type} Tokens."
-msgstr "此用户没有活动的%{type}令牌。"
+msgid "This user has no active %{type}."
+msgstr ""
msgid "This user has no identities"
msgstr "该用户无身份标识"
@@ -21446,9 +22703,6 @@ msgstr "该用户无身份标识"
msgid "This 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 "此用户将æˆä¸ºæ´»åŠ¨æµä¸­æ‰€æœ‰äº‹ä»¶çš„作者,例如创建新分支或者推é€æ–°æ交到现有分支。"
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr "此用户将æˆä¸ºæ´»åŠ¨æµä¸­æ‰€æœ‰äº‹ä»¶çš„作者,例如创建新分支或者推é€æ–°æ交到现有分支。在创建或é‡æ–°æŒ‡å®šæ—¶æ‚¨ä»…å¯å°†è‡ªå·±æŒ‡å®šä¸ºé•œåƒç”¨æˆ·ã€‚"
-
msgid "This variable can not be masked."
msgstr ""
@@ -21503,9 +22757,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr "请求"
@@ -21752,6 +23012,9 @@ msgstr "ç«‹å³"
msgid "Timeout"
msgstr "超时"
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] "å°æ—¶"
@@ -21814,6 +23077,12 @@ msgstr "è¦å®šä¹‰å†…部用户,请首先å¯ç”¨è®¾ç½®ä¸ºå¤–部的新用户"
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr "è¦å¯ç”¨å®ƒå¹¶æŸ¥çœ‹ç”¨æˆ·ä¸–代表,请访问 %{application_settings_link_start}应用程åºè®¾ç½®%{application_settings_link_end}。"
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 "首先请在下é¢è¾“入您的FogBugz URL和登录信æ¯ã€‚下一步,您将å¯ä»¥æ˜ å°„用户并选择è¦å¯¼å…¥çš„项目。"
@@ -21934,6 +23203,9 @@ msgstr "开关æ交æè¿°"
msgid "Toggle commit list"
msgstr "开关æ交列表"
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr "切æ¢è¡¨æƒ…符å·èµžèµ"
@@ -21991,15 +23263,9 @@ msgstr "贡献总计"
msgid "Total artifacts size: %{total_size}"
msgstr "所有产物大å°ï¼š %{total_size}"
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr "总议题数"
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr "所有æ交和åˆå¹¶çš„总测试时间"
@@ -22015,9 +23281,6 @@ msgstr "跟踪"
msgid "Tracing"
msgstr "跟踪"
-msgid "Track activity with Contribution Analytics."
-msgstr "通过贡献度分æžäº†è§£ç”¨æˆ·æ´»è·ƒåº¦ã€‚"
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr "在ä¸åŒé¡¹ç›®å’Œé‡Œç¨‹ç¢‘中跟踪具有åŒä¸€ä¸»é¢˜çš„议题组"
@@ -22036,6 +23299,9 @@ msgstr ""
msgid "Transfer project"
msgstr "转移项目"
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 "无法更新路径。因为此群组下的项目包å«äº†å®¹å™¨é•œåƒåº“çš„Dockeré•œåƒã€‚请先从您的项目中删除镜åƒåŽé‡è¯•ã€‚"
@@ -22147,6 +23413,9 @@ msgstr ""
msgid "Try to fork again"
msgstr "å°è¯•å†æ¬¡æ´¾ç”Ÿ"
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr "å°è¯•ä½¿ç”¨ä¸åŒçš„æœç´¢è¯æŸ¥æ‰¾ä½ æƒ³è¦çš„文件。"
@@ -22204,10 +23473,10 @@ msgstr "URL"
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22216,6 +23485,9 @@ msgstr "外部存储网å€å°†å­˜å‚¨ä»“库的é™æ€å¯¹è±¡ (例如,档案,åšå
msgid "URL or request ID"
msgstr "URL或请求ID"
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr "无法将建议应用于已删除的行。"
@@ -22255,6 +23527,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr "无法生æˆæ–°çš„实例 ID"
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22264,9 +23539,15 @@ msgstr "无法加载差异。 %{button_try_again}"
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr "无法加载åˆå¹¶è¯·æ±‚部件。请å°è¯•é‡æ–°åŠ è½½é¡µé¢ã€‚"
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr "无法解决"
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr "无法ä¿å­˜æ‚¨çš„更改。请é‡è¯•ã€‚"
@@ -22516,18 +23797,12 @@ msgstr "更新中"
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr "å‡çº§åˆ°å¯ä½¿ç”¨é‡‘ä¸é›€éƒ¨ç½²åŠŸèƒ½çš„方案"
-msgid "Upgrade your plan"
-msgstr "å‡çº§æ‚¨çš„订阅计划"
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr "å‡çº§æ‚¨çš„订阅计划以å¯ç”¨é«˜çº§å…¨å±€æœç´¢ã€‚"
msgid "Upgrade your plan to activate Audit Events."
msgstr "å‡çº§æ‚¨çš„订阅计划以激活审计事件。"
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr "å‡çº§æ‚¨çš„订阅计划以å¯ç”¨è´¡çŒ®åº¦åˆ†æžã€‚"
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr "å‡çº§æ‚¨çš„订阅计划以å¯ç”¨ç¾¤ç»„Webhook。"
@@ -22546,6 +23821,9 @@ msgstr "上传CSV文件"
msgid "Upload New File"
msgstr "上传新文件"
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr "通过存储介质上传您的域åè¯ä¹¦"
@@ -22564,6 +23842,9 @@ msgstr "点击上传"
msgid "Uploaded on"
msgstr "上传于"
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr "正在将å˜æ›´å†…容上传到终端"
@@ -22588,9 +23869,6 @@ msgstr "使用情况"
msgid "Usage ping is not enabled"
msgstr "使用情况检测(usage ping)未å¯ç”¨"
-msgid "Usage quotas help link"
-msgstr "使用é…é¢å¸®åŠ©é“¾æŽ¥"
-
msgid "Usage statistics"
msgstr "使用情况统计"
@@ -22600,12 +23878,18 @@ msgstr "%{help_link_start}共享Runner%{help_link_end}å·²ç¦ç”¨ï¼Œæ‰€ä»¥æµæ°´çº
msgid "UsageQuota|Artifacts"
msgstr "产物"
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr "è´­ä¹°é¢å¤–分钟数"
msgid "UsageQuota|Current period usage"
msgstr "当å‰å‘¨æœŸä½¿ç”¨é‡"
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr "LFS存储"
@@ -22615,12 +23899,18 @@ msgstr "软件包"
msgid "UsageQuota|Pipelines"
msgstr "æµæ°´çº¿"
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr "仓库"
msgid "UsageQuota|Storage"
msgstr "存储"
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr "此命å空间没有使用共享Runner的项目"
@@ -22639,12 +23929,18 @@ msgstr "%{strong_start}%{group_name}%{strong_end}群组中的项目使用群组è
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr "使用é‡è‡ª"
msgid "UsageQuota|Wiki"
msgstr "Wiki"
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr "使用 %{code_start}::%{code_end} 创建 %{link_start}有范围标签集%{link_end} (例如 %{code_start}priority::1%{code_end})"
@@ -22669,7 +23965,7 @@ msgstr "使用群组里程碑å¯ä»¥ç»Ÿä¸€ç®¡ç†å¤šä¸ªé¡¹ç›®ä¸­åŒä¸€é‡Œç¨‹ç¢‘çš„
msgid "Use hashed storage"
msgstr "使用哈希存储"
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22744,9 +24040,6 @@ msgstr "用户æµæ°´çº¿åˆ†é’Ÿæ•°å·²æˆåŠŸé‡ç½®ã€‚"
msgid "User restrictions"
msgstr "用户é™åˆ¶"
-msgid "User settings"
-msgstr "用户设置"
-
msgid "User was successfully created."
msgstr "用户已æˆåŠŸåˆ›å»ºã€‚"
@@ -22993,6 +24286,12 @@ msgstr "您还没有创建任何代ç ç‰‡æ®µ"
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr "您的项目å¯ä»¥æ ¹æ®æ‚¨çš„选择公开ã€å†…部或ç§ä¸‹æ供。"
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr "用户å (å¯é€‰)"
@@ -23053,6 +24352,9 @@ msgstr "使用 %{code_start}::%{code_end} 表示 %{link_start}范围标签集%{l
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr "当缺少加密字段时,使用必è¦çš„加密策略ï¼"
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr "验è¯"
@@ -23080,7 +24382,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23122,6 +24427,9 @@ msgstr "验è¯é…ç½®"
msgid "Version"
msgstr "版本"
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr "很有帮助"
@@ -23166,6 +24474,9 @@ msgstr[0] "查看%d项展示产物"
msgid "View file @ "
msgstr "æµè§ˆæ–‡ä»¶ @ "
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr "查看完整仪表æ¿"
@@ -23229,6 +24540,9 @@ msgstr "查看此环境最新æˆåŠŸéƒ¨ç½²"
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr "查看æ交"
@@ -23310,9 +24624,6 @@ msgstr "æ¼æ´ž"
msgid "Vulnerabilities over time"
msgstr "æ¼æ´žè¶‹åŠ¿å›¾"
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23343,9 +24654,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23454,6 +24762,9 @@ msgstr "WIP"
msgid "Wait for the file to load to copy its contents"
msgstr "等待文件加载以å¤åˆ¶å…¶å†…容"
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr "等待性能数æ®"
@@ -23466,6 +24777,9 @@ msgstr "警告:"
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr "我们无法确定删除å²è¯—的路径"
@@ -23487,8 +24801,14 @@ msgstr "该阶段的数æ®ä¸è¶³ï¼Œæ— æ³•æ˜¾ç¤ºã€‚"
msgid "We have found the following errors:"
msgstr "我们å‘现以下错误:"
-msgid "We heard back from your U2F device. You have been authenticated."
-msgstr "我们从您的U2F设备收到了回å¤ã€‚您已通过身份验è¯ã€‚"
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
+msgstr ""
msgid "We sent you an email with reset password instructions"
msgstr "我们å‘é€äº†ä¸€å°å¸¦æœ‰é‡ç½®å¯†ç ä¿¡æ¯çš„电å­é‚®ä»¶"
@@ -23529,9 +24849,6 @@ msgstr ""
msgid "Webhooks"
msgstr "Webhooks"
-msgid "Webhooks Help"
-msgstr "Webhooks帮助"
-
msgid "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 "如果有新的推é€æˆ–新的议题,Webhook将自动触å‘您设置URL。 您å¯ä»¥é…ç½® Webhook æ¥ç›‘å¬ç‰¹å®šäº‹ä»¶ï¼Œå¦‚推é€ã€è®®é¢˜æˆ–åˆå¹¶è¯·æ±‚。 群组 Webhook 适用于群组中的所有项目,便于您在整个群组中标准化webhook功能。"
@@ -23571,12 +24888,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr "欢迎æ¥åˆ°Guided GitLab Tour"
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr "欢迎使用议题看æ¿"
msgid "What are you searching for?"
msgstr "您正在æœç´¢ä»€ä¹ˆï¼Ÿ"
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23611,9 +24937,6 @@ msgstr "虽然没有å‘现æ¼æ´žï¼Œè¿™ç§çŽ°è±¡å¾ˆç½•è§ï¼Œä½†ä¹Ÿæ˜¯æœ‰å¯èƒ½çš„
msgid "White helpers give contextual information."
msgstr "白色助手给出了上下文信æ¯ã€‚"
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr "白åå•ä»¥å…许æ¥è‡ªé’©å­å’ŒæœåŠ¡çš„对本地网络的请求。"
-
msgid "Who can be an approver?"
msgstr "è°å¯ä»¥æ˜¯å®¡æ ¸è€…?"
@@ -23647,9 +24970,6 @@ msgstr "Git 访问"
msgid "WikiClone|Install Gollum"
msgstr "安装 Gollum"
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr "建议安装 %{markdown},以便 GFM 功能在本地渲染:"
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr "å¯åŠ¨ Gollum 并在本地编辑"
@@ -23770,11 +25090,14 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr "Wiki 页é¢"
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr "将部署到"
-msgid "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 "通过贡献度分æžï¼Œæ‚¨å¯ä»¥ä»Žæ€»ä½“上了解您的组织åŠå…¶æˆå‘˜çš„议题〠åˆå¹¶è¯·æ±‚和推é€æ´»åŠ¨çš„情况。"
+msgid "With requirements, you can set criteria to check your products against."
+msgstr ""
msgid "Withdraw Access Request"
msgstr "å–消æƒé™ç”³è¯·"
@@ -23782,11 +25105,11 @@ msgstr "å–消æƒé™ç”³è¯·"
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
-msgstr "工作æµå¸®åŠ©"
+msgid "Work in progress Limit"
+msgstr ""
msgid "Write"
msgstr "编辑"
@@ -23902,6 +25225,9 @@ msgstr "您å¯ä»¥åœ¨ %{lint_link_start}CI Lint%{lint_link_end} 中测试 %{gitla
msgid "You can also upload existing files from your computer using the instructions below."
msgstr "您还å¯ä»¥æŒ‰ç…§ä»¥ä¸‹è¯´æ˜Žä»Žè®¡ç®—机中上传现有文件。"
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -23929,6 +25255,9 @@ msgstr "å¯ä»¥è½»æ¾åœ°åœ¨Kubernetes集群上安装Runner。 %{link_to_help_page
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr "您å¯ä»¥é€šè¿‡å•å‡»å›¾è¡¨ä¸­çš„列æ¥æŒ‰â€œåˆå¹¶å¤©æ•°â€è¿›è¡Œè¿‡æ»¤ã€‚"
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -23944,6 +25273,9 @@ msgstr "您å¯ä»¥é‚€è¯·å¦ä¸€ä¸ªç¾¤ç»„加入<strong>%{project_name}</strong>。"
msgid "You can move around the graph by using the arrow keys."
msgstr "å¯ä»¥ä½¿ç”¨æ–¹å‘键移动图形。"
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24022,6 +25354,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr "您当å‰å°šæœªè®¢é˜…任何计划"
@@ -24070,6 +25405,9 @@ msgstr "您没有访问此群组效率分æžçš„æƒé™"
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr "你已被授予 %{access_level} 访问 %{source_link} %{source_type} çš„æƒé™ã€‚"
@@ -24085,7 +25423,7 @@ msgstr "您已å–消订阅该主题。"
msgid "You have declined the invitation to join %{label}."
msgstr "您已拒ç»åŠ å…¥%{label}的邀请。"
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24178,6 +25516,9 @@ msgstr "您å°è¯•æ´¾ç”Ÿ %{link_to_the_project} 但由于以下原因导致失败
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24205,6 +25546,9 @@ msgstr "接收所有活动的通知"
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr "åªæŽ¥æ”¶è¯„论中æåŠ(@)您的通知"
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr "在账å·ä¸­ %{set_password_link} 之å‰å°†æ— æ³•é€šè¿‡ %{protocol} 拉å–或推é€ä»£ç ã€‚"
@@ -24223,6 +25567,12 @@ msgstr "ä½ å°†è¦é™ä½Ž%{strong_start}%{group_name}%{strong_end}中%{strong_star
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr "ä½ å°†è¦é™ä½Žé¡¹ç›® %{strong_start}%{project_name}%{strong_end}çš„å¯è§æ€§ã€‚"
+msgid "You're at the first commit"
+msgstr ""
+
+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 "您无æƒç›´æŽ¥%{tag_start}编辑%{tag_end}这个项目的文件。请派生这个项目,并在派生中进行更改,然åŽæ交åˆå¹¶è¯·æ±‚。"
@@ -24256,7 +25606,10 @@ msgstr "您已ç»ä½¿ç”¨ä¸€æ¬¡å¯†ç éªŒè¯å™¨å¯ç”¨äº†åŒé‡è®¤è¯ã€‚如果您è¦
msgid "YouTube"
msgstr "YouTube"
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24292,8 +25645,8 @@ msgstr "您的Gitlab金牌试用的有效期为30天,之åŽæ‚¨å¯ä»¥æ°¸ä¹…ä¿ç
msgid "Your Groups"
msgstr "您的群组"
-msgid "Your New Personal Access Token"
-msgstr "您的新个人访问令牌"
+msgid "Your License"
+msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
msgstr "您的个人访问令牌将在%{days_to_expire}天内过期。"
@@ -24385,9 +25738,18 @@ msgstr "您的部署æœåŠ¡å°†å¤±æ•ˆï¼Œéœ€è¦åœ¨é‡å‘½ååŽæ‰‹åŠ¨ä¿®å¤æœåŠ¡ã€‚
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr "您的设备已æˆåŠŸè®¾ç½®ï¼è¯·ç»™å®ƒå‘½å并将其注册到GitLabæœåŠ¡å™¨ã€‚"
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr "您的群组"
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr "您的议题正在导入。完æˆåŽï¼Œæ‚¨å°†æ”¶åˆ°ä¸€å°ç¡®è®¤ç”µå­é‚®ä»¶ã€‚"
@@ -24397,12 +25759,18 @@ msgstr "您的议题将在åŽå°å¯¼å…¥ã€‚完æˆåŽï¼Œæ‚¨å°†æ”¶åˆ°ä¸€å°ç¡®è®¤ç”µ
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr "您的消æ¯æ˜¾ç¤ºäºŽæ­¤"
msgid "Your name"
msgstr "您的åå­—"
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr "您的新 SCIM 令牌"
@@ -24427,9 +25795,15 @@ msgstr "您的被é™åˆ¶ä¸ºæœ€å¤§ %{limit} 个项目ï¼è¯·ä¸Žæ‚¨çš„管ç†å‘˜è”ç³
msgid "Your projects"
msgstr "您的项目"
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr "您的访问请求已进入审核队列。"
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24476,6 +25850,9 @@ msgstr "添加Zoom通è¯åˆ°æ­¤è®®é¢˜"
msgid "ago"
msgstr "å‰"
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr "å…许失败"
@@ -24518,6 +25895,9 @@ msgstr "阻止"
msgid "branch name"
msgstr "分支å称"
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr "æ¥è‡ª"
@@ -24682,6 +26062,9 @@ msgstr "动æ€åº”用程åºå®‰å…¨æµ‹è¯•ï¼ˆDAST)å¯æ£€æµ‹Web应用程åºä¸­çš„å·
msgid "ciReport|Failed to load %{reportName} report"
msgstr "无法加载 %{reportName} 报告"
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr "已修å¤:"
@@ -24700,6 +26083,9 @@ msgstr "载入%{reportName} 报告"
msgid "ciReport|Manage licenses"
msgstr "管ç†è®¸å¯è¯"
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr "代ç è´¨é‡æ— å˜åŒ–"
@@ -24718,6 +26104,9 @@ msgstr "通过åˆå¹¶è¯·æ±‚解决"
msgid "ciReport|SAST"
msgstr "SAST"
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24758,6 +26147,9 @@ msgstr[0] "已用于 %{packagesString} 和 %{lastPackage}"
msgid "ciReport|View full report"
msgstr "查看完整报告"
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr "评论"
@@ -24767,6 +26159,9 @@ msgstr "评论 %{link_to_project}"
msgid "commit %{commit_id}"
msgstr "æ交 %{commit_id}"
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr "å³å°†å…³é—­ç§å¯†æ€§ã€‚这将使得 <strong>所有用户</strong>都å¯ä»¥æŸ¥çœ‹å¹¶ä¸”评论当å‰è®®é¢˜ã€‚"
@@ -24776,6 +26171,9 @@ msgstr "å³å°†è®¾ç½®ç§å¯†æ€§ã€‚这将使得 <strong>至少有Reporter以上æƒé
msgid "connecting"
msgstr "连接中"
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr "container_nameä¸èƒ½è¶…过%{max_length}个字符"
@@ -24825,6 +26223,9 @@ msgstr "当å‰æ‰©å±•åä¸æ”¯æŒã€‚åªæ”¯æŒ%{extension_list}"
msgid "done"
msgstr "完æˆ"
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] "è‰ç¨¿"
@@ -24835,8 +26236,11 @@ msgstr "例如, %{token}"
msgid "element is not a hierarchy"
msgstr "此元素并éžç¾¤ç»„层级"
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
-msgstr "电å­é‚®ä»¶â€œ%{email}â€ä¸Žå…许的域å“%{email_domain}â€ä¸åŒ¹é…"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
+msgstr ""
msgid "enabled"
msgstr "å·²å¯ç”¨"
@@ -24868,11 +26272,11 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
-msgstr "过期于 %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
+msgstr ""
-msgid "expires on %{milestone_due_date}"
-msgstr "过期于 %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
+msgstr ""
msgid "external_url"
msgstr ""
@@ -24935,9 +26339,18 @@ msgstr "此处"
msgid "https://your-bitbucket-server"
msgstr "https://your-bitbucket-server"
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr "图åƒå·®å¼‚"
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr "导入æµç¨‹"
@@ -24999,6 +26412,9 @@ msgstr "ä¸æ˜¯æ‚¨è‡ªå·±çš„电å­é‚®ä»¶"
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr "太长(%{current_value})。最大值为%{max_size}。"
@@ -25020,6 +26436,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr "它是外部存储的"
@@ -25059,6 +26481,9 @@ msgstr "等级: %{level}"
msgid "limit of %{project_limit} reached"
msgstr "已达到%{project_limit}çš„é™åˆ¶"
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr "被 %{path_lock_user_name} 在 %{created_at} é”定"
@@ -25186,7 +26611,7 @@ msgstr "删除æºåˆ†æ”¯"
msgid "mrWidget|Deployment statistics are not available currently"
msgstr "部署统计信æ¯å½“å‰ä¸å¯ç”¨"
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25366,9 +26791,6 @@ msgstr "æ­¤åˆå¹¶è¯·æ±‚å¯ä»¥æ‰‹åŠ¨åˆå¹¶ï¼Œè¯·ä½¿ç”¨ä»¥ä¸‹"
msgid "mrWidget|Your password"
msgstr "您的密ç "
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr "分支ä¸å­˜åœ¨"
@@ -25378,15 +26800,6 @@ msgstr "命令行"
msgid "mrWidget|into"
msgstr "å…¥"
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr "æµæ°´çº¿æˆåŠŸæ—¶æ·»åŠ åˆ°åˆå¹¶é˜Ÿåˆ—"
@@ -25399,6 +26812,9 @@ msgstr "æµæ°´çº¿æˆåŠŸæ—¶å¯åŠ¨åˆå¹¶é˜Ÿåˆ—"
msgid "must be greater than start date"
msgstr "必须大于开始日期"
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr "ä¸é€‚用"
@@ -25444,6 +26860,9 @@ msgstr "%{item},和 %{lastItem}"
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr "%{user}å¼€å¯äºŽ%{timeAgoString}"
@@ -25473,9 +26892,18 @@ msgstr "等待中的移除"
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr "æµæ°´çº¿"
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr "pod_nameä¸èƒ½å¤§äºŽ%{max_length}个字符"
@@ -25496,6 +26924,12 @@ msgid "project"
msgid_plural "projects"
msgstr[0] "项目"
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr "项目头åƒ"
@@ -25545,6 +26979,9 @@ msgstr "é‡ç½®å®ƒã€‚"
msgid "resolved the corresponding error and closed the issue."
msgstr "解决了相应的错误并关闭了该议题。"
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr "分"
@@ -25611,11 +27048,11 @@ msgstr "已开始"
msgid "started a discussion on %{design_link}"
msgstr "开始讨论%{design_link}"
-msgid "started on %{milestone_start_date}"
-msgstr "开始于 %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
+msgstr ""
-msgid "starts on %{milestone_start_date}"
-msgstr "开始于 %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
+msgstr ""
msgid "stuck"
msgstr "阻塞"
@@ -25669,7 +27106,7 @@ msgid "unicode domains should use IDNA encoding"
msgstr "unicode域å应使用IDNAç¼–ç "
msgid "updated"
-msgstr "已更新"
+msgstr "更新于"
msgid "updated %{timeAgo}"
msgstr ""
@@ -25677,6 +27114,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr "更新于%{time_ago}"
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr "用户头åƒ"
@@ -25704,6 +27147,9 @@ msgstr "使用GitLab查看"
msgid "view the blob"
msgstr "查看blob"
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25731,6 +27177,9 @@ msgstr "已忽略"
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr "å…± %{additions} æ¡æ–°å¢ž, %{deletions} æ¡åˆ é™¤."
diff --git a/locale/zh_HK/gitlab.po b/locale/zh_HK/gitlab.po
index bcf3a220dea..2d0e8b52885 100644
--- a/locale/zh_HK/gitlab.po
+++ b/locale/zh_HK/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: zh-HK\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:32\n"
+"PO-Revision-Date: 2020-06-08 15:12\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -71,6 +71,14 @@ msgid "%d URL scanned"
msgid_plural "%d URLs scanned"
msgstr[0] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -87,6 +95,10 @@ msgid "%d comment"
msgid_plural "%d comments"
msgstr[0] "%d 則留言"
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] "%d 個æ交"
@@ -106,6 +118,10 @@ msgid "%d contribution"
msgid_plural "%d contributions"
msgstr[0] ""
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -162,6 +178,10 @@ msgid "%d more comment"
msgid_plural "%d more comments"
msgstr[0] ""
+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] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] ""
@@ -186,6 +206,14 @@ msgid "%d unresolved thread"
msgid_plural "%d unresolved threads"
msgstr[0] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -206,6 +234,9 @@ msgstr "ç”± %{commit_author_link} æ交於 %{commit_timeago}"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -279,6 +310,9 @@ msgstr "已刪除 %{filePath}"
msgid "%{firstLabel} +%{labelCount} more"
msgstr "%{firstLabel} +%{labelCount} 更多"
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr ""
@@ -288,6 +322,9 @@ msgstr "%{group_docs_link_start}群組%{group_docs_link_end}å…許您管ç†ã€å
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr ""
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr ""
@@ -300,6 +337,30 @@ msgstr ""
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr ""
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr ""
@@ -333,12 +394,21 @@ msgstr "%{loadingIcon} 開始"
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr "%{lock_path} 被使用者 %{lock_user_id} 鎖定"
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr ""
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -354,6 +424,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr "%{name} çš„é ­åƒ"
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -392,6 +468,12 @@ msgid "%{releases} release"
msgid_plural "%{releases} releases"
msgstr[0] ""
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -533,6 +615,9 @@ msgid "(%d closed)"
msgid_plural "(%d closed)"
msgstr[0] ""
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr ""
@@ -719,6 +804,9 @@ msgstr "404 |如果您èªç‚ºé€™æ˜¯éŒ¯èª¤ï¼Œè«‹è¯ç¹«æ‚¨çš„GitLab管ç†å“¡ã€‚"
msgid "8 hours"
msgstr "8 å°æ™‚"
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr ""
@@ -749,6 +837,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr "<strong>%{group_name}</strong> 群組æˆå“¡"
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr "<strong>刪除</strong>來æºåˆ†æ”¯"
@@ -758,6 +849,9 @@ msgstr ""
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ""
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr ""
@@ -794,7 +888,10 @@ msgstr ""
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr ""
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -845,6 +942,9 @@ msgstr ""
msgid "A secure token that identifies an external storage request."
msgstr ""
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -857,9 +957,6 @@ msgstr "一個有存å–原始分支權é™çš„使用者,é¸æ“‡äº†æ­¤é …ç›®"
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr ""
-
msgid "API Token"
msgstr ""
@@ -905,9 +1002,6 @@ msgstr "接å—æ¢æ¬¾"
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr ""
-
msgid "Access Tokens"
msgstr "å­˜å–憑證 (access token)"
@@ -998,12 +1092,6 @@ msgstr ""
msgid "AccessTokens|reset it"
msgstr ""
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1040,7 +1128,7 @@ msgstr ""
msgid "Active"
msgstr "啟用"
-msgid "Active %{type} Tokens (%{token_length})"
+msgid "Active %{type} (%{token_length})"
msgstr ""
msgid "Active Sessions"
@@ -1049,6 +1137,9 @@ msgstr ""
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr "活動"
@@ -1092,7 +1183,7 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr ""
-msgid "Add a %{type} token"
+msgid "Add a %{type}"
msgstr ""
msgid "Add a GPG key"
@@ -1107,6 +1198,9 @@ msgstr ""
msgid "Add a bullet list"
msgstr ""
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr ""
@@ -1116,9 +1210,15 @@ msgstr "å° %{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 ""
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr "新增連çµ"
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr ""
@@ -1134,7 +1234,10 @@ msgstr ""
msgid "Add an SSH key"
msgstr ""
-msgid "Add an existing issue to the epic."
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
msgstr ""
msgid "Add an issue"
@@ -1200,6 +1303,9 @@ msgstr ""
msgid "Add request manually"
msgstr ""
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr ""
@@ -1290,18 +1396,18 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
-msgid "Adjust your filters/search criteria above."
+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 ""
msgid "Admin Area"
msgstr "管ç†å€åŸŸ"
+msgid "Admin Note"
+msgstr ""
+
msgid "Admin Overview"
msgstr "管ç†ç¸½è¦½"
-msgid "Admin Section"
-msgstr ""
-
msgid "Admin mode already enabled"
msgstr ""
@@ -1626,62 +1732,116 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] "æ示"
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Info"
+msgstr ""
+
+msgid "AlertManagement|Low"
+msgstr ""
+
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1690,16 +1850,34 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
+msgstr ""
+
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr ""
msgid "Alerts"
@@ -1873,6 +2051,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr ""
+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 ""
@@ -2038,9 +2219,6 @@ msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr "載入上交簽署時發生錯誤"
@@ -2062,6 +2240,9 @@ msgstr ""
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2137,6 +2318,9 @@ msgstr ""
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr ""
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr "訂閱通知時出錯"
@@ -2173,9 +2357,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr ""
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -2191,6 +2381,9 @@ msgstr ""
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr ""
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr ""
@@ -2200,6 +2393,9 @@ msgstr ""
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2224,12 +2420,6 @@ msgstr ""
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2239,9 +2429,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2305,6 +2501,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2369,12 +2568,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr "批准"
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr ""
@@ -2384,12 +2577,18 @@ msgstr ""
msgid "Approve the current merge request."
msgstr ""
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr ""
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr ""
@@ -2498,6 +2697,9 @@ msgstr ""
msgid "Are you sure you want to remove the attachment?"
msgstr ""
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr ""
@@ -2510,7 +2712,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr "確定è¦é‡ç½®å¥åº·æª¢æŸ¥ä»¤ç‰Œå—Žï¼Ÿ"
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2624,6 +2826,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2698,15 +2903,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr "八月"
@@ -2764,6 +2987,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2785,9 +3011,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2806,6 +3029,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2836,6 +3062,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2851,6 +3080,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3328,16 +3560,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3361,7 +3593,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3370,6 +3602,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3388,6 +3623,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3418,9 +3656,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3448,6 +3683,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3523,8 +3764,8 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
-msgstr "無法通éŽå…§éƒ¨ID引用組里程碑ï¼"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
+msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
msgstr ""
@@ -3538,6 +3779,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3574,6 +3818,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3616,6 +3866,9 @@ msgstr "變更"
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3634,6 +3887,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3739,15 +3995,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4096,9 +4343,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4111,6 +4355,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4123,6 +4370,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4150,9 +4400,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4192,6 +4439,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4387,6 +4637,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4408,9 +4661,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4462,7 +4712,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4489,6 +4739,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4567,10 +4820,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4729,6 +4982,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -4963,9 +5222,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5044,6 +5300,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5074,6 +5333,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5083,9 +5345,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5143,6 +5411,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5161,6 +5432,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5200,6 +5474,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr "收起å´é‚Šæ¬„"
@@ -5209,6 +5486,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5245,6 +5525,9 @@ msgstr "留言框ä½ç½®"
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5405,7 +5688,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5429,9 +5715,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5465,9 +5748,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5516,16 +5796,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5552,6 +5826,14 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5564,6 +5846,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5588,27 +5873,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5630,10 +5927,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5652,9 +5946,6 @@ msgid "ContainerRegistry|Remove tag"
msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5676,6 +5967,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5703,12 +5997,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5727,7 +6015,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5736,7 +6027,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5775,10 +6066,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5865,6 +6156,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5910,9 +6204,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -5928,9 +6219,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6027,7 +6315,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6045,9 +6333,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6066,9 +6351,6 @@ msgstr ""
msgid "Create a new issue"
msgstr "建立新議題"
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6078,9 +6360,6 @@ msgstr "在帳戶上創建個人訪å•ä»¤ç‰Œï¼Œä»¥é€šéŽ %{protocol} 來拉å–æˆ
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr "建立議題。為已觸發的æ¯å€‹è­¦å ±å»ºç«‹è­°é¡Œã€‚"
@@ -6123,6 +6402,9 @@ msgstr "建立群組標籤"
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr "建立標籤列表。å«æœ‰æ­¤æ¨™ç±¤çš„議題將會在清單中顯示。"
@@ -6135,6 +6417,9 @@ msgstr "建立åˆä½µè«‹æ±‚åŠåˆ†æ”¯"
msgid "Create milestone"
msgstr "建立里程碑"
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6174,6 +6459,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6207,6 +6498,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6258,9 +6552,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr "Cron 時å€"
-msgid "Cron syntax"
-msgstr "Cron 語法"
-
msgid "Crossplane"
msgstr ""
@@ -6297,6 +6588,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6321,6 +6615,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6369,6 +6666,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6393,6 +6693,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6643,6 +6946,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6679,6 +6985,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr "使用 Cron 語法定義自定義模å¼"
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6721,6 +7030,12 @@ msgstr "刪除留言"
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6809,10 +7124,6 @@ msgid "Dependencies|%d additional vulnerability not shown"
msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6847,12 +7158,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6862,9 +7167,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -6976,12 +7278,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7003,13 +7311,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7129,10 +7437,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7141,9 +7449,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7153,6 +7476,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7180,12 +7506,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7195,6 +7536,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7207,6 +7554,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr "詳情"
@@ -7433,6 +7783,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7481,6 +7834,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7505,6 +7861,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr "截止日期"
@@ -7652,6 +8011,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7667,6 +8029,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7760,6 +8125,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7769,9 +8137,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7799,6 +8164,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -7922,6 +8290,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -7946,10 +8317,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8006,7 +8377,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8219,10 +8590,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8234,12 +8605,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8309,7 +8674,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8414,9 +8788,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr "更新標籤時發生錯誤。"
@@ -8432,6 +8803,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr "上傳檔案時出錯"
@@ -8483,10 +8857,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8528,14 +8902,14 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
-msgstr "æ¯æ—¥åŸ·è¡Œï¼ˆæ·©æ™¨ 4 點)"
+msgid "Every day (at %{time})"
+msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
-msgstr "æ¯æœˆåŸ·è¡Œï¼ˆæ¯æœˆ 1 日淩晨 4 點)"
+msgid "Every month (Day %{day} at %{time})"
+msgstr ""
msgid "Every three months"
msgstr ""
@@ -8546,8 +8920,8 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
-msgstr "æ¯é€±åŸ·è¡Œï¼ˆå‘¨æ—¥æ·©æ™¨ 4 點)"
+msgid "Every week (%{weekday} at %{time})"
+msgstr ""
msgid "Everyone"
msgstr ""
@@ -8585,6 +8959,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8603,6 +8980,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8636,6 +9016,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8651,6 +9034,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8660,6 +9046,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8738,18 +9127,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8876,6 +9253,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -8951,7 +9331,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9014,6 +9394,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9026,6 +9412,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9035,15 +9424,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9062,6 +9460,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9077,9 +9478,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9170,6 +9577,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9182,6 +9592,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9191,9 +9604,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr "文件"
@@ -9209,24 +9619,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr "按æ交消æ¯éŽæ¿¾"
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr "é€éŽé‡Œç¨‹ç¢‘å稱篩é¸"
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9236,6 +9667,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9467,9 +9901,6 @@ msgstr "從創建議題到部署到生產環境"
msgid "From merge request merge until deploy to production"
msgstr "從åˆä½µè«‹æ±‚çš„åˆä½µåˆ°éƒ¨ç½²è‡³ç”Ÿç”¢ç’°å¢ƒ"
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9509,15 +9940,15 @@ msgstr ""
msgid "Geo"
msgstr ""
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9695,6 +10126,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9704,10 +10141,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9758,6 +10195,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9809,6 +10252,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9827,6 +10273,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9836,6 +10285,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10088,9 +10543,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10124,9 +10576,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10289,12 +10738,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10328,6 +10786,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10340,10 +10804,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10361,10 +10828,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10382,12 +10852,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10454,9 +10930,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10658,6 +11131,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10763,6 +11239,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10772,6 +11251,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10876,6 +11358,9 @@ msgstr "æ­·å²ç´€éŒ„"
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10885,6 +11370,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11035,6 +11523,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11044,7 +11535,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11053,6 +11547,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11065,7 +11565,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11083,13 +11586,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11101,6 +11604,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11110,6 +11616,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11119,10 +11628,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11215,10 +11724,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11251,6 +11760,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11284,6 +11796,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11308,18 +11826,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11369,6 +11905,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11408,6 +11968,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11444,18 +12010,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11468,6 +12043,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11531,6 +12109,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11543,6 +12124,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr "看æ¿"
@@ -11600,6 +12208,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11645,6 +12256,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11657,19 +12292,22 @@ msgstr "一月"
msgid "January"
msgstr "一月"
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11795,6 +12433,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11834,6 +12475,9 @@ msgstr "六月"
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr ""
@@ -12012,6 +12656,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12096,6 +12743,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12117,9 +12767,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr "了解更多"
@@ -12147,6 +12794,9 @@ msgstr "退出項目"
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12159,6 +12809,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12183,15 +12836,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12322,6 +12969,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12337,6 +12987,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12431,6 +13084,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12545,10 +13201,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12575,6 +13231,9 @@ msgstr "管ç†ç¾¤çµ„標籤"
msgid "Manage labels"
msgstr "管ç†æ¨™ç±¤"
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr "管ç†å°ˆæ¡ˆæ¨™ç±¤"
@@ -12626,9 +13285,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12638,9 +13294,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12818,6 +13471,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12827,9 +13483,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12842,6 +13495,9 @@ msgstr "åˆä½µè«‹æ±‚"
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr "åˆä½µè«‹æ±‚"
@@ -12875,6 +13531,9 @@ msgstr "åˆä½µè«‹æ±‚"
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -12923,9 +13582,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -12986,7 +13654,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13004,6 +13672,9 @@ msgstr ""
msgid "Merged"
msgstr "å·²åˆä½µ"
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13025,9 +13696,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13049,19 +13717,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is invalid:"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13085,6 +13756,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13140,6 +13832,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13158,6 +13856,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13194,6 +13895,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13255,6 +13959,63 @@ msgstr "ç›®å‰è¨±å¯è­‰ç„¡æ³•ä½¿ç”¨é‡Œç¨‹ç¢‘列表"
msgid "Milestone lists show all issues from the selected milestone."
msgstr "里程碑列表將顯示所é¸é‡Œç¨‹ç¢‘的所有議題"
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr "里程碑"
@@ -13264,6 +14025,12 @@ msgstr "ä½ å³å°‡æ°¸ä¹…刪除里程碑 %{milestoneTitle} 並將其中 %{issuesWi
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr "ä½ å³å°‡æ°¸ä¹…刪除里程碑 %{milestoneTitle}。此里程碑裡目å‰æ²’有任何議題或åˆä½µè«‹æ±‚。"
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr "刪除里程碑"
@@ -13273,21 +14040,39 @@ msgstr "刪除里程碑 %{milestoneTitle} ?"
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr "刪除里程碑 %{milestoneTitle} 時發生錯誤"
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr "找ä¸åˆ°é‡Œç¨‹ç¢‘ %{milestoneTitle}"
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr "å°‡ %{milestoneTitle} æå‡æˆç¾¤çµ„里程碑?"
msgid "Milestones|Promote Milestone"
msgstr "æå‡é‡Œç¨‹ç¢‘"
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr "這動作無法復原。"
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13348,6 +14133,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13462,6 +14250,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13471,6 +14262,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13483,9 +14277,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13495,9 +14286,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13531,6 +14319,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13559,6 +14395,9 @@ msgid "New Issue"
msgid_plural "New Issues"
msgstr[0] "新議題"
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13625,6 +14464,9 @@ msgstr "新議題"
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13682,6 +14524,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13700,18 +14545,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13802,12 +14638,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13832,6 +14674,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr "沒有è¦é¡¯ç¤ºçš„里程碑"
@@ -13967,6 +14812,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -13991,6 +14839,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr "顯示所有活動"
@@ -14105,9 +14956,15 @@ msgstr "å一月"
msgid "November"
msgstr "å一月"
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14174,6 +15031,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14183,9 +15049,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14250,7 +15113,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14295,7 +15158,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14310,6 +15173,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14340,7 +15206,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14388,6 +15254,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14406,6 +15275,9 @@ msgstr ""
msgid "Owner"
msgstr "所有者"
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14427,6 +15299,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14514,6 +15392,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14532,6 +15413,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14562,22 +15446,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14610,6 +15509,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14697,6 +15599,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14715,6 +15620,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14757,9 +15665,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14781,9 +15695,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14805,9 +15716,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -14916,6 +15824,9 @@ msgstr "去年的æµæ°´ç·š"
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -14976,15 +15887,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -14997,30 +15917,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15036,6 +15980,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15072,6 +16019,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15165,6 +16118,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15240,6 +16196,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15330,6 +16289,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15366,6 +16328,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15585,9 +16550,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15633,9 +16595,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15780,12 +16739,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15816,6 +16769,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15837,6 +16793,9 @@ msgstr "é …ç›® '%{project_name}' 已更新完æˆã€‚"
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15867,6 +16826,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15891,8 +16853,8 @@ msgstr "項目導出已被刪除。"
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr "項目導出éˆæŽ¥å·²éŽæœŸã€‚請從項目設置中é‡æ–°ç”Ÿæˆé …目導出。"
-msgid "Project export started. A download link will be sent by email."
-msgstr "項目導出已開始。下載éˆæŽ¥å°‡é€šéŽé›»å­éƒµä»¶ç™¼é€ã€‚"
+msgid "Project export started. A download link will be sent by email and made available on this page."
+msgstr ""
msgid "Project has too many %{label_for_message} to search"
msgstr ""
@@ -15900,6 +16862,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16014,9 +16979,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16182,6 +17144,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16227,6 +17192,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16377,6 +17345,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16470,12 +17441,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16551,9 +17528,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr "將這些專案里程碑æå‡æˆç¾¤çµ„里程碑。"
-msgid "Promote to Group Milestone"
-msgstr "æå‡è‡³ç¾¤çµ„里程碑"
-
msgid "Promote to group label"
msgstr ""
@@ -16572,30 +17546,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16731,9 +17759,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16743,6 +17768,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16845,6 +17876,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16854,9 +17888,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16893,9 +17924,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -16990,6 +18018,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr "相關的部署作業"
@@ -17033,6 +18076,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17054,6 +18109,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17123,6 +18181,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17165,6 +18229,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17204,6 +18271,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17255,6 +18325,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17285,6 +18358,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17300,7 +18376,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17403,6 +18482,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17439,6 +18521,9 @@ msgstr ""
msgid "Request Access"
msgstr "申請權é™"
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17454,10 +18539,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17472,6 +18560,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17493,10 +18587,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17564,6 +18655,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17576,6 +18670,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17721,6 +18821,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17784,9 +18887,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17823,9 +18923,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -17955,9 +19052,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18015,6 +19118,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18045,10 +19151,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18127,9 +19233,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18142,9 +19254,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18154,24 +19263,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18307,6 +19416,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18388,6 +19500,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr "é¸æ“‡ä¸‹è¼‰æ ¼å¼"
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18439,12 +19554,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr "é¸æ“‡åˆ†æ”¯/標籤"
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18490,9 +19611,18 @@ msgstr ""
msgid "Select source branch"
msgstr "é¸æ“‡ä¾†æºåˆ†æ”¯"
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr "é¸æ“‡ç›®æ¨™åˆ†æ”¯"
@@ -18565,6 +19695,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18730,6 +19866,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18766,6 +19905,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18850,6 +19992,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18868,7 +20013,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -18907,15 +20052,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr "顯示所有活動"
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -18940,12 +20085,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -18965,6 +20119,13 @@ msgid "Showing %d event"
msgid_plural "Showing %d events"
msgstr[0] "顯示 %d 個事件"
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19151,6 +20312,9 @@ msgstr ""
msgid "Snippets"
msgstr "程å¼ç¢¼ç‰‡æ®µ"
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19187,9 +20351,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19286,6 +20456,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19325,6 +20498,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19373,6 +20549,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19490,6 +20672,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19655,7 +20840,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19730,6 +20915,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19856,6 +21044,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19883,6 +21074,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -19910,6 +21104,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20090,9 +21287,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20177,6 +21380,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr "切æ›åˆ†æ”¯/標籤"
@@ -20204,9 +21410,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20457,6 +21660,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20539,9 +21745,6 @@ msgstr "與該階段相關的事件。"
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20578,9 +21781,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20618,6 +21827,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20792,6 +22004,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr "é ç™¼å¸ƒéšŽæ®µæ¦‚述了åˆä½µè«‹æ±‚çš„åˆä½µåˆ°éƒ¨ç½²ä»£ç¢¼åˆ°ç”Ÿç”¢ç’°å¢ƒçš„總時間。當首次部署到生產環境後,數據將自動添加到此處。"
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr "測試階段概述了 GitLab CI 為相關åˆä½µè«‹æ±‚é‹è¡Œæ¯å€‹æµæ°´ç·šæ‰€éœ€çš„時間。當第壹個æµæ°´ç·šé‹è¡Œå®Œæˆå¾Œï¼Œæ•¸æ“šå°‡è‡ªå‹•æ·»åŠ åˆ°æ­¤è™•ã€‚"
@@ -20840,6 +22055,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -20915,6 +22133,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -20987,6 +22214,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21050,6 +22280,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21134,6 +22367,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21173,6 +22409,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21218,9 +22457,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21332,7 +22568,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21359,6 +22595,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr "在創建壹個空的存儲庫或導入ç¾æœ‰å­˜å„²åº«ä¹‹å‰ï¼Œæ‚¨å°‡ç„¡æ³•æŽ¨é€ä»£ç¢¼ã€‚"
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21395,12 +22634,18 @@ msgstr "這個專案"
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21413,12 +22658,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21437,7 +22694,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21446,9 +22703,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21503,9 +22757,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21752,6 +23012,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] "å°æ™‚"
@@ -21814,6 +23077,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -21934,6 +23203,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -21991,15 +23263,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr "所有æ交和åˆä½µçš„總測試時間"
@@ -22015,9 +23281,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22036,6 +23299,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22147,6 +23413,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22204,10 +23473,10 @@ msgstr ""
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22216,6 +23485,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22255,6 +23527,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22264,9 +23539,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22516,18 +23797,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22546,6 +23821,9 @@ msgstr ""
msgid "Upload New File"
msgstr "上傳新文件"
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22564,6 +23842,9 @@ msgstr "點擊上傳"
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22588,9 +23869,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22600,12 +23878,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22615,12 +23899,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22639,12 +23929,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22669,7 +23965,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22744,9 +24040,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -22993,6 +24286,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23053,6 +24352,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23080,7 +24382,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23122,6 +24427,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23166,6 +24474,9 @@ msgstr[0] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23229,6 +24540,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23310,9 +24624,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23343,9 +24654,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23454,6 +24762,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23466,6 +24777,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23487,7 +24801,13 @@ msgstr "該階段的數據ä¸è¶³ï¼Œç„¡æ³•é¡¯ç¤ºã€‚"
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23529,9 +24849,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23571,12 +24888,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23611,9 +24937,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23647,9 +24970,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23770,10 +25090,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23782,10 +25105,10 @@ msgstr "å–消權é™ç”³è¯·"
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -23902,6 +25225,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -23929,6 +25255,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -23944,6 +25273,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24022,6 +25354,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24070,6 +25405,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24085,7 +25423,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24178,6 +25516,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24205,6 +25546,9 @@ msgstr "接收所有活動的通知"
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr "åªæŽ¥æ”¶è©•è«–中æåŠ(@)您的通知"
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr "在賬號上 %{set_password_link} 之å‰å°‡ç„¡æ³•é€šéŽ %{protocol} 拉å–或推é€ä»£ç¢¼ã€‚"
@@ -24223,6 +25567,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24256,7 +25606,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24292,7 +25645,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24385,9 +25738,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24397,12 +25759,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr "您的åå­—"
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24427,9 +25795,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24476,6 +25850,9 @@ msgstr ""
msgid "ago"
msgstr ""
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24518,6 +25895,9 @@ msgstr ""
msgid "branch name"
msgstr "分支å稱"
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -24682,6 +26062,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24700,6 +26083,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr "程å¼ç¢¼å“質沒有變更"
@@ -24718,6 +26104,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24758,6 +26147,9 @@ msgstr[0] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24767,6 +26159,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24776,6 +26171,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24825,6 +26223,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24835,7 +26236,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24868,10 +26272,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -24935,9 +26339,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -24999,6 +26412,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25020,6 +26436,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25059,6 +26481,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25186,7 +26611,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25366,9 +26791,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25378,15 +26800,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr "進入"
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25399,6 +26812,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr ""
@@ -25444,6 +26860,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25473,9 +26892,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25496,6 +26924,12 @@ msgid "project"
msgid_plural "projects"
msgstr[0] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25545,6 +26979,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25611,10 +27048,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25677,6 +27114,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25704,6 +27147,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25731,6 +27177,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/locale/zh_TW/gitlab.po b/locale/zh_TW/gitlab.po
index c5739f2f412..dc88bafd0ed 100644
--- a/locale/zh_TW/gitlab.po
+++ b/locale/zh_TW/gitlab.po
@@ -12,7 +12,7 @@ msgstr ""
"X-Crowdin-Project: gitlab-ee\n"
"X-Crowdin-Language: zh-TW\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
-"PO-Revision-Date: 2020-05-05 21:37\n"
+"PO-Revision-Date: 2020-06-08 15:08\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -71,6 +71,14 @@ msgid "%d URL scanned"
msgid_plural "%d URLs scanned"
msgstr[0] ""
+msgid "%d approver"
+msgid_plural "%d approvers"
+msgstr[0] ""
+
+msgid "%d approver (you've approved)"
+msgid_plural "%d approvers (you've approved)"
+msgstr[0] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -87,6 +95,10 @@ msgid "%d comment"
msgid_plural "%d comments"
msgstr[0] "%d 則留言"
+msgid "%d comment on this commit"
+msgid_plural "%d comments on this commit"
+msgstr[0] ""
+
msgid "%d commit"
msgid_plural "%d commits"
msgstr[0] "%d 次æ交"
@@ -106,6 +118,10 @@ msgid "%d contribution"
msgid_plural "%d contributions"
msgstr[0] "%d 個貢ç»"
+msgid "%d day"
+msgid_plural "%d days"
+msgstr[0] ""
+
msgid "%d error"
msgid_plural "%d errors"
msgstr[0] ""
@@ -162,6 +178,10 @@ msgid "%d more comment"
msgid_plural "%d more comments"
msgstr[0] "還有 %d 則留言"
+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] ""
+
msgid "%d project"
msgid_plural "%d projects"
msgstr[0] "%d 個專案"
@@ -186,6 +206,14 @@ msgid "%d unresolved thread"
msgid_plural "%d unresolved threads"
msgstr[0] ""
+msgid "%d url scanned"
+msgid_plural "%d urls scanned"
+msgstr[0] ""
+
+msgid "%d vulnerability"
+msgid_plural "%d vulnerabilities"
+msgstr[0] ""
+
msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
@@ -206,6 +234,9 @@ msgstr "ç”± %{commit_author_link} æ交於 %{commit_timeago}"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}."
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} 核心"
@@ -279,6 +310,9 @@ msgstr "%{filePath} 已刪除"
msgid "%{firstLabel} +%{labelCount} more"
msgstr "%{firstLabel} 還有 %{labelCount} 個"
+msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
+msgstr ""
+
msgid "%{global_id} is not a valid id for %{expected_type}."
msgstr "%{global_id} ä¸æ˜¯æœ‰æ•ˆçš„ %{expected_type} ID。"
@@ -288,6 +322,9 @@ msgstr "%{group_docs_link_start}群組%{group_docs_link_end} å…許您管ç†ã€å
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
msgstr "%{group_name} 使用群組管ç†å¸³æˆ¶ã€‚您需è¦å»ºç«‹ä¸€å€‹æ–°çš„ GitLab 帳戶,該帳戶將由 %{group_name} 群組管ç†ã€‚"
+msgid "%{host} sign-in from new location"
+msgstr ""
+
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
msgstr "%{icon} 您正打算加入 %{usersTag} 個人到討論中,請å°å¿ƒã€‚"
@@ -300,6 +337,30 @@ msgstr "%{issuesSize} 個議題"
msgid "%{issuesSize} issues with a limit of %{maxIssueCount}"
msgstr "%{issuesSize} å€‹è­°é¡Œï¼Œä¸Šé™ %{maxIssueCount} 個。"
+msgid "%{labelStart}Class:%{labelEnd} %{class}"
+msgstr ""
+
+msgid "%{labelStart}Confidence:%{labelEnd} %{confidence}"
+msgstr ""
+
+msgid "%{labelStart}File:%{labelEnd} %{file}"
+msgstr ""
+
+msgid "%{labelStart}Image:%{labelEnd} %{image}"
+msgstr ""
+
+msgid "%{labelStart}Method:%{labelEnd} %{method}"
+msgstr ""
+
+msgid "%{labelStart}Namespace:%{labelEnd} %{namespace}"
+msgstr ""
+
+msgid "%{labelStart}Report Type:%{labelEnd} %{reportType}"
+msgstr ""
+
+msgid "%{labelStart}Severity:%{labelEnd} %{severity}"
+msgstr ""
+
msgid "%{label_for_message} unavailable"
msgstr "%{label_for_message} 無法使用"
@@ -333,12 +394,21 @@ msgstr "%{loadingIcon} 已開始"
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr "%{lock_path} 被 GitLab 使用者 %{lock_user_id} 鎖定"
+msgid "%{markdownDocsLinkStart}Markdown%{markdownDocsLinkEnd} and %{quickActionsDocsLinkStart}quick actions%{quickActionsDocsLinkEnd} are supported"
+msgstr ""
+
msgid "%{mergeLength}/%{usersLength} can merge"
msgstr "%{mergeLength}/%{usersLength} å¯ä»¥åˆä½µ"
msgid "%{mrText}, this issue will be closed automatically."
msgstr "%{mrText},此議題將自動關閉。"
+msgid "%{name_with_link} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name_with_link} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{namespace_name} is now read-only. You cannot: %{base_message}"
msgstr ""
@@ -354,6 +424,12 @@ msgstr ""
msgid "%{name}'s avatar"
msgstr "%{name} 的大頭貼"
+msgid "%{name}(%{url}) has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name}(%{url}) has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
msgstr[0] ""
@@ -392,6 +468,12 @@ msgid "%{releases} release"
msgid_plural "%{releases} releases"
msgstr[0] "%{releases} 個發布版"
+msgid "%{remaining_approvals} left"
+msgstr ""
+
+msgid "%{retryButtonStart}Try again%{retryButtonEnd} or %{newFileButtonStart}attach a new file%{newFileButtonEnd}"
+msgstr ""
+
msgid "%{screenreaderOnlyStart}Keyboard shorcuts%{screenreaderOnlyEnd} Disabled"
msgstr ""
@@ -533,6 +615,9 @@ msgid "(%d closed)"
msgid_plural "(%d closed)"
msgstr[0] "(%d 個已關閉)"
+msgid "(%{linkStart}Cron syntax%{linkEnd})"
+msgstr ""
+
msgid "(%{mrCount} merged)"
msgstr "(%{mrCount} å·²åˆä½µ)"
@@ -719,6 +804,9 @@ msgstr "如果您覺得這是失誤,請è¯çµ¡æ‚¨çš„ GitLab 管ç†å“¡ã€‚"
msgid "8 hours"
msgstr "8å°æ™‚"
+msgid ":%{startLine} to %{endLine}"
+msgstr ""
+
msgid "< 1 hour"
msgstr "< 1 å°æ™‚"
@@ -749,6 +837,9 @@ msgstr ""
msgid "<strong>%{group_name}</strong> group members"
msgstr "<strong>%{group_name}</strong> 群組的æˆå“¡"
+msgid "<strong>%{label_name}</strong> <span>will be permanently deleted from %{subject_name}. This cannot be undone.</span>"
+msgstr ""
+
msgid "<strong>Deletes</strong> source branch"
msgstr "<strong>刪除</strong>來æºåˆ†æ”¯"
@@ -758,6 +849,9 @@ msgstr "「執行器ã€æ˜¯ä¸€å€‹åŸ·è¡Œä½œæ¥­çš„行程。您å¯ä»¥æ ¹æ“šéœ€è¦é…
msgid "A .NET Core console application template, customizable for any .NET Core project"
msgstr ".NET Core 控制å°æ‡‰ç”¨ç¨‹å¼ç¯„本,å¯é‡å°ä»»ä½• .NET Core 專案自訂"
+msgid "A DAG must have two dependent jobs to be visualized on this tab."
+msgstr ""
+
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
msgstr "一個 GitBook ç«™å°ï¼Œä½¿ç”¨ Netlify 代替 GitLab çš„ CI/CD,但ä»å…·æœ‰æ‰€æœ‰å…¶ä»–主è¦çš„ GitLab 功能。"
@@ -794,7 +888,10 @@ msgstr "「%{file_name}ã€æª”å已經在 %{branch} 分支"
msgid "A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project."
msgstr "分å‰æ˜¯å°ˆæ¡ˆçš„複本。<br />分å‰ç‰ˆæœ¬åº«è®“您在ä¸å½±éŸ¿åŽŸå§‹å°ˆæ¡ˆçš„情æ³ä¸‹ï¼Œé€²è¡Œè®Šæ›´ã€‚"
-msgid "A group represents your organization in GitLab."
+msgid "A group is a collection of several projects"
+msgstr ""
+
+msgid "A group represents your organization in GitLab. Groups allow you to manage users and collaborate across multiple projects."
msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
@@ -845,6 +942,9 @@ msgstr "用來在作業記錄中尋找測試覆蓋率輸出的正è¦è¡¨ç¤ºå¼ã€‚
msgid "A secure token that identifies an external storage request."
msgstr "一個用於識別外部儲存請求的安全權æ–。"
+msgid "A sign-in to your account has been made from the following IP address: %{ip}"
+msgstr ""
+
msgid "A subscription will 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 ""
@@ -857,9 +957,6 @@ msgstr "有ä½å…·æœ‰ä¾†æºåˆ†æ”¯å¯«å…¥æ¬Šé™çš„使用者é¸æ“‡äº†æ­¤é¸é …"
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
msgstr ""
-msgid "API Help"
-msgstr "API 說明"
-
msgid "API Token"
msgstr "API 權æ–"
@@ -905,9 +1002,6 @@ msgstr "接å—æœå‹™æ¢æ¬¾"
msgid "Acceptable for use in this project"
msgstr ""
-msgid "Accepted MR"
-msgstr "接å—çš„åˆä½µè«‹æ±‚"
-
msgid "Access Tokens"
msgstr "å­˜å–憑證"
@@ -998,12 +1092,6 @@ msgstr "您的éœæ…‹ç‰©ä»¶æ¬Šæ–用來從外部儲存空間存å–éœæ…‹ç‰©ä»¶ï¼ˆ
msgid "AccessTokens|reset it"
msgstr "é‡è¨­æ¬Šæ–"
-msgid "AccessibilityReport|Accessibility report artifact not found"
-msgstr ""
-
-msgid "AccessibilityReport|Failed to retrieve accessibility report"
-msgstr ""
-
msgid "AccessibilityReport|Learn More"
msgstr ""
@@ -1040,8 +1128,8 @@ msgstr "啟用æœå‹™å°"
msgid "Active"
msgstr "使用中"
-msgid "Active %{type} Tokens (%{token_length})"
-msgstr "使用中的%{type}æ¬Šæ– (%{token_length})"
+msgid "Active %{type} (%{token_length})"
+msgstr ""
msgid "Active Sessions"
msgstr "使用中的工作階段"
@@ -1049,6 +1137,9 @@ msgstr "使用中的工作階段"
msgid "Active Users:"
msgstr ""
+msgid "Active users"
+msgstr ""
+
msgid "Activity"
msgstr "å‹•æ…‹"
@@ -1092,8 +1183,8 @@ msgstr ""
msgid "Add Zoom meeting"
msgstr "加入 Zoom 會議"
-msgid "Add a %{type} token"
-msgstr "加入%{type}權æ–"
+msgid "Add a %{type}"
+msgstr ""
msgid "Add a GPG key"
msgstr "加入 GPG 金鑰"
@@ -1107,6 +1198,9 @@ msgstr "加入待辦事項"
msgid "Add a bullet list"
msgstr "加入項目清單"
+msgid "Add a comment to this line"
+msgstr ""
+
msgid "Add a general comment to this %{noteableDisplayName}."
msgstr "加入一般留言至 %{noteableDisplayName}。"
@@ -1116,9 +1210,15 @@ msgstr "加入一般留言至 %{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 "在 wiki 中加入首é ï¼Œå…¶ä¸­åŒ…å«æœ‰é—œå°ˆæ¡ˆçš„資訊,GitLab 將在這裡顯示該首é ï¼Œè€Œä¸æ˜¯æ­¤è¨Šæ¯ã€‚"
+msgid "Add a line"
+msgstr ""
+
msgid "Add a link"
msgstr "加入連çµ"
+msgid "Add a new issue"
+msgstr ""
+
msgid "Add a numbered list"
msgstr "加入編號列表"
@@ -1134,8 +1234,11 @@ msgstr "è¦åœ¨æ‰€æœ‰é›»å­éƒµä»¶åŠ å…¥çš„附加文字。長度ä¸èƒ½è¶…éŽ %{cha
msgid "Add an SSH key"
msgstr "加入 SSH 金鑰"
-msgid "Add an existing issue to the epic."
-msgstr "å°‡ç¾æœ‰è­°é¡ŒåŠ å…¥åˆ°å²è©©ä¸­ã€‚"
+msgid "Add an existing issue"
+msgstr ""
+
+msgid "Add an impersonation token"
+msgstr ""
msgid "Add an issue"
msgstr "加入議題"
@@ -1200,6 +1303,9 @@ msgstr "加入回應"
msgid "Add request manually"
msgstr "手動加入請求"
+msgid "Add strikethrough text"
+msgstr ""
+
msgid "Add system hook"
msgstr "加入系統掛鉤"
@@ -1290,18 +1396,18 @@ msgstr "加入 Zoom 會議"
msgid "Adds an issue to an epic."
msgstr "å‘å²è©©åŠ å…¥è­°é¡Œã€‚"
-msgid "Adjust your filters/search criteria above."
-msgstr "在上方調整您的éŽæ¿¾å™¨ï¼æœå°‹æ¢ä»¶ã€‚"
+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 ""
msgid "Admin Area"
msgstr "管ç†ä¸­å¿ƒ"
+msgid "Admin Note"
+msgstr ""
+
msgid "Admin Overview"
msgstr "管ç†æ¦‚覽"
-msgid "Admin Section"
-msgstr "管ç†éƒ¨åˆ†"
-
msgid "Admin mode already enabled"
msgstr "管ç†å“¡æ¨¡å¼å·²å•Ÿç”¨"
@@ -1626,62 +1732,116 @@ msgstr "密碼更新æˆåŠŸå¾Œï¼Œæ‚¨å°‡è¢«é‡æ–°å°Žå‘至登入é é¢ã€‚"
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr "密碼更新æˆåŠŸå¾Œï¼Œæ‚¨å°‡è¢«é‡æ–°å°Žå‘到登入é é¢ï¼Œæ‚¨å¯ä»¥ç”¨æ–°å¯†ç¢¼é‡æ–°ç™»å…¥ã€‚"
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] "警示"
-msgid "Alert Details"
-msgstr ""
-
msgid "AlertManagement|Acknowledged"
msgstr ""
msgid "AlertManagement|Alert"
msgstr ""
+msgid "AlertManagement|Alert detail"
+msgstr ""
+
+msgid "AlertManagement|Alert details"
+msgstr ""
+
+msgid "AlertManagement|Alert status: %{status}"
+msgstr ""
+
+msgid "AlertManagement|Alerts"
+msgstr ""
+
+msgid "AlertManagement|All alerts"
+msgstr ""
+
+msgid "AlertManagement|Assign status"
+msgstr ""
+
+msgid "AlertManagement|Assignees"
+msgstr ""
+
msgid "AlertManagement|Authorize external service"
msgstr ""
+msgid "AlertManagement|Create issue"
+msgstr ""
+
+msgid "AlertManagement|Critical"
+msgstr ""
+
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|End time"
+msgid "AlertManagement|Edit"
msgstr ""
-msgid "AlertManagement|End time:"
+msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
msgstr ""
-msgid "AlertManagement|Events:"
+msgid "AlertManagement|High"
+msgstr ""
+
+msgid "AlertManagement|Info"
msgstr ""
-msgid "AlertManagement|Full Alert Details"
+msgid "AlertManagement|Low"
+msgstr ""
+
+msgid "AlertManagement|Medium"
msgstr ""
msgid "AlertManagement|More information"
msgstr ""
+msgid "AlertManagement|No alert data to display."
+msgstr ""
+
msgid "AlertManagement|No alerts available to display. If you think you're seeing this message in error, refresh the page."
msgstr ""
msgid "AlertManagement|No alerts to display."
msgstr ""
+msgid "AlertManagement|None"
+msgstr ""
+
+msgid "AlertManagement|Open"
+msgstr ""
+
msgid "AlertManagement|Overview"
msgstr ""
+msgid "AlertManagement|Reported %{when}"
+msgstr ""
+
+msgid "AlertManagement|Reported %{when} by %{tool}"
+msgstr ""
+
msgid "AlertManagement|Resolved"
msgstr ""
-msgid "AlertManagement|Severity"
+msgid "AlertManagement|Service"
msgstr ""
-msgid "AlertManagement|Start time"
+msgid "AlertManagement|Severity"
msgstr ""
-msgid "AlertManagement|Start time:"
+msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
@@ -1690,17 +1850,35 @@ msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
+msgid "AlertManagement|There was an error displaying the alert. Please refresh the page to try again."
+msgstr ""
+
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
+msgid "AlertManagement|There was an error while updating the status of the alert. Please try again."
+msgstr ""
+
+msgid "AlertManagement|Tool"
+msgstr ""
+
msgid "AlertManagement|Triggered"
msgstr ""
-msgid "AlertService|%{linkStart}Learn more%{linkEnd} about configuring this endpoint to receive alerts."
-msgstr "%{linkStart}了解更多%{linkEnd}有關接收警示端點設定"
+msgid "AlertManagement|Unassigned"
+msgstr ""
+
+msgid "AlertManagement|Unknown"
+msgstr ""
+
+msgid "AlertManagement|View issue"
+msgstr ""
+
+msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
+msgstr ""
-msgid "AlertService|Each alert source must be authorized using the following URL and authorization key."
-msgstr "æ¯å€‹è­¦ç¤ºä¾†æºéƒ½å¿…須使用下述網å€å’ŒæŽˆæ¬Šé‡‘鑰授權。"
+msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
+msgstr ""
msgid "Alerts"
msgstr "警示"
@@ -1873,6 +2051,9 @@ msgstr ""
msgid "An application called %{link_to_client} is requesting access to your GitLab account."
msgstr "æ‡‰ç”¨ç¨‹å¼ %{link_to_client} 請求存å–您的 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 ""
+
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 "空 GitLab 使用者欄ä½å°‡åœ¨æ‰€æœ‰è­°é¡ŒåŠç•™è¨€çš„æ述中加入 FogBugz 使用者的全å(例如「由 John Smithã€ï¼‰ã€‚其還會與專案建立者關è¯å’Œï¼æˆ–分é…這些議題或留言。"
@@ -2038,9 +2219,6 @@ msgstr "載入所有檔案時發生錯誤。"
msgid "An error occurred while loading chart data"
msgstr "載入圖表資料時發生錯誤"
-msgid "An error occurred while loading clusters"
-msgstr ""
-
msgid "An error occurred while loading commit signatures"
msgstr "載入æ交簽å時發生錯誤"
@@ -2062,6 +2240,9 @@ msgstr "載入議題時發生錯誤"
msgid "An error occurred while loading merge requests."
msgstr ""
+msgid "An error occurred while loading milestones"
+msgstr ""
+
msgid "An error occurred while loading terraform report"
msgstr ""
@@ -2137,6 +2318,9 @@ msgstr "儲存核准設定時發生錯誤"
msgid "An error occurred while saving the template. Please check if the template exists."
msgstr "儲存範本時發生錯誤。請檢查範本是å¦å­˜åœ¨ã€‚"
+msgid "An error occurred while searching for milestones"
+msgstr ""
+
msgid "An error occurred while subscribing to notifications."
msgstr "訂閱通知時發生錯誤。"
@@ -2173,9 +2357,15 @@ msgstr ""
msgid "An instance-level serverless domain already exists."
msgstr ""
+msgid "An issue already exists"
+msgstr ""
+
msgid "An issue can be a bug, a todo or a feature request that needs to be discussed in a project. Besides, issues are searchable and filterable."
msgstr "è­°é¡Œå¯ä»¥æ˜¯éœ€è¦åœ¨å°ˆæ¡ˆä¸­è¨Žè«–的缺陷ã€å¾…辦事項或功能請求。此外,議題是å¯æœå°‹å’ŒéŽæ¿¾çš„。"
+msgid "An unauthenticated user"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr "檢查專案環境時發生æ„外錯誤。"
@@ -2191,6 +2381,9 @@ msgstr "啟動網é çµ‚端機時發生æ„外錯誤。"
msgid "An unexpected error occurred while stopping the Web Terminal."
msgstr "åœæ­¢ç¶²é çµ‚端機時發生æ„外錯誤。"
+msgid "An unknown error occurred while loading this graph."
+msgstr ""
+
msgid "Analytics"
msgstr "分æž"
@@ -2200,6 +2393,9 @@ msgstr "分æžç¶²é æ‡‰ç”¨ç¨‹å¼çš„審閱版本。"
msgid "Analyze your dependencies for known vulnerabilities."
msgstr ""
+msgid "Analyze your source code and git history for secrets"
+msgstr ""
+
msgid "Analyze your source code for known vulnerabilities."
msgstr ""
@@ -2224,12 +2420,6 @@ msgstr "任何"
msgid "Any Author"
msgstr ""
-msgid "Any Label"
-msgstr ""
-
-msgid "Any Milestone"
-msgstr ""
-
msgid "Any branch"
msgstr ""
@@ -2239,9 +2429,15 @@ msgstr ""
msgid "Any encrypted tokens"
msgstr ""
+msgid "Any label"
+msgstr ""
+
msgid "Any member with Developer or higher permissions to the project."
msgstr ""
+msgid "Any milestone"
+msgstr ""
+
msgid "Any namespace"
msgstr ""
@@ -2305,6 +2501,9 @@ msgstr ""
msgid "Apply a template"
msgstr ""
+msgid "Apply changes"
+msgstr ""
+
msgid "Apply suggestion"
msgstr ""
@@ -2369,12 +2568,6 @@ msgstr ""
msgid "ApprovalRule|e.g. QA, Security, etc."
msgstr ""
-msgid "Approvals"
-msgstr ""
-
-msgid "Approvals (you've approved)"
-msgstr ""
-
msgid "Approve"
msgstr "核准"
@@ -2384,12 +2577,18 @@ msgstr "核准åˆä½µè«‹æ±‚"
msgid "Approve the current merge request."
msgstr "核准目å‰åˆä½µè«‹æ±‚。"
+msgid "Approved"
+msgstr ""
+
msgid "Approved by: "
msgstr ""
msgid "Approved the current merge request."
msgstr "核准了目å‰çš„åˆä½µè«‹æ±‚。"
+msgid "Approved-By"
+msgstr ""
+
msgid "Approver"
msgstr "核准人"
@@ -2498,6 +2697,9 @@ msgstr "您確定è¦ç§»é™¤ %{group_name} 嗎?"
msgid "Are you sure you want to remove the attachment?"
msgstr "您確定è¦ç§»é™¤æ­¤é™„件嗎?"
+msgid "Are you sure you want to remove the license?"
+msgstr ""
+
msgid "Are you sure you want to remove this identity?"
msgstr "您確定è¦ç§»é™¤é€™å€‹èº«ä»½è­˜åˆ¥å—Žï¼Ÿ"
@@ -2510,7 +2712,7 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
-msgid "Are you sure you want to revoke this %{type} Token? This action cannot be undone."
+msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to revoke this nickname?"
@@ -2624,6 +2826,9 @@ msgstr ""
msgid "Assigned Merge Requests"
msgstr ""
+msgid "Assigned to %{assignee_name}"
+msgstr ""
+
msgid "Assigned to me"
msgstr ""
@@ -2698,15 +2903,33 @@ msgstr ""
msgid "AuditLogs|Date"
msgstr ""
+msgid "AuditLogs|Failed to find %{type}. Please search for another %{type}."
+msgstr ""
+
+msgid "AuditLogs|Failed to find %{type}. Please try again."
+msgstr ""
+
+msgid "AuditLogs|Group Events"
+msgstr ""
+
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|No matching %{type} found."
+msgstr ""
+
msgid "AuditLogs|Object"
msgstr ""
+msgid "AuditLogs|Project Events"
+msgstr ""
+
msgid "AuditLogs|Target"
msgstr ""
+msgid "AuditLogs|User Events"
+msgstr ""
+
msgid "Aug"
msgstr "8月"
@@ -2764,6 +2987,9 @@ msgstr ""
msgid "Authorize %{link_to_client} to use your account?"
msgstr ""
+msgid "Authorize external services to send alerts to GitLab"
+msgstr ""
+
msgid "Authorized %{new_chat_name}"
msgstr ""
@@ -2785,9 +3011,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts"
msgstr ""
-msgid "Auto License Compliance"
-msgstr ""
-
msgid "Auto stop successfully canceled."
msgstr ""
@@ -2806,6 +3029,9 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
+msgid "AutoDevOps|Dismiss Auto DevOps box"
+msgstr ""
+
msgid "AutoDevOps|Enable in settings"
msgstr ""
@@ -2836,6 +3062,9 @@ msgstr ""
msgid "Automatic certificate management using Let's Encrypt"
msgstr ""
+msgid "Automatically create merge requests for vulnerabilities that have fixes available."
+msgstr ""
+
msgid "Automatically marked as default internal user"
msgstr ""
@@ -2851,6 +3080,9 @@ msgstr ""
msgid "Available"
msgstr ""
+msgid "Available for dependency and container scanning"
+msgstr ""
+
msgid "Available group Runners: %{runners}"
msgstr ""
@@ -3328,16 +3560,16 @@ msgstr ""
msgid "BurndownChartLabel|Open issues"
msgstr ""
-msgid "Business"
+msgid "Burnup chart"
msgstr ""
-msgid "Business metrics (Custom)"
+msgid "Business"
msgstr ""
-msgid "Buy EE"
+msgid "Business metrics (Custom)"
msgstr ""
-msgid "Buy GitLab Enterprise Edition"
+msgid "Buy License"
msgstr ""
msgid "Buy more Pipeline minutes"
@@ -3361,7 +3593,7 @@ msgstr ""
msgid "CI / CD"
msgstr ""
-msgid "CI / CD Charts"
+msgid "CI / CD Analytics"
msgstr ""
msgid "CI / CD Settings"
@@ -3370,6 +3602,9 @@ msgstr ""
msgid "CI Lint"
msgstr ""
+msgid "CI settings"
+msgstr ""
+
msgid "CI variables"
msgstr ""
@@ -3388,6 +3623,9 @@ msgstr ""
msgid "CI/CD settings"
msgstr ""
+msgid "CICD|Add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} with a domain or create an AUTO_DEVOPS_PLATFORM_TARGET CI variable."
+msgstr ""
+
msgid "CICD|Auto DevOps"
msgstr ""
@@ -3418,9 +3656,6 @@ msgstr ""
msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
-msgstr ""
-
msgid "CICD|group enabled"
msgstr ""
@@ -3448,6 +3683,12 @@ msgstr ""
msgid "Can override approvers and approvals required per merge request"
msgstr ""
+msgid "Can't create snippet: %{err}"
+msgstr ""
+
+msgid "Can't edit as source branch was deleted"
+msgstr ""
+
msgid "Can't find HEAD commit for this branch"
msgstr ""
@@ -3523,7 +3764,7 @@ msgstr ""
msgid "Cannot promote issue due to insufficient permissions."
msgstr ""
-msgid "Cannot refer to a group milestone by an internal id!"
+msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
msgid "Cannot set confidential epic for not-confidential issue"
@@ -3538,6 +3779,9 @@ msgstr ""
msgid "Capacity threshold"
msgstr ""
+msgid "Certain user content will be moved to a system-wide \"Ghost User\" in order to maintain content for posterity. For further information, please refer to the %{link_start}user account deletion documentation.%{link_end}"
+msgstr ""
+
msgid "Certificate"
msgstr ""
@@ -3574,6 +3818,12 @@ msgstr ""
msgid "Change permissions"
msgstr ""
+msgid "Change status"
+msgstr ""
+
+msgid "Change subscription"
+msgstr ""
+
msgid "Change template"
msgstr ""
@@ -3616,6 +3866,9 @@ msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
+msgid "Changes are still tracked. Useful for cluster/index migrations."
+msgstr ""
+
msgid "Changes are unknown"
msgstr ""
@@ -3634,6 +3887,9 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
+msgid "Channel handle (e.g. town-square)"
+msgstr ""
+
msgid "Charts"
msgstr ""
@@ -3739,15 +3995,6 @@ msgstr ""
msgid "Checkout|(x%{numberOfUsers})"
msgstr ""
-msgid "Checkout|1. Your profile"
-msgstr ""
-
-msgid "Checkout|2. Checkout"
-msgstr ""
-
-msgid "Checkout|3. Your GitLab group"
-msgstr ""
-
msgid "Checkout|Billing address"
msgstr ""
@@ -4096,9 +4343,6 @@ msgstr ""
msgid "Class"
msgstr ""
-msgid "Class:"
-msgstr ""
-
msgid "Classification Label (optional)"
msgstr ""
@@ -4111,6 +4355,9 @@ msgstr ""
msgid "Clear chart filters"
msgstr ""
+msgid "Clear due date"
+msgstr ""
+
msgid "Clear input"
msgstr ""
@@ -4123,6 +4370,9 @@ msgstr ""
msgid "Clear search input"
msgstr ""
+msgid "Clear start date"
+msgstr ""
+
msgid "Clear templates search input"
msgstr ""
@@ -4150,9 +4400,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -4192,6 +4439,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{display_issuable_type}"
+msgstr ""
+
msgid "Close %{tabname}"
msgstr ""
@@ -4387,6 +4637,9 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
+msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
+msgstr ""
+
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters."
msgstr ""
@@ -4408,9 +4661,6 @@ msgstr ""
msgid "ClusterIntegration|Copy Kubernetes cluster name"
msgstr ""
-msgid "ClusterIntegration|Copy Service Token"
-msgstr ""
-
msgid "ClusterIntegration|Could not load IAM roles"
msgstr ""
@@ -4462,7 +4712,7 @@ msgstr ""
msgid "ClusterIntegration|Crossplane"
msgstr ""
-msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{kubectl} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
+msgid "ClusterIntegration|Crossplane enables declarative provisioning of managed services from your cloud of choice using %{codeStart}kubectl%{codeEnd} or %{gitlabIntegrationLink}. Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on."
msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
@@ -4489,6 +4739,9 @@ msgstr ""
msgid "ClusterIntegration|Enabled stack"
msgstr ""
+msgid "ClusterIntegration|Enter new Service Token"
+msgstr ""
+
msgid "ClusterIntegration|Enter the details for your Amazon EKS Kubernetes cluster"
msgstr ""
@@ -4567,10 +4820,10 @@ msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
-msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
+msgid "ClusterIntegration|Helm release failed to install"
msgstr ""
-msgid "ClusterIntegration|Hide"
+msgid "ClusterIntegration|Helm streamlines installing and managing Kubernetes applications. Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts."
msgstr ""
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
@@ -4729,6 +4982,12 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
+msgid "ClusterIntegration|No deployment cluster found for this job"
+msgstr ""
+
+msgid "ClusterIntegration|No deployment found for this job"
+msgstr ""
+
msgid "ClusterIntegration|No instance type found"
msgstr ""
@@ -4963,9 +5222,6 @@ msgstr ""
msgid "ClusterIntegration|Set the global mode for the WAF in this cluster. This can be overridden at the environmental level."
msgstr ""
-msgid "ClusterIntegration|Show"
-msgstr ""
-
msgid "ClusterIntegration|Something went wrong on our end."
msgstr ""
@@ -5044,6 +5300,9 @@ msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
+msgid "ClusterIntegration|Update %{appTitle}"
+msgstr ""
+
msgid "ClusterIntegration|Update failed. Please check the logs and try again."
msgstr ""
@@ -5074,6 +5333,9 @@ msgstr ""
msgid "ClusterIntegration|You are about to uninstall %{appTitle} from your cluster."
msgstr ""
+msgid "ClusterIntegration|You are about to update %{appTitle} on your cluster."
+msgstr ""
+
msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
msgstr ""
@@ -5083,9 +5345,15 @@ msgstr ""
msgid "ClusterIntegration|You must have an RBAC-enabled cluster to install Knative."
msgstr ""
+msgid "ClusterIntegration|You must specify a domain before you can install Knative."
+msgstr ""
+
msgid "ClusterIntegration|You should select at least two subnets"
msgstr ""
+msgid "ClusterIntegration|Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days."
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -5143,6 +5411,9 @@ msgstr ""
msgid "ClusterIntergation|Select service role"
msgstr ""
+msgid "Clusters|An error occurred while loading clusters"
+msgstr ""
+
msgid "Code"
msgstr ""
@@ -5161,6 +5432,9 @@ msgstr ""
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 ""
+msgid "Code coverage statistics for master %{start_date} - %{end_date}"
+msgstr ""
+
msgid "Code owner approval is required"
msgstr ""
@@ -5200,6 +5474,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -5209,6 +5486,9 @@ msgstr ""
msgid "ComboSearch is not defined"
msgstr ""
+msgid "Coming soon"
+msgstr ""
+
msgid "Command"
msgstr ""
@@ -5245,6 +5525,9 @@ msgstr ""
msgid "Comment is being updated"
msgstr ""
+msgid "Comment on lines %{startLine} to %{endLine}"
+msgstr ""
+
msgid "Comment/Reply (quoting selected text)"
msgstr ""
@@ -5405,7 +5688,10 @@ msgstr ""
msgid "ComplianceFramework|SOX - Sarbanes-Oxley"
msgstr ""
-msgid "Confidence: %{confidence}"
+msgid "ComplianceFramework|This project is regulated by %{framework}."
+msgstr ""
+
+msgid "Confidence"
msgstr ""
msgid "Confidential"
@@ -5429,9 +5715,6 @@ msgstr ""
msgid "Configure Prometheus"
msgstr ""
-msgid "Configure Security %{wordBreakOpportunity}and Compliance"
-msgstr ""
-
msgid "Configure Tracing"
msgstr ""
@@ -5465,9 +5748,6 @@ msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
-msgid "Configure the Jira integration first on your project's %{strong_start} Settings > Integrations > Jira%{strong_end} page."
-msgstr ""
-
msgid "Configure the way a user creates a new account."
msgstr ""
@@ -5516,16 +5796,10 @@ msgstr ""
msgid "Connection timed out"
msgstr ""
-msgid "Contact an owner of group %{namespace_name} to upgrade the plan."
-msgstr ""
-
-msgid "Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
-msgstr ""
-
msgid "Contact sales to upgrade"
msgstr ""
-msgid "Contact your Administrator to upgrade your license."
+msgid "Contact support"
msgstr ""
msgid "Container Registry"
@@ -5552,6 +5826,14 @@ msgstr ""
msgid "ContainerRegistry| Please visit the %{linkStart}administration settings%{linkEnd} to enable this feature."
msgstr ""
+msgid "ContainerRegistry|%{count} Image repository"
+msgid_plural "ContainerRegistry|%{count} Image repositories"
+msgstr[0] ""
+
+msgid "ContainerRegistry|%{count} Tag"
+msgid_plural "ContainerRegistry|%{count} Tags"
+msgstr[0] ""
+
msgid "ContainerRegistry|%{imageName} tags"
msgstr ""
@@ -5564,6 +5846,9 @@ msgstr ""
msgid "ContainerRegistry|Build an image"
msgstr ""
+msgid "ContainerRegistry|CLI Commands"
+msgstr ""
+
msgid "ContainerRegistry|Compressed Size"
msgstr ""
@@ -5588,27 +5873,39 @@ msgstr ""
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
msgstr ""
-msgid "ContainerRegistry|Edit Settings"
+msgid "ContainerRegistry|Expiration interval:"
msgstr ""
-msgid "ContainerRegistry|Expiration interval:"
+msgid "ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}"
+msgstr ""
+
+msgid "ContainerRegistry|Expiration policy is disabled"
msgstr ""
msgid "ContainerRegistry|Expiration policy successfully saved."
msgstr ""
+msgid "ContainerRegistry|Expiration policy will run in %{time}"
+msgstr ""
+
msgid "ContainerRegistry|Expiration policy:"
msgstr ""
msgid "ContainerRegistry|Expiration schedule:"
msgstr ""
+msgid "ContainerRegistry|Filter by name"
+msgstr ""
+
msgid "ContainerRegistry|If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have %{twofaDocLinkStart}Two-Factor Authentication%{twofaDocLinkEnd} enabled, use a %{personalAccessTokensDocLinkStart}Personal Access Token%{personalAccessTokensDocLinkEnd} instead of a password."
msgstr ""
msgid "ContainerRegistry|Image ID"
msgstr ""
+msgid "ContainerRegistry|Image Repositories"
+msgstr ""
+
msgid "ContainerRegistry|Keep and protect the images that matter most."
msgstr ""
@@ -5630,10 +5927,7 @@ msgstr ""
msgid "ContainerRegistry|Push an image"
msgstr ""
-msgid "ContainerRegistry|Quick Start"
-msgstr ""
-
-msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
+msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-master%{codeEnd} or %{codeStart}release-.*%{codeEnd} are supported"
msgstr ""
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
@@ -5652,9 +5946,6 @@ msgid "ContainerRegistry|Remove tag"
msgid_plural "ContainerRegistry|Remove tags"
msgstr[0] ""
-msgid "ContainerRegistry|Retention policy has been Enabled"
-msgstr ""
-
msgid "ContainerRegistry|Something went wrong while fetching the expiration policy."
msgstr ""
@@ -5676,6 +5967,9 @@ msgstr ""
msgid "ContainerRegistry|Something went wrong while updating the expiration policy."
msgstr ""
+msgid "ContainerRegistry|Sorry, your filter produced no results."
+msgstr ""
+
msgid "ContainerRegistry|Tag"
msgstr ""
@@ -5703,12 +5997,6 @@ msgstr ""
msgid "ContainerRegistry|The last tag related to this image was recently removed. This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process. If you have any questions, contact your administrator."
msgstr ""
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled and will run in %{days}. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
-msgid "ContainerRegistry|The retention and expiration policy for this Container Registry has been enabled. For more information visit the %{linkStart}documentation%{linkEnd}"
-msgstr ""
-
msgid "ContainerRegistry|The value of this input should be less than 255 characters"
msgstr ""
@@ -5727,7 +6015,10 @@ msgstr ""
msgid "ContainerRegistry|This image repository is scheduled for deletion"
msgstr ""
-msgid "ContainerRegistry|We are having trouble connecting to Docker, which could be due to an issue with your project name or path. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|To widen your search, change or remove the filters above."
+msgstr ""
+
+msgid "ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|With the Container Registry, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
@@ -5736,7 +6027,7 @@ msgstr ""
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 ""
-msgid "ContainerRegistry|With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images. %{docLinkStart}More Information%{docLinkEnd}"
+msgid "ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "ContainerRegistry|You are about to remove %{item} tags. Are you sure?"
@@ -5775,10 +6066,10 @@ msgstr ""
msgid "Contribution Analytics"
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
msgstr ""
-msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{closed_count}</strong> closed."
+msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{merged_count}</strong> merged."
msgstr ""
msgid "ContributionAnalytics|<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
@@ -5865,6 +6156,9 @@ msgstr ""
msgid "Copy %{proxy_url}"
msgstr ""
+msgid "Copy %{type}"
+msgstr ""
+
msgid "Copy Account ID to clipboard"
msgstr ""
@@ -5910,9 +6204,6 @@ msgstr ""
msgid "Copy file path"
msgstr ""
-msgid "Copy impersonation token"
-msgstr ""
-
msgid "Copy key"
msgstr ""
@@ -5928,9 +6219,6 @@ msgstr ""
msgid "Copy link to chart"
msgstr ""
-msgid "Copy personal access token"
-msgstr ""
-
msgid "Copy reference"
msgstr ""
@@ -6027,7 +6315,7 @@ msgstr ""
msgid "Create %{environment}"
msgstr ""
-msgid "Create %{type} token"
+msgid "Create %{type}"
msgstr ""
msgid "Create New Directory"
@@ -6045,9 +6333,6 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
-msgid "Create a group for your organization"
-msgstr ""
-
msgid "Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies."
msgstr ""
@@ -6066,9 +6351,6 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
-msgid "Create a new issue and add it to the epic."
-msgstr ""
-
msgid "Create a new repository"
msgstr ""
@@ -6078,9 +6360,6 @@ msgstr ""
msgid "Create an account using:"
msgstr ""
-msgid "Create an issue"
-msgstr ""
-
msgid "Create an issue. Issues are created for each alert triggered."
msgstr ""
@@ -6123,6 +6402,9 @@ msgstr ""
msgid "Create issue"
msgstr ""
+msgid "Create iteration"
+msgstr ""
+
msgid "Create lists from labels. Issues with that label appear in that list."
msgstr ""
@@ -6135,6 +6417,9 @@ msgstr ""
msgid "Create milestone"
msgstr ""
+msgid "Create new"
+msgstr ""
+
msgid "Create new board"
msgstr ""
@@ -6174,6 +6459,12 @@ msgstr ""
msgid "Create your first page"
msgstr ""
+msgid "Create your group"
+msgstr ""
+
+msgid "Create/import your first project"
+msgstr ""
+
msgid "CreateGroup|You don’t have permission to create a subgroup in this group."
msgstr ""
@@ -6207,6 +6498,9 @@ msgstr ""
msgid "Created by me"
msgstr ""
+msgid "Created date"
+msgstr ""
+
msgid "Created issue %{issueLink}"
msgstr ""
@@ -6258,9 +6552,6 @@ msgstr ""
msgid "Cron Timezone"
msgstr ""
-msgid "Cron syntax"
-msgstr ""
-
msgid "Crossplane"
msgstr ""
@@ -6297,6 +6588,9 @@ msgstr ""
msgid "CurrentUser|Start a Gold trial"
msgstr ""
+msgid "CurrentUser|Upgrade"
+msgstr ""
+
msgid "Custom CI configuration path"
msgstr ""
@@ -6321,6 +6615,9 @@ msgstr ""
msgid "Custom range"
msgstr ""
+msgid "Custom range (UTC)"
+msgstr ""
+
msgid "CustomCycleAnalytics|Add a stage"
msgstr ""
@@ -6369,6 +6666,9 @@ msgstr ""
msgid "CustomCycleAnalytics|Update stage"
msgstr ""
+msgid "Customer Portal"
+msgstr ""
+
msgid "Customize colors"
msgstr ""
@@ -6393,6 +6693,9 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
+msgid "Cycle Time"
+msgstr ""
+
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
@@ -6643,6 +6946,9 @@ msgstr ""
msgid "Default classification label"
msgstr ""
+msgid "Default dashboard"
+msgstr ""
+
msgid "Default deletion adjourned period"
msgstr ""
@@ -6679,6 +6985,9 @@ msgstr ""
msgid "Define a custom pattern with cron syntax"
msgstr ""
+msgid "Define custom rules for what constitutes spam, independent of Akismet"
+msgstr ""
+
msgid "Define environments in the deploy stage(s) in <code>.gitlab-ci.yml</code> to track deployments here."
msgstr ""
@@ -6721,6 +7030,12 @@ msgstr ""
msgid "Delete domain"
msgstr ""
+msgid "Delete label"
+msgstr ""
+
+msgid "Delete label: %{label_name} ?"
+msgstr ""
+
msgid "Delete license"
msgstr ""
@@ -6809,10 +7124,6 @@ msgid "Dependencies|%d additional vulnerability not shown"
msgid_plural "Dependencies|%d additional vulnerabilities not shown"
msgstr[0] ""
-msgid "Dependencies|%d vulnerability"
-msgid_plural "Dependencies|%d vulnerabilities"
-msgstr[0] ""
-
msgid "Dependencies|%d vulnerability detected"
msgid_plural "Dependencies|%d vulnerabilities detected"
msgstr[0] ""
@@ -6847,12 +7158,6 @@ msgstr ""
msgid "Dependencies|Packager"
msgstr ""
-msgid "Dependencies|Safe"
-msgstr ""
-
-msgid "Dependencies|Status"
-msgstr ""
-
msgid "Dependencies|The %{codeStartTag}dependency_scanning%{codeEndTag} job has failed and cannot generate the list. Please ensure the job is running properly and run the pipeline again."
msgstr ""
@@ -6862,9 +7167,6 @@ msgstr ""
msgid "Dependencies|Unsupported file(s) detected"
msgstr ""
-msgid "Dependencies|Version"
-msgstr ""
-
msgid "Dependencies|Vulnerable components"
msgstr ""
@@ -6976,12 +7278,18 @@ msgstr ""
msgid "DeployTokens|Add a deploy token"
msgstr ""
+msgid "DeployTokens|Allows read access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows read-only access to the registry images"
msgstr ""
msgid "DeployTokens|Allows read-only access to the repository"
msgstr ""
+msgid "DeployTokens|Allows write access to the package registry"
+msgstr ""
+
msgid "DeployTokens|Allows write access to the registry images"
msgstr ""
@@ -7003,13 +7311,13 @@ msgstr ""
msgid "DeployTokens|Deploy Tokens"
msgstr ""
-msgid "DeployTokens|Deploy tokens allow access to your repository and registry images."
+msgid "DeployTokens|Deploy tokens allow access to packages, your repository, and registry images."
msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
-msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
+msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
@@ -7129,10 +7437,10 @@ msgstr ""
msgid "DesignManagement|%{filename} did not change."
msgstr ""
-msgid "DesignManagement|Add designs"
+msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
-msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
+msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
@@ -7141,9 +7449,24 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
+msgid "DesignManagement|Cancel changes"
+msgstr ""
+
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
+msgid "DesignManagement|Cancel comment update confirmation"
+msgstr ""
+
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
+msgid "DesignManagement|Comment"
+msgstr ""
+
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7153,6 +7476,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
+msgid "DesignManagement|Could not update note. Please try again."
+msgstr ""
+
msgid "DesignManagement|Delete"
msgstr ""
@@ -7180,12 +7506,27 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
+msgid "DesignManagement|Keep changes"
+msgstr ""
+
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
+msgid "DesignManagement|Save comment"
+msgstr ""
+
msgid "DesignManagement|Select all"
msgstr ""
@@ -7195,6 +7536,12 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
+msgid "DesignManagement|Upload designs"
+msgstr ""
+
msgid "DesignManagement|Upload skipped."
msgstr ""
@@ -7207,6 +7554,9 @@ msgstr ""
msgid "Destroy"
msgstr ""
+msgid "Detail"
+msgstr ""
+
msgid "Details"
msgstr ""
@@ -7433,6 +7783,9 @@ msgstr ""
msgid "Don't have an account yet?"
msgstr ""
+msgid "Don't include description in commit message"
+msgstr ""
+
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
@@ -7481,6 +7834,9 @@ msgstr ""
msgid "Download license"
msgstr ""
+msgid "Download raw data (.csv)"
+msgstr ""
+
msgid "Download source code"
msgstr ""
@@ -7505,6 +7861,9 @@ msgstr ""
msgid "Drop your designs to start your upload."
msgstr ""
+msgid "Due Date"
+msgstr ""
+
msgid "Due date"
msgstr ""
@@ -7652,6 +8011,9 @@ msgstr ""
msgid "Email address"
msgstr ""
+msgid "Email could not be sent"
+msgstr ""
+
msgid "Email display name"
msgstr ""
@@ -7667,6 +8029,9 @@ msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
+msgid "Email sent"
+msgstr ""
+
msgid "Email the pipelines status to a list of recipients."
msgstr ""
@@ -7760,6 +8125,9 @@ msgstr ""
msgid "Enable Seat Link"
msgstr ""
+msgid "Enable Spam Check via external API endpoint"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -7769,9 +8137,6 @@ msgstr ""
msgid "Enable and configure Grafana."
msgstr ""
-msgid "Enable and configure InfluxDB metrics."
-msgstr ""
-
msgid "Enable and configure Prometheus metrics."
msgstr ""
@@ -7799,6 +8164,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
+msgid "Enable integration"
+msgstr ""
+
msgid "Enable maintenance mode"
msgstr ""
@@ -7922,6 +8290,9 @@ msgstr ""
msgid "Enter merge request URLs"
msgstr ""
+msgid "Enter new %{field_title}"
+msgstr ""
+
msgid "Enter new AWS Secret Access Key"
msgstr ""
@@ -7946,10 +8317,10 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
-msgid "Enter your password to approve"
+msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
-msgid "Enter zen mode"
+msgid "Enter your password to approve"
msgstr ""
msgid "Environment"
@@ -8006,7 +8377,7 @@ msgstr ""
msgid "EnvironmentsDashboard|More actions"
msgstr ""
-msgid "EnvironmentsDashboard|Read more."
+msgid "EnvironmentsDashboard|More information"
msgstr ""
msgid "EnvironmentsDashboard|Remove"
@@ -8219,10 +8590,10 @@ msgstr ""
msgid "Epics, Issues, and Merge Requests"
msgstr ""
-msgid "Epics|Add an epic"
+msgid "Epics|Add a new epic"
msgstr ""
-msgid "Epics|Add an existing epic as a child epic."
+msgid "Epics|Add an existing epic"
msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
@@ -8234,12 +8605,6 @@ msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
-msgid "Epics|Create an epic within this group and add it as a child epic."
-msgstr ""
-
-msgid "Epics|Create new epic"
-msgstr ""
-
msgid "Epics|How can I solve this?"
msgstr ""
@@ -8309,7 +8674,16 @@ msgstr ""
msgid "Error creating label."
msgstr ""
-msgid "Error deleting %{issuableType}"
+msgid "Error creating new iteration"
+msgstr ""
+
+msgid "Error creating repository for snippet with id %{snippet_id}"
+msgstr ""
+
+msgid "Error creating the snippet"
+msgstr ""
+
+msgid "Error deleting %{issuableType}"
msgstr ""
msgid "Error deleting project. Check logs for error details."
@@ -8414,9 +8788,6 @@ msgstr ""
msgid "Error rendering markdown preview"
msgstr ""
-msgid "Error rendering query"
-msgstr ""
-
msgid "Error saving label update."
msgstr ""
@@ -8432,6 +8803,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
+msgid "Error updating the snippet"
+msgstr ""
+
msgid "Error uploading file"
msgstr ""
@@ -8483,10 +8857,10 @@ msgstr ""
msgid "Errors:"
msgstr ""
-msgid "Estimated"
+msgid "Estimate"
msgstr ""
-msgid "Event Actions"
+msgid "Estimated"
msgstr ""
msgid "EventFilterBy|Filter by all"
@@ -8528,13 +8902,13 @@ msgstr ""
msgid "Every day"
msgstr ""
-msgid "Every day (at 4:00am)"
+msgid "Every day (at %{time})"
msgstr ""
msgid "Every month"
msgstr ""
-msgid "Every month (on the 1st at 4:00am)"
+msgid "Every month (Day %{day} at %{time})"
msgstr ""
msgid "Every three months"
@@ -8546,7 +8920,7 @@ msgstr ""
msgid "Every week"
msgstr ""
-msgid "Every week (Sundays at 4:00am)"
+msgid "Every week (%{weekday} at %{time})"
msgstr ""
msgid "Everyone"
@@ -8585,6 +8959,9 @@ msgstr ""
msgid "Exactly one of %{attributes} is required"
msgstr ""
+msgid "Example: <code>acme.com,acme.co.in,acme.uk</code>."
+msgstr ""
+
msgid "Example: @sub\\.company\\.com$"
msgstr ""
@@ -8603,6 +8980,9 @@ msgstr ""
msgid "Existing members and groups"
msgstr ""
+msgid "Existing projects may be moved into a group"
+msgstr ""
+
msgid "Existing projects will be able to use expiration policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
@@ -8636,6 +9016,9 @@ msgstr ""
msgid "Expand up"
msgstr ""
+msgid "Experienced"
+msgstr ""
+
msgid "Expiration"
msgstr ""
@@ -8651,6 +9034,9 @@ msgstr ""
msgid "Expired %{expiredOn}"
msgstr ""
+msgid "Expired:"
+msgstr ""
+
msgid "Expires"
msgstr ""
@@ -8660,6 +9046,9 @@ msgstr ""
msgid "Expires in %{expires_at}"
msgstr ""
+msgid "Expires on"
+msgstr ""
+
msgid "Expires:"
msgstr ""
@@ -8738,18 +9127,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
-msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
-msgstr ""
-
-msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
-msgstr ""
-
-msgid "ExternalMetrics|External Dashboard"
-msgstr ""
-
-msgid "ExternalMetrics|Full dashboard URL"
-msgstr ""
-
msgid "ExternalWikiService|External Wiki"
msgstr ""
@@ -8876,6 +9253,9 @@ msgstr ""
msgid "Failed to protect the environment"
msgstr ""
+msgid "Failed to publish issue on status page."
+msgstr ""
+
msgid "Failed to remove a Zoom meeting"
msgstr ""
@@ -8951,7 +9331,7 @@ msgstr ""
msgid "Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged."
msgstr ""
-msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch or merge target branch into source branch to allow this merge request to be merged."
+msgid "Fast-forward merge is not possible. Rebase the source branch onto the target branch."
msgstr ""
msgid "Fast-forward merge without a merge commit"
@@ -9014,6 +9394,12 @@ msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
+msgid "FeatureFlags|Edit Feature Flag User List"
+msgstr ""
+
+msgid "FeatureFlags|Edit list"
+msgstr ""
+
msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments."
msgstr ""
@@ -9026,6 +9412,9 @@ msgstr ""
msgid "FeatureFlags|Feature Flag"
msgstr ""
+msgid "FeatureFlags|Feature Flag User List Details"
+msgstr ""
+
msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}."
msgstr ""
@@ -9035,15 +9424,24 @@ msgstr ""
msgid "FeatureFlags|Feature Flags"
msgstr ""
+msgid "FeatureFlags|Feature Flags will look different in the next milestone. No action is needed, but you may notice the functionality was changed to improve the workflow."
+msgstr ""
+
msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?"
msgstr ""
msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality."
msgstr ""
+msgid "FeatureFlags|Flag becomes read only soon"
+msgstr ""
+
msgid "FeatureFlags|Get started with feature flags"
msgstr ""
+msgid "FeatureFlags|GitLab is moving to a new way of managing feature flags, and in 13.4, this feature flag will become read-only. Please create a new feature flag."
+msgstr ""
+
msgid "FeatureFlags|ID"
msgstr ""
@@ -9062,6 +9460,9 @@ msgstr ""
msgid "FeatureFlags|Instance ID"
msgstr ""
+msgid "FeatureFlags|List details"
+msgstr ""
+
msgid "FeatureFlags|Loading feature flags"
msgstr ""
@@ -9077,9 +9478,15 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
+msgid "FeatureFlags|New Feature Flag User List"
+msgstr ""
+
msgid "FeatureFlags|New feature flag"
msgstr ""
+msgid "FeatureFlags|New list"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -9170,6 +9577,9 @@ msgstr ""
msgid "File deleted"
msgstr ""
+msgid "File format is no longer supported"
+msgstr ""
+
msgid "File hooks are similar to system hooks but are executed as files instead of sending data to a URL."
msgstr ""
@@ -9182,6 +9592,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File renamed with no changes."
+msgstr ""
+
msgid "File sync capacity"
msgstr ""
@@ -9191,9 +9604,6 @@ msgstr ""
msgid "File upload error."
msgstr ""
-msgid "File:"
-msgstr ""
-
msgid "Files"
msgstr ""
@@ -9209,24 +9619,45 @@ msgstr ""
msgid "Filter"
msgstr ""
-msgid "Filter by %{issuable_type} that are currently archived."
-msgstr ""
-
msgid "Filter by %{issuable_type} that are currently closed."
msgstr ""
msgid "Filter by %{issuable_type} that are currently opened."
msgstr ""
+msgid "Filter by %{page_context_word} that are currently opened."
+msgstr ""
+
+msgid "Filter by Git revision"
+msgstr ""
+
msgid "Filter by commit message"
msgstr ""
+msgid "Filter by issues that are currently closed."
+msgstr ""
+
+msgid "Filter by label"
+msgstr ""
+
+msgid "Filter by merge requests that are currently closed and unmerged."
+msgstr ""
+
+msgid "Filter by merge requests that are currently merged."
+msgstr ""
+
msgid "Filter by milestone name"
msgstr ""
msgid "Filter by name"
msgstr ""
+msgid "Filter by requirements that are currently archived."
+msgstr ""
+
+msgid "Filter by requirements that are currently opened."
+msgstr ""
+
msgid "Filter by status"
msgstr ""
@@ -9236,6 +9667,9 @@ msgstr ""
msgid "Filter by user"
msgstr ""
+msgid "Filter pipelines"
+msgstr ""
+
msgid "Filter projects"
msgstr ""
@@ -9467,9 +9901,6 @@ msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
-msgid "From project"
-msgstr ""
-
msgid "From the Kubernetes cluster details view, install Runner from the applications list"
msgstr ""
@@ -9509,15 +9940,15 @@ msgstr ""
msgid "Geo"
msgstr "Geo"
-msgid "Geo Designs"
-msgstr ""
-
msgid "Geo Nodes"
msgstr ""
msgid "Geo Nodes|Cannot remove a primary node if there is a secondary node"
msgstr ""
+msgid "Geo Replication"
+msgstr ""
+
msgid "Geo Settings"
msgstr ""
@@ -9695,6 +10126,12 @@ msgstr ""
msgid "GeoNodes|secondary nodes"
msgstr ""
+msgid "Geo|%{label} can't be blank"
+msgstr ""
+
+msgid "Geo|%{label} should be between 1-999"
+msgstr ""
+
msgid "Geo|%{name} is scheduled for forced re-download"
msgstr ""
@@ -9704,10 +10141,10 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
-msgid "Geo|All"
+msgid "Geo|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 ""
-msgid "Geo|All %{replicable_type}"
+msgid "Geo|All %{replicable_name}"
msgstr ""
msgid "Geo|All projects"
@@ -9758,6 +10195,12 @@ msgstr ""
msgid "Geo|Next sync scheduled at"
msgstr ""
+msgid "Geo|Node name can't be blank"
+msgstr ""
+
+msgid "Geo|Node name should be between 1 and 255 characters"
+msgstr ""
+
msgid "Geo|Not synced yet"
msgstr ""
@@ -9809,6 +10252,9 @@ msgstr ""
msgid "Geo|Reverify all"
msgstr ""
+msgid "Geo|Review replication status, and resynchronize and reverify items with the primary node."
+msgstr ""
+
msgid "Geo|Status"
msgstr ""
@@ -9827,6 +10273,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
+msgid "Geo|There are no %{replicable_type} to show"
+msgstr ""
+
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
@@ -9836,6 +10285,12 @@ msgstr ""
msgid "Geo|Tracking entry for upload (%{type}/%{id}) was successfully removed."
msgstr ""
+msgid "Geo|URL can't be blank"
+msgstr ""
+
+msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
+msgstr ""
+
msgid "Geo|Unknown state"
msgstr ""
@@ -10088,9 +10543,6 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
-msgid "Gitlab CI/CD"
-msgstr ""
-
msgid "Gitlab Pages"
msgstr ""
@@ -10124,9 +10576,6 @@ msgstr ""
msgid "Go full screen"
msgstr ""
-msgid "Go to"
-msgstr ""
-
msgid "Go to %{link_to_google_takeout}."
msgstr ""
@@ -10289,12 +10738,21 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group %{group_name} couldn't be exported."
+msgstr ""
+
+msgid "Group %{group_name} was exported successfully."
+msgstr ""
+
msgid "Group %{group_name} was scheduled for deletion."
msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group '%{group_name}' is being imported."
+msgstr ""
+
msgid "Group Audit Events"
msgstr ""
@@ -10328,6 +10786,12 @@ msgstr ""
msgid "Group avatar"
msgstr ""
+msgid "Group by:"
+msgstr ""
+
+msgid "Group could not be imported: %{errors}"
+msgstr ""
+
msgid "Group description"
msgstr ""
@@ -10340,10 +10804,13 @@ msgstr ""
msgid "Group export could not be started."
msgstr ""
+msgid "Group export error"
+msgstr ""
+
msgid "Group export link has expired. Please generate a new export from your group settings."
msgstr ""
-msgid "Group export started."
+msgid "Group export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Group has been already marked for deletion"
@@ -10361,10 +10828,13 @@ msgstr ""
msgid "Group members"
msgstr ""
+msgid "Group milestone"
+msgstr ""
+
msgid "Group name"
msgstr ""
-msgid "Group name (Your organization)"
+msgid "Group name (your organization)"
msgstr ""
msgid "Group overview"
@@ -10382,12 +10852,18 @@ msgstr ""
msgid "Group pipeline minutes were successfully reset."
msgstr ""
+msgid "Group project URLs are prefixed with the group namespace"
+msgstr ""
+
msgid "Group requires separate account"
msgstr ""
msgid "Group variables (inherited)"
msgstr ""
+msgid "Group was exported"
+msgstr ""
+
msgid "Group was successfully updated."
msgstr ""
@@ -10454,9 +10930,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for this group."
msgstr ""
-msgid "GroupSAML|Enforce SSO-only membership for this group."
-msgstr ""
-
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgstr ""
@@ -10658,6 +11131,9 @@ msgstr ""
msgid "GroupSettings|You will need to update your local repositories to point to the new location."
msgstr ""
+msgid "GroupSettings|cannot be changed by you"
+msgstr ""
+
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr ""
@@ -10763,6 +11239,9 @@ msgstr ""
msgid "Hashed repository storage paths"
msgstr ""
+msgid "Hashed storage can't be disabled anymore for new projects"
+msgstr ""
+
msgid "Have your users email"
msgstr ""
@@ -10772,6 +11251,9 @@ msgstr ""
msgid "Header message"
msgstr ""
+msgid "Headings"
+msgstr ""
+
msgid "Health"
msgstr ""
@@ -10876,6 +11358,9 @@ msgstr ""
msgid "History of authentications"
msgstr ""
+msgid "Homepage"
+msgstr ""
+
msgid "Hook execution failed. Ensure the group has a project with commits."
msgstr ""
@@ -10885,6 +11370,9 @@ msgstr ""
msgid "Hook was successfully updated."
msgstr ""
+msgid "Hostname"
+msgstr ""
+
msgid "Hour (UTC)"
msgstr ""
@@ -11035,6 +11523,9 @@ msgstr ""
msgid "If enabled, and if object storage is enabled, GitLab will handle Object Storage replication using Geo"
msgstr ""
+msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
+msgstr ""
+
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
msgstr ""
@@ -11044,7 +11535,10 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
-msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
+msgid "If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}."
+msgstr ""
+
+msgid "If you did not recently sign in, you should immediately change your password: %{password_link}."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
@@ -11053,6 +11547,12 @@ msgstr ""
msgid "If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
+msgid "If you recently signed in and recognize the IP address, you may disregard this email."
+msgstr ""
+
+msgid "If you remove this license, GitLab will fall back on the previous license, if any."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr ""
@@ -11065,7 +11565,10 @@ msgstr ""
msgid "Ignored"
msgstr ""
-msgid "Image: %{image}"
+msgid "Image Details"
+msgstr ""
+
+msgid "Image URL"
msgstr ""
msgid "ImageDiffViewer|2-up"
@@ -11083,13 +11586,13 @@ msgstr ""
msgid "ImageViewerDimensions|W"
msgstr ""
-msgid "Impersonation has been disabled"
+msgid "Impersonation Tokens"
msgstr ""
-msgid "Import"
+msgid "Impersonation has been disabled"
msgstr ""
-msgid "Import %{status}"
+msgid "Import"
msgstr ""
msgid "Import CSV"
@@ -11101,6 +11604,9 @@ msgstr ""
msgid "Import all compatible projects"
msgstr ""
+msgid "Import all compatible repositories"
+msgstr ""
+
msgid "Import all projects"
msgstr ""
@@ -11110,6 +11616,9 @@ msgstr ""
msgid "Import an exported GitLab project"
msgstr ""
+msgid "Import failed due to a GitHub error: %{original}"
+msgstr ""
+
msgid "Import from"
msgstr ""
@@ -11119,10 +11628,10 @@ msgstr ""
msgid "Import in progress"
msgstr ""
-msgid "Import issues"
+msgid "Import in progress. Refresh page to see newly added issues."
msgstr ""
-msgid "Import issues from Jira"
+msgid "Import issues"
msgstr ""
msgid "Import members"
@@ -11215,10 +11724,10 @@ msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
-msgid "Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
msgstr ""
-msgid "Improve search with Advanced Global Search and GitLab Enterprise Edition."
+msgid "In %{time_to_now}"
msgstr ""
msgid "In order to enable instance-level analytics, please ask an admin to enable %{usage_ping_link_start}usage ping%{usage_ping_link_end}."
@@ -11251,6 +11760,9 @@ msgstr ""
msgid "Include author name in notification email body"
msgstr ""
+msgid "Include description in commit message"
+msgstr ""
+
msgid "Include merge request description"
msgstr ""
@@ -11284,6 +11796,12 @@ msgstr ""
msgid "Incompatible options set!"
msgstr ""
+msgid "Incompatible project"
+msgstr ""
+
+msgid "Indent"
+msgstr ""
+
msgid "Index all projects"
msgstr ""
@@ -11308,18 +11826,36 @@ msgstr ""
msgid "Input your repository URL"
msgstr ""
+msgid "Insert"
+msgstr ""
+
+msgid "Insert a code block"
+msgstr ""
+
msgid "Insert a quote"
msgstr ""
+msgid "Insert an image"
+msgstr ""
+
msgid "Insert code"
msgstr ""
+msgid "Insert inline code"
+msgstr ""
+
msgid "Insert suggestion"
msgstr ""
msgid "Insights"
msgstr ""
+msgid "Insights|Some items are not visible beacuse the project was filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
+msgid "Insights|This project is filtered out in the insights.yml file (see the projects.only config for more information)."
+msgstr ""
+
msgid "Install"
msgstr ""
@@ -11369,6 +11905,30 @@ msgstr ""
msgid "Integrations allow you to integrate GitLab with other applications"
msgstr ""
+msgid "Integrations|All details"
+msgstr ""
+
+msgid "Integrations|Comment detail:"
+msgstr ""
+
+msgid "Integrations|Comment settings:"
+msgstr ""
+
+msgid "Integrations|Enable comments"
+msgstr ""
+
+msgid "Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs"
+msgstr ""
+
+msgid "Integrations|Includes commit title and branch"
+msgstr ""
+
+msgid "Integrations|Standard"
+msgstr ""
+
+msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
+msgstr ""
+
msgid "Interested parties can even contribute by pushing commits if they want to."
msgstr ""
@@ -11408,6 +11968,12 @@ msgstr ""
msgid "Invalid URL"
msgstr ""
+msgid "Invalid container_name"
+msgstr ""
+
+msgid "Invalid cursor parameter"
+msgstr ""
+
msgid "Invalid cursor value provided"
msgstr ""
@@ -11444,18 +12010,27 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid pod_name"
+msgstr ""
+
msgid "Invalid query"
msgstr ""
msgid "Invalid repository path"
msgstr ""
+msgid "Invalid search parameter"
+msgstr ""
+
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
+msgid "Invalid status"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -11468,6 +12043,9 @@ msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
+msgid "Invite Members"
+msgstr ""
+
msgid "Invite group"
msgstr ""
@@ -11531,6 +12109,9 @@ msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
+msgid "Issue published on status page."
+msgstr ""
+
msgid "Issue template (optional)"
msgstr ""
@@ -11543,6 +12124,33 @@ msgstr ""
msgid "Issue weight"
msgstr ""
+msgid "IssueAnalytics|Age"
+msgstr ""
+
+msgid "IssueAnalytics|Assignees"
+msgstr ""
+
+msgid "IssueAnalytics|Due date"
+msgstr ""
+
+msgid "IssueAnalytics|Failed to load issues. Please try again."
+msgstr ""
+
+msgid "IssueAnalytics|Issue"
+msgstr ""
+
+msgid "IssueAnalytics|Milestone"
+msgstr ""
+
+msgid "IssueAnalytics|Opened by"
+msgstr ""
+
+msgid "IssueAnalytics|Status"
+msgstr ""
+
+msgid "IssueAnalytics|Weight"
+msgstr ""
+
msgid "IssueBoards|Board"
msgstr ""
@@ -11600,6 +12208,9 @@ msgstr ""
msgid "Issues referenced by merge requests and commits within the default branch will be closed automatically"
msgstr ""
+msgid "Issues successfully imported with the label"
+msgstr ""
+
msgid "Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities"
msgstr ""
@@ -11645,6 +12256,30 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Iteration changed to"
+msgstr ""
+
+msgid "Iteration removed"
+msgstr ""
+
+msgid "Iterations"
+msgstr ""
+
+msgid "Iteration|Dates cannot overlap with other existing Iterations"
+msgstr ""
+
+msgid "Iteration|cannot be in the past"
+msgstr ""
+
+msgid "Iteration|cannot be more than 500 years in the future"
+msgstr ""
+
+msgid "I’m familiar with the basics of project management and DevOps."
+msgstr ""
+
+msgid "I’m not very familiar with the basics of project management and DevOps."
+msgstr ""
+
msgid "Jaeger URL"
msgstr ""
@@ -11657,19 +12292,22 @@ msgstr "1月"
msgid "January"
msgstr ""
-msgid "Jira Issue Import"
+msgid "Jira import is already running."
msgstr ""
-msgid "Jira import feature is disabled."
+msgid "Jira integration not configured."
msgstr ""
-msgid "Jira import is already running."
+msgid "Jira project: %{importProject}"
msgstr ""
-msgid "Jira integration not configured."
+msgid "Jira service not configured."
msgstr ""
-msgid "Jira project: %{importProject}"
+msgid "JiraService| on branch %{branch_link}"
+msgstr ""
+
+msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
@@ -11795,6 +12433,9 @@ msgstr ""
msgid "Job|The artifacts will be removed"
msgstr ""
+msgid "Job|These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available."
+msgstr ""
+
msgid "Job|This job failed because the necessary resources were not successfully created."
msgstr ""
@@ -11834,6 +12475,9 @@ msgstr "6月"
msgid "Just me"
msgstr ""
+msgid "Keep divergent refs"
+msgstr ""
+
msgid "Key"
msgstr "金鑰"
@@ -12012,6 +12656,9 @@ msgstr ""
msgid "Last reply by"
msgstr ""
+msgid "Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages."
+msgstr ""
+
msgid "Last repository check run"
msgstr ""
@@ -12096,6 +12743,9 @@ msgstr ""
msgid "Learn more about Web Terminal"
msgstr ""
+msgid "Learn more about X.509 signed commits"
+msgstr ""
+
msgid "Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}."
msgstr ""
@@ -12117,9 +12767,6 @@ msgstr ""
msgid "Learn more about the dependency list"
msgstr ""
-msgid "Learn more about x509 signed commits"
-msgstr ""
-
msgid "Learn more in the"
msgstr ""
@@ -12147,6 +12794,9 @@ msgstr ""
msgid "Leave the \"File type\" and \"Delivery method\" options on their default values."
msgstr ""
+msgid "Leave zen mode"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -12159,6 +12809,9 @@ msgstr ""
msgid "License Compliance"
msgstr ""
+msgid "License History"
+msgstr ""
+
msgid "License-Check"
msgstr ""
@@ -12183,15 +12836,9 @@ msgstr ""
msgid "LicenseCompliance|Deny"
msgstr ""
-msgid "LicenseCompliance|Here you can allow or deny licenses for this project. Using %{ci} or %{license} will allow you to see if there are any unmanaged licenses and allow or deny them in merge request."
-msgstr ""
-
msgid "LicenseCompliance|License"
msgstr ""
-msgid "LicenseCompliance|License Compliance"
-msgstr ""
-
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] ""
@@ -12322,6 +12969,9 @@ msgstr ""
msgid "License|License"
msgstr ""
+msgid "License|Licensed user count exceeded"
+msgstr ""
+
msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr ""
@@ -12337,6 +12987,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr ""
+msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
+msgstr ""
+
msgid "Limit display of time tracking units to hours."
msgstr ""
@@ -12431,6 +13084,9 @@ msgstr ""
msgid "Loading…"
msgstr ""
+msgid "Local IP addresses and domain names that hooks and services may access."
+msgstr ""
+
msgid "Localization"
msgstr ""
@@ -12545,10 +13201,10 @@ msgstr ""
msgid "Make sure you're logged into the account that owns the projects you'd like to import."
msgstr ""
-msgid "Makes this issue confidential."
+msgid "Make this epic confidential"
msgstr ""
-msgid "Malformed string"
+msgid "Makes this issue confidential."
msgstr ""
msgid "Manage"
@@ -12575,6 +13231,9 @@ msgstr ""
msgid "Manage labels"
msgstr ""
+msgid "Manage milestones"
+msgstr ""
+
msgid "Manage project labels"
msgstr ""
@@ -12626,9 +13285,6 @@ msgstr ""
msgid "Mark as resolved"
msgstr ""
-msgid "Mark comment as resolved"
-msgstr ""
-
msgid "Mark this issue as a duplicate of another issue"
msgstr ""
@@ -12638,9 +13294,6 @@ msgstr ""
msgid "Markdown"
msgstr ""
-msgid "Markdown Help"
-msgstr ""
-
msgid "Markdown enabled"
msgstr ""
@@ -12818,6 +13471,9 @@ msgstr ""
msgid "Members of <strong>%{project_name}</strong>"
msgstr ""
+msgid "Members of a group may only view projects they have permission to access"
+msgstr ""
+
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
msgstr ""
@@ -12827,9 +13483,6 @@ msgstr ""
msgid "Memory Usage"
msgstr ""
-msgid "Memory limit exceeded while rendering template"
-msgstr ""
-
msgid "Merge"
msgstr ""
@@ -12842,6 +13495,9 @@ msgstr ""
msgid "Merge Request Approvals"
msgstr ""
+msgid "Merge Request Commits"
+msgstr ""
+
msgid "Merge Requests"
msgstr ""
@@ -12875,6 +13531,9 @@ msgstr ""
msgid "Merge request %{iid} authored by %{authorName}"
msgstr ""
+msgid "Merge request %{mr_link} was reviewed by %{mr_author}"
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
@@ -12923,9 +13582,18 @@ msgstr ""
msgid "MergeConflict|origin//their changes"
msgstr ""
+msgid "MergeRequestDiffs|Commenting on lines %{selectStart}start%{selectEnd} to %{end}"
+msgstr ""
+
+msgid "MergeRequestDiffs|Select comment starting line"
+msgstr ""
+
msgid "MergeRequests|Add a reply"
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 ""
@@ -12986,7 +13654,7 @@ msgstr ""
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
msgstr ""
-msgid "MergeRequest|Compare %{source} and %{target}"
+msgid "MergeRequest|Compare %{target} and %{source}"
msgstr ""
msgid "MergeRequest|Error dismissing suggestion popover. Please try again."
@@ -13004,6 +13672,9 @@ msgstr ""
msgid "Merged"
msgstr ""
+msgid "Merged MRs"
+msgstr ""
+
msgid "Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes."
msgstr ""
@@ -13025,9 +13696,6 @@ msgstr ""
msgid "Method"
msgstr ""
-msgid "Method:"
-msgstr ""
-
msgid "Metric was successfully added."
msgstr ""
@@ -13049,19 +13717,22 @@ msgstr ""
msgid "Metrics - Grafana"
msgstr ""
-msgid "Metrics - Influx"
-msgstr ""
-
msgid "Metrics - Prometheus"
msgstr ""
msgid "Metrics Dashboard"
msgstr ""
-msgid "Metrics and profiling"
+msgid "Metrics Dashboard YAML definition"
+msgstr ""
+
+msgid "Metrics Dashboard YAML definition is invalid:"
msgstr ""
-msgid "Metrics for environment"
+msgid "Metrics Dashboard YAML definition is valid."
+msgstr ""
+
+msgid "Metrics and profiling"
msgstr ""
msgid "Metrics::Dashboard::Annotation|Annotation can't belong to both a cluster and an environment at the same time"
@@ -13085,6 +13756,27 @@ msgstr ""
msgid "Metrics::Dashboard::Annotation|You are not authorized to delete this annotation"
msgstr ""
+msgid "Metrics::Dashboard::Annotation|can't be before starting_at time"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|Dashboard with requested path can not be found"
+msgstr ""
+
+msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
+msgstr ""
+
+msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
+msgstr ""
+
+msgid "MetricsSettings|External dashboard URL"
+msgstr ""
+
+msgid "MetricsSettings|Manage Metrics Dashboard settings."
+msgstr ""
+
+msgid "MetricsSettings|Metrics Dashboard"
+msgstr ""
+
msgid "Metrics|Add metric"
msgstr ""
@@ -13140,6 +13832,12 @@ msgstr ""
msgid "Metrics|Link contains an invalid time window, please verify the link to see the requested time range."
msgstr ""
+msgid "Metrics|Link contains invalid chart information, please verify the link to see the expanded panel."
+msgstr ""
+
+msgid "Metrics|Manage chart links"
+msgstr ""
+
msgid "Metrics|Max"
msgstr ""
@@ -13158,6 +13856,9 @@ msgstr ""
msgid "Metrics|Refresh dashboard"
msgstr ""
+msgid "Metrics|Star dashboard"
+msgstr ""
+
msgid "Metrics|There was an error creating the dashboard."
msgstr ""
@@ -13194,6 +13895,9 @@ msgstr ""
msgid "Metrics|Unit label"
msgstr ""
+msgid "Metrics|Unstar dashboard"
+msgstr ""
+
msgid "Metrics|Used as a title for the chart"
msgstr ""
@@ -13255,6 +13959,63 @@ msgstr ""
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
+msgid "MilestoneSidebar|Closed:"
+msgstr ""
+
+msgid "MilestoneSidebar|Copy reference"
+msgstr ""
+
+msgid "MilestoneSidebar|Due date"
+msgstr ""
+
+msgid "MilestoneSidebar|Edit"
+msgstr ""
+
+msgid "MilestoneSidebar|From"
+msgstr ""
+
+msgid "MilestoneSidebar|Issues"
+msgstr ""
+
+msgid "MilestoneSidebar|Merge requests"
+msgstr ""
+
+msgid "MilestoneSidebar|Merged:"
+msgstr ""
+
+msgid "MilestoneSidebar|New Issue"
+msgstr ""
+
+msgid "MilestoneSidebar|New issue"
+msgstr ""
+
+msgid "MilestoneSidebar|No due date"
+msgstr ""
+
+msgid "MilestoneSidebar|No start date"
+msgstr ""
+
+msgid "MilestoneSidebar|None"
+msgstr ""
+
+msgid "MilestoneSidebar|Open:"
+msgstr ""
+
+msgid "MilestoneSidebar|Reference:"
+msgstr ""
+
+msgid "MilestoneSidebar|Start date"
+msgstr ""
+
+msgid "MilestoneSidebar|Toggle sidebar"
+msgstr ""
+
+msgid "MilestoneSidebar|Until"
+msgstr ""
+
+msgid "MilestoneSidebar|complete"
+msgstr ""
+
msgid "Milestones"
msgstr ""
@@ -13264,6 +14025,12 @@ msgstr ""
msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
+msgid "Milestones|Close Milestone"
+msgstr ""
+
+msgid "Milestones|Completed Issues (closed)"
+msgstr ""
+
msgid "Milestones|Delete milestone"
msgstr ""
@@ -13273,21 +14040,39 @@ msgstr ""
msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr ""
+msgid "Milestones|Group Milestone"
+msgstr ""
+
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr ""
+msgid "Milestones|Ongoing Issues (open and assigned)"
+msgstr ""
+
+msgid "Milestones|Project Milestone"
+msgstr ""
+
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr ""
msgid "Milestones|Promote Milestone"
msgstr ""
+msgid "Milestones|Promote to Group Milestone"
+msgstr ""
+
msgid "Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged."
msgstr ""
+msgid "Milestones|Reopen Milestone"
+msgstr ""
+
msgid "Milestones|This action cannot be reversed."
msgstr ""
+msgid "Milestones|Unstarted Issues (open and unassigned)"
+msgstr ""
+
msgid "Minimum capacity to be available before we schedule more mirrors preemptively."
msgstr ""
@@ -13348,6 +14133,9 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgstr ""
+msgid "ModalButton|Add projects"
+msgstr ""
+
msgid "Modal|Cancel"
msgstr ""
@@ -13462,6 +14250,9 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "Multiple domains are supported with comma delimiters."
+msgstr ""
+
msgid "Multiple issue boards"
msgstr ""
@@ -13471,6 +14262,9 @@ msgstr ""
msgid "Multiple uploaders found: %{uploader_types}"
msgstr ""
+msgid "My Awesome Group"
+msgstr ""
+
msgid "My company or team"
msgstr ""
@@ -13483,9 +14277,6 @@ msgstr ""
msgid "Name has already been taken"
msgstr ""
-msgid "Name must be between 1 and 255 characters"
-msgstr ""
-
msgid "Name new label"
msgstr ""
@@ -13495,9 +14286,6 @@ msgstr ""
msgid "Namespace is empty"
msgstr ""
-msgid "Namespace: %{namespace}"
-msgstr ""
-
msgid "Namespaces to index"
msgstr ""
@@ -13531,6 +14319,54 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "NetworkPolicies|Choose whether to enforce this policy."
+msgstr ""
+
+msgid "NetworkPolicies|Define this policy's location, conditions and actions."
+msgstr ""
+
+msgid "NetworkPolicies|Enforcement status"
+msgstr ""
+
+msgid "NetworkPolicies|Environment does not have deployment platform"
+msgstr ""
+
+msgid "NetworkPolicies|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 "NetworkPolicies|Invalid or empty policy"
+msgstr ""
+
+msgid "NetworkPolicies|Kubernetes error: %{error}"
+msgstr ""
+
+msgid "NetworkPolicies|Last modified"
+msgstr ""
+
+msgid "NetworkPolicies|Name"
+msgstr ""
+
+msgid "NetworkPolicies|No policies detected"
+msgstr ""
+
+msgid "NetworkPolicies|Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints."
+msgstr ""
+
+msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
+msgstr ""
+
+msgid "NetworkPolicies|Policy definition"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, failed to update policy"
+msgstr ""
+
+msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
+msgstr ""
+
+msgid "NetworkPolicies|Status"
+msgstr ""
+
msgid "Never"
msgstr ""
@@ -13559,6 +14395,9 @@ msgid "New Issue"
msgid_plural "New Issues"
msgstr[0] ""
+msgid "New Iteration"
+msgstr ""
+
msgid "New Jira import"
msgstr ""
@@ -13625,6 +14464,9 @@ msgstr ""
msgid "New issue title"
msgstr ""
+msgid "New iteration created"
+msgstr ""
+
msgid "New label"
msgstr ""
@@ -13682,6 +14524,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Next commit"
+msgstr ""
+
msgid "Next file in diff"
msgstr ""
@@ -13700,18 +14545,9 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
-msgid "No %{replicableType} match this filter"
-msgstr ""
-
msgid "No Epic"
msgstr ""
-msgid "No Label"
-msgstr ""
-
-msgid "No Milestone"
-msgstr ""
-
msgid "No Scopes"
msgstr ""
@@ -13802,12 +14638,18 @@ msgstr ""
msgid "No forks are available to you."
msgstr ""
+msgid "No grouping"
+msgstr ""
+
msgid "No job log"
msgstr ""
msgid "No jobs to show"
msgstr ""
+msgid "No label"
+msgstr ""
+
msgid "No labels with such name or description"
msgstr ""
@@ -13832,6 +14674,9 @@ msgstr ""
msgid "No messages were logged"
msgstr ""
+msgid "No milestone"
+msgstr ""
+
msgid "No milestones to show"
msgstr ""
@@ -13967,6 +14812,9 @@ msgstr ""
msgid "Note parameters are invalid: %{errors}"
msgstr ""
+msgid "Note that PostgreSQL 11 will become the minimum required PostgreSQL version in GitLab 13.0 (May 2020). PostgreSQL 9.6 and PostgreSQL 10 will no longer be supported in GitLab 13.0. Please consider upgrading your PostgreSQL version (%{db_version}) soon."
+msgstr ""
+
msgid "Note that 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 ""
@@ -13991,6 +14839,9 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
+msgid "Notes|Private comments are accessible by internal staff only"
+msgstr ""
+
msgid "Notes|Show all activity"
msgstr ""
@@ -14105,9 +14956,15 @@ msgstr "11月"
msgid "November"
msgstr ""
+msgid "Novice"
+msgstr ""
+
msgid "Now you can access the merge request navigation tabs at the top, where they’re easier to find."
msgstr ""
+msgid "Nuget metadatum must have at least license_url, project_url or icon_url set"
+msgstr ""
+
msgid "Number of %{itemTitle}"
msgstr ""
@@ -14174,6 +15031,15 @@ msgstr ""
msgid "On track"
msgstr ""
+msgid "OnDemandScans|Create new DAST scan"
+msgstr ""
+
+msgid "OnDemandScans|On-demand Scans"
+msgstr ""
+
+msgid "OnDemandScans|Schedule or run scans immediately against target sites. Currently available on-demand scan type: DAST. %{helpLinkStart}More information%{helpLinkEnd}"
+msgstr ""
+
msgid "Onboarding"
msgstr ""
@@ -14183,9 +15049,6 @@ msgstr ""
msgid "Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source."
msgstr ""
-msgid "Once the exported file is ready you can download it from this page."
-msgstr ""
-
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 ""
@@ -14250,7 +15113,7 @@ msgstr ""
msgid "Only project members will be imported. Group members will be skipped."
msgstr ""
-msgid "Only users with an email address in this domain can be added to the group.<br>Example: <code>gitlab.com</code>. Some common domains are not allowed. %{read_more_link}."
+msgid "Only verified users with an email address in any of these domains can be added to the group."
msgstr ""
msgid "Only ‘Reporter’ roles and above on tiers Premium / Silver and above can see Productivity Analytics."
@@ -14295,7 +15158,7 @@ msgstr ""
msgid "Opened"
msgstr ""
-msgid "Opened MR"
+msgid "Opened MRs"
msgstr ""
msgid "Opened issues"
@@ -14310,6 +15173,9 @@ msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
+msgid "Operation not allowed"
+msgstr ""
+
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -14340,7 +15206,7 @@ msgstr ""
msgid "Optional"
msgstr ""
-msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]"
+msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
@@ -14388,6 +15254,9 @@ msgstr ""
msgid "OutdatedBrowser|You can provide feedback %{feedback_link_start}on this issue%{feedback_link_end} or via your usual support channels."
msgstr ""
+msgid "Outdent"
+msgstr ""
+
msgid "Overridden"
msgstr ""
@@ -14406,6 +15275,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Package Files"
+msgstr ""
+
msgid "Package Registry"
msgstr ""
@@ -14427,6 +15299,12 @@ msgstr ""
msgid "Package type must be Maven"
msgstr ""
+msgid "Package type must be NuGet"
+msgstr ""
+
+msgid "Package type must be PyPi"
+msgstr ""
+
msgid "Package was removed"
msgstr ""
@@ -14514,6 +15392,9 @@ msgstr ""
msgid "PackageRegistry|Installation"
msgstr ""
+msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar."
+msgstr ""
+
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
msgstr ""
@@ -14532,6 +15413,9 @@ msgstr ""
msgid "PackageRegistry|NPM"
msgstr ""
+msgid "PackageRegistry|No upcoming issues"
+msgstr ""
+
msgid "PackageRegistry|NuGet"
msgstr ""
@@ -14562,22 +15446,37 @@ msgstr ""
msgid "PackageRegistry|There are no %{packageType} packages yet"
msgstr ""
+msgid "PackageRegistry|There are no other versions of this package."
+msgstr ""
+
msgid "PackageRegistry|There are no packages yet"
msgstr ""
+msgid "PackageRegistry|There are no upcoming issues to display."
+msgstr ""
+
msgid "PackageRegistry|There was a problem fetching the details for this package."
msgstr ""
+msgid "PackageRegistry|This NuGet package has no dependencies."
+msgstr ""
+
msgid "PackageRegistry|To widen your search, change or remove the filters above."
msgstr ""
+msgid "PackageRegistry|Unable to fetch package version information."
+msgstr ""
+
msgid "PackageRegistry|Unable to load package"
msgstr ""
-msgid "PackageRegistry|You are about to delete <b>%{packageName}</b>, this operation is irreversible, are you sure?"
+msgid "PackageRegistry|Upcoming package managers"
+msgstr ""
+
+msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
msgstr ""
-msgid "PackageRegistry|You are about to delete version %{boldStart}%{version}%{boldEnd} of %{boldStart}%{name}%{boldEnd}. Are you sure?"
+msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
msgstr ""
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
@@ -14610,6 +15509,9 @@ msgstr ""
msgid "Packages"
msgstr ""
+msgid "Packages & Registries"
+msgstr ""
+
msgid "Page not found"
msgstr ""
@@ -14697,6 +15599,9 @@ msgstr ""
msgid "Password was successfully updated. Please login with it"
msgstr ""
+msgid "Passwords should be unique and not used for any other sites or services."
+msgstr ""
+
msgid "Past due"
msgstr ""
@@ -14715,6 +15620,9 @@ 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'. Don't use your private SSH key."
msgstr ""
+msgid "Patch to apply"
+msgstr ""
+
msgid "Path"
msgstr ""
@@ -14757,9 +15665,15 @@ msgstr ""
msgid "Performance optimization"
msgstr ""
+msgid "PerformanceBar|Bullet notifications"
+msgstr ""
+
msgid "PerformanceBar|Download"
msgstr ""
+msgid "PerformanceBar|Elasticsearch calls"
+msgstr ""
+
msgid "PerformanceBar|Frontend resources"
msgstr ""
@@ -14781,9 +15695,6 @@ msgstr ""
msgid "Permissions"
msgstr ""
-msgid "Permissions Help"
-msgstr ""
-
msgid "Permissions, LFS, 2FA"
msgstr ""
@@ -14805,9 +15716,6 @@ msgstr ""
msgid "Pick a name"
msgstr ""
-msgid "Pick a name for the application, and we'll give you a unique %{type} token."
-msgstr ""
-
msgid "Pin code"
msgstr ""
@@ -14916,6 +15824,9 @@ msgstr ""
msgid "Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more in the documentation for Pipelines for Merged Results."
msgstr ""
+msgid "Pipelines must succeed for merge requests to be eligible to merge. Please enable pipelines for this project to continue. For more information, see the %{linkStart}documentation.%{linkEnd}"
+msgstr ""
+
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -14976,15 +15887,24 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
+msgid "Pipeline|Branch name"
+msgstr ""
+
+msgid "Pipeline|Canceled"
+msgstr ""
+
msgid "Pipeline|Commit"
msgstr ""
-msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation.%{linkEnd}"
+msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "Pipeline|Coverage"
msgstr ""
+msgid "Pipeline|Created"
+msgstr ""
+
msgid "Pipeline|Date"
msgstr ""
@@ -14997,30 +15917,54 @@ msgstr ""
msgid "Pipeline|Existing branch name or tag"
msgstr ""
+msgid "Pipeline|Failed"
+msgstr ""
+
msgid "Pipeline|Key"
msgstr ""
+msgid "Pipeline|Manual"
+msgstr ""
+
msgid "Pipeline|Merge train pipeline"
msgstr ""
msgid "Pipeline|Merged result pipeline"
msgstr ""
+msgid "Pipeline|No pipeline has been run for this commit."
+msgstr ""
+
+msgid "Pipeline|Passed"
+msgstr ""
+
+msgid "Pipeline|Pending"
+msgstr ""
+
msgid "Pipeline|Pipeline"
msgstr ""
msgid "Pipeline|Pipelines"
msgstr ""
+msgid "Pipeline|Raw text search is not currently supported. Please use the available search tokens."
+msgstr ""
+
msgid "Pipeline|Run Pipeline"
msgstr ""
msgid "Pipeline|Run for"
msgstr ""
+msgid "Pipeline|Running"
+msgstr ""
+
msgid "Pipeline|Search branches"
msgstr ""
+msgid "Pipeline|Skipped"
+msgstr ""
+
msgid "Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default."
msgstr ""
@@ -15036,6 +15980,9 @@ msgstr ""
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
msgstr ""
+msgid "Pipeline|Trigger author"
+msgstr ""
+
msgid "Pipeline|Triggerer"
msgstr ""
@@ -15072,6 +16019,12 @@ msgstr ""
msgid "Plain diff"
msgstr ""
+msgid "Plan"
+msgstr ""
+
+msgid "Plan:"
+msgstr ""
+
msgid "PlantUML"
msgstr ""
@@ -15165,6 +16118,9 @@ msgstr ""
msgid "Please provide a name"
msgstr ""
+msgid "Please provide a valid URL"
+msgstr ""
+
msgid "Please provide a valid email address."
msgstr ""
@@ -15240,6 +16196,9 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
+msgid "Pre-defined push rules."
+msgstr ""
+
msgid "Preferences"
msgstr ""
@@ -15330,6 +16289,9 @@ msgstr ""
msgid "Press %{key}-C to copy"
msgstr ""
+msgid "Prev"
+msgstr ""
+
msgid "Prevent adding new members to project membership within this group"
msgstr ""
@@ -15366,6 +16328,9 @@ msgstr ""
msgid "Previous Artifacts"
msgstr ""
+msgid "Previous commit"
+msgstr ""
+
msgid "Previous file in diff"
msgstr ""
@@ -15585,9 +16550,6 @@ msgstr ""
msgid "Profiles|Give your individual key a title"
msgstr ""
-msgid "Profiles|Impersonation"
-msgstr ""
-
msgid "Profiles|Include private contributions on my profile"
msgstr ""
@@ -15633,9 +16595,6 @@ msgstr ""
msgid "Profiles|Path"
msgstr ""
-msgid "Profiles|Personal Access"
-msgstr ""
-
msgid "Profiles|Position and size your new avatar"
msgstr ""
@@ -15780,12 +16739,6 @@ msgstr ""
msgid "Profiles|e.g. My MacBook key"
msgstr ""
-msgid "Profiles|impersonation"
-msgstr ""
-
-msgid "Profiles|personal access"
-msgstr ""
-
msgid "Profiles|username"
msgstr ""
@@ -15816,6 +16769,9 @@ msgstr ""
msgid "Project %{project_repo} could not be found"
msgstr ""
+msgid "Project & Group can not be assigned at the same time"
+msgstr ""
+
msgid "Project '%{project_name}' is being imported."
msgstr ""
@@ -15837,6 +16793,9 @@ msgstr ""
msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
+msgid "Project Access Tokens"
+msgstr ""
+
msgid "Project Audit Events"
msgstr ""
@@ -15867,6 +16826,9 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
+msgid "Project clone URL"
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -15891,7 +16853,7 @@ msgstr ""
msgid "Project export link has expired. Please generate a new export from your project settings."
msgstr ""
-msgid "Project export started. A download link will be sent by email."
+msgid "Project export started. A download link will be sent by email and made available on this page."
msgstr ""
msgid "Project has too many %{label_for_message} to search"
@@ -15900,6 +16862,9 @@ msgstr ""
msgid "Project members"
msgstr ""
+msgid "Project milestone"
+msgstr ""
+
msgid "Project name"
msgstr ""
@@ -16014,9 +16979,6 @@ msgstr ""
msgid "ProjectService|Comment will be posted on each event"
msgstr ""
-msgid "ProjectService|Last edit"
-msgstr ""
-
msgid "ProjectService|Perform common operations on GitLab project: %{project_name}"
msgstr ""
@@ -16182,6 +17144,9 @@ msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
+msgid "ProjectSettings|Show default award emojis"
+msgstr ""
+
msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
msgstr ""
@@ -16227,6 +17192,9 @@ msgstr ""
msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
msgstr ""
+msgid "ProjectSettings|When enabled, issues, merge requests, and snippets will always show thumbs-up and thumbs-down award emoji buttons."
+msgstr ""
+
msgid "ProjectSettings|Wiki"
msgstr ""
@@ -16377,6 +17345,9 @@ msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
+msgid "ProjectsNew|Create"
+msgstr ""
+
msgid "ProjectsNew|Create from template"
msgstr ""
@@ -16470,12 +17441,18 @@ msgstr ""
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
msgstr ""
+msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
+msgstr ""
+
msgid "PrometheusService|Common metrics"
msgstr ""
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
msgstr ""
+msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
+msgstr ""
+
msgid "PrometheusService|Custom metrics"
msgstr ""
@@ -16551,9 +17528,6 @@ msgstr ""
msgid "Promote these project milestones into a group milestone."
msgstr ""
-msgid "Promote to Group Milestone"
-msgstr ""
-
msgid "Promote to group label"
msgstr ""
@@ -16572,30 +17546,84 @@ msgstr ""
msgid "Promoted issue to an epic."
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 ""
+
+msgid "Promotions|Buy EE"
+msgstr ""
+
+msgid "Promotions|Buy GitLab Enterprise Edition"
+msgstr ""
+
+msgid "Promotions|Contact an owner of group %{namespace_name} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact owner %{link_start}%{owner_name}%{link_end} to upgrade the plan."
+msgstr ""
+
+msgid "Promotions|Contact your Administrator to upgrade your license."
+msgstr ""
+
+msgid "Promotions|Dismiss burndown charts promotion"
+msgstr ""
+
msgid "Promotions|Don't show me this again"
msgstr ""
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 ""
+msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
+msgstr ""
+
+msgid "Promotions|Improve milestones with Burndown Charts."
+msgstr ""
+
msgid "Promotions|Learn more"
msgstr ""
+msgid "Promotions|Not now, thanks!"
+msgstr ""
+
msgid "Promotions|See the other features in the %{subscription_link_start}bronze plan%{subscription_link_end}"
msgstr ""
+msgid "Promotions|Start GitLab Ultimate trial"
+msgstr ""
+
msgid "Promotions|This feature is locked."
msgstr ""
+msgid "Promotions|Track activity with Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Try it for free"
+msgstr ""
+
msgid "Promotions|Upgrade plan"
msgstr ""
+msgid "Promotions|Upgrade your plan"
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to activate Contribution Analytics."
+msgstr ""
+
+msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts."
+msgstr ""
+
+msgid "Promotions|Weight"
+msgstr ""
+
msgid "Promotions|Weighting your issue"
msgstr ""
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 ""
+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 ""
+
msgid "Prompt users to upload SSH keys"
msgstr ""
@@ -16731,9 +17759,6 @@ msgstr ""
msgid "Public - The project can be accessed without any authentication."
msgstr ""
-msgid "Public Access Help"
-msgstr ""
-
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
@@ -16743,6 +17768,12 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Publish to status page"
+msgstr ""
+
+msgid "Publishes this issue to the associated status page."
+msgstr ""
+
msgid "Pull"
msgstr ""
@@ -16845,6 +17876,9 @@ msgstr ""
msgid "Queued"
msgstr ""
+msgid "Quick actions"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -16854,9 +17888,6 @@ msgstr ""
msgid "README"
msgstr ""
-msgid "Rake Tasks Help"
-msgstr ""
-
msgid "Raw blob request rate limit per minute"
msgstr ""
@@ -16893,9 +17924,6 @@ msgstr ""
msgid "Receive alerts from manually configured Prometheus servers."
msgstr ""
-msgid "Receive alerts on GitLab from any source"
-msgstr ""
-
msgid "Receive notifications about your own activity"
msgstr ""
@@ -16990,6 +18018,21 @@ msgstr ""
msgid "Registration"
msgstr ""
+msgid "Registration|Checkout"
+msgstr ""
+
+msgid "Registration|Your GitLab group"
+msgstr ""
+
+msgid "Registration|Your first project"
+msgstr ""
+
+msgid "Registration|Your profile"
+msgstr ""
+
+msgid "Rejected (closed)"
+msgstr ""
+
msgid "Related Deployed Jobs"
msgstr ""
@@ -17033,6 +18076,18 @@ msgstr ""
msgid "Release title"
msgstr ""
+msgid "ReleaseAssetLinkType|Image"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Other"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Package"
+msgstr ""
+
+msgid "ReleaseAssetLinkType|Runbook"
+msgstr ""
+
msgid "Releases"
msgstr ""
@@ -17054,6 +18109,9 @@ msgstr ""
msgid "Remediated: needs review"
msgstr ""
+msgid "Remediations"
+msgstr ""
+
msgid "Remember me"
msgstr ""
@@ -17123,6 +18181,12 @@ msgstr ""
msgid "Remove group"
msgstr ""
+msgid "Remove iteration"
+msgstr ""
+
+msgid "Remove license"
+msgstr ""
+
msgid "Remove limit"
msgstr ""
@@ -17165,6 +18229,9 @@ msgstr ""
msgid "Removed %{epic_ref} from child epics."
msgstr ""
+msgid "Removed %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removed %{label_references} %{label_text}."
msgstr ""
@@ -17204,6 +18271,9 @@ msgstr ""
msgid "Removes %{epic_ref} from child epics."
msgstr ""
+msgid "Removes %{iteration_reference} iteration."
+msgstr ""
+
msgid "Removes %{label_references} %{label_text}."
msgstr ""
@@ -17255,6 +18325,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{display_issuable_type}"
+msgstr ""
+
msgid "Reopen epic"
msgstr ""
@@ -17285,6 +18358,9 @@ msgstr ""
msgid "Replaces the clone URL root."
msgstr ""
+msgid "Replication"
+msgstr ""
+
msgid "Reply by email"
msgstr ""
@@ -17300,7 +18376,10 @@ msgstr ""
msgid "Repo by URL"
msgstr ""
-msgid "Report Type: %{report_type}"
+msgid "Report %{display_issuable_type} that are abusive, inappropriate or spam."
+msgstr ""
+
+msgid "Report abuse"
msgstr ""
msgid "Report abuse to admin"
@@ -17403,6 +18482,9 @@ msgstr ""
msgid "Repository URL"
msgstr ""
+msgid "Repository check"
+msgstr ""
+
msgid "Repository check was triggered."
msgstr ""
@@ -17439,6 +18521,9 @@ msgstr ""
msgid "Request Access"
msgstr ""
+msgid "Request Headers"
+msgstr ""
+
msgid "Request parameter %{param} is missing."
msgstr ""
@@ -17454,10 +18539,13 @@ msgstr ""
msgid "Requested states are invalid"
msgstr ""
+msgid "Requests"
+msgstr ""
+
msgid "Requests Profiles"
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 whitelist 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."
+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 all users in this group to setup Two-factor authentication"
@@ -17472,6 +18560,12 @@ msgstr ""
msgid "Require users to prove ownership of custom domains"
msgstr ""
+msgid "Required approvals (%{approvals_given} given)"
+msgstr ""
+
+msgid "Required approvals (%{approvals_given} given, you've approved)"
+msgstr ""
+
msgid "Requirement"
msgstr ""
@@ -17493,10 +18587,7 @@ msgstr ""
msgid "Requirements"
msgstr ""
-msgid "Requirements allow you to create criteria to check your products against."
-msgstr ""
-
-msgid "Requirements can be based on users, stakeholders, system, software or anything else you find important to capture."
+msgid "Requirements can be based on users, stakeholders, system, software, or anything else you find important to capture."
msgstr ""
msgid "Requires approval from %{names}."
@@ -17564,6 +18655,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -17576,6 +18670,12 @@ msgstr ""
msgid "Response"
msgstr ""
+msgid "Response Headers"
+msgstr ""
+
+msgid "Response Status"
+msgstr ""
+
msgid "Response didn't include `service_desk_address`"
msgstr ""
@@ -17721,6 +18821,9 @@ msgstr ""
msgid "Rook"
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 ""
+
msgid "Rules that define what git pushes are accepted for a project. All newly created projects will use these settings."
msgstr ""
@@ -17784,9 +18887,6 @@ msgstr ""
msgid "Runners currently online: %{active_runners_count}"
msgstr ""
-msgid "Runners page"
-msgstr ""
-
msgid "Runners page."
msgstr ""
@@ -17823,9 +18923,6 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
-msgid "SSH Keys Help"
-msgstr ""
-
msgid "SSH host key fingerprints"
msgstr ""
@@ -17955,9 +19052,15 @@ msgstr ""
msgid "Search Button"
msgstr ""
+msgid "Search Milestones"
+msgstr ""
+
msgid "Search an environment spec"
msgstr ""
+msgid "Search authors"
+msgstr ""
+
msgid "Search branches"
msgstr ""
@@ -18015,6 +19118,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search requirements"
+msgstr ""
+
msgid "Search users"
msgstr ""
@@ -18045,10 +19151,10 @@ msgstr ""
msgid "SearchAutocomplete|in all GitLab"
msgstr ""
-msgid "SearchAutocomplete|in this group"
+msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
-msgid "SearchAutocomplete|in this project"
+msgid "SearchAutocomplete|in project %{projectName}"
msgstr ""
msgid "SearchCodeResults|in"
@@ -18127,9 +19233,15 @@ msgstr ""
msgid "Seats in license"
msgstr ""
+msgid "Secondary"
+msgstr ""
+
msgid "Secret"
msgstr ""
+msgid "Secret Detection"
+msgstr ""
+
msgid "Security"
msgstr ""
@@ -18142,9 +19254,6 @@ msgstr ""
msgid "Security Dashboard"
msgstr ""
-msgid "Security configuration help link"
-msgstr ""
-
msgid "Security dashboard"
msgstr ""
@@ -18154,24 +19263,24 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "SecurityConfiguration|Configured"
-msgstr ""
-
-msgid "SecurityConfiguration|Feature"
+msgid "SecurityConfiguration|Enabled"
msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|Not yet configured"
+msgid "SecurityConfiguration|Not yet enabled"
msgstr ""
-msgid "SecurityConfiguration|Secure features"
+msgid "SecurityConfiguration|Security Control"
msgstr ""
msgid "SecurityConfiguration|Status"
msgstr ""
+msgid "SecurityConfiguration|Testing & Compliance"
+msgstr ""
+
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr ""
@@ -18307,6 +19416,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
@@ -18388,6 +19500,9 @@ msgstr ""
msgid "Select Archive Format"
msgstr ""
+msgid "Select Git revision"
+msgstr ""
+
msgid "Select GitLab project to link with your Slack team"
msgstr ""
@@ -18439,12 +19554,18 @@ msgstr ""
msgid "Select an existing Kubernetes cluster or create a new one"
msgstr ""
+msgid "Select assignee"
+msgstr ""
+
msgid "Select branch"
msgstr ""
msgid "Select branch/tag"
msgstr ""
+msgid "Select due date"
+msgstr ""
+
msgid "Select group or project"
msgstr ""
@@ -18490,9 +19611,18 @@ msgstr ""
msgid "Select source branch"
msgstr ""
+msgid "Select start date"
+msgstr ""
+
+msgid "Select status"
+msgstr ""
+
msgid "Select strategy activation method"
msgstr ""
+msgid "Select subscription"
+msgstr ""
+
msgid "Select target branch"
msgstr ""
@@ -18565,6 +19695,12 @@ msgstr ""
msgid "Send email"
msgstr ""
+msgid "Send email notification"
+msgstr ""
+
+msgid "Send message"
+msgstr ""
+
msgid "Send report"
msgstr ""
@@ -18730,6 +19866,9 @@ msgstr ""
msgid "Set instance-wide template repository"
msgstr ""
+msgid "Set iteration"
+msgstr ""
+
msgid "Set max session time for web terminal."
msgstr ""
@@ -18766,6 +19905,9 @@ msgstr ""
msgid "Set the duration for which the jobs will be considered as old and expired. Once that time passes, the jobs will be archived and no longer able to be retried. Make it empty to never expire jobs. It has to be no less than 1 day, for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>."
msgstr ""
+msgid "Set the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Set the maximum file size for each job's artifacts"
msgstr ""
@@ -18850,6 +19992,9 @@ msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
+msgid "Sets the iteration to %{iteration_reference}."
+msgstr ""
+
msgid "Sets the milestone to %{milestone_reference}."
msgstr ""
@@ -18868,7 +20013,7 @@ msgstr ""
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
msgstr ""
-msgid "Severity: %{severity}"
+msgid "Severity"
msgstr ""
msgid "Shards (%{shards})"
@@ -18907,15 +20052,15 @@ msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{b_start}will%{b_end} lose access to your account."
msgstr ""
-msgid "Show all %{issuable_type}."
-msgstr ""
-
msgid "Show all activity"
msgstr ""
msgid "Show all members"
msgstr ""
+msgid "Show all requirements."
+msgstr ""
+
msgid "Show archived projects"
msgstr ""
@@ -18940,12 +20085,21 @@ msgstr ""
msgid "Show file browser"
msgstr ""
+msgid "Show file contents"
+msgstr ""
+
msgid "Show latest version"
msgstr ""
+msgid "Show me everything"
+msgstr ""
+
msgid "Show me how"
msgstr ""
+msgid "Show me more advanced stuff"
+msgstr ""
+
msgid "Show only direct members"
msgstr ""
@@ -18965,6 +20119,13 @@ msgid "Showing %d event"
msgid_plural "Showing %d events"
msgstr[0] ""
+msgid "Showing %{count} of %{total} projects"
+msgstr ""
+
+msgid "Showing %{count} project"
+msgid_plural "Showing %{count} projects"
+msgstr[0] ""
+
msgid "Showing %{limit} of %{total_count} issues. "
msgstr ""
@@ -19151,6 +20312,9 @@ msgstr ""
msgid "Snippets"
msgstr ""
+msgid "Snippets with non-text files can only be edited via Git."
+msgstr ""
+
msgid "SnippetsEmptyState|Code snippets"
msgstr ""
@@ -19187,9 +20351,15 @@ msgstr ""
msgid "Snowplow"
msgstr ""
+msgid "Solution"
+msgstr ""
+
msgid "Some child epics may be hidden due to applied filters"
msgstr ""
+msgid "Some common domains are not allowed. %{read_more_link}."
+msgstr ""
+
msgid "Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead."
msgstr ""
@@ -19286,6 +20456,9 @@ msgstr ""
msgid "Something went wrong while fetching related merge requests."
msgstr ""
+msgid "Something went wrong while fetching requirements count."
+msgstr ""
+
msgid "Something went wrong while fetching requirements list."
msgstr ""
@@ -19325,6 +20498,9 @@ msgstr ""
msgid "Something went wrong while stopping this environment. Please try again."
msgstr ""
+msgid "Something went wrong while toggling auto-fix settings, please try again later."
+msgstr ""
+
msgid "Something went wrong while updating a requirement."
msgstr ""
@@ -19373,6 +20549,12 @@ msgstr ""
msgid "Sort direction"
msgstr ""
+msgid "Sort direction: Ascending"
+msgstr ""
+
+msgid "Sort direction: Descending"
+msgstr ""
+
msgid "SortOptions|Access level, ascending"
msgstr ""
@@ -19490,6 +20672,9 @@ msgstr ""
msgid "SortOptions|Size"
msgstr ""
+msgid "SortOptions|Sort by:"
+msgstr ""
+
msgid "SortOptions|Sort direction"
msgstr ""
@@ -19655,7 +20840,7 @@ msgstr ""
msgid "Stars"
msgstr ""
-msgid "Start GitLab Ultimate trial"
+msgid "Start Date"
msgstr ""
msgid "Start Web Terminal"
@@ -19730,6 +20915,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started:"
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -19856,6 +21044,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Still, we recommend keeping a backup saved somewhere. Otherwise, if you ever need it and have lost it, you will need to request GitLab Inc. to send it to you again."
+msgstr ""
+
msgid "Stop Terminal"
msgstr ""
@@ -19883,6 +21074,9 @@ msgstr ""
msgid "StorageSize|Unknown"
msgstr ""
+msgid "Subgroup milestone"
+msgstr ""
+
msgid "Subgroup overview"
msgstr ""
@@ -19910,6 +21104,9 @@ msgstr ""
msgid "Subkeys"
msgstr ""
+msgid "Submit %{humanized_resource_name}"
+msgstr ""
+
msgid "Submit Changes"
msgstr ""
@@ -20090,9 +21287,15 @@ msgstr ""
msgid "Suggest code changes which can be immediately applied in one click. Try it out!"
msgstr ""
+msgid "Suggested Solutions"
+msgstr ""
+
msgid "Suggested change"
msgstr ""
+msgid "Suggested solutions help link"
+msgstr ""
+
msgid "SuggestedColors|Bright green"
msgstr ""
@@ -20177,6 +21380,9 @@ msgstr ""
msgid "Support page URL"
msgstr ""
+msgid "Survey Response"
+msgstr ""
+
msgid "Switch branch/tag"
msgstr ""
@@ -20204,9 +21410,6 @@ msgstr ""
msgid "System Hooks"
msgstr ""
-msgid "System Hooks Help"
-msgstr ""
-
msgid "System Info"
msgstr ""
@@ -20457,6 +21660,9 @@ msgstr ""
msgid "Thank you for signing up for your free trial! You will get additional instructions in your inbox shortly."
msgstr ""
+msgid "Thank you for your feedback!"
+msgstr ""
+
msgid "Thank you for your report. A GitLab administrator will look into it shortly."
msgstr ""
@@ -20539,9 +21745,6 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
-msgid "The configuration status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've configured a scan for the default branch, any subsequent feature branch you create will include the scan."
-msgstr ""
-
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
@@ -20578,9 +21781,15 @@ msgstr ""
msgid "The domain you entered is not allowed."
msgstr ""
+msgid "The download link will expire in 24 hours."
+msgstr ""
+
msgid "The entered user map is not a valid JSON user map."
msgstr ""
+msgid "The errors we encountered were:"
+msgstr ""
+
msgid "The file has been successfully created."
msgstr ""
@@ -20618,6 +21827,9 @@ msgstr ""
msgid "The group can be fully restored"
msgstr ""
+msgid "The group export can be downloaded from:"
+msgstr ""
+
msgid "The group has already been shared with this group"
msgstr ""
@@ -20792,6 +22004,9 @@ msgstr ""
msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
msgstr ""
+msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
+msgstr ""
+
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
@@ -20840,6 +22055,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
+msgid "There are no %{replicableTypeName} to show"
+msgstr ""
+
msgid "There are no GPG keys associated with this account."
msgstr ""
@@ -20915,6 +22133,15 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem fetching project branches."
+msgstr ""
+
+msgid "There was a problem fetching project users."
+msgstr ""
+
+msgid "There was a problem fetching users."
+msgstr ""
+
msgid "There was a problem refreshing the data, please try again"
msgstr ""
@@ -20987,6 +22214,9 @@ msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
+msgid "There was an error parsing the data for this graph."
+msgstr ""
+
msgid "There was an error removing the e-mail."
msgstr ""
@@ -21050,6 +22280,9 @@ msgstr ""
msgid "There was an error while fetching value stream analytics recent activity data."
msgstr ""
+msgid "There was an error while fetching value stream analytics time summary data."
+msgstr ""
+
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
msgstr ""
@@ -21134,6 +22367,9 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
+msgid "This content could not be displayed because %{reason}. You can %{options} instead."
+msgstr ""
+
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
@@ -21173,6 +22409,9 @@ msgstr ""
msgid "This epic already has the maximum number of child epics."
msgstr ""
+msgid "This epic and its child elements will only be visible to team members with at minimum Reporter access."
+msgstr ""
+
msgid "This epic does not exist or you don't have sufficient permission."
msgstr ""
@@ -21218,9 +22457,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr ""
-msgid "This is a primary node"
-msgstr ""
-
msgid "This is a security log of important events involving your account."
msgstr ""
@@ -21332,7 +22568,7 @@ msgstr ""
msgid "This job is preparing to start"
msgstr ""
-msgid "This job is stuck because you don't have any active runners online with any of these tags assigned to them:"
+msgid "This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:"
msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
@@ -21359,6 +22595,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request does not have accessibility reports"
+msgstr ""
+
msgid "This merge request is locked."
msgstr ""
@@ -21395,12 +22634,18 @@ msgstr ""
msgid "This project does not belong to a group and can therefore not make use of group Runners."
msgstr ""
+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 ""
+
msgid "This project does not have a wiki homepage yet"
msgstr ""
msgid "This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target=\"_blank\" rel=\"noopener noreferrer\">enable billing <i class=\"fa fa-external-link\" aria-hidden=\"true\"></i></a> and try again."
msgstr ""
+msgid "This project has no active access tokens."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -21413,12 +22658,24 @@ msgstr ""
msgid "This project will be removed on %{date} since its parent group '%{parent_group_name}' has been scheduled for removal."
msgstr ""
+msgid "This project will live in your group <strong>%{namespace}</strong>. A project is where you house your files (repository), plan your work (issues), publish your documentation (wiki), and so much more."
+msgstr ""
+
msgid "This repository"
msgstr ""
+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 ""
+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 ""
+
+msgid "This repository was last checked %{last_check_timestamp}. The check passed."
+msgstr ""
+
msgid "This runner will only run on pipelines triggered on protected branches"
msgstr ""
@@ -21437,7 +22694,7 @@ msgstr ""
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
-msgid "This user has no active %{type} Tokens."
+msgid "This user has no active %{type}."
msgstr ""
msgid "This user has no identities"
@@ -21446,9 +22703,6 @@ msgstr ""
msgid "This 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 ""
-msgid "This 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. Upon creation or when reassigning you can only assign yourself to be the mirror user."
-msgstr ""
-
msgid "This variable can not be masked."
msgstr ""
@@ -21503,9 +22757,15 @@ msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
msgstr ""
+msgid "ThreatMonitoring|Overview"
+msgstr ""
+
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
+msgid "ThreatMonitoring|Policies"
+msgstr ""
+
msgid "ThreatMonitoring|Requests"
msgstr ""
@@ -21752,6 +23012,9 @@ msgstr ""
msgid "Timeout"
msgstr ""
+msgid "Timeout connecting to the Google API. Please try again."
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -21814,6 +23077,12 @@ msgstr ""
msgid "To enable it and see User Cohorts, visit %{application_settings_link_start}application settings%{application_settings_link_end}."
msgstr ""
+msgid "To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method."
+msgstr ""
+
+msgid "To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}."
+msgstr ""
+
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 ""
@@ -21934,6 +23203,9 @@ msgstr ""
msgid "Toggle commit list"
msgstr ""
+msgid "Toggle dropdown"
+msgstr ""
+
msgid "Toggle emoji award"
msgstr ""
@@ -21991,15 +23263,9 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
-msgid "Total cores (vCPUs)"
-msgstr ""
-
msgid "Total issues"
msgstr ""
-msgid "Total memory (GB)"
-msgstr ""
-
msgid "Total test time for all commits/merges"
msgstr ""
@@ -22015,9 +23281,6 @@ msgstr ""
msgid "Tracing"
msgstr ""
-msgid "Track activity with Contribution Analytics."
-msgstr ""
-
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
@@ -22036,6 +23299,9 @@ msgstr ""
msgid "Transfer project"
msgstr ""
+msgid "TransferGroup|Cannot transfer group to one of its subgroup."
+msgstr ""
+
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 ""
@@ -22147,6 +23413,9 @@ msgstr ""
msgid "Try to fork again"
msgstr ""
+msgid "Try to keep the first line under 52 characters and the others under 72."
+msgstr ""
+
msgid "Try using a different search term to find the file you are looking for."
msgstr ""
@@ -22204,10 +23473,10 @@ msgstr "URL"
msgid "URL is required"
msgstr ""
-msgid "URL must be a valid url (ex: https://gitlab.com)"
+msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
-msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
+msgid "URL of the external Spam Check endpoint"
msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
@@ -22216,6 +23485,9 @@ msgstr ""
msgid "URL or request ID"
msgstr ""
+msgid "UTC"
+msgstr ""
+
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
@@ -22255,6 +23527,9 @@ msgstr ""
msgid "Unable to generate new instance ID"
msgstr ""
+msgid "Unable to load file contents. Try again later."
+msgstr ""
+
msgid "Unable to load the diff"
msgstr ""
@@ -22264,9 +23539,15 @@ msgstr ""
msgid "Unable to load the merge request widget. Try reloading the page."
msgstr ""
+msgid "Unable to process group import file"
+msgstr ""
+
msgid "Unable to resolve"
msgstr ""
+msgid "Unable to save iteration. Please try again"
+msgstr ""
+
msgid "Unable to save your changes. Please try again."
msgstr ""
@@ -22516,18 +23797,12 @@ msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
-msgid "Upgrade your plan"
-msgstr ""
-
msgid "Upgrade your plan to activate Advanced Global Search."
msgstr ""
msgid "Upgrade your plan to activate Audit Events."
msgstr ""
-msgid "Upgrade your plan to activate Contribution Analytics."
-msgstr ""
-
msgid "Upgrade your plan to activate Group Webhooks."
msgstr ""
@@ -22546,6 +23821,9 @@ msgstr ""
msgid "Upload New File"
msgstr ""
+msgid "Upload New License"
+msgstr ""
+
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -22564,6 +23842,9 @@ msgstr ""
msgid "Uploaded on"
msgstr ""
+msgid "Uploaded:"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -22588,9 +23869,6 @@ msgstr ""
msgid "Usage ping is not enabled"
msgstr ""
-msgid "Usage quotas help link"
-msgstr ""
-
msgid "Usage statistics"
msgstr ""
@@ -22600,12 +23878,18 @@ msgstr ""
msgid "UsageQuota|Artifacts"
msgstr ""
+msgid "UsageQuota|Build Artifacts"
+msgstr ""
+
msgid "UsageQuota|Buy additional minutes"
msgstr ""
msgid "UsageQuota|Current period usage"
msgstr ""
+msgid "UsageQuota|LFS Objects"
+msgstr ""
+
msgid "UsageQuota|LFS Storage"
msgstr ""
@@ -22615,12 +23899,18 @@ msgstr ""
msgid "UsageQuota|Pipelines"
msgstr ""
+msgid "UsageQuota|Repositories"
+msgstr ""
+
msgid "UsageQuota|Repository"
msgstr ""
msgid "UsageQuota|Storage"
msgstr ""
+msgid "UsageQuota|Storage usage:"
+msgstr ""
+
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
@@ -22639,12 +23929,18 @@ msgstr ""
msgid "UsageQuota|Usage of resources across your projects"
msgstr ""
+msgid "UsageQuota|Usage quotas help link"
+msgstr ""
+
msgid "UsageQuota|Usage since"
msgstr ""
msgid "UsageQuota|Wiki"
msgstr ""
+msgid "UsageQuota|Wikis"
+msgstr ""
+
msgid "Use %{code_start}::%{code_end} to create a %{link_start}scoped label set%{link_end} (eg. %{code_start}priority::1%{code_end})"
msgstr ""
@@ -22669,7 +23965,7 @@ msgstr ""
msgid "Use hashed storage"
msgstr ""
-msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance."
+msgid "Use hashed storage paths for newly created and renamed repositories. Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents repositories from having to be moved or renamed when the Repository URL changes and may improve disk I/O performance. (Always enabled since 13.0)"
msgstr ""
msgid "Use one line per URI"
@@ -22744,9 +24040,6 @@ msgstr ""
msgid "User restrictions"
msgstr ""
-msgid "User settings"
-msgstr ""
-
msgid "User was successfully created."
msgstr ""
@@ -22993,6 +24286,12 @@ msgstr ""
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
msgstr ""
+msgid "UserProfile|at"
+msgstr ""
+
+msgid "UserProfile|made a private contribution"
+msgstr ""
+
msgid "Username (optional)"
msgstr ""
@@ -23053,6 +24352,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!"
msgstr ""
+msgid "Valid from"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -23080,7 +24382,10 @@ 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 "Var"
+msgid "ValueStreamAnalytics|%{days}d"
+msgstr ""
+
+msgid "Variable"
msgstr ""
msgid "Variable will be masked in job logs."
@@ -23122,6 +24427,9 @@ msgstr ""
msgid "Version"
msgstr ""
+msgid "Versions"
+msgstr ""
+
msgid "Very helpful"
msgstr ""
@@ -23166,6 +24474,9 @@ msgstr[0] ""
msgid "View file @ "
msgstr ""
+msgid "View file @ %{commitSha}"
+msgstr ""
+
msgid "View full dashboard"
msgstr ""
@@ -23229,6 +24540,9 @@ msgstr ""
msgid "View the performance dashboard at"
msgstr ""
+msgid "View users statistics"
+msgstr ""
+
msgid "Viewing commit"
msgstr ""
@@ -23310,9 +24624,6 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
-msgid "Vulnerability List"
-msgstr ""
-
msgid "Vulnerability remediated. Review before resolving."
msgstr ""
@@ -23343,9 +24654,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr ""
-msgid "VulnerabilityManagement|Create issue"
-msgstr ""
-
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
msgstr ""
@@ -23454,6 +24762,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for merge (open and assigned)"
+msgstr ""
+
msgid "Waiting for performance data"
msgstr ""
@@ -23466,6 +24777,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
+msgid "We are currently unable to fetch data for this graph."
+msgstr ""
+
msgid "We could not determine the path to remove the epic"
msgstr ""
@@ -23487,7 +24801,13 @@ msgstr ""
msgid "We have found the following errors:"
msgstr ""
-msgid "We heard back from your U2F device. You have been authenticated."
+msgid "We heard back from your device. You have been authenticated."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
msgstr ""
msgid "We sent you an email with reset password instructions"
@@ -23529,9 +24849,6 @@ msgstr ""
msgid "Webhooks"
msgstr ""
-msgid "Webhooks Help"
-msgstr ""
-
msgid "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 ""
@@ -23571,12 +24888,21 @@ msgstr ""
msgid "Welcome to the Guided GitLab Tour"
msgstr ""
+msgid "Welcome to the guided GitLab tour"
+msgstr ""
+
msgid "Welcome to your Issue Board!"
msgstr ""
msgid "What are you searching for?"
msgstr ""
+msgid "What describes you best?"
+msgstr ""
+
+msgid "What’s your experience level?"
+msgstr ""
+
msgid "When a deployment job is successful, skip older deployment jobs that are still pending"
msgstr ""
@@ -23611,9 +24937,6 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
-msgid "Whitelist to allow requests to the local network from hooks and services"
-msgstr ""
-
msgid "Who can be an approver?"
msgstr ""
@@ -23647,9 +24970,6 @@ msgstr ""
msgid "WikiClone|Install Gollum"
msgstr ""
-msgid "WikiClone|It is recommended to install %{markdown} so that GFM features render locally:"
-msgstr ""
-
msgid "WikiClone|Start Gollum and edit locally"
msgstr ""
@@ -23770,10 +25090,13 @@ msgstr ""
msgid "Wiki|Wiki Pages"
msgstr ""
+msgid "Will be created"
+msgstr ""
+
msgid "Will deploy to"
msgstr ""
-msgid "With contribution analytics you can have an overview for the activity of issues, merge requests and push events of your organization and its members."
+msgid "With requirements, you can set criteria to check your products against."
msgstr ""
msgid "Withdraw Access Request"
@@ -23782,10 +25105,10 @@ msgstr ""
msgid "Won't fix / Accept risk"
msgstr ""
-msgid "Work in progress Limit"
+msgid "Work in progress (open and unassigned)"
msgstr ""
-msgid "Workflow Help"
+msgid "Work in progress Limit"
msgstr ""
msgid "Write"
@@ -23902,6 +25225,9 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
+msgid "You can also use project access tokens to authenticate against Git over HTTP."
+msgstr ""
+
msgid "You can always edit this later"
msgstr ""
@@ -23929,6 +25255,9 @@ msgstr ""
msgid "You can filter by 'days to merge' by clicking on the columns in the chart."
msgstr ""
+msgid "You can generate an access token scoped to this project for each application to use the GitLab API."
+msgstr ""
+
msgid "You can get started by cloning the repository or start adding files to it with one of the following options."
msgstr ""
@@ -23944,6 +25273,9 @@ msgstr ""
msgid "You can move around the graph by using the arrow keys."
msgstr ""
+msgid "You can notify the app / group or a project by sending them an email notification"
+msgstr ""
+
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -24022,6 +25354,9 @@ msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
+msgid "You do not have an active license"
+msgstr ""
+
msgid "You do not have any subscriptions yet"
msgstr ""
@@ -24070,6 +25405,9 @@ msgstr ""
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
+msgid "You have a license that activates at a future date. Please see the License History table below."
+msgstr ""
+
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
msgstr ""
@@ -24085,7 +25423,7 @@ msgstr ""
msgid "You have declined the invitation to join %{label}."
msgstr ""
-msgid "You have imported from this project %{numberOfPreviousImportsForProject} times before. Each new import will create duplicate issues."
+msgid "You have imported from this project %{numberOfPreviousImports} times before. Each new import will create duplicate issues."
msgstr ""
msgid "You have no permissions"
@@ -24178,6 +25516,9 @@ msgstr ""
msgid "You will be removed from existing projects/groups"
msgstr ""
+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 ""
+
msgid "You will first need to set up Jira Integration to use this feature."
msgstr ""
@@ -24205,6 +25546,9 @@ msgstr ""
msgid "You will receive notifications only for comments in which you were @mentioned"
msgstr ""
+msgid "You won't be able to create new projects because you have reached your project limit."
+msgstr ""
+
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
@@ -24223,6 +25567,12 @@ msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
+msgid "You're at the first commit"
+msgstr ""
+
+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 ""
@@ -24256,7 +25606,10 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+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}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
@@ -24292,7 +25645,7 @@ msgstr ""
msgid "Your Groups"
msgstr ""
-msgid "Your New Personal Access Token"
+msgid "Your License"
msgstr ""
msgid "Your Personal Access Tokens will expire in %{days_to_expire} days or less"
@@ -24385,9 +25738,18 @@ msgstr ""
msgid "Your device was successfully set up! Give it a name and register it with the GitLab server."
msgstr ""
+msgid "Your first project"
+msgstr ""
+
msgid "Your groups"
msgstr ""
+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 ""
+
+msgid "Your instance is approaching its licensed user count"
+msgstr ""
+
msgid "Your issues are being imported. Once finished, you'll get a confirmation email."
msgstr ""
@@ -24397,12 +25759,18 @@ msgstr ""
msgid "Your license is valid from"
msgstr ""
+msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your <code>.gitlab-license</code> file."
+msgstr ""
+
msgid "Your message here"
msgstr ""
msgid "Your name"
msgstr ""
+msgid "Your new %{type}"
+msgstr ""
+
msgid "Your new SCIM token"
msgstr ""
@@ -24427,9 +25795,15 @@ msgstr ""
msgid "Your projects"
msgstr ""
+msgid "Your request for access could not be processed: %{error_meesage}"
+msgstr ""
+
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your response has been recorded."
+msgstr ""
+
msgid "Your search didn't match any commits."
msgstr ""
@@ -24476,6 +25850,9 @@ msgstr ""
msgid "ago"
msgstr "å‰"
+msgid "alert"
+msgstr ""
+
msgid "allowed to fail"
msgstr ""
@@ -24518,6 +25895,9 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "build pipeline reference mismatch"
+msgstr ""
+
msgid "by"
msgstr "來自"
@@ -24682,6 +26062,9 @@ msgstr ""
msgid "ciReport|Failed to load %{reportName} report"
msgstr ""
+msgid "ciReport|Fixed"
+msgstr ""
+
msgid "ciReport|Fixed:"
msgstr ""
@@ -24700,6 +26083,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
+msgid "ciReport|New"
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -24718,6 +26104,9 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret Detection"
+msgstr ""
+
msgid "ciReport|Secret scanning"
msgstr ""
@@ -24758,6 +26147,9 @@ msgstr[0] ""
msgid "ciReport|View full report"
msgstr ""
+msgid "closed issue"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -24767,6 +26159,9 @@ msgstr ""
msgid "commit %{commit_id}"
msgstr ""
+msgid "committed"
+msgstr ""
+
msgid "confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue."
msgstr ""
@@ -24776,6 +26171,9 @@ msgstr ""
msgid "connecting"
msgstr ""
+msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "container_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -24825,6 +26223,9 @@ msgstr ""
msgid "done"
msgstr ""
+msgid "download it"
+msgstr ""
+
msgid "draft"
msgid_plural "drafts"
msgstr[0] ""
@@ -24835,7 +26236,10 @@ msgstr ""
msgid "element is not a hierarchy"
msgstr ""
-msgid "email '%{email}' does not match the allowed domain of '%{email_domain}'"
+msgid "email '%{email}' does not match the allowed domains of %{email_domains}"
+msgstr ""
+
+msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
@@ -24868,10 +26272,10 @@ msgstr ""
msgid "exceeds the limit of %{bytes} bytes for directory name \"%{dirname}\""
msgstr ""
-msgid "expired on %{milestone_due_date}"
+msgid "expired on %{timebox_due_date}"
msgstr ""
-msgid "expires on %{milestone_due_date}"
+msgid "expires on %{timebox_due_date}"
msgstr ""
msgid "external_url"
@@ -24935,9 +26339,18 @@ msgstr ""
msgid "https://your-bitbucket-server"
msgstr ""
+msgid "image"
+msgstr ""
+
msgid "image diff"
msgstr ""
+msgid "impersonation token"
+msgstr ""
+
+msgid "impersonation tokens"
+msgstr ""
+
msgid "import flow"
msgstr ""
@@ -24999,6 +26412,9 @@ msgstr ""
msgid "is not in the group enforcing Group Managed Account"
msgstr ""
+msgid "is read only"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -25020,6 +26436,12 @@ msgstr ""
msgid "issues on track"
msgstr ""
+msgid "it is larger than %{limit}"
+msgstr ""
+
+msgid "it is stored as a job artifact"
+msgstr ""
+
msgid "it is stored externally"
msgstr ""
@@ -25059,6 +26481,9 @@ msgstr ""
msgid "limit of %{project_limit} reached"
msgstr ""
+msgid "load it anyway"
+msgstr ""
+
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -25186,7 +26611,7 @@ msgstr ""
msgid "mrWidget|Deployment statistics are not available currently"
msgstr ""
-msgid "mrWidget|Detect issues before deployment with a CI pipeline"
+msgid "mrWidget|Detect issues before deployment with a CI pipeline that continuously tests your code. We created a quick guide that will show you how to create one. Make your code more secure and more robust in just a minute."
msgstr ""
msgid "mrWidget|Did not close"
@@ -25366,9 +26791,6 @@ msgstr ""
msgid "mrWidget|Your password"
msgstr ""
-msgid "mrWidget|a quick guide that'll show you how to create"
-msgstr ""
-
msgid "mrWidget|branch does not exist."
msgstr ""
@@ -25378,15 +26800,6 @@ msgstr ""
msgid "mrWidget|into"
msgstr ""
-msgid "mrWidget|one. Make your code more secure and more"
-msgstr ""
-
-msgid "mrWidget|robust in just a minute."
-msgstr ""
-
-msgid "mrWidget|that continuously tests your code. We created"
-msgstr ""
-
msgid "mrWidget|to be added to the merge train when the pipeline succeeds"
msgstr ""
@@ -25399,6 +26812,9 @@ msgstr ""
msgid "must be greater than start date"
msgstr ""
+msgid "my-awesome-group"
+msgstr ""
+
msgid "n/a"
msgstr "ä¸é©ç”¨"
@@ -25444,6 +26860,9 @@ msgstr ""
msgid "on track"
msgstr ""
+msgid "open issue"
+msgstr ""
+
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
@@ -25473,9 +26892,18 @@ msgstr ""
msgid "per day"
msgstr ""
+msgid "personal access token"
+msgstr ""
+
+msgid "personal access tokens"
+msgstr ""
+
msgid "pipeline"
msgstr ""
+msgid "pod_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
+msgstr ""
+
msgid "pod_name cannot be larger than %{max_length} chars"
msgstr ""
@@ -25496,6 +26924,12 @@ msgid "project"
msgid_plural "projects"
msgstr[0] ""
+msgid "project access token"
+msgstr ""
+
+msgid "project access tokens"
+msgstr ""
+
msgid "project avatar"
msgstr ""
@@ -25545,6 +26979,9 @@ msgstr ""
msgid "resolved the corresponding error and closed the issue."
msgstr ""
+msgid "revised"
+msgstr ""
+
msgid "score"
msgstr ""
@@ -25611,10 +27048,10 @@ msgstr ""
msgid "started a discussion on %{design_link}"
msgstr ""
-msgid "started on %{milestone_start_date}"
+msgid "started on %{timebox_start_date}"
msgstr ""
-msgid "starts on %{milestone_start_date}"
+msgid "starts on %{timebox_start_date}"
msgstr ""
msgid "stuck"
@@ -25677,6 +27114,12 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
+msgid "uploaded"
+msgstr ""
+
+msgid "uploads"
+msgstr ""
+
msgid "user avatar"
msgstr ""
@@ -25704,6 +27147,9 @@ msgstr ""
msgid "view the blob"
msgstr ""
+msgid "view the source"
+msgstr ""
+
msgid "vulnerability|Add a comment"
msgstr ""
@@ -25731,6 +27177,9 @@ msgstr ""
msgid "wiki page"
msgstr ""
+msgid "will be released %{time}"
+msgstr ""
+
msgid "with %{additions} additions, %{deletions} deletions."
msgstr ""
diff --git a/package.json b/package.json
index 82976399171..99614c0acc3 100644
--- a/package.json
+++ b/package.json
@@ -10,7 +10,7 @@
"eslint-report": "eslint --max-warnings 0 --ext .js,.vue --format html --output-file ./eslint-report.html --no-inline-config .",
"file-coverage": "scripts/frontend/file_test_coverage.js",
"prejest": "yarn check-dependencies",
- "jest": "jest --config jest.config.unit.js",
+ "jest": "jest --config jest.config.js",
"jest-debug": "node --inspect-brk node_modules/.bin/jest --runInBand",
"jest:integration": "jest --config jest.config.integration.js",
"jsdoc": "jsdoc -c config/jsdocs.config.js",
@@ -33,19 +33,19 @@
"webpack-prod": "NODE_OPTIONS=\"--max-old-space-size=3584\" NODE_ENV=production webpack --config config/webpack.config.js"
},
"dependencies": {
- "@babel/core": "^7.8.4",
- "@babel/plugin-proposal-class-properties": "^7.8.3",
- "@babel/plugin-proposal-json-strings": "^7.8.3",
- "@babel/plugin-proposal-private-methods": "^7.8.3",
- "@babel/plugin-syntax-import-meta": "^7.8.3",
- "@babel/preset-env": "^7.8.4",
+ "@babel/core": "^7.10.1",
+ "@babel/plugin-proposal-class-properties": "^7.10.1",
+ "@babel/plugin-proposal-json-strings": "^7.10.1",
+ "@babel/plugin-proposal-private-methods": "^7.10.1",
+ "@babel/plugin-syntax-import-meta": "^7.10.1",
+ "@babel/preset-env": "^7.10.1",
"@gitlab/at.js": "1.5.5",
- "@gitlab/svgs": "1.127.0",
- "@gitlab/ui": "14.10.0",
+ "@gitlab/svgs": "1.139.0",
+ "@gitlab/ui": "16.12.1",
"@gitlab/visual-review-tools": "1.6.1",
- "@rails/actioncable": "^6.0.3",
+ "@rails/actioncable": "^6.0.3-1",
"@sentry/browser": "^5.10.2",
- "@sourcegraph/code-host-integration": "0.0.46",
+ "@sourcegraph/code-host-integration": "0.0.48",
"@toast-ui/editor": "^2.0.1",
"@toast-ui/vue-editor": "^2.0.1",
"apollo-cache-inmemory": "^1.6.3",
@@ -58,10 +58,9 @@
"axios": "^0.19.0",
"babel-loader": "^8.0.6",
"babel-plugin-lodash": "^3.3.4",
- "bootstrap": "4.3.1",
+ "bootstrap": "4.4.1",
"brace-expansion": "^1.1.8",
"cache-loader": "^4.1.0",
- "chart.js": "2.7.2",
"classlist-polyfill": "^1.2.0",
"clipboard": "^1.7.1",
"codemirror": "^5.48.4",
@@ -71,6 +70,8 @@
"core-js": "^3.6.4",
"cropper": "^2.3.0",
"css-loader": "^2.1.1",
+ "d3": "^5.16.0",
+ "d3-sankey": "^0.12.3",
"d3-scale": "^2.2.2",
"d3-selection": "^1.2.0",
"dateformat": "^3.0.3",
@@ -78,6 +79,7 @@
"diff": "^3.4.0",
"document-register-element": "1.14.3",
"dropzone": "^4.2.0",
+ "editorconfig": "^0.15.3",
"emoji-regex": "^7.0.3",
"emoji-unicode-version": "^0.2.1",
"exports-loader": "^0.7.0",
@@ -100,7 +102,9 @@
"katex": "^0.10.0",
"lodash": "^4.17.15",
"marked": "^0.3.12",
- "mermaid": "^8.4.8",
+ "mermaid": "^8.5.2",
+ "mersenne-twister": "1.1.0",
+ "minimatch": "^3.0.4",
"mitt": "^1.2.0",
"monaco-editor": "^0.18.1",
"monaco-editor-webpack-plugin": "^1.7.0",
@@ -119,6 +123,7 @@
"sortablejs": "^1.10.2",
"sql.js": "^0.4.0",
"stickyfilljs": "^2.1.0",
+ "string-hash": "1.1.3",
"style-loader": "^1.1.3",
"svg4everybody": "2.1.9",
"swagger-ui-dist": "^3.24.3",
@@ -132,6 +137,7 @@
"tributejs": "4.1.3",
"unfetch": "^4.1.0",
"url-loader": "^3.0.0",
+ "uuid": "8.1.0",
"visibilityjs": "^1.2.4",
"vue": "^2.6.10",
"vue-apollo": "^3.0.3",
@@ -149,7 +155,8 @@
"xterm": "^3.5.0"
},
"devDependencies": {
- "@babel/plugin-transform-modules-commonjs": "^7.8.3",
+ "acorn": "^6.3.0",
+ "@babel/plugin-transform-modules-commonjs": "^7.10.1",
"@gitlab/eslint-plugin": "3.1.0",
"@vue/test-utils": "^1.0.0-beta.30",
"axios-mock-adapter": "^1.15.0",
@@ -177,7 +184,7 @@
"jasmine-jquery": "^2.1.1",
"jest": "^24.1.0",
"jest-canvas-mock": "^2.1.2",
- "jest-environment-jsdom": "^24.0.0",
+ "jest-environment-jsdom-sixteen": "^1.0.0",
"jest-junit": "^6.3.0",
"jest-util": "^24.0.0",
"jsdoc": "^3.5.5",
@@ -193,7 +200,7 @@
"markdownlint-cli": "0.18.0",
"md5": "^2.2.1",
"node-sass": "^4.12.0",
- "nodemon": "^1.18.9",
+ "nodemon": "^2.0.4",
"pixelmatch": "^4.0.2",
"postcss": "^7.0.14",
"prettier": "1.18.2",
@@ -204,6 +211,7 @@
"timezone-mock": "^1.0.8",
"vue-jest": "^4.0.0-beta.2",
"webpack-dev-server": "^3.10.3",
+ "xhr-mock": "^2.5.1",
"yarn-check-webpack-plugin": "^1.2.0",
"yarn-deduplicate": "^1.1.1"
},
@@ -211,8 +219,9 @@
"bootstrap-vue": "https://docs.gitlab.com/ee/development/fe_guide/dependencies.md#bootstrapvue"
},
"resolutions": {
- "vue-jest/ts-jest": "24.0.0",
- "monaco-editor": "0.18.1"
+ "chokidar": "^3.4.0",
+ "monaco-editor": "0.18.1",
+ "vue-jest/ts-jest": "24.0.0"
},
"engines": {
"node": ">=10.13.0",
diff --git a/public/-/emojis/1/emojis.json b/public/-/emojis/1/emojis.json
new file mode 100644
index 00000000000..20a564720d1
--- /dev/null
+++ b/public/-/emojis/1/emojis.json
@@ -0,0 +1,10760 @@
+{
+ "100": {
+ "c": "symbols",
+ "e": "💯",
+ "d": "hundred points symbol",
+ "u": "6.0"
+ },
+ "1234": {
+ "c": "symbols",
+ "e": "🔢",
+ "d": "input symbol for numbers",
+ "u": "6.0"
+ },
+ "8ball": {
+ "c": "activity",
+ "e": "🎱",
+ "d": "billiards",
+ "u": "6.0"
+ },
+ "a": {
+ "c": "symbols",
+ "e": "🅰",
+ "d": "negative squared latin capital letter a",
+ "u": "6.0"
+ },
+ "ab": {
+ "c": "symbols",
+ "e": "🆎",
+ "d": "negative squared ab",
+ "u": "6.0"
+ },
+ "abc": {
+ "c": "symbols",
+ "e": "🔤",
+ "d": "input symbol for latin letters",
+ "u": "6.0"
+ },
+ "abcd": {
+ "c": "symbols",
+ "e": "🔡",
+ "d": "input symbol for latin small letters",
+ "u": "6.0"
+ },
+ "accept": {
+ "c": "symbols",
+ "e": "🉑",
+ "d": "circled ideograph accept",
+ "u": "6.0"
+ },
+ "aerial_tramway": {
+ "c": "travel",
+ "e": "🚡",
+ "d": "aerial tramway",
+ "u": "6.0"
+ },
+ "airplane": {
+ "c": "travel",
+ "e": "✈",
+ "d": "airplane",
+ "u": "1.1"
+ },
+ "airplane_arriving": {
+ "c": "travel",
+ "e": "🛬",
+ "d": "airplane arriving",
+ "u": "7.0"
+ },
+ "airplane_departure": {
+ "c": "travel",
+ "e": "🛫",
+ "d": "airplane departure",
+ "u": "7.0"
+ },
+ "airplane_small": {
+ "c": "travel",
+ "e": "🛩",
+ "d": "small airplane",
+ "u": "7.0"
+ },
+ "alarm_clock": {
+ "c": "objects",
+ "e": "â°",
+ "d": "alarm clock",
+ "u": "6.0"
+ },
+ "alembic": {
+ "c": "objects",
+ "e": "âš—",
+ "d": "alembic",
+ "u": "4.1"
+ },
+ "alien": {
+ "c": "people",
+ "e": "👽",
+ "d": "extraterrestrial alien",
+ "u": "6.0"
+ },
+ "ambulance": {
+ "c": "travel",
+ "e": "🚑",
+ "d": "ambulance",
+ "u": "6.0"
+ },
+ "amphora": {
+ "c": "objects",
+ "e": "ðŸº",
+ "d": "amphora",
+ "u": "8.0"
+ },
+ "anchor": {
+ "c": "travel",
+ "e": "âš“",
+ "d": "anchor",
+ "u": "4.1"
+ },
+ "angel": {
+ "c": "people",
+ "e": "👼",
+ "d": "baby angel",
+ "u": "6.0"
+ },
+ "angel_tone1": {
+ "c": "people",
+ "e": "👼ðŸ»",
+ "d": "baby angel tone 1",
+ "u": "8.0"
+ },
+ "angel_tone2": {
+ "c": "people",
+ "e": "👼ðŸ¼",
+ "d": "baby angel tone 2",
+ "u": "8.0"
+ },
+ "angel_tone3": {
+ "c": "people",
+ "e": "👼ðŸ½",
+ "d": "baby angel tone 3",
+ "u": "8.0"
+ },
+ "angel_tone4": {
+ "c": "people",
+ "e": "👼ðŸ¾",
+ "d": "baby angel tone 4",
+ "u": "8.0"
+ },
+ "angel_tone5": {
+ "c": "people",
+ "e": "👼ðŸ¿",
+ "d": "baby angel tone 5",
+ "u": "8.0"
+ },
+ "anger": {
+ "c": "symbols",
+ "e": "💢",
+ "d": "anger symbol",
+ "u": "6.0"
+ },
+ "anger_right": {
+ "c": "symbols",
+ "e": "🗯",
+ "d": "right anger bubble",
+ "u": "7.0"
+ },
+ "angry": {
+ "c": "people",
+ "e": "😠",
+ "d": "angry face",
+ "u": "6.0"
+ },
+ "ant": {
+ "c": "nature",
+ "e": "ðŸœ",
+ "d": "ant",
+ "u": "6.0"
+ },
+ "apple": {
+ "c": "food",
+ "e": "ðŸŽ",
+ "d": "red apple",
+ "u": "6.0"
+ },
+ "aquarius": {
+ "c": "symbols",
+ "e": "â™’",
+ "d": "aquarius",
+ "u": "1.1"
+ },
+ "aries": {
+ "c": "symbols",
+ "e": "♈",
+ "d": "aries",
+ "u": "1.1"
+ },
+ "arrow_backward": {
+ "c": "symbols",
+ "e": "â—€",
+ "d": "black left-pointing triangle",
+ "u": "1.1"
+ },
+ "arrow_double_down": {
+ "c": "symbols",
+ "e": "â¬",
+ "d": "black down-pointing double triangle",
+ "u": "6.0"
+ },
+ "arrow_double_up": {
+ "c": "symbols",
+ "e": "â«",
+ "d": "black up-pointing double triangle",
+ "u": "6.0"
+ },
+ "arrow_down": {
+ "c": "symbols",
+ "e": "⬇",
+ "d": "downwards black arrow",
+ "u": "4.0"
+ },
+ "arrow_down_small": {
+ "c": "symbols",
+ "e": "🔽",
+ "d": "down-pointing small red triangle",
+ "u": "6.0"
+ },
+ "arrow_forward": {
+ "c": "symbols",
+ "e": "â–¶",
+ "d": "black right-pointing triangle",
+ "u": "1.1"
+ },
+ "arrow_heading_down": {
+ "c": "symbols",
+ "e": "⤵",
+ "d": "arrow pointing rightwards then curving downwards",
+ "u": "3.2"
+ },
+ "arrow_heading_up": {
+ "c": "symbols",
+ "e": "⤴",
+ "d": "arrow pointing rightwards then curving upwards",
+ "u": "3.2"
+ },
+ "arrow_left": {
+ "c": "symbols",
+ "e": "⬅",
+ "d": "leftwards black arrow",
+ "u": "4.0"
+ },
+ "arrow_lower_left": {
+ "c": "symbols",
+ "e": "↙",
+ "d": "south west arrow",
+ "u": "1.1"
+ },
+ "arrow_lower_right": {
+ "c": "symbols",
+ "e": "↘",
+ "d": "south east arrow",
+ "u": "1.1"
+ },
+ "arrow_right": {
+ "c": "symbols",
+ "e": "âž¡",
+ "d": "black rightwards arrow",
+ "u": "1.1"
+ },
+ "arrow_right_hook": {
+ "c": "symbols",
+ "e": "↪",
+ "d": "rightwards arrow with hook",
+ "u": "1.1"
+ },
+ "arrow_up": {
+ "c": "symbols",
+ "e": "⬆",
+ "d": "upwards black arrow",
+ "u": "4.0"
+ },
+ "arrow_up_down": {
+ "c": "symbols",
+ "e": "↕",
+ "d": "up down arrow",
+ "u": "1.1"
+ },
+ "arrow_up_small": {
+ "c": "symbols",
+ "e": "🔼",
+ "d": "up-pointing small red triangle",
+ "u": "6.0"
+ },
+ "arrow_upper_left": {
+ "c": "symbols",
+ "e": "↖",
+ "d": "north west arrow",
+ "u": "1.1"
+ },
+ "arrow_upper_right": {
+ "c": "symbols",
+ "e": "↗",
+ "d": "north east arrow",
+ "u": "1.1"
+ },
+ "arrows_clockwise": {
+ "c": "symbols",
+ "e": "🔃",
+ "d": "clockwise downwards and upwards open circle arrows",
+ "u": "6.0"
+ },
+ "arrows_counterclockwise": {
+ "c": "symbols",
+ "e": "🔄",
+ "d": "anticlockwise downwards and upwards open circle ar",
+ "u": "6.0"
+ },
+ "art": {
+ "c": "activity",
+ "e": "🎨",
+ "d": "artist palette",
+ "u": "6.0"
+ },
+ "articulated_lorry": {
+ "c": "travel",
+ "e": "🚛",
+ "d": "articulated lorry",
+ "u": "6.0"
+ },
+ "asterisk": {
+ "c": "symbols",
+ "e": "*⃣",
+ "d": "keycap asterisk",
+ "u": "3.0"
+ },
+ "astonished": {
+ "c": "people",
+ "e": "😲",
+ "d": "astonished face",
+ "u": "6.0"
+ },
+ "athletic_shoe": {
+ "c": "people",
+ "e": "👟",
+ "d": "athletic shoe",
+ "u": "6.0"
+ },
+ "atm": {
+ "c": "symbols",
+ "e": "ðŸ§",
+ "d": "automated teller machine",
+ "u": "6.0"
+ },
+ "atom": {
+ "c": "symbols",
+ "e": "âš›",
+ "d": "atom symbol",
+ "u": "4.1"
+ },
+ "avocado": {
+ "c": "food",
+ "e": "🥑",
+ "d": "avocado",
+ "u": "9.0"
+ },
+ "b": {
+ "c": "symbols",
+ "e": "🅱",
+ "d": "negative squared latin capital letter b",
+ "u": "6.0"
+ },
+ "baby": {
+ "c": "people",
+ "e": "👶",
+ "d": "baby",
+ "u": "6.0"
+ },
+ "baby_bottle": {
+ "c": "food",
+ "e": "ðŸ¼",
+ "d": "baby bottle",
+ "u": "6.0"
+ },
+ "baby_chick": {
+ "c": "nature",
+ "e": "ðŸ¤",
+ "d": "baby chick",
+ "u": "6.0"
+ },
+ "baby_symbol": {
+ "c": "symbols",
+ "e": "🚼",
+ "d": "baby symbol",
+ "u": "6.0"
+ },
+ "baby_tone1": {
+ "c": "people",
+ "e": "👶ðŸ»",
+ "d": "baby tone 1",
+ "u": "8.0"
+ },
+ "baby_tone2": {
+ "c": "people",
+ "e": "👶ðŸ¼",
+ "d": "baby tone 2",
+ "u": "8.0"
+ },
+ "baby_tone3": {
+ "c": "people",
+ "e": "👶ðŸ½",
+ "d": "baby tone 3",
+ "u": "8.0"
+ },
+ "baby_tone4": {
+ "c": "people",
+ "e": "👶ðŸ¾",
+ "d": "baby tone 4",
+ "u": "8.0"
+ },
+ "baby_tone5": {
+ "c": "people",
+ "e": "👶ðŸ¿",
+ "d": "baby tone 5",
+ "u": "8.0"
+ },
+ "back": {
+ "c": "symbols",
+ "e": "🔙",
+ "d": "back with leftwards arrow above",
+ "u": "6.0"
+ },
+ "bacon": {
+ "c": "food",
+ "e": "🥓",
+ "d": "bacon",
+ "u": "9.0"
+ },
+ "badminton": {
+ "c": "activity",
+ "e": "ðŸ¸",
+ "d": "badminton racquet",
+ "u": "8.0"
+ },
+ "baggage_claim": {
+ "c": "symbols",
+ "e": "🛄",
+ "d": "baggage claim",
+ "u": "6.0"
+ },
+ "balloon": {
+ "c": "objects",
+ "e": "🎈",
+ "d": "balloon",
+ "u": "6.0"
+ },
+ "ballot_box": {
+ "c": "objects",
+ "e": "🗳",
+ "d": "ballot box with ballot",
+ "u": "7.0"
+ },
+ "ballot_box_with_check": {
+ "c": "symbols",
+ "e": "☑",
+ "d": "ballot box with check",
+ "u": "1.1"
+ },
+ "bamboo": {
+ "c": "nature",
+ "e": "ðŸŽ",
+ "d": "pine decoration",
+ "u": "6.0"
+ },
+ "banana": {
+ "c": "food",
+ "e": "ðŸŒ",
+ "d": "banana",
+ "u": "6.0"
+ },
+ "bangbang": {
+ "c": "symbols",
+ "e": "‼",
+ "d": "double exclamation mark",
+ "u": "1.1"
+ },
+ "bank": {
+ "c": "travel",
+ "e": "ðŸ¦",
+ "d": "bank",
+ "u": "6.0"
+ },
+ "bar_chart": {
+ "c": "objects",
+ "e": "📊",
+ "d": "bar chart",
+ "u": "6.0"
+ },
+ "barber": {
+ "c": "objects",
+ "e": "💈",
+ "d": "barber pole",
+ "u": "6.0"
+ },
+ "baseball": {
+ "c": "activity",
+ "e": "âš¾",
+ "d": "baseball",
+ "u": "5.2"
+ },
+ "basketball": {
+ "c": "activity",
+ "e": "ðŸ€",
+ "d": "basketball and hoop",
+ "u": "6.0"
+ },
+ "basketball_player": {
+ "c": "activity",
+ "e": "⛹",
+ "d": "person with ball",
+ "u": "5.2"
+ },
+ "basketball_player_tone1": {
+ "c": "activity",
+ "e": "⛹ðŸ»",
+ "d": "person with ball tone 1",
+ "u": "8.0"
+ },
+ "basketball_player_tone2": {
+ "c": "activity",
+ "e": "⛹ðŸ¼",
+ "d": "person with ball tone 2",
+ "u": "8.0"
+ },
+ "basketball_player_tone3": {
+ "c": "activity",
+ "e": "⛹ðŸ½",
+ "d": "person with ball tone 3",
+ "u": "8.0"
+ },
+ "basketball_player_tone4": {
+ "c": "activity",
+ "e": "⛹ðŸ¾",
+ "d": "person with ball tone 4",
+ "u": "8.0"
+ },
+ "basketball_player_tone5": {
+ "c": "activity",
+ "e": "⛹ðŸ¿",
+ "d": "person with ball tone 5",
+ "u": "8.0"
+ },
+ "bat": {
+ "c": "nature",
+ "e": "🦇",
+ "d": "bat",
+ "u": "9.0"
+ },
+ "bath": {
+ "c": "activity",
+ "e": "🛀",
+ "d": "bath",
+ "u": "6.0"
+ },
+ "bath_tone1": {
+ "c": "activity",
+ "e": "🛀ðŸ»",
+ "d": "bath tone 1",
+ "u": "8.0"
+ },
+ "bath_tone2": {
+ "c": "activity",
+ "e": "🛀ðŸ¼",
+ "d": "bath tone 2",
+ "u": "8.0"
+ },
+ "bath_tone3": {
+ "c": "activity",
+ "e": "🛀ðŸ½",
+ "d": "bath tone 3",
+ "u": "8.0"
+ },
+ "bath_tone4": {
+ "c": "activity",
+ "e": "🛀ðŸ¾",
+ "d": "bath tone 4",
+ "u": "8.0"
+ },
+ "bath_tone5": {
+ "c": "activity",
+ "e": "🛀ðŸ¿",
+ "d": "bath tone 5",
+ "u": "8.0"
+ },
+ "bathtub": {
+ "c": "objects",
+ "e": "ðŸ›",
+ "d": "bathtub",
+ "u": "6.0"
+ },
+ "battery": {
+ "c": "objects",
+ "e": "🔋",
+ "d": "battery",
+ "u": "6.0"
+ },
+ "beach": {
+ "c": "travel",
+ "e": "ðŸ–",
+ "d": "beach with umbrella",
+ "u": "7.0"
+ },
+ "beach_umbrella": {
+ "c": "objects",
+ "e": "â›±",
+ "d": "umbrella on ground",
+ "u": "5.2"
+ },
+ "bear": {
+ "c": "nature",
+ "e": "ðŸ»",
+ "d": "bear face",
+ "u": "6.0"
+ },
+ "bed": {
+ "c": "objects",
+ "e": "ðŸ›",
+ "d": "bed",
+ "u": "7.0"
+ },
+ "bee": {
+ "c": "nature",
+ "e": "ðŸ",
+ "d": "honeybee",
+ "u": "6.0"
+ },
+ "beer": {
+ "c": "food",
+ "e": "ðŸº",
+ "d": "beer mug",
+ "u": "6.0"
+ },
+ "beers": {
+ "c": "food",
+ "e": "ðŸ»",
+ "d": "clinking beer mugs",
+ "u": "6.0"
+ },
+ "beetle": {
+ "c": "nature",
+ "e": "ðŸž",
+ "d": "lady beetle",
+ "u": "6.0"
+ },
+ "beginner": {
+ "c": "symbols",
+ "e": "🔰",
+ "d": "japanese symbol for beginner",
+ "u": "6.0"
+ },
+ "bell": {
+ "c": "symbols",
+ "e": "🔔",
+ "d": "bell",
+ "u": "6.0"
+ },
+ "bellhop": {
+ "c": "objects",
+ "e": "🛎",
+ "d": "bellhop bell",
+ "u": "7.0"
+ },
+ "bento": {
+ "c": "food",
+ "e": "ðŸ±",
+ "d": "bento box",
+ "u": "6.0"
+ },
+ "bicyclist": {
+ "c": "activity",
+ "e": "🚴",
+ "d": "bicyclist",
+ "u": "6.0"
+ },
+ "bicyclist_tone1": {
+ "c": "activity",
+ "e": "🚴ðŸ»",
+ "d": "bicyclist tone 1",
+ "u": "8.0"
+ },
+ "bicyclist_tone2": {
+ "c": "activity",
+ "e": "🚴ðŸ¼",
+ "d": "bicyclist tone 2",
+ "u": "8.0"
+ },
+ "bicyclist_tone3": {
+ "c": "activity",
+ "e": "🚴ðŸ½",
+ "d": "bicyclist tone 3",
+ "u": "8.0"
+ },
+ "bicyclist_tone4": {
+ "c": "activity",
+ "e": "🚴ðŸ¾",
+ "d": "bicyclist tone 4",
+ "u": "8.0"
+ },
+ "bicyclist_tone5": {
+ "c": "activity",
+ "e": "🚴ðŸ¿",
+ "d": "bicyclist tone 5",
+ "u": "8.0"
+ },
+ "bike": {
+ "c": "travel",
+ "e": "🚲",
+ "d": "bicycle",
+ "u": "6.0"
+ },
+ "bikini": {
+ "c": "people",
+ "e": "👙",
+ "d": "bikini",
+ "u": "6.0"
+ },
+ "biohazard": {
+ "c": "symbols",
+ "e": "☣",
+ "d": "biohazard sign",
+ "u": "1.1"
+ },
+ "bird": {
+ "c": "nature",
+ "e": "ðŸ¦",
+ "d": "bird",
+ "u": "6.0"
+ },
+ "birthday": {
+ "c": "food",
+ "e": "🎂",
+ "d": "birthday cake",
+ "u": "6.0"
+ },
+ "black_circle": {
+ "c": "symbols",
+ "e": "âš«",
+ "d": "medium black circle",
+ "u": "4.1"
+ },
+ "black_heart": {
+ "c": "symbols",
+ "e": "🖤",
+ "d": "black heart",
+ "u": "9.0"
+ },
+ "black_joker": {
+ "c": "symbols",
+ "e": "ðŸƒ",
+ "d": "playing card black joker",
+ "u": "6.0"
+ },
+ "black_large_square": {
+ "c": "symbols",
+ "e": "⬛",
+ "d": "black large square",
+ "u": "5.1"
+ },
+ "black_medium_small_square": {
+ "c": "symbols",
+ "e": "â—¾",
+ "d": "black medium small square",
+ "u": "3.2"
+ },
+ "black_medium_square": {
+ "c": "symbols",
+ "e": "â—¼",
+ "d": "black medium square",
+ "u": "3.2"
+ },
+ "black_nib": {
+ "c": "objects",
+ "e": "✒",
+ "d": "black nib",
+ "u": "1.1"
+ },
+ "black_small_square": {
+ "c": "symbols",
+ "e": "â–ª",
+ "d": "black small square",
+ "u": "1.1"
+ },
+ "black_square_button": {
+ "c": "symbols",
+ "e": "🔲",
+ "d": "black square button",
+ "u": "6.0"
+ },
+ "blossom": {
+ "c": "nature",
+ "e": "🌼",
+ "d": "blossom",
+ "u": "6.0"
+ },
+ "blowfish": {
+ "c": "nature",
+ "e": "ðŸ¡",
+ "d": "blowfish",
+ "u": "6.0"
+ },
+ "blue_book": {
+ "c": "objects",
+ "e": "📘",
+ "d": "blue book",
+ "u": "6.0"
+ },
+ "blue_car": {
+ "c": "travel",
+ "e": "🚙",
+ "d": "recreational vehicle",
+ "u": "6.0"
+ },
+ "blue_heart": {
+ "c": "symbols",
+ "e": "💙",
+ "d": "blue heart",
+ "u": "6.0"
+ },
+ "blush": {
+ "c": "people",
+ "e": "😊",
+ "d": "smiling face with smiling eyes",
+ "u": "6.0"
+ },
+ "boar": {
+ "c": "nature",
+ "e": "ðŸ—",
+ "d": "boar",
+ "u": "6.0"
+ },
+ "bomb": {
+ "c": "objects",
+ "e": "💣",
+ "d": "bomb",
+ "u": "6.0"
+ },
+ "book": {
+ "c": "objects",
+ "e": "📖",
+ "d": "open book",
+ "u": "6.0"
+ },
+ "bookmark": {
+ "c": "objects",
+ "e": "🔖",
+ "d": "bookmark",
+ "u": "6.0"
+ },
+ "bookmark_tabs": {
+ "c": "objects",
+ "e": "📑",
+ "d": "bookmark tabs",
+ "u": "6.0"
+ },
+ "books": {
+ "c": "objects",
+ "e": "📚",
+ "d": "books",
+ "u": "6.0"
+ },
+ "boom": {
+ "c": "nature",
+ "e": "💥",
+ "d": "collision symbol",
+ "u": "6.0"
+ },
+ "boot": {
+ "c": "people",
+ "e": "👢",
+ "d": "womans boots",
+ "u": "6.0"
+ },
+ "bouquet": {
+ "c": "nature",
+ "e": "ðŸ’",
+ "d": "bouquet",
+ "u": "6.0"
+ },
+ "bow": {
+ "c": "people",
+ "e": "🙇",
+ "d": "person bowing deeply",
+ "u": "6.0"
+ },
+ "bow_and_arrow": {
+ "c": "activity",
+ "e": "ðŸ¹",
+ "d": "bow and arrow",
+ "u": "8.0"
+ },
+ "bow_tone1": {
+ "c": "people",
+ "e": "🙇ðŸ»",
+ "d": "person bowing deeply tone 1",
+ "u": "8.0"
+ },
+ "bow_tone2": {
+ "c": "people",
+ "e": "🙇ðŸ¼",
+ "d": "person bowing deeply tone 2",
+ "u": "8.0"
+ },
+ "bow_tone3": {
+ "c": "people",
+ "e": "🙇ðŸ½",
+ "d": "person bowing deeply tone 3",
+ "u": "8.0"
+ },
+ "bow_tone4": {
+ "c": "people",
+ "e": "🙇ðŸ¾",
+ "d": "person bowing deeply tone 4",
+ "u": "8.0"
+ },
+ "bow_tone5": {
+ "c": "people",
+ "e": "🙇ðŸ¿",
+ "d": "person bowing deeply tone 5",
+ "u": "8.0"
+ },
+ "bowling": {
+ "c": "activity",
+ "e": "🎳",
+ "d": "bowling",
+ "u": "6.0"
+ },
+ "boxing_glove": {
+ "c": "activity",
+ "e": "🥊",
+ "d": "boxing glove",
+ "u": "9.0"
+ },
+ "boy": {
+ "c": "people",
+ "e": "👦",
+ "d": "boy",
+ "u": "6.0"
+ },
+ "boy_tone1": {
+ "c": "people",
+ "e": "👦ðŸ»",
+ "d": "boy tone 1",
+ "u": "8.0"
+ },
+ "boy_tone2": {
+ "c": "people",
+ "e": "👦ðŸ¼",
+ "d": "boy tone 2",
+ "u": "8.0"
+ },
+ "boy_tone3": {
+ "c": "people",
+ "e": "👦ðŸ½",
+ "d": "boy tone 3",
+ "u": "8.0"
+ },
+ "boy_tone4": {
+ "c": "people",
+ "e": "👦ðŸ¾",
+ "d": "boy tone 4",
+ "u": "8.0"
+ },
+ "boy_tone5": {
+ "c": "people",
+ "e": "👦ðŸ¿",
+ "d": "boy tone 5",
+ "u": "8.0"
+ },
+ "bread": {
+ "c": "food",
+ "e": "ðŸž",
+ "d": "bread",
+ "u": "6.0"
+ },
+ "bride_with_veil": {
+ "c": "people",
+ "e": "👰",
+ "d": "bride with veil",
+ "u": "6.0"
+ },
+ "bride_with_veil_tone1": {
+ "c": "people",
+ "e": "👰ðŸ»",
+ "d": "bride with veil tone 1",
+ "u": "8.0"
+ },
+ "bride_with_veil_tone2": {
+ "c": "people",
+ "e": "👰ðŸ¼",
+ "d": "bride with veil tone 2",
+ "u": "8.0"
+ },
+ "bride_with_veil_tone3": {
+ "c": "people",
+ "e": "👰ðŸ½",
+ "d": "bride with veil tone 3",
+ "u": "8.0"
+ },
+ "bride_with_veil_tone4": {
+ "c": "people",
+ "e": "👰ðŸ¾",
+ "d": "bride with veil tone 4",
+ "u": "8.0"
+ },
+ "bride_with_veil_tone5": {
+ "c": "people",
+ "e": "👰ðŸ¿",
+ "d": "bride with veil tone 5",
+ "u": "8.0"
+ },
+ "bridge_at_night": {
+ "c": "travel",
+ "e": "🌉",
+ "d": "bridge at night",
+ "u": "6.0"
+ },
+ "briefcase": {
+ "c": "people",
+ "e": "💼",
+ "d": "briefcase",
+ "u": "6.0"
+ },
+ "broken_heart": {
+ "c": "symbols",
+ "e": "💔",
+ "d": "broken heart",
+ "u": "6.0"
+ },
+ "bug": {
+ "c": "nature",
+ "e": "ðŸ›",
+ "d": "bug",
+ "u": "6.0"
+ },
+ "bulb": {
+ "c": "objects",
+ "e": "💡",
+ "d": "electric light bulb",
+ "u": "6.0"
+ },
+ "bullettrain_front": {
+ "c": "travel",
+ "e": "🚅",
+ "d": "high-speed train with bullet nose",
+ "u": "6.0"
+ },
+ "bullettrain_side": {
+ "c": "travel",
+ "e": "🚄",
+ "d": "high-speed train",
+ "u": "6.0"
+ },
+ "burrito": {
+ "c": "food",
+ "e": "🌯",
+ "d": "burrito",
+ "u": "8.0"
+ },
+ "bus": {
+ "c": "travel",
+ "e": "🚌",
+ "d": "bus",
+ "u": "6.0"
+ },
+ "busstop": {
+ "c": "travel",
+ "e": "ðŸš",
+ "d": "bus stop",
+ "u": "6.0"
+ },
+ "bust_in_silhouette": {
+ "c": "people",
+ "e": "👤",
+ "d": "bust in silhouette",
+ "u": "6.0"
+ },
+ "busts_in_silhouette": {
+ "c": "people",
+ "e": "👥",
+ "d": "busts in silhouette",
+ "u": "6.0"
+ },
+ "butterfly": {
+ "c": "nature",
+ "e": "🦋",
+ "d": "butterfly",
+ "u": "9.0"
+ },
+ "cactus": {
+ "c": "nature",
+ "e": "🌵",
+ "d": "cactus",
+ "u": "6.0"
+ },
+ "cake": {
+ "c": "food",
+ "e": "ðŸ°",
+ "d": "shortcake",
+ "u": "6.0"
+ },
+ "calendar": {
+ "c": "objects",
+ "e": "📆",
+ "d": "tear-off calendar",
+ "u": "6.0"
+ },
+ "calendar_spiral": {
+ "c": "objects",
+ "e": "🗓",
+ "d": "spiral calendar pad",
+ "u": "7.0"
+ },
+ "call_me": {
+ "c": "people",
+ "e": "🤙",
+ "d": "call me hand",
+ "u": "9.0"
+ },
+ "call_me_tone1": {
+ "c": "people",
+ "e": "🤙ðŸ»",
+ "d": "call me hand tone 1",
+ "u": "9.0"
+ },
+ "call_me_tone2": {
+ "c": "people",
+ "e": "🤙ðŸ¼",
+ "d": "call me hand tone 2",
+ "u": "9.0"
+ },
+ "call_me_tone3": {
+ "c": "people",
+ "e": "🤙ðŸ½",
+ "d": "call me hand tone 3",
+ "u": "9.0"
+ },
+ "call_me_tone4": {
+ "c": "people",
+ "e": "🤙ðŸ¾",
+ "d": "call me hand tone 4",
+ "u": "9.0"
+ },
+ "call_me_tone5": {
+ "c": "people",
+ "e": "🤙ðŸ¿",
+ "d": "call me hand tone 5",
+ "u": "9.0"
+ },
+ "calling": {
+ "c": "objects",
+ "e": "📲",
+ "d": "mobile phone with rightwards arrow at left",
+ "u": "6.0"
+ },
+ "camel": {
+ "c": "nature",
+ "e": "ðŸ«",
+ "d": "bactrian camel",
+ "u": "6.0"
+ },
+ "camera": {
+ "c": "objects",
+ "e": "📷",
+ "d": "camera",
+ "u": "6.0"
+ },
+ "camera_with_flash": {
+ "c": "objects",
+ "e": "📸",
+ "d": "camera with flash",
+ "u": "7.0"
+ },
+ "camping": {
+ "c": "travel",
+ "e": "ðŸ•",
+ "d": "camping",
+ "u": "7.0"
+ },
+ "cancer": {
+ "c": "symbols",
+ "e": "♋",
+ "d": "cancer",
+ "u": "1.1"
+ },
+ "candle": {
+ "c": "objects",
+ "e": "🕯",
+ "d": "candle",
+ "u": "7.0"
+ },
+ "candy": {
+ "c": "food",
+ "e": "ðŸ¬",
+ "d": "candy",
+ "u": "6.0"
+ },
+ "canoe": {
+ "c": "travel",
+ "e": "🛶",
+ "d": "canoe",
+ "u": "9.0"
+ },
+ "capital_abcd": {
+ "c": "symbols",
+ "e": "🔠",
+ "d": "input symbol for latin capital letters",
+ "u": "6.0"
+ },
+ "capricorn": {
+ "c": "symbols",
+ "e": "♑",
+ "d": "capricorn",
+ "u": "1.1"
+ },
+ "card_box": {
+ "c": "objects",
+ "e": "🗃",
+ "d": "card file box",
+ "u": "7.0"
+ },
+ "card_index": {
+ "c": "objects",
+ "e": "📇",
+ "d": "card index",
+ "u": "6.0"
+ },
+ "carousel_horse": {
+ "c": "travel",
+ "e": "🎠",
+ "d": "carousel horse",
+ "u": "6.0"
+ },
+ "carrot": {
+ "c": "food",
+ "e": "🥕",
+ "d": "carrot",
+ "u": "9.0"
+ },
+ "cartwheel": {
+ "c": "activity",
+ "e": "🤸",
+ "d": "person doing cartwheel",
+ "u": "9.0"
+ },
+ "cartwheel_tone1": {
+ "c": "activity",
+ "e": "🤸ðŸ»",
+ "d": "person doing cartwheel tone 1",
+ "u": "9.0"
+ },
+ "cartwheel_tone2": {
+ "c": "activity",
+ "e": "🤸ðŸ¼",
+ "d": "person doing cartwheel tone 2",
+ "u": "9.0"
+ },
+ "cartwheel_tone3": {
+ "c": "activity",
+ "e": "🤸ðŸ½",
+ "d": "person doing cartwheel tone 3",
+ "u": "9.0"
+ },
+ "cartwheel_tone4": {
+ "c": "activity",
+ "e": "🤸ðŸ¾",
+ "d": "person doing cartwheel tone 4",
+ "u": "9.0"
+ },
+ "cartwheel_tone5": {
+ "c": "activity",
+ "e": "🤸ðŸ¿",
+ "d": "person doing cartwheel tone 5",
+ "u": "9.0"
+ },
+ "cat": {
+ "c": "nature",
+ "e": "ðŸ±",
+ "d": "cat face",
+ "u": "6.0"
+ },
+ "cat2": {
+ "c": "nature",
+ "e": "ðŸˆ",
+ "d": "cat",
+ "u": "6.0"
+ },
+ "cd": {
+ "c": "objects",
+ "e": "💿",
+ "d": "optical disc",
+ "u": "6.0"
+ },
+ "chains": {
+ "c": "objects",
+ "e": "⛓",
+ "d": "chains",
+ "u": "5.2"
+ },
+ "champagne": {
+ "c": "food",
+ "e": "ðŸ¾",
+ "d": "bottle with popping cork",
+ "u": "8.0"
+ },
+ "champagne_glass": {
+ "c": "food",
+ "e": "🥂",
+ "d": "clinking glasses",
+ "u": "9.0"
+ },
+ "chart": {
+ "c": "symbols",
+ "e": "💹",
+ "d": "chart with upwards trend and yen sign",
+ "u": "6.0"
+ },
+ "chart_with_downwards_trend": {
+ "c": "objects",
+ "e": "📉",
+ "d": "chart with downwards trend",
+ "u": "6.0"
+ },
+ "chart_with_upwards_trend": {
+ "c": "objects",
+ "e": "📈",
+ "d": "chart with upwards trend",
+ "u": "6.0"
+ },
+ "checkered_flag": {
+ "c": "travel",
+ "e": "ðŸ",
+ "d": "chequered flag",
+ "u": "6.0"
+ },
+ "cheese": {
+ "c": "food",
+ "e": "🧀",
+ "d": "cheese wedge",
+ "u": "8.0"
+ },
+ "cherries": {
+ "c": "food",
+ "e": "ðŸ’",
+ "d": "cherries",
+ "u": "6.0"
+ },
+ "cherry_blossom": {
+ "c": "nature",
+ "e": "🌸",
+ "d": "cherry blossom",
+ "u": "6.0"
+ },
+ "chestnut": {
+ "c": "nature",
+ "e": "🌰",
+ "d": "chestnut",
+ "u": "6.0"
+ },
+ "chicken": {
+ "c": "nature",
+ "e": "ðŸ”",
+ "d": "chicken",
+ "u": "6.0"
+ },
+ "children_crossing": {
+ "c": "symbols",
+ "e": "🚸",
+ "d": "children crossing",
+ "u": "6.0"
+ },
+ "chipmunk": {
+ "c": "nature",
+ "e": "ðŸ¿",
+ "d": "chipmunk",
+ "u": "7.0"
+ },
+ "chocolate_bar": {
+ "c": "food",
+ "e": "ðŸ«",
+ "d": "chocolate bar",
+ "u": "6.0"
+ },
+ "christmas_tree": {
+ "c": "nature",
+ "e": "🎄",
+ "d": "christmas tree",
+ "u": "6.0"
+ },
+ "church": {
+ "c": "travel",
+ "e": "⛪",
+ "d": "church",
+ "u": "5.2"
+ },
+ "cinema": {
+ "c": "symbols",
+ "e": "🎦",
+ "d": "cinema",
+ "u": "6.0"
+ },
+ "circus_tent": {
+ "c": "activity",
+ "e": "🎪",
+ "d": "circus tent",
+ "u": "6.0"
+ },
+ "city_dusk": {
+ "c": "travel",
+ "e": "🌆",
+ "d": "cityscape at dusk",
+ "u": "6.0"
+ },
+ "city_sunset": {
+ "c": "travel",
+ "e": "🌇",
+ "d": "sunset over buildings",
+ "u": "6.0"
+ },
+ "cityscape": {
+ "c": "travel",
+ "e": "ðŸ™",
+ "d": "cityscape",
+ "u": "7.0"
+ },
+ "cl": {
+ "c": "symbols",
+ "e": "🆑",
+ "d": "squared cl",
+ "u": "6.0"
+ },
+ "clap": {
+ "c": "people",
+ "e": "ðŸ‘",
+ "d": "clapping hands sign",
+ "u": "6.0"
+ },
+ "clap_tone1": {
+ "c": "people",
+ "e": "ðŸ‘ðŸ»",
+ "d": "clapping hands sign tone 1",
+ "u": "8.0"
+ },
+ "clap_tone2": {
+ "c": "people",
+ "e": "ðŸ‘ðŸ¼",
+ "d": "clapping hands sign tone 2",
+ "u": "8.0"
+ },
+ "clap_tone3": {
+ "c": "people",
+ "e": "ðŸ‘ðŸ½",
+ "d": "clapping hands sign tone 3",
+ "u": "8.0"
+ },
+ "clap_tone4": {
+ "c": "people",
+ "e": "ðŸ‘ðŸ¾",
+ "d": "clapping hands sign tone 4",
+ "u": "8.0"
+ },
+ "clap_tone5": {
+ "c": "people",
+ "e": "ðŸ‘ðŸ¿",
+ "d": "clapping hands sign tone 5",
+ "u": "8.0"
+ },
+ "clapper": {
+ "c": "activity",
+ "e": "🎬",
+ "d": "clapper board",
+ "u": "6.0"
+ },
+ "classical_building": {
+ "c": "travel",
+ "e": "ðŸ›",
+ "d": "classical building",
+ "u": "7.0"
+ },
+ "clipboard": {
+ "c": "objects",
+ "e": "📋",
+ "d": "clipboard",
+ "u": "6.0"
+ },
+ "clock": {
+ "c": "objects",
+ "e": "🕰",
+ "d": "mantlepiece clock",
+ "u": "7.0"
+ },
+ "clock1": {
+ "c": "symbols",
+ "e": "ðŸ•",
+ "d": "clock face one oclock",
+ "u": "6.0"
+ },
+ "clock10": {
+ "c": "symbols",
+ "e": "🕙",
+ "d": "clock face ten oclock",
+ "u": "6.0"
+ },
+ "clock1030": {
+ "c": "symbols",
+ "e": "🕥",
+ "d": "clock face ten-thirty",
+ "u": "6.0"
+ },
+ "clock11": {
+ "c": "symbols",
+ "e": "🕚",
+ "d": "clock face eleven oclock",
+ "u": "6.0"
+ },
+ "clock1130": {
+ "c": "symbols",
+ "e": "🕦",
+ "d": "clock face eleven-thirty",
+ "u": "6.0"
+ },
+ "clock12": {
+ "c": "symbols",
+ "e": "🕛",
+ "d": "clock face twelve oclock",
+ "u": "6.0"
+ },
+ "clock1230": {
+ "c": "symbols",
+ "e": "🕧",
+ "d": "clock face twelve-thirty",
+ "u": "6.0"
+ },
+ "clock130": {
+ "c": "symbols",
+ "e": "🕜",
+ "d": "clock face one-thirty",
+ "u": "6.0"
+ },
+ "clock2": {
+ "c": "symbols",
+ "e": "🕑",
+ "d": "clock face two oclock",
+ "u": "6.0"
+ },
+ "clock230": {
+ "c": "symbols",
+ "e": "ðŸ•",
+ "d": "clock face two-thirty",
+ "u": "6.0"
+ },
+ "clock3": {
+ "c": "symbols",
+ "e": "🕒",
+ "d": "clock face three oclock",
+ "u": "6.0"
+ },
+ "clock330": {
+ "c": "symbols",
+ "e": "🕞",
+ "d": "clock face three-thirty",
+ "u": "6.0"
+ },
+ "clock4": {
+ "c": "symbols",
+ "e": "🕓",
+ "d": "clock face four oclock",
+ "u": "6.0"
+ },
+ "clock430": {
+ "c": "symbols",
+ "e": "🕟",
+ "d": "clock face four-thirty",
+ "u": "6.0"
+ },
+ "clock5": {
+ "c": "symbols",
+ "e": "🕔",
+ "d": "clock face five oclock",
+ "u": "6.0"
+ },
+ "clock530": {
+ "c": "symbols",
+ "e": "🕠",
+ "d": "clock face five-thirty",
+ "u": "6.0"
+ },
+ "clock6": {
+ "c": "symbols",
+ "e": "🕕",
+ "d": "clock face six oclock",
+ "u": "6.0"
+ },
+ "clock630": {
+ "c": "symbols",
+ "e": "🕡",
+ "d": "clock face six-thirty",
+ "u": "6.0"
+ },
+ "clock7": {
+ "c": "symbols",
+ "e": "🕖",
+ "d": "clock face seven oclock",
+ "u": "6.0"
+ },
+ "clock730": {
+ "c": "symbols",
+ "e": "🕢",
+ "d": "clock face seven-thirty",
+ "u": "6.0"
+ },
+ "clock8": {
+ "c": "symbols",
+ "e": "🕗",
+ "d": "clock face eight oclock",
+ "u": "6.0"
+ },
+ "clock830": {
+ "c": "symbols",
+ "e": "🕣",
+ "d": "clock face eight-thirty",
+ "u": "6.0"
+ },
+ "clock9": {
+ "c": "symbols",
+ "e": "🕘",
+ "d": "clock face nine oclock",
+ "u": "6.0"
+ },
+ "clock930": {
+ "c": "symbols",
+ "e": "🕤",
+ "d": "clock face nine-thirty",
+ "u": "6.0"
+ },
+ "closed_book": {
+ "c": "objects",
+ "e": "📕",
+ "d": "closed book",
+ "u": "6.0"
+ },
+ "closed_lock_with_key": {
+ "c": "objects",
+ "e": "ðŸ”",
+ "d": "closed lock with key",
+ "u": "6.0"
+ },
+ "closed_umbrella": {
+ "c": "people",
+ "e": "🌂",
+ "d": "closed umbrella",
+ "u": "6.0"
+ },
+ "cloud": {
+ "c": "nature",
+ "e": "â˜",
+ "d": "cloud",
+ "u": "1.1"
+ },
+ "cloud_lightning": {
+ "c": "nature",
+ "e": "🌩",
+ "d": "cloud with lightning",
+ "u": "7.0"
+ },
+ "cloud_rain": {
+ "c": "nature",
+ "e": "🌧",
+ "d": "cloud with rain",
+ "u": "7.0"
+ },
+ "cloud_snow": {
+ "c": "nature",
+ "e": "🌨",
+ "d": "cloud with snow",
+ "u": "7.0"
+ },
+ "cloud_tornado": {
+ "c": "nature",
+ "e": "🌪",
+ "d": "cloud with tornado",
+ "u": "7.0"
+ },
+ "clown": {
+ "c": "people",
+ "e": "🤡",
+ "d": "clown face",
+ "u": "9.0"
+ },
+ "clubs": {
+ "c": "symbols",
+ "e": "♣",
+ "d": "black club suit",
+ "u": "1.1"
+ },
+ "cocktail": {
+ "c": "food",
+ "e": "ðŸ¸",
+ "d": "cocktail glass",
+ "u": "6.0"
+ },
+ "coffee": {
+ "c": "food",
+ "e": "☕",
+ "d": "hot beverage",
+ "u": "4.0"
+ },
+ "coffin": {
+ "c": "objects",
+ "e": "âš°",
+ "d": "coffin",
+ "u": "4.1"
+ },
+ "cold_sweat": {
+ "c": "people",
+ "e": "😰",
+ "d": "face with open mouth and cold sweat",
+ "u": "6.0"
+ },
+ "comet": {
+ "c": "nature",
+ "e": "☄",
+ "d": "comet",
+ "u": "1.1"
+ },
+ "compression": {
+ "c": "objects",
+ "e": "🗜",
+ "d": "compression",
+ "u": "7.0"
+ },
+ "computer": {
+ "c": "objects",
+ "e": "💻",
+ "d": "personal computer",
+ "u": "6.0"
+ },
+ "confetti_ball": {
+ "c": "objects",
+ "e": "🎊",
+ "d": "confetti ball",
+ "u": "6.0"
+ },
+ "confounded": {
+ "c": "people",
+ "e": "😖",
+ "d": "confounded face",
+ "u": "6.0"
+ },
+ "confused": {
+ "c": "people",
+ "e": "😕",
+ "d": "confused face",
+ "u": "6.1"
+ },
+ "congratulations": {
+ "c": "symbols",
+ "e": "㊗",
+ "d": "circled ideograph congratulation",
+ "u": "1.1"
+ },
+ "construction": {
+ "c": "travel",
+ "e": "🚧",
+ "d": "construction sign",
+ "u": "6.0"
+ },
+ "construction_site": {
+ "c": "travel",
+ "e": "ðŸ—",
+ "d": "building construction",
+ "u": "7.0"
+ },
+ "construction_worker": {
+ "c": "people",
+ "e": "👷",
+ "d": "construction worker",
+ "u": "6.0"
+ },
+ "construction_worker_tone1": {
+ "c": "people",
+ "e": "👷ðŸ»",
+ "d": "construction worker tone 1",
+ "u": "8.0"
+ },
+ "construction_worker_tone2": {
+ "c": "people",
+ "e": "👷ðŸ¼",
+ "d": "construction worker tone 2",
+ "u": "8.0"
+ },
+ "construction_worker_tone3": {
+ "c": "people",
+ "e": "👷ðŸ½",
+ "d": "construction worker tone 3",
+ "u": "8.0"
+ },
+ "construction_worker_tone4": {
+ "c": "people",
+ "e": "👷ðŸ¾",
+ "d": "construction worker tone 4",
+ "u": "8.0"
+ },
+ "construction_worker_tone5": {
+ "c": "people",
+ "e": "👷ðŸ¿",
+ "d": "construction worker tone 5",
+ "u": "8.0"
+ },
+ "control_knobs": {
+ "c": "objects",
+ "e": "🎛",
+ "d": "control knobs",
+ "u": "7.0"
+ },
+ "convenience_store": {
+ "c": "travel",
+ "e": "ðŸª",
+ "d": "convenience store",
+ "u": "6.0"
+ },
+ "cookie": {
+ "c": "food",
+ "e": "ðŸª",
+ "d": "cookie",
+ "u": "6.0"
+ },
+ "cooking": {
+ "c": "food",
+ "e": "ðŸ³",
+ "d": "cooking",
+ "u": "6.0"
+ },
+ "cool": {
+ "c": "symbols",
+ "e": "🆒",
+ "d": "squared cool",
+ "u": "6.0"
+ },
+ "cop": {
+ "c": "people",
+ "e": "👮",
+ "d": "police officer",
+ "u": "6.0"
+ },
+ "cop_tone1": {
+ "c": "people",
+ "e": "👮ðŸ»",
+ "d": "police officer tone 1",
+ "u": "8.0"
+ },
+ "cop_tone2": {
+ "c": "people",
+ "e": "👮ðŸ¼",
+ "d": "police officer tone 2",
+ "u": "8.0"
+ },
+ "cop_tone3": {
+ "c": "people",
+ "e": "👮ðŸ½",
+ "d": "police officer tone 3",
+ "u": "8.0"
+ },
+ "cop_tone4": {
+ "c": "people",
+ "e": "👮ðŸ¾",
+ "d": "police officer tone 4",
+ "u": "8.0"
+ },
+ "cop_tone5": {
+ "c": "people",
+ "e": "👮ðŸ¿",
+ "d": "police officer tone 5",
+ "u": "8.0"
+ },
+ "copyright": {
+ "c": "symbols",
+ "e": "©",
+ "d": "copyright sign",
+ "u": "1.1"
+ },
+ "corn": {
+ "c": "food",
+ "e": "🌽",
+ "d": "ear of maize",
+ "u": "6.0"
+ },
+ "couch": {
+ "c": "objects",
+ "e": "🛋",
+ "d": "couch and lamp",
+ "u": "7.0"
+ },
+ "couple": {
+ "c": "people",
+ "e": "👫",
+ "d": "man and woman holding hands",
+ "u": "6.0"
+ },
+ "couple_mm": {
+ "c": "people",
+ "e": "👨â€â¤ï¸â€ðŸ‘¨",
+ "d": "couple (man,man)",
+ "u": "6.0"
+ },
+ "couple_with_heart": {
+ "c": "people",
+ "e": "💑",
+ "d": "couple with heart",
+ "u": "6.0"
+ },
+ "couple_ww": {
+ "c": "people",
+ "e": "👩â€â¤ï¸â€ðŸ‘©",
+ "d": "couple (woman,woman)",
+ "u": "6.0"
+ },
+ "couplekiss": {
+ "c": "people",
+ "e": "ðŸ’",
+ "d": "kiss",
+ "u": "6.0"
+ },
+ "cow": {
+ "c": "nature",
+ "e": "ðŸ®",
+ "d": "cow face",
+ "u": "6.0"
+ },
+ "cow2": {
+ "c": "nature",
+ "e": "ðŸ„",
+ "d": "cow",
+ "u": "6.0"
+ },
+ "cowboy": {
+ "c": "people",
+ "e": "🤠",
+ "d": "face with cowboy hat",
+ "u": "9.0"
+ },
+ "crab": {
+ "c": "nature",
+ "e": "🦀",
+ "d": "crab",
+ "u": "8.0"
+ },
+ "crayon": {
+ "c": "objects",
+ "e": "ðŸ–",
+ "d": "lower left crayon",
+ "u": "7.0"
+ },
+ "credit_card": {
+ "c": "objects",
+ "e": "💳",
+ "d": "credit card",
+ "u": "6.0"
+ },
+ "crescent_moon": {
+ "c": "nature",
+ "e": "🌙",
+ "d": "crescent moon",
+ "u": "6.0"
+ },
+ "cricket": {
+ "c": "activity",
+ "e": "ðŸ",
+ "d": "cricket bat and ball",
+ "u": "8.0"
+ },
+ "crocodile": {
+ "c": "nature",
+ "e": "ðŸŠ",
+ "d": "crocodile",
+ "u": "6.0"
+ },
+ "croissant": {
+ "c": "food",
+ "e": "ðŸ¥",
+ "d": "croissant",
+ "u": "9.0"
+ },
+ "cross": {
+ "c": "symbols",
+ "e": "âœ",
+ "d": "latin cross",
+ "u": "1.1"
+ },
+ "crossed_flags": {
+ "c": "objects",
+ "e": "🎌",
+ "d": "crossed flags",
+ "u": "6.0"
+ },
+ "crossed_swords": {
+ "c": "objects",
+ "e": "âš”",
+ "d": "crossed swords",
+ "u": "4.1"
+ },
+ "crown": {
+ "c": "people",
+ "e": "👑",
+ "d": "crown",
+ "u": "6.0"
+ },
+ "cruise_ship": {
+ "c": "travel",
+ "e": "🛳",
+ "d": "passenger ship",
+ "u": "7.0"
+ },
+ "cry": {
+ "c": "people",
+ "e": "😢",
+ "d": "crying face",
+ "u": "6.0"
+ },
+ "crying_cat_face": {
+ "c": "people",
+ "e": "😿",
+ "d": "crying cat face",
+ "u": "6.0"
+ },
+ "crystal_ball": {
+ "c": "objects",
+ "e": "🔮",
+ "d": "crystal ball",
+ "u": "6.0"
+ },
+ "cucumber": {
+ "c": "food",
+ "e": "🥒",
+ "d": "cucumber",
+ "u": "9.0"
+ },
+ "cupid": {
+ "c": "symbols",
+ "e": "💘",
+ "d": "heart with arrow",
+ "u": "6.0"
+ },
+ "curly_loop": {
+ "c": "symbols",
+ "e": "âž°",
+ "d": "curly loop",
+ "u": "6.0"
+ },
+ "currency_exchange": {
+ "c": "symbols",
+ "e": "💱",
+ "d": "currency exchange",
+ "u": "6.0"
+ },
+ "curry": {
+ "c": "food",
+ "e": "ðŸ›",
+ "d": "curry and rice",
+ "u": "6.0"
+ },
+ "custard": {
+ "c": "food",
+ "e": "ðŸ®",
+ "d": "custard",
+ "u": "6.0"
+ },
+ "customs": {
+ "c": "symbols",
+ "e": "🛃",
+ "d": "customs",
+ "u": "6.0"
+ },
+ "cyclone": {
+ "c": "symbols",
+ "e": "🌀",
+ "d": "cyclone",
+ "u": "6.0"
+ },
+ "dagger": {
+ "c": "objects",
+ "e": "🗡",
+ "d": "dagger knife",
+ "u": "7.0"
+ },
+ "dancer": {
+ "c": "people",
+ "e": "💃",
+ "d": "dancer",
+ "u": "6.0"
+ },
+ "dancer_tone1": {
+ "c": "people",
+ "e": "💃ðŸ»",
+ "d": "dancer tone 1",
+ "u": "8.0"
+ },
+ "dancer_tone2": {
+ "c": "people",
+ "e": "💃ðŸ¼",
+ "d": "dancer tone 2",
+ "u": "8.0"
+ },
+ "dancer_tone3": {
+ "c": "people",
+ "e": "💃ðŸ½",
+ "d": "dancer tone 3",
+ "u": "8.0"
+ },
+ "dancer_tone4": {
+ "c": "people",
+ "e": "💃ðŸ¾",
+ "d": "dancer tone 4",
+ "u": "8.0"
+ },
+ "dancer_tone5": {
+ "c": "people",
+ "e": "💃ðŸ¿",
+ "d": "dancer tone 5",
+ "u": "8.0"
+ },
+ "dancers": {
+ "c": "people",
+ "e": "👯",
+ "d": "woman with bunny ears",
+ "u": "6.0"
+ },
+ "dango": {
+ "c": "food",
+ "e": "ðŸ¡",
+ "d": "dango",
+ "u": "6.0"
+ },
+ "dark_sunglasses": {
+ "c": "people",
+ "e": "🕶",
+ "d": "dark sunglasses",
+ "u": "7.0"
+ },
+ "dart": {
+ "c": "activity",
+ "e": "🎯",
+ "d": "direct hit",
+ "u": "6.0"
+ },
+ "dash": {
+ "c": "nature",
+ "e": "💨",
+ "d": "dash symbol",
+ "u": "6.0"
+ },
+ "date": {
+ "c": "objects",
+ "e": "📅",
+ "d": "calendar",
+ "u": "6.0"
+ },
+ "deciduous_tree": {
+ "c": "nature",
+ "e": "🌳",
+ "d": "deciduous tree",
+ "u": "6.0"
+ },
+ "deer": {
+ "c": "nature",
+ "e": "🦌",
+ "d": "deer",
+ "u": "9.0"
+ },
+ "department_store": {
+ "c": "travel",
+ "e": "ðŸ¬",
+ "d": "department store",
+ "u": "6.0"
+ },
+ "desert": {
+ "c": "travel",
+ "e": "ðŸœ",
+ "d": "desert",
+ "u": "7.0"
+ },
+ "desktop": {
+ "c": "objects",
+ "e": "🖥",
+ "d": "desktop computer",
+ "u": "7.0"
+ },
+ "diamond_shape_with_a_dot_inside": {
+ "c": "symbols",
+ "e": "💠",
+ "d": "diamond shape with a dot inside",
+ "u": "6.0"
+ },
+ "diamonds": {
+ "c": "symbols",
+ "e": "♦",
+ "d": "black diamond suit",
+ "u": "1.1"
+ },
+ "disappointed": {
+ "c": "people",
+ "e": "😞",
+ "d": "disappointed face",
+ "u": "6.0"
+ },
+ "disappointed_relieved": {
+ "c": "people",
+ "e": "😥",
+ "d": "disappointed but relieved face",
+ "u": "6.0"
+ },
+ "dividers": {
+ "c": "objects",
+ "e": "🗂",
+ "d": "card index dividers",
+ "u": "7.0"
+ },
+ "dizzy": {
+ "c": "nature",
+ "e": "💫",
+ "d": "dizzy symbol",
+ "u": "6.0"
+ },
+ "dizzy_face": {
+ "c": "people",
+ "e": "😵",
+ "d": "dizzy face",
+ "u": "6.0"
+ },
+ "do_not_litter": {
+ "c": "symbols",
+ "e": "🚯",
+ "d": "do not litter symbol",
+ "u": "6.0"
+ },
+ "dog": {
+ "c": "nature",
+ "e": "ðŸ¶",
+ "d": "dog face",
+ "u": "6.0"
+ },
+ "dog2": {
+ "c": "nature",
+ "e": "ðŸ•",
+ "d": "dog",
+ "u": "6.0"
+ },
+ "dollar": {
+ "c": "objects",
+ "e": "💵",
+ "d": "banknote with dollar sign",
+ "u": "6.0"
+ },
+ "dolls": {
+ "c": "objects",
+ "e": "🎎",
+ "d": "japanese dolls",
+ "u": "6.0"
+ },
+ "dolphin": {
+ "c": "nature",
+ "e": "ðŸ¬",
+ "d": "dolphin",
+ "u": "6.0"
+ },
+ "door": {
+ "c": "objects",
+ "e": "🚪",
+ "d": "door",
+ "u": "6.0"
+ },
+ "doughnut": {
+ "c": "food",
+ "e": "ðŸ©",
+ "d": "doughnut",
+ "u": "6.0"
+ },
+ "dove": {
+ "c": "nature",
+ "e": "🕊",
+ "d": "dove of peace",
+ "u": "7.0"
+ },
+ "dragon": {
+ "c": "nature",
+ "e": "ðŸ‰",
+ "d": "dragon",
+ "u": "6.0"
+ },
+ "dragon_face": {
+ "c": "nature",
+ "e": "ðŸ²",
+ "d": "dragon face",
+ "u": "6.0"
+ },
+ "dress": {
+ "c": "people",
+ "e": "👗",
+ "d": "dress",
+ "u": "6.0"
+ },
+ "dromedary_camel": {
+ "c": "nature",
+ "e": "ðŸª",
+ "d": "dromedary camel",
+ "u": "6.0"
+ },
+ "drooling_face": {
+ "c": "people",
+ "e": "🤤",
+ "d": "drooling face",
+ "u": "9.0"
+ },
+ "droplet": {
+ "c": "nature",
+ "e": "💧",
+ "d": "droplet",
+ "u": "6.0"
+ },
+ "drum": {
+ "c": "activity",
+ "e": "ðŸ¥",
+ "d": "drum with drumsticks",
+ "u": "9.0"
+ },
+ "duck": {
+ "c": "nature",
+ "e": "🦆",
+ "d": "duck",
+ "u": "9.0"
+ },
+ "dvd": {
+ "c": "objects",
+ "e": "📀",
+ "d": "dvd",
+ "u": "6.0"
+ },
+ "e-mail": {
+ "c": "objects",
+ "e": "📧",
+ "d": "e-mail symbol",
+ "u": "6.0"
+ },
+ "eagle": {
+ "c": "nature",
+ "e": "🦅",
+ "d": "eagle",
+ "u": "9.0"
+ },
+ "ear": {
+ "c": "people",
+ "e": "👂",
+ "d": "ear",
+ "u": "6.0"
+ },
+ "ear_of_rice": {
+ "c": "nature",
+ "e": "🌾",
+ "d": "ear of rice",
+ "u": "6.0"
+ },
+ "ear_tone1": {
+ "c": "people",
+ "e": "👂ðŸ»",
+ "d": "ear tone 1",
+ "u": "8.0"
+ },
+ "ear_tone2": {
+ "c": "people",
+ "e": "👂ðŸ¼",
+ "d": "ear tone 2",
+ "u": "8.0"
+ },
+ "ear_tone3": {
+ "c": "people",
+ "e": "👂ðŸ½",
+ "d": "ear tone 3",
+ "u": "8.0"
+ },
+ "ear_tone4": {
+ "c": "people",
+ "e": "👂ðŸ¾",
+ "d": "ear tone 4",
+ "u": "8.0"
+ },
+ "ear_tone5": {
+ "c": "people",
+ "e": "👂ðŸ¿",
+ "d": "ear tone 5",
+ "u": "8.0"
+ },
+ "earth_africa": {
+ "c": "nature",
+ "e": "ðŸŒ",
+ "d": "earth globe europe-africa",
+ "u": "6.0"
+ },
+ "earth_americas": {
+ "c": "nature",
+ "e": "🌎",
+ "d": "earth globe americas",
+ "u": "6.0"
+ },
+ "earth_asia": {
+ "c": "nature",
+ "e": "ðŸŒ",
+ "d": "earth globe asia-australia",
+ "u": "6.0"
+ },
+ "egg": {
+ "c": "food",
+ "e": "🥚",
+ "d": "egg",
+ "u": "9.0"
+ },
+ "eggplant": {
+ "c": "food",
+ "e": "ðŸ†",
+ "d": "aubergine",
+ "u": "6.0"
+ },
+ "eight": {
+ "c": "symbols",
+ "e": "8ï¸âƒ£",
+ "d": "keycap digit eight",
+ "u": "3.0"
+ },
+ "eight_pointed_black_star": {
+ "c": "symbols",
+ "e": "✴",
+ "d": "eight pointed black star",
+ "u": "1.1"
+ },
+ "eight_spoked_asterisk": {
+ "c": "symbols",
+ "e": "✳",
+ "d": "eight spoked asterisk",
+ "u": "1.1"
+ },
+ "eject": {
+ "c": "symbols",
+ "e": "â",
+ "d": "eject symbol",
+ "u": "4.0"
+ },
+ "electric_plug": {
+ "c": "objects",
+ "e": "🔌",
+ "d": "electric plug",
+ "u": "6.0"
+ },
+ "elephant": {
+ "c": "nature",
+ "e": "ðŸ˜",
+ "d": "elephant",
+ "u": "6.0"
+ },
+ "end": {
+ "c": "symbols",
+ "e": "🔚",
+ "d": "end with leftwards arrow above",
+ "u": "6.0"
+ },
+ "envelope": {
+ "c": "objects",
+ "e": "✉",
+ "d": "envelope",
+ "u": "1.1"
+ },
+ "envelope_with_arrow": {
+ "c": "objects",
+ "e": "📩",
+ "d": "envelope with downwards arrow above",
+ "u": "6.0"
+ },
+ "euro": {
+ "c": "objects",
+ "e": "💶",
+ "d": "banknote with euro sign",
+ "u": "6.0"
+ },
+ "european_castle": {
+ "c": "travel",
+ "e": "ðŸ°",
+ "d": "european castle",
+ "u": "6.0"
+ },
+ "european_post_office": {
+ "c": "travel",
+ "e": "ðŸ¤",
+ "d": "european post office",
+ "u": "6.0"
+ },
+ "evergreen_tree": {
+ "c": "nature",
+ "e": "🌲",
+ "d": "evergreen tree",
+ "u": "6.0"
+ },
+ "exclamation": {
+ "c": "symbols",
+ "e": "â—",
+ "d": "heavy exclamation mark symbol",
+ "u": "5.2"
+ },
+ "expressionless": {
+ "c": "people",
+ "e": "😑",
+ "d": "expressionless face",
+ "u": "6.1"
+ },
+ "eye": {
+ "c": "people",
+ "e": "ðŸ‘",
+ "d": "eye",
+ "u": "7.0"
+ },
+ "eye_in_speech_bubble": {
+ "c": "symbols",
+ "e": "ðŸ‘â€ðŸ—¨",
+ "d": "eye in speech bubble",
+ "u": "7.0"
+ },
+ "eyeglasses": {
+ "c": "people",
+ "e": "👓",
+ "d": "eyeglasses",
+ "u": "6.0"
+ },
+ "eyes": {
+ "c": "people",
+ "e": "👀",
+ "d": "eyes",
+ "u": "6.0"
+ },
+ "face_palm": {
+ "c": "people",
+ "e": "🤦",
+ "d": "face palm",
+ "u": "9.0"
+ },
+ "face_palm_tone1": {
+ "c": "people",
+ "e": "🤦ðŸ»",
+ "d": "face palm tone 1",
+ "u": "9.0"
+ },
+ "face_palm_tone2": {
+ "c": "people",
+ "e": "🤦ðŸ¼",
+ "d": "face palm tone 2",
+ "u": "9.0"
+ },
+ "face_palm_tone3": {
+ "c": "people",
+ "e": "🤦ðŸ½",
+ "d": "face palm tone 3",
+ "u": "9.0"
+ },
+ "face_palm_tone4": {
+ "c": "people",
+ "e": "🤦ðŸ¾",
+ "d": "face palm tone 4",
+ "u": "9.0"
+ },
+ "face_palm_tone5": {
+ "c": "people",
+ "e": "🤦ðŸ¿",
+ "d": "face palm tone 5",
+ "u": "9.0"
+ },
+ "factory": {
+ "c": "travel",
+ "e": "ðŸ­",
+ "d": "factory",
+ "u": "6.0"
+ },
+ "fallen_leaf": {
+ "c": "nature",
+ "e": "ðŸ‚",
+ "d": "fallen leaf",
+ "u": "6.0"
+ },
+ "family": {
+ "c": "people",
+ "e": "👪",
+ "d": "family",
+ "u": "6.0"
+ },
+ "family_mmb": {
+ "c": "people",
+ "e": "👨â€ðŸ‘¨â€ðŸ‘¦",
+ "d": "family (man,man,boy)",
+ "u": "6.0"
+ },
+ "family_mmbb": {
+ "c": "people",
+ "e": "👨â€ðŸ‘¨â€ðŸ‘¦â€ðŸ‘¦",
+ "d": "family (man,man,boy,boy)",
+ "u": "6.0"
+ },
+ "family_mmg": {
+ "c": "people",
+ "e": "👨â€ðŸ‘¨â€ðŸ‘§",
+ "d": "family (man,man,girl)",
+ "u": "6.0"
+ },
+ "family_mmgb": {
+ "c": "people",
+ "e": "👨â€ðŸ‘¨â€ðŸ‘§â€ðŸ‘¦",
+ "d": "family (man,man,girl,boy)",
+ "u": "6.0"
+ },
+ "family_mmgg": {
+ "c": "people",
+ "e": "👨â€ðŸ‘¨â€ðŸ‘§â€ðŸ‘§",
+ "d": "family (man,man,girl,girl)",
+ "u": "6.0"
+ },
+ "family_mwbb": {
+ "c": "people",
+ "e": "👨â€ðŸ‘©â€ðŸ‘¦â€ðŸ‘¦",
+ "d": "family (man,woman,boy,boy)",
+ "u": "6.0"
+ },
+ "family_mwg": {
+ "c": "people",
+ "e": "👨â€ðŸ‘©â€ðŸ‘§",
+ "d": "family (man,woman,girl)",
+ "u": "6.0"
+ },
+ "family_mwgb": {
+ "c": "people",
+ "e": "👨â€ðŸ‘©â€ðŸ‘§â€ðŸ‘¦",
+ "d": "family (man,woman,girl,boy)",
+ "u": "6.0"
+ },
+ "family_mwgg": {
+ "c": "people",
+ "e": "👨â€ðŸ‘©â€ðŸ‘§â€ðŸ‘§",
+ "d": "family (man,woman,girl,girl)",
+ "u": "6.0"
+ },
+ "family_wwb": {
+ "c": "people",
+ "e": "👩â€ðŸ‘©â€ðŸ‘¦",
+ "d": "family (woman,woman,boy)",
+ "u": "6.0"
+ },
+ "family_wwbb": {
+ "c": "people",
+ "e": "👩â€ðŸ‘©â€ðŸ‘¦â€ðŸ‘¦",
+ "d": "family (woman,woman,boy,boy)",
+ "u": "6.0"
+ },
+ "family_wwg": {
+ "c": "people",
+ "e": "👩â€ðŸ‘©â€ðŸ‘§",
+ "d": "family (woman,woman,girl)",
+ "u": "6.0"
+ },
+ "family_wwgb": {
+ "c": "people",
+ "e": "👩â€ðŸ‘©â€ðŸ‘§â€ðŸ‘¦",
+ "d": "family (woman,woman,girl,boy)",
+ "u": "6.0"
+ },
+ "family_wwgg": {
+ "c": "people",
+ "e": "👩â€ðŸ‘©â€ðŸ‘§â€ðŸ‘§",
+ "d": "family (woman,woman,girl,girl)",
+ "u": "6.0"
+ },
+ "fast_forward": {
+ "c": "symbols",
+ "e": "â©",
+ "d": "black right-pointing double triangle",
+ "u": "6.0"
+ },
+ "fax": {
+ "c": "objects",
+ "e": "📠",
+ "d": "fax machine",
+ "u": "6.0"
+ },
+ "fearful": {
+ "c": "people",
+ "e": "😨",
+ "d": "fearful face",
+ "u": "6.0"
+ },
+ "feet": {
+ "c": "nature",
+ "e": "ðŸ¾",
+ "d": "paw prints",
+ "u": "6.0"
+ },
+ "fencer": {
+ "c": "activity",
+ "e": "🤺",
+ "d": "fencer",
+ "u": "9.0"
+ },
+ "ferris_wheel": {
+ "c": "travel",
+ "e": "🎡",
+ "d": "ferris wheel",
+ "u": "6.0"
+ },
+ "ferry": {
+ "c": "travel",
+ "e": "â›´",
+ "d": "ferry",
+ "u": "5.2"
+ },
+ "field_hockey": {
+ "c": "activity",
+ "e": "ðŸ‘",
+ "d": "field hockey stick and ball",
+ "u": "8.0"
+ },
+ "file_cabinet": {
+ "c": "objects",
+ "e": "🗄",
+ "d": "file cabinet",
+ "u": "7.0"
+ },
+ "file_folder": {
+ "c": "objects",
+ "e": "ðŸ“",
+ "d": "file folder",
+ "u": "6.0"
+ },
+ "film_frames": {
+ "c": "objects",
+ "e": "🎞",
+ "d": "film frames",
+ "u": "7.0"
+ },
+ "fingers_crossed": {
+ "c": "people",
+ "e": "🤞",
+ "d": "hand with first and index finger crossed",
+ "u": "9.0"
+ },
+ "fingers_crossed_tone1": {
+ "c": "people",
+ "e": "🤞ðŸ»",
+ "d": "hand with index and middle fingers crossed tone 1",
+ "u": "9.0"
+ },
+ "fingers_crossed_tone2": {
+ "c": "people",
+ "e": "🤞ðŸ¼",
+ "d": "hand with index and middle fingers crossed tone 2",
+ "u": "9.0"
+ },
+ "fingers_crossed_tone3": {
+ "c": "people",
+ "e": "🤞ðŸ½",
+ "d": "hand with index and middle fingers crossed tone 3",
+ "u": "9.0"
+ },
+ "fingers_crossed_tone4": {
+ "c": "people",
+ "e": "🤞ðŸ¾",
+ "d": "hand with index and middle fingers crossed tone 4",
+ "u": "9.0"
+ },
+ "fingers_crossed_tone5": {
+ "c": "people",
+ "e": "🤞ðŸ¿",
+ "d": "hand with index and middle fingers crossed tone 5",
+ "u": "9.0"
+ },
+ "fire": {
+ "c": "nature",
+ "e": "🔥",
+ "d": "fire",
+ "u": "6.0"
+ },
+ "fire_engine": {
+ "c": "travel",
+ "e": "🚒",
+ "d": "fire engine",
+ "u": "6.0"
+ },
+ "fireworks": {
+ "c": "travel",
+ "e": "🎆",
+ "d": "fireworks",
+ "u": "6.0"
+ },
+ "first_place": {
+ "c": "activity",
+ "e": "🥇",
+ "d": "first place medal",
+ "u": "9.0"
+ },
+ "first_quarter_moon": {
+ "c": "nature",
+ "e": "🌓",
+ "d": "first quarter moon symbol",
+ "u": "6.0"
+ },
+ "first_quarter_moon_with_face": {
+ "c": "nature",
+ "e": "🌛",
+ "d": "first quarter moon with face",
+ "u": "6.0"
+ },
+ "fish": {
+ "c": "nature",
+ "e": "ðŸŸ",
+ "d": "fish",
+ "u": "6.0"
+ },
+ "fish_cake": {
+ "c": "food",
+ "e": "ðŸ¥",
+ "d": "fish cake with swirl design",
+ "u": "6.0"
+ },
+ "fishing_pole_and_fish": {
+ "c": "activity",
+ "e": "🎣",
+ "d": "fishing pole and fish",
+ "u": "6.0"
+ },
+ "fist": {
+ "c": "people",
+ "e": "✊",
+ "d": "raised fist",
+ "u": "6.0"
+ },
+ "fist_tone1": {
+ "c": "people",
+ "e": "✊ðŸ»",
+ "d": "raised fist tone 1",
+ "u": "8.0"
+ },
+ "fist_tone2": {
+ "c": "people",
+ "e": "✊ðŸ¼",
+ "d": "raised fist tone 2",
+ "u": "8.0"
+ },
+ "fist_tone3": {
+ "c": "people",
+ "e": "✊ðŸ½",
+ "d": "raised fist tone 3",
+ "u": "8.0"
+ },
+ "fist_tone4": {
+ "c": "people",
+ "e": "✊ðŸ¾",
+ "d": "raised fist tone 4",
+ "u": "8.0"
+ },
+ "fist_tone5": {
+ "c": "people",
+ "e": "✊ðŸ¿",
+ "d": "raised fist tone 5",
+ "u": "8.0"
+ },
+ "five": {
+ "c": "symbols",
+ "e": "5ï¸âƒ£",
+ "d": "keycap digit five",
+ "u": "3.0"
+ },
+ "flag_ac": {
+ "c": "flags",
+ "e": "🇦🇨",
+ "d": "ascension",
+ "u": "6.0"
+ },
+ "flag_ad": {
+ "c": "flags",
+ "e": "🇦🇩",
+ "d": "andorra",
+ "u": "6.0"
+ },
+ "flag_ae": {
+ "c": "flags",
+ "e": "🇦🇪",
+ "d": "the united arab emirates",
+ "u": "6.0"
+ },
+ "flag_af": {
+ "c": "flags",
+ "e": "🇦🇫",
+ "d": "afghanistan",
+ "u": "6.0"
+ },
+ "flag_ag": {
+ "c": "flags",
+ "e": "🇦🇬",
+ "d": "antigua and barbuda",
+ "u": "6.0"
+ },
+ "flag_ai": {
+ "c": "flags",
+ "e": "🇦🇮",
+ "d": "anguilla",
+ "u": "6.0"
+ },
+ "flag_al": {
+ "c": "flags",
+ "e": "🇦🇱",
+ "d": "albania",
+ "u": "6.0"
+ },
+ "flag_am": {
+ "c": "flags",
+ "e": "🇦🇲",
+ "d": "armenia",
+ "u": "6.0"
+ },
+ "flag_ao": {
+ "c": "flags",
+ "e": "🇦🇴",
+ "d": "angola",
+ "u": "6.0"
+ },
+ "flag_aq": {
+ "c": "flags",
+ "e": "🇦🇶",
+ "d": "antarctica",
+ "u": "6.0"
+ },
+ "flag_ar": {
+ "c": "flags",
+ "e": "🇦🇷",
+ "d": "argentina",
+ "u": "6.0"
+ },
+ "flag_as": {
+ "c": "flags",
+ "e": "🇦🇸",
+ "d": "american samoa",
+ "u": "6.0"
+ },
+ "flag_at": {
+ "c": "flags",
+ "e": "🇦🇹",
+ "d": "austria",
+ "u": "6.0"
+ },
+ "flag_au": {
+ "c": "flags",
+ "e": "🇦🇺",
+ "d": "australia",
+ "u": "6.0"
+ },
+ "flag_aw": {
+ "c": "flags",
+ "e": "🇦🇼",
+ "d": "aruba",
+ "u": "6.0"
+ },
+ "flag_ax": {
+ "c": "flags",
+ "e": "🇦🇽",
+ "d": "Ã¥land islands",
+ "u": "6.0"
+ },
+ "flag_az": {
+ "c": "flags",
+ "e": "🇦🇿",
+ "d": "azerbaijan",
+ "u": "6.0"
+ },
+ "flag_ba": {
+ "c": "flags",
+ "e": "🇧🇦",
+ "d": "bosnia and herzegovina",
+ "u": "6.0"
+ },
+ "flag_bb": {
+ "c": "flags",
+ "e": "🇧🇧",
+ "d": "barbados",
+ "u": "6.0"
+ },
+ "flag_bd": {
+ "c": "flags",
+ "e": "🇧🇩",
+ "d": "bangladesh",
+ "u": "6.0"
+ },
+ "flag_be": {
+ "c": "flags",
+ "e": "🇧🇪",
+ "d": "belgium",
+ "u": "6.0"
+ },
+ "flag_bf": {
+ "c": "flags",
+ "e": "🇧🇫",
+ "d": "burkina faso",
+ "u": "6.0"
+ },
+ "flag_bg": {
+ "c": "flags",
+ "e": "🇧🇬",
+ "d": "bulgaria",
+ "u": "6.0"
+ },
+ "flag_bh": {
+ "c": "flags",
+ "e": "🇧🇭",
+ "d": "bahrain",
+ "u": "6.0"
+ },
+ "flag_bi": {
+ "c": "flags",
+ "e": "🇧🇮",
+ "d": "burundi",
+ "u": "6.0"
+ },
+ "flag_bj": {
+ "c": "flags",
+ "e": "🇧🇯",
+ "d": "benin",
+ "u": "6.0"
+ },
+ "flag_bl": {
+ "c": "flags",
+ "e": "🇧🇱",
+ "d": "saint barthélemy",
+ "u": "6.0"
+ },
+ "flag_black": {
+ "c": "objects",
+ "e": "ðŸ´",
+ "d": "waving black flag",
+ "u": "6.0"
+ },
+ "flag_bm": {
+ "c": "flags",
+ "e": "🇧🇲",
+ "d": "bermuda",
+ "u": "6.0"
+ },
+ "flag_bn": {
+ "c": "flags",
+ "e": "🇧🇳",
+ "d": "brunei",
+ "u": "6.0"
+ },
+ "flag_bo": {
+ "c": "flags",
+ "e": "🇧🇴",
+ "d": "bolivia",
+ "u": "6.0"
+ },
+ "flag_bq": {
+ "c": "flags",
+ "e": "🇧🇶",
+ "d": "caribbean netherlands",
+ "u": "6.0"
+ },
+ "flag_br": {
+ "c": "flags",
+ "e": "🇧🇷",
+ "d": "brazil",
+ "u": "6.0"
+ },
+ "flag_bs": {
+ "c": "flags",
+ "e": "🇧🇸",
+ "d": "the bahamas",
+ "u": "6.0"
+ },
+ "flag_bt": {
+ "c": "flags",
+ "e": "🇧🇹",
+ "d": "bhutan",
+ "u": "6.0"
+ },
+ "flag_bv": {
+ "c": "flags",
+ "e": "🇧🇻",
+ "d": "bouvet island",
+ "u": "6.0"
+ },
+ "flag_bw": {
+ "c": "flags",
+ "e": "🇧🇼",
+ "d": "botswana",
+ "u": "6.0"
+ },
+ "flag_by": {
+ "c": "flags",
+ "e": "🇧🇾",
+ "d": "belarus",
+ "u": "6.0"
+ },
+ "flag_bz": {
+ "c": "flags",
+ "e": "🇧🇿",
+ "d": "belize",
+ "u": "6.0"
+ },
+ "flag_ca": {
+ "c": "flags",
+ "e": "🇨🇦",
+ "d": "canada",
+ "u": "6.0"
+ },
+ "flag_cc": {
+ "c": "flags",
+ "e": "🇨🇨",
+ "d": "cocos (keeling) islands",
+ "u": "6.0"
+ },
+ "flag_cd": {
+ "c": "flags",
+ "e": "🇨🇩",
+ "d": "the democratic republic of the congo",
+ "u": "6.0"
+ },
+ "flag_cf": {
+ "c": "flags",
+ "e": "🇨🇫",
+ "d": "central african republic",
+ "u": "6.0"
+ },
+ "flag_cg": {
+ "c": "flags",
+ "e": "🇨🇬",
+ "d": "the republic of the congo",
+ "u": "6.0"
+ },
+ "flag_ch": {
+ "c": "flags",
+ "e": "🇨🇭",
+ "d": "switzerland",
+ "u": "6.0"
+ },
+ "flag_ci": {
+ "c": "flags",
+ "e": "🇨🇮",
+ "d": "cote d'ivoire",
+ "u": "6.0"
+ },
+ "flag_ck": {
+ "c": "flags",
+ "e": "🇨🇰",
+ "d": "cook islands",
+ "u": "6.0"
+ },
+ "flag_cl": {
+ "c": "flags",
+ "e": "🇨🇱",
+ "d": "chile",
+ "u": "6.0"
+ },
+ "flag_cm": {
+ "c": "flags",
+ "e": "🇨🇲",
+ "d": "cameroon",
+ "u": "6.0"
+ },
+ "flag_cn": {
+ "c": "flags",
+ "e": "🇨🇳",
+ "d": "china",
+ "u": "6.0"
+ },
+ "flag_co": {
+ "c": "flags",
+ "e": "🇨🇴",
+ "d": "colombia",
+ "u": "6.0"
+ },
+ "flag_cp": {
+ "c": "flags",
+ "e": "🇨🇵",
+ "d": "clipperton island",
+ "u": "6.0"
+ },
+ "flag_cr": {
+ "c": "flags",
+ "e": "🇨🇷",
+ "d": "costa rica",
+ "u": "6.0"
+ },
+ "flag_cu": {
+ "c": "flags",
+ "e": "🇨🇺",
+ "d": "cuba",
+ "u": "6.0"
+ },
+ "flag_cv": {
+ "c": "flags",
+ "e": "🇨🇻",
+ "d": "cape verde",
+ "u": "6.0"
+ },
+ "flag_cw": {
+ "c": "flags",
+ "e": "🇨🇼",
+ "d": "curaçao",
+ "u": "6.0"
+ },
+ "flag_cx": {
+ "c": "flags",
+ "e": "🇨🇽",
+ "d": "christmas island",
+ "u": "6.0"
+ },
+ "flag_cy": {
+ "c": "flags",
+ "e": "🇨🇾",
+ "d": "cyprus",
+ "u": "6.0"
+ },
+ "flag_cz": {
+ "c": "flags",
+ "e": "🇨🇿",
+ "d": "the czech republic",
+ "u": "6.0"
+ },
+ "flag_de": {
+ "c": "flags",
+ "e": "🇩🇪",
+ "d": "germany",
+ "u": "6.0"
+ },
+ "flag_dg": {
+ "c": "flags",
+ "e": "🇩🇬",
+ "d": "diego garcia",
+ "u": "6.0"
+ },
+ "flag_dj": {
+ "c": "flags",
+ "e": "🇩🇯",
+ "d": "djibouti",
+ "u": "6.0"
+ },
+ "flag_dk": {
+ "c": "flags",
+ "e": "🇩🇰",
+ "d": "denmark",
+ "u": "6.0"
+ },
+ "flag_dm": {
+ "c": "flags",
+ "e": "🇩🇲",
+ "d": "dominica",
+ "u": "6.0"
+ },
+ "flag_do": {
+ "c": "flags",
+ "e": "🇩🇴",
+ "d": "the dominican republic",
+ "u": "6.0"
+ },
+ "flag_dz": {
+ "c": "flags",
+ "e": "🇩🇿",
+ "d": "algeria",
+ "u": "6.0"
+ },
+ "flag_ea": {
+ "c": "flags",
+ "e": "🇪🇦",
+ "d": "ceuta, melilla",
+ "u": "6.0"
+ },
+ "flag_ec": {
+ "c": "flags",
+ "e": "🇪🇨",
+ "d": "ecuador",
+ "u": "6.0"
+ },
+ "flag_ee": {
+ "c": "flags",
+ "e": "🇪🇪",
+ "d": "estonia",
+ "u": "6.0"
+ },
+ "flag_eg": {
+ "c": "flags",
+ "e": "🇪🇬",
+ "d": "egypt",
+ "u": "6.0"
+ },
+ "flag_eh": {
+ "c": "flags",
+ "e": "🇪🇭",
+ "d": "western sahara",
+ "u": "6.0"
+ },
+ "flag_er": {
+ "c": "flags",
+ "e": "🇪🇷",
+ "d": "eritrea",
+ "u": "6.0"
+ },
+ "flag_es": {
+ "c": "flags",
+ "e": "🇪🇸",
+ "d": "spain",
+ "u": "6.0"
+ },
+ "flag_et": {
+ "c": "flags",
+ "e": "🇪🇹",
+ "d": "ethiopia",
+ "u": "6.0"
+ },
+ "flag_eu": {
+ "c": "flags",
+ "e": "🇪🇺",
+ "d": "european union",
+ "u": "6.0"
+ },
+ "flag_fi": {
+ "c": "flags",
+ "e": "🇫🇮",
+ "d": "finland",
+ "u": "6.0"
+ },
+ "flag_fj": {
+ "c": "flags",
+ "e": "🇫🇯",
+ "d": "fiji",
+ "u": "6.0"
+ },
+ "flag_fk": {
+ "c": "flags",
+ "e": "🇫🇰",
+ "d": "falkland islands",
+ "u": "6.0"
+ },
+ "flag_fm": {
+ "c": "flags",
+ "e": "🇫🇲",
+ "d": "micronesia",
+ "u": "6.0"
+ },
+ "flag_fo": {
+ "c": "flags",
+ "e": "🇫🇴",
+ "d": "faroe islands",
+ "u": "6.0"
+ },
+ "flag_fr": {
+ "c": "flags",
+ "e": "🇫🇷",
+ "d": "france",
+ "u": "6.0"
+ },
+ "flag_ga": {
+ "c": "flags",
+ "e": "🇬🇦",
+ "d": "gabon",
+ "u": "6.0"
+ },
+ "flag_gb": {
+ "c": "flags",
+ "e": "🇬🇧",
+ "d": "great britain",
+ "u": "6.0"
+ },
+ "flag_gd": {
+ "c": "flags",
+ "e": "🇬🇩",
+ "d": "grenada",
+ "u": "6.0"
+ },
+ "flag_ge": {
+ "c": "flags",
+ "e": "🇬🇪",
+ "d": "georgia",
+ "u": "6.0"
+ },
+ "flag_gf": {
+ "c": "flags",
+ "e": "🇬🇫",
+ "d": "french guiana",
+ "u": "6.0"
+ },
+ "flag_gg": {
+ "c": "flags",
+ "e": "🇬🇬",
+ "d": "guernsey",
+ "u": "6.0"
+ },
+ "flag_gh": {
+ "c": "flags",
+ "e": "🇬🇭",
+ "d": "ghana",
+ "u": "6.0"
+ },
+ "flag_gi": {
+ "c": "flags",
+ "e": "🇬🇮",
+ "d": "gibraltar",
+ "u": "6.0"
+ },
+ "flag_gl": {
+ "c": "flags",
+ "e": "🇬🇱",
+ "d": "greenland",
+ "u": "6.0"
+ },
+ "flag_gm": {
+ "c": "flags",
+ "e": "🇬🇲",
+ "d": "the gambia",
+ "u": "6.0"
+ },
+ "flag_gn": {
+ "c": "flags",
+ "e": "🇬🇳",
+ "d": "guinea",
+ "u": "6.0"
+ },
+ "flag_gp": {
+ "c": "flags",
+ "e": "🇬🇵",
+ "d": "guadeloupe",
+ "u": "6.0"
+ },
+ "flag_gq": {
+ "c": "flags",
+ "e": "🇬🇶",
+ "d": "equatorial guinea",
+ "u": "6.0"
+ },
+ "flag_gr": {
+ "c": "flags",
+ "e": "🇬🇷",
+ "d": "greece",
+ "u": "6.0"
+ },
+ "flag_gs": {
+ "c": "flags",
+ "e": "🇬🇸",
+ "d": "south georgia",
+ "u": "6.0"
+ },
+ "flag_gt": {
+ "c": "flags",
+ "e": "🇬🇹",
+ "d": "guatemala",
+ "u": "6.0"
+ },
+ "flag_gu": {
+ "c": "flags",
+ "e": "🇬🇺",
+ "d": "guam",
+ "u": "6.0"
+ },
+ "flag_gw": {
+ "c": "flags",
+ "e": "🇬🇼",
+ "d": "guinea-bissau",
+ "u": "6.0"
+ },
+ "flag_gy": {
+ "c": "flags",
+ "e": "🇬🇾",
+ "d": "guyana",
+ "u": "6.0"
+ },
+ "flag_hk": {
+ "c": "flags",
+ "e": "🇭🇰",
+ "d": "hong kong",
+ "u": "6.0"
+ },
+ "flag_hm": {
+ "c": "flags",
+ "e": "🇭🇲",
+ "d": "heard island and mcdonald islands",
+ "u": "6.0"
+ },
+ "flag_hn": {
+ "c": "flags",
+ "e": "🇭🇳",
+ "d": "honduras",
+ "u": "6.0"
+ },
+ "flag_hr": {
+ "c": "flags",
+ "e": "🇭🇷",
+ "d": "croatia",
+ "u": "6.0"
+ },
+ "flag_ht": {
+ "c": "flags",
+ "e": "🇭🇹",
+ "d": "haiti",
+ "u": "6.0"
+ },
+ "flag_hu": {
+ "c": "flags",
+ "e": "🇭🇺",
+ "d": "hungary",
+ "u": "6.0"
+ },
+ "flag_ic": {
+ "c": "flags",
+ "e": "🇮🇨",
+ "d": "canary islands",
+ "u": "6.0"
+ },
+ "flag_id": {
+ "c": "flags",
+ "e": "🇮🇩",
+ "d": "indonesia",
+ "u": "6.0"
+ },
+ "flag_ie": {
+ "c": "flags",
+ "e": "🇮🇪",
+ "d": "ireland",
+ "u": "6.0"
+ },
+ "flag_il": {
+ "c": "flags",
+ "e": "🇮🇱",
+ "d": "israel",
+ "u": "6.0"
+ },
+ "flag_im": {
+ "c": "flags",
+ "e": "🇮🇲",
+ "d": "isle of man",
+ "u": "6.0"
+ },
+ "flag_in": {
+ "c": "flags",
+ "e": "🇮🇳",
+ "d": "india",
+ "u": "6.0"
+ },
+ "flag_io": {
+ "c": "flags",
+ "e": "🇮🇴",
+ "d": "british indian ocean territory",
+ "u": "6.0"
+ },
+ "flag_iq": {
+ "c": "flags",
+ "e": "🇮🇶",
+ "d": "iraq",
+ "u": "6.0"
+ },
+ "flag_ir": {
+ "c": "flags",
+ "e": "🇮🇷",
+ "d": "iran",
+ "u": "6.0"
+ },
+ "flag_is": {
+ "c": "flags",
+ "e": "🇮🇸",
+ "d": "iceland",
+ "u": "6.0"
+ },
+ "flag_it": {
+ "c": "flags",
+ "e": "🇮🇹",
+ "d": "italy",
+ "u": "6.0"
+ },
+ "flag_je": {
+ "c": "flags",
+ "e": "🇯🇪",
+ "d": "jersey",
+ "u": "6.0"
+ },
+ "flag_jm": {
+ "c": "flags",
+ "e": "🇯🇲",
+ "d": "jamaica",
+ "u": "6.0"
+ },
+ "flag_jo": {
+ "c": "flags",
+ "e": "🇯🇴",
+ "d": "jordan",
+ "u": "6.0"
+ },
+ "flag_jp": {
+ "c": "flags",
+ "e": "🇯🇵",
+ "d": "japan",
+ "u": "6.0"
+ },
+ "flag_ke": {
+ "c": "flags",
+ "e": "🇰🇪",
+ "d": "kenya",
+ "u": "6.0"
+ },
+ "flag_kg": {
+ "c": "flags",
+ "e": "🇰🇬",
+ "d": "kyrgyzstan",
+ "u": "6.0"
+ },
+ "flag_kh": {
+ "c": "flags",
+ "e": "🇰🇭",
+ "d": "cambodia",
+ "u": "6.0"
+ },
+ "flag_ki": {
+ "c": "flags",
+ "e": "🇰🇮",
+ "d": "kiribati",
+ "u": "6.0"
+ },
+ "flag_km": {
+ "c": "flags",
+ "e": "🇰🇲",
+ "d": "the comoros",
+ "u": "6.0"
+ },
+ "flag_kn": {
+ "c": "flags",
+ "e": "🇰🇳",
+ "d": "saint kitts and nevis",
+ "u": "6.0"
+ },
+ "flag_kp": {
+ "c": "flags",
+ "e": "🇰🇵",
+ "d": "north korea",
+ "u": "6.0"
+ },
+ "flag_kr": {
+ "c": "flags",
+ "e": "🇰🇷",
+ "d": "korea",
+ "u": "6.0"
+ },
+ "flag_kw": {
+ "c": "flags",
+ "e": "🇰🇼",
+ "d": "kuwait",
+ "u": "6.0"
+ },
+ "flag_ky": {
+ "c": "flags",
+ "e": "🇰🇾",
+ "d": "cayman islands",
+ "u": "6.0"
+ },
+ "flag_kz": {
+ "c": "flags",
+ "e": "🇰🇿",
+ "d": "kazakhstan",
+ "u": "6.0"
+ },
+ "flag_la": {
+ "c": "flags",
+ "e": "🇱🇦",
+ "d": "laos",
+ "u": "6.0"
+ },
+ "flag_lb": {
+ "c": "flags",
+ "e": "🇱🇧",
+ "d": "lebanon",
+ "u": "6.0"
+ },
+ "flag_lc": {
+ "c": "flags",
+ "e": "🇱🇨",
+ "d": "saint lucia",
+ "u": "6.0"
+ },
+ "flag_li": {
+ "c": "flags",
+ "e": "🇱🇮",
+ "d": "liechtenstein",
+ "u": "6.0"
+ },
+ "flag_lk": {
+ "c": "flags",
+ "e": "🇱🇰",
+ "d": "sri lanka",
+ "u": "6.0"
+ },
+ "flag_lr": {
+ "c": "flags",
+ "e": "🇱🇷",
+ "d": "liberia",
+ "u": "6.0"
+ },
+ "flag_ls": {
+ "c": "flags",
+ "e": "🇱🇸",
+ "d": "lesotho",
+ "u": "6.0"
+ },
+ "flag_lt": {
+ "c": "flags",
+ "e": "🇱🇹",
+ "d": "lithuania",
+ "u": "6.0"
+ },
+ "flag_lu": {
+ "c": "flags",
+ "e": "🇱🇺",
+ "d": "luxembourg",
+ "u": "6.0"
+ },
+ "flag_lv": {
+ "c": "flags",
+ "e": "🇱🇻",
+ "d": "latvia",
+ "u": "6.0"
+ },
+ "flag_ly": {
+ "c": "flags",
+ "e": "🇱🇾",
+ "d": "libya",
+ "u": "6.0"
+ },
+ "flag_ma": {
+ "c": "flags",
+ "e": "🇲🇦",
+ "d": "morocco",
+ "u": "6.0"
+ },
+ "flag_mc": {
+ "c": "flags",
+ "e": "🇲🇨",
+ "d": "monaco",
+ "u": "6.0"
+ },
+ "flag_md": {
+ "c": "flags",
+ "e": "🇲🇩",
+ "d": "moldova",
+ "u": "6.0"
+ },
+ "flag_me": {
+ "c": "flags",
+ "e": "🇲🇪",
+ "d": "montenegro",
+ "u": "6.0"
+ },
+ "flag_mf": {
+ "c": "flags",
+ "e": "🇲🇫",
+ "d": "saint martin",
+ "u": "6.0"
+ },
+ "flag_mg": {
+ "c": "flags",
+ "e": "🇲🇬",
+ "d": "madagascar",
+ "u": "6.0"
+ },
+ "flag_mh": {
+ "c": "flags",
+ "e": "🇲🇭",
+ "d": "the marshall islands",
+ "u": "6.0"
+ },
+ "flag_mk": {
+ "c": "flags",
+ "e": "🇲🇰",
+ "d": "macedonia",
+ "u": "6.0"
+ },
+ "flag_ml": {
+ "c": "flags",
+ "e": "🇲🇱",
+ "d": "mali",
+ "u": "6.0"
+ },
+ "flag_mm": {
+ "c": "flags",
+ "e": "🇲🇲",
+ "d": "myanmar",
+ "u": "6.0"
+ },
+ "flag_mn": {
+ "c": "flags",
+ "e": "🇲🇳",
+ "d": "mongolia",
+ "u": "6.0"
+ },
+ "flag_mo": {
+ "c": "flags",
+ "e": "🇲🇴",
+ "d": "macau",
+ "u": "6.0"
+ },
+ "flag_mp": {
+ "c": "flags",
+ "e": "🇲🇵",
+ "d": "northern mariana islands",
+ "u": "6.0"
+ },
+ "flag_mq": {
+ "c": "flags",
+ "e": "🇲🇶",
+ "d": "martinique",
+ "u": "6.0"
+ },
+ "flag_mr": {
+ "c": "flags",
+ "e": "🇲🇷",
+ "d": "mauritania",
+ "u": "6.0"
+ },
+ "flag_ms": {
+ "c": "flags",
+ "e": "🇲🇸",
+ "d": "montserrat",
+ "u": "6.0"
+ },
+ "flag_mt": {
+ "c": "flags",
+ "e": "🇲🇹",
+ "d": "malta",
+ "u": "6.0"
+ },
+ "flag_mu": {
+ "c": "flags",
+ "e": "🇲🇺",
+ "d": "mauritius",
+ "u": "6.0"
+ },
+ "flag_mv": {
+ "c": "flags",
+ "e": "🇲🇻",
+ "d": "maldives",
+ "u": "6.0"
+ },
+ "flag_mw": {
+ "c": "flags",
+ "e": "🇲🇼",
+ "d": "malawi",
+ "u": "6.0"
+ },
+ "flag_mx": {
+ "c": "flags",
+ "e": "🇲🇽",
+ "d": "mexico",
+ "u": "6.0"
+ },
+ "flag_my": {
+ "c": "flags",
+ "e": "🇲🇾",
+ "d": "malaysia",
+ "u": "6.0"
+ },
+ "flag_mz": {
+ "c": "flags",
+ "e": "🇲🇿",
+ "d": "mozambique",
+ "u": "6.0"
+ },
+ "flag_na": {
+ "c": "flags",
+ "e": "🇳🇦",
+ "d": "namibia",
+ "u": "6.0"
+ },
+ "flag_nc": {
+ "c": "flags",
+ "e": "🇳🇨",
+ "d": "new caledonia",
+ "u": "6.0"
+ },
+ "flag_ne": {
+ "c": "flags",
+ "e": "🇳🇪",
+ "d": "niger",
+ "u": "6.0"
+ },
+ "flag_nf": {
+ "c": "flags",
+ "e": "🇳🇫",
+ "d": "norfolk island",
+ "u": "6.0"
+ },
+ "flag_ng": {
+ "c": "flags",
+ "e": "🇳🇬",
+ "d": "nigeria",
+ "u": "6.0"
+ },
+ "flag_ni": {
+ "c": "flags",
+ "e": "🇳🇮",
+ "d": "nicaragua",
+ "u": "6.0"
+ },
+ "flag_nl": {
+ "c": "flags",
+ "e": "🇳🇱",
+ "d": "the netherlands",
+ "u": "6.0"
+ },
+ "flag_no": {
+ "c": "flags",
+ "e": "🇳🇴",
+ "d": "norway",
+ "u": "6.0"
+ },
+ "flag_np": {
+ "c": "flags",
+ "e": "🇳🇵",
+ "d": "nepal",
+ "u": "6.0"
+ },
+ "flag_nr": {
+ "c": "flags",
+ "e": "🇳🇷",
+ "d": "nauru",
+ "u": "6.0"
+ },
+ "flag_nu": {
+ "c": "flags",
+ "e": "🇳🇺",
+ "d": "niue",
+ "u": "6.0"
+ },
+ "flag_nz": {
+ "c": "flags",
+ "e": "🇳🇿",
+ "d": "new zealand",
+ "u": "6.0"
+ },
+ "flag_om": {
+ "c": "flags",
+ "e": "🇴🇲",
+ "d": "oman",
+ "u": "6.0"
+ },
+ "flag_pa": {
+ "c": "flags",
+ "e": "🇵🇦",
+ "d": "panama",
+ "u": "6.0"
+ },
+ "flag_pe": {
+ "c": "flags",
+ "e": "🇵🇪",
+ "d": "peru",
+ "u": "6.0"
+ },
+ "flag_pf": {
+ "c": "flags",
+ "e": "🇵🇫",
+ "d": "french polynesia",
+ "u": "6.0"
+ },
+ "flag_pg": {
+ "c": "flags",
+ "e": "🇵🇬",
+ "d": "papua new guinea",
+ "u": "6.0"
+ },
+ "flag_ph": {
+ "c": "flags",
+ "e": "🇵🇭",
+ "d": "the philippines",
+ "u": "6.0"
+ },
+ "flag_pk": {
+ "c": "flags",
+ "e": "🇵🇰",
+ "d": "pakistan",
+ "u": "6.0"
+ },
+ "flag_pl": {
+ "c": "flags",
+ "e": "🇵🇱",
+ "d": "poland",
+ "u": "6.0"
+ },
+ "flag_pm": {
+ "c": "flags",
+ "e": "🇵🇲",
+ "d": "saint pierre and miquelon",
+ "u": "6.0"
+ },
+ "flag_pn": {
+ "c": "flags",
+ "e": "🇵🇳",
+ "d": "pitcairn",
+ "u": "6.0"
+ },
+ "flag_pr": {
+ "c": "flags",
+ "e": "🇵🇷",
+ "d": "puerto rico",
+ "u": "6.0"
+ },
+ "flag_ps": {
+ "c": "flags",
+ "e": "🇵🇸",
+ "d": "palestinian authority",
+ "u": "6.0"
+ },
+ "flag_pt": {
+ "c": "flags",
+ "e": "🇵🇹",
+ "d": "portugal",
+ "u": "6.0"
+ },
+ "flag_pw": {
+ "c": "flags",
+ "e": "🇵🇼",
+ "d": "palau",
+ "u": "6.0"
+ },
+ "flag_py": {
+ "c": "flags",
+ "e": "🇵🇾",
+ "d": "paraguay",
+ "u": "6.0"
+ },
+ "flag_qa": {
+ "c": "flags",
+ "e": "🇶🇦",
+ "d": "qatar",
+ "u": "6.0"
+ },
+ "flag_re": {
+ "c": "flags",
+ "e": "🇷🇪",
+ "d": "réunion",
+ "u": "6.0"
+ },
+ "flag_ro": {
+ "c": "flags",
+ "e": "🇷🇴",
+ "d": "romania",
+ "u": "6.0"
+ },
+ "flag_rs": {
+ "c": "flags",
+ "e": "🇷🇸",
+ "d": "serbia",
+ "u": "6.0"
+ },
+ "flag_ru": {
+ "c": "flags",
+ "e": "🇷🇺",
+ "d": "russia",
+ "u": "6.0"
+ },
+ "flag_rw": {
+ "c": "flags",
+ "e": "🇷🇼",
+ "d": "rwanda",
+ "u": "6.0"
+ },
+ "flag_sa": {
+ "c": "flags",
+ "e": "🇸🇦",
+ "d": "saudi arabia",
+ "u": "6.0"
+ },
+ "flag_sb": {
+ "c": "flags",
+ "e": "🇸🇧",
+ "d": "the solomon islands",
+ "u": "6.0"
+ },
+ "flag_sc": {
+ "c": "flags",
+ "e": "🇸🇨",
+ "d": "the seychelles",
+ "u": "6.0"
+ },
+ "flag_sd": {
+ "c": "flags",
+ "e": "🇸🇩",
+ "d": "sudan",
+ "u": "6.0"
+ },
+ "flag_se": {
+ "c": "flags",
+ "e": "🇸🇪",
+ "d": "sweden",
+ "u": "6.0"
+ },
+ "flag_sg": {
+ "c": "flags",
+ "e": "🇸🇬",
+ "d": "singapore",
+ "u": "6.0"
+ },
+ "flag_sh": {
+ "c": "flags",
+ "e": "🇸🇭",
+ "d": "saint helena",
+ "u": "6.0"
+ },
+ "flag_si": {
+ "c": "flags",
+ "e": "🇸🇮",
+ "d": "slovenia",
+ "u": "6.0"
+ },
+ "flag_sj": {
+ "c": "flags",
+ "e": "🇸🇯",
+ "d": "svalbard and jan mayen",
+ "u": "6.0"
+ },
+ "flag_sk": {
+ "c": "flags",
+ "e": "🇸🇰",
+ "d": "slovakia",
+ "u": "6.0"
+ },
+ "flag_sl": {
+ "c": "flags",
+ "e": "🇸🇱",
+ "d": "sierra leone",
+ "u": "6.0"
+ },
+ "flag_sm": {
+ "c": "flags",
+ "e": "🇸🇲",
+ "d": "san marino",
+ "u": "6.0"
+ },
+ "flag_sn": {
+ "c": "flags",
+ "e": "🇸🇳",
+ "d": "senegal",
+ "u": "6.0"
+ },
+ "flag_so": {
+ "c": "flags",
+ "e": "🇸🇴",
+ "d": "somalia",
+ "u": "6.0"
+ },
+ "flag_sr": {
+ "c": "flags",
+ "e": "🇸🇷",
+ "d": "suriname",
+ "u": "6.0"
+ },
+ "flag_ss": {
+ "c": "flags",
+ "e": "🇸🇸",
+ "d": "south sudan",
+ "u": "6.0"
+ },
+ "flag_st": {
+ "c": "flags",
+ "e": "🇸🇹",
+ "d": "sao tome and principe",
+ "u": "6.0"
+ },
+ "flag_sv": {
+ "c": "flags",
+ "e": "🇸🇻",
+ "d": "el salvador",
+ "u": "6.0"
+ },
+ "flag_sx": {
+ "c": "flags",
+ "e": "🇸🇽",
+ "d": "sint maarten",
+ "u": "6.0"
+ },
+ "flag_sy": {
+ "c": "flags",
+ "e": "🇸🇾",
+ "d": "syria",
+ "u": "6.0"
+ },
+ "flag_sz": {
+ "c": "flags",
+ "e": "🇸🇿",
+ "d": "swaziland",
+ "u": "6.0"
+ },
+ "flag_ta": {
+ "c": "flags",
+ "e": "🇹🇦",
+ "d": "tristan da cunha",
+ "u": "6.0"
+ },
+ "flag_tc": {
+ "c": "flags",
+ "e": "🇹🇨",
+ "d": "turks and caicos islands",
+ "u": "6.0"
+ },
+ "flag_td": {
+ "c": "flags",
+ "e": "🇹🇩",
+ "d": "chad",
+ "u": "6.0"
+ },
+ "flag_tf": {
+ "c": "flags",
+ "e": "🇹🇫",
+ "d": "french southern territories",
+ "u": "6.0"
+ },
+ "flag_tg": {
+ "c": "flags",
+ "e": "🇹🇬",
+ "d": "togo",
+ "u": "6.0"
+ },
+ "flag_th": {
+ "c": "flags",
+ "e": "🇹🇭",
+ "d": "thailand",
+ "u": "6.0"
+ },
+ "flag_tj": {
+ "c": "flags",
+ "e": "🇹🇯",
+ "d": "tajikistan",
+ "u": "6.0"
+ },
+ "flag_tk": {
+ "c": "flags",
+ "e": "🇹🇰",
+ "d": "tokelau",
+ "u": "6.0"
+ },
+ "flag_tl": {
+ "c": "flags",
+ "e": "🇹🇱",
+ "d": "east timor",
+ "u": "6.0"
+ },
+ "flag_tm": {
+ "c": "flags",
+ "e": "🇹🇲",
+ "d": "turkmenistan",
+ "u": "6.0"
+ },
+ "flag_tn": {
+ "c": "flags",
+ "e": "🇹🇳",
+ "d": "tunisia",
+ "u": "6.0"
+ },
+ "flag_to": {
+ "c": "flags",
+ "e": "🇹🇴",
+ "d": "tonga",
+ "u": "6.0"
+ },
+ "flag_tr": {
+ "c": "flags",
+ "e": "🇹🇷",
+ "d": "turkey",
+ "u": "6.0"
+ },
+ "flag_tt": {
+ "c": "flags",
+ "e": "🇹🇹",
+ "d": "trinidad and tobago",
+ "u": "6.0"
+ },
+ "flag_tv": {
+ "c": "flags",
+ "e": "🇹🇻",
+ "d": "tuvalu",
+ "u": "6.0"
+ },
+ "flag_tw": {
+ "c": "flags",
+ "e": "🇹🇼",
+ "d": "the republic of china",
+ "u": "6.0"
+ },
+ "flag_tz": {
+ "c": "flags",
+ "e": "🇹🇿",
+ "d": "tanzania",
+ "u": "6.0"
+ },
+ "flag_ua": {
+ "c": "flags",
+ "e": "🇺🇦",
+ "d": "ukraine",
+ "u": "6.0"
+ },
+ "flag_ug": {
+ "c": "flags",
+ "e": "🇺🇬",
+ "d": "uganda",
+ "u": "6.0"
+ },
+ "flag_um": {
+ "c": "flags",
+ "e": "🇺🇲",
+ "d": "united states minor outlying islands",
+ "u": "6.0"
+ },
+ "flag_us": {
+ "c": "flags",
+ "e": "🇺🇸",
+ "d": "united states",
+ "u": "6.0"
+ },
+ "flag_uy": {
+ "c": "flags",
+ "e": "🇺🇾",
+ "d": "uruguay",
+ "u": "6.0"
+ },
+ "flag_uz": {
+ "c": "flags",
+ "e": "🇺🇿",
+ "d": "uzbekistan",
+ "u": "6.0"
+ },
+ "flag_va": {
+ "c": "flags",
+ "e": "🇻🇦",
+ "d": "the vatican city",
+ "u": "6.0"
+ },
+ "flag_vc": {
+ "c": "flags",
+ "e": "🇻🇨",
+ "d": "saint vincent and the grenadines",
+ "u": "6.0"
+ },
+ "flag_ve": {
+ "c": "flags",
+ "e": "🇻🇪",
+ "d": "venezuela",
+ "u": "6.0"
+ },
+ "flag_vg": {
+ "c": "flags",
+ "e": "🇻🇬",
+ "d": "british virgin islands",
+ "u": "6.0"
+ },
+ "flag_vi": {
+ "c": "flags",
+ "e": "🇻🇮",
+ "d": "u.s. virgin islands",
+ "u": "6.0"
+ },
+ "flag_vn": {
+ "c": "flags",
+ "e": "🇻🇳",
+ "d": "vietnam",
+ "u": "6.0"
+ },
+ "flag_vu": {
+ "c": "flags",
+ "e": "🇻🇺",
+ "d": "vanuatu",
+ "u": "6.0"
+ },
+ "flag_wf": {
+ "c": "flags",
+ "e": "🇼🇫",
+ "d": "wallis and futuna",
+ "u": "6.0"
+ },
+ "flag_white": {
+ "c": "objects",
+ "e": "ðŸ³",
+ "d": "waving white flag",
+ "u": "6.0"
+ },
+ "flag_ws": {
+ "c": "flags",
+ "e": "🇼🇸",
+ "d": "samoa",
+ "u": "6.0"
+ },
+ "flag_xk": {
+ "c": "flags",
+ "e": "🇽🇰",
+ "d": "kosovo",
+ "u": "6.0"
+ },
+ "flag_ye": {
+ "c": "flags",
+ "e": "🇾🇪",
+ "d": "yemen",
+ "u": "6.0"
+ },
+ "flag_yt": {
+ "c": "flags",
+ "e": "🇾🇹",
+ "d": "mayotte",
+ "u": "6.0"
+ },
+ "flag_za": {
+ "c": "flags",
+ "e": "🇿🇦",
+ "d": "south africa",
+ "u": "6.0"
+ },
+ "flag_zm": {
+ "c": "flags",
+ "e": "🇿🇲",
+ "d": "zambia",
+ "u": "6.0"
+ },
+ "flag_zw": {
+ "c": "flags",
+ "e": "🇿🇼",
+ "d": "zimbabwe",
+ "u": "6.0"
+ },
+ "flags": {
+ "c": "objects",
+ "e": "ðŸŽ",
+ "d": "carp streamer",
+ "u": "6.0"
+ },
+ "flashlight": {
+ "c": "objects",
+ "e": "🔦",
+ "d": "electric torch",
+ "u": "6.0"
+ },
+ "fleur-de-lis": {
+ "c": "symbols",
+ "e": "⚜",
+ "d": "fleur-de-lis",
+ "u": "4.1"
+ },
+ "floppy_disk": {
+ "c": "objects",
+ "e": "💾",
+ "d": "floppy disk",
+ "u": "6.0"
+ },
+ "flower_playing_cards": {
+ "c": "symbols",
+ "e": "🎴",
+ "d": "flower playing cards",
+ "u": "6.0"
+ },
+ "flushed": {
+ "c": "people",
+ "e": "😳",
+ "d": "flushed face",
+ "u": "6.0"
+ },
+ "fog": {
+ "c": "nature",
+ "e": "🌫",
+ "d": "fog",
+ "u": "7.0"
+ },
+ "foggy": {
+ "c": "travel",
+ "e": "ðŸŒ",
+ "d": "foggy",
+ "u": "6.0"
+ },
+ "football": {
+ "c": "activity",
+ "e": "ðŸˆ",
+ "d": "american football",
+ "u": "6.0"
+ },
+ "footprints": {
+ "c": "people",
+ "e": "👣",
+ "d": "footprints",
+ "u": "6.0"
+ },
+ "fork_and_knife": {
+ "c": "food",
+ "e": "ðŸ´",
+ "d": "fork and knife",
+ "u": "6.0"
+ },
+ "fork_knife_plate": {
+ "c": "food",
+ "e": "ðŸ½",
+ "d": "fork and knife with plate",
+ "u": "7.0"
+ },
+ "fountain": {
+ "c": "travel",
+ "e": "⛲",
+ "d": "fountain",
+ "u": "5.2"
+ },
+ "four": {
+ "c": "symbols",
+ "e": "4ï¸âƒ£",
+ "d": "keycap digit four",
+ "u": "3.0"
+ },
+ "four_leaf_clover": {
+ "c": "nature",
+ "e": "ðŸ€",
+ "d": "four leaf clover",
+ "u": "6.0"
+ },
+ "fox": {
+ "c": "nature",
+ "e": "🦊",
+ "d": "fox face",
+ "u": "9.0"
+ },
+ "frame_photo": {
+ "c": "objects",
+ "e": "🖼",
+ "d": "frame with picture",
+ "u": "7.0"
+ },
+ "free": {
+ "c": "symbols",
+ "e": "🆓",
+ "d": "squared free",
+ "u": "6.0"
+ },
+ "french_bread": {
+ "c": "food",
+ "e": "🥖",
+ "d": "baguette bread",
+ "u": "9.0"
+ },
+ "fried_shrimp": {
+ "c": "food",
+ "e": "ðŸ¤",
+ "d": "fried shrimp",
+ "u": "6.0"
+ },
+ "fries": {
+ "c": "food",
+ "e": "ðŸŸ",
+ "d": "french fries",
+ "u": "6.0"
+ },
+ "frog": {
+ "c": "nature",
+ "e": "ðŸ¸",
+ "d": "frog face",
+ "u": "6.0"
+ },
+ "frowning": {
+ "c": "people",
+ "e": "😦",
+ "d": "frowning face with open mouth",
+ "u": "6.1"
+ },
+ "frowning2": {
+ "c": "people",
+ "e": "☹",
+ "d": "white frowning face",
+ "u": "1.1"
+ },
+ "fuelpump": {
+ "c": "travel",
+ "e": "⛽",
+ "d": "fuel pump",
+ "u": "5.2"
+ },
+ "full_moon": {
+ "c": "nature",
+ "e": "🌕",
+ "d": "full moon symbol",
+ "u": "6.0"
+ },
+ "full_moon_with_face": {
+ "c": "nature",
+ "e": "ðŸŒ",
+ "d": "full moon with face",
+ "u": "6.0"
+ },
+ "game_die": {
+ "c": "activity",
+ "e": "🎲",
+ "d": "game die",
+ "u": "6.0"
+ },
+ "gear": {
+ "c": "objects",
+ "e": "âš™",
+ "d": "gear",
+ "u": "4.1"
+ },
+ "gem": {
+ "c": "objects",
+ "e": "💎",
+ "d": "gem stone",
+ "u": "6.0"
+ },
+ "gay_pride_flag": {
+ "c": "flags",
+ "e": "ðŸ³ðŸŒˆ",
+ "d": "gay_pride_flag",
+ "u": "6.0"
+ },
+ "gemini": {
+ "c": "symbols",
+ "e": "♊",
+ "d": "gemini",
+ "u": "1.1"
+ },
+ "ghost": {
+ "c": "people",
+ "e": "👻",
+ "d": "ghost",
+ "u": "6.0"
+ },
+ "gift": {
+ "c": "objects",
+ "e": "ðŸŽ",
+ "d": "wrapped present",
+ "u": "6.0"
+ },
+ "gift_heart": {
+ "c": "symbols",
+ "e": "ðŸ’",
+ "d": "heart with ribbon",
+ "u": "6.0"
+ },
+ "girl": {
+ "c": "people",
+ "e": "👧",
+ "d": "girl",
+ "u": "6.0"
+ },
+ "girl_tone1": {
+ "c": "people",
+ "e": "👧ðŸ»",
+ "d": "girl tone 1",
+ "u": "8.0"
+ },
+ "girl_tone2": {
+ "c": "people",
+ "e": "👧ðŸ¼",
+ "d": "girl tone 2",
+ "u": "8.0"
+ },
+ "girl_tone3": {
+ "c": "people",
+ "e": "👧ðŸ½",
+ "d": "girl tone 3",
+ "u": "8.0"
+ },
+ "girl_tone4": {
+ "c": "people",
+ "e": "👧ðŸ¾",
+ "d": "girl tone 4",
+ "u": "8.0"
+ },
+ "girl_tone5": {
+ "c": "people",
+ "e": "👧ðŸ¿",
+ "d": "girl tone 5",
+ "u": "8.0"
+ },
+ "globe_with_meridians": {
+ "c": "symbols",
+ "e": "ðŸŒ",
+ "d": "globe with meridians",
+ "u": "6.0"
+ },
+ "goal": {
+ "c": "activity",
+ "e": "🥅",
+ "d": "goal net",
+ "u": "9.0"
+ },
+ "goat": {
+ "c": "nature",
+ "e": "ðŸ",
+ "d": "goat",
+ "u": "6.0"
+ },
+ "golf": {
+ "c": "activity",
+ "e": "⛳",
+ "d": "flag in hole",
+ "u": "5.2"
+ },
+ "golfer": {
+ "c": "activity",
+ "e": "ðŸŒ",
+ "d": "golfer",
+ "u": "7.0"
+ },
+ "gorilla": {
+ "c": "nature",
+ "e": "ðŸ¦",
+ "d": "gorilla",
+ "u": "9.0"
+ },
+ "grapes": {
+ "c": "food",
+ "e": "ðŸ‡",
+ "d": "grapes",
+ "u": "6.0"
+ },
+ "green_apple": {
+ "c": "food",
+ "e": "ðŸ",
+ "d": "green apple",
+ "u": "6.0"
+ },
+ "green_book": {
+ "c": "objects",
+ "e": "📗",
+ "d": "green book",
+ "u": "6.0"
+ },
+ "green_heart": {
+ "c": "symbols",
+ "e": "💚",
+ "d": "green heart",
+ "u": "6.0"
+ },
+ "grey_exclamation": {
+ "c": "symbols",
+ "e": "â•",
+ "d": "white exclamation mark ornament",
+ "u": "6.0"
+ },
+ "grey_question": {
+ "c": "symbols",
+ "e": "â”",
+ "d": "white question mark ornament",
+ "u": "6.0"
+ },
+ "grimacing": {
+ "c": "people",
+ "e": "😬",
+ "d": "grimacing face",
+ "u": "6.1"
+ },
+ "grin": {
+ "c": "people",
+ "e": "ðŸ˜",
+ "d": "grinning face with smiling eyes",
+ "u": "6.0"
+ },
+ "grinning": {
+ "c": "people",
+ "e": "😀",
+ "d": "grinning face",
+ "u": "6.1"
+ },
+ "guardsman": {
+ "c": "people",
+ "e": "💂",
+ "d": "guardsman",
+ "u": "6.0"
+ },
+ "guardsman_tone1": {
+ "c": "people",
+ "e": "💂ðŸ»",
+ "d": "guardsman tone 1",
+ "u": "8.0"
+ },
+ "guardsman_tone2": {
+ "c": "people",
+ "e": "💂ðŸ¼",
+ "d": "guardsman tone 2",
+ "u": "8.0"
+ },
+ "guardsman_tone3": {
+ "c": "people",
+ "e": "💂ðŸ½",
+ "d": "guardsman tone 3",
+ "u": "8.0"
+ },
+ "guardsman_tone4": {
+ "c": "people",
+ "e": "💂ðŸ¾",
+ "d": "guardsman tone 4",
+ "u": "8.0"
+ },
+ "guardsman_tone5": {
+ "c": "people",
+ "e": "💂ðŸ¿",
+ "d": "guardsman tone 5",
+ "u": "8.0"
+ },
+ "guitar": {
+ "c": "activity",
+ "e": "🎸",
+ "d": "guitar",
+ "u": "6.0"
+ },
+ "gun": {
+ "c": "objects",
+ "e": "🔫",
+ "d": "pistol",
+ "u": "6.0"
+ },
+ "haircut": {
+ "c": "people",
+ "e": "💇",
+ "d": "haircut",
+ "u": "6.0"
+ },
+ "haircut_tone1": {
+ "c": "people",
+ "e": "💇ðŸ»",
+ "d": "haircut tone 1",
+ "u": "8.0"
+ },
+ "haircut_tone2": {
+ "c": "people",
+ "e": "💇ðŸ¼",
+ "d": "haircut tone 2",
+ "u": "8.0"
+ },
+ "haircut_tone3": {
+ "c": "people",
+ "e": "💇ðŸ½",
+ "d": "haircut tone 3",
+ "u": "8.0"
+ },
+ "haircut_tone4": {
+ "c": "people",
+ "e": "💇ðŸ¾",
+ "d": "haircut tone 4",
+ "u": "8.0"
+ },
+ "haircut_tone5": {
+ "c": "people",
+ "e": "💇ðŸ¿",
+ "d": "haircut tone 5",
+ "u": "8.0"
+ },
+ "hamburger": {
+ "c": "food",
+ "e": "ðŸ”",
+ "d": "hamburger",
+ "u": "6.0"
+ },
+ "hammer": {
+ "c": "objects",
+ "e": "🔨",
+ "d": "hammer",
+ "u": "6.0"
+ },
+ "hammer_pick": {
+ "c": "objects",
+ "e": "âš’",
+ "d": "hammer and pick",
+ "u": "4.1"
+ },
+ "hamster": {
+ "c": "nature",
+ "e": "ðŸ¹",
+ "d": "hamster face",
+ "u": "6.0"
+ },
+ "hand_splayed": {
+ "c": "people",
+ "e": "ðŸ–",
+ "d": "raised hand with fingers splayed",
+ "u": "7.0"
+ },
+ "hand_splayed_tone1": {
+ "c": "people",
+ "e": "ðŸ–ðŸ»",
+ "d": "raised hand with fingers splayed tone 1",
+ "u": "8.0"
+ },
+ "hand_splayed_tone2": {
+ "c": "people",
+ "e": "ðŸ–ðŸ¼",
+ "d": "raised hand with fingers splayed tone 2",
+ "u": "8.0"
+ },
+ "hand_splayed_tone3": {
+ "c": "people",
+ "e": "ðŸ–ðŸ½",
+ "d": "raised hand with fingers splayed tone 3",
+ "u": "8.0"
+ },
+ "hand_splayed_tone4": {
+ "c": "people",
+ "e": "ðŸ–ðŸ¾",
+ "d": "raised hand with fingers splayed tone 4",
+ "u": "8.0"
+ },
+ "hand_splayed_tone5": {
+ "c": "people",
+ "e": "ðŸ–ðŸ¿",
+ "d": "raised hand with fingers splayed tone 5",
+ "u": "8.0"
+ },
+ "handbag": {
+ "c": "people",
+ "e": "👜",
+ "d": "handbag",
+ "u": "6.0"
+ },
+ "handball": {
+ "c": "activity",
+ "e": "🤾",
+ "d": "handball",
+ "u": "9.0"
+ },
+ "handball_tone1": {
+ "c": "activity",
+ "e": "🤾ðŸ»",
+ "d": "handball tone 1",
+ "u": "9.0"
+ },
+ "handball_tone2": {
+ "c": "activity",
+ "e": "🤾ðŸ¼",
+ "d": "handball tone 2",
+ "u": "9.0"
+ },
+ "handball_tone3": {
+ "c": "activity",
+ "e": "🤾ðŸ½",
+ "d": "handball tone 3",
+ "u": "9.0"
+ },
+ "handball_tone4": {
+ "c": "activity",
+ "e": "🤾ðŸ¾",
+ "d": "handball tone 4",
+ "u": "9.0"
+ },
+ "handball_tone5": {
+ "c": "activity",
+ "e": "🤾ðŸ¿",
+ "d": "handball tone 5",
+ "u": "9.0"
+ },
+ "handshake": {
+ "c": "people",
+ "e": "ðŸ¤",
+ "d": "handshake",
+ "u": "9.0"
+ },
+ "handshake_tone1": {
+ "c": "people",
+ "e": "ðŸ¤ðŸ»",
+ "d": "handshake tone 1",
+ "u": "9.0"
+ },
+ "handshake_tone2": {
+ "c": "people",
+ "e": "ðŸ¤ðŸ¼",
+ "d": "handshake tone 2",
+ "u": "9.0"
+ },
+ "handshake_tone3": {
+ "c": "people",
+ "e": "ðŸ¤ðŸ½",
+ "d": "handshake tone 3",
+ "u": "9.0"
+ },
+ "handshake_tone4": {
+ "c": "people",
+ "e": "ðŸ¤ðŸ¾",
+ "d": "handshake tone 4",
+ "u": "9.0"
+ },
+ "handshake_tone5": {
+ "c": "people",
+ "e": "ðŸ¤ðŸ¿",
+ "d": "handshake tone 5",
+ "u": "9.0"
+ },
+ "hash": {
+ "c": "symbols",
+ "e": "#⃣",
+ "d": "number sign",
+ "u": "3.0"
+ },
+ "hatched_chick": {
+ "c": "nature",
+ "e": "ðŸ¥",
+ "d": "front-facing baby chick",
+ "u": "6.0"
+ },
+ "hatching_chick": {
+ "c": "nature",
+ "e": "ðŸ£",
+ "d": "hatching chick",
+ "u": "6.0"
+ },
+ "head_bandage": {
+ "c": "people",
+ "e": "🤕",
+ "d": "face with head-bandage",
+ "u": "8.0"
+ },
+ "headphones": {
+ "c": "activity",
+ "e": "🎧",
+ "d": "headphone",
+ "u": "6.0"
+ },
+ "hear_no_evil": {
+ "c": "nature",
+ "e": "🙉",
+ "d": "hear-no-evil monkey",
+ "u": "6.0"
+ },
+ "heart": {
+ "c": "symbols",
+ "e": "â¤",
+ "d": "heavy black heart",
+ "u": "1.1"
+ },
+ "heart_decoration": {
+ "c": "symbols",
+ "e": "💟",
+ "d": "heart decoration",
+ "u": "6.0"
+ },
+ "heart_exclamation": {
+ "c": "symbols",
+ "e": "â£",
+ "d": "heavy heart exclamation mark ornament",
+ "u": "1.1"
+ },
+ "heart_eyes": {
+ "c": "people",
+ "e": "ðŸ˜",
+ "d": "smiling face with heart-shaped eyes",
+ "u": "6.0"
+ },
+ "heart_eyes_cat": {
+ "c": "people",
+ "e": "😻",
+ "d": "smiling cat face with heart-shaped eyes",
+ "u": "6.0"
+ },
+ "heartbeat": {
+ "c": "symbols",
+ "e": "💓",
+ "d": "beating heart",
+ "u": "6.0"
+ },
+ "heartpulse": {
+ "c": "symbols",
+ "e": "💗",
+ "d": "growing heart",
+ "u": "6.0"
+ },
+ "hearts": {
+ "c": "symbols",
+ "e": "♥",
+ "d": "black heart suit",
+ "u": "1.1"
+ },
+ "heavy_check_mark": {
+ "c": "symbols",
+ "e": "✔",
+ "d": "heavy check mark",
+ "u": "1.1"
+ },
+ "heavy_division_sign": {
+ "c": "symbols",
+ "e": "âž—",
+ "d": "heavy division sign",
+ "u": "6.0"
+ },
+ "heavy_dollar_sign": {
+ "c": "symbols",
+ "e": "💲",
+ "d": "heavy dollar sign",
+ "u": "6.0"
+ },
+ "heavy_minus_sign": {
+ "c": "symbols",
+ "e": "âž–",
+ "d": "heavy minus sign",
+ "u": "6.0"
+ },
+ "heavy_multiplication_x": {
+ "c": "symbols",
+ "e": "✖",
+ "d": "heavy multiplication x",
+ "u": "1.1"
+ },
+ "heavy_plus_sign": {
+ "c": "symbols",
+ "e": "âž•",
+ "d": "heavy plus sign",
+ "u": "6.0"
+ },
+ "helicopter": {
+ "c": "travel",
+ "e": "ðŸš",
+ "d": "helicopter",
+ "u": "6.0"
+ },
+ "helmet_with_cross": {
+ "c": "people",
+ "e": "⛑",
+ "d": "helmet with white cross",
+ "u": "5.2"
+ },
+ "herb": {
+ "c": "nature",
+ "e": "🌿",
+ "d": "herb",
+ "u": "6.0"
+ },
+ "hibiscus": {
+ "c": "nature",
+ "e": "🌺",
+ "d": "hibiscus",
+ "u": "6.0"
+ },
+ "high_brightness": {
+ "c": "symbols",
+ "e": "🔆",
+ "d": "high brightness symbol",
+ "u": "6.0"
+ },
+ "high_heel": {
+ "c": "people",
+ "e": "👠",
+ "d": "high-heeled shoe",
+ "u": "6.0"
+ },
+ "hockey": {
+ "c": "activity",
+ "e": "ðŸ’",
+ "d": "ice hockey stick and puck",
+ "u": "8.0"
+ },
+ "hole": {
+ "c": "objects",
+ "e": "🕳",
+ "d": "hole",
+ "u": "7.0"
+ },
+ "homes": {
+ "c": "travel",
+ "e": "ðŸ˜",
+ "d": "house buildings",
+ "u": "7.0"
+ },
+ "honey_pot": {
+ "c": "food",
+ "e": "ðŸ¯",
+ "d": "honey pot",
+ "u": "6.0"
+ },
+ "horse": {
+ "c": "nature",
+ "e": "ðŸ´",
+ "d": "horse face",
+ "u": "6.0"
+ },
+ "horse_racing": {
+ "c": "activity",
+ "e": "ðŸ‡",
+ "d": "horse racing",
+ "u": "6.0"
+ },
+ "horse_racing_tone1": {
+ "c": "activity",
+ "e": "ðŸ‡ðŸ»",
+ "d": "horse racing tone 1",
+ "u": "8.0"
+ },
+ "horse_racing_tone2": {
+ "c": "activity",
+ "e": "ðŸ‡ðŸ¼",
+ "d": "horse racing tone 2",
+ "u": "8.0"
+ },
+ "horse_racing_tone3": {
+ "c": "activity",
+ "e": "ðŸ‡ðŸ½",
+ "d": "horse racing tone 3",
+ "u": "8.0"
+ },
+ "horse_racing_tone4": {
+ "c": "activity",
+ "e": "ðŸ‡ðŸ¾",
+ "d": "horse racing tone 4",
+ "u": "8.0"
+ },
+ "horse_racing_tone5": {
+ "c": "activity",
+ "e": "ðŸ‡ðŸ¿",
+ "d": "horse racing tone 5",
+ "u": "8.0"
+ },
+ "hospital": {
+ "c": "travel",
+ "e": "ðŸ¥",
+ "d": "hospital",
+ "u": "6.0"
+ },
+ "hot_pepper": {
+ "c": "food",
+ "e": "🌶",
+ "d": "hot pepper",
+ "u": "7.0"
+ },
+ "hotdog": {
+ "c": "food",
+ "e": "🌭",
+ "d": "hot dog",
+ "u": "8.0"
+ },
+ "hotel": {
+ "c": "travel",
+ "e": "ðŸ¨",
+ "d": "hotel",
+ "u": "6.0"
+ },
+ "hotsprings": {
+ "c": "symbols",
+ "e": "♨",
+ "d": "hot springs",
+ "u": "1.1"
+ },
+ "hourglass": {
+ "c": "objects",
+ "e": "⌛",
+ "d": "hourglass",
+ "u": "1.1"
+ },
+ "hourglass_flowing_sand": {
+ "c": "objects",
+ "e": "â³",
+ "d": "hourglass with flowing sand",
+ "u": "6.0"
+ },
+ "house": {
+ "c": "travel",
+ "e": "ðŸ ",
+ "d": "house building",
+ "u": "6.0"
+ },
+ "house_abandoned": {
+ "c": "travel",
+ "e": "ðŸš",
+ "d": "derelict house building",
+ "u": "7.0"
+ },
+ "house_with_garden": {
+ "c": "travel",
+ "e": "ðŸ¡",
+ "d": "house with garden",
+ "u": "6.0"
+ },
+ "hugging": {
+ "c": "people",
+ "e": "🤗",
+ "d": "hugging face",
+ "u": "8.0"
+ },
+ "hushed": {
+ "c": "people",
+ "e": "😯",
+ "d": "hushed face",
+ "u": "6.1"
+ },
+ "ice_cream": {
+ "c": "food",
+ "e": "ðŸ¨",
+ "d": "ice cream",
+ "u": "6.0"
+ },
+ "ice_skate": {
+ "c": "activity",
+ "e": "⛸",
+ "d": "ice skate",
+ "u": "5.2"
+ },
+ "icecream": {
+ "c": "food",
+ "e": "ðŸ¦",
+ "d": "soft ice cream",
+ "u": "6.0"
+ },
+ "id": {
+ "c": "symbols",
+ "e": "🆔",
+ "d": "squared id",
+ "u": "6.0"
+ },
+ "ideograph_advantage": {
+ "c": "symbols",
+ "e": "ðŸ‰",
+ "d": "circled ideograph advantage",
+ "u": "6.0"
+ },
+ "imp": {
+ "c": "people",
+ "e": "👿",
+ "d": "imp",
+ "u": "6.0"
+ },
+ "inbox_tray": {
+ "c": "objects",
+ "e": "📥",
+ "d": "inbox tray",
+ "u": "6.0"
+ },
+ "incoming_envelope": {
+ "c": "objects",
+ "e": "📨",
+ "d": "incoming envelope",
+ "u": "6.0"
+ },
+ "information_desk_person": {
+ "c": "people",
+ "e": "ðŸ’",
+ "d": "information desk person",
+ "u": "6.0"
+ },
+ "information_desk_person_tone1": {
+ "c": "people",
+ "e": "ðŸ’ðŸ»",
+ "d": "information desk person tone 1",
+ "u": "8.0"
+ },
+ "information_desk_person_tone2": {
+ "c": "people",
+ "e": "ðŸ’ðŸ¼",
+ "d": "information desk person tone 2",
+ "u": "8.0"
+ },
+ "information_desk_person_tone3": {
+ "c": "people",
+ "e": "ðŸ’ðŸ½",
+ "d": "information desk person tone 3",
+ "u": "8.0"
+ },
+ "information_desk_person_tone4": {
+ "c": "people",
+ "e": "ðŸ’ðŸ¾",
+ "d": "information desk person tone 4",
+ "u": "8.0"
+ },
+ "information_desk_person_tone5": {
+ "c": "people",
+ "e": "ðŸ’ðŸ¿",
+ "d": "information desk person tone 5",
+ "u": "8.0"
+ },
+ "information_source": {
+ "c": "symbols",
+ "e": "ℹ",
+ "d": "information source",
+ "u": "3.0"
+ },
+ "innocent": {
+ "c": "people",
+ "e": "😇",
+ "d": "smiling face with halo",
+ "u": "6.0"
+ },
+ "interrobang": {
+ "c": "symbols",
+ "e": "â‰",
+ "d": "exclamation question mark",
+ "u": "3.0"
+ },
+ "iphone": {
+ "c": "objects",
+ "e": "📱",
+ "d": "mobile phone",
+ "u": "6.0"
+ },
+ "island": {
+ "c": "travel",
+ "e": "ðŸ",
+ "d": "desert island",
+ "u": "7.0"
+ },
+ "izakaya_lantern": {
+ "c": "objects",
+ "e": "ðŸ®",
+ "d": "izakaya lantern",
+ "u": "6.0"
+ },
+ "jack_o_lantern": {
+ "c": "nature",
+ "e": "🎃",
+ "d": "jack-o-lantern",
+ "u": "6.0"
+ },
+ "japan": {
+ "c": "travel",
+ "e": "🗾",
+ "d": "silhouette of japan",
+ "u": "6.0"
+ },
+ "japanese_castle": {
+ "c": "travel",
+ "e": "ðŸ¯",
+ "d": "japanese castle",
+ "u": "6.0"
+ },
+ "japanese_goblin": {
+ "c": "people",
+ "e": "👺",
+ "d": "japanese goblin",
+ "u": "6.0"
+ },
+ "japanese_ogre": {
+ "c": "people",
+ "e": "👹",
+ "d": "japanese ogre",
+ "u": "6.0"
+ },
+ "jeans": {
+ "c": "people",
+ "e": "👖",
+ "d": "jeans",
+ "u": "6.0"
+ },
+ "joy": {
+ "c": "people",
+ "e": "😂",
+ "d": "face with tears of joy",
+ "u": "6.0"
+ },
+ "joy_cat": {
+ "c": "people",
+ "e": "😹",
+ "d": "cat face with tears of joy",
+ "u": "6.0"
+ },
+ "joystick": {
+ "c": "objects",
+ "e": "🕹",
+ "d": "joystick",
+ "u": "7.0"
+ },
+ "juggling": {
+ "c": "activity",
+ "e": "🤹",
+ "d": "juggling",
+ "u": "9.0"
+ },
+ "juggling_tone1": {
+ "c": "activity",
+ "e": "🤹ðŸ»",
+ "d": "juggling tone 1",
+ "u": "9.0"
+ },
+ "juggling_tone2": {
+ "c": "activity",
+ "e": "🤹ðŸ¼",
+ "d": "juggling tone 2",
+ "u": "9.0"
+ },
+ "juggling_tone3": {
+ "c": "activity",
+ "e": "🤹ðŸ½",
+ "d": "juggling tone 3",
+ "u": "9.0"
+ },
+ "juggling_tone4": {
+ "c": "activity",
+ "e": "🤹ðŸ¾",
+ "d": "juggling tone 4",
+ "u": "9.0"
+ },
+ "juggling_tone5": {
+ "c": "activity",
+ "e": "🤹ðŸ¿",
+ "d": "juggling tone 5",
+ "u": "9.0"
+ },
+ "kaaba": {
+ "c": "travel",
+ "e": "🕋",
+ "d": "kaaba",
+ "u": "8.0"
+ },
+ "key": {
+ "c": "objects",
+ "e": "🔑",
+ "d": "key",
+ "u": "6.0"
+ },
+ "key2": {
+ "c": "objects",
+ "e": "ðŸ—",
+ "d": "old key",
+ "u": "7.0"
+ },
+ "keyboard": {
+ "c": "objects",
+ "e": "⌨",
+ "d": "keyboard",
+ "u": "1.1"
+ },
+ "kimono": {
+ "c": "people",
+ "e": "👘",
+ "d": "kimono",
+ "u": "6.0"
+ },
+ "kiss": {
+ "c": "people",
+ "e": "💋",
+ "d": "kiss mark",
+ "u": "6.0"
+ },
+ "kiss_mm": {
+ "c": "people",
+ "e": "👨â€â¤ï¸â€ðŸ’‹â€ðŸ‘¨",
+ "d": "kiss (man,man)",
+ "u": "6.0"
+ },
+ "kiss_ww": {
+ "c": "people",
+ "e": "👩â€â¤ï¸â€ðŸ’‹â€ðŸ‘©",
+ "d": "kiss (woman,woman)",
+ "u": "6.0"
+ },
+ "kissing": {
+ "c": "people",
+ "e": "😗",
+ "d": "kissing face",
+ "u": "6.1"
+ },
+ "kissing_cat": {
+ "c": "people",
+ "e": "😽",
+ "d": "kissing cat face with closed eyes",
+ "u": "6.0"
+ },
+ "kissing_closed_eyes": {
+ "c": "people",
+ "e": "😚",
+ "d": "kissing face with closed eyes",
+ "u": "6.0"
+ },
+ "kissing_heart": {
+ "c": "people",
+ "e": "😘",
+ "d": "face throwing a kiss",
+ "u": "6.0"
+ },
+ "kissing_smiling_eyes": {
+ "c": "people",
+ "e": "😙",
+ "d": "kissing face with smiling eyes",
+ "u": "6.1"
+ },
+ "kiwi": {
+ "c": "food",
+ "e": "ðŸ¥",
+ "d": "kiwifruit",
+ "u": "9.0"
+ },
+ "knife": {
+ "c": "objects",
+ "e": "🔪",
+ "d": "hocho",
+ "u": "6.0"
+ },
+ "koala": {
+ "c": "nature",
+ "e": "ðŸ¨",
+ "d": "koala",
+ "u": "6.0"
+ },
+ "koko": {
+ "c": "symbols",
+ "e": "ðŸˆ",
+ "d": "squared katakana koko",
+ "u": "6.0"
+ },
+ "label": {
+ "c": "objects",
+ "e": "ðŸ·",
+ "d": "label",
+ "u": "7.0"
+ },
+ "large_blue_circle": {
+ "c": "symbols",
+ "e": "🔵",
+ "d": "large blue circle",
+ "u": "6.0"
+ },
+ "large_blue_diamond": {
+ "c": "symbols",
+ "e": "🔷",
+ "d": "large blue diamond",
+ "u": "6.0"
+ },
+ "large_orange_diamond": {
+ "c": "symbols",
+ "e": "🔶",
+ "d": "large orange diamond",
+ "u": "6.0"
+ },
+ "last_quarter_moon": {
+ "c": "nature",
+ "e": "🌗",
+ "d": "last quarter moon symbol",
+ "u": "6.0"
+ },
+ "last_quarter_moon_with_face": {
+ "c": "nature",
+ "e": "🌜",
+ "d": "last quarter moon with face",
+ "u": "6.0"
+ },
+ "laughing": {
+ "c": "people",
+ "e": "😆",
+ "d": "smiling face with open mouth and tightly-closed ey",
+ "u": "6.0"
+ },
+ "leaves": {
+ "c": "nature",
+ "e": "ðŸƒ",
+ "d": "leaf fluttering in wind",
+ "u": "6.0"
+ },
+ "ledger": {
+ "c": "objects",
+ "e": "📒",
+ "d": "ledger",
+ "u": "6.0"
+ },
+ "left_facing_fist": {
+ "c": "people",
+ "e": "🤛",
+ "d": "left-facing fist",
+ "u": "9.0"
+ },
+ "left_facing_fist_tone1": {
+ "c": "people",
+ "e": "🤛ðŸ»",
+ "d": "left facing fist tone 1",
+ "u": "9.0"
+ },
+ "left_facing_fist_tone2": {
+ "c": "people",
+ "e": "🤛ðŸ¼",
+ "d": "left facing fist tone 2",
+ "u": "9.0"
+ },
+ "left_facing_fist_tone3": {
+ "c": "people",
+ "e": "🤛ðŸ½",
+ "d": "left facing fist tone 3",
+ "u": "9.0"
+ },
+ "left_facing_fist_tone4": {
+ "c": "people",
+ "e": "🤛ðŸ¾",
+ "d": "left facing fist tone 4",
+ "u": "9.0"
+ },
+ "left_facing_fist_tone5": {
+ "c": "people",
+ "e": "🤛ðŸ¿",
+ "d": "left facing fist tone 5",
+ "u": "9.0"
+ },
+ "left_luggage": {
+ "c": "symbols",
+ "e": "🛅",
+ "d": "left luggage",
+ "u": "6.0"
+ },
+ "left_right_arrow": {
+ "c": "symbols",
+ "e": "↔",
+ "d": "left right arrow",
+ "u": "1.1"
+ },
+ "leftwards_arrow_with_hook": {
+ "c": "symbols",
+ "e": "↩",
+ "d": "leftwards arrow with hook",
+ "u": "1.1"
+ },
+ "lemon": {
+ "c": "food",
+ "e": "ðŸ‹",
+ "d": "lemon",
+ "u": "6.0"
+ },
+ "leo": {
+ "c": "symbols",
+ "e": "♌",
+ "d": "leo",
+ "u": "1.1"
+ },
+ "leopard": {
+ "c": "nature",
+ "e": "ðŸ†",
+ "d": "leopard",
+ "u": "6.0"
+ },
+ "level_slider": {
+ "c": "objects",
+ "e": "🎚",
+ "d": "level slider",
+ "u": "7.0"
+ },
+ "levitate": {
+ "c": "activity",
+ "e": "🕴",
+ "d": "man in business suit levitating",
+ "u": "7.0"
+ },
+ "libra": {
+ "c": "symbols",
+ "e": "♎",
+ "d": "libra",
+ "u": "1.1"
+ },
+ "lifter": {
+ "c": "activity",
+ "e": "ðŸ‹",
+ "d": "weight lifter",
+ "u": "7.0"
+ },
+ "lifter_tone1": {
+ "c": "activity",
+ "e": "ðŸ‹ðŸ»",
+ "d": "weight lifter tone 1",
+ "u": "8.0"
+ },
+ "lifter_tone2": {
+ "c": "activity",
+ "e": "ðŸ‹ðŸ¼",
+ "d": "weight lifter tone 2",
+ "u": "8.0"
+ },
+ "lifter_tone3": {
+ "c": "activity",
+ "e": "ðŸ‹ðŸ½",
+ "d": "weight lifter tone 3",
+ "u": "8.0"
+ },
+ "lifter_tone4": {
+ "c": "activity",
+ "e": "ðŸ‹ðŸ¾",
+ "d": "weight lifter tone 4",
+ "u": "8.0"
+ },
+ "lifter_tone5": {
+ "c": "activity",
+ "e": "ðŸ‹ðŸ¿",
+ "d": "weight lifter tone 5",
+ "u": "8.0"
+ },
+ "light_rail": {
+ "c": "travel",
+ "e": "🚈",
+ "d": "light rail",
+ "u": "6.0"
+ },
+ "link": {
+ "c": "objects",
+ "e": "🔗",
+ "d": "link symbol",
+ "u": "6.0"
+ },
+ "lion_face": {
+ "c": "nature",
+ "e": "ðŸ¦",
+ "d": "lion face",
+ "u": "8.0"
+ },
+ "lips": {
+ "c": "people",
+ "e": "👄",
+ "d": "mouth",
+ "u": "6.0"
+ },
+ "lipstick": {
+ "c": "people",
+ "e": "💄",
+ "d": "lipstick",
+ "u": "6.0"
+ },
+ "lizard": {
+ "c": "nature",
+ "e": "🦎",
+ "d": "lizard",
+ "u": "9.0"
+ },
+ "lock": {
+ "c": "objects",
+ "e": "🔒",
+ "d": "lock",
+ "u": "6.0"
+ },
+ "lock_with_ink_pen": {
+ "c": "objects",
+ "e": "ðŸ”",
+ "d": "lock with ink pen",
+ "u": "6.0"
+ },
+ "lollipop": {
+ "c": "food",
+ "e": "ðŸ­",
+ "d": "lollipop",
+ "u": "6.0"
+ },
+ "loop": {
+ "c": "symbols",
+ "e": "âž¿",
+ "d": "double curly loop",
+ "u": "6.0"
+ },
+ "loud_sound": {
+ "c": "symbols",
+ "e": "🔊",
+ "d": "speaker with three sound waves",
+ "u": "6.0"
+ },
+ "loudspeaker": {
+ "c": "symbols",
+ "e": "📢",
+ "d": "public address loudspeaker",
+ "u": "6.0"
+ },
+ "love_hotel": {
+ "c": "travel",
+ "e": "ðŸ©",
+ "d": "love hotel",
+ "u": "6.0"
+ },
+ "love_letter": {
+ "c": "objects",
+ "e": "💌",
+ "d": "love letter",
+ "u": "6.0"
+ },
+ "low_brightness": {
+ "c": "symbols",
+ "e": "🔅",
+ "d": "low brightness symbol",
+ "u": "6.0"
+ },
+ "lying_face": {
+ "c": "people",
+ "e": "🤥",
+ "d": "lying face",
+ "u": "9.0"
+ },
+ "m": {
+ "c": "symbols",
+ "e": "â“‚",
+ "d": "circled latin capital letter m",
+ "u": "1.1"
+ },
+ "mag": {
+ "c": "objects",
+ "e": "ðŸ”",
+ "d": "left-pointing magnifying glass",
+ "u": "6.0"
+ },
+ "mag_right": {
+ "c": "objects",
+ "e": "🔎",
+ "d": "right-pointing magnifying glass",
+ "u": "6.0"
+ },
+ "mahjong": {
+ "c": "symbols",
+ "e": "🀄",
+ "d": "mahjong tile red dragon",
+ "u": "5.1"
+ },
+ "mailbox": {
+ "c": "objects",
+ "e": "📫",
+ "d": "closed mailbox with raised flag",
+ "u": "6.0"
+ },
+ "mailbox_closed": {
+ "c": "objects",
+ "e": "📪",
+ "d": "closed mailbox with lowered flag",
+ "u": "6.0"
+ },
+ "mailbox_with_mail": {
+ "c": "objects",
+ "e": "📬",
+ "d": "open mailbox with raised flag",
+ "u": "6.0"
+ },
+ "mailbox_with_no_mail": {
+ "c": "objects",
+ "e": "📭",
+ "d": "open mailbox with lowered flag",
+ "u": "6.0"
+ },
+ "man": {
+ "c": "people",
+ "e": "👨",
+ "d": "man",
+ "u": "6.0"
+ },
+ "man_dancing": {
+ "c": "people",
+ "e": "🕺",
+ "d": "man dancing",
+ "u": "9.0"
+ },
+ "man_dancing_tone1": {
+ "c": "activity",
+ "e": "🕺ðŸ»",
+ "d": "man dancing tone 1",
+ "u": "9.0"
+ },
+ "man_dancing_tone2": {
+ "c": "activity",
+ "e": "🕺ðŸ¼",
+ "d": "man dancing tone 2",
+ "u": "9.0"
+ },
+ "man_dancing_tone3": {
+ "c": "activity",
+ "e": "🕺ðŸ½",
+ "d": "man dancing tone 3",
+ "u": "9.0"
+ },
+ "man_dancing_tone4": {
+ "c": "activity",
+ "e": "🕺ðŸ¾",
+ "d": "man dancing tone 4",
+ "u": "9.0"
+ },
+ "man_dancing_tone5": {
+ "c": "activity",
+ "e": "🕺ðŸ¿",
+ "d": "man dancing tone 5",
+ "u": "9.0"
+ },
+ "man_in_tuxedo": {
+ "c": "people",
+ "e": "🤵",
+ "d": "man in tuxedo",
+ "u": "9.0"
+ },
+ "man_in_tuxedo_tone1": {
+ "c": "people",
+ "e": "🤵ðŸ»",
+ "d": "man in tuxedo tone 1",
+ "u": "9.0"
+ },
+ "man_in_tuxedo_tone2": {
+ "c": "people",
+ "e": "🤵ðŸ¼",
+ "d": "man in tuxedo tone 2",
+ "u": "9.0"
+ },
+ "man_in_tuxedo_tone3": {
+ "c": "people",
+ "e": "🤵ðŸ½",
+ "d": "man in tuxedo tone 3",
+ "u": "9.0"
+ },
+ "man_in_tuxedo_tone4": {
+ "c": "people",
+ "e": "🤵ðŸ¾",
+ "d": "man in tuxedo tone 4",
+ "u": "9.0"
+ },
+ "man_in_tuxedo_tone5": {
+ "c": "people",
+ "e": "🤵ðŸ¿",
+ "d": "man in tuxedo tone 5",
+ "u": "9.0"
+ },
+ "man_tone1": {
+ "c": "people",
+ "e": "👨ðŸ»",
+ "d": "man tone 1",
+ "u": "8.0"
+ },
+ "man_tone2": {
+ "c": "people",
+ "e": "👨ðŸ¼",
+ "d": "man tone 2",
+ "u": "8.0"
+ },
+ "man_tone3": {
+ "c": "people",
+ "e": "👨ðŸ½",
+ "d": "man tone 3",
+ "u": "8.0"
+ },
+ "man_tone4": {
+ "c": "people",
+ "e": "👨ðŸ¾",
+ "d": "man tone 4",
+ "u": "8.0"
+ },
+ "man_tone5": {
+ "c": "people",
+ "e": "👨ðŸ¿",
+ "d": "man tone 5",
+ "u": "8.0"
+ },
+ "man_with_gua_pi_mao": {
+ "c": "people",
+ "e": "👲",
+ "d": "man with gua pi mao",
+ "u": "6.0"
+ },
+ "man_with_gua_pi_mao_tone1": {
+ "c": "people",
+ "e": "👲ðŸ»",
+ "d": "man with gua pi mao tone 1",
+ "u": "8.0"
+ },
+ "man_with_gua_pi_mao_tone2": {
+ "c": "people",
+ "e": "👲ðŸ¼",
+ "d": "man with gua pi mao tone 2",
+ "u": "8.0"
+ },
+ "man_with_gua_pi_mao_tone3": {
+ "c": "people",
+ "e": "👲ðŸ½",
+ "d": "man with gua pi mao tone 3",
+ "u": "8.0"
+ },
+ "man_with_gua_pi_mao_tone4": {
+ "c": "people",
+ "e": "👲ðŸ¾",
+ "d": "man with gua pi mao tone 4",
+ "u": "8.0"
+ },
+ "man_with_gua_pi_mao_tone5": {
+ "c": "people",
+ "e": "👲ðŸ¿",
+ "d": "man with gua pi mao tone 5",
+ "u": "8.0"
+ },
+ "man_with_turban": {
+ "c": "people",
+ "e": "👳",
+ "d": "man with turban",
+ "u": "6.0"
+ },
+ "man_with_turban_tone1": {
+ "c": "people",
+ "e": "👳ðŸ»",
+ "d": "man with turban tone 1",
+ "u": "8.0"
+ },
+ "man_with_turban_tone2": {
+ "c": "people",
+ "e": "👳ðŸ¼",
+ "d": "man with turban tone 2",
+ "u": "8.0"
+ },
+ "man_with_turban_tone3": {
+ "c": "people",
+ "e": "👳ðŸ½",
+ "d": "man with turban tone 3",
+ "u": "8.0"
+ },
+ "man_with_turban_tone4": {
+ "c": "people",
+ "e": "👳ðŸ¾",
+ "d": "man with turban tone 4",
+ "u": "8.0"
+ },
+ "man_with_turban_tone5": {
+ "c": "people",
+ "e": "👳ðŸ¿",
+ "d": "man with turban tone 5",
+ "u": "8.0"
+ },
+ "mans_shoe": {
+ "c": "people",
+ "e": "👞",
+ "d": "mans shoe",
+ "u": "6.0"
+ },
+ "map": {
+ "c": "objects",
+ "e": "🗺",
+ "d": "world map",
+ "u": "7.0"
+ },
+ "maple_leaf": {
+ "c": "nature",
+ "e": "ðŸ",
+ "d": "maple leaf",
+ "u": "6.0"
+ },
+ "martial_arts_uniform": {
+ "c": "activity",
+ "e": "🥋",
+ "d": "martial arts uniform",
+ "u": "9.0"
+ },
+ "mask": {
+ "c": "people",
+ "e": "😷",
+ "d": "face with medical mask",
+ "u": "6.0"
+ },
+ "massage": {
+ "c": "people",
+ "e": "💆",
+ "d": "face massage",
+ "u": "6.0"
+ },
+ "massage_tone1": {
+ "c": "people",
+ "e": "💆ðŸ»",
+ "d": "face massage tone 1",
+ "u": "8.0"
+ },
+ "massage_tone2": {
+ "c": "people",
+ "e": "💆ðŸ¼",
+ "d": "face massage tone 2",
+ "u": "8.0"
+ },
+ "massage_tone3": {
+ "c": "people",
+ "e": "💆ðŸ½",
+ "d": "face massage tone 3",
+ "u": "8.0"
+ },
+ "massage_tone4": {
+ "c": "people",
+ "e": "💆ðŸ¾",
+ "d": "face massage tone 4",
+ "u": "8.0"
+ },
+ "massage_tone5": {
+ "c": "people",
+ "e": "💆ðŸ¿",
+ "d": "face massage tone 5",
+ "u": "8.0"
+ },
+ "meat_on_bone": {
+ "c": "food",
+ "e": "ðŸ–",
+ "d": "meat on bone",
+ "u": "6.0"
+ },
+ "medal": {
+ "c": "activity",
+ "e": "ðŸ…",
+ "d": "sports medal",
+ "u": "7.0"
+ },
+ "mega": {
+ "c": "symbols",
+ "e": "📣",
+ "d": "cheering megaphone",
+ "u": "6.0"
+ },
+ "melon": {
+ "c": "food",
+ "e": "ðŸˆ",
+ "d": "melon",
+ "u": "6.0"
+ },
+ "menorah": {
+ "c": "symbols",
+ "e": "🕎",
+ "d": "menorah with nine branches",
+ "u": "8.0"
+ },
+ "mens": {
+ "c": "symbols",
+ "e": "🚹",
+ "d": "mens symbol",
+ "u": "6.0"
+ },
+ "metal": {
+ "c": "people",
+ "e": "🤘",
+ "d": "sign of the horns",
+ "u": "8.0"
+ },
+ "metal_tone1": {
+ "c": "people",
+ "e": "🤘ðŸ»",
+ "d": "sign of the horns tone 1",
+ "u": "8.0"
+ },
+ "metal_tone2": {
+ "c": "people",
+ "e": "🤘ðŸ¼",
+ "d": "sign of the horns tone 2",
+ "u": "8.0"
+ },
+ "metal_tone3": {
+ "c": "people",
+ "e": "🤘ðŸ½",
+ "d": "sign of the horns tone 3",
+ "u": "8.0"
+ },
+ "metal_tone4": {
+ "c": "people",
+ "e": "🤘ðŸ¾",
+ "d": "sign of the horns tone 4",
+ "u": "8.0"
+ },
+ "metal_tone5": {
+ "c": "people",
+ "e": "🤘ðŸ¿",
+ "d": "sign of the horns tone 5",
+ "u": "8.0"
+ },
+ "metro": {
+ "c": "travel",
+ "e": "🚇",
+ "d": "metro",
+ "u": "6.0"
+ },
+ "microphone": {
+ "c": "activity",
+ "e": "🎤",
+ "d": "microphone",
+ "u": "6.0"
+ },
+ "microphone2": {
+ "c": "objects",
+ "e": "🎙",
+ "d": "studio microphone",
+ "u": "7.0"
+ },
+ "microscope": {
+ "c": "objects",
+ "e": "🔬",
+ "d": "microscope",
+ "u": "6.0"
+ },
+ "middle_finger": {
+ "c": "people",
+ "e": "🖕",
+ "d": "reversed hand with middle finger extended",
+ "u": "7.0"
+ },
+ "middle_finger_tone1": {
+ "c": "people",
+ "e": "🖕ðŸ»",
+ "d": "reversed hand with middle finger extended tone 1",
+ "u": "8.0"
+ },
+ "middle_finger_tone2": {
+ "c": "people",
+ "e": "🖕ðŸ¼",
+ "d": "reversed hand with middle finger extended tone 2",
+ "u": "8.0"
+ },
+ "middle_finger_tone3": {
+ "c": "people",
+ "e": "🖕ðŸ½",
+ "d": "reversed hand with middle finger extended tone 3",
+ "u": "8.0"
+ },
+ "middle_finger_tone4": {
+ "c": "people",
+ "e": "🖕ðŸ¾",
+ "d": "reversed hand with middle finger extended tone 4",
+ "u": "8.0"
+ },
+ "middle_finger_tone5": {
+ "c": "people",
+ "e": "🖕ðŸ¿",
+ "d": "reversed hand with middle finger extended tone 5",
+ "u": "8.0"
+ },
+ "military_medal": {
+ "c": "activity",
+ "e": "🎖",
+ "d": "military medal",
+ "u": "7.0"
+ },
+ "milk": {
+ "c": "food",
+ "e": "🥛",
+ "d": "glass of milk",
+ "u": "9.0"
+ },
+ "milky_way": {
+ "c": "travel",
+ "e": "🌌",
+ "d": "milky way",
+ "u": "6.0"
+ },
+ "minibus": {
+ "c": "travel",
+ "e": "ðŸš",
+ "d": "minibus",
+ "u": "6.0"
+ },
+ "minidisc": {
+ "c": "objects",
+ "e": "💽",
+ "d": "minidisc",
+ "u": "6.0"
+ },
+ "mobile_phone_off": {
+ "c": "symbols",
+ "e": "📴",
+ "d": "mobile phone off",
+ "u": "6.0"
+ },
+ "money_mouth": {
+ "c": "people",
+ "e": "🤑",
+ "d": "money-mouth face",
+ "u": "8.0"
+ },
+ "money_with_wings": {
+ "c": "objects",
+ "e": "💸",
+ "d": "money with wings",
+ "u": "6.0"
+ },
+ "moneybag": {
+ "c": "objects",
+ "e": "💰",
+ "d": "money bag",
+ "u": "6.0"
+ },
+ "monkey": {
+ "c": "nature",
+ "e": "ðŸ’",
+ "d": "monkey",
+ "u": "6.0"
+ },
+ "monkey_face": {
+ "c": "nature",
+ "e": "ðŸµ",
+ "d": "monkey face",
+ "u": "6.0"
+ },
+ "monorail": {
+ "c": "travel",
+ "e": "ðŸš",
+ "d": "monorail",
+ "u": "6.0"
+ },
+ "mortar_board": {
+ "c": "people",
+ "e": "🎓",
+ "d": "graduation cap",
+ "u": "6.0"
+ },
+ "mosque": {
+ "c": "travel",
+ "e": "🕌",
+ "d": "mosque",
+ "u": "8.0"
+ },
+ "motor_scooter": {
+ "c": "travel",
+ "e": "🛵",
+ "d": "motor scooter",
+ "u": "9.0"
+ },
+ "motorboat": {
+ "c": "travel",
+ "e": "🛥",
+ "d": "motorboat",
+ "u": "7.0"
+ },
+ "motorcycle": {
+ "c": "travel",
+ "e": "ðŸ",
+ "d": "racing motorcycle",
+ "u": "7.0"
+ },
+ "motorway": {
+ "c": "travel",
+ "e": "🛣",
+ "d": "motorway",
+ "u": "7.0"
+ },
+ "mount_fuji": {
+ "c": "travel",
+ "e": "🗻",
+ "d": "mount fuji",
+ "u": "6.0"
+ },
+ "mountain": {
+ "c": "travel",
+ "e": "â›°",
+ "d": "mountain",
+ "u": "5.2"
+ },
+ "mountain_bicyclist": {
+ "c": "activity",
+ "e": "🚵",
+ "d": "mountain bicyclist",
+ "u": "6.0"
+ },
+ "mountain_bicyclist_tone1": {
+ "c": "activity",
+ "e": "🚵ðŸ»",
+ "d": "mountain bicyclist tone 1",
+ "u": "8.0"
+ },
+ "mountain_bicyclist_tone2": {
+ "c": "activity",
+ "e": "🚵ðŸ¼",
+ "d": "mountain bicyclist tone 2",
+ "u": "8.0"
+ },
+ "mountain_bicyclist_tone3": {
+ "c": "activity",
+ "e": "🚵ðŸ½",
+ "d": "mountain bicyclist tone 3",
+ "u": "8.0"
+ },
+ "mountain_bicyclist_tone4": {
+ "c": "activity",
+ "e": "🚵ðŸ¾",
+ "d": "mountain bicyclist tone 4",
+ "u": "8.0"
+ },
+ "mountain_bicyclist_tone5": {
+ "c": "activity",
+ "e": "🚵ðŸ¿",
+ "d": "mountain bicyclist tone 5",
+ "u": "8.0"
+ },
+ "mountain_cableway": {
+ "c": "travel",
+ "e": "🚠",
+ "d": "mountain cableway",
+ "u": "6.0"
+ },
+ "mountain_railway": {
+ "c": "travel",
+ "e": "🚞",
+ "d": "mountain railway",
+ "u": "6.0"
+ },
+ "mountain_snow": {
+ "c": "travel",
+ "e": "ðŸ”",
+ "d": "snow capped mountain",
+ "u": "7.0"
+ },
+ "mouse": {
+ "c": "nature",
+ "e": "ðŸ­",
+ "d": "mouse face",
+ "u": "6.0"
+ },
+ "mouse2": {
+ "c": "nature",
+ "e": "ðŸ",
+ "d": "mouse",
+ "u": "6.0"
+ },
+ "mouse_three_button": {
+ "c": "objects",
+ "e": "🖱",
+ "d": "three button mouse",
+ "u": "7.0"
+ },
+ "movie_camera": {
+ "c": "objects",
+ "e": "🎥",
+ "d": "movie camera",
+ "u": "6.0"
+ },
+ "moyai": {
+ "c": "objects",
+ "e": "🗿",
+ "d": "moyai",
+ "u": "6.0"
+ },
+ "mrs_claus": {
+ "c": "people",
+ "e": "🤶",
+ "d": "mother christmas",
+ "u": "9.0"
+ },
+ "mrs_claus_tone1": {
+ "c": "people",
+ "e": "🤶ðŸ»",
+ "d": "mother christmas tone 1",
+ "u": "9.0"
+ },
+ "mrs_claus_tone2": {
+ "c": "people",
+ "e": "🤶ðŸ¼",
+ "d": "mother christmas tone 2",
+ "u": "9.0"
+ },
+ "mrs_claus_tone3": {
+ "c": "people",
+ "e": "🤶ðŸ½",
+ "d": "mother christmas tone 3",
+ "u": "9.0"
+ },
+ "mrs_claus_tone4": {
+ "c": "people",
+ "e": "🤶ðŸ¾",
+ "d": "mother christmas tone 4",
+ "u": "9.0"
+ },
+ "mrs_claus_tone5": {
+ "c": "people",
+ "e": "🤶ðŸ¿",
+ "d": "mother christmas tone 5",
+ "u": "9.0"
+ },
+ "muscle": {
+ "c": "people",
+ "e": "💪",
+ "d": "flexed biceps",
+ "u": "6.0"
+ },
+ "muscle_tone1": {
+ "c": "people",
+ "e": "💪ðŸ»",
+ "d": "flexed biceps tone 1",
+ "u": "8.0"
+ },
+ "muscle_tone2": {
+ "c": "people",
+ "e": "💪ðŸ¼",
+ "d": "flexed biceps tone 2",
+ "u": "8.0"
+ },
+ "muscle_tone3": {
+ "c": "people",
+ "e": "💪ðŸ½",
+ "d": "flexed biceps tone 3",
+ "u": "8.0"
+ },
+ "muscle_tone4": {
+ "c": "people",
+ "e": "💪ðŸ¾",
+ "d": "flexed biceps tone 4",
+ "u": "8.0"
+ },
+ "muscle_tone5": {
+ "c": "people",
+ "e": "💪ðŸ¿",
+ "d": "flexed biceps tone 5",
+ "u": "8.0"
+ },
+ "mushroom": {
+ "c": "nature",
+ "e": "ðŸ„",
+ "d": "mushroom",
+ "u": "6.0"
+ },
+ "musical_keyboard": {
+ "c": "activity",
+ "e": "🎹",
+ "d": "musical keyboard",
+ "u": "6.0"
+ },
+ "musical_note": {
+ "c": "symbols",
+ "e": "🎵",
+ "d": "musical note",
+ "u": "6.0"
+ },
+ "musical_score": {
+ "c": "activity",
+ "e": "🎼",
+ "d": "musical score",
+ "u": "6.0"
+ },
+ "mute": {
+ "c": "symbols",
+ "e": "🔇",
+ "d": "speaker with cancellation stroke",
+ "u": "6.0"
+ },
+ "nail_care": {
+ "c": "people",
+ "e": "💅",
+ "d": "nail polish",
+ "u": "6.0"
+ },
+ "nail_care_tone1": {
+ "c": "people",
+ "e": "💅ðŸ»",
+ "d": "nail polish tone 1",
+ "u": "8.0"
+ },
+ "nail_care_tone2": {
+ "c": "people",
+ "e": "💅ðŸ¼",
+ "d": "nail polish tone 2",
+ "u": "8.0"
+ },
+ "nail_care_tone3": {
+ "c": "people",
+ "e": "💅ðŸ½",
+ "d": "nail polish tone 3",
+ "u": "8.0"
+ },
+ "nail_care_tone4": {
+ "c": "people",
+ "e": "💅ðŸ¾",
+ "d": "nail polish tone 4",
+ "u": "8.0"
+ },
+ "nail_care_tone5": {
+ "c": "people",
+ "e": "💅ðŸ¿",
+ "d": "nail polish tone 5",
+ "u": "8.0"
+ },
+ "name_badge": {
+ "c": "symbols",
+ "e": "📛",
+ "d": "name badge",
+ "u": "6.0"
+ },
+ "nauseated_face": {
+ "c": "people",
+ "e": "🤢",
+ "d": "nauseated face",
+ "u": "9.0"
+ },
+ "necktie": {
+ "c": "people",
+ "e": "👔",
+ "d": "necktie",
+ "u": "6.0"
+ },
+ "negative_squared_cross_mark": {
+ "c": "symbols",
+ "e": "âŽ",
+ "d": "negative squared cross mark",
+ "u": "6.0"
+ },
+ "nerd": {
+ "c": "people",
+ "e": "🤓",
+ "d": "nerd face",
+ "u": "8.0"
+ },
+ "neutral_face": {
+ "c": "people",
+ "e": "ðŸ˜",
+ "d": "neutral face",
+ "u": "6.0"
+ },
+ "new": {
+ "c": "symbols",
+ "e": "🆕",
+ "d": "squared new",
+ "u": "6.0"
+ },
+ "new_moon": {
+ "c": "nature",
+ "e": "🌑",
+ "d": "new moon symbol",
+ "u": "6.0"
+ },
+ "new_moon_with_face": {
+ "c": "nature",
+ "e": "🌚",
+ "d": "new moon with face",
+ "u": "6.0"
+ },
+ "newspaper": {
+ "c": "objects",
+ "e": "📰",
+ "d": "newspaper",
+ "u": "6.0"
+ },
+ "newspaper2": {
+ "c": "objects",
+ "e": "🗞",
+ "d": "rolled-up newspaper",
+ "u": "7.0"
+ },
+ "ng": {
+ "c": "symbols",
+ "e": "🆖",
+ "d": "squared ng",
+ "u": "6.0"
+ },
+ "night_with_stars": {
+ "c": "travel",
+ "e": "🌃",
+ "d": "night with stars",
+ "u": "6.0"
+ },
+ "nine": {
+ "c": "symbols",
+ "e": "9ï¸âƒ£",
+ "d": "keycap digit nine",
+ "u": "3.0"
+ },
+ "no_bell": {
+ "c": "symbols",
+ "e": "🔕",
+ "d": "bell with cancellation stroke",
+ "u": "6.0"
+ },
+ "no_bicycles": {
+ "c": "symbols",
+ "e": "🚳",
+ "d": "no bicycles",
+ "u": "6.0"
+ },
+ "no_entry": {
+ "c": "symbols",
+ "e": "â›”",
+ "d": "no entry",
+ "u": "5.2"
+ },
+ "no_entry_sign": {
+ "c": "symbols",
+ "e": "🚫",
+ "d": "no entry sign",
+ "u": "6.0"
+ },
+ "no_good": {
+ "c": "people",
+ "e": "🙅",
+ "d": "face with no good gesture",
+ "u": "6.0"
+ },
+ "no_good_tone1": {
+ "c": "people",
+ "e": "🙅ðŸ»",
+ "d": "face with no good gesture tone 1",
+ "u": "8.0"
+ },
+ "no_good_tone2": {
+ "c": "people",
+ "e": "🙅ðŸ¼",
+ "d": "face with no good gesture tone 2",
+ "u": "8.0"
+ },
+ "no_good_tone3": {
+ "c": "people",
+ "e": "🙅ðŸ½",
+ "d": "face with no good gesture tone 3",
+ "u": "8.0"
+ },
+ "no_good_tone4": {
+ "c": "people",
+ "e": "🙅ðŸ¾",
+ "d": "face with no good gesture tone 4",
+ "u": "8.0"
+ },
+ "no_good_tone5": {
+ "c": "people",
+ "e": "🙅ðŸ¿",
+ "d": "face with no good gesture tone 5",
+ "u": "8.0"
+ },
+ "no_mobile_phones": {
+ "c": "symbols",
+ "e": "📵",
+ "d": "no mobile phones",
+ "u": "6.0"
+ },
+ "no_mouth": {
+ "c": "people",
+ "e": "😶",
+ "d": "face without mouth",
+ "u": "6.0"
+ },
+ "no_pedestrians": {
+ "c": "symbols",
+ "e": "🚷",
+ "d": "no pedestrians",
+ "u": "6.0"
+ },
+ "no_smoking": {
+ "c": "symbols",
+ "e": "🚭",
+ "d": "no smoking symbol",
+ "u": "6.0"
+ },
+ "non-potable_water": {
+ "c": "symbols",
+ "e": "🚱",
+ "d": "non-potable water symbol",
+ "u": "6.0"
+ },
+ "nose": {
+ "c": "people",
+ "e": "👃",
+ "d": "nose",
+ "u": "6.0"
+ },
+ "nose_tone1": {
+ "c": "people",
+ "e": "👃ðŸ»",
+ "d": "nose tone 1",
+ "u": "8.0"
+ },
+ "nose_tone2": {
+ "c": "people",
+ "e": "👃ðŸ¼",
+ "d": "nose tone 2",
+ "u": "8.0"
+ },
+ "nose_tone3": {
+ "c": "people",
+ "e": "👃ðŸ½",
+ "d": "nose tone 3",
+ "u": "8.0"
+ },
+ "nose_tone4": {
+ "c": "people",
+ "e": "👃ðŸ¾",
+ "d": "nose tone 4",
+ "u": "8.0"
+ },
+ "nose_tone5": {
+ "c": "people",
+ "e": "👃ðŸ¿",
+ "d": "nose tone 5",
+ "u": "8.0"
+ },
+ "notebook": {
+ "c": "objects",
+ "e": "📓",
+ "d": "notebook",
+ "u": "6.0"
+ },
+ "notebook_with_decorative_cover": {
+ "c": "objects",
+ "e": "📔",
+ "d": "notebook with decorative cover",
+ "u": "6.0"
+ },
+ "notepad_spiral": {
+ "c": "objects",
+ "e": "🗒",
+ "d": "spiral note pad",
+ "u": "7.0"
+ },
+ "notes": {
+ "c": "symbols",
+ "e": "🎶",
+ "d": "multiple musical notes",
+ "u": "6.0"
+ },
+ "nut_and_bolt": {
+ "c": "objects",
+ "e": "🔩",
+ "d": "nut and bolt",
+ "u": "6.0"
+ },
+ "o": {
+ "c": "symbols",
+ "e": "â­•",
+ "d": "heavy large circle",
+ "u": "5.2"
+ },
+ "o2": {
+ "c": "symbols",
+ "e": "🅾",
+ "d": "negative squared latin capital letter o",
+ "u": "6.0"
+ },
+ "ocean": {
+ "c": "nature",
+ "e": "🌊",
+ "d": "water wave",
+ "u": "6.0"
+ },
+ "octagonal_sign": {
+ "c": "symbols",
+ "e": "🛑",
+ "d": "octagonal sign",
+ "u": "9.0"
+ },
+ "octopus": {
+ "c": "nature",
+ "e": "ðŸ™",
+ "d": "octopus",
+ "u": "6.0"
+ },
+ "oden": {
+ "c": "food",
+ "e": "ðŸ¢",
+ "d": "oden",
+ "u": "6.0"
+ },
+ "office": {
+ "c": "travel",
+ "e": "ðŸ¢",
+ "d": "office building",
+ "u": "6.0"
+ },
+ "oil": {
+ "c": "objects",
+ "e": "🛢",
+ "d": "oil drum",
+ "u": "7.0"
+ },
+ "ok": {
+ "c": "symbols",
+ "e": "🆗",
+ "d": "squared ok",
+ "u": "6.0"
+ },
+ "ok_hand": {
+ "c": "people",
+ "e": "👌",
+ "d": "ok hand sign",
+ "u": "6.0"
+ },
+ "ok_hand_tone1": {
+ "c": "people",
+ "e": "👌ðŸ»",
+ "d": "ok hand sign tone 1",
+ "u": "8.0"
+ },
+ "ok_hand_tone2": {
+ "c": "people",
+ "e": "👌ðŸ¼",
+ "d": "ok hand sign tone 2",
+ "u": "8.0"
+ },
+ "ok_hand_tone3": {
+ "c": "people",
+ "e": "👌ðŸ½",
+ "d": "ok hand sign tone 3",
+ "u": "8.0"
+ },
+ "ok_hand_tone4": {
+ "c": "people",
+ "e": "👌ðŸ¾",
+ "d": "ok hand sign tone 4",
+ "u": "8.0"
+ },
+ "ok_hand_tone5": {
+ "c": "people",
+ "e": "👌ðŸ¿",
+ "d": "ok hand sign tone 5",
+ "u": "8.0"
+ },
+ "ok_woman": {
+ "c": "people",
+ "e": "🙆",
+ "d": "face with ok gesture",
+ "u": "6.0"
+ },
+ "ok_woman_tone1": {
+ "c": "people",
+ "e": "🙆ðŸ»",
+ "d": "face with ok gesture tone1",
+ "u": "8.0"
+ },
+ "ok_woman_tone2": {
+ "c": "people",
+ "e": "🙆ðŸ¼",
+ "d": "face with ok gesture tone2",
+ "u": "8.0"
+ },
+ "ok_woman_tone3": {
+ "c": "people",
+ "e": "🙆ðŸ½",
+ "d": "face with ok gesture tone3",
+ "u": "8.0"
+ },
+ "ok_woman_tone4": {
+ "c": "people",
+ "e": "🙆ðŸ¾",
+ "d": "face with ok gesture tone4",
+ "u": "8.0"
+ },
+ "ok_woman_tone5": {
+ "c": "people",
+ "e": "🙆ðŸ¿",
+ "d": "face with ok gesture tone5",
+ "u": "8.0"
+ },
+ "older_man": {
+ "c": "people",
+ "e": "👴",
+ "d": "older man",
+ "u": "6.0"
+ },
+ "older_man_tone1": {
+ "c": "people",
+ "e": "👴ðŸ»",
+ "d": "older man tone 1",
+ "u": "8.0"
+ },
+ "older_man_tone2": {
+ "c": "people",
+ "e": "👴ðŸ¼",
+ "d": "older man tone 2",
+ "u": "8.0"
+ },
+ "older_man_tone3": {
+ "c": "people",
+ "e": "👴ðŸ½",
+ "d": "older man tone 3",
+ "u": "8.0"
+ },
+ "older_man_tone4": {
+ "c": "people",
+ "e": "👴ðŸ¾",
+ "d": "older man tone 4",
+ "u": "8.0"
+ },
+ "older_man_tone5": {
+ "c": "people",
+ "e": "👴ðŸ¿",
+ "d": "older man tone 5",
+ "u": "8.0"
+ },
+ "older_woman": {
+ "c": "people",
+ "e": "👵",
+ "d": "older woman",
+ "u": "6.0"
+ },
+ "older_woman_tone1": {
+ "c": "people",
+ "e": "👵ðŸ»",
+ "d": "older woman tone 1",
+ "u": "8.0"
+ },
+ "older_woman_tone2": {
+ "c": "people",
+ "e": "👵ðŸ¼",
+ "d": "older woman tone 2",
+ "u": "8.0"
+ },
+ "older_woman_tone3": {
+ "c": "people",
+ "e": "👵ðŸ½",
+ "d": "older woman tone 3",
+ "u": "8.0"
+ },
+ "older_woman_tone4": {
+ "c": "people",
+ "e": "👵ðŸ¾",
+ "d": "older woman tone 4",
+ "u": "8.0"
+ },
+ "older_woman_tone5": {
+ "c": "people",
+ "e": "👵ðŸ¿",
+ "d": "older woman tone 5",
+ "u": "8.0"
+ },
+ "om_symbol": {
+ "c": "symbols",
+ "e": "🕉",
+ "d": "om symbol",
+ "u": "7.0"
+ },
+ "on": {
+ "c": "symbols",
+ "e": "🔛",
+ "d": "on with exclamation mark with left right arrow abo",
+ "u": "6.0"
+ },
+ "oncoming_automobile": {
+ "c": "travel",
+ "e": "🚘",
+ "d": "oncoming automobile",
+ "u": "6.0"
+ },
+ "oncoming_bus": {
+ "c": "travel",
+ "e": "ðŸš",
+ "d": "oncoming bus",
+ "u": "6.0"
+ },
+ "oncoming_police_car": {
+ "c": "travel",
+ "e": "🚔",
+ "d": "oncoming police car",
+ "u": "6.0"
+ },
+ "oncoming_taxi": {
+ "c": "travel",
+ "e": "🚖",
+ "d": "oncoming taxi",
+ "u": "6.0"
+ },
+ "one": {
+ "c": "symbols",
+ "e": "1ï¸âƒ£",
+ "d": "keycap digit one",
+ "u": "3.0"
+ },
+ "open_file_folder": {
+ "c": "objects",
+ "e": "📂",
+ "d": "open file folder",
+ "u": "6.0"
+ },
+ "open_hands": {
+ "c": "people",
+ "e": "ðŸ‘",
+ "d": "open hands sign",
+ "u": "6.0"
+ },
+ "open_hands_tone1": {
+ "c": "people",
+ "e": "ðŸ‘ðŸ»",
+ "d": "open hands sign tone 1",
+ "u": "8.0"
+ },
+ "open_hands_tone2": {
+ "c": "people",
+ "e": "ðŸ‘ðŸ¼",
+ "d": "open hands sign tone 2",
+ "u": "8.0"
+ },
+ "open_hands_tone3": {
+ "c": "people",
+ "e": "ðŸ‘ðŸ½",
+ "d": "open hands sign tone 3",
+ "u": "8.0"
+ },
+ "open_hands_tone4": {
+ "c": "people",
+ "e": "ðŸ‘ðŸ¾",
+ "d": "open hands sign tone 4",
+ "u": "8.0"
+ },
+ "open_hands_tone5": {
+ "c": "people",
+ "e": "ðŸ‘ðŸ¿",
+ "d": "open hands sign tone 5",
+ "u": "8.0"
+ },
+ "open_mouth": {
+ "c": "people",
+ "e": "😮",
+ "d": "face with open mouth",
+ "u": "6.1"
+ },
+ "ophiuchus": {
+ "c": "symbols",
+ "e": "⛎",
+ "d": "ophiuchus",
+ "u": "6.0"
+ },
+ "orange_book": {
+ "c": "objects",
+ "e": "📙",
+ "d": "orange book",
+ "u": "6.0"
+ },
+ "orthodox_cross": {
+ "c": "symbols",
+ "e": "☦",
+ "d": "orthodox cross",
+ "u": "1.1"
+ },
+ "outbox_tray": {
+ "c": "objects",
+ "e": "📤",
+ "d": "outbox tray",
+ "u": "6.0"
+ },
+ "owl": {
+ "c": "nature",
+ "e": "🦉",
+ "d": "owl",
+ "u": "9.0"
+ },
+ "ox": {
+ "c": "nature",
+ "e": "ðŸ‚",
+ "d": "ox",
+ "u": "6.0"
+ },
+ "package": {
+ "c": "objects",
+ "e": "📦",
+ "d": "package",
+ "u": "6.0"
+ },
+ "page_facing_up": {
+ "c": "objects",
+ "e": "📄",
+ "d": "page facing up",
+ "u": "6.0"
+ },
+ "page_with_curl": {
+ "c": "objects",
+ "e": "📃",
+ "d": "page with curl",
+ "u": "6.0"
+ },
+ "pager": {
+ "c": "objects",
+ "e": "📟",
+ "d": "pager",
+ "u": "6.0"
+ },
+ "paintbrush": {
+ "c": "objects",
+ "e": "🖌",
+ "d": "lower left paintbrush",
+ "u": "7.0"
+ },
+ "palm_tree": {
+ "c": "nature",
+ "e": "🌴",
+ "d": "palm tree",
+ "u": "6.0"
+ },
+ "pancakes": {
+ "c": "food",
+ "e": "🥞",
+ "d": "pancakes",
+ "u": "9.0"
+ },
+ "panda_face": {
+ "c": "nature",
+ "e": "ðŸ¼",
+ "d": "panda face",
+ "u": "6.0"
+ },
+ "paperclip": {
+ "c": "objects",
+ "e": "📎",
+ "d": "paperclip",
+ "u": "6.0"
+ },
+ "paperclips": {
+ "c": "objects",
+ "e": "🖇",
+ "d": "linked paperclips",
+ "u": "7.0"
+ },
+ "park": {
+ "c": "travel",
+ "e": "ðŸž",
+ "d": "national park",
+ "u": "7.0"
+ },
+ "parking": {
+ "c": "symbols",
+ "e": "🅿",
+ "d": "negative squared latin capital letter p",
+ "u": "5.2"
+ },
+ "part_alternation_mark": {
+ "c": "symbols",
+ "e": "〽",
+ "d": "part alternation mark",
+ "u": "3.2"
+ },
+ "partly_sunny": {
+ "c": "nature",
+ "e": "â›…",
+ "d": "sun behind cloud",
+ "u": "5.2"
+ },
+ "passport_control": {
+ "c": "symbols",
+ "e": "🛂",
+ "d": "passport control",
+ "u": "6.0"
+ },
+ "pause_button": {
+ "c": "symbols",
+ "e": "â¸",
+ "d": "double vertical bar",
+ "u": "7.0"
+ },
+ "peace": {
+ "c": "symbols",
+ "e": "☮",
+ "d": "peace symbol",
+ "u": "1.1"
+ },
+ "peach": {
+ "c": "food",
+ "e": "ðŸ‘",
+ "d": "peach",
+ "u": "6.0"
+ },
+ "peanuts": {
+ "c": "food",
+ "e": "🥜",
+ "d": "peanuts",
+ "u": "9.0"
+ },
+ "pear": {
+ "c": "food",
+ "e": "ðŸ",
+ "d": "pear",
+ "u": "6.0"
+ },
+ "pen_ballpoint": {
+ "c": "objects",
+ "e": "🖊",
+ "d": "lower left ballpoint pen",
+ "u": "7.0"
+ },
+ "pen_fountain": {
+ "c": "objects",
+ "e": "🖋",
+ "d": "lower left fountain pen",
+ "u": "7.0"
+ },
+ "pencil": {
+ "c": "objects",
+ "e": "ðŸ“",
+ "d": "memo",
+ "u": "6.0"
+ },
+ "pencil2": {
+ "c": "objects",
+ "e": "âœ",
+ "d": "pencil",
+ "u": "1.1"
+ },
+ "penguin": {
+ "c": "nature",
+ "e": "ðŸ§",
+ "d": "penguin",
+ "u": "6.0"
+ },
+ "pensive": {
+ "c": "people",
+ "e": "😔",
+ "d": "pensive face",
+ "u": "6.0"
+ },
+ "performing_arts": {
+ "c": "activity",
+ "e": "🎭",
+ "d": "performing arts",
+ "u": "6.0"
+ },
+ "persevere": {
+ "c": "people",
+ "e": "😣",
+ "d": "persevering face",
+ "u": "6.0"
+ },
+ "person_frowning": {
+ "c": "people",
+ "e": "ðŸ™",
+ "d": "person frowning",
+ "u": "6.0"
+ },
+ "person_frowning_tone1": {
+ "c": "people",
+ "e": "ðŸ™ðŸ»",
+ "d": "person frowning tone 1",
+ "u": "8.0"
+ },
+ "person_frowning_tone2": {
+ "c": "people",
+ "e": "ðŸ™ðŸ¼",
+ "d": "person frowning tone 2",
+ "u": "8.0"
+ },
+ "person_frowning_tone3": {
+ "c": "people",
+ "e": "ðŸ™ðŸ½",
+ "d": "person frowning tone 3",
+ "u": "8.0"
+ },
+ "person_frowning_tone4": {
+ "c": "people",
+ "e": "ðŸ™ðŸ¾",
+ "d": "person frowning tone 4",
+ "u": "8.0"
+ },
+ "person_frowning_tone5": {
+ "c": "people",
+ "e": "ðŸ™ðŸ¿",
+ "d": "person frowning tone 5",
+ "u": "8.0"
+ },
+ "person_with_blond_hair": {
+ "c": "people",
+ "e": "👱",
+ "d": "person with blond hair",
+ "u": "6.0"
+ },
+ "person_with_blond_hair_tone1": {
+ "c": "people",
+ "e": "👱ðŸ»",
+ "d": "person with blond hair tone 1",
+ "u": "8.0"
+ },
+ "person_with_blond_hair_tone2": {
+ "c": "people",
+ "e": "👱ðŸ¼",
+ "d": "person with blond hair tone 2",
+ "u": "8.0"
+ },
+ "person_with_blond_hair_tone3": {
+ "c": "people",
+ "e": "👱ðŸ½",
+ "d": "person with blond hair tone 3",
+ "u": "8.0"
+ },
+ "person_with_blond_hair_tone4": {
+ "c": "people",
+ "e": "👱ðŸ¾",
+ "d": "person with blond hair tone 4",
+ "u": "8.0"
+ },
+ "person_with_blond_hair_tone5": {
+ "c": "people",
+ "e": "👱ðŸ¿",
+ "d": "person with blond hair tone 5",
+ "u": "8.0"
+ },
+ "person_with_pouting_face": {
+ "c": "people",
+ "e": "🙎",
+ "d": "person with pouting face",
+ "u": "6.0"
+ },
+ "person_with_pouting_face_tone1": {
+ "c": "people",
+ "e": "🙎ðŸ»",
+ "d": "person with pouting face tone1",
+ "u": "8.0"
+ },
+ "person_with_pouting_face_tone2": {
+ "c": "people",
+ "e": "🙎ðŸ¼",
+ "d": "person with pouting face tone2",
+ "u": "8.0"
+ },
+ "person_with_pouting_face_tone3": {
+ "c": "people",
+ "e": "🙎ðŸ½",
+ "d": "person with pouting face tone3",
+ "u": "8.0"
+ },
+ "person_with_pouting_face_tone4": {
+ "c": "people",
+ "e": "🙎ðŸ¾",
+ "d": "person with pouting face tone4",
+ "u": "8.0"
+ },
+ "person_with_pouting_face_tone5": {
+ "c": "people",
+ "e": "🙎ðŸ¿",
+ "d": "person with pouting face tone5",
+ "u": "8.0"
+ },
+ "pick": {
+ "c": "objects",
+ "e": "â›",
+ "d": "pick",
+ "u": "5.2"
+ },
+ "pig": {
+ "c": "nature",
+ "e": "ðŸ·",
+ "d": "pig face",
+ "u": "6.0"
+ },
+ "pig2": {
+ "c": "nature",
+ "e": "ðŸ–",
+ "d": "pig",
+ "u": "6.0"
+ },
+ "pig_nose": {
+ "c": "nature",
+ "e": "ðŸ½",
+ "d": "pig nose",
+ "u": "6.0"
+ },
+ "pill": {
+ "c": "objects",
+ "e": "💊",
+ "d": "pill",
+ "u": "6.0"
+ },
+ "pineapple": {
+ "c": "food",
+ "e": "ðŸ",
+ "d": "pineapple",
+ "u": "6.0"
+ },
+ "ping_pong": {
+ "c": "activity",
+ "e": "ðŸ“",
+ "d": "table tennis paddle and ball",
+ "u": "8.0"
+ },
+ "pisces": {
+ "c": "symbols",
+ "e": "♓",
+ "d": "pisces",
+ "u": "1.1"
+ },
+ "pizza": {
+ "c": "food",
+ "e": "ðŸ•",
+ "d": "slice of pizza",
+ "u": "6.0"
+ },
+ "place_of_worship": {
+ "c": "symbols",
+ "e": "ðŸ›",
+ "d": "place of worship",
+ "u": "8.0"
+ },
+ "play_pause": {
+ "c": "symbols",
+ "e": "â¯",
+ "d": "black right-pointing double triangle with double vertical bar",
+ "u": "6.0"
+ },
+ "point_down": {
+ "c": "people",
+ "e": "👇",
+ "d": "white down pointing backhand index",
+ "u": "6.0"
+ },
+ "point_down_tone1": {
+ "c": "people",
+ "e": "👇ðŸ»",
+ "d": "white down pointing backhand index tone 1",
+ "u": "8.0"
+ },
+ "point_down_tone2": {
+ "c": "people",
+ "e": "👇ðŸ¼",
+ "d": "white down pointing backhand index tone 2",
+ "u": "8.0"
+ },
+ "point_down_tone3": {
+ "c": "people",
+ "e": "👇ðŸ½",
+ "d": "white down pointing backhand index tone 3",
+ "u": "8.0"
+ },
+ "point_down_tone4": {
+ "c": "people",
+ "e": "👇ðŸ¾",
+ "d": "white down pointing backhand index tone 4",
+ "u": "8.0"
+ },
+ "point_down_tone5": {
+ "c": "people",
+ "e": "👇ðŸ¿",
+ "d": "white down pointing backhand index tone 5",
+ "u": "8.0"
+ },
+ "point_left": {
+ "c": "people",
+ "e": "👈",
+ "d": "white left pointing backhand index",
+ "u": "6.0"
+ },
+ "point_left_tone1": {
+ "c": "people",
+ "e": "👈ðŸ»",
+ "d": "white left pointing backhand index tone 1",
+ "u": "8.0"
+ },
+ "point_left_tone2": {
+ "c": "people",
+ "e": "👈ðŸ¼",
+ "d": "white left pointing backhand index tone 2",
+ "u": "8.0"
+ },
+ "point_left_tone3": {
+ "c": "people",
+ "e": "👈ðŸ½",
+ "d": "white left pointing backhand index tone 3",
+ "u": "8.0"
+ },
+ "point_left_tone4": {
+ "c": "people",
+ "e": "👈ðŸ¾",
+ "d": "white left pointing backhand index tone 4",
+ "u": "8.0"
+ },
+ "point_left_tone5": {
+ "c": "people",
+ "e": "👈ðŸ¿",
+ "d": "white left pointing backhand index tone 5",
+ "u": "8.0"
+ },
+ "point_right": {
+ "c": "people",
+ "e": "👉",
+ "d": "white right pointing backhand index",
+ "u": "6.0"
+ },
+ "point_right_tone1": {
+ "c": "people",
+ "e": "👉ðŸ»",
+ "d": "white right pointing backhand index tone 1",
+ "u": "8.0"
+ },
+ "point_right_tone2": {
+ "c": "people",
+ "e": "👉ðŸ¼",
+ "d": "white right pointing backhand index tone 2",
+ "u": "8.0"
+ },
+ "point_right_tone3": {
+ "c": "people",
+ "e": "👉ðŸ½",
+ "d": "white right pointing backhand index tone 3",
+ "u": "8.0"
+ },
+ "point_right_tone4": {
+ "c": "people",
+ "e": "👉ðŸ¾",
+ "d": "white right pointing backhand index tone 4",
+ "u": "8.0"
+ },
+ "point_right_tone5": {
+ "c": "people",
+ "e": "👉ðŸ¿",
+ "d": "white right pointing backhand index tone 5",
+ "u": "8.0"
+ },
+ "point_up": {
+ "c": "people",
+ "e": "â˜",
+ "d": "white up pointing index",
+ "u": "1.1"
+ },
+ "point_up_2": {
+ "c": "people",
+ "e": "👆",
+ "d": "white up pointing backhand index",
+ "u": "6.0"
+ },
+ "point_up_2_tone1": {
+ "c": "people",
+ "e": "👆ðŸ»",
+ "d": "white up pointing backhand index tone 1",
+ "u": "8.0"
+ },
+ "point_up_2_tone2": {
+ "c": "people",
+ "e": "👆ðŸ¼",
+ "d": "white up pointing backhand index tone 2",
+ "u": "8.0"
+ },
+ "point_up_2_tone3": {
+ "c": "people",
+ "e": "👆ðŸ½",
+ "d": "white up pointing backhand index tone 3",
+ "u": "8.0"
+ },
+ "point_up_2_tone4": {
+ "c": "people",
+ "e": "👆ðŸ¾",
+ "d": "white up pointing backhand index tone 4",
+ "u": "8.0"
+ },
+ "point_up_2_tone5": {
+ "c": "people",
+ "e": "👆ðŸ¿",
+ "d": "white up pointing backhand index tone 5",
+ "u": "8.0"
+ },
+ "point_up_tone1": {
+ "c": "people",
+ "e": "â˜ðŸ»",
+ "d": "white up pointing index tone 1",
+ "u": "8.0"
+ },
+ "point_up_tone2": {
+ "c": "people",
+ "e": "â˜ðŸ¼",
+ "d": "white up pointing index tone 2",
+ "u": "8.0"
+ },
+ "point_up_tone3": {
+ "c": "people",
+ "e": "â˜ðŸ½",
+ "d": "white up pointing index tone 3",
+ "u": "8.0"
+ },
+ "point_up_tone4": {
+ "c": "people",
+ "e": "â˜ðŸ¾",
+ "d": "white up pointing index tone 4",
+ "u": "8.0"
+ },
+ "point_up_tone5": {
+ "c": "people",
+ "e": "â˜ðŸ¿",
+ "d": "white up pointing index tone 5",
+ "u": "8.0"
+ },
+ "police_car": {
+ "c": "travel",
+ "e": "🚓",
+ "d": "police car",
+ "u": "6.0"
+ },
+ "poodle": {
+ "c": "nature",
+ "e": "ðŸ©",
+ "d": "poodle",
+ "u": "6.0"
+ },
+ "poop": {
+ "c": "people",
+ "e": "💩",
+ "d": "pile of poo",
+ "u": "6.0"
+ },
+ "popcorn": {
+ "c": "food",
+ "e": "ðŸ¿",
+ "d": "popcorn",
+ "u": "8.0"
+ },
+ "post_office": {
+ "c": "travel",
+ "e": "ðŸ£",
+ "d": "japanese post office",
+ "u": "6.0"
+ },
+ "postal_horn": {
+ "c": "objects",
+ "e": "📯",
+ "d": "postal horn",
+ "u": "6.0"
+ },
+ "postbox": {
+ "c": "objects",
+ "e": "📮",
+ "d": "postbox",
+ "u": "6.0"
+ },
+ "potable_water": {
+ "c": "symbols",
+ "e": "🚰",
+ "d": "potable water symbol",
+ "u": "6.0"
+ },
+ "potato": {
+ "c": "food",
+ "e": "🥔",
+ "d": "potato",
+ "u": "9.0"
+ },
+ "pouch": {
+ "c": "people",
+ "e": "ðŸ‘",
+ "d": "pouch",
+ "u": "6.0"
+ },
+ "poultry_leg": {
+ "c": "food",
+ "e": "ðŸ—",
+ "d": "poultry leg",
+ "u": "6.0"
+ },
+ "pound": {
+ "c": "objects",
+ "e": "💷",
+ "d": "banknote with pound sign",
+ "u": "6.0"
+ },
+ "pouting_cat": {
+ "c": "people",
+ "e": "😾",
+ "d": "pouting cat face",
+ "u": "6.0"
+ },
+ "pray": {
+ "c": "people",
+ "e": "ðŸ™",
+ "d": "person with folded hands",
+ "u": "6.0"
+ },
+ "pray_tone1": {
+ "c": "people",
+ "e": "ðŸ™ðŸ»",
+ "d": "person with folded hands tone 1",
+ "u": "8.0"
+ },
+ "pray_tone2": {
+ "c": "people",
+ "e": "ðŸ™ðŸ¼",
+ "d": "person with folded hands tone 2",
+ "u": "8.0"
+ },
+ "pray_tone3": {
+ "c": "people",
+ "e": "ðŸ™ðŸ½",
+ "d": "person with folded hands tone 3",
+ "u": "8.0"
+ },
+ "pray_tone4": {
+ "c": "people",
+ "e": "ðŸ™ðŸ¾",
+ "d": "person with folded hands tone 4",
+ "u": "8.0"
+ },
+ "pray_tone5": {
+ "c": "people",
+ "e": "ðŸ™ðŸ¿",
+ "d": "person with folded hands tone 5",
+ "u": "8.0"
+ },
+ "prayer_beads": {
+ "c": "objects",
+ "e": "📿",
+ "d": "prayer beads",
+ "u": "8.0"
+ },
+ "pregnant_woman": {
+ "c": "people",
+ "e": "🤰",
+ "d": "pregnant woman",
+ "u": "9.0"
+ },
+ "pregnant_woman_tone1": {
+ "c": "people",
+ "e": "🤰ðŸ»",
+ "d": "pregnant woman tone 1",
+ "u": "9.0"
+ },
+ "pregnant_woman_tone2": {
+ "c": "people",
+ "e": "🤰ðŸ¼",
+ "d": "pregnant woman tone 2",
+ "u": "9.0"
+ },
+ "pregnant_woman_tone3": {
+ "c": "people",
+ "e": "🤰ðŸ½",
+ "d": "pregnant woman tone 3",
+ "u": "9.0"
+ },
+ "pregnant_woman_tone4": {
+ "c": "people",
+ "e": "🤰ðŸ¾",
+ "d": "pregnant woman tone 4",
+ "u": "9.0"
+ },
+ "pregnant_woman_tone5": {
+ "c": "people",
+ "e": "🤰ðŸ¿",
+ "d": "pregnant woman tone 5",
+ "u": "9.0"
+ },
+ "prince": {
+ "c": "people",
+ "e": "🤴",
+ "d": "prince",
+ "u": "9.0"
+ },
+ "prince_tone1": {
+ "c": "people",
+ "e": "🤴ðŸ»",
+ "d": "prince tone 1",
+ "u": "9.0"
+ },
+ "prince_tone2": {
+ "c": "people",
+ "e": "🤴ðŸ¼",
+ "d": "prince tone 2",
+ "u": "9.0"
+ },
+ "prince_tone3": {
+ "c": "people",
+ "e": "🤴ðŸ½",
+ "d": "prince tone 3",
+ "u": "9.0"
+ },
+ "prince_tone4": {
+ "c": "people",
+ "e": "🤴ðŸ¾",
+ "d": "prince tone 4",
+ "u": "9.0"
+ },
+ "prince_tone5": {
+ "c": "people",
+ "e": "🤴ðŸ¿",
+ "d": "prince tone 5",
+ "u": "9.0"
+ },
+ "princess": {
+ "c": "people",
+ "e": "👸",
+ "d": "princess",
+ "u": "6.0"
+ },
+ "princess_tone1": {
+ "c": "people",
+ "e": "👸ðŸ»",
+ "d": "princess tone 1",
+ "u": "8.0"
+ },
+ "princess_tone2": {
+ "c": "people",
+ "e": "👸ðŸ¼",
+ "d": "princess tone 2",
+ "u": "8.0"
+ },
+ "princess_tone3": {
+ "c": "people",
+ "e": "👸ðŸ½",
+ "d": "princess tone 3",
+ "u": "8.0"
+ },
+ "princess_tone4": {
+ "c": "people",
+ "e": "👸ðŸ¾",
+ "d": "princess tone 4",
+ "u": "8.0"
+ },
+ "princess_tone5": {
+ "c": "people",
+ "e": "👸ðŸ¿",
+ "d": "princess tone 5",
+ "u": "8.0"
+ },
+ "printer": {
+ "c": "objects",
+ "e": "🖨",
+ "d": "printer",
+ "u": "7.0"
+ },
+ "projector": {
+ "c": "objects",
+ "e": "📽",
+ "d": "film projector",
+ "u": "7.0"
+ },
+ "punch": {
+ "c": "people",
+ "e": "👊",
+ "d": "fisted hand sign",
+ "u": "6.0"
+ },
+ "punch_tone1": {
+ "c": "people",
+ "e": "👊ðŸ»",
+ "d": "fisted hand sign tone 1",
+ "u": "8.0"
+ },
+ "punch_tone2": {
+ "c": "people",
+ "e": "👊ðŸ¼",
+ "d": "fisted hand sign tone 2",
+ "u": "8.0"
+ },
+ "punch_tone3": {
+ "c": "people",
+ "e": "👊ðŸ½",
+ "d": "fisted hand sign tone 3",
+ "u": "8.0"
+ },
+ "punch_tone4": {
+ "c": "people",
+ "e": "👊ðŸ¾",
+ "d": "fisted hand sign tone 4",
+ "u": "8.0"
+ },
+ "punch_tone5": {
+ "c": "people",
+ "e": "👊ðŸ¿",
+ "d": "fisted hand sign tone 5",
+ "u": "8.0"
+ },
+ "purple_heart": {
+ "c": "symbols",
+ "e": "💜",
+ "d": "purple heart",
+ "u": "6.0"
+ },
+ "purse": {
+ "c": "people",
+ "e": "👛",
+ "d": "purse",
+ "u": "6.0"
+ },
+ "pushpin": {
+ "c": "objects",
+ "e": "📌",
+ "d": "pushpin",
+ "u": "6.0"
+ },
+ "put_litter_in_its_place": {
+ "c": "symbols",
+ "e": "🚮",
+ "d": "put litter in its place symbol",
+ "u": "6.0"
+ },
+ "question": {
+ "c": "symbols",
+ "e": "â“",
+ "d": "black question mark ornament",
+ "u": "6.0"
+ },
+ "rabbit": {
+ "c": "nature",
+ "e": "ðŸ°",
+ "d": "rabbit face",
+ "u": "6.0"
+ },
+ "rabbit2": {
+ "c": "nature",
+ "e": "ðŸ‡",
+ "d": "rabbit",
+ "u": "6.0"
+ },
+ "race_car": {
+ "c": "travel",
+ "e": "ðŸŽ",
+ "d": "racing car",
+ "u": "7.0"
+ },
+ "racehorse": {
+ "c": "nature",
+ "e": "ðŸŽ",
+ "d": "horse",
+ "u": "6.0"
+ },
+ "radio": {
+ "c": "objects",
+ "e": "📻",
+ "d": "radio",
+ "u": "6.0"
+ },
+ "radio_button": {
+ "c": "symbols",
+ "e": "🔘",
+ "d": "radio button",
+ "u": "6.0"
+ },
+ "radioactive": {
+ "c": "symbols",
+ "e": "☢",
+ "d": "radioactive sign",
+ "u": "1.1"
+ },
+ "rage": {
+ "c": "people",
+ "e": "😡",
+ "d": "pouting face",
+ "u": "6.0"
+ },
+ "railway_car": {
+ "c": "travel",
+ "e": "🚃",
+ "d": "railway car",
+ "u": "6.0"
+ },
+ "railway_track": {
+ "c": "travel",
+ "e": "🛤",
+ "d": "railway track",
+ "u": "7.0"
+ },
+ "rainbow": {
+ "c": "travel",
+ "e": "🌈",
+ "d": "rainbow",
+ "u": "6.0"
+ },
+ "raised_back_of_hand": {
+ "c": "people",
+ "e": "🤚",
+ "d": "raised back of hand",
+ "u": "9.0"
+ },
+ "raised_back_of_hand_tone1": {
+ "c": "people",
+ "e": "🤚ðŸ»",
+ "d": "raised back of hand tone 1",
+ "u": "9.0"
+ },
+ "raised_back_of_hand_tone2": {
+ "c": "people",
+ "e": "🤚ðŸ¼",
+ "d": "raised back of hand tone 2",
+ "u": "9.0"
+ },
+ "raised_back_of_hand_tone3": {
+ "c": "people",
+ "e": "🤚ðŸ½",
+ "d": "raised back of hand tone 3",
+ "u": "9.0"
+ },
+ "raised_back_of_hand_tone4": {
+ "c": "people",
+ "e": "🤚ðŸ¾",
+ "d": "raised back of hand tone 4",
+ "u": "9.0"
+ },
+ "raised_back_of_hand_tone5": {
+ "c": "people",
+ "e": "🤚ðŸ¿",
+ "d": "raised back of hand tone 5",
+ "u": "9.0"
+ },
+ "raised_hand": {
+ "c": "people",
+ "e": "✋",
+ "d": "raised hand",
+ "u": "6.0"
+ },
+ "raised_hand_tone1": {
+ "c": "people",
+ "e": "✋ðŸ»",
+ "d": "raised hand tone 1",
+ "u": "8.0"
+ },
+ "raised_hand_tone2": {
+ "c": "people",
+ "e": "✋ðŸ¼",
+ "d": "raised hand tone 2",
+ "u": "8.0"
+ },
+ "raised_hand_tone3": {
+ "c": "people",
+ "e": "✋ðŸ½",
+ "d": "raised hand tone 3",
+ "u": "8.0"
+ },
+ "raised_hand_tone4": {
+ "c": "people",
+ "e": "✋ðŸ¾",
+ "d": "raised hand tone 4",
+ "u": "8.0"
+ },
+ "raised_hand_tone5": {
+ "c": "people",
+ "e": "✋ðŸ¿",
+ "d": "raised hand tone 5",
+ "u": "8.0"
+ },
+ "raised_hands": {
+ "c": "people",
+ "e": "🙌",
+ "d": "person raising both hands in celebration",
+ "u": "6.0"
+ },
+ "raised_hands_tone1": {
+ "c": "people",
+ "e": "🙌ðŸ»",
+ "d": "person raising both hands in celebration tone 1",
+ "u": "8.0"
+ },
+ "raised_hands_tone2": {
+ "c": "people",
+ "e": "🙌ðŸ¼",
+ "d": "person raising both hands in celebration tone 2",
+ "u": "8.0"
+ },
+ "raised_hands_tone3": {
+ "c": "people",
+ "e": "🙌ðŸ½",
+ "d": "person raising both hands in celebration tone 3",
+ "u": "8.0"
+ },
+ "raised_hands_tone4": {
+ "c": "people",
+ "e": "🙌ðŸ¾",
+ "d": "person raising both hands in celebration tone 4",
+ "u": "8.0"
+ },
+ "raised_hands_tone5": {
+ "c": "people",
+ "e": "🙌ðŸ¿",
+ "d": "person raising both hands in celebration tone 5",
+ "u": "8.0"
+ },
+ "raising_hand": {
+ "c": "people",
+ "e": "🙋",
+ "d": "happy person raising one hand",
+ "u": "6.0"
+ },
+ "raising_hand_tone1": {
+ "c": "people",
+ "e": "🙋ðŸ»",
+ "d": "happy person raising one hand tone1",
+ "u": "8.0"
+ },
+ "raising_hand_tone2": {
+ "c": "people",
+ "e": "🙋ðŸ¼",
+ "d": "happy person raising one hand tone2",
+ "u": "8.0"
+ },
+ "raising_hand_tone3": {
+ "c": "people",
+ "e": "🙋ðŸ½",
+ "d": "happy person raising one hand tone3",
+ "u": "8.0"
+ },
+ "raising_hand_tone4": {
+ "c": "people",
+ "e": "🙋ðŸ¾",
+ "d": "happy person raising one hand tone4",
+ "u": "8.0"
+ },
+ "raising_hand_tone5": {
+ "c": "people",
+ "e": "🙋ðŸ¿",
+ "d": "happy person raising one hand tone5",
+ "u": "8.0"
+ },
+ "ram": {
+ "c": "nature",
+ "e": "ðŸ",
+ "d": "ram",
+ "u": "6.0"
+ },
+ "ramen": {
+ "c": "food",
+ "e": "ðŸœ",
+ "d": "steaming bowl",
+ "u": "6.0"
+ },
+ "rat": {
+ "c": "nature",
+ "e": "ðŸ€",
+ "d": "rat",
+ "u": "6.0"
+ },
+ "record_button": {
+ "c": "symbols",
+ "e": "âº",
+ "d": "black circle for record",
+ "u": "7.0"
+ },
+ "recycle": {
+ "c": "symbols",
+ "e": "â™»",
+ "d": "black universal recycling symbol",
+ "u": "3.2"
+ },
+ "red_car": {
+ "c": "travel",
+ "e": "🚗",
+ "d": "automobile",
+ "u": "6.0"
+ },
+ "red_circle": {
+ "c": "symbols",
+ "e": "🔴",
+ "d": "large red circle",
+ "u": "6.0"
+ },
+ "registered": {
+ "c": "symbols",
+ "e": "®",
+ "d": "registered sign",
+ "u": "1.1"
+ },
+ "relaxed": {
+ "c": "people",
+ "e": "☺",
+ "d": "white smiling face",
+ "u": "1.1"
+ },
+ "relieved": {
+ "c": "people",
+ "e": "😌",
+ "d": "relieved face",
+ "u": "6.0"
+ },
+ "reminder_ribbon": {
+ "c": "activity",
+ "e": "🎗",
+ "d": "reminder ribbon",
+ "u": "7.0"
+ },
+ "repeat": {
+ "c": "symbols",
+ "e": "ðŸ”",
+ "d": "clockwise rightwards and leftwards open circle arr",
+ "u": "6.0"
+ },
+ "repeat_one": {
+ "c": "symbols",
+ "e": "🔂",
+ "d": "clockwise rightwards and leftwards open circle arr",
+ "u": "6.0"
+ },
+ "restroom": {
+ "c": "symbols",
+ "e": "🚻",
+ "d": "restroom",
+ "u": "6.0"
+ },
+ "revolving_hearts": {
+ "c": "symbols",
+ "e": "💞",
+ "d": "revolving hearts",
+ "u": "6.0"
+ },
+ "rewind": {
+ "c": "symbols",
+ "e": "âª",
+ "d": "black left-pointing double triangle",
+ "u": "6.0"
+ },
+ "rhino": {
+ "c": "nature",
+ "e": "ðŸ¦",
+ "d": "rhinoceros",
+ "u": "9.0"
+ },
+ "ribbon": {
+ "c": "objects",
+ "e": "🎀",
+ "d": "ribbon",
+ "u": "6.0"
+ },
+ "rice": {
+ "c": "food",
+ "e": "ðŸš",
+ "d": "cooked rice",
+ "u": "6.0"
+ },
+ "rice_ball": {
+ "c": "food",
+ "e": "ðŸ™",
+ "d": "rice ball",
+ "u": "6.0"
+ },
+ "rice_cracker": {
+ "c": "food",
+ "e": "ðŸ˜",
+ "d": "rice cracker",
+ "u": "6.0"
+ },
+ "rice_scene": {
+ "c": "travel",
+ "e": "🎑",
+ "d": "moon viewing ceremony",
+ "u": "6.0"
+ },
+ "right_facing_fist": {
+ "c": "people",
+ "e": "🤜",
+ "d": "right-facing fist",
+ "u": "9.0"
+ },
+ "right_facing_fist_tone1": {
+ "c": "people",
+ "e": "🤜ðŸ»",
+ "d": "right facing fist tone 1",
+ "u": "9.0"
+ },
+ "right_facing_fist_tone2": {
+ "c": "people",
+ "e": "🤜ðŸ¼",
+ "d": "right facing fist tone 2",
+ "u": "9.0"
+ },
+ "right_facing_fist_tone3": {
+ "c": "people",
+ "e": "🤜ðŸ½",
+ "d": "right facing fist tone 3",
+ "u": "9.0"
+ },
+ "right_facing_fist_tone4": {
+ "c": "people",
+ "e": "🤜ðŸ¾",
+ "d": "right facing fist tone 4",
+ "u": "9.0"
+ },
+ "right_facing_fist_tone5": {
+ "c": "people",
+ "e": "🤜ðŸ¿",
+ "d": "right facing fist tone 5",
+ "u": "9.0"
+ },
+ "ring": {
+ "c": "people",
+ "e": "ðŸ’",
+ "d": "ring",
+ "u": "6.0"
+ },
+ "robot": {
+ "c": "people",
+ "e": "🤖",
+ "d": "robot face",
+ "u": "8.0"
+ },
+ "rocket": {
+ "c": "travel",
+ "e": "🚀",
+ "d": "rocket",
+ "u": "6.0"
+ },
+ "rofl": {
+ "c": "people",
+ "e": "🤣",
+ "d": "rolling on the floor laughing",
+ "u": "9.0"
+ },
+ "roller_coaster": {
+ "c": "travel",
+ "e": "🎢",
+ "d": "roller coaster",
+ "u": "6.0"
+ },
+ "rolling_eyes": {
+ "c": "people",
+ "e": "🙄",
+ "d": "face with rolling eyes",
+ "u": "8.0"
+ },
+ "rooster": {
+ "c": "nature",
+ "e": "ðŸ“",
+ "d": "rooster",
+ "u": "6.0"
+ },
+ "rose": {
+ "c": "nature",
+ "e": "🌹",
+ "d": "rose",
+ "u": "6.0"
+ },
+ "rosette": {
+ "c": "activity",
+ "e": "ðŸµ",
+ "d": "rosette",
+ "u": "7.0"
+ },
+ "rotating_light": {
+ "c": "travel",
+ "e": "🚨",
+ "d": "police cars revolving light",
+ "u": "6.0"
+ },
+ "round_pushpin": {
+ "c": "objects",
+ "e": "ðŸ“",
+ "d": "round pushpin",
+ "u": "6.0"
+ },
+ "rowboat": {
+ "c": "activity",
+ "e": "🚣",
+ "d": "rowboat",
+ "u": "6.0"
+ },
+ "rowboat_tone1": {
+ "c": "activity",
+ "e": "🚣ðŸ»",
+ "d": "rowboat tone 1",
+ "u": "8.0"
+ },
+ "rowboat_tone2": {
+ "c": "activity",
+ "e": "🚣ðŸ¼",
+ "d": "rowboat tone 2",
+ "u": "8.0"
+ },
+ "rowboat_tone3": {
+ "c": "activity",
+ "e": "🚣ðŸ½",
+ "d": "rowboat tone 3",
+ "u": "8.0"
+ },
+ "rowboat_tone4": {
+ "c": "activity",
+ "e": "🚣ðŸ¾",
+ "d": "rowboat tone 4",
+ "u": "8.0"
+ },
+ "rowboat_tone5": {
+ "c": "activity",
+ "e": "🚣ðŸ¿",
+ "d": "rowboat tone 5",
+ "u": "8.0"
+ },
+ "rugby_football": {
+ "c": "activity",
+ "e": "ðŸ‰",
+ "d": "rugby football",
+ "u": "6.0"
+ },
+ "runner": {
+ "c": "people",
+ "e": "ðŸƒ",
+ "d": "runner",
+ "u": "6.0"
+ },
+ "runner_tone1": {
+ "c": "people",
+ "e": "ðŸƒðŸ»",
+ "d": "runner tone 1",
+ "u": "8.0"
+ },
+ "runner_tone2": {
+ "c": "people",
+ "e": "ðŸƒðŸ¼",
+ "d": "runner tone 2",
+ "u": "8.0"
+ },
+ "runner_tone3": {
+ "c": "people",
+ "e": "ðŸƒðŸ½",
+ "d": "runner tone 3",
+ "u": "8.0"
+ },
+ "runner_tone4": {
+ "c": "people",
+ "e": "ðŸƒðŸ¾",
+ "d": "runner tone 4",
+ "u": "8.0"
+ },
+ "runner_tone5": {
+ "c": "people",
+ "e": "ðŸƒðŸ¿",
+ "d": "runner tone 5",
+ "u": "8.0"
+ },
+ "running_shirt_with_sash": {
+ "c": "activity",
+ "e": "🎽",
+ "d": "running shirt with sash",
+ "u": "6.0"
+ },
+ "sa": {
+ "c": "symbols",
+ "e": "🈂",
+ "d": "squared katakana sa",
+ "u": "6.0"
+ },
+ "sagittarius": {
+ "c": "symbols",
+ "e": "â™",
+ "d": "sagittarius",
+ "u": "1.1"
+ },
+ "sailboat": {
+ "c": "travel",
+ "e": "⛵",
+ "d": "sailboat",
+ "u": "5.2"
+ },
+ "sake": {
+ "c": "food",
+ "e": "ðŸ¶",
+ "d": "sake bottle and cup",
+ "u": "6.0"
+ },
+ "salad": {
+ "c": "food",
+ "e": "🥗",
+ "d": "green salad",
+ "u": "9.0"
+ },
+ "sandal": {
+ "c": "people",
+ "e": "👡",
+ "d": "womans sandal",
+ "u": "6.0"
+ },
+ "santa": {
+ "c": "people",
+ "e": "🎅",
+ "d": "father christmas",
+ "u": "6.0"
+ },
+ "santa_tone1": {
+ "c": "people",
+ "e": "🎅ðŸ»",
+ "d": "father christmas tone 1",
+ "u": "8.0"
+ },
+ "santa_tone2": {
+ "c": "people",
+ "e": "🎅ðŸ¼",
+ "d": "father christmas tone 2",
+ "u": "8.0"
+ },
+ "santa_tone3": {
+ "c": "people",
+ "e": "🎅ðŸ½",
+ "d": "father christmas tone 3",
+ "u": "8.0"
+ },
+ "santa_tone4": {
+ "c": "people",
+ "e": "🎅ðŸ¾",
+ "d": "father christmas tone 4",
+ "u": "8.0"
+ },
+ "santa_tone5": {
+ "c": "people",
+ "e": "🎅ðŸ¿",
+ "d": "father christmas tone 5",
+ "u": "8.0"
+ },
+ "satellite": {
+ "c": "objects",
+ "e": "📡",
+ "d": "satellite antenna",
+ "u": "6.0"
+ },
+ "satellite_orbital": {
+ "c": "travel",
+ "e": "🛰",
+ "d": "satellite",
+ "u": "7.0"
+ },
+ "saxophone": {
+ "c": "activity",
+ "e": "🎷",
+ "d": "saxophone",
+ "u": "6.0"
+ },
+ "scales": {
+ "c": "objects",
+ "e": "âš–",
+ "d": "scales",
+ "u": "4.1"
+ },
+ "school": {
+ "c": "travel",
+ "e": "ðŸ«",
+ "d": "school",
+ "u": "6.0"
+ },
+ "school_satchel": {
+ "c": "people",
+ "e": "🎒",
+ "d": "school satchel",
+ "u": "6.0"
+ },
+ "scissors": {
+ "c": "objects",
+ "e": "✂",
+ "d": "black scissors",
+ "u": "1.1"
+ },
+ "scooter": {
+ "c": "travel",
+ "e": "🛴",
+ "d": "scooter",
+ "u": "9.0"
+ },
+ "scorpion": {
+ "c": "nature",
+ "e": "🦂",
+ "d": "scorpion",
+ "u": "8.0"
+ },
+ "scorpius": {
+ "c": "symbols",
+ "e": "â™",
+ "d": "scorpius",
+ "u": "1.1"
+ },
+ "scream": {
+ "c": "people",
+ "e": "😱",
+ "d": "face screaming in fear",
+ "u": "6.0"
+ },
+ "scream_cat": {
+ "c": "people",
+ "e": "🙀",
+ "d": "weary cat face",
+ "u": "6.0"
+ },
+ "scroll": {
+ "c": "objects",
+ "e": "📜",
+ "d": "scroll",
+ "u": "6.0"
+ },
+ "seat": {
+ "c": "travel",
+ "e": "💺",
+ "d": "seat",
+ "u": "6.0"
+ },
+ "second_place": {
+ "c": "activity",
+ "e": "🥈",
+ "d": "second place medal",
+ "u": "9.0"
+ },
+ "secret": {
+ "c": "symbols",
+ "e": "㊙",
+ "d": "circled ideograph secret",
+ "u": "1.1"
+ },
+ "see_no_evil": {
+ "c": "nature",
+ "e": "🙈",
+ "d": "see-no-evil monkey",
+ "u": "6.0"
+ },
+ "seedling": {
+ "c": "nature",
+ "e": "🌱",
+ "d": "seedling",
+ "u": "6.0"
+ },
+ "selfie": {
+ "c": "people",
+ "e": "🤳",
+ "d": "selfie",
+ "u": "9.0"
+ },
+ "selfie_tone1": {
+ "c": "people",
+ "e": "🤳ðŸ»",
+ "d": "selfie tone 1",
+ "u": "9.0"
+ },
+ "selfie_tone2": {
+ "c": "people",
+ "e": "🤳ðŸ¼",
+ "d": "selfie tone 2",
+ "u": "9.0"
+ },
+ "selfie_tone3": {
+ "c": "people",
+ "e": "🤳ðŸ½",
+ "d": "selfie tone 3",
+ "u": "9.0"
+ },
+ "selfie_tone4": {
+ "c": "people",
+ "e": "🤳ðŸ¾",
+ "d": "selfie tone 4",
+ "u": "9.0"
+ },
+ "selfie_tone5": {
+ "c": "people",
+ "e": "🤳ðŸ¿",
+ "d": "selfie tone 5",
+ "u": "9.0"
+ },
+ "seven": {
+ "c": "symbols",
+ "e": "7ï¸âƒ£",
+ "d": "keycap digit seven",
+ "u": "3.0"
+ },
+ "shallow_pan_of_food": {
+ "c": "food",
+ "e": "🥘",
+ "d": "shallow pan of food",
+ "u": "9.0"
+ },
+ "shamrock": {
+ "c": "nature",
+ "e": "☘",
+ "d": "shamrock",
+ "u": "4.1"
+ },
+ "shark": {
+ "c": "nature",
+ "e": "🦈",
+ "d": "shark",
+ "u": "9.0"
+ },
+ "shaved_ice": {
+ "c": "food",
+ "e": "ðŸ§",
+ "d": "shaved ice",
+ "u": "6.0"
+ },
+ "sheep": {
+ "c": "nature",
+ "e": "ðŸ‘",
+ "d": "sheep",
+ "u": "6.0"
+ },
+ "shell": {
+ "c": "nature",
+ "e": "ðŸš",
+ "d": "spiral shell",
+ "u": "6.0"
+ },
+ "shield": {
+ "c": "objects",
+ "e": "🛡",
+ "d": "shield",
+ "u": "7.0"
+ },
+ "shinto_shrine": {
+ "c": "travel",
+ "e": "⛩",
+ "d": "shinto shrine",
+ "u": "5.2"
+ },
+ "ship": {
+ "c": "travel",
+ "e": "🚢",
+ "d": "ship",
+ "u": "6.0"
+ },
+ "shirt": {
+ "c": "people",
+ "e": "👕",
+ "d": "t-shirt",
+ "u": "6.0"
+ },
+ "shopping_bags": {
+ "c": "objects",
+ "e": "ðŸ›",
+ "d": "shopping bags",
+ "u": "7.0"
+ },
+ "shopping_cart": {
+ "c": "objects",
+ "e": "🛒",
+ "d": "shopping trolley",
+ "u": "9.0"
+ },
+ "shower": {
+ "c": "objects",
+ "e": "🚿",
+ "d": "shower",
+ "u": "6.0"
+ },
+ "shrimp": {
+ "c": "nature",
+ "e": "ðŸ¦",
+ "d": "shrimp",
+ "u": "9.0"
+ },
+ "shrug": {
+ "c": "people",
+ "e": "🤷",
+ "d": "shrug",
+ "u": "9.0"
+ },
+ "shrug_tone1": {
+ "c": "people",
+ "e": "🤷ðŸ»",
+ "d": "shrug tone 1",
+ "u": "9.0"
+ },
+ "shrug_tone2": {
+ "c": "people",
+ "e": "🤷ðŸ¼",
+ "d": "shrug tone 2",
+ "u": "9.0"
+ },
+ "shrug_tone3": {
+ "c": "people",
+ "e": "🤷ðŸ½",
+ "d": "shrug tone 3",
+ "u": "9.0"
+ },
+ "shrug_tone4": {
+ "c": "people",
+ "e": "🤷ðŸ¾",
+ "d": "shrug tone 4",
+ "u": "9.0"
+ },
+ "shrug_tone5": {
+ "c": "people",
+ "e": "🤷ðŸ¿",
+ "d": "shrug tone 5",
+ "u": "9.0"
+ },
+ "signal_strength": {
+ "c": "symbols",
+ "e": "📶",
+ "d": "antenna with bars",
+ "u": "6.0"
+ },
+ "six": {
+ "c": "symbols",
+ "e": "6ï¸âƒ£",
+ "d": "keycap digit six",
+ "u": "3.0"
+ },
+ "six_pointed_star": {
+ "c": "symbols",
+ "e": "🔯",
+ "d": "six pointed star with middle dot",
+ "u": "6.0"
+ },
+ "ski": {
+ "c": "activity",
+ "e": "🎿",
+ "d": "ski and ski boot",
+ "u": "6.0"
+ },
+ "skier": {
+ "c": "activity",
+ "e": "â›·",
+ "d": "skier",
+ "u": "5.2"
+ },
+ "skull": {
+ "c": "people",
+ "e": "💀",
+ "d": "skull",
+ "u": "6.0"
+ },
+ "skull_crossbones": {
+ "c": "objects",
+ "e": "☠",
+ "d": "skull and crossbones",
+ "u": "1.1"
+ },
+ "sleeping": {
+ "c": "people",
+ "e": "😴",
+ "d": "sleeping face",
+ "u": "6.1"
+ },
+ "sleeping_accommodation": {
+ "c": "objects",
+ "e": "🛌",
+ "d": "sleeping accommodation",
+ "u": "7.0"
+ },
+ "sleepy": {
+ "c": "people",
+ "e": "😪",
+ "d": "sleepy face",
+ "u": "6.0"
+ },
+ "slight_frown": {
+ "c": "people",
+ "e": "ðŸ™",
+ "d": "slightly frowning face",
+ "u": "7.0"
+ },
+ "slight_smile": {
+ "c": "people",
+ "e": "🙂",
+ "d": "slightly smiling face",
+ "u": "7.0"
+ },
+ "slot_machine": {
+ "c": "activity",
+ "e": "🎰",
+ "d": "slot machine",
+ "u": "6.0"
+ },
+ "small_blue_diamond": {
+ "c": "symbols",
+ "e": "🔹",
+ "d": "small blue diamond",
+ "u": "6.0"
+ },
+ "small_orange_diamond": {
+ "c": "symbols",
+ "e": "🔸",
+ "d": "small orange diamond",
+ "u": "6.0"
+ },
+ "small_red_triangle": {
+ "c": "symbols",
+ "e": "🔺",
+ "d": "up-pointing red triangle",
+ "u": "6.0"
+ },
+ "small_red_triangle_down": {
+ "c": "symbols",
+ "e": "🔻",
+ "d": "down-pointing red triangle",
+ "u": "6.0"
+ },
+ "smile": {
+ "c": "people",
+ "e": "😄",
+ "d": "smiling face with open mouth and smiling eyes",
+ "u": "6.0"
+ },
+ "smile_cat": {
+ "c": "people",
+ "e": "😸",
+ "d": "grinning cat face with smiling eyes",
+ "u": "6.0"
+ },
+ "smiley": {
+ "c": "people",
+ "e": "😃",
+ "d": "smiling face with open mouth",
+ "u": "6.0"
+ },
+ "smiley_cat": {
+ "c": "people",
+ "e": "😺",
+ "d": "smiling cat face with open mouth",
+ "u": "6.0"
+ },
+ "smiling_imp": {
+ "c": "people",
+ "e": "😈",
+ "d": "smiling face with horns",
+ "u": "6.0"
+ },
+ "smirk": {
+ "c": "people",
+ "e": "ðŸ˜",
+ "d": "smirking face",
+ "u": "6.0"
+ },
+ "smirk_cat": {
+ "c": "people",
+ "e": "😼",
+ "d": "cat face with wry smile",
+ "u": "6.0"
+ },
+ "smoking": {
+ "c": "objects",
+ "e": "🚬",
+ "d": "smoking symbol",
+ "u": "6.0"
+ },
+ "snail": {
+ "c": "nature",
+ "e": "ðŸŒ",
+ "d": "snail",
+ "u": "6.0"
+ },
+ "snake": {
+ "c": "nature",
+ "e": "ðŸ",
+ "d": "snake",
+ "u": "6.0"
+ },
+ "sneezing_face": {
+ "c": "people",
+ "e": "🤧",
+ "d": "sneezing face",
+ "u": "9.0"
+ },
+ "snowboarder": {
+ "c": "activity",
+ "e": "ðŸ‚",
+ "d": "snowboarder",
+ "u": "6.0"
+ },
+ "snowflake": {
+ "c": "nature",
+ "e": "â„",
+ "d": "snowflake",
+ "u": "1.1"
+ },
+ "snowman": {
+ "c": "nature",
+ "e": "⛄",
+ "d": "snowman without snow",
+ "u": "5.2"
+ },
+ "snowman2": {
+ "c": "nature",
+ "e": "☃",
+ "d": "snowman",
+ "u": "1.1"
+ },
+ "sob": {
+ "c": "people",
+ "e": "😭",
+ "d": "loudly crying face",
+ "u": "6.0"
+ },
+ "soccer": {
+ "c": "activity",
+ "e": "âš½",
+ "d": "soccer ball",
+ "u": "5.2"
+ },
+ "soon": {
+ "c": "symbols",
+ "e": "🔜",
+ "d": "soon with rightwards arrow above",
+ "u": "6.0"
+ },
+ "sos": {
+ "c": "symbols",
+ "e": "🆘",
+ "d": "squared sos",
+ "u": "6.0"
+ },
+ "sound": {
+ "c": "symbols",
+ "e": "🔉",
+ "d": "speaker with one sound wave",
+ "u": "6.0"
+ },
+ "space_invader": {
+ "c": "activity",
+ "e": "👾",
+ "d": "alien monster",
+ "u": "6.0"
+ },
+ "spades": {
+ "c": "symbols",
+ "e": "â™ ",
+ "d": "black spade suit",
+ "u": "1.1"
+ },
+ "spaghetti": {
+ "c": "food",
+ "e": "ðŸ",
+ "d": "spaghetti",
+ "u": "6.0"
+ },
+ "sparkle": {
+ "c": "symbols",
+ "e": "â‡",
+ "d": "sparkle",
+ "u": "1.1"
+ },
+ "sparkler": {
+ "c": "travel",
+ "e": "🎇",
+ "d": "firework sparkler",
+ "u": "6.0"
+ },
+ "sparkles": {
+ "c": "nature",
+ "e": "✨",
+ "d": "sparkles",
+ "u": "6.0"
+ },
+ "sparkling_heart": {
+ "c": "symbols",
+ "e": "💖",
+ "d": "sparkling heart",
+ "u": "6.0"
+ },
+ "speak_no_evil": {
+ "c": "nature",
+ "e": "🙊",
+ "d": "speak-no-evil monkey",
+ "u": "6.0"
+ },
+ "speaker": {
+ "c": "symbols",
+ "e": "🔈",
+ "d": "speaker",
+ "u": "6.0"
+ },
+ "speaking_head": {
+ "c": "people",
+ "e": "🗣",
+ "d": "speaking head in silhouette",
+ "u": "7.0"
+ },
+ "speech_balloon": {
+ "c": "symbols",
+ "e": "💬",
+ "d": "speech balloon",
+ "u": "6.0"
+ },
+ "speech_left": {
+ "c": "symbols",
+ "e": "🗨",
+ "d": "left speech bubble",
+ "u": "7.0"
+ },
+ "speedboat": {
+ "c": "travel",
+ "e": "🚤",
+ "d": "speedboat",
+ "u": "6.0"
+ },
+ "spider": {
+ "c": "nature",
+ "e": "🕷",
+ "d": "spider",
+ "u": "7.0"
+ },
+ "spider_web": {
+ "c": "nature",
+ "e": "🕸",
+ "d": "spider web",
+ "u": "7.0"
+ },
+ "spoon": {
+ "c": "food",
+ "e": "🥄",
+ "d": "spoon",
+ "u": "9.0"
+ },
+ "spy": {
+ "c": "people",
+ "e": "🕵",
+ "d": "sleuth or spy",
+ "u": "7.0"
+ },
+ "spy_tone1": {
+ "c": "people",
+ "e": "🕵ðŸ»",
+ "d": "sleuth or spy tone 1",
+ "u": "8.0"
+ },
+ "spy_tone2": {
+ "c": "people",
+ "e": "🕵ðŸ¼",
+ "d": "sleuth or spy tone 2",
+ "u": "8.0"
+ },
+ "spy_tone3": {
+ "c": "people",
+ "e": "🕵ðŸ½",
+ "d": "sleuth or spy tone 3",
+ "u": "8.0"
+ },
+ "spy_tone4": {
+ "c": "people",
+ "e": "🕵ðŸ¾",
+ "d": "sleuth or spy tone 4",
+ "u": "8.0"
+ },
+ "spy_tone5": {
+ "c": "people",
+ "e": "🕵ðŸ¿",
+ "d": "sleuth or spy tone 5",
+ "u": "8.0"
+ },
+ "squid": {
+ "c": "nature",
+ "e": "🦑",
+ "d": "squid",
+ "u": "9.0"
+ },
+ "stadium": {
+ "c": "travel",
+ "e": "ðŸŸ",
+ "d": "stadium",
+ "u": "7.0"
+ },
+ "star": {
+ "c": "nature",
+ "e": "â­",
+ "d": "white medium star",
+ "u": "5.1"
+ },
+ "star2": {
+ "c": "nature",
+ "e": "🌟",
+ "d": "glowing star",
+ "u": "6.0"
+ },
+ "star_and_crescent": {
+ "c": "symbols",
+ "e": "☪",
+ "d": "star and crescent",
+ "u": "1.1"
+ },
+ "star_of_david": {
+ "c": "symbols",
+ "e": "✡",
+ "d": "star of david",
+ "u": "1.1"
+ },
+ "stars": {
+ "c": "travel",
+ "e": "🌠",
+ "d": "shooting star",
+ "u": "6.0"
+ },
+ "station": {
+ "c": "travel",
+ "e": "🚉",
+ "d": "station",
+ "u": "6.0"
+ },
+ "statue_of_liberty": {
+ "c": "travel",
+ "e": "🗽",
+ "d": "statue of liberty",
+ "u": "6.0"
+ },
+ "steam_locomotive": {
+ "c": "travel",
+ "e": "🚂",
+ "d": "steam locomotive",
+ "u": "6.0"
+ },
+ "stew": {
+ "c": "food",
+ "e": "ðŸ²",
+ "d": "pot of food",
+ "u": "6.0"
+ },
+ "stop_button": {
+ "c": "symbols",
+ "e": "â¹",
+ "d": "black square for stop",
+ "u": "7.0"
+ },
+ "stopwatch": {
+ "c": "objects",
+ "e": "â±",
+ "d": "stopwatch",
+ "u": "6.0"
+ },
+ "straight_ruler": {
+ "c": "objects",
+ "e": "ðŸ“",
+ "d": "straight ruler",
+ "u": "6.0"
+ },
+ "strawberry": {
+ "c": "food",
+ "e": "ðŸ“",
+ "d": "strawberry",
+ "u": "6.0"
+ },
+ "stuck_out_tongue": {
+ "c": "people",
+ "e": "😛",
+ "d": "face with stuck-out tongue",
+ "u": "6.1"
+ },
+ "stuck_out_tongue_closed_eyes": {
+ "c": "people",
+ "e": "ðŸ˜",
+ "d": "face with stuck-out tongue and tightly-closed eyes",
+ "u": "6.0"
+ },
+ "stuck_out_tongue_winking_eye": {
+ "c": "people",
+ "e": "😜",
+ "d": "face with stuck-out tongue and winking eye",
+ "u": "6.0"
+ },
+ "stuffed_flatbread": {
+ "c": "food",
+ "e": "🥙",
+ "d": "stuffed flatbread",
+ "u": "9.0"
+ },
+ "sun_with_face": {
+ "c": "nature",
+ "e": "🌞",
+ "d": "sun with face",
+ "u": "6.0"
+ },
+ "sunflower": {
+ "c": "nature",
+ "e": "🌻",
+ "d": "sunflower",
+ "u": "6.0"
+ },
+ "sunglasses": {
+ "c": "people",
+ "e": "😎",
+ "d": "smiling face with sunglasses",
+ "u": "6.0"
+ },
+ "sunny": {
+ "c": "nature",
+ "e": "☀",
+ "d": "black sun with rays",
+ "u": "1.1"
+ },
+ "sunrise": {
+ "c": "travel",
+ "e": "🌅",
+ "d": "sunrise",
+ "u": "6.0"
+ },
+ "sunrise_over_mountains": {
+ "c": "travel",
+ "e": "🌄",
+ "d": "sunrise over mountains",
+ "u": "6.0"
+ },
+ "surfer": {
+ "c": "activity",
+ "e": "ðŸ„",
+ "d": "surfer",
+ "u": "6.0"
+ },
+ "surfer_tone1": {
+ "c": "activity",
+ "e": "ðŸ„ðŸ»",
+ "d": "surfer tone 1",
+ "u": "8.0"
+ },
+ "surfer_tone2": {
+ "c": "activity",
+ "e": "ðŸ„ðŸ¼",
+ "d": "surfer tone 2",
+ "u": "8.0"
+ },
+ "surfer_tone3": {
+ "c": "activity",
+ "e": "ðŸ„ðŸ½",
+ "d": "surfer tone 3",
+ "u": "8.0"
+ },
+ "surfer_tone4": {
+ "c": "activity",
+ "e": "ðŸ„ðŸ¾",
+ "d": "surfer tone 4",
+ "u": "8.0"
+ },
+ "surfer_tone5": {
+ "c": "activity",
+ "e": "ðŸ„ðŸ¿",
+ "d": "surfer tone 5",
+ "u": "8.0"
+ },
+ "sushi": {
+ "c": "food",
+ "e": "ðŸ£",
+ "d": "sushi",
+ "u": "6.0"
+ },
+ "suspension_railway": {
+ "c": "travel",
+ "e": "🚟",
+ "d": "suspension railway",
+ "u": "6.0"
+ },
+ "sweat": {
+ "c": "people",
+ "e": "😓",
+ "d": "face with cold sweat",
+ "u": "6.0"
+ },
+ "sweat_drops": {
+ "c": "nature",
+ "e": "💦",
+ "d": "splashing sweat symbol",
+ "u": "6.0"
+ },
+ "sweat_smile": {
+ "c": "people",
+ "e": "😅",
+ "d": "smiling face with open mouth and cold sweat",
+ "u": "6.0"
+ },
+ "sweet_potato": {
+ "c": "food",
+ "e": "ðŸ ",
+ "d": "roasted sweet potato",
+ "u": "6.0"
+ },
+ "swimmer": {
+ "c": "activity",
+ "e": "ðŸŠ",
+ "d": "swimmer",
+ "u": "6.0"
+ },
+ "swimmer_tone1": {
+ "c": "activity",
+ "e": "ðŸŠðŸ»",
+ "d": "swimmer tone 1",
+ "u": "8.0"
+ },
+ "swimmer_tone2": {
+ "c": "activity",
+ "e": "ðŸŠðŸ¼",
+ "d": "swimmer tone 2",
+ "u": "8.0"
+ },
+ "swimmer_tone3": {
+ "c": "activity",
+ "e": "ðŸŠðŸ½",
+ "d": "swimmer tone 3",
+ "u": "8.0"
+ },
+ "swimmer_tone4": {
+ "c": "activity",
+ "e": "ðŸŠðŸ¾",
+ "d": "swimmer tone 4",
+ "u": "8.0"
+ },
+ "swimmer_tone5": {
+ "c": "activity",
+ "e": "ðŸŠðŸ¿",
+ "d": "swimmer tone 5",
+ "u": "8.0"
+ },
+ "symbols": {
+ "c": "symbols",
+ "e": "🔣",
+ "d": "input symbol for symbols",
+ "u": "6.0"
+ },
+ "synagogue": {
+ "c": "travel",
+ "e": "ðŸ•",
+ "d": "synagogue",
+ "u": "8.0"
+ },
+ "syringe": {
+ "c": "objects",
+ "e": "💉",
+ "d": "syringe",
+ "u": "6.0"
+ },
+ "taco": {
+ "c": "food",
+ "e": "🌮",
+ "d": "taco",
+ "u": "8.0"
+ },
+ "tada": {
+ "c": "objects",
+ "e": "🎉",
+ "d": "party popper",
+ "u": "6.0"
+ },
+ "tanabata_tree": {
+ "c": "nature",
+ "e": "🎋",
+ "d": "tanabata tree",
+ "u": "6.0"
+ },
+ "tangerine": {
+ "c": "food",
+ "e": "ðŸŠ",
+ "d": "tangerine",
+ "u": "6.0"
+ },
+ "taurus": {
+ "c": "symbols",
+ "e": "♉",
+ "d": "taurus",
+ "u": "1.1"
+ },
+ "taxi": {
+ "c": "travel",
+ "e": "🚕",
+ "d": "taxi",
+ "u": "6.0"
+ },
+ "tea": {
+ "c": "food",
+ "e": "ðŸµ",
+ "d": "teacup without handle",
+ "u": "6.0"
+ },
+ "telephone": {
+ "c": "objects",
+ "e": "☎",
+ "d": "black telephone",
+ "u": "1.1"
+ },
+ "telephone_receiver": {
+ "c": "objects",
+ "e": "📞",
+ "d": "telephone receiver",
+ "u": "6.0"
+ },
+ "telescope": {
+ "c": "objects",
+ "e": "🔭",
+ "d": "telescope",
+ "u": "6.0"
+ },
+ "ten": {
+ "c": "symbols",
+ "e": "🔟",
+ "d": "keycap ten",
+ "u": "6.0"
+ },
+ "tennis": {
+ "c": "activity",
+ "e": "🎾",
+ "d": "tennis racquet and ball",
+ "u": "6.0"
+ },
+ "tent": {
+ "c": "travel",
+ "e": "⛺",
+ "d": "tent",
+ "u": "5.2"
+ },
+ "thermometer": {
+ "c": "objects",
+ "e": "🌡",
+ "d": "thermometer",
+ "u": "7.0"
+ },
+ "thermometer_face": {
+ "c": "people",
+ "e": "🤒",
+ "d": "face with thermometer",
+ "u": "8.0"
+ },
+ "thinking": {
+ "c": "people",
+ "e": "🤔",
+ "d": "thinking face",
+ "u": "8.0"
+ },
+ "third_place": {
+ "c": "activity",
+ "e": "🥉",
+ "d": "third place medal",
+ "u": "9.0"
+ },
+ "thought_balloon": {
+ "c": "symbols",
+ "e": "💭",
+ "d": "thought balloon",
+ "u": "6.0"
+ },
+ "three": {
+ "c": "symbols",
+ "e": "3ï¸âƒ£",
+ "d": "keycap digit three",
+ "u": "3.0"
+ },
+ "thumbsdown": {
+ "c": "people",
+ "e": "👎",
+ "d": "thumbs down sign",
+ "u": "6.0"
+ },
+ "thumbsdown_tone1": {
+ "c": "people",
+ "e": "👎ðŸ»",
+ "d": "thumbs down sign tone 1",
+ "u": "8.0"
+ },
+ "thumbsdown_tone2": {
+ "c": "people",
+ "e": "👎ðŸ¼",
+ "d": "thumbs down sign tone 2",
+ "u": "8.0"
+ },
+ "thumbsdown_tone3": {
+ "c": "people",
+ "e": "👎ðŸ½",
+ "d": "thumbs down sign tone 3",
+ "u": "8.0"
+ },
+ "thumbsdown_tone4": {
+ "c": "people",
+ "e": "👎ðŸ¾",
+ "d": "thumbs down sign tone 4",
+ "u": "8.0"
+ },
+ "thumbsdown_tone5": {
+ "c": "people",
+ "e": "👎ðŸ¿",
+ "d": "thumbs down sign tone 5",
+ "u": "8.0"
+ },
+ "thumbsup": {
+ "c": "people",
+ "e": "ðŸ‘",
+ "d": "thumbs up sign",
+ "u": "6.0"
+ },
+ "thumbsup_tone1": {
+ "c": "people",
+ "e": "ðŸ‘ðŸ»",
+ "d": "thumbs up sign tone 1",
+ "u": "8.0"
+ },
+ "thumbsup_tone2": {
+ "c": "people",
+ "e": "ðŸ‘ðŸ¼",
+ "d": "thumbs up sign tone 2",
+ "u": "8.0"
+ },
+ "thumbsup_tone3": {
+ "c": "people",
+ "e": "ðŸ‘ðŸ½",
+ "d": "thumbs up sign tone 3",
+ "u": "8.0"
+ },
+ "thumbsup_tone4": {
+ "c": "people",
+ "e": "ðŸ‘ðŸ¾",
+ "d": "thumbs up sign tone 4",
+ "u": "8.0"
+ },
+ "thumbsup_tone5": {
+ "c": "people",
+ "e": "ðŸ‘ðŸ¿",
+ "d": "thumbs up sign tone 5",
+ "u": "8.0"
+ },
+ "thunder_cloud_rain": {
+ "c": "nature",
+ "e": "⛈",
+ "d": "thunder cloud and rain",
+ "u": "5.2"
+ },
+ "ticket": {
+ "c": "activity",
+ "e": "🎫",
+ "d": "ticket",
+ "u": "6.0"
+ },
+ "tickets": {
+ "c": "activity",
+ "e": "🎟",
+ "d": "admission tickets",
+ "u": "7.0"
+ },
+ "tiger": {
+ "c": "nature",
+ "e": "ðŸ¯",
+ "d": "tiger face",
+ "u": "6.0"
+ },
+ "tiger2": {
+ "c": "nature",
+ "e": "ðŸ…",
+ "d": "tiger",
+ "u": "6.0"
+ },
+ "timer": {
+ "c": "objects",
+ "e": "â²",
+ "d": "timer clock",
+ "u": "6.0"
+ },
+ "tired_face": {
+ "c": "people",
+ "e": "😫",
+ "d": "tired face",
+ "u": "6.0"
+ },
+ "tm": {
+ "c": "symbols",
+ "e": "â„¢",
+ "d": "trade mark sign",
+ "u": "1.1"
+ },
+ "toilet": {
+ "c": "objects",
+ "e": "🚽",
+ "d": "toilet",
+ "u": "6.0"
+ },
+ "tokyo_tower": {
+ "c": "travel",
+ "e": "🗼",
+ "d": "tokyo tower",
+ "u": "6.0"
+ },
+ "tomato": {
+ "c": "food",
+ "e": "ðŸ…",
+ "d": "tomato",
+ "u": "6.0"
+ },
+ "tone1": {
+ "c": "modifier",
+ "e": "ðŸ»",
+ "d": "emoji modifier Fitzpatrick type-1-2",
+ "u": "8.0"
+ },
+ "tone2": {
+ "c": "modifier",
+ "e": "ðŸ¼",
+ "d": "emoji modifier Fitzpatrick type-3",
+ "u": "8.0"
+ },
+ "tone3": {
+ "c": "modifier",
+ "e": "ðŸ½",
+ "d": "emoji modifier Fitzpatrick type-4",
+ "u": "8.0"
+ },
+ "tone4": {
+ "c": "modifier",
+ "e": "ðŸ¾",
+ "d": "emoji modifier Fitzpatrick type-5",
+ "u": "8.0"
+ },
+ "tone5": {
+ "c": "modifier",
+ "e": "ðŸ¿",
+ "d": "emoji modifier Fitzpatrick type-6",
+ "u": "8.0"
+ },
+ "tongue": {
+ "c": "people",
+ "e": "👅",
+ "d": "tongue",
+ "u": "6.0"
+ },
+ "tools": {
+ "c": "objects",
+ "e": "🛠",
+ "d": "hammer and wrench",
+ "u": "7.0"
+ },
+ "top": {
+ "c": "symbols",
+ "e": "ðŸ”",
+ "d": "top with upwards arrow above",
+ "u": "6.0"
+ },
+ "tophat": {
+ "c": "people",
+ "e": "🎩",
+ "d": "top hat",
+ "u": "6.0"
+ },
+ "track_next": {
+ "c": "symbols",
+ "e": "â­",
+ "d": "black right-pointing double triangle with vertical bar",
+ "u": "6.0"
+ },
+ "track_previous": {
+ "c": "symbols",
+ "e": "â®",
+ "d": "black left-pointing double triangle with vertical bar",
+ "u": "6.0"
+ },
+ "trackball": {
+ "c": "objects",
+ "e": "🖲",
+ "d": "trackball",
+ "u": "7.0"
+ },
+ "tractor": {
+ "c": "travel",
+ "e": "🚜",
+ "d": "tractor",
+ "u": "6.0"
+ },
+ "traffic_light": {
+ "c": "travel",
+ "e": "🚥",
+ "d": "horizontal traffic light",
+ "u": "6.0"
+ },
+ "train": {
+ "c": "travel",
+ "e": "🚋",
+ "d": "Tram Car",
+ "u": "6.0"
+ },
+ "train2": {
+ "c": "travel",
+ "e": "🚆",
+ "d": "train",
+ "u": "6.0"
+ },
+ "tram": {
+ "c": "travel",
+ "e": "🚊",
+ "d": "tram",
+ "u": "6.0"
+ },
+ "triangular_flag_on_post": {
+ "c": "objects",
+ "e": "🚩",
+ "d": "triangular flag on post",
+ "u": "6.0"
+ },
+ "triangular_ruler": {
+ "c": "objects",
+ "e": "ðŸ“",
+ "d": "triangular ruler",
+ "u": "6.0"
+ },
+ "trident": {
+ "c": "symbols",
+ "e": "🔱",
+ "d": "trident emblem",
+ "u": "6.0"
+ },
+ "triumph": {
+ "c": "people",
+ "e": "😤",
+ "d": "face with look of triumph",
+ "u": "6.0"
+ },
+ "trolleybus": {
+ "c": "travel",
+ "e": "🚎",
+ "d": "trolleybus",
+ "u": "6.0"
+ },
+ "trophy": {
+ "c": "activity",
+ "e": "ðŸ†",
+ "d": "trophy",
+ "u": "6.0"
+ },
+ "tropical_drink": {
+ "c": "food",
+ "e": "ðŸ¹",
+ "d": "tropical drink",
+ "u": "6.0"
+ },
+ "tropical_fish": {
+ "c": "nature",
+ "e": "ðŸ ",
+ "d": "tropical fish",
+ "u": "6.0"
+ },
+ "truck": {
+ "c": "travel",
+ "e": "🚚",
+ "d": "delivery truck",
+ "u": "6.0"
+ },
+ "trumpet": {
+ "c": "activity",
+ "e": "🎺",
+ "d": "trumpet",
+ "u": "6.0"
+ },
+ "tulip": {
+ "c": "nature",
+ "e": "🌷",
+ "d": "tulip",
+ "u": "6.0"
+ },
+ "tumbler_glass": {
+ "c": "food",
+ "e": "🥃",
+ "d": "tumbler glass",
+ "u": "9.0"
+ },
+ "turkey": {
+ "c": "nature",
+ "e": "🦃",
+ "d": "turkey",
+ "u": "8.0"
+ },
+ "turtle": {
+ "c": "nature",
+ "e": "ðŸ¢",
+ "d": "turtle",
+ "u": "6.0"
+ },
+ "tv": {
+ "c": "objects",
+ "e": "📺",
+ "d": "television",
+ "u": "6.0"
+ },
+ "twisted_rightwards_arrows": {
+ "c": "symbols",
+ "e": "🔀",
+ "d": "twisted rightwards arrows",
+ "u": "6.0"
+ },
+ "two": {
+ "c": "symbols",
+ "e": "2ï¸âƒ£",
+ "d": "keycap digit two",
+ "u": "3.0"
+ },
+ "two_hearts": {
+ "c": "symbols",
+ "e": "💕",
+ "d": "two hearts",
+ "u": "6.0"
+ },
+ "two_men_holding_hands": {
+ "c": "people",
+ "e": "👬",
+ "d": "two men holding hands",
+ "u": "6.0"
+ },
+ "two_women_holding_hands": {
+ "c": "people",
+ "e": "👭",
+ "d": "two women holding hands",
+ "u": "6.0"
+ },
+ "u5272": {
+ "c": "symbols",
+ "e": "🈹",
+ "d": "squared cjk unified ideograph-5272",
+ "u": "6.0"
+ },
+ "u5408": {
+ "c": "symbols",
+ "e": "🈴",
+ "d": "squared cjk unified ideograph-5408",
+ "u": "6.0"
+ },
+ "u55b6": {
+ "c": "symbols",
+ "e": "🈺",
+ "d": "squared cjk unified ideograph-55b6",
+ "u": "6.0"
+ },
+ "u6307": {
+ "c": "symbols",
+ "e": "🈯",
+ "d": "squared cjk unified ideograph-6307",
+ "u": "5.2"
+ },
+ "u6708": {
+ "c": "symbols",
+ "e": "🈷",
+ "d": "squared cjk unified ideograph-6708",
+ "u": "6.0"
+ },
+ "u6709": {
+ "c": "symbols",
+ "e": "🈶",
+ "d": "squared cjk unified ideograph-6709",
+ "u": "6.0"
+ },
+ "u6e80": {
+ "c": "symbols",
+ "e": "🈵",
+ "d": "squared cjk unified ideograph-6e80",
+ "u": "6.0"
+ },
+ "u7121": {
+ "c": "symbols",
+ "e": "🈚",
+ "d": "squared cjk unified ideograph-7121",
+ "u": "5.2"
+ },
+ "u7533": {
+ "c": "symbols",
+ "e": "🈸",
+ "d": "squared cjk unified ideograph-7533",
+ "u": "6.0"
+ },
+ "u7981": {
+ "c": "symbols",
+ "e": "🈲",
+ "d": "squared cjk unified ideograph-7981",
+ "u": "6.0"
+ },
+ "u7a7a": {
+ "c": "symbols",
+ "e": "🈳",
+ "d": "squared cjk unified ideograph-7a7a",
+ "u": "6.0"
+ },
+ "umbrella": {
+ "c": "nature",
+ "e": "☔",
+ "d": "umbrella with rain drops",
+ "u": "4.0"
+ },
+ "umbrella2": {
+ "c": "nature",
+ "e": "☂",
+ "d": "umbrella",
+ "u": "1.1"
+ },
+ "unamused": {
+ "c": "people",
+ "e": "😒",
+ "d": "unamused face",
+ "u": "6.0"
+ },
+ "underage": {
+ "c": "symbols",
+ "e": "🔞",
+ "d": "no one under eighteen symbol",
+ "u": "6.0"
+ },
+ "unicorn": {
+ "c": "nature",
+ "e": "🦄",
+ "d": "unicorn face",
+ "u": "8.0"
+ },
+ "unlock": {
+ "c": "objects",
+ "e": "🔓",
+ "d": "open lock",
+ "u": "6.0"
+ },
+ "up": {
+ "c": "symbols",
+ "e": "🆙",
+ "d": "squared up with exclamation mark",
+ "u": "6.0"
+ },
+ "upside_down": {
+ "c": "people",
+ "e": "🙃",
+ "d": "upside-down face",
+ "u": "8.0"
+ },
+ "urn": {
+ "c": "objects",
+ "e": "âš±",
+ "d": "funeral urn",
+ "u": "4.1"
+ },
+ "v": {
+ "c": "people",
+ "e": "✌",
+ "d": "victory hand",
+ "u": "1.1"
+ },
+ "v_tone1": {
+ "c": "people",
+ "e": "✌ðŸ»",
+ "d": "victory hand tone 1",
+ "u": "8.0"
+ },
+ "v_tone2": {
+ "c": "people",
+ "e": "✌ðŸ¼",
+ "d": "victory hand tone 2",
+ "u": "8.0"
+ },
+ "v_tone3": {
+ "c": "people",
+ "e": "✌ðŸ½",
+ "d": "victory hand tone 3",
+ "u": "8.0"
+ },
+ "v_tone4": {
+ "c": "people",
+ "e": "✌ðŸ¾",
+ "d": "victory hand tone 4",
+ "u": "8.0"
+ },
+ "v_tone5": {
+ "c": "people",
+ "e": "✌ðŸ¿",
+ "d": "victory hand tone 5",
+ "u": "8.0"
+ },
+ "vertical_traffic_light": {
+ "c": "travel",
+ "e": "🚦",
+ "d": "vertical traffic light",
+ "u": "6.0"
+ },
+ "vhs": {
+ "c": "objects",
+ "e": "📼",
+ "d": "videocassette",
+ "u": "6.0"
+ },
+ "vibration_mode": {
+ "c": "symbols",
+ "e": "📳",
+ "d": "vibration mode",
+ "u": "6.0"
+ },
+ "video_camera": {
+ "c": "objects",
+ "e": "📹",
+ "d": "video camera",
+ "u": "6.0"
+ },
+ "video_game": {
+ "c": "activity",
+ "e": "🎮",
+ "d": "video game",
+ "u": "6.0"
+ },
+ "violin": {
+ "c": "activity",
+ "e": "🎻",
+ "d": "violin",
+ "u": "6.0"
+ },
+ "virgo": {
+ "c": "symbols",
+ "e": "â™",
+ "d": "virgo",
+ "u": "1.1"
+ },
+ "volcano": {
+ "c": "travel",
+ "e": "🌋",
+ "d": "volcano",
+ "u": "6.0"
+ },
+ "volleyball": {
+ "c": "activity",
+ "e": "ðŸ",
+ "d": "volleyball",
+ "u": "8.0"
+ },
+ "vs": {
+ "c": "symbols",
+ "e": "🆚",
+ "d": "squared vs",
+ "u": "6.0"
+ },
+ "vulcan": {
+ "c": "people",
+ "e": "🖖",
+ "d": "raised hand with part between middle and ring fingers",
+ "u": "7.0"
+ },
+ "vulcan_tone1": {
+ "c": "people",
+ "e": "🖖ðŸ»",
+ "d": "raised hand with part between middle and ring fingers tone 1",
+ "u": "8.0"
+ },
+ "vulcan_tone2": {
+ "c": "people",
+ "e": "🖖ðŸ¼",
+ "d": "raised hand with part between middle and ring fingers tone 2",
+ "u": "8.0"
+ },
+ "vulcan_tone3": {
+ "c": "people",
+ "e": "🖖ðŸ½",
+ "d": "raised hand with part between middle and ring fingers tone 3",
+ "u": "8.0"
+ },
+ "vulcan_tone4": {
+ "c": "people",
+ "e": "🖖ðŸ¾",
+ "d": "raised hand with part between middle and ring fingers tone 4",
+ "u": "8.0"
+ },
+ "vulcan_tone5": {
+ "c": "people",
+ "e": "🖖ðŸ¿",
+ "d": "raised hand with part between middle and ring fingers tone 5",
+ "u": "8.0"
+ },
+ "walking": {
+ "c": "people",
+ "e": "🚶",
+ "d": "pedestrian",
+ "u": "6.0"
+ },
+ "walking_tone1": {
+ "c": "people",
+ "e": "🚶ðŸ»",
+ "d": "pedestrian tone 1",
+ "u": "8.0"
+ },
+ "walking_tone2": {
+ "c": "people",
+ "e": "🚶ðŸ¼",
+ "d": "pedestrian tone 2",
+ "u": "8.0"
+ },
+ "walking_tone3": {
+ "c": "people",
+ "e": "🚶ðŸ½",
+ "d": "pedestrian tone 3",
+ "u": "8.0"
+ },
+ "walking_tone4": {
+ "c": "people",
+ "e": "🚶ðŸ¾",
+ "d": "pedestrian tone 4",
+ "u": "8.0"
+ },
+ "walking_tone5": {
+ "c": "people",
+ "e": "🚶ðŸ¿",
+ "d": "pedestrian tone 5",
+ "u": "8.0"
+ },
+ "waning_crescent_moon": {
+ "c": "nature",
+ "e": "🌘",
+ "d": "waning crescent moon symbol",
+ "u": "6.0"
+ },
+ "waning_gibbous_moon": {
+ "c": "nature",
+ "e": "🌖",
+ "d": "waning gibbous moon symbol",
+ "u": "6.0"
+ },
+ "warning": {
+ "c": "symbols",
+ "e": "âš ",
+ "d": "warning sign",
+ "u": "4.0"
+ },
+ "wastebasket": {
+ "c": "objects",
+ "e": "🗑",
+ "d": "wastebasket",
+ "u": "7.0"
+ },
+ "watch": {
+ "c": "objects",
+ "e": "⌚",
+ "d": "watch",
+ "u": "1.1"
+ },
+ "water_buffalo": {
+ "c": "nature",
+ "e": "ðŸƒ",
+ "d": "water buffalo",
+ "u": "6.0"
+ },
+ "water_polo": {
+ "c": "activity",
+ "e": "🤽",
+ "d": "water polo",
+ "u": "9.0"
+ },
+ "water_polo_tone1": {
+ "c": "activity",
+ "e": "🤽ðŸ»",
+ "d": "water polo tone 1",
+ "u": "9.0"
+ },
+ "water_polo_tone2": {
+ "c": "activity",
+ "e": "🤽ðŸ¼",
+ "d": "water polo tone 2",
+ "u": "9.0"
+ },
+ "water_polo_tone3": {
+ "c": "activity",
+ "e": "🤽ðŸ½",
+ "d": "water polo tone 3",
+ "u": "9.0"
+ },
+ "water_polo_tone4": {
+ "c": "activity",
+ "e": "🤽ðŸ¾",
+ "d": "water polo tone 4",
+ "u": "9.0"
+ },
+ "water_polo_tone5": {
+ "c": "activity",
+ "e": "🤽ðŸ¿",
+ "d": "water polo tone 5",
+ "u": "9.0"
+ },
+ "watermelon": {
+ "c": "food",
+ "e": "ðŸ‰",
+ "d": "watermelon",
+ "u": "6.0"
+ },
+ "wave": {
+ "c": "people",
+ "e": "👋",
+ "d": "waving hand sign",
+ "u": "6.0"
+ },
+ "wave_tone1": {
+ "c": "people",
+ "e": "👋ðŸ»",
+ "d": "waving hand sign tone 1",
+ "u": "8.0"
+ },
+ "wave_tone2": {
+ "c": "people",
+ "e": "👋ðŸ¼",
+ "d": "waving hand sign tone 2",
+ "u": "8.0"
+ },
+ "wave_tone3": {
+ "c": "people",
+ "e": "👋ðŸ½",
+ "d": "waving hand sign tone 3",
+ "u": "8.0"
+ },
+ "wave_tone4": {
+ "c": "people",
+ "e": "👋ðŸ¾",
+ "d": "waving hand sign tone 4",
+ "u": "8.0"
+ },
+ "wave_tone5": {
+ "c": "people",
+ "e": "👋ðŸ¿",
+ "d": "waving hand sign tone 5",
+ "u": "8.0"
+ },
+ "wavy_dash": {
+ "c": "symbols",
+ "e": "〰",
+ "d": "wavy dash",
+ "u": "1.1"
+ },
+ "waxing_crescent_moon": {
+ "c": "nature",
+ "e": "🌒",
+ "d": "waxing crescent moon symbol",
+ "u": "6.0"
+ },
+ "waxing_gibbous_moon": {
+ "c": "nature",
+ "e": "🌔",
+ "d": "waxing gibbous moon symbol",
+ "u": "6.0"
+ },
+ "wc": {
+ "c": "symbols",
+ "e": "🚾",
+ "d": "water closet",
+ "u": "6.0"
+ },
+ "weary": {
+ "c": "people",
+ "e": "😩",
+ "d": "weary face",
+ "u": "6.0"
+ },
+ "wedding": {
+ "c": "travel",
+ "e": "💒",
+ "d": "wedding",
+ "u": "6.0"
+ },
+ "whale": {
+ "c": "nature",
+ "e": "ðŸ³",
+ "d": "spouting whale",
+ "u": "6.0"
+ },
+ "whale2": {
+ "c": "nature",
+ "e": "ðŸ‹",
+ "d": "whale",
+ "u": "6.0"
+ },
+ "wheel_of_dharma": {
+ "c": "symbols",
+ "e": "☸",
+ "d": "wheel of dharma",
+ "u": "1.1"
+ },
+ "wheelchair": {
+ "c": "symbols",
+ "e": "♿",
+ "d": "wheelchair symbol",
+ "u": "4.1"
+ },
+ "white_check_mark": {
+ "c": "symbols",
+ "e": "✅",
+ "d": "white heavy check mark",
+ "u": "6.0"
+ },
+ "white_circle": {
+ "c": "symbols",
+ "e": "⚪",
+ "d": "medium white circle",
+ "u": "4.1"
+ },
+ "white_flower": {
+ "c": "symbols",
+ "e": "💮",
+ "d": "white flower",
+ "u": "6.0"
+ },
+ "white_large_square": {
+ "c": "symbols",
+ "e": "⬜",
+ "d": "white large square",
+ "u": "5.1"
+ },
+ "white_medium_small_square": {
+ "c": "symbols",
+ "e": "â—½",
+ "d": "white medium small square",
+ "u": "3.2"
+ },
+ "white_medium_square": {
+ "c": "symbols",
+ "e": "â—»",
+ "d": "white medium square",
+ "u": "3.2"
+ },
+ "white_small_square": {
+ "c": "symbols",
+ "e": "â–«",
+ "d": "white small square",
+ "u": "1.1"
+ },
+ "white_square_button": {
+ "c": "symbols",
+ "e": "🔳",
+ "d": "white square button",
+ "u": "6.0"
+ },
+ "white_sun_cloud": {
+ "c": "nature",
+ "e": "🌥",
+ "d": "white sun behind cloud",
+ "u": "7.0"
+ },
+ "white_sun_rain_cloud": {
+ "c": "nature",
+ "e": "🌦",
+ "d": "white sun behind cloud with rain",
+ "u": "7.0"
+ },
+ "white_sun_small_cloud": {
+ "c": "nature",
+ "e": "🌤",
+ "d": "white sun with small cloud",
+ "u": "7.0"
+ },
+ "wilted_rose": {
+ "c": "nature",
+ "e": "🥀",
+ "d": "wilted flower",
+ "u": "9.0"
+ },
+ "wind_blowing_face": {
+ "c": "nature",
+ "e": "🌬",
+ "d": "wind blowing face",
+ "u": "7.0"
+ },
+ "wind_chime": {
+ "c": "objects",
+ "e": "ðŸŽ",
+ "d": "wind chime",
+ "u": "6.0"
+ },
+ "wine_glass": {
+ "c": "food",
+ "e": "ðŸ·",
+ "d": "wine glass",
+ "u": "6.0"
+ },
+ "wink": {
+ "c": "people",
+ "e": "😉",
+ "d": "winking face",
+ "u": "6.0"
+ },
+ "wolf": {
+ "c": "nature",
+ "e": "ðŸº",
+ "d": "wolf face",
+ "u": "6.0"
+ },
+ "woman": {
+ "c": "people",
+ "e": "👩",
+ "d": "woman",
+ "u": "6.0"
+ },
+ "woman_tone1": {
+ "c": "people",
+ "e": "👩ðŸ»",
+ "d": "woman tone 1",
+ "u": "8.0"
+ },
+ "woman_tone2": {
+ "c": "people",
+ "e": "👩ðŸ¼",
+ "d": "woman tone 2",
+ "u": "8.0"
+ },
+ "woman_tone3": {
+ "c": "people",
+ "e": "👩ðŸ½",
+ "d": "woman tone 3",
+ "u": "8.0"
+ },
+ "woman_tone4": {
+ "c": "people",
+ "e": "👩ðŸ¾",
+ "d": "woman tone 4",
+ "u": "8.0"
+ },
+ "woman_tone5": {
+ "c": "people",
+ "e": "👩ðŸ¿",
+ "d": "woman tone 5",
+ "u": "8.0"
+ },
+ "womans_clothes": {
+ "c": "people",
+ "e": "👚",
+ "d": "womans clothes",
+ "u": "6.0"
+ },
+ "womans_hat": {
+ "c": "people",
+ "e": "👒",
+ "d": "womans hat",
+ "u": "6.0"
+ },
+ "womens": {
+ "c": "symbols",
+ "e": "🚺",
+ "d": "womens symbol",
+ "u": "6.0"
+ },
+ "worried": {
+ "c": "people",
+ "e": "😟",
+ "d": "worried face",
+ "u": "6.1"
+ },
+ "wrench": {
+ "c": "objects",
+ "e": "🔧",
+ "d": "wrench",
+ "u": "6.0"
+ },
+ "wrestlers": {
+ "c": "activity",
+ "e": "🤼",
+ "d": "wrestlers",
+ "u": "9.0"
+ },
+ "wrestlers_tone1": {
+ "c": "activity",
+ "e": "🤼ðŸ»",
+ "d": "wrestlers tone 1",
+ "u": "9.0"
+ },
+ "wrestlers_tone2": {
+ "c": "activity",
+ "e": "🤼ðŸ¼",
+ "d": "wrestlers tone 2",
+ "u": "9.0"
+ },
+ "wrestlers_tone3": {
+ "c": "activity",
+ "e": "🤼ðŸ½",
+ "d": "wrestlers tone 3",
+ "u": "9.0"
+ },
+ "wrestlers_tone4": {
+ "c": "activity",
+ "e": "🤼ðŸ¾",
+ "d": "wrestlers tone 4",
+ "u": "9.0"
+ },
+ "wrestlers_tone5": {
+ "c": "activity",
+ "e": "🤼ðŸ¿",
+ "d": "wrestlers tone 5",
+ "u": "9.0"
+ },
+ "writing_hand": {
+ "c": "people",
+ "e": "âœ",
+ "d": "writing hand",
+ "u": "1.1"
+ },
+ "writing_hand_tone1": {
+ "c": "people",
+ "e": "âœðŸ»",
+ "d": "writing hand tone 1",
+ "u": "8.0"
+ },
+ "writing_hand_tone2": {
+ "c": "people",
+ "e": "âœðŸ¼",
+ "d": "writing hand tone 2",
+ "u": "8.0"
+ },
+ "writing_hand_tone3": {
+ "c": "people",
+ "e": "âœðŸ½",
+ "d": "writing hand tone 3",
+ "u": "8.0"
+ },
+ "writing_hand_tone4": {
+ "c": "people",
+ "e": "âœðŸ¾",
+ "d": "writing hand tone 4",
+ "u": "8.0"
+ },
+ "writing_hand_tone5": {
+ "c": "people",
+ "e": "âœðŸ¿",
+ "d": "writing hand tone 5",
+ "u": "8.0"
+ },
+ "x": {
+ "c": "symbols",
+ "e": "âŒ",
+ "d": "cross mark",
+ "u": "6.0"
+ },
+ "yellow_heart": {
+ "c": "symbols",
+ "e": "💛",
+ "d": "yellow heart",
+ "u": "6.0"
+ },
+ "yen": {
+ "c": "objects",
+ "e": "💴",
+ "d": "banknote with yen sign",
+ "u": "6.0"
+ },
+ "yin_yang": {
+ "c": "symbols",
+ "e": "☯",
+ "d": "yin yang",
+ "u": "1.1"
+ },
+ "yum": {
+ "c": "people",
+ "e": "😋",
+ "d": "face savouring delicious food",
+ "u": "6.0"
+ },
+ "zap": {
+ "c": "nature",
+ "e": "âš¡",
+ "d": "high voltage sign",
+ "u": "4.0"
+ },
+ "zero": {
+ "c": "symbols",
+ "e": "0ï¸âƒ£",
+ "d": "keycap digit zero",
+ "u": "3.0"
+ },
+ "zipper_mouth": {
+ "c": "people",
+ "e": "ðŸ¤",
+ "d": "zipper-mouth face",
+ "u": "8.0"
+ },
+ "zzz": {
+ "c": "people",
+ "e": "💤",
+ "d": "sleeping symbol",
+ "u": "6.0"
+ }
+} \ No newline at end of file
diff --git a/public/robots.txt b/public/robots.txt
index 6f2396d0869..20cd97a596f 100644
--- a/public/robots.txt
+++ b/public/robots.txt
@@ -35,6 +35,7 @@ Disallow: /snippets/*/raw
User-Agent: *
Disallow: /*/*.git
Disallow: /*/*/fork/new
+Disallow: /*/-/archive/
Disallow: /*/*/repository/archive*
Disallow: /*/*/activity
Disallow: /*/*/new
diff --git a/qa/Dockerfile b/qa/Dockerfile
index 155a9761a6f..7f90e4bf5bf 100644
--- a/qa/Dockerfile
+++ b/qa/Dockerfile
@@ -1,6 +1,13 @@
FROM ruby:2.6-stretch
LABEL maintainer="GitLab Quality Department <quality@gitlab.com>"
-ENV DEBIAN_FRONTEND noninteractive
+
+ENV DEBIAN_FRONTEND="noninteractive"
+ENV DOCKER_VERSION="17.09.0-ce"
+ENV CHROME_VERSION="83.0.4103.61-1"
+ENV CHROME_DRIVER_VERSION="83.0.4103.39"
+ENV CHROME_DEB="google-chrome-stable_${CHROME_VERSION}_amd64.deb"
+ENV CHROME_URL="https://s3.amazonaws.com/gitlab-google-chrome-stable/${CHROME_DEB}"
+ENV K3D_VERSION="1.3.4"
##
# Add support for stretch-backports
@@ -21,28 +28,31 @@ RUN apt-get -y -t stretch-backports install git git-lfs
##
# Install Docker
#
-RUN wget -q https://download.docker.com/linux/static/stable/x86_64/docker-17.09.0-ce.tgz && \
- tar -zxf docker-17.09.0-ce.tgz && mv docker/docker /usr/local/bin/docker && \
- rm docker-17.09.0-ce.tgz
+RUN wget -q "https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKER_VERSION}.tgz" && \
+ tar -zxf "docker-${DOCKER_VERSION}.tgz" && mv docker/docker /usr/local/bin/docker && \
+ rm "docker-${DOCKER_VERSION}.tgz"
##
# Install Google Chrome version with headless support
+# Download from our local S3 bucket, populated by https://gitlab.com/gitlab-org/gitlab-build-images/-/blob/master/scripts/cache-google-chrome
#
-RUN curl -sS -L https://dl.google.com/linux/linux_signing_key.pub | apt-key add -
-RUN echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google.list
-RUN apt-get update -q && apt-get install -y google-chrome-stable && apt-get clean
+RUN curl --silent --show-error --fail -O "${CHROME_URL}" && \
+ dpkg -i "./${CHROME_DEB}" || true && \
+ apt-get install -f -y && \
+ rm -f "./${CHROME_DEB}"
##
# Install chromedriver to make it work with Selenium
#
-RUN wget -q https://chromedriver.storage.googleapis.com/$(wget -q -O - https://chromedriver.storage.googleapis.com/LATEST_RELEASE)/chromedriver_linux64.zip
+RUN wget -q "https://chromedriver.storage.googleapis.com/${CHROME_DRIVER_VERSION}/chromedriver_linux64.zip"
RUN unzip chromedriver_linux64.zip -d /usr/local/bin
+RUN rm -f chromedriver_linux64.zip
##
# Install K3d local cluster support
# https://github.com/rancher/k3d
#
-RUN curl -s https://raw.githubusercontent.com/rancher/k3d/master/install.sh | TAG=v1.3.4 bash
+RUN curl -s https://raw.githubusercontent.com/rancher/k3d/master/install.sh | TAG="v${K3D_VERSION}" bash
##
# Install gcloud and kubectl CLI used in Auto DevOps test to create K8s
diff --git a/qa/Gemfile b/qa/Gemfile
index 6eb8733ab41..d5c682ef76f 100644
--- a/qa/Gemfile
+++ b/qa/Gemfile
@@ -1,7 +1,7 @@
source 'https://rubygems.org'
gem 'gitlab-qa'
-gem 'activesupport', '~> 6.0.3' # This should stay in sync with the root's Gemfile
+gem 'activesupport', '~> 6.0.3.1' # This should stay in sync with the root's Gemfile
gem 'capybara', '~> 3.29.0'
gem 'capybara-screenshot', '~> 1.0.23'
gem 'rake', '~> 12.3.0'
diff --git a/qa/Gemfile.lock b/qa/Gemfile.lock
index 9aeba236c96..23324fccdec 100644
--- a/qa/Gemfile.lock
+++ b/qa/Gemfile.lock
@@ -1,7 +1,7 @@
GEM
remote: https://rubygems.org/
specs:
- activesupport (6.0.3)
+ activesupport (6.0.3.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
@@ -54,7 +54,7 @@ GEM
mime-types-data (3.2020.0425)
mini_mime (1.0.2)
mini_portile2 (2.4.0)
- minitest (5.14.0)
+ minitest (5.14.1)
netrc (0.11.0)
nokogiri (1.10.9)
mini_portile2 (~> 2.4.0)
@@ -116,7 +116,7 @@ PLATFORMS
ruby
DEPENDENCIES
- activesupport (~> 6.0.3)
+ activesupport (~> 6.0.3.1)
airborne (~> 0.3.4)
capybara (~> 3.29.0)
capybara-screenshot (~> 1.0.23)
diff --git a/qa/qa.rb b/qa/qa.rb
index fe22b5792c3..4649f452c6f 100644
--- a/qa/qa.rb
+++ b/qa/qa.rb
@@ -43,6 +43,7 @@ module QA
module API
autoload :Client, 'qa/runtime/api/client'
+ autoload :RepositoryStorageMoves, 'qa/runtime/api/repository_storage_moves'
autoload :Request, 'qa/runtime/api/request'
end
@@ -79,15 +80,16 @@ module QA
autoload :User, 'qa/resource/user'
autoload :ProjectMilestone, 'qa/resource/project_milestone'
autoload :Members, 'qa/resource/members'
- autoload :Wiki, 'qa/resource/wiki'
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'
module KubernetesCluster
autoload :Base, 'qa/resource/kubernetes_cluster/base'
@@ -109,6 +111,10 @@ module QA
module Settings
autoload :HashedStorage, 'qa/resource/settings/hashed_storage'
end
+
+ module Wiki
+ autoload :ProjectPage, 'qa/resource/wiki/project_page'
+ end
end
##
@@ -131,6 +137,7 @@ module QA
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
@@ -224,9 +231,11 @@ module QA
module Project
autoload :New, 'qa/page/project/new'
+ autoload :NewExperiment, 'qa/page/project/new_experiment'
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 Branches
autoload :Show, 'qa/page/project/branches/show'
@@ -254,6 +263,7 @@ module QA
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'
@@ -262,9 +272,12 @@ module QA
autoload :CiVariables, 'qa/page/project/settings/ci_variables'
autoload :Runners, 'qa/page/project/settings/runners'
autoload :MergeRequest, 'qa/page/project/settings/merge_request'
- autoload :Members, 'qa/page/project/settings/members'
autoload :MirroringRepositories, 'qa/page/project/settings/mirroring_repositories'
autoload :VisibilityFeaturesPermissions, 'qa/page/project/settings/visibility_features_permissions'
+
+ module Services
+ autoload :Jira, 'qa/page/project/settings/services/jira'
+ end
autoload :Operations, 'qa/page/project/settings/operations'
autoload :Incidents, 'qa/page/project/settings/incidents'
autoload :Integrations, 'qa/page/project/settings/integrations'
@@ -319,7 +332,6 @@ module QA
module Wiki
autoload :Edit, 'qa/page/project/wiki/edit'
- autoload :New, 'qa/page/project/wiki/new'
autoload :Show, 'qa/page/project/wiki/show'
autoload :GitAccess, 'qa/page/project/wiki/git_access'
end
@@ -327,6 +339,10 @@ module QA
module WebIDE
autoload :Edit, 'qa/page/project/web_ide/edit'
end
+
+ module Snippet
+ autoload :New, 'qa/page/project/snippet/new'
+ end
end
module Profile
@@ -339,6 +355,7 @@ module QA
end
module Issuable
+ autoload :New, 'qa/page/issuable/new'
autoload :Sidebar, 'qa/page/issuable/sidebar'
end
@@ -427,8 +444,16 @@ module QA
autoload :Common, 'qa/page/component/issuable/common'
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
@@ -512,6 +537,10 @@ module QA
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.
diff --git a/qa/qa/flow/project.rb b/qa/qa/flow/project.rb
index 72b9357a604..db42a3a3594 100644
--- a/qa/qa/flow/project.rb
+++ b/qa/qa/flow/project.rb
@@ -8,12 +8,20 @@ module QA
def add_member(project:, username:)
project.visit!
- Page::Project::Menu.perform(&:go_to_members_settings)
+ Page::Project::Menu.perform(&:click_members)
- Page::Project::Settings::Members.perform do |member_settings|
+ Page::Project::Members.perform do |member_settings|
member_settings.add_member(username)
end
end
+
+ def go_to_create_project_from_template
+ if Page::Project::NewExperiment.perform(&:shown?)
+ Page::Project::NewExperiment.perform(&:click_create_from_template_link)
+ else
+ Page::Project::New.perform(&:click_create_from_template_tab)
+ end
+ end
end
end
end
diff --git a/qa/qa/git/repository.rb b/qa/qa/git/repository.rb
index bd2fbbd80cb..43608827b2e 100644
--- a/qa/qa/git/repository.rb
+++ b/qa/qa/git/repository.rb
@@ -111,7 +111,7 @@ module QA
end
def commit_with_gpg(message)
- run(%Q{git config user.signingkey #{@gpg_key_id} && git config gpg.program $(which gpg) && git commit -S -m "#{message}"}).to_s
+ run(%Q{git config user.signingkey #{@gpg_key_id} && git config gpg.program $(command -v gpg) && git commit -S -m "#{message}"}).to_s
end
def push_changes(branch = 'master')
diff --git a/qa/qa/page/base.rb b/qa/qa/page/base.rb
index cb3827f8eb1..f0d4ae45ef8 100644
--- a/qa/qa/page/base.rb
+++ b/qa/qa/page/base.rb
@@ -99,7 +99,16 @@ module QA
def find_element(name, **kwargs)
wait_for_requests
- find(element_selector_css(name), kwargs)
+ element_selector = element_selector_css(name, reject_capybara_query_keywords(kwargs))
+ find(element_selector, only_capybara_query_keywords(kwargs))
+ end
+
+ def only_capybara_query_keywords(kwargs)
+ kwargs.select { |kwarg| Capybara::Queries::SelectorQuery::VALID_KEYS.include?(kwarg) }
+ end
+
+ def reject_capybara_query_keywords(kwargs)
+ kwargs.reject { |kwarg| Capybara::Queries::SelectorQuery::VALID_KEYS.include?(kwarg) }
end
def active_element?(name)
@@ -162,11 +171,17 @@ module QA
def has_element?(name, **kwargs)
wait_for_requests
- wait = kwargs.delete(:wait) || Capybara.default_max_wait_time
- text = kwargs.delete(:text)
- klass = kwargs.delete(:class)
+ disabled = kwargs.delete(:disabled)
- has_css?(element_selector_css(name, kwargs), text: text, wait: wait, class: klass)
+ if disabled.nil?
+ wait = kwargs.delete(:wait) || Capybara.default_max_wait_time
+ text = kwargs.delete(:text)
+ klass = kwargs.delete(:class)
+
+ has_css?(element_selector_css(name, kwargs), text: text, wait: wait, class: klass)
+ else
+ find_element(name, kwargs).disabled? == disabled
+ end
end
def has_no_element?(name, **kwargs)
diff --git a/qa/qa/page/component/issue_board/show.rb b/qa/qa/page/component/issue_board/show.rb
new file mode 100644
index 00000000000..0c840eba7ce
--- /dev/null
+++ b/qa/qa/page/component/issue_board/show.rb
@@ -0,0 +1,138 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Component
+ module IssueBoard
+ class Show < QA::Page::Base
+ view 'app/assets/javascripts/boards/components/board_card.vue' do
+ element :board_card
+ end
+
+ view 'app/assets/javascripts/boards/components/board_form.vue' do
+ element :board_name_field
+ end
+
+ view 'app/assets/javascripts/boards/components/board_list.vue' do
+ element :board_list_cards_area
+ end
+
+ view 'app/assets/javascripts/boards/components/boards_selector.vue' do
+ element :boards_dropdown
+ element :boards_dropdown_content
+ element :create_new_board_button
+ end
+
+ view 'app/assets/javascripts/vue_shared/components/deprecated_modal.vue' do
+ element :save_changes_button
+ end
+
+ view 'app/assets/javascripts/vue_shared/components/sidebar/labels_select/base.vue' do
+ element :labels_dropdown_content
+ end
+
+ view 'app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_title.vue' do
+ element :labels_edit_button
+ end
+
+ view 'app/views/shared/boards/_show.html.haml' do
+ element :boards_list
+ end
+
+ view 'app/views/shared/boards/components/_board.html.haml' do
+ element :board_list
+ element :board_list_header
+ end
+
+ view 'app/assets/javascripts/boards/toggle_focus.js' do
+ element :focus_mode_button
+ end
+
+ # The `focused_board` method does not use `find_element` with an element defined
+ # with the attribute `data-qa-selector` since such element is not unique when the
+ # `is-focused` class is not set, and it was not possible to find a better solution.
+ def focused_board
+ find('.issue-boards-content.js-focus-mode-board.is-focused')
+ end
+
+ def boards_dropdown
+ find_element(:boards_dropdown)
+ end
+
+ def boards_dropdown_content
+ find_element(:boards_dropdown_content)
+ end
+
+ def boards_list_cards_area_with_index(index)
+ wait_boards_list_finish_loading do
+ within_element_by_index(:board_list, index) do
+ find_element(:board_list_cards_area)
+ end
+ end
+ end
+
+ def boards_list_header_with_index(index)
+ wait_boards_list_finish_loading do
+ within_element_by_index(:board_list, index) do
+ find_element(:board_list_header)
+ end
+ end
+ end
+
+ def card_of_list_with_index(index)
+ wait_boards_list_finish_loading do
+ within_element_by_index(:board_list, index) do
+ find_element(:board_card)
+ end
+ end
+ end
+
+ def click_boards_dropdown_button
+ # The dropdown button comes from the `GlDropdown` component of `@gitlab/ui`,
+ # so it wasn't possible to add a `data-qa-selector` to it.
+ find_element(:boards_dropdown).find('button').click
+ end
+
+ def click_focus_mode_button
+ click_element(:focus_mode_button)
+ end
+
+ def configure_by_label(label)
+ click_boards_config_button
+ click_element(:labels_edit_button)
+ find_element(:labels_dropdown_content).find('li', text: label).click
+ click_element(:save_changes_button)
+ wait_boards_list_finish_loading
+ end
+
+ def create_new_board(board_name)
+ click_boards_dropdown_button
+ click_element(:create_new_board_button)
+ set_name(board_name)
+ end
+
+ def has_modal_board_name_field?
+ has_element?(:board_name_field, wait: 1)
+ end
+
+ def set_name(name)
+ find_element(:board_name_field).set(name)
+ click_element(:save_changes_button)
+ end
+
+ private
+
+ def wait_boards_list_finish_loading
+ within_element(:boards_list) do
+ wait_until(reload: false, max_duration: 5, sleep_interval: 1) do
+ finished_loading? && (block_given? ? yield : true)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+QA::Page::Component::IssueBoard::Show.prepend_if_ee('QA::EE::Page::Component::IssueBoard::Show')
diff --git a/qa/qa/page/component/web_ide/modal/create_new_file.rb b/qa/qa/page/component/web_ide/modal/create_new_file.rb
new file mode 100644
index 00000000000..48eb32fefd6
--- /dev/null
+++ b/qa/qa/page/component/web_ide/modal/create_new_file.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Component
+ module WebIDE
+ module Modal
+ class CreateNewFile < Page::Base
+ view 'app/assets/javascripts/ide/components/new_dropdown/modal.vue' do
+ element :file_name_field, required: true
+ element :new_file_modal, required: true
+ element :template_list, required: true
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/dashboard/snippet/new.rb b/qa/qa/page/dashboard/snippet/new.rb
index d1a194ba1db..bcfb4734b59 100644
--- a/qa/qa/page/dashboard/snippet/new.rb
+++ b/qa/qa/page/dashboard/snippet/new.rb
@@ -6,6 +6,7 @@ module QA
module Snippet
class New < Page::Base
view 'app/assets/javascripts/snippets/components/edit.vue' do
+ element :snippet_title_field, required: true
element :submit_button
end
@@ -14,12 +15,8 @@ module QA
element :description_placeholder, required: true
end
- view 'app/assets/javascripts/snippets/components/snippet_title.vue' do
- element :snippet_title, required: true
- end
-
view 'app/assets/javascripts/snippets/components/snippet_blob_edit.vue' do
- element :snippet_file_name
+ element :file_name_field
end
view 'app/views/shared/form_elements/_description.html.haml' do
@@ -29,18 +26,18 @@ module QA
view 'app/views/shared/snippets/_form.html.haml' do
element :snippet_description_field
element :description_placeholder
- element :snippet_title
- element :snippet_file_name
+ element :snippet_title_field
+ element :file_name_field
element :submit_button
end
- view 'app/views/projects/_zen.html.haml' do
+ view 'app/views/shared/_zen.html.haml' do
# This 'element' is here only to ensure the changes in the view source aren't mistakenly changed
element :_, "qa_selector = local_assigns.fetch(:qa_selector, '')" # rubocop:disable QA/ElementWithPattern
end
def fill_title(title)
- fill_element :snippet_title, title
+ fill_element :snippet_title_field, title
end
def fill_description(description)
@@ -54,7 +51,7 @@ module QA
def fill_file_name(name)
finished_loading?
- fill_element :snippet_file_name, name
+ fill_element :file_name_field, name
end
def fill_file_content(content)
diff --git a/qa/qa/page/dashboard/snippet/show.rb b/qa/qa/page/dashboard/snippet/show.rb
index d43b64cd1d4..da494ae70ec 100644
--- a/qa/qa/page/dashboard/snippet/show.rb
+++ b/qa/qa/page/dashboard/snippet/show.rb
@@ -6,32 +6,26 @@ module QA
module Snippet
class Show < Page::Base
view 'app/assets/javascripts/snippets/components/snippet_description_view.vue' do
- element :snippet_description_field
+ element :snippet_description_content
end
view 'app/assets/javascripts/snippets/components/snippet_title.vue' do
- element :snippet_title, required: true
+ element :snippet_title_content, required: true
end
- view 'app/views/shared/snippets/_header.html.haml' do
- element :snippet_title, required: true
- element :snippet_description_field, required: true
- element :snippet_box
- end
-
- view 'app/views/projects/blob/_header_content.html.haml' do
- element :file_title_name
+ view 'app/assets/javascripts/snippets/components/snippet_header.vue' do
+ element :snippet_container
end
view 'app/assets/javascripts/blob/components/blob_header_filepath.vue' do
- element :file_title_name
+ element :file_title_content
end
- view 'app/views/shared/_file_highlight.html.haml' do
+ view 'app/assets/javascripts/vue_shared/components/blob_viewers/simple_viewer.vue' do
element :file_content
end
- view 'app/assets/javascripts/vue_shared/components/blob_viewers/simple_viewer.vue' do
+ view 'app/assets/javascripts/blob/components/blob_content.vue' do
element :file_content
end
@@ -50,21 +44,25 @@ module QA
end
def has_snippet_title?(snippet_title)
- has_element? :snippet_title, text: snippet_title
+ has_element? :snippet_title_content, text: snippet_title
end
def has_snippet_description?(snippet_description)
- has_element? :snippet_description_field, text: snippet_description
+ has_element? :snippet_description_content, text: snippet_description
+ end
+
+ def has_no_snippet_description?
+ has_no_element?(:snippet_description_field)
end
def has_visibility_type?(visibility_type)
- within_element(:snippet_box) do
+ within_element(:snippet_container) do
has_text?(visibility_type)
end
end
def has_file_name?(file_name)
- within_element(:file_title_name) do
+ within_element(:file_title_content) do
has_text?(file_name)
end
end
@@ -85,7 +83,11 @@ module QA
finished_loading?
click_element(:snippet_action_button, action: 'Delete')
click_element(:delete_snippet_button)
- finished_loading? # wait for the page to reload after deletion
+ # wait for the page to reload after deletion
+ wait_until(reload: false) do
+ has_no_element?(:delete_snippet_button) &&
+ has_no_element?(:snippet_action_button, action: 'Delete')
+ end
end
def get_repository_uri_http
diff --git a/qa/qa/page/group/new.rb b/qa/qa/page/group/new.rb
index e01b8754d55..88e7121dbe0 100644
--- a/qa/qa/page/group/new.rb
+++ b/qa/qa/page/group/new.rb
@@ -10,7 +10,7 @@ module QA
element :group_description_field, 'text_area :description' # rubocop:disable QA/ElementWithPattern
end
- view 'app/views/groups/new.html.haml' do
+ view 'app/views/groups/_new_group_fields.html.haml' do
element :create_group_button, "submit _('Create group')" # rubocop:disable QA/ElementWithPattern
element :visibility_radios, 'visibility_level:' # rubocop:disable QA/ElementWithPattern
end
diff --git a/qa/qa/page/issuable/new.rb b/qa/qa/page/issuable/new.rb
new file mode 100644
index 00000000000..7891074092e
--- /dev/null
+++ b/qa/qa/page/issuable/new.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Issuable
+ class New < Page::Base
+ view 'app/views/shared/issuable/form/_title.html.haml' do
+ element :issuable_form_title
+ end
+
+ view 'app/views/shared/issuable/form/_metadata.html.haml' do
+ element :issuable_milestone_dropdown
+ end
+
+ view 'app/views/shared/form_elements/_description.html.haml' do
+ element :issuable_form_description
+ end
+
+ view 'app/views/shared/issuable/_milestone_dropdown.html.haml' do
+ element :issuable_dropdown_menu_milestone
+ end
+
+ view 'app/views/shared/issuable/_label_dropdown.html.haml' do
+ element :issuable_label
+ end
+
+ view 'app/views/shared/issuable/form/_metadata_issuable_assignee.html.haml' do
+ element :assign_to_me_link
+ end
+
+ def fill_title(title)
+ fill_element :issuable_form_title, title
+ end
+
+ def fill_description(description)
+ fill_element :issuable_form_description, description
+ end
+
+ def choose_milestone(milestone)
+ click_element :issuable_milestone_dropdown
+ within_element(:issuable_dropdown_menu_milestone) do
+ click_on milestone.title
+ end
+ end
+
+ def select_label(label)
+ click_element :issuable_label
+
+ click_link label.title
+ end
+
+ def assign_to_me
+ click_element :assign_to_me_link
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/merge_request/new.rb b/qa/qa/page/merge_request/new.rb
index f877ba76b38..eda7da89a35 100644
--- a/qa/qa/page/merge_request/new.rb
+++ b/qa/qa/page/merge_request/new.rb
@@ -3,62 +3,13 @@
module QA
module Page
module MergeRequest
- class New < Page::Base
+ class New < Page::Issuable::New
view 'app/views/shared/issuable/_form.html.haml' do
element :issuable_create_button
end
- view 'app/views/shared/issuable/form/_title.html.haml' do
- element :issuable_form_title
- end
-
- view 'app/views/shared/issuable/form/_metadata.html.haml' do
- element :issuable_milestone_dropdown
- end
-
- view 'app/views/shared/form_elements/_description.html.haml' do
- element :issuable_form_description
- end
-
- view 'app/views/shared/issuable/_milestone_dropdown.html.haml' do
- element :issuable_dropdown_menu_milestone
- end
-
- view 'app/views/shared/issuable/_label_dropdown.html.haml' do
- element :issuable_label
- end
-
- view 'app/views/shared/issuable/form/_metadata_issuable_assignee.html.haml' do
- element :assign_to_me_link
- end
-
def create_merge_request
- click_element :issuable_create_button
- end
-
- def fill_title(title)
- fill_element :issuable_form_title, title
- end
-
- def fill_description(description)
- fill_element :issuable_form_description, description
- end
-
- def choose_milestone(milestone)
- click_element :issuable_milestone_dropdown
- within_element(:issuable_dropdown_menu_milestone) do
- click_on milestone.title
- end
- end
-
- def select_label(label)
- click_element :issuable_label
-
- click_link label.title
- end
-
- def assign_to_me
- click_element :assign_to_me_link
+ click_element :issuable_create_button, Page::MergeRequest::Show
end
end
end
diff --git a/qa/qa/page/merge_request/show.rb b/qa/qa/page/merge_request/show.rb
index 0da40b35938..07f8e568b2a 100644
--- a/qa/qa/page/merge_request/show.rb
+++ b/qa/qa/page/merge_request/show.rb
@@ -73,6 +73,70 @@ module QA
element :edit_button
end
+ view 'app/assets/javascripts/batch_comments/components/publish_button.vue' do
+ element :submit_review
+ end
+
+ view 'app/assets/javascripts/batch_comments/components/review_bar.vue' do
+ element :review_bar
+ element :discard_review
+ element :modal_delete_pending_comments
+ end
+
+ view 'app/assets/javascripts/notes/components/note_form.vue' do
+ element :unresolve_review_discussion_checkbox
+ element :resolve_review_discussion_checkbox
+ element :start_review
+ element :comment_now
+ end
+
+ view 'app/assets/javascripts/batch_comments/components/preview_dropdown.vue' do
+ element :review_preview_toggle
+ end
+
+ def start_review
+ click_element :start_review
+
+ # After clicking the button, wait for it to disappear
+ # before moving on to the next part of the test
+ has_no_element? :start_review
+ end
+
+ def comment_now
+ click_element :comment_now
+
+ # After clicking the button, wait for it to disappear
+ # before moving on to the next part of the test
+ has_no_element? :comment_now
+ end
+
+ def submit_pending_reviews
+ within_element :review_bar do
+ click_element :review_preview_toggle
+ click_element :submit_review
+
+ # After clicking the button, wait for it to disappear
+ # before moving on to the next part of the test
+ has_no_element? :submit_review
+ end
+ end
+
+ def discard_pending_reviews
+ within_element :review_bar do
+ click_element :discard_review
+ end
+ click_element :modal_delete_pending_comments
+ end
+
+ def resolve_review_discussion
+ scroll_to_element :start_review
+ check_element :resolve_review_discussion_checkbox
+ end
+
+ def unresolve_review_discussion
+ check_element :unresolve_review_discussion_checkbox
+ end
+
def add_comment_to_diff(text)
wait_until(sleep_interval: 5) do
has_text?("No newline at end of file")
@@ -154,8 +218,8 @@ module QA
end
def merge!
- click_element :merge_button if ready_to_merge?
-
+ wait_until_ready_to_merge
+ click_element(:merge_button)
finished_loading?
raise "Merge did not appear to be successful" unless merged?
@@ -165,11 +229,18 @@ module QA
has_element?(:merged_status_content, text: 'The changes were merged into', wait: 30)
end
- def ready_to_merge?
- # The merge button is disabled on load
- wait_until do
- has_element?(:merge_button)
- end
+ # Check if the MR is able to be merged
+ # Waits up 10 seconds and returns false if the MR can't be merged
+ def mergeable?
+ # The merge button is enabled via JS, but `has_element?` calls
+ # `wait_for_requests`, which should ensure the disabled/enabled
+ # state of the element is reliable
+ has_element?(:merge_button, disabled: false)
+ end
+
+ # Waits up 60 seconds and raises an error if unable to merge
+ def wait_until_ready_to_merge
+ has_element?(:merge_button)
# The merge button is enabled via JS
wait_until(reload: false) do
@@ -198,7 +269,9 @@ module QA
end
def try_to_merge!
- click_element :merge_button if ready_to_merge?
+ wait_until_ready_to_merge
+
+ click_element(:merge_button)
end
def view_email_patches
diff --git a/qa/qa/page/project/fork/new.rb b/qa/qa/page/project/fork/new.rb
index 1a52c61551d..49c2205fd08 100644
--- a/qa/qa/page/project/fork/new.rb
+++ b/qa/qa/page/project/fork/new.rb
@@ -6,11 +6,11 @@ module QA
module Fork
class New < Page::Base
view 'app/views/projects/forks/_fork_button.html.haml' do
- element :namespace, 'link_to project_forks_path' # rubocop:disable QA/ElementWithPattern
+ element :fork_namespace_content
end
def choose_namespace(namespace = Runtime::Namespace.path)
- click_on namespace
+ click_element(:fork_namespace_content, name: namespace)
end
end
end
diff --git a/qa/qa/page/project/issue/new.rb b/qa/qa/page/project/issue/new.rb
index 65c02801d67..c90a09dce2e 100644
--- a/qa/qa/page/project/issue/new.rb
+++ b/qa/qa/page/project/issue/new.rb
@@ -4,27 +4,11 @@ module QA
module Page
module Project
module Issue
- class New < Page::Base
+ class New < Page::Issuable::New
view 'app/views/shared/issuable/_form.html.haml' do
element :issuable_create_button
end
- view 'app/views/shared/issuable/form/_title.html.haml' do
- element :issue_title_textbox, 'form.text_field :title' # rubocop:disable QA/ElementWithPattern
- end
-
- view 'app/views/shared/form_elements/_description.html.haml' do
- element :issue_description_textarea, "render 'projects/zen', f: form, attr: :description" # rubocop:disable QA/ElementWithPattern
- end
-
- def add_title(title)
- fill_in 'issue_title', with: title
- end
-
- def add_description(description)
- fill_in 'issue_description', with: description
- end
-
def create_new_issue
click_element :issuable_create_button, Page::Project::Issue::Show
end
diff --git a/qa/qa/page/project/members.rb b/qa/qa/page/project/members.rb
new file mode 100644
index 00000000000..88b05ceb1d1
--- /dev/null
+++ b/qa/qa/page/project/members.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Project
+ class Members < Page::Base
+ include QA::Page::Component::Select2
+
+ view 'app/views/shared/members/_invite_member.html.haml' do
+ element :member_select_field
+ element :invite_member_button
+ end
+
+ view 'app/views/projects/project_members/_team.html.haml' do
+ element :members_list
+ end
+
+ view 'app/views/projects/project_members/index.html.haml' do
+ element :invite_group_tab
+ end
+
+ view 'app/views/shared/members/_invite_group.html.haml' do
+ element :group_select_field
+ element :invite_group_button
+ end
+
+ view 'app/views/shared/members/_group.html.haml' do
+ element :group_row
+ element :delete_group_access_link
+ end
+
+ def select_group(group_name)
+ click_element :group_select_field
+ search_and_select(group_name)
+ end
+
+ def invite_group(group_name)
+ click_element :invite_group_tab
+ select_group(group_name)
+ click_element :invite_group_button
+ end
+
+ def add_member(username)
+ click_element :member_select_field
+ search_and_select username
+ click_element :invite_member_button
+ end
+
+ def remove_group(group_name)
+ click_element :invite_group_tab
+ page.accept_alert do
+ within_element(:group_row, text: group_name) do
+ click_element :delete_group_access_link
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/project/menu.rb b/qa/qa/page/project/menu.rb
index 5967213a52b..3d4d0ff9d22 100644
--- a/qa/qa/page/project/menu.rb
+++ b/qa/qa/page/project/menu.rb
@@ -16,6 +16,8 @@ module QA
element :activity_link
element :merge_requests_link
element :wiki_link
+ element :snippets_link
+ element :members_link
end
def click_merge_requests
@@ -35,6 +37,18 @@ module QA
click_element(:activity_link)
end
end
+
+ def click_snippets
+ within_sidebar do
+ click_element(:snippets_link)
+ end
+ end
+
+ def click_members
+ within_sidebar do
+ click_element(:members_link)
+ end
+ end
end
end
end
diff --git a/qa/qa/page/project/new_experiment.rb b/qa/qa/page/project/new_experiment.rb
new file mode 100644
index 00000000000..813f7f6cefe
--- /dev/null
+++ b/qa/qa/page/project/new_experiment.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Project
+ class NewExperiment < Page::Base
+ view 'app/assets/javascripts/projects/experiment_new_project_creation/components/welcome.vue' do
+ element :blank_project_link, ':data-qa-selector="`${panel.name}_link`"' # rubocop:disable QA/ElementWithPattern
+ element :create_from_template_link, ':data-qa-selector="`${panel.name}_link`"' # rubocop:disable QA/ElementWithPattern
+ end
+
+ def shown?
+ has_element? :blank_project_link
+ end
+
+ def click_blank_project_link
+ click_element :blank_project_link
+ end
+
+ def click_create_from_template_link
+ click_element :create_from_template_link
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/project/operations/metrics/show.rb b/qa/qa/page/project/operations/metrics/show.rb
index 2228cca1d3d..a1c15e72f44 100644
--- a/qa/qa/page/project/operations/metrics/show.rb
+++ b/qa/qa/page/project/operations/metrics/show.rb
@@ -11,6 +11,9 @@ module QA
view 'app/assets/javascripts/monitoring/components/dashboard.vue' do
element :prometheus_graphs
+ end
+
+ view 'app/assets/javascripts/monitoring/components/dashboard_header.vue' do
element :dashboards_filter_dropdown
element :environments_dropdown
element :edit_dashboard_button
diff --git a/qa/qa/page/project/settings/advanced.rb b/qa/qa/page/project/settings/advanced.rb
index 3bb5181a31c..d6e004e827e 100644
--- a/qa/qa/page/project/settings/advanced.rb
+++ b/qa/qa/page/project/settings/advanced.rb
@@ -43,7 +43,9 @@ module QA
def transfer_project!(project_name, namespace)
expand_select_list
- select_transfer_option(namespace)
+ # Workaround for a failure to search when there are no spaces around the /
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/218965
+ select_transfer_option(namespace.gsub(/([^\s])\/([^\s])/, '\1 / \2'))
click_element(:transfer_button)
fill_confirmation_text(project_name)
click_confirm_button
diff --git a/qa/qa/page/project/settings/ci_cd.rb b/qa/qa/page/project/settings/ci_cd.rb
index aa27c030b78..a7a0f6f57b6 100644
--- a/qa/qa/page/project/settings/ci_cd.rb
+++ b/qa/qa/page/project/settings/ci_cd.rb
@@ -42,5 +42,3 @@ module QA
end
end
end
-
-QA::Page::Project::Settings::CICD.prepend_if_ee('QA::EE::Page::Project::Settings::CICD')
diff --git a/qa/qa/page/project/settings/integrations.rb b/qa/qa/page/project/settings/integrations.rb
index 436a42fb093..e18ff71bcb3 100644
--- a/qa/qa/page/project/settings/integrations.rb
+++ b/qa/qa/page/project/settings/integrations.rb
@@ -7,13 +7,20 @@ module QA
class Integrations < QA::Page::Base
view 'app/views/shared/integrations/_index.html.haml' do
element :prometheus_link, '{ data: { qa_selector: "#{integration.to_param' # rubocop:disable QA/ElementWithPattern
+ element :jira_link, '{ data: { qa_selector: "#{integration.to_param' # rubocop:disable QA/ElementWithPattern
end
def click_on_prometheus_integration
click_element :prometheus_link
end
+
+ def click_jira_link
+ click_element :jira_link
+ end
end
end
end
end
end
+
+QA::Page::Project::Settings::Integrations.prepend_if_ee('QA::EE::Page::Project::Settings::Integrations')
diff --git a/qa/qa/page/project/settings/main.rb b/qa/qa/page/project/settings/main.rb
index efae497b6ba..880711770c0 100644
--- a/qa/qa/page/project/settings/main.rb
+++ b/qa/qa/page/project/settings/main.rb
@@ -58,3 +58,5 @@ module QA
end
end
end
+
+QA::Page::Project::Settings::Main.prepend_if_ee("QA::EE::Page::Project::Settings::Main")
diff --git a/qa/qa/page/project/settings/members.rb b/qa/qa/page/project/settings/members.rb
deleted file mode 100644
index 5dc873750b0..00000000000
--- a/qa/qa/page/project/settings/members.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- module Page
- module Project
- module Settings
- class Members < Page::Base
- include QA::Page::Component::Select2
-
- view 'app/views/shared/members/_invite_member.html.haml' do
- element :member_select_field
- element :invite_member_button
- end
-
- view 'app/views/projects/project_members/_team.html.haml' do
- element :members_list
- end
-
- view 'app/views/projects/project_members/index.html.haml' do
- element :invite_group_tab
- end
-
- view 'app/views/shared/members/_invite_group.html.haml' do
- element :group_select_field
- element :invite_group_button
- end
-
- view 'app/views/shared/members/_group.html.haml' do
- element :group_row
- element :delete_group_access_link
- end
-
- def select_group(group_name)
- click_element :group_select_field
- search_and_select(group_name)
- end
-
- def invite_group(group_name)
- click_element :invite_group_tab
- select_group(group_name)
- click_element :invite_group_button
- end
-
- def add_member(username)
- click_element :member_select_field
- search_and_select username
- click_element :invite_member_button
- end
-
- def remove_group(group_name)
- click_element :invite_group_tab
- page.accept_alert do
- within_element(:group_row, text: group_name) do
- click_element :delete_group_access_link
- end
- end
- end
- end
- end
- end
- end
-end
diff --git a/qa/qa/page/project/settings/services/jira.rb b/qa/qa/page/project/settings/services/jira.rb
new file mode 100644
index 00000000000..9f9331bac94
--- /dev/null
+++ b/qa/qa/page/project/settings/services/jira.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Project
+ module Settings
+ module Services
+ class Jira < QA::Page::Base
+ view 'app/views/shared/_field.html.haml' do
+ element :url_field, 'data: { qa_selector: "#{name.downcase.gsub' # rubocop:disable QA/ElementWithPattern
+ element :username_field, 'data: { qa_selector: "#{name.downcase.gsub' # rubocop:disable QA/ElementWithPattern
+ element :password_field, 'data: { qa_selector: "#{name.downcase.gsub' # rubocop:disable QA/ElementWithPattern
+ element :jira_issue_transition_id_field, 'data: { qa_selector: "#{name.downcase.gsub' # rubocop:disable QA/ElementWithPattern
+ end
+
+ view 'app/helpers/services_helper.rb' do
+ element :save_changes_button
+ end
+
+ def setup_service_with(url:)
+ QA::Runtime::Logger.info "Setting up JIRA"
+
+ set_jira_server_url(url)
+ set_username(Runtime::Env.jira_admin_username)
+ set_password(Runtime::Env.jira_admin_password)
+ set_transaction_ids('11,21,31,41')
+
+ click_save_changes_button
+ wait_until(reload: false) do
+ has_element?(:save_changes_button, wait: 1) ? !find_element(:save_changes_button).disabled? : true
+ end
+ end
+
+ private
+
+ def set_jira_server_url(url)
+ fill_element(:url_field, url)
+ end
+
+ def set_username(username)
+ fill_element(:username_field, username)
+ end
+
+ def set_password(password)
+ fill_element(:password_field, password)
+ end
+
+ def set_transaction_ids(transaction_ids)
+ fill_element(:jira_issue_transition_id_field, transaction_ids)
+ end
+
+ def click_save_changes_button
+ click_element :save_changes_button
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/project/snippet/new.rb b/qa/qa/page/project/snippet/new.rb
new file mode 100644
index 00000000000..1463dfc2c7f
--- /dev/null
+++ b/qa/qa/page/project/snippet/new.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Project
+ module Snippet
+ class New < Page::Dashboard::Snippet::New
+ include Component::LazyLoader
+ view 'app/views/shared/empty_states/_snippets.html.haml' do
+ element :create_first_snippet_link
+ element :svg_content
+ end
+
+ def click_create_first_snippet
+ finished_loading?
+ # The svg takes a fraction of a second to load after which the
+ # "New snippet" button shifts up a bit. This can cause
+ # webdriver to miss the hit so we wait for the svg to load before
+ # clicking the button.
+ within_element(:svg_content) do
+ has_element?(:js_lazy_loaded)
+ end
+ click_element(:create_first_snippet_link)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/project/sub_menus/settings.rb b/qa/qa/page/project/sub_menus/settings.rb
index 0dd4bd1817a..47274c8db54 100644
--- a/qa/qa/page/project/sub_menus/settings.rb
+++ b/qa/qa/page/project/sub_menus/settings.rb
@@ -15,7 +15,6 @@ module QA
view 'app/views/layouts/nav/sidebar/_project.html.haml' do
element :settings_item
- element :link_members_settings
element :general_settings_link
element :integrations_settings_link
element :operations_settings_link
@@ -31,14 +30,6 @@ module QA
end
end
- def go_to_members_settings
- hover_settings do
- within_submenu do
- click_element :link_members_settings
- end
- end
- end
-
def go_to_repository_settings
hover_settings do
within_submenu do
diff --git a/qa/qa/page/project/web_ide/edit.rb b/qa/qa/page/project/web_ide/edit.rb
index 7809f9246ec..29f431d81df 100644
--- a/qa/qa/page/project/web_ide/edit.rb
+++ b/qa/qa/page/project/web_ide/edit.rb
@@ -20,12 +20,6 @@ module QA
element :file_list
end
- view 'app/assets/javascripts/ide/components/new_dropdown/modal.vue' do
- element :full_file_path
- element :new_file_modal
- element :template_list
- end
-
view 'app/assets/javascripts/ide/components/file_templates/bar.vue' do
element :file_templates_bar
element :file_template_dropdown
@@ -52,6 +46,10 @@ module QA
element :editor_container
end
+ view 'app/assets/javascripts/ide/components/ide.vue' do
+ element :first_file_button
+ end
+
def has_file?(file_name)
within_element(:file_list) do
page.has_content? file_name
@@ -59,10 +57,7 @@ module QA
end
def create_new_file_from_template(file_name, template)
- click_element :new_file
-
- # Wait for the modal animation to complete before clicking on the file name
- wait_for_animated_element(:new_file_modal)
+ click_element(:new_file, Page::Component::WebIDE::Modal::CreateNewFile)
within_element(:template_list) do
click_on file_name
@@ -130,6 +125,13 @@ module QA
find('.modified textarea.inputarea')
end
end
+
+ def create_first_file(file_name)
+ finished_loading?
+ click_element(:first_file_button, Page::Component::WebIDE::Modal::CreateNewFile)
+ fill_element(:file_name_field, file_name)
+ click_button('Create file')
+ end
end
end
end
diff --git a/qa/qa/page/project/wiki/edit.rb b/qa/qa/page/project/wiki/edit.rb
index f6edc28c41a..96301e33733 100644
--- a/qa/qa/page/project/wiki/edit.rb
+++ b/qa/qa/page/project/wiki/edit.rb
@@ -5,14 +5,32 @@ module QA
module Project
module Wiki
class Edit < Page::Base
- view 'app/views/projects/wikis/_main_links.html.haml' do
- element :new_page_link, 'New page' # rubocop:disable QA/ElementWithPattern
- element :page_history_link, 'Page history' # rubocop:disable QA/ElementWithPattern
- element :edit_page_link, 'Edit' # rubocop:disable QA/ElementWithPattern
+ view 'app/views/shared/wikis/_form.html.haml' do
+ element :wiki_title_textbox
+ element :wiki_content_textarea
+ element :wiki_message_textbox
+ element :save_changes_button
+ element :create_page_button
end
- def click_edit
- click_on 'Edit'
+ def set_title(title)
+ fill_element :wiki_title_textbox, title
+ end
+
+ def set_content(content)
+ fill_element :wiki_content_textarea, content
+ end
+
+ def set_message(message)
+ fill_element :wiki_message_textbox, message
+ end
+
+ def click_save_changes
+ click_element :save_changes_button
+ end
+
+ def click_create_page
+ click_element :create_page_button
end
end
end
diff --git a/qa/qa/page/project/wiki/new.rb b/qa/qa/page/project/wiki/new.rb
deleted file mode 100644
index 792eba4bab7..00000000000
--- a/qa/qa/page/project/wiki/new.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- module Page
- module Project
- module Wiki
- class New < Page::Base
- include Component::LazyLoader
-
- view 'app/views/projects/wikis/_form.html.haml' do
- element :wiki_title_textbox
- element :wiki_content_textarea
- element :wiki_message_textbox
- element :save_changes_button
- element :create_page_button
- end
-
- view 'app/views/shared/empty_states/_wikis.html.haml' do
- element :create_first_page_link
- end
-
- view 'app/views/shared/empty_states/_wikis_layout.html.haml' do
- element :svg_content
- end
-
- def click_create_your_first_page_button
- # The svg takes a fraction of a second to load after which the
- # "Create your first page" button shifts up a bit. This can cause
- # webdriver to miss the hit so we wait for the svg to load before
- # clicking the button.
- within_element(:svg_content) do
- has_element? :js_lazy_loaded
- end
-
- click_element :create_first_page_link
- end
-
- def set_title(title)
- fill_element :wiki_title_textbox, title
- end
-
- def set_content(content)
- fill_element :wiki_content_textarea, content
- end
-
- def set_message(message)
- fill_element :wiki_message_textbox, message
- end
-
- def save_changes
- click_element :save_changes_button
- end
-
- def create_new_page
- click_element :create_page_button
- end
- end
- end
- end
- end
-end
diff --git a/qa/qa/page/project/wiki/show.rb b/qa/qa/page/project/wiki/show.rb
index 44619d177b1..7e4e714f4a6 100644
--- a/qa/qa/page/project/wiki/show.rb
+++ b/qa/qa/page/project/wiki/show.rb
@@ -5,23 +5,70 @@ module QA
module Project
module Wiki
class Show < Page::Base
- include Page::Component::LegacyClonePanel
+ include Component::LazyLoader
- view 'app/views/projects/wikis/pages.html.haml' do
- element :clone_repository_link, 'Clone repository' # rubocop:disable QA/ElementWithPattern
+ view 'app/views/shared/wikis/_sidebar.html.haml' do
+ element :clone_repository_link
end
- view 'app/views/projects/wikis/show.html.haml' do
+ view 'app/views/shared/wikis/show.html.haml' do
+ element :wiki_page_title
element :wiki_page_content
end
+ view 'app/views/shared/wikis/_main_links.html.haml' do
+ element :new_page_button
+ element :page_history_button
+ element :edit_page_button
+ end
+
+ view 'app/views/shared/empty_states/_wikis.html.haml' do
+ element :create_first_page_link
+ end
+
+ view 'app/views/shared/empty_states/_wikis_layout.html.haml' do
+ element :svg_content
+ end
+
+ def click_create_your_first_page
+ # The svg takes a fraction of a second to load after which the
+ # "Create your first page" button shifts up a bit. This can cause
+ # webdriver to miss the hit so we wait for the svg to load before
+ # clicking the button.
+ within_element(:svg_content) do
+ has_element? :js_lazy_loaded
+ end
+
+ click_element :create_first_page_link
+ end
+
+ def click_new_page
+ click_element(:new_page_button)
+ end
+
+ def click_page_history
+ click_element(:page_history_button)
+ end
+
+ def click_edit
+ click_element(:edit_page_button)
+ end
+
def click_clone_repository
- click_on 'Clone repository'
+ click_element(:clone_repository_link)
end
def wiki_text
find_element(:wiki_page_content).text
end
+
+ def has_title?(title)
+ has_element?(:wiki_page_title, title)
+ end
+
+ def has_content?(content)
+ has_element?(:wiki_page_content, content)
+ end
end
end
end
diff --git a/qa/qa/resource/group.rb b/qa/qa/resource/group.rb
index a30bb8cbc77..850d6205305 100644
--- a/qa/qa/resource/group.rb
+++ b/qa/qa/resource/group.rb
@@ -14,6 +14,7 @@ module QA
end
end
+ attribute :full_path
attribute :id
attribute :name
attribute :runners_token
@@ -74,10 +75,6 @@ module QA
def api_delete_path
"/groups/#{id}"
end
-
- def full_path
- sandbox.path + ' / ' + path
- end
end
end
end
diff --git a/qa/qa/resource/issue.rb b/qa/qa/resource/issue.rb
index 0817a9de06f..b4295a35263 100644
--- a/qa/qa/resource/issue.rb
+++ b/qa/qa/resource/issue.rb
@@ -32,8 +32,8 @@ module QA
Page::Project::Show.perform(&:go_to_new_issue)
Page::Project::Issue::New.perform do |new_page|
- new_page.add_title(@title)
- new_page.add_description(@description)
+ new_page.fill_title(@title)
+ new_page.fill_description(@description)
new_page.create_new_issue
end
end
diff --git a/qa/qa/resource/project.rb b/qa/qa/resource/project.rb
index 78e2ba8a248..645f4e97ee0 100644
--- a/qa/qa/resource/project.rb
+++ b/qa/qa/resource/project.rb
@@ -30,6 +30,8 @@ module QA
"#{sandbox_path}#{group.path}/#{name}" if group
end
+ alias_method :full_path, :path_with_namespace
+
def sandbox_path
group.respond_to?('sandbox') ? "#{group.sandbox.path}/" : ''
end
@@ -54,6 +56,8 @@ module QA
@auto_devops_enabled = false
@visibility = :public
@template_name = nil
+
+ self.name = "the_awesome_project"
end
def name=(raw_name)
@@ -67,12 +71,14 @@ module QA
end
if @template_name
+ QA::Flow::Project.go_to_create_project_from_template
Page::Project::New.perform do |new_page|
- new_page.click_create_from_template_tab
new_page.use_template_for_project(@template_name)
end
end
+ Page::Project::NewExperiment.perform(&:click_blank_project_link) if Page::Project::NewExperiment.perform(&:shown?)
+
Page::Project::New.perform do |new_page|
new_page.choose_test_namespace
new_page.choose_name(@name)
@@ -89,6 +95,10 @@ module QA
super
end
+ def has_file?(file_path)
+ repository_tree.any? { |file| file[:path] == file_path }
+ end
+
def api_get_path
"/projects/#{CGI.escape(path_with_namespace)}"
end
@@ -109,6 +119,14 @@ module QA
"#{api_get_path}/runners"
end
+ def api_repository_branches_path
+ "#{api_get_path}/repository/branches"
+ end
+
+ def api_repository_tree_path
+ "#{api_get_path}/repository/tree"
+ end
+
def api_pipelines_path
"#{api_get_path}/pipelines"
end
@@ -149,11 +167,9 @@ module QA
raise ResourceUpdateFailedError, "Could not change repository storage to #{new_storage}. Request returned (#{response.code}): `#{response}`."
end
- wait_until do
- reload!
-
- api_response[:repository_storage] == new_storage
- end
+ wait_until(sleep_interval: 1) { Runtime::API::RepositoryStorageMoves.has_status?(self, 'finished', new_storage) }
+ rescue Support::Repeater::RepeaterConditionExceededError
+ raise Runtime::API::RepositoryStorageMoves::RepositoryStorageMovesError, 'Timed out while waiting for the repository storage move to finish'
end
def import_status
@@ -180,6 +196,14 @@ module QA
parse_body(response)
end
+ def repository_branches
+ parse_body(get(Runtime::API::Request.new(api_client, api_repository_branches_path).url))
+ end
+
+ def repository_tree
+ parse_body(get(Runtime::API::Request.new(api_client, api_repository_tree_path).url))
+ end
+
def pipelines
parse_body(get(Runtime::API::Request.new(api_client, api_pipelines_path).url))
end
diff --git a/qa/qa/resource/project_milestone.rb b/qa/qa/resource/project_milestone.rb
index 4d6b37937b4..385b9f0c96b 100644
--- a/qa/qa/resource/project_milestone.rb
+++ b/qa/qa/resource/project_milestone.rb
@@ -3,6 +3,8 @@
module QA
module Resource
class ProjectMilestone < Base
+ attr_writer :start_date, :due_date
+
attribute :id
attribute :title
@@ -27,7 +29,10 @@ module QA
def api_post_body
{
title: title
- }
+ }.tap do |hash|
+ hash[:start_date] = @start_date if @start_date
+ hash[:due_date] = @due_date if @due_date
+ end
end
end
end
diff --git a/qa/qa/resource/project_snippet.rb b/qa/qa/resource/project_snippet.rb
new file mode 100644
index 00000000000..ce4be6445f1
--- /dev/null
+++ b/qa/qa/resource/project_snippet.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module QA
+ module Resource
+ class ProjectSnippet < Snippet
+ attribute :project do
+ Project.fabricate_via_api! do |resource|
+ resource.name = 'project-with-snippets'
+ end
+ end
+
+ def fabricate!
+ project.visit!
+
+ Page::Project::Menu.perform { |sidebar| sidebar.click_snippets }
+
+ Page::Project::Snippet::New.perform do |new_snippet|
+ new_snippet.click_create_first_snippet
+ new_snippet.fill_title(@title)
+ new_snippet.fill_description(@description)
+ new_snippet.set_visibility(@visibility)
+ new_snippet.fill_file_name(@file_name)
+ new_snippet.fill_file_content(@file_content)
+ new_snippet.click_create_snippet_button
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/resource/protected_branch.rb b/qa/qa/resource/protected_branch.rb
index 9c65e0e5a31..9b728fc4c24 100644
--- a/qa/qa/resource/protected_branch.rb
+++ b/qa/qa/resource/protected_branch.rb
@@ -5,7 +5,12 @@ require 'securerandom'
module QA
module Resource
class ProtectedBranch < Base
- attr_accessor :branch_name, :allowed_to_push, :allowed_to_merge, :protected
+ attr_accessor :branch_name,
+ :allowed_to_push,
+ :allowed_to_merge,
+ :protected,
+ :new_branch,
+ :require_code_owner_approval
attribute :project do
Project.fabricate_via_api! do |resource|
@@ -21,11 +26,12 @@ module QA
project_push.commit_message = 'Add new file'
project_push.branch_name = branch_name
project_push.new_branch = true
- project_push.remote_branch = @branch_name
+ project_push.remote_branch = branch_name
end
end
def initialize
+ @new_branch = true
@branch_name = 'test/branch'
@allowed_to_push = {
roles: Resource::ProtectedBranch::Roles::DEVS_AND_MAINTAINERS
@@ -34,22 +40,29 @@ module QA
roles: Resource::ProtectedBranch::Roles::DEVS_AND_MAINTAINERS
}
@protected = false
+ @require_code_owner_approval = true
end
def fabricate!
- populate(:branch)
+ if new_branch
+ populate(:branch)
- project.wait_for_push_new_branch @branch_name
+ project.wait_for_push_new_branch branch_name
+ end
project.visit!
Page::Project::Menu.perform(&:go_to_repository_settings)
Page::Project::Settings::Repository.perform do |setting|
setting.expand_protected_branches do |page|
- page.select_branch(branch_name)
- page.select_allowed_to_merge(allowed_to_merge)
- page.select_allowed_to_push(allowed_to_push)
- page.protect_branch
+ if new_branch
+ page.select_branch(branch_name)
+ page.select_allowed_to_merge(allowed_to_merge)
+ page.select_allowed_to_push(allowed_to_push)
+ page.protect_branch
+ else
+ page.require_code_owner_approval(branch_name) if require_code_owner_approval
+ end
end
end
end
@@ -59,11 +72,11 @@ module QA
end
def api_get_path
- "/projects/#{@project.api_resource[:id]}/protected_branches/#{@branch_name}"
+ "/projects/#{project.id}/protected_branches/#{branch_name}"
end
def api_delete_path
- "/projects/#{@project.api_resource[:id]}/protected_branches/#{@branch_name}"
+ "/projects/#{project.id}/protected_branches/#{branch_name}"
end
class Roles
diff --git a/qa/qa/resource/repository/project_push.rb b/qa/qa/resource/repository/project_push.rb
index 17596601cf9..c46921ad0c7 100644
--- a/qa/qa/resource/repository/project_push.rb
+++ b/qa/qa/resource/repository/project_push.rb
@@ -9,8 +9,11 @@ module QA
attr_accessor :project_name
attr_writer :wait_for_push
+ attribute :group
+
attribute :project do
Project.fabricate! do |resource|
+ resource.group = group if @group
resource.name = project_name
resource.description = 'Project with repository'
end
@@ -24,6 +27,7 @@ module QA
@new_branch = true
@project_name = 'project-with-code'
@wait_for_push = true
+ @group = nil
end
def repository_http_uri
diff --git a/qa/qa/resource/repository/push.rb b/qa/qa/resource/repository/push.rb
index 902ae9f3135..1e5399fcc59 100644
--- a/qa/qa/resource/repository/push.rb
+++ b/qa/qa/resource/repository/push.rb
@@ -60,13 +60,13 @@ module QA
repository.use_lfs = use_lfs
- username = 'GitLab QA'
+ name = 'GitLab QA'
email = 'root@gitlab.com'
if user
repository.username = user.username
repository.password = user.password
- username = user.name
+ name = user.name
email = user.email
end
@@ -75,7 +75,7 @@ module QA
end
@output += repository.clone
- repository.configure_identity(username, email)
+ repository.configure_identity(name, email)
@output += repository.checkout(branch_name, new_branch: new_branch)
diff --git a/qa/qa/resource/repository/wiki_push.rb b/qa/qa/resource/repository/wiki_push.rb
index e926c00d380..edf76c7cd78 100644
--- a/qa/qa/resource/repository/wiki_push.rb
+++ b/qa/qa/resource/repository/wiki_push.rb
@@ -5,17 +5,17 @@ module QA
module Repository
class WikiPush < Repository::Push
attribute :wiki do
- Wiki.fabricate! do |resource|
+ # We are using the project based wiki as a standard.
+ Wiki::ProjectPage.fabricate_via_api! do |resource|
resource.title = 'Home'
resource.content = '# My First Wiki Content'
- resource.message = 'Update home'
end
end
def initialize
@file_name = 'Home.md'
- @file_content = '# Welcome to My Wiki'
- @commit_message = 'Updating Home Page'
+ @file_content = 'This line was created using git push'
+ @commit_message = 'Updating using git push'
@branch_name = 'master'
@new_branch = false
end
@@ -28,9 +28,12 @@ module QA
@repository_ssh_uri ||= wiki.repository_ssh_location.uri
end
- def fabricate!
- super
- wiki.visit!
+ def web_url
+ # TODO
+ # workaround
+ # i.e. This replaces the last occurence of the string (case sensitive)
+ # and attaches everything before to the new substring
+ repository_http_uri.to_s.gsub(/(.*)\b\.wiki\.git\b/i, "\\1/-/wikis/#{@file_name.gsub('.md', '')}")
end
end
end
diff --git a/qa/qa/resource/sandbox.rb b/qa/qa/resource/sandbox.rb
index 7b427af6b74..032ff65c58b 100644
--- a/qa/qa/resource/sandbox.rb
+++ b/qa/qa/resource/sandbox.rb
@@ -13,6 +13,7 @@ module QA
attribute :id
attribute :runners_token
+ attribute :name
def initialize
@path = Runtime::Namespace.sandbox_name
diff --git a/qa/qa/resource/ssh_key.rb b/qa/qa/resource/ssh_key.rb
index b948bf3969b..317d70ef2c3 100644
--- a/qa/qa/resource/ssh_key.rb
+++ b/qa/qa/resource/ssh_key.rb
@@ -6,6 +6,7 @@ module QA
extend Forwardable
attr_reader :title
+ attr_accessor :expires_at
attribute :id
@@ -53,13 +54,27 @@ module QA
def api_post_body
{
title: title,
- key: public_key
+ key: public_key,
+ expires_at: expires_at
}
end
def api_delete_path
"/user/keys/#{id}"
end
+
+ def replicated?
+ api_client = Runtime::API::Client.new(:geo_secondary)
+
+ QA::Runtime::Logger.debug('Checking for SSH key replication')
+
+ 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 &&
+ parse_body(response)[:title].include?(title)
+ end
+ end
end
end
end
diff --git a/qa/qa/resource/wiki.rb b/qa/qa/resource/wiki.rb
deleted file mode 100644
index 45d5da9346d..00000000000
--- a/qa/qa/resource/wiki.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- module Resource
- class Wiki < Base
- attr_accessor :title, :content, :message
-
- attribute :project do
- Project.fabricate! do |resource|
- resource.name = 'project-for-wikis'
- resource.description = 'project for adding wikis'
- end
- end
-
- attribute :repository_http_location do
- Page::Project::Wiki::Show.perform(&:click_clone_repository)
-
- Page::Project::Wiki::GitAccess.perform do |git_access|
- git_access.choose_repository_clone_http
- git_access.repository_location
- end
- end
-
- attribute :repository_ssh_location do
- Page::Project::Wiki::Show.perform(&:click_clone_repository)
-
- Page::Project::Wiki::GitAccess.perform do |git_access|
- git_access.choose_repository_clone_ssh
- git_access.repository_location
- end
- end
-
- def fabricate!
- project.visit!
-
- Page::Project::Menu.perform { |menu_side| menu_side.click_wiki }
-
- Page::Project::Wiki::New.perform do |wiki_new|
- wiki_new.click_create_your_first_page_button
- wiki_new.set_title(@title)
- wiki_new.set_content(@content)
- wiki_new.set_message(@message)
- wiki_new.create_new_page
- end
- end
- end
- end
-end
diff --git a/qa/qa/resource/wiki/project_page.rb b/qa/qa/resource/wiki/project_page.rb
new file mode 100644
index 00000000000..5d0a0a37765
--- /dev/null
+++ b/qa/qa/resource/wiki/project_page.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+module QA
+ module Resource
+ module Wiki
+ class ProjectPage < Base
+ attribute :title
+ attribute :content
+ attribute :slug
+ attribute :format
+
+ attribute :project do
+ Project.fabricate_via_api! do |project|
+ project.name = 'wiki_testing'
+ project.description = 'project for testing wikis'
+ end
+ end
+
+ attribute :repository_http_location do
+ switching_to_wiki_url project.repository_http_location.git_uri
+ end
+
+ attribute :repository_ssh_location do
+ switching_to_wiki_url project.repository_ssh_location.git_uri
+ end
+
+ def initialize
+ @title = 'Home'
+ @content = 'This wiki page is created by the API'
+ end
+
+ def resource_web_url(resource)
+ super
+ rescue ResourceURLMissingError
+ # TODO
+ # workaround
+ project.web_url.concat("/-/wikis/#{slug}")
+ end
+
+ def api_get_path
+ "/projects/#{project.id}/wikis/#{slug}"
+ end
+
+ def api_post_path
+ "/projects/#{project.id}/wikis"
+ end
+
+ def api_post_body
+ {
+ id: project.id,
+ content: content,
+ title: title
+ }
+ end
+
+ private
+
+ def switching_to_wiki_url(url)
+ # TODO
+ # workaround
+ # i.e. This replaces the last occurence of the string (case sensitive)
+ # and attaches everything before to the new substring
+ Git::Location.new(url.to_s.gsub(/(.*)\bgit\b/i, '\1wiki.git'))
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/runtime/api/repository_storage_moves.rb b/qa/qa/runtime/api/repository_storage_moves.rb
new file mode 100644
index 00000000000..c94a693289f
--- /dev/null
+++ b/qa/qa/runtime/api/repository_storage_moves.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module QA
+ module Runtime
+ module API
+ module RepositoryStorageMoves
+ extend self
+ extend Support::Api
+
+ RepositoryStorageMovesError = Class.new(RuntimeError)
+
+ def has_status?(project, status, destination_storage = Env.additional_repository_storage)
+ all.any? do |move|
+ move[:project][:path_with_namespace] == project.path_with_namespace &&
+ move[:state] == status &&
+ move[:destination_storage_name] == destination_storage
+ end
+ end
+
+ def all
+ Logger.debug('Getting repository storage moves')
+ parse_body(get(Request.new(api_client, '/project_repository_storage_moves').url))
+ end
+
+ private
+
+ def api_client
+ @api_client ||= Client.as_admin
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/runtime/env.rb b/qa/qa/runtime/env.rb
index 5c23586fb3e..677fba7ced7 100644
--- a/qa/qa/runtime/env.rb
+++ b/qa/qa/runtime/env.rb
@@ -210,6 +210,18 @@ module QA
ENV['GITLAB_QA_1P_GITHUB_UUID']
end
+ def jira_admin_username
+ ENV['JIRA_ADMIN_USERNAME']
+ end
+
+ def jira_admin_password
+ ENV['JIRA_ADMIN_PASSWORD']
+ end
+
+ def jira_hostname
+ ENV['JIRA_HOSTNAME']
+ end
+
def knapsack?
!!(ENV['KNAPSACK_GENERATE_REPORT'] || ENV['KNAPSACK_REPORT_PATH'] || ENV['KNAPSACK_TEST_FILE_PATTERN'])
end
diff --git a/qa/qa/runtime/feature.rb b/qa/qa/runtime/feature.rb
index 5e948b5b850..579c2293c51 100644
--- a/qa/qa/runtime/feature.rb
+++ b/qa/qa/runtime/feature.rb
@@ -28,19 +28,11 @@ module QA
end
def enable_and_verify(key)
- Support::Retrier.retry_on_exception(sleep_interval: 2) do
- enable(key)
-
- is_enabled = false
-
- QA::Support::Waiter.wait_until(sleep_interval: 1) do
- is_enabled = enabled?(key)
- end
-
- raise SetFeatureError, "#{key} was not enabled!" unless is_enabled
+ set_and_verify(key, enable: true)
+ end
- QA::Runtime::Logger.info("Successfully enabled and verified feature flag: #{key}")
- end
+ def disable_and_verify(key)
+ set_and_verify(key, enable: false)
end
def enabled?(key)
@@ -75,6 +67,27 @@ module QA
end
end
+ # Change a feature flag and verify that the change was successful
+ # Arguments:
+ # key: The feature flag to set (as a string)
+ # enable: `true` to enable the flag, `false` to disable it
+ def set_and_verify(key, enable:)
+ Support::Retrier.retry_on_exception(sleep_interval: 2) do
+ enable ? enable(key) : disable(key)
+
+ is_enabled = nil
+
+ QA::Support::Waiter.wait_until(sleep_interval: 1) do
+ is_enabled = enabled?(key)
+ is_enabled == enable
+ end
+
+ raise SetFeatureError, "#{key} was not #{enable ? 'enabled' : 'disabled'}!" unless is_enabled == enable
+
+ QA::Runtime::Logger.info("Successfully #{enable ? 'enabled' : 'disabled'} and verified feature flag: #{key}")
+ end
+ end
+
def set_feature(key, value)
request = Runtime::API::Request.new(api_client, "/features/#{key}")
response = post(request.url, { value: value })
diff --git a/qa/qa/scenario/test/instance/airgapped.rb b/qa/qa/scenario/test/instance/airgapped.rb
new file mode 100644
index 00000000000..556741ec040
--- /dev/null
+++ b/qa/qa/scenario/test/instance/airgapped.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module QA
+ module Scenario
+ module Test
+ module Instance
+ class Airgapped < Template
+ include Bootable
+ include SharedAttributes
+ def perform(address, *rspec_options)
+ Runtime::Scenario.define(:runner_network, 'airgapped')
+
+ super
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/service/docker_run/base.rb b/qa/qa/service/docker_run/base.rb
index b02bbea8ff5..512960e8232 100644
--- a/qa/qa/service/docker_run/base.rb
+++ b/qa/qa/service/docker_run/base.rb
@@ -8,6 +8,7 @@ module QA
def initialize
@network = Runtime::Scenario.attributes[:network] || 'test'
+ @runner_network = Runtime::Scenario.attributes[:runner_network] || @network
end
def network
@@ -18,6 +19,14 @@ module QA
@network
end
+ def runner_network
+ shell "docker network inspect #{@runner_network}"
+ rescue CommandError
+ network
+ else
+ @runner_network
+ end
+
def pull
shell "docker pull #{@image}"
end
diff --git a/qa/qa/service/docker_run/gitlab_runner.rb b/qa/qa/service/docker_run/gitlab_runner.rb
index 834f6b430ac..6022ee4ceab 100644
--- a/qa/qa/service/docker_run/gitlab_runner.rb
+++ b/qa/qa/service/docker_run/gitlab_runner.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
+require 'resolv'
require 'securerandom'
module QA
@@ -38,11 +39,16 @@ module QA
def register!
shell <<~CMD.tr("\n", ' ')
docker run -d --rm --entrypoint=/bin/sh
- --network #{network} --name #{@name}
+ --network #{runner_network} --name #{@name}
#{'-v /var/run/docker.sock:/var/run/docker.sock' if @executor == :docker}
--privileged
#{@image} -c "#{register_command}"
CMD
+
+ # Prove airgappedness
+ if runner_network == 'airgapped'
+ shell("docker exec #{@name} sh -c '#{prove_airgap}'")
+ end
end
def tags=(tags)
@@ -85,6 +91,17 @@ module QA
gitlab-runner run
CMD
end
+
+ # Ping CloudFlare DNS, should fail
+ # Ping Registry, should fail to resolve
+ def prove_airgap
+ gitlab_ip = Resolv.getaddress 'registry.gitlab.com'
+ <<~CMD
+ echo "Checking airgapped connectivity..."
+ nc -zv -w 10 #{gitlab_ip} 80 && (echo "Airgapped network faulty. Connectivity netcat check failed." && exit 1) || (echo "Connectivity netcat check passed." && exit 0)
+ wget --retry-connrefused --waitretry=1 --read-timeout=15 --timeout=10 -t 2 http://registry.gitlab.com > /dev/null 2>&1 && (echo "Airgapped network faulty. Connectivity wget check failed." && exit 1) || (echo "Airgapped network confirmed. Connectivity wget check passed." && exit 0)
+ CMD
+ end
end
end
end
diff --git a/qa/qa/service/docker_run/jenkins.rb b/qa/qa/service/docker_run/jenkins.rb
index 00b63282484..808fab80c63 100644
--- a/qa/qa/service/docker_run/jenkins.rb
+++ b/qa/qa/service/docker_run/jenkins.rb
@@ -16,7 +16,9 @@ module QA
end
def host_name
- return 'localhost' unless QA::Runtime::Env.running_in_ci?
+ if !QA::Runtime::Env.running_in_ci? && !runner_network.equal?('airgapped')
+ 'localhost'
+ end
super
end
@@ -33,7 +35,9 @@ module QA
#{@image}
CMD
- command.gsub!("--network #{network} ", '') unless QA::Runtime::Env.running_in_ci?
+ if !QA::Runtime::Env.running_in_ci? && !runner_network.equal?('airgapped')
+ command.gsub!("--network #{network} ", '')
+ end
shell command
end
diff --git a/qa/qa/specs/features/api/3_create/repository/changing_repository_storage_spec.rb b/qa/qa/specs/features/api/3_create/repository/changing_repository_storage_spec.rb
new file mode 100644
index 00000000000..d5ab6a3544d
--- /dev/null
+++ b/qa/qa/specs/features/api/3_create/repository/changing_repository_storage_spec.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+module QA
+ context 'Create' do
+ describe 'Changing Gitaly repository storage', :orchestrated, :requires_admin do
+ shared_examples 'repository storage move' do
+ it 'confirms a `finished` status after moving project repository storage' do
+ expect(project).to have_file('README.md')
+
+ project.change_repository_storage(destination_storage)
+
+ expect(Runtime::API::RepositoryStorageMoves).to have_status(project, 'finished', destination_storage)
+
+ Resource::Repository::ProjectPush.fabricate! do |push|
+ push.project = project
+ push.file_name = 'new_file'
+ push.file_content = '# This is a new file'
+ push.commit_message = 'Add new file'
+ push.new_branch = false
+ end
+
+ expect(project).to have_file('README.md')
+ expect(project).to have_file('new_file')
+ end
+ end
+
+ context 'when moving from one Gitaly storage to another', :repository_storage do
+ let(:project) do
+ Resource::Project.fabricate_via_api! do |project|
+ project.name = 'repo-storage-move-status'
+ project.initialize_with_readme = true
+ end
+ end
+ let(:destination_storage) { QA::Runtime::Env.additional_repository_storage }
+
+ it_behaves_like 'repository storage move'
+ end
+
+ context 'when moving from Gitaly to Gitaly Cluster', :requires_praefect do
+ let(:project) do
+ Resource::Project.fabricate_via_api! do |project|
+ project.name = 'repo-storage-move'
+ project.initialize_with_readme = true
+ project.repository_storage = 'gitaly'
+ end
+ end
+ let(:destination_storage) { QA::Runtime::Env.praefect_repository_storage }
+
+ it_behaves_like 'repository storage move'
+ end
+ end
+ end
+end
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 e30afbf8ae0..67055537567 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
@@ -12,8 +12,8 @@ module QA
project.name = 'add-member-project'
end.visit!
- Page::Project::Menu.perform(&:go_to_members_settings)
- Page::Project::Settings::Members.perform do |members|
+ Page::Project::Menu.perform(&:click_members)
+ Page::Project::Members.perform do |members|
members.add_member(user.username)
end
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 7b4418191a3..57b0859856e 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
@@ -3,6 +3,8 @@
module QA
context 'Plan', :smoke do
describe 'Issue creation' do
+ let(:closed_issue) { Resource::Issue.fabricate_via_api! }
+
before do
Flow::Login.sign_in
end
@@ -17,6 +19,25 @@ module QA
end
end
+ it 'closes an issue' do
+ closed_issue.visit!
+
+ Page::Project::Issue::Show.perform do |issue_page|
+ issue_page.click_close_issue_button
+
+ expect(issue_page).to have_element(:reopen_issue_button)
+ end
+
+ Page::Project::Menu.perform(&:click_issues)
+ Page::Project::Issue::Index.perform do |index|
+ expect(index).not_to have_issue(closed_issue)
+
+ index.click_closed_issues_link
+
+ expect(index).to have_issue(closed_issue)
+ end
+ end
+
context 'when using attachments in comments', :object_storage do
let(:gif_file_name) { 'banana_sample.gif' }
let(:file_to_attach) do
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 9b46a066c8e..623573a1397 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
@@ -16,10 +16,10 @@ module QA
it 'shows issue suggestions when creating a new issue' do
Page::Project::Show.perform(&:go_to_new_issue)
Page::Project::Issue::New.perform do |new_page|
- new_page.add_title("issue")
+ new_page.fill_title("issue")
expect(new_page).to have_content(issue_title)
- new_page.add_title("Issue Board")
+ new_page.fill_title("Issue Board")
expect(new_page).not_to have_content(issue_title)
end
end
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 409c7d321f0..c81a6f9281c 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
@@ -17,7 +17,7 @@ module QA
project.visit!
Page::Project::Menu.perform(&:go_to_boards)
- EE::Page::Component::IssueBoard::Show.perform do |show|
+ Page::Component::IssueBoard::Show.perform do |show|
show.click_focus_mode_button
expect(show.focused_board).to be_visible
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
new file mode 100644
index 00000000000..05a932fd53e
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/jira/jira_basic_integration_spec.rb
@@ -0,0 +1,105 @@
+# frozen_string_literal: true
+
+module QA
+ context 'Create' do
+ include Support::Api
+
+ describe 'Jira integration', :jira, :orchestrated, :requires_admin do
+ let(:jira_project_key) { 'JITP' }
+
+ before(:all) do
+ page.visit Vendor::Jira::JiraAPI.perform(&:base_url)
+
+ QA::Support::Retrier.retry_until(sleep_interval: 3, reload_page: page, max_attempts: 20, raise_on_failure: true) do
+ page.has_text? 'Welcome to Jira'
+ end
+
+ @project = Resource::Project.fabricate_via_api! do |project|
+ project.name = "project_with_jira_integration"
+ end
+
+ # Retry is required because allow_local_requests_from_web_hooks_and_services
+ # takes some time to get enabled.
+ # Bug issue: https://gitlab.com/gitlab-org/gitlab/-/issues/217010
+ QA::Support::Retrier.retry_on_exception(max_attempts: 5, sleep_interval: 3) do
+ Runtime::ApplicationSettings.set_application_settings(allow_local_requests_from_web_hooks_and_services: true)
+
+ page.visit Runtime::Scenario.gitlab_address
+ Flow::Login.sign_in_unless_signed_in
+
+ @project.visit!
+
+ Page::Project::Menu.perform(&:go_to_integrations_settings)
+ QA::Page::Project::Settings::Integrations.perform(&:click_jira_link)
+
+ QA::Page::Project::Settings::Services::Jira.perform do |jira|
+ jira.setup_service_with(url: Vendor::Jira::JiraAPI.perform(&:base_url))
+ end
+
+ expect(page).not_to have_text("Requests to the local network are not allowed")
+ end
+ end
+
+ it 'closes an issue via pushing a commit' do
+ issue_key = Vendor::Jira::JiraAPI.perform do |jira_api|
+ jira_api.create_issue(jira_project_key)
+ end
+
+ push_commit("Closes #{issue_key}")
+
+ expect_issue_done(issue_key)
+ end
+
+ it 'closes an issue via a merge request' do
+ issue_key = Vendor::Jira::JiraAPI.perform do |jira_api|
+ jira_api.create_issue(jira_project_key)
+ end
+
+ page.visit Runtime::Scenario.gitlab_address
+ Flow::Login.sign_in_unless_signed_in
+
+ merge_request = create_mr_with_description("Closes #{issue_key}")
+
+ merge_request.visit!
+
+ Page::MergeRequest::Show.perform(&:merge!)
+
+ expect_issue_done(issue_key)
+ end
+
+ def create_mr_with_description(description)
+ Resource::MergeRequest.fabricate! do |merge_request|
+ merge_request.project = @project
+ merge_request.target_new_branch = !master_branch_exists?
+ merge_request.description = description
+ end
+ end
+
+ def push_commit(commit_message)
+ Resource::Repository::ProjectPush.fabricate! do |push|
+ push.branch_name = 'master'
+ push.commit_message = commit_message
+ push.file_content = commit_message
+ push.project = @project
+ push.new_branch = !master_branch_exists?
+ end
+ end
+
+ def expect_issue_done(issue_key)
+ expect do
+ Support::Waiter.wait_until(raise_on_failure: true) do
+ jira_issue = Vendor::Jira::JiraAPI.perform do |jira_api|
+ jira_api.fetch_issue(issue_key)
+ end
+
+ jira_issue[:fields][:status][:name] == 'Done'
+ end
+ end.not_to raise_error
+ end
+
+ def master_branch_exists?
+ @project.repository_branches.map { |item| item[:name] }.include?("master")
+ end
+ end
+ end
+end
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 9b504ad76b4..21ae10774c9 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
@@ -3,6 +3,12 @@
module QA
context 'Create', :requires_admin do
describe 'push after setting the file size limit via admin/application_settings' do
+ # Note: The file size limits in this test should be greater than the limits in
+ # ee/browser_ui/3_create/repository/push_rules_spec to prevent that test from
+ # triggering the limit set in this test (which can happen on Staging where the
+ # tests are run in parallel).
+ # See: https://gitlab.com/gitlab-org/gitlab/-/issues/218620#note_361634705
+
include Support::Api
before(:context) do
@@ -31,7 +37,7 @@ module QA
end
it 'push fails when the file size is above the limit' do
- set_file_size_limit(1)
+ set_file_size_limit(2)
retry_on_fail do
expect { push_new_file('oversize_file_2.bin', wait_for_push: false) }
@@ -52,7 +58,7 @@ module QA
output = Resource::Repository::Push.fabricate! do |p|
p.repository_http_uri = @project.repository_http_location.uri
p.file_name = file_name
- p.file_content = SecureRandom.random_bytes(2000000)
+ p.file_content = SecureRandom.random_bytes(3000000)
p.commit_message = commit_message
p.new_branch = false
end
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
new file mode 100644
index 00000000000..a3011550db8
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb
@@ -0,0 +1,101 @@
+# frozen_string_literal: true
+
+module QA
+ context 'Create' do
+ describe 'Version control for project snippets' do
+ let(:new_file) { 'new_snippet_file' }
+ let(:changed_content) { 'changes' }
+ let(:commit_message) { 'Changes to snippets' }
+ let(:added_content) { 'updated ' }
+ let(:branch_name) { 'master' }
+
+ let(:snippet) do
+ Resource::ProjectSnippet.fabricate! do |snippet|
+ snippet.file_name = new_file
+ end
+ end
+
+ let(:ssh_key) do
+ Resource::SSHKey.fabricate_via_api! do |resource|
+ resource.title = "my key title #{Time.now.to_f}"
+ end
+ end
+
+ let(:repository_uri_http) do
+ snippet
+ Page::Dashboard::Snippet::Show.perform(&:get_repository_uri_http)
+ end
+
+ let(:repository_uri_ssh) do
+ ssh_key
+ snippet
+ Page::Dashboard::Snippet::Show.perform(&:get_repository_uri_ssh)
+ end
+
+ before do
+ Flow::Login.sign_in
+ end
+
+ it 'clones, pushes, and pulls a project snippet over HTTP, edits via UI' do
+ Resource::Repository::Push.fabricate! do |push|
+ push.repository_http_uri = repository_uri_http
+ push.file_name = new_file
+ push.file_content = changed_content
+ push.commit_message = commit_message
+ push.new_branch = false
+ end
+
+ page.refresh
+ verify_changes_in_ui
+
+ Page::Dashboard::Snippet::Show.perform(&:click_edit_button)
+
+ Page::Dashboard::Snippet::Edit.perform do |snippet|
+ snippet.add_to_file_content(added_content)
+ snippet.save_changes
+ end
+
+ Git::Repository.perform do |repository|
+ repository.init_repository
+ repository.pull(repository_uri_http, branch_name)
+
+ expect(repository.commits.size).to eq 3
+ expect(repository.commits.first).to include 'Update snippet'
+ expect(repository.file_content(new_file)).to include "#{added_content}#{changed_content}"
+ end
+ end
+
+ it 'clones, pushes, and pulls a project snippet over SSH, deletes via UI' do
+ Resource::Repository::Push.fabricate! do |push|
+ push.repository_ssh_uri = repository_uri_ssh
+ push.ssh_key = ssh_key
+ push.file_name = new_file
+ push.file_content = changed_content
+ push.commit_message = commit_message
+ push.new_branch = false
+ end
+
+ page.refresh
+ verify_changes_in_ui
+ Page::Dashboard::Snippet::Show.perform(&:click_delete_button)
+
+ # attempt to pull a deleted snippet, get a missing repository error
+ Git::Repository.perform do |repository|
+ repository.uri = repository_uri_ssh
+ repository.use_ssh_key(ssh_key)
+ repository.init_repository
+
+ expect { repository.pull(repository_uri_ssh, branch_name) }
+ .to raise_error(QA::Git::Repository::RepositoryCommandError, /[fatal: Could not read from remote repository.]+/)
+ end
+ end
+
+ def verify_changes_in_ui
+ Page::Dashboard::Snippet::Show.perform do |snippet|
+ expect(snippet).to have_file_name(new_file)
+ expect(snippet).to have_file_content(changed_content)
+ end
+ end
+ end
+ end
+end
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
new file mode 100644
index 00000000000..451a7847f8b
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module QA
+ context 'Create', :smoke do
+ describe 'Personal snippet creation' do
+ it 'User creates a personal snippet' do
+ Flow::Login.sign_in
+
+ Page::Main::Menu.perform(&:go_to_snippets)
+
+ Resource::Snippet.fabricate_via_browser_ui! do |snippet|
+ snippet.title = 'Snippet title'
+ snippet.description = 'Snippet description'
+ snippet.visibility = 'Private'
+ snippet.file_name = 'New snippet file name'
+ snippet.file_content = 'Snippet file text'
+ end
+
+ Page::Dashboard::Snippet::Show.perform do |snippet|
+ expect(snippet).to have_snippet_title('Snippet title')
+ expect(snippet).to have_snippet_description('Snippet description')
+ expect(snippet).to have_visibility_type(/private/i)
+ expect(snippet).to have_file_name('New snippet file name')
+ expect(snippet).to have_file_content('Snippet file text')
+ end
+ end
+ end
+ end
+end
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
new file mode 100644
index 00000000000..8fc4427bda7
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_spec.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+module QA
+ context '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' do
+ Flow::Login.sign_in
+
+ Resource::ProjectSnippet.fabricate_via_browser_ui! do |snippet|
+ snippet.title = 'Project snippet'
+ snippet.description = ' '
+ snippet.visibility = 'Private'
+ snippet.file_name = 'markdown_file.md'
+ snippet.file_content = "### Snippet heading\n\n[Gitlab link](https://gitlab.com/)"
+ end
+
+ Page::Dashboard::Snippet::Show.perform do |snippet|
+ expect(snippet).to have_snippet_title('Project snippet')
+ expect(snippet).to have_no_snippet_description
+ expect(snippet).to have_visibility_type(/private/i)
+ expect(snippet).to have_file_name('markdown_file.md')
+ expect(snippet).to have_file_content('Snippet heading')
+ expect(snippet).to have_file_content('Gitlab link')
+ expect(snippet).not_to have_file_content('###')
+ expect(snippet).not_to have_file_content('https://gitlab.com/')
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/create_snippet_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/create_snippet_spec.rb
deleted file mode 100644
index dfcbf4b44c8..00000000000
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/create_snippet_spec.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- context 'Create', :smoke do
- describe 'Snippet creation' do
- it 'User creates a snippet' do
- Flow::Login.sign_in
-
- Page::Main::Menu.perform(&:go_to_snippets)
-
- Resource::Snippet.fabricate_via_browser_ui! do |snippet|
- snippet.title = 'Snippet title'
- snippet.description = 'Snippet description'
- snippet.visibility = 'Private'
- snippet.file_name = 'New snippet file name'
- snippet.file_content = 'Snippet file text'
- end
-
- Page::Dashboard::Snippet::Show.perform do |snippet|
- expect(snippet).to have_snippet_title('Snippet title')
- expect(snippet).to have_snippet_description('Snippet description')
- expect(snippet).to have_visibility_type(/private/i)
- expect(snippet).to have_file_name('New snippet file name')
- expect(snippet).to have_file_content('Snippet file text')
- end
- end
- end
- end
-end
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
new file mode 100644
index 00000000000..3bf6e156967
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+module QA
+ context 'Create' do
+ describe 'First file using Web IDE' do
+ let(:project) do
+ Resource::Project.fabricate_via_api! do |project|
+ project.name = 'empty-project'
+ project.initialize_with_readme = false
+ end
+ end
+
+ let(:web_ide_url) { current_url + '-/ide/project/' + project.path_with_namespace }
+ let(:file_name) { 'the very first file.txt' }
+
+ before do
+ Flow::Login.sign_in
+ end
+
+ it "creates the first file in an empty project via Web IDE" do
+ # In the first iteration, the test opens Web IDE by modifying the URL to address past regressions.
+ # Once the Web IDE button is introduced for empty projects, the test will be modified to go through UI.
+ # See https://gitlab.com/gitlab-org/gitlab/-/issues/27915 and https://gitlab.com/gitlab-org/gitlab/-/issues/27535.
+ page.visit(web_ide_url)
+
+ Page::Project::WebIDE::Edit.perform do |ide|
+ ide.create_first_file(file_name)
+ ide.commit_changes
+ end
+
+ project.visit!
+
+ Page::Project::Show.perform do |project|
+ expect(project).to have_file(file_name)
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/3_create/wiki/create_edit_clone_push_wiki_spec.rb b/qa/qa/specs/features/browser_ui/3_create/wiki/create_edit_clone_push_wiki_spec.rb
deleted file mode 100644
index 185d10a64ed..00000000000
--- a/qa/qa/specs/features/browser_ui/3_create/wiki/create_edit_clone_push_wiki_spec.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- context 'Create' do
- describe 'Wiki management' do
- it 'user creates, edits, clones, and pushes to the wiki' do
- Flow::Login.sign_in
-
- wiki = Resource::Wiki.fabricate_via_browser_ui! do |resource|
- resource.title = 'Home'
- resource.content = '# My First Wiki Content'
- resource.message = 'Update home'
- end
-
- validate_content('My First Wiki Content')
-
- Page::Project::Wiki::Edit.perform(&:click_edit)
- Page::Project::Wiki::New.perform do |wiki|
- wiki.set_content("My Second Wiki Content")
- wiki.save_changes
- end
-
- validate_content('My Second Wiki Content')
-
- Resource::Repository::WikiPush.fabricate! do |push|
- push.wiki = wiki
- push.file_name = 'Home.md'
- push.file_content = '# My Third Wiki Content'
- push.commit_message = 'Update Home.md'
- end
- Page::Project::Menu.perform(&:click_wiki)
-
- expect(page).to have_content('My Third Wiki Content')
- end
-
- def validate_content(content)
- expect(page).to have_content('Wiki was successfully updated')
- expect(page).to have_content(/#{content}/)
- end
- end
- end
-end
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
new file mode 100644
index 00000000000..1d0c8ee60d4
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_content_creation_spec.rb
@@ -0,0 +1,93 @@
+# frozen_string_literal: true
+
+module QA
+ context 'Create' do
+ context 'Wiki' do
+ describe 'testing wiki content creation inside a project' do
+ let(:new_wiki_title) { "just_another_wiki_page" }
+ let(:new_wiki_content) { "this content is changed or added" }
+ let(:commit_message) { "this is a new addition to the wiki" }
+
+ let(:project) { Resource::Project.fabricate_via_api! }
+ let(:wiki) { Resource::Wiki::ProjectPage.fabricate_via_api! }
+
+ before do
+ Flow::Login.sign_in
+ end
+
+ it 'by adding a home page to the wiki' do
+ project.visit!
+
+ Page::Project::Menu.perform(&:click_wiki)
+ Page::Project::Wiki::Show.perform(&:click_create_your_first_page)
+
+ Page::Project::Wiki::Edit.perform do |edit|
+ edit.set_title new_wiki_title
+ edit.set_content new_wiki_content
+ edit.set_message commit_message
+ end
+
+ Page::Project::Wiki::Edit.perform(&:click_create_page)
+
+ Page::Project::Wiki::Show.perform do |wiki|
+ expect(wiki).to have_title new_wiki_title
+ expect(wiki).to have_content new_wiki_content
+ end
+ end
+
+ it 'by adding a second page to the wiki' do
+ wiki.visit!
+
+ Page::Project::Wiki::Show.perform(&:click_new_page)
+
+ Page::Project::Wiki::Edit.perform do |edit|
+ edit.set_title new_wiki_title
+ edit.set_content new_wiki_content
+ edit.set_message commit_message
+ end
+
+ Page::Project::Wiki::Edit.perform(&:click_create_page)
+
+ Page::Project::Wiki::Show.perform do |wiki|
+ expect(wiki).to have_title new_wiki_title
+ expect(wiki).to have_content new_wiki_content
+ end
+ end
+
+ it 'by adding a home page to the wiki using git push' do
+ empty_wiki = Resource::Wiki::ProjectPage.new do |empty_wiki|
+ empty_wiki.project = project
+ end
+
+ Resource::Repository::WikiPush.fabricate! do |push|
+ push.file_name = "#{new_wiki_title}.md"
+ push.file_content = new_wiki_content
+ push.commit_message = commit_message
+ push.wiki = empty_wiki
+ push.new_branch = true
+ end.visit!
+
+ Page::Project::Wiki::Show.perform do |wiki|
+ expect(wiki).to have_title new_wiki_title
+ expect(wiki).to have_content new_wiki_content
+ end
+ end
+
+ it 'by adding a second page to the wiki using git push' do
+ Resource::Repository::WikiPush.fabricate! do |push|
+ push.file_name = "#{new_wiki_title}.md"
+ push.file_content = new_wiki_content
+ push.commit_message = commit_message
+ push.wiki = wiki
+ push.new_branch = false
+ end.visit!
+
+ Page::Project::Wiki::Show.perform do |wiki|
+ expect(wiki).to have_title new_wiki_title
+ expect(wiki).to have_content new_wiki_content
+ end
+ end
+ end
+ end
+ end
+end
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
new file mode 100644
index 00000000000..10370c80476
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_content_manipulation_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+module QA
+ context 'Create' do
+ context 'Wiki' do
+ describe 'testing wiki content manipulation inside a project' do
+ let(:new_wiki_title) { "just_another_wiki_page" }
+ let(:new_wiki_content) { "this content is changed or added" }
+ let(:commit_message) { "this is a new addition to the wiki" }
+
+ let(:wiki) { Resource::Wiki::ProjectPage.fabricate_via_api! }
+
+ before do
+ Flow::Login.sign_in
+ end
+
+ it 'by manipulating content on the page' do
+ wiki.visit!
+
+ Page::Project::Wiki::Show.perform(&:click_edit)
+
+ Page::Project::Wiki::Edit.perform do |edit|
+ edit.set_title new_wiki_title
+ edit.set_content new_wiki_content
+ edit.set_message commit_message
+ end
+
+ Page::Project::Wiki::Edit.perform(&:click_save_changes)
+
+ Page::Project::Wiki::Show.perform do |wiki|
+ expect(wiki).to have_title new_wiki_title
+ expect(wiki).to have_content new_wiki_content
+ end
+ end
+
+ it 'by manipulating content on the page using git push' do
+ Resource::Repository::WikiPush.fabricate! do |push|
+ push.file_content = new_wiki_content
+ push.commit_message = commit_message
+ push.wiki = wiki
+ push.new_branch = false
+ end.visit!
+
+ Page::Project::Wiki::Show.perform do |wiki|
+ expect(wiki).to have_content new_wiki_content
+ end
+ end
+ end
+ end
+ end
+end
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 b1eb26f0d63..e1d8c50ab75 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
@@ -29,10 +29,12 @@ module QA
view_pipelines
Page::Project::Pipeline::Show.perform do |parent_pipeline|
- parent_pipeline.click_linked_job(project.name)
+ expect(parent_pipeline).to have_passed
+ parent_pipeline.retry_on_exception(sleep_interval: 1.0) do
+ parent_pipeline.click_linked_job(project.name)
+ end
expect(parent_pipeline).to have_job("child_job")
- expect(parent_pipeline).to have_passed
end
end
@@ -41,10 +43,12 @@ module QA
view_pipelines
Page::Project::Pipeline::Show.perform do |parent_pipeline|
- parent_pipeline.click_linked_job(project.name)
+ expect(parent_pipeline).to have_failed
+ parent_pipeline.retry_on_exception(sleep_interval: 1.0) do
+ parent_pipeline.click_linked_job(project.name)
+ end
expect(parent_pipeline).to have_job("child_job")
- expect(parent_pipeline).to have_failed
end
end
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 c9a61fc6305..c365e084991 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
@@ -29,10 +29,12 @@ module QA
view_pipelines
Page::Project::Pipeline::Show.perform do |parent_pipeline|
- parent_pipeline.click_linked_job(project.name)
+ expect(parent_pipeline).to have_passed
+ parent_pipeline.retry_on_exception(reload: true, sleep_interval: 1.0) do
+ parent_pipeline.click_linked_job(project.name)
+ end
expect(parent_pipeline).to have_job("child_job")
- expect(parent_pipeline).to have_passed
end
end
@@ -41,10 +43,12 @@ module QA
view_pipelines
Page::Project::Pipeline::Show.perform do |parent_pipeline|
- parent_pipeline.click_linked_job(project.name)
+ expect(parent_pipeline).to have_passed
+ parent_pipeline.retry_on_exception(reload: true, sleep_interval: 1.0) do
+ parent_pipeline.click_linked_job(project.name)
+ end
expect(parent_pipeline).to have_job("child_job")
- expect(parent_pipeline).to have_passed
end
end
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 04c68598239..0e9c369e97f 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
@@ -1,10 +1,10 @@
# frozen_string_literal: true
module QA
- context 'Configure', quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/209085', type: :investigating } do
- describe 'Kubernetes Cluster Integration', :orchestrated, :kubernetes, :requires_admin do
+ context 'Configure' do
+ describe 'Kubernetes Cluster Integration', :orchestrated, :kubernetes, :requires_admin, :skip_live_env do
context 'Project Clusters' do
- let(:cluster) { Service::KubernetesCluster.new(provider_class: Service::ClusterProvider::K3s).create! }
+ let!(:cluster) { Service::KubernetesCluster.new(provider_class: Service::ClusterProvider::K3s).create! }
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'project-with-k8s'
@@ -13,7 +13,7 @@ module QA
end
before do
- Flow::Login.sign_in
+ Flow::Login.sign_in_as_admin
end
after do
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 45273655bb6..a9ed6651069 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
@@ -1,11 +1,16 @@
# frozen_string_literal: true
module QA
- context 'Monitor', quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/217705', type: :flaky } do
- describe 'with Prometheus Gitlab-managed cluster', :orchestrated, :kubernetes, :docker, :runner do
+ context 'Monitor' do
+ describe 'with Prometheus in a Gitlab-managed cluster', :orchestrated, :kubernetes do
before :all do
- Flow::Login.sign_in
- @project, @runner = deploy_project_with_prometheus
+ @cluster = Service::KubernetesCluster.new.create!
+ @project = Resource::Project.fabricate_via_api! do |project|
+ project.name = 'monitoring-project'
+ project.auto_devops_enabled = true
+ end
+
+ deploy_project_with_prometheus
end
before do
@@ -14,7 +19,6 @@ module QA
end
after :all do
- @runner.remove_via_api!
@cluster.remove!
end
@@ -27,81 +31,94 @@ module QA
it 'duplicates to create dashboard to custom' do
Page::Project::Menu.perform(&:go_to_operations_metrics)
- Page::Project::Operations::Metrics::Show.perform do |dashboard|
- dashboard.duplicate_dashboard
+ Page::Project::Operations::Metrics::Show.perform do |on_dashboard|
+ on_dashboard.duplicate_dashboard
- expect(dashboard).to have_metrics
- expect(dashboard).to have_edit_dashboard_enabled
+ expect(on_dashboard).to have_metrics
+ expect(on_dashboard).to have_edit_dashboard_enabled
end
end
it 'verifies data on filtered deployed environment' do
Page::Project::Menu.perform(&:go_to_operations_metrics)
- Page::Project::Operations::Metrics::Show.perform do |dashboard|
- dashboard.filter_environment
+ Page::Project::Operations::Metrics::Show.perform do |on_dashboard|
+ on_dashboard.filter_environment
- expect(dashboard).to have_metrics
+ expect(on_dashboard).to have_metrics
end
end
it 'filters using the quick range' do
Page::Project::Menu.perform(&:go_to_operations_metrics)
- Page::Project::Operations::Metrics::Show.perform do |dashboard|
- dashboard.show_last('30 minutes')
- expect(dashboard).to have_metrics
+ Page::Project::Operations::Metrics::Show.perform do |on_dashboard|
+ on_dashboard.show_last('30 minutes')
+ expect(on_dashboard).to have_metrics
- dashboard.show_last('3 hours')
- expect(dashboard).to have_metrics
+ on_dashboard.show_last('3 hours')
+ expect(on_dashboard).to have_metrics
- dashboard.show_last('1 day')
- expect(dashboard).to have_metrics
+ on_dashboard.show_last('1 day')
+ expect(on_dashboard).to have_metrics
end
end
private
def deploy_project_with_prometheus
- project = Resource::Project.fabricate_via_api! do |project|
- project.name = 'cluster-with-prometheus'
- project.description = 'Cluster with Prometheus'
+ %w[
+ CODE_QUALITY_DISABLED TEST_DISABLED LICENSE_MANAGEMENT_DISABLED
+ SAST_DISABLED DAST_DISABLED DEPENDENCY_SCANNING_DISABLED
+ CONTAINER_SCANNING_DISABLED PERFORMANCE_DISABLED
+ ].each do |key|
+ Resource::CiVariable.fabricate_via_api! do |resource|
+ resource.project = @project
+ resource.key = key
+ resource.value = '1'
+ resource.masked = false
+ end
end
- runner = Resource::Runner.fabricate_via_api! do |runner|
- runner.project = project
- runner.name = project.name
- end
-
- @cluster = Service::KubernetesCluster.new.create!
+ Flow::Login.sign_in
- cluster_props = Resource::KubernetesCluster::ProjectCluster.fabricate! do |cluster_settings|
- cluster_settings.project = project
+ Resource::KubernetesCluster::ProjectCluster.fabricate! do |cluster_settings|
+ cluster_settings.project = @project
cluster_settings.cluster = @cluster
cluster_settings.install_helm_tiller = true
+ cluster_settings.install_runner = true
cluster_settings.install_ingress = true
cluster_settings.install_prometheus = true
end
- Resource::CiVariable.fabricate_via_api! do |ci_variable|
- ci_variable.project = project
- ci_variable.key = 'AUTO_DEVOPS_DOMAIN'
- ci_variable.value = cluster_props.ingress_ip
- ci_variable.masked = false
- end
-
Resource::Repository::ProjectPush.fabricate! do |push|
- push.project = project
+ push.project = @project
push.directory = Pathname
.new(__dir__)
- .join('../../../../fixtures/monitored_auto_devops')
+ .join('../../../../fixtures/auto_devops_rack')
push.commit_message = 'Create AutoDevOps compatible Project for Monitoring'
end
Page::Project::Menu.perform(&:click_ci_cd_pipelines)
- Page::Project::Pipeline::Index.perform(&:wait_for_latest_pipeline_success_or_retry)
+ Page::Project::Pipeline::Index.perform(&:click_on_latest_pipeline)
+
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('build')
+ end
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 600)
+
+ job.click_element(:pipeline_path)
+ end
+
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('production')
+ end
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 1200)
- [project, runner]
+ job.click_element(:pipeline_path)
+ end
end
def verify_add_custom_metric
@@ -115,8 +132,8 @@ module QA
Page::Project::Menu.perform(&:go_to_operations_metrics)
- Page::Project::Operations::Metrics::Show.perform do |dashboard|
- expect(dashboard).to have_custom_metric('HTTP Requests Total')
+ Page::Project::Operations::Metrics::Show.perform do |on_dashboard|
+ expect(on_dashboard).to have_custom_metric('HTTP Requests Total')
end
end
@@ -130,8 +147,8 @@ module QA
Page::Project::Menu.perform(&:go_to_operations_metrics)
- Page::Project::Operations::Metrics::Show.perform do |dashboard|
- expect(dashboard).to have_custom_metric('Throughput')
+ Page::Project::Operations::Metrics::Show.perform do |on_dashboard|
+ expect(on_dashboard).to have_custom_metric('Throughput')
end
end
@@ -146,8 +163,8 @@ module QA
Page::Project::Menu.perform(&:go_to_operations_metrics)
- Page::Project::Operations::Metrics::Show.perform do |dashboard|
- expect(dashboard).not_to have_custom_metric('Throughput')
+ Page::Project::Operations::Metrics::Show.perform do |on_dashboard|
+ expect(on_dashboard).not_to have_custom_metric('Throughput')
end
end
end
diff --git a/qa/qa/support/api.rb b/qa/qa/support/api.rb
index f5e4d4e294b..3c46c039eae 100644
--- a/qa/qa/support/api.rb
+++ b/qa/qa/support/api.rb
@@ -11,22 +11,31 @@ module QA
HTTP_STATUS_ACCEPTED = 202
HTTP_STATUS_SERVER_ERROR = 500
- def post(url, payload)
- RestClient::Request.execute(
+ def post(url, payload, args = {})
+ default_args = {
method: :post,
url: url,
payload: payload,
- verify_ssl: false)
+ verify_ssl: false
+ }
+
+ RestClient::Request.execute(
+ default_args.merge(args)
+ )
rescue RestClient::ExceptionWithResponse => e
return_response_or_raise(e)
end
- def get(url, raw_response: false)
- RestClient::Request.execute(
+ def get(url, args = {})
+ default_args = {
method: :get,
url: url,
- verify_ssl: false,
- raw_response: raw_response)
+ verify_ssl: false
+ }
+
+ RestClient::Request.execute(
+ default_args.merge(args)
+ )
rescue RestClient::ExceptionWithResponse => e
return_response_or_raise(e)
end
diff --git a/qa/qa/support/repeater.rb b/qa/qa/support/repeater.rb
index 14771243beb..6f8c4a59566 100644
--- a/qa/qa/support/repeater.rb
+++ b/qa/qa/support/repeater.rb
@@ -7,8 +7,9 @@ module QA
module Repeater
DEFAULT_MAX_WAIT_TIME = 60
- RetriesExceededError = Class.new(RuntimeError)
- WaitExceededError = Class.new(RuntimeError)
+ RepeaterConditionExceededError = Class.new(RuntimeError)
+ RetriesExceededError = Class.new(RepeaterConditionExceededError)
+ WaitExceededError = Class.new(RepeaterConditionExceededError)
def repeat_until(max_attempts: nil, max_duration: nil, reload_page: nil, sleep_interval: 0, raise_on_failure: true, retry_on_exception: false, log: true)
attempts = 0
diff --git a/qa/qa/vendor/jira/jira_api.rb b/qa/qa/vendor/jira/jira_api.rb
new file mode 100644
index 00000000000..65b080df3d0
--- /dev/null
+++ b/qa/qa/vendor/jira/jira_api.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+module QA
+ module Vendor
+ module Jira
+ class JiraAPI
+ include Scenario::Actable
+ include Support::Api
+
+ def base_url
+ host = QA::Runtime::Env.jira_hostname || 'localhost'
+
+ "http://#{host}:8080"
+ end
+
+ def api_url
+ "#{base_url}/rest/api/2"
+ end
+
+ def fetch_issue(issue_key)
+ response = get("#{api_url}/issue/#{issue_key}", user: Runtime::Env.jira_admin_username, password: Runtime::Env.jira_admin_password)
+
+ parse_body(response)
+ end
+
+ def create_issue(jira_project_key)
+ payload = {
+ fields: {
+ project: {
+ key: jira_project_key
+ },
+ summary: 'REST ye merry gentlemen.',
+ description: 'Creating of an issue using project keys and issue type names using the REST API',
+ issuetype: {
+ name: 'Bug'
+ }
+ }
+ }
+
+ response = post("#{api_url}/issue",
+ payload.to_json, headers: { 'Content-Type': 'application/json' },
+ user: Runtime::Env.jira_admin_username,
+ password: Runtime::Env.jira_admin_password)
+
+ issue_key = parse_body(response)[:key]
+
+ QA::Runtime::Logger.debug("Created JIRA issue with key: '#{issue_key}'")
+
+ issue_key
+ end
+ end
+ end
+ end
+end
diff --git a/qa/spec/runtime/feature_spec.rb b/qa/spec/runtime/feature_spec.rb
index 94638d99b01..db3c2f65963 100644
--- a/qa/spec/runtime/feature_spec.rb
+++ b/qa/spec/runtime/feature_spec.rb
@@ -25,6 +25,21 @@ describe QA::Runtime::Feature do
end
end
+ describe '.enable_and_verify' do
+ it 'enables a feature flag' do
+ allow(described_class).to receive(:get).and_return(response_get)
+
+ expect(QA::Runtime::API::Request).to receive(:new)
+ .with(api_client, "/features/a-flag").and_return(request)
+ expect(described_class).to receive(:post)
+ .with(request.url, { value: true }).and_return(response_post)
+ expect(QA::Runtime::API::Request).to receive(:new)
+ .with(api_client, "/features").and_return(request)
+
+ subject.enable_and_verify('a-flag')
+ end
+ end
+
describe '.disable' do
it 'disables a feature flag' do
expect(QA::Runtime::API::Request)
@@ -40,6 +55,22 @@ describe QA::Runtime::Feature do
end
end
+ describe '.disable_and_verify' do
+ it 'disables a feature flag' do
+ allow(described_class).to receive(:get)
+ .and_return(Struct.new(:code, :body).new(200, '[{ "name": "a-flag", "state": "off" }]'))
+
+ expect(QA::Runtime::API::Request).to receive(:new)
+ .with(api_client, "/features/a-flag").and_return(request)
+ expect(described_class).to receive(:post)
+ .with(request.url, { value: false }).and_return(response_post)
+ expect(QA::Runtime::API::Request).to receive(:new)
+ .with(api_client, "/features").and_return(request)
+
+ subject.disable_and_verify('a-flag')
+ end
+ end
+
describe '.enabled?' do
it 'returns a feature flag state' do
expect(QA::Runtime::API::Request)
diff --git a/qa/spec/scenario/test/instance/airgapped_spec.rb b/qa/spec/scenario/test/instance/airgapped_spec.rb
new file mode 100644
index 00000000000..0c4167eafff
--- /dev/null
+++ b/qa/spec/scenario/test/instance/airgapped_spec.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+describe QA::Scenario::Test::Instance::Airgapped do
+ describe '#perform' do
+ it_behaves_like 'a QA scenario class' do
+ end
+ end
+end
diff --git a/qa/spec/support/shared_examples/merge_with_code_owner_shared_examples.rb b/qa/spec/support/shared_examples/merge_with_code_owner_shared_examples.rb
new file mode 100644
index 00000000000..feaeb78815d
--- /dev/null
+++ b/qa/spec/support/shared_examples/merge_with_code_owner_shared_examples.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+module QA
+ shared_examples 'code owner merge request' do
+ let(:branch_name) { 'new-branch' }
+
+ it 'is approved and merged' do
+ # Require one approval from any eligible user on any branch
+ # This will confirm that this type of unrestricted approval is
+ # also satisfied when a code owner grants approval
+ Page::Project::Menu.perform(&:go_to_general_settings)
+ Page::Project::Settings::Main.perform do |main|
+ main.expand_merge_request_approvals_settings do |settings|
+ settings.set_default_number_of_approvals_required(1)
+ end
+ end
+
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ commit.project = project
+ commit.commit_message = 'Add CODEOWNERS'
+ commit.add_files(
+ [
+ {
+ file_path: 'CODEOWNERS',
+ content: <<~CONTENT
+ README.md @#{codeowner}
+ CONTENT
+ }
+ ]
+ )
+ end
+
+ # Require approval from code owners on master
+ Resource::ProtectedBranch.fabricate! do |protected_branch|
+ protected_branch.project = project
+ protected_branch.branch_name = 'master'
+ protected_branch.new_branch = false
+ protected_branch.require_code_owner_approval = true
+ end
+
+ # Push a change to the file with a CODEOWNERS rule
+ Resource::Repository::Push.fabricate! do |push|
+ push.repository_http_uri = project.repository_http_location.uri
+ push.branch_name = branch_name
+ push.file_name = 'README.md'
+ push.file_content = 'Updated'
+ end
+
+ merge_request = Resource::MergeRequest.fabricate! do |merge_request|
+ merge_request.project = project
+ merge_request.target_new_branch = false
+ merge_request.source_branch = branch_name
+ merge_request.no_preparation = true
+ end
+
+ Flow::Login.while_signed_in(as: approver) do
+ merge_request.visit!
+
+ Page::MergeRequest::Show.perform do |merge_request|
+ expect(merge_request.approvals_required_from).to include('Code Owners')
+ expect(merge_request).not_to be_mergeable
+
+ merge_request.click_approve
+ merge_request.merge!
+
+ expect(merge_request).to be_merged
+ end
+ end
+ end
+ end
+end
diff --git a/rubocop/cop/default_scope.rb b/rubocop/cop/default_scope.rb
new file mode 100644
index 00000000000..39f8c8e9ed0
--- /dev/null
+++ b/rubocop/cop/default_scope.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module RuboCop
+ module Cop
+ # Cop that blacklists the use of `default_scope`.
+ class DefaultScope < RuboCop::Cop::Cop
+ MSG = <<~EOF
+ Do not use `default_scope`, as it does not follow the principle of
+ least surprise. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33847
+ for more details.
+ EOF
+
+ def_node_matcher :default_scope?, <<~PATTERN
+ (send {nil? (const nil? ...)} :default_scope ...)
+ PATTERN
+
+ def on_send(node)
+ return unless default_scope?(node)
+
+ add_offense(node, location: :expression)
+ end
+ end
+ end
+end
diff --git a/rubocop/cop/gitlab/avoid_feature_get.rb b/rubocop/cop/gitlab/avoid_feature_get.rb
new file mode 100644
index 00000000000..e36e0b020c0
--- /dev/null
+++ b/rubocop/cop/gitlab/avoid_feature_get.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module RuboCop
+ module Cop
+ module Gitlab
+ # Cop that blacklists the use of `Feature.get`.
+ class AvoidFeatureGet < RuboCop::Cop::Cop
+ MSG = 'Use `Feature.enable/disable` methods instead of `Feature.get`. ' \
+ 'See doc/development/testing_guide/best_practices.md#feature-flags-in-tests for more information.'
+
+ def_node_matcher :feature_get?, <<~PATTERN
+ (send (const nil? :Feature) :get ...)
+ PATTERN
+
+ def_node_matcher :global_feature_get?, <<~PATTERN
+ (send (const (cbase) :Feature) :get ...)
+ PATTERN
+
+ def on_send(node)
+ return unless feature_get?(node) || global_feature_get?(node)
+
+ add_offense(node, location: :selector)
+ end
+ end
+ end
+ end
+end
diff --git a/rubocop/cop/gitlab/bulk_insert.rb b/rubocop/cop/gitlab/bulk_insert.rb
new file mode 100644
index 00000000000..c03ffbe0b2a
--- /dev/null
+++ b/rubocop/cop/gitlab/bulk_insert.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module RuboCop
+ module Cop
+ module Gitlab
+ # Cop that disallows the use of `Gitlab::Database.bulk_insert`, in favour of using
+ # the `BulkInsertSafe` module.
+ class BulkInsert < RuboCop::Cop::Cop
+ MSG = 'Use the `BulkInsertSafe` concern, instead of using `Gitlab::Database.bulk_insert`. See https://docs.gitlab.com/ee/development/insert_into_tables_in_batches.html'
+
+ def_node_matcher :raw_union?, <<~PATTERN
+ (send (const (const nil? :Gitlab) :Database) :bulk_insert ...)
+ PATTERN
+
+ def on_send(node)
+ return unless raw_union?(node)
+
+ add_offense(node, location: :expression)
+ end
+ end
+ end
+ end
+end
diff --git a/rubocop/cop/inject_enterprise_edition_module.rb b/rubocop/cop/inject_enterprise_edition_module.rb
index 7edce94eaee..16e4b647265 100644
--- a/rubocop/cop/inject_enterprise_edition_module.rb
+++ b/rubocop/cop/inject_enterprise_edition_module.rb
@@ -2,9 +2,8 @@
module RuboCop
module Cop
- # Cop that blacklists the injecting of EE specific modules anywhere but on
- # the last line of a file. Injecting a module in the middle of a file will
- # cause merge conflicts, while placing it on the last line will not.
+ # Cop that blacklists the injecting of EE specific modules before any lines which are not already injecting another module.
+ # It allows multiple module injections as long as they're all at the end.
class InjectEnterpriseEditionModule < RuboCop::Cop::Cop
INVALID_LINE = 'Injecting EE modules must be done on the last line of this file' \
', outside of any class or module definitions'
@@ -17,10 +16,12 @@ module RuboCop
CHECK_LINE_METHODS =
Set.new(%i[include_if_ee extend_if_ee prepend_if_ee]).freeze
- CHECK_LINE_METHODS_REGEXP = Regexp.union(CHECK_LINE_METHODS.map(&:to_s)).freeze
-
DISALLOW_METHODS = Set.new(%i[include extend prepend]).freeze
+ COMMENT_OR_EMPTY_LINE = /^\s*(#.*|$)/.freeze
+
+ CHECK_LINE_METHODS_REGEXP = Regexp.union((CHECK_LINE_METHODS + DISALLOW_METHODS).map(&:to_s) + [COMMENT_OR_EMPTY_LINE]).freeze
+
def ee_const?(node)
line = node.location.expression.source_line
@@ -44,15 +45,11 @@ module RuboCop
line = node.location.line
buffer = node.location.expression.source_buffer
last_line = buffer.last_line
+ lines = buffer.source.split("\n")
+ # We allow multiple includes, extends and prepends as long as they're all at the end.
+ allowed_line = (line...last_line).all? { |i| CHECK_LINE_METHODS_REGEXP.match?(lines[i - 1]) }
- # Parser treats the final newline (if present) as a separate line,
- # meaning that a simple `line < last_line` would yield true even though
- # the expression is the last line _of code_.
- last_line -= 1 if buffer.source.end_with?("\n")
-
- last_line_content = buffer.source.split("\n")[-1]
-
- if CHECK_LINE_METHODS_REGEXP.match?(last_line_content)
+ if allowed_line
ignore_node(node)
elsif line < last_line
add_offense(node, message: INVALID_LINE)
diff --git a/rubocop/cop/migration/add_limit_to_text_columns.rb b/rubocop/cop/migration/add_limit_to_text_columns.rb
index 15c28bb9266..b578e73f19e 100644
--- a/rubocop/cop/migration/add_limit_to_text_columns.rb
+++ b/rubocop/cop/migration/add_limit_to_text_columns.rb
@@ -39,6 +39,9 @@ module RuboCop
private
def text_operation?(node)
+ # Don't complain about text arrays
+ return false if array_column?(node)
+
modifier = node.children[0]
migration_method = node.children[1]
diff --git a/rubocop/cop/migration/drop_table.rb b/rubocop/cop/migration/drop_table.rb
new file mode 100644
index 00000000000..2a0f57c0c13
--- /dev/null
+++ b/rubocop/cop/migration/drop_table.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+require_relative '../../migration_helpers'
+
+module RuboCop
+ module Cop
+ module Migration
+ # Cop that checks if `drop_table` is called in deployment migrations.
+ # Calling it in deployment migrations can cause downtimes as there still may be code using the target tables.
+ class DropTable < RuboCop::Cop::Cop
+ include MigrationHelpers
+
+ MSG = <<-MESSAGE.delete("\n").squeeze
+ `drop_table` in deployment migrations requires downtime.
+ Drop tables in post-deployment migrations instead.
+ MESSAGE
+
+ def on_def(node)
+ return unless in_deployment_migration?(node)
+
+ node.each_descendant(:send) do |send_node|
+ next unless offensible?(send_node)
+
+ add_offense(send_node, location: :selector)
+ end
+ end
+
+ private
+
+ def offensible?(node)
+ drop_table?(node) || drop_table_in_execute?(node)
+ end
+
+ def drop_table?(node)
+ node.children[1] == :drop_table
+ end
+
+ def drop_table_in_execute?(node)
+ execute?(node) && drop_table_in_execute_sql?(node)
+ end
+
+ def execute?(node)
+ node.children[1] == :execute
+ end
+
+ def drop_table_in_execute_sql?(node)
+ node.children[2].to_s.match?(/drop\s+table/i)
+ end
+ end
+ end
+ end
+end
diff --git a/rubocop/cop/migration/prevent_strings.rb b/rubocop/cop/migration/prevent_strings.rb
index 25c00194698..bfeabd2c78d 100644
--- a/rubocop/cop/migration/prevent_strings.rb
+++ b/rubocop/cop/migration/prevent_strings.rb
@@ -33,6 +33,9 @@ module RuboCop
private
def string_operation?(node)
+ # Don't complain about string arrays
+ return false if array_column?(node)
+
modifier = node.children[0]
migration_method = node.children[1]
diff --git a/rubocop/cop/migration/update_large_table.rb b/rubocop/cop/migration/update_large_table.rb
deleted file mode 100644
index e44eadbdb92..00000000000
--- a/rubocop/cop/migration/update_large_table.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-require_relative '../../migration_helpers'
-
-module RuboCop
- module Cop
- module Migration
- # This cop checks for `add_column_with_default` on a table that's been
- # explicitly blacklisted because of its size.
- #
- # Even though this helper performs the update in batches to avoid
- # downtime, using it with tables with millions of rows still causes a
- # significant delay in the deploy process and is best avoided.
- #
- # See https://gitlab.com/gitlab-com/infrastructure/issues/1602 for more
- # information.
- class UpdateLargeTable < RuboCop::Cop::Cop
- include MigrationHelpers
-
- MSG = 'Using `%s` on the `%s` table will take a long time to ' \
- 'complete, and should be avoided unless absolutely ' \
- 'necessary'.freeze
-
- BATCH_UPDATE_METHODS = %w[
- :add_column_with_default
- :change_column_type_concurrently
- :rename_column_concurrently
- :update_column_in_batches
- ].join(' ').freeze
-
- def_node_matcher :batch_update?, <<~PATTERN
- (send nil? ${#{BATCH_UPDATE_METHODS}} $(sym ...) ...)
- PATTERN
-
- def on_send(node)
- return unless in_migration?(node)
-
- matches = batch_update?(node)
- return unless matches
-
- update_method = matches.first
- table = matches.last.to_a.first
-
- return unless BLACKLISTED_TABLES.include?(table)
-
- add_offense(node, location: :expression, message: format(MSG, update_method, table))
- end
- end
- end
- end
-end
diff --git a/rubocop/cop/rspec/empty_line_after_shared_example.rb b/rubocop/cop/rspec/empty_line_after_shared_example.rb
deleted file mode 100644
index 5d09565bd5a..00000000000
--- a/rubocop/cop/rspec/empty_line_after_shared_example.rb
+++ /dev/null
@@ -1,64 +0,0 @@
-# frozen_string_literal: true
-
-require 'rubocop/rspec/final_end_location'
-require 'rubocop/rspec/blank_line_separation'
-require 'rubocop/rspec/language'
-
-module RuboCop
- module Cop
- module RSpec
- # Checks if there is an empty line after shared example blocks.
- #
- # @example
- # # bad
- # RSpec.describe Foo do
- # it_behaves_like 'do this first'
- # it_behaves_like 'does this' do
- # end
- # it_behaves_like 'does that' do
- # end
- # it_behaves_like 'do some more'
- # end
- #
- # # good
- # RSpec.describe Foo do
- # it_behaves_like 'do this first'
- # it_behaves_like 'does this' do
- # end
- #
- # it_behaves_like 'does that' do
- # end
- #
- # it_behaves_like 'do some more'
- # end
- #
- # # fair - it's ok to have non-separated without blocks
- # RSpec.describe Foo do
- # it_behaves_like 'do this first'
- # it_behaves_like 'does this'
- # end
- #
- class EmptyLineAfterSharedExample < RuboCop::Cop::Cop
- include RuboCop::RSpec::BlankLineSeparation
- include RuboCop::RSpec::Language
-
- MSG = 'Add an empty line after `%<example>s` block.'
-
- def_node_matcher :shared_examples,
- (SharedGroups::ALL + Includes::ALL).block_pattern
-
- def on_block(node)
- shared_examples(node) do
- break if last_child?(node)
-
- missing_separating_line(node) do |location|
- add_offense(node,
- location: location,
- message: format(MSG, example: node.method_name))
- end
- end
- end
- end
- end
- end
-end
diff --git a/rubocop/migration_helpers.rb b/rubocop/migration_helpers.rb
index de377b15cc8..355450bbf57 100644
--- a/rubocop/migration_helpers.rb
+++ b/rubocop/migration_helpers.rb
@@ -7,45 +7,6 @@ module RuboCop
].freeze
# Blacklisted tables due to:
- # - size in GB (>= 10 GB on GitLab.com as of 02/2020)
- # - number of records
- BLACKLISTED_TABLES = %i[
- audit_events
- ci_build_trace_sections
- ci_builds
- ci_builds_metadata
- ci_job_artifacts
- ci_pipeline_variables
- ci_pipelines
- ci_stages
- deployments
- events
- issues
- merge_request_diff_commits
- merge_request_diff_files
- merge_request_diffs
- merge_request_metrics
- merge_requests
- namespaces
- note_diff_files
- notes
- project_authorizations
- projects
- project_ci_cd_settings
- project_features
- push_event_payloads
- resource_label_events
- routes
- sent_notifications
- services
- system_note_metadata
- taggings
- todos
- users
- web_hook_logs
- ].freeze
-
- # Blacklisted tables due to:
# - number of columns (> 50 on GitLab.com as of 03/2020)
# - number of records
WIDE_TABLES = %i[
@@ -62,7 +23,11 @@ module RuboCop
# Returns true if the given node originated from the db/migrate directory.
def in_migration?(node)
- dirname(node).end_with?('db/migrate', 'db/geo/migrate') || in_post_deployment_migration?(node)
+ in_deployment_migration?(node) || in_post_deployment_migration?(node)
+ end
+
+ def in_deployment_migration?(node)
+ dirname(node).end_with?('db/migrate', 'db/geo/migrate')
end
def in_post_deployment_migration?(node)
@@ -73,6 +38,16 @@ module RuboCop
File.basename(node.location.expression.source_buffer.name).split('_').first.to_i
end
+ # Returns true if a column definition is for an array
+ # rubocop:disable Lint/BooleanSymbol
+ def array_column?(node)
+ node.each_descendant(:pair).any? do |pair_node|
+ pair_node.child_nodes[0].value == :array && # Searching for a (pair (sym :array) (true)) node
+ pair_node.child_nodes[1].type == :true # RuboCop::AST::Node uses symbols for types, even when that is a :true
+ end
+ end
+ # rubocop:enable Lint/BooleanSymbol
+
private
def dirname(node)
diff --git a/rubocop/rubocop-migrations.yml b/rubocop/rubocop-migrations.yml
new file mode 100644
index 00000000000..8699f7b9c68
--- /dev/null
+++ b/rubocop/rubocop-migrations.yml
@@ -0,0 +1,40 @@
+Migration/UpdateLargeTable:
+ Enabled: true
+ DeniedTables: &denied_tables # size in GB (>= 10 GB on GitLab.com as of 02/2020) and/or number of records
+ - :audit_events
+ - :ci_build_trace_sections
+ - :ci_builds
+ - :ci_builds_metadata
+ - :ci_job_artifacts
+ - :ci_pipeline_variables
+ - :ci_pipelines
+ - :ci_stages
+ - :deployments
+ - :events
+ - :issues
+ - :merge_request_diff_commits
+ - :merge_request_diff_files
+ - :merge_request_diffs
+ - :merge_request_metrics
+ - :merge_requests
+ - :namespaces
+ - :note_diff_files
+ - :notes
+ - :project_authorizations
+ - :projects
+ - :project_ci_cd_settings
+ - :project_features
+ - :push_event_payloads
+ - :resource_label_events
+ - :routes
+ - :sent_notifications
+ - :services
+ - :system_note_metadata
+ - :taggings
+ - :todos
+ - :users
+ - :web_hook_logs
+ DeniedMethods:
+ - :change_column_type_concurrently
+ - :rename_column_concurrently
+ - :update_column_in_batches
diff --git a/scripts/build_assets_image b/scripts/build_assets_image
index 9eb1ccd5515..12beddfa184 100755
--- a/scripts/build_assets_image
+++ b/scripts/build_assets_image
@@ -1,7 +1,7 @@
# Exit early if we don't want to build the image
if [[ "${BUILD_ASSETS_IMAGE}" != "true" ]]
then
- exit 0
+ exit 0
fi
# Generate the image name based on the project this is being run in
diff --git a/scripts/gemfile_lock_changed.sh b/scripts/gemfile_lock_changed.sh
index 24e2c685f11..eec31af1f77 100755
--- a/scripts/gemfile_lock_changed.sh
+++ b/scripts/gemfile_lock_changed.sh
@@ -2,7 +2,7 @@
gemfile_lock_changed() {
if [ -n "$(git diff --name-only -- Gemfile.lock)" ]; then
- cat << EOF
+ cat <<EOF
Gemfile was updated but Gemfile.lock was not updated.
Usually, when Gemfile is updated, you should run
diff --git a/scripts/gitaly-test-build b/scripts/gitaly-test-build
index fcf0049162b..5254d957afd 100755
--- a/scripts/gitaly-test-build
+++ b/scripts/gitaly-test-build
@@ -14,6 +14,7 @@ class GitalyTestBuild
def run
abort 'gitaly build failed' unless system(env, 'make', chdir: tmp_tests_gitaly_dir)
+ ensure_gitlab_shell_secret!
check_gitaly_config!
# Starting gitaly further validates its configuration
diff --git a/scripts/gitaly_test.rb b/scripts/gitaly_test.rb
index e6f2c9885d9..c69c4ea747b 100644
--- a/scripts/gitaly_test.rb
+++ b/scripts/gitaly_test.rb
@@ -4,6 +4,7 @@
# Please be careful when modifying this file. Your changes must work
# both for local development rspec runs, and in CI.
+require 'securerandom'
require 'socket'
module GitalyTest
@@ -11,10 +12,22 @@ module GitalyTest
File.expand_path('../tmp/tests/gitaly', __dir__)
end
+ def tmp_tests_gitlab_shell_dir
+ File.expand_path('../tmp/tests/gitlab-shell', __dir__)
+ end
+
+ def rails_gitlab_shell_secret
+ File.expand_path('../.gitlab_shell_secret', __dir__)
+ end
+
def gemfile
File.join(tmp_tests_gitaly_dir, 'ruby', 'Gemfile')
end
+ def gitlab_shell_secret_file
+ File.join(tmp_tests_gitlab_shell_dir, '.gitlab_shell_secret')
+ end
+
def env
env_hash = {
'HOME' => File.expand_path('tmp/tests'),
@@ -70,6 +83,20 @@ module GitalyTest
pid
end
+ # Taken from Gitlab::Shell.generate_and_link_secret_token
+ def ensure_gitlab_shell_secret!
+ secret_file = rails_gitlab_shell_secret
+ shell_link = gitlab_shell_secret_file
+
+ unless File.size?(secret_file)
+ File.write(secret_file, SecureRandom.hex(16))
+ end
+
+ unless File.exist?(shell_link)
+ FileUtils.ln_s(secret_file, shell_link)
+ end
+ end
+
def check_gitaly_config!
puts "Checking gitaly-ruby Gemfile..."
diff --git a/scripts/lint-changelog-filenames b/scripts/lint-changelog-filenames
index 2355ac6f7b2..fc07b7153aa 100755
--- a/scripts/lint-changelog-filenames
+++ b/scripts/lint-changelog-filenames
@@ -6,7 +6,7 @@ lint_paths="changelogs/unreleased"
invalid_files=$(find $lint_paths -type f -not -name "*.yml" -not -name ".gitkeep")
if [ -n "$invalid_files" ]; then
- echo "Changelog files must end in .yml, but these did not:"
- echo "$invalid_files" | sed -e "s/^/* /"
+ echo "Changelog files must end in .yml, but these did not:"
+ echo "$invalid_files" | sed -e "s/^/* /"
exit 1
fi
diff --git a/scripts/lint-conflicts.sh b/scripts/lint-conflicts.sh
index 239e227a41e..2d240e420d9 100755
--- a/scripts/lint-conflicts.sh
+++ b/scripts/lint-conflicts.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-output=`git grep -En '^<<<<<<< '`
+output=$(git grep -En '^<<<<<<< ')
echo $output
test -z "$output"
diff --git a/scripts/lint-doc.sh b/scripts/lint-doc.sh
index d9de48fd0c0..ca9747987df 100755
--- a/scripts/lint-doc.sh
+++ b/scripts/lint-doc.sh
@@ -40,8 +40,8 @@ then
fi
# Do not use 'README.md', instead use 'index.md'
-# Number of 'README.md's as of 2018-03-26
-NUMBER_READMES=46
+# Number of 'README.md's as of 2020-05-28
+NUMBER_READMES=45
FIND_READMES=$(find doc/ -name "README.md" | wc -l)
echo '=> Checking for new README.md files...'
echo
diff --git a/scripts/review_apps/base-config.yaml b/scripts/review_apps/base-config.yaml
index a34bb23a5e6..6fb6943fb90 100644
--- a/scripts/review_apps/base-config.yaml
+++ b/scripts/review_apps/base-config.yaml
@@ -66,7 +66,7 @@ gitlab:
limits:
cpu: 100m
memory: 700M
- unicorn:
+ webservice:
resources:
requests:
cpu: 746m
diff --git a/scripts/review_apps/review-apps.sh b/scripts/review_apps/review-apps.sh
index 097fe9c8cca..1214ee5f462 100755
--- a/scripts/review_apps/review-apps.sh
+++ b/scripts/review_apps/review-apps.sh
@@ -245,7 +245,7 @@ function deploy() {
IMAGE_REPOSITORY="registry.gitlab.com/gitlab-org/build/cng-mirror"
gitlab_migrations_image_repository="${IMAGE_REPOSITORY}/gitlab-rails-ee"
gitlab_sidekiq_image_repository="${IMAGE_REPOSITORY}/gitlab-sidekiq-ee"
- gitlab_unicorn_image_repository="${IMAGE_REPOSITORY}/gitlab-webservice-ee"
+ gitlab_webservice_image_repository="${IMAGE_REPOSITORY}/gitlab-webservice-ee"
gitlab_task_runner_image_repository="${IMAGE_REPOSITORY}/gitlab-task-runner-ee"
gitlab_gitaly_image_repository="${IMAGE_REPOSITORY}/gitaly"
gitlab_shell_image_repository="${IMAGE_REPOSITORY}/gitlab-shell"
@@ -275,11 +275,11 @@ HELM_CMD=$(cat << EOF
--set gitlab.sidekiq.annotations.commit="${CI_COMMIT_SHORT_SHA}" \
--set gitlab.sidekiq.image.repository="${gitlab_sidekiq_image_repository}" \
--set gitlab.sidekiq.image.tag="${CI_COMMIT_REF_SLUG}" \
- --set gitlab.unicorn.annotations.commit="${CI_COMMIT_SHORT_SHA}" \
- --set gitlab.unicorn.image.repository="${gitlab_unicorn_image_repository}" \
- --set gitlab.unicorn.image.tag="${CI_COMMIT_REF_SLUG}" \
- --set gitlab.unicorn.workhorse.image="${gitlab_workhorse_image_repository}" \
- --set gitlab.unicorn.workhorse.tag="${CI_COMMIT_REF_SLUG}" \
+ --set gitlab.webservice.annotations.commit="${CI_COMMIT_SHORT_SHA}" \
+ --set gitlab.webservice.image.repository="${gitlab_webservice_image_repository}" \
+ --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.tag="${CI_COMMIT_REF_SLUG}"
EOF
diff --git a/scripts/rspec_helpers.sh b/scripts/rspec_helpers.sh
index 0c9d3505ff3..110567a15be 100644
--- a/scripts/rspec_helpers.sh
+++ b/scripts/rspec_helpers.sh
@@ -110,3 +110,27 @@ function rspec_paralellized_job() {
date
}
+
+function rspec_matched_tests() {
+ local test_file_count_threshold=20
+ local matching_tests_file=${1}
+ local rspec_opts=${2}
+ local test_files="$(cat "${matching_tests_file}")"
+ local test_file_count=$(wc -w "${matching_tests_file}" | awk {'print $1'})
+
+ if [[ "${test_file_count}" -gt "${test_file_count_threshold}" ]]; then
+ echo "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 "This would run all as-if-foss jobs in this merge request"
+ echo "and remove this job from the pipeline."
+ exit 1
+ fi
+
+ if [[ -n $test_files ]]; then
+ rspec_simple_job "${rspec_opts} ${test_files}"
+ else
+ echo "No test files to run"
+ fi
+}
diff --git a/scripts/static-analysis b/scripts/static-analysis
index ede29b85b8d..9103a9c14af 100755
--- a/scripts/static-analysis
+++ b/scripts/static-analysis
@@ -5,103 +5,118 @@ require_relative '../lib/gitlab'
require_relative '../lib/gitlab/popen'
require_relative '../lib/gitlab/popen/runner'
-def emit_warnings(static_analysis)
- static_analysis.warned_results.each do |result|
- puts
- puts "**** #{result.cmd.join(' ')} had the following warning(s):"
- puts
- puts result.stderr
- puts
- end
-end
+class StaticAnalysis
+ ALLOWED_WARNINGS = [
+ # https://github.com/browserslist/browserslist/blob/d0ec62eb48c41c218478cd3ac28684df051cc865/node.js#L329
+ # warns if caniuse-lite package is older than 6 months. Ignore this
+ # warning message so that GitLab backports don't fail.
+ "Browserslist: caniuse-lite is outdated. Please run next command `yarn upgrade`"
+ ].freeze
+
+ # `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] => 338,
+ (Gitlab.ee? ? %w[bin/rake gettext:updated_check] : nil) => 308,
+ # Most of the time, RuboCop finishes in 30 seconds, but sometimes it can take around 1200 seconds so we set a
+ # duration of 300 to lower the likelihood that it will run in the same job as another long task...
+ %w[bundle exec rubocop --parallel] => 300,
+ %w[yarn run eslint] => 197,
+ %w[yarn run prettier-all] => 124,
+ %w[bin/rake gettext:lint] => 96,
+ %w[bundle exec license_finder] => 49,
+ %w[bin/rake scss_lint] => 38,
+ %w[bin/rake lint:static_verification] => 22,
+ %w[bin/rake gitlab:sidekiq:all_queues_yml:check] => 13,
+ (Gitlab.ee? ? %w[bin/rake gitlab:sidekiq:sidekiq_queues_yml:check] : nil) => 13,
+ %w[bin/rake config_lint] => 11,
+ %w[yarn run stylelint] => 9,
+ %w[scripts/lint-conflicts.sh] => 0.59,
+ %w[yarn run block-dependencies] => 0.35,
+ %w[scripts/lint-rugged] => 0.23,
+ %w[scripts/gemfile_lock_changed.sh] => 0.02,
+ %w[scripts/frontend/check_no_partial_karma_jest.sh] => 0.01,
+ %w[scripts/lint-changelog-filenames] => 0.01
+ }.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)
+
+ static_analysis = Gitlab::Popen::Runner.new
+
+ static_analysis.run(tasks) do |cmd, &run|
+ puts
+ puts "$ #{cmd.join(' ')}"
+
+ result = run.call
+
+ puts "==> Finished in #{result.duration} seconds"
+ puts
+ end
-def emit_errors(static_analysis)
- static_analysis.failed_results.each do |result|
puts
- puts "**** #{result.cmd.join(' ')} failed with the following error(s):"
+ puts '==================================================='
puts
- puts result.stdout
- puts result.stderr
puts
- end
-end
-ALLOWED_WARNINGS = [
- # https://github.com/browserslist/browserslist/blob/d0ec62eb48c41c218478cd3ac28684df051cc865/node.js#L329
- # warns if caniuse-lite package is older than 6 months. Ignore this
- # warning message so that GitLab backports don't fail.
- "Browserslist: caniuse-lite is outdated. Please run next command `yarn upgrade`"
-].freeze
+ if static_analysis.all_success_and_clean?
+ puts 'All static analyses passed successfully.'
+ elsif static_analysis.all_success?
+ puts 'All static analyses passed successfully, but we have warnings:'
+ puts
-def warning_count(static_analysis)
- static_analysis.warned_results
- .count { |result| !ALLOWED_WARNINGS.include?(result.stderr.strip) }
-end
+ emit_warnings(static_analysis)
-def jobs_to_run(node_index, node_total)
- all_tasks = [
- %w[bin/rake lint:all],
- %w[bundle exec license_finder],
- %w[yarn run eslint],
- %w[yarn run stylelint],
- %w[yarn run prettier-all],
- %w[yarn run block-dependencies],
- %w[bundle exec rubocop --parallel],
- %w[scripts/lint-conflicts.sh],
- %w[scripts/lint-rugged],
- %w[scripts/frontend/check_no_partial_karma_jest.sh],
- %w[scripts/lint-changelog-filenames],
- %w[scripts/gemfile_lock_changed.sh]
- ]
-
- case node_total
- when 1
- all_tasks
- when 2
- rake_lint_all, *rest_jobs = all_tasks
- case node_index
- when 1
- [rake_lint_all]
+ exit 2 if warning_count(static_analysis).nonzero?
else
- rest_jobs
- end
- else
- raise "Parallelization > 2 (currently set to #{node_total}) isn't supported yet!"
- end
-end
-
-tasks = jobs_to_run((ENV['CI_NODE_INDEX'] || 1).to_i, (ENV['CI_NODE_TOTAL'] || 1).to_i)
-static_analysis = Gitlab::Popen::Runner.new
+ puts 'Some static analyses failed:'
-static_analysis.run(tasks) do |cmd, &run|
- puts
- puts "$ #{cmd.join(' ')}"
+ emit_warnings(static_analysis)
+ emit_errors(static_analysis)
- result = run.call
-
- puts "==> Finished in #{result.duration} seconds"
- puts
-end
+ exit 1
+ end
+ end
-puts
-puts '==================================================='
-puts
-puts
+ def emit_warnings(static_analysis)
+ static_analysis.warned_results.each do |result|
+ puts
+ puts "**** #{result.cmd.join(' ')} had the following warning(s):"
+ puts
+ puts result.stderr
+ puts
+ end
+ end
-if static_analysis.all_success_and_clean?
- puts 'All static analyses passed successfully.'
-elsif static_analysis.all_success?
- puts 'All static analyses passed successfully, but we have warnings:'
- puts
+ def emit_errors(static_analysis)
+ static_analysis.failed_results.each do |result|
+ puts
+ puts "**** #{result.cmd.join(' ')} failed with the following error(s):"
+ puts
+ puts result.stdout
+ puts result.stderr
+ puts
+ end
+ end
- emit_warnings(static_analysis)
+ def warning_count(static_analysis)
+ static_analysis.warned_results
+ .count { |result| !ALLOWED_WARNINGS.include?(result.stderr.strip) }
+ end
- exit 2 if warning_count(static_analysis).nonzero?
-else
- puts 'Some static analyses failed:'
+ 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)
+ end
- emit_warnings(static_analysis)
- emit_errors(static_analysis)
+ tasks
+ end
+end
- exit 1
+if $0 == __FILE__
+ StaticAnalysis.new.run_tasks!
end
diff --git a/scripts/sync-stable-branch.sh b/scripts/sync-stable-branch.sh
index 5aaec323628..59ab52844fb 100644
--- a/scripts/sync-stable-branch.sh
+++ b/scripts/sync-stable-branch.sh
@@ -7,56 +7,56 @@ set -e
if [[ "$MERGE_TRAIN_TRIGGER_TOKEN" == '' ]]
then
- echo 'The variable MERGE_TRAIN_TRIGGER_TOKEN must be set to a non-empty value'
- exit 1
+ echo 'The variable MERGE_TRAIN_TRIGGER_TOKEN must be set to a non-empty value'
+ exit 1
fi
if [[ "$MERGE_TRAIN_TRIGGER_URL" == '' ]]
then
- echo 'The variable MERGE_TRAIN_TRIGGER_URL must be set to a non-empty value'
- exit 1
+ echo 'The variable MERGE_TRAIN_TRIGGER_URL must be set to a non-empty value'
+ exit 1
fi
if [[ "$CI_COMMIT_REF_NAME" == '' ]]
then
- echo 'The variable CI_COMMIT_REF_NAME must be set to a non-empty value'
- exit 1
+ echo 'The variable CI_COMMIT_REF_NAME must be set to a non-empty value'
+ exit 1
fi
if [[ "$SOURCE_PROJECT" == '' ]]
then
- echo 'The variable SOURCE_PROJECT must be set to a non-empty value'
- exit 1
+ echo 'The variable SOURCE_PROJECT must be set to a non-empty value'
+ exit 1
fi
if [[ "$TARGET_PROJECT" == '' ]]
then
- echo 'The variable TARGET_PROJECT must be set to a non-empty value'
- exit 1
+ echo 'The variable TARGET_PROJECT must be set to a non-empty value'
+ exit 1
fi
if [[ "$TARGET_PROJECT" != "gitlab-org/gitlab-foss" ]]
then
- echo 'This is a security FOSS merge train'
- echo "Checking if $CI_COMMIT_SHA is available on canonical"
+ echo 'This is a security FOSS merge train'
+ echo "Checking if $CI_COMMIT_SHA is available on canonical"
- gitlab_com_commit_status=$(curl -s "https://gitlab.com/api/v4/projects/278964/repository/commits/$CI_COMMIT_SHA" | jq -M .status)
+ gitlab_com_commit_status=$(curl -s "https://gitlab.com/api/v4/projects/278964/repository/commits/$CI_COMMIT_SHA" | jq -M .status)
- if [[ "$gitlab_com_commit_status" != "null" ]]
- then
- echo 'Commit available on canonical, skipping merge train'
- exit 0
- fi
+ if [[ "$gitlab_com_commit_status" != "null" ]]
+ then
+ echo 'Commit available on canonical, skipping merge train'
+ exit 0
+ fi
- echo 'Commit not available, triggering a merge train'
+ echo 'Commit not available, triggering a merge train'
fi
curl -X POST \
- -F token="$MERGE_TRAIN_TRIGGER_TOKEN" \
- -F ref=master \
- -F "variables[MERGE_FOSS]=1" \
- -F "variables[SOURCE_BRANCH]=$CI_COMMIT_REF_NAME" \
- -F "variables[TARGET_BRANCH]=${CI_COMMIT_REF_NAME/-ee/}" \
- -F "variables[SOURCE_PROJECT]=$SOURCE_PROJECT" \
- -F "variables[TARGET_PROJECT]=$TARGET_PROJECT" \
- "$MERGE_TRAIN_TRIGGER_URL"
+ -F token="$MERGE_TRAIN_TRIGGER_TOKEN" \
+ -F ref=master \
+ -F "variables[MERGE_FOSS]=1" \
+ -F "variables[SOURCE_BRANCH]=$CI_COMMIT_REF_NAME" \
+ -F "variables[TARGET_BRANCH]=${CI_COMMIT_REF_NAME/-ee/}" \
+ -F "variables[SOURCE_PROJECT]=$SOURCE_PROJECT" \
+ -F "variables[TARGET_PROJECT]=$TARGET_PROJECT" \
+ "$MERGE_TRAIN_TRIGGER_URL"
diff --git a/scripts/trigger-build b/scripts/trigger-build
index c7b45480bf3..b8bea95a069 100755
--- a/scripts/trigger-build
+++ b/scripts/trigger-build
@@ -16,6 +16,10 @@ module Trigger
%w[gitlab gitlab-ee].include?(ENV['CI_PROJECT_NAME'])
end
+ def self.security?
+ %r{\Agitlab-org/security(\z|/)}.match?(ENV['CI_PROJECT_NAMESPACE'])
+ end
+
def self.non_empty_variable_value(variable)
variable_value = ENV[variable]
@@ -26,6 +30,9 @@ module Trigger
class Base
def invoke!(post_comment: false, downstream_job_name: nil)
+ # gitlab-bot's token "GitLab multi-project pipeline polling"
+ Gitlab.private_token = access_token
+
pipeline_variables = variables
puts "Triggering downstream pipeline on #{downstream_project_path}"
@@ -40,7 +47,7 @@ module Trigger
puts "Triggered downstream pipeline: #{pipeline.web_url}\n"
puts "Waiting for downstream pipeline status"
- Trigger::CommitComment.post!(pipeline, access_token) if post_comment
+ Trigger::CommitComment.post!(pipeline) if post_comment
downstream_job =
if downstream_job_name
Gitlab.pipeline_jobs(downstream_project_path, pipeline.id).auto_paginate.find do |potential_job|
@@ -49,9 +56,9 @@ module Trigger
end
if downstream_job
- Trigger::Job.new(downstream_project_path, downstream_job.id, access_token)
+ Trigger::Job.new(downstream_project_path, downstream_job.id)
else
- Trigger::Pipeline.new(downstream_project_path, pipeline.id, access_token)
+ Trigger::Pipeline.new(downstream_project_path, pipeline.id)
end
end
@@ -140,6 +147,7 @@ module Trigger
{
'GITLAB_VERSION' => Trigger.non_empty_variable_value('CI_MERGE_REQUEST_SOURCE_BRANCH_SHA') || ENV['CI_COMMIT_SHA'],
'ALTERNATIVE_SOURCES' => 'true',
+ 'SECURITY_SOURCES' => Trigger.security? ? 'true' : 'false',
'ee' => Trigger.ee? ? 'true' : 'false',
'QA_BRANCH' => ENV['QA_BRANCH'] || 'master'
}
@@ -197,9 +205,7 @@ module Trigger
end
class CommitComment
- def self.post!(downstream_pipeline, access_token)
- Gitlab.private_token = access_token
-
+ def self.post!(downstream_pipeline)
Gitlab.create_commit_comment(
ENV['CI_PROJECT_PATH'],
Trigger.non_empty_variable_value('CI_MERGE_REQUEST_SOURCE_BRANCH_SHA') || ENV['CI_COMMIT_SHA'],
@@ -214,7 +220,7 @@ module Trigger
INTERVAL = 60 # seconds
MAX_DURATION = 3600 * 3 # 3 hours
- attr_reader :project, :id, :api_token
+ attr_reader :project, :id
def self.unscoped_class_name
name.split('::').last
@@ -224,14 +230,10 @@ module Trigger
unscoped_class_name.downcase
end
- def initialize(project, id, api_token)
+ def initialize(project, id)
@project = project
@id = id
- @api_token = api_token
@start = Time.now.to_i
-
- # gitlab-bot's token "GitLab multi-project pipeline polling"
- Gitlab.private_token = api_token
end
def wait!
diff --git a/scripts/utils.sh b/scripts/utils.sh
index 897f8d5a8b8..f81e5c8982a 100644
--- a/scripts/utils.sh
+++ b/scripts/utils.sh
@@ -1,25 +1,25 @@
function retry() {
+ if eval "$@"; then
+ return 0
+ fi
+
+ for i in 2 1; do
+ sleep 3s
+ echo "Retrying $i..."
if eval "$@"; then
- return 0
+ return 0
fi
-
- for i in 2 1; do
- sleep 3s
- echo "Retrying $i..."
- if eval "$@"; then
- return 0
- fi
- done
- return 1
+ done
+ return 1
}
function setup_db_user_only() {
- source scripts/create_postgres_user.sh
+ source scripts/create_postgres_user.sh
}
function setup_db() {
- run_timed_command "setup_db_user_only"
- run_timed_command "bundle exec rake db:drop db:create db:structure:load db:migrate gitlab:db:setup_ee"
+ run_timed_command "setup_db_user_only"
+ run_timed_command "bundle exec rake db:drop db:create db:structure:load db:migrate gitlab:db:setup_ee"
}
function install_api_client_dependencies_with_apk() {
diff --git a/spec/bin/changelog_spec.rb b/spec/bin/changelog_spec.rb
index ce7f7648c0c..8a86f574bf5 100644
--- a/spec/bin/changelog_spec.rb
+++ b/spec/bin/changelog_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
load File.expand_path('../../bin/changelog', __dir__)
-describe 'bin/changelog' do
+RSpec.describe 'bin/changelog' do
let(:options) { OpenStruct.new(title: 'Test title', type: 'fixed', dry_run: true) }
describe ChangelogEntry do
diff --git a/spec/bin/sidekiq_cluster_spec.rb b/spec/bin/sidekiq_cluster_spec.rb
index c0240214a6b..fc5e2ae861a 100644
--- a/spec/bin/sidekiq_cluster_spec.rb
+++ b/spec/bin/sidekiq_cluster_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require 'shellwords'
-describe 'bin/sidekiq-cluster' do
+RSpec.describe 'bin/sidekiq-cluster' do
using RSpec::Parameterized::TableSyntax
context 'when selecting some queues and excluding others' do
diff --git a/spec/channels/application_cable/connection_spec.rb b/spec/channels/application_cable/connection_spec.rb
index f3d67133528..e5f7ea1103c 100644
--- a/spec/channels/application_cable/connection_spec.rb
+++ b/spec/channels/application_cable/connection_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ApplicationCable::Connection, :clean_gitlab_redis_shared_state do
+RSpec.describe ApplicationCable::Connection, :clean_gitlab_redis_shared_state do
let(:session_id) { Rack::Session::SessionId.new('6919a6f1bb119dd7396fadc38fd18d0d') }
before do
diff --git a/spec/channels/issues_channel_spec.rb b/spec/channels/issues_channel_spec.rb
index 1c88cc73456..4c860402f03 100644
--- a/spec/channels/issues_channel_spec.rb
+++ b/spec/channels/issues_channel_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe IssuesChannel do
+RSpec.describe IssuesChannel do
let_it_be(:issue) { create(:issue) }
it 'rejects when project path is invalid' do
@@ -18,7 +18,7 @@ describe IssuesChannel do
end
it 'rejects when the user does not have access' do
- stub_connection current_user: nil
+ stub_action_cable_connection current_user: nil
subscribe(project_path: issue.project.full_path, iid: issue.iid)
@@ -26,7 +26,7 @@ describe IssuesChannel do
end
it 'subscribes to a stream when the user has access' do
- stub_connection current_user: issue.author
+ stub_action_cable_connection current_user: issue.author
subscribe(project_path: issue.project.full_path, iid: issue.iid)
diff --git a/spec/config/application_spec.rb b/spec/config/application_spec.rb
index e6b8da690a2..94fecc26e7f 100644
--- a/spec/config/application_spec.rb
+++ b/spec/config/application_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Gitlab::Application do # rubocop:disable RSpec/FilePath
+RSpec.describe Gitlab::Application do # rubocop:disable RSpec/FilePath
using RSpec::Parameterized::TableSyntax
filtered_param = ActiveSupport::ParameterFilter::FILTERED
diff --git a/spec/config/mail_room_spec.rb b/spec/config/mail_room_spec.rb
index bd8269fb2c5..206f2744281 100644
--- a/spec/config/mail_room_spec.rb
+++ b/spec/config/mail_room_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'mail_room.yml' do
+RSpec.describe 'mail_room.yml' do
include StubENV
let(:mailroom_config_path) { 'config/mail_room.yml' }
diff --git a/spec/config/object_store_settings_spec.rb b/spec/config/object_store_settings_spec.rb
index c38910cff0a..67e77aa4466 100644
--- a/spec/config/object_store_settings_spec.rb
+++ b/spec/config/object_store_settings_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require Rails.root.join('config', 'object_store_settings.rb')
-describe ObjectStoreSettings do
+RSpec.describe ObjectStoreSettings do
describe '.parse' do
it 'sets correct default values' do
settings = described_class.parse(nil)
diff --git a/spec/config/settings_spec.rb b/spec/config/settings_spec.rb
index 20c0b92f135..9db3d35cbe5 100644
--- a/spec/config/settings_spec.rb
+++ b/spec/config/settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Settings do
+RSpec.describe Settings do
describe 'omniauth' do
it 'defaults to enabled' do
expect(described_class.omniauth.enabled).to be true
diff --git a/spec/config/smime_signature_settings_spec.rb b/spec/config/smime_signature_settings_spec.rb
index 7e7b42b129a..5ce6fdd975b 100644
--- a/spec/config/smime_signature_settings_spec.rb
+++ b/spec/config/smime_signature_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe SmimeSignatureSettings do
+RSpec.describe SmimeSignatureSettings do
describe '.parse' do
let(:default_smime_key) { Rails.root.join('.gitlab_smime_key') }
let(:default_smime_cert) { Rails.root.join('.gitlab_smime_cert') }
diff --git a/spec/controllers/abuse_reports_controller_spec.rb b/spec/controllers/abuse_reports_controller_spec.rb
index 087b564dddb..da7577c371d 100644
--- a/spec/controllers/abuse_reports_controller_spec.rb
+++ b/spec/controllers/abuse_reports_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe AbuseReportsController do
+RSpec.describe AbuseReportsController do
let(:reporter) { create(:user) }
let(:user) { create(:user) }
let(:attrs) do
diff --git a/spec/controllers/acme_challenges_controller_spec.rb b/spec/controllers/acme_challenges_controller_spec.rb
index be077a4b20d..e737999fa2d 100644
--- a/spec/controllers/acme_challenges_controller_spec.rb
+++ b/spec/controllers/acme_challenges_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe AcmeChallengesController do
+RSpec.describe AcmeChallengesController do
describe '#show' do
let!(:acme_order) { create(:pages_domain_acme_order) }
diff --git a/spec/controllers/admin/appearances_controller_spec.rb b/spec/controllers/admin/appearances_controller_spec.rb
index 621aa148301..ee6a4a4c7af 100644
--- a/spec/controllers/admin/appearances_controller_spec.rb
+++ b/spec/controllers/admin/appearances_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::AppearancesController do
+RSpec.describe Admin::AppearancesController do
let(:admin) { create(:admin) }
let(:header_message) { 'Header message' }
let(:footer_message) { 'Footer' }
diff --git a/spec/controllers/admin/application_settings_controller_spec.rb b/spec/controllers/admin/application_settings_controller_spec.rb
index fe28e791ade..8ab29a72477 100644
--- a/spec/controllers/admin/application_settings_controller_spec.rb
+++ b/spec/controllers/admin/application_settings_controller_spec.rb
@@ -2,8 +2,9 @@
require 'spec_helper'
-describe Admin::ApplicationSettingsController do
+RSpec.describe Admin::ApplicationSettingsController do
include StubENV
+ include UsageDataHelpers
let(:group) { create(:group) }
let(:project) { create(:project, namespace: group) }
@@ -16,7 +17,7 @@ describe Admin::ApplicationSettingsController do
describe 'GET #usage_data with no access' do
before do
- allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false)
+ stub_usage_data_connections
sign_in(user)
end
@@ -29,7 +30,7 @@ describe Admin::ApplicationSettingsController do
describe 'GET #usage_data' do
before do
- allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false)
+ stub_usage_data_connections
sign_in(admin)
end
@@ -120,6 +121,13 @@ describe Admin::ApplicationSettingsController do
expect(ApplicationSetting.current.namespace_storage_size_limit).not_to eq(-100)
end
+ it 'updates repository_storages_weighted setting' do
+ put :update, params: { application_setting: { repository_storages_weighted_default: 75 } }
+
+ expect(response).to redirect_to(general_admin_application_settings_path)
+ expect(ApplicationSetting.current.repository_storages_weighted_default).to eq(75)
+ end
+
context 'external policy classification settings' do
let(:settings) do
{
diff --git a/spec/controllers/admin/applications_controller_spec.rb b/spec/controllers/admin/applications_controller_spec.rb
index 163a2033b58..732d20666cb 100644
--- a/spec/controllers/admin/applications_controller_spec.rb
+++ b/spec/controllers/admin/applications_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::ApplicationsController do
+RSpec.describe Admin::ApplicationsController do
let(:admin) { create(:admin) }
let(:application) { create(:oauth_application, owner_id: nil, owner_type: nil) }
diff --git a/spec/controllers/admin/ci/variables_controller_spec.rb b/spec/controllers/admin/ci/variables_controller_spec.rb
index 57f2dd21f39..9f0a1bd3be1 100644
--- a/spec/controllers/admin/ci/variables_controller_spec.rb
+++ b/spec/controllers/admin/ci/variables_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::Ci::VariablesController do
+RSpec.describe Admin::Ci::VariablesController do
let_it_be(:variable) { create(:ci_instance_variable) }
before do
diff --git a/spec/controllers/admin/clusters/applications_controller_spec.rb b/spec/controllers/admin/clusters/applications_controller_spec.rb
index 44693505c4f..2a77693061c 100644
--- a/spec/controllers/admin/clusters/applications_controller_spec.rb
+++ b/spec/controllers/admin/clusters/applications_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::Clusters::ApplicationsController do
+RSpec.describe Admin::Clusters::ApplicationsController do
include AccessMatchersForController
def current_application
diff --git a/spec/controllers/admin/clusters_controller_spec.rb b/spec/controllers/admin/clusters_controller_spec.rb
index d4a12e0dc52..d899e86ae5f 100644
--- a/spec/controllers/admin/clusters_controller_spec.rb
+++ b/spec/controllers/admin/clusters_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::ClustersController do
+RSpec.describe Admin::ClustersController do
include AccessMatchersForController
include GoogleApi::CloudPlatformHelpers
@@ -42,6 +42,13 @@ describe Admin::ClustersController do
expect(response).to match_response_schema('cluster_list')
end
+ it 'sets the polling interval header for json requests' do
+ get_index(format: :json)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.headers['Poll-Interval']).to eq("10000")
+ end
+
context 'when page is specified' do
let(:last_page) { Clusters::Cluster.instance_type.page.total_pages }
let(:total_count) { Clusters::Cluster.instance_type.page.total_count }
diff --git a/spec/controllers/admin/dashboard_controller_spec.rb b/spec/controllers/admin/dashboard_controller_spec.rb
index 4de69a9aea1..283d82a3ab8 100644
--- a/spec/controllers/admin/dashboard_controller_spec.rb
+++ b/spec/controllers/admin/dashboard_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::DashboardController do
+RSpec.describe Admin::DashboardController do
describe '#index' do
context 'with pending_delete projects' do
render_views
diff --git a/spec/controllers/admin/gitaly_servers_controller_spec.rb b/spec/controllers/admin/gitaly_servers_controller_spec.rb
index db94ea06f59..53f8a06ab52 100644
--- a/spec/controllers/admin/gitaly_servers_controller_spec.rb
+++ b/spec/controllers/admin/gitaly_servers_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::GitalyServersController do
+RSpec.describe Admin::GitalyServersController do
describe '#index' do
before do
sign_in(create(:admin))
diff --git a/spec/controllers/admin/groups_controller_spec.rb b/spec/controllers/admin/groups_controller_spec.rb
index 1123563c1e3..3f32209543f 100644
--- a/spec/controllers/admin/groups_controller_spec.rb
+++ b/spec/controllers/admin/groups_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::GroupsController do
+RSpec.describe Admin::GroupsController do
let(:group) { create(:group) }
let(:project) { create(:project, namespace: group) }
let(:admin) { create(:admin) }
diff --git a/spec/controllers/admin/health_check_controller_spec.rb b/spec/controllers/admin/health_check_controller_spec.rb
index cf5b27156c0..06aace429e3 100644
--- a/spec/controllers/admin/health_check_controller_spec.rb
+++ b/spec/controllers/admin/health_check_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::HealthCheckController do
+RSpec.describe Admin::HealthCheckController do
let(:admin) { create(:admin) }
before do
diff --git a/spec/controllers/admin/hooks_controller_spec.rb b/spec/controllers/admin/hooks_controller_spec.rb
index 9973ef93cd9..8975f746dd7 100644
--- a/spec/controllers/admin/hooks_controller_spec.rb
+++ b/spec/controllers/admin/hooks_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::HooksController do
+RSpec.describe Admin::HooksController do
let(:admin) { create(:admin) }
before do
diff --git a/spec/controllers/admin/identities_controller_spec.rb b/spec/controllers/admin/identities_controller_spec.rb
index f483c88d18d..6ac5ce13884 100644
--- a/spec/controllers/admin/identities_controller_spec.rb
+++ b/spec/controllers/admin/identities_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::IdentitiesController do
+RSpec.describe Admin::IdentitiesController do
let(:admin) { create(:admin) }
before do
diff --git a/spec/controllers/admin/impersonations_controller_spec.rb b/spec/controllers/admin/impersonations_controller_spec.rb
index fa3923bca8c..326003acaf8 100644
--- a/spec/controllers/admin/impersonations_controller_spec.rb
+++ b/spec/controllers/admin/impersonations_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::ImpersonationsController do
+RSpec.describe Admin::ImpersonationsController do
let(:impersonator) { create(:admin) }
let(:user) { create(:user) }
diff --git a/spec/controllers/admin/integrations_controller_spec.rb b/spec/controllers/admin/integrations_controller_spec.rb
index 817223bd91a..7e7b60db2dc 100644
--- a/spec/controllers/admin/integrations_controller_spec.rb
+++ b/spec/controllers/admin/integrations_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::IntegrationsController do
+RSpec.describe Admin::IntegrationsController do
let(:admin) { create(:admin) }
before do
@@ -36,7 +36,9 @@ describe Admin::IntegrationsController do
let(:integration) { create(:jira_service, :instance) }
before do
- put :update, params: { id: integration.class.to_param, service: { url: url } }
+ allow(PropagateIntegrationWorker).to receive(:perform_async)
+
+ put :update, params: { id: integration.class.to_param, overwrite: true, service: { url: url } }
end
context 'valid params' do
@@ -46,6 +48,10 @@ describe Admin::IntegrationsController do
expect(response).to have_gitlab_http_status(:found)
expect(integration.reload.url).to eq(url)
end
+
+ it 'calls to PropagateIntegrationWorker' do
+ expect(PropagateIntegrationWorker).to have_received(:perform_async).with(integration.id, true)
+ end
end
context 'invalid params' do
@@ -56,6 +62,10 @@ describe Admin::IntegrationsController do
expect(response).to render_template(:edit)
expect(integration.reload.url).not_to eq(url)
end
+
+ it 'does not call to PropagateIntegrationWorker' do
+ expect(PropagateIntegrationWorker).not_to have_received(:perform_async)
+ end
end
end
end
diff --git a/spec/controllers/admin/projects_controller_spec.rb b/spec/controllers/admin/projects_controller_spec.rb
index f0157fb4260..b5f411c9121 100644
--- a/spec/controllers/admin/projects_controller_spec.rb
+++ b/spec/controllers/admin/projects_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::ProjectsController do
+RSpec.describe Admin::ProjectsController do
let!(:project) { create(:project, :public) }
before do
diff --git a/spec/controllers/admin/requests_profiles_controller_spec.rb b/spec/controllers/admin/requests_profiles_controller_spec.rb
index 629233b04e7..7ee46b5b28a 100644
--- a/spec/controllers/admin/requests_profiles_controller_spec.rb
+++ b/spec/controllers/admin/requests_profiles_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::RequestsProfilesController do
+RSpec.describe Admin::RequestsProfilesController do
let_it_be(:admin) { create(:admin) }
before do
diff --git a/spec/controllers/admin/runners_controller_spec.rb b/spec/controllers/admin/runners_controller_spec.rb
index 803fcf90135..013eee19409 100644
--- a/spec/controllers/admin/runners_controller_spec.rb
+++ b/spec/controllers/admin/runners_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::RunnersController do
+RSpec.describe Admin::RunnersController do
let_it_be(:runner) { create(:ci_runner) }
before do
diff --git a/spec/controllers/admin/serverless/domains_controller_spec.rb b/spec/controllers/admin/serverless/domains_controller_spec.rb
index 43c3f0117bc..e7503fb37fa 100644
--- a/spec/controllers/admin/serverless/domains_controller_spec.rb
+++ b/spec/controllers/admin/serverless/domains_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::Serverless::DomainsController do
+RSpec.describe Admin::Serverless::DomainsController do
let(:admin) { create(:admin) }
let(:user) { create(:user) }
diff --git a/spec/controllers/admin/services_controller_spec.rb b/spec/controllers/admin/services_controller_spec.rb
index 5dde0d57293..2ad4989af4f 100644
--- a/spec/controllers/admin/services_controller_spec.rb
+++ b/spec/controllers/admin/services_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::ServicesController do
+RSpec.describe Admin::ServicesController do
let(:admin) { create(:admin) }
before do
diff --git a/spec/controllers/admin/sessions_controller_spec.rb b/spec/controllers/admin/sessions_controller_spec.rb
index 351148dbc65..82366cc6952 100644
--- a/spec/controllers/admin/sessions_controller_spec.rb
+++ b/spec/controllers/admin/sessions_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::SessionsController, :do_not_mock_admin_mode do
+RSpec.describe Admin::SessionsController, :do_not_mock_admin_mode do
include_context 'custom session'
let(:user) { create(:user) }
diff --git a/spec/controllers/admin/spam_logs_controller_spec.rb b/spec/controllers/admin/spam_logs_controller_spec.rb
index ec0d8c47660..13038339d08 100644
--- a/spec/controllers/admin/spam_logs_controller_spec.rb
+++ b/spec/controllers/admin/spam_logs_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::SpamLogsController do
+RSpec.describe Admin::SpamLogsController do
let(:admin) { create(:admin) }
let(:user) { create(:user) }
let!(:first_spam) { create(:spam_log, user: user) }
diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb
index 7a7201a6454..08a1d7c9fa9 100644
--- a/spec/controllers/admin/users_controller_spec.rb
+++ b/spec/controllers/admin/users_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::UsersController do
+RSpec.describe Admin::UsersController do
let(:user) { create(:user) }
let_it_be(:admin) { create(:admin) }
@@ -254,6 +254,18 @@ describe Admin::UsersController do
errors = assigns[:user].errors
expect(errors).to contain_exactly(errors.full_message(:email, I18n.t('errors.messages.invalid')))
end
+
+ context 'admin notes' do
+ it 'creates the user with note' do
+ note = '2020-05-12 | Note | DCMA | Link'
+ user_params = attributes_for(:user, note: note)
+
+ expect { post :create, params: { user: user_params } }.to change { User.count }.by(1)
+
+ new_user = User.last
+ expect(new_user.note).to eq(note)
+ end
+ end
end
describe 'POST update' do
@@ -338,6 +350,20 @@ describe Admin::UsersController do
end
end
end
+
+ context 'admin notes' do
+ it 'updates the note for the user' do
+ note = '2020-05-12 | Note | DCMA | Link'
+ params = {
+ id: user.to_param,
+ user: {
+ note: note
+ }
+ }
+
+ expect { post :update, params: params }.to change { user.reload.note }.to(note)
+ end
+ end
end
describe "DELETE #remove_email" do
diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb
index ed2e61d6cf6..4002b7aca63 100644
--- a/spec/controllers/application_controller_spec.rb
+++ b/spec/controllers/application_controller_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe ApplicationController do
+RSpec.describe ApplicationController do
include TermsHelper
let(:user) { create(:user) }
@@ -310,13 +310,6 @@ describe ApplicationController do
expect(subject).to be_truthy
end
-
- it 'returns true if user has signed up using omniauth-ultraauth' do
- user = create(:omniauth_user, provider: 'ultraauth')
- allow(controller).to receive(:current_user).and_return(user)
-
- expect(subject).to be_truthy
- end
end
describe '#two_factor_grace_period' do
diff --git a/spec/controllers/autocomplete_controller_spec.rb b/spec/controllers/autocomplete_controller_spec.rb
index 7b1e9748268..aeb3f4dcb17 100644
--- a/spec/controllers/autocomplete_controller_spec.rb
+++ b/spec/controllers/autocomplete_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe AutocompleteController do
+RSpec.describe AutocompleteController do
let(:project) { create(:project) }
let(:user) { project.owner }
diff --git a/spec/controllers/boards/issues_controller_spec.rb b/spec/controllers/boards/issues_controller_spec.rb
index 8639b76ef0f..601b8d427e0 100644
--- a/spec/controllers/boards/issues_controller_spec.rb
+++ b/spec/controllers/boards/issues_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Boards::IssuesController do
+RSpec.describe Boards::IssuesController do
include ExternalAuthorizationServiceHelpers
let(:project) { create(:project, :private) }
diff --git a/spec/controllers/boards/lists_controller_spec.rb b/spec/controllers/boards/lists_controller_spec.rb
index d0b34b55c36..c72d9e5053a 100644
--- a/spec/controllers/boards/lists_controller_spec.rb
+++ b/spec/controllers/boards/lists_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Boards::ListsController do
+RSpec.describe Boards::ListsController do
let(:project) { create(:project) }
let(:board) { create(:board, project: project) }
let(:user) { create(:user) }
diff --git a/spec/controllers/chaos_controller_spec.rb b/spec/controllers/chaos_controller_spec.rb
index 5812990ce7a..550303d292a 100644
--- a/spec/controllers/chaos_controller_spec.rb
+++ b/spec/controllers/chaos_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ChaosController do
+RSpec.describe ChaosController do
describe '#leakmem' do
it 'calls synchronously' do
expect(Gitlab::Chaos).to receive(:leak_mem).with(100, 30.seconds)
diff --git a/spec/controllers/concerns/boards_responses_spec.rb b/spec/controllers/concerns/boards_responses_spec.rb
index bdebdf94761..553a547d42c 100644
--- a/spec/controllers/concerns/boards_responses_spec.rb
+++ b/spec/controllers/concerns/boards_responses_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe BoardsResponses do
+RSpec.describe BoardsResponses do
let(:controller_class) do
Class.new do
include BoardsResponses
diff --git a/spec/controllers/concerns/checks_collaboration_spec.rb b/spec/controllers/concerns/checks_collaboration_spec.rb
index 7187e239486..be8beff5dd6 100644
--- a/spec/controllers/concerns/checks_collaboration_spec.rb
+++ b/spec/controllers/concerns/checks_collaboration_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ChecksCollaboration do
+RSpec.describe ChecksCollaboration do
include ProjectForksHelper
let(:helper) do
diff --git a/spec/controllers/concerns/confirm_email_warning_spec.rb b/spec/controllers/concerns/confirm_email_warning_spec.rb
index 93e3423261c..24ee6fb30d2 100644
--- a/spec/controllers/concerns/confirm_email_warning_spec.rb
+++ b/spec/controllers/concerns/confirm_email_warning_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ConfirmEmailWarning do
+RSpec.describe ConfirmEmailWarning do
before do
stub_feature_flags(soft_email_confirmation: true)
end
diff --git a/spec/controllers/concerns/continue_params_spec.rb b/spec/controllers/concerns/continue_params_spec.rb
index 6af01aa837c..c010e8ffbd0 100644
--- a/spec/controllers/concerns/continue_params_spec.rb
+++ b/spec/controllers/concerns/continue_params_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ContinueParams do
+RSpec.describe ContinueParams do
let(:controller_class) do
Class.new(ActionController::Base) do
include ContinueParams
diff --git a/spec/controllers/concerns/controller_with_cross_project_access_check_spec.rb b/spec/controllers/concerns/controller_with_cross_project_access_check_spec.rb
index 3f9d690837b..a58b83dc42c 100644
--- a/spec/controllers/concerns/controller_with_cross_project_access_check_spec.rb
+++ b/spec/controllers/concerns/controller_with_cross_project_access_check_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ControllerWithCrossProjectAccessCheck do
+RSpec.describe ControllerWithCrossProjectAccessCheck do
let(:user) { create(:user) }
before do
diff --git a/spec/controllers/concerns/enforces_admin_authentication_spec.rb b/spec/controllers/concerns/enforces_admin_authentication_spec.rb
index 1809bb2d636..c6ad1a00484 100644
--- a/spec/controllers/concerns/enforces_admin_authentication_spec.rb
+++ b/spec/controllers/concerns/enforces_admin_authentication_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe EnforcesAdminAuthentication do
+RSpec.describe EnforcesAdminAuthentication do
include AdminModeHelper
let(:user) { create(:user) }
diff --git a/spec/controllers/concerns/group_tree_spec.rb b/spec/controllers/concerns/group_tree_spec.rb
index 543f0170be0..a0707688e54 100644
--- a/spec/controllers/concerns/group_tree_spec.rb
+++ b/spec/controllers/concerns/group_tree_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe GroupTree do
+RSpec.describe GroupTree do
let(:group) { create(:group, :public) }
let(:user) { create(:user) }
diff --git a/spec/controllers/concerns/import_url_params_spec.rb b/spec/controllers/concerns/import_url_params_spec.rb
index 41e29d71386..72f13cdcc94 100644
--- a/spec/controllers/concerns/import_url_params_spec.rb
+++ b/spec/controllers/concerns/import_url_params_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ImportUrlParams do
+RSpec.describe ImportUrlParams do
let(:import_url_params) do
controller = OpenStruct.new(params: params).extend(described_class)
controller.import_url_params
diff --git a/spec/controllers/concerns/internal_redirect_spec.rb b/spec/controllers/concerns/internal_redirect_spec.rb
index cc6422f2817..3741ff647e4 100644
--- a/spec/controllers/concerns/internal_redirect_spec.rb
+++ b/spec/controllers/concerns/internal_redirect_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe InternalRedirect do
+RSpec.describe InternalRedirect do
let(:controller_class) do
Class.new do
include InternalRedirect
diff --git a/spec/controllers/concerns/issuable_actions_spec.rb b/spec/controllers/concerns/issuable_actions_spec.rb
index 2ab46992b99..c3fef591b91 100644
--- a/spec/controllers/concerns/issuable_actions_spec.rb
+++ b/spec/controllers/concerns/issuable_actions_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe IssuableActions do
+RSpec.describe IssuableActions do
let(:project) { double('project') }
let(:user) { double('user') }
let(:issuable) { double('issuable') }
diff --git a/spec/controllers/concerns/issuable_collections_spec.rb b/spec/controllers/concerns/issuable_collections_spec.rb
index 7bdf5c49425..befdd760965 100644
--- a/spec/controllers/concerns/issuable_collections_spec.rb
+++ b/spec/controllers/concerns/issuable_collections_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe IssuableCollections do
+RSpec.describe IssuableCollections do
let(:user) { create(:user) }
let(:controller) do
diff --git a/spec/controllers/concerns/lfs_request_spec.rb b/spec/controllers/concerns/lfs_request_spec.rb
index f771a3438cf..3bafd761a3e 100644
--- a/spec/controllers/concerns/lfs_request_spec.rb
+++ b/spec/controllers/concerns/lfs_request_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe LfsRequest do
+RSpec.describe LfsRequest do
include ProjectForksHelper
controller(Repositories::GitHttpClientController) do
diff --git a/spec/controllers/concerns/metrics_dashboard_spec.rb b/spec/controllers/concerns/metrics_dashboard_spec.rb
index e2fa03670d9..39ddf687dca 100644
--- a/spec/controllers/concerns/metrics_dashboard_spec.rb
+++ b/spec/controllers/concerns/metrics_dashboard_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MetricsDashboard do
+RSpec.describe MetricsDashboard do
include MetricsDashboardHelpers
describe 'GET #metrics_dashboard' do
@@ -134,7 +134,7 @@ describe MetricsDashboard do
it 'adds starred dashboard information and sorts the list' do
all_dashboards = json_response['all_dashboards'].map { |dashboard| dashboard.slice('display_name', 'starred', 'user_starred_path') }
expected_response = [
- { "display_name" => "Default", "starred" => false, 'user_starred_path' => api_v4_projects_metrics_user_starred_dashboards_path(id: project.id, params: { dashboard_path: 'config/prometheus/common_metrics.yml' }) },
+ { "display_name" => "Default dashboard", "starred" => false, 'user_starred_path' => api_v4_projects_metrics_user_starred_dashboards_path(id: project.id, params: { dashboard_path: 'config/prometheus/common_metrics.yml' }) },
{ "display_name" => "anomaly.yml", "starred" => false, 'user_starred_path' => api_v4_projects_metrics_user_starred_dashboards_path(id: project.id, params: { dashboard_path: '.gitlab/dashboards/anomaly.yml' }) },
{ "display_name" => "errors.yml", "starred" => true, 'user_starred_path' => api_v4_projects_metrics_user_starred_dashboards_path(id: project.id, params: { dashboard_path: '.gitlab/dashboards/errors.yml' }) },
{ "display_name" => "test.yml", "starred" => true, 'user_starred_path' => api_v4_projects_metrics_user_starred_dashboards_path(id: project.id, params: { dashboard_path: '.gitlab/dashboards/test.yml' }) }
diff --git a/spec/controllers/concerns/page_limiter_spec.rb b/spec/controllers/concerns/page_limiter_spec.rb
index 287b62cb66c..a4177943c05 100644
--- a/spec/controllers/concerns/page_limiter_spec.rb
+++ b/spec/controllers/concerns/page_limiter_spec.rb
@@ -14,7 +14,7 @@ class PageLimiterSpecController < ApplicationController
end
end
-describe PageLimiter do
+RSpec.describe PageLimiter do
let(:controller_class) do
PageLimiterSpecController
end
diff --git a/spec/controllers/concerns/project_unauthorized_spec.rb b/spec/controllers/concerns/project_unauthorized_spec.rb
index 9b40660811e..4fce160cdaf 100644
--- a/spec/controllers/concerns/project_unauthorized_spec.rb
+++ b/spec/controllers/concerns/project_unauthorized_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ProjectUnauthorized do
+RSpec.describe ProjectUnauthorized do
include ExternalAuthorizationServiceHelpers
let(:user) { create(:user) }
diff --git a/spec/controllers/concerns/redirects_for_missing_path_on_tree_spec.rb b/spec/controllers/concerns/redirects_for_missing_path_on_tree_spec.rb
index 903100ba93f..5c3b6e13ee3 100644
--- a/spec/controllers/concerns/redirects_for_missing_path_on_tree_spec.rb
+++ b/spec/controllers/concerns/redirects_for_missing_path_on_tree_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe RedirectsForMissingPathOnTree, type: :controller do
+RSpec.describe RedirectsForMissingPathOnTree, type: :controller do
controller(ActionController::Base) do
include Gitlab::Routing.url_helpers
include RedirectsForMissingPathOnTree
diff --git a/spec/controllers/concerns/renders_commits_spec.rb b/spec/controllers/concerns/renders_commits_spec.rb
index c43ceb6b795..0bffb39d608 100644
--- a/spec/controllers/concerns/renders_commits_spec.rb
+++ b/spec/controllers/concerns/renders_commits_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe RendersCommits do
+RSpec.describe RendersCommits do
let_it_be(:project) { create(:project, :public, :repository) }
let_it_be(:merge_request) { create(:merge_request, source_project: project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/concerns/routable_actions_spec.rb b/spec/controllers/concerns/routable_actions_spec.rb
index 80c67022219..f28f990ecbb 100644
--- a/spec/controllers/concerns/routable_actions_spec.rb
+++ b/spec/controllers/concerns/routable_actions_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe RoutableActions do
+RSpec.describe RoutableActions do
controller(::ApplicationController) do
include RoutableActions
diff --git a/spec/controllers/concerns/send_file_upload_spec.rb b/spec/controllers/concerns/send_file_upload_spec.rb
index 3cfb7b5a488..7cfaf1b248f 100644
--- a/spec/controllers/concerns/send_file_upload_spec.rb
+++ b/spec/controllers/concerns/send_file_upload_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe SendFileUpload do
+RSpec.describe SendFileUpload do
let(:uploader_class) do
Class.new(GitlabUploader) do
include ObjectStorage::Concern
diff --git a/spec/controllers/concerns/sorting_preference_spec.rb b/spec/controllers/concerns/sorting_preference_spec.rb
index a36124c6776..4f9506d4675 100644
--- a/spec/controllers/concerns/sorting_preference_spec.rb
+++ b/spec/controllers/concerns/sorting_preference_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe SortingPreference do
+RSpec.describe SortingPreference do
let(:user) { create(:user) }
let(:controller_class) do
diff --git a/spec/controllers/concerns/sourcegraph_decorator_spec.rb b/spec/controllers/concerns/sourcegraph_decorator_spec.rb
index f1f3f0489c6..2fca5a606d8 100644
--- a/spec/controllers/concerns/sourcegraph_decorator_spec.rb
+++ b/spec/controllers/concerns/sourcegraph_decorator_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe SourcegraphDecorator do
+RSpec.describe SourcegraphDecorator do
let_it_be(:enabled_user) { create(:user, sourcegraph_enabled: true) }
let_it_be(:disabled_user) { create(:user, sourcegraph_enabled: false) }
let_it_be(:public_project) { create(:project, :public) }
@@ -25,7 +25,7 @@ describe SourcegraphDecorator do
end
before do
- Feature.get(:sourcegraph).enable(feature_enabled)
+ stub_feature_flags(sourcegraph: feature_enabled)
stub_application_setting(sourcegraph_url: sourcegraph_url, sourcegraph_enabled: sourcegraph_enabled, sourcegraph_public_only: sourcegraph_public_only)
@@ -36,10 +36,6 @@ describe SourcegraphDecorator do
sign_in user if user
end
- after do
- Feature.get(:sourcegraph).disable
- end
-
subject do
get :index, format: format
diff --git a/spec/controllers/concerns/static_object_external_storage_spec.rb b/spec/controllers/concerns/static_object_external_storage_spec.rb
index d3ece587ef7..afb43d531c0 100644
--- a/spec/controllers/concerns/static_object_external_storage_spec.rb
+++ b/spec/controllers/concerns/static_object_external_storage_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe StaticObjectExternalStorage do
+RSpec.describe StaticObjectExternalStorage do
controller(Projects::ApplicationController) do
include StaticObjectExternalStorage
diff --git a/spec/controllers/dashboard/groups_controller_spec.rb b/spec/controllers/dashboard/groups_controller_spec.rb
index b615bcc1e6b..f246d7bcaf1 100644
--- a/spec/controllers/dashboard/groups_controller_spec.rb
+++ b/spec/controllers/dashboard/groups_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Dashboard::GroupsController do
+RSpec.describe Dashboard::GroupsController do
include ExternalAuthorizationServiceHelpers
let(:user) { create(:user) }
diff --git a/spec/controllers/dashboard/labels_controller_spec.rb b/spec/controllers/dashboard/labels_controller_spec.rb
index cb9c3660b9b..415cb821545 100644
--- a/spec/controllers/dashboard/labels_controller_spec.rb
+++ b/spec/controllers/dashboard/labels_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Dashboard::LabelsController do
+RSpec.describe Dashboard::LabelsController do
let(:project) { create(:project) }
let(:user) { create(:user) }
let!(:label) { create(:label, project: project) }
diff --git a/spec/controllers/dashboard/milestones_controller_spec.rb b/spec/controllers/dashboard/milestones_controller_spec.rb
index f4b04ad6dee..899aa7a41c1 100644
--- a/spec/controllers/dashboard/milestones_controller_spec.rb
+++ b/spec/controllers/dashboard/milestones_controller_spec.rb
@@ -2,18 +2,13 @@
require 'spec_helper'
-describe Dashboard::MilestonesController do
+RSpec.describe Dashboard::MilestonesController do
let(:project) { create(:project) }
let(:group) { create(:group) }
let(:user) { create(:user) }
let(:project_milestone) { create(:milestone, project: project) }
let(:group_milestone) { create(:milestone, group: group) }
- let(:milestone) do
- DashboardMilestone.build(
- [project],
- project_milestone.title
- )
- end
+ let(:milestone) { create(:milestone, group: group) }
let(:issue) { create(:issue, project: project, milestone: project_milestone) }
let(:group_issue) { create(:issue, milestone: group_milestone, project: create(:project, group: group)) }
@@ -28,22 +23,6 @@ describe Dashboard::MilestonesController do
group.add_developer(user)
end
- it_behaves_like 'milestone tabs'
-
- describe "#show" do
- render_views
-
- def view_milestone
- get :show, params: { id: milestone.safe_title, title: milestone.title }
- end
-
- it 'shows milestone page' do
- view_milestone
-
- expect(response).to have_gitlab_http_status(:ok)
- end
- end
-
describe "#index" do
let(:public_group) { create(:group, :public) }
let!(:public_milestone) { create(:milestone, group: public_group) }
@@ -58,7 +37,6 @@ describe Dashboard::MilestonesController do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(2)
expect(json_response.map { |i| i["name"] }).to match_array([group_milestone.name, project_milestone.name])
- expect(json_response.map { |i| i["group_name"] }.compact).to match_array(group.name)
end
it 'returns closed group and project milestones to which the user belongs' do
@@ -67,7 +45,6 @@ describe Dashboard::MilestonesController do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to eq(2)
expect(json_response.map { |i| i["name"] }).to match_array([closed_group_milestone.name, closed_project_milestone.name])
- expect(json_response.map { |i| i["group_name"] }.compact).to match_array(group.name)
end
it 'searches legacy project milestones by title when search_title is given' do
diff --git a/spec/controllers/dashboard/projects_controller_spec.rb b/spec/controllers/dashboard/projects_controller_spec.rb
index eeac696c3f2..ee043fde0ff 100644
--- a/spec/controllers/dashboard/projects_controller_spec.rb
+++ b/spec/controllers/dashboard/projects_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Dashboard::ProjectsController do
+RSpec.describe Dashboard::ProjectsController do
include ExternalAuthorizationServiceHelpers
describe '#index' do
diff --git a/spec/controllers/dashboard/snippets_controller_spec.rb b/spec/controllers/dashboard/snippets_controller_spec.rb
index d5e3a348cd2..3c316d07408 100644
--- a/spec/controllers/dashboard/snippets_controller_spec.rb
+++ b/spec/controllers/dashboard/snippets_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Dashboard::SnippetsController do
+RSpec.describe Dashboard::SnippetsController do
let(:user) { create(:user) }
before do
diff --git a/spec/controllers/dashboard/todos_controller_spec.rb b/spec/controllers/dashboard/todos_controller_spec.rb
index 004eef1873e..f0aa351bee0 100644
--- a/spec/controllers/dashboard/todos_controller_spec.rb
+++ b/spec/controllers/dashboard/todos_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Dashboard::TodosController do
+RSpec.describe Dashboard::TodosController do
let(:user) { create(:user) }
let(:author) { create(:user) }
let(:project) { create(:project) }
diff --git a/spec/controllers/dashboard_controller_spec.rb b/spec/controllers/dashboard_controller_spec.rb
index a280d829d83..d27817c0a82 100644
--- a/spec/controllers/dashboard_controller_spec.rb
+++ b/spec/controllers/dashboard_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe DashboardController do
+RSpec.describe DashboardController do
context 'signed in' do
let(:user) { create(:user) }
let(:project) { create(:project) }
diff --git a/spec/controllers/explore/groups_controller_spec.rb b/spec/controllers/explore/groups_controller_spec.rb
index eccbd7fa14d..310fe609cf1 100644
--- a/spec/controllers/explore/groups_controller_spec.rb
+++ b/spec/controllers/explore/groups_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Explore::GroupsController do
+RSpec.describe Explore::GroupsController do
let(:user) { create(:user) }
before do
diff --git a/spec/controllers/explore/projects_controller_spec.rb b/spec/controllers/explore/projects_controller_spec.rb
index 00cc2d5a81c..fd86501ff5d 100644
--- a/spec/controllers/explore/projects_controller_spec.rb
+++ b/spec/controllers/explore/projects_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Explore::ProjectsController do
+RSpec.describe Explore::ProjectsController do
shared_examples 'explore projects' do
describe 'GET #index.json' do
render_views
diff --git a/spec/controllers/explore/snippets_controller_spec.rb b/spec/controllers/explore/snippets_controller_spec.rb
index ab91faa6cef..f7bd2ba917e 100644
--- a/spec/controllers/explore/snippets_controller_spec.rb
+++ b/spec/controllers/explore/snippets_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Explore::SnippetsController do
+RSpec.describe Explore::SnippetsController do
describe 'GET #index' do
let!(:project_snippet) { create_list(:project_snippet, 3, :public) }
let!(:personal_snippet) { create_list(:personal_snippet, 3, :public) }
diff --git a/spec/controllers/google_api/authorizations_controller_spec.rb b/spec/controllers/google_api/authorizations_controller_spec.rb
index 9d0e0d92978..3dd2cc307d5 100644
--- a/spec/controllers/google_api/authorizations_controller_spec.rb
+++ b/spec/controllers/google_api/authorizations_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe GoogleApi::AuthorizationsController do
+RSpec.describe GoogleApi::AuthorizationsController do
describe 'GET|POST #callback' do
let(:user) { create(:user) }
let(:token) { 'token' }
diff --git a/spec/controllers/graphql_controller_spec.rb b/spec/controllers/graphql_controller_spec.rb
index 68150504fe3..c5643f96b7a 100644
--- a/spec/controllers/graphql_controller_spec.rb
+++ b/spec/controllers/graphql_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe GraphqlController do
+RSpec.describe GraphqlController do
include GraphqlHelpers
before do
diff --git a/spec/controllers/groups/avatars_controller_spec.rb b/spec/controllers/groups/avatars_controller_spec.rb
index 1229328000b..18b116831b2 100644
--- a/spec/controllers/groups/avatars_controller_spec.rb
+++ b/spec/controllers/groups/avatars_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::AvatarsController do
+RSpec.describe Groups::AvatarsController do
include ExternalAuthorizationServiceHelpers
let(:user) { create(:user) }
diff --git a/spec/controllers/groups/boards_controller_spec.rb b/spec/controllers/groups/boards_controller_spec.rb
index b556af0eedc..66595c27531 100644
--- a/spec/controllers/groups/boards_controller_spec.rb
+++ b/spec/controllers/groups/boards_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::BoardsController do
+RSpec.describe Groups::BoardsController do
let(:group) { create(:group) }
let(:user) { create(:user) }
diff --git a/spec/controllers/groups/children_controller_spec.rb b/spec/controllers/groups/children_controller_spec.rb
index a8921300e6b..e97fe50c468 100644
--- a/spec/controllers/groups/children_controller_spec.rb
+++ b/spec/controllers/groups/children_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::ChildrenController do
+RSpec.describe Groups::ChildrenController do
include ExternalAuthorizationServiceHelpers
let(:group) { create(:group, :public) }
diff --git a/spec/controllers/groups/clusters/applications_controller_spec.rb b/spec/controllers/groups/clusters/applications_controller_spec.rb
index bab9e64cfdb..c1d170edce3 100644
--- a/spec/controllers/groups/clusters/applications_controller_spec.rb
+++ b/spec/controllers/groups/clusters/applications_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::Clusters::ApplicationsController do
+RSpec.describe Groups::Clusters::ApplicationsController do
include AccessMatchersForController
def current_application
diff --git a/spec/controllers/groups/clusters_controller_spec.rb b/spec/controllers/groups/clusters_controller_spec.rb
index 1f2f6bd811b..6765cf0990a 100644
--- a/spec/controllers/groups/clusters_controller_spec.rb
+++ b/spec/controllers/groups/clusters_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::ClustersController do
+RSpec.describe Groups::ClustersController do
include AccessMatchersForController
include GoogleApi::CloudPlatformHelpers
@@ -47,6 +47,13 @@ describe Groups::ClustersController do
expect(response).to match_response_schema('cluster_list')
end
+ it 'sets the polling interval header for json requests' do
+ go(format: :json)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.headers['Poll-Interval']).to eq("10000")
+ end
+
context 'when page is specified' do
let(:last_page) { group.clusters.page.total_pages }
let(:total_count) { group.clusters.page.total_count }
diff --git a/spec/controllers/groups/group_links_controller_spec.rb b/spec/controllers/groups/group_links_controller_spec.rb
index ca430414d17..07299382230 100644
--- a/spec/controllers/groups/group_links_controller_spec.rb
+++ b/spec/controllers/groups/group_links_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::GroupLinksController do
+RSpec.describe Groups::GroupLinksController do
let(:shared_with_group) { create(:group, :private) }
let(:shared_group) { create(:group, :private) }
let(:user) { create(:user) }
diff --git a/spec/controllers/groups/group_members_controller_spec.rb b/spec/controllers/groups/group_members_controller_spec.rb
index f69d0602404..85f1b247ee9 100644
--- a/spec/controllers/groups/group_members_controller_spec.rb
+++ b/spec/controllers/groups/group_members_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::GroupMembersController do
+RSpec.describe Groups::GroupMembersController do
include ExternalAuthorizationServiceHelpers
let(:user) { create(:user) }
diff --git a/spec/controllers/groups/imports_controller_spec.rb b/spec/controllers/groups/imports_controller_spec.rb
new file mode 100644
index 00000000000..eb43a62b75b
--- /dev/null
+++ b/spec/controllers/groups/imports_controller_spec.rb
@@ -0,0 +1,85 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Groups::ImportsController do
+ describe 'GET #show' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group, :private) }
+
+ context 'when the user has permission to view the group' do
+ before do
+ sign_in(user)
+ group.add_maintainer(user)
+ end
+
+ context 'when the import is in progress' do
+ before do
+ create(:group_import_state, group: group)
+ end
+
+ it 'renders the show template' do
+ get :show, params: { group_id: group }
+
+ expect(response).to render_template :show
+ end
+
+ it 'sets the flash notice' do
+ get :show, params: { group_id: group, continue: { to: '/', notice_now: 'In progress' } }
+
+ expect(flash.now[:notice]).to eq 'In progress'
+ end
+ end
+
+ context 'when the import has failed' do
+ before do
+ create(:group_import_state, :failed, group: group)
+ end
+
+ it 'redirects to the new group path' do
+ get :show, params: { group_id: group }
+
+ expect(response).to redirect_to new_group_path(group)
+ end
+
+ it 'sets a flash error' do
+ get :show, params: { group_id: group }
+
+ expect(flash[:alert]).to eq 'Failed to import group.'
+ end
+ end
+
+ context 'when the import has finished' do
+ before do
+ create(:group_import_state, :finished, group: group)
+ end
+
+ it 'redirects to the group page' do
+ get :show, params: { group_id: group }
+
+ expect(response).to redirect_to group_path(group)
+ end
+ end
+
+ context 'when there is no import state' do
+ it 'redirects to the group page' do
+ get :show, params: { group_id: group }
+
+ expect(response).to redirect_to group_path(group)
+ end
+ end
+ end
+
+ context 'when the user does not have permission to view the group' do
+ before do
+ sign_in(user)
+ end
+
+ it 'returns a 404' do
+ get :show, params: { group_id: group }
+
+ expect(response).to have_gitlab_http_status :not_found
+ end
+ end
+ end
+end
diff --git a/spec/controllers/groups/labels_controller_spec.rb b/spec/controllers/groups/labels_controller_spec.rb
index 90f91a4ff72..20ee19b01d1 100644
--- a/spec/controllers/groups/labels_controller_spec.rb
+++ b/spec/controllers/groups/labels_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::LabelsController do
+RSpec.describe Groups::LabelsController do
let_it_be(:group) { create(:group) }
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, namespace: group) }
diff --git a/spec/controllers/groups/milestones_controller_spec.rb b/spec/controllers/groups/milestones_controller_spec.rb
index afb950bc538..e47bb75af22 100644
--- a/spec/controllers/groups/milestones_controller_spec.rb
+++ b/spec/controllers/groups/milestones_controller_spec.rb
@@ -2,21 +2,13 @@
require 'spec_helper'
-describe Groups::MilestonesController do
+RSpec.describe Groups::MilestonesController do
let(:group) { create(:group, :public) }
let!(:project) { create(:project, :public, group: group) }
let!(:project2) { create(:project, group: group) }
let(:user) { create(:user) }
let(:title) { '肯定ä¸æ˜¯ä¸­æ–‡çš„问题' }
- let(:milestone) do
- project_milestone = create(:milestone, project: project)
-
- GroupMilestone.build(
- group,
- [project],
- project_milestone.title
- )
- end
+ let(:milestone) { create(:milestone, project: project) }
let(:milestone_path) { group_milestone_path(group, milestone.safe_title, title: milestone.title) }
let(:milestone_params) do
@@ -168,17 +160,16 @@ describe Groups::MilestonesController do
context 'as JSON' do
let!(:milestone) { create(:milestone, group: group, title: 'group milestone') }
- let!(:legacy_milestone1) { create(:milestone, project: project, title: 'legacy') }
- let!(:legacy_milestone2) { create(:milestone, project: project2, title: 'legacy') }
+ let!(:project_milestone1) { create(:milestone, project: project, title: 'same name') }
+ let!(:project_milestone2) { create(:milestone, project: project2, title: 'same name') }
- it 'lists legacy group milestones and group milestones' do
+ it 'lists project and group milestones' do
get :index, params: { group_id: group.to_param }, format: :json
milestones = json_response
- expect(milestones.count).to eq(2)
- expect(milestones.first["title"]).to eq("group milestone")
- expect(milestones.second["title"]).to eq("legacy")
+ expect(milestones.count).to eq(3)
+ expect(milestones.collect { |m| m['title'] }).to match_array(['same name', 'same name', 'group milestone'])
expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type).to eq 'application/json'
end
@@ -191,8 +182,9 @@ describe Groups::MilestonesController do
get :index, params: { group_id: group.to_param }, format: :json
milestones = json_response
- expect(milestones.count).to eq(3)
- expect(milestones.second["title"]).to eq("subgroup milestone")
+ milestone_titles = milestones.map { |m| m['title'] }
+ expect(milestones.count).to eq(4)
+ expect(milestone_titles).to match_array(['same name', 'same name', 'group milestone', 'subgroup milestone'])
end
end
@@ -218,31 +210,18 @@ describe Groups::MilestonesController do
end
describe '#show' do
- let(:milestone1) { create(:milestone, project: project, title: 'legacy') }
- let(:milestone2) { create(:milestone, project: project, title: 'legacy') }
- let(:group_milestone) { create(:milestone, group: group) }
+ render_views
- context 'when there is a title parameter' do
- it 'searches for a legacy group milestone' do
- expect(GroupMilestone).to receive(:build)
- expect(Milestone).not_to receive(:find_by_iid)
+ let!(:group_milestone) { create(:milestone, group: group) }
- get :show, params: { group_id: group.to_param, id: title, title: milestone1.safe_title }
- end
- end
+ it 'renders for a group milestone' do
+ get :show, params: { group_id: group.to_param, id: group_milestone.iid }
- context 'when there is not a title parameter' do
- it 'searches for a group milestone' do
- expect(GlobalMilestone).not_to receive(:build)
- expect(Milestone).to receive(:find_by_iid)
-
- get :show, params: { group_id: group.to_param, id: group_milestone.id }
- end
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.body).to include(group_milestone.title)
end
end
- it_behaves_like 'milestone tabs'
-
describe "#create" do
it "creates group milestone with Chinese title" do
post :create,
@@ -277,34 +256,6 @@ describe Groups::MilestonesController do
expect(response).to redirect_to(group_milestone_path(group, milestone.iid))
expect(milestone.title).to eq("title changed")
end
-
- context "legacy group milestones" do
- let!(:milestone1) { create(:milestone, project: project, title: 'legacy milestone', description: "old description") }
- let!(:milestone2) { create(:milestone, project: project2, title: 'legacy milestone', description: "old description") }
-
- it "updates only group milestones state" do
- milestone_params[:title] = "title changed"
- milestone_params[:description] = "description changed"
- milestone_params[:state_event] = "close"
-
- put :update,
- params: {
- id: milestone1.title.to_slug.to_s,
- group_id: group.to_param,
- milestone: milestone_params,
- title: milestone1.title
- }
-
- expect(response).to redirect_to(group_milestone_path(group, milestone1.safe_title, title: milestone1.title))
-
- [milestone1, milestone2].each do |milestone|
- milestone.reload
- expect(milestone.title).to eq("legacy milestone")
- expect(milestone.description).to eq("old description")
- expect(milestone.state).to eq("closed")
- end
- end
- end
end
describe "#destroy" do
diff --git a/spec/controllers/groups/registry/repositories_controller_spec.rb b/spec/controllers/groups/registry/repositories_controller_spec.rb
index 7b78aeadbd8..ddac8fc5002 100644
--- a/spec/controllers/groups/registry/repositories_controller_spec.rb
+++ b/spec/controllers/groups/registry/repositories_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::Registry::RepositoriesController do
+RSpec.describe Groups::Registry::RepositoriesController do
let_it_be(:user) { create(:user) }
let_it_be(:guest) { create(:user) }
let_it_be(:group, reload: true) { create(:group) }
@@ -17,6 +17,7 @@ describe Groups::Registry::RepositoriesController do
before do
stub_container_registry_config(enabled: true)
+ stub_container_registry_tags(repository: :any, tags: [])
group.add_owner(user)
group.add_guest(guest)
sign_in(user)
diff --git a/spec/controllers/groups/runners_controller_spec.rb b/spec/controllers/groups/runners_controller_spec.rb
index bf556078eec..376cd569952 100644
--- a/spec/controllers/groups/runners_controller_spec.rb
+++ b/spec/controllers/groups/runners_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::RunnersController do
+RSpec.describe Groups::RunnersController do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:runner) { create(:ci_runner, :group, groups: [group]) }
diff --git a/spec/controllers/groups/settings/ci_cd_controller_spec.rb b/spec/controllers/groups/settings/ci_cd_controller_spec.rb
index 45d62a7e6cf..55c19de4aa1 100644
--- a/spec/controllers/groups/settings/ci_cd_controller_spec.rb
+++ b/spec/controllers/groups/settings/ci_cd_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::Settings::CiCdController do
+RSpec.describe Groups::Settings::CiCdController do
include ExternalAuthorizationServiceHelpers
let(:group) { create(:group) }
diff --git a/spec/controllers/groups/settings/integrations_controller_spec.rb b/spec/controllers/groups/settings/integrations_controller_spec.rb
index 29c93c621bd..d079f3f077e 100644
--- a/spec/controllers/groups/settings/integrations_controller_spec.rb
+++ b/spec/controllers/groups/settings/integrations_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::Settings::IntegrationsController do
+RSpec.describe Groups::Settings::IntegrationsController do
let_it_be(:project) { create(:project) }
let(:user) { create(:user) }
let(:group) { create(:group) }
diff --git a/spec/controllers/groups/settings/repository_controller_spec.rb b/spec/controllers/groups/settings/repository_controller_spec.rb
index 9523d404538..6d0caf6d655 100644
--- a/spec/controllers/groups/settings/repository_controller_spec.rb
+++ b/spec/controllers/groups/settings/repository_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::Settings::RepositoryController do
+RSpec.describe Groups::Settings::RepositoryController do
include ExternalAuthorizationServiceHelpers
let(:group) { create(:group) }
diff --git a/spec/controllers/groups/shared_projects_controller_spec.rb b/spec/controllers/groups/shared_projects_controller_spec.rb
index a31b5682ae0..dafce094b14 100644
--- a/spec/controllers/groups/shared_projects_controller_spec.rb
+++ b/spec/controllers/groups/shared_projects_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::SharedProjectsController do
+RSpec.describe Groups::SharedProjectsController do
def get_shared_projects(params = {})
get :index, params: params.reverse_merge(format: :json, group_id: group.full_path)
end
diff --git a/spec/controllers/groups/uploads_controller_spec.rb b/spec/controllers/groups/uploads_controller_spec.rb
index 8abebd04e8b..ea6a5ce8841 100644
--- a/spec/controllers/groups/uploads_controller_spec.rb
+++ b/spec/controllers/groups/uploads_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::UploadsController do
+RSpec.describe Groups::UploadsController do
include WorkhorseHelpers
let(:model) { create(:group, :public) }
diff --git a/spec/controllers/groups/variables_controller_spec.rb b/spec/controllers/groups/variables_controller_spec.rb
index d6c790ae7b8..e2a14165cb4 100644
--- a/spec/controllers/groups/variables_controller_spec.rb
+++ b/spec/controllers/groups/variables_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::VariablesController do
+RSpec.describe Groups::VariablesController do
include ExternalAuthorizationServiceHelpers
let(:group) { create(:group) }
diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb
index 354c9e047c8..dce7105c073 100644
--- a/spec/controllers/groups_controller_spec.rb
+++ b/spec/controllers/groups_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe GroupsController do
+RSpec.describe GroupsController do
include ExternalAuthorizationServiceHelpers
let(:user) { create(:user) }
@@ -37,6 +37,8 @@ describe GroupsController do
end
shared_examples 'details view' do
+ let(:namespace) { group }
+
it { is_expected.to render_template('groups/show') }
context 'as atom' do
@@ -50,6 +52,8 @@ describe GroupsController do
expect(assigns(:events).map(&:id)).to contain_exactly(event.id)
end
end
+
+ it_behaves_like 'namespace storage limit alert'
end
describe 'GET #show' do
@@ -62,7 +66,19 @@ describe GroupsController do
subject { get :show, params: { id: group.to_param }, format: format }
- it_behaves_like 'details view'
+ context 'when the group is not importing' do
+ it_behaves_like 'details view'
+ end
+
+ context 'when the group is importing' do
+ before do
+ create(:group_import_state, group: group)
+ end
+
+ it 'redirects to the import status page' do
+ expect(subject).to redirect_to group_import_path(group)
+ end
+ end
end
describe 'GET #details' do
@@ -301,6 +317,66 @@ describe GroupsController do
end
end
end
+
+ describe 'tracking group creation for onboarding issues experiment' do
+ before do
+ sign_in(user)
+ end
+
+ subject(:create_namespace) { post :create, params: { group: { name: 'new_group', path: 'new_group' } } }
+
+ context 'experiment disabled' do
+ before do
+ stub_experiment(onboarding_issues: false)
+ end
+
+ it 'does not track anything' do
+ expect(Gitlab::Tracking).not_to receive(:event)
+
+ create_namespace
+ end
+ end
+
+ context 'experiment enabled' do
+ before do
+ stub_experiment(onboarding_issues: true)
+ end
+
+ context 'and the user is part of the control group' do
+ before do
+ stub_experiment_for_user(onboarding_issues: false)
+ end
+
+ it 'tracks the event with the "created_namespace" action with the "control_group" property' do
+ expect(Gitlab::Tracking).to receive(:event).with(
+ 'Growth::Conversion::Experiment::OnboardingIssues',
+ 'created_namespace',
+ label: anything,
+ property: 'control_group'
+ )
+
+ create_namespace
+ end
+ end
+
+ context 'and the user is part of the experimental group' do
+ before do
+ stub_experiment_for_user(onboarding_issues: true)
+ end
+
+ it 'tracks the event with the "created_namespace" action with the "experimental_group" property' do
+ expect(Gitlab::Tracking).to receive(:event).with(
+ 'Growth::Conversion::Experiment::OnboardingIssues',
+ 'created_namespace',
+ label: anything,
+ property: 'experimental_group'
+ )
+
+ create_namespace
+ end
+ end
+ end
+ end
end
describe 'GET #index' do
@@ -862,14 +938,17 @@ describe GroupsController do
context 'when the endpoint receives requests above the rate limit' do
before do
sign_in(admin)
- allow(Gitlab::ApplicationRateLimiter).to receive(:throttled?).and_return(true)
+
+ allow(Gitlab::ApplicationRateLimiter)
+ .to receive(:increment)
+ .and_return(Gitlab::ApplicationRateLimiter.rate_limits[:group_export][:threshold] + 1)
end
it 'throttles the endpoint' do
post :export, params: { id: group.to_param }
- expect(flash[:alert]).to eq('This endpoint has been requested too many times. Try again later.')
- expect(response).to have_gitlab_http_status(:found)
+ expect(response.body).to eq('This endpoint has been requested too many times. Try again later.')
+ expect(response).to have_gitlab_http_status :too_many_requests
end
end
end
@@ -933,14 +1012,17 @@ describe GroupsController do
context 'when the endpoint receives requests above the rate limit' do
before do
sign_in(admin)
- allow(Gitlab::ApplicationRateLimiter).to receive(:throttled?).and_return(true)
+
+ allow(Gitlab::ApplicationRateLimiter)
+ .to receive(:increment)
+ .and_return(Gitlab::ApplicationRateLimiter.rate_limits[:group_download_export][:threshold] + 1)
end
it 'throttles the endpoint' do
get :download_export, params: { id: group.to_param }
- expect(flash[:alert]).to eq('This endpoint has been requested too many times. Try again later.')
- expect(response).to have_gitlab_http_status(:found)
+ expect(response.body).to eq('This endpoint has been requested too many times. Try again later.')
+ expect(response).to have_gitlab_http_status :too_many_requests
end
end
end
diff --git a/spec/controllers/health_check_controller_spec.rb b/spec/controllers/health_check_controller_spec.rb
index d1de669ad43..32b72eec0d6 100644
--- a/spec/controllers/health_check_controller_spec.rb
+++ b/spec/controllers/health_check_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe HealthCheckController, :request_store do
+RSpec.describe HealthCheckController, :request_store do
include StubENV
let(:xml_response) { Hash.from_xml(response.body)['hash'] }
diff --git a/spec/controllers/help_controller_spec.rb b/spec/controllers/help_controller_spec.rb
index fafbe6bffe1..6c0b3efa53b 100644
--- a/spec/controllers/help_controller_spec.rb
+++ b/spec/controllers/help_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe HelpController do
+RSpec.describe HelpController do
let(:user) { create(:user) }
before do
diff --git a/spec/controllers/ide_controller_spec.rb b/spec/controllers/ide_controller_spec.rb
index 0462f9520d5..39d92846863 100644
--- a/spec/controllers/ide_controller_spec.rb
+++ b/spec/controllers/ide_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe IdeController do
+RSpec.describe IdeController do
let(:user) { create(:user) }
before do
diff --git a/spec/controllers/import/bitbucket_controller_spec.rb b/spec/controllers/import/bitbucket_controller_spec.rb
index d44edb63635..ec38a635c2d 100644
--- a/spec/controllers/import/bitbucket_controller_spec.rb
+++ b/spec/controllers/import/bitbucket_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Import::BitbucketController do
+RSpec.describe Import::BitbucketController do
include ImportSpecHelper
let(:user) { create(:user) }
@@ -56,8 +56,42 @@ describe Import::BitbucketController do
describe "GET status" do
before do
- @repo = double(slug: 'vim', owner: 'asd', full_name: 'asd/vim', "valid?" => true)
+ @repo = double(name: 'vim', slug: 'vim', owner: 'asd', full_name: 'asd/vim', clone_url: 'http://test.host/demo/url.git', 'valid?' => true)
+ @invalid_repo = double(name: 'mercurialrepo', slug: 'mercurialrepo', owner: 'asd', full_name: 'asd/mercurialrepo', clone_url: 'http://test.host/demo/mercurialrepo.git', 'valid?' => false)
+
assign_session_tokens
+ stub_feature_flags(new_import_ui: false)
+ end
+
+ it_behaves_like 'import controller with new_import_ui feature flag' do
+ before do
+ allow(controller).to receive(:provider_url).and_return('http://demobitbucket.org')
+ end
+
+ let(:repo) { @repo }
+ let(:repo_id) { @repo.full_name }
+ let(:import_source) { @repo.full_name }
+ let(:provider_name) { 'bitbucket' }
+ let(:client_repos_field) { :repos }
+ end
+
+ context 'with new_import_ui feature flag enabled' do
+ before do
+ stub_feature_flags(new_import_ui: true)
+ allow(controller).to receive(:provider_url).and_return('http://demobitbucket.org')
+ end
+
+ it 'returns invalid repos' do
+ allow_any_instance_of(Bitbucket::Client).to receive(:repos).and_return([@repo, @invalid_repo])
+
+ get :status, format: :json
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['incompatible_repos'].length).to eq(1)
+ expect(json_response.dig("incompatible_repos", 0, "id")).to eq(@invalid_repo.full_name)
+ expect(json_response['provider_repos'].length).to eq(1)
+ expect(json_response.dig("provider_repos", 0, "id")).to eq(@repo.full_name)
+ end
end
it "assigns variables" do
diff --git a/spec/controllers/import/bitbucket_server_controller_spec.rb b/spec/controllers/import/bitbucket_server_controller_spec.rb
index 3a347368884..af471b478fa 100644
--- a/spec/controllers/import/bitbucket_server_controller_spec.rb
+++ b/spec/controllers/import/bitbucket_server_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Import::BitbucketServerController do
+RSpec.describe Import::BitbucketServerController do
let(:user) { create(:user) }
let(:project_key) { 'test-project' }
let(:repo_slug) { 'some-repo' }
@@ -33,7 +33,7 @@ describe Import::BitbucketServerController do
let(:project_name) { "my-project_123" }
before do
- allow(controller).to receive(:bitbucket_client).and_return(client)
+ allow(controller).to receive(:client).and_return(client)
repo = double(name: project_name)
allow(client).to receive(:repo).with(project_key, repo_slug).and_return(repo)
assign_session_tokens
@@ -139,12 +139,39 @@ describe Import::BitbucketServerController do
let(:repos) { instance_double(BitbucketServer::Collection) }
before do
- allow(controller).to receive(:bitbucket_client).and_return(client)
+ allow(controller).to receive(:client).and_return(client)
@repo = double(slug: 'vim', project_key: 'asd', full_name: 'asd/vim', "valid?" => true, project_name: 'asd', browse_url: 'http://test', name: 'vim')
- @invalid_repo = double(slug: 'invalid', project_key: 'foobar', full_name: 'asd/foobar', "valid?" => false, browse_url: 'http://bad-repo')
+ @invalid_repo = double(slug: 'invalid', project_key: 'foobar', full_name: 'asd/foobar', "valid?" => false, browse_url: 'http://bad-repo', name: 'invalid')
@created_repo = double(slug: 'created', project_key: 'existing', full_name: 'group/created', "valid?" => true, browse_url: 'http://existing')
assign_session_tokens
+ stub_feature_flags(new_import_ui: false)
+ end
+
+ context 'with new_import_ui feature flag enabled' do
+ before do
+ stub_feature_flags(new_import_ui: true)
+ end
+
+ it 'returns invalid repos' do
+ allow(client).to receive(:repos).with(filter: nil, limit: 25, page_offset: 0).and_return([@repo, @invalid_repo])
+
+ get :status, format: :json
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['incompatible_repos'].length).to eq(1)
+ expect(json_response.dig("incompatible_repos", 0, "id")).to eq(@invalid_repo.full_name)
+ expect(json_response['provider_repos'].length).to eq(1)
+ expect(json_response.dig("provider_repos", 0, "id")).to eq(@repo.full_name)
+ end
+ end
+
+ it_behaves_like 'import controller with new_import_ui feature flag' do
+ let(:repo) { @repo }
+ let(:repo_id) { @repo.full_name }
+ let(:import_source) { @repo.browse_url }
+ let(:provider_name) { 'bitbucket_server' }
+ let(:client_repos_field) { :repos }
end
it 'assigns repository categories' do
diff --git a/spec/controllers/import/fogbugz_controller_spec.rb b/spec/controllers/import/fogbugz_controller_spec.rb
index c833fbfaea5..aabbcb30358 100644
--- a/spec/controllers/import/fogbugz_controller_spec.rb
+++ b/spec/controllers/import/fogbugz_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Import::FogbugzController do
+RSpec.describe Import::FogbugzController do
include ImportSpecHelper
let(:user) { create(:user) }
@@ -80,8 +80,17 @@ describe Import::FogbugzController do
describe 'GET status' do
before do
- @repo = OpenStruct.new(name: 'vim')
+ @repo = OpenStruct.new(id: 'demo', name: 'vim')
stub_client(valid?: true)
+ stub_feature_flags(new_import_ui: false)
+ end
+
+ it_behaves_like 'import controller with new_import_ui feature flag' do
+ let(:repo) { @repo }
+ let(:repo_id) { @repo.id }
+ let(:import_source) { @repo.name }
+ let(:provider_name) { 'fogbugz' }
+ let(:client_repos_field) { :repos }
end
it 'assigns variables' do
diff --git a/spec/controllers/import/gitea_controller_spec.rb b/spec/controllers/import/gitea_controller_spec.rb
index 006b423ce5f..9001faef408 100644
--- a/spec/controllers/import/gitea_controller_spec.rb
+++ b/spec/controllers/import/gitea_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Import::GiteaController do
+RSpec.describe Import::GiteaController do
include ImportSpecHelper
let(:provider) { :gitea }
diff --git a/spec/controllers/import/github_controller_spec.rb b/spec/controllers/import/github_controller_spec.rb
index 40ea0bb3a44..a5a3dc463d3 100644
--- a/spec/controllers/import/github_controller_spec.rb
+++ b/spec/controllers/import/github_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Import::GithubController do
+RSpec.describe Import::GithubController do
include ImportSpecHelper
let(:provider) { :github }
diff --git a/spec/controllers/import/gitlab_controller_spec.rb b/spec/controllers/import/gitlab_controller_spec.rb
index 96a8eb99d5c..1cd0593f762 100644
--- a/spec/controllers/import/gitlab_controller_spec.rb
+++ b/spec/controllers/import/gitlab_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Import::GitlabController do
+RSpec.describe Import::GitlabController do
include ImportSpecHelper
let(:user) { create(:user) }
@@ -34,8 +34,17 @@ describe Import::GitlabController do
describe "GET status" do
before do
- @repo = OpenStruct.new(path: 'vim', path_with_namespace: 'asd/vim')
+ @repo = OpenStruct.new(id: 1, path: 'vim', path_with_namespace: 'asd/vim', web_url: 'https://gitlab.com/asd/vim')
assign_session_token
+ stub_feature_flags(new_import_ui: false)
+ end
+
+ it_behaves_like 'import controller with new_import_ui feature flag' do
+ let(:repo) { @repo }
+ let(:repo_id) { @repo.id }
+ let(:import_source) { @repo.path_with_namespace }
+ let(:provider_name) { 'gitlab' }
+ let(:client_repos_field) { :projects }
end
it "assigns variables" do
diff --git a/spec/controllers/import/google_code_controller_spec.rb b/spec/controllers/import/google_code_controller_spec.rb
index 3773f691ed0..0fda111c029 100644
--- a/spec/controllers/import/google_code_controller_spec.rb
+++ b/spec/controllers/import/google_code_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Import::GoogleCodeController do
+RSpec.describe Import::GoogleCodeController do
include ImportSpecHelper
let(:user) { create(:user) }
diff --git a/spec/controllers/import/phabricator_controller_spec.rb b/spec/controllers/import/phabricator_controller_spec.rb
index d29a06efbb5..9827a6d077c 100644
--- a/spec/controllers/import/phabricator_controller_spec.rb
+++ b/spec/controllers/import/phabricator_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Import::PhabricatorController do
+RSpec.describe Import::PhabricatorController do
let(:current_user) { create(:user) }
before do
diff --git a/spec/controllers/instance_statistics/cohorts_controller_spec.rb b/spec/controllers/instance_statistics/cohorts_controller_spec.rb
index 596d3c7abe5..b92fcb2575c 100644
--- a/spec/controllers/instance_statistics/cohorts_controller_spec.rb
+++ b/spec/controllers/instance_statistics/cohorts_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe InstanceStatistics::CohortsController do
+RSpec.describe InstanceStatistics::CohortsController do
let(:user) { create(:user) }
before do
diff --git a/spec/controllers/instance_statistics/dev_ops_score_controller_spec.rb b/spec/controllers/instance_statistics/dev_ops_score_controller_spec.rb
index 5825c6295f6..d729682bef0 100644
--- a/spec/controllers/instance_statistics/dev_ops_score_controller_spec.rb
+++ b/spec/controllers/instance_statistics/dev_ops_score_controller_spec.rb
@@ -2,6 +2,6 @@
require 'spec_helper'
-describe InstanceStatistics::DevOpsScoreController do
+RSpec.describe InstanceStatistics::DevOpsScoreController do
it_behaves_like 'instance statistics availability'
end
diff --git a/spec/controllers/invites_controller_spec.rb b/spec/controllers/invites_controller_spec.rb
index 9daaa258aa2..f2821bb67e8 100644
--- a/spec/controllers/invites_controller_spec.rb
+++ b/spec/controllers/invites_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe InvitesController do
+RSpec.describe InvitesController do
let(:token) { '123456' }
let(:user) { create(:user) }
let(:member) { create(:project_member, invite_token: token, invite_email: 'test@abc.com', user: user) }
diff --git a/spec/controllers/ldap/omniauth_callbacks_controller_spec.rb b/spec/controllers/ldap/omniauth_callbacks_controller_spec.rb
index 0242a91ac60..2de824bbf3c 100644
--- a/spec/controllers/ldap/omniauth_callbacks_controller_spec.rb
+++ b/spec/controllers/ldap/omniauth_callbacks_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ldap::OmniauthCallbacksController do
+RSpec.describe Ldap::OmniauthCallbacksController do
include_context 'Ldap::OmniauthCallbacksController'
it 'allows sign in' do
diff --git a/spec/controllers/metrics_controller_spec.rb b/spec/controllers/metrics_controller_spec.rb
index 75509cc509f..f350d7378dc 100644
--- a/spec/controllers/metrics_controller_spec.rb
+++ b/spec/controllers/metrics_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MetricsController, :request_store do
+RSpec.describe MetricsController, :request_store do
include StubENV
let(:metrics_multiproc_dir) { @metrics_multiproc_dir }
diff --git a/spec/controllers/notification_settings_controller_spec.rb b/spec/controllers/notification_settings_controller_spec.rb
index f3b608aee0c..c4d67df15f7 100644
--- a/spec/controllers/notification_settings_controller_spec.rb
+++ b/spec/controllers/notification_settings_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe NotificationSettingsController do
+RSpec.describe NotificationSettingsController do
let(:project) { create(:project) }
let(:group) { create(:group, :internal) }
let(:user) { create(:user) }
diff --git a/spec/controllers/oauth/applications_controller_spec.rb b/spec/controllers/oauth/applications_controller_spec.rb
index 09f8ad4332d..f20204b6718 100644
--- a/spec/controllers/oauth/applications_controller_spec.rb
+++ b/spec/controllers/oauth/applications_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Oauth::ApplicationsController do
+RSpec.describe Oauth::ApplicationsController do
let(:user) { create(:user) }
let(:application) { create(:oauth_application, owner: user) }
diff --git a/spec/controllers/oauth/authorizations_controller_spec.rb b/spec/controllers/oauth/authorizations_controller_spec.rb
index f975502ca4e..89b74675d28 100644
--- a/spec/controllers/oauth/authorizations_controller_spec.rb
+++ b/spec/controllers/oauth/authorizations_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Oauth::AuthorizationsController do
+RSpec.describe Oauth::AuthorizationsController do
let!(:application) { create(:oauth_application, scopes: 'api read_user', redirect_uri: 'http://example.com') }
let(:params) do
{
diff --git a/spec/controllers/oauth/authorized_applications_controller_spec.rb b/spec/controllers/oauth/authorized_applications_controller_spec.rb
index 32be6a3ddb7..15b2969a859 100644
--- a/spec/controllers/oauth/authorized_applications_controller_spec.rb
+++ b/spec/controllers/oauth/authorized_applications_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Oauth::AuthorizedApplicationsController do
+RSpec.describe Oauth::AuthorizedApplicationsController do
let(:user) { create(:user) }
let(:guest) { create(:user) }
let(:application) { create(:oauth_application, owner: guest) }
diff --git a/spec/controllers/omniauth_callbacks_controller_spec.rb b/spec/controllers/omniauth_callbacks_controller_spec.rb
index 0d8a6827afe..0b99f28f79b 100644
--- a/spec/controllers/omniauth_callbacks_controller_spec.rb
+++ b/spec/controllers/omniauth_callbacks_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe OmniauthCallbacksController, type: :controller do
+RSpec.describe OmniauthCallbacksController, type: :controller do
include LoginHelpers
describe 'omniauth' do
@@ -212,7 +212,7 @@ describe OmniauthCallbacksController, type: :controller do
end
it 'allows linking the disabled provider' do
- user.identities.destroy_all # rubocop: disable DestroyAll
+ user.identities.destroy_all # rubocop: disable Cop/DestroyAll
sign_in(user)
expect { post provider }.to change { user.reload.identities.count }.by(1)
diff --git a/spec/controllers/passwords_controller_spec.rb b/spec/controllers/passwords_controller_spec.rb
index 3ec8e347659..ba2c0c0455d 100644
--- a/spec/controllers/passwords_controller_spec.rb
+++ b/spec/controllers/passwords_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe PasswordsController do
+RSpec.describe PasswordsController do
describe '#check_password_authentication_available' do
before do
@request.env["devise.mapping"] = Devise.mappings[:user]
diff --git a/spec/controllers/profiles/accounts_controller_spec.rb b/spec/controllers/profiles/accounts_controller_spec.rb
index 518ea4e5c48..52a7a1609a1 100644
--- a/spec/controllers/profiles/accounts_controller_spec.rb
+++ b/spec/controllers/profiles/accounts_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Profiles::AccountsController do
+RSpec.describe Profiles::AccountsController do
describe 'DELETE unlink' do
let(:user) { create(:omniauth_user) }
diff --git a/spec/controllers/profiles/avatars_controller_spec.rb b/spec/controllers/profiles/avatars_controller_spec.rb
index 1a64cb72265..d120d9ce559 100644
--- a/spec/controllers/profiles/avatars_controller_spec.rb
+++ b/spec/controllers/profiles/avatars_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Profiles::AvatarsController do
+RSpec.describe Profiles::AvatarsController do
let(:user) { create(:user, avatar: fixture_file_upload("spec/fixtures/dk.png")) }
before do
diff --git a/spec/controllers/profiles/emails_controller_spec.rb b/spec/controllers/profiles/emails_controller_spec.rb
index ffec43fea2c..246f8a6cd76 100644
--- a/spec/controllers/profiles/emails_controller_spec.rb
+++ b/spec/controllers/profiles/emails_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Profiles::EmailsController do
+RSpec.describe Profiles::EmailsController do
let(:user) { create(:user) }
before do
diff --git a/spec/controllers/profiles/keys_controller_spec.rb b/spec/controllers/profiles/keys_controller_spec.rb
index 8582ecbb06d..258ed62262a 100644
--- a/spec/controllers/profiles/keys_controller_spec.rb
+++ b/spec/controllers/profiles/keys_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Profiles::KeysController do
+RSpec.describe Profiles::KeysController do
let(:user) { create(:user) }
describe 'POST #create' do
diff --git a/spec/controllers/profiles/notifications_controller_spec.rb b/spec/controllers/profiles/notifications_controller_spec.rb
index 343f29ef687..40b4c8f0371 100644
--- a/spec/controllers/profiles/notifications_controller_spec.rb
+++ b/spec/controllers/profiles/notifications_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Profiles::NotificationsController do
+RSpec.describe Profiles::NotificationsController do
let(:user) do
create(:user) do |user|
user.emails.create(email: 'original@example.com', confirmed_at: Time.current)
diff --git a/spec/controllers/profiles/personal_access_tokens_controller_spec.rb b/spec/controllers/profiles/personal_access_tokens_controller_spec.rb
index b467ecc4af9..1fdd1200028 100644
--- a/spec/controllers/profiles/personal_access_tokens_controller_spec.rb
+++ b/spec/controllers/profiles/personal_access_tokens_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Profiles::PersonalAccessTokensController do
+RSpec.describe Profiles::PersonalAccessTokensController do
let(:user) { create(:user) }
let(:token_attributes) { attributes_for(:personal_access_token) }
diff --git a/spec/controllers/profiles/preferences_controller_spec.rb b/spec/controllers/profiles/preferences_controller_spec.rb
index 98a9c3eaec6..4a68475c37f 100644
--- a/spec/controllers/profiles/preferences_controller_spec.rb
+++ b/spec/controllers/profiles/preferences_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Profiles::PreferencesController do
+RSpec.describe Profiles::PreferencesController do
let(:user) { create(:user) }
before do
diff --git a/spec/controllers/profiles/two_factor_auths_controller_spec.rb b/spec/controllers/profiles/two_factor_auths_controller_spec.rb
index b02af0096a5..f645081219a 100644
--- a/spec/controllers/profiles/two_factor_auths_controller_spec.rb
+++ b/spec/controllers/profiles/two_factor_auths_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Profiles::TwoFactorAuthsController do
+RSpec.describe Profiles::TwoFactorAuthsController do
before do
# `user` should be defined within the action-specific describe blocks
sign_in(user)
diff --git a/spec/controllers/profiles_controller_spec.rb b/spec/controllers/profiles_controller_spec.rb
index d6d2c73d049..e08c92da87f 100644
--- a/spec/controllers/profiles_controller_spec.rb
+++ b/spec/controllers/profiles_controller_spec.rb
@@ -2,7 +2,7 @@
require('spec_helper')
-describe ProfilesController, :request_store do
+RSpec.describe ProfilesController, :request_store do
let(:user) { create(:user) }
describe 'POST update' do
diff --git a/spec/controllers/projects/alert_management_controller_spec.rb b/spec/controllers/projects/alert_management_controller_spec.rb
index b84376db33d..6a1952f949b 100644
--- a/spec/controllers/projects/alert_management_controller_spec.rb
+++ b/spec/controllers/projects/alert_management_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::AlertManagementController do
+RSpec.describe Projects::AlertManagementController do
let_it_be(:project) { create(:project) }
let_it_be(:role) { :developer }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/alerting/notifications_controller_spec.rb b/spec/controllers/projects/alerting/notifications_controller_spec.rb
index 9d26c2278b1..33fd73c762a 100644
--- a/spec/controllers/projects/alerting/notifications_controller_spec.rb
+++ b/spec/controllers/projects/alerting/notifications_controller_spec.rb
@@ -2,90 +2,101 @@
require 'spec_helper'
-describe Projects::Alerting::NotificationsController do
+RSpec.describe Projects::Alerting::NotificationsController do
let_it_be(:project) { create(:project) }
let_it_be(:environment) { create(:environment, project: project) }
describe 'POST #create' do
- let(:service_response) { ServiceResponse.success }
- let(:notify_service) { instance_double(Projects::Alerting::NotifyService, execute: service_response) }
-
around do |example|
ForgeryProtection.with_forgery_protection { example.run }
end
- before do
- allow(Projects::Alerting::NotifyService).to receive(:new).and_return(notify_service)
- end
+ shared_examples 'process alert payload' do |notify_service_class|
+ let(:service_response) { ServiceResponse.success }
+ let(:notify_service) { instance_double(notify_service_class, execute: service_response) }
- def make_request(body = {})
- post :create, params: project_params, body: body.to_json, as: :json
- end
+ before do
+ allow(notify_service_class).to receive(:new).and_return(notify_service)
+ end
- context 'when notification service succeeds' do
- let(:payload) do
- {
- title: 'Alert title',
- hosts: 'https://gitlab.com'
- }
+ def make_request
+ post :create, params: project_params, body: payload.to_json, as: :json
end
- let(:permitted_params) { ActionController::Parameters.new(payload).permit! }
+ context 'when notification service succeeds' do
+ let(:permitted_params) { ActionController::Parameters.new(payload).permit! }
- it 'responds with ok' do
- make_request
+ it 'responds with ok' do
+ make_request
- expect(response).to have_gitlab_http_status(:ok)
- end
+ expect(response).to have_gitlab_http_status(:ok)
+ end
- it 'does not pass excluded parameters to the notify service' do
- make_request(payload)
+ it 'does not pass excluded parameters to the notify service' do
+ make_request
- expect(Projects::Alerting::NotifyService)
- .to have_received(:new)
- .with(project, nil, permitted_params)
+ expect(notify_service_class)
+ .to have_received(:new)
+ .with(project, nil, permitted_params)
+ end
end
- end
- context 'when notification service fails' do
- let(:service_response) { ServiceResponse.error(message: 'Unauthorized', http_status: :unauthorized) }
+ context 'when notification service fails' do
+ let(:service_response) { ServiceResponse.error(message: 'Unauthorized', http_status: :unauthorized) }
- it 'responds with the service response' do
- make_request
+ it 'responds with the service response' do
+ make_request
- expect(response).to have_gitlab_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
end
- end
- context 'bearer token' do
- context 'when set' do
- it 'extracts bearer token' do
- request.headers['HTTP_AUTHORIZATION'] = 'Bearer some token'
+ context 'bearer token' do
+ context 'when set' do
+ it 'extracts bearer token' do
+ request.headers['HTTP_AUTHORIZATION'] = 'Bearer some token'
- expect(notify_service).to receive(:execute).with('some token')
+ expect(notify_service).to receive(:execute).with('some token')
- make_request
- end
+ make_request
+ end
- it 'pass nil if cannot extract a non-bearer token' do
- request.headers['HTTP_AUTHORIZATION'] = 'some token'
+ it 'pass nil if cannot extract a non-bearer token' do
+ request.headers['HTTP_AUTHORIZATION'] = 'some token'
- expect(notify_service).to receive(:execute).with(nil)
+ expect(notify_service).to receive(:execute).with(nil)
- make_request
+ make_request
+ end
end
- end
- context 'when missing' do
- it 'passes nil' do
- expect(notify_service).to receive(:execute).with(nil)
+ context 'when missing' do
+ it 'passes nil' do
+ expect(notify_service).to receive(:execute).with(nil)
- make_request
+ make_request
+ end
end
end
end
+
+ context 'generic alert payload' do
+ it_behaves_like 'process alert payload', Projects::Alerting::NotifyService do
+ let(:payload) { { title: 'Alert title' } }
+ end
+ end
+
+ context 'Prometheus alert payload' do
+ include PrometheusHelpers
+
+ it_behaves_like 'process alert payload', Projects::Prometheus::Alerts::NotifyService do
+ let(:payload) { prometheus_alert_payload }
+ end
+ end
end
+ private
+
def project_params(opts = {})
opts.reverse_merge(namespace_id: project.namespace, project_id: project)
end
diff --git a/spec/controllers/projects/artifacts_controller_spec.rb b/spec/controllers/projects/artifacts_controller_spec.rb
index 4c815a5b40c..69ab9873b90 100644
--- a/spec/controllers/projects/artifacts_controller_spec.rb
+++ b/spec/controllers/projects/artifacts_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ArtifactsController do
+RSpec.describe Projects::ArtifactsController do
include RepoHelpers
let(:user) { project.owner }
@@ -371,10 +371,9 @@ describe Projects::ArtifactsController do
end
context 'when the artifact is zip' do
- let!(:artifact) { create(:ci_job_artifact, :lsif, job: job, file_path: Rails.root.join("spec/fixtures/#{file_name}")) }
+ let!(:artifact) { create(:ci_job_artifact, :lsif, job: job) }
let(:path) { 'lsif/main.go.json' }
- let(:file_name) { 'lsif.json.zip' }
- let(:archive_matcher) { file_name }
+ let(:archive_matcher) { 'lsif.json.zip' }
let(:query_params) { super().merge(file_type: :lsif, path: path) }
it_behaves_like 'a valid file' do
diff --git a/spec/controllers/projects/autocomplete_sources_controller_spec.rb b/spec/controllers/projects/autocomplete_sources_controller_spec.rb
index d35192b2ccb..865b31a28d7 100644
--- a/spec/controllers/projects/autocomplete_sources_controller_spec.rb
+++ b/spec/controllers/projects/autocomplete_sources_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::AutocompleteSourcesController do
+RSpec.describe Projects::AutocompleteSourcesController do
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project, namespace: group) }
let_it_be(:issue) { create(:issue, project: project) }
diff --git a/spec/controllers/projects/avatars_controller_spec.rb b/spec/controllers/projects/avatars_controller_spec.rb
index 54c2397625f..16e9c845307 100644
--- a/spec/controllers/projects/avatars_controller_spec.rb
+++ b/spec/controllers/projects/avatars_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::AvatarsController do
+RSpec.describe Projects::AvatarsController do
let_it_be(:project) { create(:project, :repository) }
before do
diff --git a/spec/controllers/projects/badges_controller_spec.rb b/spec/controllers/projects/badges_controller_spec.rb
index 4ae29ba7f54..7e7a630921f 100644
--- a/spec/controllers/projects/badges_controller_spec.rb
+++ b/spec/controllers/projects/badges_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::BadgesController do
+RSpec.describe Projects::BadgesController do
let(:project) { pipeline.project }
let!(:pipeline) { create(:ci_empty_pipeline) }
let(:user) { create(:user) }
@@ -54,7 +54,7 @@ describe Projects::BadgesController do
context 'when style param is set to `flat`' do
it 'renders the `flat` badge layout' do
- get_badge(badge_type, 'flat')
+ get_badge(badge_type, style: 'flat')
expect(response).to render_template('projects/badges/badge')
end
@@ -62,7 +62,7 @@ describe Projects::BadgesController do
context 'when style param is set to an invalid type' do
it 'renders the `flat` (default) badge layout' do
- get_badge(badge_type, 'xxx')
+ get_badge(badge_type, style: 'xxx')
expect(response).to render_template('projects/badges/badge')
end
@@ -70,7 +70,7 @@ describe Projects::BadgesController do
context 'when style param is set to `flat-square`' do
it 'renders the `flat-square` badge layout' do
- get_badge(badge_type, 'flat-square')
+ get_badge(badge_type, style: 'flat-square')
expect(response).to render_template('projects/badges/badge_flat-square')
end
@@ -102,12 +102,37 @@ describe Projects::BadgesController do
end
it 'defaults to project permissions' do
- get_badge(:coverage)
+ get_badge(badge_type)
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
+
+ context 'customization' do
+ render_views
+
+ before do
+ project.add_maintainer(user)
+ sign_in(user)
+ end
+
+ context 'when key_text param is used' do
+ it 'sets custom key text' do
+ get_badge(badge_type, key_text: 'custom key text')
+
+ expect(response.body).to include('custom key text')
+ end
+ end
+
+ context 'when key_width param is used' do
+ it 'sets custom key width' do
+ get_badge(badge_type, key_width: '123')
+
+ expect(response.body).to include('123')
+ end
+ end
+ end
end
describe '#pipeline' do
@@ -118,13 +143,12 @@ describe Projects::BadgesController do
it_behaves_like 'a badge resource', :coverage
end
- def get_badge(badge, style = nil)
+ def get_badge(badge, args = {})
params = {
namespace_id: project.namespace.to_param,
project_id: project,
- ref: pipeline.ref,
- style: style
- }
+ ref: pipeline.ref
+ }.merge(args.slice(:style, :key_text, :key_width))
get badge, params: params, format: :svg
end
diff --git a/spec/controllers/projects/blame_controller_spec.rb b/spec/controllers/projects/blame_controller_spec.rb
index ac8394e3cd4..bf475f6135a 100644
--- a/spec/controllers/projects/blame_controller_spec.rb
+++ b/spec/controllers/projects/blame_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::BlameController do
+RSpec.describe Projects::BlameController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/blob_controller_spec.rb b/spec/controllers/projects/blob_controller_spec.rb
index ad04c6e61e8..9fee97f938c 100644
--- a/spec/controllers/projects/blob_controller_spec.rb
+++ b/spec/controllers/projects/blob_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::BlobController do
+RSpec.describe Projects::BlobController do
include ProjectForksHelper
let(:project) { create(:project, :public, :repository) }
@@ -378,6 +378,22 @@ describe Projects::BlobController do
expect(response).to redirect_to(after_delete_path)
end
+
+ context 'when a validation failure occurs' do
+ let(:failure_path) { project_blob_path(project, default_params[:id]) }
+
+ render_views
+
+ it 'redirects to a valid page' do
+ expect_next_instance_of(Files::DeleteService) do |instance|
+ expect(instance).to receive(:validate!).and_raise(Commits::CreateService::ValidationError, "validation error")
+ end
+
+ delete :destroy, params: default_params
+
+ expect(response).to redirect_to(failure_path)
+ end
+ end
end
context 'if deleted file is the last one in a subdirectory' do
diff --git a/spec/controllers/projects/boards_controller_spec.rb b/spec/controllers/projects/boards_controller_spec.rb
index 6634801939b..dad932f9cdf 100644
--- a/spec/controllers/projects/boards_controller_spec.rb
+++ b/spec/controllers/projects/boards_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::BoardsController do
+RSpec.describe Projects::BoardsController do
let(:project) { create(:project) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/branches_controller_spec.rb b/spec/controllers/projects/branches_controller_spec.rb
index 174d8904481..625fc5bddda 100644
--- a/spec/controllers/projects/branches_controller_spec.rb
+++ b/spec/controllers/projects/branches_controller_spec.rb
@@ -2,14 +2,13 @@
require 'spec_helper'
-describe Projects::BranchesController do
+RSpec.describe Projects::BranchesController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:developer) { create(:user) }
before do
- project.add_maintainer(user)
- project.add_developer(user)
+ project.add_developer(developer)
allow(project).to receive(:branches).and_return(['master', 'foo/bar/baz'])
allow(project).to receive(:tags).and_return(['v1.0.0', 'v2.0.0'])
@@ -21,7 +20,7 @@ describe Projects::BranchesController do
context "on creation of a new branch" do
before do
- sign_in(user)
+ sign_in(developer)
post :create,
params: {
@@ -80,7 +79,7 @@ describe Projects::BranchesController do
let(:issue) { create(:issue, project: project) }
before do
- sign_in(user)
+ sign_in(developer)
end
it 'redirects' do
@@ -97,7 +96,7 @@ describe Projects::BranchesController do
end
it 'posts a system note' do
- expect(SystemNoteService).to receive(:new_issue_branch).with(issue, project, user, "1-feature-branch", branch_project: project)
+ expect(SystemNoteService).to receive(:new_issue_branch).with(issue, project, developer, "1-feature-branch", branch_project: project)
post :create,
params: {
@@ -136,14 +135,14 @@ describe Projects::BranchesController do
context 'user can update issue' do
before do
- confidential_issue_project.add_reporter(user)
+ confidential_issue_project.add_reporter(developer)
end
context 'issue is under the specified project' do
let(:issue) { create(:issue, project: confidential_issue_project) }
it 'posts a system note' do
- expect(SystemNoteService).to receive(:new_issue_branch).with(issue, confidential_issue_project, user, "1-feature-branch", branch_project: project)
+ expect(SystemNoteService).to receive(:new_issue_branch).with(issue, confidential_issue_project, developer, "1-feature-branch", branch_project: project)
create_branch_with_confidential_issue_project
end
@@ -264,7 +263,7 @@ describe Projects::BranchesController do
describe 'POST create with JSON format' do
before do
- sign_in(user)
+ sign_in(developer)
end
context 'with valid params' do
@@ -305,7 +304,7 @@ describe Projects::BranchesController do
render_views
before do
- sign_in(user)
+ sign_in(developer)
end
it 'returns 303' do
@@ -325,7 +324,7 @@ describe Projects::BranchesController do
render_views
before do
- sign_in(user)
+ sign_in(developer)
post :destroy,
format: format,
@@ -436,7 +435,7 @@ describe Projects::BranchesController do
context 'when user is allowed to push' do
before do
- sign_in(user)
+ sign_in(developer)
end
it 'redirects to branches' do
@@ -454,7 +453,7 @@ describe Projects::BranchesController do
context 'when user is not allowed to push' do
before do
- sign_in(developer)
+ sign_in(user)
end
it 'responds with status 404' do
@@ -469,7 +468,7 @@ describe Projects::BranchesController do
render_views
before do
- sign_in(user)
+ sign_in(developer)
end
context 'when rendering a JSON format' do
@@ -487,6 +486,82 @@ describe Projects::BranchesController do
end
end
+ context 'when a branch has multiple pipelines' do
+ it 'chooses the latest to determine status' do
+ sha = project.repository.create_file(developer, generate(:branch), 'content', message: 'message', branch_name: 'master')
+ create(:ci_pipeline,
+ project: project,
+ user: developer,
+ ref: "master",
+ sha: sha,
+ status: :running,
+ created_at: 6.months.ago)
+ create(:ci_pipeline,
+ project: project,
+ user: developer,
+ ref: "master",
+ sha: sha,
+ status: :success,
+ created_at: 2.months.ago)
+
+ get :index,
+ format: :html,
+ params: {
+ namespace_id: project.namespace,
+ project_id: project,
+ state: 'all'
+ }
+
+ expect(controller.instance_variable_get(:@branch_pipeline_statuses)["master"].group).to eq("success")
+ end
+ end
+
+ context 'when multiple branches exist' do
+ it 'all relevant commit statuses are received' do
+ master_sha = project.repository.create_file(developer, generate(:branch), 'content', message: 'message', branch_name: 'master')
+ create(:ci_pipeline,
+ project: project,
+ user: developer,
+ ref: "master",
+ sha: master_sha,
+ status: :running,
+ created_at: 6.months.ago)
+ test_sha = project.repository.create_file(developer, generate(:branch), 'content', message: 'message', branch_name: 'test')
+ create(:ci_pipeline,
+ project: project,
+ user: developer,
+ ref: "test",
+ sha: test_sha,
+ status: :success,
+ created_at: 2.months.ago)
+
+ get :index,
+ format: :html,
+ params: {
+ namespace_id: project.namespace,
+ project_id: project,
+ state: 'all'
+ }
+
+ expect(controller.instance_variable_get(:@branch_pipeline_statuses)["master"].group).to eq("running")
+ expect(controller.instance_variable_get(:@branch_pipeline_statuses)["test"].group).to eq("success")
+ end
+ end
+
+ context 'when a branch contains no pipelines' do
+ it 'no commit statuses are received' do
+ get :index,
+ format: :html,
+ params: {
+ namespace_id: project.namespace,
+ project_id: project,
+ state: 'all'
+ }
+
+ expect(controller.instance_variable_get(:@branch_pipeline_statuses)).to be_blank
+ end
+ end
+
# We need :request_store because Gitaly only counts the queries whenever
# `RequestStore.active?` in GitalyClient.enforce_gitaly_request_limits
# And the main goal of this test is making sure TooManyInvocationsError
@@ -564,7 +639,7 @@ describe Projects::BranchesController do
describe 'GET diverging_commit_counts' do
before do
- sign_in(user)
+ sign_in(developer)
end
it 'returns the commit counts behind and ahead of default branch' do
diff --git a/spec/controllers/projects/ci/daily_build_group_report_results_controller_spec.rb b/spec/controllers/projects/ci/daily_build_group_report_results_controller_spec.rb
index ac31045678f..252ad6ec9c4 100644
--- a/spec/controllers/projects/ci/daily_build_group_report_results_controller_spec.rb
+++ b/spec/controllers/projects/ci/daily_build_group_report_results_controller_spec.rb
@@ -2,34 +2,27 @@
require 'spec_helper'
-describe Projects::Ci::DailyBuildGroupReportResultsController do
+RSpec.describe Projects::Ci::DailyBuildGroupReportResultsController do
describe 'GET index' do
let(:project) { create(:project, :public, :repository) }
let(:ref_path) { 'refs/heads/master' }
let(:param_type) { 'coverage' }
let(:start_date) { '2019-12-10' }
let(:end_date) { '2020-03-09' }
-
- def create_daily_coverage(group_name, coverage, date)
- create(
- :ci_daily_build_group_report_result,
- project: project,
- ref_path: ref_path,
- group_name: group_name,
- data: { 'coverage' => coverage },
- date: date
- )
- end
-
- def csv_response
- CSV.parse(response.body)
- end
+ let(:allowed_to_read) { true }
+ let(:user) { create(:user) }
before do
create_daily_coverage('rspec', 79.0, '2020-03-09')
+ create_daily_coverage('rspec', 77.0, '2020-03-08')
create_daily_coverage('karma', 81.0, '2019-12-10')
- create_daily_coverage('rspec', 67.0, '2019-12-09')
- create_daily_coverage('karma', 71.0, '2019-12-09')
+ create_daily_coverage('minitest', 67.0, '2019-12-09')
+ create_daily_coverage('mocha', 71.0, '2019-12-09')
+
+ sign_in(user)
+
+ allow(Ability).to receive(:allowed?).and_call_original
+ allow(Ability).to receive(:allowed?).with(user, :read_build_report_results, project).and_return(allowed_to_read)
get :index, params: {
namespace_id: project.namespace,
@@ -38,43 +31,126 @@ describe Projects::Ci::DailyBuildGroupReportResultsController do
param_type: param_type,
start_date: start_date,
end_date: end_date,
- format: :csv
+ format: format
}
end
- it 'serves the results in CSV' do
- expect(response).to have_gitlab_http_status(:ok)
- expect(response.headers['Content-Type']).to eq('text/csv; charset=utf-8')
+ shared_examples_for 'validating param_type' do
+ context 'when given param_type is invalid' do
+ let(:param_type) { 'something_else' }
- expect(csv_response).to eq([
- %w[date group_name coverage],
- ['2020-03-09', 'rspec', '79.0'],
- ['2019-12-10', 'karma', '81.0']
- ])
+ it 'responds with 422 error' do
+ expect(response).to have_gitlab_http_status(:unprocessable_entity)
+ end
+ end
end
- context 'when given date range spans more than 90 days' do
- let(:start_date) { '2019-12-09' }
- let(:end_date) { '2020-03-09' }
+ shared_examples_for 'ensuring policy' do
+ context 'when user is not allowed to read build report results' do
+ let(:allowed_to_read) { false }
+
+ it 'responds with 404 error' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
- it 'limits the result to 90 days from the given start_date' do
+ context 'when format is CSV' do
+ let(:format) { :csv }
+
+ it 'serves the results in CSV' do
expect(response).to have_gitlab_http_status(:ok)
expect(response.headers['Content-Type']).to eq('text/csv; charset=utf-8')
expect(csv_response).to eq([
%w[date group_name coverage],
['2020-03-09', 'rspec', '79.0'],
+ ['2020-03-08', 'rspec', '77.0'],
['2019-12-10', 'karma', '81.0']
])
end
+
+ context 'when given date range spans more than 90 days' do
+ let(:start_date) { '2019-12-09' }
+ let(:end_date) { '2020-03-09' }
+
+ it 'limits the result to 90 days from the given start_date' do
+ expect(csv_response).to eq([
+ %w[date group_name coverage],
+ ['2020-03-09', 'rspec', '79.0'],
+ ['2020-03-08', 'rspec', '77.0'],
+ ['2019-12-10', 'karma', '81.0']
+ ])
+ end
+ end
+
+ it_behaves_like 'validating param_type'
+ it_behaves_like 'ensuring policy'
end
- context 'when given param_type is invalid' do
- let(:param_type) { 'something_else' }
+ context 'when format is JSON' do
+ let(:format) { :json }
+
+ it 'serves the results in JSON' do
+ expect(response).to have_gitlab_http_status(:ok)
- it 'responds with 422 error' do
- expect(response).to have_gitlab_http_status(:unprocessable_entity)
+ expect(json_response).to eq([
+ {
+ 'group_name' => 'rspec',
+ 'data' => [
+ { 'date' => '2020-03-09', 'coverage' => 79.0 },
+ { 'date' => '2020-03-08', 'coverage' => 77.0 }
+ ]
+ },
+ {
+ 'group_name' => 'karma',
+ 'data' => [
+ { 'date' => '2019-12-10', 'coverage' => 81.0 }
+ ]
+ }
+ ])
end
+
+ context 'when given date range spans more than 90 days' do
+ let(:start_date) { '2019-12-09' }
+ let(:end_date) { '2020-03-09' }
+
+ it 'limits the result to 90 days from the given start_date' do
+ expect(json_response).to eq([
+ {
+ 'group_name' => 'rspec',
+ 'data' => [
+ { 'date' => '2020-03-09', 'coverage' => 79.0 },
+ { 'date' => '2020-03-08', 'coverage' => 77.0 }
+ ]
+ },
+ {
+ 'group_name' => 'karma',
+ 'data' => [
+ { 'date' => '2019-12-10', 'coverage' => 81.0 }
+ ]
+ }
+ ])
+ end
+ end
+
+ it_behaves_like 'validating param_type'
+ it_behaves_like 'ensuring policy'
end
end
+
+ def create_daily_coverage(group_name, coverage, date)
+ create(
+ :ci_daily_build_group_report_result,
+ project: project,
+ ref_path: ref_path,
+ group_name: group_name,
+ data: { 'coverage' => coverage },
+ date: date
+ )
+ end
+
+ def csv_response
+ CSV.parse(response.body)
+ end
end
diff --git a/spec/controllers/projects/ci/lints_controller_spec.rb b/spec/controllers/projects/ci/lints_controller_spec.rb
index f45b1d7ddd8..eb92385fc83 100644
--- a/spec/controllers/projects/ci/lints_controller_spec.rb
+++ b/spec/controllers/projects/ci/lints_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Ci::LintsController do
+RSpec.describe Projects::Ci::LintsController do
include StubRequests
let(:project) { create(:project, :repository) }
diff --git a/spec/controllers/projects/clusters/applications_controller_spec.rb b/spec/controllers/projects/clusters/applications_controller_spec.rb
index 6de3593be28..b50814b4790 100644
--- a/spec/controllers/projects/clusters/applications_controller_spec.rb
+++ b/spec/controllers/projects/clusters/applications_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Clusters::ApplicationsController do
+RSpec.describe Projects::Clusters::ApplicationsController do
include AccessMatchersForController
def current_application
diff --git a/spec/controllers/projects/clusters_controller_spec.rb b/spec/controllers/projects/clusters_controller_spec.rb
index 698a3773d59..5645e25b741 100644
--- a/spec/controllers/projects/clusters_controller_spec.rb
+++ b/spec/controllers/projects/clusters_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ClustersController do
+RSpec.describe Projects::ClustersController do
include AccessMatchersForController
include GoogleApi::CloudPlatformHelpers
include KubernetesHelpers
@@ -41,6 +41,13 @@ describe Projects::ClustersController do
expect(response).to match_response_schema('cluster_list')
end
+ it 'sets the polling interval header for json requests' do
+ go(format: :json)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.headers['Poll-Interval']).to eq("10000")
+ end
+
context 'when page is specified' do
let(:last_page) { project.clusters.page.total_pages }
let(:total_count) { project.clusters.page.total_count }
diff --git a/spec/controllers/projects/commit_controller_spec.rb b/spec/controllers/projects/commit_controller_spec.rb
index c8ddd181d10..706bf787b2d 100644
--- a/spec/controllers/projects/commit_controller_spec.rb
+++ b/spec/controllers/projects/commit_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::CommitController do
+RSpec.describe Projects::CommitController do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/commits_controller_spec.rb b/spec/controllers/projects/commits_controller_spec.rb
index 1977e92e42b..557002acbc0 100644
--- a/spec/controllers/projects/commits_controller_spec.rb
+++ b/spec/controllers/projects/commits_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::CommitsController do
+RSpec.describe Projects::CommitsController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/compare_controller_spec.rb b/spec/controllers/projects/compare_controller_spec.rb
index d1a4a9a0058..6aa4bfe235b 100644
--- a/spec/controllers/projects/compare_controller_spec.rb
+++ b/spec/controllers/projects/compare_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::CompareController do
+RSpec.describe Projects::CompareController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/cycle_analytics/events_controller_spec.rb b/spec/controllers/projects/cycle_analytics/events_controller_spec.rb
index 942e095d669..408ce51d34b 100644
--- a/spec/controllers/projects/cycle_analytics/events_controller_spec.rb
+++ b/spec/controllers/projects/cycle_analytics/events_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::CycleAnalytics::EventsController do
+RSpec.describe Projects::CycleAnalytics::EventsController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/cycle_analytics_controller_spec.rb b/spec/controllers/projects/cycle_analytics_controller_spec.rb
index 65eee7b8ead..8feb964cdde 100644
--- a/spec/controllers/projects/cycle_analytics_controller_spec.rb
+++ b/spec/controllers/projects/cycle_analytics_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::CycleAnalyticsController do
+RSpec.describe Projects::CycleAnalyticsController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/deploy_keys_controller_spec.rb b/spec/controllers/projects/deploy_keys_controller_spec.rb
index 9d41e2f59cb..821f7fca73d 100644
--- a/spec/controllers/projects/deploy_keys_controller_spec.rb
+++ b/spec/controllers/projects/deploy_keys_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::DeployKeysController do
+RSpec.describe Projects::DeployKeysController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:admin) { create(:admin) }
diff --git a/spec/controllers/projects/deployments_controller_spec.rb b/spec/controllers/projects/deployments_controller_spec.rb
index 37dcfa78772..85dd86d91e9 100644
--- a/spec/controllers/projects/deployments_controller_spec.rb
+++ b/spec/controllers/projects/deployments_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::DeploymentsController do
+RSpec.describe Projects::DeploymentsController do
include ApiHelpers
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/design_management/designs/raw_images_controller_spec.rb b/spec/controllers/projects/design_management/designs/raw_images_controller_spec.rb
index 30d2b79a92f..f664604ac15 100644
--- a/spec/controllers/projects/design_management/designs/raw_images_controller_spec.rb
+++ b/spec/controllers/projects/design_management/designs/raw_images_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::DesignManagement::Designs::RawImagesController do
+RSpec.describe Projects::DesignManagement::Designs::RawImagesController do
include DesignManagementTestHelpers
let_it_be(:project) { create(:project, :private) }
diff --git a/spec/controllers/projects/design_management/designs/resized_image_controller_spec.rb b/spec/controllers/projects/design_management/designs/resized_image_controller_spec.rb
index 6bfec1b314e..96ecbaf55b6 100644
--- a/spec/controllers/projects/design_management/designs/resized_image_controller_spec.rb
+++ b/spec/controllers/projects/design_management/designs/resized_image_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::DesignManagement::Designs::ResizedImageController do
+RSpec.describe Projects::DesignManagement::Designs::ResizedImageController do
include DesignManagementTestHelpers
let_it_be(:project) { create(:project, :private) }
diff --git a/spec/controllers/projects/discussions_controller_spec.rb b/spec/controllers/projects/discussions_controller_spec.rb
index b2e4a3b7b0d..f2efd40afdb 100644
--- a/spec/controllers/projects/discussions_controller_spec.rb
+++ b/spec/controllers/projects/discussions_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::DiscussionsController do
+RSpec.describe Projects::DiscussionsController do
let(:user) { create(:user) }
let(:merge_request) { create(:merge_request) }
let(:project) { merge_request.source_project }
diff --git a/spec/controllers/projects/environments/prometheus_api_controller_spec.rb b/spec/controllers/projects/environments/prometheus_api_controller_spec.rb
index fb8da52930c..17952aa0683 100644
--- a/spec/controllers/projects/environments/prometheus_api_controller_spec.rb
+++ b/spec/controllers/projects/environments/prometheus_api_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Environments::PrometheusApiController do
+RSpec.describe Projects::Environments::PrometheusApiController do
let_it_be(:project) { create(:project) }
let_it_be(:environment) { create(:environment, project: project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/environments/sample_metrics_controller_spec.rb b/spec/controllers/projects/environments/sample_metrics_controller_spec.rb
index 19b07a2ccc4..14e3ded76f2 100644
--- a/spec/controllers/projects/environments/sample_metrics_controller_spec.rb
+++ b/spec/controllers/projects/environments/sample_metrics_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Environments::SampleMetricsController do
+RSpec.describe Projects::Environments::SampleMetricsController do
include StubENV
let_it_be(:project) { create(:project) }
diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb
index 56fff2771ec..cca4b597f4c 100644
--- a/spec/controllers/projects/environments_controller_spec.rb
+++ b/spec/controllers/projects/environments_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::EnvironmentsController do
+RSpec.describe Projects::EnvironmentsController do
include MetricsDashboardHelpers
let_it_be(:project) { create(:project) }
@@ -354,6 +354,19 @@ describe Projects::EnvironmentsController do
expect(response).to redirect_to(environment_metrics_path(environment))
end
+ context 'with anonymous user and public dashboard visibility' do
+ let(:project) { create(:project, :public) }
+ let(:user) { create(:user) }
+
+ it 'redirects successfully' do
+ project.project_feature.update!(metrics_dashboard_access_level: ProjectFeature::ENABLED)
+
+ get :metrics_redirect, params: { namespace_id: project.namespace, project_id: project }
+
+ expect(response).to redirect_to(environment_metrics_path(environment))
+ end
+ end
+
context 'when there are no environments' do
let(:environment) { }
@@ -422,6 +435,19 @@ describe Projects::EnvironmentsController do
get :metrics, params: environment_params
end
end
+
+ context 'with anonymous user and public dashboard visibility' do
+ let(:project) { create(:project, :public) }
+ let(:user) { create(:user) }
+
+ it 'returns success' do
+ project.project_feature.update!(metrics_dashboard_access_level: ProjectFeature::ENABLED)
+
+ get :metrics, params: environment_params
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
end
describe 'GET #additional_metrics' do
@@ -497,6 +523,26 @@ describe Projects::EnvironmentsController do
get :metrics, params: environment_params
end
end
+
+ context 'with anonymous user and public dashboard visibility' do
+ let(:project) { create(:project, :public) }
+ let(:user) { create(:user) }
+
+ it 'does not fail' do
+ allow(environment)
+ .to receive(:additional_metrics)
+ .and_return({
+ success: true,
+ data: {},
+ last_update: 42
+ })
+ project.project_feature.update!(metrics_dashboard_access_level: ProjectFeature::ENABLED)
+
+ additional_metrics(window_params)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
end
describe 'GET #metrics_dashboard' do
@@ -673,6 +719,17 @@ describe Projects::EnvironmentsController do
it_behaves_like 'dashboard can be specified'
it_behaves_like 'dashboard can be embedded'
+ context 'with anonymous user and public dashboard visibility' do
+ let(:project) { create(:project, :public) }
+ let(:user) { create(:user) }
+
+ before do
+ project.project_feature.update!(metrics_dashboard_access_level: ProjectFeature::ENABLED)
+ end
+
+ it_behaves_like 'the default dashboard'
+ end
+
context 'permissions' do
before do
allow(controller).to receive(:can?).and_return true
diff --git a/spec/controllers/projects/error_tracking/projects_controller_spec.rb b/spec/controllers/projects/error_tracking/projects_controller_spec.rb
index 1737528b597..67947d1c9d9 100644
--- a/spec/controllers/projects/error_tracking/projects_controller_spec.rb
+++ b/spec/controllers/projects/error_tracking/projects_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ErrorTracking::ProjectsController do
+RSpec.describe Projects::ErrorTracking::ProjectsController do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/error_tracking/stack_traces_controller_spec.rb b/spec/controllers/projects/error_tracking/stack_traces_controller_spec.rb
index 27d49147e99..7c080504c31 100644
--- a/spec/controllers/projects/error_tracking/stack_traces_controller_spec.rb
+++ b/spec/controllers/projects/error_tracking/stack_traces_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ErrorTracking::StackTracesController do
+RSpec.describe Projects::ErrorTracking::StackTracesController do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/error_tracking_controller_spec.rb b/spec/controllers/projects/error_tracking_controller_spec.rb
index 6be979418ad..5ea885e4fd6 100644
--- a/spec/controllers/projects/error_tracking_controller_spec.rb
+++ b/spec/controllers/projects/error_tracking_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ErrorTrackingController do
+RSpec.describe Projects::ErrorTrackingController do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/find_file_controller_spec.rb b/spec/controllers/projects/find_file_controller_spec.rb
index 4d8933f3aaf..a6c71cff74b 100644
--- a/spec/controllers/projects/find_file_controller_spec.rb
+++ b/spec/controllers/projects/find_file_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::FindFileController do
+RSpec.describe Projects::FindFileController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/forks_controller_spec.rb b/spec/controllers/projects/forks_controller_spec.rb
index e362790cd3c..4c0fd7b8954 100644
--- a/spec/controllers/projects/forks_controller_spec.rb
+++ b/spec/controllers/projects/forks_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ForksController do
+RSpec.describe Projects::ForksController do
let(:user) { create(:user) }
let(:project) { create(:project, :public, :repository) }
let(:forked_project) { Projects::ForkService.new(project, user, name: 'Some name').execute }
diff --git a/spec/controllers/projects/grafana_api_controller_spec.rb b/spec/controllers/projects/grafana_api_controller_spec.rb
index 8502bd1ab0a..baee9705127 100644
--- a/spec/controllers/projects/grafana_api_controller_spec.rb
+++ b/spec/controllers/projects/grafana_api_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::GrafanaApiController do
+RSpec.describe Projects::GrafanaApiController do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/graphs_controller_spec.rb b/spec/controllers/projects/graphs_controller_spec.rb
index e589815c45d..12cef6bea09 100644
--- a/spec/controllers/projects/graphs_controller_spec.rb
+++ b/spec/controllers/projects/graphs_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::GraphsController do
+RSpec.describe Projects::GraphsController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
@@ -42,23 +42,42 @@ describe Projects::GraphsController do
expect(response).to render_template(:charts)
end
- it 'sets the daily coverage options' do
- Timecop.freeze do
+ context 'when anonymous users can read build report results' do
+ it 'sets the daily coverage options' do
+ Timecop.freeze do
+ get(:charts, params: { namespace_id: project.namespace.path, project_id: project.path, id: 'master' })
+
+ expect(assigns[:daily_coverage_options]).to eq(
+ base_params: {
+ start_date: Date.current - 90.days,
+ end_date: Date.current,
+ ref_path: project.repository.expand_ref('master'),
+ param_type: 'coverage'
+ },
+ download_path: namespace_project_ci_daily_build_group_report_results_path(
+ namespace_id: project.namespace,
+ project_id: project,
+ format: :csv
+ ),
+ graph_api_path: namespace_project_ci_daily_build_group_report_results_path(
+ namespace_id: project.namespace,
+ project_id: project,
+ format: :json
+ )
+ )
+ end
+ end
+ end
+
+ context 'when anonymous users cannot read build report results' do
+ before do
+ project.update_column(:public_builds, false)
+
get(:charts, params: { namespace_id: project.namespace.path, project_id: project.path, id: 'master' })
+ end
- expect(assigns[:daily_coverage_options]).to eq(
- base_params: {
- start_date: Time.current.to_date - 90.days,
- end_date: Time.current.to_date,
- ref_path: project.repository.expand_ref('master'),
- param_type: 'coverage'
- },
- download_path: namespace_project_ci_daily_build_group_report_results_path(
- namespace_id: project.namespace,
- project_id: project,
- format: :csv
- )
- )
+ it 'does not set daily coverage options' do
+ expect(assigns[:daily_coverage_options]).to be_nil
end
end
end
diff --git a/spec/controllers/projects/group_links_controller_spec.rb b/spec/controllers/projects/group_links_controller_spec.rb
index 28999257957..762ef795f6e 100644
--- a/spec/controllers/projects/group_links_controller_spec.rb
+++ b/spec/controllers/projects/group_links_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::GroupLinksController do
+RSpec.describe Projects::GroupLinksController do
let(:group) { create(:group, :private) }
let(:group2) { create(:group, :private) }
let(:project) { create(:project, :private, group: group2) }
diff --git a/spec/controllers/projects/hooks_controller_spec.rb b/spec/controllers/projects/hooks_controller_spec.rb
index e97f602d9ab..440e6b2a74c 100644
--- a/spec/controllers/projects/hooks_controller_spec.rb
+++ b/spec/controllers/projects/hooks_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::HooksController do
+RSpec.describe Projects::HooksController do
let(:project) { create(:project) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/import/jira_controller_spec.rb b/spec/controllers/projects/import/jira_controller_spec.rb
index d1b0a086576..b82735a56b3 100644
--- a/spec/controllers/projects/import/jira_controller_spec.rb
+++ b/spec/controllers/projects/import/jira_controller_spec.rb
@@ -2,230 +2,101 @@
require 'spec_helper'
-describe Projects::Import::JiraController do
+RSpec.describe Projects::Import::JiraController do
include JiraServiceHelper
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:jira_project_key) { 'Test' }
- context 'with anonymous user' do
- before do
- stub_feature_flags(jira_issue_import: true)
- end
+ def ensure_correct_config
+ sign_in(user)
+ project.add_maintainer(user)
+ stub_feature_flags(jira_issue_import: true)
+ stub_jira_service_test
+ end
- context 'get show' do
- it 'redirects to issues page' do
- get :show, params: { namespace_id: project.namespace, project_id: project }
+ shared_examples 'redirect with error' do |error|
+ it 'redirects to project issues path' do
+ subject
- expect(response).to redirect_to(new_user_session_path)
- end
+ expect(response).to redirect_to(project_issues_path(project))
end
- context 'post import' do
- it 'redirects to issues page' do
- post :import, params: { namespace_id: project.namespace, project_id: project, jira_project_key: jira_project_key }
+ it 'renders a correct error' do
+ subject
- expect(response).to redirect_to(new_user_session_path)
- end
+ expect(flash[:notice]).to eq(error)
end
end
- context 'with logged in user' do
- before do
- sign_in(user)
- project.add_maintainer(user)
- end
+ shared_examples 'template with no message' do
+ it 'does not set any message' do
+ subject
- context 'when feature flag not enabled' do
- before do
- stub_feature_flags(jira_issue_import: false)
- end
+ expect(flash).to be_empty
+ end
- context 'get show' do
- it 'redirects to issues page' do
- get :show, params: { namespace_id: project.namespace, project_id: project }
+ it 'renders show template' do
+ subject
- expect(response).to redirect_to(project_issues_path(project))
- end
- end
+ expect(response).to render_template(template)
+ end
+ end
- context 'post import' do
- it 'redirects to issues page' do
- post :import, params: { namespace_id: project.namespace, project_id: project, jira_project_key: jira_project_key }
+ shared_examples 'users without permissions' do
+ context 'with anonymous user' do
+ it 'redirects to new user page' do
+ subject
- expect(response).to redirect_to(project_issues_path(project))
- end
+ expect(response).to redirect_to(new_user_session_path)
end
end
- context 'when feature flag enabled' do
+ context 'when loged user is a developer' do
before do
- stub_feature_flags(jira_issue_import: true)
- stub_feature_flags(jira_issue_import_vue: false)
+ create(:jira_service, project: project)
stub_jira_service_test
- end
-
- context 'when Jira service is enabled for the project' do
- let_it_be(:jira_service) { create(:jira_service, project: project) }
-
- context 'when user is developer' do
- let_it_be(:dev) { create(:user) }
-
- before do
- sign_in(dev)
- project.add_developer(dev)
- end
-
- context 'get show' do
- before do
- get :show, params: { namespace_id: project.namespace.to_param, project_id: project }
- end
-
- it 'does not query Jira service' do
- expect(project).not_to receive(:jira_service)
- end
-
- it 'renders show template' do
- expect(response).to render_template(:show)
- expect(assigns(:jira_projects)).not_to be_present
- end
- end
-
- context 'post import' do
- it 'returns 404' do
- post :import, params: { namespace_id: project.namespace, project_id: project, jira_project_key: jira_project_key }
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
- end
-
- context 'when issues disabled' do
- let_it_be(:disabled_issues_project) { create(:project, :public, :issues_disabled) }
-
- context 'get show' do
- it 'returs 404' do
- get :show, params: { namespace_id: project.namespace.to_param, project_id: disabled_issues_project }
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
-
- context 'post import' do
- it 'returs 404' do
- post :import, params: { namespace_id: disabled_issues_project.namespace, project_id: disabled_issues_project, jira_project_key: jira_project_key }
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
- end
-
- context 'when running Jira import first time' do
- context 'get show' do
- before do
- allow(JIRA::Resource::Project).to receive(:all).and_return(jira_projects)
-
- expect(project.jira_imports).to be_empty
-
- get :show, params: { namespace_id: project.namespace.to_param, project_id: project }
- end
-
- context 'when no projects have been retrieved from Jira' do
- let(:jira_projects) { [] }
-
- it 'render an error message' do
- expect(flash[:alert]).to eq('No projects have been returned from Jira. Please check your Jira configuration.')
- expect(response).to render_template(:show)
- end
- end
-
- context 'when projects retrieved from Jira' do
- let(:jira_projects) { [double(name: 'FOO project', key: 'FOO')] }
-
- it 'renders show template' do
- expect(response).to render_template(:show)
- end
- end
- end
+ sign_in(user)
+ project.add_developer(user)
+ end
- context 'post import' do
- context 'when Jira project key is empty' do
- it 'redirects back to show with an error' do
- post :import, params: { namespace_id: project.namespace, project_id: project, jira_project_key: '' }
+ it_behaves_like 'redirect with error', 'You do not have permissions to run the import.'
+ end
+ end
- expect(response).to redirect_to(project_import_jira_path(project))
- expect(flash[:alert]).to eq('No Jira project key has been provided.')
- end
- end
+ describe 'GET #show' do
+ let(:template) { 'show' }
- context 'when everything is ok' do
- it 'creates import state' do
- expect(project.latest_jira_import).to be_nil
+ subject { get :show, params: { namespace_id: project.namespace, project_id: project } }
- post :import, params: { namespace_id: project.namespace, project_id: project, jira_project_key: jira_project_key }
+ it_behaves_like 'users without permissions'
- project.reload
+ context 'jira service configuration' do
+ before do
+ sign_in(user)
+ project.add_maintainer(user)
+ stub_feature_flags(jira_issue_import: true)
+ end
- jira_import = project.latest_jira_import
- expect(project.import_type).to eq 'jira'
- expect(jira_import.status).to eq 'scheduled'
- expect(jira_import.jira_project_key).to eq jira_project_key
- expect(response).to redirect_to(project_import_jira_path(project))
- end
- end
- end
+ context 'when Jira service is not enabled for the project' do
+ it 'does not query Jira service' do
+ expect(project).not_to receive(:jira_service)
end
- context 'when import state is scheduled' do
- let_it_be(:jira_import_state) { create(:jira_import_state, :scheduled, project: project) }
-
- context 'get show' do
- it 'renders import status' do
- get :show, params: { namespace_id: project.namespace.to_param, project_id: project }
-
- jira_import = project.latest_jira_import
- expect(jira_import.status).to eq 'scheduled'
- expect(flash.now[:notice]).to eq 'Import scheduled'
- end
- end
+ it_behaves_like 'template with no message'
+ end
- context 'post import' do
- it 'uses the existing import data' do
- post :import, params: { namespace_id: project.namespace, project_id: project, jira_project_key: 'New Project' }
+ context 'when Jira service is not configured correctly for the project' do
+ let_it_be(:jira_service) { create(:jira_service, project: project) }
- expect(flash[:notice]).to eq('Jira import is already running.')
- expect(response).to redirect_to(project_import_jira_path(project))
- end
- end
+ before do
+ WebMock.stub_request(:get, 'https://jira.example.com/rest/api/2/serverInfo')
+ .to_raise(JIRA::HTTPError.new(double(message: 'Some failure.')))
end
- context 'when Jira import ran before' do
- let_it_be(:jira_import_state) { create(:jira_import_state, :finished, project: project, jira_project_key: jira_project_key) }
-
- context 'get show' do
- it 'renders import status' do
- allow(JIRA::Resource::Project).to receive(:all).and_return([])
- get :show, params: { namespace_id: project.namespace.to_param, project_id: project }
-
- expect(project.latest_jira_import.status).to eq 'finished'
- expect(flash.now[:notice]).to eq 'Import finished'
- end
- end
-
- context 'post import' do
- it 'uses the existing import data' do
- post :import, params: { namespace_id: project.namespace, project_id: project, jira_project_key: 'New Project' }
-
- project.reload
- expect(project.latest_jira_import.status).to eq 'scheduled'
- expect(project.jira_imports.size).to eq 2
- expect(project.jira_imports.first.jira_project_key).to eq jira_project_key
- expect(project.jira_imports.last.jira_project_key).to eq 'New Project'
- expect(response).to redirect_to(project_import_jira_path(project))
- end
- end
- end
+ it_behaves_like 'template with no message'
end
end
end
diff --git a/spec/controllers/projects/imports_controller_spec.rb b/spec/controllers/projects/imports_controller_spec.rb
index bdc81efe3bc..29cfd1c352e 100644
--- a/spec/controllers/projects/imports_controller_spec.rb
+++ b/spec/controllers/projects/imports_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ImportsController do
+RSpec.describe Projects::ImportsController do
let(:user) { create(:user) }
let(:project) { create(:project) }
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index 96f11f11dc4..bcd1a53bd47 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::IssuesController do
+RSpec.describe Projects::IssuesController do
include ProjectForksHelper
include_context 'includes Spam constants'
@@ -332,8 +332,7 @@ describe Projects::IssuesController do
end
before do
- allow(controller).to receive(:find_routable!)
- .with(Project, project.full_path, any_args).and_return(project)
+ allow(controller).to receive(:find_routable!).and_return(project)
allow(project).to receive(:default_branch).and_return(master_branch)
allow_next_instance_of(Issues::RelatedBranchesService) do |service|
allow(service).to receive(:execute).and_return(related_branches)
@@ -536,7 +535,7 @@ describe Projects::IssuesController do
before do
stub_application_setting(recaptcha_enabled: true)
expect_next_instance_of(Spam::SpamVerdictService) do |verdict_service|
- expect(verdict_service).to receive(:execute).and_return(REQUIRE_RECAPTCHA)
+ expect(verdict_service).to receive(:execute).and_return(CONDITIONAL_ALLOW)
end
end
@@ -851,7 +850,7 @@ describe Projects::IssuesController do
context 'when recaptcha is not verified' do
before do
expect_next_instance_of(Spam::SpamVerdictService) do |verdict_service|
- expect(verdict_service).to receive(:execute).and_return(REQUIRE_RECAPTCHA)
+ expect(verdict_service).to receive(:execute).and_return(CONDITIONAL_ALLOW)
end
end
@@ -1103,7 +1102,7 @@ describe Projects::IssuesController do
context 'when captcha is not verified' do
before do
expect_next_instance_of(Spam::SpamVerdictService) do |verdict_service|
- expect(verdict_service).to receive(:execute).and_return(REQUIRE_RECAPTCHA)
+ expect(verdict_service).to receive(:execute).and_return(CONDITIONAL_ALLOW)
end
end
diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb
index ef1253edda5..44dcb0caab2 100644
--- a/spec/controllers/projects/jobs_controller_spec.rb
+++ b/spec/controllers/projects/jobs_controller_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe Projects::JobsController, :clean_gitlab_redis_shared_state do
+RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do
include ApiHelpers
include HttpIOHelpers
@@ -1225,4 +1225,198 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
get :terminal_websocket_authorize, params: params.merge(extra_params)
end
end
+
+ describe 'GET #proxy_websocket_authorize' do
+ let_it_be(:owner) { create(:owner) }
+ let_it_be(:admin) { create(:admin) }
+ let_it_be(:maintainer) { create(:user) }
+ let_it_be(:developer) { create(:user) }
+ let_it_be(:reporter) { create(:user) }
+ let_it_be(:guest) { create(:user) }
+ let_it_be(:project) { create(:project, :private, :repository, namespace: owner.namespace) }
+ let(:user) { maintainer }
+ let(:pipeline) { create(:ci_pipeline, project: project, source: :webide, config_source: :webide_source, user: user) }
+ let(:job) { create(:ci_build, :running, :with_runner_session, pipeline: pipeline, user: user) }
+ let(:extra_params) { { id: job.id } }
+ let(:path) { :proxy_websocket_authorize }
+ let(:render_method) { :channel_websocket }
+ let(:expected_data) do
+ {
+ 'Channel' => {
+ 'Subprotocols' => ["terminal.gitlab.com"],
+ 'Url' => 'wss://localhost/proxy/build/default_port/',
+ 'Header' => {
+ 'Authorization' => [nil]
+ },
+ 'MaxSessionTime' => nil,
+ 'CAPem' => nil
+ }
+ }.to_json
+ end
+
+ before do
+ stub_feature_flags(build_service_proxy: true)
+ allow(job).to receive(:has_terminal?).and_return(true)
+
+ project.add_maintainer(maintainer)
+ project.add_developer(developer)
+ project.add_reporter(reporter)
+ project.add_guest(guest)
+
+ sign_in(user)
+ end
+
+ context 'access rights' do
+ before do
+ allow(Gitlab::Workhorse).to receive(:verify_api_request!).and_return(nil)
+
+ make_request
+ end
+
+ context 'with admin' do
+ let(:user) { admin }
+
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it 'returns 200' do
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'when admin mode is disabled' do
+ it 'returns 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ context 'with owner' do
+ let(:user) { owner }
+
+ it 'returns 200' do
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'with maintainer' do
+ let(:user) { maintainer }
+
+ it 'returns 200' do
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'with developer' do
+ let(:user) { developer }
+
+ it 'returns 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'with reporter' do
+ let(:user) { reporter }
+
+ it 'returns 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'with guest' do
+ let(:user) { guest }
+
+ it 'returns 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'with non member' do
+ let(:user) { create(:user) }
+
+ it 'returns 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ context 'when pipeline is not from a webide source' do
+ context 'with admin' do
+ let(:user) { admin }
+ let(:pipeline) { create(:ci_pipeline, project: project, source: :chat, user: user) }
+
+ before do
+ allow(Gitlab::Workhorse).to receive(:verify_api_request!).and_return(nil)
+ make_request
+ end
+
+ it 'returns 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ context 'when workhorse signature is valid' do
+ before do
+ allow(Gitlab::Workhorse).to receive(:verify_api_request!).and_return(nil)
+ end
+
+ context 'and the id is valid' do
+ it 'returns the proxy data for the service running in the job' do
+ make_request
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.headers["Content-Type"]).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
+ expect(response.body).to eq(expected_data)
+ end
+ end
+
+ context 'and the id is invalid' do
+ let(:extra_params) { { id: non_existing_record_id } }
+
+ it 'returns 404' do
+ make_request
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ context 'with invalid workhorse signature' do
+ it 'aborts with an exception' do
+ allow(Gitlab::Workhorse).to receive(:verify_api_request!).and_raise(JWT::DecodeError)
+
+ expect { make_request }.to raise_error(JWT::DecodeError)
+ end
+ end
+
+ context 'when feature flag :build_service_proxy is disabled' do
+ let(:user) { admin }
+
+ it 'returns 404' do
+ allow(Gitlab::Workhorse).to receive(:verify_api_request!).and_return(nil)
+ stub_feature_flags(build_service_proxy: false)
+
+ make_request
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ it 'converts the url scheme into wss' do
+ allow(Gitlab::Workhorse).to receive(:verify_api_request!).and_return(nil)
+
+ expect(job.runner_session_url).to start_with('https://')
+ expect(Gitlab::Workhorse).to receive(:channel_websocket).with(a_hash_including(url: "wss://localhost/proxy/build/default_port/"))
+
+ make_request
+ end
+
+ def make_request
+ params = {
+ namespace_id: project.namespace.to_param,
+ project_id: project
+ }
+
+ get path, params: params.merge(extra_params)
+ end
+ end
end
diff --git a/spec/controllers/projects/labels_controller_spec.rb b/spec/controllers/projects/labels_controller_spec.rb
index c6098f5934d..f213d104747 100644
--- a/spec/controllers/projects/labels_controller_spec.rb
+++ b/spec/controllers/projects/labels_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::LabelsController do
+RSpec.describe Projects::LabelsController do
let(:group) { create(:group) }
let(:project) { create(:project, namespace: group) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/logs_controller_spec.rb b/spec/controllers/projects/logs_controller_spec.rb
index e86a42b03c8..1eb5a6fcc12 100644
--- a/spec/controllers/projects/logs_controller_spec.rb
+++ b/spec/controllers/projects/logs_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::LogsController do
+RSpec.describe Projects::LogsController do
include KubernetesHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/mattermosts_controller_spec.rb b/spec/controllers/projects/mattermosts_controller_spec.rb
index 693176d0cfc..001f2564698 100644
--- a/spec/controllers/projects/mattermosts_controller_spec.rb
+++ b/spec/controllers/projects/mattermosts_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MattermostsController do
+RSpec.describe Projects::MattermostsController do
let!(:project) { create(:project) }
let!(:user) { create(:user) }
diff --git a/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb b/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb
index 8e4ac64f7b0..5f636bd4340 100644
--- a/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MergeRequests::ConflictsController do
+RSpec.describe Projects::MergeRequests::ConflictsController do
let(:project) { create(:project, :repository) }
let(:user) { project.owner }
let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) }
diff --git a/spec/controllers/projects/merge_requests/content_controller_spec.rb b/spec/controllers/projects/merge_requests/content_controller_spec.rb
index 72eedc837a4..7fb20b4666a 100644
--- a/spec/controllers/projects/merge_requests/content_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/content_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MergeRequests::ContentController do
+RSpec.describe Projects::MergeRequests::ContentController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:merge_request) { create(:merge_request, target_project: project, source_project: project) }
diff --git a/spec/controllers/projects/merge_requests/creations_controller_spec.rb b/spec/controllers/projects/merge_requests/creations_controller_spec.rb
index db25ad62019..091a44130a1 100644
--- a/spec/controllers/projects/merge_requests/creations_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/creations_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MergeRequests::CreationsController do
+RSpec.describe Projects::MergeRequests::CreationsController do
let(:project) { create(:project, :repository) }
let(:user) { project.owner }
let(:fork_project) { create(:forked_project_with_submodules) }
diff --git a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
index 3d9193e3e33..02b4c2d1da9 100644
--- a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MergeRequests::DiffsController do
+RSpec.describe Projects::MergeRequests::DiffsController do
include ProjectForksHelper
shared_examples '404 for unexistent diffable' do
diff --git a/spec/controllers/projects/merge_requests/drafts_controller_spec.rb b/spec/controllers/projects/merge_requests/drafts_controller_spec.rb
new file mode 100644
index 00000000000..7d74e872d29
--- /dev/null
+++ b/spec/controllers/projects/merge_requests/drafts_controller_spec.rb
@@ -0,0 +1,455 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Projects::MergeRequests::DraftsController do
+ include RepoHelpers
+
+ let(:project) { create(:project, :repository) }
+ let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) }
+ let(:user) { project.owner }
+ let(:user2) { create(:user) }
+
+ let(:params) do
+ {
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ merge_request_id: merge_request.iid
+ }
+ end
+
+ before do
+ sign_in(user)
+ stub_licensed_features(multiple_merge_request_assignees: true)
+ stub_commonmark_sourcepos_disabled
+ end
+
+ describe 'GET #index' do
+ let!(:draft_note) { create(:draft_note, merge_request: merge_request, author: user) }
+
+ it 'list merge request draft notes for current user' do
+ get :index, params: params
+
+ expect(json_response.first['merge_request_id']).to eq(merge_request.id)
+ expect(json_response.first['author']['id']).to eq(user.id)
+ expect(json_response.first['note_html']).not_to be_empty
+ end
+ end
+
+ describe 'POST #create' do
+ def create_draft_note(draft_overrides: {}, overrides: {})
+ post_params = params.merge({
+ draft_note: {
+ note: 'This is a unpublished comment'
+ }.merge(draft_overrides)
+ }.merge(overrides))
+
+ post :create, params: post_params
+ end
+
+ context 'without permissions' do
+ let(:project) { create(:project, :private) }
+
+ before do
+ sign_in(user2)
+ end
+
+ it 'does not allow draft note creation' do
+ expect { create_draft_note }.to change { DraftNote.count }.by(0)
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ it 'creates a draft note' do
+ expect { create_draft_note }.to change { DraftNote.count }.by(1)
+ end
+
+ it 'creates draft note with position' do
+ diff_refs = project.commit(sample_commit.id).try(:diff_refs)
+
+ position = Gitlab::Diff::Position.new(
+ old_path: "files/ruby/popen.rb",
+ new_path: "files/ruby/popen.rb",
+ old_line: nil,
+ new_line: 14,
+ diff_refs: diff_refs
+ )
+
+ create_draft_note(draft_overrides: { position: position.to_json })
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['position']).to be_present
+ expect(json_response['file_hash']).to be_present
+ expect(json_response['file_identifier_hash']).to be_present
+ expect(json_response['line_code']).to match(/\w+_\d+_\d+/)
+ expect(json_response['note_html']).to eq('<p dir="auto">This is a unpublished comment</p>')
+ end
+
+ it 'creates a draft note with quick actions' do
+ create_draft_note(draft_overrides: { note: "#{user2.to_reference}\n/assign #{user.to_reference}" })
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['note_html']).to match(/#{user2.to_reference}/)
+ expect(json_response['references']['commands']).to match(/Assigns/)
+ expect(json_response['references']['users']).to include(user2.username)
+ end
+
+ context 'in a thread' do
+ let(:discussion) { create(:discussion_note_on_merge_request, noteable: merge_request, project: project).discussion }
+
+ it 'creates draft note as a reply' do
+ expect do
+ create_draft_note(overrides: { in_reply_to_discussion_id: discussion.reply_id })
+ end.to change { DraftNote.count }.by(1)
+
+ draft_note = DraftNote.last
+
+ expect(draft_note).to be_valid
+ expect(draft_note.discussion_id).to eq(discussion.reply_id)
+ end
+
+ it 'creates a draft note that will resolve a thread' do
+ expect do
+ create_draft_note(
+ overrides: { in_reply_to_discussion_id: discussion.reply_id },
+ draft_overrides: { resolve_discussion: true }
+ )
+ end.to change { DraftNote.count }.by(1)
+
+ draft_note = DraftNote.last
+
+ expect(draft_note).to be_valid
+ expect(draft_note.discussion_id).to eq(discussion.reply_id)
+ expect(draft_note.resolve_discussion).to eq(true)
+ end
+
+ it 'cannot create more than one draft note per thread' do
+ expect do
+ create_draft_note(
+ overrides: { in_reply_to_discussion_id: discussion.reply_id },
+ draft_overrides: { resolve_discussion: true }
+ )
+ end.to change { DraftNote.count }.by(1)
+
+ expect do
+ create_draft_note(
+ overrides: { in_reply_to_discussion_id: discussion.reply_id },
+ draft_overrides: { resolve_discussion: true, note: 'A note' }
+ )
+ end.to change { DraftNote.count }.by(0)
+ end
+ end
+
+ context 'commit_id is present' do
+ let(:commit) { project.commit(sample_commit.id) }
+
+ let(:position) do
+ Gitlab::Diff::Position.new(
+ old_path: "files/ruby/popen.rb",
+ new_path: "files/ruby/popen.rb",
+ old_line: nil,
+ new_line: 14,
+ diff_refs: commit.diff_refs
+ )
+ end
+
+ before do
+ create_draft_note(draft_overrides: { commit_id: commit_id, position: position.to_json })
+ end
+
+ context 'value is a commit sha' do
+ let(:commit_id) { commit.id }
+
+ it 'creates the draft note with commit ID' do
+ expect(DraftNote.last.commit_id).to eq(commit_id)
+ end
+ end
+
+ context 'value is "undefined"' do
+ let(:commit_id) { 'undefined' }
+
+ it 'creates the draft note with nil commit ID' do
+ expect(DraftNote.last.commit_id).to be_nil
+ end
+ end
+ end
+ end
+
+ describe 'PUT #update' do
+ let(:draft) { create(:draft_note, merge_request: merge_request, author: user) }
+
+ def update_draft_note(overrides = {})
+ put_params = params.merge({
+ id: draft.id,
+ draft_note: {
+ note: 'This is an updated unpublished comment'
+ }.merge(overrides)
+ })
+
+ put :update, params: put_params
+ end
+
+ context 'without permissions' do
+ before do
+ sign_in(user2)
+ project.add_developer(user2)
+ end
+
+ it 'does not allow editing draft note belonging to someone else' do
+ update_draft_note
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ expect(draft.reload.note).not_to eq('This is an updated unpublished comment')
+ end
+ end
+
+ it 'updates the draft' do
+ expect(draft.note).not_to be_empty
+
+ expect { update_draft_note }.not_to change { DraftNote.count }
+
+ draft.reload
+
+ expect(draft.note).to eq('This is an updated unpublished comment')
+ expect(json_response['note_html']).not_to be_empty
+ end
+ end
+
+ describe 'POST #publish' do
+ context 'without permissions' do
+ shared_examples_for 'action that does not allow publishing draft note' do
+ it 'does not allow publishing draft note' do
+ expect { action }
+ .to not_change { Note.count }
+ .and not_change { DraftNote.count }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ before do
+ sign_in(user2)
+ end
+
+ context 'when note belongs to someone else' do
+ before do
+ project.add_developer(user2)
+ end
+
+ it_behaves_like 'action that does not allow publishing draft note' do
+ let!(:draft) { create(:draft_note, merge_request: merge_request, author: user) }
+ let(:action) { post :publish, params: params.merge(id: draft.id) }
+ end
+ end
+
+ context 'when merge request discussion is locked' do
+ let(:project) { create(:project, :public, :merge_requests_public, :repository) }
+
+ before do
+ create(:draft_note, merge_request: merge_request, author: user2)
+ merge_request.update!(discussion_locked: true)
+ end
+
+ it_behaves_like 'action that does not allow publishing draft note' do
+ let(:action) { post :publish, params: params }
+ end
+ end
+ end
+
+ context 'when PublishService errors' do
+ it 'returns message and 500 response' do
+ create(:draft_note, merge_request: merge_request, author: user)
+ error_message = "Something went wrong"
+
+ expect_next_instance_of(DraftNotes::PublishService) do |service|
+ allow(service).to receive(:execute).and_return({ message: error_message, status: :error })
+ end
+
+ post :publish, params: params
+
+ expect(response).to have_gitlab_http_status(:error)
+ expect(json_response["message"]).to include(error_message)
+ end
+ end
+
+ it 'publishes draft notes with position' do
+ diff_refs = project.commit(sample_commit.id).try(:diff_refs)
+
+ position = Gitlab::Diff::Position.new(
+ old_path: "files/ruby/popen.rb",
+ new_path: "files/ruby/popen.rb",
+ old_line: nil,
+ new_line: 14,
+ diff_refs: diff_refs
+ )
+
+ draft = create(:draft_note_on_text_diff, merge_request: merge_request, author: user, position: position)
+
+ expect { post :publish, params: params }.to change { Note.count }.by(1)
+ .and change { DraftNote.count }.by(-1)
+
+ note = merge_request.notes.reload.last
+
+ expect(note.note).to eq(draft.note)
+ expect(note.position).to eq(draft.position)
+ end
+
+ it 'does nothing if there are no draft notes' do
+ expect { post :publish, params: params }.to change { Note.count }.by(0).and change { DraftNote.count }.by(0)
+ end
+
+ it 'publishes a draft note with quick actions and applies them' do
+ project.add_developer(user2)
+ create(:draft_note, merge_request: merge_request, author: user,
+ note: "/assign #{user2.to_reference}")
+
+ expect(merge_request.assignees).to be_empty
+
+ expect { post :publish, params: params }.to change { Note.count }.by(1)
+ .and change { DraftNote.count }.by(-1)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(merge_request.reload.assignee_ids).to match_array([user2.id])
+ expect(Note.last.system?).to be true
+ end
+
+ it 'publishes all draft notes for an MR' do
+ draft_params = { merge_request: merge_request, author: user }
+
+ drafts = create_list(:draft_note, 4, draft_params)
+
+ note = create(:discussion_note_on_merge_request, noteable: merge_request, project: project)
+ draft_reply = create(:draft_note, draft_params.merge(discussion_id: note.discussion_id))
+
+ diff_note = create(:diff_note_on_merge_request, noteable: merge_request, project: project)
+ diff_draft_reply = create(:draft_note, draft_params.merge(discussion_id: diff_note.discussion_id))
+
+ expect { post :publish, params: params }.to change { Note.count }.by(6)
+ .and change { DraftNote.count }.by(-6)
+
+ expect(response).to have_gitlab_http_status(:ok)
+
+ notes = merge_request.notes.reload
+
+ expect(notes.pluck(:note)).to include(*drafts.map(&:note))
+ expect(note.discussion.notes.last.note).to eq(draft_reply.note)
+ expect(diff_note.discussion.notes.last.note).to eq(diff_draft_reply.note)
+ end
+
+ it 'can publish just a single draft note' do
+ draft_params = { merge_request: merge_request, author: user }
+
+ drafts = create_list(:draft_note, 4, draft_params)
+
+ expect { post :publish, params: params.merge(id: drafts.first.id) }.to change { Note.count }.by(1)
+ .and change { DraftNote.count }.by(-1)
+ end
+
+ context 'when publishing drafts in a thread' do
+ let(:note) { create(:discussion_note_on_merge_request, noteable: merge_request, project: project) }
+
+ def create_reply(discussion_id, resolves: false)
+ create(:draft_note,
+ merge_request: merge_request,
+ author: user,
+ discussion_id: discussion_id,
+ resolve_discussion: resolves
+ )
+ end
+
+ it 'resolves a thread if the draft note resolves it' do
+ draft_reply = create_reply(note.discussion_id, resolves: true)
+
+ post :publish, params: params
+
+ discussion = note.discussion
+
+ expect(discussion.notes.last.note).to eq(draft_reply.note)
+ expect(discussion.resolved?).to eq(true)
+ expect(discussion.resolved_by.id).to eq(user.id)
+ end
+
+ it 'unresolves a thread if the draft note unresolves it' do
+ note.discussion.resolve!(user)
+ expect(note.discussion.resolved?).to eq(true)
+
+ draft_reply = create_reply(note.discussion_id, resolves: false)
+
+ post :publish, params: params
+
+ discussion = note.discussion
+
+ expect(discussion.notes.last.note).to eq(draft_reply.note)
+ expect(discussion.resolved?).to eq(false)
+ end
+ end
+ end
+
+ describe 'DELETE #destroy' do
+ let(:draft) { create(:draft_note, merge_request: merge_request, author: user) }
+
+ def create_draft
+ create(:draft_note, merge_request: merge_request, author: user)
+ end
+
+ context 'without permissions' do
+ before do
+ sign_in(user2)
+ project.add_developer(user2)
+ end
+
+ it 'does not allow destroying a draft note belonging to someone else' do
+ draft = create(:draft_note, merge_request: merge_request, author: user)
+
+ expect { post :destroy, params: params.merge(id: draft.id) }
+ .not_to change { DraftNote.count }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ it 'destroys the draft note when ID is given' do
+ draft = create_draft
+
+ expect { delete :destroy, params: params.merge(id: draft.id) }.to change { DraftNote.count }.by(-1)
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ context 'without permissions' do
+ before do
+ sign_in(user2)
+ end
+
+ it 'does not allow editing draft note belonging to someone else' do
+ draft = create_draft
+
+ expect { delete :destroy, params: params.merge(id: draft.id) }.to change { DraftNote.count }.by(0)
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ describe 'DELETE #discard' do
+ it 'deletes all DraftNotes belonging to a user in a Merge Request' do
+ create_list(:draft_note, 6, merge_request: merge_request, author: user)
+
+ expect { delete :discard, params: params }.to change { DraftNote.count }.by(-6)
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ context 'without permissions' do
+ before do
+ sign_in(user2)
+ project.add_developer(user2)
+ end
+
+ it 'does not destroys a draft note belonging to someone else' do
+ create(:draft_note, merge_request: merge_request, author: user)
+
+ expect { post :discard, params: params }
+ .not_to change { DraftNote.count }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+ end
+end
diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb
index 7d9e42fcc2d..382593fd7cb 100644
--- a/spec/controllers/projects/merge_requests_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MergeRequestsController do
+RSpec.describe Projects::MergeRequestsController do
include ProjectForksHelper
include Gitlab::Routing
@@ -1183,15 +1183,19 @@ describe Projects::MergeRequestsController do
subject
expect(response).to have_gitlab_http_status(:ok)
- expect(json_response).to match(
- a_hash_including(
- 'tfplan.json' => hash_including(
- 'create' => 0,
- 'delete' => 0,
- 'update' => 1
+
+ pipeline.builds.each do |build|
+ expect(json_response).to match(
+ a_hash_including(
+ build.id.to_s => hash_including(
+ 'create' => 0,
+ 'delete' => 0,
+ 'update' => 1,
+ 'job_name' => build.options.dig(:artifacts, :name).to_s
+ )
)
)
- )
+ end
end
end
@@ -1409,20 +1413,6 @@ describe Projects::MergeRequestsController do
end
end
- context 'when feature flag is disabled' do
- let(:accessibility_comparison) { { status: :parsed, data: { summary: 1 } } }
-
- before do
- stub_feature_flags(accessibility_report_view: false)
- end
-
- it 'returns 204 HTTP status' do
- subject
-
- expect(response).to have_gitlab_http_status(:no_content)
- end
- end
-
context 'when pipeline has jobs with accessibility reports' do
before do
allow_any_instance_of(MergeRequest)
diff --git a/spec/controllers/projects/milestones_controller_spec.rb b/spec/controllers/projects/milestones_controller_spec.rb
index ee61ef73b45..0c7391c1b9c 100644
--- a/spec/controllers/projects/milestones_controller_spec.rb
+++ b/spec/controllers/projects/milestones_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MilestonesController do
+RSpec.describe Projects::MilestonesController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:milestone) { create(:milestone, project: project) }
@@ -145,7 +145,7 @@ describe Projects::MilestonesController do
delete :destroy, params: { namespace_id: project.namespace.id, project_id: project.id, id: milestone.iid }, format: :js
expect(response).to be_successful
- expect(Event.recent.first.action).to eq(Event::DESTROYED)
+ expect(Event.recent.first).to be_destroyed_action
expect { Milestone.find(milestone.id) }.to raise_exception(ActiveRecord::RecordNotFound)
issue.reload
diff --git a/spec/controllers/projects/mirrors_controller_spec.rb b/spec/controllers/projects/mirrors_controller_spec.rb
index 8cd940978c0..7c5d14d3a22 100644
--- a/spec/controllers/projects/mirrors_controller_spec.rb
+++ b/spec/controllers/projects/mirrors_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MirrorsController do
+RSpec.describe Projects::MirrorsController do
include ReactiveCachingHelpers
shared_examples 'only admin is allowed when mirroring is disabled' do
diff --git a/spec/controllers/projects/notes_controller_spec.rb b/spec/controllers/projects/notes_controller_spec.rb
index 39594ff287d..b3a83723189 100644
--- a/spec/controllers/projects/notes_controller_spec.rb
+++ b/spec/controllers/projects/notes_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::NotesController do
+RSpec.describe Projects::NotesController do
include ProjectForksHelper
let(:user) { create(:user) }
@@ -37,7 +37,7 @@ describe Projects::NotesController do
project.add_developer(user)
end
- it 'passes last_fetched_at from headers to NotesFinder' do
+ it 'passes last_fetched_at from headers to NotesFinder and MergeIntoNotesService' do
last_fetched_at = 3.hours.ago.to_i
request.headers['X-Last-Fetched-At'] = last_fetched_at
@@ -46,6 +46,10 @@ describe Projects::NotesController do
.with(anything, hash_including(last_fetched_at: last_fetched_at))
.and_call_original
+ expect(ResourceEvents::MergeIntoNotesService).to receive(:new)
+ .with(anything, anything, hash_including(last_fetched_at: last_fetched_at))
+ .and_call_original
+
get :index, params: request_params
end
diff --git a/spec/controllers/projects/pages_controller_spec.rb b/spec/controllers/projects/pages_controller_spec.rb
index 102c0b6b048..1fa8838b548 100644
--- a/spec/controllers/projects/pages_controller_spec.rb
+++ b/spec/controllers/projects/pages_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::PagesController do
+RSpec.describe Projects::PagesController do
let(:user) { create(:user) }
let(:project) { create(:project, :public) }
diff --git a/spec/controllers/projects/pages_domains_controller_spec.rb b/spec/controllers/projects/pages_domains_controller_spec.rb
index 40a6f77f0d6..691508d1e14 100644
--- a/spec/controllers/projects/pages_domains_controller_spec.rb
+++ b/spec/controllers/projects/pages_domains_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::PagesDomainsController do
+RSpec.describe Projects::PagesDomainsController do
let(:user) { create(:user) }
let(:project) { create(:project) }
let!(:pages_domain) { create(:pages_domain, project: project) }
diff --git a/spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb b/spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb
index 6a53e8f3dbf..8a344a72120 100644
--- a/spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb
+++ b/spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::PerformanceMonitoring::DashboardsController do
+RSpec.describe Projects::PerformanceMonitoring::DashboardsController do
let_it_be(:user) { create(:user) }
let_it_be(:namespace) { create(:namespace) }
let!(:project) { create(:project, :repository, name: 'dashboard-project', namespace: namespace) }
diff --git a/spec/controllers/projects/pipeline_schedules_controller_spec.rb b/spec/controllers/projects/pipeline_schedules_controller_spec.rb
index 635980ba93b..27a3e95896a 100644
--- a/spec/controllers/projects/pipeline_schedules_controller_spec.rb
+++ b/spec/controllers/projects/pipeline_schedules_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::PipelineSchedulesController do
+RSpec.describe Projects::PipelineSchedulesController do
include AccessMatchersForController
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb
index b3d8fb94fb3..ca09d2b1428 100644
--- a/spec/controllers/projects/pipelines_controller_spec.rb
+++ b/spec/controllers/projects/pipelines_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::PipelinesController do
+RSpec.describe Projects::PipelinesController do
include ApiHelpers
let_it_be(:user) { create(:user) }
@@ -26,10 +26,6 @@ describe Projects::PipelinesController do
context 'when using persisted stages', :request_store do
render_views
- before do
- stub_feature_flags(ci_pipeline_persisted_stages: true)
- end
-
it 'returns serialized pipelines' do
expect(::Gitlab::GitalyClient).to receive(:allow_ref_name_caching).and_call_original
@@ -66,46 +62,6 @@ describe Projects::PipelinesController do
end
end
- context 'when using legacy stages', :request_store do
- before do
- stub_feature_flags(ci_pipeline_persisted_stages: false)
- end
-
- it 'returns JSON with serialized pipelines' do
- get_pipelines_index_json
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(response).to match_response_schema('pipeline')
-
- expect(json_response).to include('pipelines')
- expect(json_response['pipelines'].count).to eq 6
- expect(json_response['count']['all']).to eq '6'
- expect(json_response['count']['running']).to eq '2'
- expect(json_response['count']['pending']).to eq '1'
- expect(json_response['count']['finished']).to eq '3'
-
- json_response.dig('pipelines', 0, 'details', 'stages').tap do |stages|
- expect(stages.count).to eq 3
- end
- end
-
- it 'does not execute N+1 queries' do
- get_pipelines_index_json
-
- control_count = ActiveRecord::QueryRecorder.new do
- get_pipelines_index_json
- end.count
-
- create_all_pipeline_types
-
- # There appears to be one extra query for Pipelines#has_warnings? for some reason
- expect { get_pipelines_index_json }.not_to exceed_query_limit(control_count + 1)
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['pipelines'].count).to eq 12
- end
- end
-
it 'does not include coverage data for the pipelines' do
get_pipelines_index_json
@@ -215,6 +171,40 @@ describe Projects::PipelinesController do
end
end
+ context 'filter by status' do
+ context 'when pipelines with the status exists' do
+ it 'returns matched pipelines' do
+ get_pipelines_index_json(status: 'success')
+
+ check_pipeline_response(returned: 1, all: 1, running: 0, pending: 0, finished: 1)
+ end
+
+ context 'when filter by unrelated scope' do
+ it 'returns empty list' do
+ get_pipelines_index_json(status: 'success', scope: 'running')
+
+ check_pipeline_response(returned: 0, all: 1, running: 0, pending: 0, finished: 1)
+ end
+ end
+ end
+
+ context 'when no pipeline with the status exists' do
+ it 'returns empty list' do
+ get_pipelines_index_json(status: 'manual')
+
+ check_pipeline_response(returned: 0, all: 0, running: 0, pending: 0, finished: 0)
+ end
+ end
+
+ context 'when invalid status' do
+ it 'returns all list' do
+ get_pipelines_index_json(status: 'invalid-status')
+
+ check_pipeline_response(returned: 6, all: 6, running: 2, pending: 1, finished: 3)
+ end
+ end
+ end
+
def get_pipelines_index_json(params = {})
get :index, params: {
namespace_id: project.namespace,
@@ -548,6 +538,39 @@ describe Projects::PipelinesController do
end
end
+ describe 'GET dag.json' do
+ let(:pipeline) { create(:ci_pipeline, project: project) }
+
+ before do
+ create_build('build', 1, 'build')
+ create_build('test', 2, 'test', scheduling_type: 'dag').tap do |job|
+ create(:ci_build_need, build: job, name: 'build')
+ end
+ end
+
+ it 'returns the pipeline with DAG serialization' do
+ get :dag, params: { namespace_id: project.namespace, project_id: project, id: pipeline }, format: :json
+
+ expect(response).to have_gitlab_http_status(:ok)
+
+ expect(json_response.fetch('stages')).not_to be_empty
+
+ build_stage = json_response['stages'].first
+ expect(build_stage.fetch('name')).to eq 'build'
+ expect(build_stage.fetch('groups').first.fetch('jobs'))
+ .to eq [{ 'name' => 'build', 'scheduling_type' => 'stage' }]
+
+ test_stage = json_response['stages'].last
+ expect(test_stage.fetch('name')).to eq 'test'
+ expect(test_stage.fetch('groups').first.fetch('jobs'))
+ .to eq [{ 'name' => 'test', 'scheduling_type' => 'dag', 'needs' => ['build'] }]
+ end
+
+ def create_build(stage, stage_idx, name, params = {})
+ create(:ci_build, pipeline: pipeline, stage: stage, stage_idx: stage_idx, name: name, **params)
+ end
+ end
+
describe 'GET stages.json' do
let(:pipeline) { create(:ci_pipeline, project: project) }
@@ -685,7 +708,7 @@ describe Projects::PipelinesController do
end
shared_examples 'creates a pipeline' do
- it do
+ specify do
expect { post_request }.to change { project.ci_pipelines.count }.by(1)
pipeline = project.ci_pipelines.last
diff --git a/spec/controllers/projects/pipelines_settings_controller_spec.rb b/spec/controllers/projects/pipelines_settings_controller_spec.rb
index 789b2104d3c..ad631b7c3da 100644
--- a/spec/controllers/projects/pipelines_settings_controller_spec.rb
+++ b/spec/controllers/projects/pipelines_settings_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::PipelinesSettingsController do
+RSpec.describe Projects::PipelinesSettingsController do
let_it_be(:user) { create(:user) }
let_it_be(:project_auto_devops) { create(:project_auto_devops) }
let(:project) { project_auto_devops.project }
diff --git a/spec/controllers/projects/project_members_controller_spec.rb b/spec/controllers/projects/project_members_controller_spec.rb
index f354bba902a..7457e4c5023 100644
--- a/spec/controllers/projects/project_members_controller_spec.rb
+++ b/spec/controllers/projects/project_members_controller_spec.rb
@@ -2,7 +2,7 @@
require('spec_helper')
-describe Projects::ProjectMembersController do
+RSpec.describe Projects::ProjectMembersController do
let(:user) { create(:user) }
let(:group) { create(:group, :public) }
let(:project) { create(:project, :public) }
diff --git a/spec/controllers/projects/prometheus/alerts_controller_spec.rb b/spec/controllers/projects/prometheus/alerts_controller_spec.rb
index e936cb5916e..6e3148231bd 100644
--- a/spec/controllers/projects/prometheus/alerts_controller_spec.rb
+++ b/spec/controllers/projects/prometheus/alerts_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Prometheus::AlertsController do
+RSpec.describe Projects::Prometheus::AlertsController do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:environment) { create(:environment, project: project) }
diff --git a/spec/controllers/projects/prometheus/metrics_controller_spec.rb b/spec/controllers/projects/prometheus/metrics_controller_spec.rb
index 36f694cda29..c7c3be20f29 100644
--- a/spec/controllers/projects/prometheus/metrics_controller_spec.rb
+++ b/spec/controllers/projects/prometheus/metrics_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Prometheus::MetricsController do
+RSpec.describe Projects::Prometheus::MetricsController do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:prometheus_project) }
diff --git a/spec/controllers/projects/protected_branches_controller_spec.rb b/spec/controllers/projects/protected_branches_controller_spec.rb
index 262f77a7328..09eb1a45c73 100644
--- a/spec/controllers/projects/protected_branches_controller_spec.rb
+++ b/spec/controllers/projects/protected_branches_controller_spec.rb
@@ -2,7 +2,7 @@
require('spec_helper')
-describe Projects::ProtectedBranchesController do
+RSpec.describe Projects::ProtectedBranchesController do
let(:project) { create(:project, :repository) }
let(:protected_branch) { create(:protected_branch, project: project) }
let(:project_params) { { namespace_id: project.namespace.to_param, project_id: project } }
diff --git a/spec/controllers/projects/protected_tags_controller_spec.rb b/spec/controllers/projects/protected_tags_controller_spec.rb
index a900947d82e..2c2240cb0d0 100644
--- a/spec/controllers/projects/protected_tags_controller_spec.rb
+++ b/spec/controllers/projects/protected_tags_controller_spec.rb
@@ -2,7 +2,7 @@
require('spec_helper')
-describe Projects::ProtectedTagsController do
+RSpec.describe Projects::ProtectedTagsController do
describe "GET #index" do
let(:project) { create(:project_empty_repo, :public) }
diff --git a/spec/controllers/projects/raw_controller_spec.rb b/spec/controllers/projects/raw_controller_spec.rb
index 4a684dcfbc6..5f10343eb76 100644
--- a/spec/controllers/projects/raw_controller_spec.rb
+++ b/spec/controllers/projects/raw_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::RawController do
+RSpec.describe Projects::RawController do
include RepoHelpers
let(:project) { create(:project, :public, :repository) }
diff --git a/spec/controllers/projects/refs_controller_spec.rb b/spec/controllers/projects/refs_controller_spec.rb
index b043e7f2538..a6a4aff7ce9 100644
--- a/spec/controllers/projects/refs_controller_spec.rb
+++ b/spec/controllers/projects/refs_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::RefsController do
+RSpec.describe Projects::RefsController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
@@ -73,7 +73,7 @@ describe Projects::RefsController do
cache_key = "projects/#{project.id}/logs/#{project.commit.id}/#{path}/25"
expect(Rails.cache.fetch(cache_key)).to eq(['logs', 50])
- expect(response.headers['More-Logs-Offset']).to eq(50)
+ expect(response.headers['More-Logs-Offset']).to eq("50")
end
end
end
diff --git a/spec/controllers/projects/registry/repositories_controller_spec.rb b/spec/controllers/projects/registry/repositories_controller_spec.rb
index badb84f9b50..098fa9bac2c 100644
--- a/spec/controllers/projects/registry/repositories_controller_spec.rb
+++ b/spec/controllers/projects/registry/repositories_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Registry::RepositoriesController do
+RSpec.describe Projects::Registry::RepositoriesController do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :private) }
@@ -46,7 +46,7 @@ describe Projects::Registry::RepositoriesController do
context 'when root container repository is not created' do
context 'when there are tags for this repository' do
before do
- stub_container_registry_tags(repository: project.full_path,
+ stub_container_registry_tags(repository: :any,
tags: %w[rc1 latest])
end
diff --git a/spec/controllers/projects/registry/tags_controller_spec.rb b/spec/controllers/projects/registry/tags_controller_spec.rb
index 5ab32b7d81d..6adee35b60a 100644
--- a/spec/controllers/projects/registry/tags_controller_spec.rb
+++ b/spec/controllers/projects/registry/tags_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Registry::TagsController do
+RSpec.describe Projects::Registry::TagsController do
let(:user) { create(:user) }
let(:project) { create(:project, :private) }
diff --git a/spec/controllers/projects/releases/evidences_controller_spec.rb b/spec/controllers/projects/releases/evidences_controller_spec.rb
index d3808087681..d5a9665d6a5 100644
--- a/spec/controllers/projects/releases/evidences_controller_spec.rb
+++ b/spec/controllers/projects/releases/evidences_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Releases::EvidencesController do
+RSpec.describe Projects::Releases::EvidencesController do
let!(:project) { create(:project, :repository, :public) }
let_it_be(:private_project) { create(:project, :repository, :private) }
let_it_be(:developer) { create(:user) }
@@ -31,8 +31,8 @@ describe Projects::Releases::EvidencesController do
end
describe 'GET #show' do
- let_it_be(:tag_name) { "v1.1.0-evidence" }
- let!(:release) { create(:release, :with_evidence, project: project, tag: tag_name) }
+ let(:tag_name) { "v1.1.0-evidence" }
+ let!(:release) { create(:release, project: project, tag: tag_name) }
let(:evidence) { release.evidences.first }
let(:tag) { CGI.escape(release.tag) }
let(:format) { :json }
@@ -48,6 +48,8 @@ describe Projects::Releases::EvidencesController do
end
before do
+ ::Releases::CreateEvidenceService.new(release).execute
+
sign_in(user)
end
@@ -84,14 +86,9 @@ describe Projects::Releases::EvidencesController do
end
context 'when release is associated to a milestone which includes an issue' do
- let_it_be(:project) { create(:project, :repository, :public) }
- let_it_be(:issue) { create(:issue, project: project) }
- let_it_be(:milestone) { create(:milestone, project: project, issues: [issue]) }
- let_it_be(:release) { create(:release, project: project, tag: tag_name, milestones: [milestone]) }
-
- before do
- create(:evidence, release: release)
- end
+ let(:issue) { create(:issue, project: project) }
+ let(:milestone) { create(:milestone, project: project, issues: [issue]) }
+ let(:release) { create(:release, project: project, tag: tag_name, milestones: [milestone]) }
shared_examples_for 'does not show the issue in evidence' do
it do
@@ -111,7 +108,9 @@ describe Projects::Releases::EvidencesController do
end
end
- shared_examples_for 'safely expose evidence' do
+ context 'when user is non-project member' do
+ let(:user) { create(:user) }
+
it_behaves_like 'does not show the issue in evidence'
context 'when the issue is confidential' do
@@ -127,28 +126,50 @@ describe Projects::Releases::EvidencesController do
end
context 'when project is private' do
- let!(:project) { create(:project, :repository, :private) }
+ let(:project) { create(:project, :repository, :private) }
it_behaves_like 'evidence not found'
end
context 'when project restricts the visibility of issues to project members only' do
- let!(:project) { create(:project, :repository, :issues_private) }
+ let(:project) { create(:project, :repository, :issues_private) }
it_behaves_like 'evidence not found'
end
end
- context 'when user is non-project member' do
- let(:user) { create(:user) }
-
- it_behaves_like 'safely expose evidence'
- end
-
context 'when user is auditor', if: Gitlab.ee? do
let(:user) { create(:user, :auditor) }
- it_behaves_like 'safely expose evidence'
+ it_behaves_like 'does not show the issue in evidence'
+
+ context 'when the issue is confidential' do
+ let(:issue) { create(:issue, :confidential, project: project) }
+
+ it_behaves_like 'does not show the issue in evidence'
+ end
+
+ context 'when the user is the author of the confidential issue' do
+ let(:issue) { create(:issue, :confidential, project: project, author: user) }
+
+ it_behaves_like 'does not show the issue in evidence'
+ end
+
+ context 'when project is private' do
+ let(:project) { create(:project, :repository, :private) }
+
+ it 'returns evidence ' do
+ subject
+
+ expect(json_response).to eq(evidence.summary)
+ end
+ end
+
+ context 'when project restricts the visibility of issues to project members only' do
+ let(:project) { create(:project, :repository, :issues_private) }
+
+ it_behaves_like 'evidence not found'
+ end
end
context 'when external authorization control is enabled' do
diff --git a/spec/controllers/projects/releases_controller_spec.rb b/spec/controllers/projects/releases_controller_spec.rb
index 45f4433ed0a..96c38c1b726 100644
--- a/spec/controllers/projects/releases_controller_spec.rb
+++ b/spec/controllers/projects/releases_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ReleasesController do
+RSpec.describe Projects::ReleasesController do
let!(:project) { create(:project, :repository, :public) }
let_it_be(:private_project) { create(:project, :repository, :private) }
let_it_be(:developer) { create(:user) }
diff --git a/spec/controllers/projects/repositories_controller_spec.rb b/spec/controllers/projects/repositories_controller_spec.rb
index 42032b4cad0..97eea7c7e9d 100644
--- a/spec/controllers/projects/repositories_controller_spec.rb
+++ b/spec/controllers/projects/repositories_controller_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe Projects::RepositoriesController do
+RSpec.describe Projects::RepositoriesController do
let(:project) { create(:project, :repository) }
describe "GET archive" do
diff --git a/spec/controllers/projects/runners_controller_spec.rb b/spec/controllers/projects/runners_controller_spec.rb
index 1893180fe9b..66f20bd50c4 100644
--- a/spec/controllers/projects/runners_controller_spec.rb
+++ b/spec/controllers/projects/runners_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::RunnersController do
+RSpec.describe Projects::RunnersController do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:runner) { create(:ci_runner, :project, projects: [project]) }
diff --git a/spec/controllers/projects/serverless/functions_controller_spec.rb b/spec/controllers/projects/serverless/functions_controller_spec.rb
index 203e1e49994..3071d0b7f54 100644
--- a/spec/controllers/projects/serverless/functions_controller_spec.rb
+++ b/spec/controllers/projects/serverless/functions_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Serverless::FunctionsController do
+RSpec.describe Projects::Serverless::FunctionsController do
include KubernetesHelpers
include ReactiveCachingHelpers
diff --git a/spec/controllers/projects/service_hook_logs_controller_spec.rb b/spec/controllers/projects/service_hook_logs_controller_spec.rb
index a5130cd6e32..97fb31f0546 100644
--- a/spec/controllers/projects/service_hook_logs_controller_spec.rb
+++ b/spec/controllers/projects/service_hook_logs_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ServiceHookLogsController do
+RSpec.describe Projects::ServiceHookLogsController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:service) { create(:drone_ci_service, project: project) }
diff --git a/spec/controllers/projects/services_controller_spec.rb b/spec/controllers/projects/services_controller_spec.rb
index c669119fa4e..04c74dfdefe 100644
--- a/spec/controllers/projects/services_controller_spec.rb
+++ b/spec/controllers/projects/services_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ServicesController do
+RSpec.describe Projects::ServicesController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:service) { create(:jira_service, project: project) }
@@ -134,24 +134,50 @@ describe Projects::ServicesController do
describe 'PUT #update' do
describe 'as HTML' do
let(:service_params) { { active: true } }
+ let(:params) { project_params(service: service_params) }
+
+ let(:message) { 'Jira activated.' }
+ let(:redirect_url) { project_settings_integrations_path(project) }
before do
- put :update, params: project_params(service: service_params)
+ put :update, params: params
+ end
+
+ shared_examples 'service update' do
+ it 'redirects to the correct url with a flash message' do
+ expect(response).to redirect_to(redirect_url)
+ expect(flash[:notice]).to eq(message)
+ end
end
context 'when param `active` is set to true' do
- it 'activates the service and redirects to integrations paths' do
- expect(response).to redirect_to(project_settings_integrations_path(project))
- expect(flash[:notice]).to eq 'Jira activated.'
+ let(:params) { project_params(service: service_params, redirect_to: redirect) }
+
+ context 'when redirect_to param is present' do
+ let(:redirect) { '/redirect_here' }
+ let(:redirect_url) { redirect }
+
+ it_behaves_like 'service update'
+ end
+
+ context 'when redirect_to is an external domain' do
+ let(:redirect) { 'http://examle.com' }
+
+ it_behaves_like 'service update'
+ end
+
+ context 'when redirect_to param is an empty string' do
+ let(:redirect) { '' }
+
+ it_behaves_like 'service update'
end
end
context 'when param `active` is set to false' do
let(:service_params) { { active: false } }
+ let(:message) { 'Jira settings saved, but not activated.' }
- it 'does not activate the service but saves the settings' do
- expect(flash[:notice]).to eq 'Jira settings saved, but not activated.'
- end
+ it_behaves_like 'service update'
end
end
diff --git a/spec/controllers/projects/settings/access_tokens_controller_spec.rb b/spec/controllers/projects/settings/access_tokens_controller_spec.rb
index 884a5bc2836..4743ab2b7c1 100644
--- a/spec/controllers/projects/settings/access_tokens_controller_spec.rb
+++ b/spec/controllers/projects/settings/access_tokens_controller_spec.rb
@@ -2,7 +2,7 @@
require('spec_helper')
-describe Projects::Settings::AccessTokensController do
+RSpec.describe Projects::Settings::AccessTokensController do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
diff --git a/spec/controllers/projects/settings/ci_cd_controller_spec.rb b/spec/controllers/projects/settings/ci_cd_controller_spec.rb
index 6891af54eb4..8498ff49826 100644
--- a/spec/controllers/projects/settings/ci_cd_controller_spec.rb
+++ b/spec/controllers/projects/settings/ci_cd_controller_spec.rb
@@ -2,7 +2,7 @@
require('spec_helper')
-describe Projects::Settings::CiCdController do
+RSpec.describe Projects::Settings::CiCdController do
let_it_be(:user) { create(:user) }
let_it_be(:project_auto_devops) { create(:project_auto_devops) }
let(:project) { project_auto_devops.project }
diff --git a/spec/controllers/projects/settings/integrations_controller_spec.rb b/spec/controllers/projects/settings/integrations_controller_spec.rb
index 5d9fe3da912..0652786c787 100644
--- a/spec/controllers/projects/settings/integrations_controller_spec.rb
+++ b/spec/controllers/projects/settings/integrations_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Settings::IntegrationsController do
+RSpec.describe Projects::Settings::IntegrationsController do
let(:project) { create(:project, :public) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/settings/operations_controller_spec.rb b/spec/controllers/projects/settings/operations_controller_spec.rb
index c9afff0b73d..6b440e910ad 100644
--- a/spec/controllers/projects/settings/operations_controller_spec.rb
+++ b/spec/controllers/projects/settings/operations_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Settings::OperationsController do
+RSpec.describe Projects::Settings::OperationsController do
let_it_be(:user) { create(:user) }
let_it_be(:project, reload: true) { create(:project) }
diff --git a/spec/controllers/projects/settings/repository_controller_spec.rb b/spec/controllers/projects/settings/repository_controller_spec.rb
index fb9cdd860dc..46dba691bc4 100644
--- a/spec/controllers/projects/settings/repository_controller_spec.rb
+++ b/spec/controllers/projects/settings/repository_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Settings::RepositoryController do
+RSpec.describe Projects::Settings::RepositoryController do
let(:project) { create(:project_empty_repo, :public) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/snippets_controller_spec.rb b/spec/controllers/projects/snippets_controller_spec.rb
index b5f4929d8ce..8bbfaa8d327 100644
--- a/spec/controllers/projects/snippets_controller_spec.rb
+++ b/spec/controllers/projects/snippets_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::SnippetsController do
+RSpec.describe Projects::SnippetsController do
include Gitlab::Routing
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/stages_controller_spec.rb b/spec/controllers/projects/stages_controller_spec.rb
index c38e3d2544f..dcf8607ae18 100644
--- a/spec/controllers/projects/stages_controller_spec.rb
+++ b/spec/controllers/projects/stages_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::StagesController do
+RSpec.describe Projects::StagesController do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
diff --git a/spec/controllers/projects/starrers_controller_spec.rb b/spec/controllers/projects/starrers_controller_spec.rb
index 5774ff7c576..66888fa3024 100644
--- a/spec/controllers/projects/starrers_controller_spec.rb
+++ b/spec/controllers/projects/starrers_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::StarrersController do
+RSpec.describe Projects::StarrersController do
let(:user_1) { create(:user, name: 'John') }
let(:user_2) { create(:user, name: 'Michael') }
let(:private_user) { create(:user, name: 'Michael Douglas', private_profile: true) }
diff --git a/spec/controllers/projects/static_site_editor_controller_spec.rb b/spec/controllers/projects/static_site_editor_controller_spec.rb
index 7b470254de1..384218504b9 100644
--- a/spec/controllers/projects/static_site_editor_controller_spec.rb
+++ b/spec/controllers/projects/static_site_editor_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::StaticSiteEditorController do
+RSpec.describe Projects::StaticSiteEditorController do
let_it_be(:project) { create(:project, :public, :repository) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/tags/releases_controller_spec.rb b/spec/controllers/projects/tags/releases_controller_spec.rb
index cb12e074732..b3d4d944440 100644
--- a/spec/controllers/projects/tags/releases_controller_spec.rb
+++ b/spec/controllers/projects/tags/releases_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Tags::ReleasesController do
+RSpec.describe Projects::Tags::ReleasesController do
let!(:project) { create(:project, :repository) }
let!(:user) { create(:user) }
let!(:release) { create(:release, project: project) }
@@ -16,7 +16,7 @@ describe Projects::Tags::ReleasesController do
describe 'GET #edit' do
it 'initializes a new release' do
tag_id = release.tag
- project.releases.destroy_all # rubocop: disable DestroyAll
+ project.releases.destroy_all # rubocop: disable Cop/DestroyAll
response = get :edit, params: { namespace_id: project.namespace, project_id: project, tag_id: tag_id }
diff --git a/spec/controllers/projects/tags_controller_spec.rb b/spec/controllers/projects/tags_controller_spec.rb
index 15ef1c65c53..122d1b072d0 100644
--- a/spec/controllers/projects/tags_controller_spec.rb
+++ b/spec/controllers/projects/tags_controller_spec.rb
@@ -2,10 +2,11 @@
require 'spec_helper'
-describe Projects::TagsController do
+RSpec.describe Projects::TagsController do
let(:project) { create(:project, :public, :repository) }
let!(:release) { create(:release, project: project) }
let!(:invalid_release) { create(:release, project: project, tag: 'does-not-exist') }
+ let(:user) { create(:user) }
describe 'GET index' do
before do
@@ -61,4 +62,69 @@ describe Projects::TagsController do
end
end
end
+
+ describe 'POST #create' do
+ before do
+ project.add_developer(user)
+ sign_in(user)
+ end
+
+ let(:release_description) { nil }
+ let(:request) do
+ post(:create, params: {
+ namespace_id: project.namespace.to_param,
+ project_id: project,
+ tag_name: '1.0',
+ ref: 'master',
+ release_description: release_description
+ })
+ end
+
+ it 'creates tag' do
+ request
+
+ expect(response).to have_gitlab_http_status(:found)
+ expect(project.repository.find_tag('1.0')).to be_present
+ end
+
+ # TODO: remove this with the release creation moved to it's own form https://gitlab.com/gitlab-org/gitlab/-/issues/214245
+ context 'when release description is set' do
+ let(:release_description) { 'some release description' }
+
+ it 'creates tag and release' do
+ request
+
+ expect(response).to have_gitlab_http_status(:found)
+ expect(project.repository.find_tag('1.0')).to be_present
+
+ release = project.releases.find_by_tag!('1.0')
+
+ expect(release).to be_present
+ expect(release.description).to eq(release_description)
+ end
+
+ it 'passes the last pipeline for evidence creation', :sidekiq_inline do
+ sha = project.repository.commit('master').sha
+ create(:ci_empty_pipeline, sha: sha, project: project) # old pipeline
+ pipeline = create(:ci_empty_pipeline, sha: sha, project: project)
+
+ # simulating pipeline creation by new tag
+ expect_any_instance_of(Repository).to receive(:add_tag).and_wrap_original do |m, *args|
+ create(:ci_empty_pipeline, sha: sha, project: project)
+ m.call(*args)
+ end
+
+ expect_next_instance_of(Releases::CreateEvidenceService, anything, pipeline: pipeline) do |service|
+ expect(service).to receive(:execute).and_call_original
+ end
+
+ request
+
+ release = project.releases.find_by_tag!('1.0')
+
+ expect(release).to be_present
+ expect(release.description).to eq(release_description)
+ end
+ end
+ end
end
diff --git a/spec/controllers/projects/templates_controller_spec.rb b/spec/controllers/projects/templates_controller_spec.rb
index fcd9b4aa8bd..40632e0dea7 100644
--- a/spec/controllers/projects/templates_controller_spec.rb
+++ b/spec/controllers/projects/templates_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::TemplatesController do
+RSpec.describe Projects::TemplatesController do
let(:project) { create(:project, :repository, :private) }
let(:user) { create(:user) }
let(:file_path_1) { '.gitlab/issue_templates/issue_template.md' }
diff --git a/spec/controllers/projects/todos_controller_spec.rb b/spec/controllers/projects/todos_controller_spec.rb
index b7d40d2a452..e1e1e455094 100644
--- a/spec/controllers/projects/todos_controller_spec.rb
+++ b/spec/controllers/projects/todos_controller_spec.rb
@@ -2,7 +2,7 @@
require('spec_helper')
-describe Projects::TodosController do
+RSpec.describe Projects::TodosController do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
diff --git a/spec/controllers/projects/tree_controller_spec.rb b/spec/controllers/projects/tree_controller_spec.rb
index 96838383540..f6ec04d4dd7 100644
--- a/spec/controllers/projects/tree_controller_spec.rb
+++ b/spec/controllers/projects/tree_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::TreeController do
+RSpec.describe Projects::TreeController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/uploads_controller_spec.rb b/spec/controllers/projects/uploads_controller_spec.rb
index bb5415ee62c..dda58f06a37 100644
--- a/spec/controllers/projects/uploads_controller_spec.rb
+++ b/spec/controllers/projects/uploads_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::UploadsController do
+RSpec.describe Projects::UploadsController do
include WorkhorseHelpers
let(:model) { create(:project, :public) }
diff --git a/spec/controllers/projects/usage_ping_controller_spec.rb b/spec/controllers/projects/usage_ping_controller_spec.rb
index a68967c228f..9ace072d561 100644
--- a/spec/controllers/projects/usage_ping_controller_spec.rb
+++ b/spec/controllers/projects/usage_ping_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::UsagePingController do
+RSpec.describe Projects::UsagePingController do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/variables_controller_spec.rb b/spec/controllers/projects/variables_controller_spec.rb
index 21e106660d0..8bb4c2dae4b 100644
--- a/spec/controllers/projects/variables_controller_spec.rb
+++ b/spec/controllers/projects/variables_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::VariablesController do
+RSpec.describe Projects::VariablesController do
let(:project) { create(:project) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/web_ide_terminals_controller_spec.rb b/spec/controllers/projects/web_ide_terminals_controller_spec.rb
new file mode 100644
index 00000000000..2ae5899c258
--- /dev/null
+++ b/spec/controllers/projects/web_ide_terminals_controller_spec.rb
@@ -0,0 +1,304 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Projects::WebIdeTerminalsController do
+ let_it_be(:owner) { create(:owner) }
+ let_it_be(:admin) { create(:admin) }
+ let_it_be(:maintainer) { create(:user) }
+ let_it_be(:developer) { create(:user) }
+ let_it_be(:reporter) { create(:user) }
+ let_it_be(:guest) { create(:user) }
+ let_it_be(:project) { create(:project, :private, :repository, namespace: owner.namespace) }
+ let(:pipeline) { create(:ci_pipeline, project: project, source: :webide, config_source: :webide_source, user: user) }
+ let(:job) { create(:ci_build, pipeline: pipeline, user: user, project: project) }
+ let(:user) { maintainer }
+
+ before do
+ project.add_maintainer(maintainer)
+ project.add_developer(developer)
+ project.add_reporter(reporter)
+ project.add_guest(guest)
+
+ sign_in(user)
+ end
+
+ shared_examples 'terminal access rights' do
+ context 'with admin' do
+ let(:user) { admin }
+
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it 'returns 200' do
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'when admin mode is disabled' do
+ it 'returns 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ context 'with owner' do
+ let(:user) { owner }
+
+ it 'returns 200' do
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'with maintainer' do
+ let(:user) { maintainer }
+
+ it 'returns 200' do
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'with developer' do
+ let(:user) { developer }
+
+ it 'returns 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'with reporter' do
+ let(:user) { reporter }
+
+ it 'returns 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'with guest' do
+ let(:user) { guest }
+
+ it 'returns 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'with non member' do
+ let(:user) { create(:user) }
+
+ it 'returns 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ shared_examples 'when pipeline is not from a webide source' do
+ context 'with admin' do
+ let(:user) { admin }
+ let(:pipeline) { create(:ci_pipeline, project: project, source: :chat, user: user) }
+
+ it 'returns 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ describe 'GET show' do
+ before do
+ get(:show, params: { namespace_id: project.namespace.to_param, project_id: project, id: job.id })
+ end
+
+ it_behaves_like 'terminal access rights'
+ it_behaves_like 'when pipeline is not from a webide source'
+ end
+
+ describe 'POST check_config' do
+ let(:result) { { status: :success } }
+
+ before do
+ allow_next_instance_of(::Ci::WebIdeConfigService) do |instance|
+ allow(instance).to receive(:execute).and_return(result)
+ end
+
+ post :check_config, params: {
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ branch: 'master'
+ }
+ end
+
+ it_behaves_like 'terminal access rights'
+
+ context 'when invalid config file' do
+ let(:user) { admin }
+ let(:result) { { status: :error } }
+
+ it 'returns 422', :enable_admin_mode do
+ expect(response).to have_gitlab_http_status(:unprocessable_entity)
+ end
+ end
+ end
+
+ describe 'POST create' do
+ let(:branch) { 'master' }
+
+ subject do
+ post :create, params: {
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ branch: branch
+ }
+ end
+
+ context 'when terminal job is created successfully' do
+ let(:build) { create(:ci_build, project: project) }
+ let(:pipeline) { build.pipeline }
+
+ before do
+ allow_next_instance_of(::Ci::CreateWebIdeTerminalService) do |instance|
+ allow(instance).to receive(:execute).and_return(status: :success, pipeline: pipeline)
+ end
+ end
+
+ context 'access rights' do
+ before do
+ subject
+ end
+
+ it_behaves_like 'terminal access rights'
+ end
+
+ it 'increases the web ide terminal counter' do
+ expect(Gitlab::UsageDataCounters::WebIdeCounter).to receive(:increment_terminals_count)
+
+ subject
+ end
+ end
+
+ shared_examples 'web ide terminal usage counter' do
+ it 'does not increase', :enable_admin_mode do
+ expect(Gitlab::UsageDataCounters::WebIdeCounter).not_to receive(:increment_terminals_count)
+
+ subject
+ end
+ end
+
+ context 'when branch does not exist' do
+ let(:user) { admin }
+ let(:branch) { 'foobar' }
+
+ it 'returns 400', :enable_admin_mode do
+ subject
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ end
+
+ it_behaves_like 'web ide terminal usage counter'
+ end
+
+ context 'when there is an error creating the job' do
+ let(:user) { admin }
+
+ before do
+ allow_next_instance_of(::Ci::CreateWebIdeTerminalService) do |instance|
+ allow(instance).to receive(:execute).and_return(status: :error, message: 'foobar')
+ end
+ end
+
+ it 'returns 400', :enable_admin_mode do
+ subject
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ end
+
+ it_behaves_like 'web ide terminal usage counter'
+ end
+
+ context 'when the current build is nil' do
+ let(:user) { admin }
+
+ before do
+ allow(pipeline).to receive(:builds).and_return([])
+ allow_next_instance_of(::Ci::CreateWebIdeTerminalService) do |instance|
+ allow(instance).to receive(:execute).and_return(status: :success, pipeline: pipeline)
+ end
+ end
+
+ it 'returns 400', :enable_admin_mode do
+ subject
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ end
+
+ it_behaves_like 'web ide terminal usage counter'
+ end
+ end
+
+ describe 'POST cancel' do
+ let(:job) { create(:ci_build, :running, pipeline: pipeline, user: user, project: project) }
+
+ before do
+ post(:cancel, params: {
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ id: job.id
+ })
+ end
+
+ it_behaves_like 'terminal access rights'
+ it_behaves_like 'when pipeline is not from a webide source'
+
+ context 'when job is not cancelable' do
+ let!(:job) { create(:ci_build, :failed, pipeline: pipeline, user: user) }
+
+ it 'returns 422' do
+ expect(response).to have_gitlab_http_status(:unprocessable_entity)
+ end
+ end
+ end
+
+ describe 'POST retry' do
+ let(:status) { :failed }
+ let(:job) { create(:ci_build, status, pipeline: pipeline, user: user, project: project) }
+
+ before do
+ post(:retry, params: {
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ id: job.id
+ })
+ end
+
+ it_behaves_like 'terminal access rights'
+ it_behaves_like 'when pipeline is not from a webide source'
+
+ context 'when job is not retryable' do
+ let(:status) { :running }
+
+ it 'returns 422' do
+ expect(response).to have_gitlab_http_status(:unprocessable_entity)
+ end
+ end
+
+ context 'when job is cancelled' do
+ let(:status) { :canceled }
+
+ it 'returns 200' do
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'when job fails' do
+ let(:status) { :failed }
+
+ it 'returns 200' do
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'when job is successful' do
+ let(:status) { :success }
+
+ it 'returns 200' do
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+ end
+end
diff --git a/spec/controllers/projects/wikis_controller_spec.rb b/spec/controllers/projects/wikis_controller_spec.rb
index b4bbf76ce18..4e58822b613 100644
--- a/spec/controllers/projects/wikis_controller_spec.rb
+++ b/spec/controllers/projects/wikis_controller_spec.rb
@@ -2,283 +2,9 @@
require 'spec_helper'
-describe Projects::WikisController do
- let_it_be(:project) { create(:project, :public, :repository) }
- let(:user) { project.owner }
- let(:project_wiki) { ProjectWiki.new(project, user) }
- let(:wiki) { project_wiki.wiki }
- let(:wiki_title) { 'page title test' }
-
- before do
- create_page(wiki_title, 'hello world')
-
- sign_in(user)
- end
-
- after do
- destroy_page(wiki_title)
- end
-
- describe 'GET #new' do
- subject { get :new, params: { namespace_id: project.namespace, project_id: project } }
-
- it 'redirects to #show and appends a `random_title` param' do
- subject
-
- expect(response).to have_gitlab_http_status(:found)
- expect(Rails.application.routes.recognize_path(response.redirect_url)).to include(
- controller: 'projects/wikis',
- action: 'show'
- )
- expect(response.redirect_url).to match(/\?random_title=true\Z/)
- end
- end
-
- describe 'GET #pages' do
- subject { get :pages, params: { namespace_id: project.namespace, project_id: project, id: wiki_title } }
-
- it 'does not load the pages content' do
- expect(controller).to receive(:load_wiki).and_return(project_wiki)
-
- expect(project_wiki).to receive(:list_pages).twice.and_call_original
-
- subject
- end
- end
-
- describe 'GET #history' do
- before do
- allow(controller)
- .to receive(:can?)
- .with(any_args)
- .and_call_original
-
- # The :create_wiki permission is irrelevant to reading history.
- expect(controller)
- .not_to receive(:can?)
- .with(anything, :create_wiki, any_args)
-
- allow(controller)
- .to receive(:can?)
- .with(anything, :read_wiki, any_args)
- .and_return(allow_read_wiki)
- end
-
- shared_examples 'fetching history' do |expected_status|
- before do
- get :history, params: { namespace_id: project.namespace, project_id: project, id: wiki_title }
- end
-
- it "returns status #{expected_status}" do
- expect(response).to have_gitlab_http_status(expected_status)
- end
- end
-
- it_behaves_like 'fetching history', :ok do
- let(:allow_read_wiki) { true }
-
- it 'assigns @page_versions' do
- expect(assigns(:page_versions)).to be_present
- end
- end
-
- it_behaves_like 'fetching history', :not_found do
- let(:allow_read_wiki) { false }
- end
- end
-
- describe 'GET #show' do
- render_views
-
- let(:random_title) { nil }
-
- subject { get :show, params: { namespace_id: project.namespace, project_id: project, id: id, random_title: random_title } }
-
- context 'when page exists' do
- let(:id) { wiki_title }
-
- it 'limits the retrieved pages for the sidebar' do
- subject
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(assigns(:page).title).to eq(wiki_title)
- expect(assigns(:sidebar_wiki_entries)).to contain_exactly(an_instance_of(WikiPage))
- expect(assigns(:sidebar_limited)).to be(false)
- end
-
- context 'when page content encoding is invalid' do
- it 'sets flash error' do
- allow(controller).to receive(:valid_encoding?).and_return(false)
-
- subject
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(flash[:notice]).to eq(_('The content of this page is not encoded in UTF-8. Edits can only be made via the Git repository.'))
- end
- end
- end
-
- context 'when the page does not exist' do
- let(:id) { 'does not exist' }
-
- before do
- subject
- end
-
- it 'builds a new wiki page with the id as the title' do
- expect(assigns(:page).title).to eq(id)
- end
-
- context 'when a random_title param is present' do
- let(:random_title) { true }
-
- it 'builds a new wiki page with no title' do
- expect(assigns(:page).title).to be_empty
- end
- end
- end
-
- context 'when page is a file' do
- include WikiHelpers
-
- let(:id) { upload_file_to_wiki(project, user, file_name) }
-
- context 'when file is an image' do
- let(:file_name) { 'dk.png' }
-
- it 'delivers the image' do
- subject
-
- expect(response.headers['Content-Disposition']).to match(/^inline/)
- expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
- end
-
- context 'when file is a svg' do
- let(:file_name) { 'unsanitized.svg' }
-
- it 'delivers the image' do
- subject
-
- expect(response.headers['Content-Disposition']).to match(/^inline/)
- expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
- end
- end
-
- it_behaves_like 'project cache control headers'
- end
-
- context 'when file is a pdf' do
- let(:file_name) { 'git-cheat-sheet.pdf' }
-
- it 'sets the content type to sets the content response headers' do
- subject
-
- expect(response.headers['Content-Disposition']).to match(/^inline/)
- expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
- end
-
- it_behaves_like 'project cache control headers'
- end
- end
- end
-
- describe 'POST #preview_markdown' do
- it 'renders json in a correct format' do
- post :preview_markdown, params: { namespace_id: project.namespace, project_id: project, id: 'page/path', text: '*Markdown* text' }
-
- expect(json_response.keys).to match_array(%w(body references))
- end
- end
-
- describe 'GET #edit' do
- subject { get(:edit, params: { namespace_id: project.namespace, project_id: project, id: wiki_title }) }
-
- context 'when page content encoding is invalid' do
- it 'redirects to show' do
- allow(controller).to receive(:valid_encoding?).and_return(false)
-
- subject
-
- expect(response).to redirect_to_wiki(project, project_wiki.list_pages.first)
- end
- end
-
- context 'when the page has nil content' do
- let(:page) { create(:wiki_page) }
-
- it 'redirects to show' do
- allow(page).to receive(:content).and_return(nil)
- allow(controller).to receive(:find_page).and_return(page)
-
- subject
-
- expect(response).to redirect_to_wiki(project, page)
- end
- end
-
- context 'when page content encoding is valid' do
- render_views
-
- it 'shows the edit page' do
- subject
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(response.body).to include(s_('Wiki|Edit Page'))
- end
- end
- end
-
- describe 'PATCH #update' do
- let(:new_title) { 'New title' }
- let(:new_content) { 'New content' }
-
- subject do
- patch(:update,
- params: {
- namespace_id: project.namespace,
- project_id: project,
- id: wiki_title,
- wiki: { title: new_title, content: new_content }
- })
- end
-
- context 'when page content encoding is invalid' do
- it 'redirects to show' do
- allow(controller).to receive(:valid_encoding?).and_return(false)
-
- subject
- expect(response).to redirect_to_wiki(project, project_wiki.list_pages.first)
- end
- end
-
- context 'when page content encoding is valid' do
- render_views
-
- it 'updates the page' do
- subject
-
- wiki_page = project_wiki.list_pages(load_content: true).first
-
- expect(wiki_page.title).to eq new_title
- expect(wiki_page.content).to eq new_content
- end
- end
- end
-
- def create_page(name, content)
- wiki.write_page(name, :markdown, content, commit_details(name))
- end
-
- def commit_details(name)
- Gitlab::Git::Wiki::CommitDetails.new(user.id, user.username, user.name, user.email, "created page #{name}")
- end
-
- def destroy_page(title, dir = '')
- page = wiki.page(title: title, dir: dir)
- project_wiki.delete_page(page, "test commit")
- end
-
- def redirect_to_wiki(project, page)
- redirect_to(controller.project_wiki_path(project, page))
+RSpec.describe Projects::WikisController do
+ it_behaves_like 'wiki controller actions' do
+ let(:container) { create(:project, :public, :repository, namespace: user.namespace) }
+ let(:routing_params) { { namespace_id: container.namespace, project_id: container } }
end
end
diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb
index 6c00dad8bb7..8aae9ef85be 100644
--- a/spec/controllers/projects_controller_spec.rb
+++ b/spec/controllers/projects_controller_spec.rb
@@ -2,7 +2,7 @@
require('spec_helper')
-describe ProjectsController do
+RSpec.describe ProjectsController do
include ExternalAuthorizationServiceHelpers
include ProjectForksHelper
@@ -41,6 +41,27 @@ describe ProjectsController do
end
end
end
+
+ context 'with the new_create_project_ui experiment enabled and the user is part of the control group' do
+ before do
+ stub_experiment(new_create_project_ui: true)
+ stub_experiment_for_user(new_create_project_ui: false)
+ allow_any_instance_of(described_class).to receive(:experimentation_subject_id).and_return('uuid')
+ end
+
+ it 'passes the right tracking parameters to the frontend' do
+ get(:new)
+
+ expect(Gon.tracking_data).to eq(
+ {
+ category: 'Manage::Import::Experiment::NewCreateProjectUi',
+ action: 'click_tab',
+ label: 'uuid',
+ property: 'control_group'
+ }
+ )
+ end
+ end
end
end
@@ -359,6 +380,15 @@ describe ProjectsController do
end
end
end
+
+ context 'namespace storage limit' do
+ let_it_be(:project) { create(:project, :public, :repository ) }
+ let(:namespace) { project.namespace }
+
+ subject { get :show, params: { namespace_id: namespace, id: project } }
+
+ it_behaves_like 'namespace storage limit alert'
+ end
end
describe 'GET edit' do
@@ -1160,16 +1190,16 @@ describe ProjectsController do
shared_examples 'rate limits project export endpoint' do
before do
- allow(::Gitlab::ApplicationRateLimiter)
- .to receive(:throttled?)
- .and_return(true)
+ allow(Gitlab::ApplicationRateLimiter)
+ .to receive(:increment)
+ .and_return(Gitlab::ApplicationRateLimiter.rate_limits["project_#{action}".to_sym][:threshold] + 1)
end
it 'prevents requesting project export' do
post action, params: { namespace_id: project.namespace, id: project }
- expect(flash[:alert]).to eq('This endpoint has been requested too many times. Try again later.')
- expect(response).to have_gitlab_http_status(:found)
+ expect(response.body).to eq('This endpoint has been requested too many times. Try again later.')
+ expect(response).to have_gitlab_http_status(:too_many_requests)
end
end
@@ -1226,7 +1256,18 @@ describe ProjectsController do
end
context 'when the endpoint receives requests above the limit', :clean_gitlab_redis_cache do
- include_examples 'rate limits project export endpoint'
+ before do
+ allow(Gitlab::ApplicationRateLimiter)
+ .to receive(:increment)
+ .and_return(Gitlab::ApplicationRateLimiter.rate_limits[:project_download_export][:threshold] + 1)
+ end
+
+ it 'prevents requesting project export' do
+ post action, params: { namespace_id: project.namespace, id: project }
+
+ expect(response.body).to eq('This endpoint has been requested too many times. Try again later.')
+ expect(response).to have_gitlab_http_status(:too_many_requests)
+ end
end
end
end
diff --git a/spec/controllers/registrations/experience_levels_controller_spec.rb b/spec/controllers/registrations/experience_levels_controller_spec.rb
new file mode 100644
index 00000000000..1fc728f5de8
--- /dev/null
+++ b/spec/controllers/registrations/experience_levels_controller_spec.rb
@@ -0,0 +1,143 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Registrations::ExperienceLevelsController do
+ 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)
+ stub_experiment_for_user(onboarding_issues: true)
+ end
+
+ it { is_expected.to have_gitlab_http_status(:ok) }
+ it { is_expected.to render_template(:show) }
+
+ context 'when not part of the onboarding issues experiment' do
+ before do
+ stub_experiment_for_user(onboarding_issues: false)
+ end
+
+ it { is_expected.to have_gitlab_http_status(:not_found) }
+ end
+ 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
+ before do
+ sign_in(user)
+ stub_experiment_for_user(onboarding_issues: true)
+ end
+
+ context 'when not part of the onboarding issues experiment' do
+ before do
+ stub_experiment_for_user(onboarding_issues: false)
+ end
+
+ it { is_expected.to have_gitlab_http_status(:not_found) }
+ end
+
+ context 'when user is successfully updated' do
+ it { is_expected.to set_flash[:message].to('Welcome! You have signed up successfully.') }
+
+ 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 a namespace_path is sent' do
+ it { is_expected.to have_gitlab_http_status(:redirect) }
+ it { is_expected.to redirect_to(group_path(namespace)) }
+ end
+
+ context 'when no namespace_path is sent' do
+ let(:params) { super().merge(namespace_path: nil) }
+
+ it { is_expected.to have_gitlab_http_status(:redirect) }
+ it { is_expected.to redirect_to(root_path) }
+ end
+
+ describe 'applying the chosen level' do
+ context "when an 'onboarding_issues_settings' cookie does not exist" do
+ let(:params) { super().merge(experience_level: :novice) }
+
+ it 'does not change the cookie' do
+ expect { subject }.not_to change { cookies[:onboarding_issues_settings] }
+ end
+ end
+
+ context "when an 'onboarding_issues_settings' cookie does exist" do
+ before do
+ request.cookies[:onboarding_issues_settings] = '{}'
+ end
+
+ context 'when novice' do
+ let(:params) { super().merge(experience_level: :novice) }
+
+ it "adds a 'hideAdvanced' setting to the cookie" do
+ expect { subject }.to change { Gitlab::Json.parse(cookies[:onboarding_issues_settings])['hideAdvanced'] }.from(nil).to(true)
+ end
+ end
+
+ context 'when experienced' do
+ let(:params) { super().merge(experience_level: :experienced) }
+
+ it 'does not change the cookie' do
+ expect { subject }.not_to change { cookies[:onboarding_issues_settings] }
+ end
+ end
+ 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 01a9647a763..66caa58666f 100644
--- a/spec/controllers/registrations_controller_spec.rb
+++ b/spec/controllers/registrations_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe RegistrationsController do
+RSpec.describe RegistrationsController do
include TermsHelper
before do
diff --git a/spec/controllers/repositories/git_http_controller_spec.rb b/spec/controllers/repositories/git_http_controller_spec.rb
index 1a2eee5d3a9..aafb933df32 100644
--- a/spec/controllers/repositories/git_http_controller_spec.rb
+++ b/spec/controllers/repositories/git_http_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Repositories::GitHttpController do
+RSpec.describe Repositories::GitHttpController do
include GitHttpHelpers
let_it_be(:project) { create(:project, :public, :repository) }
diff --git a/spec/controllers/root_controller_spec.rb b/spec/controllers/root_controller_spec.rb
index 4892ff43086..9eefbcb0835 100644
--- a/spec/controllers/root_controller_spec.rb
+++ b/spec/controllers/root_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe RootController do
+RSpec.describe RootController do
describe 'GET index' do
context 'when user is not logged in' do
it 'redirects to the sign-in page' do
diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb
index 79ffa297da3..bae6bd07b67 100644
--- a/spec/controllers/search_controller_spec.rb
+++ b/spec/controllers/search_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe SearchController do
+RSpec.describe SearchController do
include ExternalAuthorizationServiceHelpers
let(:user) { create(:user) }
@@ -211,9 +211,4 @@ describe SearchController do
end.to raise_error(ActionController::ParameterMissing)
end
end
-
- describe 'GET #autocomplete' do
- it_behaves_like 'when the user cannot read cross project', :autocomplete, { term: 'hello' }
- it_behaves_like 'with external authorization service enabled', :autocomplete, { term: 'hello' }
- end
end
diff --git a/spec/controllers/sent_notifications_controller_spec.rb b/spec/controllers/sent_notifications_controller_spec.rb
index a0a18f66b0c..0c4a77d5926 100644
--- a/spec/controllers/sent_notifications_controller_spec.rb
+++ b/spec/controllers/sent_notifications_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe SentNotificationsController do
+RSpec.describe SentNotificationsController do
let(:user) { create(:user) }
let(:project) { create(:project, :public) }
let(:private_project) { create(:project, :private) }
diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb
index a65698a5b56..16a58112479 100644
--- a/spec/controllers/sessions_controller_spec.rb
+++ b/spec/controllers/sessions_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe SessionsController do
+RSpec.describe SessionsController do
include DeviseHelpers
include LdapHelpers
diff --git a/spec/controllers/snippets/notes_controller_spec.rb b/spec/controllers/snippets/notes_controller_spec.rb
index 0676ed05212..487635169fc 100644
--- a/spec/controllers/snippets/notes_controller_spec.rb
+++ b/spec/controllers/snippets/notes_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Snippets::NotesController do
+RSpec.describe Snippets::NotesController do
let(:user) { create(:user) }
let(:private_snippet) { create(:personal_snippet, :private) }
diff --git a/spec/controllers/snippets_controller_spec.rb b/spec/controllers/snippets_controller_spec.rb
index 046ee40cec2..70df1faf7dd 100644
--- a/spec/controllers/snippets_controller_spec.rb
+++ b/spec/controllers/snippets_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe SnippetsController do
+RSpec.describe SnippetsController do
let_it_be(:user) { create(:user) }
describe 'GET #index' do
diff --git a/spec/controllers/uploads_controller_spec.rb b/spec/controllers/uploads_controller_spec.rb
index 309a8226226..043fd97f1ad 100644
--- a/spec/controllers/uploads_controller_spec.rb
+++ b/spec/controllers/uploads_controller_spec.rb
@@ -1,25 +1,25 @@
# frozen_string_literal: true
require 'spec_helper'
-shared_examples 'content 5 min private cached with revalidation' do
+RSpec.shared_examples 'content 5 min private cached with revalidation' do
it 'ensures content will not be cached without revalidation' do
expect(subject['Cache-Control']).to eq('max-age=300, private, must-revalidate')
end
end
-shared_examples 'content not cached' do
+RSpec.shared_examples 'content not cached' do
it 'ensures content will not be cached without revalidation' do
expect(subject['Cache-Control']).to eq('max-age=0, private, must-revalidate')
end
end
-shared_examples 'content publicly cached' do
+RSpec.shared_examples 'content publicly cached' do
it 'ensures content is publicly cached' do
expect(subject['Cache-Control']).to eq('max-age=300, public')
end
end
-describe UploadsController do
+RSpec.describe UploadsController do
include WorkhorseHelpers
let!(:user) { create(:user, avatar: fixture_file_upload("spec/fixtures/dk.png", "image/png")) }
diff --git a/spec/controllers/user_callouts_controller_spec.rb b/spec/controllers/user_callouts_controller_spec.rb
index 04f73749e1d..279f825e40f 100644
--- a/spec/controllers/user_callouts_controller_spec.rb
+++ b/spec/controllers/user_callouts_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe UserCalloutsController do
+RSpec.describe UserCalloutsController do
let(:user) { create(:user) }
before do
diff --git a/spec/controllers/users/terms_controller_spec.rb b/spec/controllers/users/terms_controller_spec.rb
index 99582652c39..0acc3008187 100644
--- a/spec/controllers/users/terms_controller_spec.rb
+++ b/spec/controllers/users/terms_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Users::TermsController do
+RSpec.describe Users::TermsController do
include TermsHelper
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb
index 2af398e143d..bec4b24484a 100644
--- a/spec/controllers/users_controller_spec.rb
+++ b/spec/controllers/users_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe UsersController do
+RSpec.describe UsersController do
let(:user) { create(:user) }
let(:private_user) { create(:user, private_profile: true) }
let(:public_user) { create(:user) }
diff --git a/spec/db/development/import_common_metrics_spec.rb b/spec/db/development/import_common_metrics_spec.rb
index 25061ef0887..396eae9293e 100644
--- a/spec/db/development/import_common_metrics_spec.rb
+++ b/spec/db/development/import_common_metrics_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Import metrics on development seed' do
+RSpec.describe 'Import metrics on development seed' do
subject { load Rails.root.join('db', 'fixtures', 'development', '99_common_metrics.rb') }
it "imports all prometheus metrics" do
diff --git a/spec/db/production/import_common_metrics_spec.rb b/spec/db/production/import_common_metrics_spec.rb
index 1e4ff818a86..1cc0c2fd77f 100644
--- a/spec/db/production/import_common_metrics_spec.rb
+++ b/spec/db/production/import_common_metrics_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Import metrics on production seed' do
+RSpec.describe 'Import metrics on production seed' do
subject { load Rails.root.join('db', 'fixtures', 'production', '999_common_metrics.rb') }
it "imports all prometheus metrics" do
diff --git a/spec/db/production/settings_spec.rb b/spec/db/production/settings_spec.rb
index 02e25aa37e3..84f7ae12728 100644
--- a/spec/db/production/settings_spec.rb
+++ b/spec/db/production/settings_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require 'rainbow/ext/string'
-describe 'seed production settings' do
+RSpec.describe 'seed production settings' do
let(:settings_file) { Rails.root.join('db/fixtures/production/010_settings.rb') }
let(:settings) { Gitlab::CurrentSettings.current_application_settings }
diff --git a/spec/db/schema_spec.rb b/spec/db/schema_spec.rb
index eac9eb7aa47..95d7981b85c 100644
--- a/spec/db/schema_spec.rb
+++ b/spec/db/schema_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require Rails.root.join('ee', 'spec', 'db', 'schema_support') if Gitlab.ee?
-describe 'Database schema' do
+RSpec.describe 'Database schema' do
prepend_if_ee('EE::DB::SchemaSupport')
let(:connection) { ActiveRecord::Base.connection }
@@ -92,7 +92,8 @@ describe 'Database schema' do
let(:indexes) { connection.indexes(table) }
let(:columns) { connection.columns(table) }
let(:foreign_keys) { connection.foreign_keys(table) }
- let(:primary_key_column) { connection.primary_key(table) }
+ # take the first column in case we're using a composite primary key
+ let(:primary_key_column) { Array(connection.primary_key(table)).first }
context 'all foreign keys' do
# for index to be effective, the FK constraint has to be at first place
diff --git a/spec/dependencies/omniauth_saml_spec.rb b/spec/dependencies/omniauth_saml_spec.rb
index e0ea9c38e69..fa179eb1516 100644
--- a/spec/dependencies/omniauth_saml_spec.rb
+++ b/spec/dependencies/omniauth_saml_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require 'omniauth/strategies/saml'
-describe 'processing of SAMLResponse in dependencies' do
+RSpec.describe 'processing of SAMLResponse in dependencies' do
let(:mock_saml_response) { File.read('spec/fixtures/authentication/saml_response.xml') }
let(:saml_strategy) { OmniAuth::Strategies::SAML.new({}) }
let(:session_mock) { {} }
diff --git a/spec/factories/alert_management/alerts.rb b/spec/factories/alert_management/alerts.rb
index 01f40a7a465..8724a626d77 100644
--- a/spec/factories/alert_management/alerts.rb
+++ b/spec/factories/alert_management/alerts.rb
@@ -8,10 +8,23 @@ FactoryBot.define do
title { FFaker::Lorem.sentence }
started_at { Time.current }
+ trait :with_validation_errors do
+ after(:create) do |alert|
+ too_many_hosts = Array.new(AlertManagement::Alert::HOSTS_MAX_LENGTH + 1) { |_| 'host' }
+ alert.update_columns(hosts: too_many_hosts)
+ end
+ end
+
trait :with_issue do
issue
end
+ trait :with_assignee do |alert|
+ after(:create) do |alert|
+ alert.alert_assignees.create(assignee: create(:user))
+ end
+ end
+
trait :with_fingerprint do
fingerprint { SecureRandom.hex }
end
@@ -70,6 +83,7 @@ FactoryBot.define do
trait :all_fields do
with_issue
+ with_assignee
with_fingerprint
with_service
with_monitoring_tool
diff --git a/spec/factories/ci/build_report_results.rb b/spec/factories/ci/build_report_results.rb
new file mode 100644
index 00000000000..0685c0e5554
--- /dev/null
+++ b/spec/factories/ci/build_report_results.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :ci_build_report_result, class: 'Ci::BuildReportResult' do
+ build factory: :ci_build
+ project factory: :project
+ data do
+ {
+ tests: {
+ name: "rspec",
+ duration: 0.42,
+ failed: 0,
+ errored: 2,
+ skipped: 0,
+ success: 0
+ }
+ }
+ end
+
+ trait :with_junit_success do
+ data do
+ {
+ tests: {
+ name: "rspec",
+ duration: 0.42,
+ failed: 0,
+ errored: 0,
+ skipped: 0,
+ success: 2
+ }
+ }
+ end
+ end
+ end
+end
diff --git a/spec/factories/ci/builds.rb b/spec/factories/ci/builds.rb
index 26786aab12c..9403967aa0a 100644
--- a/spec/factories/ci/builds.rb
+++ b/spec/factories/ci/builds.rb
@@ -378,6 +378,21 @@ FactoryBot.define do
end
end
+ trait :release_options do
+ options do
+ {
+ only: 'tags',
+ script: ['make changelog | tee release_changelog.txt'],
+ release: {
+ name: 'Release $CI_COMMIT_SHA',
+ description: 'Created using the release-cli $EXTRA_DESCRIPTION',
+ tag_name: 'release-$CI_COMMIT_SHA',
+ ref: '$CI_COMMIT_SHA'
+ }
+ }
+ end
+ end
+
trait :no_options do
options { {} }
end
@@ -400,6 +415,14 @@ FactoryBot.define do
end
end
+ trait :secret_detection do
+ options do
+ {
+ artifacts: { reports: { secret_detection: 'gl-secret-detection-report.json' } }
+ }
+ end
+ end
+
trait :dependency_scanning do
options do
{
diff --git a/spec/factories/ci/job_artifacts.rb b/spec/factories/ci/job_artifacts.rb
index 26c09795a0b..1bd4b2826c4 100644
--- a/spec/factories/ci/job_artifacts.rb
+++ b/spec/factories/ci/job_artifacts.rb
@@ -233,12 +233,9 @@ FactoryBot.define do
file_type { :lsif }
file_format { :zip }
- transient do
- file_path { Rails.root.join('spec/fixtures/lsif.json.gz') }
- end
-
after(:build) do |artifact, evaluator|
- artifact.file = fixture_file_upload(evaluator.file_path, 'application/x-gzip')
+ artifact.file = fixture_file_upload(
+ Rails.root.join('spec/fixtures/lsif.json.zip'), 'application/zip')
end
end
diff --git a/spec/factories/ci/pipelines.rb b/spec/factories/ci/pipelines.rb
index 0b3653a01ed..85cdeaca12c 100644
--- a/spec/factories/ci/pipelines.rb
+++ b/spec/factories/ci/pipelines.rb
@@ -21,6 +21,12 @@ FactoryBot.define do
end
factory :ci_pipeline do
+ transient { ci_ref_presence { true } }
+
+ after(:build) do |pipeline, evaluator|
+ pipeline.ensure_ci_ref! if evaluator.ci_ref_presence && pipeline.ci_ref_id.nil?
+ end
+
trait :invalid do
status { :failed }
yaml_errors { 'invalid YAML' }
@@ -104,6 +110,7 @@ FactoryBot.define do
after(:build) do |pipeline, evaluator|
pipeline.builds << build(:ci_build, :terraform_reports, pipeline: pipeline, project: pipeline.project)
+ pipeline.builds << build(:ci_build, :terraform_reports, pipeline: pipeline, project: pipeline.project)
end
end
@@ -155,6 +162,11 @@ FactoryBot.define do
source_sha { merge_request.source_branch_sha }
target_sha { merge_request.target_branch_sha }
end
+
+ trait :webide do
+ source { :webide }
+ config_source { :webide_source }
+ end
end
end
end
diff --git a/spec/factories/ci/ref.rb b/spec/factories/ci/ref.rb
index 891d8848a72..bf6fa743743 100644
--- a/spec/factories/ci/ref.rb
+++ b/spec/factories/ci/ref.rb
@@ -2,15 +2,7 @@
FactoryBot.define do
factory :ci_ref, class: 'Ci::Ref' do
- ref { 'master' }
- status { :success }
- tag { false }
+ ref_path { 'refs/heads/master' }
project
-
- before(:create) do |ref, evaluator|
- next if ref.pipelines.exists?
-
- ref.update!(last_updated_by_pipeline: create(:ci_pipeline, project: evaluator.project, ref: evaluator.ref, tag: evaluator.tag, status: evaluator.status))
- end
end
end
diff --git a/spec/factories/clusters/clusters.rb b/spec/factories/clusters/clusters.rb
index 843f87ef7d6..7d0aaa45e40 100644
--- a/spec/factories/clusters/clusters.rb
+++ b/spec/factories/clusters/clusters.rb
@@ -86,6 +86,23 @@ FactoryBot.define do
application_helm factory: %i(clusters_applications_helm installed)
end
+ trait :with_installed_prometheus do
+ application_prometheus factory: %i(clusters_applications_prometheus installed)
+ end
+
+ trait :with_all_applications do
+ application_helm factory: %i(clusters_applications_helm installed)
+ application_ingress factory: %i(clusters_applications_ingress installed)
+ application_cert_manager factory: %i(clusters_applications_cert_manager installed)
+ application_crossplane factory: %i(clusters_applications_crossplane installed)
+ application_prometheus factory: %i(clusters_applications_prometheus installed)
+ application_runner factory: %i(clusters_applications_runner installed)
+ application_jupyter factory: %i(clusters_applications_jupyter installed)
+ application_knative factory: %i(clusters_applications_knative installed)
+ application_elastic_stack factory: %i(clusters_applications_elastic_stack installed)
+ application_fluentd factory: %i(clusters_applications_fluentd installed)
+ end
+
trait :with_domain do
domain { 'example.com' }
end
diff --git a/spec/factories/design_management/designs.rb b/spec/factories/design_management/designs.rb
index 59d4cc56f95..6d1229063d8 100644
--- a/spec/factories/design_management/designs.rb
+++ b/spec/factories/design_management/designs.rb
@@ -35,7 +35,7 @@ FactoryBot.define do
sha = commit_version[action]
version = DesignManagement::Version.new(sha: sha, issue: issue, author: evaluator.author)
version.save(validate: false) # We need it to have an ID, validate later
- Gitlab::Database.bulk_insert(dv_table_name, [action.row_attrs(version)])
+ Gitlab::Database.bulk_insert(dv_table_name, [action.row_attrs(version)]) # rubocop:disable Gitlab/BulkInsert
end
# always a creation
diff --git a/spec/factories/draft_note.rb b/spec/factories/draft_note.rb
new file mode 100644
index 00000000000..24563dc92b7
--- /dev/null
+++ b/spec/factories/draft_note.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+FactoryBot.define do
+ factory :draft_note do
+ note { generate(:title) }
+ association :author, factory: :user
+ association :merge_request, factory: :merge_request
+
+ factory :draft_note_on_text_diff do
+ transient do
+ line_number { 14 }
+ diff_refs { merge_request.try(:diff_refs) }
+ end
+
+ position do
+ Gitlab::Diff::Position.new(
+ old_path: "files/ruby/popen.rb",
+ new_path: "files/ruby/popen.rb",
+ old_line: nil,
+ new_line: line_number,
+ diff_refs: diff_refs
+ )
+ end
+ end
+
+ factory :draft_note_on_discussion, traits: [:on_discussion]
+
+ trait :on_discussion do
+ discussion_id { create(:discussion_note_on_merge_request, noteable: merge_request, project: project).discussion_id }
+ end
+ end
+end
diff --git a/spec/factories/events.rb b/spec/factories/events.rb
index ed6cb3505f4..60bb3044191 100644
--- a/spec/factories/events.rb
+++ b/spec/factories/events.rb
@@ -4,27 +4,28 @@ FactoryBot.define do
factory :event do
project
author(factory: :user) { project.creator }
- action { Event::JOINED }
-
- trait(:created) { action { Event::CREATED } }
- trait(:updated) { action { Event::UPDATED } }
- trait(:closed) { action { Event::CLOSED } }
- trait(:reopened) { action { Event::REOPENED } }
- trait(:pushed) { action { Event::PUSHED } }
- trait(:commented) { action { Event::COMMENTED } }
- trait(:merged) { action { Event::MERGED } }
- trait(:joined) { action { Event::JOINED } }
- trait(:left) { action { Event::LEFT } }
- trait(:destroyed) { action { Event::DESTROYED } }
- trait(:expired) { action { Event::EXPIRED } }
+ action { :joined }
+
+ trait(:created) { action { :created } }
+ trait(:updated) { action { :updated } }
+ trait(:closed) { action { :closed } }
+ trait(:reopened) { action { :reopened } }
+ trait(:pushed) { action { :pushed } }
+ trait(:commented) { action { :commented } }
+ trait(:merged) { action { :merged } }
+ trait(:joined) { action { :joined } }
+ trait(:left) { action { :left } }
+ trait(:destroyed) { action { :destroyed } }
+ trait(:expired) { action { :expired } }
+ trait(:archived) { action { :archived } }
factory :closed_issue_event do
- action { Event::CLOSED }
+ action { :closed }
target factory: :closed_issue
end
factory :wiki_page_event do
- action { Event::CREATED }
+ action { :created }
project { @overrides[:wiki_page]&.container || create(:project, :wiki_repo) }
target { create(:wiki_page_meta, :for_wiki_page, wiki_page: wiki_page) }
@@ -33,21 +34,33 @@ FactoryBot.define do
end
end
- trait :for_design do
+ trait :has_design do
transient do
design { create(:design, issue: create(:issue, project: project)) }
+ end
+ end
+
+ trait :for_design do
+ has_design
+
+ transient do
note { create(:note, author: author, project: project, noteable: design) }
end
- action { Event::COMMENTED }
+ action { :commented }
target { note }
end
+
+ factory :design_event, traits: [:has_design] do
+ action { :created }
+ target { design }
+ end
end
factory :push_event, class: 'PushEvent' do
project factory: :project_empty_repo
author(factory: :user) { project.creator }
- action { Event::PUSHED }
+ action { :pushed }
end
factory :push_event_payload do
diff --git a/spec/factories/evidences.rb b/spec/factories/evidences.rb
index 77116d8e9ed..dc9fc374103 100644
--- a/spec/factories/evidences.rb
+++ b/spec/factories/evidences.rb
@@ -3,5 +3,7 @@
FactoryBot.define do
factory :evidence, class: 'Releases::Evidence' do
release
+ summary_sha { "760d6cdfb0879c3ffedec13af470e0f71cf52c6cde4d" }
+ summary { { "release": { "tag": "v4.0", "name": "New release", "project_name": "Project name" } } }
end
end
diff --git a/spec/factories/group_import_states.rb b/spec/factories/group_import_states.rb
new file mode 100644
index 00000000000..0b491d444fa
--- /dev/null
+++ b/spec/factories/group_import_states.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :group_import_state, class: 'GroupImportState', traits: %i[created] do
+ association :group, factory: :group
+
+ trait :created do
+ status { 0 }
+ end
+
+ trait :started do
+ status { 1 }
+ sequence(:jid) { |n| "group_import_state_#{n}" }
+ end
+
+ trait :finished do
+ status { 2 }
+ sequence(:jid) { |n| "group_import_state_#{n}" }
+ end
+
+ trait :failed do
+ status { -1 }
+ end
+ end
+end
diff --git a/spec/factories/keys.rb b/spec/factories/keys.rb
index 087d2521836..cf52e772ae0 100644
--- a/spec/factories/keys.rb
+++ b/spec/factories/keys.rb
@@ -13,6 +13,10 @@ FactoryBot.define do
factory :deploy_key, class: 'DeployKey'
+ factory :group_deploy_key, class: 'GroupDeployKey' do
+ user
+ end
+
factory :personal_key do
user
end
diff --git a/spec/factories/labels.rb b/spec/factories/labels.rb
index 81d3e4be6fd..2e783adcc94 100644
--- a/spec/factories/labels.rb
+++ b/spec/factories/labels.rb
@@ -6,6 +6,18 @@ FactoryBot.define do
color { "#990000" }
end
+ trait :described do
+ description { "Description of #{title}" }
+ end
+
+ trait :scoped do
+ transient do
+ prefix { 'scope' }
+ end
+
+ title { "#{prefix}::#{generate(:label_title)}" }
+ end
+
factory :label, traits: [:base_label], class: 'ProjectLabel' do
project
diff --git a/spec/factories/merge_requests.rb b/spec/factories/merge_requests.rb
index b10c04a37f7..2a06690f894 100644
--- a/spec/factories/merge_requests.rb
+++ b/spec/factories/merge_requests.rb
@@ -109,6 +109,17 @@ FactoryBot.define do
end
end
+ trait :with_head_pipeline do
+ after(:build) do |merge_request|
+ merge_request.head_pipeline = build(
+ :ci_pipeline,
+ :running,
+ project: merge_request.source_project,
+ ref: merge_request.source_branch,
+ sha: merge_request.diff_head_sha)
+ end
+ end
+
trait :with_test_reports do
after(:build) do |merge_request|
merge_request.head_pipeline = build(
@@ -133,6 +144,11 @@ FactoryBot.define do
end
end
+ trait :unique_branches do
+ source_branch { generate(:branch) }
+ target_branch { generate(:branch) }
+ end
+
trait :with_coverage_reports do
after(:build) do |merge_request|
merge_request.head_pipeline = build(
diff --git a/spec/factories/notes.rb b/spec/factories/notes.rb
index 7c3ba122b5a..52e91f31ec1 100644
--- a/spec/factories/notes.rb
+++ b/spec/factories/notes.rb
@@ -17,17 +17,13 @@ FactoryBot.define do
factory :note_on_project_snippet, traits: [:on_project_snippet]
factory :note_on_personal_snippet, traits: [:on_personal_snippet]
factory :note_on_design, traits: [:on_design]
+ factory :note_on_alert, traits: [:on_alert]
factory :system_note, traits: [:system]
factory :discussion_note, class: 'DiscussionNote'
factory :discussion_note_on_merge_request, traits: [:on_merge_request], class: 'DiscussionNote' do
association :project, :repository
-
- trait :resolved do
- resolved_at { Time.now }
- resolved_by { create(:user) }
- end
end
factory :track_mr_picking_note, traits: [:on_merge_request, :system] do
@@ -76,11 +72,6 @@ FactoryBot.define do
end
end
- trait :resolved do
- resolved_at { Time.now }
- resolved_by { create(:user) }
- end
-
factory :image_diff_note_on_merge_request do
position do
build(:image_diff_position,
@@ -155,6 +146,15 @@ FactoryBot.define do
end
end
+ trait :on_alert do
+ noteable { association(:alert_management_alert, project: project) }
+ end
+
+ trait :resolved do
+ resolved_at { Time.now }
+ resolved_by { association(:user) }
+ end
+
trait :system do
system { true }
end
@@ -183,6 +183,10 @@ FactoryBot.define do
confidential { true }
end
+ trait :with_review do
+ review
+ end
+
transient do
in_reply_to { nil }
end
diff --git a/spec/factories/project_group_links.rb b/spec/factories/project_group_links.rb
index b9119a5788b..5e3e83f18c1 100644
--- a/spec/factories/project_group_links.rb
+++ b/spec/factories/project_group_links.rb
@@ -5,10 +5,15 @@ FactoryBot.define do
project
group
expires_at { nil }
+ group_access { Gitlab::Access::DEVELOPER }
trait(:guest) { group_access { Gitlab::Access::GUEST } }
trait(:reporter) { group_access { Gitlab::Access::REPORTER } }
trait(:developer) { group_access { Gitlab::Access::DEVELOPER } }
trait(:maintainer) { group_access { Gitlab::Access::MAINTAINER } }
+
+ after(:create) do |project_group_link, evaluator|
+ project_group_link.group.refresh_members_authorized_projects
+ end
end
end
diff --git a/spec/factories/project_repository_storage_moves.rb b/spec/factories/project_repository_storage_moves.rb
index aa8576834eb..b35d5e1d535 100644
--- a/spec/factories/project_repository_storage_moves.rb
+++ b/spec/factories/project_repository_storage_moves.rb
@@ -10,5 +10,9 @@ FactoryBot.define do
trait :scheduled do
state { ProjectRepositoryStorageMove.state_machines[:state].states[:scheduled].value }
end
+
+ trait :started do
+ state { ProjectRepositoryStorageMove.state_machines[:state].states[:started].value }
+ end
end
end
diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb
index 45caa7a2b6a..4affab295b8 100644
--- a/spec/factories/projects.rb
+++ b/spec/factories/projects.rb
@@ -297,6 +297,12 @@ FactoryBot.define do
trait :auto_devops_disabled do
association :auto_devops, factory: [:project_auto_devops, :disabled]
end
+
+ trait :without_container_expiration_policy do
+ after :create do |project|
+ project.container_expiration_policy.destroy!
+ end
+ end
end
# Project with empty repository
diff --git a/spec/factories/releases/link.rb b/spec/factories/releases/link.rb
index 001deeb71a0..da0efe4a749 100644
--- a/spec/factories/releases/link.rb
+++ b/spec/factories/releases/link.rb
@@ -6,5 +6,6 @@ FactoryBot.define do
sequence(:name) { |n| "release-18.#{n}.dmg" }
sequence(:url) { |n| "https://example.com/scrambled-url/app-#{n}.zip" }
sequence(:filepath) { |n| "/binaries/awesome-app-#{n}" }
+ link_type { 'other' }
end
end
diff --git a/spec/factories/reviews.rb b/spec/factories/reviews.rb
new file mode 100644
index 00000000000..7cf752f1cd9
--- /dev/null
+++ b/spec/factories/reviews.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :review do
+ merge_request
+ association :project, :repository
+ author factory: :user
+ end
+end
diff --git a/spec/factories/services.rb b/spec/factories/services.rb
index b6696769da9..fd97f6abb85 100644
--- a/spec/factories/services.rb
+++ b/spec/factories/services.rb
@@ -45,9 +45,13 @@ FactoryBot.define do
end
factory :alerts_service do
+ active
project
type { 'AlertsService' }
- active { true }
+
+ trait :active do
+ active { true }
+ end
trait :inactive do
active { false }
@@ -165,6 +169,13 @@ FactoryBot.define do
type { 'SlackService' }
end
+ factory :pipelines_email_service do
+ project
+ active { true }
+ type { 'PipelinesEmailService' }
+ recipients { 'test@example.com' }
+ end
+
# this is for testing storing values inside properties, which is deprecated and will be removed in
# https://gitlab.com/gitlab-org/gitlab/issues/29404
trait :without_properties_callback do
diff --git a/spec/factories/usage_data.rb b/spec/factories/usage_data.rb
index 8fe0018b5a6..c0c5b1103fe 100644
--- a/spec/factories/usage_data.rb
+++ b/spec/factories/usage_data.rb
@@ -33,6 +33,12 @@ FactoryBot.define do
issues = create_list(:issue, 4, project: projects[0])
create_list(:prometheus_alert, 2, project: projects[0])
create(:prometheus_alert, project: projects[1])
+ create(:merge_request, :simple, :with_terraform_reports, source_project: projects[0])
+ create(:merge_request, :rebased, :with_terraform_reports, source_project: projects[0])
+ create(:merge_request, :simple, :with_terraform_reports, source_project: projects[1])
+ create(:terraform_state, project: projects[0])
+ create(:terraform_state, project: projects[0])
+ create(:terraform_state, project: projects[1])
create(:zoom_meeting, project: projects[0], issue: projects[0].issues[0], issue_status: :added)
create_list(:zoom_meeting, 2, project: projects[0], issue: projects[0].issues[1], issue_status: :removed)
create(:zoom_meeting, project: projects[0], issue: projects[0].issues[2], issue_status: :added)
@@ -52,6 +58,7 @@ FactoryBot.define do
# Alert Issues
create(:alert_management_alert, issue: issues[0], project: projects[0])
create(:alert_management_alert, issue: alert_bot_issues[0], project: projects[0])
+ create(:self_managed_prometheus_alert_event, related_issues: [issues[1]], project: projects[0])
# Enabled clusters
gcp_cluster = create(:cluster_provider_gcp, :created).cluster
diff --git a/spec/factories_spec.rb b/spec/factories_spec.rb
index aa72a116be2..f89aeb1c93d 100644
--- a/spec/factories_spec.rb
+++ b/spec/factories_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'factories' do
+RSpec.describe 'factories' do
FactoryBot.factories.each do |factory|
describe "#{factory.name} factory" do
it 'does not raise error when built' do
diff --git a/spec/fast_spec_helper.rb b/spec/fast_spec_helper.rb
index 1a8af335244..cbab809cddb 100644
--- a/spec/fast_spec_helper.rb
+++ b/spec/fast_spec_helper.rb
@@ -13,4 +13,5 @@ require 'active_support/all'
ActiveSupport::Dependencies.autoload_paths << 'lib'
ActiveSupport::Dependencies.autoload_paths << 'ee/lib'
+
ActiveSupport::XmlMini.backend = 'Nokogiri'
diff --git a/spec/features/abuse_report_spec.rb b/spec/features/abuse_report_spec.rb
index b1573bfb270..5959fcd6306 100644
--- a/spec/features/abuse_report_spec.rb
+++ b/spec/features/abuse_report_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Abuse reports' do
+RSpec.describe 'Abuse reports' do
let(:another_user) { create(:user) }
before do
diff --git a/spec/features/action_cable_logging_spec.rb b/spec/features/action_cable_logging_spec.rb
new file mode 100644
index 00000000000..ce7c0e03aad
--- /dev/null
+++ b/spec/features/action_cable_logging_spec.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'ActionCable logging', :js do
+ let_it_be(:project) { create(:project, :public) }
+ let_it_be(:issue) { create(:issue, project: project) }
+ let_it_be(:user) { create(:user) }
+
+ before_all do
+ project.add_developer(user)
+ end
+
+ it 'adds extra context to logs' do
+ allow(ActiveSupport::Notifications).to receive(:instrument).and_call_original
+
+ expect(ActiveSupport::Notifications).to receive(:instrument).with(
+ 'connect.action_cable',
+ a_hash_including(remote_ip: '127.0.0.1', user_id: nil, username: nil)
+ )
+
+ subscription_data = a_hash_including(
+ remote_ip: '127.0.0.1',
+ user_id: user.id,
+ username: user.username,
+ params: a_hash_including(
+ project_path: project.full_path,
+ iid: issue.iid.to_s
+ )
+ )
+
+ expect(ActiveSupport::Notifications).to receive(:instrument).with('subscribe.action_cable', subscription_data)
+
+ gitlab_sign_in(user)
+ visit project_issue_path(project, issue)
+
+ # Because there is no visual indicator for Capybara to wait on before closing the browser,
+ # we need to test an actual feature to ensure that the subscription was already established.
+
+ expect(page.find('.assignee')).to have_content 'None'
+
+ fill_in 'note[note]', with: "/assign #{user.username}"
+ click_button 'Comment'
+
+ expect(page.find('.assignee')).to have_content user.name
+ end
+end
diff --git a/spec/features/admin/admin_abuse_reports_spec.rb b/spec/features/admin/admin_abuse_reports_spec.rb
index 93051a8a355..845e186dd5b 100644
--- a/spec/features/admin/admin_abuse_reports_spec.rb
+++ b/spec/features/admin/admin_abuse_reports_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Admin::AbuseReports", :js do
+RSpec.describe "Admin::AbuseReports", :js do
let(:user) { create(:user) }
context 'as an admin' do
diff --git a/spec/features/admin/admin_appearance_spec.rb b/spec/features/admin/admin_appearance_spec.rb
index e711ee7d40e..48aaec6e6df 100644
--- a/spec/features/admin/admin_appearance_spec.rb
+++ b/spec/features/admin/admin_appearance_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin Appearance' do
+RSpec.describe 'Admin Appearance' do
let!(:appearance) { create(:appearance) }
it 'Create new appearance' do
diff --git a/spec/features/admin/admin_broadcast_messages_spec.rb b/spec/features/admin/admin_broadcast_messages_spec.rb
index bf7f8563e68..091ed0a3396 100644
--- a/spec/features/admin/admin_broadcast_messages_spec.rb
+++ b/spec/features/admin/admin_broadcast_messages_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin Broadcast Messages' do
+RSpec.describe 'Admin Broadcast Messages' do
before do
sign_in(create(:admin))
create(:broadcast_message, :expired, message: 'Migration to new server')
diff --git a/spec/features/admin/admin_browse_spam_logs_spec.rb b/spec/features/admin/admin_browse_spam_logs_spec.rb
index c79524a7fb3..65847876c11 100644
--- a/spec/features/admin/admin_browse_spam_logs_spec.rb
+++ b/spec/features/admin/admin_browse_spam_logs_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin browse spam logs' do
+RSpec.describe 'Admin browse spam logs' do
let!(:spam_log) { create(:spam_log, description: 'abcde ' * 20) }
before do
diff --git a/spec/features/admin/admin_builds_spec.rb b/spec/features/admin/admin_builds_spec.rb
index afdf8eb0cca..85f0c44ed9c 100644
--- a/spec/features/admin/admin_builds_spec.rb
+++ b/spec/features/admin/admin_builds_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin Builds' do
+RSpec.describe 'Admin Builds' do
before do
sign_in(create(:admin))
end
diff --git a/spec/features/admin/admin_disables_git_access_protocol_spec.rb b/spec/features/admin/admin_disables_git_access_protocol_spec.rb
index 05ebb7e90d2..d7feb21a8b3 100644
--- a/spec/features/admin/admin_disables_git_access_protocol_spec.rb
+++ b/spec/features/admin/admin_disables_git_access_protocol_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin disables Git access protocol', :js do
+RSpec.describe 'Admin disables Git access protocol', :js do
include StubENV
include MobileHelpers
diff --git a/spec/features/admin/admin_disables_two_factor_spec.rb b/spec/features/admin/admin_disables_two_factor_spec.rb
index 7227141168e..216c8ae36c7 100644
--- a/spec/features/admin/admin_disables_two_factor_spec.rb
+++ b/spec/features/admin/admin_disables_two_factor_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin disables 2FA for a user' do
+RSpec.describe 'Admin disables 2FA for a user' do
it 'successfully', :js do
sign_in(create(:admin))
user = create(:user, :two_factor)
diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb
index 1d82650d11d..9cd335ffb8c 100644
--- a/spec/features/admin/admin_groups_spec.rb
+++ b/spec/features/admin/admin_groups_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin Groups' do
+RSpec.describe 'Admin Groups' do
include Select2Helper
let(:internal) { Gitlab::VisibilityLevel::INTERNAL }
@@ -181,7 +181,7 @@ describe 'Admin Groups' do
end
end
- describe 'admin remove himself from a group', :js do
+ describe 'admin remove themself from a group', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/222342' do
it 'removes admin from the group' do
group.add_user(current_user, Gitlab::Access::DEVELOPER)
diff --git a/spec/features/admin/admin_health_check_spec.rb b/spec/features/admin/admin_health_check_spec.rb
index 9ce96fe8020..dfc7f5f6f84 100644
--- a/spec/features/admin/admin_health_check_spec.rb
+++ b/spec/features/admin/admin_health_check_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Admin Health Check", :feature do
+RSpec.describe "Admin Health Check", :feature do
include StubENV
let_it_be(:admin) { create(:admin) }
diff --git a/spec/features/admin/admin_hook_logs_spec.rb b/spec/features/admin/admin_hook_logs_spec.rb
index 98900142353..f4a70621cee 100644
--- a/spec/features/admin/admin_hook_logs_spec.rb
+++ b/spec/features/admin/admin_hook_logs_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin::HookLogs' do
+RSpec.describe 'Admin::HookLogs' do
let(:project) { create(:project) }
let(:system_hook) { create(:system_hook) }
let(:hook_log) { create(:web_hook_log, web_hook: system_hook, internal_error_message: 'some error') }
diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb
index 40bcf4a31e4..1c14d65a1cd 100644
--- a/spec/features/admin/admin_hooks_spec.rb
+++ b/spec/features/admin/admin_hooks_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin::Hooks' do
+RSpec.describe 'Admin::Hooks' do
let(:user) { create(:admin) }
before do
diff --git a/spec/features/admin/admin_mode/login_spec.rb b/spec/features/admin/admin_mode/login_spec.rb
index afc6f2ddb56..4b26ceb55e2 100644
--- a/spec/features/admin/admin_mode/login_spec.rb
+++ b/spec/features/admin/admin_mode/login_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin Mode Login', :clean_gitlab_redis_shared_state, :do_not_mock_admin_mode do
+RSpec.describe 'Admin Mode Login', :clean_gitlab_redis_shared_state, :do_not_mock_admin_mode do
include TermsHelper
include UserLoginHelper
include LdapHelpers
diff --git a/spec/features/admin/admin_mode/logout_spec.rb b/spec/features/admin/admin_mode/logout_spec.rb
index e1b4aba5724..b4d49fe760f 100644
--- a/spec/features/admin/admin_mode/logout_spec.rb
+++ b/spec/features/admin/admin_mode/logout_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin Mode Logout', :js, :clean_gitlab_redis_shared_state, :do_not_mock_admin_mode do
+RSpec.describe 'Admin Mode Logout', :js, :clean_gitlab_redis_shared_state, :do_not_mock_admin_mode do
include TermsHelper
include UserLoginHelper
diff --git a/spec/features/admin/admin_mode/workers_spec.rb b/spec/features/admin/admin_mode/workers_spec.rb
index 0ca61e6c193..d037f5555dc 100644
--- a/spec/features/admin/admin_mode/workers_spec.rb
+++ b/spec/features/admin/admin_mode/workers_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
# Test an operation that triggers background jobs requiring administrative rights
-describe 'Admin mode for workers', :do_not_mock_admin_mode, :request_store, :clean_gitlab_redis_shared_state do
+RSpec.describe 'Admin mode for workers', :do_not_mock_admin_mode, :request_store, :clean_gitlab_redis_shared_state do
let(:user) { create(:user) }
let(:user_to_delete) { create(:user) }
diff --git a/spec/features/admin/admin_mode_spec.rb b/spec/features/admin/admin_mode_spec.rb
index f642d614a5d..3b4edbc1a07 100644
--- a/spec/features/admin/admin_mode_spec.rb
+++ b/spec/features/admin/admin_mode_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin mode', :clean_gitlab_redis_shared_state, :do_not_mock_admin_mode do
+RSpec.describe 'Admin mode', :clean_gitlab_redis_shared_state, :do_not_mock_admin_mode do
include MobileHelpers
include StubENV
diff --git a/spec/features/admin/admin_projects_spec.rb b/spec/features/admin/admin_projects_spec.rb
index d1889d3a89a..cbaa18509ba 100644
--- a/spec/features/admin/admin_projects_spec.rb
+++ b/spec/features/admin/admin_projects_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Admin::Projects" do
+RSpec.describe "Admin::Projects" do
include Select2Helper
let(:user) { create :user }
diff --git a/spec/features/admin/admin_requests_profiles_spec.rb b/spec/features/admin/admin_requests_profiles_spec.rb
index e93c0ff8b20..c649fdd8e19 100644
--- a/spec/features/admin/admin_requests_profiles_spec.rb
+++ b/spec/features/admin/admin_requests_profiles_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin::RequestsProfilesController' do
+RSpec.describe 'Admin::RequestsProfilesController' do
let(:tmpdir) { Dir.mktmpdir('profiler-test') }
before do
diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb
index ca2fd2f2e9e..0e20ccf6bec 100644
--- a/spec/features/admin/admin_runners_spec.rb
+++ b/spec/features/admin/admin_runners_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Admin Runners" do
+RSpec.describe "Admin Runners" do
include StubENV
include FilteredSearchHelpers
include SortingHelper
diff --git a/spec/features/admin/admin_sees_project_statistics_spec.rb b/spec/features/admin/admin_sees_project_statistics_spec.rb
index ecd0aab925b..6e8211a9b4e 100644
--- a/spec/features/admin/admin_sees_project_statistics_spec.rb
+++ b/spec/features/admin/admin_sees_project_statistics_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Admin > Admin sees project statistics" do
+RSpec.describe "Admin > Admin sees project statistics" do
let(:current_user) { create(:admin) }
before do
diff --git a/spec/features/admin/admin_sees_projects_statistics_spec.rb b/spec/features/admin/admin_sees_projects_statistics_spec.rb
index 6a6f369ac7c..786fa98255c 100644
--- a/spec/features/admin/admin_sees_projects_statistics_spec.rb
+++ b/spec/features/admin/admin_sees_projects_statistics_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Admin > Admin sees projects statistics" do
+RSpec.describe "Admin > Admin sees projects statistics" do
let(:current_user) { create(:admin) }
before do
diff --git a/spec/features/admin/admin_serverless_domains_spec.rb b/spec/features/admin/admin_serverless_domains_spec.rb
index 48f6af8d4bd..256887f425f 100644
--- a/spec/features/admin/admin_serverless_domains_spec.rb
+++ b/spec/features/admin/admin_serverless_domains_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin Serverless Domains', :js do
+RSpec.describe 'Admin Serverless Domains', :js do
let(:sample_domain) { build(:pages_domain) }
before do
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index 7ec3c2abb51..55f6a9930ff 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -2,9 +2,10 @@
require 'spec_helper'
-describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_not_mock_admin_mode do
+RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_not_mock_admin_mode do
include StubENV
include TermsHelper
+ include UsageDataHelpers
let(:admin) { create(:admin) }
@@ -104,6 +105,16 @@ describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_not_moc
expect(page).to have_content "Application settings saved successfully"
end
+ it 'Change Maximum import size' do
+ page.within('.as-account-limit') do
+ fill_in 'Maximum import size (MB)', with: 15
+ click_button 'Save changes'
+ end
+
+ expect(current_settings.max_import_size).to eq 15
+ expect(page).to have_content "Application settings saved successfully"
+ end
+
it 'Change New users set to external', :js do
user_internal_regex = find('#application_setting_user_default_internal_regex', visible: :all)
@@ -277,16 +288,31 @@ describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_not_moc
end
end
+ context 'Repository page' do
+ it 'Change Repository storage settings' do
+ visit repository_admin_application_settings_path
+
+ page.within('.as-repository-storage') do
+ fill_in 'application_setting_repository_storages_weighted_default', with: 50
+ click_button 'Save changes'
+ end
+
+ expect(current_settings.repository_storages_weighted_default).to be 50
+ end
+ end
+
context 'Reporting page' do
it 'Change Spam settings' do
visit reporting_admin_application_settings_path
page.within('.as-spam') do
- check 'Enable reCAPTCHA'
- check 'Enable reCAPTCHA for login'
fill_in 'reCAPTCHA Site Key', with: 'key'
fill_in 'reCAPTCHA Private Key', with: 'key'
+ check 'Enable reCAPTCHA'
+ check 'Enable reCAPTCHA for login'
fill_in 'IPs per user', with: 15
+ check 'Enable Spam Check via external API endpoint'
+ fill_in 'URL of the external Spam Check endpoint', with: 'https://www.example.com/spamcheck'
click_button 'Save changes'
end
@@ -294,6 +320,8 @@ describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_not_moc
expect(current_settings.recaptcha_enabled).to be true
expect(current_settings.login_recaptcha_protection_enabled).to be true
expect(current_settings.unique_ips_limit_per_user).to eq(15)
+ expect(current_settings.spam_check_endpoint_enabled).to be true
+ expect(current_settings.spam_check_endpoint_url).to eq 'https://www.example.com/spamcheck'
end
end
@@ -336,7 +364,7 @@ describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_not_moc
end
it 'loads usage ping payload on click', :js do
- allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false)
+ stub_usage_data_connections
page.within('#js-usage-settings') do
expected_payload_content = /(?=.*"uuid")(?=.*"hostname")/m
@@ -377,7 +405,7 @@ describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_not_moc
visit network_admin_application_settings_path
page.within('.as-issue-limits') do
- fill_in 'Max requests per second per user', with: 0
+ fill_in 'Max requests per minute per user', with: 0
click_button 'Save changes'
end
diff --git a/spec/features/admin/admin_system_info_spec.rb b/spec/features/admin/admin_system_info_spec.rb
index 3dacf63e25a..6a0448fd890 100644
--- a/spec/features/admin/admin_system_info_spec.rb
+++ b/spec/features/admin/admin_system_info_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin System Info' do
+RSpec.describe 'Admin System Info' do
before do
sign_in(create(:admin))
end
diff --git a/spec/features/admin/admin_users_impersonation_tokens_spec.rb b/spec/features/admin/admin_users_impersonation_tokens_spec.rb
index b9de858e3b9..ec3dd322f97 100644
--- a/spec/features/admin/admin_users_impersonation_tokens_spec.rb
+++ b/spec/features/admin/admin_users_impersonation_tokens_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin > Users > Impersonation Tokens', :js do
+RSpec.describe 'Admin > Users > Impersonation Tokens', :js do
let(:admin) { create(:admin) }
let!(:user) { create(:user) }
diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb
index 0c8cd895c00..369f91c6faa 100644
--- a/spec/features/admin/admin_users_spec.rb
+++ b/spec/features/admin/admin_users_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Admin::Users" do
+RSpec.describe "Admin::Users" do
include Spec::Support::Helpers::Features::ResponsiveTableHelpers
let!(:user) do
diff --git a/spec/features/admin/admin_uses_repository_checks_spec.rb b/spec/features/admin/admin_uses_repository_checks_spec.rb
index 954773e766d..b8851c28531 100644
--- a/spec/features/admin/admin_uses_repository_checks_spec.rb
+++ b/spec/features/admin/admin_uses_repository_checks_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin uses repository checks', :request_store, :clean_gitlab_redis_shared_state, :do_not_mock_admin_mode do
+RSpec.describe 'Admin uses repository checks', :request_store, :clean_gitlab_redis_shared_state, :do_not_mock_admin_mode do
include StubENV
let(:admin) { create(:admin) }
diff --git a/spec/features/admin/clusters/applications_spec.rb b/spec/features/admin/clusters/applications_spec.rb
index 8310811b43d..3bcadfdbfc1 100644
--- a/spec/features/admin/clusters/applications_spec.rb
+++ b/spec/features/admin/clusters/applications_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require_relative '../../../../spec/features/clusters/installing_applications_shared_examples'
-describe 'Instance-level Cluster Applications', :js do
+RSpec.describe 'Instance-level Cluster Applications', :js do
include GoogleApi::CloudPlatformHelpers
let(:user) { create(:admin) }
diff --git a/spec/features/admin/clusters/eks_spec.rb b/spec/features/admin/clusters/eks_spec.rb
index 40561aa508c..ef49aebc7c5 100644
--- a/spec/features/admin/clusters/eks_spec.rb
+++ b/spec/features/admin/clusters/eks_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Instance-level AWS EKS Cluster', :js do
+RSpec.describe 'Instance-level AWS EKS Cluster', :js do
let(:user) { create(:admin) }
before do
diff --git a/spec/features/admin/dashboard_spec.rb b/spec/features/admin/dashboard_spec.rb
index 018ef13cbb6..4ffa5e3be0b 100644
--- a/spec/features/admin/dashboard_spec.rb
+++ b/spec/features/admin/dashboard_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'admin visits dashboard' do
+RSpec.describe 'admin visits dashboard' do
include ProjectForksHelper
before do
diff --git a/spec/features/admin/services/admin_activates_prometheus_spec.rb b/spec/features/admin/services/admin_activates_prometheus_spec.rb
index 64c57cd425b..35af9dd6c68 100644
--- a/spec/features/admin/services/admin_activates_prometheus_spec.rb
+++ b/spec/features/admin/services/admin_activates_prometheus_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin activates Prometheus' do
+RSpec.describe 'Admin activates Prometheus', :js do
let(:admin) { create(:user, :admin) }
before do
diff --git a/spec/features/atom/dashboard_issues_spec.rb b/spec/features/atom/dashboard_issues_spec.rb
index d523e2992db..511cdcc2940 100644
--- a/spec/features/atom/dashboard_issues_spec.rb
+++ b/spec/features/atom/dashboard_issues_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Dashboard Issues Feed" do
+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') }
diff --git a/spec/features/atom/dashboard_spec.rb b/spec/features/atom/dashboard_spec.rb
index 7df0e47cd14..851ae7b02a0 100644
--- a/spec/features/atom/dashboard_spec.rb
+++ b/spec/features/atom/dashboard_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Dashboard Feed" do
+RSpec.describe "Dashboard Feed" do
describe "GET /" do
let!(:user) { create(:user, name: "Jonh") }
diff --git a/spec/features/atom/issues_spec.rb b/spec/features/atom/issues_spec.rb
index c0413f0f352..13798a94fe9 100644
--- a/spec/features/atom/issues_spec.rb
+++ b/spec/features/atom/issues_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Issues Feed' do
+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') }
diff --git a/spec/features/atom/users_spec.rb b/spec/features/atom/users_spec.rb
index 6f013e13ae4..c79b812df46 100644
--- a/spec/features/atom/users_spec.rb
+++ b/spec/features/atom/users_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "User Feed" do
+RSpec.describe "User Feed" do
describe "GET /" do
let!(:user) { create(:user) }
diff --git a/spec/features/boards/add_issues_modal_spec.rb b/spec/features/boards/add_issues_modal_spec.rb
index 0412dc2b69c..d432825e113 100644
--- a/spec/features/boards/add_issues_modal_spec.rb
+++ b/spec/features/boards/add_issues_modal_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Issue Boards add issue modal', :js do
+RSpec.describe 'Issue Boards add issue modal', :js do
let(:project) { create(:project, :public) }
let(:board) { create(:board, project: project) }
let(:user) { create(:user) }
diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb
index e82b1be4310..8e2a9381aa0 100644
--- a/spec/features/boards/boards_spec.rb
+++ b/spec/features/boards/boards_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Issue Boards', :js do
+RSpec.describe 'Issue Boards', :js do
include DragTo
include MobileHelpers
diff --git a/spec/features/boards/focus_mode_spec.rb b/spec/features/boards/focus_mode_spec.rb
index fff3cce3c1a..b1684ad69a6 100644
--- a/spec/features/boards/focus_mode_spec.rb
+++ b/spec/features/boards/focus_mode_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Issue Boards focus mode', :js do
+RSpec.describe 'Issue Boards focus mode', :js do
let(:project) { create(:project, :public) }
before do
diff --git a/spec/features/boards/issue_ordering_spec.rb b/spec/features/boards/issue_ordering_spec.rb
index 4c723ddf324..03a76d9d3fd 100644
--- a/spec/features/boards/issue_ordering_spec.rb
+++ b/spec/features/boards/issue_ordering_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Issue Boards', :js do
+RSpec.describe 'Issue Boards', :js do
include DragTo
let(:project) { create(:project, :public) }
diff --git a/spec/features/boards/keyboard_shortcut_spec.rb b/spec/features/boards/keyboard_shortcut_spec.rb
index 6074c559701..f51b4d21e3b 100644
--- a/spec/features/boards/keyboard_shortcut_spec.rb
+++ b/spec/features/boards/keyboard_shortcut_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Issue Boards shortcut', :js do
+RSpec.describe 'Issue Boards shortcut', :js do
context 'issues are enabled' do
let(:project) { create(:project) }
diff --git a/spec/features/boards/modal_filter_spec.rb b/spec/features/boards/modal_filter_spec.rb
index 31f4c502c61..5aeb9eb5e50 100644
--- a/spec/features/boards/modal_filter_spec.rb
+++ b/spec/features/boards/modal_filter_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Issue Boards add issue modal filtering', :js do
+RSpec.describe 'Issue Boards add issue modal filtering', :js do
let(:project) { create(:project, :public) }
let(:board) { create(:board, project: project) }
let(:planning) { create(:label, project: project, name: 'Planning') }
diff --git a/spec/features/boards/multi_select_spec.rb b/spec/features/boards/multi_select_spec.rb
index 885dc08e38d..162455f75e6 100644
--- a/spec/features/boards/multi_select_spec.rb
+++ b/spec/features/boards/multi_select_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Multi Select Issue', :js do
+RSpec.describe 'Multi Select Issue', :js do
include DragTo
let(:group) { create(:group, :nested) }
diff --git a/spec/features/boards/multiple_boards_spec.rb b/spec/features/boards/multiple_boards_spec.rb
index 8e56be6bdd0..2894d5c7666 100644
--- a/spec/features/boards/multiple_boards_spec.rb
+++ b/spec/features/boards/multiple_boards_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Multiple Issue Boards', :js do
+RSpec.describe 'Multiple Issue Boards', :js do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :public) }
let_it_be(:planning) { create(:label, project: project, name: 'Planning') }
diff --git a/spec/features/boards/new_issue_spec.rb b/spec/features/boards/new_issue_spec.rb
index 2d41b5d612d..efa1f8cfc0d 100644
--- a/spec/features/boards/new_issue_spec.rb
+++ b/spec/features/boards/new_issue_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Issue Boards new issue', :js do
+RSpec.describe 'Issue Boards new issue', :js do
let(:project) { create(:project, :public) }
let(:board) { create(:board, project: project) }
let!(:list) { create(:list, board: board, position: 0) }
diff --git a/spec/features/boards/reload_boards_on_browser_back_spec.rb b/spec/features/boards/reload_boards_on_browser_back_spec.rb
index 6528b8f58bb..181cbcc9811 100644
--- a/spec/features/boards/reload_boards_on_browser_back_spec.rb
+++ b/spec/features/boards/reload_boards_on_browser_back_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Ensure Boards do not show stale data on browser back', :js do
+RSpec.describe 'Ensure Boards do not show stale data on browser back', :js do
let(:project) {create(:project, :public)}
let(:board) {create(:board, project: project)}
let(:user) {create(:user)}
diff --git a/spec/features/boards/sidebar_spec.rb b/spec/features/boards/sidebar_spec.rb
index d05709b7e2f..65f2e5dfc0d 100644
--- a/spec/features/boards/sidebar_spec.rb
+++ b/spec/features/boards/sidebar_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Issue Boards', :js do
+RSpec.describe 'Issue Boards', :js do
include BoardHelpers
include FilteredSearchHelpers
diff --git a/spec/features/boards/sub_group_project_spec.rb b/spec/features/boards/sub_group_project_spec.rb
index 4384a1a9379..cd3d61726f6 100644
--- a/spec/features/boards/sub_group_project_spec.rb
+++ b/spec/features/boards/sub_group_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Sub-group project issue boards', :js do
+RSpec.describe 'Sub-group project issue boards', :js do
let(:group) { create(:group) }
let(:nested_group_1) { create(:group, parent: group) }
let(:project) { create(:project, group: nested_group_1) }
diff --git a/spec/features/broadcast_messages_spec.rb b/spec/features/broadcast_messages_spec.rb
index c770e6e4f81..f339d45671d 100644
--- a/spec/features/broadcast_messages_spec.rb
+++ b/spec/features/broadcast_messages_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Broadcast Messages' do
+RSpec.describe 'Broadcast Messages' do
let_it_be(:user) { create(:user) }
shared_examples 'a Broadcast Messages' do |type|
diff --git a/spec/features/calendar_spec.rb b/spec/features/calendar_spec.rb
index acdc38038aa..5b78d93ae04 100644
--- a/spec/features/calendar_spec.rb
+++ b/spec/features/calendar_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Contributions Calendar', :js do
+RSpec.describe 'Contributions Calendar', :js do
include MobileHelpers
let(:user) { create(:user) }
@@ -59,7 +59,7 @@ describe 'Contributions Calendar', :js do
def note_comment_contribution
note_comment_params = {
project: contributed_project,
- action: Event::COMMENTED,
+ action: :commented,
target: issue_note,
author_id: user.id
}
diff --git a/spec/features/clusters/cluster_detail_page_spec.rb b/spec/features/clusters/cluster_detail_page_spec.rb
index 4b478163952..6058c35c2cf 100644
--- a/spec/features/clusters/cluster_detail_page_spec.rb
+++ b/spec/features/clusters/cluster_detail_page_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Clusterable > Show page' do
+RSpec.describe 'Clusterable > Show page' do
include KubernetesHelpers
let(:current_user) { create(:user) }
diff --git a/spec/features/clusters/installing_applications_shared_examples.rb b/spec/features/clusters/installing_applications_shared_examples.rb
index 5b565c0a304..d2f28f5b219 100644
--- a/spec/features/clusters/installing_applications_shared_examples.rb
+++ b/spec/features/clusters/installing_applications_shared_examples.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-shared_examples "installing applications for a cluster" do |managed_apps_local_tiller|
+RSpec.shared_examples "installing applications for a cluster" do |managed_apps_local_tiller|
before do
stub_feature_flags(managed_apps_local_tiller: managed_apps_local_tiller)
@@ -279,7 +279,7 @@ shared_examples "installing applications for a cluster" do |managed_apps_local_t
end
end
-shared_examples "installing applications on a cluster" do
+RSpec.shared_examples "installing applications on a cluster" do
it_behaves_like "installing applications for a cluster", false
it_behaves_like "installing applications for a cluster", true
end
diff --git a/spec/features/commits/user_uses_quick_actions_spec.rb b/spec/features/commits/user_uses_quick_actions_spec.rb
index 70ea920b7ec..12e7865e490 100644
--- a/spec/features/commits/user_uses_quick_actions_spec.rb
+++ b/spec/features/commits/user_uses_quick_actions_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Commit > User uses quick actions', :js do
+RSpec.describe 'Commit > User uses quick actions', :js do
include Spec::Support::Helpers::Features::NotesHelpers
include RepoHelpers
diff --git a/spec/features/commits/user_view_commits_spec.rb b/spec/features/commits/user_view_commits_spec.rb
index 133baca8b1c..5907534220d 100644
--- a/spec/features/commits/user_view_commits_spec.rb
+++ b/spec/features/commits/user_view_commits_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Commit > User view commits' do
+RSpec.describe 'Commit > User view commits' do
let_it_be(:project) { create(:project, :public, :repository) }
let_it_be(:user) { project.creator }
diff --git a/spec/features/commits_spec.rb b/spec/features/commits_spec.rb
index d8b886b239f..60c37d1e125 100644
--- a/spec/features/commits_spec.rb
+++ b/spec/features/commits_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Commits' do
+RSpec.describe 'Commits' do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user) }
diff --git a/spec/features/contextual_sidebar_spec.rb b/spec/features/contextual_sidebar_spec.rb
index e250e8cc90a..8ea1ebac6b7 100644
--- a/spec/features/contextual_sidebar_spec.rb
+++ b/spec/features/contextual_sidebar_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Contextual sidebar', :js do
+RSpec.describe 'Contextual sidebar', :js do
let(:user) { create(:user) }
let(:project) { create(:project) }
diff --git a/spec/features/cycle_analytics_spec.rb b/spec/features/cycle_analytics_spec.rb
index 50d9cb1c833..0294ebbe13f 100644
--- a/spec/features/cycle_analytics_spec.rb
+++ b/spec/features/cycle_analytics_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Value Stream Analytics', :js do
+RSpec.describe 'Value Stream Analytics', :js do
let(:user) { create(:user) }
let(:guest) { create(:user) }
let(:project) { create(:project, :repository) }
diff --git a/spec/features/dashboard/activity_spec.rb b/spec/features/dashboard/activity_spec.rb
index 0a3b550c0c4..b419a063858 100644
--- a/spec/features/dashboard/activity_spec.rb
+++ b/spec/features/dashboard/activity_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Dashboard > Activity' do
+RSpec.describe 'Dashboard > Activity' do
let(:user) { create(:user) }
before do
diff --git a/spec/features/dashboard/datetime_on_tooltips_spec.rb b/spec/features/dashboard/datetime_on_tooltips_spec.rb
index 56b47b74626..ed28ec6099d 100644
--- a/spec/features/dashboard/datetime_on_tooltips_spec.rb
+++ b/spec/features/dashboard/datetime_on_tooltips_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Tooltips on .timeago dates', :js do
+RSpec.describe 'Tooltips on .timeago dates', :js do
let(:user) { create(:user) }
let(:project) { create(:project, name: 'test', namespace: user.namespace) }
let(:created_date) { Date.yesterday.to_time }
@@ -12,7 +12,7 @@ describe 'Tooltips on .timeago dates', :js do
before do
project.add_maintainer(user)
- Event.create( project: project, author_id: user.id, action: Event::JOINED,
+ Event.create( project: project, author_id: user.id, action: :joined,
updated_at: created_date, created_at: created_date)
sign_in user
diff --git a/spec/features/dashboard/group_dashboard_with_external_authorization_service_spec.rb b/spec/features/dashboard/group_dashboard_with_external_authorization_service_spec.rb
index aebc2eb1916..c2a3b90b6f4 100644
--- a/spec/features/dashboard/group_dashboard_with_external_authorization_service_spec.rb
+++ b/spec/features/dashboard/group_dashboard_with_external_authorization_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'The group dashboard' do
+RSpec.describe 'The group dashboard' do
include ExternalAuthorizationServiceHelpers
let(:user) { create(:user) }
diff --git a/spec/features/dashboard/groups_list_spec.rb b/spec/features/dashboard/groups_list_spec.rb
index 5b336f994f7..8c941b27cd2 100644
--- a/spec/features/dashboard/groups_list_spec.rb
+++ b/spec/features/dashboard/groups_list_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Dashboard Groups page', :js do
+RSpec.describe 'Dashboard Groups page', :js do
let(:user) { create :user }
let(:group) { create(:group) }
let(:nested_group) { create(:group, :nested) }
diff --git a/spec/features/dashboard/instance_statistics_spec.rb b/spec/features/dashboard/instance_statistics_spec.rb
index feb568d8ef4..f85b8454113 100644
--- a/spec/features/dashboard/instance_statistics_spec.rb
+++ b/spec/features/dashboard/instance_statistics_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Showing analytics' do
+RSpec.describe 'Showing analytics' do
before do
sign_in user if user
end
diff --git a/spec/features/dashboard/issuables_counter_spec.rb b/spec/features/dashboard/issuables_counter_spec.rb
index eca78749171..7526a55a3c1 100644
--- a/spec/features/dashboard/issuables_counter_spec.rb
+++ b/spec/features/dashboard/issuables_counter_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Navigation bar counter', :use_clean_rails_memory_store_caching do
+RSpec.describe 'Navigation bar counter', :use_clean_rails_memory_store_caching do
let(:user) { create(:user) }
let(:project) { create(:project, namespace: user.namespace) }
let(:issue) { create(:issue, project: project) }
diff --git a/spec/features/dashboard/issues_filter_spec.rb b/spec/features/dashboard/issues_filter_spec.rb
index 8e2a3d983b1..4bd00bd0a80 100644
--- a/spec/features/dashboard/issues_filter_spec.rb
+++ b/spec/features/dashboard/issues_filter_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Dashboard Issues filtering', :js do
+RSpec.describe 'Dashboard Issues filtering', :js do
include Spec::Support::Helpers::Features::SortingHelpers
include FilteredSearchHelpers
diff --git a/spec/features/dashboard/label_filter_spec.rb b/spec/features/dashboard/label_filter_spec.rb
index 630b2b636b4..ebe5c3e1091 100644
--- a/spec/features/dashboard/label_filter_spec.rb
+++ b/spec/features/dashboard/label_filter_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Dashboard > label filter', :js do
+RSpec.describe 'Dashboard > label filter', :js do
include FilteredSearchHelpers
let(:filtered_search) { find('.filtered-search') }
diff --git a/spec/features/dashboard/merge_requests_spec.rb b/spec/features/dashboard/merge_requests_spec.rb
index 0c728ab22de..5331b5559d8 100644
--- a/spec/features/dashboard/merge_requests_spec.rb
+++ b/spec/features/dashboard/merge_requests_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Dashboard Merge Requests' do
+RSpec.describe 'Dashboard Merge Requests' do
include Spec::Support::Helpers::Features::SortingHelpers
include FilteredSearchHelpers
include ProjectForksHelper
diff --git a/spec/features/dashboard/milestone_tabs_spec.rb b/spec/features/dashboard/milestone_tabs_spec.rb
deleted file mode 100644
index a83e4c1f7c9..00000000000
--- a/spec/features/dashboard/milestone_tabs_spec.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe 'Dashboard milestone tabs', :js do
- let(:user) { create(:user) }
- let(:project) { create(:project) }
- let!(:label) { create(:label, project: project) }
- let(:project_milestone) { create(:milestone, project: project) }
- let(:milestone) do
- DashboardMilestone.build(
- [project],
- project_milestone.title
- )
- end
- let!(:merge_request) { create(:labeled_merge_request, source_project: project, target_project: project, milestone: project_milestone, labels: [label]) }
-
- before do
- project.add_maintainer(user)
- sign_in(user)
-
- visit dashboard_milestone_path(milestone.safe_title, title: milestone.title)
- end
-
- it 'loads merge requests async' do
- click_link 'Merge Requests'
-
- expect(page).to have_selector('.milestone-merge_requests-list')
- end
-
- it 'loads participants async' do
- click_link 'Participants'
-
- expect(page).to have_selector('#tab-participants .bordered-list')
- end
-
- it 'loads labels async' do
- click_link 'Labels'
-
- expect(page).to have_selector('#tab-labels .bordered-list')
- end
-end
diff --git a/spec/features/dashboard/milestones_spec.rb b/spec/features/dashboard/milestones_spec.rb
index 4ad19710d90..308432b7a1b 100644
--- a/spec/features/dashboard/milestones_spec.rb
+++ b/spec/features/dashboard/milestones_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Dashboard > Milestones' do
+RSpec.describe 'Dashboard > Milestones' do
describe 'as anonymous user' do
before do
visit dashboard_milestones_path
diff --git a/spec/features/dashboard/project_member_activity_index_spec.rb b/spec/features/dashboard/project_member_activity_index_spec.rb
index 8e7a0b2a611..6e6e466294f 100644
--- a/spec/features/dashboard/project_member_activity_index_spec.rb
+++ b/spec/features/dashboard/project_member_activity_index_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project member activity', :js do
+RSpec.describe 'Project member activity', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :public, name: 'x', namespace: user.namespace) }
@@ -18,7 +18,7 @@ describe 'Project member activity', :js do
context 'when a user joins the project' do
before do
- visit_activities_and_wait_with_event(Event::JOINED)
+ visit_activities_and_wait_with_event(:joined)
end
it "presents the correct message" do
@@ -29,7 +29,7 @@ describe 'Project member activity', :js do
context 'when a user leaves the project' do
before do
- visit_activities_and_wait_with_event(Event::LEFT)
+ visit_activities_and_wait_with_event(:left)
end
it "presents the correct message" do
@@ -40,7 +40,7 @@ describe 'Project member activity', :js do
context 'when a users membership expires for the project' do
before do
- visit_activities_and_wait_with_event(Event::EXPIRED)
+ visit_activities_and_wait_with_event(:expired)
end
it "presents the correct message" do
diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb
index 218cbf871a9..e1beaf923e8 100644
--- a/spec/features/dashboard/projects_spec.rb
+++ b/spec/features/dashboard/projects_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Dashboard Projects' do
+RSpec.describe 'Dashboard Projects' do
let(:user) { create(:user) }
let(:project) { create(:project, :repository, name: 'awesome stuff') }
let(:project2) { create(:project, :public, name: 'Community project') }
@@ -125,7 +125,7 @@ describe 'Dashboard Projects' do
end
context 'when on Starred projects tab', :js do
- it 'shows the empty state when there are no starred projects' do
+ it 'shows the empty state when there are no starred projects', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/222357' do
visit(starred_dashboard_projects_path)
element = page.find('.row.empty-state')
diff --git a/spec/features/dashboard/root_explore_spec.rb b/spec/features/dashboard/root_explore_spec.rb
index 0e065dbed67..a3c346ffe2a 100644
--- a/spec/features/dashboard/root_explore_spec.rb
+++ b/spec/features/dashboard/root_explore_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Root explore' do
+RSpec.describe 'Root explore' do
let_it_be(:public_project) { create(:project, :public) }
let_it_be(:archived_project) { create(:project, :archived) }
let_it_be(:internal_project) { create(:project, :internal) }
diff --git a/spec/features/dashboard/shortcuts_spec.rb b/spec/features/dashboard/shortcuts_spec.rb
index 6907c681417..04bbc3059de 100644
--- a/spec/features/dashboard/shortcuts_spec.rb
+++ b/spec/features/dashboard/shortcuts_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Dashboard shortcuts', :js do
+RSpec.describe 'Dashboard shortcuts', :js do
context 'logged in' do
let(:user) { create(:user) }
let(:project) { create(:project) }
diff --git a/spec/features/dashboard/snippets_spec.rb b/spec/features/dashboard/snippets_spec.rb
index 94aef03e093..224f2111014 100644
--- a/spec/features/dashboard/snippets_spec.rb
+++ b/spec/features/dashboard/snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Dashboard snippets' do
+RSpec.describe 'Dashboard snippets' do
let_it_be(:user) { create(:user) }
context 'when the project has snippets' do
diff --git a/spec/features/dashboard/todos/target_state_spec.rb b/spec/features/dashboard/todos/target_state_spec.rb
index 0ea1f43e34b..4c43948201c 100644
--- a/spec/features/dashboard/todos/target_state_spec.rb
+++ b/spec/features/dashboard/todos/target_state_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Dashboard > Todo target states' do
+RSpec.describe 'Dashboard > Todo target states' do
let(:user) { create(:user) }
let(:author) { create(:user) }
let(:project) { create(:project, :public) }
diff --git a/spec/features/dashboard/todos/todos_filtering_spec.rb b/spec/features/dashboard/todos/todos_filtering_spec.rb
index efa163042f9..f60b07c976e 100644
--- a/spec/features/dashboard/todos/todos_filtering_spec.rb
+++ b/spec/features/dashboard/todos/todos_filtering_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Dashboard > User filters todos', :js do
+RSpec.describe 'Dashboard > User filters todos', :js do
let(:user_1) { create(:user, username: 'user_1', name: 'user_1') }
let(:user_2) { create(:user, username: 'user_2', name: 'user_2') }
diff --git a/spec/features/dashboard/todos/todos_sorting_spec.rb b/spec/features/dashboard/todos/todos_sorting_spec.rb
index 421a66c6d48..d0f9a2b35f3 100644
--- a/spec/features/dashboard/todos/todos_sorting_spec.rb
+++ b/spec/features/dashboard/todos/todos_sorting_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Dashboard > User sorts todos' do
+RSpec.describe 'Dashboard > User sorts todos' do
let(:user) { create(:user) }
let(:project) { create(:project) }
diff --git a/spec/features/dashboard/todos/todos_spec.rb b/spec/features/dashboard/todos/todos_spec.rb
index 63867d5796a..cf773d2caed 100644
--- a/spec/features/dashboard/todos/todos_spec.rb
+++ b/spec/features/dashboard/todos/todos_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Dashboard Todos' do
+RSpec.describe 'Dashboard Todos' do
let_it_be(:user) { create(:user, username: 'john') }
let_it_be(:author) { create(:user) }
let_it_be(:project) { create(:project, :public) }
@@ -114,7 +114,7 @@ describe 'Dashboard Todos' do
context 'todo is stale on the page' do
before do
todos = TodosFinder.new(user, state: :pending).execute
- TodoService.new.mark_todos_as_done(todos, user)
+ TodoService.new.resolve_todos(todos, user)
end
it_behaves_like 'deleting the todo'
diff --git a/spec/features/dashboard/user_filters_projects_spec.rb b/spec/features/dashboard/user_filters_projects_spec.rb
index c4e4eb8affe..832f50932f4 100644
--- a/spec/features/dashboard/user_filters_projects_spec.rb
+++ b/spec/features/dashboard/user_filters_projects_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Dashboard > User filters projects' do
+RSpec.describe 'Dashboard > User filters projects' do
let(:user) { create(:user) }
let(:project) { create(:project, name: 'Victorialand', namespace: user.namespace, created_at: 2.seconds.ago, updated_at: 2.seconds.ago) }
let(:user2) { create(:user) }
diff --git a/spec/features/discussion_comments/commit_spec.rb b/spec/features/discussion_comments/commit_spec.rb
index f594a30165b..5a744e43bb6 100644
--- a/spec/features/discussion_comments/commit_spec.rb
+++ b/spec/features/discussion_comments/commit_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Thread Comments Commit', :js do
+RSpec.describe 'Thread Comments Commit', :js do
include RepoHelpers
let(:user) { create(:user) }
diff --git a/spec/features/discussion_comments/issue_spec.rb b/spec/features/discussion_comments/issue_spec.rb
index fbceb2a51ae..2ad77a2884c 100644
--- a/spec/features/discussion_comments/issue_spec.rb
+++ b/spec/features/discussion_comments/issue_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Thread Comments Issue', :js do
+RSpec.describe 'Thread Comments Issue', :js do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
diff --git a/spec/features/discussion_comments/merge_request_spec.rb b/spec/features/discussion_comments/merge_request_spec.rb
index c5457522c8e..43801b30608 100644
--- a/spec/features/discussion_comments/merge_request_spec.rb
+++ b/spec/features/discussion_comments/merge_request_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Thread Comments Merge Request', :js do
+RSpec.describe 'Thread Comments Merge Request', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:merge_request) { create(:merge_request, source_project: project) }
diff --git a/spec/features/discussion_comments/snippets_spec.rb b/spec/features/discussion_comments/snippets_spec.rb
index bf78a5261c5..50201bbdb21 100644
--- a/spec/features/discussion_comments/snippets_spec.rb
+++ b/spec/features/discussion_comments/snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Thread Comments Snippet', :js do
+RSpec.describe 'Thread Comments Snippet', :js do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:snippet) { create(:project_snippet, :private, :repository, project: project, author: user) }
diff --git a/spec/features/display_system_header_and_footer_bar_spec.rb b/spec/features/display_system_header_and_footer_bar_spec.rb
index e32da1a02bc..0979371a574 100644
--- a/spec/features/display_system_header_and_footer_bar_spec.rb
+++ b/spec/features/display_system_header_and_footer_bar_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Display system header and footer bar' do
+RSpec.describe 'Display system header and footer bar' do
let(:header_message) { "Foo" }
let(:footer_message) { "Bar" }
diff --git a/spec/features/error_pages_spec.rb b/spec/features/error_pages_spec.rb
index 562277388bb..77f8aa87237 100644
--- a/spec/features/error_pages_spec.rb
+++ b/spec/features/error_pages_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Error Pages' do
+RSpec.describe 'Error Pages' do
let(:user) { create(:user) }
let(:project) { create(:project, :public) }
diff --git a/spec/features/error_tracking/user_filters_errors_by_status_spec.rb b/spec/features/error_tracking/user_filters_errors_by_status_spec.rb
index 4b5bc16c4db..a0d93b791d9 100644
--- a/spec/features/error_tracking/user_filters_errors_by_status_spec.rb
+++ b/spec/features/error_tracking/user_filters_errors_by_status_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'When a user filters Sentry errors by status', :js, :use_clean_rails_memory_store_caching, :sidekiq_inline do
+RSpec.describe 'When a user filters Sentry errors by status', :js, :use_clean_rails_memory_store_caching, :sidekiq_inline do
include_context 'sentry error tracking context feature'
let_it_be(:issues_response_body) { fixture_file('sentry/issues_sample_response.json') }
diff --git a/spec/features/error_tracking/user_searches_sentry_errors_spec.rb b/spec/features/error_tracking/user_searches_sentry_errors_spec.rb
index c5559081feb..025a6261957 100644
--- a/spec/features/error_tracking/user_searches_sentry_errors_spec.rb
+++ b/spec/features/error_tracking/user_searches_sentry_errors_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'When a user searches for Sentry errors', :js, :use_clean_rails_memory_store_caching, :sidekiq_inline do
+RSpec.describe 'When a user searches for Sentry errors', :js, :use_clean_rails_memory_store_caching, :sidekiq_inline do
include_context 'sentry error tracking context feature'
let_it_be(:issues_response_body) { fixture_file('sentry/issues_sample_response.json') }
diff --git a/spec/features/error_tracking/user_sees_error_details_spec.rb b/spec/features/error_tracking/user_sees_error_details_spec.rb
index 6f72c44c689..e4a09d04ca1 100644
--- a/spec/features/error_tracking/user_sees_error_details_spec.rb
+++ b/spec/features/error_tracking/user_sees_error_details_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'View error details page', :js, :use_clean_rails_memory_store_caching, :sidekiq_inline do
+RSpec.describe 'View error details page', :js, :use_clean_rails_memory_store_caching, :sidekiq_inline do
include_context 'sentry error tracking context feature'
context 'with current user as project owner' do
diff --git a/spec/features/error_tracking/user_sees_error_index_spec.rb b/spec/features/error_tracking/user_sees_error_index_spec.rb
index 34a3a4b5a49..a4b15432ef3 100644
--- a/spec/features/error_tracking/user_sees_error_index_spec.rb
+++ b/spec/features/error_tracking/user_sees_error_index_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'View error index page', :js, :use_clean_rails_memory_store_caching, :sidekiq_inline do
+RSpec.describe 'View error index page', :js, :use_clean_rails_memory_store_caching, :sidekiq_inline do
include_context 'sentry error tracking context feature'
let_it_be(:issues_response_body) { fixture_file('sentry/issues_sample_response.json') }
diff --git a/spec/features/expand_collapse_diffs_spec.rb b/spec/features/expand_collapse_diffs_spec.rb
index 4bd2a305dfa..6b8df8467e5 100644
--- a/spec/features/expand_collapse_diffs_spec.rb
+++ b/spec/features/expand_collapse_diffs_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Expand and collapse diffs', :js do
+RSpec.describe 'Expand and collapse diffs', :js do
let(:branch) { 'expand-collapse-diffs' }
let(:project) { create(:project, :repository) }
diff --git a/spec/features/explore/groups_list_spec.rb b/spec/features/explore/groups_list_spec.rb
index c14144ab3d5..ba09cc20154 100644
--- a/spec/features/explore/groups_list_spec.rb
+++ b/spec/features/explore/groups_list_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Explore Groups page', :js do
+RSpec.describe 'Explore Groups page', :js do
let!(:user) { create :user }
let!(:group) { create(:group) }
let!(:public_group) { create(:group, :public) }
diff --git a/spec/features/explore/groups_spec.rb b/spec/features/explore/groups_spec.rb
index aee0a7c5573..6e9749f29c3 100644
--- a/spec/features/explore/groups_spec.rb
+++ b/spec/features/explore/groups_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Explore Groups', :js do
+RSpec.describe 'Explore Groups', :js do
let(:user) { create :user }
let(:group) { create :group }
let!(:private_project) do
diff --git a/spec/features/explore/user_explores_projects_spec.rb b/spec/features/explore/user_explores_projects_spec.rb
index 6adf51a1cf6..e217638f62b 100644
--- a/spec/features/explore/user_explores_projects_spec.rb
+++ b/spec/features/explore/user_explores_projects_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User explores projects' do
+RSpec.describe 'User explores projects' do
let_it_be(:archived_project) { create(:project, :archived) }
let_it_be(:internal_project) { create(:project, :internal) }
let_it_be(:private_project) { create(:project, :private) }
diff --git a/spec/features/global_search_spec.rb b/spec/features/global_search_spec.rb
index a7c8c29517e..c878ee7329f 100644
--- a/spec/features/global_search_spec.rb
+++ b/spec/features/global_search_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Global search' do
+RSpec.describe 'Global search' do
let(:user) { create(:user) }
let(:project) { create(:project, namespace: user.namespace) }
@@ -14,7 +14,8 @@ describe 'Global search' do
end
it 'increases usage ping searches counter' do
- expect(Gitlab::UsageDataCounters::SearchCounter).to receive(:increment_navbar_searches_count)
+ expect(Gitlab::UsageDataCounters::SearchCounter).to receive(:count).with(:navbar_searches)
+ expect(Gitlab::UsageDataCounters::SearchCounter).to receive(:count).with(:all_searches)
submit_search('foobar')
end
diff --git a/spec/features/graphiql_spec.rb b/spec/features/graphiql_spec.rb
index 329758113ab..91f53b4bb7c 100644
--- a/spec/features/graphiql_spec.rb
+++ b/spec/features/graphiql_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'GraphiQL' do
+RSpec.describe 'GraphiQL' do
context 'without relative_url_root' do
before do
visit '/-/graphql-explorer'
diff --git a/spec/features/group_variables_spec.rb b/spec/features/group_variables_spec.rb
index 524ae837b5e..9a3dca61680 100644
--- a/spec/features/group_variables_spec.rb
+++ b/spec/features/group_variables_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Group variables', :js do
+RSpec.describe 'Group variables', :js do
let(:user) { create(:user) }
let(:group) { create(:group) }
let!(:variable) { create(:ci_group_variable, key: 'test_key', value: 'test_value', masked: true, group: group) }
diff --git a/spec/features/groups/activity_spec.rb b/spec/features/groups/activity_spec.rb
index c102e19d477..6ca69e76d33 100644
--- a/spec/features/groups/activity_spec.rb
+++ b/spec/features/groups/activity_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Group activity page' do
+RSpec.describe 'Group activity page' do
let(:user) { create(:group_member, :developer, user: create(:user), group: group ).user }
let(:group) { create(:group) }
let(:path) { activity_group_path(group) }
diff --git a/spec/features/groups/board_sidebar_spec.rb b/spec/features/groups/board_sidebar_spec.rb
index ed874141ef4..3bbeed10948 100644
--- a/spec/features/groups/board_sidebar_spec.rb
+++ b/spec/features/groups/board_sidebar_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Group Issue Boards', :js do
+RSpec.describe 'Group Issue Boards', :js do
include BoardHelpers
let(:group) { create(:group) }
diff --git a/spec/features/groups/board_spec.rb b/spec/features/groups/board_spec.rb
index f95e2e91cd7..29d0347086c 100644
--- a/spec/features/groups/board_spec.rb
+++ b/spec/features/groups/board_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Group Boards' do
+RSpec.describe 'Group Boards' do
let(:group) { create(:group) }
let!(:project) { create(:project_empty_repo, group: group) }
let(:user) { create(:group_member, :maintainer, user: create(:user), group: group ).user }
diff --git a/spec/features/groups/clusters/applications_spec.rb b/spec/features/groups/clusters/applications_spec.rb
index 5d48df234eb..324ef24efc4 100644
--- a/spec/features/groups/clusters/applications_spec.rb
+++ b/spec/features/groups/clusters/applications_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require_relative '../../../../spec/features/clusters/installing_applications_shared_examples'
-describe 'Group-level Cluster Applications', :js do
+RSpec.describe 'Group-level Cluster Applications', :js do
include GoogleApi::CloudPlatformHelpers
let(:group) { create(:group) }
diff --git a/spec/features/groups/clusters/eks_spec.rb b/spec/features/groups/clusters/eks_spec.rb
index a9267d58739..5a62741250a 100644
--- a/spec/features/groups/clusters/eks_spec.rb
+++ b/spec/features/groups/clusters/eks_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Group AWS EKS Cluster', :js do
+RSpec.describe 'Group AWS EKS Cluster', :js do
let(:group) { create(:group) }
let(:user) { create(:user) }
diff --git a/spec/features/groups/clusters/user_spec.rb b/spec/features/groups/clusters/user_spec.rb
index a29afba99e4..c6e5da92160 100644
--- a/spec/features/groups/clusters/user_spec.rb
+++ b/spec/features/groups/clusters/user_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User Cluster', :js do
+RSpec.describe 'User Cluster', :js do
include GoogleApi::CloudPlatformHelpers
let(:group) { create(:group) }
diff --git a/spec/features/groups/container_registry_spec.rb b/spec/features/groups/container_registry_spec.rb
index 7e3c1728f3c..87ef2131211 100644
--- a/spec/features/groups/container_registry_spec.rb
+++ b/spec/features/groups/container_registry_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Container Registry', :js do
+RSpec.describe 'Container Registry', :js do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:project) { create(:project, namespace: group) }
@@ -24,6 +24,13 @@ describe 'Container Registry', :js do
expect(page).to have_title _('Container Registry')
end
+ it 'sidebar menu is open' do
+ visit_container_registry
+
+ sidebar = find('.nav-sidebar')
+ expect(sidebar).to have_link _('Container Registry')
+ end
+
context 'when there are no image repositories' do
it 'list page has no container title' do
visit_container_registry
@@ -75,7 +82,7 @@ describe 'Container Registry', :js do
expect(service).to receive(:execute).with(container_repository) { { status: :success } }
expect(Projects::ContainerRepository::DeleteTagsService).to receive(:new).with(container_repository.project, user, tags: ['latest']) { service }
- click_on(class: 'js-delete-registry')
+ first('[data-testid="singleDeleteButton"]').click
expect(find('.modal .modal-title')).to have_content _('Remove tag')
find('.modal .modal-footer .btn-danger').click
end
diff --git a/spec/features/groups/empty_states_spec.rb b/spec/features/groups/empty_states_spec.rb
index bbc80b7eec4..d76cf993004 100644
--- a/spec/features/groups/empty_states_spec.rb
+++ b/spec/features/groups/empty_states_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Group empty states' do
+RSpec.describe 'Group empty states' do
let(:group) { create(:group) }
let(:user) { create(:group_member, :developer, user: create(:user), group: group ).user }
diff --git a/spec/features/groups/group_page_with_external_authorization_service_spec.rb b/spec/features/groups/group_page_with_external_authorization_service_spec.rb
index a71b930d35f..8ef1b60d8ca 100644
--- a/spec/features/groups/group_page_with_external_authorization_service_spec.rb
+++ b/spec/features/groups/group_page_with_external_authorization_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'The group page' do
+RSpec.describe 'The group page' do
include ExternalAuthorizationServiceHelpers
let(:user) { create(:user) }
diff --git a/spec/features/groups/group_settings_spec.rb b/spec/features/groups/group_settings_spec.rb
index d686e0ed9d2..8972be45acb 100644
--- a/spec/features/groups/group_settings_spec.rb
+++ b/spec/features/groups/group_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Edit group settings' do
+RSpec.describe 'Edit group settings' do
let(:user) { create(:user) }
let(:group) { create(:group, path: 'foo') }
diff --git a/spec/features/groups/import_export/export_file_spec.rb b/spec/features/groups/import_export/export_file_spec.rb
index 5829e659722..9feb8085e66 100644
--- a/spec/features/groups/import_export/export_file_spec.rb
+++ b/spec/features/groups/import_export/export_file_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Group Export', :js do
+RSpec.describe 'Group Export', :js do
include ExportFileHelper
let_it_be(:user) { create(:user) }
diff --git a/spec/features/groups/import_export/import_file_spec.rb b/spec/features/groups/import_export/import_file_spec.rb
new file mode 100644
index 00000000000..577198ef3f1
--- /dev/null
+++ b/spec/features/groups/import_export/import_file_spec.rb
@@ -0,0 +1,104 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'Import/Export - Group Import', :js do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:import_path) { "#{Dir.tmpdir}/group_import_spec" }
+
+ before do
+ allow_next_instance_of(Gitlab::ImportExport) do |import_export|
+ allow(import_export).to receive(:storage_path).and_return(import_path)
+ end
+
+ stub_uploads_object_storage(FileUploader)
+
+ gitlab_sign_in(user)
+ end
+
+ after do
+ FileUtils.rm_rf(import_path, secure: true)
+ end
+
+ context 'when the user uploads a valid export file' do
+ let(:file) { File.join(Rails.root, 'spec', %w[fixtures group_export.tar.gz]) }
+
+ context 'when using the pre-filled path', :sidekiq_inline do
+ it 'successfully imports the group' do
+ group_name = 'Test Group Import'
+
+ visit new_group_path
+
+ fill_in :group_name, with: group_name
+ find('#import-group-tab').click
+
+ expect(page).to have_content 'GitLab group export'
+ attach_file(file) do
+ find('.js-filepicker-button').click
+ end
+
+ expect { click_on 'Import group' }.to change { Group.count }.by 1
+
+ group = Group.find_by(name: group_name)
+
+ expect(group).not_to be_nil
+ expect(group.description).to eq 'A voluptate non sequi temporibus quam at.'
+ expect(group.path).to eq 'test-group-import'
+ expect(group.import_state.status).to eq GroupImportState.state_machine.states[:finished].value
+ end
+ end
+
+ context 'when modifying the pre-filled path' do
+ it 'successfully imports the group' do
+ visit new_group_path
+
+ fill_in :group_name, with: 'Test Group Import'
+ find('#import-group-tab').click
+
+ fill_in :import_group_path, with: 'custom-path'
+ attach_file(file) do
+ find('.js-filepicker-button').click
+ end
+
+ expect { click_on 'Import group' }.to change { Group.count }.by 1
+
+ group = Group.find_by(name: 'Test Group Import')
+ expect(group.path).to eq 'custom-path'
+ end
+ end
+
+ context 'when the path is already taken' do
+ before do
+ create(:group, path: 'test-group-import')
+ end
+
+ it 'suggests a unique path' do
+ visit new_group_path
+ find('#import-group-tab').click
+
+ fill_in :import_group_path, with: 'test-group-import'
+ expect(page).to have_content 'Group path is already taken. Suggestions: test-group-import1'
+ end
+ end
+ end
+
+ context 'when the user uploads an invalid export file' do
+ let(:file) { File.join(Rails.root, 'spec', %w[fixtures big-image.png]) }
+
+ it 'displays an error' do
+ visit new_group_path
+
+ fill_in :group_name, with: 'Test Group Import'
+ find('#import-group-tab').click
+ attach_file(file) do
+ find('.js-filepicker-button').click
+ end
+
+ expect { click_on 'Import group' }.not_to change { Group.count }
+
+ page.within('.flash-container') do
+ expect(page).to have_content('Unable to process group import file')
+ end
+ end
+ end
+end
diff --git a/spec/features/groups/issues_spec.rb b/spec/features/groups/issues_spec.rb
index 1cefcd18989..c76e0c311a6 100644
--- a/spec/features/groups/issues_spec.rb
+++ b/spec/features/groups/issues_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Group issues page' do
+RSpec.describe 'Group issues page' do
include FilteredSearchHelpers
include DragTo
diff --git a/spec/features/groups/labels/create_spec.rb b/spec/features/groups/labels/create_spec.rb
index f5062a65321..9c1a3672ebd 100644
--- a/spec/features/groups/labels/create_spec.rb
+++ b/spec/features/groups/labels/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Create a group label' do
+RSpec.describe 'Create a group label' do
let(:user) { create(:user) }
let(:group) { create(:group) }
diff --git a/spec/features/groups/labels/edit_spec.rb b/spec/features/groups/labels/edit_spec.rb
index 43f067b89d6..2be7f61eeb9 100644
--- a/spec/features/groups/labels/edit_spec.rb
+++ b/spec/features/groups/labels/edit_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Edit group label' do
+RSpec.describe 'Edit group label' do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:label) { create(:group_label, group: group) }
diff --git a/spec/features/groups/labels/index_spec.rb b/spec/features/groups/labels/index_spec.rb
index 62308d3b518..3de29231f5c 100644
--- a/spec/features/groups/labels/index_spec.rb
+++ b/spec/features/groups/labels/index_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Group labels' do
+RSpec.describe 'Group labels' do
let(:user) { create(:user) }
let(:group) { create(:group) }
let!(:label) { create(:group_label, group: group) }
diff --git a/spec/features/groups/labels/search_labels_spec.rb b/spec/features/groups/labels/search_labels_spec.rb
index 14b88a561b1..fbb0acfb923 100644
--- a/spec/features/groups/labels/search_labels_spec.rb
+++ b/spec/features/groups/labels/search_labels_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Search for labels', :js do
+RSpec.describe 'Search for labels', :js do
let(:user) { create(:user) }
let(:group) { create(:group) }
let!(:label1) { create(:group_label, title: 'Foo', description: 'Lorem ipsum', group: group) }
diff --git a/spec/features/groups/labels/sort_labels_spec.rb b/spec/features/groups/labels/sort_labels_spec.rb
index 2aea4d77675..b5657db23cb 100644
--- a/spec/features/groups/labels/sort_labels_spec.rb
+++ b/spec/features/groups/labels/sort_labels_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Sort labels', :js do
+RSpec.describe 'Sort labels', :js do
let(:user) { create(:user) }
let(:group) { create(:group) }
let!(:label1) { create(:group_label, title: 'Foo', description: 'Lorem ipsum', group: group) }
diff --git a/spec/features/groups/labels/subscription_spec.rb b/spec/features/groups/labels/subscription_spec.rb
index cbccf4f3880..dedded777ac 100644
--- a/spec/features/groups/labels/subscription_spec.rb
+++ b/spec/features/groups/labels/subscription_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Labels subscription' do
+RSpec.describe 'Labels subscription' do
let(:user) { create(:user) }
let(:group) { create(:group) }
let!(:label1) { create(:group_label, group: group, title: 'foo') }
diff --git a/spec/features/groups/labels/user_sees_links_to_issuables_spec.rb b/spec/features/groups/labels/user_sees_links_to_issuables_spec.rb
index 38561c71323..b0508633065 100644
--- a/spec/features/groups/labels/user_sees_links_to_issuables_spec.rb
+++ b/spec/features/groups/labels/user_sees_links_to_issuables_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Groups > Labels > User sees links to issuables' do
+RSpec.describe 'Groups > Labels > User sees links to issuables' do
let_it_be(:group) { create(:group, :public) }
before do
diff --git a/spec/features/groups/members/filter_members_spec.rb b/spec/features/groups/members/filter_members_spec.rb
index cba86f7e651..643c8407578 100644
--- a/spec/features/groups/members/filter_members_spec.rb
+++ b/spec/features/groups/members/filter_members_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Groups > Members > Filter members' do
+RSpec.describe 'Groups > Members > Filter members' do
let(:user) { create(:user) }
let(:nested_group_user) { create(:user) }
let(:user_with_2fa) { create(:user, :two_factor_via_otp) }
diff --git a/spec/features/groups/members/leave_group_spec.rb b/spec/features/groups/members/leave_group_spec.rb
index 5c7c83aea6d..fecc90f20c7 100644
--- a/spec/features/groups/members/leave_group_spec.rb
+++ b/spec/features/groups/members/leave_group_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Groups > Members > Leave group' do
+RSpec.describe 'Groups > Members > Leave group' do
let(:user) { create(:user) }
let(:other_user) { create(:user) }
let(:group) { create(:group) }
@@ -31,6 +31,7 @@ describe 'Groups > Members > Leave group' do
page.accept_confirm
+ wait_for_all_requests
expect(current_path).to eq(dashboard_groups_path)
expect(group.users).not_to include(user)
end
diff --git a/spec/features/groups/members/list_members_spec.rb b/spec/features/groups/members/list_members_spec.rb
index 8df807186be..415c6927320 100644
--- a/spec/features/groups/members/list_members_spec.rb
+++ b/spec/features/groups/members/list_members_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Groups > Members > List members' do
+RSpec.describe 'Groups > Members > List members' do
include Select2Helper
include Spec::Support::Helpers::Features::ListRowsHelpers
diff --git a/spec/features/groups/members/manage_groups_spec.rb b/spec/features/groups/members/manage_groups_spec.rb
index 593c450c6d6..f1cf04417c0 100644
--- a/spec/features/groups/members/manage_groups_spec.rb
+++ b/spec/features/groups/members/manage_groups_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Groups > Members > Manage groups', :js do
+RSpec.describe 'Groups > Members > Manage groups', :js do
include Select2Helper
include Spec::Support::Helpers::Features::ListRowsHelpers
diff --git a/spec/features/groups/members/manage_members_spec.rb b/spec/features/groups/members/manage_members_spec.rb
index e4ba3022d8b..e29d8fd651e 100644
--- a/spec/features/groups/members/manage_members_spec.rb
+++ b/spec/features/groups/members/manage_members_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Groups > Members > Manage members' do
+RSpec.describe 'Groups > Members > Manage members' do
include Select2Helper
include Spec::Support::Helpers::Features::ListRowsHelpers
diff --git a/spec/features/groups/members/master_adds_member_with_expiration_date_spec.rb b/spec/features/groups/members/master_adds_member_with_expiration_date_spec.rb
index 491937ce4ab..f80925186ed 100644
--- a/spec/features/groups/members/master_adds_member_with_expiration_date_spec.rb
+++ b/spec/features/groups/members/master_adds_member_with_expiration_date_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Groups > Members > Owner adds member with expiration date', :js do
+RSpec.describe 'Groups > Members > Owner adds member with expiration date', :js do
include Select2Helper
include ActiveSupport::Testing::TimeHelpers
diff --git a/spec/features/groups/members/master_manages_access_requests_spec.rb b/spec/features/groups/members/master_manages_access_requests_spec.rb
index 1c13bd3d59e..2a17e7d2a5c 100644
--- a/spec/features/groups/members/master_manages_access_requests_spec.rb
+++ b/spec/features/groups/members/master_manages_access_requests_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Groups > Members > Maintainer manages access requests' do
+RSpec.describe 'Groups > Members > Maintainer manages access requests' do
it_behaves_like 'Maintainer manages access requests' do
let(:entity) { create(:group, :public) }
let(:members_page_path) { group_group_members_path(entity) }
diff --git a/spec/features/groups/members/request_access_spec.rb b/spec/features/groups/members/request_access_spec.rb
index 5f22af3529c..307cb63ec8e 100644
--- a/spec/features/groups/members/request_access_spec.rb
+++ b/spec/features/groups/members/request_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Groups > Members > Request access' do
+RSpec.describe 'Groups > Members > Request access' do
let(:user) { create(:user) }
let(:owner) { create(:user) }
let(:group) { create(:group, :public) }
diff --git a/spec/features/groups/members/search_members_spec.rb b/spec/features/groups/members/search_members_spec.rb
index fda129ce422..4c34ccf87c3 100644
--- a/spec/features/groups/members/search_members_spec.rb
+++ b/spec/features/groups/members/search_members_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Search group member' do
+RSpec.describe 'Search group member' do
let(:user) { create :user }
let(:member) { create :user }
diff --git a/spec/features/groups/members/sort_members_spec.rb b/spec/features/groups/members/sort_members_spec.rb
index 76709199942..cfc0e421aeb 100644
--- a/spec/features/groups/members/sort_members_spec.rb
+++ b/spec/features/groups/members/sort_members_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Groups > Members > Sort members' do
+RSpec.describe 'Groups > Members > Sort members' do
let(:owner) { create(:user, name: 'John Doe') }
let(:developer) { create(:user, name: 'Mary Jane', last_sign_in_at: 5.days.ago) }
let(:group) { create(:group) }
diff --git a/spec/features/groups/merge_requests_spec.rb b/spec/features/groups/merge_requests_spec.rb
index f87fa10e2f4..43d4b6b23e0 100644
--- a/spec/features/groups/merge_requests_spec.rb
+++ b/spec/features/groups/merge_requests_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Group merge requests page' do
+RSpec.describe 'Group merge requests page' do
include FilteredSearchHelpers
let(:path) { merge_requests_group_path(group) }
diff --git a/spec/features/groups/milestone_spec.rb b/spec/features/groups/milestone_spec.rb
index 65ef0af5be3..2217bd9d6b5 100644
--- a/spec/features/groups/milestone_spec.rb
+++ b/spec/features/groups/milestone_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Group milestones' do
+RSpec.describe 'Group milestones' do
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project_empty_repo, group: group) }
let_it_be(:user) { create(:group_member, :maintainer, user: create(:user), group: group ).user }
@@ -102,11 +102,9 @@ describe 'Group milestones' do
expect(find('.top-area .all .badge').text).to eq("6")
end
- it 'lists legacy group milestones and group milestones' do
- legacy_milestone = GroupMilestone.build_collection(group, group.projects, { state: 'active' }).first
-
+ it 'lists group and project milestones' do
expect(page).to have_selector("#milestone_#{active_group_milestone.id}", count: 1)
- expect(page).to have_selector("#milestone_#{legacy_milestone.milestone.id}", count: 1)
+ expect(page).to have_selector("#milestone_#{active_project_milestone2.id}", count: 1)
end
it 'shows milestone detail and supports its edit' do
@@ -126,74 +124,34 @@ describe 'Group milestones' do
expect(page).to have_content('v1.1')
expect(page).to have_content('GL-113')
expect(page).to have_link(
+ 'v1.0',
+ href: project_milestone_path(project, active_project_milestone1)
+ )
+ expect(page).to have_link(
'1 Issue',
- href: issues_group_path(group, milestone_title: 'v1.0')
+ href: project_issues_path(project, milestone_title: 'v1.0')
)
expect(page).to have_link(
'0 Merge Requests',
- href: merge_requests_group_path(group, milestone_title: 'v1.0')
+ href: project_merge_requests_path(project, milestone_title: 'v1.0')
+ )
+ expect(page).to have_link(
+ 'GL-113',
+ href: group_milestone_path(group, active_group_milestone)
+ )
+ expect(page).to have_link(
+ '0 Issues',
+ href: issues_group_path(group, milestone_title: 'GL-113')
+ )
+ expect(page).to have_link(
+ '0 Merge Requests',
+ href: merge_requests_group_path(group, milestone_title: 'GL-113')
)
- end
-
- it 'renders group milestone details' do
- click_link 'v1.0'
-
- expect(page).to have_content('expires on Aug 20, 2114')
- expect(page).to have_content('v1.0')
- expect(page).to have_content('Issues 1 Open: 1 Closed: 0')
- expect(page).to have_link(issue.title, href: project_issue_path(issue.project, issue))
end
end
end
describe 'milestone tabs', :js do
- context 'for a legacy group milestone' do
- let_it_be(:milestone) { create(:milestone, project: project) }
- let_it_be(:label) { create(:label, project: project) }
- let_it_be(:issue) { create(:labeled_issue, project: project, milestone: milestone, labels: [label], assignees: [create(:user)]) }
- let_it_be(:mr) { create(:merge_request, source_project: project, milestone: milestone) }
-
- before do
- visit group_milestone_path(group, milestone.title, title: milestone.title)
- end
-
- it 'renders the issues tab' do
- within('#tab-issues') do
- expect(page).to have_content issue.title
- end
- end
-
- it 'renders the merge requests tab' do
- within('.js-milestone-tabs') do
- click_link('Merge Requests')
- end
-
- within('#tab-merge-requests') do
- expect(page).to have_content mr.title
- end
- end
-
- it 'renders the participants tab' do
- within('.js-milestone-tabs') do
- click_link('Participants')
- end
-
- within('#tab-participants') do
- expect(page).to have_content issue.assignees.first.name
- end
- end
-
- it 'renders the labels tab' do
- within('.js-milestone-tabs') do
- click_link('Labels')
- end
-
- within('#tab-labels') do
- expect(page).to have_content label.title
- end
- end
- end
-
context 'for a group milestone' do
let_it_be(:other_project) { create(:project_empty_repo, group: group) }
let_it_be(:milestone) { create(:milestone, group: group) }
diff --git a/spec/features/groups/milestones_sorting_spec.rb b/spec/features/groups/milestones_sorting_spec.rb
index d27511be0b0..a06e64fdee0 100644
--- a/spec/features/groups/milestones_sorting_spec.rb
+++ b/spec/features/groups/milestones_sorting_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Milestones sorting', :js do
+RSpec.describe 'Milestones sorting', :js do
let(:group) { create(:group) }
let!(:project) { create(:project_empty_repo, group: group) }
let!(:other_project) { create(:project_empty_repo, group: group) }
@@ -24,21 +24,12 @@ describe 'Milestones sorting', :js do
# assert default sorting
within '.milestones' do
- expect(page.all('ul.content-list > li').first.text).to include('v2.0')
- expect(page.all('ul.content-list > li')[1].text).to include('v3.0')
- expect(page.all('ul.content-list > li').last.text).to include('v1.0')
+ expect(page.all('ul.content-list > li strong > a').map(&:text)).to eq(['v2.0', 'v2.0', 'v3.0', 'v1.0', 'v1.0'])
end
click_button 'Due soon'
- sort_options = find('ul.dropdown-menu-sort li').all('a').collect(&:text)
-
- expect(sort_options[0]).to eq('Due soon')
- expect(sort_options[1]).to eq('Due later')
- expect(sort_options[2]).to eq('Start soon')
- expect(sort_options[3]).to eq('Start later')
- expect(sort_options[4]).to eq('Name, ascending')
- expect(sort_options[5]).to eq('Name, descending')
+ expect(find('ul.dropdown-menu-sort li').all('a').map(&:text)).to eq(['Due soon', 'Due later', 'Start soon', 'Start later', 'Name, ascending', 'Name, descending'])
click_link 'Due later'
@@ -46,9 +37,7 @@ describe 'Milestones sorting', :js do
# assert descending sorting
within '.milestones' do
- expect(page.all('ul.content-list > li').first.text).to include('v1.0')
- expect(page.all('ul.content-list > li')[1].text).to include('v3.0')
- expect(page.all('ul.content-list > li').last.text).to include('v2.0')
+ expect(page.all('ul.content-list > li strong > a').map(&:text)).to eq(['v1.0', 'v1.0', 'v3.0', 'v2.0', 'v2.0'])
end
end
end
diff --git a/spec/features/groups/navbar_spec.rb b/spec/features/groups/navbar_spec.rb
index fd5b4ec9345..cfa1f3338a1 100644
--- a/spec/features/groups/navbar_spec.rb
+++ b/spec/features/groups/navbar_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Group navbar' do
+RSpec.describe 'Group navbar' do
include NavbarStructureHelper
include_context 'group navbar structure'
@@ -46,6 +46,7 @@ describe 'Group navbar' do
before do
stub_feature_flags(group_push_rules: false)
+ stub_feature_flags(group_iterations: false)
group.add_maintainer(user)
sign_in(user)
end
diff --git a/spec/features/groups/settings/ci_cd_spec.rb b/spec/features/groups/settings/ci_cd_spec.rb
index 5b1a9512c55..9c2f9512b9d 100644
--- a/spec/features/groups/settings/ci_cd_spec.rb
+++ b/spec/features/groups/settings/ci_cd_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Group CI/CD settings' do
+RSpec.describe 'Group CI/CD settings' do
include WaitForRequests
let(:user) { create(:user) }
diff --git a/spec/features/groups/settings/group_badges_spec.rb b/spec/features/groups/settings/group_badges_spec.rb
index 72e74df368b..5bf736cc7ce 100644
--- a/spec/features/groups/settings/group_badges_spec.rb
+++ b/spec/features/groups/settings/group_badges_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Group Badges' do
+RSpec.describe 'Group Badges' do
include WaitForRequests
let(:user) { create(:user) }
diff --git a/spec/features/groups/settings/repository_spec.rb b/spec/features/groups/settings/repository_spec.rb
index 722fd98ce59..d20303027e5 100644
--- a/spec/features/groups/settings/repository_spec.rb
+++ b/spec/features/groups/settings/repository_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Group Repository settings' do
+RSpec.describe 'Group Repository settings' do
include WaitForRequests
let(:user) { create(:user) }
diff --git a/spec/features/groups/share_lock_spec.rb b/spec/features/groups/share_lock_spec.rb
index 777f5d98720..d8207899e24 100644
--- a/spec/features/groups/share_lock_spec.rb
+++ b/spec/features/groups/share_lock_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Group share with group lock' do
+RSpec.describe 'Group share with group lock' do
let(:root_owner) { create(:user) }
let(:root_group) { create(:group) }
diff --git a/spec/features/groups/show_spec.rb b/spec/features/groups/show_spec.rb
index bcaed2a5f18..ec30f34199d 100644
--- a/spec/features/groups/show_spec.rb
+++ b/spec/features/groups/show_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Group show page' do
+RSpec.describe 'Group show page' do
let(:group) { create(:group) }
let(:path) { group_path(group) }
diff --git a/spec/features/groups/user_browse_projects_group_page_spec.rb b/spec/features/groups/user_browse_projects_group_page_spec.rb
index 68221e3fefe..999449a94b0 100644
--- a/spec/features/groups/user_browse_projects_group_page_spec.rb
+++ b/spec/features/groups/user_browse_projects_group_page_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User browse group projects page' do
+RSpec.describe 'User browse group projects page' do
let(:user) { create :user }
let(:group) { create :group }
diff --git a/spec/features/groups/user_sees_package_sidebar_spec.rb b/spec/features/groups/user_sees_package_sidebar_spec.rb
index f85b6841636..ee216488232 100644
--- a/spec/features/groups/user_sees_package_sidebar_spec.rb
+++ b/spec/features/groups/user_sees_package_sidebar_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Groups > sidebar' do
+RSpec.describe 'Groups > sidebar' do
let(:user) { create(:user) }
let(:group) { create(:group) }
diff --git a/spec/features/groups/user_sees_users_dropdowns_in_issuables_list_spec.rb b/spec/features/groups/user_sees_users_dropdowns_in_issuables_list_spec.rb
index 742021ae4a1..9fe11070187 100644
--- a/spec/features/groups/user_sees_users_dropdowns_in_issuables_list_spec.rb
+++ b/spec/features/groups/user_sees_users_dropdowns_in_issuables_list_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Groups > User sees users dropdowns in issuables list' do
+RSpec.describe 'Groups > User sees users dropdowns in issuables list' do
let(:entity) { create(:group) }
let(:user_in_dropdown) { create(:user) }
let!(:user_not_in_dropdown) { create(:user) }
diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb
index c1cb0b4951e..78a35fe1d3f 100644
--- a/spec/features/groups_spec.rb
+++ b/spec/features/groups_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Group' do
+RSpec.describe 'Group' do
let(:user) { create(:admin) }
before do
diff --git a/spec/features/help_pages_spec.rb b/spec/features/help_pages_spec.rb
index 1ba3849fe2c..1f8397e45f7 100644
--- a/spec/features/help_pages_spec.rb
+++ b/spec/features/help_pages_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Help Pages' do
+RSpec.describe 'Help Pages' do
describe 'Get the main help page' do
before do
allow(File).to receive(:read).and_call_original
diff --git a/spec/features/ics/dashboard_issues_spec.rb b/spec/features/ics/dashboard_issues_spec.rb
index bde5488f375..4a93a4b490a 100644
--- a/spec/features/ics/dashboard_issues_spec.rb
+++ b/spec/features/ics/dashboard_issues_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Dashboard Issues Calendar Feed' do
+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') }
diff --git a/spec/features/ics/group_issues_spec.rb b/spec/features/ics/group_issues_spec.rb
index 0b317095678..05caca4b5a8 100644
--- a/spec/features/ics/group_issues_spec.rb
+++ b/spec/features/ics/group_issues_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Group Issues Calendar Feed' do
+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') }
diff --git a/spec/features/ics/project_issues_spec.rb b/spec/features/ics/project_issues_spec.rb
index 3c940149670..58a1a32eac2 100644
--- a/spec/features/ics/project_issues_spec.rb
+++ b/spec/features/ics/project_issues_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project Issues Calendar Feed' do
+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') }
diff --git a/spec/features/ide/clientside_preview_csp_spec.rb b/spec/features/ide/clientside_preview_csp_spec.rb
index e097513def3..eadcb9cd008 100644
--- a/spec/features/ide/clientside_preview_csp_spec.rb
+++ b/spec/features/ide/clientside_preview_csp_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'IDE Clientside Preview CSP' do
+RSpec.describe 'IDE Clientside Preview CSP' do
let_it_be(:user) { create(:user) }
shared_context 'disable feature' do
diff --git a/spec/features/ide/static_object_external_storage_csp_spec.rb b/spec/features/ide/static_object_external_storage_csp_spec.rb
index 739b3fe2471..24d37f25739 100644
--- a/spec/features/ide/static_object_external_storage_csp_spec.rb
+++ b/spec/features/ide/static_object_external_storage_csp_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Static Object External Storage Content Security Policy' do
+RSpec.describe 'Static Object External Storage Content Security Policy' do
let_it_be(:user) { create(:user) }
shared_context 'disable feature' do
diff --git a/spec/features/ide/user_commits_changes_spec.rb b/spec/features/ide/user_commits_changes_spec.rb
index 56f2c6b8afc..1b1e71e2862 100644
--- a/spec/features/ide/user_commits_changes_spec.rb
+++ b/spec/features/ide/user_commits_changes_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'IDE user commits changes', :js do
+RSpec.describe 'IDE user commits changes', :js do
include WebIdeSpecHelpers
let(:project) { create(:project, :public, :repository) }
@@ -30,14 +30,4 @@ describe 'IDE user commits changes', :js do
expect(project.repository.blob_at('master', 'foo/bar/.gitkeep')).to be_nil
expect(project.repository.blob_at('master', 'foo/bar/lorem_ipsum.md').data).to eql(content)
end
-
- it 'user adds then deletes new file' do
- ide_create_new_file('foo/bar/lorem_ipsum.md')
-
- expect(page).to have_selector(ide_commit_tab_selector)
-
- ide_delete_file('foo/bar/lorem_ipsum.md')
-
- expect(page).not_to have_selector(ide_commit_tab_selector)
- end
end
diff --git a/spec/features/ide/user_opens_merge_request_spec.rb b/spec/features/ide/user_opens_merge_request_spec.rb
index 03318287db9..e6101e90a83 100644
--- a/spec/features/ide/user_opens_merge_request_spec.rb
+++ b/spec/features/ide/user_opens_merge_request_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'IDE merge request', :js do
+RSpec.describe 'IDE merge request', :js do
let(:merge_request) { create(:merge_request, :with_diffs, :simple, source_project: project) }
let(:project) { create(:project, :public, :repository) }
let(:user) { project.owner }
diff --git a/spec/features/ide_spec.rb b/spec/features/ide_spec.rb
index 73f6180d944..2505ab0afee 100644
--- a/spec/features/ide_spec.rb
+++ b/spec/features/ide_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'IDE', :js do
+RSpec.describe 'IDE', :js do
describe 'sub-groups' do
let(:user) { create(:user) }
let(:group) { create(:group) }
diff --git a/spec/features/import/manifest_import_spec.rb b/spec/features/import/manifest_import_spec.rb
index 36478128dd1..1efbc5642d4 100644
--- a/spec/features/import/manifest_import_spec.rb
+++ b/spec/features/import/manifest_import_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Import multiple repositories by uploading a manifest file', :js do
+RSpec.describe 'Import multiple repositories by uploading a manifest file', :js do
include Select2Helper
let(:user) { create(:admin) }
diff --git a/spec/features/instance_statistics/cohorts_spec.rb b/spec/features/instance_statistics/cohorts_spec.rb
index 0bb2e4b997d..1f112e1831c 100644
--- a/spec/features/instance_statistics/cohorts_spec.rb
+++ b/spec/features/instance_statistics/cohorts_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Cohorts page' do
+RSpec.describe 'Cohorts page' do
before do
sign_in(create(:admin))
diff --git a/spec/features/instance_statistics/dev_ops_score_spec.rb b/spec/features/instance_statistics/dev_ops_score_spec.rb
index 453b5582f48..da87aedab5c 100644
--- a/spec/features/instance_statistics/dev_ops_score_spec.rb
+++ b/spec/features/instance_statistics/dev_ops_score_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'DevOps Score' do
+RSpec.describe 'DevOps Score' do
before do
sign_in(create(:admin))
end
diff --git a/spec/features/instance_statistics/instance_statistics_spec.rb b/spec/features/instance_statistics/instance_statistics_spec.rb
index 0fb78c6eef8..7695bf7874b 100644
--- a/spec/features/instance_statistics/instance_statistics_spec.rb
+++ b/spec/features/instance_statistics/instance_statistics_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Cohorts page', :js do
+RSpec.describe 'Cohorts page', :js do
before do
sign_in(create(:admin))
end
diff --git a/spec/features/invites_spec.rb b/spec/features/invites_spec.rb
index 9cd01894575..f85b4b78e35 100644
--- a/spec/features/invites_spec.rb
+++ b/spec/features/invites_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Invites' do
+RSpec.describe 'Invites' do
let(:user) { create(:user) }
let(:owner) { create(:user, name: 'John Doe') }
let(:group) { create(:group, name: 'Owned') }
diff --git a/spec/features/issuables/close_reopen_report_toggle_spec.rb b/spec/features/issuables/close_reopen_report_toggle_spec.rb
index 8805018902f..cf3028ec4c9 100644
--- a/spec/features/issuables/close_reopen_report_toggle_spec.rb
+++ b/spec/features/issuables/close_reopen_report_toggle_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Issuables Close/Reopen/Report toggle' do
+RSpec.describe 'Issuables Close/Reopen/Report toggle' do
let(:user) { create(:user) }
shared_examples 'an issuable close/reopen/report toggle' do
diff --git a/spec/features/issuables/discussion_lock_spec.rb b/spec/features/issuables/discussion_lock_spec.rb
index 0cd2c077081..13f1742fbf6 100644
--- a/spec/features/issuables/discussion_lock_spec.rb
+++ b/spec/features/issuables/discussion_lock_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Discussion Lock', :js do
+RSpec.describe 'Discussion Lock', :js do
let(:user) { create(:user) }
let(:issue) { create(:issue, project: project, author: user) }
let(:project) { create(:project, :public) }
diff --git a/spec/features/issuables/issuable_list_spec.rb b/spec/features/issuables/issuable_list_spec.rb
index 7014a51ccdc..382a7a9321c 100644
--- a/spec/features/issuables/issuable_list_spec.rb
+++ b/spec/features/issuables/issuable_list_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'issuable list' do
+RSpec.describe 'issuable list' do
let(:project) { create(:project) }
let(:user) { create(:user) }
diff --git a/spec/features/issuables/markdown_references/internal_references_spec.rb b/spec/features/issuables/markdown_references/internal_references_spec.rb
index efd84cf67b0..aceaea8d2ed 100644
--- a/spec/features/issuables/markdown_references/internal_references_spec.rb
+++ b/spec/features/issuables/markdown_references/internal_references_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Internal references", :js do
+RSpec.describe "Internal references", :js do
include Spec::Support::Helpers::Features::NotesHelpers
let(:private_project_user) { private_project.owner }
diff --git a/spec/features/issuables/markdown_references/jira_spec.rb b/spec/features/issuables/markdown_references/jira_spec.rb
index 779606effdc..a3a259e21a1 100644
--- a/spec/features/issuables/markdown_references/jira_spec.rb
+++ b/spec/features/issuables/markdown_references/jira_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Jira", :js do
+RSpec.describe "Jira", :js do
let(:user) { create(:user) }
let(:actual_project) { create(:project, :public, :repository) }
let(:merge_request) { create(:merge_request, target_project: actual_project, source_project: actual_project) }
diff --git a/spec/features/issuables/shortcuts_issuable_spec.rb b/spec/features/issuables/shortcuts_issuable_spec.rb
index da8a0dd7b0f..78cd8d0bef3 100644
--- a/spec/features/issuables/shortcuts_issuable_spec.rb
+++ b/spec/features/issuables/shortcuts_issuable_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Blob shortcuts', :js do
+RSpec.describe 'Blob shortcuts', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :public, :repository) }
let(:issue) { create(:issue, project: project, author: user) }
diff --git a/spec/features/issuables/sorting_list_spec.rb b/spec/features/issuables/sorting_list_spec.rb
index b7813c8ba30..59518723740 100644
--- a/spec/features/issuables/sorting_list_spec.rb
+++ b/spec/features/issuables/sorting_list_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe 'Sort Issuable List' do
+RSpec.describe 'Sort Issuable List' do
let(:project) { create(:project, :public) }
let(:first_created_issuable) { issuables.order_created_asc.first }
diff --git a/spec/features/issuables/user_sees_sidebar_spec.rb b/spec/features/issuables/user_sees_sidebar_spec.rb
index 52040eb8cbb..04bf704b6a4 100644
--- a/spec/features/issuables/user_sees_sidebar_spec.rb
+++ b/spec/features/issuables/user_sees_sidebar_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Issue Sidebar on Mobile' do
+RSpec.describe 'Issue Sidebar on Mobile' do
include MobileHelpers
let(:project) { create(:project, :public, :repository) }
diff --git a/spec/features/issues/bulk_assignment_labels_spec.rb b/spec/features/issues/bulk_assignment_labels_spec.rb
index fc9176715c3..84a786e91a7 100644
--- a/spec/features/issues/bulk_assignment_labels_spec.rb
+++ b/spec/features/issues/bulk_assignment_labels_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Issues > Labels bulk assignment' do
+RSpec.describe 'Issues > Labels bulk assignment' do
let(:user) { create(:user) }
let!(:project) { create(:project) }
let!(:issue1) { create(:issue, project: project, title: "Issue 1") }
@@ -302,7 +302,23 @@ describe 'Issues > Labels bulk assignment' do
sleep 1 # needed
expect(find("#issue_#{issue1.id}")).to have_content 'bug'
- expect(find("#issue_#{issue1.id}")).not_to have_content 'feature'
+ expect(find("#issue_#{issue1.id}")).to have_content 'feature'
+ end
+ end
+
+ context 'mark previously toggled label' do
+ before do
+ enable_bulk_update
+ end
+
+ it do
+ open_labels_dropdown ['feature']
+
+ check_issue issue1
+
+ update_issues
+
+ expect(find("#issue_#{issue1.id}")).to have_content 'feature'
end
end
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 a3742af31de..6fc648954b4 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
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Resolving all open threads in a merge request from an issue', :js do
+RSpec.describe 'Resolving all open threads in a merge request from an issue', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:merge_request) { create(:merge_request, source_project: project) }
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 1c17b39c03a..55a02dc4255 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
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Resolve an open thread in a merge request by creating an issue', :js do
+RSpec.describe 'Resolve an open thread in a merge request by creating an issue', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :repository, only_allow_merge_if_all_discussions_are_resolved: true) }
let(:merge_request) { create(:merge_request, source_project: project) }
diff --git a/spec/features/issues/csv_spec.rb b/spec/features/issues/csv_spec.rb
index 193c83d2a40..8d06bf24f8b 100644
--- a/spec/features/issues/csv_spec.rb
+++ b/spec/features/issues/csv_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Issues csv' do
+RSpec.describe 'Issues csv' do
let(:user) { create(:user) }
let(:project) { create(:project, :public) }
let(:milestone) { create(:milestone, title: 'v1.0', project: project) }
diff --git a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
index c207e91f02e..381633b0fc9 100644
--- a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Dropdown assignee', :js do
+RSpec.describe 'Dropdown assignee', :js do
include FilteredSearchHelpers
let!(:project) { create(:project) }
diff --git a/spec/features/issues/filtered_search/dropdown_author_spec.rb b/spec/features/issues/filtered_search/dropdown_author_spec.rb
index 8ded11b3b08..91c85825a17 100644
--- a/spec/features/issues/filtered_search/dropdown_author_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_author_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Dropdown author', :js do
+RSpec.describe 'Dropdown author', :js do
include FilteredSearchHelpers
let!(:project) { create(:project) }
diff --git a/spec/features/issues/filtered_search/dropdown_base_spec.rb b/spec/features/issues/filtered_search/dropdown_base_spec.rb
index 14d3f48b8fc..d730525cb8b 100644
--- a/spec/features/issues/filtered_search/dropdown_base_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_base_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Dropdown base', :js do
+RSpec.describe 'Dropdown base', :js do
include FilteredSearchHelpers
let!(:project) { create(:project) }
diff --git a/spec/features/issues/filtered_search/dropdown_emoji_spec.rb b/spec/features/issues/filtered_search/dropdown_emoji_spec.rb
index 9ab0f49cd15..c2c933f8a86 100644
--- a/spec/features/issues/filtered_search/dropdown_emoji_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_emoji_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Dropdown emoji', :js do
+RSpec.describe 'Dropdown emoji', :js do
include FilteredSearchHelpers
let!(:project) { create(:project, :public) }
diff --git a/spec/features/issues/filtered_search/dropdown_hint_spec.rb b/spec/features/issues/filtered_search/dropdown_hint_spec.rb
index 10b092c6957..9edc6e0b593 100644
--- a/spec/features/issues/filtered_search/dropdown_hint_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_hint_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Dropdown hint', :js do
+RSpec.describe 'Dropdown hint', :js do
include FilteredSearchHelpers
let!(:project) { create(:project, :public) }
diff --git a/spec/features/issues/filtered_search/dropdown_label_spec.rb b/spec/features/issues/filtered_search/dropdown_label_spec.rb
index a982053dbcb..c0d5fe0d860 100644
--- a/spec/features/issues/filtered_search/dropdown_label_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_label_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Dropdown label', :js do
+RSpec.describe 'Dropdown label', :js do
include FilteredSearchHelpers
let(:project) { create(:project) }
diff --git a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb
index 56beb35a1c5..68afd973f1d 100644
--- a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Dropdown milestone', :js do
+RSpec.describe 'Dropdown milestone', :js do
include FilteredSearchHelpers
let!(:project) { create(:project) }
diff --git a/spec/features/issues/filtered_search/dropdown_release_spec.rb b/spec/features/issues/filtered_search/dropdown_release_spec.rb
index ae1c84d71b4..daf686c2850 100644
--- a/spec/features/issues/filtered_search/dropdown_release_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_release_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Dropdown release', :js do
+RSpec.describe 'Dropdown release', :js do
include FilteredSearchHelpers
let!(:project) { create(:project, :repository) }
diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb
index 3ee5840e1b9..5b5348d4069 100644
--- a/spec/features/issues/filtered_search/filter_issues_spec.rb
+++ b/spec/features/issues/filtered_search/filter_issues_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Filter issues', :js do
+RSpec.describe 'Filter issues', :js do
include FilteredSearchHelpers
let(:project) { create(:project) }
diff --git a/spec/features/issues/filtered_search/recent_searches_spec.rb b/spec/features/issues/filtered_search/recent_searches_spec.rb
index e05c7aa3af5..85b7a093536 100644
--- a/spec/features/issues/filtered_search/recent_searches_spec.rb
+++ b/spec/features/issues/filtered_search/recent_searches_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Recent searches', :js do
+RSpec.describe 'Recent searches', :js do
include FilteredSearchHelpers
let(:project_1) { create(:project, :public) }
diff --git a/spec/features/issues/filtered_search/search_bar_spec.rb b/spec/features/issues/filtered_search/search_bar_spec.rb
index ad994270218..167fecc5ab1 100644
--- a/spec/features/issues/filtered_search/search_bar_spec.rb
+++ b/spec/features/issues/filtered_search/search_bar_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Search bar', :js do
+RSpec.describe 'Search bar', :js do
include FilteredSearchHelpers
let!(:project) { create(:project) }
diff --git a/spec/features/issues/filtered_search/visual_tokens_spec.rb b/spec/features/issues/filtered_search/visual_tokens_spec.rb
index d34253b3c5e..59588978a8e 100644
--- a/spec/features/issues/filtered_search/visual_tokens_spec.rb
+++ b/spec/features/issues/filtered_search/visual_tokens_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Visual tokens', :js do
+RSpec.describe 'Visual tokens', :js do
include FilteredSearchHelpers
let!(:project) { create(:project) }
diff --git a/spec/features/issues/form_spec.rb b/spec/features/issues/form_spec.rb
index 8d7b6be5ea2..dac066856c0 100644
--- a/spec/features/issues/form_spec.rb
+++ b/spec/features/issues/form_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'New/edit issue', :js do
+RSpec.describe 'New/edit issue', :js do
include ActionView::Helpers::JavaScriptHelper
include FormHelper
diff --git a/spec/features/issues/gfm_autocomplete_spec.rb b/spec/features/issues/gfm_autocomplete_spec.rb
index 501a2d347d1..4a7e1ba99e9 100644
--- a/spec/features/issues/gfm_autocomplete_spec.rb
+++ b/spec/features/issues/gfm_autocomplete_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'GFM autocomplete', :js do
+RSpec.describe 'GFM autocomplete', :js do
let(:issue_xss_title) { 'This will execute alert<img src=x onerror=alert(2)&lt;img src=x onerror=alert(1)&gt;' }
let(:user_xss_title) { 'eve <img src=x onerror=alert(2)&lt;img src=x onerror=alert(1)&gt;' }
let(:label_xss_title) { 'alert label &lt;img src=x onerror="alert(\'Hello xss\');" a' }
diff --git a/spec/features/issues/group_label_sidebar_spec.rb b/spec/features/issues/group_label_sidebar_spec.rb
index fe6d95e1039..e6a173f4589 100644
--- a/spec/features/issues/group_label_sidebar_spec.rb
+++ b/spec/features/issues/group_label_sidebar_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Group label on issue' do
+RSpec.describe 'Group label on issue' do
it 'renders link to the project issues page' do
group = create(:group)
project = create(:project, :public, namespace: group)
diff --git a/spec/features/issues/issue_detail_spec.rb b/spec/features/issues/issue_detail_spec.rb
index 3bb70fdf376..ab319daec71 100644
--- a/spec/features/issues/issue_detail_spec.rb
+++ b/spec/features/issues/issue_detail_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Issue Detail', :js do
+RSpec.describe 'Issue Detail', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :public) }
let(:issue) { create(:issue, project: project, author: user) }
diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb
index e7c675bf6bf..9e4362bf0e5 100644
--- a/spec/features/issues/issue_sidebar_spec.rb
+++ b/spec/features/issues/issue_sidebar_spec.rb
@@ -2,12 +2,12 @@
require 'spec_helper'
-describe 'Issue Sidebar' do
+RSpec.describe 'Issue Sidebar' do
include MobileHelpers
let(:group) { create(:group, :nested) }
let(:project) { create(:project, :public, namespace: group) }
- let!(:user) { create(:user)}
+ let!(:user) { create(:user) }
let!(:label) { create(:label, project: project, title: 'bug') }
let(:issue) { create(:labeled_issue, project: project, labels: [label]) }
let!(:xss_label) { create(:label, project: project, title: '&lt;script&gt;alert("xss");&lt;&#x2F;script&gt;') }
@@ -20,62 +20,125 @@ describe 'Issue Sidebar' do
let(:user2) { create(:user) }
let(:issue2) { create(:issue, project: project, author: user2) }
- before do
- project.add_developer(user)
- visit_issue(project, issue2)
+ context 'when invite_members_version_a experiment is enabled' do
+ before do
+ stub_experiment_for_user(invite_members_version_a: true)
+ end
- find('.block.assignee .edit-link').click
+ context 'when user can not see invite members' do
+ before do
+ project.add_developer(user)
+ visit_issue(project, issue2)
- wait_for_requests
- end
+ find('.block.assignee .edit-link').click
- it 'shows author in assignee dropdown' do
- page.within '.dropdown-menu-user' do
- expect(page).to have_content(user2.name)
+ wait_for_requests
+ end
+
+ it 'does not see link to invite members' do
+ page.within '.dropdown-menu-user' do
+ expect(page).not_to have_link('Invite Members')
+ end
+ end
end
- end
- it 'shows author when filtering assignee dropdown' do
- page.within '.dropdown-menu-user' do
- find('.dropdown-input-field').native.send_keys user2.name
- sleep 1 # Required to wait for end of input delay
+ context 'when user can see invite members' do
+ before do
+ project.add_maintainer(user)
+ visit_issue(project, issue2)
+
+ find('.block.assignee .edit-link').click
- wait_for_requests
+ wait_for_requests
+ end
- expect(page).to have_content(user2.name)
+ it 'sees link to invite members' do
+ page.within '.dropdown-menu-user' do
+ expect(page).to have_link('Invite Members', href: project_project_members_path(project))
+ expect(page).to have_selector('[data-track-event="click_invite_members"]')
+ expect(page).to have_selector("[data-track-label='edit_assignee']")
+ end
+ end
end
end
- it 'assigns yourself' do
- find('.block.assignee .dropdown-menu-toggle').click
+ context 'when invite_members_version_a experiment is not enabled' do
+ context 'when user is a developer' do
+ before do
+ project.add_developer(user)
+ visit_issue(project, issue2)
- click_button 'assign yourself'
+ find('.block.assignee .edit-link').click
- wait_for_requests
+ wait_for_requests
+ end
- find('.block.assignee .edit-link').click
+ it 'shows author in assignee dropdown' do
+ page.within '.dropdown-menu-user' do
+ expect(page).to have_content(user2.name)
+ end
+ end
- page.within '.dropdown-menu-user' do
- expect(page.find('.dropdown-header')).to be_visible
- expect(page.find('.dropdown-menu-user-link.is-active')).to have_content(user.name)
- end
- end
+ it 'shows author when filtering assignee dropdown' do
+ page.within '.dropdown-menu-user' do
+ find('.dropdown-input-field').native.send_keys user2.name
+ sleep 1 # Required to wait for end of input delay
- it 'keeps your filtered term after filtering and dismissing the dropdown' do
- find('.dropdown-input-field').native.send_keys user2.name
+ wait_for_requests
- wait_for_requests
+ expect(page).to have_content(user2.name)
+ end
+ end
+
+ it 'assigns yourself' do
+ find('.block.assignee .dropdown-menu-toggle').click
+
+ click_button 'assign yourself'
+
+ wait_for_requests
+
+ find('.block.assignee .edit-link').click
+
+ page.within '.dropdown-menu-user' do
+ expect(page.find('.dropdown-header')).to be_visible
+ expect(page.find('.dropdown-menu-user-link.is-active')).to have_content(user.name)
+ end
+ end
+
+ it 'keeps your filtered term after filtering and dismissing the dropdown' do
+ find('.dropdown-input-field').native.send_keys user2.name
+
+ wait_for_requests
- page.within '.dropdown-menu-user' do
- expect(page).not_to have_content 'Unassigned'
- click_link user2.name
+ page.within '.dropdown-menu-user' do
+ expect(page).not_to have_content 'Unassigned'
+ click_link user2.name
+ end
+
+ find('.js-right-sidebar').click
+ find('.block.assignee .edit-link').click
+
+ expect(page.all('.dropdown-menu-user li').length).to eq(1)
+ expect(find('.dropdown-input-field').value).to eq(user2.name)
+ end
end
- find('.js-right-sidebar').click
- find('.block.assignee .edit-link').click
+ context 'when user is a maintainer' do
+ before do
+ project.add_maintainer(user)
+ visit_issue(project, issue2)
+
+ find('.block.assignee .edit-link').click
- expect(page.all('.dropdown-menu-user li').length).to eq(1)
- expect(find('.dropdown-input-field').value).to eq(user2.name)
+ wait_for_requests
+ end
+
+ it 'shows author in assignee dropdown and no invite link' do
+ page.within '.dropdown-menu-user' do
+ expect(page).not_to have_link('Invite Members')
+ end
+ end
+ end
end
end
diff --git a/spec/features/issues/keyboard_shortcut_spec.rb b/spec/features/issues/keyboard_shortcut_spec.rb
index c5d53cd1cd0..ab40f124257 100644
--- a/spec/features/issues/keyboard_shortcut_spec.rb
+++ b/spec/features/issues/keyboard_shortcut_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Issues shortcut', :js do
+RSpec.describe 'Issues shortcut', :js do
context 'New Issue shortcut' do
context 'issues are enabled' do
let(:project) { create(:project) }
diff --git a/spec/features/issues/markdown_toolbar_spec.rb b/spec/features/issues/markdown_toolbar_spec.rb
index d174fdcb25e..aab9d1026f9 100644
--- a/spec/features/issues/markdown_toolbar_spec.rb
+++ b/spec/features/issues/markdown_toolbar_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Issue markdown toolbar', :js do
+RSpec.describe 'Issue markdown toolbar', :js do
let(:project) { create(:project, :public) }
let(:issue) { create(:issue, project: project) }
let(:user) { create(:user) }
diff --git a/spec/features/issues/move_spec.rb b/spec/features/issues/move_spec.rb
index 831bcf8931e..f3a6655f397 100644
--- a/spec/features/issues/move_spec.rb
+++ b/spec/features/issues/move_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'issue move to another project' do
+RSpec.describe 'issue move to another project' do
let(:user) { create(:user) }
let(:old_project) { create(:project, :repository) }
let(:text) { 'Some issue description' }
diff --git a/spec/features/issues/note_polling_spec.rb b/spec/features/issues/note_polling_spec.rb
index 04ad012d57e..bc4c67fdd79 100644
--- a/spec/features/issues/note_polling_spec.rb
+++ b/spec/features/issues/note_polling_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Issue notes polling', :js do
+RSpec.describe 'Issue notes polling', :js do
include NoteInteractionHelpers
let(:project) { create(:project, :public) }
diff --git a/spec/features/issues/notes_on_issues_spec.rb b/spec/features/issues/notes_on_issues_spec.rb
index 74eb699c7ef..be85d73d777 100644
--- a/spec/features/issues/notes_on_issues_spec.rb
+++ b/spec/features/issues/notes_on_issues_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Create notes on issues', :js do
+RSpec.describe 'Create notes on issues', :js do
let(:user) { create(:user) }
def submit_comment(text)
diff --git a/spec/features/issues/resource_label_events_spec.rb b/spec/features/issues/resource_label_events_spec.rb
index b367bbe2c99..f2c978c525e 100644
--- a/spec/features/issues/resource_label_events_spec.rb
+++ b/spec/features/issues/resource_label_events_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'List issue resource label events', :js do
+RSpec.describe 'List issue resource label events', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :public) }
let(:issue) { create(:issue, project: project, author: user) }
diff --git a/spec/features/issues/rss_spec.rb b/spec/features/issues/rss_spec.rb
index 7577df3bc7d..6c4498ea711 100644
--- a/spec/features/issues/rss_spec.rb
+++ b/spec/features/issues/rss_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project Issues RSS' do
+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) }
diff --git a/spec/features/issues/spam_issues_spec.rb b/spec/features/issues/spam_issues_spec.rb
index 47e7022011d..aec806c566d 100644
--- a/spec/features/issues/spam_issues_spec.rb
+++ b/spec/features/issues/spam_issues_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'New issue', :js do
+RSpec.describe 'New issue', :js do
include StubENV
let(:project) { create(:project, :public) }
@@ -81,7 +81,7 @@ describe 'New issue', :js do
before do
allow_next_instance_of(Spam::SpamVerdictService) do |verdict_service|
- allow(verdict_service).to receive(:execute).and_return(REQUIRE_RECAPTCHA)
+ allow(verdict_service).to receive(:execute).and_return(CONDITIONAL_ALLOW)
end
visit new_project_issue_path(project)
@@ -164,6 +164,8 @@ describe 'New issue', :js do
end
context 'when the SpamVerdictService allows' do
+ include_context 'includes Spam constants'
+
before do
allow_next_instance_of(Spam::SpamVerdictService) do |verdict_service|
allow(verdict_service).to receive(:execute).and_return(ALLOW)
diff --git a/spec/features/issues/todo_spec.rb b/spec/features/issues/todo_spec.rb
index 4bb96ad069c..3de33049db0 100644
--- a/spec/features/issues/todo_spec.rb
+++ b/spec/features/issues/todo_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Manually create a todo item from issue', :js do
+RSpec.describe 'Manually create a todo item from issue', :js do
let!(:project) { create(:project) }
let!(:issue) { create(:issue, project: project) }
let!(:user) { create(:user)}
diff --git a/spec/features/issues/update_issues_spec.rb b/spec/features/issues/update_issues_spec.rb
index 98f70df1c8b..f8385f183d2 100644
--- a/spec/features/issues/update_issues_spec.rb
+++ b/spec/features/issues/update_issues_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Multiple issue updating from issues#index', :js do
+RSpec.describe 'Multiple issue updating from issues#index', :js do
let!(:project) { create(:project) }
let!(:issue) { create(:issue, project: project) }
let!(:user) { create(:user)}
diff --git a/spec/features/issues/user_comments_on_issue_spec.rb b/spec/features/issues/user_comments_on_issue_spec.rb
index 363906b017a..005d45d9c92 100644
--- a/spec/features/issues/user_comments_on_issue_spec.rb
+++ b/spec/features/issues/user_comments_on_issue_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User comments on issue", :js do
+RSpec.describe "User comments on issue", :js do
include Spec::Support::Helpers::Features::NotesHelpers
let(:project) { create(:project_empty_repo, :public) }
diff --git a/spec/features/issues/user_creates_branch_and_merge_request_spec.rb b/spec/features/issues/user_creates_branch_and_merge_request_spec.rb
index 848dbbb85a6..a546fb3e85b 100644
--- a/spec/features/issues/user_creates_branch_and_merge_request_spec.rb
+++ b/spec/features/issues/user_creates_branch_and_merge_request_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User creates branch and merge request on issue page', :js do
+RSpec.describe 'User creates branch and merge request on issue page', :js do
let(:membership_level) { :developer }
let(:user) { create(:user) }
let!(:project) { create(:project, :repository, :public) }
diff --git a/spec/features/issues/user_creates_confidential_merge_request_spec.rb b/spec/features/issues/user_creates_confidential_merge_request_spec.rb
index 84f358061e6..ea96165d7b7 100644
--- a/spec/features/issues/user_creates_confidential_merge_request_spec.rb
+++ b/spec/features/issues/user_creates_confidential_merge_request_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User creates confidential merge request on issue page', :js do
+RSpec.describe 'User creates confidential merge request on issue page', :js do
include ProjectForksHelper
let(:user) { create(:user) }
diff --git a/spec/features/issues/user_creates_issue_by_email_spec.rb b/spec/features/issues/user_creates_issue_by_email_spec.rb
index c73a65849cc..5a0036170ab 100644
--- a/spec/features/issues/user_creates_issue_by_email_spec.rb
+++ b/spec/features/issues/user_creates_issue_by_email_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Issues > User creates issue by email' do
+RSpec.describe 'Issues > User creates issue by email' do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :public) }
diff --git a/spec/features/issues/user_creates_issue_spec.rb b/spec/features/issues/user_creates_issue_spec.rb
index efcaa8247df..a2c868d0256 100644
--- a/spec/features/issues/user_creates_issue_spec.rb
+++ b/spec/features/issues/user_creates_issue_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User creates issue" do
+RSpec.describe "User creates issue" do
include DropzoneHelper
let_it_be(:project) { create(:project_empty_repo, :public) }
diff --git a/spec/features/issues/user_edits_issue_spec.rb b/spec/features/issues/user_edits_issue_spec.rb
index d50cf16d8ef..39bf535c715 100644
--- a/spec/features/issues/user_edits_issue_spec.rb
+++ b/spec/features/issues/user_edits_issue_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "Issues > User edits issue", :js do
+RSpec.describe "Issues > User edits issue", :js do
let_it_be(:project) { create(:project_empty_repo, :public) }
let_it_be(:user) { create(:user) }
let_it_be(:issue) { create(:issue, project: project, author: user, assignees: [user]) }
diff --git a/spec/features/issues/user_filters_issues_spec.rb b/spec/features/issues/user_filters_issues_spec.rb
index 9ce47e68926..20ad47b111a 100644
--- a/spec/features/issues/user_filters_issues_spec.rb
+++ b/spec/features/issues/user_filters_issues_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User filters issues' do
+RSpec.describe 'User filters issues' do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project_empty_repo, :public) }
diff --git a/spec/features/issues/user_interacts_with_awards_spec.rb b/spec/features/issues/user_interacts_with_awards_spec.rb
index 095ae9f276c..7b7e087a6d6 100644
--- a/spec/features/issues/user_interacts_with_awards_spec.rb
+++ b/spec/features/issues/user_interacts_with_awards_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User interacts with awards' do
+RSpec.describe 'User interacts with awards' do
let(:user) { create(:user) }
describe 'User interacts with awards in an issue', :js do
diff --git a/spec/features/issues/user_resets_their_incoming_email_token_spec.rb b/spec/features/issues/user_resets_their_incoming_email_token_spec.rb
index 108b6f550db..a20f65abebf 100644
--- a/spec/features/issues/user_resets_their_incoming_email_token_spec.rb
+++ b/spec/features/issues/user_resets_their_incoming_email_token_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Issues > User resets their incoming email token' do
+RSpec.describe 'Issues > User resets their incoming email token' do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :public, namespace: user.namespace) }
let_it_be(:issue) { create(:issue, project: project) }
diff --git a/spec/features/issues/user_sees_breadcrumb_links_spec.rb b/spec/features/issues/user_sees_breadcrumb_links_spec.rb
index 8a120a0a0b2..2660101c330 100644
--- a/spec/features/issues/user_sees_breadcrumb_links_spec.rb
+++ b/spec/features/issues/user_sees_breadcrumb_links_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'New issue breadcrumb' do
+RSpec.describe 'New issue breadcrumb' do
let_it_be(:project, reload: true) { create(:project) }
let(:user) { project.creator }
diff --git a/spec/features/issues/user_sees_empty_state_spec.rb b/spec/features/issues/user_sees_empty_state_spec.rb
index 114d119aca8..047c5ca2189 100644
--- a/spec/features/issues/user_sees_empty_state_spec.rb
+++ b/spec/features/issues/user_sees_empty_state_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Issues > User sees empty state' do
+RSpec.describe 'Issues > User sees empty state' do
let_it_be(:project) { create(:project, :public) }
let_it_be(:user) { project.creator }
diff --git a/spec/features/issues/user_sees_live_update_spec.rb b/spec/features/issues/user_sees_live_update_spec.rb
index 98c7d289fb0..c9b751715bc 100644
--- a/spec/features/issues/user_sees_live_update_spec.rb
+++ b/spec/features/issues/user_sees_live_update_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Issues > User sees live update', :js do
+RSpec.describe 'Issues > User sees live update', :js do
let_it_be(:project) { create(:project, :public) }
let_it_be(:user) { project.creator }
diff --git a/spec/features/issues/user_sees_sidebar_updates_in_realtime_spec.rb b/spec/features/issues/user_sees_sidebar_updates_in_realtime_spec.rb
index c3f17227701..7a2b637e48e 100644
--- a/spec/features/issues/user_sees_sidebar_updates_in_realtime_spec.rb
+++ b/spec/features/issues/user_sees_sidebar_updates_in_realtime_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Issues > Real-time sidebar', :js do
+RSpec.describe 'Issues > Real-time sidebar', :js do
let_it_be(:project) { create(:project, :public) }
let_it_be(:issue) { create(:issue, project: project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/features/issues/user_sorts_issue_comments_spec.rb b/spec/features/issues/user_sorts_issue_comments_spec.rb
index e1c0acc32f1..555f8827374 100644
--- a/spec/features/issues/user_sorts_issue_comments_spec.rb
+++ b/spec/features/issues/user_sorts_issue_comments_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Comment sort direction' do
+RSpec.describe 'Comment sort direction' do
let_it_be(:project) { create(:project, :public, :repository) }
let_it_be(:issue) { create(:issue, project: project) }
let_it_be(:comment_1) { create(:note_on_issue, noteable: issue, project: project, note: 'written first') }
diff --git a/spec/features/issues/user_sorts_issues_spec.rb b/spec/features/issues/user_sorts_issues_spec.rb
index 66110f55435..ec38bf99035 100644
--- a/spec/features/issues/user_sorts_issues_spec.rb
+++ b/spec/features/issues/user_sorts_issues_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User sorts issues" do
+RSpec.describe "User sorts issues" do
include SortingHelper
include IssueHelpers
diff --git a/spec/features/issues/user_toggles_subscription_spec.rb b/spec/features/issues/user_toggles_subscription_spec.rb
index ba167362511..971c8a3b431 100644
--- a/spec/features/issues/user_toggles_subscription_spec.rb
+++ b/spec/features/issues/user_toggles_subscription_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User toggles subscription", :js do
+RSpec.describe "User toggles subscription", :js do
let(:project) { create(:project_empty_repo, :public) }
let(:user) { create(:user) }
let(:issue) { create(:issue, project: project, author: user) }
diff --git a/spec/features/issues/user_uses_quick_actions_spec.rb b/spec/features/issues/user_uses_quick_actions_spec.rb
index 09f07f8c908..c5eb3f415ff 100644
--- a/spec/features/issues/user_uses_quick_actions_spec.rb
+++ b/spec/features/issues/user_uses_quick_actions_spec.rb
@@ -7,7 +7,7 @@ require 'spec_helper'
# for example, adding quick actions when creating the issue and checking DateTime formats on UI.
# Because this kind of spec takes more time to run there is no need to add new ones
# for each existing quick action unless they test something not tested by existing tests.
-describe 'Issues > User uses quick actions', :js do
+RSpec.describe 'Issues > User uses quick actions', :js do
include Spec::Support::Helpers::Features::NotesHelpers
context "issuable common quick actions" do
diff --git a/spec/features/issues/user_views_issue_spec.rb b/spec/features/issues/user_views_issue_spec.rb
index dd04ac94105..2b610bab9f0 100644
--- a/spec/features/issues/user_views_issue_spec.rb
+++ b/spec/features/issues/user_views_issue_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User views issue" do
+RSpec.describe "User views issue" do
let(:project) { create(:project_empty_repo, :public) }
let(:user) { create(:user) }
let(:issue) { create(:issue, project: project, description: "# Description header", author: user) }
@@ -35,18 +35,38 @@ describe "User views issue" do
describe 'user status' do
subject { visit(project_issue_path(project, issue)) }
- describe 'showing status of the author of the issue' do
+ context 'when showing status of the author of the issue' do
it_behaves_like 'showing user status' do
let(:user_with_status) { issue.author }
end
end
- describe 'showing status of a user who commented on an issue', :js do
+ context 'when showing status of a user who commented on an issue', :js do
let!(:note) { create(:note, noteable: issue, project: project, author: user_with_status) }
it_behaves_like 'showing user status' do
let(:user_with_status) { create(:user) }
end
end
+
+ context 'when status message has an emoji', :js do
+ let(:message) { 'My status with an emoji' }
+ let(:message_emoji) { 'basketball' }
+
+ let!(:note) { create(:note, noteable: issue, project: project, author: user) }
+ let!(:status) { create(:user_status, user: user, emoji: 'smirk', message: "#{message} :#{message_emoji}:") }
+
+ it 'correctly renders the emoji' do
+ tooltip_span = page.first(".user-status-emoji[title^='#{message}']")
+
+ tooltip_span.hover
+
+ tooltip = page.find('.tooltip .tooltip-inner')
+
+ page.within(tooltip) do
+ expect(page).to have_emoji(message_emoji)
+ end
+ end
+ end
end
end
diff --git a/spec/features/issues/user_views_issues_spec.rb b/spec/features/issues/user_views_issues_spec.rb
index 796e618c7c8..91de813e414 100644
--- a/spec/features/issues/user_views_issues_spec.rb
+++ b/spec/features/issues/user_views_issues_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User views issues" do
+RSpec.describe "User views issues" do
let!(:closed_issue) { create(:closed_issue, project: project) }
let!(:open_issue1) { create(:issue, project: project) }
let!(:open_issue2) { create(:issue, project: project) }
diff --git a/spec/features/labels_hierarchy_spec.rb b/spec/features/labels_hierarchy_spec.rb
index c66d858a019..3ab7fbea198 100644
--- a/spec/features/labels_hierarchy_spec.rb
+++ b/spec/features/labels_hierarchy_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Labels Hierarchy', :js do
+RSpec.describe 'Labels Hierarchy', :js do
include FilteredSearchHelpers
let!(:user) { create(:user) }
diff --git a/spec/features/markdown/copy_as_gfm_spec.rb b/spec/features/markdown/copy_as_gfm_spec.rb
index d40c2b8bafd..80dcdd08f74 100644
--- a/spec/features/markdown/copy_as_gfm_spec.rb
+++ b/spec/features/markdown/copy_as_gfm_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Copy as GFM', :js do
+RSpec.describe 'Copy as GFM', :js do
include MarkupHelper
include RepoHelpers
include ActionView::Helpers::JavaScriptHelper
@@ -157,7 +157,7 @@ describe 'Copy as GFM', :js do
GFM
pipeline: :wiki,
- project_wiki: @project.wiki
+ wiki: @project.wiki
)
verify(
diff --git a/spec/features/markdown/gitlab_flavored_markdown_spec.rb b/spec/features/markdown/gitlab_flavored_markdown_spec.rb
index f34af268630..da4208318eb 100644
--- a/spec/features/markdown/gitlab_flavored_markdown_spec.rb
+++ b/spec/features/markdown/gitlab_flavored_markdown_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "GitLab Flavored Markdown" do
+RSpec.describe "GitLab Flavored Markdown" do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
diff --git a/spec/features/markdown/markdown_spec.rb b/spec/features/markdown/markdown_spec.rb
index 9ebd85acb81..d9d3f566bce 100644
--- a/spec/features/markdown/markdown_spec.rb
+++ b/spec/features/markdown/markdown_spec.rb
@@ -26,7 +26,7 @@ require 'erb'
#
# See the MarkdownFeature class for setup details.
-describe 'GitLab Markdown', :aggregate_failures do
+RSpec.describe 'GitLab Markdown', :aggregate_failures do
include Capybara::Node::Matchers
include MarkupHelper
include MarkdownMatchers
@@ -269,15 +269,15 @@ describe 'GitLab Markdown', :aggregate_failures do
context 'wiki pipeline' do
before do
- @project_wiki = @feat.project_wiki
- @project_wiki_page = @feat.project_wiki_page
+ @wiki = @feat.wiki
+ @wiki_page = @feat.wiki_page
path = 'images/example.jpg'
gitaly_wiki_file = Gitlab::GitalyClient::WikiFile.new(path: path)
- expect(@project_wiki).to receive(:find_file).with(path).and_return(Gitlab::Git::WikiFile.new(gitaly_wiki_file))
- allow(@project_wiki).to receive(:wiki_base_path) { '/namespace1/gitlabhq/wikis' }
+ expect(@wiki).to receive(:find_file).with(path).and_return(Gitlab::Git::WikiFile.new(gitaly_wiki_file))
+ allow(@wiki).to receive(:wiki_base_path) { '/namespace1/gitlabhq/wikis' }
- @html = markdown(@feat.raw_markdown, { pipeline: :wiki, project_wiki: @project_wiki, page_slug: @project_wiki_page.slug })
+ @html = markdown(@feat.raw_markdown, { pipeline: :wiki, wiki: @wiki, page_slug: @wiki_page.slug })
end
it_behaves_like 'all pipelines'
diff --git a/spec/features/markdown/math_spec.rb b/spec/features/markdown/math_spec.rb
index 76eef66c517..e5fb9131ce0 100644
--- a/spec/features/markdown/math_spec.rb
+++ b/spec/features/markdown/math_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Math rendering', :js do
+RSpec.describe 'Math rendering', :js do
let!(:project) { create(:project, :public) }
it 'renders inline and display math correctly' do
diff --git a/spec/features/markdown/mermaid_spec.rb b/spec/features/markdown/mermaid_spec.rb
index 4bf7edf98ca..256dfdc26e9 100644
--- a/spec/features/markdown/mermaid_spec.rb
+++ b/spec/features/markdown/mermaid_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Mermaid rendering', :js do
+RSpec.describe 'Mermaid rendering', :js do
it 'renders Mermaid diagrams correctly' do
description = <<~MERMAID
```mermaid
@@ -118,10 +118,7 @@ describe 'Mermaid rendering', :js do
visit project_issue_path(project, issue)
- svg = page.find('svg.mermaid')
- expect(svg[:style]).to match(/max-width/)
- expect(svg[:width].to_i).to eq(100)
- expect(svg[:height].to_i).to eq(0)
+ expect(page).to have_css('svg.mermaid[style*="max-width"][width="100%"]')
end
it 'display button when diagram exceeds length', :js do
diff --git a/spec/features/markdown/metrics_spec.rb b/spec/features/markdown/metrics_spec.rb
index 7b0eb8959a5..092408c2be0 100644
--- a/spec/features/markdown/metrics_spec.rb
+++ b/spec/features/markdown/metrics_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Metrics rendering', :js, :use_clean_rails_memory_store_caching, :sidekiq_inline do
+RSpec.describe 'Metrics rendering', :js, :use_clean_rails_memory_store_caching, :sidekiq_inline do
include PrometheusHelpers
include GrafanaApiHelpers
include MetricsDashboardUrlHelpers
diff --git a/spec/features/merge_request/batch_comments_spec.rb b/spec/features/merge_request/batch_comments_spec.rb
new file mode 100644
index 00000000000..60671213d75
--- /dev/null
+++ b/spec/features/merge_request/batch_comments_spec.rb
@@ -0,0 +1,259 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Merge request > Batch comments', :js do
+ include MergeRequestDiffHelpers
+ include RepoHelpers
+
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :repository) }
+ let(:merge_request) do
+ create(:merge_request_with_diffs, source_project: project, target_project: project, source_branch: 'merge-test')
+ end
+
+ before do
+ project.add_maintainer(user)
+
+ sign_in(user)
+ end
+
+ context 'Feature is enabled' do
+ before do
+ stub_feature_flags(diffs_batch_load: false)
+
+ visit_diffs
+ end
+
+ it 'has review bar' do
+ expect(page).to have_css('.review-bar-component', visible: false)
+ end
+
+ it 'adds draft note' do
+ write_comment
+
+ expect(find('.draft-note-component')).to have_content('Line is wrong')
+
+ expect(page).to have_css('.review-bar-component')
+
+ expect(find('.review-bar-content .btn-success')).to have_content('1')
+ end
+
+ it 'publishes review' do
+ write_comment
+
+ page.within('.review-bar-content') do
+ click_button 'Finish review'
+ click_button 'Submit review'
+ end
+
+ wait_for_requests
+
+ expect(page).not_to have_selector('.draft-note-component', text: 'Line is wrong')
+
+ expect(page).to have_selector('.note:not(.draft-note)', text: 'Line is wrong')
+ end
+
+ it 'publishes single comment' do
+ write_comment
+
+ click_button 'Add comment now'
+
+ wait_for_requests
+
+ expect(page).not_to have_selector('.draft-note-component', text: 'Line is wrong')
+
+ expect(page).to have_selector('.note:not(.draft-note)', text: 'Line is wrong')
+ end
+
+ it 'discards review' do
+ write_comment
+
+ click_button 'Discard review'
+
+ click_button 'Delete all pending comments'
+
+ wait_for_requests
+
+ expect(page).not_to have_selector('.draft-note-component')
+ end
+
+ it 'deletes draft note' do
+ write_comment
+
+ accept_alert { find('.js-note-delete').click }
+
+ wait_for_requests
+
+ expect(page).not_to have_selector('.draft-note-component', text: 'Line is wrong')
+ end
+
+ it 'edits draft note' do
+ write_comment
+
+ find('.js-note-edit').click
+
+ # make sure comment form is in view
+ execute_script("window.scrollBy(0, 200)")
+
+ page.within('.js-discussion-note-form') do
+ fill_in('note_note', with: 'Testing update')
+ click_button('Save comment')
+ end
+
+ wait_for_requests
+
+ expect(page).to have_selector('.draft-note-component', text: 'Testing update')
+ end
+
+ context 'in parallel diff' do
+ before do
+ find('.js-show-diff-settings').click
+ click_button 'Side-by-side'
+ end
+
+ it 'adds draft comments to both sides' do
+ write_parallel_comment('2f6fcd96b88b36ce98c38da085c795a27d92a3dd_10_9')
+
+ # make sure line 9 is in the view
+ execute_script("window.scrollBy(0, -200)")
+
+ write_parallel_comment('2f6fcd96b88b36ce98c38da085c795a27d92a3dd_9_9', button_text: 'Add to review', text: 'Another wrong line')
+
+ expect(find('.new .draft-note-component')).to have_content('Line is wrong')
+ expect(find('.old .draft-note-component')).to have_content('Another wrong line')
+
+ expect(find('.review-bar-content .btn-success')).to have_content('2')
+ end
+ end
+
+ context 'thread is unresolved' do
+ let!(:active_discussion) { create(:diff_note_on_merge_request, noteable: merge_request, project: project).to_discussion }
+
+ before do
+ visit_diffs
+ end
+
+ it 'publishes comment right away and resolves the thread' do
+ expect(active_discussion.resolved?).to eq(false)
+
+ write_reply_to_discussion(button_text: 'Add comment now', resolve: true)
+
+ page.within '.line-resolve-all-container' do
+ expect(page).to have_content('All threads resolved')
+ expect(page).to have_selector('.line-resolve-btn.is-active')
+ end
+ end
+
+ it 'publishes review and resolves the thread' do
+ expect(active_discussion.resolved?).to eq(false)
+
+ write_reply_to_discussion(resolve: true)
+
+ page.within('.review-bar-content') do
+ click_button 'Finish review'
+ click_button 'Submit review'
+ end
+
+ wait_for_requests
+
+ page.within '.line-resolve-all-container' do
+ expect(page).to have_content('All threads resolved')
+ expect(page).to have_selector('.line-resolve-btn.is-active')
+ end
+ end
+ end
+
+ context 'thread is resolved' do
+ let!(:active_discussion) { create(:diff_note_on_merge_request, :resolved, noteable: merge_request, project: project).to_discussion }
+
+ before do
+ active_discussion.resolve!(@current_user)
+
+ visit_diffs
+
+ page.find('.js-diff-comment-avatar').click
+ end
+
+ it 'publishes comment right away and unresolves the thread' do
+ expect(active_discussion.resolved?).to eq(true)
+
+ write_reply_to_discussion(button_text: 'Add comment now', unresolve: true)
+
+ page.within '.line-resolve-all-container' do
+ expect(page).to have_content('1 unresolved thread')
+ expect(page).not_to have_selector('.line-resolve-btn.is-active')
+ end
+ end
+
+ it 'publishes review and unresolves the thread' do
+ expect(active_discussion.resolved?).to eq(true)
+
+ wait_for_requests
+
+ write_reply_to_discussion(button_text: 'Start a review', unresolve: true)
+
+ page.within('.review-bar-content') do
+ click_button 'Finish review'
+ click_button 'Submit review'
+ end
+
+ wait_for_requests
+
+ page.within '.line-resolve-all-container' do
+ expect(page).to have_content('1 unresolved thread')
+ expect(page).not_to have_selector('.line-resolve-btn.is-active')
+ end
+ end
+ end
+ end
+
+ def visit_diffs
+ visit diffs_project_merge_request_path(merge_request.project, merge_request)
+
+ wait_for_requests
+ end
+
+ def write_comment(button_text: 'Start a review', text: 'Line is wrong')
+ click_diff_line(find("[id='#{sample_compare.changes[0][:line_code]}']"))
+
+ page.within('.js-discussion-note-form') do
+ fill_in('note_note', with: text)
+ click_button(button_text)
+ end
+
+ wait_for_requests
+ end
+
+ def write_parallel_comment(line, button_text: 'Start a review', text: 'Line is wrong')
+ find("td[id='#{line}']").hover
+ find(".is-over button").click
+
+ page.within("form[data-line-code='#{line}']") do
+ fill_in('note_note', with: text)
+ click_button(button_text)
+ end
+
+ wait_for_requests
+ end
+end
+
+def write_reply_to_discussion(button_text: 'Start a review', text: 'Line is wrong', resolve: false, unresolve: false)
+ page.within(first('.diff-files-holder .discussion-reply-holder')) do
+ click_button('Reply...')
+
+ fill_in('note_note', with: text)
+
+ if resolve
+ page.check('Resolve thread')
+ end
+
+ if unresolve
+ page.check('Unresolve thread')
+ end
+
+ click_button(button_text)
+ end
+
+ wait_for_requests
+end
diff --git a/spec/features/merge_request/maintainer_edits_fork_spec.rb b/spec/features/merge_request/maintainer_edits_fork_spec.rb
index 17ff494a6fa..4db1633abe6 100644
--- a/spec/features/merge_request/maintainer_edits_fork_spec.rb
+++ b/spec/features/merge_request/maintainer_edits_fork_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'a maintainer edits files on a source-branch of an MR from a fork', :js, :sidekiq_might_not_need_inline do
+RSpec.describe 'a maintainer edits files on a source-branch of an MR from a fork', :js, :sidekiq_might_not_need_inline do
include ProjectForksHelper
let(:user) { create(:user, username: 'the-maintainer') }
let(:target_project) { create(:project, :public, :repository) }
diff --git a/spec/features/merge_request/user_accepts_merge_request_spec.rb b/spec/features/merge_request/user_accepts_merge_request_spec.rb
index 5e1ff232b80..d7c9c8bddb1 100644
--- a/spec/features/merge_request/user_accepts_merge_request_spec.rb
+++ b/spec/features/merge_request/user_accepts_merge_request_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User accepts a merge request', :js, :sidekiq_might_not_need_inline do
+RSpec.describe 'User accepts a merge request', :js, :sidekiq_might_not_need_inline do
let(:merge_request) { create(:merge_request, :with_diffs, :simple, source_project: project) }
let(:project) { create(:project, :public, :repository) }
let(:user) { create(:user) }
diff --git a/spec/features/merge_request/user_allows_commits_from_memebers_who_can_merge_spec.rb b/spec/features/merge_request/user_allows_commits_from_memebers_who_can_merge_spec.rb
index 0ecd32565d0..fd13083c185 100644
--- a/spec/features/merge_request/user_allows_commits_from_memebers_who_can_merge_spec.rb
+++ b/spec/features/merge_request/user_allows_commits_from_memebers_who_can_merge_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'create a merge request, allowing commits from members who can merge to the target branch', :js do
+RSpec.describe 'create a merge request, allowing commits from members who can merge to the target branch', :js do
include ProjectForksHelper
let(:user) { create(:user) }
let(:target_project) { create(:project, :public, :repository) }
diff --git a/spec/features/merge_request/user_assigns_themselves_spec.rb b/spec/features/merge_request/user_assigns_themselves_spec.rb
index 549d6e50337..b6cd97dcc5a 100644
--- a/spec/features/merge_request/user_assigns_themselves_spec.rb
+++ b/spec/features/merge_request/user_assigns_themselves_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User assigns themselves' do
+RSpec.describe 'Merge request > User assigns themselves' do
let(:project) { create(:project, :public, :repository) }
let(:user) { project.creator }
let(:issue1) { create(:issue, project: project) }
diff --git a/spec/features/merge_request/user_awards_emoji_spec.rb b/spec/features/merge_request/user_awards_emoji_spec.rb
index 8aa90107251..62e4209f386 100644
--- a/spec/features/merge_request/user_awards_emoji_spec.rb
+++ b/spec/features/merge_request/user_awards_emoji_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User awards emoji', :js do
+RSpec.describe 'Merge request > User awards emoji', :js do
let(:project) { create(:project, :public, :repository) }
let(:user) { project.creator }
let(:merge_request) { create(:merge_request, source_project: project, author: create(:user)) }
diff --git a/spec/features/merge_request/user_clicks_merge_request_tabs_spec.rb b/spec/features/merge_request/user_clicks_merge_request_tabs_spec.rb
new file mode 100644
index 00000000000..f3cbc1ea1f5
--- /dev/null
+++ b/spec/features/merge_request/user_clicks_merge_request_tabs_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'User clicks on merge request tabs', :js do
+ let(:project) { create(:project, :public, :repository) }
+ let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
+
+ it 'adds entry to page history' do
+ visit('/')
+ visit(merge_request_path(merge_request))
+ click_link('Changes')
+
+ expect(current_url).to match(/diffs$/)
+
+ page.driver.go_back
+
+ expect(current_url).to match(merge_request_path(merge_request))
+
+ page.driver.go_back
+
+ expect(current_url).to match('/')
+ end
+end
diff --git a/spec/features/merge_request/user_closes_merge_request_spec.rb b/spec/features/merge_request/user_closes_merge_request_spec.rb
index c5125c38ed7..669bd989f4f 100644
--- a/spec/features/merge_request/user_closes_merge_request_spec.rb
+++ b/spec/features/merge_request/user_closes_merge_request_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User closes a merge requests', :js do
+RSpec.describe 'User closes a merge requests', :js do
let(:project) { create(:project, :repository) }
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
let(:user) { create(:user) }
diff --git a/spec/features/merge_request/user_comments_on_commit_spec.rb b/spec/features/merge_request/user_comments_on_commit_spec.rb
index 6b869d93e4c..8fa1fe3812d 100644
--- a/spec/features/merge_request/user_comments_on_commit_spec.rb
+++ b/spec/features/merge_request/user_comments_on_commit_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User comments on a commit', :js do
+RSpec.describe 'User comments on a commit', :js do
include MergeRequestDiffHelpers
include RepoHelpers
diff --git a/spec/features/merge_request/user_comments_on_diff_spec.rb b/spec/features/merge_request/user_comments_on_diff_spec.rb
index 19b8a7f74b7..9cd3c7eaf76 100644
--- a/spec/features/merge_request/user_comments_on_diff_spec.rb
+++ b/spec/features/merge_request/user_comments_on_diff_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User comments on a diff', :js do
+RSpec.describe 'User comments on a diff', :js do
include MergeRequestDiffHelpers
include RepoHelpers
@@ -27,7 +27,7 @@ describe 'User comments on a diff', :js do
page.within('.js-discussion-note-form') do
fill_in('note_note', with: 'Line is wrong')
- click_button('Comment')
+ click_button('Add comment now')
end
page.within('.diff-files-holder > div:nth-child(3)') do
@@ -46,7 +46,7 @@ describe 'User comments on a diff', :js do
page.within('.js-discussion-note-form') do
fill_in('note_note', with: 'Line is correct')
- click_button('Comment')
+ click_button('Add comment now')
end
wait_for_requests
@@ -59,7 +59,7 @@ describe 'User comments on a diff', :js do
page.within('.js-discussion-note-form') do
fill_in('note_note', with: 'Line is wrong')
- click_button('Comment')
+ click_button('Add comment now')
end
wait_for_requests
@@ -114,13 +114,47 @@ describe 'User comments on a diff', :js do
include_examples 'comment on merge request file'
end
+ context 'when adding multiline comments' do
+ it 'saves a multiline comment' do
+ click_diff_line(find("[id='#{sample_commit.line_code}']"))
+
+ page.within('.discussion-form') do
+ find('#comment-line-start option', text: '-13').select_option
+ end
+
+ page.within('.js-discussion-note-form') do
+ fill_in(:note_note, with: 'Line is wrong')
+ click_button('Add comment now')
+ end
+
+ wait_for_requests
+
+ page.within('.notes_holder') do
+ expect(page).to have_content('Line is wrong')
+ expect(page).to have_content('Comment on lines -13 to +14')
+ end
+
+ visit(merge_request_path(merge_request))
+
+ page.within('.notes .discussion') do
+ expect(page).to have_content("#{user.name} #{user.to_reference} started a thread")
+ expect(page).to have_content(sample_commit.line_code_path)
+ expect(page).to have_content('Line is wrong')
+ end
+
+ page.within('.notes-tab .badge') do
+ expect(page).to have_content('1')
+ end
+ end
+ end
+
context 'when editing comments' do
it 'edits a comment' do
click_diff_line(find("[id='#{sample_commit.line_code}']"))
page.within('.js-discussion-note-form') do
fill_in(:note_note, with: 'Line is wrong')
- click_button('Comment')
+ click_button('Add comment now')
end
page.within('.diff-file:nth-of-type(5) .discussion .note') do
@@ -146,7 +180,7 @@ describe 'User comments on a diff', :js do
page.within('.js-discussion-note-form') do
fill_in(:note_note, with: 'Line is wrong')
- click_button('Comment')
+ click_button('Add comment now')
end
page.within('.notes-tab .badge') do
diff --git a/spec/features/merge_request/user_comments_on_merge_request_spec.rb b/spec/features/merge_request/user_comments_on_merge_request_spec.rb
index c7845b4cce4..73f2b1a25ce 100644
--- a/spec/features/merge_request/user_comments_on_merge_request_spec.rb
+++ b/spec/features/merge_request/user_comments_on_merge_request_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User comments on a merge request', :js do
+RSpec.describe 'User comments on a merge request', :js do
include RepoHelpers
let(:project) { create(:project, :repository) }
diff --git a/spec/features/merge_request/user_creates_image_diff_notes_spec.rb b/spec/features/merge_request/user_creates_image_diff_notes_spec.rb
index cea9056cd93..34eaca24a01 100644
--- a/spec/features/merge_request/user_creates_image_diff_notes_spec.rb
+++ b/spec/features/merge_request/user_creates_image_diff_notes_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User creates image diff notes', :js do
+RSpec.describe 'Merge request > User creates image diff notes', :js do
include NoteInteractionHelpers
let(:project) { create(:project, :public, :repository) }
diff --git a/spec/features/merge_request/user_creates_merge_request_spec.rb b/spec/features/merge_request/user_creates_merge_request_spec.rb
index 86ee9fa5aa5..37d329d4d5d 100644
--- a/spec/features/merge_request/user_creates_merge_request_spec.rb
+++ b/spec/features/merge_request/user_creates_merge_request_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User creates a merge request", :js do
+RSpec.describe "User creates a merge request", :js do
include ProjectForksHelper
let_it_be(:project) { create(:project, :repository) }
diff --git a/spec/features/merge_request/user_creates_mr_spec.rb b/spec/features/merge_request/user_creates_mr_spec.rb
index 665bc352c0f..9d97e57fe3a 100644
--- a/spec/features/merge_request/user_creates_mr_spec.rb
+++ b/spec/features/merge_request/user_creates_mr_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User creates MR' do
+RSpec.describe 'Merge request > User creates MR' do
include ProjectForksHelper
before do
diff --git a/spec/features/merge_request/user_customizes_merge_commit_message_spec.rb b/spec/features/merge_request/user_customizes_merge_commit_message_spec.rb
index 895cbb8f02b..23df7635aa1 100644
--- a/spec/features/merge_request/user_customizes_merge_commit_message_spec.rb
+++ b/spec/features/merge_request/user_customizes_merge_commit_message_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request < User customizes merge commit message', :js do
+RSpec.describe 'Merge request < User customizes merge commit message', :js do
let(:project) { create(:project, :public, :repository) }
let(:user) { project.creator }
let(:issue_1) { create(:issue, project: project)}
diff --git a/spec/features/merge_request/user_edits_assignees_sidebar_spec.rb b/spec/features/merge_request/user_edits_assignees_sidebar_spec.rb
index e6b77e28281..affd6f6b7b5 100644
--- a/spec/features/merge_request/user_edits_assignees_sidebar_spec.rb
+++ b/spec/features/merge_request/user_edits_assignees_sidebar_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User edits assignees sidebar', :js do
+RSpec.describe 'Merge request > User edits assignees sidebar', :js do
let(:project) { create(:project, :public, :repository) }
let(:protected_branch) { create(:protected_branch, :maintainers_can_push, name: 'master', project: project) }
let(:merge_request) { create(:merge_request, :simple, source_project: project, target_branch: protected_branch.name) }
@@ -20,49 +20,102 @@ describe 'Merge request > User edits assignees sidebar', :js do
let(:sidebar_assignee_dropdown_item) { sidebar_assignee_block.find(".dropdown-menu li[data-user-id=\"#{assignee.id}\"]") }
let(:sidebar_assignee_dropdown_tooltip) { sidebar_assignee_dropdown_item.find('a')['data-title'] || '' }
- before do
- stub_const('Autocomplete::UsersFinder::LIMIT', users_find_limit)
+ context 'when invite_members_version_a experiment is not enabled' do
+ before do
+ stub_const('Autocomplete::UsersFinder::LIMIT', users_find_limit)
- sign_in(project.owner)
+ sign_in(project.owner)
- merge_request.assignees << assignee
+ merge_request.assignees << assignee
- visit project_merge_request_path(project, merge_request)
+ visit project_merge_request_path(project, merge_request)
- wait_for_requests
- end
+ wait_for_requests
+ end
+
+ shared_examples 'when assigned' do |expected_tooltip: ''|
+ it 'shows assignee name' do
+ expect(sidebar_assignee_block).to have_text(assignee.name)
+ end
+
+ it "shows assignee tooltip '#{expected_tooltip}'" do
+ expect(sidebar_assignee_tooltip).to eql(expected_tooltip)
+ end
+
+ context 'when edit is clicked' do
+ before do
+ sidebar_assignee_block.click_link('Edit')
+
+ wait_for_requests
+ end
+
+ it "shows assignee tooltip '#{expected_tooltip}" do
+ expect(sidebar_assignee_dropdown_tooltip).to eql(expected_tooltip)
+ end
+
+ it 'does not show invite link' do
+ page.within '.dropdown-menu-user' do
+ expect(page).not_to have_link('Invite Members')
+ end
+ end
+ end
+ end
+
+ context 'when assigned to maintainer' do
+ let(:assignee) { project_maintainers.last }
- shared_examples 'when assigned' do |expected_tooltip: ''|
- it 'shows assignee name' do
- expect(sidebar_assignee_block).to have_text(assignee.name)
+ it_behaves_like 'when assigned', expected_tooltip: ''
end
- it "shows assignee tooltip '#{expected_tooltip}'" do
- expect(sidebar_assignee_tooltip).to eql(expected_tooltip)
+ context 'when assigned to developer' do
+ let(:assignee) { project_developers.last }
+
+ it_behaves_like 'when assigned', expected_tooltip: 'Cannot merge'
end
+ end
- context 'when edit is clicked' do
+ context 'when invite_members_version_a experiment is enabled' do
+ let_it_be(:user) { create(:user) }
+
+ before do
+ stub_experiment_for_user(invite_members_version_a: true)
+ sign_in(user)
+ end
+
+ context 'when user can not see invite members' do
before do
- sidebar_assignee_block.click_link('Edit')
+ project.add_developer(user)
+ visit project_merge_request_path(project, merge_request)
+
+ find('.block.assignee .edit-link').click
wait_for_requests
end
- it "shows assignee tooltip '#{expected_tooltip}" do
- expect(sidebar_assignee_dropdown_tooltip).to eql(expected_tooltip)
+ it 'does not see link to invite members' do
+ page.within '.dropdown-menu-user' do
+ expect(page).not_to have_link('Invite Members')
+ end
end
end
- end
- context 'when assigned to maintainer' do
- let(:assignee) { project_maintainers.last }
+ context 'when user can see invite members' do
+ before do
+ project.add_maintainer(user)
+ visit project_merge_request_path(project, merge_request)
- it_behaves_like 'when assigned', expected_tooltip: ''
- end
+ find('.block.assignee .edit-link').click
- context 'when assigned to developer' do
- let(:assignee) { project_developers.last }
+ wait_for_requests
+ end
- it_behaves_like 'when assigned', expected_tooltip: 'Cannot merge'
+ it 'sees link to invite members' do
+ page.within '.dropdown-menu-user' do
+ expect(page).to have_link('Invite Members', href: project_project_members_path(project))
+ expect(page).to have_selector('[data-track-event="click_invite_members"]')
+ expect(page).to have_selector("[data-track-label='edit_assignee']")
+ end
+ end
+ end
end
end
diff --git a/spec/features/merge_request/user_edits_merge_request_spec.rb b/spec/features/merge_request/user_edits_merge_request_spec.rb
index 821db8a1d5b..84ecd6537dc 100644
--- a/spec/features/merge_request/user_edits_merge_request_spec.rb
+++ b/spec/features/merge_request/user_edits_merge_request_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User edits a merge request', :js do
+RSpec.describe 'User edits a merge request', :js do
include Select2Helper
let(:project) { create(:project, :repository) }
diff --git a/spec/features/merge_request/user_edits_mr_spec.rb b/spec/features/merge_request/user_edits_mr_spec.rb
index e6b847c5e7f..2c949ed84f4 100644
--- a/spec/features/merge_request/user_edits_mr_spec.rb
+++ b/spec/features/merge_request/user_edits_mr_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User edits MR' do
+RSpec.describe 'Merge request > User edits MR' do
include ProjectForksHelper
before do
diff --git a/spec/features/merge_request/user_expands_diff_spec.rb b/spec/features/merge_request/user_expands_diff_spec.rb
index 9bce5264817..d3867a91846 100644
--- a/spec/features/merge_request/user_expands_diff_spec.rb
+++ b/spec/features/merge_request/user_expands_diff_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User expands diff', :js do
+RSpec.describe 'User expands diff', :js do
let(:project) { create(:project, :public, :repository) }
let(:merge_request) { create(:merge_request, source_branch: 'expand-collapse-files', source_project: project, target_project: project) }
diff --git a/spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb b/spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb
index 2a4192374bd..1a7baff2fb1 100644
--- a/spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb
+++ b/spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Batch diffs', :js do
+RSpec.describe 'Batch diffs', :js do
include MergeRequestDiffHelpers
include RepoHelpers
@@ -22,14 +22,14 @@ describe 'Batch diffs', :js do
click_diff_line(find('.diff-file.file-holder:first-of-type tr.line_holder.new:first-of-type'))
page.within('.js-discussion-note-form') do
fill_in('note_note', with: 'First Line Comment')
- click_button('Comment')
+ click_button('Add comment now')
end
# Add discussion to first line of last file
click_diff_line(find('.diff-file.file-holder:last-of-type tr.line_holder.new:first-of-type'))
page.within('.js-discussion-note-form') do
fill_in('note_note', with: 'Last Line Comment')
- click_button('Comment')
+ click_button('Add comment now')
end
wait_for_requests
diff --git a/spec/features/merge_request/user_locks_discussion_spec.rb b/spec/features/merge_request/user_locks_discussion_spec.rb
index 0eaaf32dc31..c8a6fdd4007 100644
--- a/spec/features/merge_request/user_locks_discussion_spec.rb
+++ b/spec/features/merge_request/user_locks_discussion_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User locks discussion', :js do
+RSpec.describe 'Merge request > User locks discussion', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :public, :repository) }
let(:merge_request) { create(:merge_request, source_project: project) }
diff --git a/spec/features/merge_request/user_manages_subscription_spec.rb b/spec/features/merge_request/user_manages_subscription_spec.rb
index 54d27a06bb1..9ed5b67fa0e 100644
--- a/spec/features/merge_request/user_manages_subscription_spec.rb
+++ b/spec/features/merge_request/user_manages_subscription_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User manages subscription', :js do
+RSpec.describe 'User manages subscription', :js do
let(:project) { create(:project, :public, :repository) }
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
let(:user) { create(:user) }
diff --git a/spec/features/merge_request/user_merges_immediately_spec.rb b/spec/features/merge_request/user_merges_immediately_spec.rb
index 1188d3b2ceb..47dc09ae79f 100644
--- a/spec/features/merge_request/user_merges_immediately_spec.rb
+++ b/spec/features/merge_request/user_merges_immediately_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge requests > User merges immediately', :js do
+RSpec.describe 'Merge requests > User merges immediately', :js do
let(:project) { create(:project, :public, :repository) }
let(:user) { project.creator }
let!(:merge_request) do
diff --git a/spec/features/merge_request/user_merges_merge_request_spec.rb b/spec/features/merge_request/user_merges_merge_request_spec.rb
index 32e40740a61..7758fa8e666 100644
--- a/spec/features/merge_request/user_merges_merge_request_spec.rb
+++ b/spec/features/merge_request/user_merges_merge_request_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User merges a merge request", :js do
+RSpec.describe "User merges a merge request", :js do
let(:user) { project.owner }
before do
diff --git a/spec/features/merge_request/user_merges_only_if_pipeline_succeeds_spec.rb b/spec/features/merge_request/user_merges_only_if_pipeline_succeeds_spec.rb
index 419f741d0ea..ea3e90a4508 100644
--- a/spec/features/merge_request/user_merges_only_if_pipeline_succeeds_spec.rb
+++ b/spec/features/merge_request/user_merges_only_if_pipeline_succeeds_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User merges only if pipeline succeeds', :js do
+RSpec.describe 'Merge request > User merges only if pipeline succeeds', :js do
let(:merge_request) { create(:merge_request_with_diffs) }
let(:project) { merge_request.target_project }
diff --git a/spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb b/spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb
index 5cc61333bb4..d5ff31de073 100644
--- a/spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb
+++ b/spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User merges when pipeline succeeds', :js do
+RSpec.describe 'Merge request > User merges when pipeline succeeds', :js do
let(:project) { create(:project, :public, :repository) }
let(:user) { project.creator }
let(:merge_request) do
diff --git a/spec/features/merge_request/user_posts_diff_notes_spec.rb b/spec/features/merge_request/user_posts_diff_notes_spec.rb
index ebfb5ce796f..dbad2f191a1 100644
--- a/spec/features/merge_request/user_posts_diff_notes_spec.rb
+++ b/spec/features/merge_request/user_posts_diff_notes_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User posts diff notes', :js do
+RSpec.describe 'Merge request > User posts diff notes', :js do
include MergeRequestDiffHelpers
let(:merge_request) { create(:merge_request) }
@@ -225,7 +225,7 @@ describe 'Merge request > User posts diff notes', :js do
def should_allow_commenting(line_holder, diff_side = nil, asset_form_reset: true)
write_comment_on_line(line_holder, diff_side)
- click_button 'Comment'
+ click_button 'Add comment now'
wait_for_requests
diff --git a/spec/features/merge_request/user_posts_notes_spec.rb b/spec/features/merge_request/user_posts_notes_spec.rb
index 0548d958322..3c70819319d 100644
--- a/spec/features/merge_request/user_posts_notes_spec.rb
+++ b/spec/features/merge_request/user_posts_notes_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User posts notes', :js do
+RSpec.describe 'Merge request > User posts notes', :js do
include NoteInteractionHelpers
let_it_be(:project) { create(:project, :repository) }
@@ -105,7 +105,7 @@ describe 'Merge request > User posts notes', :js do
page.within('.discussion-reply-holder') do
fill_in 'note[note]', with: 'A reply'
- click_button 'Comment'
+ click_button 'Add comment now'
wait_for_requests
expect(page).to have_content('Your comment could not be submitted because discussion to reply to cannot be found')
end
diff --git a/spec/features/merge_request/user_rebases_merge_request_spec.rb b/spec/features/merge_request/user_rebases_merge_request_spec.rb
index 34f009000dc..a3f72a6266b 100644
--- a/spec/features/merge_request/user_rebases_merge_request_spec.rb
+++ b/spec/features/merge_request/user_rebases_merge_request_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User rebases a merge request", :js do
+RSpec.describe "User rebases a merge request", :js do
let(:merge_request) { create(:merge_request, :simple, source_project: project) }
let(:user) { project.owner }
diff --git a/spec/features/merge_request/user_reopens_merge_request_spec.rb b/spec/features/merge_request/user_reopens_merge_request_spec.rb
index 6dee5770d0c..020929dc416 100644
--- a/spec/features/merge_request/user_reopens_merge_request_spec.rb
+++ b/spec/features/merge_request/user_reopens_merge_request_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User reopens a merge requests', :js do
+RSpec.describe 'User reopens a merge requests', :js do
let(:project) { create(:project, :public, :repository) }
let!(:merge_request) { create(:closed_merge_request, source_project: project, target_project: project) }
let(:user) { create(:user) }
diff --git a/spec/features/merge_request/user_resolves_conflicts_spec.rb b/spec/features/merge_request/user_resolves_conflicts_spec.rb
index 41a7456aed5..f96408fb10b 100644
--- a/spec/features/merge_request/user_resolves_conflicts_spec.rb
+++ b/spec/features/merge_request/user_resolves_conflicts_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User resolves conflicts', :js do
+RSpec.describe 'Merge request > User resolves conflicts', :js do
let(:project) { create(:project, :repository) }
let(:user) { project.creator }
diff --git a/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb b/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb
index 0e30df518d7..aa3840b4376 100644
--- a/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb
+++ b/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User resolves diff notes and threads', :js do
+RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
let(:project) { create(:project, :public, :repository) }
let(:user) { project.creator }
let(:guest) { create(:user) }
@@ -146,17 +146,16 @@ describe 'Merge request > User resolves diff notes and threads', :js do
describe 'reply form' do
before do
click_button 'Toggle thread'
-
- page.within '.diff-content' do
- click_button 'Reply...'
- end
end
it 'allows user to comment' do
page.within '.diff-content' do
+ click_button 'Reply...'
+
+ find(".js-unresolve-checkbox").set false
find('.js-note-text').set 'testing'
- click_button 'Comment'
+ click_button 'Add comment now'
wait_for_requests
end
@@ -181,9 +180,11 @@ describe 'Merge request > User resolves diff notes and threads', :js do
it 'allows user to comment & unresolve thread' do
page.within '.diff-content' do
+ click_button 'Reply...'
+
find('.js-note-text').set 'testing'
- click_button 'Comment & unresolve thread'
+ click_button 'Add comment now'
wait_for_requests
end
@@ -197,8 +198,6 @@ describe 'Merge request > User resolves diff notes and threads', :js do
it 'allows user to resolve from reply form without a comment' do
page.within '.diff-content' do
- click_button 'Reply...'
-
click_button 'Resolve thread'
end
@@ -214,7 +213,9 @@ describe 'Merge request > User resolves diff notes and threads', :js do
find('.js-note-text').set 'testing'
- click_button 'Comment & resolve thread'
+ find('.js-resolve-checkbox').set(true)
+
+ click_button 'Add comment now'
end
page.within '.line-resolve-all-container' do
@@ -445,7 +446,9 @@ describe 'Merge request > User resolves diff notes and threads', :js do
find('.js-note-text').set 'testing'
- click_button 'Comment & resolve thread'
+ find('.js-resolve-checkbox').set(true)
+
+ click_button 'Add comment now'
end
page.within '.line-resolve-all-container' do
@@ -462,7 +465,7 @@ describe 'Merge request > User resolves diff notes and threads', :js do
find('.js-note-text').set 'testing'
- click_button 'Comment & unresolve thread'
+ click_button 'Add comment now'
end
page.within '.line-resolve-all-container' do
diff --git a/spec/features/merge_request/user_resolves_outdated_diff_discussions_spec.rb b/spec/features/merge_request/user_resolves_outdated_diff_discussions_spec.rb
index 9f7c97e510c..f8f3467f6fb 100644
--- a/spec/features/merge_request/user_resolves_outdated_diff_discussions_spec.rb
+++ b/spec/features/merge_request/user_resolves_outdated_diff_discussions_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User resolves outdated diff discussions', :js do
+RSpec.describe 'Merge request > User resolves outdated diff discussions', :js do
let(:project) { create(:project, :repository, :public) }
let(:merge_request) do
diff --git a/spec/features/merge_request/user_resolves_wip_mr_spec.rb b/spec/features/merge_request/user_resolves_wip_mr_spec.rb
index 93ef0801791..34a3490a152 100644
--- a/spec/features/merge_request/user_resolves_wip_mr_spec.rb
+++ b/spec/features/merge_request/user_resolves_wip_mr_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User resolves Work in Progress', :js do
+RSpec.describe 'Merge request > User resolves Work in Progress', :js do
let(:project) { create(:project, :public, :repository) }
let(:user) { project.creator }
let(:merge_request) do
diff --git a/spec/features/merge_request/user_reverts_merge_request_spec.rb b/spec/features/merge_request/user_reverts_merge_request_spec.rb
index 906ff1d61b2..5e9611de460 100644
--- a/spec/features/merge_request/user_reverts_merge_request_spec.rb
+++ b/spec/features/merge_request/user_reverts_merge_request_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User reverts a merge request', :js do
+RSpec.describe 'User reverts a merge request', :js do
let(:merge_request) { create(:merge_request, :with_diffs, :simple, source_project: project) }
let(:project) { create(:project, :public, :repository) }
let(:user) { create(:user) }
diff --git a/spec/features/merge_request/user_reviews_image_spec.rb b/spec/features/merge_request/user_reviews_image_spec.rb
new file mode 100644
index 00000000000..533f3c9c91a
--- /dev/null
+++ b/spec/features/merge_request/user_reviews_image_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Merge request > image review', :js do
+ include MergeRequestDiffHelpers
+ include RepoHelpers
+
+ let(:user) { project.owner }
+ let(:project) { create(:project, :repository) }
+ let(:merge_request) { create(:merge_request_with_diffs, :with_image_diffs, source_project: project, author: user) }
+
+ before do
+ sign_in(user)
+
+ allow_any_instance_of(DiffHelper).to receive(:diff_file_blob_raw_url).and_return('/apple-touch-icon.png')
+ allow_any_instance_of(DiffHelper).to receive(:diff_file_old_blob_raw_url).and_return('/favicon.png')
+
+ visit diffs_project_merge_request_path(merge_request.project, merge_request)
+
+ wait_for_requests
+ end
+
+ it 'leaves review' do
+ find('.js-add-image-diff-note-button', match: :first).click
+
+ find('.diff-content .note-textarea').native.send_keys('image diff test comment')
+
+ click_button('Start a review')
+
+ wait_for_requests
+
+ page.within(find('.draft-note-component')) do
+ expect(page).to have_content('image diff test comment')
+ end
+ end
+end
diff --git a/spec/features/merge_request/user_scrolls_to_note_on_load_spec.rb b/spec/features/merge_request/user_scrolls_to_note_on_load_spec.rb
index 48c3ed7178d..d9950f5504b 100644
--- a/spec/features/merge_request/user_scrolls_to_note_on_load_spec.rb
+++ b/spec/features/merge_request/user_scrolls_to_note_on_load_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User scrolls to note on load', :js do
+RSpec.describe 'Merge request > User scrolls to note on load', :js do
let(:project) { create(:project, :public, :repository) }
let(:user) { project.creator }
let(:merge_request) { create(:merge_request, source_project: project, author: user) }
diff --git a/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb b/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb
index 21599164ac3..415e6b29d5a 100644
--- a/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb
+++ b/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User sees avatars on diff notes', :js do
+RSpec.describe 'Merge request > User sees avatars on diff notes', :js do
include NoteInteractionHelpers
let(:project) { create(:project, :public, :repository) }
@@ -42,7 +42,7 @@ describe 'Merge request > User sees avatars on diff notes', :js do
page.within('.js-discussion-note-form') do
find('.note-textarea').native.send_keys('Test comment')
- click_button 'Comment'
+ click_button 'Add comment now'
end
expect(page).to have_content('Test comment')
@@ -137,7 +137,7 @@ describe 'Merge request > User sees avatars on diff notes', :js do
page.within '.js-discussion-note-form' do
find('.js-note-text').native.send_keys('Test')
- click_button 'Comment'
+ click_button 'Add comment now'
wait_for_requests
end
@@ -155,7 +155,7 @@ describe 'Merge request > User sees avatars on diff notes', :js do
page.within '.js-discussion-note-form' do
find('.js-note-text').native.send_keys('Test')
- find('.js-comment-button').click
+ click_button 'Add comment now'
wait_for_requests
end
diff --git a/spec/features/merge_request/user_sees_breadcrumb_links_spec.rb b/spec/features/merge_request/user_sees_breadcrumb_links_spec.rb
index 592ad3aae9b..95e435a333e 100644
--- a/spec/features/merge_request/user_sees_breadcrumb_links_spec.rb
+++ b/spec/features/merge_request/user_sees_breadcrumb_links_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'New merge request breadcrumb' do
+RSpec.describe 'New merge request breadcrumb' do
let(:project) { create(:project, :repository) }
let(:user) { project.creator }
diff --git a/spec/features/merge_request/user_sees_check_out_branch_modal_spec.rb b/spec/features/merge_request/user_sees_check_out_branch_modal_spec.rb
index f54161fbaec..e47f9ff2660 100644
--- a/spec/features/merge_request/user_sees_check_out_branch_modal_spec.rb
+++ b/spec/features/merge_request/user_sees_check_out_branch_modal_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User sees check out branch modal', :js do
+RSpec.describe 'Merge request > User sees check out branch modal', :js do
let(:project) { create(:project, :public, :repository) }
let(:user) { project.creator }
let(:merge_request) { create(:merge_request, source_project: project) }
diff --git a/spec/features/merge_request/user_sees_cherry_pick_modal_spec.rb b/spec/features/merge_request/user_sees_cherry_pick_modal_spec.rb
index d7675cd06a8..ec2fb856be5 100644
--- a/spec/features/merge_request/user_sees_cherry_pick_modal_spec.rb
+++ b/spec/features/merge_request/user_sees_cherry_pick_modal_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User cherry-picks', :js do
+RSpec.describe 'Merge request > User cherry-picks', :js do
let(:group) { create(:group) }
let(:project) { create(:project, :repository, namespace: group) }
let(:user) { project.creator }
diff --git a/spec/features/merge_request/user_sees_closing_issues_message_spec.rb b/spec/features/merge_request/user_sees_closing_issues_message_spec.rb
index f77ea82649c..baef547a480 100644
--- a/spec/features/merge_request/user_sees_closing_issues_message_spec.rb
+++ b/spec/features/merge_request/user_sees_closing_issues_message_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User sees closing issues message', :js do
+RSpec.describe 'Merge request > User sees closing issues message', :js do
let(:project) { create(:project, :public, :repository) }
let(:user) { project.creator }
let(:issue_1) { create(:issue, project: project)}
diff --git a/spec/features/merge_request/user_sees_deleted_target_branch_spec.rb b/spec/features/merge_request/user_sees_deleted_target_branch_spec.rb
index 9ef6847f7f5..7c93952ee99 100644
--- a/spec/features/merge_request/user_sees_deleted_target_branch_spec.rb
+++ b/spec/features/merge_request/user_sees_deleted_target_branch_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User sees deleted target branch', :js do
+RSpec.describe 'Merge request > User sees deleted target branch', :js do
let(:merge_request) { create(:merge_request) }
let(:project) { merge_request.project }
let(:user) { project.creator }
diff --git a/spec/features/merge_request/user_sees_deployment_widget_spec.rb b/spec/features/merge_request/user_sees_deployment_widget_spec.rb
index 9670bd798bf..1e547d504ef 100644
--- a/spec/features/merge_request/user_sees_deployment_widget_spec.rb
+++ b/spec/features/merge_request/user_sees_deployment_widget_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User sees deployment widget', :js do
+RSpec.describe 'Merge request > User sees deployment widget', :js do
describe 'when merge request has associated environments' do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
diff --git a/spec/features/merge_request/user_sees_diff_spec.rb b/spec/features/merge_request/user_sees_diff_spec.rb
index 868451883d8..2229b242d5b 100644
--- a/spec/features/merge_request/user_sees_diff_spec.rb
+++ b/spec/features/merge_request/user_sees_diff_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User sees diff', :js do
+RSpec.describe 'Merge request > User sees diff', :js do
include ProjectForksHelper
include RepoHelpers
diff --git a/spec/features/merge_request/user_sees_discussions_spec.rb b/spec/features/merge_request/user_sees_discussions_spec.rb
index b4afd8c6332..ca8c4f84677 100644
--- a/spec/features/merge_request/user_sees_discussions_spec.rb
+++ b/spec/features/merge_request/user_sees_discussions_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User sees threads', :js do
+RSpec.describe 'Merge request > User sees threads', :js do
let(:project) { create(:project, :public, :repository) }
let(:user) { project.creator }
let(:merge_request) { create(:merge_request, source_project: project) }
diff --git a/spec/features/merge_request/user_sees_empty_state_spec.rb b/spec/features/merge_request/user_sees_empty_state_spec.rb
index 88eba976d62..ac07b31731d 100644
--- a/spec/features/merge_request/user_sees_empty_state_spec.rb
+++ b/spec/features/merge_request/user_sees_empty_state_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User sees empty state' do
+RSpec.describe 'Merge request > User sees empty state' do
let(:project) { create(:project, :public, :repository) }
let(:user) { project.creator }
diff --git a/spec/features/merge_request/user_sees_merge_button_depending_on_unresolved_discussions_spec.rb b/spec/features/merge_request/user_sees_merge_button_depending_on_unresolved_discussions_spec.rb
index 4cc129e5d5f..cae04dd1693 100644
--- a/spec/features/merge_request/user_sees_merge_button_depending_on_unresolved_discussions_spec.rb
+++ b/spec/features/merge_request/user_sees_merge_button_depending_on_unresolved_discussions_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User sees merge button depending on unresolved threads', :js do
+RSpec.describe 'Merge request > User sees merge button depending on unresolved threads', :js do
let(:project) { create(:project, :repository) }
let(:user) { project.creator }
let!(:merge_request) { create(:merge_request_with_diff_notes, source_project: project, author: user) }
diff --git a/spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb b/spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb
index 5b14450a289..e2aa10d80dd 100644
--- a/spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb
+++ b/spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User sees pipelines triggered by merge request', :js do
+RSpec.describe 'Merge request > User sees pipelines triggered by merge request', :js do
include ProjectForksHelper
include TestReportsHelper
diff --git a/spec/features/merge_request/user_sees_merge_widget_spec.rb b/spec/features/merge_request/user_sees_merge_widget_spec.rb
index eca011bc786..bd140a0643d 100644
--- a/spec/features/merge_request/user_sees_merge_widget_spec.rb
+++ b/spec/features/merge_request/user_sees_merge_widget_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User sees merge widget', :js do
+RSpec.describe 'Merge request > User sees merge widget', :js do
include ProjectForksHelper
include TestReportsHelper
include ReactiveCachingHelpers
diff --git a/spec/features/merge_request/user_sees_mini_pipeline_graph_spec.rb b/spec/features/merge_request/user_sees_mini_pipeline_graph_spec.rb
index 29b8dc19860..04d8c52df61 100644
--- a/spec/features/merge_request/user_sees_mini_pipeline_graph_spec.rb
+++ b/spec/features/merge_request/user_sees_mini_pipeline_graph_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request < User sees mini pipeline graph', :js do
+RSpec.describe 'Merge request < User sees mini pipeline graph', :js do
let(:project) { create(:project, :public, :repository) }
let(:user) { project.creator }
let(:merge_request) { create(:merge_request, source_project: project, head_pipeline: pipeline) }
diff --git a/spec/features/merge_request/user_sees_mr_from_deleted_forked_project_spec.rb b/spec/features/merge_request/user_sees_mr_from_deleted_forked_project_spec.rb
index b4fb844b943..cbd68025b50 100644
--- a/spec/features/merge_request/user_sees_mr_from_deleted_forked_project_spec.rb
+++ b/spec/features/merge_request/user_sees_mr_from_deleted_forked_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User sees MR from deleted forked project', :js do
+RSpec.describe 'Merge request > User sees MR from deleted forked project', :js do
include ProjectForksHelper
let(:project) { create(:project, :public, :repository) }
diff --git a/spec/features/merge_request/user_sees_mr_with_deleted_source_branch_spec.rb b/spec/features/merge_request/user_sees_mr_with_deleted_source_branch_spec.rb
index 59e5f5c847d..e997fb3e853 100644
--- a/spec/features/merge_request/user_sees_mr_with_deleted_source_branch_spec.rb
+++ b/spec/features/merge_request/user_sees_mr_with_deleted_source_branch_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
# This test serves as a regression test for a bug that caused an error
# message to be shown by JavaScript when the source branch was deleted.
# Please do not remove ":js".
-describe 'Merge request > User sees MR with deleted source branch', :js do
+RSpec.describe 'Merge request > User sees MR with deleted source branch', :js do
let(:project) { create(:project, :public, :repository) }
let(:merge_request) { create(:merge_request, source_project: project) }
let(:user) { project.creator }
diff --git a/spec/features/merge_request/user_sees_notes_from_forked_project_spec.rb b/spec/features/merge_request/user_sees_notes_from_forked_project_spec.rb
index 029f55c2cd6..20c45a1d652 100644
--- a/spec/features/merge_request/user_sees_notes_from_forked_project_spec.rb
+++ b/spec/features/merge_request/user_sees_notes_from_forked_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User sees notes from forked project', :js do
+RSpec.describe 'Merge request > User sees notes from forked project', :js do
include ProjectForksHelper
let(:project) { create(:project, :public, :repository) }
diff --git a/spec/features/merge_request/user_sees_pipelines_from_forked_project_spec.rb b/spec/features/merge_request/user_sees_pipelines_from_forked_project_spec.rb
index d258b98f4a9..56092da5136 100644
--- a/spec/features/merge_request/user_sees_pipelines_from_forked_project_spec.rb
+++ b/spec/features/merge_request/user_sees_pipelines_from_forked_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User sees pipelines from forked project', :js do
+RSpec.describe 'Merge request > User sees pipelines from forked project', :js do
include ProjectForksHelper
let(:target_project) { create(:project, :public, :repository) }
diff --git a/spec/features/merge_request/user_sees_pipelines_spec.rb b/spec/features/merge_request/user_sees_pipelines_spec.rb
index f3d8f2b42f8..2d125087cb6 100644
--- a/spec/features/merge_request/user_sees_pipelines_spec.rb
+++ b/spec/features/merge_request/user_sees_pipelines_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User sees pipelines', :js do
+RSpec.describe 'Merge request > User sees pipelines', :js do
describe 'pipeline tab' do
let(:merge_request) { create(:merge_request) }
let(:project) { merge_request.target_project }
diff --git a/spec/features/merge_request/user_sees_system_notes_spec.rb b/spec/features/merge_request/user_sees_system_notes_spec.rb
index 0482458d5ac..9f8d4c6d63f 100644
--- a/spec/features/merge_request/user_sees_system_notes_spec.rb
+++ b/spec/features/merge_request/user_sees_system_notes_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User sees system notes', :js do
+RSpec.describe 'Merge request > User sees system notes', :js do
let(:public_project) { create(:project, :public, :repository) }
let(:private_project) { create(:project, :private, :repository) }
let(:user) { private_project.creator }
diff --git a/spec/features/merge_request/user_sees_versions_spec.rb b/spec/features/merge_request/user_sees_versions_spec.rb
index 5b43fe407eb..75319c8a22d 100644
--- a/spec/features/merge_request/user_sees_versions_spec.rb
+++ b/spec/features/merge_request/user_sees_versions_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User sees versions', :js do
+RSpec.describe 'Merge request > User sees versions', :js do
let(:merge_request) do
create(:merge_request).tap do |mr|
mr.merge_request_diff.destroy
@@ -34,7 +34,7 @@ describe 'Merge request > User sees versions', :js do
page.within("form[data-line-code='#{line_code}']") do
fill_in "note[note]", with: comment
- find(".js-comment-button").click
+ click_button('Add comment now')
end
wait_for_requests
diff --git a/spec/features/merge_request/user_sees_wip_help_message_spec.rb b/spec/features/merge_request/user_sees_wip_help_message_spec.rb
index 1179303171c..42fe18cfc93 100644
--- a/spec/features/merge_request/user_sees_wip_help_message_spec.rb
+++ b/spec/features/merge_request/user_sees_wip_help_message_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User sees WIP help message' do
+RSpec.describe 'Merge request > User sees WIP help message' do
let(:project) { create(:project, :public, :repository) }
let(:user) { project.creator }
diff --git a/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb b/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb
index 22b2ea81b32..bf445de44ba 100644
--- a/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb
+++ b/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User selects branches for new MR', :js do
+RSpec.describe 'Merge request > User selects branches for new MR', :js do
let(:project) { create(:project, :public, :repository) }
let(:user) { project.creator }
diff --git a/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb b/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb
index 62e0e4d76ed..b81c0e49538 100644
--- a/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb
+++ b/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User comments on a diff', :js do
+RSpec.describe 'User comments on a diff', :js do
include MergeRequestDiffHelpers
include RepoHelpers
@@ -49,7 +49,7 @@ describe 'User comments on a diff', :js do
page.within('.js-discussion-note-form') do
fill_in('note_note', with: "```suggestion\n# change to a comment\n```")
- click_button('Comment')
+ click_button('Add comment now')
end
wait_for_requests
@@ -77,7 +77,7 @@ describe 'User comments on a diff', :js do
page.within('.js-discussion-note-form') do
fill_in('note_note', with: "```suggestion\n# change to a comment\n```")
- click_button('Comment')
+ click_button('Add comment now')
end
wait_for_requests
@@ -93,6 +93,100 @@ describe 'User comments on a diff', :js do
end
end
+ context 'applying suggestions in batches' do
+ def hash(path)
+ diff_file = merge_request.diffs(paths: [path]).diff_files.first
+ Digest::SHA1.hexdigest(diff_file.file_path)
+ end
+
+ file1 = 'files/ruby/popen.rb'
+ file2 = 'files/ruby/regex.rb'
+
+ let(:files) do
+ [
+ {
+ hash: hash(file1),
+ line_code: "#{hash(file1)}_12_12"
+ },
+ {
+ hash: hash(file2),
+ line_code: "#{hash(file2)}_21_21"
+ }
+ ]
+ end
+
+ it 'can add and remove suggestions from a batch' do
+ files.each_with_index do |file, index|
+ page.within("[id='#{file[:hash]}']") do
+ find("button[title='Show full file']").click
+ wait_for_requests
+
+ click_diff_line(find("[id='#{file[:line_code]}']"))
+
+ page.within('.js-discussion-note-form') do
+ fill_in('note_note', with: "```suggestion\n# change to a comment\n```")
+ click_button('Add comment now')
+ wait_for_requests
+ end
+ end
+
+ page.within("[id='#{file[:hash]}']") do
+ expect(page).not_to have_content('Applied')
+
+ click_button('Add suggestion to batch')
+ wait_for_requests
+
+ expect(page).to have_content('Remove from batch')
+ expect(page).to have_content("Apply suggestions #{index + 1}")
+ end
+ end
+
+ page.within("[id='#{files[0][:hash]}']") do
+ click_button('Remove from batch')
+ wait_for_requests
+
+ expect(page).to have_content('Apply suggestion')
+ expect(page).to have_content('Add suggestion to batch')
+ end
+
+ page.within("[id='#{files[1][:hash]}']") do
+ expect(page).to have_content('Remove from batch')
+ expect(page).to have_content('Apply suggestions 1')
+ end
+ end
+
+ it 'can apply multiple suggestions as a batch' do
+ files.each_with_index do |file, index|
+ page.within("[id='#{file[:hash]}']") do
+ find("button[title='Show full file']").click
+ wait_for_requests
+
+ click_diff_line(find("[id='#{file[:line_code]}']"))
+
+ page.within('.js-discussion-note-form') do
+ fill_in('note_note', with: "```suggestion\n# change to a comment\n```")
+ click_button('Add comment now')
+ wait_for_requests
+ end
+ end
+
+ page.within("[id='#{file[:hash]}']") do
+ click_button('Add suggestion to batch')
+ wait_for_requests
+ end
+ end
+
+ expect(page).not_to have_content('Applied')
+
+ page.within("[id='#{files[0][:hash]}']") do
+ click_button('Apply suggestions 2')
+ wait_for_requests
+ end
+
+ expect(page).to have_content('Applied').twice
+ end
+ end
+
context 'multiple suggestions in expanded lines' do
# https://gitlab.com/gitlab-org/gitlab/issues/38277
it 'suggestions are appliable', :quarantine do
@@ -119,7 +213,7 @@ describe 'User comments on a diff', :js do
page.within('.js-discussion-note-form') do
fill_in('note_note', with: "```suggestion\n# change to a comment\n```")
- click_button('Comment')
+ click_button('Add comment now')
wait_for_requests
end
@@ -127,7 +221,7 @@ describe 'User comments on a diff', :js do
page.within('.js-discussion-note-form') do
fill_in('note_note', with: "```suggestion\n# 2nd change to a comment\n```")
- click_button('Comment')
+ click_button('Add comment now')
wait_for_requests
end
@@ -158,7 +252,7 @@ describe 'User comments on a diff', :js do
page.within('.js-discussion-note-form') do
fill_in('note_note', with: "```suggestion\n# change to a comment\n```\n```suggestion:-2\n# or that\n# heh\n```")
- click_button('Comment')
+ click_button('Add comment now')
end
wait_for_requests
@@ -201,7 +295,7 @@ describe 'User comments on a diff', :js do
page.within('.js-discussion-note-form') do
fill_in('note_note', with: "```suggestion:-3+5\n# change to a\n# comment\n# with\n# broken\n# lines\n```")
- click_button('Comment')
+ click_button('Add comment now')
end
wait_for_requests
diff --git a/spec/features/merge_request/user_toggles_whitespace_changes_spec.rb b/spec/features/merge_request/user_toggles_whitespace_changes_spec.rb
index 4db067a4e41..fab500f47bf 100644
--- a/spec/features/merge_request/user_toggles_whitespace_changes_spec.rb
+++ b/spec/features/merge_request/user_toggles_whitespace_changes_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User toggles whitespace changes', :js do
+RSpec.describe 'Merge request > User toggles whitespace changes', :js do
let(:merge_request) { create(:merge_request) }
let(:project) { merge_request.project }
let(:user) { project.creator }
diff --git a/spec/features/merge_request/user_tries_to_access_private_project_info_through_new_mr_spec.rb b/spec/features/merge_request/user_tries_to_access_private_project_info_through_new_mr_spec.rb
index 1ebe9e2e409..b864cb55785 100644
--- a/spec/features/merge_request/user_tries_to_access_private_project_info_through_new_mr_spec.rb
+++ b/spec/features/merge_request/user_tries_to_access_private_project_info_through_new_mr_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge Request > User tries to access private project information through the new mr page' do
+RSpec.describe 'Merge Request > User tries to access private project information through the new mr page' do
let(:current_user) { create(:user) }
let(:private_project) do
create(:project, :public, :repository,
diff --git a/spec/features/merge_request/user_uses_quick_actions_spec.rb b/spec/features/merge_request/user_uses_quick_actions_spec.rb
index 318f8812263..04a2e046f42 100644
--- a/spec/features/merge_request/user_uses_quick_actions_spec.rb
+++ b/spec/features/merge_request/user_uses_quick_actions_spec.rb
@@ -7,7 +7,7 @@ require 'spec_helper'
# for example, adding quick actions when creating the issue and checking DateTime formats on UI.
# Because this kind of spec takes more time to run there is no need to add new ones
# for each existing quick action unless they test something not tested by existing tests.
-describe 'Merge request > User uses quick actions', :js do
+RSpec.describe 'Merge request > User uses quick actions', :js do
include Spec::Support::Helpers::Features::NotesHelpers
let(:project) { create(:project, :public, :repository) }
diff --git a/spec/features/merge_request/user_views_diffs_spec.rb b/spec/features/merge_request/user_views_diffs_spec.rb
index cd0cf1cc78a..14d10fc1c9f 100644
--- a/spec/features/merge_request/user_views_diffs_spec.rb
+++ b/spec/features/merge_request/user_views_diffs_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views diffs', :js do
+RSpec.describe 'User views diffs', :js do
let(:merge_request) do
create(:merge_request_with_diffs, source_project: project, target_project: project, source_branch: 'merge-test')
end
diff --git a/spec/features/merge_request/user_views_merge_request_from_deleted_fork_spec.rb b/spec/features/merge_request/user_views_merge_request_from_deleted_fork_spec.rb
index a38bc4f702b..370341a43f9 100644
--- a/spec/features/merge_request/user_views_merge_request_from_deleted_fork_spec.rb
+++ b/spec/features/merge_request/user_views_merge_request_from_deleted_fork_spec.rb
@@ -6,7 +6,7 @@ require 'spec_helper'
# updated.
# This can occur when the fork a merge request is created from is in the process
# of being destroyed.
-describe 'User views merged merge request from deleted fork' do
+RSpec.describe 'User views merged merge request from deleted fork' do
include ProjectForksHelper
let(:project) { create(:project, :repository) }
diff --git a/spec/features/merge_request/user_views_open_merge_request_spec.rb b/spec/features/merge_request/user_views_open_merge_request_spec.rb
index a788fc71286..448844ae57d 100644
--- a/spec/features/merge_request/user_views_open_merge_request_spec.rb
+++ b/spec/features/merge_request/user_views_open_merge_request_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views an open merge request' do
+RSpec.describe 'User views an open merge request' do
let(:merge_request) do
create(:merge_request, source_project: project, target_project: project, description: '# Description header')
end
diff --git a/spec/features/merge_request/user_views_user_status_on_merge_request_spec.rb b/spec/features/merge_request/user_views_user_status_on_merge_request_spec.rb
index 78d9c6c6db1..a6de443e96f 100644
--- a/spec/features/merge_request/user_views_user_status_on_merge_request_spec.rb
+++ b/spec/features/merge_request/user_views_user_status_on_merge_request_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project > Merge request > View user status' do
+RSpec.describe 'Project > Merge request > View user status' do
let(:project) { create(:project, :public, :repository) }
let(:merge_request) do
create(:merge_request, source_project: project, target_project: project, author: create(:user))
diff --git a/spec/features/merge_requests/filters_generic_behavior_spec.rb b/spec/features/merge_requests/filters_generic_behavior_spec.rb
index 2bea819cc33..80009cca2fb 100644
--- a/spec/features/merge_requests/filters_generic_behavior_spec.rb
+++ b/spec/features/merge_requests/filters_generic_behavior_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge Requests > Filters generic behavior', :js do
+RSpec.describe 'Merge Requests > Filters generic behavior', :js do
include FilteredSearchHelpers
let(:project) { create(:project, :public, :repository) }
diff --git a/spec/features/merge_requests/user_filters_by_assignees_spec.rb b/spec/features/merge_requests/user_filters_by_assignees_spec.rb
index 12d682bbb15..9827b067649 100644
--- a/spec/features/merge_requests/user_filters_by_assignees_spec.rb
+++ b/spec/features/merge_requests/user_filters_by_assignees_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge Requests > User filters by assignees', :js do
+RSpec.describe 'Merge Requests > User filters by assignees', :js do
include FilteredSearchHelpers
let(:project) { create(:project, :public, :repository) }
diff --git a/spec/features/merge_requests/user_filters_by_labels_spec.rb b/spec/features/merge_requests/user_filters_by_labels_spec.rb
index 6308579d2d9..980046ccd71 100644
--- a/spec/features/merge_requests/user_filters_by_labels_spec.rb
+++ b/spec/features/merge_requests/user_filters_by_labels_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge Requests > User filters by labels', :js do
+RSpec.describe 'Merge Requests > User filters by labels', :js do
include FilteredSearchHelpers
let(:project) { create(:project, :public, :repository) }
diff --git a/spec/features/merge_requests/user_filters_by_milestones_spec.rb b/spec/features/merge_requests/user_filters_by_milestones_spec.rb
index d2a420be996..41a0b0012d1 100644
--- a/spec/features/merge_requests/user_filters_by_milestones_spec.rb
+++ b/spec/features/merge_requests/user_filters_by_milestones_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge Requests > User filters by milestones', :js do
+RSpec.describe 'Merge Requests > User filters by milestones', :js do
include FilteredSearchHelpers
let(:project) { create(:project, :public, :repository) }
diff --git a/spec/features/merge_requests/user_filters_by_multiple_criteria_spec.rb b/spec/features/merge_requests/user_filters_by_multiple_criteria_spec.rb
index 5fac31e58ba..3aba023b077 100644
--- a/spec/features/merge_requests/user_filters_by_multiple_criteria_spec.rb
+++ b/spec/features/merge_requests/user_filters_by_multiple_criteria_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge requests > User filters by multiple criteria', :js do
+RSpec.describe 'Merge requests > User filters by multiple criteria', :js do
include FilteredSearchHelpers
let!(:project) { create(:project, :public, :repository) }
diff --git a/spec/features/merge_requests/user_filters_by_target_branch_spec.rb b/spec/features/merge_requests/user_filters_by_target_branch_spec.rb
index abe97d4c07e..540d87eb969 100644
--- a/spec/features/merge_requests/user_filters_by_target_branch_spec.rb
+++ b/spec/features/merge_requests/user_filters_by_target_branch_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge Requests > User filters by target branch', :js do
+RSpec.describe 'Merge Requests > User filters by target branch', :js do
include FilteredSearchHelpers
let!(:project) { create(:project, :public, :repository) }
diff --git a/spec/features/merge_requests/user_lists_merge_requests_spec.rb b/spec/features/merge_requests/user_lists_merge_requests_spec.rb
index ee0d7307e6c..4531ef40901 100644
--- a/spec/features/merge_requests/user_lists_merge_requests_spec.rb
+++ b/spec/features/merge_requests/user_lists_merge_requests_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge requests > User lists merge requests' do
+RSpec.describe 'Merge requests > User lists merge requests' do
include MergeRequestHelpers
include SortingHelper
diff --git a/spec/features/merge_requests/user_mass_updates_spec.rb b/spec/features/merge_requests/user_mass_updates_spec.rb
index fa951dd50d3..df94fe2cbd0 100644
--- a/spec/features/merge_requests/user_mass_updates_spec.rb
+++ b/spec/features/merge_requests/user_mass_updates_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge requests > User mass updates', :js do
+RSpec.describe 'Merge requests > User mass updates', :js do
let(:project) { create(:project, :repository) }
let(:user) { project.creator }
let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
diff --git a/spec/features/merge_requests/user_sorts_merge_requests_spec.rb b/spec/features/merge_requests/user_sorts_merge_requests_spec.rb
index 5a84bcb0c44..54c9fbef218 100644
--- a/spec/features/merge_requests/user_sorts_merge_requests_spec.rb
+++ b/spec/features/merge_requests/user_sorts_merge_requests_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User sorts merge requests' do
+RSpec.describe 'User sorts merge requests' do
include CookieHelper
let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
diff --git a/spec/features/merge_requests/user_squashes_merge_request_spec.rb b/spec/features/merge_requests/user_squashes_merge_request_spec.rb
index ce5ed76dc7a..84964bd0637 100644
--- a/spec/features/merge_requests/user_squashes_merge_request_spec.rb
+++ b/spec/features/merge_requests/user_squashes_merge_request_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User squashes a merge request', :js do
+RSpec.describe 'User squashes a merge request', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:source_branch) { 'csv' }
diff --git a/spec/features/merge_requests/user_views_all_merge_requests_spec.rb b/spec/features/merge_requests/user_views_all_merge_requests_spec.rb
index 60496d61e87..f8fe2c5ebe2 100644
--- a/spec/features/merge_requests/user_views_all_merge_requests_spec.rb
+++ b/spec/features/merge_requests/user_views_all_merge_requests_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views all merge requests' do
+RSpec.describe 'User views all merge requests' do
let!(:closed_merge_request) { create(:closed_merge_request, source_project: project, target_project: project) }
let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
let(:project) { create(:project, :public) }
diff --git a/spec/features/merge_requests/user_views_closed_merge_requests_spec.rb b/spec/features/merge_requests/user_views_closed_merge_requests_spec.rb
index dc0d35e4fea..abc652c3bbd 100644
--- a/spec/features/merge_requests/user_views_closed_merge_requests_spec.rb
+++ b/spec/features/merge_requests/user_views_closed_merge_requests_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views closed merge requests' do
+RSpec.describe 'User views closed merge requests' do
let!(:closed_merge_request) { create(:closed_merge_request, source_project: project, target_project: project) }
let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
let(:project) { create(:project, :public) }
diff --git a/spec/features/merge_requests/user_views_merged_merge_requests_spec.rb b/spec/features/merge_requests/user_views_merged_merge_requests_spec.rb
index ddb354204c9..3b93fb7e4bf 100644
--- a/spec/features/merge_requests/user_views_merged_merge_requests_spec.rb
+++ b/spec/features/merge_requests/user_views_merged_merge_requests_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views merged merge requests' do
+RSpec.describe 'User views merged merge requests' do
let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
let!(:merged_merge_request) { create(:merged_merge_request, source_project: project, target_project: project) }
let(:project) { create(:project, :public) }
diff --git a/spec/features/merge_requests/user_views_open_merge_requests_spec.rb b/spec/features/merge_requests/user_views_open_merge_requests_spec.rb
index 4aaa20f0455..49509f89a8d 100644
--- a/spec/features/merge_requests/user_views_open_merge_requests_spec.rb
+++ b/spec/features/merge_requests/user_views_open_merge_requests_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views open merge requests' do
+RSpec.describe 'User views open merge requests' do
let_it_be(:user) { create(:user) }
shared_examples_for 'shows merge requests' do
diff --git a/spec/features/milestone_spec.rb b/spec/features/milestone_spec.rb
index bfff33f3956..4a7f14d5a1b 100644
--- a/spec/features/milestone_spec.rb
+++ b/spec/features/milestone_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Milestone' do
+RSpec.describe 'Milestone' do
let(:group) { create(:group, :public) }
let(:project) { create(:project, :public, namespace: group) }
let(:user) { create(:user) }
@@ -111,20 +111,6 @@ describe 'Milestone' do
end
end
- describe 'deprecation popover', :js do
- it 'opens deprecation popover' do
- milestone = create(:milestone, project: project)
-
- visit group_milestone_path(group, milestone, title: milestone.title)
-
- expect(page).to have_selector('.milestone-deprecation-message')
-
- find('.milestone-deprecation-message .js-popover-link').click
-
- expect(page).to have_selector('.popover')
- end
- end
-
describe 'reopen closed milestones' do
before do
create(:milestone, :closed, project: project)
diff --git a/spec/features/milestones/user_creates_milestone_spec.rb b/spec/features/milestones/user_creates_milestone_spec.rb
index 12cb27b0062..d80796b8f9a 100644
--- a/spec/features/milestones/user_creates_milestone_spec.rb
+++ b/spec/features/milestones/user_creates_milestone_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "User creates milestone", :js do
+RSpec.describe "User creates milestone", :js do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
diff --git a/spec/features/milestones/user_deletes_milestone_spec.rb b/spec/features/milestones/user_deletes_milestone_spec.rb
index fd72f2dfefa..ede9faed876 100644
--- a/spec/features/milestones/user_deletes_milestone_spec.rb
+++ b/spec/features/milestones/user_deletes_milestone_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "User deletes milestone", :js do
+RSpec.describe "User deletes milestone", :js do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:project) { create(:project, namespace: group) }
diff --git a/spec/features/milestones/user_edits_milestone_spec.rb b/spec/features/milestones/user_edits_milestone_spec.rb
index be05685aff7..3edd50922b6 100644
--- a/spec/features/milestones/user_edits_milestone_spec.rb
+++ b/spec/features/milestones/user_edits_milestone_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "User edits milestone", :js do
+RSpec.describe "User edits milestone", :js do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:milestone) { create(:milestone, project: project, start_date: Date.today, due_date: 5.days.from_now) }
diff --git a/spec/features/milestones/user_promotes_milestone_spec.rb b/spec/features/milestones/user_promotes_milestone_spec.rb
index d14097e1ef4..a9c3c9706a0 100644
--- a/spec/features/milestones/user_promotes_milestone_spec.rb
+++ b/spec/features/milestones/user_promotes_milestone_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User promotes milestone' do
+RSpec.describe 'User promotes milestone' do
let_it_be(:group) { create(:group) }
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, namespace: group) }
diff --git a/spec/features/milestones/user_sees_breadcrumb_links_spec.rb b/spec/features/milestones/user_sees_breadcrumb_links_spec.rb
index 92445735328..e9cfa9b20dc 100644
--- a/spec/features/milestones/user_sees_breadcrumb_links_spec.rb
+++ b/spec/features/milestones/user_sees_breadcrumb_links_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'New project milestone breadcrumb' do
+RSpec.describe 'New project milestone breadcrumb' do
let(:project) { create(:project) }
let(:milestone) { create(:milestone, project: project) }
let(:user) { project.creator }
diff --git a/spec/features/milestones/user_views_milestone_spec.rb b/spec/features/milestones/user_views_milestone_spec.rb
index ca13e226432..420f8d49483 100644
--- a/spec/features/milestones/user_views_milestone_spec.rb
+++ b/spec/features/milestones/user_views_milestone_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "User views milestone" do
+RSpec.describe "User views milestone" do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:milestone) { create(:milestone, project: project) }
diff --git a/spec/features/milestones/user_views_milestones_spec.rb b/spec/features/milestones/user_views_milestones_spec.rb
index e17797a8165..3f606577121 100644
--- a/spec/features/milestones/user_views_milestones_spec.rb
+++ b/spec/features/milestones/user_views_milestones_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "User views milestones" do
+RSpec.describe "User views milestones" do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:milestone) { create(:milestone, project: project) }
@@ -65,7 +65,7 @@ describe "User views milestones" do
end
end
-describe "User views milestones with no MR" do
+RSpec.describe "User views milestones with no MR" do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :merge_requests_disabled) }
let_it_be(:milestone) { create(:milestone, project: project) }
diff --git a/spec/features/oauth_login_spec.rb b/spec/features/oauth_login_spec.rb
index 29e9b0c313a..dc27bfbef50 100644
--- a/spec/features/oauth_login_spec.rb
+++ b/spec/features/oauth_login_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'OAuth Login', :js, :allow_forgery_protection do
+RSpec.describe 'OAuth Login', :js, :allow_forgery_protection do
include DeviseHelpers
def enter_code(code)
diff --git a/spec/features/oauth_provider_authorize_spec.rb b/spec/features/oauth_provider_authorize_spec.rb
index 284fe3b0af9..f5a1a35b66f 100644
--- a/spec/features/oauth_provider_authorize_spec.rb
+++ b/spec/features/oauth_provider_authorize_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'OAuth Provider' do
+RSpec.describe 'OAuth Provider' do
describe 'Standard OAuth Authorization' do
let(:application) { create(:oauth_application, scopes: 'read_user') }
diff --git a/spec/features/participants_autocomplete_spec.rb b/spec/features/participants_autocomplete_spec.rb
index fdedd319116..5c29ac870c0 100644
--- a/spec/features/participants_autocomplete_spec.rb
+++ b/spec/features/participants_autocomplete_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Member autocomplete', :js do
+RSpec.describe 'Member autocomplete', :js do
let(:project) { create(:project, :public) }
let(:user) { create(:user) }
let(:author) { create(:user) }
diff --git a/spec/features/password_reset_spec.rb b/spec/features/password_reset_spec.rb
index 8ceca1e3175..31b2b2d15aa 100644
--- a/spec/features/password_reset_spec.rb
+++ b/spec/features/password_reset_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Password reset' do
+RSpec.describe 'Password reset' do
describe 'throttling' do
it 'sends reset instructions when not previously sent' do
user = create(:user)
diff --git a/spec/features/populate_new_pipeline_vars_with_params_spec.rb b/spec/features/populate_new_pipeline_vars_with_params_spec.rb
index 5fe80e73e38..f931e8497fc 100644
--- a/spec/features/populate_new_pipeline_vars_with_params_spec.rb
+++ b/spec/features/populate_new_pipeline_vars_with_params_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Populate new pipeline CI variables with url params", :js do
+RSpec.describe "Populate new pipeline CI variables with url params", :js do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:page_path) { new_project_pipeline_path(project) }
diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb
index 0147963c0a3..4326700bab1 100644
--- a/spec/features/profile_spec.rb
+++ b/spec/features/profile_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Profile account page', :js do
+RSpec.describe 'Profile account page', :js do
let(:user) { create(:user) }
before do
diff --git a/spec/features/profiles/account_spec.rb b/spec/features/profiles/account_spec.rb
index c6db15065f2..620c2f60ba3 100644
--- a/spec/features/profiles/account_spec.rb
+++ b/spec/features/profiles/account_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Profile > Account', :js do
+RSpec.describe 'Profile > Account', :js do
let(:user) { create(:user, username: 'foo') }
before do
@@ -56,6 +56,37 @@ describe 'Profile > Account', :js do
end
end
end
+
+ describe 'Delete account' do
+ before do
+ create_list(:project, number_of_projects, namespace: user.namespace)
+ visit profile_account_path
+ end
+
+ context 'when there are no personal projects' do
+ let(:number_of_projects) { 0 }
+
+ it 'does not show personal projects removal message' do
+ expect(page).not_to have_content(/\d personal projects? will be removed and cannot be restored/)
+ end
+ end
+
+ context 'when one personal project exists' do
+ let(:number_of_projects) { 1 }
+
+ it 'does show personal project removal message' do
+ expect(page).to have_content('1 personal project will be removed and cannot be restored')
+ end
+ end
+
+ context 'when more than one personal projects exists' do
+ let(:number_of_projects) { 3 }
+
+ it 'shows pluralized personal project removal message' do
+ expect(page).to have_content('3 personal projects will be removed and cannot be restored')
+ end
+ end
+ end
end
def update_username(new_username)
diff --git a/spec/features/profiles/active_sessions_spec.rb b/spec/features/profiles/active_sessions_spec.rb
index 8f63ce2a197..75531d43df2 100644
--- a/spec/features/profiles/active_sessions_spec.rb
+++ b/spec/features/profiles/active_sessions_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Profile > Active Sessions', :clean_gitlab_redis_shared_state do
+RSpec.describe 'Profile > Active Sessions', :clean_gitlab_redis_shared_state do
let(:user) do
create(:user).tap do |user|
user.current_sign_in_at = Time.current
diff --git a/spec/features/profiles/chat_names_spec.rb b/spec/features/profiles/chat_names_spec.rb
index 4c447faf77e..80b36aa37b8 100644
--- a/spec/features/profiles/chat_names_spec.rb
+++ b/spec/features/profiles/chat_names_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Profile > Chat' do
+RSpec.describe 'Profile > Chat' do
let(:user) { create(:user) }
let(:service) { create(:service) }
diff --git a/spec/features/profiles/emails_spec.rb b/spec/features/profiles/emails_spec.rb
index a41ef9e86ae..fc7de6d8b23 100644
--- a/spec/features/profiles/emails_spec.rb
+++ b/spec/features/profiles/emails_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Profile > Emails' do
+RSpec.describe 'Profile > Emails' do
let(:user) { create(:user) }
before do
diff --git a/spec/features/profiles/gpg_keys_spec.rb b/spec/features/profiles/gpg_keys_spec.rb
index 07e87f36c65..18ed4e646b3 100644
--- a/spec/features/profiles/gpg_keys_spec.rb
+++ b/spec/features/profiles/gpg_keys_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Profile > GPG Keys' do
+RSpec.describe 'Profile > GPG Keys' do
let(:user) { create(:user, email: GpgHelpers::User2.emails.first) }
before do
diff --git a/spec/features/profiles/keys_spec.rb b/spec/features/profiles/keys_spec.rb
index 3fc0fd76d2e..b5e784a749f 100644
--- a/spec/features/profiles/keys_spec.rb
+++ b/spec/features/profiles/keys_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Profile > SSH Keys' do
+RSpec.describe 'Profile > SSH Keys' do
let(:user) { create(:user) }
before do
diff --git a/spec/features/profiles/oauth_applications_spec.rb b/spec/features/profiles/oauth_applications_spec.rb
index 94c9897a7a9..2735f601307 100644
--- a/spec/features/profiles/oauth_applications_spec.rb
+++ b/spec/features/profiles/oauth_applications_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Profile > Applications' do
+RSpec.describe 'Profile > Applications' do
let(:user) { create(:user) }
let(:application) { create(:oauth_application, owner: user) }
diff --git a/spec/features/profiles/password_spec.rb b/spec/features/profiles/password_spec.rb
index 9dc96080732..a274f2b6d96 100644
--- a/spec/features/profiles/password_spec.rb
+++ b/spec/features/profiles/password_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Profile > Password' do
+RSpec.describe 'Profile > Password' do
let(:user) { create(:user) }
def fill_passwords(password, confirmation)
diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb
index 1fb61eeeb5a..21a0d01a9bf 100644
--- a/spec/features/profiles/personal_access_tokens_spec.rb
+++ b/spec/features/profiles/personal_access_tokens_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Profile > Personal Access Tokens', :js do
+RSpec.describe 'Profile > Personal Access Tokens', :js do
let(:user) { create(:user) }
def active_personal_access_tokens
diff --git a/spec/features/profiles/user_changes_notified_of_own_activity_spec.rb b/spec/features/profiles/user_changes_notified_of_own_activity_spec.rb
index 5af48c4503d..a5b7b1fba9d 100644
--- a/spec/features/profiles/user_changes_notified_of_own_activity_spec.rb
+++ b/spec/features/profiles/user_changes_notified_of_own_activity_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Profile > Notifications > User changes notified_of_own_activity setting', :js do
+RSpec.describe 'Profile > Notifications > User changes notified_of_own_activity setting', :js do
let(:user) { create(:user) }
before do
diff --git a/spec/features/profiles/user_edit_preferences_spec.rb b/spec/features/profiles/user_edit_preferences_spec.rb
index 6e61536d5ff..e1117d2d420 100644
--- a/spec/features/profiles/user_edit_preferences_spec.rb
+++ b/spec/features/profiles/user_edit_preferences_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe 'User edit preferences profile' do
+RSpec.describe 'User edit preferences profile' do
let(:user) { create(:user) }
before do
diff --git a/spec/features/profiles/user_edit_profile_spec.rb b/spec/features/profiles/user_edit_profile_spec.rb
index 171dfb353f0..2659157d61d 100644
--- a/spec/features/profiles/user_edit_profile_spec.rb
+++ b/spec/features/profiles/user_edit_profile_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User edit profile' do
+RSpec.describe 'User edit profile' do
let(:user) { create(:user) }
before do
@@ -245,6 +245,15 @@ describe 'User edit profile' do
end
end
+ it 'opens the emoji modal again after closing it' do
+ open_user_status_modal
+ select_emoji('biohazard', true)
+
+ find('.js-toggle-emoji-menu').click
+
+ expect(page).to have_selector('.emoji-menu')
+ end
+
it 'does not update the awards panel emoji' do
project.add_maintainer(user)
visit(project_issue_path(project, issue))
diff --git a/spec/features/profiles/user_manages_applications_spec.rb b/spec/features/profiles/user_manages_applications_spec.rb
index 668c4e8c784..d65365db880 100644
--- a/spec/features/profiles/user_manages_applications_spec.rb
+++ b/spec/features/profiles/user_manages_applications_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User manages applications' do
+RSpec.describe 'User manages applications' do
let(:user) { create(:user) }
before do
diff --git a/spec/features/profiles/user_manages_emails_spec.rb b/spec/features/profiles/user_manages_emails_spec.rb
index 09da819a187..373c4f565f2 100644
--- a/spec/features/profiles/user_manages_emails_spec.rb
+++ b/spec/features/profiles/user_manages_emails_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User manages emails' do
+RSpec.describe 'User manages emails' do
let(:user) { create(:user) }
before do
diff --git a/spec/features/profiles/user_visits_notifications_tab_spec.rb b/spec/features/profiles/user_visits_notifications_tab_spec.rb
index d788c0574e2..997cc8e3c4b 100644
--- a/spec/features/profiles/user_visits_notifications_tab_spec.rb
+++ b/spec/features/profiles/user_visits_notifications_tab_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User visits the notifications tab', :js do
+RSpec.describe 'User visits the notifications tab', :js do
let(:project) { create(:project) }
let(:user) { create(:user) }
diff --git a/spec/features/profiles/user_visits_profile_account_page_spec.rb b/spec/features/profiles/user_visits_profile_account_page_spec.rb
index f576a2bf9e1..b4d1185412b 100644
--- a/spec/features/profiles/user_visits_profile_account_page_spec.rb
+++ b/spec/features/profiles/user_visits_profile_account_page_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User visits the profile account page' do
+RSpec.describe 'User visits the profile account page' do
let(:user) { create(:user) }
before do
diff --git a/spec/features/profiles/user_visits_profile_authentication_log_spec.rb b/spec/features/profiles/user_visits_profile_authentication_log_spec.rb
index 2f6f8ebee9c..22292eff9a3 100644
--- a/spec/features/profiles/user_visits_profile_authentication_log_spec.rb
+++ b/spec/features/profiles/user_visits_profile_authentication_log_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User visits the authentication log' do
+RSpec.describe 'User visits the authentication log' do
let(:user) { create(:user) }
context 'when user signed in' do
diff --git a/spec/features/profiles/user_visits_profile_preferences_page_spec.rb b/spec/features/profiles/user_visits_profile_preferences_page_spec.rb
index b18f763a968..d9421631b32 100644
--- a/spec/features/profiles/user_visits_profile_preferences_page_spec.rb
+++ b/spec/features/profiles/user_visits_profile_preferences_page_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User visits the profile preferences page' do
+RSpec.describe 'User visits the profile preferences page' do
include Select2Helper
let(:user) { create(:user) }
diff --git a/spec/features/profiles/user_visits_profile_spec.rb b/spec/features/profiles/user_visits_profile_spec.rb
index 1c90a794099..77da1f138c7 100644
--- a/spec/features/profiles/user_visits_profile_spec.rb
+++ b/spec/features/profiles/user_visits_profile_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User visits their profile' do
+RSpec.describe 'User visits their profile' do
let(:user) { create(:user) }
before do
diff --git a/spec/features/profiles/user_visits_profile_ssh_keys_page_spec.rb b/spec/features/profiles/user_visits_profile_ssh_keys_page_spec.rb
index 05ad9096f65..0531434f00c 100644
--- a/spec/features/profiles/user_visits_profile_ssh_keys_page_spec.rb
+++ b/spec/features/profiles/user_visits_profile_ssh_keys_page_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User visits the profile SSH keys page' do
+RSpec.describe 'User visits the profile SSH keys page' do
let(:user) { create(:user) }
before do
diff --git a/spec/features/project_group_variables_spec.rb b/spec/features/project_group_variables_spec.rb
index 242fc993718..e964a7def14 100644
--- a/spec/features/project_group_variables_spec.rb
+++ b/spec/features/project_group_variables_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project group variables', :js do
+RSpec.describe 'Project group variables', :js do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:subgroup) { create(:group, parent: group) }
diff --git a/spec/features/project_variables_spec.rb b/spec/features/project_variables_spec.rb
index 1452317c22b..c67bcbf919b 100644
--- a/spec/features/project_variables_spec.rb
+++ b/spec/features/project_variables_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project variables', :js do
+RSpec.describe 'Project variables', :js do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:variable) { create(:ci_variable, key: 'test_key', value: 'test_value', masked: true) }
diff --git a/spec/features/projects/active_tabs_spec.rb b/spec/features/projects/active_tabs_spec.rb
index 815cf3b9c58..349e5f5e177 100644
--- a/spec/features/projects/active_tabs_spec.rb
+++ b/spec/features/projects/active_tabs_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project active tab' do
+RSpec.describe 'Project active tab' do
let(:user) { create :user }
let(:project) { create(:project, :repository) }
@@ -84,7 +84,7 @@ describe 'Project active tab' do
context 'on project Wiki' do
before do
- visit project_wiki_path(project, :home)
+ visit wiki_path(project.wiki)
end
it_behaves_like 'page has active tab', 'Wiki'
diff --git a/spec/features/projects/activity/rss_spec.rb b/spec/features/projects/activity/rss_spec.rb
index e1efe6ca64d..9012b335bf4 100644
--- a/spec/features/projects/activity/rss_spec.rb
+++ b/spec/features/projects/activity/rss_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project Activity RSS' do
+RSpec.describe 'Project Activity RSS' do
let(:project) { create(:project, :public) }
let(:user) { project.owner }
let(:path) { activity_project_path(project) }
diff --git a/spec/features/projects/activity/user_sees_activity_spec.rb b/spec/features/projects/activity/user_sees_activity_spec.rb
index 664002d909c..a9cdbd5c342 100644
--- a/spec/features/projects/activity/user_sees_activity_spec.rb
+++ b/spec/features/projects/activity/user_sees_activity_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Activity > User sees activity' do
+RSpec.describe 'Projects > Activity > User sees activity' do
let(:project) { create(:project, :repository, :public) }
let(:user) { project.creator }
let(:issue) { create(:issue, project: project) }
diff --git a/spec/features/projects/activity/user_sees_design_comment_spec.rb b/spec/features/projects/activity/user_sees_design_comment_spec.rb
index 9864e9ce29f..e60deba65f0 100644
--- a/spec/features/projects/activity/user_sees_design_comment_spec.rb
+++ b/spec/features/projects/activity/user_sees_design_comment_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Activity > User sees design comment', :js do
+RSpec.describe 'Projects > Activity > User sees design comment', :js do
include DesignManagementTestHelpers
let_it_be(:project) { create(:project, :repository, :public) }
diff --git a/spec/features/projects/activity/user_sees_private_activity_spec.rb b/spec/features/projects/activity/user_sees_private_activity_spec.rb
index 0ec4752d418..86692bc6b4c 100644
--- a/spec/features/projects/activity/user_sees_private_activity_spec.rb
+++ b/spec/features/projects/activity/user_sees_private_activity_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project > Activity > User sees private activity', :js do
+RSpec.describe 'Project > Activity > User sees private activity', :js do
let(:project) { create(:project, :public) }
let(:author) { create(:user) }
let(:user) { create(:user) }
diff --git a/spec/features/projects/artifacts/file_spec.rb b/spec/features/projects/artifacts/file_spec.rb
index f7eaae12072..b61ee623fec 100644
--- a/spec/features/projects/artifacts/file_spec.rb
+++ b/spec/features/projects/artifacts/file_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Artifact file', :js do
+RSpec.describe 'Artifact file', :js do
let(:project) { create(:project, :public) }
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
let(:build) { create(:ci_build, :artifacts, pipeline: pipeline) }
diff --git a/spec/features/projects/artifacts/raw_spec.rb b/spec/features/projects/artifacts/raw_spec.rb
index 0606ab0ed08..d72a35fddf8 100644
--- a/spec/features/projects/artifacts/raw_spec.rb
+++ b/spec/features/projects/artifacts/raw_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Raw artifact', :js do
+RSpec.describe 'Raw artifact', :js do
let(:project) { create(:project, :public) }
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
let(:job) { create(:ci_build, :artifacts, pipeline: pipeline) }
diff --git a/spec/features/projects/artifacts/user_browses_artifacts_spec.rb b/spec/features/projects/artifacts/user_browses_artifacts_spec.rb
index d8c6ef4755d..77e3c7f972d 100644
--- a/spec/features/projects/artifacts/user_browses_artifacts_spec.rb
+++ b/spec/features/projects/artifacts/user_browses_artifacts_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User browses artifacts" do
+RSpec.describe "User browses artifacts" do
let(:project) { create(:project, :public) }
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
let(:job) { create(:ci_build, :artifacts, pipeline: pipeline) }
diff --git a/spec/features/projects/artifacts/user_downloads_artifacts_spec.rb b/spec/features/projects/artifacts/user_downloads_artifacts_spec.rb
index 78ff89799ad..7d6ae03e08e 100644
--- a/spec/features/projects/artifacts/user_downloads_artifacts_spec.rb
+++ b/spec/features/projects/artifacts/user_downloads_artifacts_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User downloads artifacts" do
+RSpec.describe "User downloads artifacts" do
let_it_be(:project) { create(:project, :repository, :public) }
let_it_be(:pipeline) { create(:ci_empty_pipeline, status: :success, sha: project.commit.id, project: project) }
let_it_be(:job) { create(:ci_build, :artifacts, :success, pipeline: pipeline) }
diff --git a/spec/features/projects/badges/coverage_spec.rb b/spec/features/projects/badges/coverage_spec.rb
index d17588bb7b4..4c144037acd 100644
--- a/spec/features/projects/badges/coverage_spec.rb
+++ b/spec/features/projects/badges/coverage_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'test coverage badge' do
+RSpec.describe 'test coverage badge' do
let!(:user) { create(:user) }
let!(:project) { create(:project, :private) }
diff --git a/spec/features/projects/badges/list_spec.rb b/spec/features/projects/badges/list_spec.rb
index 7a90457c942..3382bdcd65f 100644
--- a/spec/features/projects/badges/list_spec.rb
+++ b/spec/features/projects/badges/list_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'list of badges' do
+RSpec.describe 'list of badges' do
before do
user = create(:user)
project = create(:project, :repository)
diff --git a/spec/features/projects/badges/pipeline_badge_spec.rb b/spec/features/projects/badges/pipeline_badge_spec.rb
index b2f09a9d0b7..c24ab5c4058 100644
--- a/spec/features/projects/badges/pipeline_badge_spec.rb
+++ b/spec/features/projects/badges/pipeline_badge_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Pipeline Badge' do
+RSpec.describe 'Pipeline Badge' do
let_it_be(:project) { create(:project, :repository, :public) }
let(:ref) { project.default_branch }
diff --git a/spec/features/projects/blobs/blob_line_permalink_updater_spec.rb b/spec/features/projects/blobs/blob_line_permalink_updater_spec.rb
index e54137b9492..6bd6634822c 100644
--- a/spec/features/projects/blobs/blob_line_permalink_updater_spec.rb
+++ b/spec/features/projects/blobs/blob_line_permalink_updater_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Blob button line permalinks (BlobLinePermalinkUpdater)', :js do
+RSpec.describe 'Blob button line permalinks (BlobLinePermalinkUpdater)', :js do
include TreeHelper
let(:project) { create(:project, :public, :repository) }
diff --git a/spec/features/projects/blobs/blob_show_spec.rb b/spec/features/projects/blobs/blob_show_spec.rb
index 9fc70412975..c738c5ee5fa 100644
--- a/spec/features/projects/blobs/blob_show_spec.rb
+++ b/spec/features/projects/blobs/blob_show_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'File blob', :js do
+RSpec.describe 'File blob', :js do
include MobileHelpers
let(:project) { create(:project, :public, :repository) }
@@ -555,6 +555,53 @@ describe 'File blob', :js do
end
end
+ describe '.gitlab/dashboards/custom-dashboard.yml' do
+ before do
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add .gitlab/dashboards/custom-dashboard.yml",
+ file_path: '.gitlab/dashboards/custom-dashboard.yml',
+ file_content: file_content
+ ).execute
+
+ visit_blob('.gitlab/dashboards/custom-dashboard.yml')
+ end
+
+ context 'valid dashboard file' do
+ let(:file_content) { File.read(Rails.root.join('config/prometheus/common_metrics.yml')) }
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows that dashboard yaml is valid
+ expect(page).to have_content('Metrics Dashboard YAML definition is valid.')
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more')
+ end
+ end
+ end
+
+ context 'invalid dashboard file' do
+ let(:file_content) { "dashboard: 'invalid'" }
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows that dashboard yaml is invalid
+ expect(page).to have_content('Metrics Dashboard YAML definition is invalid:')
+ expect(page).to have_content("panel_groups: can't be blank")
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more')
+ end
+ end
+ end
+ end
+
context 'LICENSE' do
before do
visit_blob('LICENSE')
diff --git a/spec/features/projects/blobs/edit_spec.rb b/spec/features/projects/blobs/edit_spec.rb
index 5d62b2f87bb..56bf31f24ba 100644
--- a/spec/features/projects/blobs/edit_spec.rb
+++ b/spec/features/projects/blobs/edit_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Editing file blob', :js do
+RSpec.describe 'Editing file blob', :js do
include TreeHelper
let(:project) { create(:project, :public, :repository) }
diff --git a/spec/features/projects/blobs/shortcuts_blob_spec.rb b/spec/features/projects/blobs/shortcuts_blob_spec.rb
index bc12a8ff007..64d643aa102 100644
--- a/spec/features/projects/blobs/shortcuts_blob_spec.rb
+++ b/spec/features/projects/blobs/shortcuts_blob_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Blob shortcuts', :js do
+RSpec.describe 'Blob shortcuts', :js do
include TreeHelper
let(:project) { create(:project, :public, :repository) }
let(:path) { project.repository.ls_files(project.repository.root_ref)[0] }
diff --git a/spec/features/projects/blobs/user_creates_new_blob_in_new_project_spec.rb b/spec/features/projects/blobs/user_creates_new_blob_in_new_project_spec.rb
index 30878b7fb64..f54bceec2b3 100644
--- a/spec/features/projects/blobs/user_creates_new_blob_in_new_project_spec.rb
+++ b/spec/features/projects/blobs/user_creates_new_blob_in_new_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User creates blob in new project', :js do
+RSpec.describe 'User creates blob in new project', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :empty_repo) }
diff --git a/spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb b/spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb
index 09130d34281..5270774b541 100644
--- a/spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb
+++ b/spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User follows pipeline suggest nudge spec when feature is enabled', :js do
+RSpec.describe 'User follows pipeline suggest nudge spec when feature is enabled', :js do
include CookieHelper
let(:user) { create(:user, :admin) }
diff --git a/spec/features/projects/branches/download_buttons_spec.rb b/spec/features/projects/branches/download_buttons_spec.rb
index e0b0e22823e..569a93a55fc 100644
--- a/spec/features/projects/branches/download_buttons_spec.rb
+++ b/spec/features/projects/branches/download_buttons_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Download buttons in branches page' do
+RSpec.describe 'Download buttons in branches page' do
let(:user) { create(:user) }
let(:role) { :developer }
let(:status) { 'success' }
diff --git a/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb b/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb
index 4b6b07f6cda..5f58e446ed9 100644
--- a/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb
+++ b/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'New Branch Ref Dropdown', :js do
+RSpec.describe 'New Branch Ref Dropdown', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :public, :repository) }
let(:toggle) { find('.create-from .dropdown-menu-toggle') }
diff --git a/spec/features/projects/branches/user_creates_branch_spec.rb b/spec/features/projects/branches/user_creates_branch_spec.rb
index 8aac188160b..52c860bfe36 100644
--- a/spec/features/projects/branches/user_creates_branch_spec.rb
+++ b/spec/features/projects/branches/user_creates_branch_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User creates branch", :js do
+RSpec.describe "User creates branch", :js do
include Spec::Support::Helpers::Features::BranchesHelpers
let(:user) { create(:user) }
diff --git a/spec/features/projects/branches/user_deletes_branch_spec.rb b/spec/features/projects/branches/user_deletes_branch_spec.rb
index 184954c1c78..21a1d31bad4 100644
--- a/spec/features/projects/branches/user_deletes_branch_spec.rb
+++ b/spec/features/projects/branches/user_deletes_branch_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User deletes branch", :js do
+RSpec.describe "User deletes branch", :js do
let_it_be(:user) { create(:user) }
let(:project) { create(:project, :repository) }
diff --git a/spec/features/projects/branches/user_views_branches_spec.rb b/spec/features/projects/branches/user_views_branches_spec.rb
index e127e784b94..19d96579785 100644
--- a/spec/features/projects/branches/user_views_branches_spec.rb
+++ b/spec/features/projects/branches/user_views_branches_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User views branches" do
+RSpec.describe "User views branches" do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { project.owner }
diff --git a/spec/features/projects/branches_spec.rb b/spec/features/projects/branches_spec.rb
index 9dc0f7c90c2..dbd1cebd515 100644
--- a/spec/features/projects/branches_spec.rb
+++ b/spec/features/projects/branches_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Branches' do
+RSpec.describe 'Branches' do
let(:user) { create(:user) }
let(:project) { create(:project, :public, :repository) }
let(:repository) { project.repository }
@@ -231,6 +231,44 @@ describe 'Branches' do
end
end
+ context 'with one or more pipeline', :js do
+ before do
+ sha = create_file(branch_name: "branch")
+ create(:ci_pipeline,
+ project: project,
+ user: user,
+ ref: "branch",
+ sha: sha,
+ status: :success,
+ created_at: 5.months.ago)
+ visit project_branches_path(project)
+ end
+
+ it 'shows pipeline status when available' do
+ page.within first('.all-branches li') do
+ expect(page).to have_css 'a.ci-status-icon-success'
+ end
+ end
+
+ it 'displays a placeholder when not available' do
+ page.all('.all-branches li') do |li|
+ expect(li).to have_css 'svg.s24'
+ end
+ end
+ end
+
+ context 'with no pipelines', :js do
+ before do
+ visit project_branches_path(project)
+ end
+
+ it 'does not show placeholder or pipeline status' do
+ page.all('.all-branches') do |branches|
+ expect(branches).not_to have_css 'svg.s24'
+ end
+ end
+ end
+
describe 'comparing branches' do
before do
sign_in(user)
diff --git a/spec/features/projects/ci/lint_spec.rb b/spec/features/projects/ci/lint_spec.rb
index 521cfb54cd2..f3845bb8dec 100644
--- a/spec/features/projects/ci/lint_spec.rb
+++ b/spec/features/projects/ci/lint_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'CI Lint', :js do
+RSpec.describe 'CI Lint', :js do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/features/projects/classification_label_on_project_pages_spec.rb b/spec/features/projects/classification_label_on_project_pages_spec.rb
index 92f8aa8eb8d..0f07ca7635b 100644
--- a/spec/features/projects/classification_label_on_project_pages_spec.rb
+++ b/spec/features/projects/classification_label_on_project_pages_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Classification label on project pages' do
+RSpec.describe 'Classification label on project pages' do
let(:project) do
create(:project, external_authorization_classification_label: 'authorized label')
end
diff --git a/spec/features/projects/clusters/applications_spec.rb b/spec/features/projects/clusters/applications_spec.rb
index ce971b158a3..74b477dd85d 100644
--- a/spec/features/projects/clusters/applications_spec.rb
+++ b/spec/features/projects/clusters/applications_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require_relative '../../../../spec/features/clusters/installing_applications_shared_examples'
-describe 'Project-level Cluster Applications', :js do
+RSpec.describe 'Project-level Cluster Applications', :js do
include GoogleApi::CloudPlatformHelpers
let(:project) { create(:project) }
diff --git a/spec/features/projects/clusters/eks_spec.rb b/spec/features/projects/clusters/eks_spec.rb
index a856376cb4b..c5feef6c6f3 100644
--- a/spec/features/projects/clusters/eks_spec.rb
+++ b/spec/features/projects/clusters/eks_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'AWS EKS Cluster', :js do
+RSpec.describe 'AWS EKS Cluster', :js do
let(:project) { create(:project) }
let(:user) { create(:user) }
diff --git a/spec/features/projects/clusters/gcp_spec.rb b/spec/features/projects/clusters/gcp_spec.rb
index b35e79bef43..3e1006920e7 100644
--- a/spec/features/projects/clusters/gcp_spec.rb
+++ b/spec/features/projects/clusters/gcp_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Gcp Cluster', :js, :do_not_mock_admin_mode do
+RSpec.describe 'Gcp Cluster', :js, :do_not_mock_admin_mode do
include GoogleApi::CloudPlatformHelpers
let(:project) { create(:project) }
diff --git a/spec/features/projects/clusters/user_spec.rb b/spec/features/projects/clusters/user_spec.rb
index 5c82d848563..15fed0c2727 100644
--- a/spec/features/projects/clusters/user_spec.rb
+++ b/spec/features/projects/clusters/user_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User Cluster', :js do
+RSpec.describe 'User Cluster', :js do
include GoogleApi::CloudPlatformHelpers
let(:project) { create(:project) }
diff --git a/spec/features/projects/clusters_spec.rb b/spec/features/projects/clusters_spec.rb
index fc2de4df5ec..1cf214a5c4e 100644
--- a/spec/features/projects/clusters_spec.rb
+++ b/spec/features/projects/clusters_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Clusters', :js do
+RSpec.describe 'Clusters', :js do
include GoogleApi::CloudPlatformHelpers
let(:project) { create(:project) }
diff --git a/spec/features/projects/commit/builds_spec.rb b/spec/features/projects/commit/builds_spec.rb
index d28ff5d3b5f..13f73b8cf44 100644
--- a/spec/features/projects/commit/builds_spec.rb
+++ b/spec/features/projects/commit/builds_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'project commit pipelines', :js do
+RSpec.describe 'project commit pipelines', :js do
let(:project) { create(:project, :repository) }
before do
diff --git a/spec/features/projects/commit/cherry_pick_spec.rb b/spec/features/projects/commit/cherry_pick_spec.rb
index 34b15aeaa25..9fe3f4cd63e 100644
--- a/spec/features/projects/commit/cherry_pick_spec.rb
+++ b/spec/features/projects/commit/cherry_pick_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Cherry-pick Commits' do
+RSpec.describe 'Cherry-pick Commits' do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:project) { create(:project, :repository, namespace: group) }
diff --git a/spec/features/projects/commit/comments/user_adds_comment_spec.rb b/spec/features/projects/commit/comments/user_adds_comment_spec.rb
index bae8e6dc827..a470215186b 100644
--- a/spec/features/projects/commit/comments/user_adds_comment_spec.rb
+++ b/spec/features/projects/commit/comments/user_adds_comment_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User adds a comment on a commit", :js do
+RSpec.describe "User adds a comment on a commit", :js do
include Spec::Support::Helpers::Features::NotesHelpers
include RepoHelpers
diff --git a/spec/features/projects/commit/comments/user_deletes_comments_spec.rb b/spec/features/projects/commit/comments/user_deletes_comments_spec.rb
index 2993a402e37..431cbb4ffbb 100644
--- a/spec/features/projects/commit/comments/user_deletes_comments_spec.rb
+++ b/spec/features/projects/commit/comments/user_deletes_comments_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User deletes comments on a commit", :js do
+RSpec.describe "User deletes comments on a commit", :js do
include Spec::Support::Helpers::Features::NotesHelpers
include RepoHelpers
diff --git a/spec/features/projects/commit/comments/user_edits_comments_spec.rb b/spec/features/projects/commit/comments/user_edits_comments_spec.rb
index 29132173674..787d8cdb02b 100644
--- a/spec/features/projects/commit/comments/user_edits_comments_spec.rb
+++ b/spec/features/projects/commit/comments/user_edits_comments_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User edits a comment on a commit", :js do
+RSpec.describe "User edits a comment on a commit", :js do
include Spec::Support::Helpers::Features::NotesHelpers
include RepoHelpers
diff --git a/spec/features/projects/commit/diff_notes_spec.rb b/spec/features/projects/commit/diff_notes_spec.rb
index 04bd66df28d..ff86047d812 100644
--- a/spec/features/projects/commit/diff_notes_spec.rb
+++ b/spec/features/projects/commit/diff_notes_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Commit diff', :js do
+RSpec.describe 'Commit diff', :js do
include RepoHelpers
let(:user) { create(:user) }
diff --git a/spec/features/projects/commit/mini_pipeline_graph_spec.rb b/spec/features/projects/commit/mini_pipeline_graph_spec.rb
index 3d9fcfe0f62..9349f36282d 100644
--- a/spec/features/projects/commit/mini_pipeline_graph_spec.rb
+++ b/spec/features/projects/commit/mini_pipeline_graph_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Mini Pipeline Graph in Commit View', :js do
+RSpec.describe 'Mini Pipeline Graph in Commit View', :js do
let(:project) { create(:project, :public, :repository) }
context 'when commit has pipelines' do
diff --git a/spec/features/projects/commit/user_comments_on_commit_spec.rb b/spec/features/projects/commit/user_comments_on_commit_spec.rb
index f4fea9b9ae0..87a022d74a3 100644
--- a/spec/features/projects/commit/user_comments_on_commit_spec.rb
+++ b/spec/features/projects/commit/user_comments_on_commit_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User comments on commit", :js do
+RSpec.describe "User comments on commit", :js do
include Spec::Support::Helpers::Features::NotesHelpers
include RepoHelpers
diff --git a/spec/features/projects/commit/user_reverts_commit_spec.rb b/spec/features/projects/commit/user_reverts_commit_spec.rb
index 39ee72a4a99..ca4e070703b 100644
--- a/spec/features/projects/commit/user_reverts_commit_spec.rb
+++ b/spec/features/projects/commit/user_reverts_commit_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User reverts a commit', :js do
+RSpec.describe 'User reverts a commit', :js do
include RepoHelpers
let(:project) { create(:project, :repository, namespace: user.namespace) }
diff --git a/spec/features/projects/commit/user_views_user_status_on_commit_spec.rb b/spec/features/projects/commit/user_views_user_status_on_commit_spec.rb
index c07f6081d2c..71405cf917d 100644
--- a/spec/features/projects/commit/user_views_user_status_on_commit_spec.rb
+++ b/spec/features/projects/commit/user_views_user_status_on_commit_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project > Commit > View user status' do
+RSpec.describe 'Project > Commit > View user status' do
include RepoHelpers
let_it_be(:project) { create(:project, :repository) }
diff --git a/spec/features/projects/commits/rss_spec.rb b/spec/features/projects/commits/rss_spec.rb
index 0266df48d4a..b521bb865ae 100644
--- a/spec/features/projects/commits/rss_spec.rb
+++ b/spec/features/projects/commits/rss_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project Commits RSS' do
+RSpec.describe 'Project Commits RSS' do
let(:user) { create(:user) }
let(:project) { create(:project, :repository, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
let(:path) { project_commits_path(project, :master) }
diff --git a/spec/features/projects/commits/user_browses_commits_spec.rb b/spec/features/projects/commits/user_browses_commits_spec.rb
index 7e59e36ccb7..2796156bfbf 100644
--- a/spec/features/projects/commits/user_browses_commits_spec.rb
+++ b/spec/features/projects/commits/user_browses_commits_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User browses commits' do
+RSpec.describe 'User browses commits' do
include RepoHelpers
let(:user) { create(:user) }
diff --git a/spec/features/projects/compare_spec.rb b/spec/features/projects/compare_spec.rb
index df5cec80ae4..865ae3ad8cb 100644
--- a/spec/features/projects/compare_spec.rb
+++ b/spec/features/projects/compare_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "Compare", :js do
+RSpec.describe "Compare", :js do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
diff --git a/spec/features/projects/container_registry_spec.rb b/spec/features/projects/container_registry_spec.rb
index a75da5f1080..f561149d2ad 100644
--- a/spec/features/projects/container_registry_spec.rb
+++ b/spec/features/projects/container_registry_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Container Registry', :js do
+RSpec.describe 'Container Registry', :js do
let(:user) { create(:user) }
let(:project) { create(:project) }
@@ -30,10 +30,10 @@ describe 'Container Registry', :js do
expect(page).to have_content _('There are no container images stored for this project')
end
- it 'list page has quickstart' do
+ it 'list page has cli commands' do
visit_container_registry
- expect(page).to have_content _('Quick Start')
+ expect(page).to have_content _('CLI Commands')
end
end
@@ -84,7 +84,7 @@ describe 'Container Registry', :js do
expect(service).to receive(:execute).with(container_repository) { { status: :success } }
expect(Projects::ContainerRepository::DeleteTagsService).to receive(:new).with(container_repository.project, user, tags: ['1']) { service }
- first('.js-delete-registry').click
+ first('[data-testid="singleDeleteButton"]').click
expect(find('.modal .modal-title')).to have_content _('Remove tag')
find('.modal .modal-footer .btn-danger').click
end
diff --git a/spec/features/projects/deploy_keys_spec.rb b/spec/features/projects/deploy_keys_spec.rb
index 687b6461f05..70d47516246 100644
--- a/spec/features/projects/deploy_keys_spec.rb
+++ b/spec/features/projects/deploy_keys_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project deploy keys', :js do
+RSpec.describe 'Project deploy keys', :js do
let(:user) { create(:user) }
let(:project) { create(:project_empty_repo) }
diff --git a/spec/features/projects/diffs/diff_show_spec.rb b/spec/features/projects/diffs/diff_show_spec.rb
index df94d6debd6..19f111a727b 100644
--- a/spec/features/projects/diffs/diff_show_spec.rb
+++ b/spec/features/projects/diffs/diff_show_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Diff file viewer', :js do
+RSpec.describe 'Diff file viewer', :js do
let(:project) { create(:project, :public, :repository) }
def visit_commit(sha, anchor: nil)
diff --git a/spec/features/projects/environments/environment_metrics_spec.rb b/spec/features/projects/environments/environment_metrics_spec.rb
index 150df66bdd7..a3b979d0f42 100644
--- a/spec/features/projects/environments/environment_metrics_spec.rb
+++ b/spec/features/projects/environments/environment_metrics_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Environment > Metrics' do
+RSpec.describe 'Environment > Metrics' do
include PrometheusHelpers
let(:user) { create(:user) }
diff --git a/spec/features/projects/environments/environment_spec.rb b/spec/features/projects/environments/environment_spec.rb
index bbd33225bb9..fa10e429af2 100644
--- a/spec/features/projects/environments/environment_spec.rb
+++ b/spec/features/projects/environments/environment_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Environment' do
+RSpec.describe 'Environment' do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:role) { :developer }
diff --git a/spec/features/projects/environments/environments_spec.rb b/spec/features/projects/environments/environments_spec.rb
index cee9b6d50ba..b3f671d57a9 100644
--- a/spec/features/projects/environments/environments_spec.rb
+++ b/spec/features/projects/environments/environments_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Environments page', :js do
+RSpec.describe 'Environments page', :js do
let(:project) { create(:project) }
let(:user) { create(:user) }
let(:role) { :developer }
diff --git a/spec/features/projects/environments_pod_logs_spec.rb b/spec/features/projects/environments_pod_logs_spec.rb
index 32eaf690950..82dafbc6237 100644
--- a/spec/features/projects/environments_pod_logs_spec.rb
+++ b/spec/features/projects/environments_pod_logs_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Environment > Pod Logs', :js, :kubeclient do
+RSpec.describe 'Environment > Pod Logs', :js, :kubeclient do
include KubernetesHelpers
let(:pod_names) { %w(kube-pod) }
diff --git a/spec/features/projects/features_visibility_spec.rb b/spec/features/projects/features_visibility_spec.rb
index 9854335a7ad..d84c39de8d8 100644
--- a/spec/features/projects/features_visibility_spec.rb
+++ b/spec/features/projects/features_visibility_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Edit Project Settings' do
+RSpec.describe 'Edit Project Settings' do
let(:member) { create(:user) }
let!(:project) { create(:project, :public, :repository) }
let!(:issue) { create(:issue, project: project) }
@@ -94,7 +94,7 @@ describe 'Edit Project Settings' do
{
builds: project_job_path(project, job),
issues: project_issues_path(project),
- wiki: project_wiki_path(project, :home),
+ wiki: wiki_path(project.wiki),
snippets: project_snippets_path(project),
merge_requests: project_merge_requests_path(project)
}
diff --git a/spec/features/projects/files/dockerfile_dropdown_spec.rb b/spec/features/projects/files/dockerfile_dropdown_spec.rb
index 756f2f2d493..a99df8a79d8 100644
--- a/spec/features/projects/files/dockerfile_dropdown_spec.rb
+++ b/spec/features/projects/files/dockerfile_dropdown_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Files > User wants to add a Dockerfile file' do
+RSpec.describe 'Projects > Files > User wants to add a Dockerfile file' do
before do
project = create(:project, :repository)
sign_in project.owner
diff --git a/spec/features/projects/files/download_buttons_spec.rb b/spec/features/projects/files/download_buttons_spec.rb
index 871f5212ddd..a486d7517ac 100644
--- a/spec/features/projects/files/download_buttons_spec.rb
+++ b/spec/features/projects/files/download_buttons_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Files > Download buttons in files tree' do
+RSpec.describe 'Projects > Files > Download buttons in files tree' do
let(:project) { create(:project, :repository) }
let(:user) { project.creator }
diff --git a/spec/features/projects/files/edit_file_soft_wrap_spec.rb b/spec/features/projects/files/edit_file_soft_wrap_spec.rb
index 53b1a522a8e..ede22204dbd 100644
--- a/spec/features/projects/files/edit_file_soft_wrap_spec.rb
+++ b/spec/features/projects/files/edit_file_soft_wrap_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Files > User uses soft wrap while editing file', :js do
+RSpec.describe 'Projects > Files > User uses soft wrap while editing file', :js do
before do
project = create(:project, :repository)
user = project.owner
diff --git a/spec/features/projects/files/editing_a_file_spec.rb b/spec/features/projects/files/editing_a_file_spec.rb
index 085276f96a8..819864b3def 100644
--- a/spec/features/projects/files/editing_a_file_spec.rb
+++ b/spec/features/projects/files/editing_a_file_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Files > User wants to edit a file' do
+RSpec.describe 'Projects > Files > User wants to edit a file' do
let(:project) { create(:project, :repository) }
let(:user) { project.owner }
let(:commit_params) do
diff --git a/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb b/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb
index 622764487d8..94190889ace 100644
--- a/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb
+++ b/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Files > User views files page' do
+RSpec.describe 'Projects > Files > User views files page' do
let(:project) { create(:forked_project_with_submodules) }
let(:user) { project.owner }
diff --git a/spec/features/projects/files/find_file_keyboard_spec.rb b/spec/features/projects/files/find_file_keyboard_spec.rb
index b680be09444..4293183fd9a 100644
--- a/spec/features/projects/files/find_file_keyboard_spec.rb
+++ b/spec/features/projects/files/find_file_keyboard_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Files > Find file keyboard shortcuts', :js do
+RSpec.describe 'Projects > Files > Find file keyboard shortcuts', :js do
let(:project) { create(:project, :repository) }
let(:user) { project.owner }
diff --git a/spec/features/projects/files/gitignore_dropdown_spec.rb b/spec/features/projects/files/gitignore_dropdown_spec.rb
index a8c6e780d47..dae1164f7f2 100644
--- a/spec/features/projects/files/gitignore_dropdown_spec.rb
+++ b/spec/features/projects/files/gitignore_dropdown_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Files > User wants to add a .gitignore file' do
+RSpec.describe 'Projects > Files > User wants to add a .gitignore file' do
before do
project = create(:project, :repository)
sign_in project.owner
diff --git a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb
index 107d426a893..879cb6a65c8 100644
--- a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb
+++ b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Files > User wants to add a .gitlab-ci.yml file' do
+RSpec.describe 'Projects > Files > User wants to add a .gitlab-ci.yml file' do
before do
project = create(:project, :repository)
sign_in project.owner
diff --git a/spec/features/projects/files/project_owner_creates_license_file_spec.rb b/spec/features/projects/files/project_owner_creates_license_file_spec.rb
index 9fccb3441d6..ab62e8aabc0 100644
--- a/spec/features/projects/files/project_owner_creates_license_file_spec.rb
+++ b/spec/features/projects/files/project_owner_creates_license_file_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Files > Project owner creates a license file', :js do
+RSpec.describe 'Projects > Files > Project owner creates a license file', :js do
let(:project) { create(:project, :repository) }
let(:project_maintainer) { project.owner }
diff --git a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
index ad6c565c8f9..eed1e7aaf1b 100644
--- a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
+++ b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Files > Project owner sees a link to create a license file in empty project', :js do
+RSpec.describe 'Projects > Files > Project owner sees a link to create a license file in empty project', :js do
let(:project) { create(:project_empty_repo) }
let(:project_maintainer) { project.owner }
diff --git a/spec/features/projects/files/template_selector_menu_spec.rb b/spec/features/projects/files/template_selector_menu_spec.rb
index 838a484d62e..51ae6616d4a 100644
--- a/spec/features/projects/files/template_selector_menu_spec.rb
+++ b/spec/features/projects/files/template_selector_menu_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Template selector menu', :js do
+RSpec.describe 'Template selector menu', :js do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/features/projects/files/template_type_dropdown_spec.rb b/spec/features/projects/files/template_type_dropdown_spec.rb
index 5ea0b9b015f..ca9ce841a92 100644
--- a/spec/features/projects/files/template_type_dropdown_spec.rb
+++ b/spec/features/projects/files/template_type_dropdown_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Files > Template type dropdown selector', :js do
+RSpec.describe 'Projects > Files > Template type dropdown selector', :js do
let(:project) { create(:project, :repository) }
let(:user) { project.owner }
diff --git a/spec/features/projects/files/undo_template_spec.rb b/spec/features/projects/files/undo_template_spec.rb
index 887214e1dbf..09ae595490a 100644
--- a/spec/features/projects/files/undo_template_spec.rb
+++ b/spec/features/projects/files/undo_template_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Files > Template Undo Button', :js do
+RSpec.describe 'Projects > Files > Template Undo Button', :js do
let(:project) { create(:project, :repository) }
let(:user) { project.owner }
diff --git a/spec/features/projects/files/user_browses_a_tree_with_a_folder_containing_only_a_folder_spec.rb b/spec/features/projects/files/user_browses_a_tree_with_a_folder_containing_only_a_folder_spec.rb
index e88fad9d3f7..4d9da783f98 100644
--- a/spec/features/projects/files/user_browses_a_tree_with_a_folder_containing_only_a_folder_spec.rb
+++ b/spec/features/projects/files/user_browses_a_tree_with_a_folder_containing_only_a_folder_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
# This is a regression test for https://gitlab.com/gitlab-org/gitlab-foss/issues/37569
-describe 'Projects > Files > User browses a tree with a folder containing only a folder', :js do
+RSpec.describe 'Projects > Files > User browses a tree with a folder containing only a folder', :js do
let(:project) { create(:project, :empty_repo) }
let(:user) { project.owner }
diff --git a/spec/features/projects/files/user_browses_files_spec.rb b/spec/features/projects/files/user_browses_files_spec.rb
index 7e3d8e5c1c5..44b5833a8c8 100644
--- a/spec/features/projects/files/user_browses_files_spec.rb
+++ b/spec/features/projects/files/user_browses_files_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User browses files" do
+RSpec.describe "User browses files" do
let(:fork_message) do
"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."
diff --git a/spec/features/projects/files/user_browses_lfs_files_spec.rb b/spec/features/projects/files/user_browses_lfs_files_spec.rb
index dbeec973865..ecc56b794b2 100644
--- a/spec/features/projects/files/user_browses_lfs_files_spec.rb
+++ b/spec/features/projects/files/user_browses_lfs_files_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Files > User browses LFS files' do
+RSpec.describe 'Projects > Files > User browses LFS files' do
let(:project) { create(:project, :repository) }
let(:user) { project.owner }
diff --git a/spec/features/projects/files/user_creates_directory_spec.rb b/spec/features/projects/files/user_creates_directory_spec.rb
index 4291f0a74f8..47c5d667f4f 100644
--- a/spec/features/projects/files/user_creates_directory_spec.rb
+++ b/spec/features/projects/files/user_creates_directory_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Files > User creates a directory', :js do
+RSpec.describe 'Projects > Files > User creates a directory', :js do
let(:fork_message) do
"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."
diff --git a/spec/features/projects/files/user_creates_files_spec.rb b/spec/features/projects/files/user_creates_files_spec.rb
index 2d4f22e299e..7d412730115 100644
--- a/spec/features/projects/files/user_creates_files_spec.rb
+++ b/spec/features/projects/files/user_creates_files_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Files > User creates files', :js do
+RSpec.describe 'Projects > Files > User creates files', :js do
let(:fork_message) do
"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."
diff --git a/spec/features/projects/files/user_deletes_files_spec.rb b/spec/features/projects/files/user_deletes_files_spec.rb
index 5e36407d9cb..70f125560e0 100644
--- a/spec/features/projects/files/user_deletes_files_spec.rb
+++ b/spec/features/projects/files/user_deletes_files_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Files > User deletes files', :js do
+RSpec.describe 'Projects > Files > User deletes files', :js do
let(:fork_message) do
"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."
diff --git a/spec/features/projects/files/user_edits_files_spec.rb b/spec/features/projects/files/user_edits_files_spec.rb
index cc428dce2a8..1bb931e35ec 100644
--- a/spec/features/projects/files/user_edits_files_spec.rb
+++ b/spec/features/projects/files/user_edits_files_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Files > User edits files', :js do
+RSpec.describe 'Projects > Files > User edits files', :js do
include ProjectForksHelper
let(:project) { create(:project, :repository, name: 'Shop') }
let(:project2) { create(:project, :repository, name: 'Another Project', path: 'another-project') }
diff --git a/spec/features/projects/files/user_find_file_spec.rb b/spec/features/projects/files/user_find_file_spec.rb
index 72f6ccb20d6..69ea8b0eb5f 100644
--- a/spec/features/projects/files/user_find_file_spec.rb
+++ b/spec/features/projects/files/user_find_file_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User find project file' do
+RSpec.describe 'User find project file' do
let(:user) { create :user }
let(:project) { create :project, :repository }
diff --git a/spec/features/projects/files/user_reads_pipeline_status_spec.rb b/spec/features/projects/files/user_reads_pipeline_status_spec.rb
index 9d38c44b6ef..294a03813cd 100644
--- a/spec/features/projects/files/user_reads_pipeline_status_spec.rb
+++ b/spec/features/projects/files/user_reads_pipeline_status_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'user reads pipeline status', :js do
+RSpec.describe 'user reads pipeline status', :js do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:v110_pipeline) { create_pipeline('v1.1.0', 'success') }
diff --git a/spec/features/projects/files/user_replaces_files_spec.rb b/spec/features/projects/files/user_replaces_files_spec.rb
index e1eefdcc40f..1d4085ef21c 100644
--- a/spec/features/projects/files/user_replaces_files_spec.rb
+++ b/spec/features/projects/files/user_replaces_files_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Files > User replaces files', :js do
+RSpec.describe 'Projects > Files > User replaces files', :js do
include DropzoneHelper
let(:fork_message) do
diff --git a/spec/features/projects/files/user_searches_for_files_spec.rb b/spec/features/projects/files/user_searches_for_files_spec.rb
index ff7547bce83..7fd7dfff279 100644
--- a/spec/features/projects/files/user_searches_for_files_spec.rb
+++ b/spec/features/projects/files/user_searches_for_files_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Files > User searches for files' do
+RSpec.describe 'Projects > Files > User searches for files' do
let(:user) { project.owner }
before do
diff --git a/spec/features/projects/files/user_uploads_files_spec.rb b/spec/features/projects/files/user_uploads_files_spec.rb
index ecf40969541..944d08df3f3 100644
--- a/spec/features/projects/files/user_uploads_files_spec.rb
+++ b/spec/features/projects/files/user_uploads_files_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Files > User uploads files' do
+RSpec.describe 'Projects > Files > User uploads files' do
include DropzoneHelper
let(:user) { create(:user) }
diff --git a/spec/features/projects/fork_spec.rb b/spec/features/projects/fork_spec.rb
index bfab4387688..f0ed4013230 100644
--- a/spec/features/projects/fork_spec.rb
+++ b/spec/features/projects/fork_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project fork' do
+RSpec.describe 'Project fork' do
include ProjectForksHelper
let(:user) { create(:user) }
diff --git a/spec/features/projects/forks/fork_list_spec.rb b/spec/features/projects/forks/fork_list_spec.rb
index 3b63d9a4c2d..b48c46ef8cb 100644
--- a/spec/features/projects/forks/fork_list_spec.rb
+++ b/spec/features/projects/forks/fork_list_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'listing forks of a project' do
+RSpec.describe 'listing forks of a project' do
include ProjectForksHelper
include ExternalAuthorizationServiceHelpers
diff --git a/spec/features/projects/gfm_autocomplete_load_spec.rb b/spec/features/projects/gfm_autocomplete_load_spec.rb
index ad39dec0a43..b02483be489 100644
--- a/spec/features/projects/gfm_autocomplete_load_spec.rb
+++ b/spec/features/projects/gfm_autocomplete_load_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'GFM autocomplete loading', :js do
+RSpec.describe 'GFM autocomplete loading', :js do
let(:project) { create(:project) }
before do
diff --git a/spec/features/projects/graph_spec.rb b/spec/features/projects/graph_spec.rb
index 25efb7b28a7..7b9f79c9f7f 100644
--- a/spec/features/projects/graph_spec.rb
+++ b/spec/features/projects/graph_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project Graph', :js do
+RSpec.describe 'Project Graph', :js do
let(:user) { create :user }
let(:project) { create(:project, :repository, namespace: user.namespace) }
let(:branch_name) { 'master' }
diff --git a/spec/features/projects/hook_logs/user_reads_log_spec.rb b/spec/features/projects/hook_logs/user_reads_log_spec.rb
index 8c666f5d67a..8513a9374d1 100644
--- a/spec/features/projects/hook_logs/user_reads_log_spec.rb
+++ b/spec/features/projects/hook_logs/user_reads_log_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Hook logs' do
+RSpec.describe 'Hook logs' do
let(:web_hook_log) { create(:web_hook_log, response_body: '<script>') }
let(:project) { web_hook_log.web_hook.project }
let(:user) { create(:user) }
diff --git a/spec/features/projects/import_export/export_file_spec.rb b/spec/features/projects/import_export/export_file_spec.rb
index 1d6d5ae1b4d..86aeb2bc80c 100644
--- a/spec/features/projects/import_export/export_file_spec.rb
+++ b/spec/features/projects/import_export/export_file_spec.rb
@@ -6,7 +6,7 @@ require 'spec_helper'
# It looks up for any sensitive word inside the JSON, so if a sensitive word is found
# we'll have to either include it adding the model that includes it to the +safe_list+
# or make sure the attribute is blacklisted in the +import_export.yml+ configuration
-describe 'Import/Export - project export integration test', :js do
+RSpec.describe 'Import/Export - project export integration test', :js do
include Select2Helper
include ExportFileHelper
diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb
index 33c7182c084..83ceffa621c 100644
--- a/spec/features/projects/import_export/import_file_spec.rb
+++ b/spec/features/projects/import_export/import_file_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Import/Export - project import integration test', :js do
+RSpec.describe 'Import/Export - project import integration test', :js do
include GitHelpers
let(:user) { create(:user) }
diff --git a/spec/features/projects/issuable_templates_spec.rb b/spec/features/projects/issuable_templates_spec.rb
index 4b6f1672f08..8f1c31f229f 100644
--- a/spec/features/projects/issuable_templates_spec.rb
+++ b/spec/features/projects/issuable_templates_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'issuable templates', :js do
+RSpec.describe 'issuable templates', :js do
include ProjectForksHelper
let(:user) { create(:user) }
diff --git a/spec/features/projects/issues/design_management/user_links_to_designs_in_issue_spec.rb b/spec/features/projects/issues/design_management/user_links_to_designs_in_issue_spec.rb
new file mode 100644
index 00000000000..8d5e99d7e2b
--- /dev/null
+++ b/spec/features/projects/issues/design_management/user_links_to_designs_in_issue_spec.rb
@@ -0,0 +1,123 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'viewing issues with design references' do
+ include DesignManagementTestHelpers
+
+ let_it_be(:public_project) { create(:project_empty_repo, :public) }
+ let_it_be(:private_project) { create(:project_empty_repo) }
+
+ let(:user) { create(:user) }
+ let(:design_issue) { create(:issue, project: project) }
+ let(:design_a) { create(:design, :with_file, issue: design_issue) }
+ let(:design_b) { create(:design, :with_file, issue: design_issue) }
+ let(:issue_ref) { design_issue.to_reference(public_project) }
+ let(:design_ref_a) { design_a.to_reference(public_project) }
+ let(:design_ref_b) { design_b.to_reference(public_project) }
+ let(:design_tab_ref) { "#{issue_ref} (designs)" }
+
+ let(:description) do
+ <<~MD
+ The designs I mentioned:
+
+ * #{url_for_designs(design_issue)}
+ * #{url_for_design(design_a)}
+ * #{url_for_design(design_b)}
+ MD
+ end
+
+ def visit_page_with_design_references
+ public_issue = create(:issue, project: public_project, description: description)
+ visit project_issue_path(public_issue.project, public_issue)
+ end
+
+ shared_examples 'successful use of design link references' do
+ before do
+ enable_design_management
+ end
+
+ it 'shows the issue description and design references', :aggregate_failures do
+ visit_page_with_design_references
+
+ expect(page).to have_text('The designs I mentioned')
+ expect(page).to have_link(design_tab_ref)
+ expect(page).to have_link(design_ref_a)
+ expect(page).to have_link(design_ref_b)
+ end
+ end
+
+ context 'the user has access to a public project' do
+ let(:project) { public_project }
+
+ it_behaves_like 'successful use of design link references'
+ end
+
+ context 'the user does not have access to a private project' do
+ let(:project) { private_project }
+
+ it 'redacts inaccessible design references', :aggregate_failures do
+ visit_page_with_design_references
+
+ expect(page).to have_text('The designs I mentioned')
+ expect(page).not_to have_link(issue_ref)
+ expect(page).not_to have_link(design_tab_ref)
+ expect(page).not_to have_link(design_ref_a)
+ expect(page).not_to have_link(design_ref_b)
+ end
+ end
+
+ context 'the user has access to a private project' do
+ let(:project) { private_project }
+
+ before do
+ project.add_developer(user)
+ sign_in(user)
+ end
+
+ it_behaves_like 'successful use of design link references'
+
+ context 'design management is entirely disabled' do
+ it 'processes design links as issue references', :aggregate_failures do
+ enable_design_management(false)
+
+ visit_page_with_design_references
+
+ expect(page).to have_text('The designs I mentioned')
+ expect(page).to have_link(issue_ref)
+ expect(page).not_to have_link(design_tab_ref)
+ expect(page).not_to have_link(design_ref_a)
+ expect(page).not_to have_link(design_ref_b)
+ end
+ end
+
+ context 'design management is enabled, but the filter is disabled globally' do
+ before do
+ enable_design_management
+ stub_feature_flags(
+ Banzai::Filter::DesignReferenceFilter::FEATURE_FLAG => false
+ )
+ end
+
+ it 'processes design tab links successfully, and design references as issue references', :aggregate_failures do
+ visit_page_with_design_references
+
+ expect(page).to have_text('The designs I mentioned')
+ expect(page).to have_link(design_tab_ref)
+ expect(page).to have_link(issue_ref)
+ expect(page).not_to have_link(design_ref_a)
+ expect(page).not_to have_link(design_ref_b)
+ end
+ end
+
+ context 'design management is enabled, and the filter is enabled for the current project' do
+ before do
+ stub_feature_flags(
+ Banzai::Filter::DesignReferenceFilter::FEATURE_FLAG => public_project
+ )
+ end
+
+ it_behaves_like 'successful use of design link references'
+ end
+ end
+end
diff --git a/spec/features/projects/issues/design_management/user_paginates_designs_spec.rb b/spec/features/projects/issues/design_management/user_paginates_designs_spec.rb
index d9a72f2d5c5..f871ca60596 100644
--- a/spec/features/projects/issues/design_management/user_paginates_designs_spec.rb
+++ b/spec/features/projects/issues/design_management/user_paginates_designs_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User paginates issue designs', :js do
+RSpec.describe 'User paginates issue designs', :js do
include DesignManagementTestHelpers
let(:project) { create(:project_empty_repo, :public) }
diff --git a/spec/features/projects/issues/design_management/user_permissions_upload_spec.rb b/spec/features/projects/issues/design_management/user_permissions_upload_spec.rb
index 2238e86a47f..902a84afc83 100644
--- a/spec/features/projects/issues/design_management/user_permissions_upload_spec.rb
+++ b/spec/features/projects/issues/design_management/user_permissions_upload_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User design permissions', :js do
+RSpec.describe 'User design permissions', :js do
include DesignManagementTestHelpers
let(:project) { create(:project_empty_repo, :public) }
diff --git a/spec/features/projects/issues/design_management/user_uploads_designs_spec.rb b/spec/features/projects/issues/design_management/user_uploads_designs_spec.rb
index d160ab95a65..66b449a9de5 100644
--- a/spec/features/projects/issues/design_management/user_uploads_designs_spec.rb
+++ b/spec/features/projects/issues/design_management/user_uploads_designs_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User uploads new design', :js do
+RSpec.describe 'User uploads new design', :js do
include DesignManagementTestHelpers
let_it_be(:project) { create(:project_empty_repo, :public) }
diff --git a/spec/features/projects/issues/design_management/user_views_design_images_spec.rb b/spec/features/projects/issues/design_management/user_views_design_images_spec.rb
index 3d0f4df55c4..4a4c33cb881 100644
--- a/spec/features/projects/issues/design_management/user_views_design_images_spec.rb
+++ b/spec/features/projects/issues/design_management/user_views_design_images_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Users views raw design image files' do
+RSpec.describe 'Users views raw design image files' do
include DesignManagementTestHelpers
let_it_be(:project) { create(:project, :public) }
diff --git a/spec/features/projects/issues/design_management/user_views_design_spec.rb b/spec/features/projects/issues/design_management/user_views_design_spec.rb
index 707049b0068..527442d5339 100644
--- a/spec/features/projects/issues/design_management/user_views_design_spec.rb
+++ b/spec/features/projects/issues/design_management/user_views_design_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views issue designs', :js do
+RSpec.describe 'User views issue designs', :js do
include DesignManagementTestHelpers
let_it_be(:project) { create(:project_empty_repo, :public) }
diff --git a/spec/features/projects/issues/design_management/user_views_designs_spec.rb b/spec/features/projects/issues/design_management/user_views_designs_spec.rb
index a4fb7456922..d371ae1aad7 100644
--- a/spec/features/projects/issues/design_management/user_views_designs_spec.rb
+++ b/spec/features/projects/issues/design_management/user_views_designs_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views issue designs', :js do
+RSpec.describe 'User views issue designs', :js do
include DesignManagementTestHelpers
let_it_be(:project) { create(:project_empty_repo, :public) }
diff --git a/spec/features/projects/issues/design_management/user_views_designs_with_svg_xss_spec.rb b/spec/features/projects/issues/design_management/user_views_designs_with_svg_xss_spec.rb
index a9e4aa899a7..5bc1271309c 100644
--- a/spec/features/projects/issues/design_management/user_views_designs_with_svg_xss_spec.rb
+++ b/spec/features/projects/issues/design_management/user_views_designs_with_svg_xss_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views an SVG design that contains XSS', :js do
+RSpec.describe 'User views an SVG design that contains XSS', :js do
include DesignManagementTestHelpers
let(:project) { create(:project_empty_repo, :public) }
diff --git a/spec/features/projects/issues/viewing_issues_with_external_authorization_enabled_spec.rb b/spec/features/projects/issues/viewing_issues_with_external_authorization_enabled_spec.rb
index 6c8f4b51ea0..6feefff9207 100644
--- a/spec/features/projects/issues/viewing_issues_with_external_authorization_enabled_spec.rb
+++ b/spec/features/projects/issues/viewing_issues_with_external_authorization_enabled_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'viewing an issue with cross project references' do
+RSpec.describe 'viewing an issue with cross project references' do
include ExternalAuthorizationServiceHelpers
include Gitlab::Routing.url_helpers
diff --git a/spec/features/projects/jobs/permissions_spec.rb b/spec/features/projects/jobs/permissions_spec.rb
index d78cf674dc6..7f46a369dd6 100644
--- a/spec/features/projects/jobs/permissions_spec.rb
+++ b/spec/features/projects/jobs/permissions_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project Jobs Permissions' do
+RSpec.describe 'Project Jobs Permissions' do
let(:user) { create(:user) }
let(:group) { create(:group, name: 'some group') }
let(:project) { create(:project, :repository, namespace: group) }
diff --git a/spec/features/projects/jobs/user_browses_job_spec.rb b/spec/features/projects/jobs/user_browses_job_spec.rb
index 16ba1c1b73d..67299e852b3 100644
--- a/spec/features/projects/jobs/user_browses_job_spec.rb
+++ b/spec/features/projects/jobs/user_browses_job_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User browses a job', :js do
+RSpec.describe 'User browses a job', :js do
let(:user) { create(:user) }
let(:user_access_level) { :developer }
let(:project) { create(:project, :repository, namespace: user.namespace) }
diff --git a/spec/features/projects/jobs/user_browses_jobs_spec.rb b/spec/features/projects/jobs/user_browses_jobs_spec.rb
index 44709cb1230..c768b0e281c 100644
--- a/spec/features/projects/jobs/user_browses_jobs_spec.rb
+++ b/spec/features/projects/jobs/user_browses_jobs_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User browses jobs' do
+RSpec.describe 'User browses jobs' do
let!(:build) { create(:ci_build, :coverage, pipeline: pipeline) }
let(:pipeline) { create(:ci_empty_pipeline, project: project, sha: project.commit.sha, ref: 'master') }
let(:project) { create(:project, :repository, namespace: user.namespace) }
diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb
index a17793bc6d6..e78e8989575 100644
--- a/spec/features/projects/jobs_spec.rb
+++ b/spec/features/projects/jobs_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require 'tempfile'
-describe 'Jobs', :clean_gitlab_redis_shared_state do
+RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
include Gitlab::Routing
include ProjectForksHelper
@@ -940,7 +940,7 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do
it 'renders message about job being stuck because of no runners with the specified tags' do
expect(page).to have_css('.js-stuck-with-tags')
- expect(page).to have_content("This job is stuck because you don't have any active runners online with any of these tags assigned to them:")
+ expect(page).to have_content("This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:")
end
end
@@ -950,7 +950,7 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do
it 'renders message about job being stuck because of no runners with the specified tags' do
expect(page).to have_css('.js-stuck-with-tags')
- expect(page).to have_content("This job is stuck because you don't have any active runners online with any of these tags assigned to them:")
+ expect(page).to have_content("This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:")
end
end
diff --git a/spec/features/projects/labels/issues_sorted_by_priority_spec.rb b/spec/features/projects/labels/issues_sorted_by_priority_spec.rb
index 503ac8caddf..66d61e629df 100644
--- a/spec/features/projects/labels/issues_sorted_by_priority_spec.rb
+++ b/spec/features/projects/labels/issues_sorted_by_priority_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Issue prioritization' do
+RSpec.describe 'Issue prioritization' do
let(:user) { create(:user) }
let(:project) { create(:project, name: 'test', namespace: user.namespace) }
diff --git a/spec/features/projects/labels/search_labels_spec.rb b/spec/features/projects/labels/search_labels_spec.rb
index e2eec7400ff..04dfd4ca5f1 100644
--- a/spec/features/projects/labels/search_labels_spec.rb
+++ b/spec/features/projects/labels/search_labels_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Search for labels', :js do
+RSpec.describe 'Search for labels', :js do
let(:user) { create(:user) }
let(:project) { create(:project) }
let!(:label1) { create(:label, title: 'Foo', description: 'Lorem ipsum', project: project) }
diff --git a/spec/features/projects/labels/sort_labels_spec.rb b/spec/features/projects/labels/sort_labels_spec.rb
index 01c3f251173..83559b816d2 100644
--- a/spec/features/projects/labels/sort_labels_spec.rb
+++ b/spec/features/projects/labels/sort_labels_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Sort labels', :js do
+RSpec.describe 'Sort labels', :js do
let(:user) { create(:user) }
let(:project) { create(:project) }
let!(:label1) { create(:label, title: 'Foo', description: 'Lorem ipsum', project: project) }
diff --git a/spec/features/projects/labels/subscription_spec.rb b/spec/features/projects/labels/subscription_spec.rb
index 1d0f9e73a1b..7ca8a542c21 100644
--- a/spec/features/projects/labels/subscription_spec.rb
+++ b/spec/features/projects/labels/subscription_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Labels subscription' do
+RSpec.describe 'Labels subscription' do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:project) { create(:project, :public, namespace: group) }
diff --git a/spec/features/projects/labels/update_prioritization_spec.rb b/spec/features/projects/labels/update_prioritization_spec.rb
index 3a37ee6623d..706ea92c086 100644
--- a/spec/features/projects/labels/update_prioritization_spec.rb
+++ b/spec/features/projects/labels/update_prioritization_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Prioritize labels' do
+RSpec.describe 'Prioritize labels' do
include DragTo
let(:user) { create(:user) }
diff --git a/spec/features/projects/labels/user_creates_labels_spec.rb b/spec/features/projects/labels/user_creates_labels_spec.rb
index 180cd8eff14..001d23cd2c9 100644
--- a/spec/features/projects/labels/user_creates_labels_spec.rb
+++ b/spec/features/projects/labels/user_creates_labels_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User creates labels" do
+RSpec.describe "User creates labels" do
let_it_be(:project) { create(:project_empty_repo, :public) }
let_it_be(:user) { create(:user) }
diff --git a/spec/features/projects/labels/user_edits_labels_spec.rb b/spec/features/projects/labels/user_edits_labels_spec.rb
index add959ccda6..8300a1a8542 100644
--- a/spec/features/projects/labels/user_edits_labels_spec.rb
+++ b/spec/features/projects/labels/user_edits_labels_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User edits labels" do
+RSpec.describe "User edits labels" do
let_it_be(:project) { create(:project_empty_repo, :public) }
let_it_be(:label) { create(:label, project: project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/features/projects/labels/user_promotes_label_spec.rb b/spec/features/projects/labels/user_promotes_label_spec.rb
index cf7320d3cf9..4cb22c2e48c 100644
--- a/spec/features/projects/labels/user_promotes_label_spec.rb
+++ b/spec/features/projects/labels/user_promotes_label_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User promotes label' do
+RSpec.describe 'User promotes label' do
let_it_be(:group) { create(:group) }
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, namespace: group) }
diff --git a/spec/features/projects/labels/user_removes_labels_spec.rb b/spec/features/projects/labels/user_removes_labels_spec.rb
index 459adeeec30..217f86b92cf 100644
--- a/spec/features/projects/labels/user_removes_labels_spec.rb
+++ b/spec/features/projects/labels/user_removes_labels_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User removes labels" do
+RSpec.describe "User removes labels" do
let(:project) { create(:project_empty_repo, :public) }
let(:user) { create(:user) }
diff --git a/spec/features/projects/labels/user_sees_breadcrumb_links_spec.rb b/spec/features/projects/labels/user_sees_breadcrumb_links_spec.rb
index 68a924e4fad..f9c65c08ec0 100644
--- a/spec/features/projects/labels/user_sees_breadcrumb_links_spec.rb
+++ b/spec/features/projects/labels/user_sees_breadcrumb_links_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'New project label breadcrumb' do
+RSpec.describe 'New project label breadcrumb' do
let(:project) { create(:project) }
let(:user) { project.creator }
diff --git a/spec/features/projects/labels/user_sees_links_to_issuables_spec.rb b/spec/features/projects/labels/user_sees_links_to_issuables_spec.rb
index f60e7e9703f..11aa53fd963 100644
--- a/spec/features/projects/labels/user_sees_links_to_issuables_spec.rb
+++ b/spec/features/projects/labels/user_sees_links_to_issuables_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Labels > User sees links to issuables' do
+RSpec.describe 'Projects > Labels > User sees links to issuables' do
let_it_be(:user) { create(:user) }
before do
diff --git a/spec/features/projects/labels/user_views_labels_spec.rb b/spec/features/projects/labels/user_views_labels_spec.rb
index 7f70ac903d6..da8520ca8fb 100644
--- a/spec/features/projects/labels/user_views_labels_spec.rb
+++ b/spec/features/projects/labels/user_views_labels_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User views labels" do
+RSpec.describe "User views labels" do
let_it_be(:project) { create(:project_empty_repo, :public) }
let_it_be(:user) { create(:user) }
let(:label_titles) { %w[bug enhancement feature] }
diff --git a/spec/features/projects/members/anonymous_user_sees_members_spec.rb b/spec/features/projects/members/anonymous_user_sees_members_spec.rb
index 096cf97551a..3b0f00c5494 100644
--- a/spec/features/projects/members/anonymous_user_sees_members_spec.rb
+++ b/spec/features/projects/members/anonymous_user_sees_members_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Members > Anonymous user sees members' do
+RSpec.describe 'Projects > Members > Anonymous user sees members' do
let(:user) { create(:user) }
let(:group) { create(:group, :public) }
let(:project) { create(:project, :public) }
diff --git a/spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb b/spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb
index b6f6e2ca85f..c8a9f959188 100644
--- a/spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb
+++ b/spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Members > Group member cannot leave group project' do
+RSpec.describe 'Projects > Members > Group member cannot leave group project' do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:project) { create(:project, namespace: group) }
diff --git a/spec/features/projects/members/group_member_cannot_request_access_to_his_group_project_spec.rb b/spec/features/projects/members/group_member_cannot_request_access_to_his_group_project_spec.rb
index cf9441bcd55..34c870b8a96 100644
--- a/spec/features/projects/members/group_member_cannot_request_access_to_his_group_project_spec.rb
+++ b/spec/features/projects/members/group_member_cannot_request_access_to_his_group_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Members > Group member cannot request access to their group project' do
+RSpec.describe 'Projects > Members > Group member cannot request access to their group project' do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:project) { create(:project, namespace: group) }
diff --git a/spec/features/projects/members/group_members_spec.rb b/spec/features/projects/members/group_members_spec.rb
index d37f912a2bc..3060d2c6a43 100644
--- a/spec/features/projects/members/group_members_spec.rb
+++ b/spec/features/projects/members/group_members_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects members' do
+RSpec.describe 'Projects members' do
let(:user) { create(:user) }
let(:developer) { create(:user) }
let(:group) { create(:group, :public) }
@@ -21,7 +21,7 @@ describe 'Projects members' do
context 'with a group invitee' do
before do
group_invitee
- visit project_settings_members_path(project)
+ visit project_project_members_path(project)
end
it 'does not appear in the project members page' do
@@ -70,7 +70,7 @@ describe 'Projects members' do
before do
group_invitee
project_invitee
- visit project_settings_members_path(project)
+ visit project_project_members_path(project)
end
it 'shows the project invitee, the project developer, and the group owner' do
@@ -91,7 +91,7 @@ describe 'Projects members' do
context 'with a group requester' do
before do
group.request_access(group_requester)
- visit project_settings_members_path(project)
+ visit project_project_members_path(project)
end
it 'does not appear in the project members page' do
@@ -105,7 +105,7 @@ describe 'Projects members' do
before do
group.request_access(group_requester)
project.request_access(project_requester)
- visit project_settings_members_path(project)
+ visit project_project_members_path(project)
end
it 'shows the project requester, the project developer, and the group owner' do
@@ -129,7 +129,7 @@ describe 'Projects members' do
it_behaves_like 'showing user status' do
let(:user_with_status) { developer }
- subject { visit project_settings_members_path(project) }
+ subject { visit project_project_members_path(project) }
end
end
end
diff --git a/spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb b/spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb
index ecd55f71c84..ec86b7db4fa 100644
--- a/spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb
+++ b/spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Members > Group requester cannot request access to project', :js do
+RSpec.describe 'Projects > Members > Group requester cannot request access to project', :js do
let(:user) { create(:user) }
let(:owner) { create(:user) }
let(:group) { create(:group, :public) }
diff --git a/spec/features/projects/members/groups_with_access_list_spec.rb b/spec/features/projects/members/groups_with_access_list_spec.rb
index 6e8d1a945e1..2ee6bc103e9 100644
--- a/spec/features/projects/members/groups_with_access_list_spec.rb
+++ b/spec/features/projects/members/groups_with_access_list_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Members > Groups with access list', :js do
+RSpec.describe 'Projects > Members > Groups with access list', :js do
let(:user) { create(:user) }
let(:group) { create(:group, :public) }
let(:project) { create(:project, :public) }
@@ -12,7 +12,7 @@ describe 'Projects > Members > Groups with access list', :js do
@group_link = create(:project_group_link, project: project, group: group)
sign_in(user)
- visit project_settings_members_path(project)
+ visit project_project_members_path(project)
end
it 'updates group access level' do
@@ -24,7 +24,7 @@ describe 'Projects > Members > Groups with access list', :js do
wait_for_requests
- visit project_settings_members_path(project)
+ visit project_project_members_path(project)
expect(first('.group_member')).to have_content('Guest')
end
diff --git a/spec/features/projects/members/invite_group_spec.rb b/spec/features/projects/members/invite_group_spec.rb
index e76637039c6..058cbfff662 100644
--- a/spec/features/projects/members/invite_group_spec.rb
+++ b/spec/features/projects/members/invite_group_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project > Members > Invite group', :js do
+RSpec.describe 'Project > Members > Invite group', :js do
include Select2Helper
include ActionView::Helpers::DateHelper
@@ -11,14 +11,14 @@ describe 'Project > Members > Invite group', :js do
describe 'Share with group lock' do
shared_examples 'the project can be shared with groups' do
it 'the "Invite group" tab exists' do
- visit project_settings_members_path(project)
+ visit project_project_members_path(project)
expect(page).to have_selector('#invite-group-tab')
end
end
shared_examples 'the project cannot be shared with groups' do
it 'the "Invite group" tab does not exist' do
- visit project_settings_members_path(project)
+ visit project_project_members_path(project)
expect(page).not_to have_selector('#invite-group-tab')
end
end
@@ -37,7 +37,9 @@ describe 'Project > Members > Invite group', :js do
it_behaves_like 'the project can be shared with groups'
it 'the project can be shared with another group' do
- visit project_settings_members_path(project)
+ visit project_project_members_path(project)
+
+ expect(page).not_to have_css('.project-members-groups')
click_on 'invite-group-tab'
@@ -118,7 +120,7 @@ describe 'Project > Members > Invite group', :js do
group.add_guest(maintainer)
sign_in(maintainer)
- visit project_settings_members_path(project)
+ visit project_project_members_path(project)
click_on 'invite-group-tab'
@@ -151,7 +153,7 @@ describe 'Project > Members > Invite group', :js do
create(:group).add_owner(maintainer)
create(:group).add_owner(maintainer)
- visit project_settings_members_path(project)
+ visit project_project_members_path(project)
click_link 'Invite group'
@@ -184,7 +186,7 @@ describe 'Project > Members > Invite group', :js do
end
it 'the groups dropdown does not show ancestors' do
- visit project_settings_members_path(project)
+ visit project_project_members_path(project)
click_on 'invite-group-tab'
click_link 'Search for a group'
diff --git a/spec/features/projects/members/list_spec.rb b/spec/features/projects/members/list_spec.rb
index f404699b2f6..f51ebde8f80 100644
--- a/spec/features/projects/members/list_spec.rb
+++ b/spec/features/projects/members/list_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project members list' do
+RSpec.describe 'Project members list' do
include Select2Helper
include Spec::Support::Helpers::Features::ListRowsHelpers
@@ -113,6 +113,6 @@ describe 'Project members list' do
end
def visit_members_page
- visit project_settings_members_path(project)
+ visit project_project_members_path(project)
end
end
diff --git a/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb b/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb
index cbcd03b33ce..979bbd57aa3 100644
--- a/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb
+++ b/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Members > Maintainer adds member with expiration date', :js do
+RSpec.describe 'Projects > Members > Maintainer adds member with expiration date', :js do
include Select2Helper
include ActiveSupport::Testing::TimeHelpers
diff --git a/spec/features/projects/members/master_manages_access_requests_spec.rb b/spec/features/projects/members/master_manages_access_requests_spec.rb
index f113fb643f8..4c3eaa93352 100644
--- a/spec/features/projects/members/master_manages_access_requests_spec.rb
+++ b/spec/features/projects/members/master_manages_access_requests_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Members > Maintainer manages access requests' do
+RSpec.describe 'Projects > Members > Maintainer manages access requests' do
it_behaves_like 'Maintainer manages access requests' do
let(:entity) { create(:project, :public) }
let(:members_page_path) { project_project_members_path(entity) }
diff --git a/spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb b/spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb
index e2b57472b2e..fa02e815867 100644
--- a/spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb
+++ b/spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Members > Member cannot request access to their project' do
+RSpec.describe 'Projects > Members > Member cannot request access to their project' do
let(:member) { create(:user) }
let(:project) { create(:project) }
diff --git a/spec/features/projects/members/member_leaves_project_spec.rb b/spec/features/projects/members/member_leaves_project_spec.rb
index cb7a405e821..aa7633c3b28 100644
--- a/spec/features/projects/members/member_leaves_project_spec.rb
+++ b/spec/features/projects/members/member_leaves_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Members > Member leaves project' do
+RSpec.describe 'Projects > Members > Member leaves project' do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
diff --git a/spec/features/projects/members/owner_cannot_leave_project_spec.rb b/spec/features/projects/members/owner_cannot_leave_project_spec.rb
index 781c584796d..fbe8583b236 100644
--- a/spec/features/projects/members/owner_cannot_leave_project_spec.rb
+++ b/spec/features/projects/members/owner_cannot_leave_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Members > Owner cannot leave project' do
+RSpec.describe 'Projects > Members > Owner cannot leave project' do
let(:project) { create(:project) }
before do
diff --git a/spec/features/projects/members/owner_cannot_request_access_to_his_project_spec.rb b/spec/features/projects/members/owner_cannot_request_access_to_his_project_spec.rb
index 5643a29b4e4..5e6e3d4d7f2 100644
--- a/spec/features/projects/members/owner_cannot_request_access_to_his_project_spec.rb
+++ b/spec/features/projects/members/owner_cannot_request_access_to_his_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Members > Owner cannot request access to their own project' do
+RSpec.describe 'Projects > Members > Owner cannot request access to their own project' do
let(:project) { create(:project) }
before do
diff --git a/spec/features/projects/members/sorting_spec.rb b/spec/features/projects/members/sorting_spec.rb
index 12f485317d8..be27cbc0d66 100644
--- a/spec/features/projects/members/sorting_spec.rb
+++ b/spec/features/projects/members/sorting_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Members > Sorting' do
+RSpec.describe 'Projects > Members > Sorting' do
let(:maintainer) { create(:user, name: 'John Doe') }
let(:developer) { create(:user, name: 'Mary Jane', last_sign_in_at: 5.days.ago) }
let(:project) { create(:project, namespace: maintainer.namespace, creator: maintainer) }
diff --git a/spec/features/projects/members/user_requests_access_spec.rb b/spec/features/projects/members/user_requests_access_spec.rb
index 7e7faca9741..a339130ee3c 100644
--- a/spec/features/projects/members/user_requests_access_spec.rb
+++ b/spec/features/projects/members/user_requests_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Members > User requests access', :js do
+RSpec.describe 'Projects > Members > User requests access', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :public, :repository) }
let(:maintainer) { project.owner }
diff --git a/spec/features/projects/merge_request_button_spec.rb b/spec/features/projects/merge_request_button_spec.rb
index 950af8b0ae0..e3d8534ace9 100644
--- a/spec/features/projects/merge_request_button_spec.rb
+++ b/spec/features/projects/merge_request_button_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge Request button' do
+RSpec.describe 'Merge Request button' do
shared_examples 'Merge request button only shown when allowed' do
let(:user) { create(:user) }
let(:project) { create(:project, :public, :repository) }
diff --git a/spec/features/projects/milestones/milestone_spec.rb b/spec/features/projects/milestones/milestone_spec.rb
index fb9667cd67d..9ffb1746f3e 100644
--- a/spec/features/projects/milestones/milestone_spec.rb
+++ b/spec/features/projects/milestones/milestone_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project milestone' do
+RSpec.describe 'Project milestone' do
let(:user) { create(:user) }
let(:project) { create(:project, name: 'test', namespace: user.namespace) }
let(:milestone) { create(:milestone, project: project) }
diff --git a/spec/features/projects/milestones/milestones_sorting_spec.rb b/spec/features/projects/milestones/milestones_sorting_spec.rb
index 77cf696fb7c..565c61cfaa0 100644
--- a/spec/features/projects/milestones/milestones_sorting_spec.rb
+++ b/spec/features/projects/milestones/milestones_sorting_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Milestones sorting', :js do
+RSpec.describe 'Milestones sorting', :js do
let(:user) { create(:user) }
let(:project) { create(:project, name: 'test', namespace: user.namespace) }
diff --git a/spec/features/projects/milestones/new_spec.rb b/spec/features/projects/milestones/new_spec.rb
index b1b74bed59d..170268297cd 100644
--- a/spec/features/projects/milestones/new_spec.rb
+++ b/spec/features/projects/milestones/new_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Creating a new project milestone', :js do
+RSpec.describe 'Creating a new project milestone', :js do
let(:user) { create(:user) }
let(:project) { create(:project, name: 'test', namespace: user.namespace) }
diff --git a/spec/features/projects/milestones/user_interacts_with_labels_spec.rb b/spec/features/projects/milestones/user_interacts_with_labels_spec.rb
index 0177871599a..d658599c52b 100644
--- a/spec/features/projects/milestones/user_interacts_with_labels_spec.rb
+++ b/spec/features/projects/milestones/user_interacts_with_labels_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User interacts with labels' do
+RSpec.describe 'User interacts with labels' do
let(:user) { create(:user) }
let(:project) { create(:project, namespace: user.namespace) }
let(:milestone) { create(:milestone, project: project, title: 'v2.2', description: '# Description header') }
diff --git a/spec/features/projects/navbar_spec.rb b/spec/features/projects/navbar_spec.rb
index 1797ca8aa7d..94d79d60aeb 100644
--- a/spec/features/projects/navbar_spec.rb
+++ b/spec/features/projects/navbar_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project navbar' do
+RSpec.describe 'Project navbar' do
include NavbarStructureHelper
include WaitForRequests
diff --git a/spec/features/projects/network_graph_spec.rb b/spec/features/projects/network_graph_spec.rb
index 2f6a2e90ab9..4ae809399b6 100644
--- a/spec/features/projects/network_graph_spec.rb
+++ b/spec/features/projects/network_graph_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project Network Graph', :js do
+RSpec.describe 'Project Network Graph', :js do
let(:user) { create :user }
let(:project) { create :project, :repository, namespace: user.namespace }
diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb
index 22a0d268243..6a2ec9aa4a8 100644
--- a/spec/features/projects/new_project_spec.rb
+++ b/spec/features/projects/new_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'New project' do
+RSpec.describe 'New project' do
include Select2Helper
context 'as a user' do
diff --git a/spec/features/projects/pages_lets_encrypt_spec.rb b/spec/features/projects/pages_lets_encrypt_spec.rb
index da9b191271a..302e9f5e533 100644
--- a/spec/features/projects/pages_lets_encrypt_spec.rb
+++ b/spec/features/projects/pages_lets_encrypt_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe "Pages with Let's Encrypt", :https_pages_enabled do
+RSpec.describe "Pages with Let's Encrypt", :https_pages_enabled do
include LetsEncryptHelpers
let(:project) { create(:project, pages_https_only: false) }
diff --git a/spec/features/projects/pages_spec.rb b/spec/features/projects/pages_spec.rb
index faa2b3c9424..e1ace817c72 100644
--- a/spec/features/projects/pages_spec.rb
+++ b/spec/features/projects/pages_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-shared_examples 'pages settings editing' do
+RSpec.shared_examples 'pages settings editing' do
let_it_be(:project) { create(:project, pages_https_only: false) }
let(:user) { create(:user) }
let(:role) { :maintainer }
@@ -394,7 +394,7 @@ shared_examples 'pages settings editing' do
end
end
-describe 'Pages', :js do
+RSpec.describe 'Pages', :js do
include LetsEncryptHelpers
context 'when editing normally' do
diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb
index c21b1e36f9a..921bbbfbe7d 100644
--- a/spec/features/projects/pipeline_schedules_spec.rb
+++ b/spec/features/projects/pipeline_schedules_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Pipeline Schedules', :js do
+RSpec.describe 'Pipeline Schedules', :js do
include PipelineSchedulesHelper
let!(:project) { create(:project, :repository) }
diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb
index de81547887b..c6a002ad18b 100644
--- a/spec/features/projects/pipelines/pipeline_spec.rb
+++ b/spec/features/projects/pipelines/pipeline_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Pipeline', :js do
+RSpec.describe 'Pipeline', :js do
include RoutesHelpers
include ProjectForksHelper
include ::ExclusiveLeaseHelpers
diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb
index 7634100347e..0e33204f851 100644
--- a/spec/features/projects/pipelines/pipelines_spec.rb
+++ b/spec/features/projects/pipelines/pipelines_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Pipelines', :js do
+RSpec.describe 'Pipelines', :js do
include ProjectForksHelper
let(:project) { create(:project) }
@@ -453,10 +453,12 @@ describe 'Pipelines', :js do
context 'downloadable pipelines' do
context 'with artifacts' do
let!(:with_artifacts) do
- create(:ci_build, :artifacts, :success,
+ build = create(:ci_build, :success,
pipeline: pipeline,
name: 'rspec tests',
stage: 'test')
+
+ create(:ci_job_artifact, :codequality, job: build)
end
before do
@@ -470,7 +472,7 @@ describe 'Pipelines', :js do
it 'has artifacts download dropdown' do
find('.js-pipeline-dropdown-download').click
- expect(page).to have_link(with_artifacts.name)
+ expect(page).to have_link(with_artifacts.file_type)
end
it 'has download attribute on download links' do
diff --git a/spec/features/projects/raw/user_interacts_with_raw_endpoint_spec.rb b/spec/features/projects/raw/user_interacts_with_raw_endpoint_spec.rb
index 673766073a2..6745eb1a3fb 100644
--- a/spec/features/projects/raw/user_interacts_with_raw_endpoint_spec.rb
+++ b/spec/features/projects/raw/user_interacts_with_raw_endpoint_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Raw > User interacts with raw endpoint' do
+RSpec.describe 'Projects > Raw > User interacts with raw endpoint' do
include RepoHelpers
let(:user) { create(:user) }
diff --git a/spec/features/projects/releases/user_views_edit_release_spec.rb b/spec/features/projects/releases/user_views_edit_release_spec.rb
index 217d6a25a23..4ed1be6db6b 100644
--- a/spec/features/projects/releases/user_views_edit_release_spec.rb
+++ b/spec/features/projects/releases/user_views_edit_release_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User edits Release', :js do
+RSpec.describe 'User edits Release', :js do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:release) { create(:release, project: project, name: 'The first release' ) }
let_it_be(:user) { create(:user) }
diff --git a/spec/features/projects/releases/user_views_release_spec.rb b/spec/features/projects/releases/user_views_release_spec.rb
index 6120acb4f1f..c82588746a8 100644
--- a/spec/features/projects/releases/user_views_release_spec.rb
+++ b/spec/features/projects/releases/user_views_release_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views Release', :js do
+RSpec.describe 'User views Release', :js do
let(:project) { create(:project, :repository) }
let(:release) { create(:release, project: project, name: 'The first release' ) }
let(:user) { create(:user) }
diff --git a/spec/features/projects/releases/user_views_releases_spec.rb b/spec/features/projects/releases/user_views_releases_spec.rb
index e21d8ec16e1..962d5551631 100644
--- a/spec/features/projects/releases/user_views_releases_spec.rb
+++ b/spec/features/projects/releases/user_views_releases_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views releases', :js do
+RSpec.describe 'User views releases', :js do
let_it_be(:project) { create(:project, :repository, :private) }
let_it_be(:release) { create(:release, project: project, name: 'The first release' ) }
let_it_be(:maintainer) { create(:user) }
@@ -26,47 +26,65 @@ describe 'User views releases', :js do
expect(page).not_to have_content('Upcoming Release')
end
- context 'when there is a link as an asset' do
- let!(:release_link) { create(:release_link, release: release, url: url ) }
- let(:url) { "#{project.web_url}/-/jobs/1/artifacts/download" }
- let(:direct_asset_link) { Gitlab::Routing.url_helpers.project_release_url(project, release) << release_link.filepath }
-
- it 'sees the link' do
- visit project_releases_path(project)
-
- page.within('.js-assets-list') do
- expect(page).to have_link release_link.name, href: direct_asset_link
- expect(page).not_to have_content('(external source)')
- end
- end
-
- context 'when there is a link redirect' do
- let!(:release_link) { create(:release_link, release: release, name: 'linux-amd64 binaries', filepath: '/binaries/linux-amd64', url: url) }
+ shared_examples 'asset link tests' do
+ context 'when there is a link as an asset' do
+ let!(:release_link) { create(:release_link, release: release, url: url ) }
let(:url) { "#{project.web_url}/-/jobs/1/artifacts/download" }
+ let(:direct_asset_link) { Gitlab::Routing.url_helpers.project_release_url(project, release) << release_link.filepath }
it 'sees the link' do
visit project_releases_path(project)
page.within('.js-assets-list') do
expect(page).to have_link release_link.name, href: direct_asset_link
- expect(page).not_to have_content('(external source)')
+ expect(page).not_to have_css('[data-testid="external-link-indicator"]')
end
end
- end
- context 'when url points to external resource' do
- let(:url) { 'http://google.com/download' }
+ context 'when there is a link redirect' do
+ let!(:release_link) { create(:release_link, release: release, name: 'linux-amd64 binaries', filepath: '/binaries/linux-amd64', url: url) }
+ let(:url) { "#{project.web_url}/-/jobs/1/artifacts/download" }
- it 'sees that the link is external resource' do
- visit project_releases_path(project)
+ it 'sees the link' do
+ visit project_releases_path(project)
- page.within('.js-assets-list') do
- expect(page).to have_content('(external source)')
+ page.within('.js-assets-list') do
+ expect(page).to have_link release_link.name, href: direct_asset_link
+ expect(page).not_to have_css('[data-testid="external-link-indicator"]')
+ end
+ end
+ end
+
+ context 'when url points to external resource' do
+ let(:url) { 'http://google.com/download' }
+
+ it 'sees that the link is external resource' do
+ visit project_releases_path(project)
+
+ page.within('.js-assets-list') do
+ expect(page).to have_css('[data-testid="external-link-indicator"]')
+ end
end
end
end
end
+ context 'when the release_asset_link_type feature flag is enabled' do
+ before do
+ stub_feature_flags(release_asset_link_type: true)
+ end
+
+ it_behaves_like 'asset link tests'
+ end
+
+ context 'when the release_asset_link_type feature flag is disabled' do
+ before do
+ stub_feature_flags(release_asset_link_type: false)
+ end
+
+ it_behaves_like 'asset link tests'
+ end
+
context 'with an upcoming release' do
let(:tomorrow) { Time.zone.now + 1.day }
let!(:release) { create(:release, project: project, released_at: tomorrow ) }
@@ -80,7 +98,7 @@ describe 'User views releases', :js do
context 'with a tag containing a slash' do
it 'sees the release' do
- release = create :release, :with_evidence, project: project, tag: 'debian/2.4.0-1'
+ release = create :release, project: project, tag: 'debian/2.4.0-1'
visit project_releases_path(project)
expect(page).to have_content(release.name)
diff --git a/spec/features/projects/remote_mirror_spec.rb b/spec/features/projects/remote_mirror_spec.rb
index d357aabead7..26d27c914cc 100644
--- a/spec/features/projects/remote_mirror_spec.rb
+++ b/spec/features/projects/remote_mirror_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project remote mirror', :feature do
+RSpec.describe 'Project remote mirror', :feature do
let(:project) { create(:project, :repository, :remote_mirror) }
let(:remote_mirror) { project.remote_mirrors.first }
let(:user) { create(:user) }
diff --git a/spec/features/projects/serverless/functions_spec.rb b/spec/features/projects/serverless/functions_spec.rb
index 4c89af29339..a0b06d7e2a1 100644
--- a/spec/features/projects/serverless/functions_spec.rb
+++ b/spec/features/projects/serverless/functions_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Functions', :js do
+RSpec.describe 'Functions', :js do
include KubernetesHelpers
include ReactiveCachingHelpers
diff --git a/spec/features/projects/services/disable_triggers_spec.rb b/spec/features/projects/services/disable_triggers_spec.rb
index d07abb94208..8f87d0e7ff1 100644
--- a/spec/features/projects/services/disable_triggers_spec.rb
+++ b/spec/features/projects/services/disable_triggers_spec.rb
@@ -2,10 +2,10 @@
require 'spec_helper'
-describe 'Disable individual triggers' do
+RSpec.describe 'Disable individual triggers', :js do
include_context 'project service activation'
- let(:checkbox_selector) { 'input[type=checkbox][id$=_events]' }
+ let(:checkbox_selector) { 'input[type=checkbox][name$="_events]"]' }
before do
visit_project_integration(service_name)
diff --git a/spec/features/projects/services/prometheus_external_alerts_spec.rb b/spec/features/projects/services/prometheus_external_alerts_spec.rb
index 1a706f20352..4c32905a8c5 100644
--- a/spec/features/projects/services/prometheus_external_alerts_spec.rb
+++ b/spec/features/projects/services/prometheus_external_alerts_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Prometheus external alerts', :js do
+RSpec.describe 'Prometheus external alerts', :js do
include_context 'project service activation'
let(:alerts_section_selector) { '.js-prometheus-alerts' }
diff --git a/spec/features/projects/services/user_activates_alerts_spec.rb b/spec/features/projects/services/user_activates_alerts_spec.rb
index 47de7fab859..95642f49d61 100644
--- a/spec/features/projects/services/user_activates_alerts_spec.rb
+++ b/spec/features/projects/services/user_activates_alerts_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates Alerts', :js do
+RSpec.describe 'User activates Alerts', :js do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/features/projects/services/user_activates_asana_spec.rb b/spec/features/projects/services/user_activates_asana_spec.rb
index dac60fce6e9..3e24d106be0 100644
--- a/spec/features/projects/services/user_activates_asana_spec.rb
+++ b/spec/features/projects/services/user_activates_asana_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates Asana' do
+RSpec.describe 'User activates Asana' do
include_context 'project service activation'
it 'activates service', :js do
diff --git a/spec/features/projects/services/user_activates_assembla_spec.rb b/spec/features/projects/services/user_activates_assembla_spec.rb
index 999a95e3e23..2e49f4caa82 100644
--- a/spec/features/projects/services/user_activates_assembla_spec.rb
+++ b/spec/features/projects/services/user_activates_assembla_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates Assembla' do
+RSpec.describe 'User activates Assembla' do
include_context 'project service activation'
before do
diff --git a/spec/features/projects/services/user_activates_atlassian_bamboo_ci_spec.rb b/spec/features/projects/services/user_activates_atlassian_bamboo_ci_spec.rb
index 28ed08f71b6..7b89b9ac4a7 100644
--- a/spec/features/projects/services/user_activates_atlassian_bamboo_ci_spec.rb
+++ b/spec/features/projects/services/user_activates_atlassian_bamboo_ci_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates Atlassian Bamboo CI' do
+RSpec.describe 'User activates Atlassian Bamboo CI' do
include_context 'project service activation'
before do
@@ -23,6 +23,6 @@ describe 'User activates Atlassian Bamboo CI' do
# Password field should not be filled in.
click_link('Atlassian Bamboo CI')
- expect(find_field('Enter new password').value).to be_blank
+ expect(find_field('Enter new Password').value).to be_blank
end
end
diff --git a/spec/features/projects/services/user_activates_emails_on_push_spec.rb b/spec/features/projects/services/user_activates_emails_on_push_spec.rb
index 42c069eb29e..40947027146 100644
--- a/spec/features/projects/services/user_activates_emails_on_push_spec.rb
+++ b/spec/features/projects/services/user_activates_emails_on_push_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates Emails on push' do
+RSpec.describe 'User activates Emails on push' do
include_context 'project service activation'
it 'activates service', :js do
diff --git a/spec/features/projects/services/user_activates_flowdock_spec.rb b/spec/features/projects/services/user_activates_flowdock_spec.rb
index 4762363b3fe..9581d718400 100644
--- a/spec/features/projects/services/user_activates_flowdock_spec.rb
+++ b/spec/features/projects/services/user_activates_flowdock_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates Flowdock' do
+RSpec.describe 'User activates Flowdock' do
include_context 'project service activation' do
let(:project) { create(:project, :repository) }
end
diff --git a/spec/features/projects/services/user_activates_hipchat_spec.rb b/spec/features/projects/services/user_activates_hipchat_spec.rb
index 2fb056f3533..a2820c4bb0f 100644
--- a/spec/features/projects/services/user_activates_hipchat_spec.rb
+++ b/spec/features/projects/services/user_activates_hipchat_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates HipChat', :js do
+RSpec.describe 'User activates HipChat', :js do
include_context 'project service activation'
context 'with standart settings' do
diff --git a/spec/features/projects/services/user_activates_irker_spec.rb b/spec/features/projects/services/user_activates_irker_spec.rb
index 56df403499c..fad40fa6085 100644
--- a/spec/features/projects/services/user_activates_irker_spec.rb
+++ b/spec/features/projects/services/user_activates_irker_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates Irker (IRC gateway)' do
+RSpec.describe 'User activates Irker (IRC gateway)' do
include_context 'project service activation'
it 'activates service', :js do
diff --git a/spec/features/projects/services/user_activates_issue_tracker_spec.rb b/spec/features/projects/services/user_activates_issue_tracker_spec.rb
index 3c5005d0c0c..a2a2604c610 100644
--- a/spec/features/projects/services/user_activates_issue_tracker_spec.rb
+++ b/spec/features/projects/services/user_activates_issue_tracker_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates issue tracker', :js do
+RSpec.describe 'User activates issue tracker', :js do
include_context 'project service activation'
let(:url) { 'http://tracker.example.com' }
diff --git a/spec/features/projects/services/user_activates_jetbrains_teamcity_ci_spec.rb b/spec/features/projects/services/user_activates_jetbrains_teamcity_ci_spec.rb
index 8c84a81ac89..8ee369eb6ec 100644
--- a/spec/features/projects/services/user_activates_jetbrains_teamcity_ci_spec.rb
+++ b/spec/features/projects/services/user_activates_jetbrains_teamcity_ci_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates JetBrains TeamCity CI' do
+RSpec.describe 'User activates JetBrains TeamCity CI' do
include_context 'project service activation'
before do
@@ -12,7 +12,7 @@ describe 'User activates JetBrains TeamCity CI' do
it 'activates service', :js do
visit_project_integration('JetBrains TeamCity CI')
check('Push')
- check('Merge request')
+ check('Merge Request')
fill_in('Teamcity url', with: 'http://teamcity.example.com')
fill_in('Build type', with: 'GitlabTest_Build')
fill_in('Username', with: 'user')
diff --git a/spec/features/projects/services/user_activates_jira_spec.rb b/spec/features/projects/services/user_activates_jira_spec.rb
index a14dbf9c14d..1da8a49699b 100644
--- a/spec/features/projects/services/user_activates_jira_spec.rb
+++ b/spec/features/projects/services/user_activates_jira_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates Jira', :js do
+RSpec.describe 'User activates Jira', :js do
include_context 'project service activation'
let(:url) { 'http://jira.example.com' }
diff --git a/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb b/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb
index c6825ee663a..a6b4aaccfb5 100644
--- a/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb
+++ b/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Set up Mattermost slash commands', :js do
+RSpec.describe 'Set up Mattermost slash commands', :js do
describe 'user visits the mattermost slash command config page' do
include_context 'project service activation'
diff --git a/spec/features/projects/services/user_activates_packagist_spec.rb b/spec/features/projects/services/user_activates_packagist_spec.rb
index 274f293ebf3..70cf612bb2a 100644
--- a/spec/features/projects/services/user_activates_packagist_spec.rb
+++ b/spec/features/projects/services/user_activates_packagist_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates Packagist' do
+RSpec.describe 'User activates Packagist' do
include_context 'project service activation'
before do
diff --git a/spec/features/projects/services/user_activates_pivotaltracker_spec.rb b/spec/features/projects/services/user_activates_pivotaltracker_spec.rb
index c81c5081867..8e99c6e303b 100644
--- a/spec/features/projects/services/user_activates_pivotaltracker_spec.rb
+++ b/spec/features/projects/services/user_activates_pivotaltracker_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates PivotalTracker' do
+RSpec.describe 'User activates PivotalTracker' do
include_context 'project service activation'
before do
diff --git a/spec/features/projects/services/user_activates_prometheus_spec.rb b/spec/features/projects/services/user_activates_prometheus_spec.rb
index 76dc7d1bbc8..89b1f447c32 100644
--- a/spec/features/projects/services/user_activates_prometheus_spec.rb
+++ b/spec/features/projects/services/user_activates_prometheus_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates Prometheus' do
+RSpec.describe 'User activates Prometheus' do
include_context 'project service activation'
before do
diff --git a/spec/features/projects/services/user_activates_pushover_spec.rb b/spec/features/projects/services/user_activates_pushover_spec.rb
index 62e03e68aee..789cc30a42e 100644
--- a/spec/features/projects/services/user_activates_pushover_spec.rb
+++ b/spec/features/projects/services/user_activates_pushover_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates Pushover' do
+RSpec.describe 'User activates Pushover' do
include_context 'project service activation'
before do
diff --git a/spec/features/projects/services/user_activates_slack_notifications_spec.rb b/spec/features/projects/services/user_activates_slack_notifications_spec.rb
index 12f15699e26..20e2bd3f085 100644
--- a/spec/features/projects/services/user_activates_slack_notifications_spec.rb
+++ b/spec/features/projects/services/user_activates_slack_notifications_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates Slack notifications' do
+RSpec.describe 'User activates Slack notifications', :js do
include_context 'project service activation'
context 'when service is not configured yet' do
@@ -10,7 +10,7 @@ describe 'User activates Slack notifications' do
visit_project_integration('Slack notifications')
end
- it 'activates service', :js do
+ it 'activates service' do
fill_in('Webhook', with: 'https://hooks.slack.com/services/SVRWFV0VVAR97N/B02R25XN3/ZBqu7xMupaEEICInN685')
click_test_then_save_integration
@@ -38,13 +38,13 @@ describe 'User activates Slack notifications' do
end
it 'filters events by channel' do
- expect(page.find_field('service_push_channel').value).to have_content('1')
- expect(page.find_field('service_issue_channel').value).to have_content('2')
- expect(page.find_field('service_merge_request_channel').value).to have_content('3')
- expect(page.find_field('service_note_channel').value).to have_content('4')
- expect(page.find_field('service_tag_push_channel').value).to have_content('5')
- expect(page.find_field('service_pipeline_channel').value).to have_content('6')
- expect(page.find_field('service_wiki_page_channel').value).to have_content('7')
+ expect(page.find_field(name: 'service[push_channel]').value).to have_content('1')
+ expect(page.find_field(name: 'service[issue_channel]').value).to have_content('2')
+ expect(page.find_field(name: 'service[merge_request_channel]').value).to have_content('3')
+ expect(page.find_field(name: 'service[note_channel]').value).to have_content('4')
+ expect(page.find_field(name: 'service[tag_push_channel]').value).to have_content('5')
+ expect(page.find_field(name: 'service[pipeline_channel]').value).to have_content('6')
+ expect(page.find_field(name: 'service[wiki_page_channel]').value).to have_content('7')
end
end
end
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 05f1a0c6b17..360e462b935 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
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Slack slash commands' do
+RSpec.describe 'Slack slash commands', :js do
include_context 'project service activation'
before do
@@ -10,7 +10,7 @@ describe 'Slack slash commands' do
end
it 'shows a token placeholder' do
- token_placeholder = find_field('service_token')['placeholder']
+ token_placeholder = find_field('Token')['placeholder']
expect(token_placeholder).to eq('XXxxXXxxXXxxXXxxXXxxXXxx')
end
@@ -19,8 +19,8 @@ describe 'Slack slash commands' do
expect(page).to have_content('This service allows users to perform common')
end
- it 'redirects to the integrations page after saving but not activating', :js do
- fill_in 'service_token', with: 'token'
+ it 'redirects to the integrations page after saving but not activating' do
+ fill_in 'Token', with: 'token'
click_active_toggle
click_on 'Save'
@@ -28,8 +28,8 @@ describe 'Slack slash commands' do
expect(page).to have_content('Slack slash commands settings saved, but not activated.')
end
- it 'redirects to the integrations page after activating', :js do
- fill_in 'service_token', with: 'token'
+ it 'redirects to the integrations page after activating' do
+ fill_in 'Token', with: 'token'
click_on 'Save'
expect(current_path).to eq(project_settings_integrations_path(project))
diff --git a/spec/features/projects/services/user_views_services_spec.rb b/spec/features/projects/services/user_views_services_spec.rb
index 6df0123c30a..fef6b7bd991 100644
--- a/spec/features/projects/services/user_views_services_spec.rb
+++ b/spec/features/projects/services/user_views_services_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views services' do
+RSpec.describe 'User views services' do
include_context 'project service activation'
it 'shows the list of available services' do
diff --git a/spec/features/projects/settings/access_tokens_spec.rb b/spec/features/projects/settings/access_tokens_spec.rb
index 9a8a8e38164..45fe19deb8e 100644
--- a/spec/features/projects/settings/access_tokens_spec.rb
+++ b/spec/features/projects/settings/access_tokens_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project > Settings > Access Tokens', :js do
+RSpec.describe 'Project > Settings > Access Tokens', :js do
let_it_be(:user) { create(:user) }
let_it_be(:bot_user) { create(:user, :project_bot) }
let_it_be(:project) { create(:project) }
diff --git a/spec/features/projects/settings/external_authorization_service_settings_spec.rb b/spec/features/projects/settings/external_authorization_service_settings_spec.rb
index 31b2892cf6f..c236c85b773 100644
--- a/spec/features/projects/settings/external_authorization_service_settings_spec.rb
+++ b/spec/features/projects/settings/external_authorization_service_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > External Authorization Classification Label setting' do
+RSpec.describe 'Projects > Settings > External Authorization Classification Label setting' do
let(:user) { create(:user) }
let(:project) { create(:project_empty_repo) }
diff --git a/spec/features/projects/settings/forked_project_settings_spec.rb b/spec/features/projects/settings/forked_project_settings_spec.rb
index a2c6dd8e288..f6c25d483ad 100644
--- a/spec/features/projects/settings/forked_project_settings_spec.rb
+++ b/spec/features/projects/settings/forked_project_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > For a forked project', :js do
+RSpec.describe 'Projects > Settings > For a forked project', :js do
include ProjectForksHelper
let(:user) { create(:user) }
let(:original_project) { create(:project) }
diff --git a/spec/features/projects/settings/lfs_settings_spec.rb b/spec/features/projects/settings/lfs_settings_spec.rb
index 5fa3b9bba55..6e1be3c7e51 100644
--- a/spec/features/projects/settings/lfs_settings_spec.rb
+++ b/spec/features/projects/settings/lfs_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > LFS settings' do
+RSpec.describe 'Projects > Settings > LFS settings' do
let(:project) { create(:project) }
let(:user) { create(:user) }
let(:role) { :maintainer }
diff --git a/spec/features/projects/settings/operations_settings_spec.rb b/spec/features/projects/settings/operations_settings_spec.rb
index 752353cf2f5..dfbb6342173 100644
--- a/spec/features/projects/settings/operations_settings_spec.rb
+++ b/spec/features/projects/settings/operations_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > For a forked project', :js do
+RSpec.describe 'Projects > Settings > For a forked project', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :repository, create_templates: :issue) }
let(:role) { :maintainer }
diff --git a/spec/features/projects/settings/pipelines_settings_spec.rb b/spec/features/projects/settings/pipelines_settings_spec.rb
index 87e467571e6..0358acc8dcc 100644
--- a/spec/features/projects/settings/pipelines_settings_spec.rb
+++ b/spec/features/projects/settings/pipelines_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Projects > Settings > Pipelines settings" do
+RSpec.describe "Projects > Settings > Pipelines settings" do
let(:project) { create(:project) }
let(:user) { create(:user) }
let(:role) { :developer }
diff --git a/spec/features/projects/settings/project_badges_spec.rb b/spec/features/projects/settings/project_badges_spec.rb
index c419bb1868c..2c26168e3c0 100644
--- a/spec/features/projects/settings/project_badges_spec.rb
+++ b/spec/features/projects/settings/project_badges_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project Badges' do
+RSpec.describe 'Project Badges' do
include WaitForRequests
let(:user) { create(:user) }
diff --git a/spec/features/projects/settings/project_settings_spec.rb b/spec/features/projects/settings/project_settings_spec.rb
index 171c7920878..7b2b5594c22 100644
--- a/spec/features/projects/settings/project_settings_spec.rb
+++ b/spec/features/projects/settings/project_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects settings' do
+RSpec.describe 'Projects settings' do
let_it_be(:project) { create(:project) }
let(:user) { project.owner }
let(:panel) { find('.general-settings', match: :first) }
diff --git a/spec/features/projects/settings/registry_settings_spec.rb b/spec/features/projects/settings/registry_settings_spec.rb
index ba92e8bc516..3dcb7ca54a1 100644
--- a/spec/features/projects/settings/registry_settings_spec.rb
+++ b/spec/features/projects/settings/registry_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project > Settings > CI/CD > Container registry tag expiration policy', :js do
+RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration policy', :js do
let(:user) { create(:user) }
let(:project) { create(:project, namespace: user.namespace, container_registry_enabled: container_registry_enabled) }
let(:container_registry_enabled) { true }
@@ -29,7 +29,7 @@ describe 'Project > Settings > CI/CD > Container registry tag expiration policy'
select('7 days until tags are automatically removed', from: 'Expiration interval:')
select('Every day', from: 'Expiration schedule:')
select('50 tags per image name', from: 'Number of tags to retain:')
- fill_in('Tags with names matching this regex pattern will expire:', with: '*-production')
+ fill_in('Tags with names matching this regex pattern will expire:', with: '.*-production')
end
submit_button = find('.card-footer .btn.btn-success')
expect(submit_button).not_to be_disabled
@@ -38,6 +38,19 @@ describe 'Project > Settings > CI/CD > Container registry tag expiration policy'
toast = find('.gl-toast')
expect(toast).to have_content('Expiration policy successfully saved.')
end
+
+ it 'does not save expiration policy submit form with invalid regex' do
+ within '#js-registry-policies' do
+ within '.card-body' do
+ fill_in('Tags with names matching this regex pattern will expire:', with: '*-production')
+ end
+ submit_button = find('.card-footer .btn.btn-success')
+ expect(submit_button).not_to be_disabled
+ submit_button.click
+ end
+ toast = find('.gl-toast')
+ expect(toast).to have_content('Something went wrong while updating the expiration policy.')
+ end
end
context 'when registry is disabled' do
diff --git a/spec/features/projects/settings/repository_settings_spec.rb b/spec/features/projects/settings/repository_settings_spec.rb
index b8baaa3e963..8beecedf85f 100644
--- a/spec/features/projects/settings/repository_settings_spec.rb
+++ b/spec/features/projects/settings/repository_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > Repository settings' do
+RSpec.describe 'Projects > Settings > Repository settings' do
let(:project) { create(:project_empty_repo) }
let(:user) { create(:user) }
let(:role) { :developer }
diff --git a/spec/features/projects/settings/user_archives_project_spec.rb b/spec/features/projects/settings/user_archives_project_spec.rb
index 7667fad7b03..03ea9e7c580 100644
--- a/spec/features/projects/settings/user_archives_project_spec.rb
+++ b/spec/features/projects/settings/user_archives_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > User archives a project' do
+RSpec.describe 'Projects > Settings > User archives a project' do
let(:user) { create(:user) }
before do
diff --git a/spec/features/projects/settings/user_changes_avatar_spec.rb b/spec/features/projects/settings/user_changes_avatar_spec.rb
index 67789b869da..92d5b4c1fcd 100644
--- a/spec/features/projects/settings/user_changes_avatar_spec.rb
+++ b/spec/features/projects/settings/user_changes_avatar_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > User changes avatar' do
+RSpec.describe 'Projects > Settings > User changes avatar' do
let(:project) { create(:project, :repository) }
let(:user) { project.creator }
diff --git a/spec/features/projects/settings/user_changes_default_branch_spec.rb b/spec/features/projects/settings/user_changes_default_branch_spec.rb
index 411fc0c7e07..84e6c50cf61 100644
--- a/spec/features/projects/settings/user_changes_default_branch_spec.rb
+++ b/spec/features/projects/settings/user_changes_default_branch_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > User changes default branch' do
+RSpec.describe 'Projects > Settings > User changes default branch' do
include Select2Helper
let(:user) { create(:user) }
diff --git a/spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb b/spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb
index 45a16fda2cb..ba504624823 100644
--- a/spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb
+++ b/spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User interacts with deploy keys", :js do
+RSpec.describe "User interacts with deploy keys", :js do
let(:project) { create(:project, :repository) }
let(:user) { project.owner }
diff --git a/spec/features/projects/settings/user_manages_group_links_spec.rb b/spec/features/projects/settings/user_manages_group_links_spec.rb
deleted file mode 100644
index 7df0bbb9d02..00000000000
--- a/spec/features/projects/settings/user_manages_group_links_spec.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe 'Projects > Settings > User manages group links' do
- include Select2Helper
-
- let(:user) { create(:user) }
- let(:project) { create(:project, namespace: user.namespace) }
- let(:group_ops) { create(:group, name: 'Ops') }
- let(:group_market) { create(:group, name: 'Market', path: 'market') }
-
- before do
- project.add_maintainer(user)
- group_market.add_guest(user)
- sign_in(user)
-
- share_link = project.project_group_links.new(group_access: Gitlab::Access::MAINTAINER)
- share_link.group_id = group_ops.id
- share_link.save!
-
- visit(project_group_links_path(project))
- end
-
- it 'shows a list of groups' do
- page.within('.project-members-groups') do
- expect(page).to have_content('Ops')
- expect(page).not_to have_content('Market')
- end
- end
-
- it 'invites a group to a project', :js do
- click_link('Invite group')
-
- select2(group_market.id, from: '#link_group_id')
- select('Maintainer', from: 'link_group_access')
-
- click_button('Invite')
-
- page.within('.project-members-groups') do
- expect(page).to have_content('Market')
- end
- end
-end
diff --git a/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb b/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb
index c0089e3c28c..3fc1f47d98a 100644
--- a/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb
+++ b/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe 'Projects > Settings > User manages merge request settings' do
+RSpec.describe 'Projects > Settings > User manages merge request settings' do
let(:user) { create(:user) }
let(:project) { create(:project, :public, namespace: user.namespace, path: 'gitlab', name: 'sample') }
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 705c60f15ee..d32f4cb8ec7 100644
--- a/spec/features/projects/settings/user_manages_project_members_spec.rb
+++ b/spec/features/projects/settings/user_manages_project_members_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > User manages project members' do
+RSpec.describe 'Projects > Settings > User manages project members' do
let(:group) { create(:group, name: 'OpenSource') }
let(:project) { create(:project) }
let(:project2) { create(:project) }
diff --git a/spec/features/projects/settings/user_renames_a_project_spec.rb b/spec/features/projects/settings/user_renames_a_project_spec.rb
index 789c5e31748..6088ea31661 100644
--- a/spec/features/projects/settings/user_renames_a_project_spec.rb
+++ b/spec/features/projects/settings/user_renames_a_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > User renames a project' do
+RSpec.describe 'Projects > Settings > User renames a project' do
let(:user) { create(:user) }
let(:project) { create(:project, namespace: user.namespace, path: 'gitlab', name: 'sample') }
diff --git a/spec/features/projects/settings/user_sees_revoke_deploy_token_modal_spec.rb b/spec/features/projects/settings/user_sees_revoke_deploy_token_modal_spec.rb
index 0abc4b41a2b..d0f297d2067 100644
--- a/spec/features/projects/settings/user_sees_revoke_deploy_token_modal_spec.rb
+++ b/spec/features/projects/settings/user_sees_revoke_deploy_token_modal_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Repository Settings > User sees revoke deploy token modal', :js do
+RSpec.describe 'Repository Settings > User sees revoke deploy token modal', :js do
let(:project) { create(:project, :public, :repository) }
let(:user) { project.creator }
let(:role) { :developer }
diff --git a/spec/features/projects/settings/user_tags_project_spec.rb b/spec/features/projects/settings/user_tags_project_spec.rb
index a919dd0e4af..ff19ed22744 100644
--- a/spec/features/projects/settings/user_tags_project_spec.rb
+++ b/spec/features/projects/settings/user_tags_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > User tags a project' do
+RSpec.describe 'Projects > Settings > User tags a project' do
let(:user) { create(:user) }
let(:project) { create(:project, namespace: user.namespace) }
diff --git a/spec/features/projects/settings/user_transfers_a_project_spec.rb b/spec/features/projects/settings/user_transfers_a_project_spec.rb
index 8989eac77b5..ba4c379ef0a 100644
--- a/spec/features/projects/settings/user_transfers_a_project_spec.rb
+++ b/spec/features/projects/settings/user_transfers_a_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > User transfers a project', :js do
+RSpec.describe 'Projects > Settings > User transfers a project', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :repository, namespace: user.namespace) }
let(:group) { create(:group) }
diff --git a/spec/features/projects/settings/visibility_settings_spec.rb b/spec/features/projects/settings/visibility_settings_spec.rb
index a2b36874aea..6cecbbdb3d0 100644
--- a/spec/features/projects/settings/visibility_settings_spec.rb
+++ b/spec/features/projects/settings/visibility_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > Visibility settings', :js do
+RSpec.describe 'Projects > Settings > Visibility settings', :js do
let(:user) { create(:user) }
let(:project) { create(:project, namespace: user.namespace, visibility_level: 20) }
diff --git a/spec/features/projects/settings/webhooks_settings_spec.rb b/spec/features/projects/settings/webhooks_settings_spec.rb
index 7e22117c63c..d184f08bd89 100644
--- a/spec/features/projects/settings/webhooks_settings_spec.rb
+++ b/spec/features/projects/settings/webhooks_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > Webhook Settings' do
+RSpec.describe 'Projects > Settings > Webhook Settings' do
let(:project) { create(:project) }
let(:user) { create(:user) }
let(:webhooks_path) { project_hooks_path(project) }
diff --git a/spec/features/projects/show/developer_views_empty_project_instructions_spec.rb b/spec/features/projects/show/developer_views_empty_project_instructions_spec.rb
index 70dc6c966ba..8d239cb2cbf 100644
--- a/spec/features/projects/show/developer_views_empty_project_instructions_spec.rb
+++ b/spec/features/projects/show/developer_views_empty_project_instructions_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > Developer views empty project instructions' do
+RSpec.describe 'Projects > Show > Developer views empty project instructions' do
let(:project) { create(:project, :empty_repo) }
let(:developer) { create(:user) }
diff --git a/spec/features/projects/show/download_buttons_spec.rb b/spec/features/projects/show/download_buttons_spec.rb
index 0d609069426..e73bb3198e6 100644
--- a/spec/features/projects/show/download_buttons_spec.rb
+++ b/spec/features/projects/show/download_buttons_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > Download buttons' do
+RSpec.describe 'Projects > Show > Download buttons' do
let(:user) { create(:user) }
let(:role) { :developer }
let(:status) { 'success' }
diff --git a/spec/features/projects/show/no_password_spec.rb b/spec/features/projects/show/no_password_spec.rb
index 0048b1bf017..79cd65e5406 100644
--- a/spec/features/projects/show/no_password_spec.rb
+++ b/spec/features/projects/show/no_password_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'No Password Alert' do
+RSpec.describe 'No Password Alert' do
let(:project) { create(:project, :repository, namespace: user.namespace) }
context 'with internal auth enabled' do
diff --git a/spec/features/projects/show/redirects_spec.rb b/spec/features/projects/show/redirects_spec.rb
index 1b579ab0121..659edda5672 100644
--- a/spec/features/projects/show/redirects_spec.rb
+++ b/spec/features/projects/show/redirects_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > Redirects' do
+RSpec.describe 'Projects > Show > Redirects' do
let(:user) { create :user }
let(:public_project) { create :project, :public }
let(:private_project) { create :project, :private }
diff --git a/spec/features/projects/show/rss_spec.rb b/spec/features/projects/show/rss_spec.rb
index 4fe1fde5bdd..0bd6e9cbe3b 100644
--- a/spec/features/projects/show/rss_spec.rb
+++ b/spec/features/projects/show/rss_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > RSS' do
+RSpec.describe 'Projects > Show > RSS' do
let(:user) { create(:user) }
let(:project) { create(:project, :repository, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
let(:path) { project_path(project) }
diff --git a/spec/features/projects/show/user_interacts_with_auto_devops_banner_spec.rb b/spec/features/projects/show/user_interacts_with_auto_devops_banner_spec.rb
index df63856492e..59f1bc94226 100644
--- a/spec/features/projects/show/user_interacts_with_auto_devops_banner_spec.rb
+++ b/spec/features/projects/show/user_interacts_with_auto_devops_banner_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project > Show > User interacts with auto devops implicitly enabled banner' do
+RSpec.describe 'Project > Show > User interacts with auto devops implicitly enabled banner' do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/features/projects/show/user_interacts_with_stars_spec.rb b/spec/features/projects/show/user_interacts_with_stars_spec.rb
index e4cd8294f7a..99f84c19bf3 100644
--- a/spec/features/projects/show/user_interacts_with_stars_spec.rb
+++ b/spec/features/projects/show/user_interacts_with_stars_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > User interacts with project stars' do
+RSpec.describe 'Projects > Show > User interacts with project stars' do
let(:project) { create(:project, :public, :repository) }
context 'when user is signed in', :js do
diff --git a/spec/features/projects/show/user_manages_notifications_spec.rb b/spec/features/projects/show/user_manages_notifications_spec.rb
index 0cd6743304e..58a2c793b7b 100644
--- a/spec/features/projects/show/user_manages_notifications_spec.rb
+++ b/spec/features/projects/show/user_manages_notifications_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > User manages notifications', :js do
+RSpec.describe 'Projects > Show > User manages notifications', :js do
let(:project) { create(:project, :public, :repository) }
before do
diff --git a/spec/features/projects/show/user_sees_collaboration_links_spec.rb b/spec/features/projects/show/user_sees_collaboration_links_spec.rb
index 63fcec4f9b3..ffdfbb9fe81 100644
--- a/spec/features/projects/show/user_sees_collaboration_links_spec.rb
+++ b/spec/features/projects/show/user_sees_collaboration_links_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > Collaboration links', :js do
+RSpec.describe 'Projects > Show > Collaboration links', :js do
using RSpec::Parameterized::TableSyntax
let(:project) { create(:project, :repository, :public) }
diff --git a/spec/features/projects/show/user_sees_deletion_failure_message_spec.rb b/spec/features/projects/show/user_sees_deletion_failure_message_spec.rb
index bdd0ab688f0..5e878411f6a 100644
--- a/spec/features/projects/show/user_sees_deletion_failure_message_spec.rb
+++ b/spec/features/projects/show/user_sees_deletion_failure_message_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > User sees a deletion failure message' do
+RSpec.describe 'Projects > Show > User sees a deletion failure message' do
let(:project) { create(:project, :empty_repo, pending_delete: true) }
before do
diff --git a/spec/features/projects/show/user_sees_git_instructions_spec.rb b/spec/features/projects/show/user_sees_git_instructions_spec.rb
index 0c486056329..a35f6420bdc 100644
--- a/spec/features/projects/show/user_sees_git_instructions_spec.rb
+++ b/spec/features/projects/show/user_sees_git_instructions_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > User sees Git instructions' do
+RSpec.describe 'Projects > Show > User sees Git instructions' do
let_it_be(:user) { create(:user) }
shared_examples_for 'redirects to the sign in page' do
diff --git a/spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb b/spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb
index c0fcd10f394..0aa0f7754c6 100644
--- a/spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb
+++ b/spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > User sees last commit CI status' do
+RSpec.describe 'Projects > Show > User sees last commit CI status' do
let_it_be(:project) { create(:project, :repository, :public) }
it 'shows the project README', :js do
diff --git a/spec/features/projects/show/user_sees_readme_spec.rb b/spec/features/projects/show/user_sees_readme_spec.rb
index 52745b06cd3..250f707948e 100644
--- a/spec/features/projects/show/user_sees_readme_spec.rb
+++ b/spec/features/projects/show/user_sees_readme_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > User sees README' do
+RSpec.describe 'Projects > Show > User sees README' do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :repository, :public) }
diff --git a/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb b/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb
index 8e20facda15..0f10b0a4010 100644
--- a/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb
+++ b/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > User sees setup shortcut buttons' do
+RSpec.describe 'Projects > Show > User sees setup shortcut buttons' do
# For "New file", "Add license" functionality,
# see spec/features/projects/files/project_owner_creates_license_file_spec.rb
# see spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
diff --git a/spec/features/projects/show/user_uploads_files_spec.rb b/spec/features/projects/show/user_uploads_files_spec.rb
index e279cdf92da..053598a528e 100644
--- a/spec/features/projects/show/user_uploads_files_spec.rb
+++ b/spec/features/projects/show/user_uploads_files_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > User uploads files' do
+RSpec.describe 'Projects > Show > User uploads files' do
include DropzoneHelper
let(:user) { create(:user) }
diff --git a/spec/features/projects/snippets/create_snippet_spec.rb b/spec/features/projects/snippets/create_snippet_spec.rb
index 1e8f9fa0875..73d033cbdb8 100644
--- a/spec/features/projects/snippets/create_snippet_spec.rb
+++ b/spec/features/projects/snippets/create_snippet_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-shared_examples_for 'snippet editor' do
+RSpec.shared_examples_for 'snippet editor' do
before do
stub_feature_flags(snippets_edit_vue: false)
end
@@ -138,7 +138,7 @@ shared_examples_for 'snippet editor' do
end
end
-describe 'Projects > Snippets > Create Snippet', :js do
+RSpec.describe 'Projects > Snippets > Create Snippet', :js do
include DropzoneHelper
let_it_be(:user) { create(:user) }
diff --git a/spec/features/projects/snippets/show_spec.rb b/spec/features/projects/snippets/show_spec.rb
index 9be226c017f..0f6429d49f6 100644
--- a/spec/features/projects/snippets/show_spec.rb
+++ b/spec/features/projects/snippets/show_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Snippets > Project snippet', :js do
+RSpec.describe 'Projects > Snippets > Project snippet', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:snippet) { create(:project_snippet, project: project, file_name: file_name, content: content) }
diff --git a/spec/features/projects/snippets/user_comments_on_snippet_spec.rb b/spec/features/projects/snippets/user_comments_on_snippet_spec.rb
index a7a220b926d..2784fec3dc1 100644
--- a/spec/features/projects/snippets/user_comments_on_snippet_spec.rb
+++ b/spec/features/projects/snippets/user_comments_on_snippet_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Snippets > User comments on a snippet', :js do
+RSpec.describe 'Projects > Snippets > User comments on a snippet', :js do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
let_it_be(:snippet) { create(:project_snippet, :repository, project: project, author: user) }
diff --git a/spec/features/projects/snippets/user_deletes_snippet_spec.rb b/spec/features/projects/snippets/user_deletes_snippet_spec.rb
index 7e337710e19..44fe9834484 100644
--- a/spec/features/projects/snippets/user_deletes_snippet_spec.rb
+++ b/spec/features/projects/snippets/user_deletes_snippet_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Snippets > User deletes a snippet' do
+RSpec.describe 'Projects > Snippets > User deletes a snippet' do
let(:project) { create(:project) }
let!(:snippet) { create(:project_snippet, project: project, author: user) }
let(:user) { create(:user) }
diff --git a/spec/features/projects/snippets/user_updates_snippet_spec.rb b/spec/features/projects/snippets/user_updates_snippet_spec.rb
index d19fe9e8d38..a40113bd93e 100644
--- a/spec/features/projects/snippets/user_updates_snippet_spec.rb
+++ b/spec/features/projects/snippets/user_updates_snippet_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Snippets > User updates a snippet', :js do
+RSpec.describe 'Projects > Snippets > User updates a snippet', :js do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, namespace: user.namespace) }
let_it_be(:snippet, reload: true) { create(:project_snippet, :repository, project: project, author: user) }
diff --git a/spec/features/projects/snippets/user_views_snippets_spec.rb b/spec/features/projects/snippets/user_views_snippets_spec.rb
index 22910029ee5..bc8cba1dc31 100644
--- a/spec/features/projects/snippets/user_views_snippets_spec.rb
+++ b/spec/features/projects/snippets/user_views_snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Snippets > User views snippets' do
+RSpec.describe 'Projects > Snippets > User views snippets' do
let_it_be(:project) { create(:project) }
let(:user) { create(:user) }
diff --git a/spec/features/projects/sourcegraph_csp_spec.rb b/spec/features/projects/sourcegraph_csp_spec.rb
index f252d3cd027..25d27462aa9 100644
--- a/spec/features/projects/sourcegraph_csp_spec.rb
+++ b/spec/features/projects/sourcegraph_csp_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Sourcegraph Content Security Policy' do
+RSpec.describe 'Sourcegraph Content Security Policy' do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :repository, namespace: user.namespace) }
diff --git a/spec/features/projects/sub_group_issuables_spec.rb b/spec/features/projects/sub_group_issuables_spec.rb
index d6faec2078d..8c1d88276df 100644
--- a/spec/features/projects/sub_group_issuables_spec.rb
+++ b/spec/features/projects/sub_group_issuables_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Subgroup Issuables', :js do
+RSpec.describe 'Subgroup Issuables', :js do
let!(:group) { create(:group, name: 'group') }
let!(:subgroup) { create(:group, parent: group, name: 'subgroup') }
let!(:project) { create(:project, namespace: subgroup, name: 'project') }
diff --git a/spec/features/projects/tags/download_buttons_spec.rb b/spec/features/projects/tags/download_buttons_spec.rb
index 64141cf5dc9..0f1f72fd039 100644
--- a/spec/features/projects/tags/download_buttons_spec.rb
+++ b/spec/features/projects/tags/download_buttons_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Download buttons in tags page' do
+RSpec.describe 'Download buttons in tags page' do
let(:user) { create(:user) }
let(:role) { :developer }
let(:status) { 'success' }
diff --git a/spec/features/projects/tags/user_edits_tags_spec.rb b/spec/features/projects/tags/user_edits_tags_spec.rb
index 6388875a619..7a8a685f3d9 100644
--- a/spec/features/projects/tags/user_edits_tags_spec.rb
+++ b/spec/features/projects/tags/user_edits_tags_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project > Tags', :js do
+RSpec.describe 'Project > Tags', :js do
include DropzoneHelper
let(:user) { create(:user) }
diff --git a/spec/features/projects/tags/user_views_tags_spec.rb b/spec/features/projects/tags/user_views_tags_spec.rb
index 7b49b0d0f65..ef363ab6158 100644
--- a/spec/features/projects/tags/user_views_tags_spec.rb
+++ b/spec/features/projects/tags/user_views_tags_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe 'User views tags', :feature do
+RSpec.describe 'User views tags', :feature do
context 'rss' do
shared_examples 'has access to the tags RSS feed' do
it do
diff --git a/spec/features/projects/tree/create_directory_spec.rb b/spec/features/projects/tree/create_directory_spec.rb
index 829b01832df..54b081161e5 100644
--- a/spec/features/projects/tree/create_directory_spec.rb
+++ b/spec/features/projects/tree/create_directory_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Multi-file editor new directory', :js do
+RSpec.describe 'Multi-file editor new directory', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
diff --git a/spec/features/projects/tree/create_file_spec.rb b/spec/features/projects/tree/create_file_spec.rb
index 58ff623c9ae..cefb84e6f5e 100644
--- a/spec/features/projects/tree/create_file_spec.rb
+++ b/spec/features/projects/tree/create_file_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Multi-file editor new file', :js do
+RSpec.describe 'Multi-file editor new file', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
diff --git a/spec/features/projects/tree/rss_spec.rb b/spec/features/projects/tree/rss_spec.rb
index 4300574210f..efbfc329c9f 100644
--- a/spec/features/projects/tree/rss_spec.rb
+++ b/spec/features/projects/tree/rss_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project Tree RSS' do
+RSpec.describe 'Project Tree RSS' do
let(:user) { create(:user) }
let(:project) { create(:project, :repository, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
let(:path) { project_tree_path(project, :master) }
diff --git a/spec/features/projects/tree/tree_show_spec.rb b/spec/features/projects/tree/tree_show_spec.rb
index 2407a9e6ea3..388fa39874d 100644
--- a/spec/features/projects/tree/tree_show_spec.rb
+++ b/spec/features/projects/tree/tree_show_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects tree', :js do
+RSpec.describe 'Projects tree', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:gravatar_enabled) { true }
@@ -24,7 +24,7 @@ describe 'Projects tree', :js do
expect(page).to have_selector('.tree-item')
expect(page).to have_content('add tests for .gitattributes custom highlighting')
expect(page).not_to have_selector('.flash-alert')
- expect(page).not_to have_selector('.label-lfs', text: 'LFS')
+ expect(page).not_to have_selector('[data-qa-selector="label-lfs"]', text: 'LFS')
end
it 'renders tree table for a subtree without errors' do
@@ -33,7 +33,7 @@ describe 'Projects tree', :js do
expect(page).to have_selector('.tree-item')
expect(page).to have_content('add spaces in whitespace file')
- expect(page).not_to have_selector('.label-lfs', text: 'LFS')
+ expect(page).not_to have_selector('[data-qa-selector="label-lfs"]', text: 'LFS')
expect(page).not_to have_selector('.flash-alert')
end
@@ -86,7 +86,7 @@ describe 'Projects tree', :js do
it 'renders LFS badge on blob item' do
visit project_tree_path(project, File.join('master', 'files/lfs'))
- expect(page).to have_selector('.label-lfs', text: 'LFS')
+ expect(page).to have_selector('[data-qa-selector="label-lfs"]', text: 'LFS')
end
end
diff --git a/spec/features/projects/tree/upload_file_spec.rb b/spec/features/projects/tree/upload_file_spec.rb
index 38c29263b1e..ce00483bc91 100644
--- a/spec/features/projects/tree/upload_file_spec.rb
+++ b/spec/features/projects/tree/upload_file_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Multi-file editor upload file', :js do
+RSpec.describe 'Multi-file editor upload file', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:txt_file) { File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt') }
diff --git a/spec/features/projects/user_changes_project_visibility_spec.rb b/spec/features/projects/user_changes_project_visibility_spec.rb
index 31da4140d35..6935ad4be02 100644
--- a/spec/features/projects/user_changes_project_visibility_spec.rb
+++ b/spec/features/projects/user_changes_project_visibility_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User changes public project visibility', :js do
+RSpec.describe 'User changes public project visibility', :js do
include ProjectForksHelper
before do
diff --git a/spec/features/projects/user_creates_project_spec.rb b/spec/features/projects/user_creates_project_spec.rb
index 361367f1a3d..b204ae76e07 100644
--- a/spec/features/projects/user_creates_project_spec.rb
+++ b/spec/features/projects/user_creates_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User creates a project', :js do
+RSpec.describe 'User creates a project', :js do
let(:user) { create(:user) }
before do
diff --git a/spec/features/projects/user_sees_sidebar_spec.rb b/spec/features/projects/user_sees_sidebar_spec.rb
index 4226cdcc759..cc2a9eacbad 100644
--- a/spec/features/projects/user_sees_sidebar_spec.rb
+++ b/spec/features/projects/user_sees_sidebar_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > User sees sidebar' do
+RSpec.describe 'Projects > User sees sidebar' do
let(:user) { create(:user) }
let(:project) { create(:project, :private, public_builds: false, namespace: user.namespace) }
diff --git a/spec/features/projects/user_sees_user_popover_spec.rb b/spec/features/projects/user_sees_user_popover_spec.rb
index 6197460776d..851ce79e1c6 100644
--- a/spec/features/projects/user_sees_user_popover_spec.rb
+++ b/spec/features/projects/user_sees_user_popover_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User sees user popover', :js do
+RSpec.describe 'User sees user popover', :js do
include Spec::Support::Helpers::Features::NotesHelpers
let_it_be(:project) { create(:project, :repository) }
diff --git a/spec/features/projects/user_uses_shortcuts_spec.rb b/spec/features/projects/user_uses_shortcuts_spec.rb
index 2d629ef538a..8fa5f741a95 100644
--- a/spec/features/projects/user_uses_shortcuts_spec.rb
+++ b/spec/features/projects/user_uses_shortcuts_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User uses shortcuts', :js do
+RSpec.describe 'User uses shortcuts', :js do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/features/projects/user_views_empty_project_spec.rb b/spec/features/projects/user_views_empty_project_spec.rb
index cb6b63d4dd5..9202d18b86f 100644
--- a/spec/features/projects/user_views_empty_project_spec.rb
+++ b/spec/features/projects/user_views_empty_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views an empty project' do
+RSpec.describe 'User views an empty project' do
let(:project) { create(:project, :empty_repo) }
let(:user) { create(:user) }
diff --git a/spec/features/projects/view_on_env_spec.rb b/spec/features/projects/view_on_env_spec.rb
index 845c7b89a71..6f78f888c12 100644
--- a/spec/features/projects/view_on_env_spec.rb
+++ b/spec/features/projects/view_on_env_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'View on environment', :js do
+RSpec.describe 'View on environment', :js do
let(:branch_name) { 'feature' }
let(:file_path) { 'files/ruby/feature.rb' }
let(:project) { create(:project, :repository) }
diff --git a/spec/features/projects/wiki/markdown_preview_spec.rb b/spec/features/projects/wiki/markdown_preview_spec.rb
index bc567d4db42..8eba2c98595 100644
--- a/spec/features/projects/wiki/markdown_preview_spec.rb
+++ b/spec/features/projects/wiki/markdown_preview_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Wiki > User previews markdown changes', :js do
+RSpec.describe 'Projects > Wiki > User previews markdown changes', :js do
let_it_be(:user) { create(:user) }
let(:project) { create(:project, :wiki_repo, namespace: user.namespace) }
let(:wiki_page) { create(:wiki_page, wiki: project.wiki, title: 'home', content: '[some link](other-page)') }
diff --git a/spec/features/projects/wiki/shortcuts_spec.rb b/spec/features/projects/wiki/shortcuts_spec.rb
index c51af2526c9..170e7afb51f 100644
--- a/spec/features/projects/wiki/shortcuts_spec.rb
+++ b/spec/features/projects/wiki/shortcuts_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Wiki shortcuts', :js do
+RSpec.describe 'Wiki shortcuts', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :wiki_repo, namespace: user.namespace) }
let(:wiki_page) { create(:wiki_page, wiki: project.wiki, title: 'home', content: 'Home page') }
diff --git a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb
index 5678ebcb72a..eba1b63765a 100644
--- a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User creates wiki page" do
+RSpec.describe "User creates wiki page" do
include WikiHelpers
let(:user) { create(:user) }
diff --git a/spec/features/projects/wiki/user_deletes_wiki_page_spec.rb b/spec/features/projects/wiki/user_deletes_wiki_page_spec.rb
index 38e5e292064..a5d865d581b 100644
--- a/spec/features/projects/wiki/user_deletes_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_deletes_wiki_page_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User deletes wiki page', :js do
+RSpec.describe 'User deletes wiki page', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :wiki_repo, namespace: user.namespace) }
let(:wiki_page) { create(:wiki_page, wiki: project.wiki) }
diff --git a/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb b/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb
index 6c6af1c41d2..83679c6bd1d 100644
--- a/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Wiki > User views Git access wiki page' do
+RSpec.describe 'Projects > Wiki > User views Git access wiki page' do
let(:user) { create(:user) }
let(:project) { create(:project, :wiki_repo, :public) }
let(:wiki_page) { create(:wiki_page, wiki: project.wiki, title: 'home', content: '[some link](other-page)') }
diff --git a/spec/features/projects/wiki/user_updates_wiki_page_spec.rb b/spec/features/projects/wiki/user_updates_wiki_page_spec.rb
index 55509ddfa10..05d8989d88a 100644
--- a/spec/features/projects/wiki/user_updates_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_updates_wiki_page_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User updates wiki page' do
+RSpec.describe 'User updates wiki page' do
include WikiHelpers
let(:user) { create(:user) }
@@ -29,7 +29,7 @@ describe 'User updates wiki page' do
click_on('Cancel')
end
- expect(current_path).to eq project_wiki_path(project, :home)
+ expect(current_path).to eq wiki_path(project.wiki)
end
it 'updates a page that has a path', :js do
diff --git a/spec/features/projects/wiki/user_views_wiki_empty_spec.rb b/spec/features/projects/wiki/user_views_wiki_empty_spec.rb
index ab0f9b750d2..d9f79162c19 100644
--- a/spec/features/projects/wiki/user_views_wiki_empty_spec.rb
+++ b/spec/features/projects/wiki/user_views_wiki_empty_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views empty wiki' do
+RSpec.describe 'User views empty wiki' do
let(:user) { create(:user) }
shared_examples 'empty wiki and accessible issues' do
@@ -12,6 +12,8 @@ describe 'User views empty wiki' do
element = page.find('.row.empty-state')
expect(element).to have_content('This project has no wiki pages')
+ expect(element).to have_content('You must be a project member')
+ expect(element).to have_content('improve the wiki for this project')
expect(element).to have_link("issue tracker", href: project_issues_path(project))
expect(element).to have_link("Suggest wiki improvement", href: new_project_issue_path(project))
end
@@ -24,6 +26,7 @@ describe 'User views empty wiki' do
element = page.find('.row.empty-state')
expect(element).to have_content('This project has no wiki pages')
+ expect(element).to have_content('You must be a project member')
expect(element).to have_no_link('Suggest wiki improvement')
end
end
@@ -66,9 +69,10 @@ describe 'User views empty wiki' do
it 'show "create first page" message' do
visit(project_wikis_path(project))
-
element = page.find('.row.empty-state')
+ expect(element).to have_content('your project', count: 2)
+
element.click_link 'Create your first page'
expect(page).to have_button('Create page')
diff --git a/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb b/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb
index cb425e8b704..30b94495e3d 100644
--- a/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb
+++ b/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Wiki > User views wiki in project page' do
+RSpec.describe 'Projects > Wiki > User views wiki in project page' do
let(:user) { create(:user) }
before do
diff --git a/spec/features/projects/wiki/user_views_wiki_page_spec.rb b/spec/features/projects/wiki/user_views_wiki_page_spec.rb
index e379e7466db..59ccb83a9bb 100644
--- a/spec/features/projects/wiki/user_views_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_views_wiki_page_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views a wiki page' do
+RSpec.describe 'User views a wiki page' do
include WikiHelpers
let(:user) { create(:user) }
diff --git a/spec/features/projects/wiki/user_views_wiki_pages_spec.rb b/spec/features/projects/wiki/user_views_wiki_pages_spec.rb
index 584b2a76143..fea913b8212 100644
--- a/spec/features/projects/wiki/user_views_wiki_pages_spec.rb
+++ b/spec/features/projects/wiki/user_views_wiki_pages_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views wiki pages' do
+RSpec.describe 'User views wiki pages' do
include WikiHelpers
let(:user) { create(:user) }
diff --git a/spec/features/projects/wiki/users_views_asciidoc_page_with_includes_spec.rb b/spec/features/projects/wiki/users_views_asciidoc_page_with_includes_spec.rb
index 014b63fa154..5c45e34595f 100644
--- a/spec/features/projects/wiki/users_views_asciidoc_page_with_includes_spec.rb
+++ b/spec/features/projects/wiki/users_views_asciidoc_page_with_includes_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views AsciiDoc page with includes', :js do
+RSpec.describe 'User views AsciiDoc page with includes', :js do
let_it_be(:user) { create(:user) }
let_it_be(:wiki_content_selector) { '[data-qa-selector=wiki_page_content]' }
let(:project) { create(:project, :public, :wiki_repo) }
diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb
index 47f32e0113c..ab0b6725491 100644
--- a/spec/features/projects_spec.rb
+++ b/spec/features/projects_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project' do
+RSpec.describe 'Project' do
include ProjectForksHelper
include MobileHelpers
diff --git a/spec/features/protected_branches_spec.rb b/spec/features/protected_branches_spec.rb
index 36c5a116b66..f0707610c3f 100644
--- a/spec/features/protected_branches_spec.rb
+++ b/spec/features/protected_branches_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Protected Branches', :js do
+RSpec.describe 'Protected Branches', :js do
include ProtectedBranchHelpers
let(:user) { create(:user) }
diff --git a/spec/features/protected_tags_spec.rb b/spec/features/protected_tags_spec.rb
index 3322a747cf5..12e4bbde293 100644
--- a/spec/features/protected_tags_spec.rb
+++ b/spec/features/protected_tags_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Protected Tags', :js do
+RSpec.describe 'Protected Tags', :js do
include ProtectedTagHelpers
let(:user) { create(:user, :admin) }
diff --git a/spec/features/read_only_spec.rb b/spec/features/read_only_spec.rb
index a33535a7b0b..eb043d2193a 100644
--- a/spec/features/read_only_spec.rb
+++ b/spec/features/read_only_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'read-only message' do
+RSpec.describe 'read-only message' do
let_it_be(:user) { create(:user) }
before do
diff --git a/spec/features/reportable_note/commit_spec.rb b/spec/features/reportable_note/commit_spec.rb
index 3502401095e..fc0df9d6113 100644
--- a/spec/features/reportable_note/commit_spec.rb
+++ b/spec/features/reportable_note/commit_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Reportable note on commit', :js do
+RSpec.describe 'Reportable note on commit', :js do
include RepoHelpers
let(:user) { create(:user) }
diff --git a/spec/features/reportable_note/issue_spec.rb b/spec/features/reportable_note/issue_spec.rb
index c45ef77df55..80c321d0f5a 100644
--- a/spec/features/reportable_note/issue_spec.rb
+++ b/spec/features/reportable_note/issue_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Reportable note on issue', :js do
+RSpec.describe 'Reportable note on issue', :js do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
diff --git a/spec/features/reportable_note/merge_request_spec.rb b/spec/features/reportable_note/merge_request_spec.rb
index 2e4d032754b..58a39bac707 100644
--- a/spec/features/reportable_note/merge_request_spec.rb
+++ b/spec/features/reportable_note/merge_request_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Reportable note on merge request', :js do
+RSpec.describe 'Reportable note on merge request', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:merge_request) { create(:merge_request, source_project: project) }
diff --git a/spec/features/reportable_note/snippets_spec.rb b/spec/features/reportable_note/snippets_spec.rb
index a4e609ce40c..4d61e5d8285 100644
--- a/spec/features/reportable_note/snippets_spec.rb
+++ b/spec/features/reportable_note/snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Reportable note on snippets', :js do
+RSpec.describe 'Reportable note on snippets', :js do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb
index 0049d3ca7c9..8806a363ca4 100644
--- a/spec/features/runners_spec.rb
+++ b/spec/features/runners_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Runners' do
+RSpec.describe 'Runners' do
let(:user) { create(:user) }
before do
diff --git a/spec/features/search/user_searches_for_code_spec.rb b/spec/features/search/user_searches_for_code_spec.rb
index 0fdc7346535..227e75088d2 100644
--- a/spec/features/search/user_searches_for_code_spec.rb
+++ b/spec/features/search/user_searches_for_code_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User searches for code' do
+RSpec.describe 'User searches for code' do
let(:user) { create(:user) }
let(:project) { create(:project, :repository, namespace: user.namespace) }
diff --git a/spec/features/search/user_searches_for_comments_spec.rb b/spec/features/search/user_searches_for_comments_spec.rb
index 0a203a5bf2d..2a12b22b457 100644
--- a/spec/features/search/user_searches_for_comments_spec.rb
+++ b/spec/features/search/user_searches_for_comments_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User searches for comments' do
+RSpec.describe 'User searches for comments' do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/features/search/user_searches_for_commits_spec.rb b/spec/features/search/user_searches_for_commits_spec.rb
index 958f12d3b84..b860cd08e64 100644
--- a/spec/features/search/user_searches_for_commits_spec.rb
+++ b/spec/features/search/user_searches_for_commits_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User searches for commits' do
+RSpec.describe 'User searches for commits' do
let(:project) { create(:project, :repository) }
let(:sha) { '6d394385cf567f80a8fd85055db1ab4c5295806f' }
let(:user) { create(:user) }
diff --git a/spec/features/search/user_searches_for_issues_spec.rb b/spec/features/search/user_searches_for_issues_spec.rb
index ae718cec7af..e9943347522 100644
--- a/spec/features/search/user_searches_for_issues_spec.rb
+++ b/spec/features/search/user_searches_for_issues_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User searches for issues', :js do
+RSpec.describe 'User searches for issues', :js do
let(:user) { create(:user) }
let(:project) { create(:project, namespace: user.namespace) }
let!(:issue1) { create(:issue, title: 'Foo', project: project) }
diff --git a/spec/features/search/user_searches_for_merge_requests_spec.rb b/spec/features/search/user_searches_for_merge_requests_spec.rb
index 0139ac26816..40583664958 100644
--- a/spec/features/search/user_searches_for_merge_requests_spec.rb
+++ b/spec/features/search/user_searches_for_merge_requests_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User searches for merge requests', :js do
+RSpec.describe 'User searches for merge requests', :js do
let(:user) { create(:user) }
let(:project) { create(:project, namespace: user.namespace) }
let!(:merge_request1) { create(:merge_request, title: 'Foo', source_project: project, target_project: project) }
diff --git a/spec/features/search/user_searches_for_milestones_spec.rb b/spec/features/search/user_searches_for_milestones_spec.rb
index 0714cfcc309..64e756db180 100644
--- a/spec/features/search/user_searches_for_milestones_spec.rb
+++ b/spec/features/search/user_searches_for_milestones_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User searches for milestones', :js do
+RSpec.describe 'User searches for milestones', :js do
let(:user) { create(:user) }
let(:project) { create(:project, namespace: user.namespace) }
let!(:milestone1) { create(:milestone, title: 'Foo', project: project) }
diff --git a/spec/features/search/user_searches_for_projects_spec.rb b/spec/features/search/user_searches_for_projects_spec.rb
index b194ac32ff6..7bb5a4da7d0 100644
--- a/spec/features/search/user_searches_for_projects_spec.rb
+++ b/spec/features/search/user_searches_for_projects_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User searches for projects' do
+RSpec.describe 'User searches for projects' do
let!(:project) { create(:project, :public, name: 'Shop') }
context 'when signed out' do
diff --git a/spec/features/search/user_searches_for_users_spec.rb b/spec/features/search/user_searches_for_users_spec.rb
index 6f2c5d48018..826ed73c9bf 100644
--- a/spec/features/search/user_searches_for_users_spec.rb
+++ b/spec/features/search/user_searches_for_users_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User searches for users' do
+RSpec.describe 'User searches for users' do
let(:user1) { create(:user, username: 'gob_bluth', name: 'Gob Bluth') }
let(:user2) { create(:user, username: 'michael_bluth', name: 'Michael Bluth') }
let(:user3) { create(:user, username: 'gob_2018', name: 'George Oscar Bluth') }
diff --git a/spec/features/search/user_searches_for_wiki_pages_spec.rb b/spec/features/search/user_searches_for_wiki_pages_spec.rb
index 10c3032da8b..fc60b6244d9 100644
--- a/spec/features/search/user_searches_for_wiki_pages_spec.rb
+++ b/spec/features/search/user_searches_for_wiki_pages_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User searches for wiki pages', :js do
+RSpec.describe 'User searches for wiki pages', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :repository, :wiki_repo, namespace: user.namespace) }
let!(:wiki_page) { create(:wiki_page, wiki: project.wiki, title: 'directory/title', content: 'Some Wiki content') }
diff --git a/spec/features/search/user_uses_header_search_field_spec.rb b/spec/features/search/user_uses_header_search_field_spec.rb
index 7b969aea547..5567dcb30ec 100644
--- a/spec/features/search/user_uses_header_search_field_spec.rb
+++ b/spec/features/search/user_uses_header_search_field_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User uses header search field', :js do
+RSpec.describe 'User uses header search field', :js do
include FilteredSearchHelpers
let(:project) { create(:project) }
@@ -95,14 +95,6 @@ describe 'User uses header search field', :js do
expect(page).not_to have_selector('.dropdown-header', text: /#{scope_name}/i)
end
-
- it 'hides the dropdown when there are no results' do
- page.within('.search-input-wrap') do
- fill_in('search', with: 'a_search_term_with_no_results')
- end
-
- expect(page).not_to have_selector('.dropdown-menu')
- end
end
end
diff --git a/spec/features/search/user_uses_search_filters_spec.rb b/spec/features/search/user_uses_search_filters_spec.rb
index fbd7da3c643..f39a1f8fe37 100644
--- a/spec/features/search/user_uses_search_filters_spec.rb
+++ b/spec/features/search/user_uses_search_filters_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User uses search filters', :js do
+RSpec.describe 'User uses search filters', :js do
let(:group) { create(:group) }
let!(:group_project) { create(:project, group: group) }
let(:project) { create(:project, namespace: user.namespace) }
diff --git a/spec/features/security/admin_access_spec.rb b/spec/features/security/admin_access_spec.rb
index 9b2c873b2aa..38f00f399f3 100644
--- a/spec/features/security/admin_access_spec.rb
+++ b/spec/features/security/admin_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Admin::Projects" do
+RSpec.describe "Admin::Projects" do
include AccessMatchers
describe "GET /admin/projects" do
diff --git a/spec/features/security/dashboard_access_spec.rb b/spec/features/security/dashboard_access_spec.rb
index 13fafd88a4c..5ac4a5c1840 100644
--- a/spec/features/security/dashboard_access_spec.rb
+++ b/spec/features/security/dashboard_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Dashboard access" do
+RSpec.describe "Dashboard access" do
include AccessMatchers
describe "GET /dashboard" do
diff --git a/spec/features/security/group/internal_access_spec.rb b/spec/features/security/group/internal_access_spec.rb
index 114bc1a1f0c..c146ac1e8ee 100644
--- a/spec/features/security/group/internal_access_spec.rb
+++ b/spec/features/security/group/internal_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Internal Group access' do
+RSpec.describe 'Internal Group access' do
include AccessMatchers
let(:group) { create(:group, :internal) }
diff --git a/spec/features/security/group/private_access_spec.rb b/spec/features/security/group/private_access_spec.rb
index 3362b9a9e9e..de05b4d3d16 100644
--- a/spec/features/security/group/private_access_spec.rb
+++ b/spec/features/security/group/private_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Private Group access' do
+RSpec.describe 'Private Group access' do
include AccessMatchers
let(:group) { create(:group, :private) }
diff --git a/spec/features/security/group/public_access_spec.rb b/spec/features/security/group/public_access_spec.rb
index bf05f276cc6..ee72b84616a 100644
--- a/spec/features/security/group/public_access_spec.rb
+++ b/spec/features/security/group/public_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Public Group access' do
+RSpec.describe 'Public Group access' do
include AccessMatchers
let(:group) { create(:group, :public) }
diff --git a/spec/features/security/profile_access_spec.rb b/spec/features/security/profile_access_spec.rb
index 044a47567be..3aa8278866c 100644
--- a/spec/features/security/profile_access_spec.rb
+++ b/spec/features/security/profile_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Profile access" do
+RSpec.describe "Profile access" do
include AccessMatchers
describe "GET /profile/keys" do
diff --git a/spec/features/security/project/internal_access_spec.rb b/spec/features/security/project/internal_access_spec.rb
index f29aa8de928..99f30d2f904 100644
--- a/spec/features/security/project/internal_access_spec.rb
+++ b/spec/features/security/project/internal_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Internal Project Access" do
+RSpec.describe "Internal Project Access" do
include AccessMatchers
let_it_be(:project, reload: true) { create(:project, :internal, :repository) }
@@ -85,8 +85,8 @@ describe "Internal Project Access" do
it { is_expected.to be_denied_for(:visitor) }
end
- describe "GET /:project_path/-/settings/members" do
- subject { project_settings_members_path(project) }
+ describe "GET /:project_path/-/project_members" do
+ subject { project_project_members_path(project) }
it { is_expected.to be_allowed_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
diff --git a/spec/features/security/project/private_access_spec.rb b/spec/features/security/project/private_access_spec.rb
index ac8596d89bc..e891e79db70 100644
--- a/spec/features/security/project/private_access_spec.rb
+++ b/spec/features/security/project/private_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Private Project Access" do
+RSpec.describe "Private Project Access" do
include AccessMatchers
let_it_be(:project, reload: true) { create(:project, :private, :repository, public_builds: false) }
@@ -85,8 +85,8 @@ describe "Private Project Access" do
it { is_expected.to be_denied_for(:visitor) }
end
- describe "GET /:project_path/-/settings/members" do
- subject { project_settings_members_path(project) }
+ describe "GET /:project_path/-/project_members" do
+ subject { project_project_members_path(project) }
it { is_expected.to be_allowed_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
diff --git a/spec/features/security/project/public_access_spec.rb b/spec/features/security/project/public_access_spec.rb
index 11e9bff10a1..ea00a59dee4 100644
--- a/spec/features/security/project/public_access_spec.rb
+++ b/spec/features/security/project/public_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Public Project Access" do
+RSpec.describe "Public Project Access" do
include AccessMatchers
let_it_be(:project, reload: true) { create(:project, :public, :repository) }
@@ -85,8 +85,8 @@ describe "Public Project Access" do
it { is_expected.to be_allowed_for(:visitor) }
end
- describe "GET /:project_path/-/settings/members" do
- subject { project_settings_members_path(project) }
+ describe "GET /:project_path/-/project_members" do
+ subject { project_project_members_path(project) }
it { is_expected.to be_allowed_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
diff --git a/spec/features/security/project/snippet/internal_access_spec.rb b/spec/features/security/project/snippet/internal_access_spec.rb
index 4b6c7d2c8fb..52ae1022a4e 100644
--- a/spec/features/security/project/snippet/internal_access_spec.rb
+++ b/spec/features/security/project/snippet/internal_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Internal Project Snippets Access" do
+RSpec.describe "Internal Project Snippets Access" do
include AccessMatchers
let(:project) { create(:project, :internal) }
diff --git a/spec/features/security/project/snippet/private_access_spec.rb b/spec/features/security/project/snippet/private_access_spec.rb
index 3135d25cc10..0c97b012ad1 100644
--- a/spec/features/security/project/snippet/private_access_spec.rb
+++ b/spec/features/security/project/snippet/private_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Private Project Snippets Access" do
+RSpec.describe "Private Project Snippets Access" do
include AccessMatchers
let(:project) { create(:project, :private) }
diff --git a/spec/features/security/project/snippet/public_access_spec.rb b/spec/features/security/project/snippet/public_access_spec.rb
index 81689a7bcb5..dfe78aa7ebc 100644
--- a/spec/features/security/project/snippet/public_access_spec.rb
+++ b/spec/features/security/project/snippet/public_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Public Project Snippets Access" do
+RSpec.describe "Public Project Snippets Access" do
include AccessMatchers
let(:project) { create(:project, :public) }
diff --git a/spec/features/sentry_js_spec.rb b/spec/features/sentry_js_spec.rb
index b39c4f0a0ae..1d277ba7b3c 100644
--- a/spec/features/sentry_js_spec.rb
+++ b/spec/features/sentry_js_spec.rb
@@ -2,8 +2,8 @@
require 'spec_helper'
-describe 'Sentry' do
- let(:sentry_path) { '/sentry.chunk.js' }
+RSpec.describe 'Sentry' do
+ let(:sentry_regex_path) { '\/sentry.*\.chunk\.js' }
it 'does not load sentry if sentry is disabled' do
allow(Gitlab.config.sentry).to receive(:enabled).and_return(false)
@@ -22,7 +22,7 @@ describe 'Sentry' do
def has_requested_sentry
page.all('script', visible: false).one? do |elm|
- elm[:src] =~ /#{sentry_path}$/
+ elm[:src] =~ /#{sentry_regex_path}$/
end
end
end
diff --git a/spec/features/signed_commits_spec.rb b/spec/features/signed_commits_spec.rb
index 3c7a31ac11b..04ca8a09ca8 100644
--- a/spec/features/signed_commits_spec.rb
+++ b/spec/features/signed_commits_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'GPG signed commits' do
+RSpec.describe 'GPG signed commits' do
let(:project) { create(:project, :public, :repository) }
it 'changes from unverified to verified when the user changes their email to match the gpg key', :sidekiq_might_not_need_inline do
diff --git a/spec/features/snippets/embedded_snippet_spec.rb b/spec/features/snippets/embedded_snippet_spec.rb
index d6275b5a265..4f2ab598a6f 100644
--- a/spec/features/snippets/embedded_snippet_spec.rb
+++ b/spec/features/snippets/embedded_snippet_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Embedded Snippets' do
+RSpec.describe 'Embedded Snippets' do
let(:snippet) { create(:personal_snippet, :public, file_name: 'random_dir.rb', content: content) }
let(:content) { "require 'fileutils'\nFileUtils.mkdir_p 'some/random_dir'\n" }
diff --git a/spec/features/snippets/explore_spec.rb b/spec/features/snippets/explore_spec.rb
index 2075742eafb..b62c35bf96e 100644
--- a/spec/features/snippets/explore_spec.rb
+++ b/spec/features/snippets/explore_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Explore Snippets' do
+RSpec.describe 'Explore Snippets' do
let!(:public_snippet) { create(:personal_snippet, :public) }
let!(:internal_snippet) { create(:personal_snippet, :internal) }
let!(:private_snippet) { create(:personal_snippet, :private) }
diff --git a/spec/features/snippets/internal_snippet_spec.rb b/spec/features/snippets/internal_snippet_spec.rb
index fd7ef71db15..3ce297ab22d 100644
--- a/spec/features/snippets/internal_snippet_spec.rb
+++ b/spec/features/snippets/internal_snippet_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Internal Snippets', :js do
+RSpec.describe 'Internal Snippets', :js do
let(:internal_snippet) { create(:personal_snippet, :internal) }
before do
diff --git a/spec/features/snippets/notes_on_personal_snippets_spec.rb b/spec/features/snippets/notes_on_personal_snippets_spec.rb
index 57264f97ddc..aaaa61fec62 100644
--- a/spec/features/snippets/notes_on_personal_snippets_spec.rb
+++ b/spec/features/snippets/notes_on_personal_snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Comments on personal snippets', :js do
+RSpec.describe 'Comments on personal snippets', :js do
include NoteInteractionHelpers
let!(:user) { create(:user) }
diff --git a/spec/features/snippets/private_snippets_spec.rb b/spec/features/snippets/private_snippets_spec.rb
index 37f45f22a27..6b45f3485e7 100644
--- a/spec/features/snippets/private_snippets_spec.rb
+++ b/spec/features/snippets/private_snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Private Snippets', :js do
+RSpec.describe 'Private Snippets', :js do
let(:user) { create(:user) }
before do
diff --git a/spec/features/snippets/public_snippets_spec.rb b/spec/features/snippets/public_snippets_spec.rb
index 295e61ffb56..4b72b33245d 100644
--- a/spec/features/snippets/public_snippets_spec.rb
+++ b/spec/features/snippets/public_snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Public Snippets', :js do
+RSpec.describe 'Public Snippets', :js do
before do
stub_feature_flags(snippets_vue: false)
end
diff --git a/spec/features/snippets/search_snippets_spec.rb b/spec/features/snippets/search_snippets_spec.rb
index d3e02d43813..4f299edc9da 100644
--- a/spec/features/snippets/search_snippets_spec.rb
+++ b/spec/features/snippets/search_snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Search Snippets' do
+RSpec.describe 'Search Snippets' do
it 'User searches for snippets by title' do
public_snippet = create(:personal_snippet, :public, title: 'Beginning and Middle')
private_snippet = create(:personal_snippet, :private, title: 'Middle and End')
diff --git a/spec/features/snippets/show_spec.rb b/spec/features/snippets/show_spec.rb
index 9c686be012b..9125ed74273 100644
--- a/spec/features/snippets/show_spec.rb
+++ b/spec/features/snippets/show_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Snippet', :js do
+RSpec.describe 'Snippet', :js do
let(:project) { create(:project, :repository) }
let(:snippet) { create(:personal_snippet, :public, file_name: file_name, content: content) }
diff --git a/spec/features/snippets/spam_snippets_spec.rb b/spec/features/snippets/spam_snippets_spec.rb
index d7b181dc678..e6a9467a3d7 100644
--- a/spec/features/snippets/spam_snippets_spec.rb
+++ b/spec/features/snippets/spam_snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-shared_examples_for 'snippet editor' do
+RSpec.shared_examples_for 'snippet editor' do
include_context 'includes Spam constants'
def description_field
@@ -68,7 +68,7 @@ shared_examples_for 'snippet editor' do
context 'when SpamVerdictService requires recaptcha' do
before do
expect_next_instance_of(Spam::SpamVerdictService) do |verdict_service|
- expect(verdict_service).to receive(:execute).and_return(REQUIRE_RECAPTCHA)
+ expect(verdict_service).to receive(:execute).and_return(CONDITIONAL_ALLOW)
end
end
@@ -122,7 +122,7 @@ shared_examples_for 'snippet editor' do
end
end
-describe 'User creates snippet', :js do
+RSpec.describe 'User creates snippet', :js do
let_it_be(:user) { create(:user) }
it_behaves_like "snippet editor"
diff --git a/spec/features/snippets/user_creates_snippet_spec.rb b/spec/features/snippets/user_creates_snippet_spec.rb
index 62054c1f491..b100e035d38 100644
--- a/spec/features/snippets/user_creates_snippet_spec.rb
+++ b/spec/features/snippets/user_creates_snippet_spec.rb
@@ -2,12 +2,11 @@
require 'spec_helper'
-shared_examples_for 'snippet editor' do
+RSpec.shared_examples_for 'snippet editor' do
before do
stub_feature_flags(snippets_vue: false)
stub_feature_flags(snippets_edit_vue: false)
sign_in(user)
- visit new_snippet_path
end
def description_field
@@ -28,6 +27,8 @@ shared_examples_for 'snippet editor' do
end
it 'Authenticated user creates a snippet' do
+ visit new_snippet_path
+
fill_form
click_button('Create snippet')
@@ -42,6 +43,8 @@ shared_examples_for 'snippet editor' do
end
it 'previews a snippet with file' do
+ visit new_snippet_path
+
# Click placeholder first to expand full description field
description_field.click
fill_in 'personal_snippet_description', with: 'My Snippet'
@@ -62,6 +65,8 @@ shared_examples_for 'snippet editor' do
end
it 'uploads a file when dragging into textarea' do
+ visit new_snippet_path
+
fill_form
dropzone_file Rails.root.join('spec', 'fixtures', 'banana_sample.gif')
@@ -86,6 +91,8 @@ shared_examples_for 'snippet editor' do
allow(instance).to receive(:create_commit).and_raise(StandardError, error)
end
+ visit new_snippet_path
+
fill_form
click_button('Create snippet')
@@ -107,6 +114,8 @@ shared_examples_for 'snippet editor' do
end
it 'validation fails for the first time' do
+ visit new_snippet_path
+
fill_in 'personal_snippet_title', with: 'My Snippet Title'
click_button('Create snippet')
@@ -132,6 +141,8 @@ shared_examples_for 'snippet editor' do
end
it 'Authenticated user creates a snippet with + in filename' do
+ visit new_snippet_path
+
fill_in 'personal_snippet_title', with: 'My Snippet Title'
page.within('.file-editor') do
find(:xpath, "//input[@id='personal_snippet_file_name']").set 'snippet+file+name'
@@ -146,9 +157,32 @@ shared_examples_for 'snippet editor' do
expect(page).to have_content('snippet+file+name')
expect(page).to have_content('Hello World!')
end
+
+ context 'when snippets default visibility level is restricted' do
+ before do
+ stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PRIVATE],
+ default_snippet_visibility: Gitlab::VisibilityLevel::PRIVATE)
+ end
+
+ it 'creates a snippet using the lowest available visibility level as default' do
+ visit new_snippet_path
+
+ fill_form
+
+ click_button('Create snippet')
+ wait_for_requests
+
+ visit snippets_path
+ click_link('Internal')
+
+ expect(page).to have_content('My Snippet Title')
+ created_snippet = Snippet.last
+ expect(created_snippet.visibility_level).to eq(Gitlab::VisibilityLevel::INTERNAL)
+ end
+ end
end
-describe 'User creates snippet', :js do
+RSpec.describe 'User creates snippet', :js do
include DropzoneHelper
let_it_be(:user) { create(:user) }
diff --git a/spec/features/snippets/user_deletes_snippet_spec.rb b/spec/features/snippets/user_deletes_snippet_spec.rb
index 35619b92561..d7cfc67df13 100644
--- a/spec/features/snippets/user_deletes_snippet_spec.rb
+++ b/spec/features/snippets/user_deletes_snippet_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User deletes snippet' do
+RSpec.describe 'User deletes snippet' do
let(:user) { create(:user) }
let(:content) { 'puts "test"' }
let(:snippet) { create(:personal_snippet, :public, content: content, author: user) }
diff --git a/spec/features/snippets/user_edits_snippet_spec.rb b/spec/features/snippets/user_edits_snippet_spec.rb
index 40b0113cf39..3692b0d1ad8 100644
--- a/spec/features/snippets/user_edits_snippet_spec.rb
+++ b/spec/features/snippets/user_edits_snippet_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User edits snippet', :js do
+RSpec.describe 'User edits snippet', :js do
include DropzoneHelper
let_it_be(:file_name) { 'test.rb' }
diff --git a/spec/features/snippets/user_snippets_spec.rb b/spec/features/snippets/user_snippets_spec.rb
index d9faea55b29..a313dc3b26a 100644
--- a/spec/features/snippets/user_snippets_spec.rb
+++ b/spec/features/snippets/user_snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User Snippets' do
+RSpec.describe 'User Snippets' do
let(:author) { create(:user) }
let!(:public_snippet) { create(:personal_snippet, :public, author: author, title: "This is a public snippet") }
let!(:internal_snippet) { create(:personal_snippet, :internal, author: author, title: "This is an internal snippet") }
diff --git a/spec/features/snippets_spec.rb b/spec/features/snippets_spec.rb
index bc7fa161e87..75309ca3e7c 100644
--- a/spec/features/snippets_spec.rb
+++ b/spec/features/snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Snippets' do
+RSpec.describe 'Snippets' do
context 'when the project has snippets' do
let(:project) { create(:project, :public) }
let!(:snippets) { create_list(:project_snippet, 2, :public, author: project.owner, project: project) }
diff --git a/spec/features/static_site_editor_spec.rb b/spec/features/static_site_editor_spec.rb
index de000ee2b9f..9ae23b4bdec 100644
--- a/spec/features/static_site_editor_spec.rb
+++ b/spec/features/static_site_editor_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Static Site Editor' do
+RSpec.describe 'Static Site Editor' do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :public, :repository) }
diff --git a/spec/features/tags/developer_creates_tag_spec.rb b/spec/features/tags/developer_creates_tag_spec.rb
index a2d53b04c9d..f982d403ce1 100644
--- a/spec/features/tags/developer_creates_tag_spec.rb
+++ b/spec/features/tags/developer_creates_tag_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Developer creates tag' do
+RSpec.describe 'Developer creates tag' do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:project) { create(:project, :repository, namespace: group) }
diff --git a/spec/features/tags/developer_deletes_tag_spec.rb b/spec/features/tags/developer_deletes_tag_spec.rb
index 50eac8ddaed..de9296bc08e 100644
--- a/spec/features/tags/developer_deletes_tag_spec.rb
+++ b/spec/features/tags/developer_deletes_tag_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Developer deletes tag' do
+RSpec.describe 'Developer deletes tag' do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:project) { create(:project, :repository, namespace: group) }
diff --git a/spec/features/tags/developer_updates_tag_spec.rb b/spec/features/tags/developer_updates_tag_spec.rb
index 167079c3f31..93a275131bd 100644
--- a/spec/features/tags/developer_updates_tag_spec.rb
+++ b/spec/features/tags/developer_updates_tag_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Developer updates tag' do
+RSpec.describe 'Developer updates tag' do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:project) { create(:project, :repository, namespace: group) }
diff --git a/spec/features/tags/developer_views_tags_spec.rb b/spec/features/tags/developer_views_tags_spec.rb
index b892b2b4d12..4888611472c 100644
--- a/spec/features/tags/developer_views_tags_spec.rb
+++ b/spec/features/tags/developer_views_tags_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Developer views tags' do
+RSpec.describe 'Developer views tags' do
let(:user) { create(:user) }
let(:group) { create(:group) }
diff --git a/spec/features/task_lists_spec.rb b/spec/features/task_lists_spec.rb
index 24a183017c9..fa87c4bb1c4 100644
--- a/spec/features/task_lists_spec.rb
+++ b/spec/features/task_lists_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Task Lists' do
+RSpec.describe 'Task Lists' do
include Warden::Test::Helpers
let(:project) { create(:project, :public, :repository) }
diff --git a/spec/features/triggers_spec.rb b/spec/features/triggers_spec.rb
index af406961bbc..577134fe722 100644
--- a/spec/features/triggers_spec.rb
+++ b/spec/features/triggers_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Triggers', :js do
+RSpec.describe 'Triggers', :js do
let(:trigger_title) { 'trigger desc' }
let(:user) { create(:user) }
let(:user2) { create(:user) }
diff --git a/spec/features/u2f_spec.rb b/spec/features/u2f_spec.rb
index bb18703f90e..8dbedc0a7ee 100644
--- a/spec/features/u2f_spec.rb
+++ b/spec/features/u2f_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do
+RSpec.describe 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do
def manage_two_factor_authentication
click_on 'Manage two-factor authentication'
expect(page).to have_content("Set up new U2F device")
@@ -257,7 +257,7 @@ describe 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do
expect(page).to have_button('Verify code')
expect(page).to have_css('#user_otp_attempt')
expect(page).not_to have_link('Sign in via 2FA code')
- expect(page).not_to have_css('#js-authenticate-u2f')
+ expect(page).not_to have_css('#js-authenticate-token-2fa')
end
before do
diff --git a/spec/features/unsubscribe_links_spec.rb b/spec/features/unsubscribe_links_spec.rb
index cf30776786b..966d90ab16b 100644
--- a/spec/features/unsubscribe_links_spec.rb
+++ b/spec/features/unsubscribe_links_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Unsubscribe links', :sidekiq_might_not_need_inline do
+RSpec.describe 'Unsubscribe links', :sidekiq_might_not_need_inline do
include Warden::Test::Helpers
let(:recipient) { create(:user) }
diff --git a/spec/features/uploads/user_uploads_avatar_to_group_spec.rb b/spec/features/uploads/user_uploads_avatar_to_group_spec.rb
index d9d9d7e4b04..8daa869a6e3 100644
--- a/spec/features/uploads/user_uploads_avatar_to_group_spec.rb
+++ b/spec/features/uploads/user_uploads_avatar_to_group_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User uploads avatar to group' do
+RSpec.describe 'User uploads avatar to group' do
it 'they see the new avatar' do
user = create(:user)
group = create(:group)
diff --git a/spec/features/uploads/user_uploads_avatar_to_profile_spec.rb b/spec/features/uploads/user_uploads_avatar_to_profile_spec.rb
index fc31d7aa3d1..31e29810c65 100644
--- a/spec/features/uploads/user_uploads_avatar_to_profile_spec.rb
+++ b/spec/features/uploads/user_uploads_avatar_to_profile_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User uploads avatar to profile' do
+RSpec.describe 'User uploads avatar to profile' do
let!(:user) { create(:user) }
let(:avatar_file_path) { Rails.root.join('spec', 'fixtures', 'dk.png') }
diff --git a/spec/features/uploads/user_uploads_file_to_note_spec.rb b/spec/features/uploads/user_uploads_file_to_note_spec.rb
index 570ecad41fa..7f55ddc1d64 100644
--- a/spec/features/uploads/user_uploads_file_to_note_spec.rb
+++ b/spec/features/uploads/user_uploads_file_to_note_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User uploads file to note' do
+RSpec.describe 'User uploads file to note' do
include DropzoneHelper
let(:user) { create(:user) }
diff --git a/spec/features/usage_stats_consent_spec.rb b/spec/features/usage_stats_consent_spec.rb
index 14232b1b370..04bdf25acc0 100644
--- a/spec/features/usage_stats_consent_spec.rb
+++ b/spec/features/usage_stats_consent_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Usage stats consent' do
+RSpec.describe 'Usage stats consent' do
context 'when signed in' do
let(:user) { create(:admin, created_at: 8.days.ago) }
let(:message) { 'To help improve GitLab, we would like to periodically collect usage information.' }
diff --git a/spec/features/user_can_display_performance_bar_spec.rb b/spec/features/user_can_display_performance_bar_spec.rb
index 8b3f193f418..9c67523f88f 100644
--- a/spec/features/user_can_display_performance_bar_spec.rb
+++ b/spec/features/user_can_display_performance_bar_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User can display performance bar', :js do
+RSpec.describe 'User can display performance bar', :js do
shared_examples 'performance bar cannot be displayed' do
it 'does not show the performance bar by default' do
expect(page).not_to have_css('#js-peek')
diff --git a/spec/features/user_opens_link_to_comment_spec.rb b/spec/features/user_opens_link_to_comment_spec.rb
index 9533a4fe40d..ae84f69f432 100644
--- a/spec/features/user_opens_link_to_comment_spec.rb
+++ b/spec/features/user_opens_link_to_comment_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User opens link to comment', :js do
+RSpec.describe 'User opens link to comment', :js do
let(:project) { create(:project, :public) }
let(:note) { create(:note_on_issue, project: project) }
diff --git a/spec/features/user_sees_revert_modal_spec.rb b/spec/features/user_sees_revert_modal_spec.rb
index c0cffe885de..331f51dad95 100644
--- a/spec/features/user_sees_revert_modal_spec.rb
+++ b/spec/features/user_sees_revert_modal_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Merge request > User sees revert modal', :js, :sidekiq_might_not_need_inline do
+RSpec.describe 'Merge request > User sees revert modal', :js, :sidekiq_might_not_need_inline do
let(:project) { create(:project, :public, :repository) }
let(:user) { project.creator }
let(:merge_request) { create(:merge_request, source_project: project) }
diff --git a/spec/features/user_sorts_things_spec.rb b/spec/features/user_sorts_things_spec.rb
index 8397854df27..6eaa620b538 100644
--- a/spec/features/user_sorts_things_spec.rb
+++ b/spec/features/user_sorts_things_spec.rb
@@ -6,7 +6,7 @@ require "spec_helper"
# to check if the sorting option set by user is being kept persisted while going through pages.
# The `it`s are named here by convention `starting point -> some pages -> final point`.
# All those specs are moved out to this spec intentionally to keep them all in one place.
-describe "User sorts things" do
+RSpec.describe "User sorts things" do
include Spec::Support::Helpers::Features::SortingHelpers
include DashboardHelper
diff --git a/spec/features/users/active_sessions_spec.rb b/spec/features/users/active_sessions_spec.rb
index c717e89eafb..8e2e16e555e 100644
--- a/spec/features/users/active_sessions_spec.rb
+++ b/spec/features/users/active_sessions_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Active user sessions', :clean_gitlab_redis_shared_state do
+RSpec.describe 'Active user sessions', :clean_gitlab_redis_shared_state do
it 'Successful login adds a new active user login' do
now = Time.zone.parse('2018-03-12 09:06')
Timecop.freeze(now) do
diff --git a/spec/features/users/add_email_to_existing_account_spec.rb b/spec/features/users/add_email_to_existing_account_spec.rb
index 42e352399a8..9130b96b0e3 100644
--- a/spec/features/users/add_email_to_existing_account_spec.rb
+++ b/spec/features/users/add_email_to_existing_account_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'AdditionalEmailToExistingAccount' do
+RSpec.describe 'AdditionalEmailToExistingAccount' do
describe 'add secondary email associated with account' do
let(:user) { create(:user) }
diff --git a/spec/features/users/anonymous_sessions_spec.rb b/spec/features/users/anonymous_sessions_spec.rb
index e87ee39a3f4..420fb225f94 100644
--- a/spec/features/users/anonymous_sessions_spec.rb
+++ b/spec/features/users/anonymous_sessions_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Session TTLs', :clean_gitlab_redis_shared_state do
+RSpec.describe 'Session TTLs', :clean_gitlab_redis_shared_state do
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
diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb
index 5a8db3c070d..7ba663d08d4 100644
--- a/spec/features/users/login_spec.rb
+++ b/spec/features/users/login_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Login' do
+RSpec.describe 'Login' do
include TermsHelper
include UserLoginHelper
diff --git a/spec/features/users/logout_spec.rb b/spec/features/users/logout_spec.rb
index a72a42c738d..ffb8785b277 100644
--- a/spec/features/users/logout_spec.rb
+++ b/spec/features/users/logout_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Logout/Sign out', :js do
+RSpec.describe 'Logout/Sign out', :js do
let(:user) { create(:user) }
before do
diff --git a/spec/features/users/overview_spec.rb b/spec/features/users/overview_spec.rb
index b3531d040e4..549087e5950 100644
--- a/spec/features/users/overview_spec.rb
+++ b/spec/features/users/overview_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Overview tab on a user profile', :js do
+RSpec.describe 'Overview tab on a user profile', :js do
let(:user) { create(:user) }
let(:contributed_project) { create(:project, :public, :repository) }
diff --git a/spec/features/users/rss_spec.rb b/spec/features/users/rss_spec.rb
index ecdbf032623..aba1ff63fab 100644
--- a/spec/features/users/rss_spec.rb
+++ b/spec/features/users/rss_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User RSS' do
+RSpec.describe 'User RSS' do
let(:user) { create(:user) }
let(:path) { user_path(create(:user)) }
diff --git a/spec/features/users/show_spec.rb b/spec/features/users/show_spec.rb
index a45389a7ed5..dd5c2442d00 100644
--- a/spec/features/users/show_spec.rb
+++ b/spec/features/users/show_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User page' do
+RSpec.describe 'User page' do
include ExternalAuthorizationServiceHelpers
let(:user) { create(:user) }
diff --git a/spec/features/users/signup_spec.rb b/spec/features/users/signup_spec.rb
index 0ef86dde030..66a26493339 100644
--- a/spec/features/users/signup_spec.rb
+++ b/spec/features/users/signup_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-shared_examples 'Signup' do
+RSpec.shared_examples 'Signup' do
include TermsHelper
let(:new_user) { build_stubbed(:user) }
@@ -420,7 +420,7 @@ shared_examples 'Signup' do
end
end
-shared_examples 'Signup name validation' do |field, max_length|
+RSpec.shared_examples 'Signup name validation' do |field, max_length|
before do
visit new_user_registration_path
end
@@ -458,7 +458,7 @@ shared_examples 'Signup name validation' do |field, max_length|
end
end
-describe 'With original flow' do
+RSpec.describe 'With original flow' do
before do
stub_experiment(signup_flow: false)
stub_experiment_for_user(signup_flow: false)
@@ -468,7 +468,7 @@ describe 'With original flow' do
it_behaves_like 'Signup name validation', 'new_user_name', 255
end
-describe 'With experimental flow' do
+RSpec.describe 'With experimental flow' do
before do
stub_experiment(signup_flow: true)
stub_experiment_for_user(signup_flow: true)
diff --git a/spec/features/users/snippets_spec.rb b/spec/features/users/snippets_spec.rb
index 8b6bf54b642..ce19e491a7c 100644
--- a/spec/features/users/snippets_spec.rb
+++ b/spec/features/users/snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Snippets tab on a user profile', :js do
+RSpec.describe 'Snippets tab on a user profile', :js do
context 'when the user has snippets' do
let(:user) { create(:user) }
diff --git a/spec/features/users/terms_spec.rb b/spec/features/users/terms_spec.rb
index ec2210faa80..5275845fe5b 100644
--- a/spec/features/users/terms_spec.rb
+++ b/spec/features/users/terms_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Users > Terms' do
+RSpec.describe 'Users > Terms' do
include TermsHelper
let!(:term) { create(:term, terms: 'By accepting, you promise to be nice!') }
diff --git a/spec/features/users/user_browses_projects_on_user_page_spec.rb b/spec/features/users/user_browses_projects_on_user_page_spec.rb
index 9a1ee7715d6..7d05b2ae27a 100644
--- a/spec/features/users/user_browses_projects_on_user_page_spec.rb
+++ b/spec/features/users/user_browses_projects_on_user_page_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Users > User browses projects on user page', :js do
+RSpec.describe 'Users > User browses projects on user page', :js do
let!(:user) { create :user }
let!(:private_project) do
create :project, :private, name: 'private', namespace: user.namespace do |project|
diff --git a/spec/finders/abuse_reports_finder_spec.rb b/spec/finders/abuse_reports_finder_spec.rb
index c84a645ca08..52620b3e421 100644
--- a/spec/finders/abuse_reports_finder_spec.rb
+++ b/spec/finders/abuse_reports_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe AbuseReportsFinder, '#execute' do
+RSpec.describe AbuseReportsFinder, '#execute' do
let(:params) { {} }
let!(:user1) { create(:user) }
let!(:user2) { create(:user) }
diff --git a/spec/finders/access_requests_finder_spec.rb b/spec/finders/access_requests_finder_spec.rb
index fbfc8035bcc..f4fda1f3dd2 100644
--- a/spec/finders/access_requests_finder_spec.rb
+++ b/spec/finders/access_requests_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe AccessRequestsFinder do
+RSpec.describe AccessRequestsFinder do
let(:user) { create(:user) }
let(:access_requester) { create(:user) }
diff --git a/spec/finders/admin/projects_finder_spec.rb b/spec/finders/admin/projects_finder_spec.rb
index eb5d0bba183..03eb41ddfb6 100644
--- a/spec/finders/admin/projects_finder_spec.rb
+++ b/spec/finders/admin/projects_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::ProjectsFinder do
+RSpec.describe Admin::ProjectsFinder do
describe '#execute' do
let(:user) { create(:user) }
let(:group) { create(:group, :public) }
diff --git a/spec/finders/admin/runners_finder_spec.rb b/spec/finders/admin/runners_finder_spec.rb
deleted file mode 100644
index 94ccb398801..00000000000
--- a/spec/finders/admin/runners_finder_spec.rb
+++ /dev/null
@@ -1,81 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe Admin::RunnersFinder do
- describe '#execute' do
- context 'with empty params' do
- it 'returns all runners' do
- runner1 = create :ci_runner, active: true
- runner2 = create :ci_runner, active: false
-
- expect(described_class.new(params: {}).execute).to match_array [runner1, runner2]
- end
- end
-
- context 'filter by search term' do
- it 'calls Ci::Runner.search' do
- expect(Ci::Runner).to receive(:search).with('term').and_call_original
-
- described_class.new(params: { search: 'term' }).execute
- end
- end
-
- context 'filter by status' do
- it 'calls the corresponding scope on Ci::Runner' do
- expect(Ci::Runner).to receive(:paused).and_call_original
-
- described_class.new(params: { status_status: 'paused' }).execute
- end
- end
-
- context 'filter by runner type' do
- it 'calls the corresponding scope on Ci::Runner' do
- expect(Ci::Runner).to receive(:project_type).and_call_original
-
- described_class.new(params: { type_type: 'project_type' }).execute
- end
- end
-
- context 'filter by tag_name' do
- it 'calls the corresponding scope on Ci::Runner' do
- expect(Ci::Runner).to receive(:tagged_with).with(%w[tag1 tag2]).and_call_original
-
- described_class.new(params: { tag_name: %w[tag1 tag2] }).execute
- end
- end
-
- context 'sort' do
- context 'without sort param' do
- it 'sorts by created_at' do
- runner1 = create :ci_runner, created_at: '2018-07-12 07:00'
- runner2 = create :ci_runner, created_at: '2018-07-12 08:00'
- runner3 = create :ci_runner, created_at: '2018-07-12 09:00'
-
- expect(described_class.new(params: {}).execute).to eq [runner3, runner2, runner1]
- end
- end
-
- context 'with sort param' do
- it 'sorts by specified attribute' do
- runner1 = create :ci_runner, contacted_at: 1.minute.ago
- runner2 = create :ci_runner, contacted_at: 3.minutes.ago
- runner3 = create :ci_runner, contacted_at: 2.minutes.ago
-
- expect(described_class.new(params: { sort: 'contacted_asc' }).execute).to eq [runner2, runner3, runner1]
- end
- end
- end
-
- context 'paginate' do
- it 'returns the runners for the specified page' do
- stub_const('Admin::RunnersFinder::NUMBER_OF_RUNNERS_PER_PAGE', 1)
- runner1 = create :ci_runner, created_at: '2018-07-12 07:00'
- runner2 = create :ci_runner, created_at: '2018-07-12 08:00'
-
- expect(described_class.new(params: { page: 1 }).execute).to eq [runner2]
- expect(described_class.new(params: { page: 2 }).execute).to eq [runner1]
- end
- end
- end
-end
diff --git a/spec/finders/alert_management/alerts_finder_spec.rb b/spec/finders/alert_management/alerts_finder_spec.rb
index c6d2d0ad4ef..5920d579ba6 100644
--- a/spec/finders/alert_management/alerts_finder_spec.rb
+++ b/spec/finders/alert_management/alerts_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe AlertManagement::AlertsFinder, '#execute' do
+RSpec.describe AlertManagement::AlertsFinder, '#execute' do
let_it_be(:current_user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:alert_1) { create(:alert_management_alert, :all_fields, :resolved, project: project, ended_at: 1.year.ago, events: 2, severity: :high) }
@@ -100,13 +100,13 @@ describe AlertManagement::AlertsFinder, '#execute' do
context 'when sorting by start time' do
context 'sorts alerts ascending' do
- let(:params) { { sort: 'start_time_asc' } }
+ let(:params) { { sort: 'started_at_asc' } }
it { is_expected.to eq [alert_1, alert_2] }
end
context 'sorts alerts descending' do
- let(:params) { { sort: 'start_time_desc' } }
+ let(:params) { { sort: 'started_at_desc' } }
it { is_expected.to eq [alert_2, alert_1] }
end
@@ -114,13 +114,13 @@ describe AlertManagement::AlertsFinder, '#execute' do
context 'when sorting by end time' do
context 'sorts alerts ascending' do
- let(:params) { { sort: 'end_time_asc' } }
+ let(:params) { { sort: 'ended_at_asc' } }
it { is_expected.to eq [alert_1, alert_2] }
end
context 'sorts alerts descending' do
- let(:params) { { sort: 'end_time_desc' } }
+ let(:params) { { sort: 'ended_at_desc' } }
it { is_expected.to eq [alert_2, alert_1] }
end
@@ -131,13 +131,13 @@ describe AlertManagement::AlertsFinder, '#execute' do
let_it_be(:alert_count_3) { create(:alert_management_alert, project: project, events: 3) }
context 'sorts alerts ascending' do
- let(:params) { { sort: 'events_count_asc' } }
+ let(:params) { { sort: 'event_count_asc' } }
it { is_expected.to eq [alert_2, alert_1, alert_count_3, alert_count_6] }
end
context 'sorts alerts descending' do
- let(:params) { { sort: 'events_count_desc' } }
+ let(:params) { { sort: 'event_count_desc' } }
it { is_expected.to eq [alert_count_6, alert_count_3, alert_1, alert_2] }
end
diff --git a/spec/finders/applications_finder_spec.rb b/spec/finders/applications_finder_spec.rb
index 14d6b35cc27..dc615144b88 100644
--- a/spec/finders/applications_finder_spec.rb
+++ b/spec/finders/applications_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ApplicationsFinder do
+RSpec.describe ApplicationsFinder do
let(:application1) { create(:application, name: 'some_application', owner: nil, redirect_uri: 'http://some_application.url', scopes: '') }
let(:application2) { create(:application, name: 'another_application', owner: nil, redirect_uri: 'http://other_application.url', scopes: '') }
diff --git a/spec/finders/autocomplete/acts_as_taggable_on/tags_finder_spec.rb b/spec/finders/autocomplete/acts_as_taggable_on/tags_finder_spec.rb
index c4e6c9cc9f5..9e91de32d0b 100644
--- a/spec/finders/autocomplete/acts_as_taggable_on/tags_finder_spec.rb
+++ b/spec/finders/autocomplete/acts_as_taggable_on/tags_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Autocomplete::ActsAsTaggableOn::TagsFinder do
+RSpec.describe Autocomplete::ActsAsTaggableOn::TagsFinder do
describe '#execute' do
context 'with empty params' do
it 'returns all tags' do
diff --git a/spec/finders/autocomplete/group_finder_spec.rb b/spec/finders/autocomplete/group_finder_spec.rb
index d7cb2c3bbe2..8cbb8cdbee8 100644
--- a/spec/finders/autocomplete/group_finder_spec.rb
+++ b/spec/finders/autocomplete/group_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Autocomplete::GroupFinder do
+RSpec.describe Autocomplete::GroupFinder do
let(:user) { create(:user) }
describe '#execute' do
diff --git a/spec/finders/autocomplete/move_to_project_finder_spec.rb b/spec/finders/autocomplete/move_to_project_finder_spec.rb
index f2da82bb9be..61328a5335a 100644
--- a/spec/finders/autocomplete/move_to_project_finder_spec.rb
+++ b/spec/finders/autocomplete/move_to_project_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Autocomplete::MoveToProjectFinder do
+RSpec.describe Autocomplete::MoveToProjectFinder do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
diff --git a/spec/finders/autocomplete/project_finder_spec.rb b/spec/finders/autocomplete/project_finder_spec.rb
index 207d0598c28..0c9b4989ed1 100644
--- a/spec/finders/autocomplete/project_finder_spec.rb
+++ b/spec/finders/autocomplete/project_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Autocomplete::ProjectFinder do
+RSpec.describe Autocomplete::ProjectFinder do
let(:user) { create(:user) }
describe '#execute' do
diff --git a/spec/finders/autocomplete/users_finder_spec.rb b/spec/finders/autocomplete/users_finder_spec.rb
index 5d340c46114..357b6dfcea2 100644
--- a/spec/finders/autocomplete/users_finder_spec.rb
+++ b/spec/finders/autocomplete/users_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Autocomplete::UsersFinder do
+RSpec.describe Autocomplete::UsersFinder do
describe '#execute' do
let!(:user1) { create(:user, username: 'johndoe') }
let!(:user2) { create(:user, :blocked, username: 'notsorandom') }
diff --git a/spec/finders/award_emojis_finder_spec.rb b/spec/finders/award_emojis_finder_spec.rb
index 975722e780b..7a75ad716d0 100644
--- a/spec/finders/award_emojis_finder_spec.rb
+++ b/spec/finders/award_emojis_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe AwardEmojisFinder do
+RSpec.describe AwardEmojisFinder do
let_it_be(:issue_1) { create(:issue) }
let_it_be(:issue_1_thumbsup) { create(:award_emoji, name: 'thumbsup', awardable: issue_1) }
let_it_be(:issue_1_thumbsdown) { create(:award_emoji, name: 'thumbsdown', awardable: issue_1) }
diff --git a/spec/finders/boards/visits_finder_spec.rb b/spec/finders/boards/visits_finder_spec.rb
index 7e3ad8aa9f0..3811c99cc59 100644
--- a/spec/finders/boards/visits_finder_spec.rb
+++ b/spec/finders/boards/visits_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Boards::VisitsFinder do
+RSpec.describe Boards::VisitsFinder do
describe '#latest' do
let(:user) { create(:user) }
diff --git a/spec/finders/branches_finder_spec.rb b/spec/finders/branches_finder_spec.rb
index 5f75ff8c6ff..2e52093342d 100644
--- a/spec/finders/branches_finder_spec.rb
+++ b/spec/finders/branches_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe BranchesFinder do
+RSpec.describe BranchesFinder do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:repository) { project.repository }
diff --git a/spec/finders/ci/daily_build_group_report_results_finder_spec.rb b/spec/finders/ci/daily_build_group_report_results_finder_spec.rb
index 3000ef650d3..bdb0bc9b561 100644
--- a/spec/finders/ci/daily_build_group_report_results_finder_spec.rb
+++ b/spec/finders/ci/daily_build_group_report_results_finder_spec.rb
@@ -2,23 +2,12 @@
require 'spec_helper'
-describe Ci::DailyBuildGroupReportResultsFinder do
+RSpec.describe Ci::DailyBuildGroupReportResultsFinder do
describe '#execute' do
let(:project) { create(:project, :private) }
let(:ref_path) { 'refs/heads/master' }
let(:limit) { nil }
- def create_daily_coverage(group_name, coverage, date)
- create(
- :ci_daily_build_group_report_result,
- project: project,
- ref_path: ref_path,
- group_name: group_name,
- data: { 'coverage' => coverage },
- date: date
- )
- end
-
let!(:rspec_coverage_1) { create_daily_coverage('rspec', 79.0, '2020-03-09') }
let!(:karma_coverage_1) { create_daily_coverage('karma', 89.0, '2020-03-09') }
let!(:rspec_coverage_2) { create_daily_coverage('rspec', 95.0, '2020-03-10') }
@@ -37,7 +26,7 @@ describe Ci::DailyBuildGroupReportResultsFinder do
).execute
end
- context 'when current user is allowed to download project code' do
+ context 'when current user is allowed to read build report results' do
let(:current_user) { project.owner }
it 'returns all matching results within the given date range' do
@@ -61,7 +50,7 @@ describe Ci::DailyBuildGroupReportResultsFinder do
end
end
- context 'when current user is not allowed to download project code' do
+ context 'when current user is not allowed to read build report results' do
let(:current_user) { create(:user) }
it 'returns an empty result' do
@@ -69,4 +58,15 @@ describe Ci::DailyBuildGroupReportResultsFinder do
end
end
end
+
+ def create_daily_coverage(group_name, coverage, date)
+ create(
+ :ci_daily_build_group_report_result,
+ project: project,
+ ref_path: ref_path,
+ group_name: group_name,
+ data: { 'coverage' => coverage },
+ date: date
+ )
+ end
end
diff --git a/spec/finders/ci/job_artifacts_finder_spec.rb b/spec/finders/ci/job_artifacts_finder_spec.rb
index 3e701ba87fa..74875ab8b06 100644
--- a/spec/finders/ci/job_artifacts_finder_spec.rb
+++ b/spec/finders/ci/job_artifacts_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::JobArtifactsFinder do
+RSpec.describe Ci::JobArtifactsFinder do
let(:project) { create(:project) }
describe '#execute' do
diff --git a/spec/finders/ci/jobs_finder_spec.rb b/spec/finders/ci/jobs_finder_spec.rb
index 7083e8fbf43..e6680afa15c 100644
--- a/spec/finders/ci/jobs_finder_spec.rb
+++ b/spec/finders/ci/jobs_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::JobsFinder, '#execute' do
+RSpec.describe Ci::JobsFinder, '#execute' do
let_it_be(:user) { create(:user) }
let_it_be(:admin) { create(:user, :admin) }
let_it_be(:project) { create(:project, :private, public_builds: false) }
diff --git a/spec/finders/ci/pipeline_schedules_finder_spec.rb b/spec/finders/ci/pipeline_schedules_finder_spec.rb
index 5b5154ce834..57842bbecd7 100644
--- a/spec/finders/ci/pipeline_schedules_finder_spec.rb
+++ b/spec/finders/ci/pipeline_schedules_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::PipelineSchedulesFinder do
+RSpec.describe Ci::PipelineSchedulesFinder do
let(:project) { create(:project) }
let!(:active_schedule) { create(:ci_pipeline_schedule, project: project) }
diff --git a/spec/finders/ci/pipelines_finder_spec.rb b/spec/finders/ci/pipelines_finder_spec.rb
index 6528093731e..680955ff9f9 100644
--- a/spec/finders/ci/pipelines_finder_spec.rb
+++ b/spec/finders/ci/pipelines_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::PipelinesFinder do
+RSpec.describe Ci::PipelinesFinder do
let(:project) { create(:project, :public, :repository) }
let(:current_user) { nil }
let(:params) { {} }
diff --git a/spec/finders/ci/pipelines_for_merge_request_finder_spec.rb b/spec/finders/ci/pipelines_for_merge_request_finder_spec.rb
index c49ac487519..543c289d366 100644
--- a/spec/finders/ci/pipelines_for_merge_request_finder_spec.rb
+++ b/spec/finders/ci/pipelines_for_merge_request_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::PipelinesForMergeRequestFinder do
+RSpec.describe Ci::PipelinesForMergeRequestFinder do
describe '#all' do
let(:merge_request) { create(:merge_request) }
let(:project) { merge_request.source_project }
diff --git a/spec/finders/ci/runner_jobs_finder_spec.rb b/spec/finders/ci/runner_jobs_finder_spec.rb
index a3245119291..7c9f762c000 100644
--- a/spec/finders/ci/runner_jobs_finder_spec.rb
+++ b/spec/finders/ci/runner_jobs_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::RunnerJobsFinder do
+RSpec.describe Ci::RunnerJobsFinder do
let(:project) { create(:project) }
let(:runner) { create(:ci_runner, :instance) }
diff --git a/spec/finders/ci/runners_finder_spec.rb b/spec/finders/ci/runners_finder_spec.rb
new file mode 100644
index 00000000000..d4795d786bc
--- /dev/null
+++ b/spec/finders/ci/runners_finder_spec.rb
@@ -0,0 +1,304 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::RunnersFinder do
+ context 'admin' do
+ let_it_be(:admin) { create(:user, :admin) }
+
+ describe '#execute' do
+ context 'with empty params' do
+ it 'returns all runners' do
+ runner1 = create :ci_runner, active: true
+ runner2 = create :ci_runner, active: false
+
+ expect(described_class.new(current_user: admin, params: {}).execute).to match_array [runner1, runner2]
+ end
+ end
+
+ context 'filter by search term' do
+ it 'calls Ci::Runner.search' do
+ expect(Ci::Runner).to receive(:search).with('term').and_call_original
+
+ described_class.new(current_user: admin, params: { search: 'term' }).execute
+ end
+ end
+
+ context 'filter by status' do
+ it 'calls the corresponding scope on Ci::Runner' do
+ expect(Ci::Runner).to receive(:paused).and_call_original
+
+ described_class.new(current_user: admin, params: { status_status: 'paused' }).execute
+ end
+ end
+
+ context 'filter by runner type' do
+ it 'calls the corresponding scope on Ci::Runner' do
+ expect(Ci::Runner).to receive(:project_type).and_call_original
+
+ described_class.new(current_user: admin, params: { type_type: 'project_type' }).execute
+ end
+ end
+
+ context 'filter by tag_name' do
+ it 'calls the corresponding scope on Ci::Runner' do
+ expect(Ci::Runner).to receive(:tagged_with).with(%w[tag1 tag2]).and_call_original
+
+ described_class.new(current_user: admin, params: { tag_name: %w[tag1 tag2] }).execute
+ end
+ end
+
+ context 'sort' do
+ context 'without sort param' do
+ it 'sorts by created_at' do
+ runner1 = create :ci_runner, created_at: '2018-07-12 07:00'
+ runner2 = create :ci_runner, created_at: '2018-07-12 08:00'
+ runner3 = create :ci_runner, created_at: '2018-07-12 09:00'
+
+ expect(described_class.new(current_user: admin, params: {}).execute).to eq [runner3, runner2, runner1]
+ end
+ end
+
+ context 'with sort param' do
+ it 'sorts by specified attribute' do
+ runner1 = create :ci_runner, contacted_at: 1.minute.ago
+ runner2 = create :ci_runner, contacted_at: 3.minutes.ago
+ runner3 = create :ci_runner, contacted_at: 2.minutes.ago
+
+ expect(described_class.new(current_user: admin, params: { sort: 'contacted_asc' }).execute).to eq [runner2, runner3, runner1]
+ end
+ end
+ end
+
+ context 'paginate' do
+ it 'returns the runners for the specified page' do
+ stub_const('Ci::RunnersFinder::NUMBER_OF_RUNNERS_PER_PAGE', 1)
+ runner1 = create :ci_runner, created_at: '2018-07-12 07:00'
+ runner2 = create :ci_runner, created_at: '2018-07-12 08:00'
+
+ expect(described_class.new(current_user: admin, params: { page: 1 }).execute).to eq [runner2]
+ expect(described_class.new(current_user: admin, params: { page: 2 }).execute).to eq [runner1]
+ end
+ end
+
+ context 'non admin user' do
+ it 'returns no runners' do
+ user = create :user
+ create :ci_runner, active: true
+ create :ci_runner, active: false
+
+ expect(described_class.new(current_user: user, params: {}).execute).to be_empty
+ end
+ end
+
+ context 'user is nil' do
+ it 'returns no runners' do
+ user = nil
+ create :ci_runner, active: true
+ create :ci_runner, active: false
+
+ expect(described_class.new(current_user: user, params: {}).execute).to be_empty
+ end
+ end
+ end
+ end
+
+ context 'group' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:sub_group_1) { create(:group, parent: group) }
+ let_it_be(:sub_group_2) { create(:group, parent: group) }
+ let_it_be(:sub_group_3) { create(:group, parent: sub_group_1) }
+ let_it_be(:sub_group_4) { create(:group, parent: sub_group_3) }
+ let_it_be(:project) { create(:project, group: group) }
+ let_it_be(:project_2) { create(:project, group: 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_group_3) }
+ let_it_be(:project_6) { create(:project, group: sub_group_4) }
+ 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) }
+ let_it_be(:runner_sub_group_3) { create(:ci_runner, :group, contacted_at: 9.minutes.ago) }
+ let_it_be(:runner_sub_group_4) { create(:ci_runner, :group, contacted_at: 8.minutes.ago) }
+ let_it_be(:runner_project_1) { create(:ci_runner, :project, contacted_at: 7.minutes.ago, projects: [project])}
+ let_it_be(:runner_project_2) { create(:ci_runner, :project, contacted_at: 6.minutes.ago, projects: [project_2])}
+ let_it_be(:runner_project_3) { create(:ci_runner, :project, contacted_at: 5.minutes.ago, description: 'runner_project_search', projects: [project, project_2])}
+ let_it_be(:runner_project_4) { create(:ci_runner, :project, contacted_at: 4.minutes.ago, projects: [project_3])}
+ let_it_be(:runner_project_5) { create(:ci_runner, :project, contacted_at: 3.minutes.ago, tag_list: %w[runner_tag], projects: [project_4])}
+ 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) { {} }
+
+ before do
+ group.runners << runner_group
+ sub_group_1.runners << runner_sub_group_1
+ sub_group_2.runners << runner_sub_group_2
+ sub_group_3.runners << runner_sub_group_3
+ sub_group_4.runners << runner_sub_group_4
+ end
+
+ describe '#execute' do
+ subject { described_class.new(current_user: user, group: group, params: params).execute }
+
+ context 'no params' do
+ before do
+ group.add_owner(user)
+ end
+
+ it 'returns all 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 sort param' do
+ let(:params) { { sort: 'contacted_asc' } }
+
+ before do
+ group.add_owner(user)
+ end
+
+ 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 'paginate' do
+ using RSpec::Parameterized::TableSyntax
+
+ let(:runners) do
+ [[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
+
+ where(:page, :index) do
+ 1 | 0
+ 2 | 1
+ 3 | 2
+ 4 | 3
+ end
+
+ before do
+ stub_const('Ci::RunnersFinder::NUMBER_OF_RUNNERS_PER_PAGE', 3)
+
+ group.add_owner(user)
+ end
+
+ with_them do
+ let(:params) { { page: page } }
+
+ it 'returns the runners for the specified page' do
+ expect(subject).to eq(runners[index])
+ end
+ end
+ end
+
+ context 'filter by search term' do
+ let(:params) { { search: 'runner_project_search' } }
+
+ before do
+ group.add_owner(user)
+ end
+
+ it 'returns correct runner' do
+ expect(subject).to eq([runner_project_3])
+ end
+ end
+
+ context 'filter by status' do
+ let(:params) { { status_status: 'paused' } }
+
+ before do
+ group.add_owner(user)
+ end
+
+ it 'returns correct runner' do
+ expect(subject).to eq([runner_sub_group_1])
+ end
+ end
+
+ context 'filter by tag_name' do
+ let(:params) { { tag_name: %w[runner_tag] } }
+
+ before do
+ group.add_owner(user)
+ end
+
+ it 'returns correct runner' do
+ expect(subject).to eq([runner_project_5])
+ end
+ end
+
+ context 'filter by runner type' do
+ let(:params) { { type_type: 'project_type' } }
+
+ before do
+ group.add_owner(user)
+ end
+
+ 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
+
+ context 'user has no access to runners' do
+ where(:user_permission) do
+ [:maintainer, :developer, :reporter, :guest]
+ end
+
+ with_them do
+ before do
+ create(:group_member, user_permission, group: group, user: user)
+ end
+
+ it 'returns no runners' do
+ expect(subject).to be_empty
+ end
+ end
+ end
+
+ context 'user with no access' do
+ it 'returns no runners' do
+ expect(subject).to be_empty
+ end
+ end
+
+ context 'user is nil' do
+ let_it_be(:user) { nil }
+
+ it 'returns no runners' do
+ expect(subject).to be_empty
+ end
+ end
+ end
+
+ describe '#sort_key' do
+ subject { described_class.new(current_user: user, group: group, params: params).sort_key }
+
+ context 'no params' do
+ it 'returns created_date' do
+ expect(subject).to eq('created_date')
+ end
+ end
+
+ context 'with params' do
+ let(:params) { { sort: 'contacted_asc' } }
+
+ it 'returns contacted_asc' do
+ expect(subject).to eq('contacted_asc')
+ end
+ end
+ end
+ end
+end
diff --git a/spec/finders/cluster_ancestors_finder_spec.rb b/spec/finders/cluster_ancestors_finder_spec.rb
index 4aedb41d446..ea1dbea4cfe 100644
--- a/spec/finders/cluster_ancestors_finder_spec.rb
+++ b/spec/finders/cluster_ancestors_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ClusterAncestorsFinder, '#execute' do
+RSpec.describe ClusterAncestorsFinder, '#execute' do
let(:group) { create(:group) }
let(:project) { create(:project, group: group) }
let(:user) { create(:user) }
diff --git a/spec/finders/clusters/knative_services_finder_spec.rb b/spec/finders/clusters/knative_services_finder_spec.rb
index 57dbead7921..c61fac27bd9 100644
--- a/spec/finders/clusters/knative_services_finder_spec.rb
+++ b/spec/finders/clusters/knative_services_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::KnativeServicesFinder do
+RSpec.describe Clusters::KnativeServicesFinder do
include KubernetesHelpers
include ReactiveCachingHelpers
diff --git a/spec/finders/clusters_finder_spec.rb b/spec/finders/clusters_finder_spec.rb
index 3bad88573f7..fc6616f4a28 100644
--- a/spec/finders/clusters_finder_spec.rb
+++ b/spec/finders/clusters_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ClustersFinder do
+RSpec.describe ClustersFinder do
let(:project) { create(:project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/finders/concerns/finder_methods_spec.rb b/spec/finders/concerns/finder_methods_spec.rb
index 2e44df8b044..3e299c93eda 100644
--- a/spec/finders/concerns/finder_methods_spec.rb
+++ b/spec/finders/concerns/finder_methods_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe FinderMethods do
+RSpec.describe FinderMethods do
let(:finder_class) do
Class.new do
include FinderMethods
diff --git a/spec/finders/concerns/finder_with_cross_project_access_spec.rb b/spec/finders/concerns/finder_with_cross_project_access_spec.rb
index d11d4da25a8..116b523bd99 100644
--- a/spec/finders/concerns/finder_with_cross_project_access_spec.rb
+++ b/spec/finders/concerns/finder_with_cross_project_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe FinderWithCrossProjectAccess do
+RSpec.describe FinderWithCrossProjectAccess do
let(:finder_class) do
Class.new do
prepend FinderWithCrossProjectAccess
diff --git a/spec/finders/container_repositories_finder_spec.rb b/spec/finders/container_repositories_finder_spec.rb
index d0c91a8f734..b6305e3f5b7 100644
--- a/spec/finders/container_repositories_finder_spec.rb
+++ b/spec/finders/container_repositories_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ContainerRepositoriesFinder do
+RSpec.describe ContainerRepositoriesFinder do
let_it_be(:reporter) { create(:user) }
let_it_be(:guest) { create(:user) }
diff --git a/spec/finders/context_commits_finder_spec.rb b/spec/finders/context_commits_finder_spec.rb
index 13cfa32ecfc..95c685aea24 100644
--- a/spec/finders/context_commits_finder_spec.rb
+++ b/spec/finders/context_commits_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ContextCommitsFinder do
+RSpec.describe ContextCommitsFinder do
describe "#execute" do
let(:project) { create(:project, :repository) }
let(:merge_request) { create(:merge_request) }
diff --git a/spec/finders/contributed_projects_finder_spec.rb b/spec/finders/contributed_projects_finder_spec.rb
index 1d907261fe9..86d3e7f8f19 100644
--- a/spec/finders/contributed_projects_finder_spec.rb
+++ b/spec/finders/contributed_projects_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ContributedProjectsFinder do
+RSpec.describe ContributedProjectsFinder do
let(:source_user) { create(:user) }
let(:current_user) { create(:user) }
diff --git a/spec/finders/deployments_finder_spec.rb b/spec/finders/deployments_finder_spec.rb
index b20c7e5a8a5..e4e0f366eeb 100644
--- a/spec/finders/deployments_finder_spec.rb
+++ b/spec/finders/deployments_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe DeploymentsFinder do
+RSpec.describe DeploymentsFinder do
subject { described_class.new(project, params).execute }
let(:project) { create(:project, :public, :test_repo) }
diff --git a/spec/finders/design_management/designs_finder_spec.rb b/spec/finders/design_management/designs_finder_spec.rb
index 04bd0ad0a45..696327cc49c 100644
--- a/spec/finders/design_management/designs_finder_spec.rb
+++ b/spec/finders/design_management/designs_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe DesignManagement::DesignsFinder do
+RSpec.describe DesignManagement::DesignsFinder do
include DesignManagementTestHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/finders/design_management/versions_finder_spec.rb b/spec/finders/design_management/versions_finder_spec.rb
index 11d53d0d630..6a56ccb10b8 100644
--- a/spec/finders/design_management/versions_finder_spec.rb
+++ b/spec/finders/design_management/versions_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe DesignManagement::VersionsFinder do
+RSpec.describe DesignManagement::VersionsFinder do
include DesignManagementTestHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/finders/environments_finder_spec.rb b/spec/finders/environments_finder_spec.rb
index 66e404f5236..fd714ab9a8f 100644
--- a/spec/finders/environments_finder_spec.rb
+++ b/spec/finders/environments_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe EnvironmentsFinder do
+RSpec.describe EnvironmentsFinder do
let(:project) { create(:project, :repository) }
let(:user) { project.creator }
let(:environment) { create(:environment, :available, project: project) }
diff --git a/spec/finders/events_finder_spec.rb b/spec/finders/events_finder_spec.rb
index 443e9ab4bc4..45a049f9442 100644
--- a/spec/finders/events_finder_spec.rb
+++ b/spec/finders/events_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe EventsFinder do
+RSpec.describe EventsFinder do
let_it_be(:user) { create(:user) }
let(:other_user) { create(:user) }
@@ -11,18 +11,18 @@ describe EventsFinder do
let(:closed_issue) { create(:closed_issue, project: project1, author: user) }
let(:opened_merge_request) { create(:merge_request, source_project: project2, author: user) }
- let!(:closed_issue_event) { create(:event, project: project1, author: user, target: closed_issue, action: Event::CLOSED, created_at: Date.new(2016, 12, 30)) }
- let!(:opened_merge_request_event) { create(:event, project: project2, author: user, target: opened_merge_request, action: Event::CREATED, created_at: Date.new(2017, 1, 31)) }
+ let!(:closed_issue_event) { create(:event, :closed, project: project1, author: user, target: closed_issue, created_at: Date.new(2016, 12, 30)) }
+ let!(:opened_merge_request_event) { create(:event, :created, project: project2, author: user, target: opened_merge_request, created_at: Date.new(2017, 1, 31)) }
let(:closed_issue2) { create(:closed_issue, project: project1, author: user) }
let(:opened_merge_request2) { create(:merge_request, source_project: project2, author: user) }
- let!(:closed_issue_event2) { create(:event, project: project1, author: user, target: closed_issue, action: Event::CLOSED, created_at: Date.new(2016, 2, 2)) }
- let!(:opened_merge_request_event2) { create(:event, project: project2, author: user, target: opened_merge_request, action: Event::CREATED, created_at: Date.new(2017, 2, 2)) }
+ let!(:closed_issue_event2) { create(:event, :closed, project: project1, author: user, target: closed_issue, created_at: Date.new(2016, 2, 2)) }
+ let!(:opened_merge_request_event2) { create(:event, :created, project: project2, author: user, target: opened_merge_request, created_at: Date.new(2017, 2, 2)) }
let(:opened_merge_request3) { create(:merge_request, source_project: project1, author: other_user) }
- let!(:other_developer_event) { create(:event, project: project1, author: other_user, target: opened_merge_request3, action: Event::CREATED) }
+ let!(:other_developer_event) { create(:event, :created, project: project1, author: other_user, target: opened_merge_request3 ) }
let_it_be(:public_project) { create(:project, :public, creator_id: user.id, namespace: user.namespace) }
let(:confidential_issue) { create(:closed_issue, confidential: true, project: public_project, author: user) }
- let!(:confidential_event) { create(:event, project: public_project, author: user, target: confidential_issue, action: Event::CLOSED) }
+ let!(:confidential_event) { create(:event, :closed, project: public_project, author: user, target: confidential_issue) }
context 'when targeting a user' do
it 'returns events between specified dates filtered on action and type' do
diff --git a/spec/finders/fork_projects_finder_spec.rb b/spec/finders/fork_projects_finder_spec.rb
index 02ce17ac907..9e58378b953 100644
--- a/spec/finders/fork_projects_finder_spec.rb
+++ b/spec/finders/fork_projects_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ForkProjectsFinder do
+RSpec.describe ForkProjectsFinder do
include ProjectForksHelper
let(:source_project) { create(:project, :public, :empty_repo) }
diff --git a/spec/finders/fork_targets_finder_spec.rb b/spec/finders/fork_targets_finder_spec.rb
index f8c03cdf9b3..3c66f4e5757 100644
--- a/spec/finders/fork_targets_finder_spec.rb
+++ b/spec/finders/fork_targets_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ForkTargetsFinder do
+RSpec.describe ForkTargetsFinder do
subject(:finder) { described_class.new(project, user) }
let(:project) { create(:project, namespace: create(:group)) }
diff --git a/spec/finders/freeze_periods_finder_spec.rb b/spec/finders/freeze_periods_finder_spec.rb
index 4ff356b85b7..53cc07d91b0 100644
--- a/spec/finders/freeze_periods_finder_spec.rb
+++ b/spec/finders/freeze_periods_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe FreezePeriodsFinder do
+RSpec.describe FreezePeriodsFinder do
subject(:finder) { described_class.new(project, user).execute }
let(:project) { create(:project, :private) }
diff --git a/spec/finders/group_descendants_finder_spec.rb b/spec/finders/group_descendants_finder_spec.rb
index a08772c6e7e..77ef546e083 100644
--- a/spec/finders/group_descendants_finder_spec.rb
+++ b/spec/finders/group_descendants_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe GroupDescendantsFinder do
+RSpec.describe GroupDescendantsFinder do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:params) { {} }
diff --git a/spec/finders/group_labels_finder_spec.rb b/spec/finders/group_labels_finder_spec.rb
index 7bdd312eff0..d65a8fb4fed 100644
--- a/spec/finders/group_labels_finder_spec.rb
+++ b/spec/finders/group_labels_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe GroupLabelsFinder, '#execute' do
+RSpec.describe GroupLabelsFinder, '#execute' do
let!(:group) { create(:group) }
let!(:user) { create(:user) }
let!(:label1) { create(:group_label, title: 'Foo', description: 'Lorem ipsum', group: group) }
diff --git a/spec/finders/group_members_finder_spec.rb b/spec/finders/group_members_finder_spec.rb
index d1d97f6f9f0..68b120db227 100644
--- a/spec/finders/group_members_finder_spec.rb
+++ b/spec/finders/group_members_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe GroupMembersFinder, '#execute' do
+RSpec.describe GroupMembersFinder, '#execute' do
let(:group) { create(:group) }
let(:nested_group) { create(:group, parent: group) }
let(:deeper_nested_group) { create(:group, parent: nested_group) }
diff --git a/spec/finders/group_projects_finder_spec.rb b/spec/finders/group_projects_finder_spec.rb
index 89fc1e380dc..7499461ad8f 100644
--- a/spec/finders/group_projects_finder_spec.rb
+++ b/spec/finders/group_projects_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe GroupProjectsFinder do
+RSpec.describe GroupProjectsFinder do
include_context 'GroupProjectsFinder context'
subject { finder.execute }
diff --git a/spec/finders/groups_finder_spec.rb b/spec/finders/groups_finder_spec.rb
index 939b818f165..78764f79a6c 100644
--- a/spec/finders/groups_finder_spec.rb
+++ b/spec/finders/groups_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe GroupsFinder do
+RSpec.describe GroupsFinder do
describe '#execute' do
let(:user) { create(:user) }
@@ -74,6 +74,12 @@ describe GroupsFinder do
let!(:internal_subgroup) { create(:group, :internal, parent: parent_group) }
let!(:private_subgroup) { create(:group, :private, parent: parent_group) }
+ context 'with [nil] parent' do
+ it 'returns only top-level groups' do
+ expect(described_class.new(user, parent: [nil]).execute).to contain_exactly(parent_group)
+ end
+ end
+
context 'without a user' do
it 'only returns parent and public subgroups' do
expect(described_class.new(nil).execute).to contain_exactly(parent_group, public_subgroup)
diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb
index 7493fafb5cc..672318c292e 100644
--- a/spec/finders/issues_finder_spec.rb
+++ b/spec/finders/issues_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe IssuesFinder do
+RSpec.describe IssuesFinder do
include_context 'IssuesFinder context'
describe '#execute' do
diff --git a/spec/finders/joined_groups_finder_spec.rb b/spec/finders/joined_groups_finder_spec.rb
index b01bd44470a..8f826ef67ec 100644
--- a/spec/finders/joined_groups_finder_spec.rb
+++ b/spec/finders/joined_groups_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe JoinedGroupsFinder do
+RSpec.describe JoinedGroupsFinder do
describe '#execute' do
let!(:profile_owner) { create(:user) }
let!(:profile_visitor) { create(:user) }
diff --git a/spec/finders/keys_finder_spec.rb b/spec/finders/keys_finder_spec.rb
index bae4a542484..277c852c953 100644
--- a/spec/finders/keys_finder_spec.rb
+++ b/spec/finders/keys_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe KeysFinder do
+RSpec.describe KeysFinder do
subject { described_class.new(params).execute }
let(:user) { create(:user) }
diff --git a/spec/finders/labels_finder_spec.rb b/spec/finders/labels_finder_spec.rb
index 7590c399cf9..851b9e64db6 100644
--- a/spec/finders/labels_finder_spec.rb
+++ b/spec/finders/labels_finder_spec.rb
@@ -2,37 +2,37 @@
require 'spec_helper'
-describe LabelsFinder do
+RSpec.describe LabelsFinder do
describe '#execute' do
- let(:group_1) { create(:group) }
- let(:group_2) { create(:group) }
- let(:group_3) { create(:group) }
- let(:private_group_1) { create(:group, :private) }
- let(:private_subgroup_1) { create(:group, :private, parent: private_group_1) }
-
- let(:project_1) { create(:project, namespace: group_1) }
- let(:project_2) { create(:project, namespace: group_2) }
- let(:project_3) { create(:project) }
- let(:project_4) { create(:project, :public) }
- let(:project_5) { create(:project, namespace: group_1) }
-
- let!(:project_label_1) { create(:label, project: project_1, title: 'Label 1', description: 'awesome label') }
- let!(:project_label_2) { create(:label, project: project_2, title: 'Label 2') }
- let!(:project_label_4) { create(:label, project: project_4, title: 'Label 4') }
- let!(:project_label_5) { create(:label, project: project_5, title: 'Label 5') }
-
- let!(:group_label_1) { create(:group_label, group: group_1, title: 'Label 1 (group)') }
- let!(:group_label_2) { create(:group_label, group: group_1, title: 'Group Label 2') }
- let!(:group_label_3) { create(:group_label, group: group_2, title: 'Group Label 3') }
- let!(:private_group_label_1) { create(:group_label, group: private_group_1, title: 'Private Group Label 1') }
- let!(:private_subgroup_label_1) { create(:group_label, group: private_subgroup_1, title: 'Private Sub Group Label 1') }
-
- let(:user) { create(:user) }
+ let_it_be(:group_1) { create(:group) }
+ let_it_be(:group_2) { create(:group) }
+ let_it_be(:group_3) { create(:group) }
+ let_it_be(:private_group_1) { create(:group, :private) }
+ let_it_be(:private_subgroup_1) { create(:group, :private, parent: private_group_1) }
+
+ let_it_be(:project_1, reload: true) { create(:project, namespace: group_1) }
+ let_it_be(:project_2) { create(:project, namespace: group_2) }
+ let_it_be(:project_3) { create(:project) }
+ let_it_be(:project_4) { create(:project, :public) }
+ let_it_be(:project_5) { create(:project, namespace: group_1) }
+
+ let_it_be(:project_label_1) { create(:label, project: project_1, title: 'Label 1', description: 'awesome label') }
+ let_it_be(:project_label_2) { create(:label, project: project_2, title: 'Label 2') }
+ let_it_be(:project_label_4) { create(:label, project: project_4, title: 'Label 4') }
+ let_it_be(:project_label_5) { create(:label, project: project_5, title: 'Label 5') }
+
+ let_it_be(:group_label_1) { create(:group_label, group: group_1, title: 'Label 1 (group)') }
+ let_it_be(:group_label_2) { create(:group_label, group: group_1, title: 'Group Label 2') }
+ let_it_be(:group_label_3) { create(:group_label, group: group_2, title: 'Group Label 3') }
+ let_it_be(:private_group_label_1) { create(:group_label, group: private_group_1, title: 'Private Group Label 1') }
+ let_it_be(:private_subgroup_label_1) { create(:group_label, group: private_subgroup_1, title: 'Private Sub Group Label 1') }
+
+ let_it_be(:unused_label) { create(:label, project: project_3, title: 'Label 3') }
+ let_it_be(:unused_group_label) { create(:group_label, group: group_3, title: 'Group Label 4') }
+
+ let_it_be(:user) { create(:user) }
before do
- create(:label, project: project_3, title: 'Label 3')
- create(:group_label, group: group_3, title: 'Group Label 4')
-
project_1.add_developer(user)
end
@@ -54,11 +54,11 @@ describe LabelsFinder do
end
end
- context 'filtering by group_id' do
+ shared_examples 'filtering by group' do
it 'returns labels available for any non-archived project within the group' do
group_1.add_developer(user)
::Projects::UpdateService.new(project_1, user, archived: true).execute
- finder = described_class.new(user, group_id: group_1.id)
+ finder = described_class.new(user, **group_params(group_1))
expect(finder.execute).to eq [group_label_2, group_label_1, project_label_5]
end
@@ -67,7 +67,7 @@ describe LabelsFinder do
it 'returns only group labels' do
group_1.add_developer(user)
- finder = described_class.new(user, group_id: group_1.id, only_group_labels: true)
+ finder = described_class.new(user, only_group_labels: true, **group_params(group_1))
expect(finder.execute).to eq [group_label_2, group_label_1]
end
@@ -84,7 +84,7 @@ describe LabelsFinder do
context 'when only group labels is false' do
it 'returns group labels' do
- finder = described_class.new(user, group_id: empty_group.id)
+ finder = described_class.new(user, **group_params(empty_group))
expect(finder.execute).to eq [empty_group_label_1, empty_group_label_2]
end
@@ -96,7 +96,7 @@ describe LabelsFinder do
private_group_1.add_developer(user)
private_subgroup_1.add_developer(user)
- finder = described_class.new(user, group_id: private_subgroup_1.id, only_group_labels: true, include_ancestor_groups: true)
+ finder = described_class.new(user, **group_params(private_subgroup_1), only_group_labels: true, include_ancestor_groups: true)
expect(finder.execute).to eq [private_group_label_1, private_subgroup_label_1]
end
@@ -104,7 +104,7 @@ describe LabelsFinder do
it 'ignores labels from groups which user can not read' do
private_subgroup_1.add_developer(user)
- finder = described_class.new(user, group_id: private_subgroup_1.id, only_group_labels: true, include_ancestor_groups: true)
+ finder = described_class.new(user, **group_params(private_subgroup_1), only_group_labels: true, include_ancestor_groups: true)
expect(finder.execute).to eq [private_subgroup_label_1]
end
@@ -115,7 +115,7 @@ describe LabelsFinder do
private_group_1.add_developer(user)
private_subgroup_1.add_developer(user)
- finder = described_class.new(user, group_id: private_group_1.id, only_group_labels: true, include_descendant_groups: true)
+ finder = described_class.new(user, **group_params(private_group_1), only_group_labels: true, include_descendant_groups: true)
expect(finder.execute).to eq [private_group_label_1, private_subgroup_label_1]
end
@@ -123,14 +123,14 @@ describe LabelsFinder do
it 'ignores labels from groups which user can not read' do
private_subgroup_1.add_developer(user)
- finder = described_class.new(user, group_id: private_group_1.id, only_group_labels: true, include_descendant_groups: true)
+ finder = described_class.new(user, **group_params(private_group_1), only_group_labels: true, include_descendant_groups: true)
expect(finder.execute).to eq [private_subgroup_label_1]
end
end
context 'when including labels from group projects with limited visibility' do
- let(:finder) { described_class.new(user, group_id: group_4.id) }
+ let(:finder) { described_class.new(user, **group_params(group_4)) }
let(:group_4) { create(:group) }
let(:limited_visibility_project) { create(:project, :public, group: group_4) }
let(:visible_project) { create(:project, :public, group: group_4) }
@@ -213,6 +213,24 @@ describe LabelsFinder do
end
end
+ it_behaves_like 'filtering by group' do
+ def group_params(group)
+ { group: group }
+ end
+ end
+
+ it_behaves_like 'filtering by group' do
+ def group_params(group)
+ { group_id: group.id }
+ end
+ end
+
+ it_behaves_like 'filtering by group' do
+ def group_params(group)
+ { group: '', group_id: group.id }
+ end
+ end
+
context 'filtering by project_id' do
context 'when include_ancestor_groups is true' do
let!(:sub_project) { create(:project, namespace: private_subgroup_1 ) }
diff --git a/spec/finders/license_template_finder_spec.rb b/spec/finders/license_template_finder_spec.rb
index 183ee67d801..93f13632b6f 100644
--- a/spec/finders/license_template_finder_spec.rb
+++ b/spec/finders/license_template_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe LicenseTemplateFinder do
+RSpec.describe LicenseTemplateFinder do
describe '#execute' do
subject(:result) { described_class.new(nil, params).execute }
diff --git a/spec/finders/members_finder_spec.rb b/spec/finders/members_finder_spec.rb
index d77548c6fd0..b14ad84a96e 100644
--- a/spec/finders/members_finder_spec.rb
+++ b/spec/finders/members_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MembersFinder, '#execute' do
+RSpec.describe MembersFinder, '#execute' do
let_it_be(:group) { create(:group) }
let_it_be(:nested_group) { create(:group, parent: group) }
let_it_be(:project, reload: true) { create(:project, namespace: nested_group) }
diff --git a/spec/finders/merge_request_target_project_finder_spec.rb b/spec/finders/merge_request_target_project_finder_spec.rb
index 4d2e4c5318c..dfb4d86fbb6 100644
--- a/spec/finders/merge_request_target_project_finder_spec.rb
+++ b/spec/finders/merge_request_target_project_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequestTargetProjectFinder do
+RSpec.describe MergeRequestTargetProjectFinder do
include ProjectForksHelper
let(:user) { create(:user) }
diff --git a/spec/finders/merge_requests_finder_spec.rb b/spec/finders/merge_requests_finder_spec.rb
index b6f2c7bb992..f76110e3d85 100644
--- a/spec/finders/merge_requests_finder_spec.rb
+++ b/spec/finders/merge_requests_finder_spec.rb
@@ -2,10 +2,28 @@
require 'spec_helper'
-describe MergeRequestsFinder do
+RSpec.describe MergeRequestsFinder do
context "multiple projects with merge requests" do
include_context 'MergeRequestsFinder multiple projects with merge requests context'
+ shared_examples 'scalar or array parameter' do
+ let(:values) { merge_requests.pluck(attribute) }
+ let(:params) { {} }
+ let(:key) { attribute }
+
+ it 'takes scalar values' do
+ found = described_class.new(user, params.merge(key => values.first)).execute
+
+ expect(found).to contain_exactly(merge_requests.first)
+ end
+
+ it 'takes array values' do
+ found = described_class.new(user, params.merge(key => values)).execute
+
+ expect(found).to match_array(merge_requests)
+ end
+ end
+
describe '#execute' do
it 'filters by scope' do
params = { scope: 'authored', state: 'opened' }
@@ -91,28 +109,56 @@ describe MergeRequestsFinder do
expect(merge_requests).to contain_exactly(merge_request1, merge_request2, merge_request3, merge_request5)
end
- it 'filters by iid' do
- params = { project_id: project1.id, iids: merge_request1.iid }
+ describe ':iid parameter' do
+ it_behaves_like 'scalar or array parameter' do
+ let(:params) { { project_id: project1.id } }
+ let(:merge_requests) { [merge_request1, merge_request2] }
+ let(:key) { :iids }
+ let(:attribute) { :iid }
+ end
+ end
- merge_requests = described_class.new(user, params).execute
+ [:source_branch, :target_branch].each do |param|
+ describe "#{param} parameter" do
+ let(:merge_requests) { create_list(:merge_request, 2, :unique_branches, source_project: project4, target_project: project4, author: user) }
+ let(:attribute) { param }
- expect(merge_requests).to contain_exactly(merge_request1)
+ it_behaves_like 'scalar or array parameter'
+ end
end
- it 'filters by source branch' do
- params = { source_branch: merge_request2.source_branch }
+ 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
- merge_requests = described_class.new(user, params).execute
+ def find(label_name)
+ described_class.new(user, label_name: label_name).execute
+ end
- expect(merge_requests).to contain_exactly(merge_request2)
- end
+ it 'accepts a single label' do
+ found = find(distinct_labels.first.title)
+ common = find(common_labels.first.title)
- it 'filters by target branch' do
- params = { target_branch: merge_request2.target_branch }
+ expect(found).to contain_exactly(merge_requests.first)
+ expect(common).to match_array(merge_requests)
+ end
- merge_requests = described_class.new(user, params).execute
+ 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(merge_requests).to contain_exactly(merge_request2)
+ expect(all_distinct).to be_empty
+ expect(all_common).to match_array(merge_requests)
+ end
end
it 'filters by source project id' do
@@ -158,7 +204,10 @@ describe MergeRequestsFinder do
merge_requests = described_class.new(user, params).execute
- expect(merge_requests).to contain_exactly(merge_request1, merge_request2, merge_request3, merge_request4, merge_request5, wip_merge_request1, wip_merge_request2, wip_merge_request3, wip_merge_request4)
+ expect(merge_requests).to contain_exactly(
+ merge_request1, merge_request2, merge_request3, merge_request4,
+ merge_request5, wip_merge_request1, wip_merge_request2, wip_merge_request3,
+ wip_merge_request4)
end
it 'adds wip to scalar params' do
diff --git a/spec/finders/metrics/dashboards/annotations_finder_spec.rb b/spec/finders/metrics/dashboards/annotations_finder_spec.rb
index 222875ba2e2..223fd2c047c 100644
--- a/spec/finders/metrics/dashboards/annotations_finder_spec.rb
+++ b/spec/finders/metrics/dashboards/annotations_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Metrics::Dashboards::AnnotationsFinder do
+RSpec.describe Metrics::Dashboards::AnnotationsFinder do
describe '#execute' do
subject(:annotations) { described_class.new(dashboard: dashboard, params: params).execute }
diff --git a/spec/finders/metrics/users_starred_dashboards_finder_spec.rb b/spec/finders/metrics/users_starred_dashboards_finder_spec.rb
index c32b8c2d335..61dadb5239c 100644
--- a/spec/finders/metrics/users_starred_dashboards_finder_spec.rb
+++ b/spec/finders/metrics/users_starred_dashboards_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Metrics::UsersStarredDashboardsFinder do
+RSpec.describe Metrics::UsersStarredDashboardsFinder do
describe '#execute' do
subject(:starred_dashboards) { described_class.new(user: user, project: project, params: params).execute }
diff --git a/spec/finders/milestones_finder_spec.rb b/spec/finders/milestones_finder_spec.rb
index 3402eb39b3b..5920c185c64 100644
--- a/spec/finders/milestones_finder_spec.rb
+++ b/spec/finders/milestones_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MilestonesFinder do
+RSpec.describe MilestonesFinder do
let(:now) { Time.now }
let(:group) { create(:group) }
let(:project_1) { create(:project, namespace: group) }
diff --git a/spec/finders/notes_finder_spec.rb b/spec/finders/notes_finder_spec.rb
index 44636a22ef9..5610f5889e6 100644
--- a/spec/finders/notes_finder_spec.rb
+++ b/spec/finders/notes_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe NotesFinder do
+RSpec.describe NotesFinder do
let(:user) { create :user }
let(:project) { create(:project) }
diff --git a/spec/finders/pending_todos_finder_spec.rb b/spec/finders/pending_todos_finder_spec.rb
index b41b1b46a93..10d3c2905be 100644
--- a/spec/finders/pending_todos_finder_spec.rb
+++ b/spec/finders/pending_todos_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe PendingTodosFinder do
+RSpec.describe PendingTodosFinder do
let(:user) { create(:user) }
describe '#execute' do
diff --git a/spec/finders/personal_access_tokens_finder_spec.rb b/spec/finders/personal_access_tokens_finder_spec.rb
index ce8ef80bb99..dde4f010e41 100644
--- a/spec/finders/personal_access_tokens_finder_spec.rb
+++ b/spec/finders/personal_access_tokens_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe PersonalAccessTokensFinder do
+RSpec.describe PersonalAccessTokensFinder do
def finder(options = {})
described_class.new(options)
end
diff --git a/spec/finders/personal_projects_finder_spec.rb b/spec/finders/personal_projects_finder_spec.rb
index 7686dd3dc9d..62e9999fdd6 100644
--- a/spec/finders/personal_projects_finder_spec.rb
+++ b/spec/finders/personal_projects_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe PersonalProjectsFinder do
+RSpec.describe PersonalProjectsFinder do
let(:source_user) { create(:user) }
let(:current_user) { create(:user) }
let(:finder) { described_class.new(source_user) }
diff --git a/spec/finders/projects/export_job_finder_spec.rb b/spec/finders/projects/export_job_finder_spec.rb
index 31b68717d13..1cc39e35e4d 100644
--- a/spec/finders/projects/export_job_finder_spec.rb
+++ b/spec/finders/projects/export_job_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ExportJobFinder do
+RSpec.describe Projects::ExportJobFinder do
let(:project) { create(:project) }
let(:project_export_job1) { create(:project_export_job, project: project) }
let(:project_export_job2) { create(:project_export_job, project: project) }
diff --git a/spec/finders/projects/prometheus/alerts_finder_spec.rb b/spec/finders/projects/prometheus/alerts_finder_spec.rb
index bb59e77cca8..f47f8addbe9 100644
--- a/spec/finders/projects/prometheus/alerts_finder_spec.rb
+++ b/spec/finders/projects/prometheus/alerts_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Prometheus::AlertsFinder do
+RSpec.describe Projects::Prometheus::AlertsFinder do
let(:finder) { described_class.new(params) }
let(:params) { {} }
diff --git a/spec/finders/projects/serverless/functions_finder_spec.rb b/spec/finders/projects/serverless/functions_finder_spec.rb
index 1f0e3cd2eda..3d3e4183d4e 100644
--- a/spec/finders/projects/serverless/functions_finder_spec.rb
+++ b/spec/finders/projects/serverless/functions_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Serverless::FunctionsFinder do
+RSpec.describe Projects::Serverless::FunctionsFinder do
include KubernetesHelpers
include PrometheusHelpers
include ReactiveCachingHelpers
diff --git a/spec/finders/projects_finder_spec.rb b/spec/finders/projects_finder_spec.rb
index 379cbe83a08..929927ec1c4 100644
--- a/spec/finders/projects_finder_spec.rb
+++ b/spec/finders/projects_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ProjectsFinder, :do_not_mock_admin_mode do
+RSpec.describe ProjectsFinder, :do_not_mock_admin_mode do
include AdminModeHelper
describe '#execute' do
diff --git a/spec/finders/prometheus_metrics_finder_spec.rb b/spec/finders/prometheus_metrics_finder_spec.rb
index 41b2e700e1e..10ef9f76637 100644
--- a/spec/finders/prometheus_metrics_finder_spec.rb
+++ b/spec/finders/prometheus_metrics_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe PrometheusMetricsFinder do
+RSpec.describe PrometheusMetricsFinder do
describe '#execute' do
let(:finder) { described_class.new(params) }
let(:params) { {} }
diff --git a/spec/finders/protected_branches_finder_spec.rb b/spec/finders/protected_branches_finder_spec.rb
index c6b9964b6c5..487d1be697a 100644
--- a/spec/finders/protected_branches_finder_spec.rb
+++ b/spec/finders/protected_branches_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ProtectedBranchesFinder do
+RSpec.describe ProtectedBranchesFinder do
let(:project) { create(:project) }
let!(:protected_branch) { create(:protected_branch, project: project) }
let!(:another_protected_branch) { create(:protected_branch, project: project) }
diff --git a/spec/finders/releases_finder_spec.rb b/spec/finders/releases_finder_spec.rb
index cb4e5fed816..3dc01570d64 100644
--- a/spec/finders/releases_finder_spec.rb
+++ b/spec/finders/releases_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ReleasesFinder do
+RSpec.describe ReleasesFinder do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:params) { {} }
diff --git a/spec/finders/resource_label_event_finder_spec.rb b/spec/finders/resource_label_event_finder_spec.rb
deleted file mode 100644
index 5068ea19d63..00000000000
--- a/spec/finders/resource_label_event_finder_spec.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe ResourceLabelEventFinder do
- let_it_be(:user) { create(:user) }
- let_it_be(:issue_project) { create(:project) }
- let_it_be(:issue) { create(:issue, project: issue_project) }
-
- describe '#execute' do
- subject { described_class.new(user, issue).execute }
-
- it 'returns events with labels accessible by user' do
- label = create(:label, project: issue_project)
- event = create_event(label)
- issue_project.add_guest(user)
-
- expect(subject).to eq [event]
- end
-
- it 'filters events with public project labels if issues and MRs are private' do
- project = create(:project, :public, :issues_private, :merge_requests_private)
- label = create(:label, project: project)
- create_event(label)
-
- expect(subject).to be_empty
- end
-
- it 'filters events with project labels not accessible by user' do
- project = create(:project, :private)
- label = create(:label, project: project)
- create_event(label)
-
- expect(subject).to be_empty
- end
-
- it 'filters events with group labels not accessible by user' do
- group = create(:group, :private)
- label = create(:group_label, group: group)
- create_event(label)
-
- expect(subject).to be_empty
- end
-
- it 'paginates results' do
- label = create(:label, project: issue_project)
- create_event(label)
- create_event(label)
- issue_project.add_guest(user)
-
- paginated = described_class.new(user, issue, per_page: 1).execute
-
- expect(subject.count).to eq 2
- expect(paginated.count).to eq 1
- end
-
- def create_event(label)
- create(:resource_label_event, issue: issue, label: label)
- end
- end
-end
diff --git a/spec/finders/resource_milestone_event_finder_spec.rb b/spec/finders/resource_milestone_event_finder_spec.rb
new file mode 100644
index 00000000000..ff4508996e2
--- /dev/null
+++ b/spec/finders/resource_milestone_event_finder_spec.rb
@@ -0,0 +1,83 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ResourceMilestoneEventFinder do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:issue_project) { create(:project) }
+ let_it_be(:issue) { create(:issue, project: issue_project) }
+
+ describe '#execute' do
+ subject { described_class.new(user, issue).execute }
+
+ it 'returns events with milestones accessible by user' do
+ milestone = create(:milestone, project: issue_project)
+ event = create_event(milestone)
+ issue_project.add_guest(user)
+
+ expect(subject).to eq [event]
+ end
+
+ it 'filters events with public project milestones if issues and MRs are private' do
+ project = create(:project, :public, :issues_private, :merge_requests_private)
+ milestone = create(:milestone, project: project)
+ create_event(milestone)
+
+ expect(subject).to be_empty
+ end
+
+ it 'filters events with project milestones not accessible by user' do
+ project = create(:project, :private)
+ milestone = create(:milestone, project: project)
+ create_event(milestone)
+
+ expect(subject).to be_empty
+ end
+
+ it 'filters events with group milestones not accessible by user' do
+ group = create(:group, :private)
+ milestone = create(:milestone, group: group)
+ create_event(milestone)
+
+ expect(subject).to be_empty
+ end
+
+ it 'paginates results' do
+ milestone = create(:milestone, project: issue_project)
+ create_event(milestone)
+ create_event(milestone)
+ issue_project.add_guest(user)
+
+ paginated = described_class.new(user, issue, per_page: 1).execute
+
+ expect(subject.count).to eq 2
+ expect(paginated.count).to eq 1
+ end
+
+ context 'when multiple events share the same milestone' do
+ it 'avoids N+1 queries' do
+ issue_project.add_developer(user)
+
+ milestone1 = create(:milestone, project: issue_project)
+ milestone2 = create(:milestone, project: issue_project)
+
+ control_count = ActiveRecord::QueryRecorder.new { described_class.new(user, issue).execute }.count
+ expect(control_count).to eq(1) # 1 events query
+
+ create_event(milestone1, :add)
+ create_event(milestone1, :remove)
+ create_event(milestone1, :add)
+ create_event(milestone1, :remove)
+ create_event(milestone2, :add)
+ create_event(milestone2, :remove)
+
+ # 1 events + 1 milestones + 1 project + 1 user + 4 ability
+ expect { described_class.new(user, issue).execute }.not_to exceed_query_limit(control_count + 7)
+ end
+ end
+
+ def create_event(milestone, action = :add)
+ create(:resource_milestone_event, issue: issue, milestone: milestone, action: action)
+ end
+ end
+end
diff --git a/spec/finders/sentry_issue_finder_spec.rb b/spec/finders/sentry_issue_finder_spec.rb
index 520f690a134..b6d62965cb9 100644
--- a/spec/finders/sentry_issue_finder_spec.rb
+++ b/spec/finders/sentry_issue_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe SentryIssueFinder do
+RSpec.describe SentryIssueFinder do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:issue) { create(:issue, project: project) }
diff --git a/spec/finders/serverless_domain_finder_spec.rb b/spec/finders/serverless_domain_finder_spec.rb
index c41f09535d3..4e6b9f07544 100644
--- a/spec/finders/serverless_domain_finder_spec.rb
+++ b/spec/finders/serverless_domain_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ServerlessDomainFinder do
+RSpec.describe ServerlessDomainFinder do
let(:function_name) { 'test-function' }
let(:pages_domain_name) { 'serverless.gitlab.io' }
let(:valid_cluster_uuid) { 'aba1cdef123456f278' }
diff --git a/spec/finders/snippets_finder_spec.rb b/spec/finders/snippets_finder_spec.rb
index fdcc73f6e92..0affc832b30 100644
--- a/spec/finders/snippets_finder_spec.rb
+++ b/spec/finders/snippets_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe SnippetsFinder do
+RSpec.describe SnippetsFinder do
include ExternalAuthorizationServiceHelpers
include Gitlab::Allowable
diff --git a/spec/finders/starred_projects_finder_spec.rb b/spec/finders/starred_projects_finder_spec.rb
index 7aa8251c3ab..15d4ae52ddd 100644
--- a/spec/finders/starred_projects_finder_spec.rb
+++ b/spec/finders/starred_projects_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe StarredProjectsFinder do
+RSpec.describe StarredProjectsFinder do
let(:project1) { create(:project, :public, :empty_repo) }
let(:project2) { create(:project, :public, :empty_repo) }
let(:other_project) { create(:project, :public, :empty_repo) }
diff --git a/spec/finders/tags_finder_spec.rb b/spec/finders/tags_finder_spec.rb
index b9de2d29895..08978a32e50 100644
--- a/spec/finders/tags_finder_spec.rb
+++ b/spec/finders/tags_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe TagsFinder do
+RSpec.describe TagsFinder do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:repository) { project.repository }
diff --git a/spec/finders/template_finder_spec.rb b/spec/finders/template_finder_spec.rb
index ed47752cf60..34f81e249e2 100644
--- a/spec/finders/template_finder_spec.rb
+++ b/spec/finders/template_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe TemplateFinder do
+RSpec.describe TemplateFinder do
using RSpec::Parameterized::TableSyntax
describe '#build' do
diff --git a/spec/finders/todos_finder_spec.rb b/spec/finders/todos_finder_spec.rb
index 87650835b05..4123783d828 100644
--- a/spec/finders/todos_finder_spec.rb
+++ b/spec/finders/todos_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe TodosFinder do
+RSpec.describe TodosFinder do
describe '#execute' do
let(:user) { create(:user) }
let(:group) { create(:group) }
diff --git a/spec/finders/uploader_finder_spec.rb b/spec/finders/uploader_finder_spec.rb
new file mode 100644
index 00000000000..814d4b88b57
--- /dev/null
+++ b/spec/finders/uploader_finder_spec.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe UploaderFinder do
+ describe '#execute' do
+ let(:project) { build(:project) }
+ let(:upload) { create(:upload, :issuable_upload, :with_file) }
+ let(:secret) { upload.secret }
+ let(:file_name) { upload.path }
+
+ subject { described_class.new(project, secret, file_name).execute }
+
+ before do
+ upload.save
+ end
+
+ context 'when successful' do
+ before do
+ allow_next_instance_of(FileUploader) do |uploader|
+ allow(uploader).to receive(:retrieve_from_store!).with(upload.path).and_return(uploader)
+ end
+ end
+
+ it 'gets the file-like uploader' do
+ expect(subject).to be_an_instance_of(FileUploader)
+ expect(subject.model).to eq(project)
+ expect(subject.secret).to eq(secret)
+ end
+ end
+
+ context 'when path traversal in file name' do
+ before do
+ upload.path = '/uploads/11111111111111111111111111111111/../../../../../../../../../../../../../../etc/passwd)'
+ upload.save
+ end
+
+ it 'returns nil' do
+ expect(subject).to be(nil)
+ end
+ end
+
+ context 'when unexpected failure' do
+ before do
+ allow_next_instance_of(FileUploader) do |uploader|
+ allow(uploader).to receive(:retrieve_from_store!).and_raise(StandardError)
+ end
+ end
+
+ it 'returns nil when unexpected error is raised' do
+ expect { subject }.to raise_error(StandardError)
+ end
+ end
+ end
+end
diff --git a/spec/finders/user_finder_spec.rb b/spec/finders/user_finder_spec.rb
index b89b422aa2c..e9ba2f48164 100644
--- a/spec/finders/user_finder_spec.rb
+++ b/spec/finders/user_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe UserFinder do
+RSpec.describe UserFinder do
let_it_be(:user) { create(:user) }
describe '#find_by_id' do
diff --git a/spec/finders/user_recent_events_finder_spec.rb b/spec/finders/user_recent_events_finder_spec.rb
index eef6448a4a2..04ba05c68e4 100644
--- a/spec/finders/user_recent_events_finder_spec.rb
+++ b/spec/finders/user_recent_events_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe UserRecentEventsFinder do
+RSpec.describe UserRecentEventsFinder do
let(:current_user) { create(:user) }
let(:project_owner) { create(:user) }
let(:private_project) { create(:project, :private, creator: project_owner) }
diff --git a/spec/finders/users_finder_spec.rb b/spec/finders/users_finder_spec.rb
index 7f1fc1cc1c5..17b36247b05 100644
--- a/spec/finders/users_finder_spec.rb
+++ b/spec/finders/users_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe UsersFinder do
+RSpec.describe UsersFinder do
describe '#execute' do
include_context 'UsersFinder#execute filter by project context'
@@ -21,6 +21,12 @@ describe UsersFinder do
expect(users).to contain_exactly(normal_user)
end
+ it 'filters by id' do
+ users = described_class.new(user, id: normal_user.id).execute
+
+ expect(users).to contain_exactly(normal_user)
+ end
+
it 'filters by username (case insensitive)' do
users = described_class.new(user, username: 'joHNdoE').execute
@@ -70,6 +76,12 @@ describe UsersFinder do
expect(users).to contain_exactly(user, normal_user, blocked_user, omniauth_user)
end
+
+ it 'orders returned results' do
+ users = described_class.new(user, sort: 'id_asc').execute
+
+ expect(users).to eq([normal_user, blocked_user, omniauth_user, user])
+ end
end
context 'with an admin user' do
diff --git a/spec/finders/users_star_projects_finder_spec.rb b/spec/finders/users_star_projects_finder_spec.rb
index fb1d8088f44..038506cc93f 100644
--- a/spec/finders/users_star_projects_finder_spec.rb
+++ b/spec/finders/users_star_projects_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe UsersStarProjectsFinder do
+RSpec.describe UsersStarProjectsFinder do
let(:project) { create(:project, :public, :empty_repo) }
let(:user) { create(:user) }
diff --git a/spec/finders/users_with_pending_todos_finder_spec.rb b/spec/finders/users_with_pending_todos_finder_spec.rb
index fa15355531c..565b65fbefe 100644
--- a/spec/finders/users_with_pending_todos_finder_spec.rb
+++ b/spec/finders/users_with_pending_todos_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe UsersWithPendingTodosFinder do
+RSpec.describe UsersWithPendingTodosFinder do
describe '#execute' do
it 'returns the users for all pending todos of a target' do
issue = create(:issue)
diff --git a/spec/fixtures/api/schemas/entities/merge_request_noteable.json b/spec/fixtures/api/schemas/entities/merge_request_noteable.json
index c0eb320e67f..4ef19ed32c2 100644
--- a/spec/fixtures/api/schemas/entities/merge_request_noteable.json
+++ b/spec/fixtures/api/schemas/entities/merge_request_noteable.json
@@ -32,7 +32,8 @@
},
"is_project_archived": { "type": "boolean" },
"locked_discussion_docs_path": { "type": "string" },
- "archived_project_docs_path": { "type": "string" }
+ "archived_project_docs_path": { "type": "string" },
+ "project_id": { "type": "integer"}
},
"additionalProperties": false
}
diff --git a/spec/fixtures/api/schemas/evidences/issue.json b/spec/fixtures/api/schemas/evidences/issue.json
index fd9daf17ab8..628c4c89312 100644
--- a/spec/fixtures/api/schemas/evidences/issue.json
+++ b/spec/fixtures/api/schemas/evidences/issue.json
@@ -4,7 +4,6 @@
"id",
"title",
"description",
- "author",
"state",
"iid",
"confidential",
diff --git a/spec/fixtures/api/schemas/evidences/milestone.json b/spec/fixtures/api/schemas/evidences/milestone.json
index 3ce0644225b..ab27fdecde2 100644
--- a/spec/fixtures/api/schemas/evidences/milestone.json
+++ b/spec/fixtures/api/schemas/evidences/milestone.json
@@ -7,7 +7,8 @@
"state",
"iid",
"created_at",
- "due_date"
+ "due_date",
+ "issues"
],
"properties": {
"id": { "type": "integer" },
@@ -16,7 +17,11 @@
"state": { "type": "string" },
"iid": { "type": "integer" },
"created_at": { "type": "date" },
- "due_date": { "type": ["date", "null"] }
+ "due_date": { "type": ["date", "null"] },
+ "issues": {
+ "type": "array",
+ "items": { "$ref": "issue.json" }
+ }
},
"additionalProperties": false
}
diff --git a/spec/fixtures/api/schemas/public_api/v4/board.json b/spec/fixtures/api/schemas/public_api/v4/board.json
index e4933ee0b93..89a21c29969 100644
--- a/spec/fixtures/api/schemas/public_api/v4/board.json
+++ b/spec/fixtures/api/schemas/public_api/v4/board.json
@@ -78,7 +78,8 @@
},
"position": { "type": ["integer", "null"] },
"max_issue_count": { "type": "integer" },
- "max_issue_weight": { "type": "integer" }
+ "max_issue_weight": { "type": "integer" },
+ "limit_metric": { "type": ["string", "null"] }
},
"additionalProperties": false
}
diff --git a/spec/fixtures/api/schemas/registry/repository.json b/spec/fixtures/api/schemas/registry/repository.json
index f7469aad235..1f84e787b19 100644
--- a/spec/fixtures/api/schemas/registry/repository.json
+++ b/spec/fixtures/api/schemas/registry/repository.json
@@ -1,13 +1,7 @@
{
"type": "object",
- "required" : [
- "id",
- "name",
- "path",
- "location",
- "created_at"
- ],
- "properties" : {
+ "required": ["id", "name", "path", "location", "created_at"],
+ "properties": {
"id": {
"type": "integer"
},
@@ -38,7 +32,10 @@
{ "type": "string", "enum": ["delete_scheduled", "delete_failed"] }
]
},
- "tags": { "$ref": "tags.json" }
+ "tags": { "$ref": "tags.json" },
+ "tags_count": {
+ "type": "integer"
+ }
},
"additionalProperties": false
}
diff --git a/spec/fixtures/api/schemas/release/link.json b/spec/fixtures/api/schemas/release/link.json
index bf175be2bc0..b3aebfa131e 100644
--- a/spec/fixtures/api/schemas/release/link.json
+++ b/spec/fixtures/api/schemas/release/link.json
@@ -7,7 +7,8 @@
"filepath": { "type": "string" },
"url": { "type": "string" },
"direct_asset_url": { "type": "string" },
- "external": { "type": "boolean" }
+ "external": { "type": "boolean" },
+ "link_type": { "type": "string" }
},
"additionalProperties": false
}
diff --git a/spec/fixtures/gitlab/database/structure_example.sql b/spec/fixtures/gitlab/database/structure_example.sql
index 9f288e6067e..06db67b725a 100644
--- a/spec/fixtures/gitlab/database/structure_example.sql
+++ b/spec/fixtures/gitlab/database/structure_example.sql
@@ -48,7 +48,6 @@ CREATE TABLE public.abuse_reports (
--
CREATE SEQUENCE public.abuse_reports_id_seq
- AS integer
START WITH 1
INCREMENT BY 1
NO MINVALUE
diff --git a/spec/fixtures/gitlab/database/structure_example_cleaned.sql b/spec/fixtures/gitlab/database/structure_example_cleaned.sql
index 78120fa6ce0..5618fb694a0 100644
--- a/spec/fixtures/gitlab/database/structure_example_cleaned.sql
+++ b/spec/fixtures/gitlab/database/structure_example_cleaned.sql
@@ -1,7 +1,5 @@
SET search_path=public;
-CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
-
CREATE EXTENSION IF NOT EXISTS pg_trgm WITH SCHEMA public;
CREATE TABLE public.abuse_reports (
diff --git a/spec/fixtures/lib/gitlab/metrics/dashboard/sample_dashboard.yml b/spec/fixtures/lib/gitlab/metrics/dashboard/sample_dashboard.yml
index b460a031486..5177de66fcf 100644
--- a/spec/fixtures/lib/gitlab/metrics/dashboard/sample_dashboard.yml
+++ b/spec/fixtures/lib/gitlab/metrics/dashboard/sample_dashboard.yml
@@ -1,5 +1,18 @@
dashboard: 'Test Dashboard'
priority: 1
+links:
+- title: Link 1
+ url: https://gitlab.com
+- title: Link 2
+ url: https://docs.gitlab.com
+templating:
+ variables:
+ text_variable_full_syntax:
+ label: 'Variable 1'
+ type: text
+ options:
+ default_value: 'default'
+ text_variable_simple_syntax: 'default value'
panel_groups:
- group: Group A
priority: 1
diff --git a/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/dashboard.json b/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/dashboard.json
index 5d779a323c2..259c41bf091 100644
--- a/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/dashboard.json
+++ b/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/dashboard.json
@@ -11,7 +11,9 @@
"panel_groups": {
"type": "array",
"items": { "$ref": "spec/fixtures/lib/gitlab/metrics/dashboard/schemas/panel_groups.json" }
- }
+ },
+ "templating": { "$ref": "spec/fixtures/lib/gitlab/metrics/dashboard/schemas/templating.json" },
+ "links": { "$ref": "spec/fixtures/lib/gitlab/metrics/dashboard/schemas/links.json" }
},
"additionalProperties": false
}
diff --git a/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/links.json b/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/links.json
new file mode 100644
index 00000000000..be180114052
--- /dev/null
+++ b/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/links.json
@@ -0,0 +1,9 @@
+{
+ "type": "array",
+ "required": ["url"],
+ "properties": {
+ "url": { "type": "string" },
+ "title": { "type": "string" }
+ },
+ "additionalProperties": false
+}
diff --git a/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/templating.json b/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/templating.json
new file mode 100644
index 00000000000..c82d2fcb02c
--- /dev/null
+++ b/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/templating.json
@@ -0,0 +1,8 @@
+{
+ "type": "object",
+ "required": ["variables"],
+ "properties": {
+ "variables": { "$ref": "variables.json" }
+ },
+ "additionalProperties": false
+}
diff --git a/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/text_variable_full_syntax.json b/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/text_variable_full_syntax.json
new file mode 100644
index 00000000000..f5090dc8c88
--- /dev/null
+++ b/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/text_variable_full_syntax.json
@@ -0,0 +1,12 @@
+{
+ "type": "object",
+ "required": [
+ "type", "options"
+ ],
+ "properties": {
+ "type": { "type": "string" },
+ "label": { "type": "string" },
+ "options": { "$ref": "text_variable_options.json" }
+ },
+ "additionalProperties": false
+}
diff --git a/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/text_variable_options.json b/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/text_variable_options.json
new file mode 100644
index 00000000000..ccb2e168fd1
--- /dev/null
+++ b/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/text_variable_options.json
@@ -0,0 +1,7 @@
+{
+ "type": "object",
+ "properties": {
+ "default_value": { "type": "string" }
+ },
+ "additionalProperties": false
+}
diff --git a/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/variables.json b/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/variables.json
new file mode 100644
index 00000000000..f3e0dd555a6
--- /dev/null
+++ b/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/variables.json
@@ -0,0 +1,12 @@
+{
+ "type": "object",
+ "patternProperties": {
+ "^[a-zA-Z0-9_]*$": {
+ "anyOf": [
+ { "$ref": "text_variable_full_syntax.json" },
+ { "type": "string" }
+ ]
+ }
+ },
+ "additionalProperties": false
+}
diff --git a/spec/fixtures/lsif.json.gz b/spec/fixtures/lsif.json.gz
deleted file mode 100644
index 3f74588cd7e..00000000000
--- a/spec/fixtures/lsif.json.gz
+++ /dev/null
Binary files differ
diff --git a/spec/fixtures/packages/conan/package_files/conan_package.tgz b/spec/fixtures/packages/conan/package_files/conan_package.tgz
new file mode 100644
index 00000000000..6163364f3f9
--- /dev/null
+++ b/spec/fixtures/packages/conan/package_files/conan_package.tgz
Binary files differ
diff --git a/spec/fixtures/packages/conan/package_files/conaninfo.txt b/spec/fixtures/packages/conan/package_files/conaninfo.txt
new file mode 100644
index 00000000000..2a02515a19b
--- /dev/null
+++ b/spec/fixtures/packages/conan/package_files/conaninfo.txt
@@ -0,0 +1,33 @@
+[settings]
+ arch=x86_64
+ build_type=Release
+ compiler=apple-clang
+ compiler.libcxx=libc++
+ compiler.version=10.0
+ os=Macos
+
+[requires]
+
+
+[options]
+ shared=False
+
+[full_settings]
+ arch=x86_64
+ build_type=Release
+ compiler=apple-clang
+ compiler.libcxx=libc++
+ compiler.version=10.0
+ os=Macos
+
+[full_requires]
+
+
+[full_options]
+ shared=False
+
+[recipe_hash]
+ b4b91125b36b40a7076a98310588f820
+
+[env]
+
diff --git a/spec/fixtures/packages/conan/package_files/conanmanifest.txt b/spec/fixtures/packages/conan/package_files/conanmanifest.txt
new file mode 100644
index 00000000000..bc34b81b050
--- /dev/null
+++ b/spec/fixtures/packages/conan/package_files/conanmanifest.txt
@@ -0,0 +1,4 @@
+1565723794
+conaninfo.txt: 2774ebe649804c1cd9430f26ab0ead14
+include/hello.h: 8727846905bd09baecf8bdc1edb1f46e
+lib/libhello.a: 7f2aaa8b6f3bc316bba59e47b6a0bd43
diff --git a/spec/fixtures/packages/conan/recipe_files/conanfile.py b/spec/fixtures/packages/conan/recipe_files/conanfile.py
new file mode 100644
index 00000000000..910bd5a0b51
--- /dev/null
+++ b/spec/fixtures/packages/conan/recipe_files/conanfile.py
@@ -0,0 +1,47 @@
+from conans import ConanFile, CMake, tools
+
+
+class HelloConan(ConanFile):
+ name = "Hello"
+ version = "0.1"
+ license = "<Put the package license here>"
+ author = "<Put your name here> <And your email here>"
+ url = "<Package recipe repository url here, for issues about the package>"
+ description = "<Description of Hello here>"
+ topics = ("<Put some tag here>", "<here>", "<and here>")
+ settings = "os", "compiler", "build_type", "arch"
+ options = {"shared": [True, False]}
+ default_options = "shared=False"
+ generators = "cmake"
+
+ def source(self):
+ self.run("git clone https://github.com/conan-io/hello.git")
+ # This small hack might be useful to guarantee proper /MT /MD linkage
+ # in MSVC if the packaged project doesn't have variables to set it
+ # properly
+ tools.replace_in_file("hello/CMakeLists.txt", "PROJECT(HelloWorld)",
+ '''PROJECT(HelloWorld)
+include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
+conan_basic_setup()''')
+
+ def build(self):
+ cmake = CMake(self)
+ cmake.configure(source_folder="hello")
+ cmake.build()
+
+ # Explicit way:
+ # self.run('cmake %s/hello %s'
+ # % (self.source_folder, cmake.command_line))
+ # self.run("cmake --build . %s" % cmake.build_config)
+
+ def package(self):
+ self.copy("*.h", dst="include", src="hello")
+ self.copy("*hello.lib", dst="lib", keep_path=False)
+ self.copy("*.dll", dst="bin", keep_path=False)
+ self.copy("*.so", dst="lib", keep_path=False)
+ self.copy("*.dylib", dst="lib", keep_path=False)
+ self.copy("*.a", dst="lib", keep_path=False)
+
+ def package_info(self):
+ self.cpp_info.libs = ["hello"]
+
diff --git a/spec/fixtures/packages/conan/recipe_files/conanmanifest.txt b/spec/fixtures/packages/conan/recipe_files/conanmanifest.txt
new file mode 100644
index 00000000000..432b12f39fa
--- /dev/null
+++ b/spec/fixtures/packages/conan/recipe_files/conanmanifest.txt
@@ -0,0 +1,2 @@
+1565723790
+conanfile.py: 7c042b95312cc4c4ee89199dc51aebf9
diff --git a/spec/fixtures/packages/maven/maven-metadata.xml b/spec/fixtures/packages/maven/maven-metadata.xml
new file mode 100644
index 00000000000..7d7549df227
--- /dev/null
+++ b/spec/fixtures/packages/maven/maven-metadata.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata modelVersion="1.1.0">
+ <groupId>com.mycompany.app</groupId>
+ <artifactId>my-app</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <versioning>
+ <snapshot>
+ <timestamp>20180724.124855</timestamp>
+ <buildNumber>1</buildNumber>
+ </snapshot>
+ <lastUpdated>20180724124855</lastUpdated>
+ <snapshotVersions>
+ <snapshotVersion>
+ <extension>jar</extension>
+ <value>1.0-20180724.124855-1</value>
+ <updated>20180724124855</updated>
+ </snapshotVersion>
+ <snapshotVersion>
+ <extension>pom</extension>
+ <value>1.0-20180724.124855-1</value>
+ <updated>20180724124855</updated>
+ </snapshotVersion>
+ </snapshotVersions>
+ </versioning>
+</metadata>
diff --git a/spec/fixtures/packages/maven/my-app-1.0-20180724.124855-1.jar b/spec/fixtures/packages/maven/my-app-1.0-20180724.124855-1.jar
new file mode 100644
index 00000000000..ea3903cf6d9
--- /dev/null
+++ b/spec/fixtures/packages/maven/my-app-1.0-20180724.124855-1.jar
Binary files differ
diff --git a/spec/fixtures/packages/maven/my-app-1.0-20180724.124855-1.pom b/spec/fixtures/packages/maven/my-app-1.0-20180724.124855-1.pom
new file mode 100644
index 00000000000..6b6015314aa
--- /dev/null
+++ b/spec/fixtures/packages/maven/my-app-1.0-20180724.124855-1.pom
@@ -0,0 +1,34 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>com.mycompany.app</groupId>
+ <artifactId>my-app</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0-SNAPSHOT</version>
+ <name>my-app</name>
+ <url>http://maven.apache.org</url>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <distributionManagement>
+ <snapshotRepository>
+ <id>local</id>
+ <url>file:///tmp/maven</url>
+ </snapshotRepository>
+ </distributionManagement>
+ <repositories>
+ <repository>
+ <id>local</id>
+ <url>file:///tmp/maven</url>
+ </repository>
+ </repositories>
+ <properties>
+ <maven.compiler.source>1.6</maven.compiler.source>
+ <maven.compiler.target>1.6</maven.compiler.target>
+ </properties>
+</project>
diff --git a/spec/fixtures/packages/npm/foo-1.0.1.tgz b/spec/fixtures/packages/npm/foo-1.0.1.tgz
new file mode 100644
index 00000000000..a2bcdb8d492
--- /dev/null
+++ b/spec/fixtures/packages/npm/foo-1.0.1.tgz
Binary files differ
diff --git a/spec/fixtures/packages/npm/payload.json b/spec/fixtures/packages/npm/payload.json
new file mode 100644
index 00000000000..664aa636001
--- /dev/null
+++ b/spec/fixtures/packages/npm/payload.json
@@ -0,0 +1,30 @@
+{
+ "_id":"@root/npm-test",
+ "name":"@root/npm-test",
+ "description":"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
+ "dist-tags":{
+ "latest":"1.0.1"
+ },
+ "versions":{
+ "1.0.1":{
+ "name":"@root/npm-test",
+ "version":"1.0.1",
+ "main":"app.js",
+ "dependencies":{
+ "express":"^4.16.4"
+ },
+ "dist":{
+ "shasum":"f572d396fae9206628714fb2ce00f72e94f2258f"
+ }
+ }
+ },
+ "_attachments":{
+ "@root/npm-test-1.0.1.tgz":{
+ "content_type":"application/octet-stream",
+ "data":"aGVsbG8K",
+ "length":8
+ }
+ },
+ "id":"10",
+ "package_name":"@root/npm-test"
+}
diff --git a/spec/fixtures/packages/npm/payload_with_duplicated_packages.json b/spec/fixtures/packages/npm/payload_with_duplicated_packages.json
new file mode 100644
index 00000000000..a6ea8760bd5
--- /dev/null
+++ b/spec/fixtures/packages/npm/payload_with_duplicated_packages.json
@@ -0,0 +1,44 @@
+{
+ "_id":"@root/npm-test",
+ "name":"@root/npm-test",
+ "description":"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
+ "dist-tags":{
+ "latest":"1.0.1"
+ },
+ "versions":{
+ "1.0.1":{
+ "name":"@root/npm-test",
+ "version":"1.0.1",
+ "main":"app.js",
+ "dependencies":{
+ "express":"^4.16.4",
+ "dagre-d3": "~0.3.2"
+ },
+ "devDependencies": {
+ "dagre-d3": "~0.3.2",
+ "d3": "~3.4.13"
+ },
+ "bundleDependencies": {
+ "d3": "~3.4.13"
+ },
+ "peerDependencies": {
+ "d3": "~3.3.0"
+ },
+ "deprecated": {
+ "express":"^4.16.4"
+ },
+ "dist":{
+ "shasum":"f572d396fae9206628714fb2ce00f72e94f2258f"
+ }
+ }
+ },
+ "_attachments":{
+ "@root/npm-test-1.0.1.tgz":{
+ "content_type":"application/octet-stream",
+ "data":"aGVsbG8K",
+ "length":8
+ }
+ },
+ "id":"10",
+ "package_name":"@root/npm-test"
+}
diff --git a/spec/fixtures/packages/nuget/package.nupkg b/spec/fixtures/packages/nuget/package.nupkg
new file mode 100644
index 00000000000..b36856ee569
--- /dev/null
+++ b/spec/fixtures/packages/nuget/package.nupkg
Binary files differ
diff --git a/spec/fixtures/packages/nuget/with_dependencies.nuspec b/spec/fixtures/packages/nuget/with_dependencies.nuspec
new file mode 100644
index 00000000000..753037cd05b
--- /dev/null
+++ b/spec/fixtures/packages/nuget/with_dependencies.nuspec
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
+ <metadata>
+ <id>Test.Package</id>
+ <version>3.5.2</version>
+ <authors>Test Author</authors>
+ <owners>Test Owner</owners>
+ <requireLicenseAcceptance>false</requireLicenseAcceptance>
+ <description>Package Description</description>
+ <dependencies>
+ <dependency id="Moqi" version="2.5.6" include="Runtime,Compile" />
+ <group targetFramework=".NETStandard2.0">
+ <dependency id="Test.Dependency" version="2.3.7" exclude="Build,Analyzers" include="Runtime,Compile" />
+ <dependency id="Newtonsoft.Json" version="12.0.3" exclude="Build,Analyzers" />
+ </group>
+ <dependency id="Castle.Core" />
+ </dependencies>
+ </metadata>
+</package>
diff --git a/spec/fixtures/packages/nuget/with_metadata.nuspec b/spec/fixtures/packages/nuget/with_metadata.nuspec
new file mode 100644
index 00000000000..0043bc89527
--- /dev/null
+++ b/spec/fixtures/packages/nuget/with_metadata.nuspec
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
+ <metadata>
+ <id>DummyProject.WithMetadata</id>
+ <version>1.2.3</version>
+ <title>nuspec with metadata</title>
+ <authors>Author Test</authors>
+ <owners>Author Test</owners>
+ <developmentDependency>true</developmentDependency>
+ <requireLicenseAcceptance>true</requireLicenseAcceptance>
+ <licenseUrl>https://opensource.org/licenses/MIT</licenseUrl>
+ <projectUrl>https://gitlab.com/gitlab-org/gitlab</projectUrl>
+ <iconUrl>https://opensource.org/files/osi_keyhole_300X300_90ppi_0.png</iconUrl>
+ <description>Description Test</description>
+ <releaseNotes>Release Notes Test</releaseNotes>
+ <copyright>Copyright Test</copyright>
+ <tags>foo bar test tag1 tag2 tag3 tag4 tag5</tags>
+ </metadata>
+</package>
diff --git a/spec/fixtures/packages/pypi/sample-project.tar.gz b/spec/fixtures/packages/pypi/sample-project.tar.gz
new file mode 100644
index 00000000000..c71b1fef23d
--- /dev/null
+++ b/spec/fixtures/packages/pypi/sample-project.tar.gz
Binary files differ
diff --git a/spec/fixtures/trace/sample_trace b/spec/fixtures/trace/sample_trace
index e9d1e79fc71..ebd2853e558 100644
--- a/spec/fixtures/trace/sample_trace
+++ b/spec/fixtures/trace/sample_trace
@@ -2736,9 +2736,6 @@ Service
when repository is empty
test runs execute
Template
- .build_from_template
- when template is invalid
- sets service template to inactive when template is invalid
for pushover service
is prefilled for projects pushover service
has all fields prefilled
diff --git a/spec/frontend/.eslintrc.yml b/spec/frontend/.eslintrc.yml
index b9159191114..8e6faa90c58 100644
--- a/spec/frontend/.eslintrc.yml
+++ b/spec/frontend/.eslintrc.yml
@@ -10,7 +10,7 @@ settings:
- path
import/resolver:
jest:
- jestConfigFile: 'jest.config.unit.js'
+ jestConfigFile: 'jest.config.js'
globals:
getJSONFixture: false
loadFixtures: false
diff --git a/spec/frontend/__mocks__/lodash/throttle.js b/spec/frontend/__mocks__/lodash/throttle.js
new file mode 100644
index 00000000000..aef391afd0c
--- /dev/null
+++ b/spec/frontend/__mocks__/lodash/throttle.js
@@ -0,0 +1,4 @@
+// Similar to `lodash/debounce`, `lodash/throttle` also causes flaky specs.
+// See `./debounce.js` for more details.
+
+export default fn => fn;
diff --git a/spec/frontend/__mocks__/monaco-editor/index.js b/spec/frontend/__mocks__/monaco-editor/index.js
index 18cc3a7c377..7c53cfb5174 100644
--- a/spec/frontend/__mocks__/monaco-editor/index.js
+++ b/spec/frontend/__mocks__/monaco-editor/index.js
@@ -9,5 +9,8 @@ import 'monaco-editor/esm/vs/language/json/monaco.contribution';
import 'monaco-editor/esm/vs/language/html/monaco.contribution';
import 'monaco-editor/esm/vs/basic-languages/monaco.contribution';
+// This language starts trying to spin up web workers which obviously breaks in Jest environment
+jest.mock('monaco-editor/esm/vs/language/typescript/tsMode');
+
export * from 'monaco-editor/esm/vs/editor/editor.api';
export default global.monaco;
diff --git a/spec/frontend/alert_management/components/alert_management_detail_spec.js b/spec/frontend/alert_management/components/alert_management_detail_spec.js
index 1e4c2e24ccb..14e45a4f563 100644
--- a/spec/frontend/alert_management/components/alert_management_detail_spec.js
+++ b/spec/frontend/alert_management/components/alert_management_detail_spec.js
@@ -1,39 +1,37 @@
import { mount, shallowMount } from '@vue/test-utils';
-import { GlAlert, GlLoadingIcon, GlDropdownItem, GlTable } from '@gitlab/ui';
+import { GlAlert, GlLoadingIcon, GlTable } from '@gitlab/ui';
+import axios from 'axios';
+import MockAdapter from 'axios-mock-adapter';
import AlertDetails from '~/alert_management/components/alert_details.vue';
-import updateAlertStatus from '~/alert_management/graphql/mutations/update_alert_status.graphql';
-import createFlash from '~/flash';
-
+import createIssueQuery from '~/alert_management/graphql/mutations/create_issue_from_alert.graphql';
+import { joinPaths } from '~/lib/utils/url_utility';
+import {
+ trackAlertsDetailsViewsOptions,
+ ALERTS_SEVERITY_LABELS,
+} from '~/alert_management/constants';
+import Tracking from '~/tracking';
import mockAlerts from '../mocks/alerts.json';
const mockAlert = mockAlerts[0];
-jest.mock('~/flash');
describe('AlertDetails', () => {
let wrapper;
- const newIssuePath = 'root/alerts/-/issues/new';
- const findStatusDropdownItem = () => wrapper.find(GlDropdownItem);
+ let mock;
+ const projectPath = 'root/alerts';
+ const projectIssuesPath = 'root/alerts/-/issues';
+
const findDetailsTable = () => wrapper.find(GlTable);
- function mountComponent({
- data,
- createIssueFromAlertEnabled = false,
- loading = false,
- mountMethod = shallowMount,
- stubs = {},
- } = {}) {
+ function mountComponent({ data, loading = false, mountMethod = shallowMount, stubs = {} } = {}) {
wrapper = mountMethod(AlertDetails, {
propsData: {
alertId: 'alertId',
- projectPath: 'projectPath',
- newIssuePath,
+ projectPath,
+ projectIssuesPath,
},
data() {
return { alert: { ...mockAlert }, ...data };
},
- provide: {
- glFeatures: { createIssueFromAlertEnabled },
- },
mocks: {
$apollo: {
mutate: jest.fn(),
@@ -48,13 +46,22 @@ describe('AlertDetails', () => {
});
}
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ });
+
afterEach(() => {
if (wrapper) {
- wrapper.destroy();
+ if (wrapper) {
+ wrapper.destroy();
+ }
}
+ mock.restore();
});
- const findCreatedIssueBtn = () => wrapper.find('[data-testid="createIssueBtn"]');
+ const findCreateIssueBtn = () => wrapper.find('[data-testid="createIssueBtn"]');
+ const findViewIssueBtn = () => wrapper.find('[data-testid="viewIssueBtn"]');
+ const findIssueCreationAlert = () => wrapper.find('[data-testid="issueCreationError"]');
describe('Alert details', () => {
describe('when alert is null', () => {
@@ -80,6 +87,12 @@ describe('AlertDetails', () => {
expect(wrapper.find('[data-testid="fullDetailsTab"]').exists()).toBe(true);
});
+ it('renders severity', () => {
+ expect(wrapper.find('[data-testid="severity"]').text()).toBe(
+ ALERTS_SEVERITY_LABELS[mockAlert.severity],
+ );
+ });
+
it('renders a title', () => {
expect(wrapper.find('[data-testid="title"]').text()).toBe(mockAlert.title);
});
@@ -117,18 +130,54 @@ describe('AlertDetails', () => {
});
describe('Create issue from alert', () => {
- describe('createIssueFromAlertEnabled feature flag enabled', () => {
- it('should display a button that links to new issue page', () => {
- mountComponent({ createIssueFromAlertEnabled: true });
- expect(findCreatedIssueBtn().exists()).toBe(true);
- expect(findCreatedIssueBtn().attributes('href')).toBe(newIssuePath);
+ it('should display "View issue" button that links the issue page when issue exists', () => {
+ const issueIid = '3';
+ mountComponent({
+ data: { alert: { ...mockAlert, issueIid } },
});
+ expect(findViewIssueBtn().exists()).toBe(true);
+ expect(findViewIssueBtn().attributes('href')).toBe(joinPaths(projectIssuesPath, issueIid));
+ expect(findCreateIssueBtn().exists()).toBe(false);
});
- describe('createIssueFromAlertEnabled feature flag disabled', () => {
- it('should display a button that links to a new issue page', () => {
- mountComponent({ createIssueFromAlertEnabled: false });
- expect(findCreatedIssueBtn().exists()).toBe(false);
+ it('should display "Create issue" button when issue doesn\'t exist yet', () => {
+ const issueIid = null;
+ mountComponent({
+ mountMethod: mount,
+ data: { alert: { ...mockAlert, issueIid } },
+ });
+ expect(findViewIssueBtn().exists()).toBe(false);
+ expect(findCreateIssueBtn().exists()).toBe(true);
+ });
+
+ it('calls `$apollo.mutate` with `createIssueQuery`', () => {
+ const issueIid = '10';
+ jest
+ .spyOn(wrapper.vm.$apollo, 'mutate')
+ .mockResolvedValue({ data: { createAlertIssue: { issue: { iid: issueIid } } } });
+
+ findCreateIssueBtn().trigger('click');
+ expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({
+ mutation: createIssueQuery,
+ variables: {
+ iid: mockAlert.iid,
+ projectPath,
+ },
+ });
+ });
+
+ it('shows error alert when issue creation fails ', () => {
+ const errorMsg = 'Something went wrong';
+ mountComponent({
+ mountMethod: mount,
+ data: { alert: { ...mockAlert, alertIid: 1 } },
+ });
+
+ jest.spyOn(wrapper.vm.$apollo, 'mutate').mockRejectedValue(errorMsg);
+ findCreateIssueBtn().trigger('click');
+
+ setImmediate(() => {
+ expect(findIssueCreationAlert().text()).toBe(errorMsg);
});
});
});
@@ -171,15 +220,15 @@ describe('AlertDetails', () => {
describe('individual header fields', () => {
describe.each`
- severity | createdAt | monitoringTool | result
- ${'MEDIUM'} | ${'2020-04-17T23:18:14.996Z'} | ${null} | ${'Medium • Reported now'}
- ${'INFO'} | ${'2020-04-17T23:18:14.996Z'} | ${'Datadog'} | ${'Info • Reported now by Datadog'}
+ createdAt | monitoringTool | result
+ ${'2020-04-17T23:18:14.996Z'} | ${null} | ${'Alert Reported now'}
+ ${'2020-04-17T23:18:14.996Z'} | ${'Datadog'} | ${'Alert Reported now by Datadog'}
`(
- `When severity=$severity, createdAt=$createdAt, monitoringTool=$monitoringTool`,
- ({ severity, createdAt, monitoringTool, result }) => {
+ `When createdAt=$createdAt, monitoringTool=$monitoringTool`,
+ ({ createdAt, monitoringTool, result }) => {
beforeEach(() => {
mountComponent({
- data: { alert: { ...mockAlert, severity, createdAt, monitoringTool } },
+ data: { alert: { ...mockAlert, createdAt, monitoringTool } },
mountMethod: mount,
stubs,
});
@@ -194,19 +243,9 @@ describe('AlertDetails', () => {
});
});
- describe('updating the alert status', () => {
- const mockUpdatedMutationResult = {
- data: {
- updateAlertStatus: {
- errors: [],
- alert: {
- status: 'acknowledged',
- },
- },
- },
- };
-
+ describe('Snowplow tracking', () => {
beforeEach(() => {
+ jest.spyOn(Tracking, 'event');
mountComponent({
props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
data: { alert: mockAlert },
@@ -214,29 +253,9 @@ describe('AlertDetails', () => {
});
});
- it('calls `$apollo.mutate` with `updateAlertStatus` mutation and variables containing `iid`, `status`, & `projectPath`', () => {
- jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue(mockUpdatedMutationResult);
- findStatusDropdownItem().vm.$emit('click');
-
- expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({
- mutation: updateAlertStatus,
- variables: {
- iid: 'alertId',
- status: 'TRIGGERED',
- projectPath: 'projectPath',
- },
- });
- });
-
- it('calls `createFlash` when request fails', () => {
- jest.spyOn(wrapper.vm.$apollo, 'mutate').mockReturnValue(Promise.reject(new Error()));
- findStatusDropdownItem().vm.$emit('click');
-
- setImmediate(() => {
- expect(createFlash).toHaveBeenCalledWith(
- 'There was an error while updating the status of the alert. Please try again.',
- );
- });
+ it('should track alert details page views', () => {
+ const { category, action } = trackAlertsDetailsViewsOptions;
+ expect(Tracking.event).toHaveBeenCalledWith(category, action);
});
});
});
diff --git a/spec/frontend/alert_management/components/alert_management_list_spec.js b/spec/frontend/alert_management/components/alert_management_list_spec.js
index c4630ac57fe..0154e5fa112 100644
--- a/spec/frontend/alert_management/components/alert_management_list_spec.js
+++ b/spec/frontend/alert_management/components/alert_management_list_spec.js
@@ -7,15 +7,23 @@ import {
GlDropdown,
GlDropdownItem,
GlIcon,
+ GlTabs,
GlTab,
+ GlBadge,
+ GlPagination,
} from '@gitlab/ui';
import { visitUrl } from '~/lib/utils/url_utility';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import createFlash from '~/flash';
import AlertManagementList from '~/alert_management/components/alert_management_list.vue';
-import { ALERTS_STATUS_TABS } from '../../../../app/assets/javascripts/alert_management/constants';
+import {
+ ALERTS_STATUS_TABS,
+ trackAlertListViewsOptions,
+ trackAlertStatusUpdateOptions,
+} from '~/alert_management/constants';
import updateAlertStatus from '~/alert_management/graphql/mutations/update_alert_status.graphql';
import mockAlerts from '../mocks/alerts.json';
+import Tracking from '~/tracking';
jest.mock('~/flash');
@@ -33,9 +41,21 @@ describe('AlertManagementList', () => {
const findLoader = () => wrapper.find(GlLoadingIcon);
const findStatusDropdown = () => wrapper.find(GlDropdown);
const findStatusFilterTabs = () => wrapper.findAll(GlTab);
+ const findStatusTabs = () => wrapper.find(GlTabs);
+ const findStatusFilterBadge = () => wrapper.findAll(GlBadge);
const findDateFields = () => wrapper.findAll(TimeAgo);
const findFirstStatusOption = () => findStatusDropdown().find(GlDropdownItem);
+ const findAssignees = () => wrapper.findAll('[data-testid="assigneesField"]');
const findSeverityFields = () => wrapper.findAll('[data-testid="severityField"]');
+ const findSeverityColumnHeader = () => wrapper.findAll('th').at(0);
+ const findPagination = () => wrapper.find(GlPagination);
+ const alertsCount = {
+ open: 14,
+ triggered: 10,
+ acknowledged: 6,
+ resolved: 1,
+ all: 16,
+ };
function mountComponent({
props = {
@@ -44,7 +64,6 @@ describe('AlertManagementList', () => {
},
data = {},
loading = false,
- alertListStatusFilteringEnabled = false,
stubs = {},
} = {}) {
wrapper = mount(AlertManagementList, {
@@ -54,17 +73,13 @@ describe('AlertManagementList', () => {
emptyAlertSvgPath: 'illustration/path',
...props,
},
- provide: {
- glFeatures: {
- alertListStatusFilteringEnabled,
- },
- },
data() {
return data;
},
mocks: {
$apollo: {
mutate: jest.fn(),
+ query: jest.fn(),
queries: {
alerts: {
loading,
@@ -86,49 +101,32 @@ describe('AlertManagementList', () => {
}
});
- describe('alert management feature renders empty state', () => {
+ describe('Empty state', () => {
it('shows empty state', () => {
expect(wrapper.find(GlEmptyState).exists()).toBe(true);
});
});
describe('Status Filter Tabs', () => {
- describe('alertListStatusFilteringEnabled feature flag enabled', () => {
- beforeEach(() => {
- mountComponent({
- props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
- data: { alerts: mockAlerts },
- loading: false,
- alertListStatusFilteringEnabled: true,
- stubs: {
- GlTab: true,
- },
- });
- });
-
- it('should display filter tabs for all statuses', () => {
- const tabs = findStatusFilterTabs().wrappers;
- tabs.forEach((tab, i) => {
- expect(tab.text()).toContain(ALERTS_STATUS_TABS[i].title);
- });
+ beforeEach(() => {
+ mountComponent({
+ props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
+ data: { alerts: mockAlerts, alertsCount },
+ loading: false,
+ stubs: {
+ GlTab: true,
+ },
});
});
- describe('alertListStatusFilteringEnabled feature flag disabled', () => {
- beforeEach(() => {
- mountComponent({
- props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
- data: { alerts: mockAlerts },
- loading: false,
- alertListStatusFilteringEnabled: false,
- stubs: {
- GlTab: true,
- },
- });
- });
+ it('should display filter tabs with alerts count badge for each status', () => {
+ const tabs = findStatusFilterTabs().wrappers;
+ const badges = findStatusFilterBadge();
- it('should NOT display tabs', () => {
- expect(findStatusFilterTabs()).not.toExist();
+ tabs.forEach((tab, i) => {
+ const status = ALERTS_STATUS_TABS[i].status.toLowerCase();
+ expect(tab.text()).toContain(ALERTS_STATUS_TABS[i].title);
+ expect(badges.at(i).text()).toContain(alertsCount[status]);
});
});
});
@@ -137,52 +135,72 @@ describe('AlertManagementList', () => {
it('loading state', () => {
mountComponent({
props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
- data: { alerts: null },
+ data: { alerts: {}, alertsCount: null },
loading: true,
});
expect(findAlertsTable().exists()).toBe(true);
expect(findLoader().exists()).toBe(true);
+ expect(
+ findAlerts()
+ .at(0)
+ .classes(),
+ ).not.toContain('gl-hover-bg-blue-50');
});
it('error state', () => {
mountComponent({
props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
- data: { alerts: null, errored: true },
+ data: { alerts: { errors: ['error'] }, alertsCount: null, errored: true },
loading: false,
});
expect(findAlertsTable().exists()).toBe(true);
expect(findAlertsTable().text()).toContain('No alerts to display');
expect(findLoader().exists()).toBe(false);
expect(findAlert().props().variant).toBe('danger');
+ expect(
+ findAlerts()
+ .at(0)
+ .classes(),
+ ).not.toContain('gl-hover-bg-blue-50');
});
it('empty state', () => {
mountComponent({
props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
- data: { alerts: [], errored: false },
+ data: { alerts: { list: [], pageInfo: {} }, alertsCount: { all: 0 }, errored: false },
loading: false,
});
expect(findAlertsTable().exists()).toBe(true);
expect(findAlertsTable().text()).toContain('No alerts to display');
expect(findLoader().exists()).toBe(false);
expect(findAlert().props().variant).toBe('info');
+ expect(
+ findAlerts()
+ .at(0)
+ .classes(),
+ ).not.toContain('gl-hover-bg-blue-50');
});
it('has data state', () => {
mountComponent({
props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
- data: { alerts: mockAlerts, errored: false },
+ data: { alerts: { list: mockAlerts }, alertsCount, errored: false },
loading: false,
});
expect(findLoader().exists()).toBe(false);
expect(findAlertsTable().exists()).toBe(true);
expect(findAlerts()).toHaveLength(mockAlerts.length);
+ expect(
+ findAlerts()
+ .at(0)
+ .classes(),
+ ).toContain('gl-hover-bg-blue-50');
});
it('displays status dropdown', () => {
mountComponent({
props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
- data: { alerts: mockAlerts, errored: false },
+ data: { alerts: { list: mockAlerts }, alertsCount, errored: false },
loading: false,
});
expect(findStatusDropdown().exists()).toBe(true);
@@ -191,7 +209,7 @@ describe('AlertManagementList', () => {
it('shows correct severity icons', () => {
mountComponent({
props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
- data: { alerts: mockAlerts, errored: false },
+ data: { alerts: { list: mockAlerts }, alertsCount, errored: false },
loading: false,
});
@@ -208,7 +226,7 @@ describe('AlertManagementList', () => {
it('renders severity text', () => {
mountComponent({
props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
- data: { alerts: mockAlerts, errored: false },
+ data: { alerts: { list: mockAlerts }, alertsCount, errored: false },
loading: false,
});
@@ -219,10 +237,38 @@ describe('AlertManagementList', () => {
).toBe('Critical');
});
+ it('renders Unassigned when no assignee(s) present', () => {
+ mountComponent({
+ props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
+ data: { alerts: { list: mockAlerts }, alertsCount, errored: false },
+ loading: false,
+ });
+
+ expect(
+ findAssignees()
+ .at(0)
+ .text(),
+ ).toBe('Unassigned');
+ });
+
+ it('renders username(s) when assignee(s) present', () => {
+ mountComponent({
+ props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
+ data: { alerts: { list: mockAlerts }, alertsCount, errored: false },
+ loading: false,
+ });
+
+ expect(
+ findAssignees()
+ .at(1)
+ .text(),
+ ).toBe(mockAlerts[1].assignees.nodes[0].username);
+ });
+
it('navigates to the detail page when alert row is clicked', () => {
mountComponent({
props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
- data: { alerts: mockAlerts, errored: false },
+ data: { alerts: { list: mockAlerts }, alertsCount, errored: false },
loading: false,
});
@@ -237,15 +283,19 @@ describe('AlertManagementList', () => {
mountComponent({
props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
data: {
- alerts: [
- {
- iid: 1,
- status: 'acknowledged',
- startedAt: '2020-03-17T23:18:14.996Z',
- endedAt: '2020-04-17T23:18:14.996Z',
- severity: 'high',
- },
- ],
+ alerts: {
+ list: [
+ {
+ iid: 1,
+ status: 'acknowledged',
+ startedAt: '2020-03-17T23:18:14.996Z',
+ endedAt: '2020-04-17T23:18:14.996Z',
+ severity: 'high',
+ assignees: { nodes: [] },
+ },
+ ],
+ },
+ alertsCount,
errored: false,
},
loading: false,
@@ -266,6 +316,7 @@ describe('AlertManagementList', () => {
severity: 'high',
},
],
+ alertsCount,
errored: false,
},
loading: false,
@@ -275,6 +326,32 @@ describe('AlertManagementList', () => {
});
});
+ describe('sorting the alert list by column', () => {
+ beforeEach(() => {
+ mountComponent({
+ props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
+ data: {
+ alerts: { list: mockAlerts },
+ errored: false,
+ sort: 'STARTED_AT_DESC',
+ alertsCount,
+ },
+ loading: false,
+ stubs: { GlTable },
+ });
+ });
+
+ it('updates sort with new direction and column key', () => {
+ findSeverityColumnHeader().trigger('click');
+
+ expect(wrapper.vm.$data.sort).toBe('SEVERITY_DESC');
+
+ findSeverityColumnHeader().trigger('click');
+
+ expect(wrapper.vm.$data.sort).toBe('SEVERITY_ASC');
+ });
+ });
+
describe('updating the alert status', () => {
const iid = '1527542';
const mockUpdatedMutationResult = {
@@ -292,7 +369,7 @@ describe('AlertManagementList', () => {
beforeEach(() => {
mountComponent({
props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
- data: { alerts: mockAlerts, errored: false },
+ data: { alerts: { list: mockAlerts }, alertsCount, errored: false },
loading: false,
});
});
@@ -322,4 +399,91 @@ describe('AlertManagementList', () => {
});
});
});
+
+ describe('Snowplow tracking', () => {
+ beforeEach(() => {
+ jest.spyOn(Tracking, 'event');
+ mountComponent({
+ props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
+ data: { alerts: { list: mockAlerts }, alertsCount },
+ loading: false,
+ });
+ });
+
+ it('should track alert list page views', () => {
+ const { category, action } = trackAlertListViewsOptions;
+ expect(Tracking.event).toHaveBeenCalledWith(category, action);
+ });
+
+ it('should track alert status updates', () => {
+ Tracking.event.mockClear();
+ jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue({});
+ findFirstStatusOption().vm.$emit('click');
+ const status = findFirstStatusOption().text();
+ setImmediate(() => {
+ const { category, action, label } = trackAlertStatusUpdateOptions;
+ expect(Tracking.event).toHaveBeenCalledWith(category, action, { label, property: status });
+ });
+ });
+ });
+
+ describe('Pagination', () => {
+ beforeEach(() => {
+ mountComponent({
+ props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
+ data: { alerts: { list: mockAlerts, pageInfo: {} }, alertsCount, errored: false },
+ loading: false,
+ });
+ });
+
+ it('does NOT show pagination control when list is smaller than default page size', () => {
+ findStatusTabs().vm.$emit('input', 3);
+ wrapper.vm.$nextTick(() => {
+ expect(findPagination().exists()).toBe(false);
+ });
+ });
+
+ it('shows pagination control when list is larger than default page size', () => {
+ findStatusTabs().vm.$emit('input', 0);
+ wrapper.vm.$nextTick(() => {
+ expect(findPagination().exists()).toBe(true);
+ });
+ });
+
+ describe('prevPage', () => {
+ it('returns prevPage number', () => {
+ findPagination().vm.$emit('input', 3);
+
+ return wrapper.vm.$nextTick(() => {
+ expect(wrapper.vm.prevPage).toBe(2);
+ });
+ });
+
+ it('returns 0 when it is the first page', () => {
+ findPagination().vm.$emit('input', 1);
+
+ return wrapper.vm.$nextTick(() => {
+ expect(wrapper.vm.prevPage).toBe(0);
+ });
+ });
+ });
+
+ describe('nextPage', () => {
+ it('returns nextPage number', () => {
+ findPagination().vm.$emit('input', 1);
+
+ return wrapper.vm.$nextTick(() => {
+ expect(wrapper.vm.nextPage).toBe(2);
+ });
+ });
+
+ it('returns `null` when currentPage is already last page', () => {
+ findStatusTabs().vm.$emit('input', 3);
+ findPagination().vm.$emit('input', 1);
+ return wrapper.vm.$nextTick(() => {
+ expect(wrapper.vm.nextPage).toBeNull();
+ });
+ });
+ });
+ });
});
diff --git a/spec/frontend/alert_management/components/alert_management_system_note_spec.js b/spec/frontend/alert_management/components/alert_management_system_note_spec.js
new file mode 100644
index 00000000000..87dc36cc7cb
--- /dev/null
+++ b/spec/frontend/alert_management/components/alert_management_system_note_spec.js
@@ -0,0 +1,34 @@
+import { shallowMount } from '@vue/test-utils';
+import SystemNote from '~/alert_management/components/system_notes/system_note.vue';
+import mockAlerts from '../mocks/alerts.json';
+
+const mockAlert = mockAlerts[1];
+
+describe('Alert Details System Note', () => {
+ let wrapper;
+
+ function mountComponent({ stubs = {} } = {}) {
+ wrapper = shallowMount(SystemNote, {
+ propsData: {
+ note: { ...mockAlert.notes.nodes[0] },
+ },
+ stubs,
+ });
+ }
+
+ afterEach(() => {
+ if (wrapper) {
+ wrapper.destroy();
+ }
+ });
+
+ describe('System notes', () => {
+ beforeEach(() => {
+ mountComponent({});
+ });
+
+ it('renders the correct system note', () => {
+ expect(wrapper.find('.note-wrapper').attributes('id')).toBe('note_1628');
+ });
+ });
+});
diff --git a/spec/frontend/alert_management/components/alert_managment_sidebar_assignees_spec.js b/spec/frontend/alert_management/components/alert_managment_sidebar_assignees_spec.js
new file mode 100644
index 00000000000..5dbd83dbdac
--- /dev/null
+++ b/spec/frontend/alert_management/components/alert_managment_sidebar_assignees_spec.js
@@ -0,0 +1,133 @@
+import { shallowMount } from '@vue/test-utils';
+import axios from 'axios';
+import MockAdapter from 'axios-mock-adapter';
+import { GlDropdownItem } from '@gitlab/ui';
+import SidebarAssignee from '~/alert_management/components/sidebar/sidebar_assignee.vue';
+import SidebarAssignees from '~/alert_management/components/sidebar/sidebar_assignees.vue';
+import AlertSetAssignees from '~/alert_management/graphql/mutations/alert_set_assignees.graphql';
+import mockAlerts from '../mocks/alerts.json';
+
+const mockAlert = mockAlerts[0];
+
+describe('Alert Details Sidebar Assignees', () => {
+ let wrapper;
+ let mock;
+
+ function mountComponent({
+ data,
+ users = [],
+ isDropdownSearching = false,
+ sidebarCollapsed = true,
+ loading = false,
+ stubs = {},
+ } = {}) {
+ wrapper = shallowMount(SidebarAssignees, {
+ data() {
+ return {
+ users,
+ isDropdownSearching,
+ };
+ },
+ propsData: {
+ alert: { ...mockAlert },
+ ...data,
+ sidebarCollapsed,
+ projectPath: 'projectPath',
+ },
+ mocks: {
+ $apollo: {
+ mutate: jest.fn(),
+ queries: {
+ alert: {
+ loading,
+ },
+ },
+ },
+ },
+ stubs,
+ });
+ }
+
+ afterEach(() => {
+ if (wrapper) {
+ wrapper.destroy();
+ }
+ mock.restore();
+ });
+
+ describe('updating the alert status', () => {
+ const mockUpdatedMutationResult = {
+ data: {
+ updateAlertStatus: {
+ errors: [],
+ alert: {
+ assigneeUsernames: ['root'],
+ },
+ },
+ },
+ };
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ const path = '/autocomplete/users.json';
+ const users = [
+ {
+ avatar_url:
+ 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ id: 1,
+ name: 'User 1',
+ username: 'root',
+ },
+ {
+ avatar_url:
+ 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ id: 2,
+ name: 'User 2',
+ username: 'not-root',
+ },
+ ];
+
+ mock.onGet(path).replyOnce(200, users);
+ mountComponent({
+ data: { alert: mockAlert },
+ sidebarCollapsed: false,
+ loading: false,
+ users,
+ stubs: {
+ SidebarAssignee,
+ },
+ });
+ });
+
+ it('renders a unassigned option', () => {
+ wrapper.setData({ isDropdownSearching: false });
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.find(GlDropdownItem).text()).toBe('Unassigned');
+ });
+ });
+
+ it('calls `$apollo.mutate` with `AlertSetAssignees` mutation and variables containing `iid`, `assigneeUsernames`, & `projectPath`', () => {
+ jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue(mockUpdatedMutationResult);
+ wrapper.setData({ isDropdownSearching: false });
+
+ return wrapper.vm.$nextTick().then(() => {
+ wrapper.find(SidebarAssignee).vm.$emit('update-alert-assignees', 'root');
+
+ expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({
+ mutation: AlertSetAssignees,
+ variables: {
+ iid: '1527542',
+ assigneeUsernames: ['root'],
+ projectPath: 'projectPath',
+ },
+ });
+ });
+ });
+
+ it('stops updating and cancels loading when the request fails', () => {
+ jest.spyOn(wrapper.vm.$apollo, 'mutate').mockReturnValue(Promise.reject(new Error()));
+ wrapper.vm.updateAlertAssignees('root');
+ expect(wrapper.find('[data-testid="unassigned-users"]').text()).toBe('assign yourself');
+ });
+ });
+});
diff --git a/spec/frontend/alert_management/components/alert_sidebar_spec.js b/spec/frontend/alert_management/components/alert_sidebar_spec.js
new file mode 100644
index 00000000000..80c4d9e0650
--- /dev/null
+++ b/spec/frontend/alert_management/components/alert_sidebar_spec.js
@@ -0,0 +1,55 @@
+import { shallowMount, mount } from '@vue/test-utils';
+import axios from 'axios';
+import MockAdapter from 'axios-mock-adapter';
+import AlertSidebar from '~/alert_management/components/alert_sidebar.vue';
+import SidebarAssignees from '~/alert_management/components/sidebar/sidebar_assignees.vue';
+import mockAlerts from '../mocks/alerts.json';
+
+const mockAlert = mockAlerts[0];
+
+describe('Alert Details Sidebar', () => {
+ let wrapper;
+ let mock;
+
+ function mountComponent({
+ sidebarCollapsed = true,
+ mountMethod = shallowMount,
+ stubs = {},
+ alert = {},
+ } = {}) {
+ wrapper = mountMethod(AlertSidebar, {
+ propsData: {
+ alert,
+ sidebarCollapsed,
+ projectPath: 'projectPath',
+ },
+ stubs,
+ });
+ }
+
+ afterEach(() => {
+ if (wrapper) {
+ wrapper.destroy();
+ }
+ mock.restore();
+ });
+
+ describe('the sidebar renders', () => {
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ mountComponent();
+ });
+
+ it('open as default', () => {
+ expect(wrapper.props('sidebarCollapsed')).toBe(true);
+ });
+
+ it('should render side bar assignee dropdown', () => {
+ mountComponent({
+ mountMethod: mount,
+ alert: mockAlert,
+ });
+ expect(wrapper.find(SidebarAssignees).exists()).toBe(true);
+ });
+ });
+});
diff --git a/spec/frontend/alert_management/components/alert_sidebar_status_spec.js b/spec/frontend/alert_management/components/alert_sidebar_status_spec.js
new file mode 100644
index 00000000000..94643966a43
--- /dev/null
+++ b/spec/frontend/alert_management/components/alert_sidebar_status_spec.js
@@ -0,0 +1,107 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlDropdownItem, GlLoadingIcon } from '@gitlab/ui';
+import { trackAlertStatusUpdateOptions } from '~/alert_management/constants';
+import AlertSidebarStatus from '~/alert_management/components/sidebar/sidebar_status.vue';
+import updateAlertStatus from '~/alert_management/graphql/mutations/update_alert_status.graphql';
+import Tracking from '~/tracking';
+import mockAlerts from '../mocks/alerts.json';
+
+const mockAlert = mockAlerts[0];
+
+describe('Alert Details Sidebar Status', () => {
+ let wrapper;
+ const findStatusDropdownItem = () => wrapper.find(GlDropdownItem);
+ const findStatusLoadingIcon = () => wrapper.find(GlLoadingIcon);
+
+ function mountComponent({ data, sidebarCollapsed = true, loading = false, stubs = {} } = {}) {
+ wrapper = shallowMount(AlertSidebarStatus, {
+ propsData: {
+ alert: { ...mockAlert },
+ ...data,
+ sidebarCollapsed,
+ projectPath: 'projectPath',
+ },
+ mocks: {
+ $apollo: {
+ mutate: jest.fn(),
+ queries: {
+ alert: {
+ loading,
+ },
+ },
+ },
+ },
+ stubs,
+ });
+ }
+
+ afterEach(() => {
+ if (wrapper) {
+ wrapper.destroy();
+ }
+ });
+
+ describe('updating the alert status', () => {
+ const mockUpdatedMutationResult = {
+ data: {
+ updateAlertStatus: {
+ errors: [],
+ alert: {
+ status: 'acknowledged',
+ },
+ },
+ },
+ };
+
+ beforeEach(() => {
+ mountComponent({
+ data: { alert: mockAlert },
+ sidebarCollapsed: false,
+ loading: false,
+ });
+ });
+
+ it('calls `$apollo.mutate` with `updateAlertStatus` mutation and variables containing `iid`, `status`, & `projectPath`', () => {
+ jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue(mockUpdatedMutationResult);
+ findStatusDropdownItem().vm.$emit('click');
+
+ expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({
+ mutation: updateAlertStatus,
+ variables: {
+ iid: '1527542',
+ status: 'TRIGGERED',
+ projectPath: 'projectPath',
+ },
+ });
+ });
+
+ it('stops updating when the request fails', () => {
+ jest.spyOn(wrapper.vm.$apollo, 'mutate').mockReturnValue(Promise.reject(new Error()));
+ findStatusDropdownItem().vm.$emit('click');
+ expect(findStatusLoadingIcon().exists()).toBe(false);
+ expect(wrapper.find('[data-testid="status"]').text()).toBe('Triggered');
+ });
+ });
+
+ describe('Snowplow tracking', () => {
+ beforeEach(() => {
+ jest.spyOn(Tracking, 'event');
+ mountComponent({
+ props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
+ data: { alert: mockAlert },
+ loading: false,
+ });
+ });
+
+ it('should track alert status updates', () => {
+ Tracking.event.mockClear();
+ jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue({});
+ findStatusDropdownItem().vm.$emit('click');
+ const status = findStatusDropdownItem().text();
+ setImmediate(() => {
+ const { category, action, label } = trackAlertStatusUpdateOptions;
+ expect(Tracking.event).toHaveBeenCalledWith(category, action, { label, property: status });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/alert_management/mocks/alerts.json b/spec/frontend/alert_management/mocks/alerts.json
index b67e2cfc52e..312d1756790 100644
--- a/spec/frontend/alert_management/mocks/alerts.json
+++ b/spec/frontend/alert_management/mocks/alerts.json
@@ -1,29 +1,66 @@
[
- {
- "iid": "1527542",
- "title": "SyntaxError: Invalid or unexpected token",
- "severity": "CRITICAL",
- "eventCount": 7,
- "startedAt": "2020-04-17T23:18:14.996Z",
- "endedAt": "2020-04-17T23:18:14.996Z",
- "status": "TRIGGERED"
- },
- {
- "iid": "1527543",
- "title": "Some other alert Some other alert Some other alert Some other alert Some other alert Some other alert",
- "severity": "MEDIUM",
- "eventCount": 1,
- "startedAt": "2020-04-17T23:18:14.996Z",
- "endedAt": "2020-04-17T23:18:14.996Z",
- "status": "ACKNOWLEDGED"
- },
- {
- "iid": "1527544",
- "title": "SyntaxError: Invalid or unexpected token",
- "severity": "LOW",
- "eventCount": 4,
- "startedAt": "2020-04-17T23:18:14.996Z",
- "endedAt": "2020-04-17T23:18:14.996Z",
- "status": "RESOLVED"
+ {
+ "iid": "1527542",
+ "title": "SyntaxError: Invalid or unexpected token",
+ "severity": "CRITICAL",
+ "eventCount": 7,
+ "createdAt": "2020-04-17T23:18:14.996Z",
+ "startedAt": "2020-04-17T23:18:14.996Z",
+ "endedAt": "2020-04-17T23:18:14.996Z",
+ "status": "TRIGGERED",
+ "assignees": { "nodes": [] },
+ "notes": { "nodes": [] }
+ },
+ {
+ "iid": "1527543",
+ "title": "Some other alert Some other alert Some other alert Some other alert Some other alert Some other alert",
+ "severity": "MEDIUM",
+ "eventCount": 1,
+ "startedAt": "2020-04-17T23:18:14.996Z",
+ "endedAt": "2020-04-17T23:18:14.996Z",
+ "status": "ACKNOWLEDGED",
+ "assignees": { "nodes": [{ "username": "root" }] },
+ "notes": {
+ "nodes": [
+ {
+ "id": "gid://gitlab/Note/1628",
+ "author": {
+ "id": "gid://gitlab/User/1",
+ "state": "active",
+ "__typename": "User",
+ "avatarUrl": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon",
+ "name": "Administrator",
+ "username": "root",
+ "webUrl": "http://192.168.1.4:3000/root"
+ }
+ }
+ ]
}
- ]
+ },
+ {
+ "iid": "1527544",
+ "title": "SyntaxError: Invalid or unexpected token",
+ "severity": "LOW",
+ "eventCount": 4,
+ "startedAt": "2020-04-17T23:18:14.996Z",
+ "endedAt": "2020-04-17T23:18:14.996Z",
+ "status": "RESOLVED",
+ "assignees": { "nodes": [{ "username": "root" }] },
+ "notes": {
+ "nodes": [
+ {
+ "id": "gid://gitlab/Note/1629",
+ "author": {
+ "id": "gid://gitlab/User/2",
+ "state": "active",
+ "__typename": "User",
+ "avatarUrl": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon",
+ "name": "Administrator",
+ "username": "root",
+ "webUrl": "http://192.168.1.4:3000/root"
+ }
+ }
+ ]
+ }
+ }
+]
diff --git a/spec/frontend/alerts_service_settings/components/__snapshots__/alerts_service_form_spec.js.snap b/spec/frontend/alerts_service_settings/components/__snapshots__/alerts_service_form_spec.js.snap
index 36ec0badade..0d4171a20b3 100644
--- a/spec/frontend/alerts_service_settings/components/__snapshots__/alerts_service_form_spec.js.snap
+++ b/spec/frontend/alerts_service_settings/components/__snapshots__/alerts_service_form_spec.js.snap
@@ -6,4 +6,4 @@ exports[`AlertsServiceForm with default values renders "url" input 1`] = `"<gl-f
exports[`AlertsServiceForm with default values renders toggle button 1`] = `"<toggle-button-stub id=\\"activated\\"></toggle-button-stub>"`;
-exports[`AlertsServiceForm with default values shows description and "Learn More" link 1`] = `"Each alert source must be authorized using the following URL and authorization key. <a href=\\"https://docs.gitlab.com/ee/user/project/integrations/generic_alerts.md\\" target=\\"_blank\\" rel=\\"noopener noreferrer\\">Learn more</a> about configuring this endpoint to receive alerts."`;
+exports[`AlertsServiceForm with default values shows description and docs links 1`] = `"<p><gl-sprintf-stub message=\\"You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page.\\"></gl-sprintf-stub></p><p><gl-sprintf-stub message=\\"Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint.\\"></gl-sprintf-stub></p>"`;
diff --git a/spec/frontend/alerts_service_settings/components/alerts_service_form_spec.js b/spec/frontend/alerts_service_settings/components/alerts_service_form_spec.js
index b7a008c78d0..c7c15c8fd44 100644
--- a/spec/frontend/alerts_service_settings/components/alerts_service_form_spec.js
+++ b/spec/frontend/alerts_service_settings/components/alerts_service_form_spec.js
@@ -12,7 +12,8 @@ const defaultProps = {
initialAuthorizationKey: 'abcedfg123',
formPath: 'http://invalid',
url: 'https://gitlab.com/endpoint-url',
- learnMoreUrl: 'https://docs.gitlab.com/ee/user/project/integrations/generic_alerts.md',
+ alertsSetupUrl: 'http://invalid',
+ alertsUsageUrl: 'http://invalid',
initialActivated: false,
};
@@ -32,7 +33,7 @@ describe('AlertsServiceForm', () => {
const findUrl = () => wrapper.find('#url');
const findAuthorizationKey = () => wrapper.find('#authorization-key');
- const findDescription = () => wrapper.find('p');
+ const findDescription = () => wrapper.find('[data-testid="description"');
const findActiveStatusIcon = val =>
document.querySelector(`.js-service-active-status[data-value=${val.toString()}]`);
@@ -67,7 +68,7 @@ describe('AlertsServiceForm', () => {
expect(wrapper.find(ToggleButton).html()).toMatchSnapshot();
});
- it('shows description and "Learn More" link', () => {
+ it('shows description and docs links', () => {
expect(findDescription().element.innerHTML).toMatchSnapshot();
});
});
diff --git a/spec/frontend/api_spec.js b/spec/frontend/api_spec.js
index d365048ab0b..c1a23d441b3 100644
--- a/spec/frontend/api_spec.js
+++ b/spec/frontend/api_spec.js
@@ -691,4 +691,60 @@ describe('Api', () => {
});
});
});
+
+ describe('updateIssue', () => {
+ it('update an issue with the given payload', done => {
+ const projectId = 8;
+ const issue = 1;
+ const expectedArray = [1, 2, 3];
+ const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${projectId}/issues/${issue}`;
+ mock.onPut(expectedUrl).reply(200, { assigneeIds: expectedArray });
+
+ Api.updateIssue(projectId, issue, { assigneeIds: expectedArray })
+ .then(({ data }) => {
+ expect(data.assigneeIds).toEqual(expectedArray);
+ done();
+ })
+ .catch(done.fail);
+ });
+ });
+
+ describe('updateMergeRequest', () => {
+ it('update an issue with the given payload', done => {
+ const projectId = 8;
+ const mergeRequest = 1;
+ const expectedArray = [1, 2, 3];
+ const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${projectId}/merge_requests/${mergeRequest}`;
+ mock.onPut(expectedUrl).reply(200, { assigneeIds: expectedArray });
+
+ Api.updateMergeRequest(projectId, mergeRequest, { assigneeIds: expectedArray })
+ .then(({ data }) => {
+ expect(data.assigneeIds).toEqual(expectedArray);
+ done();
+ })
+ .catch(done.fail);
+ });
+ });
+
+ describe('tags', () => {
+ it('fetches all tags of a particular project', done => {
+ const query = 'dummy query';
+ const options = { unused: 'option' };
+ const projectId = 8;
+ const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${projectId}/repository/tags`;
+ mock.onGet(expectedUrl).reply(200, [
+ {
+ name: 'test',
+ },
+ ]);
+
+ Api.tags(projectId, query, options)
+ .then(({ data }) => {
+ expect(data.length).toBe(1);
+ expect(data[0].name).toBe('test');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
});
diff --git a/spec/frontend/authentication/u2f/authenticate_spec.js b/spec/frontend/authentication/u2f/authenticate_spec.js
new file mode 100644
index 00000000000..8abef2ae1b2
--- /dev/null
+++ b/spec/frontend/authentication/u2f/authenticate_spec.js
@@ -0,0 +1,109 @@
+import $ from 'jquery';
+import U2FAuthenticate from '~/authentication/u2f/authenticate';
+import 'vendor/u2f';
+import MockU2FDevice from './mock_u2f_device';
+
+describe('U2FAuthenticate', () => {
+ let u2fDevice;
+ let container;
+ let component;
+
+ preloadFixtures('u2f/authenticate.html');
+
+ beforeEach(() => {
+ loadFixtures('u2f/authenticate.html');
+ u2fDevice = new MockU2FDevice();
+ container = $('#js-authenticate-token-2fa');
+ component = new U2FAuthenticate(
+ container,
+ '#js-login-token-2fa-form',
+ {
+ sign_requests: [],
+ },
+ document.querySelector('#js-login-2fa-device'),
+ document.querySelector('.js-2fa-form'),
+ );
+ });
+
+ describe('with u2f unavailable', () => {
+ let oldu2f;
+
+ beforeEach(() => {
+ jest.spyOn(component, 'switchToFallbackUI').mockImplementation(() => {});
+ oldu2f = window.u2f;
+ window.u2f = null;
+ });
+
+ afterEach(() => {
+ window.u2f = oldu2f;
+ });
+
+ it('falls back to normal 2fa', done => {
+ component
+ .start()
+ .then(() => {
+ expect(component.switchToFallbackUI).toHaveBeenCalled();
+ done();
+ })
+ .catch(done.fail);
+ });
+ });
+
+ describe('with u2f available', () => {
+ beforeEach(done => {
+ // bypass automatic form submission within renderAuthenticated
+ jest.spyOn(component, 'renderAuthenticated').mockReturnValue(true);
+ u2fDevice = new MockU2FDevice();
+
+ component
+ .start()
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('allows authenticating via a U2F device', () => {
+ const inProgressMessage = container.find('p');
+
+ expect(inProgressMessage.text()).toContain('Trying to communicate with your device');
+ u2fDevice.respondToAuthenticateRequest({
+ deviceData: 'this is data from the device',
+ });
+
+ expect(component.renderAuthenticated).toHaveBeenCalledWith(
+ '{"deviceData":"this is data from the device"}',
+ );
+ });
+
+ describe('errors', () => {
+ it('displays an error message', () => {
+ const setupButton = container.find('#js-login-u2f-device');
+ setupButton.trigger('click');
+ u2fDevice.respondToAuthenticateRequest({
+ errorCode: 'error!',
+ });
+ const errorMessage = container.find('p');
+
+ expect(errorMessage.text()).toContain('There was a problem communicating with your device');
+ });
+
+ it('allows retrying authentication after an error', () => {
+ let setupButton = container.find('#js-login-u2f-device');
+ setupButton.trigger('click');
+ u2fDevice.respondToAuthenticateRequest({
+ errorCode: 'error!',
+ });
+ const retryButton = container.find('#js-token-2fa-try-again');
+ retryButton.trigger('click');
+ setupButton = container.find('#js-login-u2f-device');
+ setupButton.trigger('click');
+ u2fDevice.respondToAuthenticateRequest({
+ deviceData: 'this is data from the device',
+ });
+
+ expect(component.renderAuthenticated).toHaveBeenCalledWith(
+ '{"deviceData":"this is data from the device"}',
+ );
+ });
+ });
+ });
+});
diff --git a/spec/frontend/u2f/mock_u2f_device.js b/spec/frontend/authentication/u2f/mock_u2f_device.js
index ec8425a4e3e..ec8425a4e3e 100644
--- a/spec/frontend/u2f/mock_u2f_device.js
+++ b/spec/frontend/authentication/u2f/mock_u2f_device.js
diff --git a/spec/frontend/authentication/u2f/register_spec.js b/spec/frontend/authentication/u2f/register_spec.js
new file mode 100644
index 00000000000..3c2ecdbba66
--- /dev/null
+++ b/spec/frontend/authentication/u2f/register_spec.js
@@ -0,0 +1,83 @@
+import $ from 'jquery';
+import U2FRegister from '~/authentication/u2f/register';
+import 'vendor/u2f';
+import MockU2FDevice from './mock_u2f_device';
+
+describe('U2FRegister', () => {
+ let u2fDevice;
+ let container;
+ let component;
+
+ preloadFixtures('u2f/register.html');
+
+ beforeEach(done => {
+ loadFixtures('u2f/register.html');
+ u2fDevice = new MockU2FDevice();
+ container = $('#js-register-u2f');
+ component = new U2FRegister(container, $('#js-register-u2f-templates'), {}, 'token');
+ component
+ .start()
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('allows registering a U2F device', () => {
+ const setupButton = container.find('#js-setup-u2f-device');
+
+ expect(setupButton.text()).toBe('Set up new U2F device');
+ setupButton.trigger('click');
+ const inProgressMessage = container.children('p');
+
+ expect(inProgressMessage.text()).toContain('Trying to communicate with your device');
+ u2fDevice.respondToRegisterRequest({
+ deviceData: 'this is data from the device',
+ });
+ const registeredMessage = container.find('p');
+ const deviceResponse = container.find('#js-device-response');
+
+ expect(registeredMessage.text()).toContain('Your device was successfully set up!');
+ expect(deviceResponse.val()).toBe('{"deviceData":"this is data from the device"}');
+ });
+
+ describe('errors', () => {
+ it("doesn't allow the same device to be registered twice (for the same user", () => {
+ const setupButton = container.find('#js-setup-u2f-device');
+ setupButton.trigger('click');
+ u2fDevice.respondToRegisterRequest({
+ errorCode: 4,
+ });
+ const errorMessage = container.find('p');
+
+ expect(errorMessage.text()).toContain('already been registered with us');
+ });
+
+ it('displays an error message for other errors', () => {
+ const setupButton = container.find('#js-setup-u2f-device');
+ setupButton.trigger('click');
+ u2fDevice.respondToRegisterRequest({
+ errorCode: 'error!',
+ });
+ const errorMessage = container.find('p');
+
+ expect(errorMessage.text()).toContain('There was a problem communicating with your device');
+ });
+
+ it('allows retrying registration after an error', () => {
+ let setupButton = container.find('#js-setup-u2f-device');
+ setupButton.trigger('click');
+ u2fDevice.respondToRegisterRequest({
+ errorCode: 'error!',
+ });
+ const retryButton = container.find('#U2FTryAgain');
+ retryButton.trigger('click');
+ setupButton = container.find('#js-setup-u2f-device');
+ setupButton.trigger('click');
+ u2fDevice.respondToRegisterRequest({
+ deviceData: 'this is data from the device',
+ });
+ const registeredMessage = container.find('p');
+
+ expect(registeredMessage.text()).toContain('Your device was successfully set up!');
+ });
+ });
+});
diff --git a/spec/frontend/authentication/u2f/util_spec.js b/spec/frontend/authentication/u2f/util_spec.js
new file mode 100644
index 00000000000..67fd4c73243
--- /dev/null
+++ b/spec/frontend/authentication/u2f/util_spec.js
@@ -0,0 +1,61 @@
+import { canInjectU2fApi } from '~/authentication/u2f/util';
+
+describe('U2F Utils', () => {
+ describe('canInjectU2fApi', () => {
+ it('returns false for Chrome < 41', () => {
+ const userAgent =
+ 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.28 Safari/537.36';
+
+ expect(canInjectU2fApi(userAgent)).toBe(false);
+ });
+
+ it('returns true for Chrome >= 41', () => {
+ const userAgent =
+ 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36';
+
+ expect(canInjectU2fApi(userAgent)).toBe(true);
+ });
+
+ it('returns false for Opera < 40', () => {
+ const userAgent =
+ 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36 OPR/32.0.1948.25';
+
+ expect(canInjectU2fApi(userAgent)).toBe(false);
+ });
+
+ it('returns true for Opera >= 40', () => {
+ const userAgent =
+ 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 OPR/43.0.2442.991';
+
+ expect(canInjectU2fApi(userAgent)).toBe(true);
+ });
+
+ it('returns false for Safari', () => {
+ const userAgent =
+ 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/603.2.4 (KHTML, like Gecko) Version/10.1.1 Safari/603.2.4';
+
+ expect(canInjectU2fApi(userAgent)).toBe(false);
+ });
+
+ it('returns false for Chrome on Android', () => {
+ const userAgent =
+ 'Mozilla/5.0 (Linux; Android 7.0; VS988 Build/NRD90U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3145.0 Mobile Safari/537.36';
+
+ expect(canInjectU2fApi(userAgent)).toBe(false);
+ });
+
+ it('returns false for Chrome on iOS', () => {
+ const userAgent =
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1';
+
+ expect(canInjectU2fApi(userAgent)).toBe(false);
+ });
+
+ it('returns false for Safari on iOS', () => {
+ const userAgent =
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A356 Safari/604.1';
+
+ expect(canInjectU2fApi(userAgent)).toBe(false);
+ });
+ });
+});
diff --git a/spec/frontend/awards_handler_spec.js b/spec/frontend/awards_handler_spec.js
new file mode 100644
index 00000000000..754f0702b84
--- /dev/null
+++ b/spec/frontend/awards_handler_spec.js
@@ -0,0 +1,403 @@
+import $ from 'jquery';
+import Cookies from 'js-cookie';
+import loadAwardsHandler from '~/awards_handler';
+import '~/lib/utils/common_utils';
+import waitForPromises from './helpers/wait_for_promises';
+
+window.gl = window.gl || {};
+window.gon = window.gon || {};
+
+let openAndWaitForEmojiMenu;
+let awardsHandler = null;
+const urlRoot = gon.relative_url_root;
+
+const lazyAssert = (done, assertFn) => {
+ jest.runOnlyPendingTimers();
+ waitForPromises()
+ .then(() => {
+ assertFn();
+ done();
+ })
+ .catch(e => {
+ throw e;
+ });
+};
+
+describe('AwardsHandler', () => {
+ preloadFixtures('snippets/show.html');
+ beforeEach(done => {
+ loadFixtures('snippets/show.html');
+ loadAwardsHandler(true)
+ .then(obj => {
+ awardsHandler = obj;
+ jest.spyOn(awardsHandler, 'postEmoji').mockImplementation((button, url, emoji, cb) => cb());
+ done();
+ })
+ .catch(done.fail);
+
+ let isEmojiMenuBuilt = false;
+ openAndWaitForEmojiMenu = () => {
+ return new Promise(resolve => {
+ if (isEmojiMenuBuilt) {
+ resolve();
+ } else {
+ $('.js-add-award')
+ .eq(0)
+ .click();
+ const $menu = $('.emoji-menu');
+ $menu.one('build-emoji-menu-finish', () => {
+ isEmojiMenuBuilt = true;
+ resolve();
+ });
+ }
+ });
+ };
+ });
+
+ afterEach(() => {
+ // restore original url root value
+ gon.relative_url_root = urlRoot;
+
+ // Undo what we did to the shared <body>
+ $('body').removeAttr('data-page');
+
+ awardsHandler.destroy();
+ });
+
+ describe('::showEmojiMenu', () => {
+ it('should show emoji menu when Add emoji button clicked', done => {
+ $('.js-add-award')
+ .eq(0)
+ .click();
+ lazyAssert(done, () => {
+ const $emojiMenu = $('.emoji-menu');
+
+ expect($emojiMenu.length).toBe(1);
+ expect($emojiMenu.hasClass('is-visible')).toBe(true);
+ expect($emojiMenu.find('.js-emoji-menu-search').length).toBe(1);
+ expect($('.js-awards-block.current').length).toBe(1);
+ });
+ });
+
+ it('should also show emoji menu for the smiley icon in notes', done => {
+ $('.js-add-award.note-action-button').click();
+ lazyAssert(done, () => {
+ const $emojiMenu = $('.emoji-menu');
+
+ expect($emojiMenu.length).toBe(1);
+ });
+ });
+
+ it('should remove emoji menu when body is clicked', done => {
+ $('.js-add-award')
+ .eq(0)
+ .click();
+ lazyAssert(done, () => {
+ const $emojiMenu = $('.emoji-menu');
+ $('body').click();
+
+ expect($emojiMenu.length).toBe(1);
+ expect($emojiMenu.hasClass('is-visible')).toBe(false);
+ expect($('.js-awards-block.current').length).toBe(0);
+ });
+ });
+
+ it('should not remove emoji menu when search is clicked', done => {
+ $('.js-add-award')
+ .eq(0)
+ .click();
+ lazyAssert(done, () => {
+ const $emojiMenu = $('.emoji-menu');
+ $('.emoji-search').click();
+
+ expect($emojiMenu.length).toBe(1);
+ expect($emojiMenu.hasClass('is-visible')).toBe(true);
+ expect($('.js-awards-block.current').length).toBe(1);
+ });
+ });
+ });
+
+ describe('::addAwardToEmojiBar', () => {
+ it('should add emoji to votes block', () => {
+ const $votesBlock = $('.js-awards-block').eq(0);
+ awardsHandler.addAwardToEmojiBar($votesBlock, 'heart', false);
+ const $emojiButton = $votesBlock.find('[data-name=heart]');
+
+ expect($emojiButton.length).toBe(1);
+ expect($emojiButton.next('.js-counter').text()).toBe('1');
+ expect($votesBlock.hasClass('hidden')).toBe(false);
+ });
+
+ it('should remove the emoji when we click again', () => {
+ const $votesBlock = $('.js-awards-block').eq(0);
+ awardsHandler.addAwardToEmojiBar($votesBlock, 'heart', false);
+ awardsHandler.addAwardToEmojiBar($votesBlock, 'heart', false);
+ const $emojiButton = $votesBlock.find('[data-name=heart]');
+
+ expect($emojiButton.length).toBe(0);
+ });
+
+ it('should decrement the emoji counter', () => {
+ const $votesBlock = $('.js-awards-block').eq(0);
+ awardsHandler.addAwardToEmojiBar($votesBlock, 'heart', false);
+ const $emojiButton = $votesBlock.find('[data-name=heart]');
+ $emojiButton.next('.js-counter').text(5);
+ awardsHandler.addAwardToEmojiBar($votesBlock, 'heart', false);
+
+ expect($emojiButton.length).toBe(1);
+ expect($emojiButton.next('.js-counter').text()).toBe('4');
+ });
+ });
+
+ describe('::userAuthored', () => {
+ it('should update tooltip to user authored title', () => {
+ const $votesBlock = $('.js-awards-block').eq(0);
+ const $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
+ $thumbsUpEmoji.attr('data-title', 'sam');
+ awardsHandler.userAuthored($thumbsUpEmoji);
+
+ expect($thumbsUpEmoji.data('originalTitle')).toBe(
+ 'You cannot vote on your own issue, MR and note',
+ );
+ });
+
+ it('should restore tooltip back to initial vote list', () => {
+ const $votesBlock = $('.js-awards-block').eq(0);
+ const $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
+ $thumbsUpEmoji.attr('data-title', 'sam');
+ awardsHandler.userAuthored($thumbsUpEmoji);
+ jest.advanceTimersByTime(2801);
+
+ expect($thumbsUpEmoji.data('originalTitle')).toBe('sam');
+ });
+ });
+
+ describe('::getAwardUrl', () => {
+ it('returns the url for request', () => {
+ expect(awardsHandler.getAwardUrl()).toBe('http://test.host/snippets/1/toggle_award_emoji');
+ });
+ });
+
+ describe('::addAward and ::checkMutuality', () => {
+ it('should handle :+1: and :-1: mutuality', () => {
+ const awardUrl = awardsHandler.getAwardUrl();
+ const $votesBlock = $('.js-awards-block').eq(0);
+ const $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
+ const $thumbsDownEmoji = $votesBlock.find('[data-name=thumbsdown]').parent();
+ awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false);
+
+ expect($thumbsUpEmoji.hasClass('active')).toBe(true);
+ expect($thumbsDownEmoji.hasClass('active')).toBe(false);
+ $thumbsUpEmoji.tooltip();
+ $thumbsDownEmoji.tooltip();
+ awardsHandler.addAward($votesBlock, awardUrl, 'thumbsdown', true);
+
+ expect($thumbsUpEmoji.hasClass('active')).toBe(false);
+ expect($thumbsDownEmoji.hasClass('active')).toBe(true);
+ });
+ });
+
+ describe('::removeEmoji', () => {
+ it('should remove emoji', () => {
+ const awardUrl = awardsHandler.getAwardUrl();
+ const $votesBlock = $('.js-awards-block').eq(0);
+ awardsHandler.addAward($votesBlock, awardUrl, 'fire', false);
+
+ expect($votesBlock.find('[data-name=fire]').length).toBe(1);
+ awardsHandler.removeEmoji($votesBlock.find('[data-name=fire]').closest('button'));
+
+ expect($votesBlock.find('[data-name=fire]').length).toBe(0);
+ });
+ });
+
+ describe('::addYouToUserList', () => {
+ it('should prepend "You" to the award tooltip', () => {
+ const awardUrl = awardsHandler.getAwardUrl();
+ const $votesBlock = $('.js-awards-block').eq(0);
+ const $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
+ $thumbsUpEmoji.attr('data-title', 'sam, jerry, max, and andy');
+ awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false);
+ $thumbsUpEmoji.tooltip();
+
+ expect($thumbsUpEmoji.data('originalTitle')).toBe('You, sam, jerry, max, and andy');
+ });
+
+ it('handles the special case where "You" is not cleanly comma separated', () => {
+ const awardUrl = awardsHandler.getAwardUrl();
+ const $votesBlock = $('.js-awards-block').eq(0);
+ const $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
+ $thumbsUpEmoji.attr('data-title', 'sam');
+ awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false);
+ $thumbsUpEmoji.tooltip();
+
+ expect($thumbsUpEmoji.data('originalTitle')).toBe('You and sam');
+ });
+ });
+
+ describe('::removeYouToUserList', () => {
+ it('removes "You" from the front of the tooltip', () => {
+ const awardUrl = awardsHandler.getAwardUrl();
+ const $votesBlock = $('.js-awards-block').eq(0);
+ const $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
+ $thumbsUpEmoji.attr('data-title', 'You, sam, jerry, max, and andy');
+ $thumbsUpEmoji.addClass('active');
+ awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false);
+ $thumbsUpEmoji.tooltip();
+
+ expect($thumbsUpEmoji.data('originalTitle')).toBe('sam, jerry, max, and andy');
+ });
+
+ it('handles the special case where "You" is not cleanly comma separated', () => {
+ const awardUrl = awardsHandler.getAwardUrl();
+ const $votesBlock = $('.js-awards-block').eq(0);
+ const $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
+ $thumbsUpEmoji.attr('data-title', 'You and sam');
+ $thumbsUpEmoji.addClass('active');
+ awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false);
+ $thumbsUpEmoji.tooltip();
+
+ expect($thumbsUpEmoji.data('originalTitle')).toBe('sam');
+ });
+ });
+
+ describe('::searchEmojis', () => {
+ it('should filter the emoji', done => {
+ openAndWaitForEmojiMenu()
+ .then(() => {
+ expect($('[data-name=angel]').is(':visible')).toBe(true);
+ expect($('[data-name=anger]').is(':visible')).toBe(true);
+ awardsHandler.searchEmojis('ali');
+
+ expect($('[data-name=angel]').is(':visible')).toBe(false);
+ expect($('[data-name=anger]').is(':visible')).toBe(false);
+ expect($('[data-name=alien]').is(':visible')).toBe(true);
+ expect($('.js-emoji-menu-search').val()).toBe('ali');
+ })
+ .then(done)
+ .catch(err => {
+ done.fail(`Failed to open and build emoji menu: ${err.message}`);
+ });
+ });
+
+ it('should clear the search when searching for nothing', done => {
+ openAndWaitForEmojiMenu()
+ .then(() => {
+ awardsHandler.searchEmojis('ali');
+
+ expect($('[data-name=angel]').is(':visible')).toBe(false);
+ expect($('[data-name=anger]').is(':visible')).toBe(false);
+ expect($('[data-name=alien]').is(':visible')).toBe(true);
+ awardsHandler.searchEmojis('');
+
+ expect($('[data-name=angel]').is(':visible')).toBe(true);
+ expect($('[data-name=anger]').is(':visible')).toBe(true);
+ expect($('[data-name=alien]').is(':visible')).toBe(true);
+ expect($('.js-emoji-menu-search').val()).toBe('');
+ })
+ .then(done)
+ .catch(err => {
+ done.fail(`Failed to open and build emoji menu: ${err.message}`);
+ });
+ });
+ });
+
+ describe('emoji menu', () => {
+ const emojiSelector = '[data-name="sunglasses"]';
+ const openEmojiMenuAndAddEmoji = () => {
+ return openAndWaitForEmojiMenu().then(() => {
+ const $menu = $('.emoji-menu');
+ const $block = $('.js-awards-block');
+ const $emoji = $menu.find(`.emoji-menu-list:not(.frequent-emojis) ${emojiSelector}`);
+
+ expect($emoji.length).toBe(1);
+ expect($block.find(emojiSelector).length).toBe(0);
+ $emoji.click();
+
+ expect($menu.hasClass('.is-visible')).toBe(false);
+ expect($block.find(emojiSelector).length).toBe(1);
+ });
+ };
+
+ it('should add selected emoji to awards block', done => {
+ openEmojiMenuAndAddEmoji()
+ .then(done)
+ .catch(err => {
+ done.fail(`Failed to open and build emoji menu: ${err.message}`);
+ });
+ });
+
+ it('should remove already selected emoji', done => {
+ openEmojiMenuAndAddEmoji()
+ .then(() => {
+ $('.js-add-award')
+ .eq(0)
+ .click();
+ const $block = $('.js-awards-block');
+ const $emoji = $('.emoji-menu').find(
+ `.emoji-menu-list:not(.frequent-emojis) ${emojiSelector}`,
+ );
+ $emoji.click();
+
+ expect($block.find(emojiSelector).length).toBe(0);
+ })
+ .then(done)
+ .catch(err => {
+ done.fail(`Failed to open and build emoji menu: ${err.message}`);
+ });
+ });
+ });
+
+ describe('frequently used emojis', () => {
+ beforeEach(() => {
+ // Clear it out
+ Cookies.set('frequently_used_emojis', '');
+ });
+
+ it('shouldn\'t have any "Frequently used" heading if no frequently used emojis', done => {
+ return openAndWaitForEmojiMenu()
+ .then(() => {
+ const emojiMenu = document.querySelector('.emoji-menu');
+ Array.prototype.forEach.call(emojiMenu.querySelectorAll('.emoji-menu-title'), title => {
+ expect(title.textContent.trim().toLowerCase()).not.toBe('frequently used');
+ });
+ })
+ .then(done)
+ .catch(err => {
+ done.fail(`Failed to open and build emoji menu: ${err.message}`);
+ });
+ });
+
+ it('should have any frequently used section when there are frequently used emojis', done => {
+ awardsHandler.addEmojiToFrequentlyUsedList('8ball');
+
+ return openAndWaitForEmojiMenu()
+ .then(() => {
+ const emojiMenu = document.querySelector('.emoji-menu');
+ const hasFrequentlyUsedHeading = Array.prototype.some.call(
+ emojiMenu.querySelectorAll('.emoji-menu-title'),
+ title => title.textContent.trim().toLowerCase() === 'frequently used',
+ );
+
+ expect(hasFrequentlyUsedHeading).toBe(true);
+ })
+ .then(done)
+ .catch(err => {
+ done.fail(`Failed to open and build emoji menu: ${err.message}`);
+ });
+ });
+
+ it('should disregard invalid frequently used emoji that are being attempted to be added', () => {
+ awardsHandler.addEmojiToFrequentlyUsedList('8ball');
+ awardsHandler.addEmojiToFrequentlyUsedList('invalid_emoji');
+ awardsHandler.addEmojiToFrequentlyUsedList('grinning');
+
+ expect(awardsHandler.getFrequentlyUsedEmojis()).toEqual(['8ball', 'grinning']);
+ });
+
+ it('should disregard invalid frequently used emoji already set in cookie', () => {
+ Cookies.set('frequently_used_emojis', '8ball,invalid_emoji,grinning');
+
+ expect(awardsHandler.getFrequentlyUsedEmojis()).toEqual(['8ball', 'grinning']);
+ });
+ });
+});
diff --git a/spec/frontend/batch_comments/components/diff_file_drafts_spec.js b/spec/frontend/batch_comments/components/diff_file_drafts_spec.js
new file mode 100644
index 00000000000..6e0b61db9fa
--- /dev/null
+++ b/spec/frontend/batch_comments/components/diff_file_drafts_spec.js
@@ -0,0 +1,61 @@
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import Vuex from 'vuex';
+import DiffFileDrafts from '~/batch_comments/components/diff_file_drafts.vue';
+import DraftNote from '~/batch_comments/components/draft_note.vue';
+
+const localVue = createLocalVue();
+
+localVue.use(Vuex);
+
+describe('Batch comments diff file drafts component', () => {
+ let vm;
+
+ function factory() {
+ const store = new Vuex.Store({
+ modules: {
+ batchComments: {
+ namespaced: true,
+ getters: {
+ draftsForFile: () => () => [{ id: 1 }, { id: 2 }],
+ },
+ },
+ },
+ });
+
+ vm = shallowMount(localVue.extend(DiffFileDrafts), {
+ store,
+ localVue,
+ propsData: { fileHash: 'filehash' },
+ });
+ }
+
+ afterEach(() => {
+ vm.destroy();
+ });
+
+ it('renders list of draft notes', () => {
+ factory();
+
+ expect(vm.findAll(DraftNote).length).toEqual(2);
+ });
+
+ it('renders index of draft note', () => {
+ factory();
+
+ expect(vm.findAll('.js-diff-notes-index').length).toEqual(2);
+
+ expect(
+ vm
+ .findAll('.js-diff-notes-index')
+ .at(0)
+ .text(),
+ ).toEqual('1');
+
+ expect(
+ vm
+ .findAll('.js-diff-notes-index')
+ .at(1)
+ .text(),
+ ).toEqual('2');
+ });
+});
diff --git a/spec/frontend/batch_comments/components/draft_note_spec.js b/spec/frontend/batch_comments/components/draft_note_spec.js
new file mode 100644
index 00000000000..eea7f25dbc1
--- /dev/null
+++ b/spec/frontend/batch_comments/components/draft_note_spec.js
@@ -0,0 +1,125 @@
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import DraftNote from '~/batch_comments/components/draft_note.vue';
+import { createStore } from '~/batch_comments/stores';
+import NoteableNote from '~/notes/components/noteable_note.vue';
+import '~/behaviors/markdown/render_gfm';
+import { createDraft } from '../mock_data';
+
+const localVue = createLocalVue();
+
+describe('Batch comments draft note component', () => {
+ let wrapper;
+ let draft;
+
+ beforeEach(() => {
+ const store = createStore();
+
+ draft = createDraft();
+
+ wrapper = shallowMount(localVue.extend(DraftNote), {
+ store,
+ propsData: { draft },
+ localVue,
+ });
+
+ jest.spyOn(wrapper.vm.$store, 'dispatch').mockImplementation();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders template', () => {
+ expect(wrapper.find('.draft-pending-label').exists()).toBe(true);
+
+ const note = wrapper.find(NoteableNote);
+
+ expect(note.exists()).toBe(true);
+ expect(note.props().note).toEqual(draft);
+ });
+
+ describe('add comment now', () => {
+ it('dispatches publishSingleDraft when clicking', () => {
+ const publishNowButton = wrapper.find({ ref: 'publishNowButton' });
+ publishNowButton.vm.$emit('click');
+
+ expect(wrapper.vm.$store.dispatch).toHaveBeenCalledWith(
+ 'batchComments/publishSingleDraft',
+ 1,
+ );
+ });
+
+ it('sets as loading when draft is publishing', done => {
+ wrapper.vm.$store.state.batchComments.currentlyPublishingDrafts.push(1);
+
+ wrapper.vm.$nextTick(() => {
+ const publishNowButton = wrapper.find({ ref: 'publishNowButton' });
+
+ expect(publishNowButton.props().loading).toBe(true);
+
+ done();
+ });
+ });
+ });
+
+ describe('update', () => {
+ it('dispatches updateDraft', done => {
+ const note = wrapper.find(NoteableNote);
+
+ note.vm.$emit('handleEdit');
+
+ wrapper.vm
+ .$nextTick()
+ .then(() => {
+ const formData = {
+ note: draft,
+ noteText: 'a',
+ resolveDiscussion: false,
+ };
+
+ note.vm.$emit('handleUpdateNote', formData);
+
+ expect(wrapper.vm.$store.dispatch).toHaveBeenCalledWith(
+ 'batchComments/updateDraft',
+ formData,
+ );
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('deleteDraft', () => {
+ it('dispatches deleteDraft', () => {
+ jest.spyOn(window, 'confirm').mockImplementation(() => true);
+
+ const note = wrapper.find(NoteableNote);
+
+ note.vm.$emit('handleDeleteNote', draft);
+
+ expect(wrapper.vm.$store.dispatch).toHaveBeenCalledWith('batchComments/deleteDraft', draft);
+ });
+ });
+
+ describe('quick actions', () => {
+ it('renders referenced commands', done => {
+ wrapper.setProps({
+ draft: {
+ ...draft,
+ references: {
+ commands: 'test command',
+ },
+ },
+ });
+
+ wrapper.vm.$nextTick(() => {
+ const referencedCommands = wrapper.find('.referenced-commands');
+
+ expect(referencedCommands.exists()).toBe(true);
+ expect(referencedCommands.text()).toContain('test command');
+
+ done();
+ });
+ });
+ });
+});
diff --git a/spec/frontend/batch_comments/components/drafts_count_spec.js b/spec/frontend/batch_comments/components/drafts_count_spec.js
new file mode 100644
index 00000000000..9d9fffce7e7
--- /dev/null
+++ b/spec/frontend/batch_comments/components/drafts_count_spec.js
@@ -0,0 +1,43 @@
+import Vue from 'vue';
+import DraftsCount from '~/batch_comments/components/drafts_count.vue';
+import { mountComponentWithStore } from 'helpers/vue_mount_component_helper';
+import { createStore } from '~/batch_comments/stores';
+
+describe('Batch comments drafts count component', () => {
+ let vm;
+ let Component;
+
+ beforeAll(() => {
+ Component = Vue.extend(DraftsCount);
+ });
+
+ beforeEach(() => {
+ const store = createStore();
+
+ store.state.batchComments.drafts.push('comment');
+
+ vm = mountComponentWithStore(Component, { store });
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('renders count', () => {
+ expect(vm.$el.querySelector('.drafts-count-number').textContent).toBe('1');
+ });
+
+ it('renders screen reader text', done => {
+ const el = vm.$el.querySelector('.sr-only');
+
+ expect(el.textContent).toContain('draft');
+
+ vm.$store.state.batchComments.drafts.push('comment 2');
+
+ vm.$nextTick(() => {
+ expect(el.textContent).toContain('drafts');
+
+ done();
+ });
+ });
+});
diff --git a/spec/frontend/batch_comments/components/preview_item_spec.js b/spec/frontend/batch_comments/components/preview_item_spec.js
new file mode 100644
index 00000000000..7d951fd7799
--- /dev/null
+++ b/spec/frontend/batch_comments/components/preview_item_spec.js
@@ -0,0 +1,130 @@
+import Vue from 'vue';
+import PreviewItem from '~/batch_comments/components/preview_item.vue';
+import { mountComponentWithStore } from 'helpers/vue_mount_component_helper';
+import { createStore } from '~/batch_comments/stores';
+import diffsModule from '~/diffs/store/modules';
+import notesModule from '~/notes/stores/modules';
+import '~/behaviors/markdown/render_gfm';
+import { createDraft } from '../mock_data';
+
+describe('Batch comments draft preview item component', () => {
+ let vm;
+ let Component;
+ let draft;
+
+ function createComponent(isLast = false, extra = {}, extendStore = () => {}) {
+ const store = createStore();
+ store.registerModule('diffs', diffsModule());
+ store.registerModule('notes', notesModule());
+
+ extendStore(store);
+
+ draft = {
+ ...createDraft(),
+ ...extra,
+ };
+
+ vm = mountComponentWithStore(Component, { store, props: { draft, isLast } });
+ }
+
+ beforeAll(() => {
+ Component = Vue.extend(PreviewItem);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('renders text content', () => {
+ createComponent(false, { note_html: '<img src="" /><p>Hello world</p>' });
+
+ expect(vm.$el.querySelector('.review-preview-item-content').innerHTML).toEqual(
+ '<p>Hello world</p>',
+ );
+ });
+
+ it('adds is last class', () => {
+ createComponent(true);
+
+ expect(vm.$el.classList).toContain('is-last');
+ });
+
+ it('scrolls to draft on click', () => {
+ createComponent();
+
+ jest.spyOn(vm.$store, 'dispatch').mockImplementation();
+
+ vm.$el.click();
+
+ expect(vm.$store.dispatch).toHaveBeenCalledWith('batchComments/scrollToDraft', vm.draft);
+ });
+
+ describe('for file', () => {
+ it('renders file path', () => {
+ createComponent(false, { file_path: 'index.js', file_hash: 'abc', position: {} });
+
+ expect(vm.$el.querySelector('.review-preview-item-header-text').textContent).toContain(
+ 'index.js',
+ );
+ });
+
+ it('renders new line position', () => {
+ createComponent(false, {
+ file_path: 'index.js',
+ file_hash: 'abc',
+ position: { new_line: 1 },
+ });
+
+ expect(vm.$el.querySelector('.bold').textContent).toContain(':1');
+ });
+
+ it('renders old line position', () => {
+ createComponent(false, {
+ file_path: 'index.js',
+ file_hash: 'abc',
+ position: { old_line: 2 },
+ });
+
+ expect(vm.$el.querySelector('.bold').textContent).toContain(':2');
+ });
+
+ it('renders image position', () => {
+ createComponent(false, {
+ file_path: 'index.js',
+ file_hash: 'abc',
+ position: { position_type: 'image', x: 10, y: 20 },
+ });
+
+ expect(vm.$el.querySelector('.bold').textContent).toContain('10x 20y');
+ });
+ });
+
+ describe('for thread', () => {
+ beforeEach(() => {
+ createComponent(false, { discussion_id: '1', resolve_discussion: true }, store => {
+ store.state.notes.discussions.push({
+ id: '1',
+ notes: [
+ {
+ author: {
+ name: 'Author Name',
+ },
+ },
+ ],
+ });
+ });
+ });
+
+ it('renders title', () => {
+ expect(vm.$el.querySelector('.review-preview-item-header-text').textContent).toContain(
+ "Author Name's thread",
+ );
+ });
+
+ it('it renders thread resolved text', () => {
+ expect(vm.$el.querySelector('.draft-note-resolution').textContent).toContain(
+ 'Thread will be resolved',
+ );
+ });
+ });
+});
diff --git a/spec/frontend/batch_comments/components/publish_button_spec.js b/spec/frontend/batch_comments/components/publish_button_spec.js
new file mode 100644
index 00000000000..97f3a1c8939
--- /dev/null
+++ b/spec/frontend/batch_comments/components/publish_button_spec.js
@@ -0,0 +1,52 @@
+import Vue from 'vue';
+import PublishButton from '~/batch_comments/components/publish_button.vue';
+import { mountComponentWithStore } from 'helpers/vue_mount_component_helper';
+import { createStore } from '~/batch_comments/stores';
+
+describe('Batch comments publish button component', () => {
+ let vm;
+ let Component;
+
+ beforeAll(() => {
+ Component = Vue.extend(PublishButton);
+ });
+
+ beforeEach(() => {
+ const store = createStore();
+
+ vm = mountComponentWithStore(Component, { store, props: { shouldPublish: true } });
+
+ jest.spyOn(vm.$store, 'dispatch').mockImplementation();
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('dispatches publishReview on click', () => {
+ vm.$el.click();
+
+ expect(vm.$store.dispatch).toHaveBeenCalledWith('batchComments/publishReview', undefined);
+ });
+
+ it('dispatches toggleReviewDropdown when shouldPublish is false on click', () => {
+ vm.shouldPublish = false;
+
+ vm.$el.click();
+
+ expect(vm.$store.dispatch).toHaveBeenCalledWith(
+ 'batchComments/toggleReviewDropdown',
+ undefined,
+ );
+ });
+
+ it('sets loading when isPublishing is true', done => {
+ vm.$store.state.batchComments.isPublishing = true;
+
+ vm.$nextTick(() => {
+ expect(vm.$el.getAttribute('disabled')).toBe('disabled');
+
+ done();
+ });
+ });
+});
diff --git a/spec/frontend/batch_comments/components/publish_dropdown_spec.js b/spec/frontend/batch_comments/components/publish_dropdown_spec.js
new file mode 100644
index 00000000000..b50ae340691
--- /dev/null
+++ b/spec/frontend/batch_comments/components/publish_dropdown_spec.js
@@ -0,0 +1,96 @@
+import Vue from 'vue';
+import PreviewDropdown from '~/batch_comments/components/preview_dropdown.vue';
+import { mountComponentWithStore } from 'helpers/vue_mount_component_helper';
+import { createStore } from '~/mr_notes/stores';
+import '~/behaviors/markdown/render_gfm';
+import { createDraft } from '../mock_data';
+
+describe('Batch comments publish dropdown component', () => {
+ let vm;
+ let Component;
+
+ function createComponent(extendStore = () => {}) {
+ const store = createStore();
+ store.state.batchComments.drafts.push(createDraft(), { ...createDraft(), id: 2 });
+
+ extendStore(store);
+
+ vm = mountComponentWithStore(Component, { store });
+ }
+
+ beforeAll(() => {
+ Component = Vue.extend(PreviewDropdown);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('toggles dropdown when clicking button', done => {
+ createComponent();
+
+ jest.spyOn(vm.$store, 'dispatch');
+
+ vm.$el.querySelector('.review-preview-dropdown-toggle').click();
+
+ expect(vm.$store.dispatch).toHaveBeenCalledWith(
+ 'batchComments/toggleReviewDropdown',
+ expect.anything(),
+ );
+
+ setImmediate(() => {
+ expect(vm.$el.classList).toContain('show');
+
+ done();
+ });
+ });
+
+ it('toggles dropdown when clicking body', () => {
+ createComponent();
+
+ vm.$store.state.batchComments.showPreviewDropdown = true;
+
+ jest.spyOn(vm.$store, 'dispatch').mockImplementation();
+
+ document.body.click();
+
+ expect(vm.$store.dispatch).toHaveBeenCalledWith(
+ 'batchComments/toggleReviewDropdown',
+ undefined,
+ );
+ });
+
+ it('renders list of drafts', () => {
+ createComponent(store => {
+ Object.assign(store.state.notes, {
+ isNotesFetched: true,
+ });
+ });
+
+ expect(vm.$el.querySelectorAll('.dropdown-content li').length).toBe(2);
+ });
+
+ it('adds is-last class to last item', () => {
+ createComponent(store => {
+ Object.assign(store.state.notes, {
+ isNotesFetched: true,
+ });
+ });
+
+ expect(vm.$el.querySelectorAll('.dropdown-content li')[1].querySelector('.is-last')).not.toBe(
+ null,
+ );
+ });
+
+ it('renders draft count in dropdown title', () => {
+ createComponent();
+
+ expect(vm.$el.querySelector('.dropdown-title').textContent).toContain('2 pending comments');
+ });
+
+ it('renders publish button in footer', () => {
+ createComponent();
+
+ expect(vm.$el.querySelector('.dropdown-footer .js-publish-draft-button')).not.toBe(null);
+ });
+});
diff --git a/spec/frontend/batch_comments/mock_data.js b/spec/frontend/batch_comments/mock_data.js
new file mode 100644
index 00000000000..c50fea94fe3
--- /dev/null
+++ b/spec/frontend/batch_comments/mock_data.js
@@ -0,0 +1,27 @@
+import { TEST_HOST } from 'spec/test_constants';
+
+export const createDraft = () => ({
+ author: {
+ id: 1,
+ name: 'Test',
+ username: 'test',
+ state: 'active',
+ avatar_url: TEST_HOST,
+ },
+ current_user: { can_edit: true, can_award_emoji: false, can_resolve: false },
+ discussion_id: null,
+ file_hash: null,
+ file_path: null,
+ id: 1,
+ line_code: null,
+ merge_request_id: 1,
+ note: 'a',
+ note_html: '<p>Test</p>',
+ noteable_type: 'MergeRequest',
+ references: { users: [], commands: '' },
+ resolve_discussion: false,
+ isDraft: true,
+ position: null,
+});
+
+export default () => {};
diff --git a/spec/frontend/batch_comments/stores/modules/batch_comments/actions_spec.js b/spec/frontend/batch_comments/stores/modules/batch_comments/actions_spec.js
new file mode 100644
index 00000000000..2ec114d026a
--- /dev/null
+++ b/spec/frontend/batch_comments/stores/modules/batch_comments/actions_spec.js
@@ -0,0 +1,403 @@
+import MockAdapter from 'axios-mock-adapter';
+import testAction from 'helpers/vuex_action_helper';
+import * as actions from '~/batch_comments/stores/modules/batch_comments/actions';
+import axios from '~/lib/utils/axios_utils';
+
+describe('Batch comments store actions', () => {
+ let res = {};
+ let mock;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ });
+
+ afterEach(() => {
+ res = {};
+ mock.restore();
+ });
+
+ describe('saveDraft', () => {
+ it('dispatches saveNote on root', () => {
+ const dispatch = jest.fn();
+
+ actions.saveDraft({ dispatch }, { id: 1 });
+
+ expect(dispatch).toHaveBeenCalledWith('saveNote', { id: 1, isDraft: true }, { root: true });
+ });
+ });
+
+ describe('addDraftToDiscussion', () => {
+ it('commits ADD_NEW_DRAFT if no errors returned', done => {
+ res = { id: 1 };
+ mock.onAny().reply(200, res);
+
+ testAction(
+ actions.addDraftToDiscussion,
+ { endpoint: gl.TEST_HOST, data: 'test' },
+ null,
+ [{ type: 'ADD_NEW_DRAFT', payload: res }],
+ [],
+ done,
+ );
+ });
+
+ it('does not commit ADD_NEW_DRAFT if errors returned', done => {
+ mock.onAny().reply(500);
+
+ testAction(
+ actions.addDraftToDiscussion,
+ { endpoint: gl.TEST_HOST, data: 'test' },
+ null,
+ [],
+ [],
+ done,
+ );
+ });
+ });
+
+ describe('createNewDraft', () => {
+ it('commits ADD_NEW_DRAFT if no errors returned', done => {
+ res = { id: 1 };
+ mock.onAny().reply(200, res);
+
+ testAction(
+ actions.createNewDraft,
+ { endpoint: gl.TEST_HOST, data: 'test' },
+ null,
+ [{ type: 'ADD_NEW_DRAFT', payload: res }],
+ [],
+ done,
+ );
+ });
+
+ it('does not commit ADD_NEW_DRAFT if errors returned', done => {
+ mock.onAny().reply(500);
+
+ testAction(
+ actions.createNewDraft,
+ { endpoint: gl.TEST_HOST, data: 'test' },
+ null,
+ [],
+ [],
+ done,
+ );
+ });
+ });
+
+ describe('deleteDraft', () => {
+ let getters;
+
+ beforeEach(() => {
+ getters = {
+ getNotesData: {
+ draftsDiscardPath: gl.TEST_HOST,
+ },
+ };
+ });
+
+ it('commits DELETE_DRAFT if no errors returned', done => {
+ const commit = jest.fn();
+ const context = {
+ getters,
+ commit,
+ };
+ res = { id: 1 };
+ mock.onAny().reply(200);
+
+ actions
+ .deleteDraft(context, { id: 1 })
+ .then(() => {
+ expect(commit).toHaveBeenCalledWith('DELETE_DRAFT', 1);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('does not commit DELETE_DRAFT if errors returned', done => {
+ const commit = jest.fn();
+ const context = {
+ getters,
+ commit,
+ };
+ mock.onAny().reply(500);
+
+ actions
+ .deleteDraft(context, { id: 1 })
+ .then(() => {
+ expect(commit).not.toHaveBeenCalledWith('DELETE_DRAFT', 1);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('fetchDrafts', () => {
+ let getters;
+
+ beforeEach(() => {
+ getters = {
+ getNotesData: {
+ draftsPath: gl.TEST_HOST,
+ },
+ };
+ });
+
+ it('commits SET_BATCH_COMMENTS_DRAFTS with returned data', done => {
+ const commit = jest.fn();
+ const context = {
+ getters,
+ commit,
+ };
+ res = { id: 1 };
+ mock.onAny().reply(200, res);
+
+ actions
+ .fetchDrafts(context)
+ .then(() => {
+ expect(commit).toHaveBeenCalledWith('SET_BATCH_COMMENTS_DRAFTS', { id: 1 });
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('publishReview', () => {
+ let dispatch;
+ let commit;
+ let getters;
+ let rootGetters;
+
+ beforeEach(() => {
+ dispatch = jest.fn();
+ commit = jest.fn();
+ getters = {
+ getNotesData: { draftsPublishPath: gl.TEST_HOST, discussionsPath: gl.TEST_HOST },
+ };
+ rootGetters = { discussionsStructuredByLineCode: 'discussions' };
+ });
+
+ it('dispatches actions & commits', done => {
+ mock.onAny().reply(200);
+
+ actions
+ .publishReview({ dispatch, commit, getters, rootGetters })
+ .then(() => {
+ expect(commit.mock.calls[0]).toEqual(['REQUEST_PUBLISH_REVIEW']);
+ expect(commit.mock.calls[1]).toEqual(['RECEIVE_PUBLISH_REVIEW_SUCCESS']);
+
+ expect(dispatch.mock.calls[0]).toEqual(['updateDiscussionsAfterPublish']);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('dispatches error commits', done => {
+ mock.onAny().reply(500);
+
+ actions
+ .publishReview({ dispatch, commit, getters, rootGetters })
+ .then(() => {
+ expect(commit.mock.calls[0]).toEqual(['REQUEST_PUBLISH_REVIEW']);
+ expect(commit.mock.calls[1]).toEqual(['RECEIVE_PUBLISH_REVIEW_ERROR']);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('discardReview', () => {
+ it('commits mutations', done => {
+ const getters = {
+ getNotesData: { draftsDiscardPath: gl.TEST_HOST },
+ };
+ const commit = jest.fn();
+ mock.onAny().reply(200);
+
+ actions
+ .discardReview({ getters, commit })
+ .then(() => {
+ expect(commit.mock.calls[0]).toEqual(['REQUEST_DISCARD_REVIEW']);
+ expect(commit.mock.calls[1]).toEqual(['RECEIVE_DISCARD_REVIEW_SUCCESS']);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('commits error mutations', done => {
+ const getters = {
+ getNotesData: { draftsDiscardPath: gl.TEST_HOST },
+ };
+ const commit = jest.fn();
+ mock.onAny().reply(500);
+
+ actions
+ .discardReview({ getters, commit })
+ .then(() => {
+ expect(commit.mock.calls[0]).toEqual(['REQUEST_DISCARD_REVIEW']);
+ expect(commit.mock.calls[1]).toEqual(['RECEIVE_DISCARD_REVIEW_ERROR']);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('updateDraft', () => {
+ let getters;
+
+ beforeEach(() => {
+ getters = {
+ getNotesData: {
+ draftsPath: gl.TEST_HOST,
+ },
+ };
+ });
+
+ it('commits RECEIVE_DRAFT_UPDATE_SUCCESS with returned data', done => {
+ const commit = jest.fn();
+ const context = {
+ getters,
+ commit,
+ };
+ res = { id: 1 };
+ mock.onAny().reply(200, res);
+
+ actions
+ .updateDraft(context, { note: { id: 1 }, noteText: 'test', callback() {} })
+ .then(() => {
+ expect(commit).toHaveBeenCalledWith('RECEIVE_DRAFT_UPDATE_SUCCESS', { id: 1 });
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('calls passed callback', done => {
+ const commit = jest.fn();
+ const context = {
+ getters,
+ commit,
+ };
+ const callback = jest.fn();
+ res = { id: 1 };
+ mock.onAny().reply(200, res);
+
+ actions
+ .updateDraft(context, { note: { id: 1 }, noteText: 'test', callback })
+ .then(() => {
+ expect(callback).toHaveBeenCalled();
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('toggleReviewDropdown', () => {
+ it('dispatches openReviewDropdown', done => {
+ testAction(
+ actions.toggleReviewDropdown,
+ null,
+ { showPreviewDropdown: false },
+ [],
+ [{ type: 'openReviewDropdown' }],
+ done,
+ );
+ });
+
+ it('dispatches closeReviewDropdown when showPreviewDropdown is true', done => {
+ testAction(
+ actions.toggleReviewDropdown,
+ null,
+ { showPreviewDropdown: true },
+ [],
+ [{ type: 'closeReviewDropdown' }],
+ done,
+ );
+ });
+ });
+
+ describe('openReviewDropdown', () => {
+ it('commits OPEN_REVIEW_DROPDOWN', done => {
+ testAction(
+ actions.openReviewDropdown,
+ null,
+ null,
+ [{ type: 'OPEN_REVIEW_DROPDOWN' }],
+ [],
+ done,
+ );
+ });
+ });
+
+ describe('closeReviewDropdown', () => {
+ it('commits CLOSE_REVIEW_DROPDOWN', done => {
+ testAction(
+ actions.closeReviewDropdown,
+ null,
+ null,
+ [{ type: 'CLOSE_REVIEW_DROPDOWN' }],
+ [],
+ done,
+ );
+ });
+ });
+
+ describe('expandAllDiscussions', () => {
+ it('dispatches expandDiscussion for all drafts', done => {
+ const state = {
+ drafts: [
+ {
+ discussion_id: '1',
+ },
+ ],
+ };
+
+ testAction(
+ actions.expandAllDiscussions,
+ null,
+ state,
+ [],
+ [
+ {
+ type: 'expandDiscussion',
+ payload: { discussionId: '1' },
+ },
+ ],
+ done,
+ );
+ });
+ });
+
+ describe('scrollToDraft', () => {
+ beforeEach(() => {
+ window.mrTabs = {
+ currentAction: 'notes',
+ tabShown: jest.fn(),
+ };
+ });
+
+ it('scrolls to draft item', () => {
+ const dispatch = jest.fn();
+ const rootGetters = {
+ getDiscussion: () => ({
+ id: '1',
+ diff_discussion: true,
+ }),
+ };
+ const draft = {
+ discussion_id: '1',
+ id: '2',
+ };
+
+ actions.scrollToDraft({ dispatch, rootGetters }, draft);
+
+ expect(dispatch.mock.calls[0]).toEqual(['closeReviewDropdown']);
+
+ expect(dispatch.mock.calls[1]).toEqual([
+ 'expandDiscussion',
+ { discussionId: '1' },
+ { root: true },
+ ]);
+
+ expect(window.mrTabs.tabShown).toHaveBeenCalledWith('diffs');
+ });
+ });
+});
diff --git a/spec/frontend/batch_comments/stores/modules/batch_comments/getters_spec.js b/spec/frontend/batch_comments/stores/modules/batch_comments/getters_spec.js
new file mode 100644
index 00000000000..2398bb4feb1
--- /dev/null
+++ b/spec/frontend/batch_comments/stores/modules/batch_comments/getters_spec.js
@@ -0,0 +1,27 @@
+import * as getters from '~/batch_comments/stores/modules/batch_comments/getters';
+
+describe('Batch comments store getters', () => {
+ describe('draftsForFile', () => {
+ it('returns drafts for a file hash', () => {
+ const state = {
+ drafts: [
+ {
+ file_hash: 'filehash',
+ comment: 'testing 123',
+ },
+ {
+ file_hash: 'filehash2',
+ comment: 'testing 1234',
+ },
+ ],
+ };
+
+ expect(getters.draftsForFile(state)('filehash')).toEqual([
+ {
+ file_hash: 'filehash',
+ comment: 'testing 123',
+ },
+ ]);
+ });
+ });
+});
diff --git a/spec/frontend/batch_comments/stores/modules/batch_comments/mutations_spec.js b/spec/frontend/batch_comments/stores/modules/batch_comments/mutations_spec.js
new file mode 100644
index 00000000000..a86726269ef
--- /dev/null
+++ b/spec/frontend/batch_comments/stores/modules/batch_comments/mutations_spec.js
@@ -0,0 +1,159 @@
+import createState from '~/batch_comments/stores/modules/batch_comments/state';
+import mutations from '~/batch_comments/stores/modules/batch_comments/mutations';
+import * as types from '~/batch_comments/stores/modules/batch_comments/mutation_types';
+
+describe('Batch comments mutations', () => {
+ let state;
+
+ beforeEach(() => {
+ state = createState();
+ });
+
+ describe(types.ADD_NEW_DRAFT, () => {
+ it('adds processed object into drafts array', () => {
+ const draft = { id: 1, note: 'test' };
+
+ mutations[types.ADD_NEW_DRAFT](state, draft);
+
+ expect(state.drafts).toEqual([
+ {
+ ...draft,
+ isDraft: true,
+ },
+ ]);
+ });
+ });
+
+ describe(types.DELETE_DRAFT, () => {
+ it('removes draft from array by ID', () => {
+ state.drafts.push({ id: 1 }, { id: 2 });
+
+ mutations[types.DELETE_DRAFT](state, 1);
+
+ expect(state.drafts).toEqual([{ id: 2 }]);
+ });
+ });
+
+ describe(types.SET_BATCH_COMMENTS_DRAFTS, () => {
+ it('adds to processed drafts in state', () => {
+ const drafts = [{ id: 1 }, { id: 2 }];
+
+ mutations[types.SET_BATCH_COMMENTS_DRAFTS](state, drafts);
+
+ expect(state.drafts).toEqual([
+ {
+ id: 1,
+ isDraft: true,
+ },
+ {
+ id: 2,
+ isDraft: true,
+ },
+ ]);
+ });
+ });
+
+ describe(types.REQUEST_PUBLISH_REVIEW, () => {
+ it('sets isPublishing to true', () => {
+ mutations[types.REQUEST_PUBLISH_REVIEW](state);
+
+ expect(state.isPublishing).toBe(true);
+ });
+ });
+
+ describe(types.RECEIVE_PUBLISH_REVIEW_SUCCESS, () => {
+ it('resets drafts', () => {
+ state.drafts.push('test');
+
+ mutations[types.RECEIVE_PUBLISH_REVIEW_SUCCESS](state);
+
+ expect(state.drafts).toEqual([]);
+ });
+
+ it('sets isPublishing to false', () => {
+ state.isPublishing = true;
+
+ mutations[types.RECEIVE_PUBLISH_REVIEW_SUCCESS](state);
+
+ expect(state.isPublishing).toBe(false);
+ });
+ });
+
+ describe(types.RECEIVE_PUBLISH_REVIEW_ERROR, () => {
+ it('updates isPublishing to false', () => {
+ state.isPublishing = true;
+
+ mutations[types.RECEIVE_PUBLISH_REVIEW_ERROR](state);
+
+ expect(state.isPublishing).toBe(false);
+ });
+ });
+
+ describe(types.REQUEST_DISCARD_REVIEW, () => {
+ it('sets isDiscarding to true', () => {
+ mutations[types.REQUEST_DISCARD_REVIEW](state);
+
+ expect(state.isDiscarding).toBe(true);
+ });
+ });
+
+ describe(types.RECEIVE_DISCARD_REVIEW_SUCCESS, () => {
+ it('emptys drafts array', () => {
+ state.drafts.push('test');
+
+ mutations[types.RECEIVE_DISCARD_REVIEW_SUCCESS](state);
+
+ expect(state.drafts).toEqual([]);
+ });
+
+ it('sets isDiscarding to false', () => {
+ state.isDiscarding = true;
+
+ mutations[types.RECEIVE_DISCARD_REVIEW_SUCCESS](state);
+
+ expect(state.isDiscarding).toBe(false);
+ });
+ });
+
+ describe(types.RECEIVE_DISCARD_REVIEW_ERROR, () => {
+ it('updates isDiscarding to false', () => {
+ state.isDiscarding = true;
+
+ mutations[types.RECEIVE_DISCARD_REVIEW_ERROR](state);
+
+ expect(state.isDiscarding).toBe(false);
+ });
+ });
+
+ describe(types.RECEIVE_DRAFT_UPDATE_SUCCESS, () => {
+ it('updates draft in store', () => {
+ state.drafts.push({ id: 1 });
+
+ mutations[types.RECEIVE_DRAFT_UPDATE_SUCCESS](state, { id: 1, note: 'test' });
+
+ expect(state.drafts).toEqual([
+ {
+ id: 1,
+ note: 'test',
+ isDraft: true,
+ },
+ ]);
+ });
+ });
+
+ describe(types.OPEN_REVIEW_DROPDOWN, () => {
+ it('sets showPreviewDropdown to true', () => {
+ mutations[types.OPEN_REVIEW_DROPDOWN](state);
+
+ expect(state.showPreviewDropdown).toBe(true);
+ });
+ });
+
+ describe(types.CLOSE_REVIEW_DROPDOWN, () => {
+ it('sets showPreviewDropdown to false', () => {
+ mutations[types.CLOSE_REVIEW_DROPDOWN](state);
+
+ expect(state.showPreviewDropdown).toBe(false);
+ });
+ });
+});
diff --git a/spec/javascripts/behaviors/autosize_spec.js b/spec/frontend/behaviors/autosize_spec.js
index 59abae479d4..59abae479d4 100644
--- a/spec/javascripts/behaviors/autosize_spec.js
+++ b/spec/frontend/behaviors/autosize_spec.js
diff --git a/spec/frontend/behaviors/bind_in_out_spec.js b/spec/frontend/behaviors/bind_in_out_spec.js
index 923b6d372dd..92a68ddd387 100644
--- a/spec/frontend/behaviors/bind_in_out_spec.js
+++ b/spec/frontend/behaviors/bind_in_out_spec.js
@@ -163,14 +163,8 @@ describe('BindInOut', () => {
describe('init', () => {
beforeEach(() => {
- // eslint-disable-next-line func-names
- jest.spyOn(BindInOut.prototype, 'addEvents').mockImplementation(function() {
- return this;
- });
- // eslint-disable-next-line func-names
- jest.spyOn(BindInOut.prototype, 'updateOut').mockImplementation(function() {
- return this;
- });
+ jest.spyOn(BindInOut.prototype, 'addEvents').mockReturnThis();
+ jest.spyOn(BindInOut.prototype, 'updateOut').mockReturnThis();
testContext.init = BindInOut.init({}, {});
});
diff --git a/spec/frontend/behaviors/copy_as_gfm_spec.js b/spec/frontend/behaviors/copy_as_gfm_spec.js
new file mode 100644
index 00000000000..cf96ac488a8
--- /dev/null
+++ b/spec/frontend/behaviors/copy_as_gfm_spec.js
@@ -0,0 +1,125 @@
+import initCopyAsGFM, { CopyAsGFM } from '~/behaviors/markdown/copy_as_gfm';
+
+describe('CopyAsGFM', () => {
+ describe('CopyAsGFM.pasteGFM', () => {
+ function callPasteGFM() {
+ const e = {
+ originalEvent: {
+ clipboardData: {
+ getData(mimeType) {
+ // When GFM code is copied, we put the regular plain text
+ // on the clipboard as `text/plain`, and the GFM as `text/x-gfm`.
+ // This emulates the behavior of `getData` with that data.
+ if (mimeType === 'text/plain') {
+ return 'code';
+ }
+ if (mimeType === 'text/x-gfm') {
+ return '`code`';
+ }
+ return null;
+ },
+ },
+ },
+ preventDefault() {},
+ };
+
+ CopyAsGFM.pasteGFM(e);
+ }
+
+ it('wraps pasted code when not already in code tags', () => {
+ jest.spyOn(window.gl.utils, 'insertText').mockImplementation((el, textFunc) => {
+ const insertedText = textFunc('This is code: ', '');
+
+ expect(insertedText).toEqual('`code`');
+ });
+
+ callPasteGFM();
+ });
+
+ it('does not wrap pasted code when already in code tags', () => {
+ jest.spyOn(window.gl.utils, 'insertText').mockImplementation((el, textFunc) => {
+ const insertedText = textFunc('This is code: `', '`');
+
+ expect(insertedText).toEqual('code');
+ });
+
+ callPasteGFM();
+ });
+ });
+
+ describe('CopyAsGFM.copyGFM', () => {
+ // Stub getSelection to return a purpose-built object.
+ const stubSelection = (html, parentNode) => ({
+ getRangeAt: () => ({
+ commonAncestorContainer: { tagName: parentNode },
+ cloneContents: () => {
+ const fragment = document.createDocumentFragment();
+ const node = document.createElement('div');
+ node.innerHTML = html;
+ Array.from(node.childNodes).forEach(item => fragment.appendChild(item));
+ return fragment;
+ },
+ }),
+ rangeCount: 1,
+ });
+
+ const clipboardData = {
+ setData() {},
+ };
+
+ const simulateCopy = () => {
+ const e = {
+ originalEvent: {
+ clipboardData,
+ },
+ preventDefault() {},
+ stopPropagation() {},
+ };
+ CopyAsGFM.copyAsGFM(e, CopyAsGFM.transformGFMSelection);
+ return clipboardData;
+ };
+
+ beforeAll(done => {
+ initCopyAsGFM();
+
+ // Fake call to nodeToGfm so the import of lazy bundle happened
+ CopyAsGFM.nodeToGFM(document.createElement('div'))
+ .then(() => {
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ beforeEach(() => jest.spyOn(clipboardData, 'setData'));
+
+ describe('list handling', () => {
+ it('uses correct gfm for unordered lists', done => {
+ const selection = stubSelection('<li>List Item1</li><li>List Item2</li>\n', 'UL');
+
+ window.getSelection = jest.fn(() => selection);
+ simulateCopy();
+
+ setImmediate(() => {
+ const expectedGFM = '* List Item1\n* List Item2';
+
+ expect(clipboardData.setData).toHaveBeenCalledWith('text/x-gfm', expectedGFM);
+ done();
+ });
+ });
+
+ it('uses correct gfm for ordered lists', done => {
+ const selection = stubSelection('<li>List Item1</li><li>List Item2</li>\n', 'OL');
+
+ window.getSelection = jest.fn(() => selection);
+ simulateCopy();
+
+ setImmediate(() => {
+ const expectedGFM = '1. List Item1\n1. List Item2';
+
+ expect(clipboardData.setData).toHaveBeenCalledWith('text/x-gfm', expectedGFM);
+ done();
+ });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/behaviors/gl_emoji/unicode_support_map_spec.js b/spec/frontend/behaviors/gl_emoji/unicode_support_map_spec.js
new file mode 100644
index 00000000000..aaee9c30cac
--- /dev/null
+++ b/spec/frontend/behaviors/gl_emoji/unicode_support_map_spec.js
@@ -0,0 +1,52 @@
+import getUnicodeSupportMap from '~/emoji/support/unicode_support_map';
+import AccessorUtilities from '~/lib/utils/accessor';
+import { useLocalStorageSpy } from 'helpers/local_storage_helper';
+
+describe('Unicode Support Map', () => {
+ useLocalStorageSpy();
+ describe('getUnicodeSupportMap', () => {
+ const stringSupportMap = 'stringSupportMap';
+
+ beforeEach(() => {
+ jest.spyOn(AccessorUtilities, 'isLocalStorageAccessSafe').mockImplementation(() => {});
+ jest.spyOn(JSON, 'parse').mockImplementation(() => {});
+ jest.spyOn(JSON, 'stringify').mockReturnValue(stringSupportMap);
+ });
+
+ describe('if isLocalStorageAvailable is `true`', () => {
+ beforeEach(() => {
+ jest.spyOn(AccessorUtilities, 'isLocalStorageAccessSafe').mockReturnValue(true);
+
+ getUnicodeSupportMap();
+ });
+
+ it('should call .getItem and .setItem', () => {
+ const getArgs = window.localStorage.getItem.mock.calls;
+ const setArgs = window.localStorage.setItem.mock.calls;
+
+ expect(getArgs[0][0]).toBe('gl-emoji-version');
+ expect(getArgs[1][0]).toBe('gl-emoji-user-agent');
+
+ expect(setArgs[0][0]).toBe('gl-emoji-version');
+ expect(setArgs[0][1]).toBe('0.2.0');
+ expect(setArgs[1][0]).toBe('gl-emoji-user-agent');
+ expect(setArgs[1][1]).toBe(navigator.userAgent);
+ expect(setArgs[2][0]).toBe('gl-emoji-unicode-support-map');
+ expect(setArgs[2][1]).toBe(stringSupportMap);
+ });
+ });
+
+ describe('if isLocalStorageAvailable is `false`', () => {
+ beforeEach(() => {
+ jest.spyOn(AccessorUtilities, 'isLocalStorageAccessSafe').mockReturnValue(false);
+
+ getUnicodeSupportMap();
+ });
+
+ it('should not call .getItem or .setItem', () => {
+ expect(window.localStorage.getItem.mock.calls.length).toBe(1);
+ expect(window.localStorage.setItem).not.toHaveBeenCalled();
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/behaviors/markdown/highlight_current_user_spec.js b/spec/frontend/behaviors/markdown/highlight_current_user_spec.js
index 3305ddc412d..3305ddc412d 100644
--- a/spec/javascripts/behaviors/markdown/highlight_current_user_spec.js
+++ b/spec/frontend/behaviors/markdown/highlight_current_user_spec.js
diff --git a/spec/javascripts/behaviors/requires_input_spec.js b/spec/frontend/behaviors/requires_input_spec.js
index 617fe49b059..617fe49b059 100644
--- a/spec/javascripts/behaviors/requires_input_spec.js
+++ b/spec/frontend/behaviors/requires_input_spec.js
diff --git a/spec/frontend/behaviors/shortcuts/shortcuts_issuable_spec.js b/spec/frontend/behaviors/shortcuts/shortcuts_issuable_spec.js
new file mode 100644
index 00000000000..6391a544985
--- /dev/null
+++ b/spec/frontend/behaviors/shortcuts/shortcuts_issuable_spec.js
@@ -0,0 +1,322 @@
+import $ from 'jquery';
+import 'mousetrap';
+import initCopyAsGFM, { CopyAsGFM } from '~/behaviors/markdown/copy_as_gfm';
+import ShortcutsIssuable from '~/behaviors/shortcuts/shortcuts_issuable';
+import { getSelectedFragment } from '~/lib/utils/common_utils';
+
+const FORM_SELECTOR = '.js-main-target-form .js-vue-comment-form';
+
+jest.mock('~/lib/utils/common_utils', () => ({
+ ...jest.requireActual('~/lib/utils/common_utils'),
+ getSelectedFragment: jest.fn().mockName('getSelectedFragment'),
+}));
+
+describe('ShortcutsIssuable', () => {
+ const fixtureName = 'snippets/show.html';
+
+ preloadFixtures(fixtureName);
+
+ beforeAll(done => {
+ initCopyAsGFM();
+
+ // Fake call to nodeToGfm so the import of lazy bundle happened
+ CopyAsGFM.nodeToGFM(document.createElement('div'))
+ .then(() => {
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ beforeEach(() => {
+ loadFixtures(fixtureName);
+ $('body').append(
+ `<div class="js-main-target-form">
+ <textarea class="js-vue-comment-form"></textarea>
+ </div>`,
+ );
+ document.querySelector('.js-new-note-form').classList.add('js-main-target-form');
+
+ window.shortcut = new ShortcutsIssuable(true);
+ });
+
+ afterEach(() => {
+ $(FORM_SELECTOR).remove();
+
+ delete window.shortcut;
+ });
+
+ describe('replyWithSelectedText', () => {
+ // Stub window.gl.utils.getSelectedFragment to return a node with the provided HTML.
+ const stubSelection = (html, invalidNode) => {
+ getSelectedFragment.mockImplementation(() => {
+ const documentFragment = document.createDocumentFragment();
+ const node = document.createElement('div');
+
+ node.innerHTML = html;
+ if (!invalidNode) node.className = 'md';
+
+ documentFragment.appendChild(node);
+ return documentFragment;
+ });
+ };
+
+ describe('with empty selection', () => {
+ it('does not return an error', () => {
+ ShortcutsIssuable.replyWithSelectedText(true);
+
+ expect($(FORM_SELECTOR).val()).toBe('');
+ });
+
+ it('triggers `focus`', () => {
+ const spy = jest.spyOn(document.querySelector(FORM_SELECTOR), 'focus');
+ ShortcutsIssuable.replyWithSelectedText(true);
+
+ expect(spy).toHaveBeenCalled();
+ });
+ });
+
+ describe('with any selection', () => {
+ beforeEach(() => {
+ stubSelection('<p>Selected text.</p>');
+ });
+
+ it('leaves existing input intact', done => {
+ $(FORM_SELECTOR).val('This text was already here.');
+
+ expect($(FORM_SELECTOR).val()).toBe('This text was already here.');
+
+ ShortcutsIssuable.replyWithSelectedText(true);
+
+ setImmediate(() => {
+ expect($(FORM_SELECTOR).val()).toBe(
+ 'This text was already here.\n\n> Selected text.\n\n',
+ );
+ done();
+ });
+ });
+
+ it('triggers `input`', done => {
+ let triggered = false;
+ $(FORM_SELECTOR).on('input', () => {
+ triggered = true;
+ });
+
+ ShortcutsIssuable.replyWithSelectedText(true);
+
+ setImmediate(() => {
+ expect(triggered).toBe(true);
+ done();
+ });
+ });
+
+ it('triggers `focus`', done => {
+ const spy = jest.spyOn(document.querySelector(FORM_SELECTOR), 'focus');
+ ShortcutsIssuable.replyWithSelectedText(true);
+
+ setImmediate(() => {
+ expect(spy).toHaveBeenCalled();
+ done();
+ });
+ });
+ });
+
+ describe('with a one-line selection', () => {
+ it('quotes the selection', done => {
+ stubSelection('<p>This text has been selected.</p>');
+ ShortcutsIssuable.replyWithSelectedText(true);
+
+ setImmediate(() => {
+ expect($(FORM_SELECTOR).val()).toBe('> This text has been selected.\n\n');
+ done();
+ });
+ });
+ });
+
+ describe('with a multi-line selection', () => {
+ it('quotes the selected lines as a group', done => {
+ stubSelection(
+ '<p>Selected line one.</p>\n<p>Selected line two.</p>\n<p>Selected line three.</p>',
+ );
+ ShortcutsIssuable.replyWithSelectedText(true);
+
+ setImmediate(() => {
+ expect($(FORM_SELECTOR).val()).toBe(
+ '> Selected line one.\n>\n> Selected line two.\n>\n> Selected line three.\n\n',
+ );
+ done();
+ });
+ });
+ });
+
+ describe('with an invalid selection', () => {
+ beforeEach(() => {
+ stubSelection('<p>Selected text.</p>', true);
+ });
+
+ it('does not add anything to the input', done => {
+ ShortcutsIssuable.replyWithSelectedText(true);
+
+ setImmediate(() => {
+ expect($(FORM_SELECTOR).val()).toBe('');
+ done();
+ });
+ });
+
+ it('triggers `focus`', done => {
+ const spy = jest.spyOn(document.querySelector(FORM_SELECTOR), 'focus');
+ ShortcutsIssuable.replyWithSelectedText(true);
+
+ setImmediate(() => {
+ expect(spy).toHaveBeenCalled();
+ done();
+ });
+ });
+ });
+
+ describe('with a semi-valid selection', () => {
+ beforeEach(() => {
+ stubSelection('<div class="md">Selected text.</div><p>Invalid selected text.</p>', true);
+ });
+
+ it('only adds the valid part to the input', done => {
+ ShortcutsIssuable.replyWithSelectedText(true);
+
+ setImmediate(() => {
+ expect($(FORM_SELECTOR).val()).toBe('> Selected text.\n\n');
+ done();
+ });
+ });
+
+ it('triggers `focus`', done => {
+ const spy = jest.spyOn(document.querySelector(FORM_SELECTOR), 'focus');
+ ShortcutsIssuable.replyWithSelectedText(true);
+
+ setImmediate(() => {
+ expect(spy).toHaveBeenCalled();
+ done();
+ });
+ });
+
+ it('triggers `input`', done => {
+ let triggered = false;
+ $(FORM_SELECTOR).on('input', () => {
+ triggered = true;
+ });
+
+ ShortcutsIssuable.replyWithSelectedText(true);
+
+ setImmediate(() => {
+ expect(triggered).toBe(true);
+ done();
+ });
+ });
+ });
+
+ describe('with a selection in a valid block', () => {
+ beforeEach(() => {
+ getSelectedFragment.mockImplementation(() => {
+ const documentFragment = document.createDocumentFragment();
+ const node = document.createElement('div');
+ const originalNode = document.createElement('body');
+ originalNode.innerHTML = `<div class="issue">
+ <div class="otherElem">Text...</div>
+ <div class="md"><p><em>Selected text.</em></p></div>
+ </div>`;
+ documentFragment.originalNodes = [originalNode.querySelector('em')];
+
+ node.innerHTML = '<em>Selected text.</em>';
+
+ documentFragment.appendChild(node);
+
+ return documentFragment;
+ });
+ });
+
+ it('adds the quoted selection to the input', done => {
+ ShortcutsIssuable.replyWithSelectedText(true);
+
+ setImmediate(() => {
+ expect($(FORM_SELECTOR).val()).toBe('> *Selected text.*\n\n');
+ done();
+ });
+ });
+
+ it('triggers `focus`', done => {
+ const spy = jest.spyOn(document.querySelector(FORM_SELECTOR), 'focus');
+ ShortcutsIssuable.replyWithSelectedText(true);
+
+ setImmediate(() => {
+ expect(spy).toHaveBeenCalled();
+ done();
+ });
+ });
+
+ it('triggers `input`', done => {
+ let triggered = false;
+ $(FORM_SELECTOR).on('input', () => {
+ triggered = true;
+ });
+
+ ShortcutsIssuable.replyWithSelectedText(true);
+
+ setImmediate(() => {
+ expect(triggered).toBe(true);
+ done();
+ });
+ });
+ });
+
+ describe('with a selection in an invalid block', () => {
+ beforeEach(() => {
+ getSelectedFragment.mockImplementation(() => {
+ const documentFragment = document.createDocumentFragment();
+ const node = document.createElement('div');
+ const originalNode = document.createElement('body');
+ originalNode.innerHTML = `<div class="issue">
+ <div class="otherElem"><div><b>Selected text.</b></div></div>
+ <div class="md"><p><em>Valid text</em></p></div>
+ </div>`;
+ documentFragment.originalNodes = [originalNode.querySelector('b')];
+
+ node.innerHTML = '<b>Selected text.</b>';
+
+ documentFragment.appendChild(node);
+
+ return documentFragment;
+ });
+ });
+
+ it('does not add anything to the input', done => {
+ ShortcutsIssuable.replyWithSelectedText(true);
+
+ setImmediate(() => {
+ expect($(FORM_SELECTOR).val()).toBe('');
+ done();
+ });
+ });
+
+ it('triggers `focus`', done => {
+ const spy = jest.spyOn(document.querySelector(FORM_SELECTOR), 'focus');
+ ShortcutsIssuable.replyWithSelectedText(true);
+
+ setImmediate(() => {
+ expect(spy).toHaveBeenCalled();
+ done();
+ });
+ });
+ });
+
+ describe('with a valid selection with no text content', () => {
+ it('returns the proper markdown', done => {
+ stubSelection('<img src="https://gitlab.com/logo.png" alt="logo" />');
+ ShortcutsIssuable.replyWithSelectedText(true);
+
+ setImmediate(() => {
+ expect($(FORM_SELECTOR).val()).toBe('> ![logo](https://gitlab.com/logo.png)\n\n');
+
+ done();
+ });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/blob/components/__snapshots__/blob_header_filepath_spec.js.snap b/spec/frontend/blob/components/__snapshots__/blob_header_filepath_spec.js.snap
index 2ac6e0d5d24..005b2c5da1c 100644
--- a/spec/frontend/blob/components/__snapshots__/blob_header_filepath_spec.js.snap
+++ b/spec/frontend/blob/components/__snapshots__/blob_header_filepath_spec.js.snap
@@ -14,7 +14,7 @@ exports[`Blob Header Filepath rendering matches the snapshot 1`] = `
<strong
class="file-title-name mr-1 js-blob-header-filepath"
- data-qa-selector="file_title_name"
+ data-qa-selector="file_title_content"
>
foo/bar/dummy.md
</strong>
diff --git a/spec/frontend/blob/components/blob_header_default_actions_spec.js b/spec/frontend/blob/components/blob_header_default_actions_spec.js
index 684840afe1c..0247a12d8d3 100644
--- a/spec/frontend/blob/components/blob_header_default_actions_spec.js
+++ b/spec/frontend/blob/components/blob_header_default_actions_spec.js
@@ -66,5 +66,13 @@ describe('Blob Header Default Actions', () => {
expect(buttons.at(0).attributes('disabled')).toBeTruthy();
});
+
+ it('does not render the copy button if a rendering error is set', () => {
+ createComponent({
+ hasRenderError: true,
+ });
+
+ expect(wrapper.find('[data-testid="copyContentsButton"]').exists()).toBe(false);
+ });
});
});
diff --git a/spec/frontend/blob/components/blob_header_filepath_spec.js b/spec/frontend/blob/components/blob_header_filepath_spec.js
index 3a53208f357..43057353051 100644
--- a/spec/frontend/blob/components/blob_header_filepath_spec.js
+++ b/spec/frontend/blob/components/blob_header_filepath_spec.js
@@ -4,9 +4,8 @@ import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import { Blob as MockBlob } from './mock_data';
import { numberToHumanSize } from '~/lib/utils/number_utils';
-const mockHumanReadableSize = 'a lot';
jest.mock('~/lib/utils/number_utils', () => ({
- numberToHumanSize: jest.fn(() => mockHumanReadableSize),
+ numberToHumanSize: jest.fn(() => 'a lot'),
}));
describe('Blob Header Filepath', () => {
@@ -57,7 +56,7 @@ describe('Blob Header Filepath', () => {
it('renders filesize in a human-friendly format', () => {
createComponent();
expect(numberToHumanSize).toHaveBeenCalled();
- expect(wrapper.vm.blobSize).toBe(mockHumanReadableSize);
+ expect(wrapper.vm.blobSize).toBe('a lot');
});
it('renders a slot and prepends its contents to the existing one', () => {
diff --git a/spec/frontend/blob/components/blob_header_spec.js b/spec/frontend/blob/components/blob_header_spec.js
index 0e7d2f6516a..01d4bf834d2 100644
--- a/spec/frontend/blob/components/blob_header_spec.js
+++ b/spec/frontend/blob/components/blob_header_spec.js
@@ -87,6 +87,17 @@ describe('Blob Header Default Actions', () => {
expect(wrapper.text()).toContain(slotContent);
});
});
+
+ it('passes information about render error down to default actions', () => {
+ createComponent(
+ {},
+ {},
+ {
+ hasRenderError: true,
+ },
+ );
+ expect(wrapper.find(DefaultActions).props('hasRenderError')).toBe(true);
+ });
});
describe('functionality', () => {
diff --git a/spec/javascripts/boards/board_list_common_spec.js b/spec/frontend/boards/board_list_helper.js
index b51a82f2a35..b51a82f2a35 100644
--- a/spec/javascripts/boards/board_list_common_spec.js
+++ b/spec/frontend/boards/board_list_helper.js
diff --git a/spec/frontend/boards/board_list_spec.js b/spec/frontend/boards/board_list_spec.js
index fa21053e2de..3a64b004847 100644
--- a/spec/frontend/boards/board_list_spec.js
+++ b/spec/frontend/boards/board_list_spec.js
@@ -118,7 +118,7 @@ describe('Board list component', () => {
});
it('shows new issue form after eventhub event', () => {
- eventHub.$emit(`hide-issue-form-${component.list.id}`);
+ eventHub.$emit(`toggle-issue-form-${component.list.id}`);
return Vue.nextTick().then(() => {
expect(component.$el.querySelector('.board-new-issue-form')).not.toBeNull();
diff --git a/spec/frontend/boards/components/board_column_spec.js b/spec/frontend/boards/components/board_column_spec.js
index 7cf6ec913b4..6853fe2559d 100644
--- a/spec/frontend/boards/components/board_column_spec.js
+++ b/spec/frontend/boards/components/board_column_spec.js
@@ -70,37 +70,6 @@ describe('Board Column Component', () => {
const isExpandable = () => wrapper.classes('is-expandable');
const isCollapsed = () => wrapper.classes('is-collapsed');
- const findAddIssueButton = () => wrapper.find({ ref: 'newIssueBtn' });
-
- describe('Add issue button', () => {
- const hasNoAddButton = [ListType.promotion, ListType.blank, ListType.closed];
- const hasAddButton = [ListType.backlog, ListType.label, ListType.milestone, 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 render when logged out', () => {
- createComponent();
-
- expect(findAddIssueButton().exists()).toBe(true);
- });
- });
-
describe('Given different list types', () => {
it('is expandable when List Type is `backlog`', () => {
createComponent({ listType: ListType.backlog });
@@ -109,64 +78,17 @@ describe('Board Column Component', () => {
});
});
- describe('expanding / collapsing the column', () => {
- it('does not collapse when clicking the header', () => {
- createComponent();
- expect(isCollapsed()).toBe(false);
- wrapper.find('.board-header').trigger('click');
+ describe('expanded / collaped column', () => {
+ it('has class is-collapsed when list is collapsed', () => {
+ createComponent({ collapsed: false });
- return wrapper.vm.$nextTick().then(() => {
- expect(isCollapsed()).toBe(false);
- });
- });
-
- it('collapses expanded Column when clicking the collapse icon', () => {
- createComponent();
expect(wrapper.vm.list.isExpanded).toBe(true);
- wrapper.find('.board-title-caret').trigger('click');
-
- return wrapper.vm.$nextTick().then(() => {
- expect(isCollapsed()).toBe(true);
- });
});
- it('expands collapsed Column when clicking the expand icon', () => {
+ it('does not have class is-collapsed when list is expanded', () => {
createComponent({ collapsed: true });
- expect(isCollapsed()).toBe(true);
- wrapper.find('.board-title-caret').trigger('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');
- window.gon.current_user_id = 1;
-
- createComponent({ withLocalStorage: false });
- wrapper.find('.board-title-caret').trigger('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();
-
- wrapper.find('.board-title-caret').trigger('click');
-
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.vm.list.update).toHaveBeenCalledTimes(0);
- expect(localStorage.getItem(`${wrapper.vm.uniqueKey}.expanded`)).toBe(
- String(wrapper.vm.list.isExpanded),
- );
- });
+ expect(isCollapsed()).toBe(true);
});
});
});
diff --git a/spec/frontend/boards/components/board_list_header_spec.js b/spec/frontend/boards/components/board_list_header_spec.js
new file mode 100644
index 00000000000..95673da1c56
--- /dev/null
+++ b/spec/frontend/boards/components/board_list_header_spec.js
@@ -0,0 +1,166 @@
+import Vue from 'vue';
+import { shallowMount } from '@vue/test-utils';
+import AxiosMockAdapter from 'axios-mock-adapter';
+
+import BoardListHeader from '~/boards/components/board_list_header.vue';
+import List from '~/boards/models/list';
+import { ListType } from '~/boards/constants';
+import axios from '~/lib/utils/axios_utils';
+
+import { TEST_HOST } from 'helpers/test_constants';
+import { listObj } from 'jest/boards/mock_data';
+
+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,
+ } = {}) => {
+ 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: {
+ boardId,
+ disabled: false,
+ issueLinkBase: '/',
+ rootPath: '/',
+ list,
+ },
+ });
+ };
+
+ 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.promotion, ListType.blank, ListType.closed];
+ const hasAddButton = [ListType.backlog, ListType.label, ListType.milestone, 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 render when logged out', () => {
+ createComponent();
+
+ expect(findAddIssueButton().exists()).toBe(true);
+ });
+ });
+
+ 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"]').vm.$emit('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');
+ window.gon.current_user_id = 1;
+
+ 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();
+
+ 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/stores/actions_spec.js b/spec/frontend/boards/stores/actions_spec.js
index d23393db60d..0debca1310a 100644
--- a/spec/frontend/boards/stores/actions_spec.js
+++ b/spec/frontend/boards/stores/actions_spec.js
@@ -1,4 +1,6 @@
import actions from '~/boards/stores/actions';
+import * as types from '~/boards/stores/mutation_types';
+import testAction from 'helpers/vuex_action_helper';
const expectNotImplemented = action => {
it('is not implemented', () => {
@@ -7,7 +9,20 @@ const expectNotImplemented = action => {
};
describe('setEndpoints', () => {
- expectNotImplemented(actions.setEndpoints);
+ it('sets endpoints object', () => {
+ const mockEndpoints = {
+ foo: 'bar',
+ bar: 'baz',
+ };
+
+ return testAction(
+ actions.setEndpoints,
+ mockEndpoints,
+ {},
+ [{ type: types.SET_ENDPOINTS, payload: mockEndpoints }],
+ [],
+ );
+ });
});
describe('fetchLists', () => {
diff --git a/spec/frontend/boards/stores/mutations_spec.js b/spec/frontend/boards/stores/mutations_spec.js
index aa477766978..bc57c30b354 100644
--- a/spec/frontend/boards/stores/mutations_spec.js
+++ b/spec/frontend/boards/stores/mutations_spec.js
@@ -1,4 +1,6 @@
import mutations from '~/boards/stores/mutations';
+import * as types from '~/boards/stores/mutation_types';
+import defaultState from '~/boards/stores/state';
const expectNotImplemented = action => {
it('is not implemented', () => {
@@ -6,86 +8,107 @@ const expectNotImplemented = action => {
});
};
-describe('SET_ENDPOINTS', () => {
- expectNotImplemented(mutations.SET_ENDPOINTS);
-});
+describe('Board Store Mutations', () => {
+ let state;
-describe('REQUEST_ADD_LIST', () => {
- expectNotImplemented(mutations.REQUEST_ADD_LIST);
-});
+ beforeEach(() => {
+ state = defaultState();
+ });
-describe('RECEIVE_ADD_LIST_SUCCESS', () => {
- expectNotImplemented(mutations.RECEIVE_ADD_LIST_SUCCESS);
-});
+ describe('SET_ENDPOINTS', () => {
+ it('Should set initial Boards data to state', () => {
+ const endpoints = {
+ boardsEndpoint: '/boards/',
+ recentBoardsEndpoint: '/boards/',
+ listsEndpoint: '/boards/lists',
+ bulkUpdatePath: '/boards/bulkUpdate',
+ boardId: 1,
+ fullPath: 'gitlab-org',
+ };
+
+ mutations[types.SET_ENDPOINTS](state, endpoints);
+
+ expect(state.endpoints).toEqual(endpoints);
+ });
+ });
-describe('RECEIVE_ADD_LIST_ERROR', () => {
- expectNotImplemented(mutations.RECEIVE_ADD_LIST_ERROR);
-});
+ describe('REQUEST_ADD_LIST', () => {
+ expectNotImplemented(mutations.REQUEST_ADD_LIST);
+ });
-describe('REQUEST_UPDATE_LIST', () => {
- expectNotImplemented(mutations.REQUEST_UPDATE_LIST);
-});
+ describe('RECEIVE_ADD_LIST_SUCCESS', () => {
+ expectNotImplemented(mutations.RECEIVE_ADD_LIST_SUCCESS);
+ });
-describe('RECEIVE_UPDATE_LIST_SUCCESS', () => {
- expectNotImplemented(mutations.RECEIVE_UPDATE_LIST_SUCCESS);
-});
+ describe('RECEIVE_ADD_LIST_ERROR', () => {
+ expectNotImplemented(mutations.RECEIVE_ADD_LIST_ERROR);
+ });
-describe('RECEIVE_UPDATE_LIST_ERROR', () => {
- expectNotImplemented(mutations.RECEIVE_UPDATE_LIST_ERROR);
-});
+ describe('REQUEST_UPDATE_LIST', () => {
+ expectNotImplemented(mutations.REQUEST_UPDATE_LIST);
+ });
-describe('REQUEST_REMOVE_LIST', () => {
- expectNotImplemented(mutations.REQUEST_REMOVE_LIST);
-});
+ describe('RECEIVE_UPDATE_LIST_SUCCESS', () => {
+ expectNotImplemented(mutations.RECEIVE_UPDATE_LIST_SUCCESS);
+ });
-describe('RECEIVE_REMOVE_LIST_SUCCESS', () => {
- expectNotImplemented(mutations.RECEIVE_REMOVE_LIST_SUCCESS);
-});
+ describe('RECEIVE_UPDATE_LIST_ERROR', () => {
+ expectNotImplemented(mutations.RECEIVE_UPDATE_LIST_ERROR);
+ });
-describe('RECEIVE_REMOVE_LIST_ERROR', () => {
- expectNotImplemented(mutations.RECEIVE_REMOVE_LIST_ERROR);
-});
+ describe('REQUEST_REMOVE_LIST', () => {
+ expectNotImplemented(mutations.REQUEST_REMOVE_LIST);
+ });
-describe('REQUEST_ADD_ISSUE', () => {
- expectNotImplemented(mutations.REQUEST_ADD_ISSUE);
-});
+ describe('RECEIVE_REMOVE_LIST_SUCCESS', () => {
+ expectNotImplemented(mutations.RECEIVE_REMOVE_LIST_SUCCESS);
+ });
-describe('RECEIVE_ADD_ISSUE_SUCCESS', () => {
- expectNotImplemented(mutations.RECEIVE_ADD_ISSUE_SUCCESS);
-});
+ describe('RECEIVE_REMOVE_LIST_ERROR', () => {
+ expectNotImplemented(mutations.RECEIVE_REMOVE_LIST_ERROR);
+ });
-describe('RECEIVE_ADD_ISSUE_ERROR', () => {
- expectNotImplemented(mutations.RECEIVE_ADD_ISSUE_ERROR);
-});
+ describe('REQUEST_ADD_ISSUE', () => {
+ expectNotImplemented(mutations.REQUEST_ADD_ISSUE);
+ });
-describe('REQUEST_MOVE_ISSUE', () => {
- expectNotImplemented(mutations.REQUEST_MOVE_ISSUE);
-});
+ describe('RECEIVE_ADD_ISSUE_SUCCESS', () => {
+ expectNotImplemented(mutations.RECEIVE_ADD_ISSUE_SUCCESS);
+ });
-describe('RECEIVE_MOVE_ISSUE_SUCCESS', () => {
- expectNotImplemented(mutations.RECEIVE_MOVE_ISSUE_SUCCESS);
-});
+ describe('RECEIVE_ADD_ISSUE_ERROR', () => {
+ expectNotImplemented(mutations.RECEIVE_ADD_ISSUE_ERROR);
+ });
-describe('RECEIVE_MOVE_ISSUE_ERROR', () => {
- expectNotImplemented(mutations.RECEIVE_MOVE_ISSUE_ERROR);
-});
+ describe('REQUEST_MOVE_ISSUE', () => {
+ expectNotImplemented(mutations.REQUEST_MOVE_ISSUE);
+ });
-describe('REQUEST_UPDATE_ISSUE', () => {
- expectNotImplemented(mutations.REQUEST_UPDATE_ISSUE);
-});
+ describe('RECEIVE_MOVE_ISSUE_SUCCESS', () => {
+ expectNotImplemented(mutations.RECEIVE_MOVE_ISSUE_SUCCESS);
+ });
-describe('RECEIVE_UPDATE_ISSUE_SUCCESS', () => {
- expectNotImplemented(mutations.RECEIVE_UPDATE_ISSUE_SUCCESS);
-});
+ describe('RECEIVE_MOVE_ISSUE_ERROR', () => {
+ expectNotImplemented(mutations.RECEIVE_MOVE_ISSUE_ERROR);
+ });
-describe('RECEIVE_UPDATE_ISSUE_ERROR', () => {
- expectNotImplemented(mutations.RECEIVE_UPDATE_ISSUE_ERROR);
-});
+ describe('REQUEST_UPDATE_ISSUE', () => {
+ expectNotImplemented(mutations.REQUEST_UPDATE_ISSUE);
+ });
-describe('SET_CURRENT_PAGE', () => {
- expectNotImplemented(mutations.SET_CURRENT_PAGE);
-});
+ describe('RECEIVE_UPDATE_ISSUE_SUCCESS', () => {
+ expectNotImplemented(mutations.RECEIVE_UPDATE_ISSUE_SUCCESS);
+ });
-describe('TOGGLE_EMPTY_STATE', () => {
- expectNotImplemented(mutations.TOGGLE_EMPTY_STATE);
+ describe('RECEIVE_UPDATE_ISSUE_ERROR', () => {
+ expectNotImplemented(mutations.RECEIVE_UPDATE_ISSUE_ERROR);
+ });
+
+ describe('SET_CURRENT_PAGE', () => {
+ expectNotImplemented(mutations.SET_CURRENT_PAGE);
+ });
+
+ describe('TOGGLE_EMPTY_STATE', () => {
+ expectNotImplemented(mutations.TOGGLE_EMPTY_STATE);
+ });
});
diff --git a/spec/frontend/ci_variable_list/components/ci_variable_modal_spec.js b/spec/frontend/ci_variable_list/components/ci_variable_modal_spec.js
index 9179302f786..094fdcdc185 100644
--- a/spec/frontend/ci_variable_list/components/ci_variable_modal_spec.js
+++ b/spec/frontend/ci_variable_list/components/ci_variable_modal_spec.js
@@ -105,6 +105,46 @@ describe('Ci variable modal', () => {
});
});
+ describe('Adding a new non-AWS variable', () => {
+ beforeEach(() => {
+ const [variable] = mockData.mockVariables;
+ const invalidKeyVariable = {
+ ...variable,
+ key: 'key',
+ value: 'value',
+ secret_value: 'secret_value',
+ };
+ createComponent(mount);
+ store.state.variable = invalidKeyVariable;
+ });
+
+ it('does not show AWS guidance tip', () => {
+ const tip = wrapper.find(`div[data-testid='aws-guidance-tip']`);
+ expect(tip.exists()).toBe(true);
+ expect(tip.isVisible()).toBe(false);
+ });
+ });
+
+ describe('Adding a new AWS variable', () => {
+ beforeEach(() => {
+ const [variable] = mockData.mockVariables;
+ const invalidKeyVariable = {
+ ...variable,
+ key: AWS_ACCESS_KEY_ID,
+ value: 'AKIAIOSFODNN7EXAMPLEjdhy',
+ secret_value: 'AKIAIOSFODNN7EXAMPLEjdhy',
+ };
+ createComponent(mount);
+ store.state.variable = invalidKeyVariable;
+ });
+
+ it('shows AWS guidance tip', () => {
+ const tip = wrapper.find(`[data-testid='aws-guidance-tip']`);
+ expect(tip.exists()).toBe(true);
+ expect(tip.isVisible()).toBe(true);
+ });
+ });
+
describe('Editing a variable', () => {
beforeEach(() => {
const [variable] = mockData.mockVariables;
diff --git a/spec/frontend/clusters/clusters_bundle_spec.js b/spec/frontend/clusters/clusters_bundle_spec.js
index 9d0ed423759..a9870e4db57 100644
--- a/spec/frontend/clusters/clusters_bundle_spec.js
+++ b/spec/frontend/clusters/clusters_bundle_spec.js
@@ -268,13 +268,18 @@ describe('Clusters', () => {
cluster.store.state.applications[applicationId].status = INSTALLABLE;
+ const params = {};
+ if (applicationId === 'knative') {
+ params.hostname = 'test-example.com';
+ }
+
// eslint-disable-next-line promise/valid-params
cluster
- .installApplication({ id: applicationId })
+ .installApplication({ id: applicationId, params })
.then(() => {
expect(cluster.store.state.applications[applicationId].status).toEqual(INSTALLING);
expect(cluster.store.state.applications[applicationId].requestReason).toEqual(null);
- expect(cluster.service.installApplication).toHaveBeenCalledWith(applicationId, undefined);
+ expect(cluster.service.installApplication).toHaveBeenCalledWith(applicationId, params);
done();
})
.catch();
diff --git a/spec/frontend/clusters/components/__snapshots__/applications_spec.js.snap b/spec/frontend/clusters/components/__snapshots__/applications_spec.js.snap
new file mode 100644
index 00000000000..92237590550
--- /dev/null
+++ b/spec/frontend/clusters/components/__snapshots__/applications_spec.js.snap
@@ -0,0 +1,89 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Applications Cert-Manager application shows the correct description 1`] = `
+<p
+ data-testid="certManagerDescription"
+>
+ Cert-Manager is a native Kubernetes certificate management controller that helps with issuing certificates. Installing Cert-Manager on your cluster will issue a certificate by
+ <a
+ class="gl-link"
+ href="https://letsencrypt.org/"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ Let's Encrypt
+ </a>
+ and ensure that certificates are valid and up-to-date.
+</p>
+`;
+
+exports[`Applications Crossplane application shows the correct description 1`] = `
+<p
+ data-testid="crossplaneDescription"
+>
+ Crossplane enables declarative provisioning of managed services from your cloud of choice using
+ <code>
+ kubectl
+ </code>
+ or
+ <a
+ class="gl-link"
+ href="https://docs.gitlab.com/ee/user/clusters/applications.html#crossplane"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ GitLab Integration
+ </a>
+ . Crossplane runs inside your Kubernetes cluster and supports secure connectivity and secrets management between app containers and the cloud services they depend on.
+</p>
+`;
+
+exports[`Applications Ingress application shows the correct warning message 1`] = `
+<strong
+ data-testid="ingressCostWarning"
+>
+ Installing Ingress may incur additional costs. Learn more about
+ <a
+ class="gl-link"
+ href="https://cloud.google.com/compute/pricing#lb"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ pricing
+ </a>
+ .
+</strong>
+`;
+
+exports[`Applications Knative application shows the correct description 1`] = `
+<span
+ data-testid="installedVia"
+>
+ installed via
+ <a
+ class="gl-link"
+ href=""
+ rel="noopener"
+ target="_blank"
+ >
+ Cloud Run
+ </a>
+</span>
+`;
+
+exports[`Applications Prometheus application shows the correct description 1`] = `
+<span
+ data-testid="prometheusDescription"
+>
+ Prometheus is an open-source monitoring system with
+ <a
+ class="gl-link"
+ href="https://docs.gitlab.com/ce/user/project/integrations/prometheus.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ GitLab Integration
+ </a>
+ to monitor deployed applications.
+</span>
+`;
diff --git a/spec/frontend/clusters/components/application_row_spec.js b/spec/frontend/clusters/components/application_row_spec.js
index 33ff1424c61..94bdd7b7778 100644
--- a/spec/frontend/clusters/components/application_row_spec.js
+++ b/spec/frontend/clusters/components/application_row_spec.js
@@ -1,242 +1,194 @@
-import Vue from 'vue';
import { shallowMount } from '@vue/test-utils';
-import mountComponent from 'helpers/vue_mount_component_helper';
+import { GlSprintf } from '@gitlab/ui';
import eventHub from '~/clusters/event_hub';
-import { APPLICATION_STATUS } from '~/clusters/constants';
-import applicationRow from '~/clusters/components/application_row.vue';
+import { APPLICATION_STATUS, ELASTIC_STACK } from '~/clusters/constants';
+import ApplicationRow from '~/clusters/components/application_row.vue';
import UninstallApplicationConfirmationModal from '~/clusters/components/uninstall_application_confirmation_modal.vue';
+import UpdateApplicationConfirmationModal from '~/clusters/components/update_application_confirmation_modal.vue';
import { DEFAULT_APPLICATION_STATE } from '../services/mock_data';
describe('Application Row', () => {
- let vm;
- let ApplicationRow;
-
- beforeEach(() => {
- ApplicationRow = Vue.extend(applicationRow);
- });
+ let wrapper;
afterEach(() => {
- vm.$destroy();
+ wrapper.destroy();
});
+ const mountComponent = data => {
+ wrapper = shallowMount(ApplicationRow, {
+ stubs: { GlSprintf },
+ propsData: {
+ ...DEFAULT_APPLICATION_STATE,
+ ...data,
+ },
+ });
+ };
+
describe('Title', () => {
it('shows title', () => {
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
- titleLink: null,
- });
- const title = vm.$el.querySelector('.js-cluster-application-title');
+ mountComponent({ titleLink: null });
+
+ const title = wrapper.find('.js-cluster-application-title');
- expect(title.tagName).toEqual('SPAN');
- expect(title.textContent.trim()).toEqual(DEFAULT_APPLICATION_STATE.title);
+ expect(title.element).toBeInstanceOf(HTMLSpanElement);
+ expect(title.text()).toEqual(DEFAULT_APPLICATION_STATE.title);
});
it('shows title link', () => {
expect(DEFAULT_APPLICATION_STATE.titleLink).toBeDefined();
+ mountComponent();
+ const title = wrapper.find('.js-cluster-application-title');
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
- });
- const title = vm.$el.querySelector('.js-cluster-application-title');
-
- expect(title.tagName).toEqual('A');
- expect(title.textContent.trim()).toEqual(DEFAULT_APPLICATION_STATE.title);
+ expect(title.element).toBeInstanceOf(HTMLAnchorElement);
+ expect(title.text()).toEqual(DEFAULT_APPLICATION_STATE.title);
});
});
describe('Install button', () => {
+ const button = () => wrapper.find('.js-cluster-application-install-button');
+ const checkButtonState = (label, loading, disabled) => {
+ expect(button().props('label')).toEqual(label);
+ expect(button().props('loading')).toEqual(loading);
+ expect(button().props('disabled')).toEqual(disabled);
+ };
+
it('has indeterminate state on page load', () => {
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
- status: null,
- });
+ mountComponent({ status: null });
- expect(vm.installButtonLabel).toBeUndefined();
+ expect(button().props('label')).toBeUndefined();
});
it('has install button', () => {
- const installationBtn = vm.$el.querySelector('.js-cluster-application-install-button');
+ mountComponent();
- expect(installationBtn).not.toBe(null);
+ expect(button().exists()).toBe(true);
});
it('has disabled "Install" when APPLICATION_STATUS.NOT_INSTALLABLE', () => {
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
- status: APPLICATION_STATUS.NOT_INSTALLABLE,
- });
+ mountComponent({ status: APPLICATION_STATUS.NOT_INSTALLABLE });
- expect(vm.installButtonLabel).toEqual('Install');
- expect(vm.installButtonLoading).toEqual(false);
- expect(vm.installButtonDisabled).toEqual(true);
+ checkButtonState('Install', false, true);
});
it('has enabled "Install" when APPLICATION_STATUS.INSTALLABLE', () => {
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
- status: APPLICATION_STATUS.INSTALLABLE,
- });
+ mountComponent({ status: APPLICATION_STATUS.INSTALLABLE });
- expect(vm.installButtonLabel).toEqual('Install');
- expect(vm.installButtonLoading).toEqual(false);
- expect(vm.installButtonDisabled).toEqual(false);
+ checkButtonState('Install', false, false);
});
it('has loading "Installing" when APPLICATION_STATUS.INSTALLING', () => {
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
- status: APPLICATION_STATUS.INSTALLING,
- });
+ mountComponent({ status: APPLICATION_STATUS.INSTALLING });
- expect(vm.installButtonLabel).toEqual('Installing');
- expect(vm.installButtonLoading).toEqual(true);
- expect(vm.installButtonDisabled).toEqual(true);
+ checkButtonState('Installing', true, true);
});
it('has disabled "Installed" when application is installed and not uninstallable', () => {
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
+ mountComponent({
status: APPLICATION_STATUS.INSTALLED,
installed: true,
uninstallable: false,
});
- expect(vm.installButtonLabel).toEqual('Installed');
- expect(vm.installButtonLoading).toEqual(false);
- expect(vm.installButtonDisabled).toEqual(true);
+ checkButtonState('Installed', false, true);
});
it('hides when application is installed and uninstallable', () => {
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
+ mountComponent({
status: APPLICATION_STATUS.INSTALLED,
installed: true,
uninstallable: true,
});
- const installBtn = vm.$el.querySelector('.js-cluster-application-install-button');
- expect(installBtn).toBe(null);
+ expect(button().exists()).toBe(false);
});
it('has enabled "Install" when install fails', () => {
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
+ mountComponent({
status: APPLICATION_STATUS.INSTALLABLE,
installFailed: true,
});
- expect(vm.installButtonLabel).toEqual('Install');
- expect(vm.installButtonLoading).toEqual(false);
- expect(vm.installButtonDisabled).toEqual(false);
+ checkButtonState('Install', false, false);
});
it('has enabled "Install" when REQUEST_FAILURE (so you can try installing again)', () => {
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
- status: APPLICATION_STATUS.INSTALLABLE,
- });
+ mountComponent({ status: APPLICATION_STATUS.INSTALLABLE });
- expect(vm.installButtonLabel).toEqual('Install');
- expect(vm.installButtonLoading).toEqual(false);
- expect(vm.installButtonDisabled).toEqual(false);
+ checkButtonState('Install', false, false);
});
it('clicking install button emits event', () => {
- jest.spyOn(eventHub, '$emit');
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
- status: APPLICATION_STATUS.INSTALLABLE,
- });
- const installButton = vm.$el.querySelector('.js-cluster-application-install-button');
+ const spy = jest.spyOn(eventHub, '$emit');
+ mountComponent({ status: APPLICATION_STATUS.INSTALLABLE });
- installButton.click();
+ button().vm.$emit('click');
- expect(eventHub.$emit).toHaveBeenCalledWith('installApplication', {
+ expect(spy).toHaveBeenCalledWith('installApplication', {
id: DEFAULT_APPLICATION_STATE.id,
params: {},
});
});
it('clicking install button when installApplicationRequestParams are provided emits event', () => {
- jest.spyOn(eventHub, '$emit');
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
+ const spy = jest.spyOn(eventHub, '$emit');
+ mountComponent({
status: APPLICATION_STATUS.INSTALLABLE,
installApplicationRequestParams: { hostname: 'jupyter' },
});
- const installButton = vm.$el.querySelector('.js-cluster-application-install-button');
- installButton.click();
+ button().vm.$emit('click');
- expect(eventHub.$emit).toHaveBeenCalledWith('installApplication', {
+ expect(spy).toHaveBeenCalledWith('installApplication', {
id: DEFAULT_APPLICATION_STATE.id,
params: { hostname: 'jupyter' },
});
});
it('clicking disabled install button emits nothing', () => {
- jest.spyOn(eventHub, '$emit');
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
- status: APPLICATION_STATUS.INSTALLING,
- });
- const installButton = vm.$el.querySelector('.js-cluster-application-install-button');
+ const spy = jest.spyOn(eventHub, '$emit');
+ mountComponent({ status: APPLICATION_STATUS.INSTALLING });
- expect(vm.installButtonDisabled).toEqual(true);
+ expect(button().props('disabled')).toEqual(true);
- installButton.click();
+ button().vm.$emit('click');
- expect(eventHub.$emit).not.toHaveBeenCalled();
+ expect(spy).not.toHaveBeenCalled();
});
});
describe('Uninstall button', () => {
it('displays button when app is installed and uninstallable', () => {
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
+ mountComponent({
installed: true,
uninstallable: true,
status: APPLICATION_STATUS.NOT_INSTALLABLE,
});
- const uninstallButton = vm.$el.querySelector('.js-cluster-application-uninstall-button');
+ const uninstallButton = wrapper.find('.js-cluster-application-uninstall-button');
- expect(uninstallButton).toBeTruthy();
+ expect(uninstallButton.exists()).toBe(true);
});
- it('displays a success toast message if application uninstall was successful', () => {
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
+ it('displays a success toast message if application uninstall was successful', async () => {
+ mountComponent({
title: 'GitLab Runner',
uninstallSuccessful: false,
});
- vm.$toast = { show: jest.fn() };
- vm.uninstallSuccessful = true;
+ wrapper.vm.$toast = { show: jest.fn() };
+ wrapper.setProps({ uninstallSuccessful: true });
- return vm.$nextTick(() => {
- expect(vm.$toast.show).toHaveBeenCalledWith('GitLab Runner uninstalled successfully.');
- });
+ await wrapper.vm.$nextTick();
+ expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(
+ 'GitLab Runner uninstalled successfully.',
+ );
});
});
describe('when confirmation modal triggers confirm event', () => {
- let wrapper;
-
- beforeEach(() => {
- wrapper = shallowMount(ApplicationRow, {
- propsData: {
- ...DEFAULT_APPLICATION_STATE,
- },
- });
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
it('triggers uninstallApplication event', () => {
jest.spyOn(eventHub, '$emit');
+ mountComponent();
wrapper.find(UninstallApplicationConfirmationModal).vm.$emit('confirm');
expect(eventHub.$emit).toHaveBeenCalledWith('uninstallApplication', {
@@ -246,172 +198,226 @@ describe('Application Row', () => {
});
describe('Update button', () => {
+ const button = () => wrapper.find('.js-cluster-application-update-button');
+
it('has indeterminate state on page load', () => {
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
- status: null,
- });
- const updateBtn = vm.$el.querySelector('.js-cluster-application-update-button');
+ mountComponent();
- expect(updateBtn).toBe(null);
+ expect(button().exists()).toBe(false);
});
it('has enabled "Update" when "updateAvailable" is true', () => {
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
- updateAvailable: true,
- });
- const updateBtn = vm.$el.querySelector('.js-cluster-application-update-button');
+ mountComponent({ updateAvailable: true });
- expect(updateBtn).not.toBe(null);
- expect(updateBtn.innerHTML).toContain('Update');
+ expect(button().exists()).toBe(true);
+ expect(button().props('label')).toContain('Update');
});
it('has enabled "Retry update" when update process fails', () => {
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
+ mountComponent({
status: APPLICATION_STATUS.INSTALLED,
updateFailed: true,
});
- const updateBtn = vm.$el.querySelector('.js-cluster-application-update-button');
- expect(updateBtn).not.toBe(null);
- expect(updateBtn.innerHTML).toContain('Retry update');
+ expect(button().exists()).toBe(true);
+ expect(button().props('label')).toContain('Retry update');
});
it('has disabled "Updating" when APPLICATION_STATUS.UPDATING', () => {
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
- status: APPLICATION_STATUS.UPDATING,
- });
- const updateBtn = vm.$el.querySelector('.js-cluster-application-update-button');
+ mountComponent({ status: APPLICATION_STATUS.UPDATING });
- expect(updateBtn).not.toBe(null);
- expect(vm.isUpdating).toBe(true);
- expect(updateBtn.innerHTML).toContain('Updating');
+ expect(button().exists()).toBe(true);
+ expect(button().props('label')).toContain('Updating');
});
it('clicking update button emits event', () => {
- jest.spyOn(eventHub, '$emit');
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
+ const spy = jest.spyOn(eventHub, '$emit');
+ mountComponent({
status: APPLICATION_STATUS.INSTALLED,
updateAvailable: true,
});
- const updateBtn = vm.$el.querySelector('.js-cluster-application-update-button');
- updateBtn.click();
+ button().vm.$emit('click');
- expect(eventHub.$emit).toHaveBeenCalledWith('updateApplication', {
+ expect(spy).toHaveBeenCalledWith('updateApplication', {
id: DEFAULT_APPLICATION_STATE.id,
params: {},
});
});
it('clicking disabled update button emits nothing', () => {
- jest.spyOn(eventHub, '$emit');
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
- status: APPLICATION_STATUS.UPDATING,
- });
- const updateBtn = vm.$el.querySelector('.js-cluster-application-update-button');
+ const spy = jest.spyOn(eventHub, '$emit');
+ mountComponent({ status: APPLICATION_STATUS.UPDATING });
- updateBtn.click();
+ button().vm.$emit('click');
- expect(eventHub.$emit).not.toHaveBeenCalled();
+ expect(spy).not.toHaveBeenCalled();
});
it('displays an error message if application update failed', () => {
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
+ mountComponent({
title: 'GitLab Runner',
status: APPLICATION_STATUS.INSTALLED,
updateFailed: true,
});
- const failureMessage = vm.$el.querySelector('.js-cluster-application-update-details');
+ const failureMessage = wrapper.find('.js-cluster-application-update-details');
- expect(failureMessage).not.toBe(null);
- expect(failureMessage.innerHTML).toContain(
+ expect(failureMessage.exists()).toBe(true);
+ expect(failureMessage.text()).toContain(
'Update failed. Please check the logs and try again.',
);
});
- it('displays a success toast message if application update was successful', () => {
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
+ it('displays a success toast message if application update was successful', async () => {
+ mountComponent({
title: 'GitLab Runner',
updateSuccessful: false,
});
- vm.$toast = { show: jest.fn() };
- vm.updateSuccessful = true;
+ wrapper.vm.$toast = { show: jest.fn() };
+ wrapper.setProps({ updateSuccessful: true });
- return vm.$nextTick(() => {
- expect(vm.$toast.show).toHaveBeenCalledWith('GitLab Runner updated successfully.');
+ await wrapper.vm.$nextTick();
+ expect(wrapper.vm.$toast.show).toHaveBeenCalledWith('GitLab Runner updated successfully.');
+ });
+
+ describe('when updating does not require confirmation', () => {
+ beforeEach(() => mountComponent({ updateAvailable: true }));
+
+ it('the modal is not rendered', () => {
+ expect(wrapper.contains(UpdateApplicationConfirmationModal)).toBe(false);
+ });
+
+ it('the correct button is rendered', () => {
+ expect(wrapper.contains("[data-qa-selector='update_button']")).toBe(true);
+ });
+ });
+
+ describe('when updating requires confirmation', () => {
+ beforeEach(() => {
+ mountComponent({
+ updateAvailable: true,
+ id: ELASTIC_STACK,
+ version: '1.1.2',
+ });
+ });
+
+ it('displays a modal', () => {
+ expect(wrapper.contains(UpdateApplicationConfirmationModal)).toBe(true);
+ });
+
+ it('the correct button is rendered', () => {
+ expect(wrapper.contains("[data-qa-selector='update_button_with_confirmation']")).toBe(true);
+ });
+
+ it('triggers updateApplication event', () => {
+ jest.spyOn(eventHub, '$emit');
+ wrapper.find(UpdateApplicationConfirmationModal).vm.$emit('confirm');
+
+ expect(eventHub.$emit).toHaveBeenCalledWith('updateApplication', {
+ id: ELASTIC_STACK,
+ params: {},
+ });
+ });
+ });
+
+ describe('updating Elastic Stack special case', () => {
+ it('needs confirmation if version is lower than 3.0.0', () => {
+ mountComponent({
+ updateAvailable: true,
+ id: ELASTIC_STACK,
+ version: '1.1.2',
+ });
+
+ expect(wrapper.contains("[data-qa-selector='update_button_with_confirmation']")).toBe(true);
+ expect(wrapper.contains(UpdateApplicationConfirmationModal)).toBe(true);
+ });
+
+ it('does not need confirmation is version is 3.0.0', () => {
+ mountComponent({
+ updateAvailable: true,
+ id: ELASTIC_STACK,
+ version: '3.0.0',
+ });
+
+ expect(wrapper.contains("[data-qa-selector='update_button']")).toBe(true);
+ expect(wrapper.contains(UpdateApplicationConfirmationModal)).toBe(false);
+ });
+
+ it('does not need confirmation if version is higher than 3.0.0', () => {
+ mountComponent({
+ updateAvailable: true,
+ id: ELASTIC_STACK,
+ version: '5.2.1',
+ });
+
+ expect(wrapper.contains("[data-qa-selector='update_button']")).toBe(true);
+ expect(wrapper.contains(UpdateApplicationConfirmationModal)).toBe(false);
});
});
});
describe('Version', () => {
+ const updateDetails = () => wrapper.find('.js-cluster-application-update-details');
+ const versionEl = () => wrapper.find('.js-cluster-application-update-version');
+
it('displays a version number if application has been updated', () => {
const version = '0.1.45';
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
+ mountComponent({
status: APPLICATION_STATUS.INSTALLED,
updateSuccessful: true,
version,
});
- const updateDetails = vm.$el.querySelector('.js-cluster-application-update-details');
- const versionEl = vm.$el.querySelector('.js-cluster-application-update-version');
- expect(updateDetails.innerHTML).toContain('Updated');
- expect(versionEl).not.toBe(null);
- expect(versionEl.innerHTML).toContain(version);
+ expect(updateDetails().text()).toBe(`Updated to chart v${version}`);
});
it('contains a link to the chart repo if application has been updated', () => {
const version = '0.1.45';
const chartRepo = 'https://gitlab.com/gitlab-org/charts/gitlab-runner';
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
+ mountComponent({
status: APPLICATION_STATUS.INSTALLED,
updateSuccessful: true,
chartRepo,
version,
});
- const versionEl = vm.$el.querySelector('.js-cluster-application-update-version');
- expect(versionEl.href).toEqual(chartRepo);
- expect(versionEl.target).toEqual('_blank');
+ expect(versionEl().attributes('href')).toEqual(chartRepo);
+ expect(versionEl().props('target')).toEqual('_blank');
});
it('does not display a version number if application update failed', () => {
const version = '0.1.45';
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
+ mountComponent({
status: APPLICATION_STATUS.INSTALLED,
updateFailed: true,
version,
});
- const updateDetails = vm.$el.querySelector('.js-cluster-application-update-details');
- const versionEl = vm.$el.querySelector('.js-cluster-application-update-version');
- expect(updateDetails.innerHTML).toContain('failed');
- expect(versionEl).toBe(null);
+ expect(updateDetails().text()).toBe('Update failed');
+ expect(versionEl().exists()).toBe(false);
+ });
+
+ it('displays updating when the application update is currently updating', () => {
+ mountComponent({
+ status: APPLICATION_STATUS.UPDATING,
+ updateSuccessful: true,
+ version: '1.2.3',
+ });
+
+ expect(updateDetails().text()).toBe('Updating');
+ expect(versionEl().exists()).toBe(false);
});
});
describe('Error block', () => {
+ const generalErrorMessage = () => wrapper.find('.js-cluster-application-general-error-message');
+
describe('when nothing fails', () => {
it('does not show error block', () => {
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
- });
- const generalErrorMessage = vm.$el.querySelector(
- '.js-cluster-application-general-error-message',
- );
+ mountComponent();
- expect(generalErrorMessage).toBeNull();
+ expect(generalErrorMessage().exists()).toBe(false);
});
});
@@ -420,8 +426,7 @@ describe('Application Row', () => {
const requestReason = 'We broke the request 0.0';
beforeEach(() => {
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
+ mountComponent({
status: APPLICATION_STATUS.ERROR,
statusReason,
requestReason,
@@ -430,37 +435,28 @@ describe('Application Row', () => {
});
it('shows status reason if it is available', () => {
- const statusErrorMessage = vm.$el.querySelector(
- '.js-cluster-application-status-error-message',
- );
+ const statusErrorMessage = wrapper.find('.js-cluster-application-status-error-message');
- expect(statusErrorMessage.textContent.trim()).toEqual(statusReason);
+ expect(statusErrorMessage.text()).toEqual(statusReason);
});
it('shows request reason if it is available', () => {
- const requestErrorMessage = vm.$el.querySelector(
- '.js-cluster-application-request-error-message',
- );
+ const requestErrorMessage = wrapper.find('.js-cluster-application-request-error-message');
- expect(requestErrorMessage.textContent.trim()).toEqual(requestReason);
+ expect(requestErrorMessage.text()).toEqual(requestReason);
});
});
describe('when install fails', () => {
beforeEach(() => {
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
+ mountComponent({
status: APPLICATION_STATUS.ERROR,
installFailed: true,
});
});
it('shows a general message indicating the installation failed', () => {
- const generalErrorMessage = vm.$el.querySelector(
- '.js-cluster-application-general-error-message',
- );
-
- expect(generalErrorMessage.textContent.trim()).toEqual(
+ expect(generalErrorMessage().text()).toEqual(
`Something went wrong while installing ${DEFAULT_APPLICATION_STATE.title}`,
);
});
@@ -468,19 +464,14 @@ describe('Application Row', () => {
describe('when uninstall fails', () => {
beforeEach(() => {
- vm = mountComponent(ApplicationRow, {
- ...DEFAULT_APPLICATION_STATE,
+ mountComponent({
status: APPLICATION_STATUS.ERROR,
uninstallFailed: true,
});
});
it('shows a general message indicating the uninstalling failed', () => {
- const generalErrorMessage = vm.$el.querySelector(
- '.js-cluster-application-general-error-message',
- );
-
- expect(generalErrorMessage.textContent.trim()).toEqual(
+ expect(generalErrorMessage().text()).toEqual(
`Something went wrong while uninstalling ${DEFAULT_APPLICATION_STATE.title}`,
);
});
diff --git a/spec/frontend/clusters/components/applications_spec.js b/spec/frontend/clusters/components/applications_spec.js
index 33b30891d5e..7fc771201c1 100644
--- a/spec/frontend/clusters/components/applications_spec.js
+++ b/spec/frontend/clusters/components/applications_spec.js
@@ -1,174 +1,175 @@
-import Vue from 'vue';
-import mountComponent from 'helpers/vue_mount_component_helper';
-import { shallowMount } from '@vue/test-utils';
-import applications from '~/clusters/components/applications.vue';
-import { CLUSTER_TYPE } from '~/clusters/constants';
+import { shallowMount, mount } from '@vue/test-utils';
+import Applications from '~/clusters/components/applications.vue';
+import { CLUSTER_TYPE, PROVIDER_TYPE } from '~/clusters/constants';
import { APPLICATIONS_MOCK_STATE } from '../services/mock_data';
import eventHub from '~/clusters/event_hub';
+import ApplicationRow from '~/clusters/components/application_row.vue';
import KnativeDomainEditor from '~/clusters/components/knative_domain_editor.vue';
import CrossplaneProviderStack from '~/clusters/components/crossplane_provider_stack.vue';
import IngressModsecuritySettings from '~/clusters/components/ingress_modsecurity_settings.vue';
import FluentdOutputSettings from '~/clusters/components/fluentd_output_settings.vue';
describe('Applications', () => {
- let vm;
- let Applications;
+ let wrapper;
beforeEach(() => {
- Applications = Vue.extend(applications);
-
gon.features = gon.features || {};
gon.features.managedAppsLocalTiller = false;
});
+ const createApp = ({ applications, type } = {}, isShallow) => {
+ const mountMethod = isShallow ? shallowMount : mount;
+
+ wrapper = mountMethod(Applications, {
+ stubs: { ApplicationRow },
+ propsData: {
+ type,
+ applications: { ...APPLICATIONS_MOCK_STATE, ...applications },
+ },
+ });
+ };
+
+ const createShallowApp = options => createApp(options, true);
+ const findByTestId = id => wrapper.find(`[data-testid="${id}"]`);
afterEach(() => {
- vm.$destroy();
+ wrapper.destroy();
});
describe('Project cluster applications', () => {
beforeEach(() => {
- vm = mountComponent(Applications, {
- applications: APPLICATIONS_MOCK_STATE,
- type: CLUSTER_TYPE.PROJECT,
- });
+ createApp({ type: CLUSTER_TYPE.PROJECT });
});
it('renders a row for Helm Tiller', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-helm')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-helm').exists()).toBe(true);
});
it('renders a row for Ingress', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-ingress')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-ingress').exists()).toBe(true);
});
it('renders a row for Cert-Manager', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-cert_manager')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-cert_manager').exists()).toBe(true);
});
it('renders a row for Crossplane', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-crossplane')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-crossplane').exists()).toBe(true);
});
it('renders a row for Prometheus', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-prometheus')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-prometheus').exists()).toBe(true);
});
it('renders a row for GitLab Runner', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-runner')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-runner').exists()).toBe(true);
});
it('renders a row for Jupyter', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-jupyter')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-jupyter').exists()).toBe(true);
});
it('renders a row for Knative', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-knative')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-knative').exists()).toBe(true);
});
it('renders a row for Elastic Stack', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-elastic_stack')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-elastic_stack').exists()).toBe(true);
});
it('renders a row for Fluentd', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-fluentd')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-fluentd').exists()).toBe(true);
});
});
describe('Group cluster applications', () => {
beforeEach(() => {
- vm = mountComponent(Applications, {
- type: CLUSTER_TYPE.GROUP,
- applications: APPLICATIONS_MOCK_STATE,
- });
+ createApp({ type: CLUSTER_TYPE.GROUP });
});
it('renders a row for Helm Tiller', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-helm')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-helm').exists()).toBe(true);
});
it('renders a row for Ingress', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-ingress')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-ingress').exists()).toBe(true);
});
it('renders a row for Cert-Manager', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-cert_manager')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-cert_manager').exists()).toBe(true);
});
it('renders a row for Crossplane', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-crossplane')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-crossplane').exists()).toBe(true);
});
it('renders a row for Prometheus', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-prometheus')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-prometheus').exists()).toBe(true);
});
it('renders a row for GitLab Runner', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-runner')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-runner').exists()).toBe(true);
});
it('renders a row for Jupyter', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-jupyter')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-jupyter').exists()).toBe(true);
});
it('renders a row for Knative', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-knative')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-knative').exists()).toBe(true);
});
it('renders a row for Elastic Stack', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-elastic_stack')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-elastic_stack').exists()).toBe(true);
});
it('renders a row for Fluentd', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-fluentd')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-fluentd').exists()).toBe(true);
});
});
describe('Instance cluster applications', () => {
beforeEach(() => {
- vm = mountComponent(Applications, {
- type: CLUSTER_TYPE.INSTANCE,
- applications: APPLICATIONS_MOCK_STATE,
- });
+ createApp({ type: CLUSTER_TYPE.INSTANCE });
});
it('renders a row for Helm Tiller', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-helm')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-helm').exists()).toBe(true);
});
it('renders a row for Ingress', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-ingress')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-ingress').exists()).toBe(true);
});
it('renders a row for Cert-Manager', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-cert_manager')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-cert_manager').exists()).toBe(true);
});
it('renders a row for Crossplane', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-crossplane')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-crossplane').exists()).toBe(true);
});
it('renders a row for Prometheus', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-prometheus')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-prometheus').exists()).toBe(true);
});
it('renders a row for GitLab Runner', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-runner')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-runner').exists()).toBe(true);
});
it('renders a row for Jupyter', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-jupyter')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-jupyter').exists()).toBe(true);
});
it('renders a row for Knative', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-knative')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-knative').exists()).toBe(true);
});
it('renders a row for Elastic Stack', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-elastic_stack')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-elastic_stack').exists()).toBe(true);
});
it('renders a row for Fluentd', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-fluentd')).not.toBeNull();
+ expect(wrapper.find('.js-cluster-application-row-fluentd').exists()).toBe(true);
});
});
@@ -179,20 +180,21 @@ describe('Applications', () => {
});
it('does not render a row for Helm Tiller', () => {
- vm = mountComponent(Applications, {
- applications: APPLICATIONS_MOCK_STATE,
- });
-
- expect(vm.$el.querySelector('.js-cluster-application-row-helm')).toBeNull();
+ createApp();
+ expect(wrapper.find('.js-cluster-application-row-helm').exists()).toBe(false);
});
});
});
describe('Ingress application', () => {
+ it('shows the correct warning message', () => {
+ createApp();
+ expect(findByTestId('ingressCostWarning').element).toMatchSnapshot();
+ });
+
describe('with nested component', () => {
const propsData = {
applications: {
- ...APPLICATIONS_MOCK_STATE,
ingress: {
title: 'Ingress',
status: 'installed',
@@ -200,13 +202,8 @@ describe('Applications', () => {
},
};
- let wrapper;
- beforeEach(() => {
- wrapper = shallowMount(Applications, { propsData });
- });
- afterEach(() => {
- wrapper.destroy();
- });
+ beforeEach(() => createShallowApp(propsData));
+
it('renders IngressModsecuritySettings', () => {
const modsecuritySettings = wrapper.find(IngressModsecuritySettings);
expect(modsecuritySettings.exists()).toBe(true);
@@ -216,9 +213,8 @@ describe('Applications', () => {
describe('when installed', () => {
describe('with ip address', () => {
it('renders ip address with a clipboard button', () => {
- vm = mountComponent(Applications, {
+ createApp({
applications: {
- ...APPLICATIONS_MOCK_STATE,
ingress: {
title: 'Ingress',
status: 'installed',
@@ -227,17 +223,16 @@ describe('Applications', () => {
},
});
- expect(vm.$el.querySelector('.js-endpoint').value).toEqual('0.0.0.0');
-
- expect(
- vm.$el.querySelector('.js-clipboard-btn').getAttribute('data-clipboard-text'),
- ).toEqual('0.0.0.0');
+ expect(wrapper.find('.js-endpoint').element.value).toEqual('0.0.0.0');
+ expect(wrapper.find('.js-clipboard-btn').attributes('data-clipboard-text')).toEqual(
+ '0.0.0.0',
+ );
});
});
describe('with hostname', () => {
it('renders hostname with a clipboard button', () => {
- vm = mountComponent(Applications, {
+ createApp({
applications: {
ingress: {
title: 'Ingress',
@@ -257,19 +252,18 @@ describe('Applications', () => {
},
});
- expect(vm.$el.querySelector('.js-endpoint').value).toEqual('localhost.localdomain');
+ expect(wrapper.find('.js-endpoint').element.value).toEqual('localhost.localdomain');
- expect(
- vm.$el.querySelector('.js-clipboard-btn').getAttribute('data-clipboard-text'),
- ).toEqual('localhost.localdomain');
+ expect(wrapper.find('.js-clipboard-btn').attributes('data-clipboard-text')).toEqual(
+ 'localhost.localdomain',
+ );
});
});
describe('without ip address', () => {
it('renders an input text with a loading icon and an alert text', () => {
- vm = mountComponent(Applications, {
+ createApp({
applications: {
- ...APPLICATIONS_MOCK_STATE,
ingress: {
title: 'Ingress',
status: 'installed',
@@ -277,142 +271,139 @@ describe('Applications', () => {
},
});
- expect(vm.$el.querySelector('.js-ingress-ip-loading-icon')).not.toBe(null);
- expect(vm.$el.querySelector('.js-no-endpoint-message')).not.toBe(null);
+ expect(wrapper.find('.js-ingress-ip-loading-icon').exists()).toBe(true);
+ expect(wrapper.find('.js-no-endpoint-message').exists()).toBe(true);
});
});
});
describe('before installing', () => {
it('does not render the IP address', () => {
- vm = mountComponent(Applications, {
- applications: APPLICATIONS_MOCK_STATE,
- });
+ createApp();
- expect(vm.$el.textContent).not.toContain('Ingress IP Address');
- expect(vm.$el.querySelector('.js-endpoint')).toBe(null);
+ expect(wrapper.text()).not.toContain('Ingress IP Address');
+ expect(wrapper.find('.js-endpoint').exists()).toBe(false);
});
});
+ });
- describe('Cert-Manager application', () => {
- describe('when not installed', () => {
- it('renders email & allows editing', () => {
- vm = mountComponent(Applications, {
- applications: {
- ...APPLICATIONS_MOCK_STATE,
- cert_manager: {
- title: 'Cert-Manager',
- email: 'before@example.com',
- status: 'installable',
- },
- },
- });
+ describe('Cert-Manager application', () => {
+ it('shows the correct description', () => {
+ createApp();
+ expect(findByTestId('certManagerDescription').element).toMatchSnapshot();
+ });
- expect(vm.$el.querySelector('.js-email').value).toEqual('before@example.com');
- expect(vm.$el.querySelector('.js-email').getAttribute('readonly')).toBe(null);
+ describe('when not installed', () => {
+ it('renders email & allows editing', () => {
+ createApp({
+ applications: {
+ cert_manager: {
+ title: 'Cert-Manager',
+ email: 'before@example.com',
+ status: 'installable',
+ },
+ },
});
+
+ expect(wrapper.find('.js-email').element.value).toEqual('before@example.com');
+ expect(wrapper.find('.js-email').attributes('readonly')).toBe(undefined);
});
+ });
- describe('when installed', () => {
- it('renders email in readonly', () => {
- vm = mountComponent(Applications, {
- applications: {
- ...APPLICATIONS_MOCK_STATE,
- cert_manager: {
- title: 'Cert-Manager',
- email: 'after@example.com',
- status: 'installed',
- },
+ describe('when installed', () => {
+ it('renders email in readonly', () => {
+ createApp({
+ applications: {
+ cert_manager: {
+ title: 'Cert-Manager',
+ email: 'after@example.com',
+ status: 'installed',
},
- });
-
- expect(vm.$el.querySelector('.js-email').value).toEqual('after@example.com');
- expect(vm.$el.querySelector('.js-email').getAttribute('readonly')).toEqual('readonly');
+ },
});
+
+ expect(wrapper.find('.js-email').element.value).toEqual('after@example.com');
+ expect(wrapper.find('.js-email').attributes('readonly')).toEqual('readonly');
});
});
+ });
- describe('Jupyter application', () => {
- describe('with ingress installed with ip & jupyter installable', () => {
- it('renders hostname active input', () => {
- vm = mountComponent(Applications, {
- applications: {
- ...APPLICATIONS_MOCK_STATE,
- ingress: {
- title: 'Ingress',
- status: 'installed',
- externalIp: '1.1.1.1',
- },
+ describe('Jupyter application', () => {
+ describe('with ingress installed with ip & jupyter installable', () => {
+ it('renders hostname active input', () => {
+ createApp({
+ applications: {
+ ingress: {
+ title: 'Ingress',
+ status: 'installed',
+ externalIp: '1.1.1.1',
},
- });
-
- expect(
- vm.$el
- .querySelector('.js-cluster-application-row-jupyter .js-hostname')
- .getAttribute('readonly'),
- ).toEqual(null);
+ },
});
- });
- describe('with ingress installed without external ip', () => {
- it('does not render hostname input', () => {
- vm = mountComponent(Applications, {
- applications: {
- ...APPLICATIONS_MOCK_STATE,
- ingress: { title: 'Ingress', status: 'installed' },
- },
- });
+ expect(
+ wrapper.find('.js-cluster-application-row-jupyter .js-hostname').attributes('readonly'),
+ ).toEqual(undefined);
+ });
+ });
- expect(vm.$el.querySelector('.js-cluster-application-row-jupyter .js-hostname')).toBe(
- null,
- );
+ describe('with ingress installed without external ip', () => {
+ it('does not render hostname input', () => {
+ createApp({
+ applications: {
+ ingress: { title: 'Ingress', status: 'installed' },
+ },
});
- });
- describe('with ingress & jupyter installed', () => {
- it('renders readonly input', () => {
- vm = mountComponent(Applications, {
- applications: {
- ...APPLICATIONS_MOCK_STATE,
- ingress: { title: 'Ingress', status: 'installed', externalIp: '1.1.1.1' },
- jupyter: { title: 'JupyterHub', status: 'installed', hostname: '' },
- },
- });
+ expect(wrapper.find('.js-cluster-application-row-jupyter .js-hostname').exists()).toBe(
+ false,
+ );
+ });
+ });
- expect(
- vm.$el
- .querySelector('.js-cluster-application-row-jupyter .js-hostname')
- .getAttribute('readonly'),
- ).toEqual('readonly');
+ describe('with ingress & jupyter installed', () => {
+ it('renders readonly input', () => {
+ createApp({
+ applications: {
+ ingress: { title: 'Ingress', status: 'installed', externalIp: '1.1.1.1' },
+ jupyter: { title: 'JupyterHub', status: 'installed', hostname: '' },
+ },
});
+
+ expect(
+ wrapper.find('.js-cluster-application-row-jupyter .js-hostname').attributes('readonly'),
+ ).toEqual('readonly');
});
+ });
- describe('without ingress installed', () => {
- beforeEach(() => {
- vm = mountComponent(Applications, {
- applications: APPLICATIONS_MOCK_STATE,
- });
- });
+ describe('without ingress installed', () => {
+ beforeEach(() => {
+ createApp();
+ });
- it('does not render input', () => {
- expect(vm.$el.querySelector('.js-cluster-application-row-jupyter .js-hostname')).toBe(
- null,
- );
- });
+ it('does not render input', () => {
+ expect(wrapper.find('.js-cluster-application-row-jupyter .js-hostname').exists()).toBe(
+ false,
+ );
+ });
- it('renders disabled install button', () => {
- expect(
- vm.$el
- .querySelector(
- '.js-cluster-application-row-jupyter .js-cluster-application-install-button',
- )
- .getAttribute('disabled'),
- ).toEqual('disabled');
- });
+ it('renders disabled install button', () => {
+ expect(
+ wrapper
+ .find('.js-cluster-application-row-jupyter .js-cluster-application-install-button')
+ .attributes('disabled'),
+ ).toEqual('disabled');
});
});
});
+ describe('Prometheus application', () => {
+ it('shows the correct description', () => {
+ createApp();
+ expect(findByTestId('prometheusDescription').element).toMatchSnapshot();
+ });
+ });
+
describe('Knative application', () => {
const availableDomain = {
id: 4,
@@ -420,7 +411,6 @@ describe('Applications', () => {
};
const propsData = {
applications: {
- ...APPLICATIONS_MOCK_STATE,
knative: {
title: 'Knative',
hostname: 'example.com',
@@ -432,18 +422,25 @@ describe('Applications', () => {
},
},
};
- let wrapper;
let knativeDomainEditor;
beforeEach(() => {
- wrapper = shallowMount(Applications, { propsData });
+ createShallowApp(propsData);
jest.spyOn(eventHub, '$emit');
knativeDomainEditor = wrapper.find(KnativeDomainEditor);
});
- afterEach(() => {
- wrapper.destroy();
+ it('shows the correct description', async () => {
+ createApp();
+ wrapper.setProps({
+ providerType: PROVIDER_TYPE.GCP,
+ preInstalledKnative: true,
+ });
+
+ await wrapper.vm.$nextTick();
+
+ expect(findByTestId('installedVia').element).toMatchSnapshot();
});
it('emits saveKnativeDomain event when knative domain editor emits save event', () => {
@@ -492,7 +489,6 @@ describe('Applications', () => {
describe('Crossplane application', () => {
const propsData = {
applications: {
- ...APPLICATIONS_MOCK_STATE,
crossplane: {
title: 'Crossplane',
stack: {
@@ -502,74 +498,58 @@ describe('Applications', () => {
},
};
- let wrapper;
- beforeEach(() => {
- wrapper = shallowMount(Applications, { propsData });
- });
- afterEach(() => {
- wrapper.destroy();
- });
+ beforeEach(() => createShallowApp(propsData));
+
it('renders the correct Component', () => {
const crossplane = wrapper.find(CrossplaneProviderStack);
expect(crossplane.exists()).toBe(true);
});
+
+ it('shows the correct description', () => {
+ createApp();
+ expect(findByTestId('crossplaneDescription').element).toMatchSnapshot();
+ });
});
describe('Elastic Stack application', () => {
describe('with elastic stack installable', () => {
it('renders hostname active input', () => {
- vm = mountComponent(Applications, {
- applications: {
- ...APPLICATIONS_MOCK_STATE,
- },
- });
+ createApp();
expect(
- vm.$el
- .querySelector(
+ wrapper
+ .find(
'.js-cluster-application-row-elastic_stack .js-cluster-application-install-button',
)
- .getAttribute('disabled'),
+ .attributes('disabled'),
).toEqual('disabled');
});
});
describe('elastic stack installed', () => {
it('renders uninstall button', () => {
- vm = mountComponent(Applications, {
+ createApp({
applications: {
- ...APPLICATIONS_MOCK_STATE,
elastic_stack: { title: 'Elastic Stack', status: 'installed' },
},
});
expect(
- vm.$el
- .querySelector(
+ wrapper
+ .find(
'.js-cluster-application-row-elastic_stack .js-cluster-application-install-button',
)
- .getAttribute('disabled'),
+ .attributes('disabled'),
).toEqual('disabled');
});
});
});
describe('Fluentd application', () => {
- const propsData = {
- applications: {
- ...APPLICATIONS_MOCK_STATE,
- },
- };
+ beforeEach(() => createShallowApp());
- let wrapper;
- beforeEach(() => {
- wrapper = shallowMount(Applications, { propsData });
- });
- afterEach(() => {
- wrapper.destroy();
- });
it('renders the correct Component', () => {
- expect(wrapper.contains(FluentdOutputSettings)).toBe(true);
+ expect(wrapper.find(FluentdOutputSettings).exists()).toBe(true);
});
});
});
diff --git a/spec/frontend/clusters/components/fluentd_output_settings_spec.js b/spec/frontend/clusters/components/fluentd_output_settings_spec.js
index 5e27cc49049..f03f2535947 100644
--- a/spec/frontend/clusters/components/fluentd_output_settings_spec.js
+++ b/spec/frontend/clusters/components/fluentd_output_settings_spec.js
@@ -70,12 +70,12 @@ describe('FluentdOutputSettings', () => {
});
describe.each`
- desc | changeFn | key | value
- ${'when protocol dropdown is triggered'} | ${() => changeProtocol(1)} | ${'protocol'} | ${'udp'}
- ${'when host is changed'} | ${() => changeHost('test-host')} | ${'host'} | ${'test-host'}
- ${'when port is changed'} | ${() => changePort(123)} | ${'port'} | ${123}
- ${'when wafLogEnabled changes'} | ${() => changeCheckbox(findCheckbox('Send ModSecurity Logs'))} | ${'wafLogEnabled'} | ${!defaultSettings.wafLogEnabled}
- ${'when ciliumLogEnabled changes'} | ${() => changeCheckbox(findCheckbox('Send Cilium Logs'))} | ${'ciliumLogEnabled'} | ${!defaultSettings.ciliumLogEnabled}
+ desc | changeFn | key | value
+ ${'when protocol dropdown is triggered'} | ${() => changeProtocol(1)} | ${'protocol'} | ${'udp'}
+ ${'when host is changed'} | ${() => changeHost('test-host')} | ${'host'} | ${'test-host'}
+ ${'when port is changed'} | ${() => changePort(123)} | ${'port'} | ${123}
+ ${'when wafLogEnabled changes'} | ${() => changeCheckbox(findCheckbox('Send Web Application Firewall Logs'))} | ${'wafLogEnabled'} | ${!defaultSettings.wafLogEnabled}
+ ${'when ciliumLogEnabled changes'} | ${() => changeCheckbox(findCheckbox('Send Container Network Policies Logs'))} | ${'ciliumLogEnabled'} | ${!defaultSettings.ciliumLogEnabled}
`('$desc', ({ changeFn, key, value }) => {
beforeEach(() => {
changeFn();
diff --git a/spec/frontend/clusters/components/update_application_confirmation_modal_spec.js b/spec/frontend/clusters/components/update_application_confirmation_modal_spec.js
new file mode 100644
index 00000000000..dd3aaf6f946
--- /dev/null
+++ b/spec/frontend/clusters/components/update_application_confirmation_modal_spec.js
@@ -0,0 +1,52 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlModal } from '@gitlab/ui';
+import UpdateApplicationConfirmationModal from '~/clusters/components/update_application_confirmation_modal.vue';
+import { ELASTIC_STACK } from '~/clusters/constants';
+
+describe('UpdateApplicationConfirmationModal', () => {
+ let wrapper;
+ const appTitle = 'Elastic stack';
+
+ const createComponent = (props = {}) => {
+ wrapper = shallowMount(UpdateApplicationConfirmationModal, {
+ propsData: { ...props },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ beforeEach(() => {
+ createComponent({ application: ELASTIC_STACK, applicationTitle: appTitle });
+ });
+
+ it(`renders a modal with a title "Update ${appTitle}"`, () => {
+ expect(wrapper.find(GlModal).attributes('title')).toEqual(`Update ${appTitle}`);
+ });
+
+ it(`renders a modal with an ok button labeled "Update ${appTitle}"`, () => {
+ expect(wrapper.find(GlModal).attributes('ok-title')).toEqual(`Update ${appTitle}`);
+ });
+
+ describe('when ok button is clicked', () => {
+ beforeEach(() => {
+ wrapper.find(GlModal).vm.$emit('ok');
+ });
+
+ it('emits confirm event', () =>
+ wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.emitted('confirm')).toBeTruthy();
+ }));
+
+ it('displays a warning text indicating the app will be updated', () => {
+ expect(wrapper.text()).toContain(`You are about to update ${appTitle} on your cluster.`);
+ });
+
+ it('displays a custom warning text depending on the application', () => {
+ expect(wrapper.text()).toContain(
+ `Your Elasticsearch cluster will be re-created during this upgrade. Your logs will be re-indexed, and you will lose historical logs from hosts terminated in the last 30 days.`,
+ );
+ });
+ });
+});
diff --git a/spec/frontend/clusters_list/components/clusters_spec.js b/spec/frontend/clusters_list/components/clusters_spec.js
index e2d2e4b73b3..07faee7e50b 100644
--- a/spec/frontend/clusters_list/components/clusters_spec.js
+++ b/spec/frontend/clusters_list/components/clusters_spec.js
@@ -5,6 +5,7 @@ import MockAdapter from 'axios-mock-adapter';
import { apiData } from '../mock_data';
import { mount } from '@vue/test-utils';
import { GlLoadingIcon, GlTable, GlPagination } from '@gitlab/ui';
+import * as Sentry from '@sentry/browser';
describe('Clusters', () => {
let mock;
@@ -13,6 +14,13 @@ describe('Clusters', () => {
const endpoint = 'some/endpoint';
+ const entryData = {
+ endpoint,
+ imgTagsAwsText: 'AWS Icon',
+ imgTagsDefaultText: 'Default Icon',
+ imgTagsGcpText: 'GCP Icon',
+ };
+
const findLoader = () => wrapper.find(GlLoadingIcon);
const findPaginatedButtons = () => wrapper.find(GlPagination);
const findTable = () => wrapper.find(GlTable);
@@ -23,18 +31,26 @@ describe('Clusters', () => {
};
const mountWrapper = () => {
- store = ClusterStore({ endpoint });
+ store = ClusterStore(entryData);
wrapper = mount(Clusters, { store });
return axios.waitForAll();
};
+ const paginationHeader = (total = apiData.clusters.length, perPage = 20, currentPage = 1) => {
+ return {
+ 'x-total': total,
+ 'x-per-page': perPage,
+ 'x-page': currentPage,
+ };
+ };
+
+ let captureException;
+
beforeEach(() => {
+ captureException = jest.spyOn(Sentry, 'captureException');
+
mock = new MockAdapter(axios);
- mockPollingApi(200, apiData, {
- 'x-total': apiData.clusters.length,
- 'x-per-page': 20,
- 'x-page': 1,
- });
+ mockPollingApi(200, apiData, paginationHeader());
return mountWrapper();
});
@@ -42,6 +58,7 @@ describe('Clusters', () => {
afterEach(() => {
wrapper.destroy();
mock.restore();
+ captureException.mockRestore();
});
describe('clusters table', () => {
@@ -77,25 +94,108 @@ describe('Clusters', () => {
});
});
+ describe('cluster icon', () => {
+ it.each`
+ providerText | lineNumber
+ ${'GCP Icon'} | ${0}
+ ${'AWS Icon'} | ${1}
+ ${'Default Icon'} | ${2}
+ ${'Default Icon'} | ${3}
+ ${'Default Icon'} | ${4}
+ ${'Default Icon'} | ${5}
+ `('renders provider image and alt text for each cluster', ({ providerText, lineNumber }) => {
+ const images = findTable().findAll('.js-status img');
+ const image = images.at(lineNumber);
+
+ expect(image.attributes('alt')).toBe(providerText);
+ });
+ });
+
describe('cluster status', () => {
it.each`
- statusName | className | lineNumber
- ${'disabled'} | ${'disabled'} | ${0}
- ${'unreachable'} | ${'bg-danger'} | ${1}
- ${'authentication_failure'} | ${'bg-warning'} | ${2}
- ${'deleting'} | ${null} | ${3}
- ${'created'} | ${'bg-success'} | ${4}
- ${'default'} | ${'bg-white'} | ${5}
- `('renders a status for each cluster', ({ statusName, className, lineNumber }) => {
- const statuses = findStatuses();
- const status = statuses.at(lineNumber);
- if (statusName !== 'deleting') {
- const statusIndicator = status.find('.cluster-status-indicator');
- expect(statusIndicator.exists()).toBe(true);
- expect(statusIndicator.classes()).toContain(className);
- } else {
- expect(status.find(GlLoadingIcon).exists()).toBe(true);
- }
+ statusName | lineNumber | result
+ ${'creating'} | ${0} | ${true}
+ ${null} | ${1} | ${false}
+ ${null} | ${2} | ${false}
+ ${'deleting'} | ${3} | ${true}
+ ${null} | ${4} | ${false}
+ ${null} | ${5} | ${false}
+ `(
+ 'renders $result when status=$statusName and lineNumber=$lineNumber',
+ ({ lineNumber, result }) => {
+ const statuses = findStatuses();
+ const status = statuses.at(lineNumber);
+ expect(status.find(GlLoadingIcon).exists()).toBe(result);
+ },
+ );
+ });
+
+ describe('nodes present', () => {
+ it.each`
+ nodeSize | lineNumber
+ ${'Unknown'} | ${0}
+ ${'1'} | ${1}
+ ${'2'} | ${2}
+ ${'1'} | ${3}
+ ${'1'} | ${4}
+ ${'Unknown'} | ${5}
+ `('renders node size for each cluster', ({ nodeSize, lineNumber }) => {
+ const sizes = findTable().findAll('td:nth-child(3)');
+ const size = sizes.at(lineNumber);
+
+ expect(size.text()).toBe(nodeSize);
+ });
+
+ describe('nodes with unknown quantity', () => {
+ it('notifies Sentry about all missing quantity types', () => {
+ expect(captureException).toHaveBeenCalledTimes(8);
+ });
+
+ it('notifies Sentry about CPU missing quantity types', () => {
+ const missingCpuTypeError = new Error('UnknownK8sCpuQuantity:1missingCpuUnit');
+
+ expect(captureException).toHaveBeenCalledWith(missingCpuTypeError);
+ });
+
+ it('notifies Sentry about Memory missing quantity types', () => {
+ const missingMemoryTypeError = new Error('UnknownK8sMemoryQuantity:1missingMemoryUnit');
+
+ expect(captureException).toHaveBeenCalledWith(missingMemoryTypeError);
+ });
+ });
+ });
+
+ describe('cluster CPU', () => {
+ it.each`
+ clusterCpu | lineNumber
+ ${''} | ${0}
+ ${'1.93 (87% free)'} | ${1}
+ ${'3.87 (86% free)'} | ${2}
+ ${'(% free)'} | ${3}
+ ${'(% free)'} | ${4}
+ ${''} | ${5}
+ `('renders total cpu for each cluster', ({ clusterCpu, lineNumber }) => {
+ const clusterCpus = findTable().findAll('td:nth-child(4)');
+ const cpuData = clusterCpus.at(lineNumber);
+
+ expect(cpuData.text()).toBe(clusterCpu);
+ });
+ });
+
+ describe('cluster Memory', () => {
+ it.each`
+ clusterMemory | lineNumber
+ ${''} | ${0}
+ ${'5.92 (78% free)'} | ${1}
+ ${'12.86 (79% free)'} | ${2}
+ ${'(% free)'} | ${3}
+ ${'(% free)'} | ${4}
+ ${''} | ${5}
+ `('renders total memory for each cluster', ({ clusterMemory, lineNumber }) => {
+ const clusterMemories = findTable().findAll('td:nth-child(5)');
+ const memoryData = clusterMemories.at(lineNumber);
+
+ expect(memoryData.text()).toBe(clusterMemory);
});
});
@@ -105,11 +205,7 @@ describe('Clusters', () => {
const totalSecondPage = 500;
beforeEach(() => {
- mockPollingApi(200, apiData, {
- 'x-total': totalFirstPage,
- 'x-per-page': perPage,
- 'x-page': 1,
- });
+ mockPollingApi(200, apiData, paginationHeader(totalFirstPage, perPage, 1));
return mountWrapper();
});
@@ -123,11 +219,7 @@ describe('Clusters', () => {
describe('when updating currentPage', () => {
beforeEach(() => {
- mockPollingApi(200, apiData, {
- 'x-total': totalSecondPage,
- 'x-per-page': perPage,
- 'x-page': 2,
- });
+ mockPollingApi(200, apiData, paginationHeader(totalSecondPage, perPage, 2));
wrapper.setData({ currentPage: 2 });
return axios.waitForAll();
});
diff --git a/spec/frontend/clusters_list/mock_data.js b/spec/frontend/clusters_list/mock_data.js
index 9a90a378f31..48af3b91c94 100644
--- a/spec/frontend/clusters_list/mock_data.js
+++ b/spec/frontend/clusters_list/mock_data.js
@@ -1,57 +1,70 @@
export const clusterList = [
{
name: 'My Cluster 1',
- environmentScope: '*',
- size: '3',
- clusterType: 'group_type',
- status: 'disabled',
- cpu: '6 (100% free)',
- memory: '22.50 (30% free)',
+ environment_scope: '*',
+ cluster_type: 'group_type',
+ provider_type: 'gcp',
+ status: 'creating',
+ nodes: null,
},
{
name: 'My Cluster 2',
- environmentScope: 'development',
- size: '12',
- clusterType: 'project_type',
+ environment_scope: 'development',
+ cluster_type: 'project_type',
+ provider_type: 'aws',
status: 'unreachable',
- cpu: '3 (50% free)',
- memory: '11 (60% free)',
+ nodes: [
+ {
+ status: { allocatable: { cpu: '1930m', memory: '5777156Ki' } },
+ usage: { cpu: '246155922n', memory: '1255212Ki' },
+ },
+ ],
},
{
name: 'My Cluster 3',
- environmentScope: 'development',
- size: '12',
- clusterType: 'project_type',
+ environment_scope: 'development',
+ cluster_type: 'project_type',
+ provider_type: 'none',
status: 'authentication_failure',
- cpu: '1 (0% free)',
- memory: '22 (33% free)',
+ nodes: [
+ {
+ status: { allocatable: { cpu: '1930m', memory: '5777156Ki' } },
+ usage: { cpu: '246155922n', memory: '1255212Ki' },
+ },
+ {
+ status: { allocatable: { cpu: '1940m', memory: '6777156Ki' } },
+ usage: { cpu: '307051934n', memory: '1379136Ki' },
+ },
+ ],
},
{
name: 'My Cluster 4',
- environmentScope: 'production',
- size: '12',
- clusterType: 'project_type',
+ environment_scope: 'production',
+ cluster_type: 'project_type',
status: 'deleting',
- cpu: '6 (100% free)',
- memory: '45 (15% free)',
+ nodes: [
+ {
+ status: { allocatable: { cpu: '1missingCpuUnit', memory: '1missingMemoryUnit' } },
+ usage: { cpu: '1missingCpuUnit', memory: '1missingMemoryUnit' },
+ },
+ ],
},
{
name: 'My Cluster 5',
- environmentScope: 'development',
- size: '12',
- clusterType: 'project_type',
+ environment_scope: 'development',
+ cluster_type: 'project_type',
status: 'created',
- cpu: '6 (100% free)',
- memory: '20.12 (35% free)',
+ nodes: [
+ {
+ status: { allocatable: { cpu: '1missingCpuUnit', memory: '1missingMemoryUnit' } },
+ },
+ ],
},
{
name: 'My Cluster 6',
- environmentScope: '*',
- size: '1',
- clusterType: 'project_type',
+ environment_scope: '*',
+ cluster_type: 'project_type',
status: 'cleanup_ongoing',
- cpu: '6 (100% free)',
- memory: '20.12 (35% free)',
},
];
diff --git a/spec/frontend/clusters_list/store/actions_spec.js b/spec/frontend/clusters_list/store/actions_spec.js
index 70766af3ec4..74e351a3704 100644
--- a/spec/frontend/clusters_list/store/actions_spec.js
+++ b/spec/frontend/clusters_list/store/actions_spec.js
@@ -1,10 +1,14 @@
import MockAdapter from 'axios-mock-adapter';
+import Poll from '~/lib/utils/poll';
import flashError from '~/flash';
import testAction from 'helpers/vuex_action_helper';
import axios from '~/lib/utils/axios_utils';
+import waitForPromises from 'helpers/wait_for_promises';
import { apiData } from '../mock_data';
+import { MAX_REQUESTS } from '~/clusters_list/constants';
import * as types from '~/clusters_list/store/mutation_types';
import * as actions from '~/clusters_list/store/actions';
+import * as Sentry from '@sentry/browser';
jest.mock('~/flash.js');
@@ -12,6 +16,24 @@ describe('Clusters store actions', () => {
describe('fetchClusters', () => {
let mock;
+ const headers = {
+ 'x-next-page': 1,
+ 'x-total': apiData.clusters.length,
+ 'x-total-pages': 1,
+ 'x-per-page': 20,
+ 'x-page': 1,
+ 'x-prev-page': 1,
+ };
+
+ const paginationInformation = {
+ nextPage: 1,
+ page: 1,
+ perPage: 20,
+ previousPage: 1,
+ total: apiData.clusters.length,
+ totalPages: 1,
+ };
+
beforeEach(() => {
mock = new MockAdapter(axios);
});
@@ -19,21 +41,6 @@ describe('Clusters store actions', () => {
afterEach(() => mock.restore());
it('should commit SET_CLUSTERS_DATA with received response', done => {
- const headers = {
- 'x-total': apiData.clusters.length,
- 'x-per-page': 20,
- 'x-page': 1,
- };
-
- const paginationInformation = {
- nextPage: NaN,
- page: 1,
- perPage: 20,
- previousPage: NaN,
- total: apiData.clusters.length,
- totalPages: NaN,
- };
-
mock.onGet().reply(200, apiData, headers);
testAction(
@@ -52,9 +59,110 @@ describe('Clusters store actions', () => {
it('should show flash on API error', done => {
mock.onGet().reply(400, 'Not Found');
- testAction(actions.fetchClusters, { endpoint: apiData.endpoint }, {}, [], [], () => {
- expect(flashError).toHaveBeenCalledWith(expect.stringMatching('error'));
- done();
+ testAction(
+ actions.fetchClusters,
+ { endpoint: apiData.endpoint },
+ {},
+ [{ type: types.SET_LOADING_STATE, payload: false }],
+ [],
+ () => {
+ expect(flashError).toHaveBeenCalledWith(expect.stringMatching('error'));
+ done();
+ },
+ );
+ });
+
+ describe('multiple api requests', () => {
+ let captureException;
+ let pollRequest;
+ let pollStop;
+
+ const pollInterval = 10;
+ const pollHeaders = { 'poll-interval': pollInterval, ...headers };
+
+ beforeEach(() => {
+ captureException = jest.spyOn(Sentry, 'captureException');
+ pollRequest = jest.spyOn(Poll.prototype, 'makeRequest');
+ pollStop = jest.spyOn(Poll.prototype, 'stop');
+
+ mock.onGet().reply(200, apiData, pollHeaders);
+ });
+
+ afterEach(() => {
+ captureException.mockRestore();
+ pollRequest.mockRestore();
+ pollStop.mockRestore();
+ });
+
+ it('should stop polling after MAX Requests', done => {
+ testAction(
+ actions.fetchClusters,
+ { endpoint: apiData.endpoint },
+ {},
+ [
+ { type: types.SET_CLUSTERS_DATA, payload: { data: apiData, paginationInformation } },
+ { type: types.SET_LOADING_STATE, payload: false },
+ ],
+ [],
+ () => {
+ expect(pollRequest).toHaveBeenCalledTimes(1);
+ expect(pollStop).toHaveBeenCalledTimes(0);
+ jest.advanceTimersByTime(pollInterval);
+
+ waitForPromises()
+ .then(() => {
+ expect(pollRequest).toHaveBeenCalledTimes(2);
+ expect(pollStop).toHaveBeenCalledTimes(0);
+ jest.advanceTimersByTime(pollInterval);
+ })
+ .then(() => waitForPromises())
+ .then(() => {
+ expect(pollRequest).toHaveBeenCalledTimes(MAX_REQUESTS);
+ expect(pollStop).toHaveBeenCalledTimes(0);
+ jest.advanceTimersByTime(pollInterval);
+ })
+ .then(() => waitForPromises())
+ .then(() => {
+ expect(pollRequest).toHaveBeenCalledTimes(MAX_REQUESTS + 1);
+ // Stops poll once it exceeds the MAX_REQUESTS limit
+ expect(pollStop).toHaveBeenCalledTimes(1);
+ jest.advanceTimersByTime(pollInterval);
+ })
+ .then(() => waitForPromises())
+ .then(() => {
+ // Additional poll requests are not made once pollStop is called
+ expect(pollRequest).toHaveBeenCalledTimes(MAX_REQUESTS + 1);
+ expect(pollStop).toHaveBeenCalledTimes(1);
+ })
+ .then(done)
+ .catch(done.fail);
+ },
+ );
+ });
+
+ it('should stop polling and report to Sentry when data is invalid', done => {
+ const badApiResponse = { clusters: {} };
+ mock.onGet().reply(200, badApiResponse, pollHeaders);
+
+ testAction(
+ actions.fetchClusters,
+ { endpoint: apiData.endpoint },
+ {},
+ [
+ {
+ type: types.SET_CLUSTERS_DATA,
+ payload: { data: badApiResponse, paginationInformation },
+ },
+ { type: types.SET_LOADING_STATE, payload: false },
+ ],
+ [],
+ () => {
+ expect(pollRequest).toHaveBeenCalledTimes(1);
+ expect(pollStop).toHaveBeenCalledTimes(1);
+ expect(captureException).toHaveBeenCalledTimes(1);
+ done();
+ },
+ );
});
});
});
diff --git a/spec/frontend/code_navigation/components/__snapshots__/popover_spec.js.snap b/spec/frontend/code_navigation/components/__snapshots__/popover_spec.js.snap
index c9fdd388585..7079ddfc2ab 100644
--- a/spec/frontend/code_navigation/components/__snapshots__/popover_spec.js.snap
+++ b/spec/frontend/code_navigation/components/__snapshots__/popover_spec.js.snap
@@ -16,7 +16,27 @@ exports[`Code navigation popover component renders popover 1`] = `
<pre
class="border-0 bg-transparent m-0 code highlight"
>
- console.log
+ <span
+ class="line"
+ lang="javascript"
+ >
+ <span
+ class="k"
+ >
+ function
+ </span>
+ <span>
+ main() {
+ </span>
+ </span>
+ <span
+ class="line"
+ lang="javascript"
+ >
+ <span>
+ }
+ </span>
+ </span>
</pre>
</div>
diff --git a/spec/frontend/code_navigation/components/popover_spec.js b/spec/frontend/code_navigation/components/popover_spec.js
index 858e94cf155..b3f814f1be4 100644
--- a/spec/frontend/code_navigation/components/popover_spec.js
+++ b/spec/frontend/code_navigation/components/popover_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Popover from '~/code_navigation/components/popover.vue';
+import DocLine from '~/code_navigation/components/doc_line.vue';
const DEFINITION_PATH_PREFIX = 'http://gitlab.com';
@@ -7,7 +8,22 @@ const MOCK_CODE_DATA = Object.freeze({
hover: [
{
language: 'javascript',
- value: 'console.log',
+ tokens: [
+ [
+ {
+ class: 'k',
+ value: 'function',
+ },
+ {
+ value: ' main() {',
+ },
+ ],
+ [
+ {
+ value: '}',
+ },
+ ],
+ ],
},
],
definition_path: 'test.js#L20',
@@ -28,6 +44,7 @@ let wrapper;
function factory({ position, data, definitionPathPrefix, blobPath = 'index.js' }) {
wrapper = shallowMount(Popover, {
propsData: { position, data, definitionPathPrefix, blobPath },
+ stubs: { DocLine },
});
}
diff --git a/spec/frontend/collapsed_sidebar_todo_spec.js b/spec/frontend/collapsed_sidebar_todo_spec.js
new file mode 100644
index 00000000000..0ea797ce4b3
--- /dev/null
+++ b/spec/frontend/collapsed_sidebar_todo_spec.js
@@ -0,0 +1,172 @@
+/* eslint-disable no-new */
+import { clone } from 'lodash';
+import MockAdapter from 'axios-mock-adapter';
+import axios from '~/lib/utils/axios_utils';
+import Sidebar from '~/right_sidebar';
+import waitForPromises from './helpers/wait_for_promises';
+import { TEST_HOST } from 'spec/test_constants';
+
+describe('Issuable right sidebar collapsed todo toggle', () => {
+ const fixtureName = 'issues/open-issue.html';
+ const jsonFixtureName = 'todos/todos.json';
+ let mock;
+
+ preloadFixtures(fixtureName);
+ preloadFixtures(jsonFixtureName);
+
+ beforeEach(() => {
+ const todoData = getJSONFixture(jsonFixtureName);
+ new Sidebar();
+ loadFixtures(fixtureName);
+
+ document.querySelector('.js-right-sidebar').classList.toggle('right-sidebar-expanded');
+ document.querySelector('.js-right-sidebar').classList.toggle('right-sidebar-collapsed');
+
+ mock = new MockAdapter(axios);
+
+ mock.onPost(`${TEST_HOST}/frontend-fixtures/issues-project/todos`).reply(() => {
+ const response = clone(todoData);
+
+ return [200, response];
+ });
+
+ mock.onDelete(/(.*)\/dashboard\/todos\/\d+$/).reply(() => {
+ const response = clone(todoData);
+ delete response.delete_path;
+
+ return [200, response];
+ });
+ });
+
+ afterEach(() => {
+ mock.restore();
+ });
+
+ it('shows add todo button', () => {
+ expect(document.querySelector('.js-issuable-todo.sidebar-collapsed-icon')).not.toBeNull();
+
+ expect(
+ document
+ .querySelector('.js-issuable-todo.sidebar-collapsed-icon svg use')
+ .getAttribute('xlink:href'),
+ ).toContain('todo-add');
+
+ expect(
+ document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .todo-undone'),
+ ).toBeNull();
+ });
+
+ it('sets default tooltip title', () => {
+ expect(
+ document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').getAttribute('title'),
+ ).toBe('Add a To Do');
+ });
+
+ it('toggle todo state', done => {
+ document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
+
+ setImmediate(() => {
+ expect(
+ document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .todo-undone'),
+ ).not.toBeNull();
+
+ expect(
+ document
+ .querySelector('.js-issuable-todo.sidebar-collapsed-icon svg.todo-undone use')
+ .getAttribute('xlink:href'),
+ ).toContain('todo-done');
+
+ done();
+ });
+ });
+
+ it('toggle todo state of expanded todo toggle', done => {
+ document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
+
+ setImmediate(() => {
+ expect(
+ document.querySelector('.issuable-sidebar-header .js-issuable-todo').textContent.trim(),
+ ).toBe('Mark as done');
+
+ done();
+ });
+ });
+
+ it('toggles todo button tooltip', done => {
+ document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
+
+ setImmediate(() => {
+ expect(
+ document
+ .querySelector('.js-issuable-todo.sidebar-collapsed-icon')
+ .getAttribute('data-original-title'),
+ ).toBe('Mark as done');
+
+ done();
+ });
+ });
+
+ it('marks todo as done', done => {
+ document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
+
+ waitForPromises()
+ .then(() => {
+ expect(
+ document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .todo-undone'),
+ ).not.toBeNull();
+
+ document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
+ })
+ .then(waitForPromises)
+ .then(() => {
+ expect(
+ document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .todo-undone'),
+ ).toBeNull();
+
+ expect(
+ document.querySelector('.issuable-sidebar-header .js-issuable-todo').textContent.trim(),
+ ).toBe('Add a To Do');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('updates aria-label to Mark as done', done => {
+ document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
+
+ setImmediate(() => {
+ expect(
+ document
+ .querySelector('.js-issuable-todo.sidebar-collapsed-icon')
+ .getAttribute('aria-label'),
+ ).toBe('Mark as done');
+
+ done();
+ });
+ });
+
+ it('updates aria-label to add todo', done => {
+ document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
+
+ waitForPromises()
+ .then(() => {
+ expect(
+ document
+ .querySelector('.js-issuable-todo.sidebar-collapsed-icon')
+ .getAttribute('aria-label'),
+ ).toBe('Mark as done');
+
+ document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
+ })
+ .then(waitForPromises)
+ .then(() => {
+ expect(
+ document
+ .querySelector('.js-issuable-todo.sidebar-collapsed-icon')
+ .getAttribute('aria-label'),
+ ).toBe('Add a To Do');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+});
diff --git a/spec/frontend/comment_type_toggle_spec.js b/spec/frontend/comment_type_toggle_spec.js
new file mode 100644
index 00000000000..06dbfac1803
--- /dev/null
+++ b/spec/frontend/comment_type_toggle_spec.js
@@ -0,0 +1,169 @@
+import CommentTypeToggle from '~/comment_type_toggle';
+import DropLab from '~/droplab/drop_lab';
+import InputSetter from '~/droplab/plugins/input_setter';
+
+describe('CommentTypeToggle', () => {
+ const testContext = {};
+
+ describe('class constructor', () => {
+ beforeEach(() => {
+ testContext.dropdownTrigger = {};
+ testContext.dropdownList = {};
+ testContext.noteTypeInput = {};
+ testContext.submitButton = {};
+ testContext.closeButton = {};
+
+ testContext.commentTypeToggle = new CommentTypeToggle({
+ dropdownTrigger: testContext.dropdownTrigger,
+ dropdownList: testContext.dropdownList,
+ noteTypeInput: testContext.noteTypeInput,
+ submitButton: testContext.submitButton,
+ closeButton: testContext.closeButton,
+ });
+ });
+
+ it('should set .dropdownTrigger', () => {
+ expect(testContext.commentTypeToggle.dropdownTrigger).toBe(testContext.dropdownTrigger);
+ });
+
+ it('should set .dropdownList', () => {
+ expect(testContext.commentTypeToggle.dropdownList).toBe(testContext.dropdownList);
+ });
+
+ it('should set .noteTypeInput', () => {
+ expect(testContext.commentTypeToggle.noteTypeInput).toBe(testContext.noteTypeInput);
+ });
+
+ it('should set .submitButton', () => {
+ expect(testContext.commentTypeToggle.submitButton).toBe(testContext.submitButton);
+ });
+
+ it('should set .closeButton', () => {
+ expect(testContext.commentTypeToggle.closeButton).toBe(testContext.closeButton);
+ });
+
+ it('should set .reopenButton', () => {
+ expect(testContext.commentTypeToggle.reopenButton).toBe(testContext.reopenButton);
+ });
+ });
+
+ describe('initDroplab', () => {
+ beforeEach(() => {
+ testContext.commentTypeToggle = {
+ dropdownTrigger: {},
+ dropdownList: {},
+ noteTypeInput: {},
+ submitButton: {},
+ closeButton: {},
+ setConfig: () => {},
+ };
+ testContext.config = {};
+
+ jest.spyOn(DropLab.prototype, 'init').mockImplementation();
+ jest.spyOn(DropLab.prototype, 'constructor').mockImplementation();
+
+ jest.spyOn(testContext.commentTypeToggle, 'setConfig').mockReturnValue(testContext.config);
+
+ CommentTypeToggle.prototype.initDroplab.call(testContext.commentTypeToggle);
+ });
+
+ it('should instantiate a DropLab instance and set .droplab', () => {
+ expect(testContext.commentTypeToggle.droplab instanceof DropLab).toBe(true);
+ });
+
+ it('should call .setConfig', () => {
+ expect(testContext.commentTypeToggle.setConfig).toHaveBeenCalled();
+ });
+
+ it('should call DropLab.prototype.init', () => {
+ expect(DropLab.prototype.init).toHaveBeenCalledWith(
+ testContext.commentTypeToggle.dropdownTrigger,
+ testContext.commentTypeToggle.dropdownList,
+ [InputSetter],
+ testContext.config,
+ );
+ });
+ });
+
+ describe('setConfig', () => {
+ describe('if no .closeButton is provided', () => {
+ beforeEach(() => {
+ testContext.commentTypeToggle = {
+ dropdownTrigger: {},
+ dropdownList: {},
+ noteTypeInput: {},
+ submitButton: {},
+ reopenButton: {},
+ };
+
+ testContext.setConfig = CommentTypeToggle.prototype.setConfig.call(
+ testContext.commentTypeToggle,
+ );
+ });
+
+ it('should not add .closeButton related InputSetter config', () => {
+ expect(testContext.setConfig).toEqual({
+ InputSetter: [
+ {
+ input: testContext.commentTypeToggle.noteTypeInput,
+ valueAttribute: 'data-value',
+ },
+ {
+ input: testContext.commentTypeToggle.submitButton,
+ valueAttribute: 'data-submit-text',
+ },
+ {
+ input: testContext.commentTypeToggle.reopenButton,
+ valueAttribute: 'data-reopen-text',
+ },
+ {
+ input: testContext.commentTypeToggle.reopenButton,
+ valueAttribute: 'data-reopen-text',
+ inputAttribute: 'data-alternative-text',
+ },
+ ],
+ });
+ });
+ });
+
+ describe('if no .reopenButton is provided', () => {
+ beforeEach(() => {
+ testContext.commentTypeToggle = {
+ dropdownTrigger: {},
+ dropdownList: {},
+ noteTypeInput: {},
+ submitButton: {},
+ closeButton: {},
+ };
+
+ testContext.setConfig = CommentTypeToggle.prototype.setConfig.call(
+ testContext.commentTypeToggle,
+ );
+ });
+
+ it('should not add .reopenButton related InputSetter config', () => {
+ expect(testContext.setConfig).toEqual({
+ InputSetter: [
+ {
+ input: testContext.commentTypeToggle.noteTypeInput,
+ valueAttribute: 'data-value',
+ },
+ {
+ input: testContext.commentTypeToggle.submitButton,
+ valueAttribute: 'data-submit-text',
+ },
+ {
+ input: testContext.commentTypeToggle.closeButton,
+ valueAttribute: 'data-close-text',
+ },
+ {
+ input: testContext.commentTypeToggle.closeButton,
+ valueAttribute: 'data-close-text',
+ inputAttribute: 'data-alternative-text',
+ },
+ ],
+ });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/confirm_modal_spec.js b/spec/frontend/confirm_modal_spec.js
index 89cfc3ef3a3..b14d1c3e01d 100644
--- a/spec/frontend/confirm_modal_spec.js
+++ b/spec/frontend/confirm_modal_spec.js
@@ -51,7 +51,7 @@ describe('ConfirmModal', () => {
const findModalOkButton = (modal, variant) =>
modal.querySelector(`.modal-footer .btn-${variant}`);
const findModalCancelButton = modal => modal.querySelector('.modal-footer .btn-secondary');
- const modalIsHidden = () => findModal().getAttribute('aria-hidden') === 'true';
+ const modalIsHidden = () => findModal() === null;
const serializeModal = (modal, buttonIndex) => {
const { modalAttributes } = buttons[buttonIndex];
@@ -101,7 +101,9 @@ describe('ConfirmModal', () => {
});
it('closes the modal', () => {
- expect(modalIsHidden()).toBe(true);
+ setImmediate(() => {
+ expect(modalIsHidden()).toBe(true);
+ });
});
});
});
diff --git a/spec/frontend/contributors/component/__snapshots__/contributors_spec.js.snap b/spec/frontend/contributors/component/__snapshots__/contributors_spec.js.snap
index fafffcb6e0c..a5eb42e0f08 100644
--- a/spec/frontend/contributors/component/__snapshots__/contributors_spec.js.snap
+++ b/spec/frontend/contributors/component/__snapshots__/contributors_spec.js.snap
@@ -20,7 +20,10 @@ exports[`Contributors charts should render charts when loading completed and the
height="264"
includelegendavgmax="true"
legendaveragetext="Avg"
+ legendcurrenttext="Current"
+ legendlayout="inline"
legendmaxtext="Max"
+ legendmintext="Min"
option="[object Object]"
thresholds=""
width="0"
@@ -48,7 +51,10 @@ exports[`Contributors charts should render charts when loading completed and the
height="216"
includelegendavgmax="true"
legendaveragetext="Avg"
+ legendcurrenttext="Current"
+ legendlayout="inline"
legendmaxtext="Max"
+ legendmintext="Min"
option="[object Object]"
thresholds=""
width="0"
diff --git a/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js b/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js
index 1139f094705..01f7ada9cd6 100644
--- a/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js
+++ b/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js
@@ -1,4 +1,5 @@
import testAction from 'helpers/vuex_action_helper';
+import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
import MockAdapter from 'axios-mock-adapter';
import createState from '~/create_cluster/eks_cluster/store/state';
import * as actions from '~/create_cluster/eks_cluster/store/actions';
@@ -251,12 +252,7 @@ describe('EKS Cluster Store Actions', () => {
});
describe('createClusterSuccess', () => {
- beforeEach(() => {
- jest.spyOn(window.location, 'assign').mockImplementation(() => {});
- });
- afterEach(() => {
- window.location.assign.mockRestore();
- });
+ useMockLocationHelper();
it('redirects to the new cluster URL', () => {
actions.createClusterSuccess(null, newClusterUrl);
diff --git a/spec/frontend/design_management/components/__snapshots__/design_note_pin_spec.js.snap b/spec/frontend/design_management/components/__snapshots__/design_note_pin_spec.js.snap
index 4828e8cb3c2..4c848256e5b 100644
--- a/spec/frontend/design_management/components/__snapshots__/design_note_pin_spec.js.snap
+++ b/spec/frontend/design_management/components/__snapshots__/design_note_pin_spec.js.snap
@@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`Design discussions component should match the snapshot of note when repositioning 1`] = `
+exports[`Design note pin component should match the snapshot of note when repositioning 1`] = `
<button
aria-label="Comment form position"
- class="position-absolute btn-transparent comment-indicator"
+ class="design-pin gl-absolute gl-display-flex gl-align-items-center gl-justify-content-center btn-transparent comment-indicator"
style="left: 10px; top: 10px; cursor: move;"
type="button"
>
@@ -14,10 +14,10 @@ exports[`Design discussions component should match the snapshot of note when rep
</button>
`;
-exports[`Design discussions component should match the snapshot of note with index 1`] = `
+exports[`Design note pin component should match the snapshot of note with index 1`] = `
<button
aria-label="Comment '1' position"
- class="position-absolute js-image-badge badge badge-pill"
+ class="design-pin gl-absolute gl-display-flex gl-align-items-center gl-justify-content-center js-image-badge badge badge-pill"
style="left: 10px; top: 10px;"
type="button"
>
@@ -27,10 +27,10 @@ exports[`Design discussions component should match the snapshot of note with ind
</button>
`;
-exports[`Design discussions component should match the snapshot of note without index 1`] = `
+exports[`Design note pin component should match the snapshot of note without index 1`] = `
<button
aria-label="Comment form position"
- class="position-absolute btn-transparent comment-indicator"
+ class="design-pin gl-absolute gl-display-flex gl-align-items-center gl-justify-content-center btn-transparent comment-indicator"
style="left: 10px; top: 10px;"
type="button"
>
diff --git a/spec/frontend/design_management/components/design_note_pin_spec.js b/spec/frontend/design_management/components/design_note_pin_spec.js
index 4f7260b1363..4e045b58a35 100644
--- a/spec/frontend/design_management/components/design_note_pin_spec.js
+++ b/spec/frontend/design_management/components/design_note_pin_spec.js
@@ -1,7 +1,7 @@
import { shallowMount } from '@vue/test-utils';
import DesignNotePin from '~/design_management/components/design_note_pin.vue';
-describe('Design discussions component', () => {
+describe('Design note pin component', () => {
let wrapper;
function createComponent(propsData = {}) {
@@ -26,7 +26,7 @@ describe('Design discussions component', () => {
});
it('should match the snapshot of note with index', () => {
- createComponent({ label: '1' });
+ createComponent({ label: 1 });
expect(wrapper.element).toMatchSnapshot();
});
diff --git a/spec/frontend/design_management/components/design_notes/__snapshots__/design_note_spec.js.snap b/spec/frontend/design_management/components/design_notes/__snapshots__/design_note_spec.js.snap
index e071274cc81..b55bacb6fc5 100644
--- a/spec/frontend/design_management/components/design_notes/__snapshots__/design_note_spec.js.snap
+++ b/spec/frontend/design_management/components/design_notes/__snapshots__/design_note_spec.js.snap
@@ -50,12 +50,18 @@ exports[`Design note component should match the snapshot 1`] = `
</span>
</div>
- <!---->
+ <div
+ class="gl-display-flex"
+ >
+
+ <!---->
+ </div>
</div>
<div
class="note-text js-note-text md"
data-qa-selector="note_content"
/>
+
</timeline-entry-item-stub>
`;
diff --git a/spec/frontend/design_management/components/design_notes/design_discussion_spec.js b/spec/frontend/design_management/components/design_notes/design_discussion_spec.js
index b16b26ff82f..557f53e864f 100644
--- a/spec/frontend/design_management/components/design_notes/design_discussion_spec.js
+++ b/spec/frontend/design_management/components/design_notes/design_discussion_spec.js
@@ -1,16 +1,33 @@
-import { shallowMount } from '@vue/test-utils';
-import { ApolloMutation } from 'vue-apollo';
+import { mount } from '@vue/test-utils';
+import { GlLoadingIcon } from '@gitlab/ui';
+import notes from '../../mock_data/notes';
import DesignDiscussion from '~/design_management/components/design_notes/design_discussion.vue';
import DesignNote from '~/design_management/components/design_notes/design_note.vue';
import DesignReplyForm from '~/design_management/components/design_notes/design_reply_form.vue';
import createNoteMutation from '~/design_management/graphql/mutations/createNote.mutation.graphql';
+import toggleResolveDiscussionMutation from '~/design_management/graphql/mutations/toggle_resolve_discussion.mutation.graphql';
import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue';
+import ToggleRepliesWidget from '~/design_management/components/design_notes/toggle_replies_widget.vue';
+
+const discussion = {
+ id: '0',
+ resolved: false,
+ resolvable: true,
+ notes,
+};
describe('Design discussions component', () => {
let wrapper;
+ const findDesignNotes = () => wrapper.findAll(DesignNote);
const findReplyPlaceholder = () => wrapper.find(ReplyPlaceholder);
const findReplyForm = () => wrapper.find(DesignReplyForm);
+ const findRepliesWidget = () => wrapper.find(ToggleRepliesWidget);
+ const findResolveButton = () => wrapper.find('[data-testid="resolve-button"]');
+ const findResolveIcon = () => wrapper.find('[data-testid="resolve-icon"]');
+ const findResolvedMessage = () => wrapper.find('[data-testid="resolved-message"]');
+ const findResolveLoadingIcon = () => wrapper.find(GlLoadingIcon);
+ const findResolveCheckbox = () => wrapper.find('[data-testid="resolve-checkbox"]');
const mutationVariables = {
mutation: createNoteMutation,
@@ -29,22 +46,14 @@ describe('Design discussions component', () => {
};
function createComponent(props = {}, data = {}) {
- wrapper = shallowMount(DesignDiscussion, {
+ wrapper = mount(DesignDiscussion, {
propsData: {
- discussion: {
- id: '0',
- notes: [
- {
- id: '1',
- },
- {
- id: '2',
- },
- ],
- },
+ resolvedDiscussionsExpanded: true,
+ discussion,
noteableId: 'noteable-id',
designId: 'design-id',
discussionIndex: 1,
+ discussionWithOpenForm: '',
...props,
},
data() {
@@ -52,11 +61,12 @@ describe('Design discussions component', () => {
...data,
};
},
- stubs: {
- ReplyPlaceholder,
- ApolloMutation,
+ mocks: {
+ $apollo,
+ $route: {
+ hash: '#note_1',
+ },
},
- mocks: { $apollo },
});
}
@@ -64,19 +74,147 @@ describe('Design discussions component', () => {
wrapper.destroy();
});
- it('renders correct amount of discussion notes', () => {
- createComponent();
- expect(wrapper.findAll(DesignNote)).toHaveLength(2);
+ describe('when discussion is not resolvable', () => {
+ beforeEach(() => {
+ createComponent({
+ discussion: {
+ ...discussion,
+ resolvable: false,
+ },
+ });
+ });
+
+ it('does not render an icon to resolve a thread', () => {
+ expect(findResolveIcon().exists()).toBe(false);
+ });
+
+ it('does not render a checkbox in reply form', () => {
+ findReplyPlaceholder().vm.$emit('onMouseDown');
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findResolveCheckbox().exists()).toBe(false);
+ });
+ });
});
- it('renders reply placeholder by default', () => {
- createComponent();
- expect(findReplyPlaceholder().exists()).toBe(true);
+ describe('when discussion is unresolved', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('renders correct amount of discussion notes', () => {
+ expect(findDesignNotes()).toHaveLength(2);
+ expect(findDesignNotes().wrappers.every(w => w.isVisible())).toBe(true);
+ });
+
+ it('renders reply placeholder', () => {
+ expect(findReplyPlaceholder().isVisible()).toBe(true);
+ });
+
+ it('does not render toggle replies widget', () => {
+ expect(findRepliesWidget().exists()).toBe(false);
+ });
+
+ it('renders a correct icon to resolve a thread', () => {
+ expect(findResolveIcon().props('name')).toBe('check-circle');
+ });
+
+ it('renders a checkbox with Resolve thread text in reply form', () => {
+ findReplyPlaceholder().vm.$emit('onClick');
+ wrapper.setProps({ discussionWithOpenForm: discussion.id });
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findResolveCheckbox().text()).toBe('Resolve thread');
+ });
+ });
+
+ it('does not render resolved message', () => {
+ expect(findResolvedMessage().exists()).toBe(false);
+ });
+ });
+
+ describe('when discussion is resolved', () => {
+ beforeEach(() => {
+ createComponent({
+ discussion: {
+ ...discussion,
+ resolved: true,
+ resolvedBy: notes[0].author,
+ resolvedAt: '2020-05-08T07:10:45Z',
+ },
+ });
+ });
+
+ it('shows only the first note', () => {
+ expect(
+ findDesignNotes()
+ .at(0)
+ .isVisible(),
+ ).toBe(true);
+ expect(
+ findDesignNotes()
+ .at(1)
+ .isVisible(),
+ ).toBe(false);
+ });
+
+ it('renders resolved message', () => {
+ expect(findResolvedMessage().exists()).toBe(true);
+ });
+
+ it('does not show renders reply placeholder', () => {
+ expect(findReplyPlaceholder().isVisible()).toBe(false);
+ });
+
+ it('renders toggle replies widget with correct props', () => {
+ expect(findRepliesWidget().exists()).toBe(true);
+ expect(findRepliesWidget().props()).toEqual({
+ collapsed: true,
+ replies: notes.slice(1),
+ });
+ });
+
+ it('renders a correct icon to resolve a thread', () => {
+ expect(findResolveIcon().props('name')).toBe('check-circle-filled');
+ });
+
+ describe('when replies are expanded', () => {
+ beforeEach(() => {
+ findRepliesWidget().vm.$emit('toggle');
+ return wrapper.vm.$nextTick();
+ });
+
+ it('renders replies widget with collapsed prop equal to false', () => {
+ expect(findRepliesWidget().props('collapsed')).toBe(false);
+ });
+
+ it('renders the second note', () => {
+ expect(
+ findDesignNotes()
+ .at(1)
+ .isVisible(),
+ ).toBe(true);
+ });
+
+ it('renders a reply placeholder', () => {
+ expect(findReplyPlaceholder().isVisible()).toBe(true);
+ });
+
+ it('renders a checkbox with Unresolve thread text in reply form', () => {
+ findReplyPlaceholder().vm.$emit('onClick');
+ wrapper.setProps({ discussionWithOpenForm: discussion.id });
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findResolveCheckbox().text()).toBe('Unresolve thread');
+ });
+ });
+ });
});
it('hides reply placeholder and opens form on placeholder click', () => {
createComponent();
- findReplyPlaceholder().trigger('click');
+ findReplyPlaceholder().vm.$emit('onClick');
+ wrapper.setProps({ discussionWithOpenForm: discussion.id });
return wrapper.vm.$nextTick().then(() => {
expect(findReplyPlaceholder().exists()).toBe(false);
@@ -85,7 +223,10 @@ describe('Design discussions component', () => {
});
it('calls mutation on submitting form and closes the form', () => {
- createComponent({}, { discussionComment: 'test', isFormRendered: true });
+ createComponent(
+ { discussionWithOpenForm: discussion.id },
+ { discussionComment: 'test', isFormRendered: true },
+ );
findReplyForm().vm.$emit('submitForm');
expect(mutate).toHaveBeenCalledWith(mutationVariables);
@@ -100,7 +241,10 @@ describe('Design discussions component', () => {
});
it('clears the discussion comment on closing comment form', () => {
- createComponent({}, { discussionComment: 'test', isFormRendered: true });
+ createComponent(
+ { discussionWithOpenForm: discussion.id },
+ { discussionComment: 'test', isFormRendered: true },
+ );
return wrapper.vm
.$nextTick()
@@ -120,7 +264,7 @@ describe('Design discussions component', () => {
{},
{
activeDiscussion: {
- id: '1',
+ id: notes[0].id,
source: 'pin',
},
},
@@ -130,4 +274,45 @@ describe('Design discussions component', () => {
true,
);
});
+
+ it('calls toggleResolveDiscussion mutation on resolve thread button click', () => {
+ createComponent();
+ findResolveButton().trigger('click');
+ expect(mutate).toHaveBeenCalledWith({
+ mutation: toggleResolveDiscussionMutation,
+ variables: {
+ id: discussion.id,
+ resolve: true,
+ },
+ });
+ return wrapper.vm.$nextTick(() => {
+ expect(findResolveLoadingIcon().exists()).toBe(true);
+ });
+ });
+
+ it('calls toggleResolveDiscussion mutation after adding a note if checkbox was checked', () => {
+ createComponent(
+ { discussionWithOpenForm: discussion.id },
+ { discussionComment: 'test', isFormRendered: true },
+ );
+ findResolveButton().trigger('click');
+ findReplyForm().vm.$emit('submitForm');
+
+ return mutate().then(() => {
+ expect(mutate).toHaveBeenCalledWith({
+ mutation: toggleResolveDiscussionMutation,
+ variables: {
+ id: discussion.id,
+ resolve: true,
+ },
+ });
+ });
+ });
+
+ it('emits openForm event on opening the form', () => {
+ createComponent();
+ findReplyPlaceholder().vm.$emit('onClick');
+
+ expect(wrapper.emitted('openForm')).toBeTruthy();
+ });
});
diff --git a/spec/frontend/design_management/components/design_notes/design_reply_form_spec.js b/spec/frontend/design_management/components/design_notes/design_reply_form_spec.js
index 34b8f1f9fa8..16b34f150b8 100644
--- a/spec/frontend/design_management/components/design_notes/design_reply_form_spec.js
+++ b/spec/frontend/design_management/components/design_notes/design_reply_form_spec.js
@@ -18,7 +18,7 @@ describe('Design reply form component', () => {
const findCancelButton = () => wrapper.find({ ref: 'cancelButton' });
const findModal = () => wrapper.find({ ref: 'cancelCommentModal' });
- function createComponent(props = {}) {
+ function createComponent(props = {}, mountOptions = {}) {
wrapper = mount(DesignReplyForm, {
propsData: {
value: '',
@@ -26,6 +26,7 @@ describe('Design reply form component', () => {
...props,
},
stubs: { GlModal },
+ ...mountOptions,
});
}
@@ -34,7 +35,8 @@ describe('Design reply form component', () => {
});
it('textarea has focus after component mount', () => {
- createComponent();
+ // We need to attach to document, so that `document.activeElement` is properly set in jsdom
+ createComponent({}, { attachToDocument: true });
expect(findTextarea().element).toEqual(document.activeElement);
});
diff --git a/spec/frontend/design_management/components/design_notes/toggle_replies_widget_spec.js b/spec/frontend/design_management/components/design_notes/toggle_replies_widget_spec.js
new file mode 100644
index 00000000000..7eda294d2d3
--- /dev/null
+++ b/spec/frontend/design_management/components/design_notes/toggle_replies_widget_spec.js
@@ -0,0 +1,98 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlIcon, GlButton, GlLink } from '@gitlab/ui';
+import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
+import ToggleRepliesWidget from '~/design_management/components/design_notes/toggle_replies_widget.vue';
+import notes from '../../mock_data/notes';
+
+describe('Toggle replies widget component', () => {
+ let wrapper;
+
+ const findToggleWrapper = () => wrapper.find('[data-testid="toggle-comments-wrapper"]');
+ const findIcon = () => wrapper.find(GlIcon);
+ const findButton = () => wrapper.find(GlButton);
+ const findAuthorLink = () => wrapper.find(GlLink);
+ const findTimeAgo = () => wrapper.find(TimeAgoTooltip);
+
+ function createComponent(props = {}) {
+ wrapper = shallowMount(ToggleRepliesWidget, {
+ propsData: {
+ collapsed: true,
+ replies: notes,
+ ...props,
+ },
+ });
+ }
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('when replies are collapsed', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('should not have expanded class', () => {
+ expect(findToggleWrapper().classes()).not.toContain('expanded');
+ });
+
+ it('should render chevron-right icon', () => {
+ expect(findIcon().props('name')).toBe('chevron-right');
+ });
+
+ it('should have replies length on button', () => {
+ expect(findButton().text()).toBe('2 replies');
+ });
+
+ it('should render a link to the last reply author', () => {
+ expect(findAuthorLink().exists()).toBe(true);
+ expect(findAuthorLink().text()).toBe(notes[1].author.name);
+ expect(findAuthorLink().attributes('href')).toBe(notes[1].author.webUrl);
+ });
+
+ it('should render correct time ago tooltip', () => {
+ expect(findTimeAgo().exists()).toBe(true);
+ expect(findTimeAgo().props('time')).toBe(notes[1].createdAt);
+ });
+ });
+
+ describe('when replies are expanded', () => {
+ beforeEach(() => {
+ createComponent({ collapsed: false });
+ });
+
+ it('should have expanded class', () => {
+ expect(findToggleWrapper().classes()).toContain('expanded');
+ });
+
+ it('should render chevron-down icon', () => {
+ expect(findIcon().props('name')).toBe('chevron-down');
+ });
+
+ it('should have Collapse replies text on button', () => {
+ expect(findButton().text()).toBe('Collapse replies');
+ });
+
+ it('should not have a link to the last reply author', () => {
+ expect(findAuthorLink().exists()).toBe(false);
+ });
+
+ it('should not render time ago tooltip', () => {
+ expect(findTimeAgo().exists()).toBe(false);
+ });
+ });
+
+ it('should emit toggle event on icon click', () => {
+ createComponent();
+ findIcon().vm.$emit('click', new MouseEvent('click'));
+
+ expect(wrapper.emitted('toggle')).toHaveLength(1);
+ });
+
+ it('should emit toggle event on button click', () => {
+ createComponent();
+ findButton().vm.$emit('click', new MouseEvent('click'));
+
+ expect(wrapper.emitted('toggle')).toHaveLength(1);
+ });
+});
diff --git a/spec/frontend/design_management/components/design_overlay_spec.js b/spec/frontend/design_management/components/design_overlay_spec.js
index 1c9b130aca6..f243323b162 100644
--- a/spec/frontend/design_management/components/design_overlay_spec.js
+++ b/spec/frontend/design_management/components/design_overlay_spec.js
@@ -10,16 +10,6 @@ describe('Design overlay component', () => {
let wrapper;
const mockDimensions = { width: 100, height: 100 };
- const mockNoteNotAuthorised = {
- id: 'note-not-authorised',
- discussion: { id: 'discussion-not-authorised' },
- position: {
- x: 1,
- y: 80,
- ...mockDimensions,
- },
- userPermissions: {},
- };
const findOverlay = () => wrapper.find('.image-diff-overlay');
const findAllNotes = () => wrapper.findAll('.js-image-badge');
@@ -43,6 +33,7 @@ describe('Design overlay component', () => {
top: '0',
left: '0',
},
+ resolvedDiscussionsExpanded: false,
...props,
},
data() {
@@ -88,19 +79,46 @@ describe('Design overlay component', () => {
});
describe('with notes', () => {
- beforeEach(() => {
+ it('should render only the first note', () => {
createComponent({
notes,
});
+ expect(findAllNotes()).toHaveLength(1);
});
- it('should render a correct amount of notes', () => {
- expect(findAllNotes()).toHaveLength(notes.length);
- });
+ describe('with resolved discussions toggle expanded', () => {
+ beforeEach(() => {
+ createComponent({
+ notes,
+ resolvedDiscussionsExpanded: true,
+ });
+ });
+
+ it('should render all notes', () => {
+ expect(findAllNotes()).toHaveLength(notes.length);
+ });
+
+ it('should have set the correct position for each note badge', () => {
+ expect(findFirstBadge().attributes().style).toBe('left: 10px; top: 15px;');
+ expect(findSecondBadge().attributes().style).toBe('left: 50px; top: 50px;');
+ });
+
+ it('should apply resolved class to the resolved note pin', () => {
+ expect(findSecondBadge().classes()).toContain('resolved');
+ });
+
+ it('when there is an active discussion, should apply inactive class to all pins besides the active one', () => {
+ wrapper.setData({
+ activeDiscussion: {
+ id: notes[0].id,
+ source: 'discussion',
+ },
+ });
- it('should have a correct style for each note badge', () => {
- expect(findFirstBadge().attributes().style).toBe('left: 10px; top: 15px;');
- expect(findSecondBadge().attributes().style).toBe('left: 50px; top: 50px;');
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findSecondBadge().classes()).toContain('inactive');
+ });
+ });
});
it('should recalculate badges positions on window resize', () => {
@@ -144,19 +162,6 @@ describe('Design overlay component', () => {
expect(mutate).toHaveBeenCalledWith(mutationVariables);
});
});
-
- it('when there is an active discussion, should apply inactive class to all pins besides the active one', () => {
- wrapper.setData({
- activeDiscussion: {
- id: notes[0].id,
- source: 'discussion',
- },
- });
-
- return wrapper.vm.$nextTick().then(() => {
- expect(findSecondBadge().classes()).toContain('inactive');
- });
- });
});
describe('when moving notes', () => {
@@ -213,20 +218,32 @@ describe('Design overlay component', () => {
});
});
- it('should do nothing if [adminNote] permission is not present', () => {
- createComponent({
- dimensions: mockDimensions,
- notes: [mockNoteNotAuthorised],
- });
+ describe('without [adminNote] permission', () => {
+ const mockNoteNotAuthorised = {
+ ...notes[0],
+ userPermissions: {
+ adminNote: false,
+ },
+ };
- const badge = findAllNotes().at(0);
- return clickAndDragBadge(
- badge,
- { x: mockNoteNotAuthorised.x, y: mockNoteNotAuthorised.y },
- { x: 20, y: 20 },
- ).then(() => {
- expect(wrapper.vm.movingNoteStartPosition).toBeNull();
- expect(findFirstBadge().attributes().style).toBe('left: 1px; top: 80px;');
+ const mockNoteCoordinates = {
+ x: mockNoteNotAuthorised.position.x,
+ y: mockNoteNotAuthorised.position.y,
+ };
+
+ it('should be unable to move a note', () => {
+ createComponent({
+ dimensions: mockDimensions,
+ notes: [mockNoteNotAuthorised],
+ });
+
+ const badge = findAllNotes().at(0);
+ return clickAndDragBadge(badge, { ...mockNoteCoordinates }, { x: 20, y: 20 }).then(() => {
+ // note position should not change after a click-and-drag attempt
+ expect(findFirstBadge().attributes().style).toContain(
+ `left: ${mockNoteCoordinates.x}px; top: ${mockNoteCoordinates.y}px;`,
+ );
+ });
});
});
});
diff --git a/spec/frontend/design_management/components/design_presentation_spec.js b/spec/frontend/design_management/components/design_presentation_spec.js
index 8a709393d92..7e513182589 100644
--- a/spec/frontend/design_management/components/design_presentation_spec.js
+++ b/spec/frontend/design_management/components/design_presentation_spec.js
@@ -17,7 +17,13 @@ describe('Design management design presentation component', () => {
let wrapper;
function createComponent(
- { image, imageName, discussions = [], isAnnotating = false } = {},
+ {
+ image,
+ imageName,
+ discussions = [],
+ isAnnotating = false,
+ resolvedDiscussionsExpanded = false,
+ } = {},
data = {},
stubs = {},
) {
@@ -27,6 +33,7 @@ describe('Design management design presentation component', () => {
imageName,
discussions,
isAnnotating,
+ resolvedDiscussionsExpanded,
},
stubs,
});
diff --git a/spec/frontend/design_management/components/design_sidebar_spec.js b/spec/frontend/design_management/components/design_sidebar_spec.js
new file mode 100644
index 00000000000..e098e7de867
--- /dev/null
+++ b/spec/frontend/design_management/components/design_sidebar_spec.js
@@ -0,0 +1,236 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlCollapse, GlPopover } from '@gitlab/ui';
+import Cookies from 'js-cookie';
+import DesignSidebar from '~/design_management/components/design_sidebar.vue';
+import Participants from '~/sidebar/components/participants/participants.vue';
+import DesignDiscussion from '~/design_management/components/design_notes/design_discussion.vue';
+import design from '../mock_data/design';
+import updateActiveDiscussionMutation from '~/design_management/graphql/mutations/update_active_discussion.mutation.graphql';
+
+const updateActiveDiscussionMutationVariables = {
+ mutation: updateActiveDiscussionMutation,
+ variables: {
+ id: design.discussions.nodes[0].notes.nodes[0].id,
+ source: 'discussion',
+ },
+};
+
+const $route = {
+ params: {
+ id: '1',
+ },
+};
+
+const cookieKey = 'hide_design_resolved_comments_popover';
+
+const mutate = jest.fn().mockResolvedValue();
+
+describe('Design management design sidebar component', () => {
+ let wrapper;
+
+ const findDiscussions = () => wrapper.findAll(DesignDiscussion);
+ const findFirstDiscussion = () => findDiscussions().at(0);
+ const findUnresolvedDiscussions = () => wrapper.findAll('[data-testid="unresolved-discussion"]');
+ const findResolvedDiscussions = () => wrapper.findAll('[data-testid="resolved-discussion"]');
+ const findParticipants = () => wrapper.find(Participants);
+ const findCollapsible = () => wrapper.find(GlCollapse);
+ const findToggleResolvedCommentsButton = () => wrapper.find('[data-testid="resolved-comments"]');
+ const findPopover = () => wrapper.find(GlPopover);
+ const findNewDiscussionDisclaimer = () =>
+ wrapper.find('[data-testid="new-discussion-disclaimer"]');
+
+ function createComponent(props = {}) {
+ wrapper = shallowMount(DesignSidebar, {
+ propsData: {
+ design,
+ resolvedDiscussionsExpanded: false,
+ markdownPreviewPath: '',
+ ...props,
+ },
+ mocks: {
+ $route,
+ $apollo: {
+ mutate,
+ },
+ },
+ });
+ }
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders participants', () => {
+ createComponent();
+
+ expect(findParticipants().exists()).toBe(true);
+ });
+
+ it('passes the correct amount of participants to the Participants component', () => {
+ createComponent();
+
+ expect(findParticipants().props('participants')).toHaveLength(1);
+ });
+
+ describe('when has no discussions', () => {
+ beforeEach(() => {
+ createComponent({
+ design: {
+ ...design,
+ discussions: {
+ nodes: [],
+ },
+ },
+ });
+ });
+
+ it('does not render discussions', () => {
+ expect(findDiscussions().exists()).toBe(false);
+ });
+
+ it('renders a message about possibility to create a new discussion', () => {
+ expect(findNewDiscussionDisclaimer().exists()).toBe(true);
+ });
+ });
+
+ describe('when has discussions', () => {
+ beforeEach(() => {
+ Cookies.set(cookieKey, true);
+ createComponent();
+ });
+
+ it('renders correct amount of unresolved discussions', () => {
+ expect(findUnresolvedDiscussions()).toHaveLength(1);
+ });
+
+ it('renders correct amount of resolved discussions', () => {
+ expect(findResolvedDiscussions()).toHaveLength(1);
+ });
+
+ it('has resolved comments collapsible collapsed', () => {
+ expect(findCollapsible().attributes('visible')).toBeUndefined();
+ });
+
+ it('emits toggleResolveComments event on resolve comments button click', () => {
+ findToggleResolvedCommentsButton().vm.$emit('click');
+ expect(wrapper.emitted('toggleResolvedComments')).toHaveLength(1);
+ });
+
+ it('opens a collapsible when resolvedDiscussionsExpanded prop changes to true', () => {
+ expect(findCollapsible().attributes('visible')).toBeUndefined();
+ wrapper.setProps({
+ resolvedDiscussionsExpanded: true,
+ });
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findCollapsible().attributes('visible')).toBe('true');
+ });
+ });
+
+ it('does not popover about resolved comments', () => {
+ expect(findPopover().exists()).toBe(false);
+ });
+
+ it('sends a mutation to set an active discussion when clicking on a discussion', () => {
+ findFirstDiscussion().trigger('click');
+
+ expect(mutate).toHaveBeenCalledWith(updateActiveDiscussionMutationVariables);
+ });
+
+ it('sends a mutation to reset an active discussion when clicking outside of discussion', () => {
+ wrapper.trigger('click');
+
+ expect(mutate).toHaveBeenCalledWith({
+ ...updateActiveDiscussionMutationVariables,
+ variables: { id: undefined, source: 'discussion' },
+ });
+ });
+
+ it('emits correct event on discussion create note error', () => {
+ findFirstDiscussion().vm.$emit('createNoteError', 'payload');
+ expect(wrapper.emitted('onDesignDiscussionError')).toEqual([['payload']]);
+ });
+
+ it('emits correct event on discussion update note error', () => {
+ findFirstDiscussion().vm.$emit('updateNoteError', 'payload');
+ expect(wrapper.emitted('updateNoteError')).toEqual([['payload']]);
+ });
+
+ it('emits correct event on discussion resolve error', () => {
+ findFirstDiscussion().vm.$emit('resolveDiscussionError', 'payload');
+ expect(wrapper.emitted('resolveDiscussionError')).toEqual([['payload']]);
+ });
+
+ it('changes prop correctly on opening discussion form', () => {
+ findFirstDiscussion().vm.$emit('openForm', 'some-id');
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findFirstDiscussion().props('discussionWithOpenForm')).toBe('some-id');
+ });
+ });
+ });
+
+ describe('when all discussions are resolved', () => {
+ beforeEach(() => {
+ createComponent({
+ design: {
+ ...design,
+ discussions: {
+ nodes: [
+ {
+ id: 'discussion-id',
+ replyId: 'discussion-reply-id',
+ resolved: true,
+ notes: {
+ nodes: [
+ {
+ id: 'note-id',
+ body: '123',
+ author: {
+ name: 'Administrator',
+ username: 'root',
+ webUrl: 'link-to-author',
+ avatarUrl: 'link-to-avatar',
+ },
+ },
+ ],
+ },
+ },
+ ],
+ },
+ },
+ });
+ });
+
+ it('renders a message about possibility to create a new discussion', () => {
+ expect(findNewDiscussionDisclaimer().exists()).toBe(true);
+ });
+
+ it('does not render unresolved discussions', () => {
+ expect(findUnresolvedDiscussions()).toHaveLength(0);
+ });
+ });
+
+ describe('when showing resolved discussions for the first time', () => {
+ beforeEach(() => {
+ Cookies.set(cookieKey, false);
+ createComponent();
+ });
+
+ it('renders a popover if we show resolved comments collapsible for the first time', () => {
+ expect(findPopover().exists()).toBe(true);
+ });
+
+ it('dismisses a popover on the outside click', () => {
+ wrapper.trigger('click');
+ return wrapper.vm.$nextTick(() => {
+ expect(findPopover().exists()).toBe(false);
+ });
+ });
+
+ it(`sets a ${cookieKey} cookie on clicking outside the popover`, () => {
+ jest.spyOn(Cookies, 'set');
+ wrapper.trigger('click');
+ expect(Cookies.set).toHaveBeenCalledWith(cookieKey, 'true', { expires: 365 * 10 });
+ });
+ });
+});
diff --git a/spec/frontend/design_management/components/upload/__snapshots__/button_spec.js.snap b/spec/frontend/design_management/components/upload/__snapshots__/button_spec.js.snap
index 185bf4a48f7..27c0ba589e6 100644
--- a/spec/frontend/design_management/components/upload/__snapshots__/button_spec.js.snap
+++ b/spec/frontend/design_management/components/upload/__snapshots__/button_spec.js.snap
@@ -10,7 +10,7 @@ exports[`Design management upload button component renders inverted upload desig
variant="success"
>
- Add designs
+ Upload designs
<!---->
</gl-deprecated-button-stub>
@@ -34,7 +34,7 @@ exports[`Design management upload button component renders loading icon 1`] = `
variant="success"
>
- Add designs
+ Upload designs
<gl-loading-icon-stub
class="ml-1"
@@ -63,7 +63,7 @@ exports[`Design management upload button component renders upload design button
variant="success"
>
- Add designs
+ Upload designs
<!---->
</gl-deprecated-button-stub>
diff --git a/spec/frontend/design_management/mock_data/design.js b/spec/frontend/design_management/mock_data/design.js
index 34e3077f4a2..675198b9408 100644
--- a/spec/frontend/design_management/mock_data/design.js
+++ b/spec/frontend/design_management/mock_data/design.js
@@ -29,6 +29,7 @@ export default {
{
id: 'discussion-id',
replyId: 'discussion-reply-id',
+ resolved: false,
notes: {
nodes: [
{
@@ -44,6 +45,25 @@ export default {
],
},
},
+ {
+ id: 'discussion-resolved',
+ replyId: 'discussion-reply-resolved',
+ resolved: true,
+ notes: {
+ nodes: [
+ {
+ id: 'note-resolved',
+ body: '123',
+ author: {
+ name: 'Administrator',
+ username: 'root',
+ webUrl: 'link-to-author',
+ avatarUrl: 'link-to-avatar',
+ },
+ },
+ ],
+ },
+ },
],
},
diffRefs: {
diff --git a/spec/frontend/design_management/mock_data/notes.js b/spec/frontend/design_management/mock_data/notes.js
index db4624c8524..80cb3944786 100644
--- a/spec/frontend/design_management/mock_data/notes.js
+++ b/spec/frontend/design_management/mock_data/notes.js
@@ -1,32 +1,46 @@
export default [
{
id: 'note-id-1',
+ index: 1,
position: {
height: 100,
width: 100,
x: 10,
y: 15,
},
+ author: {
+ name: 'John',
+ webUrl: 'link-to-john-profile',
+ },
+ createdAt: '2020-05-08T07:10:45Z',
userPermissions: {
adminNote: true,
},
discussion: {
id: 'discussion-id-1',
},
+ resolved: false,
},
{
id: 'note-id-2',
+ index: 2,
position: {
height: 50,
width: 50,
x: 25,
y: 25,
},
+ author: {
+ name: 'Mary',
+ webUrl: 'link-to-mary-profile',
+ },
+ createdAt: '2020-05-08T07:10:45Z',
userPermissions: {
adminNote: true,
},
discussion: {
id: 'discussion-id-2',
},
+ resolved: true,
},
];
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 76e481ee518..65c4811536e 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
@@ -16,7 +16,7 @@ exports[`Design management design index page renders design index 1`] = `
<!---->
<design-presentation-stub
- discussions="[object Object]"
+ discussions="[object Object],[object Object]"
image="test.jpg"
imagename="test.jpg"
scale="1"
@@ -33,58 +33,86 @@ exports[`Design management design index page renders design index 1`] = `
class="image-notes"
>
<h2
- class="gl-font-size-20-deprecated-no-really-do-not-use-me font-weight-bold mt-0"
+ class="gl-font-weight-bold gl-mt-0"
>
- My precious issue
-
+ My precious issue
+
</h2>
<a
- class="text-tertiary text-decoration-none mb-3 d-block"
+ class="gl-text-gray-600 gl-text-decoration-none gl-mb-6 gl-display-block"
href="full-issue-url"
>
ull-issue-path
</a>
<participants-stub
- class="mb-4"
+ class="gl-mb-4"
numberoflessparticipants="7"
participants="[object Object]"
/>
- <div
- class="design-discussion-wrapper"
+ <!---->
+
+ <design-discussion-stub
+ data-testid="unresolved-discussion"
+ designid="test"
+ discussion="[object Object]"
+ discussionwithopenform=""
+ markdownpreviewpath="//preview_markdown?target_type=Issue"
+ noteableid="design-id"
+ />
+
+ <gl-button-stub
+ category="tertiary"
+ class="link-inherit-color gl-text-black-normal gl-text-decoration-none gl-font-weight-bold gl-mb-4"
+ data-testid="resolved-comments"
+ icon="chevron-right"
+ id="resolved-comments"
+ size="medium"
+ variant="link"
>
- <div
- class="badge badge-pill"
- type="button"
- >
- 1
- </div>
+ Resolved Comments (1)
+
+ </gl-button-stub>
+
+ <gl-popover-stub
+ container="popovercontainer"
+ cssclasses=""
+ placement="top"
+ show="true"
+ target="resolved-comments"
+ title="Resolved Comments"
+ >
+ <p>
+
+ Comments you resolve can be viewed and unresolved by going to the "Resolved Comments" section below
+
+ </p>
- <div
- class="design-discussion bordered-box position-relative"
- data-qa-selector="design_discussion_content"
+ <a
+ href="#"
+ rel="noopener noreferrer"
+ target="_blank"
>
- <design-note-stub
- class=""
- markdownpreviewpath="//preview_markdown?target_type=Issue"
- note="[object Object]"
- />
-
- <div
- class="reply-wrapper"
- >
- <reply-placeholder-stub
- buttontext="Reply..."
- class="qa-discussion-reply"
- />
- </div>
- </div>
- </div>
+ Learn more about resolving comments
+ </a>
+ </gl-popover-stub>
+
+ <gl-collapse-stub
+ class="gl-mt-3"
+ >
+ <design-discussion-stub
+ data-testid="resolved-discussion"
+ designid="test"
+ discussion="[object Object]"
+ discussionwithopenform=""
+ markdownpreviewpath="//preview_markdown?target_type=Issue"
+ noteableid="design-id"
+ />
+ </gl-collapse-stub>
- <!---->
</div>
</div>
`;
@@ -152,33 +180,37 @@ exports[`Design management design index page with error GlAlert is rendered in c
class="image-notes"
>
<h2
- class="gl-font-size-20-deprecated-no-really-do-not-use-me font-weight-bold mt-0"
+ class="gl-font-weight-bold gl-mt-0"
>
- My precious issue
-
+ My precious issue
+
</h2>
<a
- class="text-tertiary text-decoration-none mb-3 d-block"
+ class="gl-text-gray-600 gl-text-decoration-none gl-mb-6 gl-display-block"
href="full-issue-url"
>
ull-issue-path
</a>
<participants-stub
- class="mb-4"
+ class="gl-mb-4"
numberoflessparticipants="7"
participants="[object Object]"
/>
<h2
- class="new-discussion-disclaimer gl-font-base m-0"
+ class="new-discussion-disclaimer gl-font-base gl-m-0 gl-mb-4"
+ data-testid="new-discussion-disclaimer"
>
- Click the image where you'd like to start a new discussion
-
+ Click the image where you'd like to start a new discussion
+
</h2>
+
+ <!---->
+
</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 9e2f071a983..430cf8722fe 100644
--- a/spec/frontend/design_management/pages/design/index_spec.js
+++ b/spec/frontend/design_management/pages/design/index_spec.js
@@ -1,13 +1,12 @@
-import { shallowMount } from '@vue/test-utils';
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import VueRouter from 'vue-router';
import { GlAlert } from '@gitlab/ui';
import { ApolloMutation } from 'vue-apollo';
import createFlash from '~/flash';
import DesignIndex from '~/design_management/pages/design/index.vue';
-import DesignDiscussion from '~/design_management/components/design_notes/design_discussion.vue';
+import DesignSidebar from '~/design_management/components/design_sidebar.vue';
import DesignReplyForm from '~/design_management/components/design_notes/design_reply_form.vue';
-import Participants from '~/sidebar/components/participants/participants.vue';
import createImageDiffNoteMutation from '~/design_management/graphql/mutations/createImageDiffNote.mutation.graphql';
-import updateActiveDiscussionMutation from '~/design_management/graphql/mutations/update_active_discussion.mutation.graphql';
import design from '../../mock_data/design';
import mockResponseWithDesigns from '../../mock_data/designs';
import mockResponseNoDesigns from '../../mock_data/no_designs';
@@ -17,6 +16,9 @@ import {
DESIGN_VERSION_NOT_EXIST_ERROR,
} from '~/design_management/utils/error_messages';
import { DESIGNS_ROUTE_NAME } from '~/design_management/router/constants';
+import createRouter from '~/design_management/router';
+import * as utils from '~/design_management/utils/design_management_utils';
+import { DESIGN_DETAIL_LAYOUT_CLASSLIST } from '~/design_management/constants';
jest.mock('~/flash');
jest.mock('mousetrap', () => ({
@@ -24,8 +26,13 @@ jest.mock('mousetrap', () => ({
unbind: jest.fn(),
}));
+const localVue = createLocalVue();
+localVue.use(VueRouter);
+
describe('Design management design index page', () => {
let wrapper;
+ let router;
+
const newComment = 'new comment';
const annotationCoordinates = {
x: 10,
@@ -53,23 +60,12 @@ describe('Design management design index page', () => {
},
};
- const updateActiveDiscussionMutationVariables = {
- mutation: updateActiveDiscussionMutation,
- variables: {
- id: design.discussions.nodes[0].notes.nodes[0].id,
- source: 'discussion',
- },
- };
-
const mutate = jest.fn().mockResolvedValue();
- const routerPush = jest.fn();
- const findDiscussions = () => wrapper.findAll(DesignDiscussion);
const findDiscussionForm = () => wrapper.find(DesignReplyForm);
- const findParticipants = () => wrapper.find(Participants);
- const findDiscussionsWrapper = () => wrapper.find('.image-notes');
+ const findSidebar = () => wrapper.find(DesignSidebar);
- function createComponent(loading = false, data = {}, { routeQuery = {} } = {}) {
+ function createComponent(loading = false, data = {}) {
const $apollo = {
queries: {
design: {
@@ -79,20 +75,14 @@ describe('Design management design index page', () => {
mutate,
};
- const $router = {
- push: routerPush,
- };
-
- const $route = {
- query: routeQuery,
- };
+ router = createRouter();
wrapper = shallowMount(DesignIndex, {
propsData: { id: '1' },
- mocks: { $apollo, $router, $route },
+ mocks: { $apollo },
stubs: {
ApolloMutation,
- DesignDiscussion,
+ DesignSidebar,
},
data() {
return {
@@ -104,6 +94,8 @@ describe('Design management design index page', () => {
...data,
};
},
+ localVue,
+ router,
});
}
@@ -111,6 +103,23 @@ describe('Design management design index page', () => {
wrapper.destroy();
});
+ describe('when navigating', () => {
+ it('applies fullscreen layout', () => {
+ const mockEl = {
+ classList: {
+ add: jest.fn(),
+ remove: jest.fn(),
+ },
+ };
+ jest.spyOn(utils, 'getPageLayoutElement').mockReturnValue(mockEl);
+ createComponent(true);
+
+ wrapper.vm.$router.push('/designs/test');
+ expect(mockEl.classList.add).toHaveBeenCalledTimes(1);
+ expect(mockEl.classList.add).toHaveBeenCalledWith(...DESIGN_DETAIL_LAYOUT_CLASSLIST);
+ });
+ });
+
it('sets loading state', () => {
createComponent(true);
@@ -124,63 +133,13 @@ describe('Design management design index page', () => {
expect(wrapper.find(GlAlert).exists()).toBe(false);
});
- it('renders participants', () => {
- createComponent(false, { design });
-
- expect(findParticipants().exists()).toBe(true);
- });
-
- it('passes the correct amount of participants to the Participants component', () => {
+ it('passes correct props to sidebar component', () => {
createComponent(false, { design });
- expect(findParticipants().props('participants')).toHaveLength(1);
- });
-
- describe('when has no discussions', () => {
- beforeEach(() => {
- createComponent(false, {
- design: {
- ...design,
- discussions: {
- nodes: [],
- },
- },
- });
- });
-
- it('does not render discussions', () => {
- expect(findDiscussions().exists()).toBe(false);
- });
-
- it('renders a message about possibility to create a new discussion', () => {
- expect(wrapper.find('.new-discussion-disclaimer').exists()).toBe(true);
- });
- });
-
- describe('when has discussions', () => {
- beforeEach(() => {
- createComponent(false, { design });
- });
-
- it('renders correct amount of discussions', () => {
- expect(findDiscussions()).toHaveLength(1);
- });
-
- it('sends a mutation to set an active discussion when clicking on a discussion', () => {
- findDiscussions()
- .at(0)
- .trigger('click');
-
- expect(mutate).toHaveBeenCalledWith(updateActiveDiscussionMutationVariables);
- });
-
- it('sends a mutation to reset an active discussion when clicking outside of discussion', () => {
- findDiscussionsWrapper().trigger('click');
-
- expect(mutate).toHaveBeenCalledWith({
- ...updateActiveDiscussionMutationVariables,
- variables: { id: undefined, source: 'discussion' },
- });
+ expect(findSidebar().props()).toEqual({
+ design,
+ markdownPreviewPath: '//preview_markdown?target_type=Issue',
+ resolvedDiscussionsExpanded: false,
});
});
@@ -269,31 +228,35 @@ describe('Design management design index page', () => {
describe('with no designs', () => {
it('redirects to /designs', () => {
createComponent(true);
+ router.push = jest.fn();
wrapper.vm.onDesignQueryResult({ data: mockResponseNoDesigns, loading: false });
return wrapper.vm.$nextTick().then(() => {
expect(createFlash).toHaveBeenCalledTimes(1);
expect(createFlash).toHaveBeenCalledWith(DESIGN_NOT_FOUND_ERROR);
- expect(routerPush).toHaveBeenCalledTimes(1);
- expect(routerPush).toHaveBeenCalledWith({ name: DESIGNS_ROUTE_NAME });
+ expect(router.push).toHaveBeenCalledTimes(1);
+ expect(router.push).toHaveBeenCalledWith({ name: DESIGNS_ROUTE_NAME });
});
});
});
describe('when no design exists for given version', () => {
it('redirects to /designs', () => {
- // attempt to query for a version of the design that doesn't exist
- createComponent(true, {}, { routeQuery: { version: '999' } });
+ createComponent(true);
wrapper.setData({
allVersions: mockAllVersions,
});
+ // attempt to query for a version of the design that doesn't exist
+ router.push({ query: { version: '999' } });
+ router.push = jest.fn();
+
wrapper.vm.onDesignQueryResult({ data: mockResponseWithDesigns, loading: false });
return wrapper.vm.$nextTick().then(() => {
expect(createFlash).toHaveBeenCalledTimes(1);
expect(createFlash).toHaveBeenCalledWith(DESIGN_VERSION_NOT_EXIST_ERROR);
- expect(routerPush).toHaveBeenCalledTimes(1);
- expect(routerPush).toHaveBeenCalledWith({ name: DESIGNS_ROUTE_NAME });
+ expect(router.push).toHaveBeenCalledTimes(1);
+ expect(router.push).toHaveBeenCalledWith({ name: DESIGNS_ROUTE_NAME });
});
});
});
diff --git a/spec/frontend/design_management/pages/index_spec.js b/spec/frontend/design_management/pages/index_spec.js
index 2299b858da9..d4e9bae3e89 100644
--- a/spec/frontend/design_management/pages/index_spec.js
+++ b/spec/frontend/design_management/pages/index_spec.js
@@ -2,7 +2,6 @@ import { createLocalVue, shallowMount } from '@vue/test-utils';
import { ApolloMutation } from 'vue-apollo';
import VueRouter from 'vue-router';
import { GlEmptyState } from '@gitlab/ui';
-
import Index from '~/design_management/pages/index.vue';
import uploadDesignQuery from '~/design_management/graphql/mutations/uploadDesign.mutation.graphql';
import DesignDestroyer from '~/design_management/components/design_destroyer.vue';
@@ -14,20 +13,21 @@ import {
EXISTING_DESIGN_DROP_INVALID_FILENAME_MESSAGE,
} from '~/design_management/utils/error_messages';
import createFlash from '~/flash';
+import createRouter from '~/design_management/router';
+import * as utils from '~/design_management/utils/design_management_utils';
+import { DESIGN_DETAIL_LAYOUT_CLASSLIST } from '~/design_management/constants';
+
+jest.mock('~/flash.js');
+const mockPageEl = {
+ classList: {
+ remove: jest.fn(),
+ },
+};
+jest.spyOn(utils, 'getPageLayoutElement').mockReturnValue(mockPageEl);
const localVue = createLocalVue();
+const router = createRouter();
localVue.use(VueRouter);
-const router = new VueRouter({
- routes: [
- {
- name: DESIGNS_ROUTE_NAME,
- path: '/designs',
- component: Index,
- },
- ],
-});
-
-jest.mock('~/flash.js');
const mockDesigns = [
{
@@ -530,4 +530,14 @@ describe('Design management index page', () => {
expect(wrapper.vm.onUploadDesign).not.toHaveBeenCalled();
});
});
+
+ describe('when navigating', () => {
+ it('ensures fullscreen layout is not applied', () => {
+ createComponent(true);
+
+ wrapper.vm.$router.push('/designs');
+ expect(mockPageEl.classList.remove).toHaveBeenCalledTimes(1);
+ expect(mockPageEl.classList.remove).toHaveBeenCalledWith(...DESIGN_DETAIL_LAYOUT_CLASSLIST);
+ });
+ });
});
diff --git a/spec/frontend/design_management/router_spec.js b/spec/frontend/design_management/router_spec.js
index 0f4afa5e288..d6488d3837a 100644
--- a/spec/frontend/design_management/router_spec.js
+++ b/spec/frontend/design_management/router_spec.js
@@ -33,6 +33,7 @@ function factory(routeArg) {
design: { loading: true },
permissions: { loading: true },
},
+ mutate: jest.fn(),
},
},
});
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 af631073df6..478ebadc8f6 100644
--- a/spec/frontend/design_management/utils/design_management_utils_spec.js
+++ b/spec/frontend/design_management/utils/design_management_utils_spec.js
@@ -53,10 +53,10 @@ describe('extractDiscussions', () => {
it('discards the edges.node artifacts of GraphQL', () => {
expect(extractDiscussions(discussions)).toEqual([
- { id: 1, notes: ['a'] },
- { id: 2, notes: ['b'] },
- { id: 3, notes: ['c'] },
- { id: 4, notes: ['d'] },
+ { id: 1, notes: ['a'], index: 1 },
+ { id: 2, notes: ['b'], index: 2 },
+ { id: 3, notes: ['c'], index: 3 },
+ { id: 4, notes: ['d'], index: 4 },
]);
});
});
diff --git a/spec/frontend/diffs/components/diff_file_spec.js b/spec/frontend/diffs/components/diff_file_spec.js
index d0ba71fce47..71e975f2409 100644
--- a/spec/frontend/diffs/components/diff_file_spec.js
+++ b/spec/frontend/diffs/components/diff_file_spec.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import { createStore } from 'ee_else_ce/mr_notes/stores';
+import { createStore } from '~/mr_notes/stores';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import { mockTracking, triggerEvent } from 'helpers/tracking_helper';
import DiffFileComponent from '~/diffs/components/diff_file.vue';
diff --git a/spec/frontend/diffs/components/diff_line_note_form_spec.js b/spec/frontend/diffs/components/diff_line_note_form_spec.js
index 3e0acd0dace..623df8bd55e 100644
--- a/spec/frontend/diffs/components/diff_line_note_form_spec.js
+++ b/spec/frontend/diffs/components/diff_line_note_form_spec.js
@@ -77,12 +77,24 @@ describe('DiffLineNoteForm', () => {
.spyOn(wrapper.vm, 'saveDiffDiscussion')
.mockReturnValue(Promise.resolve());
+ const lineRange = {
+ start_line_code: wrapper.vm.commentLineStart.lineCode,
+ start_line_type: wrapper.vm.commentLineStart.type,
+ end_line_code: wrapper.vm.line.line_code,
+ end_line_type: wrapper.vm.line.type,
+ };
+
+ const formData = {
+ ...wrapper.vm.formData,
+ lineRange,
+ };
+
wrapper.vm
.handleSaveNote('note body')
.then(() => {
expect(saveDiffDiscussionSpy).toHaveBeenCalledWith({
note: 'note body',
- formData: wrapper.vm.formData,
+ formData,
});
})
.then(done)
diff --git a/spec/frontend/diffs/components/inline_diff_view_spec.js b/spec/frontend/diffs/components/inline_diff_view_spec.js
index 9b0cf6a84d9..eeef8e5a7b0 100644
--- a/spec/frontend/diffs/components/inline_diff_view_spec.js
+++ b/spec/frontend/diffs/components/inline_diff_view_spec.js
@@ -1,6 +1,6 @@
import Vue from 'vue';
import '~/behaviors/markdown/render_gfm';
-import { createStore } from 'ee_else_ce/mr_notes/stores';
+import { createStore } from '~/mr_notes/stores';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import InlineDiffView from '~/diffs/components/inline_diff_view.vue';
import diffFileMockData from '../mock_data/diff_file';
diff --git a/spec/frontend/diffs/components/parallel_diff_view_spec.js b/spec/frontend/diffs/components/parallel_diff_view_spec.js
index 03cf1b72b62..30231f0ba71 100644
--- a/spec/frontend/diffs/components/parallel_diff_view_spec.js
+++ b/spec/frontend/diffs/components/parallel_diff_view_spec.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import { createStore } from 'ee_else_ce/mr_notes/stores';
+import { createStore } from '~/mr_notes/stores';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import ParallelDiffView from '~/diffs/components/parallel_diff_view.vue';
import * as constants from '~/diffs/constants';
diff --git a/spec/frontend/diffs/mock_data/diff_file.js b/spec/frontend/diffs/mock_data/diff_file.js
index 27428197c1c..e4b2fdf6ede 100644
--- a/spec/frontend/diffs/mock_data/diff_file.js
+++ b/spec/frontend/diffs/mock_data/diff_file.js
@@ -13,6 +13,7 @@ export default {
blob_name: 'CHANGELOG',
blob_icon: '<i aria-hidden="true" data-hidden="true" class="fa fa-file-text-o fa-fw"></i>',
file_hash: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a',
+ file_identifier_hash: '928f8286952bda02d674b692addcbe077084663a',
file_path: 'CHANGELOG',
new_file: false,
deleted_file: false,
diff --git a/spec/frontend/diffs/mock_data/diff_metadata.js b/spec/frontend/diffs/mock_data/diff_metadata.js
new file mode 100644
index 00000000000..b73b29e4bc8
--- /dev/null
+++ b/spec/frontend/diffs/mock_data/diff_metadata.js
@@ -0,0 +1,58 @@
+/* eslint-disable import/prefer-default-export */
+/* https://gitlab.com/gitlab-org/frontend/rfcs/-/issues/20 */
+
+export const diffMetadata = {
+ real_size: '1',
+ size: 1,
+ branch_name: 'update-changelog',
+ source_branch_exists: true,
+ target_branch_name: 'master',
+ commit: null,
+ context_commits: null,
+ merge_request_diff: {
+ version_index: null,
+ created_at: '2019-11-07T06:48:35.202Z',
+ commits_count: 1,
+ latest: true,
+ short_commit_sha: 'eb227b3e',
+ base_version_path: '/gitlab-org/gitlab-test/-/merge_requests/4/diffs?diff_id=4',
+ head_version_path: '/gitlab-org/gitlab-test/-/merge_requests/4/diffs?diff_head=true',
+ version_path: '/gitlab-org/gitlab-test/-/merge_requests/4/diffs?diff_id=4',
+ compare_path:
+ '/gitlab-org/gitlab-test/-/merge_requests/4/diffs?diff_id=4\u0026start_sha=eb227b3e214624708c474bdab7bde7afc17cefcc',
+ },
+ start_version: null,
+ latest_diff: true,
+ latest_version_path: '/gitlab-org/gitlab-test/-/merge_requests/4/diffs',
+ added_lines: 2,
+ removed_lines: 0,
+ render_overflow_warning: false,
+ email_patch_path: '/gitlab-org/gitlab-test/-/merge_requests/4.patch',
+ plain_diff_path: '/gitlab-org/gitlab-test/-/merge_requests/4.diff',
+ merge_request_diffs: [
+ {
+ version_index: null,
+ created_at: '2019-11-07T06:48:35.202Z',
+ commits_count: 1,
+ latest: true,
+ short_commit_sha: 'eb227b3e',
+ base_version_path: '/gitlab-org/gitlab-test/-/merge_requests/4/diffs?diff_id=4',
+ head_version_path: '/gitlab-org/gitlab-test/-/merge_requests/4/diffs?diff_head=true',
+ version_path: '/gitlab-org/gitlab-test/-/merge_requests/4/diffs?diff_id=4',
+ compare_path:
+ '/gitlab-org/gitlab-test/-/merge_requests/4/diffs?diff_id=4\u0026start_sha=eb227b3e214624708c474bdab7bde7afc17cefcc',
+ },
+ ],
+ diff_files: [
+ {
+ added_lines: 2,
+ removed_lines: 0,
+ new_path: 'CHANGELOG',
+ old_path: 'CHANGELOG',
+ new_file: false,
+ deleted_file: false,
+ file_identifier_hash: '928f8286952bda02d674b692addcbe077084663a',
+ file_hash: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a',
+ },
+ ],
+};
diff --git a/spec/frontend/diffs/store/actions_spec.js b/spec/frontend/diffs/store/actions_spec.js
index 3fba661da44..7d79dcfbfe3 100644
--- a/spec/frontend/diffs/store/actions_spec.js
+++ b/spec/frontend/diffs/store/actions_spec.js
@@ -35,8 +35,6 @@ import {
setRenderTreeList,
setShowWhitespace,
setRenderIt,
- requestFullDiff,
- receiveFullDiffSucess,
receiveFullDiffError,
fetchFullDiff,
toggleFullDiff,
@@ -53,7 +51,9 @@ import axios from '~/lib/utils/axios_utils';
import testAction from '../../helpers/vuex_action_helper';
import * as utils from '~/diffs/store/utils';
import * as commonUtils from '~/lib/utils/common_utils';
+import { mergeUrlParams } from '~/lib/utils/url_utility';
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
+import { diffMetadata } from '../mock_data/diff_metadata';
import createFlash from '~/flash';
jest.mock('~/flash', () => jest.fn());
@@ -175,19 +175,44 @@ describe('DiffsStoreActions', () => {
});
describe('fetchDiffFilesBatch', () => {
+ let mock;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ });
+
+ afterEach(() => {
+ mock.restore();
+ });
+
it('should fetch batch diff files', done => {
const endpointBatch = '/fetch/diffs_batch';
- const mock = new MockAdapter(axios);
const res1 = { diff_files: [], pagination: { next_page: 2 } };
const res2 = { diff_files: [], pagination: {} };
mock
- .onGet(endpointBatch, {
- params: { page: 1, per_page: DIFFS_PER_PAGE, w: '1', view: 'inline' },
- })
+ .onGet(
+ mergeUrlParams(
+ {
+ per_page: DIFFS_PER_PAGE,
+ w: '1',
+ view: 'inline',
+ page: 1,
+ },
+ endpointBatch,
+ ),
+ )
.reply(200, res1)
- .onGet(endpointBatch, {
- params: { page: 2, per_page: DIFFS_PER_PAGE, w: '1', view: 'inline' },
- })
+ .onGet(
+ mergeUrlParams(
+ {
+ per_page: DIFFS_PER_PAGE,
+ w: '1',
+ view: 'inline',
+ page: 2,
+ },
+ endpointBatch,
+ ),
+ )
.reply(200, res2);
testAction(
@@ -204,22 +229,50 @@ describe('DiffsStoreActions', () => {
{ type: types.SET_RETRIEVING_BATCHES, payload: false },
],
[],
- () => {
- mock.restore();
- done();
- },
+ done,
);
});
+
+ it.each`
+ viewStyle | otherView
+ ${'inline'} | ${'parallel'}
+ ${'parallel'} | ${'inline'}
+ `(
+ 'should make a request with the view parameter "$viewStyle" when the batchEndpoint already contains "$otherView"',
+ ({ viewStyle, otherView }) => {
+ const endpointBatch = '/fetch/diffs_batch';
+
+ fetchDiffFilesBatch({
+ commit: () => {},
+ state: {
+ endpointBatch: `${endpointBatch}?view=${otherView}`,
+ useSingleDiffStyle: true,
+ diffViewType: viewStyle,
+ },
+ })
+ .then(() => {
+ expect(mock.history.get[0].url).toContain(`view=${viewStyle}`);
+ expect(mock.history.get[0].url).not.toContain(`view=${otherView}`);
+ })
+ .catch(() => {});
+ },
+ );
});
describe('fetchDiffFilesMeta', () => {
- it('should fetch diff meta information', done => {
- const endpointMetadata = '/fetch/diffs_meta?view=inline';
- const mock = new MockAdapter(axios);
- const data = { diff_files: [] };
- const res = { data };
- mock.onGet(endpointMetadata).reply(200, res);
+ const endpointMetadata = '/fetch/diffs_metadata.json?view=inline';
+ const noFilesData = { ...diffMetadata };
+ let mock;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+
+ delete noFilesData.diff_files;
+
+ mock.onGet(endpointMetadata).reply(200, diffMetadata);
+ });
+ it('should fetch diff meta information', done => {
testAction(
fetchDiffFilesMeta,
{},
@@ -227,8 +280,8 @@ describe('DiffsStoreActions', () => {
[
{ type: types.SET_LOADING, payload: true },
{ type: types.SET_LOADING, payload: false },
- { type: types.SET_MERGE_REQUEST_DIFFS, payload: [] },
- { type: types.SET_DIFF_DATA, payload: { data } },
+ { type: types.SET_MERGE_REQUEST_DIFFS, payload: diffMetadata.merge_request_diffs },
+ { type: types.SET_DIFF_DATA, payload: noFilesData },
],
[],
() => {
@@ -280,15 +333,24 @@ describe('DiffsStoreActions', () => {
});
describe('fetchDiffFilesBatch', () => {
+ let mock;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ });
+
+ afterEach(() => {
+ mock.restore();
+ });
+
it('should fetch batch diff files', done => {
const endpointBatch = '/fetch/diffs_batch';
- const mock = new MockAdapter(axios);
const res1 = { diff_files: [], pagination: { next_page: 2 } };
const res2 = { diff_files: [], pagination: {} };
mock
- .onGet(endpointBatch, { params: { page: 1, per_page: DIFFS_PER_PAGE, w: '1' } })
+ .onGet(mergeUrlParams({ per_page: DIFFS_PER_PAGE, w: '1', page: 1 }, endpointBatch))
.reply(200, res1)
- .onGet(endpointBatch, { params: { page: 2, per_page: DIFFS_PER_PAGE, w: '1' } })
+ .onGet(mergeUrlParams({ per_page: DIFFS_PER_PAGE, w: '1', page: 2 }, endpointBatch))
.reply(200, res2);
testAction(
@@ -305,22 +367,48 @@ describe('DiffsStoreActions', () => {
{ type: types.SET_RETRIEVING_BATCHES, payload: false },
],
[],
- () => {
- mock.restore();
- done();
- },
+ done,
);
});
+
+ it.each`
+ querystrings | requestUrl
+ ${'?view=parallel'} | ${'/fetch/diffs_batch?view=parallel'}
+ ${'?view=inline'} | ${'/fetch/diffs_batch?view=inline'}
+ ${''} | ${'/fetch/diffs_batch'}
+ `(
+ 'should use the endpoint $requestUrl if the endpointBatch in state includes `$querystrings` as a querystring',
+ ({ querystrings, requestUrl }) => {
+ const endpointBatch = '/fetch/diffs_batch';
+
+ fetchDiffFilesBatch({
+ commit: () => {},
+ state: {
+ endpointBatch: `${endpointBatch}${querystrings}`,
+ diffViewType: 'inline',
+ },
+ })
+ .then(() => {
+ expect(mock.history.get[0].url).toEqual(requestUrl);
+ })
+ .catch(() => {});
+ },
+ );
});
describe('fetchDiffFilesMeta', () => {
- it('should fetch diff meta information', done => {
- const endpointMetadata = '/fetch/diffs_meta';
- const mock = new MockAdapter(axios);
- const data = { diff_files: [] };
- const res = { data };
- mock.onGet(endpointMetadata).reply(200, res);
+ const endpointMetadata = '/fetch/diffs_metadata.json';
+ const noFilesData = { ...diffMetadata };
+ let mock;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+
+ delete noFilesData.diff_files;
+ mock.onGet(endpointMetadata).reply(200, diffMetadata);
+ });
+ it('should fetch diff meta information', done => {
testAction(
fetchDiffFilesMeta,
{},
@@ -328,8 +416,8 @@ describe('DiffsStoreActions', () => {
[
{ type: types.SET_LOADING, payload: true },
{ type: types.SET_LOADING, payload: false },
- { type: types.SET_MERGE_REQUEST_DIFFS, payload: [] },
- { type: types.SET_DIFF_DATA, payload: { data } },
+ { type: types.SET_MERGE_REQUEST_DIFFS, payload: diffMetadata.merge_request_diffs },
+ { type: types.SET_DIFF_DATA, payload: noFilesData },
],
[],
() => {
@@ -467,9 +555,9 @@ describe('DiffsStoreActions', () => {
new_path: 'file1',
old_line: 5,
old_path: 'file2',
+ line_range: null,
line_code: 'ABC_1_1',
position_type: 'text',
- line_range: null,
},
},
hash: 'ABC_123',
@@ -1136,34 +1224,8 @@ describe('DiffsStoreActions', () => {
});
});
- describe('requestFullDiff', () => {
- it('commits REQUEST_FULL_DIFF', done => {
- testAction(
- requestFullDiff,
- 'file',
- {},
- [{ type: types.REQUEST_FULL_DIFF, payload: 'file' }],
- [],
- done,
- );
- });
- });
-
- describe('receiveFullDiffSucess', () => {
- it('commits REQUEST_FULL_DIFF', done => {
- testAction(
- receiveFullDiffSucess,
- { filePath: 'test' },
- {},
- [{ type: types.RECEIVE_FULL_DIFF_SUCCESS, payload: { filePath: 'test' } }],
- [],
- done,
- );
- });
- });
-
describe('receiveFullDiffError', () => {
- it('commits REQUEST_FULL_DIFF', done => {
+ it('updates state with the file that did not load', done => {
testAction(
receiveFullDiffError,
'file',
@@ -1191,7 +1253,7 @@ describe('DiffsStoreActions', () => {
mock.onGet(`${gl.TEST_HOST}/context`).replyOnce(200, ['test']);
});
- it('dispatches receiveFullDiffSucess', done => {
+ it('commits the success and dispatches an action to expand the new lines', done => {
const file = {
context_lines_path: `${gl.TEST_HOST}/context`,
file_path: 'test',
@@ -1201,11 +1263,8 @@ describe('DiffsStoreActions', () => {
fetchFullDiff,
file,
null,
- [],
- [
- { type: 'receiveFullDiffSucess', payload: { filePath: 'test' } },
- { type: 'setExpandedDiffLines', payload: { file, data: ['test'] } },
- ],
+ [{ type: types.RECEIVE_FULL_DIFF_SUCCESS, payload: { filePath: 'test' } }],
+ [{ type: 'setExpandedDiffLines', payload: { file, data: ['test'] } }],
done,
);
});
@@ -1243,11 +1302,8 @@ describe('DiffsStoreActions', () => {
toggleFullDiff,
'test',
state,
- [],
- [
- { type: 'requestFullDiff', payload: 'test' },
- { type: 'fetchFullDiff', payload: state.diffFiles[0] },
- ],
+ [{ type: types.REQUEST_FULL_DIFF, payload: 'test' }],
+ [{ type: 'fetchFullDiff', payload: state.diffFiles[0] }],
done,
);
});
@@ -1255,7 +1311,6 @@ describe('DiffsStoreActions', () => {
describe('switchToFullDiffFromRenamedFile', () => {
const SUCCESS_URL = 'fakehost/context.success';
- const ERROR_URL = 'fakehost/context.error';
const testFilePath = 'testpath';
const updatedViewerName = 'testviewer';
const preparedLine = { prepared: 'in-a-test' };
@@ -1311,27 +1366,6 @@ describe('DiffsStoreActions', () => {
},
);
});
-
- describe('error', () => {
- beforeEach(() => {
- renamedFile = { ...testFile, context_lines_path: ERROR_URL };
- mock.onGet(ERROR_URL).reply(500);
- });
-
- it('dispatches the error handling action', () => {
- const rejected = testAction(
- switchToFullDiffFromRenamedFile,
- { diffFile: renamedFile },
- null,
- [],
- [{ type: 'receiveFullDiffError', payload: testFilePath }],
- );
-
- return rejected.catch(error =>
- expect(error).toEqual(new Error('Request failed with status code 500')),
- );
- });
- });
});
describe('setFileCollapsed', () => {
diff --git a/spec/frontend/diffs/store/utils_spec.js b/spec/frontend/diffs/store/utils_spec.js
index 641373e666f..891de45e268 100644
--- a/spec/frontend/diffs/store/utils_spec.js
+++ b/spec/frontend/diffs/store/utils_spec.js
@@ -14,9 +14,11 @@ import {
} from '~/diffs/constants';
import { MERGE_REQUEST_NOTEABLE_TYPE } from '~/notes/constants';
import diffFileMockData from '../mock_data/diff_file';
+import { diffMetadata } from '../mock_data/diff_metadata';
import { noteableDataMock } from '../../notes/mock_data';
const getDiffFileMock = () => JSON.parse(JSON.stringify(diffFileMockData));
+const getDiffMetadataMock = () => JSON.parse(JSON.stringify(diffMetadata));
describe('DiffsStoreUtils', () => {
describe('findDiffFile', () => {
@@ -187,6 +189,7 @@ describe('DiffsStoreUtils', () => {
},
diffViewType: PARALLEL_DIFF_VIEW_TYPE,
linePosition: LINE_POSITION_LEFT,
+ lineRange: { start_line_code: 'abc_1_1', end_line_code: 'abc_2_2' },
};
const position = JSON.stringify({
@@ -198,6 +201,7 @@ describe('DiffsStoreUtils', () => {
position_type: TEXT_DIFF_POSITION_TYPE,
old_line: options.noteTargetLine.old_line,
new_line: options.noteTargetLine.new_line,
+ line_range: options.lineRange,
});
const postData = {
@@ -428,112 +432,177 @@ describe('DiffsStoreUtils', () => {
});
describe('prepareDiffData', () => {
- let mock;
- let preparedDiff;
- let splitInlineDiff;
- let splitParallelDiff;
- let completedDiff;
+ describe('for regular diff files', () => {
+ let mock;
+ let preparedDiff;
+ let splitInlineDiff;
+ let splitParallelDiff;
+ let completedDiff;
+
+ beforeEach(() => {
+ mock = getDiffFileMock();
+
+ preparedDiff = { diff_files: [mock] };
+ splitInlineDiff = {
+ diff_files: [{ ...mock, parallel_diff_lines: undefined }],
+ };
+ splitParallelDiff = {
+ diff_files: [{ ...mock, highlighted_diff_lines: undefined }],
+ };
+ completedDiff = {
+ diff_files: [{ ...mock, highlighted_diff_lines: undefined }],
+ };
- beforeEach(() => {
- mock = getDiffFileMock();
- preparedDiff = { diff_files: [mock] };
- splitInlineDiff = {
- diff_files: [{ ...mock, parallel_diff_lines: undefined }],
- };
- splitParallelDiff = {
- diff_files: [{ ...mock, highlighted_diff_lines: undefined }],
- };
- completedDiff = {
- diff_files: [{ ...mock, highlighted_diff_lines: undefined }],
- };
+ preparedDiff.diff_files = utils.prepareDiffData(preparedDiff);
+ splitInlineDiff.diff_files = utils.prepareDiffData(splitInlineDiff);
+ splitParallelDiff.diff_files = utils.prepareDiffData(splitParallelDiff);
+ completedDiff.diff_files = utils.prepareDiffData(completedDiff, [mock]);
+ });
- preparedDiff.diff_files = utils.prepareDiffData(preparedDiff);
- splitInlineDiff.diff_files = utils.prepareDiffData(splitInlineDiff);
- splitParallelDiff.diff_files = utils.prepareDiffData(splitParallelDiff);
- completedDiff.diff_files = utils.prepareDiffData(completedDiff, [mock]);
- });
+ it('sets the renderIt and collapsed attribute on files', () => {
+ const firstParallelDiffLine = preparedDiff.diff_files[0].parallel_diff_lines[2];
- it('sets the renderIt and collapsed attribute on files', () => {
- const firstParallelDiffLine = preparedDiff.diff_files[0].parallel_diff_lines[2];
+ expect(firstParallelDiffLine.left.discussions.length).toBe(0);
+ expect(firstParallelDiffLine.left).not.toHaveAttr('text');
+ expect(firstParallelDiffLine.right.discussions.length).toBe(0);
+ expect(firstParallelDiffLine.right).not.toHaveAttr('text');
+ const firstParallelChar = firstParallelDiffLine.right.rich_text.charAt(0);
- expect(firstParallelDiffLine.left.discussions.length).toBe(0);
- expect(firstParallelDiffLine.left).not.toHaveAttr('text');
- expect(firstParallelDiffLine.right.discussions.length).toBe(0);
- expect(firstParallelDiffLine.right).not.toHaveAttr('text');
- const firstParallelChar = firstParallelDiffLine.right.rich_text.charAt(0);
+ expect(firstParallelChar).not.toBe(' ');
+ expect(firstParallelChar).not.toBe('+');
+ expect(firstParallelChar).not.toBe('-');
- expect(firstParallelChar).not.toBe(' ');
- expect(firstParallelChar).not.toBe('+');
- expect(firstParallelChar).not.toBe('-');
+ const checkLine = preparedDiff.diff_files[0].highlighted_diff_lines[0];
- const checkLine = preparedDiff.diff_files[0].highlighted_diff_lines[0];
+ expect(checkLine.discussions.length).toBe(0);
+ expect(checkLine).not.toHaveAttr('text');
+ const firstChar = checkLine.rich_text.charAt(0);
- expect(checkLine.discussions.length).toBe(0);
- expect(checkLine).not.toHaveAttr('text');
- const firstChar = checkLine.rich_text.charAt(0);
+ expect(firstChar).not.toBe(' ');
+ expect(firstChar).not.toBe('+');
+ expect(firstChar).not.toBe('-');
- expect(firstChar).not.toBe(' ');
- expect(firstChar).not.toBe('+');
- expect(firstChar).not.toBe('-');
+ expect(preparedDiff.diff_files[0].renderIt).toBeTruthy();
+ expect(preparedDiff.diff_files[0].collapsed).toBeFalsy();
+ });
- expect(preparedDiff.diff_files[0].renderIt).toBeTruthy();
- expect(preparedDiff.diff_files[0].collapsed).toBeFalsy();
- });
+ it('adds line_code to all lines', () => {
+ expect(
+ preparedDiff.diff_files[0].parallel_diff_lines.filter(line => !line.line_code),
+ ).toHaveLength(0);
+ });
- it('adds line_code to all lines', () => {
- expect(
- preparedDiff.diff_files[0].parallel_diff_lines.filter(line => !line.line_code),
- ).toHaveLength(0);
- });
+ it('uses right line code if left has none', () => {
+ const firstLine = preparedDiff.diff_files[0].parallel_diff_lines[0];
- it('uses right line code if left has none', () => {
- const firstLine = preparedDiff.diff_files[0].parallel_diff_lines[0];
+ expect(firstLine.line_code).toEqual(firstLine.right.line_code);
+ });
- expect(firstLine.line_code).toEqual(firstLine.right.line_code);
- });
+ it('guarantees an empty array for both diff styles', () => {
+ expect(splitInlineDiff.diff_files[0].parallel_diff_lines.length).toEqual(0);
+ expect(splitInlineDiff.diff_files[0].highlighted_diff_lines.length).toBeGreaterThan(0);
+ expect(splitParallelDiff.diff_files[0].parallel_diff_lines.length).toBeGreaterThan(0);
+ expect(splitParallelDiff.diff_files[0].highlighted_diff_lines.length).toEqual(0);
+ });
- it('guarantees an empty array for both diff styles', () => {
- expect(splitInlineDiff.diff_files[0].parallel_diff_lines.length).toEqual(0);
- expect(splitInlineDiff.diff_files[0].highlighted_diff_lines.length).toBeGreaterThan(0);
- expect(splitParallelDiff.diff_files[0].parallel_diff_lines.length).toBeGreaterThan(0);
- expect(splitParallelDiff.diff_files[0].highlighted_diff_lines.length).toEqual(0);
- });
+ it('merges existing diff files with newly loaded diff files to ensure split diffs are eventually completed', () => {
+ expect(completedDiff.diff_files.length).toEqual(1);
+ expect(completedDiff.diff_files[0].parallel_diff_lines.length).toBeGreaterThan(0);
+ expect(completedDiff.diff_files[0].highlighted_diff_lines.length).toBeGreaterThan(0);
+ });
- it('merges existing diff files with newly loaded diff files to ensure split diffs are eventually completed', () => {
- expect(completedDiff.diff_files.length).toEqual(1);
- expect(completedDiff.diff_files[0].parallel_diff_lines.length).toBeGreaterThan(0);
- expect(completedDiff.diff_files[0].highlighted_diff_lines.length).toBeGreaterThan(0);
- });
+ it('leaves files in the existing state', () => {
+ const priorFiles = [mock];
+ const fakeNewFile = {
+ ...mock,
+ content_sha: 'ABC',
+ file_hash: 'DEF',
+ };
+ const updatedFilesList = utils.prepareDiffData({ diff_files: [fakeNewFile] }, priorFiles);
- it('leaves files in the existing state', () => {
- const priorFiles = [mock];
- const fakeNewFile = {
- ...mock,
- content_sha: 'ABC',
- file_hash: 'DEF',
- };
- const updatedFilesList = utils.prepareDiffData({ diff_files: [fakeNewFile] }, priorFiles);
+ expect(updatedFilesList).toEqual([mock, fakeNewFile]);
+ });
- expect(updatedFilesList).toEqual([mock, fakeNewFile]);
+ it('completes an existing split diff without overwriting existing diffs', () => {
+ // The current state has a file that has only loaded inline lines
+ const priorFiles = [{ ...mock, parallel_diff_lines: [] }];
+ // The next (batch) load loads two files: the other half of that file, and a new file
+ const fakeBatch = [
+ { ...mock, highlighted_diff_lines: undefined },
+ { ...mock, highlighted_diff_lines: undefined, content_sha: 'ABC', file_hash: 'DEF' },
+ ];
+ const updatedFilesList = utils.prepareDiffData({ diff_files: fakeBatch }, priorFiles);
+
+ expect(updatedFilesList).toEqual([
+ mock,
+ expect.objectContaining({
+ content_sha: 'ABC',
+ file_hash: 'DEF',
+ }),
+ ]);
+ });
});
- it('completes an existing split diff without overwriting existing diffs', () => {
- // The current state has a file that has only loaded inline lines
- const priorFiles = [{ ...mock, parallel_diff_lines: [] }];
- // The next (batch) load loads two files: the other half of that file, and a new file
- const fakeBatch = [
- { ...mock, highlighted_diff_lines: undefined },
- { ...mock, highlighted_diff_lines: undefined, content_sha: 'ABC', file_hash: 'DEF' },
- ];
- const updatedFilesList = utils.prepareDiffData({ diff_files: fakeBatch }, priorFiles);
+ describe('for diff metadata', () => {
+ let mock;
+ let preparedDiffFiles;
- expect(updatedFilesList).toEqual([
- mock,
- expect.objectContaining({
- content_sha: 'ABC',
- file_hash: 'DEF',
- }),
- ]);
+ beforeEach(() => {
+ mock = getDiffMetadataMock();
+
+ preparedDiffFiles = utils.prepareDiffData(mock);
+ });
+
+ it('sets the renderIt and collapsed attribute on files', () => {
+ expect(preparedDiffFiles[0].renderIt).toBeTruthy();
+ expect(preparedDiffFiles[0].collapsed).toBeFalsy();
+ });
+
+ it('guarantees an empty array of lines for both diff styles', () => {
+ expect(preparedDiffFiles[0].parallel_diff_lines.length).toEqual(0);
+ expect(preparedDiffFiles[0].highlighted_diff_lines.length).toEqual(0);
+ });
+
+ it('leaves files in the existing state', () => {
+ const fileMock = getDiffFileMock();
+ const metaData = getDiffMetadataMock();
+ const priorFiles = [fileMock];
+ const updatedFilesList = utils.prepareDiffData(metaData, priorFiles);
+
+ expect(updatedFilesList.length).toEqual(2);
+ expect(updatedFilesList[0]).toEqual(fileMock);
+ });
+
+ it('adds a new file to the file that already exists in state', () => {
+ // This is actually buggy behavior:
+ // Because the metadata doesn't include a content_sha,
+ // the de-duplicator in prepareDiffData doesn't realize it
+ // should combine these two.
+
+ // This buggy behavior hasn't caused a defect YET, because
+ // `diffs_metadata.json` is only called the first time the
+ // diffs app starts up, which is:
+ // - after a fresh page load
+ // - after you switch to the changes tab *the first time*
+
+ // This test should begin FAILING and can be reversed to check
+ // for just a single file when this is implemented:
+ // https://gitlab.com/groups/gitlab-org/-/epics/2852#note_304803233
+
+ const fileMock = getDiffFileMock();
+ const metaMock = getDiffMetadataMock();
+ const priorFiles = [{ ...fileMock }];
+ const updatedFilesList = utils.prepareDiffData(metaMock, priorFiles);
+
+ expect(updatedFilesList).toEqual([
+ fileMock,
+ {
+ ...metaMock.diff_files[0],
+ highlighted_diff_lines: [],
+ parallel_diff_lines: [],
+ },
+ ]);
+ });
});
});
diff --git a/spec/frontend/diffs/utils/uuids_spec.js b/spec/frontend/diffs/utils/uuids_spec.js
new file mode 100644
index 00000000000..79d3ebadd4f
--- /dev/null
+++ b/spec/frontend/diffs/utils/uuids_spec.js
@@ -0,0 +1,92 @@
+import { uuids } from '~/diffs/utils/uuids';
+
+const HEX = /[a-f0-9]/i;
+const HEX_RE = HEX.source;
+const UUIDV4 = new RegExp(
+ `${HEX_RE}{8}-${HEX_RE}{4}-4${HEX_RE}{3}-[89ab]${HEX_RE}{3}-${HEX_RE}{12}`,
+ 'i',
+);
+
+describe('UUIDs Util', () => {
+ describe('uuids', () => {
+ const SEQUENCE_FOR_GITLAB_SEED = [
+ 'a1826a44-316c-480e-a93d-8cdfeb36617c',
+ 'e049db1f-a4cf-4cba-aa60-6d95e3b547dc',
+ '6e3c737c-13a7-4380-b17d-601f187d7e69',
+ 'bee5cc7f-c486-45c0-8ad3-d1ac5402632d',
+ 'af248c9f-a3a6-4d4f-a311-fe151ffab25a',
+ ];
+ const SEQUENCE_FOR_12345_SEED = [
+ 'edfb51e2-e3e1-4de5-90fd-fd1d21760881',
+ '2f154da4-0a2d-4da9-b45e-0ffed391517e',
+ '91566d65-8836-4222-9875-9e1df4d0bb01',
+ 'f6ea6c76-7640-4d71-a736-9d3bec7a1a8e',
+ 'bfb85869-5fb9-4c5b-a750-5af727ac5576',
+ ];
+
+ it('returns version 4 UUIDs', () => {
+ expect(uuids()[0]).toMatch(UUIDV4);
+ });
+
+ it('outputs an array of UUIDs', () => {
+ const ids = uuids({ count: 11 });
+
+ expect(ids.length).toEqual(11);
+ expect(ids.every(id => UUIDV4.test(id))).toEqual(true);
+ });
+
+ it.each`
+ seeds | uuid
+ ${['some', 'special', 'seed']} | ${'6fa53e51-0f70-4072-9c84-1c1eee1b9934'}
+ ${['magic']} | ${'fafae8cd-7083-44f3-b82d-43b30bd27486'}
+ ${['seeded']} | ${'e06ed291-46c5-4e42-836b-e7c772d48b49'}
+ ${['GitLab']} | ${'a1826a44-316c-480e-a93d-8cdfeb36617c'}
+ ${['JavaScript']} | ${'12dfb297-1560-4c38-9775-7178ef8472fb'}
+ ${[99, 169834, 2619]} | ${'3ecc8ad6-5b7c-4c9b-94a8-c7271c2fa083'}
+ ${[12]} | ${'2777374b-723b-469b-bd73-e586df964cfd'}
+ ${[9876, 'mixed!', 7654]} | ${'865212e0-4a16-4934-96f9-103cf36a6931'}
+ ${[123, 1234, 12345, 6]} | ${'40aa2ee6-0a11-4e67-8f09-72f5eba04244'}
+ ${[0]} | ${'8c7f0aac-97c4-4a2f-b716-a675d821ccc0'}
+ `(
+ 'should always output the UUID $uuid when the options.seeds argument is $seeds',
+ ({ uuid, seeds }) => {
+ expect(uuids({ seeds })[0]).toEqual(uuid);
+ },
+ );
+
+ describe('unseeded UUID randomness', () => {
+ const nonRandom = Array(6)
+ .fill(0)
+ .map((_, i) => uuids({ seeds: [i] })[0]);
+ const random = uuids({ count: 6 });
+ const moreRandom = uuids({ count: 6 });
+
+ it('is different from a seeded result', () => {
+ random.forEach((id, i) => {
+ expect(id).not.toEqual(nonRandom[i]);
+ });
+ });
+
+ it('is different from other random results', () => {
+ random.forEach((id, i) => {
+ expect(id).not.toEqual(moreRandom[i]);
+ });
+ });
+
+ it('never produces any duplicates', () => {
+ expect(new Set(random).size).toEqual(random.length);
+ });
+ });
+
+ it.each`
+ seed | sequence
+ ${'GitLab'} | ${SEQUENCE_FOR_GITLAB_SEED}
+ ${12345} | ${SEQUENCE_FOR_12345_SEED}
+ `(
+ 'should output the same sequence of UUIDs for the given seed "$seed"',
+ ({ seed, sequence }) => {
+ expect(uuids({ seeds: [seed], count: 5 })).toEqual(sequence);
+ },
+ );
+ });
+});
diff --git a/spec/frontend/droplab/drop_down_spec.js b/spec/frontend/droplab/drop_down_spec.js
new file mode 100644
index 00000000000..d33d6bb70f1
--- /dev/null
+++ b/spec/frontend/droplab/drop_down_spec.js
@@ -0,0 +1,662 @@
+import DropDown from '~/droplab/drop_down';
+import utils from '~/droplab/utils';
+import { SELECTED_CLASS } from '~/droplab/constants';
+
+describe('DropLab DropDown', () => {
+ let testContext;
+
+ beforeEach(() => {
+ testContext = {};
+ });
+
+ describe('class constructor', () => {
+ beforeEach(() => {
+ jest.spyOn(DropDown.prototype, 'getItems').mockImplementation(() => {});
+ jest.spyOn(DropDown.prototype, 'initTemplateString').mockImplementation(() => {});
+ jest.spyOn(DropDown.prototype, 'addEvents').mockImplementation(() => {});
+
+ testContext.list = { innerHTML: 'innerHTML' };
+ testContext.dropdown = new DropDown(testContext.list);
+ });
+
+ it('sets the .hidden property to true', () => {
+ expect(testContext.dropdown.hidden).toBe(true);
+ });
+
+ it('sets the .list property', () => {
+ expect(testContext.dropdown.list).toBe(testContext.list);
+ });
+
+ it('calls .getItems', () => {
+ expect(DropDown.prototype.getItems).toHaveBeenCalled();
+ });
+
+ it('calls .initTemplateString', () => {
+ expect(DropDown.prototype.initTemplateString).toHaveBeenCalled();
+ });
+
+ it('calls .addEvents', () => {
+ expect(DropDown.prototype.addEvents).toHaveBeenCalled();
+ });
+
+ it('sets the .initialState property to the .list.innerHTML', () => {
+ expect(testContext.dropdown.initialState).toBe(testContext.list.innerHTML);
+ });
+
+ describe('if the list argument is a string', () => {
+ beforeEach(() => {
+ testContext.element = {};
+ testContext.selector = '.selector';
+
+ jest.spyOn(Document.prototype, 'querySelector').mockReturnValue(testContext.element);
+
+ testContext.dropdown = new DropDown(testContext.selector);
+ });
+
+ it('calls .querySelector with the selector string', () => {
+ expect(Document.prototype.querySelector).toHaveBeenCalledWith(testContext.selector);
+ });
+
+ it('sets the .list property element', () => {
+ expect(testContext.dropdown.list).toBe(testContext.element);
+ });
+ });
+ });
+
+ describe('getItems', () => {
+ beforeEach(() => {
+ testContext.list = { querySelectorAll: () => {} };
+ testContext.dropdown = { list: testContext.list };
+ testContext.nodeList = [];
+
+ jest.spyOn(testContext.list, 'querySelectorAll').mockReturnValue(testContext.nodeList);
+
+ testContext.getItems = DropDown.prototype.getItems.call(testContext.dropdown);
+ });
+
+ it('calls .querySelectorAll with a list item query', () => {
+ expect(testContext.list.querySelectorAll).toHaveBeenCalledWith('li');
+ });
+
+ it('sets the .items property to the returned list items', () => {
+ expect(testContext.dropdown.items).toEqual(expect.any(Array));
+ });
+
+ it('returns the .items', () => {
+ expect(testContext.getItems).toEqual(expect.any(Array));
+ });
+ });
+
+ describe('initTemplateString', () => {
+ beforeEach(() => {
+ testContext.items = [{ outerHTML: '<a></a>' }, { outerHTML: '<img>' }];
+ testContext.dropdown = { items: testContext.items };
+
+ DropDown.prototype.initTemplateString.call(testContext.dropdown);
+ });
+
+ it('should set .templateString to the last items .outerHTML', () => {
+ expect(testContext.dropdown.templateString).toBe(testContext.items[1].outerHTML);
+ });
+
+ it('should not set .templateString to a non-last items .outerHTML', () => {
+ expect(testContext.dropdown.templateString).not.toBe(testContext.items[0].outerHTML);
+ });
+
+ describe('if .items is not set', () => {
+ beforeEach(() => {
+ testContext.dropdown = { getItems: () => {} };
+
+ jest.spyOn(testContext.dropdown, 'getItems').mockReturnValue([]);
+
+ DropDown.prototype.initTemplateString.call(testContext.dropdown);
+ });
+
+ it('should call .getItems', () => {
+ expect(testContext.dropdown.getItems).toHaveBeenCalled();
+ });
+ });
+
+ describe('if items array is empty', () => {
+ beforeEach(() => {
+ testContext.dropdown = { items: [] };
+
+ DropDown.prototype.initTemplateString.call(testContext.dropdown);
+ });
+
+ it('should set .templateString to an empty string', () => {
+ expect(testContext.dropdown.templateString).toBe('');
+ });
+ });
+ });
+
+ describe('clickEvent', () => {
+ beforeEach(() => {
+ testContext.classList = {
+ contains: jest.fn(),
+ };
+ testContext.list = { dispatchEvent: () => {} };
+ testContext.dropdown = {
+ hideOnClick: true,
+ hide: () => {},
+ list: testContext.list,
+ addSelectedClass: () => {},
+ };
+ testContext.event = {
+ preventDefault: () => {},
+ target: {
+ classList: testContext.classList,
+ closest: () => null,
+ },
+ };
+
+ testContext.dummyListItem = document.createElement('li');
+ jest.spyOn(testContext.event.target, 'closest').mockImplementation(selector => {
+ if (selector === 'li') {
+ return testContext.dummyListItem;
+ }
+
+ return null;
+ });
+
+ jest.spyOn(testContext.dropdown, 'hide').mockImplementation(() => {});
+ jest.spyOn(testContext.dropdown, 'addSelectedClass').mockImplementation(() => {});
+ jest.spyOn(testContext.list, 'dispatchEvent').mockImplementation(() => {});
+ jest.spyOn(testContext.event, 'preventDefault').mockImplementation(() => {});
+ window.CustomEvent = jest.fn();
+ testContext.classList.contains.mockReturnValue(false);
+ });
+
+ describe('normal click event', () => {
+ beforeEach(() => {
+ DropDown.prototype.clickEvent.call(testContext.dropdown, testContext.event);
+ });
+ it('should call event.target.closest', () => {
+ expect(testContext.event.target.closest).toHaveBeenCalledWith('.droplab-item-ignore');
+ expect(testContext.event.target.closest).toHaveBeenCalledWith('li');
+ });
+
+ it('should call addSelectedClass', () => {
+ expect(testContext.dropdown.addSelectedClass).toHaveBeenCalledWith(
+ testContext.dummyListItem,
+ );
+ });
+
+ it('should call .preventDefault', () => {
+ expect(testContext.event.preventDefault).toHaveBeenCalled();
+ });
+
+ it('should call .hide', () => {
+ expect(testContext.dropdown.hide).toHaveBeenCalled();
+ });
+
+ it('should construct CustomEvent', () => {
+ expect(window.CustomEvent).toHaveBeenCalledWith('click.dl', expect.any(Object));
+ });
+
+ it('should call .dispatchEvent with the customEvent', () => {
+ expect(testContext.list.dispatchEvent).toHaveBeenCalledWith({});
+ });
+ });
+
+ describe('if the target is a UL element', () => {
+ beforeEach(() => {
+ testContext.event.target = document.createElement('ul');
+
+ jest.spyOn(testContext.event.target, 'closest').mockImplementation(() => {});
+ });
+
+ it('should return immediately', () => {
+ DropDown.prototype.clickEvent.call(testContext.dropdown, testContext.event);
+
+ expect(testContext.event.target.closest).not.toHaveBeenCalled();
+ expect(testContext.dropdown.addSelectedClass).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('if the target has the droplab-item-ignore class', () => {
+ beforeEach(() => {
+ testContext.ignoredButton = document.createElement('button');
+ testContext.ignoredButton.classList.add('droplab-item-ignore');
+ testContext.event.target = testContext.ignoredButton;
+
+ jest.spyOn(testContext.ignoredButton, 'closest');
+ });
+
+ it('does not select element', () => {
+ DropDown.prototype.clickEvent.call(testContext.dropdown, testContext.event);
+
+ expect(testContext.ignoredButton.closest.mock.calls.length).toBe(1);
+ expect(testContext.ignoredButton.closest).toHaveBeenCalledWith('.droplab-item-ignore');
+ expect(testContext.dropdown.addSelectedClass).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('if no selected element exists', () => {
+ beforeEach(() => {
+ testContext.event.preventDefault.mockReset();
+ testContext.dummyListItem = null;
+ });
+
+ it('should return before .preventDefault is called', () => {
+ DropDown.prototype.clickEvent.call(testContext.dropdown, testContext.event);
+
+ expect(testContext.event.preventDefault).not.toHaveBeenCalled();
+ expect(testContext.dropdown.addSelectedClass).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('if hideOnClick is false', () => {
+ beforeEach(() => {
+ testContext.dropdown.hideOnClick = false;
+ testContext.dropdown.hide.mockReset();
+ });
+
+ it('should not call .hide', () => {
+ DropDown.prototype.clickEvent.call(testContext.dropdown, testContext.event);
+
+ expect(testContext.dropdown.hide).not.toHaveBeenCalled();
+ });
+ });
+ });
+
+ describe('addSelectedClass', () => {
+ beforeEach(() => {
+ testContext.items = Array(4).forEach((item, i) => {
+ testContext.items[i] = { classList: { add: () => {} } };
+ jest.spyOn(testContext.items[i].classList, 'add').mockImplementation(() => {});
+ });
+ testContext.selected = { classList: { add: () => {} } };
+ testContext.dropdown = { removeSelectedClasses: () => {} };
+
+ jest.spyOn(testContext.dropdown, 'removeSelectedClasses').mockImplementation(() => {});
+ jest.spyOn(testContext.selected.classList, 'add').mockImplementation(() => {});
+
+ DropDown.prototype.addSelectedClass.call(testContext.dropdown, testContext.selected);
+ });
+
+ it('should call .removeSelectedClasses', () => {
+ expect(testContext.dropdown.removeSelectedClasses).toHaveBeenCalled();
+ });
+
+ it('should call .classList.add', () => {
+ expect(testContext.selected.classList.add).toHaveBeenCalledWith(SELECTED_CLASS);
+ });
+ });
+
+ describe('removeSelectedClasses', () => {
+ beforeEach(() => {
+ testContext.items = [...Array(4)];
+ testContext.items.forEach((item, i) => {
+ testContext.items[i] = { classList: { add: jest.fn(), remove: jest.fn() } };
+ });
+ testContext.dropdown = { items: testContext.items };
+
+ DropDown.prototype.removeSelectedClasses.call(testContext.dropdown);
+ });
+
+ it('should call .classList.remove for all items', () => {
+ testContext.items.forEach((_, i) => {
+ expect(testContext.items[i].classList.remove).toHaveBeenCalledWith(SELECTED_CLASS);
+ });
+ });
+
+ describe('if .items is not set', () => {
+ beforeEach(() => {
+ testContext.dropdown = { getItems: () => {} };
+
+ jest.spyOn(testContext.dropdown, 'getItems').mockReturnValue([]);
+
+ DropDown.prototype.removeSelectedClasses.call(testContext.dropdown);
+ });
+
+ it('should call .getItems', () => {
+ expect(testContext.dropdown.getItems).toHaveBeenCalled();
+ });
+ });
+ });
+
+ describe('addEvents', () => {
+ beforeEach(() => {
+ testContext.list = {
+ addEventListener: () => {},
+ querySelectorAll: () => [],
+ };
+ testContext.dropdown = {
+ list: testContext.list,
+ clickEvent: () => {},
+ closeDropdown: () => {},
+ eventWrapper: {},
+ };
+ });
+
+ it('should call .addEventListener', () => {
+ jest.spyOn(testContext.list, 'addEventListener').mockImplementation(() => {});
+
+ DropDown.prototype.addEvents.call(testContext.dropdown);
+
+ expect(testContext.list.addEventListener).toHaveBeenCalledWith('click', expect.any(Function));
+ expect(testContext.list.addEventListener).toHaveBeenCalledWith('keyup', expect.any(Function));
+ });
+ });
+
+ describe('setData', () => {
+ beforeEach(() => {
+ testContext.dropdown = { render: () => {} };
+ testContext.data = ['data'];
+
+ jest.spyOn(testContext.dropdown, 'render').mockImplementation(() => {});
+
+ DropDown.prototype.setData.call(testContext.dropdown, testContext.data);
+ });
+
+ it('should set .data', () => {
+ expect(testContext.dropdown.data).toBe(testContext.data);
+ });
+
+ it('should call .render with the .data', () => {
+ expect(testContext.dropdown.render).toHaveBeenCalledWith(testContext.data);
+ });
+ });
+
+ describe('addData', () => {
+ beforeEach(() => {
+ testContext.dropdown = { render: () => {}, data: ['data1'] };
+ testContext.data = ['data2'];
+
+ jest.spyOn(testContext.dropdown, 'render').mockImplementation(() => {});
+ jest.spyOn(Array.prototype, 'concat');
+
+ DropDown.prototype.addData.call(testContext.dropdown, testContext.data);
+ });
+
+ it('should call .concat with data', () => {
+ expect(Array.prototype.concat).toHaveBeenCalledWith(testContext.data);
+ });
+
+ it('should set .data with concatination', () => {
+ expect(testContext.dropdown.data).toStrictEqual(['data1', 'data2']);
+ });
+
+ it('should call .render with the .data', () => {
+ expect(testContext.dropdown.render).toHaveBeenCalledWith(['data1', 'data2']);
+ });
+
+ describe('if .data is undefined', () => {
+ beforeEach(() => {
+ testContext.dropdown = { render: () => {}, data: undefined };
+ testContext.data = ['data2'];
+
+ jest.spyOn(testContext.dropdown, 'render').mockImplementation(() => {});
+
+ DropDown.prototype.addData.call(testContext.dropdown, testContext.data);
+ });
+
+ it('should set .data with concatination', () => {
+ expect(testContext.dropdown.data).toStrictEqual(['data2']);
+ });
+ });
+ });
+
+ describe('render', () => {
+ beforeEach(() => {
+ testContext.renderableList = {};
+ testContext.list = {
+ querySelector: q => {
+ if (q === '.filter-dropdown-loading') {
+ return false;
+ }
+ return testContext.renderableList;
+ },
+ dispatchEvent: () => {},
+ };
+ testContext.dropdown = { renderChildren: () => {}, list: testContext.list };
+ testContext.data = [0, 1];
+ testContext.customEvent = {};
+
+ jest.spyOn(testContext.dropdown, 'renderChildren').mockImplementation(data => data);
+ jest.spyOn(testContext.list, 'dispatchEvent').mockImplementation(() => {});
+ jest.spyOn(testContext.data, 'map');
+ jest.spyOn(window, 'CustomEvent').mockReturnValue(testContext.customEvent);
+
+ DropDown.prototype.render.call(testContext.dropdown, testContext.data);
+ });
+
+ it('should call .map', () => {
+ expect(testContext.data.map).toHaveBeenCalledWith(expect.any(Function));
+ });
+
+ it('should call .renderChildren for each data item', () => {
+ expect(testContext.dropdown.renderChildren.mock.calls.length).toBe(testContext.data.length);
+ });
+
+ it('sets the renderableList .innerHTML', () => {
+ expect(testContext.renderableList.innerHTML).toBe('01');
+ });
+
+ it('should call render.dl', () => {
+ expect(window.CustomEvent).toHaveBeenCalledWith('render.dl', expect.any(Object));
+ });
+
+ it('should call dispatchEvent with the customEvent', () => {
+ expect(testContext.list.dispatchEvent).toHaveBeenCalledWith(testContext.customEvent);
+ });
+
+ describe('if no data argument is passed', () => {
+ beforeEach(() => {
+ testContext.data.map.mockReset();
+ testContext.dropdown.renderChildren.mockReset();
+
+ DropDown.prototype.render.call(testContext.dropdown, undefined);
+ });
+
+ it('should not call .map', () => {
+ expect(testContext.data.map).not.toHaveBeenCalled();
+ });
+
+ it('should not call .renderChildren', () => {
+ expect(testContext.dropdown.renderChildren).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('if no dynamic list is present', () => {
+ beforeEach(() => {
+ testContext.list = { querySelector: () => {}, dispatchEvent: () => {} };
+ testContext.dropdown = { renderChildren: () => {}, list: testContext.list };
+ testContext.data = [0, 1];
+
+ jest.spyOn(testContext.dropdown, 'renderChildren').mockImplementation(data => data);
+ jest.spyOn(testContext.list, 'querySelector').mockImplementation(() => {});
+ jest.spyOn(testContext.data, 'map');
+
+ DropDown.prototype.render.call(testContext.dropdown, testContext.data);
+ });
+
+ it('sets the .list .innerHTML', () => {
+ expect(testContext.list.innerHTML).toBe('01');
+ });
+ });
+ });
+
+ describe('renderChildren', () => {
+ beforeEach(() => {
+ testContext.templateString = 'templateString';
+ testContext.dropdown = { templateString: testContext.templateString };
+ testContext.data = { droplab_hidden: true };
+ testContext.html = 'html';
+ testContext.template = { firstChild: { outerHTML: 'outerHTML', style: {} } };
+
+ jest.spyOn(utils, 'template').mockReturnValue(testContext.html);
+ jest.spyOn(document, 'createElement').mockReturnValue(testContext.template);
+ jest.spyOn(DropDown, 'setImagesSrc').mockImplementation(() => {});
+
+ testContext.renderChildren = DropDown.prototype.renderChildren.call(
+ testContext.dropdown,
+ testContext.data,
+ );
+ });
+
+ it('should call utils.t with .templateString and data', () => {
+ expect(utils.template).toHaveBeenCalledWith(testContext.templateString, testContext.data);
+ });
+
+ it('should call document.createElement', () => {
+ expect(document.createElement).toHaveBeenCalledWith('div');
+ });
+
+ it('should set the templates .innerHTML to the HTML', () => {
+ expect(testContext.template.innerHTML).toBe(testContext.html);
+ });
+
+ it('should call .setImagesSrc with the template', () => {
+ expect(DropDown.setImagesSrc).toHaveBeenCalledWith(testContext.template);
+ });
+
+ it('should set the template display to none', () => {
+ expect(testContext.template.firstChild.style.display).toBe('none');
+ });
+
+ it('should return the templates .firstChild.outerHTML', () => {
+ expect(testContext.renderChildren).toBe(testContext.template.firstChild.outerHTML);
+ });
+
+ describe('if droplab_hidden is false', () => {
+ beforeEach(() => {
+ testContext.data = { droplab_hidden: false };
+ testContext.renderChildren = DropDown.prototype.renderChildren.call(
+ testContext.dropdown,
+ testContext.data,
+ );
+ });
+
+ it('should set the template display to block', () => {
+ expect(testContext.template.firstChild.style.display).toBe('block');
+ });
+ });
+ });
+
+ describe('setImagesSrc', () => {
+ beforeEach(() => {
+ testContext.template = { querySelectorAll: () => {} };
+
+ jest.spyOn(testContext.template, 'querySelectorAll').mockReturnValue([]);
+
+ DropDown.setImagesSrc(testContext.template);
+ });
+
+ it('should call .querySelectorAll', () => {
+ expect(testContext.template.querySelectorAll).toHaveBeenCalledWith('img[data-src]');
+ });
+ });
+
+ describe('show', () => {
+ beforeEach(() => {
+ testContext.list = { style: {} };
+ testContext.dropdown = { list: testContext.list, hidden: true };
+
+ DropDown.prototype.show.call(testContext.dropdown);
+ });
+
+ it('it should set .list display to block', () => {
+ expect(testContext.list.style.display).toBe('block');
+ });
+
+ it('it should set .hidden to false', () => {
+ expect(testContext.dropdown.hidden).toBe(false);
+ });
+
+ describe('if .hidden is false', () => {
+ beforeEach(() => {
+ testContext.list = { style: {} };
+ testContext.dropdown = { list: testContext.list, hidden: false };
+
+ testContext.show = DropDown.prototype.show.call(testContext.dropdown);
+ });
+
+ it('should return undefined', () => {
+ expect(testContext.show).toBeUndefined();
+ });
+
+ it('should not set .list display to block', () => {
+ expect(testContext.list.style.display).not.toBe('block');
+ });
+ });
+ });
+
+ describe('hide', () => {
+ beforeEach(() => {
+ testContext.list = { style: {} };
+ testContext.dropdown = { list: testContext.list };
+
+ DropDown.prototype.hide.call(testContext.dropdown);
+ });
+
+ it('it should set .list display to none', () => {
+ expect(testContext.list.style.display).toBe('none');
+ });
+
+ it('it should set .hidden to true', () => {
+ expect(testContext.dropdown.hidden).toBe(true);
+ });
+ });
+
+ describe('toggle', () => {
+ beforeEach(() => {
+ testContext.hidden = true;
+ testContext.dropdown = { hidden: testContext.hidden, show: () => {}, hide: () => {} };
+
+ jest.spyOn(testContext.dropdown, 'show').mockImplementation(() => {});
+ jest.spyOn(testContext.dropdown, 'hide').mockImplementation(() => {});
+
+ DropDown.prototype.toggle.call(testContext.dropdown);
+ });
+
+ it('should call .show', () => {
+ expect(testContext.dropdown.show).toHaveBeenCalled();
+ });
+
+ describe('if .hidden is false', () => {
+ beforeEach(() => {
+ testContext.hidden = false;
+ testContext.dropdown = { hidden: testContext.hidden, show: () => {}, hide: () => {} };
+
+ jest.spyOn(testContext.dropdown, 'show').mockImplementation(() => {});
+ jest.spyOn(testContext.dropdown, 'hide').mockImplementation(() => {});
+
+ DropDown.prototype.toggle.call(testContext.dropdown);
+ });
+
+ it('should call .hide', () => {
+ expect(testContext.dropdown.hide).toHaveBeenCalled();
+ });
+ });
+ });
+
+ describe('destroy', () => {
+ beforeEach(() => {
+ testContext.list = { removeEventListener: () => {} };
+ testContext.eventWrapper = { clickEvent: 'clickEvent' };
+ testContext.dropdown = {
+ list: testContext.list,
+ hide: () => {},
+ eventWrapper: testContext.eventWrapper,
+ };
+
+ jest.spyOn(testContext.list, 'removeEventListener').mockImplementation(() => {});
+ jest.spyOn(testContext.dropdown, 'hide').mockImplementation(() => {});
+
+ DropDown.prototype.destroy.call(testContext.dropdown);
+ });
+
+ it('it should call .hide', () => {
+ expect(testContext.dropdown.hide).toHaveBeenCalled();
+ });
+
+ it('it should call .removeEventListener', () => {
+ expect(testContext.list.removeEventListener).toHaveBeenCalledWith(
+ 'click',
+ testContext.eventWrapper.clickEvent,
+ );
+ });
+ });
+});
diff --git a/spec/frontend/droplab/hook_spec.js b/spec/frontend/droplab/hook_spec.js
new file mode 100644
index 00000000000..11488cab521
--- /dev/null
+++ b/spec/frontend/droplab/hook_spec.js
@@ -0,0 +1,94 @@
+import Hook from '~/droplab/hook';
+import DropDown from '~/droplab/drop_down';
+
+jest.mock('~/droplab/drop_down', () => jest.fn());
+
+describe('Hook', () => {
+ let testContext;
+
+ beforeEach(() => {
+ testContext = {};
+ });
+
+ describe('class constructor', () => {
+ beforeEach(() => {
+ testContext.trigger = { id: 'id' };
+ testContext.list = {};
+ testContext.plugins = {};
+ testContext.config = {};
+
+ testContext.hook = new Hook(
+ testContext.trigger,
+ testContext.list,
+ testContext.plugins,
+ testContext.config,
+ );
+ });
+
+ it('should set .trigger', () => {
+ expect(testContext.hook.trigger).toBe(testContext.trigger);
+ });
+
+ it('should set .list', () => {
+ expect(testContext.hook.list).toEqual({});
+ });
+
+ it('should call DropDown constructor', () => {
+ expect(DropDown).toHaveBeenCalledWith(testContext.list, testContext.config);
+ });
+
+ it('should set .type', () => {
+ expect(testContext.hook.type).toBe('Hook');
+ });
+
+ it('should set .event', () => {
+ expect(testContext.hook.event).toBe('click');
+ });
+
+ it('should set .plugins', () => {
+ expect(testContext.hook.plugins).toBe(testContext.plugins);
+ });
+
+ it('should set .config', () => {
+ expect(testContext.hook.config).toBe(testContext.config);
+ });
+
+ it('should set .id', () => {
+ expect(testContext.hook.id).toBe(testContext.trigger.id);
+ });
+
+ describe('if config argument is undefined', () => {
+ beforeEach(() => {
+ testContext.config = undefined;
+
+ testContext.hook = new Hook(
+ testContext.trigger,
+ testContext.list,
+ testContext.plugins,
+ testContext.config,
+ );
+ });
+
+ it('should set .config to an empty object', () => {
+ expect(testContext.hook.config).toEqual({});
+ });
+ });
+
+ describe('if plugins argument is undefined', () => {
+ beforeEach(() => {
+ testContext.plugins = undefined;
+
+ testContext.hook = new Hook(
+ testContext.trigger,
+ testContext.list,
+ testContext.plugins,
+ testContext.config,
+ );
+ });
+
+ it('should set .plugins to an empty array', () => {
+ expect(testContext.hook.plugins).toEqual([]);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/droplab/plugins/input_setter_spec.js b/spec/frontend/droplab/plugins/input_setter_spec.js
new file mode 100644
index 00000000000..eebde018fa1
--- /dev/null
+++ b/spec/frontend/droplab/plugins/input_setter_spec.js
@@ -0,0 +1,259 @@
+import InputSetter from '~/droplab/plugins/input_setter';
+
+describe('InputSetter', () => {
+ let testContext;
+
+ beforeEach(() => {
+ testContext = {};
+ });
+
+ describe('init', () => {
+ beforeEach(() => {
+ testContext.config = { InputSetter: {} };
+ testContext.hook = { config: testContext.config };
+ testContext.inputSetter = {
+ addEvents: jest.fn(),
+ };
+
+ InputSetter.init.call(testContext.inputSetter, testContext.hook);
+ });
+
+ it('should set .hook', () => {
+ expect(testContext.inputSetter.hook).toBe(testContext.hook);
+ });
+
+ it('should set .config', () => {
+ expect(testContext.inputSetter.config).toBe(testContext.config.InputSetter);
+ });
+
+ it('should set .eventWrapper', () => {
+ expect(testContext.inputSetter.eventWrapper).toEqual({});
+ });
+
+ it('should call .addEvents', () => {
+ expect(testContext.inputSetter.addEvents).toHaveBeenCalled();
+ });
+
+ describe('if config.InputSetter is not set', () => {
+ beforeEach(() => {
+ testContext.config = { InputSetter: undefined };
+ testContext.hook = { config: testContext.config };
+
+ InputSetter.init.call(testContext.inputSetter, testContext.hook);
+ });
+
+ it('should set .config to an empty object', () => {
+ expect(testContext.inputSetter.config).toEqual({});
+ });
+
+ it('should set hook.config to an empty object', () => {
+ expect(testContext.hook.config.InputSetter).toEqual({});
+ });
+ });
+ });
+
+ describe('addEvents', () => {
+ beforeEach(() => {
+ testContext.hook = {
+ list: {
+ list: {
+ addEventListener: jest.fn(),
+ },
+ },
+ };
+ testContext.inputSetter = { eventWrapper: {}, hook: testContext.hook, setInputs: () => {} };
+
+ InputSetter.addEvents.call(testContext.inputSetter);
+ });
+
+ it('should set .eventWrapper.setInputs', () => {
+ expect(testContext.inputSetter.eventWrapper.setInputs).toEqual(expect.any(Function));
+ });
+
+ it('should call .addEventListener', () => {
+ expect(testContext.hook.list.list.addEventListener).toHaveBeenCalledWith(
+ 'click.dl',
+ testContext.inputSetter.eventWrapper.setInputs,
+ );
+ });
+ });
+
+ describe('removeEvents', () => {
+ beforeEach(() => {
+ testContext.hook = {
+ list: {
+ list: {
+ removeEventListener: jest.fn(),
+ },
+ },
+ };
+ testContext.eventWrapper = {
+ setInputs: jest.fn(),
+ };
+ testContext.inputSetter = { eventWrapper: testContext.eventWrapper, hook: testContext.hook };
+
+ InputSetter.removeEvents.call(testContext.inputSetter);
+ });
+
+ it('should call .removeEventListener', () => {
+ expect(testContext.hook.list.list.removeEventListener).toHaveBeenCalledWith(
+ 'click.dl',
+ testContext.eventWrapper.setInputs,
+ );
+ });
+ });
+
+ describe('setInputs', () => {
+ beforeEach(() => {
+ testContext.event = { detail: { selected: {} } };
+ testContext.config = [0, 1];
+ testContext.inputSetter = { config: testContext.config, setInput: () => {} };
+
+ jest.spyOn(testContext.inputSetter, 'setInput').mockImplementation(() => {});
+
+ InputSetter.setInputs.call(testContext.inputSetter, testContext.event);
+ });
+
+ it('should call .setInput for each config element', () => {
+ const allArgs = testContext.inputSetter.setInput.mock.calls;
+
+ expect(allArgs.length).toEqual(2);
+
+ allArgs.forEach((args, i) => {
+ expect(args[0]).toBe(testContext.config[i]);
+ expect(args[1]).toBe(testContext.event.detail.selected);
+ });
+ });
+
+ describe('if config isnt an array', () => {
+ beforeEach(() => {
+ testContext.inputSetter = { config: {}, setInput: () => {} };
+
+ InputSetter.setInputs.call(testContext.inputSetter, testContext.event);
+ });
+
+ it('should set .config to an array with .config as the first element', () => {
+ expect(testContext.inputSetter.config).toEqual([{}]);
+ });
+ });
+ });
+
+ describe('setInput', () => {
+ beforeEach(() => {
+ testContext.selectedItem = { getAttribute: () => {} };
+ testContext.input = { value: 'oldValue', tagName: 'INPUT', hasAttribute: () => {} };
+ testContext.config = { valueAttribute: {}, input: testContext.input };
+ testContext.inputSetter = { hook: { trigger: {} } };
+ testContext.newValue = 'newValue';
+
+ jest.spyOn(testContext.selectedItem, 'getAttribute').mockReturnValue(testContext.newValue);
+ jest.spyOn(testContext.input, 'hasAttribute').mockReturnValue(false);
+
+ InputSetter.setInput.call(
+ testContext.inputSetter,
+ testContext.config,
+ testContext.selectedItem,
+ );
+ });
+
+ it('should call .getAttribute', () => {
+ expect(testContext.selectedItem.getAttribute).toHaveBeenCalledWith(
+ testContext.config.valueAttribute,
+ );
+ });
+
+ it('should call .hasAttribute', () => {
+ expect(testContext.input.hasAttribute).toHaveBeenCalledWith(undefined);
+ });
+
+ it('should set the value of the input', () => {
+ expect(testContext.input.value).toBe(testContext.newValue);
+ });
+
+ describe('if no config.input is provided', () => {
+ beforeEach(() => {
+ testContext.config = { valueAttribute: {} };
+ testContext.trigger = { value: 'oldValue', tagName: 'INPUT', hasAttribute: () => {} };
+ testContext.inputSetter = { hook: { trigger: testContext.trigger } };
+
+ InputSetter.setInput.call(
+ testContext.inputSetter,
+ testContext.config,
+ testContext.selectedItem,
+ );
+ });
+
+ it('should set the value of the hook.trigger', () => {
+ expect(testContext.trigger.value).toBe(testContext.newValue);
+ });
+ });
+
+ describe('if the input tag is not INPUT', () => {
+ beforeEach(() => {
+ testContext.input = { textContent: 'oldValue', tagName: 'SPAN', hasAttribute: () => {} };
+ testContext.config = { valueAttribute: {}, input: testContext.input };
+
+ InputSetter.setInput.call(
+ testContext.inputSetter,
+ testContext.config,
+ testContext.selectedItem,
+ );
+ });
+
+ it('should set the textContent of the input', () => {
+ expect(testContext.input.textContent).toBe(testContext.newValue);
+ });
+ });
+
+ describe('if there is an inputAttribute', () => {
+ beforeEach(() => {
+ testContext.selectedItem = { getAttribute: () => {} };
+ testContext.input = { id: 'oldValue', hasAttribute: () => {}, setAttribute: () => {} };
+ testContext.inputSetter = { hook: { trigger: {} } };
+ testContext.newValue = 'newValue';
+ testContext.inputAttribute = 'id';
+ testContext.config = {
+ valueAttribute: {},
+ input: testContext.input,
+ inputAttribute: testContext.inputAttribute,
+ };
+
+ jest.spyOn(testContext.selectedItem, 'getAttribute').mockReturnValue(testContext.newValue);
+ jest.spyOn(testContext.input, 'hasAttribute').mockReturnValue(true);
+ jest.spyOn(testContext.input, 'setAttribute').mockImplementation(() => {});
+
+ InputSetter.setInput.call(
+ testContext.inputSetter,
+ testContext.config,
+ testContext.selectedItem,
+ );
+ });
+
+ it('should call setAttribute', () => {
+ expect(testContext.input.setAttribute).toHaveBeenCalledWith(
+ testContext.inputAttribute,
+ testContext.newValue,
+ );
+ });
+
+ it('should not set the value or textContent of the input', () => {
+ expect(testContext.input.value).not.toBe('newValue');
+ expect(testContext.input.textContent).not.toBe('newValue');
+ });
+ });
+ });
+
+ describe('destroy', () => {
+ beforeEach(() => {
+ testContext.inputSetter = {
+ removeEvents: jest.fn(),
+ };
+
+ InputSetter.destroy.call(testContext.inputSetter);
+ });
+
+ it('should call .removeEvents', () => {
+ expect(testContext.inputSetter.removeEvents).toHaveBeenCalled();
+ });
+ });
+});
diff --git a/spec/frontend/dropzone_input_spec.js b/spec/frontend/dropzone_input_spec.js
new file mode 100644
index 00000000000..688b9164e5f
--- /dev/null
+++ b/spec/frontend/dropzone_input_spec.js
@@ -0,0 +1,97 @@
+import $ from 'jquery';
+import mock from 'xhr-mock';
+import { TEST_HOST } from 'spec/test_constants';
+import dropzoneInput from '~/dropzone_input';
+import PasteMarkdownTable from '~/behaviors/markdown/paste_markdown_table';
+import waitForPromises from 'helpers/wait_for_promises';
+
+const TEST_FILE = new File([], 'somefile.jpg');
+TEST_FILE.upload = {};
+
+const TEST_UPLOAD_PATH = `${TEST_HOST}/upload/file`;
+const TEST_ERROR_MESSAGE = 'A big error occurred!';
+const TEMPLATE = `<form class="gfm-form" data-uploads-path="${TEST_UPLOAD_PATH}">
+ <textarea class="js-gfm-input"></textarea>
+ <div class="uploading-error-message"></div>
+</form>`;
+
+describe('dropzone_input', () => {
+ it('returns null when failed to initialize', () => {
+ const dropzone = dropzoneInput($('<form class="gfm-form"></form>'));
+
+ expect(dropzone).toBeNull();
+ });
+
+ it('returns valid dropzone when successfully initialize', () => {
+ const dropzone = dropzoneInput($(TEMPLATE));
+
+ expect(dropzone.version).toBeTruthy();
+ });
+
+ describe('handlePaste', () => {
+ beforeEach(() => {
+ loadFixtures('issues/new-issue.html');
+
+ const form = $('#new_issue');
+ form.data('uploads-path', TEST_UPLOAD_PATH);
+ dropzoneInput(form);
+ });
+
+ it('pastes Markdown tables', () => {
+ const event = $.Event('paste');
+ const origEvent = new Event('paste');
+
+ origEvent.clipboardData = {
+ 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();
+ });
+ });
+
+ describe('shows error message', () => {
+ let form;
+ let dropzone;
+
+ beforeEach(() => {
+ mock.setup();
+
+ form = $(TEMPLATE);
+
+ dropzone = dropzoneInput(form);
+ });
+
+ afterEach(() => {
+ mock.teardown();
+ });
+
+ beforeEach(() => {});
+
+ it.each`
+ responseType | responseBody
+ ${'application/json'} | ${JSON.stringify({ message: TEST_ERROR_MESSAGE })}
+ ${'text/plain'} | ${TEST_ERROR_MESSAGE}
+ `('when AJAX fails with json', ({ responseType, responseBody }) => {
+ mock.post(TEST_UPLOAD_PATH, {
+ status: 400,
+ body: responseBody,
+ headers: { 'Content-Type': responseType },
+ });
+
+ dropzone.processFile(TEST_FILE);
+
+ return waitForPromises().then(() => {
+ expect(form.find('.uploading-error-message').text()).toEqual(TEST_ERROR_MESSAGE);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/environment.js b/spec/frontend/environment.js
index cd4fae60049..08da34aa27a 100644
--- a/spec/frontend/environment.js
+++ b/spec/frontend/environment.js
@@ -2,7 +2,7 @@
const path = require('path');
const { ErrorWithStack } = require('jest-util');
-const JSDOMEnvironment = require('jest-environment-jsdom');
+const JSDOMEnvironment = require('jest-environment-jsdom-sixteen');
const ROOT_PATH = path.resolve(__dirname, '../..');
diff --git a/spec/frontend/environments/environments_app_spec.js b/spec/frontend/environments/environments_app_spec.js
index f3d2bd2462e..c0bf0dca176 100644
--- a/spec/frontend/environments/environments_app_spec.js
+++ b/spec/frontend/environments/environments_app_spec.js
@@ -53,7 +53,7 @@ describe('Environment', () => {
describe('without environments', () => {
beforeEach(() => {
mockRequest(200, { environments: [] });
- return createWrapper(true);
+ return createWrapper();
});
it('should render the empty state', () => {
@@ -118,7 +118,7 @@ describe('Environment', () => {
describe('unsuccessful request', () => {
beforeEach(() => {
mockRequest(500, {});
- return createWrapper(true);
+ return createWrapper();
});
it('should render empty state', () => {
diff --git a/spec/frontend/error_tracking/components/error_details_spec.js b/spec/frontend/error_tracking/components/error_details_spec.js
index adbbc04ce78..fd2164d05fc 100644
--- a/spec/frontend/error_tracking/components/error_details_spec.js
+++ b/spec/frontend/error_tracking/components/error_details_spec.js
@@ -18,6 +18,12 @@ import {
severityLevelVariant,
errorStatus,
} from '~/error_tracking/components/constants';
+import Tracking from '~/tracking';
+import {
+ trackClickErrorLinkToSentryOptions,
+ trackErrorDetailsViewsOptions,
+ trackErrorStatusUpdateOptions,
+} from '~/error_tracking/utils';
jest.mock('~/flash');
@@ -30,12 +36,19 @@ describe('ErrorDetails', () => {
let actions;
let getters;
let mocks;
+ const externalUrl = 'https://sentry.io/organizations/test-sentry-nk/issues/1/?project=1';
const findInput = name => {
const inputs = wrapper.findAll(GlFormInput).filter(c => c.attributes('name') === name);
return inputs.length ? inputs.at(0) : inputs;
};
+ const findUpdateIgnoreStatusButton = () =>
+ wrapper.find('[data-testid="update-ignore-status-btn"]');
+ const findUpdateResolveStatusButton = () =>
+ wrapper.find('[data-testid="update-resolve-status-btn"]');
+ const findExternalUrl = () => wrapper.find('[data-testid="external-url-link"]');
+
function mountComponent() {
wrapper = shallowMount(ErrorDetails, {
stubs: { GlDeprecatedButton, GlSprintf },
@@ -57,7 +70,7 @@ describe('ErrorDetails', () => {
beforeEach(() => {
actions = {
startPollingStacktrace: () => {},
- updateIgnoreStatus: jest.fn(),
+ updateIgnoreStatus: jest.fn().mockResolvedValue({}),
updateResolveStatus: jest.fn().mockResolvedValue({ closed_issue_iid: 1 }),
};
@@ -170,6 +183,9 @@ describe('ErrorDetails', () => {
count: 12,
userCount: 2,
},
+ stacktraceData: {
+ date_received: '2020-05-20',
+ },
});
});
@@ -235,7 +251,7 @@ describe('ErrorDetails', () => {
},
});
return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.find(GlBadge).attributes('variant')).toEqual(
+ expect(wrapper.find(GlBadge).props('variant')).toEqual(
severityLevelVariant[severityLevel[level]],
);
});
@@ -249,7 +265,7 @@ describe('ErrorDetails', () => {
},
});
return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.find(GlBadge).attributes('variant')).toEqual(
+ expect(wrapper.find(GlBadge).props('variant')).toEqual(
severityLevelVariant[severityLevel.ERROR],
);
});
@@ -302,11 +318,6 @@ describe('ErrorDetails', () => {
});
describe('Status update', () => {
- const findUpdateIgnoreStatusButton = () =>
- wrapper.find('[data-qa-selector="update_ignore_status_button"]');
- const findUpdateResolveStatusButton = () =>
- wrapper.find('[data-qa-selector="update_resolve_status_button"]');
-
afterEach(() => {
actions.updateIgnoreStatus.mockClear();
actions.updateResolveStatus.mockClear();
@@ -491,4 +502,49 @@ describe('ErrorDetails', () => {
});
});
});
+
+ describe('Snowplow tracking', () => {
+ beforeEach(() => {
+ jest.spyOn(Tracking, 'event');
+ mocks.$apollo.queries.error.loading = false;
+ mountComponent();
+ wrapper.setData({
+ error: { externalUrl },
+ });
+ });
+
+ it('should track detail page views', () => {
+ const { category, action } = trackErrorDetailsViewsOptions;
+ expect(Tracking.event).toHaveBeenCalledWith(category, action);
+ });
+
+ it('should track IGNORE status update', () => {
+ Tracking.event.mockClear();
+ findUpdateIgnoreStatusButton().vm.$emit('click');
+ setImmediate(() => {
+ const { category, action } = trackErrorStatusUpdateOptions('ignored');
+ expect(Tracking.event).toHaveBeenCalledWith(category, action);
+ });
+ });
+
+ it('should track RESOLVE status update', () => {
+ Tracking.event.mockClear();
+ findUpdateResolveStatusButton().vm.$emit('click');
+ setImmediate(() => {
+ const { category, action } = trackErrorStatusUpdateOptions('resolved');
+ expect(Tracking.event).toHaveBeenCalledWith(category, action);
+ });
+ });
+
+ it('should track external Sentry link views', () => {
+ Tracking.event.mockClear();
+ findExternalUrl().trigger('click');
+ setImmediate(() => {
+ const { category, action, label, property } = trackClickErrorLinkToSentryOptions(
+ externalUrl,
+ );
+ expect(Tracking.event).toHaveBeenCalledWith(category, action, { label, property });
+ });
+ });
+ });
});
diff --git a/spec/frontend/error_tracking/components/error_tracking_list_spec.js b/spec/frontend/error_tracking/components/error_tracking_list_spec.js
index a6cb074f481..d88a412fb50 100644
--- a/spec/frontend/error_tracking/components/error_tracking_list_spec.js
+++ b/spec/frontend/error_tracking/components/error_tracking_list_spec.js
@@ -4,7 +4,9 @@ import { GlEmptyState, GlLoadingIcon, GlFormInput, GlPagination, GlDropdown } fr
import stubChildren from 'helpers/stub_children';
import ErrorTrackingList from '~/error_tracking/components/error_tracking_list.vue';
import ErrorTrackingActions from '~/error_tracking/components/error_tracking_actions.vue';
+import { trackErrorListViewsOptions, trackErrorStatusUpdateOptions } from '~/error_tracking/utils';
import errorsList from './list_mock.json';
+import Tracking from '~/tracking';
const localVue = createLocalVue();
localVue.use(Vuex);
@@ -460,4 +462,38 @@ describe('ErrorTrackingList', () => {
});
});
});
+
+ describe('Snowplow tracking', () => {
+ beforeEach(() => {
+ jest.spyOn(Tracking, 'event');
+ store.state.list.loading = false;
+ store.state.list.errors = errorsList;
+ mountComponent({
+ stubs: {
+ GlTable: false,
+ GlLink: false,
+ GlDeprecatedButton: false,
+ },
+ });
+ });
+
+ it('should track list views', () => {
+ const { category, action } = trackErrorListViewsOptions;
+ expect(Tracking.event).toHaveBeenCalledWith(category, action);
+ });
+
+ it('should track status updates', () => {
+ Tracking.event.mockClear();
+ const status = 'ignored';
+ findErrorActions().vm.$emit('update-issue-status', {
+ errorId: 1,
+ status,
+ });
+
+ setImmediate(() => {
+ const { category, action } = trackErrorStatusUpdateOptions(status);
+ expect(Tracking.event).toHaveBeenCalledWith(category, action);
+ });
+ });
+ });
});
diff --git a/spec/frontend/filtered_search/filtered_search_dropdown_manager_spec.js b/spec/frontend/filtered_search/filtered_search_dropdown_manager_spec.js
new file mode 100644
index 00000000000..e9ee69ca163
--- /dev/null
+++ b/spec/frontend/filtered_search/filtered_search_dropdown_manager_spec.js
@@ -0,0 +1,130 @@
+import axios from 'axios';
+import MockAdapter from 'axios-mock-adapter';
+import FilteredSearchDropdownManager from '~/filtered_search/filtered_search_dropdown_manager';
+
+describe('Filtered Search Dropdown Manager', () => {
+ let mock;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ mock.onGet().reply(200);
+ });
+
+ describe('addWordToInput', () => {
+ function getInputValue() {
+ return document.querySelector('.filtered-search').value;
+ }
+
+ function setInputValue(value) {
+ document.querySelector('.filtered-search').value = value;
+ }
+
+ beforeEach(() => {
+ setFixtures(`
+ <ul class="tokens-container">
+ <li class="input-token">
+ <input class="filtered-search">
+ </li>
+ </ul>
+ `);
+ });
+
+ describe('input has no existing value', () => {
+ it('should add just tokenName', () => {
+ FilteredSearchDropdownManager.addWordToInput({ tokenName: 'milestone' });
+
+ const token = document.querySelector('.tokens-container .js-visual-token');
+
+ expect(token.classList.contains('filtered-search-token')).toEqual(true);
+ expect(token.querySelector('.name').textContent).toBe('milestone');
+ expect(getInputValue()).toBe('');
+ });
+
+ it('should add tokenName, tokenOperator, and tokenValue', () => {
+ FilteredSearchDropdownManager.addWordToInput({ tokenName: 'label' });
+
+ let token = document.querySelector('.tokens-container .js-visual-token');
+
+ expect(token.classList.contains('filtered-search-token')).toEqual(true);
+ expect(token.querySelector('.name').textContent).toBe('label');
+ expect(getInputValue()).toBe('');
+
+ FilteredSearchDropdownManager.addWordToInput({ tokenName: 'label', tokenOperator: '=' });
+
+ token = document.querySelector('.tokens-container .js-visual-token');
+
+ expect(token.classList.contains('filtered-search-token')).toEqual(true);
+ expect(token.querySelector('.name').textContent).toBe('label');
+ expect(token.querySelector('.operator').textContent).toBe('=');
+ expect(getInputValue()).toBe('');
+
+ FilteredSearchDropdownManager.addWordToInput({
+ tokenName: 'label',
+ tokenOperator: '=',
+ tokenValue: 'none',
+ });
+ // We have to get that reference again
+ // Because FilteredSearchDropdownManager deletes the previous token
+ token = document.querySelector('.tokens-container .js-visual-token');
+
+ expect(token.classList.contains('filtered-search-token')).toEqual(true);
+ expect(token.querySelector('.name').textContent).toBe('label');
+ expect(token.querySelector('.operator').textContent).toBe('=');
+ expect(token.querySelector('.value').textContent).toBe('none');
+ expect(getInputValue()).toBe('');
+ });
+ });
+
+ describe('input has existing value', () => {
+ it('should be able to just add tokenName', () => {
+ setInputValue('a');
+ FilteredSearchDropdownManager.addWordToInput({ tokenName: 'author' });
+
+ const token = document.querySelector('.tokens-container .js-visual-token');
+
+ expect(token.classList.contains('filtered-search-token')).toEqual(true);
+ expect(token.querySelector('.name').textContent).toBe('author');
+ expect(getInputValue()).toBe('');
+ });
+
+ it('should replace tokenValue', () => {
+ FilteredSearchDropdownManager.addWordToInput({ tokenName: 'author' });
+ FilteredSearchDropdownManager.addWordToInput({ tokenName: 'author', tokenOperator: '=' });
+
+ setInputValue('roo');
+ FilteredSearchDropdownManager.addWordToInput({
+ tokenName: null,
+ tokenOperator: '=',
+ tokenValue: '@root',
+ });
+
+ const token = document.querySelector('.tokens-container .js-visual-token');
+
+ expect(token.classList.contains('filtered-search-token')).toEqual(true);
+ expect(token.querySelector('.name').textContent).toBe('author');
+ expect(token.querySelector('.operator').textContent).toBe('=');
+ expect(token.querySelector('.value').textContent).toBe('@root');
+ expect(getInputValue()).toBe('');
+ });
+
+ it('should add tokenValues containing spaces', () => {
+ FilteredSearchDropdownManager.addWordToInput({ tokenName: 'label' });
+
+ setInputValue('"test ');
+ FilteredSearchDropdownManager.addWordToInput({
+ tokenName: 'label',
+ tokenOperator: '=',
+ tokenValue: '~\'"test me"\'',
+ });
+
+ const token = document.querySelector('.tokens-container .js-visual-token');
+
+ expect(token.classList.contains('filtered-search-token')).toEqual(true);
+ expect(token.querySelector('.name').textContent).toBe('label');
+ expect(token.querySelector('.operator').textContent).toBe('=');
+ expect(token.querySelector('.value').textContent).toBe('~\'"test me"\'');
+ expect(getInputValue()).toBe('');
+ });
+ });
+ });
+});
diff --git a/spec/frontend/filtered_search/filtered_search_visual_tokens_spec.js b/spec/frontend/filtered_search/filtered_search_visual_tokens_spec.js
new file mode 100644
index 00000000000..e59ee925cc7
--- /dev/null
+++ b/spec/frontend/filtered_search/filtered_search_visual_tokens_spec.js
@@ -0,0 +1,732 @@
+import axios from 'axios';
+import MockAdapter from 'axios-mock-adapter';
+import FilteredSearchVisualTokens from '~/filtered_search/filtered_search_visual_tokens';
+import FilteredSearchSpecHelper from '../helpers/filtered_search_spec_helper';
+
+describe('Filtered Search Visual Tokens', () => {
+ let mock;
+ const subject = FilteredSearchVisualTokens;
+
+ const findElements = tokenElement => {
+ const tokenNameElement = tokenElement.querySelector('.name');
+ const tokenOperatorElement = tokenElement.querySelector('.operator');
+ const tokenValueContainer = tokenElement.querySelector('.value-container');
+ const tokenValueElement = tokenValueContainer.querySelector('.value');
+ return { tokenNameElement, tokenOperatorElement, tokenValueContainer, tokenValueElement };
+ };
+
+ let tokensContainer;
+ let authorToken;
+ let bugLabelToken;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ mock.onGet().reply(200);
+
+ setFixtures(`
+ <ul class="tokens-container">
+ ${FilteredSearchSpecHelper.createInputHTML()}
+ </ul>
+ `);
+ tokensContainer = document.querySelector('.tokens-container');
+
+ authorToken = FilteredSearchSpecHelper.createFilterVisualToken('author', '=', '@user');
+ bugLabelToken = FilteredSearchSpecHelper.createFilterVisualToken('label', '=', '~bug');
+ });
+
+ describe('getLastVisualTokenBeforeInput', () => {
+ it('returns when there are no visual tokens', () => {
+ const { lastVisualToken, isLastVisualTokenValid } = subject.getLastVisualTokenBeforeInput();
+
+ expect(lastVisualToken).toEqual(null);
+ expect(isLastVisualTokenValid).toEqual(true);
+ });
+
+ describe('input is the last item in tokensContainer', () => {
+ it('returns when there is one visual token', () => {
+ tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
+ bugLabelToken.outerHTML,
+ );
+
+ const { lastVisualToken, isLastVisualTokenValid } = subject.getLastVisualTokenBeforeInput();
+
+ expect(lastVisualToken).toEqual(document.querySelector('.filtered-search-token'));
+ expect(isLastVisualTokenValid).toEqual(true);
+ });
+
+ it('returns when there is an incomplete visual token', () => {
+ tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
+ FilteredSearchSpecHelper.createNameFilterVisualTokenHTML('Author'),
+ );
+
+ const { lastVisualToken, isLastVisualTokenValid } = subject.getLastVisualTokenBeforeInput();
+
+ expect(lastVisualToken).toEqual(document.querySelector('.filtered-search-token'));
+ expect(isLastVisualTokenValid).toEqual(false);
+ });
+
+ it('returns when there are multiple visual tokens', () => {
+ tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(`
+ ${bugLabelToken.outerHTML}
+ ${FilteredSearchSpecHelper.createSearchVisualTokenHTML('search term')}
+ ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('author', '=', '@root')}
+ `);
+
+ const { lastVisualToken, isLastVisualTokenValid } = subject.getLastVisualTokenBeforeInput();
+ const items = document.querySelectorAll('.tokens-container .js-visual-token');
+
+ expect(lastVisualToken.isEqualNode(items[items.length - 1])).toEqual(true);
+ expect(isLastVisualTokenValid).toEqual(true);
+ });
+
+ it('returns when there are multiple visual tokens and an incomplete visual token', () => {
+ tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(`
+ ${bugLabelToken.outerHTML}
+ ${FilteredSearchSpecHelper.createSearchVisualTokenHTML('search term')}
+ ${FilteredSearchSpecHelper.createNameFilterVisualTokenHTML('assignee')}
+ `);
+
+ const { lastVisualToken, isLastVisualTokenValid } = subject.getLastVisualTokenBeforeInput();
+ const items = document.querySelectorAll('.tokens-container .js-visual-token');
+
+ expect(lastVisualToken.isEqualNode(items[items.length - 1])).toEqual(true);
+ expect(isLastVisualTokenValid).toEqual(false);
+ });
+ });
+
+ describe('input is a middle item in tokensContainer', () => {
+ it('returns last token before input', () => {
+ tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(`
+ ${bugLabelToken.outerHTML}
+ ${FilteredSearchSpecHelper.createInputHTML()}
+ ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('author', '=', '@root')}
+ `);
+
+ const { lastVisualToken, isLastVisualTokenValid } = subject.getLastVisualTokenBeforeInput();
+
+ expect(lastVisualToken).toEqual(document.querySelector('.filtered-search-token'));
+ expect(isLastVisualTokenValid).toEqual(true);
+ });
+
+ it('returns last partial token before input', () => {
+ tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(`
+ ${FilteredSearchSpecHelper.createNameFilterVisualTokenHTML('label')}
+ ${FilteredSearchSpecHelper.createInputHTML()}
+ ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('author', '=', '@root')}
+ `);
+
+ const { lastVisualToken, isLastVisualTokenValid } = subject.getLastVisualTokenBeforeInput();
+
+ expect(lastVisualToken).toEqual(document.querySelector('.filtered-search-token'));
+ expect(isLastVisualTokenValid).toEqual(false);
+ });
+ });
+ });
+
+ describe('getEndpointWithQueryParams', () => {
+ it('returns `endpoint` string as is when second param `endpointQueryParams` is undefined, null or empty string', () => {
+ const endpoint = 'foo/bar/-/labels.json';
+
+ expect(subject.getEndpointWithQueryParams(endpoint)).toBe(endpoint);
+ expect(subject.getEndpointWithQueryParams(endpoint, null)).toBe(endpoint);
+ expect(subject.getEndpointWithQueryParams(endpoint, '')).toBe(endpoint);
+ });
+
+ it('returns `endpoint` string with values of `endpointQueryParams`', () => {
+ const endpoint = 'foo/bar/-/labels.json';
+ const singleQueryParams = '{"foo":"true"}';
+ const multipleQueryParams = '{"foo":"true","bar":"true"}';
+
+ expect(subject.getEndpointWithQueryParams(endpoint, singleQueryParams)).toBe(
+ `${endpoint}?foo=true`,
+ );
+
+ expect(subject.getEndpointWithQueryParams(endpoint, multipleQueryParams)).toBe(
+ `${endpoint}?foo=true&bar=true`,
+ );
+ });
+ });
+
+ describe('unselectTokens', () => {
+ it('does nothing when there are no tokens', () => {
+ const beforeHTML = tokensContainer.innerHTML;
+ subject.unselectTokens();
+
+ expect(tokensContainer.innerHTML).toEqual(beforeHTML);
+ });
+
+ it('removes the selected class from buttons', () => {
+ tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(`
+ ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('author', '=', '@author')}
+ ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('milestone', '=', '%123', true)}
+ `);
+
+ const selected = tokensContainer.querySelector('.js-visual-token .selected');
+
+ expect(selected.classList.contains('selected')).toEqual(true);
+
+ subject.unselectTokens();
+
+ expect(selected.classList.contains('selected')).toEqual(false);
+ });
+ });
+
+ describe('selectToken', () => {
+ beforeEach(() => {
+ tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(`
+ ${bugLabelToken.outerHTML}
+ ${FilteredSearchSpecHelper.createSearchVisualTokenHTML('search term')}
+ ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('label', '=', '~awesome')}
+ `);
+ });
+
+ it('removes the selected class if it has selected class', () => {
+ const firstTokenButton = tokensContainer.querySelector('.js-visual-token .selectable');
+ firstTokenButton.classList.add('selected');
+
+ subject.selectToken(firstTokenButton);
+
+ expect(firstTokenButton.classList.contains('selected')).toEqual(false);
+ });
+
+ describe('has no selected class', () => {
+ it('adds selected class', () => {
+ const firstTokenButton = tokensContainer.querySelector('.js-visual-token .selectable');
+
+ subject.selectToken(firstTokenButton);
+
+ expect(firstTokenButton.classList.contains('selected')).toEqual(true);
+ });
+
+ it('removes selected class from other tokens', () => {
+ const tokenButtons = tokensContainer.querySelectorAll('.js-visual-token .selectable');
+ tokenButtons[1].classList.add('selected');
+
+ subject.selectToken(tokenButtons[0]);
+
+ expect(tokenButtons[0].classList.contains('selected')).toEqual(true);
+ expect(tokenButtons[1].classList.contains('selected')).toEqual(false);
+ });
+ });
+ });
+
+ describe('removeSelectedToken', () => {
+ it('does not remove when there are no selected tokens', () => {
+ tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
+ FilteredSearchSpecHelper.createFilterVisualTokenHTML('milestone', '=', 'none'),
+ );
+
+ expect(tokensContainer.querySelector('.js-visual-token .selectable')).not.toEqual(null);
+
+ subject.removeSelectedToken();
+
+ expect(tokensContainer.querySelector('.js-visual-token .selectable')).not.toEqual(null);
+ });
+
+ it('removes selected token', () => {
+ tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
+ FilteredSearchSpecHelper.createFilterVisualTokenHTML('milestone', '=', 'none', true),
+ );
+
+ expect(tokensContainer.querySelector('.js-visual-token .selectable')).not.toEqual(null);
+
+ subject.removeSelectedToken();
+
+ expect(tokensContainer.querySelector('.js-visual-token .selectable')).toEqual(null);
+ });
+ });
+
+ describe('createVisualTokenElementHTML', () => {
+ let tokenElement;
+
+ beforeEach(() => {
+ setFixtures(`
+ <div class="test-area">
+ ${subject.createVisualTokenElementHTML('custom-token')}
+ </div>
+ `);
+
+ tokenElement = document.querySelector('.test-area').firstElementChild;
+ });
+
+ it('should add class name to token element', () => {
+ expect(document.querySelector('.test-area .custom-token')).toBeDefined();
+ });
+
+ it('contains name div', () => {
+ expect(tokenElement.querySelector('.name')).toEqual(expect.anything());
+ });
+
+ it('contains value container div', () => {
+ expect(tokenElement.querySelector('.value-container')).toEqual(expect.anything());
+ });
+
+ it('contains value div', () => {
+ expect(tokenElement.querySelector('.value-container .value')).toEqual(expect.anything());
+ });
+
+ it('contains selectable class', () => {
+ expect(tokenElement.classList.contains('selectable')).toEqual(true);
+ });
+
+ it('contains button role', () => {
+ expect(tokenElement.getAttribute('role')).toEqual('button');
+ });
+
+ describe('remove token', () => {
+ it('contains remove-token button', () => {
+ expect(tokenElement.querySelector('.value-container .remove-token')).toEqual(
+ expect.anything(),
+ );
+ });
+
+ it('contains fa-close icon', () => {
+ expect(tokenElement.querySelector('.remove-token .fa-close')).toEqual(expect.anything());
+ });
+ });
+ });
+
+ describe('addVisualTokenElement', () => {
+ it('renders search visual tokens', () => {
+ subject.addVisualTokenElement({
+ name: 'search term',
+ operator: '=',
+ value: null,
+ options: { isSearchTerm: true },
+ });
+ const token = tokensContainer.querySelector('.js-visual-token');
+
+ expect(token.classList.contains('filtered-search-term')).toEqual(true);
+ expect(token.querySelector('.name').innerText).toEqual('search term');
+ expect(token.querySelector('.operator').innerText).toEqual('=');
+ expect(token.querySelector('.value')).toEqual(null);
+ });
+
+ it('renders filter visual token name', () => {
+ subject.addVisualTokenElement({ name: 'milestone' });
+ const token = tokensContainer.querySelector('.js-visual-token');
+
+ expect(token.classList.contains('search-token-milestone')).toEqual(true);
+ expect(token.classList.contains('filtered-search-token')).toEqual(true);
+ expect(token.querySelector('.name').innerText).toEqual('milestone');
+ expect(token.querySelector('.value')).toEqual(null);
+ });
+
+ it('renders filter visual token name, operator, and value', () => {
+ subject.addVisualTokenElement({ name: 'label', operator: '!=', value: 'Frontend' });
+ const token = tokensContainer.querySelector('.js-visual-token');
+
+ expect(token.classList.contains('search-token-label')).toEqual(true);
+ expect(token.classList.contains('filtered-search-token')).toEqual(true);
+ expect(token.querySelector('.name').innerText).toEqual('label');
+ expect(token.querySelector('.operator').innerText).toEqual('!=');
+ expect(token.querySelector('.value').innerText).toEqual('Frontend');
+ });
+
+ it('inserts visual token before input', () => {
+ tokensContainer.appendChild(
+ FilteredSearchSpecHelper.createFilterVisualToken('assignee', '=', '@root'),
+ );
+
+ subject.addVisualTokenElement({ name: 'label', operator: '!=', value: 'Frontend' });
+ const tokens = tokensContainer.querySelectorAll('.js-visual-token');
+ const labelToken = tokens[0];
+ const assigneeToken = tokens[1];
+
+ expect(labelToken.classList.contains('search-token-label')).toEqual(true);
+ expect(labelToken.classList.contains('filtered-search-token')).toEqual(true);
+ expect(labelToken.querySelector('.name').innerText).toEqual('label');
+ expect(labelToken.querySelector('.value').innerText).toEqual('Frontend');
+ expect(labelToken.querySelector('.operator').innerText).toEqual('!=');
+
+ expect(assigneeToken.classList.contains('search-token-assignee')).toEqual(true);
+ expect(assigneeToken.classList.contains('filtered-search-token')).toEqual(true);
+ expect(assigneeToken.querySelector('.name').innerText).toEqual('assignee');
+ expect(assigneeToken.querySelector('.value').innerText).toEqual('@root');
+ expect(assigneeToken.querySelector('.operator').innerText).toEqual('=');
+ });
+ });
+
+ describe('addValueToPreviousVisualTokenElement', () => {
+ it('does not add when previous visual token element has no value', () => {
+ tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
+ FilteredSearchSpecHelper.createFilterVisualTokenHTML('author', '=', '@root'),
+ );
+
+ const original = tokensContainer.innerHTML;
+ subject.addValueToPreviousVisualTokenElement('value');
+
+ expect(original).toEqual(tokensContainer.innerHTML);
+ });
+
+ it('does not add when previous visual token element is a search', () => {
+ tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(`
+ ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('author', '=', '@root')}
+ ${FilteredSearchSpecHelper.createSearchVisualTokenHTML('search term')}
+ `);
+
+ const original = tokensContainer.innerHTML;
+ subject.addValueToPreviousVisualTokenElement('value');
+
+ expect(original).toEqual(tokensContainer.innerHTML);
+ });
+
+ it('adds value to previous visual filter token', () => {
+ tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
+ FilteredSearchSpecHelper.createNameOperatorFilterVisualTokenHTML('label', '='),
+ );
+
+ const original = tokensContainer.innerHTML;
+ subject.addValueToPreviousVisualTokenElement('value');
+ const updatedToken = tokensContainer.querySelector('.js-visual-token');
+
+ expect(updatedToken.querySelector('.name').innerText).toEqual('label');
+ expect(updatedToken.querySelector('.value').innerText).toEqual('value');
+ expect(original).not.toEqual(tokensContainer.innerHTML);
+ });
+ });
+
+ describe('addFilterVisualToken', () => {
+ it('creates visual token with just tokenName', () => {
+ subject.addFilterVisualToken('milestone');
+ const token = tokensContainer.querySelector('.js-visual-token');
+
+ expect(token.classList.contains('filtered-search-token')).toEqual(true);
+ expect(token.querySelector('.name').innerText).toEqual('milestone');
+ expect(token.querySelector('.operator')).toEqual(null);
+ expect(token.querySelector('.value')).toEqual(null);
+ });
+
+ it('creates visual token with just tokenValue', () => {
+ subject.addFilterVisualToken('milestone', '=');
+ subject.addFilterVisualToken('%8.17');
+ const token = tokensContainer.querySelector('.js-visual-token');
+
+ expect(token.classList.contains('filtered-search-token')).toEqual(true);
+ expect(token.querySelector('.name').innerText).toEqual('milestone');
+ expect(token.querySelector('.operator').innerText).toEqual('=');
+ expect(token.querySelector('.value').innerText).toEqual('%8.17');
+ });
+
+ it('creates full visual token', () => {
+ subject.addFilterVisualToken('assignee', '=', '@john');
+ const token = tokensContainer.querySelector('.js-visual-token');
+
+ expect(token.classList.contains('filtered-search-token')).toEqual(true);
+ expect(token.querySelector('.name').innerText).toEqual('assignee');
+ expect(token.querySelector('.operator').innerText).toEqual('=');
+ expect(token.querySelector('.value').innerText).toEqual('@john');
+ });
+ });
+
+ describe('addSearchVisualToken', () => {
+ it('creates search visual token', () => {
+ subject.addSearchVisualToken('search term');
+ const token = tokensContainer.querySelector('.js-visual-token');
+
+ expect(token.classList.contains('filtered-search-term')).toEqual(true);
+ expect(token.querySelector('.name').innerText).toEqual('search term');
+ expect(token.querySelector('.value')).toEqual(null);
+ });
+
+ it('appends to previous search visual token if previous token was a search token', () => {
+ tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(`
+ ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('author', '=', '@root')}
+ ${FilteredSearchSpecHelper.createSearchVisualTokenHTML('search term')}
+ `);
+
+ subject.addSearchVisualToken('append this');
+ const token = tokensContainer.querySelector('.filtered-search-term');
+
+ expect(token.querySelector('.name').innerText).toEqual('search term append this');
+ expect(token.querySelector('.value')).toEqual(null);
+ });
+ });
+
+ describe('getLastTokenPartial', () => {
+ it('should get last token value', () => {
+ const value = '~bug';
+ tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
+ bugLabelToken.outerHTML,
+ );
+
+ expect(subject.getLastTokenPartial()).toEqual(value);
+ });
+
+ it('should get last token original value if available', () => {
+ const originalValue = '@user';
+ const valueContainer = authorToken.querySelector('.value-container');
+ valueContainer.dataset.originalValue = originalValue;
+ const avatar = document.createElement('img');
+ const valueElement = valueContainer.querySelector('.value');
+ valueElement.appendChild(avatar);
+ tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
+ authorToken.outerHTML,
+ );
+
+ const lastTokenValue = subject.getLastTokenPartial();
+
+ expect(lastTokenValue).toEqual(originalValue);
+ });
+
+ it('should get last token name if there is no value', () => {
+ const name = 'assignee';
+ tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
+ FilteredSearchSpecHelper.createNameFilterVisualTokenHTML(name),
+ );
+
+ expect(subject.getLastTokenPartial()).toEqual(name);
+ });
+
+ it('should return empty when there are no tokens', () => {
+ expect(subject.getLastTokenPartial()).toEqual('');
+ });
+ });
+
+ describe('removeLastTokenPartial', () => {
+ it('should remove the last token value if it exists', () => {
+ tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
+ FilteredSearchSpecHelper.createFilterVisualTokenHTML(
+ 'label',
+ '=',
+ '~"Community Contribution"',
+ ),
+ );
+
+ expect(tokensContainer.querySelector('.js-visual-token .value')).not.toEqual(null);
+
+ subject.removeLastTokenPartial();
+
+ expect(tokensContainer.querySelector('.js-visual-token .value')).toEqual(null);
+ });
+
+ it('should remove the last token name if there is no value', () => {
+ tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
+ FilteredSearchSpecHelper.createNameFilterVisualTokenHTML('milestone'),
+ );
+
+ expect(tokensContainer.querySelector('.js-visual-token .name')).not.toEqual(null);
+
+ subject.removeLastTokenPartial();
+
+ expect(tokensContainer.querySelector('.js-visual-token .name')).toEqual(null);
+ });
+
+ it('should not remove anything when there are no tokens', () => {
+ const html = tokensContainer.innerHTML;
+ subject.removeLastTokenPartial();
+
+ expect(tokensContainer.innerHTML).toEqual(html);
+ });
+ });
+
+ describe('tokenizeInput', () => {
+ it('does not do anything if there is no input', () => {
+ const original = tokensContainer.innerHTML;
+ subject.tokenizeInput();
+
+ expect(tokensContainer.innerHTML).toEqual(original);
+ });
+
+ it('adds search visual token if previous visual token is valid', () => {
+ tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
+ FilteredSearchSpecHelper.createFilterVisualTokenHTML('assignee', '=', 'none'),
+ );
+
+ const input = document.querySelector('.filtered-search');
+ input.value = 'some value';
+ subject.tokenizeInput();
+
+ const newToken = tokensContainer.querySelector('.filtered-search-term');
+
+ expect(input.value).toEqual('');
+ expect(newToken.querySelector('.name').innerText).toEqual('some value');
+ expect(newToken.querySelector('.value')).toEqual(null);
+ });
+
+ it('adds value to previous visual token element if previous visual token is invalid', () => {
+ tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
+ FilteredSearchSpecHelper.createNameOperatorFilterVisualTokenHTML('assignee', '='),
+ );
+
+ const input = document.querySelector('.filtered-search');
+ input.value = '@john';
+ subject.tokenizeInput();
+
+ const updatedToken = tokensContainer.querySelector('.filtered-search-token');
+
+ expect(input.value).toEqual('');
+ expect(updatedToken.querySelector('.name').innerText).toEqual('assignee');
+ expect(updatedToken.querySelector('.operator').innerText).toEqual('=');
+ expect(updatedToken.querySelector('.value').innerText).toEqual('@john');
+ });
+ });
+
+ describe('editToken', () => {
+ let input;
+ let token;
+
+ beforeEach(() => {
+ tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(`
+ ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('label', '=', 'none')}
+ ${FilteredSearchSpecHelper.createSearchVisualTokenHTML('search')}
+ ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('milestone', '=', 'upcoming')}
+ `);
+
+ input = document.querySelector('.filtered-search');
+ token = document.querySelector('.js-visual-token');
+ });
+
+ it("tokenize's existing input", () => {
+ input.value = 'some text';
+ jest.spyOn(subject, 'tokenizeInput');
+
+ subject.editToken(token);
+
+ expect(subject.tokenizeInput).toHaveBeenCalled();
+ expect(input.value).not.toEqual('some text');
+ });
+
+ it('moves input to the token position', () => {
+ expect(tokensContainer.children[3].querySelector('.filtered-search')).not.toEqual(null);
+
+ subject.editToken(token);
+
+ expect(tokensContainer.children[1].querySelector('.filtered-search')).not.toEqual(null);
+ expect(tokensContainer.children[3].querySelector('.filtered-search')).toEqual(null);
+ });
+
+ it('input contains the visual token value', () => {
+ subject.editToken(token);
+
+ expect(input.value).toEqual('none');
+ });
+
+ it('input contains the original value if present', () => {
+ const originalValue = '@user';
+ const valueContainer = token.querySelector('.value-container');
+ valueContainer.dataset.originalValue = originalValue;
+
+ subject.editToken(token);
+
+ expect(input.value).toEqual(originalValue);
+ });
+
+ describe('selected token is a search term token', () => {
+ beforeEach(() => {
+ token = document.querySelector('.filtered-search-term');
+ });
+
+ it('token is removed', () => {
+ expect(tokensContainer.querySelector('.filtered-search-term')).not.toEqual(null);
+
+ subject.editToken(token);
+
+ expect(tokensContainer.querySelector('.filtered-search-term')).toEqual(null);
+ });
+
+ it('input has the same value as removed token', () => {
+ expect(input.value).toEqual('');
+
+ subject.editToken(token);
+
+ expect(input.value).toEqual('search');
+ });
+ });
+ });
+
+ describe('moveInputTotheRight', () => {
+ it('does nothing if the input is already the right most element', () => {
+ tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
+ FilteredSearchSpecHelper.createFilterVisualTokenHTML('label', '=', 'none'),
+ );
+
+ jest.spyOn(subject, 'tokenizeInput').mockImplementation(() => {});
+ jest.spyOn(subject, 'getLastVisualTokenBeforeInput');
+
+ subject.moveInputToTheRight();
+
+ expect(subject.tokenizeInput).toHaveBeenCalled();
+ expect(subject.getLastVisualTokenBeforeInput).not.toHaveBeenCalled();
+ });
+
+ it("tokenize's input", () => {
+ tokensContainer.innerHTML = `
+ ${FilteredSearchSpecHelper.createNameOperatorFilterVisualTokenHTML('label', '=')}
+ ${FilteredSearchSpecHelper.createInputHTML()}
+ ${bugLabelToken.outerHTML}
+ `;
+
+ tokensContainer.querySelector('.filtered-search').value = 'none';
+
+ subject.moveInputToTheRight();
+ const value = tokensContainer.querySelector('.js-visual-token .value');
+
+ expect(value.innerText).toEqual('none');
+ });
+
+ it('converts input into search term token if last token is valid', () => {
+ tokensContainer.innerHTML = `
+ ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('label', '=', 'none')}
+ ${FilteredSearchSpecHelper.createInputHTML()}
+ ${bugLabelToken.outerHTML}
+ `;
+
+ document.querySelector('.filtered-search').value = 'test';
+
+ subject.moveInputToTheRight();
+ const searchValue = tokensContainer.querySelector('.filtered-search-term .name');
+
+ expect(searchValue.innerText).toEqual('test');
+ });
+
+ it('moves the input to the right most element', () => {
+ tokensContainer.innerHTML = `
+ ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('label', '=', 'none')}
+ ${FilteredSearchSpecHelper.createInputHTML()}
+ ${bugLabelToken.outerHTML}
+ `;
+
+ subject.moveInputToTheRight();
+
+ expect(tokensContainer.children[2].querySelector('.filtered-search')).not.toEqual(null);
+ });
+
+ it('tokenizes input even if input is the right most element', () => {
+ tokensContainer.innerHTML = `
+ ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('label', '=', 'none')}
+ ${FilteredSearchSpecHelper.createNameOperatorFilterVisualTokenHTML('label')}
+ ${FilteredSearchSpecHelper.createInputHTML('', '~bug')}
+ `;
+
+ subject.moveInputToTheRight();
+
+ const token = tokensContainer.children[1];
+
+ expect(token.querySelector('.value').innerText).toEqual('~bug');
+ });
+ });
+
+ describe('renderVisualTokenValue', () => {
+ beforeEach(() => {
+ tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(`
+ ${authorToken.outerHTML}
+ ${bugLabelToken.outerHTML}
+ `);
+ });
+
+ it('renders a author token value element', () => {
+ const { tokenNameElement, tokenValueElement } = findElements(authorToken);
+ const tokenName = tokenNameElement.textContent;
+ const tokenValue = 'new value';
+
+ subject.renderVisualTokenValue(authorToken, tokenName, tokenValue);
+
+ jest.runOnlyPendingTimers();
+
+ setImmediate(() => {
+ expect(tokenValueElement.textContent).toBe(tokenValue);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/fixtures/abuse_reports.rb b/spec/frontend/fixtures/abuse_reports.rb
index 712ed2e8d7e..48b055fcda5 100644
--- a/spec/frontend/fixtures/abuse_reports.rb
+++ b/spec/frontend/fixtures/abuse_reports.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::AbuseReportsController, '(JavaScript fixtures)', type: :controller do
+RSpec.describe Admin::AbuseReportsController, '(JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
let(:admin) { create(:admin) }
diff --git a/spec/frontend/fixtures/admin_users.rb b/spec/frontend/fixtures/admin_users.rb
index b0f7d69f091..f068ada53e1 100644
--- a/spec/frontend/fixtures/admin_users.rb
+++ b/spec/frontend/fixtures/admin_users.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::UsersController, '(JavaScript fixtures)', type: :controller do
+RSpec.describe Admin::UsersController, '(JavaScript fixtures)', type: :controller do
include StubENV
include JavaScriptFixturesHelpers
diff --git a/spec/frontend/fixtures/application_settings.rb b/spec/frontend/fixtures/application_settings.rb
index a16888d8f03..6156e6a43bc 100644
--- a/spec/frontend/fixtures/application_settings.rb
+++ b/spec/frontend/fixtures/application_settings.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Admin::ApplicationSettingsController, '(JavaScript fixtures)', type: :controller do
+RSpec.describe Admin::ApplicationSettingsController, '(JavaScript fixtures)', type: :controller do
include StubENV
include JavaScriptFixturesHelpers
diff --git a/spec/frontend/fixtures/autocomplete_sources.rb b/spec/frontend/fixtures/autocomplete_sources.rb
index 812364c8b06..8858d69a939 100644
--- a/spec/frontend/fixtures/autocomplete_sources.rb
+++ b/spec/frontend/fixtures/autocomplete_sources.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::AutocompleteSourcesController, '(JavaScript fixtures)', type: :controller do
+RSpec.describe Projects::AutocompleteSourcesController, '(JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
let_it_be(:admin) { create(:admin) }
diff --git a/spec/frontend/fixtures/blob.rb b/spec/frontend/fixtures/blob.rb
index 28a3badaa17..712c3bd9b23 100644
--- a/spec/frontend/fixtures/blob.rb
+++ b/spec/frontend/fixtures/blob.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::BlobController, '(JavaScript fixtures)', type: :controller do
+RSpec.describe Projects::BlobController, '(JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
let(:admin) { create(:admin) }
diff --git a/spec/frontend/fixtures/boards.rb b/spec/frontend/fixtures/boards.rb
index b3c7865a088..90e2ca4db63 100644
--- a/spec/frontend/fixtures/boards.rb
+++ b/spec/frontend/fixtures/boards.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::BoardsController, '(JavaScript fixtures)', type: :controller do
+RSpec.describe Projects::BoardsController, '(JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
let(:admin) { create(:admin) }
diff --git a/spec/frontend/fixtures/branches.rb b/spec/frontend/fixtures/branches.rb
index 2dc8cde625a..4667dfb69f8 100644
--- a/spec/frontend/fixtures/branches.rb
+++ b/spec/frontend/fixtures/branches.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::BranchesController, '(JavaScript fixtures)', type: :controller do
+RSpec.describe Projects::BranchesController, '(JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
let(:admin) { create(:admin) }
diff --git a/spec/frontend/fixtures/clusters.rb b/spec/frontend/fixtures/clusters.rb
index fd64d3c0e28..d0940c7dc7f 100644
--- a/spec/frontend/fixtures/clusters.rb
+++ b/spec/frontend/fixtures/clusters.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ClustersController, '(JavaScript fixtures)', type: :controller do
+RSpec.describe Projects::ClustersController, '(JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
let(:admin) { create(:admin) }
diff --git a/spec/frontend/fixtures/commit.rb b/spec/frontend/fixtures/commit.rb
index c9a5aa9a67c..c5c00afd4ca 100644
--- a/spec/frontend/fixtures/commit.rb
+++ b/spec/frontend/fixtures/commit.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::CommitController, '(JavaScript fixtures)', type: :controller do
+RSpec.describe Projects::CommitController, '(JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
let_it_be(:project) { create(:project, :repository) }
diff --git a/spec/frontend/fixtures/deploy_keys.rb b/spec/frontend/fixtures/deploy_keys.rb
index f491c424bcf..e87600e9d24 100644
--- a/spec/frontend/fixtures/deploy_keys.rb
+++ b/spec/frontend/fixtures/deploy_keys.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::DeployKeysController, '(JavaScript fixtures)', type: :controller do
+RSpec.describe Projects::DeployKeysController, '(JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
let(:admin) { create(:admin) }
diff --git a/spec/frontend/fixtures/groups.rb b/spec/frontend/fixtures/groups.rb
index 2421b67a130..6f0d7aa1f7c 100644
--- a/spec/frontend/fixtures/groups.rb
+++ b/spec/frontend/fixtures/groups.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Groups (JavaScript fixtures)', type: :controller do
+RSpec.describe 'Groups (JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
let(:admin) { create(:admin) }
diff --git a/spec/frontend/fixtures/issues.rb b/spec/frontend/fixtures/issues.rb
index 9a194e5ca84..2c380ba6a96 100644
--- a/spec/frontend/fixtures/issues.rb
+++ b/spec/frontend/fixtures/issues.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::IssuesController, '(JavaScript fixtures)', type: :controller do
+RSpec.describe Projects::IssuesController, '(JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
let(:admin) { create(:admin, feed_token: 'feedtoken:coldfeed') }
@@ -75,7 +75,7 @@ describe Projects::IssuesController, '(JavaScript fixtures)', type: :controller
end
end
-describe API::Issues, '(JavaScript fixtures)', type: :request do
+RSpec.describe API::Issues, '(JavaScript fixtures)', type: :request do
include ApiHelpers
include JavaScriptFixturesHelpers
diff --git a/spec/frontend/fixtures/jobs.rb b/spec/frontend/fixtures/jobs.rb
index 787ab517f75..64197a62301 100644
--- a/spec/frontend/fixtures/jobs.rb
+++ b/spec/frontend/fixtures/jobs.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::JobsController, '(JavaScript fixtures)', type: :controller do
+RSpec.describe Projects::JobsController, '(JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
let(:admin) { create(:admin) }
diff --git a/spec/frontend/fixtures/labels.rb b/spec/frontend/fixtures/labels.rb
index e5a0501ac03..2b7babb2e52 100644
--- a/spec/frontend/fixtures/labels.rb
+++ b/spec/frontend/fixtures/labels.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Labels (JavaScript fixtures)' do
+RSpec.describe 'Labels (JavaScript fixtures)' do
include JavaScriptFixturesHelpers
let(:admin) { create(:admin) }
diff --git a/spec/frontend/fixtures/merge_requests.rb b/spec/frontend/fixtures/merge_requests.rb
index a347ef683e7..7801eb27ce8 100644
--- a/spec/frontend/fixtures/merge_requests.rb
+++ b/spec/frontend/fixtures/merge_requests.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MergeRequestsController, '(JavaScript fixtures)', type: :controller do
+RSpec.describe Projects::MergeRequestsController, '(JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
let(:admin) { create(:admin) }
diff --git a/spec/frontend/fixtures/merge_requests_diffs.rb b/spec/frontend/fixtures/merge_requests_diffs.rb
index 76bb8567a64..63bd02d0fbd 100644
--- a/spec/frontend/fixtures/merge_requests_diffs.rb
+++ b/spec/frontend/fixtures/merge_requests_diffs.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MergeRequests::DiffsController, '(JavaScript fixtures)', type: :controller do
+RSpec.describe Projects::MergeRequests::DiffsController, '(JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
let(:admin) { create(:admin) }
diff --git a/spec/frontend/fixtures/metrics_dashboard.rb b/spec/frontend/fixtures/metrics_dashboard.rb
index f0c741af37d..b5dee7525f6 100644
--- a/spec/frontend/fixtures/metrics_dashboard.rb
+++ b/spec/frontend/fixtures/metrics_dashboard.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MetricsDashboard, '(JavaScript fixtures)', type: :controller do
+RSpec.describe MetricsDashboard, '(JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
include MetricsDashboardHelpers
diff --git a/spec/frontend/fixtures/pipeline_schedules.rb b/spec/frontend/fixtures/pipeline_schedules.rb
index e00a35d5362..e47bb25ec0a 100644
--- a/spec/frontend/fixtures/pipeline_schedules.rb
+++ b/spec/frontend/fixtures/pipeline_schedules.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::PipelineSchedulesController, '(JavaScript fixtures)', type: :controller do
+RSpec.describe Projects::PipelineSchedulesController, '(JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
let(:admin) { create(:admin) }
diff --git a/spec/frontend/fixtures/pipelines.rb b/spec/frontend/fixtures/pipelines.rb
index 83fc13af7d3..93e2c19fc27 100644
--- a/spec/frontend/fixtures/pipelines.rb
+++ b/spec/frontend/fixtures/pipelines.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::PipelinesController, '(JavaScript fixtures)', type: :controller do
+RSpec.describe Projects::PipelinesController, '(JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
let(:admin) { create(:admin) }
diff --git a/spec/frontend/fixtures/projects.rb b/spec/frontend/fixtures/projects.rb
index ff21dbaebe8..d33909fb98b 100644
--- a/spec/frontend/fixtures/projects.rb
+++ b/spec/frontend/fixtures/projects.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects (JavaScript fixtures)', type: :controller do
+RSpec.describe 'Projects (JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
runners_token = 'runnerstoken:intabulasreferre'
diff --git a/spec/frontend/fixtures/prometheus_service.rb b/spec/frontend/fixtures/prometheus_service.rb
index c404b8260d2..8c923d91d08 100644
--- a/spec/frontend/fixtures/prometheus_service.rb
+++ b/spec/frontend/fixtures/prometheus_service.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ServicesController, '(JavaScript fixtures)', type: :controller do
+RSpec.describe Projects::ServicesController, '(JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
let(:admin) { create(:admin) }
diff --git a/spec/frontend/fixtures/raw.rb b/spec/frontend/fixtures/raw.rb
index 9c9fa4ec40b..337067121d0 100644
--- a/spec/frontend/fixtures/raw.rb
+++ b/spec/frontend/fixtures/raw.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Raw files', '(JavaScript fixtures)' do
+RSpec.describe 'Raw files', '(JavaScript fixtures)' do
include JavaScriptFixturesHelpers
let(:namespace) { create(:namespace, name: 'frontend-fixtures' )}
diff --git a/spec/frontend/fixtures/search.rb b/spec/frontend/fixtures/search.rb
index cbe3e373986..fcd68662acc 100644
--- a/spec/frontend/fixtures/search.rb
+++ b/spec/frontend/fixtures/search.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe SearchController, '(JavaScript fixtures)', type: :controller do
+RSpec.describe SearchController, '(JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
render_views
diff --git a/spec/frontend/fixtures/services.rb b/spec/frontend/fixtures/services.rb
index 1b81a83ca49..0877998cc9d 100644
--- a/spec/frontend/fixtures/services.rb
+++ b/spec/frontend/fixtures/services.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ServicesController, '(JavaScript fixtures)', type: :controller do
+RSpec.describe Projects::ServicesController, '(JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
let(:admin) { create(:admin) }
diff --git a/spec/frontend/fixtures/sessions.rb b/spec/frontend/fixtures/sessions.rb
index a4dc0aef79c..0ef14c1d4fa 100644
--- a/spec/frontend/fixtures/sessions.rb
+++ b/spec/frontend/fixtures/sessions.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Sessions (JavaScript fixtures)' do
+RSpec.describe 'Sessions (JavaScript fixtures)' do
include JavaScriptFixturesHelpers
before(:all) do
diff --git a/spec/frontend/fixtures/snippet.rb b/spec/frontend/fixtures/snippet.rb
index d27c2fbe68b..26b088bbd88 100644
--- a/spec/frontend/fixtures/snippet.rb
+++ b/spec/frontend/fixtures/snippet.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe SnippetsController, '(JavaScript fixtures)', type: :controller do
+RSpec.describe SnippetsController, '(JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
let(:admin) { create(:admin) }
diff --git a/spec/frontend/fixtures/static/search_autocomplete.html b/spec/frontend/fixtures/static/global_search_input.html
index 29db9020424..29db9020424 100644
--- a/spec/frontend/fixtures/static/search_autocomplete.html
+++ b/spec/frontend/fixtures/static/global_search_input.html
diff --git a/spec/frontend/fixtures/static/oauth_remember_me.html b/spec/frontend/fixtures/static/oauth_remember_me.html
index 9ba1ffc72fe..c6af8129b4d 100644
--- a/spec/frontend/fixtures/static/oauth_remember_me.html
+++ b/spec/frontend/fixtures/static/oauth_remember_me.html
@@ -1,6 +1,22 @@
<div id="oauth-container">
<input id="remember_me" type="checkbox">
-<a class="oauth-login twitter" href="http://example.com/"></a>
-<a class="oauth-login github" href="http://example.com/"></a>
-<a class="oauth-login facebook" href="http://example.com/?redirect_fragment=L1"></a>
+
+<form method="post" action="http://example.com/">
+ <button class="oauth-login twitter" type="submit">
+ <span>Twitter</span>
+ </button>
+</form>
+
+<form method="post" action="http://example.com/">
+ <button class="oauth-login github" type="submit">
+ <span>GitHub</span>
+ </button>
+</form>
+
+<form method="post" action="http://example.com/?redirect_fragment=L1">
+ <button class="oauth-login facebook" type="submit">
+ <span>Facebook</span>
+ </button>
+</form>
+
</div>
diff --git a/spec/frontend/fixtures/test_report.rb b/spec/frontend/fixtures/test_report.rb
index d0ecaf11994..16496aa901b 100644
--- a/spec/frontend/fixtures/test_report.rb
+++ b/spec/frontend/fixtures/test_report.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe Projects::PipelinesController, "(JavaScript fixtures)", type: :controller do
+RSpec.describe Projects::PipelinesController, "(JavaScript fixtures)", type: :controller do
include JavaScriptFixturesHelpers
let(:namespace) { create(:namespace, name: "frontend-fixtures") }
diff --git a/spec/frontend/fixtures/todos.rb b/spec/frontend/fixtures/todos.rb
index e5bdb4998ed..399be272e9b 100644
--- a/spec/frontend/fixtures/todos.rb
+++ b/spec/frontend/fixtures/todos.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Todos (JavaScript fixtures)' do
+RSpec.describe 'Todos (JavaScript fixtures)' do
include JavaScriptFixturesHelpers
let(:admin) { create(:admin) }
diff --git a/spec/frontend/fixtures/u2f.rb b/spec/frontend/fixtures/u2f.rb
index 9710fbbc181..be3874d7c42 100644
--- a/spec/frontend/fixtures/u2f.rb
+++ b/spec/frontend/fixtures/u2f.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-context 'U2F' do
+RSpec.context 'U2F' do
include JavaScriptFixturesHelpers
let(:user) { create(:user, :two_factor_via_u2f, otp_secret: 'otpsecret:coolkids') }
diff --git a/spec/frontend/gl_dropdown_spec.js b/spec/frontend/gl_dropdown_spec.js
new file mode 100644
index 00000000000..8bfe7f56e37
--- /dev/null
+++ b/spec/frontend/gl_dropdown_spec.js
@@ -0,0 +1,345 @@
+/* eslint-disable no-param-reassign */
+
+import $ from 'jquery';
+import '~/gl_dropdown';
+import '~/lib/utils/common_utils';
+import { visitUrl } from '~/lib/utils/url_utility';
+
+jest.mock('~/lib/utils/url_utility', () => ({
+ visitUrl: jest.fn().mockName('visitUrl'),
+}));
+
+describe('glDropdown', () => {
+ preloadFixtures('static/gl_dropdown.html');
+
+ const NON_SELECTABLE_CLASSES =
+ '.divider, .separator, .dropdown-header, .dropdown-menu-empty-item';
+ const SEARCH_INPUT_SELECTOR = '.dropdown-input-field';
+ const ITEM_SELECTOR = `.dropdown-content li:not(${NON_SELECTABLE_CLASSES})`;
+ const FOCUSED_ITEM_SELECTOR = `${ITEM_SELECTOR} a.is-focused`;
+ const ARROW_KEYS = {
+ DOWN: 40,
+ UP: 38,
+ ENTER: 13,
+ ESC: 27,
+ };
+
+ let remoteCallback;
+
+ const test = {};
+
+ const navigateWithKeys = (direction, steps, cb, i) => {
+ i = i || 0;
+ if (!i) direction = direction.toUpperCase();
+ $('body').trigger({
+ type: 'keydown',
+ which: ARROW_KEYS[direction],
+ keyCode: ARROW_KEYS[direction],
+ });
+ i += 1;
+ if (i <= steps) {
+ navigateWithKeys(direction, steps, cb, i);
+ } else {
+ cb();
+ }
+ };
+
+ const remoteMock = (data, term, callback) => {
+ remoteCallback = callback.bind({}, data);
+ };
+
+ function initDropDown(hasRemote, isFilterable, extraOpts = {}) {
+ const options = {
+ selectable: true,
+ filterable: isFilterable,
+ data: hasRemote ? remoteMock.bind({}, test.projectsData) : test.projectsData,
+ search: {
+ fields: ['name'],
+ },
+ text: project => project.name_with_namespace || project.name,
+ id: project => project.id,
+ ...extraOpts,
+ };
+ test.dropdownButtonElement = $(
+ '#js-project-dropdown',
+ test.dropdownContainerElement,
+ ).glDropdown(options);
+ }
+
+ beforeEach(() => {
+ loadFixtures('static/gl_dropdown.html');
+ test.dropdownContainerElement = $('.dropdown.inline');
+ test.$dropdownMenuElement = $('.dropdown-menu', test.dropdownContainerElement);
+ test.projectsData = getJSONFixture('static/projects.json');
+ });
+
+ afterEach(() => {
+ $('body').off('keydown');
+ test.dropdownContainerElement.off('keyup');
+ });
+
+ it('should open on click', () => {
+ initDropDown.call(this, false);
+
+ expect(test.dropdownContainerElement).not.toHaveClass('show');
+ test.dropdownButtonElement.click();
+
+ expect(test.dropdownContainerElement).toHaveClass('show');
+ });
+
+ it('escapes HTML as text', () => {
+ test.projectsData[0].name_with_namespace = '<script>alert("testing");</script>';
+
+ initDropDown.call(this, false);
+
+ test.dropdownButtonElement.click();
+
+ expect($('.dropdown-content li:first-child').text()).toBe('<script>alert("testing");</script>');
+ });
+
+ it('should output HTML when highlighting', () => {
+ test.projectsData[0].name_with_namespace = 'testing';
+ $('.dropdown-input .dropdown-input-field').val('test');
+
+ initDropDown.call(this, false, true, {
+ highlight: true,
+ });
+
+ test.dropdownButtonElement.click();
+
+ expect($('.dropdown-content li:first-child').text()).toBe('testing');
+
+ expect($('.dropdown-content li:first-child a').html()).toBe(
+ '<b>t</b><b>e</b><b>s</b><b>t</b>ing',
+ );
+ });
+
+ describe('that is open', () => {
+ beforeEach(() => {
+ initDropDown.call(this, false, false);
+ test.dropdownButtonElement.click();
+ });
+
+ it('should select a following item on DOWN keypress', () => {
+ expect($(FOCUSED_ITEM_SELECTOR, test.$dropdownMenuElement).length).toBe(0);
+ const randomIndex = Math.floor(Math.random() * (test.projectsData.length - 1)) + 0;
+ navigateWithKeys('down', randomIndex, () => {
+ expect($(FOCUSED_ITEM_SELECTOR, test.$dropdownMenuElement).length).toBe(1);
+ expect($(`${ITEM_SELECTOR}:eq(${randomIndex}) a`, test.$dropdownMenuElement)).toHaveClass(
+ 'is-focused',
+ );
+ });
+ });
+
+ it('should select a previous item on UP keypress', () => {
+ expect($(FOCUSED_ITEM_SELECTOR, test.$dropdownMenuElement).length).toBe(0);
+ navigateWithKeys('down', test.projectsData.length - 1, () => {
+ expect($(FOCUSED_ITEM_SELECTOR, test.$dropdownMenuElement).length).toBe(1);
+ const randomIndex = Math.floor(Math.random() * (test.projectsData.length - 2)) + 0;
+ navigateWithKeys('up', randomIndex, () => {
+ expect($(FOCUSED_ITEM_SELECTOR, test.$dropdownMenuElement).length).toBe(1);
+ expect(
+ $(
+ `${ITEM_SELECTOR}:eq(${test.projectsData.length - 2 - randomIndex}) a`,
+ test.$dropdownMenuElement,
+ ),
+ ).toHaveClass('is-focused');
+ });
+ });
+ });
+
+ it('should click the selected item on ENTER keypress', () => {
+ expect(test.dropdownContainerElement).toHaveClass('show');
+ const randomIndex = Math.floor(Math.random() * (test.projectsData.length - 1)) + 0;
+ navigateWithKeys('down', randomIndex, () => {
+ navigateWithKeys('enter', null, () => {
+ expect(test.dropdownContainerElement).not.toHaveClass('show');
+ const link = $(`${ITEM_SELECTOR}:eq(${randomIndex}) a`, test.$dropdownMenuElement);
+
+ expect(link).toHaveClass('is-active');
+ const linkedLocation = link.attr('href');
+ if (linkedLocation && linkedLocation !== '#') {
+ expect(visitUrl).toHaveBeenCalledWith(linkedLocation);
+ }
+ });
+ });
+ });
+
+ it('should close on ESC keypress', () => {
+ expect(test.dropdownContainerElement).toHaveClass('show');
+ test.dropdownContainerElement.trigger({
+ type: 'keyup',
+ which: ARROW_KEYS.ESC,
+ keyCode: ARROW_KEYS.ESC,
+ });
+
+ expect(test.dropdownContainerElement).not.toHaveClass('show');
+ });
+ });
+
+ describe('opened and waiting for a remote callback', () => {
+ beforeEach(() => {
+ initDropDown.call(this, true, true);
+ test.dropdownButtonElement.click();
+ });
+
+ it('should show loading indicator while search results are being fetched by backend', () => {
+ const dropdownMenu = document.querySelector('.dropdown-menu');
+
+ expect(dropdownMenu.className.indexOf('is-loading')).not.toBe(-1);
+ remoteCallback();
+
+ expect(dropdownMenu.className.indexOf('is-loading')).toBe(-1);
+ });
+
+ it('should not focus search input while remote task is not complete', () => {
+ expect($(document.activeElement)).not.toEqual($(SEARCH_INPUT_SELECTOR));
+ remoteCallback();
+
+ expect($(document.activeElement)).toEqual($(SEARCH_INPUT_SELECTOR));
+ });
+
+ it('should focus search input after remote task is complete', () => {
+ remoteCallback();
+
+ expect($(document.activeElement)).toEqual($(SEARCH_INPUT_SELECTOR));
+ });
+
+ it('should focus on input when opening for the second time after transition', () => {
+ remoteCallback();
+ test.dropdownContainerElement.trigger({
+ type: 'keyup',
+ which: ARROW_KEYS.ESC,
+ keyCode: ARROW_KEYS.ESC,
+ });
+ test.dropdownButtonElement.click();
+ test.dropdownContainerElement.trigger('transitionend');
+
+ expect($(document.activeElement)).toEqual($(SEARCH_INPUT_SELECTOR));
+ });
+ });
+
+ describe('input focus with array data', () => {
+ it('should focus input when passing array data to drop down', () => {
+ initDropDown.call(this, false, true);
+ test.dropdownButtonElement.click();
+ test.dropdownContainerElement.trigger('transitionend');
+
+ expect($(document.activeElement)).toEqual($(SEARCH_INPUT_SELECTOR));
+ });
+ });
+
+ it('should still have input value on close and restore', () => {
+ const $searchInput = $(SEARCH_INPUT_SELECTOR);
+ initDropDown.call(this, false, true);
+ $searchInput
+ .trigger('focus')
+ .val('g')
+ .trigger('input');
+
+ expect($searchInput.val()).toEqual('g');
+ test.dropdownButtonElement.trigger('hidden.bs.dropdown');
+ $searchInput.trigger('blur').trigger('focus');
+
+ expect($searchInput.val()).toEqual('g');
+ });
+
+ describe('renderItem', () => {
+ function dropdownWithOptions(options) {
+ const $dropdownDiv = $('<div />');
+
+ $dropdownDiv.glDropdown(options);
+
+ return $dropdownDiv.data('glDropdown');
+ }
+
+ function basicDropdown() {
+ return dropdownWithOptions({});
+ }
+
+ describe('without selected value', () => {
+ let dropdown;
+
+ beforeEach(() => {
+ dropdown = basicDropdown();
+ });
+
+ it('marks items without ID as active', () => {
+ const dummyData = {};
+
+ const html = dropdown.renderItem(dummyData, null, null);
+
+ const link = html.querySelector('a');
+
+ expect(link).toHaveClass('is-active');
+ });
+
+ it('does not mark items with ID as active', () => {
+ const dummyData = {
+ id: 'ea',
+ };
+
+ const html = dropdown.renderItem(dummyData, null, null);
+
+ const link = html.querySelector('a');
+
+ expect(link).not.toHaveClass('is-active');
+ });
+ });
+
+ it('should return an empty .separator li when when appropriate', () => {
+ const dropdown = basicDropdown();
+ const sep = { type: 'separator' };
+ const li = dropdown.renderItem(sep);
+
+ expect(li).toHaveClass('separator');
+ expect(li.childNodes.length).toEqual(0);
+ });
+
+ it('should return an empty .divider li when when appropriate', () => {
+ const dropdown = basicDropdown();
+ const div = { type: 'divider' };
+ const li = dropdown.renderItem(div);
+
+ expect(li).toHaveClass('divider');
+ expect(li.childNodes.length).toEqual(0);
+ });
+
+ it('should return a .dropdown-header li with the correct content when when appropriate', () => {
+ const dropdown = basicDropdown();
+ const text = 'My Header';
+ const header = { type: 'header', content: text };
+ const li = dropdown.renderItem(header);
+
+ expect(li).toHaveClass('dropdown-header');
+ expect(li.childNodes.length).toEqual(1);
+ expect(li.textContent).toEqual(text);
+ });
+ });
+
+ it('should keep selected item after selecting a second time', () => {
+ const options = {
+ isSelectable(item, $el) {
+ return !$el.hasClass('is-active');
+ },
+ toggleLabel(item) {
+ return item && item.id;
+ },
+ };
+ initDropDown.call(this, false, false, options);
+ const $item = $(`${ITEM_SELECTOR}:first() a`, test.$dropdownMenuElement);
+
+ // select item the first time
+ test.dropdownButtonElement.click();
+ $item.click();
+
+ expect($item).toHaveClass('is-active');
+ // select item the second time
+ test.dropdownButtonElement.click();
+ $item.click();
+
+ expect($item).toHaveClass('is-active');
+
+ expect($('.dropdown-toggle-text')).toHaveText(test.projectsData[0].id.toString());
+ });
+});
diff --git a/spec/frontend/gl_form_spec.js b/spec/frontend/gl_form_spec.js
new file mode 100644
index 00000000000..150d8a053d5
--- /dev/null
+++ b/spec/frontend/gl_form_spec.js
@@ -0,0 +1,115 @@
+import $ from 'jquery';
+import autosize from 'autosize';
+import GLForm from '~/gl_form';
+import '~/lib/utils/text_utility';
+import '~/lib/utils/common_utils';
+
+describe('GLForm', () => {
+ const testContext = {};
+
+ describe('when instantiated', () => {
+ beforeEach(done => {
+ testContext.form = $('<form class="gfm-form"><textarea class="js-gfm-input"></form>');
+ testContext.textarea = testContext.form.find('textarea');
+ jest.spyOn($.prototype, 'off').mockReturnValue(testContext.textarea);
+ jest.spyOn($.prototype, 'on').mockReturnValue(testContext.textarea);
+ jest.spyOn($.prototype, 'css').mockImplementation(() => {});
+
+ testContext.glForm = new GLForm(testContext.form, false);
+
+ setImmediate(() => {
+ $.prototype.off.mockClear();
+ $.prototype.on.mockClear();
+ $.prototype.css.mockClear();
+ done();
+ });
+ });
+
+ describe('setupAutosize', () => {
+ beforeEach(done => {
+ testContext.glForm.setupAutosize();
+
+ setImmediate(() => {
+ done();
+ });
+ });
+
+ it('should register an autosize event handler on the textarea', () => {
+ expect($.prototype.off).toHaveBeenCalledWith('autosize:resized');
+ expect($.prototype.on).toHaveBeenCalledWith('autosize:resized', expect.any(Function));
+ });
+
+ it('should register a mouseup event handler on the textarea', () => {
+ expect($.prototype.off).toHaveBeenCalledWith('mouseup.autosize');
+ expect($.prototype.on).toHaveBeenCalledWith('mouseup.autosize', expect.any(Function));
+ });
+
+ it('should set the resize css property to vertical', () => {
+ jest.runOnlyPendingTimers();
+ expect($.prototype.css).toHaveBeenCalledWith('resize', 'vertical');
+ });
+ });
+
+ describe('setHeightData', () => {
+ beforeEach(() => {
+ jest.spyOn($.prototype, 'data').mockImplementation(() => {});
+ jest.spyOn($.prototype, 'outerHeight').mockReturnValue(200);
+ testContext.glForm.setHeightData();
+ });
+
+ it('should set the height data attribute', () => {
+ expect($.prototype.data).toHaveBeenCalledWith('height', 200);
+ });
+
+ it('should call outerHeight', () => {
+ expect($.prototype.outerHeight).toHaveBeenCalled();
+ });
+ });
+
+ describe('destroyAutosize', () => {
+ describe('when called', () => {
+ beforeEach(() => {
+ jest.spyOn($.prototype, 'data').mockImplementation(() => {});
+ jest.spyOn($.prototype, 'outerHeight').mockReturnValue(200);
+ window.outerHeight = () => 400;
+ jest.spyOn(autosize, 'destroy').mockImplementation(() => {});
+
+ testContext.glForm.destroyAutosize();
+ });
+
+ it('should call outerHeight', () => {
+ expect($.prototype.outerHeight).toHaveBeenCalled();
+ });
+
+ it('should get data-height attribute', () => {
+ expect($.prototype.data).toHaveBeenCalledWith('height');
+ });
+
+ it('should call autosize destroy', () => {
+ expect(autosize.destroy).toHaveBeenCalledWith(testContext.textarea);
+ });
+
+ it('should set the data-height attribute', () => {
+ expect($.prototype.data).toHaveBeenCalledWith('height', 200);
+ });
+
+ it('should set the outerHeight', () => {
+ expect($.prototype.outerHeight).toHaveBeenCalledWith(200);
+ });
+
+ it('should set the css', () => {
+ expect($.prototype.css).toHaveBeenCalledWith('max-height', window.outerHeight);
+ });
+ });
+
+ it('should return undefined if the data-height equals the outerHeight', () => {
+ jest.spyOn($.prototype, 'outerHeight').mockReturnValue(200);
+ jest.spyOn($.prototype, 'data').mockReturnValue(200);
+ jest.spyOn(autosize, 'destroy').mockImplementation(() => {});
+
+ expect(testContext.glForm.destroyAutosize()).toBeUndefined();
+ expect(autosize.destroy).not.toHaveBeenCalled();
+ });
+ });
+ });
+});
diff --git a/spec/frontend/global_search_input_spec.js b/spec/frontend/global_search_input_spec.js
new file mode 100644
index 00000000000..8c00ea5f193
--- /dev/null
+++ b/spec/frontend/global_search_input_spec.js
@@ -0,0 +1,215 @@
+/* eslint-disable no-unused-expressions, consistent-return, no-param-reassign, default-case, no-return-assign */
+
+import $ from 'jquery';
+import '~/gl_dropdown';
+import initGlobalSearchInput from '~/global_search_input';
+import '~/lib/utils/common_utils';
+
+describe('Global search input dropdown', () => {
+ let widget = null;
+
+ const userName = 'root';
+
+ const userId = 1;
+
+ const dashboardIssuesPath = '/dashboard/issues';
+
+ const dashboardMRsPath = '/dashboard/merge_requests';
+
+ const projectIssuesPath = '/gitlab-org/gitlab-foss/issues';
+
+ const projectMRsPath = '/gitlab-org/gitlab-foss/-/merge_requests';
+
+ const groupIssuesPath = '/groups/gitlab-org/-/issues';
+
+ const groupMRsPath = '/groups/gitlab-org/-/merge_requests';
+
+ const projectName = 'GitLab Community Edition';
+
+ const groupName = 'Gitlab Org';
+
+ const removeBodyAttributes = () => {
+ const $body = $('body');
+
+ $body.removeAttr('data-page');
+ $body.removeAttr('data-project');
+ $body.removeAttr('data-group');
+ };
+
+ // Add required attributes to body before starting the test.
+ // section would be dashboard|group|project
+ const addBodyAttributes = section => {
+ if (section == null) {
+ section = 'dashboard';
+ }
+
+ const $body = $('body');
+ removeBodyAttributes();
+ switch (section) {
+ case 'dashboard':
+ return $body.attr('data-page', 'root:index');
+ case 'group':
+ $body.attr('data-page', 'groups:show');
+ return $body.data('group', 'gitlab-org');
+ case 'project':
+ $body.attr('data-page', 'projects:show');
+ return $body.data('project', 'gitlab-ce');
+ }
+ };
+
+ const disableProjectIssues = () => {
+ document.querySelector('.js-search-project-options').setAttribute('data-issues-disabled', true);
+ };
+
+ // Mock `gl` object in window for dashboard specific page. App code will need it.
+ const mockDashboardOptions = () => {
+ window.gl || (window.gl = {});
+ return (window.gl.dashboardOptions = {
+ issuesPath: dashboardIssuesPath,
+ mrPath: dashboardMRsPath,
+ });
+ };
+
+ // Mock `gl` object in window for project specific page. App code will need it.
+ const mockProjectOptions = () => {
+ window.gl || (window.gl = {});
+ return (window.gl.projectOptions = {
+ 'gitlab-ce': {
+ issuesPath: projectIssuesPath,
+ mrPath: projectMRsPath,
+ projectName,
+ },
+ });
+ };
+
+ const mockGroupOptions = () => {
+ window.gl || (window.gl = {});
+ return (window.gl.groupOptions = {
+ 'gitlab-org': {
+ issuesPath: groupIssuesPath,
+ mrPath: groupMRsPath,
+ projectName: groupName,
+ },
+ });
+ };
+
+ const assertLinks = (list, issuesPath, mrsPath) => {
+ if (issuesPath) {
+ const issuesAssignedToMeLink = `a[href="${issuesPath}/?assignee_username=${userName}"]`;
+ const issuesIHaveCreatedLink = `a[href="${issuesPath}/?author_username=${userName}"]`;
+
+ expect(list.find(issuesAssignedToMeLink).length).toBe(1);
+ expect(list.find(issuesAssignedToMeLink).text()).toBe('Issues assigned to me');
+ expect(list.find(issuesIHaveCreatedLink).length).toBe(1);
+ expect(list.find(issuesIHaveCreatedLink).text()).toBe("Issues I've created");
+ }
+ const mrsAssignedToMeLink = `a[href="${mrsPath}/?assignee_username=${userName}"]`;
+ const mrsIHaveCreatedLink = `a[href="${mrsPath}/?author_username=${userName}"]`;
+
+ expect(list.find(mrsAssignedToMeLink).length).toBe(1);
+ expect(list.find(mrsAssignedToMeLink).text()).toBe('Merge requests assigned to me');
+ expect(list.find(mrsIHaveCreatedLink).length).toBe(1);
+ expect(list.find(mrsIHaveCreatedLink).text()).toBe("Merge requests I've created");
+ };
+
+ preloadFixtures('static/global_search_input.html');
+ beforeEach(() => {
+ loadFixtures('static/global_search_input.html');
+
+ window.gon = {};
+ window.gon.current_user_id = userId;
+ window.gon.current_username = userName;
+
+ return (widget = initGlobalSearchInput());
+ });
+
+ afterEach(() => {
+ // Undo what we did to the shared <body>
+ removeBodyAttributes();
+ window.gon = {};
+ });
+
+ it('should show Dashboard specific dropdown menu', () => {
+ addBodyAttributes();
+ mockDashboardOptions();
+ widget.searchInput.triggerHandler('focus');
+ const list = widget.wrap.find('.dropdown-menu').find('ul');
+ return assertLinks(list, dashboardIssuesPath, dashboardMRsPath);
+ });
+
+ it('should show Group specific dropdown menu', () => {
+ addBodyAttributes('group');
+ mockGroupOptions();
+ widget.searchInput.triggerHandler('focus');
+ const list = widget.wrap.find('.dropdown-menu').find('ul');
+ return assertLinks(list, groupIssuesPath, groupMRsPath);
+ });
+
+ it('should show Project specific dropdown menu', () => {
+ addBodyAttributes('project');
+ mockProjectOptions();
+ widget.searchInput.triggerHandler('focus');
+ const list = widget.wrap.find('.dropdown-menu').find('ul');
+ return assertLinks(list, projectIssuesPath, projectMRsPath);
+ });
+
+ it('should show only Project mergeRequest dropdown menu items when project issues are disabled', () => {
+ addBodyAttributes('project');
+ disableProjectIssues();
+ mockProjectOptions();
+ widget.searchInput.triggerHandler('focus');
+ const list = widget.wrap.find('.dropdown-menu').find('ul');
+ assertLinks(list, null, projectMRsPath);
+ });
+
+ it('should not show category related menu if there is text in the input', () => {
+ addBodyAttributes('project');
+ mockProjectOptions();
+ widget.searchInput.val('help');
+ widget.searchInput.triggerHandler('focus');
+ const list = widget.wrap.find('.dropdown-menu').find('ul');
+ const link = `a[href='${projectIssuesPath}/?assignee_username=${userName}']`;
+
+ expect(list.find(link).length).toBe(0);
+ });
+
+ it('should not submit the search form when selecting an autocomplete row with the keyboard', () => {
+ const ENTER = 13;
+ const DOWN = 40;
+ addBodyAttributes();
+ mockDashboardOptions(true);
+ const submitSpy = jest.spyOn(document.querySelector('form'), 'submit');
+ widget.searchInput.triggerHandler('focus');
+ widget.wrap.trigger($.Event('keydown', { which: DOWN }));
+ const enterKeyEvent = $.Event('keydown', { which: ENTER });
+ widget.searchInput.trigger(enterKeyEvent);
+ // This does not currently catch failing behavior. For security reasons,
+ // browsers will not trigger default behavior (form submit, in this
+ // example) on JavaScript-created keypresses.
+ expect(submitSpy).not.toHaveBeenCalled();
+ });
+
+ describe('disableDropdown', () => {
+ beforeEach(() => {
+ widget.enableDropdown();
+ });
+
+ it('should close the Dropdown', () => {
+ const toggleSpy = jest.spyOn(widget.dropdownToggle, 'dropdown');
+
+ widget.dropdown.addClass('show');
+ widget.disableDropdown();
+
+ expect(toggleSpy).toHaveBeenCalledWith('toggle');
+ });
+ });
+
+ describe('enableDropdown', () => {
+ it('should open the Dropdown', () => {
+ const toggleSpy = jest.spyOn(widget.dropdownToggle, 'dropdown');
+ widget.enableDropdown();
+
+ expect(toggleSpy).toHaveBeenCalledWith('toggle');
+ });
+ });
+});
diff --git a/spec/frontend/header_spec.js b/spec/frontend/header_spec.js
index 6d2d7976196..467d9678f69 100644
--- a/spec/frontend/header_spec.js
+++ b/spec/frontend/header_spec.js
@@ -60,7 +60,7 @@ describe('Header', () => {
beforeEach(() => {
setFixtures(`
<li class="js-nav-user-dropdown">
- <a class="js-buy-ci-minutes-link" data-track-event="click_buy_ci_minutes" data-track-label="free" data-track-property="user_dropdown">Buy CI minutes</a>
+ <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>
</li>`);
@@ -74,7 +74,7 @@ describe('Header', () => {
unmockTracking();
});
- it('sends a tracking event when the dropdown is opened and contains Buy CI minutes link', () => {
+ it('sends a tracking event when the dropdown is opened and contains Buy Pipeline minutes link', () => {
$('.js-nav-user-dropdown').trigger('shown.bs.dropdown');
expect(trackingSpy).toHaveBeenCalledWith('some:page', 'show_buy_ci_minutes', {
diff --git a/spec/frontend/helpers/dom_shims/element_scroll_to.js b/spec/frontend/helpers/dom_shims/element_scroll_to.js
new file mode 100644
index 00000000000..68f8a115865
--- /dev/null
+++ b/spec/frontend/helpers/dom_shims/element_scroll_to.js
@@ -0,0 +1,6 @@
+Element.prototype.scrollTo = jest.fn().mockImplementation(function scrollTo(x, y) {
+ this.scrollLeft = x;
+ this.scrollTop = y;
+
+ this.dispatchEvent(new Event('scroll'));
+});
diff --git a/spec/frontend/helpers/dom_shims/image_element_properties.js b/spec/frontend/helpers/dom_shims/image_element_properties.js
index 525246e6ade..d94c157e44d 100644
--- a/spec/frontend/helpers/dom_shims/image_element_properties.js
+++ b/spec/frontend/helpers/dom_shims/image_element_properties.js
@@ -1,6 +1,6 @@
Object.defineProperty(global.HTMLImageElement.prototype, 'src', {
get() {
- return this.$_jest_src;
+ return this.$_jest_src || this.getAttribute('src');
},
set(val) {
this.$_jest_src = val;
diff --git a/spec/frontend/helpers/dom_shims/index.js b/spec/frontend/helpers/dom_shims/index.js
index 17a2090d2f1..d18bb94c107 100644
--- a/spec/frontend/helpers/dom_shims/index.js
+++ b/spec/frontend/helpers/dom_shims/index.js
@@ -1,8 +1,10 @@
import './element_scroll_into_view';
import './element_scroll_by';
+import './element_scroll_to';
import './form_element';
import './get_client_rects';
import './inner_text';
+import './mutation_observer';
import './window_scroll_to';
import './scroll_by';
import './size_properties';
diff --git a/spec/frontend/helpers/dom_shims/mutation_observer.js b/spec/frontend/helpers/dom_shims/mutation_observer.js
new file mode 100644
index 00000000000..68c494f19ea
--- /dev/null
+++ b/spec/frontend/helpers/dom_shims/mutation_observer.js
@@ -0,0 +1,7 @@
+/* eslint-disable class-methods-use-this */
+class MutationObserverStub {
+ disconnect() {}
+ observe() {}
+}
+
+global.MutationObserver = MutationObserverStub;
diff --git a/spec/frontend/helpers/local_storage_helper.js b/spec/frontend/helpers/local_storage_helper.js
index 48e66b11767..a66c31d1353 100644
--- a/spec/frontend/helpers/local_storage_helper.js
+++ b/spec/frontend/helpers/local_storage_helper.js
@@ -28,12 +28,20 @@ const useLocalStorage = fn => {
/**
* Create an object with the localStorage interface but `jest.fn()` implementations.
*/
-export const createLocalStorageSpy = () => ({
- clear: jest.fn(),
- getItem: jest.fn(),
- setItem: jest.fn(),
- removeItem: jest.fn(),
-});
+export const createLocalStorageSpy = () => {
+ let storage = {};
+
+ return {
+ clear: jest.fn(() => {
+ storage = {};
+ }),
+ getItem: jest.fn(key => storage[key]),
+ setItem: jest.fn((key, value) => {
+ storage[key] = value;
+ }),
+ removeItem: jest.fn(key => delete storage[key]),
+ };
+};
/**
* Before each test, overwrite `window.localStorage` with a spy implementation.
diff --git a/spec/frontend/helpers/local_storage_helper_spec.js b/spec/frontend/helpers/local_storage_helper_spec.js
new file mode 100644
index 00000000000..18aec0f329a
--- /dev/null
+++ b/spec/frontend/helpers/local_storage_helper_spec.js
@@ -0,0 +1,21 @@
+import { useLocalStorageSpy } from './local_storage_helper';
+
+useLocalStorageSpy();
+
+describe('localStorage helper', () => {
+ it('mocks localStorage but works exactly like original localStorage', () => {
+ localStorage.setItem('test', 'testing');
+ localStorage.setItem('test2', 'testing');
+
+ expect(localStorage.getItem('test')).toBe('testing');
+
+ localStorage.removeItem('test', 'testing');
+
+ expect(localStorage.getItem('test')).toBeUndefined();
+ expect(localStorage.getItem('test2')).toBe('testing');
+
+ localStorage.clear();
+
+ expect(localStorage.getItem('test2')).toBeUndefined();
+ });
+});
diff --git a/spec/frontend/helpers/mock_dom_observer.js b/spec/frontend/helpers/mock_dom_observer.js
new file mode 100644
index 00000000000..7aac51f6264
--- /dev/null
+++ b/spec/frontend/helpers/mock_dom_observer.js
@@ -0,0 +1,94 @@
+/* eslint-disable class-methods-use-this, max-classes-per-file */
+import { isMatch } from 'lodash';
+
+/**
+ * This class gives us a JSDom friendly DOM observer which we can manually trigger in tests
+ *
+ * Use this in place of MutationObserver or IntersectionObserver
+ */
+class MockObserver {
+ constructor(cb) {
+ this.$_cb = cb;
+ this.$_observers = [];
+ }
+
+ observe(node, options = {}) {
+ this.$_observers.push([node, options]);
+ }
+
+ disconnect() {
+ this.$_observers = [];
+ }
+
+ takeRecords() {}
+
+ // eslint-disable-next-line babel/camelcase
+ $_triggerObserve(node, { entry = {}, options = {} } = {}) {
+ if (this.$_hasObserver(node, options)) {
+ this.$_cb([{ target: node, ...entry }]);
+ }
+ }
+
+ // eslint-disable-next-line babel/camelcase
+ $_hasObserver(node, options = {}) {
+ return this.$_observers.some(
+ ([obvNode, obvOptions]) => node === obvNode && isMatch(options, obvOptions),
+ );
+ }
+}
+
+class MockIntersectionObserver extends MockObserver {
+ unobserve(node) {
+ this.$_observers = this.$_observers.filter(([obvNode]) => node === obvNode);
+ }
+}
+
+/**
+ * Use this function to setup a mock observer instance in place of the given DOM Observer
+ *
+ * Example:
+ * ```
+ * describe('', () => {
+ * const { trigger: triggerMutate } = useMockMutationObserver();
+ *
+ * it('test', () => {
+ * trigger(el, { options: { childList: true }, entry: { } });
+ * });
+ * })
+ * ```
+ *
+ * @param {String} key
+ */
+const useMockObserver = (key, createMock) => {
+ let mockObserver;
+ let origObserver;
+
+ beforeEach(() => {
+ origObserver = global[key];
+ global[key] = jest.fn().mockImplementation((...args) => {
+ mockObserver = createMock(...args);
+ return mockObserver;
+ });
+ });
+
+ afterEach(() => {
+ mockObserver = null;
+ global[key] = origObserver;
+ });
+
+ const trigger = (...args) => {
+ if (!mockObserver) {
+ return;
+ }
+
+ mockObserver.$_triggerObserve(...args);
+ };
+
+ return { trigger };
+};
+
+export const useMockIntersectionObserver = () =>
+ useMockObserver('IntersectionObserver', (...args) => new MockIntersectionObserver(...args));
+
+export const useMockMutationObserver = () =>
+ useMockObserver('MutationObserver', (...args) => new MockObserver(...args));
diff --git a/spec/frontend/helpers/mock_window_location_helper.js b/spec/frontend/helpers/mock_window_location_helper.js
new file mode 100644
index 00000000000..175044d1fce
--- /dev/null
+++ b/spec/frontend/helpers/mock_window_location_helper.js
@@ -0,0 +1,43 @@
+/**
+ * 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
+ *
+ * @param {() => any} fn Function that returns the object to use for window.location
+ */
+const useMockLocation = fn => {
+ const origWindowLocation = window.location;
+ let currentWindowLocation;
+
+ Object.defineProperty(window, 'location', {
+ get: () => currentWindowLocation,
+ });
+
+ beforeEach(() => {
+ currentWindowLocation = fn();
+ });
+
+ afterEach(() => {
+ currentWindowLocation = origWindowLocation;
+ });
+};
+
+/**
+ * Create an object with the location interface but `jest.fn()` implementations.
+ */
+export const createWindowLocationSpy = () => {
+ return {
+ assign: jest.fn(),
+ reload: jest.fn(),
+ replace: jest.fn(),
+ toString: jest.fn(),
+ };
+};
+
+/**
+ * Before each test, overwrite `window.location` with a spy implementation.
+ */
+export const useMockLocationHelper = () => useMockLocation(createWindowLocationSpy);
diff --git a/spec/frontend/helpers/scroll_into_view_promise.js b/spec/frontend/helpers/scroll_into_view_promise.js
deleted file mode 100644
index 0edea2103da..00000000000
--- a/spec/frontend/helpers/scroll_into_view_promise.js
+++ /dev/null
@@ -1,28 +0,0 @@
-export default function scrollIntoViewPromise(intersectionTarget, timeout = 100, maxTries = 5) {
- return new Promise((resolve, reject) => {
- let intersectionObserver;
- let retry = 0;
-
- const intervalId = setInterval(() => {
- if (retry >= maxTries) {
- intersectionObserver.disconnect();
- clearInterval(intervalId);
- reject(new Error(`Could not scroll target into viewPort within ${timeout * maxTries} ms`));
- }
- retry += 1;
- intersectionTarget.scrollIntoView();
- }, timeout);
-
- intersectionObserver = new IntersectionObserver(entries => {
- if (entries[0].isIntersecting) {
- intersectionObserver.disconnect();
- clearInterval(intervalId);
- resolve();
- }
- });
-
- intersectionObserver.observe(intersectionTarget);
-
- intersectionTarget.scrollIntoView();
- });
-}
diff --git a/spec/frontend/helpers/set_window_location_helper_spec.js b/spec/frontend/helpers/set_window_location_helper_spec.js
index 2a2c024c824..da609b6bbf0 100644
--- a/spec/frontend/helpers/set_window_location_helper_spec.js
+++ b/spec/frontend/helpers/set_window_location_helper_spec.js
@@ -33,7 +33,7 @@ describe('setWindowLocation', () => {
it.each([null, 1, undefined, false, '', 'gitlab.com'])(
'throws an error when called with an invalid url: "%s"',
invalidUrl => {
- expect(() => setWindowLocation(invalidUrl)).toThrow(new TypeError('Invalid URL'));
+ expect(() => setWindowLocation(invalidUrl)).toThrow(/Invalid URL/);
expect(window.location).toBe(originalLocation);
},
);
diff --git a/spec/frontend/helpers/vue_mock_directive.js b/spec/frontend/helpers/vue_mock_directive.js
new file mode 100644
index 00000000000..699fe3eab26
--- /dev/null
+++ b/spec/frontend/helpers/vue_mock_directive.js
@@ -0,0 +1,17 @@
+export const getKey = name => `$_gl_jest_${name}`;
+
+export const getBinding = (el, name) => el[getKey(name)];
+
+export const createMockDirective = () => ({
+ bind(el, { name, value, arg, modifiers }) {
+ el[getKey(name)] = {
+ value,
+ arg,
+ modifiers,
+ };
+ },
+
+ unbind(el, { name }) {
+ delete el[getKey(name)];
+ },
+});
diff --git a/spec/frontend/helpers/wait_for_attribute_change.js b/spec/frontend/helpers/wait_for_attribute_change.js
deleted file mode 100644
index 8f22d569222..00000000000
--- a/spec/frontend/helpers/wait_for_attribute_change.js
+++ /dev/null
@@ -1,16 +0,0 @@
-export default (domElement, attributes, timeout = 1500) =>
- new Promise((resolve, reject) => {
- let observer;
- const timeoutId = setTimeout(() => {
- observer.disconnect();
- reject(new Error(`Could not see an attribute update within ${timeout} ms`));
- }, timeout);
-
- observer = new MutationObserver(() => {
- clearTimeout(timeoutId);
- observer.disconnect();
- resolve();
- });
-
- observer.observe(domElement, { attributes: true, attributeFilter: attributes });
- });
diff --git a/spec/frontend/ide/commit_icon_spec.js b/spec/frontend/ide/commit_icon_spec.js
new file mode 100644
index 00000000000..90b8e34497c
--- /dev/null
+++ b/spec/frontend/ide/commit_icon_spec.js
@@ -0,0 +1,45 @@
+import { commitItemIconMap } from '~/ide/constants';
+import { decorateData } from '~/ide/stores/utils';
+import getCommitIconMap from '~/ide/commit_icon';
+
+const createFile = (name = 'name', id = name, type = '', parent = null) =>
+ decorateData({
+ id,
+ type,
+ icon: 'icon',
+ url: 'url',
+ name,
+ path: parent ? `${parent.path}/${name}` : name,
+ parentPath: parent ? parent.path : '',
+ lastCommit: {},
+ });
+
+describe('getCommitIconMap', () => {
+ let entry;
+
+ beforeEach(() => {
+ entry = createFile('Entry item');
+ });
+
+ it('renders "deleted" icon for deleted entries', () => {
+ entry.deleted = true;
+ expect(getCommitIconMap(entry)).toEqual(commitItemIconMap.deleted);
+ });
+
+ it('renders "addition" icon for temp entries', () => {
+ entry.tempFile = true;
+ expect(getCommitIconMap(entry)).toEqual(commitItemIconMap.addition);
+ });
+
+ it('renders "modified" icon for newly-renamed entries', () => {
+ entry.prevPath = 'foo/bar';
+ entry.tempFile = false;
+ expect(getCommitIconMap(entry)).toEqual(commitItemIconMap.modified);
+ });
+
+ it('renders "modified" icon even for temp entries if they are newly-renamed', () => {
+ entry.prevPath = 'foo/bar';
+ entry.tempFile = true;
+ expect(getCommitIconMap(entry)).toEqual(commitItemIconMap.modified);
+ });
+});
diff --git a/spec/frontend/ide/components/branches/item_spec.js b/spec/frontend/ide/components/branches/item_spec.js
index 138443b715e..d8175025755 100644
--- a/spec/frontend/ide/components/branches/item_spec.js
+++ b/spec/frontend/ide/components/branches/item_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
-import router from '~/ide/ide_router';
+import { createStore } from '~/ide/stores';
+import { createRouter } from '~/ide/ide_router';
import Item from '~/ide/components/branches/item.vue';
import Icon from '~/vue_shared/components/icon.vue';
import Timeago from '~/vue_shared/components/time_ago_tooltip.vue';
@@ -13,6 +14,8 @@ const TEST_PROJECT_ID = projectData.name_with_namespace;
describe('IDE branch item', () => {
let wrapper;
+ let store;
+ let router;
function createComponent(props = {}) {
wrapper = shallowMount(Item, {
@@ -22,9 +25,15 @@ describe('IDE branch item', () => {
isActive: false,
...props,
},
+ router,
});
}
+ beforeEach(() => {
+ store = createStore();
+ router = createRouter(store);
+ });
+
afterEach(() => {
wrapper.destroy();
});
diff --git a/spec/frontend/ide/components/commit_sidebar/form_spec.js b/spec/frontend/ide/components/commit_sidebar/form_spec.js
index 129180bb46e..c62df4a3795 100644
--- a/spec/frontend/ide/components/commit_sidebar/form_spec.js
+++ b/spec/frontend/ide/components/commit_sidebar/form_spec.js
@@ -5,11 +5,14 @@ import store from '~/ide/stores';
import CommitForm from '~/ide/components/commit_sidebar/form.vue';
import { leftSidebarViews } from '~/ide/constants';
import { resetStore } from '../../helpers';
+import waitForPromises from 'helpers/wait_for_promises';
describe('IDE commit form', () => {
const Component = Vue.extend(CommitForm);
let vm;
+ const beginCommitButton = () => vm.$el.querySelector('[data-testid="begin-commit-button"]');
+
beforeEach(() => {
store.state.changedFiles.push('test');
store.state.currentProjectId = 'abcproject';
@@ -25,8 +28,15 @@ describe('IDE commit form', () => {
resetStore(vm.$store);
});
- it('enables button when has changes', () => {
- expect(vm.$el.querySelector('[disabled]')).toBe(null);
+ it('enables begin commit button when there are changes', () => {
+ expect(beginCommitButton()).not.toHaveAttr('disabled');
+ });
+
+ it('disables begin commit button when there are no changes', async () => {
+ store.state.changedFiles = [];
+ await vm.$nextTick();
+
+ expect(beginCommitButton()).toHaveAttr('disabled');
});
describe('compact', () => {
@@ -37,8 +47,8 @@ describe('IDE commit form', () => {
});
it('renders commit button in compact mode', () => {
- expect(vm.$el.querySelector('.btn-primary')).not.toBeNull();
- expect(vm.$el.querySelector('.btn-primary').textContent).toContain('Commit');
+ expect(beginCommitButton()).not.toBeNull();
+ expect(beginCommitButton().textContent).toContain('Commit');
});
it('does not render form', () => {
@@ -54,7 +64,7 @@ describe('IDE commit form', () => {
});
it('shows form when clicking commit button', () => {
- vm.$el.querySelector('.btn-primary').click();
+ beginCommitButton().click();
return vm.$nextTick(() => {
expect(vm.$el.querySelector('form')).not.toBeNull();
@@ -62,31 +72,117 @@ describe('IDE commit form', () => {
});
it('toggles activity bar view when clicking commit button', () => {
- vm.$el.querySelector('.btn-primary').click();
+ beginCommitButton().click();
return vm.$nextTick(() => {
expect(store.state.currentActivityView).toBe(leftSidebarViews.commit.name);
});
});
- it('collapses if lastCommitMsg is set to empty and current view is not commit view', () => {
+ it('collapses if lastCommitMsg is set to empty and current view is not commit view', async () => {
store.state.lastCommitMsg = 'abc';
store.state.currentActivityView = leftSidebarViews.edit.name;
+ await vm.$nextTick();
- return vm
- .$nextTick()
- .then(() => {
- // if commit message is set, form is uncollapsed
- expect(vm.isCompact).toBe(false);
+ // if commit message is set, form is uncollapsed
+ expect(vm.isCompact).toBe(false);
- store.state.lastCommitMsg = '';
+ store.state.lastCommitMsg = '';
+ await vm.$nextTick();
- return vm.$nextTick();
- })
- .then(() => {
- // collapsed when set to empty
- expect(vm.isCompact).toBe(true);
- });
+ // collapsed when set to empty
+ expect(vm.isCompact).toBe(true);
+ });
+
+ it('collapses if in commit view but there are no changes and vice versa', async () => {
+ store.state.currentActivityView = leftSidebarViews.commit.name;
+ await vm.$nextTick();
+
+ // expanded by default if there are changes
+ expect(vm.isCompact).toBe(false);
+
+ store.state.changedFiles = [];
+ await vm.$nextTick();
+
+ expect(vm.isCompact).toBe(true);
+
+ store.state.changedFiles.push('test');
+ await vm.$nextTick();
+
+ // uncollapsed once again
+ expect(vm.isCompact).toBe(false);
+ });
+
+ it('collapses if switched from commit view to edit view and vice versa', async () => {
+ store.state.currentActivityView = leftSidebarViews.edit.name;
+ await vm.$nextTick();
+
+ expect(vm.isCompact).toBe(true);
+
+ store.state.currentActivityView = leftSidebarViews.commit.name;
+ await vm.$nextTick();
+
+ expect(vm.isCompact).toBe(false);
+
+ store.state.currentActivityView = leftSidebarViews.edit.name;
+ await vm.$nextTick();
+
+ expect(vm.isCompact).toBe(true);
+ });
+
+ describe('when window height is less than MAX_WINDOW_HEIGHT', () => {
+ let oldHeight;
+
+ beforeEach(() => {
+ oldHeight = window.innerHeight;
+ window.innerHeight = 700;
+ });
+
+ afterEach(() => {
+ window.innerHeight = oldHeight;
+ });
+
+ it('stays collapsed when switching from edit view to commit view and back', async () => {
+ store.state.currentActivityView = leftSidebarViews.edit.name;
+ await vm.$nextTick();
+
+ expect(vm.isCompact).toBe(true);
+
+ store.state.currentActivityView = leftSidebarViews.commit.name;
+ await vm.$nextTick();
+
+ expect(vm.isCompact).toBe(true);
+
+ store.state.currentActivityView = leftSidebarViews.edit.name;
+ await vm.$nextTick();
+
+ expect(vm.isCompact).toBe(true);
+ });
+
+ it('stays uncollapsed if changes are added or removed', async () => {
+ store.state.currentActivityView = leftSidebarViews.commit.name;
+ await vm.$nextTick();
+
+ expect(vm.isCompact).toBe(true);
+
+ store.state.changedFiles = [];
+ await vm.$nextTick();
+
+ expect(vm.isCompact).toBe(true);
+
+ store.state.changedFiles.push('test');
+ await vm.$nextTick();
+
+ expect(vm.isCompact).toBe(true);
+ });
+
+ it('uncollapses when clicked on Commit button in the edit view', async () => {
+ store.state.currentActivityView = leftSidebarViews.edit.name;
+ beginCommitButton().click();
+ await waitForPromises();
+
+ expect(vm.isCompact).toBe(false);
+ });
});
});
@@ -118,7 +214,7 @@ describe('IDE commit form', () => {
});
it('always opens itself in full view current activity view is not commit view when clicking commit button', () => {
- vm.$el.querySelector('.btn-primary').click();
+ beginCommitButton().click();
return vm.$nextTick(() => {
expect(store.state.currentActivityView).toBe(leftSidebarViews.commit.name);
diff --git a/spec/frontend/ide/components/commit_sidebar/list_item_spec.js b/spec/frontend/ide/components/commit_sidebar/list_item_spec.js
index ebb41448905..7ce628d4da7 100644
--- a/spec/frontend/ide/components/commit_sidebar/list_item_spec.js
+++ b/spec/frontend/ide/components/commit_sidebar/list_item_spec.js
@@ -1,17 +1,22 @@
import Vue from 'vue';
import { trimText } from 'helpers/text_helper';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
-import store from '~/ide/stores';
+import { createStore } from '~/ide/stores';
import listItem from '~/ide/components/commit_sidebar/list_item.vue';
-import router from '~/ide/ide_router';
-import { file, resetStore } from '../../helpers';
+import { createRouter } from '~/ide/ide_router';
+import { file } from '../../helpers';
describe('Multi-file editor commit sidebar list item', () => {
let vm;
let f;
let findPathEl;
+ let store;
+ let router;
beforeEach(() => {
+ store = createStore();
+ router = createRouter(store);
+
const Component = Vue.extend(listItem);
f = file('test-file');
@@ -28,8 +33,6 @@ describe('Multi-file editor commit sidebar list item', () => {
afterEach(() => {
vm.$destroy();
-
- resetStore(store);
});
const findPathText = () => trimText(findPathEl.textContent);
diff --git a/spec/frontend/ide/components/commit_sidebar/message_field_spec.js b/spec/frontend/ide/components/commit_sidebar/message_field_spec.js
new file mode 100644
index 00000000000..d6ea8b9a4bd
--- /dev/null
+++ b/spec/frontend/ide/components/commit_sidebar/message_field_spec.js
@@ -0,0 +1,170 @@
+import Vue from 'vue';
+import createComponent from 'helpers/vue_mount_component_helper';
+import CommitMessageField from '~/ide/components/commit_sidebar/message_field.vue';
+
+describe('IDE commit message field', () => {
+ const Component = Vue.extend(CommitMessageField);
+ let vm;
+
+ beforeEach(() => {
+ setFixtures('<div id="app"></div>');
+
+ vm = createComponent(
+ Component,
+ {
+ text: '',
+ placeholder: 'testing',
+ },
+ '#app',
+ );
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('adds is-focused class on focus', done => {
+ vm.$el.querySelector('textarea').focus();
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelector('.is-focused')).not.toBeNull();
+
+ done();
+ });
+ });
+
+ it('removed is-focused class on blur', done => {
+ vm.$el.querySelector('textarea').focus();
+
+ vm.$nextTick()
+ .then(() => {
+ expect(vm.$el.querySelector('.is-focused')).not.toBeNull();
+
+ vm.$el.querySelector('textarea').blur();
+
+ return vm.$nextTick();
+ })
+ .then(() => {
+ expect(vm.$el.querySelector('.is-focused')).toBeNull();
+
+ done();
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('emits input event on input', () => {
+ jest.spyOn(vm, '$emit').mockImplementation();
+
+ const textarea = vm.$el.querySelector('textarea');
+ textarea.value = 'testing';
+
+ textarea.dispatchEvent(new Event('input'));
+
+ expect(vm.$emit).toHaveBeenCalledWith('input', 'testing');
+ });
+
+ describe('highlights', () => {
+ describe('subject line', () => {
+ it('does not highlight less than 50 characters', done => {
+ vm.text = 'text less than 50 chars';
+
+ vm.$nextTick()
+ .then(() => {
+ expect(vm.$el.querySelector('.highlights span').textContent).toContain(
+ 'text less than 50 chars',
+ );
+
+ expect(vm.$el.querySelector('mark').style.display).toBe('none');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('highlights characters over 50 length', done => {
+ vm.text =
+ 'text less than 50 chars that should not highlighted. text more than 50 should be highlighted';
+
+ vm.$nextTick()
+ .then(() => {
+ expect(vm.$el.querySelector('.highlights span').textContent).toContain(
+ 'text less than 50 chars that should not highlighte',
+ );
+
+ expect(vm.$el.querySelector('mark').style.display).not.toBe('none');
+ expect(vm.$el.querySelector('mark').textContent).toBe(
+ 'd. text more than 50 should be highlighted',
+ );
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('body text', () => {
+ it('does not highlight body text less tan 72 characters', done => {
+ vm.text = 'subject line\nbody content';
+
+ vm.$nextTick()
+ .then(() => {
+ expect(vm.$el.querySelectorAll('.highlights span').length).toBe(2);
+ expect(vm.$el.querySelectorAll('mark')[1].style.display).toBe('none');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('highlights body text more than 72 characters', done => {
+ vm.text =
+ 'subject line\nbody content that will be highlighted when it is more than 72 characters in length';
+
+ vm.$nextTick()
+ .then(() => {
+ expect(vm.$el.querySelectorAll('.highlights span').length).toBe(2);
+ expect(vm.$el.querySelectorAll('mark')[1].style.display).not.toBe('none');
+ expect(vm.$el.querySelectorAll('mark')[1].textContent).toBe(' in length');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('highlights body text & subject line', done => {
+ vm.text =
+ 'text less than 50 chars that should not highlighted\nbody content that will be highlighted when it is more than 72 characters in length';
+
+ vm.$nextTick()
+ .then(() => {
+ expect(vm.$el.querySelectorAll('.highlights span').length).toBe(2);
+ expect(vm.$el.querySelectorAll('mark').length).toBe(2);
+
+ expect(vm.$el.querySelectorAll('mark')[0].textContent).toContain('d');
+ expect(vm.$el.querySelectorAll('mark')[1].textContent).toBe(' in length');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+ });
+
+ describe('scrolling textarea', () => {
+ it('updates transform of highlights', done => {
+ vm.text = 'subject line\n\n\n\n\n\n\n\n\n\n\nbody content';
+
+ vm.$nextTick()
+ .then(() => {
+ vm.$el.querySelector('textarea').scrollTo(0, 50);
+
+ vm.handleScroll();
+ })
+ .then(vm.$nextTick)
+ .then(() => {
+ expect(vm.scrollTop).toBe(50);
+ expect(vm.$el.querySelector('.highlights').style.transform).toBe(
+ 'translate3d(0, -50px, 0)',
+ );
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+});
diff --git a/spec/frontend/ide/components/ide_sidebar_nav_spec.js b/spec/frontend/ide/components/ide_sidebar_nav_spec.js
new file mode 100644
index 00000000000..49d476b56e4
--- /dev/null
+++ b/spec/frontend/ide/components/ide_sidebar_nav_spec.js
@@ -0,0 +1,118 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlIcon } from '@gitlab/ui';
+import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
+import IdeSidebarNav from '~/ide/components/ide_sidebar_nav.vue';
+import { SIDE_RIGHT, SIDE_LEFT } from '~/ide/constants';
+
+const TEST_TABS = [
+ {
+ title: 'Lorem',
+ icon: 'angle-up',
+ views: [{ name: 'lorem-1' }, { name: 'lorem-2' }],
+ },
+ {
+ title: 'Ipsum',
+ icon: 'angle-down',
+ views: [{ name: 'ipsum-1' }, { name: 'ipsum-2' }],
+ },
+];
+const TEST_CURRENT_INDEX = 1;
+const TEST_CURRENT_VIEW = TEST_TABS[TEST_CURRENT_INDEX].views[1].name;
+const TEST_OPEN_VIEW = TEST_TABS[TEST_CURRENT_INDEX].views[0];
+
+describe('ide/components/ide_sidebar_nav', () => {
+ let wrapper;
+
+ const createComponent = (props = {}) => {
+ if (wrapper) {
+ throw new Error('wrapper already exists');
+ }
+
+ wrapper = shallowMount(IdeSidebarNav, {
+ propsData: {
+ tabs: TEST_TABS,
+ currentView: TEST_CURRENT_VIEW,
+ isOpen: false,
+ ...props,
+ },
+ directives: {
+ tooltip: createMockDirective(),
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ const findButtons = () => wrapper.findAll('li button');
+ const findButtonsData = () =>
+ findButtons().wrappers.map(button => {
+ return {
+ title: button.attributes('title'),
+ ariaLabel: button.attributes('aria-label'),
+ classes: button.classes(),
+ qaSelector: button.attributes('data-qa-selector'),
+ icon: button.find(GlIcon).props('name'),
+ tooltip: getBinding(button.element, 'tooltip').value,
+ };
+ });
+ const clickTab = () =>
+ findButtons()
+ .at(TEST_CURRENT_INDEX)
+ .trigger('click');
+
+ describe.each`
+ isOpen | side | otherSide | classes | classesObj | emitEvent | emitArg
+ ${false} | ${SIDE_LEFT} | ${SIDE_RIGHT} | ${[]} | ${{}} | ${'open'} | ${[TEST_OPEN_VIEW]}
+ ${false} | ${SIDE_RIGHT} | ${SIDE_LEFT} | ${['is-right']} | ${{}} | ${'open'} | ${[TEST_OPEN_VIEW]}
+ ${true} | ${SIDE_RIGHT} | ${SIDE_LEFT} | ${['is-right']} | ${{ [TEST_CURRENT_INDEX]: ['active'] }} | ${'close'} | ${[]}
+ `(
+ 'with side = $side, isOpen = $isOpen',
+ ({ isOpen, side, otherSide, classes, classesObj, emitEvent, emitArg }) => {
+ let bsTooltipHide;
+
+ beforeEach(() => {
+ createComponent({ isOpen, side });
+
+ bsTooltipHide = jest.fn();
+ wrapper.vm.$root.$on('bv::hide::tooltip', bsTooltipHide);
+ });
+
+ it('renders buttons', () => {
+ expect(findButtonsData()).toEqual(
+ TEST_TABS.map((tab, index) => ({
+ title: tab.title,
+ ariaLabel: tab.title,
+ classes: ['ide-sidebar-link', ...classes, ...(classesObj[index] || [])],
+ qaSelector: `${tab.title.toLowerCase()}_tab_button`,
+ icon: tab.icon,
+ tooltip: {
+ container: 'body',
+ placement: otherSide,
+ },
+ })),
+ );
+ });
+
+ it('when tab clicked, emits event', () => {
+ expect(wrapper.emitted()).toEqual({});
+
+ clickTab();
+
+ expect(wrapper.emitted()).toEqual({
+ [emitEvent]: [emitArg],
+ });
+ });
+
+ it('when tab clicked, hides tooltip', () => {
+ expect(bsTooltipHide).not.toHaveBeenCalled();
+
+ clickTab();
+
+ expect(bsTooltipHide).toHaveBeenCalled();
+ });
+ },
+ );
+});
diff --git a/spec/frontend/ide/components/ide_spec.js b/spec/frontend/ide/components/ide_spec.js
index 78a280e6304..efc1d984dec 100644
--- a/spec/frontend/ide/components/ide_spec.js
+++ b/spec/frontend/ide/components/ide_spec.js
@@ -1,11 +1,18 @@
import Vue from 'vue';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
-import store from '~/ide/stores';
+import { createStore } from '~/ide/stores';
import ide from '~/ide/components/ide.vue';
import { file, resetStore } from '../helpers';
import { projectData } from '../mock_data';
+import extendStore from '~/ide/stores/extend';
+
+let store;
function bootstrap(projData) {
+ store = createStore();
+
+ extendStore(store, document.createElement('div'));
+
const Component = Vue.extend(ide);
store.state.currentProjectId = 'abcproject';
diff --git a/spec/frontend/ide/components/ide_status_list_spec.js b/spec/frontend/ide/components/ide_status_list_spec.js
index 99c27ca30fb..847464ed806 100644
--- a/spec/frontend/ide/components/ide_status_list_spec.js
+++ b/spec/frontend/ide/components/ide_status_list_spec.js
@@ -1,13 +1,14 @@
import Vuex from 'vuex';
import { createLocalVue, shallowMount } from '@vue/test-utils';
import IdeStatusList from '~/ide/components/ide_status_list.vue';
+import TerminalSyncStatusSafe from '~/ide/components/terminal_sync/terminal_sync_status_safe.vue';
const TEST_FILE = {
name: 'lorem.md',
- eol: 'LF',
editorRow: 3,
editorColumn: 23,
fileLanguage: 'markdown',
+ content: 'abc\nndef',
};
const localVue = createLocalVue();
@@ -55,7 +56,8 @@ describe('ide/components/ide_status_list', () => {
});
it('shows file eol', () => {
- expect(wrapper.text()).toContain(TEST_FILE.name);
+ expect(wrapper.text()).not.toContain('CRLF');
+ expect(wrapper.text()).toContain('LF');
});
it('shows file editor position', () => {
@@ -78,13 +80,9 @@ describe('ide/components/ide_status_list', () => {
});
});
- it('adds slot as child of list', () => {
- createComponent({
- slots: {
- default: ['<div class="js-test">Hello</div>', '<div class="js-test">World</div>'],
- },
- });
+ it('renders terminal sync status', () => {
+ createComponent();
- expect(wrapper.find('.ide-status-list').findAll('.js-test').length).toEqual(2);
+ expect(wrapper.find(TerminalSyncStatusSafe).exists()).toBe(true);
});
});
diff --git a/spec/frontend/ide/components/jobs/__snapshots__/stage_spec.js.snap b/spec/frontend/ide/components/jobs/__snapshots__/stage_spec.js.snap
index db5175c3f7b..bdd3d439fd4 100644
--- a/spec/frontend/ide/components/jobs/__snapshots__/stage_spec.js.snap
+++ b/spec/frontend/ide/components/jobs/__snapshots__/stage_spec.js.snap
@@ -14,7 +14,7 @@ exports[`IDE pipeline stage renders stage details & icon 1`] = `
/>
<strong
- class="prepend-left-8 text-truncate"
+ class="gl-ml-3 text-truncate"
data-container="body"
data-original-title=""
title=""
@@ -25,7 +25,7 @@ exports[`IDE pipeline stage renders stage details & icon 1`] = `
</strong>
<div
- class="append-right-8 prepend-left-4"
+ class="gl-mr-3 gl-ml-2"
>
<span
class="badge badge-pill"
diff --git a/spec/frontend/ide/components/jobs/detail_spec.js b/spec/frontend/ide/components/jobs/detail_spec.js
new file mode 100644
index 00000000000..8f3815d5aab
--- /dev/null
+++ b/spec/frontend/ide/components/jobs/detail_spec.js
@@ -0,0 +1,187 @@
+import Vue from 'vue';
+import JobDetail from '~/ide/components/jobs/detail.vue';
+import { createStore } from '~/ide/stores';
+import { createComponentWithStore } from '../../../helpers/vue_mount_component_helper';
+import { jobs } from '../../mock_data';
+import { TEST_HOST } from 'helpers/test_constants';
+
+describe('IDE jobs detail view', () => {
+ let vm;
+
+ const createComponent = () => {
+ const store = createStore();
+
+ store.state.pipelines.detailJob = {
+ ...jobs[0],
+ isLoading: true,
+ output: 'testing',
+ rawPath: `${TEST_HOST}/raw`,
+ };
+
+ return createComponentWithStore(Vue.extend(JobDetail), store);
+ };
+
+ beforeEach(() => {
+ vm = createComponent();
+
+ jest.spyOn(vm, 'fetchJobTrace').mockResolvedValue();
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('mounted', () => {
+ beforeEach(() => {
+ vm = vm.$mount();
+ });
+
+ it('calls fetchJobTrace', () => {
+ expect(vm.fetchJobTrace).toHaveBeenCalled();
+ });
+
+ it('scrolls to bottom', () => {
+ expect(vm.$refs.buildTrace.scrollTo).toHaveBeenCalled();
+ });
+
+ it('renders job output', () => {
+ expect(vm.$el.querySelector('.bash').textContent).toContain('testing');
+ });
+
+ it('renders empty message output', done => {
+ vm.$store.state.pipelines.detailJob.output = '';
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelector('.bash').textContent).toContain('No messages were logged');
+
+ done();
+ });
+ });
+
+ it('renders loading icon', () => {
+ expect(vm.$el.querySelector('.build-loader-animation')).not.toBe(null);
+ expect(vm.$el.querySelector('.build-loader-animation').style.display).toBe('');
+ });
+
+ it('hides output when loading', () => {
+ expect(vm.$el.querySelector('.bash')).not.toBe(null);
+ expect(vm.$el.querySelector('.bash').style.display).toBe('none');
+ });
+
+ it('hide loading icon when isLoading is false', done => {
+ vm.$store.state.pipelines.detailJob.isLoading = false;
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelector('.build-loader-animation').style.display).toBe('none');
+
+ done();
+ });
+ });
+
+ it('resets detailJob when clicking header button', () => {
+ jest.spyOn(vm, 'setDetailJob').mockImplementation();
+
+ vm.$el.querySelector('.btn').click();
+
+ expect(vm.setDetailJob).toHaveBeenCalledWith(null);
+ });
+
+ it('renders raw path link', () => {
+ expect(vm.$el.querySelector('.controllers-buttons').getAttribute('href')).toBe(
+ `${TEST_HOST}/raw`,
+ );
+ });
+ });
+
+ describe('scroll buttons', () => {
+ beforeEach(() => {
+ vm = createComponent();
+ jest.spyOn(vm, 'fetchJobTrace').mockResolvedValue();
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it.each`
+ fnName | btnName | scrollPos
+ ${'scrollDown'} | ${'down'} | ${0}
+ ${'scrollUp'} | ${'up'} | ${1}
+ `('triggers $fnName when clicking $btnName button', ({ fnName, scrollPos }) => {
+ jest.spyOn(vm, fnName).mockImplementation();
+
+ vm = vm.$mount();
+
+ vm.scrollPos = scrollPos;
+
+ return vm.$nextTick().then(() => {
+ vm.$el.querySelector('.btn-scroll:not([disabled])').click();
+ expect(vm[fnName]).toHaveBeenCalled();
+ });
+ });
+ });
+
+ describe('scrollDown', () => {
+ beforeEach(() => {
+ vm = vm.$mount();
+
+ jest.spyOn(vm.$refs.buildTrace, 'scrollTo').mockImplementation();
+ });
+
+ it('scrolls build trace to bottom', () => {
+ jest.spyOn(vm.$refs.buildTrace, 'scrollHeight', 'get').mockReturnValue(1000);
+
+ vm.scrollDown();
+
+ expect(vm.$refs.buildTrace.scrollTo).toHaveBeenCalledWith(0, 1000);
+ });
+ });
+
+ describe('scrollUp', () => {
+ beforeEach(() => {
+ vm = vm.$mount();
+
+ jest.spyOn(vm.$refs.buildTrace, 'scrollTo').mockImplementation();
+ });
+
+ it('scrolls build trace to top', () => {
+ vm.scrollUp();
+
+ expect(vm.$refs.buildTrace.scrollTo).toHaveBeenCalledWith(0, 0);
+ });
+ });
+
+ describe('scrollBuildLog', () => {
+ beforeEach(() => {
+ vm = vm.$mount();
+ jest.spyOn(vm.$refs.buildTrace, 'scrollTo').mockImplementation();
+ jest.spyOn(vm.$refs.buildTrace, 'offsetHeight', 'get').mockReturnValue(100);
+ jest.spyOn(vm.$refs.buildTrace, 'scrollHeight', 'get').mockReturnValue(200);
+ });
+
+ it('sets scrollPos to bottom when at the bottom', () => {
+ jest.spyOn(vm.$refs.buildTrace, 'scrollTop', 'get').mockReturnValue(100);
+
+ vm.scrollBuildLog();
+
+ expect(vm.scrollPos).toBe(1);
+ });
+
+ it('sets scrollPos to top when at the top', () => {
+ jest.spyOn(vm.$refs.buildTrace, 'scrollTop', 'get').mockReturnValue(0);
+ vm.scrollPos = 1;
+
+ vm.scrollBuildLog();
+
+ expect(vm.scrollPos).toBe(0);
+ });
+
+ it('resets scrollPos when not at top or bottom', () => {
+ jest.spyOn(vm.$refs.buildTrace, 'scrollTop', 'get').mockReturnValue(10);
+
+ vm.scrollBuildLog();
+
+ expect(vm.scrollPos).toBe('');
+ });
+ });
+});
diff --git a/spec/frontend/ide/components/merge_requests/item_spec.js b/spec/frontend/ide/components/merge_requests/item_spec.js
index 6a2451ad263..b1da89d7a9b 100644
--- a/spec/frontend/ide/components/merge_requests/item_spec.js
+++ b/spec/frontend/ide/components/merge_requests/item_spec.js
@@ -1,63 +1,91 @@
-import Vue from 'vue';
-import router from '~/ide/ide_router';
+import Vuex from 'vuex';
+import { mount, createLocalVue } from '@vue/test-utils';
+import { createStore } from '~/ide/stores';
+import { createRouter } from '~/ide/ide_router';
import Item from '~/ide/components/merge_requests/item.vue';
-import mountCompontent from '../../../helpers/vue_mount_component_helper';
+
+const TEST_ITEM = {
+ iid: 1,
+ projectPathWithNamespace: 'gitlab-org/gitlab-ce',
+ title: 'Merge request title',
+};
describe('IDE merge request item', () => {
- const Component = Vue.extend(Item);
- let vm;
+ const localVue = createLocalVue();
+ localVue.use(Vuex);
- beforeEach(() => {
- vm = mountCompontent(Component, {
- item: {
- iid: 1,
- projectPathWithNamespace: 'gitlab-org/gitlab-ce',
- title: 'Merge request title',
+ let wrapper;
+ let store;
+ let router;
+
+ const createComponent = (props = {}) => {
+ wrapper = mount(Item, {
+ propsData: {
+ item: {
+ ...TEST_ITEM,
+ },
+ currentId: `${TEST_ITEM.iid}`,
+ currentProjectId: TEST_ITEM.projectPathWithNamespace,
+ ...props,
},
- currentId: '1',
- currentProjectId: 'gitlab-org/gitlab-ce',
+ localVue,
+ router,
+ store,
});
+ };
+ const findIcon = () => wrapper.find('.ic-mobile-issue-close');
+
+ beforeEach(() => {
+ store = createStore();
+ router = createRouter(store);
});
afterEach(() => {
- vm.$destroy();
+ wrapper.destroy();
+ wrapper = null;
});
- it('renders merge requests data', () => {
- expect(vm.$el.textContent).toContain('Merge request title');
- expect(vm.$el.textContent).toContain('gitlab-org/gitlab-ce!1');
- });
+ describe('default', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('renders merge requests data', () => {
+ expect(wrapper.text()).toContain('Merge request title');
+ expect(wrapper.text()).toContain('gitlab-org/gitlab-ce!1');
+ });
- it('renders link with href', () => {
- const expectedHref = router.resolve(
- `/project/${vm.item.projectPathWithNamespace}/merge_requests/${vm.item.iid}`,
- ).href;
+ it('renders link with href', () => {
+ const expectedHref = router.resolve(
+ `/project/${TEST_ITEM.projectPathWithNamespace}/merge_requests/${TEST_ITEM.iid}`,
+ ).href;
- expect(vm.$el.tagName.toLowerCase()).toBe('a');
- expect(vm.$el).toHaveAttr('href', expectedHref);
- });
+ expect(wrapper.element.tagName.toLowerCase()).toBe('a');
+ expect(wrapper.attributes('href')).toBe(expectedHref);
+ });
- it('renders icon if ID matches currentId', () => {
- expect(vm.$el.querySelector('.ic-mobile-issue-close')).not.toBe(null);
+ it('renders icon if ID matches currentId', () => {
+ expect(findIcon().exists()).toBe(true);
+ });
});
- it('does not render icon if ID does not match currentId', done => {
- vm.currentId = '2';
-
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.ic-mobile-issue-close')).toBe(null);
+ describe('with different currentId', () => {
+ beforeEach(() => {
+ createComponent({ currentId: `${TEST_ITEM.iid + 1}` });
+ });
- done();
+ it('does not render icon', () => {
+ expect(findIcon().exists()).toBe(false);
});
});
- it('does not render icon if project ID does not match', done => {
- vm.currentProjectId = 'test/test';
-
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.ic-mobile-issue-close')).toBe(null);
+ describe('with different project ID', () => {
+ beforeEach(() => {
+ createComponent({ currentProjectId: 'test/test' });
+ });
- done();
+ it('does not render icon', () => {
+ expect(findIcon().exists()).toBe(false);
});
});
});
diff --git a/spec/frontend/ide/components/new_dropdown/modal_spec.js b/spec/frontend/ide/components/new_dropdown/modal_spec.js
index 62a59a76bf4..da17cc3601e 100644
--- a/spec/frontend/ide/components/new_dropdown/modal_spec.js
+++ b/spec/frontend/ide/components/new_dropdown/modal_spec.js
@@ -120,6 +120,46 @@ describe('new file modal component', () => {
});
});
+ describe('createFromTemplate', () => {
+ let store;
+
+ beforeEach(() => {
+ store = createStore();
+ store.state.entries = {
+ 'test-path/test': {
+ name: 'test',
+ deleted: false,
+ },
+ };
+
+ vm = createComponentWithStore(Component, store).$mount();
+ vm.open('blob');
+
+ jest.spyOn(vm, 'createTempEntry').mockImplementation();
+ });
+
+ it.each`
+ entryName | newFilePath
+ ${''} | ${'.gitignore'}
+ ${'README.md'} | ${'.gitignore'}
+ ${'test-path/test/'} | ${'test-path/test/.gitignore'}
+ ${'test-path/test'} | ${'test-path/.gitignore'}
+ ${'test-path/test/abc.md'} | ${'test-path/test/.gitignore'}
+ `(
+ 'creates a new file with the given template name in appropriate directory for path: $path',
+ ({ entryName, newFilePath }) => {
+ vm.entryName = entryName;
+
+ vm.createFromTemplate({ name: '.gitignore' });
+
+ expect(vm.createTempEntry).toHaveBeenCalledWith({
+ name: newFilePath,
+ type: 'blob',
+ });
+ },
+ );
+ });
+
describe('submitForm', () => {
let store;
diff --git a/spec/frontend/ide/components/new_dropdown/upload_spec.js b/spec/frontend/ide/components/new_dropdown/upload_spec.js
index a418fdeb572..ad27954cd10 100644
--- a/spec/frontend/ide/components/new_dropdown/upload_spec.js
+++ b/spec/frontend/ide/components/new_dropdown/upload_spec.js
@@ -85,7 +85,6 @@ describe('new dropdown upload', () => {
name: textFile.name,
type: 'blob',
content: 'plain text',
- base64: false,
binary: false,
rawPath: '',
});
@@ -103,7 +102,6 @@ describe('new dropdown upload', () => {
name: binaryFile.name,
type: 'blob',
content: binaryTarget.result.split('base64,')[1],
- base64: true,
binary: true,
rawPath: binaryTarget.result,
});
diff --git a/spec/frontend/ide/components/panes/collapsible_sidebar_spec.js b/spec/frontend/ide/components/panes/collapsible_sidebar_spec.js
index 3bc89996978..e32abc98aae 100644
--- a/spec/frontend/ide/components/panes/collapsible_sidebar_spec.js
+++ b/spec/frontend/ide/components/panes/collapsible_sidebar_spec.js
@@ -2,6 +2,7 @@ import { createLocalVue, shallowMount } from '@vue/test-utils';
import { createStore } from '~/ide/stores';
import paneModule from '~/ide/stores/modules/pane';
import CollapsibleSidebar from '~/ide/components/panes/collapsible_sidebar.vue';
+import IdeSidebarNav from '~/ide/components/ide_sidebar_nav.vue';
import Vuex from 'vuex';
const localVue = createLocalVue();
@@ -24,19 +25,15 @@ describe('ide/components/panes/collapsible_sidebar.vue', () => {
width,
...props,
},
- slots: {
- 'header-icon': '<div class=".header-icon-slot">SLOT ICON</div>',
- header: '<div class=".header-slot"/>',
- footer: '<div class=".footer-slot"/>',
- },
});
};
- const findTabButton = () => wrapper.find(`[data-qa-selector="${fakeComponentName}_tab_button"]`);
+ const findSidebarNav = () => wrapper.find(IdeSidebarNav);
beforeEach(() => {
store = createStore();
store.registerModule('leftPane', paneModule());
+ jest.spyOn(store, 'dispatch').mockImplementation();
});
afterEach(() => {
@@ -75,92 +72,60 @@ describe('ide/components/panes/collapsible_sidebar.vue', () => {
${'left'}
${'right'}
`('when side=$side', ({ side }) => {
- it('correctly renders side specific attributes', () => {
+ beforeEach(() => {
createComponent({ extensionTabs, side });
- const button = findTabButton();
-
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.classes()).toContain('multi-file-commit-panel');
- expect(wrapper.classes()).toContain(`ide-${side}-sidebar`);
- expect(wrapper.find('.multi-file-commit-panel-inner')).not.toBe(null);
- expect(wrapper.find(`.ide-${side}-sidebar-${fakeComponentName}`)).not.toBe(null);
- expect(button.attributes('data-placement')).toEqual(side === 'left' ? 'right' : 'left');
- if (side === 'right') {
- // this class is only needed on the right side; there is no 'is-left'
- expect(button.classes()).toContain('is-right');
- } else {
- expect(button.classes()).not.toContain('is-right');
- }
- });
});
- });
-
- describe('when default side', () => {
- let button;
- beforeEach(() => {
- createComponent({ extensionTabs });
-
- button = findTabButton();
+ it('correctly renders side specific attributes', () => {
+ expect(wrapper.classes()).toContain('multi-file-commit-panel');
+ expect(wrapper.classes()).toContain(`ide-${side}-sidebar`);
+ expect(wrapper.find('.multi-file-commit-panel-inner')).not.toBe(null);
+ expect(wrapper.find(`.ide-${side}-sidebar-${fakeComponentName}`)).not.toBe(null);
+ expect(findSidebarNav().props('side')).toBe(side);
});
- it('correctly renders tab-specific classes', () => {
- store.state.rightPane.currentView = fakeComponentName;
-
- return wrapper.vm.$nextTick().then(() => {
- expect(button.classes()).toContain('button-class-1');
- expect(button.classes()).toContain('button-class-2');
- });
+ it('nothing is dispatched', () => {
+ expect(store.dispatch).not.toHaveBeenCalled();
});
- it('can show an open pane tab with an active view', () => {
- store.state.rightPane.isOpen = true;
- store.state.rightPane.currentView = fakeComponentName;
+ it('when sidebar emits open, dispatch open', () => {
+ const view = 'lorem-view';
- return wrapper.vm.$nextTick().then(() => {
- expect(button.classes()).toEqual(expect.arrayContaining(['ide-sidebar-link', 'active']));
- expect(button.attributes('data-original-title')).toEqual(fakeComponentName);
- expect(wrapper.find('.js-tab-view').exists()).toBe(true);
- });
- });
-
- it('does not show a pane which is not open', () => {
- store.state.rightPane.isOpen = false;
- store.state.rightPane.currentView = fakeComponentName;
+ findSidebarNav().vm.$emit('open', view);
- return wrapper.vm.$nextTick().then(() => {
- expect(button.classes()).not.toEqual(
- expect.arrayContaining(['ide-sidebar-link', 'active']),
- );
- expect(wrapper.find('.js-tab-view').exists()).toBe(false);
- });
+ expect(store.dispatch).toHaveBeenCalledWith(`${side}Pane/open`, view);
});
- describe('when button is clicked', () => {
- it('opens view', () => {
- button.trigger('click');
- expect(store.state.rightPane.isOpen).toBeTruthy();
- });
-
- it('toggles open view if tab is currently active', () => {
- button.trigger('click');
- expect(store.state.rightPane.isOpen).toBeTruthy();
+ it('when sidebar emits close, dispatch toggleOpen', () => {
+ findSidebarNav().vm.$emit('close');
- button.trigger('click');
- expect(store.state.rightPane.isOpen).toBeFalsy();
- });
+ expect(store.dispatch).toHaveBeenCalledWith(`${side}Pane/toggleOpen`);
});
+ });
- it('shows header-icon', () => {
- expect(wrapper.find('.header-icon-slot')).not.toBeNull();
+ describe.each`
+ isOpen
+ ${true}
+ ${false}
+ `('when isOpen=$isOpen', ({ isOpen }) => {
+ beforeEach(() => {
+ store.state.rightPane.isOpen = isOpen;
+ store.state.rightPane.currentView = fakeComponentName;
+
+ createComponent({ extensionTabs });
});
- it('shows header', () => {
- expect(wrapper.find('.header-slot')).not.toBeNull();
+ it(`tab view is shown=${isOpen}`, () => {
+ expect(wrapper.find('.js-tab-view').exists()).toBe(isOpen);
});
- it('shows footer', () => {
- expect(wrapper.find('.footer-slot')).not.toBeNull();
+ it('renders sidebar nav', () => {
+ expect(findSidebarNav().props()).toEqual({
+ tabs: extensionTabs,
+ side: 'right',
+ currentView: fakeComponentName,
+ isOpen,
+ });
});
});
});
diff --git a/spec/frontend/ide/components/panes/right_spec.js b/spec/frontend/ide/components/panes/right_spec.js
index 84b2d440b60..203d35ed335 100644
--- a/spec/frontend/ide/components/panes/right_spec.js
+++ b/spec/frontend/ide/components/panes/right_spec.js
@@ -5,6 +5,7 @@ import { createStore } from '~/ide/stores';
import RightPane from '~/ide/components/panes/right.vue';
import CollapsibleSidebar from '~/ide/components/panes/collapsible_sidebar.vue';
import { rightSidebarViews } from '~/ide/constants';
+import extendStore from '~/ide/stores/extend';
const localVue = createLocalVue();
localVue.use(Vuex);
@@ -14,6 +15,8 @@ describe('ide/components/panes/right.vue', () => {
let store;
const createComponent = props => {
+ extendStore(store, document.createElement('div'));
+
wrapper = shallowMount(RightPane, {
localVue,
store,
@@ -32,26 +35,6 @@ describe('ide/components/panes/right.vue', () => {
wrapper = null;
});
- it('allows tabs to be added via extensionTabs prop', () => {
- createComponent({
- extensionTabs: [
- {
- show: true,
- title: 'FakeTab',
- },
- ],
- });
-
- expect(wrapper.find(CollapsibleSidebar).props('extensionTabs')).toEqual(
- expect.arrayContaining([
- expect.objectContaining({
- show: true,
- title: 'FakeTab',
- }),
- ]),
- );
- });
-
describe('pipelines tab', () => {
it('is always shown', () => {
createComponent();
@@ -99,4 +82,38 @@ describe('ide/components/panes/right.vue', () => {
);
});
});
+
+ describe('terminal tab', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('adds terminal tab', () => {
+ store.state.terminal.isVisible = true;
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.find(CollapsibleSidebar).props('extensionTabs')).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ show: true,
+ title: 'Terminal',
+ }),
+ ]),
+ );
+ });
+ });
+
+ it('hides terminal tab when not visible', () => {
+ store.state.terminal.isVisible = false;
+
+ expect(wrapper.find(CollapsibleSidebar).props('extensionTabs')).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ show: false,
+ title: 'Terminal',
+ }),
+ ]),
+ );
+ });
+ });
});
diff --git a/spec/frontend/ide/components/pipelines/list_spec.js b/spec/frontend/ide/components/pipelines/list_spec.js
index d909a5e478e..795ded35d20 100644
--- a/spec/frontend/ide/components/pipelines/list_spec.js
+++ b/spec/frontend/ide/components/pipelines/list_spec.js
@@ -6,7 +6,7 @@ import List from '~/ide/components/pipelines/list.vue';
import JobsList from '~/ide/components/jobs/list.vue';
import Tab from '~/vue_shared/components/tabs/tab.vue';
import CiIcon from '~/vue_shared/components/ci_icon.vue';
-import { pipelines } from '../../../../javascripts/ide/mock_data';
+import { pipelines } from 'jest/ide/mock_data';
import IDEServices from '~/ide/services';
const localVue = createLocalVue();
diff --git a/spec/frontend/ide/components/repo_commit_section_spec.js b/spec/frontend/ide/components/repo_commit_section_spec.js
index 237be018807..3b837622720 100644
--- a/spec/frontend/ide/components/repo_commit_section_spec.js
+++ b/spec/frontend/ide/components/repo_commit_section_spec.js
@@ -1,7 +1,8 @@
import { mount } from '@vue/test-utils';
import { createStore } from '~/ide/stores';
-import router from '~/ide/ide_router';
+import { createRouter } from '~/ide/ide_router';
import RepoCommitSection from '~/ide/components/repo_commit_section.vue';
+import EmptyState from '~/ide/components/commit_sidebar/empty_state.vue';
import { stageKeys } from '~/ide/constants';
import { file } from '../helpers';
@@ -9,6 +10,7 @@ const TEST_NO_CHANGES_SVG = 'nochangessvg';
describe('RepoCommitSection', () => {
let wrapper;
+ let router;
let store;
function createComponent() {
@@ -54,6 +56,7 @@ describe('RepoCommitSection', () => {
beforeEach(() => {
store = createStore();
+ router = createRouter(store);
jest.spyOn(store, 'dispatch');
jest.spyOn(router, 'push').mockImplementation();
@@ -63,7 +66,7 @@ describe('RepoCommitSection', () => {
wrapper.destroy();
});
- describe('empty Stage', () => {
+ describe('empty state', () => {
beforeEach(() => {
store.state.noChangesStateSvgPath = TEST_NO_CHANGES_SVG;
store.state.committedStateSvgPath = 'svg';
@@ -74,11 +77,16 @@ describe('RepoCommitSection', () => {
it('renders no changes text', () => {
expect(
wrapper
- .find('.js-empty-state')
+ .find(EmptyState)
.text()
.trim(),
).toContain('No changes');
- expect(wrapper.find('.js-empty-state img').attributes('src')).toBe(TEST_NO_CHANGES_SVG);
+ expect(
+ wrapper
+ .find(EmptyState)
+ .find('img')
+ .attributes('src'),
+ ).toBe(TEST_NO_CHANGES_SVG);
});
});
@@ -109,6 +117,32 @@ describe('RepoCommitSection', () => {
expect(changedFileNames).toEqual(allFiles.map(x => x.path));
});
+
+ it('does not show empty state', () => {
+ expect(wrapper.find(EmptyState).exists()).toBe(false);
+ });
+ });
+
+ describe('if nothing is changed or staged', () => {
+ beforeEach(() => {
+ setupDefaultState();
+
+ store.state.openFiles = [...Object.values(store.state.entries)];
+ store.state.openFiles[0].active = true;
+ store.state.stagedFiles = [];
+
+ createComponent();
+ });
+
+ it('opens currently active file', () => {
+ expect(store.state.openFiles.length).toBe(1);
+ expect(store.state.openFiles[0].pending).toBe(true);
+
+ expect(store.dispatch).toHaveBeenCalledWith('openPendingTab', {
+ file: store.state.entries[store.getters.activeFile.path],
+ keyPrefix: stageKeys.unstaged,
+ });
+ });
});
describe('with unstaged file', () => {
@@ -129,5 +163,9 @@ describe('RepoCommitSection', () => {
keyPrefix: stageKeys.unstaged,
});
});
+
+ it('does not show empty state', () => {
+ expect(wrapper.find(EmptyState).exists()).toBe(false);
+ });
});
});
diff --git a/spec/frontend/ide/components/repo_editor_spec.js b/spec/frontend/ide/components/repo_editor_spec.js
new file mode 100644
index 00000000000..4967434dfd7
--- /dev/null
+++ b/spec/frontend/ide/components/repo_editor_spec.js
@@ -0,0 +1,664 @@
+import Vuex from 'vuex';
+import Vue from 'vue';
+import MockAdapter from 'axios-mock-adapter';
+import '~/behaviors/markdown/render_gfm';
+import { Range } from 'monaco-editor';
+import axios from '~/lib/utils/axios_utils';
+import { createStoreOptions } from '~/ide/stores';
+import RepoEditor from '~/ide/components/repo_editor.vue';
+import Editor from '~/ide/lib/editor';
+import { leftSidebarViews, FILE_VIEW_MODE_EDITOR, FILE_VIEW_MODE_PREVIEW } from '~/ide/constants';
+import { createComponentWithStore } from '../../helpers/vue_mount_component_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import { file } from '../helpers';
+import { exampleConfigs, exampleFiles } from '../lib/editorconfig/mock_data';
+
+describe('RepoEditor', () => {
+ let vm;
+ let store;
+ let mockActions;
+
+ const waitForEditorSetup = () =>
+ new Promise(resolve => {
+ vm.$once('editorSetup', resolve);
+ });
+
+ const createComponent = () => {
+ if (vm) {
+ throw new Error('vm already exists');
+ }
+ vm = createComponentWithStore(Vue.extend(RepoEditor), store, {
+ file: store.state.openFiles[0],
+ });
+ vm.$mount();
+ };
+
+ const createOpenFile = path => {
+ const origFile = store.state.openFiles[0];
+ const newFile = { ...origFile, path, key: path };
+
+ store.state.entries[path] = newFile;
+
+ store.state.openFiles = [newFile];
+ };
+
+ beforeEach(() => {
+ mockActions = {
+ getFileData: jest.fn().mockResolvedValue(),
+ getRawFileData: jest.fn().mockResolvedValue(),
+ };
+
+ const f = {
+ ...file(),
+ viewMode: FILE_VIEW_MODE_EDITOR,
+ };
+
+ const storeOptions = createStoreOptions();
+ storeOptions.actions = {
+ ...storeOptions.actions,
+ ...mockActions,
+ };
+ store = new Vuex.Store(storeOptions);
+
+ f.active = true;
+ f.tempFile = true;
+
+ store.state.openFiles.push(f);
+ store.state.projects = {
+ 'gitlab-org/gitlab': {
+ branches: {
+ master: {
+ name: 'master',
+ commit: {
+ id: 'abcdefgh',
+ },
+ },
+ },
+ },
+ };
+ store.state.currentProjectId = 'gitlab-org/gitlab';
+ store.state.currentBranchId = 'master';
+
+ Vue.set(store.state.entries, f.path, f);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ vm = null;
+
+ Editor.editorInstance.dispose();
+ });
+
+ const findEditor = () => vm.$el.querySelector('.multi-file-editor-holder');
+
+ describe('default', () => {
+ beforeEach(() => {
+ createComponent();
+
+ return waitForEditorSetup();
+ });
+
+ it('sets renderWhitespace to `all`', () => {
+ vm.$store.state.renderWhitespaceInCode = true;
+
+ expect(vm.editorOptions.renderWhitespace).toEqual('all');
+ });
+
+ it('sets renderWhitespace to `none`', () => {
+ vm.$store.state.renderWhitespaceInCode = false;
+
+ expect(vm.editorOptions.renderWhitespace).toEqual('none');
+ });
+
+ it('renders an ide container', () => {
+ expect(vm.shouldHideEditor).toBeFalsy();
+ expect(vm.showEditor).toBe(true);
+ expect(findEditor()).not.toHaveCss({ display: 'none' });
+ });
+
+ it('renders only an edit tab', done => {
+ Vue.nextTick(() => {
+ const tabs = vm.$el.querySelectorAll('.ide-mode-tabs .nav-links li');
+
+ expect(tabs.length).toBe(1);
+ expect(tabs[0].textContent.trim()).toBe('Edit');
+
+ done();
+ });
+ });
+
+ describe('when file is markdown', () => {
+ let mock;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+
+ mock.onPost(/(.*)\/preview_markdown/).reply(200, {
+ body: '<p>testing 123</p>',
+ });
+
+ Vue.set(vm, 'file', {
+ ...vm.file,
+ projectId: 'namespace/project',
+ path: 'sample.md',
+ content: 'testing 123',
+ });
+
+ vm.$store.state.entries[vm.file.path] = vm.file;
+
+ return vm.$nextTick();
+ });
+
+ afterEach(() => {
+ mock.restore();
+ });
+
+ it('renders an Edit and a Preview Tab', done => {
+ Vue.nextTick(() => {
+ const tabs = vm.$el.querySelectorAll('.ide-mode-tabs .nav-links li');
+
+ expect(tabs.length).toBe(2);
+ expect(tabs[0].textContent.trim()).toBe('Edit');
+ expect(tabs[1].textContent.trim()).toBe('Preview Markdown');
+
+ done();
+ });
+ });
+
+ it('renders markdown for tempFile', done => {
+ vm.file.tempFile = true;
+
+ vm.$nextTick()
+ .then(() => {
+ vm.$el.querySelectorAll('.ide-mode-tabs .nav-links a')[1].click();
+ })
+ .then(waitForPromises)
+ .then(() => {
+ expect(vm.$el.querySelector('.preview-container').innerHTML).toContain(
+ '<p>testing 123</p>',
+ );
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ describe('when not in edit mode', () => {
+ beforeEach(async () => {
+ await vm.$nextTick();
+
+ vm.$store.state.currentActivityView = leftSidebarViews.review.name;
+
+ return vm.$nextTick();
+ });
+
+ it('shows no tabs', () => {
+ expect(vm.$el.querySelectorAll('.ide-mode-tabs .nav-links a')).toHaveLength(0);
+ });
+ });
+ });
+
+ describe('when open file is binary and not raw', () => {
+ beforeEach(done => {
+ vm.file.binary = true;
+
+ vm.$nextTick(done);
+ });
+
+ it('does not render the IDE', () => {
+ expect(vm.shouldHideEditor).toBeTruthy();
+ });
+ });
+
+ describe('createEditorInstance', () => {
+ it('calls createInstance when viewer is editor', done => {
+ jest.spyOn(vm.editor, 'createInstance').mockImplementation();
+
+ vm.createEditorInstance();
+
+ vm.$nextTick(() => {
+ expect(vm.editor.createInstance).toHaveBeenCalled();
+
+ done();
+ });
+ });
+
+ it('calls createDiffInstance when viewer is diff', done => {
+ vm.$store.state.viewer = 'diff';
+
+ jest.spyOn(vm.editor, 'createDiffInstance').mockImplementation();
+
+ vm.createEditorInstance();
+
+ vm.$nextTick(() => {
+ expect(vm.editor.createDiffInstance).toHaveBeenCalled();
+
+ done();
+ });
+ });
+
+ it('calls createDiffInstance when viewer is a merge request diff', done => {
+ vm.$store.state.viewer = 'mrdiff';
+
+ jest.spyOn(vm.editor, 'createDiffInstance').mockImplementation();
+
+ vm.createEditorInstance();
+
+ vm.$nextTick(() => {
+ expect(vm.editor.createDiffInstance).toHaveBeenCalled();
+
+ done();
+ });
+ });
+ });
+
+ describe('setupEditor', () => {
+ it('creates new model', () => {
+ jest.spyOn(vm.editor, 'createModel');
+
+ Editor.editorInstance.modelManager.dispose();
+
+ vm.setupEditor();
+
+ expect(vm.editor.createModel).toHaveBeenCalledWith(vm.file, null);
+ expect(vm.model).not.toBeNull();
+ });
+
+ it('attaches model to editor', () => {
+ jest.spyOn(vm.editor, 'attachModel');
+
+ Editor.editorInstance.modelManager.dispose();
+
+ vm.setupEditor();
+
+ expect(vm.editor.attachModel).toHaveBeenCalledWith(vm.model);
+ });
+
+ it('attaches model to merge request editor', () => {
+ vm.$store.state.viewer = 'mrdiff';
+ vm.file.mrChange = true;
+ jest.spyOn(vm.editor, 'attachMergeRequestModel').mockImplementation();
+
+ Editor.editorInstance.modelManager.dispose();
+
+ vm.setupEditor();
+
+ expect(vm.editor.attachMergeRequestModel).toHaveBeenCalledWith(vm.model);
+ });
+
+ it('does not attach model to merge request editor when not a MR change', () => {
+ vm.$store.state.viewer = 'mrdiff';
+ vm.file.mrChange = false;
+ jest.spyOn(vm.editor, 'attachMergeRequestModel').mockImplementation();
+
+ Editor.editorInstance.modelManager.dispose();
+
+ vm.setupEditor();
+
+ expect(vm.editor.attachMergeRequestModel).not.toHaveBeenCalledWith(vm.model);
+ });
+
+ it('adds callback methods', () => {
+ jest.spyOn(vm.editor, 'onPositionChange');
+
+ Editor.editorInstance.modelManager.dispose();
+
+ vm.setupEditor();
+
+ expect(vm.editor.onPositionChange).toHaveBeenCalled();
+ expect(vm.model.events.size).toBe(2);
+ });
+
+ it('updates state with the value of the model', () => {
+ vm.model.setValue('testing 1234\n');
+
+ vm.setupEditor();
+
+ expect(vm.file.content).toBe('testing 1234\n');
+ });
+
+ it('sets head model as staged file', () => {
+ jest.spyOn(vm.editor, 'createModel');
+
+ Editor.editorInstance.modelManager.dispose();
+
+ vm.$store.state.stagedFiles.push({ ...vm.file, key: 'staged' });
+ vm.file.staged = true;
+ vm.file.key = `unstaged-${vm.file.key}`;
+
+ vm.setupEditor();
+
+ expect(vm.editor.createModel).toHaveBeenCalledWith(vm.file, vm.$store.state.stagedFiles[0]);
+ });
+ });
+
+ describe('editor updateDimensions', () => {
+ beforeEach(() => {
+ jest.spyOn(vm.editor, 'updateDimensions');
+ jest.spyOn(vm.editor, 'updateDiffView').mockImplementation();
+ });
+
+ it('calls updateDimensions when panelResizing is false', done => {
+ vm.$store.state.panelResizing = true;
+
+ vm.$nextTick()
+ .then(() => {
+ vm.$store.state.panelResizing = false;
+ })
+ .then(vm.$nextTick)
+ .then(() => {
+ expect(vm.editor.updateDimensions).toHaveBeenCalled();
+ expect(vm.editor.updateDiffView).toHaveBeenCalled();
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('does not call updateDimensions when panelResizing is true', done => {
+ vm.$store.state.panelResizing = true;
+
+ vm.$nextTick(() => {
+ expect(vm.editor.updateDimensions).not.toHaveBeenCalled();
+ expect(vm.editor.updateDiffView).not.toHaveBeenCalled();
+
+ done();
+ });
+ });
+
+ it('calls updateDimensions when rightPane is opened', done => {
+ vm.$store.state.rightPane.isOpen = true;
+
+ vm.$nextTick(() => {
+ expect(vm.editor.updateDimensions).toHaveBeenCalled();
+ expect(vm.editor.updateDiffView).toHaveBeenCalled();
+
+ done();
+ });
+ });
+ });
+
+ describe('show tabs', () => {
+ it('shows tabs in edit mode', () => {
+ expect(vm.$el.querySelector('.nav-links')).not.toBe(null);
+ });
+
+ it('hides tabs in review mode', done => {
+ vm.$store.state.currentActivityView = leftSidebarViews.review.name;
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelector('.nav-links')).toBe(null);
+
+ done();
+ });
+ });
+
+ it('hides tabs in commit mode', done => {
+ vm.$store.state.currentActivityView = leftSidebarViews.commit.name;
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelector('.nav-links')).toBe(null);
+
+ done();
+ });
+ });
+ });
+
+ describe('when files view mode is preview', () => {
+ beforeEach(done => {
+ jest.spyOn(vm.editor, 'updateDimensions').mockImplementation();
+ vm.file.viewMode = FILE_VIEW_MODE_PREVIEW;
+ vm.$nextTick(done);
+ });
+
+ it('should hide editor', () => {
+ expect(vm.showEditor).toBe(false);
+ expect(findEditor()).toHaveCss({ display: 'none' });
+ });
+
+ describe('when file view mode changes to editor', () => {
+ it('should update dimensions', () => {
+ vm.file.viewMode = FILE_VIEW_MODE_EDITOR;
+
+ return vm.$nextTick().then(() => {
+ expect(vm.editor.updateDimensions).toHaveBeenCalled();
+ });
+ });
+ });
+ });
+
+ describe('initEditor', () => {
+ beforeEach(() => {
+ vm.file.tempFile = false;
+ jest.spyOn(vm.editor, 'createInstance').mockImplementation();
+ jest.spyOn(vm, 'shouldHideEditor', 'get').mockReturnValue(true);
+ });
+
+ it('does not fetch file information for temp entries', done => {
+ vm.file.tempFile = true;
+
+ vm.initEditor();
+ vm.$nextTick()
+ .then(() => {
+ expect(mockActions.getFileData).not.toHaveBeenCalled();
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('is being initialised for files without content even if shouldHideEditor is `true`', done => {
+ vm.file.content = '';
+ vm.file.raw = '';
+
+ vm.initEditor();
+ vm.$nextTick()
+ .then(() => {
+ expect(mockActions.getFileData).toHaveBeenCalled();
+ expect(mockActions.getRawFileData).toHaveBeenCalled();
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('does not initialize editor for files already with content', done => {
+ vm.file.content = 'foo';
+
+ vm.initEditor();
+ vm.$nextTick()
+ .then(() => {
+ expect(mockActions.getFileData).not.toHaveBeenCalled();
+ expect(mockActions.getRawFileData).not.toHaveBeenCalled();
+ expect(vm.editor.createInstance).not.toHaveBeenCalled();
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('updates on file changes', () => {
+ beforeEach(() => {
+ jest.spyOn(vm, 'initEditor').mockImplementation();
+ });
+
+ it('calls removePendingTab when old file is pending', done => {
+ jest.spyOn(vm, 'shouldHideEditor', 'get').mockReturnValue(true);
+ jest.spyOn(vm, 'removePendingTab').mockImplementation();
+
+ vm.file.pending = true;
+
+ vm.$nextTick()
+ .then(() => {
+ vm.file = file('testing');
+ vm.file.content = 'foo'; // need to prevent full cycle of initEditor
+
+ return vm.$nextTick();
+ })
+ .then(() => {
+ expect(vm.removePendingTab).toHaveBeenCalled();
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('does not call initEditor if the file did not change', done => {
+ Vue.set(vm, 'file', vm.file);
+
+ vm.$nextTick()
+ .then(() => {
+ expect(vm.initEditor).not.toHaveBeenCalled();
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('calls initEditor when file key is changed', done => {
+ expect(vm.initEditor).not.toHaveBeenCalled();
+
+ Vue.set(vm, 'file', {
+ ...vm.file,
+ key: 'new',
+ });
+
+ vm.$nextTick()
+ .then(() => {
+ expect(vm.initEditor).toHaveBeenCalled();
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('onPaste', () => {
+ const setFileName = name => {
+ Vue.set(vm, 'file', {
+ ...vm.file,
+ content: 'hello world\n',
+ name,
+ path: `foo/${name}`,
+ key: 'new',
+ });
+
+ vm.$store.state.entries[vm.file.path] = vm.file;
+ };
+
+ const pasteImage = () => {
+ window.dispatchEvent(
+ Object.assign(new Event('paste'), {
+ clipboardData: {
+ files: [new File(['foo'], 'foo.png', { type: 'image/png' })],
+ },
+ }),
+ );
+ };
+
+ const watchState = watched =>
+ new Promise(resolve => {
+ const unwatch = vm.$store.watch(watched, () => {
+ unwatch();
+ resolve();
+ });
+ });
+
+ beforeEach(() => {
+ setFileName('bar.md');
+
+ vm.$store.state.trees['gitlab-org/gitlab'] = { tree: [] };
+ vm.$store.state.currentProjectId = 'gitlab-org';
+ vm.$store.state.currentBranchId = 'gitlab';
+
+ // create a new model each time, otherwise tests conflict with each other
+ // because of same model being used in multiple tests
+ Editor.editorInstance.modelManager.dispose();
+ vm.setupEditor();
+
+ return waitForPromises().then(() => {
+ // set cursor to line 2, column 1
+ vm.editor.instance.setSelection(new Range(2, 1, 2, 1));
+ vm.editor.instance.focus();
+ });
+ });
+
+ it('adds an image entry to the same folder for a pasted image in a markdown file', () => {
+ pasteImage();
+
+ return waitForPromises().then(() => {
+ expect(vm.$store.state.entries['foo/foo.png']).toMatchObject({
+ path: 'foo/foo.png',
+ type: 'blob',
+ content: 'Zm9v',
+ binary: true,
+ rawPath: 'data:image/png;base64,Zm9v',
+ });
+ });
+ });
+
+ it("adds a markdown image tag to the file's contents", () => {
+ pasteImage();
+
+ // Pasting an image does a lot of things like using the FileReader API,
+ // so, waitForPromises isn't very reliable (and causes a flaky spec)
+ // Read more about state.watch: https://vuex.vuejs.org/api/#watch
+ return watchState(s => s.entries['foo/bar.md'].content).then(() => {
+ expect(vm.file.content).toBe('hello world\n![foo.png](./foo.png)');
+ });
+ });
+
+ it("does not add file to state or set markdown image syntax if the file isn't markdown", () => {
+ setFileName('myfile.txt');
+ pasteImage();
+
+ return waitForPromises().then(() => {
+ expect(vm.$store.state.entries['foo/foo.png']).toBeUndefined();
+ expect(vm.file.content).toBe('hello world\n');
+ });
+ });
+ });
+ });
+
+ describe('fetchEditorconfigRules', () => {
+ beforeEach(() => {
+ exampleConfigs.forEach(({ path, content }) => {
+ store.state.entries[path] = { ...file(), path, content };
+ });
+ });
+
+ it.each(exampleFiles)(
+ 'does not fetch content from remote for .editorconfig files present locally (case %#)',
+ ({ path, monacoRules }) => {
+ createOpenFile(path);
+ createComponent();
+
+ return waitForEditorSetup().then(() => {
+ expect(vm.rules).toEqual(monacoRules);
+ expect(vm.model.options).toMatchObject(monacoRules);
+ expect(mockActions.getFileData).not.toHaveBeenCalled();
+ expect(mockActions.getRawFileData).not.toHaveBeenCalled();
+ });
+ },
+ );
+
+ it('fetches content from remote for .editorconfig files not available locally', () => {
+ exampleConfigs.forEach(({ path }) => {
+ delete store.state.entries[path].content;
+ delete store.state.entries[path].raw;
+ });
+
+ // Include a "test" directory which does not exist in store. This one should be skipped.
+ createOpenFile('foo/bar/baz/test/my_spec.js');
+ createComponent();
+
+ return waitForEditorSetup().then(() => {
+ expect(mockActions.getFileData.mock.calls.map(([, args]) => args)).toEqual([
+ { makeFileActive: false, path: 'foo/bar/baz/.editorconfig' },
+ { makeFileActive: false, path: 'foo/bar/.editorconfig' },
+ { makeFileActive: false, path: 'foo/.editorconfig' },
+ { makeFileActive: false, path: '.editorconfig' },
+ ]);
+ expect(mockActions.getRawFileData.mock.calls.map(([, args]) => args)).toEqual([
+ { path: 'foo/bar/baz/.editorconfig' },
+ { path: 'foo/bar/.editorconfig' },
+ { path: 'foo/.editorconfig' },
+ { path: '.editorconfig' },
+ ]);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/ide/components/repo_tab_spec.js b/spec/frontend/ide/components/repo_tab_spec.js
index 82ea73ffbb1..5a591d3dcd0 100644
--- a/spec/frontend/ide/components/repo_tab_spec.js
+++ b/spec/frontend/ide/components/repo_tab_spec.js
@@ -1,11 +1,13 @@
import Vue from 'vue';
-import store from '~/ide/stores';
+import { createStore } from '~/ide/stores';
import repoTab from '~/ide/components/repo_tab.vue';
-import router from '~/ide/ide_router';
-import { file, resetStore } from '../helpers';
+import { createRouter } from '~/ide/ide_router';
+import { file } from '../helpers';
describe('RepoTab', () => {
let vm;
+ let store;
+ let router;
function createComponent(propsData) {
const RepoTab = Vue.extend(repoTab);
@@ -17,13 +19,13 @@ describe('RepoTab', () => {
}
beforeEach(() => {
+ store = createStore();
+ router = createRouter(store);
jest.spyOn(router, 'push').mockImplementation(() => {});
});
afterEach(() => {
vm.$destroy();
-
- resetStore(vm.$store);
});
it('renders a close link and a name link', () => {
diff --git a/spec/frontend/ide/components/repo_tabs_spec.js b/spec/frontend/ide/components/repo_tabs_spec.js
index 583f71e6121..df5b01770f5 100644
--- a/spec/frontend/ide/components/repo_tabs_spec.js
+++ b/spec/frontend/ide/components/repo_tabs_spec.js
@@ -16,9 +16,7 @@ describe('RepoTabs', () => {
vm = createComponent(RepoTabs, {
files: openedFiles,
viewer: 'editor',
- hasChanges: false,
activeFile: file('activeFile'),
- hasMergeRequest: false,
});
openedFiles[0].active = true;
diff --git a/spec/frontend/ide/components/resizable_panel_spec.js b/spec/frontend/ide/components/resizable_panel_spec.js
new file mode 100644
index 00000000000..7368de0cee7
--- /dev/null
+++ b/spec/frontend/ide/components/resizable_panel_spec.js
@@ -0,0 +1,114 @@
+import Vuex from 'vuex';
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import ResizablePanel from '~/ide/components/resizable_panel.vue';
+import PanelResizer from '~/vue_shared/components/panel_resizer.vue';
+import { SIDE_LEFT, SIDE_RIGHT } from '~/ide/constants';
+
+const TEST_WIDTH = 500;
+const TEST_MIN_WIDTH = 400;
+
+describe('~/ide/components/resizable_panel', () => {
+ const localVue = createLocalVue();
+ localVue.use(Vuex);
+
+ let wrapper;
+ let store;
+
+ beforeEach(() => {
+ store = new Vuex.Store({});
+ jest.spyOn(store, 'dispatch').mockImplementation();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ const createComponent = (props = {}) => {
+ wrapper = shallowMount(ResizablePanel, {
+ propsData: {
+ initialWidth: TEST_WIDTH,
+ minSize: TEST_MIN_WIDTH,
+ side: SIDE_LEFT,
+ ...props,
+ },
+ store,
+ localVue,
+ });
+ };
+ const findResizer = () => wrapper.find(PanelResizer);
+ const findInlineStyle = () => wrapper.element.style.cssText;
+ const createInlineStyle = width => `width: ${width}px;`;
+
+ describe.each`
+ props | showResizer | resizerSide | expectedStyle
+ ${{ resizable: true, side: SIDE_LEFT }} | ${true} | ${SIDE_RIGHT} | ${createInlineStyle(TEST_WIDTH)}
+ ${{ resizable: true, side: SIDE_RIGHT }} | ${true} | ${SIDE_LEFT} | ${createInlineStyle(TEST_WIDTH)}
+ ${{ resizable: false, side: SIDE_LEFT }} | ${false} | ${SIDE_RIGHT} | ${''}
+ `('with props $props', ({ props, showResizer, resizerSide, expectedStyle }) => {
+ beforeEach(() => {
+ createComponent(props);
+ });
+
+ it(`show resizer is ${showResizer}`, () => {
+ const expectedDisplay = showResizer ? '' : 'none';
+ const resizer = findResizer();
+
+ expect(resizer.exists()).toBe(true);
+ expect(resizer.element.style.display).toBe(expectedDisplay);
+ });
+
+ it(`resizer side is '${resizerSide}'`, () => {
+ const resizer = findResizer();
+
+ expect(resizer.props('side')).toBe(resizerSide);
+ });
+
+ it(`has style '${expectedStyle}'`, () => {
+ expect(findInlineStyle()).toBe(expectedStyle);
+ });
+ });
+
+ describe('default', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('does not dispatch anything', () => {
+ expect(store.dispatch).not.toHaveBeenCalled();
+ });
+
+ it.each`
+ event | dispatchArgs
+ ${'resize-start'} | ${['setResizingStatus', true]}
+ ${'resize-end'} | ${['setResizingStatus', false]}
+ `('when resizer emits $event, dispatch $dispatchArgs', ({ event, dispatchArgs }) => {
+ const resizer = findResizer();
+
+ resizer.vm.$emit(event);
+
+ expect(store.dispatch).toHaveBeenCalledWith(...dispatchArgs);
+ });
+
+ it('renders resizer', () => {
+ const resizer = findResizer();
+
+ expect(resizer.props()).toMatchObject({
+ maxSize: window.innerWidth / 2,
+ minSize: TEST_MIN_WIDTH,
+ startSize: TEST_WIDTH,
+ });
+ });
+
+ it('when resizer emits update:size, changes inline width', () => {
+ const newSize = TEST_WIDTH - 100;
+ const resizer = findResizer();
+
+ resizer.vm.$emit('update:size', newSize);
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findInlineStyle()).toBe(createInlineStyle(newSize));
+ });
+ });
+ });
+});
diff --git a/spec/frontend/ide/components/terminal/empty_state_spec.js b/spec/frontend/ide/components/terminal/empty_state_spec.js
new file mode 100644
index 00000000000..a3f2089608d
--- /dev/null
+++ b/spec/frontend/ide/components/terminal/empty_state_spec.js
@@ -0,0 +1,107 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlLoadingIcon } from '@gitlab/ui';
+import { TEST_HOST } from 'spec/test_constants';
+import TerminalEmptyState from '~/ide/components/terminal/empty_state.vue';
+
+const TEST_HELP_PATH = `${TEST_HOST}/help/test`;
+const TEST_PATH = `${TEST_HOST}/home.png`;
+const TEST_HTML_MESSAGE = 'lorem <strong>ipsum</strong>';
+
+describe('IDE TerminalEmptyState', () => {
+ let wrapper;
+
+ const factory = (options = {}) => {
+ wrapper = shallowMount(TerminalEmptyState, {
+ ...options,
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('does not show illustration, if no path specified', () => {
+ factory();
+
+ expect(wrapper.find('.svg-content').exists()).toBe(false);
+ });
+
+ it('shows illustration with path', () => {
+ factory({
+ propsData: {
+ illustrationPath: TEST_PATH,
+ },
+ });
+
+ const img = wrapper.find('.svg-content img');
+
+ expect(img.exists()).toBe(true);
+ expect(img.attributes('src')).toEqual(TEST_PATH);
+ });
+
+ it('when loading, shows loading icon', () => {
+ factory({
+ propsData: {
+ isLoading: true,
+ },
+ });
+
+ expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
+ });
+
+ it('when not loading, does not show loading icon', () => {
+ factory({
+ propsData: {
+ isLoading: false,
+ },
+ });
+
+ expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
+ });
+
+ describe('when valid', () => {
+ let button;
+
+ beforeEach(() => {
+ factory({
+ propsData: {
+ isLoading: false,
+ isValid: true,
+ helpPath: TEST_HELP_PATH,
+ },
+ });
+
+ button = wrapper.find('button');
+ });
+
+ it('shows button', () => {
+ expect(button.text()).toEqual('Start Web Terminal');
+ expect(button.attributes('disabled')).toBeFalsy();
+ });
+
+ it('emits start when button is clicked', () => {
+ expect(wrapper.emitted().start).toBeFalsy();
+
+ button.trigger('click');
+
+ expect(wrapper.emitted().start).toHaveLength(1);
+ });
+
+ it('shows help path link', () => {
+ expect(wrapper.find('a').attributes('href')).toEqual(TEST_HELP_PATH);
+ });
+ });
+
+ it('when not valid, shows disabled button and message', () => {
+ factory({
+ propsData: {
+ isLoading: false,
+ isValid: false,
+ message: TEST_HTML_MESSAGE,
+ },
+ });
+
+ expect(wrapper.find('button').attributes('disabled')).not.toBe(null);
+ expect(wrapper.find('.bs-callout').element.innerHTML).toEqual(TEST_HTML_MESSAGE);
+ });
+});
diff --git a/spec/frontend/ide/components/terminal/session_spec.js b/spec/frontend/ide/components/terminal/session_spec.js
new file mode 100644
index 00000000000..2399446ed15
--- /dev/null
+++ b/spec/frontend/ide/components/terminal/session_spec.js
@@ -0,0 +1,96 @@
+import { createLocalVue, shallowMount } from '@vue/test-utils';
+import Vuex from 'vuex';
+import TerminalSession from '~/ide/components/terminal/session.vue';
+import Terminal from '~/ide/components/terminal/terminal.vue';
+import {
+ STARTING,
+ PENDING,
+ RUNNING,
+ STOPPING,
+ STOPPED,
+} from '~/ide/stores/modules/terminal/constants';
+
+const TEST_TERMINAL_PATH = 'terminal/path';
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+describe('IDE TerminalSession', () => {
+ let wrapper;
+ let actions;
+ let state;
+
+ const factory = (options = {}) => {
+ const store = new Vuex.Store({
+ modules: {
+ terminal: {
+ namespaced: true,
+ actions,
+ state,
+ },
+ },
+ });
+
+ wrapper = shallowMount(TerminalSession, {
+ localVue,
+ store,
+ ...options,
+ });
+ };
+
+ beforeEach(() => {
+ state = {
+ session: { status: RUNNING, terminalPath: TEST_TERMINAL_PATH },
+ };
+ actions = {
+ restartSession: jest.fn(),
+ stopSession: jest.fn(),
+ };
+ });
+
+ it('is empty if session is falsey', () => {
+ state.session = null;
+ factory();
+
+ expect(wrapper.isEmpty()).toBe(true);
+ });
+
+ it('shows terminal', () => {
+ factory();
+
+ expect(wrapper.find(Terminal).props()).toEqual({
+ terminalPath: TEST_TERMINAL_PATH,
+ status: RUNNING,
+ });
+ });
+
+ [STARTING, PENDING, RUNNING].forEach(status => {
+ it(`show stop button when status is ${status}`, () => {
+ state.session = { status };
+ factory();
+
+ const button = wrapper.find('button');
+ button.trigger('click');
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(button.text()).toEqual('Stop Terminal');
+ expect(actions.stopSession).toHaveBeenCalled();
+ });
+ });
+ });
+
+ [STOPPING, STOPPED].forEach(status => {
+ it(`show stop button when status is ${status}`, () => {
+ state.session = { status };
+ factory();
+
+ const button = wrapper.find('button');
+ button.trigger('click');
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(button.text()).toEqual('Restart Terminal');
+ expect(actions.restartSession).toHaveBeenCalled();
+ });
+ });
+ });
+});
diff --git a/spec/frontend/ide/components/terminal/terminal_controls_spec.js b/spec/frontend/ide/components/terminal/terminal_controls_spec.js
new file mode 100644
index 00000000000..6c2871abb46
--- /dev/null
+++ b/spec/frontend/ide/components/terminal/terminal_controls_spec.js
@@ -0,0 +1,65 @@
+import { shallowMount } from '@vue/test-utils';
+import TerminalControls from '~/ide/components/terminal/terminal_controls.vue';
+import ScrollButton from '~/ide/components/jobs/detail/scroll_button.vue';
+
+describe('IDE TerminalControls', () => {
+ let wrapper;
+ let buttons;
+
+ const factory = (options = {}) => {
+ wrapper = shallowMount(TerminalControls, {
+ ...options,
+ });
+
+ buttons = wrapper.findAll(ScrollButton);
+ };
+
+ it('shows an up and down scroll button', () => {
+ factory();
+
+ expect(buttons.wrappers.map(x => x.props())).toEqual([
+ expect.objectContaining({ direction: 'up', disabled: true }),
+ expect.objectContaining({ direction: 'down', disabled: true }),
+ ]);
+ });
+
+ it('enables up button with prop', () => {
+ factory({ propsData: { canScrollUp: true } });
+
+ expect(buttons.at(0).props()).toEqual(
+ expect.objectContaining({ direction: 'up', disabled: false }),
+ );
+ });
+
+ it('enables down button with prop', () => {
+ factory({ propsData: { canScrollDown: true } });
+
+ expect(buttons.at(1).props()).toEqual(
+ expect.objectContaining({ direction: 'down', disabled: false }),
+ );
+ });
+
+ it('emits "scroll-up" when click up button', () => {
+ factory({ propsData: { canScrollUp: true } });
+
+ expect(wrapper.emittedByOrder()).toEqual([]);
+
+ buttons.at(0).vm.$emit('click');
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.emittedByOrder()).toEqual([{ name: 'scroll-up', args: [] }]);
+ });
+ });
+
+ it('emits "scroll-down" when click down button', () => {
+ factory({ propsData: { canScrollDown: true } });
+
+ expect(wrapper.emittedByOrder()).toEqual([]);
+
+ buttons.at(1).vm.$emit('click');
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.emittedByOrder()).toEqual([{ name: 'scroll-down', args: [] }]);
+ });
+ });
+});
diff --git a/spec/frontend/ide/components/terminal/terminal_spec.js b/spec/frontend/ide/components/terminal/terminal_spec.js
new file mode 100644
index 00000000000..3095288bb28
--- /dev/null
+++ b/spec/frontend/ide/components/terminal/terminal_spec.js
@@ -0,0 +1,225 @@
+import { createLocalVue, shallowMount } from '@vue/test-utils';
+import Vuex from 'vuex';
+import { GlLoadingIcon } from '@gitlab/ui';
+import Terminal from '~/ide/components/terminal/terminal.vue';
+import TerminalControls from '~/ide/components/terminal/terminal_controls.vue';
+import {
+ STARTING,
+ PENDING,
+ RUNNING,
+ STOPPING,
+ STOPPED,
+} from '~/ide/stores/modules/terminal/constants';
+import GLTerminal from '~/terminal/terminal';
+
+const TEST_TERMINAL_PATH = 'terminal/path';
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+jest.mock('~/terminal/terminal', () =>
+ jest.fn().mockImplementation(() => ({
+ dispose: jest.fn(),
+ disable: jest.fn(),
+ addScrollListener: jest.fn(),
+ scrollToTop: jest.fn(),
+ scrollToBottom: jest.fn(),
+ })),
+);
+
+describe('IDE Terminal', () => {
+ let wrapper;
+ let state;
+
+ const factory = propsData => {
+ const store = new Vuex.Store({
+ state,
+ mutations: {
+ set(prevState, newState) {
+ Object.assign(prevState, newState);
+ },
+ },
+ });
+
+ wrapper = shallowMount(localVue.extend(Terminal), {
+ propsData: {
+ status: RUNNING,
+ terminalPath: TEST_TERMINAL_PATH,
+ ...propsData,
+ },
+ localVue,
+ store,
+ });
+ };
+
+ beforeEach(() => {
+ state = {
+ panelResizing: false,
+ };
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('loading text', () => {
+ [STARTING, PENDING].forEach(status => {
+ it(`shows when starting (${status})`, () => {
+ factory({ status });
+
+ expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
+ expect(wrapper.find('.top-bar').text()).toBe('Starting...');
+ });
+ });
+
+ it(`shows when stopping`, () => {
+ factory({ status: STOPPING });
+
+ expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
+ expect(wrapper.find('.top-bar').text()).toBe('Stopping...');
+ });
+
+ [RUNNING, STOPPED].forEach(status => {
+ it('hides when not loading', () => {
+ factory({ status });
+
+ expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
+ expect(wrapper.find('.top-bar').text()).toBe('');
+ });
+ });
+ });
+
+ describe('refs.terminal', () => {
+ it('has terminal path in data', () => {
+ factory();
+
+ expect(wrapper.vm.$refs.terminal.dataset.projectPath).toBe(TEST_TERMINAL_PATH);
+ });
+ });
+
+ describe('terminal controls', () => {
+ beforeEach(() => {
+ factory();
+ wrapper.vm.createTerminal();
+
+ return localVue.nextTick();
+ });
+
+ it('is visible if terminal is created', () => {
+ expect(wrapper.find(TerminalControls).exists()).toBe(true);
+ });
+
+ it('scrolls glterminal on scroll-up', () => {
+ wrapper.find(TerminalControls).vm.$emit('scroll-up');
+
+ expect(wrapper.vm.glterminal.scrollToTop).toHaveBeenCalled();
+ });
+
+ it('scrolls glterminal on scroll-down', () => {
+ wrapper.find(TerminalControls).vm.$emit('scroll-down');
+
+ expect(wrapper.vm.glterminal.scrollToBottom).toHaveBeenCalled();
+ });
+
+ it('has props set', () => {
+ expect(wrapper.find(TerminalControls).props()).toEqual({
+ canScrollUp: false,
+ canScrollDown: false,
+ });
+
+ wrapper.setData({ canScrollUp: true, canScrollDown: true });
+
+ return localVue.nextTick().then(() => {
+ expect(wrapper.find(TerminalControls).props()).toEqual({
+ canScrollUp: true,
+ canScrollDown: true,
+ });
+ });
+ });
+ });
+
+ describe('refresh', () => {
+ let createTerminal;
+ let stopTerminal;
+
+ beforeEach(() => {
+ createTerminal = jest.fn().mockName('createTerminal');
+ stopTerminal = jest.fn().mockName('stopTerminal');
+ });
+
+ it('creates the terminal if running', () => {
+ factory({ status: RUNNING, terminalPath: TEST_TERMINAL_PATH });
+
+ wrapper.setMethods({ createTerminal });
+ wrapper.vm.refresh();
+
+ expect(createTerminal).toHaveBeenCalled();
+ });
+
+ it('stops the terminal if stopping', () => {
+ factory({ status: STOPPING });
+
+ wrapper.setMethods({ stopTerminal });
+ wrapper.vm.refresh();
+
+ expect(stopTerminal).toHaveBeenCalled();
+ });
+ });
+
+ describe('createTerminal', () => {
+ beforeEach(() => {
+ factory();
+ wrapper.vm.createTerminal();
+ });
+
+ it('creates the terminal', () => {
+ expect(GLTerminal).toHaveBeenCalledWith(wrapper.vm.$refs.terminal);
+ expect(wrapper.vm.glterminal).toBeTruthy();
+ });
+
+ describe('scroll listener', () => {
+ it('has been called', () => {
+ expect(wrapper.vm.glterminal.addScrollListener).toHaveBeenCalled();
+ });
+
+ it('updates scroll data when called', () => {
+ expect(wrapper.vm.canScrollUp).toBe(false);
+ expect(wrapper.vm.canScrollDown).toBe(false);
+
+ const listener = wrapper.vm.glterminal.addScrollListener.mock.calls[0][0];
+ listener({ canScrollUp: true, canScrollDown: true });
+
+ expect(wrapper.vm.canScrollUp).toBe(true);
+ expect(wrapper.vm.canScrollDown).toBe(true);
+ });
+ });
+ });
+
+ describe('destroyTerminal', () => {
+ it('calls dispose', () => {
+ factory();
+ wrapper.vm.createTerminal();
+ const disposeSpy = wrapper.vm.glterminal.dispose;
+
+ expect(disposeSpy).not.toHaveBeenCalled();
+
+ wrapper.vm.destroyTerminal();
+
+ expect(disposeSpy).toHaveBeenCalled();
+ expect(wrapper.vm.glterminal).toBe(null);
+ });
+ });
+
+ describe('stopTerminal', () => {
+ it('calls disable', () => {
+ factory();
+ wrapper.vm.createTerminal();
+
+ expect(wrapper.vm.glterminal.disable).not.toHaveBeenCalled();
+
+ wrapper.vm.stopTerminal();
+
+ expect(wrapper.vm.glterminal.disable).toHaveBeenCalled();
+ });
+ });
+});
diff --git a/spec/frontend/ide/components/terminal/view_spec.js b/spec/frontend/ide/components/terminal/view_spec.js
new file mode 100644
index 00000000000..eff200550da
--- /dev/null
+++ b/spec/frontend/ide/components/terminal/view_spec.js
@@ -0,0 +1,91 @@
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import Vuex from 'vuex';
+import { TEST_HOST } from 'spec/test_constants';
+import TerminalEmptyState from '~/ide/components/terminal/empty_state.vue';
+import TerminalView from '~/ide/components/terminal/view.vue';
+import TerminalSession from '~/ide/components/terminal/session.vue';
+
+const TEST_HELP_PATH = `${TEST_HOST}/help`;
+const TEST_SVG_PATH = `${TEST_HOST}/illustration.svg`;
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+describe('IDE TerminalView', () => {
+ let state;
+ let actions;
+ let getters;
+ let wrapper;
+
+ const factory = () => {
+ const store = new Vuex.Store({
+ modules: {
+ terminal: {
+ namespaced: true,
+ state,
+ actions,
+ getters,
+ },
+ },
+ });
+
+ wrapper = shallowMount(TerminalView, { localVue, store });
+ };
+
+ beforeEach(() => {
+ state = {
+ isShowSplash: true,
+ paths: {
+ webTerminalHelpPath: TEST_HELP_PATH,
+ webTerminalSvgPath: TEST_SVG_PATH,
+ },
+ };
+
+ actions = {
+ hideSplash: jest.fn().mockName('hideSplash'),
+ startSession: jest.fn().mockName('startSession'),
+ };
+
+ getters = {
+ allCheck: () => ({
+ isLoading: false,
+ isValid: false,
+ message: 'bad',
+ }),
+ };
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders empty state', () => {
+ factory();
+
+ expect(wrapper.find(TerminalEmptyState).props()).toEqual({
+ helpPath: TEST_HELP_PATH,
+ illustrationPath: TEST_SVG_PATH,
+ ...getters.allCheck(),
+ });
+ });
+
+ it('hides splash and starts, when started', () => {
+ factory();
+
+ expect(actions.startSession).not.toHaveBeenCalled();
+ expect(actions.hideSplash).not.toHaveBeenCalled();
+
+ wrapper.find(TerminalEmptyState).vm.$emit('start');
+
+ expect(actions.startSession).toHaveBeenCalled();
+ expect(actions.hideSplash).toHaveBeenCalled();
+ });
+
+ it('shows Web Terminal when started', () => {
+ state.isShowSplash = false;
+ factory();
+
+ expect(wrapper.find(TerminalEmptyState).exists()).toBe(false);
+ expect(wrapper.find(TerminalSession).exists()).toBe(true);
+ });
+});
diff --git a/spec/frontend/ide/components/terminal_sync/terminal_sync_status_safe_spec.js b/spec/frontend/ide/components/terminal_sync/terminal_sync_status_safe_spec.js
new file mode 100644
index 00000000000..afdecb7bbbd
--- /dev/null
+++ b/spec/frontend/ide/components/terminal_sync/terminal_sync_status_safe_spec.js
@@ -0,0 +1,47 @@
+import Vuex from 'vuex';
+import { createLocalVue, shallowMount } from '@vue/test-utils';
+import TerminalSyncStatus from '~/ide/components/terminal_sync/terminal_sync_status.vue';
+import TerminalSyncStatusSafe from '~/ide/components/terminal_sync/terminal_sync_status_safe.vue';
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+describe('ide/components/terminal_sync/terminal_sync_status_safe', () => {
+ let store;
+ let wrapper;
+
+ const createComponent = () => {
+ store = new Vuex.Store({
+ state: {},
+ });
+
+ wrapper = shallowMount(TerminalSyncStatusSafe, {
+ localVue,
+ store,
+ });
+ };
+
+ beforeEach(createComponent);
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('with terminal sync module in store', () => {
+ beforeEach(() => {
+ store.registerModule('terminalSync', {
+ state: {},
+ });
+ });
+
+ it('renders terminal sync status', () => {
+ expect(wrapper.find(TerminalSyncStatus).exists()).toBe(true);
+ });
+ });
+
+ describe('without terminal sync module', () => {
+ it('does not render terminal sync status', () => {
+ expect(wrapper.find(TerminalSyncStatus).exists()).toBe(false);
+ });
+ });
+});
diff --git a/spec/frontend/ide/components/terminal_sync/terminal_sync_status_spec.js b/spec/frontend/ide/components/terminal_sync/terminal_sync_status_spec.js
new file mode 100644
index 00000000000..16a76fae1dd
--- /dev/null
+++ b/spec/frontend/ide/components/terminal_sync/terminal_sync_status_spec.js
@@ -0,0 +1,99 @@
+import Vuex from 'vuex';
+import { createLocalVue, shallowMount } from '@vue/test-utils';
+import { GlLoadingIcon } from '@gitlab/ui';
+import TerminalSyncStatus from '~/ide/components/terminal_sync/terminal_sync_status.vue';
+import {
+ MSG_TERMINAL_SYNC_CONNECTING,
+ MSG_TERMINAL_SYNC_UPLOADING,
+ MSG_TERMINAL_SYNC_RUNNING,
+} from '~/ide/stores/modules/terminal_sync/messages';
+import Icon from '~/vue_shared/components/icon.vue';
+
+const TEST_MESSAGE = 'lorem ipsum dolar sit';
+const START_LOADING = 'START_LOADING';
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+describe('ide/components/terminal_sync/terminal_sync_status', () => {
+ let moduleState;
+ let store;
+ let wrapper;
+
+ const createComponent = () => {
+ store = new Vuex.Store({
+ modules: {
+ terminalSync: {
+ namespaced: true,
+ state: moduleState,
+ mutations: {
+ [START_LOADING]: state => {
+ state.isLoading = true;
+ },
+ },
+ },
+ },
+ });
+
+ wrapper = shallowMount(TerminalSyncStatus, {
+ localVue,
+ store,
+ });
+ };
+
+ beforeEach(() => {
+ moduleState = {
+ isLoading: false,
+ isStarted: false,
+ isError: false,
+ message: '',
+ };
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('when doing nothing', () => {
+ it('shows nothing', () => {
+ createComponent();
+
+ expect(wrapper.isEmpty()).toBe(true);
+ });
+ });
+
+ describe.each`
+ description | state | statusMessage | icon
+ ${'when loading'} | ${{ isLoading: true }} | ${MSG_TERMINAL_SYNC_CONNECTING} | ${''}
+ ${'when loading and started'} | ${{ isLoading: true, isStarted: true }} | ${MSG_TERMINAL_SYNC_UPLOADING} | ${''}
+ ${'when error'} | ${{ isError: true, message: TEST_MESSAGE }} | ${TEST_MESSAGE} | ${'warning'}
+ ${'when started'} | ${{ isStarted: true }} | ${MSG_TERMINAL_SYNC_RUNNING} | ${'mobile-issue-close'}
+ `('$description', ({ state, statusMessage, icon }) => {
+ beforeEach(() => {
+ Object.assign(moduleState, state);
+ createComponent();
+ });
+
+ it('shows message', () => {
+ expect(wrapper.attributes('title')).toContain(statusMessage);
+ });
+
+ if (!icon) {
+ it('does not render icon', () => {
+ expect(wrapper.find(Icon).exists()).toBe(false);
+ });
+
+ it('renders loading icon', () => {
+ expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
+ });
+ } else {
+ it('renders icon', () => {
+ expect(wrapper.find(Icon).props('name')).toEqual(icon);
+ });
+
+ it('does not render loading icon', () => {
+ expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
+ });
+ }
+ });
+});
diff --git a/spec/frontend/ide/file_helpers.js b/spec/frontend/ide/file_helpers.js
new file mode 100644
index 00000000000..326f8b9716d
--- /dev/null
+++ b/spec/frontend/ide/file_helpers.js
@@ -0,0 +1,35 @@
+export const createFile = (path, content = '') => ({
+ id: path,
+ path,
+ content,
+ raw: content,
+});
+
+export const createNewFile = (path, content) =>
+ Object.assign(createFile(path, content), {
+ tempFile: true,
+ raw: '',
+ });
+
+export const createDeletedFile = (path, content) =>
+ Object.assign(createFile(path, content), {
+ deleted: true,
+ });
+
+export const createUpdatedFile = (path, oldContent, content) =>
+ Object.assign(createFile(path, content), {
+ raw: oldContent,
+ });
+
+export const createMovedFile = (path, prevPath, content) =>
+ Object.assign(createNewFile(path, content), {
+ prevPath,
+ });
+
+export const createEntries = path =>
+ path.split('/').reduce((acc, part, idx, parts) => {
+ const parentPath = parts.slice(0, idx).join('/');
+ const fullPath = parentPath ? `${parentPath}/${part}` : part;
+
+ return Object.assign(acc, { [fullPath]: { ...createFile(fullPath), parentPath } });
+ }, {});
diff --git a/spec/frontend/ide/ide_router_spec.js b/spec/frontend/ide/ide_router_spec.js
index 1461b756d13..b53e2019819 100644
--- a/spec/frontend/ide/ide_router_spec.js
+++ b/spec/frontend/ide/ide_router_spec.js
@@ -1,17 +1,20 @@
-import router from '~/ide/ide_router';
-import store from '~/ide/stores';
+import { createRouter } from '~/ide/ide_router';
+import { createStore } from '~/ide/stores';
+import waitForPromises from 'helpers/wait_for_promises';
describe('IDE router', () => {
const PROJECT_NAMESPACE = 'my-group/sub-group';
const PROJECT_NAME = 'my-project';
+ const TEST_PATH = `/project/${PROJECT_NAMESPACE}/${PROJECT_NAME}/merge_requests/2`;
- afterEach(() => {
- router.push('/');
- });
+ let store;
+ let router;
- afterAll(() => {
- // VueRouter leaves this window.history at the "base" url. We need to clean this up.
+ beforeEach(() => {
window.history.replaceState({}, '', '/');
+ store = createStore();
+ router = createRouter(store);
+ jest.spyOn(store, 'dispatch').mockReturnValue(new Promise(() => {}));
});
[
@@ -31,8 +34,6 @@ describe('IDE router', () => {
`/project/${PROJECT_NAMESPACE}/${PROJECT_NAME}`,
].forEach(route => {
it(`finds project path when route is "${route}"`, () => {
- jest.spyOn(store, 'dispatch').mockReturnValue(new Promise(() => {}));
-
router.push(route);
expect(store.dispatch).toHaveBeenCalledWith('getProjectData', {
@@ -41,4 +42,22 @@ describe('IDE router', () => {
});
});
});
+
+ it('keeps router in sync when store changes', async () => {
+ expect(router.currentRoute.fullPath).toBe('/');
+
+ store.state.router.fullPath = TEST_PATH;
+
+ await waitForPromises();
+
+ expect(router.currentRoute.fullPath).toBe(TEST_PATH);
+ });
+
+ it('keeps store in sync when router changes', () => {
+ expect(store.dispatch).not.toHaveBeenCalled();
+
+ router.push(TEST_PATH);
+
+ expect(store.dispatch).toHaveBeenCalledWith('router/push', TEST_PATH, { root: true });
+ });
});
diff --git a/spec/frontend/ide/lib/common/model_spec.js b/spec/frontend/ide/lib/common/model_spec.js
index 2ef2f0da6da..df46b7774b0 100644
--- a/spec/frontend/ide/lib/common/model_spec.js
+++ b/spec/frontend/ide/lib/common/model_spec.js
@@ -133,5 +133,77 @@ describe('Multi-file editor library model', () => {
expect(disposeSpy).toHaveBeenCalled();
});
+
+ it('applies custom options and triggers onChange callback', () => {
+ const changeSpy = jest.fn();
+ jest.spyOn(model, 'applyCustomOptions');
+
+ model.onChange(changeSpy);
+
+ model.dispose();
+
+ expect(model.applyCustomOptions).toHaveBeenCalled();
+ expect(changeSpy).toHaveBeenCalled();
+ });
+ });
+
+ describe('updateOptions', () => {
+ it('sets the options on the options object', () => {
+ model.updateOptions({ insertSpaces: true, someOption: 'some value' });
+
+ expect(model.options).toEqual({
+ endOfLine: 0,
+ insertFinalNewline: true,
+ insertSpaces: true,
+ someOption: 'some value',
+ trimTrailingWhitespace: false,
+ });
+ });
+
+ it.each`
+ option | value
+ ${'insertSpaces'} | ${true}
+ ${'insertSpaces'} | ${false}
+ ${'indentSize'} | ${4}
+ ${'tabSize'} | ${3}
+ `("correctly sets option: $option=$value to Monaco's TextModel", ({ option, value }) => {
+ model.updateOptions({ [option]: value });
+
+ expect(model.getModel().getOptions()).toMatchObject({ [option]: value });
+ });
+
+ it('applies custom options immediately', () => {
+ jest.spyOn(model, 'applyCustomOptions');
+
+ model.updateOptions({ trimTrailingWhitespace: true, someOption: 'some value' });
+
+ expect(model.applyCustomOptions).toHaveBeenCalled();
+ });
+ });
+
+ describe('applyCustomOptions', () => {
+ it.each`
+ option | value | contentBefore | contentAfter
+ ${'endOfLine'} | ${0} | ${'hello\nworld\n'} | ${'hello\nworld\n'}
+ ${'endOfLine'} | ${0} | ${'hello\r\nworld\r\n'} | ${'hello\nworld\n'}
+ ${'endOfLine'} | ${1} | ${'hello\nworld\n'} | ${'hello\r\nworld\r\n'}
+ ${'endOfLine'} | ${1} | ${'hello\r\nworld\r\n'} | ${'hello\r\nworld\r\n'}
+ ${'insertFinalNewline'} | ${true} | ${'hello\nworld'} | ${'hello\nworld\n'}
+ ${'insertFinalNewline'} | ${true} | ${'hello\nworld\n'} | ${'hello\nworld\n'}
+ ${'insertFinalNewline'} | ${false} | ${'hello\nworld'} | ${'hello\nworld'}
+ ${'trimTrailingWhitespace'} | ${true} | ${'hello \t\nworld \t\n'} | ${'hello\nworld\n'}
+ ${'trimTrailingWhitespace'} | ${true} | ${'hello \t\r\nworld \t\r\n'} | ${'hello\nworld\n'}
+ ${'trimTrailingWhitespace'} | ${false} | ${'hello \t\r\nworld \t\r\n'} | ${'hello \t\nworld \t\n'}
+ `(
+ 'correctly applies custom option $option=$value to content',
+ ({ option, value, contentBefore, contentAfter }) => {
+ model.options[option] = value;
+
+ model.updateNewContent(contentBefore);
+ model.applyCustomOptions();
+
+ expect(model.getModel().getValue()).toEqual(contentAfter);
+ },
+ );
});
});
diff --git a/spec/frontend/ide/lib/create_diff_spec.js b/spec/frontend/ide/lib/create_diff_spec.js
new file mode 100644
index 00000000000..273f9ee27bd
--- /dev/null
+++ b/spec/frontend/ide/lib/create_diff_spec.js
@@ -0,0 +1,182 @@
+import createDiff from '~/ide/lib/create_diff';
+import createFileDiff from '~/ide/lib/create_file_diff';
+import { commitActionTypes } from '~/ide/constants';
+import {
+ createNewFile,
+ createUpdatedFile,
+ createDeletedFile,
+ createMovedFile,
+ createEntries,
+} from '../file_helpers';
+
+const PATH_FOO = 'test/foo.md';
+const PATH_BAR = 'test/bar.md';
+const PATH_ZED = 'test/zed.md';
+const PATH_LOREM = 'test/lipsum/nested/lorem.md';
+const PATH_IPSUM = 'test/lipsum/ipsum.md';
+const TEXT = `Lorem ipsum dolor sit amet,
+consectetur adipiscing elit.
+Morbi ex dolor, euismod nec rutrum nec, egestas at ligula.
+Praesent scelerisque ut nisi eu eleifend.
+Suspendisse potenti.
+`;
+const LINES = TEXT.trim().split('\n');
+
+const joinDiffs = (...patches) => patches.join('');
+
+describe('IDE lib/create_diff', () => {
+ it('with created files, generates patch', () => {
+ const changedFiles = [createNewFile(PATH_FOO, TEXT), createNewFile(PATH_BAR, '')];
+ const result = createDiff({ changedFiles });
+
+ expect(result).toEqual({
+ patch: joinDiffs(
+ createFileDiff(changedFiles[0], commitActionTypes.create),
+ createFileDiff(changedFiles[1], commitActionTypes.create),
+ ),
+ toDelete: [],
+ });
+ });
+
+ it('with deleted files, adds to delete', () => {
+ const changedFiles = [createDeletedFile(PATH_FOO, TEXT), createDeletedFile(PATH_BAR, '')];
+
+ const result = createDiff({ changedFiles });
+
+ expect(result).toEqual({
+ patch: '',
+ toDelete: [PATH_FOO, PATH_BAR],
+ });
+ });
+
+ it('with updated files, generates patch', () => {
+ const changedFiles = [createUpdatedFile(PATH_FOO, TEXT, 'A change approaches!')];
+
+ const result = createDiff({ changedFiles });
+
+ expect(result).toEqual({
+ patch: createFileDiff(changedFiles[0], commitActionTypes.update),
+ toDelete: [],
+ });
+ });
+
+ it('with files in both staged and changed, prefer changed', () => {
+ const changedFiles = [
+ createUpdatedFile(PATH_FOO, TEXT, 'Do a change!'),
+ createDeletedFile(PATH_LOREM),
+ ];
+
+ const result = createDiff({
+ changedFiles,
+ stagedFiles: [createUpdatedFile(PATH_LOREM, TEXT, ''), createDeletedFile(PATH_FOO, TEXT)],
+ });
+
+ expect(result).toEqual({
+ patch: createFileDiff(changedFiles[0], commitActionTypes.update),
+ toDelete: [PATH_LOREM],
+ });
+ });
+
+ it('with file created in staging and deleted in changed, do nothing', () => {
+ const result = createDiff({
+ changedFiles: [createDeletedFile(PATH_FOO)],
+ stagedFiles: [createNewFile(PATH_FOO, TEXT)],
+ });
+
+ expect(result).toEqual({
+ patch: '',
+ toDelete: [],
+ });
+ });
+
+ it('with file deleted in both staged and changed, delete', () => {
+ const result = createDiff({
+ changedFiles: [createDeletedFile(PATH_LOREM)],
+ stagedFiles: [createDeletedFile(PATH_LOREM)],
+ });
+
+ expect(result).toEqual({
+ patch: '',
+ toDelete: [PATH_LOREM],
+ });
+ });
+
+ it('with file moved, create and delete', () => {
+ const changedFiles = [createMovedFile(PATH_BAR, PATH_FOO, TEXT)];
+
+ const result = createDiff({
+ changedFiles,
+ stagedFiles: [createDeletedFile(PATH_FOO)],
+ });
+
+ expect(result).toEqual({
+ patch: createFileDiff(changedFiles[0], commitActionTypes.create),
+ toDelete: [PATH_FOO],
+ });
+ });
+
+ it('with file moved and no content, move', () => {
+ const changedFiles = [createMovedFile(PATH_BAR, PATH_FOO)];
+
+ const result = createDiff({
+ changedFiles,
+ stagedFiles: [createDeletedFile(PATH_FOO)],
+ });
+
+ expect(result).toEqual({
+ patch: createFileDiff(changedFiles[0], commitActionTypes.move),
+ toDelete: [],
+ });
+ });
+
+ it('creates a well formatted patch', () => {
+ const changedFiles = [
+ createMovedFile(PATH_BAR, PATH_FOO),
+ createDeletedFile(PATH_ZED),
+ createNewFile(PATH_LOREM, TEXT),
+ createUpdatedFile(PATH_IPSUM, TEXT, "That's all folks!"),
+ ];
+
+ const expectedPatch = `diff --git "a/${PATH_FOO}" "b/${PATH_BAR}"
+rename from ${PATH_FOO}
+rename to ${PATH_BAR}
+diff --git "a/${PATH_LOREM}" "b/${PATH_LOREM}"
+new file mode 100644
+--- /dev/null
++++ b/${PATH_LOREM}
+@@ -0,0 +1,${LINES.length} @@
+${LINES.map(line => `+${line}`).join('\n')}
+diff --git "a/${PATH_IPSUM}" "b/${PATH_IPSUM}"
+--- a/${PATH_IPSUM}
++++ b/${PATH_IPSUM}
+@@ -1,${LINES.length} +1,1 @@
+${LINES.map(line => `-${line}`).join('\n')}
++That's all folks!
+\\ No newline at end of file
+`;
+
+ const result = createDiff({ changedFiles });
+
+ expect(result).toEqual({
+ patch: expectedPatch,
+ toDelete: [PATH_ZED],
+ });
+ });
+
+ it('deletes deleted parent directories', () => {
+ const deletedFiles = ['foo/bar/zed/test.md', 'foo/bar/zed/test2.md'];
+ const entries = deletedFiles.reduce((acc, path) => Object.assign(acc, createEntries(path)), {});
+ const allDeleted = [...deletedFiles, 'foo/bar/zed', 'foo/bar'];
+ allDeleted.forEach(path => {
+ entries[path].deleted = true;
+ });
+ const changedFiles = deletedFiles.map(x => entries[x]);
+
+ const result = createDiff({ changedFiles, entries });
+
+ expect(result).toEqual({
+ patch: '',
+ toDelete: allDeleted,
+ });
+ });
+});
diff --git a/spec/frontend/ide/lib/create_file_diff_spec.js b/spec/frontend/ide/lib/create_file_diff_spec.js
new file mode 100644
index 00000000000..4b428468a6d
--- /dev/null
+++ b/spec/frontend/ide/lib/create_file_diff_spec.js
@@ -0,0 +1,163 @@
+import createFileDiff from '~/ide/lib/create_file_diff';
+import { commitActionTypes } from '~/ide/constants';
+import {
+ createUpdatedFile,
+ createNewFile,
+ createMovedFile,
+ createDeletedFile,
+} from '../file_helpers';
+
+const PATH = 'test/numbers.md';
+const PATH_FOO = 'test/foo.md';
+const TEXT_LINE_COUNT = 100;
+const TEXT = Array(TEXT_LINE_COUNT)
+ .fill(0)
+ .map((_, idx) => `${idx + 1}`)
+ .join('\n');
+
+const spliceLines = (content, lineNumber, deleteCount = 0, newLines = []) => {
+ const lines = content.split('\n');
+ lines.splice(lineNumber, deleteCount, ...newLines);
+ return lines.join('\n');
+};
+
+const mapLines = (content, mapFn) =>
+ content
+ .split('\n')
+ .map(mapFn)
+ .join('\n');
+
+describe('IDE lib/create_file_diff', () => {
+ it('returns empty string with "garbage" action', () => {
+ const result = createFileDiff(createNewFile(PATH, ''), 'garbage');
+
+ expect(result).toBe('');
+ });
+
+ it('preserves ending whitespace in file', () => {
+ const oldContent = spliceLines(TEXT, 99, 1, ['100 ']);
+ const newContent = spliceLines(oldContent, 99, 0, ['Lorem', 'Ipsum']);
+ const expected = `
+ 99
++Lorem
++Ipsum
+ 100 `;
+
+ const result = createFileDiff(
+ createUpdatedFile(PATH, oldContent, newContent),
+ commitActionTypes.update,
+ );
+
+ expect(result).toContain(expected);
+ });
+
+ describe('with "create" action', () => {
+ const expectedHead = `diff --git "a/${PATH}" "b/${PATH}"
+new file mode 100644`;
+
+ const expectedChunkHead = lineCount => `--- /dev/null
++++ b/${PATH}
+@@ -0,0 +1,${lineCount} @@`;
+
+ it('with empty file, does not include diff body', () => {
+ const result = createFileDiff(createNewFile(PATH, ''), commitActionTypes.create);
+
+ expect(result).toBe(`${expectedHead}\n`);
+ });
+
+ it('with single line, includes diff body', () => {
+ const result = createFileDiff(createNewFile(PATH, '\n'), commitActionTypes.create);
+
+ expect(result).toBe(`${expectedHead}
+${expectedChunkHead(1)}
++
+`);
+ });
+
+ it('without newline, includes no newline comment', () => {
+ const result = createFileDiff(createNewFile(PATH, 'Lorem ipsum'), commitActionTypes.create);
+
+ expect(result).toBe(`${expectedHead}
+${expectedChunkHead(1)}
++Lorem ipsum
+\\ No newline at end of file
+`);
+ });
+
+ it('with content, includes diff body', () => {
+ const content = `${TEXT}\n`;
+ const result = createFileDiff(createNewFile(PATH, content), commitActionTypes.create);
+
+ expect(result).toBe(`${expectedHead}
+${expectedChunkHead(TEXT_LINE_COUNT)}
+${mapLines(TEXT, line => `+${line}`)}
+`);
+ });
+ });
+
+ describe('with "delete" action', () => {
+ const expectedHead = `diff --git "a/${PATH}" "b/${PATH}"
+deleted file mode 100644`;
+
+ const expectedChunkHead = lineCount => `--- a/${PATH}
++++ /dev/null
+@@ -1,${lineCount} +0,0 @@`;
+
+ it('with empty file, does not include diff body', () => {
+ const result = createFileDiff(createDeletedFile(PATH, ''), commitActionTypes.delete);
+
+ expect(result).toBe(`${expectedHead}\n`);
+ });
+
+ it('with content, includes diff body', () => {
+ const content = `${TEXT}\n`;
+ const result = createFileDiff(createDeletedFile(PATH, content), commitActionTypes.delete);
+
+ expect(result).toBe(`${expectedHead}
+${expectedChunkHead(TEXT_LINE_COUNT)}
+${mapLines(TEXT, line => `-${line}`)}
+`);
+ });
+ });
+
+ describe('with "update" action', () => {
+ it('includes diff body', () => {
+ const oldContent = `${TEXT}\n`;
+ const newContent = `${spliceLines(TEXT, 50, 3, ['Lorem'])}\n`;
+
+ const result = createFileDiff(
+ createUpdatedFile(PATH, oldContent, newContent),
+ commitActionTypes.update,
+ );
+
+ expect(result).toBe(`diff --git "a/${PATH}" "b/${PATH}"
+--- a/${PATH}
++++ b/${PATH}
+@@ -47,11 +47,9 @@
+ 47
+ 48
+ 49
+ 50
+-51
+-52
+-53
++Lorem
+ 54
+ 55
+ 56
+ 57
+`);
+ });
+ });
+
+ describe('with "move" action', () => {
+ it('returns rename head', () => {
+ const result = createFileDiff(createMovedFile(PATH, PATH_FOO), commitActionTypes.move);
+
+ expect(result).toBe(`diff --git "a/${PATH_FOO}" "b/${PATH}"
+rename from ${PATH_FOO}
+rename to ${PATH}
+`);
+ });
+ });
+});
diff --git a/spec/frontend/ide/lib/diff/diff_spec.js b/spec/frontend/ide/lib/diff/diff_spec.js
index d9b088e2c12..901f9e7cfd1 100644
--- a/spec/frontend/ide/lib/diff/diff_spec.js
+++ b/spec/frontend/ide/lib/diff/diff_spec.js
@@ -73,5 +73,13 @@ describe('Multi-file editor library diff calculator', () => {
expect(diff.endLineNumber).toBe(1);
});
+
+ it('disregards changes for EOL type changes', () => {
+ const text1 = 'line1\nline2\nline3\n';
+ const text2 = 'line1\r\nline2\r\nline3\r\n';
+
+ expect(computeDiff(text1, text2)).toEqual([]);
+ expect(computeDiff(text2, text1)).toEqual([]);
+ });
});
});
diff --git a/spec/frontend/ide/lib/editor_options_spec.js b/spec/frontend/ide/lib/editor_options_spec.js
deleted file mode 100644
index b07a583b7c8..00000000000
--- a/spec/frontend/ide/lib/editor_options_spec.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import editorOptions from '~/ide/lib/editor_options';
-
-describe('Multi-file editor library editor options', () => {
- it('returns an array', () => {
- expect(editorOptions).toEqual(expect.any(Array));
- });
-
- it('contains readOnly option', () => {
- expect(editorOptions[0].readOnly).toBeDefined();
- });
-});
diff --git a/spec/frontend/ide/lib/editor_spec.js b/spec/frontend/ide/lib/editor_spec.js
index 36d4c3c26ee..f5815771cdf 100644
--- a/spec/frontend/ide/lib/editor_spec.js
+++ b/spec/frontend/ide/lib/editor_spec.js
@@ -1,4 +1,9 @@
-import { editor as monacoEditor, languages as monacoLanguages } from 'monaco-editor';
+import {
+ editor as monacoEditor,
+ languages as monacoLanguages,
+ Range,
+ Selection,
+} from 'monaco-editor';
import Editor from '~/ide/lib/editor';
import { defaultEditorOptions } from '~/ide/lib/editor_options';
import { file } from '../helpers';
@@ -72,12 +77,13 @@ describe('Multi-file editor library', () => {
expect(monacoEditor.createDiffEditor).toHaveBeenCalledWith(holder, {
...defaultEditorOptions,
+ ignoreTrimWhitespace: false,
quickSuggestions: false,
occurrencesHighlight: false,
renderSideBySide: false,
- readOnly: true,
- renderLineHighlight: 'all',
- hideCursorInOverviewRuler: false,
+ readOnly: false,
+ renderLineHighlight: 'none',
+ hideCursorInOverviewRuler: true,
});
});
});
@@ -193,6 +199,38 @@ describe('Multi-file editor library', () => {
});
});
+ describe('replaceSelectedText', () => {
+ let model;
+ let editor;
+
+ beforeEach(() => {
+ instance.createInstance(holder);
+
+ model = instance.createModel({
+ ...file(),
+ key: 'index.md',
+ path: 'index.md',
+ });
+
+ instance.attachModel(model);
+
+ editor = instance.instance;
+ editor.getModel().setValue('foo bar baz');
+ editor.setSelection(new Range(1, 5, 1, 8));
+
+ instance.replaceSelectedText('hello');
+ });
+
+ it('replaces the text selected in editor with the one provided', () => {
+ expect(editor.getModel().getValue()).toBe('foo hello baz');
+ });
+
+ it('sets cursor to end of the replaced string', () => {
+ const selection = editor.getSelection();
+ expect(selection).toEqual(new Selection(1, 10, 1, 10));
+ });
+ });
+
describe('dispose', () => {
it('calls disposble dispose method', () => {
jest.spyOn(instance.disposable, 'dispose');
diff --git a/spec/frontend/ide/lib/editorconfig/mock_data.js b/spec/frontend/ide/lib/editorconfig/mock_data.js
new file mode 100644
index 00000000000..b21f4a5b735
--- /dev/null
+++ b/spec/frontend/ide/lib/editorconfig/mock_data.js
@@ -0,0 +1,146 @@
+export const exampleConfigs = [
+ {
+ path: 'foo/bar/baz/.editorconfig',
+ content: `
+[*]
+tab_width = 6
+indent_style = tab
+`,
+ },
+ {
+ path: 'foo/bar/.editorconfig',
+ content: `
+root = false
+
+[*]
+indent_size = 5
+indent_style = space
+trim_trailing_whitespace = true
+
+[*_spec.{js,py}]
+end_of_line = crlf
+ `,
+ },
+ {
+ path: 'foo/.editorconfig',
+ content: `
+[*]
+tab_width = 4
+indent_style = tab
+ `,
+ },
+ {
+ path: '.editorconfig',
+ content: `
+root = true
+
+[*]
+indent_size = 3
+indent_style = space
+end_of_line = lf
+insert_final_newline = true
+
+[*.js]
+indent_size = 2
+indent_style = space
+trim_trailing_whitespace = true
+
+[*.txt]
+end_of_line = crlf
+ `,
+ },
+ {
+ path: 'foo/bar/root/.editorconfig',
+ content: `
+root = true
+
+[*]
+tab_width = 1
+indent_style = tab
+ `,
+ },
+];
+
+export const exampleFiles = [
+ {
+ path: 'foo/bar/root/README.md',
+ rules: {
+ indent_style: 'tab', // foo/bar/root/.editorconfig
+ tab_width: '1', // foo/bar/root/.editorconfig
+ },
+ monacoRules: {
+ insertSpaces: false,
+ tabSize: 1,
+ },
+ },
+ {
+ path: 'foo/bar/baz/my_spec.js',
+ rules: {
+ end_of_line: 'crlf', // foo/bar/.editorconfig (for _spec.js files)
+ indent_size: '5', // foo/bar/.editorconfig
+ indent_style: 'tab', // foo/bar/baz/.editorconfig
+ insert_final_newline: 'true', // .editorconfig
+ tab_width: '6', // foo/bar/baz/.editorconfig
+ trim_trailing_whitespace: 'true', // .editorconfig (for .js files)
+ },
+ monacoRules: {
+ endOfLine: 1,
+ insertFinalNewline: true,
+ insertSpaces: false,
+ tabSize: 6,
+ trimTrailingWhitespace: true,
+ },
+ },
+ {
+ path: 'foo/my_file.js',
+ rules: {
+ end_of_line: 'lf', // .editorconfig
+ indent_size: '2', // .editorconfig (for .js files)
+ indent_style: 'tab', // foo/.editorconfig
+ insert_final_newline: 'true', // .editorconfig
+ tab_width: '4', // foo/.editorconfig
+ trim_trailing_whitespace: 'true', // .editorconfig (for .js files)
+ },
+ monacoRules: {
+ endOfLine: 0,
+ insertFinalNewline: true,
+ insertSpaces: false,
+ tabSize: 4,
+ trimTrailingWhitespace: true,
+ },
+ },
+ {
+ path: 'foo/my_file.md',
+ rules: {
+ end_of_line: 'lf', // .editorconfig
+ indent_size: '3', // .editorconfig
+ indent_style: 'tab', // foo/.editorconfig
+ insert_final_newline: 'true', // .editorconfig
+ tab_width: '4', // foo/.editorconfig
+ },
+ monacoRules: {
+ endOfLine: 0,
+ insertFinalNewline: true,
+ insertSpaces: false,
+ tabSize: 4,
+ },
+ },
+ {
+ path: 'foo/bar/my_file.txt',
+ rules: {
+ end_of_line: 'crlf', // .editorconfig (for .txt files)
+ indent_size: '5', // foo/bar/.editorconfig
+ indent_style: 'space', // foo/bar/.editorconfig
+ insert_final_newline: 'true', // .editorconfig
+ tab_width: '4', // foo/.editorconfig
+ trim_trailing_whitespace: 'true', // foo/bar/.editorconfig
+ },
+ monacoRules: {
+ endOfLine: 1,
+ insertFinalNewline: true,
+ insertSpaces: true,
+ tabSize: 4,
+ trimTrailingWhitespace: true,
+ },
+ },
+];
diff --git a/spec/frontend/ide/lib/editorconfig/parser_spec.js b/spec/frontend/ide/lib/editorconfig/parser_spec.js
new file mode 100644
index 00000000000..f99410236e1
--- /dev/null
+++ b/spec/frontend/ide/lib/editorconfig/parser_spec.js
@@ -0,0 +1,18 @@
+import { getRulesWithTraversal } from '~/ide/lib/editorconfig/parser';
+import { exampleConfigs, exampleFiles } from './mock_data';
+
+describe('~/ide/lib/editorconfig/parser', () => {
+ const getExampleConfigContent = path =>
+ Promise.resolve(exampleConfigs.find(x => x.path === path)?.content);
+
+ describe('getRulesWithTraversal', () => {
+ it.each(exampleFiles)(
+ 'traverses through all editorconfig files in parent directories (until root=true is hit) and finds rules for this file (case %#)',
+ ({ path, rules }) => {
+ return getRulesWithTraversal(path, getExampleConfigContent).then(result => {
+ expect(result).toEqual(rules);
+ });
+ },
+ );
+ });
+});
diff --git a/spec/frontend/ide/lib/editorconfig/rules_mapper_spec.js b/spec/frontend/ide/lib/editorconfig/rules_mapper_spec.js
new file mode 100644
index 00000000000..536b1409435
--- /dev/null
+++ b/spec/frontend/ide/lib/editorconfig/rules_mapper_spec.js
@@ -0,0 +1,43 @@
+import mapRulesToMonaco from '~/ide/lib/editorconfig/rules_mapper';
+
+describe('mapRulesToMonaco', () => {
+ const multipleEntries = {
+ input: { indent_style: 'tab', indent_size: '4', insert_final_newline: 'true' },
+ output: { insertSpaces: false, tabSize: 4, insertFinalNewline: true },
+ };
+
+ // tab width takes precedence
+ const tabWidthAndIndent = {
+ input: { indent_style: 'tab', indent_size: '4', tab_width: '3' },
+ output: { insertSpaces: false, tabSize: 3 },
+ };
+
+ it.each`
+ rule | monacoOption
+ ${{ indent_style: 'tab' }} | ${{ insertSpaces: false }}
+ ${{ indent_style: 'space' }} | ${{ insertSpaces: true }}
+ ${{ indent_style: 'unset' }} | ${{}}
+ ${{ indent_size: '4' }} | ${{ tabSize: 4 }}
+ ${{ indent_size: '4.4' }} | ${{ tabSize: 4 }}
+ ${{ indent_size: '0' }} | ${{}}
+ ${{ indent_size: '-10' }} | ${{}}
+ ${{ indent_size: 'NaN' }} | ${{}}
+ ${{ tab_width: '4' }} | ${{ tabSize: 4 }}
+ ${{ tab_width: '5.4' }} | ${{ tabSize: 5 }}
+ ${{ tab_width: '-10' }} | ${{}}
+ ${{ trim_trailing_whitespace: 'true' }} | ${{ trimTrailingWhitespace: true }}
+ ${{ trim_trailing_whitespace: 'false' }} | ${{ trimTrailingWhitespace: false }}
+ ${{ trim_trailing_whitespace: 'unset' }} | ${{}}
+ ${{ end_of_line: 'lf' }} | ${{ endOfLine: 0 }}
+ ${{ end_of_line: 'crlf' }} | ${{ endOfLine: 1 }}
+ ${{ end_of_line: 'cr' }} | ${{}}
+ ${{ end_of_line: 'unset' }} | ${{}}
+ ${{ insert_final_newline: 'true' }} | ${{ insertFinalNewline: true }}
+ ${{ insert_final_newline: 'false' }} | ${{ insertFinalNewline: false }}
+ ${{ insert_final_newline: 'unset' }} | ${{}}
+ ${multipleEntries.input} | ${multipleEntries.output}
+ ${tabWidthAndIndent.input} | ${tabWidthAndIndent.output}
+ `('correctly maps editorconfig rule to monaco option: $rule', ({ rule, monacoOption }) => {
+ expect(mapRulesToMonaco(rule)).toEqual(monacoOption);
+ });
+});
diff --git a/spec/frontend/ide/lib/files_spec.js b/spec/frontend/ide/lib/files_spec.js
index 2b15aef6454..6974cdc4074 100644
--- a/spec/frontend/ide/lib/files_spec.js
+++ b/spec/frontend/ide/lib/files_spec.js
@@ -11,7 +11,6 @@ const createEntries = paths => {
const createUrl = base => (type === 'tree' ? `${base}/` : base);
const { name, parent } = splitParent(path);
- const parentEntry = acc[parent];
const previewMode = viewerInformationForPath(name);
acc[path] = {
@@ -26,9 +25,6 @@ const createEntries = paths => {
previewMode,
binary: (previewMode && previewMode.binary) || false,
parentPath: parent,
- parentTreeUrl: parentEntry
- ? parentEntry.url
- : createUrl(`/${TEST_PROJECT_ID}/${type}/${TEST_BRANCH_ID}`),
}),
tree: children.map(childName => expect.objectContaining({ name: childName })),
};
diff --git a/spec/frontend/ide/lib/mirror_spec.js b/spec/frontend/ide/lib/mirror_spec.js
new file mode 100644
index 00000000000..21bed5948f3
--- /dev/null
+++ b/spec/frontend/ide/lib/mirror_spec.js
@@ -0,0 +1,184 @@
+import createDiff from '~/ide/lib/create_diff';
+import {
+ canConnect,
+ createMirror,
+ SERVICE_NAME,
+ PROTOCOL,
+ MSG_CONNECTION_ERROR,
+ SERVICE_DELAY,
+} from '~/ide/lib/mirror';
+import { getWebSocketUrl } from '~/lib/utils/url_utility';
+
+jest.mock('~/ide/lib/create_diff', () => jest.fn());
+
+const TEST_PATH = '/project/ide/proxy/path';
+const TEST_DIFF = {
+ patch: 'lorem ipsum',
+ toDelete: ['foo.md'],
+};
+const TEST_ERROR = 'Something bad happened...';
+const TEST_SUCCESS_RESPONSE = {
+ data: JSON.stringify({ error: { code: 0 }, payload: { status_code: 200 } }),
+};
+const TEST_ERROR_RESPONSE = {
+ data: JSON.stringify({ error: { code: 1, Message: TEST_ERROR }, payload: { status_code: 200 } }),
+};
+const TEST_ERROR_PAYLOAD_RESPONSE = {
+ data: JSON.stringify({
+ error: { code: 0 },
+ payload: { status_code: 500, error_message: TEST_ERROR },
+ }),
+};
+
+const buildUploadMessage = ({ toDelete, patch }) =>
+ JSON.stringify({
+ code: 'EVENT',
+ namespace: '/files',
+ event: 'PATCH',
+ payload: { diff: patch, delete_files: toDelete },
+ });
+
+describe('ide/lib/mirror', () => {
+ describe('canConnect', () => {
+ it('can connect if the session has the expected service', () => {
+ const result = canConnect({ services: ['test1', SERVICE_NAME, 'test2'] });
+
+ expect(result).toBe(true);
+ });
+
+ it('cannot connect if the session does not have the expected service', () => {
+ const result = canConnect({ services: ['test1', 'test2'] });
+
+ expect(result).toBe(false);
+ });
+ });
+
+ describe('createMirror', () => {
+ const origWebSocket = global.WebSocket;
+ let mirror;
+ let mockWebSocket;
+
+ beforeEach(() => {
+ mockWebSocket = {
+ close: jest.fn(),
+ send: jest.fn(),
+ };
+ global.WebSocket = jest.fn().mockImplementation(() => mockWebSocket);
+ mirror = createMirror();
+ });
+
+ afterEach(() => {
+ global.WebSocket = origWebSocket;
+ });
+
+ const waitForConnection = (delay = SERVICE_DELAY) => {
+ const wait = new Promise(resolve => {
+ setTimeout(resolve, 10);
+ });
+
+ jest.advanceTimersByTime(delay);
+
+ return wait;
+ };
+ const connectPass = () => waitForConnection().then(() => mockWebSocket.onopen());
+ const connectFail = () => waitForConnection().then(() => mockWebSocket.onerror());
+ const sendResponse = msg => {
+ mockWebSocket.onmessage(msg);
+ };
+
+ describe('connect', () => {
+ let connection;
+
+ beforeEach(() => {
+ connection = mirror.connect(TEST_PATH);
+ });
+
+ it('waits before creating web socket', () => {
+ // ignore error when test suite terminates
+ connection.catch(() => {});
+
+ return waitForConnection(SERVICE_DELAY - 10).then(() => {
+ expect(global.WebSocket).not.toHaveBeenCalled();
+ });
+ });
+
+ it('is canceled when disconnected before finished waiting', () => {
+ mirror.disconnect();
+
+ return waitForConnection(SERVICE_DELAY).then(() => {
+ expect(global.WebSocket).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('when connection is successful', () => {
+ beforeEach(connectPass);
+
+ it('connects to service', () => {
+ const expectedPath = `${getWebSocketUrl(TEST_PATH)}?service=${SERVICE_NAME}`;
+
+ return connection.then(() => {
+ expect(global.WebSocket).toHaveBeenCalledWith(expectedPath, [PROTOCOL]);
+ });
+ });
+
+ it('disconnects when connected again', () => {
+ const result = connection
+ .then(() => {
+ // https://gitlab.com/gitlab-org/gitlab/issues/33024
+ // eslint-disable-next-line promise/no-nesting
+ mirror.connect(TEST_PATH).catch(() => {});
+ })
+ .then(() => {
+ expect(mockWebSocket.close).toHaveBeenCalled();
+ });
+
+ return result;
+ });
+ });
+
+ describe('when connection fails', () => {
+ beforeEach(connectFail);
+
+ it('rejects with error', () => {
+ return expect(connection).rejects.toEqual(new Error(MSG_CONNECTION_ERROR));
+ });
+ });
+ });
+
+ describe('upload', () => {
+ let state;
+
+ beforeEach(() => {
+ state = { changedFiles: [] };
+ createDiff.mockReturnValue(TEST_DIFF);
+
+ const connection = mirror.connect(TEST_PATH);
+
+ return connectPass().then(() => connection);
+ });
+
+ it('creates a diff from the given state', () => {
+ const result = mirror.upload(state);
+
+ sendResponse(TEST_SUCCESS_RESPONSE);
+
+ return result.then(() => {
+ expect(createDiff).toHaveBeenCalledWith(state);
+ expect(mockWebSocket.send).toHaveBeenCalledWith(buildUploadMessage(TEST_DIFF));
+ });
+ });
+
+ it.each`
+ response | description
+ ${TEST_ERROR_RESPONSE} | ${'error in error'}
+ ${TEST_ERROR_PAYLOAD_RESPONSE} | ${'error in payload'}
+ `('rejects if response has $description', ({ response }) => {
+ const result = mirror.upload(state);
+
+ sendResponse(response);
+
+ return expect(result).rejects.toEqual({ message: TEST_ERROR });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/ide/stores/actions/file_spec.js b/spec/frontend/ide/stores/actions/file_spec.js
index 43cb06f5d92..e2dc7626c67 100644
--- a/spec/frontend/ide/stores/actions/file_spec.js
+++ b/spec/frontend/ide/stores/actions/file_spec.js
@@ -5,7 +5,7 @@ import { createStore } from '~/ide/stores';
import * as actions from '~/ide/stores/actions/file';
import * as types from '~/ide/stores/mutation_types';
import service from '~/ide/services';
-import router from '~/ide/ide_router';
+import { createRouter } from '~/ide/ide_router';
import eventHub from '~/ide/eventhub';
import { file } from '../../helpers';
@@ -16,6 +16,7 @@ describe('IDE store file actions', () => {
let mock;
let originalGon;
let store;
+ let router;
beforeEach(() => {
mock = new MockAdapter(axios);
@@ -26,6 +27,7 @@ describe('IDE store file actions', () => {
};
store = createStore();
+ router = createRouter(store);
jest.spyOn(store, 'commit');
jest.spyOn(store, 'dispatch');
@@ -44,7 +46,6 @@ describe('IDE store file actions', () => {
localFile = file('testFile');
localFile.active = true;
localFile.opened = true;
- localFile.parentTreeUrl = 'parentTreeUrl';
store.state.openFiles.push(localFile);
store.state.entries[localFile.path] = localFile;
@@ -254,13 +255,8 @@ describe('IDE store file actions', () => {
mock.onGet(`${RELATIVE_URL_ROOT}/test/test/-/7297abc/${localFile.path}`).replyOnce(
200,
{
- blame_path: 'blame_path',
- commits_path: 'commits_path',
- permalink: 'permalink',
raw_path: 'raw_path',
binary: false,
- html: '123',
- render_error: '',
},
{
'page-title': 'testing getFileData',
@@ -281,17 +277,6 @@ describe('IDE store file actions', () => {
.catch(done.fail);
});
- it('sets the file data', done => {
- store
- .dispatch('getFileData', { path: localFile.path })
- .then(() => {
- expect(localFile.blamePath).toBe('blame_path');
-
- done();
- })
- .catch(done.fail);
- });
-
it('sets document title with the branchId', done => {
store
.dispatch('getFileData', { path: localFile.path })
@@ -348,13 +333,8 @@ describe('IDE store file actions', () => {
mock.onGet(`${RELATIVE_URL_ROOT}/test/test/-/7297abc/old-dull-file`).replyOnce(
200,
{
- blame_path: 'blame_path',
- commits_path: 'commits_path',
- permalink: 'permalink',
raw_path: 'raw_path',
binary: false,
- html: '123',
- render_error: '',
},
{
'page-title': 'testing old-dull-file',
@@ -587,20 +567,6 @@ describe('IDE store file actions', () => {
})
.catch(done.fail);
});
-
- it('bursts unused seal', done => {
- store
- .dispatch('changeFileContent', {
- path: tmpFile.path,
- content: 'content',
- })
- .then(() => {
- expect(store.state.unusedSeal).toBe(false);
-
- done();
- })
- .catch(done.fail);
- });
});
describe('with changed file', () => {
diff --git a/spec/frontend/ide/stores/actions/merge_request_spec.js b/spec/frontend/ide/stores/actions/merge_request_spec.js
new file mode 100644
index 00000000000..cb4eebd97d9
--- /dev/null
+++ b/spec/frontend/ide/stores/actions/merge_request_spec.js
@@ -0,0 +1,504 @@
+import MockAdapter from 'axios-mock-adapter';
+import axios from '~/lib/utils/axios_utils';
+import store from '~/ide/stores';
+import createFlash from '~/flash';
+import {
+ getMergeRequestData,
+ getMergeRequestChanges,
+ getMergeRequestVersions,
+ openMergeRequest,
+} from '~/ide/stores/actions/merge_request';
+import service from '~/ide/services';
+import { leftSidebarViews, PERMISSION_READ_MR } from '~/ide/constants';
+import { resetStore } from '../../helpers';
+
+const TEST_PROJECT = 'abcproject';
+const TEST_PROJECT_ID = 17;
+
+jest.mock('~/flash');
+
+describe('IDE store merge request actions', () => {
+ let mock;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+
+ store.state.projects[TEST_PROJECT] = {
+ id: TEST_PROJECT_ID,
+ mergeRequests: {},
+ userPermissions: {
+ [PERMISSION_READ_MR]: true,
+ },
+ };
+ });
+
+ afterEach(() => {
+ mock.restore();
+ resetStore(store);
+ });
+
+ describe('getMergeRequestsForBranch', () => {
+ describe('success', () => {
+ const mrData = { iid: 2, source_branch: 'bar' };
+ const mockData = [mrData];
+
+ describe('base case', () => {
+ beforeEach(() => {
+ jest.spyOn(service, 'getProjectMergeRequests');
+ mock.onGet(/api\/(.*)\/projects\/abcproject\/merge_requests/).reply(200, mockData);
+ });
+
+ it('calls getProjectMergeRequests service method', done => {
+ store
+ .dispatch('getMergeRequestsForBranch', { projectId: TEST_PROJECT, branchId: 'bar' })
+ .then(() => {
+ expect(service.getProjectMergeRequests).toHaveBeenCalledWith(TEST_PROJECT, {
+ source_branch: 'bar',
+ source_project_id: TEST_PROJECT_ID,
+ order_by: 'created_at',
+ per_page: 1,
+ });
+
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('sets the "Merge Request" Object', done => {
+ store
+ .dispatch('getMergeRequestsForBranch', { projectId: TEST_PROJECT, branchId: 'bar' })
+ .then(() => {
+ expect(store.state.projects.abcproject.mergeRequests).toEqual({
+ '2': expect.objectContaining(mrData),
+ });
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('sets "Current Merge Request" object to the most recent MR', done => {
+ store
+ .dispatch('getMergeRequestsForBranch', { projectId: TEST_PROJECT, branchId: 'bar' })
+ .then(() => {
+ expect(store.state.currentMergeRequestId).toEqual('2');
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('does nothing if user cannot read MRs', done => {
+ store.state.projects[TEST_PROJECT].userPermissions[PERMISSION_READ_MR] = false;
+
+ store
+ .dispatch('getMergeRequestsForBranch', { projectId: TEST_PROJECT, branchId: 'bar' })
+ .then(() => {
+ expect(service.getProjectMergeRequests).not.toHaveBeenCalled();
+ expect(store.state.currentMergeRequestId).toBe('');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('no merge requests for branch available case', () => {
+ beforeEach(() => {
+ jest.spyOn(service, 'getProjectMergeRequests');
+ mock.onGet(/api\/(.*)\/projects\/abcproject\/merge_requests/).reply(200, []);
+ });
+
+ it('does not fail if there are no merge requests for current branch', done => {
+ store
+ .dispatch('getMergeRequestsForBranch', { projectId: TEST_PROJECT, branchId: 'foo' })
+ .then(() => {
+ expect(store.state.projects[TEST_PROJECT].mergeRequests).toEqual({});
+ expect(store.state.currentMergeRequestId).toEqual('');
+ done();
+ })
+ .catch(done.fail);
+ });
+ });
+ });
+
+ describe('error', () => {
+ beforeEach(() => {
+ mock.onGet(/api\/(.*)\/projects\/abcproject\/merge_requests/).networkError();
+ });
+
+ it('flashes message, if error', done => {
+ store
+ .dispatch('getMergeRequestsForBranch', { projectId: TEST_PROJECT, branchId: 'bar' })
+ .catch(() => {
+ expect(createFlash).toHaveBeenCalled();
+ expect(createFlash.mock.calls[0][0]).toBe('Error fetching merge requests for bar');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+ });
+
+ describe('getMergeRequestData', () => {
+ describe('success', () => {
+ beforeEach(() => {
+ jest.spyOn(service, 'getProjectMergeRequestData');
+
+ mock
+ .onGet(/api\/(.*)\/projects\/abcproject\/merge_requests\/1/)
+ .reply(200, { title: 'mergerequest' });
+ });
+
+ it('calls getProjectMergeRequestData service method', done => {
+ store
+ .dispatch('getMergeRequestData', { projectId: TEST_PROJECT, mergeRequestId: 1 })
+ .then(() => {
+ expect(service.getProjectMergeRequestData).toHaveBeenCalledWith(TEST_PROJECT, 1);
+
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('sets the Merge Request Object', done => {
+ store
+ .dispatch('getMergeRequestData', { projectId: TEST_PROJECT, mergeRequestId: 1 })
+ .then(() => {
+ expect(store.state.currentMergeRequestId).toBe(1);
+ expect(store.state.projects[TEST_PROJECT].mergeRequests['1'].title).toBe(
+ 'mergerequest',
+ );
+
+ done();
+ })
+ .catch(done.fail);
+ });
+ });
+
+ describe('error', () => {
+ beforeEach(() => {
+ mock.onGet(/api\/(.*)\/projects\/abcproject\/merge_requests\/1/).networkError();
+ });
+
+ it('dispatches error action', done => {
+ const dispatch = jest.fn();
+
+ getMergeRequestData(
+ {
+ commit() {},
+ dispatch,
+ state: store.state,
+ },
+ { projectId: TEST_PROJECT, mergeRequestId: 1 },
+ )
+ .then(done.fail)
+ .catch(() => {
+ expect(dispatch).toHaveBeenCalledWith('setErrorMessage', {
+ text: 'An error occurred while loading the merge request.',
+ action: expect.any(Function),
+ actionText: 'Please try again',
+ actionPayload: {
+ projectId: TEST_PROJECT,
+ mergeRequestId: 1,
+ force: false,
+ },
+ });
+
+ done();
+ });
+ });
+ });
+ });
+
+ describe('getMergeRequestChanges', () => {
+ beforeEach(() => {
+ store.state.projects[TEST_PROJECT].mergeRequests['1'] = { changes: [] };
+ });
+
+ describe('success', () => {
+ beforeEach(() => {
+ jest.spyOn(service, 'getProjectMergeRequestChanges');
+
+ mock
+ .onGet(/api\/(.*)\/projects\/abcproject\/merge_requests\/1\/changes/)
+ .reply(200, { title: 'mergerequest' });
+ });
+
+ it('calls getProjectMergeRequestChanges service method', done => {
+ store
+ .dispatch('getMergeRequestChanges', { projectId: TEST_PROJECT, mergeRequestId: 1 })
+ .then(() => {
+ expect(service.getProjectMergeRequestChanges).toHaveBeenCalledWith(TEST_PROJECT, 1);
+
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('sets the Merge Request Changes Object', done => {
+ store
+ .dispatch('getMergeRequestChanges', { projectId: TEST_PROJECT, mergeRequestId: 1 })
+ .then(() => {
+ expect(store.state.projects[TEST_PROJECT].mergeRequests['1'].changes.title).toBe(
+ 'mergerequest',
+ );
+ done();
+ })
+ .catch(done.fail);
+ });
+ });
+
+ describe('error', () => {
+ beforeEach(() => {
+ mock.onGet(/api\/(.*)\/projects\/abcproject\/merge_requests\/1\/changes/).networkError();
+ });
+
+ it('dispatches error action', done => {
+ const dispatch = jest.fn();
+
+ getMergeRequestChanges(
+ {
+ commit() {},
+ dispatch,
+ state: store.state,
+ },
+ { projectId: TEST_PROJECT, mergeRequestId: 1 },
+ )
+ .then(done.fail)
+ .catch(() => {
+ expect(dispatch).toHaveBeenCalledWith('setErrorMessage', {
+ text: 'An error occurred while loading the merge request changes.',
+ action: expect.any(Function),
+ actionText: 'Please try again',
+ actionPayload: {
+ projectId: TEST_PROJECT,
+ mergeRequestId: 1,
+ force: false,
+ },
+ });
+
+ done();
+ });
+ });
+ });
+ });
+
+ describe('getMergeRequestVersions', () => {
+ beforeEach(() => {
+ store.state.projects[TEST_PROJECT].mergeRequests['1'] = { versions: [] };
+ });
+
+ describe('success', () => {
+ beforeEach(() => {
+ mock
+ .onGet(/api\/(.*)\/projects\/abcproject\/merge_requests\/1\/versions/)
+ .reply(200, [{ id: 789 }]);
+ jest.spyOn(service, 'getProjectMergeRequestVersions');
+ });
+
+ it('calls getProjectMergeRequestVersions service method', done => {
+ store
+ .dispatch('getMergeRequestVersions', { projectId: TEST_PROJECT, mergeRequestId: 1 })
+ .then(() => {
+ expect(service.getProjectMergeRequestVersions).toHaveBeenCalledWith(TEST_PROJECT, 1);
+
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('sets the Merge Request Versions Object', done => {
+ store
+ .dispatch('getMergeRequestVersions', { projectId: TEST_PROJECT, mergeRequestId: 1 })
+ .then(() => {
+ expect(store.state.projects[TEST_PROJECT].mergeRequests['1'].versions.length).toBe(1);
+ done();
+ })
+ .catch(done.fail);
+ });
+ });
+
+ describe('error', () => {
+ beforeEach(() => {
+ mock.onGet(/api\/(.*)\/projects\/abcproject\/merge_requests\/1\/versions/).networkError();
+ });
+
+ it('dispatches error action', done => {
+ const dispatch = jest.fn();
+
+ getMergeRequestVersions(
+ {
+ commit() {},
+ dispatch,
+ state: store.state,
+ },
+ { projectId: TEST_PROJECT, mergeRequestId: 1 },
+ )
+ .then(done.fail)
+ .catch(() => {
+ expect(dispatch).toHaveBeenCalledWith('setErrorMessage', {
+ text: 'An error occurred while loading the merge request version data.',
+ action: expect.any(Function),
+ actionText: 'Please try again',
+ actionPayload: {
+ projectId: TEST_PROJECT,
+ mergeRequestId: 1,
+ force: false,
+ },
+ });
+
+ done();
+ });
+ });
+ });
+ });
+
+ describe('openMergeRequest', () => {
+ const mr = {
+ projectId: TEST_PROJECT,
+ targetProjectId: 'defproject',
+ mergeRequestId: 2,
+ };
+ let testMergeRequest;
+ let testMergeRequestChanges;
+
+ const mockGetters = { findBranch: () => ({ commit: { id: 'abcd2322' } }) };
+
+ beforeEach(() => {
+ testMergeRequest = {
+ source_branch: 'abcbranch',
+ };
+ testMergeRequestChanges = {
+ changes: [],
+ };
+ store.state.entries = {
+ foo: {
+ type: 'blob',
+ },
+ bar: {
+ type: 'blob',
+ },
+ };
+
+ store.state.currentProjectId = 'test/test';
+ store.state.currentBranchId = 'master';
+
+ store.state.projects['test/test'] = {
+ branches: {
+ master: {
+ commit: {
+ id: '7297abc',
+ },
+ },
+ abcbranch: {
+ commit: {
+ id: '29020fc',
+ },
+ },
+ },
+ };
+
+ const originalDispatch = store.dispatch;
+
+ jest.spyOn(store, 'dispatch').mockImplementation((type, payload) => {
+ switch (type) {
+ case 'getMergeRequestData':
+ return Promise.resolve(testMergeRequest);
+ case 'getMergeRequestChanges':
+ return Promise.resolve(testMergeRequestChanges);
+ case 'getFiles':
+ case 'getMergeRequestVersions':
+ case 'getBranchData':
+ case 'setFileMrChange':
+ return Promise.resolve();
+ default:
+ return originalDispatch(type, payload);
+ }
+ });
+ jest.spyOn(service, 'getFileData').mockImplementation(() =>
+ Promise.resolve({
+ headers: {},
+ }),
+ );
+ });
+
+ it('dispatches actions for merge request data', done => {
+ openMergeRequest({ state: store.state, dispatch: store.dispatch, getters: mockGetters }, mr)
+ .then(() => {
+ expect(store.dispatch.mock.calls).toEqual([
+ ['getMergeRequestData', mr],
+ ['setCurrentBranchId', testMergeRequest.source_branch],
+ [
+ 'getBranchData',
+ {
+ projectId: mr.projectId,
+ branchId: testMergeRequest.source_branch,
+ },
+ ],
+ [
+ 'getFiles',
+ {
+ projectId: mr.projectId,
+ branchId: testMergeRequest.source_branch,
+ ref: 'abcd2322',
+ },
+ ],
+ ['getMergeRequestVersions', mr],
+ ['getMergeRequestChanges', mr],
+ ]);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('updates activity bar view and gets file data, if changes are found', done => {
+ store.state.entries.foo = {
+ url: 'test',
+ type: 'blob',
+ };
+ store.state.entries.bar = {
+ url: 'test',
+ type: 'blob',
+ };
+
+ testMergeRequestChanges.changes = [
+ { new_path: 'foo', path: 'foo' },
+ { new_path: 'bar', path: 'bar' },
+ ];
+
+ openMergeRequest({ state: store.state, dispatch: store.dispatch, getters: mockGetters }, mr)
+ .then(() => {
+ expect(store.dispatch).toHaveBeenCalledWith(
+ 'updateActivityBarView',
+ leftSidebarViews.review.name,
+ );
+
+ testMergeRequestChanges.changes.forEach((change, i) => {
+ expect(store.dispatch).toHaveBeenCalledWith('setFileMrChange', {
+ file: store.state.entries[change.new_path],
+ mrChange: change,
+ });
+
+ expect(store.dispatch).toHaveBeenCalledWith('getFileData', {
+ path: change.new_path,
+ makeFileActive: i === 0,
+ openFile: true,
+ });
+ });
+
+ expect(store.state.openFiles.length).toBe(testMergeRequestChanges.changes.length);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('flashes message, if error', done => {
+ store.dispatch.mockRejectedValue();
+
+ openMergeRequest(store, mr)
+ .catch(() => {
+ expect(createFlash).toHaveBeenCalledWith(expect.any(String));
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+});
diff --git a/spec/frontend/ide/stores/actions/project_spec.js b/spec/frontend/ide/stores/actions/project_spec.js
new file mode 100644
index 00000000000..64024c12903
--- /dev/null
+++ b/spec/frontend/ide/stores/actions/project_spec.js
@@ -0,0 +1,397 @@
+import MockAdapter from 'axios-mock-adapter';
+import axios from '~/lib/utils/axios_utils';
+import { createStore } from '~/ide/stores';
+import {
+ refreshLastCommitData,
+ showBranchNotFoundError,
+ createNewBranchFromDefault,
+ loadEmptyBranch,
+ openBranch,
+ loadFile,
+ loadBranch,
+} from '~/ide/stores/actions';
+import service from '~/ide/services';
+import api from '~/api';
+import testAction from 'helpers/vuex_action_helper';
+import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
+
+const TEST_PROJECT_ID = 'abc/def';
+
+describe('IDE store project actions', () => {
+ let mock;
+ let store;
+
+ beforeEach(() => {
+ store = createStore();
+ mock = new MockAdapter(axios);
+
+ store.state.projects[TEST_PROJECT_ID] = {
+ branches: {},
+ };
+ });
+
+ afterEach(() => {
+ mock.restore();
+ });
+
+ describe('refreshLastCommitData', () => {
+ beforeEach(() => {
+ store.state.currentProjectId = 'abc/def';
+ store.state.currentBranchId = 'master';
+ store.state.projects['abc/def'] = {
+ id: 4,
+ branches: {
+ master: {
+ commit: null,
+ },
+ },
+ };
+ jest.spyOn(service, 'getBranchData').mockResolvedValue({
+ data: {
+ commit: { id: '123' },
+ },
+ });
+ });
+
+ it('calls the service', done => {
+ store
+ .dispatch('refreshLastCommitData', {
+ projectId: store.state.currentProjectId,
+ branchId: store.state.currentBranchId,
+ })
+ .then(() => {
+ expect(service.getBranchData).toHaveBeenCalledWith('abc/def', 'master');
+
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('commits getBranchData', done => {
+ testAction(
+ refreshLastCommitData,
+ {
+ projectId: store.state.currentProjectId,
+ branchId: store.state.currentBranchId,
+ },
+ store.state,
+ // mutations
+ [
+ {
+ type: 'SET_BRANCH_COMMIT',
+ payload: {
+ projectId: TEST_PROJECT_ID,
+ branchId: 'master',
+ commit: { id: '123' },
+ },
+ },
+ ],
+ // action
+ [],
+ done,
+ );
+ });
+ });
+
+ describe('showBranchNotFoundError', () => {
+ it('dispatches setErrorMessage', done => {
+ testAction(
+ showBranchNotFoundError,
+ 'master',
+ null,
+ [],
+ [
+ {
+ type: 'setErrorMessage',
+ payload: {
+ text: "Branch <strong>master</strong> was not found in this project's repository.",
+ action: expect.any(Function),
+ actionText: 'Create branch',
+ actionPayload: 'master',
+ },
+ },
+ ],
+ done,
+ );
+ });
+ });
+
+ describe('createNewBranchFromDefault', () => {
+ useMockLocationHelper();
+
+ beforeEach(() => {
+ jest.spyOn(api, 'createBranch').mockResolvedValue();
+ });
+
+ it('calls API', done => {
+ createNewBranchFromDefault(
+ {
+ state: {
+ currentProjectId: 'project-path',
+ },
+ getters: {
+ currentProject: {
+ default_branch: 'master',
+ },
+ },
+ dispatch() {},
+ },
+ 'new-branch-name',
+ )
+ .then(() => {
+ expect(api.createBranch).toHaveBeenCalledWith('project-path', {
+ ref: 'master',
+ branch: 'new-branch-name',
+ });
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('clears error message', done => {
+ const dispatchSpy = jest.fn().mockName('dispatch');
+
+ createNewBranchFromDefault(
+ {
+ state: {
+ currentProjectId: 'project-path',
+ },
+ getters: {
+ currentProject: {
+ default_branch: 'master',
+ },
+ },
+ dispatch: dispatchSpy,
+ },
+ 'new-branch-name',
+ )
+ .then(() => {
+ expect(dispatchSpy).toHaveBeenCalledWith('setErrorMessage', null);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('reloads window', done => {
+ createNewBranchFromDefault(
+ {
+ state: {
+ currentProjectId: 'project-path',
+ },
+ getters: {
+ currentProject: {
+ default_branch: 'master',
+ },
+ },
+ dispatch() {},
+ },
+ 'new-branch-name',
+ )
+ .then(() => {
+ expect(window.location.reload).toHaveBeenCalled();
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('loadEmptyBranch', () => {
+ it('creates a blank tree and sets loading state to false', done => {
+ testAction(
+ loadEmptyBranch,
+ { projectId: TEST_PROJECT_ID, branchId: 'master' },
+ store.state,
+ [
+ { type: 'CREATE_TREE', payload: { treePath: `${TEST_PROJECT_ID}/master` } },
+ {
+ type: 'TOGGLE_LOADING',
+ payload: { entry: store.state.trees[`${TEST_PROJECT_ID}/master`], forceValue: false },
+ },
+ ],
+ expect.any(Object),
+ done,
+ );
+ });
+
+ it('does nothing, if tree already exists', done => {
+ const trees = { [`${TEST_PROJECT_ID}/master`]: [] };
+
+ testAction(
+ loadEmptyBranch,
+ { projectId: TEST_PROJECT_ID, branchId: 'master' },
+ { trees },
+ [],
+ [],
+ done,
+ );
+ });
+ });
+
+ describe('loadFile', () => {
+ beforeEach(() => {
+ Object.assign(store.state, {
+ entries: {
+ foo: { pending: false },
+ 'foo/bar-pending': { pending: true },
+ 'foo/bar': { pending: false },
+ },
+ });
+ jest.spyOn(store, 'dispatch').mockImplementation();
+ });
+
+ it('does nothing, if basePath is not given', () => {
+ loadFile(store, { basePath: undefined });
+
+ expect(store.dispatch).not.toHaveBeenCalled();
+ });
+
+ it('handles tree entry action, if basePath is given and the entry is not pending', () => {
+ loadFile(store, { basePath: 'foo/bar/' });
+
+ expect(store.dispatch).toHaveBeenCalledWith(
+ 'handleTreeEntryAction',
+ store.state.entries['foo/bar'],
+ );
+ });
+
+ it('does not handle tree entry action, if entry is pending', () => {
+ loadFile(store, { basePath: 'foo/bar-pending/' });
+
+ expect(store.dispatch).not.toHaveBeenCalledWith('handleTreeEntryAction', expect.anything());
+ });
+
+ it('creates a new temp file supplied via URL if the file does not exist yet', () => {
+ loadFile(store, { basePath: 'not-existent.md' });
+
+ expect(store.dispatch.mock.calls).toHaveLength(1);
+
+ expect(store.dispatch).not.toHaveBeenCalledWith('handleTreeEntryAction', expect.anything());
+
+ expect(store.dispatch).toHaveBeenCalledWith('createTempEntry', {
+ name: 'not-existent.md',
+ type: 'blob',
+ });
+ });
+ });
+
+ describe('loadBranch', () => {
+ const projectId = TEST_PROJECT_ID;
+ const branchId = '123-lorem';
+ const ref = 'abcd2322';
+
+ it('when empty repo, loads empty branch', done => {
+ const mockGetters = { emptyRepo: true };
+
+ testAction(
+ loadBranch,
+ { projectId, branchId },
+ { ...store.state, ...mockGetters },
+ [],
+ [{ type: 'loadEmptyBranch', payload: { projectId, branchId } }],
+ done,
+ );
+ });
+
+ it('when branch already exists, does nothing', done => {
+ store.state.projects[projectId].branches[branchId] = {};
+
+ testAction(loadBranch, { projectId, branchId }, store.state, [], [], done);
+ });
+
+ it('fetches branch data', done => {
+ const mockGetters = { findBranch: () => ({ commit: { id: ref } }) };
+ jest.spyOn(store, 'dispatch').mockResolvedValue();
+
+ loadBranch(
+ { getters: mockGetters, state: store.state, dispatch: store.dispatch },
+ { projectId, branchId },
+ )
+ .then(() => {
+ expect(store.dispatch.mock.calls).toEqual([
+ ['getBranchData', { projectId, branchId }],
+ ['getMergeRequestsForBranch', { projectId, branchId }],
+ ['getFiles', { projectId, branchId, ref }],
+ ]);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('shows an error if branch can not be fetched', done => {
+ jest.spyOn(store, 'dispatch').mockReturnValue(Promise.reject());
+
+ loadBranch(store, { projectId, branchId })
+ .then(done.fail)
+ .catch(() => {
+ expect(store.dispatch.mock.calls).toEqual([
+ ['getBranchData', { projectId, branchId }],
+ ['showBranchNotFoundError', branchId],
+ ]);
+ done();
+ });
+ });
+ });
+
+ describe('openBranch', () => {
+ const projectId = TEST_PROJECT_ID;
+ const branchId = '123-lorem';
+
+ const branch = {
+ projectId,
+ branchId,
+ };
+
+ beforeEach(() => {
+ Object.assign(store.state, {
+ entries: {
+ foo: { pending: false },
+ 'foo/bar-pending': { pending: true },
+ 'foo/bar': { pending: false },
+ },
+ });
+ });
+
+ describe('existing branch', () => {
+ beforeEach(() => {
+ jest.spyOn(store, 'dispatch').mockResolvedValue();
+ });
+
+ it('dispatches branch actions', done => {
+ openBranch(store, branch)
+ .then(() => {
+ expect(store.dispatch.mock.calls).toEqual([
+ ['setCurrentBranchId', branchId],
+ ['loadBranch', { projectId, branchId }],
+ ['loadFile', { basePath: undefined }],
+ ]);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('non-existent branch', () => {
+ beforeEach(() => {
+ jest.spyOn(store, 'dispatch').mockReturnValue(Promise.reject());
+ });
+
+ it('dispatches correct branch actions', done => {
+ openBranch(store, branch)
+ .then(val => {
+ expect(store.dispatch.mock.calls).toEqual([
+ ['setCurrentBranchId', branchId],
+ ['loadBranch', { projectId, branchId }],
+ ]);
+
+ expect(val).toEqual(
+ new Error(
+ `An error occurred while getting files for - <strong>${projectId}/${branchId}</strong>`,
+ ),
+ );
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/ide/stores/actions/tree_spec.js b/spec/frontend/ide/stores/actions/tree_spec.js
new file mode 100644
index 00000000000..44e2fcab436
--- /dev/null
+++ b/spec/frontend/ide/stores/actions/tree_spec.js
@@ -0,0 +1,218 @@
+import MockAdapter from 'axios-mock-adapter';
+import testAction from 'helpers/vuex_action_helper';
+import { showTreeEntry, getFiles, setDirectoryData } from '~/ide/stores/actions/tree';
+import * as types from '~/ide/stores/mutation_types';
+import axios from '~/lib/utils/axios_utils';
+import { createStore } from '~/ide/stores';
+import service from '~/ide/services';
+import { createRouter } from '~/ide/ide_router';
+import { file, createEntriesFromPaths } from '../../helpers';
+
+describe('Multi-file store tree actions', () => {
+ let projectTree;
+ let mock;
+ let store;
+ let router;
+
+ const basicCallParameters = {
+ endpoint: 'rootEndpoint',
+ projectId: 'abcproject',
+ branch: 'master',
+ branchId: 'master',
+ ref: '12345678',
+ };
+
+ beforeEach(() => {
+ store = createStore();
+ router = createRouter(store);
+ jest.spyOn(router, 'push').mockImplementation();
+
+ mock = new MockAdapter(axios);
+
+ store.state.currentProjectId = 'abcproject';
+ store.state.currentBranchId = 'master';
+ store.state.projects.abcproject = {
+ web_url: '',
+ path_with_namespace: 'foo/abcproject',
+ };
+ });
+
+ afterEach(() => {
+ mock.restore();
+ });
+
+ describe('getFiles', () => {
+ describe('success', () => {
+ beforeEach(() => {
+ jest.spyOn(service, 'getFiles');
+
+ mock
+ .onGet(/(.*)/)
+ .replyOnce(200, [
+ 'file.txt',
+ 'folder/fileinfolder.js',
+ 'folder/subfolder/fileinsubfolder.js',
+ ]);
+ });
+
+ it('calls service getFiles', () => {
+ return (
+ store
+ .dispatch('getFiles', basicCallParameters)
+ // getFiles actions calls lodash.defer
+ .then(() => jest.runOnlyPendingTimers())
+ .then(() => {
+ expect(service.getFiles).toHaveBeenCalledWith('foo/abcproject', '12345678');
+ })
+ );
+ });
+
+ it('adds data into tree', done => {
+ store
+ .dispatch('getFiles', basicCallParameters)
+ .then(() => {
+ // The populating of the tree is deferred for performance reasons.
+ // See this merge request for details: https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/25700
+ jest.advanceTimersByTime(1);
+ })
+ .then(() => {
+ projectTree = store.state.trees['abcproject/master'];
+
+ expect(projectTree.tree.length).toBe(2);
+ expect(projectTree.tree[0].type).toBe('tree');
+ expect(projectTree.tree[0].tree[1].name).toBe('fileinfolder.js');
+ expect(projectTree.tree[1].type).toBe('blob');
+ expect(projectTree.tree[0].tree[0].tree[0].type).toBe('blob');
+ expect(projectTree.tree[0].tree[0].tree[0].name).toBe('fileinsubfolder.js');
+
+ done();
+ })
+ .catch(done.fail);
+ });
+ });
+
+ describe('error', () => {
+ it('dispatches error action', done => {
+ const dispatch = jest.fn();
+
+ store.state.projects = {
+ 'abc/def': {
+ web_url: `${gl.TEST_HOST}/files`,
+ branches: {
+ 'master-testing': {
+ commit: {
+ id: '12345',
+ },
+ },
+ },
+ },
+ };
+ const getters = {
+ findBranch: () => store.state.projects['abc/def'].branches['master-testing'],
+ };
+
+ mock.onGet(/(.*)/).replyOnce(500);
+
+ getFiles(
+ {
+ commit() {},
+ dispatch,
+ state: store.state,
+ getters,
+ },
+ {
+ projectId: 'abc/def',
+ branchId: 'master-testing',
+ },
+ )
+ .then(done.fail)
+ .catch(() => {
+ expect(dispatch).toHaveBeenCalledWith('setErrorMessage', {
+ text: 'An error occurred while loading all the files.',
+ action: expect.any(Function),
+ actionText: 'Please try again',
+ actionPayload: { projectId: 'abc/def', branchId: 'master-testing' },
+ });
+ done();
+ });
+ });
+ });
+ });
+
+ describe('toggleTreeOpen', () => {
+ let tree;
+
+ beforeEach(() => {
+ tree = file('testing', '1', 'tree');
+ store.state.entries[tree.path] = tree;
+ });
+
+ it('toggles the tree open', done => {
+ store
+ .dispatch('toggleTreeOpen', tree.path)
+ .then(() => {
+ expect(tree.opened).toBeTruthy();
+
+ done();
+ })
+ .catch(done.fail);
+ });
+ });
+
+ describe('showTreeEntry', () => {
+ beforeEach(() => {
+ const paths = [
+ 'grandparent',
+ 'ancestor',
+ 'grandparent/parent',
+ 'grandparent/aunt',
+ 'grandparent/parent/child.txt',
+ 'grandparent/aunt/cousing.txt',
+ ];
+
+ Object.assign(store.state.entries, createEntriesFromPaths(paths));
+ });
+
+ it('opens the parents', done => {
+ testAction(
+ showTreeEntry,
+ 'grandparent/parent/child.txt',
+ store.state,
+ [{ type: types.SET_TREE_OPEN, payload: 'grandparent/parent' }],
+ [{ type: 'showTreeEntry', payload: 'grandparent/parent' }],
+ done,
+ );
+ });
+ });
+
+ describe('setDirectoryData', () => {
+ it('sets tree correctly if there are no opened files yet', done => {
+ const treeFile = file({ name: 'README.md' });
+ store.state.trees['abcproject/master'] = {};
+
+ testAction(
+ setDirectoryData,
+ { projectId: 'abcproject', branchId: 'master', treeList: [treeFile] },
+ store.state,
+ [
+ {
+ type: types.SET_DIRECTORY_DATA,
+ payload: {
+ treePath: 'abcproject/master',
+ data: [treeFile],
+ },
+ },
+ {
+ type: types.TOGGLE_LOADING,
+ payload: {
+ entry: {},
+ forceValue: false,
+ },
+ },
+ ],
+ [],
+ done,
+ );
+ });
+ });
+});
diff --git a/spec/frontend/ide/stores/actions_spec.js b/spec/frontend/ide/stores/actions_spec.js
new file mode 100644
index 00000000000..f77dbd80025
--- /dev/null
+++ b/spec/frontend/ide/stores/actions_spec.js
@@ -0,0 +1,1062 @@
+import MockAdapter from 'axios-mock-adapter';
+import { visitUrl } from '~/lib/utils/url_utility';
+import { createStore } from '~/ide/stores';
+import { createRouter } from '~/ide/ide_router';
+import {
+ stageAllChanges,
+ unstageAllChanges,
+ toggleFileFinder,
+ setCurrentBranchId,
+ setEmptyStateSvgs,
+ updateActivityBarView,
+ updateTempFlagForEntry,
+ setErrorMessage,
+ deleteEntry,
+ renameEntry,
+ getBranchData,
+ createTempEntry,
+ discardAllChanges,
+} from '~/ide/stores/actions';
+import axios from '~/lib/utils/axios_utils';
+import * as types from '~/ide/stores/mutation_types';
+import { file } from '../helpers';
+import testAction from '../../helpers/vuex_action_helper';
+import eventHub from '~/ide/eventhub';
+
+jest.mock('~/lib/utils/url_utility', () => ({
+ visitUrl: jest.fn(),
+ joinPaths: jest.requireActual('~/lib/utils/url_utility').joinPaths,
+}));
+
+describe('Multi-file store actions', () => {
+ let store;
+ let router;
+
+ beforeEach(() => {
+ store = createStore();
+ router = createRouter(store);
+
+ jest.spyOn(store, 'commit');
+ jest.spyOn(store, 'dispatch');
+ jest.spyOn(router, 'push').mockImplementation();
+ });
+
+ describe('redirectToUrl', () => {
+ it('calls visitUrl', done => {
+ store
+ .dispatch('redirectToUrl', 'test')
+ .then(() => {
+ expect(visitUrl).toHaveBeenCalledWith('test');
+
+ done();
+ })
+ .catch(done.fail);
+ });
+ });
+
+ describe('setInitialData', () => {
+ it('commits initial data', done => {
+ store
+ .dispatch('setInitialData', { canCommit: true })
+ .then(() => {
+ expect(store.state.canCommit).toBeTruthy();
+ done();
+ })
+ .catch(done.fail);
+ });
+ });
+
+ describe('discardAllChanges', () => {
+ const paths = ['to_discard', 'another_one_to_discard'];
+
+ beforeEach(() => {
+ paths.forEach(path => {
+ const f = file(path);
+ f.changed = true;
+
+ store.state.openFiles.push(f);
+ store.state.changedFiles.push(f);
+ store.state.entries[f.path] = f;
+ });
+ });
+
+ it('discards all changes in file', () => {
+ const expectedCalls = paths.map(path => ['restoreOriginalFile', path]);
+
+ discardAllChanges(store);
+
+ expect(store.dispatch.mock.calls).toEqual(expect.arrayContaining(expectedCalls));
+ });
+
+ it('removes all files from changedFiles state', done => {
+ store
+ .dispatch('discardAllChanges')
+ .then(() => {
+ expect(store.state.changedFiles.length).toBe(0);
+ expect(store.state.openFiles.length).toBe(2);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('createTempEntry', () => {
+ beforeEach(() => {
+ document.body.innerHTML += '<div class="flash-container"></div>';
+
+ store.state.currentProjectId = 'abcproject';
+ store.state.currentBranchId = 'mybranch';
+
+ store.state.trees['abcproject/mybranch'] = {
+ tree: [],
+ };
+ store.state.projects.abcproject = {
+ web_url: '',
+ };
+ });
+
+ afterEach(() => {
+ document.querySelector('.flash-container').remove();
+ });
+
+ describe('tree', () => {
+ it('creates temp tree', done => {
+ store
+ .dispatch('createTempEntry', {
+ branchId: store.state.currentBranchId,
+ name: 'test',
+ type: 'tree',
+ })
+ .then(() => {
+ const entry = store.state.entries.test;
+
+ expect(entry).not.toBeNull();
+ expect(entry.type).toBe('tree');
+
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('creates new folder inside another tree', done => {
+ const tree = {
+ type: 'tree',
+ name: 'testing',
+ path: 'testing',
+ tree: [],
+ };
+
+ store.state.entries[tree.path] = tree;
+
+ store
+ .dispatch('createTempEntry', {
+ branchId: store.state.currentBranchId,
+ name: 'testing/test',
+ type: 'tree',
+ })
+ .then(() => {
+ expect(tree.tree[0].tempFile).toBeTruthy();
+ expect(tree.tree[0].name).toBe('test');
+ expect(tree.tree[0].type).toBe('tree');
+
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('does not create new tree if already exists', done => {
+ const tree = {
+ type: 'tree',
+ path: 'testing',
+ tempFile: false,
+ tree: [],
+ };
+
+ store.state.entries[tree.path] = tree;
+
+ store
+ .dispatch('createTempEntry', {
+ branchId: store.state.currentBranchId,
+ name: 'testing',
+ type: 'tree',
+ })
+ .then(() => {
+ expect(store.state.entries[tree.path].tempFile).toEqual(false);
+ expect(document.querySelector('.flash-alert')).not.toBeNull();
+
+ done();
+ })
+ .catch(done.fail);
+ });
+ });
+
+ describe('blob', () => {
+ it('creates temp file', done => {
+ const name = 'test';
+
+ store
+ .dispatch('createTempEntry', {
+ name,
+ branchId: 'mybranch',
+ type: 'blob',
+ })
+ .then(() => {
+ const f = store.state.entries[name];
+
+ expect(f.tempFile).toBeTruthy();
+ expect(store.state.trees['abcproject/mybranch'].tree.length).toBe(1);
+
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('adds tmp file to open files', done => {
+ const name = 'test';
+
+ store
+ .dispatch('createTempEntry', {
+ name,
+ branchId: 'mybranch',
+ type: 'blob',
+ })
+ .then(() => {
+ const f = store.state.entries[name];
+
+ expect(store.state.openFiles.length).toBe(1);
+ expect(store.state.openFiles[0].name).toBe(f.name);
+
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('adds tmp file to staged files', done => {
+ const name = 'test';
+
+ store
+ .dispatch('createTempEntry', {
+ name,
+ branchId: 'mybranch',
+ type: 'blob',
+ })
+ .then(() => {
+ expect(store.state.stagedFiles).toEqual([expect.objectContaining({ name })]);
+
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('sets tmp file as active', () => {
+ createTempEntry(store, { name: 'test', branchId: 'mybranch', type: 'blob' });
+
+ expect(store.dispatch).toHaveBeenCalledWith('setFileActive', 'test');
+ });
+
+ it('creates flash message if file already exists', done => {
+ const f = file('test', '1', 'blob');
+ store.state.trees['abcproject/mybranch'].tree = [f];
+ store.state.entries[f.path] = f;
+
+ store
+ .dispatch('createTempEntry', {
+ name: 'test',
+ branchId: 'mybranch',
+ type: 'blob',
+ })
+ .then(() => {
+ expect(document.querySelector('.flash-alert')?.textContent.trim()).toEqual(
+ `The name "${f.name}" is already taken in this directory.`,
+ );
+
+ done();
+ })
+ .catch(done.fail);
+ });
+ });
+ });
+
+ describe('scrollToTab', () => {
+ it('focuses the current active element', done => {
+ document.body.innerHTML +=
+ '<div id="tabs"><div class="active"><div class="repo-tab"></div></div></div>';
+ const el = document.querySelector('.repo-tab');
+ jest.spyOn(el, 'focus').mockImplementation();
+
+ store
+ .dispatch('scrollToTab')
+ .then(() => {
+ setImmediate(() => {
+ expect(el.focus).toHaveBeenCalled();
+
+ document.getElementById('tabs').remove();
+
+ done();
+ });
+ })
+ .catch(done.fail);
+ });
+ });
+
+ describe('stage/unstageAllChanges', () => {
+ let file1;
+ let file2;
+
+ beforeEach(() => {
+ file1 = { ...file('test'), content: 'changed test', raw: 'test' };
+ file2 = { ...file('test2'), content: 'changed test2', raw: 'test2' };
+
+ store.state.openFiles = [file1];
+ store.state.changedFiles = [file1];
+ store.state.stagedFiles = [{ ...file2, content: 'staged test' }];
+
+ store.state.entries = {
+ [file1.path]: { ...file1 },
+ [file2.path]: { ...file2 },
+ };
+ });
+
+ describe('stageAllChanges', () => {
+ it('adds all files from changedFiles to stagedFiles', () => {
+ stageAllChanges(store);
+
+ expect(store.commit.mock.calls).toEqual(
+ expect.arrayContaining([
+ [types.SET_LAST_COMMIT_MSG, ''],
+ [types.STAGE_CHANGE, expect.objectContaining({ path: file1.path })],
+ ]),
+ );
+ });
+
+ it('opens pending tab if a change exists in that file', () => {
+ stageAllChanges(store);
+
+ expect(store.dispatch.mock.calls).toEqual([
+ [
+ 'openPendingTab',
+ { file: { ...file1, staged: true, changed: true }, keyPrefix: 'staged' },
+ ],
+ ]);
+ });
+
+ it('does not open pending tab if no change exists in that file', () => {
+ store.state.entries[file1.path].content = 'test';
+ store.state.stagedFiles = [file1];
+ store.state.changedFiles = [store.state.entries[file1.path]];
+
+ stageAllChanges(store);
+
+ expect(store.dispatch).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('unstageAllChanges', () => {
+ it('removes all files from stagedFiles after unstaging', () => {
+ unstageAllChanges(store);
+
+ expect(store.commit.mock.calls).toEqual(
+ expect.arrayContaining([
+ [types.UNSTAGE_CHANGE, expect.objectContaining({ path: file2.path })],
+ ]),
+ );
+ });
+
+ it('opens pending tab if a change exists in that file', () => {
+ unstageAllChanges(store);
+
+ expect(store.dispatch.mock.calls).toEqual([
+ ['openPendingTab', { file: file1, keyPrefix: 'unstaged' }],
+ ]);
+ });
+
+ it('does not open pending tab if no change exists in that file', () => {
+ store.state.entries[file1.path].content = 'test';
+ store.state.stagedFiles = [file1];
+ store.state.changedFiles = [store.state.entries[file1.path]];
+
+ unstageAllChanges(store);
+
+ expect(store.dispatch).not.toHaveBeenCalled();
+ });
+ });
+ });
+
+ describe('updateViewer', () => {
+ it('updates viewer state', done => {
+ store
+ .dispatch('updateViewer', 'diff')
+ .then(() => {
+ expect(store.state.viewer).toBe('diff');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('updateActivityBarView', () => {
+ it('commits UPDATE_ACTIVITY_BAR_VIEW', done => {
+ testAction(
+ updateActivityBarView,
+ 'test',
+ {},
+ [{ type: 'UPDATE_ACTIVITY_BAR_VIEW', payload: 'test' }],
+ [],
+ done,
+ );
+ });
+ });
+
+ describe('setEmptyStateSvgs', () => {
+ it('commits setEmptyStateSvgs', done => {
+ testAction(
+ setEmptyStateSvgs,
+ 'svg',
+ {},
+ [{ type: 'SET_EMPTY_STATE_SVGS', payload: 'svg' }],
+ [],
+ done,
+ );
+ });
+ });
+
+ describe('updateTempFlagForEntry', () => {
+ it('commits UPDATE_TEMP_FLAG', done => {
+ const f = {
+ ...file(),
+ path: 'test',
+ tempFile: true,
+ };
+ store.state.entries[f.path] = f;
+
+ testAction(
+ updateTempFlagForEntry,
+ { file: f, tempFile: false },
+ store.state,
+ [{ type: 'UPDATE_TEMP_FLAG', payload: { path: f.path, tempFile: false } }],
+ [],
+ done,
+ );
+ });
+
+ it('commits UPDATE_TEMP_FLAG and dispatches for parent', done => {
+ const parent = {
+ ...file(),
+ path: 'testing',
+ };
+ const f = {
+ ...file(),
+ path: 'test',
+ parentPath: 'testing',
+ };
+ store.state.entries[parent.path] = parent;
+ store.state.entries[f.path] = f;
+
+ testAction(
+ updateTempFlagForEntry,
+ { file: f, tempFile: false },
+ store.state,
+ [{ type: 'UPDATE_TEMP_FLAG', payload: { path: f.path, tempFile: false } }],
+ [{ type: 'updateTempFlagForEntry', payload: { file: parent, tempFile: false } }],
+ done,
+ );
+ });
+
+ it('does not dispatch for parent, if parent does not exist', done => {
+ const f = {
+ ...file(),
+ path: 'test',
+ parentPath: 'testing',
+ };
+ store.state.entries[f.path] = f;
+
+ testAction(
+ updateTempFlagForEntry,
+ { file: f, tempFile: false },
+ store.state,
+ [{ type: 'UPDATE_TEMP_FLAG', payload: { path: f.path, tempFile: false } }],
+ [],
+ done,
+ );
+ });
+ });
+
+ describe('setCurrentBranchId', () => {
+ it('commits setCurrentBranchId', done => {
+ testAction(
+ setCurrentBranchId,
+ 'branchId',
+ {},
+ [{ type: 'SET_CURRENT_BRANCH', payload: 'branchId' }],
+ [],
+ done,
+ );
+ });
+ });
+
+ describe('toggleFileFinder', () => {
+ it('commits TOGGLE_FILE_FINDER', done => {
+ testAction(
+ toggleFileFinder,
+ true,
+ null,
+ [{ type: 'TOGGLE_FILE_FINDER', payload: true }],
+ [],
+ done,
+ );
+ });
+ });
+
+ describe('setErrorMessage', () => {
+ it('commis error messsage', done => {
+ testAction(
+ setErrorMessage,
+ 'error',
+ null,
+ [{ type: types.SET_ERROR_MESSAGE, payload: 'error' }],
+ [],
+ done,
+ );
+ });
+ });
+
+ describe('deleteEntry', () => {
+ it('commits entry deletion', done => {
+ store.state.entries.path = 'testing';
+
+ testAction(
+ deleteEntry,
+ 'path',
+ store.state,
+ [{ type: types.DELETE_ENTRY, payload: 'path' }],
+ [{ type: 'stageChange', payload: 'path' }, { type: 'triggerFilesChange' }],
+ done,
+ );
+ });
+
+ it('does not delete a folder after it is emptied', done => {
+ const testFolder = {
+ type: 'tree',
+ tree: [],
+ };
+ const testEntry = {
+ path: 'testFolder/entry-to-delete',
+ parentPath: 'testFolder',
+ opened: false,
+ tree: [],
+ };
+ testFolder.tree.push(testEntry);
+ store.state.entries = {
+ testFolder,
+ 'testFolder/entry-to-delete': testEntry,
+ };
+
+ testAction(
+ deleteEntry,
+ 'testFolder/entry-to-delete',
+ store.state,
+ [{ type: types.DELETE_ENTRY, payload: 'testFolder/entry-to-delete' }],
+ [
+ { type: 'stageChange', payload: 'testFolder/entry-to-delete' },
+ { type: 'triggerFilesChange' },
+ ],
+ done,
+ );
+ });
+
+ describe('when renamed', () => {
+ let testEntry;
+
+ beforeEach(() => {
+ testEntry = {
+ path: 'test',
+ name: 'test',
+ prevPath: 'test_old',
+ prevName: 'test_old',
+ prevParentPath: '',
+ };
+
+ store.state.entries = { test: testEntry };
+ });
+
+ describe('and previous does not exist', () => {
+ it('reverts the rename before deleting', done => {
+ testAction(
+ deleteEntry,
+ testEntry.path,
+ store.state,
+ [],
+ [
+ {
+ type: 'renameEntry',
+ payload: {
+ path: testEntry.path,
+ name: testEntry.prevName,
+ parentPath: testEntry.prevParentPath,
+ },
+ },
+ {
+ type: 'deleteEntry',
+ payload: testEntry.prevPath,
+ },
+ ],
+ done,
+ );
+ });
+ });
+
+ describe('and previous exists', () => {
+ beforeEach(() => {
+ const oldEntry = {
+ path: testEntry.prevPath,
+ name: testEntry.prevName,
+ };
+
+ store.state.entries[oldEntry.path] = oldEntry;
+ });
+
+ it('does not revert rename before deleting', done => {
+ testAction(
+ deleteEntry,
+ testEntry.path,
+ store.state,
+ [{ type: types.DELETE_ENTRY, payload: testEntry.path }],
+ [{ type: 'stageChange', payload: testEntry.path }, { type: 'triggerFilesChange' }],
+ done,
+ );
+ });
+
+ it('when previous is deleted, it reverts rename before deleting', done => {
+ store.state.entries[testEntry.prevPath].deleted = true;
+
+ testAction(
+ deleteEntry,
+ testEntry.path,
+ store.state,
+ [],
+ [
+ {
+ type: 'renameEntry',
+ payload: {
+ path: testEntry.path,
+ name: testEntry.prevName,
+ parentPath: testEntry.prevParentPath,
+ },
+ },
+ {
+ type: 'deleteEntry',
+ payload: testEntry.prevPath,
+ },
+ ],
+ done,
+ );
+ });
+ });
+ });
+ });
+
+ describe('renameEntry', () => {
+ describe('purging of file model cache', () => {
+ beforeEach(() => {
+ jest.spyOn(eventHub, '$emit').mockImplementation();
+ });
+
+ it('does not purge model cache for temporary entries that got renamed', done => {
+ Object.assign(store.state.entries, {
+ test: {
+ ...file('test'),
+ key: 'foo-key',
+ type: 'blob',
+ tempFile: true,
+ },
+ });
+
+ store
+ .dispatch('renameEntry', {
+ path: 'test',
+ name: 'new',
+ })
+ .then(() => {
+ expect(eventHub.$emit.mock.calls).not.toContain('editor.update.model.dispose.foo-bar');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('purges model cache for renamed entry', done => {
+ Object.assign(store.state.entries, {
+ test: {
+ ...file('test'),
+ key: 'foo-key',
+ type: 'blob',
+ tempFile: false,
+ },
+ });
+
+ store
+ .dispatch('renameEntry', {
+ path: 'test',
+ name: 'new',
+ })
+ .then(() => {
+ expect(eventHub.$emit).toHaveBeenCalled();
+ expect(eventHub.$emit).toHaveBeenCalledWith(`editor.update.model.dispose.foo-key`);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('single entry', () => {
+ let origEntry;
+ let renamedEntry;
+
+ beforeEach(() => {
+ // Need to insert both because `testAction` doesn't actually call the mutation
+ origEntry = file('orig', 'orig', 'blob');
+ renamedEntry = {
+ ...file('renamed', 'renamed', 'blob'),
+ prevKey: origEntry.key,
+ prevName: origEntry.name,
+ prevPath: origEntry.path,
+ };
+
+ Object.assign(store.state.entries, {
+ orig: origEntry,
+ renamed: renamedEntry,
+ });
+ });
+
+ it('by default renames an entry and stages it', () => {
+ const dispatch = jest.fn();
+ const commit = jest.fn();
+
+ renameEntry(
+ { dispatch, commit, state: store.state, getters: store.getters },
+ { path: 'orig', name: 'renamed' },
+ );
+
+ expect(commit.mock.calls).toEqual([
+ [types.RENAME_ENTRY, { path: 'orig', name: 'renamed', parentPath: undefined }],
+ [types.STAGE_CHANGE, expect.objectContaining({ path: 'renamed' })],
+ ]);
+ });
+
+ it('if not changed, completely unstages and discards entry if renamed to original', done => {
+ testAction(
+ renameEntry,
+ { path: 'renamed', name: 'orig' },
+ store.state,
+ [
+ {
+ type: types.RENAME_ENTRY,
+ payload: {
+ path: 'renamed',
+ name: 'orig',
+ parentPath: undefined,
+ },
+ },
+ {
+ type: types.REMOVE_FILE_FROM_STAGED_AND_CHANGED,
+ payload: origEntry,
+ },
+ ],
+ [{ type: 'triggerFilesChange' }],
+ done,
+ );
+ });
+
+ it('if already in changed, does not add to change', done => {
+ store.state.changedFiles.push(renamedEntry);
+
+ testAction(
+ renameEntry,
+ { path: 'orig', name: 'renamed' },
+ store.state,
+ [expect.objectContaining({ type: types.RENAME_ENTRY })],
+ [{ type: 'triggerFilesChange' }],
+ done,
+ );
+ });
+
+ it('routes to the renamed file if the original file has been opened', done => {
+ Object.assign(store.state.entries.orig, {
+ opened: true,
+ url: '/foo-bar.md',
+ });
+
+ store
+ .dispatch('renameEntry', {
+ path: 'orig',
+ name: 'renamed',
+ })
+ .then(() => {
+ expect(router.push.mock.calls).toHaveLength(1);
+ expect(router.push).toHaveBeenCalledWith(`/project/foo-bar.md`);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('folder', () => {
+ let folder;
+ let file1;
+ let file2;
+
+ beforeEach(() => {
+ folder = file('folder', 'folder', 'tree');
+ file1 = file('file-1', 'file-1', 'blob', folder);
+ file2 = file('file-2', 'file-2', 'blob', folder);
+
+ folder.tree = [file1, file2];
+
+ Object.assign(store.state.entries, {
+ [folder.path]: folder,
+ [file1.path]: file1,
+ [file2.path]: file2,
+ });
+ });
+
+ it('updates entries in a folder correctly, when folder is renamed', done => {
+ store
+ .dispatch('renameEntry', {
+ path: 'folder',
+ name: 'new-folder',
+ })
+ .then(() => {
+ const keys = Object.keys(store.state.entries);
+
+ expect(keys.length).toBe(3);
+ expect(keys.indexOf('new-folder')).toBe(0);
+ expect(keys.indexOf('new-folder/file-1')).toBe(1);
+ expect(keys.indexOf('new-folder/file-2')).toBe(2);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('discards renaming of an entry if the root folder is renamed back to a previous name', done => {
+ const rootFolder = file('old-folder', 'old-folder', 'tree');
+ const testEntry = file('test', 'test', 'blob', rootFolder);
+
+ Object.assign(store.state, {
+ entries: {
+ 'old-folder': {
+ ...rootFolder,
+ tree: [testEntry],
+ },
+ 'old-folder/test': testEntry,
+ },
+ });
+
+ store
+ .dispatch('renameEntry', {
+ path: 'old-folder',
+ name: 'new-folder',
+ })
+ .then(() => {
+ const { entries } = store.state;
+
+ expect(Object.keys(entries).length).toBe(2);
+ expect(entries['old-folder']).toBeUndefined();
+ expect(entries['old-folder/test']).toBeUndefined();
+
+ expect(entries['new-folder']).toBeDefined();
+ expect(entries['new-folder/test']).toEqual(
+ expect.objectContaining({
+ path: 'new-folder/test',
+ name: 'test',
+ prevPath: 'old-folder/test',
+ prevName: 'test',
+ }),
+ );
+ })
+ .then(() =>
+ store.dispatch('renameEntry', {
+ path: 'new-folder',
+ name: 'old-folder',
+ }),
+ )
+ .then(() => {
+ const { entries } = store.state;
+
+ expect(Object.keys(entries).length).toBe(2);
+ expect(entries['new-folder']).toBeUndefined();
+ expect(entries['new-folder/test']).toBeUndefined();
+
+ expect(entries['old-folder']).toBeDefined();
+ expect(entries['old-folder/test']).toEqual(
+ expect.objectContaining({
+ path: 'old-folder/test',
+ name: 'test',
+ prevPath: undefined,
+ prevName: undefined,
+ }),
+ );
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ describe('with file in directory', () => {
+ const parentPath = 'original-dir';
+ const newParentPath = 'new-dir';
+ const fileName = 'test.md';
+ const filePath = `${parentPath}/${fileName}`;
+
+ let rootDir;
+
+ beforeEach(() => {
+ const parentEntry = file(parentPath, parentPath, 'tree');
+ const fileEntry = file(filePath, filePath, 'blob', parentEntry);
+ rootDir = {
+ tree: [],
+ };
+
+ Object.assign(store.state, {
+ entries: {
+ [parentPath]: {
+ ...parentEntry,
+ tree: [fileEntry],
+ },
+ [filePath]: fileEntry,
+ },
+ trees: {
+ '/': rootDir,
+ },
+ });
+ });
+
+ it('creates new directory', done => {
+ expect(store.state.entries[newParentPath]).toBeUndefined();
+
+ store
+ .dispatch('renameEntry', { path: filePath, name: fileName, parentPath: newParentPath })
+ .then(() => {
+ expect(store.state.entries[newParentPath]).toEqual(
+ expect.objectContaining({
+ path: newParentPath,
+ type: 'tree',
+ tree: expect.arrayContaining([
+ store.state.entries[`${newParentPath}/${fileName}`],
+ ]),
+ }),
+ );
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ describe('when new directory exists', () => {
+ let newDir;
+
+ beforeEach(() => {
+ newDir = file(newParentPath, newParentPath, 'tree');
+
+ store.state.entries[newDir.path] = newDir;
+ rootDir.tree.push(newDir);
+ });
+
+ it('inserts in new directory', done => {
+ expect(newDir.tree).toEqual([]);
+
+ store
+ .dispatch('renameEntry', {
+ path: filePath,
+ name: fileName,
+ parentPath: newParentPath,
+ })
+ .then(() => {
+ expect(newDir.tree).toEqual([store.state.entries[`${newParentPath}/${fileName}`]]);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('when new directory is deleted, it undeletes it', done => {
+ store.dispatch('deleteEntry', newParentPath);
+
+ expect(store.state.entries[newParentPath].deleted).toBe(true);
+ expect(rootDir.tree.some(x => x.path === newParentPath)).toBe(false);
+
+ store
+ .dispatch('renameEntry', {
+ path: filePath,
+ name: fileName,
+ parentPath: newParentPath,
+ })
+ .then(() => {
+ expect(store.state.entries[newParentPath].deleted).toBe(false);
+ expect(rootDir.tree.some(x => x.path === newParentPath)).toBe(true);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+ });
+ });
+ });
+
+ describe('getBranchData', () => {
+ let mock;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ });
+
+ afterEach(() => {
+ mock.restore();
+ });
+
+ describe('error', () => {
+ let dispatch;
+ let callParams;
+
+ beforeEach(() => {
+ callParams = [
+ {
+ commit() {},
+ state: store.state,
+ },
+ {
+ projectId: 'abc/def',
+ branchId: 'master-testing',
+ },
+ ];
+ dispatch = jest.fn();
+ document.body.innerHTML += '<div class="flash-container"></div>';
+ });
+
+ afterEach(() => {
+ document.querySelector('.flash-container').remove();
+ });
+
+ it('passes the error further unchanged without dispatching any action when response is 404', done => {
+ mock.onGet(/(.*)/).replyOnce(404);
+
+ getBranchData(...callParams)
+ .then(done.fail)
+ .catch(e => {
+ expect(dispatch.mock.calls).toHaveLength(0);
+ expect(e.response.status).toEqual(404);
+ expect(document.querySelector('.flash-alert')).toBeNull();
+ done();
+ });
+ });
+
+ it('does not pass the error further and flashes an alert if error is not 404', done => {
+ mock.onGet(/(.*)/).replyOnce(418);
+
+ getBranchData(...callParams)
+ .then(done.fail)
+ .catch(e => {
+ expect(dispatch.mock.calls).toHaveLength(0);
+ expect(e.response).toBeUndefined();
+ expect(document.querySelector('.flash-alert')).not.toBeNull();
+ done();
+ });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/ide/stores/extend_spec.js b/spec/frontend/ide/stores/extend_spec.js
new file mode 100644
index 00000000000..b0f1063153e
--- /dev/null
+++ b/spec/frontend/ide/stores/extend_spec.js
@@ -0,0 +1,74 @@
+import extendStore from '~/ide/stores/extend';
+import terminalPlugin from '~/ide/stores/plugins/terminal';
+import terminalSyncPlugin from '~/ide/stores/plugins/terminal_sync';
+
+jest.mock('~/ide/stores/plugins/terminal', () => jest.fn());
+jest.mock('~/ide/stores/plugins/terminal_sync', () => jest.fn());
+
+describe('ide/stores/extend', () => {
+ let prevGon;
+ let store;
+ let el;
+
+ beforeEach(() => {
+ prevGon = global.gon;
+ store = {};
+ el = {};
+
+ [terminalPlugin, terminalSyncPlugin].forEach(x => {
+ const plugin = jest.fn();
+
+ x.mockImplementation(() => plugin);
+ });
+ });
+
+ afterEach(() => {
+ global.gon = prevGon;
+ terminalPlugin.mockClear();
+ terminalSyncPlugin.mockClear();
+ });
+
+ const withGonFeatures = features => {
+ global.gon = { ...global.gon, features };
+ };
+
+ describe('terminalPlugin', () => {
+ beforeEach(() => {
+ extendStore(store, el);
+ });
+
+ it('is created', () => {
+ expect(terminalPlugin).toHaveBeenCalledWith(el);
+ });
+
+ it('is called with store', () => {
+ expect(terminalPlugin()).toHaveBeenCalledWith(store);
+ });
+ });
+
+ describe('terminalSyncPlugin', () => {
+ describe('when buildServiceProxy feature is enabled', () => {
+ beforeEach(() => {
+ withGonFeatures({ buildServiceProxy: true });
+
+ extendStore(store, el);
+ });
+
+ it('is created', () => {
+ expect(terminalSyncPlugin).toHaveBeenCalledWith(el);
+ });
+
+ it('is called with store', () => {
+ expect(terminalSyncPlugin()).toHaveBeenCalledWith(store);
+ });
+ });
+
+ describe('when buildServiceProxy feature is disabled', () => {
+ it('is not created', () => {
+ extendStore(store, el);
+
+ expect(terminalSyncPlugin).not.toHaveBeenCalled();
+ });
+ });
+ });
+});
diff --git a/spec/frontend/ide/stores/getters_spec.js b/spec/frontend/ide/stores/getters_spec.js
index 408ea2b2939..dcf05329ce0 100644
--- a/spec/frontend/ide/stores/getters_spec.js
+++ b/spec/frontend/ide/stores/getters_spec.js
@@ -417,4 +417,69 @@ describe('IDE store getters', () => {
expect(localStore.getters[getterName]).toBe(val);
});
});
+
+ describe('entryExists', () => {
+ beforeEach(() => {
+ localState.entries = {
+ foo: file('foo', 'foo', 'tree'),
+ 'foo/bar.png': file(),
+ };
+ });
+
+ it.each`
+ path | deleted | value
+ ${'foo/bar.png'} | ${false} | ${true}
+ ${'foo/bar.png'} | ${true} | ${false}
+ ${'foo'} | ${false} | ${true}
+ `(
+ 'returns $value for an existing entry path: $path (deleted: $deleted)',
+ ({ path, deleted, value }) => {
+ localState.entries[path].deleted = deleted;
+
+ expect(localStore.getters.entryExists(path)).toBe(value);
+ },
+ );
+
+ it('returns false for a non existing entry path', () => {
+ expect(localStore.getters.entryExists('bar.baz')).toBe(false);
+ });
+ });
+
+ describe('getAvailableFileName', () => {
+ it.each`
+ path | newPath
+ ${'foo'} | ${'foo_1'}
+ ${'foo__93.png'} | ${'foo__94.png'}
+ ${'foo/bar.png'} | ${'foo/bar_1.png'}
+ ${'foo/bar--34.png'} | ${'foo/bar--35.png'}
+ ${'foo/bar 2.png'} | ${'foo/bar 3.png'}
+ ${'foo/bar-621.png'} | ${'foo/bar-622.png'}
+ ${'jquery.min.js'} | ${'jquery_1.min.js'}
+ ${'my_spec_22.js.snap'} | ${'my_spec_23.js.snap'}
+ ${'subtitles5.mp4.srt'} | ${'subtitles_6.mp4.srt'}
+ ${'sample_file.mp3'} | ${'sample_file_1.mp3'}
+ ${'Screenshot 2020-05-26 at 10.53.08 PM.png'} | ${'Screenshot 2020-05-26 at 11.53.08 PM.png'}
+ `('suffixes the path with a number if the path already exists', ({ path, newPath }) => {
+ localState.entries[path] = file();
+
+ expect(localStore.getters.getAvailableFileName(path)).toBe(newPath);
+ });
+
+ it('loops through all incremented entries and keeps trying until a file path that does not exist is found', () => {
+ localState.entries = {
+ 'bar/baz_1.png': file(),
+ 'bar/baz_2.png': file(),
+ 'bar/baz_3.png': file(),
+ 'bar/baz_4.png': file(),
+ 'bar/baz_5.png': file(),
+ 'bar/baz_72.png': file(),
+ };
+
+ expect(localStore.getters.getAvailableFileName('bar/baz_1.png')).toBe('bar/baz_6.png');
+ });
+
+ it('returns the entry path as is if the path does not exist', () => {
+ expect(localStore.getters.getAvailableFileName('foo-bar1.jpg')).toBe('foo-bar1.jpg');
+ });
+ });
});
diff --git a/spec/frontend/ide/stores/modules/commit/actions_spec.js b/spec/frontend/ide/stores/modules/commit/actions_spec.js
new file mode 100644
index 00000000000..a14879112fd
--- /dev/null
+++ b/spec/frontend/ide/stores/modules/commit/actions_spec.js
@@ -0,0 +1,598 @@
+import { file } from 'jest/ide/helpers';
+import axios from 'axios';
+import MockAdapter from 'axios-mock-adapter';
+import { visitUrl } from '~/lib/utils/url_utility';
+import { createStore } from '~/ide/stores';
+import service from '~/ide/services';
+import { createRouter } from '~/ide/ide_router';
+import eventHub from '~/ide/eventhub';
+import consts from '~/ide/stores/modules/commit/constants';
+import * as mutationTypes from '~/ide/stores/modules/commit/mutation_types';
+import * as actions from '~/ide/stores/modules/commit/actions';
+import { commitActionTypes, PERMISSION_CREATE_MR } from '~/ide/constants';
+import testAction from '../../../../helpers/vuex_action_helper';
+
+jest.mock('~/lib/utils/url_utility', () => ({
+ ...jest.requireActual('~/lib/utils/url_utility'),
+ visitUrl: jest.fn(),
+}));
+
+const TEST_COMMIT_SHA = '123456789';
+
+describe('IDE commit module actions', () => {
+ let mock;
+ let store;
+ let router;
+
+ beforeEach(() => {
+ store = createStore();
+ router = createRouter(store);
+ gon.api_version = 'v1';
+ mock = new MockAdapter(axios);
+ jest.spyOn(router, 'push').mockImplementation();
+
+ mock.onGet('/api/v1/projects/abcproject/repository/branches/master').reply(200);
+ });
+
+ afterEach(() => {
+ delete gon.api_version;
+ mock.restore();
+ });
+
+ describe('updateCommitMessage', () => {
+ it('updates store with new commit message', done => {
+ store
+ .dispatch('commit/updateCommitMessage', 'testing')
+ .then(() => {
+ expect(store.state.commit.commitMessage).toBe('testing');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('discardDraft', () => {
+ it('resets commit message to blank', done => {
+ store.state.commit.commitMessage = 'testing';
+
+ store
+ .dispatch('commit/discardDraft')
+ .then(() => {
+ expect(store.state.commit.commitMessage).not.toBe('testing');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('updateCommitAction', () => {
+ it('updates store with new commit action', done => {
+ store
+ .dispatch('commit/updateCommitAction', '1')
+ .then(() => {
+ expect(store.state.commit.commitAction).toBe('1');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('sets shouldCreateMR to true if "Create new MR" option is visible', done => {
+ Object.assign(store.state, {
+ shouldHideNewMrOption: false,
+ });
+
+ testAction(
+ actions.updateCommitAction,
+ {},
+ store.state,
+ [
+ {
+ type: mutationTypes.UPDATE_COMMIT_ACTION,
+ payload: { commitAction: expect.anything() },
+ },
+ { type: mutationTypes.TOGGLE_SHOULD_CREATE_MR, payload: true },
+ ],
+ [],
+ done,
+ );
+ });
+
+ it('sets shouldCreateMR to false if "Create new MR" option is hidden', done => {
+ Object.assign(store.state, {
+ shouldHideNewMrOption: true,
+ });
+
+ testAction(
+ actions.updateCommitAction,
+ {},
+ store.state,
+ [
+ {
+ type: mutationTypes.UPDATE_COMMIT_ACTION,
+ payload: { commitAction: expect.anything() },
+ },
+ { type: mutationTypes.TOGGLE_SHOULD_CREATE_MR, payload: false },
+ ],
+ [],
+ done,
+ );
+ });
+ });
+
+ describe('updateBranchName', () => {
+ it('updates store with new branch name', done => {
+ store
+ .dispatch('commit/updateBranchName', 'branch-name')
+ .then(() => {
+ expect(store.state.commit.newBranchName).toBe('branch-name');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('setLastCommitMessage', () => {
+ beforeEach(() => {
+ Object.assign(store.state, {
+ currentProjectId: 'abcproject',
+ projects: {
+ abcproject: {
+ web_url: 'http://testing',
+ },
+ },
+ });
+ });
+
+ it('updates commit message with short_id', done => {
+ store
+ .dispatch('commit/setLastCommitMessage', { short_id: '123' })
+ .then(() => {
+ expect(store.state.lastCommitMsg).toContain(
+ 'Your changes have been committed. Commit <a href="http://testing/-/commit/123" class="commit-sha">123</a>',
+ );
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('updates commit message with stats', done => {
+ store
+ .dispatch('commit/setLastCommitMessage', {
+ short_id: '123',
+ stats: {
+ additions: '1',
+ deletions: '2',
+ },
+ })
+ .then(() => {
+ expect(store.state.lastCommitMsg).toBe(
+ 'Your changes have been committed. Commit <a href="http://testing/-/commit/123" class="commit-sha">123</a> with 1 additions, 2 deletions.',
+ );
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('updateFilesAfterCommit', () => {
+ const data = {
+ id: '123',
+ message: 'testing commit message',
+ committed_date: '123',
+ committer_name: 'root',
+ };
+ const branch = 'master';
+ let f;
+
+ beforeEach(() => {
+ jest.spyOn(eventHub, '$emit').mockImplementation();
+
+ f = file('changedFile');
+ Object.assign(f, {
+ active: true,
+ changed: true,
+ content: 'file content',
+ });
+
+ Object.assign(store.state, {
+ currentProjectId: 'abcproject',
+ currentBranchId: 'master',
+ projects: {
+ abcproject: {
+ web_url: 'web_url',
+ branches: {
+ master: {
+ workingReference: '',
+ commit: {
+ short_id: TEST_COMMIT_SHA,
+ },
+ },
+ },
+ },
+ },
+ stagedFiles: [
+ f,
+ {
+ ...file('changedFile2'),
+ changed: true,
+ },
+ ],
+ });
+
+ store.state.openFiles = store.state.stagedFiles;
+ store.state.stagedFiles.forEach(stagedFile => {
+ store.state.entries[stagedFile.path] = stagedFile;
+ });
+ });
+
+ it('updates stores working reference', done => {
+ store
+ .dispatch('commit/updateFilesAfterCommit', {
+ data,
+ branch,
+ })
+ .then(() => {
+ expect(store.state.projects.abcproject.branches.master.workingReference).toBe(data.id);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('resets all files changed status', done => {
+ store
+ .dispatch('commit/updateFilesAfterCommit', {
+ data,
+ branch,
+ })
+ .then(() => {
+ store.state.openFiles.forEach(entry => {
+ expect(entry.changed).toBeFalsy();
+ });
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('sets files commit data', done => {
+ store
+ .dispatch('commit/updateFilesAfterCommit', {
+ data,
+ branch,
+ })
+ .then(() => {
+ expect(f.lastCommitSha).toBe(data.id);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('updates raw content for changed file', done => {
+ store
+ .dispatch('commit/updateFilesAfterCommit', {
+ data,
+ branch,
+ })
+ .then(() => {
+ expect(f.raw).toBe(f.content);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('emits changed event for file', done => {
+ store
+ .dispatch('commit/updateFilesAfterCommit', {
+ data,
+ branch,
+ })
+ .then(() => {
+ expect(eventHub.$emit).toHaveBeenCalledWith(`editor.update.model.content.${f.key}`, {
+ content: f.content,
+ changed: false,
+ });
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('commitChanges', () => {
+ beforeEach(() => {
+ document.body.innerHTML += '<div class="flash-container"></div>';
+
+ const f = {
+ ...file('changed'),
+ type: 'blob',
+ active: true,
+ lastCommitSha: TEST_COMMIT_SHA,
+ content: '\n',
+ raw: '\n',
+ };
+
+ Object.assign(store.state, {
+ stagedFiles: [f],
+ changedFiles: [f],
+ openFiles: [f],
+ currentProjectId: 'abcproject',
+ currentBranchId: 'master',
+ projects: {
+ abcproject: {
+ web_url: 'webUrl',
+ branches: {
+ master: {
+ workingReference: '1',
+ commit: {
+ id: TEST_COMMIT_SHA,
+ },
+ },
+ },
+ userPermissions: {
+ [PERMISSION_CREATE_MR]: true,
+ },
+ },
+ },
+ });
+
+ store.state.commit.commitAction = '2';
+ store.state.commit.commitMessage = 'testing 123';
+
+ store.state.openFiles.forEach(localF => {
+ store.state.entries[localF.path] = localF;
+ });
+ });
+
+ afterEach(() => {
+ document.querySelector('.flash-container').remove();
+ });
+
+ describe('success', () => {
+ const COMMIT_RESPONSE = {
+ id: '123456',
+ short_id: '123',
+ message: 'test message',
+ committed_date: 'date',
+ parent_ids: '321',
+ stats: {
+ additions: '1',
+ deletions: '2',
+ },
+ };
+
+ beforeEach(() => {
+ jest.spyOn(service, 'commit').mockResolvedValue({ data: COMMIT_RESPONSE });
+ });
+
+ it('calls service', done => {
+ store
+ .dispatch('commit/commitChanges')
+ .then(() => {
+ expect(service.commit).toHaveBeenCalledWith('abcproject', {
+ branch: expect.anything(),
+ commit_message: 'testing 123',
+ actions: [
+ {
+ action: commitActionTypes.update,
+ file_path: expect.anything(),
+ content: '\n',
+ encoding: expect.anything(),
+ last_commit_id: undefined,
+ previous_path: undefined,
+ },
+ ],
+ start_sha: TEST_COMMIT_SHA,
+ });
+
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('sends lastCommit ID when not creating new branch', done => {
+ store.state.commit.commitAction = '1';
+
+ store
+ .dispatch('commit/commitChanges')
+ .then(() => {
+ expect(service.commit).toHaveBeenCalledWith('abcproject', {
+ branch: expect.anything(),
+ commit_message: 'testing 123',
+ actions: [
+ {
+ action: commitActionTypes.update,
+ file_path: expect.anything(),
+ content: '\n',
+ encoding: expect.anything(),
+ last_commit_id: TEST_COMMIT_SHA,
+ previous_path: undefined,
+ },
+ ],
+ start_sha: undefined,
+ });
+
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('sets last Commit Msg', done => {
+ store
+ .dispatch('commit/commitChanges')
+ .then(() => {
+ expect(store.state.lastCommitMsg).toBe(
+ 'Your changes have been committed. Commit <a href="webUrl/-/commit/123" class="commit-sha">123</a> with 1 additions, 2 deletions.',
+ );
+
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('adds commit data to files', done => {
+ store
+ .dispatch('commit/commitChanges')
+ .then(() => {
+ expect(store.state.entries[store.state.openFiles[0].path].lastCommitSha).toBe(
+ COMMIT_RESPONSE.id,
+ );
+
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('resets stores commit actions', done => {
+ store.state.commit.commitAction = consts.COMMIT_TO_NEW_BRANCH;
+
+ store
+ .dispatch('commit/commitChanges')
+ .then(() => {
+ expect(store.state.commit.commitAction).not.toBe(consts.COMMIT_TO_NEW_BRANCH);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('removes all staged files', done => {
+ store
+ .dispatch('commit/commitChanges')
+ .then(() => {
+ expect(store.state.stagedFiles.length).toBe(0);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ describe('merge request', () => {
+ it('redirects to new merge request page', done => {
+ jest.spyOn(eventHub, '$on').mockImplementation();
+
+ store.state.commit.commitAction = consts.COMMIT_TO_NEW_BRANCH;
+ store.state.commit.shouldCreateMR = true;
+
+ store
+ .dispatch('commit/commitChanges')
+ .then(() => {
+ expect(visitUrl).toHaveBeenCalledWith(
+ `webUrl/-/merge_requests/new?merge_request[source_branch]=${
+ store.getters['commit/placeholderBranchName']
+ }&merge_request[target_branch]=master&nav_source=webide`,
+ );
+
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('does not redirect to new merge request page when shouldCreateMR is not checked', done => {
+ jest.spyOn(eventHub, '$on').mockImplementation();
+
+ store.state.commit.commitAction = consts.COMMIT_TO_NEW_BRANCH;
+ store.state.commit.shouldCreateMR = false;
+
+ store
+ .dispatch('commit/commitChanges')
+ .then(() => {
+ expect(visitUrl).not.toHaveBeenCalled();
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('resets changed files before redirecting', () => {
+ jest.spyOn(eventHub, '$on').mockImplementation();
+
+ store.state.commit.commitAction = '3';
+
+ return store.dispatch('commit/commitChanges').then(() => {
+ expect(store.state.stagedFiles.length).toBe(0);
+ });
+ });
+ });
+ });
+
+ describe('failed', () => {
+ beforeEach(() => {
+ jest.spyOn(service, 'commit').mockResolvedValue({
+ data: {
+ message: 'failed message',
+ },
+ });
+ });
+
+ it('shows failed message', done => {
+ store
+ .dispatch('commit/commitChanges')
+ .then(() => {
+ const alert = document.querySelector('.flash-container');
+
+ expect(alert.textContent.trim()).toBe('failed message');
+
+ done();
+ })
+ .catch(done.fail);
+ });
+ });
+
+ describe('first commit of a branch', () => {
+ const COMMIT_RESPONSE = {
+ id: '123456',
+ short_id: '123',
+ message: 'test message',
+ committed_date: 'date',
+ parent_ids: [],
+ stats: {
+ additions: '1',
+ deletions: '2',
+ },
+ };
+
+ it('commits TOGGLE_EMPTY_STATE mutation on empty repo', done => {
+ jest.spyOn(service, 'commit').mockResolvedValue({ data: COMMIT_RESPONSE });
+ jest.spyOn(store, 'commit');
+
+ store
+ .dispatch('commit/commitChanges')
+ .then(() => {
+ expect(store.commit.mock.calls).toEqual(
+ expect.arrayContaining([
+ ['TOGGLE_EMPTY_STATE', expect.any(Object), expect.any(Object)],
+ ]),
+ );
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('does not commmit TOGGLE_EMPTY_STATE mutation on existing project', done => {
+ COMMIT_RESPONSE.parent_ids.push('1234');
+ jest.spyOn(service, 'commit').mockResolvedValue({ data: COMMIT_RESPONSE });
+ jest.spyOn(store, 'commit');
+
+ store
+ .dispatch('commit/commitChanges')
+ .then(() => {
+ expect(store.commit.mock.calls).not.toEqual(
+ expect.arrayContaining([
+ ['TOGGLE_EMPTY_STATE', expect.any(Object), expect.any(Object)],
+ ]),
+ );
+ done();
+ })
+ .catch(done.fail);
+ });
+ });
+ });
+
+ describe('toggleShouldCreateMR', () => {
+ it('commits both toggle and interacting with MR checkbox actions', done => {
+ testAction(
+ actions.toggleShouldCreateMR,
+ {},
+ store.state,
+ [{ type: mutationTypes.TOGGLE_SHOULD_CREATE_MR }],
+ [],
+ done,
+ );
+ });
+ });
+});
diff --git a/spec/frontend/ide/stores/modules/pane/getters_spec.js b/spec/frontend/ide/stores/modules/pane/getters_spec.js
index 8a213323de0..a321571f058 100644
--- a/spec/frontend/ide/stores/modules/pane/getters_spec.js
+++ b/spec/frontend/ide/stores/modules/pane/getters_spec.js
@@ -7,20 +7,6 @@ describe('IDE pane module getters', () => {
[TEST_VIEW]: true,
};
- describe('isActiveView', () => {
- it('returns true if given view matches currentView', () => {
- const result = getters.isActiveView({ currentView: 'A' })('A');
-
- expect(result).toBe(true);
- });
-
- it('returns false if given view does not match currentView', () => {
- const result = getters.isActiveView({ currentView: 'A' })('B');
-
- expect(result).toBe(false);
- });
- });
-
describe('isAliveView', () => {
it('returns true if given view is in keepAliveViews', () => {
const result = getters.isAliveView({ keepAliveViews: TEST_KEEP_ALIVE_VIEWS }, {})(TEST_VIEW);
@@ -29,25 +15,25 @@ describe('IDE pane module getters', () => {
});
it('returns true if given view is active view and open', () => {
- const result = getters.isAliveView(
- { ...state(), isOpen: true },
- { isActiveView: () => true },
- )(TEST_VIEW);
+ const result = getters.isAliveView({ ...state(), isOpen: true, currentView: TEST_VIEW })(
+ TEST_VIEW,
+ );
expect(result).toBe(true);
});
it('returns false if given view is active view and closed', () => {
- const result = getters.isAliveView(state(), { isActiveView: () => true })(TEST_VIEW);
+ const result = getters.isAliveView({ ...state(), currentView: TEST_VIEW })(TEST_VIEW);
expect(result).toBe(false);
});
it('returns false if given view is not activeView', () => {
- const result = getters.isAliveView(
- { ...state(), isOpen: true },
- { isActiveView: () => false },
- )(TEST_VIEW);
+ const result = getters.isAliveView({
+ ...state(),
+ isOpen: true,
+ currentView: `${TEST_VIEW}_other`,
+ })(TEST_VIEW);
expect(result).toBe(false);
});
diff --git a/spec/frontend/ide/stores/modules/router/actions_spec.js b/spec/frontend/ide/stores/modules/router/actions_spec.js
new file mode 100644
index 00000000000..4795eae2b79
--- /dev/null
+++ b/spec/frontend/ide/stores/modules/router/actions_spec.js
@@ -0,0 +1,19 @@
+import * as actions from '~/ide/stores/modules/router/actions';
+import * as types from '~/ide/stores/modules/router/mutation_types';
+import testAction from 'helpers/vuex_action_helper';
+
+const TEST_PATH = 'test/path/abc';
+
+describe('ide/stores/modules/router/actions', () => {
+ describe('push', () => {
+ it('commits mutation', () => {
+ return testAction(
+ actions.push,
+ TEST_PATH,
+ {},
+ [{ type: types.PUSH, payload: TEST_PATH }],
+ [],
+ );
+ });
+ });
+});
diff --git a/spec/frontend/ide/stores/modules/router/mutations_spec.js b/spec/frontend/ide/stores/modules/router/mutations_spec.js
new file mode 100644
index 00000000000..a4a83c9344d
--- /dev/null
+++ b/spec/frontend/ide/stores/modules/router/mutations_spec.js
@@ -0,0 +1,23 @@
+import mutations from '~/ide/stores/modules/router/mutations';
+import * as types from '~/ide/stores/modules/router/mutation_types';
+import createState from '~/ide/stores/modules/router/state';
+
+const TEST_PATH = 'test/path/abc';
+
+describe('ide/stores/modules/router/mutations', () => {
+ let state;
+
+ beforeEach(() => {
+ state = createState();
+ });
+
+ describe(types.PUSH, () => {
+ it('updates state', () => {
+ expect(state.fullPath).toBe('');
+
+ mutations[types.PUSH](state, TEST_PATH);
+
+ expect(state.fullPath).toBe(TEST_PATH);
+ });
+ });
+});
diff --git a/spec/frontend/ide/stores/modules/terminal/actions/checks_spec.js b/spec/frontend/ide/stores/modules/terminal/actions/checks_spec.js
new file mode 100644
index 00000000000..242b1579be7
--- /dev/null
+++ b/spec/frontend/ide/stores/modules/terminal/actions/checks_spec.js
@@ -0,0 +1,289 @@
+import MockAdapter from 'axios-mock-adapter';
+import testAction from 'helpers/vuex_action_helper';
+import { TEST_HOST } from 'spec/test_constants';
+import {
+ CHECK_CONFIG,
+ CHECK_RUNNERS,
+ RETRY_RUNNERS_INTERVAL,
+} from '~/ide/stores/modules/terminal/constants';
+import * as mutationTypes from '~/ide/stores/modules/terminal/mutation_types';
+import * as messages from '~/ide/stores/modules/terminal/messages';
+import * as actions from '~/ide/stores/modules/terminal/actions/checks';
+import axios from '~/lib/utils/axios_utils';
+import httpStatus from '~/lib/utils/http_status';
+
+const TEST_PROJECT_PATH = 'lorem/root';
+const TEST_BRANCH_ID = 'master';
+const TEST_YAML_HELP_PATH = `${TEST_HOST}/test/yaml/help`;
+const TEST_RUNNERS_HELP_PATH = `${TEST_HOST}/test/runners/help`;
+
+describe('IDE store terminal check actions', () => {
+ let mock;
+ let state;
+ let rootState;
+ let rootGetters;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ state = {
+ paths: {
+ webTerminalConfigHelpPath: TEST_YAML_HELP_PATH,
+ webTerminalRunnersHelpPath: TEST_RUNNERS_HELP_PATH,
+ },
+ checks: {
+ config: { isLoading: true },
+ },
+ };
+ rootState = {
+ currentBranchId: TEST_BRANCH_ID,
+ };
+ rootGetters = {
+ currentProject: {
+ id: 7,
+ path_with_namespace: TEST_PROJECT_PATH,
+ },
+ };
+ });
+
+ afterEach(() => {
+ mock.restore();
+ });
+
+ describe('requestConfigCheck', () => {
+ it('handles request loading', () => {
+ return testAction(
+ actions.requestConfigCheck,
+ null,
+ {},
+ [{ type: mutationTypes.REQUEST_CHECK, payload: CHECK_CONFIG }],
+ [],
+ );
+ });
+ });
+
+ describe('receiveConfigCheckSuccess', () => {
+ it('handles successful response', () => {
+ return testAction(
+ actions.receiveConfigCheckSuccess,
+ null,
+ {},
+ [
+ { type: mutationTypes.SET_VISIBLE, payload: true },
+ { type: mutationTypes.RECEIVE_CHECK_SUCCESS, payload: CHECK_CONFIG },
+ ],
+ [],
+ );
+ });
+ });
+
+ describe('receiveConfigCheckError', () => {
+ it('handles error response', () => {
+ const status = httpStatus.UNPROCESSABLE_ENTITY;
+ const payload = { response: { status } };
+
+ return testAction(
+ actions.receiveConfigCheckError,
+ payload,
+ state,
+ [
+ {
+ type: mutationTypes.SET_VISIBLE,
+ payload: true,
+ },
+ {
+ type: mutationTypes.RECEIVE_CHECK_ERROR,
+ payload: {
+ type: CHECK_CONFIG,
+ message: messages.configCheckError(status, TEST_YAML_HELP_PATH),
+ },
+ },
+ ],
+ [],
+ );
+ });
+
+ [httpStatus.FORBIDDEN, httpStatus.NOT_FOUND].forEach(status => {
+ it(`hides tab, when status is ${status}`, () => {
+ const payload = { response: { status } };
+
+ return testAction(
+ actions.receiveConfigCheckError,
+ payload,
+ state,
+ [
+ {
+ type: mutationTypes.SET_VISIBLE,
+ payload: false,
+ },
+ expect.objectContaining({ type: mutationTypes.RECEIVE_CHECK_ERROR }),
+ ],
+ [],
+ );
+ });
+ });
+ });
+
+ describe('fetchConfigCheck', () => {
+ it('dispatches request and receive', () => {
+ mock.onPost(/.*\/ide_terminals\/check_config/).reply(200, {});
+
+ return testAction(
+ actions.fetchConfigCheck,
+ null,
+ {
+ ...rootGetters,
+ ...rootState,
+ },
+ [],
+ [{ type: 'requestConfigCheck' }, { type: 'receiveConfigCheckSuccess' }],
+ );
+ });
+
+ it('when error, dispatches request and receive', () => {
+ mock.onPost(/.*\/ide_terminals\/check_config/).reply(400, {});
+
+ return testAction(
+ actions.fetchConfigCheck,
+ null,
+ {
+ ...rootGetters,
+ ...rootState,
+ },
+ [],
+ [
+ { type: 'requestConfigCheck' },
+ { type: 'receiveConfigCheckError', payload: expect.any(Error) },
+ ],
+ );
+ });
+ });
+
+ describe('requestRunnersCheck', () => {
+ it('handles request loading', () => {
+ return testAction(
+ actions.requestRunnersCheck,
+ null,
+ {},
+ [{ type: mutationTypes.REQUEST_CHECK, payload: CHECK_RUNNERS }],
+ [],
+ );
+ });
+ });
+
+ describe('receiveRunnersCheckSuccess', () => {
+ it('handles successful response, with data', () => {
+ const payload = [{}];
+
+ return testAction(
+ actions.receiveRunnersCheckSuccess,
+ payload,
+ state,
+ [{ type: mutationTypes.RECEIVE_CHECK_SUCCESS, payload: CHECK_RUNNERS }],
+ [],
+ );
+ });
+
+ it('handles successful response, with empty data', () => {
+ const commitPayload = {
+ type: CHECK_RUNNERS,
+ message: messages.runnersCheckEmpty(TEST_RUNNERS_HELP_PATH),
+ };
+
+ return testAction(
+ actions.receiveRunnersCheckSuccess,
+ [],
+ state,
+ [{ type: mutationTypes.RECEIVE_CHECK_ERROR, payload: commitPayload }],
+ [{ type: 'retryRunnersCheck' }],
+ );
+ });
+ });
+
+ describe('receiveRunnersCheckError', () => {
+ it('dispatches handle with message', () => {
+ const commitPayload = {
+ type: CHECK_RUNNERS,
+ message: messages.UNEXPECTED_ERROR_RUNNERS,
+ };
+
+ return testAction(
+ actions.receiveRunnersCheckError,
+ null,
+ {},
+ [{ type: mutationTypes.RECEIVE_CHECK_ERROR, payload: commitPayload }],
+ [],
+ );
+ });
+ });
+
+ describe('retryRunnersCheck', () => {
+ it('dispatches fetch again after timeout', () => {
+ const dispatch = jest.fn().mockName('dispatch');
+
+ actions.retryRunnersCheck({ dispatch, state });
+
+ expect(dispatch).not.toHaveBeenCalled();
+
+ jest.advanceTimersByTime(RETRY_RUNNERS_INTERVAL + 1);
+
+ expect(dispatch).toHaveBeenCalledWith('fetchRunnersCheck', { background: true });
+ });
+
+ it('does not dispatch fetch if config check is error', () => {
+ const dispatch = jest.fn().mockName('dispatch');
+ state.checks.config = {
+ isLoading: false,
+ isValid: false,
+ };
+
+ actions.retryRunnersCheck({ dispatch, state });
+
+ expect(dispatch).not.toHaveBeenCalled();
+
+ jest.advanceTimersByTime(RETRY_RUNNERS_INTERVAL + 1);
+
+ expect(dispatch).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('fetchRunnersCheck', () => {
+ it('dispatches request and receive', () => {
+ mock.onGet(/api\/.*\/projects\/.*\/runners/, { params: { scope: 'active' } }).reply(200, []);
+
+ return testAction(
+ actions.fetchRunnersCheck,
+ {},
+ rootGetters,
+ [],
+ [{ type: 'requestRunnersCheck' }, { type: 'receiveRunnersCheckSuccess', payload: [] }],
+ );
+ });
+
+ it('does not dispatch request when background is true', () => {
+ mock.onGet(/api\/.*\/projects\/.*\/runners/, { params: { scope: 'active' } }).reply(200, []);
+
+ return testAction(
+ actions.fetchRunnersCheck,
+ { background: true },
+ rootGetters,
+ [],
+ [{ type: 'receiveRunnersCheckSuccess', payload: [] }],
+ );
+ });
+
+ it('dispatches request and receive, when error', () => {
+ mock.onGet(/api\/.*\/projects\/.*\/runners/, { params: { scope: 'active' } }).reply(500, []);
+
+ return testAction(
+ actions.fetchRunnersCheck,
+ {},
+ rootGetters,
+ [],
+ [
+ { type: 'requestRunnersCheck' },
+ { type: 'receiveRunnersCheckError', payload: expect.any(Error) },
+ ],
+ );
+ });
+ });
+});
diff --git a/spec/frontend/ide/stores/modules/terminal/actions/session_controls_spec.js b/spec/frontend/ide/stores/modules/terminal/actions/session_controls_spec.js
new file mode 100644
index 00000000000..4bc937b4784
--- /dev/null
+++ b/spec/frontend/ide/stores/modules/terminal/actions/session_controls_spec.js
@@ -0,0 +1,300 @@
+import MockAdapter from 'axios-mock-adapter';
+import testAction from 'helpers/vuex_action_helper';
+import { STARTING, PENDING, STOPPING, STOPPED } from '~/ide/stores/modules/terminal/constants';
+import * as messages from '~/ide/stores/modules/terminal/messages';
+import * as mutationTypes from '~/ide/stores/modules/terminal/mutation_types';
+import * as actions from '~/ide/stores/modules/terminal/actions/session_controls';
+import httpStatus from '~/lib/utils/http_status';
+import axios from '~/lib/utils/axios_utils';
+import createFlash from '~/flash';
+
+jest.mock('~/flash');
+
+const TEST_PROJECT_PATH = 'lorem/root';
+const TEST_BRANCH_ID = 'master';
+const TEST_SESSION = {
+ id: 7,
+ status: PENDING,
+ show_path: 'path/show',
+ cancel_path: 'path/cancel',
+ retry_path: 'path/retry',
+ terminal_path: 'path/terminal',
+ proxy_websocket_path: 'path/proxy',
+ services: ['test-service'],
+};
+
+describe('IDE store terminal session controls actions', () => {
+ let mock;
+ let dispatch;
+ let rootState;
+ let rootGetters;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ dispatch = jest.fn().mockName('dispatch');
+ rootState = {
+ currentBranchId: TEST_BRANCH_ID,
+ };
+ rootGetters = {
+ currentProject: {
+ id: 7,
+ path_with_namespace: TEST_PROJECT_PATH,
+ },
+ };
+ });
+
+ afterEach(() => {
+ mock.restore();
+ });
+
+ describe('requestStartSession', () => {
+ it('sets session status', () => {
+ return testAction(
+ actions.requestStartSession,
+ null,
+ {},
+ [{ type: mutationTypes.SET_SESSION_STATUS, payload: STARTING }],
+ [],
+ );
+ });
+ });
+
+ describe('receiveStartSessionSuccess', () => {
+ it('sets session and starts polling status', () => {
+ return testAction(
+ actions.receiveStartSessionSuccess,
+ TEST_SESSION,
+ {},
+ [
+ {
+ type: mutationTypes.SET_SESSION,
+ payload: {
+ id: TEST_SESSION.id,
+ status: TEST_SESSION.status,
+ showPath: TEST_SESSION.show_path,
+ cancelPath: TEST_SESSION.cancel_path,
+ retryPath: TEST_SESSION.retry_path,
+ terminalPath: TEST_SESSION.terminal_path,
+ proxyWebsocketPath: TEST_SESSION.proxy_websocket_path,
+ services: TEST_SESSION.services,
+ },
+ },
+ ],
+ [{ type: 'pollSessionStatus' }],
+ );
+ });
+ });
+
+ describe('receiveStartSessionError', () => {
+ it('flashes message', () => {
+ actions.receiveStartSessionError({ dispatch });
+
+ expect(createFlash).toHaveBeenCalledWith(messages.UNEXPECTED_ERROR_STARTING);
+ });
+
+ it('sets session status', () => {
+ return testAction(actions.receiveStartSessionError, null, {}, [], [{ type: 'killSession' }]);
+ });
+ });
+
+ describe('startSession', () => {
+ it('does nothing if session is already starting', () => {
+ const state = {
+ session: { status: STARTING },
+ };
+
+ actions.startSession({ state, dispatch });
+
+ expect(dispatch).not.toHaveBeenCalled();
+ });
+
+ it('dispatches request and receive on success', () => {
+ mock.onPost(/.*\/ide_terminals/).reply(200, TEST_SESSION);
+
+ return testAction(
+ actions.startSession,
+ null,
+ { ...rootGetters, ...rootState },
+ [],
+ [
+ { type: 'requestStartSession' },
+ { type: 'receiveStartSessionSuccess', payload: TEST_SESSION },
+ ],
+ );
+ });
+
+ it('dispatches request and receive on error', () => {
+ mock.onPost(/.*\/ide_terminals/).reply(400);
+
+ return testAction(
+ actions.startSession,
+ null,
+ { ...rootGetters, ...rootState },
+ [],
+ [
+ { type: 'requestStartSession' },
+ { type: 'receiveStartSessionError', payload: expect.any(Error) },
+ ],
+ );
+ });
+ });
+
+ describe('requestStopSession', () => {
+ it('sets session status', () => {
+ return testAction(
+ actions.requestStopSession,
+ null,
+ {},
+ [{ type: mutationTypes.SET_SESSION_STATUS, payload: STOPPING }],
+ [],
+ );
+ });
+ });
+
+ describe('receiveStopSessionSuccess', () => {
+ it('kills the session', () => {
+ return testAction(actions.receiveStopSessionSuccess, null, {}, [], [{ type: 'killSession' }]);
+ });
+ });
+
+ describe('receiveStopSessionError', () => {
+ it('flashes message', () => {
+ actions.receiveStopSessionError({ dispatch });
+
+ expect(createFlash).toHaveBeenCalledWith(messages.UNEXPECTED_ERROR_STOPPING);
+ });
+
+ it('kills the session', () => {
+ return testAction(actions.receiveStopSessionError, null, {}, [], [{ type: 'killSession' }]);
+ });
+ });
+
+ describe('stopSession', () => {
+ it('dispatches request and receive on success', () => {
+ mock.onPost(TEST_SESSION.cancel_path).reply(200, {});
+
+ const state = {
+ session: { cancelPath: TEST_SESSION.cancel_path },
+ };
+
+ return testAction(
+ actions.stopSession,
+ null,
+ state,
+ [],
+ [{ type: 'requestStopSession' }, { type: 'receiveStopSessionSuccess' }],
+ );
+ });
+
+ it('dispatches request and receive on error', () => {
+ mock.onPost(TEST_SESSION.cancel_path).reply(400);
+
+ const state = {
+ session: { cancelPath: TEST_SESSION.cancel_path },
+ };
+
+ return testAction(
+ actions.stopSession,
+ null,
+ state,
+ [],
+ [
+ { type: 'requestStopSession' },
+ { type: 'receiveStopSessionError', payload: expect.any(Error) },
+ ],
+ );
+ });
+ });
+
+ describe('killSession', () => {
+ it('stops polling and sets status', () => {
+ return testAction(
+ actions.killSession,
+ null,
+ {},
+ [{ type: mutationTypes.SET_SESSION_STATUS, payload: STOPPED }],
+ [{ type: 'stopPollingSessionStatus' }],
+ );
+ });
+ });
+
+ describe('restartSession', () => {
+ let state;
+
+ beforeEach(() => {
+ state = {
+ session: { status: STOPPED, retryPath: 'test/retry' },
+ };
+ });
+
+ it('does nothing if current not stopped', () => {
+ state.session.status = STOPPING;
+
+ actions.restartSession({ state, dispatch, rootState });
+
+ expect(dispatch).not.toHaveBeenCalled();
+ });
+
+ it('dispatches startSession if retryPath is empty', () => {
+ state.session.retryPath = '';
+
+ return testAction(
+ actions.restartSession,
+ null,
+ { ...state, ...rootState },
+ [],
+ [{ type: 'startSession' }],
+ );
+ });
+
+ it('dispatches request and receive on success', () => {
+ mock
+ .onPost(state.session.retryPath, { branch: rootState.currentBranchId, format: 'json' })
+ .reply(200, TEST_SESSION);
+
+ return testAction(
+ actions.restartSession,
+ null,
+ { ...state, ...rootState },
+ [],
+ [
+ { type: 'requestStartSession' },
+ { type: 'receiveStartSessionSuccess', payload: TEST_SESSION },
+ ],
+ );
+ });
+
+ it('dispatches request and receive on error', () => {
+ mock
+ .onPost(state.session.retryPath, { branch: rootState.currentBranchId, format: 'json' })
+ .reply(400);
+
+ return testAction(
+ actions.restartSession,
+ null,
+ { ...state, ...rootState },
+ [],
+ [
+ { type: 'requestStartSession' },
+ { type: 'receiveStartSessionError', payload: expect.any(Error) },
+ ],
+ );
+ });
+
+ [httpStatus.NOT_FOUND, httpStatus.UNPROCESSABLE_ENTITY].forEach(status => {
+ it(`dispatches request and startSession on ${status}`, () => {
+ mock
+ .onPost(state.session.retryPath, { branch: rootState.currentBranchId, format: 'json' })
+ .reply(status);
+
+ return testAction(
+ actions.restartSession,
+ null,
+ { ...state, ...rootState },
+ [],
+ [{ type: 'requestStartSession' }, { type: 'startSession' }],
+ );
+ });
+ });
+ });
+});
diff --git a/spec/frontend/ide/stores/modules/terminal/actions/session_status_spec.js b/spec/frontend/ide/stores/modules/terminal/actions/session_status_spec.js
new file mode 100644
index 00000000000..7909f828124
--- /dev/null
+++ b/spec/frontend/ide/stores/modules/terminal/actions/session_status_spec.js
@@ -0,0 +1,169 @@
+import MockAdapter from 'axios-mock-adapter';
+import testAction from 'helpers/vuex_action_helper';
+import { PENDING, RUNNING, STOPPING, STOPPED } from '~/ide/stores/modules/terminal/constants';
+import * as messages from '~/ide/stores/modules/terminal/messages';
+import * as mutationTypes from '~/ide/stores/modules/terminal/mutation_types';
+import * as actions from '~/ide/stores/modules/terminal/actions/session_status';
+import axios from '~/lib/utils/axios_utils';
+import createFlash from '~/flash';
+
+jest.mock('~/flash');
+
+const TEST_SESSION = {
+ id: 7,
+ status: PENDING,
+ show_path: 'path/show',
+ cancel_path: 'path/cancel',
+ retry_path: 'path/retry',
+ terminal_path: 'path/terminal',
+};
+
+describe('IDE store terminal session controls actions', () => {
+ let mock;
+ let dispatch;
+ let commit;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ dispatch = jest.fn().mockName('dispatch');
+ commit = jest.fn().mockName('commit');
+ });
+
+ afterEach(() => {
+ mock.restore();
+ });
+
+ describe('pollSessionStatus', () => {
+ it('starts interval to poll status', () => {
+ return testAction(
+ actions.pollSessionStatus,
+ null,
+ {},
+ [{ type: mutationTypes.SET_SESSION_STATUS_INTERVAL, payload: expect.any(Number) }],
+ [{ type: 'stopPollingSessionStatus' }, { type: 'fetchSessionStatus' }],
+ );
+ });
+
+ it('on interval, stops polling if no session', () => {
+ const state = {
+ session: null,
+ };
+
+ actions.pollSessionStatus({ state, dispatch, commit });
+ dispatch.mockClear();
+
+ jest.advanceTimersByTime(5001);
+
+ expect(dispatch).toHaveBeenCalledWith('stopPollingSessionStatus');
+ });
+
+ it('on interval, fetches status', () => {
+ const state = {
+ session: TEST_SESSION,
+ };
+
+ actions.pollSessionStatus({ state, dispatch, commit });
+ dispatch.mockClear();
+
+ jest.advanceTimersByTime(5001);
+
+ expect(dispatch).toHaveBeenCalledWith('fetchSessionStatus');
+ });
+ });
+
+ describe('stopPollingSessionStatus', () => {
+ it('does nothing if sessionStatusInterval is empty', () => {
+ return testAction(actions.stopPollingSessionStatus, null, {}, [], []);
+ });
+
+ it('clears interval', () => {
+ return testAction(
+ actions.stopPollingSessionStatus,
+ null,
+ { sessionStatusInterval: 7 },
+ [{ type: mutationTypes.SET_SESSION_STATUS_INTERVAL, payload: 0 }],
+ [],
+ );
+ });
+ });
+
+ describe('receiveSessionStatusSuccess', () => {
+ it('sets session status', () => {
+ return testAction(
+ actions.receiveSessionStatusSuccess,
+ { status: RUNNING },
+ {},
+ [{ type: mutationTypes.SET_SESSION_STATUS, payload: RUNNING }],
+ [],
+ );
+ });
+
+ [STOPPING, STOPPED, 'unexpected'].forEach(status => {
+ it(`kills session if status is ${status}`, () => {
+ return testAction(
+ actions.receiveSessionStatusSuccess,
+ { status },
+ {},
+ [{ type: mutationTypes.SET_SESSION_STATUS, payload: status }],
+ [{ type: 'killSession' }],
+ );
+ });
+ });
+ });
+
+ describe('receiveSessionStatusError', () => {
+ it('flashes message', () => {
+ actions.receiveSessionStatusError({ dispatch });
+
+ expect(createFlash).toHaveBeenCalledWith(messages.UNEXPECTED_ERROR_STATUS);
+ });
+
+ it('kills the session', () => {
+ return testAction(actions.receiveSessionStatusError, null, {}, [], [{ type: 'killSession' }]);
+ });
+ });
+
+ describe('fetchSessionStatus', () => {
+ let state;
+
+ beforeEach(() => {
+ state = {
+ session: {
+ showPath: TEST_SESSION.show_path,
+ },
+ };
+ });
+
+ it('does nothing if session is falsey', () => {
+ state.session = null;
+
+ actions.fetchSessionStatus({ dispatch, state });
+
+ expect(dispatch).not.toHaveBeenCalled();
+ });
+
+ it('dispatches success on success', () => {
+ mock.onGet(state.session.showPath).reply(200, TEST_SESSION);
+
+ return testAction(
+ actions.fetchSessionStatus,
+ null,
+ state,
+ [],
+ [{ type: 'receiveSessionStatusSuccess', payload: TEST_SESSION }],
+ );
+ });
+
+ it('dispatches error on error', () => {
+ mock.onGet(state.session.showPath).reply(400);
+
+ return testAction(
+ actions.fetchSessionStatus,
+ null,
+ state,
+ [],
+ [{ type: 'receiveSessionStatusError', payload: expect.any(Error) }],
+ );
+ });
+ });
+});
diff --git a/spec/frontend/ide/stores/modules/terminal/actions/setup_spec.js b/spec/frontend/ide/stores/modules/terminal/actions/setup_spec.js
new file mode 100644
index 00000000000..8bf3b58228e
--- /dev/null
+++ b/spec/frontend/ide/stores/modules/terminal/actions/setup_spec.js
@@ -0,0 +1,40 @@
+import testAction from 'helpers/vuex_action_helper';
+import * as mutationTypes from '~/ide/stores/modules/terminal/mutation_types';
+import * as actions from '~/ide/stores/modules/terminal/actions/setup';
+
+describe('IDE store terminal setup actions', () => {
+ describe('init', () => {
+ it('dispatches checks', () => {
+ return testAction(
+ actions.init,
+ null,
+ {},
+ [],
+ [{ type: 'fetchConfigCheck' }, { type: 'fetchRunnersCheck' }],
+ );
+ });
+ });
+
+ describe('hideSplash', () => {
+ it('commits HIDE_SPLASH', () => {
+ return testAction(actions.hideSplash, null, {}, [{ type: mutationTypes.HIDE_SPLASH }], []);
+ });
+ });
+
+ describe('setPaths', () => {
+ it('commits SET_PATHS', () => {
+ const paths = {
+ foo: 'bar',
+ lorem: 'ipsum',
+ };
+
+ return testAction(
+ actions.setPaths,
+ paths,
+ {},
+ [{ type: mutationTypes.SET_PATHS, payload: paths }],
+ [],
+ );
+ });
+ });
+});
diff --git a/spec/frontend/ide/stores/modules/terminal/getters_spec.js b/spec/frontend/ide/stores/modules/terminal/getters_spec.js
new file mode 100644
index 00000000000..b5d6a4bc746
--- /dev/null
+++ b/spec/frontend/ide/stores/modules/terminal/getters_spec.js
@@ -0,0 +1,50 @@
+import { CHECK_CONFIG, CHECK_RUNNERS } from '~/ide/stores/modules/terminal/constants';
+import * as getters from '~/ide/stores/modules/terminal/getters';
+
+describe('IDE store terminal getters', () => {
+ describe('allCheck', () => {
+ it('is loading if one check is loading', () => {
+ const checks = {
+ [CHECK_CONFIG]: { isLoading: false, isValid: true },
+ [CHECK_RUNNERS]: { isLoading: true },
+ };
+
+ const result = getters.allCheck({ checks });
+
+ expect(result).toEqual({
+ isLoading: true,
+ });
+ });
+
+ it('is invalid if one check is invalid', () => {
+ const message = 'lorem ipsum';
+ const checks = {
+ [CHECK_CONFIG]: { isLoading: false, isValid: false, message },
+ [CHECK_RUNNERS]: { isLoading: false, isValid: true },
+ };
+
+ const result = getters.allCheck({ checks });
+
+ expect(result).toEqual({
+ isLoading: false,
+ isValid: false,
+ message,
+ });
+ });
+
+ it('is valid if all checks are valid', () => {
+ const checks = {
+ [CHECK_CONFIG]: { isLoading: false, isValid: true },
+ [CHECK_RUNNERS]: { isLoading: false, isValid: true },
+ };
+
+ const result = getters.allCheck({ checks });
+
+ expect(result).toEqual({
+ isLoading: false,
+ isValid: true,
+ message: '',
+ });
+ });
+ });
+});
diff --git a/spec/frontend/ide/stores/modules/terminal/messages_spec.js b/spec/frontend/ide/stores/modules/terminal/messages_spec.js
new file mode 100644
index 00000000000..966158999da
--- /dev/null
+++ b/spec/frontend/ide/stores/modules/terminal/messages_spec.js
@@ -0,0 +1,38 @@
+import { escape } from 'lodash';
+import { TEST_HOST } from 'spec/test_constants';
+import * as messages from '~/ide/stores/modules/terminal/messages';
+import { sprintf } from '~/locale';
+import httpStatus from '~/lib/utils/http_status';
+
+const TEST_HELP_URL = `${TEST_HOST}/help`;
+
+describe('IDE store terminal messages', () => {
+ describe('configCheckError', () => {
+ it('returns job error, with status UNPROCESSABLE_ENTITY', () => {
+ const result = messages.configCheckError(httpStatus.UNPROCESSABLE_ENTITY, TEST_HELP_URL);
+
+ expect(result).toBe(
+ sprintf(
+ messages.ERROR_CONFIG,
+ {
+ helpStart: `<a href="${escape(TEST_HELP_URL)}" target="_blank">`,
+ helpEnd: '</a>',
+ },
+ false,
+ ),
+ );
+ });
+
+ it('returns permission error, with status FORBIDDEN', () => {
+ const result = messages.configCheckError(httpStatus.FORBIDDEN, TEST_HELP_URL);
+
+ expect(result).toBe(messages.ERROR_PERMISSION);
+ });
+
+ it('returns unexpected error, with unexpected status', () => {
+ const result = messages.configCheckError(httpStatus.NOT_FOUND, TEST_HELP_URL);
+
+ expect(result).toBe(messages.UNEXPECTED_ERROR_CONFIG);
+ });
+ });
+});
diff --git a/spec/frontend/ide/stores/modules/terminal/mutations_spec.js b/spec/frontend/ide/stores/modules/terminal/mutations_spec.js
new file mode 100644
index 00000000000..e9933bdd7be
--- /dev/null
+++ b/spec/frontend/ide/stores/modules/terminal/mutations_spec.js
@@ -0,0 +1,142 @@
+import {
+ CHECK_CONFIG,
+ CHECK_RUNNERS,
+ RUNNING,
+ STOPPING,
+} from '~/ide/stores/modules/terminal/constants';
+import createState from '~/ide/stores/modules/terminal/state';
+import * as types from '~/ide/stores/modules/terminal/mutation_types';
+import mutations from '~/ide/stores/modules/terminal/mutations';
+
+describe('IDE store terminal mutations', () => {
+ let state;
+
+ beforeEach(() => {
+ state = createState();
+ });
+
+ describe(types.SET_VISIBLE, () => {
+ it('sets isVisible', () => {
+ state.isVisible = false;
+
+ mutations[types.SET_VISIBLE](state, true);
+
+ expect(state.isVisible).toBe(true);
+ });
+ });
+
+ describe(types.HIDE_SPLASH, () => {
+ it('sets isShowSplash', () => {
+ state.isShowSplash = true;
+
+ mutations[types.HIDE_SPLASH](state);
+
+ expect(state.isShowSplash).toBe(false);
+ });
+ });
+
+ describe(types.SET_PATHS, () => {
+ it('sets paths', () => {
+ const paths = {
+ test: 'foo',
+ };
+
+ mutations[types.SET_PATHS](state, paths);
+
+ expect(state.paths).toBe(paths);
+ });
+ });
+
+ describe(types.REQUEST_CHECK, () => {
+ it('sets isLoading for check', () => {
+ const type = CHECK_CONFIG;
+
+ state.checks[type] = {};
+ mutations[types.REQUEST_CHECK](state, type);
+
+ expect(state.checks[type]).toEqual({
+ isLoading: true,
+ });
+ });
+ });
+
+ describe(types.RECEIVE_CHECK_ERROR, () => {
+ it('sets error for check', () => {
+ const type = CHECK_RUNNERS;
+ const message = 'lorem ipsum';
+
+ state.checks[type] = {};
+ mutations[types.RECEIVE_CHECK_ERROR](state, { type, message });
+
+ expect(state.checks[type]).toEqual({
+ isLoading: false,
+ isValid: false,
+ message,
+ });
+ });
+ });
+
+ describe(types.RECEIVE_CHECK_SUCCESS, () => {
+ it('sets success for check', () => {
+ const type = CHECK_CONFIG;
+
+ state.checks[type] = {};
+ mutations[types.RECEIVE_CHECK_SUCCESS](state, type);
+
+ expect(state.checks[type]).toEqual({
+ isLoading: false,
+ isValid: true,
+ message: null,
+ });
+ });
+ });
+
+ describe(types.SET_SESSION, () => {
+ it('sets session', () => {
+ const session = {
+ terminalPath: 'terminal/foo',
+ status: RUNNING,
+ };
+
+ mutations[types.SET_SESSION](state, session);
+
+ expect(state.session).toBe(session);
+ });
+ });
+
+ describe(types.SET_SESSION_STATUS, () => {
+ it('sets session if a session does not exists', () => {
+ const status = RUNNING;
+
+ mutations[types.SET_SESSION_STATUS](state, status);
+
+ expect(state.session).toEqual({
+ status,
+ });
+ });
+
+ it('sets session status', () => {
+ state.session = {
+ terminalPath: 'terminal/foo',
+ status: RUNNING,
+ };
+
+ mutations[types.SET_SESSION_STATUS](state, STOPPING);
+
+ expect(state.session).toEqual({
+ terminalPath: 'terminal/foo',
+ status: STOPPING,
+ });
+ });
+ });
+
+ describe(types.SET_SESSION_STATUS_INTERVAL, () => {
+ it('sets sessionStatusInterval', () => {
+ const val = 7;
+
+ mutations[types.SET_SESSION_STATUS_INTERVAL](state, val);
+
+ expect(state.sessionStatusInterval).toEqual(val);
+ });
+ });
+});
diff --git a/spec/frontend/ide/stores/modules/terminal_sync/actions_spec.js b/spec/frontend/ide/stores/modules/terminal_sync/actions_spec.js
new file mode 100644
index 00000000000..ac976300ed0
--- /dev/null
+++ b/spec/frontend/ide/stores/modules/terminal_sync/actions_spec.js
@@ -0,0 +1,118 @@
+import * as actions from '~/ide/stores/modules/terminal_sync/actions';
+import mirror, { canConnect, SERVICE_NAME } from '~/ide/lib/mirror';
+import * as types from '~/ide/stores/modules/terminal_sync/mutation_types';
+import testAction from 'helpers/vuex_action_helper';
+
+jest.mock('~/ide/lib/mirror');
+
+const TEST_SESSION = {
+ proxyWebsocketPath: 'test/path',
+ services: [SERVICE_NAME],
+};
+
+describe('ide/stores/modules/terminal_sync/actions', () => {
+ let rootState;
+
+ beforeEach(() => {
+ canConnect.mockReturnValue(true);
+ rootState = {
+ changedFiles: [],
+ terminal: {},
+ };
+ });
+
+ describe('upload', () => {
+ it('uploads to mirror and sets success', done => {
+ mirror.upload.mockReturnValue(Promise.resolve());
+
+ testAction(
+ actions.upload,
+ null,
+ rootState,
+ [{ type: types.START_LOADING }, { type: types.SET_SUCCESS }],
+ [],
+ () => {
+ expect(mirror.upload).toHaveBeenCalledWith(rootState);
+ done();
+ },
+ );
+ });
+
+ it('sets error when failed', done => {
+ const err = { message: 'it failed!' };
+ mirror.upload.mockReturnValue(Promise.reject(err));
+
+ testAction(
+ actions.upload,
+ null,
+ rootState,
+ [{ type: types.START_LOADING }, { type: types.SET_ERROR, payload: err }],
+ [],
+ done,
+ );
+ });
+ });
+
+ describe('stop', () => {
+ it('disconnects from mirror', done => {
+ testAction(actions.stop, null, rootState, [{ type: types.STOP }], [], () => {
+ expect(mirror.disconnect).toHaveBeenCalled();
+ done();
+ });
+ });
+ });
+
+ describe('start', () => {
+ it.each`
+ session | canConnectMock | description
+ ${null} | ${true} | ${'does not exist'}
+ ${{}} | ${true} | ${'does not have proxyWebsocketPath'}
+ ${{ proxyWebsocketPath: 'test/path' }} | ${false} | ${'can not connect service'}
+ `('rejects if session $description', ({ session, canConnectMock }) => {
+ canConnect.mockReturnValue(canConnectMock);
+
+ const result = actions.start({ rootState: { terminal: { session } } });
+
+ return expect(result).rejects.toBe(undefined);
+ });
+
+ describe('with terminal session in state', () => {
+ beforeEach(() => {
+ rootState = {
+ terminal: { session: TEST_SESSION },
+ };
+ });
+
+ it('connects to mirror and sets success', done => {
+ mirror.connect.mockReturnValue(Promise.resolve());
+
+ testAction(
+ actions.start,
+ null,
+ rootState,
+ [{ type: types.START_LOADING }, { type: types.SET_SUCCESS }],
+ [],
+ () => {
+ expect(mirror.connect).toHaveBeenCalledWith(TEST_SESSION.proxyWebsocketPath);
+ done();
+ },
+ );
+ });
+
+ it('sets error if connection fails', () => {
+ const commit = jest.fn();
+ const err = new Error('test');
+ mirror.connect.mockReturnValue(Promise.reject(err));
+
+ const result = actions.start({ rootState, commit });
+
+ return Promise.all([
+ expect(result).rejects.toEqual(err),
+ result.catch(() => {
+ expect(commit).toHaveBeenCalledWith(types.SET_ERROR, err);
+ }),
+ ]);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/ide/stores/modules/terminal_sync/mutations_spec.js b/spec/frontend/ide/stores/modules/terminal_sync/mutations_spec.js
new file mode 100644
index 00000000000..ecf35d60e96
--- /dev/null
+++ b/spec/frontend/ide/stores/modules/terminal_sync/mutations_spec.js
@@ -0,0 +1,89 @@
+import createState from '~/ide/stores/modules/terminal_sync/state';
+import * as types from '~/ide/stores/modules/terminal_sync/mutation_types';
+import mutations from '~/ide/stores/modules/terminal_sync/mutations';
+
+const TEST_MESSAGE = 'lorem ipsum dolar sit';
+
+describe('ide/stores/modules/terminal_sync/mutations', () => {
+ let state;
+
+ beforeEach(() => {
+ state = createState();
+ });
+
+ describe(types.START_LOADING, () => {
+ it('sets isLoading and resets error', () => {
+ Object.assign(state, {
+ isLoading: false,
+ isError: true,
+ });
+
+ mutations[types.START_LOADING](state);
+
+ expect(state).toEqual(
+ expect.objectContaining({
+ isLoading: true,
+ isError: false,
+ }),
+ );
+ });
+ });
+
+ describe(types.SET_ERROR, () => {
+ it('sets isLoading and error message', () => {
+ Object.assign(state, {
+ isLoading: true,
+ isError: false,
+ message: '',
+ });
+
+ mutations[types.SET_ERROR](state, { message: TEST_MESSAGE });
+
+ expect(state).toEqual(
+ expect.objectContaining({
+ isLoading: false,
+ isError: true,
+ message: TEST_MESSAGE,
+ }),
+ );
+ });
+ });
+
+ describe(types.SET_SUCCESS, () => {
+ it('sets isLoading and resets error and is started', () => {
+ Object.assign(state, {
+ isLoading: true,
+ isError: true,
+ isStarted: false,
+ });
+
+ mutations[types.SET_SUCCESS](state);
+
+ expect(state).toEqual(
+ expect.objectContaining({
+ isLoading: false,
+ isError: false,
+ isStarted: true,
+ }),
+ );
+ });
+ });
+
+ describe(types.STOP, () => {
+ it('sets stop values', () => {
+ Object.assign(state, {
+ isLoading: true,
+ isStarted: true,
+ });
+
+ mutations[types.STOP](state);
+
+ expect(state).toEqual(
+ expect.objectContaining({
+ isLoading: false,
+ isStarted: false,
+ }),
+ );
+ });
+ });
+});
diff --git a/spec/frontend/ide/stores/mutations/file_spec.js b/spec/frontend/ide/stores/mutations/file_spec.js
index 9b96b910fcb..ff904bbc9cd 100644
--- a/spec/frontend/ide/stores/mutations/file_spec.js
+++ b/spec/frontend/ide/stores/mutations/file_spec.js
@@ -60,22 +60,14 @@ describe('IDE store file mutations', () => {
it('sets extra file data', () => {
mutations.SET_FILE_DATA(localState, {
data: {
- blame_path: 'blame',
- commits_path: 'commits',
- permalink: 'permalink',
raw_path: 'raw',
binary: true,
- render_error: 'render_error',
},
file: localFile,
});
- expect(localFile.blamePath).toBe('blame');
- expect(localFile.commitsPath).toBe('commits');
- expect(localFile.permalink).toBe('permalink');
expect(localFile.rawPath).toBe('raw');
expect(localFile.binary).toBeTruthy();
- expect(localFile.renderError).toBe('render_error');
expect(localFile.raw).toBeNull();
expect(localFile.baseRaw).toBeNull();
});
@@ -356,14 +348,6 @@ describe('IDE store file mutations', () => {
expect(localState.changedFiles.length).toBe(1);
});
-
- it('bursts unused seal', () => {
- expect(localState.unusedSeal).toBe(true);
-
- mutations.ADD_FILE_TO_CHANGED(localState, localFile.path);
-
- expect(localState.unusedSeal).toBe(false);
- });
});
describe('REMOVE_FILE_FROM_CHANGED', () => {
@@ -374,14 +358,6 @@ describe('IDE store file mutations', () => {
expect(localState.changedFiles.length).toBe(0);
});
-
- it('bursts unused seal', () => {
- expect(localState.unusedSeal).toBe(true);
-
- mutations.REMOVE_FILE_FROM_CHANGED(localState, localFile.path);
-
- expect(localState.unusedSeal).toBe(false);
- });
});
describe.each`
@@ -533,19 +509,6 @@ describe('IDE store file mutations', () => {
},
);
- describe('STAGE_CHANGE', () => {
- it('bursts unused seal', () => {
- expect(localState.unusedSeal).toBe(true);
-
- mutations.STAGE_CHANGE(localState, {
- path: localFile.path,
- diffInfo: localStore.getters.getDiffInfo(localFile.path),
- });
-
- expect(localState.unusedSeal).toBe(false);
- });
- });
-
describe('TOGGLE_FILE_CHANGED', () => {
it('updates file changed status', () => {
mutations.TOGGLE_FILE_CHANGED(localState, {
diff --git a/spec/frontend/ide/stores/mutations_spec.js b/spec/frontend/ide/stores/mutations_spec.js
index 2eca9acb8d8..1b29648fb8b 100644
--- a/spec/frontend/ide/stores/mutations_spec.js
+++ b/spec/frontend/ide/stores/mutations_spec.js
@@ -120,24 +120,6 @@ describe('Multi-file store mutations', () => {
expect(localState.trees['gitlab-ce/master'].tree.length).toEqual(1);
expect(localState.entries.test.tempFile).toEqual(true);
});
-
- it('marks entry as replacing previous entry if the old one has been deleted', () => {
- const tmpFile = file('test');
- localState.entries.test = { ...tmpFile, deleted: true };
- mutations.CREATE_TMP_ENTRY(localState, {
- data: {
- entries: {
- test: { ...tmpFile, tempFile: true, changed: true },
- },
- treeList: [tmpFile],
- },
- projectId: 'gitlab-ce',
- branchId: 'master',
- });
-
- expect(localState.trees['gitlab-ce/master'].tree.length).toEqual(1);
- expect(localState.entries.test.replaces).toEqual(true);
- });
});
describe('UPDATE_TEMP_FLAG', () => {
@@ -265,16 +247,6 @@ describe('Multi-file store mutations', () => {
expect(localState.changedFiles).toEqual([]);
expect(localState.stagedFiles).toEqual([]);
});
-
- it('bursts unused seal', () => {
- localState.entries.test = file('test');
-
- expect(localState.unusedSeal).toBe(true);
-
- mutations.DELETE_ENTRY(localState, 'test');
-
- expect(localState.unusedSeal).toBe(false);
- });
});
describe('UPDATE_FILE_AFTER_COMMIT', () => {
@@ -283,10 +255,6 @@ describe('Multi-file store mutations', () => {
...file('test'),
prevPath: 'testing-123',
rawPath: `${TEST_HOST}/testing-123`,
- permalink: `${TEST_HOST}/testing-123`,
- commitsPath: `${TEST_HOST}/testing-123`,
- blamePath: `${TEST_HOST}/testing-123`,
- replaces: true,
};
localState.entries.test = f;
localState.changedFiles.push(f);
@@ -301,10 +269,6 @@ describe('Multi-file store mutations', () => {
expect(f).toEqual(
expect.objectContaining({
rawPath: `${TEST_HOST}/test`,
- permalink: `${TEST_HOST}/test`,
- commitsPath: `${TEST_HOST}/test`,
- blamePath: `${TEST_HOST}/test`,
- replaces: false,
prevId: undefined,
prevPath: undefined,
prevName: undefined,
diff --git a/spec/frontend/ide/stores/plugins/terminal_spec.js b/spec/frontend/ide/stores/plugins/terminal_spec.js
new file mode 100644
index 00000000000..948c2131fd8
--- /dev/null
+++ b/spec/frontend/ide/stores/plugins/terminal_spec.js
@@ -0,0 +1,58 @@
+import { createLocalVue } from '@vue/test-utils';
+import Vuex from 'vuex';
+import { TEST_HOST } from 'helpers/test_constants';
+import terminalModule from '~/ide/stores/modules/terminal';
+import createTerminalPlugin from '~/ide/stores/plugins/terminal';
+import { SET_BRANCH_WORKING_REFERENCE } from '~/ide/stores/mutation_types';
+
+const TEST_DATASET = {
+ eeWebTerminalSvgPath: `${TEST_HOST}/web/terminal/svg`,
+ eeWebTerminalHelpPath: `${TEST_HOST}/web/terminal/help`,
+ eeWebTerminalConfigHelpPath: `${TEST_HOST}/web/terminal/config/help`,
+ eeWebTerminalRunnersHelpPath: `${TEST_HOST}/web/terminal/runners/help`,
+};
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+describe('ide/stores/extend', () => {
+ let store;
+
+ beforeEach(() => {
+ const el = document.createElement('div');
+ Object.assign(el.dataset, TEST_DATASET);
+
+ store = new Vuex.Store({
+ mutations: {
+ [SET_BRANCH_WORKING_REFERENCE]: () => {},
+ },
+ });
+
+ jest.spyOn(store, 'registerModule').mockImplementation();
+ jest.spyOn(store, 'dispatch').mockImplementation();
+
+ const plugin = createTerminalPlugin(el);
+
+ plugin(store);
+ });
+
+ it('registers terminal module', () => {
+ expect(store.registerModule).toHaveBeenCalledWith('terminal', terminalModule());
+ });
+
+ it('dispatches terminal/setPaths', () => {
+ expect(store.dispatch).toHaveBeenCalledWith('terminal/setPaths', {
+ webTerminalSvgPath: TEST_DATASET.eeWebTerminalSvgPath,
+ webTerminalHelpPath: TEST_DATASET.eeWebTerminalHelpPath,
+ webTerminalConfigHelpPath: TEST_DATASET.eeWebTerminalConfigHelpPath,
+ webTerminalRunnersHelpPath: TEST_DATASET.eeWebTerminalRunnersHelpPath,
+ });
+ });
+
+ it(`dispatches terminal/init on ${SET_BRANCH_WORKING_REFERENCE}`, () => {
+ store.dispatch.mockReset();
+
+ store.commit(SET_BRANCH_WORKING_REFERENCE);
+
+ expect(store.dispatch).toHaveBeenCalledWith('terminal/init');
+ });
+});
diff --git a/spec/frontend/ide/stores/plugins/terminal_sync_spec.js b/spec/frontend/ide/stores/plugins/terminal_sync_spec.js
new file mode 100644
index 00000000000..2aa3e770e7d
--- /dev/null
+++ b/spec/frontend/ide/stores/plugins/terminal_sync_spec.js
@@ -0,0 +1,72 @@
+import createTerminalPlugin from '~/ide/stores/plugins/terminal';
+import createTerminalSyncPlugin from '~/ide/stores/plugins/terminal_sync';
+import { SET_SESSION_STATUS } from '~/ide/stores/modules/terminal/mutation_types';
+import { RUNNING, STOPPING } from '~/ide/stores/modules/terminal/constants';
+import { createStore } from '~/ide/stores';
+import eventHub from '~/ide/eventhub';
+
+jest.mock('~/ide/lib/mirror');
+
+const ACTION_START = 'terminalSync/start';
+const ACTION_STOP = 'terminalSync/stop';
+const ACTION_UPLOAD = 'terminalSync/upload';
+const FILES_CHANGE_EVENT = 'ide.files.change';
+
+describe('IDE stores/plugins/mirror', () => {
+ let store;
+
+ beforeEach(() => {
+ const root = document.createElement('div');
+
+ store = createStore();
+ createTerminalPlugin(root)(store);
+
+ store.dispatch = jest.fn(() => Promise.resolve());
+
+ createTerminalSyncPlugin(root)(store);
+ });
+
+ it('does nothing on ide.files.change event', () => {
+ eventHub.$emit(FILES_CHANGE_EVENT);
+
+ expect(store.dispatch).not.toHaveBeenCalled();
+ });
+
+ describe('when session starts running', () => {
+ beforeEach(() => {
+ store.commit(`terminal/${SET_SESSION_STATUS}`, RUNNING);
+ });
+
+ it('starts', () => {
+ expect(store.dispatch).toHaveBeenCalledWith(ACTION_START);
+ });
+
+ it('uploads when ide.files.change is emitted', () => {
+ expect(store.dispatch).not.toHaveBeenCalledWith(ACTION_UPLOAD);
+
+ eventHub.$emit(FILES_CHANGE_EVENT);
+
+ jest.runAllTimers();
+
+ expect(store.dispatch).toHaveBeenCalledWith(ACTION_UPLOAD);
+ });
+
+ describe('when session stops', () => {
+ beforeEach(() => {
+ store.commit(`terminal/${SET_SESSION_STATUS}`, STOPPING);
+ });
+
+ it('stops', () => {
+ expect(store.dispatch).toHaveBeenCalledWith(ACTION_STOP);
+ });
+
+ it('does not upload anymore', () => {
+ eventHub.$emit(FILES_CHANGE_EVENT);
+
+ jest.runAllTimers();
+
+ expect(store.dispatch).not.toHaveBeenCalledWith(ACTION_UPLOAD);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/ide/stores/utils_spec.js b/spec/frontend/ide/stores/utils_spec.js
index b87f6c1f05a..d1eb4304c79 100644
--- a/spec/frontend/ide/stores/utils_spec.js
+++ b/spec/frontend/ide/stores/utils_spec.js
@@ -28,61 +28,6 @@ describe('Multi-file store utils', () => {
});
});
- describe('findIndexOfFile', () => {
- let localState;
-
- beforeEach(() => {
- localState = [
- {
- path: '1',
- },
- {
- path: '2',
- },
- ];
- });
-
- it('finds in the index of an entry by path', () => {
- const index = utils.findIndexOfFile(localState, {
- path: '2',
- });
-
- expect(index).toBe(1);
- });
- });
-
- describe('findEntry', () => {
- let localState;
-
- beforeEach(() => {
- localState = {
- tree: [
- {
- type: 'tree',
- name: 'test',
- },
- {
- type: 'blob',
- name: 'file',
- },
- ],
- };
- });
-
- it('returns an entry found by name', () => {
- const foundEntry = utils.findEntry(localState.tree, 'tree', 'test');
-
- expect(foundEntry.type).toBe('tree');
- expect(foundEntry.name).toBe('test');
- });
-
- it('returns undefined when no entry found', () => {
- const foundEntry = utils.findEntry(localState.tree, 'blob', 'test');
-
- expect(foundEntry).toBeUndefined();
- });
- });
-
describe('createCommitPayload', () => {
it('returns API payload', () => {
const state = {
@@ -101,12 +46,11 @@ describe('Multi-file store utils', () => {
path: 'added',
tempFile: true,
content: 'new file content',
- base64: true,
+ rawPath: 'data:image/png;base64,abc',
lastCommitSha: '123456789',
},
{ ...file('deletedFile'), path: 'deletedFile', deleted: true },
{ ...file('renamedFile'), path: 'renamedFile', prevPath: 'prevPath' },
- { ...file('replacingFile'), path: 'replacingFile', replaces: true },
],
currentBranchId: 'master',
};
@@ -154,14 +98,6 @@ describe('Multi-file store utils', () => {
last_commit_id: undefined,
previous_path: 'prevPath',
},
- {
- action: commitActionTypes.update,
- file_path: 'replacingFile',
- content: undefined,
- encoding: 'text',
- last_commit_id: undefined,
- previous_path: undefined,
- },
],
start_sha: undefined,
});
@@ -181,7 +117,7 @@ describe('Multi-file store utils', () => {
path: 'added',
tempFile: true,
content: 'new file content',
- base64: true,
+ rawPath: 'data:image/png;base64,abc',
lastCommitSha: '123456789',
},
],
@@ -661,31 +597,6 @@ describe('Multi-file store utils', () => {
});
});
- describe('addFinalNewlineIfNeeded', () => {
- it('adds a newline if it doesnt already exist', () => {
- [
- {
- input: 'some text',
- output: 'some text\n',
- },
- {
- input: 'some text\n',
- output: 'some text\n',
- },
- {
- input: 'some text\n\n',
- output: 'some text\n\n',
- },
- {
- input: 'some\n text',
- output: 'some\n text\n',
- },
- ].forEach(({ input, output }) => {
- expect(utils.addFinalNewlineIfNeeded(input)).toEqual(output);
- });
- });
- });
-
describe('extractMarkdownImagesFromEntries', () => {
let mdFile;
let entries;
diff --git a/spec/frontend/ide/sync_router_and_store_spec.js b/spec/frontend/ide/sync_router_and_store_spec.js
new file mode 100644
index 00000000000..c4ce92b99cc
--- /dev/null
+++ b/spec/frontend/ide/sync_router_and_store_spec.js
@@ -0,0 +1,150 @@
+import VueRouter from 'vue-router';
+import { createStore } from '~/ide/stores';
+import { syncRouterAndStore } from '~/ide/sync_router_and_store';
+import waitForPromises from 'helpers/wait_for_promises';
+
+const TEST_ROUTE = '/test/lorem/ipsum';
+
+describe('~/ide/sync_router_and_store', () => {
+ let unsync;
+ let router;
+ let store;
+ let onRouterChange;
+
+ const createSync = () => {
+ unsync = syncRouterAndStore(router, store);
+ };
+
+ const getRouterCurrentPath = () => router.currentRoute.fullPath;
+ const getStoreCurrentPath = () => store.state.router.fullPath;
+ const updateRouter = path => {
+ router.push(path);
+ return waitForPromises();
+ };
+ const updateStore = path => {
+ store.dispatch('router/push', path);
+ return waitForPromises();
+ };
+
+ beforeEach(() => {
+ router = new VueRouter();
+ store = createStore();
+ jest.spyOn(store, 'dispatch');
+
+ onRouterChange = jest.fn();
+ router.beforeEach((to, from, next) => {
+ onRouterChange(to, from);
+ next();
+ });
+ });
+
+ afterEach(() => {
+ unsync();
+ unsync = null;
+ });
+
+ it('keeps store and router in sync', async () => {
+ createSync();
+
+ await updateRouter('/test/test');
+ await updateRouter('/test/test');
+ await updateStore('123/abc');
+ await updateRouter('def');
+
+ // Even though we pused relative paths, the store and router kept track of the resulting fullPath
+ expect(getRouterCurrentPath()).toBe('/test/123/def');
+ expect(getStoreCurrentPath()).toBe('/test/123/def');
+ });
+
+ describe('default', () => {
+ beforeEach(() => {
+ createSync();
+ });
+
+ it('store is default', () => {
+ expect(store.dispatch).not.toHaveBeenCalled();
+ expect(getStoreCurrentPath()).toBe('');
+ });
+
+ it('router is default', () => {
+ expect(onRouterChange).not.toHaveBeenCalled();
+ expect(getRouterCurrentPath()).toBe('/');
+ });
+
+ describe('when store changes', () => {
+ beforeEach(() => {
+ updateStore(TEST_ROUTE);
+ });
+
+ it('store is updated', () => {
+ // let's make sure the action isn't dispatched more than necessary
+ expect(store.dispatch).toHaveBeenCalledTimes(1);
+ expect(getStoreCurrentPath()).toBe(TEST_ROUTE);
+ });
+
+ it('router is updated', () => {
+ expect(onRouterChange).toHaveBeenCalledTimes(1);
+ expect(getRouterCurrentPath()).toBe(TEST_ROUTE);
+ });
+
+ describe('when store changes again to the same thing', () => {
+ beforeEach(() => {
+ onRouterChange.mockClear();
+ updateStore(TEST_ROUTE);
+ });
+
+ it('doesnt change router again', () => {
+ expect(onRouterChange).not.toHaveBeenCalled();
+ });
+ });
+ });
+
+ describe('when router changes', () => {
+ beforeEach(() => {
+ updateRouter(TEST_ROUTE);
+ });
+
+ it('store is updated', () => {
+ expect(store.dispatch).toHaveBeenCalledTimes(1);
+ expect(getStoreCurrentPath()).toBe(TEST_ROUTE);
+ });
+
+ it('router is updated', () => {
+ // let's make sure the router change isn't triggered more than necessary
+ expect(onRouterChange).toHaveBeenCalledTimes(1);
+ expect(getRouterCurrentPath()).toBe(TEST_ROUTE);
+ });
+
+ describe('when router changes again to the same thing', () => {
+ beforeEach(() => {
+ store.dispatch.mockClear();
+ updateRouter(TEST_ROUTE);
+ });
+
+ it('doesnt change store again', () => {
+ expect(store.dispatch).not.toHaveBeenCalled();
+ });
+ });
+ });
+
+ describe('when disposed', () => {
+ beforeEach(() => {
+ unsync();
+ });
+
+ it('a store change does not trigger a router change', () => {
+ updateStore(TEST_ROUTE);
+
+ expect(getRouterCurrentPath()).toBe('/');
+ expect(onRouterChange).not.toHaveBeenCalled();
+ });
+
+ it('a router change does not trigger a store change', () => {
+ updateRouter(TEST_ROUTE);
+
+ expect(getStoreCurrentPath()).toBe('');
+ expect(store.dispatch).not.toHaveBeenCalled();
+ });
+ });
+ });
+});
diff --git a/spec/frontend/ide/utils_spec.js b/spec/frontend/ide/utils_spec.js
index ea975500e8d..15baeca7f36 100644
--- a/spec/frontend/ide/utils_spec.js
+++ b/spec/frontend/ide/utils_spec.js
@@ -1,6 +1,13 @@
-import { commitItemIconMap } from '~/ide/constants';
-import { getCommitIconMap, isTextFile, registerLanguages, trimPathComponents } from '~/ide/utils';
-import { decorateData } from '~/ide/stores/utils';
+import {
+ isTextFile,
+ registerLanguages,
+ trimPathComponents,
+ insertFinalNewline,
+ trimTrailingWhitespace,
+ getPathParents,
+ getPathParent,
+ readFileAsDataURL,
+} from '~/ide/utils';
import { languages } from 'monaco-editor';
describe('WebIDE utils', () => {
@@ -62,48 +69,6 @@ describe('WebIDE utils', () => {
});
});
- const createFile = (name = 'name', id = name, type = '', parent = null) =>
- decorateData({
- id,
- type,
- icon: 'icon',
- url: 'url',
- name,
- path: parent ? `${parent.path}/${name}` : name,
- parentPath: parent ? parent.path : '',
- lastCommit: {},
- });
-
- describe('getCommitIconMap', () => {
- let entry;
-
- beforeEach(() => {
- entry = createFile('Entry item');
- });
-
- it('renders "deleted" icon for deleted entries', () => {
- entry.deleted = true;
- expect(getCommitIconMap(entry)).toEqual(commitItemIconMap.deleted);
- });
-
- it('renders "addition" icon for temp entries', () => {
- entry.tempFile = true;
- expect(getCommitIconMap(entry)).toEqual(commitItemIconMap.addition);
- });
-
- it('renders "modified" icon for newly-renamed entries', () => {
- entry.prevPath = 'foo/bar';
- entry.tempFile = false;
- expect(getCommitIconMap(entry)).toEqual(commitItemIconMap.modified);
- });
-
- it('renders "modified" icon even for temp entries if they are newly-renamed', () => {
- entry.prevPath = 'foo/bar';
- entry.tempFile = true;
- expect(getCommitIconMap(entry)).toEqual(commitItemIconMap.modified);
- });
- });
-
describe('trimPathComponents', () => {
it.each`
input | output
@@ -192,4 +157,86 @@ describe('WebIDE utils', () => {
]);
});
});
+
+ describe('trimTrailingWhitespace', () => {
+ it.each`
+ input | output
+ ${'text \n more text \n'} | ${'text\n more text\n'}
+ ${'text \n more text \n\n \n'} | ${'text\n more text\n\n\n'}
+ ${'text \t\t \n more text \n\t\ttext\n \n\t\t'} | ${'text\n more text\n\t\ttext\n\n'}
+ ${'text \r\n more text \r\n'} | ${'text\r\n more text\r\n'}
+ ${'text \r\n more text \r\n\r\n \r\n'} | ${'text\r\n more text\r\n\r\n\r\n'}
+ ${'text \t\t \r\n more text \r\n\t\ttext\r\n \r\n\t\t'} | ${'text\r\n more text\r\n\t\ttext\r\n\r\n'}
+ `("trims trailing whitespace in each line of file's contents: $input", ({ input, output }) => {
+ expect(trimTrailingWhitespace(input)).toBe(output);
+ });
+ });
+
+ describe('addFinalNewline', () => {
+ it.each`
+ input | output
+ ${'some text'} | ${'some text\n'}
+ ${'some text\n'} | ${'some text\n'}
+ ${'some text\n\n'} | ${'some text\n\n'}
+ ${'some\n text'} | ${'some\n text\n'}
+ `('adds a newline if it doesnt already exist for input: $input', ({ input, output }) => {
+ expect(insertFinalNewline(input)).toBe(output);
+ });
+
+ it.each`
+ input | output
+ ${'some text'} | ${'some text\r\n'}
+ ${'some text\r\n'} | ${'some text\r\n'}
+ ${'some text\n'} | ${'some text\n\r\n'}
+ ${'some text\r\n\r\n'} | ${'some text\r\n\r\n'}
+ ${'some\r\n text'} | ${'some\r\n text\r\n'}
+ `('works with CRLF newline style; input: $input', ({ input, output }) => {
+ expect(insertFinalNewline(input, '\r\n')).toBe(output);
+ });
+ });
+
+ describe('getPathParents', () => {
+ it.each`
+ path | parents
+ ${'foo/bar/baz/index.md'} | ${['foo/bar/baz', 'foo/bar', 'foo']}
+ ${'foo/bar/baz'} | ${['foo/bar', 'foo']}
+ ${'index.md'} | ${[]}
+ ${'path with/spaces to/something.md'} | ${['path with/spaces to', 'path with']}
+ `('gets all parent directory names for path: $path', ({ path, parents }) => {
+ expect(getPathParents(path)).toEqual(parents);
+ });
+
+ it.each`
+ path | depth | parents
+ ${'foo/bar/baz/index.md'} | ${0} | ${[]}
+ ${'foo/bar/baz/index.md'} | ${1} | ${['foo/bar/baz']}
+ ${'foo/bar/baz/index.md'} | ${2} | ${['foo/bar/baz', 'foo/bar']}
+ ${'foo/bar/baz/index.md'} | ${3} | ${['foo/bar/baz', 'foo/bar', 'foo']}
+ ${'foo/bar/baz/index.md'} | ${4} | ${['foo/bar/baz', 'foo/bar', 'foo']}
+ `('gets only the immediate $depth parents if when depth=$depth', ({ path, depth, parents }) => {
+ expect(getPathParents(path, depth)).toEqual(parents);
+ });
+ });
+
+ describe('getPathParent', () => {
+ it.each`
+ path | parents
+ ${'foo/bar/baz/index.md'} | ${'foo/bar/baz'}
+ ${'foo/bar/baz'} | ${'foo/bar'}
+ ${'index.md'} | ${undefined}
+ ${'path with/spaces to/something.md'} | ${'path with/spaces to'}
+ `('gets the immediate parent for path: $path', ({ path, parents }) => {
+ expect(getPathParent(path)).toEqual(parents);
+ });
+ });
+
+ describe('readFileAsDataURL', () => {
+ it('reads a file and returns its output as a data url', () => {
+ const file = new File(['foo'], 'foo.png', { type: 'image/png' });
+
+ return readFileAsDataURL(file).then(contents => {
+ expect(contents).toBe('data:image/png;base64,Zm9v');
+ });
+ });
+ });
});
diff --git a/spec/frontend/import_projects/components/bitbucket_status_table_spec.js b/spec/frontend/import_projects/components/bitbucket_status_table_spec.js
new file mode 100644
index 00000000000..132ccd0e324
--- /dev/null
+++ b/spec/frontend/import_projects/components/bitbucket_status_table_spec.js
@@ -0,0 +1,59 @@
+import { nextTick } from 'vue';
+import { shallowMount } from '@vue/test-utils';
+
+import { GlAlert } from '@gitlab/ui';
+import BitbucketStatusTable from '~/import_projects/components/bitbucket_status_table.vue';
+import ImportProjectsTable from '~/import_projects/components/import_projects_table.vue';
+
+const ImportProjectsTableStub = {
+ name: 'ImportProjectsTable',
+ template:
+ '<div><slot name="incompatible-repos-warning"></slot><slot name="actions"></slot></div>',
+};
+
+describe('BitbucketStatusTable', () => {
+ let wrapper;
+
+ afterEach(() => {
+ if (wrapper) {
+ wrapper.destroy();
+ wrapper = null;
+ }
+ });
+
+ function createComponent(propsData, importProjectsTableStub = true, slots) {
+ wrapper = shallowMount(BitbucketStatusTable, {
+ propsData,
+ stubs: {
+ ImportProjectsTable: importProjectsTableStub,
+ },
+ slots,
+ });
+ }
+
+ it('renders import table component', () => {
+ createComponent({ providerTitle: 'Test' });
+ expect(wrapper.contains(ImportProjectsTable)).toBe(true);
+ });
+
+ it('passes alert in incompatible-repos-warning slot', () => {
+ createComponent({ providerTitle: 'Test' }, ImportProjectsTableStub);
+ expect(wrapper.find(GlAlert).exists()).toBe(true);
+ });
+
+ it('passes actions slot to import project table component', () => {
+ const actionsSlotContent = 'DEMO';
+ createComponent({ providerTitle: 'Test' }, ImportProjectsTableStub, {
+ actions: actionsSlotContent,
+ });
+ expect(wrapper.find(ImportProjectsTable).text()).toBe(actionsSlotContent);
+ });
+
+ it('dismisses alert when requested', async () => {
+ createComponent({ providerTitle: 'Test' }, ImportProjectsTableStub);
+ wrapper.find(GlAlert).vm.$emit('dismiss');
+ await nextTick();
+
+ expect(wrapper.find(GlAlert).exists()).toBe(false);
+ });
+});
diff --git a/spec/frontend/import_projects/components/import_projects_table_spec.js b/spec/frontend/import_projects/components/import_projects_table_spec.js
index 9491b52c888..419d67e239f 100644
--- a/spec/frontend/import_projects/components/import_projects_table_spec.js
+++ b/spec/frontend/import_projects/components/import_projects_table_spec.js
@@ -1,11 +1,24 @@
+import { nextTick } from 'vue';
import Vuex from 'vuex';
-import { createLocalVue, mount } from '@vue/test-utils';
-import { state, actions, getters, mutations } from '~/import_projects/store';
-import importProjectsTable from '~/import_projects/components/import_projects_table.vue';
-import STATUS_MAP from '~/import_projects/constants';
+import { createLocalVue, shallowMount } from '@vue/test-utils';
+import { GlLoadingIcon, GlButton } from '@gitlab/ui';
+import { state, getters } from '~/import_projects/store';
+import eventHub from '~/import_projects/event_hub';
+import ImportProjectsTable from '~/import_projects/components/import_projects_table.vue';
+import ImportedProjectTableRow from '~/import_projects/components/imported_project_table_row.vue';
+import ProviderRepoTableRow from '~/import_projects/components/provider_repo_table_row.vue';
+import IncompatibleRepoTableRow from '~/import_projects/components/incompatible_repo_table_row.vue';
+
+jest.mock('~/import_projects/event_hub', () => ({
+ $emit: jest.fn(),
+}));
describe('ImportProjectsTable', () => {
- let vm;
+ let wrapper;
+
+ const findFilterField = () =>
+ wrapper.find('input[data-qa-selector="githubish_import_filter_field"]');
+
const providerTitle = 'THE PROVIDER';
const providerRepo = { id: 10, sanitizedName: 'sanitizedName', fullName: 'fullName' };
const importedProject = {
@@ -16,176 +29,175 @@ describe('ImportProjectsTable', () => {
importSource: 'importSource',
};
- function initStore() {
- const stubbedActions = {
- ...actions,
- fetchJobs: jest.fn(),
- fetchRepos: jest.fn(actions.requestRepos),
- fetchImport: jest.fn(actions.requestImport),
- };
-
- const store = new Vuex.Store({
- state: state(),
- actions: stubbedActions,
- mutations,
- getters,
- });
-
- return store;
- }
-
- function mountComponent() {
+ const findImportAllButton = () =>
+ wrapper
+ .findAll(GlButton)
+ .filter(w => w.props().variant === 'success')
+ .at(0);
+
+ function createComponent({
+ state: initialState,
+ getters: customGetters,
+ slots,
+ filterable,
+ } = {}) {
const localVue = createLocalVue();
localVue.use(Vuex);
- const store = initStore();
+ const store = new Vuex.Store({
+ state: { ...state(), ...initialState },
+ getters: {
+ ...getters,
+ ...customGetters,
+ },
+ actions: {
+ fetchRepos: jest.fn(),
+ fetchReposFiltered: jest.fn(),
+ fetchJobs: jest.fn(),
+ stopJobsPolling: jest.fn(),
+ clearJobsEtagPoll: jest.fn(),
+ setFilter: jest.fn(),
+ },
+ });
- const component = mount(importProjectsTable, {
+ wrapper = shallowMount(ImportProjectsTable, {
localVue,
store,
propsData: {
providerTitle,
+ filterable,
},
+ slots,
});
-
- return component.vm;
}
- beforeEach(() => {
- vm = mountComponent();
- });
-
afterEach(() => {
- vm.$destroy();
+ if (wrapper) {
+ wrapper.destroy();
+ wrapper = null;
+ }
});
- it('renders a loading icon while repos are loading', () =>
- vm.$nextTick().then(() => {
- expect(vm.$el.querySelector('.js-loading-button-icon')).not.toBeNull();
- }));
-
- it('renders a table with imported projects and provider repos', () => {
- vm.$store.dispatch('receiveReposSuccess', {
- importedProjects: [importedProject],
- providerRepos: [providerRepo],
- namespaces: [{ path: 'path' }],
+ it('renders a loading icon while repos are loading', () => {
+ createComponent({
+ state: {
+ isLoadingRepos: true,
+ },
});
- return vm.$nextTick().then(() => {
- expect(vm.$el.querySelector('.js-loading-button-icon')).toBeNull();
- expect(vm.$el.querySelector('.table')).not.toBeNull();
- expect(vm.$el.querySelector('.import-jobs-from-col').innerText).toMatch(
- `From ${providerTitle}`,
- );
-
- expect(vm.$el.querySelector('.js-imported-project')).not.toBeNull();
- expect(vm.$el.querySelector('.js-provider-repo')).not.toBeNull();
- });
+ expect(wrapper.contains(GlLoadingIcon)).toBe(true);
});
- it('renders an empty state if there are no imported projects or provider repos', () => {
- vm.$store.dispatch('receiveReposSuccess', {
- importedProjects: [],
- providerRepos: [],
- namespaces: [],
+ it('renders a table with imported projects and provider repos', () => {
+ createComponent({
+ state: {
+ importedProjects: [importedProject],
+ providerRepos: [providerRepo],
+ incompatibleRepos: [{ ...providerRepo, id: 11 }],
+ namespaces: [{ path: 'path' }],
+ },
});
- return vm.$nextTick().then(() => {
- expect(vm.$el.querySelector('.js-loading-button-icon')).toBeNull();
- expect(vm.$el.querySelector('.table')).toBeNull();
- expect(vm.$el.innerText).toMatch(`No ${providerTitle} repositories found`);
- });
+ expect(wrapper.contains(GlLoadingIcon)).toBe(false);
+ expect(wrapper.contains('table')).toBe(true);
+ expect(
+ wrapper
+ .findAll('th')
+ .filter(w => w.text() === `From ${providerTitle}`)
+ .isEmpty(),
+ ).toBe(false);
+
+ expect(wrapper.contains(ProviderRepoTableRow)).toBe(true);
+ expect(wrapper.contains(ImportedProjectTableRow)).toBe(true);
+ expect(wrapper.contains(IncompatibleRepoTableRow)).toBe(true);
});
- it('shows loading spinner when bulk import button is clicked', () => {
- vm.$store.dispatch('receiveReposSuccess', {
- importedProjects: [],
- providerRepos: [providerRepo],
- namespaces: [{ path: 'path' }],
- });
-
- return vm
- .$nextTick()
- .then(() => {
- expect(vm.$el.querySelector('.js-imported-project')).toBeNull();
- expect(vm.$el.querySelector('.js-provider-repo')).not.toBeNull();
-
- vm.$el.querySelector('.js-import-all').click();
- })
- .then(() => vm.$nextTick())
- .then(() => {
- expect(vm.$el.querySelector('.js-import-all .js-loading-button-icon')).not.toBeNull();
+ it.each`
+ hasIncompatibleRepos | buttonText
+ ${false} | ${'Import all repositories'}
+ ${true} | ${'Import all compatible repositories'}
+ `(
+ 'import all button has "$buttonText" text when hasIncompatibleRepos is $hasIncompatibleRepos',
+ ({ hasIncompatibleRepos, buttonText }) => {
+ createComponent({
+ state: {
+ providerRepos: [providerRepo],
+ },
+ getters: {
+ hasIncompatibleRepos: () => hasIncompatibleRepos,
+ },
});
- });
- it('imports provider repos if bulk import button is clicked', () => {
- mountComponent();
+ expect(findImportAllButton().text()).toBe(buttonText);
+ },
+ );
- vm.$store.dispatch('receiveReposSuccess', {
- importedProjects: [],
- providerRepos: [providerRepo],
- namespaces: [{ path: 'path' }],
+ it('renders an empty state if there are no projects available', () => {
+ createComponent({
+ state: {
+ importedProjects: [],
+ providerRepos: [],
+ incompatibleProjects: [],
+ },
});
- return vm
- .$nextTick()
- .then(() => {
- expect(vm.$el.querySelector('.js-imported-project')).toBeNull();
- expect(vm.$el.querySelector('.js-provider-repo')).not.toBeNull();
-
- vm.$store.dispatch('receiveImportSuccess', { importedProject, repoId: providerRepo.id });
- })
- .then(() => vm.$nextTick())
- .then(() => {
- expect(vm.$el.querySelector('.js-imported-project')).not.toBeNull();
- expect(vm.$el.querySelector('.js-provider-repo')).toBeNull();
- });
+ expect(wrapper.contains(ProviderRepoTableRow)).toBe(false);
+ expect(wrapper.contains(ImportedProjectTableRow)).toBe(false);
+ expect(wrapper.text()).toContain(`No ${providerTitle} repositories found`);
});
- it('polls to update the status of imported projects', () => {
- const updatedProjects = [
- {
- id: importedProject.id,
- importStatus: 'finished',
+ it('sends importAll event when import button is clicked', async () => {
+ createComponent({
+ state: {
+ providerRepos: [providerRepo],
},
- ];
-
- vm.$store.dispatch('receiveReposSuccess', {
- importedProjects: [importedProject],
- providerRepos: [],
- namespaces: [{ path: 'path' }],
});
- return vm
- .$nextTick()
- .then(() => {
- const statusObject = STATUS_MAP[importedProject.importStatus];
+ findImportAllButton().vm.$emit('click');
+ await nextTick();
+ expect(eventHub.$emit).toHaveBeenCalledWith('importAll');
+ });
- expect(vm.$el.querySelector('.js-imported-project')).not.toBeNull();
- expect(vm.$el.querySelector(`.${statusObject.textClass}`).textContent).toMatch(
- statusObject.text,
- );
+ it('shows loading spinner when import is in progress', () => {
+ createComponent({
+ getters: {
+ isImportingAnyRepo: () => true,
+ },
+ });
- expect(vm.$el.querySelector(`.ic-status_${statusObject.icon}`)).not.toBeNull();
+ expect(findImportAllButton().props().loading).toBe(true);
+ });
- vm.$store.dispatch('receiveJobsSuccess', updatedProjects);
- })
- .then(() => vm.$nextTick())
- .then(() => {
- const statusObject = STATUS_MAP[updatedProjects[0].importStatus];
+ it('renders filtering input field by default', () => {
+ createComponent();
+ expect(findFilterField().exists()).toBe(true);
+ });
- expect(vm.$el.querySelector('.js-imported-project')).not.toBeNull();
- expect(vm.$el.querySelector(`.${statusObject.textClass}`).textContent).toMatch(
- statusObject.text,
- );
+ it('does not render filtering input field when filterable is false', () => {
+ createComponent({ filterable: false });
+ expect(findFilterField().exists()).toBe(false);
+ });
- expect(vm.$el.querySelector(`.ic-status_${statusObject.icon}`)).not.toBeNull();
+ it.each`
+ hasIncompatibleRepos | shouldRenderSlot | action
+ ${false} | ${false} | ${'does not render'}
+ ${true} | ${true} | ${'render'}
+ `(
+ '$action incompatible-repos-warning slot if hasIncompatibleRepos is $hasIncompatibleRepos',
+ ({ hasIncompatibleRepos, shouldRenderSlot }) => {
+ const INCOMPATIBLE_TEXT = 'INCOMPATIBLE!';
+
+ createComponent({
+ getters: {
+ hasIncompatibleRepos: () => hasIncompatibleRepos,
+ },
+
+ slots: {
+ 'incompatible-repos-warning': INCOMPATIBLE_TEXT,
+ },
});
- });
- it('renders filtering input field', () => {
- expect(
- vm.$el.querySelector('input[data-qa-selector="githubish_import_filter_field"]'),
- ).not.toBeNull();
- });
+ expect(wrapper.text().includes(INCOMPATIBLE_TEXT)).toBe(shouldRenderSlot);
+ },
+ );
});
diff --git a/spec/frontend/import_projects/components/provider_repo_table_row_spec.js b/spec/frontend/import_projects/components/provider_repo_table_row_spec.js
index 8be645c496f..f5e5141eac8 100644
--- a/spec/frontend/import_projects/components/provider_repo_table_row_spec.js
+++ b/spec/frontend/import_projects/components/provider_repo_table_row_spec.js
@@ -6,7 +6,7 @@ import STATUS_MAP, { STATUSES } from '~/import_projects/constants';
describe('ProviderRepoTableRow', () => {
let vm;
- const fetchImport = jest.fn((context, data) => actions.requestImport(context, data));
+ const fetchImport = jest.fn();
const importPath = '/import-path';
const defaultTargetNamespace = 'user';
const ciCdOnly = true;
@@ -17,11 +17,11 @@ describe('ProviderRepoTableRow', () => {
providerLink: 'providerLink',
};
- function initStore() {
+ function initStore(initialState) {
const stubbedActions = { ...actions, fetchImport };
const store = new Vuex.Store({
- state: state(),
+ state: { ...state(), ...initialState },
actions: stubbedActions,
mutations,
getters,
@@ -30,12 +30,11 @@ describe('ProviderRepoTableRow', () => {
return store;
}
- function mountComponent() {
+ function mountComponent(initialState) {
const localVue = createLocalVue();
localVue.use(Vuex);
- const store = initStore();
- store.dispatch('setInitialData', { importPath, defaultTargetNamespace, ciCdOnly });
+ const store = initStore({ importPath, defaultTargetNamespace, ciCdOnly, ...initialState });
const component = mount(providerRepoTableRow, {
localVue,
diff --git a/spec/frontend/import_projects/store/actions_spec.js b/spec/frontend/import_projects/store/actions_spec.js
index 4954513715e..1f2882a2532 100644
--- a/spec/frontend/import_projects/store/actions_spec.js
+++ b/spec/frontend/import_projects/store/actions_spec.js
@@ -4,7 +4,6 @@ import { TEST_HOST } from 'helpers/test_constants';
import axios from '~/lib/utils/axios_utils';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import {
- SET_INITIAL_DATA,
REQUEST_REPOS,
RECEIVE_REPOS_SUCCESS,
RECEIVE_REPOS_ERROR,
@@ -14,14 +13,7 @@ import {
RECEIVE_JOBS_SUCCESS,
} from '~/import_projects/store/mutation_types';
import {
- setInitialData,
- requestRepos,
- receiveReposSuccess,
- receiveReposError,
fetchRepos,
- requestImport,
- receiveImportSuccess,
- receiveImportError,
fetchImport,
receiveJobsSuccess,
fetchJobs,
@@ -32,7 +24,6 @@ import state from '~/import_projects/store/state';
describe('import_projects store actions', () => {
let localState;
- const repoId = 1;
const repos = [{ id: 1 }, { id: 2 }];
const importPayload = { newName: 'newName', targetNamespace: 'targetNamespace', repo: { id: 1 } };
@@ -40,61 +31,6 @@ describe('import_projects store actions', () => {
localState = state();
});
- describe('setInitialData', () => {
- it(`commits ${SET_INITIAL_DATA} mutation`, done => {
- const initialData = {
- reposPath: 'reposPath',
- provider: 'provider',
- jobsPath: 'jobsPath',
- importPath: 'impapp/assets/javascripts/vue_shared/components/select2_select.vueortPath',
- defaultTargetNamespace: 'defaultTargetNamespace',
- ciCdOnly: 'ciCdOnly',
- canSelectNamespace: 'canSelectNamespace',
- };
-
- testAction(
- setInitialData,
- initialData,
- localState,
- [{ type: SET_INITIAL_DATA, payload: initialData }],
- [],
- done,
- );
- });
- });
-
- describe('requestRepos', () => {
- it(`requestRepos commits ${REQUEST_REPOS} mutation`, done => {
- testAction(
- requestRepos,
- null,
- localState,
- [{ type: REQUEST_REPOS, payload: null }],
- [],
- done,
- );
- });
- });
-
- describe('receiveReposSuccess', () => {
- it(`commits ${RECEIVE_REPOS_SUCCESS} mutation`, done => {
- testAction(
- receiveReposSuccess,
- repos,
- localState,
- [{ type: RECEIVE_REPOS_SUCCESS, payload: repos }],
- [],
- done,
- );
- });
- });
-
- describe('receiveReposError', () => {
- it(`commits ${RECEIVE_REPOS_ERROR} mutation`, done => {
- testAction(receiveReposError, repos, localState, [{ type: RECEIVE_REPOS_ERROR }], [], done);
- });
- });
-
describe('fetchRepos', () => {
let mock;
const payload = { imported_projects: [{}], provider_repos: [{}], namespaces: [{}] };
@@ -106,39 +42,33 @@ describe('import_projects store actions', () => {
afterEach(() => mock.restore());
- it('dispatches stopJobsPolling, requestRepos and receiveReposSuccess actions on a successful request', done => {
+ it('dispatches stopJobsPolling actions and commits REQUEST_REPOS, RECEIVE_REPOS_SUCCESS mutations on a successful request', () => {
mock.onGet(`${TEST_HOST}/endpoint.json`).reply(200, payload);
- testAction(
+ return testAction(
fetchRepos,
null,
localState,
- [],
[
- { type: 'stopJobsPolling' },
- { type: 'requestRepos' },
+ { type: REQUEST_REPOS },
{
- type: 'receiveReposSuccess',
+ type: RECEIVE_REPOS_SUCCESS,
payload: convertObjectPropsToCamelCase(payload, { deep: true }),
},
- {
- type: 'fetchJobs',
- },
],
- done,
+ [{ type: 'stopJobsPolling' }, { type: 'fetchJobs' }],
);
});
- it('dispatches stopJobsPolling, requestRepos and receiveReposError actions on an unsuccessful request', done => {
+ it('dispatches stopJobsPolling action and commits REQUEST_REPOS, RECEIVE_REPOS_ERROR mutations on an unsuccessful request', () => {
mock.onGet(`${TEST_HOST}/endpoint.json`).reply(500);
- testAction(
+ return testAction(
fetchRepos,
null,
localState,
- [],
- [{ type: 'stopJobsPolling' }, { type: 'requestRepos' }, { type: 'receiveReposError' }],
- done,
+ [{ type: REQUEST_REPOS }, { type: RECEIVE_REPOS_ERROR }],
+ [{ type: 'stopJobsPolling' }],
);
});
@@ -147,72 +77,26 @@ describe('import_projects store actions', () => {
localState.filter = 'filter';
});
- it('fetches repos with filter applied', done => {
+ it('fetches repos with filter applied', () => {
mock.onGet(`${TEST_HOST}/endpoint.json?filter=filter`).reply(200, payload);
- testAction(
+ return testAction(
fetchRepos,
null,
localState,
- [],
[
- { type: 'stopJobsPolling' },
- { type: 'requestRepos' },
+ { type: REQUEST_REPOS },
{
- type: 'receiveReposSuccess',
+ type: RECEIVE_REPOS_SUCCESS,
payload: convertObjectPropsToCamelCase(payload, { deep: true }),
},
- {
- type: 'fetchJobs',
- },
],
- done,
+ [{ type: 'stopJobsPolling' }, { type: 'fetchJobs' }],
);
});
});
});
- describe('requestImport', () => {
- it(`commits ${REQUEST_IMPORT} mutation`, done => {
- testAction(
- requestImport,
- repoId,
- localState,
- [{ type: REQUEST_IMPORT, payload: repoId }],
- [],
- done,
- );
- });
- });
-
- describe('receiveImportSuccess', () => {
- it(`commits ${RECEIVE_IMPORT_SUCCESS} mutation`, done => {
- const payload = { importedProject: { name: 'imported/project' }, repoId: 2 };
-
- testAction(
- receiveImportSuccess,
- payload,
- localState,
- [{ type: RECEIVE_IMPORT_SUCCESS, payload }],
- [],
- done,
- );
- });
- });
-
- describe('receiveImportError', () => {
- it(`commits ${RECEIVE_IMPORT_ERROR} mutation`, done => {
- testAction(
- receiveImportError,
- repoId,
- localState,
- [{ type: RECEIVE_IMPORT_ERROR, payload: repoId }],
- [],
- done,
- );
- });
- });
-
describe('fetchImport', () => {
let mock;
@@ -223,56 +107,53 @@ describe('import_projects store actions', () => {
afterEach(() => mock.restore());
- it('dispatches requestImport and receiveImportSuccess actions on a successful request', done => {
+ it('commits REQUEST_IMPORT and REQUEST_IMPORT_SUCCESS mutations on a successful request', () => {
const importedProject = { name: 'imported/project' };
const importRepoId = importPayload.repo.id;
mock.onPost(`${TEST_HOST}/endpoint.json`).reply(200, importedProject);
- testAction(
+ return testAction(
fetchImport,
importPayload,
localState,
- [],
[
- { type: 'requestImport', payload: importRepoId },
+ { type: REQUEST_IMPORT, payload: importRepoId },
{
- type: 'receiveImportSuccess',
+ type: RECEIVE_IMPORT_SUCCESS,
payload: {
importedProject: convertObjectPropsToCamelCase(importedProject, { deep: true }),
repoId: importRepoId,
},
},
],
- done,
+ [],
);
});
- it('dispatches requestImport and receiveImportSuccess actions on an unsuccessful request', done => {
+ it('commits REQUEST_IMPORT and RECEIVE_IMPORT_ERROR on an unsuccessful request', () => {
mock.onPost(`${TEST_HOST}/endpoint.json`).reply(500);
- testAction(
+ return testAction(
fetchImport,
importPayload,
localState,
- [],
[
- { type: 'requestImport', payload: importPayload.repo.id },
- { type: 'receiveImportError', payload: { repoId: importPayload.repo.id } },
+ { type: REQUEST_IMPORT, payload: importPayload.repo.id },
+ { type: RECEIVE_IMPORT_ERROR, payload: importPayload.repo.id },
],
- done,
+ [],
);
});
});
describe('receiveJobsSuccess', () => {
- it(`commits ${RECEIVE_JOBS_SUCCESS} mutation`, done => {
- testAction(
+ it(`commits ${RECEIVE_JOBS_SUCCESS} mutation`, () => {
+ return testAction(
receiveJobsSuccess,
repos,
localState,
[{ type: RECEIVE_JOBS_SUCCESS, payload: repos }],
[],
- done,
);
});
});
@@ -293,21 +174,20 @@ describe('import_projects store actions', () => {
afterEach(() => mock.restore());
- it('dispatches requestJobs and receiveJobsSuccess actions on a successful request', done => {
+ it('commits RECEIVE_JOBS_SUCCESS mutation on a successful request', async () => {
mock.onGet(`${TEST_HOST}/endpoint.json`).reply(200, updatedProjects);
- testAction(
+ await testAction(
fetchJobs,
null,
localState,
- [],
[
{
- type: 'receiveJobsSuccess',
+ type: RECEIVE_JOBS_SUCCESS,
payload: convertObjectPropsToCamelCase(updatedProjects, { deep: true }),
},
],
- done,
+ [],
);
});
@@ -316,21 +196,20 @@ describe('import_projects store actions', () => {
localState.filter = 'filter';
});
- it('fetches realtime changes with filter applied', done => {
+ it('fetches realtime changes with filter applied', () => {
mock.onGet(`${TEST_HOST}/endpoint.json?filter=filter`).reply(200, updatedProjects);
- testAction(
+ return testAction(
fetchJobs,
null,
localState,
- [],
[
{
- type: 'receiveJobsSuccess',
+ type: RECEIVE_JOBS_SUCCESS,
payload: convertObjectPropsToCamelCase(updatedProjects, { deep: true }),
},
],
- done,
+ [],
);
});
});
diff --git a/spec/frontend/import_projects/store/getters_spec.js b/spec/frontend/import_projects/store/getters_spec.js
index e5e4a95f473..93d1ed89783 100644
--- a/spec/frontend/import_projects/store/getters_spec.js
+++ b/spec/frontend/import_projects/store/getters_spec.js
@@ -2,6 +2,7 @@ import {
namespaceSelectOptions,
isImportingAnyRepo,
hasProviderRepos,
+ hasIncompatibleRepos,
hasImportedProjects,
} from '~/import_projects/store/getters';
import state from '~/import_projects/store/state';
@@ -80,4 +81,18 @@ describe('import_projects store getters', () => {
expect(hasImportedProjects(localState)).toBe(false);
});
});
+
+ describe('hasIncompatibleRepos', () => {
+ it('returns true if there are any incompatibleProjects', () => {
+ localState.incompatibleRepos = new Array(1);
+
+ expect(hasIncompatibleRepos(localState)).toBe(true);
+ });
+
+ it('returns false if there are no incompatibleProjects', () => {
+ localState.incompatibleRepos = [];
+
+ expect(hasIncompatibleRepos(localState)).toBe(false);
+ });
+ });
});
diff --git a/spec/frontend/importer_status_spec.js b/spec/frontend/importer_status_spec.js
new file mode 100644
index 00000000000..4ef74a2fe84
--- /dev/null
+++ b/spec/frontend/importer_status_spec.js
@@ -0,0 +1,141 @@
+import MockAdapter from 'axios-mock-adapter';
+import { ImporterStatus } from '~/importer_status';
+import axios from '~/lib/utils/axios_utils';
+
+describe('Importer Status', () => {
+ let instance;
+ let mock;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ });
+
+ afterEach(() => {
+ mock.restore();
+ });
+
+ describe('addToImport', () => {
+ const importUrl = '/import_url';
+ const fixtures = `
+ <table>
+ <tr id="repo_123">
+ <td class="import-target"></td>
+ <td class="import-actions job-status">
+ <button name="button" type="submit" class="btn btn-import js-add-to-import">
+ </button>
+ </td>
+ </tr>
+ </table>
+ `;
+
+ beforeEach(() => {
+ setFixtures(fixtures);
+ jest.spyOn(ImporterStatus.prototype, 'initStatusPage').mockImplementation(() => {});
+ jest.spyOn(ImporterStatus.prototype, 'setAutoUpdate').mockImplementation(() => {});
+ instance = new ImporterStatus({
+ jobsUrl: '',
+ importUrl,
+ });
+ });
+
+ it('sets table row to active after post request', done => {
+ mock.onPost(importUrl).reply(200, {
+ id: 1,
+ full_path: '/full_path',
+ });
+
+ instance
+ .addToImport({
+ currentTarget: document.querySelector('.js-add-to-import'),
+ })
+ .then(() => {
+ expect(document.querySelector('tr').classList.contains('table-active')).toEqual(true);
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('shows error message after failed POST request', done => {
+ setFixtures(`${fixtures}<div class="flash-container"></div>`);
+
+ mock.onPost(importUrl).reply(422, {
+ errors: 'You forgot your lunch',
+ });
+
+ instance
+ .addToImport({
+ currentTarget: document.querySelector('.js-add-to-import'),
+ })
+ .then(() => {
+ const flashMessage = document.querySelector('.flash-text');
+
+ expect(flashMessage.textContent.trim()).toEqual(
+ 'An error occurred while importing project: You forgot your lunch',
+ );
+ done();
+ })
+ .catch(done.fail);
+ });
+ });
+
+ describe('autoUpdate', () => {
+ const jobsUrl = '/jobs_url';
+
+ beforeEach(() => {
+ const div = document.createElement('div');
+ div.innerHTML = `
+ <div id="project_1">
+ <div class="job-status">
+ </div>
+ </div>
+ `;
+
+ document.body.appendChild(div);
+
+ jest.spyOn(ImporterStatus.prototype, 'initStatusPage').mockImplementation(() => {});
+ jest.spyOn(ImporterStatus.prototype, 'setAutoUpdate').mockImplementation(() => {});
+ instance = new ImporterStatus({
+ jobsUrl,
+ });
+ });
+
+ function setupMock(importStatus) {
+ mock.onGet(jobsUrl).reply(200, [
+ {
+ id: 1,
+ import_status: importStatus,
+ },
+ ]);
+ }
+
+ function expectJobStatus(done, status) {
+ instance
+ .autoUpdate()
+ .then(() => {
+ expect(document.querySelector('#project_1').innerText.trim()).toEqual(status);
+ done();
+ })
+ .catch(done.fail);
+ }
+
+ it('sets the job status to done', done => {
+ setupMock('finished');
+ expectJobStatus(done, 'Done');
+ });
+
+ it('sets the job status to scheduled', done => {
+ setupMock('scheduled');
+ expectJobStatus(done, 'Scheduled');
+ });
+
+ it('sets the job status to started', done => {
+ setupMock('started');
+ expectJobStatus(done, 'Started');
+ });
+
+ it('sets the job status to custom status', done => {
+ setupMock('custom status');
+ expectJobStatus(done, 'custom status');
+ });
+ });
+});
diff --git a/spec/frontend/integrations/edit/components/dynamic_field_spec.js b/spec/frontend/integrations/edit/components/dynamic_field_spec.js
new file mode 100644
index 00000000000..e5710641f81
--- /dev/null
+++ b/spec/frontend/integrations/edit/components/dynamic_field_spec.js
@@ -0,0 +1,179 @@
+import { mount } from '@vue/test-utils';
+import DynamicField from '~/integrations/edit/components/dynamic_field.vue';
+import { GlFormGroup, GlFormCheckbox, GlFormInput, GlFormSelect, GlFormTextarea } from '@gitlab/ui';
+
+describe('DynamicField', () => {
+ let wrapper;
+
+ const defaultProps = {
+ help: 'The URL of the project',
+ name: 'project_url',
+ placeholder: 'https://jira.example.com',
+ title: 'Project URL',
+ type: 'text',
+ value: '1',
+ };
+
+ const createComponent = props => {
+ wrapper = mount(DynamicField, {
+ propsData: { ...defaultProps, ...props },
+ });
+ };
+
+ afterEach(() => {
+ if (wrapper) {
+ wrapper.destroy();
+ wrapper = null;
+ }
+ });
+
+ const findGlFormGroup = () => wrapper.find(GlFormGroup);
+ const findGlFormCheckbox = () => wrapper.find(GlFormCheckbox);
+ const findGlFormInput = () => wrapper.find(GlFormInput);
+ const findGlFormSelect = () => wrapper.find(GlFormSelect);
+ const findGlFormTextarea = () => wrapper.find(GlFormTextarea);
+
+ describe('template', () => {
+ describe('dynamic field', () => {
+ describe('type is checkbox', () => {
+ beforeEach(() => {
+ createComponent({
+ type: 'checkbox',
+ });
+ });
+
+ it('renders GlFormCheckbox', () => {
+ expect(findGlFormCheckbox().exists()).toBe(true);
+ });
+
+ it('does not render other types of input', () => {
+ expect(findGlFormSelect().exists()).toBe(false);
+ expect(findGlFormTextarea().exists()).toBe(false);
+ expect(findGlFormInput().exists()).toBe(false);
+ });
+ });
+
+ describe('type is select', () => {
+ beforeEach(() => {
+ createComponent({
+ type: 'select',
+ choices: [['all', 'All details'], ['standard', 'Standard']],
+ });
+ });
+
+ it('renders findGlFormSelect', () => {
+ expect(findGlFormSelect().exists()).toBe(true);
+ expect(findGlFormSelect().findAll('option')).toHaveLength(2);
+ });
+
+ it('does not render other types of input', () => {
+ expect(findGlFormCheckbox().exists()).toBe(false);
+ expect(findGlFormTextarea().exists()).toBe(false);
+ expect(findGlFormInput().exists()).toBe(false);
+ });
+ });
+
+ describe('type is textarea', () => {
+ beforeEach(() => {
+ createComponent({
+ type: 'textarea',
+ });
+ });
+
+ it('renders findGlFormTextarea', () => {
+ expect(findGlFormTextarea().exists()).toBe(true);
+ });
+
+ it('does not render other types of input', () => {
+ expect(findGlFormCheckbox().exists()).toBe(false);
+ expect(findGlFormSelect().exists()).toBe(false);
+ expect(findGlFormInput().exists()).toBe(false);
+ });
+ });
+
+ describe('type is password', () => {
+ beforeEach(() => {
+ createComponent({
+ type: 'password',
+ });
+ });
+
+ it('renders GlFormInput', () => {
+ expect(findGlFormInput().exists()).toBe(true);
+ expect(findGlFormInput().attributes('type')).toBe('password');
+ });
+
+ it('does not render other types of input', () => {
+ expect(findGlFormCheckbox().exists()).toBe(false);
+ expect(findGlFormSelect().exists()).toBe(false);
+ expect(findGlFormTextarea().exists()).toBe(false);
+ });
+ });
+
+ describe('type is text', () => {
+ beforeEach(() => {
+ createComponent({
+ type: 'text',
+ required: true,
+ });
+ });
+
+ it('renders GlFormInput', () => {
+ expect(findGlFormInput().exists()).toBe(true);
+ expect(findGlFormInput().attributes()).toMatchObject({
+ type: 'text',
+ id: 'service_project_url',
+ name: 'service[project_url]',
+ placeholder: defaultProps.placeholder,
+ required: 'required',
+ });
+ });
+
+ it('does not render other types of input', () => {
+ expect(findGlFormCheckbox().exists()).toBe(false);
+ expect(findGlFormSelect().exists()).toBe(false);
+ expect(findGlFormTextarea().exists()).toBe(false);
+ });
+ });
+ });
+
+ describe('help text', () => {
+ it('renders description with help text', () => {
+ createComponent();
+
+ expect(
+ findGlFormGroup()
+ .find('small')
+ .text(),
+ ).toBe(defaultProps.help);
+ });
+ });
+
+ describe('label text', () => {
+ it('renders label with title', () => {
+ createComponent();
+
+ expect(
+ findGlFormGroup()
+ .find('label')
+ .text(),
+ ).toBe(defaultProps.title);
+ });
+
+ describe('for password field with some value (hidden by backend)', () => {
+ it('renders label with new password title', () => {
+ createComponent({
+ type: 'password',
+ value: 'true',
+ });
+
+ expect(
+ findGlFormGroup()
+ .find('label')
+ .text(),
+ ).toBe(`Enter new ${defaultProps.title}`);
+ });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/integrations/edit/components/integration_form_spec.js b/spec/frontend/integrations/edit/components/integration_form_spec.js
index c93f63b11d0..b598a71cea8 100644
--- a/spec/frontend/integrations/edit/components/integration_form_spec.js
+++ b/spec/frontend/integrations/edit/components/integration_form_spec.js
@@ -3,6 +3,7 @@ import IntegrationForm from '~/integrations/edit/components/integration_form.vue
import ActiveToggle from '~/integrations/edit/components/active_toggle.vue';
import JiraTriggerFields from '~/integrations/edit/components/jira_trigger_fields.vue';
import TriggerFields from '~/integrations/edit/components/trigger_fields.vue';
+import DynamicField from '~/integrations/edit/components/dynamic_field.vue';
describe('IntegrationForm', () => {
let wrapper;
@@ -95,5 +96,25 @@ describe('IntegrationForm', () => {
expect(findTriggerFields().props('type')).toBe(type);
});
});
+
+ describe('fields is present', () => {
+ it('renders DynamicField for each field', () => {
+ const fields = [
+ { name: 'username', type: 'text' },
+ { name: 'API token', type: 'password' },
+ ];
+
+ createComponent({
+ fields,
+ });
+
+ const dynamicFields = wrapper.findAll(DynamicField);
+
+ expect(dynamicFields).toHaveLength(2);
+ dynamicFields.wrappers.forEach((field, index) => {
+ expect(field.props()).toMatchObject(fields[index]);
+ });
+ });
+ });
});
});
diff --git a/spec/frontend/issue_show/components/app_spec.js b/spec/frontend/issue_show/components/app_spec.js
index a59d6d35ded..d970fd349e7 100644
--- a/spec/frontend/issue_show/components/app_spec.js
+++ b/spec/frontend/issue_show/components/app_spec.js
@@ -1,10 +1,11 @@
-import Vue from 'vue';
+import { GlIntersectionObserver } from '@gitlab/ui';
+import { mount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import { TEST_HOST } from 'helpers/test_constants';
import axios from '~/lib/utils/axios_utils';
import { visitUrl } from '~/lib/utils/url_utility';
import '~/behaviors/markdown/render_gfm';
-import issuableApp from '~/issue_show/components/app.vue';
+import IssuableApp from '~/issue_show/components/app.vue';
import eventHub from '~/issue_show/event_hub';
import { initialRequest, secondRequest } from '../mock_data';
@@ -17,10 +18,15 @@ jest.mock('~/issue_show/event_hub');
const REALTIME_REQUEST_STACK = [initialRequest, secondRequest];
+const zoomMeetingUrl = 'https://gitlab.zoom.us/j/95919234811';
+const publishedIncidentUrl = 'https://status.com/';
+
describe('Issuable output', () => {
let mock;
let realtimeRequestCount = 0;
- let vm;
+ let wrapper;
+
+ const findStickyHeader = () => wrapper.find('[data-testid="issue-sticky-header"]');
beforeEach(() => {
setFixtures(`
@@ -39,7 +45,10 @@ describe('Issuable output', () => {
</div>
`);
- const IssuableDescriptionComponent = Vue.extend(issuableApp);
+ window.IntersectionObserver = class {
+ disconnect = jest.fn();
+ observe = jest.fn();
+ };
mock = new MockAdapter(axios);
mock
@@ -50,13 +59,14 @@ describe('Issuable output', () => {
return res;
});
- vm = new IssuableDescriptionComponent({
+ wrapper = mount(IssuableApp, {
propsData: {
canUpdate: true,
canDestroy: true,
endpoint: '/gitlab-org/gitlab-shell/-/issues/9/realtime_changes',
updateEndpoint: TEST_HOST,
issuableRef: '#1',
+ issuableStatus: 'opened',
initialTitleHtml: '',
initialTitleText: '',
initialDescriptionHtml: 'test',
@@ -67,16 +77,20 @@ describe('Issuable output', () => {
projectNamespace: '/',
projectPath: '/',
issuableTemplateNamesPath: '/issuable-templates-path',
+ zoomMeetingUrl,
+ publishedIncidentUrl,
},
- }).$mount();
+ });
});
afterEach(() => {
+ delete window.IntersectionObserver;
mock.restore();
realtimeRequestCount = 0;
- vm.poll.stop();
- vm.$destroy();
+ wrapper.vm.poll.stop();
+ wrapper.destroy();
+ wrapper = null;
});
it('should render a title/description/edited and update title/description/edited on update', () => {
@@ -84,196 +98,209 @@ describe('Issuable output', () => {
return axios
.waitForAll()
.then(() => {
- editedText = vm.$el.querySelector('.edited-text');
+ editedText = wrapper.find('.edited-text');
})
.then(() => {
expect(document.querySelector('title').innerText).toContain('this is a title (#1)');
- expect(vm.$el.querySelector('.title').innerHTML).toContain('<p>this is a title</p>');
- expect(vm.$el.querySelector('.md').innerHTML).toContain('<p>this is a description!</p>');
- expect(vm.$el.querySelector('.js-task-list-field').value).toContain(
+ expect(wrapper.find('.title').text()).toContain('this is a title');
+ expect(wrapper.find('.md').text()).toContain('this is a description!');
+ expect(wrapper.find('.js-task-list-field').element.value).toContain(
'this is a description',
);
- expect(formatText(editedText.innerText)).toMatch(/Edited[\s\S]+?by Some User/);
- expect(editedText.querySelector('.author-link').href).toMatch(/\/some_user$/);
- expect(editedText.querySelector('time')).toBeTruthy();
- expect(vm.state.lock_version).toEqual(1);
+ expect(formatText(editedText.text())).toMatch(/Edited[\s\S]+?by Some User/);
+ expect(editedText.find('.author-link').attributes('href')).toMatch(/\/some_user$/);
+ expect(editedText.find('time').text()).toBeTruthy();
+ expect(wrapper.vm.state.lock_version).toEqual(1);
})
.then(() => {
- vm.poll.makeRequest();
+ wrapper.vm.poll.makeRequest();
return axios.waitForAll();
})
.then(() => {
expect(document.querySelector('title').innerText).toContain('2 (#1)');
- expect(vm.$el.querySelector('.title').innerHTML).toContain('<p>2</p>');
- expect(vm.$el.querySelector('.md').innerHTML).toContain('<p>42</p>');
- expect(vm.$el.querySelector('.js-task-list-field').value).toContain('42');
- expect(vm.$el.querySelector('.edited-text')).toBeTruthy();
- expect(formatText(vm.$el.querySelector('.edited-text').innerText)).toMatch(
+ expect(wrapper.find('.title').text()).toContain('2');
+ expect(wrapper.find('.md').text()).toContain('42');
+ expect(wrapper.find('.js-task-list-field').element.value).toContain('42');
+ expect(wrapper.find('.edited-text').text()).toBeTruthy();
+ expect(formatText(wrapper.find('.edited-text').text())).toMatch(
/Edited[\s\S]+?by Other User/,
);
- expect(editedText.querySelector('.author-link').href).toMatch(/\/other_user$/);
- expect(editedText.querySelector('time')).toBeTruthy();
- expect(vm.state.lock_version).toEqual(2);
+ expect(editedText.find('.author-link').attributes('href')).toMatch(/\/other_user$/);
+ expect(editedText.find('time').text()).toBeTruthy();
+ expect(wrapper.vm.state.lock_version).toEqual(2);
});
});
it('shows actions if permissions are correct', () => {
- vm.showForm = true;
+ wrapper.vm.showForm = true;
- return vm.$nextTick().then(() => {
- expect(vm.$el.querySelector('.btn')).not.toBeNull();
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.contains('.markdown-selector')).toBe(true);
});
});
it('does not show actions if permissions are incorrect', () => {
- vm.showForm = true;
- vm.canUpdate = false;
+ wrapper.vm.showForm = true;
+ wrapper.setProps({ canUpdate: false });
- return vm.$nextTick().then(() => {
- expect(vm.$el.querySelector('.btn')).toBeNull();
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.contains('.markdown-selector')).toBe(false);
});
});
it('does not update formState if form is already open', () => {
- vm.updateAndShowForm();
+ wrapper.vm.updateAndShowForm();
- vm.state.titleText = 'testing 123';
+ wrapper.vm.state.titleText = 'testing 123';
- vm.updateAndShowForm();
+ wrapper.vm.updateAndShowForm();
- return vm.$nextTick().then(() => {
- expect(vm.store.formState.title).not.toBe('testing 123');
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.vm.store.formState.title).not.toBe('testing 123');
});
});
it('opens reCAPTCHA modal if update rejected as spam', () => {
let modal;
- jest.spyOn(vm.service, 'updateIssuable').mockResolvedValue({
+ jest.spyOn(wrapper.vm.service, 'updateIssuable').mockResolvedValue({
data: {
recaptcha_html: '<div class="g-recaptcha">recaptcha_html</div>',
},
});
- vm.canUpdate = true;
- vm.showForm = true;
+ wrapper.vm.canUpdate = true;
+ wrapper.vm.showForm = true;
- return vm
+ return wrapper.vm
.$nextTick()
.then(() => {
- vm.$refs.recaptchaModal.scriptSrc = '//scriptsrc';
- return vm.updateIssuable();
+ wrapper.vm.$refs.recaptchaModal.scriptSrc = '//scriptsrc';
+ return wrapper.vm.updateIssuable();
})
.then(() => {
- modal = vm.$el.querySelector('.js-recaptcha-modal');
-
- expect(modal.style.display).not.toEqual('none');
- expect(modal.querySelector('.g-recaptcha').textContent).toEqual('recaptcha_html');
+ modal = wrapper.find('.js-recaptcha-modal');
+ expect(modal.isVisible()).toBe(true);
+ expect(modal.find('.g-recaptcha').text()).toEqual('recaptcha_html');
expect(document.body.querySelector('.js-recaptcha-script').src).toMatch('//scriptsrc');
})
.then(() => {
- modal.querySelector('.close').click();
- return vm.$nextTick();
+ modal.find('.close').trigger('click');
+ return wrapper.vm.$nextTick();
})
.then(() => {
- expect(modal.style.display).toEqual('none');
+ expect(modal.isVisible()).toBe(false);
expect(document.body.querySelector('.js-recaptcha-script')).toBeNull();
});
});
+ describe('Pinned links propagated', () => {
+ it.each`
+ prop | value
+ ${'zoomMeetingUrl'} | ${zoomMeetingUrl}
+ ${'publishedIncidentUrl'} | ${publishedIncidentUrl}
+ `('sets the $prop correctly on underlying pinned links', ({ prop, value }) => {
+ expect(wrapper.vm[prop]).toEqual(value);
+ expect(wrapper.find(`[data-testid="${prop}"]`).attributes('href')).toBe(value);
+ });
+ });
+
describe('updateIssuable', () => {
it('fetches new data after update', () => {
- const updateStoreSpy = jest.spyOn(vm, 'updateStoreState');
- const getDataSpy = jest.spyOn(vm.service, 'getData');
- jest.spyOn(vm.service, 'updateIssuable').mockResolvedValue({
+ const updateStoreSpy = jest.spyOn(wrapper.vm, 'updateStoreState');
+ const getDataSpy = jest.spyOn(wrapper.vm.service, 'getData');
+ jest.spyOn(wrapper.vm.service, 'updateIssuable').mockResolvedValue({
data: { web_url: window.location.pathname },
});
- return vm.updateIssuable().then(() => {
+ return wrapper.vm.updateIssuable().then(() => {
expect(updateStoreSpy).toHaveBeenCalled();
expect(getDataSpy).toHaveBeenCalled();
});
});
it('correctly updates issuable data', () => {
- const spy = jest.spyOn(vm.service, 'updateIssuable').mockResolvedValue({
+ const spy = jest.spyOn(wrapper.vm.service, 'updateIssuable').mockResolvedValue({
data: { web_url: window.location.pathname },
});
- return vm.updateIssuable().then(() => {
- expect(spy).toHaveBeenCalledWith(vm.formState);
+ return wrapper.vm.updateIssuable().then(() => {
+ expect(spy).toHaveBeenCalledWith(wrapper.vm.formState);
expect(eventHub.$emit).toHaveBeenCalledWith('close.form');
});
});
it('does not redirect if issue has not moved', () => {
- jest.spyOn(vm.service, 'updateIssuable').mockResolvedValue({
+ jest.spyOn(wrapper.vm.service, 'updateIssuable').mockResolvedValue({
data: {
web_url: window.location.pathname,
- confidential: vm.isConfidential,
+ confidential: wrapper.vm.isConfidential,
},
});
- return vm.updateIssuable().then(() => {
+ return wrapper.vm.updateIssuable().then(() => {
expect(visitUrl).not.toHaveBeenCalled();
});
});
it('does not redirect if issue has not moved and user has switched tabs', () => {
- jest.spyOn(vm.service, 'updateIssuable').mockResolvedValue({
+ jest.spyOn(wrapper.vm.service, 'updateIssuable').mockResolvedValue({
data: {
web_url: '',
- confidential: vm.isConfidential,
+ confidential: wrapper.vm.isConfidential,
},
});
- return vm.updateIssuable().then(() => {
+ return wrapper.vm.updateIssuable().then(() => {
expect(visitUrl).not.toHaveBeenCalled();
});
});
it('redirects if returned web_url has changed', () => {
- jest.spyOn(vm.service, 'updateIssuable').mockResolvedValue({
+ jest.spyOn(wrapper.vm.service, 'updateIssuable').mockResolvedValue({
data: {
web_url: '/testing-issue-move',
- confidential: vm.isConfidential,
+ confidential: wrapper.vm.isConfidential,
},
});
- vm.updateIssuable();
+ wrapper.vm.updateIssuable();
- return vm.updateIssuable().then(() => {
+ return wrapper.vm.updateIssuable().then(() => {
expect(visitUrl).toHaveBeenCalledWith('/testing-issue-move');
});
});
describe('shows dialog when issue has unsaved changed', () => {
it('confirms on title change', () => {
- vm.showForm = true;
- vm.state.titleText = 'title has changed';
+ wrapper.vm.showForm = true;
+ wrapper.vm.state.titleText = 'title has changed';
const e = { returnValue: null };
- vm.handleBeforeUnloadEvent(e);
- return vm.$nextTick().then(() => {
+ wrapper.vm.handleBeforeUnloadEvent(e);
+
+ return wrapper.vm.$nextTick().then(() => {
expect(e.returnValue).not.toBeNull();
});
});
it('confirms on description change', () => {
- vm.showForm = true;
- vm.state.descriptionText = 'description has changed';
+ wrapper.vm.showForm = true;
+ wrapper.vm.state.descriptionText = 'description has changed';
const e = { returnValue: null };
- vm.handleBeforeUnloadEvent(e);
- return vm.$nextTick().then(() => {
+ wrapper.vm.handleBeforeUnloadEvent(e);
+
+ return wrapper.vm.$nextTick().then(() => {
expect(e.returnValue).not.toBeNull();
});
});
it('does nothing when nothing has changed', () => {
const e = { returnValue: null };
- vm.handleBeforeUnloadEvent(e);
- return vm.$nextTick().then(() => {
+ wrapper.vm.handleBeforeUnloadEvent(e);
+
+ return wrapper.vm.$nextTick().then(() => {
expect(e.returnValue).toBeNull();
});
});
@@ -281,8 +308,9 @@ describe('Issuable output', () => {
describe('error when updating', () => {
it('closes form on error', () => {
- jest.spyOn(vm.service, 'updateIssuable').mockRejectedValue();
- return vm.updateIssuable().then(() => {
+ jest.spyOn(wrapper.vm.service, 'updateIssuable').mockRejectedValue();
+
+ return wrapper.vm.updateIssuable().then(() => {
expect(eventHub.$emit).not.toHaveBeenCalledWith('close.form');
expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
`Error updating issue`,
@@ -291,12 +319,12 @@ describe('Issuable output', () => {
});
it('returns the correct error message for issuableType', () => {
- jest.spyOn(vm.service, 'updateIssuable').mockRejectedValue();
- vm.issuableType = 'merge request';
+ jest.spyOn(wrapper.vm.service, 'updateIssuable').mockRejectedValue();
+ wrapper.setProps({ issuableType: 'merge request' });
- return vm
+ return wrapper.vm
.$nextTick()
- .then(vm.updateIssuable)
+ .then(wrapper.vm.updateIssuable)
.then(() => {
expect(eventHub.$emit).not.toHaveBeenCalledWith('close.form');
expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
@@ -308,12 +336,12 @@ describe('Issuable output', () => {
it('shows error message from backend if exists', () => {
const msg = 'Custom error message from backend';
jest
- .spyOn(vm.service, 'updateIssuable')
+ .spyOn(wrapper.vm.service, 'updateIssuable')
.mockRejectedValue({ response: { data: { errors: [msg] } } });
- return vm.updateIssuable().then(() => {
+ return wrapper.vm.updateIssuable().then(() => {
expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
- `${vm.defaultErrorMessage}. ${msg}`,
+ `${wrapper.vm.defaultErrorMessage}. ${msg}`,
);
});
});
@@ -322,34 +350,34 @@ describe('Issuable output', () => {
describe('deleteIssuable', () => {
it('changes URL when deleted', () => {
- jest.spyOn(vm.service, 'deleteIssuable').mockResolvedValue({
+ jest.spyOn(wrapper.vm.service, 'deleteIssuable').mockResolvedValue({
data: {
web_url: '/test',
},
});
- return vm.deleteIssuable().then(() => {
+ return wrapper.vm.deleteIssuable().then(() => {
expect(visitUrl).toHaveBeenCalledWith('/test');
});
});
it('stops polling when deleting', () => {
- const spy = jest.spyOn(vm.poll, 'stop');
- jest.spyOn(vm.service, 'deleteIssuable').mockResolvedValue({
+ const spy = jest.spyOn(wrapper.vm.poll, 'stop');
+ jest.spyOn(wrapper.vm.service, 'deleteIssuable').mockResolvedValue({
data: {
web_url: '/test',
},
});
- return vm.deleteIssuable().then(() => {
+ return wrapper.vm.deleteIssuable().then(() => {
expect(spy).toHaveBeenCalledWith();
});
});
it('closes form on error', () => {
- jest.spyOn(vm.service, 'deleteIssuable').mockRejectedValue();
+ jest.spyOn(wrapper.vm.service, 'deleteIssuable').mockRejectedValue();
- return vm.deleteIssuable().then(() => {
+ return wrapper.vm.deleteIssuable().then(() => {
expect(eventHub.$emit).not.toHaveBeenCalledWith('close.form');
expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
'Error deleting issue',
@@ -360,23 +388,25 @@ describe('Issuable output', () => {
describe('updateAndShowForm', () => {
it('shows locked warning if form is open & data is different', () => {
- return vm
+ return wrapper.vm
.$nextTick()
.then(() => {
- vm.updateAndShowForm();
+ wrapper.vm.updateAndShowForm();
- vm.poll.makeRequest();
+ wrapper.vm.poll.makeRequest();
return new Promise(resolve => {
- vm.$watch('formState.lockedWarningVisible', value => {
- if (value) resolve();
+ wrapper.vm.$watch('formState.lockedWarningVisible', value => {
+ if (value) {
+ resolve();
+ }
});
});
})
.then(() => {
- expect(vm.formState.lockedWarningVisible).toEqual(true);
- expect(vm.formState.lock_version).toEqual(1);
- expect(vm.$el.querySelector('.alert')).not.toBeNull();
+ expect(wrapper.vm.formState.lockedWarningVisible).toEqual(true);
+ expect(wrapper.vm.formState.lock_version).toEqual(1);
+ expect(wrapper.contains('.alert')).toBe(true);
});
});
});
@@ -385,14 +415,14 @@ describe('Issuable output', () => {
let formSpy;
beforeEach(() => {
- formSpy = jest.spyOn(vm, 'updateAndShowForm');
+ formSpy = jest.spyOn(wrapper.vm, 'updateAndShowForm');
});
it('shows the form if template names request is successful', () => {
const mockData = [{ name: 'Bug' }];
mock.onGet('/issuable-templates-path').reply(() => Promise.resolve([200, mockData]));
- return vm.requestTemplatesAndShowForm().then(() => {
+ return wrapper.vm.requestTemplatesAndShowForm().then(() => {
expect(formSpy).toHaveBeenCalledWith(mockData);
});
});
@@ -402,7 +432,7 @@ describe('Issuable output', () => {
.onGet('/issuable-templates-path')
.reply(() => Promise.reject(new Error('something went wrong')));
- return vm.requestTemplatesAndShowForm().then(() => {
+ return wrapper.vm.requestTemplatesAndShowForm().then(() => {
expect(document.querySelector('.flash-container .flash-text').textContent).toContain(
'Error updating issue',
);
@@ -414,35 +444,39 @@ describe('Issuable output', () => {
describe('show inline edit button', () => {
it('should not render by default', () => {
- expect(vm.$el.querySelector('.title-container .note-action-button')).toBeDefined();
+ expect(wrapper.contains('.btn-edit')).toBe(true);
});
it('should render if showInlineEditButton', () => {
- vm.showInlineEditButton = true;
+ wrapper.setProps({ showInlineEditButton: true });
- expect(vm.$el.querySelector('.title-container .note-action-button')).toBeDefined();
+ return wrapper.vm.$nextTick(() => {
+ expect(wrapper.contains('.btn-edit')).toBe(true);
+ });
});
});
describe('updateStoreState', () => {
it('should make a request and update the state of the store', () => {
const data = { foo: 1 };
- const getDataSpy = jest.spyOn(vm.service, 'getData').mockResolvedValue({ data });
- const updateStateSpy = jest.spyOn(vm.store, 'updateState').mockImplementation(jest.fn);
+ const getDataSpy = jest.spyOn(wrapper.vm.service, 'getData').mockResolvedValue({ data });
+ const updateStateSpy = jest
+ .spyOn(wrapper.vm.store, 'updateState')
+ .mockImplementation(jest.fn);
- return vm.updateStoreState().then(() => {
+ return wrapper.vm.updateStoreState().then(() => {
expect(getDataSpy).toHaveBeenCalled();
expect(updateStateSpy).toHaveBeenCalledWith(data);
});
});
it('should show error message if store update fails', () => {
- jest.spyOn(vm.service, 'getData').mockRejectedValue();
- vm.issuableType = 'merge request';
+ jest.spyOn(wrapper.vm.service, 'getData').mockRejectedValue();
+ wrapper.setProps({ issuableType: 'merge request' });
- return vm.updateStoreState().then(() => {
+ return wrapper.vm.updateStoreState().then(() => {
expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
- `Error updating ${vm.issuableType}`,
+ `Error updating ${wrapper.vm.issuableType}`,
);
});
});
@@ -450,48 +484,85 @@ describe('Issuable output', () => {
describe('issueChanged', () => {
beforeEach(() => {
- vm.store.formState.title = '';
- vm.store.formState.description = '';
- vm.initialDescriptionText = '';
- vm.initialTitleText = '';
+ wrapper.vm.store.formState.title = '';
+ wrapper.vm.store.formState.description = '';
+ wrapper.setProps({
+ initialDescriptionText: '',
+ initialTitleText: '',
+ });
});
it('returns true when title is changed', () => {
- vm.store.formState.title = 'RandomText';
+ wrapper.vm.store.formState.title = 'RandomText';
- expect(vm.issueChanged).toBe(true);
+ expect(wrapper.vm.issueChanged).toBe(true);
});
it('returns false when title is empty null', () => {
- vm.store.formState.title = null;
+ wrapper.vm.store.formState.title = null;
- expect(vm.issueChanged).toBe(false);
+ expect(wrapper.vm.issueChanged).toBe(false);
});
it('returns false when `initialTitleText` is null and `formState.title` is empty string', () => {
- vm.store.formState.title = '';
- vm.initialTitleText = null;
+ wrapper.vm.store.formState.title = '';
+ wrapper.setProps({ initialTitleText: null });
- expect(vm.issueChanged).toBe(false);
+ expect(wrapper.vm.issueChanged).toBe(false);
});
it('returns true when description is changed', () => {
- vm.store.formState.description = 'RandomText';
+ wrapper.vm.store.formState.description = 'RandomText';
- expect(vm.issueChanged).toBe(true);
+ expect(wrapper.vm.issueChanged).toBe(true);
});
it('returns false when description is empty null', () => {
- vm.store.formState.title = null;
+ wrapper.vm.store.formState.description = null;
- expect(vm.issueChanged).toBe(false);
+ expect(wrapper.vm.issueChanged).toBe(false);
});
it('returns false when `initialDescriptionText` is null and `formState.description` is empty string', () => {
- vm.store.formState.description = '';
- vm.initialDescriptionText = null;
+ wrapper.vm.store.formState.description = '';
+ wrapper.setProps({ initialDescriptionText: null });
- expect(vm.issueChanged).toBe(false);
+ expect(wrapper.vm.issueChanged).toBe(false);
+ });
+ });
+
+ describe('sticky header', () => {
+ describe('when title is in view', () => {
+ it('is not shown', () => {
+ expect(wrapper.contains('.issue-sticky-header')).toBe(false);
+ });
+ });
+
+ describe('when title is not in view', () => {
+ beforeEach(() => {
+ wrapper.vm.state.titleText = 'Sticky header title';
+ wrapper.find(GlIntersectionObserver).vm.$emit('disappear');
+ });
+
+ it('is shown with title', () => {
+ expect(findStickyHeader().text()).toContain('Sticky header title');
+ });
+
+ it('is shown with Open when status is opened', () => {
+ wrapper.setProps({ issuableStatus: 'opened' });
+
+ return wrapper.vm.$nextTick(() => {
+ expect(findStickyHeader().text()).toContain('Open');
+ });
+ });
+
+ it('is shown with Closed when status is closed', () => {
+ wrapper.setProps({ issuableStatus: 'closed' });
+
+ return wrapper.vm.$nextTick(() => {
+ expect(findStickyHeader().text()).toContain('Closed');
+ });
+ });
});
});
});
diff --git a/spec/frontend/issue_show/components/pinned_links_spec.js b/spec/frontend/issue_show/components/pinned_links_spec.js
index 59c919c85d5..007ad4c9a1b 100644
--- a/spec/frontend/issue_show/components/pinned_links_spec.js
+++ b/spec/frontend/issue_show/components/pinned_links_spec.js
@@ -3,23 +3,18 @@ import { GlLink } from '@gitlab/ui';
import PinnedLinks from '~/issue_show/components/pinned_links.vue';
const plainZoomUrl = 'https://zoom.us/j/123456789';
+const plainStatusUrl = 'https://status.com';
describe('PinnedLinks', () => {
let wrapper;
- const link = {
- get text() {
- return wrapper.find(GlLink).text();
- },
- get href() {
- return wrapper.find(GlLink).attributes('href');
- },
- };
+ const findLinks = () => wrapper.findAll(GlLink);
const createComponent = props => {
wrapper = shallowMount(PinnedLinks, {
propsData: {
- zoomMeetingUrl: null,
+ zoomMeetingUrl: '',
+ publishedIncidentUrl: '',
...props,
},
});
@@ -30,12 +25,29 @@ describe('PinnedLinks', () => {
zoomMeetingUrl: `<a href="${plainZoomUrl}">Zoom</a>`,
});
- expect(link.text).toBe('Join Zoom meeting');
+ expect(
+ findLinks()
+ .at(0)
+ .text(),
+ ).toBe('Join Zoom meeting');
+ });
+
+ it('displays Status link', () => {
+ createComponent({
+ publishedIncidentUrl: `<a href="${plainStatusUrl}">Status</a>`,
+ });
+
+ expect(
+ findLinks()
+ .at(0)
+ .text(),
+ ).toBe('Published on status page');
});
it('does not render if there are no links', () => {
createComponent({
- zoomMeetingUrl: null,
+ zoomMeetingUrl: '',
+ publishedIncidentUrl: '',
});
expect(wrapper.find(GlLink).exists()).toBe(false);
diff --git a/spec/frontend/jira_import/components/jira_import_app_spec.js b/spec/frontend/jira_import/components/jira_import_app_spec.js
index 0040e71c192..a21b89f6517 100644
--- a/spec/frontend/jira_import/components/jira_import_app_spec.js
+++ b/spec/frontend/jira_import/components/jira_import_app_spec.js
@@ -6,14 +6,13 @@ import JiraImportForm from '~/jira_import/components/jira_import_form.vue';
import JiraImportProgress from '~/jira_import/components/jira_import_progress.vue';
import JiraImportSetup from '~/jira_import/components/jira_import_setup.vue';
import initiateJiraImportMutation from '~/jira_import/queries/initiate_jira_import.mutation.graphql';
-import { IMPORT_STATE } from '~/jira_import/utils';
const mountComponent = ({
isJiraConfigured = true,
errorMessage = '',
selectedProject = 'MTG',
showAlert = false,
- status = IMPORT_STATE.NONE,
+ isInProgress = false,
loading = false,
mutate = jest.fn(() => Promise.resolve()),
mountType,
@@ -22,14 +21,9 @@ const mountComponent = ({
return mountFunction(JiraImportApp, {
propsData: {
- isJiraConfigured,
inProgressIllustration: 'in-progress-illustration.svg',
+ isJiraConfigured,
issuesPath: 'gitlab-org/gitlab-test/-/issues',
- jiraProjects: [
- ['My Jira Project', 'MJP'],
- ['My Second Jira Project', 'MSJP'],
- ['Migrate to GitLab', 'MTG'],
- ],
jiraIntegrationPath: 'gitlab-org/gitlab-test/-/services/jira/edit',
projectPath: 'gitlab-org/gitlab-test',
setupIllustration: 'setup-illustration.svg',
@@ -40,7 +34,7 @@ const mountComponent = ({
showAlert,
selectedProject,
jiraImportDetails: {
- status,
+ isInProgress,
imports: [
{
jiraProjectKey: 'MTG',
@@ -64,6 +58,18 @@ const mountComponent = ({
},
},
],
+ mostRecentImport: {
+ jiraProjectKey: 'MTG',
+ scheduledAt: '2020-04-09T16:17:18+00:00',
+ scheduledBy: {
+ name: 'Jane Doe',
+ },
+ },
+ projects: [
+ { text: 'My Jira Project (MJP)', value: 'MJP' },
+ { text: 'My Second Jira Project (MSJP)', value: 'MSJP' },
+ { text: 'Migrate to GitLab (MTG)', value: 'MTG' },
+ ],
},
};
},
@@ -140,7 +146,7 @@ describe('JiraImportApp', () => {
describe('when Jira integration is configured but import is in progress', () => {
beforeEach(() => {
- wrapper = mountComponent({ status: IMPORT_STATE.SCHEDULED });
+ wrapper = mountComponent({ isInProgress: true });
});
it('does not show the "Set up Jira integration" screen', () => {
@@ -184,7 +190,7 @@ describe('JiraImportApp', () => {
describe('import in progress screen', () => {
beforeEach(() => {
- wrapper = mountComponent({ status: IMPORT_STATE.SCHEDULED });
+ wrapper = mountComponent({ isInProgress: true });
});
it('shows the illustration', () => {
diff --git a/spec/frontend/jira_import/mock_data.js b/spec/frontend/jira_import/mock_data.js
new file mode 100644
index 00000000000..e82ab53cb6f
--- /dev/null
+++ b/spec/frontend/jira_import/mock_data.js
@@ -0,0 +1,72 @@
+import getJiraImportDetailsQuery from '~/jira_import/queries/get_jira_import_details.query.graphql';
+import { IMPORT_STATE } from '~/jira_import/utils/jira_import_utils';
+
+export const fullPath = 'gitlab-org/gitlab-test';
+
+export const queryDetails = {
+ query: getJiraImportDetailsQuery,
+ variables: {
+ fullPath,
+ },
+};
+
+export const jiraImportDetailsQueryResponse = {
+ project: {
+ jiraImportStatus: IMPORT_STATE.NONE,
+ jiraImports: {
+ nodes: [
+ {
+ jiraProjectKey: 'MJP',
+ scheduledAt: '2020-01-01T12:34:56Z',
+ scheduledBy: {
+ name: 'Jane Doe',
+ __typename: 'User',
+ },
+ __typename: 'JiraImport',
+ },
+ ],
+ __typename: 'JiraImportConnection',
+ },
+ services: {
+ nodes: [
+ {
+ projects: {
+ nodes: [
+ {
+ key: 'MJP',
+ name: 'My Jira Project',
+ __typename: 'JiraProject',
+ },
+ {
+ key: 'MTG',
+ name: 'Migrate To GitLab',
+ __typename: 'JiraProject',
+ },
+ ],
+ __typename: 'JiraProjectConnection',
+ },
+ __typename: 'JiraService',
+ },
+ ],
+ __typename: 'ServiceConnection',
+ },
+ __typename: 'Project',
+ },
+};
+
+export const jiraImportMutationResponse = {
+ jiraImportStart: {
+ clientMutationId: null,
+ jiraImport: {
+ jiraProjectKey: 'MTG',
+ scheduledAt: '2020-02-02T20:20:20Z',
+ scheduledBy: {
+ name: 'John Doe',
+ __typename: 'User',
+ },
+ __typename: 'JiraImport',
+ },
+ errors: [],
+ __typename: 'JiraImportStartPayload',
+ },
+};
diff --git a/spec/frontend/jira_import/utils/cache_update_spec.js b/spec/frontend/jira_import/utils/cache_update_spec.js
new file mode 100644
index 00000000000..4812510f9b8
--- /dev/null
+++ b/spec/frontend/jira_import/utils/cache_update_spec.js
@@ -0,0 +1,64 @@
+import { addInProgressImportToStore } from '~/jira_import/utils/cache_update';
+import { IMPORT_STATE } from '~/jira_import/utils/jira_import_utils';
+import {
+ fullPath,
+ queryDetails,
+ jiraImportDetailsQueryResponse,
+ jiraImportMutationResponse,
+} from '../mock_data';
+
+describe('addInProgressImportToStore', () => {
+ const store = {
+ readQuery: jest.fn(() => jiraImportDetailsQueryResponse),
+ writeQuery: jest.fn(),
+ };
+
+ describe('when updating the cache', () => {
+ beforeEach(() => {
+ addInProgressImportToStore(store, jiraImportMutationResponse.jiraImportStart, fullPath);
+ });
+
+ it('reads the cache with the correct query', () => {
+ expect(store.readQuery).toHaveBeenCalledWith(queryDetails);
+ });
+
+ it('writes to the cache with the expected arguments', () => {
+ const expected = {
+ ...queryDetails,
+ data: {
+ project: {
+ ...jiraImportDetailsQueryResponse.project,
+ jiraImportStatus: IMPORT_STATE.SCHEDULED,
+ jiraImports: {
+ ...jiraImportDetailsQueryResponse.project.jiraImports,
+ nodes: jiraImportDetailsQueryResponse.project.jiraImports.nodes.concat(
+ jiraImportMutationResponse.jiraImportStart.jiraImport,
+ ),
+ },
+ },
+ },
+ };
+
+ expect(store.writeQuery).toHaveBeenCalledWith(expected);
+ });
+ });
+
+ describe('when there are errors', () => {
+ beforeEach(() => {
+ const jiraImportStart = {
+ ...jiraImportMutationResponse.jiraImportStart,
+ errors: ['There was an error'],
+ };
+
+ addInProgressImportToStore(store, jiraImportStart, fullPath);
+ });
+
+ it('does not read from the store', () => {
+ expect(store.readQuery).not.toHaveBeenCalled();
+ });
+
+ it('does not write to the store', () => {
+ expect(store.writeQuery).not.toHaveBeenCalled();
+ });
+ });
+});
diff --git a/spec/frontend/jira_import/utils/jira_import_utils_spec.js b/spec/frontend/jira_import/utils/jira_import_utils_spec.js
new file mode 100644
index 00000000000..504d399217a
--- /dev/null
+++ b/spec/frontend/jira_import/utils/jira_import_utils_spec.js
@@ -0,0 +1,91 @@
+import {
+ calculateJiraImportLabel,
+ extractJiraProjectsOptions,
+ IMPORT_STATE,
+ isFinished,
+ isInProgress,
+} from '~/jira_import/utils/jira_import_utils';
+
+describe('isInProgress', () => {
+ it.each`
+ state | result
+ ${IMPORT_STATE.SCHEDULED} | ${true}
+ ${IMPORT_STATE.STARTED} | ${true}
+ ${IMPORT_STATE.FAILED} | ${false}
+ ${IMPORT_STATE.FINISHED} | ${false}
+ ${IMPORT_STATE.NONE} | ${false}
+ ${undefined} | ${false}
+ `('returns $result when state is $state', ({ state, result }) => {
+ expect(isInProgress(state)).toBe(result);
+ });
+});
+
+describe('isFinished', () => {
+ it.each`
+ state | result
+ ${IMPORT_STATE.SCHEDULED} | ${false}
+ ${IMPORT_STATE.STARTED} | ${false}
+ ${IMPORT_STATE.FAILED} | ${false}
+ ${IMPORT_STATE.FINISHED} | ${true}
+ ${IMPORT_STATE.NONE} | ${false}
+ ${undefined} | ${false}
+ `('returns $result when state is $state', ({ state, result }) => {
+ expect(isFinished(state)).toBe(result);
+ });
+});
+
+describe('extractJiraProjectsOptions', () => {
+ const jiraProjects = [
+ {
+ key: 'MJP',
+ name: 'My Jira project',
+ },
+ {
+ key: 'MTG',
+ name: 'Migrate to GitLab',
+ },
+ ];
+
+ const expected = [
+ {
+ text: 'My Jira project (MJP)',
+ value: 'MJP',
+ },
+ {
+ text: 'Migrate to GitLab (MTG)',
+ value: 'MTG',
+ },
+ ];
+
+ it('returns a list of Jira projects in a format suitable for GlFormSelect', () => {
+ expect(extractJiraProjectsOptions(jiraProjects)).toEqual(expected);
+ });
+});
+
+describe('calculateJiraImportLabel', () => {
+ const jiraImports = [
+ { jiraProjectKey: 'MTG' },
+ { jiraProjectKey: 'MJP' },
+ { jiraProjectKey: 'MTG' },
+ { jiraProjectKey: 'MSJP' },
+ { jiraProjectKey: 'MTG' },
+ ];
+
+ const labels = [
+ { color: '#111', title: 'jira-import::MTG-1' },
+ { color: '#222', title: 'jira-import::MTG-2' },
+ { color: '#333', title: 'jira-import::MTG-3' },
+ ];
+
+ it('returns a label with the Jira project key and correct import count in the title', () => {
+ const label = calculateJiraImportLabel(jiraImports, labels);
+
+ expect(label.title).toBe('jira-import::MTG-3');
+ });
+
+ it('returns a label with the correct color', () => {
+ const label = calculateJiraImportLabel(jiraImports, labels);
+
+ expect(label.color).toBe('#333');
+ });
+});
diff --git a/spec/frontend/jira_import/utils_spec.js b/spec/frontend/jira_import/utils_spec.js
deleted file mode 100644
index 0b1edd6550a..00000000000
--- a/spec/frontend/jira_import/utils_spec.js
+++ /dev/null
@@ -1,62 +0,0 @@
-import {
- calculateJiraImportLabel,
- IMPORT_STATE,
- isFinished,
- isInProgress,
-} from '~/jira_import/utils';
-
-describe('isInProgress', () => {
- it.each`
- state | result
- ${IMPORT_STATE.SCHEDULED} | ${true}
- ${IMPORT_STATE.STARTED} | ${true}
- ${IMPORT_STATE.FAILED} | ${false}
- ${IMPORT_STATE.FINISHED} | ${false}
- ${IMPORT_STATE.NONE} | ${false}
- ${undefined} | ${false}
- `('returns $result when state is $state', ({ state, result }) => {
- expect(isInProgress(state)).toBe(result);
- });
-});
-
-describe('isFinished', () => {
- it.each`
- state | result
- ${IMPORT_STATE.SCHEDULED} | ${false}
- ${IMPORT_STATE.STARTED} | ${false}
- ${IMPORT_STATE.FAILED} | ${false}
- ${IMPORT_STATE.FINISHED} | ${true}
- ${IMPORT_STATE.NONE} | ${false}
- ${undefined} | ${false}
- `('returns $result when state is $state', ({ state, result }) => {
- expect(isFinished(state)).toBe(result);
- });
-});
-
-describe('calculateJiraImportLabel', () => {
- const jiraImports = [
- { jiraProjectKey: 'MTG' },
- { jiraProjectKey: 'MJP' },
- { jiraProjectKey: 'MTG' },
- { jiraProjectKey: 'MSJP' },
- { jiraProjectKey: 'MTG' },
- ];
-
- const labels = [
- { color: '#111', title: 'jira-import::MTG-1' },
- { color: '#222', title: 'jira-import::MTG-2' },
- { color: '#333', title: 'jira-import::MTG-3' },
- ];
-
- it('returns a label with the Jira project key and correct import count in the title', () => {
- const label = calculateJiraImportLabel(jiraImports, labels);
-
- expect(label.title).toBe('jira-import::MTG-3');
- });
-
- it('returns a label with the correct color', () => {
- const label = calculateJiraImportLabel(jiraImports, labels);
-
- expect(label.color).toBe('#333');
- });
-});
diff --git a/spec/frontend/jobs/components/artifacts_block_spec.js b/spec/frontend/jobs/components/artifacts_block_spec.js
index 9cb56737f3e..11bd645916e 100644
--- a/spec/frontend/jobs/components/artifacts_block_spec.js
+++ b/spec/frontend/jobs/components/artifacts_block_spec.js
@@ -1,20 +1,32 @@
-import Vue from 'vue';
+import { mount } from '@vue/test-utils';
import { getTimeago } from '~/lib/utils/datetime_utility';
-import component from '~/jobs/components/artifacts_block.vue';
-import mountComponent from '../../helpers/vue_mount_component_helper';
+import ArtifactsBlock from '~/jobs/components/artifacts_block.vue';
import { trimText } from '../../helpers/text_helper';
describe('Artifacts block', () => {
- const Component = Vue.extend(component);
- let vm;
+ let wrapper;
+
+ const createWrapper = propsData =>
+ mount(ArtifactsBlock, {
+ propsData,
+ });
+
+ const findArtifactRemoveElt = () => wrapper.find('[data-testid="artifacts-remove-timeline"]');
+ const findJobLockedElt = () => wrapper.find('[data-testid="job-locked-message"]');
+ const findKeepBtn = () => wrapper.find('[data-testid="keep-artifacts"]');
+ const findDownloadBtn = () => wrapper.find('[data-testid="download-artifacts"]');
+ const findBrowseBtn = () => wrapper.find('[data-testid="browse-artifacts"]');
const expireAt = '2018-08-14T09:38:49.157Z';
const timeago = getTimeago();
const formattedDate = timeago.format(expireAt);
+ const lockedText =
+ 'These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available.';
const expiredArtifact = {
expire_at: expireAt,
expired: true,
+ locked: false,
};
const nonExpiredArtifact = {
@@ -23,97 +35,127 @@ describe('Artifacts block', () => {
keep_path: '/gitlab-org/gitlab-foss/-/jobs/98314558/artifacts/keep',
expire_at: expireAt,
expired: false,
+ locked: false,
+ };
+
+ const lockedExpiredArtifact = {
+ ...expiredArtifact,
+ download_path: '/gitlab-org/gitlab-foss/-/jobs/98314558/artifacts/download',
+ browse_path: '/gitlab-org/gitlab-foss/-/jobs/98314558/artifacts/browse',
+ expired: true,
+ locked: true,
+ };
+
+ const lockedNonExpiredArtifact = {
+ ...nonExpiredArtifact,
+ keep_path: undefined,
+ locked: true,
};
afterEach(() => {
- vm.$destroy();
+ wrapper.destroy();
+ wrapper = null;
});
- describe('with expired artifacts', () => {
- it('renders expired artifact date and info', () => {
- vm = mountComponent(Component, {
+ describe('with expired artifacts that are not locked', () => {
+ beforeEach(() => {
+ wrapper = createWrapper({
artifact: expiredArtifact,
});
+ });
- expect(vm.$el.querySelector('.js-artifacts-removed')).not.toBeNull();
- expect(vm.$el.querySelector('.js-artifacts-will-be-removed')).toBeNull();
- expect(trimText(vm.$el.querySelector('.js-artifacts-removed').textContent)).toEqual(
+ it('renders expired artifact date and info', () => {
+ expect(trimText(findArtifactRemoveElt().text())).toBe(
`The artifacts were removed ${formattedDate}`,
);
});
+
+ it('does not show the keep button', () => {
+ expect(findKeepBtn().exists()).toBe(false);
+ });
+
+ it('does not show the download button', () => {
+ expect(findDownloadBtn().exists()).toBe(false);
+ });
+
+ it('does not show the browse button', () => {
+ expect(findBrowseBtn().exists()).toBe(false);
+ });
});
describe('with artifacts that will expire', () => {
- it('renders will expire artifact date and info', () => {
- vm = mountComponent(Component, {
+ beforeEach(() => {
+ wrapper = createWrapper({
artifact: nonExpiredArtifact,
});
+ });
- expect(vm.$el.querySelector('.js-artifacts-removed')).toBeNull();
- expect(vm.$el.querySelector('.js-artifacts-will-be-removed')).not.toBeNull();
- expect(trimText(vm.$el.querySelector('.js-artifacts-will-be-removed').textContent)).toEqual(
+ it('renders will expire artifact date and info', () => {
+ expect(trimText(findArtifactRemoveElt().text())).toBe(
`The artifacts will be removed ${formattedDate}`,
);
});
- });
- describe('with keep path', () => {
it('renders the keep button', () => {
- vm = mountComponent(Component, {
- artifact: nonExpiredArtifact,
- });
-
- expect(vm.$el.querySelector('.js-keep-artifacts')).not.toBeNull();
+ expect(findKeepBtn().exists()).toBe(true);
});
- });
- describe('without keep path', () => {
- it('does not render the keep button', () => {
- vm = mountComponent(Component, {
- artifact: expiredArtifact,
- });
+ it('renders the download button', () => {
+ expect(findDownloadBtn().exists()).toBe(true);
+ });
- expect(vm.$el.querySelector('.js-keep-artifacts')).toBeNull();
+ it('renders the browse button', () => {
+ expect(findBrowseBtn().exists()).toBe(true);
});
});
- describe('with download path', () => {
- it('renders the download button', () => {
- vm = mountComponent(Component, {
- artifact: nonExpiredArtifact,
+ describe('with expired locked artifacts', () => {
+ beforeEach(() => {
+ wrapper = createWrapper({
+ artifact: lockedExpiredArtifact,
});
+ });
- expect(vm.$el.querySelector('.js-download-artifacts')).not.toBeNull();
+ it('renders the information that the artefacts are locked', () => {
+ expect(findArtifactRemoveElt().exists()).toBe(false);
+ expect(trimText(findJobLockedElt().text())).toBe(lockedText);
});
- });
- describe('without download path', () => {
it('does not render the keep button', () => {
- vm = mountComponent(Component, {
- artifact: expiredArtifact,
- });
+ expect(findKeepBtn().exists()).toBe(false);
+ });
- expect(vm.$el.querySelector('.js-download-artifacts')).toBeNull();
+ it('renders the download button', () => {
+ expect(findDownloadBtn().exists()).toBe(true);
+ });
+
+ it('renders the browse button', () => {
+ expect(findBrowseBtn().exists()).toBe(true);
});
});
- describe('with browse path', () => {
- it('does not render the browse button', () => {
- vm = mountComponent(Component, {
- artifact: nonExpiredArtifact,
+ describe('with non expired locked artifacts', () => {
+ beforeEach(() => {
+ wrapper = createWrapper({
+ artifact: lockedNonExpiredArtifact,
});
+ });
- expect(vm.$el.querySelector('.js-browse-artifacts')).not.toBeNull();
+ it('renders the information that the artefacts are locked', () => {
+ expect(findArtifactRemoveElt().exists()).toBe(false);
+ expect(trimText(findJobLockedElt().text())).toBe(lockedText);
});
- });
- describe('without browse path', () => {
- it('does not render the browse button', () => {
- vm = mountComponent(Component, {
- artifact: expiredArtifact,
- });
+ it('does not render the keep button', () => {
+ expect(findKeepBtn().exists()).toBe(false);
+ });
+
+ it('renders the download button', () => {
+ expect(findDownloadBtn().exists()).toBe(true);
+ });
- expect(vm.$el.querySelector('.js-browse-artifacts')).toBeNull();
+ it('renders the browse button', () => {
+ expect(findBrowseBtn().exists()).toBe(true);
});
});
});
diff --git a/spec/frontend/jobs/components/job_log_spec.js b/spec/frontend/jobs/components/job_log_spec.js
index 2bb1e0af3a2..a167fe8a134 100644
--- a/spec/frontend/jobs/components/job_log_spec.js
+++ b/spec/frontend/jobs/components/job_log_spec.js
@@ -10,7 +10,7 @@ describe('Job Log', () => {
let vm;
const trace =
- '<span>Running with gitlab-runner 12.1.0 (de7731dd)<br/></span><span> on docker-auto-scale-com d5ae8d25<br/></span><div class="append-right-8" data-timestamp="1565502765" data-section="prepare-executor" role="button"></div><span class="section section-header js-s-prepare-executor">Using Docker executor with image ruby:2.6 ...<br/></span>';
+ '<span>Running with gitlab-runner 12.1.0 (de7731dd)<br/></span><span> on docker-auto-scale-com d5ae8d25<br/></span><div class="gl-mr-3" data-timestamp="1565502765" data-section="prepare-executor" role="button"></div><span class="section section-header js-s-prepare-executor">Using Docker executor with image ruby:2.6 ...<br/></span>';
beforeEach(() => {
store = createStore();
diff --git a/spec/frontend/jobs/components/log/mock_data.js b/spec/frontend/jobs/components/log/mock_data.js
index d92c009756a..a6a767f7921 100644
--- a/spec/frontend/jobs/components/log/mock_data.js
+++ b/spec/frontend/jobs/components/log/mock_data.js
@@ -34,7 +34,7 @@ export const utilsMockData = [
content: [
{
text:
- 'Using Docker executor with image dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.6.5-golang-1.12-git-2.26-lfs-2.9-chrome-73.0-node-12.x-yarn-1.16-postgresql-9.6-graphicsmagick-1.3.34',
+ 'Using Docker executor with image dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.6.6-golang-1.14-git-2.27-lfs-2.9-chrome-83-node-12.x-yarn-1.21-postgresql-11-graphicsmagick-1.3.34',
},
],
section: 'prepare-executor',
diff --git a/spec/frontend/labels_issue_sidebar_spec.js b/spec/frontend/labels_issue_sidebar_spec.js
new file mode 100644
index 00000000000..fafefca94df
--- /dev/null
+++ b/spec/frontend/labels_issue_sidebar_spec.js
@@ -0,0 +1,99 @@
+/* eslint-disable no-new */
+
+import $ from 'jquery';
+import MockAdapter from 'axios-mock-adapter';
+import { shuffle } from 'lodash';
+import axios from '~/lib/utils/axios_utils';
+import IssuableContext from '~/issuable_context';
+import LabelsSelect from '~/labels_select';
+
+import '~/gl_dropdown';
+import 'select2';
+import '~/api';
+import '~/create_label';
+import '~/users_select';
+
+let saveLabelCount = 0;
+let mock;
+
+function testLabelClicks(labelOrder, done) {
+ $('.edit-link')
+ .get(0)
+ .click();
+
+ jest.runOnlyPendingTimers();
+
+ setImmediate(() => {
+ const labelsInDropdown = $('.dropdown-content a');
+
+ expect(labelsInDropdown.length).toBe(10);
+
+ const arrayOfLabels = labelsInDropdown.get();
+ const randomArrayOfLabels = shuffle(arrayOfLabels);
+ randomArrayOfLabels.forEach((label, i) => {
+ if (i < saveLabelCount) {
+ $(label).click();
+ }
+ });
+
+ $('.edit-link')
+ .get(0)
+ .click();
+
+ setImmediate(() => {
+ expect($('.sidebar-collapsed-icon').attr('data-original-title')).toBe(labelOrder);
+ done();
+ });
+ });
+}
+
+describe('Issue dropdown sidebar', () => {
+ preloadFixtures('static/issue_sidebar_label.html');
+
+ beforeEach(() => {
+ loadFixtures('static/issue_sidebar_label.html');
+
+ mock = new MockAdapter(axios);
+
+ new IssuableContext('{"id":1,"name":"Administrator","username":"root"}');
+ new LabelsSelect();
+
+ mock.onGet('/root/test/labels.json').reply(() => {
+ const labels = Array(10)
+ .fill()
+ .map((_val, i) => ({
+ id: i,
+ title: `test ${i}`,
+ color: '#5CB85C',
+ }));
+
+ return [200, labels];
+ });
+
+ mock.onPut('/root/test/issues/2.json').reply(() => {
+ const labels = Array(saveLabelCount)
+ .fill()
+ .map((_val, i) => ({
+ id: i,
+ title: `test ${i}`,
+ color: '#5CB85C',
+ }));
+
+ return [200, { labels }];
+ });
+ });
+
+ afterEach(() => {
+ mock.restore();
+ });
+
+ it('changes collapsed tooltip when changing labels when less than 5', done => {
+ saveLabelCount = 5;
+ testLabelClicks('test 0, test 1, test 2, test 3, test 4', done);
+ });
+
+ it('changes collapsed tooltip when changing labels when more than 5', done => {
+ saveLabelCount = 6;
+ testLabelClicks('test 0, test 1, test 2, test 3, test 4, and 1 more', done);
+ });
+});
diff --git a/spec/frontend/lazy_loader_spec.js b/spec/frontend/lazy_loader_spec.js
new file mode 100644
index 00000000000..79a49aedf37
--- /dev/null
+++ b/spec/frontend/lazy_loader_spec.js
@@ -0,0 +1,153 @@
+import { noop } from 'lodash';
+import LazyLoader from '~/lazy_loader';
+import { TEST_HOST } from 'helpers/test_constants';
+import waitForPromises from './helpers/wait_for_promises';
+import { useMockMutationObserver, useMockIntersectionObserver } from 'helpers/mock_dom_observer';
+
+const execImmediately = callback => {
+ callback();
+};
+
+const TEST_PATH = `${TEST_HOST}/img/testimg.png`;
+
+describe('LazyLoader', () => {
+ let lazyLoader = null;
+
+ const { trigger: triggerMutation } = useMockMutationObserver();
+ const { trigger: triggerIntersection } = useMockIntersectionObserver();
+
+ const triggerChildMutation = () => {
+ triggerMutation(document.body, { options: { childList: true, subtree: true } });
+ };
+
+ const triggerIntersectionWithRatio = img => {
+ triggerIntersection(img, { entry: { intersectionRatio: 0.1 } });
+ };
+
+ const createLazyLoadImage = () => {
+ const newImg = document.createElement('img');
+ newImg.className = 'lazy';
+ newImg.setAttribute('data-src', TEST_PATH);
+
+ document.body.appendChild(newImg);
+ triggerChildMutation();
+
+ return newImg;
+ };
+
+ const createImage = () => {
+ const newImg = document.createElement('img');
+ newImg.setAttribute('src', TEST_PATH);
+
+ document.body.appendChild(newImg);
+ triggerChildMutation();
+
+ return newImg;
+ };
+
+ beforeEach(() => {
+ jest.spyOn(window, 'requestAnimationFrame').mockImplementation(execImmediately);
+ jest.spyOn(window, 'requestIdleCallback').mockImplementation(execImmediately);
+ jest.spyOn(LazyLoader, 'loadImage');
+ });
+
+ afterEach(() => {
+ document.body.innerHTML = '';
+ });
+
+ describe.each`
+ hasIntersectionObserver | trigger
+ ${true} | ${triggerIntersectionWithRatio}
+ ${false} | ${noop}
+ `(
+ 'with hasIntersectionObserver=$hasIntersectionObserver',
+ ({ hasIntersectionObserver, trigger }) => {
+ let origIntersectionObserver;
+
+ beforeEach(() => {
+ origIntersectionObserver = global.IntersectionObserver;
+ global.IntersectionObserver = hasIntersectionObserver
+ ? global.IntersectionObserver
+ : undefined;
+
+ lazyLoader = new LazyLoader({
+ observerNode: 'foobar',
+ });
+ });
+
+ afterEach(() => {
+ global.IntersectionObserver = origIntersectionObserver;
+ lazyLoader.unregister();
+ });
+
+ it('determines intersection observer support', () => {
+ expect(LazyLoader.supportsIntersectionObserver()).toBe(hasIntersectionObserver);
+ });
+
+ it('should copy value from data-src to src for img 1', () => {
+ const img = createLazyLoadImage();
+
+ // Doing everything that happens normally in onload
+ lazyLoader.register();
+
+ trigger(img);
+
+ expect(LazyLoader.loadImage).toHaveBeenCalledWith(img);
+ expect(img.getAttribute('src')).toBe(TEST_PATH);
+ expect(img.getAttribute('data-src')).toBe(null);
+ expect(img).toHaveClass('js-lazy-loaded');
+ });
+
+ it('should lazy load dynamically added data-src images', async () => {
+ lazyLoader.register();
+
+ const newImg = createLazyLoadImage();
+
+ trigger(newImg);
+
+ await waitForPromises();
+
+ expect(LazyLoader.loadImage).toHaveBeenCalledWith(newImg);
+ expect(newImg.getAttribute('src')).toBe(TEST_PATH);
+ expect(newImg).toHaveClass('js-lazy-loaded');
+ });
+
+ it('should not alter normal images', () => {
+ const newImg = createImage();
+
+ lazyLoader.register();
+
+ expect(LazyLoader.loadImage).not.toHaveBeenCalled();
+ expect(newImg).not.toHaveClass('js-lazy-loaded');
+ });
+
+ it('should not load dynamically added pictures if content observer is turned off', async () => {
+ lazyLoader.register();
+ lazyLoader.stopContentObserver();
+
+ const newImg = createLazyLoadImage();
+
+ await waitForPromises();
+
+ expect(LazyLoader.loadImage).not.toHaveBeenCalledWith(newImg);
+ expect(newImg).not.toHaveClass('js-lazy-loaded');
+ });
+
+ it('should load dynamically added pictures if content observer is turned off and on again', async () => {
+ lazyLoader.register();
+ lazyLoader.stopContentObserver();
+ lazyLoader.startContentObserver();
+
+ const newImg = createLazyLoadImage();
+
+ trigger(newImg);
+
+ await waitForPromises();
+
+ expect(LazyLoader.loadImage).toHaveBeenCalledWith(newImg);
+ expect(newImg.getAttribute('src')).toBe(TEST_PATH);
+ expect(newImg).toHaveClass('js-lazy-loaded');
+ });
+ },
+ );
+});
diff --git a/spec/frontend/lib/utils/common_utils_spec.js b/spec/frontend/lib/utils/common_utils_spec.js
index c8dc90c9ace..f597255538c 100644
--- a/spec/frontend/lib/utils/common_utils_spec.js
+++ b/spec/frontend/lib/utils/common_utils_spec.js
@@ -1,4 +1,5 @@
import * as commonUtils from '~/lib/utils/common_utils';
+import $ from 'jquery';
describe('common_utils', () => {
describe('parseUrl', () => {
@@ -211,6 +212,59 @@ describe('common_utils', () => {
});
});
+ describe('scrollToElement*', () => {
+ let elem;
+ const windowHeight = 1000;
+ const elemTop = 100;
+
+ beforeEach(() => {
+ elem = document.createElement('div');
+ window.innerHeight = windowHeight;
+ jest.spyOn($.fn, 'animate');
+ jest.spyOn($.fn, 'offset').mockReturnValue({ top: elemTop });
+ });
+
+ afterEach(() => {
+ $.fn.animate.mockRestore();
+ $.fn.offset.mockRestore();
+ });
+
+ describe('scrollToElement', () => {
+ it('scrolls to element', () => {
+ commonUtils.scrollToElement(elem);
+ expect($.fn.animate).toHaveBeenCalledWith(
+ {
+ scrollTop: elemTop,
+ },
+ expect.any(Number),
+ );
+ });
+
+ it('scrolls to element with offset', () => {
+ const offset = 50;
+ commonUtils.scrollToElement(elem, { offset });
+ expect($.fn.animate).toHaveBeenCalledWith(
+ {
+ scrollTop: elemTop + offset,
+ },
+ expect.any(Number),
+ );
+ });
+ });
+
+ describe('scrollToElementWithContext', () => {
+ it('scrolls with context', () => {
+ commonUtils.scrollToElementWithContext();
+ expect($.fn.animate).toHaveBeenCalledWith(
+ {
+ scrollTop: elemTop - windowHeight * 0.1,
+ },
+ expect.any(Number),
+ );
+ });
+ });
+ });
+
describe('debounceByAnimationFrame', () => {
it('debounces a function to allow a maximum of one call per animation frame', done => {
const spy = jest.fn();
@@ -535,6 +589,7 @@ describe('common_utils', () => {
id: 1,
group_name: 'GitLab.org',
absolute_web_url: 'https://gitlab.com/gitlab-org/',
+ milestones: ['12.3', '12.4'],
},
objNested: {
project_name: 'GitLab CE',
@@ -545,6 +600,7 @@ describe('common_utils', () => {
frontend_framework: 'Vue',
database: 'PostgreSQL',
},
+ milestones: ['12.3', '12.4'],
},
},
convertObjectPropsToCamelCase: {
@@ -552,6 +608,7 @@ describe('common_utils', () => {
id: 1,
group_name: 'GitLab.org',
absolute_web_url: 'https://gitlab.com/gitlab-org/',
+ milestones: ['12.3', '12.4'],
},
objNested: {
project_name: 'GitLab CE',
@@ -562,6 +619,7 @@ describe('common_utils', () => {
frontend_framework: 'Vue',
database: 'PostgreSQL',
},
+ milestones: ['12.3', '12.4'],
},
},
convertObjectPropsToSnakeCase: {
@@ -569,6 +627,7 @@ describe('common_utils', () => {
id: 1,
groupName: 'GitLab.org',
absoluteWebUrl: 'https://gitlab.com/gitlab-org/',
+ milestones: ['12.3', '12.4'],
},
objNested: {
projectName: 'GitLab CE',
@@ -579,6 +638,7 @@ describe('common_utils', () => {
frontendFramework: 'Vue',
database: 'PostgreSQL',
},
+ milestones: ['12.3', '12.4'],
},
},
};
@@ -615,16 +675,19 @@ describe('common_utils', () => {
id_converted: 1,
group_name_converted: 'GitLab.org',
absolute_web_url_converted: 'https://gitlab.com/gitlab-org/',
+ milestones_converted: ['12.3', '12.4'],
},
convertObjectPropsToCamelCase: {
id: 1,
groupName: 'GitLab.org',
absoluteWebUrl: 'https://gitlab.com/gitlab-org/',
+ milestones: ['12.3', '12.4'],
},
convertObjectPropsToSnakeCase: {
id: 1,
group_name: 'GitLab.org',
absolute_web_url: 'https://gitlab.com/gitlab-org/',
+ milestones: ['12.3', '12.4'],
},
};
@@ -642,6 +705,7 @@ describe('common_utils', () => {
frontend_framework: 'Vue',
database: 'PostgreSQL',
},
+ milestones_converted: ['12.3', '12.4'],
},
convertObjectPropsToCamelCase: {
projectName: 'GitLab CE',
@@ -652,6 +716,7 @@ describe('common_utils', () => {
frontend_framework: 'Vue',
database: 'PostgreSQL',
},
+ milestones: ['12.3', '12.4'],
},
convertObjectPropsToSnakeCase: {
project_name: 'GitLab CE',
@@ -662,6 +727,7 @@ describe('common_utils', () => {
frontendFramework: 'Vue',
database: 'PostgreSQL',
},
+ milestones: ['12.3', '12.4'],
},
};
@@ -680,6 +746,7 @@ describe('common_utils', () => {
frontend_framework_converted: 'Vue',
database_converted: 'PostgreSQL',
},
+ milestones_converted: ['12.3', '12.4'],
},
convertObjectPropsToCamelCase: {
projectName: 'GitLab CE',
@@ -690,6 +757,7 @@ describe('common_utils', () => {
frontendFramework: 'Vue',
database: 'PostgreSQL',
},
+ milestones: ['12.3', '12.4'],
},
convertObjectPropsToSnakeCase: {
project_name: 'GitLab CE',
@@ -700,6 +768,7 @@ describe('common_utils', () => {
frontend_framework: 'Vue',
database: 'PostgreSQL',
},
+ milestones: ['12.3', '12.4'],
},
};
@@ -729,6 +798,7 @@ describe('common_utils', () => {
frontend_framework: 'Vue',
database: 'PostgreSQL',
},
+ milestones_converted: ['12.3', '12.4'],
},
convertObjectPropsToCamelCase: {
projectName: 'GitLab CE',
@@ -738,6 +808,7 @@ describe('common_utils', () => {
frontend_framework: 'Vue',
database: 'PostgreSQL',
},
+ milestones: ['12.3', '12.4'],
},
convertObjectPropsToSnakeCase: {
project_name: 'GitLab CE',
@@ -747,6 +818,7 @@ describe('common_utils', () => {
frontendFramework: 'Vue',
database: 'PostgreSQL',
},
+ milestones: ['12.3', '12.4'],
},
};
@@ -772,6 +844,7 @@ describe('common_utils', () => {
backend_converted: 'Ruby',
frontend_framework_converted: 'Vue',
},
+ milestones_converted: ['12.3', '12.4'],
},
convertObjectPropsToCamelCase: {
projectName: 'GitLab CE',
@@ -780,6 +853,7 @@ describe('common_utils', () => {
backend: 'Ruby',
frontendFramework: 'Vue',
},
+ milestones: ['12.3', '12.4'],
},
convertObjectPropsToSnakeCase: {
project_name: 'GitLab CE',
@@ -788,6 +862,7 @@ describe('common_utils', () => {
backend: 'Ruby',
frontend_framework: 'Vue',
},
+ milestones: ['12.3', '12.4'],
},
};
@@ -818,6 +893,7 @@ describe('common_utils', () => {
frontend_framework: 'Vue',
database: 'PostgreSQL',
},
+ milestones_converted: ['12.3', '12.4'],
},
convertObjectPropsToCamelCase: {
projectName: 'GitLab CE',
@@ -828,6 +904,7 @@ describe('common_utils', () => {
frontend_framework: 'Vue',
database: 'PostgreSQL',
},
+ milestones: ['12.3', '12.4'],
},
convertObjectPropsToSnakeCase: {
project_name: 'GitLab CE',
@@ -838,6 +915,7 @@ describe('common_utils', () => {
frontendFramework: 'Vue',
database: 'PostgreSQL',
},
+ milestones: ['12.3', '12.4'],
},
};
@@ -865,6 +943,7 @@ describe('common_utils', () => {
frontend_framework: 'Vue',
database_converted: 'PostgreSQL',
},
+ milestones_converted: ['12.3', '12.4'],
},
convertObjectPropsToCamelCase: {
projectName: 'GitLab CE',
@@ -875,6 +954,7 @@ describe('common_utils', () => {
frontend_framework: 'Vue',
database: 'PostgreSQL',
},
+ milestones: ['12.3', '12.4'],
},
convertObjectPropsToSnakeCase: {
project_name: 'GitLab CE',
@@ -885,6 +965,7 @@ describe('common_utils', () => {
frontendFramework: 'Vue',
database: 'PostgreSQL',
},
+ milestones: ['12.3', '12.4'],
},
};
diff --git a/spec/frontend/lib/utils/text_markdown_spec.js b/spec/frontend/lib/utils/text_markdown_spec.js
index 1d616a7da0b..aca299aea0f 100644
--- a/spec/frontend/lib/utils/text_markdown_spec.js
+++ b/spec/frontend/lib/utils/text_markdown_spec.js
@@ -25,13 +25,13 @@ describe('init markdown', () => {
insertMarkdownText({
textArea,
text: textArea.value,
- tag: '* ',
+ tag: '- ',
blockTag: null,
selected: '',
wrap: false,
});
- expect(textArea.value).toEqual(`${initialValue}* `);
+ expect(textArea.value).toEqual(`${initialValue}- `);
});
it('inserts the tag on a new line if the current one is not empty', () => {
@@ -43,13 +43,13 @@ describe('init markdown', () => {
insertMarkdownText({
textArea,
text: textArea.value,
- tag: '* ',
+ tag: '- ',
blockTag: null,
selected: '',
wrap: false,
});
- expect(textArea.value).toEqual(`${initialValue}\n* `);
+ expect(textArea.value).toEqual(`${initialValue}\n- `);
});
it('inserts the tag on the same line if the current line only contains spaces', () => {
@@ -61,13 +61,13 @@ describe('init markdown', () => {
insertMarkdownText({
textArea,
text: textArea.value,
- tag: '* ',
+ tag: '- ',
blockTag: null,
selected: '',
wrap: false,
});
- expect(textArea.value).toEqual(`${initialValue}* `);
+ expect(textArea.value).toEqual(`${initialValue}- `);
});
it('inserts the tag on the same line if the current line only contains tabs', () => {
@@ -79,13 +79,13 @@ describe('init markdown', () => {
insertMarkdownText({
textArea,
text: textArea.value,
- tag: '* ',
+ tag: '- ',
blockTag: null,
selected: '',
wrap: false,
});
- expect(textArea.value).toEqual(`${initialValue}* `);
+ expect(textArea.value).toEqual(`${initialValue}- `);
});
it('places the cursor inside the tags', () => {
diff --git a/spec/frontend/lib/utils/text_utility_spec.js b/spec/frontend/lib/utils/text_utility_spec.js
index 4969c591dcd..76e0e435860 100644
--- a/spec/frontend/lib/utils/text_utility_spec.js
+++ b/spec/frontend/lib/utils/text_utility_spec.js
@@ -126,6 +126,8 @@ describe('text_utility', () => {
${'snake case'} | ${'snake_case'}
${'snake_case'} | ${'snake_case'}
${'snakeCasesnake Case'} | ${'snake_casesnake_case'}
+ ${'123'} | ${'123'}
+ ${'123 456'} | ${'123_456'}
`('converts string $txt to $result string', ({ txt, result }) => {
expect(textUtils.convertToSnakeCase(txt)).toEqual(result);
});
@@ -190,6 +192,20 @@ describe('text_utility', () => {
'app/…/…/diff',
);
});
+
+ describe('given a path too long for the maxWidth', () => {
+ it.each`
+ path | maxWidth | result
+ ${'aa/bb/cc'} | ${1} | ${'…'}
+ ${'aa/bb/cc'} | ${2} | ${'…'}
+ ${'aa/bb/cc'} | ${3} | ${'…/…'}
+ ${'aa/bb/cc'} | ${4} | ${'…/…'}
+ ${'aa/bb/cc'} | ${5} | ${'…/…/…'}
+ `('truncates ($path, $maxWidth) to $result', ({ path, maxWidth, result }) => {
+ expect(result.length).toBeLessThanOrEqual(maxWidth);
+ expect(textUtils.truncatePathMiddleToLength(path, maxWidth)).toEqual(result);
+ });
+ });
});
describe('slugifyWithUnderscore', () => {
diff --git a/spec/frontend/lib/utils/url_utility_spec.js b/spec/frontend/lib/utils/url_utility_spec.js
index c494033badd..85e680fe216 100644
--- a/spec/frontend/lib/utils/url_utility_spec.js
+++ b/spec/frontend/lib/utils/url_utility_spec.js
@@ -371,6 +371,23 @@ describe('URL utility', () => {
});
});
+ describe('isBase64DataUrl', () => {
+ it.each`
+ url | valid
+ ${undefined} | ${false}
+ ${'http://gitlab.com'} | ${false}
+ ${'data:image/png;base64,abcdef'} | ${true}
+ ${'data:application/smil+xml;base64,abcdef'} | ${true}
+ ${'data:application/vnd.syncml+xml;base64,abcdef'} | ${true}
+ ${'data:application/vnd.3m.post-it-notes;base64,abcdef'} | ${true}
+ ${'notaurl'} | ${false}
+ ${'../relative_url'} | ${false}
+ ${'<a></a>'} | ${false}
+ `('returns $valid for $url', ({ url, valid }) => {
+ expect(urlUtils.isBase64DataUrl(url)).toBe(valid);
+ });
+ });
+
describe('relativePathToAbsolute', () => {
it.each`
path | base | result
diff --git a/spec/frontend/line_highlighter_spec.js b/spec/frontend/line_highlighter_spec.js
new file mode 100644
index 00000000000..0da1ea1df2d
--- /dev/null
+++ b/spec/frontend/line_highlighter_spec.js
@@ -0,0 +1,268 @@
+/* eslint-disable no-return-assign, no-new, no-underscore-dangle */
+
+import $ from 'jquery';
+import LineHighlighter from '~/line_highlighter';
+
+describe('LineHighlighter', () => {
+ const testContext = {};
+
+ preloadFixtures('static/line_highlighter.html');
+ const clickLine = (number, eventData = {}) => {
+ if ($.isEmptyObject(eventData)) {
+ return $(`#L${number}`).click();
+ }
+ const e = $.Event('click', eventData);
+ return $(`#L${number}`).trigger(e);
+ };
+ beforeEach(() => {
+ loadFixtures('static/line_highlighter.html');
+ testContext.class = new LineHighlighter();
+ testContext.css = testContext.class.highlightLineClass;
+ return (testContext.spies = {
+ __setLocationHash__: jest
+ .spyOn(testContext.class, '__setLocationHash__')
+ .mockImplementation(() => {}),
+ });
+ });
+
+ describe('behavior', () => {
+ it('highlights one line given in the URL hash', () => {
+ new LineHighlighter({ hash: '#L13' });
+
+ expect($('#LC13')).toHaveClass(testContext.css);
+ });
+
+ it('highlights one line given in the URL hash with given CSS class name', () => {
+ const hiliter = new LineHighlighter({ hash: '#L13', highlightLineClass: 'hilite' });
+
+ expect(hiliter.highlightLineClass).toBe('hilite');
+ expect($('#LC13')).toHaveClass('hilite');
+ expect($('#LC13')).not.toHaveClass('hll');
+ });
+
+ it('highlights a range of lines given in the URL hash', () => {
+ new LineHighlighter({ hash: '#L5-25' });
+
+ expect($(`.${testContext.css}`).length).toBe(21);
+ for (let line = 5; line <= 25; line += 1) {
+ expect($(`#LC${line}`)).toHaveClass(testContext.css);
+ }
+ });
+
+ it('scrolls to the first highlighted line on initial load', () => {
+ const spy = jest.spyOn($, 'scrollTo');
+ new LineHighlighter({ hash: '#L5-25' });
+
+ expect(spy).toHaveBeenCalledWith('#L5', expect.anything());
+ });
+
+ it('discards click events', () => {
+ const clickSpy = jest.fn();
+
+ $('a[data-line-number]').click(clickSpy);
+
+ clickLine(13);
+
+ expect(clickSpy.mock.calls[0][0].isDefaultPrevented()).toEqual(true);
+ });
+
+ it('handles garbage input from the hash', () => {
+ const func = () => {
+ return new LineHighlighter({ fileHolderSelector: '#blob-content-holder' });
+ };
+
+ expect(func).not.toThrow();
+ });
+
+ it('handles hashchange event', () => {
+ const highlighter = new LineHighlighter();
+
+ jest.spyOn(highlighter, 'highlightHash').mockImplementation(() => {});
+
+ window.dispatchEvent(new Event('hashchange'), 'L15');
+
+ expect(highlighter.highlightHash).toHaveBeenCalled();
+ });
+ });
+
+ describe('clickHandler', () => {
+ it('handles clicking on a child icon element', () => {
+ const spy = jest.spyOn(testContext.class, 'setHash');
+ $('#L13 i')
+ .mousedown()
+ .click();
+
+ expect(spy).toHaveBeenCalledWith(13);
+ expect($('#LC13')).toHaveClass(testContext.css);
+ });
+
+ describe('without shiftKey', () => {
+ it('highlights one line when clicked', () => {
+ clickLine(13);
+
+ expect($('#LC13')).toHaveClass(testContext.css);
+ });
+
+ it('unhighlights previously highlighted lines', () => {
+ clickLine(13);
+ clickLine(20);
+
+ expect($('#LC13')).not.toHaveClass(testContext.css);
+ expect($('#LC20')).toHaveClass(testContext.css);
+ });
+
+ it('sets the hash', () => {
+ const spy = jest.spyOn(testContext.class, 'setHash');
+ clickLine(13);
+
+ expect(spy).toHaveBeenCalledWith(13);
+ });
+ });
+
+ describe('with shiftKey', () => {
+ it('sets the hash', () => {
+ const spy = jest.spyOn(testContext.class, 'setHash');
+ clickLine(13);
+ clickLine(20, {
+ shiftKey: true,
+ });
+
+ expect(spy).toHaveBeenCalledWith(13);
+ expect(spy).toHaveBeenCalledWith(13, 20);
+ });
+
+ describe('without existing highlight', () => {
+ it('highlights the clicked line', () => {
+ clickLine(13, {
+ shiftKey: true,
+ });
+
+ expect($('#LC13')).toHaveClass(testContext.css);
+ expect($(`.${testContext.css}`).length).toBe(1);
+ });
+
+ it('sets the hash', () => {
+ const spy = jest.spyOn(testContext.class, 'setHash');
+ clickLine(13, {
+ shiftKey: true,
+ });
+
+ expect(spy).toHaveBeenCalledWith(13);
+ });
+ });
+
+ describe('with existing single-line highlight', () => {
+ it('uses existing line as last line when target is lesser', () => {
+ clickLine(20);
+ clickLine(15, {
+ shiftKey: true,
+ });
+
+ expect($(`.${testContext.css}`).length).toBe(6);
+ for (let line = 15; line <= 20; line += 1) {
+ expect($(`#LC${line}`)).toHaveClass(testContext.css);
+ }
+ });
+
+ it('uses existing line as first line when target is greater', () => {
+ clickLine(5);
+ clickLine(10, {
+ shiftKey: true,
+ });
+
+ expect($(`.${testContext.css}`).length).toBe(6);
+ for (let line = 5; line <= 10; line += 1) {
+ expect($(`#LC${line}`)).toHaveClass(testContext.css);
+ }
+ });
+ });
+
+ describe('with existing multi-line highlight', () => {
+ beforeEach(() => {
+ clickLine(10, {
+ shiftKey: true,
+ });
+ clickLine(13, {
+ shiftKey: true,
+ });
+ });
+
+ it('uses target as first line when it is less than existing first line', () => {
+ clickLine(5, {
+ shiftKey: true,
+ });
+
+ expect($(`.${testContext.css}`).length).toBe(6);
+ for (let line = 5; line <= 10; line += 1) {
+ expect($(`#LC${line}`)).toHaveClass(testContext.css);
+ }
+ });
+
+ it('uses target as last line when it is greater than existing first line', () => {
+ clickLine(15, {
+ shiftKey: true,
+ });
+
+ expect($(`.${testContext.css}`).length).toBe(6);
+ for (let line = 10; line <= 15; line += 1) {
+ expect($(`#LC${line}`)).toHaveClass(testContext.css);
+ }
+ });
+ });
+ });
+ });
+
+ describe('hashToRange', () => {
+ beforeEach(() => {
+ testContext.subject = testContext.class.hashToRange;
+ });
+
+ it('extracts a single line number from the hash', () => {
+ expect(testContext.subject('#L5')).toEqual([5, null]);
+ });
+
+ it('extracts a range of line numbers from the hash', () => {
+ expect(testContext.subject('#L5-15')).toEqual([5, 15]);
+ });
+
+ it('returns [null, null] when the hash is not a line number', () => {
+ expect(testContext.subject('#foo')).toEqual([null, null]);
+ });
+ });
+
+ describe('highlightLine', () => {
+ beforeEach(() => {
+ testContext.subject = testContext.class.highlightLine;
+ });
+
+ it('highlights the specified line', () => {
+ testContext.subject(13);
+
+ expect($('#LC13')).toHaveClass(testContext.css);
+ });
+
+ it('accepts a String-based number', () => {
+ testContext.subject('13');
+
+ expect($('#LC13')).toHaveClass(testContext.css);
+ });
+ });
+
+ describe('setHash', () => {
+ beforeEach(() => {
+ testContext.subject = testContext.class.setHash;
+ });
+
+ it('sets the location hash for a single line', () => {
+ testContext.subject(5);
+
+ expect(testContext.spies.__setLocationHash__).toHaveBeenCalledWith('#L5');
+ });
+
+ it('sets the location hash for a range', () => {
+ testContext.subject(5, 15);
+
+ expect(testContext.spies.__setLocationHash__).toHaveBeenCalledWith('#L5-15');
+ });
+ });
+});
diff --git a/spec/frontend/logs/components/environment_logs_spec.js b/spec/frontend/logs/components/environment_logs_spec.js
index 9046253bdc6..62f3e8a755d 100644
--- a/spec/frontend/logs/components/environment_logs_spec.js
+++ b/spec/frontend/logs/components/environment_logs_spec.js
@@ -301,11 +301,11 @@ describe('EnvironmentLogs', () => {
});
it('refresh button, trace is refreshed', () => {
- expect(dispatch).not.toHaveBeenCalledWith(`${module}/fetchLogs`, undefined);
+ expect(dispatch).not.toHaveBeenCalledWith(`${module}/refreshPodLogs`, undefined);
findLogControlButtons().vm.$emit('refresh');
- expect(dispatch).toHaveBeenCalledWith(`${module}/fetchLogs`, undefined);
+ expect(dispatch).toHaveBeenCalledWith(`${module}/refreshPodLogs`, undefined);
});
});
});
diff --git a/spec/frontend/logs/stores/actions_spec.js b/spec/frontend/logs/stores/actions_spec.js
index 6199c400e16..e2e3c3d23c6 100644
--- a/spec/frontend/logs/stores/actions_spec.js
+++ b/spec/frontend/logs/stores/actions_spec.js
@@ -1,6 +1,6 @@
import MockAdapter from 'axios-mock-adapter';
-
import testAction from 'helpers/vuex_action_helper';
+import Tracking from '~/tracking';
import * as types from '~/logs/stores/mutation_types';
import { convertToFixedRange } from '~/lib/utils/datetime_range';
import logsPageState from '~/logs/stores/state';
@@ -104,7 +104,7 @@ describe('Logs Store actions', () => {
{ type: types.SET_CURRENT_POD_NAME, payload: null },
{ type: types.SET_SEARCH, payload: '' },
],
- [{ type: 'fetchLogs' }],
+ [{ type: 'fetchLogs', payload: 'used_search_bar' }],
));
it('text search should filter with a search term', () =>
@@ -116,7 +116,7 @@ describe('Logs Store actions', () => {
{ type: types.SET_CURRENT_POD_NAME, payload: null },
{ type: types.SET_SEARCH, payload: mockSearch },
],
- [{ type: 'fetchLogs' }],
+ [{ type: 'fetchLogs', payload: 'used_search_bar' }],
));
it('pod search should filter with a search term', () =>
@@ -128,7 +128,7 @@ describe('Logs Store actions', () => {
{ type: types.SET_CURRENT_POD_NAME, payload: mockPodName },
{ type: types.SET_SEARCH, payload: '' },
],
- [{ type: 'fetchLogs' }],
+ [{ type: 'fetchLogs', payload: 'used_search_bar' }],
));
it('pod search should filter with a pod selection and a search term', () =>
@@ -140,7 +140,7 @@ describe('Logs Store actions', () => {
{ type: types.SET_CURRENT_POD_NAME, payload: mockPodName },
{ type: types.SET_SEARCH, payload: mockSearch },
],
- [{ type: 'fetchLogs' }],
+ [{ type: 'fetchLogs', payload: 'used_search_bar' }],
));
it('pod search should filter with a pod selection and two search terms', () =>
@@ -152,7 +152,7 @@ describe('Logs Store actions', () => {
{ type: types.SET_CURRENT_POD_NAME, payload: null },
{ type: types.SET_SEARCH, payload: `term1 term2` },
],
- [{ type: 'fetchLogs' }],
+ [{ type: 'fetchLogs', payload: 'used_search_bar' }],
));
it('pod search should filter with a pod selection and a search terms before and after', () =>
@@ -168,7 +168,7 @@ describe('Logs Store actions', () => {
{ type: types.SET_CURRENT_POD_NAME, payload: mockPodName },
{ type: types.SET_SEARCH, payload: `term1 term2` },
],
- [{ type: 'fetchLogs' }],
+ [{ type: 'fetchLogs', payload: 'used_search_bar' }],
));
});
@@ -179,7 +179,7 @@ describe('Logs Store actions', () => {
mockPodName,
state,
[{ type: types.SET_CURRENT_POD_NAME, payload: mockPodName }],
- [{ type: 'fetchLogs' }],
+ [{ type: 'fetchLogs', payload: 'pod_log_changed' }],
));
});
@@ -198,7 +198,7 @@ describe('Logs Store actions', () => {
{ type: types.REQUEST_ENVIRONMENTS_DATA },
{ type: types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS, payload: mockEnvironments },
],
- [{ type: 'fetchLogs' }],
+ [{ type: 'fetchLogs', payload: 'environment_selected' }],
);
});
@@ -471,3 +471,58 @@ describe('Logs Store actions', () => {
});
});
});
+
+describe('Tracking user interaction', () => {
+ let commit;
+ let dispatch;
+ let state;
+ let mock;
+
+ beforeEach(() => {
+ jest.spyOn(Tracking, 'event');
+ commit = jest.fn();
+ dispatch = jest.fn();
+ state = logsPageState();
+ state.environments.options = mockEnvironments;
+ state.environments.current = mockEnvName;
+
+ mock = new MockAdapter(axios);
+ });
+
+ afterEach(() => {
+ mock.reset();
+ });
+
+ describe('Logs with data', () => {
+ beforeEach(() => {
+ mock.onGet(mockLogsEndpoint).reply(200, mockResponse);
+ mock.onGet(mockLogsEndpoint).replyOnce(202); // mock reactive cache
+ });
+
+ it('tracks fetched logs with data', () => {
+ return fetchLogs({ state, commit, dispatch }, 'environment_selected').then(() => {
+ expect(Tracking.event).toHaveBeenCalledWith(document.body.dataset.page, 'logs_view', {
+ label: 'environment_selected',
+ property: 'count',
+ value: 1,
+ });
+ });
+ });
+ });
+
+ describe('Logs without data', () => {
+ beforeEach(() => {
+ mock.onGet(mockLogsEndpoint).reply(200, {
+ ...mockResponse,
+ logs: [],
+ });
+ mock.onGet(mockLogsEndpoint).replyOnce(202); // mock reactive cache
+ });
+
+ it('does not track empty log responses', () => {
+ return fetchLogs({ state, commit, dispatch }).then(() => {
+ expect(Tracking.event).not.toHaveBeenCalled();
+ });
+ });
+ });
+});
diff --git a/spec/frontend/matchers.js b/spec/frontend/matchers.js
index 35c362d0bf5..53c6a72eea0 100644
--- a/spec/frontend/matchers.js
+++ b/spec/frontend/matchers.js
@@ -35,4 +35,37 @@ export default {
message: () => message,
};
},
+ toMatchInterpolatedText(received, match) {
+ let clearReceived;
+ let clearMatch;
+
+ try {
+ clearReceived = received
+ .replace(/\s\s+/gm, ' ')
+ .replace(/\s\./gm, '.')
+ .trim();
+ } catch (e) {
+ return { actual: received, message: 'The received value is not a string', pass: false };
+ }
+ try {
+ clearMatch = match.replace(/%{\w+}/gm, '').trim();
+ } catch (e) {
+ return { message: 'The comparator value is not a string', pass: false };
+ }
+ const pass = clearReceived === clearMatch;
+ const message = pass
+ ? () => `
+ \n\n
+ Expected: ${this.utils.printExpected(clearReceived)}
+ To not equal: ${this.utils.printReceived(clearMatch)}
+ `
+ : () =>
+ `
+ \n\n
+ Expected: ${this.utils.printExpected(clearReceived)}
+ To equal: ${this.utils.printReceived(clearMatch)}
+ `;
+
+ return { actual: received, message, pass };
+ },
};
diff --git a/spec/frontend/matchers_spec.js b/spec/frontend/matchers_spec.js
new file mode 100644
index 00000000000..0a2478f978a
--- /dev/null
+++ b/spec/frontend/matchers_spec.js
@@ -0,0 +1,48 @@
+describe('Custom jest matchers', () => {
+ describe('toMatchInterpolatedText', () => {
+ describe('malformed input', () => {
+ it.each([null, 1, Symbol, Array, Object])(
+ 'fails graciously if the expected value is %s',
+ expected => {
+ expect(expected).not.toMatchInterpolatedText('null');
+ },
+ );
+ });
+ describe('malformed matcher', () => {
+ it.each([null, 1, Symbol, Array, Object])(
+ 'fails graciously if the matcher is %s',
+ matcher => {
+ expect('null').not.toMatchInterpolatedText(matcher);
+ },
+ );
+ });
+
+ describe('positive assertion', () => {
+ it.each`
+ htmlString | templateString
+ ${'foo'} | ${'foo'}
+ ${'foo'} | ${'foo%{foo}'}
+ ${'foo '} | ${'foo'}
+ ${'foo '} | ${'foo%{foo}'}
+ ${'foo . '} | ${'foo%{foo}.'}
+ ${'foo bar . '} | ${'foo%{foo} bar.'}
+ ${'foo\n\nbar . '} | ${'foo%{foo} bar.'}
+ ${'foo bar . .'} | ${'foo%{fooStart} bar.%{fooEnd}.'}
+ `('$htmlString equals $templateString', ({ htmlString, templateString }) => {
+ expect(htmlString).toMatchInterpolatedText(templateString);
+ });
+ });
+
+ describe('negative assertion', () => {
+ it.each`
+ htmlString | templateString
+ ${'foo'} | ${'bar'}
+ ${'foo'} | ${'bar%{foo}'}
+ ${'foo'} | ${'@{lol}foo%{foo}'}
+ ${' fo o '} | ${'foo'}
+ `('$htmlString does not equal $templateString', ({ htmlString, templateString }) => {
+ expect(htmlString).not.toMatchInterpolatedText(templateString);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/merge_request_spec.js b/spec/frontend/merge_request_spec.js
new file mode 100644
index 00000000000..f4f2a78f5f7
--- /dev/null
+++ b/spec/frontend/merge_request_spec.js
@@ -0,0 +1,191 @@
+import $ from 'jquery';
+import MockAdapter from 'axios-mock-adapter';
+import axios from '~/lib/utils/axios_utils';
+import MergeRequest from '~/merge_request';
+import CloseReopenReportToggle from '~/close_reopen_report_toggle';
+import IssuablesHelper from '~/helpers/issuables_helper';
+import { TEST_HOST } from 'spec/test_constants';
+
+describe('MergeRequest', () => {
+ const test = {};
+ describe('task lists', () => {
+ let mock;
+
+ preloadFixtures('merge_requests/merge_request_with_task_list.html');
+ beforeEach(() => {
+ loadFixtures('merge_requests/merge_request_with_task_list.html');
+
+ jest.spyOn(axios, 'patch');
+ mock = new MockAdapter(axios);
+
+ mock
+ .onPatch(`${TEST_HOST}/frontend-fixtures/merge-requests-project/-/merge_requests/1.json`)
+ .reply(200, {});
+
+ test.merge = new MergeRequest();
+ return test.merge;
+ });
+
+ afterEach(() => {
+ mock.restore();
+ });
+
+ it('modifies the Markdown field', done => {
+ jest.spyOn($, 'ajax').mockImplementation();
+ const changeEvent = document.createEvent('HTMLEvents');
+ changeEvent.initEvent('change', true, true);
+ $('input[type=checkbox]')
+ .first()
+ .attr('checked', true)[0]
+ .dispatchEvent(changeEvent);
+ setImmediate(() => {
+ expect($('.js-task-list-field').val()).toBe(
+ '- [x] Task List Item\n- [ ] \n- [ ] Task List Item 2\n',
+ );
+ done();
+ });
+ });
+
+ it('ensure that task with only spaces does not get checked incorrectly', done => {
+ // fixed in 'deckar01-task_list', '2.2.1' gem
+ jest.spyOn($, 'ajax').mockImplementation();
+ const changeEvent = document.createEvent('HTMLEvents');
+ changeEvent.initEvent('change', true, true);
+ $('input[type=checkbox]')
+ .last()
+ .attr('checked', true)[0]
+ .dispatchEvent(changeEvent);
+ setImmediate(() => {
+ expect($('.js-task-list-field').val()).toBe(
+ '- [ ] Task List Item\n- [ ] \n- [x] Task List Item 2\n',
+ );
+ done();
+ });
+ });
+
+ describe('tasklist', () => {
+ const lineNumber = 8;
+ const lineSource = '- [ ] item 8';
+ const index = 3;
+ const checked = true;
+
+ it('submits an ajax request on tasklist:changed', done => {
+ $('.js-task-list-field').trigger({
+ type: 'tasklist:changed',
+ detail: { lineNumber, lineSource, index, checked },
+ });
+
+ setImmediate(() => {
+ expect(axios.patch).toHaveBeenCalledWith(
+ `${TEST_HOST}/frontend-fixtures/merge-requests-project/-/merge_requests/1.json`,
+ {
+ merge_request: {
+ description: '- [ ] Task List Item\n- [ ] \n- [ ] Task List Item 2\n',
+ lock_version: 0,
+ update_task: { line_number: lineNumber, line_source: lineSource, index, checked },
+ },
+ },
+ );
+
+ done();
+ });
+ });
+
+ it('shows an error notification when tasklist update failed', done => {
+ mock
+ .onPatch(`${TEST_HOST}/frontend-fixtures/merge-requests-project/-/merge_requests/1.json`)
+ .reply(409, {});
+
+ $('.js-task-list-field').trigger({
+ type: 'tasklist:changed',
+ detail: { lineNumber, lineSource, index, checked },
+ });
+
+ setImmediate(() => {
+ expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
+ 'Someone edited this merge request at the same time you did. Please refresh the page to see changes.',
+ );
+
+ done();
+ });
+ });
+ });
+ });
+
+ describe('class constructor', () => {
+ beforeEach(() => {
+ jest.spyOn($, 'ajax').mockImplementation();
+ });
+
+ it('calls .initCloseReopenReport', () => {
+ jest.spyOn(IssuablesHelper, 'initCloseReopenReport').mockImplementation(() => {});
+
+ new MergeRequest(); // eslint-disable-line no-new
+
+ expect(IssuablesHelper.initCloseReopenReport).toHaveBeenCalled();
+ });
+
+ it('calls .initDroplab', () => {
+ const container = {
+ querySelector: jest.fn().mockName('container.querySelector'),
+ };
+ const dropdownTrigger = {};
+ const dropdownList = {};
+ const button = {};
+
+ jest.spyOn(CloseReopenReportToggle.prototype, 'initDroplab').mockImplementation(() => {});
+ jest.spyOn(document, 'querySelector').mockReturnValue(container);
+
+ container.querySelector
+ .mockReturnValueOnce(dropdownTrigger)
+ .mockReturnValueOnce(dropdownList)
+ .mockReturnValueOnce(button);
+
+ new MergeRequest(); // eslint-disable-line no-new
+
+ expect(document.querySelector).toHaveBeenCalledWith('.js-issuable-close-dropdown');
+ expect(container.querySelector).toHaveBeenCalledWith('.js-issuable-close-toggle');
+ expect(container.querySelector).toHaveBeenCalledWith('.js-issuable-close-menu');
+ expect(container.querySelector).toHaveBeenCalledWith('.js-issuable-close-button');
+ expect(CloseReopenReportToggle.prototype.initDroplab).toHaveBeenCalled();
+ });
+ });
+
+ describe('hideCloseButton', () => {
+ describe('merge request of another user', () => {
+ beforeEach(() => {
+ loadFixtures('merge_requests/merge_request_with_task_list.html');
+ test.el = document.querySelector('.js-issuable-actions');
+ new MergeRequest(); // eslint-disable-line no-new
+ MergeRequest.hideCloseButton();
+ });
+
+ it('hides the dropdown close item and selects the next item', () => {
+ const closeItem = test.el.querySelector('li.close-item');
+ const smallCloseItem = test.el.querySelector('.js-close-item');
+ const reportItem = test.el.querySelector('li.report-item');
+
+ expect(closeItem).toHaveClass('hidden');
+ expect(smallCloseItem).toHaveClass('hidden');
+ expect(reportItem).toHaveClass('droplab-item-selected');
+ expect(reportItem).not.toHaveClass('hidden');
+ });
+ });
+
+ describe('merge request of current_user', () => {
+ beforeEach(() => {
+ loadFixtures('merge_requests/merge_request_of_current_user.html');
+ test.el = document.querySelector('.js-issuable-actions');
+ MergeRequest.hideCloseButton();
+ });
+
+ it('hides the close button', () => {
+ const closeButton = test.el.querySelector('.btn-close');
+ const smallCloseItem = test.el.querySelector('.js-close-item');
+
+ expect(closeButton).toHaveClass('hidden');
+ expect(smallCloseItem).toHaveClass('hidden');
+ });
+ });
+ });
+});
diff --git a/spec/frontend/merge_request_tabs_spec.js b/spec/frontend/merge_request_tabs_spec.js
new file mode 100644
index 00000000000..3d3be647d12
--- /dev/null
+++ b/spec/frontend/merge_request_tabs_spec.js
@@ -0,0 +1,293 @@
+import $ from 'jquery';
+import MockAdapter from 'axios-mock-adapter';
+import axios from '~/lib/utils/axios_utils';
+import MergeRequestTabs from '~/merge_request_tabs';
+import '~/commit/pipelines/pipelines_bundle';
+import '~/lib/utils/common_utils';
+import 'vendor/jquery.scrollTo';
+import initMrPage from '../javascripts/helpers/init_vue_mr_page_helper';
+
+jest.mock('~/lib/utils/webpack', () => ({
+ resetServiceWorkersPublicPath: jest.fn(),
+}));
+
+describe('MergeRequestTabs', () => {
+ const testContext = {};
+ const stubLocation = {};
+ const setLocation = stubs => {
+ const defaults = {
+ pathname: '',
+ search: '',
+ hash: '',
+ };
+ $.extend(stubLocation, defaults, stubs || {});
+ };
+
+ preloadFixtures(
+ 'merge_requests/merge_request_with_task_list.html',
+ 'merge_requests/diff_comment.html',
+ );
+
+ beforeEach(() => {
+ initMrPage();
+
+ testContext.class = new MergeRequestTabs({ stubLocation });
+ setLocation();
+
+ testContext.spies = {
+ history: jest.spyOn(window.history, 'pushState').mockImplementation(() => {}),
+ };
+
+ gl.mrWidget = {};
+ });
+
+ describe('opensInNewTab', () => {
+ const windowTarget = '_blank';
+ let clickTabParams;
+ let tabUrl;
+
+ beforeEach(() => {
+ loadFixtures('merge_requests/merge_request_with_task_list.html');
+
+ tabUrl = $('.commits-tab a').attr('href');
+
+ clickTabParams = {
+ metaKey: false,
+ ctrlKey: false,
+ which: 1,
+ stopImmediatePropagation() {},
+ preventDefault() {},
+ currentTarget: {
+ getAttribute(attr) {
+ return attr === 'href' ? tabUrl : null;
+ },
+ },
+ };
+ });
+
+ describe('meta click', () => {
+ let metakeyEvent;
+
+ beforeEach(() => {
+ metakeyEvent = $.Event('click', { keyCode: 91, ctrlKey: true });
+ });
+
+ it('opens page when commits link is clicked', () => {
+ jest.spyOn(window, 'open').mockImplementation((url, name) => {
+ expect(url).toEqual(tabUrl);
+ expect(name).toEqual(windowTarget);
+ });
+
+ testContext.class.bindEvents();
+ $('.merge-request-tabs .commits-tab a').trigger(metakeyEvent);
+
+ expect(window.open).toHaveBeenCalled();
+ });
+
+ it('opens page when commits badge is clicked', () => {
+ jest.spyOn(window, 'open').mockImplementation((url, name) => {
+ expect(url).toEqual(tabUrl);
+ expect(name).toEqual(windowTarget);
+ });
+
+ testContext.class.bindEvents();
+ $('.merge-request-tabs .commits-tab a .badge').trigger(metakeyEvent);
+
+ expect(window.open).toHaveBeenCalled();
+ });
+ });
+
+ it('opens page tab in a new browser tab with Ctrl+Click - Windows/Linux', () => {
+ jest.spyOn(window, 'open').mockImplementation((url, name) => {
+ expect(url).toEqual(tabUrl);
+ expect(name).toEqual(windowTarget);
+ });
+
+ testContext.class.clickTab({ ...clickTabParams, metaKey: true });
+
+ expect(window.open).toHaveBeenCalled();
+ });
+
+ it('opens page tab in a new browser tab with Cmd+Click - Mac', () => {
+ jest.spyOn(window, 'open').mockImplementation((url, name) => {
+ expect(url).toEqual(tabUrl);
+ expect(name).toEqual(windowTarget);
+ });
+
+ testContext.class.clickTab({ ...clickTabParams, ctrlKey: true });
+
+ expect(window.open).toHaveBeenCalled();
+ });
+
+ it('opens page tab in a new browser tab with Middle-click - Mac/PC', () => {
+ jest.spyOn(window, 'open').mockImplementation((url, name) => {
+ expect(url).toEqual(tabUrl);
+ expect(name).toEqual(windowTarget);
+ });
+
+ testContext.class.clickTab({ ...clickTabParams, which: 2 });
+
+ expect(window.open).toHaveBeenCalled();
+ });
+ });
+
+ describe('setCurrentAction', () => {
+ let mock;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ mock.onAny().reply({ data: {} });
+ testContext.subject = testContext.class.setCurrentAction;
+ });
+
+ afterEach(() => {
+ mock.restore();
+ window.history.replaceState({}, '', '/');
+ });
+
+ it('changes from commits', () => {
+ setLocation({
+ pathname: '/foo/bar/-/merge_requests/1/commits',
+ });
+
+ expect(testContext.subject('show')).toBe('/foo/bar/-/merge_requests/1');
+ expect(testContext.subject('diffs')).toBe('/foo/bar/-/merge_requests/1/diffs');
+ });
+
+ it('changes from diffs', () => {
+ setLocation({
+ pathname: '/foo/bar/-/merge_requests/1/diffs',
+ });
+
+ expect(testContext.subject('show')).toBe('/foo/bar/-/merge_requests/1');
+ expect(testContext.subject('commits')).toBe('/foo/bar/-/merge_requests/1/commits');
+ });
+
+ it('changes from diffs.html', () => {
+ setLocation({
+ pathname: '/foo/bar/-/merge_requests/1/diffs.html',
+ });
+
+ expect(testContext.subject('show')).toBe('/foo/bar/-/merge_requests/1');
+ expect(testContext.subject('commits')).toBe('/foo/bar/-/merge_requests/1/commits');
+ });
+
+ it('changes from notes', () => {
+ setLocation({
+ pathname: '/foo/bar/-/merge_requests/1',
+ });
+
+ expect(testContext.subject('diffs')).toBe('/foo/bar/-/merge_requests/1/diffs');
+ expect(testContext.subject('commits')).toBe('/foo/bar/-/merge_requests/1/commits');
+ });
+
+ it('includes search parameters and hash string', () => {
+ setLocation({
+ pathname: '/foo/bar/-/merge_requests/1/diffs',
+ search: '?view=parallel',
+ hash: '#L15-35',
+ });
+
+ expect(testContext.subject('show')).toBe('/foo/bar/-/merge_requests/1?view=parallel#L15-35');
+ });
+
+ it('replaces the current history state', () => {
+ setLocation({
+ pathname: '/foo/bar/-/merge_requests/1',
+ });
+ window.history.replaceState(
+ {
+ url: window.location.href,
+ action: 'show',
+ },
+ document.title,
+ window.location.href,
+ );
+
+ const newState = testContext.subject('commits');
+
+ expect(testContext.spies.history).toHaveBeenCalledWith(
+ {
+ url: newState,
+ action: 'commits',
+ },
+ document.title,
+ newState,
+ );
+ });
+
+ it('treats "show" like "notes"', () => {
+ setLocation({
+ pathname: '/foo/bar/-/merge_requests/1/commits',
+ });
+
+ expect(testContext.subject('show')).toBe('/foo/bar/-/merge_requests/1');
+ });
+ });
+
+ describe('expandViewContainer', () => {
+ beforeEach(() => {
+ $('body').append(
+ '<div class="content-wrapper"><div class="container-fluid container-limited"></div></div>',
+ );
+ });
+
+ afterEach(() => {
+ $('.content-wrapper').remove();
+ });
+
+ it('removes container-limited from containers', () => {
+ testContext.class.expandViewContainer();
+
+ expect($('.content-wrapper .container-limited')).toHaveLength(0);
+ });
+
+ it('does not add container-limited when fluid layout is prefered', () => {
+ $('.content-wrapper .container-fluid').removeClass('container-limited');
+
+ testContext.class.expandViewContainer(false);
+
+ expect($('.content-wrapper .container-limited')).toHaveLength(0);
+ });
+
+ it('does remove container-limited from breadcrumbs', () => {
+ $('.container-limited').addClass('breadcrumbs');
+ testContext.class.expandViewContainer();
+
+ expect($('.content-wrapper .container-limited')).toHaveLength(1);
+ });
+ });
+
+ describe('tabShown', () => {
+ const mainContent = document.createElement('div');
+ const tabContent = document.createElement('div');
+
+ beforeEach(() => {
+ jest.spyOn(mainContent, 'getBoundingClientRect').mockReturnValue({ top: 10 });
+ jest.spyOn(tabContent, 'getBoundingClientRect').mockReturnValue({ top: 100 });
+ jest.spyOn(document, 'querySelector').mockImplementation(selector => {
+ return selector === '.content-wrapper' ? mainContent : tabContent;
+ });
+ testContext.class.currentAction = 'commits';
+ });
+
+ 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' });
+ });
+
+ 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]);
+ });
+ });
+});
diff --git a/spec/frontend/mini_pipeline_graph_dropdown_spec.js b/spec/frontend/mini_pipeline_graph_dropdown_spec.js
new file mode 100644
index 00000000000..506290834c8
--- /dev/null
+++ b/spec/frontend/mini_pipeline_graph_dropdown_spec.js
@@ -0,0 +1,106 @@
+import $ from 'jquery';
+import MockAdapter from 'axios-mock-adapter';
+import axios from '~/lib/utils/axios_utils';
+import MiniPipelineGraph from '~/mini_pipeline_graph_dropdown';
+import waitForPromises from './helpers/wait_for_promises';
+
+describe('Mini Pipeline Graph Dropdown', () => {
+ preloadFixtures('static/mini_dropdown_graph.html');
+
+ beforeEach(() => {
+ loadFixtures('static/mini_dropdown_graph.html');
+ });
+
+ describe('When is initialized', () => {
+ it('should initialize without errors when no options are given', () => {
+ const miniPipelineGraph = new MiniPipelineGraph();
+
+ expect(miniPipelineGraph.dropdownListSelector).toEqual('.js-builds-dropdown-container');
+ });
+
+ it('should set the container as the given prop', () => {
+ const container = '.foo';
+
+ const miniPipelineGraph = new MiniPipelineGraph({ container });
+
+ expect(miniPipelineGraph.container).toEqual(container);
+ });
+ });
+
+ describe('When dropdown is clicked', () => {
+ let mock;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ });
+
+ afterEach(() => {
+ mock.restore();
+ });
+
+ it('should call getBuildsList', () => {
+ const getBuildsListSpy = jest
+ .spyOn(MiniPipelineGraph.prototype, 'getBuildsList')
+ .mockImplementation(() => {});
+
+ new MiniPipelineGraph({ container: '.js-builds-dropdown-tests' }).bindEvents();
+
+ document.querySelector('.js-builds-dropdown-button').click();
+
+ expect(getBuildsListSpy).toHaveBeenCalled();
+ });
+
+ it('should make a request to the endpoint provided in the html', () => {
+ const ajaxSpy = jest.spyOn(axios, 'get');
+
+ mock.onGet('foobar').reply(200, {
+ html: '',
+ });
+
+ new MiniPipelineGraph({ container: '.js-builds-dropdown-tests' }).bindEvents();
+
+ document.querySelector('.js-builds-dropdown-button').click();
+
+ expect(ajaxSpy.mock.calls[0][0]).toEqual('foobar');
+ });
+
+ it('should not close when user uses cmd/ctrl + click', done => {
+ mock.onGet('foobar').reply(200, {
+ html: `<li>
+ <a class="mini-pipeline-graph-dropdown-item" href="#">
+ <span class="ci-status-icon ci-status-icon-failed"></span>
+ <span class="ci-build-text">build</span>
+ </a>
+ <a class="ci-action-icon-wrapper js-ci-action-icon" href="#"></a>
+ </li>`,
+ });
+ new MiniPipelineGraph({ container: '.js-builds-dropdown-tests' }).bindEvents();
+
+ document.querySelector('.js-builds-dropdown-button').click();
+
+ waitForPromises()
+ .then(() => {
+ document.querySelector('a.mini-pipeline-graph-dropdown-item').click();
+ })
+ .then(waitForPromises)
+ .then(() => {
+ expect($('.js-builds-dropdown-list').is(':visible')).toEqual(true);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('should close the dropdown when request returns an error', done => {
+ mock.onGet('foobar').networkError();
+
+ new MiniPipelineGraph({ container: '.js-builds-dropdown-tests' }).bindEvents();
+
+ document.querySelector('.js-builds-dropdown-button').click();
+
+ setImmediate(() => {
+ expect($('.js-builds-dropdown-tests .dropdown').hasClass('open')).toEqual(false);
+ done();
+ });
+ });
+ });
+});
diff --git a/spec/frontend/monitoring/__snapshots__/alert_widget_spec.js.snap b/spec/frontend/monitoring/__snapshots__/alert_widget_spec.js.snap
index 2179e7b4ab5..59c17daacff 100644
--- a/spec/frontend/monitoring/__snapshots__/alert_widget_spec.js.snap
+++ b/spec/frontend/monitoring/__snapshots__/alert_widget_spec.js.snap
@@ -3,7 +3,7 @@
exports[`AlertWidget Alert firing displays a warning icon and matches snapshot 1`] = `
<gl-badge-stub
class="d-flex-center text-truncate"
- pill=""
+ size="md"
variant="danger"
>
<gl-icon-stub
@@ -25,8 +25,8 @@ exports[`AlertWidget Alert firing displays a warning icon and matches snapshot 1
exports[`AlertWidget Alert not firing displays a warning icon and matches snapshot 1`] = `
<gl-badge-stub
class="d-flex-center text-truncate"
- pill=""
- variant="secondary"
+ size="md"
+ variant="neutral"
>
<gl-icon-stub
class="flex-shrink-0"
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 9be5fa72110..4b08163f30a 100644
--- a/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap
+++ b/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap
@@ -38,8 +38,8 @@ exports[`Dashboard template matches the default snapshot 1`] = `
class="monitor-environment-dropdown-header text-center"
>
- Environment
-
+ Environment
+
</gl-dropdown-header-stub>
<gl-dropdown-divider-stub />
@@ -58,8 +58,8 @@ exports[`Dashboard template matches the default snapshot 1`] = `
class="text-secondary no-matches-message"
>
- No matching results
-
+ No matching results
+
</div>
</div>
</gl-dropdown-stub>
@@ -132,6 +132,8 @@ exports[`Dashboard template matches the default snapshot 1`] = `
<!---->
+ <!---->
+
<empty-state-stub
clusterspath="/path/to/clusters"
documentationpath="/path/to/docs"
diff --git a/spec/frontend/monitoring/components/charts/anomaly_spec.js b/spec/frontend/monitoring/components/charts/anomaly_spec.js
index e2d001c3058..4178d3f0d2d 100644
--- a/spec/frontend/monitoring/components/charts/anomaly_spec.js
+++ b/spec/frontend/monitoring/components/charts/anomaly_spec.js
@@ -13,8 +13,6 @@ import MonitorTimeSeriesChart from '~/monitoring/components/charts/time_series.v
const mockProjectPath = `${TEST_HOST}${mockProjectDir}`;
-jest.mock('~/lib/utils/icon_utils'); // mock getSvgIconPathContent
-
const makeAnomalyGraphData = (datasetName, template = anomalyMockGraphData) => {
const metrics = anomalyMockResultValues[datasetName].map((values, index) => ({
...template.metrics[index],
diff --git a/spec/frontend/monitoring/components/charts/column_spec.js b/spec/frontend/monitoring/components/charts/column_spec.js
index f368cb7916c..89739a7485d 100644
--- a/spec/frontend/monitoring/components/charts/column_spec.js
+++ b/spec/frontend/monitoring/components/charts/column_spec.js
@@ -1,4 +1,5 @@
import { shallowMount } from '@vue/test-utils';
+import timezoneMock from 'timezone-mock';
import { GlColumnChart } from '@gitlab/ui/dist/charts';
import ColumnChart from '~/monitoring/components/charts/column.vue';
@@ -18,10 +19,7 @@ const dataValues = [
describe('Column component', () => {
let wrapper;
- const findChart = () => wrapper.find(GlColumnChart);
- const chartProps = prop => findChart().props(prop);
-
- beforeEach(() => {
+ const createWrapper = (props = {}) => {
wrapper = shallowMount(ColumnChart, {
propsData: {
graphData: {
@@ -41,14 +39,60 @@ describe('Column component', () => {
},
],
},
+ ...props,
},
});
+ };
+ const findChart = () => wrapper.find(GlColumnChart);
+ const chartProps = prop => findChart().props(prop);
+
+ beforeEach(() => {
+ createWrapper();
});
afterEach(() => {
wrapper.destroy();
});
+ describe('xAxisLabel', () => {
+ const mockDate = Date.UTC(2020, 4, 26, 20); // 8:00 PM in GMT
+
+ const useXAxisFormatter = date => {
+ const { xAxis } = chartProps('option');
+ const { formatter } = xAxis.axisLabel;
+ return formatter(date);
+ };
+
+ it('x-axis is formatted correctly in AM/PM format', () => {
+ expect(useXAxisFormatter(mockDate)).toEqual('8:00 PM');
+ });
+
+ describe('when in PT timezone', () => {
+ beforeAll(() => {
+ timezoneMock.register('US/Pacific');
+ });
+
+ afterAll(() => {
+ timezoneMock.unregister();
+ });
+
+ it('by default, values are formatted in PT', () => {
+ createWrapper();
+ expect(useXAxisFormatter(mockDate)).toEqual('1:00 PM');
+ });
+
+ it('when the chart uses local timezone, y-axis is formatted in PT', () => {
+ createWrapper({ timezone: 'LOCAL' });
+ expect(useXAxisFormatter(mockDate)).toEqual('1:00 PM');
+ });
+
+ it('when the chart uses UTC, y-axis is formatted in UTC', () => {
+ createWrapper({ timezone: 'UTC' });
+ expect(useXAxisFormatter(mockDate)).toEqual('8:00 PM');
+ });
+ });
+ });
+
describe('wrapped components', () => {
describe('GitLab UI column chart', () => {
it('is a Vue instance', () => {
diff --git a/spec/frontend/monitoring/components/charts/heatmap_spec.js b/spec/frontend/monitoring/components/charts/heatmap_spec.js
index 5e2c1932e9e..2a1c78025ae 100644
--- a/spec/frontend/monitoring/components/charts/heatmap_spec.js
+++ b/spec/frontend/monitoring/components/charts/heatmap_spec.js
@@ -1,68 +1,101 @@
import { shallowMount } from '@vue/test-utils';
import { GlHeatmap } from '@gitlab/ui/dist/charts';
+import timezoneMock from 'timezone-mock';
import Heatmap from '~/monitoring/components/charts/heatmap.vue';
import { graphDataPrometheusQueryRangeMultiTrack } from '../../mock_data';
describe('Heatmap component', () => {
- let heatmapChart;
+ let wrapper;
let store;
- beforeEach(() => {
- heatmapChart = shallowMount(Heatmap, {
+ const findChart = () => wrapper.find(GlHeatmap);
+
+ const createWrapper = (props = {}) => {
+ wrapper = shallowMount(Heatmap, {
propsData: {
graphData: graphDataPrometheusQueryRangeMultiTrack,
containerWidth: 100,
+ ...props,
},
store,
});
- });
+ };
- afterEach(() => {
- heatmapChart.destroy();
- });
+ describe('wrapped chart', () => {
+ let glHeatmapChart;
- describe('wrapped components', () => {
- describe('GitLab UI heatmap chart', () => {
- let glHeatmapChart;
+ beforeEach(() => {
+ createWrapper();
+ glHeatmapChart = findChart();
+ });
- beforeEach(() => {
- glHeatmapChart = heatmapChart.find(GlHeatmap);
- });
+ afterEach(() => {
+ wrapper.destroy();
+ });
- it('is a Vue instance', () => {
- expect(glHeatmapChart.isVueInstance()).toBe(true);
- });
+ it('is a Vue instance', () => {
+ expect(glHeatmapChart.isVueInstance()).toBe(true);
+ });
- it('should display a label on the x axis', () => {
- expect(heatmapChart.vm.xAxisName).toBe(graphDataPrometheusQueryRangeMultiTrack.x_label);
- });
+ it('should display a label on the x axis', () => {
+ expect(wrapper.vm.xAxisName).toBe(graphDataPrometheusQueryRangeMultiTrack.x_label);
+ });
- it('should display a label on the y axis', () => {
- expect(heatmapChart.vm.yAxisName).toBe(graphDataPrometheusQueryRangeMultiTrack.y_label);
- });
+ it('should display a label on the y axis', () => {
+ expect(wrapper.vm.yAxisName).toBe(graphDataPrometheusQueryRangeMultiTrack.y_label);
+ });
- // According to the echarts docs https://echarts.apache.org/en/option.html#series-heatmap.data
- // each row of the heatmap chart is represented by an array inside another parent array
- // e.g. [[0, 0, 10]], the format represents the column, the row and finally the value
- // corresponding to the cell
+ // According to the echarts docs https://echarts.apache.org/en/option.html#series-heatmap.data
+ // each row of the heatmap chart is represented by an array inside another parent array
+ // e.g. [[0, 0, 10]], the format represents the column, the row and finally the value
+ // corresponding to the cell
- it('should return chartData with a length of x by y, with a length of 3 per array', () => {
- const row = heatmapChart.vm.chartData[0];
+ it('should return chartData with a length of x by y, with a length of 3 per array', () => {
+ const row = wrapper.vm.chartData[0];
- expect(row.length).toBe(3);
- expect(heatmapChart.vm.chartData.length).toBe(30);
- });
+ expect(row.length).toBe(3);
+ expect(wrapper.vm.chartData.length).toBe(30);
+ });
+
+ it('returns a series of labels for the x axis', () => {
+ const { xAxisLabels } = wrapper.vm;
+
+ expect(xAxisLabels.length).toBe(5);
+ });
- it('returns a series of labels for the x axis', () => {
- const { xAxisLabels } = heatmapChart.vm;
+ describe('y axis labels', () => {
+ const gmtLabels = ['3:00 PM', '4:00 PM', '5:00 PM', '6:00 PM', '7:00 PM', '8:00 PM'];
- expect(xAxisLabels.length).toBe(5);
+ it('y-axis labels are formatted in AM/PM format', () => {
+ expect(findChart().props('yAxisLabels')).toEqual(gmtLabels);
});
- it('returns a series of labels for the y axis', () => {
- const { yAxisLabels } = heatmapChart.vm;
+ describe('when in PT timezone', () => {
+ const ptLabels = ['8:00 AM', '9:00 AM', '10:00 AM', '11:00 AM', '12:00 PM', '1:00 PM'];
+ const utcLabels = gmtLabels; // Identical in this case
+
+ beforeAll(() => {
+ timezoneMock.register('US/Pacific');
+ });
+
+ afterAll(() => {
+ timezoneMock.unregister();
+ });
+
+ it('by default, y-axis is formatted in PT', () => {
+ createWrapper();
+ expect(findChart().props('yAxisLabels')).toEqual(ptLabels);
+ });
+
+ it('when the chart uses local timezone, y-axis is formatted in PT', () => {
+ createWrapper({ timezone: 'LOCAL' });
+ expect(findChart().props('yAxisLabels')).toEqual(ptLabels);
+ });
- expect(yAxisLabels.length).toBe(6);
+ it('when the chart uses UTC, y-axis is formatted in UTC', () => {
+ createWrapper({ timezone: 'UTC' });
+ expect(findChart().props('yAxisLabels')).toEqual(utcLabels);
+ });
});
});
});
diff --git a/spec/frontend/monitoring/components/charts/stacked_column_spec.js b/spec/frontend/monitoring/components/charts/stacked_column_spec.js
index abb89ac15ef..bb2fbc68eaa 100644
--- a/spec/frontend/monitoring/components/charts/stacked_column_spec.js
+++ b/spec/frontend/monitoring/components/charts/stacked_column_spec.js
@@ -1,45 +1,192 @@
-import { shallowMount } from '@vue/test-utils';
-import { GlStackedColumnChart } from '@gitlab/ui/dist/charts';
+import { shallowMount, mount } from '@vue/test-utils';
+import timezoneMock from 'timezone-mock';
+import { cloneDeep } from 'lodash';
+import { GlStackedColumnChart, GlChartLegend } from '@gitlab/ui/dist/charts';
import StackedColumnChart from '~/monitoring/components/charts/stacked_column.vue';
import { stackedColumnMockedData } from '../../mock_data';
jest.mock('~/lib/utils/icon_utils', () => ({
- getSvgIconPathContent: jest.fn().mockResolvedValue('mockSvgPathContent'),
+ getSvgIconPathContent: jest.fn().mockImplementation(icon => Promise.resolve(`${icon}-content`)),
}));
describe('Stacked column chart component', () => {
let wrapper;
- const glStackedColumnChart = () => wrapper.find(GlStackedColumnChart);
- beforeEach(() => {
- wrapper = shallowMount(StackedColumnChart, {
+ const findChart = () => wrapper.find(GlStackedColumnChart);
+ const findLegend = () => wrapper.find(GlChartLegend);
+
+ const createWrapper = (props = {}, mountingMethod = shallowMount) =>
+ mountingMethod(StackedColumnChart, {
propsData: {
graphData: stackedColumnMockedData,
+ ...props,
+ },
+ stubs: {
+ GlPopover: true,
},
+ attachToDocument: true,
+ });
+
+ beforeEach(() => {
+ wrapper = createWrapper({}, mount);
+ });
+
+ describe('when graphData is present', () => {
+ beforeEach(() => {
+ createWrapper();
+ return wrapper.vm.$nextTick();
+ });
+
+ it('chart is rendered', () => {
+ expect(findChart().exists()).toBe(true);
+ });
+
+ it('data should match the graphData y value for each series', () => {
+ const data = findChart().props('data');
+
+ data.forEach((series, index) => {
+ const { values } = stackedColumnMockedData.metrics[index].result[0];
+ expect(series).toEqual(values.map(value => value[1]));
+ });
+ });
+
+ it('series names should be the same as the graphData metrics labels', () => {
+ const seriesNames = findChart().props('seriesNames');
+
+ expect(seriesNames).toHaveLength(stackedColumnMockedData.metrics.length);
+ seriesNames.forEach((name, index) => {
+ expect(stackedColumnMockedData.metrics[index].label).toBe(name);
+ });
+ });
+
+ it('group by should be the same as the graphData first metric results', () => {
+ const groupBy = findChart().props('groupBy');
+
+ expect(groupBy).toEqual([
+ '2020-01-30T12:00:00.000Z',
+ '2020-01-30T12:01:00.000Z',
+ '2020-01-30T12:02:00.000Z',
+ ]);
+ });
+
+ it('chart options should configure data zoom and axis label ', () => {
+ const chartOptions = findChart().props('option');
+ const xAxisType = findChart().props('xAxisType');
+
+ expect(chartOptions).toMatchObject({
+ dataZoom: [{ handleIcon: 'path://scroll-handle-content' }],
+ xAxis: {
+ axisLabel: { formatter: expect.any(Function) },
+ },
+ });
+
+ expect(xAxisType).toBe('category');
+ });
+
+ it('chart options should configure category as x axis type', () => {
+ const chartOptions = findChart().props('option');
+ const xAxisType = findChart().props('xAxisType');
+
+ expect(chartOptions).toMatchObject({
+ xAxis: {
+ type: 'category',
+ },
+ });
+ expect(xAxisType).toBe('category');
+ });
+
+ it('format date is correct', () => {
+ const { xAxis } = findChart().props('option');
+ expect(xAxis.axisLabel.formatter('2020-01-30T12:01:00.000Z')).toBe('12:01 PM');
+ });
+
+ describe('when in PT timezone', () => {
+ beforeAll(() => {
+ timezoneMock.register('US/Pacific');
+ });
+
+ afterAll(() => {
+ timezoneMock.unregister();
+ });
+
+ it('date is shown in local time', () => {
+ const { xAxis } = findChart().props('option');
+ expect(xAxis.axisLabel.formatter('2020-01-30T12:01:00.000Z')).toBe('4:01 AM');
+ });
+
+ it('date is shown in UTC', () => {
+ wrapper.setProps({ timezone: 'UTC' });
+
+ return wrapper.vm.$nextTick().then(() => {
+ const { xAxis } = findChart().props('option');
+ expect(xAxis.axisLabel.formatter('2020-01-30T12:01:00.000Z')).toBe('12:01 PM');
+ });
+ });
});
});
- afterEach(() => {
- wrapper.destroy();
+ describe('when graphData has results missing', () => {
+ beforeEach(() => {
+ const graphData = cloneDeep(stackedColumnMockedData);
+
+ graphData.metrics[0].result = null;
+
+ createWrapper({ graphData });
+ return wrapper.vm.$nextTick();
+ });
+
+ it('chart is rendered', () => {
+ expect(findChart().exists()).toBe(true);
+ });
});
- describe('with graphData present', () => {
- it('is a Vue instance', () => {
- expect(glStackedColumnChart().exists()).toBe(true);
+ describe('legend', () => {
+ beforeEach(() => {
+ wrapper = createWrapper({}, mount);
+ });
+
+ it('allows user to override legend label texts using props', () => {
+ const legendRelatedProps = {
+ legendMinText: 'legendMinText',
+ legendMaxText: 'legendMaxText',
+ legendAverageText: 'legendAverageText',
+ legendCurrentText: 'legendCurrentText',
+ };
+ wrapper.setProps({
+ ...legendRelatedProps,
+ });
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findChart().props()).toMatchObject(legendRelatedProps);
+ });
});
- it('should contain the same number of elements in the seriesNames computed prop as the graphData metrics prop', () =>
- wrapper.vm
- .$nextTick()
- .then(expect(wrapper.vm.seriesNames).toHaveLength(stackedColumnMockedData.metrics.length)));
+ it('should render a tabular legend layout by default', () => {
+ expect(findLegend().props('layout')).toBe('table');
+ });
+
+ describe('when inline legend layout prop is set', () => {
+ beforeEach(() => {
+ wrapper.setProps({
+ legendLayout: 'inline',
+ });
+ });
+
+ it('should render an inline legend layout', () => {
+ expect(findLegend().props('layout')).toBe('inline');
+ });
+ });
+
+ describe('when table legend layout prop is set', () => {
+ beforeEach(() => {
+ wrapper.setProps({
+ legendLayout: 'table',
+ });
+ });
- it('should contain the same number of elements in the groupBy computed prop as the graphData result prop', () =>
- wrapper.vm
- .$nextTick()
- .then(
- expect(wrapper.vm.groupBy).toHaveLength(
- stackedColumnMockedData.metrics[0].result[0].values.length,
- ),
- ));
+ it('should render a tabular legend layout', () => {
+ expect(findLegend().props('layout')).toBe('table');
+ });
+ });
});
});
diff --git a/spec/frontend/monitoring/components/charts/time_series_spec.js b/spec/frontend/monitoring/components/charts/time_series_spec.js
index 7d5a08bc4a1..50d2c9c80b2 100644
--- a/spec/frontend/monitoring/components/charts/time_series_spec.js
+++ b/spec/frontend/monitoring/components/charts/time_series_spec.js
@@ -1,5 +1,6 @@
import { mount, shallowMount } from '@vue/test-utils';
import { setTestTimeout } from 'helpers/timeout';
+import timezoneMock from 'timezone-mock';
import { GlLink } from '@gitlab/ui';
import { TEST_HOST } from 'jest/helpers/test_constants';
import {
@@ -20,9 +21,6 @@ import {
metricsDashboardViewModel,
metricResultStatus,
} from '../../fixture_data';
-import * as iconUtils from '~/lib/utils/icon_utils';
-
-const mockSvgPathContent = 'mockSvgPathContent';
jest.mock('lodash/throttle', () =>
// this throttle mock executes immediately
@@ -33,26 +31,33 @@ jest.mock('lodash/throttle', () =>
}),
);
jest.mock('~/lib/utils/icon_utils', () => ({
- getSvgIconPathContent: jest.fn().mockImplementation(() => Promise.resolve(mockSvgPathContent)),
+ getSvgIconPathContent: jest.fn().mockImplementation(icon => Promise.resolve(`${icon}-content`)),
}));
describe('Time series component', () => {
let mockGraphData;
let store;
+ let wrapper;
- const createWrapper = (graphData = mockGraphData, mountingMethod = shallowMount) =>
- mountingMethod(TimeSeries, {
+ const createWrapper = (
+ { graphData = mockGraphData, ...props } = {},
+ mountingMethod = shallowMount,
+ ) => {
+ wrapper = mountingMethod(TimeSeries, {
propsData: {
graphData,
deploymentData: store.state.monitoringDashboard.deploymentData,
annotations: store.state.monitoringDashboard.annotations,
projectPath: `${TEST_HOST}${mockProjectDir}`,
+ ...props,
},
store,
stubs: {
GlPopover: true,
},
+ attachToDocument: true,
});
+ };
describe('With a single time series', () => {
beforeEach(() => {
@@ -76,39 +81,41 @@ describe('Time series component', () => {
});
describe('general functions', () => {
- let timeSeriesChart;
-
- const findChart = () => timeSeriesChart.find({ ref: 'chart' });
+ const findChart = () => wrapper.find({ ref: 'chart' });
beforeEach(() => {
- timeSeriesChart = createWrapper(mockGraphData, mount);
- return timeSeriesChart.vm.$nextTick();
+ createWrapper({}, mount);
+ return wrapper.vm.$nextTick();
});
- it('allows user to override max value label text using prop', () => {
- timeSeriesChart.setProps({ legendMaxText: 'legendMaxText' });
-
- return timeSeriesChart.vm.$nextTick().then(() => {
- expect(timeSeriesChart.props().legendMaxText).toBe('legendMaxText');
- });
+ afterEach(() => {
+ wrapper.destroy();
});
- it('allows user to override average value label text using prop', () => {
- timeSeriesChart.setProps({ legendAverageText: 'averageText' });
+ it('allows user to override legend label texts using props', () => {
+ const legendRelatedProps = {
+ legendMinText: 'legendMinText',
+ legendMaxText: 'legendMaxText',
+ legendAverageText: 'legendAverageText',
+ legendCurrentText: 'legendCurrentText',
+ };
+ wrapper.setProps({
+ ...legendRelatedProps,
+ });
- return timeSeriesChart.vm.$nextTick().then(() => {
- expect(timeSeriesChart.props().legendAverageText).toBe('averageText');
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findChart().props()).toMatchObject(legendRelatedProps);
});
});
it('chart sets a default height', () => {
- const wrapper = createWrapper();
+ createWrapper();
expect(wrapper.props('height')).toBe(chartHeight);
});
it('chart has a configurable height', () => {
const mockHeight = 599;
- const wrapper = createWrapper();
+ createWrapper();
wrapper.setProps({ height: mockHeight });
return wrapper.vm.$nextTick().then(() => {
@@ -122,7 +129,7 @@ describe('Time series component', () => {
let startValue;
let endValue;
- beforeEach(done => {
+ beforeEach(() => {
eChartMock = {
handlers: {},
getOption: () => ({
@@ -141,10 +148,9 @@ describe('Time series component', () => {
}),
};
- timeSeriesChart = createWrapper(mockGraphData, mount);
- timeSeriesChart.vm.$nextTick(() => {
+ createWrapper({}, mount);
+ return wrapper.vm.$nextTick(() => {
findChart().vm.$emit('created', eChartMock);
- done();
});
});
@@ -153,8 +159,8 @@ describe('Time series component', () => {
endValue = 1577840400000; // 2020-01-01T01:00:00.000Z
eChartMock.handlers.datazoom();
- expect(timeSeriesChart.emitted('datazoom')).toHaveLength(1);
- expect(timeSeriesChart.emitted('datazoom')[0]).toEqual([
+ expect(wrapper.emitted('datazoom')).toHaveLength(1);
+ expect(wrapper.emitted('datazoom')[0]).toEqual([
{
start: new Date(startValue).toISOString(),
end: new Date(endValue).toISOString(),
@@ -172,7 +178,7 @@ describe('Time series component', () => {
const mockLineSeriesData = () => ({
seriesData: [
{
- seriesName: timeSeriesChart.vm.chartData[0].name,
+ seriesName: wrapper.vm.chartData[0].name,
componentSubType: 'line',
value: [mockDate, 5.55555],
dataIndex: 0,
@@ -210,86 +216,118 @@ describe('Time series component', () => {
value: undefined,
})),
};
- expect(timeSeriesChart.vm.formatTooltipText(seriesDataWithoutValue)).toBeUndefined();
+ expect(wrapper.vm.formatTooltipText(seriesDataWithoutValue)).toBeUndefined();
});
describe('when series is of line type', () => {
- beforeEach(done => {
- timeSeriesChart.vm.formatTooltipText(mockLineSeriesData());
- timeSeriesChart.vm.$nextTick(done);
+ beforeEach(() => {
+ createWrapper();
+ wrapper.vm.formatTooltipText(mockLineSeriesData());
+ return wrapper.vm.$nextTick();
});
it('formats tooltip title', () => {
- expect(timeSeriesChart.vm.tooltip.title).toBe('16 Jul 2019, 10:14AM');
+ expect(wrapper.vm.tooltip.title).toBe('16 Jul 2019, 10:14AM (GMT+0000)');
});
it('formats tooltip content', () => {
const name = 'Status Code';
const value = '5.556';
const dataIndex = 0;
- const seriesLabel = timeSeriesChart.find(GlChartSeriesLabel);
+ const seriesLabel = wrapper.find(GlChartSeriesLabel);
expect(seriesLabel.vm.color).toBe('');
expect(shallowWrapperContainsSlotText(seriesLabel, 'default', name)).toBe(true);
- expect(timeSeriesChart.vm.tooltip.content).toEqual([
+ expect(wrapper.vm.tooltip.content).toEqual([
{ name, value, dataIndex, color: undefined },
]);
expect(
- shallowWrapperContainsSlotText(
- timeSeriesChart.find(GlAreaChart),
- 'tooltipContent',
- value,
- ),
+ shallowWrapperContainsSlotText(wrapper.find(GlAreaChart), 'tooltipContent', value),
).toBe(true);
});
+
+ describe('when in PT timezone', () => {
+ beforeAll(() => {
+ // Note: node.js env renders (GMT-0700), in the browser we see (PDT)
+ timezoneMock.register('US/Pacific');
+ });
+
+ afterAll(() => {
+ timezoneMock.unregister();
+ });
+
+ it('formats tooltip title in local timezone by default', () => {
+ createWrapper();
+ wrapper.vm.formatTooltipText(mockLineSeriesData());
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.vm.tooltip.title).toBe('16 Jul 2019, 3:14AM (GMT-0700)');
+ });
+ });
+
+ it('formats tooltip title in local timezone', () => {
+ createWrapper({ timezone: 'LOCAL' });
+ wrapper.vm.formatTooltipText(mockLineSeriesData());
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.vm.tooltip.title).toBe('16 Jul 2019, 3:14AM (GMT-0700)');
+ });
+ });
+
+ it('formats tooltip title in UTC format', () => {
+ createWrapper({ timezone: 'UTC' });
+ wrapper.vm.formatTooltipText(mockLineSeriesData());
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.vm.tooltip.title).toBe('16 Jul 2019, 10:14AM (UTC)');
+ });
+ });
+ });
});
describe('when series is of scatter type, for deployments', () => {
beforeEach(() => {
- timeSeriesChart.vm.formatTooltipText({
+ wrapper.vm.formatTooltipText({
...mockAnnotationsSeriesData,
seriesData: mockAnnotationsSeriesData.seriesData.map(data => ({
...data,
data: annotationsMetadata,
})),
});
- return timeSeriesChart.vm.$nextTick;
+ return wrapper.vm.$nextTick;
});
it('set tooltip type to deployments', () => {
- expect(timeSeriesChart.vm.tooltip.type).toBe('deployments');
+ expect(wrapper.vm.tooltip.type).toBe('deployments');
});
it('formats tooltip title', () => {
- expect(timeSeriesChart.vm.tooltip.title).toBe('16 Jul 2019, 10:14AM');
+ expect(wrapper.vm.tooltip.title).toBe('16 Jul 2019, 10:14AM (GMT+0000)');
});
it('formats tooltip sha', () => {
- expect(timeSeriesChart.vm.tooltip.sha).toBe('f5bcd1d9');
+ expect(wrapper.vm.tooltip.sha).toBe('f5bcd1d9');
});
it('formats tooltip commit url', () => {
- expect(timeSeriesChart.vm.tooltip.commitUrl).toBe(mockCommitUrl);
+ expect(wrapper.vm.tooltip.commitUrl).toBe(mockCommitUrl);
});
});
describe('when series is of scatter type and deployments data is missing', () => {
beforeEach(() => {
- timeSeriesChart.vm.formatTooltipText(mockAnnotationsSeriesData);
- return timeSeriesChart.vm.$nextTick;
+ wrapper.vm.formatTooltipText(mockAnnotationsSeriesData);
+ return wrapper.vm.$nextTick;
});
it('formats tooltip title', () => {
- expect(timeSeriesChart.vm.tooltip.title).toBe('16 Jul 2019, 10:14AM');
+ expect(wrapper.vm.tooltip.title).toBe('16 Jul 2019, 10:14AM (GMT+0000)');
});
it('formats tooltip sha', () => {
- expect(timeSeriesChart.vm.tooltip.sha).toBeUndefined();
+ expect(wrapper.vm.tooltip.sha).toBeUndefined();
});
it('formats tooltip commit url', () => {
- expect(timeSeriesChart.vm.tooltip.commitUrl).toBeUndefined();
+ expect(wrapper.vm.tooltip.commitUrl).toBeUndefined();
});
});
});
@@ -313,43 +351,12 @@ describe('Time series component', () => {
};
it('formats tooltip title and sets tooltip content', () => {
- const formattedTooltipData = timeSeriesChart.vm.formatAnnotationsTooltipText(
- mockMarkPoint,
- );
- expect(formattedTooltipData.title).toBe('19 Feb 2020, 10:01AM');
+ const formattedTooltipData = wrapper.vm.formatAnnotationsTooltipText(mockMarkPoint);
+ expect(formattedTooltipData.title).toBe('19 Feb 2020, 10:01AM (GMT+0000)');
expect(formattedTooltipData.content).toBe(annotationsMetadata.tooltipData.content);
});
});
- describe('setSvg', () => {
- const mockSvgName = 'mockSvgName';
-
- beforeEach(done => {
- timeSeriesChart.vm.setSvg(mockSvgName);
- timeSeriesChart.vm.$nextTick(done);
- });
-
- it('gets svg path content', () => {
- expect(iconUtils.getSvgIconPathContent).toHaveBeenCalledWith(mockSvgName);
- });
-
- it('sets svg path content', () => {
- timeSeriesChart.vm.$nextTick(() => {
- expect(timeSeriesChart.vm.svgs[mockSvgName]).toBe(`path://${mockSvgPathContent}`);
- });
- });
-
- it('contains an svg object within an array to properly render icon', () => {
- timeSeriesChart.vm.$nextTick(() => {
- expect(timeSeriesChart.vm.chartOptions.dataZoom).toEqual([
- {
- handleIcon: `path://${mockSvgPathContent}`,
- },
- ]);
- });
- });
- });
-
describe('onResize', () => {
const mockWidth = 233;
@@ -357,11 +364,11 @@ describe('Time series component', () => {
jest.spyOn(Element.prototype, 'getBoundingClientRect').mockImplementation(() => ({
width: mockWidth,
}));
- timeSeriesChart.vm.onResize();
+ wrapper.vm.onResize();
});
it('sets area chart width', () => {
- expect(timeSeriesChart.vm.width).toBe(mockWidth);
+ expect(wrapper.vm.width).toBe(mockWidth);
});
});
});
@@ -374,7 +381,7 @@ describe('Time series component', () => {
const seriesData = () => chartData[0];
beforeEach(() => {
- ({ chartData } = timeSeriesChart.vm);
+ ({ chartData } = wrapper.vm);
});
it('utilizes all data points', () => {
@@ -400,6 +407,21 @@ describe('Time series component', () => {
});
describe('chartOptions', () => {
+ describe('dataZoom', () => {
+ it('renders with scroll handle icons', () => {
+ expect(getChartOptions().dataZoom).toHaveLength(1);
+ expect(getChartOptions().dataZoom[0]).toMatchObject({
+ handleIcon: 'path://scroll-handle-content',
+ });
+ });
+ });
+
+ describe('xAxis pointer', () => {
+ it('snap is set to false by default', () => {
+ expect(getChartOptions().xAxis.axisPointer.snap).toBe(false);
+ });
+ });
+
describe('are extended by `option`', () => {
const mockSeriesName = 'Extra series 1';
const mockOption = {
@@ -408,17 +430,17 @@ describe('Time series component', () => {
};
it('arbitrary options', () => {
- timeSeriesChart.setProps({
+ wrapper.setProps({
option: mockOption,
});
- return timeSeriesChart.vm.$nextTick().then(() => {
+ return wrapper.vm.$nextTick().then(() => {
expect(getChartOptions()).toEqual(expect.objectContaining(mockOption));
});
});
it('additional series', () => {
- timeSeriesChart.setProps({
+ wrapper.setProps({
option: {
series: [
{
@@ -430,7 +452,7 @@ describe('Time series component', () => {
},
});
- return timeSeriesChart.vm.$nextTick().then(() => {
+ return wrapper.vm.$nextTick().then(() => {
const optionSeries = getChartOptions().series;
expect(optionSeries.length).toEqual(2);
@@ -446,13 +468,13 @@ describe('Time series component', () => {
},
};
- timeSeriesChart.setProps({
+ wrapper.setProps({
option: {
yAxis: mockCustomYAxisOption,
},
});
- return timeSeriesChart.vm.$nextTick().then(() => {
+ return wrapper.vm.$nextTick().then(() => {
const { yAxis } = getChartOptions();
expect(yAxis[0]).toMatchObject(mockCustomYAxisOption);
@@ -464,13 +486,13 @@ describe('Time series component', () => {
name: 'Custom x axis label',
};
- timeSeriesChart.setProps({
+ wrapper.setProps({
option: {
xAxis: mockCustomXAxisOption,
},
});
- return timeSeriesChart.vm.$nextTick().then(() => {
+ return wrapper.vm.$nextTick().then(() => {
const { xAxis } = getChartOptions();
expect(xAxis).toMatchObject(mockCustomXAxisOption);
@@ -499,25 +521,67 @@ describe('Time series component', () => {
describe('annotationSeries', () => {
it('utilizes deployment data', () => {
- const annotationSeries = timeSeriesChart.vm.chartOptionSeries[0];
+ const annotationSeries = wrapper.vm.chartOptionSeries[0];
expect(annotationSeries.yAxisIndex).toBe(1); // same as annotations y axis
expect(annotationSeries.data).toEqual([
expect.objectContaining({
symbolSize: 14,
+ symbol: 'path://rocket-content',
value: ['2019-07-16T10:14:25.589Z', expect.any(Number)],
}),
expect.objectContaining({
symbolSize: 14,
+ symbol: 'path://rocket-content',
value: ['2019-07-16T11:14:25.589Z', expect.any(Number)],
}),
expect.objectContaining({
symbolSize: 14,
+ symbol: 'path://rocket-content',
value: ['2019-07-16T12:14:25.589Z', expect.any(Number)],
}),
]);
});
});
+ describe('xAxisLabel', () => {
+ const mockDate = Date.UTC(2020, 4, 26, 20); // 8:00 PM in GMT
+
+ const useXAxisFormatter = date => {
+ const { xAxis } = getChartOptions();
+ const { formatter } = xAxis.axisLabel;
+ return formatter(date);
+ };
+
+ it('x-axis is formatted correctly in AM/PM format', () => {
+ expect(useXAxisFormatter(mockDate)).toEqual('8:00 PM');
+ });
+
+ describe('when in PT timezone', () => {
+ beforeAll(() => {
+ timezoneMock.register('US/Pacific');
+ });
+
+ afterAll(() => {
+ timezoneMock.unregister();
+ });
+
+ it('by default, values are formatted in PT', () => {
+ createWrapper();
+ expect(useXAxisFormatter(mockDate)).toEqual('1:00 PM');
+ });
+
+ it('when the chart uses local timezone, y-axis is formatted in PT', () => {
+ createWrapper({ timezone: 'LOCAL' });
+ expect(useXAxisFormatter(mockDate)).toEqual('1:00 PM');
+ });
+
+ it('when the chart uses UTC, y-axis is formatted in UTC', () => {
+ createWrapper({ timezone: 'UTC' });
+ expect(useXAxisFormatter(mockDate)).toEqual('8:00 PM');
+ });
+ });
+ });
+
describe('yAxisLabel', () => {
it('y-axis is configured correctly', () => {
const { yAxis } = getChartOptions();
@@ -544,7 +608,7 @@ describe('Time series component', () => {
});
afterEach(() => {
- timeSeriesChart.destroy();
+ wrapper.destroy();
});
});
@@ -562,19 +626,14 @@ describe('Time series component', () => {
glChartComponents.forEach(dynamicComponent => {
describe(`GitLab UI: ${dynamicComponent.chartType}`, () => {
- let timeSeriesAreaChart;
- const findChartComponent = () => timeSeriesAreaChart.find(dynamicComponent.component);
+ const findChartComponent = () => wrapper.find(dynamicComponent.component);
- beforeEach(done => {
- timeSeriesAreaChart = createWrapper(
- { ...mockGraphData, type: dynamicComponent.chartType },
+ beforeEach(() => {
+ createWrapper(
+ { graphData: { ...mockGraphData, type: dynamicComponent.chartType } },
mount,
);
- timeSeriesAreaChart.vm.$nextTick(done);
- });
-
- afterEach(() => {
- timeSeriesAreaChart.destroy();
+ return wrapper.vm.$nextTick();
});
it('is a Vue instance', () => {
@@ -585,21 +644,20 @@ describe('Time series component', () => {
it('receives data properties needed for proper chart render', () => {
const props = findChartComponent().props();
- expect(props.data).toBe(timeSeriesAreaChart.vm.chartData);
- expect(props.option).toBe(timeSeriesAreaChart.vm.chartOptions);
- expect(props.formatTooltipText).toBe(timeSeriesAreaChart.vm.formatTooltipText);
- expect(props.thresholds).toBe(timeSeriesAreaChart.vm.thresholds);
+ expect(props.data).toBe(wrapper.vm.chartData);
+ expect(props.option).toBe(wrapper.vm.chartOptions);
+ expect(props.formatTooltipText).toBe(wrapper.vm.formatTooltipText);
+ expect(props.thresholds).toBe(wrapper.vm.thresholds);
});
- it('recieves a tooltip title', done => {
+ it('receives a tooltip title', () => {
const mockTitle = 'mockTitle';
- timeSeriesAreaChart.vm.tooltip.title = mockTitle;
+ wrapper.vm.tooltip.title = mockTitle;
- timeSeriesAreaChart.vm.$nextTick(() => {
+ return wrapper.vm.$nextTick(() => {
expect(
shallowWrapperContainsSlotText(findChartComponent(), 'tooltipTitle', mockTitle),
).toBe(true);
- done();
});
});
@@ -607,13 +665,13 @@ describe('Time series component', () => {
const mockSha = 'mockSha';
const commitUrl = `${mockProjectDir}/-/commit/${mockSha}`;
- beforeEach(done => {
- timeSeriesAreaChart.setData({
+ beforeEach(() => {
+ wrapper.setData({
tooltip: {
type: 'deployments',
},
});
- timeSeriesAreaChart.vm.$nextTick(done);
+ return wrapper.vm.$nextTick();
});
it('uses deployment title', () => {
@@ -622,16 +680,15 @@ describe('Time series component', () => {
).toBe(true);
});
- it('renders clickable commit sha in tooltip content', done => {
- timeSeriesAreaChart.vm.tooltip.sha = mockSha;
- timeSeriesAreaChart.vm.tooltip.commitUrl = commitUrl;
+ it('renders clickable commit sha in tooltip content', () => {
+ wrapper.vm.tooltip.sha = mockSha;
+ wrapper.vm.tooltip.commitUrl = commitUrl;
- timeSeriesAreaChart.vm.$nextTick(() => {
- const commitLink = timeSeriesAreaChart.find(GlLink);
+ return wrapper.vm.$nextTick(() => {
+ const commitLink = wrapper.find(GlLink);
expect(shallowWrapperContainsSlotText(commitLink, 'default', mockSha)).toBe(true);
expect(commitLink.attributes('href')).toEqual(commitUrl);
- done();
});
});
});
@@ -642,30 +699,26 @@ describe('Time series component', () => {
describe('with multiple time series', () => {
describe('General functions', () => {
- let timeSeriesChart;
-
- beforeEach(done => {
+ beforeEach(() => {
store = createStore();
const graphData = cloneDeep(metricsDashboardViewModel.panelGroups[0].panels[3]);
graphData.metrics.forEach(metric =>
Object.assign(metric, { result: metricResultStatus.result }),
);
- timeSeriesChart = createWrapper({ ...graphData, type: 'area-chart' }, mount);
- timeSeriesChart.vm.$nextTick(done);
+ createWrapper({ graphData: { ...graphData, type: 'area-chart' } }, mount);
+ return wrapper.vm.$nextTick();
});
afterEach(() => {
- timeSeriesChart.destroy();
+ wrapper.destroy();
});
describe('Color match', () => {
let lineColors;
beforeEach(() => {
- lineColors = timeSeriesChart
- .find(GlAreaChart)
- .vm.series.map(item => item.lineStyle.color);
+ lineColors = wrapper.find(GlAreaChart).vm.series.map(item => item.lineStyle.color);
});
it('should contain different colors for contiguous time series', () => {
@@ -675,7 +728,7 @@ describe('Time series component', () => {
});
it('should match series color with tooltip label color', () => {
- const labels = timeSeriesChart.findAll(GlChartSeriesLabel);
+ const labels = wrapper.findAll(GlChartSeriesLabel);
lineColors.forEach((color, index) => {
const labelColor = labels.at(index).props('color');
@@ -684,7 +737,7 @@ describe('Time series component', () => {
});
it('should match series color with legend color', () => {
- const legendColors = timeSeriesChart
+ const legendColors = wrapper
.find(GlChartLegend)
.props('seriesInfo')
.map(item => item.color);
@@ -696,4 +749,45 @@ describe('Time series component', () => {
});
});
});
+
+ describe('legend layout', () => {
+ const findLegend = () => wrapper.find(GlChartLegend);
+
+ beforeEach(() => {
+ createWrapper(mockGraphData, mount);
+ return wrapper.vm.$nextTick();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('should render a tabular legend layout by default', () => {
+ expect(findLegend().props('layout')).toBe('table');
+ });
+
+ describe('when inline legend layout prop is set', () => {
+ beforeEach(() => {
+ wrapper.setProps({
+ legendLayout: 'inline',
+ });
+ });
+
+ it('should render an inline legend layout', () => {
+ expect(findLegend().props('layout')).toBe('inline');
+ });
+ });
+
+ describe('when table legend layout prop is set', () => {
+ beforeEach(() => {
+ wrapper.setProps({
+ legendLayout: 'table',
+ });
+ });
+
+ it('should render a tabular legend layout', () => {
+ expect(findLegend().props('layout')).toBe('table');
+ });
+ });
+ });
});
diff --git a/spec/frontend/monitoring/components/dashboard_panel_spec.js b/spec/frontend/monitoring/components/dashboard_panel_spec.js
index f8c9bd56721..0ad6e04588f 100644
--- a/spec/frontend/monitoring/components/dashboard_panel_spec.js
+++ b/spec/frontend/monitoring/components/dashboard_panel_spec.js
@@ -4,7 +4,7 @@ import AxiosMockAdapter from 'axios-mock-adapter';
import { setTestTimeout } from 'helpers/timeout';
import invalidUrl from '~/lib/utils/invalid_url';
import axios from '~/lib/utils/axios_utils';
-import { GlDropdownItem } from '@gitlab/ui';
+import { GlNewDropdownItem as GlDropdownItem } from '@gitlab/ui';
import AlertWidget from '~/monitoring/components/alert_widget.vue';
import DashboardPanel from '~/monitoring/components/dashboard_panel.vue';
@@ -55,7 +55,9 @@ describe('Dashboard Panel', () => {
const findCopyLink = () => wrapper.find({ ref: 'copyChartLink' });
const findTimeChart = () => wrapper.find({ ref: 'timeSeriesChart' });
const findTitle = () => wrapper.find({ ref: 'graphTitle' });
- const findContextualMenu = () => wrapper.find({ ref: 'contextualMenu' });
+ const findCtxMenu = () => wrapper.find({ ref: 'contextualMenu' });
+ const findMenuItems = () => wrapper.findAll(GlDropdownItem);
+ const findMenuItemByText = text => findMenuItems().filter(i => i.text() === text);
const createWrapper = (props, options) => {
wrapper = shallowMount(DashboardPanel, {
@@ -70,6 +72,15 @@ describe('Dashboard Panel', () => {
});
};
+ const mockGetterReturnValue = (getter, value) => {
+ jest.spyOn(monitoringDashboard.getters, getter).mockReturnValue(value);
+ store = new Vuex.Store({
+ modules: {
+ monitoringDashboard,
+ },
+ });
+ };
+
beforeEach(() => {
setTestTimeout(1000);
@@ -119,13 +130,17 @@ describe('Dashboard Panel', () => {
});
it('does not contain graph widgets', () => {
- expect(findContextualMenu().exists()).toBe(false);
+ expect(findCtxMenu().exists()).toBe(false);
});
it('The Empty Chart component is rendered and is a Vue instance', () => {
expect(wrapper.find(MonitorEmptyChart).exists()).toBe(true);
expect(wrapper.find(MonitorEmptyChart).isVueInstance()).toBe(true);
});
+
+ it('does not contain a tabindex attribute', () => {
+ expect(wrapper.find(MonitorEmptyChart).contains('[tabindex]')).toBe(false);
+ });
});
describe('When graphData is null', () => {
@@ -148,7 +163,7 @@ describe('Dashboard Panel', () => {
});
it('does not contain graph widgets', () => {
- expect(findContextualMenu().exists()).toBe(false);
+ expect(findCtxMenu().exists()).toBe(false);
});
it('The Empty Chart component is rendered and is a Vue instance', () => {
@@ -171,7 +186,7 @@ describe('Dashboard Panel', () => {
});
it('contains graph widgets', () => {
- expect(findContextualMenu().exists()).toBe(true);
+ expect(findCtxMenu().exists()).toBe(true);
expect(wrapper.find({ ref: 'downloadCsvLink' }).exists()).toBe(true);
});
@@ -367,7 +382,7 @@ describe('Dashboard Panel', () => {
});
});
- describe('when cliboard data is available', () => {
+ describe('when clipboard data is available', () => {
const clipboardText = 'A value to copy.';
beforeEach(() => {
@@ -392,7 +407,7 @@ describe('Dashboard Panel', () => {
});
});
- describe('when cliboard data is not available', () => {
+ describe('when clipboard data is not available', () => {
it('there is no "copy to clipboard" link for a null value', () => {
createWrapper({ clipboardText: null });
expect(findCopyLink().exists()).toBe(false);
@@ -498,6 +513,34 @@ describe('Dashboard Panel', () => {
});
});
+ describe('panel timezone', () => {
+ it('displays a time chart in local timezone', () => {
+ createWrapper();
+ expect(findTimeChart().props('timezone')).toBe('LOCAL');
+ });
+
+ it('displays a heatmap in local timezone', () => {
+ createWrapper({ graphData: graphDataPrometheusQueryRangeMultiTrack });
+ expect(wrapper.find(MonitorHeatmapChart).props('timezone')).toBe('LOCAL');
+ });
+
+ describe('when timezone is set to UTC', () => {
+ beforeEach(() => {
+ store = createStore({ dashboardTimezone: 'UTC' });
+ });
+
+ it('displays a time chart with UTC', () => {
+ createWrapper();
+ expect(findTimeChart().props('timezone')).toBe('UTC');
+ });
+
+ it('displays a heatmap with UTC', () => {
+ createWrapper({ graphData: graphDataPrometheusQueryRangeMultiTrack });
+ expect(wrapper.find(MonitorHeatmapChart).props('timezone')).toBe('UTC');
+ });
+ });
+ });
+
describe('Expand to full screen', () => {
const findExpandBtn = () => wrapper.find({ ref: 'expandBtn' });
@@ -530,17 +573,9 @@ describe('Dashboard Panel', () => {
const setMetricsSavedToDb = val =>
monitoringDashboard.getters.metricsSavedToDb.mockReturnValue(val);
const findAlertsWidget = () => wrapper.find(AlertWidget);
- const findMenuItemAlert = () =>
- wrapper.findAll(GlDropdownItem).filter(i => i.text() === 'Alerts');
beforeEach(() => {
- jest.spyOn(monitoringDashboard.getters, 'metricsSavedToDb').mockReturnValue([]);
-
- store = new Vuex.Store({
- modules: {
- monitoringDashboard,
- },
- });
+ mockGetterReturnValue('metricsSavedToDb', []);
createWrapper();
});
@@ -569,8 +604,99 @@ describe('Dashboard Panel', () => {
});
it(`${showsDesc} alert configuration`, () => {
- expect(findMenuItemAlert().exists()).toBe(isShown);
+ expect(findMenuItemByText('Alerts').exists()).toBe(isShown);
});
});
});
+
+ describe('When graphData contains links', () => {
+ const findManageLinksItem = () => wrapper.find({ ref: 'manageLinksItem' });
+ const mockLinks = [
+ {
+ url: 'https://example.com',
+ title: 'Example 1',
+ },
+ {
+ url: 'https://gitlab.com',
+ title: 'Example 2',
+ },
+ ];
+ const createWrapperWithLinks = (links = mockLinks) => {
+ createWrapper({
+ graphData: {
+ ...graphData,
+ links,
+ },
+ });
+ };
+
+ it('custom links are shown', () => {
+ createWrapperWithLinks();
+
+ mockLinks.forEach(({ url, title }) => {
+ const link = findMenuItemByText(title).at(0);
+
+ expect(link.exists()).toBe(true);
+ expect(link.attributes('href')).toBe(url);
+ });
+ });
+
+ it("custom links don't show unsecure content", () => {
+ createWrapperWithLinks([
+ {
+ title: '<script>alert("XSS")</script>',
+ url: 'http://example.com',
+ },
+ ]);
+
+ expect(findMenuItems().at(1).element.innerHTML).toBe(
+ '&lt;script&gt;alert("XSS")&lt;/script&gt;',
+ );
+ });
+
+ it("custom links don't show unsecure href attributes", () => {
+ const title = 'Owned!';
+
+ createWrapperWithLinks([
+ {
+ title,
+ // eslint-disable-next-line no-script-url
+ url: 'javascript:alert("Evil")',
+ },
+ ]);
+
+ const link = findMenuItemByText(title).at(0);
+ expect(link.attributes('href')).toBe('#');
+ });
+
+ it('when an editable dashboard is selected, shows `Manage chart links` link to the blob path', () => {
+ const editUrl = '/edit';
+ mockGetterReturnValue('selectedDashboard', {
+ can_edit: true,
+ project_blob_path: editUrl,
+ });
+ createWrapperWithLinks();
+
+ expect(findManageLinksItem().exists()).toBe(true);
+ expect(findManageLinksItem().attributes('href')).toBe(editUrl);
+ });
+
+ it('when no dashboard is selected, does not show `Manage chart links`', () => {
+ mockGetterReturnValue('selectedDashboard', null);
+ createWrapperWithLinks();
+
+ expect(findManageLinksItem().exists()).toBe(false);
+ });
+
+ it('when non-editable dashboard is selected, does not show `Manage chart links`', () => {
+ const editUrl = '/edit';
+ mockGetterReturnValue('selectedDashboard', {
+ can_edit: false,
+ project_blob_path: editUrl,
+ });
+ createWrapperWithLinks();
+
+ expect(findManageLinksItem().exists()).toBe(false);
+ });
+ });
});
diff --git a/spec/frontend/monitoring/components/dashboard_spec.js b/spec/frontend/monitoring/components/dashboard_spec.js
index b2c9fe93cde..7bb4c68b4cd 100644
--- a/spec/frontend/monitoring/components/dashboard_spec.js
+++ b/spec/frontend/monitoring/components/dashboard_spec.js
@@ -6,16 +6,17 @@ import { objectToQuery } from '~/lib/utils/url_utility';
import VueDraggable from 'vuedraggable';
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
-import statusCodes from '~/lib/utils/http_status';
import { metricStates } from '~/monitoring/constants';
import Dashboard from '~/monitoring/components/dashboard.vue';
+import DashboardHeader from '~/monitoring/components/dashboard_header.vue';
import DateTimePicker from '~/vue_shared/components/date_time_picker/date_time_picker.vue';
import CustomMetricsFormFields from '~/custom_metrics/components/custom_metrics_form_fields.vue';
import DashboardsDropdown from '~/monitoring/components/dashboards_dropdown.vue';
import EmptyState from '~/monitoring/components/empty_state.vue';
import GroupEmptyState from '~/monitoring/components/group_empty_state.vue';
import DashboardPanel from '~/monitoring/components/dashboard_panel.vue';
+import LinksSection from '~/monitoring/components/links_section.vue';
import { createStore } from '~/monitoring/stores';
import * as types from '~/monitoring/stores/mutation_types';
import {
@@ -24,6 +25,7 @@ import {
setMetricResult,
setupStoreWithData,
setupStoreWithVariable,
+ setupStoreWithLinks,
} from '../store_utils';
import { environmentData, dashboardGitResponse, propsData } from '../mock_data';
import { metricsDashboardViewModel, metricsDashboardPanelCount } from '../fixture_data';
@@ -36,7 +38,9 @@ describe('Dashboard', () => {
let wrapper;
let mock;
- const findEnvironmentsDropdown = () => wrapper.find({ ref: 'monitorEnvironmentsDropdown' });
+ const findDashboardHeader = () => wrapper.find(DashboardHeader);
+ const findEnvironmentsDropdown = () =>
+ findDashboardHeader().find({ ref: 'monitorEnvironmentsDropdown' });
const findAllEnvironmentsDropdownItems = () => findEnvironmentsDropdown().findAll(GlDropdownItem);
const setSearchTerm = searchTerm => {
store.commit(`monitoringDashboard/${types.SET_ENVIRONMENTS_FILTER}`, searchTerm);
@@ -46,6 +50,9 @@ describe('Dashboard', () => {
wrapper = shallowMount(Dashboard, {
propsData: { ...propsData, ...props },
store,
+ stubs: {
+ DashboardHeader,
+ },
...options,
});
};
@@ -54,7 +61,11 @@ describe('Dashboard', () => {
wrapper = mount(Dashboard, {
propsData: { ...propsData, ...props },
store,
- stubs: ['graph-group', 'dashboard-panel'],
+ stubs: {
+ 'graph-group': true,
+ 'dashboard-panel': true,
+ 'dashboard-header': DashboardHeader,
+ },
...options,
});
};
@@ -80,19 +91,6 @@ describe('Dashboard', () => {
it('shows the environment selector', () => {
expect(findEnvironmentsDropdown().exists()).toBe(true);
});
-
- it('sets initial state', () => {
- expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/setInitialState', {
- currentDashboard: '',
- currentEnvironmentName: 'production',
- dashboardEndpoint: 'https://invalid',
- dashboardsEndpoint: 'https://invalid',
- deploymentsEndpoint: null,
- logsPath: '/path/to/logs',
- metricsEndpoint: 'http://test.host/monitoring/mock',
- projectPath: '/path/to/project',
- });
- });
});
describe('no data found', () => {
@@ -288,7 +286,10 @@ describe('Dashboard', () => {
it('URL is updated with panel parameters and custom dashboard', () => {
const dashboard = 'dashboard.yml';
- createMountedWrapper({ hasMetrics: true, currentDashboard: dashboard });
+ store.commit(`monitoringDashboard/${types.SET_INITIAL_STATE}`, {
+ currentDashboard: dashboard,
+ });
+ createMountedWrapper({ hasMetrics: true });
expandPanel(group, panel);
const expectedSearch = objectToQuery({
@@ -326,8 +327,10 @@ describe('Dashboard', () => {
describe('when all requests have been commited by the store', () => {
beforeEach(() => {
+ store.commit(`monitoringDashboard/${types.SET_INITIAL_STATE}`, {
+ currentEnvironmentName: 'production',
+ });
createMountedWrapper({ hasMetrics: true });
-
setupStoreWithData(store);
return wrapper.vm.$nextTick();
@@ -345,7 +348,9 @@ describe('Dashboard', () => {
});
});
- it('renders the environments dropdown with a single active element', () => {
+ // Note: This test is not working, .active does not show the active environment
+ // eslint-disable-next-line jest/no-disabled-tests
+ it.skip('renders the environments dropdown with a single active element', () => {
const activeItem = findAllEnvironmentsDropdownItems().wrappers.filter(itemWrapper =>
itemWrapper.find('.active').exists(),
);
@@ -355,7 +360,7 @@ describe('Dashboard', () => {
});
describe('star dashboards', () => {
- const findToggleStar = () => wrapper.find({ ref: 'toggleStarBtn' });
+ const findToggleStar = () => wrapper.find(DashboardHeader).find({ ref: 'toggleStarBtn' });
const findToggleStarIcon = () => findToggleStar().find(GlIcon);
beforeEach(() => {
@@ -459,7 +464,7 @@ describe('Dashboard', () => {
setupStoreWithData(store);
return wrapper.vm.$nextTick().then(() => {
- const refreshBtn = wrapper.findAll({ ref: 'refreshDashboardBtn' });
+ const refreshBtn = wrapper.find(DashboardHeader).findAll({ ref: 'refreshDashboardBtn' });
expect(refreshBtn).toHaveLength(1);
expect(refreshBtn.is(GlDeprecatedButton)).toBe(true);
@@ -480,6 +485,21 @@ describe('Dashboard', () => {
});
});
+ describe('links section', () => {
+ beforeEach(() => {
+ createShallowWrapper({ hasMetrics: true });
+ setupStoreWithData(store);
+ setupStoreWithLinks(store);
+
+ return wrapper.vm.$nextTick();
+ });
+
+ it('shows the links section', () => {
+ expect(wrapper.vm.shouldShowLinksSection).toBe(true);
+ expect(wrapper.find(LinksSection)).toExist();
+ });
+ });
+
describe('single panel expands to "full screen" mode', () => {
const findExpandedPanel = () => wrapper.find({ ref: 'expandedPanel' });
@@ -630,7 +650,12 @@ describe('Dashboard', () => {
});
it('renders a search input', () => {
- expect(wrapper.find({ ref: 'monitorEnvironmentsDropdownSearch' }).exists()).toBe(true);
+ expect(
+ wrapper
+ .find(DashboardHeader)
+ .find({ ref: 'monitorEnvironmentsDropdownSearch' })
+ .exists(),
+ ).toBe(true);
});
it('renders dropdown items', () => {
@@ -666,7 +691,12 @@ describe('Dashboard', () => {
setSearchTerm(searchTerm);
return wrapper.vm.$nextTick(() => {
- expect(wrapper.find({ ref: 'monitorEnvironmentsDropdownMsg' }).isVisible()).toBe(true);
+ expect(
+ wrapper
+ .find(DashboardHeader)
+ .find({ ref: 'monitorEnvironmentsDropdownMsg' })
+ .isVisible(),
+ ).toBe(true);
});
});
@@ -676,7 +706,12 @@ describe('Dashboard', () => {
return wrapper.vm
.$nextTick()
.then(() => {
- expect(wrapper.find({ ref: 'monitorEnvironmentsDropdownLoading' }).exists()).toBe(true);
+ expect(
+ wrapper
+ .find(DashboardHeader)
+ .find({ ref: 'monitorEnvironmentsDropdownLoading' })
+ .exists(),
+ ).toBe(true);
})
.then(() => {
store.commit(
@@ -685,7 +720,12 @@ describe('Dashboard', () => {
);
})
.then(() => {
- expect(wrapper.find({ ref: 'monitorEnvironmentsDropdownLoading' }).exists()).toBe(false);
+ expect(
+ wrapper
+ .find(DashboardHeader)
+ .find({ ref: 'monitorEnvironmentsDropdownLoading' })
+ .exists(),
+ ).toBe(false);
});
});
});
@@ -783,9 +823,59 @@ describe('Dashboard', () => {
});
});
+ describe('dashboard timezone', () => {
+ const setupWithTimezone = value => {
+ store = createStore({ dashboardTimezone: value });
+ setupStoreWithData(store);
+ createShallowWrapper({ hasMetrics: true });
+ return wrapper.vm.$nextTick;
+ };
+
+ describe('local timezone is enabled by default', () => {
+ beforeEach(() => {
+ return setupWithTimezone();
+ });
+
+ it('shows the data time picker in local timezone', () => {
+ expect(
+ findDashboardHeader()
+ .find(DateTimePicker)
+ .props('utc'),
+ ).toBe(false);
+ });
+ });
+
+ describe('when LOCAL timezone is enabled', () => {
+ beforeEach(() => {
+ return setupWithTimezone('LOCAL');
+ });
+
+ it('shows the data time picker in local timezone', () => {
+ expect(
+ findDashboardHeader()
+ .find(DateTimePicker)
+ .props('utc'),
+ ).toBe(false);
+ });
+ });
+
+ describe('when UTC timezone is enabled', () => {
+ beforeEach(() => {
+ return setupWithTimezone('UTC');
+ });
+
+ it('shows the data time picker in UTC format', () => {
+ expect(
+ findDashboardHeader()
+ .find(DateTimePicker)
+ .props('utc'),
+ ).toBe(true);
+ });
+ });
+ });
+
describe('cluster health', () => {
beforeEach(() => {
- mock.onGet(propsData.metricsEndpoint).reply(statusCodes.OK, JSON.stringify({}));
createShallowWrapper({ hasMetrics: true, showHeader: false });
// all_dashboards is not defined in health dashboards
@@ -830,6 +920,62 @@ describe('Dashboard', () => {
});
});
+ describe('document title', () => {
+ const originalTitle = 'Original Title';
+ const defaultDashboardName = dashboardGitResponse[0].display_name;
+
+ beforeEach(() => {
+ document.title = originalTitle;
+ createShallowWrapper({ hasMetrics: true });
+ });
+
+ afterAll(() => {
+ document.title = '';
+ });
+
+ it('is prepended with default dashboard name by default', () => {
+ setupAllDashboards(store);
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(document.title.startsWith(`${defaultDashboardName} · `)).toBe(true);
+ });
+ });
+
+ it('is prepended with dashboard name if path is known', () => {
+ const dashboard = dashboardGitResponse[1];
+ const currentDashboard = dashboard.path;
+
+ setupAllDashboards(store, currentDashboard);
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(document.title.startsWith(`${dashboard.display_name} · `)).toBe(true);
+ });
+ });
+
+ it('is prepended with default dashboard name is path is not known', () => {
+ setupAllDashboards(store, 'unknown/path');
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(document.title.startsWith(`${defaultDashboardName} · `)).toBe(true);
+ });
+ });
+
+ it('is not modified when dashboard name is not provided', () => {
+ const dashboard = { ...dashboardGitResponse[1], display_name: null };
+ const currentDashboard = dashboard.path;
+
+ store.commit(`monitoringDashboard/${types.SET_ALL_DASHBOARDS}`, [dashboard]);
+
+ store.commit(`monitoringDashboard/${types.SET_INITIAL_STATE}`, {
+ currentDashboard,
+ });
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(document.title).toBe(originalTitle);
+ });
+ });
+ });
+
describe('Dashboard dropdown', () => {
beforeEach(() => {
createMountedWrapper({ hasMetrics: true });
@@ -877,7 +1023,10 @@ describe('Dashboard', () => {
beforeEach(() => {
setupStoreWithData(store);
- createShallowWrapper({ hasMetrics: true, currentDashboard });
+ store.commit(`monitoringDashboard/${types.SET_INITIAL_STATE}`, {
+ currentDashboard,
+ });
+ createShallowWrapper({ hasMetrics: true });
return wrapper.vm.$nextTick();
});
@@ -893,7 +1042,8 @@ describe('Dashboard', () => {
});
describe('add custom metrics', () => {
- const findAddMetricButton = () => wrapper.vm.$refs.addMetricBtn;
+ const findAddMetricButton = () => wrapper.find(DashboardHeader).find({ ref: 'addMetricBtn' });
+
describe('when not available', () => {
beforeEach(() => {
createShallowWrapper({
@@ -902,7 +1052,7 @@ describe('Dashboard', () => {
});
});
it('does not render add button on the dashboard', () => {
- expect(findAddMetricButton()).toBeUndefined();
+ expect(findAddMetricButton().exists()).toBe(false);
});
});
@@ -935,10 +1085,9 @@ describe('Dashboard', () => {
expect(wrapper.find(GlModal).attributes().modalid).toBe('add-metric');
});
it('adding new metric is tracked', done => {
- const submitButton = wrapper.vm.$refs.submitCustomMetricsFormBtn;
- wrapper.setData({
- formIsValid: true,
- });
+ const submitButton = wrapper
+ .find(DashboardHeader)
+ .find({ ref: 'submitCustomMetricsFormBtn' }).vm;
wrapper.vm.$nextTick(() => {
submitButton.$el.click();
wrapper.vm.$nextTick(() => {
diff --git a/spec/frontend/monitoring/components/dashboard_template_spec.js b/spec/frontend/monitoring/components/dashboard_template_spec.js
index cc0ac348b11..a1a450d4abe 100644
--- a/spec/frontend/monitoring/components/dashboard_template_spec.js
+++ b/spec/frontend/monitoring/components/dashboard_template_spec.js
@@ -2,6 +2,7 @@ import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import Dashboard from '~/monitoring/components/dashboard.vue';
+import DashboardHeader from '~/monitoring/components/dashboard_header.vue';
import { createStore } from '~/monitoring/stores';
import { setupAllDashboards } from '../store_utils';
import { propsData } from '../mock_data';
@@ -14,7 +15,9 @@ describe('Dashboard template', () => {
let mock;
beforeEach(() => {
- store = createStore();
+ store = createStore({
+ currentEnvironmentName: 'production',
+ });
mock = new MockAdapter(axios);
setupAllDashboards(store);
@@ -25,7 +28,13 @@ describe('Dashboard template', () => {
});
it('matches the default snapshot', () => {
- wrapper = shallowMount(Dashboard, { propsData: { ...propsData }, store });
+ wrapper = shallowMount(Dashboard, {
+ propsData: { ...propsData },
+ store,
+ stubs: {
+ DashboardHeader,
+ },
+ });
expect(wrapper.element).toMatchSnapshot();
});
diff --git a/spec/frontend/monitoring/components/dashboard_url_time_spec.js b/spec/frontend/monitoring/components/dashboard_url_time_spec.js
index 9bba5280007..a74c621db9b 100644
--- a/spec/frontend/monitoring/components/dashboard_url_time_spec.js
+++ b/spec/frontend/monitoring/components/dashboard_url_time_spec.js
@@ -12,6 +12,7 @@ import axios from '~/lib/utils/axios_utils';
import { mockProjectDir, propsData } from '../mock_data';
import Dashboard from '~/monitoring/components/dashboard.vue';
+import DashboardHeader from '~/monitoring/components/dashboard_header.vue';
import { createStore } from '~/monitoring/stores';
import { defaultTimeRange } from '~/vue_shared/constants';
@@ -27,12 +28,12 @@ describe('dashboard invalid url parameters', () => {
wrapper = mount(Dashboard, {
propsData: { ...propsData, ...props },
store,
- stubs: ['graph-group', 'dashboard-panel'],
+ stubs: { 'graph-group': true, 'dashboard-panel': true, 'dashboard-header': DashboardHeader },
...options,
});
};
- const findDateTimePicker = () => wrapper.find({ ref: 'dateTimePicker' });
+ const findDateTimePicker = () => wrapper.find(DashboardHeader).find({ ref: 'dateTimePicker' });
beforeEach(() => {
store = createStore();
diff --git a/spec/frontend/monitoring/components/duplicate_dashboard_form_spec.js b/spec/frontend/monitoring/components/duplicate_dashboard_form_spec.js
index 8ab7c8b9e50..29e4c4514fe 100644
--- a/spec/frontend/monitoring/components/duplicate_dashboard_form_spec.js
+++ b/spec/frontend/monitoring/components/duplicate_dashboard_form_spec.js
@@ -10,6 +10,8 @@ const createMountedWrapper = (props = {}) => {
wrapper = mount(DuplicateDashboardForm, {
propsData: { ...props },
sync: false,
+ // We need to attach to document, so that `document.activeElement` is properly set in jsdom
+ attachToDocument: true,
});
};
diff --git a/spec/frontend/monitoring/components/embeds/metric_embed_spec.js b/spec/frontend/monitoring/components/embeds/metric_embed_spec.js
index f23823ccad6..4e7fee81d66 100644
--- a/spec/frontend/monitoring/components/embeds/metric_embed_spec.js
+++ b/spec/frontend/monitoring/components/embeds/metric_embed_spec.js
@@ -4,6 +4,7 @@ import DashboardPanel from '~/monitoring/components/dashboard_panel.vue';
import { TEST_HOST } from 'helpers/test_constants';
import MetricEmbed from '~/monitoring/components/embeds/metric_embed.vue';
import { groups, initialState, metricsData, metricsWithData } from './mock_data';
+import { setHTMLFixture } from 'helpers/fixtures';
const localVue = createLocalVue();
localVue.use(Vuex);
@@ -25,6 +26,8 @@ describe('MetricEmbed', () => {
}
beforeEach(() => {
+ setHTMLFixture('<div class="layout-page"></div>');
+
actions = {
setInitialState: jest.fn(),
setShowErrorBanner: jest.fn(),
diff --git a/spec/frontend/monitoring/components/embeds/mock_data.js b/spec/frontend/monitoring/components/embeds/mock_data.js
index 9cf66e52d22..e32e1a08cdb 100644
--- a/spec/frontend/monitoring/components/embeds/mock_data.js
+++ b/spec/frontend/monitoring/components/embeds/mock_data.js
@@ -52,7 +52,6 @@ export const initialState = () => ({
dashboard: {
panel_groups: [],
},
- useDashboardEndpoint: true,
});
export const initialEmbedGroupState = () => ({
diff --git a/spec/frontend/monitoring/components/graph_group_spec.js b/spec/frontend/monitoring/components/graph_group_spec.js
index 28a6af64394..92829135c0f 100644
--- a/spec/frontend/monitoring/components/graph_group_spec.js
+++ b/spec/frontend/monitoring/components/graph_group_spec.js
@@ -8,6 +8,7 @@ describe('Graph group component', () => {
const findGroup = () => wrapper.find({ ref: 'graph-group' });
const findContent = () => wrapper.find({ ref: 'graph-group-content' });
const findCaretIcon = () => wrapper.find(Icon);
+ const findToggleButton = () => wrapper.find('[data-testid="group-toggle-button"]');
const createComponent = propsData => {
wrapper = shallowMount(GraphGroup, {
@@ -41,6 +42,16 @@ describe('Graph group component', () => {
});
});
+ it('should contain a tabindex', () => {
+ expect(findGroup().contains('[tabindex]')).toBe(true);
+ });
+
+ it('should contain a tab index for the collapse button', () => {
+ const groupToggle = findToggleButton();
+
+ expect(groupToggle.contains('[tabindex]')).toBe(true);
+ });
+
it('should show the open the group when collapseGroup is set to true', () => {
wrapper.setProps({
collapseGroup: true,
@@ -69,6 +80,15 @@ describe('Graph group component', () => {
expect(wrapper.vm.caretIcon).toBe('angle-down');
});
+
+ it('should call collapse the graph group content when enter is pressed on the caret icon', () => {
+ const graphGroupContent = findContent();
+ const button = findToggleButton();
+
+ button.trigger('keyup.enter');
+
+ expect(graphGroupContent.isVisible()).toBe(false);
+ });
});
describe('When groups can not be collapsed', () => {
diff --git a/spec/frontend/monitoring/components/links_section_spec.js b/spec/frontend/monitoring/components/links_section_spec.js
new file mode 100644
index 00000000000..3b5b72d84ee
--- /dev/null
+++ b/spec/frontend/monitoring/components/links_section_spec.js
@@ -0,0 +1,64 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlLink } from '@gitlab/ui';
+import { createStore } from '~/monitoring/stores';
+import LinksSection from '~/monitoring/components/links_section.vue';
+
+describe('Links Section component', () => {
+ let store;
+ let wrapper;
+
+ const createShallowWrapper = () => {
+ wrapper = shallowMount(LinksSection, {
+ store,
+ });
+ };
+ const setState = links => {
+ store.state.monitoringDashboard = {
+ ...store.state.monitoringDashboard,
+ showEmptyState: false,
+ links,
+ };
+ };
+ const findLinks = () => wrapper.findAll(GlLink);
+
+ beforeEach(() => {
+ store = createStore();
+ createShallowWrapper();
+ });
+
+ it('does not render a section if no links are present', () => {
+ setState();
+
+ return wrapper.vm.$nextTick(() => {
+ expect(findLinks()).not.toExist();
+ });
+ });
+
+ it('renders a link inside a section', () => {
+ setState([
+ {
+ title: 'GitLab Website',
+ url: 'https://gitlab.com',
+ },
+ ]);
+
+ return wrapper.vm.$nextTick(() => {
+ expect(findLinks()).toHaveLength(1);
+ const firstLink = findLinks().at(0);
+
+ expect(firstLink.attributes('href')).toBe('https://gitlab.com');
+ expect(firstLink.text()).toBe('GitLab Website');
+ });
+ });
+
+ it('renders multiple links inside a section', () => {
+ const links = new Array(10)
+ .fill(null)
+ .map((_, i) => ({ title: `Title ${i}`, url: `https://gitlab.com/projects/${i}` }));
+ setState(links);
+
+ return wrapper.vm.$nextTick(() => {
+ expect(findLinks()).toHaveLength(10);
+ });
+ });
+});
diff --git a/spec/frontend/monitoring/components/variables_section_spec.js b/spec/frontend/monitoring/components/variables_section_spec.js
index 095d89c9231..fd814e81c8f 100644
--- a/spec/frontend/monitoring/components/variables_section_spec.js
+++ b/spec/frontend/monitoring/components/variables_section_spec.js
@@ -57,8 +57,7 @@ describe('Metrics dashboard/variables section component', () => {
});
describe('when changing the variable inputs', () => {
- const fetchDashboardData = jest.fn();
- const updateVariableValues = jest.fn();
+ const updateVariablesAndFetchData = jest.fn();
beforeEach(() => {
store = new Vuex.Store({
@@ -67,11 +66,10 @@ describe('Metrics dashboard/variables section component', () => {
namespaced: true,
state: {
showEmptyState: false,
- promVariables: sampleVariables,
+ variables: sampleVariables,
},
actions: {
- fetchDashboardData,
- updateVariableValues,
+ updateVariablesAndFetchData,
},
},
},
@@ -86,13 +84,12 @@ describe('Metrics dashboard/variables section component', () => {
firstInput.vm.$emit('onUpdate', 'label1', 'test');
return wrapper.vm.$nextTick(() => {
- expect(updateVariableValues).toHaveBeenCalled();
+ expect(updateVariablesAndFetchData).toHaveBeenCalled();
expect(mergeUrlParams).toHaveBeenCalledWith(
convertVariablesForURL(sampleVariables),
window.location.href,
);
expect(updateHistory).toHaveBeenCalled();
- expect(fetchDashboardData).toHaveBeenCalled();
});
});
@@ -102,13 +99,12 @@ describe('Metrics dashboard/variables section component', () => {
firstInput.vm.$emit('onUpdate', 'label1', 'test');
return wrapper.vm.$nextTick(() => {
- expect(updateVariableValues).toHaveBeenCalled();
+ expect(updateVariablesAndFetchData).toHaveBeenCalled();
expect(mergeUrlParams).toHaveBeenCalledWith(
convertVariablesForURL(sampleVariables),
window.location.href,
);
expect(updateHistory).toHaveBeenCalled();
- expect(fetchDashboardData).toHaveBeenCalled();
});
});
@@ -117,10 +113,9 @@ describe('Metrics dashboard/variables section component', () => {
firstInput.vm.$emit('onUpdate', 'label1', 'Simple text');
- expect(updateVariableValues).not.toHaveBeenCalled();
+ expect(updateVariablesAndFetchData).not.toHaveBeenCalled();
expect(mergeUrlParams).not.toHaveBeenCalled();
expect(updateHistory).not.toHaveBeenCalled();
- expect(fetchDashboardData).not.toHaveBeenCalled();
});
});
});
diff --git a/spec/frontend/monitoring/mock_data.js b/spec/frontend/monitoring/mock_data.js
index 4611e6f1b18..05b29e78ecd 100644
--- a/spec/frontend/monitoring/mock_data.js
+++ b/spec/frontend/monitoring/mock_data.js
@@ -11,17 +11,12 @@ export const propsData = {
settingsPath: '/path/to/settings',
clustersPath: '/path/to/clusters',
tagsPath: '/path/to/tags',
- projectPath: '/path/to/project',
- logsPath: '/path/to/logs',
defaultBranch: 'master',
- metricsEndpoint: mockApiEndpoint,
- deploymentsEndpoint: null,
emptyGettingStartedSvgPath: '/path/to/getting-started.svg',
emptyLoadingSvgPath: '/path/to/loading.svg',
emptyNoDataSvgPath: '/path/to/no-data.svg',
emptyNoDataSmallSvgPath: '/path/to/no-data-small.svg',
emptyUnableToConnectSvgPath: '/path/to/unable-to-connect.svg',
- currentEnvironmentName: 'production',
customMetricsAvailable: false,
customMetricsPath: '',
validateQueryPath: '',
@@ -472,9 +467,9 @@ export const stackedColumnMockedData = {
{
metric: {},
values: [
- ['2020-01-30 12:00:00', '5'],
- ['2020-01-30 12:01:00', '10'],
- ['2020-01-30 12:02:00', '15'],
+ ['2020-01-30T12:00:00.000Z', '5'],
+ ['2020-01-30T12:01:00.000Z', '10'],
+ ['2020-01-30T12:02:00.000Z', '15'],
],
},
],
@@ -490,9 +485,9 @@ export const stackedColumnMockedData = {
{
metric: {},
values: [
- ['2020-01-30 12:00:00', '20'],
- ['2020-01-30 12:01:00', '25'],
- ['2020-01-30 12:02:00', '30'],
+ ['2020-01-30T12:00:00.000Z', '20'],
+ ['2020-01-30T12:01:00.000Z', '25'],
+ ['2020-01-30T12:02:00.000Z', '30'],
],
},
],
@@ -563,6 +558,89 @@ export const mockLogsPath = '/mockLogsPath';
export const mockLogsHref = `${mockLogsPath}?duration_seconds=${mockTimeRange.duration.seconds}`;
+export const mockLinks = [
+ {
+ title: 'Job',
+ url: 'http://intel.com/bibendum/felis/sed/interdum/venenatis.png',
+ },
+ {
+ title: 'Solarbreeze',
+ url: 'http://ebay.co.uk/primis/in/faucibus.jsp',
+ },
+ {
+ title: 'Bentosanzap',
+ url: 'http://cargocollective.com/sociis/natoque/penatibus/et/magnis/dis.js',
+ },
+ {
+ title: 'Wrapsafe',
+ url: 'https://bloomberg.com/tempus/vel/pede/morbi.aspx',
+ },
+ {
+ title: 'Stronghold',
+ url: 'https://networkadvertising.org/primis/in/faucibus/orci/luctus/et/ultrices.html',
+ },
+ {
+ title: 'Lotstring',
+ url:
+ 'https://huffingtonpost.com/sapien/a/libero.aspx?et=lacus&ultrices=at&posuere=velit&cubilia=vivamus&curae=vel&duis=nulla&faucibus=eget&accumsan=eros&odio=elementum&curabitur=pellentesque&convallis=quisque&duis=porta&consequat=volutpat&dui=erat&nec=quisque&nisi=erat&volutpat=eros&eleifend=viverra&donec=eget&ut=congue&dolor=eget&morbi=semper&vel=rutrum&lectus=nulla&in=nunc&quam=purus&fringilla=phasellus&rhoncus=in&mauris=felis&enim=donec&leo=semper&rhoncus=sapien&sed=a&vestibulum=libero&sit=nam&amet=dui&cursus=proin&id=leo&turpis=odio&integer=porttitor&aliquet=id&massa=consequat&id=in&lobortis=consequat&convallis=ut&tortor=nulla&risus=sed&dapibus=accumsan&augue=felis&vel=ut&accumsan=at&tellus=dolor&nisi=quis&eu=odio',
+ },
+ {
+ title: 'Cardify',
+ url:
+ 'http://nature.com/imperdiet/et/commodo/vulputate/justo/in/blandit.json?tempus=posuere&semper=felis&est=sed&quam=lacus&pharetra=morbi&magna=sem&ac=mauris&consequat=laoreet&metus=ut&sapien=rhoncus&ut=aliquet&nunc=pulvinar&vestibulum=sed&ante=nisl&ipsum=nunc&primis=rhoncus&in=dui&faucibus=vel&orci=sem&luctus=sed&et=sagittis&ultrices=nam&posuere=congue&cubilia=risus&curae=semper&mauris=porta&viverra=volutpat&diam=quam&vitae=pede&quam=lobortis&suspendisse=ligula&potenti=sit&nullam=amet&porttitor=eleifend&lacus=pede&at=libero&turpis=quis',
+ },
+ {
+ title: 'Ventosanzap',
+ url:
+ 'http://stanford.edu/augue/vestibulum/ante/ipsum/primis/in/faucibus.xml?metus=morbi&sapien=quis&ut=tortor&nunc=id&vestibulum=nulla&ante=ultrices&ipsum=aliquet&primis=maecenas&in=leo&faucibus=odio&orci=condimentum&luctus=id&et=luctus&ultrices=nec&posuere=molestie&cubilia=sed&curae=justo&mauris=pellentesque&viverra=viverra&diam=pede&vitae=ac&quam=diam&suspendisse=cras&potenti=pellentesque&nullam=volutpat&porttitor=dui&lacus=maecenas&at=tristique&turpis=est&donec=et&posuere=tempus&metus=semper&vitae=est&ipsum=quam&aliquam=pharetra&non=magna&mauris=ac&morbi=consequat&non=metus',
+ },
+ {
+ title: 'Cardguard',
+ url:
+ 'https://google.com.hk/lacinia/eget/tincidunt/eget/tempus/vel.js?at=eget&turpis=nunc&a=donec',
+ },
+ {
+ title: 'Namfix',
+ url:
+ 'https://fotki.com/eget/rutrum/at/lorem.jsp?at=id&vulputate=nulla&vitae=ultrices&nisl=aliquet&aenean=maecenas&lectus=leo&pellentesque=odio&eget=condimentum&nunc=id&donec=luctus&quis=nec&orci=molestie&eget=sed&orci=justo&vehicula=pellentesque&condimentum=viverra&curabitur=pede&in=ac&libero=diam&ut=cras&massa=pellentesque&volutpat=volutpat&convallis=dui&morbi=maecenas&odio=tristique&odio=est&elementum=et&eu=tempus&interdum=semper&eu=est&tincidunt=quam&in=pharetra&leo=magna&maecenas=ac&pulvinar=consequat&lobortis=metus&est=sapien&phasellus=ut&sit=nunc&amet=vestibulum&erat=ante&nulla=ipsum&tempus=primis&vivamus=in&in=faucibus&felis=orci&eu=luctus&sapien=et&cursus=ultrices&vestibulum=posuere&proin=cubilia&eu=curae&mi=mauris&nulla=viverra&ac=diam&enim=vitae&in=quam&tempor=suspendisse&turpis=potenti&nec=nullam&euismod=porttitor&scelerisque=lacus&quam=at&turpis=turpis&adipiscing=donec&lorem=posuere&vitae=metus&mattis=vitae&nibh=ipsum&ligula=aliquam&nec=non&sem=mauris&duis=morbi&aliquam=non&convallis=lectus&nunc=aliquam&proin=sit&at=amet',
+ },
+ {
+ title: 'Alpha',
+ url:
+ 'http://bravesites.com/tempus/vel.jpg?risus=est&auctor=phasellus&sed=sit&tristique=amet&in=erat&tempus=nulla&sit=tempus&amet=vivamus&sem=in&fusce=felis&consequat=eu&nulla=sapien&nisl=cursus&nunc=vestibulum&nisl=proin&duis=eu&bibendum=mi&felis=nulla&sed=ac&interdum=enim&venenatis=in&turpis=tempor&enim=turpis&blandit=nec&mi=euismod&in=scelerisque&porttitor=quam&pede=turpis&justo=adipiscing&eu=lorem&massa=vitae&donec=mattis&dapibus=nibh&duis=ligula',
+ },
+ {
+ title: 'Sonsing',
+ url:
+ 'http://microsoft.com/blandit.js?quis=ante&lectus=vestibulum&suspendisse=ante&potenti=ipsum&in=primis&eleifend=in&quam=faucibus&a=orci&odio=luctus&in=et&hac=ultrices&habitasse=posuere&platea=cubilia&dictumst=curae&maecenas=duis&ut=faucibus&massa=accumsan&quis=odio&augue=curabitur&luctus=convallis&tincidunt=duis&nulla=consequat&mollis=dui&molestie=nec&lorem=nisi&quisque=volutpat&ut=eleifend&erat=donec&curabitur=ut&gravida=dolor&nisi=morbi&at=vel&nibh=lectus&in=in&hac=quam&habitasse=fringilla&platea=rhoncus&dictumst=mauris&aliquam=enim&augue=leo&quam=rhoncus&sollicitudin=sed&vitae=vestibulum&consectetuer=sit&eget=amet&rutrum=cursus&at=id&lorem=turpis&integer=integer&tincidunt=aliquet&ante=massa&vel=id&ipsum=lobortis&praesent=convallis&blandit=tortor&lacinia=risus&erat=dapibus&vestibulum=augue&sed=vel&magna=accumsan&at=tellus&nunc=nisi&commodo=eu&placerat=orci&praesent=mauris&blandit=lacinia&nam=sapien&nulla=quis&integer=libero',
+ },
+ {
+ title: 'Fintone',
+ url:
+ 'https://linkedin.com/duis/bibendum/felis/sed/interdum/venenatis.json?ut=justo&suscipit=sollicitudin&a=ut&feugiat=suscipit&et=a&eros=feugiat&vestibulum=et&ac=eros&est=vestibulum&lacinia=ac&nisi=est&venenatis=lacinia&tristique=nisi&fusce=venenatis&congue=tristique&diam=fusce&id=congue&ornare=diam&imperdiet=id&sapien=ornare&urna=imperdiet&pretium=sapien&nisl=urna&ut=pretium&volutpat=nisl&sapien=ut&arcu=volutpat&sed=sapien&augue=arcu&aliquam=sed&erat=augue&volutpat=aliquam&in=erat&congue=volutpat&etiam=in&justo=congue&etiam=etiam&pretium=justo&iaculis=etiam&justo=pretium&in=iaculis&hac=justo&habitasse=in&platea=hac&dictumst=habitasse&etiam=platea&faucibus=dictumst&cursus=etiam&urna=faucibus&ut=cursus&tellus=urna&nulla=ut&ut=tellus&erat=nulla&id=ut&mauris=erat&vulputate=id&elementum=mauris&nullam=vulputate&varius=elementum&nulla=nullam&facilisi=varius&cras=nulla&non=facilisi&velit=cras&nec=non&nisi=velit&vulputate=nec&nonummy=nisi&maecenas=vulputate&tincidunt=nonummy&lacus=maecenas&at=tincidunt&velit=lacus&vivamus=at&vel=velit&nulla=vivamus&eget=vel&eros=nulla&elementum=eget',
+ },
+ {
+ title: 'Fix San',
+ url:
+ 'http://pinterest.com/mi/in/porttitor/pede.png?varius=nibh&integer=quisque&ac=id&leo=justo&pellentesque=sit&ultrices=amet&mattis=sapien&odio=dignissim&donec=vestibulum&vitae=vestibulum&nisi=ante&nam=ipsum&ultrices=primis&libero=in&non=faucibus&mattis=orci&pulvinar=luctus&nulla=et&pede=ultrices&ullamcorper=posuere&augue=cubilia&a=curae&suscipit=nulla&nulla=dapibus&elit=dolor&ac=vel&nulla=est&sed=donec&vel=odio&enim=justo&sit=sollicitudin&amet=ut&nunc=suscipit&viverra=a&dapibus=feugiat&nulla=et&suscipit=eros&ligula=vestibulum&in=ac&lacus=est&curabitur=lacinia&at=nisi&ipsum=venenatis&ac=tristique&tellus=fusce&semper=congue&interdum=diam&mauris=id&ullamcorper=ornare&purus=imperdiet&sit=sapien&amet=urna&nulla=pretium&quisque=nisl&arcu=ut&libero=volutpat&rutrum=sapien&ac=arcu&lobortis=sed&vel=augue&dapibus=aliquam&at=erat&diam=volutpat&nam=in&tristique=congue&tortor=etiam',
+ },
+ {
+ title: 'Ronstring',
+ url:
+ 'https://ebay.com/ut/erat.aspx?nulla=sed&eget=nisl&eros=nunc&elementum=rhoncus&pellentesque=dui&quisque=vel&porta=sem&volutpat=sed&erat=sagittis&quisque=nam&erat=congue&eros=risus&viverra=semper&eget=porta&congue=volutpat&eget=quam&semper=pede&rutrum=lobortis&nulla=ligula',
+ },
+ {
+ title: 'It',
+ url:
+ 'http://symantec.com/tortor/sollicitudin/mi/sit/amet.json?in=nullam&libero=varius&ut=nulla&massa=facilisi&volutpat=cras&convallis=non&morbi=velit&odio=nec&odio=nisi&elementum=vulputate&eu=nonummy&interdum=maecenas&eu=tincidunt&tincidunt=lacus&in=at&leo=velit&maecenas=vivamus&pulvinar=vel&lobortis=nulla&est=eget&phasellus=eros&sit=elementum&amet=pellentesque&erat=quisque&nulla=porta&tempus=volutpat&vivamus=erat&in=quisque&felis=erat&eu=eros&sapien=viverra&cursus=eget&vestibulum=congue&proin=eget&eu=semper',
+ },
+ {
+ title: 'Andalax',
+ url:
+ 'https://acquirethisname.com/tortor/eu.js?volutpat=mauris&dui=laoreet&maecenas=ut&tristique=rhoncus&est=aliquet&et=pulvinar&tempus=sed&semper=nisl&est=nunc&quam=rhoncus&pharetra=dui&magna=vel&ac=sem&consequat=sed&metus=sagittis&sapien=nam&ut=congue&nunc=risus&vestibulum=semper&ante=porta&ipsum=volutpat&primis=quam&in=pede&faucibus=lobortis&orci=ligula&luctus=sit&et=amet&ultrices=eleifend&posuere=pede&cubilia=libero&curae=quis&mauris=orci&viverra=nullam&diam=molestie&vitae=nibh&quam=in&suspendisse=lectus&potenti=pellentesque&nullam=at&porttitor=nulla&lacus=suspendisse&at=potenti&turpis=cras&donec=in&posuere=purus&metus=eu&vitae=magna&ipsum=vulputate&aliquam=luctus&non=cum&mauris=sociis&morbi=natoque&non=penatibus&lectus=et&aliquam=magnis&sit=dis&amet=parturient&diam=montes&in=nascetur&magna=ridiculus&bibendum=mus',
+ },
+];
+
const templatingVariableTypes = {
text: {
simple: 'Simple text',
@@ -621,6 +699,19 @@ const templatingVariableTypes = {
],
},
},
+ withoutOptText: {
+ label: 'Options without text',
+ type: 'custom',
+ options: {
+ values: [
+ { value: 'value1' },
+ {
+ value: 'value2',
+ default: true,
+ },
+ ],
+ },
+ },
},
},
};
@@ -709,6 +800,26 @@ const responseForAdvancedCustomVariableWithoutLabel = {
},
};
+const responseForAdvancedCustomVariableWithoutOptText = {
+ advCustomWithoutOptText: {
+ label: 'Options without text',
+ value: 'value2',
+ options: [
+ {
+ default: false,
+ text: 'value1',
+ value: 'value1',
+ },
+ {
+ default: true,
+ text: 'value2',
+ value: 'value2',
+ },
+ ],
+ type: 'custom',
+ },
+};
+
const responseForAdvancedCustomVariable = {
...responseForSimpleCustomVariable,
advCustomNormal: {
@@ -752,6 +863,9 @@ export const mockTemplatingData = {
advCustomWithoutLabel: generateMockTemplatingData({
advCustomWithoutLabel: templatingVariableTypes.custom.advanced.withoutLabel,
}),
+ advCustomWithoutOptText: generateMockTemplatingData({
+ advCustomWithoutOptText: templatingVariableTypes.custom.advanced.withoutOptText,
+ }),
simpleAndAdv: generateMockTemplatingData({
simpleCustom: templatingVariableTypes.custom.simple,
advCustomNormal: templatingVariableTypes.custom.advanced.normal,
@@ -773,6 +887,7 @@ export const mockTemplatingDataResponses = {
advCustomWithoutOpts: responseForAdvancedCustomVariableWithoutOptions,
advCustomWithoutType: {},
advCustomWithoutLabel: responseForAdvancedCustomVariableWithoutLabel,
+ advCustomWithoutOptText: responseForAdvancedCustomVariableWithoutOptText,
simpleAndAdv: responseForAdvancedCustomVariable,
allVariableTypes: responsesForAllVariableTypes,
};
diff --git a/spec/frontend/monitoring/pages/dashboard_page_spec.js b/spec/frontend/monitoring/pages/dashboard_page_spec.js
new file mode 100644
index 00000000000..e3c56ef4cbf
--- /dev/null
+++ b/spec/frontend/monitoring/pages/dashboard_page_spec.js
@@ -0,0 +1,36 @@
+import { shallowMount } from '@vue/test-utils';
+import DashboardPage from '~/monitoring/pages/dashboard_page.vue';
+import Dashboard from '~/monitoring/components/dashboard.vue';
+import { propsData } from '../mock_data';
+
+describe('monitoring/pages/dashboard_page', () => {
+ let wrapper;
+
+ const buildWrapper = (props = {}) => {
+ wrapper = shallowMount(DashboardPage, {
+ propsData: {
+ ...props,
+ },
+ });
+ };
+
+ const findDashboardComponent = () => wrapper.find(Dashboard);
+
+ afterEach(() => {
+ if (wrapper) {
+ wrapper.destroy();
+ wrapper = null;
+ }
+ });
+
+ it('throws errors if dashboard props are not passed', () => {
+ expect(() => buildWrapper()).toThrow('Missing required prop: "dashboardProps"');
+ });
+
+ it('renders the dashboard page with dashboard component', () => {
+ buildWrapper({ dashboardProps: propsData });
+
+ expect(findDashboardComponent().props()).toMatchObject(propsData);
+ expect(findDashboardComponent()).toExist();
+ });
+});
diff --git a/spec/frontend/monitoring/store/actions_spec.js b/spec/frontend/monitoring/store/actions_spec.js
index 8914f2e66ea..d0290386f12 100644
--- a/spec/frontend/monitoring/store/actions_spec.js
+++ b/spec/frontend/monitoring/store/actions_spec.js
@@ -8,7 +8,7 @@ import createFlash from '~/flash';
import { defaultTimeRange } from '~/vue_shared/constants';
import { ENVIRONMENT_AVAILABLE_STATE } from '~/monitoring/constants';
-import store from '~/monitoring/stores';
+import { createStore } from '~/monitoring/stores';
import * as types from '~/monitoring/stores/mutation_types';
import {
fetchData,
@@ -26,7 +26,7 @@ import {
clearExpandedPanel,
setGettingStartedEmptyState,
duplicateSystemDashboard,
- updateVariableValues,
+ updateVariablesAndFetchData,
} from '~/monitoring/stores/actions';
import {
gqClient,
@@ -52,20 +52,16 @@ import {
jest.mock('~/flash');
-const resetStore = str => {
- str.replaceState({
- showEmptyState: true,
- emptyState: 'loading',
- groups: [],
- });
-};
-
describe('Monitoring store actions', () => {
const { convertObjectPropsToCamelCase } = commonUtils;
let mock;
+ let store;
+ let state;
beforeEach(() => {
+ store = createStore();
+ state = store.state.monitoringDashboard;
mock = new MockAdapter(axios);
jest.spyOn(commonUtils, 'backOff').mockImplementation(callback => {
@@ -83,7 +79,6 @@ describe('Monitoring store actions', () => {
});
});
afterEach(() => {
- resetStore(store);
mock.reset();
commonUtils.backOff.mockReset();
@@ -92,8 +87,6 @@ describe('Monitoring store actions', () => {
describe('fetchData', () => {
it('dispatches fetchEnvironmentsData and fetchEnvironmentsData', () => {
- const { state } = store;
-
return testAction(
fetchData,
null,
@@ -111,8 +104,6 @@ describe('Monitoring store actions', () => {
const origGon = window.gon;
window.gon = { features: { metricsDashboardAnnotations: true } };
- const { state } = store;
-
return testAction(
fetchData,
null,
@@ -131,7 +122,6 @@ describe('Monitoring store actions', () => {
describe('fetchDeploymentsData', () => {
it('dispatches receiveDeploymentsDataSuccess on success', () => {
- const { state } = store;
state.deploymentsEndpoint = '/success';
mock.onGet(state.deploymentsEndpoint).reply(200, {
deployments: deploymentData,
@@ -146,7 +136,6 @@ describe('Monitoring store actions', () => {
);
});
it('dispatches receiveDeploymentsDataFailure on error', () => {
- const { state } = store;
state.deploymentsEndpoint = '/error';
mock.onGet(state.deploymentsEndpoint).reply(500);
@@ -164,11 +153,8 @@ describe('Monitoring store actions', () => {
});
describe('fetchEnvironmentsData', () => {
- const { state } = store;
- state.projectPath = 'gitlab-org/gitlab-test';
-
- afterEach(() => {
- resetStore(store);
+ beforeEach(() => {
+ state.projectPath = 'gitlab-org/gitlab-test';
});
it('setting SET_ENVIRONMENTS_FILTER should dispatch fetchEnvironmentsData', () => {
@@ -269,17 +255,14 @@ describe('Monitoring store actions', () => {
});
describe('fetchAnnotations', () => {
- const { state } = store;
- state.timeRange = {
- start: '2020-04-15T12:54:32.137Z',
- end: '2020-08-15T12:54:32.137Z',
- };
- state.projectPath = 'gitlab-org/gitlab-test';
- state.currentEnvironmentName = 'production';
- state.currentDashboard = '.gitlab/dashboards/custom_dashboard.yml';
-
- afterEach(() => {
- resetStore(store);
+ beforeEach(() => {
+ state.timeRange = {
+ start: '2020-04-15T12:54:32.137Z',
+ end: '2020-08-15T12:54:32.137Z',
+ };
+ state.projectPath = 'gitlab-org/gitlab-test';
+ state.currentEnvironmentName = 'production';
+ state.currentDashboard = '.gitlab/dashboards/custom_dashboard.yml';
});
it('fetches annotations data and dispatches receiveAnnotationsSuccess', () => {
@@ -353,7 +336,6 @@ describe('Monitoring store actions', () => {
});
describe('Toggles starred value of current dashboard', () => {
- const { state } = store;
let unstarredDashboard;
let starredDashboard;
@@ -379,7 +361,13 @@ describe('Monitoring store actions', () => {
return testAction(toggleStarredValue, null, state, [
{ type: types.REQUEST_DASHBOARD_STARRING },
- { type: types.RECEIVE_DASHBOARD_STARRING_SUCCESS, payload: true },
+ {
+ type: types.RECEIVE_DASHBOARD_STARRING_SUCCESS,
+ payload: {
+ newStarredValue: true,
+ selectedDashboard: unstarredDashboard,
+ },
+ },
]);
});
@@ -396,23 +384,19 @@ describe('Monitoring store actions', () => {
});
describe('Set initial state', () => {
- let mockedState;
- beforeEach(() => {
- mockedState = storeState();
- });
it('should commit SET_INITIAL_STATE mutation', done => {
testAction(
setInitialState,
{
- metricsEndpoint: 'additional_metrics.json',
+ currentDashboard: '.gitlab/dashboards/dashboard.yml',
deploymentsEndpoint: 'deployments.json',
},
- mockedState,
+ state,
[
{
type: types.SET_INITIAL_STATE,
payload: {
- metricsEndpoint: 'additional_metrics.json',
+ currentDashboard: '.gitlab/dashboards/dashboard.yml',
deploymentsEndpoint: 'deployments.json',
},
},
@@ -423,15 +407,11 @@ describe('Monitoring store actions', () => {
});
});
describe('Set empty states', () => {
- let mockedState;
- beforeEach(() => {
- mockedState = storeState();
- });
it('should commit SET_METRICS_ENDPOINT mutation', done => {
testAction(
setGettingStartedEmptyState,
null,
- mockedState,
+ state,
[
{
type: types.SET_GETTING_STARTED_EMPTY_STATE,
@@ -443,23 +423,23 @@ describe('Monitoring store actions', () => {
});
});
- describe('updateVariableValues', () => {
- let mockedState;
- beforeEach(() => {
- mockedState = storeState();
- });
- it('should commit UPDATE_VARIABLE_VALUES mutation', done => {
+ describe('updateVariablesAndFetchData', () => {
+ it('should commit UPDATE_VARIABLES mutation and fetch data', done => {
testAction(
- updateVariableValues,
+ updateVariablesAndFetchData,
{ pod: 'POD' },
- mockedState,
+ state,
[
{
- type: types.UPDATE_VARIABLE_VALUES,
+ type: types.UPDATE_VARIABLES,
payload: { pod: 'POD' },
},
],
- [],
+ [
+ {
+ type: 'fetchDashboardData',
+ },
+ ],
done,
);
});
@@ -467,13 +447,11 @@ describe('Monitoring store actions', () => {
describe('fetchDashboard', () => {
let dispatch;
- let state;
let commit;
const response = metricsDashboardResponse;
beforeEach(() => {
dispatch = jest.fn();
commit = jest.fn();
- state = storeState();
state.dashboardEndpoint = '/dashboard';
});
@@ -557,12 +535,10 @@ describe('Monitoring store actions', () => {
describe('receiveMetricsDashboardSuccess', () => {
let commit;
let dispatch;
- let state;
beforeEach(() => {
commit = jest.fn();
dispatch = jest.fn();
- state = storeState();
});
it('stores groups', () => {
@@ -623,13 +599,11 @@ describe('Monitoring store actions', () => {
describe('fetchDashboardData', () => {
let commit;
let dispatch;
- let state;
beforeEach(() => {
jest.spyOn(Tracking, 'event');
commit = jest.fn();
dispatch = jest.fn();
- state = storeState();
state.timeRange = defaultTimeRange;
});
@@ -731,7 +705,6 @@ describe('Monitoring store actions', () => {
step: 60,
};
let metric;
- let state;
let data;
let prometheusEndpointPath;
@@ -929,10 +902,7 @@ describe('Monitoring store actions', () => {
});
describe('duplicateSystemDashboard', () => {
- let state;
-
beforeEach(() => {
- state = storeState();
state.dashboardsEndpoint = '/dashboards.json';
});
@@ -1010,12 +980,6 @@ describe('Monitoring store actions', () => {
});
describe('setExpandedPanel', () => {
- let state;
-
- beforeEach(() => {
- state = storeState();
- });
-
it('Sets a panel as expanded', () => {
const group = 'group_1';
const panel = { title: 'A Panel' };
@@ -1031,12 +995,6 @@ describe('Monitoring store actions', () => {
});
describe('clearExpandedPanel', () => {
- let state;
-
- beforeEach(() => {
- state = storeState();
- });
-
it('Clears a panel as expanded', () => {
return testAction(
clearExpandedPanel,
diff --git a/spec/frontend/monitoring/store/getters_spec.js b/spec/frontend/monitoring/store/getters_spec.js
index 19ca001c281..933ccb1e46c 100644
--- a/spec/frontend/monitoring/store/getters_spec.js
+++ b/spec/frontend/monitoring/store/getters_spec.js
@@ -8,6 +8,7 @@ import {
metricsResult,
dashboardGitResponse,
mockTemplatingDataResponses,
+ mockLinks,
} from '../mock_data';
import {
metricsDashboardPayload,
@@ -334,11 +335,11 @@ describe('Monitoring store Getters', () => {
beforeEach(() => {
state = {
- promVariables: {},
+ variables: {},
};
});
- it('transforms the promVariables object to an array in the [variable, variable_value] format for all variable types', () => {
+ it('transforms the variables object to an array in the [variable, variable_value] format for all variable types', () => {
mutations[types.SET_VARIABLES](state, mockTemplatingDataResponses.allVariableTypes);
const variablesArray = getters.getCustomVariablesParams(state);
@@ -350,7 +351,7 @@ describe('Monitoring store Getters', () => {
});
});
- it('transforms the promVariables object to an empty array when no keys are present', () => {
+ it('transforms the variables object to an empty array when no keys are present', () => {
mutations[types.SET_VARIABLES](state, {});
const variablesArray = getters.getCustomVariablesParams(state);
@@ -401,4 +402,37 @@ describe('Monitoring store Getters', () => {
expect(selectedDashboard(state)).toEqual(null);
});
});
+
+ describe('linksWithMetadata', () => {
+ let state;
+ const setupState = (initState = {}) => {
+ state = {
+ ...state,
+ ...initState,
+ };
+ };
+
+ beforeAll(() => {
+ setupState({
+ links: mockLinks,
+ });
+ });
+
+ afterAll(() => {
+ state = null;
+ });
+
+ it.each`
+ timeRange | output
+ ${{}} | ${''}
+ ${{ start: '2020-01-01T00:00:00.000Z', end: '2020-01-31T23:59:00.000Z' }} | ${'start=2020-01-01T00%3A00%3A00.000Z&end=2020-01-31T23%3A59%3A00.000Z'}
+ ${{ duration: { seconds: 86400 } }} | ${'duration_seconds=86400'}
+ `('linksWithMetadata returns URLs with time range', ({ timeRange, output }) => {
+ setupState({ timeRange });
+ const links = getters.linksWithMetadata(state);
+ links.forEach(({ url }) => {
+ expect(url).toMatch(output);
+ });
+ });
+ });
});
diff --git a/spec/frontend/monitoring/store/index_spec.js b/spec/frontend/monitoring/store/index_spec.js
new file mode 100644
index 00000000000..4184687eec8
--- /dev/null
+++ b/spec/frontend/monitoring/store/index_spec.js
@@ -0,0 +1,23 @@
+import { createStore } from '~/monitoring/stores';
+
+describe('Monitoring Store Index', () => {
+ it('creates store with a `monitoringDashboard` namespace', () => {
+ expect(createStore().state).toEqual({
+ monitoringDashboard: expect.any(Object),
+ });
+ });
+
+ it('creates store with initial values', () => {
+ const defaults = {
+ deploymentsEndpoint: '/mock/deployments',
+ dashboardEndpoint: '/mock/dashboard',
+ dashboardsEndpoint: '/mock/dashboards',
+ };
+
+ const { state } = createStore(defaults);
+
+ expect(state).toEqual({
+ monitoringDashboard: expect.objectContaining(defaults),
+ });
+ });
+});
diff --git a/spec/frontend/monitoring/store/mutations_spec.js b/spec/frontend/monitoring/store/mutations_spec.js
index 4306243689a..0283f1a86a4 100644
--- a/spec/frontend/monitoring/store/mutations_spec.js
+++ b/spec/frontend/monitoring/store/mutations_spec.js
@@ -93,14 +93,20 @@ describe('Monitoring mutations', () => {
});
it('sets a dashboard as starred', () => {
- mutations[types.RECEIVE_DASHBOARD_STARRING_SUCCESS](stateCopy, true);
+ mutations[types.RECEIVE_DASHBOARD_STARRING_SUCCESS](stateCopy, {
+ selectedDashboard: stateCopy.allDashboards[1],
+ newStarredValue: true,
+ });
expect(stateCopy.isUpdatingStarredValue).toBe(false);
expect(stateCopy.allDashboards[1].starred).toBe(true);
});
it('sets a dashboard as unstarred', () => {
- mutations[types.RECEIVE_DASHBOARD_STARRING_SUCCESS](stateCopy, false);
+ mutations[types.RECEIVE_DASHBOARD_STARRING_SUCCESS](stateCopy, {
+ selectedDashboard: stateCopy.allDashboards[1],
+ newStarredValue: false,
+ });
expect(stateCopy.isUpdatingStarredValue).toBe(false);
expect(stateCopy.allDashboards[1].starred).toBe(false);
@@ -128,13 +134,11 @@ describe('Monitoring mutations', () => {
describe('SET_INITIAL_STATE', () => {
it('should set all the endpoints', () => {
mutations[types.SET_INITIAL_STATE](stateCopy, {
- metricsEndpoint: 'additional_metrics.json',
deploymentsEndpoint: 'deployments.json',
dashboardEndpoint: 'dashboard.json',
projectPath: '/gitlab-org/gitlab-foss',
currentEnvironmentName: 'production',
});
- expect(stateCopy.metricsEndpoint).toEqual('additional_metrics.json');
expect(stateCopy.deploymentsEndpoint).toEqual('deployments.json');
expect(stateCopy.dashboardEndpoint).toEqual('dashboard.json');
expect(stateCopy.projectPath).toEqual('/gitlab-org/gitlab-foss');
@@ -179,12 +183,10 @@ describe('Monitoring mutations', () => {
describe('SET_ENDPOINTS', () => {
it('should set all the endpoints', () => {
mutations[types.SET_ENDPOINTS](stateCopy, {
- metricsEndpoint: 'additional_metrics.json',
deploymentsEndpoint: 'deployments.json',
dashboardEndpoint: 'dashboard.json',
projectPath: '/gitlab-org/gitlab-foss',
});
- expect(stateCopy.metricsEndpoint).toEqual('additional_metrics.json');
expect(stateCopy.deploymentsEndpoint).toEqual('deployments.json');
expect(stateCopy.dashboardEndpoint).toEqual('dashboard.json');
expect(stateCopy.projectPath).toEqual('/gitlab-org/gitlab-foss');
@@ -412,26 +414,26 @@ describe('Monitoring mutations', () => {
it('stores an empty variables array when no custom variables are given', () => {
mutations[types.SET_VARIABLES](stateCopy, {});
- expect(stateCopy.promVariables).toEqual({});
+ expect(stateCopy.variables).toEqual({});
});
it('stores variables in the key key_value format in the array', () => {
mutations[types.SET_VARIABLES](stateCopy, { pod: 'POD', stage: 'main ops' });
- expect(stateCopy.promVariables).toEqual({ pod: 'POD', stage: 'main ops' });
+ expect(stateCopy.variables).toEqual({ pod: 'POD', stage: 'main ops' });
});
});
- describe('UPDATE_VARIABLE_VALUES', () => {
+ describe('UPDATE_VARIABLES', () => {
afterEach(() => {
mutations[types.SET_VARIABLES](stateCopy, {});
});
- it('updates only the value of the variable in promVariables', () => {
+ it('updates only the value of the variable in variables', () => {
mutations[types.SET_VARIABLES](stateCopy, { environment: { value: 'prod', type: 'text' } });
- mutations[types.UPDATE_VARIABLE_VALUES](stateCopy, { key: 'environment', value: 'new prod' });
+ mutations[types.UPDATE_VARIABLES](stateCopy, { key: 'environment', value: 'new prod' });
- expect(stateCopy.promVariables).toEqual({ environment: { value: 'new prod', type: 'text' } });
+ expect(stateCopy.variables).toEqual({ environment: { value: 'new prod', type: 'text' } });
});
});
});
diff --git a/spec/frontend/monitoring/store/utils_spec.js b/spec/frontend/monitoring/store/utils_spec.js
index fe5754e1216..3a70bda51da 100644
--- a/spec/frontend/monitoring/store/utils_spec.js
+++ b/spec/frontend/monitoring/store/utils_spec.js
@@ -5,6 +5,9 @@ import {
parseAnnotationsResponse,
removeLeadingSlash,
mapToDashboardViewModel,
+ normalizeQueryResult,
+ convertToGrafanaTimeRange,
+ addDashboardMetaDataToLink,
} from '~/monitoring/stores/utils';
import { annotationsData } from '../mock_data';
import { NOT_IN_DB_PREFIX } from '~/monitoring/constants';
@@ -16,6 +19,8 @@ describe('mapToDashboardViewModel', () => {
expect(mapToDashboardViewModel({})).toEqual({
dashboard: '',
panelGroups: [],
+ links: [],
+ variables: {},
});
});
@@ -44,6 +49,8 @@ describe('mapToDashboardViewModel', () => {
expect(mapToDashboardViewModel(response)).toEqual({
dashboard: 'Dashboard Name',
+ links: [],
+ variables: {},
panelGroups: [
{
group: 'Group 1',
@@ -63,6 +70,7 @@ describe('mapToDashboardViewModel', () => {
format: 'engineering',
precision: 2,
},
+ links: [],
metrics: [],
},
],
@@ -75,6 +83,8 @@ describe('mapToDashboardViewModel', () => {
it('key', () => {
const response = {
dashboard: 'Dashboard Name',
+ links: [],
+ variables: {},
panel_groups: [
{
group: 'Group A',
@@ -147,6 +157,7 @@ describe('mapToDashboardViewModel', () => {
format: SUPPORTED_FORMATS.engineering,
precision: 2,
},
+ links: [],
metrics: [],
});
});
@@ -170,6 +181,7 @@ describe('mapToDashboardViewModel', () => {
format: SUPPORTED_FORMATS.engineering,
precision: 2,
},
+ links: [],
metrics: [],
});
});
@@ -238,6 +250,77 @@ describe('mapToDashboardViewModel', () => {
expect(getMappedPanel().maxValue).toBe(100);
});
+
+ describe('panel with links', () => {
+ const title = 'Example';
+ const url = 'https://example.com';
+
+ it('maps an empty link collection', () => {
+ setupWithPanel({
+ links: undefined,
+ });
+
+ expect(getMappedPanel().links).toEqual([]);
+ });
+
+ it('maps a link', () => {
+ setupWithPanel({ links: [{ title, url }] });
+
+ expect(getMappedPanel().links).toEqual([{ title, url }]);
+ });
+
+ it('maps a link without a title', () => {
+ setupWithPanel({
+ links: [{ url }],
+ });
+
+ expect(getMappedPanel().links).toEqual([{ title: url, url }]);
+ });
+
+ it('maps a link without a url', () => {
+ setupWithPanel({
+ links: [{ title }],
+ });
+
+ expect(getMappedPanel().links).toEqual([{ title, url: '#' }]);
+ });
+
+ it('maps a link without a url or title', () => {
+ setupWithPanel({
+ links: [{}],
+ });
+
+ expect(getMappedPanel().links).toEqual([{ title: 'null', url: '#' }]);
+ });
+
+ it('maps a link with an unsafe url safely', () => {
+ // eslint-disable-next-line no-script-url
+ const unsafeUrl = 'javascript:alert("XSS")';
+
+ setupWithPanel({
+ links: [
+ {
+ title,
+ url: unsafeUrl,
+ },
+ ],
+ });
+
+ expect(getMappedPanel().links).toEqual([{ title, url: '#' }]);
+ });
+
+ it('maps multple links', () => {
+ setupWithPanel({
+ links: [{ title, url }, { url }, { title }],
+ });
+
+ expect(getMappedPanel().links).toEqual([
+ { title, url },
+ { title: url, url },
+ { title, url: '#' },
+ ]);
+ });
+ });
});
describe('metrics mapping', () => {
@@ -317,6 +400,28 @@ describe('mapToDashboardViewModel', () => {
});
});
+describe('normalizeQueryResult', () => {
+ const testData = {
+ metric: {
+ __name__: 'up',
+ job: 'prometheus',
+ instance: 'localhost:9090',
+ },
+ values: [[1435781430.781, '1'], [1435781445.781, '1'], [1435781460.781, '1']],
+ };
+
+ it('processes a simple matrix result', () => {
+ expect(normalizeQueryResult(testData)).toEqual({
+ metric: { __name__: 'up', job: 'prometheus', instance: 'localhost:9090' },
+ values: [
+ ['2015-07-01T20:10:30.781Z', 1],
+ ['2015-07-01T20:10:45.781Z', 1],
+ ['2015-07-01T20:11:00.781Z', 1],
+ ],
+ });
+ });
+});
+
describe('uniqMetricsId', () => {
[
{ input: { id: 1 }, expected: `${NOT_IN_DB_PREFIX}_1` },
@@ -419,3 +524,86 @@ describe('removeLeadingSlash', () => {
});
});
});
+
+describe('user-defined links utils', () => {
+ const mockRelativeTimeRange = {
+ metricsDashboard: {
+ duration: {
+ seconds: 86400,
+ },
+ },
+ grafana: {
+ from: 'now-86400s',
+ to: 'now',
+ },
+ };
+ const mockAbsoluteTimeRange = {
+ metricsDashboard: {
+ start: '2020-06-08T16:13:01.995Z',
+ end: '2020-06-08T21:12:32.243Z',
+ },
+ grafana: {
+ from: 1591632781995,
+ to: 1591650752243,
+ },
+ };
+ describe('convertToGrafanaTimeRange', () => {
+ it('converts relative timezone to grafana timezone', () => {
+ expect(convertToGrafanaTimeRange(mockRelativeTimeRange.metricsDashboard)).toEqual(
+ mockRelativeTimeRange.grafana,
+ );
+ });
+
+ it('converts absolute timezone to grafana timezone', () => {
+ expect(convertToGrafanaTimeRange(mockAbsoluteTimeRange.metricsDashboard)).toEqual(
+ mockAbsoluteTimeRange.grafana,
+ );
+ });
+ });
+
+ describe('addDashboardMetaDataToLink', () => {
+ const link = { title: 'title', url: 'https://gitlab.com' };
+ const grafanaLink = { ...link, type: 'grafana' };
+
+ it('adds relative time range to link w/o type for metrics dashboards', () => {
+ const adder = addDashboardMetaDataToLink({
+ timeRange: mockRelativeTimeRange.metricsDashboard,
+ });
+ expect(adder(link)).toMatchObject({
+ title: 'title',
+ url: 'https://gitlab.com?duration_seconds=86400',
+ });
+ });
+
+ it('adds relative time range to Grafana type links', () => {
+ const adder = addDashboardMetaDataToLink({
+ timeRange: mockRelativeTimeRange.metricsDashboard,
+ });
+ expect(adder(grafanaLink)).toMatchObject({
+ title: 'title',
+ url: 'https://gitlab.com?from=now-86400s&to=now',
+ });
+ });
+
+ it('adds absolute time range to link w/o type for metrics dashboard', () => {
+ const adder = addDashboardMetaDataToLink({
+ timeRange: mockAbsoluteTimeRange.metricsDashboard,
+ });
+ expect(adder(link)).toMatchObject({
+ title: 'title',
+ url:
+ 'https://gitlab.com?start=2020-06-08T16%3A13%3A01.995Z&end=2020-06-08T21%3A12%3A32.243Z',
+ });
+ });
+
+ it('adds absolute time range to Grafana type links', () => {
+ const adder = addDashboardMetaDataToLink({
+ timeRange: mockAbsoluteTimeRange.metricsDashboard,
+ });
+ expect(adder(grafanaLink)).toMatchObject({
+ title: 'title',
+ url: 'https://gitlab.com?from=1591632781995&to=1591650752243',
+ });
+ });
+ });
+});
diff --git a/spec/frontend/monitoring/store/variable_mapping_spec.js b/spec/frontend/monitoring/store/variable_mapping_spec.js
index 47681ac7c65..c44bb957166 100644
--- a/spec/frontend/monitoring/store/variable_mapping_spec.js
+++ b/spec/frontend/monitoring/store/variable_mapping_spec.js
@@ -3,19 +3,20 @@ import { mockTemplatingData, mockTemplatingDataResponses } from '../mock_data';
describe('parseTemplatingVariables', () => {
it.each`
- case | input | expected
- ${'Returns empty object for no dashboard input'} | ${{}} | ${{}}
- ${'Returns empty object for empty dashboard input'} | ${{ dashboard: {} }} | ${{}}
- ${'Returns empty object for empty templating prop'} | ${mockTemplatingData.emptyTemplatingProp} | ${{}}
- ${'Returns empty object for empty variables prop'} | ${mockTemplatingData.emptyVariablesProp} | ${{}}
- ${'Returns parsed object for simple text variable'} | ${mockTemplatingData.simpleText} | ${mockTemplatingDataResponses.simpleText}
- ${'Returns parsed object for advanced text variable'} | ${mockTemplatingData.advText} | ${mockTemplatingDataResponses.advText}
- ${'Returns parsed object for simple custom variable'} | ${mockTemplatingData.simpleCustom} | ${mockTemplatingDataResponses.simpleCustom}
- ${'Returns parsed object for advanced custom variable without options'} | ${mockTemplatingData.advCustomWithoutOpts} | ${mockTemplatingDataResponses.advCustomWithoutOpts}
- ${'Returns parsed object for advanced custom variable without type'} | ${mockTemplatingData.advCustomWithoutType} | ${{}}
- ${'Returns parsed object for advanced custom variable without label'} | ${mockTemplatingData.advCustomWithoutLabel} | ${mockTemplatingDataResponses.advCustomWithoutLabel}
- ${'Returns parsed object for simple and advanced custom variables'} | ${mockTemplatingData.simpleAndAdv} | ${mockTemplatingDataResponses.simpleAndAdv}
- ${'Returns parsed object for all variable types'} | ${mockTemplatingData.allVariableTypes} | ${mockTemplatingDataResponses.allVariableTypes}
+ case | input | expected
+ ${'Returns empty object for no dashboard input'} | ${{}} | ${{}}
+ ${'Returns empty object for empty dashboard input'} | ${{ dashboard: {} }} | ${{}}
+ ${'Returns empty object for empty templating prop'} | ${mockTemplatingData.emptyTemplatingProp} | ${{}}
+ ${'Returns empty object for empty variables prop'} | ${mockTemplatingData.emptyVariablesProp} | ${{}}
+ ${'Returns parsed object for simple text variable'} | ${mockTemplatingData.simpleText} | ${mockTemplatingDataResponses.simpleText}
+ ${'Returns parsed object for advanced text variable'} | ${mockTemplatingData.advText} | ${mockTemplatingDataResponses.advText}
+ ${'Returns parsed object for simple custom variable'} | ${mockTemplatingData.simpleCustom} | ${mockTemplatingDataResponses.simpleCustom}
+ ${'Returns parsed object for advanced custom variable without options'} | ${mockTemplatingData.advCustomWithoutOpts} | ${mockTemplatingDataResponses.advCustomWithoutOpts}
+ ${'Returns parsed object for advanced custom variable for option without text'} | ${mockTemplatingData.advCustomWithoutOptText} | ${mockTemplatingDataResponses.advCustomWithoutOptText}
+ ${'Returns parsed object for advanced custom variable without type'} | ${mockTemplatingData.advCustomWithoutType} | ${{}}
+ ${'Returns parsed object for advanced custom variable without label'} | ${mockTemplatingData.advCustomWithoutLabel} | ${mockTemplatingDataResponses.advCustomWithoutLabel}
+ ${'Returns parsed object for simple and advanced custom variables'} | ${mockTemplatingData.simpleAndAdv} | ${mockTemplatingDataResponses.simpleAndAdv}
+ ${'Returns parsed object for all variable types'} | ${mockTemplatingData.allVariableTypes} | ${mockTemplatingDataResponses.allVariableTypes}
`('$case', ({ input, expected }) => {
expect(parseTemplatingVariables(input?.dashboard?.templating)).toEqual(expected);
});
diff --git a/spec/frontend/monitoring/store_utils.js b/spec/frontend/monitoring/store_utils.js
index 338af79dbbe..eb2578aa9db 100644
--- a/spec/frontend/monitoring/store_utils.js
+++ b/spec/frontend/monitoring/store_utils.js
@@ -16,8 +16,13 @@ const setEnvironmentData = store => {
store.commit(`monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`, environmentData);
};
-export const setupAllDashboards = store => {
+export const setupAllDashboards = (store, path) => {
store.commit(`monitoringDashboard/${types.SET_ALL_DASHBOARDS}`, dashboardGitResponse);
+ if (path) {
+ store.commit(`monitoringDashboard/${types.SET_INITIAL_STATE}`, {
+ currentDashboard: path,
+ });
+ }
};
export const setupStoreWithDashboard = store => {
@@ -25,10 +30,6 @@ export const setupStoreWithDashboard = store => {
`monitoringDashboard/${types.RECEIVE_METRICS_DASHBOARD_SUCCESS}`,
metricsDashboardPayload,
);
- store.commit(
- `monitoringDashboard/${types.RECEIVE_METRICS_DASHBOARD_SUCCESS}`,
- metricsDashboardPayload,
- );
};
export const setupStoreWithVariable = store => {
@@ -37,6 +38,18 @@ export const setupStoreWithVariable = store => {
});
};
+export const setupStoreWithLinks = store => {
+ store.commit(`monitoringDashboard/${types.RECEIVE_METRICS_DASHBOARD_SUCCESS}`, {
+ ...metricsDashboardPayload,
+ links: [
+ {
+ title: 'GitLab Website',
+ url: `https://gitlab.com/website`,
+ },
+ ],
+ });
+};
+
export const setupStoreWithData = store => {
setupAllDashboards(store);
setupStoreWithDashboard(store);
diff --git a/spec/frontend/namespace_storage_limit_alert_spec.js b/spec/frontend/namespace_storage_limit_alert_spec.js
new file mode 100644
index 00000000000..ef398b12e1f
--- /dev/null
+++ b/spec/frontend/namespace_storage_limit_alert_spec.js
@@ -0,0 +1,36 @@
+import Cookies from 'js-cookie';
+import initNamespaceStorageLimitAlert from '~/namespace_storage_limit_alert';
+
+describe('broadcast message on dismiss', () => {
+ const dismiss = () => {
+ const button = document.querySelector('.js-namespace-storage-alert-dismiss');
+ button.click();
+ };
+
+ beforeEach(() => {
+ setFixtures(`
+ <div class="js-namespace-storage-alert">
+ <button class="js-namespace-storage-alert-dismiss" data-id="1" data-level="info"></button>
+ </div>
+ `);
+
+ initNamespaceStorageLimitAlert();
+ });
+
+ it('removes alert', () => {
+ expect(document.querySelector('.js-namespace-storage-alert')).toBeTruthy();
+
+ dismiss();
+
+ expect(document.querySelector('.js-namespace-storage-alert')).toBeNull();
+ });
+
+ it('calls Cookies.set', () => {
+ jest.spyOn(Cookies, 'set');
+ dismiss();
+
+ expect(Cookies.set).toHaveBeenCalledWith('hide_storage_limit_alert_1_info', true, {
+ expires: 365,
+ });
+ });
+});
diff --git a/spec/frontend/notes/components/diff_with_note_spec.js b/spec/frontend/notes/components/diff_with_note_spec.js
index d6d42e1988d..6480af015db 100644
--- a/spec/frontend/notes/components/diff_with_note_spec.js
+++ b/spec/frontend/notes/components/diff_with_note_spec.js
@@ -1,4 +1,4 @@
-import { mount } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
import DiffWithNote from '~/notes/components/diff_with_note.vue';
import { createStore } from '~/mr_notes/stores';
@@ -37,7 +37,7 @@ describe('diff_with_note', () => {
beforeEach(() => {
const diffDiscussion = getJSONFixture(discussionFixture)[0];
- wrapper = mount(DiffWithNote, {
+ wrapper = shallowMount(DiffWithNote, {
propsData: {
discussion: diffDiscussion,
},
@@ -76,7 +76,10 @@ describe('diff_with_note', () => {
describe('image diff', () => {
beforeEach(() => {
const imageDiscussion = getJSONFixture(imageDiscussionFixture)[0];
- wrapper = mount(DiffWithNote, { propsData: { discussion: imageDiscussion }, store });
+ wrapper = shallowMount(DiffWithNote, {
+ propsData: { discussion: imageDiscussion, diffFile: {} },
+ store,
+ });
});
it('shows image diff', () => {
diff --git a/spec/frontend/notes/components/discussion_reply_placeholder_spec.js b/spec/frontend/notes/components/discussion_reply_placeholder_spec.js
index a881e44a007..b7b7ec08867 100644
--- a/spec/frontend/notes/components/discussion_reply_placeholder_spec.js
+++ b/spec/frontend/notes/components/discussion_reply_placeholder_spec.js
@@ -20,7 +20,7 @@ describe('ReplyPlaceholder', () => {
wrapper.destroy();
});
- it('emits onClick even on button click', () => {
+ it('emits onClick event on button click', () => {
findButton().trigger('click');
return wrapper.vm.$nextTick().then(() => {
diff --git a/spec/frontend/notes/components/multiline_comment_utils_spec.js b/spec/frontend/notes/components/multiline_comment_utils_spec.js
new file mode 100644
index 00000000000..261bfb106e7
--- /dev/null
+++ b/spec/frontend/notes/components/multiline_comment_utils_spec.js
@@ -0,0 +1,49 @@
+import {
+ getSymbol,
+ getStartLineNumber,
+ getEndLineNumber,
+} from '~/notes/components/multiline_comment_utils';
+
+describe('Multiline comment utilities', () => {
+ describe('getStartLineNumber', () => {
+ it.each`
+ lineCode | type | result
+ ${'abcdef_1_1'} | ${'old'} | ${'-1'}
+ ${'abcdef_1_1'} | ${'new'} | ${'+1'}
+ ${'abcdef_1_1'} | ${null} | ${'1'}
+ ${'abcdef'} | ${'new'} | ${''}
+ ${'abcdef'} | ${'old'} | ${''}
+ ${'abcdef'} | ${null} | ${''}
+ `('returns line number', ({ lineCode, type, result }) => {
+ expect(getStartLineNumber({ start_line_code: lineCode, start_line_type: type })).toEqual(
+ result,
+ );
+ });
+ });
+ describe('getEndLineNumber', () => {
+ it.each`
+ lineCode | type | result
+ ${'abcdef_1_1'} | ${'old'} | ${'-1'}
+ ${'abcdef_1_1'} | ${'new'} | ${'+1'}
+ ${'abcdef_1_1'} | ${null} | ${'1'}
+ ${'abcdef'} | ${'new'} | ${''}
+ ${'abcdef'} | ${'old'} | ${''}
+ ${'abcdef'} | ${null} | ${''}
+ `('returns line number', ({ lineCode, type, result }) => {
+ expect(getEndLineNumber({ end_line_code: lineCode, end_line_type: type })).toEqual(result);
+ });
+ });
+ describe('getSymbol', () => {
+ it.each`
+ type | result
+ ${'new'} | ${'+'}
+ ${'old'} | ${'-'}
+ ${'unused'} | ${''}
+ ${''} | ${''}
+ ${null} | ${''}
+ ${undefined} | ${''}
+ `('`$type` returns `$result`', ({ type, result }) => {
+ expect(getSymbol(type)).toEqual(result);
+ });
+ });
+});
diff --git a/spec/frontend/notes/components/note_actions_spec.js b/spec/frontend/notes/components/note_actions_spec.js
index 5d13f587ca7..220ac22d8eb 100644
--- a/spec/frontend/notes/components/note_actions_spec.js
+++ b/spec/frontend/notes/components/note_actions_spec.js
@@ -4,26 +4,33 @@ import { TEST_HOST } from 'spec/test_constants';
import createStore from '~/notes/stores';
import noteActions from '~/notes/components/note_actions.vue';
import { userDataMock } from '../mock_data';
+import AxiosMockAdapter from 'axios-mock-adapter';
+import axios from '~/lib/utils/axios_utils';
describe('noteActions', () => {
let wrapper;
let store;
let props;
+ let actions;
+ let axiosMock;
- const shallowMountNoteActions = propsData => {
+ const shallowMountNoteActions = (propsData, computed) => {
const localVue = createLocalVue();
return shallowMount(localVue.extend(noteActions), {
store,
propsData,
localVue,
+ computed,
});
};
beforeEach(() => {
store = createStore();
+
props = {
accessLevel: 'Maintainer',
- authorId: 26,
+ authorId: 1,
+ author: userDataMock,
canDelete: true,
canEdit: true,
canAwardEmoji: true,
@@ -33,10 +40,17 @@ describe('noteActions', () => {
reportAbusePath: `${TEST_HOST}/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-ce%2Fissues%2F7%23note_539&user_id=26`,
showReply: false,
};
+
+ actions = {
+ updateAssignees: jest.fn(),
+ };
+
+ axiosMock = new AxiosMockAdapter(axios);
});
afterEach(() => {
wrapper.destroy();
+ axiosMock.restore();
});
describe('user is logged in', () => {
@@ -76,6 +90,14 @@ describe('noteActions', () => {
it('should not show copy link action when `noteUrl` prop is empty', done => {
wrapper.setProps({
...props,
+ author: {
+ avatar_url: 'mock_path',
+ id: 26,
+ name: 'Example Maintainer',
+ path: '/ExampleMaintainer',
+ state: 'active',
+ username: 'ExampleMaintainer',
+ },
noteUrl: '',
});
@@ -104,6 +126,25 @@ describe('noteActions', () => {
})
.catch(done.fail);
});
+
+ it('should be possible to assign or unassign the comment author', () => {
+ wrapper = shallowMountNoteActions(props, {
+ targetType: () => 'issue',
+ });
+
+ const assignUserButton = wrapper.find('[data-testid="assign-user"]');
+ expect(assignUserButton.exists()).toBe(true);
+
+ assignUserButton.trigger('click');
+ axiosMock.onPut(`${TEST_HOST}/api/v4/projects/group/project/issues/1`).reply(() => {
+ expect(actions.updateAssignees).toHaveBeenCalled();
+ });
+ });
+
+ it('should not be possible to assign or unassign the comment author in a merge request', () => {
+ const assignUserButton = wrapper.find('[data-testid="assign-user"]');
+ expect(assignUserButton.exists()).toBe(false);
+ });
});
});
@@ -157,4 +198,19 @@ describe('noteActions', () => {
expect(replyButton.exists()).toBe(false);
});
});
+
+ describe('Draft notes', () => {
+ beforeEach(() => {
+ store.dispatch('setUserData', userDataMock);
+
+ wrapper = shallowMountNoteActions({ ...props, canResolve: true, isDraft: true });
+ });
+
+ it('should render the right resolve button title', () => {
+ const resolveButton = wrapper.find({ ref: 'resolveButton' });
+
+ expect(resolveButton.exists()).toBe(true);
+ expect(resolveButton.attributes('title')).toBe('Thread stays unresolved');
+ });
+ });
});
diff --git a/spec/frontend/notes/components/note_form_spec.js b/spec/frontend/notes/components/note_form_spec.js
index 8270c148fb5..15802841c57 100644
--- a/spec/frontend/notes/components/note_form_spec.js
+++ b/spec/frontend/notes/components/note_form_spec.js
@@ -1,8 +1,9 @@
import { shallowMount, createLocalVue } from '@vue/test-utils';
import createStore from '~/notes/stores';
import NoteForm from '~/notes/components/note_form.vue';
+import batchComments from '~/batch_comments/stores/modules/batch_comments';
import MarkdownField from '~/vue_shared/components/markdown/field.vue';
-import { noteableDataMock, notesDataMock } from '../mock_data';
+import { noteableDataMock, notesDataMock, discussionMock } from '../mock_data';
import { getDraft, updateDraft } from '~/lib/utils/autosave';
@@ -245,4 +246,55 @@ describe('issue_note_form component', () => {
expect(updateDraft).toHaveBeenCalledWith(dummyAutosaveKey, dummyContent);
});
});
+
+ describe('with batch comments', () => {
+ beforeEach(() => {
+ store.registerModule('batchComments', batchComments());
+
+ wrapper = createComponentWrapper();
+ wrapper.setProps({
+ ...props,
+ noteId: '',
+ discussion: { ...discussionMock, for_commit: false },
+ });
+ });
+
+ it('should be possible to cancel', () => {
+ jest.spyOn(wrapper.vm, 'cancelHandler');
+
+ return wrapper.vm.$nextTick().then(() => {
+ const cancelButton = wrapper.find('[data-testid="cancelBatchCommentsEnabled"]');
+ cancelButton.trigger('click');
+
+ expect(wrapper.vm.cancelHandler).toHaveBeenCalledWith(true);
+ });
+ });
+
+ it('shows resolve checkbox', () => {
+ expect(wrapper.find('.js-resolve-checkbox').exists()).toBe(true);
+ });
+
+ it('hides actions for commits', () => {
+ wrapper.setProps({ discussion: { for_commit: true } });
+
+ return wrapper.vm.$nextTick(() => {
+ expect(wrapper.find('.note-form-actions').text()).not.toContain('Start a review');
+ });
+ });
+
+ describe('on enter', () => {
+ it('should start review or add to review when cmd+enter is pressed', () => {
+ const textarea = wrapper.find('textarea');
+
+ jest.spyOn(wrapper.vm, 'handleAddToReview');
+
+ textarea.setValue('Foo');
+ textarea.trigger('keydown.enter', { metaKey: true });
+
+ return wrapper.vm.$nextTick(() => {
+ expect(wrapper.vm.handleAddToReview).toHaveBeenCalled();
+ });
+ });
+ });
+ });
});
diff --git a/spec/frontend/notes/components/noteable_note_spec.js b/spec/frontend/notes/components/noteable_note_spec.js
index 0d67b1d87a9..aa3eaa97e20 100644
--- a/spec/frontend/notes/components/noteable_note_spec.js
+++ b/spec/frontend/notes/components/noteable_note_spec.js
@@ -1,5 +1,5 @@
import { escape } from 'lodash';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
+import { mount, createLocalVue } from '@vue/test-utils';
import createStore from '~/notes/stores';
import issueNote from '~/notes/components/noteable_note.vue';
import NoteHeader from '~/notes/components/note_header.vue';
@@ -8,9 +8,19 @@ import NoteActions from '~/notes/components/note_actions.vue';
import NoteBody from '~/notes/components/note_body.vue';
import { noteableDataMock, notesDataMock, note } from '../mock_data';
+jest.mock('~/vue_shared/mixins/gl_feature_flags_mixin', () => () => ({
+ inject: {
+ glFeatures: {
+ from: 'glFeatures',
+ default: () => ({ multilineComments: true }),
+ },
+ },
+}));
+
describe('issue_note', () => {
let store;
let wrapper;
+ const findMultilineComment = () => wrapper.find('[data-testid="multiline-comment"]');
beforeEach(() => {
store = createStore();
@@ -18,12 +28,13 @@ describe('issue_note', () => {
store.dispatch('setNotesData', notesDataMock);
const localVue = createLocalVue();
- wrapper = shallowMount(localVue.extend(issueNote), {
+ wrapper = mount(localVue.extend(issueNote), {
store,
propsData: {
note,
},
localVue,
+ stubs: ['note-header', 'user-avatar-link', 'note-actions', 'note-body'],
});
});
@@ -31,6 +42,44 @@ describe('issue_note', () => {
wrapper.destroy();
});
+ describe('mutiline comments', () => {
+ it('should render if has multiline comment', () => {
+ const position = {
+ line_range: {
+ start_line_code: 'abc_1_1',
+ end_line_code: 'abc_2_2',
+ },
+ };
+ wrapper.setProps({
+ note: { ...note, position },
+ });
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findMultilineComment().text()).toEqual('Comment on lines 1 to 2');
+ });
+ });
+
+ it('should not render if has single line comment', () => {
+ const position = {
+ line_range: {
+ start_line_code: 'abc_1_1',
+ end_line_code: 'abc_1_1',
+ },
+ };
+ wrapper.setProps({
+ note: { ...note, position },
+ });
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findMultilineComment().exists()).toBe(false);
+ });
+ });
+
+ it('should not render if `line_range` is unavailable', () => {
+ expect(findMultilineComment().exists()).toBe(false);
+ });
+ });
+
it('should render user information', () => {
const { author } = note;
const avatar = wrapper.find(UserAvatarLink);
diff --git a/spec/frontend/notes/mixins/discussion_navigation_spec.js b/spec/frontend/notes/mixins/discussion_navigation_spec.js
index 120de023099..ae30a36fc81 100644
--- a/spec/frontend/notes/mixins/discussion_navigation_spec.js
+++ b/spec/frontend/notes/mixins/discussion_navigation_spec.js
@@ -41,7 +41,7 @@ describe('Discussion navigation mixin', () => {
.join(''),
);
- jest.spyOn(utils, 'scrollToElement');
+ jest.spyOn(utils, 'scrollToElementWithContext');
expandDiscussion = jest.fn();
const { actions, ...notesRest } = notesModule();
@@ -102,7 +102,7 @@ describe('Discussion navigation mixin', () => {
});
it('scrolls to element', () => {
- expect(utils.scrollToElement).toHaveBeenCalledWith(
+ expect(utils.scrollToElementWithContext).toHaveBeenCalledWith(
findDiscussion('div.discussion', expected),
);
});
@@ -123,11 +123,13 @@ describe('Discussion navigation mixin', () => {
});
it('scrolls when scrollToDiscussion is emitted', () => {
- expect(utils.scrollToElement).not.toHaveBeenCalled();
+ expect(utils.scrollToElementWithContext).not.toHaveBeenCalled();
eventHub.$emit('scrollToDiscussion');
- expect(utils.scrollToElement).toHaveBeenCalledWith(findDiscussion('ul.notes', expected));
+ expect(utils.scrollToElementWithContext).toHaveBeenCalledWith(
+ findDiscussion('ul.notes', expected),
+ );
});
});
@@ -167,7 +169,7 @@ describe('Discussion navigation mixin', () => {
});
it('scrolls to discussion', () => {
- expect(utils.scrollToElement).toHaveBeenCalledWith(
+ expect(utils.scrollToElementWithContext).toHaveBeenCalledWith(
findDiscussion('div.discussion', expected),
);
});
diff --git a/spec/frontend/notes/mock_data.js b/spec/frontend/notes/mock_data.js
index 980faac2b04..4ff64abe4cc 100644
--- a/spec/frontend/notes/mock_data.js
+++ b/spec/frontend/notes/mock_data.js
@@ -1254,3 +1254,16 @@ export const discussionFiltersMock = [
value: 2,
},
];
+
+export const batchSuggestionsInfoMock = [
+ {
+ suggestionId: 'a123',
+ noteId: 'b456',
+ discussionId: 'c789',
+ },
+ {
+ suggestionId: 'a001',
+ noteId: 'b002',
+ discussionId: 'c003',
+ },
+];
diff --git a/spec/frontend/notes/stores/actions_spec.js b/spec/frontend/notes/stores/actions_spec.js
index cbfb9597159..ef87cb3bee7 100644
--- a/spec/frontend/notes/stores/actions_spec.js
+++ b/spec/frontend/notes/stores/actions_spec.js
@@ -15,6 +15,7 @@ import {
userDataMock,
noteableDataMock,
individualNote,
+ batchSuggestionsInfoMock,
} from '../mock_data';
import axios from '~/lib/utils/axios_utils';
@@ -890,7 +891,23 @@ describe('Actions Notes Store', () => {
testSubmitSuggestion(done, () => {
expect(commit).not.toHaveBeenCalled();
expect(dispatch).not.toHaveBeenCalled();
- expect(Flash).toHaveBeenCalledWith(`${TEST_ERROR_MESSAGE}.`, 'alert', flashContainer);
+ expect(Flash).toHaveBeenCalledWith(TEST_ERROR_MESSAGE, 'alert', flashContainer);
+ });
+ });
+
+ it('when service fails, and no error message available, uses default message', done => {
+ const response = { response: 'foo' };
+
+ Api.applySuggestion.mockReturnValue(Promise.reject(response));
+
+ testSubmitSuggestion(done, () => {
+ expect(commit).not.toHaveBeenCalled();
+ expect(dispatch).not.toHaveBeenCalled();
+ expect(Flash).toHaveBeenCalledWith(
+ 'Something went wrong while applying the suggestion. Please try again.',
+ 'alert',
+ flashContainer,
+ );
});
});
@@ -903,6 +920,130 @@ describe('Actions Notes Store', () => {
});
});
+ describe('submitSuggestionBatch', () => {
+ const discussionIds = batchSuggestionsInfoMock.map(({ discussionId }) => discussionId);
+ const batchSuggestionsInfo = batchSuggestionsInfoMock;
+
+ let flashContainer;
+
+ beforeEach(() => {
+ jest.spyOn(Api, 'applySuggestionBatch');
+ dispatch.mockReturnValue(Promise.resolve());
+ Api.applySuggestionBatch.mockReturnValue(Promise.resolve());
+ state = { batchSuggestionsInfo };
+ flashContainer = {};
+ });
+
+ const testSubmitSuggestionBatch = (done, expectFn) => {
+ actions
+ .submitSuggestionBatch({ commit, dispatch, state }, { flashContainer })
+ .then(expectFn)
+ .then(done)
+ .catch(done.fail);
+ };
+
+ it('when service succeeds, commits, resolves discussions, resets batch and applying batch state', done => {
+ testSubmitSuggestionBatch(done, () => {
+ expect(commit.mock.calls).toEqual([
+ [mutationTypes.SET_APPLYING_BATCH_STATE, true],
+ [mutationTypes.APPLY_SUGGESTION, batchSuggestionsInfo[0]],
+ [mutationTypes.APPLY_SUGGESTION, batchSuggestionsInfo[1]],
+ [mutationTypes.CLEAR_SUGGESTION_BATCH],
+ [mutationTypes.SET_APPLYING_BATCH_STATE, false],
+ ]);
+
+ expect(dispatch.mock.calls).toEqual([
+ ['resolveDiscussion', { discussionId: discussionIds[0] }],
+ ['resolveDiscussion', { discussionId: discussionIds[1] }],
+ ]);
+
+ expect(Flash).not.toHaveBeenCalled();
+ });
+ });
+
+ it('when service fails, flashes error message, resets applying batch state', done => {
+ const response = { response: { data: { message: TEST_ERROR_MESSAGE } } };
+
+ Api.applySuggestionBatch.mockReturnValue(Promise.reject(response));
+
+ testSubmitSuggestionBatch(done, () => {
+ expect(commit.mock.calls).toEqual([
+ [mutationTypes.SET_APPLYING_BATCH_STATE, true],
+ [mutationTypes.SET_APPLYING_BATCH_STATE, false],
+ ]);
+
+ expect(dispatch).not.toHaveBeenCalled();
+ expect(Flash).toHaveBeenCalledWith(TEST_ERROR_MESSAGE, 'alert', flashContainer);
+ });
+ });
+
+ it('when service fails, and no error message available, uses default message', done => {
+ const response = { response: 'foo' };
+
+ Api.applySuggestionBatch.mockReturnValue(Promise.reject(response));
+
+ testSubmitSuggestionBatch(done, () => {
+ expect(commit.mock.calls).toEqual([
+ [mutationTypes.SET_APPLYING_BATCH_STATE, true],
+ [mutationTypes.SET_APPLYING_BATCH_STATE, false],
+ ]);
+
+ expect(dispatch).not.toHaveBeenCalled();
+ expect(Flash).toHaveBeenCalledWith(
+ 'Something went wrong while applying the batch of suggestions. Please try again.',
+ 'alert',
+ flashContainer,
+ );
+ });
+ });
+
+ it('when resolve discussions fails, fails gracefully, resets batch and applying batch state', done => {
+ dispatch.mockReturnValue(Promise.reject());
+
+ testSubmitSuggestionBatch(done, () => {
+ expect(commit.mock.calls).toEqual([
+ [mutationTypes.SET_APPLYING_BATCH_STATE, true],
+ [mutationTypes.APPLY_SUGGESTION, batchSuggestionsInfo[0]],
+ [mutationTypes.APPLY_SUGGESTION, batchSuggestionsInfo[1]],
+ [mutationTypes.CLEAR_SUGGESTION_BATCH],
+ [mutationTypes.SET_APPLYING_BATCH_STATE, false],
+ ]);
+
+ expect(Flash).not.toHaveBeenCalled();
+ });
+ });
+ });
+
+ describe('addSuggestionInfoToBatch', () => {
+ const suggestionInfo = batchSuggestionsInfoMock[0];
+
+ it("adds a suggestion's info to the current batch", done => {
+ testAction(
+ actions.addSuggestionInfoToBatch,
+ suggestionInfo,
+ { batchSuggestionsInfo: [] },
+ [{ type: 'ADD_SUGGESTION_TO_BATCH', payload: suggestionInfo }],
+ [],
+ done,
+ );
+ });
+ });
+
+ describe('removeSuggestionInfoFromBatch', () => {
+ const suggestionInfo = batchSuggestionsInfoMock[0];
+
+ it("removes a suggestion's info the current batch", done => {
+ testAction(
+ actions.removeSuggestionInfoFromBatch,
+ suggestionInfo.suggestionId,
+ { batchSuggestionsInfo: [suggestionInfo] },
+ [{ type: 'REMOVE_SUGGESTION_FROM_BATCH', payload: suggestionInfo.suggestionId }],
+ [],
+ done,
+ );
+ });
+ });
+
describe('filterDiscussion', () => {
const path = 'some-discussion-path';
const filter = 0;
@@ -942,4 +1083,75 @@ describe('Actions Notes Store', () => {
);
});
});
+
+ describe('softDeleteDescriptionVersion', () => {
+ const endpoint = '/path/to/diff/1';
+ const payload = {
+ endpoint,
+ startingVersion: undefined,
+ versionId: 1,
+ };
+
+ describe('if response contains no errors', () => {
+ it('dispatches requestDeleteDescriptionVersion', done => {
+ axiosMock.onDelete(endpoint).replyOnce(200);
+ testAction(
+ actions.softDeleteDescriptionVersion,
+ payload,
+ {},
+ [],
+ [
+ {
+ type: 'requestDeleteDescriptionVersion',
+ },
+ {
+ type: 'receiveDeleteDescriptionVersion',
+ payload: payload.versionId,
+ },
+ ],
+ done,
+ );
+ });
+ });
+
+ describe('if response contains errors', () => {
+ const errorMessage = 'Request failed with status code 503';
+ it('dispatches receiveDeleteDescriptionVersionError and throws an error', done => {
+ axiosMock.onDelete(endpoint).replyOnce(503);
+ testAction(
+ actions.softDeleteDescriptionVersion,
+ payload,
+ {},
+ [],
+ [
+ {
+ type: 'requestDeleteDescriptionVersion',
+ },
+ {
+ type: 'receiveDeleteDescriptionVersionError',
+ payload: new Error(errorMessage),
+ },
+ ],
+ )
+ .then(() => done.fail('Expected error to be thrown'))
+ .catch(() => {
+ expect(Flash).toHaveBeenCalled();
+ done();
+ });
+ });
+ });
+ });
+
+ describe('updateAssignees', () => {
+ it('update the assignees state', done => {
+ testAction(
+ actions.updateAssignees,
+ [userDataMock.id],
+ { state: noteableDataMock },
+ [{ type: mutationTypes.UPDATE_ASSIGNEES, payload: [userDataMock.id] }],
+ [],
+ done,
+ );
+ });
+ });
});
diff --git a/spec/frontend/notes/stores/mutation_spec.js b/spec/frontend/notes/stores/mutation_spec.js
index 27e3490d64b..75ef007b78d 100644
--- a/spec/frontend/notes/stores/mutation_spec.js
+++ b/spec/frontend/notes/stores/mutation_spec.js
@@ -9,6 +9,7 @@ import {
noteableDataMock,
individualNote,
notesWithDescriptionChanges,
+ batchSuggestionsInfoMock,
} from '../mock_data';
const RESOLVED_NOTE = { resolvable: true, resolved: true };
@@ -700,4 +701,120 @@ describe('Notes Store mutations', () => {
expect(state.isToggleBlockedIssueWarning).toEqual(false);
});
});
+
+ describe('SET_APPLYING_BATCH_STATE', () => {
+ const buildDiscussions = suggestionsInfo => {
+ const suggestions = suggestionsInfo.map(({ suggestionId }) => ({ id: suggestionId }));
+
+ const notes = suggestionsInfo.map(({ noteId }, index) => ({
+ id: noteId,
+ suggestions: [suggestions[index]],
+ }));
+
+ return suggestionsInfo.map(({ discussionId }, index) => ({
+ id: discussionId,
+ notes: [notes[index]],
+ }));
+ };
+
+ let state;
+ let batchedSuggestionInfo;
+ let discussions;
+ let suggestions;
+
+ beforeEach(() => {
+ [batchedSuggestionInfo] = batchSuggestionsInfoMock;
+ suggestions = batchSuggestionsInfoMock.map(({ suggestionId }) => ({ id: suggestionId }));
+ discussions = buildDiscussions(batchSuggestionsInfoMock);
+ state = {
+ batchSuggestionsInfo: [batchedSuggestionInfo],
+ discussions,
+ };
+ });
+
+ it('sets is_applying_batch to a boolean value for all batched suggestions', () => {
+ mutations.SET_APPLYING_BATCH_STATE(state, true);
+
+ const updatedSuggestion = {
+ ...suggestions[0],
+ is_applying_batch: true,
+ };
+
+ const expectedSuggestions = [updatedSuggestion, suggestions[1]];
+
+ const actualSuggestions = state.discussions
+ .map(discussion => discussion.notes.map(n => n.suggestions))
+ .flat(2);
+
+ expect(actualSuggestions).toEqual(expectedSuggestions);
+ });
+ });
+
+ describe('ADD_SUGGESTION_TO_BATCH', () => {
+ let state;
+
+ beforeEach(() => {
+ state = { batchSuggestionsInfo: [] };
+ });
+
+ it("adds a suggestion's info to a batch", () => {
+ const suggestionInfo = {
+ suggestionId: 'a123',
+ noteId: 'b456',
+ discussionId: 'c789',
+ };
+
+ mutations.ADD_SUGGESTION_TO_BATCH(state, suggestionInfo);
+
+ expect(state.batchSuggestionsInfo).toEqual([suggestionInfo]);
+ });
+ });
+
+ describe('REMOVE_SUGGESTION_FROM_BATCH', () => {
+ let state;
+ let suggestionInfo1;
+ let suggestionInfo2;
+
+ beforeEach(() => {
+ [suggestionInfo1, suggestionInfo2] = batchSuggestionsInfoMock;
+
+ state = {
+ batchSuggestionsInfo: [suggestionInfo1, suggestionInfo2],
+ };
+ });
+
+ it("removes a suggestion's info from a batch", () => {
+ mutations.REMOVE_SUGGESTION_FROM_BATCH(state, suggestionInfo1.suggestionId);
+
+ expect(state.batchSuggestionsInfo).toEqual([suggestionInfo2]);
+ });
+ });
+
+ describe('CLEAR_SUGGESTION_BATCH', () => {
+ let state;
+
+ beforeEach(() => {
+ state = {
+ batchSuggestionsInfo: batchSuggestionsInfoMock,
+ };
+ });
+
+ it('removes info for all suggestions from a batch', () => {
+ mutations.CLEAR_SUGGESTION_BATCH(state);
+
+ expect(state.batchSuggestionsInfo.length).toEqual(0);
+ });
+ });
+
+ describe('UPDATE_ASSIGNEES', () => {
+ it('should update assignees', () => {
+ const state = {
+ noteableData: noteableDataMock,
+ };
+
+ mutations.UPDATE_ASSIGNEES(state, [userDataMock.id]);
+
+ expect(state.noteableData.assignees).toEqual([userDataMock.id]);
+ });
+ });
});
diff --git a/spec/frontend/oauth_remember_me_spec.js b/spec/frontend/oauth_remember_me_spec.js
index 381be82697e..e12db05ac43 100644
--- a/spec/frontend/oauth_remember_me_spec.js
+++ b/spec/frontend/oauth_remember_me_spec.js
@@ -2,6 +2,12 @@ import $ from 'jquery';
import OAuthRememberMe from '~/pages/sessions/new/oauth_remember_me';
describe('OAuthRememberMe', () => {
+ const findFormAction = selector => {
+ return $(`#oauth-container .oauth-login${selector}`)
+ .parent('form')
+ .attr('action');
+ };
+
preloadFixtures('static/oauth_remember_me.html');
beforeEach(() => {
@@ -13,15 +19,9 @@ describe('OAuthRememberMe', () => {
it('adds the "remember_me" query parameter to all OAuth login buttons', () => {
$('#oauth-container #remember_me').click();
- expect($('#oauth-container .oauth-login.twitter').attr('href')).toBe(
- 'http://example.com/?remember_me=1',
- );
-
- expect($('#oauth-container .oauth-login.github').attr('href')).toBe(
- 'http://example.com/?remember_me=1',
- );
-
- expect($('#oauth-container .oauth-login.facebook').attr('href')).toBe(
+ expect(findFormAction('.twitter')).toBe('http://example.com/?remember_me=1');
+ expect(findFormAction('.github')).toBe('http://example.com/?remember_me=1');
+ expect(findFormAction('.facebook')).toBe(
'http://example.com/?redirect_fragment=L1&remember_me=1',
);
});
@@ -30,10 +30,8 @@ describe('OAuthRememberMe', () => {
$('#oauth-container #remember_me').click();
$('#oauth-container #remember_me').click();
- expect($('#oauth-container .oauth-login.twitter').attr('href')).toBe('http://example.com/');
- expect($('#oauth-container .oauth-login.github').attr('href')).toBe('http://example.com/');
- expect($('#oauth-container .oauth-login.facebook').attr('href')).toBe(
- 'http://example.com/?redirect_fragment=L1',
- );
+ expect(findFormAction('.twitter')).toBe('http://example.com/');
+ expect(findFormAction('.github')).toBe('http://example.com/');
+ expect(findFormAction('.facebook')).toBe('http://example.com/?redirect_fragment=L1');
});
});
diff --git a/spec/frontend/onboarding_issues/index_spec.js b/spec/frontend/onboarding_issues/index_spec.js
new file mode 100644
index 00000000000..b844caa07aa
--- /dev/null
+++ b/spec/frontend/onboarding_issues/index_spec.js
@@ -0,0 +1,137 @@
+import $ from 'jquery';
+import { showLearnGitLabIssuesPopover } from '~/onboarding_issues';
+import { getCookie, setCookie, removeCookie } from '~/lib/utils/common_utils';
+import setWindowLocation from 'helpers/set_window_location_helper';
+import Tracking from '~/tracking';
+
+describe('Onboarding Issues Popovers', () => {
+ const COOKIE_NAME = 'onboarding_issues_settings';
+ const getCookieValue = () => JSON.parse(getCookie(COOKIE_NAME));
+
+ beforeEach(() => {
+ jest.spyOn($.fn, 'popover');
+ });
+
+ afterEach(() => {
+ $.fn.popover.mockRestore();
+ document.getElementsByTagName('html')[0].innerHTML = '';
+ removeCookie(COOKIE_NAME);
+ });
+
+ const setupShowLearnGitLabIssuesPopoverTest = ({
+ currentPath = 'group/learn-gitlab',
+ isIssuesBoardsLinkShown = true,
+ isCookieSet = true,
+ cookieValue = true,
+ } = {}) => {
+ setWindowLocation(`http://example.com/${currentPath}`);
+
+ if (isIssuesBoardsLinkShown) {
+ const elem = document.createElement('a');
+ elem.setAttribute('data-qa-selector', 'issue_boards_link');
+ document.body.appendChild(elem);
+ }
+
+ if (isCookieSet) {
+ setCookie(COOKIE_NAME, { previous: true, 'issues#index': cookieValue });
+ }
+
+ showLearnGitLabIssuesPopover();
+ };
+
+ describe('showLearnGitLabIssuesPopover', () => {
+ describe('when on another project', () => {
+ beforeEach(() => {
+ setupShowLearnGitLabIssuesPopoverTest({
+ currentPath: 'group/another-project',
+ });
+ });
+
+ it('does not show a popover', () => {
+ expect($.fn.popover).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('when the issues boards link is not shown', () => {
+ beforeEach(() => {
+ setupShowLearnGitLabIssuesPopoverTest({
+ isIssuesBoardsLinkShown: false,
+ });
+ });
+
+ it('does not show a popover', () => {
+ expect($.fn.popover).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('when the cookie is not set', () => {
+ beforeEach(() => {
+ setupShowLearnGitLabIssuesPopoverTest({
+ isCookieSet: false,
+ });
+ });
+
+ it('does not show a popover', () => {
+ expect($.fn.popover).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('when the cookie value is false', () => {
+ beforeEach(() => {
+ setupShowLearnGitLabIssuesPopoverTest({
+ cookieValue: false,
+ });
+ });
+
+ it('does not show a popover', () => {
+ expect($.fn.popover).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('with all the right conditions', () => {
+ beforeEach(() => {
+ setupShowLearnGitLabIssuesPopoverTest();
+ });
+
+ it('shows a popover', () => {
+ expect($.fn.popover).toHaveBeenCalled();
+ });
+
+ it('does not change the cookie value', () => {
+ expect(getCookieValue()['issues#index']).toBe(true);
+ });
+
+ it('disables the previous popover', () => {
+ expect(getCookieValue().previous).toBe(false);
+ });
+
+ describe('when clicking the issues boards link', () => {
+ beforeEach(() => {
+ document.querySelector('a[data-qa-selector="issue_boards_link"]').click();
+ });
+
+ it('deletes the cookie', () => {
+ expect(getCookie(COOKIE_NAME)).toBe(undefined);
+ });
+ });
+
+ describe('when dismissing the popover', () => {
+ beforeEach(() => {
+ jest.spyOn(Tracking, 'event');
+ document.querySelector('.learn-gitlab.popover .close').click();
+ });
+
+ it('deletes the cookie', () => {
+ expect(getCookie(COOKIE_NAME)).toBe(undefined);
+ });
+
+ it('sends a tracking event', () => {
+ expect(Tracking.event).toHaveBeenCalledWith(
+ 'Growth::Conversion::Experiment::OnboardingIssues',
+ 'dismiss_popover',
+ );
+ });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/operation_settings/components/external_dashboard_spec.js b/spec/frontend/operation_settings/components/external_dashboard_spec.js
deleted file mode 100644
index 19214d1d954..00000000000
--- a/spec/frontend/operation_settings/components/external_dashboard_spec.js
+++ /dev/null
@@ -1,168 +0,0 @@
-import { mount, shallowMount } from '@vue/test-utils';
-import { GlDeprecatedButton, GlLink, GlFormGroup, GlFormInput } from '@gitlab/ui';
-import { TEST_HOST } from 'helpers/test_constants';
-import ExternalDashboard from '~/operation_settings/components/external_dashboard.vue';
-import store from '~/operation_settings/store';
-import axios from '~/lib/utils/axios_utils';
-import { refreshCurrentPage } from '~/lib/utils/url_utility';
-import createFlash from '~/flash';
-
-jest.mock('~/lib/utils/url_utility');
-jest.mock('~/flash');
-
-describe('operation settings external dashboard component', () => {
- let wrapper;
- const operationsSettingsEndpoint = `${TEST_HOST}/mock/ops/settings/endpoint`;
- const externalDashboardUrl = `http://mock-external-domain.com/external/dashboard/url`;
- const externalDashboardHelpPagePath = `${TEST_HOST}/help/page/path`;
- const mountComponent = (shallow = true) => {
- const config = [
- ExternalDashboard,
- {
- store: store({
- operationsSettingsEndpoint,
- externalDashboardUrl,
- externalDashboardHelpPagePath,
- }),
- },
- ];
- wrapper = shallow ? shallowMount(...config) : mount(...config);
- };
-
- beforeEach(() => {
- jest.spyOn(axios, 'patch').mockImplementation();
- });
-
- afterEach(() => {
- if (wrapper.destroy) {
- wrapper.destroy();
- }
- axios.patch.mockReset();
- refreshCurrentPage.mockReset();
- createFlash.mockReset();
- });
-
- it('renders header text', () => {
- mountComponent();
- expect(wrapper.find('.js-section-header').text()).toBe('External Dashboard');
- });
-
- describe('expand/collapse button', () => {
- it('renders as an expand button by default', () => {
- const button = wrapper.find(GlDeprecatedButton);
-
- expect(button.text()).toBe('Expand');
- });
- });
-
- describe('sub-header', () => {
- let subHeader;
-
- beforeEach(() => {
- mountComponent();
- subHeader = wrapper.find('.js-section-sub-header');
- });
-
- it('renders descriptive text', () => {
- expect(subHeader.text()).toContain(
- 'Add a button to the metrics dashboard linking directly to your existing external dashboards.',
- );
- });
-
- it('renders help page link', () => {
- const link = subHeader.find(GlLink);
-
- expect(link.text()).toBe('Learn more');
- expect(link.attributes().href).toBe(externalDashboardHelpPagePath);
- });
- });
-
- describe('form', () => {
- describe('input label', () => {
- let formGroup;
-
- beforeEach(() => {
- mountComponent();
- formGroup = wrapper.find(GlFormGroup);
- });
-
- it('uses label text', () => {
- expect(formGroup.attributes().label).toBe('Full dashboard URL');
- });
-
- it('uses description text', () => {
- expect(formGroup.attributes().description).toBe(
- 'Enter the URL of the dashboard you want to link to',
- );
- });
- });
-
- describe('input field', () => {
- let input;
-
- beforeEach(() => {
- mountComponent();
- input = wrapper.find(GlFormInput);
- });
-
- it('defaults to externalDashboardUrl', () => {
- expect(input.attributes().value).toBe(externalDashboardUrl);
- });
-
- it('uses a placeholder', () => {
- expect(input.attributes().placeholder).toBe('https://my-org.gitlab.io/my-dashboards');
- });
- });
-
- describe('submit button', () => {
- const findSubmitButton = () =>
- wrapper.find('.settings-content form').find(GlDeprecatedButton);
-
- const endpointRequest = [
- operationsSettingsEndpoint,
- {
- project: {
- metrics_setting_attributes: {
- external_dashboard_url: externalDashboardUrl,
- },
- },
- },
- ];
-
- it('renders button label', () => {
- mountComponent();
- const submit = findSubmitButton();
- expect(submit.text()).toBe('Save Changes');
- });
-
- it('submits form on click', () => {
- mountComponent(false);
- axios.patch.mockResolvedValue();
- findSubmitButton().trigger('click');
-
- expect(axios.patch).toHaveBeenCalledWith(...endpointRequest);
-
- return wrapper.vm.$nextTick().then(() => expect(refreshCurrentPage).toHaveBeenCalled());
- });
-
- it('creates flash banner on error', () => {
- mountComponent(false);
- const message = 'mockErrorMessage';
- axios.patch.mockRejectedValue({ response: { data: { message } } });
- findSubmitButton().trigger('click');
-
- expect(axios.patch).toHaveBeenCalledWith(...endpointRequest);
-
- return wrapper.vm
- .$nextTick()
- .then(jest.runAllTicks)
- .then(() =>
- expect(createFlash).toHaveBeenCalledWith(
- `There was an error saving your changes. ${message}`,
- 'alert',
- ),
- );
- });
- });
- });
-});
diff --git a/spec/frontend/operation_settings/components/metrics_settings_spec.js b/spec/frontend/operation_settings/components/metrics_settings_spec.js
new file mode 100644
index 00000000000..398b61ec693
--- /dev/null
+++ b/spec/frontend/operation_settings/components/metrics_settings_spec.js
@@ -0,0 +1,214 @@
+import { mount, shallowMount } from '@vue/test-utils';
+import { GlDeprecatedButton, GlLink, GlFormGroup, GlFormInput, GlFormSelect } from '@gitlab/ui';
+import { TEST_HOST } from 'helpers/test_constants';
+import MetricsSettings from '~/operation_settings/components/metrics_settings.vue';
+
+import ExternalDashboard from '~/operation_settings/components/form_group/external_dashboard.vue';
+import DashboardTimezone from '~/operation_settings/components/form_group/dashboard_timezone.vue';
+import { timezones } from '~/monitoring/format_date';
+import store from '~/operation_settings/store';
+import axios from '~/lib/utils/axios_utils';
+import { refreshCurrentPage } from '~/lib/utils/url_utility';
+import createFlash from '~/flash';
+
+jest.mock('~/lib/utils/url_utility');
+jest.mock('~/flash');
+
+describe('operation settings external dashboard component', () => {
+ let wrapper;
+
+ const operationsSettingsEndpoint = `${TEST_HOST}/mock/ops/settings/endpoint`;
+ const helpPage = `${TEST_HOST}/help/metrics/page/path`;
+ const externalDashboardUrl = `http://mock-external-domain.com/external/dashboard/url`;
+ const dashboardTimezoneSetting = timezones.LOCAL;
+
+ const mountComponent = (shallow = true) => {
+ const config = [
+ MetricsSettings,
+ {
+ store: store({
+ operationsSettingsEndpoint,
+ helpPage,
+ externalDashboardUrl,
+ dashboardTimezoneSetting,
+ }),
+ stubs: {
+ ExternalDashboard,
+ DashboardTimezone,
+ },
+ },
+ ];
+ wrapper = shallow ? shallowMount(...config) : mount(...config);
+ };
+
+ beforeEach(() => {
+ jest.spyOn(axios, 'patch').mockImplementation();
+ });
+
+ afterEach(() => {
+ if (wrapper.destroy) {
+ wrapper.destroy();
+ }
+ axios.patch.mockReset();
+ refreshCurrentPage.mockReset();
+ createFlash.mockReset();
+ });
+
+ it('renders header text', () => {
+ mountComponent();
+ expect(wrapper.find('.js-section-header').text()).toBe('Metrics Dashboard');
+ });
+
+ describe('expand/collapse button', () => {
+ it('renders as an expand button by default', () => {
+ const button = wrapper.find(GlDeprecatedButton);
+
+ expect(button.text()).toBe('Expand');
+ });
+ });
+
+ describe('sub-header', () => {
+ let subHeader;
+
+ beforeEach(() => {
+ mountComponent();
+ subHeader = wrapper.find('.js-section-sub-header');
+ });
+
+ it('renders descriptive text', () => {
+ expect(subHeader.text()).toContain('Manage Metrics Dashboard settings.');
+ });
+
+ it('renders help page link', () => {
+ const link = subHeader.find(GlLink);
+
+ expect(link.text()).toBe('Learn more');
+ expect(link.attributes().href).toBe(helpPage);
+ });
+ });
+
+ describe('form', () => {
+ describe('dashboard timezone', () => {
+ describe('field label', () => {
+ let formGroup;
+
+ beforeEach(() => {
+ mountComponent(false);
+ formGroup = wrapper.find(DashboardTimezone).find(GlFormGroup);
+ });
+
+ it('uses label text', () => {
+ expect(formGroup.find('label').text()).toBe('Dashboard timezone');
+ });
+
+ it('uses description text', () => {
+ const description = formGroup.find('small');
+ expect(description.text()).not.toBeFalsy();
+ });
+ });
+
+ describe('select field', () => {
+ let select;
+
+ beforeEach(() => {
+ mountComponent();
+ select = wrapper.find(DashboardTimezone).find(GlFormSelect);
+ });
+
+ it('defaults to externalDashboardUrl', () => {
+ expect(select.attributes('value')).toBe(dashboardTimezoneSetting);
+ });
+ });
+ });
+
+ describe('external dashboard', () => {
+ describe('input label', () => {
+ let formGroup;
+
+ beforeEach(() => {
+ mountComponent(false);
+ formGroup = wrapper.find(ExternalDashboard).find(GlFormGroup);
+ });
+
+ it('uses label text', () => {
+ expect(formGroup.find('label').text()).toBe('External dashboard URL');
+ });
+
+ it('uses description text', () => {
+ const description = formGroup.find('small');
+ expect(description.text()).not.toBeFalsy();
+ });
+ });
+
+ describe('input field', () => {
+ let input;
+
+ beforeEach(() => {
+ mountComponent();
+ input = wrapper.find(ExternalDashboard).find(GlFormInput);
+ });
+
+ it('defaults to externalDashboardUrl', () => {
+ expect(input.attributes().value).toBeTruthy();
+ expect(input.attributes().value).toBe(externalDashboardUrl);
+ });
+
+ it('uses a placeholder', () => {
+ expect(input.attributes().placeholder).toBe('https://my-org.gitlab.io/my-dashboards');
+ });
+ });
+ });
+
+ describe('submit button', () => {
+ const findSubmitButton = () =>
+ wrapper.find('.settings-content form').find(GlDeprecatedButton);
+
+ const endpointRequest = [
+ operationsSettingsEndpoint,
+ {
+ project: {
+ metrics_setting_attributes: {
+ dashboard_timezone: dashboardTimezoneSetting,
+ external_dashboard_url: externalDashboardUrl,
+ },
+ },
+ },
+ ];
+
+ it('renders button label', () => {
+ mountComponent();
+ const submit = findSubmitButton();
+ expect(submit.text()).toBe('Save Changes');
+ });
+
+ it('submits form on click', () => {
+ mountComponent(false);
+ axios.patch.mockResolvedValue();
+ findSubmitButton().trigger('click');
+
+ expect(axios.patch).toHaveBeenCalledWith(...endpointRequest);
+
+ return wrapper.vm.$nextTick().then(() => expect(refreshCurrentPage).toHaveBeenCalled());
+ });
+
+ it('creates flash banner on error', () => {
+ mountComponent(false);
+ const message = 'mockErrorMessage';
+ axios.patch.mockRejectedValue({ response: { data: { message } } });
+ findSubmitButton().trigger('click');
+
+ expect(axios.patch).toHaveBeenCalledWith(...endpointRequest);
+
+ return wrapper.vm
+ .$nextTick()
+ .then(jest.runAllTicks)
+ .then(() =>
+ expect(createFlash).toHaveBeenCalledWith(
+ `There was an error saving your changes. ${message}`,
+ 'alert',
+ ),
+ );
+ });
+ });
+ });
+});
diff --git a/spec/frontend/operation_settings/store/mutations_spec.js b/spec/frontend/operation_settings/store/mutations_spec.js
index 1854142c89a..88eb66095ad 100644
--- a/spec/frontend/operation_settings/store/mutations_spec.js
+++ b/spec/frontend/operation_settings/store/mutations_spec.js
@@ -1,5 +1,6 @@
import mutations from '~/operation_settings/store/mutations';
import createState from '~/operation_settings/store/state';
+import { timezones } from '~/monitoring/format_date';
describe('operation settings mutations', () => {
let localState;
@@ -13,7 +14,16 @@ describe('operation settings mutations', () => {
const mockUrl = 'mockUrl';
mutations.SET_EXTERNAL_DASHBOARD_URL(localState, mockUrl);
- expect(localState.externalDashboardUrl).toBe(mockUrl);
+ expect(localState.externalDashboard.url).toBe(mockUrl);
+ });
+ });
+
+ describe('SET_DASHBOARD_TIMEZONE', () => {
+ it('sets dashboardTimezoneSetting', () => {
+ mutations.SET_DASHBOARD_TIMEZONE(localState, timezones.LOCAL);
+
+ expect(localState.dashboardTimezone.selected).not.toBeUndefined();
+ expect(localState.dashboardTimezone.selected).toBe(timezones.LOCAL);
});
});
});
diff --git a/spec/frontend/pager_spec.js b/spec/frontend/pager_spec.js
new file mode 100644
index 00000000000..d7177a32cde
--- /dev/null
+++ b/spec/frontend/pager_spec.js
@@ -0,0 +1,167 @@
+import $ from 'jquery';
+import MockAdapter from 'axios-mock-adapter';
+import axios from '~/lib/utils/axios_utils';
+import Pager from '~/pager';
+import { removeParams } from '~/lib/utils/url_utility';
+
+jest.mock('~/lib/utils/url_utility', () => ({
+ removeParams: jest.fn().mockName('removeParams'),
+}));
+
+describe('pager', () => {
+ let axiosMock;
+
+ beforeEach(() => {
+ axiosMock = new MockAdapter(axios);
+ });
+
+ afterEach(() => {
+ axiosMock.restore();
+ });
+
+ describe('init', () => {
+ const originalHref = window.location.href;
+
+ beforeEach(() => {
+ setFixtures('<div class="content_list"></div><div class="loading"></div>');
+ jest.spyOn($.fn, 'endlessScroll').mockImplementation();
+ });
+
+ afterEach(() => {
+ window.history.replaceState({}, null, originalHref);
+ });
+
+ it('should use data-href attribute from list element', () => {
+ const href = `${gl.TEST_HOST}/some_list.json`;
+ setFixtures(`<div class="content_list" data-href="${href}"></div>`);
+ Pager.init();
+
+ expect(Pager.url).toBe(href);
+ });
+
+ it('should use current url if data-href attribute not provided', () => {
+ const href = `${gl.TEST_HOST}/some_list`;
+ removeParams.mockReturnValue(href);
+ Pager.init();
+
+ expect(Pager.url).toBe(href);
+ });
+
+ it('should get initial offset from query parameter', () => {
+ window.history.replaceState({}, null, '?offset=100');
+ Pager.init();
+
+ expect(Pager.offset).toBe(100);
+ });
+
+ it('keeps extra query parameters from url', () => {
+ window.history.replaceState({}, null, '?filter=test&offset=100');
+ const href = `${gl.TEST_HOST}/some_list?filter=test`;
+ removeParams.mockReturnValue(href);
+ Pager.init();
+
+ expect(removeParams).toHaveBeenCalledWith(['limit', 'offset']);
+ expect(Pager.url).toEqual(href);
+ });
+ });
+
+ describe('getOld', () => {
+ const urlRegex = /(.*)some_list(.*)$/;
+
+ function mockSuccess(count = 0) {
+ axiosMock.onGet(urlRegex).reply(200, {
+ count,
+ html: '',
+ });
+ }
+
+ function mockError() {
+ axiosMock.onGet(urlRegex).networkError();
+ }
+
+ beforeEach(() => {
+ setFixtures(
+ '<div class="content_list" data-href="/some_list"></div><div class="loading"></div>',
+ );
+ jest.spyOn(axios, 'get');
+
+ Pager.init();
+ });
+
+ it('shows loader while loading next page', done => {
+ mockSuccess();
+
+ jest.spyOn(Pager.loading, 'show').mockImplementation(() => {});
+ Pager.getOld();
+
+ setImmediate(() => {
+ expect(Pager.loading.show).toHaveBeenCalled();
+
+ done();
+ });
+ });
+
+ it('hides loader on success', done => {
+ mockSuccess();
+
+ jest.spyOn(Pager.loading, 'hide').mockImplementation(() => {});
+ Pager.getOld();
+
+ setImmediate(() => {
+ expect(Pager.loading.hide).toHaveBeenCalled();
+
+ done();
+ });
+ });
+
+ it('hides loader on error', done => {
+ mockError();
+
+ jest.spyOn(Pager.loading, 'hide').mockImplementation(() => {});
+ Pager.getOld();
+
+ setImmediate(() => {
+ expect(Pager.loading.hide).toHaveBeenCalled();
+
+ done();
+ });
+ });
+
+ it('sends request to url with offset and limit params', done => {
+ Pager.offset = 100;
+ Pager.limit = 20;
+ Pager.getOld();
+
+ setImmediate(() => {
+ const [url, params] = axios.get.mock.calls[0];
+
+ expect(params).toEqual({
+ params: {
+ limit: 20,
+ offset: 100,
+ },
+ });
+
+ expect(url).toBe('/some_list');
+
+ done();
+ });
+ });
+
+ it('disables if return count is less than limit', done => {
+ Pager.offset = 0;
+ Pager.limit = 20;
+
+ mockSuccess(1);
+ jest.spyOn(Pager.loading, 'hide').mockImplementation(() => {});
+ Pager.getOld();
+
+ setImmediate(() => {
+ expect(Pager.loading.hide).toHaveBeenCalled();
+ expect(Pager.disable).toBe(true);
+
+ done();
+ });
+ });
+ });
+});
diff --git a/spec/frontend/pages/dashboard/todos/index/todos_spec.js b/spec/frontend/pages/dashboard/todos/index/todos_spec.js
new file mode 100644
index 00000000000..204fe3d0a68
--- /dev/null
+++ b/spec/frontend/pages/dashboard/todos/index/todos_spec.js
@@ -0,0 +1,111 @@
+import $ from 'jquery';
+import MockAdapter from 'axios-mock-adapter';
+import Todos from '~/pages/dashboard/todos/index/todos';
+import '~/lib/utils/common_utils';
+import '~/gl_dropdown';
+import axios from '~/lib/utils/axios_utils';
+import { addDelimiter } from '~/lib/utils/text_utility';
+import { visitUrl } from '~/lib/utils/url_utility';
+
+jest.mock('~/lib/utils/url_utility', () => ({
+ visitUrl: jest.fn().mockName('visitUrl'),
+}));
+
+const TEST_COUNT_BIG = 2000;
+const TEST_DONE_COUNT_BIG = 7300;
+
+describe('Todos', () => {
+ preloadFixtures('todos/todos.html');
+ let todoItem;
+ let mock;
+
+ beforeEach(() => {
+ loadFixtures('todos/todos.html');
+ todoItem = document.querySelector('.todos-list .todo');
+ mock = new MockAdapter(axios);
+
+ return new Todos();
+ });
+
+ afterEach(() => {
+ mock.restore();
+ });
+
+ describe('goToTodoUrl', () => {
+ it('opens the todo url', done => {
+ const todoLink = todoItem.dataset.url;
+
+ visitUrl.mockImplementation(url => {
+ expect(url).toEqual(todoLink);
+ done();
+ });
+
+ todoItem.click();
+ });
+
+ describe('meta click', () => {
+ let windowOpenSpy;
+ let metakeyEvent;
+
+ beforeEach(() => {
+ metakeyEvent = $.Event('click', { keyCode: 91, ctrlKey: true });
+ windowOpenSpy = jest.spyOn(window, 'open').mockImplementation(() => {});
+ });
+
+ it('opens the todo url in another tab', () => {
+ const todoLink = todoItem.dataset.url;
+
+ $('.todos-list .todo').trigger(metakeyEvent);
+
+ expect(visitUrl).not.toHaveBeenCalled();
+ expect(windowOpenSpy).toHaveBeenCalledWith(todoLink, '_blank');
+ });
+
+ it('run native funcionality when avatar is clicked', () => {
+ $('.todos-list a').on('click', e => e.preventDefault());
+ $('.todos-list img').trigger(metakeyEvent);
+
+ expect(visitUrl).not.toHaveBeenCalled();
+ expect(windowOpenSpy).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('on done todo click', () => {
+ let onToggleSpy;
+
+ beforeEach(done => {
+ const el = document.querySelector('.js-done-todo');
+ const path = el.dataset.href;
+
+ // Arrange
+ mock
+ .onDelete(path)
+ .replyOnce(200, { count: TEST_COUNT_BIG, done_count: TEST_DONE_COUNT_BIG });
+ onToggleSpy = jest.fn();
+ $(document).on('todo:toggle', onToggleSpy);
+
+ // Act
+ el.click();
+
+ // Wait for axios and HTML to udpate
+ setImmediate(done);
+ });
+
+ it('dispatches todo:toggle', () => {
+ expect(onToggleSpy).toHaveBeenCalledWith(expect.anything(), TEST_COUNT_BIG);
+ });
+
+ it('updates pending text', () => {
+ expect(document.querySelector('.todos-pending .badge').innerHTML).toEqual(
+ addDelimiter(TEST_COUNT_BIG),
+ );
+ });
+
+ it('updates done text', () => {
+ expect(document.querySelector('.todos-done .badge').innerHTML).toEqual(
+ addDelimiter(TEST_DONE_COUNT_BIG),
+ );
+ });
+ });
+ });
+});
diff --git a/spec/frontend/pages/import/bitbucket_server/components/bitbucket_server_status_table_spec.js b/spec/frontend/pages/import/bitbucket_server/components/bitbucket_server_status_table_spec.js
new file mode 100644
index 00000000000..0bb96ee33d4
--- /dev/null
+++ b/spec/frontend/pages/import/bitbucket_server/components/bitbucket_server_status_table_spec.js
@@ -0,0 +1,47 @@
+import { shallowMount } from '@vue/test-utils';
+
+import { GlButton } from '@gitlab/ui';
+import BitbucketServerStatusTable from '~/pages/import/bitbucket_server/status/components/bitbucket_server_status_table.vue';
+import BitbucketStatusTable from '~/import_projects/components/bitbucket_status_table.vue';
+
+const BitbucketStatusTableStub = {
+ name: 'BitbucketStatusTable',
+ template: '<div><slot name="actions"></slot></div>',
+};
+
+describe('BitbucketServerStatusTable', () => {
+ let wrapper;
+
+ const findReconfigureButton = () =>
+ wrapper
+ .findAll(GlButton)
+ .filter(w => w.props().variant === 'info')
+ .at(0);
+
+ afterEach(() => {
+ if (wrapper) {
+ wrapper.destroy();
+ wrapper = null;
+ }
+ });
+
+ function createComponent(bitbucketStatusTableStub = true) {
+ wrapper = shallowMount(BitbucketServerStatusTable, {
+ propsData: { providerTitle: 'Test', reconfigurePath: '/reconfigure' },
+ stubs: {
+ BitbucketStatusTable: bitbucketStatusTableStub,
+ },
+ });
+ }
+
+ it('renders bitbucket status table component', () => {
+ createComponent();
+ expect(wrapper.contains(BitbucketStatusTable)).toBe(true);
+ });
+
+ it('renders Reconfigure button', async () => {
+ createComponent(BitbucketStatusTableStub);
+ expect(findReconfigureButton().attributes().href).toBe('/reconfigure');
+ expect(findReconfigureButton().text()).toBe('Reconfigure');
+ });
+});
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
new file mode 100644
index 00000000000..94089ea922b
--- /dev/null
+++ b/spec/frontend/pages/projects/graphs/__snapshots__/code_coverage_spec.js.snap
@@ -0,0 +1,88 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Code Coverage when fetching data is successful matches the snapshot 1`] = `
+<div>
+ <div
+ class="gl-mt-3 gl-mb-3"
+ >
+ <!---->
+
+ <!---->
+
+ <gl-dropdown-stub
+ text="rspec"
+ >
+ <gl-dropdown-item-stub
+ value="rspec"
+ >
+ <div
+ class="gl-display-flex"
+ >
+ <gl-icon-stub
+ class="gl-absolute"
+ name="mobile-issue-close"
+ size="16"
+ />
+
+ <span
+ class="gl-display-flex align-items-center ml-4"
+ >
+
+ rspec
+
+ </span>
+ </div>
+ </gl-dropdown-item-stub>
+ <gl-dropdown-item-stub
+ value="cypress"
+ >
+ <div
+ class="gl-display-flex"
+ >
+ <!---->
+
+ <span
+ class="gl-display-flex align-items-center ml-4"
+ >
+
+ cypress
+
+ </span>
+ </div>
+ </gl-dropdown-item-stub>
+ <gl-dropdown-item-stub
+ value="karma"
+ >
+ <div
+ class="gl-display-flex"
+ >
+ <!---->
+
+ <span
+ class="gl-display-flex align-items-center ml-4"
+ >
+
+ karma
+
+ </span>
+ </div>
+ </gl-dropdown-item-stub>
+ </gl-dropdown-stub>
+ </div>
+
+ <gl-area-chart-stub
+ annotations=""
+ data="[object Object]"
+ formattooltiptext="function () { [native code] }"
+ height="200"
+ includelegendavgmax="true"
+ legendaveragetext="Avg"
+ legendcurrenttext="Current"
+ legendlayout="inline"
+ legendmaxtext="Max"
+ legendmintext="Min"
+ option="[object Object]"
+ thresholds=""
+ />
+</div>
+`;
diff --git a/spec/frontend/pages/projects/graphs/code_coverage_spec.js b/spec/frontend/pages/projects/graphs/code_coverage_spec.js
new file mode 100644
index 00000000000..4990985b076
--- /dev/null
+++ b/spec/frontend/pages/projects/graphs/code_coverage_spec.js
@@ -0,0 +1,164 @@
+import MockAdapter from 'axios-mock-adapter';
+import { shallowMount } from '@vue/test-utils';
+import { GlAlert, GlIcon, GlDropdown, GlDropdownItem } from '@gitlab/ui';
+import { GlAreaChart } from '@gitlab/ui/dist/charts';
+
+import axios from '~/lib/utils/axios_utils';
+import CodeCoverage from '~/pages/projects/graphs/components/code_coverage.vue';
+import codeCoverageMockData from './mock_data';
+import waitForPromises from 'helpers/wait_for_promises';
+import httpStatusCodes from '~/lib/utils/http_status';
+
+describe('Code Coverage', () => {
+ let wrapper;
+ let mockAxios;
+
+ const graphEndpoint = '/graph';
+
+ const findAlert = () => wrapper.find(GlAlert);
+ const findAreaChart = () => wrapper.find(GlAreaChart);
+ const findAllDropdownItems = () => wrapper.findAll(GlDropdownItem);
+ const findFirstDropdownItem = () => findAllDropdownItems().at(0);
+ const findSecondDropdownItem = () => findAllDropdownItems().at(1);
+
+ const createComponent = () => {
+ wrapper = shallowMount(CodeCoverage, {
+ propsData: {
+ graphEndpoint,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ describe('when fetching data is successful', () => {
+ beforeEach(() => {
+ mockAxios = new MockAdapter(axios);
+ mockAxios.onGet().replyOnce(httpStatusCodes.OK, codeCoverageMockData);
+
+ createComponent();
+
+ return waitForPromises();
+ });
+
+ afterEach(() => {
+ mockAxios.restore();
+ });
+
+ it('renders the area chart', () => {
+ expect(findAreaChart().exists()).toBe(true);
+ });
+
+ it('matches the snapshot', () => {
+ expect(wrapper.element).toMatchSnapshot();
+ });
+
+ it('shows no error messages', () => {
+ expect(findAlert().exists()).toBe(false);
+ });
+ });
+
+ describe('when fetching data fails', () => {
+ beforeEach(() => {
+ mockAxios = new MockAdapter(axios);
+ mockAxios.onGet().replyOnce(httpStatusCodes.BAD_REQUEST);
+
+ createComponent();
+
+ return waitForPromises();
+ });
+
+ afterEach(() => {
+ mockAxios.restore();
+ });
+
+ it('renders an error message', () => {
+ expect(findAlert().exists()).toBe(true);
+ expect(findAlert().attributes().variant).toBe('danger');
+ });
+
+ it('still renders an empty graph', () => {
+ expect(findAreaChart().exists()).toBe(true);
+ });
+ });
+
+ describe('when fetching data succeed but returns an empty state', () => {
+ beforeEach(() => {
+ mockAxios = new MockAdapter(axios);
+ mockAxios.onGet().replyOnce(httpStatusCodes.OK, []);
+
+ createComponent();
+
+ return waitForPromises();
+ });
+
+ afterEach(() => {
+ mockAxios.restore();
+ });
+
+ it('renders an information message', () => {
+ expect(findAlert().exists()).toBe(true);
+ expect(findAlert().attributes().variant).toBe('info');
+ });
+
+ it('still renders an empty graph', () => {
+ expect(findAreaChart().exists()).toBe(true);
+ });
+ });
+
+ describe('dropdown options', () => {
+ beforeEach(() => {
+ mockAxios = new MockAdapter(axios);
+ mockAxios.onGet().replyOnce(httpStatusCodes.OK, codeCoverageMockData);
+
+ createComponent();
+
+ return waitForPromises();
+ });
+
+ it('renders the dropdown with all custom names as options', () => {
+ expect(wrapper.contains(GlDropdown)).toBeDefined();
+ expect(findAllDropdownItems()).toHaveLength(codeCoverageMockData.length);
+ expect(findFirstDropdownItem().text()).toBe(codeCoverageMockData[0].group_name);
+ });
+ });
+
+ describe('interactions', () => {
+ beforeEach(() => {
+ mockAxios = new MockAdapter(axios);
+ mockAxios.onGet().replyOnce(httpStatusCodes.OK, codeCoverageMockData);
+
+ createComponent();
+
+ return waitForPromises();
+ });
+
+ it('updates the selected dropdown option with an icon', async () => {
+ findSecondDropdownItem().vm.$emit('click');
+
+ await wrapper.vm.$nextTick();
+
+ expect(
+ findFirstDropdownItem()
+ .find(GlIcon)
+ .exists(),
+ ).toBe(false);
+ expect(findSecondDropdownItem().contains(GlIcon)).toBe(true);
+ });
+
+ it('updates the graph data when selecting a different option in dropdown', async () => {
+ const originalSelectedData = wrapper.vm.selectedDailyCoverage;
+ const expectedData = codeCoverageMockData[1];
+
+ findSecondDropdownItem().vm.$emit('click');
+
+ await wrapper.vm.$nextTick();
+
+ expect(wrapper.vm.selectedDailyCoverage).not.toBe(originalSelectedData);
+ expect(wrapper.vm.selectedDailyCoverage).toBe(expectedData);
+ });
+ });
+});
diff --git a/spec/frontend/pages/projects/graphs/mock_data.js b/spec/frontend/pages/projects/graphs/mock_data.js
new file mode 100644
index 00000000000..a15f861ee7a
--- /dev/null
+++ b/spec/frontend/pages/projects/graphs/mock_data.js
@@ -0,0 +1,60 @@
+export default [
+ {
+ group_name: 'rspec',
+ data: [
+ { date: '2020-04-30', coverage: 40.0 },
+ { date: '2020-05-01', coverage: 80.0 },
+ { date: '2020-05-02', coverage: 99.0 },
+ { date: '2020-05-10', coverage: 80.0 },
+ { date: '2020-05-15', coverage: 70.0 },
+ { date: '2020-05-20', coverage: 69.0 },
+ ],
+ },
+ {
+ group_name: 'cypress',
+ data: [
+ { date: '2022-07-30', coverage: 1.0 },
+ { date: '2022-08-01', coverage: 2.4 },
+ { date: '2022-08-02', coverage: 5.0 },
+ { date: '2022-08-10', coverage: 15.0 },
+ { date: '2022-08-15', coverage: 30.0 },
+ { date: '2022-08-20', coverage: 40.0 },
+ ],
+ },
+ {
+ group_name: 'karma',
+ data: [
+ { date: '2020-05-01', coverage: 94.0 },
+ { date: '2020-05-02', coverage: 94.0 },
+ { date: '2020-05-03', coverage: 94.0 },
+ { date: '2020-05-04', coverage: 94.0 },
+ { date: '2020-05-05', coverage: 92.0 },
+ { date: '2020-05-06', coverage: 91.0 },
+ { date: '2020-05-07', coverage: 78.0 },
+ { date: '2020-05-08', coverage: 94.0 },
+ { date: '2020-05-09', coverage: 94.0 },
+ { date: '2020-05-10', coverage: 94.0 },
+ { date: '2020-05-11', coverage: 94.0 },
+ { date: '2020-05-12', coverage: 94.0 },
+ { date: '2020-05-13', coverage: 92.0 },
+ { date: '2020-05-14', coverage: 91.0 },
+ { date: '2020-05-15', coverage: 78.0 },
+ { date: '2020-05-16', coverage: 94.0 },
+ { date: '2020-05-17', coverage: 94.0 },
+ { date: '2020-05-18', coverage: 93.0 },
+ { date: '2020-05-19', coverage: 92.0 },
+ { date: '2020-05-20', coverage: 91.0 },
+ { date: '2020-05-21', coverage: 90.0 },
+ { date: '2020-05-22', coverage: 91.0 },
+ { date: '2020-05-23', coverage: 92.0 },
+ { date: '2020-05-24', coverage: 75.0 },
+ { date: '2020-05-25', coverage: 74.0 },
+ { date: '2020-05-26', coverage: 74.0 },
+ { date: '2020-05-27', coverage: 74.0 },
+ { date: '2020-05-28', coverage: 80.0 },
+ { date: '2020-05-29', coverage: 85.0 },
+ { date: '2020-05-30', coverage: 92.0 },
+ { date: '2020-05-31', coverage: 91.0 },
+ ],
+ },
+];
diff --git a/spec/frontend/pages/sessions/new/preserve_url_fragment_spec.js b/spec/frontend/pages/sessions/new/preserve_url_fragment_spec.js
index 1809e92e1d9..0d9af0cb856 100644
--- a/spec/frontend/pages/sessions/new/preserve_url_fragment_spec.js
+++ b/spec/frontend/pages/sessions/new/preserve_url_fragment_spec.js
@@ -2,6 +2,12 @@ import $ from 'jquery';
import preserveUrlFragment from '~/pages/sessions/new/preserve_url_fragment';
describe('preserve_url_fragment', () => {
+ const findFormAction = selector => {
+ return $(`.omniauth-container ${selector}`)
+ .parent('form')
+ .attr('action');
+ };
+
preloadFixtures('sessions/new.html');
beforeEach(() => {
@@ -25,35 +31,36 @@ describe('preserve_url_fragment', () => {
it('does not add an empty query parameter to OmniAuth login buttons', () => {
preserveUrlFragment();
- expect($('#oauth-login-cas3').attr('href')).toBe('http://test.host/users/auth/cas3');
+ expect(findFormAction('#oauth-login-cas3')).toBe('http://test.host/users/auth/cas3');
- expect($('.omniauth-container #oauth-login-auth0').attr('href')).toBe(
- 'http://test.host/users/auth/auth0',
- );
+ expect(findFormAction('#oauth-login-auth0')).toBe('http://test.host/users/auth/auth0');
});
describe('adds "redirect_fragment" query parameter to OmniAuth login buttons', () => {
it('when "remember_me" is not present', () => {
preserveUrlFragment('#L65');
- expect($('#oauth-login-cas3').attr('href')).toBe(
+ expect(findFormAction('#oauth-login-cas3')).toBe(
'http://test.host/users/auth/cas3?redirect_fragment=L65',
);
- expect($('.omniauth-container #oauth-login-auth0').attr('href')).toBe(
+ expect(findFormAction('#oauth-login-auth0')).toBe(
'http://test.host/users/auth/auth0?redirect_fragment=L65',
);
});
it('when "remember-me" is present', () => {
- $('a.omniauth-btn').attr('href', (i, href) => `${href}?remember_me=1`);
+ $('.omniauth-btn')
+ .parent('form')
+ .attr('action', (i, href) => `${href}?remember_me=1`);
+
preserveUrlFragment('#L65');
- expect($('#oauth-login-cas3').attr('href')).toBe(
+ expect(findFormAction('#oauth-login-cas3')).toBe(
'http://test.host/users/auth/cas3?remember_me=1&redirect_fragment=L65',
);
- expect($('#oauth-login-auth0').attr('href')).toBe(
+ expect(findFormAction('#oauth-login-auth0')).toBe(
'http://test.host/users/auth/auth0?remember_me=1&redirect_fragment=L65',
);
});
diff --git a/spec/frontend/pages/sessions/new/signin_tabs_memoizer_spec.js b/spec/frontend/pages/sessions/new/signin_tabs_memoizer_spec.js
new file mode 100644
index 00000000000..738498edbd3
--- /dev/null
+++ b/spec/frontend/pages/sessions/new/signin_tabs_memoizer_spec.js
@@ -0,0 +1,218 @@
+import AccessorUtilities from '~/lib/utils/accessor';
+import SigninTabsMemoizer from '~/pages/sessions/new/signin_tabs_memoizer';
+import trackData from '~/pages/sessions/new/index';
+import Tracking from '~/tracking';
+import { useLocalStorageSpy } from 'helpers/local_storage_helper';
+
+useLocalStorageSpy();
+
+describe('SigninTabsMemoizer', () => {
+ const fixtureTemplate = 'static/signin_tabs.html';
+ const tabSelector = 'ul.new-session-tabs';
+ const currentTabKey = 'current_signin_tab';
+ let memo;
+
+ function createMemoizer() {
+ memo = new SigninTabsMemoizer({
+ currentTabKey,
+ tabSelector,
+ });
+ return memo;
+ }
+
+ preloadFixtures(fixtureTemplate);
+
+ beforeEach(() => {
+ loadFixtures(fixtureTemplate);
+
+ jest.spyOn(AccessorUtilities, 'isLocalStorageAccessSafe').mockReturnValue(true);
+ });
+
+ it('does nothing if no tab was previously selected', () => {
+ createMemoizer();
+
+ expect(document.querySelector(`${tabSelector} > li.active a`).getAttribute('href')).toEqual(
+ '#ldap',
+ );
+ });
+
+ it('shows last selected tab on boot', () => {
+ createMemoizer().saveData('#ldap');
+ const fakeTab = {
+ click: () => {},
+ };
+ jest.spyOn(document, 'querySelector').mockReturnValue(fakeTab);
+ jest.spyOn(fakeTab, 'click').mockImplementation(() => {});
+
+ memo.bootstrap();
+
+ // verify that triggers click on the last selected tab
+ expect(document.querySelector).toHaveBeenCalledWith(`${tabSelector} a[href="#ldap"]`);
+ expect(fakeTab.click).toHaveBeenCalled();
+ });
+
+ it('clicks the first tab if value in local storage is bad', () => {
+ createMemoizer().saveData('#bogus');
+ const fakeTab = {
+ click: jest.fn().mockName('fakeTab_click'),
+ };
+ jest
+ .spyOn(document, 'querySelector')
+ .mockImplementation(selector =>
+ selector === `${tabSelector} a[href="#bogus"]` ? null : fakeTab,
+ );
+
+ memo.bootstrap();
+
+ // verify that triggers click on stored selector and fallback
+ expect(document.querySelector.mock.calls).toEqual([
+ ['ul.new-session-tabs a[href="#bogus"]'],
+ ['ul.new-session-tabs a'],
+ ]);
+
+ expect(fakeTab.click).toHaveBeenCalled();
+ });
+
+ it('saves last selected tab on change', () => {
+ createMemoizer();
+
+ document.querySelector('a[href="#login-pane"]').click();
+
+ expect(memo.readData()).toEqual('#login-pane');
+ });
+
+ it('overrides last selected tab with hash tag when given', () => {
+ window.location.hash = '#ldap';
+ createMemoizer();
+
+ expect(memo.readData()).toEqual('#ldap');
+ });
+
+ describe('class constructor', () => {
+ beforeEach(() => {
+ memo = createMemoizer();
+ });
+
+ it('should set .isLocalStorageAvailable', () => {
+ expect(AccessorUtilities.isLocalStorageAccessSafe).toHaveBeenCalled();
+ expect(memo.isLocalStorageAvailable).toBe(true);
+ });
+ });
+
+ describe('trackData', () => {
+ beforeEach(() => {
+ jest.spyOn(Tracking, 'event').mockImplementation(() => {});
+ });
+
+ describe('with tracking data', () => {
+ beforeEach(() => {
+ gon.tracking_data = {
+ category: 'Growth::Acquisition::Experiment::SignUpFlow',
+ action: 'start',
+ label: 'uuid',
+ property: 'control_group',
+ };
+ trackData();
+ });
+
+ it('should track data when the "click" event of the register tab is triggered', () => {
+ document.querySelector('a[href="#register-pane"]').click();
+
+ expect(Tracking.event).toHaveBeenCalledWith(
+ 'Growth::Acquisition::Experiment::SignUpFlow',
+ 'start',
+ {
+ label: 'uuid',
+ property: 'control_group',
+ },
+ );
+ });
+ });
+
+ describe('without tracking data', () => {
+ beforeEach(() => {
+ gon.tracking_data = undefined;
+ trackData();
+ });
+
+ it('should not track data when the "click" event of the register tab is triggered', () => {
+ document.querySelector('a[href="#register-pane"]').click();
+
+ expect(Tracking.event).not.toHaveBeenCalled();
+ });
+ });
+ });
+
+ describe('saveData', () => {
+ beforeEach(() => {
+ memo = {
+ currentTabKey,
+ };
+ });
+
+ describe('if .isLocalStorageAvailable is `false`', () => {
+ beforeEach(() => {
+ memo.isLocalStorageAvailable = false;
+
+ SigninTabsMemoizer.prototype.saveData.call(memo);
+ });
+
+ it('should not call .setItem', () => {
+ expect(localStorage.setItem).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('if .isLocalStorageAvailable is `true`', () => {
+ const value = 'value';
+
+ beforeEach(() => {
+ memo.isLocalStorageAvailable = true;
+
+ SigninTabsMemoizer.prototype.saveData.call(memo, value);
+ });
+
+ it('should call .setItem', () => {
+ expect(localStorage.setItem).toHaveBeenCalledWith(currentTabKey, value);
+ });
+ });
+ });
+
+ describe('readData', () => {
+ const itemValue = 'itemValue';
+ let readData;
+
+ beforeEach(() => {
+ memo = {
+ currentTabKey,
+ };
+
+ localStorage.getItem.mockReturnValue(itemValue);
+ });
+
+ describe('if .isLocalStorageAvailable is `false`', () => {
+ beforeEach(() => {
+ memo.isLocalStorageAvailable = false;
+
+ readData = SigninTabsMemoizer.prototype.readData.call(memo);
+ });
+
+ it('should not call .getItem and should return `null`', () => {
+ expect(localStorage.getItem).not.toHaveBeenCalled();
+ expect(readData).toBe(null);
+ });
+ });
+
+ describe('if .isLocalStorageAvailable is `true`', () => {
+ beforeEach(() => {
+ memo.isLocalStorageAvailable = true;
+
+ readData = SigninTabsMemoizer.prototype.readData.call(memo);
+ });
+
+ it('should call .getItem and return the localStorage value', () => {
+ expect(window.localStorage.getItem).toHaveBeenCalledWith(currentTabKey);
+ expect(readData).toBe(itemValue);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/pdf/index_spec.js b/spec/frontend/pdf/index_spec.js
new file mode 100644
index 00000000000..0d8caa28fd1
--- /dev/null
+++ b/spec/frontend/pdf/index_spec.js
@@ -0,0 +1,62 @@
+import Vue from 'vue';
+
+import { FIXTURES_PATH } from 'spec/test_constants';
+import PDFLab from '~/pdf/index.vue';
+
+jest.mock('pdfjs-dist/webpack', () => {
+ return { default: jest.requireActual('pdfjs-dist/build/pdf') };
+});
+
+const pdf = `${FIXTURES_PATH}/blob/pdf/test.pdf`;
+
+const Component = Vue.extend(PDFLab);
+
+describe('PDF component', () => {
+ let vm;
+
+ const checkLoaded = done => {
+ if (vm.loading) {
+ setTimeout(() => {
+ checkLoaded(done);
+ }, 100);
+ } else {
+ done();
+ }
+ };
+
+ describe('without PDF data', () => {
+ beforeEach(done => {
+ vm = new Component({
+ propsData: {
+ pdf: '',
+ },
+ });
+
+ vm.$mount();
+
+ checkLoaded(done);
+ });
+
+ it('does not render', () => {
+ expect(vm.$el.tagName).toBeUndefined();
+ });
+ });
+
+ describe('with PDF data', () => {
+ beforeEach(done => {
+ vm = new Component({
+ propsData: {
+ pdf,
+ },
+ });
+
+ vm.$mount();
+
+ checkLoaded(done);
+ });
+
+ it('renders pdf component', () => {
+ expect(vm.$el.tagName).toBeDefined();
+ });
+ });
+});
diff --git a/spec/frontend/pdf/page_spec.js b/spec/frontend/pdf/page_spec.js
new file mode 100644
index 00000000000..4e24b0696ec
--- /dev/null
+++ b/spec/frontend/pdf/page_spec.js
@@ -0,0 +1,39 @@
+import Vue from 'vue';
+import PageComponent from '~/pdf/page/index.vue';
+import mountComponent from 'helpers/vue_mount_component_helper';
+
+jest.mock('pdfjs-dist/webpack', () => {
+ return { default: jest.requireActual('pdfjs-dist/build/pdf') };
+});
+
+describe('Page component', () => {
+ const Component = Vue.extend(PageComponent);
+ let vm;
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('renders the page when mounting', done => {
+ const promise = Promise.resolve();
+ const testPage = {
+ render: jest.fn().mockReturnValue({ promise: Promise.resolve() }),
+ getViewport: jest.fn().mockReturnValue({}),
+ };
+
+ vm = mountComponent(Component, {
+ page: testPage,
+ number: 1,
+ });
+
+ expect(vm.rendering).toBe(true);
+
+ promise
+ .then(() => {
+ expect(testPage.render).toHaveBeenCalledWith(vm.renderContext);
+ expect(vm.rendering).toBe(false);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+});
diff --git a/spec/frontend/performance_bar/components/detailed_metric_spec.js b/spec/frontend/performance_bar/components/detailed_metric_spec.js
index 01b6b7b043c..f040dcfdea4 100644
--- a/spec/frontend/performance_bar/components/detailed_metric_spec.js
+++ b/spec/frontend/performance_bar/components/detailed_metric_spec.js
@@ -1,22 +1,32 @@
import { shallowMount } from '@vue/test-utils';
import DetailedMetric from '~/performance_bar/components/detailed_metric.vue';
import RequestWarning from '~/performance_bar/components/request_warning.vue';
+import { trimText } from 'helpers/text_helper';
describe('detailedMetric', () => {
- const createComponent = props =>
- shallowMount(DetailedMetric, {
+ let wrapper;
+
+ const createComponent = props => {
+ wrapper = shallowMount(DetailedMetric, {
propsData: {
...props,
},
});
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
describe('when the current request has no details', () => {
- const wrapper = createComponent({
- currentRequest: {},
- metric: 'gitaly',
- header: 'Gitaly calls',
- details: 'details',
- keys: ['feature', 'request'],
+ beforeEach(() => {
+ createComponent({
+ currentRequest: {},
+ metric: 'gitaly',
+ header: 'Gitaly calls',
+ details: 'details',
+ keys: ['feature', 'request'],
+ });
});
it('does not render the element', () => {
@@ -31,20 +41,22 @@ describe('detailedMetric', () => {
];
describe('with a default metric name', () => {
- const wrapper = createComponent({
- currentRequest: {
- details: {
- gitaly: {
- duration: '123ms',
- calls: '456',
- details: requestDetails,
- warnings: ['gitaly calls: 456 over 30'],
+ beforeEach(() => {
+ createComponent({
+ currentRequest: {
+ details: {
+ gitaly: {
+ duration: '123ms',
+ calls: '456',
+ details: requestDetails,
+ warnings: ['gitaly calls: 456 over 30'],
+ },
},
},
- },
- metric: 'gitaly',
- header: 'Gitaly calls',
- keys: ['feature', 'request'],
+ metric: 'gitaly',
+ header: 'Gitaly calls',
+ keys: ['feature', 'request'],
+ });
});
it('displays details', () => {
@@ -87,25 +99,49 @@ describe('detailedMetric', () => {
});
describe('when using a custom metric title', () => {
- const wrapper = createComponent({
+ beforeEach(() => {
+ createComponent({
+ currentRequest: {
+ details: {
+ gitaly: {
+ duration: '123ms',
+ calls: '456',
+ details: requestDetails,
+ },
+ },
+ },
+ metric: 'gitaly',
+ title: 'custom',
+ header: 'Gitaly calls',
+ keys: ['feature', 'request'],
+ });
+ });
+
+ it('displays the custom title', () => {
+ expect(wrapper.text()).toContain('custom');
+ });
+ });
+ });
+
+ describe('when the details has no duration', () => {
+ beforeEach(() => {
+ createComponent({
currentRequest: {
details: {
- gitaly: {
- duration: '123ms',
+ bullet: {
calls: '456',
- details: requestDetails,
+ details: [{ notification: 'notification', backtrace: 'backtrace' }],
},
},
},
- metric: 'gitaly',
- title: 'custom',
- header: 'Gitaly calls',
- keys: ['feature', 'request'],
+ metric: 'bullet',
+ header: 'Bullet notifications',
+ keys: ['notification'],
});
+ });
- it('displays the custom title', () => {
- expect(wrapper.text()).toContain('custom');
- });
+ it('renders only the number of calls', () => {
+ expect(trimText(wrapper.text())).toEqual('456 notification backtrace bullet');
});
});
});
diff --git a/spec/frontend/performance_bar/index_spec.js b/spec/frontend/performance_bar/index_spec.js
new file mode 100644
index 00000000000..621c7d87a7e
--- /dev/null
+++ b/spec/frontend/performance_bar/index_spec.js
@@ -0,0 +1,85 @@
+import MockAdapter from 'axios-mock-adapter';
+import axios from '~/lib/utils/axios_utils';
+import '~/performance_bar/components/performance_bar_app.vue';
+import performanceBar from '~/performance_bar';
+import PerformanceBarService from '~/performance_bar/services/performance_bar_service';
+
+describe('performance bar wrapper', () => {
+ let mock;
+ let vm;
+
+ beforeEach(() => {
+ URL.createObjectURL = jest.fn();
+ performance.getEntriesByType = jest.fn().mockReturnValue([]);
+
+ // clear html so that elements from previous tests don't mess with this test
+ document.body.innerHTML = '';
+ const peekWrapper = document.createElement('div');
+
+ peekWrapper.setAttribute('id', 'js-peek');
+ peekWrapper.setAttribute('data-env', 'development');
+ peekWrapper.setAttribute('data-request-id', '123');
+ peekWrapper.setAttribute('data-peek-url', '/-/peek/results');
+ peekWrapper.setAttribute('data-profile-url', '?lineprofiler=true');
+
+ document.body.appendChild(peekWrapper);
+
+ mock = new MockAdapter(axios);
+
+ mock.onGet('/-/peek/results').reply(
+ 200,
+ {
+ data: {
+ gc: {
+ invokes: 0,
+ invoke_time: '0.00',
+ use_size: 0,
+ total_size: 0,
+ total_object: 0,
+ gc_time: '0.00',
+ },
+ host: { hostname: 'web-01' },
+ },
+ },
+ {},
+ );
+
+ vm = performanceBar({ container: '#js-peek' });
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ mock.restore();
+ });
+
+ describe('loadRequestDetails', () => {
+ beforeEach(() => {
+ jest.spyOn(vm.store, 'addRequest');
+ });
+
+ it('does nothing if the request cannot be tracked', () => {
+ jest.spyOn(vm.store, 'canTrackRequest').mockImplementation(() => false);
+
+ vm.loadRequestDetails('123', 'https://gitlab.com/');
+
+ expect(vm.store.addRequest).not.toHaveBeenCalled();
+ });
+
+ it('adds the request immediately', () => {
+ vm.loadRequestDetails('123', 'https://gitlab.com/');
+
+ expect(vm.store.addRequest).toHaveBeenCalledWith('123', 'https://gitlab.com/');
+ });
+
+ it('makes an HTTP request for the request details', () => {
+ jest.spyOn(PerformanceBarService, 'fetchRequestDetails');
+
+ vm.loadRequestDetails('456', 'https://gitlab.com/');
+
+ expect(PerformanceBarService.fetchRequestDetails).toHaveBeenCalledWith(
+ '/-/peek/results',
+ '456',
+ );
+ });
+ });
+});
diff --git a/spec/frontend/persistent_user_callout_spec.js b/spec/frontend/persistent_user_callout_spec.js
new file mode 100644
index 00000000000..db324990e71
--- /dev/null
+++ b/spec/frontend/persistent_user_callout_spec.js
@@ -0,0 +1,158 @@
+import MockAdapter from 'axios-mock-adapter';
+import waitForPromises from 'helpers/wait_for_promises';
+import axios from '~/lib/utils/axios_utils';
+import PersistentUserCallout from '~/persistent_user_callout';
+import Flash from '~/flash';
+
+jest.mock('~/flash');
+
+describe('PersistentUserCallout', () => {
+ const dismissEndpoint = '/dismiss';
+ const featureName = 'feature';
+
+ function createFixture() {
+ const fixture = document.createElement('div');
+ fixture.innerHTML = `
+ <div
+ class="container"
+ data-dismiss-endpoint="${dismissEndpoint}"
+ data-feature-id="${featureName}"
+ >
+ <button type="button" class="js-close"></button>
+ </div>
+ `;
+
+ return fixture;
+ }
+
+ function createDeferredLinkFixture() {
+ const fixture = document.createElement('div');
+ fixture.innerHTML = `
+ <div
+ class="container"
+ data-dismiss-endpoint="${dismissEndpoint}"
+ data-feature-id="${featureName}"
+ data-defer-links="true"
+ >
+ <button type="button" class="js-close"></button>
+ <a href="/somewhere-pleasant" target="_blank" class="deferred-link">A link</a>
+ <a href="/somewhere-else" target="_blank" class="normal-link">Another link</a>
+ </div>
+ `;
+
+ return fixture;
+ }
+
+ describe('dismiss', () => {
+ let button;
+ let mockAxios;
+ let persistentUserCallout;
+
+ beforeEach(() => {
+ const fixture = createFixture();
+ const container = fixture.querySelector('.container');
+ button = fixture.querySelector('.js-close');
+ mockAxios = new MockAdapter(axios);
+ persistentUserCallout = new PersistentUserCallout(container);
+ jest.spyOn(persistentUserCallout.container, 'remove').mockImplementation(() => {});
+ });
+
+ afterEach(() => {
+ mockAxios.restore();
+ });
+
+ it('POSTs endpoint and removes container when clicking close', () => {
+ mockAxios.onPost(dismissEndpoint).replyOnce(200);
+
+ button.click();
+
+ return waitForPromises().then(() => {
+ expect(persistentUserCallout.container.remove).toHaveBeenCalled();
+ expect(mockAxios.history.post[0].data).toBe(JSON.stringify({ feature_name: featureName }));
+ });
+ });
+
+ it('invokes Flash when the dismiss request fails', () => {
+ mockAxios.onPost(dismissEndpoint).replyOnce(500);
+
+ button.click();
+
+ return waitForPromises().then(() => {
+ expect(persistentUserCallout.container.remove).not.toHaveBeenCalled();
+ expect(Flash).toHaveBeenCalledWith(
+ 'An error occurred while dismissing the alert. Refresh the page and try again.',
+ );
+ });
+ });
+ });
+
+ describe('deferred links', () => {
+ let button;
+ let deferredLink;
+ let normalLink;
+ let mockAxios;
+ let persistentUserCallout;
+ let windowSpy;
+
+ beforeEach(() => {
+ const fixture = createDeferredLinkFixture();
+ const container = fixture.querySelector('.container');
+ button = fixture.querySelector('.js-close');
+ deferredLink = fixture.querySelector('.deferred-link');
+ normalLink = fixture.querySelector('.normal-link');
+ mockAxios = new MockAdapter(axios);
+ persistentUserCallout = new PersistentUserCallout(container);
+ jest.spyOn(persistentUserCallout.container, 'remove').mockImplementation(() => {});
+ windowSpy = jest.spyOn(window, 'open').mockImplementation(() => {});
+ });
+
+ afterEach(() => {
+ mockAxios.restore();
+ });
+
+ it('defers loading of a link until callout is dismissed', () => {
+ const { href, target } = deferredLink;
+ mockAxios.onPost(dismissEndpoint).replyOnce(200);
+
+ deferredLink.click();
+
+ return waitForPromises().then(() => {
+ expect(windowSpy).toHaveBeenCalledWith(href, target);
+ expect(persistentUserCallout.container.remove).toHaveBeenCalled();
+ expect(mockAxios.history.post[0].data).toBe(JSON.stringify({ feature_name: featureName }));
+ });
+ });
+
+ it('does not dismiss callout on non-deferred links', () => {
+ normalLink.click();
+
+ return waitForPromises().then(() => {
+ expect(windowSpy).not.toHaveBeenCalled();
+ expect(persistentUserCallout.container.remove).not.toHaveBeenCalled();
+ });
+ });
+
+ it('does not follow link when notification is closed', () => {
+ mockAxios.onPost(dismissEndpoint).replyOnce(200);
+
+ button.click();
+
+ return waitForPromises().then(() => {
+ expect(windowSpy).not.toHaveBeenCalled();
+ expect(persistentUserCallout.container.remove).toHaveBeenCalled();
+ });
+ });
+ });
+
+ describe('factory', () => {
+ it('returns an instance of PersistentUserCallout with the provided container property', () => {
+ const fixture = createFixture();
+
+ expect(PersistentUserCallout.factory(fixture) instanceof PersistentUserCallout).toBe(true);
+ });
+
+ it('returns undefined if container is falsey', () => {
+ expect(PersistentUserCallout.factory()).toBe(undefined);
+ });
+ });
+});
diff --git a/spec/frontend/pipelines/components/dag/__snapshots__/dag_graph_spec.js.snap b/spec/frontend/pipelines/components/dag/__snapshots__/dag_graph_spec.js.snap
new file mode 100644
index 00000000000..629efc6d3fa
--- /dev/null
+++ b/spec/frontend/pipelines/components/dag/__snapshots__/dag_graph_spec.js.snap
@@ -0,0 +1,230 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`The DAG graph in the basic case renders the graph svg 1`] = `
+"<svg viewBox=\\"0,0,1000,540\\" width=\\"1000\\" height=\\"540\\">
+ <g fill=\\"none\\" stroke-opacity=\\"0.8\\">
+ <g id=\\"dag-link43\\" class=\\"dag-link gl-cursor-pointer\\">
+ <linearGradient id=\\"dag-grad53\\" gradientUnits=\\"userSpaceOnUse\\" x1=\\"116\\" x2=\\"361.3333333333333\\">
+ <stop offset=\\"0%\\" stop-color=\\"#e17223\\"></stop>
+ <stop offset=\\"100%\\" stop-color=\\"#83ab4a\\"></stop>
+ </linearGradient>
+ <clipPath id=\\"dag-clip63\\">
+ <path d=\\"
+ M100, 129
+ V158
+ H377.3333333333333
+ V100
+ H100
+ Z
+ \\"></path>
+ </clipPath>
+ <path d=\\"M108,129L190,129L190,129L369.3333333333333,129\\" stroke=\\"url(#dag-grad53)\\" style=\\"stroke-linejoin: round;\\" stroke-width=\\"56\\" clip-path=\\"url(#dag-clip63)\\"></path>
+ </g>
+ <g id=\\"dag-link44\\" class=\\"dag-link gl-cursor-pointer\\">
+ <linearGradient id=\\"dag-grad54\\" gradientUnits=\\"userSpaceOnUse\\" x1=\\"377.3333333333333\\" x2=\\"622.6666666666666\\">
+ <stop offset=\\"0%\\" stop-color=\\"#83ab4a\\"></stop>
+ <stop offset=\\"100%\\" stop-color=\\"#6f3500\\"></stop>
+ </linearGradient>
+ <clipPath id=\\"dag-clip64\\">
+ <path d=\\"
+ M361.3333333333333, 129.0000000000002
+ V158.0000000000002
+ H638.6666666666666
+ V100
+ H361.3333333333333
+ Z
+ \\"></path>
+ </clipPath>
+ <path d=\\"M369.3333333333333,129L509.3333333333333,129L509.3333333333333,129.0000000000002L630.6666666666666,129.0000000000002\\" stroke=\\"url(#dag-grad54)\\" style=\\"stroke-linejoin: round;\\" stroke-width=\\"56\\" clip-path=\\"url(#dag-clip64)\\"></path>
+ </g>
+ <g id=\\"dag-link45\\" class=\\"dag-link gl-cursor-pointer\\">
+ <linearGradient id=\\"dag-grad55\\" gradientUnits=\\"userSpaceOnUse\\" x1=\\"116\\" x2=\\"622.6666666666666\\">
+ <stop offset=\\"0%\\" stop-color=\\"#5772ff\\"></stop>
+ <stop offset=\\"100%\\" stop-color=\\"#6f3500\\"></stop>
+ </linearGradient>
+ <clipPath id=\\"dag-clip65\\">
+ <path d=\\"
+ M100, 187.0000000000002
+ V241.00000000000003
+ H638.6666666666666
+ V158.0000000000002
+ H100
+ Z
+ \\"></path>
+ </clipPath>
+ <path d=\\"M108,212.00000000000003L306,212.00000000000003L306,187.0000000000002L630.6666666666666,187.0000000000002\\" stroke=\\"url(#dag-grad55)\\" style=\\"stroke-linejoin: round;\\" stroke-width=\\"56\\" clip-path=\\"url(#dag-clip65)\\"></path>
+ </g>
+ <g id=\\"dag-link46\\" class=\\"dag-link gl-cursor-pointer\\">
+ <linearGradient id=\\"dag-grad56\\" gradientUnits=\\"userSpaceOnUse\\" x1=\\"116\\" x2=\\"361.3333333333333\\">
+ <stop offset=\\"0%\\" stop-color=\\"#b24800\\"></stop>
+ <stop offset=\\"100%\\" stop-color=\\"#006887\\"></stop>
+ </linearGradient>
+ <clipPath id=\\"dag-clip66\\">
+ <path d=\\"
+ M100, 269.9999999999998
+ V324
+ H377.3333333333333
+ V240.99999999999977
+ H100
+ Z
+ \\"></path>
+ </clipPath>
+ <path d=\\"M108,295L338.93333333333334,295L338.93333333333334,269.9999999999998L369.3333333333333,269.9999999999998\\" stroke=\\"url(#dag-grad56)\\" style=\\"stroke-linejoin: round;\\" stroke-width=\\"56\\" clip-path=\\"url(#dag-clip66)\\"></path>
+ </g>
+ <g id=\\"dag-link47\\" class=\\"dag-link gl-cursor-pointer\\">
+ <linearGradient id=\\"dag-grad57\\" gradientUnits=\\"userSpaceOnUse\\" x1=\\"116\\" x2=\\"361.3333333333333\\">
+ <stop offset=\\"0%\\" stop-color=\\"#25d2d2\\"></stop>
+ <stop offset=\\"100%\\" stop-color=\\"#487900\\"></stop>
+ </linearGradient>
+ <clipPath id=\\"dag-clip67\\">
+ <path d=\\"
+ M100, 352.99999999999994
+ V407.00000000000006
+ H377.3333333333333
+ V323.99999999999994
+ H100
+ Z
+ \\"></path>
+ </clipPath>
+ <path d=\\"M108,378.00000000000006L144.66666666666669,378.00000000000006L144.66666666666669,352.99999999999994L369.3333333333333,352.99999999999994\\" stroke=\\"url(#dag-grad57)\\" style=\\"stroke-linejoin: round;\\" stroke-width=\\"56\\" clip-path=\\"url(#dag-clip67)\\"></path>
+ </g>
+ <g id=\\"dag-link48\\" class=\\"dag-link gl-cursor-pointer\\">
+ <linearGradient id=\\"dag-grad58\\" gradientUnits=\\"userSpaceOnUse\\" x1=\\"377.3333333333333\\" x2=\\"622.6666666666666\\">
+ <stop offset=\\"0%\\" stop-color=\\"#006887\\"></stop>
+ <stop offset=\\"100%\\" stop-color=\\"#d84280\\"></stop>
+ </linearGradient>
+ <clipPath id=\\"dag-clip68\\">
+ <path d=\\"
+ M361.3333333333333, 270.0000000000001
+ V299.0000000000001
+ H638.6666666666666
+ V240.99999999999977
+ H361.3333333333333
+ Z
+ \\"></path>
+ </clipPath>
+ <path d=\\"M369.3333333333333,269.9999999999998L464,269.9999999999998L464,270.0000000000001L630.6666666666666,270.0000000000001\\" stroke=\\"url(#dag-grad58)\\" style=\\"stroke-linejoin: round;\\" stroke-width=\\"56\\" clip-path=\\"url(#dag-clip68)\\"></path>
+ </g>
+ <g id=\\"dag-link49\\" class=\\"dag-link gl-cursor-pointer\\">
+ <linearGradient id=\\"dag-grad59\\" gradientUnits=\\"userSpaceOnUse\\" x1=\\"377.3333333333333\\" x2=\\"622.6666666666666\\">
+ <stop offset=\\"0%\\" stop-color=\\"#487900\\"></stop>
+ <stop offset=\\"100%\\" stop-color=\\"#d84280\\"></stop>
+ </linearGradient>
+ <clipPath id=\\"dag-clip69\\">
+ <path d=\\"
+ M361.3333333333333, 328.0000000000001
+ V381.99999999999994
+ H638.6666666666666
+ V299.0000000000001
+ H361.3333333333333
+ Z
+ \\"></path>
+ </clipPath>
+ <path d=\\"M369.3333333333333,352.99999999999994L522,352.99999999999994L522,328.0000000000001L630.6666666666666,328.0000000000001\\" stroke=\\"url(#dag-grad59)\\" style=\\"stroke-linejoin: round;\\" stroke-width=\\"56\\" clip-path=\\"url(#dag-clip69)\\"></path>
+ </g>
+ <g id=\\"dag-link50\\" class=\\"dag-link gl-cursor-pointer\\">
+ <linearGradient id=\\"dag-grad60\\" gradientUnits=\\"userSpaceOnUse\\" x1=\\"377.3333333333333\\" x2=\\"622.6666666666666\\">
+ <stop offset=\\"0%\\" stop-color=\\"#487900\\"></stop>
+ <stop offset=\\"100%\\" stop-color=\\"#3547de\\"></stop>
+ </linearGradient>
+ <clipPath id=\\"dag-clip70\\">
+ <path d=\\"
+ M361.3333333333333, 411
+ V440
+ H638.6666666666666
+ V381.99999999999994
+ H361.3333333333333
+ Z
+ \\"></path>
+ </clipPath>
+ <path d=\\"M369.3333333333333,410.99999999999994L580,410.99999999999994L580,411L630.6666666666666,411\\" stroke=\\"url(#dag-grad60)\\" style=\\"stroke-linejoin: round;\\" stroke-width=\\"56\\" clip-path=\\"url(#dag-clip70)\\"></path>
+ </g>
+ <g id=\\"dag-link51\\" class=\\"dag-link gl-cursor-pointer\\">
+ <linearGradient id=\\"dag-grad61\\" gradientUnits=\\"userSpaceOnUse\\" x1=\\"638.6666666666666\\" x2=\\"884\\">
+ <stop offset=\\"0%\\" stop-color=\\"#d84280\\"></stop>
+ <stop offset=\\"100%\\" stop-color=\\"#006887\\"></stop>
+ </linearGradient>
+ <clipPath id=\\"dag-clip71\\">
+ <path d=\\"
+ M622.6666666666666, 270.1890725105691
+ V299.1890725105691
+ H900
+ V241.0000000000001
+ H622.6666666666666
+ Z
+ \\"></path>
+ </clipPath>
+ <path d=\\"M630.6666666666666,270.0000000000001L861.6,270.0000000000001L861.6,270.1890725105691L892,270.1890725105691\\" stroke=\\"url(#dag-grad61)\\" style=\\"stroke-linejoin: round;\\" stroke-width=\\"56\\" clip-path=\\"url(#dag-clip71)\\"></path>
+ </g>
+ <g id=\\"dag-link52\\" class=\\"dag-link gl-cursor-pointer\\">
+ <linearGradient id=\\"dag-grad62\\" gradientUnits=\\"userSpaceOnUse\\" x1=\\"638.6666666666666\\" x2=\\"884\\">
+ <stop offset=\\"0%\\" stop-color=\\"#3547de\\"></stop>
+ <stop offset=\\"100%\\" stop-color=\\"#275600\\"></stop>
+ </linearGradient>
+ <clipPath id=\\"dag-clip72\\">
+ <path d=\\"
+ M622.6666666666666, 411
+ V440
+ H900
+ V382
+ H622.6666666666666
+ Z
+ \\"></path>
+ </clipPath>
+ <path d=\\"M630.6666666666666,411L679.9999999999999,411L679.9999999999999,411L892,411\\" stroke=\\"url(#dag-grad62)\\" style=\\"stroke-linejoin: round;\\" stroke-width=\\"56\\" clip-path=\\"url(#dag-clip72)\\"></path>
+ </g>
+ </g>
+ <g>
+ <line class=\\"dag-node gl-cursor-pointer\\" id=\\"dag-node73\\" stroke=\\"#e17223\\" stroke-width=\\"16\\" stroke-linecap=\\"round\\" x1=\\"108\\" x2=\\"108\\" y1=\\"104\\" y2=\\"154.00000000000003\\"></line>
+ <line class=\\"dag-node gl-cursor-pointer\\" id=\\"dag-node74\\" stroke=\\"#83ab4a\\" stroke-width=\\"16\\" stroke-linecap=\\"round\\" x1=\\"369\\" x2=\\"369\\" y1=\\"104\\" y2=\\"154\\"></line>
+ <line class=\\"dag-node gl-cursor-pointer\\" id=\\"dag-node75\\" stroke=\\"#5772ff\\" stroke-width=\\"16\\" stroke-linecap=\\"round\\" x1=\\"108\\" x2=\\"108\\" y1=\\"187.00000000000003\\" y2=\\"237.00000000000003\\"></line>
+ <line class=\\"dag-node gl-cursor-pointer\\" id=\\"dag-node76\\" stroke=\\"#b24800\\" stroke-width=\\"16\\" stroke-linecap=\\"round\\" x1=\\"108\\" x2=\\"108\\" y1=\\"270\\" y2=\\"320.00000000000006\\"></line>
+ <line class=\\"dag-node gl-cursor-pointer\\" id=\\"dag-node77\\" stroke=\\"#25d2d2\\" stroke-width=\\"16\\" stroke-linecap=\\"round\\" x1=\\"108\\" x2=\\"108\\" y1=\\"353.00000000000006\\" y2=\\"403.0000000000001\\"></line>
+ <line class=\\"dag-node gl-cursor-pointer\\" id=\\"dag-node78\\" stroke=\\"#6f3500\\" stroke-width=\\"16\\" stroke-linecap=\\"round\\" x1=\\"630\\" x2=\\"630\\" y1=\\"104.0000000000002\\" y2=\\"212.00000000000009\\"></line>
+ <line class=\\"dag-node gl-cursor-pointer\\" id=\\"dag-node79\\" stroke=\\"#006887\\" stroke-width=\\"16\\" stroke-linecap=\\"round\\" x1=\\"369\\" x2=\\"369\\" y1=\\"244.99999999999977\\" y2=\\"294.99999999999994\\"></line>
+ <line class=\\"dag-node gl-cursor-pointer\\" id=\\"dag-node80\\" stroke=\\"#487900\\" stroke-width=\\"16\\" stroke-linecap=\\"round\\" x1=\\"369\\" x2=\\"369\\" y1=\\"327.99999999999994\\" y2=\\"436\\"></line>
+ <line class=\\"dag-node gl-cursor-pointer\\" id=\\"dag-node81\\" stroke=\\"#d84280\\" stroke-width=\\"16\\" stroke-linecap=\\"round\\" x1=\\"630\\" x2=\\"630\\" y1=\\"245.00000000000009\\" y2=\\"353\\"></line>
+ <line class=\\"dag-node gl-cursor-pointer\\" id=\\"dag-node82\\" stroke=\\"#3547de\\" stroke-width=\\"16\\" stroke-linecap=\\"round\\" x1=\\"630\\" x2=\\"630\\" y1=\\"386\\" y2=\\"436\\"></line>
+ <line class=\\"dag-node gl-cursor-pointer\\" id=\\"dag-node83\\" stroke=\\"#006887\\" stroke-width=\\"16\\" stroke-linecap=\\"round\\" x1=\\"892\\" x2=\\"892\\" y1=\\"245.18907251056908\\" y2=\\"295.1890725105691\\"></line>
+ <line class=\\"dag-node gl-cursor-pointer\\" id=\\"dag-node84\\" stroke=\\"#275600\\" stroke-width=\\"16\\" stroke-linecap=\\"round\\" x1=\\"892\\" x2=\\"892\\" y1=\\"386\\" y2=\\"436\\"></line>
+ </g>
+ <g class=\\"gl-font-sm\\">
+ <foreignObject requiredFeatures=\\"http://www.w3.org/TR/SVG11/feature#Extensibility\\" height=\\"58.00000000000003px\\" width=\\"84\\" x=\\"8\\" y=\\"100\\" class=\\"gl-overflow-visible\\">
+ <div class=\\"gl-display-flex gl-pointer-events-none gl-flex-direction-column gl-justify-content-center gl-overflow-wrap-break\\" style=\\"height: 58.00000000000003px; text-align: right;\\">build_a</div>
+ </foreignObject>
+ <foreignObject requiredFeatures=\\"http://www.w3.org/TR/SVG11/feature#Extensibility\\" height=\\"25px\\" width=\\"84\\" x=\\"369.3333333333333\\" y=\\"75\\" class=\\"gl-overflow-visible\\">
+ <div class=\\"gl-display-flex gl-pointer-events-none gl-flex-direction-column gl-justify-content-center gl-overflow-wrap-break\\" style=\\"height: 25px; text-align: left;\\">test_a</div>
+ </foreignObject>
+ <foreignObject requiredFeatures=\\"http://www.w3.org/TR/SVG11/feature#Extensibility\\" height=\\"58px\\" width=\\"84\\" x=\\"8\\" y=\\"183.00000000000003\\" class=\\"gl-overflow-visible\\">
+ <div class=\\"gl-display-flex gl-pointer-events-none gl-flex-direction-column gl-justify-content-center gl-overflow-wrap-break\\" style=\\"height: 58px; text-align: right;\\">test_b</div>
+ </foreignObject>
+ <foreignObject requiredFeatures=\\"http://www.w3.org/TR/SVG11/feature#Extensibility\\" height=\\"58.00000000000006px\\" width=\\"84\\" x=\\"8\\" y=\\"266\\" class=\\"gl-overflow-visible\\">
+ <div class=\\"gl-display-flex gl-pointer-events-none gl-flex-direction-column gl-justify-content-center gl-overflow-wrap-break\\" style=\\"height: 58.00000000000006px; text-align: right;\\">post_test_a</div>
+ </foreignObject>
+ <foreignObject requiredFeatures=\\"http://www.w3.org/TR/SVG11/feature#Extensibility\\" height=\\"58.00000000000006px\\" width=\\"84\\" x=\\"8\\" y=\\"349.00000000000006\\" class=\\"gl-overflow-visible\\">
+ <div class=\\"gl-display-flex gl-pointer-events-none gl-flex-direction-column gl-justify-content-center gl-overflow-wrap-break\\" style=\\"height: 58.00000000000006px; text-align: right;\\">post_test_b</div>
+ </foreignObject>
+ <foreignObject requiredFeatures=\\"http://www.w3.org/TR/SVG11/feature#Extensibility\\" height=\\"25px\\" width=\\"84\\" x=\\"630.6666666666666\\" y=\\"75.0000000000002\\" class=\\"gl-overflow-visible\\">
+ <div class=\\"gl-display-flex gl-pointer-events-none gl-flex-direction-column gl-justify-content-center gl-overflow-wrap-break\\" style=\\"height: 25px; text-align: right;\\">post_test_c</div>
+ </foreignObject>
+ <foreignObject requiredFeatures=\\"http://www.w3.org/TR/SVG11/feature#Extensibility\\" height=\\"25px\\" width=\\"84\\" x=\\"369.3333333333333\\" y=\\"215.99999999999977\\" class=\\"gl-overflow-visible\\">
+ <div class=\\"gl-display-flex gl-pointer-events-none gl-flex-direction-column gl-justify-content-center gl-overflow-wrap-break\\" style=\\"height: 25px; text-align: left;\\">staging_a</div>
+ </foreignObject>
+ <foreignObject requiredFeatures=\\"http://www.w3.org/TR/SVG11/feature#Extensibility\\" height=\\"25px\\" width=\\"84\\" x=\\"369.3333333333333\\" y=\\"298.99999999999994\\" class=\\"gl-overflow-visible\\">
+ <div class=\\"gl-display-flex gl-pointer-events-none gl-flex-direction-column gl-justify-content-center gl-overflow-wrap-break\\" style=\\"height: 25px; text-align: left;\\">staging_b</div>
+ </foreignObject>
+ <foreignObject requiredFeatures=\\"http://www.w3.org/TR/SVG11/feature#Extensibility\\" height=\\"25px\\" width=\\"84\\" x=\\"630.6666666666666\\" y=\\"216.00000000000009\\" class=\\"gl-overflow-visible\\">
+ <div class=\\"gl-display-flex gl-pointer-events-none gl-flex-direction-column gl-justify-content-center gl-overflow-wrap-break\\" style=\\"height: 25px; text-align: right;\\">canary_a</div>
+ </foreignObject>
+ <foreignObject requiredFeatures=\\"http://www.w3.org/TR/SVG11/feature#Extensibility\\" height=\\"25px\\" width=\\"84\\" x=\\"630.6666666666666\\" y=\\"357\\" class=\\"gl-overflow-visible\\">
+ <div class=\\"gl-display-flex gl-pointer-events-none gl-flex-direction-column gl-justify-content-center gl-overflow-wrap-break\\" style=\\"height: 25px; text-align: right;\\">canary_c</div>
+ </foreignObject>
+ <foreignObject requiredFeatures=\\"http://www.w3.org/TR/SVG11/feature#Extensibility\\" height=\\"58px\\" width=\\"84\\" x=\\"908\\" y=\\"241.18907251056908\\" class=\\"gl-overflow-visible\\">
+ <div class=\\"gl-display-flex gl-pointer-events-none gl-flex-direction-column gl-justify-content-center gl-overflow-wrap-break\\" style=\\"height: 58px; text-align: left;\\">production_a</div>
+ </foreignObject>
+ <foreignObject requiredFeatures=\\"http://www.w3.org/TR/SVG11/feature#Extensibility\\" height=\\"58px\\" width=\\"84\\" x=\\"908\\" y=\\"382\\" class=\\"gl-overflow-visible\\">
+ <div class=\\"gl-display-flex gl-pointer-events-none gl-flex-direction-column gl-justify-content-center gl-overflow-wrap-break\\" style=\\"height: 58px; text-align: left;\\">production_d</div>
+ </foreignObject>
+ </g>
+</svg>"
+`;
diff --git a/spec/frontend/pipelines/components/dag/dag_graph_spec.js b/spec/frontend/pipelines/components/dag/dag_graph_spec.js
new file mode 100644
index 00000000000..017461dfb84
--- /dev/null
+++ b/spec/frontend/pipelines/components/dag/dag_graph_spec.js
@@ -0,0 +1,218 @@
+import { mount } from '@vue/test-utils';
+import DagGraph from '~/pipelines/components/dag/dag_graph.vue';
+import { IS_HIGHLIGHTED, LINK_SELECTOR, NODE_SELECTOR } from '~/pipelines/components/dag/constants';
+import { highlightIn, highlightOut } from '~/pipelines/components/dag/interactions';
+import { createSankey } from '~/pipelines/components/dag/drawing_utils';
+import { removeOrphanNodes } from '~/pipelines/components/dag/parsing_utils';
+import { parsedData } from './mock_data';
+
+describe('The DAG graph', () => {
+ let wrapper;
+
+ const getGraph = () => wrapper.find('.dag-graph-container > svg');
+ const getAllLinks = () => wrapper.findAll(`.${LINK_SELECTOR}`);
+ const getAllNodes = () => wrapper.findAll(`.${NODE_SELECTOR}`);
+ const getAllLabels = () => wrapper.findAll('foreignObject');
+
+ const createComponent = (propsData = {}) => {
+ if (wrapper?.destroy) {
+ wrapper.destroy();
+ }
+
+ wrapper = mount(DagGraph, {
+ attachToDocument: true,
+ propsData,
+ data() {
+ return {
+ color: () => {},
+ width: 0,
+ height: 0,
+ };
+ },
+ });
+ };
+
+ beforeEach(() => {
+ createComponent({ graphData: parsedData });
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ describe('in the basic case', () => {
+ beforeEach(() => {
+ /*
+ The graph uses random to offset links. To keep the snapshot consistent,
+ we mock Math.random. Wheeeee!
+ */
+ const randomNumber = jest.spyOn(global.Math, 'random');
+ randomNumber.mockImplementation(() => 0.2);
+ createComponent({ graphData: parsedData });
+ });
+
+ it('renders the graph svg', () => {
+ expect(getGraph().exists()).toBe(true);
+ expect(getGraph().html()).toMatchSnapshot();
+ });
+ });
+
+ describe('links', () => {
+ it('renders the expected number of links', () => {
+ expect(getAllLinks()).toHaveLength(parsedData.links.length);
+ });
+
+ it('renders the expected number of gradients', () => {
+ expect(wrapper.findAll('linearGradient')).toHaveLength(parsedData.links.length);
+ });
+
+ it('renders the expected number of clip paths', () => {
+ expect(wrapper.findAll('clipPath')).toHaveLength(parsedData.links.length);
+ });
+ });
+
+ describe('nodes and labels', () => {
+ const sankeyNodes = createSankey()(parsedData).nodes;
+ const processedNodes = removeOrphanNodes(sankeyNodes);
+
+ describe('nodes', () => {
+ it('renders the expected number of nodes', () => {
+ expect(getAllNodes()).toHaveLength(processedNodes.length);
+ });
+ });
+
+ describe('labels', () => {
+ it('renders the expected number of labels as foreignObjects', () => {
+ expect(getAllLabels()).toHaveLength(processedNodes.length);
+ });
+
+ it('renders the title as text', () => {
+ expect(
+ getAllLabels()
+ .at(0)
+ .text(),
+ ).toBe(parsedData.nodes[0].name);
+ });
+ });
+ });
+
+ describe('interactions', () => {
+ const strokeOpacity = opacity => `stroke-opacity: ${opacity};`;
+ const baseOpacity = () => wrapper.vm.$options.viewOptions.baseOpacity;
+
+ describe('links', () => {
+ const liveLink = () => getAllLinks().at(4);
+ const otherLink = () => getAllLinks().at(1);
+
+ describe('on hover', () => {
+ it('sets the link opacity to baseOpacity and background links to 0.2', () => {
+ liveLink().trigger('mouseover');
+ expect(liveLink().attributes('style')).toBe(strokeOpacity(highlightIn));
+ expect(otherLink().attributes('style')).toBe(strokeOpacity(highlightOut));
+ });
+
+ it('reverts the styles on mouseout', () => {
+ liveLink().trigger('mouseover');
+ liveLink().trigger('mouseout');
+ expect(liveLink().attributes('style')).toBe(strokeOpacity(baseOpacity()));
+ expect(otherLink().attributes('style')).toBe(strokeOpacity(baseOpacity()));
+ });
+ });
+
+ describe('on click', () => {
+ describe('toggles link liveness', () => {
+ it('turns link on', () => {
+ liveLink().trigger('click');
+ expect(liveLink().attributes('style')).toBe(strokeOpacity(highlightIn));
+ expect(otherLink().attributes('style')).toBe(strokeOpacity(highlightOut));
+ });
+
+ it('turns link off on second click', () => {
+ liveLink().trigger('click');
+ liveLink().trigger('click');
+ expect(liveLink().attributes('style')).toBe(strokeOpacity(baseOpacity()));
+ expect(otherLink().attributes('style')).toBe(strokeOpacity(baseOpacity()));
+ });
+ });
+
+ it('the link remains live even after mouseout', () => {
+ liveLink().trigger('click');
+ liveLink().trigger('mouseout');
+ expect(liveLink().attributes('style')).toBe(strokeOpacity(highlightIn));
+ expect(otherLink().attributes('style')).toBe(strokeOpacity(highlightOut));
+ });
+
+ it('preserves state when multiple links are toggled on and off', () => {
+ const anotherLiveLink = () => getAllLinks().at(2);
+
+ liveLink().trigger('click');
+ anotherLiveLink().trigger('click');
+ expect(liveLink().attributes('style')).toBe(strokeOpacity(highlightIn));
+ expect(anotherLiveLink().attributes('style')).toBe(strokeOpacity(highlightIn));
+ expect(otherLink().attributes('style')).toBe(strokeOpacity(highlightOut));
+
+ anotherLiveLink().trigger('click');
+ expect(liveLink().attributes('style')).toBe(strokeOpacity(highlightIn));
+ expect(anotherLiveLink().attributes('style')).toBe(strokeOpacity(highlightOut));
+ expect(otherLink().attributes('style')).toBe(strokeOpacity(highlightOut));
+
+ liveLink().trigger('click');
+ expect(liveLink().attributes('style')).toBe(strokeOpacity(baseOpacity()));
+ expect(anotherLiveLink().attributes('style')).toBe(strokeOpacity(baseOpacity()));
+ expect(otherLink().attributes('style')).toBe(strokeOpacity(baseOpacity()));
+ });
+ });
+ });
+
+ describe('nodes', () => {
+ const liveNode = () => getAllNodes().at(10);
+ const anotherLiveNode = () => getAllNodes().at(5);
+ const nodesNotHighlighted = () => getAllNodes().filter(n => !n.classes(IS_HIGHLIGHTED));
+ const linksNotHighlighted = () => getAllLinks().filter(n => !n.classes(IS_HIGHLIGHTED));
+ const nodesHighlighted = () => getAllNodes().filter(n => n.classes(IS_HIGHLIGHTED));
+ const linksHighlighted = () => getAllLinks().filter(n => n.classes(IS_HIGHLIGHTED));
+
+ describe('on click', () => {
+ it('highlights the clicked node and predecessors', () => {
+ liveNode().trigger('click');
+
+ expect(nodesNotHighlighted().length < getAllNodes().length).toBe(true);
+ expect(linksNotHighlighted().length < getAllLinks().length).toBe(true);
+
+ linksHighlighted().wrappers.forEach(link => {
+ expect(link.attributes('style')).toBe(strokeOpacity(highlightIn));
+ });
+
+ nodesHighlighted().wrappers.forEach(node => {
+ expect(node.attributes('stroke')).not.toBe('#f2f2f2');
+ });
+
+ linksNotHighlighted().wrappers.forEach(link => {
+ expect(link.attributes('style')).toBe(strokeOpacity(highlightOut));
+ });
+
+ nodesNotHighlighted().wrappers.forEach(node => {
+ expect(node.attributes('stroke')).toBe('#f2f2f2');
+ });
+ });
+
+ it('toggles path off on second click', () => {
+ liveNode().trigger('click');
+ liveNode().trigger('click');
+
+ expect(nodesNotHighlighted().length).toBe(getAllNodes().length);
+ expect(linksNotHighlighted().length).toBe(getAllLinks().length);
+ });
+
+ it('preserves state when multiple nodes are toggled on and off', () => {
+ anotherLiveNode().trigger('click');
+ liveNode().trigger('click');
+ anotherLiveNode().trigger('click');
+ expect(nodesNotHighlighted().length < getAllNodes().length).toBe(true);
+ expect(linksNotHighlighted().length < getAllLinks().length).toBe(true);
+ });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/pipelines/components/dag/dag_spec.js b/spec/frontend/pipelines/components/dag/dag_spec.js
new file mode 100644
index 00000000000..666b4cfaa2f
--- /dev/null
+++ b/spec/frontend/pipelines/components/dag/dag_spec.js
@@ -0,0 +1,137 @@
+import { mount, shallowMount } from '@vue/test-utils';
+import MockAdapter from 'axios-mock-adapter';
+import axios from '~/lib/utils/axios_utils';
+import waitForPromises from 'helpers/wait_for_promises';
+import { GlAlert } from '@gitlab/ui';
+import Dag from '~/pipelines/components/dag/dag.vue';
+import DagGraph from '~/pipelines/components/dag/dag_graph.vue';
+
+import {
+ DEFAULT,
+ PARSE_FAILURE,
+ LOAD_FAILURE,
+ UNSUPPORTED_DATA,
+} from '~/pipelines/components/dag//constants';
+import { mockBaseData, tooSmallGraph, unparseableGraph } from './mock_data';
+
+describe('Pipeline DAG graph wrapper', () => {
+ let wrapper;
+ let mock;
+ const getAlert = () => wrapper.find(GlAlert);
+ const getAllAlerts = () => wrapper.findAll(GlAlert);
+ const getGraph = () => wrapper.find(DagGraph);
+ const getErrorText = type => wrapper.vm.$options.errorTexts[type];
+
+ const dataPath = '/root/test/pipelines/90/dag.json';
+
+ const createComponent = (propsData = {}, method = shallowMount) => {
+ if (wrapper?.destroy) {
+ wrapper.destroy();
+ }
+
+ wrapper = method(Dag, {
+ propsData,
+ data() {
+ return {
+ showFailureAlert: false,
+ };
+ },
+ });
+ };
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ });
+
+ afterEach(() => {
+ mock.restore();
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ describe('when there is no dataUrl', () => {
+ beforeEach(() => {
+ createComponent({ graphUrl: undefined });
+ });
+
+ it('shows the DEFAULT alert and not the graph', () => {
+ expect(getAlert().exists()).toBe(true);
+ expect(getAlert().text()).toBe(getErrorText(DEFAULT));
+ expect(getGraph().exists()).toBe(false);
+ });
+ });
+
+ describe('when there is a dataUrl', () => {
+ describe('but the data fetch fails', () => {
+ beforeEach(() => {
+ mock.onGet(dataPath).replyOnce(500);
+ createComponent({ graphUrl: dataPath });
+ });
+
+ it('shows the LOAD_FAILURE alert and not the graph', () => {
+ return wrapper.vm
+ .$nextTick()
+ .then(waitForPromises)
+ .then(() => {
+ expect(getAlert().exists()).toBe(true);
+ expect(getAlert().text()).toBe(getErrorText(LOAD_FAILURE));
+ expect(getGraph().exists()).toBe(false);
+ });
+ });
+ });
+
+ describe('the data fetch succeeds but the parse fails', () => {
+ beforeEach(() => {
+ mock.onGet(dataPath).replyOnce(200, unparseableGraph);
+ createComponent({ graphUrl: dataPath });
+ });
+
+ it('shows the PARSE_FAILURE alert and not the graph', () => {
+ return wrapper.vm
+ .$nextTick()
+ .then(waitForPromises)
+ .then(() => {
+ expect(getAlert().exists()).toBe(true);
+ expect(getAlert().text()).toBe(getErrorText(PARSE_FAILURE));
+ expect(getGraph().exists()).toBe(false);
+ });
+ });
+ });
+
+ describe('and the data fetch and parse succeeds', () => {
+ beforeEach(() => {
+ mock.onGet(dataPath).replyOnce(200, mockBaseData);
+ createComponent({ graphUrl: dataPath }, mount);
+ });
+
+ it('shows the graph and not the beta alert', () => {
+ return wrapper.vm
+ .$nextTick()
+ .then(waitForPromises)
+ .then(() => {
+ expect(getAllAlerts().length).toBe(1);
+ expect(getAlert().text()).toContain('This feature is currently in beta.');
+ expect(getGraph().exists()).toBe(true);
+ });
+ });
+ });
+
+ describe('the data fetch and parse succeeds, but the resulting graph is too small', () => {
+ beforeEach(() => {
+ mock.onGet(dataPath).replyOnce(200, tooSmallGraph);
+ createComponent({ graphUrl: dataPath });
+ });
+
+ it('shows the UNSUPPORTED_DATA alert and not the graph', () => {
+ return wrapper.vm
+ .$nextTick()
+ .then(waitForPromises)
+ .then(() => {
+ expect(getAlert().exists()).toBe(true);
+ expect(getAlert().text()).toBe(getErrorText(UNSUPPORTED_DATA));
+ expect(getGraph().exists()).toBe(false);
+ });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/pipelines/components/dag/drawing_utils_spec.js b/spec/frontend/pipelines/components/dag/drawing_utils_spec.js
new file mode 100644
index 00000000000..a50163411ed
--- /dev/null
+++ b/spec/frontend/pipelines/components/dag/drawing_utils_spec.js
@@ -0,0 +1,57 @@
+import { createSankey } from '~/pipelines/components/dag/drawing_utils';
+import { parseData } from '~/pipelines/components/dag/parsing_utils';
+import { mockBaseData } from './mock_data';
+
+describe('DAG visualization drawing utilities', () => {
+ const parsed = parseData(mockBaseData.stages);
+
+ const layoutSettings = {
+ width: 200,
+ height: 200,
+ nodeWidth: 10,
+ nodePadding: 20,
+ paddingForLabels: 100,
+ };
+
+ const sankeyLayout = createSankey(layoutSettings)(parsed);
+
+ describe('createSankey', () => {
+ it('returns a nodes data structure with expected d3-added properties', () => {
+ const exampleNode = sankeyLayout.nodes[0];
+ expect(exampleNode).toHaveProperty('sourceLinks');
+ expect(exampleNode).toHaveProperty('targetLinks');
+ expect(exampleNode).toHaveProperty('depth');
+ expect(exampleNode).toHaveProperty('layer');
+ expect(exampleNode).toHaveProperty('x0');
+ expect(exampleNode).toHaveProperty('x1');
+ expect(exampleNode).toHaveProperty('y0');
+ expect(exampleNode).toHaveProperty('y1');
+ });
+
+ it('returns a links data structure with expected d3-added properties', () => {
+ const exampleLink = sankeyLayout.links[0];
+ expect(exampleLink).toHaveProperty('source');
+ expect(exampleLink).toHaveProperty('target');
+ expect(exampleLink).toHaveProperty('width');
+ expect(exampleLink).toHaveProperty('y0');
+ expect(exampleLink).toHaveProperty('y1');
+ });
+
+ describe('data structure integrity', () => {
+ const newObject = { name: 'bad-actor' };
+
+ beforeEach(() => {
+ sankeyLayout.nodes.unshift(newObject);
+ });
+
+ it('sankey does not propagate changes back to the original', () => {
+ expect(sankeyLayout.nodes[0]).toBe(newObject);
+ expect(parsed.nodes[0]).not.toBe(newObject);
+ });
+
+ afterEach(() => {
+ sankeyLayout.nodes.shift();
+ });
+ });
+ });
+});
diff --git a/spec/frontend/pipelines/components/dag/mock_data.js b/spec/frontend/pipelines/components/dag/mock_data.js
new file mode 100644
index 00000000000..5de8697170a
--- /dev/null
+++ b/spec/frontend/pipelines/components/dag/mock_data.js
@@ -0,0 +1,390 @@
+/*
+ It is important that the simple base include parallel jobs
+ as well as non-parallel jobs with spaces in the name to prevent
+ us relying on spaces as an indicator.
+*/
+export const mockBaseData = {
+ stages: [
+ {
+ name: 'test',
+ groups: [
+ {
+ name: 'jest',
+ size: 2,
+ jobs: [{ name: 'jest 1/2', needs: ['frontend fixtures'] }, { name: 'jest 2/2' }],
+ },
+ {
+ name: 'rspec',
+ size: 1,
+ jobs: [{ name: 'rspec', needs: ['frontend fixtures'] }],
+ },
+ ],
+ },
+ {
+ name: 'fixtures',
+ groups: [
+ {
+ name: 'frontend fixtures',
+ size: 1,
+ jobs: [{ name: 'frontend fixtures' }],
+ },
+ ],
+ },
+ {
+ name: 'un-needed',
+ groups: [
+ {
+ name: 'un-needed',
+ size: 1,
+ jobs: [{ name: 'un-needed' }],
+ },
+ ],
+ },
+ ],
+};
+
+export const tooSmallGraph = {
+ stages: [
+ {
+ name: 'test',
+ groups: [
+ {
+ name: 'jest',
+ size: 2,
+ jobs: [{ name: 'jest 1/2' }, { name: 'jest 2/2' }],
+ },
+ {
+ name: 'rspec',
+ size: 1,
+ jobs: [{ name: 'rspec', needs: ['frontend fixtures'] }],
+ },
+ ],
+ },
+ {
+ name: 'fixtures',
+ groups: [
+ {
+ name: 'frontend fixtures',
+ size: 1,
+ jobs: [{ name: 'frontend fixtures' }],
+ },
+ ],
+ },
+ {
+ name: 'un-needed',
+ groups: [
+ {
+ name: 'un-needed',
+ size: 1,
+ jobs: [{ name: 'un-needed' }],
+ },
+ ],
+ },
+ ],
+};
+
+export const unparseableGraph = [
+ {
+ name: 'test',
+ groups: [
+ {
+ name: 'jest',
+ size: 2,
+ jobs: [{ name: 'jest 1/2', needs: ['frontend fixtures'] }, { name: 'jest 2/2' }],
+ },
+ {
+ name: 'rspec',
+ size: 1,
+ jobs: [{ name: 'rspec', needs: ['frontend fixtures'] }],
+ },
+ ],
+ },
+ {
+ name: 'un-needed',
+ groups: [
+ {
+ name: 'un-needed',
+ size: 1,
+ jobs: [{ name: 'un-needed' }],
+ },
+ ],
+ },
+];
+
+/*
+ This represents data that has been parsed by the wrapper
+*/
+export const parsedData = {
+ nodes: [
+ {
+ name: 'build_a',
+ size: 1,
+ jobs: [
+ {
+ name: 'build_a',
+ },
+ ],
+ category: 'build',
+ },
+ {
+ name: 'build_b',
+ size: 1,
+ jobs: [
+ {
+ name: 'build_b',
+ },
+ ],
+ category: 'build',
+ },
+ {
+ name: 'test_a',
+ size: 1,
+ jobs: [
+ {
+ name: 'test_a',
+ needs: ['build_a'],
+ },
+ ],
+ category: 'test',
+ },
+ {
+ name: 'test_b',
+ size: 1,
+ jobs: [
+ {
+ name: 'test_b',
+ },
+ ],
+ category: 'test',
+ },
+ {
+ name: 'test_c',
+ size: 1,
+ jobs: [
+ {
+ name: 'test_c',
+ },
+ ],
+ category: 'test',
+ },
+ {
+ name: 'test_d',
+ size: 1,
+ jobs: [
+ {
+ name: 'test_d',
+ },
+ ],
+ category: 'test',
+ },
+ {
+ name: 'post_test_a',
+ size: 1,
+ jobs: [
+ {
+ name: 'post_test_a',
+ },
+ ],
+ category: 'post-test',
+ },
+ {
+ name: 'post_test_b',
+ size: 1,
+ jobs: [
+ {
+ name: 'post_test_b',
+ },
+ ],
+ category: 'post-test',
+ },
+ {
+ name: 'post_test_c',
+ size: 1,
+ jobs: [
+ {
+ name: 'post_test_c',
+ needs: ['test_a', 'test_b'],
+ },
+ ],
+ category: 'post-test',
+ },
+ {
+ name: 'staging_a',
+ size: 1,
+ jobs: [
+ {
+ name: 'staging_a',
+ needs: ['post_test_a'],
+ },
+ ],
+ category: 'staging',
+ },
+ {
+ name: 'staging_b',
+ size: 1,
+ jobs: [
+ {
+ name: 'staging_b',
+ needs: ['post_test_b'],
+ },
+ ],
+ category: 'staging',
+ },
+ {
+ name: 'staging_c',
+ size: 1,
+ jobs: [
+ {
+ name: 'staging_c',
+ },
+ ],
+ category: 'staging',
+ },
+ {
+ name: 'staging_d',
+ size: 1,
+ jobs: [
+ {
+ name: 'staging_d',
+ },
+ ],
+ category: 'staging',
+ },
+ {
+ name: 'staging_e',
+ size: 1,
+ jobs: [
+ {
+ name: 'staging_e',
+ },
+ ],
+ category: 'staging',
+ },
+ {
+ name: 'canary_a',
+ size: 1,
+ jobs: [
+ {
+ name: 'canary_a',
+ needs: ['staging_a', 'staging_b'],
+ },
+ ],
+ category: 'canary',
+ },
+ {
+ name: 'canary_b',
+ size: 1,
+ jobs: [
+ {
+ name: 'canary_b',
+ },
+ ],
+ category: 'canary',
+ },
+ {
+ name: 'canary_c',
+ size: 1,
+ jobs: [
+ {
+ name: 'canary_c',
+ needs: ['staging_b'],
+ },
+ ],
+ category: 'canary',
+ },
+ {
+ name: 'production_a',
+ size: 1,
+ jobs: [
+ {
+ name: 'production_a',
+ needs: ['canary_a'],
+ },
+ ],
+ category: 'production',
+ },
+ {
+ name: 'production_b',
+ size: 1,
+ jobs: [
+ {
+ name: 'production_b',
+ },
+ ],
+ category: 'production',
+ },
+ {
+ name: 'production_c',
+ size: 1,
+ jobs: [
+ {
+ name: 'production_c',
+ },
+ ],
+ category: 'production',
+ },
+ {
+ name: 'production_d',
+ size: 1,
+ jobs: [
+ {
+ name: 'production_d',
+ needs: ['canary_c'],
+ },
+ ],
+ category: 'production',
+ },
+ ],
+ links: [
+ {
+ source: 'build_a',
+ target: 'test_a',
+ value: 10,
+ },
+ {
+ source: 'test_a',
+ target: 'post_test_c',
+ value: 10,
+ },
+ {
+ source: 'test_b',
+ target: 'post_test_c',
+ value: 10,
+ },
+ {
+ source: 'post_test_a',
+ target: 'staging_a',
+ value: 10,
+ },
+ {
+ source: 'post_test_b',
+ target: 'staging_b',
+ value: 10,
+ },
+ {
+ source: 'staging_a',
+ target: 'canary_a',
+ value: 10,
+ },
+ {
+ source: 'staging_b',
+ target: 'canary_a',
+ value: 10,
+ },
+ {
+ source: 'staging_b',
+ target: 'canary_c',
+ value: 10,
+ },
+ {
+ source: 'canary_a',
+ target: 'production_a',
+ value: 10,
+ },
+ {
+ source: 'canary_c',
+ target: 'production_d',
+ value: 10,
+ },
+ ],
+};
diff --git a/spec/frontend/pipelines/components/dag/parsing_utils_spec.js b/spec/frontend/pipelines/components/dag/parsing_utils_spec.js
new file mode 100644
index 00000000000..d9a1296e572
--- /dev/null
+++ b/spec/frontend/pipelines/components/dag/parsing_utils_spec.js
@@ -0,0 +1,133 @@
+import {
+ createNodesStructure,
+ makeLinksFromNodes,
+ filterByAncestors,
+ parseData,
+ removeOrphanNodes,
+ getMaxNodes,
+} from '~/pipelines/components/dag/parsing_utils';
+
+import { createSankey } from '~/pipelines/components/dag/drawing_utils';
+import { mockBaseData } from './mock_data';
+
+describe('DAG visualization parsing utilities', () => {
+ const { nodes, nodeDict } = createNodesStructure(mockBaseData.stages);
+ const unfilteredLinks = makeLinksFromNodes(nodes, nodeDict);
+ const parsed = parseData(mockBaseData.stages);
+
+ const layoutSettings = {
+ width: 200,
+ height: 200,
+ nodeWidth: 10,
+ nodePadding: 20,
+ paddingForLabels: 100,
+ };
+
+ const sankeyLayout = createSankey(layoutSettings)(parsed);
+
+ describe('createNodesStructure', () => {
+ const parallelGroupName = 'jest';
+ const parallelJobName = 'jest 1/2';
+ const singleJobName = 'frontend fixtures';
+
+ const { name, jobs, size } = mockBaseData.stages[0].groups[0];
+
+ it('returns the expected node structure', () => {
+ expect(nodes[0]).toHaveProperty('category', mockBaseData.stages[0].name);
+ expect(nodes[0]).toHaveProperty('name', name);
+ expect(nodes[0]).toHaveProperty('jobs', jobs);
+ expect(nodes[0]).toHaveProperty('size', size);
+ });
+
+ it('adds needs to top level of nodeDict entries', () => {
+ expect(nodeDict[parallelGroupName]).toHaveProperty('needs');
+ expect(nodeDict[parallelJobName]).toHaveProperty('needs');
+ expect(nodeDict[singleJobName]).toHaveProperty('needs');
+ });
+
+ it('makes entries in nodeDict for jobs and parallel jobs', () => {
+ const nodeNames = Object.keys(nodeDict);
+
+ expect(nodeNames.includes(parallelGroupName)).toBe(true);
+ expect(nodeNames.includes(parallelJobName)).toBe(true);
+ expect(nodeNames.includes(singleJobName)).toBe(true);
+ });
+ });
+
+ describe('makeLinksFromNodes', () => {
+ it('returns the expected link structure', () => {
+ expect(unfilteredLinks[0]).toHaveProperty('source', 'frontend fixtures');
+ expect(unfilteredLinks[0]).toHaveProperty('target', 'jest');
+ expect(unfilteredLinks[0]).toHaveProperty('value', 10);
+ });
+ });
+
+ 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 cleanedNodes = removeOrphanNodes(sankeyLayout.nodes);
+ expect(cleanedNodes).toHaveLength(sankeyLayout.nodes.length - 1);
+ });
+ });
+
+ 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);
+ });
+ });
+});
diff --git a/spec/frontend/pipelines/components/pipelines_filtered_search_spec.js b/spec/frontend/pipelines/components/pipelines_filtered_search_spec.js
index 12c6fab9c41..bdc807fcbfe 100644
--- a/spec/frontend/pipelines/components/pipelines_filtered_search_spec.js
+++ b/spec/frontend/pipelines/components/pipelines_filtered_search_spec.js
@@ -3,13 +3,7 @@ import { mount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import PipelinesFilteredSearch from '~/pipelines/components/pipelines_filtered_search.vue';
-import {
- users,
- mockSearch,
- pipelineWithStages,
- branches,
- mockBranchesAfterMap,
-} from '../mock_data';
+import { users, mockSearch, branches, tags } from '../mock_data';
import { GlFilteredSearch } from '@gitlab/ui';
describe('Pipelines filtered search', () => {
@@ -21,12 +15,16 @@ describe('Pipelines filtered search', () => {
findFilteredSearch()
.props('availableTokens')
.find(token => token.type === type);
+ const findBranchToken = () => getSearchToken('ref');
+ const findTagToken = () => getSearchToken('tag');
+ const findUserToken = () => getSearchToken('username');
+ const findStatusToken = () => getSearchToken('status');
- const createComponent = () => {
+ const createComponent = (params = {}) => {
wrapper = mount(PipelinesFilteredSearch, {
propsData: {
- pipelines: [pipelineWithStages],
projectId: '21',
+ params,
},
attachToDocument: true,
});
@@ -37,6 +35,7 @@ describe('Pipelines filtered search', () => {
jest.spyOn(Api, 'projectUsers').mockResolvedValue(users);
jest.spyOn(Api, 'branches').mockResolvedValue({ data: branches });
+ jest.spyOn(Api, 'tags').mockResolvedValue({ data: tags });
createComponent();
});
@@ -55,37 +54,39 @@ describe('Pipelines filtered search', () => {
});
it('displays search tokens', () => {
- expect(getSearchToken('username')).toMatchObject({
+ expect(findUserToken()).toMatchObject({
type: 'username',
icon: 'user',
title: 'Trigger author',
unique: true,
- triggerAuthors: users,
projectId: '21',
operators: [expect.objectContaining({ value: '=' })],
});
- expect(getSearchToken('ref')).toMatchObject({
+ expect(findBranchToken()).toMatchObject({
type: 'ref',
icon: 'branch',
title: 'Branch name',
unique: true,
- branches: mockBranchesAfterMap,
projectId: '21',
operators: [expect.objectContaining({ value: '=' })],
});
- });
-
- it('fetches and sets project users', () => {
- expect(Api.projectUsers).toHaveBeenCalled();
-
- expect(wrapper.vm.projectUsers).toEqual(users);
- });
- it('fetches and sets branches', () => {
- expect(Api.branches).toHaveBeenCalled();
+ expect(findStatusToken()).toMatchObject({
+ type: 'status',
+ icon: 'status',
+ title: 'Status',
+ unique: true,
+ operators: [expect.objectContaining({ value: '=' })],
+ });
- expect(wrapper.vm.projectBranches).toEqual(mockBranchesAfterMap);
+ expect(findTagToken()).toMatchObject({
+ type: 'tag',
+ icon: 'tag',
+ title: 'Tag name',
+ unique: true,
+ operators: [expect.objectContaining({ value: '=' })],
+ });
});
it('emits filterPipelines on submit with correct filter', () => {
@@ -94,4 +95,80 @@ describe('Pipelines filtered search', () => {
expect(wrapper.emitted('filterPipelines')).toBeTruthy();
expect(wrapper.emitted('filterPipelines')[0]).toEqual([mockSearch]);
});
+
+ it('disables tag name token when branch name token is active', () => {
+ findFilteredSearch().vm.$emit('input', [
+ { type: 'ref', value: { data: 'branch-1', operator: '=' } },
+ { type: 'filtered-search-term', value: { data: '' } },
+ ]);
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findBranchToken().disabled).toBe(false);
+ expect(findTagToken().disabled).toBe(true);
+ });
+ });
+
+ it('disables branch name token when tag name token is active', () => {
+ findFilteredSearch().vm.$emit('input', [
+ { type: 'tag', value: { data: 'tag-1', operator: '=' } },
+ { type: 'filtered-search-term', value: { data: '' } },
+ ]);
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findBranchToken().disabled).toBe(true);
+ expect(findTagToken().disabled).toBe(false);
+ });
+ });
+
+ it('resets tokens disabled state on clear', () => {
+ findFilteredSearch().vm.$emit('clearInput');
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findBranchToken().disabled).toBe(false);
+ expect(findTagToken().disabled).toBe(false);
+ });
+ });
+
+ it('resets tokens disabled state when clearing tokens by backspace', () => {
+ findFilteredSearch().vm.$emit('input', [{ type: 'filtered-search-term', value: { data: '' } }]);
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findBranchToken().disabled).toBe(false);
+ expect(findTagToken().disabled).toBe(false);
+ });
+ });
+
+ describe('Url query params', () => {
+ const params = {
+ username: 'deja.green',
+ ref: 'master',
+ };
+
+ beforeEach(() => {
+ createComponent(params);
+ });
+
+ it('sets default value if url query params', () => {
+ const expectedValueProp = [
+ {
+ type: 'username',
+ value: {
+ data: params.username,
+ operator: '=',
+ },
+ },
+ {
+ type: 'ref',
+ value: {
+ data: params.ref,
+ operator: '=',
+ },
+ },
+ { type: 'filtered-search-term', value: { data: '' } },
+ ];
+
+ expect(findFilteredSearch().props('value')).toEqual(expectedValueProp);
+ expect(findFilteredSearch().props('value')).toHaveLength(expectedValueProp.length);
+ });
+ });
});
diff --git a/spec/frontend/pipelines/graph/graph_component_spec.js b/spec/frontend/pipelines/graph/graph_component_spec.js
index a9b06eab3fa..9731ce3f8a6 100644
--- a/spec/frontend/pipelines/graph/graph_component_spec.js
+++ b/spec/frontend/pipelines/graph/graph_component_spec.js
@@ -7,6 +7,7 @@ import linkedPipelinesColumn from '~/pipelines/components/graph/linked_pipelines
import graphJSON from './mock_data';
import linkedPipelineJSON from './linked_pipelines_mock_data';
import PipelinesMediator from '~/pipelines/pipeline_details_mediator';
+import { setHTMLFixture } from 'helpers/fixtures';
describe('graph component', () => {
const store = new PipelineStore();
@@ -15,6 +16,10 @@ describe('graph component', () => {
let wrapper;
+ beforeEach(() => {
+ setHTMLFixture('<div class="layout-page"></div>');
+ });
+
afterEach(() => {
wrapper.destroy();
wrapper = null;
diff --git a/spec/frontend/pipelines/mock_data.js b/spec/frontend/pipelines/mock_data.js
index 37c1e471415..e63efc543f1 100644
--- a/spec/frontend/pipelines/mock_data.js
+++ b/spec/frontend/pipelines/mock_data.js
@@ -560,9 +560,107 @@ export const branches = [
},
];
+export const tags = [
+ {
+ name: 'tag-3',
+ message: '',
+ target: '66673b07efef254dab7d537f0433a40e61cf84fe',
+ commit: {
+ id: '66673b07efef254dab7d537f0433a40e61cf84fe',
+ short_id: '66673b07',
+ created_at: '2020-03-16T11:04:46.000-04:00',
+ parent_ids: ['def28bf679235071140180495f25b657e2203587'],
+ title: 'Update .gitlab-ci.yml',
+ message: 'Update .gitlab-ci.yml',
+ author_name: 'Administrator',
+ author_email: 'admin@example.com',
+ authored_date: '2020-03-16T11:04:46.000-04:00',
+ committer_name: 'Administrator',
+ committer_email: 'admin@example.com',
+ committed_date: '2020-03-16T11:04:46.000-04:00',
+ web_url:
+ 'http://192.168.1.22:3000/root/dag-pipeline/-/commit/66673b07efef254dab7d537f0433a40e61cf84fe',
+ },
+ release: null,
+ protected: false,
+ },
+ {
+ name: 'tag-2',
+ message: '',
+ target: '66673b07efef254dab7d537f0433a40e61cf84fe',
+ commit: {
+ id: '66673b07efef254dab7d537f0433a40e61cf84fe',
+ short_id: '66673b07',
+ created_at: '2020-03-16T11:04:46.000-04:00',
+ parent_ids: ['def28bf679235071140180495f25b657e2203587'],
+ title: 'Update .gitlab-ci.yml',
+ message: 'Update .gitlab-ci.yml',
+ author_name: 'Administrator',
+ author_email: 'admin@example.com',
+ authored_date: '2020-03-16T11:04:46.000-04:00',
+ committer_name: 'Administrator',
+ committer_email: 'admin@example.com',
+ committed_date: '2020-03-16T11:04:46.000-04:00',
+ web_url:
+ 'http://192.168.1.22:3000/root/dag-pipeline/-/commit/66673b07efef254dab7d537f0433a40e61cf84fe',
+ },
+ release: null,
+ protected: false,
+ },
+ {
+ name: 'tag-1',
+ message: '',
+ target: '66673b07efef254dab7d537f0433a40e61cf84fe',
+ commit: {
+ id: '66673b07efef254dab7d537f0433a40e61cf84fe',
+ short_id: '66673b07',
+ created_at: '2020-03-16T11:04:46.000-04:00',
+ parent_ids: ['def28bf679235071140180495f25b657e2203587'],
+ title: 'Update .gitlab-ci.yml',
+ message: 'Update .gitlab-ci.yml',
+ author_name: 'Administrator',
+ author_email: 'admin@example.com',
+ authored_date: '2020-03-16T11:04:46.000-04:00',
+ committer_name: 'Administrator',
+ committer_email: 'admin@example.com',
+ committed_date: '2020-03-16T11:04:46.000-04:00',
+ web_url:
+ 'http://192.168.1.22:3000/root/dag-pipeline/-/commit/66673b07efef254dab7d537f0433a40e61cf84fe',
+ },
+ release: null,
+ protected: false,
+ },
+ {
+ name: 'master-tag',
+ message: '',
+ target: '66673b07efef254dab7d537f0433a40e61cf84fe',
+ commit: {
+ id: '66673b07efef254dab7d537f0433a40e61cf84fe',
+ short_id: '66673b07',
+ created_at: '2020-03-16T11:04:46.000-04:00',
+ parent_ids: ['def28bf679235071140180495f25b657e2203587'],
+ title: 'Update .gitlab-ci.yml',
+ message: 'Update .gitlab-ci.yml',
+ author_name: 'Administrator',
+ author_email: 'admin@example.com',
+ authored_date: '2020-03-16T11:04:46.000-04:00',
+ committer_name: 'Administrator',
+ committer_email: 'admin@example.com',
+ committed_date: '2020-03-16T11:04:46.000-04:00',
+ web_url:
+ 'http://192.168.1.22:3000/root/dag-pipeline/-/commit/66673b07efef254dab7d537f0433a40e61cf84fe',
+ },
+ release: null,
+ protected: false,
+ },
+];
+
export const mockSearch = [
{ type: 'username', value: { data: 'root', operator: '=' } },
{ type: 'ref', value: { data: 'master', operator: '=' } },
+ { type: 'status', value: { data: 'pending', operator: '=' } },
];
export const mockBranchesAfterMap = ['branch-1', 'branch-10', 'branch-11'];
+
+export const mockTagsAfterMap = ['tag-3', 'tag-2', 'tag-1', 'master-tag'];
diff --git a/spec/frontend/pipelines/pipelines_spec.js b/spec/frontend/pipelines/pipelines_spec.js
index 2ddd2116e2c..0eeaef01a2d 100644
--- a/spec/frontend/pipelines/pipelines_spec.js
+++ b/spec/frontend/pipelines/pipelines_spec.js
@@ -56,6 +56,7 @@ describe('Pipelines', () => {
propsData: {
store: new Store(),
projectId: '21',
+ params: {},
...props,
},
methods: {
@@ -683,7 +684,13 @@ describe('Pipelines', () => {
});
it('updates request data and query params on filter submit', () => {
- const expectedQueryParams = { page: '1', scope: 'all', username: 'root', ref: 'master' };
+ const expectedQueryParams = {
+ page: '1',
+ scope: 'all',
+ username: 'root',
+ ref: 'master',
+ status: 'pending',
+ };
findFilteredSearch().vm.$emit('submit', mockSearch);
diff --git a/spec/frontend/pipelines/tokens/pipeline_branch_name_token_spec.js b/spec/frontend/pipelines/tokens/pipeline_branch_name_token_spec.js
index a6753600792..1a85221581e 100644
--- a/spec/frontend/pipelines/tokens/pipeline_branch_name_token_spec.js
+++ b/spec/frontend/pipelines/tokens/pipeline_branch_name_token_spec.js
@@ -1,7 +1,8 @@
+import Api from '~/api';
import { GlFilteredSearchToken, GlFilteredSearchSuggestion, GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import PipelineBranchNameToken from '~/pipelines/components/tokens/pipeline_branch_name_token.vue';
-import { branches } from '../mock_data';
+import { branches, mockBranchesAfterMap } from '../mock_data';
describe('Pipeline Branch Name Token', () => {
let wrapper;
@@ -21,10 +22,9 @@ describe('Pipeline Branch Name Token', () => {
type: 'ref',
icon: 'branch',
title: 'Branch name',
- dataType: 'ref',
unique: true,
- branches,
projectId: '21',
+ disabled: false,
},
value: {
data: '',
@@ -46,6 +46,8 @@ describe('Pipeline Branch Name Token', () => {
};
beforeEach(() => {
+ jest.spyOn(Api, 'branches').mockResolvedValue({ data: branches });
+
createComponent();
});
@@ -58,6 +60,13 @@ describe('Pipeline Branch Name Token', () => {
expect(findFilteredSearchToken().props('config')).toEqual(defaultProps.config);
});
+ it('fetches and sets project branches', () => {
+ expect(Api.branches).toHaveBeenCalled();
+
+ expect(wrapper.vm.branches).toEqual(mockBranchesAfterMap);
+ expect(findLoadingIcon().exists()).toBe(false);
+ });
+
describe('displays loading icon correctly', () => {
it('shows loading icon', () => {
createComponent({ stubs }, { loading: true });
@@ -73,7 +82,7 @@ describe('Pipeline Branch Name Token', () => {
});
describe('shows branches correctly', () => {
- it('renders all trigger authors', () => {
+ it('renders all branches', () => {
createComponent({ stubs }, { branches, loading: false });
expect(findAllFilteredSearchSuggestions()).toHaveLength(branches.length);
diff --git a/spec/frontend/pipelines/tokens/pipeline_status_token_spec.js b/spec/frontend/pipelines/tokens/pipeline_status_token_spec.js
new file mode 100644
index 00000000000..ee3694868a5
--- /dev/null
+++ b/spec/frontend/pipelines/tokens/pipeline_status_token_spec.js
@@ -0,0 +1,62 @@
+import { GlFilteredSearchToken, GlFilteredSearchSuggestion, GlIcon } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import PipelineStatusToken from '~/pipelines/components/tokens/pipeline_status_token.vue';
+
+describe('Pipeline Status Token', () => {
+ let wrapper;
+
+ const findFilteredSearchToken = () => wrapper.find(GlFilteredSearchToken);
+ const findAllFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion);
+ const findAllGlIcons = () => wrapper.findAll(GlIcon);
+
+ const stubs = {
+ GlFilteredSearchToken: {
+ template: `<div><slot name="suggestions"></slot></div>`,
+ },
+ };
+
+ const defaultProps = {
+ config: {
+ type: 'status',
+ icon: 'status',
+ title: 'Status',
+ unique: true,
+ },
+ value: {
+ data: '',
+ },
+ };
+
+ const createComponent = options => {
+ wrapper = shallowMount(PipelineStatusToken, {
+ propsData: {
+ ...defaultProps,
+ },
+ ...options,
+ });
+ };
+
+ beforeEach(() => {
+ createComponent();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ it('passes config correctly', () => {
+ expect(findFilteredSearchToken().props('config')).toEqual(defaultProps.config);
+ });
+
+ describe('shows statuses correctly', () => {
+ beforeEach(() => {
+ createComponent({ stubs });
+ });
+
+ it('renders all pipeline statuses available', () => {
+ expect(findAllFilteredSearchSuggestions()).toHaveLength(wrapper.vm.statuses.length);
+ expect(findAllGlIcons()).toHaveLength(wrapper.vm.statuses.length);
+ });
+ });
+});
diff --git a/spec/frontend/pipelines/tokens/pipeline_tag_name_token_spec.js b/spec/frontend/pipelines/tokens/pipeline_tag_name_token_spec.js
new file mode 100644
index 00000000000..9fecc9412b7
--- /dev/null
+++ b/spec/frontend/pipelines/tokens/pipeline_tag_name_token_spec.js
@@ -0,0 +1,98 @@
+import Api from '~/api';
+import { GlFilteredSearchToken, GlFilteredSearchSuggestion, GlLoadingIcon } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import PipelineTagNameToken from '~/pipelines/components/tokens/pipeline_tag_name_token.vue';
+import { tags, mockTagsAfterMap } from '../mock_data';
+
+describe('Pipeline Branch Name Token', () => {
+ let wrapper;
+
+ const findFilteredSearchToken = () => wrapper.find(GlFilteredSearchToken);
+ const findAllFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion);
+ const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
+
+ const stubs = {
+ GlFilteredSearchToken: {
+ template: `<div><slot name="suggestions"></slot></div>`,
+ },
+ };
+
+ const defaultProps = {
+ config: {
+ type: 'tag',
+ icon: 'tag',
+ title: 'Tag name',
+ unique: true,
+ projectId: '21',
+ disabled: false,
+ },
+ value: {
+ data: '',
+ },
+ };
+
+ const createComponent = (options, data) => {
+ wrapper = shallowMount(PipelineTagNameToken, {
+ propsData: {
+ ...defaultProps,
+ },
+ data() {
+ return {
+ ...data,
+ };
+ },
+ ...options,
+ });
+ };
+
+ beforeEach(() => {
+ jest.spyOn(Api, 'tags').mockResolvedValue({ data: tags });
+
+ createComponent();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ it('passes config correctly', () => {
+ expect(findFilteredSearchToken().props('config')).toEqual(defaultProps.config);
+ });
+
+ it('fetches and sets project tags', () => {
+ expect(Api.tags).toHaveBeenCalled();
+
+ expect(wrapper.vm.tags).toEqual(mockTagsAfterMap);
+ expect(findLoadingIcon().exists()).toBe(false);
+ });
+
+ describe('displays loading icon correctly', () => {
+ it('shows loading icon', () => {
+ createComponent({ stubs }, { loading: true });
+
+ expect(findLoadingIcon().exists()).toBe(true);
+ });
+
+ it('does not show loading icon', () => {
+ createComponent({ stubs }, { loading: false });
+
+ expect(findLoadingIcon().exists()).toBe(false);
+ });
+ });
+
+ describe('shows tags correctly', () => {
+ it('renders all tags', () => {
+ createComponent({ stubs }, { tags, loading: false });
+
+ expect(findAllFilteredSearchSuggestions()).toHaveLength(tags.length);
+ });
+
+ it('renders only the tag searched for', () => {
+ const mockTags = ['master-tag'];
+ createComponent({ stubs }, { tags: mockTags, loading: false });
+
+ expect(findAllFilteredSearchSuggestions()).toHaveLength(mockTags.length);
+ });
+ });
+});
diff --git a/spec/frontend/pipelines/tokens/pipeline_trigger_author_token_spec.js b/spec/frontend/pipelines/tokens/pipeline_trigger_author_token_spec.js
index 00a9ff04e75..98de4f40c51 100644
--- a/spec/frontend/pipelines/tokens/pipeline_trigger_author_token_spec.js
+++ b/spec/frontend/pipelines/tokens/pipeline_trigger_author_token_spec.js
@@ -1,3 +1,4 @@
+import Api from '~/api';
import { GlFilteredSearchToken, GlFilteredSearchSuggestion, GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import PipelineTriggerAuthorToken from '~/pipelines/components/tokens/pipeline_trigger_author_token.vue';
@@ -45,6 +46,8 @@ describe('Pipeline Trigger Author Token', () => {
};
beforeEach(() => {
+ jest.spyOn(Api, 'projectUsers').mockResolvedValue(users);
+
createComponent();
});
@@ -57,6 +60,13 @@ describe('Pipeline Trigger Author Token', () => {
expect(findFilteredSearchToken().props('config')).toEqual(defaultProps.config);
});
+ it('fetches and sets project users', () => {
+ expect(Api.projectUsers).toHaveBeenCalled();
+
+ expect(wrapper.vm.users).toEqual(users);
+ expect(findLoadingIcon().exists()).toBe(false);
+ });
+
describe('displays loading icon correctly', () => {
it('shows loading icon', () => {
createComponent({ stubs }, { loading: true });
diff --git a/spec/frontend/projects/experiment_new_project_creation/components/app_spec.js b/spec/frontend/projects/experiment_new_project_creation/components/app_spec.js
new file mode 100644
index 00000000000..a1e1e4554e2
--- /dev/null
+++ b/spec/frontend/projects/experiment_new_project_creation/components/app_spec.js
@@ -0,0 +1,70 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlBreadcrumb } from '@gitlab/ui';
+import App from '~/projects/experiment_new_project_creation/components/app.vue';
+import WelcomePage from '~/projects/experiment_new_project_creation/components/welcome.vue';
+import LegacyContainer from '~/projects/experiment_new_project_creation/components/legacy_container.vue';
+
+describe('Experimental new project creation app', () => {
+ let wrapper;
+
+ const createComponent = propsData => {
+ wrapper = shallowMount(App, { propsData });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ window.location.hash = '';
+ wrapper = null;
+ });
+
+ describe('with empty hash', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('renders welcome page', () => {
+ expect(wrapper.find(WelcomePage).exists()).toBe(true);
+ });
+
+ it('does not render breadcrumbs', () => {
+ expect(wrapper.find(GlBreadcrumb).exists()).toBe(false);
+ });
+ });
+
+ it('renders blank project container if there are errors', () => {
+ createComponent({ hasErrors: true });
+ expect(wrapper.find(WelcomePage).exists()).toBe(false);
+ expect(wrapper.find(LegacyContainer).exists()).toBe(true);
+ });
+
+ describe('when hash is not empty on load', () => {
+ beforeEach(() => {
+ window.location.hash = '#blank_project';
+ createComponent();
+ });
+
+ it('renders relevant container', () => {
+ expect(wrapper.find(WelcomePage).exists()).toBe(false);
+ expect(wrapper.find(LegacyContainer).exists()).toBe(true);
+ });
+
+ it('renders breadcrumbs', () => {
+ expect(wrapper.find(GlBreadcrumb).exists()).toBe(true);
+ });
+ });
+
+ it('renders relevant container when hash changes', () => {
+ createComponent();
+ expect(wrapper.find(WelcomePage).exists()).toBe(true);
+
+ window.location.hash = '#blank_project';
+ const ev = document.createEvent('HTMLEvents');
+ ev.initEvent('hashchange', false, false);
+ window.dispatchEvent(ev);
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.find(WelcomePage).exists()).toBe(false);
+ expect(wrapper.find(LegacyContainer).exists()).toBe(true);
+ });
+ });
+});
diff --git a/spec/frontend/projects/experiment_new_project_creation/components/legacy_container_spec.js b/spec/frontend/projects/experiment_new_project_creation/components/legacy_container_spec.js
new file mode 100644
index 00000000000..cd8b39f0426
--- /dev/null
+++ b/spec/frontend/projects/experiment_new_project_creation/components/legacy_container_spec.js
@@ -0,0 +1,63 @@
+import { shallowMount } from '@vue/test-utils';
+import LegacyContainer from '~/projects/experiment_new_project_creation/components/legacy_container.vue';
+import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
+
+describe('Legacy container component', () => {
+ let wrapper;
+ let dummy;
+
+ const createComponent = propsData => {
+ wrapper = shallowMount(LegacyContainer, { propsData });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ resetHTMLFixture();
+ wrapper = null;
+ });
+
+ describe('when selector targets real node', () => {
+ beforeEach(() => {
+ setHTMLFixture('<div class="dummy-target"></div>');
+ dummy = document.querySelector('.dummy-target');
+ createComponent({ selector: '.dummy-target' });
+ });
+
+ describe('when mounted', () => {
+ it('moves node inside component', () => {
+ expect(dummy.parentNode).toBe(wrapper.element);
+ });
+
+ it('sets active class', () => {
+ expect(dummy.classList.contains('active')).toBe(true);
+ });
+ });
+
+ describe('when unmounted', () => {
+ beforeEach(() => {
+ wrapper.destroy();
+ });
+
+ it('moves node back', () => {
+ expect(dummy.parentNode).toBe(document.body);
+ });
+
+ it('removes active class', () => {
+ expect(dummy.classList.contains('active')).toBe(false);
+ });
+ });
+ });
+
+ describe('when selector targets template node', () => {
+ beforeEach(() => {
+ setHTMLFixture('<template class="dummy-target">content</template>');
+ dummy = document.querySelector('.dummy-target');
+ createComponent({ selector: '.dummy-target' });
+ });
+
+ it('copies node content when mounted', () => {
+ expect(dummy.innerHTML).toEqual(wrapper.element.innerHTML);
+ expect(dummy.parentNode).toBe(document.body);
+ });
+ });
+});
diff --git a/spec/frontend/projects/experiment_new_project_creation/components/welcome_spec.js b/spec/frontend/projects/experiment_new_project_creation/components/welcome_spec.js
new file mode 100644
index 00000000000..acd142fa5ba
--- /dev/null
+++ b/spec/frontend/projects/experiment_new_project_creation/components/welcome_spec.js
@@ -0,0 +1,31 @@
+import { shallowMount } from '@vue/test-utils';
+import WelcomePage from '~/projects/experiment_new_project_creation/components/welcome.vue';
+import { mockTracking } from 'helpers/tracking_helper';
+
+describe('Welcome page', () => {
+ let wrapper;
+ let trackingSpy;
+
+ const createComponent = propsData => {
+ wrapper = shallowMount(WelcomePage, { propsData });
+ };
+
+ beforeEach(() => {
+ trackingSpy = mockTracking('_category_', document, jest.spyOn);
+ trackingSpy.mockImplementation(() => {});
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ window.location.hash = '';
+ wrapper = null;
+ });
+
+ it('tracks link clicks', () => {
+ createComponent({ panels: [{ name: 'test', href: '#' }] });
+ wrapper.find('a').trigger('click');
+ return wrapper.vm.$nextTick().then(() => {
+ expect(trackingSpy).toHaveBeenCalledWith(undefined, 'click_tab', { label: 'test' });
+ });
+ });
+});
diff --git a/spec/frontend/projects/pipelines/charts/components/__snapshots__/pipelines_area_chart_spec.js.snap b/spec/frontend/projects/pipelines/charts/components/__snapshots__/pipelines_area_chart_spec.js.snap
index 3222b92d23f..f280ecaa0bc 100644
--- a/spec/frontend/projects/pipelines/charts/components/__snapshots__/pipelines_area_chart_spec.js.snap
+++ b/spec/frontend/projects/pipelines/charts/components/__snapshots__/pipelines_area_chart_spec.js.snap
@@ -14,7 +14,10 @@ exports[`PipelinesAreaChart matches the snapshot 1`] = `
data="[object Object],[object Object]"
height="300"
legendaveragetext="Avg"
+ legendcurrenttext="Current"
+ legendlayout="inline"
legendmaxtext="Max"
+ legendmintext="Min"
option="[object Object]"
thresholds=""
width="0"
diff --git a/spec/javascripts/read_more_spec.js b/spec/frontend/read_more_spec.js
index d1d01272403..d1d01272403 100644
--- a/spec/javascripts/read_more_spec.js
+++ b/spec/frontend/read_more_spec.js
diff --git a/spec/frontend/registry/explorer/components/__snapshots__/project_empty_state_spec.js.snap b/spec/frontend/registry/explorer/components/__snapshots__/project_empty_state_spec.js.snap
deleted file mode 100644
index 19767aefd1a..00000000000
--- a/spec/frontend/registry/explorer/components/__snapshots__/project_empty_state_spec.js.snap
+++ /dev/null
@@ -1,119 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Registry Project Empty state to match the default snapshot 1`] = `
-<div
- class="container-message"
- svg-path="bazFoo"
- title="There are no container images stored for this project"
->
- <p
- class="js-no-container-images-text"
- >
- With the Container Registry, every project can have its own space to store its Docker images.
- <gl-link-stub
- href="baz"
- target="_blank"
- >
- More Information
- </gl-link-stub>
- </p>
-
- <h5>
- Quick Start
- </h5>
-
- <p
- class="js-not-logged-in-to-registry-text"
- >
- If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have
- <gl-link-stub
- href="barBaz"
- target="_blank"
- >
- Two-Factor Authentication
- </gl-link-stub>
- enabled, use a
- <gl-link-stub
- href="fooBaz"
- target="_blank"
- >
- Personal Access Token
- </gl-link-stub>
- instead of a password.
- </p>
-
- <div
- class="input-group append-bottom-10"
- >
- <input
- class="form-control monospace"
- readonly="readonly"
- type="text"
- />
-
- <span
- class="input-group-append"
- >
- <clipboard-button-stub
- class="input-group-text"
- cssclass="btn-default"
- text="docker login bar"
- title="Copy login command"
- tooltipplacement="top"
- />
- </span>
- </div>
-
- <p />
-
- <p>
-
- You can add an image to this registry with the following commands:
-
- </p>
-
- <div
- class="input-group append-bottom-10"
- >
- <input
- class="form-control monospace"
- readonly="readonly"
- type="text"
- />
-
- <span
- class="input-group-append"
- >
- <clipboard-button-stub
- class="input-group-text"
- cssclass="btn-default"
- text="docker build -t foo ."
- title="Copy build command"
- tooltipplacement="top"
- />
- </span>
- </div>
-
- <div
- class="input-group"
- >
- <input
- class="form-control monospace"
- readonly="readonly"
- type="text"
- />
-
- <span
- class="input-group-append"
- >
- <clipboard-button-stub
- class="input-group-text"
- cssclass="btn-default"
- text="docker push foo"
- title="Copy push command"
- tooltipplacement="top"
- />
- </span>
- </div>
-</div>
-`;
diff --git a/spec/frontend/registry/explorer/components/details_page/__snapshots__/tags_loader_spec.js.snap b/spec/frontend/registry/explorer/components/details_page/__snapshots__/tags_loader_spec.js.snap
new file mode 100644
index 00000000000..aeb49f88770
--- /dev/null
+++ b/spec/frontend/registry/explorer/components/details_page/__snapshots__/tags_loader_spec.js.snap
@@ -0,0 +1,63 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`TagsLoader component has the correct markup 1`] = `
+<div>
+ <div
+ preserve-aspect-ratio="xMinYMax meet"
+ >
+ <rect
+ height="15"
+ rx="4"
+ width="15"
+ x="0"
+ y="12.5"
+ />
+
+ <rect
+ height="20"
+ rx="4"
+ width="250"
+ x="25"
+ y="10"
+ />
+
+ <circle
+ cx="290"
+ cy="20"
+ r="10"
+ />
+
+ <rect
+ height="20"
+ rx="4"
+ width="100"
+ x="315"
+ y="10"
+ />
+
+ <rect
+ height="20"
+ rx="4"
+ width="100"
+ x="500"
+ y="10"
+ />
+
+ <rect
+ height="20"
+ rx="4"
+ width="100"
+ x="630"
+ y="10"
+ />
+
+ <rect
+ height="40"
+ rx="4"
+ width="40"
+ x="960"
+ y="0"
+ />
+ </div>
+</div>
+`;
diff --git a/spec/frontend/registry/explorer/components/details_page/delete_alert_spec.js b/spec/frontend/registry/explorer/components/details_page/delete_alert_spec.js
new file mode 100644
index 00000000000..5d54986978b
--- /dev/null
+++ b/spec/frontend/registry/explorer/components/details_page/delete_alert_spec.js
@@ -0,0 +1,116 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlAlert, GlSprintf, GlLink } from '@gitlab/ui';
+import component from '~/registry/explorer/components/details_page/delete_alert.vue';
+import {
+ DELETE_TAG_SUCCESS_MESSAGE,
+ DELETE_TAG_ERROR_MESSAGE,
+ DELETE_TAGS_SUCCESS_MESSAGE,
+ DELETE_TAGS_ERROR_MESSAGE,
+ ADMIN_GARBAGE_COLLECTION_TIP,
+} from '~/registry/explorer/constants';
+
+describe('Delete alert', () => {
+ let wrapper;
+
+ const findAlert = () => wrapper.find(GlAlert);
+ const findLink = () => wrapper.find(GlLink);
+
+ const mountComponent = propsData => {
+ wrapper = shallowMount(component, { stubs: { GlSprintf }, propsData });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ describe('when deleteAlertType is null', () => {
+ it('does not show the alert', () => {
+ mountComponent();
+ expect(findAlert().exists()).toBe(false);
+ });
+ });
+
+ describe('when deleteAlertType is not null', () => {
+ describe('success states', () => {
+ describe.each`
+ deleteAlertType | message
+ ${'success_tag'} | ${DELETE_TAG_SUCCESS_MESSAGE}
+ ${'success_tags'} | ${DELETE_TAGS_SUCCESS_MESSAGE}
+ `('when deleteAlertType is $deleteAlertType', ({ deleteAlertType, message }) => {
+ it('alert exists', () => {
+ mountComponent({ deleteAlertType });
+ expect(findAlert().exists()).toBe(true);
+ });
+
+ describe('when the user is an admin', () => {
+ beforeEach(() => {
+ mountComponent({
+ deleteAlertType,
+ isAdmin: true,
+ garbageCollectionHelpPagePath: 'foo',
+ });
+ });
+
+ it(`alert title is ${message}`, () => {
+ expect(findAlert().attributes('title')).toBe(message);
+ });
+
+ it('alert body contains admin tip', () => {
+ expect(findAlert().text()).toMatchInterpolatedText(ADMIN_GARBAGE_COLLECTION_TIP);
+ });
+
+ it('alert body contains link', () => {
+ const alertLink = findLink();
+ expect(alertLink.exists()).toBe(true);
+ expect(alertLink.attributes('href')).toBe('foo');
+ });
+ });
+
+ describe('when the user is not an admin', () => {
+ it('alert exist and text is appropriate', () => {
+ mountComponent({ deleteAlertType });
+ expect(findAlert().exists()).toBe(true);
+ expect(findAlert().text()).toBe(message);
+ });
+ });
+ });
+ });
+ describe('error states', () => {
+ describe.each`
+ deleteAlertType | message
+ ${'danger_tag'} | ${DELETE_TAG_ERROR_MESSAGE}
+ ${'danger_tags'} | ${DELETE_TAGS_ERROR_MESSAGE}
+ `('when deleteAlertType is $deleteAlertType', ({ deleteAlertType, message }) => {
+ it('alert exists', () => {
+ mountComponent({ deleteAlertType });
+ expect(findAlert().exists()).toBe(true);
+ });
+
+ describe('when the user is an admin', () => {
+ it('alert exist and text is appropriate', () => {
+ mountComponent({ deleteAlertType });
+ expect(findAlert().exists()).toBe(true);
+ expect(findAlert().text()).toBe(message);
+ });
+ });
+
+ describe('when the user is not an admin', () => {
+ it('alert exist and text is appropriate', () => {
+ mountComponent({ deleteAlertType });
+ expect(findAlert().exists()).toBe(true);
+ expect(findAlert().text()).toBe(message);
+ });
+ });
+ });
+ });
+
+ describe('dismissing alert', () => {
+ it('GlAlert dismiss event triggers a change event', () => {
+ mountComponent({ deleteAlertType: 'success_tags' });
+ findAlert().vm.$emit('dismiss');
+ expect(wrapper.emitted('change')).toEqual([[null]]);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/registry/explorer/components/details_page/delete_modal_spec.js b/spec/frontend/registry/explorer/components/details_page/delete_modal_spec.js
new file mode 100644
index 00000000000..c77f7a54d34
--- /dev/null
+++ b/spec/frontend/registry/explorer/components/details_page/delete_modal_spec.js
@@ -0,0 +1,79 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlSprintf } from '@gitlab/ui';
+import component from '~/registry/explorer/components/details_page/delete_modal.vue';
+import {
+ REMOVE_TAG_CONFIRMATION_TEXT,
+ REMOVE_TAGS_CONFIRMATION_TEXT,
+} from '~/registry/explorer/constants';
+import { GlModal } from '../../stubs';
+
+describe('Delete Modal', () => {
+ let wrapper;
+
+ const findModal = () => wrapper.find(GlModal);
+ const findDescription = () => wrapper.find('[data-testid="description"]');
+
+ const mountComponent = propsData => {
+ wrapper = shallowMount(component, {
+ propsData,
+ stubs: {
+ GlSprintf,
+ GlModal,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ it('contains a GlModal', () => {
+ mountComponent();
+ expect(findModal().exists()).toBe(true);
+ });
+
+ describe('events', () => {
+ it.each`
+ glEvent | localEvent
+ ${'ok'} | ${'confirmDelete'}
+ ${'cancel'} | ${'cancelDelete'}
+ `('GlModal $glEvent emits $localEvent', ({ glEvent, localEvent }) => {
+ mountComponent();
+ findModal().vm.$emit(glEvent);
+ expect(wrapper.emitted(localEvent)).toBeTruthy();
+ });
+ });
+
+ describe('methods', () => {
+ it('show calls gl-modal show', () => {
+ mountComponent();
+ wrapper.vm.show();
+ expect(GlModal.methods.show).toHaveBeenCalled();
+ });
+ });
+
+ describe('itemsToBeDeleted contains one element', () => {
+ beforeEach(() => {
+ mountComponent({ itemsToBeDeleted: [{ path: 'foo' }] });
+ });
+ it(`has the correct description`, () => {
+ expect(findDescription().text()).toBe(REMOVE_TAG_CONFIRMATION_TEXT.replace('%{item}', 'foo'));
+ });
+ it('has the correct action', () => {
+ expect(wrapper.text()).toContain('Remove tag');
+ });
+ });
+
+ describe('itemsToBeDeleted contains more than element', () => {
+ beforeEach(() => {
+ mountComponent({ itemsToBeDeleted: [{ path: 'foo' }, { path: 'bar' }] });
+ });
+ it(`has the correct description`, () => {
+ expect(findDescription().text()).toBe(REMOVE_TAGS_CONFIRMATION_TEXT.replace('%{item}', '2'));
+ });
+ it('has the correct action', () => {
+ expect(wrapper.text()).toContain('Remove tags');
+ });
+ });
+});
diff --git a/spec/frontend/registry/explorer/components/details_page/details_header_spec.js b/spec/frontend/registry/explorer/components/details_page/details_header_spec.js
new file mode 100644
index 00000000000..cb31efa428f
--- /dev/null
+++ b/spec/frontend/registry/explorer/components/details_page/details_header_spec.js
@@ -0,0 +1,32 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlSprintf } from '@gitlab/ui';
+import component from '~/registry/explorer/components/details_page/details_header.vue';
+import { DETAILS_PAGE_TITLE } from '~/registry/explorer/constants';
+
+describe('Details Header', () => {
+ let wrapper;
+
+ const mountComponent = propsData => {
+ wrapper = shallowMount(component, {
+ propsData,
+ stubs: {
+ GlSprintf,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ it('has the correct title ', () => {
+ mountComponent();
+ expect(wrapper.text()).toMatchInterpolatedText(DETAILS_PAGE_TITLE);
+ });
+
+ it('shows imageName in the title', () => {
+ mountComponent({ imageName: 'foo' });
+ expect(wrapper.text()).toContain('foo');
+ });
+});
diff --git a/spec/frontend/registry/explorer/components/details_page/empty_tags_state.js b/spec/frontend/registry/explorer/components/details_page/empty_tags_state.js
new file mode 100644
index 00000000000..da80c75a26a
--- /dev/null
+++ b/spec/frontend/registry/explorer/components/details_page/empty_tags_state.js
@@ -0,0 +1,43 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlEmptyState } from '@gitlab/ui';
+import component from '~/registry/explorer/components/details_page/empty_tags_state.vue';
+import {
+ EMPTY_IMAGE_REPOSITORY_TITLE,
+ EMPTY_IMAGE_REPOSITORY_MESSAGE,
+} from '~/registry/explorer/constants';
+
+describe('EmptyTagsState component', () => {
+ let wrapper;
+
+ const findEmptyState = () => wrapper.find(GlEmptyState);
+
+ const mountComponent = () => {
+ wrapper = shallowMount(component, {
+ stubs: {
+ GlEmptyState,
+ },
+ propsData: {
+ noContainersImage: 'foo',
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ it('contains gl-empty-state', () => {
+ mountComponent();
+ expect(findEmptyState().exist()).toBe(true);
+ });
+
+ it('has the correct props', () => {
+ mountComponent();
+ expect(findEmptyState().props()).toMatchObject({
+ title: EMPTY_IMAGE_REPOSITORY_TITLE,
+ description: EMPTY_IMAGE_REPOSITORY_MESSAGE,
+ svgPath: 'foo',
+ });
+ });
+});
diff --git a/spec/frontend/registry/explorer/components/details_page/tags_loader_spec.js b/spec/frontend/registry/explorer/components/details_page/tags_loader_spec.js
new file mode 100644
index 00000000000..b27d3e2c042
--- /dev/null
+++ b/spec/frontend/registry/explorer/components/details_page/tags_loader_spec.js
@@ -0,0 +1,49 @@
+import { shallowMount } from '@vue/test-utils';
+import component from '~/registry/explorer/components/details_page/tags_loader.vue';
+import { GlSkeletonLoader } from '../../stubs';
+
+describe('TagsLoader component', () => {
+ let wrapper;
+
+ const findGlSkeletonLoaders = () => wrapper.findAll(GlSkeletonLoader);
+
+ const mountComponent = () => {
+ wrapper = shallowMount(component, {
+ stubs: {
+ GlSkeletonLoader,
+ },
+ // set the repeat to 1 to avoid a long and verbose snapshot
+ loader: {
+ ...component.loader,
+ repeat: 1,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ it('produces the correct amount of loaders ', () => {
+ mountComponent();
+ expect(findGlSkeletonLoaders().length).toBe(1);
+ });
+
+ it('has the correct props', () => {
+ mountComponent();
+ expect(
+ findGlSkeletonLoaders()
+ .at(0)
+ .props(),
+ ).toMatchObject({
+ width: component.loader.width,
+ height: component.loader.height,
+ });
+ });
+
+ it('has the correct markup', () => {
+ mountComponent();
+ expect(wrapper.element).toMatchSnapshot();
+ });
+});
diff --git a/spec/frontend/registry/explorer/components/details_page/tags_table_spec.js b/spec/frontend/registry/explorer/components/details_page/tags_table_spec.js
new file mode 100644
index 00000000000..a60a362dcfe
--- /dev/null
+++ b/spec/frontend/registry/explorer/components/details_page/tags_table_spec.js
@@ -0,0 +1,286 @@
+import { mount } from '@vue/test-utils';
+import stubChildren from 'helpers/stub_children';
+import component from '~/registry/explorer/components/details_page/tags_table.vue';
+import { tagsListResponse } from '../../mock_data';
+
+describe('tags_table', () => {
+ let wrapper;
+ const tags = [...tagsListResponse.data];
+
+ const findMainCheckbox = () => wrapper.find('[data-testid="mainCheckbox"]');
+ const findFirstRowItem = testid => wrapper.find(`[data-testid="${testid}"]`);
+ const findBulkDeleteButton = () => wrapper.find('[data-testid="bulkDeleteButton"]');
+ const findAllDeleteButtons = () => wrapper.findAll('[data-testid="singleDeleteButton"]');
+ const findAllCheckboxes = () => wrapper.findAll('[data-testid="rowCheckbox"]');
+ const findCheckedCheckboxes = () => findAllCheckboxes().filter(c => c.attributes('checked'));
+ const findFirsTagColumn = () => wrapper.find('.js-tag-column');
+ const findFirstTagNameText = () => wrapper.find('[data-testid="rowNameText"]');
+
+ const findLoaderSlot = () => wrapper.find('[data-testid="loaderSlot"]');
+ const findEmptySlot = () => wrapper.find('[data-testid="emptySlot"]');
+
+ const mountComponent = (propsData = { tags, isDesktop: true }) => {
+ wrapper = mount(component, {
+ stubs: {
+ ...stubChildren(component),
+ GlTable: false,
+ },
+ propsData,
+ slots: {
+ loader: '<div data-testid="loaderSlot"></div>',
+ empty: '<div data-testid="emptySlot"></div>',
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ it.each([
+ 'rowCheckbox',
+ 'rowName',
+ 'rowShortRevision',
+ 'rowSize',
+ 'rowTime',
+ 'singleDeleteButton',
+ ])('%s exist in the table', element => {
+ mountComponent();
+
+ expect(findFirstRowItem(element).exists()).toBe(true);
+ });
+
+ describe('header checkbox', () => {
+ it('exists', () => {
+ mountComponent();
+ expect(findMainCheckbox().exists()).toBe(true);
+ });
+
+ it('if selected selects all the rows', () => {
+ mountComponent();
+ findMainCheckbox().vm.$emit('change');
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findMainCheckbox().attributes('checked')).toBeTruthy();
+ expect(findCheckedCheckboxes()).toHaveLength(tags.length);
+ });
+ });
+
+ it('if deselect deselects all the row', () => {
+ mountComponent();
+ findMainCheckbox().vm.$emit('change');
+ return wrapper.vm
+ .$nextTick()
+ .then(() => {
+ expect(findMainCheckbox().attributes('checked')).toBeTruthy();
+ findMainCheckbox().vm.$emit('change');
+ return wrapper.vm.$nextTick();
+ })
+ .then(() => {
+ expect(findMainCheckbox().attributes('checked')).toBe(undefined);
+ expect(findCheckedCheckboxes()).toHaveLength(0);
+ });
+ });
+ });
+
+ describe('row checkbox', () => {
+ beforeEach(() => {
+ mountComponent();
+ });
+
+ it('selecting and deselecting the checkbox works as intended', () => {
+ findFirstRowItem('rowCheckbox').vm.$emit('change');
+ return wrapper.vm
+ .$nextTick()
+ .then(() => {
+ expect(wrapper.vm.selectedItems).toEqual([tags[0].name]);
+ expect(findFirstRowItem('rowCheckbox').attributes('checked')).toBeTruthy();
+ findFirstRowItem('rowCheckbox').vm.$emit('change');
+ return wrapper.vm.$nextTick();
+ })
+ .then(() => {
+ expect(wrapper.vm.selectedItems.length).toBe(0);
+ expect(findFirstRowItem('rowCheckbox').attributes('checked')).toBe(undefined);
+ });
+ });
+ });
+
+ describe('header delete button', () => {
+ beforeEach(() => {
+ mountComponent();
+ });
+
+ it('exists', () => {
+ expect(findBulkDeleteButton().exists()).toBe(true);
+ });
+
+ it('is disabled if no item is selected', () => {
+ expect(findBulkDeleteButton().attributes('disabled')).toBe('true');
+ });
+
+ it('is enabled if at least one item is selected', () => {
+ expect(findBulkDeleteButton().attributes('disabled')).toBe('true');
+ findFirstRowItem('rowCheckbox').vm.$emit('change');
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findBulkDeleteButton().attributes('disabled')).toBeFalsy();
+ });
+ });
+
+ describe('on click', () => {
+ it('when one item is selected', () => {
+ findFirstRowItem('rowCheckbox').vm.$emit('change');
+ findBulkDeleteButton().vm.$emit('click');
+ expect(wrapper.emitted('delete')).toEqual([[['centos6']]]);
+ });
+
+ it('when multiple items are selected', () => {
+ findMainCheckbox().vm.$emit('change');
+ findBulkDeleteButton().vm.$emit('click');
+
+ expect(wrapper.emitted('delete')).toEqual([[tags.map(t => t.name)]]);
+ });
+ });
+ });
+
+ describe('row delete button', () => {
+ beforeEach(() => {
+ mountComponent();
+ });
+
+ it('exists', () => {
+ expect(
+ findAllDeleteButtons()
+ .at(0)
+ .exists(),
+ ).toBe(true);
+ });
+
+ it('is disabled if the item has no destroy_path', () => {
+ expect(
+ findAllDeleteButtons()
+ .at(1)
+ .attributes('disabled'),
+ ).toBe('true');
+ });
+
+ it('on click', () => {
+ findAllDeleteButtons()
+ .at(0)
+ .vm.$emit('click');
+
+ expect(wrapper.emitted('delete')).toEqual([[['centos6']]]);
+ });
+ });
+
+ describe('name cell', () => {
+ it('tag column has a tooltip with the tag name', () => {
+ mountComponent();
+ expect(findFirstTagNameText().attributes('title')).toBe(tagsListResponse.data[0].name);
+ });
+
+ describe('on desktop viewport', () => {
+ beforeEach(() => {
+ mountComponent();
+ });
+
+ it('table header has class w-25', () => {
+ expect(findFirsTagColumn().classes()).toContain('w-25');
+ });
+
+ it('tag column has the mw-m class', () => {
+ expect(findFirstRowItem('rowName').classes()).toContain('mw-m');
+ });
+ });
+
+ describe('on mobile viewport', () => {
+ beforeEach(() => {
+ mountComponent({ tags, isDesktop: false });
+ });
+
+ it('table header does not have class w-25', () => {
+ expect(findFirsTagColumn().classes()).not.toContain('w-25');
+ });
+
+ it('tag column has the gl-justify-content-end class', () => {
+ expect(findFirstRowItem('rowName').classes()).toContain('gl-justify-content-end');
+ });
+ });
+ });
+
+ describe('last updated cell', () => {
+ let timeCell;
+
+ beforeEach(() => {
+ mountComponent();
+ timeCell = findFirstRowItem('rowTime');
+ });
+
+ it('displays the time in string format', () => {
+ expect(timeCell.text()).toBe('2 years ago');
+ });
+
+ it('has a tooltip timestamp', () => {
+ expect(timeCell.attributes('title')).toBe('Sep 19, 2017 1:45pm GMT+0000');
+ });
+ });
+
+ describe('empty state slot', () => {
+ describe('when the table is empty', () => {
+ beforeEach(() => {
+ mountComponent({ tags: [], isDesktop: true });
+ });
+
+ it('does not show table rows', () => {
+ expect(findFirstTagNameText().exists()).toBe(false);
+ });
+
+ it('has the empty state slot', () => {
+ expect(findEmptySlot().exists()).toBe(true);
+ });
+ });
+
+ describe('when the table is not empty', () => {
+ beforeEach(() => {
+ mountComponent({ tags, isDesktop: true });
+ });
+
+ it('does show table rows', () => {
+ expect(findFirstTagNameText().exists()).toBe(true);
+ });
+
+ it('does not show the empty state', () => {
+ expect(findEmptySlot().exists()).toBe(false);
+ });
+ });
+ });
+
+ describe('loader slot', () => {
+ describe('when the data is loading', () => {
+ beforeEach(() => {
+ mountComponent({ isLoading: true, tags });
+ });
+
+ it('show the loader', () => {
+ expect(findLoaderSlot().exists()).toBe(true);
+ });
+
+ it('does not show the table rows', () => {
+ expect(findFirstTagNameText().exists()).toBe(false);
+ });
+ });
+
+ describe('when the data is not loading', () => {
+ beforeEach(() => {
+ mountComponent({ isLoading: false, tags });
+ });
+
+ it('does not show the loader', () => {
+ expect(findLoaderSlot().exists()).toBe(false);
+ });
+
+ it('shows the table rows', () => {
+ expect(findFirstTagNameText().exists()).toBe(true);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/registry/explorer/components/group_empty_state_spec.js b/spec/frontend/registry/explorer/components/group_empty_state_spec.js
deleted file mode 100644
index 1b4de534317..00000000000
--- a/spec/frontend/registry/explorer/components/group_empty_state_spec.js
+++ /dev/null
@@ -1,40 +0,0 @@
-import Vuex from 'vuex';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
-import { GlSprintf } from '@gitlab/ui';
-import { GlEmptyState } from '../stubs';
-import groupEmptyState from '~/registry/explorer/components/group_empty_state.vue';
-
-const localVue = createLocalVue();
-localVue.use(Vuex);
-
-describe('Registry Group Empty state', () => {
- let wrapper;
- let store;
-
- beforeEach(() => {
- store = new Vuex.Store({
- state: {
- config: {
- noContainersImage: 'foo',
- helpPagePath: 'baz',
- },
- },
- });
- wrapper = shallowMount(groupEmptyState, {
- localVue,
- store,
- stubs: {
- GlEmptyState,
- GlSprintf,
- },
- });
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- it('to match the default snapshot', () => {
- expect(wrapper.element).toMatchSnapshot();
- });
-});
diff --git a/spec/frontend/registry/explorer/components/image_list_spec.js b/spec/frontend/registry/explorer/components/image_list_spec.js
deleted file mode 100644
index 12f0fbe0c87..00000000000
--- a/spec/frontend/registry/explorer/components/image_list_spec.js
+++ /dev/null
@@ -1,74 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import { GlPagination } from '@gitlab/ui';
-import Component from '~/registry/explorer/components/image_list.vue';
-import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
-import { RouterLink } from '../stubs';
-import { imagesListResponse, imagePagination } from '../mock_data';
-
-describe('Image List', () => {
- let wrapper;
-
- const firstElement = imagesListResponse.data[0];
-
- const findDeleteBtn = () => wrapper.find('[data-testid="deleteImageButton"]');
- const findRowItems = () => wrapper.findAll('[data-testid="rowItem"]');
- const findDetailsLink = () => wrapper.find('[data-testid="detailsLink"]');
- const findClipboardButton = () => wrapper.find(ClipboardButton);
- const findPagination = () => wrapper.find(GlPagination);
-
- const mountComponent = () => {
- wrapper = shallowMount(Component, {
- stubs: {
- RouterLink,
- },
- propsData: {
- images: imagesListResponse.data,
- pagination: imagePagination,
- },
- });
- };
-
- beforeEach(() => {
- mountComponent();
- });
-
- it('contains one list element for each image', () => {
- expect(findRowItems().length).toBe(imagesListResponse.data.length);
- });
-
- it('contains a link to the details page', () => {
- const link = findDetailsLink();
- expect(link.html()).toContain(firstElement.path);
- expect(link.props('to').name).toBe('details');
- });
-
- it('contains a clipboard button', () => {
- const button = findClipboardButton();
- expect(button.exists()).toBe(true);
- expect(button.props('text')).toBe(firstElement.location);
- expect(button.props('title')).toBe(firstElement.location);
- });
-
- it('should be possible to delete a repo', () => {
- const deleteBtn = findDeleteBtn();
- expect(deleteBtn.exists()).toBe(true);
- });
-
- describe('pagination', () => {
- it('exists', () => {
- expect(findPagination().exists()).toBe(true);
- });
-
- it('is wired to the correct pagination props', () => {
- const pagination = findPagination();
- expect(pagination.props('perPage')).toBe(imagePagination.perPage);
- expect(pagination.props('totalItems')).toBe(imagePagination.total);
- expect(pagination.props('value')).toBe(imagePagination.page);
- });
-
- it('emits a pageChange event when the page change', () => {
- wrapper.setData({ currentPage: 2 });
- expect(wrapper.emitted('pageChange')).toEqual([[2]]);
- });
- });
-});
diff --git a/spec/frontend/registry/explorer/components/__snapshots__/group_empty_state_spec.js.snap b/spec/frontend/registry/explorer/components/list_page/__snapshots__/group_empty_state_spec.js.snap
index 3761369c944..3761369c944 100644
--- a/spec/frontend/registry/explorer/components/__snapshots__/group_empty_state_spec.js.snap
+++ b/spec/frontend/registry/explorer/components/list_page/__snapshots__/group_empty_state_spec.js.snap
diff --git a/spec/frontend/registry/explorer/components/list_page/__snapshots__/project_empty_state_spec.js.snap b/spec/frontend/registry/explorer/components/list_page/__snapshots__/project_empty_state_spec.js.snap
new file mode 100644
index 00000000000..d8ec9c3ca4d
--- /dev/null
+++ b/spec/frontend/registry/explorer/components/list_page/__snapshots__/project_empty_state_spec.js.snap
@@ -0,0 +1,119 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Registry Project Empty state to match the default snapshot 1`] = `
+<div
+ class="container-message"
+ svg-path="bazFoo"
+ title="There are no container images stored for this project"
+>
+ <p
+ class="js-no-container-images-text"
+ >
+ With the Container Registry, every project can have its own space to store its Docker images.
+ <gl-link-stub
+ href="baz"
+ target="_blank"
+ >
+ More Information
+ </gl-link-stub>
+ </p>
+
+ <h5>
+ CLI Commands
+ </h5>
+
+ <p
+ class="js-not-logged-in-to-registry-text"
+ >
+ If you are not already logged in, you need to authenticate to the Container Registry by using your GitLab username and password. If you have
+ <gl-link-stub
+ href="barBaz"
+ target="_blank"
+ >
+ Two-Factor Authentication
+ </gl-link-stub>
+ enabled, use a
+ <gl-link-stub
+ href="fooBaz"
+ target="_blank"
+ >
+ Personal Access Token
+ </gl-link-stub>
+ instead of a password.
+ </p>
+
+ <div
+ class="input-group append-bottom-10"
+ >
+ <input
+ class="form-control monospace"
+ readonly="readonly"
+ type="text"
+ />
+
+ <span
+ class="input-group-append"
+ >
+ <clipboard-button-stub
+ class="input-group-text"
+ cssclass="btn-default"
+ text="docker login bar"
+ title="Copy login command"
+ tooltipplacement="top"
+ />
+ </span>
+ </div>
+
+ <p />
+
+ <p>
+
+ You can add an image to this registry with the following commands:
+
+ </p>
+
+ <div
+ class="input-group append-bottom-10"
+ >
+ <input
+ class="form-control monospace"
+ readonly="readonly"
+ type="text"
+ />
+
+ <span
+ class="input-group-append"
+ >
+ <clipboard-button-stub
+ class="input-group-text"
+ cssclass="btn-default"
+ text="docker build -t foo ."
+ title="Copy build command"
+ tooltipplacement="top"
+ />
+ </span>
+ </div>
+
+ <div
+ class="input-group"
+ >
+ <input
+ class="form-control monospace"
+ readonly="readonly"
+ type="text"
+ />
+
+ <span
+ class="input-group-append"
+ >
+ <clipboard-button-stub
+ class="input-group-text"
+ cssclass="btn-default"
+ text="docker push foo"
+ title="Copy push command"
+ tooltipplacement="top"
+ />
+ </span>
+ </div>
+</div>
+`;
diff --git a/spec/frontend/registry/explorer/components/list_page/cli_commands_spec.js b/spec/frontend/registry/explorer/components/list_page/cli_commands_spec.js
new file mode 100644
index 00000000000..a556be12089
--- /dev/null
+++ b/spec/frontend/registry/explorer/components/list_page/cli_commands_spec.js
@@ -0,0 +1,120 @@
+import Vuex from 'vuex';
+import { mount, createLocalVue } from '@vue/test-utils';
+import { GlDropdown, GlFormGroup, GlFormInputGroup } from '@gitlab/ui';
+import Tracking from '~/tracking';
+import * as getters from '~/registry/explorer/stores/getters';
+import QuickstartDropdown from '~/registry/explorer/components/list_page/cli_commands.vue';
+import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
+
+import {
+ QUICK_START,
+ LOGIN_COMMAND_LABEL,
+ COPY_LOGIN_TITLE,
+ BUILD_COMMAND_LABEL,
+ COPY_BUILD_TITLE,
+ PUSH_COMMAND_LABEL,
+ COPY_PUSH_TITLE,
+} from '~/registry/explorer//constants';
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+describe('cli_commands', () => {
+ let wrapper;
+ let store;
+
+ const findDropdownButton = () => wrapper.find(GlDropdown);
+ const findFormGroups = () => wrapper.findAll(GlFormGroup);
+
+ const mountComponent = () => {
+ store = new Vuex.Store({
+ state: {
+ config: {
+ repositoryUrl: 'foo',
+ registryHostUrlWithPort: 'bar',
+ },
+ },
+ getters,
+ });
+ wrapper = mount(QuickstartDropdown, {
+ localVue,
+ store,
+ });
+ };
+
+ beforeEach(() => {
+ jest.spyOn(Tracking, 'event');
+ mountComponent();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ store = null;
+ });
+
+ it('shows the correct text on the button', () => {
+ expect(findDropdownButton().text()).toContain(QUICK_START);
+ });
+
+ it('clicking on the dropdown emit a tracking event', () => {
+ findDropdownButton().vm.$emit('shown');
+ expect(Tracking.event).toHaveBeenCalledWith(
+ undefined,
+ 'click_dropdown',
+ expect.objectContaining({ label: 'quickstart_dropdown' }),
+ );
+ });
+
+ describe.each`
+ index | id | labelText | titleText | getter | trackedEvent
+ ${0} | ${'docker-login-btn'} | ${LOGIN_COMMAND_LABEL} | ${COPY_LOGIN_TITLE} | ${'dockerLoginCommand'} | ${'click_copy_login'}
+ ${1} | ${'docker-build-btn'} | ${BUILD_COMMAND_LABEL} | ${COPY_BUILD_TITLE} | ${'dockerBuildCommand'} | ${'click_copy_build'}
+ ${2} | ${'docker-push-btn'} | ${PUSH_COMMAND_LABEL} | ${COPY_PUSH_TITLE} | ${'dockerPushCommand'} | ${'click_copy_push'}
+ `('form group at $index', ({ index, id, labelText, titleText, getter, trackedEvent }) => {
+ let formGroup;
+
+ const findFormInputGroup = parent => parent.find(GlFormInputGroup);
+ const findClipboardButton = parent => parent.find(ClipboardButton);
+
+ beforeEach(() => {
+ formGroup = findFormGroups().at(index);
+ });
+
+ it('exists', () => {
+ expect(formGroup.exists()).toBe(true);
+ });
+
+ it(`has a label ${labelText}`, () => {
+ expect(formGroup.text()).toBe(labelText);
+ });
+
+ it(`contains a form input group with ${id} id and with value equal to ${getter} getter`, () => {
+ const formInputGroup = findFormInputGroup(formGroup);
+ expect(formInputGroup.exists()).toBe(true);
+ expect(formInputGroup.attributes('id')).toBe(id);
+ expect(formInputGroup.props('value')).toBe(store.getters[getter]);
+ });
+
+ it(`contains a clipboard button with title of ${titleText} and text equal to ${getter} getter`, () => {
+ const clipBoardButton = findClipboardButton(formGroup);
+ expect(clipBoardButton.exists()).toBe(true);
+ expect(clipBoardButton.props('title')).toBe(titleText);
+ expect(clipBoardButton.props('text')).toBe(store.getters[getter]);
+ });
+
+ it('clipboard button tracks click event', () => {
+ const clipBoardButton = findClipboardButton(formGroup);
+ clipBoardButton.trigger('click');
+ /* This expect to be called with first argument undefined so that
+ * the function internally can default to document.body.dataset.page
+ * https://docs.gitlab.com/ee/telemetry/frontend.html#tracking-within-vue-components
+ */
+ expect(Tracking.event).toHaveBeenCalledWith(
+ undefined,
+ trackedEvent,
+ expect.objectContaining({ label: 'quickstart_dropdown' }),
+ );
+ });
+ });
+});
diff --git a/spec/frontend/registry/explorer/components/list_page/group_empty_state_spec.js b/spec/frontend/registry/explorer/components/list_page/group_empty_state_spec.js
new file mode 100644
index 00000000000..2f51e875672
--- /dev/null
+++ b/spec/frontend/registry/explorer/components/list_page/group_empty_state_spec.js
@@ -0,0 +1,40 @@
+import Vuex from 'vuex';
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import { GlSprintf } from '@gitlab/ui';
+import { GlEmptyState } from '../../stubs';
+import groupEmptyState from '~/registry/explorer/components/list_page/group_empty_state.vue';
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+describe('Registry Group Empty state', () => {
+ let wrapper;
+ let store;
+
+ beforeEach(() => {
+ store = new Vuex.Store({
+ state: {
+ config: {
+ noContainersImage: 'foo',
+ helpPagePath: 'baz',
+ },
+ },
+ });
+ wrapper = shallowMount(groupEmptyState, {
+ localVue,
+ store,
+ stubs: {
+ GlEmptyState,
+ GlSprintf,
+ },
+ });
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('to match the default snapshot', () => {
+ expect(wrapper.element).toMatchSnapshot();
+ });
+});
diff --git a/spec/frontend/registry/explorer/components/list_page/image_list_row_spec.js b/spec/frontend/registry/explorer/components/list_page/image_list_row_spec.js
new file mode 100644
index 00000000000..78de35ae1dc
--- /dev/null
+++ b/spec/frontend/registry/explorer/components/list_page/image_list_row_spec.js
@@ -0,0 +1,140 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlIcon, GlSprintf } from '@gitlab/ui';
+import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
+import Component from '~/registry/explorer/components/list_page/image_list_row.vue';
+import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
+import {
+ ROW_SCHEDULED_FOR_DELETION,
+ LIST_DELETE_BUTTON_DISABLED,
+} from '~/registry/explorer/constants';
+import { RouterLink } from '../../stubs';
+import { imagesListResponse } from '../../mock_data';
+
+describe('Image List Row', () => {
+ let wrapper;
+ const item = imagesListResponse.data[0];
+ const findDeleteBtn = () => wrapper.find('[data-testid="deleteImageButton"]');
+ const findDetailsLink = () => wrapper.find('[data-testid="detailsLink"]');
+ const findTagsCount = () => wrapper.find('[data-testid="tagsCount"]');
+ const findDeleteButtonWrapper = () => wrapper.find('[data-testid="deleteButtonWrapper"]');
+ const findClipboardButton = () => wrapper.find(ClipboardButton);
+
+ const mountComponent = props => {
+ wrapper = shallowMount(Component, {
+ stubs: {
+ RouterLink,
+ GlSprintf,
+ },
+ propsData: {
+ item,
+ ...props,
+ },
+ directives: {
+ GlTooltip: createMockDirective(),
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ describe('main tooltip', () => {
+ it(`the title is ${ROW_SCHEDULED_FOR_DELETION}`, () => {
+ mountComponent();
+ const tooltip = getBinding(wrapper.element, 'gl-tooltip');
+ expect(tooltip).toBeDefined();
+ expect(tooltip.value.title).toBe(ROW_SCHEDULED_FOR_DELETION);
+ });
+
+ it('is disabled when item is being deleted', () => {
+ mountComponent({ item: { ...item, deleting: true } });
+ const tooltip = getBinding(wrapper.element, 'gl-tooltip');
+ expect(tooltip.value.disabled).toBe(false);
+ });
+ });
+
+ describe('image title and path', () => {
+ it('contains a link to the details page', () => {
+ mountComponent();
+ const link = findDetailsLink();
+ expect(link.html()).toContain(item.path);
+ expect(link.props('to').name).toBe('details');
+ });
+
+ it('contains a clipboard button', () => {
+ mountComponent();
+ const button = findClipboardButton();
+ expect(button.exists()).toBe(true);
+ expect(button.props('text')).toBe(item.location);
+ expect(button.props('title')).toBe(item.location);
+ });
+ });
+
+ describe('delete button wrapper', () => {
+ it('has a tooltip', () => {
+ mountComponent();
+ const tooltip = getBinding(findDeleteButtonWrapper().element, 'gl-tooltip');
+ expect(tooltip).toBeDefined();
+ expect(tooltip.value.title).toBe(LIST_DELETE_BUTTON_DISABLED);
+ });
+ it('tooltip is enabled when destroy_path is falsy', () => {
+ mountComponent({ item: { ...item, destroy_path: null } });
+ const tooltip = getBinding(findDeleteButtonWrapper().element, 'gl-tooltip');
+ expect(tooltip.value.disabled).toBeFalsy();
+ });
+ });
+
+ describe('delete button', () => {
+ it('exists', () => {
+ mountComponent();
+ expect(findDeleteBtn().exists()).toBe(true);
+ });
+
+ it('emits a delete event', () => {
+ mountComponent();
+ findDeleteBtn().vm.$emit('click');
+ expect(wrapper.emitted('delete')).toEqual([[item]]);
+ });
+
+ it.each`
+ destroy_path | deleting | state
+ ${null} | ${null} | ${'true'}
+ ${null} | ${true} | ${'true'}
+ ${'foo'} | ${true} | ${'true'}
+ ${'foo'} | ${false} | ${undefined}
+ `(
+ 'disabled is $state when destroy_path is $destroy_path and deleting is $deleting',
+ ({ destroy_path, deleting, state }) => {
+ mountComponent({ item: { ...item, destroy_path, deleting } });
+ expect(findDeleteBtn().attributes('disabled')).toBe(state);
+ },
+ );
+ });
+
+ describe('tags count', () => {
+ it('exists', () => {
+ mountComponent();
+ expect(findTagsCount().exists()).toBe(true);
+ });
+
+ it('contains a tag icon', () => {
+ mountComponent();
+ const icon = findTagsCount().find(GlIcon);
+ expect(icon.exists()).toBe(true);
+ expect(icon.props('name')).toBe('tag');
+ });
+
+ describe('tags count text', () => {
+ it('with one tag in the image', () => {
+ mountComponent({ item: { ...item, tags_count: 1 } });
+ expect(findTagsCount().text()).toMatchInterpolatedText('1 Tag');
+ });
+ it('with more than one tag in the image', () => {
+ mountComponent({ item: { ...item, tags_count: 3 } });
+ expect(findTagsCount().text()).toMatchInterpolatedText('3 Tags');
+ });
+ });
+ });
+});
diff --git a/spec/frontend/registry/explorer/components/list_page/image_list_spec.js b/spec/frontend/registry/explorer/components/list_page/image_list_spec.js
new file mode 100644
index 00000000000..03ba6ad7f80
--- /dev/null
+++ b/spec/frontend/registry/explorer/components/list_page/image_list_spec.js
@@ -0,0 +1,62 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlPagination } from '@gitlab/ui';
+import Component from '~/registry/explorer/components/list_page/image_list.vue';
+import ImageListRow from '~/registry/explorer/components/list_page/image_list_row.vue';
+
+import { imagesListResponse, imagePagination } from '../../mock_data';
+
+describe('Image List', () => {
+ let wrapper;
+
+ const findRow = () => wrapper.findAll(ImageListRow);
+ const findPagination = () => wrapper.find(GlPagination);
+
+ const mountComponent = () => {
+ wrapper = shallowMount(Component, {
+ propsData: {
+ images: imagesListResponse.data,
+ pagination: imagePagination,
+ },
+ });
+ };
+
+ beforeEach(() => {
+ mountComponent();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ describe('list', () => {
+ it('contains one list element for each image', () => {
+ expect(findRow().length).toBe(imagesListResponse.data.length);
+ });
+
+ it('when delete event is emitted on the row it emits up a delete event', () => {
+ findRow()
+ .at(0)
+ .vm.$emit('delete', 'foo');
+ expect(wrapper.emitted('delete')).toEqual([['foo']]);
+ });
+ });
+
+ describe('pagination', () => {
+ it('exists', () => {
+ expect(findPagination().exists()).toBe(true);
+ });
+
+ it('is wired to the correct pagination props', () => {
+ const pagination = findPagination();
+ expect(pagination.props('perPage')).toBe(imagePagination.perPage);
+ expect(pagination.props('totalItems')).toBe(imagePagination.total);
+ expect(pagination.props('value')).toBe(imagePagination.page);
+ });
+
+ it('emits a pageChange event when the page change', () => {
+ findPagination().vm.$emit(GlPagination.model.event, 2);
+ expect(wrapper.emitted('pageChange')).toEqual([[2]]);
+ });
+ });
+});
diff --git a/spec/frontend/registry/explorer/components/list_page/project_empty_state_spec.js b/spec/frontend/registry/explorer/components/list_page/project_empty_state_spec.js
new file mode 100644
index 00000000000..73746c545cb
--- /dev/null
+++ b/spec/frontend/registry/explorer/components/list_page/project_empty_state_spec.js
@@ -0,0 +1,46 @@
+import Vuex from 'vuex';
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import { GlSprintf } from '@gitlab/ui';
+import { GlEmptyState } from '../../stubs';
+import projectEmptyState from '~/registry/explorer/components/list_page/project_empty_state.vue';
+import * as getters from '~/registry/explorer/stores/getters';
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+describe('Registry Project Empty state', () => {
+ let wrapper;
+ let store;
+
+ beforeEach(() => {
+ store = new Vuex.Store({
+ state: {
+ config: {
+ repositoryUrl: 'foo',
+ registryHostUrlWithPort: 'bar',
+ helpPagePath: 'baz',
+ twoFactorAuthHelpLink: 'barBaz',
+ personalAccessTokensHelpLink: 'fooBaz',
+ noContainersImage: 'bazFoo',
+ },
+ },
+ getters,
+ });
+ wrapper = shallowMount(projectEmptyState, {
+ localVue,
+ store,
+ stubs: {
+ GlEmptyState,
+ GlSprintf,
+ },
+ });
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('to match the default snapshot', () => {
+ expect(wrapper.element).toMatchSnapshot();
+ });
+});
diff --git a/spec/frontend/registry/explorer/components/list_page/registry_header_spec.js b/spec/frontend/registry/explorer/components/list_page/registry_header_spec.js
new file mode 100644
index 00000000000..7484fccbea7
--- /dev/null
+++ b/spec/frontend/registry/explorer/components/list_page/registry_header_spec.js
@@ -0,0 +1,221 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlSprintf, GlLink } from '@gitlab/ui';
+import Component from '~/registry/explorer/components/list_page/registry_header.vue';
+import {
+ CONTAINER_REGISTRY_TITLE,
+ LIST_INTRO_TEXT,
+ EXPIRATION_POLICY_DISABLED_MESSAGE,
+ EXPIRATION_POLICY_DISABLED_TEXT,
+ EXPIRATION_POLICY_WILL_RUN_IN,
+} from '~/registry/explorer/constants';
+
+jest.mock('~/lib/utils/datetime_utility', () => ({
+ approximateDuration: jest.fn(),
+ calculateRemainingMilliseconds: jest.fn(),
+}));
+
+describe('registry_header', () => {
+ let wrapper;
+
+ const findHeader = () => wrapper.find('[data-testid="header"]');
+ const findTitle = () => wrapper.find('[data-testid="title"]');
+ const findCommandsSlot = () => wrapper.find('[data-testid="commands-slot"]');
+ const findInfoArea = () => wrapper.find('[data-testid="info-area"]');
+ const findIntroText = () => wrapper.find('[data-testid="default-intro"]');
+ const findSubHeader = () => wrapper.find('[data-testid="subheader"]');
+ const findImagesCountSubHeader = () => wrapper.find('[data-testid="images-count"]');
+ const findExpirationPolicySubHeader = () => wrapper.find('[data-testid="expiration-policy"]');
+ const findDisabledExpirationPolicyMessage = () =>
+ wrapper.find('[data-testid="expiration-disabled-message"]');
+
+ const mountComponent = (propsData, slots) => {
+ wrapper = shallowMount(Component, {
+ stubs: {
+ GlSprintf,
+ },
+ propsData,
+ slots,
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ describe('header', () => {
+ it('exists', () => {
+ mountComponent();
+ expect(findHeader().exists()).toBe(true);
+ });
+
+ it('contains the title of the page', () => {
+ mountComponent();
+ const title = findTitle();
+ expect(title.exists()).toBe(true);
+ expect(title.text()).toBe(CONTAINER_REGISTRY_TITLE);
+ });
+
+ it('has a commands slot', () => {
+ mountComponent(null, { commands: 'baz' });
+ expect(findCommandsSlot().text()).toBe('baz');
+ });
+ });
+
+ describe('subheader', () => {
+ describe('when there are no images', () => {
+ it('is hidden ', () => {
+ mountComponent();
+ expect(findSubHeader().exists()).toBe(false);
+ });
+ });
+
+ describe('when there are images', () => {
+ it('is visible', () => {
+ mountComponent({ imagesCount: 1 });
+ expect(findSubHeader().exists()).toBe(true);
+ });
+
+ describe('sub header parts', () => {
+ describe('images count', () => {
+ it('exists', () => {
+ mountComponent({ imagesCount: 1 });
+ expect(findImagesCountSubHeader().exists()).toBe(true);
+ });
+
+ it('when there is one image', () => {
+ mountComponent({ imagesCount: 1 });
+ expect(findImagesCountSubHeader().text()).toMatchInterpolatedText('1 Image repository');
+ });
+
+ it('when there is more than one image', () => {
+ mountComponent({ imagesCount: 3 });
+ expect(findImagesCountSubHeader().text()).toMatchInterpolatedText(
+ '3 Image repositories',
+ );
+ });
+ });
+
+ describe('expiration policy', () => {
+ it('when is disabled', () => {
+ mountComponent({
+ expirationPolicy: { enabled: false },
+ expirationPolicyHelpPagePath: 'foo',
+ imagesCount: 1,
+ });
+ const text = findExpirationPolicySubHeader();
+ expect(text.exists()).toBe(true);
+ expect(text.text()).toMatchInterpolatedText(EXPIRATION_POLICY_DISABLED_TEXT);
+ });
+
+ it('when is enabled', () => {
+ mountComponent({
+ expirationPolicy: { enabled: true },
+ expirationPolicyHelpPagePath: 'foo',
+ imagesCount: 1,
+ });
+ const text = findExpirationPolicySubHeader();
+ expect(text.exists()).toBe(true);
+ expect(text.text()).toMatchInterpolatedText(EXPIRATION_POLICY_WILL_RUN_IN);
+ });
+ it('when the expiration policy is completely disabled', () => {
+ mountComponent({
+ expirationPolicy: { enabled: true },
+ expirationPolicyHelpPagePath: 'foo',
+ imagesCount: 1,
+ hideExpirationPolicyData: true,
+ });
+ const text = findExpirationPolicySubHeader();
+ expect(text.exists()).toBe(false);
+ });
+ });
+ });
+ });
+ });
+
+ describe('info area', () => {
+ it('exists', () => {
+ mountComponent();
+ expect(findInfoArea().exists()).toBe(true);
+ });
+
+ describe('default message', () => {
+ beforeEach(() => {
+ mountComponent({ helpPagePath: 'bar' });
+ });
+
+ it('exists', () => {
+ expect(findIntroText().exists()).toBe(true);
+ });
+
+ it('has the correct copy', () => {
+ expect(findIntroText().text()).toMatchInterpolatedText(LIST_INTRO_TEXT);
+ });
+
+ it('has the correct link', () => {
+ expect(
+ findIntroText()
+ .find(GlLink)
+ .attributes('href'),
+ ).toBe('bar');
+ });
+ });
+
+ describe('expiration policy info message', () => {
+ describe('when there are no images', () => {
+ it('is hidden', () => {
+ mountComponent();
+ expect(findDisabledExpirationPolicyMessage().exists()).toBe(false);
+ });
+ });
+
+ describe('when there are images', () => {
+ describe('when expiration policy is disabled', () => {
+ beforeEach(() => {
+ mountComponent({
+ expirationPolicy: { enabled: false },
+ expirationPolicyHelpPagePath: 'foo',
+ imagesCount: 1,
+ });
+ });
+ it('message exist', () => {
+ expect(findDisabledExpirationPolicyMessage().exists()).toBe(true);
+ });
+ it('has the correct copy', () => {
+ expect(findDisabledExpirationPolicyMessage().text()).toMatchInterpolatedText(
+ EXPIRATION_POLICY_DISABLED_MESSAGE,
+ );
+ });
+
+ it('has the correct link', () => {
+ expect(
+ findDisabledExpirationPolicyMessage()
+ .find(GlLink)
+ .attributes('href'),
+ ).toBe('foo');
+ });
+ });
+
+ describe('when expiration policy is enabled', () => {
+ it('message does not exist', () => {
+ mountComponent({
+ expirationPolicy: { enabled: true },
+ imagesCount: 1,
+ });
+ expect(findDisabledExpirationPolicyMessage().exists()).toBe(false);
+ });
+ });
+ describe('when the expiration policy is completely disabled', () => {
+ it('message does not exist', () => {
+ mountComponent({
+ expirationPolicy: { enabled: true },
+ imagesCount: 1,
+ hideExpirationPolicyData: true,
+ });
+ expect(findDisabledExpirationPolicyMessage().exists()).toBe(false);
+ });
+ });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/registry/explorer/components/project_empty_state_spec.js b/spec/frontend/registry/explorer/components/project_empty_state_spec.js
deleted file mode 100644
index 4b209646da9..00000000000
--- a/spec/frontend/registry/explorer/components/project_empty_state_spec.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import Vuex from 'vuex';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
-import { GlSprintf } from '@gitlab/ui';
-import { GlEmptyState } from '../stubs';
-import projectEmptyState from '~/registry/explorer/components/project_empty_state.vue';
-import * as getters from '~/registry/explorer/stores/getters';
-
-const localVue = createLocalVue();
-localVue.use(Vuex);
-
-describe('Registry Project Empty state', () => {
- let wrapper;
- let store;
-
- beforeEach(() => {
- store = new Vuex.Store({
- state: {
- config: {
- repositoryUrl: 'foo',
- registryHostUrlWithPort: 'bar',
- helpPagePath: 'baz',
- twoFactorAuthHelpLink: 'barBaz',
- personalAccessTokensHelpLink: 'fooBaz',
- noContainersImage: 'bazFoo',
- },
- },
- getters,
- });
- wrapper = shallowMount(projectEmptyState, {
- localVue,
- store,
- stubs: {
- GlEmptyState,
- GlSprintf,
- },
- });
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- it('to match the default snapshot', () => {
- expect(wrapper.element).toMatchSnapshot();
- });
-});
diff --git a/spec/frontend/registry/explorer/components/project_policy_alert_spec.js b/spec/frontend/registry/explorer/components/project_policy_alert_spec.js
deleted file mode 100644
index 89c37e55398..00000000000
--- a/spec/frontend/registry/explorer/components/project_policy_alert_spec.js
+++ /dev/null
@@ -1,132 +0,0 @@
-import Vuex from 'vuex';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
-import { GlSprintf, GlAlert, GlLink } from '@gitlab/ui';
-import * as dateTimeUtils from '~/lib/utils/datetime_utility';
-import component from '~/registry/explorer/components/project_policy_alert.vue';
-import {
- EXPIRATION_POLICY_ALERT_TITLE,
- EXPIRATION_POLICY_ALERT_PRIMARY_BUTTON,
-} from '~/registry/explorer/constants';
-
-const localVue = createLocalVue();
-localVue.use(Vuex);
-
-describe('Project Policy Alert', () => {
- let wrapper;
- let store;
-
- const defaultState = {
- config: {
- expirationPolicy: {
- enabled: true,
- },
- settingsPath: 'foo',
- expirationPolicyHelpPagePath: 'bar',
- },
- images: [],
- isLoading: false,
- };
-
- const findAlert = () => wrapper.find(GlAlert);
- const findLink = () => wrapper.find(GlLink);
-
- const createComponent = (state = defaultState) => {
- store = new Vuex.Store({
- state,
- });
- wrapper = shallowMount(component, {
- localVue,
- store,
- stubs: {
- GlSprintf,
- },
- });
- };
-
- const documentationExpectation = () => {
- it('contain a documentation link', () => {
- createComponent();
- expect(findLink().attributes('href')).toBe(defaultState.config.expirationPolicyHelpPagePath);
- expect(findLink().text()).toBe('documentation');
- });
- };
-
- beforeEach(() => {
- jest.spyOn(dateTimeUtils, 'approximateDuration').mockReturnValue('1 day');
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- describe('is hidden', () => {
- it('when expiration policy does not exist', () => {
- createComponent({ config: {} });
- expect(findAlert().exists()).toBe(false);
- });
-
- it('when expiration policy exist but is disabled', () => {
- createComponent({
- ...defaultState,
- config: {
- expirationPolicy: {
- enabled: false,
- },
- },
- });
- expect(findAlert().exists()).toBe(false);
- });
- });
-
- describe('is visible', () => {
- it('when expiration policy exists and is enabled', () => {
- createComponent();
- expect(findAlert().exists()).toBe(true);
- });
- });
-
- describe('full info alert', () => {
- beforeEach(() => {
- createComponent({ ...defaultState, images: [1] });
- });
-
- it('has a primary button', () => {
- const alert = findAlert();
- expect(alert.props('primaryButtonText')).toBe(EXPIRATION_POLICY_ALERT_PRIMARY_BUTTON);
- expect(alert.props('primaryButtonLink')).toBe(defaultState.config.settingsPath);
- });
-
- it('has a title', () => {
- const alert = findAlert();
- expect(alert.props('title')).toBe(EXPIRATION_POLICY_ALERT_TITLE);
- });
-
- it('has the full message', () => {
- expect(findAlert().html()).toContain('<strong>1 day</strong>');
- });
-
- documentationExpectation();
- });
-
- describe('compact info alert', () => {
- beforeEach(() => {
- createComponent({ ...defaultState, images: [] });
- });
-
- it('does not have a button', () => {
- const alert = findAlert();
- expect(alert.props('primaryButtonText')).toBe(null);
- });
-
- it('does not have a title', () => {
- const alert = findAlert();
- expect(alert.props('title')).toBe(null);
- });
-
- it('has the short message', () => {
- expect(findAlert().html()).not.toContain('<strong>1 day</strong>');
- });
-
- documentationExpectation();
- });
-});
diff --git a/spec/frontend/registry/explorer/components/quickstart_dropdown_spec.js b/spec/frontend/registry/explorer/components/quickstart_dropdown_spec.js
deleted file mode 100644
index 0c3baefbc58..00000000000
--- a/spec/frontend/registry/explorer/components/quickstart_dropdown_spec.js
+++ /dev/null
@@ -1,120 +0,0 @@
-import Vuex from 'vuex';
-import { mount, createLocalVue } from '@vue/test-utils';
-import { GlDropdown, GlFormGroup, GlFormInputGroup } from '@gitlab/ui';
-import Tracking from '~/tracking';
-import * as getters from '~/registry/explorer/stores/getters';
-import QuickstartDropdown from '~/registry/explorer/components/quickstart_dropdown.vue';
-import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
-
-import {
- QUICK_START,
- LOGIN_COMMAND_LABEL,
- COPY_LOGIN_TITLE,
- BUILD_COMMAND_LABEL,
- COPY_BUILD_TITLE,
- PUSH_COMMAND_LABEL,
- COPY_PUSH_TITLE,
-} from '~/registry/explorer//constants';
-
-const localVue = createLocalVue();
-localVue.use(Vuex);
-
-describe('quickstart_dropdown', () => {
- let wrapper;
- let store;
-
- const findDropdownButton = () => wrapper.find(GlDropdown);
- const findFormGroups = () => wrapper.findAll(GlFormGroup);
-
- const mountComponent = () => {
- store = new Vuex.Store({
- state: {
- config: {
- repositoryUrl: 'foo',
- registryHostUrlWithPort: 'bar',
- },
- },
- getters,
- });
- wrapper = mount(QuickstartDropdown, {
- localVue,
- store,
- });
- };
-
- beforeEach(() => {
- jest.spyOn(Tracking, 'event');
- mountComponent();
- });
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- store = null;
- });
-
- it('shows the correct text on the button', () => {
- expect(findDropdownButton().text()).toContain(QUICK_START);
- });
-
- it('clicking on the dropdown emit a tracking event', () => {
- findDropdownButton().vm.$emit('shown');
- expect(Tracking.event).toHaveBeenCalledWith(
- undefined,
- 'click_dropdown',
- expect.objectContaining({ label: 'quickstart_dropdown' }),
- );
- });
-
- describe.each`
- index | id | labelText | titleText | getter | trackedEvent
- ${0} | ${'docker-login-btn'} | ${LOGIN_COMMAND_LABEL} | ${COPY_LOGIN_TITLE} | ${'dockerLoginCommand'} | ${'click_copy_login'}
- ${1} | ${'docker-build-btn'} | ${BUILD_COMMAND_LABEL} | ${COPY_BUILD_TITLE} | ${'dockerBuildCommand'} | ${'click_copy_build'}
- ${2} | ${'docker-push-btn'} | ${PUSH_COMMAND_LABEL} | ${COPY_PUSH_TITLE} | ${'dockerPushCommand'} | ${'click_copy_push'}
- `('form group at $index', ({ index, id, labelText, titleText, getter, trackedEvent }) => {
- let formGroup;
-
- const findFormInputGroup = parent => parent.find(GlFormInputGroup);
- const findClipboardButton = parent => parent.find(ClipboardButton);
-
- beforeEach(() => {
- formGroup = findFormGroups().at(index);
- });
-
- it('exists', () => {
- expect(formGroup.exists()).toBe(true);
- });
-
- it(`has a label ${labelText}`, () => {
- expect(formGroup.text()).toBe(labelText);
- });
-
- it(`contains a form input group with ${id} id and with value equal to ${getter} getter`, () => {
- const formInputGroup = findFormInputGroup(formGroup);
- expect(formInputGroup.exists()).toBe(true);
- expect(formInputGroup.attributes('id')).toBe(id);
- expect(formInputGroup.props('value')).toBe(store.getters[getter]);
- });
-
- it(`contains a clipboard button with title of ${titleText} and text equal to ${getter} getter`, () => {
- const clipBoardButton = findClipboardButton(formGroup);
- expect(clipBoardButton.exists()).toBe(true);
- expect(clipBoardButton.props('title')).toBe(titleText);
- expect(clipBoardButton.props('text')).toBe(store.getters[getter]);
- });
-
- it('clipboard button tracks click event', () => {
- const clipBoardButton = findClipboardButton(formGroup);
- clipBoardButton.trigger('click');
- /* This expect to be called with first argument undefined so that
- * the function internally can default to document.body.dataset.page
- * https://docs.gitlab.com/ee/telemetry/frontend.html#tracking-within-vue-components
- */
- expect(Tracking.event).toHaveBeenCalledWith(
- undefined,
- trackedEvent,
- expect.objectContaining({ label: 'quickstart_dropdown' }),
- );
- });
- });
-});
diff --git a/spec/frontend/registry/explorer/mock_data.js b/spec/frontend/registry/explorer/mock_data.js
index f6beccda9b1..e2b33826503 100644
--- a/spec/frontend/registry/explorer/mock_data.js
+++ b/spec/frontend/registry/explorer/mock_data.js
@@ -64,7 +64,7 @@ export const imagesListResponse = {
export const tagsListResponse = {
data: [
{
- tag: 'centos6',
+ name: 'centos6',
revision: 'b118ab5b0e90b7cb5127db31d5321ac14961d097516a8e0e72084b6cdc783b43',
short_revision: 'b118ab5b0',
size: 19,
@@ -75,7 +75,7 @@ export const tagsListResponse = {
destroy_path: 'path',
},
{
- tag: 'test-image',
+ name: 'test-tag',
revision: 'b969de599faea2b3d9b6605a8b0897261c571acaa36db1bdc7349b5775b4e0b4',
short_revision: 'b969de599',
size: 19,
diff --git a/spec/frontend/registry/explorer/pages/details_spec.js b/spec/frontend/registry/explorer/pages/details_spec.js
index 93098403a28..b7e01cad9bc 100644
--- a/spec/frontend/registry/explorer/pages/details_spec.js
+++ b/spec/frontend/registry/explorer/pages/details_spec.js
@@ -1,55 +1,43 @@
-import { mount } from '@vue/test-utils';
-import { GlTable, GlPagination, GlSkeletonLoader, GlAlert, GlLink } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import { GlPagination } from '@gitlab/ui';
import Tracking from '~/tracking';
-import stubChildren from 'helpers/stub_children';
import component from '~/registry/explorer/pages/details.vue';
+import DeleteAlert from '~/registry/explorer/components/details_page/delete_alert.vue';
+import DetailsHeader from '~/registry/explorer/components/details_page/details_header.vue';
+import TagsLoader from '~/registry/explorer/components/details_page/tags_loader.vue';
+import EmptyTagsState from '~/registry/explorer/components/details_page/empty_tags_state.vue';
import { createStore } from '~/registry/explorer/stores/';
import {
SET_MAIN_LOADING,
- SET_INITIAL_STATE,
SET_TAGS_LIST_SUCCESS,
SET_TAGS_PAGINATION,
+ SET_INITIAL_STATE,
} from '~/registry/explorer/stores/mutation_types/';
-import {
- DELETE_TAG_SUCCESS_MESSAGE,
- DELETE_TAG_ERROR_MESSAGE,
- DELETE_TAGS_SUCCESS_MESSAGE,
- DELETE_TAGS_ERROR_MESSAGE,
- ADMIN_GARBAGE_COLLECTION_TIP,
-} from '~/registry/explorer/constants';
+
import { tagsListResponse } from '../mock_data';
-import { GlModal } from '../stubs';
-import { $toast } from '../../shared/mocks';
+import { TagsTable, DeleteModal } from '../stubs';
describe('Details Page', () => {
let wrapper;
let dispatchSpy;
let store;
- const findDeleteModal = () => wrapper.find(GlModal);
+ const findDeleteModal = () => wrapper.find(DeleteModal);
const findPagination = () => wrapper.find(GlPagination);
- const findSkeletonLoader = () => wrapper.find(GlSkeletonLoader);
- const findMainCheckbox = () => wrapper.find({ ref: 'mainCheckbox' });
- const findFirstRowItem = ref => wrapper.find({ ref });
- const findBulkDeleteButton = () => wrapper.find({ ref: 'bulkDeleteButton' });
- // findAll and refs seems to no work falling back to class
- const findAllDeleteButtons = () => wrapper.findAll('.js-delete-registry');
- const findAllCheckboxes = () => wrapper.findAll('.js-row-checkbox');
- const findCheckedCheckboxes = () => findAllCheckboxes().filter(c => c.attributes('checked'));
- const findFirsTagColumn = () => wrapper.find('.js-tag-column');
- const findFirstTagNameText = () => wrapper.find('[data-testid="rowNameText"]');
- const findAlert = () => wrapper.find(GlAlert);
+ const findTagsLoader = () => wrapper.find(TagsLoader);
+ const findTagsTable = () => wrapper.find(TagsTable);
+ const findDeleteAlert = () => wrapper.find(DeleteAlert);
+ const findDetailsHeader = () => wrapper.find(DetailsHeader);
+ const findEmptyTagsState = () => wrapper.find(EmptyTagsState);
const routeId = window.btoa(JSON.stringify({ name: 'foo', tags_path: 'bar' }));
const mountComponent = options => {
- wrapper = mount(component, {
+ wrapper = shallowMount(component, {
store,
stubs: {
- ...stubChildren(component),
- GlModal,
- GlSprintf: false,
- GlTable,
+ TagsTable,
+ DeleteModal,
},
mocks: {
$route: {
@@ -57,7 +45,6 @@ describe('Details Page', () => {
id: routeId,
},
},
- $toast,
},
...options,
});
@@ -80,18 +67,14 @@ describe('Details Page', () => {
describe('when isLoading is true', () => {
beforeEach(() => {
mountComponent();
- store.dispatch('receiveTagsListSuccess', { ...tagsListResponse, data: [] });
store.commit(SET_MAIN_LOADING, true);
+ return wrapper.vm.$nextTick();
});
- afterAll(() => store.commit(SET_MAIN_LOADING, false));
+ afterEach(() => store.commit(SET_MAIN_LOADING, false));
- it('has a skeleton loader', () => {
- expect(findSkeletonLoader().exists()).toBe(true);
- });
-
- it('does not have list items', () => {
- expect(findFirstRowItem('rowCheckbox').exists()).toBe(false);
+ it('binds isLoading to tags-table', () => {
+ expect(findTagsTable().props('isLoading')).toBe(true);
});
it('does not show pagination', () => {
@@ -99,207 +82,76 @@ describe('Details Page', () => {
});
});
- describe('table', () => {
+ describe('table slots', () => {
beforeEach(() => {
mountComponent();
});
- it.each([
- 'rowCheckbox',
- 'rowName',
- 'rowShortRevision',
- 'rowSize',
- 'rowTime',
- 'singleDeleteButton',
- ])('%s exist in the table', element => {
- expect(findFirstRowItem(element).exists()).toBe(true);
+ it('has the empty state', () => {
+ expect(findEmptyTagsState().exists()).toBe(true);
});
- describe('header checkbox', () => {
- beforeEach(() => {
- mountComponent();
- });
-
- it('exists', () => {
- expect(findMainCheckbox().exists()).toBe(true);
- });
-
- it('if selected set selectedItem and allSelected', () => {
- findMainCheckbox().vm.$emit('change');
- return wrapper.vm.$nextTick().then(() => {
- expect(findMainCheckbox().attributes('checked')).toBeTruthy();
- expect(findCheckedCheckboxes()).toHaveLength(store.state.tags.length);
- });
- });
-
- it('if deselect unset selectedItem and allSelected', () => {
- wrapper.setData({ selectedItems: [1, 2], selectAllChecked: true });
- findMainCheckbox().vm.$emit('change');
- return wrapper.vm.$nextTick().then(() => {
- expect(findMainCheckbox().attributes('checked')).toBe(undefined);
- expect(findCheckedCheckboxes()).toHaveLength(0);
- });
- });
+ it('has a skeleton loader', () => {
+ expect(findTagsLoader().exists()).toBe(true);
});
+ });
- describe('row checkbox', () => {
- it('if selected adds item to selectedItems', () => {
- findFirstRowItem('rowCheckbox').vm.$emit('change');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.vm.selectedItems).toEqual([1]);
- expect(findFirstRowItem('rowCheckbox').attributes('checked')).toBeTruthy();
- });
- });
-
- it('if deselect remove index from selectedItems', () => {
- wrapper.setData({ selectedItems: [1] });
- findFirstRowItem('rowCheckbox').vm.$emit('change');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.vm.selectedItems.length).toBe(0);
- expect(findFirstRowItem('rowCheckbox').attributes('checked')).toBe(undefined);
- });
- });
+ describe('table', () => {
+ beforeEach(() => {
+ mountComponent();
});
- describe('header delete button', () => {
- beforeEach(() => {
- mountComponent();
- });
-
- it('exists', () => {
- expect(findBulkDeleteButton().exists()).toBe(true);
- });
+ it('exists', () => {
+ expect(findTagsTable().exists()).toBe(true);
+ });
- it('is disabled if no item is selected', () => {
- expect(findBulkDeleteButton().attributes('disabled')).toBe('true');
+ it('has the correct props bound', () => {
+ expect(findTagsTable().props()).toMatchObject({
+ isDesktop: true,
+ isLoading: false,
+ tags: store.state.tags,
});
+ });
- it('is enabled if at least one item is selected', () => {
- wrapper.setData({ selectedItems: [1] });
- return wrapper.vm.$nextTick().then(() => {
- expect(findBulkDeleteButton().attributes('disabled')).toBeFalsy();
+ describe('deleteEvent', () => {
+ describe('single item', () => {
+ beforeEach(() => {
+ findTagsTable().vm.$emit('delete', [store.state.tags[0].name]);
});
- });
- describe('on click', () => {
- it('when one item is selected', () => {
- wrapper.setData({ selectedItems: [1] });
- findBulkDeleteButton().vm.$emit('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(findDeleteModal().html()).toContain(
- 'You are about to remove <b>foo</b>. Are you sure?',
- );
- expect(GlModal.methods.show).toHaveBeenCalled();
- expect(Tracking.event).toHaveBeenCalledWith(undefined, 'click_button', {
- label: 'registry_tag_delete',
- });
- });
+ it('open the modal', () => {
+ expect(DeleteModal.methods.show).toHaveBeenCalled();
});
- it('when multiple items are selected', () => {
- wrapper.setData({ selectedItems: [0, 1] });
- findBulkDeleteButton().vm.$emit('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(findDeleteModal().html()).toContain(
- 'You are about to remove <b>2</b> tags. Are you sure?',
- );
- expect(GlModal.methods.show).toHaveBeenCalled();
- expect(Tracking.event).toHaveBeenCalledWith(undefined, 'click_button', {
- label: 'bulk_registry_tag_delete',
- });
- });
+ it('maps the selection to itemToBeDeleted', () => {
+ expect(wrapper.vm.itemsToBeDeleted).toEqual([store.state.tags[0]]);
});
- });
- });
- describe('row delete button', () => {
- beforeEach(() => {
- mountComponent();
- });
-
- it('exists', () => {
- expect(
- findAllDeleteButtons()
- .at(0)
- .exists(),
- ).toBe(true);
- });
-
- it('is disabled if the item has no destroy_path', () => {
- expect(
- findAllDeleteButtons()
- .at(1)
- .attributes('disabled'),
- ).toBe('true');
- });
-
- it('on click', () => {
- findAllDeleteButtons()
- .at(0)
- .vm.$emit('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(findDeleteModal().html()).toContain(
- 'You are about to remove <b>bar</b>. Are you sure?',
- );
- expect(GlModal.methods.show).toHaveBeenCalled();
+ it('tracks a single delete event', () => {
expect(Tracking.event).toHaveBeenCalledWith(undefined, 'click_button', {
label: 'registry_tag_delete',
});
});
});
- });
-
- describe('name cell', () => {
- it('tag column has a tooltip with the tag name', () => {
- mountComponent();
- expect(findFirstTagNameText().attributes('title')).toBe(tagsListResponse.data[0].name);
- });
- describe('on desktop viewport', () => {
+ describe('multiple items', () => {
beforeEach(() => {
- mountComponent();
+ findTagsTable().vm.$emit('delete', store.state.tags.map(t => t.name));
});
- it('table header has class w-25', () => {
- expect(findFirsTagColumn().classes()).toContain('w-25');
+ it('open the modal', () => {
+ expect(DeleteModal.methods.show).toHaveBeenCalled();
});
- it('tag column has the mw-m class', () => {
- expect(findFirstRowItem('rowName').classes()).toContain('mw-m');
+ it('maps the selection to itemToBeDeleted', () => {
+ expect(wrapper.vm.itemsToBeDeleted).toEqual(store.state.tags);
});
- });
- describe('on mobile viewport', () => {
- beforeEach(() => {
- mountComponent({
- data() {
- return { isDesktop: false };
- },
+ it('tracks a single delete event', () => {
+ expect(Tracking.event).toHaveBeenCalledWith(undefined, 'click_button', {
+ label: 'bulk_registry_tag_delete',
});
});
-
- it('table header does not have class w-25', () => {
- expect(findFirsTagColumn().classes()).not.toContain('w-25');
- });
-
- it('tag column has the gl-justify-content-end class', () => {
- expect(findFirstRowItem('rowName').classes()).toContain('gl-justify-content-end');
- });
- });
- });
-
- describe('last updated cell', () => {
- let timeCell;
-
- beforeEach(() => {
- timeCell = findFirstRowItem('rowTime');
- });
-
- it('displays the time in string format', () => {
- expect(timeCell.text()).toBe('2 years ago');
- });
- it('has a tooltip timestamp', () => {
- expect(timeCell.attributes('title')).toBe('Sep 19, 2017 1:45pm GMT+0000');
});
});
});
@@ -322,7 +174,7 @@ describe('Details Page', () => {
it('fetch the data from the API when the v-model changes', () => {
dispatchSpy.mockResolvedValue();
- wrapper.setData({ currentPage: 2 });
+ findPagination().vm.$emit(GlPagination.model.event, 2);
expect(store.dispatch).toHaveBeenCalledWith('requestTagsList', {
params: wrapper.vm.$route.params.id,
pagination: { page: 2 },
@@ -331,176 +183,86 @@ describe('Details Page', () => {
});
describe('modal', () => {
- beforeEach(() => {
- mountComponent();
- });
-
it('exists', () => {
+ mountComponent();
expect(findDeleteModal().exists()).toBe(true);
});
- describe('when ok event is emitted', () => {
- beforeEach(() => {
- dispatchSpy.mockResolvedValue();
- });
-
- it('tracks confirm_delete', () => {
- const deleteModal = findDeleteModal();
- deleteModal.vm.$emit('ok');
- return wrapper.vm.$nextTick().then(() => {
- expect(Tracking.event).toHaveBeenCalledWith(undefined, 'confirm_delete', {
- label: 'registry_tag_delete',
- });
+ describe('cancel event', () => {
+ it('tracks cancel_delete', () => {
+ mountComponent();
+ findDeleteModal().vm.$emit('cancel');
+ expect(Tracking.event).toHaveBeenCalledWith(undefined, 'cancel_delete', {
+ label: 'registry_tag_delete',
});
});
+ });
- describe('when only one element is selected', () => {
- it('execute the delete and remove selection', () => {
- wrapper.setData({ itemsToBeDeleted: [0] });
- findDeleteModal().vm.$emit('ok');
+ describe('confirmDelete event', () => {
+ describe('when one item is selected to be deleted', () => {
+ beforeEach(() => {
+ mountComponent();
+ findTagsTable().vm.$emit('delete', [store.state.tags[0].name]);
+ });
- expect(store.dispatch).toHaveBeenCalledWith('requestDeleteTag', {
+ it('dispatch requestDeleteTag with the right parameters', () => {
+ findDeleteModal().vm.$emit('confirmDelete');
+ expect(dispatchSpy).toHaveBeenCalledWith('requestDeleteTag', {
tag: store.state.tags[0],
- params: wrapper.vm.$route.params.id,
+ params: routeId,
});
- // itemsToBeDeleted is not represented in the DOM, is used as parking variable between selected and deleted items
- expect(wrapper.vm.itemsToBeDeleted).toEqual([]);
- expect(wrapper.vm.selectedItems).toEqual([]);
- expect(findCheckedCheckboxes()).toHaveLength(0);
});
});
- describe('when multiple elements are selected', () => {
+ describe('when more than one item is selected to be deleted', () => {
beforeEach(() => {
- wrapper.setData({ itemsToBeDeleted: [0, 1] });
+ mountComponent();
+ findTagsTable().vm.$emit('delete', store.state.tags.map(t => t.name));
});
- it('execute the delete and remove selection', () => {
- findDeleteModal().vm.$emit('ok');
-
- expect(store.dispatch).toHaveBeenCalledWith('requestDeleteTags', {
+ it('dispatch requestDeleteTags with the right parameters', () => {
+ findDeleteModal().vm.$emit('confirmDelete');
+ expect(dispatchSpy).toHaveBeenCalledWith('requestDeleteTags', {
ids: store.state.tags.map(t => t.name),
- params: wrapper.vm.$route.params.id,
+ params: routeId,
});
- // itemsToBeDeleted is not represented in the DOM, is used as parking variable between selected and deleted items
- expect(wrapper.vm.itemsToBeDeleted).toEqual([]);
- expect(findCheckedCheckboxes()).toHaveLength(0);
});
});
});
+ });
- it('tracks cancel_delete when cancel event is emitted', () => {
- const deleteModal = findDeleteModal();
- deleteModal.vm.$emit('cancel');
- return wrapper.vm.$nextTick().then(() => {
- expect(Tracking.event).toHaveBeenCalledWith(undefined, 'cancel_delete', {
- label: 'registry_tag_delete',
- });
- });
+ describe('Header', () => {
+ it('exists', () => {
+ mountComponent();
+ expect(findDetailsHeader().exists()).toBe(true);
+ });
+
+ it('has the correct props', () => {
+ mountComponent();
+ expect(findDetailsHeader().props()).toEqual({ imageName: 'foo' });
});
});
- describe('Delete alert', () => {
+ describe('Delete Alert', () => {
const config = {
- garbageCollectionHelpPagePath: 'foo',
+ isAdmin: true,
+ garbageCollectionHelpPagePath: 'baz',
};
+ const deleteAlertType = 'success_tag';
- describe('when the user is an admin', () => {
- beforeEach(() => {
- store.commit(SET_INITIAL_STATE, { ...config, isAdmin: true });
- });
-
- afterEach(() => {
- store.commit(SET_INITIAL_STATE, config);
- });
-
- describe.each`
- deleteType | successTitle | errorTitle
- ${'handleSingleDelete'} | ${DELETE_TAG_SUCCESS_MESSAGE} | ${DELETE_TAG_ERROR_MESSAGE}
- ${'handleMultipleDelete'} | ${DELETE_TAGS_SUCCESS_MESSAGE} | ${DELETE_TAGS_ERROR_MESSAGE}
- `('behaves correctly on $deleteType', ({ deleteType, successTitle, errorTitle }) => {
- describe('when delete is successful', () => {
- beforeEach(() => {
- dispatchSpy.mockResolvedValue();
- mountComponent();
- return wrapper.vm[deleteType]('foo');
- });
-
- it('alert exists', () => {
- expect(findAlert().exists()).toBe(true);
- });
-
- it('alert body contains admin tip', () => {
- expect(
- findAlert()
- .text()
- .replace(/\s\s+/gm, ' '),
- ).toBe(ADMIN_GARBAGE_COLLECTION_TIP.replace(/%{\w+}/gm, ''));
- });
-
- it('alert body contains link', () => {
- const alertLink = findAlert().find(GlLink);
- expect(alertLink.exists()).toBe(true);
- expect(alertLink.attributes('href')).toBe(config.garbageCollectionHelpPagePath);
- });
-
- it('alert title is appropriate', () => {
- expect(findAlert().attributes('title')).toBe(successTitle);
- });
- });
-
- describe('when delete is not successful', () => {
- beforeEach(() => {
- mountComponent();
- dispatchSpy.mockRejectedValue();
- return wrapper.vm[deleteType]('foo');
- });
+ it('exists', () => {
+ mountComponent();
+ expect(findDeleteAlert().exists()).toBe(true);
+ });
- it('alert exist and text is appropriate', () => {
- expect(findAlert().exists()).toBe(true);
- expect(findAlert().text()).toBe(errorTitle);
- });
- });
+ it('has the correct props', () => {
+ store.commit(SET_INITIAL_STATE, { ...config });
+ mountComponent({
+ data: () => ({
+ deleteAlertType,
+ }),
});
+ expect(findDeleteAlert().props()).toEqual({ ...config, deleteAlertType });
});
-
- describe.each`
- deleteType | successTitle | errorTitle
- ${'handleSingleDelete'} | ${DELETE_TAG_SUCCESS_MESSAGE} | ${DELETE_TAG_ERROR_MESSAGE}
- ${'handleMultipleDelete'} | ${DELETE_TAGS_SUCCESS_MESSAGE} | ${DELETE_TAGS_ERROR_MESSAGE}
- `(
- 'when the user is not an admin alert behaves correctly on $deleteType',
- ({ deleteType, successTitle, errorTitle }) => {
- beforeEach(() => {
- store.commit('SET_INITIAL_STATE', { ...config });
- });
-
- describe('when delete is successful', () => {
- beforeEach(() => {
- dispatchSpy.mockResolvedValue();
- mountComponent();
- return wrapper.vm[deleteType]('foo');
- });
-
- it('alert exist and text is appropriate', () => {
- expect(findAlert().exists()).toBe(true);
- expect(findAlert().text()).toBe(successTitle);
- });
- });
-
- describe('when delete is not successful', () => {
- beforeEach(() => {
- mountComponent();
- dispatchSpy.mockRejectedValue();
- return wrapper.vm[deleteType]('foo');
- });
-
- it('alert exist and text is appropriate', () => {
- expect(findAlert().exists()).toBe(true);
- expect(findAlert().text()).toBe(errorTitle);
- });
- });
- },
- );
});
});
diff --git a/spec/frontend/registry/explorer/pages/index_spec.js b/spec/frontend/registry/explorer/pages/index_spec.js
index b558727ed5e..1dc5376cacf 100644
--- a/spec/frontend/registry/explorer/pages/index_spec.js
+++ b/spec/frontend/registry/explorer/pages/index_spec.js
@@ -1,9 +1,10 @@
import { shallowMount } from '@vue/test-utils';
import component from '~/registry/explorer/pages/index.vue';
-import store from '~/registry/explorer/stores/';
+import { createStore } from '~/registry/explorer/stores/';
describe('List Page', () => {
let wrapper;
+ let store;
const findRouterView = () => wrapper.find({ ref: 'router-view' });
@@ -17,6 +18,7 @@ describe('List Page', () => {
};
beforeEach(() => {
+ store = createStore();
mountComponent();
});
diff --git a/spec/frontend/registry/explorer/pages/list_spec.js b/spec/frontend/registry/explorer/pages/list_spec.js
index 97742b9e9b3..2ece7593b41 100644
--- a/spec/frontend/registry/explorer/pages/list_spec.js
+++ b/spec/frontend/registry/explorer/pages/list_spec.js
@@ -3,11 +3,11 @@ import { GlSkeletonLoader, GlSprintf, GlAlert, GlSearchBoxByClick } from '@gitla
import Tracking from '~/tracking';
import waitForPromises from 'helpers/wait_for_promises';
import component from '~/registry/explorer/pages/list.vue';
-import QuickstartDropdown from '~/registry/explorer/components/quickstart_dropdown.vue';
-import GroupEmptyState from '~/registry/explorer/components/group_empty_state.vue';
-import ProjectEmptyState from '~/registry/explorer/components/project_empty_state.vue';
-import ProjectPolicyAlert from '~/registry/explorer/components/project_policy_alert.vue';
-import ImageList from '~/registry/explorer/components/image_list.vue';
+import CliCommands from '~/registry/explorer/components/list_page/cli_commands.vue';
+import GroupEmptyState from '~/registry/explorer/components/list_page/group_empty_state.vue';
+import ProjectEmptyState from '~/registry/explorer/components/list_page/project_empty_state.vue';
+import RegistryHeader from '~/registry/explorer/components/list_page/registry_header.vue';
+import ImageList from '~/registry/explorer/components/list_page/image_list.vue';
import { createStore } from '~/registry/explorer/stores/';
import {
SET_MAIN_LOADING,
@@ -32,14 +32,14 @@ describe('List Page', () => {
const findDeleteModal = () => wrapper.find(GlModal);
const findSkeletonLoader = () => wrapper.find(GlSkeletonLoader);
- const findImagesList = () => wrapper.find({ ref: 'imagesList' });
const findEmptyState = () => wrapper.find(GlEmptyState);
- const findQuickStartDropdown = () => wrapper.find(QuickstartDropdown);
+ const findCliCommands = () => wrapper.find(CliCommands);
const findProjectEmptyState = () => wrapper.find(ProjectEmptyState);
const findGroupEmptyState = () => wrapper.find(GroupEmptyState);
- const findProjectPolicyAlert = () => wrapper.find(ProjectPolicyAlert);
+ const findRegistryHeader = () => wrapper.find(RegistryHeader);
+
const findDeleteAlert = () => wrapper.find(GlAlert);
const findImageList = () => wrapper.find(ImageList);
const findListHeader = () => wrapper.find('[data-testid="listHeader"]');
@@ -53,6 +53,7 @@ describe('List Page', () => {
GlModal,
GlEmptyState,
GlSprintf,
+ RegistryHeader,
},
mocks: {
$toast,
@@ -76,21 +77,6 @@ describe('List Page', () => {
wrapper.destroy();
});
- describe('Expiration policy notification', () => {
- beforeEach(() => {
- mountComponent();
- });
- it('shows up on project page', () => {
- expect(findProjectPolicyAlert().exists()).toBe(true);
- });
- it('does show up on group page', () => {
- store.commit(SET_INITIAL_STATE, { isGroupPage: true });
- return wrapper.vm.$nextTick().then(() => {
- expect(findProjectPolicyAlert().exists()).toBe(false);
- });
- });
- });
-
describe('API calls', () => {
it.each`
imageList | name | called
@@ -109,6 +95,11 @@ describe('List Page', () => {
);
});
+ it('contains registry header', () => {
+ mountComponent();
+ expect(findRegistryHeader().exists()).toBe(true);
+ });
+
describe('connection error', () => {
const config = {
characterError: true,
@@ -139,7 +130,7 @@ describe('List Page', () => {
it('should not show the loading or default state', () => {
expect(findSkeletonLoader().exists()).toBe(false);
- expect(findImagesList().exists()).toBe(false);
+ expect(findImageList().exists()).toBe(false);
});
});
@@ -156,11 +147,11 @@ describe('List Page', () => {
});
it('imagesList is not visible', () => {
- expect(findImagesList().exists()).toBe(false);
+ expect(findImageList().exists()).toBe(false);
});
- it('quick start is not visible', () => {
- expect(findQuickStartDropdown().exists()).toBe(false);
+ it('cli commands is not visible', () => {
+ expect(findCliCommands().exists()).toBe(false);
});
});
@@ -171,8 +162,8 @@ describe('List Page', () => {
return waitForPromises();
});
- it('quick start is not visible', () => {
- expect(findQuickStartDropdown().exists()).toBe(false);
+ it('cli commands is not visible', () => {
+ expect(findCliCommands().exists()).toBe(false);
});
it('project empty state is visible', () => {
@@ -193,8 +184,8 @@ describe('List Page', () => {
expect(findGroupEmptyState().exists()).toBe(true);
});
- it('quick start is not visible', () => {
- expect(findQuickStartDropdown().exists()).toBe(false);
+ it('cli commands is not visible', () => {
+ expect(findCliCommands().exists()).toBe(false);
});
it('list header is not visible', () => {
@@ -210,7 +201,7 @@ describe('List Page', () => {
});
it('quick start is visible', () => {
- expect(findQuickStartDropdown().exists()).toBe(true);
+ expect(findCliCommands().exists()).toBe(true);
});
it('list component is visible', () => {
@@ -311,7 +302,7 @@ describe('List Page', () => {
});
it('contains a description with the path of the item to delete', () => {
- wrapper.setData({ itemToDelete: { path: 'foo' } });
+ findImageList().vm.$emit('delete', { path: 'foo' });
return wrapper.vm.$nextTick().then(() => {
expect(findDeleteModal().html()).toContain('foo');
});
diff --git a/spec/frontend/registry/explorer/stores/getters_spec.js b/spec/frontend/registry/explorer/stores/getters_spec.js
index cd053ea8edc..4cab65d2bb0 100644
--- a/spec/frontend/registry/explorer/stores/getters_spec.js
+++ b/spec/frontend/registry/explorer/stores/getters_spec.js
@@ -2,35 +2,6 @@ import * as getters from '~/registry/explorer/stores/getters';
describe('Getters RegistryExplorer store', () => {
let state;
- const tags = ['foo', 'bar'];
-
- describe('tags', () => {
- describe('when isLoading is false', () => {
- beforeEach(() => {
- state = {
- tags,
- isLoading: false,
- };
- });
-
- it('returns tags', () => {
- expect(getters.tags(state)).toEqual(state.tags);
- });
- });
-
- describe('when isLoading is true', () => {
- beforeEach(() => {
- state = {
- tags,
- isLoading: true,
- };
- });
-
- it('returns empty array', () => {
- expect(getters.tags(state)).toEqual([]);
- });
- });
- });
describe.each`
getter | prefix | configParameter | suffix
diff --git a/spec/frontend/registry/explorer/stores/mutations_spec.js b/spec/frontend/registry/explorer/stores/mutations_spec.js
index 43b2ba84218..4ca0211cdc3 100644
--- a/spec/frontend/registry/explorer/stores/mutations_spec.js
+++ b/spec/frontend/registry/explorer/stores/mutations_spec.js
@@ -12,11 +12,14 @@ describe('Mutations Registry Explorer Store', () => {
it('should set the initial state', () => {
const payload = {
endpoint: 'foo',
- isGroupPage: true,
+ isGroupPage: '',
expirationPolicy: { foo: 'bar' },
- isAdmin: true,
+ isAdmin: '',
+ };
+ const expectedState = {
+ ...mockState,
+ config: { ...payload, isGroupPage: false, isAdmin: false },
};
- const expectedState = { ...mockState, config: payload };
mutations[types.SET_INITIAL_STATE](mockState, {
...payload,
expirationPolicy: JSON.stringify(payload.expirationPolicy),
diff --git a/spec/frontend/registry/explorer/stubs.js b/spec/frontend/registry/explorer/stubs.js
index 0e178abfbed..d3518c36c82 100644
--- a/spec/frontend/registry/explorer/stubs.js
+++ b/spec/frontend/registry/explorer/stubs.js
@@ -1,3 +1,6 @@
+import RealTagsTable from '~/registry/explorer/components/details_page/tags_table.vue';
+import RealDeleteModal from '~/registry/explorer/components/details_page/delete_modal.vue';
+
export const GlModal = {
template: '<div><slot name="modal-title"></slot><slot></slot><slot name="modal-ok"></slot></div>',
methods: {
@@ -14,3 +17,21 @@ export const RouterLink = {
template: `<div><slot></slot></div>`,
props: ['to'],
};
+
+export const TagsTable = {
+ props: RealTagsTable.props,
+ template: `<div><slot name="empty"></slot><slot name="loader"></slot></div>`,
+};
+
+export const DeleteModal = {
+ template: '<div></div>',
+ methods: {
+ show: jest.fn(),
+ },
+ props: RealDeleteModal.props,
+};
+
+export const GlSkeletonLoader = {
+ template: `<div><slot></slot></div>`,
+ props: ['width', 'height'],
+};
diff --git a/spec/frontend/releases/components/app_index_spec.js b/spec/frontend/releases/components/app_index_spec.js
new file mode 100644
index 00000000000..91beb5b1418
--- /dev/null
+++ b/spec/frontend/releases/components/app_index_spec.js
@@ -0,0 +1,150 @@
+import { range as rge } from 'lodash';
+import Vue from 'vue';
+import { mountComponentWithStore } from 'helpers/vue_mount_component_helper';
+import app from '~/releases/components/app_index.vue';
+import createStore from '~/releases/stores';
+import listModule from '~/releases/stores/modules/list';
+import api from '~/api';
+import { resetStore } from '../stores/modules/list/helpers';
+import {
+ pageInfoHeadersWithoutPagination,
+ pageInfoHeadersWithPagination,
+ release2 as release,
+ releases,
+} from '../mock_data';
+import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
+import waitForPromises from 'helpers/wait_for_promises';
+
+describe('Releases App ', () => {
+ const Component = Vue.extend(app);
+ let store;
+ let vm;
+ let releasesPagination;
+
+ const props = {
+ projectId: 'gitlab-ce',
+ documentationPath: 'help/releases',
+ illustrationPath: 'illustration/path',
+ };
+
+ beforeEach(() => {
+ store = createStore({ modules: { list: listModule } });
+ releasesPagination = rge(21).map(index => ({
+ ...convertObjectPropsToCamelCase(release, { deep: true }),
+ tagName: `${index}.00`,
+ }));
+ });
+
+ afterEach(() => {
+ resetStore(store);
+ vm.$destroy();
+ });
+
+ describe('while loading', () => {
+ beforeEach(() => {
+ jest
+ .spyOn(api, 'releases')
+ // Need to defer the return value here to the next stack,
+ // otherwise the loading state disappears before our test even starts.
+ .mockImplementation(() => waitForPromises().then(() => ({ data: [], headers: {} })));
+ vm = mountComponentWithStore(Component, { props, store });
+ });
+
+ it('renders loading icon', () => {
+ expect(vm.$el.querySelector('.js-loading')).not.toBeNull();
+ expect(vm.$el.querySelector('.js-empty-state')).toBeNull();
+ expect(vm.$el.querySelector('.js-success-state')).toBeNull();
+ expect(vm.$el.querySelector('.gl-pagination')).toBeNull();
+
+ return waitForPromises();
+ });
+ });
+
+ describe('with successful request', () => {
+ beforeEach(() => {
+ jest
+ .spyOn(api, 'releases')
+ .mockResolvedValue({ data: releases, headers: pageInfoHeadersWithoutPagination });
+ vm = mountComponentWithStore(Component, { props, store });
+ });
+
+ it('renders success state', () => {
+ expect(vm.$el.querySelector('.js-loading')).toBeNull();
+ expect(vm.$el.querySelector('.js-empty-state')).toBeNull();
+ expect(vm.$el.querySelector('.js-success-state')).not.toBeNull();
+ expect(vm.$el.querySelector('.gl-pagination')).toBeNull();
+ });
+ });
+
+ describe('with successful request and pagination', () => {
+ beforeEach(() => {
+ jest
+ .spyOn(api, 'releases')
+ .mockResolvedValue({ data: releasesPagination, headers: pageInfoHeadersWithPagination });
+ vm = mountComponentWithStore(Component, { props, store });
+ });
+
+ it('renders success state', () => {
+ expect(vm.$el.querySelector('.js-loading')).toBeNull();
+ expect(vm.$el.querySelector('.js-empty-state')).toBeNull();
+ expect(vm.$el.querySelector('.js-success-state')).not.toBeNull();
+ expect(vm.$el.querySelector('.gl-pagination')).not.toBeNull();
+ });
+ });
+
+ describe('with empty request', () => {
+ beforeEach(() => {
+ jest.spyOn(api, 'releases').mockResolvedValue({ data: [], headers: {} });
+ vm = mountComponentWithStore(Component, { props, store });
+ });
+
+ it('renders empty state', () => {
+ expect(vm.$el.querySelector('.js-loading')).toBeNull();
+ expect(vm.$el.querySelector('.js-empty-state')).not.toBeNull();
+ expect(vm.$el.querySelector('.js-success-state')).toBeNull();
+ expect(vm.$el.querySelector('.gl-pagination')).toBeNull();
+ });
+ });
+
+ describe('"New release" button', () => {
+ const findNewReleaseButton = () => vm.$el.querySelector('.js-new-release-btn');
+
+ beforeEach(() => {
+ jest.spyOn(api, 'releases').mockResolvedValue({ data: [], headers: {} });
+ });
+
+ const factory = additionalProps => {
+ vm = mountComponentWithStore(Component, {
+ props: {
+ ...props,
+ ...additionalProps,
+ },
+ store,
+ });
+ };
+
+ describe('when the user is allowed to create a new Release', () => {
+ const newReleasePath = 'path/to/new/release';
+
+ beforeEach(() => {
+ factory({ newReleasePath });
+ });
+
+ it('renders the "New release" button', () => {
+ expect(findNewReleaseButton()).not.toBeNull();
+ });
+
+ it('renders the "New release" button with the correct href', () => {
+ expect(findNewReleaseButton().getAttribute('href')).toBe(newReleasePath);
+ });
+ });
+
+ describe('when the user is not allowed to create a new Release', () => {
+ beforeEach(() => factory());
+
+ it('does not render the "New release" button', () => {
+ expect(findNewReleaseButton()).toBeNull();
+ });
+ });
+ });
+});
diff --git a/spec/frontend/releases/components/asset_links_form_spec.js b/spec/frontend/releases/components/asset_links_form_spec.js
index 44542868cfe..e1f8592270e 100644
--- a/spec/frontend/releases/components/asset_links_form_spec.js
+++ b/spec/frontend/releases/components/asset_links_form_spec.js
@@ -3,6 +3,7 @@ import { mount, createLocalVue } from '@vue/test-utils';
import AssetLinksForm from '~/releases/components/asset_links_form.vue';
import { release as originalRelease } from '../mock_data';
import * as commonUtils from '~/lib/utils/common_utils';
+import { ASSET_LINK_TYPE, DEFAULT_ASSET_LINK_TYPE } from '~/releases/constants';
const localVue = createLocalVue();
localVue.use(Vuex);
@@ -24,6 +25,7 @@ describe('Release edit component', () => {
addEmptyAssetLink: jest.fn(),
updateAssetLinkUrl: jest.fn(),
updateAssetLinkName: jest.fn(),
+ updateAssetLinkType: jest.fn(),
removeAssetLink: jest.fn().mockImplementation((_context, linkId) => {
state.release.assets.links = state.release.assets.links.filter(l => l.id !== linkId);
}),
@@ -51,6 +53,11 @@ describe('Release edit component', () => {
wrapper = mount(AssetLinksForm, {
localVue,
store,
+ provide: {
+ glFeatures: {
+ releaseAssetLinkType: true,
+ },
+ },
});
};
@@ -103,7 +110,7 @@ describe('Release edit component', () => {
);
});
- it('calls the "updateAssetLinName" store method when text is entered into the "Link title" input field', () => {
+ it('calls the "updateAssetLinkName" store method when text is entered into the "Link title" input field', () => {
const linkIdToUpdate = release.assets.links[0].id;
const newName = 'updated name';
@@ -121,6 +128,31 @@ describe('Release edit component', () => {
undefined,
);
});
+
+ it('calls the "updateAssetLinkType" store method when an option is selected from the "Type" dropdown', () => {
+ const linkIdToUpdate = release.assets.links[0].id;
+ const newType = ASSET_LINK_TYPE.RUNBOOK;
+
+ expect(actions.updateAssetLinkType).not.toHaveBeenCalled();
+
+ wrapper.find({ ref: 'typeSelect' }).vm.$emit('change', newType);
+
+ expect(actions.updateAssetLinkType).toHaveBeenCalledTimes(1);
+ expect(actions.updateAssetLinkType).toHaveBeenCalledWith(
+ expect.anything(),
+ {
+ linkIdToUpdate,
+ newType,
+ },
+ undefined,
+ );
+ });
+
+ it('selects the default asset type if no type was provided by the backend', () => {
+ const selected = wrapper.find({ ref: 'typeSelect' }).element.value;
+
+ expect(selected).toBe(DEFAULT_ASSET_LINK_TYPE);
+ });
});
describe('validation', () => {
diff --git a/spec/frontend/releases/components/release_block_assets_spec.js b/spec/frontend/releases/components/release_block_assets_spec.js
new file mode 100644
index 00000000000..44b190b0d19
--- /dev/null
+++ b/spec/frontend/releases/components/release_block_assets_spec.js
@@ -0,0 +1,137 @@
+import { mount } from '@vue/test-utils';
+import { GlCollapse } from '@gitlab/ui';
+import ReleaseBlockAssets from '~/releases/components/release_block_assets.vue';
+import { ASSET_LINK_TYPE } from '~/releases/constants';
+import { trimText } from 'helpers/text_helper';
+import { assets } from '../mock_data';
+
+describe('Release block assets', () => {
+ let wrapper;
+ let defaultProps;
+
+ // A map of types to the expected section heading text
+ const sections = {
+ [ASSET_LINK_TYPE.IMAGE]: 'Images',
+ [ASSET_LINK_TYPE.PACKAGE]: 'Packages',
+ [ASSET_LINK_TYPE.RUNBOOK]: 'Runbooks',
+ [ASSET_LINK_TYPE.OTHER]: 'Other',
+ };
+
+ const createComponent = (propsData = defaultProps) => {
+ wrapper = mount(ReleaseBlockAssets, {
+ provide: {
+ glFeatures: { releaseAssetLinkType: true },
+ },
+ propsData,
+ });
+ };
+
+ const findSectionHeading = type =>
+ wrapper.findAll('h5').filter(h5 => h5.text() === sections[type]);
+
+ beforeEach(() => {
+ defaultProps = { assets };
+ });
+
+ describe('with default props', () => {
+ beforeEach(() => createComponent());
+
+ const findAccordionButton = () => wrapper.find('[data-testid="accordion-button"]');
+
+ it('renders an "Assets" accordion with the asset count', () => {
+ const accordionButton = findAccordionButton();
+
+ expect(accordionButton.exists()).toBe(true);
+ expect(trimText(accordionButton.text())).toBe('Assets 5');
+ });
+
+ it('renders the accordion as expanded by default', () => {
+ const accordion = wrapper.find(GlCollapse);
+
+ expect(accordion.exists()).toBe(true);
+ expect(accordion.isVisible()).toBe(true);
+ });
+
+ it('renders sources with the expected text and URL', () => {
+ defaultProps.assets.sources.forEach(s => {
+ const sourceLink = wrapper.find(`li>a[href="${s.url}"]`);
+
+ expect(sourceLink.exists()).toBe(true);
+ expect(sourceLink.text()).toBe(`Source code (${s.format})`);
+ });
+ });
+
+ it('renders a heading for each assets type (except sources)', () => {
+ Object.keys(sections).forEach(type => {
+ const sectionHeadings = findSectionHeading(type);
+
+ expect(sectionHeadings).toHaveLength(1);
+ });
+ });
+
+ it('renders asset links with the expected text and URL', () => {
+ defaultProps.assets.links.forEach(l => {
+ const sourceLink = wrapper.find(`li>a[href="${l.directAssetUrl}"]`);
+
+ expect(sourceLink.exists()).toBe(true);
+ expect(sourceLink.text()).toBe(l.name);
+ });
+ });
+ });
+
+ describe("when a release doesn't have a link with a certain asset type", () => {
+ const typeToExclude = ASSET_LINK_TYPE.IMAGE;
+
+ beforeEach(() => {
+ defaultProps.assets.links = defaultProps.assets.links.filter(
+ l => l.linkType !== typeToExclude,
+ );
+ createComponent(defaultProps);
+ });
+
+ it('does not render a section heading if there are no links of that type', () => {
+ const sectionHeadings = findSectionHeading(typeToExclude);
+
+ expect(sectionHeadings).toHaveLength(0);
+ });
+ });
+
+ describe('external vs internal links', () => {
+ const containsExternalSourceIndicator = () =>
+ wrapper.contains('[data-testid="external-link-indicator"]');
+
+ describe('when a link is external', () => {
+ beforeEach(() => {
+ defaultProps.assets.sources = [];
+ defaultProps.assets.links = [
+ {
+ ...defaultProps.assets.links[0],
+ external: true,
+ },
+ ];
+ createComponent(defaultProps);
+ });
+
+ it('renders the link with an "external source" indicator', () => {
+ expect(containsExternalSourceIndicator()).toBe(true);
+ });
+ });
+
+ describe('when a link is internal', () => {
+ beforeEach(() => {
+ defaultProps.assets.sources = [];
+ defaultProps.assets.links = [
+ {
+ ...defaultProps.assets.links[0],
+ external: false,
+ },
+ ];
+ createComponent(defaultProps);
+ });
+
+ it('renders the link without the "external source" indicator', () => {
+ expect(containsExternalSourceIndicator()).toBe(false);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/releases/mock_data.js b/spec/frontend/releases/mock_data.js
index bd5fc86275e..b97385154bd 100644
--- a/spec/frontend/releases/mock_data.js
+++ b/spec/frontend/releases/mock_data.js
@@ -1,3 +1,5 @@
+import { ASSET_LINK_TYPE } from '~/releases/constants';
+
export const milestones = [
{
id: 50,
@@ -131,3 +133,92 @@ export const release = {
edit_url: 'http://0.0.0.0:3001/root/release-test/-/releases/v0.3/edit',
},
};
+
+export const pageInfoHeadersWithoutPagination = {
+ 'X-NEXT-PAGE': '',
+ 'X-PAGE': '1',
+ 'X-PER-PAGE': '20',
+ 'X-PREV-PAGE': '',
+ 'X-TOTAL': '19',
+ 'X-TOTAL-PAGES': '1',
+};
+
+export const pageInfoHeadersWithPagination = {
+ 'X-NEXT-PAGE': '2',
+ 'X-PAGE': '1',
+ 'X-PER-PAGE': '20',
+ 'X-PREV-PAGE': '',
+ 'X-TOTAL': '21',
+ 'X-TOTAL-PAGES': '2',
+};
+
+export const assets = {
+ count: 5,
+ sources: [
+ {
+ format: 'zip',
+ url: 'https://example.gitlab.com/path/to/zip',
+ },
+ ],
+ links: [
+ {
+ linkType: ASSET_LINK_TYPE.IMAGE,
+ url: 'https://example.gitlab.com/path/to/image',
+ directAssetUrl: 'https://example.gitlab.com/path/to/image',
+ name: 'Example image link',
+ },
+ {
+ linkType: ASSET_LINK_TYPE.PACKAGE,
+ url: 'https://example.gitlab.com/path/to/package',
+ directAssetUrl: 'https://example.gitlab.com/path/to/package',
+ name: 'Example package link',
+ },
+ {
+ linkType: ASSET_LINK_TYPE.RUNBOOK,
+ url: 'https://example.gitlab.com/path/to/runbook',
+ directAssetUrl: 'https://example.gitlab.com/path/to/runbook',
+ name: 'Example runbook link',
+ },
+ {
+ linkType: ASSET_LINK_TYPE.OTHER,
+ url: 'https://example.gitlab.com/path/to/link',
+ directAssetUrl: 'https://example.gitlab.com/path/to/link',
+ name: 'Example link',
+ },
+ ],
+};
+
+export const release2 = {
+ name: 'Bionic Beaver',
+ tag_name: '18.04',
+ description: '## changelog\n\n* line 1\n* line2',
+ description_html: '<div><h2>changelog</h2><ul><li>line1</li<li>line 2</li></ul></div>',
+ author_name: 'Release bot',
+ author_email: 'release-bot@example.com',
+ created_at: '2012-05-28T05:00:00-07:00',
+ commit: {
+ id: '2695effb5807a22ff3d138d593fd856244e155e7',
+ short_id: '2695effb',
+ title: 'Initial commit',
+ created_at: '2017-07-26T11:08:53.000+02:00',
+ parent_ids: ['2a4b78934375d7f53875269ffd4f45fd83a84ebe'],
+ message: 'Initial commit',
+ author: {
+ avatar_url: 'uploads/-/system/user/avatar/johndoe/avatar.png',
+ id: 482476,
+ name: 'John Doe',
+ path: '/johndoe',
+ state: 'active',
+ status_tooltip_html: null,
+ username: 'johndoe',
+ web_url: 'https://gitlab.com/johndoe',
+ },
+ authored_date: '2012-05-28T04:42:42-07:00',
+ committer_name: 'Jack Smith',
+ committer_email: 'jack@example.com',
+ committed_date: '2012-05-28T04:42:42-07:00',
+ },
+ assets,
+};
+
+export const releases = [release, release2];
diff --git a/spec/frontend/releases/stores/modules/detail/actions_spec.js b/spec/frontend/releases/stores/modules/detail/actions_spec.js
index 854f06821be..345be2acc71 100644
--- a/spec/frontend/releases/stores/modules/detail/actions_spec.js
+++ b/spec/frontend/releases/stores/modules/detail/actions_spec.js
@@ -10,6 +10,7 @@ import createFlash from '~/flash';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { redirectTo } from '~/lib/utils/url_utility';
import api from '~/api';
+import { ASSET_LINK_TYPE } from '~/releases/constants';
jest.mock('~/flash', () => jest.fn());
@@ -130,6 +131,54 @@ describe('Release detail actions', () => {
});
});
+ describe('updateAssetLinkUrl', () => {
+ it(`commits ${types.UPDATE_ASSET_LINK_URL} with the updated link URL`, () => {
+ const params = {
+ linkIdToUpdate: 2,
+ newUrl: 'https://example.com/updated',
+ };
+
+ return testAction(actions.updateAssetLinkUrl, params, state, [
+ { type: types.UPDATE_ASSET_LINK_URL, payload: params },
+ ]);
+ });
+ });
+
+ describe('updateAssetLinkName', () => {
+ it(`commits ${types.UPDATE_ASSET_LINK_NAME} with the updated link name`, () => {
+ const params = {
+ linkIdToUpdate: 2,
+ newName: 'Updated link name',
+ };
+
+ return testAction(actions.updateAssetLinkName, params, state, [
+ { type: types.UPDATE_ASSET_LINK_NAME, payload: params },
+ ]);
+ });
+ });
+
+ describe('updateAssetLinkType', () => {
+ it(`commits ${types.UPDATE_ASSET_LINK_TYPE} with the updated link type`, () => {
+ const params = {
+ linkIdToUpdate: 2,
+ newType: ASSET_LINK_TYPE.RUNBOOK,
+ };
+
+ return testAction(actions.updateAssetLinkType, params, state, [
+ { type: types.UPDATE_ASSET_LINK_TYPE, payload: params },
+ ]);
+ });
+ });
+
+ describe('removeAssetLink', () => {
+ it(`commits ${types.REMOVE_ASSET_LINK} with the ID of the asset link to remove`, () => {
+ const idToRemove = 2;
+ return testAction(actions.removeAssetLink, idToRemove, state, [
+ { type: types.REMOVE_ASSET_LINK, payload: idToRemove },
+ ]);
+ });
+ });
+
describe('updateReleaseMilestones', () => {
it(`commits ${types.UPDATE_RELEASE_MILESTONES} with the updated release milestones`, () => {
const newReleaseMilestones = ['v0.0', 'v0.1'];
diff --git a/spec/frontend/releases/stores/modules/detail/mutations_spec.js b/spec/frontend/releases/stores/modules/detail/mutations_spec.js
index f3f7ca797b4..a34c1be64d9 100644
--- a/spec/frontend/releases/stores/modules/detail/mutations_spec.js
+++ b/spec/frontend/releases/stores/modules/detail/mutations_spec.js
@@ -3,6 +3,7 @@ import mutations from '~/releases/stores/modules/detail/mutations';
import * as types from '~/releases/stores/modules/detail/mutation_types';
import { release as originalRelease } from '../../../mock_data';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
+import { ASSET_LINK_TYPE, DEFAULT_ASSET_LINK_TYPE } from '~/releases/constants';
describe('Release detail mutations', () => {
let state;
@@ -24,7 +25,7 @@ describe('Release detail mutations', () => {
it('set state.isFetchingRelease to true', () => {
mutations[types.REQUEST_RELEASE](state);
- expect(state.isFetchingRelease).toEqual(true);
+ expect(state.isFetchingRelease).toBe(true);
});
});
@@ -32,9 +33,9 @@ describe('Release detail mutations', () => {
it('handles a successful response from the server', () => {
mutations[types.RECEIVE_RELEASE_SUCCESS](state, release);
- expect(state.fetchError).toEqual(undefined);
+ expect(state.fetchError).toBeUndefined();
- expect(state.isFetchingRelease).toEqual(false);
+ expect(state.isFetchingRelease).toBe(false);
expect(state.release).toEqual(release);
@@ -47,7 +48,7 @@ describe('Release detail mutations', () => {
const error = { message: 'An error occurred!' };
mutations[types.RECEIVE_RELEASE_ERROR](state, error);
- expect(state.isFetchingRelease).toEqual(false);
+ expect(state.isFetchingRelease).toBe(false);
expect(state.release).toBeUndefined();
@@ -61,7 +62,7 @@ describe('Release detail mutations', () => {
const newTitle = 'The new release title';
mutations[types.UPDATE_RELEASE_TITLE](state, newTitle);
- expect(state.release.name).toEqual(newTitle);
+ expect(state.release.name).toBe(newTitle);
});
});
@@ -71,7 +72,7 @@ describe('Release detail mutations', () => {
const newNotes = 'The new release notes';
mutations[types.UPDATE_RELEASE_NOTES](state, newNotes);
- expect(state.release.description).toEqual(newNotes);
+ expect(state.release.description).toBe(newNotes);
});
});
@@ -79,7 +80,7 @@ describe('Release detail mutations', () => {
it('set state.isUpdatingRelease to true', () => {
mutations[types.REQUEST_UPDATE_RELEASE](state);
- expect(state.isUpdatingRelease).toEqual(true);
+ expect(state.isUpdatingRelease).toBe(true);
});
});
@@ -87,9 +88,9 @@ describe('Release detail mutations', () => {
it('handles a successful response from the server', () => {
mutations[types.RECEIVE_UPDATE_RELEASE_SUCCESS](state, release);
- expect(state.updateError).toEqual(undefined);
+ expect(state.updateError).toBeUndefined();
- expect(state.isUpdatingRelease).toEqual(false);
+ expect(state.isUpdatingRelease).toBe(false);
});
});
@@ -98,7 +99,7 @@ describe('Release detail mutations', () => {
const error = { message: 'An error occurred!' };
mutations[types.RECEIVE_UPDATE_RELEASE_ERROR](state, error);
- expect(state.isUpdatingRelease).toEqual(false);
+ expect(state.isUpdatingRelease).toBe(false);
expect(state.updateError).toEqual(error);
});
@@ -118,6 +119,7 @@ describe('Release detail mutations', () => {
id: expect.stringMatching(/^new-link-/),
url: '',
name: '',
+ linkType: DEFAULT_ASSET_LINK_TYPE,
},
]);
});
@@ -134,7 +136,7 @@ describe('Release detail mutations', () => {
newUrl,
});
- expect(state.release.assets.links[0].url).toEqual(newUrl);
+ expect(state.release.assets.links[0].url).toBe(newUrl);
});
});
@@ -149,7 +151,22 @@ describe('Release detail mutations', () => {
newName,
});
- expect(state.release.assets.links[0].name).toEqual(newName);
+ expect(state.release.assets.links[0].name).toBe(newName);
+ });
+ });
+
+ describe(`${types.UPDATE_ASSET_LINK_TYPE}`, () => {
+ it('updates an asset link with a new type', () => {
+ state.release = release;
+
+ const newType = ASSET_LINK_TYPE.RUNBOOK;
+
+ mutations[types.UPDATE_ASSET_LINK_TYPE](state, {
+ linkIdToUpdate: state.release.assets.links[0].id,
+ newType,
+ });
+
+ expect(state.release.assets.links[0].linkType).toBe(newType);
});
});
diff --git a/spec/frontend/releases/stores/modules/list/actions_spec.js b/spec/frontend/releases/stores/modules/list/actions_spec.js
new file mode 100644
index 00000000000..4c3af157684
--- /dev/null
+++ b/spec/frontend/releases/stores/modules/list/actions_spec.js
@@ -0,0 +1,131 @@
+import testAction from 'helpers/vuex_action_helper';
+import {
+ requestReleases,
+ fetchReleases,
+ receiveReleasesSuccess,
+ receiveReleasesError,
+} from '~/releases/stores/modules/list/actions';
+import state from '~/releases/stores/modules/list/state';
+import * as types from '~/releases/stores/modules/list/mutation_types';
+import api from '~/api';
+import { parseIntPagination, convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
+import { pageInfoHeadersWithoutPagination, releases as originalReleases } from '../../../mock_data';
+
+describe('Releases State actions', () => {
+ let mockedState;
+ let pageInfo;
+ let releases;
+
+ beforeEach(() => {
+ mockedState = state();
+ pageInfo = parseIntPagination(pageInfoHeadersWithoutPagination);
+ releases = convertObjectPropsToCamelCase(originalReleases, { deep: true });
+ });
+
+ describe('requestReleases', () => {
+ it('should commit REQUEST_RELEASES mutation', done => {
+ testAction(requestReleases, null, mockedState, [{ type: types.REQUEST_RELEASES }], [], done);
+ });
+ });
+
+ describe('fetchReleases', () => {
+ describe('success', () => {
+ it('dispatches requestReleases and receiveReleasesSuccess', done => {
+ jest.spyOn(api, 'releases').mockImplementation((id, options) => {
+ expect(id).toEqual(1);
+ expect(options.page).toEqual('1');
+ return Promise.resolve({ data: releases, headers: pageInfoHeadersWithoutPagination });
+ });
+
+ testAction(
+ fetchReleases,
+ { projectId: 1 },
+ mockedState,
+ [],
+ [
+ {
+ type: 'requestReleases',
+ },
+ {
+ payload: { data: releases, headers: pageInfoHeadersWithoutPagination },
+ type: 'receiveReleasesSuccess',
+ },
+ ],
+ done,
+ );
+ });
+
+ it('dispatches requestReleases and receiveReleasesSuccess on page two', done => {
+ jest.spyOn(api, 'releases').mockImplementation((_, options) => {
+ expect(options.page).toEqual('2');
+ return Promise.resolve({ data: releases, headers: pageInfoHeadersWithoutPagination });
+ });
+
+ testAction(
+ fetchReleases,
+ { page: '2', projectId: 1 },
+ mockedState,
+ [],
+ [
+ {
+ type: 'requestReleases',
+ },
+ {
+ payload: { data: releases, headers: pageInfoHeadersWithoutPagination },
+ type: 'receiveReleasesSuccess',
+ },
+ ],
+ done,
+ );
+ });
+ });
+
+ describe('error', () => {
+ it('dispatches requestReleases and receiveReleasesError', done => {
+ jest.spyOn(api, 'releases').mockReturnValue(Promise.reject());
+
+ testAction(
+ fetchReleases,
+ { projectId: null },
+ mockedState,
+ [],
+ [
+ {
+ type: 'requestReleases',
+ },
+ {
+ type: 'receiveReleasesError',
+ },
+ ],
+ done,
+ );
+ });
+ });
+ });
+
+ describe('receiveReleasesSuccess', () => {
+ it('should commit RECEIVE_RELEASES_SUCCESS mutation', done => {
+ testAction(
+ receiveReleasesSuccess,
+ { data: releases, headers: pageInfoHeadersWithoutPagination },
+ mockedState,
+ [{ type: types.RECEIVE_RELEASES_SUCCESS, payload: { pageInfo, data: releases } }],
+ [],
+ done,
+ );
+ });
+ });
+
+ describe('receiveReleasesError', () => {
+ it('should commit RECEIVE_RELEASES_ERROR mutation', done => {
+ testAction(
+ receiveReleasesError,
+ null,
+ mockedState,
+ [{ type: types.RECEIVE_RELEASES_ERROR }],
+ [],
+ done,
+ );
+ });
+ });
+});
diff --git a/spec/javascripts/releases/stores/modules/list/helpers.js b/spec/frontend/releases/stores/modules/list/helpers.js
index 435ca36047e..435ca36047e 100644
--- a/spec/javascripts/releases/stores/modules/list/helpers.js
+++ b/spec/frontend/releases/stores/modules/list/helpers.js
diff --git a/spec/javascripts/releases/stores/modules/list/mutations_spec.js b/spec/frontend/releases/stores/modules/list/mutations_spec.js
index 3035b916ff6..3035b916ff6 100644
--- a/spec/javascripts/releases/stores/modules/list/mutations_spec.js
+++ b/spec/frontend/releases/stores/modules/list/mutations_spec.js
diff --git a/spec/frontend/reports/components/grouped_test_reports_app_spec.js b/spec/frontend/reports/components/grouped_test_reports_app_spec.js
index 1a01db391da..6a402277f52 100644
--- a/spec/frontend/reports/components/grouped_test_reports_app_spec.js
+++ b/spec/frontend/reports/components/grouped_test_reports_app_spec.js
@@ -1,260 +1,214 @@
-import Vue from 'vue';
-import MockAdapter from 'axios-mock-adapter';
-import axios from '~/lib/utils/axios_utils';
-import state from '~/reports/store/state';
-import component from '~/reports/components/grouped_test_reports_app.vue';
-import mountComponent from '../../helpers/vue_mount_component_helper';
+import { mount, createLocalVue } from '@vue/test-utils';
+import Vuex from 'vuex';
+import GroupedTestReportsApp from '~/reports/components/grouped_test_reports_app.vue';
+import store from '~/reports/store';
+
import { failedReport } from '../mock_data/mock_data';
+import successTestReports from '../mock_data/no_failures_report.json';
import newFailedTestReports from '../mock_data/new_failures_report.json';
import newErrorsTestReports from '../mock_data/new_errors_report.json';
-import successTestReports from '../mock_data/no_failures_report.json';
import mixedResultsTestReports from '../mock_data/new_and_fixed_failures_report.json';
import resolvedFailures from '../mock_data/resolved_failures.json';
-describe('Grouped Test Reports App', () => {
- let vm;
- let mock;
- const Component = Vue.extend(component);
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+describe('Grouped test reports app', () => {
+ const endpoint = 'endpoint.json';
+ const Component = localVue.extend(GroupedTestReportsApp);
+ let wrapper;
+ let mockStore;
+
+ const mountComponent = () => {
+ wrapper = mount(Component, {
+ store: mockStore,
+ localVue,
+ propsData: {
+ endpoint,
+ },
+ methods: {
+ fetchReports: () => {},
+ },
+ });
+ };
+
+ const setReports = reports => {
+ mockStore.state.status = reports.status;
+ mockStore.state.summary = reports.summary;
+ mockStore.state.reports = reports.suites;
+ };
+
+ const findHeader = () => wrapper.find('[data-testid="report-section-code-text"]');
+ const findSummaryDescription = () => wrapper.find('[data-testid="test-summary-row-description"]');
+ const findIssueDescription = () => wrapper.find('[data-testid="test-issue-body-description"]');
+ const findAllIssueDescriptions = () =>
+ wrapper.findAll('[data-testid="test-issue-body-description"]');
beforeEach(() => {
- mock = new MockAdapter(axios);
+ mockStore = store();
+ mountComponent();
});
afterEach(() => {
- vm.$store.replaceState(state());
- vm.$destroy();
- mock.restore();
+ wrapper.destroy();
+ wrapper = null;
});
describe('with success result', () => {
beforeEach(() => {
- mock.onGet('test_results.json').reply(200, successTestReports, {});
- vm = mountComponent(Component, {
- endpoint: 'test_results.json',
- });
+ setReports(successTestReports);
+ mountComponent();
});
- it('renders success summary text', done => {
- setImmediate(() => {
- expect(vm.$el.querySelector('.gl-spinner')).toBeNull();
- expect(vm.$el.querySelector('.js-code-text').textContent.trim()).toEqual(
- 'Test summary contained no changed test results out of 11 total tests',
- );
-
- expect(vm.$el.textContent).toContain(
- 'rspec:pg found no changed test results out of 8 total tests',
- );
-
- expect(vm.$el.textContent).toContain(
- 'java ant found no changed test results out of 3 total tests',
- );
- done();
- });
+ it('renders success summary text', () => {
+ expect(findHeader().text()).toBe(
+ 'Test summary contained no changed test results out of 11 total tests',
+ );
});
});
- describe('with 204 result', () => {
+ describe('with new failed result', () => {
beforeEach(() => {
- mock.onGet('test_results.json').reply(204, {}, {});
- vm = mountComponent(Component, {
- endpoint: 'test_results.json',
- });
+ setReports(newFailedTestReports);
+ mountComponent();
});
- it('renders success summary text', done => {
- setImmediate(() => {
- expect(vm.$el.querySelector('.gl-spinner')).not.toBeNull();
- expect(vm.$el.querySelector('.js-code-text').textContent.trim()).toEqual(
- 'Test summary results are being parsed',
- );
-
- done();
- });
+ it('renders failed summary text', () => {
+ expect(findHeader().text()).toBe('Test summary contained 2 failed out of 11 total tests');
});
- });
- describe('with new failed result', () => {
- beforeEach(() => {
- mock.onGet('test_results.json').reply(200, newFailedTestReports, {});
- vm = mountComponent(Component, {
- endpoint: 'test_results.json',
- });
+ it('renders failed test suite', () => {
+ expect(findSummaryDescription().text()).toContain(
+ 'rspec:pg found 2 failed out of 8 total tests',
+ );
});
- it('renders failed summary text + new badge', done => {
- setImmediate(() => {
- expect(vm.$el.querySelector('.gl-spinner')).toBeNull();
- expect(vm.$el.querySelector('.js-code-text').textContent.trim()).toEqual(
- 'Test summary contained 2 failed out of 11 total tests',
- );
-
- expect(vm.$el.textContent).toContain('rspec:pg found 2 failed out of 8 total tests');
-
- expect(vm.$el.textContent).toContain('New');
- expect(vm.$el.textContent).toContain(
- 'java ant found no changed test results out of 3 total tests',
- );
- done();
- });
+ it('renders failed issue in list', () => {
+ expect(findIssueDescription().text()).toContain('New');
+ expect(findIssueDescription().text()).toContain(
+ 'Test#sum when a is 1 and b is 2 returns summary',
+ );
});
});
describe('with new error result', () => {
beforeEach(() => {
- mock.onGet('test_results.json').reply(200, newErrorsTestReports, {});
- vm = mountComponent(Component, {
- endpoint: 'test_results.json',
- });
+ setReports(newErrorsTestReports);
+ mountComponent();
+ });
+
+ it('renders error summary text', () => {
+ expect(findHeader().text()).toBe('Test summary contained 2 errors out of 11 total tests');
+ });
+
+ it('renders error test suite', () => {
+ expect(findSummaryDescription().text()).toContain(
+ 'karma found 2 errors out of 3 total tests',
+ );
});
- it('renders error summary text + new badge', done => {
- setImmediate(() => {
- expect(vm.$el.querySelector('.gl-spinner')).toBeNull();
- expect(vm.$el.querySelector('.js-code-text').textContent.trim()).toEqual(
- 'Test summary contained 2 errors out of 11 total tests',
- );
-
- expect(vm.$el.textContent).toContain('karma found 2 errors out of 3 total tests');
-
- expect(vm.$el.textContent).toContain('New');
- expect(vm.$el.textContent).toContain(
- 'rspec:pg found no changed test results out of 8 total tests',
- );
- done();
- });
+ it('renders error issue in list', () => {
+ expect(findIssueDescription().text()).toContain('New');
+ expect(findIssueDescription().text()).toContain(
+ 'Test#sum when a is 1 and b is 2 returns summary',
+ );
});
});
describe('with mixed results', () => {
beforeEach(() => {
- mock.onGet('test_results.json').reply(200, mixedResultsTestReports, {});
- vm = mountComponent(Component, {
- endpoint: 'test_results.json',
- });
+ setReports(mixedResultsTestReports);
+ mountComponent();
+ });
+
+ it('renders summary text', () => {
+ expect(findHeader().text()).toBe(
+ 'Test summary contained 2 failed and 2 fixed test results out of 11 total tests',
+ );
});
- it('renders summary text', done => {
- setImmediate(() => {
- expect(vm.$el.querySelector('.gl-spinner')).toBeNull();
- expect(vm.$el.querySelector('.js-code-text').textContent.trim()).toEqual(
- 'Test summary contained 2 failed and 2 fixed test results out of 11 total tests',
- );
-
- expect(vm.$el.textContent).toContain(
- 'rspec:pg found 1 failed and 2 fixed test results out of 8 total tests',
- );
-
- expect(vm.$el.textContent).toContain('New');
- expect(vm.$el.textContent).toContain(' java ant found 1 failed out of 3 total tests');
- done();
- });
+ it('renders failed test suite', () => {
+ expect(findSummaryDescription().text()).toContain(
+ 'rspec:pg found 1 failed and 2 fixed test results out of 8 total tests',
+ );
+ });
+
+ it('renders failed issue in list', () => {
+ expect(findIssueDescription().text()).toContain('New');
+ expect(findIssueDescription().text()).toContain(
+ 'Test#subtract when a is 2 and b is 1 returns correct result',
+ );
});
});
describe('with resolved failures and resolved errors', () => {
beforeEach(() => {
- mock.onGet('test_results.json').reply(200, resolvedFailures, {});
- vm = mountComponent(Component, {
- endpoint: 'test_results.json',
- });
+ setReports(resolvedFailures);
+ mountComponent();
});
- it('renders summary text', done => {
- setImmediate(() => {
- expect(vm.$el.querySelector('.gl-spinner')).toBeNull();
- expect(vm.$el.querySelector('.js-code-text').textContent.trim()).toEqual(
- 'Test summary contained 4 fixed test results out of 11 total tests',
- );
-
- expect(vm.$el.textContent).toContain(
- 'rspec:pg found 4 fixed test results out of 8 total tests',
- );
- done();
- });
+ it('renders summary text', () => {
+ expect(findHeader().text()).toBe(
+ 'Test summary contained 4 fixed test results out of 11 total tests',
+ );
+ });
+
+ it('renders resolved test suite', () => {
+ expect(findSummaryDescription().text()).toContain(
+ 'rspec:pg found 4 fixed test results out of 8 total tests',
+ );
});
- it('renders resolved failures', done => {
- setImmediate(() => {
- expect(vm.$el.querySelector('.report-block-container').textContent).toContain(
- resolvedFailures.suites[0].resolved_failures[0].name,
- );
-
- expect(vm.$el.querySelector('.report-block-container').textContent).toContain(
- resolvedFailures.suites[0].resolved_failures[1].name,
- );
- done();
- });
+ it('renders resolved failures', () => {
+ expect(findIssueDescription().text()).toContain(
+ resolvedFailures.suites[0].resolved_failures[0].name,
+ );
});
- it('renders resolved errors', done => {
- setImmediate(() => {
- expect(vm.$el.querySelector('.report-block-container').textContent).toContain(
- resolvedFailures.suites[0].resolved_errors[0].name,
- );
-
- expect(vm.$el.querySelector('.report-block-container').textContent).toContain(
- resolvedFailures.suites[0].resolved_errors[1].name,
- );
- done();
- });
+ it('renders resolved errors', () => {
+ expect(
+ findAllIssueDescriptions()
+ .at(2)
+ .text(),
+ ).toContain(resolvedFailures.suites[0].resolved_errors[0].name);
});
});
describe('with a report that failed to load', () => {
beforeEach(() => {
- mock.onGet('test_results.json').reply(200, failedReport, {});
- vm = mountComponent(Component, {
- endpoint: 'test_results.json',
- });
+ setReports(failedReport);
+ mountComponent();
});
- it('renders an error status for the report', done => {
- setImmediate(() => {
- const { name } = failedReport.suites[0];
+ it('renders an error status for the report', () => {
+ const { name } = failedReport.suites[0];
- expect(vm.$el.querySelector('.report-block-list-issue').textContent).toContain(
- `An error occurred while loading ${name} results`,
- );
- done();
- });
+ expect(findSummaryDescription().text()).toContain(
+ `An error occurred while loading ${name} result`,
+ );
});
});
describe('with error', () => {
beforeEach(() => {
- mock.onGet('test_results.json').reply(500, {}, {});
- vm = mountComponent(Component, {
- endpoint: 'test_results.json',
- });
+ mockStore.state.isLoading = false;
+ mockStore.state.hasError = true;
+ mountComponent();
});
- it('renders loading summary text with loading icon', done => {
- setImmediate(() => {
- expect(vm.$el.querySelector('.js-code-text').textContent.trim()).toEqual(
- 'Test summary failed loading results',
- );
- done();
- });
+ it('renders loading state', () => {
+ expect(findHeader().text()).toBe('Test summary failed loading results');
});
});
describe('while loading', () => {
beforeEach(() => {
- mock.onGet('test_results.json').reply(200, {}, {});
- vm = mountComponent(Component, {
- endpoint: 'test_results.json',
- });
+ mockStore.state.isLoading = true;
+ mountComponent();
});
- it('renders loading summary text with loading icon', done => {
- expect(vm.$el.querySelector('.gl-spinner')).not.toBeNull();
- expect(vm.$el.querySelector('.js-code-text').textContent.trim()).toEqual(
- 'Test summary results are being parsed',
- );
-
- setImmediate(() => {
- done();
- });
+ it('renders loading state', () => {
+ expect(findHeader().text()).toBe('Test summary results are being parsed');
});
});
});
diff --git a/spec/frontend/reports/mock_data/new_errors_report.json b/spec/frontend/reports/mock_data/new_errors_report.json
index cebf98fdb63..6573d23ee50 100644
--- a/spec/frontend/reports/mock_data/new_errors_report.json
+++ b/spec/frontend/reports/mock_data/new_errors_report.json
@@ -2,16 +2,6 @@
"summary": { "total": 11, "resolved": 0, "errored": 2, "failed": 0 },
"suites": [
{
- "name": "rspec:pg",
- "summary": { "total": 8, "resolved": 0, "errored": 0, "failed": 0 },
- "new_failures": [],
- "resolved_failures": [],
- "existing_failures": [],
- "new_errors": [],
- "resolved_errors": [],
- "existing_errors": []
- },
- {
"name": "karma",
"summary": { "total": 3, "resolved": 0, "errored": 2, "failed": 0 },
"new_failures": [],
@@ -33,6 +23,16 @@
],
"resolved_errors": [],
"existing_errors": []
+ },
+ {
+ "name": "rspec:pg",
+ "summary": { "total": 8, "resolved": 0, "errored": 0, "failed": 0 },
+ "new_failures": [],
+ "resolved_failures": [],
+ "existing_failures": [],
+ "new_errors": [],
+ "resolved_errors": [],
+ "existing_errors": []
}
]
}
diff --git a/spec/frontend/right_sidebar_spec.js b/spec/frontend/right_sidebar_spec.js
new file mode 100644
index 00000000000..d80d80152a5
--- /dev/null
+++ b/spec/frontend/right_sidebar_spec.js
@@ -0,0 +1,87 @@
+import $ from 'jquery';
+import MockAdapter from 'axios-mock-adapter';
+import '~/commons/bootstrap';
+import axios from '~/lib/utils/axios_utils';
+import Sidebar from '~/right_sidebar';
+
+let $aside = null;
+let $toggle = null;
+let $icon = null;
+let $page = null;
+let $labelsIcon = null;
+
+const assertSidebarState = state => {
+ const shouldBeExpanded = state === 'expanded';
+ const shouldBeCollapsed = state === 'collapsed';
+ expect($aside.hasClass('right-sidebar-expanded')).toBe(shouldBeExpanded);
+ expect($page.hasClass('right-sidebar-expanded')).toBe(shouldBeExpanded);
+ expect($icon.hasClass('fa-angle-double-right')).toBe(shouldBeExpanded);
+ expect($aside.hasClass('right-sidebar-collapsed')).toBe(shouldBeCollapsed);
+ expect($page.hasClass('right-sidebar-collapsed')).toBe(shouldBeCollapsed);
+ expect($icon.hasClass('fa-angle-double-left')).toBe(shouldBeCollapsed);
+};
+
+describe('RightSidebar', () => {
+ describe('fixture tests', () => {
+ const fixtureName = 'issues/open-issue.html';
+ preloadFixtures(fixtureName);
+ let mock;
+
+ beforeEach(() => {
+ loadFixtures(fixtureName);
+ mock = new MockAdapter(axios);
+ new Sidebar(); // eslint-disable-line no-new
+ $aside = $('.right-sidebar');
+ $page = $('.layout-page');
+ $icon = $aside.find('i');
+ $toggle = $aside.find('.js-sidebar-toggle');
+ $labelsIcon = $aside.find('.sidebar-collapsed-icon');
+ });
+
+ afterEach(() => {
+ mock.restore();
+ });
+
+ it('should expand/collapse the sidebar when arrow is clicked', () => {
+ assertSidebarState('expanded');
+ $toggle.click();
+ assertSidebarState('collapsed');
+ $toggle.click();
+ assertSidebarState('expanded');
+ });
+
+ it('should float over the page and when sidebar icons clicked', () => {
+ $labelsIcon.click();
+ assertSidebarState('expanded');
+ });
+
+ it('should collapse when the icon arrow clicked while it is floating on page', () => {
+ $labelsIcon.click();
+ assertSidebarState('expanded');
+ $toggle.click();
+ assertSidebarState('collapsed');
+ });
+
+ it('should broadcast todo:toggle event when add todo clicked', done => {
+ const todos = getJSONFixture('todos/todos.json');
+ mock.onPost(/(.*)\/todos$/).reply(200, todos);
+
+ const todoToggleSpy = jest.fn();
+ $(document).on('todo:toggle', todoToggleSpy);
+
+ $('.issuable-sidebar-header .js-issuable-todo').click();
+
+ setImmediate(() => {
+ expect(todoToggleSpy.mock.calls.length).toEqual(1);
+
+ done();
+ });
+ });
+
+ it('should not hide collapsed icons', () => {
+ [].forEach.call(document.querySelectorAll('.sidebar-collapsed-icon'), el => {
+ expect(el.querySelector('.fa, svg').classList.contains('hidden')).toBeFalsy();
+ });
+ });
+ });
+});
diff --git a/spec/frontend/shortcuts_spec.js b/spec/frontend/shortcuts_spec.js
new file mode 100644
index 00000000000..3d16074154c
--- /dev/null
+++ b/spec/frontend/shortcuts_spec.js
@@ -0,0 +1,46 @@
+import $ from 'jquery';
+import Shortcuts from '~/behaviors/shortcuts/shortcuts';
+
+describe('Shortcuts', () => {
+ const fixtureName = 'snippets/show.html';
+ const createEvent = (type, target) =>
+ $.Event(type, {
+ target,
+ });
+
+ preloadFixtures(fixtureName);
+
+ describe('toggleMarkdownPreview', () => {
+ beforeEach(() => {
+ loadFixtures(fixtureName);
+
+ jest.spyOn(document.querySelector('.js-new-note-form .js-md-preview-button'), 'focus');
+ jest.spyOn(document.querySelector('.edit-note .js-md-preview-button'), 'focus');
+
+ new Shortcuts(); // eslint-disable-line no-new
+ });
+
+ it('focuses preview button in form', () => {
+ Shortcuts.toggleMarkdownPreview(
+ createEvent('KeyboardEvent', document.querySelector('.js-new-note-form .js-note-text')),
+ );
+
+ expect(
+ document.querySelector('.js-new-note-form .js-md-preview-button').focus,
+ ).toHaveBeenCalled();
+ });
+
+ it('focues preview button inside edit comment form', () => {
+ document.querySelector('.js-note-edit').click();
+
+ Shortcuts.toggleMarkdownPreview(
+ createEvent('KeyboardEvent', document.querySelector('.edit-note .js-note-text')),
+ );
+
+ expect(
+ document.querySelector('.js-new-note-form .js-md-preview-button').focus,
+ ).not.toHaveBeenCalled();
+ expect(document.querySelector('.edit-note .js-md-preview-button').focus).toHaveBeenCalled();
+ });
+ });
+});
diff --git a/spec/frontend/sidebar/confidential_issue_sidebar_spec.js b/spec/frontend/sidebar/confidential_issue_sidebar_spec.js
index e7a64ec5ed9..fe7c3aadeeb 100644
--- a/spec/frontend/sidebar/confidential_issue_sidebar_spec.js
+++ b/spec/frontend/sidebar/confidential_issue_sidebar_spec.js
@@ -6,11 +6,14 @@ import SidebarService from '~/sidebar/services/sidebar_service';
import createFlash from '~/flash';
import RecaptchaModal from '~/vue_shared/components/recaptcha_modal.vue';
import createStore from '~/notes/stores';
+import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
jest.mock('~/flash');
jest.mock('~/sidebar/services/sidebar_service');
describe('Confidential Issue Sidebar Block', () => {
+ useMockLocationHelper();
+
let wrapper;
const findRecaptchaModal = () => wrapper.find(RecaptchaModal);
@@ -43,10 +46,6 @@ describe('Confidential Issue Sidebar Block', () => {
});
};
- beforeEach(() => {
- jest.spyOn(window.location, 'reload').mockImplementation();
- });
-
afterEach(() => {
wrapper.destroy();
});
diff --git a/spec/frontend/snippets/components/__snapshots__/snippet_blob_edit_spec.js.snap b/spec/frontend/snippets/components/__snapshots__/snippet_blob_edit_spec.js.snap
index 301ec5652a9..959bc24eef6 100644
--- a/spec/frontend/snippets/components/__snapshots__/snippet_blob_edit_spec.js.snap
+++ b/spec/frontend/snippets/components/__snapshots__/snippet_blob_edit_spec.js.snap
@@ -12,7 +12,7 @@ exports[`Snippet Blob Edit component rendering matches the snapshot 1`] = `
class="file-holder snippet"
>
<blob-header-edit-stub
- data-qa-selector="snippet_file_name"
+ data-qa-selector="file_name_field"
value="lorem.txt"
/>
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 9fd4cba5b87..297ad16b681 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
@@ -4,7 +4,9 @@ exports[`Snippet Description Edit component rendering matches the snapshot 1`] =
<div
class="form-group js-description-input"
>
- <label>
+ <label
+ for="snippet-description"
+ >
Description (optional)
</label>
@@ -21,27 +23,67 @@ exports[`Snippet Description Edit component rendering matches the snapshot 1`] =
/>
</div>
- <markdown-field-stub
- addspacingclasses="true"
- canattachfile="true"
- class="js-expanded"
- enableautocomplete="true"
- helppagepath=""
- markdowndocspath="help/"
- markdownpreviewpath="foo/"
- note="[object Object]"
- quickactionsdocspath=""
- textareavalue=""
+ <div
+ class="js-vue-markdown-field md-area position-relative js-expanded gfm-form"
>
- <textarea
- aria-label="Description"
- class="note-textarea js-gfm-input js-autosize markdown-area"
- data-qa-selector="snippet_description_field"
- data-supports-quick-actions="false"
- dir="auto"
- placeholder="Write a comment or drag your files here…"
+ <markdown-header-stub
+ linecontent=""
/>
- </markdown-field-stub>
+
+ <div
+ class="md-write-holder"
+ >
+ <div
+ class="zen-backdrop div-dropzone-wrapper"
+ >
+ <div
+ class="div-dropzone js-invalid-dropzone"
+ >
+ <textarea
+ aria-label="Description"
+ class="note-textarea js-gfm-input js-autosize markdown-area"
+ data-qa-selector="snippet_description_field"
+ data-supports-quick-actions="false"
+ dir="auto"
+ id="snippet-description"
+ placeholder="Write a comment or drag your files here…"
+ style="overflow-x: hidden; word-wrap: break-word; overflow-y: hidden;"
+ />
+ <div
+ class="div-dropzone-hover"
+ >
+ <i
+ class="fa fa-paperclip div-dropzone-icon"
+ />
+ </div>
+ </div>
+
+ <a
+ aria-label="Leave zen mode"
+ class="zen-control zen-control-leave js-zen-leave gl-text-gray-700"
+ href="#"
+ >
+ <icon-stub
+ name="screen-normal"
+ size="16"
+ />
+ </a>
+
+ <markdown-toolbar-stub
+ canattachfile="true"
+ markdowndocspath="help/"
+ quickactionsdocspath=""
+ />
+ </div>
+ </div>
+
+ <div
+ class="js-vue-md-preview md md-preview-holder"
+ style="display: none;"
+ />
+
+ <!---->
+ </div>
</div>
</div>
`;
diff --git a/spec/frontend/snippets/components/__snapshots__/snippet_description_view_spec.js.snap b/spec/frontend/snippets/components/__snapshots__/snippet_description_view_spec.js.snap
index 9ebc4e81baf..9fb43815cbc 100644
--- a/spec/frontend/snippets/components/__snapshots__/snippet_description_view_spec.js.snap
+++ b/spec/frontend/snippets/components/__snapshots__/snippet_description_view_spec.js.snap
@@ -3,7 +3,7 @@
exports[`Snippet Description component matches the snapshot 1`] = `
<markdown-field-view-stub
class="snippet-description"
- data-qa-selector="snippet_description_field"
+ data-qa-selector="snippet_description_content"
>
<div
class="md js-snippet-description"
diff --git a/spec/frontend/snippets/components/edit_spec.js b/spec/frontend/snippets/components/edit_spec.js
index ba62a0a92ca..83f46dd347f 100644
--- a/spec/frontend/snippets/components/edit_spec.js
+++ b/spec/frontend/snippets/components/edit_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import axios from '~/lib/utils/axios_utils';
+import Flash from '~/flash';
import { GlLoadingIcon } from '@gitlab/ui';
import { joinPaths, redirectTo } from '~/lib/utils/url_utility';
@@ -10,6 +11,7 @@ import SnippetVisibilityEdit from '~/snippets/components/snippet_visibility_edit
import SnippetBlobEdit from '~/snippets/components/snippet_blob_edit.vue';
import TitleField from '~/vue_shared/components/form/title.vue';
import FormFooterActions from '~/vue_shared/components/form/form_footer_actions.vue';
+import { SNIPPET_CREATE_MUTATION_ERROR, SNIPPET_UPDATE_MUTATION_ERROR } from '~/snippets/constants';
import UpdateSnippetMutation from '~/snippets/mutations/updateSnippet.mutation.graphql';
import CreateSnippetMutation from '~/snippets/mutations/createSnippet.mutation.graphql';
@@ -27,6 +29,8 @@ jest.mock('~/lib/utils/url_utility', () => ({
.mockReturnValue('contentApiURL'),
}));
+jest.mock('~/flash');
+
let flashSpy;
const contentMock = 'Foo Bar';
@@ -34,6 +38,10 @@ const rawPathMock = '/foo/bar';
const rawProjectPathMock = '/project/path';
const newlyEditedSnippetUrl = 'http://foo.bar';
const apiError = { message: 'Ufff' };
+const mutationError = 'Bummer';
+
+const attachedFilePath1 = 'foo/bar';
+const attachedFilePath2 = 'alpha/beta';
const defaultProps = {
snippetGid: 'gid://gitlab/PersonalSnippet/42',
@@ -56,10 +64,26 @@ describe('Snippet Edit app', () => {
},
});
+ const resolveMutateWithErrors = jest.fn().mockResolvedValue({
+ data: {
+ updateSnippet: {
+ errors: [mutationError],
+ snippet: {
+ webUrl: newlyEditedSnippetUrl,
+ },
+ },
+ createSnippet: {
+ errors: [mutationError],
+ snippet: null,
+ },
+ },
+ });
+
const rejectMutation = jest.fn().mockRejectedValue(apiError);
const mutationTypes = {
RESOLVE: resolveMutate,
+ RESOLVE_WITH_ERRORS: resolveMutateWithErrors,
REJECT: rejectMutation,
};
@@ -99,8 +123,9 @@ describe('Snippet Edit app', () => {
wrapper.destroy();
});
- const findSubmitButton = () => wrapper.find('[type=submit]');
+ const findSubmitButton = () => wrapper.find('[data-testid="snippet-submit-btn"]');
const findCancellButton = () => wrapper.find('[data-testid="snippet-cancel-btn"]');
+ const clickSubmitBtn = () => wrapper.find('[data-testid="snippet-edit-form"]').trigger('submit');
describe('rendering', () => {
it('renders loader while the query is in flight', () => {
@@ -268,28 +293,131 @@ describe('Snippet Edit app', () => {
},
};
- wrapper.vm.handleFormSubmit();
+ clickSubmitBtn();
+
expect(resolveMutate).toHaveBeenCalledWith(mutationPayload);
});
it('redirects to snippet view on successful mutation', () => {
createComponent();
- wrapper.vm.handleFormSubmit();
+ clickSubmitBtn();
+
return waitForPromises().then(() => {
expect(redirectTo).toHaveBeenCalledWith(newlyEditedSnippetUrl);
});
});
+ it.each`
+ newSnippet | projectPath | mutationName
+ ${true} | ${rawProjectPathMock} | ${'CreateSnippetMutation with projectPath'}
+ ${true} | ${''} | ${'CreateSnippetMutation without projectPath'}
+ ${false} | ${rawProjectPathMock} | ${'UpdateSnippetMutation with projectPath'}
+ ${false} | ${''} | ${'UpdateSnippetMutation without projectPath'}
+ `(
+ 'does not redirect to snippet view if the seemingly successful' +
+ ' $mutationName response contains errors',
+ ({ newSnippet, projectPath }) => {
+ createComponent({
+ data: {
+ newSnippet,
+ },
+ props: {
+ ...defaultProps,
+ projectPath,
+ },
+ mutationRes: mutationTypes.RESOLVE_WITH_ERRORS,
+ });
+
+ clickSubmitBtn();
+
+ return waitForPromises().then(() => {
+ expect(redirectTo).not.toHaveBeenCalled();
+ expect(flashSpy).toHaveBeenCalledWith(mutationError);
+ });
+ },
+ );
+
it('flashes an error if mutation failed', () => {
createComponent({
mutationRes: mutationTypes.REJECT,
});
- wrapper.vm.handleFormSubmit();
+
+ clickSubmitBtn();
+
return waitForPromises().then(() => {
expect(redirectTo).not.toHaveBeenCalled();
expect(flashSpy).toHaveBeenCalledWith(apiError);
});
});
+
+ it.each`
+ isNew | status | expectation
+ ${true} | ${`new`} | ${SNIPPET_CREATE_MUTATION_ERROR.replace('%{err}', '')}
+ ${false} | ${`existing`} | ${SNIPPET_UPDATE_MUTATION_ERROR.replace('%{err}', '')}
+ `(
+ `renders the correct error message if mutation fails for $status snippet`,
+ ({ isNew, expectation }) => {
+ createComponent({
+ data: {
+ newSnippet: isNew,
+ },
+ mutationRes: mutationTypes.REJECT,
+ });
+
+ clickSubmitBtn();
+
+ return waitForPromises().then(() => {
+ expect(Flash).toHaveBeenCalledWith(expect.stringContaining(expectation));
+ });
+ },
+ );
+ });
+
+ describe('correctly includes attached files into the mutation', () => {
+ const createMutationPayload = expectation => {
+ return expect.objectContaining({
+ variables: {
+ input: expect.objectContaining({ uploadedFiles: expectation }),
+ },
+ });
+ };
+
+ const updateMutationPayload = () => {
+ return expect.objectContaining({
+ variables: {
+ input: expect.not.objectContaining({ uploadedFiles: expect.anything() }),
+ },
+ });
+ };
+
+ it.each`
+ paths | expectation
+ ${[attachedFilePath1]} | ${[attachedFilePath1]}
+ ${[attachedFilePath1, attachedFilePath2]} | ${[attachedFilePath1, attachedFilePath2]}
+ ${[]} | ${[]}
+ `(`correctly sends paths for $paths.length files`, ({ paths, expectation }) => {
+ createComponent({
+ data: {
+ newSnippet: true,
+ },
+ });
+
+ const fixtures = paths.map(path => {
+ return path ? `<input name="files[]" value="${path}">` : undefined;
+ });
+ wrapper.vm.$el.innerHTML += fixtures.join('');
+
+ clickSubmitBtn();
+
+ expect(resolveMutate).toHaveBeenCalledWith(createMutationPayload(expectation));
+ });
+
+ it(`neither fails nor sends 'uploadedFiles' to update mutation`, () => {
+ createComponent();
+
+ clickSubmitBtn();
+ expect(resolveMutate).toHaveBeenCalledWith(updateMutationPayload());
+ });
});
});
});
diff --git a/spec/frontend/snippets/components/snippet_blob_view_spec.js b/spec/frontend/snippets/components/snippet_blob_view_spec.js
index d06489cffa9..e4d8ee9b7df 100644
--- a/spec/frontend/snippets/components/snippet_blob_view_spec.js
+++ b/spec/frontend/snippets/components/snippet_blob_view_spec.js
@@ -3,7 +3,11 @@ import SnippetBlobView from '~/snippets/components/snippet_blob_view.vue';
import BlobHeader from '~/blob/components/blob_header.vue';
import BlobEmbeddable from '~/blob/components/blob_embeddable.vue';
import BlobContent from '~/blob/components/blob_content.vue';
-import { BLOB_RENDER_EVENT_LOAD, BLOB_RENDER_EVENT_SHOW_SOURCE } from '~/blob/components/constants';
+import {
+ BLOB_RENDER_EVENT_LOAD,
+ BLOB_RENDER_EVENT_SHOW_SOURCE,
+ BLOB_RENDER_ERRORS,
+} from '~/blob/components/constants';
import { RichViewer, SimpleViewer } from '~/vue_shared/components/blob_viewers';
import {
SNIPPET_VISIBILITY_PRIVATE,
@@ -109,6 +113,20 @@ describe('Blob Embeddable', () => {
});
});
+ it('passes information about render error down to blob header', () => {
+ createComponent({
+ blob: {
+ ...BlobMock,
+ simpleViewer: {
+ ...SimpleViewerMock,
+ renderError: BLOB_RENDER_ERRORS.REASONS.COLLAPSED.id,
+ },
+ },
+ });
+
+ expect(wrapper.find(BlobHeader).props('hasRenderError')).toBe(true);
+ });
+
describe('URLS with hash', () => {
beforeEach(() => {
window.location.hash = '#LC2';
diff --git a/spec/frontend/snippets/components/snippet_description_edit_spec.js b/spec/frontend/snippets/components/snippet_description_edit_spec.js
index c5e667747c6..816ab4e48de 100644
--- a/spec/frontend/snippets/components/snippet_description_edit_spec.js
+++ b/spec/frontend/snippets/components/snippet_description_edit_spec.js
@@ -1,4 +1,5 @@
import SnippetDescriptionEdit from '~/snippets/components/snippet_description_edit.vue';
+import MarkdownField from '~/vue_shared/components/markdown/field.vue';
import { shallowMount } from '@vue/test-utils';
describe('Snippet Description Edit component', () => {
@@ -15,6 +16,9 @@ describe('Snippet Description Edit component', () => {
markdownPreviewPath,
markdownDocsPath,
},
+ stubs: {
+ MarkdownField,
+ },
});
}
diff --git a/spec/frontend/static_site_editor/components/edit_area_spec.js b/spec/frontend/static_site_editor/components/edit_area_spec.js
index bfe41f65d6e..d7c798e6620 100644
--- a/spec/frontend/static_site_editor/components/edit_area_spec.js
+++ b/spec/frontend/static_site_editor/components/edit_area_spec.js
@@ -5,13 +5,19 @@ import RichContentEditor from '~/vue_shared/components/rich_content_editor/rich_
import EditArea from '~/static_site_editor/components/edit_area.vue';
import PublishToolbar from '~/static_site_editor/components/publish_toolbar.vue';
import EditHeader from '~/static_site_editor/components/edit_header.vue';
+import UnsavedChangesConfirmDialog from '~/static_site_editor/components/unsaved_changes_confirm_dialog.vue';
-import { sourceContentTitle as title, sourceContent as content, returnUrl } from '../mock_data';
+import {
+ sourceContentTitle as title,
+ sourceContent as content,
+ sourceContentBody as body,
+ returnUrl,
+} from '../mock_data';
describe('~/static_site_editor/components/edit_area.vue', () => {
let wrapper;
const savingChanges = true;
- const newContent = `new ${content}`;
+ const newBody = `new ${body}`;
const buildWrapper = (propsData = {}) => {
wrapper = shallowMount(EditArea, {
@@ -28,6 +34,7 @@ describe('~/static_site_editor/components/edit_area.vue', () => {
const findEditHeader = () => wrapper.find(EditHeader);
const findRichContentEditor = () => wrapper.find(RichContentEditor);
const findPublishToolbar = () => wrapper.find(PublishToolbar);
+ const findUnsavedChangesConfirmDialog = () => wrapper.find(UnsavedChangesConfirmDialog);
beforeEach(() => {
buildWrapper();
@@ -44,29 +51,40 @@ describe('~/static_site_editor/components/edit_area.vue', () => {
it('renders rich content editor', () => {
expect(findRichContentEditor().exists()).toBe(true);
- expect(findRichContentEditor().props('value')).toBe(content);
+ expect(findRichContentEditor().props('value')).toBe(body);
});
it('renders publish toolbar', () => {
expect(findPublishToolbar().exists()).toBe(true);
- expect(findPublishToolbar().props('returnUrl')).toBe(returnUrl);
- expect(findPublishToolbar().props('savingChanges')).toBe(savingChanges);
- expect(findPublishToolbar().props('saveable')).toBe(false);
+ expect(findPublishToolbar().props()).toMatchObject({
+ returnUrl,
+ savingChanges,
+ saveable: false,
+ });
+ });
+
+ it('renders unsaved changes confirm dialog', () => {
+ expect(findUnsavedChangesConfirmDialog().exists()).toBe(true);
+ expect(findUnsavedChangesConfirmDialog().props('modified')).toBe(false);
});
describe('when content changes', () => {
beforeEach(() => {
- findRichContentEditor().vm.$emit('input', newContent);
+ findRichContentEditor().vm.$emit('input', newBody);
return wrapper.vm.$nextTick();
});
- it('sets publish toolbar as saveable when content changes', () => {
+ it('sets publish toolbar as saveable', () => {
expect(findPublishToolbar().props('saveable')).toBe(true);
});
+ it('sets unsaved changes confirm dialog as modified', () => {
+ expect(findUnsavedChangesConfirmDialog().props('modified')).toBe(true);
+ });
+
it('sets publish toolbar as not saveable when content changes are rollback', () => {
- findRichContentEditor().vm.$emit('input', content);
+ findRichContentEditor().vm.$emit('input', body);
return wrapper.vm.$nextTick().then(() => {
expect(findPublishToolbar().props('saveable')).toBe(false);
diff --git a/spec/frontend/static_site_editor/components/unsaved_changes_confirm_dialog_spec.js b/spec/frontend/static_site_editor/components/unsaved_changes_confirm_dialog_spec.js
new file mode 100644
index 00000000000..9b8b22da693
--- /dev/null
+++ b/spec/frontend/static_site_editor/components/unsaved_changes_confirm_dialog_spec.js
@@ -0,0 +1,44 @@
+import { shallowMount } from '@vue/test-utils';
+
+import UnsavedChangesConfirmDialog from '~/static_site_editor/components/unsaved_changes_confirm_dialog.vue';
+
+describe('static_site_editor/components/unsaved_changes_confirm_dialog', () => {
+ let wrapper;
+ let event;
+ let returnValueSetter;
+
+ const buildWrapper = (propsData = {}) => {
+ wrapper = shallowMount(UnsavedChangesConfirmDialog, {
+ propsData,
+ });
+ };
+
+ beforeEach(() => {
+ event = new Event('beforeunload');
+
+ jest.spyOn(event, 'preventDefault');
+ returnValueSetter = jest.spyOn(event, 'returnValue', 'set');
+ });
+
+ afterEach(() => {
+ event.preventDefault.mockRestore();
+ returnValueSetter.mockRestore();
+ wrapper.destroy();
+ });
+
+ it('displays confirmation dialog when modified = true', () => {
+ buildWrapper({ modified: true });
+ window.dispatchEvent(event);
+
+ expect(event.preventDefault).toHaveBeenCalled();
+ expect(returnValueSetter).toHaveBeenCalledWith('');
+ });
+
+ it('does not display confirmation dialog when modified = false', () => {
+ buildWrapper();
+ window.dispatchEvent(event);
+
+ expect(event.preventDefault).not.toHaveBeenCalled();
+ expect(returnValueSetter).not.toHaveBeenCalled();
+ });
+});
diff --git a/spec/frontend/static_site_editor/mock_data.js b/spec/frontend/static_site_editor/mock_data.js
index 371695e913e..422048a5f69 100644
--- a/spec/frontend/static_site_editor/mock_data.js
+++ b/spec/frontend/static_site_editor/mock_data.js
@@ -1,16 +1,17 @@
-export const sourceContent = `
----
+export const sourceContentHeader = `---
layout: handbook-page-toc
title: Handbook
twitter_image: '/images/tweets/handbook-gitlab.png'
----
-
-## On this page
+---`;
+export const sourceContentSpacing = `
+`;
+export const sourceContentBody = `## On this page
{:.no_toc .hidden-md .hidden-lg}
- TOC
{:toc .hidden-md .hidden-lg}
`;
+export const sourceContent = `${sourceContentHeader}${sourceContentSpacing}${sourceContentBody}`;
export const sourceContentTitle = 'Handbook';
export const username = 'gitlabuser';
diff --git a/spec/frontend/static_site_editor/pages/home_spec.js b/spec/frontend/static_site_editor/pages/home_spec.js
index 8c9c54f593e..d3ee70785d1 100644
--- a/spec/frontend/static_site_editor/pages/home_spec.js
+++ b/spec/frontend/static_site_editor/pages/home_spec.js
@@ -7,6 +7,8 @@ import InvalidContentMessage from '~/static_site_editor/components/invalid_conte
import SubmitChangesError from '~/static_site_editor/components/submit_changes_error.vue';
import submitContentChangesMutation from '~/static_site_editor/graphql/mutations/submit_content_changes.mutation.graphql';
import { SUCCESS_ROUTE } from '~/static_site_editor/router/constants';
+import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
+import { TRACKING_ACTION_INITIALIZE_EDITOR } from '~/static_site_editor/constants';
import {
projectId as project,
@@ -17,6 +19,7 @@ import {
username,
savedContentMeta,
submitChangesError,
+ trackingCategory,
} from '../mock_data';
const localVue = createLocalVue();
@@ -29,6 +32,7 @@ describe('static_site_editor/pages/home', () => {
let $apollo;
let $router;
let mutateMock;
+ let trackingSpy;
const buildApollo = (queries = {}) => {
mutateMock = jest.fn();
@@ -76,10 +80,14 @@ describe('static_site_editor/pages/home', () => {
beforeEach(() => {
buildApollo();
buildRouter();
+
+ document.body.dataset.page = trackingCategory;
+ trackingSpy = mockTracking(document.body.dataset.page, undefined, jest.spyOn);
});
afterEach(() => {
wrapper.destroy();
+ unmockTracking();
wrapper = null;
$apollo = null;
});
@@ -208,4 +216,12 @@ describe('static_site_editor/pages/home', () => {
expect($router.push).toHaveBeenCalledWith(SUCCESS_ROUTE);
});
});
+
+ it('tracks when editor is initialized on the mounted lifecycle hook', () => {
+ buildWrapper();
+ expect(trackingSpy).toHaveBeenCalledWith(
+ document.body.dataset.page,
+ TRACKING_ACTION_INITIALIZE_EDITOR,
+ );
+ });
});
diff --git a/spec/frontend/static_site_editor/services/parse_source_file_spec.js b/spec/frontend/static_site_editor/services/parse_source_file_spec.js
new file mode 100644
index 00000000000..fe99c4f5334
--- /dev/null
+++ b/spec/frontend/static_site_editor/services/parse_source_file_spec.js
@@ -0,0 +1,64 @@
+import {
+ sourceContent as content,
+ sourceContentHeader as header,
+ sourceContentSpacing as spacing,
+ sourceContentBody as body,
+} from '../mock_data';
+
+import parseSourceFile from '~/static_site_editor/services/parse_source_file';
+
+describe('parseSourceFile', () => {
+ const contentSimple = content;
+ const contentComplex = [content, content, content].join('');
+
+ describe('the editable shape and its expected values', () => {
+ it.each`
+ sourceContent | sourceHeader | sourceSpacing | sourceBody | desc
+ ${contentSimple} | ${header} | ${spacing} | ${body} | ${'extracts header'}
+ ${contentComplex} | ${header} | ${spacing} | ${[body, content, content].join('')} | ${'extracts body'}
+ `('$desc', ({ sourceContent, sourceHeader, sourceSpacing, sourceBody }) => {
+ const { editable } = parseSourceFile(sourceContent);
+
+ expect(editable).toMatchObject({
+ raw: sourceContent,
+ header: sourceHeader,
+ spacing: sourceSpacing,
+ body: sourceBody,
+ });
+ });
+
+ it('returns the same front matter regardless of front matter duplication', () => {
+ const parsedSourceSimple = parseSourceFile(contentSimple);
+ const parsedSourceComplex = parseSourceFile(contentComplex);
+
+ expect(parsedSourceSimple.editable.header).toBe(parsedSourceComplex.editable.header);
+ });
+ });
+
+ describe('editable body to raw content default and changes', () => {
+ it.each`
+ sourceContent | desc
+ ${contentSimple} | ${'returns false by default for both raw and body'}
+ ${contentComplex} | ${'returns false by default for both raw and body'}
+ `('$desc', ({ sourceContent }) => {
+ const parsedSource = parseSourceFile(sourceContent);
+
+ expect(parsedSource.isModifiedRaw()).toBe(false);
+ expect(parsedSource.isModifiedBody()).toBe(false);
+ });
+
+ it.each`
+ sourceContent | editableKey | syncKey | isModifiedKey | desc
+ ${contentSimple} | ${'body'} | ${'syncRaw'} | ${'isModifiedRaw'} | ${'returns true after modification and sync'}
+ ${contentSimple} | ${'raw'} | ${'syncBody'} | ${'isModifiedBody'} | ${'returns true after modification and sync'}
+ ${contentComplex} | ${'body'} | ${'syncRaw'} | ${'isModifiedRaw'} | ${'returns true after modification and sync'}
+ ${contentComplex} | ${'raw'} | ${'syncBody'} | ${'isModifiedBody'} | ${'returns true after modification and sync'}
+ `('$desc', ({ sourceContent, editableKey, syncKey, isModifiedKey }) => {
+ const parsedSource = parseSourceFile(sourceContent);
+ parsedSource.editable[editableKey] += 'Added content';
+ parsedSource[syncKey]();
+
+ expect(parsedSource[isModifiedKey]()).toBe(true);
+ });
+ });
+});
diff --git a/spec/frontend/static_site_editor/services/submit_content_changes_spec.js b/spec/frontend/static_site_editor/services/submit_content_changes_spec.js
index a1e9ff4ec4c..3636de3fe70 100644
--- a/spec/frontend/static_site_editor/services/submit_content_changes_spec.js
+++ b/spec/frontend/static_site_editor/services/submit_content_changes_spec.js
@@ -8,6 +8,7 @@ import {
SUBMIT_CHANGES_COMMIT_ERROR,
SUBMIT_CHANGES_MERGE_REQUEST_ERROR,
TRACKING_ACTION_CREATE_COMMIT,
+ TRACKING_ACTION_CREATE_MERGE_REQUEST,
} from '~/static_site_editor/constants';
import generateBranchName from '~/static_site_editor/services/generate_branch_name';
import submitContentChanges from '~/static_site_editor/services/submit_content_changes';
@@ -83,15 +84,6 @@ describe('submitContentChanges', () => {
});
});
- it('sends the correct tracking event when committing content changes', () => {
- return submitContentChanges({ username, projectId, sourcePath, content }).then(() => {
- expect(trackingSpy).toHaveBeenCalledWith(
- document.body.dataset.page,
- TRACKING_ACTION_CREATE_COMMIT,
- );
- });
- });
-
it('notifies error when content could not be committed', () => {
Api.commitMultiple.mockRejectedValueOnce();
@@ -152,4 +144,24 @@ describe('submitContentChanges', () => {
});
});
});
+
+ describe('sends the correct tracking event', () => {
+ beforeEach(() => {
+ return submitContentChanges({ username, projectId, sourcePath, content });
+ });
+
+ it('for committing changes', () => {
+ expect(trackingSpy).toHaveBeenCalledWith(
+ document.body.dataset.page,
+ TRACKING_ACTION_CREATE_COMMIT,
+ );
+ });
+
+ it('for creating a merge request', () => {
+ expect(trackingSpy).toHaveBeenCalledWith(
+ document.body.dataset.page,
+ TRACKING_ACTION_CREATE_MERGE_REQUEST,
+ );
+ });
+ });
});
diff --git a/spec/frontend/test_setup.js b/spec/frontend/test_setup.js
index e216f49630f..49eae715a45 100644
--- a/spec/frontend/test_setup.js
+++ b/spec/frontend/test_setup.js
@@ -43,15 +43,6 @@ Object.assign(global, {
preloadFixtures() {},
});
-Object.assign(global, {
- MutationObserver() {
- return {
- disconnect() {},
- observe() {},
- };
- },
-});
-
// custom-jquery-matchers was written for an old Jest version, we need to make it compatible
Object.entries(jqueryMatchers).forEach(([matcherName, matcherFactory]) => {
// Don't override existing Jest matcher
@@ -69,12 +60,6 @@ expect.extend(customMatchers);
// Tech debt issue TBD
testUtilsConfig.logModifiedComponents = false;
-// Basic stub for MutationObserver
-global.MutationObserver = () => ({
- disconnect: () => {},
- observe: () => {},
-});
-
Object.assign(global, {
requestIdleCallback(cb) {
const start = Date.now();
diff --git a/spec/frontend/toggle_buttons_spec.js b/spec/frontend/toggle_buttons_spec.js
new file mode 100644
index 00000000000..09a4bd53c09
--- /dev/null
+++ b/spec/frontend/toggle_buttons_spec.js
@@ -0,0 +1,115 @@
+import $ from 'jquery';
+import setupToggleButtons from '~/toggle_buttons';
+import waitForPromises from './helpers/wait_for_promises';
+
+function generateMarkup(isChecked = true) {
+ return `
+ <button type="button" class="${isChecked ? 'is-checked' : ''} js-project-feature-toggle">
+ <input type="hidden" class="js-project-feature-toggle-input" value="${isChecked}" />
+ </button>
+ `;
+}
+
+function setupFixture(isChecked, clickCallback) {
+ const wrapper = document.createElement('div');
+ wrapper.innerHTML = generateMarkup(isChecked);
+
+ setupToggleButtons(wrapper, clickCallback);
+
+ return wrapper;
+}
+
+describe('ToggleButtons', () => {
+ describe('when input value is true', () => {
+ it('should initialize as checked', () => {
+ const wrapper = setupFixture(true);
+
+ expect(
+ wrapper.querySelector('.js-project-feature-toggle').classList.contains('is-checked'),
+ ).toEqual(true);
+
+ expect(wrapper.querySelector('.js-project-feature-toggle-input').value).toEqual('true');
+ });
+
+ it('should toggle to unchecked when clicked', () => {
+ const wrapper = setupFixture(true);
+ const toggleButton = wrapper.querySelector('.js-project-feature-toggle');
+
+ toggleButton.click();
+
+ return waitForPromises().then(() => {
+ expect(toggleButton.classList.contains('is-checked')).toEqual(false);
+ expect(wrapper.querySelector('.js-project-feature-toggle-input').value).toEqual('false');
+ });
+ });
+ });
+
+ describe('when input value is false', () => {
+ it('should initialize as unchecked', () => {
+ const wrapper = setupFixture(false);
+
+ expect(
+ wrapper.querySelector('.js-project-feature-toggle').classList.contains('is-checked'),
+ ).toEqual(false);
+
+ expect(wrapper.querySelector('.js-project-feature-toggle-input').value).toEqual('false');
+ });
+
+ it('should toggle to checked when clicked', () => {
+ const wrapper = setupFixture(false);
+ const toggleButton = wrapper.querySelector('.js-project-feature-toggle');
+
+ toggleButton.click();
+
+ return waitForPromises().then(() => {
+ expect(toggleButton.classList.contains('is-checked')).toEqual(true);
+ expect(wrapper.querySelector('.js-project-feature-toggle-input').value).toEqual('true');
+ });
+ });
+ });
+
+ it('should emit `trigger-change` event', () => {
+ const changeSpy = jest.fn();
+ const wrapper = setupFixture(false);
+ const toggleButton = wrapper.querySelector('.js-project-feature-toggle');
+ const input = wrapper.querySelector('.js-project-feature-toggle-input');
+
+ $(input).on('trigger-change', changeSpy);
+
+ toggleButton.click();
+
+ return waitForPromises().then(() => {
+ expect(changeSpy).toHaveBeenCalled();
+ });
+ });
+
+ describe('clickCallback', () => {
+ it('should show loading indicator while waiting', () => {
+ const isChecked = true;
+ const clickCallback = (newValue, toggleButton) => {
+ const input = toggleButton.querySelector('.js-project-feature-toggle-input');
+
+ expect(newValue).toEqual(false);
+
+ // Check for the loading state
+ expect(toggleButton.classList.contains('is-checked')).toEqual(false);
+ expect(toggleButton.classList.contains('is-loading')).toEqual(true);
+ expect(toggleButton.disabled).toEqual(true);
+ expect(input.value).toEqual('true');
+
+ // After the callback finishes, check that the loading state is gone
+ return waitForPromises().then(() => {
+ expect(toggleButton.classList.contains('is-checked')).toEqual(false);
+ expect(toggleButton.classList.contains('is-loading')).toEqual(false);
+ expect(toggleButton.disabled).toEqual(false);
+ expect(input.value).toEqual('false');
+ });
+ };
+
+ const wrapper = setupFixture(isChecked, clickCallback);
+ const toggleButton = wrapper.querySelector('.js-project-feature-toggle');
+
+ toggleButton.click();
+ });
+ });
+});
diff --git a/spec/frontend/tracking_spec.js b/spec/frontend/tracking_spec.js
index 08a26d46618..8acfa655c2c 100644
--- a/spec/frontend/tracking_spec.js
+++ b/spec/frontend/tracking_spec.js
@@ -121,11 +121,6 @@ describe('Tracking', () => {
describe('tracking interface events', () => {
let eventSpy;
- const trigger = (selector, eventName = 'click') => {
- const event = new Event(eventName, { bubbles: true });
- document.querySelector(selector).dispatchEvent(event);
- };
-
beforeEach(() => {
eventSpy = jest.spyOn(Tracking, 'event');
Tracking.bindDocument('_category_'); // only happens once
@@ -140,7 +135,7 @@ describe('Tracking', () => {
});
it('binds to clicks on elements matching [data-track-event]', () => {
- trigger('[data-track-event="click_input1"]');
+ document.querySelector('[data-track-event="click_input1"]').click();
expect(eventSpy).toHaveBeenCalledWith('_category_', 'click_input1', {
label: '_label_',
@@ -149,13 +144,13 @@ describe('Tracking', () => {
});
it('does not bind to clicks on elements without [data-track-event]', () => {
- trigger('[data-track-eventbogus="click_bogusinput"]');
+ document.querySelector('[data-track-eventbogus="click_bogusinput"]').click();
expect(eventSpy).not.toHaveBeenCalled();
});
it('allows value override with the data-track-value attribute', () => {
- trigger('[data-track-event="click_input2"]');
+ document.querySelector('[data-track-event="click_input2"]').click();
expect(eventSpy).toHaveBeenCalledWith('_category_', 'click_input2', {
value: '_value_override_',
@@ -163,13 +158,15 @@ describe('Tracking', () => {
});
it('handles checkbox values correctly', () => {
- trigger('[data-track-event="toggle_checkbox"]'); // checking
+ const checkbox = document.querySelector('[data-track-event="toggle_checkbox"]');
+
+ checkbox.click(); // unchecking
expect(eventSpy).toHaveBeenCalledWith('_category_', 'toggle_checkbox', {
value: false,
});
- trigger('[data-track-event="toggle_checkbox"]'); // unchecking
+ checkbox.click(); // checking
expect(eventSpy).toHaveBeenCalledWith('_category_', 'toggle_checkbox', {
value: '_value_',
@@ -177,17 +174,19 @@ describe('Tracking', () => {
});
it('handles bootstrap dropdowns', () => {
- trigger('[data-track-event="toggle_dropdown"]', 'show.bs.dropdown'); // showing
+ const dropdown = document.querySelector('[data-track-event="toggle_dropdown"]');
+
+ dropdown.dispatchEvent(new Event('show.bs.dropdown', { bubbles: true }));
expect(eventSpy).toHaveBeenCalledWith('_category_', 'toggle_dropdown_show', {});
- trigger('[data-track-event="toggle_dropdown"]', 'hide.bs.dropdown'); // hiding
+ dropdown.dispatchEvent(new Event('hide.bs.dropdown', { bubbles: true }));
expect(eventSpy).toHaveBeenCalledWith('_category_', 'toggle_dropdown_hide', {});
});
it('handles nested elements inside an element with tracking', () => {
- trigger('span.nested', 'click');
+ document.querySelector('span.nested').click();
expect(eventSpy).toHaveBeenCalledWith('_category_', 'nested_event', {});
});
diff --git a/spec/frontend/u2f/authenticate_spec.js b/spec/frontend/u2f/authenticate_spec.js
deleted file mode 100644
index 1d39c4857ae..00000000000
--- a/spec/frontend/u2f/authenticate_spec.js
+++ /dev/null
@@ -1,109 +0,0 @@
-import $ from 'jquery';
-import U2FAuthenticate from '~/u2f/authenticate';
-import 'vendor/u2f';
-import MockU2FDevice from './mock_u2f_device';
-
-describe('U2FAuthenticate', () => {
- let u2fDevice;
- let container;
- let component;
-
- preloadFixtures('u2f/authenticate.html');
-
- beforeEach(() => {
- loadFixtures('u2f/authenticate.html');
- u2fDevice = new MockU2FDevice();
- container = $('#js-authenticate-u2f');
- component = new U2FAuthenticate(
- container,
- '#js-login-u2f-form',
- {
- sign_requests: [],
- },
- document.querySelector('#js-login-2fa-device'),
- document.querySelector('.js-2fa-form'),
- );
- });
-
- describe('with u2f unavailable', () => {
- let oldu2f;
-
- beforeEach(() => {
- jest.spyOn(component, 'switchToFallbackUI').mockImplementation(() => {});
- oldu2f = window.u2f;
- window.u2f = null;
- });
-
- afterEach(() => {
- window.u2f = oldu2f;
- });
-
- it('falls back to normal 2fa', done => {
- component
- .start()
- .then(() => {
- expect(component.switchToFallbackUI).toHaveBeenCalled();
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('with u2f available', () => {
- beforeEach(done => {
- // bypass automatic form submission within renderAuthenticated
- jest.spyOn(component, 'renderAuthenticated').mockReturnValue(true);
- u2fDevice = new MockU2FDevice();
-
- component
- .start()
- .then(done)
- .catch(done.fail);
- });
-
- it('allows authenticating via a U2F device', () => {
- const inProgressMessage = container.find('p');
-
- expect(inProgressMessage.text()).toContain('Trying to communicate with your device');
- u2fDevice.respondToAuthenticateRequest({
- deviceData: 'this is data from the device',
- });
-
- expect(component.renderAuthenticated).toHaveBeenCalledWith(
- '{"deviceData":"this is data from the device"}',
- );
- });
-
- describe('errors', () => {
- it('displays an error message', () => {
- const setupButton = container.find('#js-login-u2f-device');
- setupButton.trigger('click');
- u2fDevice.respondToAuthenticateRequest({
- errorCode: 'error!',
- });
- const errorMessage = container.find('p');
-
- expect(errorMessage.text()).toContain('There was a problem communicating with your device');
- });
-
- it('allows retrying authentication after an error', () => {
- let setupButton = container.find('#js-login-u2f-device');
- setupButton.trigger('click');
- u2fDevice.respondToAuthenticateRequest({
- errorCode: 'error!',
- });
- const retryButton = container.find('#js-u2f-try-again');
- retryButton.trigger('click');
- setupButton = container.find('#js-login-u2f-device');
- setupButton.trigger('click');
- u2fDevice.respondToAuthenticateRequest({
- deviceData: 'this is data from the device',
- });
-
- expect(component.renderAuthenticated).toHaveBeenCalledWith(
- '{"deviceData":"this is data from the device"}',
- );
- });
- });
- });
-});
diff --git a/spec/frontend/u2f/register_spec.js b/spec/frontend/u2f/register_spec.js
deleted file mode 100644
index a4395a2123a..00000000000
--- a/spec/frontend/u2f/register_spec.js
+++ /dev/null
@@ -1,83 +0,0 @@
-import $ from 'jquery';
-import U2FRegister from '~/u2f/register';
-import 'vendor/u2f';
-import MockU2FDevice from './mock_u2f_device';
-
-describe('U2FRegister', () => {
- let u2fDevice;
- let container;
- let component;
-
- preloadFixtures('u2f/register.html');
-
- beforeEach(done => {
- loadFixtures('u2f/register.html');
- u2fDevice = new MockU2FDevice();
- container = $('#js-register-u2f');
- component = new U2FRegister(container, $('#js-register-u2f-templates'), {}, 'token');
- component
- .start()
- .then(done)
- .catch(done.fail);
- });
-
- it('allows registering a U2F device', () => {
- const setupButton = container.find('#js-setup-u2f-device');
-
- expect(setupButton.text()).toBe('Set up new U2F device');
- setupButton.trigger('click');
- const inProgressMessage = container.children('p');
-
- expect(inProgressMessage.text()).toContain('Trying to communicate with your device');
- u2fDevice.respondToRegisterRequest({
- deviceData: 'this is data from the device',
- });
- const registeredMessage = container.find('p');
- const deviceResponse = container.find('#js-device-response');
-
- expect(registeredMessage.text()).toContain('Your device was successfully set up!');
- expect(deviceResponse.val()).toBe('{"deviceData":"this is data from the device"}');
- });
-
- describe('errors', () => {
- it("doesn't allow the same device to be registered twice (for the same user", () => {
- const setupButton = container.find('#js-setup-u2f-device');
- setupButton.trigger('click');
- u2fDevice.respondToRegisterRequest({
- errorCode: 4,
- });
- const errorMessage = container.find('p');
-
- expect(errorMessage.text()).toContain('already been registered with us');
- });
-
- it('displays an error message for other errors', () => {
- const setupButton = container.find('#js-setup-u2f-device');
- setupButton.trigger('click');
- u2fDevice.respondToRegisterRequest({
- errorCode: 'error!',
- });
- const errorMessage = container.find('p');
-
- expect(errorMessage.text()).toContain('There was a problem communicating with your device');
- });
-
- it('allows retrying registration after an error', () => {
- let setupButton = container.find('#js-setup-u2f-device');
- setupButton.trigger('click');
- u2fDevice.respondToRegisterRequest({
- errorCode: 'error!',
- });
- const retryButton = container.find('#U2FTryAgain');
- retryButton.trigger('click');
- setupButton = container.find('#js-setup-u2f-device');
- setupButton.trigger('click');
- u2fDevice.respondToRegisterRequest({
- deviceData: 'this is data from the device',
- });
- const registeredMessage = container.find('p');
-
- expect(registeredMessage.text()).toContain('Your device was successfully set up!');
- });
- });
-});
diff --git a/spec/frontend/u2f/util_spec.js b/spec/frontend/u2f/util_spec.js
deleted file mode 100644
index 32cd6891384..00000000000
--- a/spec/frontend/u2f/util_spec.js
+++ /dev/null
@@ -1,61 +0,0 @@
-import { canInjectU2fApi } from '~/u2f/util';
-
-describe('U2F Utils', () => {
- describe('canInjectU2fApi', () => {
- it('returns false for Chrome < 41', () => {
- const userAgent =
- 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.28 Safari/537.36';
-
- expect(canInjectU2fApi(userAgent)).toBe(false);
- });
-
- it('returns true for Chrome >= 41', () => {
- const userAgent =
- 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36';
-
- expect(canInjectU2fApi(userAgent)).toBe(true);
- });
-
- it('returns false for Opera < 40', () => {
- const userAgent =
- 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36 OPR/32.0.1948.25';
-
- expect(canInjectU2fApi(userAgent)).toBe(false);
- });
-
- it('returns true for Opera >= 40', () => {
- const userAgent =
- 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 OPR/43.0.2442.991';
-
- expect(canInjectU2fApi(userAgent)).toBe(true);
- });
-
- it('returns false for Safari', () => {
- const userAgent =
- 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/603.2.4 (KHTML, like Gecko) Version/10.1.1 Safari/603.2.4';
-
- expect(canInjectU2fApi(userAgent)).toBe(false);
- });
-
- it('returns false for Chrome on Android', () => {
- const userAgent =
- 'Mozilla/5.0 (Linux; Android 7.0; VS988 Build/NRD90U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3145.0 Mobile Safari/537.36';
-
- expect(canInjectU2fApi(userAgent)).toBe(false);
- });
-
- it('returns false for Chrome on iOS', () => {
- const userAgent =
- 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1';
-
- expect(canInjectU2fApi(userAgent)).toBe(false);
- });
-
- it('returns false for Safari on iOS', () => {
- const userAgent =
- 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A356 Safari/604.1';
-
- expect(canInjectU2fApi(userAgent)).toBe(false);
- });
- });
-});
diff --git a/spec/frontend/user_popovers_spec.js b/spec/frontend/user_popovers_spec.js
new file mode 100644
index 00000000000..0367b9cc924
--- /dev/null
+++ b/spec/frontend/user_popovers_spec.js
@@ -0,0 +1,99 @@
+import initUserPopovers from '~/user_popovers';
+import UsersCache from '~/lib/utils/users_cache';
+
+describe('User Popovers', () => {
+ const fixtureTemplate = 'merge_requests/merge_request_with_mentions.html';
+ preloadFixtures(fixtureTemplate);
+
+ const selector = '.js-user-link, .gfm-project_member';
+
+ const dummyUser = { name: 'root' };
+ const dummyUserStatus = { message: 'active' };
+
+ let popovers;
+
+ const triggerEvent = (eventName, el) => {
+ const event = new MouseEvent(eventName, {
+ bubbles: true,
+ cancelable: true,
+ view: window,
+ });
+
+ el.dispatchEvent(event);
+ };
+
+ beforeEach(() => {
+ loadFixtures(fixtureTemplate);
+
+ const usersCacheSpy = () => Promise.resolve(dummyUser);
+ jest.spyOn(UsersCache, 'retrieveById').mockImplementation(userId => usersCacheSpy(userId));
+
+ const userStatusCacheSpy = () => Promise.resolve(dummyUserStatus);
+ jest
+ .spyOn(UsersCache, 'retrieveStatusById')
+ .mockImplementation(userId => userStatusCacheSpy(userId));
+
+ popovers = initUserPopovers(document.querySelectorAll(selector));
+ });
+
+ it('initializes a popover for each user link with a user id', () => {
+ const linksWithUsers = Array.from(document.querySelectorAll(selector)).filter(
+ ({ dataset }) => dataset.user || dataset.userId,
+ );
+
+ expect(linksWithUsers.length).toBe(popovers.length);
+ });
+
+ it('does not initialize the user popovers twice for the same element', () => {
+ const newPopovers = initUserPopovers(document.querySelectorAll(selector));
+ const samePopovers = popovers.every((popover, index) => newPopovers[index] === popover);
+
+ expect(samePopovers).toBe(true);
+ });
+
+ describe('when user link emits mouseenter event', () => {
+ let userLink;
+
+ beforeEach(() => {
+ UsersCache.retrieveById.mockReset();
+
+ userLink = document.querySelector(selector);
+
+ triggerEvent('mouseenter', userLink);
+ });
+
+ it('removes title attribute from user links', () => {
+ expect(userLink.getAttribute('title')).toBeFalsy();
+ expect(userLink.dataset.originalTitle).toBeFalsy();
+ });
+
+ it('populates popovers with preloaded user data', () => {
+ const { name, userId, username } = userLink.dataset;
+ const [firstPopover] = popovers;
+
+ expect(firstPopover.$props.user).toEqual(
+ expect.objectContaining({
+ name,
+ userId,
+ username,
+ }),
+ );
+ });
+
+ it('fetches user info and status from the user cache', () => {
+ const { userId } = userLink.dataset;
+
+ expect(UsersCache.retrieveById).toHaveBeenCalledWith(userId);
+ expect(UsersCache.retrieveStatusById).toHaveBeenCalledWith(userId);
+ });
+ });
+
+ it('removes aria-describedby attribute from the user link on mouseleave', () => {
+ const userLink = document.querySelector(selector);
+
+ userLink.setAttribute('aria-describedby', 'popover');
+ triggerEvent('mouseleave', userLink);
+
+ expect(userLink.getAttribute('aria-describedby')).toBe(null);
+ });
+});
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_alert_message_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_alert_message_spec.js
index f78fcfb52b4..f78fcfb52b4 100644
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_alert_message_spec.js
+++ b/spec/frontend/vue_mr_widget/components/mr_widget_alert_message_spec.js
diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_author_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_author_spec.js
new file mode 100644
index 00000000000..05690aa1248
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/mr_widget_author_spec.js
@@ -0,0 +1,39 @@
+import Vue from 'vue';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import MrWidgetAuthor from '~/vue_merge_request_widget/components/mr_widget_author.vue';
+
+describe('MrWidgetAuthor', () => {
+ let vm;
+
+ beforeEach(() => {
+ const Component = Vue.extend(MrWidgetAuthor);
+
+ vm = mountComponent(Component, {
+ author: {
+ name: 'Administrator',
+ username: 'root',
+ webUrl: 'http://localhost:3000/root',
+ avatarUrl:
+ 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ },
+ });
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('renders link with the author web url', () => {
+ expect(vm.$el.getAttribute('href')).toEqual('http://localhost:3000/root');
+ });
+
+ it('renders image with avatar url', () => {
+ expect(vm.$el.querySelector('img').getAttribute('src')).toEqual(
+ 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ );
+ });
+
+ it('renders author name', () => {
+ expect(vm.$el.textContent.trim()).toEqual('Administrator');
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_author_time_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_author_time_spec.js
new file mode 100644
index 00000000000..58ed92298bf
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/mr_widget_author_time_spec.js
@@ -0,0 +1,44 @@
+import Vue from 'vue';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import MrWidgetAuthorTime from '~/vue_merge_request_widget/components/mr_widget_author_time.vue';
+
+describe('MrWidgetAuthorTime', () => {
+ let vm;
+
+ beforeEach(() => {
+ const Component = Vue.extend(MrWidgetAuthorTime);
+
+ vm = mountComponent(Component, {
+ actionText: 'Merged by',
+ author: {
+ name: 'Administrator',
+ username: 'root',
+ webUrl: 'http://localhost:3000/root',
+ avatarUrl:
+ 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ },
+ dateTitle: '2017-03-23T23:02:00.807Z',
+ dateReadable: '12 hours ago',
+ });
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('renders provided action text', () => {
+ expect(vm.$el.textContent).toContain('Merged by');
+ });
+
+ it('renders author', () => {
+ expect(vm.$el.textContent).toContain('Administrator');
+ });
+
+ it('renders provided time', () => {
+ expect(vm.$el.querySelector('time').getAttribute('data-original-title')).toEqual(
+ '2017-03-23T23:02:00.807Z',
+ );
+
+ expect(vm.$el.querySelector('time').textContent.trim()).toEqual('12 hours ago');
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_header_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_header_spec.js
new file mode 100644
index 00000000000..b492a69fb3d
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/mr_widget_header_spec.js
@@ -0,0 +1,313 @@
+import Vue from 'vue';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import headerComponent from '~/vue_merge_request_widget/components/mr_widget_header.vue';
+
+describe('MRWidgetHeader', () => {
+ let vm;
+ let Component;
+
+ beforeEach(() => {
+ Component = Vue.extend(headerComponent);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ gon.relative_url_root = '';
+ });
+
+ const expectDownloadDropdownItems = () => {
+ const downloadEmailPatchesEl = vm.$el.querySelector('.js-download-email-patches');
+ const downloadPlainDiffEl = vm.$el.querySelector('.js-download-plain-diff');
+
+ expect(downloadEmailPatchesEl.textContent.trim()).toEqual('Email patches');
+ expect(downloadEmailPatchesEl.getAttribute('href')).toEqual('/mr/email-patches');
+ expect(downloadPlainDiffEl.textContent.trim()).toEqual('Plain diff');
+ expect(downloadPlainDiffEl.getAttribute('href')).toEqual('/mr/plainDiffPath');
+ };
+
+ describe('computed', () => {
+ describe('shouldShowCommitsBehindText', () => {
+ it('return true when there are divergedCommitsCount', () => {
+ vm = mountComponent(Component, {
+ mr: {
+ divergedCommitsCount: 12,
+ sourceBranch: 'mr-widget-refactor',
+ sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">Link</a>',
+ targetBranch: 'master',
+ statusPath: 'abc',
+ },
+ });
+
+ expect(vm.shouldShowCommitsBehindText).toEqual(true);
+ });
+
+ it('returns false where there are no divergedComits count', () => {
+ vm = mountComponent(Component, {
+ mr: {
+ divergedCommitsCount: 0,
+ sourceBranch: 'mr-widget-refactor',
+ sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">Link</a>',
+ targetBranch: 'master',
+ statusPath: 'abc',
+ },
+ });
+
+ expect(vm.shouldShowCommitsBehindText).toEqual(false);
+ });
+ });
+
+ describe('commitsBehindText', () => {
+ it('returns singular when there is one commit', () => {
+ vm = mountComponent(Component, {
+ mr: {
+ divergedCommitsCount: 1,
+ sourceBranch: 'mr-widget-refactor',
+ sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">Link</a>',
+ targetBranch: 'master',
+ targetBranchPath: '/foo/bar/master',
+ statusPath: 'abc',
+ },
+ });
+
+ expect(vm.commitsBehindText).toEqual(
+ 'The source branch is <a href="/foo/bar/master">1 commit behind</a> the target branch',
+ );
+ });
+
+ it('returns plural when there is more than one commit', () => {
+ vm = mountComponent(Component, {
+ mr: {
+ divergedCommitsCount: 2,
+ sourceBranch: 'mr-widget-refactor',
+ sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">Link</a>',
+ targetBranch: 'master',
+ targetBranchPath: '/foo/bar/master',
+ statusPath: 'abc',
+ },
+ });
+
+ expect(vm.commitsBehindText).toEqual(
+ 'The source branch is <a href="/foo/bar/master">2 commits behind</a> the target branch',
+ );
+ });
+ });
+ });
+
+ describe('template', () => {
+ describe('common elements', () => {
+ beforeEach(() => {
+ vm = mountComponent(Component, {
+ mr: {
+ divergedCommitsCount: 12,
+ sourceBranch: 'mr-widget-refactor',
+ sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">mr-widget-refactor</a>',
+ sourceBranchRemoved: false,
+ targetBranchPath: 'foo/bar/commits-path',
+ targetBranchTreePath: 'foo/bar/tree/path',
+ targetBranch: 'master',
+ isOpen: true,
+ emailPatchesPath: '/mr/email-patches',
+ plainDiffPath: '/mr/plainDiffPath',
+ statusPath: 'abc',
+ },
+ });
+ });
+
+ it('renders source branch link', () => {
+ expect(vm.$el.querySelector('.js-source-branch').innerHTML).toEqual(
+ '<a href="/foo/bar/mr-widget-refactor">mr-widget-refactor</a>',
+ );
+ });
+
+ it('renders clipboard button', () => {
+ expect(vm.$el.querySelector('.btn-clipboard')).not.toEqual(null);
+ });
+
+ it('renders target branch', () => {
+ expect(vm.$el.querySelector('.js-target-branch').textContent.trim()).toEqual('master');
+ });
+ });
+
+ describe('with an open merge request', () => {
+ const mrDefaultOptions = {
+ iid: 1,
+ divergedCommitsCount: 12,
+ sourceBranch: 'mr-widget-refactor',
+ sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">mr-widget-refactor</a>',
+ sourceBranchRemoved: false,
+ targetBranchPath: 'foo/bar/commits-path',
+ targetBranchTreePath: 'foo/bar/tree/path',
+ targetBranch: 'master',
+ isOpen: true,
+ canPushToSourceBranch: true,
+ emailPatchesPath: '/mr/email-patches',
+ plainDiffPath: '/mr/plainDiffPath',
+ statusPath: 'abc',
+ sourceProjectFullPath: 'root/gitlab-ce',
+ targetProjectFullPath: 'gitlab-org/gitlab-ce',
+ };
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ beforeEach(() => {
+ vm = mountComponent(Component, {
+ mr: { ...mrDefaultOptions },
+ });
+ });
+
+ it('renders checkout branch button with modal trigger', () => {
+ const button = vm.$el.querySelector('.js-check-out-branch');
+
+ expect(button.textContent.trim()).toEqual('Check out branch');
+ expect(button.getAttribute('data-target')).toEqual('#modal_merge_info');
+ expect(button.getAttribute('data-toggle')).toEqual('modal');
+ });
+
+ it('renders web ide button', () => {
+ const button = vm.$el.querySelector('.js-web-ide');
+
+ expect(button.textContent.trim()).toEqual('Open in Web IDE');
+ expect(button.classList.contains('disabled')).toBe(false);
+ expect(button.getAttribute('href')).toEqual(
+ '/-/ide/project/root/gitlab-ce/merge_requests/1?target_project=gitlab-org%2Fgitlab-ce',
+ );
+ });
+
+ it('renders web ide button in disabled state with no href', () => {
+ const mr = { ...mrDefaultOptions, canPushToSourceBranch: false };
+ vm = mountComponent(Component, { mr });
+
+ const link = vm.$el.querySelector('.js-web-ide');
+
+ expect(link.classList.contains('disabled')).toBe(true);
+ expect(link.getAttribute('href')).toBeNull();
+ });
+
+ it('renders web ide button with blank query string if target & source project branch', done => {
+ vm.mr.targetProjectFullPath = 'root/gitlab-ce';
+
+ vm.$nextTick(() => {
+ const button = vm.$el.querySelector('.js-web-ide');
+
+ expect(button.textContent.trim()).toEqual('Open in Web IDE');
+ expect(button.getAttribute('href')).toEqual(
+ '/-/ide/project/root/gitlab-ce/merge_requests/1?target_project=',
+ );
+
+ done();
+ });
+ });
+
+ it('renders web ide button with relative URL', done => {
+ gon.relative_url_root = '/gitlab';
+ vm.mr.iid = 2;
+
+ vm.$nextTick(() => {
+ const button = vm.$el.querySelector('.js-web-ide');
+
+ expect(button.textContent.trim()).toEqual('Open in Web IDE');
+ expect(button.getAttribute('href')).toEqual(
+ '/gitlab/-/ide/project/root/gitlab-ce/merge_requests/2?target_project=gitlab-org%2Fgitlab-ce',
+ );
+
+ done();
+ });
+ });
+
+ it('renders download dropdown with links', () => {
+ expectDownloadDropdownItems();
+ });
+ });
+
+ describe('with a closed merge request', () => {
+ beforeEach(() => {
+ vm = mountComponent(Component, {
+ mr: {
+ divergedCommitsCount: 12,
+ sourceBranch: 'mr-widget-refactor',
+ sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">mr-widget-refactor</a>',
+ sourceBranchRemoved: false,
+ targetBranchPath: 'foo/bar/commits-path',
+ targetBranchTreePath: 'foo/bar/tree/path',
+ targetBranch: 'master',
+ isOpen: false,
+ emailPatchesPath: '/mr/email-patches',
+ plainDiffPath: '/mr/plainDiffPath',
+ statusPath: 'abc',
+ },
+ });
+ });
+
+ it('does not render checkout branch button with modal trigger', () => {
+ const button = vm.$el.querySelector('.js-check-out-branch');
+
+ expect(button).toEqual(null);
+ });
+
+ it('renders download dropdown with links', () => {
+ expectDownloadDropdownItems();
+ });
+ });
+
+ describe('without diverged commits', () => {
+ beforeEach(() => {
+ vm = mountComponent(Component, {
+ mr: {
+ divergedCommitsCount: 0,
+ sourceBranch: 'mr-widget-refactor',
+ sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">mr-widget-refactor</a>',
+ sourceBranchRemoved: false,
+ targetBranchPath: 'foo/bar/commits-path',
+ targetBranchTreePath: 'foo/bar/tree/path',
+ targetBranch: 'master',
+ isOpen: true,
+ emailPatchesPath: '/mr/email-patches',
+ plainDiffPath: '/mr/plainDiffPath',
+ statusPath: 'abc',
+ },
+ });
+ });
+
+ it('does not render diverged commits info', () => {
+ expect(vm.$el.querySelector('.diverged-commits-count')).toEqual(null);
+ });
+ });
+
+ describe('with diverged commits', () => {
+ beforeEach(() => {
+ vm = mountComponent(Component, {
+ mr: {
+ divergedCommitsCount: 12,
+ sourceBranch: 'mr-widget-refactor',
+ sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">mr-widget-refactor</a>',
+ sourceBranchRemoved: false,
+ targetBranchPath: 'foo/bar/commits-path',
+ targetBranchTreePath: 'foo/bar/tree/path',
+ targetBranch: 'master',
+ isOpen: true,
+ emailPatchesPath: '/mr/email-patches',
+ plainDiffPath: '/mr/plainDiffPath',
+ statusPath: 'abc',
+ },
+ });
+ });
+
+ it('renders diverged commits info', () => {
+ expect(vm.$el.querySelector('.diverged-commits-count').textContent).toEqual(
+ 'The source branch is 12 commits behind the target branch',
+ );
+
+ expect(vm.$el.querySelector('.diverged-commits-count a').textContent).toEqual(
+ '12 commits behind',
+ );
+
+ expect(vm.$el.querySelector('.diverged-commits-count a')).toHaveAttr(
+ 'href',
+ vm.mr.targetBranchPath,
+ );
+ });
+ });
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_memory_usage_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_memory_usage_spec.js
new file mode 100644
index 00000000000..7a932feb3a7
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/mr_widget_memory_usage_spec.js
@@ -0,0 +1,239 @@
+import Vue from 'vue';
+import axios from 'axios';
+import MockAdapter from 'axios-mock-adapter';
+import MemoryUsage from '~/vue_merge_request_widget/components/deployment/memory_usage.vue';
+import MRWidgetService from '~/vue_merge_request_widget/services/mr_widget_service';
+
+const url = '/root/acets-review-apps/environments/15/deployments/1/metrics';
+const monitoringUrl = '/root/acets-review-apps/environments/15/metrics';
+
+const metricsMockData = {
+ success: true,
+ metrics: {
+ memory_before: [
+ {
+ metric: {},
+ value: [1495785220.607, '9572875.906976745'],
+ },
+ ],
+ memory_after: [
+ {
+ metric: {},
+ value: [1495787020.607, '4485853.130206379'],
+ },
+ ],
+ memory_values: [
+ {
+ metric: {},
+ values: [[1493716685, '4.30859375']],
+ },
+ ],
+ },
+ last_update: '2017-05-02T12:34:49.628Z',
+ deployment_time: 1493718485,
+};
+
+const createComponent = () => {
+ const Component = Vue.extend(MemoryUsage);
+
+ return new Component({
+ el: document.createElement('div'),
+ propsData: {
+ metricsUrl: url,
+ metricsMonitoringUrl: monitoringUrl,
+ memoryMetrics: [],
+ deploymentTime: 0,
+ hasMetrics: false,
+ loadFailed: false,
+ loadingMetrics: true,
+ backOffRequestCounter: 0,
+ },
+ });
+};
+
+const messages = {
+ loadingMetrics: 'Loading deployment statistics',
+ hasMetrics: 'Memory usage is unchanged at 0MB',
+ loadFailed: 'Failed to load deployment statistics',
+ metricsUnavailable: 'Deployment statistics are not available currently',
+};
+
+describe('MemoryUsage', () => {
+ let vm;
+ let el;
+ let mock;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ mock.onGet(`${url}.json`).reply(200);
+
+ vm = createComponent();
+ el = vm.$el;
+ });
+
+ afterEach(() => {
+ mock.restore();
+ });
+
+ describe('data', () => {
+ it('should have default data', () => {
+ const data = MemoryUsage.data();
+
+ expect(Array.isArray(data.memoryMetrics)).toBeTruthy();
+ expect(data.memoryMetrics.length).toBe(0);
+
+ expect(typeof data.deploymentTime).toBe('number');
+ expect(data.deploymentTime).toBe(0);
+
+ expect(typeof data.hasMetrics).toBe('boolean');
+ expect(data.hasMetrics).toBeFalsy();
+
+ expect(typeof data.loadFailed).toBe('boolean');
+ expect(data.loadFailed).toBeFalsy();
+
+ expect(typeof data.loadingMetrics).toBe('boolean');
+ expect(data.loadingMetrics).toBeTruthy();
+
+ expect(typeof data.backOffRequestCounter).toBe('number');
+ expect(data.backOffRequestCounter).toBe(0);
+ });
+ });
+
+ describe('computed', () => {
+ describe('memoryChangeMessage', () => {
+ it('should contain "increased" if memoryFrom value is less than memoryTo value', () => {
+ vm.memoryFrom = 4.28;
+ vm.memoryTo = 9.13;
+
+ expect(vm.memoryChangeMessage.indexOf('increased')).not.toEqual('-1');
+ });
+
+ it('should contain "decreased" if memoryFrom value is less than memoryTo value', () => {
+ vm.memoryFrom = 9.13;
+ vm.memoryTo = 4.28;
+
+ expect(vm.memoryChangeMessage.indexOf('decreased')).not.toEqual('-1');
+ });
+
+ it('should contain "unchanged" if memoryFrom value equal to memoryTo value', () => {
+ vm.memoryFrom = 1;
+ vm.memoryTo = 1;
+
+ expect(vm.memoryChangeMessage.indexOf('unchanged')).not.toEqual('-1');
+ });
+ });
+ });
+
+ describe('methods', () => {
+ const { metrics, deployment_time } = metricsMockData;
+
+ describe('getMegabytes', () => {
+ it('should return Megabytes from provided Bytes value', () => {
+ const memoryInBytes = '9572875.906976745';
+
+ expect(vm.getMegabytes(memoryInBytes)).toEqual('9.13');
+ });
+ });
+
+ describe('computeGraphData', () => {
+ it('should populate sparkline graph', () => {
+ // ignore BoostrapVue warnings
+ jest.spyOn(console, 'warn').mockImplementation();
+
+ vm.computeGraphData(metrics, deployment_time);
+ const { hasMetrics, memoryMetrics, deploymentTime, memoryFrom, memoryTo } = vm;
+
+ expect(hasMetrics).toBeTruthy();
+ expect(memoryMetrics.length).toBeGreaterThan(0);
+ expect(deploymentTime).toEqual(deployment_time);
+ expect(memoryFrom).toEqual('9.13');
+ expect(memoryTo).toEqual('4.28');
+ });
+ });
+
+ describe('loadMetrics', () => {
+ const returnServicePromise = () =>
+ new Promise(resolve => {
+ resolve({
+ data: metricsMockData,
+ });
+ });
+
+ it('should load metrics data using MRWidgetService', done => {
+ jest.spyOn(MRWidgetService, 'fetchMetrics').mockReturnValue(returnServicePromise(true));
+ jest.spyOn(vm, 'computeGraphData').mockImplementation(() => {});
+
+ vm.loadMetrics();
+ setImmediate(() => {
+ expect(MRWidgetService.fetchMetrics).toHaveBeenCalledWith(url);
+ expect(vm.computeGraphData).toHaveBeenCalledWith(metrics, deployment_time);
+ done();
+ });
+ });
+ });
+ });
+
+ describe('template', () => {
+ it('should render template elements correctly', () => {
+ expect(el.classList.contains('mr-memory-usage')).toBeTruthy();
+ expect(el.querySelector('.js-usage-info')).toBeDefined();
+ });
+
+ it('should show loading metrics message while metrics are being loaded', done => {
+ vm.loadingMetrics = true;
+ vm.hasMetrics = false;
+ vm.loadFailed = false;
+
+ Vue.nextTick(() => {
+ expect(el.querySelector('.js-usage-info.usage-info-loading')).toBeDefined();
+
+ expect(el.querySelector('.js-usage-info .usage-info-load-spinner')).toBeDefined();
+
+ expect(el.querySelector('.js-usage-info').innerText).toContain(messages.loadingMetrics);
+ done();
+ });
+ });
+
+ it('should show deployment memory usage when metrics are loaded', done => {
+ // ignore BoostrapVue warnings
+ jest.spyOn(console, 'warn').mockImplementation();
+
+ vm.loadingMetrics = false;
+ vm.hasMetrics = true;
+ vm.loadFailed = false;
+ vm.memoryMetrics = metricsMockData.metrics.memory_values[0].values;
+
+ Vue.nextTick(() => {
+ expect(el.querySelector('.memory-graph-container')).toBeDefined();
+ expect(el.querySelector('.js-usage-info').innerText).toContain(messages.hasMetrics);
+ done();
+ });
+ });
+
+ it('should show failure message when metrics loading failed', done => {
+ vm.loadingMetrics = false;
+ vm.hasMetrics = false;
+ vm.loadFailed = true;
+
+ Vue.nextTick(() => {
+ expect(el.querySelector('.js-usage-info.usage-info-failed')).toBeDefined();
+
+ expect(el.querySelector('.js-usage-info').innerText).toContain(messages.loadFailed);
+ done();
+ });
+ });
+
+ it('should show metrics unavailable message when metrics loading failed', done => {
+ vm.loadingMetrics = false;
+ vm.hasMetrics = false;
+ vm.loadFailed = false;
+
+ Vue.nextTick(() => {
+ expect(el.querySelector('.js-usage-info.usage-info-unavailable')).toBeDefined();
+
+ expect(el.querySelector('.js-usage-info').innerText).toContain(messages.metricsUnavailable);
+ done();
+ });
+ });
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_merge_help_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_merge_help_spec.js
new file mode 100644
index 00000000000..00e79a22485
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/mr_widget_merge_help_spec.js
@@ -0,0 +1,70 @@
+import Vue from 'vue';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import mergeHelpComponent from '~/vue_merge_request_widget/components/mr_widget_merge_help.vue';
+
+describe('MRWidgetMergeHelp', () => {
+ let vm;
+ let Component;
+
+ beforeEach(() => {
+ Component = Vue.extend(mergeHelpComponent);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('with missing branch', () => {
+ beforeEach(() => {
+ vm = mountComponent(Component, {
+ missingBranch: 'this-is-not-the-branch-you-are-looking-for',
+ });
+ });
+
+ it('renders missing branch information', () => {
+ expect(
+ vm.$el.textContent
+ .trim()
+ .replace(/[\r\n]+/g, ' ')
+ .replace(/\s\s+/g, ' '),
+ ).toEqual(
+ 'If the this-is-not-the-branch-you-are-looking-for branch exists in your local repository, you can merge this merge request manually using the command line',
+ );
+ });
+
+ it('renders button to open help modal', () => {
+ expect(vm.$el.querySelector('.js-open-modal-help').getAttribute('data-target')).toEqual(
+ '#modal_merge_info',
+ );
+
+ expect(vm.$el.querySelector('.js-open-modal-help').getAttribute('data-toggle')).toEqual(
+ 'modal',
+ );
+ });
+ });
+
+ describe('without missing branch', () => {
+ beforeEach(() => {
+ vm = mountComponent(Component);
+ });
+
+ it('renders information about how to merge manually', () => {
+ expect(
+ vm.$el.textContent
+ .trim()
+ .replace(/[\r\n]+/g, ' ')
+ .replace(/\s\s+/g, ' '),
+ ).toEqual('You can merge this merge request manually using the command line');
+ });
+
+ it('renders element to open a modal', () => {
+ expect(vm.$el.querySelector('.js-open-modal-help').getAttribute('data-target')).toEqual(
+ '#modal_merge_info',
+ );
+
+ expect(vm.$el.querySelector('.js-open-modal-help').getAttribute('data-toggle')).toEqual(
+ 'modal',
+ );
+ });
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_pipeline_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_pipeline_spec.js
new file mode 100644
index 00000000000..309aec179d9
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/mr_widget_pipeline_spec.js
@@ -0,0 +1,326 @@
+import Vue from 'vue';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import { trimText } from 'helpers/text_helper';
+import pipelineComponent from '~/vue_merge_request_widget/components/mr_widget_pipeline.vue';
+import mockData from '../mock_data';
+
+describe('MRWidgetPipeline', () => {
+ let vm;
+ let Component;
+
+ beforeEach(() => {
+ Component = Vue.extend(pipelineComponent);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('computed', () => {
+ describe('hasPipeline', () => {
+ it('should return true when there is a pipeline', () => {
+ vm = mountComponent(Component, {
+ pipeline: mockData.pipeline,
+ ciStatus: 'success',
+ hasCi: true,
+ troubleshootingDocsPath: 'help',
+ });
+
+ expect(vm.hasPipeline).toEqual(true);
+ });
+
+ it('should return false when there is no pipeline', () => {
+ vm = mountComponent(Component, {
+ pipeline: {},
+ troubleshootingDocsPath: 'help',
+ });
+
+ expect(vm.hasPipeline).toEqual(false);
+ });
+ });
+
+ describe('hasCIError', () => {
+ it('should return false when there is no CI error', () => {
+ vm = mountComponent(Component, {
+ pipeline: mockData.pipeline,
+ hasCi: true,
+ ciStatus: 'success',
+ troubleshootingDocsPath: 'help',
+ });
+
+ expect(vm.hasCIError).toEqual(false);
+ });
+
+ it('should return true when there is a CI error', () => {
+ vm = mountComponent(Component, {
+ pipeline: mockData.pipeline,
+ hasCi: true,
+ ciStatus: null,
+ troubleshootingDocsPath: 'help',
+ });
+
+ expect(vm.hasCIError).toEqual(true);
+ });
+ });
+
+ describe('coverageDeltaClass', () => {
+ it('should return no class if there is no coverage change', () => {
+ vm = mountComponent(Component, {
+ pipeline: mockData.pipeline,
+ pipelineCoverageDelta: '0',
+ troubleshootingDocsPath: 'help',
+ });
+
+ expect(vm.coverageDeltaClass).toEqual('');
+ });
+
+ it('should return text-success if the coverage increased', () => {
+ vm = mountComponent(Component, {
+ pipeline: mockData.pipeline,
+ pipelineCoverageDelta: '10',
+ troubleshootingDocsPath: 'help',
+ });
+
+ expect(vm.coverageDeltaClass).toEqual('text-success');
+ });
+
+ it('should return text-danger if the coverage decreased', () => {
+ vm = mountComponent(Component, {
+ pipeline: mockData.pipeline,
+ pipelineCoverageDelta: '-12',
+ troubleshootingDocsPath: 'help',
+ });
+
+ expect(vm.coverageDeltaClass).toEqual('text-danger');
+ });
+ });
+ });
+
+ describe('rendered output', () => {
+ it('should render CI error', () => {
+ vm = mountComponent(Component, {
+ pipeline: mockData.pipeline,
+ hasCi: true,
+ troubleshootingDocsPath: 'help',
+ });
+
+ expect(vm.$el.querySelector('.media-body').textContent.trim()).toContain(
+ 'Could not retrieve the pipeline status. For troubleshooting steps, read the documentation.',
+ );
+ });
+
+ it('should render CI error when no pipeline is provided', () => {
+ vm = mountComponent(Component, {
+ pipeline: {},
+ hasCi: true,
+ ciStatus: 'success',
+ troubleshootingDocsPath: 'help',
+ });
+
+ expect(vm.$el.querySelector('.media-body').textContent.trim()).toContain(
+ 'Could not retrieve the pipeline status. For troubleshooting steps, read the documentation.',
+ );
+ });
+
+ it('should render CI error when no CI is provided and pipeline must succeed is turned on', () => {
+ vm = mountComponent(Component, {
+ pipeline: {},
+ hasCi: false,
+ pipelineMustSucceed: true,
+ troubleshootingDocsPath: 'help',
+ });
+
+ expect(vm.$el.querySelector('.media-body').textContent.trim()).toContain(
+ 'No pipeline has been run for this commit.',
+ );
+ });
+
+ describe('with a pipeline', () => {
+ beforeEach(() => {
+ vm = mountComponent(Component, {
+ pipeline: mockData.pipeline,
+ hasCi: true,
+ ciStatus: 'success',
+ pipelineCoverageDelta: mockData.pipelineCoverageDelta,
+ troubleshootingDocsPath: 'help',
+ });
+ });
+
+ it('should render pipeline ID', () => {
+ expect(vm.$el.querySelector('.pipeline-id').textContent.trim()).toEqual(
+ `#${mockData.pipeline.id}`,
+ );
+ });
+
+ it('should render pipeline status and commit id', () => {
+ expect(vm.$el.querySelector('.media-body').textContent.trim()).toContain(
+ mockData.pipeline.details.status.label,
+ );
+
+ expect(vm.$el.querySelector('.js-commit-link').textContent.trim()).toEqual(
+ mockData.pipeline.commit.short_id,
+ );
+
+ expect(vm.$el.querySelector('.js-commit-link').getAttribute('href')).toEqual(
+ mockData.pipeline.commit.commit_path,
+ );
+ });
+
+ it('should render pipeline graph', () => {
+ expect(vm.$el.querySelector('.mr-widget-pipeline-graph')).toBeDefined();
+ expect(vm.$el.querySelectorAll('.stage-container').length).toEqual(
+ mockData.pipeline.details.stages.length,
+ );
+ });
+
+ it('should render coverage information', () => {
+ expect(vm.$el.querySelector('.media-body').textContent).toContain(
+ `Coverage ${mockData.pipeline.coverage}`,
+ );
+ });
+
+ it('should render pipeline coverage delta information', () => {
+ expect(vm.$el.querySelector('.js-pipeline-coverage-delta.text-danger')).toBeDefined();
+ expect(vm.$el.querySelector('.js-pipeline-coverage-delta').textContent).toContain(
+ `(${mockData.pipelineCoverageDelta}%)`,
+ );
+ });
+ });
+
+ describe('without commit path', () => {
+ beforeEach(() => {
+ const mockCopy = JSON.parse(JSON.stringify(mockData));
+ delete mockCopy.pipeline.commit;
+
+ vm = mountComponent(Component, {
+ pipeline: mockCopy.pipeline,
+ hasCi: true,
+ ciStatus: 'success',
+ troubleshootingDocsPath: 'help',
+ });
+ });
+
+ it('should render pipeline ID', () => {
+ expect(vm.$el.querySelector('.pipeline-id').textContent.trim()).toEqual(
+ `#${mockData.pipeline.id}`,
+ );
+ });
+
+ it('should render pipeline status', () => {
+ expect(vm.$el.querySelector('.media-body').textContent.trim()).toContain(
+ mockData.pipeline.details.status.label,
+ );
+
+ expect(vm.$el.querySelector('.js-commit-link')).toBeNull();
+ });
+
+ it('should render pipeline graph', () => {
+ expect(vm.$el.querySelector('.mr-widget-pipeline-graph')).toBeDefined();
+ expect(vm.$el.querySelectorAll('.stage-container').length).toEqual(
+ mockData.pipeline.details.stages.length,
+ );
+ });
+
+ it('should render coverage information', () => {
+ expect(vm.$el.querySelector('.media-body').textContent).toContain(
+ `Coverage ${mockData.pipeline.coverage}`,
+ );
+ });
+ });
+
+ describe('without coverage', () => {
+ it('should not render a coverage', () => {
+ const mockCopy = JSON.parse(JSON.stringify(mockData));
+ delete mockCopy.pipeline.coverage;
+
+ vm = mountComponent(Component, {
+ pipeline: mockCopy.pipeline,
+ hasCi: true,
+ ciStatus: 'success',
+ troubleshootingDocsPath: 'help',
+ });
+
+ expect(vm.$el.querySelector('.media-body').textContent).not.toContain('Coverage');
+ });
+ });
+
+ describe('without a pipeline graph', () => {
+ it('should not render a pipeline graph', () => {
+ const mockCopy = JSON.parse(JSON.stringify(mockData));
+ delete mockCopy.pipeline.details.stages;
+
+ vm = mountComponent(Component, {
+ pipeline: mockCopy.pipeline,
+ hasCi: true,
+ ciStatus: 'success',
+ troubleshootingDocsPath: 'help',
+ });
+
+ expect(vm.$el.querySelector('.js-mini-pipeline-graph')).toEqual(null);
+ });
+ });
+
+ describe('for each type of pipeline', () => {
+ let pipeline;
+
+ beforeEach(() => {
+ ({ pipeline } = JSON.parse(JSON.stringify(mockData)));
+
+ pipeline.details.name = 'Pipeline';
+ pipeline.merge_request_event_type = undefined;
+ pipeline.ref.tag = false;
+ pipeline.ref.branch = false;
+ });
+
+ const factory = () => {
+ vm = mountComponent(Component, {
+ pipeline,
+ hasCi: true,
+ ciStatus: 'success',
+ troubleshootingDocsPath: 'help',
+ sourceBranchLink: mockData.source_branch_link,
+ });
+ };
+
+ describe('for a branch pipeline', () => {
+ it('renders a pipeline widget that reads "Pipeline <ID> <status> for <SHA> on <branch>"', () => {
+ pipeline.ref.branch = true;
+
+ factory();
+
+ const expected = `Pipeline #${pipeline.id} ${pipeline.details.status.label} for ${pipeline.commit.short_id} on ${mockData.source_branch_link}`;
+ const actual = trimText(vm.$el.querySelector('.js-pipeline-info-container').innerText);
+
+ expect(actual).toBe(expected);
+ });
+ });
+
+ describe('for a tag pipeline', () => {
+ it('renders a pipeline widget that reads "Pipeline <ID> <status> for <SHA> on <branch>"', () => {
+ pipeline.ref.tag = true;
+
+ factory();
+
+ const expected = `Pipeline #${pipeline.id} ${pipeline.details.status.label} for ${pipeline.commit.short_id}`;
+ const actual = trimText(vm.$el.querySelector('.js-pipeline-info-container').innerText);
+
+ expect(actual).toBe(expected);
+ });
+ });
+
+ describe('for a detached merge request pipeline', () => {
+ it('renders a pipeline widget that reads "Detached merge request pipeline <ID> <status> for <SHA>"', () => {
+ pipeline.details.name = 'Detached merge request pipeline';
+ pipeline.merge_request_event_type = 'detached';
+
+ factory();
+
+ const expected = `Detached merge request pipeline #${pipeline.id} ${pipeline.details.status.label} for ${pipeline.commit.short_id}`;
+ const actual = trimText(vm.$el.querySelector('.js-pipeline-info-container').innerText);
+
+ expect(actual).toBe(expected);
+ });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_rebase_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_rebase_spec.js
new file mode 100644
index 00000000000..6ec30493f8b
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/mr_widget_rebase_spec.js
@@ -0,0 +1,139 @@
+import Vue from 'vue';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import eventHub from '~/vue_merge_request_widget/event_hub';
+import component from '~/vue_merge_request_widget/components/states/mr_widget_rebase.vue';
+
+describe('Merge request widget rebase component', () => {
+ let Component;
+ let vm;
+ beforeEach(() => {
+ Component = Vue.extend(component);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('While rebasing', () => {
+ it('should show progress message', () => {
+ vm = mountComponent(Component, {
+ mr: { rebaseInProgress: true },
+ service: {},
+ });
+
+ expect(
+ vm.$el.querySelector('.rebase-state-find-class-convention span').textContent.trim(),
+ ).toContain('Rebase in progress');
+ });
+ });
+
+ describe('With permissions', () => {
+ beforeEach(() => {
+ vm = mountComponent(Component, {
+ mr: {
+ rebaseInProgress: false,
+ canPushToSourceBranch: true,
+ },
+ service: {},
+ });
+ });
+
+ it('it should render rebase button and warning message', () => {
+ const text = vm.$el
+ .querySelector('.rebase-state-find-class-convention span')
+ .textContent.trim();
+
+ expect(text).toContain('Fast-forward merge is not possible.');
+ expect(text.replace(/\s\s+/g, ' ')).toContain(
+ 'Rebase the source branch onto the target branch.',
+ );
+ });
+
+ it('it should render error message when it fails', done => {
+ vm.rebasingError = 'Something went wrong!';
+
+ Vue.nextTick(() => {
+ expect(
+ vm.$el.querySelector('.rebase-state-find-class-convention span').textContent.trim(),
+ ).toContain('Something went wrong!');
+ done();
+ });
+ });
+ });
+
+ describe('Without permissions', () => {
+ it('should render a message explaining user does not have permissions', () => {
+ vm = mountComponent(Component, {
+ mr: {
+ rebaseInProgress: false,
+ canPushToSourceBranch: false,
+ targetBranch: 'foo',
+ },
+ service: {},
+ });
+
+ const text = vm.$el
+ .querySelector('.rebase-state-find-class-convention span')
+ .textContent.trim();
+
+ expect(text).toContain('Fast-forward merge is not possible.');
+ expect(text).toContain('Rebase the source branch onto');
+ expect(text).toContain('foo');
+ expect(text.replace(/\s\s+/g, ' ')).toContain('to allow this merge request to be merged.');
+ });
+
+ it('should render the correct target branch name', () => {
+ const targetBranch = 'fake-branch-to-test-with';
+ vm = mountComponent(Component, {
+ mr: {
+ rebaseInProgress: false,
+ canPushToSourceBranch: false,
+ targetBranch,
+ },
+ service: {},
+ });
+
+ const elem = vm.$el.querySelector('.rebase-state-find-class-convention span');
+
+ expect(elem.innerHTML).toContain(
+ `Fast-forward merge is not possible. Rebase the source branch onto <span class="label-branch">${targetBranch}</span> to allow this merge request to be merged.`,
+ );
+ });
+ });
+
+ describe('methods', () => {
+ it('checkRebaseStatus', done => {
+ jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
+ vm = mountComponent(Component, {
+ mr: {},
+ service: {
+ rebase() {
+ return Promise.resolve();
+ },
+ poll() {
+ return Promise.resolve({
+ data: {
+ rebase_in_progress: false,
+ merge_error: null,
+ },
+ });
+ },
+ },
+ });
+
+ vm.rebase();
+
+ // Wait for the rebase request
+ vm.$nextTick()
+ // Wait for the polling request
+ .then(vm.$nextTick())
+ // Wait for the eventHub to be called
+ .then(vm.$nextTick())
+ .then(() => {
+ expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetRebaseSuccess');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_related_links_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_related_links_spec.js
new file mode 100644
index 00000000000..0c4ec7ed99b
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/mr_widget_related_links_spec.js
@@ -0,0 +1,85 @@
+import Vue from 'vue';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import relatedLinksComponent from '~/vue_merge_request_widget/components/mr_widget_related_links.vue';
+
+describe('MRWidgetRelatedLinks', () => {
+ let vm;
+
+ const createComponent = data => {
+ const Component = Vue.extend(relatedLinksComponent);
+
+ return mountComponent(Component, data);
+ };
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('computed', () => {
+ describe('closesText', () => {
+ it('returns Closes text for open merge request', () => {
+ vm = createComponent({ state: 'open', relatedLinks: {} });
+
+ expect(vm.closesText).toEqual('Closes');
+ });
+
+ it('returns correct text for closed merge request', () => {
+ vm = createComponent({ state: 'closed', relatedLinks: {} });
+
+ expect(vm.closesText).toEqual('Did not close');
+ });
+
+ it('returns correct tense for merged request', () => {
+ vm = createComponent({ state: 'merged', relatedLinks: {} });
+
+ expect(vm.closesText).toEqual('Closed');
+ });
+ });
+ });
+
+ it('should have only have closing issues text', () => {
+ vm = createComponent({
+ relatedLinks: {
+ closing: '<a href="#">#23</a> and <a>#42</a>',
+ },
+ });
+ const content = vm.$el.textContent.replace(/\n(\s)+/g, ' ').trim();
+
+ expect(content).toContain('Closes #23 and #42');
+ expect(content).not.toContain('Mentions');
+ });
+
+ it('should have only have mentioned issues text', () => {
+ vm = createComponent({
+ relatedLinks: {
+ mentioned: '<a href="#">#7</a>',
+ },
+ });
+
+ expect(vm.$el.innerText).toContain('Mentions #7');
+ expect(vm.$el.innerText).not.toContain('Closes');
+ });
+
+ it('should have closing and mentioned issues at the same time', () => {
+ vm = createComponent({
+ relatedLinks: {
+ closing: '<a href="#">#7</a>',
+ mentioned: '<a href="#">#23</a> and <a>#42</a>',
+ },
+ });
+ const content = vm.$el.textContent.replace(/\n(\s)+/g, ' ').trim();
+
+ expect(content).toContain('Closes #7');
+ expect(content).toContain('Mentions #23 and #42');
+ });
+
+ it('should have assing issues link', () => {
+ vm = createComponent({
+ relatedLinks: {
+ assignToMe: '<a href="#">Assign yourself to these issues</a>',
+ },
+ });
+
+ expect(vm.$el.innerText).toContain('Assign yourself to these issues');
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_status_icon_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_status_icon_spec.js
new file mode 100644
index 00000000000..6c3b4a01659
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/mr_widget_status_icon_spec.js
@@ -0,0 +1,48 @@
+import Vue from 'vue';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import mrStatusIcon from '~/vue_merge_request_widget/components/mr_widget_status_icon.vue';
+
+describe('MR widget status icon component', () => {
+ let vm;
+ let Component;
+
+ beforeEach(() => {
+ Component = Vue.extend(mrStatusIcon);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('while loading', () => {
+ it('renders loading icon', () => {
+ vm = mountComponent(Component, { status: 'loading' });
+
+ expect(vm.$el.querySelector('.mr-widget-icon span').classList).toContain('gl-spinner');
+ });
+ });
+
+ describe('with status icon', () => {
+ it('renders ci status icon', () => {
+ vm = mountComponent(Component, { status: 'failed' });
+
+ expect(vm.$el.querySelector('.js-ci-status-icon-failed')).not.toBeNull();
+ });
+ });
+
+ describe('with disabled button', () => {
+ it('renders a disabled button', () => {
+ vm = mountComponent(Component, { status: 'failed', showDisabledButton: true });
+
+ expect(vm.$el.querySelector('.js-disabled-merge-button').textContent.trim()).toEqual('Merge');
+ });
+ });
+
+ describe('without disabled button', () => {
+ it('does not render a disabled button', () => {
+ vm = mountComponent(Component, { status: 'failed' });
+
+ expect(vm.$el.querySelector('.js-disabled-merge-button')).toBeNull();
+ });
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_terraform_plan_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_terraform_plan_spec.js
index 91e95b2bdb1..62c5c8e8531 100644
--- a/spec/frontend/vue_mr_widget/components/mr_widget_terraform_plan_spec.js
+++ b/spec/frontend/vue_mr_widget/components/mr_widget_terraform_plan_spec.js
@@ -1,4 +1,4 @@
-import { GlLoadingIcon, GlSprintf } from '@gitlab/ui';
+import { GlLink, GlLoadingIcon, GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import axios from '~/lib/utils/axios_utils';
import MockAdapter from 'axios-mock-adapter';
@@ -38,7 +38,7 @@ describe('MrWidgetTerraformPlan', () => {
describe('loading poll', () => {
beforeEach(() => {
- mockPollingApi(200, { 'tfplan.json': plan }, {});
+ mockPollingApi(200, { '123': plan }, {});
return mountWrapper().then(() => {
wrapper.setData({ loading: true });
@@ -65,7 +65,7 @@ describe('MrWidgetTerraformPlan', () => {
pollRequest = jest.spyOn(Poll.prototype, 'makeRequest');
pollStop = jest.spyOn(Poll.prototype, 'stop');
- mockPollingApi(200, { 'tfplan.json': plan }, {});
+ mockPollingApi(200, { '123': plan }, {});
return mountWrapper();
});
@@ -80,7 +80,7 @@ describe('MrWidgetTerraformPlan', () => {
});
it('renders button when url is found', () => {
- expect(wrapper.find('a').text()).toContain('View full log');
+ expect(wrapper.find(GlLink).exists()).toBe(true);
});
it('does not make additional requests after poll is successful', () => {
@@ -101,7 +101,7 @@ describe('MrWidgetTerraformPlan', () => {
);
expect(wrapper.find('.js-terraform-report-link').exists()).toBe(false);
- expect(wrapper.text()).not.toContain('View full log');
+ expect(wrapper.find(GlLink).exists()).toBe(false);
});
});
});
diff --git a/spec/frontend/vue_mr_widget/components/review_app_link_spec.js b/spec/frontend/vue_mr_widget/components/review_app_link_spec.js
new file mode 100644
index 00000000000..7b063653a93
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/review_app_link_spec.js
@@ -0,0 +1,52 @@
+import Vue from 'vue';
+import { mockTracking, triggerEvent } from 'helpers/tracking_helper';
+import component from '~/vue_merge_request_widget/components/review_app_link.vue';
+import mountComponent from '../../helpers/vue_mount_component_helper';
+
+describe('review app link', () => {
+ const Component = Vue.extend(component);
+ const props = {
+ link: '/review',
+ cssClass: 'js-link',
+ display: {
+ text: 'View app',
+ tooltip: '',
+ },
+ };
+ let vm;
+ let el;
+
+ beforeEach(() => {
+ vm = mountComponent(Component, props);
+ el = vm.$el;
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('renders provided link as href attribute', () => {
+ expect(el.getAttribute('href')).toEqual(props.link);
+ });
+
+ it('renders provided cssClass as class attribute', () => {
+ expect(el.getAttribute('class')).toEqual(props.cssClass);
+ });
+
+ it('renders View app text', () => {
+ expect(el.textContent.trim()).toEqual('View app');
+ });
+
+ it('renders svg icon', () => {
+ expect(el.querySelector('svg')).not.toBeNull();
+ });
+
+ it('tracks an event when clicked', () => {
+ const spy = mockTracking('_category_', el, jest.spyOn);
+ triggerEvent(el);
+
+ expect(spy).toHaveBeenCalledWith('_category_', 'open_review_app', {
+ label: 'review_app',
+ });
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_archived_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_archived_spec.js
new file mode 100644
index 00000000000..4bdc6c95f22
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_archived_spec.js
@@ -0,0 +1,31 @@
+import Vue from 'vue';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import archivedComponent from '~/vue_merge_request_widget/components/states/mr_widget_archived.vue';
+
+describe('MRWidgetArchived', () => {
+ let vm;
+
+ beforeEach(() => {
+ const Component = Vue.extend(archivedComponent);
+ vm = mountComponent(Component);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('renders a ci status failed icon', () => {
+ expect(vm.$el.querySelector('.ci-status-icon')).not.toBeNull();
+ });
+
+ it('renders a disabled button', () => {
+ expect(vm.$el.querySelector('button').getAttribute('disabled')).toEqual('disabled');
+ expect(vm.$el.querySelector('button').textContent.trim()).toEqual('Merge');
+ });
+
+ it('renders information', () => {
+ expect(vm.$el.querySelector('.bold').textContent.trim()).toEqual(
+ 'This project is archived, write access has been disabled',
+ );
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_auto_merge_enabled_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_auto_merge_enabled_spec.js
new file mode 100644
index 00000000000..e2caa6e8092
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_auto_merge_enabled_spec.js
@@ -0,0 +1,230 @@
+import Vue from 'vue';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import { trimText } from 'helpers/text_helper';
+import autoMergeEnabledComponent from '~/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue';
+import MRWidgetService from '~/vue_merge_request_widget/services/mr_widget_service';
+import eventHub from '~/vue_merge_request_widget/event_hub';
+import { MWPS_MERGE_STRATEGY } from '~/vue_merge_request_widget/constants';
+
+describe('MRWidgetAutoMergeEnabled', () => {
+ let vm;
+ const targetBranchPath = '/foo/bar';
+ const targetBranch = 'foo';
+ const sha = '1EA2EZ34';
+
+ beforeEach(() => {
+ const Component = Vue.extend(autoMergeEnabledComponent);
+ jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
+
+ vm = mountComponent(Component, {
+ mr: {
+ shouldRemoveSourceBranch: false,
+ canRemoveSourceBranch: true,
+ canCancelAutomaticMerge: true,
+ mergeUserId: 1,
+ currentUserId: 1,
+ setToAutoMergeBy: {},
+ sha,
+ targetBranchPath,
+ targetBranch,
+ autoMergeStrategy: MWPS_MERGE_STRATEGY,
+ },
+ service: new MRWidgetService({}),
+ });
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('computed', () => {
+ describe('canRemoveSourceBranch', () => {
+ it('should return true when user is able to remove source branch', () => {
+ expect(vm.canRemoveSourceBranch).toBeTruthy();
+ });
+
+ it('should return false when user id is not the same with who set the MWPS', () => {
+ vm.mr.mergeUserId = 2;
+
+ expect(vm.canRemoveSourceBranch).toBeFalsy();
+
+ vm.mr.currentUserId = 2;
+
+ expect(vm.canRemoveSourceBranch).toBeTruthy();
+
+ vm.mr.currentUserId = 3;
+
+ expect(vm.canRemoveSourceBranch).toBeFalsy();
+ });
+
+ it('should return false when shouldRemoveSourceBranch set to false', () => {
+ vm.mr.shouldRemoveSourceBranch = true;
+
+ expect(vm.canRemoveSourceBranch).toBeFalsy();
+ });
+
+ it('should return false if user is not able to remove the source branch', () => {
+ vm.mr.canRemoveSourceBranch = false;
+
+ expect(vm.canRemoveSourceBranch).toBeFalsy();
+ });
+ });
+
+ describe('statusTextBeforeAuthor', () => {
+ it('should return "Set by" if the MWPS is selected', () => {
+ Vue.set(vm.mr, 'autoMergeStrategy', MWPS_MERGE_STRATEGY);
+
+ expect(vm.statusTextBeforeAuthor).toBe('Set by');
+ });
+ });
+
+ describe('statusTextAfterAuthor', () => {
+ it('should return "to be merged automatically..." if MWPS is selected', () => {
+ Vue.set(vm.mr, 'autoMergeStrategy', MWPS_MERGE_STRATEGY);
+
+ expect(vm.statusTextAfterAuthor).toBe(
+ 'to be merged automatically when the pipeline succeeds',
+ );
+ });
+ });
+
+ describe('cancelButtonText', () => {
+ it('should return "Cancel automatic merge" if MWPS is selected', () => {
+ Vue.set(vm.mr, 'autoMergeStrategy', MWPS_MERGE_STRATEGY);
+
+ expect(vm.cancelButtonText).toBe('Cancel automatic merge');
+ });
+ });
+ });
+
+ describe('methods', () => {
+ describe('cancelAutomaticMerge', () => {
+ it('should set flag and call service then tell main component to update the widget with data', done => {
+ const mrObj = {
+ is_new_mr_data: true,
+ };
+ jest.spyOn(vm.service, 'cancelAutomaticMerge').mockReturnValue(
+ new Promise(resolve => {
+ resolve({
+ data: mrObj,
+ });
+ }),
+ );
+
+ vm.cancelAutomaticMerge();
+ setImmediate(() => {
+ expect(vm.isCancellingAutoMerge).toBeTruthy();
+ expect(eventHub.$emit).toHaveBeenCalledWith('UpdateWidgetData', mrObj);
+ done();
+ });
+ });
+ });
+
+ describe('removeSourceBranch', () => {
+ it('should set flag and call service then request main component to update the widget', done => {
+ jest.spyOn(vm.service, 'merge').mockReturnValue(
+ Promise.resolve({
+ data: {
+ status: MWPS_MERGE_STRATEGY,
+ },
+ }),
+ );
+
+ vm.removeSourceBranch();
+ setImmediate(() => {
+ expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetUpdateRequested');
+ expect(vm.service.merge).toHaveBeenCalledWith({
+ sha,
+ auto_merge_strategy: MWPS_MERGE_STRATEGY,
+ should_remove_source_branch: true,
+ });
+ done();
+ });
+ });
+ });
+ });
+
+ describe('template', () => {
+ it('should have correct elements', () => {
+ expect(vm.$el.classList.contains('mr-widget-body')).toBeTruthy();
+ expect(vm.$el.innerText).toContain('to be merged automatically when the pipeline succeeds');
+
+ expect(vm.$el.innerText).toContain('The changes will be merged into');
+ expect(vm.$el.innerText).toContain(targetBranch);
+ expect(vm.$el.innerText).toContain('The source branch will not be deleted');
+ expect(vm.$el.querySelector('.js-cancel-auto-merge').innerText).toContain(
+ 'Cancel automatic merge',
+ );
+
+ expect(vm.$el.querySelector('.js-cancel-auto-merge').getAttribute('disabled')).toBeFalsy();
+ expect(vm.$el.querySelector('.js-remove-source-branch').innerText).toContain(
+ 'Delete source branch',
+ );
+
+ expect(vm.$el.querySelector('.js-remove-source-branch').getAttribute('disabled')).toBeFalsy();
+ });
+
+ it('should disable cancel auto merge button when the action is in progress', done => {
+ vm.isCancellingAutoMerge = true;
+
+ Vue.nextTick(() => {
+ expect(vm.$el.querySelector('.js-cancel-auto-merge').getAttribute('disabled')).toBeTruthy();
+ done();
+ });
+ });
+
+ it('should show source branch will be deleted text when it source branch set to remove', done => {
+ vm.mr.shouldRemoveSourceBranch = true;
+
+ Vue.nextTick(() => {
+ const normalizedText = vm.$el.innerText.replace(/\s+/g, ' ');
+
+ expect(normalizedText).toContain('The source branch will be deleted');
+ expect(normalizedText).not.toContain('The source branch will not be deleted');
+ done();
+ });
+ });
+
+ it('should not show delete source branch button when user not able to delete source branch', done => {
+ vm.mr.currentUserId = 4;
+
+ Vue.nextTick(() => {
+ expect(vm.$el.querySelector('.js-remove-source-branch')).toEqual(null);
+ done();
+ });
+ });
+
+ it('should disable delete source branch button when the action is in progress', done => {
+ vm.isRemovingSourceBranch = true;
+
+ Vue.nextTick(() => {
+ expect(
+ vm.$el.querySelector('.js-remove-source-branch').getAttribute('disabled'),
+ ).toBeTruthy();
+ done();
+ });
+ });
+
+ it('should render the status text as "...to merged automatically" if MWPS is selected', done => {
+ Vue.set(vm.mr, 'autoMergeStrategy', MWPS_MERGE_STRATEGY);
+
+ Vue.nextTick(() => {
+ const statusText = trimText(vm.$el.querySelector('.js-status-text-after-author').innerText);
+
+ expect(statusText).toBe('to be merged automatically when the pipeline succeeds');
+ done();
+ });
+ });
+
+ it('should render the cancel button as "Cancel automatic merge" if MWPS is selected', done => {
+ Vue.set(vm.mr, 'autoMergeStrategy', MWPS_MERGE_STRATEGY);
+
+ Vue.nextTick(() => {
+ const cancelButtonText = trimText(vm.$el.querySelector('.js-cancel-auto-merge').innerText);
+
+ expect(cancelButtonText).toBe('Cancel automatic merge');
+ done();
+ });
+ });
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_checking_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_checking_spec.js
new file mode 100644
index 00000000000..56d55c9afac
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_checking_spec.js
@@ -0,0 +1,31 @@
+import Vue from 'vue';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import checkingComponent from '~/vue_merge_request_widget/components/states/mr_widget_checking.vue';
+
+describe('MRWidgetChecking', () => {
+ let Component;
+ let vm;
+
+ beforeEach(() => {
+ Component = Vue.extend(checkingComponent);
+ vm = mountComponent(Component);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('renders disabled button', () => {
+ expect(vm.$el.querySelector('button').getAttribute('disabled')).toEqual('disabled');
+ });
+
+ it('renders loading icon', () => {
+ expect(vm.$el.querySelector('.mr-widget-icon span').classList).toContain('gl-spinner');
+ });
+
+ it('renders information about merging', () => {
+ expect(vm.$el.querySelector('.media-body').textContent.trim()).toEqual(
+ 'Checking ability to merge automatically…',
+ );
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_closed_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_closed_spec.js
new file mode 100644
index 00000000000..322f440763c
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_closed_spec.js
@@ -0,0 +1,69 @@
+import Vue from 'vue';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import closedComponent from '~/vue_merge_request_widget/components/states/mr_widget_closed.vue';
+
+describe('MRWidgetClosed', () => {
+ let vm;
+
+ beforeEach(() => {
+ const Component = Vue.extend(closedComponent);
+ vm = mountComponent(Component, {
+ mr: {
+ metrics: {
+ mergedBy: {},
+ closedBy: {
+ name: 'Administrator',
+ username: 'root',
+ webUrl: 'http://localhost:3000/root',
+ avatarUrl:
+ 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ },
+ mergedAt: 'Jan 24, 2018 1:02pm GMT+0000',
+ closedAt: 'Jan 24, 2018 1:02pm GMT+0000',
+ readableMergedAt: '',
+ readableClosedAt: 'less than a minute ago',
+ },
+ targetBranchPath: '/twitter/flight/commits/so_long_jquery',
+ targetBranch: 'so_long_jquery',
+ },
+ });
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('renders warning icon', () => {
+ expect(vm.$el.querySelector('.js-ci-status-icon-warning')).not.toBeNull();
+ });
+
+ it('renders closed by information with author and time', () => {
+ expect(
+ vm.$el
+ .querySelector('.js-mr-widget-author')
+ .textContent.trim()
+ .replace(/\s\s+/g, ' '),
+ ).toContain('Closed by Administrator less than a minute ago');
+ });
+
+ it('links to the user that closed the MR', () => {
+ expect(vm.$el.querySelector('.author-link').getAttribute('href')).toEqual(
+ 'http://localhost:3000/root',
+ );
+ });
+
+ it('renders information about the changes not being merged', () => {
+ expect(
+ vm.$el
+ .querySelector('.mr-info-list')
+ .textContent.trim()
+ .replace(/\s\s+/g, ' '),
+ ).toContain('The changes were not merged into so_long_jquery');
+ });
+
+ it('renders link for target branch', () => {
+ expect(vm.$el.querySelector('.label-branch').getAttribute('href')).toEqual(
+ '/twitter/flight/commits/so_long_jquery',
+ );
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_conflicts_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_conflicts_spec.js
new file mode 100644
index 00000000000..d3482b457ad
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_conflicts_spec.js
@@ -0,0 +1,226 @@
+import $ from 'jquery';
+import { createLocalVue, shallowMount } from '@vue/test-utils';
+import { removeBreakLine } from 'helpers/text_helper';
+import ConflictsComponent from '~/vue_merge_request_widget/components/states/mr_widget_conflicts.vue';
+import { TEST_HOST } from 'helpers/test_constants';
+
+describe('MRWidgetConflicts', () => {
+ let vm;
+ const path = '/conflicts';
+
+ function createComponent(propsData = {}) {
+ const localVue = createLocalVue();
+
+ vm = shallowMount(localVue.extend(ConflictsComponent), {
+ propsData,
+ });
+ }
+
+ beforeEach(() => {
+ jest.spyOn($.fn, 'popover');
+ });
+
+ afterEach(() => {
+ vm.destroy();
+ });
+
+ // There are two permissions we need to consider:
+ //
+ // 1. Is the user allowed to merge to the target branch?
+ // 2. Is the user allowed to push to the source branch?
+ //
+ // This yields 4 possible permutations that we need to test, and
+ // we test them below. A user who can push to the source
+ // branch should be allowed to resolve conflicts. This is
+ // consistent with what the backend does.
+ describe('when allowed to merge but not allowed to push to source branch', () => {
+ beforeEach(() => {
+ createComponent({
+ mr: {
+ canMerge: true,
+ canPushToSourceBranch: false,
+ conflictResolutionPath: path,
+ conflictsDocsPath: '',
+ },
+ });
+ });
+
+ it('should tell you about conflicts without bothering other people', () => {
+ expect(vm.text()).toContain('There are merge conflicts');
+ expect(vm.text()).not.toContain('ask someone with write access');
+ });
+
+ it('should not allow you to resolve the conflicts', () => {
+ expect(vm.text()).not.toContain('Resolve conflicts');
+ });
+
+ it('should have merge buttons', () => {
+ const mergeLocallyButton = vm.find('.js-merge-locally-button');
+
+ expect(mergeLocallyButton.text()).toContain('Merge locally');
+ });
+ });
+
+ describe('when not allowed to merge but allowed to push to source branch', () => {
+ beforeEach(() => {
+ createComponent({
+ mr: {
+ canMerge: false,
+ canPushToSourceBranch: true,
+ conflictResolutionPath: path,
+ conflictsDocsPath: '',
+ },
+ });
+ });
+
+ it('should tell you about conflicts', () => {
+ expect(vm.text()).toContain('There are merge conflicts');
+ expect(vm.text()).toContain('ask someone with write access');
+ });
+
+ it('should allow you to resolve the conflicts', () => {
+ const resolveButton = vm.find('.js-resolve-conflicts-button');
+
+ expect(resolveButton.text()).toContain('Resolve conflicts');
+ expect(resolveButton.attributes('href')).toEqual(path);
+ });
+
+ it('should not have merge buttons', () => {
+ expect(vm.text()).not.toContain('Merge locally');
+ });
+ });
+
+ describe('when allowed to merge and push to source branch', () => {
+ beforeEach(() => {
+ createComponent({
+ mr: {
+ canMerge: true,
+ canPushToSourceBranch: true,
+ conflictResolutionPath: path,
+ conflictsDocsPath: '',
+ },
+ });
+ });
+
+ it('should tell you about conflicts without bothering other people', () => {
+ expect(vm.text()).toContain('There are merge conflicts');
+ expect(vm.text()).not.toContain('ask someone with write access');
+ });
+
+ it('should allow you to resolve the conflicts', () => {
+ const resolveButton = vm.find('.js-resolve-conflicts-button');
+
+ expect(resolveButton.text()).toContain('Resolve conflicts');
+ expect(resolveButton.attributes('href')).toEqual(path);
+ });
+
+ it('should have merge buttons', () => {
+ const mergeLocallyButton = vm.find('.js-merge-locally-button');
+
+ expect(mergeLocallyButton.text()).toContain('Merge locally');
+ });
+ });
+
+ describe('when user does not have permission to push to source branch', () => {
+ it('should show proper message', () => {
+ createComponent({
+ mr: {
+ canMerge: false,
+ canPushToSourceBranch: false,
+ conflictsDocsPath: '',
+ },
+ });
+
+ expect(
+ vm
+ .text()
+ .trim()
+ .replace(/\s\s+/g, ' '),
+ ).toContain('ask someone with write access');
+ });
+
+ it('should not have action buttons', () => {
+ createComponent({
+ mr: {
+ canMerge: false,
+ canPushToSourceBranch: false,
+ conflictsDocsPath: '',
+ },
+ });
+
+ expect(vm.contains('.js-resolve-conflicts-button')).toBe(false);
+ expect(vm.contains('.js-merge-locally-button')).toBe(false);
+ });
+
+ it('should not have resolve button when no conflict resolution path', () => {
+ createComponent({
+ mr: {
+ canMerge: true,
+ conflictResolutionPath: null,
+ conflictsDocsPath: '',
+ },
+ });
+
+ expect(vm.contains('.js-resolve-conflicts-button')).toBe(false);
+ });
+ });
+
+ describe('when fast-forward or semi-linear merge enabled', () => {
+ it('should tell you to rebase locally', () => {
+ createComponent({
+ mr: {
+ shouldBeRebased: true,
+ conflictsDocsPath: '',
+ },
+ });
+
+ expect(removeBreakLine(vm.text()).trim()).toContain(
+ 'Fast-forward merge is not possible. To merge this request, first rebase locally.',
+ );
+ });
+ });
+
+ describe('when source branch protected', () => {
+ beforeEach(() => {
+ createComponent({
+ mr: {
+ canMerge: true,
+ canPushToSourceBranch: true,
+ conflictResolutionPath: TEST_HOST,
+ sourceBranchProtected: true,
+ conflictsDocsPath: '',
+ },
+ });
+ });
+
+ it('sets resolve button as disabled', () => {
+ expect(vm.find('.js-resolve-conflicts-button').attributes('disabled')).toBe('disabled');
+ });
+
+ it('renders popover', () => {
+ expect($.fn.popover).toHaveBeenCalled();
+ });
+ });
+
+ describe('when source branch not protected', () => {
+ beforeEach(() => {
+ createComponent({
+ mr: {
+ canMerge: true,
+ canPushToSourceBranch: true,
+ conflictResolutionPath: TEST_HOST,
+ sourceBranchProtected: false,
+ conflictsDocsPath: '',
+ },
+ });
+ });
+
+ it('sets resolve button as disabled', () => {
+ expect(vm.find('.js-resolve-conflicts-button').attributes('disabled')).toBe(undefined);
+ });
+
+ it('renders popover', () => {
+ expect($.fn.popover).not.toHaveBeenCalled();
+ });
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js
new file mode 100644
index 00000000000..f591393d721
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js
@@ -0,0 +1,156 @@
+import Vue from 'vue';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import failedToMergeComponent from '~/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.vue';
+import eventHub from '~/vue_merge_request_widget/event_hub';
+
+describe('MRWidgetFailedToMerge', () => {
+ const dummyIntervalId = 1337;
+ let Component;
+ let mr;
+ let vm;
+
+ beforeEach(() => {
+ Component = Vue.extend(failedToMergeComponent);
+ jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
+ jest.spyOn(window, 'setInterval').mockReturnValue(dummyIntervalId);
+ jest.spyOn(window, 'clearInterval').mockImplementation();
+ mr = {
+ mergeError: 'Merge error happened',
+ };
+ vm = mountComponent(Component, {
+ mr,
+ });
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('sets interval to refresh', () => {
+ expect(window.setInterval).toHaveBeenCalledWith(vm.updateTimer, 1000);
+ expect(vm.intervalId).toBe(dummyIntervalId);
+ });
+
+ it('clears interval when destroying ', () => {
+ vm.$destroy();
+
+ expect(window.clearInterval).toHaveBeenCalledWith(dummyIntervalId);
+ });
+
+ describe('computed', () => {
+ describe('timerText', () => {
+ it('should return correct timer text', () => {
+ expect(vm.timerText).toEqual('Refreshing in 10 seconds to show the updated status...');
+
+ vm.timer = 1;
+
+ expect(vm.timerText).toEqual('Refreshing in a second to show the updated status...');
+ });
+ });
+
+ describe('mergeError', () => {
+ it('removes forced line breaks', done => {
+ mr.mergeError = 'contains<br />line breaks<br />';
+
+ Vue.nextTick()
+ .then(() => {
+ expect(vm.mergeError).toBe('contains line breaks');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+ });
+
+ describe('created', () => {
+ it('should disable polling', () => {
+ expect(eventHub.$emit).toHaveBeenCalledWith('DisablePolling');
+ });
+ });
+
+ describe('methods', () => {
+ describe('refresh', () => {
+ it('should emit event to request component refresh', () => {
+ expect(vm.isRefreshing).toEqual(false);
+
+ vm.refresh();
+
+ expect(vm.isRefreshing).toEqual(true);
+ expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetUpdateRequested');
+ expect(eventHub.$emit).toHaveBeenCalledWith('EnablePolling');
+ });
+ });
+
+ describe('updateTimer', () => {
+ it('should update timer and emit event when timer end', () => {
+ jest.spyOn(vm, 'refresh').mockImplementation(() => {});
+
+ expect(vm.timer).toEqual(10);
+
+ for (let i = 0; i < 10; i += 1) {
+ expect(vm.timer).toEqual(10 - i);
+ vm.updateTimer();
+ }
+
+ expect(vm.refresh).toHaveBeenCalled();
+ });
+ });
+ });
+
+ describe('while it is refreshing', () => {
+ it('renders Refresing now', done => {
+ vm.isRefreshing = true;
+
+ Vue.nextTick(() => {
+ expect(vm.$el.querySelector('.js-refresh-label').textContent.trim()).toEqual(
+ 'Refreshing now',
+ );
+ done();
+ });
+ });
+ });
+
+ describe('while it is not regresing', () => {
+ it('renders warning icon and disabled merge button', () => {
+ expect(vm.$el.querySelector('.js-ci-status-icon-warning')).not.toBeNull();
+ expect(vm.$el.querySelector('.js-disabled-merge-button').getAttribute('disabled')).toEqual(
+ 'disabled',
+ );
+ });
+
+ it('renders given error', () => {
+ expect(vm.$el.querySelector('.has-error-message').textContent.trim()).toEqual(
+ 'Merge error happened',
+ );
+ });
+
+ it('renders refresh button', () => {
+ expect(vm.$el.querySelector('.js-refresh-button').textContent.trim()).toEqual('Refresh now');
+ });
+
+ it('renders remaining time', () => {
+ expect(vm.$el.querySelector('.has-custom-error').textContent.trim()).toEqual(
+ 'Refreshing in 10 seconds to show the updated status...',
+ );
+ });
+ });
+
+ it('should just generic merge failed message if merge_error is not available', done => {
+ vm.mr.mergeError = null;
+
+ Vue.nextTick(() => {
+ expect(vm.$el.innerText).toContain('Merge failed.');
+ expect(vm.$el.innerText).not.toContain('Merge error happened.');
+ done();
+ });
+ });
+
+ it('should show refresh label when refresh requested', done => {
+ vm.refresh();
+ Vue.nextTick(() => {
+ expect(vm.$el.innerText).not.toContain('Merge failed. Refreshing');
+ expect(vm.$el.innerText).toContain('Refreshing now');
+ done();
+ });
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_merged_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_merged_spec.js
new file mode 100644
index 00000000000..1921599ae95
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_merged_spec.js
@@ -0,0 +1,219 @@
+import Vue from 'vue';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import mergedComponent from '~/vue_merge_request_widget/components/states/mr_widget_merged.vue';
+import eventHub from '~/vue_merge_request_widget/event_hub';
+
+describe('MRWidgetMerged', () => {
+ let vm;
+ const targetBranch = 'foo';
+ const selectors = {
+ get copyMergeShaButton() {
+ return vm.$el.querySelector('button.js-mr-merged-copy-sha');
+ },
+ get mergeCommitShaLink() {
+ return vm.$el.querySelector('a.js-mr-merged-commit-sha');
+ },
+ };
+
+ beforeEach(() => {
+ const Component = Vue.extend(mergedComponent);
+ const mr = {
+ isRemovingSourceBranch: false,
+ cherryPickInForkPath: false,
+ canCherryPickInCurrentMR: true,
+ revertInForkPath: false,
+ canRevertInCurrentMR: true,
+ canRemoveSourceBranch: true,
+ sourceBranchRemoved: true,
+ metrics: {
+ mergedBy: {
+ name: 'Administrator',
+ username: 'root',
+ webUrl: 'http://localhost:3000/root',
+ avatarUrl:
+ 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ },
+ mergedAt: 'Jan 24, 2018 1:02pm GMT+0000',
+ readableMergedAt: '',
+ closedBy: {},
+ closedAt: 'Jan 24, 2018 1:02pm GMT+0000',
+ readableClosedAt: '',
+ },
+ updatedAt: 'mergedUpdatedAt',
+ shortMergeCommitSha: '958c0475',
+ mergeCommitSha: '958c047516e182dfc52317f721f696e8a1ee85ed',
+ mergeCommitPath:
+ 'http://localhost:3000/root/nautilus/commit/f7ce827c314c9340b075657fd61c789fb01cf74d',
+ sourceBranch: 'bar',
+ targetBranch,
+ };
+
+ const service = {
+ removeSourceBranch() {},
+ };
+
+ jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
+
+ vm = mountComponent(Component, { mr, service });
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('computed', () => {
+ describe('shouldShowRemoveSourceBranch', () => {
+ it('returns true when sourceBranchRemoved is false', () => {
+ vm.mr.sourceBranchRemoved = false;
+
+ expect(vm.shouldShowRemoveSourceBranch).toEqual(true);
+ });
+
+ it('returns false when sourceBranchRemoved is true', () => {
+ vm.mr.sourceBranchRemoved = true;
+
+ expect(vm.shouldShowRemoveSourceBranch).toEqual(false);
+ });
+
+ it('returns false when canRemoveSourceBranch is false', () => {
+ vm.mr.sourceBranchRemoved = false;
+ vm.mr.canRemoveSourceBranch = false;
+
+ expect(vm.shouldShowRemoveSourceBranch).toEqual(false);
+ });
+
+ it('returns false when is making request', () => {
+ vm.mr.canRemoveSourceBranch = true;
+ vm.isMakingRequest = true;
+
+ expect(vm.shouldShowRemoveSourceBranch).toEqual(false);
+ });
+
+ it('returns true when all are true', () => {
+ vm.mr.isRemovingSourceBranch = true;
+ vm.mr.canRemoveSourceBranch = true;
+ vm.isMakingRequest = true;
+
+ expect(vm.shouldShowRemoveSourceBranch).toEqual(false);
+ });
+ });
+
+ describe('shouldShowSourceBranchRemoving', () => {
+ it('should correct value when fields changed', () => {
+ vm.mr.sourceBranchRemoved = false;
+
+ expect(vm.shouldShowSourceBranchRemoving).toEqual(false);
+
+ vm.mr.sourceBranchRemoved = true;
+
+ expect(vm.shouldShowRemoveSourceBranch).toEqual(false);
+
+ vm.mr.sourceBranchRemoved = false;
+ vm.isMakingRequest = true;
+
+ expect(vm.shouldShowSourceBranchRemoving).toEqual(true);
+
+ vm.isMakingRequest = false;
+ vm.mr.isRemovingSourceBranch = true;
+
+ expect(vm.shouldShowSourceBranchRemoving).toEqual(true);
+ });
+ });
+ });
+
+ describe('methods', () => {
+ describe('removeSourceBranch', () => {
+ it('should set flag and call service then request main component to update the widget', done => {
+ jest.spyOn(vm.service, 'removeSourceBranch').mockReturnValue(
+ new Promise(resolve => {
+ resolve({
+ data: {
+ message: 'Branch was deleted',
+ },
+ });
+ }),
+ );
+
+ vm.removeSourceBranch();
+ setImmediate(() => {
+ const args = eventHub.$emit.mock.calls[0];
+
+ expect(vm.isMakingRequest).toEqual(true);
+ expect(args[0]).toEqual('MRWidgetUpdateRequested');
+ expect(args[1]).not.toThrow();
+ done();
+ });
+ });
+ });
+ });
+
+ it('has merged by information', () => {
+ expect(vm.$el.textContent).toContain('Merged by');
+ expect(vm.$el.textContent).toContain('Administrator');
+ });
+
+ it('renders branch information', () => {
+ expect(vm.$el.textContent).toContain('The changes were merged into');
+ expect(vm.$el.textContent).toContain(targetBranch);
+ });
+
+ it('renders information about branch being deleted', () => {
+ expect(vm.$el.textContent).toContain('The source branch has been deleted');
+ });
+
+ it('shows revert and cherry-pick buttons', () => {
+ expect(vm.$el.textContent).toContain('Revert');
+ expect(vm.$el.textContent).toContain('Cherry-pick');
+ });
+
+ it('shows button to copy commit SHA to clipboard', () => {
+ expect(selectors.copyMergeShaButton).toExist();
+ expect(selectors.copyMergeShaButton.getAttribute('data-clipboard-text')).toBe(
+ vm.mr.mergeCommitSha,
+ );
+ });
+
+ it('hides button to copy commit SHA if SHA does not exist', done => {
+ vm.mr.mergeCommitSha = null;
+
+ Vue.nextTick(() => {
+ expect(selectors.copyMergeShaButton).not.toExist();
+ expect(vm.$el.querySelector('.mr-info-list').innerText).not.toContain('with');
+ done();
+ });
+ });
+
+ it('shows merge commit SHA link', () => {
+ expect(selectors.mergeCommitShaLink).toExist();
+ expect(selectors.mergeCommitShaLink.text).toContain(vm.mr.shortMergeCommitSha);
+ expect(selectors.mergeCommitShaLink.href).toBe(vm.mr.mergeCommitPath);
+ });
+
+ it('should not show source branch deleted text', done => {
+ vm.mr.sourceBranchRemoved = false;
+
+ Vue.nextTick(() => {
+ expect(vm.$el.innerText).toContain('You can delete the source branch now');
+ expect(vm.$el.innerText).not.toContain('The source branch has been deleted');
+ done();
+ });
+ });
+
+ it('should show source branch deleting text', done => {
+ vm.mr.isRemovingSourceBranch = true;
+ vm.mr.sourceBranchRemoved = false;
+
+ Vue.nextTick(() => {
+ expect(vm.$el.innerText).toContain('The source branch is being deleted');
+ expect(vm.$el.innerText).not.toContain('You can delete the source branch now');
+ expect(vm.$el.innerText).not.toContain('The source branch has been deleted');
+ done();
+ });
+ });
+
+ it('should use mergedEvent mergedAt as tooltip title', () => {
+ expect(vm.$el.querySelector('time').getAttribute('data-original-title')).toBe(
+ 'Jan 24, 2018 1:02pm GMT+0000',
+ );
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_merging_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_merging_spec.js
new file mode 100644
index 00000000000..222cb74cc66
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_merging_spec.js
@@ -0,0 +1,43 @@
+import Vue from 'vue';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import mergingComponent from '~/vue_merge_request_widget/components/states/mr_widget_merging.vue';
+
+describe('MRWidgetMerging', () => {
+ let vm;
+ beforeEach(() => {
+ const Component = Vue.extend(mergingComponent);
+
+ vm = mountComponent(Component, {
+ mr: {
+ targetBranchPath: '/branch-path',
+ targetBranch: 'branch',
+ },
+ });
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('renders information about merge request being merged', () => {
+ expect(
+ vm.$el
+ .querySelector('.media-body')
+ .textContent.trim()
+ .replace(/\s\s+/g, ' ')
+ .replace(/[\r\n]+/g, ' '),
+ ).toContain('This merge request is in the process of being merged');
+ });
+
+ it('renders branch information', () => {
+ expect(
+ vm.$el
+ .querySelector('.mr-info-list')
+ .textContent.trim()
+ .replace(/\s\s+/g, ' ')
+ .replace(/[\r\n]+/g, ' '),
+ ).toEqual('The changes will be merged into branch');
+
+ expect(vm.$el.querySelector('a').getAttribute('href')).toEqual('/branch-path');
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js
new file mode 100644
index 00000000000..3f03ebdb047
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js
@@ -0,0 +1,40 @@
+import Vue from 'vue';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import missingBranchComponent from '~/vue_merge_request_widget/components/states/mr_widget_missing_branch.vue';
+
+describe('MRWidgetMissingBranch', () => {
+ let vm;
+
+ beforeEach(() => {
+ const Component = Vue.extend(missingBranchComponent);
+ vm = mountComponent(Component, { mr: { sourceBranchRemoved: true } });
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('computed', () => {
+ describe('missingBranchName', () => {
+ it('should return proper branch name', () => {
+ expect(vm.missingBranchName).toEqual('source');
+
+ vm.mr.sourceBranchRemoved = false;
+
+ expect(vm.missingBranchName).toEqual('target');
+ });
+ });
+ });
+
+ describe('template', () => {
+ it('should have correct elements', () => {
+ const el = vm.$el;
+ const content = el.textContent.replace(/\n(\s)+/g, ' ').trim();
+
+ expect(el.classList.contains('mr-widget-body')).toBeTruthy();
+ expect(el.querySelector('button').getAttribute('disabled')).toBeTruthy();
+ expect(content.replace(/\s\s+/g, ' ')).toContain('source branch does not exist.');
+ expect(content).toContain('Please restore it or use a different source branch');
+ });
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_not_allowed_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_not_allowed_spec.js
new file mode 100644
index 00000000000..63e93074857
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_not_allowed_spec.js
@@ -0,0 +1,26 @@
+import Vue from 'vue';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import notAllowedComponent from '~/vue_merge_request_widget/components/states/mr_widget_not_allowed.vue';
+
+describe('MRWidgetNotAllowed', () => {
+ let vm;
+ beforeEach(() => {
+ const Component = Vue.extend(notAllowedComponent);
+ vm = mountComponent(Component);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('renders success icon', () => {
+ expect(vm.$el.querySelector('.ci-status-icon-success')).not.toBe(null);
+ });
+
+ it('renders informative text', () => {
+ expect(vm.$el.innerText).toContain('Ready to be merged automatically.');
+ expect(vm.$el.innerText).toContain(
+ 'Ask someone with write access to this repository to merge this request',
+ );
+ });
+});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js
index bd0bd36ebc2..bd0bd36ebc2 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js
new file mode 100644
index 00000000000..8847e4e6bdd
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js
@@ -0,0 +1,26 @@
+import Vue from 'vue';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import { removeBreakLine } from 'helpers/text_helper';
+import pipelineBlockedComponent from '~/vue_merge_request_widget/components/states/mr_widget_pipeline_blocked.vue';
+
+describe('MRWidgetPipelineBlocked', () => {
+ let vm;
+ beforeEach(() => {
+ const Component = Vue.extend(pipelineBlockedComponent);
+ vm = mountComponent(Component);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('renders warning icon', () => {
+ expect(vm.$el.querySelector('.ci-status-icon-warning')).not.toBe(null);
+ });
+
+ it('renders information text', () => {
+ expect(removeBreakLine(vm.$el.textContent).trim()).toContain(
+ 'Pipeline blocked. The pipeline for this merge request requires a manual action to proceed',
+ );
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js
new file mode 100644
index 00000000000..179adef12d9
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js
@@ -0,0 +1,19 @@
+import Vue from 'vue';
+import { removeBreakLine } from 'helpers/text_helper';
+import PipelineFailed from '~/vue_merge_request_widget/components/states/pipeline_failed.vue';
+
+describe('PipelineFailed', () => {
+ describe('template', () => {
+ const Component = Vue.extend(PipelineFailed);
+ const vm = new Component({
+ el: document.createElement('div'),
+ });
+ it('should have correct elements', () => {
+ expect(vm.$el.classList.contains('mr-widget-body')).toBeTruthy();
+ expect(vm.$el.querySelector('button').getAttribute('disabled')).toBeTruthy();
+ expect(removeBreakLine(vm.$el.innerText).trim()).toContain(
+ 'The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure',
+ );
+ });
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
new file mode 100644
index 00000000000..1f0d6a7378c
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
@@ -0,0 +1,981 @@
+import Vue from 'vue';
+import { createLocalVue, shallowMount } from '@vue/test-utils';
+import ReadyToMerge from '~/vue_merge_request_widget/components/states/ready_to_merge.vue';
+import SquashBeforeMerge from '~/vue_merge_request_widget/components/states/squash_before_merge.vue';
+import CommitsHeader from '~/vue_merge_request_widget/components/states/commits_header.vue';
+import CommitEdit from '~/vue_merge_request_widget/components/states/commit_edit.vue';
+import CommitMessageDropdown from '~/vue_merge_request_widget/components/states/commit_message_dropdown.vue';
+import eventHub from '~/vue_merge_request_widget/event_hub';
+import { MWPS_MERGE_STRATEGY, MTWPS_MERGE_STRATEGY } from '~/vue_merge_request_widget/constants';
+import { refreshUserMergeRequestCounts } from '~/commons/nav/user_merge_requests';
+import simplePoll from '~/lib/utils/simple_poll';
+
+jest.mock('~/lib/utils/simple_poll', () =>
+ jest.fn().mockImplementation(jest.requireActual('~/lib/utils/simple_poll').default),
+);
+jest.mock('~/commons/nav/user_merge_requests', () => ({
+ refreshUserMergeRequestCounts: jest.fn(),
+}));
+
+const commitMessage = 'This is the commit message';
+const squashCommitMessage = 'This is the squash commit message';
+const commitMessageWithDescription = 'This is the commit message description';
+const createTestMr = customConfig => {
+ const mr = {
+ isPipelineActive: false,
+ pipeline: null,
+ isPipelineFailed: false,
+ isPipelinePassing: false,
+ isMergeAllowed: true,
+ isApproved: true,
+ onlyAllowMergeIfPipelineSucceeds: false,
+ ffOnlyEnabled: false,
+ hasCI: false,
+ ciStatus: null,
+ sha: '12345678',
+ squash: false,
+ commitMessage,
+ squashCommitMessage,
+ commitMessageWithDescription,
+ shouldRemoveSourceBranch: true,
+ canRemoveSourceBranch: false,
+ targetBranch: 'master',
+ preferredAutoMergeStrategy: MWPS_MERGE_STRATEGY,
+ availableAutoMergeStrategies: [MWPS_MERGE_STRATEGY],
+ mergeImmediatelyDocsPath: 'path/to/merge/immediately/docs',
+ };
+
+ Object.assign(mr, customConfig.mr);
+
+ return mr;
+};
+
+const createTestService = () => ({
+ merge: jest.fn(),
+ poll: jest.fn().mockResolvedValue(),
+});
+
+const createComponent = (customConfig = {}) => {
+ const Component = Vue.extend(ReadyToMerge);
+
+ return new Component({
+ el: document.createElement('div'),
+ propsData: {
+ mr: createTestMr(customConfig),
+ service: createTestService(),
+ },
+ });
+};
+
+describe('ReadyToMerge', () => {
+ let vm;
+
+ beforeEach(() => {
+ vm = createComponent();
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('props', () => {
+ it('should have props', () => {
+ const { mr, service } = ReadyToMerge.props;
+
+ expect(mr.type instanceof Object).toBeTruthy();
+ expect(mr.required).toBeTruthy();
+
+ expect(service.type instanceof Object).toBeTruthy();
+ expect(service.required).toBeTruthy();
+ });
+ });
+
+ describe('data', () => {
+ it('should have default data', () => {
+ expect(vm.mergeWhenBuildSucceeds).toBeFalsy();
+ expect(vm.useCommitMessageWithDescription).toBeFalsy();
+ expect(vm.showCommitMessageEditor).toBeFalsy();
+ expect(vm.isMakingRequest).toBeFalsy();
+ expect(vm.isMergingImmediately).toBeFalsy();
+ expect(vm.commitMessage).toBe(vm.mr.commitMessage);
+ expect(vm.successSvg).toBeDefined();
+ expect(vm.warningSvg).toBeDefined();
+ });
+ });
+
+ describe('computed', () => {
+ describe('isAutoMergeAvailable', () => {
+ it('should return true when at least one merge strategy is available', () => {
+ vm.mr.availableAutoMergeStrategies = [MWPS_MERGE_STRATEGY];
+
+ expect(vm.isAutoMergeAvailable).toBe(true);
+ });
+
+ it('should return false when no merge strategies are available', () => {
+ vm.mr.availableAutoMergeStrategies = [];
+
+ expect(vm.isAutoMergeAvailable).toBe(false);
+ });
+ });
+
+ describe('status', () => {
+ it('defaults to success', () => {
+ Vue.set(vm.mr, 'pipeline', true);
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
+
+ expect(vm.status).toEqual('success');
+ });
+
+ it('returns failed when MR has CI but also has an unknown status', () => {
+ Vue.set(vm.mr, 'hasCI', true);
+
+ expect(vm.status).toEqual('failed');
+ });
+
+ it('returns default when MR has no pipeline', () => {
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
+
+ expect(vm.status).toEqual('success');
+ });
+
+ it('returns pending when pipeline is active', () => {
+ Vue.set(vm.mr, 'pipeline', {});
+ Vue.set(vm.mr, 'isPipelineActive', true);
+
+ expect(vm.status).toEqual('pending');
+ });
+
+ it('returns failed when pipeline is failed', () => {
+ Vue.set(vm.mr, 'pipeline', {});
+ Vue.set(vm.mr, 'isPipelineFailed', true);
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
+
+ expect(vm.status).toEqual('failed');
+ });
+ });
+
+ describe('mergeButtonVariant', () => {
+ it('defaults to success class', () => {
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
+
+ expect(vm.mergeButtonVariant).toEqual('success');
+ });
+
+ it('returns success class for success status', () => {
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
+ Vue.set(vm.mr, 'pipeline', true);
+
+ expect(vm.mergeButtonVariant).toEqual('success');
+ });
+
+ it('returns info class for pending status', () => {
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', [MTWPS_MERGE_STRATEGY]);
+
+ expect(vm.mergeButtonVariant).toEqual('info');
+ });
+
+ it('returns danger class for failed status', () => {
+ vm.mr.hasCI = true;
+
+ expect(vm.mergeButtonVariant).toEqual('danger');
+ });
+ });
+
+ describe('status icon', () => {
+ it('defaults to tick icon', () => {
+ expect(vm.iconClass).toEqual('success');
+ });
+
+ it('shows tick for success status', () => {
+ vm.mr.pipeline = true;
+
+ expect(vm.iconClass).toEqual('success');
+ });
+
+ it('shows tick for pending status', () => {
+ vm.mr.pipeline = {};
+ vm.mr.isPipelineActive = true;
+
+ expect(vm.iconClass).toEqual('success');
+ });
+
+ it('shows warning icon for failed status', () => {
+ vm.mr.hasCI = true;
+
+ expect(vm.iconClass).toEqual('warning');
+ });
+
+ it('shows warning icon for merge not allowed', () => {
+ vm.mr.hasCI = true;
+
+ expect(vm.iconClass).toEqual('warning');
+ });
+ });
+
+ describe('mergeButtonText', () => {
+ it('should return "Merge" when no auto merge strategies are available', () => {
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
+
+ expect(vm.mergeButtonText).toEqual('Merge');
+ });
+
+ it('should return "Merge in progress"', () => {
+ Vue.set(vm, 'isMergingImmediately', true);
+
+ expect(vm.mergeButtonText).toEqual('Merge in progress');
+ });
+
+ it('should return "Merge when pipeline succeeds" when the MWPS auto merge strategy is available', () => {
+ Vue.set(vm, 'isMergingImmediately', false);
+ Vue.set(vm.mr, 'preferredAutoMergeStrategy', MWPS_MERGE_STRATEGY);
+
+ expect(vm.mergeButtonText).toEqual('Merge when pipeline succeeds');
+ });
+ });
+
+ describe('autoMergeText', () => {
+ it('should return Merge when pipeline succeeds', () => {
+ Vue.set(vm.mr, 'preferredAutoMergeStrategy', MWPS_MERGE_STRATEGY);
+
+ expect(vm.autoMergeText).toEqual('Merge when pipeline succeeds');
+ });
+ });
+
+ describe('shouldShowMergeImmediatelyDropdown', () => {
+ it('should return false if no pipeline is active', () => {
+ Vue.set(vm.mr, 'isPipelineActive', false);
+ Vue.set(vm.mr, 'onlyAllowMergeIfPipelineSucceeds', false);
+
+ expect(vm.shouldShowMergeImmediatelyDropdown).toBe(false);
+ });
+
+ it('should return false if "Pipelines must succeed" is enabled for the current project', () => {
+ Vue.set(vm.mr, 'isPipelineActive', true);
+ Vue.set(vm.mr, 'onlyAllowMergeIfPipelineSucceeds', true);
+
+ expect(vm.shouldShowMergeImmediatelyDropdown).toBe(false);
+ });
+
+ it('should return true if the MR\'s pipeline is active and "Pipelines must succeed" is not enabled for the current project', () => {
+ Vue.set(vm.mr, 'isPipelineActive', true);
+ Vue.set(vm.mr, 'onlyAllowMergeIfPipelineSucceeds', false);
+
+ expect(vm.shouldShowMergeImmediatelyDropdown).toBe(true);
+ });
+ });
+
+ describe('isMergeButtonDisabled', () => {
+ it('should return false with initial data', () => {
+ Vue.set(vm.mr, 'isMergeAllowed', true);
+
+ expect(vm.isMergeButtonDisabled).toBe(false);
+ });
+
+ it('should return true when there is no commit message', () => {
+ Vue.set(vm.mr, 'isMergeAllowed', true);
+ Vue.set(vm, 'commitMessage', '');
+
+ expect(vm.isMergeButtonDisabled).toBe(true);
+ });
+
+ it('should return true if merge is not allowed', () => {
+ Vue.set(vm.mr, 'isMergeAllowed', false);
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
+ Vue.set(vm.mr, 'onlyAllowMergeIfPipelineSucceeds', true);
+
+ expect(vm.isMergeButtonDisabled).toBe(true);
+ });
+
+ it('should return true when the vm instance is making request', () => {
+ Vue.set(vm.mr, 'isMergeAllowed', true);
+ Vue.set(vm, 'isMakingRequest', true);
+
+ expect(vm.isMergeButtonDisabled).toBe(true);
+ });
+ });
+
+ describe('isMergeImmediatelyDangerous', () => {
+ it('should always return false in CE', () => {
+ expect(vm.isMergeImmediatelyDangerous).toBe(false);
+ });
+ });
+ });
+
+ describe('methods', () => {
+ describe('shouldShowMergeControls', () => {
+ it('should return false when an external pipeline is running and required to succeed', () => {
+ Vue.set(vm.mr, 'isMergeAllowed', false);
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
+
+ expect(vm.shouldShowMergeControls).toBe(false);
+ });
+
+ it('should return true when the build succeeded or build not required to succeed', () => {
+ Vue.set(vm.mr, 'isMergeAllowed', true);
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
+
+ expect(vm.shouldShowMergeControls).toBe(true);
+ });
+
+ it('should return true when showing the MWPS button and a pipeline is running that needs to be successful', () => {
+ Vue.set(vm.mr, 'isMergeAllowed', false);
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', [MWPS_MERGE_STRATEGY]);
+
+ expect(vm.shouldShowMergeControls).toBe(true);
+ });
+
+ it('should return true when showing the MWPS button but not required for the pipeline to succeed', () => {
+ Vue.set(vm.mr, 'isMergeAllowed', true);
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', [MWPS_MERGE_STRATEGY]);
+
+ expect(vm.shouldShowMergeControls).toBe(true);
+ });
+ });
+
+ describe('updateMergeCommitMessage', () => {
+ it('should revert flag and change commitMessage', () => {
+ expect(vm.commitMessage).toEqual(commitMessage);
+ vm.updateMergeCommitMessage(true);
+
+ expect(vm.commitMessage).toEqual(commitMessageWithDescription);
+ vm.updateMergeCommitMessage(false);
+
+ expect(vm.commitMessage).toEqual(commitMessage);
+ });
+ });
+
+ describe('handleMergeButtonClick', () => {
+ const returnPromise = status =>
+ new Promise(resolve => {
+ resolve({
+ data: {
+ status,
+ },
+ });
+ });
+
+ it('should handle merge when pipeline succeeds', done => {
+ jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
+ jest
+ .spyOn(vm.service, 'merge')
+ .mockReturnValue(returnPromise('merge_when_pipeline_succeeds'));
+ vm.removeSourceBranch = false;
+ vm.handleMergeButtonClick(true);
+
+ setImmediate(() => {
+ expect(vm.isMakingRequest).toBeTruthy();
+ expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetUpdateRequested');
+
+ const params = vm.service.merge.mock.calls[0][0];
+
+ expect(params).toEqual(
+ expect.objectContaining({
+ sha: vm.mr.sha,
+ commit_message: vm.mr.commitMessage,
+ should_remove_source_branch: false,
+ auto_merge_strategy: 'merge_when_pipeline_succeeds',
+ }),
+ );
+ done();
+ });
+ });
+
+ it('should handle merge failed', done => {
+ jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
+ jest.spyOn(vm.service, 'merge').mockReturnValue(returnPromise('failed'));
+ vm.handleMergeButtonClick(false, true);
+
+ setImmediate(() => {
+ expect(vm.isMakingRequest).toBeTruthy();
+ expect(eventHub.$emit).toHaveBeenCalledWith('FailedToMerge', undefined);
+
+ const params = vm.service.merge.mock.calls[0][0];
+
+ expect(params.should_remove_source_branch).toBeTruthy();
+ expect(params.auto_merge_strategy).toBeUndefined();
+ done();
+ });
+ });
+
+ it('should handle merge action accepted case', done => {
+ jest.spyOn(vm.service, 'merge').mockReturnValue(returnPromise('success'));
+ jest.spyOn(vm, 'initiateMergePolling').mockImplementation(() => {});
+ vm.handleMergeButtonClick();
+
+ setImmediate(() => {
+ expect(vm.isMakingRequest).toBeTruthy();
+ expect(vm.initiateMergePolling).toHaveBeenCalled();
+
+ const params = vm.service.merge.mock.calls[0][0];
+
+ expect(params.should_remove_source_branch).toBeTruthy();
+ expect(params.auto_merge_strategy).toBeUndefined();
+ done();
+ });
+ });
+ });
+
+ describe('initiateMergePolling', () => {
+ it('should call simplePoll', () => {
+ vm.initiateMergePolling();
+
+ expect(simplePoll).toHaveBeenCalledWith(expect.any(Function), { timeout: 0 });
+ });
+
+ it('should call handleMergePolling', () => {
+ jest.spyOn(vm, 'handleMergePolling').mockImplementation(() => {});
+
+ vm.initiateMergePolling();
+
+ expect(vm.handleMergePolling).toHaveBeenCalled();
+ });
+ });
+
+ describe('handleMergePolling', () => {
+ const returnPromise = state =>
+ new Promise(resolve => {
+ resolve({
+ data: {
+ state,
+ source_branch_exists: true,
+ },
+ });
+ });
+
+ beforeEach(() => {
+ loadFixtures('merge_requests/merge_request_of_current_user.html');
+ });
+
+ it('should call start and stop polling when MR merged', done => {
+ jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
+ jest.spyOn(vm.service, 'poll').mockReturnValue(returnPromise('merged'));
+ jest.spyOn(vm, 'initiateRemoveSourceBranchPolling').mockImplementation(() => {});
+
+ let cpc = false; // continuePollingCalled
+ let spc = false; // stopPollingCalled
+
+ vm.handleMergePolling(
+ () => {
+ cpc = true;
+ },
+ () => {
+ spc = true;
+ },
+ );
+ setImmediate(() => {
+ expect(vm.service.poll).toHaveBeenCalled();
+ expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetUpdateRequested');
+ expect(eventHub.$emit).toHaveBeenCalledWith('FetchActionsContent');
+ expect(vm.initiateRemoveSourceBranchPolling).toHaveBeenCalled();
+ expect(refreshUserMergeRequestCounts).toHaveBeenCalled();
+ expect(cpc).toBeFalsy();
+ expect(spc).toBeTruthy();
+
+ done();
+ });
+ });
+
+ it('updates status box', done => {
+ jest.spyOn(vm.service, 'poll').mockReturnValue(returnPromise('merged'));
+ jest.spyOn(vm, 'initiateRemoveSourceBranchPolling').mockImplementation(() => {});
+
+ vm.handleMergePolling(() => {}, () => {});
+
+ setImmediate(() => {
+ const statusBox = document.querySelector('.status-box');
+
+ expect(statusBox.classList.contains('status-box-mr-merged')).toBeTruthy();
+ expect(statusBox.textContent).toContain('Merged');
+
+ done();
+ });
+ });
+
+ it('hides close button', done => {
+ jest.spyOn(vm.service, 'poll').mockReturnValue(returnPromise('merged'));
+ jest.spyOn(vm, 'initiateRemoveSourceBranchPolling').mockImplementation(() => {});
+
+ vm.handleMergePolling(() => {}, () => {});
+
+ setImmediate(() => {
+ expect(document.querySelector('.btn-close').classList.contains('hidden')).toBeTruthy();
+
+ done();
+ });
+ });
+
+ it('updates merge request count badge', done => {
+ jest.spyOn(vm.service, 'poll').mockReturnValue(returnPromise('merged'));
+ jest.spyOn(vm, 'initiateRemoveSourceBranchPolling').mockImplementation(() => {});
+
+ vm.handleMergePolling(() => {}, () => {});
+
+ setImmediate(() => {
+ expect(document.querySelector('.js-merge-counter').textContent).toBe('0');
+
+ done();
+ });
+ });
+
+ it('should continue polling until MR is merged', done => {
+ jest.spyOn(vm.service, 'poll').mockReturnValue(returnPromise('some_other_state'));
+ jest.spyOn(vm, 'initiateRemoveSourceBranchPolling').mockImplementation(() => {});
+
+ let cpc = false; // continuePollingCalled
+ let spc = false; // stopPollingCalled
+
+ vm.handleMergePolling(
+ () => {
+ cpc = true;
+ },
+ () => {
+ spc = true;
+ },
+ );
+ setImmediate(() => {
+ expect(cpc).toBeTruthy();
+ expect(spc).toBeFalsy();
+
+ done();
+ });
+ });
+ });
+
+ describe('initiateRemoveSourceBranchPolling', () => {
+ it('should emit event and call simplePoll', () => {
+ jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
+
+ vm.initiateRemoveSourceBranchPolling();
+
+ expect(eventHub.$emit).toHaveBeenCalledWith('SetBranchRemoveFlag', [true]);
+ expect(simplePoll).toHaveBeenCalled();
+ });
+ });
+
+ describe('handleRemoveBranchPolling', () => {
+ const returnPromise = state =>
+ new Promise(resolve => {
+ resolve({
+ data: {
+ source_branch_exists: state,
+ },
+ });
+ });
+
+ it('should call start and stop polling when MR merged', done => {
+ jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
+ jest.spyOn(vm.service, 'poll').mockReturnValue(returnPromise(false));
+
+ let cpc = false; // continuePollingCalled
+ let spc = false; // stopPollingCalled
+
+ vm.handleRemoveBranchPolling(
+ () => {
+ cpc = true;
+ },
+ () => {
+ spc = true;
+ },
+ );
+ setImmediate(() => {
+ expect(vm.service.poll).toHaveBeenCalled();
+
+ const args = eventHub.$emit.mock.calls[0];
+
+ expect(args[0]).toEqual('MRWidgetUpdateRequested');
+ expect(args[1]).toBeDefined();
+ args[1]();
+
+ expect(eventHub.$emit).toHaveBeenCalledWith('SetBranchRemoveFlag', [false]);
+
+ expect(cpc).toBeFalsy();
+ expect(spc).toBeTruthy();
+
+ done();
+ });
+ });
+
+ it('should continue polling until MR is merged', done => {
+ jest.spyOn(vm.service, 'poll').mockReturnValue(returnPromise(true));
+
+ let cpc = false; // continuePollingCalled
+ let spc = false; // stopPollingCalled
+
+ vm.handleRemoveBranchPolling(
+ () => {
+ cpc = true;
+ },
+ () => {
+ spc = true;
+ },
+ );
+ setImmediate(() => {
+ expect(cpc).toBeTruthy();
+ expect(spc).toBeFalsy();
+
+ done();
+ });
+ });
+ });
+ });
+
+ describe('Remove source branch checkbox', () => {
+ describe('when user can merge but cannot delete branch', () => {
+ it('should be disabled in the rendered output', () => {
+ const checkboxElement = vm.$el.querySelector('#remove-source-branch-input');
+
+ expect(checkboxElement).toBeNull();
+ });
+ });
+
+ describe('when user can merge and can delete branch', () => {
+ beforeEach(() => {
+ vm = createComponent({
+ mr: { canRemoveSourceBranch: true },
+ });
+ });
+
+ it('isRemoveSourceBranchButtonDisabled should be false', () => {
+ expect(vm.isRemoveSourceBranchButtonDisabled).toBe(false);
+ });
+
+ it('removed source branch should be enabled in rendered output', () => {
+ const checkboxElement = vm.$el.querySelector('#remove-source-branch-input');
+
+ expect(checkboxElement).not.toBeNull();
+ });
+ });
+ });
+
+ describe('render children components', () => {
+ let wrapper;
+ const localVue = createLocalVue();
+
+ const createLocalComponent = (customConfig = {}) => {
+ wrapper = shallowMount(localVue.extend(ReadyToMerge), {
+ localVue,
+ propsData: {
+ mr: createTestMr(customConfig),
+ service: createTestService(),
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ const findCheckboxElement = () => wrapper.find(SquashBeforeMerge);
+ const findCommitsHeaderElement = () => wrapper.find(CommitsHeader);
+ const findCommitEditElements = () => wrapper.findAll(CommitEdit);
+ const findCommitDropdownElement = () => wrapper.find(CommitMessageDropdown);
+ const findFirstCommitEditLabel = () =>
+ findCommitEditElements()
+ .at(0)
+ .props('label');
+
+ describe('squash checkbox', () => {
+ it('should be rendered when squash before merge is enabled and there is more than 1 commit', () => {
+ createLocalComponent({
+ mr: { commitsCount: 2, enableSquashBeforeMerge: true },
+ });
+
+ expect(findCheckboxElement().exists()).toBeTruthy();
+ });
+
+ it('should not be rendered when squash before merge is disabled', () => {
+ createLocalComponent({ mr: { commitsCount: 2, enableSquashBeforeMerge: false } });
+
+ expect(findCheckboxElement().exists()).toBeFalsy();
+ });
+
+ it('should not be rendered when there is only 1 commit', () => {
+ createLocalComponent({ mr: { commitsCount: 1, enableSquashBeforeMerge: true } });
+
+ expect(findCheckboxElement().exists()).toBeFalsy();
+ });
+ });
+
+ describe('commits count collapsible header', () => {
+ it('should be rendered when fast-forward is disabled', () => {
+ createLocalComponent();
+
+ expect(findCommitsHeaderElement().exists()).toBeTruthy();
+ });
+
+ describe('when fast-forward is enabled', () => {
+ it('should be rendered if squash and squash before are enabled and there is more than 1 commit', () => {
+ createLocalComponent({
+ mr: {
+ ffOnlyEnabled: true,
+ enableSquashBeforeMerge: true,
+ squash: true,
+ commitsCount: 2,
+ },
+ });
+
+ expect(findCommitsHeaderElement().exists()).toBeTruthy();
+ });
+
+ it('should not be rendered if squash before merge is disabled', () => {
+ createLocalComponent({
+ mr: {
+ ffOnlyEnabled: true,
+ enableSquashBeforeMerge: false,
+ squash: true,
+ commitsCount: 2,
+ },
+ });
+
+ expect(findCommitsHeaderElement().exists()).toBeFalsy();
+ });
+
+ it('should not be rendered if squash is disabled', () => {
+ createLocalComponent({
+ mr: {
+ ffOnlyEnabled: true,
+ squash: false,
+ enableSquashBeforeMerge: true,
+ commitsCount: 2,
+ },
+ });
+
+ expect(findCommitsHeaderElement().exists()).toBeFalsy();
+ });
+
+ it('should not be rendered if commits count is 1', () => {
+ createLocalComponent({
+ mr: {
+ ffOnlyEnabled: true,
+ squash: true,
+ enableSquashBeforeMerge: true,
+ commitsCount: 1,
+ },
+ });
+
+ expect(findCommitsHeaderElement().exists()).toBeFalsy();
+ });
+ });
+ });
+
+ describe('commits edit components', () => {
+ describe('when fast-forward merge is enabled', () => {
+ it('should not be rendered if squash is disabled', () => {
+ createLocalComponent({
+ mr: {
+ ffOnlyEnabled: true,
+ squash: false,
+ enableSquashBeforeMerge: true,
+ commitsCount: 2,
+ },
+ });
+
+ expect(findCommitEditElements().length).toBe(0);
+ });
+
+ it('should not be rendered if squash before merge is disabled', () => {
+ createLocalComponent({
+ mr: {
+ ffOnlyEnabled: true,
+ squash: true,
+ enableSquashBeforeMerge: false,
+ commitsCount: 2,
+ },
+ });
+
+ expect(findCommitEditElements().length).toBe(0);
+ });
+
+ it('should not be rendered if there is only one commit', () => {
+ createLocalComponent({
+ mr: {
+ ffOnlyEnabled: true,
+ squash: true,
+ enableSquashBeforeMerge: true,
+ commitsCount: 1,
+ },
+ });
+
+ expect(findCommitEditElements().length).toBe(0);
+ });
+
+ it('should have one edit component if squash is enabled and there is more than 1 commit', () => {
+ createLocalComponent({
+ mr: {
+ ffOnlyEnabled: true,
+ squash: true,
+ enableSquashBeforeMerge: true,
+ commitsCount: 2,
+ },
+ });
+
+ expect(findCommitEditElements().length).toBe(1);
+ expect(findFirstCommitEditLabel()).toBe('Squash commit message');
+ });
+ });
+
+ it('should have one edit component when squash is disabled', () => {
+ createLocalComponent();
+
+ expect(findCommitEditElements().length).toBe(1);
+ });
+
+ it('should have two edit components when squash is enabled and there is more than 1 commit', () => {
+ createLocalComponent({
+ mr: {
+ commitsCount: 2,
+ squash: true,
+ enableSquashBeforeMerge: true,
+ },
+ });
+
+ expect(findCommitEditElements().length).toBe(2);
+ });
+
+ it('should have one edit components when squash is enabled and there is 1 commit only', () => {
+ createLocalComponent({
+ mr: {
+ commitsCount: 1,
+ squash: true,
+ enableSquashBeforeMerge: true,
+ },
+ });
+
+ expect(findCommitEditElements().length).toBe(1);
+ });
+
+ it('should have correct edit merge commit label', () => {
+ createLocalComponent();
+
+ expect(findFirstCommitEditLabel()).toBe('Merge commit message');
+ });
+
+ it('should have correct edit squash commit label', () => {
+ createLocalComponent({
+ mr: {
+ commitsCount: 2,
+ squash: true,
+ enableSquashBeforeMerge: true,
+ },
+ });
+
+ expect(findFirstCommitEditLabel()).toBe('Squash commit message');
+ });
+ });
+
+ describe('commits dropdown', () => {
+ it('should not be rendered if squash is disabled', () => {
+ createLocalComponent();
+
+ expect(findCommitDropdownElement().exists()).toBeFalsy();
+ });
+
+ it('should be rendered if squash is enabled and there is more than 1 commit', () => {
+ createLocalComponent({
+ mr: { enableSquashBeforeMerge: true, squash: true, commitsCount: 2 },
+ });
+
+ expect(findCommitDropdownElement().exists()).toBeTruthy();
+ });
+ });
+ });
+
+ describe('Merge controls', () => {
+ describe('when allowed to merge', () => {
+ beforeEach(() => {
+ vm = createComponent({
+ mr: { isMergeAllowed: true, canRemoveSourceBranch: true },
+ });
+ });
+
+ it('shows remove source branch checkbox', () => {
+ expect(vm.$el.querySelector('.js-remove-source-branch-checkbox')).not.toBeNull();
+ });
+
+ it('shows modify commit message button', () => {
+ expect(vm.$el.querySelector('.js-modify-commit-message-button')).toBeDefined();
+ });
+
+ it('does not show message about needing to resolve items', () => {
+ expect(vm.$el.querySelector('.js-resolve-mr-widget-items-message')).toBeNull();
+ });
+ });
+
+ describe('when not allowed to merge', () => {
+ beforeEach(() => {
+ vm = createComponent({
+ mr: { isMergeAllowed: false },
+ });
+ });
+
+ it('does not show remove source branch checkbox', () => {
+ expect(vm.$el.querySelector('.js-remove-source-branch-checkbox')).toBeNull();
+ });
+
+ it('shows message to resolve all items before being allowed to merge', () => {
+ expect(vm.$el.querySelector('.js-resolve-mr-widget-items-message')).toBeDefined();
+ });
+ });
+ });
+
+ describe('Merge request project settings', () => {
+ describe('when the merge commit merge method is enabled', () => {
+ beforeEach(() => {
+ vm = createComponent({
+ mr: { ffOnlyEnabled: false },
+ });
+ });
+
+ it('should not show fast forward message', () => {
+ expect(vm.$el.querySelector('.mr-fast-forward-message')).toBeNull();
+ });
+
+ it('should show "Modify commit message" button', () => {
+ expect(vm.$el.querySelector('.js-modify-commit-message-button')).toBeDefined();
+ });
+ });
+
+ describe('when the fast-forward merge method is enabled', () => {
+ beforeEach(() => {
+ vm = createComponent({
+ mr: { ffOnlyEnabled: true },
+ });
+ });
+
+ it('should show fast forward message', () => {
+ expect(vm.$el.querySelector('.mr-fast-forward-message')).toBeDefined();
+ });
+
+ it('should not show "Modify commit message" button', () => {
+ expect(vm.$el.querySelector('.js-modify-commit-message-button')).toBeNull();
+ });
+ });
+ });
+
+ describe('with a mismatched SHA', () => {
+ const findMismatchShaBlock = () => vm.$el.querySelector('.js-sha-mismatch');
+
+ beforeEach(() => {
+ vm = createComponent({
+ mr: {
+ isSHAMismatch: true,
+ mergeRequestDiffsPath: '/merge_requests/1/diffs',
+ },
+ });
+ });
+
+ it('displays a warning message', () => {
+ expect(findMismatchShaBlock()).toExist();
+ });
+
+ it('warns the user to refresh to review', () => {
+ expect(findMismatchShaBlock().textContent.trim()).toBe(
+ 'New changes were added. Reload the page to review them',
+ );
+ });
+
+ it('displays link to the diffs tab', () => {
+ expect(findMismatchShaBlock().querySelector('a').href).toContain(vm.mr.mergeRequestDiffsPath);
+ });
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js
new file mode 100644
index 00000000000..38920846a50
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js
@@ -0,0 +1,25 @@
+import Vue from 'vue';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import { removeBreakLine } from 'helpers/text_helper';
+import ShaMismatch from '~/vue_merge_request_widget/components/states/sha_mismatch.vue';
+
+describe('ShaMismatch', () => {
+ let vm;
+
+ beforeEach(() => {
+ const Component = Vue.extend(ShaMismatch);
+ vm = mountComponent(Component);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('should render information message', () => {
+ expect(vm.$el.querySelector('button').disabled).toEqual(true);
+
+ expect(removeBreakLine(vm.$el.textContent).trim()).toContain(
+ 'The source branch HEAD has recently changed. Please reload the page and review the changes before merging',
+ );
+ });
+});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_squash_before_merge_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_squash_before_merge_spec.js
index b70d580ed04..b70d580ed04 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_squash_before_merge_spec.js
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_squash_before_merge_spec.js
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
new file mode 100644
index 00000000000..33e52f4fd36
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_unresolved_discussions_spec.js
@@ -0,0 +1,46 @@
+import Vue from 'vue';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import UnresolvedDiscussions from '~/vue_merge_request_widget/components/states/unresolved_discussions.vue';
+import { TEST_HOST } from 'helpers/test_constants';
+
+describe('UnresolvedDiscussions', () => {
+ const Component = Vue.extend(UnresolvedDiscussions);
+ let vm;
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('with threads path', () => {
+ beforeEach(() => {
+ vm = mountComponent(Component, {
+ mr: {
+ createIssueToResolveDiscussionsPath: TEST_HOST,
+ },
+ });
+ });
+
+ it('should have correct elements', () => {
+ expect(vm.$el.innerText).toContain(
+ 'There are unresolved threads. Please resolve these threads',
+ );
+
+ expect(vm.$el.innerText).toContain('Create an issue to resolve them later');
+ expect(vm.$el.querySelector('.js-create-issue').getAttribute('href')).toEqual(TEST_HOST);
+ });
+ });
+
+ describe('without threads path', () => {
+ beforeEach(() => {
+ vm = mountComponent(Component, { mr: {} });
+ });
+
+ it('should not show create issue link if user cannot create issue', () => {
+ expect(vm.$el.innerText).toContain(
+ 'There are unresolved threads. Please resolve these threads',
+ );
+
+ expect(vm.$el.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
new file mode 100644
index 00000000000..6fa555b4fc4
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_wip_spec.js
@@ -0,0 +1,104 @@
+import Vue from 'vue';
+import WorkInProgress from '~/vue_merge_request_widget/components/states/work_in_progress.vue';
+import eventHub from '~/vue_merge_request_widget/event_hub';
+import createFlash from '~/flash';
+
+jest.mock('~/flash');
+
+const createComponent = () => {
+ const Component = Vue.extend(WorkInProgress);
+ const mr = {
+ title: 'The best MR ever',
+ removeWIPPath: '/path/to/remove/wip',
+ };
+ const service = {
+ removeWIP() {},
+ };
+ return new Component({
+ el: document.createElement('div'),
+ propsData: { mr, service },
+ });
+};
+
+describe('Wip', () => {
+ describe('props', () => {
+ it('should have props', () => {
+ const { mr, service } = WorkInProgress.props;
+
+ expect(mr.type instanceof Object).toBeTruthy();
+ expect(mr.required).toBeTruthy();
+
+ expect(service.type instanceof Object).toBeTruthy();
+ expect(service.required).toBeTruthy();
+ });
+ });
+
+ describe('data', () => {
+ it('should have default data', () => {
+ const vm = createComponent();
+
+ expect(vm.isMakingRequest).toBeFalsy();
+ });
+ });
+
+ describe('methods', () => {
+ const mrObj = {
+ is_new_mr_data: true,
+ };
+
+ describe('handleRemoveWIP', () => {
+ it('should make a request to service and handle response', done => {
+ const vm = createComponent();
+
+ jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
+ jest.spyOn(vm.service, 'removeWIP').mockReturnValue(
+ new Promise(resolve => {
+ resolve({
+ data: mrObj,
+ });
+ }),
+ );
+
+ vm.handleRemoveWIP();
+ setImmediate(() => {
+ expect(vm.isMakingRequest).toBeTruthy();
+ expect(eventHub.$emit).toHaveBeenCalledWith('UpdateWidgetData', mrObj);
+ expect(createFlash).toHaveBeenCalledWith(
+ 'The merge request can now be merged.',
+ 'notice',
+ );
+ done();
+ });
+ });
+ });
+ });
+
+ describe('template', () => {
+ let vm;
+ let el;
+
+ beforeEach(() => {
+ vm = createComponent();
+ el = vm.$el;
+ });
+
+ it('should have correct elements', () => {
+ expect(el.classList.contains('mr-widget-body')).toBeTruthy();
+ expect(el.innerText).toContain('This is a Work in Progress');
+ expect(el.querySelector('button').getAttribute('disabled')).toBeTruthy();
+ expect(el.querySelector('button').innerText).toContain('Merge');
+ expect(el.querySelector('.js-remove-wip').innerText.replace(/\s\s+/g, ' ')).toContain(
+ 'Resolve WIP status',
+ );
+ });
+
+ it('should not show removeWIP button is user cannot update MR', done => {
+ vm.mr.removeWIPPath = '';
+
+ Vue.nextTick(() => {
+ expect(el.querySelector('.js-remove-wip')).toEqual(null);
+ done();
+ });
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/components/date_time_picker/date_time_picker_lib_spec.js b/spec/frontend/vue_shared/components/date_time_picker/date_time_picker_lib_spec.js
index 98962918b49..e46c63a1a32 100644
--- a/spec/frontend/vue_shared/components/date_time_picker/date_time_picker_lib_spec.js
+++ b/spec/frontend/vue_shared/components/date_time_picker/date_time_picker_lib_spec.js
@@ -1,7 +1,13 @@
-import * as dateTimePickerLib from '~/vue_shared/components/date_time_picker/date_time_picker_lib';
+import timezoneMock from 'timezone-mock';
+
+import {
+ isValidInputString,
+ inputStringToIsoDate,
+ isoDateToInputString,
+} from '~/vue_shared/components/date_time_picker/date_time_picker_lib';
describe('date time picker lib', () => {
- describe('isValidDate', () => {
+ describe('isValidInputString', () => {
[
{
input: '2019-09-09T00:00:00.000Z',
@@ -48,121 +54,137 @@ describe('date time picker lib', () => {
output: false,
},
].forEach(({ input, output }) => {
- it(`isValidDate return ${output} for ${input}`, () => {
- expect(dateTimePickerLib.isValidDate(input)).toBe(output);
+ it(`isValidInputString return ${output} for ${input}`, () => {
+ expect(isValidInputString(input)).toBe(output);
});
});
});
- describe('stringToISODate', () => {
- ['', 'null', undefined, 'abc'].forEach(input => {
+ describe('inputStringToIsoDate', () => {
+ [
+ '',
+ 'null',
+ undefined,
+ 'abc',
+ 'xxxx-xx-xx',
+ '9999-99-19',
+ '2019-19-23',
+ '2019-09-23 x',
+ '2019-09-29 24:24:24',
+ ].forEach(input => {
it(`throws error for invalid input like ${input}`, () => {
- expect(() => dateTimePickerLib.stringToISODate(input)).toThrow();
+ expect(() => inputStringToIsoDate(input)).toThrow();
});
});
+
[
{
- input: '2019-09-09 01:01:01',
- output: '2019-09-09T01:01:01Z',
+ input: '2019-09-08 01:01:01',
+ output: '2019-09-08T01:01:01Z',
},
{
- input: '2019-09-09 00:00:00',
- output: '2019-09-09T00:00:00Z',
+ input: '2019-09-08 00:00:00',
+ output: '2019-09-08T00:00:00Z',
},
{
- input: '2019-09-09 23:59:59',
- output: '2019-09-09T23:59:59Z',
+ input: '2019-09-08 23:59:59',
+ output: '2019-09-08T23:59:59Z',
},
{
- input: '2019-09-09',
- output: '2019-09-09T00:00:00Z',
+ input: '2019-09-08',
+ output: '2019-09-08T00:00:00Z',
},
- ].forEach(({ input, output }) => {
- it(`returns ${output} from ${input}`, () => {
- expect(dateTimePickerLib.stringToISODate(input)).toBe(output);
- });
- });
- });
-
- describe('truncateZerosInDateTime', () => {
- [
{
- input: '',
- output: '',
+ input: '2019-09-08',
+ output: '2019-09-08T00:00:00Z',
},
{
- input: '2019-10-10',
- output: '2019-10-10',
+ input: '2019-09-08 00:00:00',
+ output: '2019-09-08T00:00:00Z',
},
{
- input: '2019-10-10 00:00:01',
- output: '2019-10-10 00:00:01',
+ input: '2019-09-08 23:24:24',
+ output: '2019-09-08T23:24:24Z',
},
{
- input: '2019-10-10 00:00:00',
- output: '2019-10-10',
+ input: '2019-09-08 0:0:0',
+ output: '2019-09-08T00:00:00Z',
},
].forEach(({ input, output }) => {
- it(`truncateZerosInDateTime return ${output} for ${input}`, () => {
- expect(dateTimePickerLib.truncateZerosInDateTime(input)).toBe(output);
+ it(`returns ${output} from ${input}`, () => {
+ expect(inputStringToIsoDate(input)).toBe(output);
});
});
+
+ describe('timezone formatting', () => {
+ const value = '2019-09-08 01:01:01';
+ const utcResult = '2019-09-08T01:01:01Z';
+ const localResult = '2019-09-08T08:01:01Z';
+
+ test.each`
+ val | locatTimezone | utc | result
+ ${value} | ${'UTC'} | ${undefined} | ${utcResult}
+ ${value} | ${'UTC'} | ${false} | ${utcResult}
+ ${value} | ${'UTC'} | ${true} | ${utcResult}
+ ${value} | ${'US/Pacific'} | ${undefined} | ${localResult}
+ ${value} | ${'US/Pacific'} | ${false} | ${localResult}
+ ${value} | ${'US/Pacific'} | ${true} | ${utcResult}
+ `(
+ 'when timezone is $locatTimezone, formats $result for utc = $utc',
+ ({ val, locatTimezone, utc, result }) => {
+ timezoneMock.register(locatTimezone);
+
+ expect(inputStringToIsoDate(val, utc)).toBe(result);
+
+ timezoneMock.unregister();
+ },
+ );
+ });
});
- describe('isDateTimePickerInputValid', () => {
+ describe('isoDateToInputString', () => {
[
{
- input: null,
- output: false,
- },
- {
- input: '',
- output: false,
+ input: '2019-09-08T01:01:01Z',
+ output: '2019-09-08 01:01:01',
},
{
- input: 'xxxx-xx-xx',
- output: false,
+ input: '2019-09-08T01:01:01.999Z',
+ output: '2019-09-08 01:01:01',
},
{
- input: '9999-99-19',
- output: false,
- },
- {
- input: '2019-19-23',
- output: false,
- },
- {
- input: '2019-09-23',
- output: true,
- },
- {
- input: '2019-09-23 x',
- output: false,
- },
- {
- input: '2019-09-29 0:0:0',
- output: false,
- },
- {
- input: '2019-09-29 00:00:00',
- output: true,
- },
- {
- input: '2019-09-29 24:24:24',
- output: false,
- },
- {
- input: '2019-09-29 23:24:24',
- output: true,
- },
- {
- input: '2019-09-29 23:24:24 ',
- output: false,
+ input: '2019-09-08T00:00:00Z',
+ output: '2019-09-08 00:00:00',
},
].forEach(({ input, output }) => {
it(`returns ${output} for ${input}`, () => {
- expect(dateTimePickerLib.isDateTimePickerInputValid(input)).toBe(output);
+ expect(isoDateToInputString(input)).toBe(output);
});
});
+
+ describe('timezone formatting', () => {
+ const value = '2019-09-08T08:01:01Z';
+ const utcResult = '2019-09-08 08:01:01';
+ const localResult = '2019-09-08 01:01:01';
+
+ test.each`
+ val | locatTimezone | utc | result
+ ${value} | ${'UTC'} | ${undefined} | ${utcResult}
+ ${value} | ${'UTC'} | ${false} | ${utcResult}
+ ${value} | ${'UTC'} | ${true} | ${utcResult}
+ ${value} | ${'US/Pacific'} | ${undefined} | ${localResult}
+ ${value} | ${'US/Pacific'} | ${false} | ${localResult}
+ ${value} | ${'US/Pacific'} | ${true} | ${utcResult}
+ `(
+ 'when timezone is $locatTimezone, formats $result for utc = $utc',
+ ({ val, locatTimezone, utc, result }) => {
+ timezoneMock.register(locatTimezone);
+
+ expect(isoDateToInputString(val, utc)).toBe(result);
+
+ timezoneMock.unregister();
+ },
+ );
+ });
});
});
diff --git a/spec/frontend/vue_shared/components/date_time_picker/date_time_picker_spec.js b/spec/frontend/vue_shared/components/date_time_picker/date_time_picker_spec.js
index 90130917d8f..ceea8d2fa92 100644
--- a/spec/frontend/vue_shared/components/date_time_picker/date_time_picker_spec.js
+++ b/spec/frontend/vue_shared/components/date_time_picker/date_time_picker_spec.js
@@ -1,4 +1,5 @@
import { mount } from '@vue/test-utils';
+import timezoneMock from 'timezone-mock';
import DateTimePicker from '~/vue_shared/components/date_time_picker/date_time_picker.vue';
import {
defaultTimeRanges,
@@ -8,16 +9,16 @@ import {
const optionsCount = defaultTimeRanges.length;
describe('DateTimePicker', () => {
- let dateTimePicker;
+ let wrapper;
- const dropdownToggle = () => dateTimePicker.find('.dropdown-toggle');
- const dropdownMenu = () => dateTimePicker.find('.dropdown-menu');
- const applyButtonElement = () => dateTimePicker.find('button.btn-success').element;
- const findQuickRangeItems = () => dateTimePicker.findAll('.dropdown-item');
- const cancelButtonElement = () => dateTimePicker.find('button.btn-secondary').element;
+ const dropdownToggle = () => wrapper.find('.dropdown-toggle');
+ const dropdownMenu = () => wrapper.find('.dropdown-menu');
+ const applyButtonElement = () => wrapper.find('button.btn-success').element;
+ const findQuickRangeItems = () => wrapper.findAll('.dropdown-item');
+ const cancelButtonElement = () => wrapper.find('button.btn-secondary').element;
const createComponent = props => {
- dateTimePicker = mount(DateTimePicker, {
+ wrapper = mount(DateTimePicker, {
propsData: {
...props,
},
@@ -25,54 +26,86 @@ describe('DateTimePicker', () => {
};
afterEach(() => {
- dateTimePicker.destroy();
+ wrapper.destroy();
});
- it('renders dropdown toggle button with selected text', done => {
+ it('renders dropdown toggle button with selected text', () => {
createComponent();
- dateTimePicker.vm.$nextTick(() => {
+ return wrapper.vm.$nextTick(() => {
expect(dropdownToggle().text()).toBe(defaultTimeRange.label);
- done();
+ });
+ });
+
+ it('renders dropdown toggle button with selected text and utc label', () => {
+ createComponent({ utc: true });
+ return wrapper.vm.$nextTick(() => {
+ expect(dropdownToggle().text()).toContain(defaultTimeRange.label);
+ expect(dropdownToggle().text()).toContain('UTC');
});
});
it('renders dropdown with 2 custom time range inputs', () => {
createComponent();
- dateTimePicker.vm.$nextTick(() => {
- expect(dateTimePicker.findAll('input').length).toBe(2);
+ return wrapper.vm.$nextTick(() => {
+ expect(wrapper.findAll('input').length).toBe(2);
});
});
- it('renders inputs with h/m/s truncated if its all 0s', done => {
- createComponent({
- value: {
+ describe('renders label with h/m/s truncated if possible', () => {
+ [
+ {
+ start: '2019-10-10T00:00:00.000Z',
+ end: '2019-10-10T00:00:00.000Z',
+ label: '2019-10-10 to 2019-10-10',
+ },
+ {
start: '2019-10-10T00:00:00.000Z',
end: '2019-10-14T00:10:00.000Z',
+ label: '2019-10-10 to 2019-10-14 00:10:00',
},
- });
- dateTimePicker.vm.$nextTick(() => {
- expect(dateTimePicker.find('#custom-time-from').element.value).toBe('2019-10-10');
- expect(dateTimePicker.find('#custom-time-to').element.value).toBe('2019-10-14 00:10:00');
- done();
+ {
+ start: '2019-10-10T00:00:00.000Z',
+ end: '2019-10-10T00:00:01.000Z',
+ label: '2019-10-10 to 2019-10-10 00:00:01',
+ },
+ {
+ start: '2019-10-10T00:00:01.000Z',
+ end: '2019-10-10T00:00:01.000Z',
+ label: '2019-10-10 00:00:01 to 2019-10-10 00:00:01',
+ },
+ {
+ start: '2019-10-10T00:00:01.000Z',
+ end: '2019-10-10T00:00:01.000Z',
+ utc: true,
+ label: '2019-10-10 00:00:01 to 2019-10-10 00:00:01 UTC',
+ },
+ ].forEach(({ start, end, utc, label }) => {
+ it(`for start ${start}, end ${end}, and utc ${utc}, label is ${label}`, () => {
+ createComponent({
+ value: { start, end },
+ utc,
+ });
+ return wrapper.vm.$nextTick(() => {
+ expect(dropdownToggle().text()).toBe(label);
+ });
+ });
});
});
- it(`renders dropdown with ${optionsCount} (default) items in quick range`, done => {
+ it(`renders dropdown with ${optionsCount} (default) items in quick range`, () => {
createComponent();
dropdownToggle().trigger('click');
- dateTimePicker.vm.$nextTick(() => {
+ return wrapper.vm.$nextTick(() => {
expect(findQuickRangeItems().length).toBe(optionsCount);
- done();
});
});
- it('renders dropdown with a default quick range item selected', done => {
+ it('renders dropdown with a default quick range item selected', () => {
createComponent();
dropdownToggle().trigger('click');
- dateTimePicker.vm.$nextTick(() => {
- expect(dateTimePicker.find('.dropdown-item.active').exists()).toBe(true);
- expect(dateTimePicker.find('.dropdown-item.active').text()).toBe(defaultTimeRange.label);
- done();
+ return wrapper.vm.$nextTick(() => {
+ expect(wrapper.find('.dropdown-item.active').exists()).toBe(true);
+ expect(wrapper.find('.dropdown-item.active').text()).toBe(defaultTimeRange.label);
});
});
@@ -86,78 +119,128 @@ describe('DateTimePicker', () => {
describe('user input', () => {
const fillInputAndBlur = (input, val) => {
- dateTimePicker.find(input).setValue(val);
- return dateTimePicker.vm.$nextTick().then(() => {
- dateTimePicker.find(input).trigger('blur');
- return dateTimePicker.vm.$nextTick();
+ wrapper.find(input).setValue(val);
+ return wrapper.vm.$nextTick().then(() => {
+ wrapper.find(input).trigger('blur');
+ return wrapper.vm.$nextTick();
});
};
- beforeEach(done => {
+ beforeEach(() => {
createComponent();
- dateTimePicker.vm.$nextTick(done);
+ return wrapper.vm.$nextTick();
});
- it('displays inline error message if custom time range inputs are invalid', done => {
- fillInputAndBlur('#custom-time-from', '2019-10-01abc')
+ it('displays inline error message if custom time range inputs are invalid', () => {
+ return fillInputAndBlur('#custom-time-from', '2019-10-01abc')
.then(() => fillInputAndBlur('#custom-time-to', '2019-10-10abc'))
.then(() => {
- expect(dateTimePicker.findAll('.invalid-feedback').length).toBe(2);
- done();
- })
- .catch(done);
+ expect(wrapper.findAll('.invalid-feedback').length).toBe(2);
+ });
});
- it('keeps apply button disabled with invalid custom time range inputs', done => {
- fillInputAndBlur('#custom-time-from', '2019-10-01abc')
+ it('keeps apply button disabled with invalid custom time range inputs', () => {
+ return fillInputAndBlur('#custom-time-from', '2019-10-01abc')
.then(() => fillInputAndBlur('#custom-time-to', '2019-09-19'))
.then(() => {
expect(applyButtonElement().getAttribute('disabled')).toBe('disabled');
- done();
- })
- .catch(done);
+ });
});
- it('enables apply button with valid custom time range inputs', done => {
- fillInputAndBlur('#custom-time-from', '2019-10-01')
+ it('enables apply button with valid custom time range inputs', () => {
+ return fillInputAndBlur('#custom-time-from', '2019-10-01')
.then(() => fillInputAndBlur('#custom-time-to', '2019-10-19'))
.then(() => {
expect(applyButtonElement().getAttribute('disabled')).toBeNull();
- done();
- })
- .catch(done.fail);
+ });
});
- it('emits dates in an object when apply is clicked', done => {
- fillInputAndBlur('#custom-time-from', '2019-10-01')
- .then(() => fillInputAndBlur('#custom-time-to', '2019-10-19'))
- .then(() => {
- applyButtonElement().click();
-
- expect(dateTimePicker.emitted().input).toHaveLength(1);
- expect(dateTimePicker.emitted().input[0]).toEqual([
- {
- end: '2019-10-19T00:00:00Z',
- start: '2019-10-01T00:00:00Z',
- },
- ]);
- done();
- })
- .catch(done.fail);
+ describe('when "apply" is clicked', () => {
+ it('emits iso dates', () => {
+ return fillInputAndBlur('#custom-time-from', '2019-10-01 00:00:00')
+ .then(() => fillInputAndBlur('#custom-time-to', '2019-10-19 00:00:00'))
+ .then(() => {
+ applyButtonElement().click();
+
+ expect(wrapper.emitted().input).toHaveLength(1);
+ expect(wrapper.emitted().input[0]).toEqual([
+ {
+ end: '2019-10-19T00:00:00Z',
+ start: '2019-10-01T00:00:00Z',
+ },
+ ]);
+ });
+ });
+
+ it('emits iso dates, for dates without time of day', () => {
+ return fillInputAndBlur('#custom-time-from', '2019-10-01')
+ .then(() => fillInputAndBlur('#custom-time-to', '2019-10-19'))
+ .then(() => {
+ applyButtonElement().click();
+
+ expect(wrapper.emitted().input).toHaveLength(1);
+ expect(wrapper.emitted().input[0]).toEqual([
+ {
+ end: '2019-10-19T00:00:00Z',
+ start: '2019-10-01T00:00:00Z',
+ },
+ ]);
+ });
+ });
+
+ describe('when timezone is different', () => {
+ beforeAll(() => {
+ timezoneMock.register('US/Pacific');
+ });
+ afterAll(() => {
+ timezoneMock.unregister();
+ });
+
+ it('emits iso dates', () => {
+ return fillInputAndBlur('#custom-time-from', '2019-10-01 00:00:00')
+ .then(() => fillInputAndBlur('#custom-time-to', '2019-10-19 12:00:00'))
+ .then(() => {
+ applyButtonElement().click();
+
+ expect(wrapper.emitted().input).toHaveLength(1);
+ expect(wrapper.emitted().input[0]).toEqual([
+ {
+ start: '2019-10-01T07:00:00Z',
+ end: '2019-10-19T19:00:00Z',
+ },
+ ]);
+ });
+ });
+
+ it('emits iso dates with utc format', () => {
+ wrapper.setProps({ utc: true });
+ return wrapper.vm
+ .$nextTick()
+ .then(() => fillInputAndBlur('#custom-time-from', '2019-10-01 00:00:00'))
+ .then(() => fillInputAndBlur('#custom-time-to', '2019-10-19 12:00:00'))
+ .then(() => {
+ applyButtonElement().click();
+
+ expect(wrapper.emitted().input).toHaveLength(1);
+ expect(wrapper.emitted().input[0]).toEqual([
+ {
+ start: '2019-10-01T00:00:00Z',
+ end: '2019-10-19T12:00:00Z',
+ },
+ ]);
+ });
+ });
+ });
});
- it('unchecks quick range when text is input is clicked', done => {
+ it('unchecks quick range when text is input is clicked', () => {
const findActiveItems = () => findQuickRangeItems().filter(w => w.is('.active'));
expect(findActiveItems().length).toBe(1);
- fillInputAndBlur('#custom-time-from', '2019-10-01')
- .then(() => {
- expect(findActiveItems().length).toBe(0);
-
- done();
- })
- .catch(done.fail);
+ return fillInputAndBlur('#custom-time-from', '2019-10-01').then(() => {
+ expect(findActiveItems().length).toBe(0);
+ });
});
it('emits dates in an object when a is clicked', () => {
@@ -165,23 +248,22 @@ describe('DateTimePicker', () => {
.at(3) // any item
.trigger('click');
- expect(dateTimePicker.emitted().input).toHaveLength(1);
- expect(dateTimePicker.emitted().input[0][0]).toMatchObject({
+ expect(wrapper.emitted().input).toHaveLength(1);
+ expect(wrapper.emitted().input[0][0]).toMatchObject({
duration: {
seconds: expect.any(Number),
},
});
});
- it('hides the popover with cancel button', done => {
+ it('hides the popover with cancel button', () => {
dropdownToggle().trigger('click');
- dateTimePicker.vm.$nextTick(() => {
+ return wrapper.vm.$nextTick(() => {
cancelButtonElement().click();
- dateTimePicker.vm.$nextTick(() => {
+ return wrapper.vm.$nextTick(() => {
expect(dropdownMenu().classes('show')).toBe(false);
- done();
});
});
});
@@ -210,7 +292,7 @@ describe('DateTimePicker', () => {
jest.spyOn(Date, 'now').mockImplementation(() => MOCK_NOW);
});
- it('renders dropdown with a label in the quick range', done => {
+ it('renders dropdown with a label in the quick range', () => {
createComponent({
value: {
duration: { seconds: 60 * 5 },
@@ -218,14 +300,26 @@ describe('DateTimePicker', () => {
options: otherTimeRanges,
});
dropdownToggle().trigger('click');
- dateTimePicker.vm.$nextTick(() => {
+ return wrapper.vm.$nextTick(() => {
expect(dropdownToggle().text()).toBe('5 minutes');
+ });
+ });
- done();
+ it('renders dropdown with a label in the quick range and utc label', () => {
+ createComponent({
+ value: {
+ duration: { seconds: 60 * 5 },
+ },
+ utc: true,
+ options: otherTimeRanges,
+ });
+ dropdownToggle().trigger('click');
+ return wrapper.vm.$nextTick(() => {
+ expect(dropdownToggle().text()).toBe('5 minutes UTC');
});
});
- it('renders dropdown with quick range items', done => {
+ it('renders dropdown with quick range items', () => {
createComponent({
value: {
duration: { seconds: 60 * 2 },
@@ -233,7 +327,7 @@ describe('DateTimePicker', () => {
options: otherTimeRanges,
});
dropdownToggle().trigger('click');
- dateTimePicker.vm.$nextTick(() => {
+ return wrapper.vm.$nextTick(() => {
const items = findQuickRangeItems();
expect(items.length).toBe(Object.keys(otherTimeRanges).length);
@@ -245,22 +339,18 @@ describe('DateTimePicker', () => {
expect(items.at(2).text()).toBe('5 minutes');
expect(items.at(2).is('.active')).toBe(false);
-
- done();
});
});
- it('renders dropdown with a label not in the quick range', done => {
+ it('renders dropdown with a label not in the quick range', () => {
createComponent({
value: {
duration: { seconds: 60 * 4 },
},
});
dropdownToggle().trigger('click');
- dateTimePicker.vm.$nextTick(() => {
+ return wrapper.vm.$nextTick(() => {
expect(dropdownToggle().text()).toBe('2020-01-23 19:56:00 to 2020-01-23 20:00:00');
-
- done();
});
});
});
diff --git a/spec/frontend/vue_shared/components/deprecated_modal_2_spec.js b/spec/frontend/vue_shared/components/deprecated_modal_2_spec.js
new file mode 100644
index 00000000000..b201a9acdd4
--- /dev/null
+++ b/spec/frontend/vue_shared/components/deprecated_modal_2_spec.js
@@ -0,0 +1,258 @@
+import Vue from 'vue';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import DeprecatedModal2 from '~/vue_shared/components/deprecated_modal_2.vue';
+
+const modalComponent = Vue.extend(DeprecatedModal2);
+
+describe('DeprecatedModal2', () => {
+ let vm;
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('props', () => {
+ describe('with id', () => {
+ const props = {
+ id: 'my-modal',
+ };
+
+ beforeEach(() => {
+ vm = mountComponent(modalComponent, props);
+ });
+
+ it('assigns the id to the modal', () => {
+ expect(vm.$el.id).toBe(props.id);
+ });
+ });
+
+ describe('without id', () => {
+ beforeEach(() => {
+ vm = mountComponent(modalComponent, {});
+ });
+
+ it('does not add an id attribute to the modal', () => {
+ expect(vm.$el.hasAttribute('id')).toBe(false);
+ });
+ });
+
+ describe('with headerTitleText', () => {
+ const props = {
+ headerTitleText: 'my title text',
+ };
+
+ beforeEach(() => {
+ vm = mountComponent(modalComponent, props);
+ });
+
+ it('sets the modal title', () => {
+ const modalTitle = vm.$el.querySelector('.modal-title');
+
+ expect(modalTitle.innerHTML.trim()).toBe(props.headerTitleText);
+ });
+ });
+
+ describe('with footerPrimaryButtonVariant', () => {
+ const props = {
+ footerPrimaryButtonVariant: 'danger',
+ };
+
+ beforeEach(() => {
+ vm = mountComponent(modalComponent, props);
+ });
+
+ it('sets the primary button class', () => {
+ const primaryButton = vm.$el.querySelector('.modal-footer button:last-of-type');
+
+ expect(primaryButton).toHaveClass(`btn-${props.footerPrimaryButtonVariant}`);
+ });
+ });
+
+ describe('with footerPrimaryButtonText', () => {
+ const props = {
+ footerPrimaryButtonText: 'my button text',
+ };
+
+ beforeEach(() => {
+ vm = mountComponent(modalComponent, props);
+ });
+
+ it('sets the primary button text', () => {
+ const primaryButton = vm.$el.querySelector('.modal-footer button:last-of-type');
+
+ expect(primaryButton.innerHTML.trim()).toBe(props.footerPrimaryButtonText);
+ });
+ });
+ });
+
+ it('works with data-toggle="modal"', () => {
+ setFixtures(`
+ <button id="modal-button" data-toggle="modal" data-target="#my-modal"></button>
+ <div id="modal-container"></div>
+ `);
+
+ const modalContainer = document.getElementById('modal-container');
+ const modalButton = document.getElementById('modal-button');
+ vm = mountComponent(
+ modalComponent,
+ {
+ id: 'my-modal',
+ },
+ modalContainer,
+ );
+ const modalElement = document.getElementById('my-modal');
+
+ modalButton.click();
+
+ expect(modalElement).not.toHaveClass('show');
+
+ // let the modal fade in
+ jest.runOnlyPendingTimers();
+
+ expect(modalElement).toHaveClass('show');
+ });
+
+ describe('methods', () => {
+ const dummyEvent = 'not really an event';
+
+ beforeEach(() => {
+ vm = mountComponent(modalComponent, {});
+ jest.spyOn(vm, '$emit').mockImplementation(() => {});
+ });
+
+ describe('emitCancel', () => {
+ it('emits a cancel event', () => {
+ vm.emitCancel(dummyEvent);
+
+ expect(vm.$emit).toHaveBeenCalledWith('cancel', dummyEvent);
+ });
+ });
+
+ describe('emitSubmit', () => {
+ it('emits a submit event', () => {
+ vm.emitSubmit(dummyEvent);
+
+ expect(vm.$emit).toHaveBeenCalledWith('submit', dummyEvent);
+ });
+ });
+
+ describe('opened', () => {
+ it('emits a open event', () => {
+ vm.opened();
+
+ expect(vm.$emit).toHaveBeenCalledWith('open');
+ });
+ });
+
+ describe('closed', () => {
+ it('emits a closed event', () => {
+ vm.closed();
+
+ expect(vm.$emit).toHaveBeenCalledWith('closed');
+ });
+ });
+ });
+
+ describe('slots', () => {
+ const slotContent = 'this should go into the slot';
+
+ const modalWithSlot = slot => {
+ return Vue.extend({
+ components: {
+ DeprecatedModal2,
+ },
+ render: h =>
+ h('deprecated-modal-2', [slot ? h('template', { slot }, slotContent) : slotContent]),
+ });
+ };
+
+ describe('default slot', () => {
+ beforeEach(() => {
+ vm = mountComponent(modalWithSlot());
+ });
+
+ it('sets the modal body', () => {
+ const modalBody = vm.$el.querySelector('.modal-body');
+
+ expect(modalBody.innerHTML).toBe(slotContent);
+ });
+ });
+
+ describe('header slot', () => {
+ beforeEach(() => {
+ vm = mountComponent(modalWithSlot('header'));
+ });
+
+ it('sets the modal header', () => {
+ const modalHeader = vm.$el.querySelector('.modal-header');
+
+ expect(modalHeader.innerHTML).toBe(slotContent);
+ });
+ });
+
+ describe('title slot', () => {
+ beforeEach(() => {
+ vm = mountComponent(modalWithSlot('title'));
+ });
+
+ it('sets the modal title', () => {
+ const modalTitle = vm.$el.querySelector('.modal-title');
+
+ expect(modalTitle.innerHTML).toBe(slotContent);
+ });
+ });
+
+ describe('footer slot', () => {
+ beforeEach(() => {
+ vm = mountComponent(modalWithSlot('footer'));
+ });
+
+ it('sets the modal footer', () => {
+ const modalFooter = vm.$el.querySelector('.modal-footer');
+
+ expect(modalFooter.innerHTML).toBe(slotContent);
+ });
+ });
+ });
+
+ describe('handling sizes', () => {
+ it('should render modal-sm', () => {
+ vm = mountComponent(modalComponent, {
+ modalSize: 'sm',
+ });
+
+ expect(vm.$el.querySelector('.modal-dialog').classList.contains('modal-sm')).toEqual(true);
+ });
+
+ it('should render modal-lg', () => {
+ vm = mountComponent(modalComponent, {
+ modalSize: 'lg',
+ });
+
+ expect(vm.$el.querySelector('.modal-dialog').classList.contains('modal-lg')).toEqual(true);
+ });
+
+ it('should render modal-xl', () => {
+ vm = mountComponent(modalComponent, {
+ modalSize: 'xl',
+ });
+
+ expect(vm.$el.querySelector('.modal-dialog').classList.contains('modal-xl')).toEqual(true);
+ });
+
+ it('should not add modal size classes when md size is passed', () => {
+ vm = mountComponent(modalComponent, {
+ modalSize: 'md',
+ });
+
+ expect(vm.$el.querySelector('.modal-dialog').classList.contains('modal-md')).toEqual(false);
+ });
+
+ it('should not add modal size classes by default', () => {
+ vm = mountComponent(modalComponent, {});
+
+ expect(vm.$el.querySelector('.modal-dialog').classList.contains('modal-sm')).toEqual(false);
+ expect(vm.$el.querySelector('.modal-dialog').classList.contains('modal-lg')).toEqual(false);
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/components/deprecated_modal_spec.js b/spec/frontend/vue_shared/components/deprecated_modal_spec.js
new file mode 100644
index 00000000000..b9793ce2d80
--- /dev/null
+++ b/spec/frontend/vue_shared/components/deprecated_modal_spec.js
@@ -0,0 +1,73 @@
+import Vue from 'vue';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import DeprecatedModal from '~/vue_shared/components/deprecated_modal.vue';
+
+const modalComponent = Vue.extend(DeprecatedModal);
+
+describe('DeprecatedModal', () => {
+ let vm;
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('props', () => {
+ describe('without primaryButtonLabel', () => {
+ beforeEach(() => {
+ vm = mountComponent(modalComponent, {
+ primaryButtonLabel: null,
+ });
+ });
+
+ it('does not render a primary button', () => {
+ expect(vm.$el.querySelector('.js-primary-button')).toBeNull();
+ });
+ });
+
+ describe('with id', () => {
+ describe('does not render a primary button', () => {
+ beforeEach(() => {
+ vm = mountComponent(modalComponent, {
+ id: 'my-modal',
+ });
+ });
+
+ it('assigns the id to the modal', () => {
+ expect(vm.$el.querySelector('#my-modal.modal')).not.toBeNull();
+ });
+
+ it('does not show the modal immediately', () => {
+ expect(vm.$el.querySelector('#my-modal.modal')).not.toHaveClass('show');
+ });
+
+ it('does not show a backdrop', () => {
+ expect(vm.$el.querySelector('modal-backdrop')).toBeNull();
+ });
+ });
+ });
+
+ it('works with data-toggle="modal"', () => {
+ setFixtures(`
+ <button id="modal-button" data-toggle="modal" data-target="#my-modal"></button>
+ <div id="modal-container"></div>
+ `);
+
+ const modalContainer = document.getElementById('modal-container');
+ const modalButton = document.getElementById('modal-button');
+ vm = mountComponent(
+ modalComponent,
+ {
+ id: 'my-modal',
+ },
+ modalContainer,
+ );
+ const modalElement = vm.$el.querySelector('#my-modal');
+
+ expect(modalElement).not.toHaveClass('show');
+
+ modalButton.click();
+
+ expect(modalElement).toHaveClass('show');
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/components/diff_viewer/diff_viewer_spec.js b/spec/frontend/vue_shared/components/diff_viewer/diff_viewer_spec.js
index 636508be6b6..a6e4d812c3c 100644
--- a/spec/frontend/vue_shared/components/diff_viewer/diff_viewer_spec.js
+++ b/spec/frontend/vue_shared/components/diff_viewer/diff_viewer_spec.js
@@ -8,6 +8,7 @@ describe('DiffViewer', () => {
const requiredProps = {
diffMode: 'replaced',
diffViewerMode: 'image',
+ diffFile: {},
newPath: GREEN_BOX_IMAGE_URL,
newSha: 'ABC',
oldPath: RED_BOX_IMAGE_URL,
@@ -71,16 +72,27 @@ describe('DiffViewer', () => {
});
});
- it('renders renamed component', () => {
- createComponent({
- ...requiredProps,
- diffMode: 'renamed',
- diffViewerMode: 'renamed',
- newPath: 'test.abc',
- oldPath: 'testold.abc',
+ describe('renamed file', () => {
+ it.each`
+ altViewer
+ ${'text'}
+ ${'notText'}
+ `('renders the renamed component when the alternate viewer is $altViewer', ({ altViewer }) => {
+ createComponent({
+ ...requiredProps,
+ diffFile: {
+ content_sha: '',
+ view_path: '',
+ alternate_viewer: { name: altViewer },
+ },
+ diffMode: 'renamed',
+ diffViewerMode: 'renamed',
+ newPath: 'test.abc',
+ oldPath: 'testold.abc',
+ });
+
+ expect(vm.$el.textContent).toContain('File renamed with no changes.');
});
-
- expect(vm.$el.textContent).toContain('File moved');
});
it('renders mode changed component', () => {
diff --git a/spec/frontend/vue_shared/components/diff_viewer/viewers/renamed_spec.js b/spec/frontend/vue_shared/components/diff_viewer/viewers/renamed_spec.js
new file mode 100644
index 00000000000..e0e982f4e11
--- /dev/null
+++ b/spec/frontend/vue_shared/components/diff_viewer/viewers/renamed_spec.js
@@ -0,0 +1,283 @@
+import Vuex from 'vuex';
+import { createLocalVue, shallowMount, mount } from '@vue/test-utils';
+import Renamed from '~/vue_shared/components/diff_viewer/viewers/renamed.vue';
+import {
+ TRANSITION_LOAD_START,
+ TRANSITION_LOAD_ERROR,
+ TRANSITION_LOAD_SUCCEED,
+ TRANSITION_ACKNOWLEDGE_ERROR,
+ STATE_IDLING,
+ STATE_LOADING,
+ STATE_ERRORED,
+} from '~/diffs/constants';
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+function createRenamedComponent({
+ props = {},
+ methods = {},
+ store = new Vuex.Store({}),
+ deep = false,
+}) {
+ const mnt = deep ? mount : shallowMount;
+
+ return mnt(Renamed, {
+ propsData: { ...props },
+ localVue,
+ store,
+ methods,
+ });
+}
+
+describe('Renamed Diff Viewer', () => {
+ const DIFF_FILE_COMMIT_SHA = 'commitsha';
+ const DIFF_FILE_SHORT_SHA = 'commitsh';
+ const DIFF_FILE_VIEW_PATH = `blob/${DIFF_FILE_COMMIT_SHA}/filename.ext`;
+ let diffFile;
+ let wrapper;
+
+ beforeEach(() => {
+ diffFile = {
+ content_sha: DIFF_FILE_COMMIT_SHA,
+ view_path: DIFF_FILE_VIEW_PATH,
+ alternate_viewer: {
+ name: 'text',
+ },
+ };
+ });
+
+ afterEach(() => {
+ if (wrapper) {
+ wrapper.destroy();
+ wrapper = null;
+ }
+ });
+
+ describe('is', () => {
+ beforeEach(() => {
+ wrapper = createRenamedComponent({ props: { diffFile } });
+ });
+
+ it.each`
+ state | request | result
+ ${'idle'} | ${'idle'} | ${true}
+ ${'idle'} | ${'loading'} | ${false}
+ ${'idle'} | ${'errored'} | ${false}
+ ${'loading'} | ${'loading'} | ${true}
+ ${'loading'} | ${'idle'} | ${false}
+ ${'loading'} | ${'errored'} | ${false}
+ ${'errored'} | ${'errored'} | ${true}
+ ${'errored'} | ${'idle'} | ${false}
+ ${'errored'} | ${'loading'} | ${false}
+ `(
+ 'returns the $result for "$request" when the state is "$state"',
+ ({ request, result, state }) => {
+ wrapper.vm.state = state;
+
+ expect(wrapper.vm.is(request)).toEqual(result);
+ },
+ );
+ });
+
+ describe('transition', () => {
+ beforeEach(() => {
+ wrapper = createRenamedComponent({ props: { diffFile } });
+ });
+
+ it.each`
+ state | transition | result
+ ${'idle'} | ${TRANSITION_LOAD_START} | ${STATE_LOADING}
+ ${'idle'} | ${TRANSITION_LOAD_ERROR} | ${STATE_IDLING}
+ ${'idle'} | ${TRANSITION_LOAD_SUCCEED} | ${STATE_IDLING}
+ ${'idle'} | ${TRANSITION_ACKNOWLEDGE_ERROR} | ${STATE_IDLING}
+ ${'loading'} | ${TRANSITION_LOAD_START} | ${STATE_LOADING}
+ ${'loading'} | ${TRANSITION_LOAD_ERROR} | ${STATE_ERRORED}
+ ${'loading'} | ${TRANSITION_LOAD_SUCCEED} | ${STATE_IDLING}
+ ${'loading'} | ${TRANSITION_ACKNOWLEDGE_ERROR} | ${STATE_LOADING}
+ ${'errored'} | ${TRANSITION_LOAD_START} | ${STATE_LOADING}
+ ${'errored'} | ${TRANSITION_LOAD_ERROR} | ${STATE_ERRORED}
+ ${'errored'} | ${TRANSITION_LOAD_SUCCEED} | ${STATE_ERRORED}
+ ${'errored'} | ${TRANSITION_ACKNOWLEDGE_ERROR} | ${STATE_IDLING}
+ `(
+ 'correctly updates the state to "$result" when it starts as "$state" and the transition is "$transition"',
+ ({ state, transition, result }) => {
+ wrapper.vm.state = state;
+
+ wrapper.vm.transition(transition);
+
+ expect(wrapper.vm.state).toEqual(result);
+ },
+ );
+ });
+
+ describe('switchToFull', () => {
+ let store;
+
+ beforeEach(() => {
+ store = new Vuex.Store({
+ modules: {
+ diffs: {
+ namespaced: true,
+ actions: { switchToFullDiffFromRenamedFile: () => {} },
+ },
+ },
+ });
+
+ jest.spyOn(store, 'dispatch');
+
+ wrapper = createRenamedComponent({ props: { diffFile }, store });
+ });
+
+ afterEach(() => {
+ store = null;
+ });
+
+ it('calls the switchToFullDiffFromRenamedFile action when the method is triggered', () => {
+ store.dispatch.mockResolvedValue();
+
+ wrapper.vm.switchToFull();
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(store.dispatch).toHaveBeenCalledWith('diffs/switchToFullDiffFromRenamedFile', {
+ diffFile,
+ });
+ });
+ });
+
+ it.each`
+ after | resolvePromise | resolution
+ ${STATE_IDLING} | ${'mockResolvedValue'} | ${'successful'}
+ ${STATE_ERRORED} | ${'mockRejectedValue'} | ${'rejected'}
+ `(
+ 'moves through the correct states during a $resolution request',
+ ({ after, resolvePromise }) => {
+ store.dispatch[resolvePromise]();
+
+ expect(wrapper.vm.state).toEqual(STATE_IDLING);
+
+ wrapper.vm.switchToFull();
+
+ expect(wrapper.vm.state).toEqual(STATE_LOADING);
+
+ return (
+ wrapper.vm
+ // This tick is needed for when the action (promise) finishes
+ .$nextTick()
+ // This tick waits for the state change in the promise .then/.catch to bubble into the component
+ .then(() => wrapper.vm.$nextTick())
+ .then(() => {
+ expect(wrapper.vm.state).toEqual(after);
+ })
+ );
+ },
+ );
+ });
+
+ describe('clickLink', () => {
+ let event;
+
+ beforeEach(() => {
+ event = {
+ preventDefault: jest.fn(),
+ };
+ });
+
+ it.each`
+ alternateViewer | stops | handled
+ ${'text'} | ${true} | ${'should'}
+ ${'nottext'} | ${false} | ${'should not'}
+ `(
+ 'given { alternate_viewer: { name: "$alternateViewer" } }, the click event $handled be handled in the component',
+ ({ alternateViewer, stops }) => {
+ wrapper = createRenamedComponent({
+ props: {
+ diffFile: {
+ ...diffFile,
+ alternate_viewer: { name: alternateViewer },
+ },
+ },
+ });
+
+ jest.spyOn(wrapper.vm, 'switchToFull').mockImplementation(() => {});
+
+ wrapper.vm.clickLink(event);
+
+ if (stops) {
+ expect(event.preventDefault).toHaveBeenCalled();
+ expect(wrapper.vm.switchToFull).toHaveBeenCalled();
+ } else {
+ expect(event.preventDefault).not.toHaveBeenCalled();
+ expect(wrapper.vm.switchToFull).not.toHaveBeenCalled();
+ }
+ },
+ );
+ });
+
+ describe('dismissError', () => {
+ let transitionSpy;
+
+ beforeEach(() => {
+ wrapper = createRenamedComponent({ props: { diffFile } });
+ transitionSpy = jest.spyOn(wrapper.vm, 'transition');
+ });
+
+ it(`transitions the component with "${TRANSITION_ACKNOWLEDGE_ERROR}"`, () => {
+ wrapper.vm.dismissError();
+
+ expect(transitionSpy).toHaveBeenCalledWith(TRANSITION_ACKNOWLEDGE_ERROR);
+ });
+ });
+
+ describe('output', () => {
+ it.each`
+ altViewer | nameDisplay
+ ${'text'} | ${'"text"'}
+ ${'nottext'} | ${'"nottext"'}
+ ${undefined} | ${undefined}
+ ${null} | ${null}
+ `(
+ 'with { alternate_viewer: { name: $nameDisplay } }, renders the component',
+ ({ altViewer }) => {
+ const file = { ...diffFile };
+
+ file.alternate_viewer.name = altViewer;
+ wrapper = createRenamedComponent({ props: { diffFile: file } });
+
+ expect(wrapper.find('[test-id="plaintext"]').text()).toEqual(
+ 'File renamed with no changes.',
+ );
+ },
+ );
+
+ it.each`
+ altType | linkText
+ ${'text'} | ${'Show file contents'}
+ ${'nottext'} | ${`View file @ ${DIFF_FILE_SHORT_SHA}`}
+ `(
+ 'includes a link to the full file for alternate viewer type "$altType"',
+ ({ altType, linkText }) => {
+ const file = { ...diffFile };
+ const clickMock = jest.fn().mockImplementation(() => {});
+
+ file.alternate_viewer.name = altType;
+ wrapper = createRenamedComponent({
+ deep: true,
+ props: { diffFile: file },
+ methods: {
+ clickLink: clickMock,
+ },
+ });
+
+ const link = wrapper.find('a');
+
+ expect(link.text()).toEqual(linkText);
+ expect(link.attributes('href')).toEqual(DIFF_FILE_VIEW_PATH);
+
+ link.vm.$emit('click');
+
+ expect(clickMock).toHaveBeenCalled();
+ },
+ );
+ });
+});
diff --git a/spec/frontend/vue_shared/components/file_finder/index_spec.js b/spec/frontend/vue_shared/components/file_finder/index_spec.js
new file mode 100644
index 00000000000..f9e56774526
--- /dev/null
+++ b/spec/frontend/vue_shared/components/file_finder/index_spec.js
@@ -0,0 +1,368 @@
+import Vue from 'vue';
+import Mousetrap from 'mousetrap';
+import { file } from 'jest/ide/helpers';
+import waitForPromises from 'helpers/wait_for_promises';
+import FindFileComponent from '~/vue_shared/components/file_finder/index.vue';
+import { UP_KEY_CODE, DOWN_KEY_CODE, ENTER_KEY_CODE, ESC_KEY_CODE } from '~/lib/utils/keycodes';
+
+describe('File finder item spec', () => {
+ const Component = Vue.extend(FindFileComponent);
+ let vm;
+
+ function createComponent(props) {
+ vm = new Component({
+ propsData: {
+ files: [],
+ visible: true,
+ loading: false,
+ ...props,
+ },
+ });
+
+ vm.$mount('#app');
+ }
+
+ beforeEach(() => {
+ setFixtures('<div id="app"></div>');
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('with entries', () => {
+ beforeEach(done => {
+ createComponent({
+ files: [
+ {
+ ...file('index.js'),
+ path: 'index.js',
+ type: 'blob',
+ url: '/index.jsurl',
+ },
+ {
+ ...file('component.js'),
+ path: 'component.js',
+ type: 'blob',
+ },
+ ],
+ });
+
+ setImmediate(done);
+ });
+
+ it('renders list of blobs', () => {
+ expect(vm.$el.textContent).toContain('index.js');
+ expect(vm.$el.textContent).toContain('component.js');
+ expect(vm.$el.textContent).not.toContain('folder');
+ });
+
+ it('filters entries', done => {
+ vm.searchText = 'index';
+
+ setImmediate(() => {
+ expect(vm.$el.textContent).toContain('index.js');
+ expect(vm.$el.textContent).not.toContain('component.js');
+
+ done();
+ });
+ });
+
+ it('shows clear button when searchText is not empty', done => {
+ vm.searchText = 'index';
+
+ setImmediate(() => {
+ expect(vm.$el.querySelector('.dropdown-input').classList).toContain('has-value');
+ expect(vm.$el.querySelector('.dropdown-input-search').classList).toContain('hidden');
+
+ done();
+ });
+ });
+
+ it('clear button resets searchText', done => {
+ vm.searchText = 'index';
+
+ waitForPromises()
+ .then(() => {
+ vm.$el.querySelector('.dropdown-input-clear').click();
+ })
+ .then(waitForPromises)
+ .then(() => {
+ expect(vm.searchText).toBe('');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('clear button focues search input', done => {
+ jest.spyOn(vm.$refs.searchInput, 'focus').mockImplementation(() => {});
+ vm.searchText = 'index';
+
+ waitForPromises()
+ .then(() => {
+ vm.$el.querySelector('.dropdown-input-clear').click();
+ })
+ .then(waitForPromises)
+ .then(() => {
+ expect(vm.$refs.searchInput.focus).toHaveBeenCalled();
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ describe('listShowCount', () => {
+ it('returns 1 when no filtered entries exist', done => {
+ vm.searchText = 'testing 123';
+
+ setImmediate(() => {
+ expect(vm.listShowCount).toBe(1);
+
+ done();
+ });
+ });
+
+ it('returns entries length when not filtered', () => {
+ expect(vm.listShowCount).toBe(2);
+ });
+ });
+
+ describe('listHeight', () => {
+ it('returns 55 when entries exist', () => {
+ expect(vm.listHeight).toBe(55);
+ });
+
+ it('returns 33 when entries dont exist', done => {
+ vm.searchText = 'testing 123';
+
+ setImmediate(() => {
+ expect(vm.listHeight).toBe(33);
+
+ done();
+ });
+ });
+ });
+
+ describe('filteredBlobsLength', () => {
+ it('returns length of filtered blobs', done => {
+ vm.searchText = 'index';
+
+ setImmediate(() => {
+ expect(vm.filteredBlobsLength).toBe(1);
+
+ done();
+ });
+ });
+ });
+
+ describe('watches', () => {
+ describe('searchText', () => {
+ it('resets focusedIndex when updated', done => {
+ vm.focusedIndex = 1;
+ vm.searchText = 'test';
+
+ setImmediate(() => {
+ expect(vm.focusedIndex).toBe(0);
+
+ done();
+ });
+ });
+ });
+
+ describe('visible', () => {
+ it('returns searchText when false', done => {
+ vm.searchText = 'test';
+ vm.visible = true;
+
+ waitForPromises()
+ .then(() => {
+ vm.visible = false;
+ })
+ .then(waitForPromises)
+ .then(() => {
+ expect(vm.searchText).toBe('');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+ });
+
+ describe('openFile', () => {
+ beforeEach(() => {
+ jest.spyOn(vm, '$emit').mockImplementation(() => {});
+ });
+
+ it('closes file finder', () => {
+ vm.openFile(vm.files[0]);
+
+ expect(vm.$emit).toHaveBeenCalledWith('toggle', false);
+ });
+
+ it('pushes to router', () => {
+ vm.openFile(vm.files[0]);
+
+ expect(vm.$emit).toHaveBeenCalledWith('click', vm.files[0]);
+ });
+ });
+
+ describe('onKeyup', () => {
+ it('opens file on enter key', done => {
+ const event = new CustomEvent('keyup');
+ event.keyCode = ENTER_KEY_CODE;
+
+ jest.spyOn(vm, 'openFile').mockImplementation(() => {});
+
+ vm.$refs.searchInput.dispatchEvent(event);
+
+ setImmediate(() => {
+ expect(vm.openFile).toHaveBeenCalledWith(vm.files[0]);
+
+ done();
+ });
+ });
+
+ it('closes file finder on esc key', done => {
+ const event = new CustomEvent('keyup');
+ event.keyCode = ESC_KEY_CODE;
+
+ jest.spyOn(vm, '$emit').mockImplementation(() => {});
+
+ vm.$refs.searchInput.dispatchEvent(event);
+
+ setImmediate(() => {
+ expect(vm.$emit).toHaveBeenCalledWith('toggle', false);
+
+ done();
+ });
+ });
+ });
+
+ describe('onKeyDown', () => {
+ let el;
+
+ beforeEach(() => {
+ el = vm.$refs.searchInput;
+ });
+
+ describe('up key', () => {
+ const event = new CustomEvent('keydown');
+ event.keyCode = UP_KEY_CODE;
+
+ it('resets to last index when at top', () => {
+ el.dispatchEvent(event);
+
+ expect(vm.focusedIndex).toBe(1);
+ });
+
+ it('minus 1 from focusedIndex', () => {
+ vm.focusedIndex = 1;
+
+ el.dispatchEvent(event);
+
+ expect(vm.focusedIndex).toBe(0);
+ });
+ });
+
+ describe('down key', () => {
+ const event = new CustomEvent('keydown');
+ event.keyCode = DOWN_KEY_CODE;
+
+ it('resets to first index when at bottom', () => {
+ vm.focusedIndex = 1;
+ el.dispatchEvent(event);
+
+ expect(vm.focusedIndex).toBe(0);
+ });
+
+ it('adds 1 to focusedIndex', () => {
+ el.dispatchEvent(event);
+
+ expect(vm.focusedIndex).toBe(1);
+ });
+ });
+ });
+ });
+
+ describe('without entries', () => {
+ it('renders loading text when loading', () => {
+ createComponent({
+ loading: true,
+ });
+
+ expect(vm.$el.textContent).toContain('Loading...');
+ });
+
+ it('renders no files text', () => {
+ createComponent();
+
+ expect(vm.$el.textContent).toContain('No files found.');
+ });
+ });
+
+ describe('keyboard shortcuts', () => {
+ beforeEach(done => {
+ createComponent();
+
+ jest.spyOn(vm, 'toggle').mockImplementation(() => {});
+
+ vm.$nextTick(done);
+ });
+
+ it('calls toggle on `t` key press', done => {
+ Mousetrap.trigger('t');
+
+ vm.$nextTick()
+ .then(() => {
+ expect(vm.toggle).toHaveBeenCalled();
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('calls toggle on `command+p` key press', done => {
+ Mousetrap.trigger('command+p');
+
+ vm.$nextTick()
+ .then(() => {
+ expect(vm.toggle).toHaveBeenCalled();
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('calls toggle on `ctrl+p` key press', done => {
+ Mousetrap.trigger('ctrl+p');
+
+ vm.$nextTick()
+ .then(() => {
+ expect(vm.toggle).toHaveBeenCalled();
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('always allows `command+p` to trigger toggle', () => {
+ expect(
+ vm.mousetrapStopCallback(null, vm.$el.querySelector('.dropdown-input-field'), 'command+p'),
+ ).toBe(false);
+ });
+
+ it('always allows `ctrl+p` to trigger toggle', () => {
+ expect(
+ vm.mousetrapStopCallback(null, vm.$el.querySelector('.dropdown-input-field'), 'ctrl+p'),
+ ).toBe(false);
+ });
+
+ it('onlys handles `t` when focused in input-field', () => {
+ expect(
+ vm.mousetrapStopCallback(null, vm.$el.querySelector('.dropdown-input-field'), 't'),
+ ).toBe(true);
+ });
+
+ it('stops callback in monaco editor', () => {
+ setFixtures('<div class="inputarea"></div>');
+
+ expect(vm.mousetrapStopCallback(null, document.querySelector('.inputarea'), 't')).toBe(true);
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js
new file mode 100644
index 00000000000..eded5b87abc
--- /dev/null
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js
@@ -0,0 +1,259 @@
+import { shallowMount } from '@vue/test-utils';
+import {
+ GlFilteredSearch,
+ GlButtonGroup,
+ GlButton,
+ GlNewDropdown as GlDropdown,
+ GlNewDropdownItem as GlDropdownItem,
+} from '@gitlab/ui';
+
+import FilteredSearchBarRoot from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
+import { SortDirection } from '~/vue_shared/components/filtered_search_bar/constants';
+
+import RecentSearchesStore from '~/filtered_search/stores/recent_searches_store';
+import RecentSearchesService from '~/filtered_search/services/recent_searches_service';
+
+import { mockAvailableTokens, mockSortOptions } from './mock_data';
+
+const createComponent = ({
+ namespace = 'gitlab-org/gitlab-test',
+ recentSearchesStorageKey = 'requirements',
+ tokens = mockAvailableTokens,
+ sortOptions = mockSortOptions,
+ searchInputPlaceholder = 'Filter requirements',
+} = {}) =>
+ shallowMount(FilteredSearchBarRoot, {
+ propsData: {
+ namespace,
+ recentSearchesStorageKey,
+ tokens,
+ sortOptions,
+ searchInputPlaceholder,
+ },
+ });
+
+describe('FilteredSearchBarRoot', () => {
+ let wrapper;
+
+ beforeEach(() => {
+ wrapper = createComponent();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('data', () => {
+ it('initializes `filterValue`, `selectedSortOption` and `selectedSortDirection` data props', () => {
+ expect(wrapper.vm.filterValue).toEqual([]);
+ expect(wrapper.vm.selectedSortOption).toBe(mockSortOptions[0].sortDirection.descending);
+ expect(wrapper.vm.selectedSortDirection).toBe(SortDirection.descending);
+ });
+ });
+
+ describe('computed', () => {
+ describe('tokenSymbols', () => {
+ it('returns array of map containing type and symbols from `tokens` prop', () => {
+ expect(wrapper.vm.tokenSymbols).toEqual({ author_username: '@' });
+ });
+ });
+
+ describe('sortDirectionIcon', () => {
+ it('returns string "sort-lowest" when `selectedSortDirection` is "ascending"', () => {
+ wrapper.setData({
+ selectedSortDirection: SortDirection.ascending,
+ });
+
+ expect(wrapper.vm.sortDirectionIcon).toBe('sort-lowest');
+ });
+
+ it('returns string "sort-highest" when `selectedSortDirection` is "descending"', () => {
+ wrapper.setData({
+ selectedSortDirection: SortDirection.descending,
+ });
+
+ expect(wrapper.vm.sortDirectionIcon).toBe('sort-highest');
+ });
+ });
+
+ describe('sortDirectionTooltip', () => {
+ it('returns string "Sort direction: Ascending" when `selectedSortDirection` is "ascending"', () => {
+ wrapper.setData({
+ selectedSortDirection: SortDirection.ascending,
+ });
+
+ expect(wrapper.vm.sortDirectionTooltip).toBe('Sort direction: Ascending');
+ });
+
+ it('returns string "Sort direction: Descending" when `selectedSortDirection` is "descending"', () => {
+ wrapper.setData({
+ selectedSortDirection: SortDirection.descending,
+ });
+
+ expect(wrapper.vm.sortDirectionTooltip).toBe('Sort direction: Descending');
+ });
+ });
+ });
+
+ describe('watchers', () => {
+ describe('filterValue', () => {
+ it('emits component event `onFilter` with empty array when `filterValue` is cleared by GlFilteredSearch', () => {
+ wrapper.setData({
+ initialRender: false,
+ filterValue: [
+ {
+ type: 'filtered-search-term',
+ value: { data: '' },
+ },
+ ],
+ });
+
+ return wrapper.vm.$nextTick(() => {
+ expect(wrapper.emitted('onFilter')[0]).toEqual([[]]);
+ });
+ });
+ });
+ });
+
+ describe('methods', () => {
+ describe('setupRecentSearch', () => {
+ it('initializes `recentSearchesService` and `recentSearchesStore` props when `recentSearchesStorageKey` is available', () => {
+ expect(wrapper.vm.recentSearchesService instanceof RecentSearchesService).toBe(true);
+ expect(wrapper.vm.recentSearchesStore instanceof RecentSearchesStore).toBe(true);
+ });
+
+ it('initializes `recentSearchesPromise` prop with a promise by using `recentSearchesService.fetch()`', () => {
+ jest
+ .spyOn(wrapper.vm.recentSearchesService, 'fetch')
+ .mockReturnValue(new Promise(() => []));
+
+ wrapper.vm.setupRecentSearch();
+
+ expect(wrapper.vm.recentSearchesPromise instanceof Promise).toBe(true);
+ });
+ });
+
+ describe('getRecentSearches', () => {
+ it('returns array of strings representing recent searches', () => {
+ wrapper.vm.recentSearchesStore.setRecentSearches(['foo']);
+
+ expect(wrapper.vm.getRecentSearches()).toEqual(['foo']);
+ });
+ });
+
+ describe('handleSortOptionClick', () => {
+ it('emits component event `onSort` with selected sort by value', () => {
+ wrapper.vm.handleSortOptionClick(mockSortOptions[1]);
+
+ expect(wrapper.vm.selectedSortOption).toBe(mockSortOptions[1]);
+ expect(wrapper.emitted('onSort')[0]).toEqual([mockSortOptions[1].sortDirection.descending]);
+ });
+ });
+
+ describe('handleSortDirectionClick', () => {
+ beforeEach(() => {
+ wrapper.setData({
+ selectedSortOption: mockSortOptions[0],
+ });
+ });
+
+ it('sets `selectedSortDirection` to be opposite of its current value', () => {
+ expect(wrapper.vm.selectedSortDirection).toBe(SortDirection.descending);
+
+ wrapper.vm.handleSortDirectionClick();
+
+ expect(wrapper.vm.selectedSortDirection).toBe(SortDirection.ascending);
+ });
+
+ it('emits component event `onSort` with opposite of currently selected sort by value', () => {
+ wrapper.vm.handleSortDirectionClick();
+
+ expect(wrapper.emitted('onSort')[0]).toEqual([mockSortOptions[0].sortDirection.ascending]);
+ });
+ });
+
+ describe('handleFilterSubmit', () => {
+ const mockFilters = [
+ {
+ type: 'author_username',
+ value: {
+ data: 'root',
+ operator: '=',
+ },
+ },
+ 'foo',
+ ];
+
+ it('calls `recentSearchesStore.addRecentSearch` with serialized value of provided `filters` param', () => {
+ jest.spyOn(wrapper.vm.recentSearchesStore, 'addRecentSearch');
+ // jest.spyOn(wrapper.vm.recentSearchesService, 'save');
+
+ wrapper.vm.handleFilterSubmit(mockFilters);
+
+ return wrapper.vm.recentSearchesPromise.then(() => {
+ expect(wrapper.vm.recentSearchesStore.addRecentSearch).toHaveBeenCalledWith(
+ 'author_username:=@root foo',
+ );
+ });
+ });
+
+ it('calls `recentSearchesService.save` with array of searches', () => {
+ jest.spyOn(wrapper.vm.recentSearchesService, 'save');
+
+ wrapper.vm.handleFilterSubmit(mockFilters);
+
+ return wrapper.vm.recentSearchesPromise.then(() => {
+ expect(wrapper.vm.recentSearchesService.save).toHaveBeenCalledWith([
+ 'author_username:=@root foo',
+ ]);
+ });
+ });
+
+ it('emits component event `onFilter` with provided filters param', () => {
+ wrapper.vm.handleFilterSubmit(mockFilters);
+
+ expect(wrapper.emitted('onFilter')[0]).toEqual([mockFilters]);
+ });
+ });
+ });
+
+ describe('template', () => {
+ beforeEach(() => {
+ wrapper.setData({
+ selectedSortOption: mockSortOptions[0],
+ selectedSortDirection: SortDirection.descending,
+ });
+
+ return wrapper.vm.$nextTick();
+ });
+
+ it('renders gl-filtered-search component', () => {
+ const glFilteredSearchEl = wrapper.find(GlFilteredSearch);
+
+ expect(glFilteredSearchEl.props('placeholder')).toBe('Filter requirements');
+ expect(glFilteredSearchEl.props('availableTokens')).toEqual(mockAvailableTokens);
+ });
+
+ it('renders sort dropdown component', () => {
+ expect(wrapper.find(GlButtonGroup).exists()).toBe(true);
+ expect(wrapper.find(GlDropdown).exists()).toBe(true);
+ expect(wrapper.find(GlDropdown).props('text')).toBe(mockSortOptions[0].title);
+ });
+
+ it('renders dropdown items', () => {
+ const dropdownItemsEl = wrapper.findAll(GlDropdownItem);
+
+ expect(dropdownItemsEl).toHaveLength(mockSortOptions.length);
+ expect(dropdownItemsEl.at(0).text()).toBe(mockSortOptions[0].title);
+ expect(dropdownItemsEl.at(0).props('isChecked')).toBe(true);
+ expect(dropdownItemsEl.at(1).text()).toBe(mockSortOptions[1].title);
+ });
+
+ it('renders sort direction button', () => {
+ const sortButtonEl = wrapper.find(GlButton);
+
+ expect(sortButtonEl.attributes('title')).toBe('Sort direction: Descending');
+ expect(sortButtonEl.props('icon')).toBe('sort-highest');
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js b/spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js
new file mode 100644
index 00000000000..edc0f119262
--- /dev/null
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js
@@ -0,0 +1,64 @@
+import Api from '~/api';
+import AuthorToken from '~/vue_shared/components/filtered_search_bar/tokens/author_token.vue';
+
+export const mockAuthor1 = {
+ id: 1,
+ name: 'Administrator',
+ username: 'root',
+ state: 'active',
+ avatar_url: 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ web_url: 'http://0.0.0.0:3000/root',
+};
+
+export const mockAuthor2 = {
+ id: 2,
+ name: 'Claudio Beer',
+ username: 'ericka_terry',
+ state: 'active',
+ avatar_url: 'https://www.gravatar.com/avatar/12a89d115b5a398d5082897ebbcba9c2?s=80&d=identicon',
+ web_url: 'http://0.0.0.0:3000/ericka_terry',
+};
+
+export const mockAuthor3 = {
+ id: 6,
+ name: 'Shizue Hartmann',
+ username: 'junita.weimann',
+ state: 'active',
+ avatar_url: 'https://www.gravatar.com/avatar/9da1abb41b1d4c9c9e81030b71ea61a0?s=80&d=identicon',
+ web_url: 'http://0.0.0.0:3000/junita.weimann',
+};
+
+export const mockAuthors = [mockAuthor1, mockAuthor2, mockAuthor3];
+
+export const mockAuthorToken = {
+ type: 'author_username',
+ icon: 'user',
+ title: 'Author',
+ unique: false,
+ symbol: '@',
+ token: AuthorToken,
+ operators: [{ value: '=', description: 'is', default: 'true' }],
+ fetchPath: 'gitlab-org/gitlab-test',
+ fetchAuthors: Api.projectUsers.bind(Api),
+};
+
+export const mockAvailableTokens = [mockAuthorToken];
+
+export const mockSortOptions = [
+ {
+ id: 1,
+ title: 'Created date',
+ sortDirection: {
+ descending: 'created_desc',
+ ascending: 'created_asc',
+ },
+ },
+ {
+ id: 2,
+ title: 'Last updated',
+ sortDirection: {
+ descending: 'updated_desc',
+ ascending: 'updated_asc',
+ },
+ },
+];
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js
new file mode 100644
index 00000000000..3650ef79136
--- /dev/null
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js
@@ -0,0 +1,150 @@
+import { mount } from '@vue/test-utils';
+import { GlFilteredSearchToken, GlFilteredSearchTokenSegment } from '@gitlab/ui';
+import MockAdapter from 'axios-mock-adapter';
+import waitForPromises from 'helpers/wait_for_promises';
+import axios from '~/lib/utils/axios_utils';
+
+import createFlash from '~/flash';
+import AuthorToken from '~/vue_shared/components/filtered_search_bar/tokens/author_token.vue';
+
+import { mockAuthorToken, mockAuthors } from '../mock_data';
+
+jest.mock('~/flash');
+
+const createComponent = ({ config = mockAuthorToken, value = { data: '' } } = {}) =>
+ mount(AuthorToken, {
+ propsData: {
+ config,
+ value,
+ },
+ provide: {
+ portalName: 'fake target',
+ alignSuggestions: function fakeAlignSuggestions() {},
+ },
+ stubs: {
+ Portal: {
+ template: '<div><slot></slot></div>',
+ },
+ GlFilteredSearchSuggestionList: {
+ template: '<div></div>',
+ methods: {
+ getValue: () => '=',
+ },
+ },
+ },
+ });
+
+describe('AuthorToken', () => {
+ let mock;
+ let wrapper;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ wrapper = createComponent();
+ });
+
+ afterEach(() => {
+ mock.restore();
+ wrapper.destroy();
+ });
+
+ describe('computed', () => {
+ describe('currentValue', () => {
+ it('returns lowercase string for `value.data`', () => {
+ wrapper.setProps({
+ value: { data: 'FOO' },
+ });
+
+ return wrapper.vm.$nextTick(() => {
+ expect(wrapper.vm.currentValue).toBe('foo');
+ });
+ });
+ });
+
+ describe('activeAuthor', () => {
+ it('returns object for currently present `value.data`', () => {
+ wrapper.setData({
+ authors: mockAuthors,
+ });
+
+ wrapper.setProps({
+ value: { data: mockAuthors[0].username },
+ });
+
+ return wrapper.vm.$nextTick(() => {
+ expect(wrapper.vm.activeAuthor).toEqual(mockAuthors[0]);
+ });
+ });
+ });
+ });
+
+ describe('fetchAuthorBySearchTerm', () => {
+ it('calls `config.fetchAuthors` with provided searchTerm param', () => {
+ jest.spyOn(wrapper.vm.config, 'fetchAuthors');
+
+ wrapper.vm.fetchAuthorBySearchTerm(mockAuthors[0].username);
+
+ expect(wrapper.vm.config.fetchAuthors).toHaveBeenCalledWith(
+ mockAuthorToken.fetchPath,
+ mockAuthors[0].username,
+ );
+ });
+
+ it('sets response to `authors` when request is succesful', () => {
+ jest.spyOn(wrapper.vm.config, 'fetchAuthors').mockResolvedValue(mockAuthors);
+
+ wrapper.vm.fetchAuthorBySearchTerm('root');
+
+ return waitForPromises().then(() => {
+ expect(wrapper.vm.authors).toEqual(mockAuthors);
+ });
+ });
+
+ it('calls `createFlash` with flash error message when request fails', () => {
+ jest.spyOn(wrapper.vm.config, 'fetchAuthors').mockRejectedValue({});
+
+ wrapper.vm.fetchAuthorBySearchTerm('root');
+
+ return waitForPromises().then(() => {
+ expect(createFlash).toHaveBeenCalledWith('There was a problem fetching users.');
+ });
+ });
+
+ it('sets `loading` to false when request completes', () => {
+ jest.spyOn(wrapper.vm.config, 'fetchAuthors').mockRejectedValue({});
+
+ wrapper.vm.fetchAuthorBySearchTerm('root');
+
+ return waitForPromises().then(() => {
+ expect(wrapper.vm.loading).toBe(false);
+ });
+ });
+ });
+
+ describe('template', () => {
+ beforeEach(() => {
+ wrapper.setData({
+ authors: mockAuthors,
+ });
+
+ return wrapper.vm.$nextTick();
+ });
+
+ it('renders gl-filtered-search-token component', () => {
+ expect(wrapper.find(GlFilteredSearchToken).exists()).toBe(true);
+ });
+
+ it('renders token item when value is selected', () => {
+ wrapper.setProps({
+ value: { data: mockAuthors[0].username },
+ });
+
+ return wrapper.vm.$nextTick(() => {
+ const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+
+ expect(tokenSegments).toHaveLength(3); // Author, =, "Administrator"
+ expect(tokenSegments.at(2).text()).toBe(mockAuthors[0].name); // "Administrator"
+ });
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/components/icon_spec.js b/spec/frontend/vue_shared/components/icon_spec.js
new file mode 100644
index 00000000000..a448953cc8e
--- /dev/null
+++ b/spec/frontend/vue_shared/components/icon_spec.js
@@ -0,0 +1,78 @@
+import Vue from 'vue';
+import { mount } from '@vue/test-utils';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import Icon from '~/vue_shared/components/icon.vue';
+import iconsPath from '@gitlab/svgs/dist/icons.svg';
+
+jest.mock('@gitlab/svgs/dist/icons.svg', () => 'testing');
+
+describe('Sprite Icon Component', () => {
+ describe('Initialization', () => {
+ let icon;
+
+ beforeEach(() => {
+ const IconComponent = Vue.extend(Icon);
+
+ icon = mountComponent(IconComponent, {
+ name: 'commit',
+ size: 32,
+ });
+ });
+
+ afterEach(() => {
+ icon.$destroy();
+ });
+
+ it('should return a defined Vue component', () => {
+ expect(icon).toBeDefined();
+ });
+
+ it('should have <svg> as a child element', () => {
+ expect(icon.$el.tagName).toBe('svg');
+ });
+
+ it('should have <use> as a child element with the correct href', () => {
+ expect(icon.$el.firstChild.tagName).toBe('use');
+ expect(icon.$el.firstChild.getAttribute('xlink:href')).toBe(`${iconsPath}#commit`);
+ });
+
+ it('should properly compute iconSizeClass', () => {
+ expect(icon.iconSizeClass).toBe('s32');
+ });
+
+ it('forbids invalid size prop', () => {
+ expect(icon.$options.props.size.validator(NaN)).toBeFalsy();
+ expect(icon.$options.props.size.validator(0)).toBeFalsy();
+ expect(icon.$options.props.size.validator(9001)).toBeFalsy();
+ });
+
+ it('should properly render img css', () => {
+ const { classList } = icon.$el;
+ const containsSizeClass = classList.contains('s32');
+
+ expect(containsSizeClass).toBe(true);
+ });
+
+ it('`name` validator should return false for non existing icons', () => {
+ jest.spyOn(console, 'warn').mockImplementation();
+
+ expect(Icon.props.name.validator('non_existing_icon_sprite')).toBe(false);
+ });
+
+ it('`name` validator should return true for existing icons', () => {
+ expect(Icon.props.name.validator('commit')).toBe(true);
+ });
+ });
+
+ it('should call registered listeners when they are triggered', () => {
+ const clickHandler = jest.fn();
+ const wrapper = mount(Icon, {
+ propsData: { name: 'commit' },
+ listeners: { click: clickHandler },
+ });
+
+ wrapper.find('svg').trigger('click');
+
+ expect(clickHandler).toHaveBeenCalled();
+ });
+});
diff --git a/spec/frontend/vue_shared/components/issue/related_issuable_item_spec.js b/spec/frontend/vue_shared/components/issue/related_issuable_item_spec.js
index dd24ecf707d..9be0a67e4fa 100644
--- a/spec/frontend/vue_shared/components/issue/related_issuable_item_spec.js
+++ b/spec/frontend/vue_shared/components/issue/related_issuable_item_spec.js
@@ -6,6 +6,15 @@ import { defaultAssignees, defaultMilestone } from './related_issuable_mock_data
describe('RelatedIssuableItem', () => {
let wrapper;
+
+ function mountComponent({ mountMethod = mount, stubs = {}, props = {}, slots = {} } = {}) {
+ wrapper = mountMethod(RelatedIssuableItem, {
+ propsData: props,
+ slots,
+ stubs,
+ });
+ }
+
const props = {
idKey: 1,
displayReference: 'gitlab-org/gitlab-test#1',
@@ -26,10 +35,7 @@ describe('RelatedIssuableItem', () => {
};
beforeEach(() => {
- wrapper = mount(RelatedIssuableItem, {
- slots,
- propsData: props,
- });
+ mountComponent({ props, slots });
});
afterEach(() => {
diff --git a/spec/frontend/vue_shared/components/markdown/__snapshots__/suggestion_diff_spec.js.snap b/spec/frontend/vue_shared/components/markdown/__snapshots__/suggestion_diff_spec.js.snap
index 29ac754de49..cdd7a3ccaf0 100644
--- a/spec/frontend/vue_shared/components/markdown/__snapshots__/suggestion_diff_spec.js.snap
+++ b/spec/frontend/vue_shared/components/markdown/__snapshots__/suggestion_diff_spec.js.snap
@@ -5,8 +5,11 @@ exports[`Suggestion Diff component matches snapshot 1`] = `
class="md-suggestion"
>
<suggestion-diff-header-stub
+ batchsuggestionscount="1"
class="qa-suggestion-diff-header js-suggestion-diff-header"
helppagepath="path_to_docs"
+ isapplyingbatch="true"
+ isbatched="true"
/>
<table
diff --git a/spec/frontend/vue_shared/components/markdown/field_spec.js b/spec/frontend/vue_shared/components/markdown/field_spec.js
index 54ce1f47e28..74be5f8230e 100644
--- a/spec/frontend/vue_shared/components/markdown/field_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/field_spec.js
@@ -185,7 +185,7 @@ describe('Markdown field component', () => {
markdownButton.trigger('click');
return wrapper.vm.$nextTick(() => {
- expect(textarea.value).toContain('* testing');
+ expect(textarea.value).toContain('- testing');
});
});
@@ -197,7 +197,7 @@ describe('Markdown field component', () => {
markdownButton.trigger('click');
return wrapper.vm.$nextTick(() => {
- expect(textarea.value).toContain('* testing\n* 123');
+ expect(textarea.value).toContain('- testing\n- 123');
});
});
});
diff --git a/spec/frontend/vue_shared/components/markdown/suggestion_diff_header_spec.js b/spec/frontend/vue_shared/components/markdown/suggestion_diff_header_spec.js
index 9b9c3d559e3..9a5b95b555f 100644
--- a/spec/frontend/vue_shared/components/markdown/suggestion_diff_header_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/suggestion_diff_header_spec.js
@@ -3,20 +3,29 @@ import { shallowMount } from '@vue/test-utils';
import SuggestionDiffHeader from '~/vue_shared/components/markdown/suggestion_diff_header.vue';
const DEFAULT_PROPS = {
+ batchSuggestionsCount: 2,
canApply: true,
isApplied: false,
+ isBatched: false,
+ isApplyingBatch: false,
helpPagePath: 'path_to_docs',
};
describe('Suggestion Diff component', () => {
let wrapper;
- const createComponent = props => {
+ const createComponent = (props, glFeatures = {}) => {
wrapper = shallowMount(SuggestionDiffHeader, {
propsData: {
...DEFAULT_PROPS,
...props,
},
+ provide: {
+ glFeatures: {
+ batchSuggestions: true,
+ ...glFeatures,
+ },
+ },
});
};
@@ -25,6 +34,9 @@ describe('Suggestion Diff component', () => {
});
const findApplyButton = () => wrapper.find('.js-apply-btn');
+ const findApplyBatchButton = () => wrapper.find('.js-apply-batch-btn');
+ const findAddToBatchButton = () => wrapper.find('.js-add-to-batch-btn');
+ const findRemoveFromBatchButton = () => wrapper.find('.js-remove-from-batch-btn');
const findHeader = () => wrapper.find('.js-suggestion-diff-header');
const findHelpButton = () => wrapper.find('.js-help-btn');
const findLoading = () => wrapper.find(GlLoadingIcon);
@@ -44,19 +56,22 @@ describe('Suggestion Diff component', () => {
expect(findHelpButton().exists()).toBe(true);
});
- it('renders an apply button', () => {
+ it('renders apply suggestion and add to batch buttons', () => {
createComponent();
const applyBtn = findApplyButton();
+ const addToBatchBtn = findAddToBatchButton();
expect(applyBtn.exists()).toBe(true);
expect(applyBtn.html().includes('Apply suggestion')).toBe(true);
- });
- it('does not render an apply button if `canApply` is set to false', () => {
- createComponent({ canApply: false });
+ expect(addToBatchBtn.exists()).toBe(true);
+ expect(addToBatchBtn.html().includes('Add suggestion to batch')).toBe(true);
+ });
- expect(findApplyButton().exists()).toBe(false);
+ it('renders correct tooltip message for apply button', () => {
+ createComponent();
+ expect(wrapper.vm.tooltipMessage).toBe('This also resolves the discussion');
});
describe('when apply suggestion is clicked', () => {
@@ -73,13 +88,14 @@ describe('Suggestion Diff component', () => {
});
});
- it('hides apply button', () => {
+ it('does not render apply suggestion and add to batch buttons', () => {
expect(findApplyButton().exists()).toBe(false);
+ expect(findAddToBatchButton().exists()).toBe(false);
});
it('shows loading', () => {
expect(findLoading().exists()).toBe(true);
- expect(wrapper.text()).toContain('Applying suggestion');
+ expect(wrapper.text()).toContain('Applying suggestion...');
});
it('when callback of apply is called, hides loading', () => {
@@ -93,4 +109,135 @@ describe('Suggestion Diff component', () => {
});
});
});
+
+ describe('when add to batch is clicked', () => {
+ it('emits addToBatch', () => {
+ createComponent();
+
+ findAddToBatchButton().vm.$emit('click');
+
+ expect(wrapper.emittedByOrder()).toContainEqual({
+ name: 'addToBatch',
+ args: [],
+ });
+ });
+ });
+
+ describe('when remove from batch is clicked', () => {
+ it('emits removeFromBatch', () => {
+ createComponent({ isBatched: true });
+
+ findRemoveFromBatchButton().vm.$emit('click');
+
+ expect(wrapper.emittedByOrder()).toContainEqual({
+ name: 'removeFromBatch',
+ args: [],
+ });
+ });
+ });
+
+ describe('apply suggestions is clicked', () => {
+ it('emits applyBatch', () => {
+ createComponent({ isBatched: true });
+
+ findApplyBatchButton().vm.$emit('click');
+
+ expect(wrapper.emittedByOrder()).toContainEqual({
+ name: 'applyBatch',
+ args: [],
+ });
+ });
+ });
+
+ describe('when isBatched is true', () => {
+ it('shows remove from batch and apply batch buttons and displays the batch count', () => {
+ createComponent({
+ batchSuggestionsCount: 9,
+ isBatched: true,
+ });
+
+ const applyBatchBtn = findApplyBatchButton();
+ const removeFromBatchBtn = findRemoveFromBatchButton();
+
+ expect(removeFromBatchBtn.exists()).toBe(true);
+ expect(removeFromBatchBtn.html().includes('Remove from batch')).toBe(true);
+
+ expect(applyBatchBtn.exists()).toBe(true);
+ expect(applyBatchBtn.html().includes('Apply suggestions')).toBe(true);
+ expect(applyBatchBtn.html().includes(String('9'))).toBe(true);
+ });
+
+ it('hides add to batch and apply buttons', () => {
+ createComponent({
+ isBatched: true,
+ });
+
+ expect(findApplyButton().exists()).toBe(false);
+ expect(findAddToBatchButton().exists()).toBe(false);
+ });
+
+ describe('when isBatched and isApplyingBatch are true', () => {
+ it('shows loading', () => {
+ createComponent({
+ isBatched: true,
+ isApplyingBatch: true,
+ });
+
+ expect(findLoading().exists()).toBe(true);
+ expect(wrapper.text()).toContain('Applying suggestions...');
+ });
+
+ it('adjusts message for batch with single suggestion', () => {
+ createComponent({
+ batchSuggestionsCount: 1,
+ isBatched: true,
+ isApplyingBatch: true,
+ });
+
+ expect(findLoading().exists()).toBe(true);
+ expect(wrapper.text()).toContain('Applying suggestion...');
+ });
+
+ it('hides remove from batch and apply suggestions buttons', () => {
+ createComponent({
+ isBatched: true,
+ isApplyingBatch: true,
+ });
+
+ expect(findRemoveFromBatchButton().exists()).toBe(false);
+ expect(findApplyBatchButton().exists()).toBe(false);
+ });
+ });
+ });
+
+ describe('batchSuggestions feature flag is set to false', () => {
+ beforeEach(() => {
+ createComponent({}, { batchSuggestions: false });
+ });
+
+ it('disables add to batch buttons but keeps apply suggestion enabled', () => {
+ expect(findApplyButton().exists()).toBe(true);
+ expect(findAddToBatchButton().exists()).toBe(false);
+ expect(findApplyButton().attributes('disabled')).not.toBe('true');
+ });
+ });
+
+ describe('canApply is set to false', () => {
+ beforeEach(() => {
+ createComponent({ canApply: false });
+ });
+
+ it('disables apply suggestion and add to batch buttons', () => {
+ expect(findApplyButton().exists()).toBe(true);
+ expect(findAddToBatchButton().exists()).toBe(true);
+ expect(findApplyButton().attributes('disabled')).toBe('true');
+ expect(findAddToBatchButton().attributes('disabled')).toBe('true');
+ });
+
+ it('renders correct tooltip message for apply button', () => {
+ expect(wrapper.vm.tooltipMessage).toBe(
+ "Can't apply as this line has changed or the suggestion already matches its content.",
+ );
+ });
+ });
});
diff --git a/spec/frontend/vue_shared/components/markdown/suggestion_diff_spec.js b/spec/frontend/vue_shared/components/markdown/suggestion_diff_spec.js
index 162ac495385..232feb126dc 100644
--- a/spec/frontend/vue_shared/components/markdown/suggestion_diff_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/suggestion_diff_spec.js
@@ -3,9 +3,10 @@ import SuggestionDiffComponent from '~/vue_shared/components/markdown/suggestion
import SuggestionDiffHeader from '~/vue_shared/components/markdown/suggestion_diff_header.vue';
import SuggestionDiffRow from '~/vue_shared/components/markdown/suggestion_diff_row.vue';
+const suggestionId = 1;
const MOCK_DATA = {
suggestion: {
- id: 1,
+ id: suggestionId,
diff_lines: [
{
can_receive_suggestion: false,
@@ -38,8 +39,10 @@ const MOCK_DATA = {
type: 'new',
},
],
+ is_applying_batch: true,
},
helpPagePath: 'path_to_docs',
+ batchSuggestionsInfo: [{ suggestionId }],
};
describe('Suggestion Diff component', () => {
@@ -70,17 +73,24 @@ describe('Suggestion Diff component', () => {
expect(wrapper.findAll(SuggestionDiffRow)).toHaveLength(3);
});
- it('emits apply event on sugestion diff header apply', () => {
- wrapper.find(SuggestionDiffHeader).vm.$emit('apply', 'test-event');
+ it.each`
+ event | childArgs | args
+ ${'apply'} | ${['test-event']} | ${[{ callback: 'test-event', suggestionId }]}
+ ${'applyBatch'} | ${[]} | ${[]}
+ ${'addToBatch'} | ${[]} | ${[suggestionId]}
+ ${'removeFromBatch'} | ${[]} | ${[suggestionId]}
+ `('emits $event event on sugestion diff header $event', ({ event, childArgs, args }) => {
+ wrapper.find(SuggestionDiffHeader).vm.$emit(event, ...childArgs);
- expect(wrapper.emitted('apply')).toBeDefined();
- expect(wrapper.emitted('apply')).toEqual([
- [
- {
- callback: 'test-event',
- suggestionId: 1,
- },
- ],
- ]);
+ expect(wrapper.emitted(event)).toBeDefined();
+ expect(wrapper.emitted(event)).toEqual([args]);
+ });
+
+ it('passes suggestion batch props to suggestion diff header', () => {
+ expect(wrapper.find(SuggestionDiffHeader).props()).toMatchObject({
+ batchSuggestionsCount: 1,
+ isBatched: true,
+ isApplyingBatch: MOCK_DATA.suggestion.is_applying_batch,
+ });
});
});
diff --git a/spec/frontend/vue_shared/components/panel_resizer_spec.js b/spec/frontend/vue_shared/components/panel_resizer_spec.js
new file mode 100644
index 00000000000..d8b903e5bfd
--- /dev/null
+++ b/spec/frontend/vue_shared/components/panel_resizer_spec.js
@@ -0,0 +1,85 @@
+import Vue from 'vue';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import panelResizer from '~/vue_shared/components/panel_resizer.vue';
+
+describe('Panel Resizer component', () => {
+ let vm;
+ let PanelResizer;
+
+ const triggerEvent = (eventName, el = vm.$el, clientX = 0) => {
+ const event = document.createEvent('MouseEvents');
+ event.initMouseEvent(
+ eventName,
+ true,
+ true,
+ window,
+ 1,
+ clientX,
+ 0,
+ clientX,
+ 0,
+ false,
+ false,
+ false,
+ false,
+ 0,
+ null,
+ );
+
+ el.dispatchEvent(event);
+ };
+
+ beforeEach(() => {
+ PanelResizer = Vue.extend(panelResizer);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('should render a div element with the correct classes and styles', () => {
+ vm = mountComponent(PanelResizer, {
+ startSize: 100,
+ side: 'left',
+ });
+
+ expect(vm.$el.tagName).toEqual('DIV');
+ expect(vm.$el.getAttribute('class')).toBe(
+ 'position-absolute position-top-0 position-bottom-0 drag-handle position-left-0',
+ );
+
+ expect(vm.$el.getAttribute('style')).toBe('cursor: ew-resize;');
+ });
+
+ it('should render a div element with the correct classes for a right side panel', () => {
+ vm = mountComponent(PanelResizer, {
+ startSize: 100,
+ side: 'right',
+ });
+
+ expect(vm.$el.tagName).toEqual('DIV');
+ expect(vm.$el.getAttribute('class')).toBe(
+ 'position-absolute position-top-0 position-bottom-0 drag-handle position-right-0',
+ );
+ });
+
+ it('drag the resizer', () => {
+ vm = mountComponent(PanelResizer, {
+ startSize: 100,
+ side: 'left',
+ });
+
+ jest.spyOn(vm, '$emit').mockImplementation(() => {});
+ triggerEvent('mousedown', vm.$el);
+ triggerEvent('mousemove', document);
+ triggerEvent('mouseup', document);
+
+ expect(vm.$emit.mock.calls).toEqual([
+ ['resize-start', 100],
+ ['update:size', 100],
+ ['resize-end', 100],
+ ]);
+
+ expect(vm.size).toBe(100);
+ });
+});
diff --git a/spec/frontend/vue_shared/components/pikaday_spec.js b/spec/frontend/vue_shared/components/pikaday_spec.js
index 867bf88ff50..639b4828a09 100644
--- a/spec/frontend/vue_shared/components/pikaday_spec.js
+++ b/spec/frontend/vue_shared/components/pikaday_spec.js
@@ -1,30 +1,42 @@
-import Vue from 'vue';
-import mountComponent from 'helpers/vue_mount_component_helper';
+import { shallowMount } from '@vue/test-utils';
import datePicker from '~/vue_shared/components/pikaday.vue';
describe('datePicker', () => {
- let vm;
+ let wrapper;
beforeEach(() => {
- const DatePicker = Vue.extend(datePicker);
- vm = mountComponent(DatePicker, {
- label: 'label',
+ wrapper = shallowMount(datePicker, {
+ propsData: {
+ label: 'label',
+ },
+ attachToDocument: true,
});
});
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
it('should render label text', () => {
- expect(vm.$el.querySelector('.dropdown-toggle-text').innerText.trim()).toEqual('label');
+ expect(
+ wrapper
+ .find('.dropdown-toggle-text')
+ .text()
+ .trim(),
+ ).toEqual('label');
});
it('should show calendar', () => {
- expect(vm.$el.querySelector('.pika-single')).toBeDefined();
+ expect(wrapper.find('.pika-single').element).toBeDefined();
});
- it('should toggle when dropdown is clicked', () => {
- const hidePicker = jest.fn();
- vm.$on('hidePicker', hidePicker);
+ it('should emit hidePicker event when dropdown is clicked', () => {
+ // Removing the bootstrap data-toggle property,
+ // because it interfers with our click event
+ delete wrapper.find('.dropdown-menu-toggle').element.dataset.toggle;
- vm.$el.querySelector('.dropdown-menu-toggle').click();
+ wrapper.find('.dropdown-menu-toggle').trigger('click');
- expect(hidePicker).toHaveBeenCalled();
+ expect(wrapper.emitted('hidePicker')).toEqual([[]]);
});
});
diff --git a/spec/frontend/vue_shared/components/project_selector/project_selector_spec.js b/spec/frontend/vue_shared/components/project_selector/project_selector_spec.js
index 29bced394dc..6d1ebe85aa0 100644
--- a/spec/frontend/vue_shared/components/project_selector/project_selector_spec.js
+++ b/spec/frontend/vue_shared/components/project_selector/project_selector_spec.js
@@ -29,6 +29,7 @@ describe('ProjectSelector component', () => {
showMinimumSearchQueryMessage: false,
showLoadingIndicator: false,
showSearchErrorMessage: false,
+ totalResults: searchResults.length,
},
attachToDocument: true,
});
@@ -109,4 +110,26 @@ describe('ProjectSelector component', () => {
);
});
});
+
+ describe('the search results legend', () => {
+ it.each`
+ count | total | expected
+ ${0} | ${0} | ${'Showing 0 projects'}
+ ${1} | ${0} | ${'Showing 1 project'}
+ ${2} | ${0} | ${'Showing 2 projects'}
+ ${2} | ${3} | ${'Showing 2 of 3 projects'}
+ `(
+ 'is "$expected" given $count results are showing out of $total',
+ ({ count, total, expected }) => {
+ wrapper.setProps({
+ projectSearchResults: searchResults.slice(0, count),
+ totalResults: total,
+ });
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.text()).toContain(expected);
+ });
+ },
+ );
+ });
});
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/editor_service_spec.js b/spec/frontend/vue_shared/components/rich_content_editor/editor_service_spec.js
new file mode 100644
index 00000000000..faa32131fab
--- /dev/null
+++ b/spec/frontend/vue_shared/components/rich_content_editor/editor_service_spec.js
@@ -0,0 +1,77 @@
+import {
+ generateToolbarItem,
+ addCustomEventListener,
+ removeCustomEventListener,
+ addImage,
+ getMarkdown,
+} from '~/vue_shared/components/rich_content_editor/editor_service';
+
+describe('Editor Service', () => {
+ const mockInstance = {
+ eventManager: { addEventType: jest.fn(), removeEventHandler: jest.fn(), listen: jest.fn() },
+ editor: { exec: jest.fn() },
+ invoke: jest.fn(),
+ };
+ const event = 'someCustomEvent';
+ const handler = jest.fn();
+
+ describe('generateToolbarItem', () => {
+ const config = {
+ icon: 'bold',
+ command: 'some-command',
+ tooltip: 'Some Tooltip',
+ event: 'some-event',
+ };
+
+ const generatedItem = generateToolbarItem(config);
+
+ it('generates the correct command', () => {
+ expect(generatedItem.options.command).toBe(config.command);
+ });
+
+ it('generates the correct event', () => {
+ expect(generatedItem.options.event).toBe(config.event);
+ });
+
+ it('generates a divider when isDivider is set to true', () => {
+ const isDivider = true;
+
+ expect(generateToolbarItem({ isDivider })).toBe('divider');
+ });
+ });
+
+ describe('addCustomEventListener', () => {
+ it('registers an event type on the instance and adds an event handler', () => {
+ addCustomEventListener(mockInstance, event, handler);
+
+ expect(mockInstance.eventManager.addEventType).toHaveBeenCalledWith(event);
+ expect(mockInstance.eventManager.listen).toHaveBeenCalledWith(event, handler);
+ });
+ });
+
+ describe('removeCustomEventListener', () => {
+ it('removes an event handler from the instance', () => {
+ removeCustomEventListener(mockInstance, event, handler);
+
+ expect(mockInstance.eventManager.removeEventHandler).toHaveBeenCalledWith(event, handler);
+ });
+ });
+
+ describe('addImage', () => {
+ it('calls the exec method on the instance', () => {
+ const mockImage = { imageUrl: 'some/url.png', description: 'some description' };
+
+ addImage(mockInstance, mockImage);
+
+ expect(mockInstance.editor.exec).toHaveBeenCalledWith('AddImage', mockImage);
+ });
+ });
+
+ describe('getMarkdown', () => {
+ it('calls the invoke method on the instance', () => {
+ getMarkdown(mockInstance);
+
+ expect(mockInstance.invoke).toHaveBeenCalledWith('getMarkdown');
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/modals/add_image_modal_spec.js b/spec/frontend/vue_shared/components/rich_content_editor/modals/add_image_modal_spec.js
new file mode 100644
index 00000000000..4889bc8538d
--- /dev/null
+++ b/spec/frontend/vue_shared/components/rich_content_editor/modals/add_image_modal_spec.js
@@ -0,0 +1,41 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlModal } from '@gitlab/ui';
+import AddImageModal from '~/vue_shared/components/rich_content_editor/modals/add_image_modal.vue';
+
+describe('Add Image Modal', () => {
+ let wrapper;
+
+ const findModal = () => wrapper.find(GlModal);
+ const findUrlInput = () => wrapper.find({ ref: 'urlInput' });
+ const findDescriptionInput = () => wrapper.find({ ref: 'descriptionInput' });
+
+ beforeEach(() => {
+ wrapper = shallowMount(AddImageModal);
+ });
+
+ describe('when content is loaded', () => {
+ it('renders a modal component', () => {
+ expect(findModal().exists()).toBe(true);
+ });
+
+ it('renders an input to add an image URL', () => {
+ expect(findUrlInput().exists()).toBe(true);
+ });
+
+ it('renders an input to add an image description', () => {
+ expect(findDescriptionInput().exists()).toBe(true);
+ });
+ });
+
+ describe('add image', () => {
+ it('emits an addImage event when a valid URL is specified', () => {
+ const preventDefault = jest.fn();
+ const mockImage = { imageUrl: '/some/valid/url.png', altText: 'some description' };
+ wrapper.setData({ ...mockImage });
+
+ findModal().vm.$emit('ok', { preventDefault });
+ expect(preventDefault).not.toHaveBeenCalled();
+ expect(wrapper.emitted('addImage')).toEqual([[mockImage]]);
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/rich_content_editor_spec.js b/spec/frontend/vue_shared/components/rich_content_editor/rich_content_editor_spec.js
index 549d89171c6..0db10389df4 100644
--- a/spec/frontend/vue_shared/components/rich_content_editor/rich_content_editor_spec.js
+++ b/spec/frontend/vue_shared/components/rich_content_editor/rich_content_editor_spec.js
@@ -1,17 +1,33 @@
import { shallowMount } from '@vue/test-utils';
import RichContentEditor from '~/vue_shared/components/rich_content_editor/rich_content_editor.vue';
+import AddImageModal from '~/vue_shared/components/rich_content_editor/modals/add_image_modal.vue';
import {
EDITOR_OPTIONS,
EDITOR_TYPES,
EDITOR_HEIGHT,
EDITOR_PREVIEW_STYLE,
+ CUSTOM_EVENTS,
} from '~/vue_shared/components/rich_content_editor/constants';
+import {
+ addCustomEventListener,
+ removeCustomEventListener,
+ addImage,
+} from '~/vue_shared/components/rich_content_editor/editor_service';
+
+jest.mock('~/vue_shared/components/rich_content_editor/editor_service', () => ({
+ ...jest.requireActual('~/vue_shared/components/rich_content_editor/editor_service'),
+ addCustomEventListener: jest.fn(),
+ removeCustomEventListener: jest.fn(),
+ addImage: jest.fn(),
+}));
+
describe('Rich Content Editor', () => {
let wrapper;
const value = '## Some Markdown';
const findEditor = () => wrapper.find({ ref: 'editor' });
+ const findAddImageModal = () => wrapper.find(AddImageModal);
beforeEach(() => {
wrapper = shallowMount(RichContentEditor, {
@@ -56,4 +72,47 @@ describe('Rich Content Editor', () => {
expect(wrapper.emitted().input[0][0]).toBe(changedMarkdown);
});
});
+
+ describe('when editor is loaded', () => {
+ it('adds the CUSTOM_EVENTS.openAddImageModal custom event listener', () => {
+ const mockEditorApi = { eventManager: { addEventType: jest.fn(), listen: jest.fn() } };
+ findEditor().vm.$emit('load', mockEditorApi);
+
+ expect(addCustomEventListener).toHaveBeenCalledWith(
+ mockEditorApi,
+ CUSTOM_EVENTS.openAddImageModal,
+ wrapper.vm.onOpenAddImageModal,
+ );
+ });
+ });
+
+ describe('when editor is destroyed', () => {
+ it('removes the CUSTOM_EVENTS.openAddImageModal custom event listener', () => {
+ const mockEditorApi = { eventManager: { removeEventHandler: jest.fn() } };
+
+ wrapper.vm.editorApi = mockEditorApi;
+ wrapper.vm.$destroy();
+
+ expect(removeCustomEventListener).toHaveBeenCalledWith(
+ mockEditorApi,
+ CUSTOM_EVENTS.openAddImageModal,
+ wrapper.vm.onOpenAddImageModal,
+ );
+ });
+ });
+
+ describe('add image modal', () => {
+ it('renders an addImageModal component', () => {
+ expect(findAddImageModal().exists()).toBe(true);
+ });
+
+ it('calls the onAddImage method when the addImage event is emitted', () => {
+ const mockImage = { imageUrl: 'some/url.png', description: 'some description' };
+ const mockInstance = { exec: jest.fn() };
+ wrapper.vm.$refs.editor = mockInstance;
+
+ findAddImageModal().vm.$emit('addImage', mockImage);
+ expect(addImage).toHaveBeenCalledWith(mockInstance, mockImage);
+ });
+ });
});
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/toolbar_item_spec.js b/spec/frontend/vue_shared/components/rich_content_editor/toolbar_item_spec.js
index 8545c43dc1e..2db15a71215 100644
--- a/spec/frontend/vue_shared/components/rich_content_editor/toolbar_item_spec.js
+++ b/spec/frontend/vue_shared/components/rich_content_editor/toolbar_item_spec.js
@@ -1,4 +1,5 @@
import { shallowMount } from '@vue/test-utils';
+import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { GlIcon } from '@gitlab/ui';
import ToolbarItem from '~/vue_shared/components/rich_content_editor/toolbar_item.vue';
@@ -9,33 +10,45 @@ describe('Toolbar Item', () => {
const findButton = () => wrapper.find('button');
const buildWrapper = propsData => {
- wrapper = shallowMount(ToolbarItem, { propsData });
+ wrapper = shallowMount(ToolbarItem, {
+ propsData,
+ directives: {
+ GlTooltip: createMockDirective(),
+ },
+ });
};
describe.each`
- icon
- ${'heading'}
- ${'bold'}
- ${'italic'}
- ${'strikethrough'}
- ${'quote'}
- ${'link'}
- ${'doc-code'}
- ${'list-bulleted'}
- ${'list-numbered'}
- ${'list-task'}
- ${'list-indent'}
- ${'list-outdent'}
- ${'dash'}
- ${'table'}
- ${'code'}
- `('toolbar item component', ({ icon }) => {
- beforeEach(() => buildWrapper({ icon }));
+ icon | tooltip
+ ${'heading'} | ${'Headings'}
+ ${'bold'} | ${'Add bold text'}
+ ${'italic'} | ${'Add italic text'}
+ ${'strikethrough'} | ${'Add strikethrough text'}
+ ${'quote'} | ${'Insert a quote'}
+ ${'link'} | ${'Add a link'}
+ ${'doc-code'} | ${'Insert a code block'}
+ ${'list-bulleted'} | ${'Add a bullet list'}
+ ${'list-numbered'} | ${'Add a numbered list'}
+ ${'list-task'} | ${'Add a task list'}
+ ${'list-indent'} | ${'Indent'}
+ ${'list-outdent'} | ${'Outdent'}
+ ${'dash'} | ${'Add a line'}
+ ${'table'} | ${'Add a table'}
+ ${'code'} | ${'Insert an image'}
+ ${'code'} | ${'Insert inline code'}
+ `('toolbar item component', ({ icon, tooltip }) => {
+ beforeEach(() => buildWrapper({ icon, tooltip }));
it('renders a toolbar button', () => {
expect(findButton().exists()).toBe(true);
});
+ it('renders the correct tooltip', () => {
+ const buttonTooltip = getBinding(wrapper.element, 'gl-tooltip');
+ expect(buttonTooltip).toBeDefined();
+ expect(buttonTooltip.value.title).toBe(tooltip);
+ });
+
it(`renders the ${icon} icon`, () => {
expect(findIcon().exists()).toBe(true);
expect(findIcon().props().name).toBe(icon);
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/toolbar_service_spec.js b/spec/frontend/vue_shared/components/rich_content_editor/toolbar_service_spec.js
deleted file mode 100644
index 7605cc6a22c..00000000000
--- a/spec/frontend/vue_shared/components/rich_content_editor/toolbar_service_spec.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import { generateToolbarItem } from '~/vue_shared/components/rich_content_editor/toolbar_service';
-
-describe('Toolbar Service', () => {
- const config = {
- icon: 'bold',
- command: 'some-command',
- tooltip: 'Some Tooltip',
- event: 'some-event',
- };
- const generatedItem = generateToolbarItem(config);
-
- it('generates the correct command', () => {
- expect(generatedItem.options.command).toBe(config.command);
- });
-
- it('generates the correct tooltip', () => {
- expect(generatedItem.options.tooltip).toBe(config.tooltip);
- });
-
- it('generates the correct event', () => {
- expect(generatedItem.options.event).toBe(config.event);
- });
-
- it('generates a divider when isDivider is set to true', () => {
- const isDivider = true;
-
- expect(generateToolbarItem({ isDivider })).toBe('divider');
- });
-});
diff --git a/spec/frontend/vue_shared/components/sidebar/date_picker_spec.js b/spec/frontend/vue_shared/components/sidebar/date_picker_spec.js
index 198af09c9f5..47edfbe3115 100644
--- a/spec/frontend/vue_shared/components/sidebar/date_picker_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/date_picker_spec.js
@@ -1,121 +1,149 @@
-import Vue from 'vue';
-import mountComponent from 'helpers/vue_mount_component_helper';
-import sidebarDatePicker from '~/vue_shared/components/sidebar/date_picker.vue';
-
-describe('sidebarDatePicker', () => {
- let vm;
- beforeEach(() => {
- const SidebarDatePicker = Vue.extend(sidebarDatePicker);
- vm = mountComponent(SidebarDatePicker, {
- label: 'label',
- isLoading: true,
+import { mount } from '@vue/test-utils';
+import SidebarDatePicker from '~/vue_shared/components/sidebar/date_picker.vue';
+import DatePicker from '~/vue_shared/components/pikaday.vue';
+
+describe('SidebarDatePicker', () => {
+ let wrapper;
+
+ const mountComponent = (propsData = {}, data = {}) => {
+ if (wrapper) {
+ throw new Error('tried to call mountComponent without d');
+ }
+ wrapper = mount(SidebarDatePicker, {
+ stubs: {
+ DatePicker: true,
+ },
+ propsData,
+ data: () => data,
});
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
});
it('should emit toggleCollapse when collapsed toggle sidebar is clicked', () => {
- const toggleCollapse = jest.fn();
- vm.$on('toggleCollapse', toggleCollapse);
+ mountComponent();
- vm.$el.querySelector('.issuable-sidebar-header .gutter-toggle').click();
+ wrapper.find('.issuable-sidebar-header .gutter-toggle').element.click();
- expect(toggleCollapse).toHaveBeenCalled();
+ expect(wrapper.emitted('toggleCollapse')).toEqual([[]]);
});
it('should render collapsed-calendar-icon', () => {
- expect(vm.$el.querySelector('.sidebar-collapsed-icon')).toBeDefined();
+ mountComponent();
+
+ expect(wrapper.find('.sidebar-collapsed-icon').element).toBeDefined();
});
- it('should render label', () => {
- expect(vm.$el.querySelector('.title').innerText.trim()).toEqual('label');
+ it('should render value when not editing', () => {
+ mountComponent();
+
+ expect(wrapper.find('.value-content').element).toBeDefined();
});
- it('should render loading-icon when isLoading', () => {
- expect(vm.$el.querySelector('.fa-spin')).toBeDefined();
+ it('should render None if there is no selectedDate', () => {
+ mountComponent();
+
+ expect(
+ wrapper
+ .find('.value-content span')
+ .text()
+ .trim(),
+ ).toEqual('None');
});
- it('should render value when not editing', () => {
- expect(vm.$el.querySelector('.value-content')).toBeDefined();
+ it('should render date-picker when editing', () => {
+ mountComponent({}, { editing: true });
+
+ expect(wrapper.find(DatePicker).element).toBeDefined();
});
- it('should render None if there is no selectedDate', () => {
- expect(vm.$el.querySelector('.value-content span').innerText.trim()).toEqual('None');
+ it('should render label', () => {
+ const label = 'label';
+ mountComponent({ label });
+ expect(
+ wrapper
+ .find('.title')
+ .text()
+ .trim(),
+ ).toEqual(label);
});
- it('should render date-picker when editing', done => {
- vm.editing = true;
- Vue.nextTick(() => {
- expect(vm.$el.querySelector('.pika-label')).toBeDefined();
- done();
- });
+ it('should render loading-icon when isLoading', () => {
+ mountComponent({ isLoading: true });
+ expect(wrapper.find('.gl-spinner').element).toBeDefined();
});
describe('editable', () => {
- beforeEach(done => {
- vm.editable = true;
- Vue.nextTick(done);
+ beforeEach(() => {
+ mountComponent({ editable: true });
});
it('should render edit button', () => {
- expect(vm.$el.querySelector('.title .btn-blank').innerText.trim()).toEqual('Edit');
+ expect(
+ wrapper
+ .find('.title .btn-blank')
+ .text()
+ .trim(),
+ ).toEqual('Edit');
});
- it('should enable editing when edit button is clicked', done => {
- vm.isLoading = false;
- Vue.nextTick(() => {
- vm.$el.querySelector('.title .btn-blank').click();
+ it('should enable editing when edit button is clicked', async () => {
+ wrapper.find('.title .btn-blank').element.click();
+
+ await wrapper.vm.$nextTick();
- expect(vm.editing).toEqual(true);
- done();
- });
+ expect(wrapper.vm.editing).toEqual(true);
});
});
- it('should render date if selectedDate', done => {
- vm.selectedDate = new Date('07/07/2017');
- Vue.nextTick(() => {
- expect(vm.$el.querySelector('.value-content strong').innerText.trim()).toEqual('Jul 7, 2017');
- done();
- });
+ it('should render date if selectedDate', () => {
+ mountComponent({ selectedDate: new Date('07/07/2017') });
+
+ expect(
+ wrapper
+ .find('.value-content strong')
+ .text()
+ .trim(),
+ ).toEqual('Jul 7, 2017');
});
describe('selectedDate and editable', () => {
- beforeEach(done => {
- vm.selectedDate = new Date('07/07/2017');
- vm.editable = true;
- Vue.nextTick(done);
+ beforeEach(() => {
+ mountComponent({ selectedDate: new Date('07/07/2017'), editable: true });
});
it('should render remove button if selectedDate and editable', () => {
- expect(vm.$el.querySelector('.value-content .btn-blank').innerText.trim()).toEqual('remove');
+ expect(
+ wrapper
+ .find('.value-content .btn-blank')
+ .text()
+ .trim(),
+ ).toEqual('remove');
});
- it('should emit saveDate when remove button is clicked', () => {
- const saveDate = jest.fn();
- vm.$on('saveDate', saveDate);
+ it('should emit saveDate with null when remove button is clicked', () => {
+ wrapper.find('.value-content .btn-blank').element.click();
- vm.$el.querySelector('.value-content .btn-blank').click();
-
- expect(saveDate).toHaveBeenCalled();
+ expect(wrapper.emitted('saveDate')).toEqual([[null]]);
});
});
describe('showToggleSidebar', () => {
- beforeEach(done => {
- vm.showToggleSidebar = true;
- Vue.nextTick(done);
+ beforeEach(() => {
+ mountComponent({ showToggleSidebar: true });
});
it('should render toggle-sidebar when showToggleSidebar', () => {
- expect(vm.$el.querySelector('.title .gutter-toggle')).toBeDefined();
+ expect(wrapper.find('.title .gutter-toggle').element).toBeDefined();
});
it('should emit toggleCollapse when toggle sidebar is clicked', () => {
- const toggleCollapse = jest.fn();
- vm.$on('toggleCollapse', toggleCollapse);
-
- vm.$el.querySelector('.title .gutter-toggle').click();
+ wrapper.find('.title .gutter-toggle').element.click();
- expect(toggleCollapse).toHaveBeenCalled();
+ expect(wrapper.emitted('toggleCollapse')).toEqual([[]]);
});
});
});
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 74c769f86a3..1504e1521d3 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
@@ -3,6 +3,7 @@ import { shallowMount, createLocalVue } from '@vue/test-utils';
import { GlButton, GlLoadingIcon, GlSearchBoxByType, GlLink } from '@gitlab/ui';
import { UP_KEY_CODE, DOWN_KEY_CODE, ENTER_KEY_CODE, ESC_KEY_CODE } from '~/lib/utils/keycodes';
+import SmartVirtualList from '~/vue_shared/components/smart_virtual_list.vue';
import DropdownContentsLabelsView from '~/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue';
import LabelItem from '~/vue_shared/components/sidebar/labels_select_vue/label_item.vue';
@@ -224,6 +225,10 @@ describe('DropdownContentsLabelsView', () => {
expect(searchInputEl.attributes('autofocus')).toBe('true');
});
+ it('renders smart-virtual-list element', () => {
+ expect(wrapper.find(SmartVirtualList).exists()).toBe(true);
+ });
+
it('renders label elements for all labels', () => {
expect(wrapper.findAll(LabelItem)).toHaveLength(mockLabels.length);
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/label_item_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/label_item_spec.js
index 401d208da5c..ad3f073fdf9 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/label_item_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/label_item_spec.js
@@ -4,10 +4,13 @@ import { GlIcon, GlLink } from '@gitlab/ui';
import LabelItem from '~/vue_shared/components/sidebar/labels_select_vue/label_item.vue';
import { mockRegularLabel } from './mock_data';
-const createComponent = ({ label = mockRegularLabel, highlight = true } = {}) =>
+const mockLabel = { ...mockRegularLabel, set: true };
+
+const createComponent = ({ label = mockLabel, highlight = true } = {}) =>
shallowMount(LabelItem, {
propsData: {
label,
+ isLabelSet: label.set,
highlight,
},
});
@@ -28,13 +31,29 @@ describe('LabelItem', () => {
it('returns an object containing `backgroundColor` based on `label` prop', () => {
expect(wrapper.vm.labelBoxStyle).toEqual(
expect.objectContaining({
- backgroundColor: mockRegularLabel.color,
+ backgroundColor: mockLabel.color,
}),
);
});
});
});
+ describe('watchers', () => {
+ describe('isLabelSet', () => {
+ it('sets value of `isLabelSet` to `isSet` data prop', () => {
+ expect(wrapper.vm.isSet).toBe(true);
+
+ wrapper.setProps({
+ isLabelSet: false,
+ });
+
+ return wrapper.vm.$nextTick(() => {
+ expect(wrapper.vm.isSet).toBe(false);
+ });
+ });
+ });
+ });
+
describe('methods', () => {
describe('handleClick', () => {
it('sets value of `isSet` data prop to opposite of its current value', () => {
@@ -52,7 +71,7 @@ describe('LabelItem', () => {
wrapper.vm.handleClick();
expect(wrapper.emitted('clickLabel')).toBeTruthy();
- expect(wrapper.emitted('clickLabel')[0]).toEqual([mockRegularLabel]);
+ expect(wrapper.emitted('clickLabel')[0]).toEqual([mockLabel]);
});
});
});
@@ -105,7 +124,7 @@ describe('LabelItem', () => {
});
it('renders label title', () => {
- expect(wrapper.text()).toContain(mockRegularLabel.title);
+ expect(wrapper.text()).toContain(mockLabel.title);
});
});
});
diff --git a/spec/frontend/vue_shared/components/smart_virtual_list_spec.js b/spec/frontend/vue_shared/components/smart_virtual_list_spec.js
new file mode 100644
index 00000000000..e5f9b94128e
--- /dev/null
+++ b/spec/frontend/vue_shared/components/smart_virtual_list_spec.js
@@ -0,0 +1,83 @@
+import Vue from 'vue';
+import { mount } from '@vue/test-utils';
+import SmartVirtualScrollList from '~/vue_shared/components/smart_virtual_list.vue';
+
+describe('Toggle Button', () => {
+ let vm;
+
+ const createComponent = ({ length, remain }) => {
+ const smartListProperties = {
+ rtag: 'section',
+ wtag: 'ul',
+ wclass: 'test-class',
+ // Size in pixels does not matter for our tests here
+ size: 35,
+ length,
+ remain,
+ };
+
+ const Component = Vue.extend({
+ components: {
+ SmartVirtualScrollList,
+ },
+ smartListProperties,
+ items: Array(length).fill(1),
+ template: `
+ <smart-virtual-scroll-list v-bind="$options.smartListProperties">
+ <li v-for="(val, key) in $options.items" :key="key">{{ key + 1 }}</li>
+ </smart-virtual-scroll-list>`,
+ });
+
+ return mount(Component).vm;
+ };
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('if the list is shorter than the maximum shown elements', () => {
+ const listLength = 10;
+
+ beforeEach(() => {
+ vm = createComponent({ length: listLength, remain: 20 });
+ });
+
+ it('renders without the vue-virtual-scroll-list component', () => {
+ expect(vm.$el.classList).not.toContain('js-virtual-list');
+ expect(vm.$el.classList).toContain('js-plain-element');
+ });
+
+ it('renders list with provided tags and classes for the wrapper elements', () => {
+ expect(vm.$el.tagName).toEqual('SECTION');
+ expect(vm.$el.firstChild.tagName).toEqual('UL');
+ expect(vm.$el.firstChild.classList).toContain('test-class');
+ });
+
+ it('renders all children list elements', () => {
+ expect(vm.$el.querySelectorAll('li').length).toEqual(listLength);
+ });
+ });
+
+ describe('if the list is longer than the maximum shown elements', () => {
+ const maxItemsShown = 20;
+
+ beforeEach(() => {
+ vm = createComponent({ length: 1000, remain: maxItemsShown });
+ });
+
+ it('uses the vue-virtual-scroll-list component', () => {
+ expect(vm.$el.classList).toContain('js-virtual-list');
+ expect(vm.$el.classList).not.toContain('js-plain-element');
+ });
+
+ it('renders list with provided tags and classes for the wrapper elements', () => {
+ expect(vm.$el.tagName).toEqual('SECTION');
+ expect(vm.$el.firstChild.tagName).toEqual('UL');
+ expect(vm.$el.firstChild.classList).toContain('test-class');
+ });
+
+ it('renders at max twice the maximum shown elements', () => {
+ expect(vm.$el.querySelectorAll('li').length).toBeLessThanOrEqual(2 * maxItemsShown);
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/directives/autofocusonshow_spec.js b/spec/frontend/vue_shared/directives/autofocusonshow_spec.js
new file mode 100644
index 00000000000..90530b7d5c2
--- /dev/null
+++ b/spec/frontend/vue_shared/directives/autofocusonshow_spec.js
@@ -0,0 +1,46 @@
+import autofocusonshow from '~/vue_shared/directives/autofocusonshow';
+
+/**
+ * We're testing this directive's hooks as pure functions
+ * since behaviour of this directive is highly-dependent
+ * on underlying DOM methods.
+ */
+describe('AutofocusOnShow directive', () => {
+ describe('with input invisible on component render', () => {
+ let el;
+
+ beforeEach(() => {
+ setFixtures('<div id="container" style="display: none;"><input id="inputel"/></div>');
+ el = document.querySelector('#inputel');
+
+ window.IntersectionObserver = class {
+ observe = jest.fn();
+ };
+ });
+
+ afterEach(() => {
+ delete window.IntersectionObserver;
+ });
+
+ it('should bind IntersectionObserver on input element', () => {
+ jest.spyOn(el, 'focus').mockImplementation(() => {});
+
+ autofocusonshow.inserted(el);
+
+ expect(el.visibilityObserver).toBeDefined();
+ expect(el.focus).not.toHaveBeenCalled();
+ });
+
+ it('should stop IntersectionObserver on input element on unbind hook', () => {
+ el.visibilityObserver = {
+ disconnect: () => {},
+ };
+ jest.spyOn(el.visibilityObserver, 'disconnect').mockImplementation(() => {});
+
+ autofocusonshow.unbind(el);
+
+ expect(el.visibilityObserver).toBeDefined();
+ expect(el.visibilityObserver.disconnect).toHaveBeenCalled();
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/directives/tooltip_spec.js b/spec/frontend/vue_shared/directives/tooltip_spec.js
new file mode 100644
index 00000000000..9d3dd3c5f75
--- /dev/null
+++ b/spec/frontend/vue_shared/directives/tooltip_spec.js
@@ -0,0 +1,98 @@
+import $ from 'jquery';
+import { mount } from '@vue/test-utils';
+import tooltip from '~/vue_shared/directives/tooltip';
+
+describe('Tooltip directive', () => {
+ let vm;
+
+ afterEach(() => {
+ if (vm) {
+ vm.$destroy();
+ }
+ });
+
+ describe('with a single tooltip', () => {
+ beforeEach(() => {
+ const wrapper = mount(
+ {
+ directives: {
+ tooltip,
+ },
+ data() {
+ return {
+ tooltip: 'some text',
+ };
+ },
+ template: '<div v-tooltip :title="tooltip"></div>',
+ },
+ { attachToDocument: true },
+ );
+
+ vm = wrapper.vm;
+ });
+
+ it('should have tooltip plugin applied', () => {
+ expect($(vm.$el).data('bs.tooltip')).toBeDefined();
+ });
+
+ it('displays the title as tooltip', () => {
+ $(vm.$el).tooltip('show');
+ jest.runOnlyPendingTimers();
+
+ const tooltipElement = document.querySelector('.tooltip-inner');
+
+ expect(tooltipElement.textContent).toContain('some text');
+ });
+
+ it('updates a visible tooltip', () => {
+ $(vm.$el).tooltip('show');
+ jest.runOnlyPendingTimers();
+
+ const tooltipElement = document.querySelector('.tooltip-inner');
+
+ vm.tooltip = 'other text';
+
+ jest.runOnlyPendingTimers();
+
+ return vm.$nextTick().then(() => {
+ expect(tooltipElement.textContent).toContain('other text');
+ });
+ });
+ });
+
+ describe('with multiple tooltips', () => {
+ beforeEach(() => {
+ const wrapper = mount(
+ {
+ directives: {
+ tooltip,
+ },
+ template: `
+ <div>
+ <div
+ v-tooltip
+ class="js-look-for-tooltip"
+ title="foo">
+ </div>
+ <div
+ v-tooltip
+ title="bar">
+ </div>
+ </div>
+ `,
+ },
+ { attachToDocument: true },
+ );
+
+ vm = wrapper.vm;
+ });
+
+ it('should have tooltip plugin applied to all instances', () => {
+ expect(
+ $(vm.$el)
+ .find('.js-look-for-tooltip')
+ .data('bs.tooltip'),
+ ).toBeDefined();
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/translate_spec.js b/spec/frontend/vue_shared/translate_spec.js
new file mode 100644
index 00000000000..42aa28a6309
--- /dev/null
+++ b/spec/frontend/vue_shared/translate_spec.js
@@ -0,0 +1,214 @@
+import { mount, createLocalVue } from '@vue/test-utils';
+import locale from '~/locale';
+import Translate from '~/vue_shared/translate';
+
+const localVue = createLocalVue();
+localVue.use(Translate);
+
+describe('Vue translate filter', () => {
+ const createTranslationMock = (key, ...translations) => {
+ locale.textdomain('app');
+
+ locale.options.locale_data = {
+ app: {
+ '': {
+ domain: 'app',
+ lang: 'vo',
+ plural_forms: 'nplurals=2; plural=(n != 1);',
+ },
+ [key]: translations,
+ },
+ };
+ };
+
+ it('translate singular text (`__`)', () => {
+ const key = 'singular';
+ const translation = 'singular_translated';
+ createTranslationMock(key, translation);
+
+ const wrapper = mount(
+ {
+ template: `
+ <span>
+ {{ __('${key}') }}
+ </span>
+ `,
+ },
+ { localVue },
+ );
+
+ expect(wrapper.text()).toBe(translation);
+ });
+
+ it('translate plural text (`n__`) without any substituting text', () => {
+ const key = 'plural';
+ const translationPlural = 'plural_multiple translation';
+ createTranslationMock(key, 'plural_singular translation', translationPlural);
+
+ const wrapper = mount(
+ {
+ template: `
+ <span>
+ {{ n__('${key}', 'plurals', 2) }}
+ </span>
+ `,
+ },
+ { localVue },
+ );
+
+ expect(wrapper.text()).toBe(translationPlural);
+ });
+
+ describe('translate plural text (`n__`) with substituting %d', () => {
+ const key = '%d day';
+
+ beforeEach(() => {
+ createTranslationMock(key, '%d singular translated', '%d plural translated');
+ });
+
+ it('and n === 1', () => {
+ const wrapper = mount(
+ {
+ template: `
+ <span>
+ {{ n__('${key}', '%d days', 1) }}
+ </span>
+ `,
+ },
+ { localVue },
+ );
+
+ expect(wrapper.text()).toBe('1 singular translated');
+ });
+
+ it('and n > 1', () => {
+ const wrapper = mount(
+ {
+ template: `
+ <span>
+ {{ n__('${key}', '%d days', 2) }}
+ </span>
+ `,
+ },
+ { localVue },
+ );
+
+ expect(wrapper.text()).toBe('2 plural translated');
+ });
+ });
+
+ describe('translates text with context `s__`', () => {
+ const key = 'Context|Foobar';
+ const translation = 'Context|Foobar translated';
+ const expectation = 'Foobar translated';
+
+ beforeEach(() => {
+ createTranslationMock(key, translation);
+ });
+
+ it('and using two parameters', () => {
+ const wrapper = mount(
+ {
+ template: `
+ <span>
+ {{ s__('Context', 'Foobar') }}
+ </span>
+ `,
+ },
+ { localVue },
+ );
+
+ expect(wrapper.text()).toBe(expectation);
+ });
+
+ it('and using the pipe syntax', () => {
+ const wrapper = mount(
+ {
+ template: `
+ <span>
+ {{ s__('${key}') }}
+ </span>
+ `,
+ },
+ { localVue },
+ );
+
+ expect(wrapper.text()).toBe(expectation);
+ });
+ });
+
+ it('translate multi line text', () => {
+ const translation = 'multiline string translated';
+ createTranslationMock('multiline string', translation);
+
+ const wrapper = mount(
+ {
+ template: `
+ <span>
+ {{ __(\`
+ multiline
+ string
+ \`) }}
+ </span>
+ `,
+ },
+ { localVue },
+ );
+
+ expect(wrapper.text()).toBe(translation);
+ });
+
+ it('translate pluralized multi line text', () => {
+ const translation = 'multiline string plural';
+
+ createTranslationMock('multiline string', 'multiline string singular', translation);
+
+ const wrapper = mount(
+ {
+ template: `
+ <span>
+ {{ n__(
+ \`
+ multiline
+ string
+ \`,
+ \`
+ multiline
+ strings
+ \`,
+ 2
+ ) }}
+ </span>
+ `,
+ },
+ { localVue },
+ );
+
+ expect(wrapper.text()).toBe(translation);
+ });
+
+ it('translate pluralized multi line text with context', () => {
+ const translation = 'multiline string with context';
+
+ createTranslationMock('Context| multiline string', translation);
+
+ const wrapper = mount(
+ {
+ template: `
+ <span>
+ {{ s__(
+ \`
+ Context|
+ multiline
+ string
+ \`
+ ) }}
+ </span>
+ `,
+ },
+ { localVue },
+ );
+
+ expect(wrapper.text()).toBe(translation);
+ });
+});
diff --git a/spec/frontend/vuex_shared/modules/modal/actions_spec.js b/spec/frontend/vuex_shared/modules/modal/actions_spec.js
new file mode 100644
index 00000000000..353dbcb522f
--- /dev/null
+++ b/spec/frontend/vuex_shared/modules/modal/actions_spec.js
@@ -0,0 +1,31 @@
+import testAction from 'helpers/vuex_action_helper';
+import * as types from '~/vuex_shared/modules/modal/mutation_types';
+import * as actions from '~/vuex_shared/modules/modal/actions';
+
+describe('Vuex ModalModule actions', () => {
+ describe('open', () => {
+ it('works', done => {
+ const data = { id: 7 };
+
+ testAction(actions.open, data, {}, [{ type: types.OPEN, payload: data }], [], done);
+ });
+ });
+
+ describe('close', () => {
+ it('works', done => {
+ testAction(actions.close, null, {}, [{ type: types.CLOSE }], [], done);
+ });
+ });
+
+ describe('show', () => {
+ it('works', done => {
+ testAction(actions.show, null, {}, [{ type: types.SHOW }], [], done);
+ });
+ });
+
+ describe('hide', () => {
+ it('works', done => {
+ testAction(actions.hide, null, {}, [{ type: types.HIDE }], [], done);
+ });
+ });
+});
diff --git a/spec/frontend/wikis_spec.js b/spec/frontend/wikis_spec.js
index e5d869840aa..8c68edafd16 100644
--- a/spec/frontend/wikis_spec.js
+++ b/spec/frontend/wikis_spec.js
@@ -1,4 +1,4 @@
-import Wikis from '~/pages/projects/wikis/wikis';
+import Wikis from '~/pages/shared/wikis/wikis';
import { setHTMLFixture } from './helpers/fixtures';
describe('Wikis', () => {
diff --git a/spec/frontend/zen_mode_spec.js b/spec/frontend/zen_mode_spec.js
new file mode 100644
index 00000000000..8e0d170289b
--- /dev/null
+++ b/spec/frontend/zen_mode_spec.js
@@ -0,0 +1,112 @@
+import $ from 'jquery';
+import axios from 'axios';
+import MockAdapter from 'axios-mock-adapter';
+import Dropzone from 'dropzone';
+import Mousetrap from 'mousetrap';
+import ZenMode from '~/zen_mode';
+import initNotes from '~/init_notes';
+
+describe('ZenMode', () => {
+ let mock;
+ let zen;
+ let dropzoneForElementSpy;
+ const fixtureName = 'snippets/show.html';
+
+ preloadFixtures(fixtureName);
+
+ function enterZen() {
+ $('.notes-form .js-zen-enter').click();
+ }
+
+ function exitZen() {
+ $('.notes-form .js-zen-leave').click();
+ }
+
+ function escapeKeydown() {
+ $('.notes-form textarea').trigger(
+ $.Event('keydown', {
+ keyCode: 27,
+ }),
+ );
+ }
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ mock.onGet().reply(200);
+
+ loadFixtures(fixtureName);
+ initNotes();
+
+ dropzoneForElementSpy = jest.spyOn(Dropzone, 'forElement').mockImplementation(() => ({
+ enable: () => true,
+ }));
+ zen = new ZenMode();
+
+ // Set this manually because we can't actually scroll the window
+ zen.scroll_position = 456;
+ });
+
+ describe('enabling dropzone', () => {
+ beforeEach(() => {
+ enterZen();
+ });
+
+ it('should not call dropzone if element is not dropzone valid', () => {
+ $('.div-dropzone').addClass('js-invalid-dropzone');
+ exitZen();
+
+ expect(dropzoneForElementSpy.mock.calls.length).toEqual(0);
+ });
+
+ it('should call dropzone if element is dropzone valid', () => {
+ $('.div-dropzone').removeClass('js-invalid-dropzone');
+ exitZen();
+
+ expect(dropzoneForElementSpy.mock.calls.length).toEqual(2);
+ });
+ });
+
+ describe('on enter', () => {
+ it('pauses Mousetrap', () => {
+ const mouseTrapPauseSpy = jest.spyOn(Mousetrap, 'pause');
+ enterZen();
+
+ expect(mouseTrapPauseSpy).toHaveBeenCalled();
+ });
+
+ it('removes textarea styling', () => {
+ $('.notes-form textarea').attr('style', 'height: 400px');
+ enterZen();
+
+ expect($('.notes-form textarea')).not.toHaveAttr('style');
+ });
+ });
+
+ describe('in use', () => {
+ beforeEach(enterZen);
+
+ it('exits on Escape', () => {
+ escapeKeydown();
+
+ expect($('.notes-form .zen-backdrop')).not.toHaveClass('fullscreen');
+ });
+ });
+
+ describe('on exit', () => {
+ beforeEach(enterZen);
+
+ it('unpauses Mousetrap', () => {
+ const mouseTrapUnpauseSpy = jest.spyOn(Mousetrap, 'unpause');
+ exitZen();
+
+ expect(mouseTrapUnpauseSpy).toHaveBeenCalled();
+ });
+
+ it('restores the scroll position', () => {
+ jest.spyOn(zen, 'scrollTo').mockImplementation(() => {});
+ exitZen();
+
+ expect(zen.scrollTo).toHaveBeenCalled();
+ });
+ });
+});
diff --git a/spec/frontend_integration/ide/__snapshots__/ide_integration_spec.js.snap b/spec/frontend_integration/ide/__snapshots__/ide_integration_spec.js.snap
index a76f7960d03..fe714924c2b 100644
--- a/spec/frontend_integration/ide/__snapshots__/ide_integration_spec.js.snap
+++ b/spec/frontend_integration/ide/__snapshots__/ide_integration_spec.js.snap
@@ -15,7 +15,7 @@ exports[`WebIDE runs 1`] = `
(jest: contents hidden)
</div>
<div
- class="multi-file-commit-panel flex-column"
+ class="gl-relative multi-file-commit-panel flex-column"
style="width: 340px;"
>
<div
diff --git a/spec/graphql/features/authorization_spec.rb b/spec/graphql/features/authorization_spec.rb
index 4f54695e5be..6e5a8b9f4be 100644
--- a/spec/graphql/features/authorization_spec.rb
+++ b/spec/graphql/features/authorization_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Gitlab::Graphql::Authorization' do
+RSpec.describe 'Gitlab::Graphql::Authorization' do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/graphql/features/feature_flag_spec.rb b/spec/graphql/features/feature_flag_spec.rb
index 51914cf0ca8..b484663d675 100644
--- a/spec/graphql/features/feature_flag_spec.rb
+++ b/spec/graphql/features/feature_flag_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Graphql Field feature flags' do
+RSpec.describe 'Graphql Field feature flags' do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/graphql/gitlab_schema_spec.rb b/spec/graphql/gitlab_schema_spec.rb
index 8960ad91543..5d6aa863994 100644
--- a/spec/graphql/gitlab_schema_spec.rb
+++ b/spec/graphql/gitlab_schema_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe GitlabSchema do
+RSpec.describe GitlabSchema do
let_it_be(:connections) { GitlabSchema.connections.all_wrappers }
let(:user) { build :user }
@@ -46,12 +46,6 @@ describe GitlabSchema do
expect(connection).to eq(Gitlab::Graphql::Pagination::ExternallyPaginatedArrayConnection)
end
- it 'paginates FilterableArray using `Pagination::FilterableArrayConnection`' do
- connection = connections[Gitlab::Graphql::FilterableArray]
-
- expect(connection).to eq(Gitlab::Graphql::Pagination::FilterableArrayConnection)
- end
-
describe '.execute' do
context 'for different types of users' do
context 'when no context' do
diff --git a/spec/graphql/mutations/alert_management/alerts/set_assignees_spec.rb b/spec/graphql/mutations/alert_management/alerts/set_assignees_spec.rb
new file mode 100644
index 00000000000..a025b3d344a
--- /dev/null
+++ b/spec/graphql/mutations/alert_management/alerts/set_assignees_spec.rb
@@ -0,0 +1,167 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Mutations::AlertManagement::Alerts::SetAssignees do
+ let_it_be(:starting_assignee) { create(:user) }
+ let_it_be(:unassigned_user) { create(:user) }
+ let_it_be(:alert) { create(:alert_management_alert, assignees: [starting_assignee]) }
+ let_it_be(:project) { alert.project }
+
+ let(:current_user) { starting_assignee }
+ let(:assignee_usernames) { [unassigned_user.username] }
+ let(:operation_mode) { nil }
+
+ let(:args) do
+ {
+ project_path: project.full_path,
+ iid: alert.iid,
+ assignee_usernames: assignee_usernames,
+ operation_mode: operation_mode
+ }
+ end
+
+ before_all do
+ project.add_developer(starting_assignee)
+ project.add_developer(unassigned_user)
+ end
+
+ specify { expect(described_class).to require_graphql_authorizations(:update_alert_management_alert) }
+
+ describe '#resolve' do
+ let(:expected_assignees) { [unassigned_user] }
+
+ subject(:resolve) { mutation_for(project, current_user).resolve(args) }
+
+ shared_examples 'successful resolution' do
+ after do
+ alert.assignees = [starting_assignee]
+ end
+
+ it 'successfully resolves' do
+ expect(resolve).to eq(alert: alert.reload, errors: [])
+ expect(alert.assignees).to eq(expected_assignees)
+ end
+ end
+
+ shared_examples 'noop' do
+ it 'makes no changes' do
+ original_assignees = alert.assignees
+
+ expect(resolve).to eq(alert: alert.reload, errors: [])
+ expect(alert.assignees).to eq(original_assignees)
+ end
+ end
+
+ context 'when operation mode is not specified' do
+ it_behaves_like 'successful resolution'
+ end
+
+ context 'when user does not have permission to update alerts' do
+ let(:current_user) { create(:user) }
+
+ it 'raises an error if the resource is not accessible to the user' do
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+
+ context 'for APPEND operation' do
+ let(:operation_mode) { Types::MutationOperationModeEnum.enum[:append] }
+
+ # Only allow a single assignee
+ context 'when a different user is already assigned' do
+ it_behaves_like 'noop'
+ end
+
+ context 'when no users are specified' do
+ let(:assignee_usernames) { [] }
+
+ it_behaves_like 'noop'
+ end
+
+ context 'when a user is specified and no user is assigned' do
+ before do
+ alert.assignees = []
+ end
+
+ it_behaves_like 'successful resolution'
+ end
+
+ context 'when the specified user is already assigned to the alert' do
+ let(:assignee_usernames) { [starting_assignee.username] }
+
+ it_behaves_like 'noop'
+ end
+ end
+
+ context 'for REPLACE operation' do
+ let(:operation_mode) { Types::MutationOperationModeEnum.enum[:replace] }
+
+ context 'when a different user is already assigned' do
+ it_behaves_like 'successful resolution'
+ end
+
+ context 'when no users are specified' do
+ let(:assignee_usernames) { [] }
+ let(:expected_assignees) { [] }
+
+ it_behaves_like 'successful resolution'
+ end
+
+ context 'when a user is specified and no user is assigned' do
+ before do
+ alert.assignees = []
+ end
+
+ it_behaves_like 'successful resolution'
+ end
+
+ context 'when the specified user is already assigned to the alert' do
+ let(:assignee_usernames) { [starting_assignee.username] }
+
+ it_behaves_like 'noop'
+ end
+
+ context 'when multiple users are specified' do
+ let(:assignees) { [starting_assignee, unassigned_user] }
+ let(:assignee_usernames) { assignees.map(&:username) }
+ let(:expected_assignees) { [assignees.last] }
+
+ it_behaves_like 'successful resolution'
+ end
+ end
+
+ context 'for REMOVE operation' do
+ let(:operation_mode) { Types::MutationOperationModeEnum.enum[:remove] }
+
+ context 'when a different user is already assigned' do
+ it_behaves_like 'noop'
+ end
+
+ context 'when no users are specified' do
+ let(:assignee_usernames) { [] }
+
+ it_behaves_like 'noop'
+ end
+
+ context 'when a user is specified and no user is assigned' do
+ before do
+ alert.assignees = []
+ end
+
+ it_behaves_like 'noop'
+ end
+
+ context 'when the specified user is already assigned to the alert' do
+ let(:assignee_usernames) { [starting_assignee.username] }
+ let(:expected_assignees) { [] }
+
+ it_behaves_like 'successful resolution'
+ end
+ end
+ end
+
+ def mutation_for(project, user)
+ described_class.new(object: project, context: { current_user: user }, field: nil)
+ end
+end
diff --git a/spec/graphql/mutations/alert_management/create_alert_issue_spec.rb b/spec/graphql/mutations/alert_management/create_alert_issue_spec.rb
index 1e51767cf0e..fa5a84b4fcc 100644
--- a/spec/graphql/mutations/alert_management/create_alert_issue_spec.rb
+++ b/spec/graphql/mutations/alert_management/create_alert_issue_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Mutations::AlertManagement::CreateAlertIssue do
+RSpec.describe Mutations::AlertManagement::CreateAlertIssue do
let_it_be(:current_user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:alert) { create(:alert_management_alert, project: project, status: 'triggered') }
diff --git a/spec/graphql/mutations/alert_management/update_alert_status_spec.rb b/spec/graphql/mutations/alert_management/update_alert_status_spec.rb
index 8b9abd9497d..68513c02040 100644
--- a/spec/graphql/mutations/alert_management/update_alert_status_spec.rb
+++ b/spec/graphql/mutations/alert_management/update_alert_status_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Mutations::AlertManagement::UpdateAlertStatus do
+RSpec.describe Mutations::AlertManagement::UpdateAlertStatus do
let_it_be(:current_user) { create(:user) }
let_it_be(:alert) { create(:alert_management_alert, :triggered) }
let_it_be(:project) { alert.project }
@@ -33,7 +33,7 @@ describe Mutations::AlertManagement::UpdateAlertStatus do
context 'error occurs when updating' do
it 'returns the alert with errors' do
# Stub an error on the alert
- allow_next_instance_of(Resolvers::AlertManagementAlertResolver) do |resolver|
+ allow_next_instance_of(Resolvers::AlertManagement::AlertResolver) do |resolver|
allow(resolver).to receive(:resolve).and_return(alert)
end
diff --git a/spec/graphql/mutations/branches/create_spec.rb b/spec/graphql/mutations/branches/create_spec.rb
index 744f8f1f2bc..e378a8e3d41 100644
--- a/spec/graphql/mutations/branches/create_spec.rb
+++ b/spec/graphql/mutations/branches/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Mutations::Branches::Create do
+RSpec.describe Mutations::Branches::Create do
subject(:mutation) { described_class.new(object: nil, context: context, field: nil) }
let_it_be(:project) { create(:project, :public, :repository) }
diff --git a/spec/graphql/mutations/commits/create_spec.rb b/spec/graphql/mutations/commits/create_spec.rb
new file mode 100644
index 00000000000..bb0b8c577b0
--- /dev/null
+++ b/spec/graphql/mutations/commits/create_spec.rb
@@ -0,0 +1,180 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Mutations::Commits::Create do
+ subject(:mutation) { described_class.new(object: nil, context: context, field: nil) }
+
+ let_it_be(:project) { create(:project, :public, :repository) }
+ let_it_be(:user) { create(:user) }
+ let(:context) do
+ GraphQL::Query::Context.new(
+ query: OpenStruct.new(schema: nil),
+ values: { current_user: user },
+ object: nil
+ )
+ end
+
+ specify { expect(described_class).to require_graphql_authorizations(:push_code) }
+
+ describe '#resolve' do
+ subject { mutation.resolve(project_path: project.full_path, branch: branch, message: message, actions: actions) }
+
+ let(:branch) { 'master' }
+ let(:message) { 'Commit message' }
+ let(:actions) do
+ [
+ {
+ action: 'create',
+ file_path: 'NEW_FILE.md',
+ content: 'Hello'
+ }
+ ]
+ end
+
+ let(:mutated_commit) { subject[:commit] }
+
+ it 'raises an error if the resource is not accessible to the user' do
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+
+ context 'when user does not have enough permissions' do
+ before do
+ project.add_guest(user)
+ end
+
+ it 'raises an error' do
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+
+ context 'when user is a maintainer of a different project' do
+ before do
+ create(:project_empty_repo).add_maintainer(user)
+ end
+
+ it 'raises an error' do
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+
+ context 'when the user can create a commit' do
+ let(:deltas) { mutated_commit.raw_deltas }
+
+ before_all do
+ project.add_developer(user)
+ end
+
+ context 'when service successfully creates a new commit' do
+ it 'returns a new commit' do
+ expect(mutated_commit).to have_attributes(message: message, project: project)
+ expect(subject[:errors]).to be_empty
+
+ expect_to_contain_deltas([
+ a_hash_including(a_mode: '0', b_mode: '100644', new_file: true, new_path: 'NEW_FILE.md')
+ ])
+ end
+ end
+
+ context 'when request has multiple actions' do
+ let(:actions) do
+ [
+ {
+ action: 'create',
+ file_path: 'foo/foobar',
+ content: 'some content'
+ },
+ {
+ action: 'delete',
+ file_path: 'README.md'
+ },
+ {
+ action: 'move',
+ file_path: "LICENSE.md",
+ previous_path: "LICENSE",
+ content: "some content"
+ },
+ {
+ action: 'update',
+ file_path: 'VERSION',
+ content: 'new content'
+ },
+ {
+ action: 'chmod',
+ file_path: 'CHANGELOG',
+ execute_filemode: true
+ }
+ ]
+ end
+
+ it 'returns a new commit' do
+ expect(mutated_commit).to have_attributes(message: message, project: project)
+ expect(subject[:errors]).to be_empty
+
+ expect_to_contain_deltas([
+ a_hash_including(a_mode: '0', b_mode: '100644', new_path: 'foo/foobar'),
+ a_hash_including(deleted_file: true, new_path: 'README.md'),
+ a_hash_including(deleted_file: true, new_path: 'LICENSE'),
+ a_hash_including(new_file: true, new_path: 'LICENSE.md'),
+ a_hash_including(new_file: false, new_path: 'VERSION'),
+ a_hash_including(a_mode: '100644', b_mode: '100755', new_path: 'CHANGELOG')
+ ])
+ end
+ end
+
+ context 'when actions are not defined' do
+ let(:actions) { [] }
+
+ it 'returns a new commit' do
+ expect(mutated_commit).to have_attributes(message: message, project: project)
+ expect(subject[:errors]).to be_empty
+
+ expect_to_contain_deltas([])
+ end
+ end
+
+ context 'when branch does not exist' do
+ let(:branch) { 'unknown' }
+
+ it 'returns errors' do
+ expect(mutated_commit).to be_nil
+ expect(subject[:errors]).to eq(['You can only create or edit files when you are on a branch'])
+ end
+ end
+
+ context 'when message is not set' do
+ let(:message) { nil }
+
+ it 'returns errors' do
+ expect(mutated_commit).to be_nil
+ expect(subject[:errors]).to eq(['3:UserCommitFiles: empty CommitMessage'])
+ end
+ end
+
+ context 'when actions are incorrect' do
+ let(:actions) { [{ action: 'unknown', file_path: 'test.md', content: '' }] }
+
+ it 'returns errors' do
+ expect(mutated_commit).to be_nil
+ expect(subject[:errors]).to eq(['Unknown action \'unknown\''])
+ end
+ end
+
+ context 'when branch is protected' do
+ before do
+ create(:protected_branch, project: project, name: branch)
+ end
+
+ it 'returns errors' do
+ expect(mutated_commit).to be_nil
+ expect(subject[:errors]).to eq(['You are not allowed to push into this branch'])
+ end
+ end
+ end
+ end
+
+ def expect_to_contain_deltas(expected_deltas)
+ expect(deltas.count).to eq(expected_deltas.count)
+ expect(deltas).to include(*expected_deltas)
+ end
+end
diff --git a/spec/graphql/mutations/concerns/mutations/resolves_group_spec.rb b/spec/graphql/mutations/concerns/mutations/resolves_group_spec.rb
index 51d3c4f5d6b..6bed3a752ed 100644
--- a/spec/graphql/mutations/concerns/mutations/resolves_group_spec.rb
+++ b/spec/graphql/mutations/concerns/mutations/resolves_group_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Mutations::ResolvesGroup do
+RSpec.describe Mutations::ResolvesGroup do
let(:mutation_class) do
Class.new(Mutations::BaseMutation) do
include Mutations::ResolvesGroup
diff --git a/spec/graphql/mutations/concerns/mutations/resolves_issuable_spec.rb b/spec/graphql/mutations/concerns/mutations/resolves_issuable_spec.rb
index 145e42e2a51..706a54931ea 100644
--- a/spec/graphql/mutations/concerns/mutations/resolves_issuable_spec.rb
+++ b/spec/graphql/mutations/concerns/mutations/resolves_issuable_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Mutations::ResolvesIssuable do
+RSpec.describe Mutations::ResolvesIssuable do
let_it_be(:mutation_class) do
Class.new(Mutations::BaseMutation) do
include Mutations::ResolvesIssuable
diff --git a/spec/graphql/mutations/concerns/mutations/resolves_project_spec.rb b/spec/graphql/mutations/concerns/mutations/resolves_project_spec.rb
deleted file mode 100644
index b5c349f6284..00000000000
--- a/spec/graphql/mutations/concerns/mutations/resolves_project_spec.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe Mutations::ResolvesProject do
- let(:mutation_class) do
- Class.new(Mutations::BaseMutation) do
- include Mutations::ResolvesProject
- end
- end
-
- let(:context) { double }
-
- subject(:mutation) { mutation_class.new(object: nil, context: context, field: nil) }
-
- it 'uses the ProjectsResolver to resolve projects by path' do
- project = create(:project)
-
- expect(Resolvers::ProjectResolver).to receive(:new).with(object: nil, context: context, field: nil).and_call_original
- expect(mutation.resolve_project(full_path: project.full_path).sync).to eq(project)
- end
-end
diff --git a/spec/graphql/mutations/container_expiration_policies/update_spec.rb b/spec/graphql/mutations/container_expiration_policies/update_spec.rb
new file mode 100644
index 00000000000..fc90f437576
--- /dev/null
+++ b/spec/graphql/mutations/container_expiration_policies/update_spec.rb
@@ -0,0 +1,96 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Mutations::ContainerExpirationPolicies::Update do
+ using RSpec::Parameterized::TableSyntax
+
+ let_it_be(:project, reload: true) { create(:project) }
+ let_it_be(:user) { create(:user) }
+
+ let(:container_expiration_policy) { project.container_expiration_policy }
+ let(:params) { { project_path: project.full_path, cadence: '3month', keep_n: 100, older_than: '14d' } }
+
+ specify { expect(described_class).to require_graphql_authorizations(:destroy_container_image) }
+
+ describe '#resolve' do
+ subject { described_class.new(object: project, context: { current_user: user }, field: nil).resolve(params) }
+
+ RSpec.shared_examples 'returning a success' do
+ it 'returns the container expiration policy with no errors' do
+ expect(subject).to eq(
+ container_expiration_policy: container_expiration_policy,
+ errors: []
+ )
+ end
+ end
+
+ RSpec.shared_examples 'updating the container expiration policy' do
+ it_behaves_like 'updating the container expiration policy attributes', mode: :update, from: { cadence: '1d', keep_n: 10, older_than: '90d' }, to: { cadence: '3month', keep_n: 100, older_than: '14d' }
+
+ it_behaves_like 'returning a success'
+
+ context 'with invalid params' do
+ let_it_be(:params) { { project_path: project.full_path, cadence: '20d' } }
+
+ it_behaves_like 'not creating the container expiration policy'
+
+ it "doesn't update the cadence" do
+ expect { subject }
+ .not_to change { container_expiration_policy.reload.cadence }
+ end
+
+ it 'returns an error' do
+ expect(subject).to eq(
+ container_expiration_policy: nil,
+ errors: ['Cadence is not included in the list']
+ )
+ end
+ end
+ end
+
+ RSpec.shared_examples 'denying access to container expiration policy' do
+ it 'raises Gitlab::Graphql::Errors::ResourceNotAvailable' do
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+
+ context 'with existing container expiration policy' do
+ where(:user_role, :shared_examples_name) do
+ :maintainer | 'updating the container expiration policy'
+ :developer | 'updating the container expiration policy'
+ :reporter | 'denying access to container expiration policy'
+ :guest | 'denying access to container expiration policy'
+ :anonymous | 'denying access to container expiration policy'
+ end
+
+ with_them do
+ before do
+ project.send("add_#{user_role}", user) unless user_role == :anonymous
+ end
+
+ it_behaves_like params[:shared_examples_name]
+ end
+ end
+
+ context 'without existing container expiration policy' do
+ let_it_be(:project, reload: true) { create(:project, :without_container_expiration_policy) }
+
+ where(:user_role, :shared_examples_name) do
+ :maintainer | 'creating the container expiration policy'
+ :developer | 'creating the container expiration policy'
+ :reporter | 'denying access to container expiration policy'
+ :guest | 'denying access to container expiration policy'
+ :anonymous | 'denying access to container expiration policy'
+ end
+
+ with_them do
+ before do
+ project.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/mutations/design_management/delete_spec.rb b/spec/graphql/mutations/design_management/delete_spec.rb
index 60be6dad62a..3efa865c64b 100644
--- a/spec/graphql/mutations/design_management/delete_spec.rb
+++ b/spec/graphql/mutations/design_management/delete_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Mutations::DesignManagement::Delete do
+RSpec.describe Mutations::DesignManagement::Delete do
include DesignManagementTestHelpers
let(:issue) { create(:issue) }
diff --git a/spec/graphql/mutations/design_management/upload_spec.rb b/spec/graphql/mutations/design_management/upload_spec.rb
index 783af70448c..326d88cea80 100644
--- a/spec/graphql/mutations/design_management/upload_spec.rb
+++ b/spec/graphql/mutations/design_management/upload_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe Mutations::DesignManagement::Upload do
+RSpec.describe Mutations::DesignManagement::Upload do
include DesignManagementTestHelpers
include ConcurrentHelpers
diff --git a/spec/graphql/mutations/discussions/toggle_resolve_spec.rb b/spec/graphql/mutations/discussions/toggle_resolve_spec.rb
new file mode 100644
index 00000000000..9ac4d6ab165
--- /dev/null
+++ b/spec/graphql/mutations/discussions/toggle_resolve_spec.rb
@@ -0,0 +1,155 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Mutations::Discussions::ToggleResolve do
+ subject(:mutation) do
+ described_class.new(object: nil, context: { current_user: user }, field: nil)
+ end
+
+ let_it_be(:project) { create(:project, :repository) }
+
+ describe '#resolve' do
+ subject do
+ mutation.resolve({ id: id_arg, resolve: resolve_arg })
+ end
+
+ let(:id_arg) { discussion.to_global_id.to_s }
+ let(:resolve_arg) { true }
+ let(:mutated_discussion) { subject[:discussion] }
+ let(:errors) { subject[:errors] }
+
+ shared_examples 'a working resolve method' do
+ context 'when the user does not have permission' do
+ let_it_be(:user) { create(:user) }
+
+ it 'raises an error if the resource is not accessible to the user' do
+ expect { subject }.to raise_error(
+ Gitlab::Graphql::Errors::ResourceNotAvailable,
+ "The resource that you are attempting to access does not exist or you don't have permission to perform this action"
+ )
+ end
+ end
+
+ context 'when the user has permission' do
+ let_it_be(:user) { create(:user, developer_projects: [project]) }
+
+ context 'when discussion cannot be found' do
+ let(:id_arg) { "#{discussion.to_global_id}foo" }
+
+ it 'raises an error' do
+ expect { subject }.to raise_error(
+ Gitlab::Graphql::Errors::ResourceNotAvailable,
+ "The resource that you are attempting to access does not exist or you don't have permission to perform this action"
+ )
+ end
+ end
+
+ context 'when discussion is not a Discussion' do
+ let(:discussion) { create(:note, noteable: noteable, project: project) }
+
+ it 'raises an error' do
+ expect { subject }.to raise_error(
+ Gitlab::Graphql::Errors::ArgumentError,
+ "#{discussion.to_global_id} is not a valid id for Discussion."
+ )
+ end
+ end
+
+ shared_examples 'returns a resolved discussion without errors' do
+ it 'returns a resolved discussion' do
+ expect(mutated_discussion).to be_resolved
+ end
+
+ it 'returns empty errors' do
+ expect(errors).to be_empty
+ end
+ end
+
+ shared_examples 'returns an unresolved discussion without errors' do
+ it 'returns an unresolved discussion' do
+ expect(mutated_discussion).not_to be_resolved
+ end
+
+ it 'returns empty errors' do
+ expect(errors).to be_empty
+ end
+ end
+
+ context 'when the `resolve` argument is true' do
+ include_examples 'returns a resolved discussion without errors'
+
+ context 'when the discussion is already resolved' do
+ before do
+ discussion.resolve!(user)
+ end
+
+ include_examples 'returns a resolved discussion without errors'
+ end
+
+ context 'when the service raises an `ActiveRecord::RecordNotSaved` error' do
+ before do
+ allow_next_instance_of(::Discussions::ResolveService) do |service|
+ allow(service).to receive(:execute).and_raise(ActiveRecord::RecordNotSaved)
+ end
+ end
+
+ it 'does not resolve the discussion' do
+ expect(mutated_discussion).not_to be_resolved
+ end
+
+ it 'returns errors' do
+ expect(errors).to contain_exactly('Discussion failed to be resolved')
+ end
+ end
+ end
+
+ context 'when the `resolve` argument is false' do
+ let(:resolve_arg) { false }
+
+ context 'when the discussion is resolved' do
+ before do
+ discussion.resolve!(user)
+ end
+
+ include_examples 'returns an unresolved discussion without errors'
+
+ context 'when the service raises an `ActiveRecord::RecordNotSaved` error' do
+ before do
+ allow_next_instance_of(discussion.class) do |instance|
+ allow(instance).to receive(:unresolve!).and_raise(ActiveRecord::RecordNotSaved)
+ end
+ end
+
+ it 'does not unresolve the discussion' do
+ expect(mutated_discussion).to be_resolved
+ end
+
+ it 'returns errors' do
+ expect(errors).to contain_exactly('Discussion failed to be unresolved')
+ end
+ end
+ end
+
+ context 'when the discussion is already unresolved' do
+ include_examples 'returns an unresolved discussion without errors'
+ end
+ end
+ end
+ end
+
+ context 'when discussion is on a merge request' do
+ let_it_be(:noteable) { create(:merge_request, source_project: project) }
+ let(:discussion) { create(:diff_note_on_merge_request, noteable: noteable, project: project).to_discussion }
+
+ it_behaves_like 'a working resolve method'
+ end
+
+ context 'when discussion is on a design' do
+ let_it_be(:noteable) { create(:design, :with_file, issue: create(:issue, project: project)) }
+ let(:discussion) { create(:diff_note_on_design, noteable: noteable, project: project).to_discussion }
+
+ it_behaves_like 'a working resolve method'
+ end
+ end
+end
diff --git a/spec/graphql/mutations/issues/set_confidential_spec.rb b/spec/graphql/mutations/issues/set_confidential_spec.rb
index c90ce2658d6..820f9aa5e17 100644
--- a/spec/graphql/mutations/issues/set_confidential_spec.rb
+++ b/spec/graphql/mutations/issues/set_confidential_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Mutations::Issues::SetConfidential do
+RSpec.describe Mutations::Issues::SetConfidential do
let(:issue) { create(:issue) }
let(:user) { create(:user) }
diff --git a/spec/graphql/mutations/issues/set_due_date_spec.rb b/spec/graphql/mutations/issues/set_due_date_spec.rb
index 84df6fce7c7..a638971d966 100644
--- a/spec/graphql/mutations/issues/set_due_date_spec.rb
+++ b/spec/graphql/mutations/issues/set_due_date_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Mutations::Issues::SetDueDate do
+RSpec.describe Mutations::Issues::SetDueDate do
let(:issue) { create(:issue) }
let(:user) { create(:user) }
diff --git a/spec/graphql/mutations/merge_requests/create_spec.rb b/spec/graphql/mutations/merge_requests/create_spec.rb
new file mode 100644
index 00000000000..88acd3ed5b6
--- /dev/null
+++ b/spec/graphql/mutations/merge_requests/create_spec.rb
@@ -0,0 +1,87 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Mutations::MergeRequests::Create do
+ subject(:mutation) { described_class.new(object: nil, context: context, field: nil) }
+
+ let_it_be(:project) { create(:project, :public, :repository) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:context) do
+ GraphQL::Query::Context.new(
+ query: OpenStruct.new(schema: nil),
+ values: { current_user: user },
+ object: nil
+ )
+ end
+
+ describe '#resolve' do
+ subject do
+ mutation.resolve(
+ project_path: project.full_path,
+ title: title,
+ source_branch: source_branch,
+ target_branch: target_branch,
+ description: description
+ )
+ end
+
+ let(:title) { 'MergeRequest' }
+ let(:source_branch) { 'feature' }
+ let(:target_branch) { 'master' }
+ let(:description) { nil }
+
+ let(:mutated_merge_request) { subject[:merge_request] }
+
+ it 'raises an error if the resource is not accessible to the user' do
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+
+ context 'when user does not have enough permissions to create a merge request' do
+ before do
+ project.add_guest(user)
+ end
+
+ it 'raises an error if the resource is not accessible to the user' do
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+
+ context 'when the user can create a merge request' do
+ before_all do
+ project.add_developer(user)
+ end
+
+ it 'creates a new merge request' do
+ expect { mutated_merge_request }.to change(MergeRequest, :count).by(1)
+ end
+
+ it 'returns a new merge request' do
+ expect(mutated_merge_request.title).to eq(title)
+ expect(subject[:errors]).to be_empty
+ end
+
+ context 'when optional description field is set' do
+ let(:description) { 'content' }
+
+ it 'returns a new merge request with a description' do
+ expect(mutated_merge_request.description).to eq(description)
+ expect(subject[:errors]).to be_empty
+ end
+ end
+
+ context 'when service cannot create a merge request' do
+ let(:title) { nil }
+
+ it 'does not create a new merge request' do
+ expect { mutated_merge_request }.not_to change(MergeRequest, :count)
+ end
+
+ it 'returns errors' do
+ expect(mutated_merge_request).to be_nil
+ expect(subject[:errors]).to eq(['Title can\'t be blank'])
+ end
+ end
+ end
+ end
+end
diff --git a/spec/graphql/resolvers/alert_management/alert_resolver_spec.rb b/spec/graphql/resolvers/alert_management/alert_resolver_spec.rb
new file mode 100644
index 00000000000..6c12f765e69
--- /dev/null
+++ b/spec/graphql/resolvers/alert_management/alert_resolver_spec.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Resolvers::AlertManagement::AlertResolver do
+ include GraphqlHelpers
+
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:alert_1) { create(:alert_management_alert, :resolved, project: project, ended_at: 1.year.ago, events: 2, severity: :high) }
+ let_it_be(:alert_2) { create(:alert_management_alert, :ignored, project: project, events: 1, severity: :critical) }
+ let_it_be(:alert_other_proj) { create(:alert_management_alert) }
+
+ let(:args) { {} }
+
+ subject { resolve_alerts(args) }
+
+ context 'user does not have permission' do
+ it { is_expected.to eq(AlertManagement::Alert.none) }
+ end
+
+ context 'user has permission' do
+ before do
+ project.add_developer(current_user)
+ end
+
+ it { is_expected.to contain_exactly(alert_1, alert_2) }
+
+ context 'finding by iid' do
+ let(:args) { { iid: alert_1.iid } }
+
+ it { is_expected.to contain_exactly(alert_1) }
+ end
+
+ context 'finding by status' do
+ let(:args) { { status: [Types::AlertManagement::StatusEnum.values['IGNORED'].value] } }
+
+ it { is_expected.to contain_exactly(alert_2) }
+ end
+
+ describe 'sorting' do
+ # Other sorting examples in spec/finders/alert_management/alerts_finder_spec.rb
+ context 'when sorting by events count' do
+ let_it_be(:alert_count_6) { create(:alert_management_alert, project: project, events: 6) }
+ let_it_be(:alert_count_3) { create(:alert_management_alert, project: project, events: 3) }
+
+ it 'sorts alerts ascending' do
+ expect(resolve_alerts(sort: :event_count_asc)).to eq [alert_2, alert_1, alert_count_3, alert_count_6]
+ end
+
+ it 'sorts alerts descending' do
+ expect(resolve_alerts(sort: :event_count_desc)).to eq [alert_count_6, alert_count_3, alert_1, alert_2]
+ end
+ end
+ end
+ end
+
+ private
+
+ def resolve_alerts(args = {}, context = { current_user: current_user })
+ resolve(described_class, obj: project, args: args, ctx: context)
+ end
+end
diff --git a/spec/graphql/resolvers/alert_management_alert_resolver_spec.rb b/spec/graphql/resolvers/alert_management_alert_resolver_spec.rb
deleted file mode 100644
index 971a81a826d..00000000000
--- a/spec/graphql/resolvers/alert_management_alert_resolver_spec.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe Resolvers::AlertManagementAlertResolver do
- include GraphqlHelpers
-
- let_it_be(:current_user) { create(:user) }
- let_it_be(:project) { create(:project) }
- let_it_be(:alert_1) { create(:alert_management_alert, :resolved, project: project, ended_at: 1.year.ago, events: 2, severity: :high) }
- let_it_be(:alert_2) { create(:alert_management_alert, :ignored, project: project, events: 1, severity: :critical) }
- let_it_be(:alert_other_proj) { create(:alert_management_alert) }
-
- let(:args) { {} }
-
- subject { resolve_alerts(args) }
-
- context 'user does not have permission' do
- it { is_expected.to eq(AlertManagement::Alert.none) }
- end
-
- context 'user has permission' do
- before do
- project.add_developer(current_user)
- end
-
- it { is_expected.to contain_exactly(alert_1, alert_2) }
-
- context 'finding by iid' do
- let(:args) { { iid: alert_1.iid } }
-
- it { is_expected.to contain_exactly(alert_1) }
- end
-
- context 'finding by status' do
- let(:args) { { status: [Types::AlertManagement::StatusEnum.values['IGNORED'].value] } }
-
- it { is_expected.to contain_exactly(alert_2) }
- end
-
- describe 'sorting' do
- # Other sorting examples in spec/finders/alert_management/alerts_finder_spec.rb
- context 'when sorting by events count' do
- let_it_be(:alert_count_6) { create(:alert_management_alert, project: project, events: 6) }
- let_it_be(:alert_count_3) { create(:alert_management_alert, project: project, events: 3) }
-
- it 'sorts alerts ascending' do
- expect(resolve_alerts(sort: :events_count_asc)).to eq [alert_2, alert_1, alert_count_3, alert_count_6]
- end
-
- it 'sorts alerts descending' do
- expect(resolve_alerts(sort: :events_count_desc)).to eq [alert_count_6, alert_count_3, alert_1, alert_2]
- end
- end
- end
- end
-
- private
-
- def resolve_alerts(args = {}, context = { current_user: current_user })
- resolve(described_class, obj: project, args: args, ctx: context)
- end
-end
diff --git a/spec/graphql/resolvers/base_resolver_spec.rb b/spec/graphql/resolvers/base_resolver_spec.rb
index 0a21b2797ee..6c384349577 100644
--- a/spec/graphql/resolvers/base_resolver_spec.rb
+++ b/spec/graphql/resolvers/base_resolver_spec.rb
@@ -41,9 +41,35 @@ describe Resolvers::BaseResolver do
end
end
+ context 'when the resolver returns early' do
+ let(:resolver) do
+ Class.new(described_class) do
+ def ready?(**args)
+ [false, %w(early return)]
+ end
+
+ def resolve(**args)
+ raise 'Should not get here'
+ end
+ end
+ end
+
+ it 'runs correctly in our test framework' do
+ expect(resolve(resolver)).to contain_exactly('early', 'return')
+ end
+
+ it 'single selects the first early return value' do
+ expect(resolve(resolver.single)).to eq('early')
+ end
+
+ it 'last selects the last early return value' do
+ expect(resolve(resolver.last)).to eq('return')
+ end
+ end
+
describe '.last' do
it 'returns a subclass from the resolver' do
- expect(last_resolver.last.superclass).to eq(last_resolver)
+ expect(last_resolver.last.ancestors).to include(last_resolver)
end
it 'returns the same subclass every time' do
@@ -95,4 +121,28 @@ describe Resolvers::BaseResolver do
end
end
end
+
+ describe '#synchronized_object' do
+ let(:object) { double(foo: :the_foo) }
+
+ let(:resolver) do
+ Class.new(described_class) do
+ def resolve(**args)
+ [synchronized_object.foo]
+ end
+ end
+ end
+
+ it 'handles raw objects' do
+ expect(resolve(resolver, obj: object)).to contain_exactly(:the_foo)
+ end
+
+ it 'handles lazy objects' do
+ delayed = BatchLoader::GraphQL.for(1).batch do |_, loader|
+ loader.call(1, object)
+ end
+
+ expect(resolve(resolver, obj: delayed)).to contain_exactly(:the_foo)
+ end
+ end
end
diff --git a/spec/graphql/resolvers/concerns/looks_ahead_spec.rb b/spec/graphql/resolvers/concerns/looks_ahead_spec.rb
new file mode 100644
index 00000000000..8b83f887846
--- /dev/null
+++ b/spec/graphql/resolvers/concerns/looks_ahead_spec.rb
@@ -0,0 +1,177 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe LooksAhead do
+ include GraphqlHelpers
+
+ let_it_be(:the_user) { create(:user) }
+ let_it_be(:label_a) { create(:label) }
+ let_it_be(:label_b) { create(:label) }
+ let_it_be(:issue_a) { create(:issue, author: the_user, labels: [label_a, label_b]) }
+ let_it_be(:issue_b) { create(:issue, author: the_user, labels: [label_a]) }
+ let_it_be(:issue_c) { create(:issue, author: the_user, labels: [label_b]) }
+
+ # Simplified schema to test lookahead
+ let_it_be(:schema) do
+ issues_resolver = Class.new(Resolvers::BaseResolver) do
+ include LooksAhead
+
+ def resolve_with_lookahead(**args)
+ apply_lookahead(object.issues)
+ end
+
+ def preloads
+ { labels: [:labels] }
+ end
+ end
+
+ label = Class.new(GraphQL::Schema::Object) do
+ graphql_name 'Label'
+ field :id, Integer, null: false
+ end
+ issue = Class.new(GraphQL::Schema::Object) do
+ graphql_name 'Issue'
+ field :title, String, null: true
+ field :labels, label.connection_type, null: true
+ end
+ user = Class.new(GraphQL::Schema::Object) do
+ graphql_name 'User'
+ field :name, String, null: true
+ field :issues, issue.connection_type,
+ null: true
+ field :issues_with_lookahead, issue.connection_type,
+ extras: [:lookahead],
+ resolver: issues_resolver,
+ null: true
+ end
+
+ Class.new(GraphQL::Schema) do
+ query(Class.new(GraphQL::Schema::Object) do
+ graphql_name 'Query'
+ field :find_user, user, null: true do
+ argument :username, String, required: true
+ end
+
+ def find_user(username:)
+ context[:user_db].find { |u| u.username == username }
+ end
+ end)
+ end
+ end
+
+ def query(doc = document)
+ GraphQL::Query.new(schema,
+ document: doc,
+ context: { user_db: [the_user] },
+ variables: { username: the_user.username })
+ end
+
+ let(:document) do
+ GraphQL.parse <<-GRAPHQL
+ query($username: String!){
+ findUser(username: $username) {
+ name
+ issues {
+ nodes {
+ title
+ labels { nodes { id } }
+ }
+ }
+ issuesWithLookahead {
+ nodes {
+ title
+ labels { nodes { id } }
+ }
+ }
+ }
+ }
+ GRAPHQL
+ end
+
+ def run_query(gql_query)
+ query(GraphQL.parse(gql_query)).result
+ end
+
+ shared_examples 'a working query on the test schema' do
+ it 'has a good test setup', :aggregate_failures do
+ expected_label_ids = [label_a, label_b].cycle.take(4).map(&:id)
+ issue_titles = [issue_a, issue_b, issue_c].map(&:title)
+
+ res = query.result
+
+ expect(res['errors']).to be_blank
+ expect(res.dig('data', 'findUser', 'name')).to eq(the_user.name)
+ %w(issues issuesWithLookahead).each do |field|
+ expect(all_issue_titles(res, field)).to match_array(issue_titles)
+ expect(all_label_ids(res, field)).to match_array(expected_label_ids)
+ end
+ end
+ end
+
+ it_behaves_like 'a working query on the test schema'
+
+ it 'preloads labels on issues' do
+ expect(the_user.issues).to receive(:preload).with(:labels)
+
+ query.result
+ end
+
+ context 'the feature flag is off' do
+ before do
+ stub_feature_flags(described_class::FEATURE_FLAG => false)
+ end
+
+ it_behaves_like 'a working query on the test schema'
+
+ it 'does not preload labels on issues' do
+ expect(the_user.issues).not_to receive(:preload).with(:labels)
+
+ query.result
+ end
+ end
+
+ it 'issues fewer queries than the naive approach' do
+ the_user.reload # ensure no attributes are loaded before we begin
+ naive = <<-GQL
+ query($username: String!){
+ findUser(username: $username) {
+ name
+ issues {
+ nodes {
+ labels { nodes { id } }
+ }
+ }
+ }
+ }
+ GQL
+ with_lookahead = <<-GQL
+ query($username: String!){
+ findUser(username: $username) {
+ name
+ issuesWithLookahead {
+ nodes {
+ labels { nodes { id } }
+ }
+ }
+ }
+ }
+ GQL
+
+ expect { run_query(with_lookahead) }.to issue_fewer_queries_than { run_query(naive) }
+ end
+
+ private
+
+ def all_label_ids(result, field_name)
+ result.dig('data', 'findUser', field_name, 'nodes').flat_map do |node|
+ node.dig('labels', 'nodes').map { |n| n['id'] }
+ end
+ end
+
+ def all_issue_titles(result, field_name)
+ result.dig('data', 'findUser', field_name, 'nodes').map do |node|
+ node['title']
+ end
+ end
+end
diff --git a/spec/graphql/resolvers/concerns/resolves_project_spec.rb b/spec/graphql/resolvers/concerns/resolves_project_spec.rb
new file mode 100644
index 00000000000..f29f54483d6
--- /dev/null
+++ b/spec/graphql/resolvers/concerns/resolves_project_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe ResolvesProject do
+ include GraphqlHelpers
+
+ let(:implementing_class) do
+ Class.new do
+ include ResolvesProject
+ end
+ end
+
+ subject(:instance) { implementing_class.new }
+
+ let_it_be(:project) { create(:project) }
+
+ it 'can resolve projects by path' do
+ expect(sync(instance.resolve_project(full_path: project.full_path))).to eq(project)
+ end
+
+ it 'can resolve projects by id' do
+ expect(sync(instance.resolve_project(project_id: global_id_of(project)))).to eq(project)
+ end
+
+ it 'complains when both are present' do
+ expect do
+ instance.resolve_project(full_path: project.full_path, project_id: global_id_of(project))
+ end.to raise_error(::Gitlab::Graphql::Errors::ArgumentError)
+ end
+
+ it 'complains when neither is present' do
+ expect do
+ instance.resolve_project(full_path: nil, project_id: nil)
+ end.to raise_error(::Gitlab::Graphql::Errors::ArgumentError)
+ end
+end
diff --git a/spec/graphql/resolvers/merge_requests_resolver_spec.rb b/spec/graphql/resolvers/merge_requests_resolver_spec.rb
index 4217d257ab3..6ff7e1ecac6 100644
--- a/spec/graphql/resolvers/merge_requests_resolver_spec.rb
+++ b/spec/graphql/resolvers/merge_requests_resolver_spec.rb
@@ -6,61 +6,164 @@ describe Resolvers::MergeRequestsResolver do
include GraphqlHelpers
let_it_be(:project) { create(:project, :repository) }
- let_it_be(:merge_request_1) { create(:merge_request, :simple, source_project: project, target_project: project) }
- let_it_be(:merge_request_2) { create(:merge_request, :rebased, source_project: project, target_project: project) }
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:common_attrs) { { author: current_user, source_project: project, target_project: project } }
+ let_it_be(:merge_request_1) { create(:merge_request, :simple, **common_attrs) }
+ let_it_be(:merge_request_2) { create(:merge_request, :rebased, **common_attrs) }
+ let_it_be(:merge_request_3) { create(:merge_request, :unique_branches, **common_attrs) }
+ let_it_be(:merge_request_4) { create(:merge_request, :unique_branches, :locked, **common_attrs) }
+ let_it_be(:merge_request_5) { create(:merge_request, :simple, :locked, **common_attrs) }
+ let_it_be(:merge_request_6) { create(:labeled_merge_request, :unique_branches, labels: create_list(:label, 2), **common_attrs) }
let_it_be(:other_project) { create(:project, :repository) }
let_it_be(:other_merge_request) { create(:merge_request, source_project: other_project, target_project: other_project) }
let(:iid_1) { merge_request_1.iid }
let(:iid_2) { merge_request_2.iid }
let(:other_iid) { other_merge_request.iid }
+ before do
+ project.add_developer(current_user)
+ end
+
describe '#resolve' do
- it 'batch-resolves by target project full path and individual IID' do
- result = batch_sync(max_queries: 2) do
- resolve_mr(project, iid: iid_1) + resolve_mr(project, iid: iid_2)
+ context 'no arguments' do
+ it 'returns all merge requests' do
+ result = resolve_mr(project, {})
+
+ expect(result).to contain_exactly(merge_request_1, merge_request_2, merge_request_3, merge_request_4, merge_request_5, merge_request_6)
end
- expect(result).to contain_exactly(merge_request_1, merge_request_2)
+ it 'returns only merge requests that the current user can see' do
+ result = resolve_mr(project, {}, user: build(:user))
+
+ expect(result).to be_empty
+ end
end
- it 'batch-resolves by target project full path and IIDS' do
- result = batch_sync(max_queries: 2) do
- resolve_mr(project, iids: [iid_1, iid_2])
+ context 'by iid alone' do
+ it 'batch-resolves by target project full path and individual IID' do
+ result = batch_sync(max_queries: 2) do
+ [iid_1, iid_2].map { |iid| resolve_mr_single(project, iid) }
+ end
+
+ expect(result).to contain_exactly(merge_request_1, merge_request_2)
+ end
+
+ it 'batch-resolves by target project full path and IIDS' do
+ result = batch_sync(max_queries: 2) do
+ resolve_mr(project, iids: [iid_1, iid_2])
+ end
+
+ expect(result).to contain_exactly(merge_request_1, merge_request_2)
+ end
+
+ it 'can batch-resolve merge requests from different projects' do
+ result = batch_sync(max_queries: 3) do
+ resolve_mr(project, iids: iid_1) +
+ resolve_mr(project, iids: iid_2) +
+ resolve_mr(other_project, iids: other_iid)
+ end
+
+ expect(result).to contain_exactly(merge_request_1, merge_request_2, other_merge_request)
+ end
+
+ it 'resolves an unknown iid to be empty' do
+ result = batch_sync { resolve_mr_single(project, -1) }
+
+ expect(result).to be_nil
end
- expect(result).to contain_exactly(merge_request_1, merge_request_2)
+ it 'resolves empty iids to be empty' do
+ result = batch_sync { resolve_mr(project, iids: []) }
+
+ expect(result).to be_empty
+ end
+
+ it 'resolves an unknown project to be nil when single' do
+ result = batch_sync { resolve_mr_single(nil, iid_1) }
+
+ expect(result).to be_nil
+ end
+
+ it 'resolves an unknown project to be empty' do
+ result = batch_sync { resolve_mr(nil, iids: [iid_1]) }
+
+ expect(result).to be_empty
+ end
end
- it 'can batch-resolve merge requests from different projects' do
- result = batch_sync(max_queries: 3) do
- resolve_mr(project, iid: iid_1) +
- resolve_mr(project, iid: iid_2) +
- resolve_mr(other_project, iid: other_iid)
+ context 'by source branches' do
+ it 'takes one argument' do
+ result = resolve_mr(project, source_branch: [merge_request_3.source_branch])
+
+ expect(result).to contain_exactly(merge_request_3)
end
- expect(result).to contain_exactly(merge_request_1, merge_request_2, other_merge_request)
+ it 'takes more than one argument' do
+ mrs = [merge_request_3, merge_request_4]
+ branches = mrs.map(&:source_branch)
+ result = resolve_mr(project, source_branch: branches )
+
+ expect(result).to match_array(mrs)
+ end
end
- it 'resolves an unknown iid to be empty' do
- result = batch_sync { resolve_mr(project, iid: -1) }
+ context 'by target branches' do
+ it 'takes one argument' do
+ result = resolve_mr(project, target_branch: [merge_request_3.target_branch])
+
+ expect(result).to contain_exactly(merge_request_3)
+ end
- expect(result.compact).to be_empty
+ it 'takes more than one argument' do
+ mrs = [merge_request_3, merge_request_4]
+ branches = mrs.map(&:target_branch)
+ result = resolve_mr(project, target_branch: branches )
+
+ expect(result.compact).to match_array(mrs)
+ end
end
- it 'resolves empty iids to be empty' do
- result = batch_sync { resolve_mr(project, iids: []) }
+ context 'by state' do
+ it 'takes one argument' do
+ result = resolve_mr(project, state: 'locked')
- expect(result).to be_empty
+ expect(result).to contain_exactly(merge_request_4, merge_request_5)
+ end
end
- it 'resolves an unknown project to be empty' do
- result = batch_sync { resolve_mr(nil, iid: iid_1) }
+ context 'by label' do
+ let_it_be(:label) { merge_request_6.labels.first }
+ let_it_be(:with_label) { create(:labeled_merge_request, :closed, labels: [label], **common_attrs) }
- expect(result.compact).to be_empty
+ it 'takes one argument' do
+ result = resolve_mr(project, label_name: [label.title])
+
+ expect(result).to contain_exactly(merge_request_6, with_label)
+ end
+
+ it 'takes multiple arguments, with semantics of ALL MUST MATCH' do
+ result = resolve_mr(project, label_name: merge_request_6.labels.map(&:title))
+
+ expect(result).to contain_exactly(merge_request_6)
+ end
+ end
+
+ describe 'combinations' do
+ it 'requires all filters' do
+ create(:merge_request, :closed, source_project: project, target_project: project, source_branch: merge_request_4.source_branch)
+
+ result = resolve_mr(project, source_branch: [merge_request_4.source_branch], state: 'locked')
+
+ expect(result.compact).to contain_exactly(merge_request_4)
+ end
end
end
- def resolve_mr(project, args)
- resolve(described_class, obj: project, args: args)
+ def resolve_mr_single(project, iid)
+ resolve_mr(project, { iids: iid }, resolver: described_class.single)
+ end
+
+ def resolve_mr(project, args, resolver: described_class, user: current_user)
+ resolve(resolver, obj: project, args: args, ctx: { current_user: user })
end
end
diff --git a/spec/graphql/resolvers/project_members_resolver_spec.rb b/spec/graphql/resolvers/project_members_resolver_spec.rb
new file mode 100644
index 00000000000..3209838850b
--- /dev/null
+++ b/spec/graphql/resolvers/project_members_resolver_spec.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Resolvers::ProjectMembersResolver do
+ include GraphqlHelpers
+
+ context "with a group" do
+ let_it_be(:root_group) { create(:group) }
+ let_it_be(:group_1) { create(:group, parent: root_group) }
+ let_it_be(:group_2) { create(:group, parent: root_group) }
+ let_it_be(:project) { create(:project, :public, group: group_1) }
+
+ let_it_be(:user_1) { create(:user, name: 'test user') }
+ let_it_be(:user_2) { create(:user, name: 'test user 2') }
+ let_it_be(:user_3) { create(:user, name: 'another user 1') }
+ let_it_be(:user_4) { create(:user, name: 'another user 2') }
+
+ let_it_be(:project_member) { create(:project_member, user: user_1, project: project) }
+ let_it_be(:group_1_member) { create(:group_member, user: user_2, group: group_1) }
+ let_it_be(:group_2_member) { create(:group_member, user: user_3, group: group_2) }
+ let_it_be(:root_group_member) { create(:group_member, user: user_4, group: root_group) }
+
+ let(:args) { {} }
+
+ subject do
+ resolve(described_class, obj: project, args: args, ctx: { context: user_4 })
+ end
+
+ describe '#resolve' do
+ it 'finds all project members' do
+ expect(subject).to contain_exactly(project_member, group_1_member, root_group_member)
+ end
+
+ context 'with search' do
+ context 'when the search term matches a user' do
+ let(:args) { { search: 'test' } }
+
+ it 'searches users by user name' do
+ expect(subject).to contain_exactly(project_member, group_1_member)
+ end
+ end
+
+ context 'when the search term does not match any user' do
+ let(:args) { { search: 'nothing' } }
+
+ it 'is empty' do
+ expect(subject).to be_empty
+ end
+ end
+ end
+
+ context 'when project is nil' do
+ let(:project) { nil }
+
+ it 'returns nil' do
+ expect(subject).to be_empty
+ end
+ end
+ end
+ end
+end
diff --git a/spec/graphql/resolvers/project_pipeline_resolver_spec.rb b/spec/graphql/resolvers/project_pipeline_resolver_spec.rb
new file mode 100644
index 00000000000..72049f16d7d
--- /dev/null
+++ b/spec/graphql/resolvers/project_pipeline_resolver_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Resolvers::ProjectPipelineResolver do
+ include GraphqlHelpers
+
+ let_it_be(:project) { create(:project) }
+ let_it_be(:pipeline) { create(:ci_pipeline, project: project, iid: '1234') }
+ let_it_be(:other_pipeline) { create(:ci_pipeline) }
+ let(:current_user) { create(:user) }
+
+ def resolve_pipeline(project, args)
+ resolve(described_class, obj: project, args: args, ctx: { current_user: current_user })
+ end
+
+ it 'resolves pipeline for the passed iid' do
+ result = batch_sync do
+ resolve_pipeline(project, { iid: '1234' })
+ end
+
+ expect(result).to eq(pipeline)
+ end
+
+ it 'does not resolve a pipeline outside the project' do
+ result = batch_sync do
+ resolve_pipeline(other_pipeline.project, { iid: '1234' })
+ end
+
+ expect(result).to be_nil
+ end
+
+ it 'errors when no iid is passed' do
+ expect { resolve_pipeline(project, {}) }.to raise_error(ArgumentError)
+ end
+end
diff --git a/spec/graphql/resolvers/projects/jira_imports_resolver_spec.rb b/spec/graphql/resolvers/projects/jira_imports_resolver_spec.rb
index 7146bfb441b..9811075a613 100644
--- a/spec/graphql/resolvers/projects/jira_imports_resolver_spec.rb
+++ b/spec/graphql/resolvers/projects/jira_imports_resolver_spec.rb
@@ -40,16 +40,6 @@ describe Resolvers::Projects::JiraImportsResolver do
let_it_be(:jira_import1) { create(:jira_import_state, :finished, project: project, jira_project_key: 'AA', created_at: 2.days.ago) }
let_it_be(:jira_import2) { create(:jira_import_state, :finished, project: project, jira_project_key: 'BB', created_at: 5.days.ago) }
- context 'when feature flag disabled' do
- let(:current_user) { user }
-
- before do
- stub_feature_flags(jira_issue_import: false)
- end
-
- it_behaves_like 'no Jira import access'
- end
-
context 'when user cannot read Jira imports' do
context 'when anonymous user' do
let(:current_user) { nil }
diff --git a/spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb b/spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb
new file mode 100644
index 00000000000..364e2aa6ca8
--- /dev/null
+++ b/spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb
@@ -0,0 +1,81 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Resolvers::Projects::JiraProjectsResolver do
+ include GraphqlHelpers
+
+ describe '#resolve' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+
+ shared_examples 'no project service access' do
+ it 'raises error' do
+ expect do
+ resolve_jira_projects
+ end.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+
+ context 'when project has no jira service' do
+ let_it_be(:jira_service) { nil }
+
+ context 'when user is a maintainer' do
+ before do
+ project.add_maintainer(user)
+ end
+
+ it_behaves_like 'no project service access'
+ end
+ end
+
+ context 'when project has jira service' do
+ let(:jira_service) { create(:jira_service, project: project) }
+
+ context 'when user is a developer' do
+ before do
+ project.add_developer(user)
+ end
+
+ it_behaves_like 'no project service access'
+ end
+
+ context 'when user is a maintainer' do
+ before do
+ project.add_maintainer(user)
+ end
+
+ context 'when Jira connection is valid' do
+ include_context 'jira projects request context'
+
+ it 'returns jira projects' do
+ jira_projects = resolve_jira_projects
+ project_keys = jira_projects.map(&:key)
+ project_names = jira_projects.map(&:name)
+ project_ids = jira_projects.map(&:id)
+
+ expect(jira_projects.size).to eq 2
+ expect(project_keys).to eq(%w(EX ABC))
+ expect(project_names).to eq(%w(Example Alphabetical))
+ expect(project_ids).to eq(%w(10000 10001))
+ end
+ end
+
+ context 'when Jira connection is not valid' do
+ before do
+ WebMock.stub_request(:get, 'https://jira.example.com/rest/api/2/project/search?maxResults=50&query=&startAt=0')
+ .to_raise(JIRA::HTTPError.new(double(message: 'Some failure.')))
+ end
+
+ it 'raises failure error' do
+ expect { resolve_jira_projects }.to raise_error('Jira request error: Some failure.')
+ end
+ end
+ end
+ end
+ end
+
+ def resolve_jira_projects(args = {}, context = { current_user: user })
+ resolve(described_class, obj: jira_service, args: args, ctx: context)
+ end
+end
diff --git a/spec/graphql/resolvers/user_resolver_spec.rb b/spec/graphql/resolvers/user_resolver_spec.rb
new file mode 100644
index 00000000000..45a8816bf26
--- /dev/null
+++ b/spec/graphql/resolvers/user_resolver_spec.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Resolvers::UserResolver do
+ include GraphqlHelpers
+
+ describe '#resolve' do
+ let_it_be(:user) { create(:user) }
+
+ context 'when neither an ID or a username is provided' do
+ it 'raises an ArgumentError' do
+ expect { resolve_user }
+ .to raise_error(Gitlab::Graphql::Errors::ArgumentError)
+ end
+ end
+
+ it 'raises an ArgumentError when both an ID and username are provided' do
+ expect { resolve_user(id: user.to_global_id, username: user.username) }
+ .to raise_error(Gitlab::Graphql::Errors::ArgumentError)
+ end
+
+ context 'by username' do
+ it 'returns the correct user' do
+ expect(
+ resolve_user(username: user.username)
+ ).to eq(user)
+ end
+ end
+
+ context 'by ID' do
+ it 'returns the correct user' do
+ expect(
+ resolve_user(id: user.to_global_id)
+ ).to eq(user)
+ end
+ end
+ end
+
+ private
+
+ def resolve_user(args = {})
+ sync(resolve(described_class, args: args))
+ end
+end
diff --git a/spec/graphql/resolvers/users_resolver_spec.rb b/spec/graphql/resolvers/users_resolver_spec.rb
new file mode 100644
index 00000000000..e752500d52f
--- /dev/null
+++ b/spec/graphql/resolvers/users_resolver_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Resolvers::UsersResolver do
+ include GraphqlHelpers
+
+ let_it_be(:user1) { create(:user) }
+ let_it_be(:user2) { create(:user) }
+
+ describe '#resolve' do
+ it 'raises an error when read_users_list is not authorized' do
+ expect(Ability).to receive(:allowed?).with(nil, :read_users_list).and_return(false)
+
+ expect { resolve_users }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+
+ context 'when no arguments are passed' do
+ it 'returns all users' do
+ expect(resolve_users).to contain_exactly(user1, user2)
+ end
+ end
+
+ context 'when both ids and usernames are passed ' do
+ it 'raises an error' do
+ expect { resolve_users(ids: [user1.to_global_id.to_s], usernames: [user1.username]) }
+ .to raise_error(Gitlab::Graphql::Errors::ArgumentError)
+ end
+ end
+
+ context 'when a set of IDs is passed' do
+ it 'returns those users' do
+ expect(
+ resolve_users(ids: [user1.to_global_id.to_s, user2.to_global_id.to_s])
+ ).to contain_exactly(user1, user2)
+ end
+ end
+
+ context 'when a set of usernames is passed' do
+ it 'returns those users' do
+ expect(
+ resolve_users(usernames: [user1.username, user2.username])
+ ).to contain_exactly(user1, user2)
+ end
+ end
+ end
+
+ def resolve_users(args = {})
+ resolve(described_class, args: args)
+ end
+end
diff --git a/spec/graphql/types/access_level_enum_spec.rb b/spec/graphql/types/access_level_enum_spec.rb
new file mode 100644
index 00000000000..05a6d6d5545
--- /dev/null
+++ b/spec/graphql/types/access_level_enum_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['AccessLevelEnum'] do
+ specify { expect(described_class.graphql_name).to eq('AccessLevelEnum') }
+
+ it 'exposes all the existing access levels' do
+ expect(described_class.values.keys).to match_array(%w[NO_ACCESS GUEST REPORTER DEVELOPER MAINTAINER OWNER])
+ end
+end
diff --git a/spec/graphql/types/access_level_type_spec.rb b/spec/graphql/types/access_level_type_spec.rb
new file mode 100644
index 00000000000..b9711a9aa4b
--- /dev/null
+++ b/spec/graphql/types/access_level_type_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+describe GitlabSchema.types['AccessLevel'] do
+ specify { expect(described_class.graphql_name).to eq('AccessLevel') }
+ specify { expect(described_class).to require_graphql_authorizations(nil) }
+
+ it 'has expected fields' do
+ expected_fields = [:integer_value, :string_value]
+
+ expect(described_class).to have_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/alert_management/alert_type_spec.rb b/spec/graphql/types/alert_management/alert_type_spec.rb
index 9c326f30e3c..5acbf8ebb7a 100644
--- a/spec/graphql/types/alert_management/alert_type_spec.rb
+++ b/spec/graphql/types/alert_management/alert_type_spec.rb
@@ -24,6 +24,9 @@ describe GitlabSchema.types['AlertManagementAlert'] do
details
created_at
updated_at
+ assignees
+ notes
+ discussions
]
expect(described_class).to have_graphql_fields(*expected_fields)
diff --git a/spec/graphql/types/base_field_spec.rb b/spec/graphql/types/base_field_spec.rb
index daed5725e26..3ec33c75803 100644
--- a/spec/graphql/types/base_field_spec.rb
+++ b/spec/graphql/types/base_field_spec.rb
@@ -135,25 +135,6 @@ describe Types::BaseField do
it 'returns true if the feature is enabled' do
expect(field.visible?(context)).to eq(true)
end
-
- context 'falsey feature_flag values' do
- using RSpec::Parameterized::TableSyntax
-
- where(:flag, :feature_value, :visible) do
- '' | false | true
- '' | true | true
- nil | false | true
- nil | true | true
- end
-
- with_them do
- it 'returns the correct value' do
- stub_feature_flags(flag => feature_value)
-
- expect(field.visible?(context)).to eq(visible)
- end
- end
- end
end
end
end
diff --git a/spec/graphql/types/commit_action_mode_enum_spec.rb b/spec/graphql/types/commit_action_mode_enum_spec.rb
new file mode 100644
index 00000000000..9e1a27ea254
--- /dev/null
+++ b/spec/graphql/types/commit_action_mode_enum_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['CommitActionMode'] do
+ it { expect(described_class.graphql_name).to eq('CommitActionMode') }
+
+ it 'exposes all the existing commit actions' do
+ expect(described_class.values.keys).to match_array(%w[CREATE UPDATE MOVE DELETE CHMOD])
+ end
+end
diff --git a/spec/graphql/types/commit_encoding_enum_spec.rb b/spec/graphql/types/commit_encoding_enum_spec.rb
new file mode 100644
index 00000000000..30686a0c712
--- /dev/null
+++ b/spec/graphql/types/commit_encoding_enum_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['CommitEncoding'] do
+ it { expect(described_class.graphql_name).to eq('CommitEncoding') }
+
+ it 'exposes all the existing encoding option' do
+ expect(described_class.values.keys).to match_array(%w[TEXT BASE64])
+ end
+end
diff --git a/spec/graphql/types/container_expiration_policy_cadence_enum_spec.rb b/spec/graphql/types/container_expiration_policy_cadence_enum_spec.rb
new file mode 100644
index 00000000000..08c777cd365
--- /dev/null
+++ b/spec/graphql/types/container_expiration_policy_cadence_enum_spec.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['ContainerExpirationPolicyCadenceEnum'] do
+ let_it_be(:expected_values) { %w[EVERY_DAY EVERY_WEEK EVERY_TWO_WEEKS EVERY_MONTH EVERY_THREE_MONTHS] }
+
+ it_behaves_like 'exposing container expiration policy option', :cadence
+end
diff --git a/spec/graphql/types/container_expiration_policy_keep_enum_spec.rb b/spec/graphql/types/container_expiration_policy_keep_enum_spec.rb
new file mode 100644
index 00000000000..1a5b4bdd3bb
--- /dev/null
+++ b/spec/graphql/types/container_expiration_policy_keep_enum_spec.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['ContainerExpirationPolicyKeepEnum'] do
+ let_it_be(:expected_values) { %w[ONE_TAG FIVE_TAGS TEN_TAGS TWENTY_FIVE_TAGS FIFTY_TAGS ONE_HUNDRED_TAGS] }
+
+ it_behaves_like 'exposing container expiration policy option', :keep_n
+end
diff --git a/spec/graphql/types/container_expiration_policy_older_than_enum_spec.rb b/spec/graphql/types/container_expiration_policy_older_than_enum_spec.rb
new file mode 100644
index 00000000000..47f0ca22522
--- /dev/null
+++ b/spec/graphql/types/container_expiration_policy_older_than_enum_spec.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['ContainerExpirationPolicyOlderThanEnum'] do
+ let_it_be(:expected_values) { %w[SEVEN_DAYS FOURTEEN_DAYS THIRTY_DAYS NINETY_DAYS] }
+
+ it_behaves_like 'exposing container expiration policy option', :older_than
+end
diff --git a/spec/graphql/types/container_expiration_policy_type_spec.rb b/spec/graphql/types/container_expiration_policy_type_spec.rb
new file mode 100644
index 00000000000..8924ab67847
--- /dev/null
+++ b/spec/graphql/types/container_expiration_policy_type_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['ContainerExpirationPolicy'] do
+ specify { expect(described_class.graphql_name).to eq('ContainerExpirationPolicy') }
+
+ specify { expect(described_class.description).to eq('A tag expiration policy designed to keep only the images that matter most') }
+
+ specify { expect(described_class).to require_graphql_authorizations(:destroy_container_image) }
+
+ describe 'older_than field' do
+ subject { described_class.fields['olderThan'] }
+
+ it 'returns older_than enum' do
+ is_expected.to have_graphql_type(Types::ContainerExpirationPolicyOlderThanEnum)
+ end
+ end
+
+ describe 'keep n field' do
+ subject { described_class.fields['keepN'] }
+
+ it 'returns keep enum' do
+ is_expected.to have_graphql_type(Types::ContainerExpirationPolicyKeepEnum)
+ end
+ end
+end
diff --git a/spec/graphql/types/evidence_type_spec.rb b/spec/graphql/types/evidence_type_spec.rb
new file mode 100644
index 00000000000..4a11f7bcda9
--- /dev/null
+++ b/spec/graphql/types/evidence_type_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['ReleaseEvidence'] do
+ it { expect(described_class).to require_graphql_authorizations(:download_code) }
+
+ it 'has the expected fields' do
+ expected_fields = %w[
+ id sha filepath collected_at
+ ]
+
+ expect(described_class).to include_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/group_member_type_spec.rb b/spec/graphql/types/group_member_type_spec.rb
new file mode 100644
index 00000000000..5d09e60d21c
--- /dev/null
+++ b/spec/graphql/types/group_member_type_spec.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Types::GroupMemberType do
+ specify { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Group) }
+
+ specify { expect(described_class.graphql_name).to eq('GroupMember') }
+
+ specify { expect(described_class).to require_graphql_authorizations(:read_group) }
+
+ it 'has the expected fields' do
+ expected_fields = %w[
+ access_level created_by created_at updated_at expires_at group
+ ]
+
+ 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 a834a9038db..c56cd40ef12 100644
--- a/spec/graphql/types/group_type_spec.rb
+++ b/spec/graphql/types/group_type_spec.rb
@@ -29,4 +29,6 @@ describe GitlabSchema.types['Group'] do
is_expected.to have_graphql_type(Types::BoardType.connection_type)
end
end
+
+ it_behaves_like 'a GraphQL type with labels'
end
diff --git a/spec/graphql/types/jira_import_type_spec.rb b/spec/graphql/types/jira_import_type_spec.rb
index ac1aa672e30..fa1152aec41 100644
--- a/spec/graphql/types/jira_import_type_spec.rb
+++ b/spec/graphql/types/jira_import_type_spec.rb
@@ -6,6 +6,9 @@ describe GitlabSchema.types['JiraImport'] do
specify { expect(described_class.graphql_name).to eq('JiraImport') }
it 'has the expected fields' do
- expect(described_class).to have_graphql_fields(:jira_project_key, :createdAt, :scheduled_at, :scheduled_by)
+ expect(described_class).to have_graphql_fields(
+ :jira_project_key, :created_at, :scheduled_at, :scheduled_by,
+ :failed_to_import_count, :imported_issues_count, :total_issue_count
+ )
end
end
diff --git a/spec/graphql/types/merge_request_type_spec.rb b/spec/graphql/types/merge_request_type_spec.rb
index e7ab2100084..0f48264c99f 100644
--- a/spec/graphql/types/merge_request_type_spec.rb
+++ b/spec/graphql/types/merge_request_type_spec.rb
@@ -19,10 +19,11 @@ describe GitlabSchema.types['MergeRequest'] do
force_remove_source_branch merge_status in_progress_merge_commit_sha
merge_error allow_collaboration should_be_rebased rebase_commit_sha
rebase_in_progress merge_commit_message default_merge_commit_message
- merge_ongoing source_branch_exists mergeable_discussions_state web_url
+ merge_ongoing mergeable_discussions_state web_url
+ source_branch_exists target_branch_exists
upvotes downvotes head_pipeline pipelines task_completion_status
milestone assignees participants subscribed labels discussion_locked time_estimate
- total_time_spent reference
+ total_time_spent reference author merged_at
]
expect(described_class).to have_graphql_fields(*expected_fields)
diff --git a/spec/graphql/types/metrics/dashboard_type_spec.rb b/spec/graphql/types/metrics/dashboard_type_spec.rb
index 81219c596a7..0dbd0d8b38d 100644
--- a/spec/graphql/types/metrics/dashboard_type_spec.rb
+++ b/spec/graphql/types/metrics/dashboard_type_spec.rb
@@ -7,7 +7,7 @@ describe GitlabSchema.types['MetricsDashboard'] do
it 'has the expected fields' do
expected_fields = %w[
- path annotations
+ path annotations schema_validation_warnings
]
expect(described_class).to have_graphql_fields(*expected_fields)
diff --git a/spec/graphql/types/notes/diff_position_type_spec.rb b/spec/graphql/types/notes/diff_position_type_spec.rb
index 01f355cb278..87f3810d55c 100644
--- a/spec/graphql/types/notes/diff_position_type_spec.rb
+++ b/spec/graphql/types/notes/diff_position_type_spec.rb
@@ -1,11 +1,22 @@
# frozen_string_literal: true
+
require 'spec_helper'
describe GitlabSchema.types['DiffPosition'] do
it 'exposes the expected fields' do
- expected_fields = [:diff_refs, :file_path, :old_path,
- :new_path, :position_type, :old_line, :new_line, :x, :y,
- :width, :height]
+ expected_fields = %i[
+ diff_refs
+ file_path
+ height
+ new_line
+ new_path
+ old_line
+ old_path
+ position_type
+ width
+ x
+ y
+ ]
expect(described_class).to have_graphql_fields(*expected_fields)
end
diff --git a/spec/graphql/types/notes/discussion_type_spec.rb b/spec/graphql/types/notes/discussion_type_spec.rb
index 44774594d17..177000b01b2 100644
--- a/spec/graphql/types/notes/discussion_type_spec.rb
+++ b/spec/graphql/types/notes/discussion_type_spec.rb
@@ -1,8 +1,22 @@
# frozen_string_literal: true
+
require 'spec_helper'
describe GitlabSchema.types['Discussion'] do
- specify { expect(described_class).to have_graphql_fields(:id, :created_at, :notes, :reply_id) }
+ it 'exposes the expected fields' do
+ expected_fields = %i[
+ created_at
+ id
+ notes
+ reply_id
+ resolvable
+ resolved
+ resolved_at
+ resolved_by
+ ]
+
+ expect(described_class).to have_graphql_fields(*expected_fields)
+ end
specify { expect(described_class).to require_graphql_authorizations(:read_note) }
end
diff --git a/spec/graphql/types/notes/note_type_spec.rb b/spec/graphql/types/notes/note_type_spec.rb
index 019f742ee77..d6cd0800234 100644
--- a/spec/graphql/types/notes/note_type_spec.rb
+++ b/spec/graphql/types/notes/note_type_spec.rb
@@ -1,11 +1,27 @@
# frozen_string_literal: true
+
require 'spec_helper'
describe GitlabSchema.types['Note'] do
it 'exposes the expected fields' do
- expected_fields = [:id, :project, :author, :body, :created_at,
- :updated_at, :discussion, :resolvable, :position, :user_permissions,
- :resolved_by, :resolved_at, :system, :body_html, :confidential]
+ expected_fields = %i[
+ author
+ body
+ body_html
+ confidential
+ created_at
+ discussion
+ id
+ position
+ project
+ resolvable
+ resolved
+ resolved_at
+ resolved_by
+ system
+ updated_at
+ user_permissions
+ ]
expect(described_class).to have_graphql_fields(*expected_fields)
end
diff --git a/spec/graphql/types/notes/noteable_type_spec.rb b/spec/graphql/types/notes/noteable_type_spec.rb
index 4a81f45bd4e..88d8eae56d1 100644
--- a/spec/graphql/types/notes/noteable_type_spec.rb
+++ b/spec/graphql/types/notes/noteable_type_spec.rb
@@ -1,14 +1,23 @@
# frozen_string_literal: true
+
require 'spec_helper'
describe Types::Notes::NoteableType do
- specify { expect(described_class).to have_graphql_fields(:notes, :discussions) }
+ it 'exposes the expected fields' do
+ expected_fields = %i[
+ discussions
+ notes
+ ]
+
+ expect(described_class).to have_graphql_fields(*expected_fields)
+ end
describe ".resolve_type" do
it 'knows the correct type for objects' do
expect(described_class.resolve_type(build(:issue), {})).to eq(Types::IssueType)
expect(described_class.resolve_type(build(:merge_request), {})).to eq(Types::MergeRequestType)
expect(described_class.resolve_type(build(:design), {})).to eq(Types::DesignManagement::DesignType)
+ expect(described_class.resolve_type(build(:alert_management_alert), {})).to eq(Types::AlertManagement::AlertType)
end
end
end
diff --git a/spec/graphql/types/project_member_type_spec.rb b/spec/graphql/types/project_member_type_spec.rb
new file mode 100644
index 00000000000..1b1f6c24a32
--- /dev/null
+++ b/spec/graphql/types/project_member_type_spec.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Types::ProjectMemberType do
+ specify { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Project) }
+
+ specify { expect(described_class.graphql_name).to eq('ProjectMember') }
+
+ specify { expect(described_class).to require_graphql_authorizations(:read_project) }
+
+ it 'has the expected fields' do
+ expected_fields = %w[
+ access_level created_by created_at updated_at expires_at project user
+ ]
+
+ expect(described_class).to include_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/project_type_spec.rb b/spec/graphql/types/project_type_spec.rb
index 6368f743720..8ee9aa9cf3a 100644
--- a/spec/graphql/types/project_type_spec.rb
+++ b/spec/graphql/types/project_type_spec.rb
@@ -26,6 +26,7 @@ describe GitlabSchema.types['Project'] do
grafanaIntegration autocloseReferencedIssues suggestion_commit_message environments
boards jira_import_status jira_imports services releases release
alert_management_alerts alert_management_alert alert_management_alert_status_counts
+ container_expiration_policy
]
expect(described_class).to include_graphql_fields(*expected_fields)
@@ -45,18 +46,32 @@ describe GitlabSchema.types['Project'] do
it { is_expected.to have_graphql_resolver(Resolvers::IssuesResolver) }
end
- describe 'merge_requests field' do
+ describe 'merge_request field' do
subject { described_class.fields['mergeRequest'] }
it { is_expected.to have_graphql_type(Types::MergeRequestType) }
it { is_expected.to have_graphql_resolver(Resolvers::MergeRequestsResolver.single) }
+ it { is_expected.to have_graphql_arguments(:iid) }
end
- describe 'merge_request field' do
+ describe 'merge_requests field' do
subject { described_class.fields['mergeRequests'] }
it { is_expected.to have_graphql_type(Types::MergeRequestType.connection_type) }
it { is_expected.to have_graphql_resolver(Resolvers::MergeRequestsResolver) }
+
+ it do
+ is_expected.to have_graphql_arguments(:iids,
+ :source_branches,
+ :target_branches,
+ :state,
+ :labels,
+ :before,
+ :after,
+ :first,
+ :last
+ )
+ end
end
describe 'snippets field' do
@@ -80,6 +95,13 @@ describe GitlabSchema.types['Project'] do
it { is_expected.to have_graphql_resolver(Resolvers::EnvironmentsResolver) }
end
+ describe 'members field' do
+ subject { described_class.fields['projectMembers'] }
+
+ it { is_expected.to have_graphql_type(Types::ProjectMemberType.connection_type) }
+ it { is_expected.to have_graphql_resolver(Resolvers::ProjectMembersResolver) }
+ end
+
describe 'boards field' do
subject { described_class.fields['boards'] }
@@ -111,4 +133,12 @@ describe GitlabSchema.types['Project'] do
it { is_expected.to have_graphql_type(Types::ReleaseType.connection_type) }
it { is_expected.to have_graphql_resolver(Resolvers::ReleasesResolver) }
end
+
+ describe 'container expiration policy field' do
+ subject { described_class.fields['containerExpirationPolicy'] }
+
+ it { is_expected.to have_graphql_type(Types::ContainerExpirationPolicyType) }
+ end
+
+ it_behaves_like 'a GraphQL type with labels'
end
diff --git a/spec/graphql/types/projects/jira_project_type_spec.rb b/spec/graphql/types/projects/jira_project_type_spec.rb
new file mode 100644
index 00000000000..cbb01117717
--- /dev/null
+++ b/spec/graphql/types/projects/jira_project_type_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['JiraProject'] do
+ it { expect(described_class.graphql_name).to eq('JiraProject') }
+
+ it 'has basic expected fields' do
+ expect(described_class).to have_graphql_fields(:key, :project_id, :name)
+ end
+end
diff --git a/spec/graphql/types/projects/jira_service_type_spec.rb b/spec/graphql/types/projects/jira_service_type_spec.rb
index 91d7e4586cb..fad0c91caab 100644
--- a/spec/graphql/types/projects/jira_service_type_spec.rb
+++ b/spec/graphql/types/projects/jira_service_type_spec.rb
@@ -6,7 +6,7 @@ describe GitlabSchema.types['JiraService'] do
specify { expect(described_class.graphql_name).to eq('JiraService') }
it 'has basic expected fields' do
- expect(described_class).to have_graphql_fields(:type, :active)
+ expect(described_class).to have_graphql_fields(:type, :active, :projects)
end
specify { expect(described_class).to require_graphql_authorizations(:admin_project) }
diff --git a/spec/graphql/types/query_type_spec.rb b/spec/graphql/types/query_type_spec.rb
index 1f269a80d00..1194391c26a 100644
--- a/spec/graphql/types/query_type_spec.rb
+++ b/spec/graphql/types/query_type_spec.rb
@@ -8,7 +8,18 @@ describe GitlabSchema.types['Query'] do
end
it 'has the expected fields' do
- expected_fields = %i[project namespace group echo metadata current_user snippets design_management]
+ expected_fields = %i[
+ project
+ namespace
+ group
+ echo
+ metadata
+ current_user
+ snippets
+ design_management
+ user
+ users
+ ]
expect(described_class).to have_graphql_fields(*expected_fields).at_least
end
diff --git a/spec/graphql/types/release_assets_type_spec.rb b/spec/graphql/types/release_assets_type_spec.rb
new file mode 100644
index 00000000000..58f0f7ee697
--- /dev/null
+++ b/spec/graphql/types/release_assets_type_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['ReleaseAssets'] do
+ it { expect(described_class).to require_graphql_authorizations(:read_release) }
+
+ it 'has the expected fields' do
+ expected_fields = %w[
+ assets_count links sources
+ ]
+
+ expect(described_class).to include_graphql_fields(*expected_fields)
+ end
+
+ describe 'links field' do
+ subject { described_class.fields['links'] }
+
+ it { is_expected.to have_graphql_type(Types::ReleaseLinkType.connection_type) }
+ end
+
+ describe 'sources field' do
+ subject { described_class.fields['sources'] }
+
+ it { is_expected.to have_graphql_type(Types::ReleaseSourceType.connection_type) }
+ end
+end
diff --git a/spec/graphql/types/release_links_type_spec.rb b/spec/graphql/types/release_links_type_spec.rb
new file mode 100644
index 00000000000..49e04e120f4
--- /dev/null
+++ b/spec/graphql/types/release_links_type_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['ReleaseLink'] do
+ it { expect(described_class).to require_graphql_authorizations(:read_release) }
+
+ it 'has the expected fields' do
+ expected_fields = %w[
+ id name url external link_type
+ ]
+
+ expect(described_class).to include_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/release_source_type_spec.rb b/spec/graphql/types/release_source_type_spec.rb
new file mode 100644
index 00000000000..e471ac1a5ac
--- /dev/null
+++ b/spec/graphql/types/release_source_type_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['ReleaseSource'] do
+ it { expect(described_class).to require_graphql_authorizations(:read_release_sources) }
+
+ it 'has the expected fields' do
+ expected_fields = %w[
+ format url
+ ]
+
+ expect(described_class).to include_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/release_type_spec.rb b/spec/graphql/types/release_type_spec.rb
index d22a0b4f0fa..feafe5ed519 100644
--- a/spec/graphql/types/release_type_spec.rb
+++ b/spec/graphql/types/release_type_spec.rb
@@ -9,19 +9,31 @@ describe GitlabSchema.types['Release'] do
expected_fields = %w[
tag_name tag_path
description description_html
- name milestones author commit
+ name assets milestones evidences author commit
created_at released_at
]
expect(described_class).to include_graphql_fields(*expected_fields)
end
+ describe 'assets field' do
+ subject { described_class.fields['assets'] }
+
+ it { is_expected.to have_graphql_type(Types::ReleaseAssetsType) }
+ end
+
describe 'milestones field' do
subject { described_class.fields['milestones'] }
it { is_expected.to have_graphql_type(Types::MilestoneType.connection_type) }
end
+ describe 'evidences field' do
+ subject { described_class.fields['evidences'] }
+
+ it { is_expected.to have_graphql_type(Types::EvidenceType.connection_type) }
+ end
+
describe 'author field' do
subject { described_class.fields['author'] }
diff --git a/spec/graphql/types/resolvable_interface_spec.rb b/spec/graphql/types/resolvable_interface_spec.rb
new file mode 100644
index 00000000000..231287f9969
--- /dev/null
+++ b/spec/graphql/types/resolvable_interface_spec.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Types::ResolvableInterface do
+ it 'exposes the expected fields' do
+ expected_fields = %i[
+ resolvable
+ resolved
+ resolved_at
+ resolved_by
+ ]
+
+ expect(described_class).to have_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/snippet_type_spec.rb b/spec/graphql/types/snippet_type_spec.rb
index adc13d4d651..f24419ce9cc 100644
--- a/spec/graphql/types/snippet_type_spec.rb
+++ b/spec/graphql/types/snippet_type_spec.rb
@@ -11,11 +11,49 @@ describe GitlabSchema.types['Snippet'] do
:visibility_level, :created_at, :updated_at,
:web_url, :raw_url, :ssh_url_to_repo, :http_url_to_repo,
:notes, :discussions, :user_permissions,
- :description_html, :blob]
+ :description_html, :blob, :blobs]
expect(described_class).to have_graphql_fields(*expected_fields)
end
+ context 'when restricted visibility level is set to public' do
+ let_it_be(:snippet) { create(:personal_snippet, :repository, :public, author: user) }
+
+ let(:current_user) { user }
+ let(:query) do
+ %(
+ {
+ snippets {
+ nodes {
+ author {
+ id
+ }
+ }
+ }
+ }
+ )
+ end
+ let(:response) { subject.dig('data', 'snippets', 'nodes')[0] }
+
+ subject { GitlabSchema.execute(query, context: { current_user: current_user }).as_json }
+
+ before do
+ stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC])
+ end
+
+ it 'returns snippet author' do
+ expect(response['author']).to be_present
+ end
+
+ context 'when user is not logged in' do
+ let(:current_user) { nil }
+
+ it 'returns snippet author as nil' do
+ expect(response['author']).to be_nil
+ end
+ end
+ end
+
describe 'authorizations' do
specify { expect(described_class).to require_graphql_authorizations(:read_snippet) }
end
@@ -76,30 +114,14 @@ describe GitlabSchema.types['Snippet'] do
describe '#blob' do
let(:query_blob) { subject.dig('data', 'snippets', 'edges')[0]['node']['blob'] }
- let(:query) do
- %(
- {
- snippets {
- edges {
- node {
- blob {
- name
- path
- }
- }
- }
- }
- }
- )
- end
- subject { GitlabSchema.execute(query, context: { current_user: user }).as_json }
+ subject { GitlabSchema.execute(snippet_query_for(field: 'blob'), context: { current_user: user }).as_json }
context 'when snippet has repository' do
let!(:snippet) { create(:personal_snippet, :repository, :public, author: user) }
let(:blob) { snippet.blobs.first }
- it 'returns blob from the repository' do
+ it 'returns the first blob from the repository' do
expect(query_blob['name']).to eq blob.name
expect(query_blob['path']).to eq blob.path
end
@@ -115,4 +137,58 @@ describe GitlabSchema.types['Snippet'] do
end
end
end
+
+ describe '#blobs' do
+ let_it_be(:snippet) { create(:personal_snippet, :public, author: user) }
+ let(:query_blobs) { subject.dig('data', 'snippets', 'edges')[0]['node']['blobs'] }
+
+ subject { GitlabSchema.execute(snippet_query_for(field: 'blobs'), context: { current_user: user }).as_json }
+
+ shared_examples 'an array' do
+ it 'returns an array of snippet blobs' do
+ expect(query_blobs).to be_an(Array)
+ end
+ end
+
+ context 'when snippet does not have a repository' do
+ let(:blob) { snippet.blob }
+
+ it_behaves_like 'an array'
+
+ it 'contains the first blob from the snippet' do
+ expect(query_blobs.first['name']).to eq blob.name
+ expect(query_blobs.first['path']).to eq blob.path
+ end
+ end
+
+ context 'when snippet has repository' do
+ let_it_be(:snippet) { create(:personal_snippet, :repository, :public, author: user) }
+ let(:blobs) { snippet.blobs }
+
+ it_behaves_like 'an array'
+
+ it 'contains all the blobs from the repository' do
+ resulting_blobs_names = query_blobs.map { |b| b['name'] }
+
+ expect(resulting_blobs_names).to match_array(blobs.map(&:name))
+ end
+ end
+ end
+
+ def snippet_query_for(field:)
+ %(
+ {
+ snippets {
+ edges {
+ node {
+ #{field} {
+ name
+ path
+ }
+ }
+ }
+ }
+ }
+ )
+ end
end
diff --git a/spec/graphql/types/snippets/file_input_action_enum_spec.rb b/spec/graphql/types/snippets/file_input_action_enum_spec.rb
new file mode 100644
index 00000000000..2ccc8b04b8f
--- /dev/null
+++ b/spec/graphql/types/snippets/file_input_action_enum_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Types::Snippets::FileInputActionEnum do
+ specify { expect(described_class.graphql_name).to eq('SnippetFileInputActionEnum') }
+
+ it 'exposes all file input action types' do
+ expect(described_class.values.keys).to eq(%w[create update delete move])
+ end
+end
diff --git a/spec/graphql/types/snippets/file_input_type_spec.rb b/spec/graphql/types/snippets/file_input_type_spec.rb
new file mode 100644
index 00000000000..62e5caf20b7
--- /dev/null
+++ b/spec/graphql/types/snippets/file_input_type_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Types::Snippets::FileInputType do
+ specify { expect(described_class.graphql_name).to eq('SnippetFileInputType') }
+
+ it 'has the correct arguments' do
+ expect(described_class.arguments.keys).to match_array(%w[filePath action previousPath content])
+ end
+
+ it 'sets the type of action argument to FileInputActionEnum' do
+ expect(described_class.arguments['action'].type.of_type).to eq(Types::Snippets::FileInputActionEnum)
+ end
+end
diff --git a/spec/graphql/types/user_type_spec.rb b/spec/graphql/types/user_type_spec.rb
index cf1e91afb80..7b34588b0ff 100644
--- a/spec/graphql/types/user_type_spec.rb
+++ b/spec/graphql/types/user_type_spec.rb
@@ -9,7 +9,19 @@ describe GitlabSchema.types['User'] do
it 'has the expected fields' do
expected_fields = %w[
- id user_permissions snippets name username avatarUrl webUrl todos state
+ id
+ user_permissions
+ snippets
+ name
+ username
+ avatarUrl
+ webUrl
+ todos
+ state
+ authoredMergeRequests
+ assignedMergeRequests
+ groupMemberships
+ projectMemberships
]
expect(described_class).to have_graphql_fields(*expected_fields)
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index 05231cc6d09..75377356445 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -278,7 +278,7 @@ describe ApplicationHelper do
page: 'application',
page_type_id: nil,
find_file: nil,
- group: ''
+ group: nil
}
)
end
@@ -317,7 +317,7 @@ describe ApplicationHelper do
page: 'application',
page_type_id: nil,
find_file: nil,
- group: '',
+ group: nil,
project_id: project.id,
project: project.name,
namespace_id: project.namespace.id
@@ -325,6 +325,25 @@ describe ApplicationHelper do
)
end
+ context 'when @project is owned by a group' do
+ let_it_be(:project) { create(:project, :repository, group: create(:group)) }
+
+ it 'includes all possible body data elements and associates the project elements with project' do
+ expect(helper).to receive(:can?).with(nil, :download_code, project)
+ expect(helper.body_data).to eq(
+ {
+ page: 'application',
+ page_type_id: nil,
+ find_file: nil,
+ group: project.group.name,
+ project_id: project.id,
+ project: project.name,
+ namespace_id: project.namespace.id
+ }
+ )
+ end
+ end
+
context 'when controller is issues' do
before do
stub_controller_method(:controller_path, 'projects:issues')
@@ -342,7 +361,7 @@ describe ApplicationHelper do
page: 'projects:issues:show',
page_type_id: issue.id,
find_file: nil,
- group: '',
+ group: nil,
project_id: issue.project.id,
project: issue.project.name,
namespace_id: issue.project.namespace.id
diff --git a/spec/helpers/application_settings_helper_spec.rb b/spec/helpers/application_settings_helper_spec.rb
index c2f3e26f97b..3fb754f1090 100644
--- a/spec/helpers/application_settings_helper_spec.rb
+++ b/spec/helpers/application_settings_helper_spec.rb
@@ -123,4 +123,27 @@ describe ApplicationSettingsHelper do
end
end
end
+
+ describe '.storage_weights' do
+ let(:application_setting) { build(:application_setting) }
+
+ before do
+ helper.instance_variable_set(:@application_setting, application_setting)
+ stub_storage_settings({ 'default': {}, 'storage_1': {}, 'storage_2': {} })
+ allow(ApplicationSetting).to receive(:repository_storages_weighted_attributes).and_return(
+ [:repository_storages_weighted_default,
+ :repository_storages_weighted_storage_1,
+ :repository_storages_weighted_storage_2])
+
+ stub_application_setting(repository_storages_weighted: { 'default' => 100, 'storage_1' => 50, 'storage_2' => nil })
+ end
+
+ it 'returns storages correctly' do
+ expect(helper.storage_weights).to eq([
+ { name: :repository_storages_weighted_default, label: 'default', value: 100 },
+ { name: :repository_storages_weighted_storage_1, label: 'storage_1', value: 50 },
+ { name: :repository_storages_weighted_storage_2, label: 'storage_2', value: 0 }
+ ])
+ end
+ end
end
diff --git a/spec/helpers/auto_devops_helper_spec.rb b/spec/helpers/auto_devops_helper_spec.rb
index d06548f1595..e0fecb0c159 100644
--- a/spec/helpers/auto_devops_helper_spec.rb
+++ b/spec/helpers/auto_devops_helper_spec.rb
@@ -13,7 +13,7 @@ describe AutoDevopsHelper do
allow(helper).to receive(:can?).with(user, :admin_pipeline, project) { allowed }
allow(helper).to receive(:current_user) { user }
- Feature.get(:auto_devops_banner_disabled).disable
+ stub_feature_flags(auto_devops_banner_disabled: false)
end
subject { helper.show_auto_devops_callout?(project) }
@@ -32,7 +32,7 @@ describe AutoDevopsHelper do
context 'when the banner is disabled by feature flag' do
before do
- Feature.get(:auto_devops_banner_disabled).enable
+ stub_feature_flags(auto_devops_banner_disabled: true)
end
it { is_expected.to be_falsy }
diff --git a/spec/helpers/clusters_helper_spec.rb b/spec/helpers/clusters_helper_spec.rb
index d40ed2248ce..c41d4f0ede7 100644
--- a/spec/helpers/clusters_helper_spec.rb
+++ b/spec/helpers/clusters_helper_spec.rb
@@ -59,6 +59,22 @@ describe ClustersHelper do
end
end
+ describe '#js_clusters_list_data' do
+ it 'displays endpoint path and images' do
+ js_data = helper.js_clusters_list_data('/path')
+
+ expect(js_data[:endpoint]).to eq('/path')
+
+ expect(js_data.dig(:img_tags, :aws, :path)).to match(%r(/illustrations/logos/amazon_eks|svg))
+ expect(js_data.dig(:img_tags, :default, :path)).to match(%r(/illustrations/logos/kubernetes|svg))
+ expect(js_data.dig(:img_tags, :gcp, :path)).to match(%r(/illustrations/logos/google_gke|svg))
+
+ expect(js_data.dig(:img_tags, :aws, :text)).to eq('Amazon EKS')
+ expect(js_data.dig(:img_tags, :default, :text)).to eq('Kubernetes Cluster')
+ expect(js_data.dig(:img_tags, :gcp, :text)).to eq('Google GKE')
+ end
+ end
+
describe '#provider_icon' do
it 'will return GCP logo with gcp argument' do
logo = helper.provider_icon('gcp')
diff --git a/spec/helpers/environments_helper_spec.rb b/spec/helpers/environments_helper_spec.rb
index 0756e0162a5..48104dfc5a6 100644
--- a/spec/helpers/environments_helper_spec.rb
+++ b/spec/helpers/environments_helper_spec.rb
@@ -20,6 +20,7 @@ describe EnvironmentsHelper do
expect(metrics_data).to include(
'settings-path' => edit_project_service_path(project, 'prometheus'),
'clusters-path' => project_clusters_path(project),
+ 'metrics-dashboard-base-path' => environment_metrics_path(environment),
'current-environment-name' => environment.name,
'documentation-path' => help_page_path('administration/monitoring/prometheus/index.md'),
'empty-getting-started-svg-path' => match_asset_path('/assets/illustrations/monitoring/getting_started.svg'),
@@ -39,7 +40,8 @@ describe EnvironmentsHelper do
'validate-query-path' => validate_query_project_prometheus_metrics_path(project),
'custom-metrics-available' => 'true',
'alerts-endpoint' => project_prometheus_alerts_path(project, environment_id: environment.id, format: :json),
- 'prometheus-alerts-available' => 'true'
+ 'prometheus-alerts-available' => 'true',
+ 'custom-dashboard-base-path' => Metrics::Dashboard::CustomDashboardService::DASHBOARD_ROOT
)
end
diff --git a/spec/helpers/events_helper_spec.rb b/spec/helpers/events_helper_spec.rb
index 12519390137..6f24308757d 100644
--- a/spec/helpers/events_helper_spec.rb
+++ b/spec/helpers/events_helper_spec.rb
@@ -150,6 +150,21 @@ describe EventsHelper do
expect(helper.event_wiki_page_target_url(event)).to eq(url)
end
+
+ context 'there is no canonical slug' do
+ let(:event) { create(:wiki_page_event, project: project) }
+
+ before do
+ event.target.slugs.update_all(canonical: false)
+ event.target.clear_memoization(:canonical_slug)
+ end
+
+ it 'links to the home page' do
+ url = helper.project_wiki_url(project, Wiki::HOMEPAGE)
+
+ expect(helper.event_wiki_page_target_url(event)).to eq(url)
+ end
+ end
end
describe '#event_wiki_title_html' do
diff --git a/spec/helpers/gitlab_routing_helper_spec.rb b/spec/helpers/gitlab_routing_helper_spec.rb
index 1955927e2df..4def04f4284 100644
--- a/spec/helpers/gitlab_routing_helper_spec.rb
+++ b/spec/helpers/gitlab_routing_helper_spec.rb
@@ -121,6 +121,16 @@ describe GitlabRoutingHelper do
it 'matches the Rails download path' do
expect(fast_download_project_job_artifacts_path(project, job)).to eq(download_project_job_artifacts_path(project, job))
end
+
+ context 'when given parameters' do
+ it 'adds them to the path' do
+ expect(
+ fast_download_project_job_artifacts_path(project, job, file_type: :dast)
+ ).to eq(
+ download_project_job_artifacts_path(project, job, file_type: :dast)
+ )
+ end
+ end
end
describe '#fast_keep_project_job_artifacts_path' do
@@ -228,5 +238,25 @@ describe GitlabRoutingHelper do
expect(gitlab_toggle_award_emoji_snippet_url(personal_snippet)).to eq("http://test.host/snippets/#{personal_snippet.id}/toggle_award_emoji")
end
end
+
+ describe '#gitlab_dashboard_snippets_path' do
+ it 'returns the personal snippets dashboard path' do
+ expect(gitlab_dashboard_snippets_path(personal_snippet)).to eq("/dashboard/snippets")
+ end
+
+ it 'returns the project snippets dashboard path' do
+ expect(gitlab_dashboard_snippets_path(project_snippet)).to eq("/#{project_snippet.project.full_path}/snippets")
+ end
+ end
+ end
+
+ context 'wikis' do
+ let(:wiki) { create(:project_wiki) }
+
+ describe '#wiki_page_path' do
+ it 'returns the url for the wiki page' do
+ expect(wiki_page_path(wiki, 'page')).to eq("/#{wiki.project.full_path}/-/wikis/page")
+ end
+ end
end
end
diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb
index dad740d3b80..3ef6745958c 100644
--- a/spec/helpers/issues_helper_spec.rb
+++ b/spec/helpers/issues_helper_spec.rb
@@ -7,59 +7,6 @@ describe IssuesHelper do
let(:issue) { create :issue, project: project }
let(:ext_project) { create :redmine_project }
- describe "url_for_issue" do
- let(:issues_url) { ext_project.external_issue_tracker.issues_url}
- let(:ext_expected) { issues_url.gsub(':id', issue.iid.to_s).gsub(':project_id', ext_project.id.to_s) }
- let(:int_expected) { polymorphic_path([@project.namespace, @project, issue]) }
-
- it "returns internal path if used internal tracker" do
- @project = project
-
- expect(url_for_issue(issue.iid)).to match(int_expected)
- end
-
- it "returns path to external tracker" do
- @project = ext_project
-
- expect(url_for_issue(issue.iid)).to match(ext_expected)
- end
-
- it "returns path to internal issue when internal option passed" do
- @project = ext_project
-
- expect(url_for_issue(issue.iid, ext_project, internal: true)).to match(int_expected)
- end
-
- it "returns empty string if project nil" do
- @project = nil
-
- expect(url_for_issue(issue.iid)).to eq ""
- end
-
- it 'returns an empty string if issue_url is invalid' do
- expect(project).to receive_message_chain('issues_tracker.issue_url') { 'javascript:alert("foo");' }
-
- expect(url_for_issue(issue.iid, project)).to eq ''
- end
-
- it 'returns an empty string if issue_path is invalid' do
- expect(project).to receive_message_chain('issues_tracker.issue_path') { 'javascript:alert("foo");' }
-
- expect(url_for_issue(issue.iid, project, only_path: true)).to eq ''
- end
-
- describe "when external tracker was enabled and then config removed" do
- before do
- @project = ext_project
- allow(Gitlab.config).to receive(:issues_tracker).and_return(nil)
- end
-
- it "returns external path" do
- expect(url_for_issue(issue.iid)).to match(ext_expected)
- end
- end
- end
-
describe '#award_user_list' do
it "returns a comma-separated list of the first X users" do
user = build_stubbed(:user, name: 'Joe')
diff --git a/spec/helpers/markup_helper_spec.rb b/spec/helpers/markup_helper_spec.rb
index b2df543d651..1fc79a9762a 100644
--- a/spec/helpers/markup_helper_spec.rb
+++ b/spec/helpers/markup_helper_spec.rb
@@ -317,7 +317,7 @@ describe MarkupHelper do
let(:wiki_repository) { double('Repository') }
let(:context) do
{
- pipeline: :wiki, project: project, project_wiki: wiki,
+ pipeline: :wiki, project: project, wiki: wiki,
page_slug: 'nested/page', issuable_state_filter_enabled: true,
repository: wiki_repository
}
@@ -327,7 +327,7 @@ describe MarkupHelper do
expect(wiki).to receive(:content).and_return('wiki content')
expect(wiki).to receive(:slug).and_return('nested/page')
expect(wiki).to receive(:repository).and_return(wiki_repository)
- helper.instance_variable_set(:@project_wiki, wiki)
+ helper.instance_variable_set(:@wiki, wiki)
end
context 'when file is Markdown' do
diff --git a/spec/helpers/milestones_helper_spec.rb b/spec/helpers/milestones_helper_spec.rb
deleted file mode 100644
index 4ce7143bdf0..00000000000
--- a/spec/helpers/milestones_helper_spec.rb
+++ /dev/null
@@ -1,103 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe MilestonesHelper do
- describe '#milestones_filter_dropdown_path' do
- let(:project) { create(:project) }
- let(:project2) { create(:project) }
- let(:group) { create(:group) }
-
- context 'when @project present' do
- it 'returns project milestones JSON URL' do
- assign(:project, project)
-
- expect(helper.milestones_filter_dropdown_path).to eq(project_milestones_path(project, :json))
- end
- end
-
- context 'when @target_project present' do
- it 'returns targeted project milestones JSON URL' do
- assign(:target_project, project2)
-
- expect(helper.milestones_filter_dropdown_path).to eq(project_milestones_path(project2, :json))
- end
- end
-
- context 'when @group present' do
- it 'returns group milestones JSON URL' do
- assign(:group, group)
-
- expect(helper.milestones_filter_dropdown_path).to eq(group_milestones_path(group, :json))
- end
- end
-
- context 'when neither of @project/@target_project/@group present' do
- it 'returns dashboard milestones JSON URL' do
- expect(helper.milestones_filter_dropdown_path).to eq(dashboard_milestones_path(:json))
- end
- end
- end
-
- describe "#milestone_date_range" do
- def result_for(*args)
- milestone_date_range(build(:milestone, *args))
- end
-
- let(:yesterday) { Date.yesterday }
- let(:tomorrow) { yesterday + 2 }
- let(:format) { '%b %-d, %Y' }
- let(:yesterday_formatted) { yesterday.strftime(format) }
- let(:tomorrow_formatted) { tomorrow.strftime(format) }
-
- it { expect(result_for(due_date: nil, start_date: nil)).to be_nil }
- it { expect(result_for(due_date: tomorrow)).to eq("expires on #{tomorrow_formatted}") }
- it { expect(result_for(due_date: yesterday)).to eq("expired on #{yesterday_formatted}") }
- it { expect(result_for(start_date: tomorrow)).to eq("starts on #{tomorrow_formatted}") }
- it { expect(result_for(start_date: yesterday)).to eq("started on #{yesterday_formatted}") }
- it { expect(result_for(start_date: yesterday, due_date: tomorrow)).to eq("#{yesterday_formatted}–#{tomorrow_formatted}") }
- end
-
- describe '#milestone_counts' do
- let(:project) { create(:project) }
- let(:counts) { helper.milestone_counts(project.milestones) }
-
- context 'when there are milestones' do
- it 'returns the correct counts' do
- create_list(:active_milestone, 2, project: project)
- create(:closed_milestone, project: project)
-
- expect(counts).to eq(opened: 2, closed: 1, all: 3)
- end
- end
-
- context 'when there are only milestones of one type' do
- it 'returns the correct counts' do
- create_list(:active_milestone, 2, project: project)
-
- expect(counts).to eq(opened: 2, closed: 0, all: 2)
- end
- end
-
- context 'when there are no milestones' do
- it 'returns the correct counts' do
- expect(counts).to eq(opened: 0, closed: 0, all: 0)
- end
- end
- end
-
- describe "#group_milestone_route" do
- let(:group) { build_stubbed(:group) }
- let(:subgroup) { build_stubbed(:group, parent: group, name: "Test Subgrp") }
-
- context "when in subgroup" do
- let(:milestone) { build_stubbed(:group_milestone, group: subgroup) }
-
- it 'generates correct url despite assigned @group' do
- assign(:group, group)
- milestone_path = "/groups/#{subgroup.full_path}/-/milestones/#{milestone.iid}"
- expect(helper.group_milestone_route(milestone)).to eq(milestone_path)
- end
- end
- end
-end
diff --git a/spec/helpers/milestones_routing_helper_spec.rb b/spec/helpers/milestones_routing_helper_spec.rb
deleted file mode 100644
index 4da589a5007..00000000000
--- a/spec/helpers/milestones_routing_helper_spec.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe MilestonesRoutingHelper do
- let(:project) { build_stubbed(:project) }
- let(:group) { build_stubbed(:group) }
-
- describe '#milestone_path' do
- context 'for a group milestone' do
- let(:milestone) { build_stubbed(:milestone, group: group, iid: 1) }
-
- it 'links to the group milestone page' do
- expect(milestone_path(milestone))
- .to eq(group_milestone_path(group, milestone))
- end
- end
-
- context 'for a project milestone' do
- let(:milestone) { build_stubbed(:milestone, project: project, iid: 1) }
-
- it 'links to the project milestone page' do
- expect(milestone_path(milestone))
- .to eq(project_milestone_path(project, milestone))
- end
- end
- end
-
- describe '#milestone_url' do
- context 'for a group milestone' do
- let(:milestone) { build_stubbed(:milestone, group: group, iid: 1) }
-
- it 'links to the group milestone page' do
- expect(milestone_url(milestone))
- .to eq(group_milestone_url(group, milestone))
- end
- end
-
- context 'for a project milestone' do
- let(:milestone) { build_stubbed(:milestone, project: project, iid: 1) }
-
- it 'links to the project milestone page' do
- expect(milestone_url(milestone))
- .to eq(project_milestone_url(project, milestone))
- end
- end
- end
-end
diff --git a/spec/helpers/namespaces_helper_spec.rb b/spec/helpers/namespaces_helper_spec.rb
index 36465069311..ebce296d7c2 100644
--- a/spec/helpers/namespaces_helper_spec.rb
+++ b/spec/helpers/namespaces_helper_spec.rb
@@ -174,4 +174,96 @@ describe NamespacesHelper do
end
end
end
+
+ describe '#namespace_storage_alert' do
+ subject { helper.namespace_storage_alert(namespace) }
+
+ let(:namespace) { build(:namespace) }
+
+ let(:payload) do
+ {
+ alert_level: :info,
+ usage_message: "Usage",
+ explanation_message: "Explanation",
+ root_namespace: namespace
+ }
+ end
+
+ before do
+ allow(helper).to receive(:current_user).and_return(admin)
+ allow_next_instance_of(Namespaces::CheckStorageSizeService, namespace, admin) do |check_storage_size_service|
+ expect(check_storage_size_service).to receive(:execute).and_return(ServiceResponse.success(payload: payload))
+ end
+ end
+
+ context 'when payload is not empty and no cookie is set' do
+ it { is_expected.to eq(payload) }
+ end
+
+ context 'when there is no current_user' do
+ before do
+ allow(helper).to receive(:current_user).and_return(nil)
+ end
+
+ it { is_expected.to eq({}) }
+ end
+
+ context 'when payload is empty' do
+ let(:payload) { {} }
+
+ it { is_expected.to eq({}) }
+ end
+
+ context 'when cookie is set' do
+ before do
+ helper.request.cookies["hide_storage_limit_alert_#{namespace.id}_info"] = 'true'
+ end
+
+ it { is_expected.to eq({}) }
+ end
+
+ context 'when payload is empty and cookie is set' do
+ let(:payload) { {} }
+
+ before do
+ helper.request.cookies["hide_storage_limit_alert_#{namespace.id}_info"] = 'true'
+ end
+
+ it { is_expected.to eq({}) }
+ end
+ end
+
+ describe '#namespace_storage_alert_style' do
+ using RSpec::Parameterized::TableSyntax
+
+ subject { helper.namespace_storage_alert_style(alert_level) }
+
+ where(:alert_level, :result) do
+ :info | 'info'
+ :warning | 'warning'
+ :error | 'danger'
+ :alert | 'danger'
+ end
+
+ with_them do
+ it { is_expected.to eq(result) }
+ end
+ end
+
+ describe '#namespace_storage_alert_icon' do
+ using RSpec::Parameterized::TableSyntax
+
+ subject { helper.namespace_storage_alert_icon(alert_level) }
+
+ where(:alert_level, :result) do
+ :info | 'information-o'
+ :warning | 'warning'
+ :error | 'error'
+ :alert | 'error'
+ end
+
+ with_them do
+ it { is_expected.to eq(result) }
+ end
+ end
end
diff --git a/spec/helpers/notes_helper_spec.rb b/spec/helpers/notes_helper_spec.rb
index f074a918e7f..543a9081779 100644
--- a/spec/helpers/notes_helper_spec.rb
+++ b/spec/helpers/notes_helper_spec.rb
@@ -24,6 +24,36 @@ describe NotesHelper do
project.add_guest(guest)
end
+ describe '#note_target_title' do
+ context 'note does not exist' do
+ it 'returns nil' do
+ expect(helper.note_target_title(nil)).to be_blank
+ end
+ end
+
+ context 'target does not exist' do
+ it 'returns nil' do
+ note = Note.new
+ expect(helper.note_target_title(note)).to be_blank
+ end
+ end
+
+ context 'when given a design target' do
+ it 'returns nil' do
+ note = build_stubbed(:note_on_design)
+ expect(helper.note_target_title(note)).to be_blank
+ end
+ end
+
+ context 'when given a non-design target' do
+ it 'returns the issue title' do
+ issue = build_stubbed(:issue, title: 'Issue 1')
+ note = build_stubbed(:note, noteable: issue)
+ expect(helper.note_target_title(note)).to eq('Issue 1')
+ end
+ end
+ end
+
describe "#notes_max_access_for_users" do
it 'returns access levels' do
expect(helper.note_max_access_for_user(owner_note)).to eq(Gitlab::Access::OWNER)
diff --git a/spec/helpers/page_layout_helper_spec.rb b/spec/helpers/page_layout_helper_spec.rb
index 7e851a1af01..55f743ac683 100644
--- a/spec/helpers/page_layout_helper_spec.rb
+++ b/spec/helpers/page_layout_helper_spec.rb
@@ -117,4 +117,19 @@ describe PageLayoutHelper do
expect(tags).to include(%q{content="foo&quot; http-equiv=&quot;refresh"})
end
end
+
+ describe '#search_context' do
+ subject(:search_context) { helper.search_context }
+
+ describe 'a bare controller' do
+ it 'returns an empty context' do
+ expect(search_context).to have_attributes(project: nil,
+ group: nil,
+ snippets: [],
+ project_metadata: {},
+ group_metadata: {},
+ search_url: '/search')
+ end
+ end
+ end
end
diff --git a/spec/helpers/projects/alert_management_helper_spec.rb b/spec/helpers/projects/alert_management_helper_spec.rb
index 078759de39c..49b64b316e7 100644
--- a/spec/helpers/projects/alert_management_helper_spec.rb
+++ b/spec/helpers/projects/alert_management_helper_spec.rb
@@ -69,13 +69,13 @@ describe Projects::AlertManagementHelper do
describe '#alert_management_detail_data' do
let(:alert_id) { 1 }
- let(:new_issue_path) { new_project_issue_path(project) }
+ let(:issues_path) { project_issues_path(project) }
it 'returns detail page configuration' do
expect(helper.alert_management_detail_data(project, alert_id)).to eq(
'alert-id' => alert_id,
'project-path' => project_path,
- 'new-issue-path' => new_issue_path
+ 'project-issues-path' => issues_path
)
end
end
diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb
index 189ab1a8354..4e072f02ae0 100644
--- a/spec/helpers/projects_helper_spec.rb
+++ b/spec/helpers/projects_helper_spec.rb
@@ -5,6 +5,9 @@ require 'spec_helper'
describe ProjectsHelper do
include ProjectForksHelper
+ let_it_be(:project) { create(:project) }
+ let_it_be(:user) { create(:user) }
+
describe '#project_incident_management_setting' do
let(:project) { create(:project) }
@@ -29,8 +32,8 @@ describe ProjectsHelper do
setting = helper.project_incident_management_setting
expect(setting).not_to be_persisted
+ expect(setting.create_issue).to be_falsey
expect(setting.send_email).to be_falsey
- expect(setting.create_issue).to be_truthy
expect(setting.issue_template_key).to be_nil
end
end
@@ -500,6 +503,23 @@ describe ProjectsHelper do
end
end
+ describe '#can_view_operations_tab?' do
+ before do
+ allow(helper).to receive(:current_user).and_return(user)
+ end
+
+ subject { helper.send(:can_view_operations_tab?, user, project) }
+
+ [:read_environment, :read_cluster, :metrics_dashboard].each do |ability|
+ it 'includes operations tab' do
+ allow(helper).to receive(:can?).and_return(false)
+ allow(helper).to receive(:can?).with(user, ability, project).and_return(true)
+
+ is_expected.to be(true)
+ end
+ end
+ end
+
describe '#show_projects' do
let(:projects) do
create(:project)
@@ -665,11 +685,11 @@ describe ProjectsHelper do
end
end
- describe 'link_to_bfg' do
- subject { helper.link_to_bfg }
+ describe 'link_to_filter_repo' do
+ subject { helper.link_to_filter_repo }
- it 'generates a hardcoded link to the BFG Repo-Cleaner' do
- result = helper.link_to_bfg
+ it 'generates a hardcoded link to git filter-repo' do
+ result = helper.link_to_filter_repo
doc = Nokogiri::HTML.fragment(result)
expect(doc.children.size).to eq(1)
@@ -682,8 +702,8 @@ describe ProjectsHelper do
expect(link.name).to eq('a')
expect(link[:target]).to eq('_blank')
expect(link[:rel]).to eq('noopener noreferrer')
- expect(link[:href]).to eq('https://rtyley.github.io/bfg-repo-cleaner/')
- expect(link.inner_html).to eq('BFG')
+ expect(link[:href]).to eq('https://github.com/newren/git-filter-repo')
+ expect(link.inner_html).to eq('git filter-repo')
expect(result).to be_html_safe
end
diff --git a/spec/helpers/recaptcha_experiment_helper_spec.rb b/spec/helpers/recaptcha_experiment_helper_spec.rb
index 775c2caa082..a5b233e28a0 100644
--- a/spec/helpers/recaptcha_experiment_helper_spec.rb
+++ b/spec/helpers/recaptcha_experiment_helper_spec.rb
@@ -3,6 +3,12 @@
require 'spec_helper'
describe RecaptchaExperimentHelper, type: :helper do
+ let(:session) { {} }
+
+ before do
+ allow(helper).to receive(:session) { session }
+ end
+
describe '.show_recaptcha_sign_up?' do
context 'when reCAPTCHA is disabled' do
it 'returns false' do
diff --git a/spec/helpers/search_helper_spec.rb b/spec/helpers/search_helper_spec.rb
index 6a06b012c6c..b209ed869bf 100644
--- a/spec/helpers/search_helper_spec.rb
+++ b/spec/helpers/search_helper_spec.rb
@@ -8,99 +8,6 @@ describe SearchHelper do
str
end
- describe 'search_autocomplete_opts' do
- context "with no current user" do
- before do
- allow(self).to receive(:current_user).and_return(nil)
- end
-
- it "returns nil" do
- expect(search_autocomplete_opts("q")).to be_nil
- end
- end
-
- context "with a standard user" do
- let(:user) { create(:user) }
-
- before do
- allow(self).to receive(:current_user).and_return(user)
- end
-
- it "includes Help sections" do
- expect(search_autocomplete_opts("hel").size).to eq(9)
- end
-
- it "includes default sections" do
- expect(search_autocomplete_opts("dash").size).to eq(1)
- end
-
- it "does not include admin sections" do
- expect(search_autocomplete_opts("admin").size).to eq(0)
- end
-
- it "does not allow regular expression in search term" do
- expect(search_autocomplete_opts("(webhooks|api)").size).to eq(0)
- end
-
- it "includes the user's groups" do
- create(:group).add_owner(user)
- expect(search_autocomplete_opts("gro").size).to eq(1)
- end
-
- it "includes nested group" do
- create(:group, :nested, name: 'foo').add_owner(user)
- expect(search_autocomplete_opts('foo').size).to eq(1)
- end
-
- it "includes the user's projects" do
- project = create(:project, namespace: create(:namespace, owner: user))
- expect(search_autocomplete_opts(project.name).size).to eq(1)
- end
-
- it "includes the required project attrs" do
- project = create(:project, namespace: create(:namespace, owner: user))
- result = search_autocomplete_opts(project.name).first
-
- expect(result.keys).to match_array(%i[category id value label url avatar_url])
- end
-
- it "includes the required group attrs" do
- create(:group).add_owner(user)
- result = search_autocomplete_opts("gro").first
-
- expect(result.keys).to match_array(%i[category id label url avatar_url])
- end
-
- it "does not include the public group" do
- group = create(:group)
- expect(search_autocomplete_opts(group.name).size).to eq(0)
- end
-
- context "with a current project" do
- before do
- @project = create(:project, :repository)
- end
-
- it "includes project-specific sections" do
- expect(search_autocomplete_opts("Files").size).to eq(1)
- expect(search_autocomplete_opts("Commits").size).to eq(1)
- end
- end
- end
-
- context 'with an admin user' do
- let(:admin) { create(:admin) }
-
- before do
- allow(self).to receive(:current_user).and_return(admin)
- end
-
- it "includes admin sections" do
- expect(search_autocomplete_opts("admin").size).to eq(1)
- end
- end
- end
-
describe 'search_entries_info' do
using RSpec::Parameterized::TableSyntax
diff --git a/spec/helpers/subscribable_banner_helper_spec.rb b/spec/helpers/subscribable_banner_helper_spec.rb
new file mode 100644
index 00000000000..75f2e32d7d8
--- /dev/null
+++ b/spec/helpers/subscribable_banner_helper_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe SubscribableBannerHelper do
+ describe '#display_subscription_banner!' do
+ it 'is over-written in EE' do
+ expect { helper.display_subscription_banner! }.not_to raise_error
+ end
+ end
+end
diff --git a/spec/helpers/timeboxes_helper_spec.rb b/spec/helpers/timeboxes_helper_spec.rb
new file mode 100644
index 00000000000..6fe738914ce
--- /dev/null
+++ b/spec/helpers/timeboxes_helper_spec.rb
@@ -0,0 +1,114 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe TimeboxesHelper do
+ describe '#milestones_filter_dropdown_path' do
+ let(:project) { create(:project) }
+ let(:project2) { create(:project) }
+ let(:group) { create(:group) }
+
+ context 'when @project present' do
+ it 'returns project milestones JSON URL' do
+ assign(:project, project)
+
+ expect(helper.milestones_filter_dropdown_path).to eq(project_milestones_path(project, :json))
+ end
+ end
+
+ context 'when @target_project present' do
+ it 'returns targeted project milestones JSON URL' do
+ assign(:target_project, project2)
+
+ expect(helper.milestones_filter_dropdown_path).to eq(project_milestones_path(project2, :json))
+ end
+ end
+
+ context 'when @group present' do
+ it 'returns group milestones JSON URL' do
+ assign(:group, group)
+
+ expect(helper.milestones_filter_dropdown_path).to eq(group_milestones_path(group, :json))
+ end
+ end
+
+ context 'when neither of @project/@target_project/@group present' do
+ it 'returns dashboard milestones JSON URL' do
+ expect(helper.milestones_filter_dropdown_path).to eq(dashboard_milestones_path(:json))
+ end
+ end
+ end
+
+ describe "#timebox_date_range" do
+ let(:yesterday) { Date.yesterday }
+ let(:tomorrow) { yesterday + 2 }
+ let(:format) { '%b %-d, %Y' }
+ let(:yesterday_formatted) { yesterday.strftime(format) }
+ let(:tomorrow_formatted) { tomorrow.strftime(format) }
+
+ context 'milestone' do
+ def result_for(*args)
+ timebox_date_range(build(:milestone, *args))
+ end
+
+ it { expect(result_for(due_date: nil, start_date: nil)).to be_nil }
+ it { expect(result_for(due_date: tomorrow)).to eq("expires on #{tomorrow_formatted}") }
+ it { expect(result_for(due_date: yesterday)).to eq("expired on #{yesterday_formatted}") }
+ it { expect(result_for(start_date: tomorrow)).to eq("starts on #{tomorrow_formatted}") }
+ it { expect(result_for(start_date: yesterday)).to eq("started on #{yesterday_formatted}") }
+ it { expect(result_for(start_date: yesterday, due_date: tomorrow)).to eq("#{yesterday_formatted}–#{tomorrow_formatted}") }
+ end
+
+ context 'iteration' do
+ # Iterations always have start and due dates, so only A-B format is expected
+ it 'formats properly' do
+ iteration = build(:iteration, start_date: yesterday, due_date: tomorrow)
+
+ expect(timebox_date_range(iteration)).to eq("#{yesterday_formatted}–#{tomorrow_formatted}")
+ end
+ end
+ end
+
+ describe '#milestone_counts' do
+ let(:project) { create(:project) }
+ let(:counts) { helper.milestone_counts(project.milestones) }
+
+ context 'when there are milestones' do
+ it 'returns the correct counts' do
+ create_list(:active_milestone, 2, project: project)
+ create(:closed_milestone, project: project)
+
+ expect(counts).to eq(opened: 2, closed: 1, all: 3)
+ end
+ end
+
+ context 'when there are only milestones of one type' do
+ it 'returns the correct counts' do
+ create_list(:active_milestone, 2, project: project)
+
+ expect(counts).to eq(opened: 2, closed: 0, all: 2)
+ end
+ end
+
+ context 'when there are no milestones' do
+ it 'returns the correct counts' do
+ expect(counts).to eq(opened: 0, closed: 0, all: 0)
+ end
+ end
+ end
+
+ describe "#group_milestone_route" do
+ let(:group) { build_stubbed(:group) }
+ let(:subgroup) { build_stubbed(:group, parent: group, name: "Test Subgrp") }
+
+ context "when in subgroup" do
+ let(:milestone) { build_stubbed(:group_milestone, group: subgroup) }
+
+ it 'generates correct url despite assigned @group' do
+ assign(:group, group)
+ milestone_path = "/groups/#{subgroup.full_path}/-/milestones/#{milestone.iid}"
+ expect(helper.group_milestone_route(milestone)).to eq(milestone_path)
+ end
+ end
+ end
+end
diff --git a/spec/helpers/timeboxes_routing_helper_spec.rb b/spec/helpers/timeboxes_routing_helper_spec.rb
new file mode 100644
index 00000000000..1b0eb2c0ad2
--- /dev/null
+++ b/spec/helpers/timeboxes_routing_helper_spec.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe TimeboxesRoutingHelper do
+ let(:project) { build_stubbed(:project) }
+ let(:group) { build_stubbed(:group) }
+
+ describe '#milestone_path' do
+ context 'for a group milestone' do
+ let(:milestone) { build_stubbed(:milestone, group: group, iid: 1) }
+
+ it 'links to the group milestone page' do
+ expect(milestone_path(milestone))
+ .to eq(group_milestone_path(group, milestone))
+ end
+ end
+
+ context 'for a project milestone' do
+ let(:milestone) { build_stubbed(:milestone, project: project, iid: 1) }
+
+ it 'links to the project milestone page' do
+ expect(milestone_path(milestone))
+ .to eq(project_milestone_path(project, milestone))
+ end
+ end
+ end
+
+ describe '#milestone_url' do
+ context 'for a group milestone' do
+ let(:milestone) { build_stubbed(:milestone, group: group, iid: 1) }
+
+ it 'links to the group milestone page' do
+ expect(milestone_url(milestone))
+ .to eq(group_milestone_url(group, milestone))
+ end
+ end
+
+ context 'for a project milestone' do
+ let(:milestone) { build_stubbed(:milestone, project: project, iid: 1) }
+
+ it 'links to the project milestone page' do
+ expect(milestone_url(milestone))
+ .to eq(project_milestone_url(project, milestone))
+ end
+ end
+ end
+end
diff --git a/spec/helpers/todos_helper_spec.rb b/spec/helpers/todos_helper_spec.rb
index b09e1e2b83b..0811c2af891 100644
--- a/spec/helpers/todos_helper_spec.rb
+++ b/spec/helpers/todos_helper_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
describe TodosHelper do
let_it_be(:user) { create(:user) }
let_it_be(:author) { create(:user) }
- let_it_be(:issue) { create(:issue) }
+ let_it_be(:issue) { create(:issue, title: 'Issue 1') }
let_it_be(:design) { create(:design, issue: issue) }
let_it_be(:note) do
create(:note,
@@ -20,6 +20,10 @@ describe TodosHelper do
author: author,
note: note)
end
+ let_it_be(:alert_todo) do
+ alert = create(:alert_management_alert, iid: 1001)
+ create(:todo, target: alert)
+ end
describe '#todos_count_format' do
it 'shows fuzzy count for 100 or more items' do
@@ -68,6 +72,41 @@ describe TodosHelper do
end
end
+ describe '#todo_target_title' do
+ context 'when the target does not exist' do
+ let(:todo) { double('Todo', target: nil) }
+
+ it 'returns an empty string' do
+ title = helper.todo_target_title(todo)
+ expect(title).to eq("")
+ end
+ end
+
+ context 'when given a design todo' do
+ let(:todo) { design_todo }
+
+ it 'returns an empty string' do
+ title = helper.todo_target_title(todo)
+ expect(title).to eq("")
+ end
+ end
+
+ context 'when given a non-design todo' do
+ let(:todo) do
+ build_stubbed(:todo, :assigned,
+ user: user,
+ project: issue.project,
+ target: issue,
+ author: author)
+ end
+
+ it 'returns the title' do
+ title = helper.todo_target_title(todo)
+ expect(title).to eq("\"Issue 1\"")
+ end
+ end
+ end
+
describe '#todo_target_path' do
context 'when given a design' do
let(:todo) { design_todo }
@@ -80,6 +119,18 @@ describe TodosHelper do
expect(path).to eq("#{issue_path}/designs/#{design.filename}##{dom_id(design_todo.note)}")
end
end
+
+ context 'when given an alert' do
+ let(:todo) { alert_todo }
+
+ it 'responds with an appropriate path' do
+ path = helper.todo_target_path(todo)
+
+ expect(path).to eq(
+ "/#{todo.project.full_path}/-/alert_management/#{todo.target.iid}/details"
+ )
+ end
+ end
end
describe '#todo_target_type_name' do
@@ -92,6 +143,16 @@ describe TodosHelper do
expect(name).to eq('design')
end
end
+
+ context 'when given an alert todo' do
+ let(:todo) { alert_todo }
+
+ it 'responds with an appropriate target type name' do
+ name = helper.todo_target_type_name(todo)
+
+ expect(name).to eq('alert')
+ end
+ end
end
describe '#todo_types_options' do
diff --git a/spec/helpers/visibility_level_helper_spec.rb b/spec/helpers/visibility_level_helper_spec.rb
index b7a88ee5010..3b4d82c65ac 100644
--- a/spec/helpers/visibility_level_helper_spec.rb
+++ b/spec/helpers/visibility_level_helper_spec.rb
@@ -184,6 +184,84 @@ describe VisibilityLevelHelper do
end
end
+ shared_examples_for 'available visibility level' do
+ using RSpec::Parameterized::TableSyntax
+
+ let(:user) { create(:user) }
+
+ subject { helper.available_visibility_levels(form_model) }
+
+ public_vis = Gitlab::VisibilityLevel::PUBLIC
+ internal_vis = Gitlab::VisibilityLevel::INTERNAL
+ private_vis = Gitlab::VisibilityLevel::PRIVATE
+
+ where(:restricted_visibility_levels, :expected) do
+ [] | [private_vis, internal_vis, public_vis]
+ [private_vis] | [internal_vis, public_vis]
+ [private_vis, internal_vis] | [public_vis]
+ [private_vis, public_vis] | [internal_vis]
+ [internal_vis] | [private_vis, public_vis]
+ [internal_vis, private_vis] | [public_vis]
+ [internal_vis, public_vis] | [private_vis]
+ [public_vis] | [private_vis, internal_vis]
+ [public_vis, private_vis] | [internal_vis]
+ [public_vis, internal_vis] | [private_vis]
+ end
+
+ before do
+ allow(helper).to receive(:current_user) { user }
+ end
+
+ with_them do
+ before do
+ stub_application_setting(restricted_visibility_levels: restricted_visibility_levels)
+ end
+
+ it { is_expected.to eq(expected) }
+ end
+
+ it 'excludes disallowed visibility levels' do
+ stub_application_setting(restricted_visibility_levels: [])
+ allow(helper).to receive(:disallowed_visibility_level?).with(form_model, private_vis) { true }
+ allow(helper).to receive(:disallowed_visibility_level?).with(form_model, internal_vis) { false }
+ allow(helper).to receive(:disallowed_visibility_level?).with(form_model, public_vis) { false }
+
+ expect(subject).to eq([internal_vis, public_vis])
+ end
+ end
+
+ describe '#available_visibility_levels' do
+ it_behaves_like 'available visibility level' do
+ let(:form_model) { project_snippet }
+ end
+
+ it_behaves_like 'available visibility level' do
+ let(:form_model) { personal_snippet }
+ end
+
+ it_behaves_like 'available visibility level' do
+ let(:form_model) { project }
+ end
+
+ it_behaves_like 'available visibility level' do
+ let(:form_model) { group }
+ end
+ end
+
+ describe '#snippets_selected_visibility_level' do
+ let(:available_levels) { [Gitlab::VisibilityLevel::PUBLIC, Gitlab::VisibilityLevel::INTERNAL] }
+
+ it 'returns the selected visibility level' do
+ expect(helper.snippets_selected_visibility_level(available_levels, Gitlab::VisibilityLevel::PUBLIC))
+ .to eq(Gitlab::VisibilityLevel::PUBLIC)
+ end
+
+ it "fallbacks using the lowest available visibility level when selected level isn't available" do
+ expect(helper.snippets_selected_visibility_level(available_levels, Gitlab::VisibilityLevel::PRIVATE))
+ .to eq(Gitlab::VisibilityLevel::INTERNAL)
+ end
+ end
+
describe 'multiple_visibility_levels_restricted?' do
using RSpec::Parameterized::TableSyntax
diff --git a/spec/helpers/wiki_helper_spec.rb b/spec/helpers/wiki_helper_spec.rb
index 1aab01281c6..4b53823aaed 100644
--- a/spec/helpers/wiki_helper_spec.rb
+++ b/spec/helpers/wiki_helper_spec.rb
@@ -22,12 +22,12 @@ describe WikiHelper do
end
describe '#wiki_sort_controls' do
- let(:project) { create(:project) }
- let(:wiki_link) { helper.wiki_sort_controls(project, sort, direction) }
+ let(:wiki) { create(:project_wiki) }
+ let(:wiki_link) { helper.wiki_sort_controls(wiki, sort, direction) }
let(:classes) { "btn btn-default has-tooltip reverse-sort-btn qa-reverse-sort rspec-reverse-sort" }
def expected_link(sort, direction, icon_class)
- path = "/#{project.full_path}/-/wikis/pages?direction=#{direction}&sort=#{sort}"
+ path = "/#{wiki.project.full_path}/-/wikis/pages?direction=#{direction}&sort=#{sort}"
helper.link_to(path, type: 'button', class: classes, title: 'Sort direction') do
helper.sprite_icon("sort-#{icon_class}", size: 16)
diff --git a/spec/initializers/actionpack_generate_old_csrf_token_spec.rb b/spec/initializers/actionpack_generate_old_csrf_token_spec.rb
new file mode 100644
index 00000000000..036f52398bb
--- /dev/null
+++ b/spec/initializers/actionpack_generate_old_csrf_token_spec.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe ActionController::Base, 'CSRF token generation patch', type: :controller do # rubocop:disable RSpec/FilePath
+ let(:fixed_seed) { SecureRandom.random_bytes(described_class::AUTHENTICITY_TOKEN_LENGTH) }
+
+ context 'global_csrf_token feature flag is enabled' do
+ it 'generates 6.0.3.1 style CSRF token', :aggregate_failures do
+ generated_token = controller.send(:form_authenticity_token)
+
+ expect(valid_authenticity_token?(generated_token)).to be_truthy
+ expect(compare_with_real_token(generated_token)).to be_falsey
+ expect(compare_with_global_token(generated_token)).to be_truthy
+ end
+ end
+
+ context 'global_csrf_token feature flag is disabled' do
+ before do
+ stub_feature_flags(global_csrf_token: false)
+ end
+
+ it 'generates 6.0.3 style CSRF token', :aggregate_failures do
+ generated_token = controller.send(:form_authenticity_token)
+
+ expect(valid_authenticity_token?(generated_token)).to be_truthy
+ expect(compare_with_real_token(generated_token)).to be_truthy
+ expect(compare_with_global_token(generated_token)).to be_falsey
+ end
+ end
+
+ def compare_with_global_token(token)
+ unmasked_token = controller.send :unmask_token, Base64.strict_decode64(token)
+
+ controller.send(:compare_with_global_token, unmasked_token, session)
+ end
+
+ def compare_with_real_token(token)
+ unmasked_token = controller.send :unmask_token, Base64.strict_decode64(token)
+
+ controller.send(:compare_with_real_token, unmasked_token, session)
+ end
+
+ def valid_authenticity_token?(token)
+ controller.send(:valid_authenticity_token?, session, token)
+ end
+end
diff --git a/spec/initializers/database_config_spec.rb b/spec/initializers/database_config_spec.rb
index 85577ce007a..7c0b280fdaf 100644
--- a/spec/initializers/database_config_spec.rb
+++ b/spec/initializers/database_config_spec.rb
@@ -48,6 +48,21 @@ describe 'Database config initializer' do
expect { subject }.not_to change { Gitlab::Database.config['pool'] }
end
end
+
+ context "when specifying headroom through an ENV variable" do
+ let(:headroom) { 10 }
+
+ before do
+ stub_database_config(pool_size: 1)
+ stub_env("DB_POOL_HEADROOM", headroom)
+ end
+
+ it "adds headroom on top of the calculated size" do
+ expect { subject }.to change { Gitlab::Database.config['pool'] }
+ .from(1)
+ .to(max_threads + headroom)
+ end
+ end
end
context "when using single-threaded runtime" do
diff --git a/spec/initializers/google_api_client_spec.rb b/spec/initializers/google_api_client_spec.rb
deleted file mode 100644
index 44a1bc0836c..00000000000
--- a/spec/initializers/google_api_client_spec.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe './config/initializers/google_api_client.rb' do
- subject { Google::Apis::ContainerV1beta1 }
-
- it 'is needed' do |example|
- is_expected.not_to be_const_defined(:CloudRunConfig),
- <<-MSG.strip_heredoc
- The google-api-client gem has been upgraded!
- Remove:
- #{example.example_group.description}
- #{example.file_path}
- MSG
- end
-end
diff --git a/spec/initializers/lograge_spec.rb b/spec/initializers/lograge_spec.rb
index c243217d2a2..f283ac100a9 100644
--- a/spec/initializers/lograge_spec.rb
+++ b/spec/initializers/lograge_spec.rb
@@ -99,7 +99,7 @@ describe 'lograge', type: :request do
end
context 'with a log subscriber' do
- let(:subscriber) { Lograge::RequestLogSubscriber.new }
+ let(:subscriber) { Lograge::LogSubscribers::ActionController.new }
let(:event) do
ActiveSupport::Notifications::Event.new(
diff --git a/spec/javascripts/awards_handler_spec.js b/spec/javascripts/awards_handler_spec.js
deleted file mode 100644
index 02200f77ad7..00000000000
--- a/spec/javascripts/awards_handler_spec.js
+++ /dev/null
@@ -1,400 +0,0 @@
-import $ from 'jquery';
-import Cookies from 'js-cookie';
-import loadAwardsHandler from '~/awards_handler';
-import '~/lib/utils/common_utils';
-
-window.gl = window.gl || {};
-window.gon = window.gon || {};
-
-let openAndWaitForEmojiMenu;
-let awardsHandler = null;
-const urlRoot = gon.relative_url_root;
-
-const lazyAssert = function(done, assertFn) {
- setTimeout(function() {
- assertFn();
- done();
- // Maybe jasmine.clock here?
- }, 333);
-};
-
-describe('AwardsHandler', function() {
- preloadFixtures('snippets/show.html');
- beforeEach(function(done) {
- loadFixtures('snippets/show.html');
- loadAwardsHandler(true)
- .then(obj => {
- awardsHandler = obj;
- spyOn(awardsHandler, 'postEmoji').and.callFake((button, url, emoji, cb) => cb());
- done();
- })
- .catch(fail);
-
- let isEmojiMenuBuilt = false;
- openAndWaitForEmojiMenu = function() {
- return new Promise(resolve => {
- if (isEmojiMenuBuilt) {
- resolve();
- } else {
- $('.js-add-award')
- .eq(0)
- .click();
- const $menu = $('.emoji-menu');
- $menu.one('build-emoji-menu-finish', () => {
- isEmojiMenuBuilt = true;
- resolve();
- });
- }
- });
- };
- });
-
- afterEach(function() {
- // restore original url root value
- gon.relative_url_root = urlRoot;
-
- // Undo what we did to the shared <body>
- $('body').removeAttr('data-page');
-
- awardsHandler.destroy();
- });
-
- describe('::showEmojiMenu', function() {
- it('should show emoji menu when Add emoji button clicked', function(done) {
- $('.js-add-award')
- .eq(0)
- .click();
- lazyAssert(done, function() {
- const $emojiMenu = $('.emoji-menu');
-
- expect($emojiMenu.length).toBe(1);
- expect($emojiMenu.hasClass('is-visible')).toBe(true);
- expect($emojiMenu.find('.js-emoji-menu-search').length).toBe(1);
- expect($('.js-awards-block.current').length).toBe(1);
- });
- });
-
- it('should also show emoji menu for the smiley icon in notes', function(done) {
- $('.js-add-award.note-action-button').click();
- lazyAssert(done, function() {
- const $emojiMenu = $('.emoji-menu');
-
- expect($emojiMenu.length).toBe(1);
- });
- });
-
- it('should remove emoji menu when body is clicked', function(done) {
- $('.js-add-award')
- .eq(0)
- .click();
- lazyAssert(done, function() {
- const $emojiMenu = $('.emoji-menu');
- $('body').click();
-
- expect($emojiMenu.length).toBe(1);
- expect($emojiMenu.hasClass('is-visible')).toBe(false);
- expect($('.js-awards-block.current').length).toBe(0);
- });
- });
-
- it('should not remove emoji menu when search is clicked', function(done) {
- $('.js-add-award')
- .eq(0)
- .click();
- lazyAssert(done, function() {
- const $emojiMenu = $('.emoji-menu');
- $('.emoji-search').click();
-
- expect($emojiMenu.length).toBe(1);
- expect($emojiMenu.hasClass('is-visible')).toBe(true);
- expect($('.js-awards-block.current').length).toBe(1);
- });
- });
- });
-
- describe('::addAwardToEmojiBar', function() {
- it('should add emoji to votes block', function() {
- const $votesBlock = $('.js-awards-block').eq(0);
- awardsHandler.addAwardToEmojiBar($votesBlock, 'heart', false);
- const $emojiButton = $votesBlock.find('[data-name=heart]');
-
- expect($emojiButton.length).toBe(1);
- expect($emojiButton.next('.js-counter').text()).toBe('1');
- expect($votesBlock.hasClass('hidden')).toBe(false);
- });
-
- it('should remove the emoji when we click again', function() {
- const $votesBlock = $('.js-awards-block').eq(0);
- awardsHandler.addAwardToEmojiBar($votesBlock, 'heart', false);
- awardsHandler.addAwardToEmojiBar($votesBlock, 'heart', false);
- const $emojiButton = $votesBlock.find('[data-name=heart]');
-
- expect($emojiButton.length).toBe(0);
- });
-
- it('should decrement the emoji counter', function() {
- const $votesBlock = $('.js-awards-block').eq(0);
- awardsHandler.addAwardToEmojiBar($votesBlock, 'heart', false);
- const $emojiButton = $votesBlock.find('[data-name=heart]');
- $emojiButton.next('.js-counter').text(5);
- awardsHandler.addAwardToEmojiBar($votesBlock, 'heart', false);
-
- expect($emojiButton.length).toBe(1);
- expect($emojiButton.next('.js-counter').text()).toBe('4');
- });
- });
-
- describe('::userAuthored', function() {
- it('should update tooltip to user authored title', function() {
- const $votesBlock = $('.js-awards-block').eq(0);
- const $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
- $thumbsUpEmoji.attr('data-title', 'sam');
- awardsHandler.userAuthored($thumbsUpEmoji);
-
- expect($thumbsUpEmoji.data('originalTitle')).toBe(
- 'You cannot vote on your own issue, MR and note',
- );
- });
-
- it('should restore tooltip back to initial vote list', function() {
- jasmine.clock().install();
- const $votesBlock = $('.js-awards-block').eq(0);
- const $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
- $thumbsUpEmoji.attr('data-title', 'sam');
- awardsHandler.userAuthored($thumbsUpEmoji);
- jasmine.clock().tick(2801);
- jasmine.clock().uninstall();
-
- expect($thumbsUpEmoji.data('originalTitle')).toBe('sam');
- });
- });
-
- describe('::getAwardUrl', function() {
- it('returns the url for request', function() {
- expect(awardsHandler.getAwardUrl()).toBe('http://test.host/snippets/1/toggle_award_emoji');
- });
- });
-
- describe('::addAward and ::checkMutuality', function() {
- it('should handle :+1: and :-1: mutuality', function() {
- const awardUrl = awardsHandler.getAwardUrl();
- const $votesBlock = $('.js-awards-block').eq(0);
- const $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
- const $thumbsDownEmoji = $votesBlock.find('[data-name=thumbsdown]').parent();
- awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false);
-
- expect($thumbsUpEmoji.hasClass('active')).toBe(true);
- expect($thumbsDownEmoji.hasClass('active')).toBe(false);
- $thumbsUpEmoji.tooltip();
- $thumbsDownEmoji.tooltip();
- awardsHandler.addAward($votesBlock, awardUrl, 'thumbsdown', true);
-
- expect($thumbsUpEmoji.hasClass('active')).toBe(false);
- expect($thumbsDownEmoji.hasClass('active')).toBe(true);
- });
- });
-
- describe('::removeEmoji', function() {
- it('should remove emoji', function() {
- const awardUrl = awardsHandler.getAwardUrl();
- const $votesBlock = $('.js-awards-block').eq(0);
- awardsHandler.addAward($votesBlock, awardUrl, 'fire', false);
-
- expect($votesBlock.find('[data-name=fire]').length).toBe(1);
- awardsHandler.removeEmoji($votesBlock.find('[data-name=fire]').closest('button'));
-
- expect($votesBlock.find('[data-name=fire]').length).toBe(0);
- });
- });
-
- describe('::addYouToUserList', function() {
- it('should prepend "You" to the award tooltip', function() {
- const awardUrl = awardsHandler.getAwardUrl();
- const $votesBlock = $('.js-awards-block').eq(0);
- const $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
- $thumbsUpEmoji.attr('data-title', 'sam, jerry, max, and andy');
- awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false);
- $thumbsUpEmoji.tooltip();
-
- expect($thumbsUpEmoji.data('originalTitle')).toBe('You, sam, jerry, max, and andy');
- });
-
- it('handles the special case where "You" is not cleanly comma separated', function() {
- const awardUrl = awardsHandler.getAwardUrl();
- const $votesBlock = $('.js-awards-block').eq(0);
- const $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
- $thumbsUpEmoji.attr('data-title', 'sam');
- awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false);
- $thumbsUpEmoji.tooltip();
-
- expect($thumbsUpEmoji.data('originalTitle')).toBe('You and sam');
- });
- });
-
- describe('::removeYouToUserList', function() {
- it('removes "You" from the front of the tooltip', function() {
- const awardUrl = awardsHandler.getAwardUrl();
- const $votesBlock = $('.js-awards-block').eq(0);
- const $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
- $thumbsUpEmoji.attr('data-title', 'You, sam, jerry, max, and andy');
- $thumbsUpEmoji.addClass('active');
- awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false);
- $thumbsUpEmoji.tooltip();
-
- expect($thumbsUpEmoji.data('originalTitle')).toBe('sam, jerry, max, and andy');
- });
-
- it('handles the special case where "You" is not cleanly comma separated', function() {
- const awardUrl = awardsHandler.getAwardUrl();
- const $votesBlock = $('.js-awards-block').eq(0);
- const $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
- $thumbsUpEmoji.attr('data-title', 'You and sam');
- $thumbsUpEmoji.addClass('active');
- awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false);
- $thumbsUpEmoji.tooltip();
-
- expect($thumbsUpEmoji.data('originalTitle')).toBe('sam');
- });
- });
-
- describe('::searchEmojis', () => {
- it('should filter the emoji', function(done) {
- openAndWaitForEmojiMenu()
- .then(() => {
- expect($('[data-name=angel]').is(':visible')).toBe(true);
- expect($('[data-name=anger]').is(':visible')).toBe(true);
- awardsHandler.searchEmojis('ali');
-
- expect($('[data-name=angel]').is(':visible')).toBe(false);
- expect($('[data-name=anger]').is(':visible')).toBe(false);
- expect($('[data-name=alien]').is(':visible')).toBe(true);
- expect($('.js-emoji-menu-search').val()).toBe('ali');
- })
- .then(done)
- .catch(err => {
- done.fail(`Failed to open and build emoji menu: ${err.message}`);
- });
- });
-
- it('should clear the search when searching for nothing', function(done) {
- openAndWaitForEmojiMenu()
- .then(() => {
- awardsHandler.searchEmojis('ali');
-
- expect($('[data-name=angel]').is(':visible')).toBe(false);
- expect($('[data-name=anger]').is(':visible')).toBe(false);
- expect($('[data-name=alien]').is(':visible')).toBe(true);
- awardsHandler.searchEmojis('');
-
- expect($('[data-name=angel]').is(':visible')).toBe(true);
- expect($('[data-name=anger]').is(':visible')).toBe(true);
- expect($('[data-name=alien]').is(':visible')).toBe(true);
- expect($('.js-emoji-menu-search').val()).toBe('');
- })
- .then(done)
- .catch(err => {
- done.fail(`Failed to open and build emoji menu: ${err.message}`);
- });
- });
- });
-
- describe('emoji menu', function() {
- const emojiSelector = '[data-name="sunglasses"]';
- const openEmojiMenuAndAddEmoji = function() {
- return openAndWaitForEmojiMenu().then(() => {
- const $menu = $('.emoji-menu');
- const $block = $('.js-awards-block');
- const $emoji = $menu.find(`.emoji-menu-list:not(.frequent-emojis) ${emojiSelector}`);
-
- expect($emoji.length).toBe(1);
- expect($block.find(emojiSelector).length).toBe(0);
- $emoji.click();
-
- expect($menu.hasClass('.is-visible')).toBe(false);
- expect($block.find(emojiSelector).length).toBe(1);
- });
- };
-
- it('should add selected emoji to awards block', function(done) {
- openEmojiMenuAndAddEmoji()
- .then(done)
- .catch(err => {
- done.fail(`Failed to open and build emoji menu: ${err.message}`);
- });
- });
-
- it('should remove already selected emoji', function(done) {
- openEmojiMenuAndAddEmoji()
- .then(() => {
- $('.js-add-award')
- .eq(0)
- .click();
- const $block = $('.js-awards-block');
- const $emoji = $('.emoji-menu').find(
- `.emoji-menu-list:not(.frequent-emojis) ${emojiSelector}`,
- );
- $emoji.click();
-
- expect($block.find(emojiSelector).length).toBe(0);
- })
- .then(done)
- .catch(err => {
- done.fail(`Failed to open and build emoji menu: ${err.message}`);
- });
- });
- });
-
- describe('frequently used emojis', function() {
- beforeEach(() => {
- // Clear it out
- Cookies.set('frequently_used_emojis', '');
- });
-
- it('shouldn\'t have any "Frequently used" heading if no frequently used emojis', function(done) {
- return openAndWaitForEmojiMenu()
- .then(() => {
- const emojiMenu = document.querySelector('.emoji-menu');
- Array.prototype.forEach.call(emojiMenu.querySelectorAll('.emoji-menu-title'), title => {
- expect(title.textContent.trim().toLowerCase()).not.toBe('frequently used');
- });
- })
- .then(done)
- .catch(err => {
- done.fail(`Failed to open and build emoji menu: ${err.message}`);
- });
- });
-
- it('should have any frequently used section when there are frequently used emojis', function(done) {
- awardsHandler.addEmojiToFrequentlyUsedList('8ball');
-
- return openAndWaitForEmojiMenu()
- .then(() => {
- const emojiMenu = document.querySelector('.emoji-menu');
- const hasFrequentlyUsedHeading = Array.prototype.some.call(
- emojiMenu.querySelectorAll('.emoji-menu-title'),
- title => title.textContent.trim().toLowerCase() === 'frequently used',
- );
-
- expect(hasFrequentlyUsedHeading).toBe(true);
- })
- .then(done)
- .catch(err => {
- done.fail(`Failed to open and build emoji menu: ${err.message}`);
- });
- });
-
- it('should disregard invalid frequently used emoji that are being attempted to be added', function() {
- awardsHandler.addEmojiToFrequentlyUsedList('8ball');
- awardsHandler.addEmojiToFrequentlyUsedList('invalid_emoji');
- awardsHandler.addEmojiToFrequentlyUsedList('grinning');
-
- expect(awardsHandler.getFrequentlyUsedEmojis()).toEqual(['8ball', 'grinning']);
- });
-
- it('should disregard invalid frequently used emoji already set in cookie', function() {
- Cookies.set('frequently_used_emojis', '8ball,invalid_emoji,grinning');
-
- expect(awardsHandler.getFrequentlyUsedEmojis()).toEqual(['8ball', 'grinning']);
- });
- });
-});
diff --git a/spec/javascripts/behaviors/copy_as_gfm_spec.js b/spec/javascripts/behaviors/copy_as_gfm_spec.js
deleted file mode 100644
index d653fca0988..00000000000
--- a/spec/javascripts/behaviors/copy_as_gfm_spec.js
+++ /dev/null
@@ -1,125 +0,0 @@
-import initCopyAsGFM, { CopyAsGFM } from '~/behaviors/markdown/copy_as_gfm';
-
-describe('CopyAsGFM', () => {
- describe('CopyAsGFM.pasteGFM', () => {
- function callPasteGFM() {
- const e = {
- originalEvent: {
- clipboardData: {
- getData(mimeType) {
- // When GFM code is copied, we put the regular plain text
- // on the clipboard as `text/plain`, and the GFM as `text/x-gfm`.
- // This emulates the behavior of `getData` with that data.
- if (mimeType === 'text/plain') {
- return 'code';
- }
- if (mimeType === 'text/x-gfm') {
- return '`code`';
- }
- return null;
- },
- },
- },
- preventDefault() {},
- };
-
- CopyAsGFM.pasteGFM(e);
- }
-
- it('wraps pasted code when not already in code tags', () => {
- spyOn(window.gl.utils, 'insertText').and.callFake((el, textFunc) => {
- const insertedText = textFunc('This is code: ', '');
-
- expect(insertedText).toEqual('`code`');
- });
-
- callPasteGFM();
- });
-
- it('does not wrap pasted code when already in code tags', () => {
- spyOn(window.gl.utils, 'insertText').and.callFake((el, textFunc) => {
- const insertedText = textFunc('This is code: `', '`');
-
- expect(insertedText).toEqual('code');
- });
-
- callPasteGFM();
- });
- });
-
- describe('CopyAsGFM.copyGFM', () => {
- // Stub getSelection to return a purpose-built object.
- const stubSelection = (html, parentNode) => ({
- getRangeAt: () => ({
- commonAncestorContainer: { tagName: parentNode },
- cloneContents: () => {
- const fragment = document.createDocumentFragment();
- const node = document.createElement('div');
- node.innerHTML = html;
- Array.from(node.childNodes).forEach(item => fragment.appendChild(item));
- return fragment;
- },
- }),
- rangeCount: 1,
- });
-
- const clipboardData = {
- setData() {},
- };
-
- const simulateCopy = () => {
- const e = {
- originalEvent: {
- clipboardData,
- },
- preventDefault() {},
- stopPropagation() {},
- };
- CopyAsGFM.copyAsGFM(e, CopyAsGFM.transformGFMSelection);
- return clipboardData;
- };
-
- beforeAll(done => {
- initCopyAsGFM();
-
- // Fake call to nodeToGfm so the import of lazy bundle happened
- CopyAsGFM.nodeToGFM(document.createElement('div'))
- .then(() => {
- done();
- })
- .catch(done.fail);
- });
-
- beforeEach(() => spyOn(clipboardData, 'setData'));
-
- describe('list handling', () => {
- it('uses correct gfm for unordered lists', done => {
- const selection = stubSelection('<li>List Item1</li><li>List Item2</li>\n', 'UL');
-
- spyOn(window, 'getSelection').and.returnValue(selection);
- simulateCopy();
-
- setTimeout(() => {
- const expectedGFM = '* List Item1\n* List Item2';
-
- expect(clipboardData.setData).toHaveBeenCalledWith('text/x-gfm', expectedGFM);
- done();
- });
- });
-
- it('uses correct gfm for ordered lists', done => {
- const selection = stubSelection('<li>List Item1</li><li>List Item2</li>\n', 'OL');
-
- spyOn(window, 'getSelection').and.returnValue(selection);
- simulateCopy();
-
- setTimeout(() => {
- const expectedGFM = '1. List Item1\n1. List Item2';
-
- expect(clipboardData.setData).toHaveBeenCalledWith('text/x-gfm', expectedGFM);
- done();
- });
- });
- });
- });
-});
diff --git a/spec/javascripts/behaviors/gl_emoji/unicode_support_map_spec.js b/spec/javascripts/behaviors/gl_emoji/unicode_support_map_spec.js
deleted file mode 100644
index f656b97fec2..00000000000
--- a/spec/javascripts/behaviors/gl_emoji/unicode_support_map_spec.js
+++ /dev/null
@@ -1,52 +0,0 @@
-import getUnicodeSupportMap from '~/emoji/support/unicode_support_map';
-import AccessorUtilities from '~/lib/utils/accessor';
-
-describe('Unicode Support Map', () => {
- describe('getUnicodeSupportMap', () => {
- const stringSupportMap = 'stringSupportMap';
-
- beforeEach(() => {
- spyOn(AccessorUtilities, 'isLocalStorageAccessSafe');
- spyOn(window.localStorage, 'getItem');
- spyOn(window.localStorage, 'setItem');
- spyOn(JSON, 'parse');
- spyOn(JSON, 'stringify').and.returnValue(stringSupportMap);
- });
-
- describe('if isLocalStorageAvailable is `true`', function() {
- beforeEach(() => {
- AccessorUtilities.isLocalStorageAccessSafe.and.returnValue(true);
-
- getUnicodeSupportMap();
- });
-
- it('should call .getItem and .setItem', () => {
- const getArgs = window.localStorage.getItem.calls.allArgs();
- const setArgs = window.localStorage.setItem.calls.allArgs();
-
- expect(getArgs[0][0]).toBe('gl-emoji-version');
- expect(getArgs[1][0]).toBe('gl-emoji-user-agent');
-
- expect(setArgs[0][0]).toBe('gl-emoji-version');
- expect(setArgs[0][1]).toBe('0.2.0');
- expect(setArgs[1][0]).toBe('gl-emoji-user-agent');
- expect(setArgs[1][1]).toBe(navigator.userAgent);
- expect(setArgs[2][0]).toBe('gl-emoji-unicode-support-map');
- expect(setArgs[2][1]).toBe(stringSupportMap);
- });
- });
-
- describe('if isLocalStorageAvailable is `false`', function() {
- beforeEach(() => {
- AccessorUtilities.isLocalStorageAccessSafe.and.returnValue(false);
-
- getUnicodeSupportMap();
- });
-
- it('should not call .getItem or .setItem', () => {
- expect(window.localStorage.getItem.calls.count()).toBe(1);
- expect(window.localStorage.setItem).not.toHaveBeenCalled();
- });
- });
- });
-});
diff --git a/spec/javascripts/behaviors/shortcuts/shortcuts_issuable_spec.js b/spec/javascripts/behaviors/shortcuts/shortcuts_issuable_spec.js
deleted file mode 100644
index f6232026915..00000000000
--- a/spec/javascripts/behaviors/shortcuts/shortcuts_issuable_spec.js
+++ /dev/null
@@ -1,315 +0,0 @@
-/* eslint-disable
- no-underscore-dangle
-*/
-
-import $ from 'jquery';
-import initCopyAsGFM, { CopyAsGFM } from '~/behaviors/markdown/copy_as_gfm';
-import ShortcutsIssuable from '~/behaviors/shortcuts/shortcuts_issuable';
-
-const FORM_SELECTOR = '.js-main-target-form .js-vue-comment-form';
-
-describe('ShortcutsIssuable', function() {
- const fixtureName = 'snippets/show.html';
- preloadFixtures(fixtureName);
-
- beforeAll(done => {
- initCopyAsGFM();
-
- // Fake call to nodeToGfm so the import of lazy bundle happened
- CopyAsGFM.nodeToGFM(document.createElement('div'))
- .then(() => {
- done();
- })
- .catch(done.fail);
- });
-
- beforeEach(() => {
- loadFixtures(fixtureName);
- $('body').append(
- `<div class="js-main-target-form">
- <textare class="js-vue-comment-form"></textare>
- </div>`,
- );
- document.querySelector('.js-new-note-form').classList.add('js-main-target-form');
- this.shortcut = new ShortcutsIssuable(true);
- });
-
- afterEach(() => {
- $(FORM_SELECTOR).remove();
- });
-
- describe('replyWithSelectedText', () => {
- // Stub window.gl.utils.getSelectedFragment to return a node with the provided HTML.
- const stubSelection = (html, invalidNode) => {
- ShortcutsIssuable.__Rewire__('getSelectedFragment', () => {
- const documentFragment = document.createDocumentFragment();
- const node = document.createElement('div');
-
- node.innerHTML = html;
- if (!invalidNode) node.className = 'md';
-
- documentFragment.appendChild(node);
- return documentFragment;
- });
- };
-
- describe('with empty selection', () => {
- it('does not return an error', () => {
- ShortcutsIssuable.replyWithSelectedText(true);
-
- expect($(FORM_SELECTOR).val()).toBe('');
- });
-
- it('triggers `focus`', () => {
- const spy = spyOn(document.querySelector(FORM_SELECTOR), 'focus');
- ShortcutsIssuable.replyWithSelectedText(true);
-
- expect(spy).toHaveBeenCalled();
- });
- });
-
- describe('with any selection', () => {
- beforeEach(() => {
- stubSelection('<p>Selected text.</p>');
- });
-
- it('leaves existing input intact', done => {
- $(FORM_SELECTOR).val('This text was already here.');
-
- expect($(FORM_SELECTOR).val()).toBe('This text was already here.');
-
- ShortcutsIssuable.replyWithSelectedText(true);
-
- setTimeout(() => {
- expect($(FORM_SELECTOR).val()).toBe(
- 'This text was already here.\n\n> Selected text.\n\n',
- );
- done();
- });
- });
-
- it('triggers `input`', done => {
- let triggered = false;
- $(FORM_SELECTOR).on('input', () => {
- triggered = true;
- });
-
- ShortcutsIssuable.replyWithSelectedText(true);
-
- setTimeout(() => {
- expect(triggered).toBe(true);
- done();
- });
- });
-
- it('triggers `focus`', done => {
- const spy = spyOn(document.querySelector(FORM_SELECTOR), 'focus');
- ShortcutsIssuable.replyWithSelectedText(true);
-
- setTimeout(() => {
- expect(spy).toHaveBeenCalled();
- done();
- });
- });
- });
-
- describe('with a one-line selection', () => {
- it('quotes the selection', done => {
- stubSelection('<p>This text has been selected.</p>');
- ShortcutsIssuable.replyWithSelectedText(true);
-
- setTimeout(() => {
- expect($(FORM_SELECTOR).val()).toBe('> This text has been selected.\n\n');
- done();
- });
- });
- });
-
- describe('with a multi-line selection', () => {
- it('quotes the selected lines as a group', done => {
- stubSelection(
- '<p>Selected line one.</p>\n<p>Selected line two.</p>\n<p>Selected line three.</p>',
- );
- ShortcutsIssuable.replyWithSelectedText(true);
-
- setTimeout(() => {
- expect($(FORM_SELECTOR).val()).toBe(
- '> Selected line one.\n>\n> Selected line two.\n>\n> Selected line three.\n\n',
- );
- done();
- });
- });
- });
-
- describe('with an invalid selection', () => {
- beforeEach(() => {
- stubSelection('<p>Selected text.</p>', true);
- });
-
- it('does not add anything to the input', done => {
- ShortcutsIssuable.replyWithSelectedText(true);
-
- setTimeout(() => {
- expect($(FORM_SELECTOR).val()).toBe('');
- done();
- });
- });
-
- it('triggers `focus`', done => {
- const spy = spyOn(document.querySelector(FORM_SELECTOR), 'focus');
- ShortcutsIssuable.replyWithSelectedText(true);
-
- setTimeout(() => {
- expect(spy).toHaveBeenCalled();
- done();
- });
- });
- });
-
- describe('with a semi-valid selection', () => {
- beforeEach(() => {
- stubSelection('<div class="md">Selected text.</div><p>Invalid selected text.</p>', true);
- });
-
- it('only adds the valid part to the input', done => {
- ShortcutsIssuable.replyWithSelectedText(true);
-
- setTimeout(() => {
- expect($(FORM_SELECTOR).val()).toBe('> Selected text.\n\n');
- done();
- });
- });
-
- it('triggers `focus`', done => {
- const spy = spyOn(document.querySelector(FORM_SELECTOR), 'focus');
- ShortcutsIssuable.replyWithSelectedText(true);
-
- setTimeout(() => {
- expect(spy).toHaveBeenCalled();
- done();
- });
- });
-
- it('triggers `input`', done => {
- let triggered = false;
- $(FORM_SELECTOR).on('input', () => {
- triggered = true;
- });
-
- ShortcutsIssuable.replyWithSelectedText(true);
-
- setTimeout(() => {
- expect(triggered).toBe(true);
- done();
- });
- });
- });
-
- describe('with a selection in a valid block', () => {
- beforeEach(() => {
- ShortcutsIssuable.__Rewire__('getSelectedFragment', () => {
- const documentFragment = document.createDocumentFragment();
- const node = document.createElement('div');
- const originalNode = document.createElement('body');
- originalNode.innerHTML = `<div class="issue">
- <div class="otherElem">Text...</div>
- <div class="md"><p><em>Selected text.</em></p></div>
- </div>`;
- documentFragment.originalNodes = [originalNode.querySelector('em')];
-
- node.innerHTML = '<em>Selected text.</em>';
-
- documentFragment.appendChild(node);
-
- return documentFragment;
- });
- });
-
- it('adds the quoted selection to the input', done => {
- ShortcutsIssuable.replyWithSelectedText(true);
-
- setTimeout(() => {
- expect($(FORM_SELECTOR).val()).toBe('> *Selected text.*\n\n');
- done();
- });
- });
-
- it('triggers `focus`', done => {
- const spy = spyOn(document.querySelector(FORM_SELECTOR), 'focus');
- ShortcutsIssuable.replyWithSelectedText(true);
-
- setTimeout(() => {
- expect(spy).toHaveBeenCalled();
- done();
- });
- });
-
- it('triggers `input`', done => {
- let triggered = false;
- $(FORM_SELECTOR).on('input', () => {
- triggered = true;
- });
-
- ShortcutsIssuable.replyWithSelectedText(true);
-
- setTimeout(() => {
- expect(triggered).toBe(true);
- done();
- });
- });
- });
-
- describe('with a selection in an invalid block', () => {
- beforeEach(() => {
- ShortcutsIssuable.__Rewire__('getSelectedFragment', () => {
- const documentFragment = document.createDocumentFragment();
- const node = document.createElement('div');
- const originalNode = document.createElement('body');
- originalNode.innerHTML = `<div class="issue">
- <div class="otherElem"><div><b>Selected text.</b></div></div>
- <div class="md"><p><em>Valid text</em></p></div>
- </div>`;
- documentFragment.originalNodes = [originalNode.querySelector('b')];
-
- node.innerHTML = '<b>Selected text.</b>';
-
- documentFragment.appendChild(node);
-
- return documentFragment;
- });
- });
-
- it('does not add anything to the input', done => {
- ShortcutsIssuable.replyWithSelectedText(true);
-
- setTimeout(() => {
- expect($(FORM_SELECTOR).val()).toBe('');
- done();
- });
- });
-
- it('triggers `focus`', done => {
- const spy = spyOn(document.querySelector(FORM_SELECTOR), 'focus');
- ShortcutsIssuable.replyWithSelectedText(true);
-
- setTimeout(() => {
- expect(spy).toHaveBeenCalled();
- done();
- });
- });
- });
-
- describe('with a valid selection with no text content', () => {
- it('returns the proper markdown', done => {
- stubSelection('<img src="foo" alt="image" />');
- ShortcutsIssuable.replyWithSelectedText(true);
-
- setTimeout(() => {
- expect($(FORM_SELECTOR).val()).toBe('> ![image](http://localhost:9876/foo)\n\n');
-
- done();
- });
- });
- });
- });
-});
diff --git a/spec/javascripts/collapsed_sidebar_todo_spec.js b/spec/javascripts/collapsed_sidebar_todo_spec.js
deleted file mode 100644
index f2eb08fa198..00000000000
--- a/spec/javascripts/collapsed_sidebar_todo_spec.js
+++ /dev/null
@@ -1,171 +0,0 @@
-/* eslint-disable no-new */
-import { clone } from 'lodash';
-import MockAdapter from 'axios-mock-adapter';
-import axios from '~/lib/utils/axios_utils';
-import Sidebar from '~/right_sidebar';
-import timeoutPromise from './helpers/set_timeout_promise_helper';
-
-describe('Issuable right sidebar collapsed todo toggle', () => {
- const fixtureName = 'issues/open-issue.html';
- const jsonFixtureName = 'todos/todos.json';
- let mock;
-
- preloadFixtures(fixtureName);
- preloadFixtures(jsonFixtureName);
-
- beforeEach(() => {
- const todoData = getJSONFixture(jsonFixtureName);
- new Sidebar();
- loadFixtures(fixtureName);
-
- document.querySelector('.js-right-sidebar').classList.toggle('right-sidebar-expanded');
- document.querySelector('.js-right-sidebar').classList.toggle('right-sidebar-collapsed');
-
- mock = new MockAdapter(axios);
-
- mock.onPost(`${gl.TEST_HOST}/frontend-fixtures/issues-project/todos`).reply(() => {
- const response = clone(todoData);
-
- return [200, response];
- });
-
- mock.onDelete(/(.*)\/dashboard\/todos\/\d+$/).reply(() => {
- const response = clone(todoData);
- delete response.delete_path;
-
- return [200, response];
- });
- });
-
- afterEach(() => {
- mock.restore();
- });
-
- it('shows add todo button', () => {
- expect(document.querySelector('.js-issuable-todo.sidebar-collapsed-icon')).not.toBeNull();
-
- expect(
- document
- .querySelector('.js-issuable-todo.sidebar-collapsed-icon svg use')
- .getAttribute('xlink:href'),
- ).toContain('todo-add');
-
- expect(
- document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .todo-undone'),
- ).toBeNull();
- });
-
- it('sets default tooltip title', () => {
- expect(
- document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').getAttribute('title'),
- ).toBe('Add a To Do');
- });
-
- it('toggle todo state', done => {
- document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
-
- setTimeout(() => {
- expect(
- document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .todo-undone'),
- ).not.toBeNull();
-
- expect(
- document
- .querySelector('.js-issuable-todo.sidebar-collapsed-icon svg.todo-undone use')
- .getAttribute('xlink:href'),
- ).toContain('todo-done');
-
- done();
- });
- });
-
- it('toggle todo state of expanded todo toggle', done => {
- document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
-
- setTimeout(() => {
- expect(
- document.querySelector('.issuable-sidebar-header .js-issuable-todo').textContent.trim(),
- ).toBe('Mark as done');
-
- done();
- });
- });
-
- it('toggles todo button tooltip', done => {
- document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
-
- setTimeout(() => {
- expect(
- document
- .querySelector('.js-issuable-todo.sidebar-collapsed-icon')
- .getAttribute('data-original-title'),
- ).toBe('Mark as done');
-
- done();
- });
- });
-
- it('marks todo as done', done => {
- document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
-
- timeoutPromise()
- .then(() => {
- expect(
- document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .todo-undone'),
- ).not.toBeNull();
-
- document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
- })
- .then(timeoutPromise)
- .then(() => {
- expect(
- document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .todo-undone'),
- ).toBeNull();
-
- expect(
- document.querySelector('.issuable-sidebar-header .js-issuable-todo').textContent.trim(),
- ).toBe('Add a To Do');
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('updates aria-label to Mark as done', done => {
- document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
-
- setTimeout(() => {
- expect(
- document
- .querySelector('.js-issuable-todo.sidebar-collapsed-icon')
- .getAttribute('aria-label'),
- ).toBe('Mark as done');
-
- done();
- });
- });
-
- it('updates aria-label to add todo', done => {
- document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
-
- timeoutPromise()
- .then(() => {
- expect(
- document
- .querySelector('.js-issuable-todo.sidebar-collapsed-icon')
- .getAttribute('aria-label'),
- ).toBe('Mark as done');
-
- document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
- })
- .then(timeoutPromise)
- .then(() => {
- expect(
- document
- .querySelector('.js-issuable-todo.sidebar-collapsed-icon')
- .getAttribute('aria-label'),
- ).toBe('Add a To Do');
- })
- .then(done)
- .catch(done.fail);
- });
-});
diff --git a/spec/javascripts/comment_type_toggle_spec.js b/spec/javascripts/comment_type_toggle_spec.js
deleted file mode 100644
index 8b1217a000f..00000000000
--- a/spec/javascripts/comment_type_toggle_spec.js
+++ /dev/null
@@ -1,168 +0,0 @@
-import CommentTypeToggle from '~/comment_type_toggle';
-import InputSetter from '~/droplab/plugins/input_setter';
-
-describe('CommentTypeToggle', function() {
- describe('class constructor', function() {
- beforeEach(function() {
- this.dropdownTrigger = {};
- this.dropdownList = {};
- this.noteTypeInput = {};
- this.submitButton = {};
- this.closeButton = {};
-
- this.commentTypeToggle = new CommentTypeToggle({
- dropdownTrigger: this.dropdownTrigger,
- dropdownList: this.dropdownList,
- noteTypeInput: this.noteTypeInput,
- submitButton: this.submitButton,
- closeButton: this.closeButton,
- });
- });
-
- it('should set .dropdownTrigger', function() {
- expect(this.commentTypeToggle.dropdownTrigger).toBe(this.dropdownTrigger);
- });
-
- it('should set .dropdownList', function() {
- expect(this.commentTypeToggle.dropdownList).toBe(this.dropdownList);
- });
-
- it('should set .noteTypeInput', function() {
- expect(this.commentTypeToggle.noteTypeInput).toBe(this.noteTypeInput);
- });
-
- it('should set .submitButton', function() {
- expect(this.commentTypeToggle.submitButton).toBe(this.submitButton);
- });
-
- it('should set .closeButton', function() {
- expect(this.commentTypeToggle.closeButton).toBe(this.closeButton);
- });
-
- it('should set .reopenButton', function() {
- expect(this.commentTypeToggle.reopenButton).toBe(this.reopenButton);
- });
- });
-
- describe('initDroplab', function() {
- beforeEach(function() {
- this.commentTypeToggle = {
- dropdownTrigger: {},
- dropdownList: {},
- noteTypeInput: {},
- submitButton: {},
- closeButton: {},
- setConfig: () => {},
- };
- this.config = {};
-
- this.droplab = jasmine.createSpyObj('droplab', ['init']);
-
- this.droplabConstructor = spyOnDependency(CommentTypeToggle, 'DropLab').and.returnValue(
- this.droplab,
- );
- spyOn(this.commentTypeToggle, 'setConfig').and.returnValue(this.config);
-
- CommentTypeToggle.prototype.initDroplab.call(this.commentTypeToggle);
- });
-
- it('should instantiate a DropLab instance', function() {
- expect(this.droplabConstructor).toHaveBeenCalled();
- });
-
- it('should set .droplab', function() {
- expect(this.commentTypeToggle.droplab).toBe(this.droplab);
- });
-
- it('should call .setConfig', function() {
- expect(this.commentTypeToggle.setConfig).toHaveBeenCalled();
- });
-
- it('should call DropLab.prototype.init', function() {
- expect(this.droplab.init).toHaveBeenCalledWith(
- this.commentTypeToggle.dropdownTrigger,
- this.commentTypeToggle.dropdownList,
- [InputSetter],
- this.config,
- );
- });
- });
-
- describe('setConfig', function() {
- describe('if no .closeButton is provided', function() {
- beforeEach(function() {
- this.commentTypeToggle = {
- dropdownTrigger: {},
- dropdownList: {},
- noteTypeInput: {},
- submitButton: {},
- reopenButton: {},
- };
-
- this.setConfig = CommentTypeToggle.prototype.setConfig.call(this.commentTypeToggle);
- });
-
- it('should not add .closeButton related InputSetter config', function() {
- expect(this.setConfig).toEqual({
- InputSetter: [
- {
- input: this.commentTypeToggle.noteTypeInput,
- valueAttribute: 'data-value',
- },
- {
- input: this.commentTypeToggle.submitButton,
- valueAttribute: 'data-submit-text',
- },
- {
- input: this.commentTypeToggle.reopenButton,
- valueAttribute: 'data-reopen-text',
- },
- {
- input: this.commentTypeToggle.reopenButton,
- valueAttribute: 'data-reopen-text',
- inputAttribute: 'data-alternative-text',
- },
- ],
- });
- });
- });
-
- describe('if no .reopenButton is provided', function() {
- beforeEach(function() {
- this.commentTypeToggle = {
- dropdownTrigger: {},
- dropdownList: {},
- noteTypeInput: {},
- submitButton: {},
- closeButton: {},
- };
-
- this.setConfig = CommentTypeToggle.prototype.setConfig.call(this.commentTypeToggle);
- });
-
- it('should not add .reopenButton related InputSetter config', function() {
- expect(this.setConfig).toEqual({
- InputSetter: [
- {
- input: this.commentTypeToggle.noteTypeInput,
- valueAttribute: 'data-value',
- },
- {
- input: this.commentTypeToggle.submitButton,
- valueAttribute: 'data-submit-text',
- },
- {
- input: this.commentTypeToggle.closeButton,
- valueAttribute: 'data-close-text',
- },
- {
- input: this.commentTypeToggle.closeButton,
- valueAttribute: 'data-close-text',
- inputAttribute: 'data-alternative-text',
- },
- ],
- });
- });
- });
- });
-});
diff --git a/spec/javascripts/droplab/drop_down_spec.js b/spec/javascripts/droplab/drop_down_spec.js
deleted file mode 100644
index 22346c10547..00000000000
--- a/spec/javascripts/droplab/drop_down_spec.js
+++ /dev/null
@@ -1,650 +0,0 @@
-import DropDown from '~/droplab/drop_down';
-import utils from '~/droplab/utils';
-import { SELECTED_CLASS } from '~/droplab/constants';
-
-describe('DropLab DropDown', function() {
- describe('class constructor', function() {
- beforeEach(function() {
- spyOn(DropDown.prototype, 'getItems');
- spyOn(DropDown.prototype, 'initTemplateString');
- spyOn(DropDown.prototype, 'addEvents');
-
- this.list = { innerHTML: 'innerHTML' };
- this.dropdown = new DropDown(this.list);
- });
-
- it('sets the .hidden property to true', function() {
- expect(this.dropdown.hidden).toBe(true);
- });
-
- it('sets the .list property', function() {
- expect(this.dropdown.list).toBe(this.list);
- });
-
- it('calls .getItems', function() {
- expect(DropDown.prototype.getItems).toHaveBeenCalled();
- });
-
- it('calls .initTemplateString', function() {
- expect(DropDown.prototype.initTemplateString).toHaveBeenCalled();
- });
-
- it('calls .addEvents', function() {
- expect(DropDown.prototype.addEvents).toHaveBeenCalled();
- });
-
- it('sets the .initialState property to the .list.innerHTML', function() {
- expect(this.dropdown.initialState).toBe(this.list.innerHTML);
- });
-
- describe('if the list argument is a string', function() {
- beforeEach(function() {
- this.element = {};
- this.selector = '.selector';
-
- spyOn(Document.prototype, 'querySelector').and.returnValue(this.element);
-
- this.dropdown = new DropDown(this.selector);
- });
-
- it('calls .querySelector with the selector string', function() {
- expect(Document.prototype.querySelector).toHaveBeenCalledWith(this.selector);
- });
-
- it('sets the .list property element', function() {
- expect(this.dropdown.list).toBe(this.element);
- });
- });
- });
-
- describe('getItems', function() {
- beforeEach(function() {
- this.list = { querySelectorAll: () => {} };
- this.dropdown = { list: this.list };
- this.nodeList = [];
-
- spyOn(this.list, 'querySelectorAll').and.returnValue(this.nodeList);
-
- this.getItems = DropDown.prototype.getItems.call(this.dropdown);
- });
-
- it('calls .querySelectorAll with a list item query', function() {
- expect(this.list.querySelectorAll).toHaveBeenCalledWith('li');
- });
-
- it('sets the .items property to the returned list items', function() {
- expect(this.dropdown.items).toEqual(jasmine.any(Array));
- });
-
- it('returns the .items', function() {
- expect(this.getItems).toEqual(jasmine.any(Array));
- });
- });
-
- describe('initTemplateString', function() {
- beforeEach(function() {
- this.items = [{ outerHTML: '<a></a>' }, { outerHTML: '<img>' }];
- this.dropdown = { items: this.items };
-
- DropDown.prototype.initTemplateString.call(this.dropdown);
- });
-
- it('should set .templateString to the last items .outerHTML', function() {
- expect(this.dropdown.templateString).toBe(this.items[1].outerHTML);
- });
-
- it('should not set .templateString to a non-last items .outerHTML', function() {
- expect(this.dropdown.templateString).not.toBe(this.items[0].outerHTML);
- });
-
- describe('if .items is not set', function() {
- beforeEach(function() {
- this.dropdown = { getItems: () => {} };
-
- spyOn(this.dropdown, 'getItems').and.returnValue([]);
-
- DropDown.prototype.initTemplateString.call(this.dropdown);
- });
-
- it('should call .getItems', function() {
- expect(this.dropdown.getItems).toHaveBeenCalled();
- });
- });
-
- describe('if items array is empty', function() {
- beforeEach(function() {
- this.dropdown = { items: [] };
-
- DropDown.prototype.initTemplateString.call(this.dropdown);
- });
-
- it('should set .templateString to an empty string', function() {
- expect(this.dropdown.templateString).toBe('');
- });
- });
- });
-
- describe('clickEvent', function() {
- beforeEach(function() {
- this.classList = jasmine.createSpyObj('classList', ['contains']);
- this.list = { dispatchEvent: () => {} };
- this.dropdown = {
- hideOnClick: true,
- hide: () => {},
- list: this.list,
- addSelectedClass: () => {},
- };
- this.event = {
- preventDefault: () => {},
- target: {
- classList: this.classList,
- closest: () => null,
- },
- };
- this.customEvent = {};
- this.dummyListItem = document.createElement('li');
- spyOn(this.event.target, 'closest').and.callFake(selector => {
- if (selector === 'li') {
- return this.dummyListItem;
- }
-
- return null;
- });
-
- spyOn(this.dropdown, 'hide');
- spyOn(this.dropdown, 'addSelectedClass');
- spyOn(this.list, 'dispatchEvent');
- spyOn(this.event, 'preventDefault');
- spyOn(window, 'CustomEvent').and.returnValue(this.customEvent);
- this.classList.contains.and.returnValue(false);
- });
-
- it('should call event.target.closest', function() {
- DropDown.prototype.clickEvent.call(this.dropdown, this.event);
-
- expect(this.event.target.closest).toHaveBeenCalledWith('.droplab-item-ignore');
- expect(this.event.target.closest).toHaveBeenCalledWith('li');
- });
-
- it('should call addSelectedClass', function() {
- DropDown.prototype.clickEvent.call(this.dropdown, this.event);
-
- expect(this.dropdown.addSelectedClass).toHaveBeenCalledWith(this.dummyListItem);
- });
-
- it('should call .preventDefault', function() {
- DropDown.prototype.clickEvent.call(this.dropdown, this.event);
-
- expect(this.event.preventDefault).toHaveBeenCalled();
- });
-
- it('should call .hide', function() {
- DropDown.prototype.clickEvent.call(this.dropdown, this.event);
-
- expect(this.dropdown.hide).toHaveBeenCalled();
- });
-
- it('should construct CustomEvent', function() {
- DropDown.prototype.clickEvent.call(this.dropdown, this.event);
-
- expect(window.CustomEvent).toHaveBeenCalledWith('click.dl', jasmine.any(Object));
- });
-
- it('should call .dispatchEvent with the customEvent', function() {
- DropDown.prototype.clickEvent.call(this.dropdown, this.event);
-
- expect(this.list.dispatchEvent).toHaveBeenCalledWith(this.customEvent);
- });
-
- describe('if the target is a UL element', function() {
- beforeEach(function() {
- this.event.target = document.createElement('ul');
-
- spyOn(this.event.target, 'closest');
- });
-
- it('should return immediately', function() {
- DropDown.prototype.clickEvent.call(this.dropdown, this.event);
-
- expect(this.event.target.closest).not.toHaveBeenCalled();
- expect(this.dropdown.addSelectedClass).not.toHaveBeenCalled();
- });
- });
-
- describe('if the target has the droplab-item-ignore class', function() {
- beforeEach(function() {
- this.ignoredButton = document.createElement('button');
- this.ignoredButton.classList.add('droplab-item-ignore');
- this.event.target = this.ignoredButton;
-
- spyOn(this.ignoredButton, 'closest').and.callThrough();
- });
-
- it('does not select element', function() {
- DropDown.prototype.clickEvent.call(this.dropdown, this.event);
-
- expect(this.ignoredButton.closest.calls.count()).toBe(1);
- expect(this.ignoredButton.closest).toHaveBeenCalledWith('.droplab-item-ignore');
- expect(this.dropdown.addSelectedClass).not.toHaveBeenCalled();
- });
- });
-
- describe('if no selected element exists', function() {
- beforeEach(function() {
- this.event.preventDefault.calls.reset();
- this.dummyListItem = null;
- });
-
- it('should return before .preventDefault is called', function() {
- DropDown.prototype.clickEvent.call(this.dropdown, this.event);
-
- expect(this.event.preventDefault).not.toHaveBeenCalled();
- expect(this.dropdown.addSelectedClass).not.toHaveBeenCalled();
- });
- });
-
- describe('if hideOnClick is false', () => {
- beforeEach(function() {
- this.dropdown.hideOnClick = false;
- this.dropdown.hide.calls.reset();
- });
-
- it('should not call .hide', function() {
- DropDown.prototype.clickEvent.call(this.dropdown, this.event);
-
- expect(this.dropdown.hide).not.toHaveBeenCalled();
- });
- });
- });
-
- describe('addSelectedClass', function() {
- beforeEach(function() {
- this.items = Array(4).forEach((item, i) => {
- this.items[i] = { classList: { add: () => {} } };
- spyOn(this.items[i].classList, 'add');
- });
- this.selected = { classList: { add: () => {} } };
- this.dropdown = { removeSelectedClasses: () => {} };
-
- spyOn(this.dropdown, 'removeSelectedClasses');
- spyOn(this.selected.classList, 'add');
-
- DropDown.prototype.addSelectedClass.call(this.dropdown, this.selected);
- });
-
- it('should call .removeSelectedClasses', function() {
- expect(this.dropdown.removeSelectedClasses).toHaveBeenCalled();
- });
-
- it('should call .classList.add', function() {
- expect(this.selected.classList.add).toHaveBeenCalledWith(SELECTED_CLASS);
- });
- });
-
- describe('removeSelectedClasses', function() {
- beforeEach(function() {
- this.items = Array(4);
- this.items.forEach((item, i) => {
- this.items[i] = { classList: { add: () => {} } };
- spyOn(this.items[i].classList, 'add');
- });
- this.dropdown = { items: this.items };
-
- DropDown.prototype.removeSelectedClasses.call(this.dropdown);
- });
-
- it('should call .classList.remove for all items', function() {
- this.items.forEach((item, i) => {
- expect(this.items[i].classList.add).toHaveBeenCalledWith(SELECTED_CLASS);
- });
- });
-
- describe('if .items is not set', function() {
- beforeEach(function() {
- this.dropdown = { getItems: () => {} };
-
- spyOn(this.dropdown, 'getItems').and.returnValue([]);
-
- DropDown.prototype.removeSelectedClasses.call(this.dropdown);
- });
-
- it('should call .getItems', function() {
- expect(this.dropdown.getItems).toHaveBeenCalled();
- });
- });
- });
-
- describe('addEvents', function() {
- beforeEach(function() {
- this.list = {
- addEventListener: () => {},
- querySelectorAll: () => [],
- };
- this.dropdown = {
- list: this.list,
- clickEvent: () => {},
- closeDropdown: () => {},
- eventWrapper: {},
- };
- });
-
- it('should call .addEventListener', function() {
- spyOn(this.list, 'addEventListener');
-
- DropDown.prototype.addEvents.call(this.dropdown);
-
- expect(this.list.addEventListener).toHaveBeenCalledWith('click', jasmine.any(Function));
- expect(this.list.addEventListener).toHaveBeenCalledWith('keyup', jasmine.any(Function));
- });
- });
-
- describe('setData', function() {
- beforeEach(function() {
- this.dropdown = { render: () => {} };
- this.data = ['data'];
-
- spyOn(this.dropdown, 'render');
-
- DropDown.prototype.setData.call(this.dropdown, this.data);
- });
-
- it('should set .data', function() {
- expect(this.dropdown.data).toBe(this.data);
- });
-
- it('should call .render with the .data', function() {
- expect(this.dropdown.render).toHaveBeenCalledWith(this.data);
- });
- });
-
- describe('addData', function() {
- beforeEach(function() {
- this.dropdown = { render: () => {}, data: ['data1'] };
- this.data = ['data2'];
-
- spyOn(this.dropdown, 'render');
- spyOn(Array.prototype, 'concat').and.callThrough();
-
- DropDown.prototype.addData.call(this.dropdown, this.data);
- });
-
- it('should call .concat with data', function() {
- expect(Array.prototype.concat).toHaveBeenCalledWith(this.data);
- });
-
- it('should set .data with concatination', function() {
- expect(this.dropdown.data).toEqual(['data1', 'data2']);
- });
-
- it('should call .render with the .data', function() {
- expect(this.dropdown.render).toHaveBeenCalledWith(['data1', 'data2']);
- });
-
- describe('if .data is undefined', function() {
- beforeEach(function() {
- this.dropdown = { render: () => {}, data: undefined };
- this.data = ['data2'];
-
- spyOn(this.dropdown, 'render');
-
- DropDown.prototype.addData.call(this.dropdown, this.data);
- });
-
- it('should set .data with concatination', function() {
- expect(this.dropdown.data).toEqual(['data2']);
- });
- });
- });
-
- describe('render', function() {
- beforeEach(function() {
- this.renderableList = {};
- this.list = {
- querySelector: q => {
- if (q === '.filter-dropdown-loading') {
- return false;
- }
- return this.renderableList;
- },
- dispatchEvent: () => {},
- };
- this.dropdown = { renderChildren: () => {}, list: this.list };
- this.data = [0, 1];
- this.customEvent = {};
-
- spyOn(this.dropdown, 'renderChildren').and.callFake(data => data);
- spyOn(this.list, 'dispatchEvent');
- spyOn(this.data, 'map').and.callThrough();
- spyOn(window, 'CustomEvent').and.returnValue(this.customEvent);
-
- DropDown.prototype.render.call(this.dropdown, this.data);
- });
-
- it('should call .map', function() {
- expect(this.data.map).toHaveBeenCalledWith(jasmine.any(Function));
- });
-
- it('should call .renderChildren for each data item', function() {
- expect(this.dropdown.renderChildren.calls.count()).toBe(this.data.length);
- });
-
- it('sets the renderableList .innerHTML', function() {
- expect(this.renderableList.innerHTML).toBe('01');
- });
-
- it('should call render.dl', function() {
- expect(window.CustomEvent).toHaveBeenCalledWith('render.dl', jasmine.any(Object));
- });
-
- it('should call dispatchEvent with the customEvent', function() {
- expect(this.list.dispatchEvent).toHaveBeenCalledWith(this.customEvent);
- });
-
- describe('if no data argument is passed', function() {
- beforeEach(function() {
- this.data.map.calls.reset();
- this.dropdown.renderChildren.calls.reset();
-
- DropDown.prototype.render.call(this.dropdown, undefined);
- });
-
- it('should not call .map', function() {
- expect(this.data.map).not.toHaveBeenCalled();
- });
-
- it('should not call .renderChildren', function() {
- expect(this.dropdown.renderChildren).not.toHaveBeenCalled();
- });
- });
-
- describe('if no dynamic list is present', function() {
- beforeEach(function() {
- this.list = { querySelector: () => {}, dispatchEvent: () => {} };
- this.dropdown = { renderChildren: () => {}, list: this.list };
- this.data = [0, 1];
-
- spyOn(this.dropdown, 'renderChildren').and.callFake(data => data);
- spyOn(this.list, 'querySelector');
- spyOn(this.data, 'map').and.callThrough();
-
- DropDown.prototype.render.call(this.dropdown, this.data);
- });
-
- it('sets the .list .innerHTML', function() {
- expect(this.list.innerHTML).toBe('01');
- });
- });
- });
-
- describe('renderChildren', function() {
- beforeEach(function() {
- this.templateString = 'templateString';
- this.dropdown = { templateString: this.templateString };
- this.data = { droplab_hidden: true };
- this.html = 'html';
- this.template = { firstChild: { outerHTML: 'outerHTML', style: {} } };
-
- spyOn(utils, 'template').and.returnValue(this.html);
- spyOn(document, 'createElement').and.returnValue(this.template);
- spyOn(DropDown, 'setImagesSrc');
-
- this.renderChildren = DropDown.prototype.renderChildren.call(this.dropdown, this.data);
- });
-
- it('should call utils.t with .templateString and data', function() {
- expect(utils.template).toHaveBeenCalledWith(this.templateString, this.data);
- });
-
- it('should call document.createElement', function() {
- expect(document.createElement).toHaveBeenCalledWith('div');
- });
-
- it('should set the templates .innerHTML to the HTML', function() {
- expect(this.template.innerHTML).toBe(this.html);
- });
-
- it('should call .setImagesSrc with the template', function() {
- expect(DropDown.setImagesSrc).toHaveBeenCalledWith(this.template);
- });
-
- it('should set the template display to none', function() {
- expect(this.template.firstChild.style.display).toBe('none');
- });
-
- it('should return the templates .firstChild.outerHTML', function() {
- expect(this.renderChildren).toBe(this.template.firstChild.outerHTML);
- });
-
- describe('if droplab_hidden is false', function() {
- beforeEach(function() {
- this.data = { droplab_hidden: false };
- this.renderChildren = DropDown.prototype.renderChildren.call(this.dropdown, this.data);
- });
-
- it('should set the template display to block', function() {
- expect(this.template.firstChild.style.display).toBe('block');
- });
- });
- });
-
- describe('setImagesSrc', function() {
- beforeEach(function() {
- this.template = { querySelectorAll: () => {} };
-
- spyOn(this.template, 'querySelectorAll').and.returnValue([]);
-
- DropDown.setImagesSrc(this.template);
- });
-
- it('should call .querySelectorAll', function() {
- expect(this.template.querySelectorAll).toHaveBeenCalledWith('img[data-src]');
- });
- });
-
- describe('show', function() {
- beforeEach(function() {
- this.list = { style: {} };
- this.dropdown = { list: this.list, hidden: true };
-
- DropDown.prototype.show.call(this.dropdown);
- });
-
- it('it should set .list display to block', function() {
- expect(this.list.style.display).toBe('block');
- });
-
- it('it should set .hidden to false', function() {
- expect(this.dropdown.hidden).toBe(false);
- });
-
- describe('if .hidden is false', function() {
- beforeEach(function() {
- this.list = { style: {} };
- this.dropdown = { list: this.list, hidden: false };
-
- this.show = DropDown.prototype.show.call(this.dropdown);
- });
-
- it('should return undefined', function() {
- expect(this.show).toEqual(undefined);
- });
-
- it('should not set .list display to block', function() {
- expect(this.list.style.display).not.toEqual('block');
- });
- });
- });
-
- describe('hide', function() {
- beforeEach(function() {
- this.list = { style: {} };
- this.dropdown = { list: this.list };
-
- DropDown.prototype.hide.call(this.dropdown);
- });
-
- it('it should set .list display to none', function() {
- expect(this.list.style.display).toBe('none');
- });
-
- it('it should set .hidden to true', function() {
- expect(this.dropdown.hidden).toBe(true);
- });
- });
-
- describe('toggle', function() {
- beforeEach(function() {
- this.hidden = true;
- this.dropdown = { hidden: this.hidden, show: () => {}, hide: () => {} };
-
- spyOn(this.dropdown, 'show');
- spyOn(this.dropdown, 'hide');
-
- DropDown.prototype.toggle.call(this.dropdown);
- });
-
- it('should call .show', function() {
- expect(this.dropdown.show).toHaveBeenCalled();
- });
-
- describe('if .hidden is false', function() {
- beforeEach(function() {
- this.hidden = false;
- this.dropdown = { hidden: this.hidden, show: () => {}, hide: () => {} };
-
- spyOn(this.dropdown, 'show');
- spyOn(this.dropdown, 'hide');
-
- DropDown.prototype.toggle.call(this.dropdown);
- });
-
- it('should call .hide', function() {
- expect(this.dropdown.hide).toHaveBeenCalled();
- });
- });
- });
-
- describe('destroy', function() {
- beforeEach(function() {
- this.list = { removeEventListener: () => {} };
- this.eventWrapper = { clickEvent: 'clickEvent' };
- this.dropdown = { list: this.list, hide: () => {}, eventWrapper: this.eventWrapper };
-
- spyOn(this.list, 'removeEventListener');
- spyOn(this.dropdown, 'hide');
-
- DropDown.prototype.destroy.call(this.dropdown);
- });
-
- it('it should call .hide', function() {
- expect(this.dropdown.hide).toHaveBeenCalled();
- });
-
- it('it should call .removeEventListener', function() {
- expect(this.list.removeEventListener).toHaveBeenCalledWith(
- 'click',
- this.eventWrapper.clickEvent,
- );
- });
- });
-});
diff --git a/spec/javascripts/droplab/hook_spec.js b/spec/javascripts/droplab/hook_spec.js
deleted file mode 100644
index 40470436f19..00000000000
--- a/spec/javascripts/droplab/hook_spec.js
+++ /dev/null
@@ -1,73 +0,0 @@
-import Hook from '~/droplab/hook';
-
-describe('Hook', function() {
- describe('class constructor', function() {
- beforeEach(function() {
- this.trigger = { id: 'id' };
- this.list = {};
- this.plugins = {};
- this.config = {};
- this.dropdown = {};
-
- this.dropdownConstructor = spyOnDependency(Hook, 'DropDown').and.returnValue(this.dropdown);
-
- this.hook = new Hook(this.trigger, this.list, this.plugins, this.config);
- });
-
- it('should set .trigger', function() {
- expect(this.hook.trigger).toBe(this.trigger);
- });
-
- it('should set .list', function() {
- expect(this.hook.list).toBe(this.dropdown);
- });
-
- it('should call DropDown constructor', function() {
- expect(this.dropdownConstructor).toHaveBeenCalledWith(this.list, this.config);
- });
-
- it('should set .type', function() {
- expect(this.hook.type).toBe('Hook');
- });
-
- it('should set .event', function() {
- expect(this.hook.event).toBe('click');
- });
-
- it('should set .plugins', function() {
- expect(this.hook.plugins).toBe(this.plugins);
- });
-
- it('should set .config', function() {
- expect(this.hook.config).toBe(this.config);
- });
-
- it('should set .id', function() {
- expect(this.hook.id).toBe(this.trigger.id);
- });
-
- describe('if config argument is undefined', function() {
- beforeEach(function() {
- this.config = undefined;
-
- this.hook = new Hook(this.trigger, this.list, this.plugins, this.config);
- });
-
- it('should set .config to an empty object', function() {
- expect(this.hook.config).toEqual({});
- });
- });
-
- describe('if plugins argument is undefined', function() {
- beforeEach(function() {
- this.plugins = undefined;
-
- this.hook = new Hook(this.trigger, this.list, this.plugins, this.config);
- });
-
- it('should set .plugins to an empty array', function() {
- expect(this.hook.plugins).toEqual([]);
- });
- });
- });
-});
diff --git a/spec/javascripts/droplab/plugins/input_setter_spec.js b/spec/javascripts/droplab/plugins/input_setter_spec.js
deleted file mode 100644
index 711e0486bff..00000000000
--- a/spec/javascripts/droplab/plugins/input_setter_spec.js
+++ /dev/null
@@ -1,214 +0,0 @@
-import InputSetter from '~/droplab/plugins/input_setter';
-
-describe('InputSetter', function() {
- describe('init', function() {
- beforeEach(function() {
- this.config = { InputSetter: {} };
- this.hook = { config: this.config };
- this.inputSetter = jasmine.createSpyObj('inputSetter', ['addEvents']);
-
- InputSetter.init.call(this.inputSetter, this.hook);
- });
-
- it('should set .hook', function() {
- expect(this.inputSetter.hook).toBe(this.hook);
- });
-
- it('should set .config', function() {
- expect(this.inputSetter.config).toBe(this.config.InputSetter);
- });
-
- it('should set .eventWrapper', function() {
- expect(this.inputSetter.eventWrapper).toEqual({});
- });
-
- it('should call .addEvents', function() {
- expect(this.inputSetter.addEvents).toHaveBeenCalled();
- });
-
- describe('if config.InputSetter is not set', function() {
- beforeEach(function() {
- this.config = { InputSetter: undefined };
- this.hook = { config: this.config };
-
- InputSetter.init.call(this.inputSetter, this.hook);
- });
-
- it('should set .config to an empty object', function() {
- expect(this.inputSetter.config).toEqual({});
- });
-
- it('should set hook.config to an empty object', function() {
- expect(this.hook.config.InputSetter).toEqual({});
- });
- });
- });
-
- describe('addEvents', function() {
- beforeEach(function() {
- this.hook = { list: { list: jasmine.createSpyObj('list', ['addEventListener']) } };
- this.inputSetter = { eventWrapper: {}, hook: this.hook, setInputs: () => {} };
-
- InputSetter.addEvents.call(this.inputSetter);
- });
-
- it('should set .eventWrapper.setInputs', function() {
- expect(this.inputSetter.eventWrapper.setInputs).toEqual(jasmine.any(Function));
- });
-
- it('should call .addEventListener', function() {
- expect(this.hook.list.list.addEventListener).toHaveBeenCalledWith(
- 'click.dl',
- this.inputSetter.eventWrapper.setInputs,
- );
- });
- });
-
- describe('removeEvents', function() {
- beforeEach(function() {
- this.hook = { list: { list: jasmine.createSpyObj('list', ['removeEventListener']) } };
- this.eventWrapper = jasmine.createSpyObj('eventWrapper', ['setInputs']);
- this.inputSetter = { eventWrapper: this.eventWrapper, hook: this.hook };
-
- InputSetter.removeEvents.call(this.inputSetter);
- });
-
- it('should call .removeEventListener', function() {
- expect(this.hook.list.list.removeEventListener).toHaveBeenCalledWith(
- 'click.dl',
- this.eventWrapper.setInputs,
- );
- });
- });
-
- describe('setInputs', function() {
- beforeEach(function() {
- this.event = { detail: { selected: {} } };
- this.config = [0, 1];
- this.inputSetter = { config: this.config, setInput: () => {} };
-
- spyOn(this.inputSetter, 'setInput');
-
- InputSetter.setInputs.call(this.inputSetter, this.event);
- });
-
- it('should call .setInput for each config element', function() {
- const allArgs = this.inputSetter.setInput.calls.allArgs();
-
- expect(allArgs.length).toEqual(2);
-
- allArgs.forEach((args, i) => {
- expect(args[0]).toBe(this.config[i]);
- expect(args[1]).toBe(this.event.detail.selected);
- });
- });
-
- describe('if config isnt an array', function() {
- beforeEach(function() {
- this.inputSetter = { config: {}, setInput: () => {} };
-
- InputSetter.setInputs.call(this.inputSetter, this.event);
- });
-
- it('should set .config to an array with .config as the first element', function() {
- expect(this.inputSetter.config).toEqual([{}]);
- });
- });
- });
-
- describe('setInput', function() {
- beforeEach(function() {
- this.selectedItem = { getAttribute: () => {} };
- this.input = { value: 'oldValue', tagName: 'INPUT', hasAttribute: () => {} };
- this.config = { valueAttribute: {}, input: this.input };
- this.inputSetter = { hook: { trigger: {} } };
- this.newValue = 'newValue';
-
- spyOn(this.selectedItem, 'getAttribute').and.returnValue(this.newValue);
- spyOn(this.input, 'hasAttribute').and.returnValue(false);
-
- InputSetter.setInput.call(this.inputSetter, this.config, this.selectedItem);
- });
-
- it('should call .getAttribute', function() {
- expect(this.selectedItem.getAttribute).toHaveBeenCalledWith(this.config.valueAttribute);
- });
-
- it('should call .hasAttribute', function() {
- expect(this.input.hasAttribute).toHaveBeenCalledWith(undefined);
- });
-
- it('should set the value of the input', function() {
- expect(this.input.value).toBe(this.newValue);
- });
-
- describe('if no config.input is provided', function() {
- beforeEach(function() {
- this.config = { valueAttribute: {} };
- this.trigger = { value: 'oldValue', tagName: 'INPUT', hasAttribute: () => {} };
- this.inputSetter = { hook: { trigger: this.trigger } };
-
- InputSetter.setInput.call(this.inputSetter, this.config, this.selectedItem);
- });
-
- it('should set the value of the hook.trigger', function() {
- expect(this.trigger.value).toBe(this.newValue);
- });
- });
-
- describe('if the input tag is not INPUT', function() {
- beforeEach(function() {
- this.input = { textContent: 'oldValue', tagName: 'SPAN', hasAttribute: () => {} };
- this.config = { valueAttribute: {}, input: this.input };
-
- InputSetter.setInput.call(this.inputSetter, this.config, this.selectedItem);
- });
-
- it('should set the textContent of the input', function() {
- expect(this.input.textContent).toBe(this.newValue);
- });
- });
-
- describe('if there is an inputAttribute', function() {
- beforeEach(function() {
- this.selectedItem = { getAttribute: () => {} };
- this.input = { id: 'oldValue', hasAttribute: () => {}, setAttribute: () => {} };
- this.inputSetter = { hook: { trigger: {} } };
- this.newValue = 'newValue';
- this.inputAttribute = 'id';
- this.config = {
- valueAttribute: {},
- input: this.input,
- inputAttribute: this.inputAttribute,
- };
-
- spyOn(this.selectedItem, 'getAttribute').and.returnValue(this.newValue);
- spyOn(this.input, 'hasAttribute').and.returnValue(true);
- spyOn(this.input, 'setAttribute');
-
- InputSetter.setInput.call(this.inputSetter, this.config, this.selectedItem);
- });
-
- it('should call setAttribute', function() {
- expect(this.input.setAttribute).toHaveBeenCalledWith(this.inputAttribute, this.newValue);
- });
-
- it('should not set the value or textContent of the input', function() {
- expect(this.input.value).not.toBe('newValue');
- expect(this.input.textContent).not.toBe('newValue');
- });
- });
- });
-
- describe('destroy', function() {
- beforeEach(function() {
- this.inputSetter = jasmine.createSpyObj('inputSetter', ['removeEvents']);
-
- InputSetter.destroy.call(this.inputSetter);
- });
-
- it('should call .removeEvents', function() {
- expect(this.inputSetter.removeEvents).toHaveBeenCalled();
- });
- });
-});
diff --git a/spec/javascripts/dropzone_input_spec.js b/spec/javascripts/dropzone_input_spec.js
deleted file mode 100644
index 6f6f20ccca2..00000000000
--- a/spec/javascripts/dropzone_input_spec.js
+++ /dev/null
@@ -1,109 +0,0 @@
-import $ from 'jquery';
-import { TEST_HOST } from 'spec/test_constants';
-import dropzoneInput from '~/dropzone_input';
-import PasteMarkdownTable from '~/behaviors/markdown/paste_markdown_table';
-
-const TEST_FILE = new File([], 'somefile.jpg');
-TEST_FILE.upload = {};
-
-const TEST_UPLOAD_PATH = `${TEST_HOST}/upload/file`;
-const TEST_ERROR_MESSAGE = 'A big error occurred!';
-const TEMPLATE = `<form class="gfm-form" data-uploads-path="${TEST_UPLOAD_PATH}">
- <textarea class="js-gfm-input"></textarea>
- <div class="uploading-error-message"></div>
-</form>`;
-
-describe('dropzone_input', () => {
- it('returns null when failed to initialize', () => {
- const dropzone = dropzoneInput($('<form class="gfm-form"></form>'));
-
- expect(dropzone).toBeNull();
- });
-
- it('returns valid dropzone when successfully initialize', () => {
- const dropzone = dropzoneInput($(TEMPLATE));
-
- expect(dropzone.version).toBeTruthy();
- });
-
- describe('handlePaste', () => {
- beforeEach(() => {
- loadFixtures('issues/new-issue.html');
-
- const form = $('#new_issue');
- form.data('uploads-path', TEST_UPLOAD_PATH);
- dropzoneInput(form);
- });
-
- it('pastes Markdown tables', () => {
- const event = $.Event('paste');
- const origEvent = new Event('paste');
- const pasteData = new DataTransfer();
- pasteData.setData('text/plain', 'Hello World');
- pasteData.setData('text/html', '<table><tr><td>Hello World</td></tr></table>');
- origEvent.clipboardData = pasteData;
- event.originalEvent = origEvent;
-
- spyOn(PasteMarkdownTable.prototype, 'isTable').and.callThrough();
- spyOn(PasteMarkdownTable.prototype, 'convertToTableMarkdown').and.callThrough();
-
- $('.js-gfm-input').trigger(event);
-
- expect(PasteMarkdownTable.prototype.isTable).toHaveBeenCalled();
- expect(PasteMarkdownTable.prototype.convertToTableMarkdown).toHaveBeenCalled();
- });
- });
-
- describe('shows error message', () => {
- let form;
- let dropzone;
- let xhr;
- let oldXMLHttpRequest;
-
- beforeEach(() => {
- form = $(TEMPLATE);
-
- dropzone = dropzoneInput(form);
-
- xhr = jasmine.createSpyObj(Object.keys(XMLHttpRequest.prototype));
- oldXMLHttpRequest = window.XMLHttpRequest;
- window.XMLHttpRequest = () => xhr;
- });
-
- afterEach(() => {
- window.XMLHttpRequest = oldXMLHttpRequest;
- });
-
- it('when AJAX fails with json', () => {
- xhr = {
- ...xhr,
- statusCode: 400,
- readyState: 4,
- responseText: JSON.stringify({ message: TEST_ERROR_MESSAGE }),
- getResponseHeader: () => 'application/json',
- };
-
- dropzone.processFile(TEST_FILE);
-
- xhr.onload();
-
- expect(form.find('.uploading-error-message').text()).toEqual(TEST_ERROR_MESSAGE);
- });
-
- it('when AJAX fails with text', () => {
- xhr = {
- ...xhr,
- statusCode: 400,
- readyState: 4,
- responseText: TEST_ERROR_MESSAGE,
- getResponseHeader: () => 'text/plain',
- };
-
- dropzone.processFile(TEST_FILE);
-
- xhr.onload();
-
- expect(form.find('.uploading-error-message').text()).toEqual(TEST_ERROR_MESSAGE);
- });
- });
-});
diff --git a/spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js b/spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js
deleted file mode 100644
index 853f6b3b7b8..00000000000
--- a/spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js
+++ /dev/null
@@ -1,126 +0,0 @@
-import $ from 'jquery';
-import FilteredSearchDropdownManager from '~/filtered_search/filtered_search_dropdown_manager';
-
-describe('Filtered Search Dropdown Manager', () => {
- beforeEach(() => {
- spyOn($, 'ajax');
- });
-
- describe('addWordToInput', () => {
- function getInputValue() {
- return document.querySelector('.filtered-search').value;
- }
-
- function setInputValue(value) {
- document.querySelector('.filtered-search').value = value;
- }
-
- beforeEach(() => {
- setFixtures(`
- <ul class="tokens-container">
- <li class="input-token">
- <input class="filtered-search">
- </li>
- </ul>
- `);
- });
-
- describe('input has no existing value', () => {
- it('should add just tokenName', () => {
- FilteredSearchDropdownManager.addWordToInput({ tokenName: 'milestone' });
-
- const token = document.querySelector('.tokens-container .js-visual-token');
-
- expect(token.classList.contains('filtered-search-token')).toEqual(true);
- expect(token.querySelector('.name').innerText).toBe('milestone');
- expect(getInputValue()).toBe('');
- });
-
- it('should add tokenName, tokenOperator, and tokenValue', () => {
- FilteredSearchDropdownManager.addWordToInput({ tokenName: 'label' });
-
- let token = document.querySelector('.tokens-container .js-visual-token');
-
- expect(token.classList.contains('filtered-search-token')).toEqual(true);
- expect(token.querySelector('.name').innerText).toBe('label');
- expect(getInputValue()).toBe('');
-
- FilteredSearchDropdownManager.addWordToInput({ tokenName: 'label', tokenOperator: '=' });
-
- token = document.querySelector('.tokens-container .js-visual-token');
-
- expect(token.classList.contains('filtered-search-token')).toEqual(true);
- expect(token.querySelector('.name').innerText).toBe('label');
- expect(token.querySelector('.operator').innerText).toBe('=');
- expect(getInputValue()).toBe('');
-
- FilteredSearchDropdownManager.addWordToInput({
- tokenName: 'label',
- tokenOperator: '=',
- tokenValue: 'none',
- });
- // We have to get that reference again
- // Because FilteredSearchDropdownManager deletes the previous token
- token = document.querySelector('.tokens-container .js-visual-token');
-
- expect(token.classList.contains('filtered-search-token')).toEqual(true);
- expect(token.querySelector('.name').innerText).toBe('label');
- expect(token.querySelector('.operator').innerText).toBe('=');
- expect(token.querySelector('.value').innerText).toBe('none');
- expect(getInputValue()).toBe('');
- });
- });
-
- describe('input has existing value', () => {
- it('should be able to just add tokenName', () => {
- setInputValue('a');
- FilteredSearchDropdownManager.addWordToInput({ tokenName: 'author' });
-
- const token = document.querySelector('.tokens-container .js-visual-token');
-
- expect(token.classList.contains('filtered-search-token')).toEqual(true);
- expect(token.querySelector('.name').innerText).toBe('author');
- expect(getInputValue()).toBe('');
- });
-
- it('should replace tokenValue', () => {
- FilteredSearchDropdownManager.addWordToInput({ tokenName: 'author' });
- FilteredSearchDropdownManager.addWordToInput({ tokenName: 'author', tokenOperator: '=' });
-
- setInputValue('roo');
- FilteredSearchDropdownManager.addWordToInput({
- tokenName: null,
- tokenOperator: '=',
- tokenValue: '@root',
- });
-
- const token = document.querySelector('.tokens-container .js-visual-token');
-
- expect(token.classList.contains('filtered-search-token')).toEqual(true);
- expect(token.querySelector('.name').innerText).toBe('author');
- expect(token.querySelector('.operator').innerText).toBe('=');
- expect(token.querySelector('.value').innerText).toBe('@root');
- expect(getInputValue()).toBe('');
- });
-
- it('should add tokenValues containing spaces', () => {
- FilteredSearchDropdownManager.addWordToInput({ tokenName: 'label' });
-
- setInputValue('"test ');
- FilteredSearchDropdownManager.addWordToInput({
- tokenName: 'label',
- tokenOperator: '=',
- tokenValue: '~\'"test me"\'',
- });
-
- const token = document.querySelector('.tokens-container .js-visual-token');
-
- expect(token.classList.contains('filtered-search-token')).toEqual(true);
- expect(token.querySelector('.name').innerText).toBe('label');
- expect(token.querySelector('.operator').innerText).toBe('=');
- expect(token.querySelector('.value').innerText).toBe('~\'"test me"\'');
- expect(getInputValue()).toBe('');
- });
- });
- });
-});
diff --git a/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js b/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js
deleted file mode 100644
index fda078bd41c..00000000000
--- a/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js
+++ /dev/null
@@ -1,722 +0,0 @@
-import FilteredSearchVisualTokens from '~/filtered_search/filtered_search_visual_tokens';
-import FilteredSearchSpecHelper from '../helpers/filtered_search_spec_helper';
-
-describe('Filtered Search Visual Tokens', () => {
- const subject = FilteredSearchVisualTokens;
-
- const findElements = tokenElement => {
- const tokenNameElement = tokenElement.querySelector('.name');
- const tokenOperatorElement = tokenElement.querySelector('.operator');
- const tokenValueContainer = tokenElement.querySelector('.value-container');
- const tokenValueElement = tokenValueContainer.querySelector('.value');
- return { tokenNameElement, tokenOperatorElement, tokenValueContainer, tokenValueElement };
- };
-
- let tokensContainer;
- let authorToken;
- let bugLabelToken;
-
- beforeEach(() => {
- setFixtures(`
- <ul class="tokens-container">
- ${FilteredSearchSpecHelper.createInputHTML()}
- </ul>
- `);
- tokensContainer = document.querySelector('.tokens-container');
-
- authorToken = FilteredSearchSpecHelper.createFilterVisualToken('author', '=', '@user');
- bugLabelToken = FilteredSearchSpecHelper.createFilterVisualToken('label', '=', '~bug');
- });
-
- describe('getLastVisualTokenBeforeInput', () => {
- it('returns when there are no visual tokens', () => {
- const { lastVisualToken, isLastVisualTokenValid } = subject.getLastVisualTokenBeforeInput();
-
- expect(lastVisualToken).toEqual(null);
- expect(isLastVisualTokenValid).toEqual(true);
- });
-
- describe('input is the last item in tokensContainer', () => {
- it('returns when there is one visual token', () => {
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
- bugLabelToken.outerHTML,
- );
-
- const { lastVisualToken, isLastVisualTokenValid } = subject.getLastVisualTokenBeforeInput();
-
- expect(lastVisualToken).toEqual(document.querySelector('.filtered-search-token'));
- expect(isLastVisualTokenValid).toEqual(true);
- });
-
- it('returns when there is an incomplete visual token', () => {
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
- FilteredSearchSpecHelper.createNameFilterVisualTokenHTML('Author'),
- );
-
- const { lastVisualToken, isLastVisualTokenValid } = subject.getLastVisualTokenBeforeInput();
-
- expect(lastVisualToken).toEqual(document.querySelector('.filtered-search-token'));
- expect(isLastVisualTokenValid).toEqual(false);
- });
-
- it('returns when there are multiple visual tokens', () => {
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(`
- ${bugLabelToken.outerHTML}
- ${FilteredSearchSpecHelper.createSearchVisualTokenHTML('search term')}
- ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('author', '=', '@root')}
- `);
-
- const { lastVisualToken, isLastVisualTokenValid } = subject.getLastVisualTokenBeforeInput();
- const items = document.querySelectorAll('.tokens-container .js-visual-token');
-
- expect(lastVisualToken.isEqualNode(items[items.length - 1])).toEqual(true);
- expect(isLastVisualTokenValid).toEqual(true);
- });
-
- it('returns when there are multiple visual tokens and an incomplete visual token', () => {
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(`
- ${bugLabelToken.outerHTML}
- ${FilteredSearchSpecHelper.createSearchVisualTokenHTML('search term')}
- ${FilteredSearchSpecHelper.createNameFilterVisualTokenHTML('assignee')}
- `);
-
- const { lastVisualToken, isLastVisualTokenValid } = subject.getLastVisualTokenBeforeInput();
- const items = document.querySelectorAll('.tokens-container .js-visual-token');
-
- expect(lastVisualToken.isEqualNode(items[items.length - 1])).toEqual(true);
- expect(isLastVisualTokenValid).toEqual(false);
- });
- });
-
- describe('input is a middle item in tokensContainer', () => {
- it('returns last token before input', () => {
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(`
- ${bugLabelToken.outerHTML}
- ${FilteredSearchSpecHelper.createInputHTML()}
- ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('author', '=', '@root')}
- `);
-
- const { lastVisualToken, isLastVisualTokenValid } = subject.getLastVisualTokenBeforeInput();
-
- expect(lastVisualToken).toEqual(document.querySelector('.filtered-search-token'));
- expect(isLastVisualTokenValid).toEqual(true);
- });
-
- it('returns last partial token before input', () => {
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(`
- ${FilteredSearchSpecHelper.createNameFilterVisualTokenHTML('label')}
- ${FilteredSearchSpecHelper.createInputHTML()}
- ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('author', '=', '@root')}
- `);
-
- const { lastVisualToken, isLastVisualTokenValid } = subject.getLastVisualTokenBeforeInput();
-
- expect(lastVisualToken).toEqual(document.querySelector('.filtered-search-token'));
- expect(isLastVisualTokenValid).toEqual(false);
- });
- });
- });
-
- describe('getEndpointWithQueryParams', () => {
- it('returns `endpoint` string as is when second param `endpointQueryParams` is undefined, null or empty string', () => {
- const endpoint = 'foo/bar/-/labels.json';
-
- expect(subject.getEndpointWithQueryParams(endpoint)).toBe(endpoint);
- expect(subject.getEndpointWithQueryParams(endpoint, null)).toBe(endpoint);
- expect(subject.getEndpointWithQueryParams(endpoint, '')).toBe(endpoint);
- });
-
- it('returns `endpoint` string with values of `endpointQueryParams`', () => {
- const endpoint = 'foo/bar/-/labels.json';
- const singleQueryParams = '{"foo":"true"}';
- const multipleQueryParams = '{"foo":"true","bar":"true"}';
-
- expect(subject.getEndpointWithQueryParams(endpoint, singleQueryParams)).toBe(
- `${endpoint}?foo=true`,
- );
-
- expect(subject.getEndpointWithQueryParams(endpoint, multipleQueryParams)).toBe(
- `${endpoint}?foo=true&bar=true`,
- );
- });
- });
-
- describe('unselectTokens', () => {
- it('does nothing when there are no tokens', () => {
- const beforeHTML = tokensContainer.innerHTML;
- subject.unselectTokens();
-
- expect(tokensContainer.innerHTML).toEqual(beforeHTML);
- });
-
- it('removes the selected class from buttons', () => {
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(`
- ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('author', '=', '@author')}
- ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('milestone', '=', '%123', true)}
- `);
-
- const selected = tokensContainer.querySelector('.js-visual-token .selected');
-
- expect(selected.classList.contains('selected')).toEqual(true);
-
- subject.unselectTokens();
-
- expect(selected.classList.contains('selected')).toEqual(false);
- });
- });
-
- describe('selectToken', () => {
- beforeEach(() => {
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(`
- ${bugLabelToken.outerHTML}
- ${FilteredSearchSpecHelper.createSearchVisualTokenHTML('search term')}
- ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('label', '=', '~awesome')}
- `);
- });
-
- it('removes the selected class if it has selected class', () => {
- const firstTokenButton = tokensContainer.querySelector('.js-visual-token .selectable');
- firstTokenButton.classList.add('selected');
-
- subject.selectToken(firstTokenButton);
-
- expect(firstTokenButton.classList.contains('selected')).toEqual(false);
- });
-
- describe('has no selected class', () => {
- it('adds selected class', () => {
- const firstTokenButton = tokensContainer.querySelector('.js-visual-token .selectable');
-
- subject.selectToken(firstTokenButton);
-
- expect(firstTokenButton.classList.contains('selected')).toEqual(true);
- });
-
- it('removes selected class from other tokens', () => {
- const tokenButtons = tokensContainer.querySelectorAll('.js-visual-token .selectable');
- tokenButtons[1].classList.add('selected');
-
- subject.selectToken(tokenButtons[0]);
-
- expect(tokenButtons[0].classList.contains('selected')).toEqual(true);
- expect(tokenButtons[1].classList.contains('selected')).toEqual(false);
- });
- });
- });
-
- describe('removeSelectedToken', () => {
- it('does not remove when there are no selected tokens', () => {
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
- FilteredSearchSpecHelper.createFilterVisualTokenHTML('milestone', '=', 'none'),
- );
-
- expect(tokensContainer.querySelector('.js-visual-token .selectable')).not.toEqual(null);
-
- subject.removeSelectedToken();
-
- expect(tokensContainer.querySelector('.js-visual-token .selectable')).not.toEqual(null);
- });
-
- it('removes selected token', () => {
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
- FilteredSearchSpecHelper.createFilterVisualTokenHTML('milestone', '=', 'none', true),
- );
-
- expect(tokensContainer.querySelector('.js-visual-token .selectable')).not.toEqual(null);
-
- subject.removeSelectedToken();
-
- expect(tokensContainer.querySelector('.js-visual-token .selectable')).toEqual(null);
- });
- });
-
- describe('createVisualTokenElementHTML', () => {
- let tokenElement;
-
- beforeEach(() => {
- setFixtures(`
- <div class="test-area">
- ${subject.createVisualTokenElementHTML('custom-token')}
- </div>
- `);
-
- tokenElement = document.querySelector('.test-area').firstElementChild;
- });
-
- it('should add class name to token element', () => {
- expect(document.querySelector('.test-area .custom-token')).toBeDefined();
- });
-
- it('contains name div', () => {
- expect(tokenElement.querySelector('.name')).toEqual(jasmine.anything());
- });
-
- it('contains value container div', () => {
- expect(tokenElement.querySelector('.value-container')).toEqual(jasmine.anything());
- });
-
- it('contains value div', () => {
- expect(tokenElement.querySelector('.value-container .value')).toEqual(jasmine.anything());
- });
-
- it('contains selectable class', () => {
- expect(tokenElement.classList.contains('selectable')).toEqual(true);
- });
-
- it('contains button role', () => {
- expect(tokenElement.getAttribute('role')).toEqual('button');
- });
-
- describe('remove token', () => {
- it('contains remove-token button', () => {
- expect(tokenElement.querySelector('.value-container .remove-token')).toEqual(
- jasmine.anything(),
- );
- });
-
- it('contains fa-close icon', () => {
- expect(tokenElement.querySelector('.remove-token .fa-close')).toEqual(jasmine.anything());
- });
- });
- });
-
- describe('addVisualTokenElement', () => {
- it('renders search visual tokens', () => {
- subject.addVisualTokenElement({
- name: 'search term',
- operator: '=',
- value: null,
- options: { isSearchTerm: true },
- });
- const token = tokensContainer.querySelector('.js-visual-token');
-
- expect(token.classList.contains('filtered-search-term')).toEqual(true);
- expect(token.querySelector('.name').innerText).toEqual('search term');
- expect(token.querySelector('.operator').innerText).toEqual('=');
- expect(token.querySelector('.value')).toEqual(null);
- });
-
- it('renders filter visual token name', () => {
- subject.addVisualTokenElement({ name: 'milestone' });
- const token = tokensContainer.querySelector('.js-visual-token');
-
- expect(token.classList.contains('search-token-milestone')).toEqual(true);
- expect(token.classList.contains('filtered-search-token')).toEqual(true);
- expect(token.querySelector('.name').innerText).toEqual('milestone');
- expect(token.querySelector('.value')).toEqual(null);
- });
-
- it('renders filter visual token name, operator, and value', () => {
- subject.addVisualTokenElement({ name: 'label', operator: '!=', value: 'Frontend' });
- const token = tokensContainer.querySelector('.js-visual-token');
-
- expect(token.classList.contains('search-token-label')).toEqual(true);
- expect(token.classList.contains('filtered-search-token')).toEqual(true);
- expect(token.querySelector('.name').innerText).toEqual('label');
- expect(token.querySelector('.operator').innerText).toEqual('!=');
- expect(token.querySelector('.value').innerText).toEqual('Frontend');
- });
-
- it('inserts visual token before input', () => {
- tokensContainer.appendChild(
- FilteredSearchSpecHelper.createFilterVisualToken('assignee', '=', '@root'),
- );
-
- subject.addVisualTokenElement({ name: 'label', operator: '!=', value: 'Frontend' });
- const tokens = tokensContainer.querySelectorAll('.js-visual-token');
- const labelToken = tokens[0];
- const assigneeToken = tokens[1];
-
- expect(labelToken.classList.contains('search-token-label')).toEqual(true);
- expect(labelToken.classList.contains('filtered-search-token')).toEqual(true);
- expect(labelToken.querySelector('.name').innerText).toEqual('label');
- expect(labelToken.querySelector('.value').innerText).toEqual('Frontend');
- expect(labelToken.querySelector('.operator').innerText).toEqual('!=');
-
- expect(assigneeToken.classList.contains('search-token-assignee')).toEqual(true);
- expect(assigneeToken.classList.contains('filtered-search-token')).toEqual(true);
- expect(assigneeToken.querySelector('.name').innerText).toEqual('assignee');
- expect(assigneeToken.querySelector('.value').innerText).toEqual('@root');
- expect(assigneeToken.querySelector('.operator').innerText).toEqual('=');
- });
- });
-
- describe('addValueToPreviousVisualTokenElement', () => {
- it('does not add when previous visual token element has no value', () => {
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
- FilteredSearchSpecHelper.createFilterVisualTokenHTML('author', '=', '@root'),
- );
-
- const original = tokensContainer.innerHTML;
- subject.addValueToPreviousVisualTokenElement('value');
-
- expect(original).toEqual(tokensContainer.innerHTML);
- });
-
- it('does not add when previous visual token element is a search', () => {
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(`
- ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('author', '=', '@root')}
- ${FilteredSearchSpecHelper.createSearchVisualTokenHTML('search term')}
- `);
-
- const original = tokensContainer.innerHTML;
- subject.addValueToPreviousVisualTokenElement('value');
-
- expect(original).toEqual(tokensContainer.innerHTML);
- });
-
- it('adds value to previous visual filter token', () => {
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
- FilteredSearchSpecHelper.createNameOperatorFilterVisualTokenHTML('label', '='),
- );
-
- const original = tokensContainer.innerHTML;
- subject.addValueToPreviousVisualTokenElement('value');
- const updatedToken = tokensContainer.querySelector('.js-visual-token');
-
- expect(updatedToken.querySelector('.name').innerText).toEqual('label');
- expect(updatedToken.querySelector('.value').innerText).toEqual('value');
- expect(original).not.toEqual(tokensContainer.innerHTML);
- });
- });
-
- describe('addFilterVisualToken', () => {
- it('creates visual token with just tokenName', () => {
- subject.addFilterVisualToken('milestone');
- const token = tokensContainer.querySelector('.js-visual-token');
-
- expect(token.classList.contains('filtered-search-token')).toEqual(true);
- expect(token.querySelector('.name').innerText).toEqual('milestone');
- expect(token.querySelector('.operator')).toEqual(null);
- expect(token.querySelector('.value')).toEqual(null);
- });
-
- it('creates visual token with just tokenValue', () => {
- subject.addFilterVisualToken('milestone', '=');
- subject.addFilterVisualToken('%8.17');
- const token = tokensContainer.querySelector('.js-visual-token');
-
- expect(token.classList.contains('filtered-search-token')).toEqual(true);
- expect(token.querySelector('.name').innerText).toEqual('milestone');
- expect(token.querySelector('.operator').innerText).toEqual('=');
- expect(token.querySelector('.value').innerText).toEqual('%8.17');
- });
-
- it('creates full visual token', () => {
- subject.addFilterVisualToken('assignee', '=', '@john');
- const token = tokensContainer.querySelector('.js-visual-token');
-
- expect(token.classList.contains('filtered-search-token')).toEqual(true);
- expect(token.querySelector('.name').innerText).toEqual('assignee');
- expect(token.querySelector('.operator').innerText).toEqual('=');
- expect(token.querySelector('.value').innerText).toEqual('@john');
- });
- });
-
- describe('addSearchVisualToken', () => {
- it('creates search visual token', () => {
- subject.addSearchVisualToken('search term');
- const token = tokensContainer.querySelector('.js-visual-token');
-
- expect(token.classList.contains('filtered-search-term')).toEqual(true);
- expect(token.querySelector('.name').innerText).toEqual('search term');
- expect(token.querySelector('.value')).toEqual(null);
- });
-
- it('appends to previous search visual token if previous token was a search token', () => {
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(`
- ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('author', '=', '@root')}
- ${FilteredSearchSpecHelper.createSearchVisualTokenHTML('search term')}
- `);
-
- subject.addSearchVisualToken('append this');
- const token = tokensContainer.querySelector('.filtered-search-term');
-
- expect(token.querySelector('.name').innerText).toEqual('search term append this');
- expect(token.querySelector('.value')).toEqual(null);
- });
- });
-
- describe('getLastTokenPartial', () => {
- it('should get last token value', () => {
- const value = '~bug';
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
- bugLabelToken.outerHTML,
- );
-
- expect(subject.getLastTokenPartial()).toEqual(value);
- });
-
- it('should get last token original value if available', () => {
- const originalValue = '@user';
- const valueContainer = authorToken.querySelector('.value-container');
- valueContainer.dataset.originalValue = originalValue;
- const avatar = document.createElement('img');
- const valueElement = valueContainer.querySelector('.value');
- valueElement.insertAdjacentElement('afterbegin', avatar);
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
- authorToken.outerHTML,
- );
-
- const lastTokenValue = subject.getLastTokenPartial();
-
- expect(lastTokenValue).toEqual(originalValue);
- });
-
- it('should get last token name if there is no value', () => {
- const name = 'assignee';
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
- FilteredSearchSpecHelper.createNameFilterVisualTokenHTML(name),
- );
-
- expect(subject.getLastTokenPartial()).toEqual(name);
- });
-
- it('should return empty when there are no tokens', () => {
- expect(subject.getLastTokenPartial()).toEqual('');
- });
- });
-
- describe('removeLastTokenPartial', () => {
- it('should remove the last token value if it exists', () => {
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
- FilteredSearchSpecHelper.createFilterVisualTokenHTML(
- 'label',
- '=',
- '~"Community Contribution"',
- ),
- );
-
- expect(tokensContainer.querySelector('.js-visual-token .value')).not.toEqual(null);
-
- subject.removeLastTokenPartial();
-
- expect(tokensContainer.querySelector('.js-visual-token .value')).toEqual(null);
- });
-
- it('should remove the last token name if there is no value', () => {
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
- FilteredSearchSpecHelper.createNameFilterVisualTokenHTML('milestone'),
- );
-
- expect(tokensContainer.querySelector('.js-visual-token .name')).not.toEqual(null);
-
- subject.removeLastTokenPartial();
-
- expect(tokensContainer.querySelector('.js-visual-token .name')).toEqual(null);
- });
-
- it('should not remove anything when there are no tokens', () => {
- const html = tokensContainer.innerHTML;
- subject.removeLastTokenPartial();
-
- expect(tokensContainer.innerHTML).toEqual(html);
- });
- });
-
- describe('tokenizeInput', () => {
- it('does not do anything if there is no input', () => {
- const original = tokensContainer.innerHTML;
- subject.tokenizeInput();
-
- expect(tokensContainer.innerHTML).toEqual(original);
- });
-
- it('adds search visual token if previous visual token is valid', () => {
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
- FilteredSearchSpecHelper.createFilterVisualTokenHTML('assignee', '=', 'none'),
- );
-
- const input = document.querySelector('.filtered-search');
- input.value = 'some value';
- subject.tokenizeInput();
-
- const newToken = tokensContainer.querySelector('.filtered-search-term');
-
- expect(input.value).toEqual('');
- expect(newToken.querySelector('.name').innerText).toEqual('some value');
- expect(newToken.querySelector('.value')).toEqual(null);
- });
-
- it('adds value to previous visual token element if previous visual token is invalid', () => {
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
- FilteredSearchSpecHelper.createNameOperatorFilterVisualTokenHTML('assignee', '='),
- );
-
- const input = document.querySelector('.filtered-search');
- input.value = '@john';
- subject.tokenizeInput();
-
- const updatedToken = tokensContainer.querySelector('.filtered-search-token');
-
- expect(input.value).toEqual('');
- expect(updatedToken.querySelector('.name').innerText).toEqual('assignee');
- expect(updatedToken.querySelector('.operator').innerText).toEqual('=');
- expect(updatedToken.querySelector('.value').innerText).toEqual('@john');
- });
- });
-
- describe('editToken', () => {
- let input;
- let token;
-
- beforeEach(() => {
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(`
- ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('label', '=', 'none')}
- ${FilteredSearchSpecHelper.createSearchVisualTokenHTML('search')}
- ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('milestone', '=', 'upcoming')}
- `);
-
- input = document.querySelector('.filtered-search');
- token = document.querySelector('.js-visual-token');
- });
-
- it("tokenize's existing input", () => {
- input.value = 'some text';
- spyOn(subject, 'tokenizeInput').and.callThrough();
-
- subject.editToken(token);
-
- expect(subject.tokenizeInput).toHaveBeenCalled();
- expect(input.value).not.toEqual('some text');
- });
-
- it('moves input to the token position', () => {
- expect(tokensContainer.children[3].querySelector('.filtered-search')).not.toEqual(null);
-
- subject.editToken(token);
-
- expect(tokensContainer.children[1].querySelector('.filtered-search')).not.toEqual(null);
- expect(tokensContainer.children[3].querySelector('.filtered-search')).toEqual(null);
- });
-
- it('input contains the visual token value', () => {
- subject.editToken(token);
-
- expect(input.value).toEqual('none');
- });
-
- it('input contains the original value if present', () => {
- const originalValue = '@user';
- const valueContainer = token.querySelector('.value-container');
- valueContainer.dataset.originalValue = originalValue;
-
- subject.editToken(token);
-
- expect(input.value).toEqual(originalValue);
- });
-
- describe('selected token is a search term token', () => {
- beforeEach(() => {
- token = document.querySelector('.filtered-search-term');
- });
-
- it('token is removed', () => {
- expect(tokensContainer.querySelector('.filtered-search-term')).not.toEqual(null);
-
- subject.editToken(token);
-
- expect(tokensContainer.querySelector('.filtered-search-term')).toEqual(null);
- });
-
- it('input has the same value as removed token', () => {
- expect(input.value).toEqual('');
-
- subject.editToken(token);
-
- expect(input.value).toEqual('search');
- });
- });
- });
-
- describe('moveInputTotheRight', () => {
- it('does nothing if the input is already the right most element', () => {
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
- FilteredSearchSpecHelper.createFilterVisualTokenHTML('label', '=', 'none'),
- );
-
- spyOn(subject, 'tokenizeInput').and.callFake(() => {});
- spyOn(subject, 'getLastVisualTokenBeforeInput').and.callThrough();
-
- subject.moveInputToTheRight();
-
- expect(subject.tokenizeInput).toHaveBeenCalled();
- expect(subject.getLastVisualTokenBeforeInput).not.toHaveBeenCalled();
- });
-
- it("tokenize's input", () => {
- tokensContainer.innerHTML = `
- ${FilteredSearchSpecHelper.createNameOperatorFilterVisualTokenHTML('label', '=')}
- ${FilteredSearchSpecHelper.createInputHTML()}
- ${bugLabelToken.outerHTML}
- `;
-
- tokensContainer.querySelector('.filtered-search').value = 'none';
-
- subject.moveInputToTheRight();
- const value = tokensContainer.querySelector('.js-visual-token .value');
-
- expect(value.innerText).toEqual('none');
- });
-
- it('converts input into search term token if last token is valid', () => {
- tokensContainer.innerHTML = `
- ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('label', '=', 'none')}
- ${FilteredSearchSpecHelper.createInputHTML()}
- ${bugLabelToken.outerHTML}
- `;
-
- document.querySelector('.filtered-search').value = 'test';
-
- subject.moveInputToTheRight();
- const searchValue = tokensContainer.querySelector('.filtered-search-term .name');
-
- expect(searchValue.innerText).toEqual('test');
- });
-
- it('moves the input to the right most element', () => {
- tokensContainer.innerHTML = `
- ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('label', '=', 'none')}
- ${FilteredSearchSpecHelper.createInputHTML()}
- ${bugLabelToken.outerHTML}
- `;
-
- subject.moveInputToTheRight();
-
- expect(tokensContainer.children[2].querySelector('.filtered-search')).not.toEqual(null);
- });
-
- it('tokenizes input even if input is the right most element', () => {
- tokensContainer.innerHTML = `
- ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('label', '=', 'none')}
- ${FilteredSearchSpecHelper.createNameOperatorFilterVisualTokenHTML('label')}
- ${FilteredSearchSpecHelper.createInputHTML('', '~bug')}
- `;
-
- subject.moveInputToTheRight();
-
- const token = tokensContainer.children[1];
-
- expect(token.querySelector('.value').innerText).toEqual('~bug');
- });
- });
-
- describe('renderVisualTokenValue', () => {
- beforeEach(() => {
- tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(`
- ${authorToken.outerHTML}
- ${bugLabelToken.outerHTML}
- `);
- });
-
- it('renders a author token value element', () => {
- const { tokenNameElement, tokenValueElement } = findElements(authorToken);
- const tokenName = tokenNameElement.innerText;
- const tokenValue = 'new value';
-
- subject.renderVisualTokenValue(authorToken, tokenName, tokenValue);
-
- expect(tokenValueElement.innerText).toBe(tokenValue);
- });
- });
-});
diff --git a/spec/javascripts/gl_dropdown_spec.js b/spec/javascripts/gl_dropdown_spec.js
deleted file mode 100644
index 06f76c581f2..00000000000
--- a/spec/javascripts/gl_dropdown_spec.js
+++ /dev/null
@@ -1,341 +0,0 @@
-/* eslint-disable no-param-reassign */
-
-import $ from 'jquery';
-import GLDropdown from '~/gl_dropdown';
-import '~/lib/utils/common_utils';
-
-describe('glDropdown', function describeDropdown() {
- preloadFixtures('static/gl_dropdown.html');
- loadJSONFixtures('static/projects.json');
-
- const NON_SELECTABLE_CLASSES =
- '.divider, .separator, .dropdown-header, .dropdown-menu-empty-item';
- const SEARCH_INPUT_SELECTOR = '.dropdown-input-field';
- const ITEM_SELECTOR = `.dropdown-content li:not(${NON_SELECTABLE_CLASSES})`;
- const FOCUSED_ITEM_SELECTOR = `${ITEM_SELECTOR} a.is-focused`;
-
- const ARROW_KEYS = {
- DOWN: 40,
- UP: 38,
- ENTER: 13,
- ESC: 27,
- };
-
- let remoteCallback;
-
- const navigateWithKeys = function navigateWithKeys(direction, steps, cb, i) {
- i = i || 0;
- if (!i) direction = direction.toUpperCase();
- $('body').trigger({
- type: 'keydown',
- which: ARROW_KEYS[direction],
- keyCode: ARROW_KEYS[direction],
- });
- i += 1;
- if (i <= steps) {
- navigateWithKeys(direction, steps, cb, i);
- } else {
- cb();
- }
- };
-
- const remoteMock = function remoteMock(data, term, callback) {
- remoteCallback = callback.bind({}, data);
- };
-
- function initDropDown(hasRemote, isFilterable, extraOpts = {}) {
- const options = {
- selectable: true,
- filterable: isFilterable,
- data: hasRemote ? remoteMock.bind({}, this.projectsData) : this.projectsData,
- search: {
- fields: ['name'],
- },
- text: project => project.name_with_namespace || project.name,
- id: project => project.id,
- ...extraOpts,
- };
- this.dropdownButtonElement = $(
- '#js-project-dropdown',
- this.dropdownContainerElement,
- ).glDropdown(options);
- }
-
- beforeEach(() => {
- loadFixtures('static/gl_dropdown.html');
- this.dropdownContainerElement = $('.dropdown.inline');
- this.$dropdownMenuElement = $('.dropdown-menu', this.dropdownContainerElement);
- this.projectsData = getJSONFixture('static/projects.json');
- });
-
- afterEach(() => {
- $('body').off('keydown');
- this.dropdownContainerElement.off('keyup');
- });
-
- it('should open on click', () => {
- initDropDown.call(this, false);
-
- expect(this.dropdownContainerElement).not.toHaveClass('show');
- this.dropdownButtonElement.click();
-
- expect(this.dropdownContainerElement).toHaveClass('show');
- });
-
- it('escapes HTML as text', () => {
- this.projectsData[0].name_with_namespace = '<script>alert("testing");</script>';
-
- initDropDown.call(this, false);
-
- this.dropdownButtonElement.click();
-
- expect($('.dropdown-content li:first-child').text()).toBe('<script>alert("testing");</script>');
- });
-
- it('should output HTML when highlighting', () => {
- this.projectsData[0].name_with_namespace = 'testing';
- $('.dropdown-input .dropdown-input-field').val('test');
-
- initDropDown.call(this, false, true, {
- highlight: true,
- });
-
- this.dropdownButtonElement.click();
-
- expect($('.dropdown-content li:first-child').text()).toBe('testing');
-
- expect($('.dropdown-content li:first-child a').html()).toBe(
- '<b>t</b><b>e</b><b>s</b><b>t</b>ing',
- );
- });
-
- describe('that is open', () => {
- beforeEach(() => {
- initDropDown.call(this, false, false);
- this.dropdownButtonElement.click();
- });
-
- it('should select a following item on DOWN keypress', () => {
- expect($(FOCUSED_ITEM_SELECTOR, this.$dropdownMenuElement).length).toBe(0);
- const randomIndex = Math.floor(Math.random() * (this.projectsData.length - 1)) + 0;
- navigateWithKeys('down', randomIndex, () => {
- expect($(FOCUSED_ITEM_SELECTOR, this.$dropdownMenuElement).length).toBe(1);
- expect($(`${ITEM_SELECTOR}:eq(${randomIndex}) a`, this.$dropdownMenuElement)).toHaveClass(
- 'is-focused',
- );
- });
- });
-
- it('should select a previous item on UP keypress', () => {
- expect($(FOCUSED_ITEM_SELECTOR, this.$dropdownMenuElement).length).toBe(0);
- navigateWithKeys('down', this.projectsData.length - 1, () => {
- expect($(FOCUSED_ITEM_SELECTOR, this.$dropdownMenuElement).length).toBe(1);
- const randomIndex = Math.floor(Math.random() * (this.projectsData.length - 2)) + 0;
- navigateWithKeys('up', randomIndex, () => {
- expect($(FOCUSED_ITEM_SELECTOR, this.$dropdownMenuElement).length).toBe(1);
- expect(
- $(
- `${ITEM_SELECTOR}:eq(${this.projectsData.length - 2 - randomIndex}) a`,
- this.$dropdownMenuElement,
- ),
- ).toHaveClass('is-focused');
- });
- });
- });
-
- it('should click the selected item on ENTER keypress', () => {
- expect(this.dropdownContainerElement).toHaveClass('show');
- const randomIndex = Math.floor(Math.random() * (this.projectsData.length - 1)) + 0;
- navigateWithKeys('down', randomIndex, () => {
- const visitUrl = spyOnDependency(GLDropdown, 'visitUrl').and.stub();
- navigateWithKeys('enter', null, () => {
- expect(this.dropdownContainerElement).not.toHaveClass('show');
- const link = $(`${ITEM_SELECTOR}:eq(${randomIndex}) a`, this.$dropdownMenuElement);
-
- expect(link).toHaveClass('is-active');
- const linkedLocation = link.attr('href');
- if (linkedLocation && linkedLocation !== '#') {
- expect(visitUrl).toHaveBeenCalledWith(linkedLocation);
- }
- });
- });
- });
-
- it('should close on ESC keypress', () => {
- expect(this.dropdownContainerElement).toHaveClass('show');
- this.dropdownContainerElement.trigger({
- type: 'keyup',
- which: ARROW_KEYS.ESC,
- keyCode: ARROW_KEYS.ESC,
- });
-
- expect(this.dropdownContainerElement).not.toHaveClass('show');
- });
- });
-
- describe('opened and waiting for a remote callback', () => {
- beforeEach(() => {
- initDropDown.call(this, true, true);
- this.dropdownButtonElement.click();
- });
-
- it('should show loading indicator while search results are being fetched by backend', () => {
- const dropdownMenu = document.querySelector('.dropdown-menu');
-
- expect(dropdownMenu.className.indexOf('is-loading')).not.toBe(-1);
- remoteCallback();
-
- expect(dropdownMenu.className.indexOf('is-loading')).toBe(-1);
- });
-
- it('should not focus search input while remote task is not complete', () => {
- expect($(document.activeElement)).not.toEqual($(SEARCH_INPUT_SELECTOR));
- remoteCallback();
-
- expect($(document.activeElement)).toEqual($(SEARCH_INPUT_SELECTOR));
- });
-
- it('should focus search input after remote task is complete', () => {
- remoteCallback();
-
- expect($(document.activeElement)).toEqual($(SEARCH_INPUT_SELECTOR));
- });
-
- it('should focus on input when opening for the second time after transition', () => {
- remoteCallback();
- this.dropdownContainerElement.trigger({
- type: 'keyup',
- which: ARROW_KEYS.ESC,
- keyCode: ARROW_KEYS.ESC,
- });
- this.dropdownButtonElement.click();
- this.dropdownContainerElement.trigger('transitionend');
-
- expect($(document.activeElement)).toEqual($(SEARCH_INPUT_SELECTOR));
- });
- });
-
- describe('input focus with array data', () => {
- it('should focus input when passing array data to drop down', () => {
- initDropDown.call(this, false, true);
- this.dropdownButtonElement.click();
- this.dropdownContainerElement.trigger('transitionend');
-
- expect($(document.activeElement)).toEqual($(SEARCH_INPUT_SELECTOR));
- });
- });
-
- it('should still have input value on close and restore', () => {
- const $searchInput = $(SEARCH_INPUT_SELECTOR);
- initDropDown.call(this, false, true);
- $searchInput
- .trigger('focus')
- .val('g')
- .trigger('input');
-
- expect($searchInput.val()).toEqual('g');
- this.dropdownButtonElement.trigger('hidden.bs.dropdown');
- $searchInput.trigger('blur').trigger('focus');
-
- expect($searchInput.val()).toEqual('g');
- });
-
- describe('renderItem', () => {
- function dropdownWithOptions(options) {
- const $dropdownDiv = $('<div />');
-
- $dropdownDiv.glDropdown(options);
-
- return $dropdownDiv.data('glDropdown');
- }
-
- function basicDropdown() {
- return dropdownWithOptions({});
- }
-
- describe('without selected value', () => {
- let dropdown;
-
- beforeEach(() => {
- dropdown = basicDropdown();
- });
-
- it('marks items without ID as active', () => {
- const dummyData = {};
-
- const html = dropdown.renderItem(dummyData, null, null);
-
- const link = html.querySelector('a');
-
- expect(link).toHaveClass('is-active');
- });
-
- it('does not mark items with ID as active', () => {
- const dummyData = {
- id: 'ea',
- };
-
- const html = dropdown.renderItem(dummyData, null, null);
-
- const link = html.querySelector('a');
-
- expect(link).not.toHaveClass('is-active');
- });
- });
-
- it('should return an empty .separator li when when appropriate', () => {
- const dropdown = basicDropdown();
- const sep = { type: 'separator' };
- const li = dropdown.renderItem(sep);
-
- expect(li).toHaveClass('separator');
- expect(li.childNodes.length).toEqual(0);
- });
-
- it('should return an empty .divider li when when appropriate', () => {
- const dropdown = basicDropdown();
- const div = { type: 'divider' };
- const li = dropdown.renderItem(div);
-
- expect(li).toHaveClass('divider');
- expect(li.childNodes.length).toEqual(0);
- });
-
- it('should return a .dropdown-header li with the correct content when when appropriate', () => {
- const dropdown = basicDropdown();
- const text = 'My Header';
- const header = { type: 'header', content: text };
- const li = dropdown.renderItem(header);
-
- expect(li).toHaveClass('dropdown-header');
- expect(li.childNodes.length).toEqual(1);
- expect(li.textContent).toEqual(text);
- });
- });
-
- it('should keep selected item after selecting a second time', () => {
- const options = {
- isSelectable(item, $el) {
- return !$el.hasClass('is-active');
- },
- toggleLabel(item) {
- return item && item.id;
- },
- };
- initDropDown.call(this, false, false, options);
- const $item = $(`${ITEM_SELECTOR}:first() a`, this.$dropdownMenuElement);
-
- // select item the first time
- this.dropdownButtonElement.click();
- $item.click();
-
- expect($item).toHaveClass('is-active');
- // select item the second time
- this.dropdownButtonElement.click();
- $item.click();
-
- expect($item).toHaveClass('is-active');
-
- expect($('.dropdown-toggle-text')).toHaveText(this.projectsData[0].id.toString());
- });
-});
diff --git a/spec/javascripts/gl_form_spec.js b/spec/javascripts/gl_form_spec.js
deleted file mode 100644
index 69b3dae743a..00000000000
--- a/spec/javascripts/gl_form_spec.js
+++ /dev/null
@@ -1,110 +0,0 @@
-import $ from 'jquery';
-import autosize from 'autosize';
-import GLForm from '~/gl_form';
-import '~/lib/utils/text_utility';
-import '~/lib/utils/common_utils';
-
-describe('GLForm', () => {
- describe('when instantiated', function() {
- beforeEach(done => {
- this.form = $('<form class="gfm-form"><textarea class="js-gfm-input"></form>');
- this.textarea = this.form.find('textarea');
- spyOn($.prototype, 'off').and.returnValue(this.textarea);
- spyOn($.prototype, 'on').and.returnValue(this.textarea);
- spyOn($.prototype, 'css');
-
- this.glForm = new GLForm(this.form, false);
- setTimeout(() => {
- $.prototype.off.calls.reset();
- $.prototype.on.calls.reset();
- $.prototype.css.calls.reset();
- done();
- });
- });
-
- describe('setupAutosize', () => {
- beforeEach(done => {
- this.glForm.setupAutosize();
- setTimeout(() => {
- done();
- });
- });
-
- it('should register an autosize event handler on the textarea', () => {
- expect($.prototype.off).toHaveBeenCalledWith('autosize:resized');
- expect($.prototype.on).toHaveBeenCalledWith('autosize:resized', jasmine.any(Function));
- });
-
- it('should register a mouseup event handler on the textarea', () => {
- expect($.prototype.off).toHaveBeenCalledWith('mouseup.autosize');
- expect($.prototype.on).toHaveBeenCalledWith('mouseup.autosize', jasmine.any(Function));
- });
-
- it('should set the resize css property to vertical', () => {
- expect($.prototype.css).toHaveBeenCalledWith('resize', 'vertical');
- });
- });
-
- describe('setHeightData', () => {
- beforeEach(() => {
- spyOn($.prototype, 'data');
- spyOn($.prototype, 'outerHeight').and.returnValue(200);
- this.glForm.setHeightData();
- });
-
- it('should set the height data attribute', () => {
- expect($.prototype.data).toHaveBeenCalledWith('height', 200);
- });
-
- it('should call outerHeight', () => {
- expect($.prototype.outerHeight).toHaveBeenCalled();
- });
- });
-
- describe('destroyAutosize', () => {
- describe('when called', () => {
- beforeEach(() => {
- spyOn($.prototype, 'data');
- spyOn($.prototype, 'outerHeight').and.returnValue(200);
- spyOn(window, 'outerHeight').and.returnValue(400);
- spyOn(autosize, 'destroy');
-
- this.glForm.destroyAutosize();
- });
-
- it('should call outerHeight', () => {
- expect($.prototype.outerHeight).toHaveBeenCalled();
- });
-
- it('should get data-height attribute', () => {
- expect($.prototype.data).toHaveBeenCalledWith('height');
- });
-
- it('should call autosize destroy', () => {
- expect(autosize.destroy).toHaveBeenCalledWith(this.textarea);
- });
-
- it('should set the data-height attribute', () => {
- expect($.prototype.data).toHaveBeenCalledWith('height', 200);
- });
-
- it('should set the outerHeight', () => {
- expect($.prototype.outerHeight).toHaveBeenCalledWith(200);
- });
-
- it('should set the css', () => {
- expect($.prototype.css).toHaveBeenCalledWith('max-height', window.outerHeight);
- });
- });
-
- it('should return undefined if the data-height equals the outerHeight', () => {
- spyOn($.prototype, 'outerHeight').and.returnValue(200);
- spyOn($.prototype, 'data').and.returnValue(200);
- spyOn(autosize, 'destroy');
-
- expect(this.glForm.destroyAutosize()).toBeUndefined();
- expect(autosize.destroy).not.toHaveBeenCalled();
- });
- });
- });
-});
diff --git a/spec/javascripts/helpers/scroll_into_view_promise.js b/spec/javascripts/helpers/scroll_into_view_promise.js
deleted file mode 100644
index 0edea2103da..00000000000
--- a/spec/javascripts/helpers/scroll_into_view_promise.js
+++ /dev/null
@@ -1,28 +0,0 @@
-export default function scrollIntoViewPromise(intersectionTarget, timeout = 100, maxTries = 5) {
- return new Promise((resolve, reject) => {
- let intersectionObserver;
- let retry = 0;
-
- const intervalId = setInterval(() => {
- if (retry >= maxTries) {
- intersectionObserver.disconnect();
- clearInterval(intervalId);
- reject(new Error(`Could not scroll target into viewPort within ${timeout * maxTries} ms`));
- }
- retry += 1;
- intersectionTarget.scrollIntoView();
- }, timeout);
-
- intersectionObserver = new IntersectionObserver(entries => {
- if (entries[0].isIntersecting) {
- intersectionObserver.disconnect();
- clearInterval(intervalId);
- resolve();
- }
- });
-
- intersectionObserver.observe(intersectionTarget);
-
- intersectionTarget.scrollIntoView();
- });
-}
diff --git a/spec/javascripts/helpers/vuex_action_helper_spec.js b/spec/javascripts/helpers/vuex_action_helper_spec.js
deleted file mode 100644
index 09f0bd395c3..00000000000
--- a/spec/javascripts/helpers/vuex_action_helper_spec.js
+++ /dev/null
@@ -1,166 +0,0 @@
-import MockAdapter from 'axios-mock-adapter';
-import { TEST_HOST } from 'spec/test_constants';
-import axios from '~/lib/utils/axios_utils';
-import testAction from './vuex_action_helper';
-
-describe('VueX test helper (testAction)', () => {
- let originalExpect;
- let assertion;
- let mock;
- const noop = () => {};
-
- beforeAll(() => {
- mock = new MockAdapter(axios);
- /*
- In order to test the helper properly, we need to overwrite the jasmine `expect` helper.
- We test that the testAction helper properly passes the dispatched actions/committed mutations
- to the jasmine helper.
- */
- originalExpect = expect;
- assertion = null;
- global.expect = actual => ({
- toEqual: () => {
- originalExpect(actual).toEqual(assertion);
- },
- });
- });
-
- afterAll(() => {
- mock.restore();
- global.expect = originalExpect;
- });
-
- it('should properly pass on state and payload', () => {
- const exampleState = { FOO: 12, BAR: 3 };
- const examplePayload = { BAZ: 73, BIZ: 55 };
-
- const action = ({ state }, payload) => {
- originalExpect(state).toEqual(exampleState);
- originalExpect(payload).toEqual(examplePayload);
- };
-
- assertion = { mutations: [], actions: [] };
-
- testAction(action, examplePayload, exampleState);
- });
-
- describe('should work with synchronous actions', () => {
- it('committing mutation', () => {
- const action = ({ commit }) => {
- commit('MUTATION');
- };
-
- assertion = { mutations: [{ type: 'MUTATION' }], actions: [] };
-
- testAction(action, null, {}, assertion.mutations, assertion.actions, noop);
- });
-
- it('dispatching action', () => {
- const action = ({ dispatch }) => {
- dispatch('ACTION');
- };
-
- assertion = { actions: [{ type: 'ACTION' }], mutations: [] };
-
- testAction(action, null, {}, assertion.mutations, assertion.actions, noop);
- });
-
- it('work with jasmine done once finished', done => {
- assertion = { mutations: [], actions: [] };
-
- testAction(noop, null, {}, assertion.mutations, assertion.actions, done);
- });
-
- it('provide promise interface', done => {
- assertion = { mutations: [], actions: [] };
-
- testAction(noop, null, {}, assertion.mutations, assertion.actions)
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('should work with promise based actions (fetch action)', () => {
- let lastError;
- const data = { FOO: 'BAR' };
-
- const promiseAction = ({ commit, dispatch }) => {
- dispatch('ACTION');
-
- return axios
- .get(TEST_HOST)
- .catch(error => {
- commit('ERROR');
- lastError = error;
- throw error;
- })
- .then(() => {
- commit('SUCCESS');
- return data;
- });
- };
-
- beforeEach(() => {
- lastError = null;
- });
-
- it('work with jasmine done once finished', done => {
- mock.onGet(TEST_HOST).replyOnce(200, 42);
-
- assertion = { mutations: [{ type: 'SUCCESS' }], actions: [{ type: 'ACTION' }] };
-
- testAction(promiseAction, null, {}, assertion.mutations, assertion.actions, done);
- });
-
- it('return original data of successful promise while checking actions/mutations', done => {
- mock.onGet(TEST_HOST).replyOnce(200, 42);
-
- assertion = { mutations: [{ type: 'SUCCESS' }], actions: [{ type: 'ACTION' }] };
-
- testAction(promiseAction, null, {}, assertion.mutations, assertion.actions)
- .then(res => {
- originalExpect(res).toEqual(data);
- done();
- })
- .catch(done.fail);
- });
-
- it('return original error of rejected promise while checking actions/mutations', done => {
- mock.onGet(TEST_HOST).replyOnce(500, '');
-
- assertion = { mutations: [{ type: 'ERROR' }], actions: [{ type: 'ACTION' }] };
-
- testAction(promiseAction, null, {}, assertion.mutations, assertion.actions)
- .then(done.fail)
- .catch(error => {
- originalExpect(error).toBe(lastError);
- done();
- });
- });
- });
-
- it('should work with async actions not returning promises', done => {
- const data = { FOO: 'BAR' };
-
- const promiseAction = ({ commit, dispatch }) => {
- dispatch('ACTION');
-
- axios
- .get(TEST_HOST)
- .then(() => {
- commit('SUCCESS');
- return data;
- })
- .catch(error => {
- commit('ERROR');
- throw error;
- });
- };
-
- mock.onGet(TEST_HOST).replyOnce(200, 42);
-
- assertion = { mutations: [{ type: 'SUCCESS' }], actions: [{ type: 'ACTION' }] };
-
- testAction(promiseAction, null, {}, assertion.mutations, assertion.actions, done);
- });
-});
diff --git a/spec/javascripts/helpers/wait_for_attribute_change.js b/spec/javascripts/helpers/wait_for_attribute_change.js
deleted file mode 100644
index 8f22d569222..00000000000
--- a/spec/javascripts/helpers/wait_for_attribute_change.js
+++ /dev/null
@@ -1,16 +0,0 @@
-export default (domElement, attributes, timeout = 1500) =>
- new Promise((resolve, reject) => {
- let observer;
- const timeoutId = setTimeout(() => {
- observer.disconnect();
- reject(new Error(`Could not see an attribute update within ${timeout} ms`));
- }, timeout);
-
- observer = new MutationObserver(() => {
- clearTimeout(timeoutId);
- observer.disconnect();
- resolve();
- });
-
- observer.observe(domElement, { attributes: true, attributeFilter: attributes });
- });
diff --git a/spec/javascripts/ide/components/commit_sidebar/message_field_spec.js b/spec/javascripts/ide/components/commit_sidebar/message_field_spec.js
deleted file mode 100644
index 53508f52b2f..00000000000
--- a/spec/javascripts/ide/components/commit_sidebar/message_field_spec.js
+++ /dev/null
@@ -1,170 +0,0 @@
-import Vue from 'vue';
-import createComponent from 'spec/helpers/vue_mount_component_helper';
-import CommitMessageField from '~/ide/components/commit_sidebar/message_field.vue';
-
-describe('IDE commit message field', () => {
- const Component = Vue.extend(CommitMessageField);
- let vm;
-
- beforeEach(() => {
- setFixtures('<div id="app"></div>');
-
- vm = createComponent(
- Component,
- {
- text: '',
- placeholder: 'testing',
- },
- '#app',
- );
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('adds is-focused class on focus', done => {
- vm.$el.querySelector('textarea').focus();
-
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.is-focused')).not.toBeNull();
-
- done();
- });
- });
-
- it('removed is-focused class on blur', done => {
- vm.$el.querySelector('textarea').focus();
-
- vm.$nextTick()
- .then(() => {
- expect(vm.$el.querySelector('.is-focused')).not.toBeNull();
-
- vm.$el.querySelector('textarea').blur();
-
- return vm.$nextTick();
- })
- .then(() => {
- expect(vm.$el.querySelector('.is-focused')).toBeNull();
-
- done();
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('emits input event on input', () => {
- spyOn(vm, '$emit');
-
- const textarea = vm.$el.querySelector('textarea');
- textarea.value = 'testing';
-
- textarea.dispatchEvent(new Event('input'));
-
- expect(vm.$emit).toHaveBeenCalledWith('input', 'testing');
- });
-
- describe('highlights', () => {
- describe('subject line', () => {
- it('does not highlight less than 50 characters', done => {
- vm.text = 'text less than 50 chars';
-
- vm.$nextTick()
- .then(() => {
- expect(vm.$el.querySelector('.highlights span').textContent).toContain(
- 'text less than 50 chars',
- );
-
- expect(vm.$el.querySelector('mark').style.display).toBe('none');
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('highlights characters over 50 length', done => {
- vm.text =
- 'text less than 50 chars that should not highlighted. text more than 50 should be highlighted';
-
- vm.$nextTick()
- .then(() => {
- expect(vm.$el.querySelector('.highlights span').textContent).toContain(
- 'text less than 50 chars that should not highlighte',
- );
-
- expect(vm.$el.querySelector('mark').style.display).not.toBe('none');
- expect(vm.$el.querySelector('mark').textContent).toBe(
- 'd. text more than 50 should be highlighted',
- );
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('body text', () => {
- it('does not highlight body text less tan 72 characters', done => {
- vm.text = 'subject line\nbody content';
-
- vm.$nextTick()
- .then(() => {
- expect(vm.$el.querySelectorAll('.highlights span').length).toBe(2);
- expect(vm.$el.querySelectorAll('mark')[1].style.display).toBe('none');
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('highlights body text more than 72 characters', done => {
- vm.text =
- 'subject line\nbody content that will be highlighted when it is more than 72 characters in length';
-
- vm.$nextTick()
- .then(() => {
- expect(vm.$el.querySelectorAll('.highlights span').length).toBe(2);
- expect(vm.$el.querySelectorAll('mark')[1].style.display).not.toBe('none');
- expect(vm.$el.querySelectorAll('mark')[1].textContent).toBe(' in length');
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('highlights body text & subject line', done => {
- vm.text =
- 'text less than 50 chars that should not highlighted\nbody content that will be highlighted when it is more than 72 characters in length';
-
- vm.$nextTick()
- .then(() => {
- expect(vm.$el.querySelectorAll('.highlights span').length).toBe(2);
- expect(vm.$el.querySelectorAll('mark').length).toBe(2);
-
- expect(vm.$el.querySelectorAll('mark')[0].textContent).toContain('d');
- expect(vm.$el.querySelectorAll('mark')[1].textContent).toBe(' in length');
- })
- .then(done)
- .catch(done.fail);
- });
- });
- });
-
- describe('scrolling textarea', () => {
- it('updates transform of highlights', done => {
- vm.text = 'subject line\n\n\n\n\n\n\n\n\n\n\nbody content';
-
- vm.$nextTick()
- .then(() => {
- vm.$el.querySelector('textarea').scrollTo(0, 50);
-
- vm.handleScroll();
- })
- .then(vm.$nextTick)
- .then(() => {
- expect(vm.scrollTop).toBe(50);
- expect(vm.$el.querySelector('.highlights').style.transform).toBe(
- 'translate3d(0px, -50px, 0px)',
- );
- })
- .then(done)
- .catch(done.fail);
- });
- });
-});
diff --git a/spec/javascripts/ide/components/jobs/detail_spec.js b/spec/javascripts/ide/components/jobs/detail_spec.js
deleted file mode 100644
index a4e6b81acba..00000000000
--- a/spec/javascripts/ide/components/jobs/detail_spec.js
+++ /dev/null
@@ -1,184 +0,0 @@
-import Vue from 'vue';
-import JobDetail from '~/ide/components/jobs/detail.vue';
-import { createStore } from '~/ide/stores';
-import { createComponentWithStore } from '../../../helpers/vue_mount_component_helper';
-import { jobs } from '../../mock_data';
-
-describe('IDE jobs detail view', () => {
- const Component = Vue.extend(JobDetail);
- let vm;
-
- beforeEach(() => {
- const store = createStore();
-
- store.state.pipelines.detailJob = {
- ...jobs[0],
- isLoading: true,
- output: 'testing',
- rawPath: `${gl.TEST_HOST}/raw`,
- };
-
- vm = createComponentWithStore(Component, store);
-
- spyOn(vm, 'fetchJobTrace').and.returnValue(Promise.resolve());
-
- vm = vm.$mount();
-
- spyOn(vm.$refs.buildTrace, 'scrollTo');
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('calls fetchJobTrace on mount', () => {
- expect(vm.fetchJobTrace).toHaveBeenCalled();
- });
-
- it('scrolls to bottom on mount', done => {
- setTimeout(() => {
- expect(vm.$refs.buildTrace.scrollTo).toHaveBeenCalled();
-
- done();
- });
- });
-
- it('renders job output', () => {
- expect(vm.$el.querySelector('.bash').textContent).toContain('testing');
- });
-
- it('renders empty message output', done => {
- vm.$store.state.pipelines.detailJob.output = '';
-
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.bash').textContent).toContain('No messages were logged');
-
- done();
- });
- });
-
- it('renders loading icon', () => {
- expect(vm.$el.querySelector('.build-loader-animation')).not.toBe(null);
- expect(vm.$el.querySelector('.build-loader-animation').style.display).toBe('');
- });
-
- it('hides output when loading', () => {
- expect(vm.$el.querySelector('.bash')).not.toBe(null);
- expect(vm.$el.querySelector('.bash').style.display).toBe('none');
- });
-
- it('hide loading icon when isLoading is false', done => {
- vm.$store.state.pipelines.detailJob.isLoading = false;
-
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.build-loader-animation').style.display).toBe('none');
-
- done();
- });
- });
-
- it('resets detailJob when clicking header button', () => {
- spyOn(vm, 'setDetailJob');
-
- vm.$el.querySelector('.btn').click();
-
- expect(vm.setDetailJob).toHaveBeenCalledWith(null);
- });
-
- it('renders raw path link', () => {
- expect(vm.$el.querySelector('.controllers-buttons').getAttribute('href')).toBe(
- `${gl.TEST_HOST}/raw`,
- );
- });
-
- describe('scroll buttons', () => {
- it('triggers scrollDown when clicking down button', done => {
- spyOn(vm, 'scrollDown');
-
- vm.$el.querySelectorAll('.btn-scroll')[1].click();
-
- vm.$nextTick(() => {
- expect(vm.scrollDown).toHaveBeenCalled();
-
- done();
- });
- });
-
- it('triggers scrollUp when clicking up button', done => {
- spyOn(vm, 'scrollUp');
-
- vm.scrollPos = 1;
-
- vm.$nextTick()
- .then(() => vm.$el.querySelector('.btn-scroll').click())
- .then(() => vm.$nextTick())
- .then(() => {
- expect(vm.scrollUp).toHaveBeenCalled();
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('scrollDown', () => {
- it('scrolls build trace to bottom', () => {
- spyOnProperty(vm.$refs.buildTrace, 'scrollHeight').and.returnValue(1000);
-
- vm.scrollDown();
-
- expect(vm.$refs.buildTrace.scrollTo).toHaveBeenCalledWith(0, 1000);
- });
- });
-
- describe('scrollUp', () => {
- it('scrolls build trace to top', () => {
- vm.scrollUp();
-
- expect(vm.$refs.buildTrace.scrollTo).toHaveBeenCalledWith(0, 0);
- });
- });
-
- describe('scrollBuildLog', () => {
- beforeEach(() => {
- spyOnProperty(vm.$refs.buildTrace, 'offsetHeight').and.returnValue(100);
- spyOnProperty(vm.$refs.buildTrace, 'scrollHeight').and.returnValue(200);
- });
-
- it('sets scrollPos to bottom when at the bottom', done => {
- spyOnProperty(vm.$refs.buildTrace, 'scrollTop').and.returnValue(100);
-
- vm.scrollBuildLog();
-
- setTimeout(() => {
- expect(vm.scrollPos).toBe(1);
-
- done();
- });
- });
-
- it('sets scrollPos to top when at the top', done => {
- spyOnProperty(vm.$refs.buildTrace, 'scrollTop').and.returnValue(0);
- vm.scrollPos = 1;
-
- vm.scrollBuildLog();
-
- setTimeout(() => {
- expect(vm.scrollPos).toBe(0);
-
- done();
- });
- });
-
- it('resets scrollPos when not at top or bottom', done => {
- spyOnProperty(vm.$refs.buildTrace, 'scrollTop').and.returnValue(10);
-
- vm.scrollBuildLog();
-
- setTimeout(() => {
- expect(vm.scrollPos).toBe('');
-
- done();
- });
- });
- });
-});
diff --git a/spec/javascripts/ide/components/repo_editor_spec.js b/spec/javascripts/ide/components/repo_editor_spec.js
deleted file mode 100644
index 8db29011da7..00000000000
--- a/spec/javascripts/ide/components/repo_editor_spec.js
+++ /dev/null
@@ -1,512 +0,0 @@
-import Vue from 'vue';
-import MockAdapter from 'axios-mock-adapter';
-import '~/behaviors/markdown/render_gfm';
-import axios from '~/lib/utils/axios_utils';
-import store from '~/ide/stores';
-import repoEditor from '~/ide/components/repo_editor.vue';
-import Editor from '~/ide/lib/editor';
-import { leftSidebarViews, FILE_VIEW_MODE_EDITOR, FILE_VIEW_MODE_PREVIEW } from '~/ide/constants';
-import { createComponentWithStore } from '../../helpers/vue_mount_component_helper';
-import setTimeoutPromise from '../../helpers/set_timeout_promise_helper';
-import { file, resetStore } from '../helpers';
-
-describe('RepoEditor', () => {
- let vm;
-
- beforeEach(done => {
- const f = {
- ...file(),
- viewMode: FILE_VIEW_MODE_EDITOR,
- };
- const RepoEditor = Vue.extend(repoEditor);
-
- vm = createComponentWithStore(RepoEditor, store, {
- file: f,
- });
-
- f.active = true;
- f.tempFile = true;
-
- vm.$store.state.openFiles.push(f);
- vm.$store.state.projects = {
- 'gitlab-org/gitlab': {
- branches: {
- master: {
- name: 'master',
- commit: {
- id: 'abcdefgh',
- },
- },
- },
- },
- };
- vm.$store.state.currentProjectId = 'gitlab-org/gitlab';
- vm.$store.state.currentBranchId = 'master';
-
- Vue.set(vm.$store.state.entries, f.path, f);
-
- spyOn(vm, 'getFileData').and.returnValue(Promise.resolve());
- spyOn(vm, 'getRawFileData').and.returnValue(Promise.resolve());
-
- vm.$mount();
-
- Vue.nextTick(() => setTimeout(done));
- });
-
- afterEach(() => {
- vm.$destroy();
-
- resetStore(vm.$store);
-
- Editor.editorInstance.dispose();
- });
-
- const findEditor = () => vm.$el.querySelector('.multi-file-editor-holder');
-
- it('sets renderWhitespace to `all`', () => {
- vm.$store.state.renderWhitespaceInCode = true;
-
- expect(vm.editorOptions.renderWhitespace).toEqual('all');
- });
-
- it('sets renderWhitespace to `none`', () => {
- vm.$store.state.renderWhitespaceInCode = false;
-
- expect(vm.editorOptions.renderWhitespace).toEqual('none');
- });
-
- it('renders an ide container', () => {
- expect(vm.shouldHideEditor).toBeFalsy();
- expect(vm.showEditor).toBe(true);
- expect(findEditor()).not.toHaveCss({ display: 'none' });
- });
-
- it('renders only an edit tab', done => {
- Vue.nextTick(() => {
- const tabs = vm.$el.querySelectorAll('.ide-mode-tabs .nav-links li');
-
- expect(tabs.length).toBe(1);
- expect(tabs[0].textContent.trim()).toBe('Edit');
-
- done();
- });
- });
-
- describe('when file is markdown', () => {
- beforeEach(done => {
- vm.file.previewMode = {
- id: 'markdown',
- previewTitle: 'Preview Markdown',
- };
-
- vm.$nextTick(done);
- });
-
- it('renders an Edit and a Preview Tab', done => {
- Vue.nextTick(() => {
- const tabs = vm.$el.querySelectorAll('.ide-mode-tabs .nav-links li');
-
- expect(tabs.length).toBe(2);
- expect(tabs[0].textContent.trim()).toBe('Edit');
- expect(tabs[1].textContent.trim()).toBe('Preview Markdown');
-
- done();
- });
- });
- });
-
- describe('when file is markdown and viewer mode is review', () => {
- let mock;
-
- beforeEach(done => {
- mock = new MockAdapter(axios);
-
- vm.file.projectId = 'namespace/project';
- vm.file.previewMode = {
- id: 'markdown',
- previewTitle: 'Preview Markdown',
- };
- vm.file.content = 'testing 123';
- vm.$store.state.viewer = 'diff';
-
- mock.onPost(/(.*)\/preview_markdown/).reply(200, {
- body: '<p>testing 123</p>',
- });
-
- vm.$nextTick(done);
- });
-
- afterEach(() => {
- mock.restore();
- });
-
- it('renders an Edit and a Preview Tab', done => {
- Vue.nextTick(() => {
- const tabs = vm.$el.querySelectorAll('.ide-mode-tabs .nav-links li');
-
- expect(tabs.length).toBe(2);
- expect(tabs[0].textContent.trim()).toBe('Review');
- expect(tabs[1].textContent.trim()).toBe('Preview Markdown');
-
- done();
- });
- });
-
- it('renders markdown for tempFile', done => {
- vm.file.tempFile = true;
- vm.file.path = `${vm.file.path}.md`;
- vm.$store.state.entries[vm.file.path] = vm.file;
-
- vm.$nextTick()
- .then(() => {
- vm.$el.querySelectorAll('.ide-mode-tabs .nav-links a')[1].click();
- })
- .then(setTimeoutPromise)
- .then(() => {
- expect(vm.$el.querySelector('.preview-container').innerHTML).toContain(
- '<p>testing 123</p>',
- );
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('when open file is binary and not raw', () => {
- beforeEach(done => {
- vm.file.binary = true;
-
- vm.$nextTick(done);
- });
-
- it('does not render the IDE', () => {
- expect(vm.shouldHideEditor).toBeTruthy();
- });
- });
-
- describe('createEditorInstance', () => {
- it('calls createInstance when viewer is editor', done => {
- spyOn(vm.editor, 'createInstance');
-
- vm.createEditorInstance();
-
- vm.$nextTick(() => {
- expect(vm.editor.createInstance).toHaveBeenCalled();
-
- done();
- });
- });
-
- it('calls createDiffInstance when viewer is diff', done => {
- vm.$store.state.viewer = 'diff';
-
- spyOn(vm.editor, 'createDiffInstance');
-
- vm.createEditorInstance();
-
- vm.$nextTick(() => {
- expect(vm.editor.createDiffInstance).toHaveBeenCalled();
-
- done();
- });
- });
-
- it('calls createDiffInstance when viewer is a merge request diff', done => {
- vm.$store.state.viewer = 'mrdiff';
-
- spyOn(vm.editor, 'createDiffInstance');
-
- vm.createEditorInstance();
-
- vm.$nextTick(() => {
- expect(vm.editor.createDiffInstance).toHaveBeenCalled();
-
- done();
- });
- });
- });
-
- describe('setupEditor', () => {
- it('creates new model', () => {
- spyOn(vm.editor, 'createModel').and.callThrough();
-
- Editor.editorInstance.modelManager.dispose();
-
- vm.setupEditor();
-
- expect(vm.editor.createModel).toHaveBeenCalledWith(vm.file, null);
- expect(vm.model).not.toBeNull();
- });
-
- it('attaches model to editor', () => {
- spyOn(vm.editor, 'attachModel').and.callThrough();
-
- Editor.editorInstance.modelManager.dispose();
-
- vm.setupEditor();
-
- expect(vm.editor.attachModel).toHaveBeenCalledWith(vm.model);
- });
-
- it('attaches model to merge request editor', () => {
- vm.$store.state.viewer = 'mrdiff';
- vm.file.mrChange = true;
- spyOn(vm.editor, 'attachMergeRequestModel');
-
- Editor.editorInstance.modelManager.dispose();
-
- vm.setupEditor();
-
- expect(vm.editor.attachMergeRequestModel).toHaveBeenCalledWith(vm.model);
- });
-
- it('does not attach model to merge request editor when not a MR change', () => {
- vm.$store.state.viewer = 'mrdiff';
- vm.file.mrChange = false;
- spyOn(vm.editor, 'attachMergeRequestModel');
-
- Editor.editorInstance.modelManager.dispose();
-
- vm.setupEditor();
-
- expect(vm.editor.attachMergeRequestModel).not.toHaveBeenCalledWith(vm.model);
- });
-
- it('adds callback methods', () => {
- spyOn(vm.editor, 'onPositionChange').and.callThrough();
-
- Editor.editorInstance.modelManager.dispose();
-
- vm.setupEditor();
-
- expect(vm.editor.onPositionChange).toHaveBeenCalled();
- expect(vm.model.events.size).toBe(2);
- });
-
- it('updates state when model content changed', done => {
- vm.model.setValue('testing 123\n');
-
- setTimeout(() => {
- expect(vm.file.content).toBe('testing 123\n');
-
- done();
- });
- });
-
- it('sets head model as staged file', () => {
- spyOn(vm.editor, 'createModel').and.callThrough();
-
- Editor.editorInstance.modelManager.dispose();
-
- vm.$store.state.stagedFiles.push({ ...vm.file, key: 'staged' });
- vm.file.staged = true;
- vm.file.key = `unstaged-${vm.file.key}`;
-
- vm.setupEditor();
-
- expect(vm.editor.createModel).toHaveBeenCalledWith(vm.file, vm.$store.state.stagedFiles[0]);
- });
- });
-
- describe('editor updateDimensions', () => {
- beforeEach(() => {
- spyOn(vm.editor, 'updateDimensions').and.callThrough();
- spyOn(vm.editor, 'updateDiffView');
- });
-
- it('calls updateDimensions when panelResizing is false', done => {
- vm.$store.state.panelResizing = true;
-
- vm.$nextTick()
- .then(() => {
- vm.$store.state.panelResizing = false;
- })
- .then(vm.$nextTick)
- .then(() => {
- expect(vm.editor.updateDimensions).toHaveBeenCalled();
- expect(vm.editor.updateDiffView).toHaveBeenCalled();
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('does not call updateDimensions when panelResizing is true', done => {
- vm.$store.state.panelResizing = true;
-
- vm.$nextTick(() => {
- expect(vm.editor.updateDimensions).not.toHaveBeenCalled();
- expect(vm.editor.updateDiffView).not.toHaveBeenCalled();
-
- done();
- });
- });
-
- it('calls updateDimensions when rightPane is opened', done => {
- vm.$store.state.rightPane.isOpen = true;
-
- vm.$nextTick(() => {
- expect(vm.editor.updateDimensions).toHaveBeenCalled();
- expect(vm.editor.updateDiffView).toHaveBeenCalled();
-
- done();
- });
- });
- });
-
- describe('show tabs', () => {
- it('shows tabs in edit mode', () => {
- expect(vm.$el.querySelector('.nav-links')).not.toBe(null);
- });
-
- it('hides tabs in review mode', done => {
- vm.$store.state.currentActivityView = leftSidebarViews.review.name;
-
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.nav-links')).toBe(null);
-
- done();
- });
- });
-
- it('hides tabs in commit mode', done => {
- vm.$store.state.currentActivityView = leftSidebarViews.commit.name;
-
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.nav-links')).toBe(null);
-
- done();
- });
- });
- });
-
- describe('when files view mode is preview', () => {
- beforeEach(done => {
- spyOn(vm.editor, 'updateDimensions');
- vm.file.viewMode = FILE_VIEW_MODE_PREVIEW;
- vm.$nextTick(done);
- });
-
- it('should hide editor', () => {
- expect(vm.showEditor).toBe(false);
- expect(findEditor()).toHaveCss({ display: 'none' });
- });
-
- describe('when file view mode changes to editor', () => {
- beforeEach(done => {
- vm.file.viewMode = FILE_VIEW_MODE_EDITOR;
-
- // one tick to trigger watch
- vm.$nextTick()
- // another tick needed until we can update dimensions
- .then(() => vm.$nextTick())
- .then(done)
- .catch(done.fail);
- });
-
- it('should update dimensions', () => {
- expect(vm.editor.updateDimensions).toHaveBeenCalled();
- });
- });
- });
-
- describe('initEditor', () => {
- beforeEach(() => {
- vm.file.tempFile = false;
- spyOn(vm.editor, 'createInstance');
- spyOnProperty(vm, 'shouldHideEditor').and.returnValue(true);
- });
-
- it('does not fetch file information for temp entries', done => {
- vm.file.tempFile = true;
-
- vm.initEditor();
- vm.$nextTick()
- .then(() => {
- expect(vm.getFileData).not.toHaveBeenCalled();
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('is being initialised for files without content even if shouldHideEditor is `true`', done => {
- vm.file.content = '';
- vm.file.raw = '';
-
- vm.initEditor();
- vm.$nextTick()
- .then(() => {
- expect(vm.getFileData).toHaveBeenCalled();
- expect(vm.getRawFileData).toHaveBeenCalled();
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('does not initialize editor for files already with content', done => {
- vm.file.content = 'foo';
-
- vm.initEditor();
- vm.$nextTick()
- .then(() => {
- expect(vm.getFileData).not.toHaveBeenCalled();
- expect(vm.getRawFileData).not.toHaveBeenCalled();
- expect(vm.editor.createInstance).not.toHaveBeenCalled();
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('updates on file changes', () => {
- beforeEach(() => {
- spyOn(vm, 'initEditor');
- });
-
- it('calls removePendingTab when old file is pending', done => {
- spyOnProperty(vm, 'shouldHideEditor').and.returnValue(true);
- spyOn(vm, 'removePendingTab');
-
- vm.file.pending = true;
-
- vm.$nextTick()
- .then(() => {
- vm.file = file('testing');
- vm.file.content = 'foo'; // need to prevent full cycle of initEditor
-
- return vm.$nextTick();
- })
- .then(() => {
- expect(vm.removePendingTab).toHaveBeenCalled();
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('does not call initEditor if the file did not change', done => {
- Vue.set(vm, 'file', vm.file);
-
- vm.$nextTick()
- .then(() => {
- expect(vm.initEditor).not.toHaveBeenCalled();
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('calls initEditor when file key is changed', done => {
- expect(vm.initEditor).not.toHaveBeenCalled();
-
- Vue.set(vm, 'file', {
- ...vm.file,
- key: 'new',
- });
-
- vm.$nextTick()
- .then(() => {
- expect(vm.initEditor).toHaveBeenCalled();
- })
- .then(done)
- .catch(done.fail);
- });
- });
-});
diff --git a/spec/javascripts/ide/helpers.js b/spec/javascripts/ide/helpers.js
deleted file mode 100644
index 2c52780f316..00000000000
--- a/spec/javascripts/ide/helpers.js
+++ /dev/null
@@ -1 +0,0 @@
-export * from '../../frontend/ide/helpers';
diff --git a/spec/javascripts/ide/mock_data.js b/spec/javascripts/ide/mock_data.js
deleted file mode 100644
index 27f0ad01f54..00000000000
--- a/spec/javascripts/ide/mock_data.js
+++ /dev/null
@@ -1 +0,0 @@
-export * from '../../frontend/ide/mock_data';
diff --git a/spec/javascripts/ide/stores/actions/merge_request_spec.js b/spec/javascripts/ide/stores/actions/merge_request_spec.js
deleted file mode 100644
index ce09cf51ac5..00000000000
--- a/spec/javascripts/ide/stores/actions/merge_request_spec.js
+++ /dev/null
@@ -1,510 +0,0 @@
-import MockAdapter from 'axios-mock-adapter';
-import axios from '~/lib/utils/axios_utils';
-import store from '~/ide/stores';
-import actions, {
- getMergeRequestData,
- getMergeRequestChanges,
- getMergeRequestVersions,
- openMergeRequest,
-} from '~/ide/stores/actions/merge_request';
-import service from '~/ide/services';
-import { leftSidebarViews, PERMISSION_READ_MR } from '~/ide/constants';
-import { resetStore } from '../../helpers';
-
-const TEST_PROJECT = 'abcproject';
-const TEST_PROJECT_ID = 17;
-
-describe('IDE store merge request actions', () => {
- let mock;
-
- beforeEach(() => {
- mock = new MockAdapter(axios);
-
- store.state.projects[TEST_PROJECT] = {
- id: TEST_PROJECT_ID,
- mergeRequests: {},
- userPermissions: {
- [PERMISSION_READ_MR]: true,
- },
- };
- });
-
- afterEach(() => {
- mock.restore();
- resetStore(store);
- });
-
- describe('getMergeRequestsForBranch', () => {
- describe('success', () => {
- const mrData = { iid: 2, source_branch: 'bar' };
- const mockData = [mrData];
-
- describe('base case', () => {
- beforeEach(() => {
- spyOn(service, 'getProjectMergeRequests').and.callThrough();
- mock.onGet(/api\/(.*)\/projects\/abcproject\/merge_requests/).reply(200, mockData);
- });
-
- it('calls getProjectMergeRequests service method', done => {
- store
- .dispatch('getMergeRequestsForBranch', { projectId: TEST_PROJECT, branchId: 'bar' })
- .then(() => {
- expect(service.getProjectMergeRequests).toHaveBeenCalledWith(TEST_PROJECT, {
- source_branch: 'bar',
- source_project_id: TEST_PROJECT_ID,
- order_by: 'created_at',
- per_page: 1,
- });
-
- done();
- })
- .catch(done.fail);
- });
-
- it('sets the "Merge Request" Object', done => {
- store
- .dispatch('getMergeRequestsForBranch', { projectId: TEST_PROJECT, branchId: 'bar' })
- .then(() => {
- expect(store.state.projects.abcproject.mergeRequests).toEqual({
- '2': jasmine.objectContaining(mrData),
- });
- done();
- })
- .catch(done.fail);
- });
-
- it('sets "Current Merge Request" object to the most recent MR', done => {
- store
- .dispatch('getMergeRequestsForBranch', { projectId: TEST_PROJECT, branchId: 'bar' })
- .then(() => {
- expect(store.state.currentMergeRequestId).toEqual('2');
- done();
- })
- .catch(done.fail);
- });
-
- it('does nothing if user cannot read MRs', done => {
- store.state.projects[TEST_PROJECT].userPermissions[PERMISSION_READ_MR] = false;
-
- store
- .dispatch('getMergeRequestsForBranch', { projectId: TEST_PROJECT, branchId: 'bar' })
- .then(() => {
- expect(service.getProjectMergeRequests).not.toHaveBeenCalled();
- expect(store.state.currentMergeRequestId).toBe('');
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('no merge requests for branch available case', () => {
- beforeEach(() => {
- spyOn(service, 'getProjectMergeRequests').and.callThrough();
- mock.onGet(/api\/(.*)\/projects\/abcproject\/merge_requests/).reply(200, []);
- });
-
- it('does not fail if there are no merge requests for current branch', done => {
- store
- .dispatch('getMergeRequestsForBranch', { projectId: TEST_PROJECT, branchId: 'foo' })
- .then(() => {
- expect(store.state.projects[TEST_PROJECT].mergeRequests).toEqual({});
- expect(store.state.currentMergeRequestId).toEqual('');
- done();
- })
- .catch(done.fail);
- });
- });
- });
-
- describe('error', () => {
- beforeEach(() => {
- mock.onGet(/api\/(.*)\/projects\/abcproject\/merge_requests/).networkError();
- });
-
- it('flashes message, if error', done => {
- const flashSpy = spyOnDependency(actions, 'flash');
-
- store
- .dispatch('getMergeRequestsForBranch', { projectId: TEST_PROJECT, branchId: 'bar' })
- .then(() => {
- fail('Expected getMergeRequestsForBranch to throw an error');
- })
- .catch(() => {
- expect(flashSpy).toHaveBeenCalled();
- expect(flashSpy.calls.argsFor(0)[0]).toEqual('Error fetching merge requests for bar');
- })
- .then(done)
- .catch(done.fail);
- });
- });
- });
-
- describe('getMergeRequestData', () => {
- describe('success', () => {
- beforeEach(() => {
- spyOn(service, 'getProjectMergeRequestData').and.callThrough();
-
- mock
- .onGet(/api\/(.*)\/projects\/abcproject\/merge_requests\/1/)
- .reply(200, { title: 'mergerequest' });
- });
-
- it('calls getProjectMergeRequestData service method', done => {
- store
- .dispatch('getMergeRequestData', { projectId: TEST_PROJECT, mergeRequestId: 1 })
- .then(() => {
- expect(service.getProjectMergeRequestData).toHaveBeenCalledWith(TEST_PROJECT, 1);
-
- done();
- })
- .catch(done.fail);
- });
-
- it('sets the Merge Request Object', done => {
- store
- .dispatch('getMergeRequestData', { projectId: TEST_PROJECT, mergeRequestId: 1 })
- .then(() => {
- expect(store.state.currentMergeRequestId).toBe(1);
- expect(store.state.projects[TEST_PROJECT].mergeRequests['1'].title).toBe(
- 'mergerequest',
- );
-
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('error', () => {
- beforeEach(() => {
- mock.onGet(/api\/(.*)\/projects\/abcproject\/merge_requests\/1/).networkError();
- });
-
- it('dispatches error action', done => {
- const dispatch = jasmine.createSpy('dispatch');
-
- getMergeRequestData(
- {
- commit() {},
- dispatch,
- state: store.state,
- },
- { projectId: TEST_PROJECT, mergeRequestId: 1 },
- )
- .then(done.fail)
- .catch(() => {
- expect(dispatch).toHaveBeenCalledWith('setErrorMessage', {
- text: 'An error occurred while loading the merge request.',
- action: jasmine.any(Function),
- actionText: 'Please try again',
- actionPayload: {
- projectId: TEST_PROJECT,
- mergeRequestId: 1,
- force: false,
- },
- });
-
- done();
- });
- });
- });
- });
-
- describe('getMergeRequestChanges', () => {
- beforeEach(() => {
- store.state.projects[TEST_PROJECT].mergeRequests['1'] = { changes: [] };
- });
-
- describe('success', () => {
- beforeEach(() => {
- spyOn(service, 'getProjectMergeRequestChanges').and.callThrough();
-
- mock
- .onGet(/api\/(.*)\/projects\/abcproject\/merge_requests\/1\/changes/)
- .reply(200, { title: 'mergerequest' });
- });
-
- it('calls getProjectMergeRequestChanges service method', done => {
- store
- .dispatch('getMergeRequestChanges', { projectId: TEST_PROJECT, mergeRequestId: 1 })
- .then(() => {
- expect(service.getProjectMergeRequestChanges).toHaveBeenCalledWith(TEST_PROJECT, 1);
-
- done();
- })
- .catch(done.fail);
- });
-
- it('sets the Merge Request Changes Object', done => {
- store
- .dispatch('getMergeRequestChanges', { projectId: TEST_PROJECT, mergeRequestId: 1 })
- .then(() => {
- expect(store.state.projects[TEST_PROJECT].mergeRequests['1'].changes.title).toBe(
- 'mergerequest',
- );
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('error', () => {
- beforeEach(() => {
- mock.onGet(/api\/(.*)\/projects\/abcproject\/merge_requests\/1\/changes/).networkError();
- });
-
- it('dispatches error action', done => {
- const dispatch = jasmine.createSpy('dispatch');
-
- getMergeRequestChanges(
- {
- commit() {},
- dispatch,
- state: store.state,
- },
- { projectId: TEST_PROJECT, mergeRequestId: 1 },
- )
- .then(done.fail)
- .catch(() => {
- expect(dispatch).toHaveBeenCalledWith('setErrorMessage', {
- text: 'An error occurred while loading the merge request changes.',
- action: jasmine.any(Function),
- actionText: 'Please try again',
- actionPayload: {
- projectId: TEST_PROJECT,
- mergeRequestId: 1,
- force: false,
- },
- });
-
- done();
- });
- });
- });
- });
-
- describe('getMergeRequestVersions', () => {
- beforeEach(() => {
- store.state.projects[TEST_PROJECT].mergeRequests['1'] = { versions: [] };
- });
-
- describe('success', () => {
- beforeEach(() => {
- mock
- .onGet(/api\/(.*)\/projects\/abcproject\/merge_requests\/1\/versions/)
- .reply(200, [{ id: 789 }]);
- spyOn(service, 'getProjectMergeRequestVersions').and.callThrough();
- });
-
- it('calls getProjectMergeRequestVersions service method', done => {
- store
- .dispatch('getMergeRequestVersions', { projectId: TEST_PROJECT, mergeRequestId: 1 })
- .then(() => {
- expect(service.getProjectMergeRequestVersions).toHaveBeenCalledWith(TEST_PROJECT, 1);
-
- done();
- })
- .catch(done.fail);
- });
-
- it('sets the Merge Request Versions Object', done => {
- store
- .dispatch('getMergeRequestVersions', { projectId: TEST_PROJECT, mergeRequestId: 1 })
- .then(() => {
- expect(store.state.projects[TEST_PROJECT].mergeRequests['1'].versions.length).toBe(1);
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('error', () => {
- beforeEach(() => {
- mock.onGet(/api\/(.*)\/projects\/abcproject\/merge_requests\/1\/versions/).networkError();
- });
-
- it('dispatches error action', done => {
- const dispatch = jasmine.createSpy('dispatch');
-
- getMergeRequestVersions(
- {
- commit() {},
- dispatch,
- state: store.state,
- },
- { projectId: TEST_PROJECT, mergeRequestId: 1 },
- )
- .then(done.fail)
- .catch(() => {
- expect(dispatch).toHaveBeenCalledWith('setErrorMessage', {
- text: 'An error occurred while loading the merge request version data.',
- action: jasmine.any(Function),
- actionText: 'Please try again',
- actionPayload: {
- projectId: TEST_PROJECT,
- mergeRequestId: 1,
- force: false,
- },
- });
-
- done();
- });
- });
- });
- });
-
- describe('openMergeRequest', () => {
- const mr = {
- projectId: TEST_PROJECT,
- targetProjectId: 'defproject',
- mergeRequestId: 2,
- };
- let testMergeRequest;
- let testMergeRequestChanges;
-
- const mockGetters = { findBranch: () => ({ commit: { id: 'abcd2322' } }) };
-
- beforeEach(() => {
- testMergeRequest = {
- source_branch: 'abcbranch',
- };
- testMergeRequestChanges = {
- changes: [],
- };
- store.state.entries = {
- foo: {
- type: 'blob',
- },
- bar: {
- type: 'blob',
- },
- };
-
- store.state.currentProjectId = 'test/test';
- store.state.currentBranchId = 'master';
-
- store.state.projects['test/test'] = {
- branches: {
- master: {
- commit: {
- id: '7297abc',
- },
- },
- abcbranch: {
- commit: {
- id: '29020fc',
- },
- },
- },
- };
-
- const originalDispatch = store.dispatch;
-
- spyOn(store, 'dispatch').and.callFake((type, payload) => {
- switch (type) {
- case 'getMergeRequestData':
- return Promise.resolve(testMergeRequest);
- case 'getMergeRequestChanges':
- return Promise.resolve(testMergeRequestChanges);
- case 'getFiles':
- case 'getMergeRequestVersions':
- case 'getBranchData':
- case 'setFileMrChange':
- return Promise.resolve();
- default:
- return originalDispatch(type, payload);
- }
- });
- spyOn(service, 'getFileData').and.callFake(() =>
- Promise.resolve({
- headers: {},
- }),
- );
- });
-
- it('dispatches actions for merge request data', done => {
- openMergeRequest({ state: store.state, dispatch: store.dispatch, getters: mockGetters }, mr)
- .then(() => {
- expect(store.dispatch.calls.allArgs()).toEqual([
- ['getMergeRequestData', mr],
- ['setCurrentBranchId', testMergeRequest.source_branch],
- [
- 'getBranchData',
- {
- projectId: mr.projectId,
- branchId: testMergeRequest.source_branch,
- },
- ],
- [
- 'getFiles',
- {
- projectId: mr.projectId,
- branchId: testMergeRequest.source_branch,
- ref: 'abcd2322',
- },
- ],
- ['getMergeRequestVersions', mr],
- ['getMergeRequestChanges', mr],
- ]);
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('updates activity bar view and gets file data, if changes are found', done => {
- store.state.entries.foo = {
- url: 'test',
- type: 'blob',
- };
- store.state.entries.bar = {
- url: 'test',
- type: 'blob',
- };
-
- testMergeRequestChanges.changes = [
- { new_path: 'foo', path: 'foo' },
- { new_path: 'bar', path: 'bar' },
- ];
-
- openMergeRequest({ state: store.state, dispatch: store.dispatch, getters: mockGetters }, mr)
- .then(() => {
- expect(store.dispatch).toHaveBeenCalledWith(
- 'updateActivityBarView',
- leftSidebarViews.review.name,
- );
-
- testMergeRequestChanges.changes.forEach((change, i) => {
- expect(store.dispatch).toHaveBeenCalledWith('setFileMrChange', {
- file: store.state.entries[change.new_path],
- mrChange: change,
- });
-
- expect(store.dispatch).toHaveBeenCalledWith('getFileData', {
- path: change.new_path,
- makeFileActive: i === 0,
- openFile: true,
- });
- });
-
- expect(store.state.openFiles.length).toBe(testMergeRequestChanges.changes.length);
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('flashes message, if error', done => {
- const flashSpy = spyOnDependency(actions, 'flash');
- store.dispatch.and.returnValue(Promise.reject());
-
- openMergeRequest(store, mr)
- .then(() => {
- fail('Expected openMergeRequest to throw an error');
- })
- .catch(() => {
- expect(flashSpy).toHaveBeenCalledWith(jasmine.any(String));
- })
- .then(done)
- .catch(done.fail);
- });
- });
-});
diff --git a/spec/javascripts/ide/stores/actions/project_spec.js b/spec/javascripts/ide/stores/actions/project_spec.js
deleted file mode 100644
index e962224d1ad..00000000000
--- a/spec/javascripts/ide/stores/actions/project_spec.js
+++ /dev/null
@@ -1,404 +0,0 @@
-import MockAdapter from 'axios-mock-adapter';
-import axios from '~/lib/utils/axios_utils';
-import {
- refreshLastCommitData,
- showBranchNotFoundError,
- createNewBranchFromDefault,
- loadEmptyBranch,
- openBranch,
- loadFile,
- loadBranch,
-} from '~/ide/stores/actions';
-import { createStore } from '~/ide/stores';
-import service from '~/ide/services';
-import api from '~/api';
-import router from '~/ide/ide_router';
-import { resetStore } from '../../helpers';
-import testAction from '../../../helpers/vuex_action_helper';
-
-const TEST_PROJECT_ID = 'abc/def';
-
-describe('IDE store project actions', () => {
- let mock;
- let store;
-
- beforeEach(() => {
- store = createStore();
- mock = new MockAdapter(axios);
-
- store.state.projects[TEST_PROJECT_ID] = {
- branches: {},
- };
- });
-
- afterEach(() => {
- mock.restore();
-
- resetStore(store);
- });
-
- describe('refreshLastCommitData', () => {
- beforeEach(() => {
- store.state.currentProjectId = 'abc/def';
- store.state.currentBranchId = 'master';
- store.state.projects['abc/def'] = {
- id: 4,
- branches: {
- master: {
- commit: null,
- },
- },
- };
- spyOn(service, 'getBranchData').and.returnValue(
- Promise.resolve({
- data: {
- commit: { id: '123' },
- },
- }),
- );
- });
-
- it('calls the service', done => {
- store
- .dispatch('refreshLastCommitData', {
- projectId: store.state.currentProjectId,
- branchId: store.state.currentBranchId,
- })
- .then(() => {
- expect(service.getBranchData).toHaveBeenCalledWith('abc/def', 'master');
-
- done();
- })
- .catch(done.fail);
- });
-
- it('commits getBranchData', done => {
- testAction(
- refreshLastCommitData,
- {
- projectId: store.state.currentProjectId,
- branchId: store.state.currentBranchId,
- },
- store.state,
- // mutations
- [
- {
- type: 'SET_BRANCH_COMMIT',
- payload: {
- projectId: TEST_PROJECT_ID,
- branchId: 'master',
- commit: { id: '123' },
- },
- },
- ],
- // action
- [],
- done,
- );
- });
- });
-
- describe('showBranchNotFoundError', () => {
- it('dispatches setErrorMessage', done => {
- testAction(
- showBranchNotFoundError,
- 'master',
- null,
- [],
- [
- {
- type: 'setErrorMessage',
- payload: {
- text: "Branch <strong>master</strong> was not found in this project's repository.",
- action: jasmine.any(Function),
- actionText: 'Create branch',
- actionPayload: 'master',
- },
- },
- ],
- done,
- );
- });
- });
-
- describe('createNewBranchFromDefault', () => {
- it('calls API', done => {
- spyOn(api, 'createBranch').and.returnValue(Promise.resolve());
- spyOn(router, 'push');
-
- createNewBranchFromDefault(
- {
- state: {
- currentProjectId: 'project-path',
- },
- getters: {
- currentProject: {
- default_branch: 'master',
- },
- },
- dispatch() {},
- },
- 'new-branch-name',
- )
- .then(() => {
- expect(api.createBranch).toHaveBeenCalledWith('project-path', {
- ref: 'master',
- branch: 'new-branch-name',
- });
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('clears error message', done => {
- const dispatchSpy = jasmine.createSpy('dispatch');
- spyOn(api, 'createBranch').and.returnValue(Promise.resolve());
- spyOn(router, 'push');
-
- createNewBranchFromDefault(
- {
- state: {
- currentProjectId: 'project-path',
- },
- getters: {
- currentProject: {
- default_branch: 'master',
- },
- },
- dispatch: dispatchSpy,
- },
- 'new-branch-name',
- )
- .then(() => {
- expect(dispatchSpy).toHaveBeenCalledWith('setErrorMessage', null);
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('reloads window', done => {
- spyOn(api, 'createBranch').and.returnValue(Promise.resolve());
- spyOn(router, 'push');
-
- createNewBranchFromDefault(
- {
- state: {
- currentProjectId: 'project-path',
- },
- getters: {
- currentProject: {
- default_branch: 'master',
- },
- },
- dispatch() {},
- },
- 'new-branch-name',
- )
- .then(() => {
- expect(router.push).toHaveBeenCalled();
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('loadEmptyBranch', () => {
- it('creates a blank tree and sets loading state to false', done => {
- testAction(
- loadEmptyBranch,
- { projectId: TEST_PROJECT_ID, branchId: 'master' },
- store.state,
- [
- { type: 'CREATE_TREE', payload: { treePath: `${TEST_PROJECT_ID}/master` } },
- {
- type: 'TOGGLE_LOADING',
- payload: { entry: store.state.trees[`${TEST_PROJECT_ID}/master`], forceValue: false },
- },
- ],
- jasmine.any(Object),
- done,
- );
- });
-
- it('does nothing, if tree already exists', done => {
- const trees = { [`${TEST_PROJECT_ID}/master`]: [] };
-
- testAction(
- loadEmptyBranch,
- { projectId: TEST_PROJECT_ID, branchId: 'master' },
- { trees },
- [],
- [],
- done,
- );
- });
- });
-
- describe('loadFile', () => {
- beforeEach(() => {
- Object.assign(store.state, {
- entries: {
- foo: { pending: false },
- 'foo/bar-pending': { pending: true },
- 'foo/bar': { pending: false },
- },
- });
- spyOn(store, 'dispatch');
- });
-
- it('does nothing, if basePath is not given', () => {
- loadFile(store, { basePath: undefined });
-
- expect(store.dispatch).not.toHaveBeenCalled();
- });
-
- it('handles tree entry action, if basePath is given and the entry is not pending', () => {
- loadFile(store, { basePath: 'foo/bar/' });
-
- expect(store.dispatch).toHaveBeenCalledWith(
- 'handleTreeEntryAction',
- store.state.entries['foo/bar'],
- );
- });
-
- it('does not handle tree entry action, if entry is pending', () => {
- loadFile(store, { basePath: 'foo/bar-pending/' });
-
- expect(store.dispatch).not.toHaveBeenCalledWith('handleTreeEntryAction', jasmine.anything());
- });
-
- it('creates a new temp file supplied via URL if the file does not exist yet', () => {
- loadFile(store, { basePath: 'not-existent.md' });
-
- expect(store.dispatch.calls.count()).toBe(1);
-
- expect(store.dispatch).not.toHaveBeenCalledWith('handleTreeEntryAction', jasmine.anything());
-
- expect(store.dispatch).toHaveBeenCalledWith('createTempEntry', {
- name: 'not-existent.md',
- type: 'blob',
- });
- });
- });
-
- describe('loadBranch', () => {
- const projectId = TEST_PROJECT_ID;
- const branchId = '123-lorem';
- const ref = 'abcd2322';
-
- it('when empty repo, loads empty branch', done => {
- const mockGetters = { emptyRepo: true };
-
- testAction(
- loadBranch,
- { projectId, branchId },
- { ...store.state, ...mockGetters },
- [],
- [{ type: 'loadEmptyBranch', payload: { projectId, branchId } }],
- done,
- );
- });
-
- it('when branch already exists, does nothing', done => {
- store.state.projects[projectId].branches[branchId] = {};
-
- testAction(loadBranch, { projectId, branchId }, store.state, [], [], done);
- });
-
- it('fetches branch data', done => {
- const mockGetters = { findBranch: () => ({ commit: { id: ref } }) };
- spyOn(store, 'dispatch').and.returnValue(Promise.resolve());
-
- loadBranch(
- { getters: mockGetters, state: store.state, dispatch: store.dispatch },
- { projectId, branchId },
- )
- .then(() => {
- expect(store.dispatch.calls.allArgs()).toEqual([
- ['getBranchData', { projectId, branchId }],
- ['getMergeRequestsForBranch', { projectId, branchId }],
- ['getFiles', { projectId, branchId, ref }],
- ]);
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('shows an error if branch can not be fetched', done => {
- spyOn(store, 'dispatch').and.returnValue(Promise.reject());
-
- loadBranch(store, { projectId, branchId })
- .then(done.fail)
- .catch(() => {
- expect(store.dispatch.calls.allArgs()).toEqual([
- ['getBranchData', { projectId, branchId }],
- ['showBranchNotFoundError', branchId],
- ]);
- done();
- });
- });
- });
-
- describe('openBranch', () => {
- const projectId = TEST_PROJECT_ID;
- const branchId = '123-lorem';
-
- const branch = {
- projectId,
- branchId,
- };
-
- beforeEach(() => {
- Object.assign(store.state, {
- entries: {
- foo: { pending: false },
- 'foo/bar-pending': { pending: true },
- 'foo/bar': { pending: false },
- },
- });
- });
-
- describe('existing branch', () => {
- beforeEach(() => {
- spyOn(store, 'dispatch').and.returnValue(Promise.resolve());
- });
-
- it('dispatches branch actions', done => {
- openBranch(store, branch)
- .then(() => {
- expect(store.dispatch.calls.allArgs()).toEqual([
- ['setCurrentBranchId', branchId],
- ['loadBranch', { projectId, branchId }],
- ['loadFile', { basePath: undefined }],
- ]);
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('non-existent branch', () => {
- beforeEach(() => {
- spyOn(store, 'dispatch').and.returnValue(Promise.reject());
- });
-
- it('dispatches correct branch actions', done => {
- openBranch(store, branch)
- .then(val => {
- expect(store.dispatch.calls.allArgs()).toEqual([
- ['setCurrentBranchId', branchId],
- ['loadBranch', { projectId, branchId }],
- ]);
-
- expect(val).toEqual(
- new Error(
- `An error occurred while getting files for - <strong>${projectId}/${branchId}</strong>`,
- ),
- );
- })
- .then(done)
- .catch(done.fail);
- });
- });
- });
-});
diff --git a/spec/javascripts/ide/stores/actions/tree_spec.js b/spec/javascripts/ide/stores/actions/tree_spec.js
deleted file mode 100644
index 2201a3b4b57..00000000000
--- a/spec/javascripts/ide/stores/actions/tree_spec.js
+++ /dev/null
@@ -1,216 +0,0 @@
-import MockAdapter from 'axios-mock-adapter';
-import testAction from 'spec/helpers/vuex_action_helper';
-import { showTreeEntry, getFiles, setDirectoryData } from '~/ide/stores/actions/tree';
-import * as types from '~/ide/stores/mutation_types';
-import axios from '~/lib/utils/axios_utils';
-import store from '~/ide/stores';
-import service from '~/ide/services';
-import router from '~/ide/ide_router';
-import { file, resetStore, createEntriesFromPaths } from '../../helpers';
-
-describe('Multi-file store tree actions', () => {
- let projectTree;
- let mock;
-
- const basicCallParameters = {
- endpoint: 'rootEndpoint',
- projectId: 'abcproject',
- branch: 'master',
- branchId: 'master',
- ref: '12345678',
- };
-
- beforeEach(() => {
- jasmine.clock().install();
- spyOn(router, 'push');
-
- mock = new MockAdapter(axios);
-
- store.state.currentProjectId = 'abcproject';
- store.state.currentBranchId = 'master';
- store.state.projects.abcproject = {
- web_url: '',
- path_with_namespace: 'foo/abcproject',
- };
- });
-
- afterEach(() => {
- jasmine.clock().uninstall();
- mock.restore();
- resetStore(store);
- });
-
- describe('getFiles', () => {
- describe('success', () => {
- beforeEach(() => {
- spyOn(service, 'getFiles').and.callThrough();
-
- mock
- .onGet(/(.*)/)
- .replyOnce(200, [
- 'file.txt',
- 'folder/fileinfolder.js',
- 'folder/subfolder/fileinsubfolder.js',
- ]);
- });
-
- it('calls service getFiles', done => {
- store
- .dispatch('getFiles', basicCallParameters)
- .then(() => {
- expect(service.getFiles).toHaveBeenCalledWith('foo/abcproject', '12345678');
-
- done();
- })
- .catch(done.fail);
- });
-
- it('adds data into tree', done => {
- store
- .dispatch('getFiles', basicCallParameters)
- .then(() => {
- // The populating of the tree is deferred for performance reasons.
- // See this merge request for details: https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/25700
- jasmine.clock().tick(1);
- })
- .then(() => {
- projectTree = store.state.trees['abcproject/master'];
-
- expect(projectTree.tree.length).toBe(2);
- expect(projectTree.tree[0].type).toBe('tree');
- expect(projectTree.tree[0].tree[1].name).toBe('fileinfolder.js');
- expect(projectTree.tree[1].type).toBe('blob');
- expect(projectTree.tree[0].tree[0].tree[0].type).toBe('blob');
- expect(projectTree.tree[0].tree[0].tree[0].name).toBe('fileinsubfolder.js');
-
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('error', () => {
- it('dispatches error action', done => {
- const dispatch = jasmine.createSpy('dispatchSpy');
-
- store.state.projects = {
- 'abc/def': {
- web_url: `${gl.TEST_HOST}/files`,
- branches: {
- 'master-testing': {
- commit: {
- id: '12345',
- },
- },
- },
- },
- };
- const getters = {
- findBranch: () => store.state.projects['abc/def'].branches['master-testing'],
- };
-
- mock.onGet(/(.*)/).replyOnce(500);
-
- getFiles(
- {
- commit() {},
- dispatch,
- state: store.state,
- getters,
- },
- {
- projectId: 'abc/def',
- branchId: 'master-testing',
- },
- )
- .then(done.fail)
- .catch(() => {
- expect(dispatch).toHaveBeenCalledWith('setErrorMessage', {
- text: 'An error occurred while loading all the files.',
- action: jasmine.any(Function),
- actionText: 'Please try again',
- actionPayload: { projectId: 'abc/def', branchId: 'master-testing' },
- });
- done();
- });
- });
- });
- });
-
- describe('toggleTreeOpen', () => {
- let tree;
-
- beforeEach(() => {
- tree = file('testing', '1', 'tree');
- store.state.entries[tree.path] = tree;
- });
-
- it('toggles the tree open', done => {
- store
- .dispatch('toggleTreeOpen', tree.path)
- .then(() => {
- expect(tree.opened).toBeTruthy();
-
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('showTreeEntry', () => {
- beforeEach(() => {
- const paths = [
- 'grandparent',
- 'ancestor',
- 'grandparent/parent',
- 'grandparent/aunt',
- 'grandparent/parent/child.txt',
- 'grandparent/aunt/cousing.txt',
- ];
-
- Object.assign(store.state.entries, createEntriesFromPaths(paths));
- });
-
- it('opens the parents', done => {
- testAction(
- showTreeEntry,
- 'grandparent/parent/child.txt',
- store.state,
- [{ type: types.SET_TREE_OPEN, payload: 'grandparent/parent' }],
- [{ type: 'showTreeEntry', payload: 'grandparent/parent' }],
- done,
- );
- });
- });
-
- describe('setDirectoryData', () => {
- it('sets tree correctly if there are no opened files yet', done => {
- const treeFile = file({ name: 'README.md' });
- store.state.trees['abcproject/master'] = {};
-
- testAction(
- setDirectoryData,
- { projectId: 'abcproject', branchId: 'master', treeList: [treeFile] },
- store.state,
- [
- {
- type: types.SET_DIRECTORY_DATA,
- payload: {
- treePath: 'abcproject/master',
- data: [treeFile],
- },
- },
- {
- type: types.TOGGLE_LOADING,
- payload: {
- entry: {},
- forceValue: false,
- },
- },
- ],
- [],
- done,
- );
- });
- });
-});
diff --git a/spec/javascripts/ide/stores/actions_spec.js b/spec/javascripts/ide/stores/actions_spec.js
deleted file mode 100644
index 364c8421b6b..00000000000
--- a/spec/javascripts/ide/stores/actions_spec.js
+++ /dev/null
@@ -1,1116 +0,0 @@
-import MockAdapter from 'axios-mock-adapter';
-import actions, {
- stageAllChanges,
- unstageAllChanges,
- toggleFileFinder,
- setCurrentBranchId,
- setEmptyStateSvgs,
- updateActivityBarView,
- updateTempFlagForEntry,
- setErrorMessage,
- deleteEntry,
- renameEntry,
- getBranchData,
- createTempEntry,
- discardAllChanges,
-} from '~/ide/stores/actions';
-import axios from '~/lib/utils/axios_utils';
-import { createStore } from '~/ide/stores';
-import * as types from '~/ide/stores/mutation_types';
-import router from '~/ide/ide_router';
-import { file } from '../helpers';
-import testAction from '../../helpers/vuex_action_helper';
-import eventHub from '~/ide/eventhub';
-
-describe('Multi-file store actions', () => {
- let store;
-
- beforeEach(() => {
- store = createStore();
-
- spyOn(store, 'commit').and.callThrough();
- spyOn(store, 'dispatch').and.callThrough();
- spyOn(router, 'push');
- });
-
- describe('redirectToUrl', () => {
- it('calls visitUrl', done => {
- const visitUrl = spyOnDependency(actions, 'visitUrl');
-
- store
- .dispatch('redirectToUrl', 'test')
- .then(() => {
- expect(visitUrl).toHaveBeenCalledWith('test');
-
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('setInitialData', () => {
- it('commits initial data', done => {
- store
- .dispatch('setInitialData', { canCommit: true })
- .then(() => {
- expect(store.state.canCommit).toBeTruthy();
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('discardAllChanges', () => {
- const paths = ['to_discard', 'another_one_to_discard'];
-
- beforeEach(() => {
- paths.forEach(path => {
- const f = file(path);
- f.changed = true;
-
- store.state.openFiles.push(f);
- store.state.changedFiles.push(f);
- store.state.entries[f.path] = f;
- });
- });
-
- it('discards all changes in file', () => {
- const expectedCalls = paths.map(path => ['restoreOriginalFile', path]);
-
- discardAllChanges(store);
-
- expect(store.dispatch.calls.allArgs()).toEqual(jasmine.arrayContaining(expectedCalls));
- });
-
- it('removes all files from changedFiles state', done => {
- store
- .dispatch('discardAllChanges')
- .then(() => {
- expect(store.state.changedFiles.length).toBe(0);
- expect(store.state.openFiles.length).toBe(2);
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('closeAllFiles', () => {
- beforeEach(() => {
- const f = file('closeAll');
- store.state.openFiles.push(f);
- store.state.openFiles[0].opened = true;
- store.state.entries[f.path] = f;
- });
-
- it('closes all open files', done => {
- store
- .dispatch('closeAllFiles')
- .then(() => {
- expect(store.state.openFiles.length).toBe(0);
-
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('createTempEntry', () => {
- beforeEach(() => {
- document.body.innerHTML += '<div class="flash-container"></div>';
-
- store.state.currentProjectId = 'abcproject';
- store.state.currentBranchId = 'mybranch';
-
- store.state.trees['abcproject/mybranch'] = {
- tree: [],
- };
- store.state.projects.abcproject = {
- web_url: '',
- };
- });
-
- afterEach(() => {
- document.querySelector('.flash-container').remove();
- });
-
- describe('tree', () => {
- it('creates temp tree', done => {
- store
- .dispatch('createTempEntry', {
- branchId: store.state.currentBranchId,
- name: 'test',
- type: 'tree',
- })
- .then(() => {
- const entry = store.state.entries.test;
-
- expect(entry).not.toBeNull();
- expect(entry.type).toBe('tree');
-
- done();
- })
- .catch(done.fail);
- });
-
- it('creates new folder inside another tree', done => {
- const tree = {
- type: 'tree',
- name: 'testing',
- path: 'testing',
- tree: [],
- };
-
- store.state.entries[tree.path] = tree;
-
- store
- .dispatch('createTempEntry', {
- branchId: store.state.currentBranchId,
- name: 'testing/test',
- type: 'tree',
- })
- .then(() => {
- expect(tree.tree[0].tempFile).toBeTruthy();
- expect(tree.tree[0].name).toBe('test');
- expect(tree.tree[0].type).toBe('tree');
-
- done();
- })
- .catch(done.fail);
- });
-
- it('does not create new tree if already exists', done => {
- const tree = {
- type: 'tree',
- path: 'testing',
- tempFile: false,
- tree: [],
- };
-
- store.state.entries[tree.path] = tree;
-
- store
- .dispatch('createTempEntry', {
- branchId: store.state.currentBranchId,
- name: 'testing',
- type: 'tree',
- })
- .then(() => {
- expect(store.state.entries[tree.path].tempFile).toEqual(false);
- expect(document.querySelector('.flash-alert')).not.toBeNull();
-
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('blob', () => {
- it('creates temp file', done => {
- const name = 'test';
-
- store
- .dispatch('createTempEntry', {
- name,
- branchId: 'mybranch',
- type: 'blob',
- })
- .then(() => {
- const f = store.state.entries[name];
-
- expect(f.tempFile).toBeTruthy();
- expect(store.state.trees['abcproject/mybranch'].tree.length).toBe(1);
-
- done();
- })
- .catch(done.fail);
- });
-
- it('adds tmp file to open files', done => {
- const name = 'test';
-
- store
- .dispatch('createTempEntry', {
- name,
- branchId: 'mybranch',
- type: 'blob',
- })
- .then(() => {
- const f = store.state.entries[name];
-
- expect(store.state.openFiles.length).toBe(1);
- expect(store.state.openFiles[0].name).toBe(f.name);
-
- done();
- })
- .catch(done.fail);
- });
-
- it('adds tmp file to staged files', done => {
- const name = 'test';
-
- store
- .dispatch('createTempEntry', {
- name,
- branchId: 'mybranch',
- type: 'blob',
- })
- .then(() => {
- expect(store.state.stagedFiles).toEqual([jasmine.objectContaining({ name })]);
-
- done();
- })
- .catch(done.fail);
- });
-
- it('sets tmp file as active', () => {
- createTempEntry(store, { name: 'test', branchId: 'mybranch', type: 'blob' });
-
- expect(store.dispatch).toHaveBeenCalledWith('setFileActive', 'test');
- });
-
- it('creates flash message if file already exists', done => {
- const f = file('test', '1', 'blob');
- store.state.trees['abcproject/mybranch'].tree = [f];
- store.state.entries[f.path] = f;
-
- store
- .dispatch('createTempEntry', {
- name: 'test',
- branchId: 'mybranch',
- type: 'blob',
- })
- .then(() => {
- expect(document.querySelector('.flash-alert')?.textContent.trim()).toEqual(
- `The name "${f.name}" is already taken in this directory.`,
- );
-
- done();
- })
- .catch(done.fail);
- });
-
- it('bursts unused seal', done => {
- store
- .dispatch('createTempEntry', {
- name: 'test',
- branchId: 'mybranch',
- type: 'blob',
- })
- .then(() => {
- expect(store.state.unusedSeal).toBe(false);
-
- done();
- })
- .catch(done.fail);
- });
- });
- });
-
- describe('scrollToTab', () => {
- it('focuses the current active element', done => {
- document.body.innerHTML +=
- '<div id="tabs"><div class="active"><div class="repo-tab"></div></div></div>';
- const el = document.querySelector('.repo-tab');
- spyOn(el, 'focus');
-
- store
- .dispatch('scrollToTab')
- .then(() => {
- setTimeout(() => {
- expect(el.focus).toHaveBeenCalled();
-
- document.getElementById('tabs').remove();
-
- done();
- });
- })
- .catch(done.fail);
- });
- });
-
- describe('stage/unstageAllChanges', () => {
- let file1;
- let file2;
-
- beforeEach(() => {
- file1 = { ...file('test'), content: 'changed test', raw: 'test' };
- file2 = { ...file('test2'), content: 'changed test2', raw: 'test2' };
-
- store.state.openFiles = [file1];
- store.state.changedFiles = [file1];
- store.state.stagedFiles = [{ ...file2, content: 'staged test' }];
-
- store.state.entries = {
- [file1.path]: { ...file1 },
- [file2.path]: { ...file2 },
- };
- });
-
- describe('stageAllChanges', () => {
- it('adds all files from changedFiles to stagedFiles', () => {
- stageAllChanges(store);
-
- expect(store.commit.calls.allArgs()).toEqual([
- [types.SET_LAST_COMMIT_MSG, ''],
- [types.STAGE_CHANGE, jasmine.objectContaining({ path: file1.path })],
- ]);
- });
-
- it('opens pending tab if a change exists in that file', () => {
- stageAllChanges(store);
-
- expect(store.dispatch.calls.allArgs()).toEqual([
- [
- 'openPendingTab',
- { file: { ...file1, staged: true, changed: true }, keyPrefix: 'staged' },
- ],
- ]);
- });
-
- it('does not open pending tab if no change exists in that file', () => {
- store.state.entries[file1.path].content = 'test';
- store.state.stagedFiles = [file1];
- store.state.changedFiles = [store.state.entries[file1.path]];
-
- stageAllChanges(store);
-
- expect(store.dispatch).not.toHaveBeenCalled();
- });
- });
-
- describe('unstageAllChanges', () => {
- it('removes all files from stagedFiles after unstaging', () => {
- unstageAllChanges(store);
-
- expect(store.commit.calls.allArgs()).toEqual([
- [types.UNSTAGE_CHANGE, jasmine.objectContaining({ path: file2.path })],
- ]);
- });
-
- it('opens pending tab if a change exists in that file', () => {
- unstageAllChanges(store);
-
- expect(store.dispatch.calls.allArgs()).toEqual([
- ['openPendingTab', { file: file1, keyPrefix: 'unstaged' }],
- ]);
- });
-
- it('does not open pending tab if no change exists in that file', () => {
- store.state.entries[file1.path].content = 'test';
- store.state.stagedFiles = [file1];
- store.state.changedFiles = [store.state.entries[file1.path]];
-
- unstageAllChanges(store);
-
- expect(store.dispatch).not.toHaveBeenCalled();
- });
- });
- });
-
- describe('updateViewer', () => {
- it('updates viewer state', done => {
- store
- .dispatch('updateViewer', 'diff')
- .then(() => {
- expect(store.state.viewer).toBe('diff');
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('updateActivityBarView', () => {
- it('commits UPDATE_ACTIVITY_BAR_VIEW', done => {
- testAction(
- updateActivityBarView,
- 'test',
- {},
- [{ type: 'UPDATE_ACTIVITY_BAR_VIEW', payload: 'test' }],
- [],
- done,
- );
- });
- });
-
- describe('setEmptyStateSvgs', () => {
- it('commits setEmptyStateSvgs', done => {
- testAction(
- setEmptyStateSvgs,
- 'svg',
- {},
- [{ type: 'SET_EMPTY_STATE_SVGS', payload: 'svg' }],
- [],
- done,
- );
- });
- });
-
- describe('updateTempFlagForEntry', () => {
- it('commits UPDATE_TEMP_FLAG', done => {
- const f = {
- ...file(),
- path: 'test',
- tempFile: true,
- };
- store.state.entries[f.path] = f;
-
- testAction(
- updateTempFlagForEntry,
- { file: f, tempFile: false },
- store.state,
- [{ type: 'UPDATE_TEMP_FLAG', payload: { path: f.path, tempFile: false } }],
- [],
- done,
- );
- });
-
- it('commits UPDATE_TEMP_FLAG and dispatches for parent', done => {
- const parent = {
- ...file(),
- path: 'testing',
- };
- const f = {
- ...file(),
- path: 'test',
- parentPath: 'testing',
- };
- store.state.entries[parent.path] = parent;
- store.state.entries[f.path] = f;
-
- testAction(
- updateTempFlagForEntry,
- { file: f, tempFile: false },
- store.state,
- [{ type: 'UPDATE_TEMP_FLAG', payload: { path: f.path, tempFile: false } }],
- [{ type: 'updateTempFlagForEntry', payload: { file: parent, tempFile: false } }],
- done,
- );
- });
-
- it('does not dispatch for parent, if parent does not exist', done => {
- const f = {
- ...file(),
- path: 'test',
- parentPath: 'testing',
- };
- store.state.entries[f.path] = f;
-
- testAction(
- updateTempFlagForEntry,
- { file: f, tempFile: false },
- store.state,
- [{ type: 'UPDATE_TEMP_FLAG', payload: { path: f.path, tempFile: false } }],
- [],
- done,
- );
- });
- });
-
- describe('setCurrentBranchId', () => {
- it('commits setCurrentBranchId', done => {
- testAction(
- setCurrentBranchId,
- 'branchId',
- {},
- [{ type: 'SET_CURRENT_BRANCH', payload: 'branchId' }],
- [],
- done,
- );
- });
- });
-
- describe('toggleFileFinder', () => {
- it('commits TOGGLE_FILE_FINDER', done => {
- testAction(
- toggleFileFinder,
- true,
- null,
- [{ type: 'TOGGLE_FILE_FINDER', payload: true }],
- [],
- done,
- );
- });
- });
-
- describe('setErrorMessage', () => {
- it('commis error messsage', done => {
- testAction(
- setErrorMessage,
- 'error',
- null,
- [{ type: types.SET_ERROR_MESSAGE, payload: 'error' }],
- [],
- done,
- );
- });
- });
-
- describe('deleteEntry', () => {
- it('commits entry deletion', done => {
- store.state.entries.path = 'testing';
-
- testAction(
- deleteEntry,
- 'path',
- store.state,
- [{ type: types.DELETE_ENTRY, payload: 'path' }],
- [{ type: 'stageChange', payload: 'path' }, { type: 'triggerFilesChange' }],
- done,
- );
- });
-
- it('does not delete a folder after it is emptied', done => {
- const testFolder = {
- type: 'tree',
- tree: [],
- };
- const testEntry = {
- path: 'testFolder/entry-to-delete',
- parentPath: 'testFolder',
- opened: false,
- tree: [],
- };
- testFolder.tree.push(testEntry);
- store.state.entries = {
- testFolder,
- 'testFolder/entry-to-delete': testEntry,
- };
-
- testAction(
- deleteEntry,
- 'testFolder/entry-to-delete',
- store.state,
- [{ type: types.DELETE_ENTRY, payload: 'testFolder/entry-to-delete' }],
- [
- { type: 'stageChange', payload: 'testFolder/entry-to-delete' },
- { type: 'triggerFilesChange' },
- ],
- done,
- );
- });
-
- describe('when renamed', () => {
- let testEntry;
-
- beforeEach(() => {
- testEntry = {
- path: 'test',
- name: 'test',
- prevPath: 'test_old',
- prevName: 'test_old',
- prevParentPath: '',
- };
-
- store.state.entries = { test: testEntry };
- });
-
- describe('and previous does not exist', () => {
- it('reverts the rename before deleting', done => {
- testAction(
- deleteEntry,
- testEntry.path,
- store.state,
- [],
- [
- {
- type: 'renameEntry',
- payload: {
- path: testEntry.path,
- name: testEntry.prevName,
- parentPath: testEntry.prevParentPath,
- },
- },
- {
- type: 'deleteEntry',
- payload: testEntry.prevPath,
- },
- ],
- done,
- );
- });
- });
-
- describe('and previous exists', () => {
- beforeEach(() => {
- const oldEntry = {
- path: testEntry.prevPath,
- name: testEntry.prevName,
- };
-
- store.state.entries[oldEntry.path] = oldEntry;
- });
-
- it('does not revert rename before deleting', done => {
- testAction(
- deleteEntry,
- testEntry.path,
- store.state,
- [{ type: types.DELETE_ENTRY, payload: testEntry.path }],
- [{ type: 'stageChange', payload: testEntry.path }, { type: 'triggerFilesChange' }],
- done,
- );
- });
-
- it('when previous is deleted, it reverts rename before deleting', done => {
- store.state.entries[testEntry.prevPath].deleted = true;
-
- testAction(
- deleteEntry,
- testEntry.path,
- store.state,
- [],
- [
- {
- type: 'renameEntry',
- payload: {
- path: testEntry.path,
- name: testEntry.prevName,
- parentPath: testEntry.prevParentPath,
- },
- },
- {
- type: 'deleteEntry',
- payload: testEntry.prevPath,
- },
- ],
- done,
- );
- });
- });
- });
-
- it('bursts unused seal', done => {
- store.state.entries.test = file('test');
-
- store
- .dispatch('deleteEntry', 'test')
- .then(() => {
- expect(store.state.unusedSeal).toBe(false);
-
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('renameEntry', () => {
- describe('purging of file model cache', () => {
- beforeEach(() => {
- spyOn(eventHub, '$emit');
- });
-
- it('does not purge model cache for temporary entries that got renamed', done => {
- Object.assign(store.state.entries, {
- test: {
- ...file('test'),
- key: 'foo-key',
- type: 'blob',
- tempFile: true,
- },
- });
-
- store
- .dispatch('renameEntry', {
- path: 'test',
- name: 'new',
- })
- .then(() => {
- expect(eventHub.$emit.calls.allArgs()).not.toContain(
- 'editor.update.model.dispose.foo-bar',
- );
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('purges model cache for renamed entry', done => {
- Object.assign(store.state.entries, {
- test: {
- ...file('test'),
- key: 'foo-key',
- type: 'blob',
- tempFile: false,
- },
- });
-
- store
- .dispatch('renameEntry', {
- path: 'test',
- name: 'new',
- })
- .then(() => {
- expect(eventHub.$emit).toHaveBeenCalled();
- expect(eventHub.$emit).toHaveBeenCalledWith(`editor.update.model.dispose.foo-key`);
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('single entry', () => {
- let origEntry;
- let renamedEntry;
-
- beforeEach(() => {
- // Need to insert both because `testAction` doesn't actually call the mutation
- origEntry = file('orig', 'orig', 'blob');
- renamedEntry = {
- ...file('renamed', 'renamed', 'blob'),
- prevKey: origEntry.key,
- prevName: origEntry.name,
- prevPath: origEntry.path,
- };
-
- Object.assign(store.state.entries, {
- orig: origEntry,
- renamed: renamedEntry,
- });
- });
-
- it('by default renames an entry and stages it', () => {
- const dispatch = jasmine.createSpy();
- const commit = jasmine.createSpy();
-
- renameEntry(
- { dispatch, commit, state: store.state, getters: store.getters },
- { path: 'orig', name: 'renamed' },
- );
-
- expect(commit.calls.allArgs()).toEqual([
- [types.RENAME_ENTRY, { path: 'orig', name: 'renamed', parentPath: undefined }],
- [types.STAGE_CHANGE, jasmine.objectContaining({ path: 'renamed' })],
- ]);
- });
-
- it('if not changed, completely unstages and discards entry if renamed to original', done => {
- testAction(
- renameEntry,
- { path: 'renamed', name: 'orig' },
- store.state,
- [
- {
- type: types.RENAME_ENTRY,
- payload: {
- path: 'renamed',
- name: 'orig',
- parentPath: undefined,
- },
- },
- {
- type: types.REMOVE_FILE_FROM_STAGED_AND_CHANGED,
- payload: origEntry,
- },
- ],
- [{ type: 'triggerFilesChange' }],
- done,
- );
- });
-
- it('if already in changed, does not add to change', done => {
- store.state.changedFiles.push(renamedEntry);
-
- testAction(
- renameEntry,
- { path: 'orig', name: 'renamed' },
- store.state,
- [jasmine.objectContaining({ type: types.RENAME_ENTRY })],
- [{ type: 'triggerFilesChange' }],
- done,
- );
- });
-
- it('routes to the renamed file if the original file has been opened', done => {
- Object.assign(store.state.entries.orig, {
- opened: true,
- url: '/foo-bar.md',
- });
-
- store
- .dispatch('renameEntry', {
- path: 'orig',
- name: 'renamed',
- })
- .then(() => {
- expect(router.push.calls.count()).toBe(1);
- expect(router.push).toHaveBeenCalledWith(`/project/foo-bar.md`);
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('bursts unused seal', done => {
- store
- .dispatch('renameEntry', {
- path: 'orig',
- name: 'renamed',
- })
- .then(() => {
- expect(store.state.unusedSeal).toBe(false);
-
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('folder', () => {
- let folder;
- let file1;
- let file2;
-
- beforeEach(() => {
- folder = file('folder', 'folder', 'tree');
- file1 = file('file-1', 'file-1', 'blob', folder);
- file2 = file('file-2', 'file-2', 'blob', folder);
-
- folder.tree = [file1, file2];
-
- Object.assign(store.state.entries, {
- [folder.path]: folder,
- [file1.path]: file1,
- [file2.path]: file2,
- });
- });
-
- it('updates entries in a folder correctly, when folder is renamed', done => {
- store
- .dispatch('renameEntry', {
- path: 'folder',
- name: 'new-folder',
- })
- .then(() => {
- const keys = Object.keys(store.state.entries);
-
- expect(keys.length).toBe(3);
- expect(keys.indexOf('new-folder')).toBe(0);
- expect(keys.indexOf('new-folder/file-1')).toBe(1);
- expect(keys.indexOf('new-folder/file-2')).toBe(2);
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('discards renaming of an entry if the root folder is renamed back to a previous name', done => {
- const rootFolder = file('old-folder', 'old-folder', 'tree');
- const testEntry = file('test', 'test', 'blob', rootFolder);
-
- Object.assign(store.state, {
- entries: {
- 'old-folder': {
- ...rootFolder,
- tree: [testEntry],
- },
- 'old-folder/test': testEntry,
- },
- });
-
- store
- .dispatch('renameEntry', {
- path: 'old-folder',
- name: 'new-folder',
- })
- .then(() => {
- const { entries } = store.state;
-
- expect(Object.keys(entries).length).toBe(2);
- expect(entries['old-folder']).toBeUndefined();
- expect(entries['old-folder/test']).toBeUndefined();
-
- expect(entries['new-folder']).toBeDefined();
- expect(entries['new-folder/test']).toEqual(
- jasmine.objectContaining({
- path: 'new-folder/test',
- name: 'test',
- prevPath: 'old-folder/test',
- prevName: 'test',
- }),
- );
- })
- .then(() =>
- store.dispatch('renameEntry', {
- path: 'new-folder',
- name: 'old-folder',
- }),
- )
- .then(() => {
- const { entries } = store.state;
-
- expect(Object.keys(entries).length).toBe(2);
- expect(entries['new-folder']).toBeUndefined();
- expect(entries['new-folder/test']).toBeUndefined();
-
- expect(entries['old-folder']).toBeDefined();
- expect(entries['old-folder/test']).toEqual(
- jasmine.objectContaining({
- path: 'old-folder/test',
- name: 'test',
- prevPath: undefined,
- prevName: undefined,
- }),
- );
- })
- .then(done)
- .catch(done.fail);
- });
-
- describe('with file in directory', () => {
- const parentPath = 'original-dir';
- const newParentPath = 'new-dir';
- const fileName = 'test.md';
- const filePath = `${parentPath}/${fileName}`;
-
- let rootDir;
-
- beforeEach(() => {
- const parentEntry = file(parentPath, parentPath, 'tree');
- const fileEntry = file(filePath, filePath, 'blob', parentEntry);
- rootDir = {
- tree: [],
- };
-
- Object.assign(store.state, {
- entries: {
- [parentPath]: {
- ...parentEntry,
- tree: [fileEntry],
- },
- [filePath]: fileEntry,
- },
- trees: {
- '/': rootDir,
- },
- });
- });
-
- it('creates new directory', done => {
- expect(store.state.entries[newParentPath]).toBeUndefined();
-
- store
- .dispatch('renameEntry', { path: filePath, name: fileName, parentPath: newParentPath })
- .then(() => {
- expect(store.state.entries[newParentPath]).toEqual(
- jasmine.objectContaining({
- path: newParentPath,
- type: 'tree',
- tree: jasmine.arrayContaining([
- store.state.entries[`${newParentPath}/${fileName}`],
- ]),
- }),
- );
- })
- .then(done)
- .catch(done.fail);
- });
-
- describe('when new directory exists', () => {
- let newDir;
-
- beforeEach(() => {
- newDir = file(newParentPath, newParentPath, 'tree');
-
- store.state.entries[newDir.path] = newDir;
- rootDir.tree.push(newDir);
- });
-
- it('inserts in new directory', done => {
- expect(newDir.tree).toEqual([]);
-
- store
- .dispatch('renameEntry', {
- path: filePath,
- name: fileName,
- parentPath: newParentPath,
- })
- .then(() => {
- expect(newDir.tree).toEqual([store.state.entries[`${newParentPath}/${fileName}`]]);
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('when new directory is deleted, it undeletes it', done => {
- store.dispatch('deleteEntry', newParentPath);
-
- expect(store.state.entries[newParentPath].deleted).toBe(true);
- expect(rootDir.tree.some(x => x.path === newParentPath)).toBe(false);
-
- store
- .dispatch('renameEntry', {
- path: filePath,
- name: fileName,
- parentPath: newParentPath,
- })
- .then(() => {
- expect(store.state.entries[newParentPath].deleted).toBe(false);
- expect(rootDir.tree.some(x => x.path === newParentPath)).toBe(true);
- })
- .then(done)
- .catch(done.fail);
- });
- });
- });
- });
- });
-
- describe('getBranchData', () => {
- let mock;
-
- beforeEach(() => {
- mock = new MockAdapter(axios);
- });
-
- afterEach(() => {
- mock.restore();
- });
-
- describe('error', () => {
- let dispatch;
- let callParams;
-
- beforeEach(() => {
- callParams = [
- {
- commit() {},
- state: store.state,
- },
- {
- projectId: 'abc/def',
- branchId: 'master-testing',
- },
- ];
- dispatch = jasmine.createSpy('dispatchSpy');
- document.body.innerHTML += '<div class="flash-container"></div>';
- });
-
- afterEach(() => {
- document.querySelector('.flash-container').remove();
- });
-
- it('passes the error further unchanged without dispatching any action when response is 404', done => {
- mock.onGet(/(.*)/).replyOnce(404);
-
- getBranchData(...callParams)
- .then(done.fail)
- .catch(e => {
- expect(dispatch.calls.count()).toEqual(0);
- expect(e.response.status).toEqual(404);
- expect(document.querySelector('.flash-alert')).toBeNull();
- done();
- });
- });
-
- it('does not pass the error further and flashes an alert if error is not 404', done => {
- mock.onGet(/(.*)/).replyOnce(418);
-
- getBranchData(...callParams)
- .then(done.fail)
- .catch(e => {
- expect(dispatch.calls.count()).toEqual(0);
- expect(e.response).toBeUndefined();
- expect(document.querySelector('.flash-alert')).not.toBeNull();
- done();
- });
- });
- });
- });
-});
diff --git a/spec/javascripts/ide/stores/modules/commit/actions_spec.js b/spec/javascripts/ide/stores/modules/commit/actions_spec.js
deleted file mode 100644
index fb8cb300209..00000000000
--- a/spec/javascripts/ide/stores/modules/commit/actions_spec.js
+++ /dev/null
@@ -1,603 +0,0 @@
-import { resetStore, file } from 'spec/ide/helpers';
-import rootActions from '~/ide/stores/actions';
-import { createStore } from '~/ide/stores';
-import service from '~/ide/services';
-import router from '~/ide/ide_router';
-import eventHub from '~/ide/eventhub';
-import consts from '~/ide/stores/modules/commit/constants';
-import * as mutationTypes from '~/ide/stores/modules/commit/mutation_types';
-import * as actions from '~/ide/stores/modules/commit/actions';
-import { commitActionTypes, PERMISSION_CREATE_MR } from '~/ide/constants';
-import testAction from '../../../../helpers/vuex_action_helper';
-
-const TEST_COMMIT_SHA = '123456789';
-const store = createStore();
-
-describe('IDE commit module actions', () => {
- beforeEach(() => {
- spyOn(router, 'push');
- });
-
- afterEach(() => {
- resetStore(store);
- });
-
- describe('updateCommitMessage', () => {
- it('updates store with new commit message', done => {
- store
- .dispatch('commit/updateCommitMessage', 'testing')
- .then(() => {
- expect(store.state.commit.commitMessage).toBe('testing');
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('discardDraft', () => {
- it('resets commit message to blank', done => {
- store.state.commit.commitMessage = 'testing';
-
- store
- .dispatch('commit/discardDraft')
- .then(() => {
- expect(store.state.commit.commitMessage).not.toBe('testing');
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('updateCommitAction', () => {
- it('updates store with new commit action', done => {
- store
- .dispatch('commit/updateCommitAction', '1')
- .then(() => {
- expect(store.state.commit.commitAction).toBe('1');
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('sets shouldCreateMR to true if "Create new MR" option is visible', done => {
- Object.assign(store.state, {
- shouldHideNewMrOption: false,
- });
-
- testAction(
- actions.updateCommitAction,
- {},
- store.state,
- [
- {
- type: mutationTypes.UPDATE_COMMIT_ACTION,
- payload: { commitAction: jasmine.anything() },
- },
- { type: mutationTypes.TOGGLE_SHOULD_CREATE_MR, payload: true },
- ],
- [],
- done,
- );
- });
-
- it('sets shouldCreateMR to false if "Create new MR" option is hidden', done => {
- Object.assign(store.state, {
- shouldHideNewMrOption: true,
- });
-
- testAction(
- actions.updateCommitAction,
- {},
- store.state,
- [
- {
- type: mutationTypes.UPDATE_COMMIT_ACTION,
- payload: { commitAction: jasmine.anything() },
- },
- { type: mutationTypes.TOGGLE_SHOULD_CREATE_MR, payload: false },
- ],
- [],
- done,
- );
- });
- });
-
- describe('updateBranchName', () => {
- it('updates store with new branch name', done => {
- store
- .dispatch('commit/updateBranchName', 'branch-name')
- .then(() => {
- expect(store.state.commit.newBranchName).toBe('branch-name');
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('setLastCommitMessage', () => {
- beforeEach(() => {
- Object.assign(store.state, {
- currentProjectId: 'abcproject',
- projects: {
- abcproject: {
- web_url: 'http://testing',
- },
- },
- });
- });
-
- it('updates commit message with short_id', done => {
- store
- .dispatch('commit/setLastCommitMessage', { short_id: '123' })
- .then(() => {
- expect(store.state.lastCommitMsg).toContain(
- 'Your changes have been committed. Commit <a href="http://testing/-/commit/123" class="commit-sha">123</a>',
- );
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('updates commit message with stats', done => {
- store
- .dispatch('commit/setLastCommitMessage', {
- short_id: '123',
- stats: {
- additions: '1',
- deletions: '2',
- },
- })
- .then(() => {
- expect(store.state.lastCommitMsg).toBe(
- 'Your changes have been committed. Commit <a href="http://testing/-/commit/123" class="commit-sha">123</a> with 1 additions, 2 deletions.',
- );
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('updateFilesAfterCommit', () => {
- const data = {
- id: '123',
- message: 'testing commit message',
- committed_date: '123',
- committer_name: 'root',
- };
- const branch = 'master';
- let f;
-
- beforeEach(() => {
- spyOn(eventHub, '$emit');
-
- f = file('changedFile');
- Object.assign(f, {
- active: true,
- changed: true,
- content: 'file content',
- });
-
- Object.assign(store.state, {
- currentProjectId: 'abcproject',
- currentBranchId: 'master',
- projects: {
- abcproject: {
- web_url: 'web_url',
- branches: {
- master: {
- workingReference: '',
- commit: {
- short_id: TEST_COMMIT_SHA,
- },
- },
- },
- },
- },
- stagedFiles: [
- f,
- {
- ...file('changedFile2'),
- changed: true,
- },
- ],
- openFiles: store.state.stagedFiles,
- });
-
- store.state.stagedFiles.forEach(stagedFile => {
- store.state.entries[stagedFile.path] = stagedFile;
- });
- });
-
- it('updates stores working reference', done => {
- store
- .dispatch('commit/updateFilesAfterCommit', {
- data,
- branch,
- })
- .then(() => {
- expect(store.state.projects.abcproject.branches.master.workingReference).toBe(data.id);
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('resets all files changed status', done => {
- store
- .dispatch('commit/updateFilesAfterCommit', {
- data,
- branch,
- })
- .then(() => {
- store.state.openFiles.forEach(entry => {
- expect(entry.changed).toBeFalsy();
- });
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('sets files commit data', done => {
- store
- .dispatch('commit/updateFilesAfterCommit', {
- data,
- branch,
- })
- .then(() => {
- expect(f.lastCommitSha).toBe(data.id);
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('updates raw content for changed file', done => {
- store
- .dispatch('commit/updateFilesAfterCommit', {
- data,
- branch,
- })
- .then(() => {
- expect(f.raw).toBe(f.content);
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('emits changed event for file', done => {
- store
- .dispatch('commit/updateFilesAfterCommit', {
- data,
- branch,
- })
- .then(() => {
- expect(eventHub.$emit).toHaveBeenCalledWith(`editor.update.model.content.${f.key}`, {
- content: f.content,
- changed: false,
- });
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('commitChanges', () => {
- let visitUrl;
-
- beforeEach(() => {
- visitUrl = spyOnDependency(rootActions, 'visitUrl');
-
- document.body.innerHTML += '<div class="flash-container"></div>';
-
- const f = {
- ...file('changed'),
- type: 'blob',
- active: true,
- lastCommitSha: TEST_COMMIT_SHA,
- content: '\n',
- raw: '\n',
- };
-
- Object.assign(store.state, {
- stagedFiles: [f],
- changedFiles: [f],
- openFiles: [f],
- currentProjectId: 'abcproject',
- currentBranchId: 'master',
- projects: {
- abcproject: {
- web_url: 'webUrl',
- branches: {
- master: {
- workingReference: '1',
- commit: {
- id: TEST_COMMIT_SHA,
- },
- },
- },
- userPermissions: {
- [PERMISSION_CREATE_MR]: true,
- },
- },
- },
- });
-
- store.state.commit.commitAction = '2';
- store.state.commit.commitMessage = 'testing 123';
-
- store.state.openFiles.forEach(localF => {
- store.state.entries[localF.path] = localF;
- });
- });
-
- afterEach(() => {
- document.querySelector('.flash-container').remove();
- });
-
- describe('success', () => {
- const COMMIT_RESPONSE = {
- id: '123456',
- short_id: '123',
- message: 'test message',
- committed_date: 'date',
- parent_ids: '321',
- stats: {
- additions: '1',
- deletions: '2',
- },
- };
-
- beforeEach(() => {
- spyOn(service, 'commit').and.returnValue(
- Promise.resolve({
- data: COMMIT_RESPONSE,
- }),
- );
- });
-
- it('calls service', done => {
- store
- .dispatch('commit/commitChanges')
- .then(() => {
- expect(service.commit).toHaveBeenCalledWith('abcproject', {
- branch: jasmine.anything(),
- commit_message: 'testing 123',
- actions: [
- {
- action: commitActionTypes.update,
- file_path: jasmine.anything(),
- content: '\n',
- encoding: jasmine.anything(),
- last_commit_id: undefined,
- previous_path: undefined,
- },
- ],
- start_sha: TEST_COMMIT_SHA,
- });
-
- done();
- })
- .catch(done.fail);
- });
-
- it('sends lastCommit ID when not creating new branch', done => {
- store.state.commit.commitAction = '1';
-
- store
- .dispatch('commit/commitChanges')
- .then(() => {
- expect(service.commit).toHaveBeenCalledWith('abcproject', {
- branch: jasmine.anything(),
- commit_message: 'testing 123',
- actions: [
- {
- action: commitActionTypes.update,
- file_path: jasmine.anything(),
- content: '\n',
- encoding: jasmine.anything(),
- last_commit_id: TEST_COMMIT_SHA,
- previous_path: undefined,
- },
- ],
- start_sha: undefined,
- });
-
- done();
- })
- .catch(done.fail);
- });
-
- it('sets last Commit Msg', done => {
- store
- .dispatch('commit/commitChanges')
- .then(() => {
- expect(store.state.lastCommitMsg).toBe(
- 'Your changes have been committed. Commit <a href="webUrl/-/commit/123" class="commit-sha">123</a> with 1 additions, 2 deletions.',
- );
-
- done();
- })
- .catch(done.fail);
- });
-
- it('adds commit data to files', done => {
- store
- .dispatch('commit/commitChanges')
- .then(() => {
- expect(store.state.entries[store.state.openFiles[0].path].lastCommitSha).toBe(
- COMMIT_RESPONSE.id,
- );
-
- done();
- })
- .catch(done.fail);
- });
-
- it('resets stores commit actions', done => {
- store.state.commit.commitAction = consts.COMMIT_TO_NEW_BRANCH;
-
- store
- .dispatch('commit/commitChanges')
- .then(() => {
- expect(store.state.commit.commitAction).not.toBe(consts.COMMIT_TO_NEW_BRANCH);
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('removes all staged files', done => {
- store
- .dispatch('commit/commitChanges')
- .then(() => {
- expect(store.state.stagedFiles.length).toBe(0);
- })
- .then(done)
- .catch(done.fail);
- });
-
- describe('merge request', () => {
- it('redirects to new merge request page', done => {
- spyOn(eventHub, '$on');
-
- store.state.commit.commitAction = consts.COMMIT_TO_NEW_BRANCH;
- store.state.commit.shouldCreateMR = true;
-
- store
- .dispatch('commit/commitChanges')
- .then(() => {
- expect(visitUrl).toHaveBeenCalledWith(
- `webUrl/-/merge_requests/new?merge_request[source_branch]=${
- store.getters['commit/placeholderBranchName']
- }&merge_request[target_branch]=master&nav_source=webide`,
- );
-
- done();
- })
- .catch(done.fail);
- });
-
- it('does not redirect to new merge request page when shouldCreateMR is not checked', done => {
- spyOn(eventHub, '$on');
-
- store.state.commit.commitAction = consts.COMMIT_TO_NEW_BRANCH;
- store.state.commit.shouldCreateMR = false;
-
- store
- .dispatch('commit/commitChanges')
- .then(() => {
- expect(visitUrl).not.toHaveBeenCalled();
- done();
- })
- .catch(done.fail);
- });
-
- it('resets changed files before redirecting', done => {
- visitUrl = visitUrl.and.callFake(() => {
- expect(store.state.stagedFiles.length).toBe(0);
- done();
- });
-
- spyOn(eventHub, '$on');
-
- store.state.commit.commitAction = '3';
-
- store.dispatch('commit/commitChanges').catch(done.fail);
- });
- });
- });
-
- describe('failed', () => {
- beforeEach(() => {
- spyOn(service, 'commit').and.returnValue(
- Promise.resolve({
- data: {
- message: 'failed message',
- },
- }),
- );
- });
-
- it('shows failed message', done => {
- store
- .dispatch('commit/commitChanges')
- .then(() => {
- const alert = document.querySelector('.flash-container');
-
- expect(alert.textContent.trim()).toBe('failed message');
-
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('first commit of a branch', () => {
- const COMMIT_RESPONSE = {
- id: '123456',
- short_id: '123',
- message: 'test message',
- committed_date: 'date',
- parent_ids: [],
- stats: {
- additions: '1',
- deletions: '2',
- },
- };
-
- it('commits TOGGLE_EMPTY_STATE mutation on empty repo', done => {
- spyOn(service, 'commit').and.returnValue(
- Promise.resolve({
- data: COMMIT_RESPONSE,
- }),
- );
-
- spyOn(store, 'commit').and.callThrough();
-
- store
- .dispatch('commit/commitChanges')
- .then(() => {
- expect(store.commit.calls.allArgs()).toEqual(
- jasmine.arrayContaining([
- ['TOGGLE_EMPTY_STATE', jasmine.any(Object), jasmine.any(Object)],
- ]),
- );
- done();
- })
- .catch(done.fail);
- });
-
- it('does not commmit TOGGLE_EMPTY_STATE mutation on existing project', done => {
- COMMIT_RESPONSE.parent_ids.push('1234');
- spyOn(service, 'commit').and.returnValue(
- Promise.resolve({
- data: COMMIT_RESPONSE,
- }),
- );
- spyOn(store, 'commit').and.callThrough();
-
- store
- .dispatch('commit/commitChanges')
- .then(() => {
- expect(store.commit.calls.allArgs()).not.toEqual(
- jasmine.arrayContaining([
- ['TOGGLE_EMPTY_STATE', jasmine.any(Object), jasmine.any(Object)],
- ]),
- );
- done();
- })
- .catch(done.fail);
- });
- });
- });
-
- describe('toggleShouldCreateMR', () => {
- it('commits both toggle and interacting with MR checkbox actions', done => {
- testAction(
- actions.toggleShouldCreateMR,
- {},
- store.state,
- [{ type: mutationTypes.TOGGLE_SHOULD_CREATE_MR }],
- [],
- done,
- );
- });
- });
-});
diff --git a/spec/javascripts/importer_status_spec.js b/spec/javascripts/importer_status_spec.js
deleted file mode 100644
index 90835e1cc21..00000000000
--- a/spec/javascripts/importer_status_spec.js
+++ /dev/null
@@ -1,138 +0,0 @@
-import MockAdapter from 'axios-mock-adapter';
-import { ImporterStatus } from '~/importer_status';
-import axios from '~/lib/utils/axios_utils';
-
-describe('Importer Status', () => {
- let instance;
- let mock;
-
- beforeEach(() => {
- mock = new MockAdapter(axios);
- });
-
- afterEach(() => {
- mock.restore();
- });
-
- describe('addToImport', () => {
- const importUrl = '/import_url';
-
- beforeEach(() => {
- setFixtures(`
- <tr id="repo_123">
- <td class="import-target"></td>
- <td class="import-actions job-status">
- <button name="button" type="submit" class="btn btn-import js-add-to-import">
- </button>
- </td>
- </tr>
- `);
- spyOn(ImporterStatus.prototype, 'initStatusPage').and.callFake(() => {});
- spyOn(ImporterStatus.prototype, 'setAutoUpdate').and.callFake(() => {});
- instance = new ImporterStatus({
- jobsUrl: '',
- importUrl,
- });
- });
-
- it('sets table row to active after post request', done => {
- mock.onPost(importUrl).reply(200, {
- id: 1,
- full_path: '/full_path',
- });
-
- instance
- .addToImport({
- currentTarget: document.querySelector('.js-add-to-import'),
- })
- .then(() => {
- expect(document.querySelector('tr').classList.contains('table-active')).toEqual(true);
- done();
- })
- .catch(done.fail);
- });
-
- it('shows error message after failed POST request', done => {
- appendSetFixtures('<div class="flash-container"></div>');
-
- mock.onPost(importUrl).reply(422, {
- errors: 'You forgot your lunch',
- });
-
- instance
- .addToImport({
- currentTarget: document.querySelector('.js-add-to-import'),
- })
- .then(() => {
- const flashMessage = document.querySelector('.flash-text');
-
- expect(flashMessage.textContent.trim()).toEqual(
- 'An error occurred while importing project: You forgot your lunch',
- );
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('autoUpdate', () => {
- const jobsUrl = '/jobs_url';
-
- beforeEach(() => {
- const div = document.createElement('div');
- div.innerHTML = `
- <div id="project_1">
- <div class="job-status">
- </div>
- </div>
- `;
-
- document.body.appendChild(div);
-
- spyOn(ImporterStatus.prototype, 'initStatusPage').and.callFake(() => {});
- spyOn(ImporterStatus.prototype, 'setAutoUpdate').and.callFake(() => {});
- instance = new ImporterStatus({
- jobsUrl,
- });
- });
-
- function setupMock(importStatus) {
- mock.onGet(jobsUrl).reply(200, [
- {
- id: 1,
- import_status: importStatus,
- },
- ]);
- }
-
- function expectJobStatus(done, status) {
- instance
- .autoUpdate()
- .then(() => {
- expect(document.querySelector('#project_1').innerText.trim()).toEqual(status);
- done();
- })
- .catch(done.fail);
- }
-
- it('sets the job status to done', done => {
- setupMock('finished');
- expectJobStatus(done, 'Done');
- });
-
- it('sets the job status to scheduled', done => {
- setupMock('scheduled');
- expectJobStatus(done, 'Scheduled');
- });
-
- it('sets the job status to started', done => {
- setupMock('started');
- expectJobStatus(done, 'Started');
- });
-
- it('sets the job status to custom status', done => {
- setupMock('custom status');
- expectJobStatus(done, 'custom status');
- });
- });
-});
diff --git a/spec/javascripts/labels_issue_sidebar_spec.js b/spec/javascripts/labels_issue_sidebar_spec.js
deleted file mode 100644
index 94e833ec83b..00000000000
--- a/spec/javascripts/labels_issue_sidebar_spec.js
+++ /dev/null
@@ -1,97 +0,0 @@
-/* eslint-disable no-new */
-
-import $ from 'jquery';
-import MockAdapter from 'axios-mock-adapter';
-import { shuffle } from 'lodash';
-import axios from '~/lib/utils/axios_utils';
-import IssuableContext from '~/issuable_context';
-import LabelsSelect from '~/labels_select';
-
-import '~/gl_dropdown';
-import 'select2';
-import '~/api';
-import '~/create_label';
-import '~/users_select';
-
-let saveLabelCount = 0;
-let mock;
-
-function testLabelClicks(labelOrder, done) {
- $('.edit-link')
- .get(0)
- .click();
-
- setTimeout(() => {
- const labelsInDropdown = $('.dropdown-content a');
-
- expect(labelsInDropdown.length).toBe(10);
-
- const arrayOfLabels = labelsInDropdown.get();
- const randomArrayOfLabels = shuffle(arrayOfLabels);
- randomArrayOfLabels.forEach((label, i) => {
- if (i < saveLabelCount) {
- $(label).click();
- }
- });
-
- $('.edit-link')
- .get(0)
- .click();
-
- setTimeout(() => {
- expect($('.sidebar-collapsed-icon').attr('data-original-title')).toBe(labelOrder);
- done();
- }, 0);
- }, 0);
-}
-
-describe('Issue dropdown sidebar', () => {
- preloadFixtures('static/issue_sidebar_label.html');
-
- beforeEach(() => {
- loadFixtures('static/issue_sidebar_label.html');
-
- mock = new MockAdapter(axios);
-
- new IssuableContext('{"id":1,"name":"Administrator","username":"root"}');
- new LabelsSelect();
-
- mock.onGet('/root/test/labels.json').reply(() => {
- const labels = Array(10)
- .fill()
- .map((_val, i) => ({
- id: i,
- title: `test ${i}`,
- color: '#5CB85C',
- }));
-
- return [200, labels];
- });
-
- mock.onPut('/root/test/issues/2.json').reply(() => {
- const labels = Array(saveLabelCount)
- .fill()
- .map((_val, i) => ({
- id: i,
- title: `test ${i}`,
- color: '#5CB85C',
- }));
-
- return [200, { labels }];
- });
- });
-
- afterEach(() => {
- mock.restore();
- });
-
- it('changes collapsed tooltip when changing labels when less than 5', done => {
- saveLabelCount = 5;
- testLabelClicks('test 0, test 1, test 2, test 3, test 4', done);
- });
-
- it('changes collapsed tooltip when changing labels when more than 5', done => {
- saveLabelCount = 6;
- testLabelClicks('test 0, test 1, test 2, test 3, test 4, and 1 more', done);
- });
-});
diff --git a/spec/javascripts/lazy_loader_spec.js b/spec/javascripts/lazy_loader_spec.js
deleted file mode 100644
index 82ab73c2170..00000000000
--- a/spec/javascripts/lazy_loader_spec.js
+++ /dev/null
@@ -1,244 +0,0 @@
-import LazyLoader from '~/lazy_loader';
-import { TEST_HOST } from './test_constants';
-import scrollIntoViewPromise from './helpers/scroll_into_view_promise';
-import waitForPromises from './helpers/wait_for_promises';
-import waitForAttributeChange from './helpers/wait_for_attribute_change';
-
-const execImmediately = callback => {
- callback();
-};
-
-describe('LazyLoader', function() {
- let lazyLoader = null;
-
- preloadFixtures('issues/issue_with_comment.html');
-
- describe('without IntersectionObserver', () => {
- beforeEach(function() {
- loadFixtures('issues/issue_with_comment.html');
-
- lazyLoader = new LazyLoader({
- observerNode: 'foobar',
- });
-
- spyOn(LazyLoader, 'supportsIntersectionObserver').and.callFake(() => false);
-
- spyOn(LazyLoader, 'loadImage').and.callThrough();
-
- spyOn(window, 'requestAnimationFrame').and.callFake(execImmediately);
- spyOn(window, 'requestIdleCallback').and.callFake(execImmediately);
-
- // Doing everything that happens normally in onload
- lazyLoader.register();
- });
-
- afterEach(() => {
- lazyLoader.unregister();
- });
-
- it('should copy value from data-src to src for img 1', function(done) {
- const img = document.querySelectorAll('img[data-src]')[0];
- const originalDataSrc = img.getAttribute('data-src');
-
- Promise.all([scrollIntoViewPromise(img), waitForAttributeChange(img, ['data-src', 'src'])])
- .then(() => {
- expect(LazyLoader.loadImage).toHaveBeenCalled();
- expect(img.getAttribute('src')).toBe(originalDataSrc);
- expect(img).toHaveClass('js-lazy-loaded');
- done();
- })
- .catch(done.fail);
- });
-
- it('should lazy load dynamically added data-src images', function(done) {
- const newImg = document.createElement('img');
- const testPath = `${TEST_HOST}/img/testimg.png`;
- newImg.className = 'lazy';
- newImg.setAttribute('data-src', testPath);
- document.body.appendChild(newImg);
-
- Promise.all([
- scrollIntoViewPromise(newImg),
- waitForAttributeChange(newImg, ['data-src', 'src']),
- ])
- .then(() => {
- expect(LazyLoader.loadImage).toHaveBeenCalledWith(newImg);
- expect(newImg.getAttribute('src')).toBe(testPath);
- expect(newImg).toHaveClass('js-lazy-loaded');
- done();
- })
- .catch(done.fail);
- });
-
- it('should not alter normal images', function(done) {
- const newImg = document.createElement('img');
- const testPath = `${TEST_HOST}/img/testimg.png`;
- newImg.setAttribute('src', testPath);
- document.body.appendChild(newImg);
-
- scrollIntoViewPromise(newImg)
- .then(waitForPromises)
- .then(() => {
- expect(LazyLoader.loadImage).not.toHaveBeenCalledWith(newImg);
- expect(newImg).not.toHaveClass('js-lazy-loaded');
- done();
- })
- .catch(done.fail);
- });
-
- it('should not load dynamically added pictures if content observer is turned off', done => {
- lazyLoader.stopContentObserver();
-
- const newImg = document.createElement('img');
- const testPath = `${TEST_HOST}/img/testimg.png`;
- newImg.className = 'lazy';
- newImg.setAttribute('data-src', testPath);
- document.body.appendChild(newImg);
-
- scrollIntoViewPromise(newImg)
- .then(waitForPromises)
- .then(() => {
- expect(LazyLoader.loadImage).not.toHaveBeenCalledWith(newImg);
- expect(newImg).not.toHaveClass('js-lazy-loaded');
- done();
- })
- .catch(done.fail);
- });
-
- it('should load dynamically added pictures if content observer is turned off and on again', done => {
- lazyLoader.stopContentObserver();
- lazyLoader.startContentObserver();
-
- const newImg = document.createElement('img');
- const testPath = `${TEST_HOST}/img/testimg.png`;
- newImg.className = 'lazy';
- newImg.setAttribute('data-src', testPath);
- document.body.appendChild(newImg);
-
- Promise.all([
- scrollIntoViewPromise(newImg),
- waitForAttributeChange(newImg, ['data-src', 'src']),
- ])
- .then(waitForPromises)
- .then(() => {
- expect(LazyLoader.loadImage).toHaveBeenCalledWith(newImg);
- expect(newImg).toHaveClass('js-lazy-loaded');
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('with IntersectionObserver', () => {
- beforeEach(function() {
- loadFixtures('issues/issue_with_comment.html');
-
- lazyLoader = new LazyLoader({
- observerNode: 'foobar',
- });
-
- spyOn(LazyLoader, 'loadImage').and.callThrough();
-
- spyOn(window, 'requestAnimationFrame').and.callFake(execImmediately);
- spyOn(window, 'requestIdleCallback').and.callFake(execImmediately);
-
- // Doing everything that happens normally in onload
- lazyLoader.register();
- });
-
- afterEach(() => {
- lazyLoader.unregister();
- });
-
- it('should copy value from data-src to src for img 1', function(done) {
- const img = document.querySelectorAll('img[data-src]')[0];
- const originalDataSrc = img.getAttribute('data-src');
-
- Promise.all([scrollIntoViewPromise(img), waitForAttributeChange(img, ['data-src', 'src'])])
- .then(() => {
- expect(LazyLoader.loadImage).toHaveBeenCalledWith(img);
- expect(img.getAttribute('src')).toBe(originalDataSrc);
- expect(img).toHaveClass('js-lazy-loaded');
- done();
- })
- .catch(done.fail);
- });
-
- it('should lazy load dynamically added data-src images', function(done) {
- const newImg = document.createElement('img');
- const testPath = `${TEST_HOST}/img/testimg.png`;
- newImg.className = 'lazy';
- newImg.setAttribute('data-src', testPath);
- document.body.appendChild(newImg);
-
- Promise.all([
- scrollIntoViewPromise(newImg),
- waitForAttributeChange(newImg, ['data-src', 'src']),
- ])
- .then(() => {
- expect(LazyLoader.loadImage).toHaveBeenCalledWith(newImg);
- expect(newImg.getAttribute('src')).toBe(testPath);
- expect(newImg).toHaveClass('js-lazy-loaded');
- done();
- })
- .catch(done.fail);
- });
-
- it('should not alter normal images', function(done) {
- const newImg = document.createElement('img');
- const testPath = `${TEST_HOST}/img/testimg.png`;
- newImg.setAttribute('src', testPath);
- document.body.appendChild(newImg);
-
- scrollIntoViewPromise(newImg)
- .then(waitForPromises)
- .then(() => {
- expect(LazyLoader.loadImage).not.toHaveBeenCalledWith(newImg);
- expect(newImg).not.toHaveClass('js-lazy-loaded');
- done();
- })
- .catch(done.fail);
- });
-
- it('should not load dynamically added pictures if content observer is turned off', done => {
- lazyLoader.stopContentObserver();
-
- const newImg = document.createElement('img');
- const testPath = `${TEST_HOST}/img/testimg.png`;
- newImg.className = 'lazy';
- newImg.setAttribute('data-src', testPath);
- document.body.appendChild(newImg);
-
- scrollIntoViewPromise(newImg)
- .then(waitForPromises)
- .then(() => {
- expect(LazyLoader.loadImage).not.toHaveBeenCalledWith(newImg);
- expect(newImg).not.toHaveClass('js-lazy-loaded');
- done();
- })
- .catch(done.fail);
- });
-
- it('should load dynamically added pictures if content observer is turned off and on again', done => {
- lazyLoader.stopContentObserver();
- lazyLoader.startContentObserver();
-
- const newImg = document.createElement('img');
- const testPath = `${TEST_HOST}/img/testimg.png`;
- newImg.className = 'lazy';
- newImg.setAttribute('data-src', testPath);
- document.body.appendChild(newImg);
-
- Promise.all([
- scrollIntoViewPromise(newImg),
- waitForAttributeChange(newImg, ['data-src', 'src']),
- ])
- .then(() => {
- expect(LazyLoader.loadImage).toHaveBeenCalledWith(newImg);
- expect(newImg).toHaveClass('js-lazy-loaded');
- done();
- })
- .catch(done.fail);
- });
- });
-});
diff --git a/spec/javascripts/line_highlighter_spec.js b/spec/javascripts/line_highlighter_spec.js
deleted file mode 100644
index bedab0fd003..00000000000
--- a/spec/javascripts/line_highlighter_spec.js
+++ /dev/null
@@ -1,261 +0,0 @@
-/* eslint-disable dot-notation, no-return-assign, no-new, no-underscore-dangle */
-
-import $ from 'jquery';
-import LineHighlighter from '~/line_highlighter';
-
-describe('LineHighlighter', function() {
- preloadFixtures('static/line_highlighter.html');
- const clickLine = function(number, eventData = {}) {
- if ($.isEmptyObject(eventData)) {
- return $(`#L${number}`).click();
- }
- const e = $.Event('click', eventData);
- return $(`#L${number}`).trigger(e);
- };
- beforeEach(function() {
- loadFixtures('static/line_highlighter.html');
- this['class'] = new LineHighlighter();
- this.css = this['class'].highlightLineClass;
- return (this.spies = {
- __setLocationHash__: spyOn(this['class'], '__setLocationHash__').and.callFake(function() {}),
- });
- });
-
- describe('behavior', function() {
- it('highlights one line given in the URL hash', function() {
- new LineHighlighter({ hash: '#L13' });
-
- expect($('#LC13')).toHaveClass(this.css);
- });
-
- it('highlights one line given in the URL hash with given CSS class name', function() {
- const hiliter = new LineHighlighter({ hash: '#L13', highlightLineClass: 'hilite' });
-
- expect(hiliter.highlightLineClass).toBe('hilite');
- expect($('#LC13')).toHaveClass('hilite');
- expect($('#LC13')).not.toHaveClass('hll');
- });
-
- it('highlights a range of lines given in the URL hash', function() {
- new LineHighlighter({ hash: '#L5-25' });
-
- expect($(`.${this.css}`).length).toBe(21);
- for (let line = 5; line <= 25; line += 1) {
- expect($(`#LC${line}`)).toHaveClass(this.css);
- }
- });
-
- it('scrolls to the first highlighted line on initial load', function() {
- const spy = spyOn($, 'scrollTo');
- new LineHighlighter({ hash: '#L5-25' });
-
- expect(spy).toHaveBeenCalledWith('#L5', jasmine.anything());
- });
-
- it('discards click events', function() {
- const spy = spyOnEvent('a[data-line-number]', 'click');
- clickLine(13);
-
- expect(spy).toHaveBeenPrevented();
- });
-
- it('handles garbage input from the hash', function() {
- const func = function() {
- return new LineHighlighter({ fileHolderSelector: '#blob-content-holder' });
- };
-
- expect(func).not.toThrow();
- });
-
- it('handles hashchange event', () => {
- const highlighter = new LineHighlighter();
-
- spyOn(highlighter, 'highlightHash');
-
- window.dispatchEvent(new Event('hashchange'), 'L15');
-
- expect(highlighter.highlightHash).toHaveBeenCalled();
- });
- });
-
- describe('clickHandler', function() {
- it('handles clicking on a child icon element', function() {
- const spy = spyOn(this['class'], 'setHash').and.callThrough();
- $('#L13 i')
- .mousedown()
- .click();
-
- expect(spy).toHaveBeenCalledWith(13);
- expect($('#LC13')).toHaveClass(this.css);
- });
-
- describe('without shiftKey', function() {
- it('highlights one line when clicked', function() {
- clickLine(13);
-
- expect($('#LC13')).toHaveClass(this.css);
- });
-
- it('unhighlights previously highlighted lines', function() {
- clickLine(13);
- clickLine(20);
-
- expect($('#LC13')).not.toHaveClass(this.css);
- expect($('#LC20')).toHaveClass(this.css);
- });
-
- it('sets the hash', function() {
- const spy = spyOn(this['class'], 'setHash').and.callThrough();
- clickLine(13);
-
- expect(spy).toHaveBeenCalledWith(13);
- });
- });
-
- describe('with shiftKey', function() {
- it('sets the hash', function() {
- const spy = spyOn(this['class'], 'setHash').and.callThrough();
- clickLine(13);
- clickLine(20, {
- shiftKey: true,
- });
-
- expect(spy).toHaveBeenCalledWith(13);
- expect(spy).toHaveBeenCalledWith(13, 20);
- });
-
- describe('without existing highlight', function() {
- it('highlights the clicked line', function() {
- clickLine(13, {
- shiftKey: true,
- });
-
- expect($('#LC13')).toHaveClass(this.css);
- expect($(`.${this.css}`).length).toBe(1);
- });
-
- it('sets the hash', function() {
- const spy = spyOn(this['class'], 'setHash');
- clickLine(13, {
- shiftKey: true,
- });
-
- expect(spy).toHaveBeenCalledWith(13);
- });
- });
-
- describe('with existing single-line highlight', function() {
- it('uses existing line as last line when target is lesser', function() {
- clickLine(20);
- clickLine(15, {
- shiftKey: true,
- });
-
- expect($(`.${this.css}`).length).toBe(6);
- for (let line = 15; line <= 20; line += 1) {
- expect($(`#LC${line}`)).toHaveClass(this.css);
- }
- });
-
- it('uses existing line as first line when target is greater', function() {
- clickLine(5);
- clickLine(10, {
- shiftKey: true,
- });
-
- expect($(`.${this.css}`).length).toBe(6);
- for (let line = 5; line <= 10; line += 1) {
- expect($(`#LC${line}`)).toHaveClass(this.css);
- }
- });
- });
-
- describe('with existing multi-line highlight', function() {
- beforeEach(function() {
- clickLine(10, {
- shiftKey: true,
- });
- clickLine(13, {
- shiftKey: true,
- });
- });
-
- it('uses target as first line when it is less than existing first line', function() {
- clickLine(5, {
- shiftKey: true,
- });
-
- expect($(`.${this.css}`).length).toBe(6);
- for (let line = 5; line <= 10; line += 1) {
- expect($(`#LC${line}`)).toHaveClass(this.css);
- }
- });
-
- it('uses target as last line when it is greater than existing first line', function() {
- clickLine(15, {
- shiftKey: true,
- });
-
- expect($(`.${this.css}`).length).toBe(6);
- for (let line = 10; line <= 15; line += 1) {
- expect($(`#LC${line}`)).toHaveClass(this.css);
- }
- });
- });
- });
- });
-
- describe('hashToRange', function() {
- beforeEach(function() {
- this.subject = this['class'].hashToRange;
- });
-
- it('extracts a single line number from the hash', function() {
- expect(this.subject('#L5')).toEqual([5, null]);
- });
-
- it('extracts a range of line numbers from the hash', function() {
- expect(this.subject('#L5-15')).toEqual([5, 15]);
- });
-
- it('returns [null, null] when the hash is not a line number', function() {
- expect(this.subject('#foo')).toEqual([null, null]);
- });
- });
-
- describe('highlightLine', function() {
- beforeEach(function() {
- this.subject = this['class'].highlightLine;
- });
-
- it('highlights the specified line', function() {
- this.subject(13);
-
- expect($('#LC13')).toHaveClass(this.css);
- });
-
- it('accepts a String-based number', function() {
- this.subject('13');
-
- expect($('#LC13')).toHaveClass(this.css);
- });
- });
-
- describe('setHash', function() {
- beforeEach(function() {
- this.subject = this['class'].setHash;
- });
-
- it('sets the location hash for a single line', function() {
- this.subject(5);
-
- expect(this.spies.__setLocationHash__).toHaveBeenCalledWith('#L5');
- });
-
- it('sets the location hash for a range', function() {
- this.subject(5, 15);
-
- expect(this.spies.__setLocationHash__).toHaveBeenCalledWith('#L5-15');
- });
- });
-});
diff --git a/spec/javascripts/merge_request_spec.js b/spec/javascripts/merge_request_spec.js
deleted file mode 100644
index b6173b9b171..00000000000
--- a/spec/javascripts/merge_request_spec.js
+++ /dev/null
@@ -1,187 +0,0 @@
-import $ from 'jquery';
-import MockAdapter from 'axios-mock-adapter';
-import axios from '~/lib/utils/axios_utils';
-import MergeRequest from '~/merge_request';
-import CloseReopenReportToggle from '~/close_reopen_report_toggle';
-import IssuablesHelper from '~/helpers/issuables_helper';
-
-describe('MergeRequest', function() {
- describe('task lists', function() {
- let mock;
-
- preloadFixtures('merge_requests/merge_request_with_task_list.html');
- beforeEach(function() {
- loadFixtures('merge_requests/merge_request_with_task_list.html');
-
- spyOn(axios, 'patch').and.callThrough();
- mock = new MockAdapter(axios);
-
- mock
- .onPatch(`${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/-/merge_requests/1.json`)
- .reply(200, {});
-
- this.merge = new MergeRequest();
- return this.merge;
- });
-
- afterEach(() => {
- mock.restore();
- });
-
- it('modifies the Markdown field', done => {
- spyOn($, 'ajax').and.stub();
- const changeEvent = document.createEvent('HTMLEvents');
- changeEvent.initEvent('change', true, true);
- $('input[type=checkbox]')
- .first()
- .attr('checked', true)[0]
- .dispatchEvent(changeEvent);
- setTimeout(() => {
- expect($('.js-task-list-field').val()).toBe(
- '- [x] Task List Item\n- [ ] \n- [ ] Task List Item 2\n',
- );
- done();
- });
- });
-
- it('ensure that task with only spaces does not get checked incorrectly', done => {
- // fixed in 'deckar01-task_list', '2.2.1' gem
- spyOn($, 'ajax').and.stub();
- const changeEvent = document.createEvent('HTMLEvents');
- changeEvent.initEvent('change', true, true);
- $('input[type=checkbox]')
- .last()
- .attr('checked', true)[0]
- .dispatchEvent(changeEvent);
- setTimeout(() => {
- expect($('.js-task-list-field').val()).toBe(
- '- [ ] Task List Item\n- [ ] \n- [x] Task List Item 2\n',
- );
- done();
- });
- });
-
- describe('tasklist', () => {
- const lineNumber = 8;
- const lineSource = '- [ ] item 8';
- const index = 3;
- const checked = true;
-
- it('submits an ajax request on tasklist:changed', done => {
- $('.js-task-list-field').trigger({
- type: 'tasklist:changed',
- detail: { lineNumber, lineSource, index, checked },
- });
-
- setTimeout(() => {
- expect(axios.patch).toHaveBeenCalledWith(
- `${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/-/merge_requests/1.json`,
- {
- merge_request: {
- description: '- [ ] Task List Item\n- [ ] \n- [ ] Task List Item 2\n',
- lock_version: 0,
- update_task: { line_number: lineNumber, line_source: lineSource, index, checked },
- },
- },
- );
-
- done();
- });
- });
-
- // https://gitlab.com/gitlab-org/gitlab/issues/34861
- // eslint-disable-next-line jasmine/no-disabled-tests
- xit('shows an error notification when tasklist update failed', done => {
- mock
- .onPatch(
- `${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/-/merge_requests/1.json`,
- )
- .reply(409, {});
-
- $('.js-task-list-field').trigger({
- type: 'tasklist:changed',
- detail: { lineNumber, lineSource, index, checked },
- });
-
- setTimeout(() => {
- expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
- 'Someone edited this merge request at the same time you did. Please refresh the page to see changes.',
- );
-
- done();
- });
- });
- });
- });
-
- describe('class constructor', () => {
- beforeEach(() => {
- spyOn($, 'ajax').and.stub();
- });
-
- it('calls .initCloseReopenReport', () => {
- spyOn(IssuablesHelper, 'initCloseReopenReport');
-
- new MergeRequest(); // eslint-disable-line no-new
-
- expect(IssuablesHelper.initCloseReopenReport).toHaveBeenCalled();
- });
-
- it('calls .initDroplab', () => {
- const container = jasmine.createSpyObj('container', ['querySelector']);
- const dropdownTrigger = {};
- const dropdownList = {};
- const button = {};
-
- spyOn(CloseReopenReportToggle.prototype, 'initDroplab');
- spyOn(document, 'querySelector').and.returnValue(container);
- container.querySelector.and.returnValues(dropdownTrigger, dropdownList, button);
-
- new MergeRequest(); // eslint-disable-line no-new
-
- expect(document.querySelector).toHaveBeenCalledWith('.js-issuable-close-dropdown');
- expect(container.querySelector).toHaveBeenCalledWith('.js-issuable-close-toggle');
- expect(container.querySelector).toHaveBeenCalledWith('.js-issuable-close-menu');
- expect(container.querySelector).toHaveBeenCalledWith('.js-issuable-close-button');
- expect(CloseReopenReportToggle.prototype.initDroplab).toHaveBeenCalled();
- });
- });
-
- describe('hideCloseButton', () => {
- describe('merge request of another user', () => {
- beforeEach(() => {
- loadFixtures('merge_requests/merge_request_with_task_list.html');
- this.el = document.querySelector('.js-issuable-actions');
- new MergeRequest(); // eslint-disable-line no-new
- MergeRequest.hideCloseButton();
- });
-
- it('hides the dropdown close item and selects the next item', () => {
- const closeItem = this.el.querySelector('li.close-item');
- const smallCloseItem = this.el.querySelector('.js-close-item');
- const reportItem = this.el.querySelector('li.report-item');
-
- expect(closeItem).toHaveClass('hidden');
- expect(smallCloseItem).toHaveClass('hidden');
- expect(reportItem).toHaveClass('droplab-item-selected');
- expect(reportItem).not.toHaveClass('hidden');
- });
- });
-
- describe('merge request of current_user', () => {
- beforeEach(() => {
- loadFixtures('merge_requests/merge_request_of_current_user.html');
- this.el = document.querySelector('.js-issuable-actions');
- MergeRequest.hideCloseButton();
- });
-
- it('hides the close button', () => {
- const closeButton = this.el.querySelector('.btn-close');
- const smallCloseItem = this.el.querySelector('.js-close-item');
-
- expect(closeButton).toHaveClass('hidden');
- expect(smallCloseItem).toHaveClass('hidden');
- });
- });
- });
-});
diff --git a/spec/javascripts/merge_request_tabs_spec.js b/spec/javascripts/merge_request_tabs_spec.js
deleted file mode 100644
index cbb61333d77..00000000000
--- a/spec/javascripts/merge_request_tabs_spec.js
+++ /dev/null
@@ -1,283 +0,0 @@
-import $ from 'jquery';
-import MockAdapter from 'axios-mock-adapter';
-import axios from '~/lib/utils/axios_utils';
-import MergeRequestTabs from '~/merge_request_tabs';
-import '~/commit/pipelines/pipelines_bundle';
-import '~/lib/utils/common_utils';
-import 'vendor/jquery.scrollTo';
-import initMrPage from './helpers/init_vue_mr_page_helper';
-
-describe('MergeRequestTabs', function() {
- let mrPageMock;
- const stubLocation = {};
- const setLocation = function(stubs) {
- const defaults = {
- pathname: '',
- search: '',
- hash: '',
- };
- $.extend(stubLocation, defaults, stubs || {});
- };
-
- preloadFixtures(
- 'merge_requests/merge_request_with_task_list.html',
- 'merge_requests/diff_comment.html',
- );
-
- beforeEach(function() {
- mrPageMock = initMrPage();
- this.class = new MergeRequestTabs({ stubLocation });
- setLocation();
-
- this.spies = {
- history: spyOn(window.history, 'replaceState').and.callFake(function() {}),
- };
- });
-
- afterEach(function() {
- this.class.unbindEvents();
- this.class.destroyPipelinesView();
- mrPageMock.restore();
- $('.js-merge-request-test').remove();
- });
-
- describe('opensInNewTab', function() {
- const windowTarget = '_blank';
- let clickTabParams;
- let tabUrl;
-
- beforeEach(function() {
- loadFixtures('merge_requests/merge_request_with_task_list.html');
-
- tabUrl = $('.commits-tab a').attr('href');
-
- clickTabParams = {
- metaKey: false,
- ctrlKey: false,
- which: 1,
- stopImmediatePropagation() {},
- preventDefault() {},
- currentTarget: {
- getAttribute(attr) {
- return attr === 'href' ? tabUrl : null;
- },
- },
- };
- });
-
- describe('meta click', () => {
- let metakeyEvent;
-
- beforeEach(function() {
- metakeyEvent = $.Event('click', { keyCode: 91, ctrlKey: true });
- });
-
- it('opens page when commits link is clicked', function() {
- spyOn(window, 'open').and.callFake(function(url, name) {
- expect(url).toEqual(tabUrl);
- expect(name).toEqual(windowTarget);
- });
-
- this.class.bindEvents();
- $('.merge-request-tabs .commits-tab a').trigger(metakeyEvent);
-
- expect(window.open).toHaveBeenCalled();
- });
-
- it('opens page when commits badge is clicked', function() {
- spyOn(window, 'open').and.callFake(function(url, name) {
- expect(url).toEqual(tabUrl);
- expect(name).toEqual(windowTarget);
- });
-
- this.class.bindEvents();
- $('.merge-request-tabs .commits-tab a .badge').trigger(metakeyEvent);
-
- expect(window.open).toHaveBeenCalled();
- });
- });
-
- it('opens page tab in a new browser tab with Ctrl+Click - Windows/Linux', function() {
- spyOn(window, 'open').and.callFake(function(url, name) {
- expect(url).toEqual(tabUrl);
- expect(name).toEqual(windowTarget);
- });
-
- this.class.clickTab({ ...clickTabParams, metaKey: true });
-
- expect(window.open).toHaveBeenCalled();
- });
-
- it('opens page tab in a new browser tab with Cmd+Click - Mac', function() {
- spyOn(window, 'open').and.callFake(function(url, name) {
- expect(url).toEqual(tabUrl);
- expect(name).toEqual(windowTarget);
- });
-
- this.class.clickTab({ ...clickTabParams, ctrlKey: true });
-
- expect(window.open).toHaveBeenCalled();
- });
-
- it('opens page tab in a new browser tab with Middle-click - Mac/PC', function() {
- spyOn(window, 'open').and.callFake(function(url, name) {
- expect(url).toEqual(tabUrl);
- expect(name).toEqual(windowTarget);
- });
-
- this.class.clickTab({ ...clickTabParams, which: 2 });
-
- expect(window.open).toHaveBeenCalled();
- });
- });
-
- describe('setCurrentAction', function() {
- let mock;
-
- beforeEach(function() {
- mock = new MockAdapter(axios);
- mock.onAny().reply({ data: {} });
- this.subject = this.class.setCurrentAction;
- });
-
- afterEach(() => {
- mock.restore();
- });
-
- it('changes from commits', function() {
- setLocation({
- pathname: '/foo/bar/-/merge_requests/1/commits',
- });
-
- expect(this.subject('show')).toBe('/foo/bar/-/merge_requests/1');
- expect(this.subject('diffs')).toBe('/foo/bar/-/merge_requests/1/diffs');
- });
-
- it('changes from diffs', function() {
- setLocation({
- pathname: '/foo/bar/-/merge_requests/1/diffs',
- });
-
- expect(this.subject('show')).toBe('/foo/bar/-/merge_requests/1');
- expect(this.subject('commits')).toBe('/foo/bar/-/merge_requests/1/commits');
- });
-
- it('changes from diffs.html', function() {
- setLocation({
- pathname: '/foo/bar/-/merge_requests/1/diffs.html',
- });
-
- expect(this.subject('show')).toBe('/foo/bar/-/merge_requests/1');
- expect(this.subject('commits')).toBe('/foo/bar/-/merge_requests/1/commits');
- });
-
- it('changes from notes', function() {
- setLocation({
- pathname: '/foo/bar/-/merge_requests/1',
- });
-
- expect(this.subject('diffs')).toBe('/foo/bar/-/merge_requests/1/diffs');
- expect(this.subject('commits')).toBe('/foo/bar/-/merge_requests/1/commits');
- });
-
- it('includes search parameters and hash string', function() {
- setLocation({
- pathname: '/foo/bar/-/merge_requests/1/diffs',
- search: '?view=parallel',
- hash: '#L15-35',
- });
-
- expect(this.subject('show')).toBe('/foo/bar/-/merge_requests/1?view=parallel#L15-35');
- });
-
- it('replaces the current history state', function() {
- setLocation({
- pathname: '/foo/bar/-/merge_requests/1',
- });
- const newState = this.subject('commits');
-
- expect(this.spies.history).toHaveBeenCalledWith(
- {
- url: newState,
- },
- document.title,
- newState,
- );
- });
-
- it('treats "show" like "notes"', function() {
- setLocation({
- pathname: '/foo/bar/-/merge_requests/1/commits',
- });
-
- expect(this.subject('show')).toBe('/foo/bar/-/merge_requests/1');
- });
- });
-
- describe('expandViewContainer', function() {
- beforeEach(() => {
- $('body').append(
- '<div class="content-wrapper"><div class="container-fluid container-limited"></div></div>',
- );
- });
-
- afterEach(() => {
- $('.content-wrapper').remove();
- });
-
- it('removes container-limited from containers', function() {
- this.class.expandViewContainer();
-
- expect($('.content-wrapper')).not.toContainElement('.container-limited');
- });
-
- it('does not add container-limited when fluid layout is prefered', function() {
- $('.content-wrapper .container-fluid').removeClass('container-limited');
-
- this.class.expandViewContainer(false);
-
- expect($('.content-wrapper')).not.toContainElement('.container-limited');
- });
-
- it('does remove container-limited from breadcrumbs', function() {
- $('.container-limited').addClass('breadcrumbs');
- this.class.expandViewContainer();
-
- expect($('.content-wrapper')).toContainElement('.container-limited');
- });
- });
-
- describe('tabShown', function() {
- const mainContent = document.createElement('div');
- const tabContent = document.createElement('div');
-
- beforeEach(function() {
- spyOn(mainContent, 'getBoundingClientRect').and.returnValue({ top: 10 });
- spyOn(tabContent, 'getBoundingClientRect').and.returnValue({ top: 100 });
- spyOn(document, 'querySelector').and.callFake(function(selector) {
- return selector === '.content-wrapper' ? mainContent : tabContent;
- });
- this.class.currentAction = 'commits';
- });
-
- it('calls window scrollTo with options if document has scrollBehavior', function() {
- document.documentElement.style.scrollBehavior = '';
-
- spyOn(window, 'scrollTo');
-
- this.class.tabShown('commits', 'foobar');
-
- expect(window.scrollTo.calls.first().args[0]).toEqual({ top: 39, behavior: 'smooth' });
- });
-
- it('calls window scrollTo with two args if document does not have scrollBehavior', function() {
- spyOnProperty(document.documentElement, 'style', 'get').and.returnValue({});
-
- spyOn(window, 'scrollTo');
-
- this.class.tabShown('commits', 'foobar');
-
- expect(window.scrollTo.calls.first().args).toEqual([0, 39]);
- });
- });
-});
diff --git a/spec/javascripts/mini_pipeline_graph_dropdown_spec.js b/spec/javascripts/mini_pipeline_graph_dropdown_spec.js
deleted file mode 100644
index aa4a376caf7..00000000000
--- a/spec/javascripts/mini_pipeline_graph_dropdown_spec.js
+++ /dev/null
@@ -1,106 +0,0 @@
-import $ from 'jquery';
-import MockAdapter from 'axios-mock-adapter';
-import axios from '~/lib/utils/axios_utils';
-import MiniPipelineGraph from '~/mini_pipeline_graph_dropdown';
-import timeoutPromise from './helpers/set_timeout_promise_helper';
-
-describe('Mini Pipeline Graph Dropdown', () => {
- preloadFixtures('static/mini_dropdown_graph.html');
-
- beforeEach(() => {
- loadFixtures('static/mini_dropdown_graph.html');
- });
-
- describe('When is initialized', () => {
- it('should initialize without errors when no options are given', () => {
- const miniPipelineGraph = new MiniPipelineGraph();
-
- expect(miniPipelineGraph.dropdownListSelector).toEqual('.js-builds-dropdown-container');
- });
-
- it('should set the container as the given prop', () => {
- const container = '.foo';
-
- const miniPipelineGraph = new MiniPipelineGraph({ container });
-
- expect(miniPipelineGraph.container).toEqual(container);
- });
- });
-
- describe('When dropdown is clicked', () => {
- let mock;
-
- beforeEach(() => {
- mock = new MockAdapter(axios);
- });
-
- afterEach(() => {
- mock.restore();
- });
-
- it('should call getBuildsList', () => {
- const getBuildsListSpy = spyOn(MiniPipelineGraph.prototype, 'getBuildsList').and.callFake(
- function() {},
- );
-
- new MiniPipelineGraph({ container: '.js-builds-dropdown-tests' }).bindEvents();
-
- document.querySelector('.js-builds-dropdown-button').click();
-
- expect(getBuildsListSpy).toHaveBeenCalled();
- });
-
- it('should make a request to the endpoint provided in the html', () => {
- const ajaxSpy = spyOn(axios, 'get').and.callThrough();
-
- mock.onGet('foobar').reply(200, {
- html: '',
- });
-
- new MiniPipelineGraph({ container: '.js-builds-dropdown-tests' }).bindEvents();
-
- document.querySelector('.js-builds-dropdown-button').click();
-
- expect(ajaxSpy.calls.allArgs()[0][0]).toEqual('foobar');
- });
-
- it('should not close when user uses cmd/ctrl + click', done => {
- mock.onGet('foobar').reply(200, {
- html: `<li>
- <a class="mini-pipeline-graph-dropdown-item" href="#">
- <span class="ci-status-icon ci-status-icon-failed"></span>
- <span class="ci-build-text">build</span>
- </a>
- <a class="ci-action-icon-wrapper js-ci-action-icon" href="#"></a>
- </li>`,
- });
- new MiniPipelineGraph({ container: '.js-builds-dropdown-tests' }).bindEvents();
-
- document.querySelector('.js-builds-dropdown-button').click();
-
- timeoutPromise()
- .then(() => {
- document.querySelector('a.mini-pipeline-graph-dropdown-item').click();
- })
- .then(timeoutPromise)
- .then(() => {
- expect($('.js-builds-dropdown-list').is(':visible')).toEqual(true);
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('should close the dropdown when request returns an error', done => {
- mock.onGet('foobar').networkError();
-
- new MiniPipelineGraph({ container: '.js-builds-dropdown-tests' }).bindEvents();
-
- document.querySelector('.js-builds-dropdown-button').click();
-
- setTimeout(() => {
- expect($('.js-builds-dropdown-tests .dropdown').hasClass('open')).toEqual(false);
- done();
- });
- });
- });
-});
diff --git a/spec/javascripts/pager_spec.js b/spec/javascripts/pager_spec.js
deleted file mode 100644
index c95a8400c6c..00000000000
--- a/spec/javascripts/pager_spec.js
+++ /dev/null
@@ -1,162 +0,0 @@
-import $ from 'jquery';
-import MockAdapter from 'axios-mock-adapter';
-import axios from '~/lib/utils/axios_utils';
-import Pager from '~/pager';
-
-describe('pager', () => {
- let axiosMock;
-
- beforeEach(() => {
- axiosMock = new MockAdapter(axios);
- });
-
- afterEach(() => {
- axiosMock.restore();
- });
-
- describe('init', () => {
- const originalHref = window.location.href;
-
- beforeEach(() => {
- setFixtures('<div class="content_list"></div><div class="loading"></div>');
- spyOn($.fn, 'endlessScroll').and.stub();
- });
-
- afterEach(() => {
- window.history.replaceState({}, null, originalHref);
- });
-
- it('should use data-href attribute from list element', () => {
- const href = `${gl.TEST_HOST}/some_list.json`;
- setFixtures(`<div class="content_list" data-href="${href}"></div>`);
- Pager.init();
-
- expect(Pager.url).toBe(href);
- });
-
- it('should use current url if data-href attribute not provided', () => {
- const href = `${gl.TEST_HOST}/some_list`;
- spyOnDependency(Pager, 'removeParams').and.returnValue(href);
- Pager.init();
-
- expect(Pager.url).toBe(href);
- });
-
- it('should get initial offset from query parameter', () => {
- window.history.replaceState({}, null, '?offset=100');
- Pager.init();
-
- expect(Pager.offset).toBe(100);
- });
-
- it('keeps extra query parameters from url', () => {
- window.history.replaceState({}, null, '?filter=test&offset=100');
- const href = `${gl.TEST_HOST}/some_list?filter=test`;
- const removeParams = spyOnDependency(Pager, 'removeParams').and.returnValue(href);
- Pager.init();
-
- expect(removeParams).toHaveBeenCalledWith(['limit', 'offset']);
- expect(Pager.url).toEqual(href);
- });
- });
-
- describe('getOld', () => {
- const urlRegex = /(.*)some_list(.*)$/;
-
- function mockSuccess(count = 0) {
- axiosMock.onGet(urlRegex).reply(200, {
- count,
- html: '',
- });
- }
-
- function mockError() {
- axiosMock.onGet(urlRegex).networkError();
- }
-
- beforeEach(() => {
- setFixtures(
- '<div class="content_list" data-href="/some_list"></div><div class="loading"></div>',
- );
- spyOn(axios, 'get').and.callThrough();
-
- Pager.init();
- });
-
- it('shows loader while loading next page', done => {
- mockSuccess();
-
- spyOn(Pager.loading, 'show');
- Pager.getOld();
-
- setTimeout(() => {
- expect(Pager.loading.show).toHaveBeenCalled();
-
- done();
- });
- });
-
- it('hides loader on success', done => {
- mockSuccess();
-
- spyOn(Pager.loading, 'hide');
- Pager.getOld();
-
- setTimeout(() => {
- expect(Pager.loading.hide).toHaveBeenCalled();
-
- done();
- });
- });
-
- it('hides loader on error', done => {
- mockError();
-
- spyOn(Pager.loading, 'hide');
- Pager.getOld();
-
- setTimeout(() => {
- expect(Pager.loading.hide).toHaveBeenCalled();
-
- done();
- });
- });
-
- it('sends request to url with offset and limit params', done => {
- Pager.offset = 100;
- Pager.limit = 20;
- Pager.getOld();
-
- setTimeout(() => {
- const [url, params] = axios.get.calls.argsFor(0);
-
- expect(params).toEqual({
- params: {
- limit: 20,
- offset: 100,
- },
- });
-
- expect(url).toBe('/some_list');
-
- done();
- });
- });
-
- it('disables if return count is less than limit', done => {
- Pager.offset = 0;
- Pager.limit = 20;
-
- mockSuccess(1);
- spyOn(Pager.loading, 'hide');
- Pager.getOld();
-
- setTimeout(() => {
- expect(Pager.loading.hide).toHaveBeenCalled();
- expect(Pager.disable).toBe(true);
-
- done();
- });
- });
- });
-});
diff --git a/spec/javascripts/pdf/index_spec.js b/spec/javascripts/pdf/index_spec.js
deleted file mode 100644
index 39cd4dacd70..00000000000
--- a/spec/javascripts/pdf/index_spec.js
+++ /dev/null
@@ -1,58 +0,0 @@
-import Vue from 'vue';
-
-import { FIXTURES_PATH } from 'spec/test_constants';
-import PDFLab from '~/pdf/index.vue';
-
-const pdf = `${FIXTURES_PATH}/blob/pdf/test.pdf`;
-
-const Component = Vue.extend(PDFLab);
-
-describe('PDF component', () => {
- let vm;
-
- const checkLoaded = done => {
- if (vm.loading) {
- setTimeout(() => {
- checkLoaded(done);
- }, 100);
- } else {
- done();
- }
- };
-
- describe('without PDF data', () => {
- beforeEach(done => {
- vm = new Component({
- propsData: {
- pdf: '',
- },
- });
-
- vm.$mount();
-
- checkLoaded(done);
- });
-
- it('does not render', () => {
- expect(vm.$el.tagName).toBeUndefined();
- });
- });
-
- describe('with PDF data', () => {
- beforeEach(done => {
- vm = new Component({
- propsData: {
- pdf,
- },
- });
-
- vm.$mount();
-
- checkLoaded(done);
- });
-
- it('renders pdf component', () => {
- expect(vm.$el.tagName).toBeDefined();
- });
- });
-});
diff --git a/spec/javascripts/pdf/page_spec.js b/spec/javascripts/pdf/page_spec.js
deleted file mode 100644
index cc2cc204ee3..00000000000
--- a/spec/javascripts/pdf/page_spec.js
+++ /dev/null
@@ -1,49 +0,0 @@
-import Vue from 'vue';
-import pdfjsLib from 'pdfjs-dist/webpack';
-
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import { FIXTURES_PATH } from 'spec/test_constants';
-import PageComponent from '~/pdf/page/index.vue';
-
-const testPDF = `${FIXTURES_PATH}/blob/pdf/test.pdf`;
-
-describe('Page component', () => {
- const Component = Vue.extend(PageComponent);
- let vm;
- let testPage;
-
- beforeEach(done => {
- pdfjsLib
- .getDocument(testPDF)
- .promise.then(pdf => pdf.getPage(1))
- .then(page => {
- testPage = page;
- })
- .then(done)
- .catch(done.fail);
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('renders the page when mounting', done => {
- const promise = Promise.resolve();
- spyOn(testPage, 'render').and.returnValue({ promise });
-
- vm = mountComponent(Component, {
- page: testPage,
- number: 1,
- });
-
- expect(vm.rendering).toBe(true);
-
- promise
- .then(() => {
- expect(testPage.render).toHaveBeenCalledWith(vm.renderContext);
- expect(vm.rendering).toBe(false);
- })
- .then(done)
- .catch(done.fail);
- });
-});
diff --git a/spec/javascripts/performance_bar/index_spec.js b/spec/javascripts/performance_bar/index_spec.js
deleted file mode 100644
index 3957edce9e0..00000000000
--- a/spec/javascripts/performance_bar/index_spec.js
+++ /dev/null
@@ -1,80 +0,0 @@
-import MockAdapter from 'axios-mock-adapter';
-import axios from '~/lib/utils/axios_utils';
-import '~/performance_bar/components/performance_bar_app.vue';
-import performanceBar from '~/performance_bar';
-import PerformanceBarService from '~/performance_bar/services/performance_bar_service';
-
-describe('performance bar wrapper', () => {
- let mock;
- let vm;
-
- beforeEach(() => {
- const peekWrapper = document.createElement('div');
-
- peekWrapper.setAttribute('id', 'js-peek');
- peekWrapper.setAttribute('data-env', 'development');
- peekWrapper.setAttribute('data-request-id', '123');
- peekWrapper.setAttribute('data-peek-url', '/-/peek/results');
- peekWrapper.setAttribute('data-profile-url', '?lineprofiler=true');
-
- document.body.appendChild(peekWrapper);
-
- mock = new MockAdapter(axios);
-
- mock.onGet('/-/peek/results').reply(
- 200,
- {
- data: {
- gc: {
- invokes: 0,
- invoke_time: '0.00',
- use_size: 0,
- total_size: 0,
- total_object: 0,
- gc_time: '0.00',
- },
- host: { hostname: 'web-01' },
- },
- },
- {},
- );
-
- vm = performanceBar({ container: '#js-peek' });
- });
-
- afterEach(() => {
- vm.$destroy();
- mock.restore();
- });
-
- describe('loadRequestDetails', () => {
- beforeEach(() => {
- spyOn(vm.store, 'addRequest').and.callThrough();
- });
-
- it('does nothing if the request cannot be tracked', () => {
- spyOn(vm.store, 'canTrackRequest').and.callFake(() => false);
-
- vm.loadRequestDetails('123', 'https://gitlab.com/');
-
- expect(vm.store.addRequest).not.toHaveBeenCalled();
- });
-
- it('adds the request immediately', () => {
- vm.loadRequestDetails('123', 'https://gitlab.com/');
-
- expect(vm.store.addRequest).toHaveBeenCalledWith('123', 'https://gitlab.com/');
- });
-
- it('makes an HTTP request for the request details', () => {
- spyOn(PerformanceBarService, 'fetchRequestDetails').and.callThrough();
-
- vm.loadRequestDetails('456', 'https://gitlab.com/');
-
- expect(PerformanceBarService.fetchRequestDetails).toHaveBeenCalledWith(
- '/-/peek/results',
- '456',
- );
- });
- });
-});
diff --git a/spec/javascripts/persistent_user_callout_spec.js b/spec/javascripts/persistent_user_callout_spec.js
deleted file mode 100644
index d4cb92cacfd..00000000000
--- a/spec/javascripts/persistent_user_callout_spec.js
+++ /dev/null
@@ -1,175 +0,0 @@
-import MockAdapter from 'axios-mock-adapter';
-import setTimeoutPromise from 'spec/helpers/set_timeout_promise_helper';
-import axios from '~/lib/utils/axios_utils';
-import PersistentUserCallout from '~/persistent_user_callout';
-
-describe('PersistentUserCallout', () => {
- const dismissEndpoint = '/dismiss';
- const featureName = 'feature';
-
- function createFixture() {
- const fixture = document.createElement('div');
- fixture.innerHTML = `
- <div
- class="container"
- data-dismiss-endpoint="${dismissEndpoint}"
- data-feature-id="${featureName}"
- >
- <button type="button" class="js-close"></button>
- </div>
- `;
-
- return fixture;
- }
-
- function createDeferredLinkFixture() {
- const fixture = document.createElement('div');
- fixture.innerHTML = `
- <div
- class="container"
- data-dismiss-endpoint="${dismissEndpoint}"
- data-feature-id="${featureName}"
- data-defer-links="true"
- >
- <button type="button" class="js-close"></button>
- <a href="/somewhere-pleasant" target="_blank" class="deferred-link">A link</a>
- <a href="/somewhere-else" target="_blank" class="normal-link">Another link</a>
- </div>
- `;
-
- return fixture;
- }
-
- describe('dismiss', () => {
- let button;
- let mockAxios;
- let persistentUserCallout;
-
- beforeEach(() => {
- const fixture = createFixture();
- const container = fixture.querySelector('.container');
- button = fixture.querySelector('.js-close');
- mockAxios = new MockAdapter(axios);
- persistentUserCallout = new PersistentUserCallout(container);
- spyOn(persistentUserCallout.container, 'remove');
- });
-
- afterEach(() => {
- mockAxios.restore();
- });
-
- it('POSTs endpoint and removes container when clicking close', done => {
- mockAxios.onPost(dismissEndpoint).replyOnce(200);
-
- button.click();
-
- setTimeoutPromise()
- .then(() => {
- expect(persistentUserCallout.container.remove).toHaveBeenCalled();
- expect(mockAxios.history.post[0].data).toBe(
- JSON.stringify({ feature_name: featureName }),
- );
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('invokes Flash when the dismiss request fails', done => {
- const Flash = spyOnDependency(PersistentUserCallout, 'Flash');
- mockAxios.onPost(dismissEndpoint).replyOnce(500);
-
- button.click();
-
- setTimeoutPromise()
- .then(() => {
- expect(persistentUserCallout.container.remove).not.toHaveBeenCalled();
- expect(Flash).toHaveBeenCalledWith(
- 'An error occurred while dismissing the alert. Refresh the page and try again.',
- );
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('deferred links', () => {
- let button;
- let deferredLink;
- let normalLink;
- let mockAxios;
- let persistentUserCallout;
- let windowSpy;
-
- beforeEach(() => {
- const fixture = createDeferredLinkFixture();
- const container = fixture.querySelector('.container');
- button = fixture.querySelector('.js-close');
- deferredLink = fixture.querySelector('.deferred-link');
- normalLink = fixture.querySelector('.normal-link');
- mockAxios = new MockAdapter(axios);
- persistentUserCallout = new PersistentUserCallout(container);
- spyOn(persistentUserCallout.container, 'remove');
- windowSpy = spyOn(window, 'open').and.callFake(() => {});
- });
-
- afterEach(() => {
- mockAxios.restore();
- });
-
- it('defers loading of a link until callout is dismissed', done => {
- const { href, target } = deferredLink;
- mockAxios.onPost(dismissEndpoint).replyOnce(200);
-
- deferredLink.click();
-
- setTimeoutPromise()
- .then(() => {
- expect(windowSpy).toHaveBeenCalledWith(href, target);
- expect(persistentUserCallout.container.remove).toHaveBeenCalled();
- expect(mockAxios.history.post[0].data).toBe(
- JSON.stringify({ feature_name: featureName }),
- );
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('does not dismiss callout on non-deferred links', done => {
- normalLink.click();
-
- setTimeoutPromise()
- .then(() => {
- expect(windowSpy).not.toHaveBeenCalled();
- expect(persistentUserCallout.container.remove).not.toHaveBeenCalled();
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('does not follow link when notification is closed', done => {
- mockAxios.onPost(dismissEndpoint).replyOnce(200);
-
- button.click();
-
- setTimeoutPromise()
- .then(() => {
- expect(windowSpy).not.toHaveBeenCalled();
- expect(persistentUserCallout.container.remove).toHaveBeenCalled();
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('factory', () => {
- it('returns an instance of PersistentUserCallout with the provided container property', () => {
- const fixture = createFixture();
-
- expect(PersistentUserCallout.factory(fixture) instanceof PersistentUserCallout).toBe(true);
- });
-
- it('returns undefined if container is falsey', () => {
- expect(PersistentUserCallout.factory()).toBe(undefined);
- });
- });
-});
diff --git a/spec/javascripts/releases/components/app_index_spec.js b/spec/javascripts/releases/components/app_index_spec.js
deleted file mode 100644
index 020937d07e5..00000000000
--- a/spec/javascripts/releases/components/app_index_spec.js
+++ /dev/null
@@ -1,184 +0,0 @@
-import { range as rge } from 'lodash';
-import Vue from 'vue';
-import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
-import app from '~/releases/components/app_index.vue';
-import createStore from '~/releases/stores';
-import listModule from '~/releases/stores/modules/list';
-import api from '~/api';
-import { resetStore } from '../stores/modules/list/helpers';
-import {
- pageInfoHeadersWithoutPagination,
- pageInfoHeadersWithPagination,
- release,
- releases,
-} from '../mock_data';
-import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
-import waitForPromises from 'spec/helpers/wait_for_promises';
-
-describe('Releases App ', () => {
- const Component = Vue.extend(app);
- let store;
- let vm;
- let releasesPagination;
-
- const props = {
- projectId: 'gitlab-ce',
- documentationPath: 'help/releases',
- illustrationPath: 'illustration/path',
- };
-
- beforeEach(() => {
- store = createStore({ modules: { list: listModule } });
- releasesPagination = rge(21).map(index => ({
- ...convertObjectPropsToCamelCase(release, { deep: true }),
- tagName: `${index}.00`,
- }));
- });
-
- afterEach(() => {
- resetStore(store);
- vm.$destroy();
- });
-
- describe('while loading', () => {
- beforeEach(() => {
- spyOn(api, 'releases').and.returnValue(Promise.resolve({ data: [], headers: {} }));
- vm = mountComponentWithStore(Component, { props, store });
- });
-
- it('renders loading icon', done => {
- expect(vm.$el.querySelector('.js-loading')).not.toBeNull();
- expect(vm.$el.querySelector('.js-empty-state')).toBeNull();
- expect(vm.$el.querySelector('.js-success-state')).toBeNull();
- expect(vm.$el.querySelector('.gl-pagination')).toBeNull();
-
- waitForPromises()
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('with successful request', () => {
- beforeEach(() => {
- spyOn(api, 'releases').and.returnValue(
- Promise.resolve({ data: releases, headers: pageInfoHeadersWithoutPagination }),
- );
- vm = mountComponentWithStore(Component, { props, store });
- });
-
- it('renders success state', done => {
- waitForPromises()
- .then(() => {
- expect(vm.$el.querySelector('.js-loading')).toBeNull();
- expect(vm.$el.querySelector('.js-empty-state')).toBeNull();
- expect(vm.$el.querySelector('.js-success-state')).not.toBeNull();
- expect(vm.$el.querySelector('.gl-pagination')).toBeNull();
-
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('with successful request and pagination', () => {
- beforeEach(() => {
- spyOn(api, 'releases').and.returnValue(
- Promise.resolve({ data: releasesPagination, headers: pageInfoHeadersWithPagination }),
- );
- vm = mountComponentWithStore(Component, { props, store });
- });
-
- it('renders success state', done => {
- waitForPromises()
- .then(() => {
- expect(vm.$el.querySelector('.js-loading')).toBeNull();
- expect(vm.$el.querySelector('.js-empty-state')).toBeNull();
- expect(vm.$el.querySelector('.js-success-state')).not.toBeNull();
- expect(vm.$el.querySelector('.gl-pagination')).not.toBeNull();
-
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('with empty request', () => {
- beforeEach(() => {
- spyOn(api, 'releases').and.returnValue(Promise.resolve({ data: [], headers: {} }));
- vm = mountComponentWithStore(Component, { props, store });
- });
-
- it('renders empty state', done => {
- waitForPromises()
- .then(() => {
- expect(vm.$el.querySelector('.js-loading')).toBeNull();
- expect(vm.$el.querySelector('.js-empty-state')).not.toBeNull();
- expect(vm.$el.querySelector('.js-success-state')).toBeNull();
- expect(vm.$el.querySelector('.gl-pagination')).toBeNull();
-
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('"New release" button', () => {
- const findNewReleaseButton = () => vm.$el.querySelector('.js-new-release-btn');
-
- beforeEach(() => {
- spyOn(api, 'releases').and.returnValue(Promise.resolve({ data: [], headers: {} }));
- });
-
- const factory = additionalProps => {
- vm = mountComponentWithStore(Component, {
- props: {
- ...props,
- ...additionalProps,
- },
- store,
- });
- };
-
- describe('when the user is allowed to create a new Release', () => {
- const newReleasePath = 'path/to/new/release';
-
- beforeEach(() => {
- factory({ newReleasePath });
- });
-
- it('renders the "New release" button', done => {
- waitForPromises()
- .then(() => {
- expect(findNewReleaseButton()).not.toBeNull();
-
- done();
- })
- .catch(done.fail);
- });
-
- it('renders the "New release" button with the correct href', done => {
- waitForPromises()
- .then(() => {
- expect(findNewReleaseButton().getAttribute('href')).toBe(newReleasePath);
-
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('when the user is not allowed to create a new Release', () => {
- beforeEach(() => factory());
-
- it('does not render the "New release" button', done => {
- waitForPromises()
- .then(() => {
- expect(findNewReleaseButton()).toBeNull();
-
- done();
- })
- .catch(done.fail);
- });
- });
- });
-});
diff --git a/spec/javascripts/releases/mock_data.js b/spec/javascripts/releases/mock_data.js
deleted file mode 100644
index 72875dff172..00000000000
--- a/spec/javascripts/releases/mock_data.js
+++ /dev/null
@@ -1,148 +0,0 @@
-export const pageInfoHeadersWithoutPagination = {
- 'X-NEXT-PAGE': '',
- 'X-PAGE': '1',
- 'X-PER-PAGE': '20',
- 'X-PREV-PAGE': '',
- 'X-TOTAL': '19',
- 'X-TOTAL-PAGES': '1',
-};
-
-export const pageInfoHeadersWithPagination = {
- 'X-NEXT-PAGE': '2',
- 'X-PAGE': '1',
- 'X-PER-PAGE': '20',
- 'X-PREV-PAGE': '',
- 'X-TOTAL': '21',
- 'X-TOTAL-PAGES': '2',
-};
-
-export const release = {
- name: 'Bionic Beaver',
- tag_name: '18.04',
- description: '## changelog\n\n* line 1\n* line2',
- description_html: '<div><h2>changelog</h2><ul><li>line1</li<li>line 2</li></ul></div>',
- author_name: 'Release bot',
- author_email: 'release-bot@example.com',
- created_at: '2012-05-28T05:00:00-07:00',
- commit: {
- id: '2695effb5807a22ff3d138d593fd856244e155e7',
- short_id: '2695effb',
- title: 'Initial commit',
- created_at: '2017-07-26T11:08:53.000+02:00',
- parent_ids: ['2a4b78934375d7f53875269ffd4f45fd83a84ebe'],
- message: 'Initial commit',
- author: {
- avatar_url: 'uploads/-/system/user/avatar/johndoe/avatar.png',
- id: 482476,
- name: 'John Doe',
- path: '/johndoe',
- state: 'active',
- status_tooltip_html: null,
- username: 'johndoe',
- web_url: 'https://gitlab.com/johndoe',
- },
- authored_date: '2012-05-28T04:42:42-07:00',
- committer_name: 'Jack Smith',
- committer_email: 'jack@example.com',
- committed_date: '2012-05-28T04:42:42-07:00',
- },
- assets: {
- count: 6,
- sources: [
- {
- format: 'zip',
- url: 'https://gitlab.com/gitlab-org/gitlab-foss/-/archive/v11.3.12/gitlab-ce-v11.3.12.zip',
- },
- {
- format: 'tar.gz',
- url:
- 'https://gitlab.com/gitlab-org/gitlab-foss/-/archive/v11.3.12/gitlab-ce-v11.3.12.tar.gz',
- },
- {
- format: 'tar.bz2',
- url:
- 'https://gitlab.com/gitlab-org/gitlab-foss/-/archive/v11.3.12/gitlab-ce-v11.3.12.tar.bz2',
- },
- {
- format: 'tar',
- url: 'https://gitlab.com/gitlab-org/gitlab-foss/-/archive/v11.3.12/gitlab-ce-v11.3.12.tar',
- },
- ],
- links: [
- {
- name: 'release-18.04.dmg',
- url: 'https://my-external-hosting.example.com/scrambled-url/',
- external: true,
- },
- {
- name: 'binary-linux-amd64',
- url:
- 'https://gitlab.com/gitlab-org/gitlab-foss/-/jobs/artifacts/v11.6.0-rc4/download?job=rspec-mysql+41%2F50',
- external: false,
- },
- ],
- },
-};
-
-export const releases = [
- release,
- {
- name: 'JoJos Bizarre Adventure',
- tag_name: '19.00',
- description: '## changelog\n\n* line 1\n* line2',
- description_html: '<div><h2>changelog</h2><ul><li>line1</li<li>line 2</li></ul></div>',
- author_name: 'Release bot',
- author_email: 'release-bot@example.com',
- created_at: '2012-05-28T05:00:00-07:00',
- commit: {
- id: '2695effb5807a22ff3d138d593fd856244e155e7',
- short_id: '2695effb',
- title: 'Initial commit',
- created_at: '2017-07-26T11:08:53.000+02:00',
- parent_ids: ['2a4b78934375d7f53875269ffd4f45fd83a84ebe'],
- message: 'Initial commit',
- author: {
- avatar_url: 'uploads/-/system/user/avatar/johndoe/avatar.png',
- id: 482476,
- name: 'John Doe',
- path: '/johndoe',
- state: 'active',
- status_tooltip_html: null,
- username: 'johndoe',
- web_url: 'https://gitlab.com/johndoe',
- },
- authored_date: '2012-05-28T04:42:42-07:00',
- committer_name: 'Jack Smith',
- committer_email: 'jack@example.com',
- committed_date: '2012-05-28T04:42:42-07:00',
- },
- assets: {
- count: 4,
- sources: [
- {
- format: 'tar.gz',
- url:
- 'https://gitlab.com/gitlab-org/gitlab-foss/-/archive/v11.3.12/gitlab-ce-v11.3.12.tar.gz',
- },
- {
- format: 'tar.bz2',
- url:
- 'https://gitlab.com/gitlab-org/gitlab-foss/-/archive/v11.3.12/gitlab-ce-v11.3.12.tar.bz2',
- },
- {
- format: 'tar',
- url:
- 'https://gitlab.com/gitlab-org/gitlab-foss/-/archive/v11.3.12/gitlab-ce-v11.3.12.tar',
- },
- ],
- links: [
- {
- name: 'binary-linux-amd64',
- url:
- 'https://gitlab.com/gitlab-org/gitlab-foss/-/jobs/artifacts/v11.6.0-rc4/download?job=rspec-mysql+41%2F50',
- external: false,
- },
- ],
- },
- },
-];
diff --git a/spec/javascripts/releases/stores/modules/list/actions_spec.js b/spec/javascripts/releases/stores/modules/list/actions_spec.js
deleted file mode 100644
index bf85e18997b..00000000000
--- a/spec/javascripts/releases/stores/modules/list/actions_spec.js
+++ /dev/null
@@ -1,131 +0,0 @@
-import testAction from 'spec/helpers/vuex_action_helper';
-import {
- requestReleases,
- fetchReleases,
- receiveReleasesSuccess,
- receiveReleasesError,
-} from '~/releases/stores/modules/list/actions';
-import state from '~/releases/stores/modules/list/state';
-import * as types from '~/releases/stores/modules/list/mutation_types';
-import api from '~/api';
-import { parseIntPagination, convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
-import { pageInfoHeadersWithoutPagination, releases as originalReleases } from '../../../mock_data';
-
-describe('Releases State actions', () => {
- let mockedState;
- let pageInfo;
- let releases;
-
- beforeEach(() => {
- mockedState = state();
- pageInfo = parseIntPagination(pageInfoHeadersWithoutPagination);
- releases = convertObjectPropsToCamelCase(originalReleases, { deep: true });
- });
-
- describe('requestReleases', () => {
- it('should commit REQUEST_RELEASES mutation', done => {
- testAction(requestReleases, null, mockedState, [{ type: types.REQUEST_RELEASES }], [], done);
- });
- });
-
- describe('fetchReleases', () => {
- describe('success', () => {
- it('dispatches requestReleases and receiveReleasesSuccess', done => {
- spyOn(api, 'releases').and.callFake((id, options) => {
- expect(id).toEqual(1);
- expect(options.page).toEqual('1');
- return Promise.resolve({ data: releases, headers: pageInfoHeadersWithoutPagination });
- });
-
- testAction(
- fetchReleases,
- { projectId: 1 },
- mockedState,
- [],
- [
- {
- type: 'requestReleases',
- },
- {
- payload: { data: releases, headers: pageInfoHeadersWithoutPagination },
- type: 'receiveReleasesSuccess',
- },
- ],
- done,
- );
- });
-
- it('dispatches requestReleases and receiveReleasesSuccess on page two', done => {
- spyOn(api, 'releases').and.callFake((_, options) => {
- expect(options.page).toEqual('2');
- return Promise.resolve({ data: releases, headers: pageInfoHeadersWithoutPagination });
- });
-
- testAction(
- fetchReleases,
- { page: '2', projectId: 1 },
- mockedState,
- [],
- [
- {
- type: 'requestReleases',
- },
- {
- payload: { data: releases, headers: pageInfoHeadersWithoutPagination },
- type: 'receiveReleasesSuccess',
- },
- ],
- done,
- );
- });
- });
-
- describe('error', () => {
- it('dispatches requestReleases and receiveReleasesError', done => {
- spyOn(api, 'releases').and.returnValue(Promise.reject());
-
- testAction(
- fetchReleases,
- { projectId: null },
- mockedState,
- [],
- [
- {
- type: 'requestReleases',
- },
- {
- type: 'receiveReleasesError',
- },
- ],
- done,
- );
- });
- });
- });
-
- describe('receiveReleasesSuccess', () => {
- it('should commit RECEIVE_RELEASES_SUCCESS mutation', done => {
- testAction(
- receiveReleasesSuccess,
- { data: releases, headers: pageInfoHeadersWithoutPagination },
- mockedState,
- [{ type: types.RECEIVE_RELEASES_SUCCESS, payload: { pageInfo, data: releases } }],
- [],
- done,
- );
- });
- });
-
- describe('receiveReleasesError', () => {
- it('should commit RECEIVE_RELEASES_ERROR mutation', done => {
- testAction(
- receiveReleasesError,
- null,
- mockedState,
- [{ type: types.RECEIVE_RELEASES_ERROR }],
- [],
- done,
- );
- });
- });
-});
diff --git a/spec/javascripts/right_sidebar_spec.js b/spec/javascripts/right_sidebar_spec.js
deleted file mode 100644
index 9565e3ce546..00000000000
--- a/spec/javascripts/right_sidebar_spec.js
+++ /dev/null
@@ -1,87 +0,0 @@
-import $ from 'jquery';
-import MockAdapter from 'axios-mock-adapter';
-import '~/commons/bootstrap';
-import axios from '~/lib/utils/axios_utils';
-import Sidebar from '~/right_sidebar';
-
-let $aside = null;
-let $toggle = null;
-let $icon = null;
-let $page = null;
-let $labelsIcon = null;
-
-const assertSidebarState = function(state) {
- const shouldBeExpanded = state === 'expanded';
- const shouldBeCollapsed = state === 'collapsed';
- expect($aside.hasClass('right-sidebar-expanded')).toBe(shouldBeExpanded);
- expect($page.hasClass('right-sidebar-expanded')).toBe(shouldBeExpanded);
- expect($icon.hasClass('fa-angle-double-right')).toBe(shouldBeExpanded);
- expect($aside.hasClass('right-sidebar-collapsed')).toBe(shouldBeCollapsed);
- expect($page.hasClass('right-sidebar-collapsed')).toBe(shouldBeCollapsed);
- expect($icon.hasClass('fa-angle-double-left')).toBe(shouldBeCollapsed);
-};
-
-describe('RightSidebar', function() {
- describe('fixture tests', () => {
- const fixtureName = 'issues/open-issue.html';
- preloadFixtures(fixtureName);
- loadJSONFixtures('todos/todos.json');
- let mock;
-
- beforeEach(function() {
- loadFixtures(fixtureName);
- mock = new MockAdapter(axios);
- new Sidebar(); // eslint-disable-line no-new
- $aside = $('.right-sidebar');
- $page = $('.layout-page');
- $icon = $aside.find('i');
- $toggle = $aside.find('.js-sidebar-toggle');
- $labelsIcon = $aside.find('.sidebar-collapsed-icon');
- });
-
- afterEach(() => {
- mock.restore();
- });
-
- it('should expand/collapse the sidebar when arrow is clicked', function() {
- assertSidebarState('expanded');
- $toggle.click();
- assertSidebarState('collapsed');
- $toggle.click();
- assertSidebarState('expanded');
- });
-
- it('should float over the page and when sidebar icons clicked', function() {
- $labelsIcon.click();
- assertSidebarState('expanded');
- });
-
- it('should collapse when the icon arrow clicked while it is floating on page', function() {
- $labelsIcon.click();
- assertSidebarState('expanded');
- $toggle.click();
- assertSidebarState('collapsed');
- });
-
- it('should broadcast todo:toggle event when add todo clicked', function(done) {
- const todos = getJSONFixture('todos/todos.json');
- mock.onPost(/(.*)\/todos$/).reply(200, todos);
-
- const todoToggleSpy = spyOnEvent(document, 'todo:toggle');
-
- $('.issuable-sidebar-header .js-issuable-todo').click();
-
- setTimeout(() => {
- expect(todoToggleSpy.calls.count()).toEqual(1);
-
- done();
- });
- });
-
- it('should not hide collapsed icons', () => {
- [].forEach.call(document.querySelectorAll('.sidebar-collapsed-icon'), el => {
- expect(el.querySelector('.fa, svg').classList.contains('hidden')).toBeFalsy();
- });
- });
- });
-});
diff --git a/spec/javascripts/search_autocomplete_spec.js b/spec/javascripts/search_autocomplete_spec.js
deleted file mode 100644
index 4f42d4880e8..00000000000
--- a/spec/javascripts/search_autocomplete_spec.js
+++ /dev/null
@@ -1,215 +0,0 @@
-/* eslint-disable no-unused-expressions, consistent-return, no-param-reassign, default-case, no-return-assign */
-
-import $ from 'jquery';
-import '~/gl_dropdown';
-import initSearchAutocomplete from '~/search_autocomplete';
-import '~/lib/utils/common_utils';
-
-describe('Search autocomplete dropdown', () => {
- let widget = null;
-
- const userName = 'root';
-
- const userId = 1;
-
- const dashboardIssuesPath = '/dashboard/issues';
-
- const dashboardMRsPath = '/dashboard/merge_requests';
-
- const projectIssuesPath = '/gitlab-org/gitlab-foss/issues';
-
- const projectMRsPath = '/gitlab-org/gitlab-foss/-/merge_requests';
-
- const groupIssuesPath = '/groups/gitlab-org/-/issues';
-
- const groupMRsPath = '/groups/gitlab-org/-/merge_requests';
-
- const projectName = 'GitLab Community Edition';
-
- const groupName = 'Gitlab Org';
-
- const removeBodyAttributes = function() {
- const $body = $('body');
-
- $body.removeAttr('data-page');
- $body.removeAttr('data-project');
- $body.removeAttr('data-group');
- };
-
- // Add required attributes to body before starting the test.
- // section would be dashboard|group|project
- const addBodyAttributes = function(section) {
- if (section == null) {
- section = 'dashboard';
- }
-
- const $body = $('body');
- removeBodyAttributes();
- switch (section) {
- case 'dashboard':
- return $body.attr('data-page', 'root:index');
- case 'group':
- $body.attr('data-page', 'groups:show');
- return $body.data('group', 'gitlab-org');
- case 'project':
- $body.attr('data-page', 'projects:show');
- return $body.data('project', 'gitlab-ce');
- }
- };
-
- const disableProjectIssues = function() {
- document.querySelector('.js-search-project-options').setAttribute('data-issues-disabled', true);
- };
-
- // Mock `gl` object in window for dashboard specific page. App code will need it.
- const mockDashboardOptions = function() {
- window.gl || (window.gl = {});
- return (window.gl.dashboardOptions = {
- issuesPath: dashboardIssuesPath,
- mrPath: dashboardMRsPath,
- });
- };
-
- // Mock `gl` object in window for project specific page. App code will need it.
- const mockProjectOptions = function() {
- window.gl || (window.gl = {});
- return (window.gl.projectOptions = {
- 'gitlab-ce': {
- issuesPath: projectIssuesPath,
- mrPath: projectMRsPath,
- projectName,
- },
- });
- };
-
- const mockGroupOptions = function() {
- window.gl || (window.gl = {});
- return (window.gl.groupOptions = {
- 'gitlab-org': {
- issuesPath: groupIssuesPath,
- mrPath: groupMRsPath,
- projectName: groupName,
- },
- });
- };
-
- const assertLinks = function(list, issuesPath, mrsPath) {
- if (issuesPath) {
- const issuesAssignedToMeLink = `a[href="${issuesPath}/?assignee_username=${userName}"]`;
- const issuesIHaveCreatedLink = `a[href="${issuesPath}/?author_username=${userName}"]`;
-
- expect(list.find(issuesAssignedToMeLink).length).toBe(1);
- expect(list.find(issuesAssignedToMeLink).text()).toBe('Issues assigned to me');
- expect(list.find(issuesIHaveCreatedLink).length).toBe(1);
- expect(list.find(issuesIHaveCreatedLink).text()).toBe("Issues I've created");
- }
- const mrsAssignedToMeLink = `a[href="${mrsPath}/?assignee_username=${userName}"]`;
- const mrsIHaveCreatedLink = `a[href="${mrsPath}/?author_username=${userName}"]`;
-
- expect(list.find(mrsAssignedToMeLink).length).toBe(1);
- expect(list.find(mrsAssignedToMeLink).text()).toBe('Merge requests assigned to me');
- expect(list.find(mrsIHaveCreatedLink).length).toBe(1);
- expect(list.find(mrsIHaveCreatedLink).text()).toBe("Merge requests I've created");
- };
-
- preloadFixtures('static/search_autocomplete.html');
- beforeEach(function() {
- loadFixtures('static/search_autocomplete.html');
-
- window.gon = {};
- window.gon.current_user_id = userId;
- window.gon.current_username = userName;
-
- return (widget = initSearchAutocomplete());
- });
-
- afterEach(function() {
- // Undo what we did to the shared <body>
- removeBodyAttributes();
- window.gon = {};
- });
-
- it('should show Dashboard specific dropdown menu', function() {
- addBodyAttributes();
- mockDashboardOptions();
- widget.searchInput.triggerHandler('focus');
- const list = widget.wrap.find('.dropdown-menu').find('ul');
- return assertLinks(list, dashboardIssuesPath, dashboardMRsPath);
- });
-
- it('should show Group specific dropdown menu', function() {
- addBodyAttributes('group');
- mockGroupOptions();
- widget.searchInput.triggerHandler('focus');
- const list = widget.wrap.find('.dropdown-menu').find('ul');
- return assertLinks(list, groupIssuesPath, groupMRsPath);
- });
-
- it('should show Project specific dropdown menu', function() {
- addBodyAttributes('project');
- mockProjectOptions();
- widget.searchInput.triggerHandler('focus');
- const list = widget.wrap.find('.dropdown-menu').find('ul');
- return assertLinks(list, projectIssuesPath, projectMRsPath);
- });
-
- it('should show only Project mergeRequest dropdown menu items when project issues are disabled', function() {
- addBodyAttributes('project');
- disableProjectIssues();
- mockProjectOptions();
- widget.searchInput.triggerHandler('focus');
- const list = widget.wrap.find('.dropdown-menu').find('ul');
- assertLinks(list, null, projectMRsPath);
- });
-
- it('should not show category related menu if there is text in the input', function() {
- addBodyAttributes('project');
- mockProjectOptions();
- widget.searchInput.val('help');
- widget.searchInput.triggerHandler('focus');
- const list = widget.wrap.find('.dropdown-menu').find('ul');
- const link = `a[href='${projectIssuesPath}/?assignee_username=${userName}']`;
-
- expect(list.find(link).length).toBe(0);
- });
-
- it('should not submit the search form when selecting an autocomplete row with the keyboard', function() {
- const ENTER = 13;
- const DOWN = 40;
- addBodyAttributes();
- mockDashboardOptions(true);
- const submitSpy = spyOnEvent('form', 'submit');
- widget.searchInput.triggerHandler('focus');
- widget.wrap.trigger($.Event('keydown', { which: DOWN }));
- const enterKeyEvent = $.Event('keydown', { which: ENTER });
- widget.searchInput.trigger(enterKeyEvent);
- // This does not currently catch failing behavior. For security reasons,
- // browsers will not trigger default behavior (form submit, in this
- // example) on JavaScript-created keypresses.
- expect(submitSpy).not.toHaveBeenTriggered();
- });
-
- describe('disableAutocomplete', function() {
- beforeEach(function() {
- widget.enableAutocomplete();
- });
-
- it('should close the Dropdown', function() {
- const toggleSpy = spyOn(widget.dropdownToggle, 'dropdown');
-
- widget.dropdown.addClass('show');
- widget.disableAutocomplete();
-
- expect(toggleSpy).toHaveBeenCalledWith('toggle');
- });
- });
-
- describe('enableAutocomplete', function() {
- it('should open the Dropdown', function() {
- const toggleSpy = spyOn(widget.dropdownToggle, 'dropdown');
- widget.enableAutocomplete();
-
- expect(toggleSpy).toHaveBeenCalledWith('toggle');
- });
- });
-});
diff --git a/spec/javascripts/shortcuts_spec.js b/spec/javascripts/shortcuts_spec.js
deleted file mode 100644
index df7012bb659..00000000000
--- a/spec/javascripts/shortcuts_spec.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import $ from 'jquery';
-import Shortcuts from '~/behaviors/shortcuts/shortcuts';
-
-describe('Shortcuts', () => {
- const fixtureName = 'snippets/show.html';
- const createEvent = (type, target) =>
- $.Event(type, {
- target,
- });
-
- preloadFixtures(fixtureName);
-
- describe('toggleMarkdownPreview', () => {
- beforeEach(() => {
- loadFixtures(fixtureName);
-
- spyOnEvent('.js-new-note-form .js-md-preview-button', 'focus');
- spyOnEvent('.edit-note .js-md-preview-button', 'focus');
-
- new Shortcuts(); // eslint-disable-line no-new
- });
-
- it('focuses preview button in form', () => {
- Shortcuts.toggleMarkdownPreview(
- createEvent('KeyboardEvent', document.querySelector('.js-new-note-form .js-note-text')),
- );
-
- expect('focus').toHaveBeenTriggeredOn('.js-new-note-form .js-md-preview-button');
- });
-
- it('focues preview button inside edit comment form', done => {
- document.querySelector('.js-note-edit').click();
-
- setTimeout(() => {
- Shortcuts.toggleMarkdownPreview(
- createEvent('KeyboardEvent', document.querySelector('.edit-note .js-note-text')),
- );
-
- expect('focus').not.toHaveBeenTriggeredOn('.js-new-note-form .js-md-preview-button');
- expect('focus').toHaveBeenTriggeredOn('.edit-note .js-md-preview-button');
-
- done();
- });
- });
- });
-});
diff --git a/spec/javascripts/signin_tabs_memoizer_spec.js b/spec/javascripts/signin_tabs_memoizer_spec.js
deleted file mode 100644
index 966ae55ce14..00000000000
--- a/spec/javascripts/signin_tabs_memoizer_spec.js
+++ /dev/null
@@ -1,216 +0,0 @@
-import AccessorUtilities from '~/lib/utils/accessor';
-import SigninTabsMemoizer from '~/pages/sessions/new/signin_tabs_memoizer';
-import trackData from '~/pages/sessions/new/index';
-import Tracking from '~/tracking';
-
-describe('SigninTabsMemoizer', () => {
- const fixtureTemplate = 'static/signin_tabs.html';
- const tabSelector = 'ul.new-session-tabs';
- const currentTabKey = 'current_signin_tab';
- let memo;
-
- function createMemoizer() {
- memo = new SigninTabsMemoizer({
- currentTabKey,
- tabSelector,
- });
- return memo;
- }
-
- preloadFixtures(fixtureTemplate);
-
- beforeEach(() => {
- loadFixtures(fixtureTemplate);
-
- spyOn(AccessorUtilities, 'isLocalStorageAccessSafe').and.returnValue(true);
- });
-
- it('does nothing if no tab was previously selected', () => {
- createMemoizer();
-
- expect(document.querySelector(`${tabSelector} > li.active a`).getAttribute('href')).toEqual(
- '#ldap',
- );
- });
-
- it('shows last selected tab on boot', () => {
- createMemoizer().saveData('#ldap');
- const fakeTab = {
- click: () => {},
- };
- spyOn(document, 'querySelector').and.returnValue(fakeTab);
- spyOn(fakeTab, 'click');
-
- memo.bootstrap();
-
- // verify that triggers click on the last selected tab
- expect(document.querySelector).toHaveBeenCalledWith(`${tabSelector} a[href="#ldap"]`);
- expect(fakeTab.click).toHaveBeenCalled();
- });
-
- it('clicks the first tab if value in local storage is bad', () => {
- createMemoizer().saveData('#bogus');
- const fakeTab = {
- click: () => {},
- };
- spyOn(document, 'querySelector').and.callFake(selector =>
- selector === `${tabSelector} a[href="#bogus"]` ? null : fakeTab,
- );
- spyOn(fakeTab, 'click');
-
- memo.bootstrap();
-
- // verify that triggers click on stored selector and fallback
- expect(document.querySelector.calls.allArgs()).toEqual([
- ['ul.new-session-tabs a[href="#bogus"]'],
- ['ul.new-session-tabs a'],
- ]);
-
- expect(fakeTab.click).toHaveBeenCalled();
- });
-
- it('saves last selected tab on change', () => {
- createMemoizer();
-
- document.querySelector('a[href="#login-pane"]').click();
-
- expect(memo.readData()).toEqual('#login-pane');
- });
-
- it('overrides last selected tab with hash tag when given', () => {
- window.location.hash = '#ldap';
- createMemoizer();
-
- expect(memo.readData()).toEqual('#ldap');
- });
-
- describe('class constructor', () => {
- beforeEach(() => {
- memo = createMemoizer();
- });
-
- it('should set .isLocalStorageAvailable', () => {
- expect(AccessorUtilities.isLocalStorageAccessSafe).toHaveBeenCalled();
- expect(memo.isLocalStorageAvailable).toBe(true);
- });
- });
-
- describe('trackData', () => {
- beforeEach(() => {
- spyOn(Tracking, 'event');
- });
-
- describe('with tracking data', () => {
- beforeEach(() => {
- gon.tracking_data = {
- category: 'Growth::Acquisition::Experiment::SignUpFlow',
- action: 'start',
- label: 'uuid',
- property: 'control_group',
- };
- trackData();
- });
-
- it('should track data when the "click" event of the register tab is triggered', () => {
- document.querySelector('a[href="#register-pane"]').click();
-
- expect(Tracking.event).toHaveBeenCalledWith(
- 'Growth::Acquisition::Experiment::SignUpFlow',
- 'start',
- {
- label: 'uuid',
- property: 'control_group',
- },
- );
- });
- });
-
- describe('without tracking data', () => {
- beforeEach(() => {
- gon.tracking_data = undefined;
- trackData();
- });
-
- it('should not track data when the "click" event of the register tab is triggered', () => {
- document.querySelector('a[href="#register-pane"]').click();
-
- expect(Tracking.event).not.toHaveBeenCalled();
- });
- });
- });
-
- describe('saveData', () => {
- beforeEach(() => {
- memo = {
- currentTabKey,
- };
-
- spyOn(localStorage, 'setItem');
- });
-
- describe('if .isLocalStorageAvailable is `false`', () => {
- beforeEach(function() {
- memo.isLocalStorageAvailable = false;
-
- SigninTabsMemoizer.prototype.saveData.call(memo);
- });
-
- it('should not call .setItem', () => {
- expect(localStorage.setItem).not.toHaveBeenCalled();
- });
- });
-
- describe('if .isLocalStorageAvailable is `true`', () => {
- const value = 'value';
-
- beforeEach(function() {
- memo.isLocalStorageAvailable = true;
-
- SigninTabsMemoizer.prototype.saveData.call(memo, value);
- });
-
- it('should call .setItem', () => {
- expect(localStorage.setItem).toHaveBeenCalledWith(currentTabKey, value);
- });
- });
- });
-
- describe('readData', () => {
- const itemValue = 'itemValue';
- let readData;
-
- beforeEach(() => {
- memo = {
- currentTabKey,
- };
-
- spyOn(localStorage, 'getItem').and.returnValue(itemValue);
- });
-
- describe('if .isLocalStorageAvailable is `false`', () => {
- beforeEach(function() {
- memo.isLocalStorageAvailable = false;
-
- readData = SigninTabsMemoizer.prototype.readData.call(memo);
- });
-
- it('should not call .getItem and should return `null`', () => {
- expect(localStorage.getItem).not.toHaveBeenCalled();
- expect(readData).toBe(null);
- });
- });
-
- describe('if .isLocalStorageAvailable is `true`', () => {
- beforeEach(function() {
- memo.isLocalStorageAvailable = true;
-
- readData = SigninTabsMemoizer.prototype.readData.call(memo);
- });
-
- it('should call .getItem and return the localStorage value', () => {
- expect(window.localStorage.getItem).toHaveBeenCalledWith(currentTabKey);
- expect(readData).toBe(itemValue);
- });
- });
- });
-});
diff --git a/spec/javascripts/todos_spec.js b/spec/javascripts/todos_spec.js
deleted file mode 100644
index dc3c547c632..00000000000
--- a/spec/javascripts/todos_spec.js
+++ /dev/null
@@ -1,108 +0,0 @@
-import $ from 'jquery';
-import MockAdapter from 'axios-mock-adapter';
-import Todos from '~/pages/dashboard/todos/index/todos';
-import '~/lib/utils/common_utils';
-import '~/gl_dropdown';
-import axios from '~/lib/utils/axios_utils';
-import { addDelimiter } from '~/lib/utils/text_utility';
-
-const TEST_COUNT_BIG = 2000;
-const TEST_DONE_COUNT_BIG = 7300;
-
-describe('Todos', () => {
- preloadFixtures('todos/todos.html');
- let todoItem;
- let mock;
-
- beforeEach(() => {
- loadFixtures('todos/todos.html');
- todoItem = document.querySelector('.todos-list .todo');
- mock = new MockAdapter(axios);
-
- return new Todos();
- });
-
- afterEach(() => {
- mock.restore();
- });
-
- describe('goToTodoUrl', () => {
- it('opens the todo url', done => {
- const todoLink = todoItem.dataset.url;
-
- spyOnDependency(Todos, 'visitUrl').and.callFake(url => {
- expect(url).toEqual(todoLink);
- done();
- });
-
- todoItem.click();
- });
-
- describe('meta click', () => {
- let visitUrlSpy;
- let windowOpenSpy;
- let metakeyEvent;
-
- beforeEach(() => {
- metakeyEvent = $.Event('click', { keyCode: 91, ctrlKey: true });
- visitUrlSpy = spyOnDependency(Todos, 'visitUrl').and.callFake(() => {});
- windowOpenSpy = spyOn(window, 'open').and.callFake(() => {});
- });
-
- it('opens the todo url in another tab', () => {
- const todoLink = todoItem.dataset.url;
-
- $('.todos-list .todo').trigger(metakeyEvent);
-
- expect(visitUrlSpy).not.toHaveBeenCalled();
- expect(windowOpenSpy).toHaveBeenCalledWith(todoLink, '_blank');
- });
-
- it('run native funcionality when avatar is clicked', () => {
- $('.todos-list a').on('click', e => e.preventDefault());
- $('.todos-list img').trigger(metakeyEvent);
-
- expect(visitUrlSpy).not.toHaveBeenCalled();
- expect(windowOpenSpy).not.toHaveBeenCalled();
- });
- });
-
- describe('on done todo click', () => {
- let onToggleSpy;
-
- beforeEach(done => {
- const el = document.querySelector('.js-done-todo');
- const path = el.dataset.href;
-
- // Arrange
- mock
- .onDelete(path)
- .replyOnce(200, { count: TEST_COUNT_BIG, done_count: TEST_DONE_COUNT_BIG });
- onToggleSpy = jasmine.createSpy('onToggle');
- $(document).on('todo:toggle', onToggleSpy);
-
- // Act
- el.click();
-
- // Wait for axios and HTML to udpate
- setImmediate(done);
- });
-
- it('dispatches todo:toggle', () => {
- expect(onToggleSpy).toHaveBeenCalledWith(jasmine.anything(), TEST_COUNT_BIG);
- });
-
- it('updates pending text', () => {
- expect(document.querySelector('.todos-pending .badge').innerHTML).toEqual(
- addDelimiter(TEST_COUNT_BIG),
- );
- });
-
- it('updates done text', () => {
- expect(document.querySelector('.todos-done .badge').innerHTML).toEqual(
- addDelimiter(TEST_DONE_COUNT_BIG),
- );
- });
- });
- });
-});
diff --git a/spec/javascripts/toggle_buttons_spec.js b/spec/javascripts/toggle_buttons_spec.js
deleted file mode 100644
index 09756ff76ec..00000000000
--- a/spec/javascripts/toggle_buttons_spec.js
+++ /dev/null
@@ -1,127 +0,0 @@
-import $ from 'jquery';
-import setupToggleButtons from '~/toggle_buttons';
-import getSetTimeoutPromise from './helpers/set_timeout_promise_helper';
-
-function generateMarkup(isChecked = true) {
- return `
- <button type="button" class="${isChecked ? 'is-checked' : ''} js-project-feature-toggle">
- <input type="hidden" class="js-project-feature-toggle-input" value="${isChecked}" />
- </button>
- `;
-}
-
-function setupFixture(isChecked, clickCallback) {
- const wrapper = document.createElement('div');
- wrapper.innerHTML = generateMarkup(isChecked);
-
- setupToggleButtons(wrapper, clickCallback);
-
- return wrapper;
-}
-
-describe('ToggleButtons', () => {
- describe('when input value is true', () => {
- it('should initialize as checked', () => {
- const wrapper = setupFixture(true);
-
- expect(
- wrapper.querySelector('.js-project-feature-toggle').classList.contains('is-checked'),
- ).toEqual(true);
-
- expect(wrapper.querySelector('.js-project-feature-toggle-input').value).toEqual('true');
- });
-
- it('should toggle to unchecked when clicked', done => {
- const wrapper = setupFixture(true);
- const toggleButton = wrapper.querySelector('.js-project-feature-toggle');
-
- toggleButton.click();
-
- getSetTimeoutPromise()
- .then(() => {
- expect(toggleButton.classList.contains('is-checked')).toEqual(false);
- expect(wrapper.querySelector('.js-project-feature-toggle-input').value).toEqual('false');
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('when input value is false', () => {
- it('should initialize as unchecked', () => {
- const wrapper = setupFixture(false);
-
- expect(
- wrapper.querySelector('.js-project-feature-toggle').classList.contains('is-checked'),
- ).toEqual(false);
-
- expect(wrapper.querySelector('.js-project-feature-toggle-input').value).toEqual('false');
- });
-
- it('should toggle to checked when clicked', done => {
- const wrapper = setupFixture(false);
- const toggleButton = wrapper.querySelector('.js-project-feature-toggle');
-
- toggleButton.click();
-
- getSetTimeoutPromise()
- .then(() => {
- expect(toggleButton.classList.contains('is-checked')).toEqual(true);
- expect(wrapper.querySelector('.js-project-feature-toggle-input').value).toEqual('true');
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- it('should emit `trigger-change` event', done => {
- const changeSpy = jasmine.createSpy('changeEventHandler');
- const wrapper = setupFixture(false);
- const toggleButton = wrapper.querySelector('.js-project-feature-toggle');
- const input = wrapper.querySelector('.js-project-feature-toggle-input');
-
- $(input).on('trigger-change', changeSpy);
-
- toggleButton.click();
-
- getSetTimeoutPromise()
- .then(() => {
- expect(changeSpy).toHaveBeenCalled();
- })
- .then(done)
- .catch(done.fail);
- });
-
- describe('clickCallback', () => {
- it('should show loading indicator while waiting', done => {
- const isChecked = true;
- const clickCallback = (newValue, toggleButton) => {
- const input = toggleButton.querySelector('.js-project-feature-toggle-input');
-
- expect(newValue).toEqual(false);
-
- // Check for the loading state
- expect(toggleButton.classList.contains('is-checked')).toEqual(false);
- expect(toggleButton.classList.contains('is-loading')).toEqual(true);
- expect(toggleButton.disabled).toEqual(true);
- expect(input.value).toEqual('true');
-
- // After the callback finishes, check that the loading state is gone
- getSetTimeoutPromise()
- .then(() => {
- expect(toggleButton.classList.contains('is-checked')).toEqual(false);
- expect(toggleButton.classList.contains('is-loading')).toEqual(false);
- expect(toggleButton.disabled).toEqual(false);
- expect(input.value).toEqual('false');
- })
- .then(done)
- .catch(done.fail);
- };
-
- const wrapper = setupFixture(isChecked, clickCallback);
- const toggleButton = wrapper.querySelector('.js-project-feature-toggle');
-
- toggleButton.click();
- });
- });
-});
diff --git a/spec/javascripts/user_popovers_spec.js b/spec/javascripts/user_popovers_spec.js
deleted file mode 100644
index 6ac22fca2d3..00000000000
--- a/spec/javascripts/user_popovers_spec.js
+++ /dev/null
@@ -1,95 +0,0 @@
-import initUserPopovers from '~/user_popovers';
-import UsersCache from '~/lib/utils/users_cache';
-
-describe('User Popovers', () => {
- const fixtureTemplate = 'merge_requests/merge_request_with_mentions.html';
- preloadFixtures(fixtureTemplate);
-
- const selector = '.js-user-link, .gfm-project_member';
-
- const dummyUser = { name: 'root' };
- const dummyUserStatus = { message: 'active' };
-
- let popovers;
-
- const triggerEvent = (eventName, el) => {
- const event = new MouseEvent(eventName, {
- bubbles: true,
- cancelable: true,
- view: window,
- });
-
- el.dispatchEvent(event);
- };
-
- beforeEach(() => {
- loadFixtures(fixtureTemplate);
-
- const usersCacheSpy = () => Promise.resolve(dummyUser);
- spyOn(UsersCache, 'retrieveById').and.callFake(userId => usersCacheSpy(userId));
-
- const userStatusCacheSpy = () => Promise.resolve(dummyUserStatus);
- spyOn(UsersCache, 'retrieveStatusById').and.callFake(userId => userStatusCacheSpy(userId));
-
- popovers = initUserPopovers(document.querySelectorAll(selector));
- });
-
- it('initializes a popover for each user link with a user id', () => {
- const linksWithUsers = Array.from(document.querySelectorAll(selector)).filter(
- ({ dataset }) => dataset.user || dataset.userId,
- );
-
- expect(linksWithUsers.length).toBe(popovers.length);
- });
-
- it('does not initialize the user popovers twice for the same element', () => {
- const newPopovers = initUserPopovers(document.querySelectorAll(selector));
- const samePopovers = popovers.every((popover, index) => newPopovers[index] === popover);
-
- expect(samePopovers).toBe(true);
- });
-
- describe('when user link emits mouseenter event', () => {
- let userLink;
-
- beforeEach(() => {
- userLink = document.querySelector(selector);
-
- triggerEvent('mouseenter', userLink);
- });
-
- it('removes title attribute from user links', () => {
- expect(userLink.getAttribute('title')).toBeFalsy();
- expect(userLink.dataset.originalTitle).toBeFalsy();
- });
-
- it('populates popovers with preloaded user data', () => {
- const { name, userId, username } = userLink.dataset;
- const [firstPopover] = popovers;
-
- expect(firstPopover.$props.user).toEqual(
- jasmine.objectContaining({
- name,
- userId,
- username,
- }),
- );
- });
-
- it('fetches user info and status from the user cache', () => {
- const { userId } = userLink.dataset;
-
- expect(UsersCache.retrieveById).toHaveBeenCalledWith(userId);
- expect(UsersCache.retrieveStatusById).toHaveBeenCalledWith(userId);
- });
- });
-
- it('removes aria-describedby attribute from the user link on mouseleave', () => {
- const userLink = document.querySelector(selector);
-
- userLink.setAttribute('aria-describedby', 'popover');
- triggerEvent('mouseleave', userLink);
-
- expect(userLink.getAttribute('aria-describedby')).toBe(null);
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_author_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_author_spec.js
deleted file mode 100644
index a942a9dec87..00000000000
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_author_spec.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import MrWidgetAuthor from '~/vue_merge_request_widget/components/mr_widget_author.vue';
-
-describe('MrWidgetAuthor', () => {
- let vm;
-
- beforeEach(() => {
- const Component = Vue.extend(MrWidgetAuthor);
-
- vm = mountComponent(Component, {
- author: {
- name: 'Administrator',
- username: 'root',
- webUrl: 'http://localhost:3000/root',
- avatarUrl:
- 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- },
- });
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('renders link with the author web url', () => {
- expect(vm.$el.getAttribute('href')).toEqual('http://localhost:3000/root');
- });
-
- it('renders image with avatar url', () => {
- expect(vm.$el.querySelector('img').getAttribute('src')).toEqual(
- 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- );
- });
-
- it('renders author name', () => {
- expect(vm.$el.textContent.trim()).toEqual('Administrator');
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_author_time_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_author_time_spec.js
deleted file mode 100644
index 55af2baa924..00000000000
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_author_time_spec.js
+++ /dev/null
@@ -1,44 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import MrWidgetAuthorTime from '~/vue_merge_request_widget/components/mr_widget_author_time.vue';
-
-describe('MrWidgetAuthorTime', () => {
- let vm;
-
- beforeEach(() => {
- const Component = Vue.extend(MrWidgetAuthorTime);
-
- vm = mountComponent(Component, {
- actionText: 'Merged by',
- author: {
- name: 'Administrator',
- username: 'root',
- webUrl: 'http://localhost:3000/root',
- avatarUrl:
- 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- },
- dateTitle: '2017-03-23T23:02:00.807Z',
- dateReadable: '12 hours ago',
- });
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('renders provided action text', () => {
- expect(vm.$el.textContent).toContain('Merged by');
- });
-
- it('renders author', () => {
- expect(vm.$el.textContent).toContain('Administrator');
- });
-
- it('renders provided time', () => {
- expect(vm.$el.querySelector('time').getAttribute('data-original-title')).toEqual(
- '2017-03-23T23:02:00.807Z',
- );
-
- expect(vm.$el.querySelector('time').textContent.trim()).toEqual('12 hours ago');
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_header_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_header_spec.js
deleted file mode 100644
index 3cbaa47c832..00000000000
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_header_spec.js
+++ /dev/null
@@ -1,313 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import headerComponent from '~/vue_merge_request_widget/components/mr_widget_header.vue';
-
-describe('MRWidgetHeader', () => {
- let vm;
- let Component;
-
- beforeEach(() => {
- Component = Vue.extend(headerComponent);
- });
-
- afterEach(() => {
- vm.$destroy();
- gon.relative_url_root = '';
- });
-
- const expectDownloadDropdownItems = () => {
- const downloadEmailPatchesEl = vm.$el.querySelector('.js-download-email-patches');
- const downloadPlainDiffEl = vm.$el.querySelector('.js-download-plain-diff');
-
- expect(downloadEmailPatchesEl.textContent.trim()).toEqual('Email patches');
- expect(downloadEmailPatchesEl.getAttribute('href')).toEqual('/mr/email-patches');
- expect(downloadPlainDiffEl.textContent.trim()).toEqual('Plain diff');
- expect(downloadPlainDiffEl.getAttribute('href')).toEqual('/mr/plainDiffPath');
- };
-
- describe('computed', () => {
- describe('shouldShowCommitsBehindText', () => {
- it('return true when there are divergedCommitsCount', () => {
- vm = mountComponent(Component, {
- mr: {
- divergedCommitsCount: 12,
- sourceBranch: 'mr-widget-refactor',
- sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">Link</a>',
- targetBranch: 'master',
- statusPath: 'abc',
- },
- });
-
- expect(vm.shouldShowCommitsBehindText).toEqual(true);
- });
-
- it('returns false where there are no divergedComits count', () => {
- vm = mountComponent(Component, {
- mr: {
- divergedCommitsCount: 0,
- sourceBranch: 'mr-widget-refactor',
- sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">Link</a>',
- targetBranch: 'master',
- statusPath: 'abc',
- },
- });
-
- expect(vm.shouldShowCommitsBehindText).toEqual(false);
- });
- });
-
- describe('commitsBehindText', () => {
- it('returns singular when there is one commit', () => {
- vm = mountComponent(Component, {
- mr: {
- divergedCommitsCount: 1,
- sourceBranch: 'mr-widget-refactor',
- sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">Link</a>',
- targetBranch: 'master',
- targetBranchPath: '/foo/bar/master',
- statusPath: 'abc',
- },
- });
-
- expect(vm.commitsBehindText).toEqual(
- 'The source branch is <a href="/foo/bar/master">1 commit behind</a> the target branch',
- );
- });
-
- it('returns plural when there is more than one commit', () => {
- vm = mountComponent(Component, {
- mr: {
- divergedCommitsCount: 2,
- sourceBranch: 'mr-widget-refactor',
- sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">Link</a>',
- targetBranch: 'master',
- targetBranchPath: '/foo/bar/master',
- statusPath: 'abc',
- },
- });
-
- expect(vm.commitsBehindText).toEqual(
- 'The source branch is <a href="/foo/bar/master">2 commits behind</a> the target branch',
- );
- });
- });
- });
-
- describe('template', () => {
- describe('common elements', () => {
- beforeEach(() => {
- vm = mountComponent(Component, {
- mr: {
- divergedCommitsCount: 12,
- sourceBranch: 'mr-widget-refactor',
- sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">mr-widget-refactor</a>',
- sourceBranchRemoved: false,
- targetBranchPath: 'foo/bar/commits-path',
- targetBranchTreePath: 'foo/bar/tree/path',
- targetBranch: 'master',
- isOpen: true,
- emailPatchesPath: '/mr/email-patches',
- plainDiffPath: '/mr/plainDiffPath',
- statusPath: 'abc',
- },
- });
- });
-
- it('renders source branch link', () => {
- expect(vm.$el.querySelector('.js-source-branch').innerHTML).toEqual(
- '<a href="/foo/bar/mr-widget-refactor">mr-widget-refactor</a>',
- );
- });
-
- it('renders clipboard button', () => {
- expect(vm.$el.querySelector('.btn-clipboard')).not.toEqual(null);
- });
-
- it('renders target branch', () => {
- expect(vm.$el.querySelector('.js-target-branch').textContent.trim()).toEqual('master');
- });
- });
-
- describe('with an open merge request', () => {
- const mrDefaultOptions = {
- iid: 1,
- divergedCommitsCount: 12,
- sourceBranch: 'mr-widget-refactor',
- sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">mr-widget-refactor</a>',
- sourceBranchRemoved: false,
- targetBranchPath: 'foo/bar/commits-path',
- targetBranchTreePath: 'foo/bar/tree/path',
- targetBranch: 'master',
- isOpen: true,
- canPushToSourceBranch: true,
- emailPatchesPath: '/mr/email-patches',
- plainDiffPath: '/mr/plainDiffPath',
- statusPath: 'abc',
- sourceProjectFullPath: 'root/gitlab-ce',
- targetProjectFullPath: 'gitlab-org/gitlab-ce',
- };
-
- afterEach(() => {
- vm.$destroy();
- });
-
- beforeEach(() => {
- vm = mountComponent(Component, {
- mr: { ...mrDefaultOptions },
- });
- });
-
- it('renders checkout branch button with modal trigger', () => {
- const button = vm.$el.querySelector('.js-check-out-branch');
-
- expect(button.textContent.trim()).toEqual('Check out branch');
- expect(button.getAttribute('data-target')).toEqual('#modal_merge_info');
- expect(button.getAttribute('data-toggle')).toEqual('modal');
- });
-
- it('renders web ide button', () => {
- const button = vm.$el.querySelector('.js-web-ide');
-
- expect(button.textContent.trim()).toEqual('Open in Web IDE');
- expect(button.classList.contains('disabled')).toBe(false);
- expect(button.getAttribute('href')).toEqual(
- '/-/ide/project/root/gitlab-ce/merge_requests/1?target_project=gitlab-org%2Fgitlab-ce',
- );
- });
-
- it('renders web ide button in disabled state with no href', () => {
- const mr = { ...mrDefaultOptions, canPushToSourceBranch: false };
- vm = mountComponent(Component, { mr });
-
- const link = vm.$el.querySelector('.js-web-ide');
-
- expect(link.classList.contains('disabled')).toBe(true);
- expect(link.getAttribute('href')).toBeNull();
- });
-
- it('renders web ide button with blank query string if target & source project branch', done => {
- vm.mr.targetProjectFullPath = 'root/gitlab-ce';
-
- vm.$nextTick(() => {
- const button = vm.$el.querySelector('.js-web-ide');
-
- expect(button.textContent.trim()).toEqual('Open in Web IDE');
- expect(button.getAttribute('href')).toEqual(
- '/-/ide/project/root/gitlab-ce/merge_requests/1?target_project=',
- );
-
- done();
- });
- });
-
- it('renders web ide button with relative URL', done => {
- gon.relative_url_root = '/gitlab';
- vm.mr.iid = 2;
-
- vm.$nextTick(() => {
- const button = vm.$el.querySelector('.js-web-ide');
-
- expect(button.textContent.trim()).toEqual('Open in Web IDE');
- expect(button.getAttribute('href')).toEqual(
- '/gitlab/-/ide/project/root/gitlab-ce/merge_requests/2?target_project=gitlab-org%2Fgitlab-ce',
- );
-
- done();
- });
- });
-
- it('renders download dropdown with links', () => {
- expectDownloadDropdownItems();
- });
- });
-
- describe('with a closed merge request', () => {
- beforeEach(() => {
- vm = mountComponent(Component, {
- mr: {
- divergedCommitsCount: 12,
- sourceBranch: 'mr-widget-refactor',
- sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">mr-widget-refactor</a>',
- sourceBranchRemoved: false,
- targetBranchPath: 'foo/bar/commits-path',
- targetBranchTreePath: 'foo/bar/tree/path',
- targetBranch: 'master',
- isOpen: false,
- emailPatchesPath: '/mr/email-patches',
- plainDiffPath: '/mr/plainDiffPath',
- statusPath: 'abc',
- },
- });
- });
-
- it('does not render checkout branch button with modal trigger', () => {
- const button = vm.$el.querySelector('.js-check-out-branch');
-
- expect(button).toEqual(null);
- });
-
- it('renders download dropdown with links', () => {
- expectDownloadDropdownItems();
- });
- });
-
- describe('without diverged commits', () => {
- beforeEach(() => {
- vm = mountComponent(Component, {
- mr: {
- divergedCommitsCount: 0,
- sourceBranch: 'mr-widget-refactor',
- sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">mr-widget-refactor</a>',
- sourceBranchRemoved: false,
- targetBranchPath: 'foo/bar/commits-path',
- targetBranchTreePath: 'foo/bar/tree/path',
- targetBranch: 'master',
- isOpen: true,
- emailPatchesPath: '/mr/email-patches',
- plainDiffPath: '/mr/plainDiffPath',
- statusPath: 'abc',
- },
- });
- });
-
- it('does not render diverged commits info', () => {
- expect(vm.$el.querySelector('.diverged-commits-count')).toEqual(null);
- });
- });
-
- describe('with diverged commits', () => {
- beforeEach(() => {
- vm = mountComponent(Component, {
- mr: {
- divergedCommitsCount: 12,
- sourceBranch: 'mr-widget-refactor',
- sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">mr-widget-refactor</a>',
- sourceBranchRemoved: false,
- targetBranchPath: 'foo/bar/commits-path',
- targetBranchTreePath: 'foo/bar/tree/path',
- targetBranch: 'master',
- isOpen: true,
- emailPatchesPath: '/mr/email-patches',
- plainDiffPath: '/mr/plainDiffPath',
- statusPath: 'abc',
- },
- });
- });
-
- it('renders diverged commits info', () => {
- expect(vm.$el.querySelector('.diverged-commits-count').textContent).toEqual(
- 'The source branch is 12 commits behind the target branch',
- );
-
- expect(vm.$el.querySelector('.diverged-commits-count a').textContent).toEqual(
- '12 commits behind',
- );
-
- expect(vm.$el.querySelector('.diverged-commits-count a')).toHaveAttr(
- 'href',
- vm.mr.targetBranchPath,
- );
- });
- });
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js
deleted file mode 100644
index d15c3552b4a..00000000000
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js
+++ /dev/null
@@ -1,223 +0,0 @@
-import Vue from 'vue';
-import MemoryUsage from '~/vue_merge_request_widget/components/deployment/memory_usage.vue';
-import MRWidgetService from '~/vue_merge_request_widget/services/mr_widget_service';
-
-const url = '/root/acets-review-apps/environments/15/deployments/1/metrics';
-const monitoringUrl = '/root/acets-review-apps/environments/15/metrics';
-
-const metricsMockData = {
- success: true,
- metrics: {
- memory_before: [
- {
- metric: {},
- value: [1495785220.607, '9572875.906976745'],
- },
- ],
- memory_after: [
- {
- metric: {},
- value: [1495787020.607, '4485853.130206379'],
- },
- ],
- memory_values: [
- {
- metric: {},
- values: [[1493716685, '4.30859375']],
- },
- ],
- },
- last_update: '2017-05-02T12:34:49.628Z',
- deployment_time: 1493718485,
-};
-
-const createComponent = () => {
- const Component = Vue.extend(MemoryUsage);
-
- return new Component({
- el: document.createElement('div'),
- propsData: {
- metricsUrl: url,
- metricsMonitoringUrl: monitoringUrl,
- memoryMetrics: [],
- deploymentTime: 0,
- hasMetrics: false,
- loadFailed: false,
- loadingMetrics: true,
- backOffRequestCounter: 0,
- },
- });
-};
-
-const messages = {
- loadingMetrics: 'Loading deployment statistics',
- hasMetrics: 'Memory usage is unchanged at 0MB',
- loadFailed: 'Failed to load deployment statistics',
- metricsUnavailable: 'Deployment statistics are not available currently',
-};
-
-describe('MemoryUsage', () => {
- let vm;
- let el;
-
- beforeEach(() => {
- vm = createComponent();
- el = vm.$el;
- });
-
- describe('data', () => {
- it('should have default data', () => {
- const data = MemoryUsage.data();
-
- expect(Array.isArray(data.memoryMetrics)).toBeTruthy();
- expect(data.memoryMetrics.length).toBe(0);
-
- expect(typeof data.deploymentTime).toBe('number');
- expect(data.deploymentTime).toBe(0);
-
- expect(typeof data.hasMetrics).toBe('boolean');
- expect(data.hasMetrics).toBeFalsy();
-
- expect(typeof data.loadFailed).toBe('boolean');
- expect(data.loadFailed).toBeFalsy();
-
- expect(typeof data.loadingMetrics).toBe('boolean');
- expect(data.loadingMetrics).toBeTruthy();
-
- expect(typeof data.backOffRequestCounter).toBe('number');
- expect(data.backOffRequestCounter).toBe(0);
- });
- });
-
- describe('computed', () => {
- describe('memoryChangeMessage', () => {
- it('should contain "increased" if memoryFrom value is less than memoryTo value', () => {
- vm.memoryFrom = 4.28;
- vm.memoryTo = 9.13;
-
- expect(vm.memoryChangeMessage.indexOf('increased')).not.toEqual('-1');
- });
-
- it('should contain "decreased" if memoryFrom value is less than memoryTo value', () => {
- vm.memoryFrom = 9.13;
- vm.memoryTo = 4.28;
-
- expect(vm.memoryChangeMessage.indexOf('decreased')).not.toEqual('-1');
- });
-
- it('should contain "unchanged" if memoryFrom value equal to memoryTo value', () => {
- vm.memoryFrom = 1;
- vm.memoryTo = 1;
-
- expect(vm.memoryChangeMessage.indexOf('unchanged')).not.toEqual('-1');
- });
- });
- });
-
- describe('methods', () => {
- const { metrics, deployment_time } = metricsMockData;
-
- describe('getMegabytes', () => {
- it('should return Megabytes from provided Bytes value', () => {
- const memoryInBytes = '9572875.906976745';
-
- expect(vm.getMegabytes(memoryInBytes)).toEqual('9.13');
- });
- });
-
- describe('computeGraphData', () => {
- it('should populate sparkline graph', () => {
- vm.computeGraphData(metrics, deployment_time);
- const { hasMetrics, memoryMetrics, deploymentTime, memoryFrom, memoryTo } = vm;
-
- expect(hasMetrics).toBeTruthy();
- expect(memoryMetrics.length).toBeGreaterThan(0);
- expect(deploymentTime).toEqual(deployment_time);
- expect(memoryFrom).toEqual('9.13');
- expect(memoryTo).toEqual('4.28');
- });
- });
-
- describe('loadMetrics', () => {
- const returnServicePromise = () =>
- new Promise(resolve => {
- resolve({
- data: metricsMockData,
- });
- });
-
- it('should load metrics data using MRWidgetService', done => {
- spyOn(MRWidgetService, 'fetchMetrics').and.returnValue(returnServicePromise(true));
- spyOn(vm, 'computeGraphData');
-
- vm.loadMetrics();
- setTimeout(() => {
- expect(MRWidgetService.fetchMetrics).toHaveBeenCalledWith(url);
- expect(vm.computeGraphData).toHaveBeenCalledWith(metrics, deployment_time);
- done();
- }, 333);
- });
- });
- });
-
- describe('template', () => {
- it('should render template elements correctly', () => {
- expect(el.classList.contains('mr-memory-usage')).toBeTruthy();
- expect(el.querySelector('.js-usage-info')).toBeDefined();
- });
-
- it('should show loading metrics message while metrics are being loaded', done => {
- vm.loadingMetrics = true;
- vm.hasMetrics = false;
- vm.loadFailed = false;
-
- Vue.nextTick(() => {
- expect(el.querySelector('.js-usage-info.usage-info-loading')).toBeDefined();
-
- expect(el.querySelector('.js-usage-info .usage-info-load-spinner')).toBeDefined();
-
- expect(el.querySelector('.js-usage-info').innerText).toContain(messages.loadingMetrics);
- done();
- });
- });
-
- it('should show deployment memory usage when metrics are loaded', done => {
- vm.loadingMetrics = false;
- vm.hasMetrics = true;
- vm.loadFailed = false;
- vm.memoryMetrics = metricsMockData.metrics.memory_values[0].values;
-
- Vue.nextTick(() => {
- expect(el.querySelector('.memory-graph-container')).toBeDefined();
- expect(el.querySelector('.js-usage-info').innerText).toContain(messages.hasMetrics);
- done();
- });
- });
-
- it('should show failure message when metrics loading failed', done => {
- vm.loadingMetrics = false;
- vm.hasMetrics = false;
- vm.loadFailed = true;
-
- Vue.nextTick(() => {
- expect(el.querySelector('.js-usage-info.usage-info-failed')).toBeDefined();
-
- expect(el.querySelector('.js-usage-info').innerText).toContain(messages.loadFailed);
- done();
- });
- });
-
- it('should show metrics unavailable message when metrics loading failed', done => {
- vm.loadingMetrics = false;
- vm.hasMetrics = false;
- vm.loadFailed = false;
-
- Vue.nextTick(() => {
- expect(el.querySelector('.js-usage-info.usage-info-unavailable')).toBeDefined();
-
- expect(el.querySelector('.js-usage-info').innerText).toContain(messages.metricsUnavailable);
- done();
- });
- });
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_merge_help_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_merge_help_spec.js
deleted file mode 100644
index b566876fe1d..00000000000
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_merge_help_spec.js
+++ /dev/null
@@ -1,70 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import mergeHelpComponent from '~/vue_merge_request_widget/components/mr_widget_merge_help.vue';
-
-describe('MRWidgetMergeHelp', () => {
- let vm;
- let Component;
-
- beforeEach(() => {
- Component = Vue.extend(mergeHelpComponent);
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('with missing branch', () => {
- beforeEach(() => {
- vm = mountComponent(Component, {
- missingBranch: 'this-is-not-the-branch-you-are-looking-for',
- });
- });
-
- it('renders missing branch information', () => {
- expect(
- vm.$el.textContent
- .trim()
- .replace(/[\r\n]+/g, ' ')
- .replace(/\s\s+/g, ' '),
- ).toEqual(
- 'If the this-is-not-the-branch-you-are-looking-for branch exists in your local repository, you can merge this merge request manually using the command line',
- );
- });
-
- it('renders button to open help modal', () => {
- expect(vm.$el.querySelector('.js-open-modal-help').getAttribute('data-target')).toEqual(
- '#modal_merge_info',
- );
-
- expect(vm.$el.querySelector('.js-open-modal-help').getAttribute('data-toggle')).toEqual(
- 'modal',
- );
- });
- });
-
- describe('without missing branch', () => {
- beforeEach(() => {
- vm = mountComponent(Component);
- });
-
- it('renders information about how to merge manually', () => {
- expect(
- vm.$el.textContent
- .trim()
- .replace(/[\r\n]+/g, ' ')
- .replace(/\s\s+/g, ' '),
- ).toEqual('You can merge this merge request manually using the command line');
- });
-
- it('renders element to open a modal', () => {
- expect(vm.$el.querySelector('.js-open-modal-help').getAttribute('data-target')).toEqual(
- '#modal_merge_info',
- );
-
- expect(vm.$el.querySelector('.js-open-modal-help').getAttribute('data-toggle')).toEqual(
- 'modal',
- );
- });
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js
deleted file mode 100644
index 883c41085fa..00000000000
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js
+++ /dev/null
@@ -1,326 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import { trimText } from 'spec/helpers/text_helper';
-import pipelineComponent from '~/vue_merge_request_widget/components/mr_widget_pipeline.vue';
-import mockData from '../mock_data';
-
-describe('MRWidgetPipeline', () => {
- let vm;
- let Component;
-
- beforeEach(() => {
- Component = Vue.extend(pipelineComponent);
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('computed', () => {
- describe('hasPipeline', () => {
- it('should return true when there is a pipeline', () => {
- vm = mountComponent(Component, {
- pipeline: mockData.pipeline,
- ciStatus: 'success',
- hasCi: true,
- troubleshootingDocsPath: 'help',
- });
-
- expect(vm.hasPipeline).toEqual(true);
- });
-
- it('should return false when there is no pipeline', () => {
- vm = mountComponent(Component, {
- pipeline: {},
- troubleshootingDocsPath: 'help',
- });
-
- expect(vm.hasPipeline).toEqual(false);
- });
- });
-
- describe('hasCIError', () => {
- it('should return false when there is no CI error', () => {
- vm = mountComponent(Component, {
- pipeline: mockData.pipeline,
- hasCi: true,
- ciStatus: 'success',
- troubleshootingDocsPath: 'help',
- });
-
- expect(vm.hasCIError).toEqual(false);
- });
-
- it('should return true when there is a CI error', () => {
- vm = mountComponent(Component, {
- pipeline: mockData.pipeline,
- hasCi: true,
- ciStatus: null,
- troubleshootingDocsPath: 'help',
- });
-
- expect(vm.hasCIError).toEqual(true);
- });
- });
-
- describe('coverageDeltaClass', () => {
- it('should return no class if there is no coverage change', () => {
- vm = mountComponent(Component, {
- pipeline: mockData.pipeline,
- pipelineCoverageDelta: '0',
- troubleshootingDocsPath: 'help',
- });
-
- expect(vm.coverageDeltaClass).toEqual('');
- });
-
- it('should return text-success if the coverage increased', () => {
- vm = mountComponent(Component, {
- pipeline: mockData.pipeline,
- pipelineCoverageDelta: '10',
- troubleshootingDocsPath: 'help',
- });
-
- expect(vm.coverageDeltaClass).toEqual('text-success');
- });
-
- it('should return text-danger if the coverage decreased', () => {
- vm = mountComponent(Component, {
- pipeline: mockData.pipeline,
- pipelineCoverageDelta: '-12',
- troubleshootingDocsPath: 'help',
- });
-
- expect(vm.coverageDeltaClass).toEqual('text-danger');
- });
- });
- });
-
- describe('rendered output', () => {
- it('should render CI error', () => {
- vm = mountComponent(Component, {
- pipeline: mockData.pipeline,
- hasCi: true,
- troubleshootingDocsPath: 'help',
- });
-
- expect(vm.$el.querySelector('.media-body').textContent.trim()).toContain(
- 'Could not retrieve the pipeline status. For troubleshooting steps, read the documentation.',
- );
- });
-
- it('should render CI error when no pipeline is provided', () => {
- vm = mountComponent(Component, {
- pipeline: {},
- hasCi: true,
- ciStatus: 'success',
- troubleshootingDocsPath: 'help',
- });
-
- expect(vm.$el.querySelector('.media-body').textContent.trim()).toContain(
- 'Could not retrieve the pipeline status. For troubleshooting steps, read the documentation.',
- );
- });
-
- it('should render CI error when no CI is provided and pipeline must succeed is turned on', () => {
- vm = mountComponent(Component, {
- pipeline: {},
- hasCi: false,
- pipelineMustSucceed: true,
- troubleshootingDocsPath: 'help',
- });
-
- expect(vm.$el.querySelector('.media-body').textContent.trim()).toContain(
- 'No pipeline has been run for this commit.',
- );
- });
-
- describe('with a pipeline', () => {
- beforeEach(() => {
- vm = mountComponent(Component, {
- pipeline: mockData.pipeline,
- hasCi: true,
- ciStatus: 'success',
- pipelineCoverageDelta: mockData.pipelineCoverageDelta,
- troubleshootingDocsPath: 'help',
- });
- });
-
- it('should render pipeline ID', () => {
- expect(vm.$el.querySelector('.pipeline-id').textContent.trim()).toEqual(
- `#${mockData.pipeline.id}`,
- );
- });
-
- it('should render pipeline status and commit id', () => {
- expect(vm.$el.querySelector('.media-body').textContent.trim()).toContain(
- mockData.pipeline.details.status.label,
- );
-
- expect(vm.$el.querySelector('.js-commit-link').textContent.trim()).toEqual(
- mockData.pipeline.commit.short_id,
- );
-
- expect(vm.$el.querySelector('.js-commit-link').getAttribute('href')).toEqual(
- mockData.pipeline.commit.commit_path,
- );
- });
-
- it('should render pipeline graph', () => {
- expect(vm.$el.querySelector('.mr-widget-pipeline-graph')).toBeDefined();
- expect(vm.$el.querySelectorAll('.stage-container').length).toEqual(
- mockData.pipeline.details.stages.length,
- );
- });
-
- it('should render coverage information', () => {
- expect(vm.$el.querySelector('.media-body').textContent).toContain(
- `Coverage ${mockData.pipeline.coverage}`,
- );
- });
-
- it('should render pipeline coverage delta information', () => {
- expect(vm.$el.querySelector('.js-pipeline-coverage-delta.text-danger')).toBeDefined();
- expect(vm.$el.querySelector('.js-pipeline-coverage-delta').textContent).toContain(
- `(${mockData.pipelineCoverageDelta}%)`,
- );
- });
- });
-
- describe('without commit path', () => {
- beforeEach(() => {
- const mockCopy = JSON.parse(JSON.stringify(mockData));
- delete mockCopy.pipeline.commit;
-
- vm = mountComponent(Component, {
- pipeline: mockCopy.pipeline,
- hasCi: true,
- ciStatus: 'success',
- troubleshootingDocsPath: 'help',
- });
- });
-
- it('should render pipeline ID', () => {
- expect(vm.$el.querySelector('.pipeline-id').textContent.trim()).toEqual(
- `#${mockData.pipeline.id}`,
- );
- });
-
- it('should render pipeline status', () => {
- expect(vm.$el.querySelector('.media-body').textContent.trim()).toContain(
- mockData.pipeline.details.status.label,
- );
-
- expect(vm.$el.querySelector('.js-commit-link')).toBeNull();
- });
-
- it('should render pipeline graph', () => {
- expect(vm.$el.querySelector('.mr-widget-pipeline-graph')).toBeDefined();
- expect(vm.$el.querySelectorAll('.stage-container').length).toEqual(
- mockData.pipeline.details.stages.length,
- );
- });
-
- it('should render coverage information', () => {
- expect(vm.$el.querySelector('.media-body').textContent).toContain(
- `Coverage ${mockData.pipeline.coverage}`,
- );
- });
- });
-
- describe('without coverage', () => {
- it('should not render a coverage', () => {
- const mockCopy = JSON.parse(JSON.stringify(mockData));
- delete mockCopy.pipeline.coverage;
-
- vm = mountComponent(Component, {
- pipeline: mockCopy.pipeline,
- hasCi: true,
- ciStatus: 'success',
- troubleshootingDocsPath: 'help',
- });
-
- expect(vm.$el.querySelector('.media-body').textContent).not.toContain('Coverage');
- });
- });
-
- describe('without a pipeline graph', () => {
- it('should not render a pipeline graph', () => {
- const mockCopy = JSON.parse(JSON.stringify(mockData));
- delete mockCopy.pipeline.details.stages;
-
- vm = mountComponent(Component, {
- pipeline: mockCopy.pipeline,
- hasCi: true,
- ciStatus: 'success',
- troubleshootingDocsPath: 'help',
- });
-
- expect(vm.$el.querySelector('.js-mini-pipeline-graph')).toEqual(null);
- });
- });
-
- describe('for each type of pipeline', () => {
- let pipeline;
-
- beforeEach(() => {
- ({ pipeline } = JSON.parse(JSON.stringify(mockData)));
-
- pipeline.details.name = 'Pipeline';
- pipeline.merge_request_event_type = undefined;
- pipeline.ref.tag = false;
- pipeline.ref.branch = false;
- });
-
- const factory = () => {
- vm = mountComponent(Component, {
- pipeline,
- hasCi: true,
- ciStatus: 'success',
- troubleshootingDocsPath: 'help',
- sourceBranchLink: mockData.source_branch_link,
- });
- };
-
- describe('for a branch pipeline', () => {
- it('renders a pipeline widget that reads "Pipeline <ID> <status> for <SHA> on <branch>"', () => {
- pipeline.ref.branch = true;
-
- factory();
-
- const expected = `Pipeline #${pipeline.id} ${pipeline.details.status.label} for ${pipeline.commit.short_id} on ${mockData.source_branch_link}`;
- const actual = trimText(vm.$el.querySelector('.js-pipeline-info-container').innerText);
-
- expect(actual).toBe(expected);
- });
- });
-
- describe('for a tag pipeline', () => {
- it('renders a pipeline widget that reads "Pipeline <ID> <status> for <SHA> on <branch>"', () => {
- pipeline.ref.tag = true;
-
- factory();
-
- const expected = `Pipeline #${pipeline.id} ${pipeline.details.status.label} for ${pipeline.commit.short_id}`;
- const actual = trimText(vm.$el.querySelector('.js-pipeline-info-container').innerText);
-
- expect(actual).toBe(expected);
- });
- });
-
- describe('for a detached merge request pipeline', () => {
- it('renders a pipeline widget that reads "Detached merge request pipeline <ID> <status> for <SHA>"', () => {
- pipeline.details.name = 'Detached merge request pipeline';
- pipeline.merge_request_event_type = 'detached';
-
- factory();
-
- const expected = `Detached merge request pipeline #${pipeline.id} ${pipeline.details.status.label} for ${pipeline.commit.short_id}`;
- const actual = trimText(vm.$el.querySelector('.js-pipeline-info-container').innerText);
-
- expect(actual).toBe(expected);
- });
- });
- });
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_rebase_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_rebase_spec.js
deleted file mode 100644
index 5b293862b16..00000000000
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_rebase_spec.js
+++ /dev/null
@@ -1,141 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import eventHub from '~/vue_merge_request_widget/event_hub';
-import component from '~/vue_merge_request_widget/components/states/mr_widget_rebase.vue';
-
-describe('Merge request widget rebase component', () => {
- let Component;
- let vm;
- beforeEach(() => {
- Component = Vue.extend(component);
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('While rebasing', () => {
- it('should show progress message', () => {
- vm = mountComponent(Component, {
- mr: { rebaseInProgress: true },
- service: {},
- });
-
- expect(
- vm.$el.querySelector('.rebase-state-find-class-convention span').textContent.trim(),
- ).toContain('Rebase in progress');
- });
- });
-
- describe('With permissions', () => {
- beforeEach(() => {
- vm = mountComponent(Component, {
- mr: {
- rebaseInProgress: false,
- canPushToSourceBranch: true,
- },
- service: {},
- });
- });
-
- it('it should render rebase button and warning message', () => {
- const text = vm.$el
- .querySelector('.rebase-state-find-class-convention span')
- .textContent.trim();
-
- expect(text).toContain('Fast-forward merge is not possible.');
- expect(text.replace(/\s\s+/g, ' ')).toContain(
- 'Rebase the source branch onto the target branch or merge target',
- );
-
- expect(text).toContain('branch into source branch to allow this merge request to be merged.');
- });
-
- it('it should render error message when it fails', done => {
- vm.rebasingError = 'Something went wrong!';
-
- Vue.nextTick(() => {
- expect(
- vm.$el.querySelector('.rebase-state-find-class-convention span').textContent.trim(),
- ).toContain('Something went wrong!');
- done();
- });
- });
- });
-
- describe('Without permissions', () => {
- it('should render a message explaining user does not have permissions', () => {
- vm = mountComponent(Component, {
- mr: {
- rebaseInProgress: false,
- canPushToSourceBranch: false,
- targetBranch: 'foo',
- },
- service: {},
- });
-
- const text = vm.$el
- .querySelector('.rebase-state-find-class-convention span')
- .textContent.trim();
-
- expect(text).toContain('Fast-forward merge is not possible.');
- expect(text).toContain('Rebase the source branch onto');
- expect(text).toContain('foo');
- expect(text.replace(/\s\s+/g, ' ')).toContain('to allow this merge request to be merged.');
- });
-
- it('should render the correct target branch name', () => {
- const targetBranch = 'fake-branch-to-test-with';
- vm = mountComponent(Component, {
- mr: {
- rebaseInProgress: false,
- canPushToSourceBranch: false,
- targetBranch,
- },
- service: {},
- });
-
- const elem = vm.$el.querySelector('.rebase-state-find-class-convention span');
-
- expect(elem.innerHTML).toContain(
- `Fast-forward merge is not possible. Rebase the source branch onto <span class="label-branch">${targetBranch}</span> to allow this merge request to be merged.`,
- );
- });
- });
-
- describe('methods', () => {
- it('checkRebaseStatus', done => {
- spyOn(eventHub, '$emit');
- vm = mountComponent(Component, {
- mr: {},
- service: {
- rebase() {
- return Promise.resolve();
- },
- poll() {
- return Promise.resolve({
- data: {
- rebase_in_progress: false,
- merge_error: null,
- },
- });
- },
- },
- });
-
- vm.rebase();
-
- // Wait for the rebase request
- vm.$nextTick()
- // Wait for the polling request
- .then(vm.$nextTick())
- // Wait for the eventHub to be called
- .then(vm.$nextTick())
- .then(() => {
- expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetRebaseSuccess');
- })
- .then(done)
- .catch(done.fail);
- });
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_related_links_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_related_links_spec.js
deleted file mode 100644
index a152bd01916..00000000000
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_related_links_spec.js
+++ /dev/null
@@ -1,85 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import relatedLinksComponent from '~/vue_merge_request_widget/components/mr_widget_related_links.vue';
-
-describe('MRWidgetRelatedLinks', () => {
- let vm;
-
- const createComponent = data => {
- const Component = Vue.extend(relatedLinksComponent);
-
- return mountComponent(Component, data);
- };
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('computed', () => {
- describe('closesText', () => {
- it('returns Closes text for open merge request', () => {
- vm = createComponent({ state: 'open', relatedLinks: {} });
-
- expect(vm.closesText).toEqual('Closes');
- });
-
- it('returns correct text for closed merge request', () => {
- vm = createComponent({ state: 'closed', relatedLinks: {} });
-
- expect(vm.closesText).toEqual('Did not close');
- });
-
- it('returns correct tense for merged request', () => {
- vm = createComponent({ state: 'merged', relatedLinks: {} });
-
- expect(vm.closesText).toEqual('Closed');
- });
- });
- });
-
- it('should have only have closing issues text', () => {
- vm = createComponent({
- relatedLinks: {
- closing: '<a href="#">#23</a> and <a>#42</a>',
- },
- });
- const content = vm.$el.textContent.replace(/\n(\s)+/g, ' ').trim();
-
- expect(content).toContain('Closes #23 and #42');
- expect(content).not.toContain('Mentions');
- });
-
- it('should have only have mentioned issues text', () => {
- vm = createComponent({
- relatedLinks: {
- mentioned: '<a href="#">#7</a>',
- },
- });
-
- expect(vm.$el.innerText).toContain('Mentions #7');
- expect(vm.$el.innerText).not.toContain('Closes');
- });
-
- it('should have closing and mentioned issues at the same time', () => {
- vm = createComponent({
- relatedLinks: {
- closing: '<a href="#">#7</a>',
- mentioned: '<a href="#">#23</a> and <a>#42</a>',
- },
- });
- const content = vm.$el.textContent.replace(/\n(\s)+/g, ' ').trim();
-
- expect(content).toContain('Closes #7');
- expect(content).toContain('Mentions #23 and #42');
- });
-
- it('should have assing issues link', () => {
- vm = createComponent({
- relatedLinks: {
- assignToMe: '<a href="#">Assign yourself to these issues</a>',
- },
- });
-
- expect(vm.$el.innerText).toContain('Assign yourself to these issues');
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_status_icon_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_status_icon_spec.js
deleted file mode 100644
index 20bda024d89..00000000000
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_status_icon_spec.js
+++ /dev/null
@@ -1,48 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import mrStatusIcon from '~/vue_merge_request_widget/components/mr_widget_status_icon.vue';
-
-describe('MR widget status icon component', () => {
- let vm;
- let Component;
-
- beforeEach(() => {
- Component = Vue.extend(mrStatusIcon);
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('while loading', () => {
- it('renders loading icon', () => {
- vm = mountComponent(Component, { status: 'loading' });
-
- expect(vm.$el.querySelector('.mr-widget-icon span').classList).toContain('gl-spinner');
- });
- });
-
- describe('with status icon', () => {
- it('renders ci status icon', () => {
- vm = mountComponent(Component, { status: 'failed' });
-
- expect(vm.$el.querySelector('.js-ci-status-icon-failed')).not.toBeNull();
- });
- });
-
- describe('with disabled button', () => {
- it('renders a disabled button', () => {
- vm = mountComponent(Component, { status: 'failed', showDisabledButton: true });
-
- expect(vm.$el.querySelector('.js-disabled-merge-button').textContent.trim()).toEqual('Merge');
- });
- });
-
- describe('without disabled button', () => {
- it('does not render a disabled button', () => {
- vm = mountComponent(Component, { status: 'failed' });
-
- expect(vm.$el.querySelector('.js-disabled-merge-button')).toBeNull();
- });
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/review_app_link_spec.js b/spec/javascripts/vue_mr_widget/components/review_app_link_spec.js
deleted file mode 100644
index 242193c7b3d..00000000000
--- a/spec/javascripts/vue_mr_widget/components/review_app_link_spec.js
+++ /dev/null
@@ -1,52 +0,0 @@
-import Vue from 'vue';
-import { mockTracking, triggerEvent } from 'spec/helpers/tracking_helper';
-import component from '~/vue_merge_request_widget/components/review_app_link.vue';
-import mountComponent from '../../helpers/vue_mount_component_helper';
-
-describe('review app link', () => {
- const Component = Vue.extend(component);
- const props = {
- link: '/review',
- cssClass: 'js-link',
- display: {
- text: 'View app',
- tooltip: '',
- },
- };
- let vm;
- let el;
-
- beforeEach(() => {
- vm = mountComponent(Component, props);
- el = vm.$el;
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('renders provided link as href attribute', () => {
- expect(el.getAttribute('href')).toEqual(props.link);
- });
-
- it('renders provided cssClass as class attribute', () => {
- expect(el.getAttribute('class')).toEqual(props.cssClass);
- });
-
- it('renders View app text', () => {
- expect(el.textContent.trim()).toEqual('View app');
- });
-
- it('renders svg icon', () => {
- expect(el.querySelector('svg')).not.toBeNull();
- });
-
- it('tracks an event when clicked', () => {
- const spy = mockTracking('_category_', el, spyOn);
- triggerEvent(el);
-
- expect(spy).toHaveBeenCalledWith('_category_', 'open_review_app', {
- label: 'review_app',
- });
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_archived_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_archived_spec.js
deleted file mode 100644
index 29a257b0e24..00000000000
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_archived_spec.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import archivedComponent from '~/vue_merge_request_widget/components/states/mr_widget_archived.vue';
-
-describe('MRWidgetArchived', () => {
- let vm;
-
- beforeEach(() => {
- const Component = Vue.extend(archivedComponent);
- vm = mountComponent(Component);
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('renders a ci status failed icon', () => {
- expect(vm.$el.querySelector('.ci-status-icon')).not.toBeNull();
- });
-
- it('renders a disabled button', () => {
- expect(vm.$el.querySelector('button').getAttribute('disabled')).toEqual('disabled');
- expect(vm.$el.querySelector('button').textContent.trim()).toEqual('Merge');
- });
-
- it('renders information', () => {
- expect(vm.$el.querySelector('.bold').textContent.trim()).toEqual(
- 'This project is archived, write access has been disabled',
- );
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_enabled_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_enabled_spec.js
deleted file mode 100644
index 73b65178ecf..00000000000
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_enabled_spec.js
+++ /dev/null
@@ -1,230 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import { trimText } from 'spec/helpers/text_helper';
-import autoMergeEnabledComponent from '~/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue';
-import MRWidgetService from '~/vue_merge_request_widget/services/mr_widget_service';
-import eventHub from '~/vue_merge_request_widget/event_hub';
-import { MWPS_MERGE_STRATEGY } from '~/vue_merge_request_widget/constants';
-
-describe('MRWidgetAutoMergeEnabled', () => {
- let vm;
- const targetBranchPath = '/foo/bar';
- const targetBranch = 'foo';
- const sha = '1EA2EZ34';
-
- beforeEach(() => {
- const Component = Vue.extend(autoMergeEnabledComponent);
- spyOn(eventHub, '$emit');
-
- vm = mountComponent(Component, {
- mr: {
- shouldRemoveSourceBranch: false,
- canRemoveSourceBranch: true,
- canCancelAutomaticMerge: true,
- mergeUserId: 1,
- currentUserId: 1,
- setToAutoMergeBy: {},
- sha,
- targetBranchPath,
- targetBranch,
- autoMergeStrategy: MWPS_MERGE_STRATEGY,
- },
- service: new MRWidgetService({}),
- });
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('computed', () => {
- describe('canRemoveSourceBranch', () => {
- it('should return true when user is able to remove source branch', () => {
- expect(vm.canRemoveSourceBranch).toBeTruthy();
- });
-
- it('should return false when user id is not the same with who set the MWPS', () => {
- vm.mr.mergeUserId = 2;
-
- expect(vm.canRemoveSourceBranch).toBeFalsy();
-
- vm.mr.currentUserId = 2;
-
- expect(vm.canRemoveSourceBranch).toBeTruthy();
-
- vm.mr.currentUserId = 3;
-
- expect(vm.canRemoveSourceBranch).toBeFalsy();
- });
-
- it('should return false when shouldRemoveSourceBranch set to false', () => {
- vm.mr.shouldRemoveSourceBranch = true;
-
- expect(vm.canRemoveSourceBranch).toBeFalsy();
- });
-
- it('should return false if user is not able to remove the source branch', () => {
- vm.mr.canRemoveSourceBranch = false;
-
- expect(vm.canRemoveSourceBranch).toBeFalsy();
- });
- });
-
- describe('statusTextBeforeAuthor', () => {
- it('should return "Set by" if the MWPS is selected', () => {
- Vue.set(vm.mr, 'autoMergeStrategy', MWPS_MERGE_STRATEGY);
-
- expect(vm.statusTextBeforeAuthor).toBe('Set by');
- });
- });
-
- describe('statusTextAfterAuthor', () => {
- it('should return "to be merged automatically..." if MWPS is selected', () => {
- Vue.set(vm.mr, 'autoMergeStrategy', MWPS_MERGE_STRATEGY);
-
- expect(vm.statusTextAfterAuthor).toBe(
- 'to be merged automatically when the pipeline succeeds',
- );
- });
- });
-
- describe('cancelButtonText', () => {
- it('should return "Cancel automatic merge" if MWPS is selected', () => {
- Vue.set(vm.mr, 'autoMergeStrategy', MWPS_MERGE_STRATEGY);
-
- expect(vm.cancelButtonText).toBe('Cancel automatic merge');
- });
- });
- });
-
- describe('methods', () => {
- describe('cancelAutomaticMerge', () => {
- it('should set flag and call service then tell main component to update the widget with data', done => {
- const mrObj = {
- is_new_mr_data: true,
- };
- spyOn(vm.service, 'cancelAutomaticMerge').and.returnValue(
- new Promise(resolve => {
- resolve({
- data: mrObj,
- });
- }),
- );
-
- vm.cancelAutomaticMerge();
- setTimeout(() => {
- expect(vm.isCancellingAutoMerge).toBeTruthy();
- expect(eventHub.$emit).toHaveBeenCalledWith('UpdateWidgetData', mrObj);
- done();
- }, 333);
- });
- });
-
- describe('removeSourceBranch', () => {
- it('should set flag and call service then request main component to update the widget', done => {
- spyOn(vm.service, 'merge').and.returnValue(
- Promise.resolve({
- data: {
- status: MWPS_MERGE_STRATEGY,
- },
- }),
- );
-
- vm.removeSourceBranch();
- setTimeout(() => {
- expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetUpdateRequested');
- expect(vm.service.merge).toHaveBeenCalledWith({
- sha,
- auto_merge_strategy: MWPS_MERGE_STRATEGY,
- should_remove_source_branch: true,
- });
- done();
- }, 333);
- });
- });
- });
-
- describe('template', () => {
- it('should have correct elements', () => {
- expect(vm.$el.classList.contains('mr-widget-body')).toBeTruthy();
- expect(vm.$el.innerText).toContain('to be merged automatically when the pipeline succeeds');
-
- expect(vm.$el.innerText).toContain('The changes will be merged into');
- expect(vm.$el.innerText).toContain(targetBranch);
- expect(vm.$el.innerText).toContain('The source branch will not be deleted');
- expect(vm.$el.querySelector('.js-cancel-auto-merge').innerText).toContain(
- 'Cancel automatic merge',
- );
-
- expect(vm.$el.querySelector('.js-cancel-auto-merge').getAttribute('disabled')).toBeFalsy();
- expect(vm.$el.querySelector('.js-remove-source-branch').innerText).toContain(
- 'Delete source branch',
- );
-
- expect(vm.$el.querySelector('.js-remove-source-branch').getAttribute('disabled')).toBeFalsy();
- });
-
- it('should disable cancel auto merge button when the action is in progress', done => {
- vm.isCancellingAutoMerge = true;
-
- Vue.nextTick(() => {
- expect(vm.$el.querySelector('.js-cancel-auto-merge').getAttribute('disabled')).toBeTruthy();
- done();
- });
- });
-
- it('should show source branch will be deleted text when it source branch set to remove', done => {
- vm.mr.shouldRemoveSourceBranch = true;
-
- Vue.nextTick(() => {
- const normalizedText = vm.$el.innerText.replace(/\s+/g, ' ');
-
- expect(normalizedText).toContain('The source branch will be deleted');
- expect(normalizedText).not.toContain('The source branch will not be deleted');
- done();
- });
- });
-
- it('should not show delete source branch button when user not able to delete source branch', done => {
- vm.mr.currentUserId = 4;
-
- Vue.nextTick(() => {
- expect(vm.$el.querySelector('.js-remove-source-branch')).toEqual(null);
- done();
- });
- });
-
- it('should disable delete source branch button when the action is in progress', done => {
- vm.isRemovingSourceBranch = true;
-
- Vue.nextTick(() => {
- expect(
- vm.$el.querySelector('.js-remove-source-branch').getAttribute('disabled'),
- ).toBeTruthy();
- done();
- });
- });
-
- it('should render the status text as "...to merged automatically" if MWPS is selected', done => {
- Vue.set(vm.mr, 'autoMergeStrategy', MWPS_MERGE_STRATEGY);
-
- Vue.nextTick(() => {
- const statusText = trimText(vm.$el.querySelector('.js-status-text-after-author').innerText);
-
- expect(statusText).toBe('to be merged automatically when the pipeline succeeds');
- done();
- });
- });
-
- it('should render the cancel button as "Cancel automatic merge" if MWPS is selected', done => {
- Vue.set(vm.mr, 'autoMergeStrategy', MWPS_MERGE_STRATEGY);
-
- Vue.nextTick(() => {
- const cancelButtonText = trimText(vm.$el.querySelector('.js-cancel-auto-merge').innerText);
-
- expect(cancelButtonText).toBe('Cancel automatic merge');
- done();
- });
- });
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js
deleted file mode 100644
index efccd507fe2..00000000000
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import checkingComponent from '~/vue_merge_request_widget/components/states/mr_widget_checking.vue';
-
-describe('MRWidgetChecking', () => {
- let Component;
- let vm;
-
- beforeEach(() => {
- Component = Vue.extend(checkingComponent);
- vm = mountComponent(Component);
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('renders disabled button', () => {
- expect(vm.$el.querySelector('button').getAttribute('disabled')).toEqual('disabled');
- });
-
- it('renders loading icon', () => {
- expect(vm.$el.querySelector('.mr-widget-icon span').classList).toContain('gl-spinner');
- });
-
- it('renders information about merging', () => {
- expect(vm.$el.querySelector('.media-body').textContent.trim()).toEqual(
- 'Checking ability to merge automatically…',
- );
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_closed_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_closed_spec.js
deleted file mode 100644
index bbbaed0d2f5..00000000000
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_closed_spec.js
+++ /dev/null
@@ -1,69 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import closedComponent from '~/vue_merge_request_widget/components/states/mr_widget_closed.vue';
-
-describe('MRWidgetClosed', () => {
- let vm;
-
- beforeEach(() => {
- const Component = Vue.extend(closedComponent);
- vm = mountComponent(Component, {
- mr: {
- metrics: {
- mergedBy: {},
- closedBy: {
- name: 'Administrator',
- username: 'root',
- webUrl: 'http://localhost:3000/root',
- avatarUrl:
- 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- },
- mergedAt: 'Jan 24, 2018 1:02pm GMT+0000',
- closedAt: 'Jan 24, 2018 1:02pm GMT+0000',
- readableMergedAt: '',
- readableClosedAt: 'less than a minute ago',
- },
- targetBranchPath: '/twitter/flight/commits/so_long_jquery',
- targetBranch: 'so_long_jquery',
- },
- });
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('renders warning icon', () => {
- expect(vm.$el.querySelector('.js-ci-status-icon-warning')).not.toBeNull();
- });
-
- it('renders closed by information with author and time', () => {
- expect(
- vm.$el
- .querySelector('.js-mr-widget-author')
- .textContent.trim()
- .replace(/\s\s+/g, ' '),
- ).toContain('Closed by Administrator less than a minute ago');
- });
-
- it('links to the user that closed the MR', () => {
- expect(vm.$el.querySelector('.author-link').getAttribute('href')).toEqual(
- 'http://localhost:3000/root',
- );
- });
-
- it('renders information about the changes not being merged', () => {
- expect(
- vm.$el
- .querySelector('.mr-info-list')
- .textContent.trim()
- .replace(/\s\s+/g, ' '),
- ).toContain('The changes were not merged into so_long_jquery');
- });
-
- it('renders link for target branch', () => {
- expect(vm.$el.querySelector('.label-branch').getAttribute('href')).toEqual(
- '/twitter/flight/commits/so_long_jquery',
- );
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js
deleted file mode 100644
index 9035bc6f65d..00000000000
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js
+++ /dev/null
@@ -1,225 +0,0 @@
-import $ from 'jquery';
-import { createLocalVue, shallowMount } from '@vue/test-utils';
-import { removeBreakLine } from 'spec/helpers/text_helper';
-import ConflictsComponent from '~/vue_merge_request_widget/components/states/mr_widget_conflicts.vue';
-
-describe('MRWidgetConflicts', () => {
- let vm;
- const path = '/conflicts';
-
- function createComponent(propsData = {}) {
- const localVue = createLocalVue();
-
- vm = shallowMount(localVue.extend(ConflictsComponent), {
- propsData,
- });
- }
-
- beforeEach(() => {
- spyOn($.fn, 'popover').and.callThrough();
- });
-
- afterEach(() => {
- vm.destroy();
- });
-
- // There are two permissions we need to consider:
- //
- // 1. Is the user allowed to merge to the target branch?
- // 2. Is the user allowed to push to the source branch?
- //
- // This yields 4 possible permutations that we need to test, and
- // we test them below. A user who can push to the source
- // branch should be allowed to resolve conflicts. This is
- // consistent with what the backend does.
- describe('when allowed to merge but not allowed to push to source branch', () => {
- beforeEach(() => {
- createComponent({
- mr: {
- canMerge: true,
- canPushToSourceBranch: false,
- conflictResolutionPath: path,
- conflictsDocsPath: '',
- },
- });
- });
-
- it('should tell you about conflicts without bothering other people', () => {
- expect(vm.text()).toContain('There are merge conflicts');
- expect(vm.text()).not.toContain('ask someone with write access');
- });
-
- it('should not allow you to resolve the conflicts', () => {
- expect(vm.text()).not.toContain('Resolve conflicts');
- });
-
- it('should have merge buttons', () => {
- const mergeLocallyButton = vm.find('.js-merge-locally-button');
-
- expect(mergeLocallyButton.text()).toContain('Merge locally');
- });
- });
-
- describe('when not allowed to merge but allowed to push to source branch', () => {
- beforeEach(() => {
- createComponent({
- mr: {
- canMerge: false,
- canPushToSourceBranch: true,
- conflictResolutionPath: path,
- conflictsDocsPath: '',
- },
- });
- });
-
- it('should tell you about conflicts', () => {
- expect(vm.text()).toContain('There are merge conflicts');
- expect(vm.text()).toContain('ask someone with write access');
- });
-
- it('should allow you to resolve the conflicts', () => {
- const resolveButton = vm.find('.js-resolve-conflicts-button');
-
- expect(resolveButton.text()).toContain('Resolve conflicts');
- expect(resolveButton.attributes('href')).toEqual(path);
- });
-
- it('should not have merge buttons', () => {
- expect(vm.text()).not.toContain('Merge locally');
- });
- });
-
- describe('when allowed to merge and push to source branch', () => {
- beforeEach(() => {
- createComponent({
- mr: {
- canMerge: true,
- canPushToSourceBranch: true,
- conflictResolutionPath: path,
- conflictsDocsPath: '',
- },
- });
- });
-
- it('should tell you about conflicts without bothering other people', () => {
- expect(vm.text()).toContain('There are merge conflicts');
- expect(vm.text()).not.toContain('ask someone with write access');
- });
-
- it('should allow you to resolve the conflicts', () => {
- const resolveButton = vm.find('.js-resolve-conflicts-button');
-
- expect(resolveButton.text()).toContain('Resolve conflicts');
- expect(resolveButton.attributes('href')).toEqual(path);
- });
-
- it('should have merge buttons', () => {
- const mergeLocallyButton = vm.find('.js-merge-locally-button');
-
- expect(mergeLocallyButton.text()).toContain('Merge locally');
- });
- });
-
- describe('when user does not have permission to push to source branch', () => {
- it('should show proper message', () => {
- createComponent({
- mr: {
- canMerge: false,
- canPushToSourceBranch: false,
- conflictsDocsPath: '',
- },
- });
-
- expect(
- vm
- .text()
- .trim()
- .replace(/\s\s+/g, ' '),
- ).toContain('ask someone with write access');
- });
-
- it('should not have action buttons', () => {
- createComponent({
- mr: {
- canMerge: false,
- canPushToSourceBranch: false,
- conflictsDocsPath: '',
- },
- });
-
- expect(vm.contains('.js-resolve-conflicts-button')).toBe(false);
- expect(vm.contains('.js-merge-locally-button')).toBe(false);
- });
-
- it('should not have resolve button when no conflict resolution path', () => {
- createComponent({
- mr: {
- canMerge: true,
- conflictResolutionPath: null,
- conflictsDocsPath: '',
- },
- });
-
- expect(vm.contains('.js-resolve-conflicts-button')).toBe(false);
- });
- });
-
- describe('when fast-forward or semi-linear merge enabled', () => {
- it('should tell you to rebase locally', () => {
- createComponent({
- mr: {
- shouldBeRebased: true,
- conflictsDocsPath: '',
- },
- });
-
- expect(removeBreakLine(vm.text()).trim()).toContain(
- 'Fast-forward merge is not possible. To merge this request, first rebase locally.',
- );
- });
- });
-
- describe('when source branch protected', () => {
- beforeEach(() => {
- createComponent({
- mr: {
- canMerge: true,
- canPushToSourceBranch: true,
- conflictResolutionPath: gl.TEST_HOST,
- sourceBranchProtected: true,
- conflictsDocsPath: '',
- },
- });
- });
-
- it('sets resolve button as disabled', () => {
- expect(vm.find('.js-resolve-conflicts-button').attributes('disabled')).toBe('disabled');
- });
-
- it('renders popover', () => {
- expect($.fn.popover).toHaveBeenCalled();
- });
- });
-
- describe('when source branch not protected', () => {
- beforeEach(() => {
- createComponent({
- mr: {
- canMerge: true,
- canPushToSourceBranch: true,
- conflictResolutionPath: gl.TEST_HOST,
- sourceBranchProtected: false,
- conflictsDocsPath: '',
- },
- });
- });
-
- it('sets resolve button as disabled', () => {
- expect(vm.find('.js-resolve-conflicts-button').attributes('disabled')).toBe(undefined);
- });
-
- it('renders popover', () => {
- expect($.fn.popover).not.toHaveBeenCalled();
- });
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js
deleted file mode 100644
index ef76e617c07..00000000000
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js
+++ /dev/null
@@ -1,156 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import failedToMergeComponent from '~/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.vue';
-import eventHub from '~/vue_merge_request_widget/event_hub';
-
-describe('MRWidgetFailedToMerge', () => {
- const dummyIntervalId = 1337;
- let Component;
- let mr;
- let vm;
-
- beforeEach(() => {
- Component = Vue.extend(failedToMergeComponent);
- spyOn(eventHub, '$emit');
- spyOn(window, 'setInterval').and.returnValue(dummyIntervalId);
- spyOn(window, 'clearInterval').and.stub();
- mr = {
- mergeError: 'Merge error happened',
- };
- vm = mountComponent(Component, {
- mr,
- });
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('sets interval to refresh', () => {
- expect(window.setInterval).toHaveBeenCalledWith(vm.updateTimer, 1000);
- expect(vm.intervalId).toBe(dummyIntervalId);
- });
-
- it('clears interval when destroying ', () => {
- vm.$destroy();
-
- expect(window.clearInterval).toHaveBeenCalledWith(dummyIntervalId);
- });
-
- describe('computed', () => {
- describe('timerText', () => {
- it('should return correct timer text', () => {
- expect(vm.timerText).toEqual('Refreshing in 10 seconds to show the updated status...');
-
- vm.timer = 1;
-
- expect(vm.timerText).toEqual('Refreshing in a second to show the updated status...');
- });
- });
-
- describe('mergeError', () => {
- it('removes forced line breaks', done => {
- mr.mergeError = 'contains<br />line breaks<br />';
-
- Vue.nextTick()
- .then(() => {
- expect(vm.mergeError).toBe('contains line breaks');
- })
- .then(done)
- .catch(done.fail);
- });
- });
- });
-
- describe('created', () => {
- it('should disable polling', () => {
- expect(eventHub.$emit).toHaveBeenCalledWith('DisablePolling');
- });
- });
-
- describe('methods', () => {
- describe('refresh', () => {
- it('should emit event to request component refresh', () => {
- expect(vm.isRefreshing).toEqual(false);
-
- vm.refresh();
-
- expect(vm.isRefreshing).toEqual(true);
- expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetUpdateRequested');
- expect(eventHub.$emit).toHaveBeenCalledWith('EnablePolling');
- });
- });
-
- describe('updateTimer', () => {
- it('should update timer and emit event when timer end', () => {
- spyOn(vm, 'refresh');
-
- expect(vm.timer).toEqual(10);
-
- for (let i = 0; i < 10; i += 1) {
- expect(vm.timer).toEqual(10 - i);
- vm.updateTimer();
- }
-
- expect(vm.refresh).toHaveBeenCalled();
- });
- });
- });
-
- describe('while it is refreshing', () => {
- it('renders Refresing now', done => {
- vm.isRefreshing = true;
-
- Vue.nextTick(() => {
- expect(vm.$el.querySelector('.js-refresh-label').textContent.trim()).toEqual(
- 'Refreshing now',
- );
- done();
- });
- });
- });
-
- describe('while it is not regresing', () => {
- it('renders warning icon and disabled merge button', () => {
- expect(vm.$el.querySelector('.js-ci-status-icon-warning')).not.toBeNull();
- expect(vm.$el.querySelector('.js-disabled-merge-button').getAttribute('disabled')).toEqual(
- 'disabled',
- );
- });
-
- it('renders given error', () => {
- expect(vm.$el.querySelector('.has-error-message').textContent.trim()).toEqual(
- 'Merge error happened',
- );
- });
-
- it('renders refresh button', () => {
- expect(vm.$el.querySelector('.js-refresh-button').textContent.trim()).toEqual('Refresh now');
- });
-
- it('renders remaining time', () => {
- expect(vm.$el.querySelector('.has-custom-error').textContent.trim()).toEqual(
- 'Refreshing in 10 seconds to show the updated status...',
- );
- });
- });
-
- it('should just generic merge failed message if merge_error is not available', done => {
- vm.mr.mergeError = null;
-
- Vue.nextTick(() => {
- expect(vm.$el.innerText).toContain('Merge failed.');
- expect(vm.$el.innerText).not.toContain('Merge error happened.');
- done();
- });
- });
-
- it('should show refresh label when refresh requested', done => {
- vm.refresh();
- Vue.nextTick(() => {
- expect(vm.$el.innerText).not.toContain('Merge failed. Refreshing');
- expect(vm.$el.innerText).toContain('Refreshing now');
- done();
- });
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js
deleted file mode 100644
index 423c800bfbc..00000000000
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js
+++ /dev/null
@@ -1,219 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import mergedComponent from '~/vue_merge_request_widget/components/states/mr_widget_merged.vue';
-import eventHub from '~/vue_merge_request_widget/event_hub';
-
-describe('MRWidgetMerged', () => {
- let vm;
- const targetBranch = 'foo';
- const selectors = {
- get copyMergeShaButton() {
- return vm.$el.querySelector('button.js-mr-merged-copy-sha');
- },
- get mergeCommitShaLink() {
- return vm.$el.querySelector('a.js-mr-merged-commit-sha');
- },
- };
-
- beforeEach(() => {
- const Component = Vue.extend(mergedComponent);
- const mr = {
- isRemovingSourceBranch: false,
- cherryPickInForkPath: false,
- canCherryPickInCurrentMR: true,
- revertInForkPath: false,
- canRevertInCurrentMR: true,
- canRemoveSourceBranch: true,
- sourceBranchRemoved: true,
- metrics: {
- mergedBy: {
- name: 'Administrator',
- username: 'root',
- webUrl: 'http://localhost:3000/root',
- avatarUrl:
- 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- },
- mergedAt: 'Jan 24, 2018 1:02pm GMT+0000',
- readableMergedAt: '',
- closedBy: {},
- closedAt: 'Jan 24, 2018 1:02pm GMT+0000',
- readableClosedAt: '',
- },
- updatedAt: 'mergedUpdatedAt',
- shortMergeCommitSha: '958c0475',
- mergeCommitSha: '958c047516e182dfc52317f721f696e8a1ee85ed',
- mergeCommitPath:
- 'http://localhost:3000/root/nautilus/commit/f7ce827c314c9340b075657fd61c789fb01cf74d',
- sourceBranch: 'bar',
- targetBranch,
- };
-
- const service = {
- removeSourceBranch() {},
- };
-
- spyOn(eventHub, '$emit');
-
- vm = mountComponent(Component, { mr, service });
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('computed', () => {
- describe('shouldShowRemoveSourceBranch', () => {
- it('returns true when sourceBranchRemoved is false', () => {
- vm.mr.sourceBranchRemoved = false;
-
- expect(vm.shouldShowRemoveSourceBranch).toEqual(true);
- });
-
- it('returns false when sourceBranchRemoved is true', () => {
- vm.mr.sourceBranchRemoved = true;
-
- expect(vm.shouldShowRemoveSourceBranch).toEqual(false);
- });
-
- it('returns false when canRemoveSourceBranch is false', () => {
- vm.mr.sourceBranchRemoved = false;
- vm.mr.canRemoveSourceBranch = false;
-
- expect(vm.shouldShowRemoveSourceBranch).toEqual(false);
- });
-
- it('returns false when is making request', () => {
- vm.mr.canRemoveSourceBranch = true;
- vm.isMakingRequest = true;
-
- expect(vm.shouldShowRemoveSourceBranch).toEqual(false);
- });
-
- it('returns true when all are true', () => {
- vm.mr.isRemovingSourceBranch = true;
- vm.mr.canRemoveSourceBranch = true;
- vm.isMakingRequest = true;
-
- expect(vm.shouldShowRemoveSourceBranch).toEqual(false);
- });
- });
-
- describe('shouldShowSourceBranchRemoving', () => {
- it('should correct value when fields changed', () => {
- vm.mr.sourceBranchRemoved = false;
-
- expect(vm.shouldShowSourceBranchRemoving).toEqual(false);
-
- vm.mr.sourceBranchRemoved = true;
-
- expect(vm.shouldShowRemoveSourceBranch).toEqual(false);
-
- vm.mr.sourceBranchRemoved = false;
- vm.isMakingRequest = true;
-
- expect(vm.shouldShowSourceBranchRemoving).toEqual(true);
-
- vm.isMakingRequest = false;
- vm.mr.isRemovingSourceBranch = true;
-
- expect(vm.shouldShowSourceBranchRemoving).toEqual(true);
- });
- });
- });
-
- describe('methods', () => {
- describe('removeSourceBranch', () => {
- it('should set flag and call service then request main component to update the widget', done => {
- spyOn(vm.service, 'removeSourceBranch').and.returnValue(
- new Promise(resolve => {
- resolve({
- data: {
- message: 'Branch was deleted',
- },
- });
- }),
- );
-
- vm.removeSourceBranch();
- setTimeout(() => {
- const args = eventHub.$emit.calls.argsFor(0);
-
- expect(vm.isMakingRequest).toEqual(true);
- expect(args[0]).toEqual('MRWidgetUpdateRequested');
- expect(args[1]).not.toThrow();
- done();
- }, 333);
- });
- });
- });
-
- it('has merged by information', () => {
- expect(vm.$el.textContent).toContain('Merged by');
- expect(vm.$el.textContent).toContain('Administrator');
- });
-
- it('renders branch information', () => {
- expect(vm.$el.textContent).toContain('The changes were merged into');
- expect(vm.$el.textContent).toContain(targetBranch);
- });
-
- it('renders information about branch being deleted', () => {
- expect(vm.$el.textContent).toContain('The source branch has been deleted');
- });
-
- it('shows revert and cherry-pick buttons', () => {
- expect(vm.$el.textContent).toContain('Revert');
- expect(vm.$el.textContent).toContain('Cherry-pick');
- });
-
- it('shows button to copy commit SHA to clipboard', () => {
- expect(selectors.copyMergeShaButton).toExist();
- expect(selectors.copyMergeShaButton.getAttribute('data-clipboard-text')).toBe(
- vm.mr.mergeCommitSha,
- );
- });
-
- it('hides button to copy commit SHA if SHA does not exist', done => {
- vm.mr.mergeCommitSha = null;
-
- Vue.nextTick(() => {
- expect(selectors.copyMergeShaButton).not.toExist();
- expect(vm.$el.querySelector('.mr-info-list').innerText).not.toContain('with');
- done();
- });
- });
-
- it('shows merge commit SHA link', () => {
- expect(selectors.mergeCommitShaLink).toExist();
- expect(selectors.mergeCommitShaLink.text).toContain(vm.mr.shortMergeCommitSha);
- expect(selectors.mergeCommitShaLink.href).toBe(vm.mr.mergeCommitPath);
- });
-
- it('should not show source branch deleted text', done => {
- vm.mr.sourceBranchRemoved = false;
-
- Vue.nextTick(() => {
- expect(vm.$el.innerText).toContain('You can delete the source branch now');
- expect(vm.$el.innerText).not.toContain('The source branch has been deleted');
- done();
- });
- });
-
- it('should show source branch deleting text', done => {
- vm.mr.isRemovingSourceBranch = true;
- vm.mr.sourceBranchRemoved = false;
-
- Vue.nextTick(() => {
- expect(vm.$el.innerText).toContain('The source branch is being deleted');
- expect(vm.$el.innerText).not.toContain('You can delete the source branch now');
- expect(vm.$el.innerText).not.toContain('The source branch has been deleted');
- done();
- });
- });
-
- it('should use mergedEvent mergedAt as tooltip title', () => {
- expect(vm.$el.querySelector('time').getAttribute('data-original-title')).toBe(
- 'Jan 24, 2018 1:02pm GMT+0000',
- );
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merging_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merging_spec.js
deleted file mode 100644
index 06d236064dd..00000000000
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merging_spec.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import mergingComponent from '~/vue_merge_request_widget/components/states/mr_widget_merging.vue';
-
-describe('MRWidgetMerging', () => {
- let vm;
- beforeEach(() => {
- const Component = Vue.extend(mergingComponent);
-
- vm = mountComponent(Component, {
- mr: {
- targetBranchPath: '/branch-path',
- targetBranch: 'branch',
- },
- });
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('renders information about merge request being merged', () => {
- expect(
- vm.$el
- .querySelector('.media-body')
- .textContent.trim()
- .replace(/\s\s+/g, ' ')
- .replace(/[\r\n]+/g, ' '),
- ).toContain('This merge request is in the process of being merged');
- });
-
- it('renders branch information', () => {
- expect(
- vm.$el
- .querySelector('.mr-info-list')
- .textContent.trim()
- .replace(/\s\s+/g, ' ')
- .replace(/[\r\n]+/g, ' '),
- ).toEqual('The changes will be merged into branch');
-
- expect(vm.$el.querySelector('a').getAttribute('href')).toEqual('/branch-path');
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js
deleted file mode 100644
index 47b989e2022..00000000000
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js
+++ /dev/null
@@ -1,40 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import missingBranchComponent from '~/vue_merge_request_widget/components/states/mr_widget_missing_branch.vue';
-
-describe('MRWidgetMissingBranch', () => {
- let vm;
-
- beforeEach(() => {
- const Component = Vue.extend(missingBranchComponent);
- vm = mountComponent(Component, { mr: { sourceBranchRemoved: true } });
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('computed', () => {
- describe('missingBranchName', () => {
- it('should return proper branch name', () => {
- expect(vm.missingBranchName).toEqual('source');
-
- vm.mr.sourceBranchRemoved = false;
-
- expect(vm.missingBranchName).toEqual('target');
- });
- });
- });
-
- describe('template', () => {
- it('should have correct elements', () => {
- const el = vm.$el;
- const content = el.textContent.replace(/\n(\s)+/g, ' ').trim();
-
- expect(el.classList.contains('mr-widget-body')).toBeTruthy();
- expect(el.querySelector('button').getAttribute('disabled')).toBeTruthy();
- expect(content.replace(/\s\s+/g, ' ')).toContain('source branch does not exist.');
- expect(content).toContain('Please restore it or use a different source branch');
- });
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_not_allowed_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_not_allowed_spec.js
deleted file mode 100644
index b1cb91663c9..00000000000
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_not_allowed_spec.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import notAllowedComponent from '~/vue_merge_request_widget/components/states/mr_widget_not_allowed.vue';
-
-describe('MRWidgetNotAllowed', () => {
- let vm;
- beforeEach(() => {
- const Component = Vue.extend(notAllowedComponent);
- vm = mountComponent(Component);
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('renders success icon', () => {
- expect(vm.$el.querySelector('.ci-status-icon-success')).not.toBe(null);
- });
-
- it('renders informative text', () => {
- expect(vm.$el.innerText).toContain('Ready to be merged automatically.');
- expect(vm.$el.innerText).toContain(
- 'Ask someone with write access to this repository to merge this request',
- );
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js
deleted file mode 100644
index 0bca86b12b2..00000000000
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import { removeBreakLine } from 'spec/helpers/text_helper';
-import pipelineBlockedComponent from '~/vue_merge_request_widget/components/states/mr_widget_pipeline_blocked.vue';
-
-describe('MRWidgetPipelineBlocked', () => {
- let vm;
- beforeEach(() => {
- const Component = Vue.extend(pipelineBlockedComponent);
- vm = mountComponent(Component);
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('renders warning icon', () => {
- expect(vm.$el.querySelector('.ci-status-icon-warning')).not.toBe(null);
- });
-
- it('renders information text', () => {
- expect(removeBreakLine(vm.$el.textContent).trim()).toContain(
- 'Pipeline blocked. The pipeline for this merge request requires a manual action to proceed',
- );
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js
deleted file mode 100644
index 85f65d024a8..00000000000
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import Vue from 'vue';
-import { removeBreakLine } from 'spec/helpers/text_helper';
-import PipelineFailed from '~/vue_merge_request_widget/components/states/pipeline_failed.vue';
-
-describe('PipelineFailed', () => {
- describe('template', () => {
- const Component = Vue.extend(PipelineFailed);
- const vm = new Component({
- el: document.createElement('div'),
- });
- it('should have correct elements', () => {
- expect(vm.$el.classList.contains('mr-widget-body')).toBeTruthy();
- expect(vm.$el.querySelector('button').getAttribute('disabled')).toBeTruthy();
- expect(removeBreakLine(vm.$el.innerText).trim()).toContain(
- 'The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure',
- );
- });
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
deleted file mode 100644
index 9ba429c3d20..00000000000
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
+++ /dev/null
@@ -1,983 +0,0 @@
-import Vue from 'vue';
-import { createLocalVue, shallowMount } from '@vue/test-utils';
-import ReadyToMerge from '~/vue_merge_request_widget/components/states/ready_to_merge.vue';
-import SquashBeforeMerge from '~/vue_merge_request_widget/components/states/squash_before_merge.vue';
-import CommitsHeader from '~/vue_merge_request_widget/components/states/commits_header.vue';
-import CommitEdit from '~/vue_merge_request_widget/components/states/commit_edit.vue';
-import CommitMessageDropdown from '~/vue_merge_request_widget/components/states/commit_message_dropdown.vue';
-import eventHub from '~/vue_merge_request_widget/event_hub';
-import { MWPS_MERGE_STRATEGY, MTWPS_MERGE_STRATEGY } from '~/vue_merge_request_widget/constants';
-
-const commitMessage = 'This is the commit message';
-const squashCommitMessage = 'This is the squash commit message';
-const commitMessageWithDescription = 'This is the commit message description';
-const createTestMr = customConfig => {
- const mr = {
- isPipelineActive: false,
- pipeline: null,
- isPipelineFailed: false,
- isPipelinePassing: false,
- isMergeAllowed: true,
- isApproved: true,
- onlyAllowMergeIfPipelineSucceeds: false,
- ffOnlyEnabled: false,
- hasCI: false,
- ciStatus: null,
- sha: '12345678',
- squash: false,
- commitMessage,
- squashCommitMessage,
- commitMessageWithDescription,
- shouldRemoveSourceBranch: true,
- canRemoveSourceBranch: false,
- targetBranch: 'master',
- preferredAutoMergeStrategy: MWPS_MERGE_STRATEGY,
- availableAutoMergeStrategies: [MWPS_MERGE_STRATEGY],
- };
-
- Object.assign(mr, customConfig.mr);
-
- return mr;
-};
-
-const createTestService = () => ({
- merge() {},
- poll() {},
-});
-
-const createComponent = (customConfig = {}) => {
- const Component = Vue.extend(ReadyToMerge);
-
- return new Component({
- el: document.createElement('div'),
- propsData: {
- mr: createTestMr(customConfig),
- service: createTestService(),
- },
- });
-};
-
-describe('ReadyToMerge', () => {
- let vm;
- let updateMrCountSpy;
-
- beforeEach(() => {
- vm = createComponent();
- updateMrCountSpy = spyOnDependency(ReadyToMerge, 'refreshUserMergeRequestCounts');
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('props', () => {
- it('should have props', () => {
- const { mr, service } = ReadyToMerge.props;
-
- expect(mr.type instanceof Object).toBeTruthy();
- expect(mr.required).toBeTruthy();
-
- expect(service.type instanceof Object).toBeTruthy();
- expect(service.required).toBeTruthy();
- });
- });
-
- describe('data', () => {
- it('should have default data', () => {
- expect(vm.mergeWhenBuildSucceeds).toBeFalsy();
- expect(vm.useCommitMessageWithDescription).toBeFalsy();
- expect(vm.showCommitMessageEditor).toBeFalsy();
- expect(vm.isMakingRequest).toBeFalsy();
- expect(vm.isMergingImmediately).toBeFalsy();
- expect(vm.commitMessage).toBe(vm.mr.commitMessage);
- expect(vm.successSvg).toBeDefined();
- expect(vm.warningSvg).toBeDefined();
- });
- });
-
- describe('computed', () => {
- describe('isAutoMergeAvailable', () => {
- it('should return true when at least one merge strategy is available', () => {
- vm.mr.availableAutoMergeStrategies = [MWPS_MERGE_STRATEGY];
-
- expect(vm.isAutoMergeAvailable).toBe(true);
- });
-
- it('should return false when no merge strategies are available', () => {
- vm.mr.availableAutoMergeStrategies = [];
-
- expect(vm.isAutoMergeAvailable).toBe(false);
- });
- });
-
- describe('status', () => {
- it('defaults to success', () => {
- Vue.set(vm.mr, 'pipeline', true);
- Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
-
- expect(vm.status).toEqual('success');
- });
-
- it('returns failed when MR has CI but also has an unknown status', () => {
- Vue.set(vm.mr, 'hasCI', true);
-
- expect(vm.status).toEqual('failed');
- });
-
- it('returns default when MR has no pipeline', () => {
- Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
-
- expect(vm.status).toEqual('success');
- });
-
- it('returns pending when pipeline is active', () => {
- Vue.set(vm.mr, 'pipeline', {});
- Vue.set(vm.mr, 'isPipelineActive', true);
-
- expect(vm.status).toEqual('pending');
- });
-
- it('returns failed when pipeline is failed', () => {
- Vue.set(vm.mr, 'pipeline', {});
- Vue.set(vm.mr, 'isPipelineFailed', true);
- Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
-
- expect(vm.status).toEqual('failed');
- });
- });
-
- describe('mergeButtonVariant', () => {
- it('defaults to success class', () => {
- Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
-
- expect(vm.mergeButtonVariant).toEqual('success');
- });
-
- it('returns success class for success status', () => {
- Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
- Vue.set(vm.mr, 'pipeline', true);
-
- expect(vm.mergeButtonVariant).toEqual('success');
- });
-
- it('returns info class for pending status', () => {
- Vue.set(vm.mr, 'availableAutoMergeStrategies', [MTWPS_MERGE_STRATEGY]);
-
- expect(vm.mergeButtonVariant).toEqual('info');
- });
-
- it('returns danger class for failed status', () => {
- vm.mr.hasCI = true;
-
- expect(vm.mergeButtonVariant).toEqual('danger');
- });
- });
-
- describe('status icon', () => {
- it('defaults to tick icon', () => {
- expect(vm.iconClass).toEqual('success');
- });
-
- it('shows tick for success status', () => {
- vm.mr.pipeline = true;
-
- expect(vm.iconClass).toEqual('success');
- });
-
- it('shows tick for pending status', () => {
- vm.mr.pipeline = {};
- vm.mr.isPipelineActive = true;
-
- expect(vm.iconClass).toEqual('success');
- });
-
- it('shows warning icon for failed status', () => {
- vm.mr.hasCI = true;
-
- expect(vm.iconClass).toEqual('warning');
- });
-
- it('shows warning icon for merge not allowed', () => {
- vm.mr.hasCI = true;
-
- expect(vm.iconClass).toEqual('warning');
- });
- });
-
- describe('mergeButtonText', () => {
- it('should return "Merge" when no auto merge strategies are available', () => {
- Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
-
- expect(vm.mergeButtonText).toEqual('Merge');
- });
-
- it('should return "Merge in progress"', () => {
- Vue.set(vm, 'isMergingImmediately', true);
-
- expect(vm.mergeButtonText).toEqual('Merge in progress');
- });
-
- it('should return "Merge when pipeline succeeds" when the MWPS auto merge strategy is available', () => {
- Vue.set(vm, 'isMergingImmediately', false);
- Vue.set(vm.mr, 'preferredAutoMergeStrategy', MWPS_MERGE_STRATEGY);
-
- expect(vm.mergeButtonText).toEqual('Merge when pipeline succeeds');
- });
- });
-
- describe('autoMergeText', () => {
- it('should return Merge when pipeline succeeds', () => {
- Vue.set(vm.mr, 'preferredAutoMergeStrategy', MWPS_MERGE_STRATEGY);
-
- expect(vm.autoMergeText).toEqual('Merge when pipeline succeeds');
- });
- });
-
- describe('shouldShowMergeImmediatelyDropdown', () => {
- it('should return false if no pipeline is active', () => {
- Vue.set(vm.mr, 'isPipelineActive', false);
- Vue.set(vm.mr, 'onlyAllowMergeIfPipelineSucceeds', false);
-
- expect(vm.shouldShowMergeImmediatelyDropdown).toBe(false);
- });
-
- it('should return false if "Pipelines must succeed" is enabled for the current project', () => {
- Vue.set(vm.mr, 'isPipelineActive', true);
- Vue.set(vm.mr, 'onlyAllowMergeIfPipelineSucceeds', true);
-
- expect(vm.shouldShowMergeImmediatelyDropdown).toBe(false);
- });
-
- it('should return true if the MR\'s pipeline is active and "Pipelines must succeed" is not enabled for the current project', () => {
- Vue.set(vm.mr, 'isPipelineActive', true);
- Vue.set(vm.mr, 'onlyAllowMergeIfPipelineSucceeds', false);
-
- expect(vm.shouldShowMergeImmediatelyDropdown).toBe(true);
- });
- });
-
- describe('isMergeButtonDisabled', () => {
- it('should return false with initial data', () => {
- Vue.set(vm.mr, 'isMergeAllowed', true);
-
- expect(vm.isMergeButtonDisabled).toBe(false);
- });
-
- it('should return true when there is no commit message', () => {
- Vue.set(vm.mr, 'isMergeAllowed', true);
- Vue.set(vm, 'commitMessage', '');
-
- expect(vm.isMergeButtonDisabled).toBe(true);
- });
-
- it('should return true if merge is not allowed', () => {
- Vue.set(vm.mr, 'isMergeAllowed', false);
- Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
- Vue.set(vm.mr, 'onlyAllowMergeIfPipelineSucceeds', true);
-
- expect(vm.isMergeButtonDisabled).toBe(true);
- });
-
- it('should return true when the vm instance is making request', () => {
- Vue.set(vm.mr, 'isMergeAllowed', true);
- Vue.set(vm, 'isMakingRequest', true);
-
- expect(vm.isMergeButtonDisabled).toBe(true);
- });
- });
-
- describe('isMergeImmediatelyDangerous', () => {
- it('should always return false in CE', () => {
- expect(vm.isMergeImmediatelyDangerous).toBe(false);
- });
- });
- });
-
- describe('methods', () => {
- describe('shouldShowMergeControls', () => {
- it('should return false when an external pipeline is running and required to succeed', () => {
- Vue.set(vm.mr, 'isMergeAllowed', false);
- Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
-
- expect(vm.shouldShowMergeControls).toBe(false);
- });
-
- it('should return true when the build succeeded or build not required to succeed', () => {
- Vue.set(vm.mr, 'isMergeAllowed', true);
- Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
-
- expect(vm.shouldShowMergeControls).toBe(true);
- });
-
- it('should return true when showing the MWPS button and a pipeline is running that needs to be successful', () => {
- Vue.set(vm.mr, 'isMergeAllowed', false);
- Vue.set(vm.mr, 'availableAutoMergeStrategies', [MWPS_MERGE_STRATEGY]);
-
- expect(vm.shouldShowMergeControls).toBe(true);
- });
-
- it('should return true when showing the MWPS button but not required for the pipeline to succeed', () => {
- Vue.set(vm.mr, 'isMergeAllowed', true);
- Vue.set(vm.mr, 'availableAutoMergeStrategies', [MWPS_MERGE_STRATEGY]);
-
- expect(vm.shouldShowMergeControls).toBe(true);
- });
- });
-
- describe('updateMergeCommitMessage', () => {
- it('should revert flag and change commitMessage', () => {
- expect(vm.commitMessage).toEqual(commitMessage);
- vm.updateMergeCommitMessage(true);
-
- expect(vm.commitMessage).toEqual(commitMessageWithDescription);
- vm.updateMergeCommitMessage(false);
-
- expect(vm.commitMessage).toEqual(commitMessage);
- });
- });
-
- describe('handleMergeButtonClick', () => {
- const returnPromise = status =>
- new Promise(resolve => {
- resolve({
- data: {
- status,
- },
- });
- });
-
- it('should handle merge when pipeline succeeds', done => {
- spyOn(eventHub, '$emit');
- spyOn(vm.service, 'merge').and.returnValue(returnPromise('merge_when_pipeline_succeeds'));
- vm.removeSourceBranch = false;
- vm.handleMergeButtonClick(true);
-
- setTimeout(() => {
- expect(vm.isMakingRequest).toBeTruthy();
- expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetUpdateRequested');
-
- const params = vm.service.merge.calls.argsFor(0)[0];
-
- expect(params).toEqual(
- jasmine.objectContaining({
- sha: vm.mr.sha,
- commit_message: vm.mr.commitMessage,
- should_remove_source_branch: false,
- auto_merge_strategy: 'merge_when_pipeline_succeeds',
- }),
- );
- done();
- }, 333);
- });
-
- it('should handle merge failed', done => {
- spyOn(eventHub, '$emit');
- spyOn(vm.service, 'merge').and.returnValue(returnPromise('failed'));
- vm.handleMergeButtonClick(false, true);
-
- setTimeout(() => {
- expect(vm.isMakingRequest).toBeTruthy();
- expect(eventHub.$emit).toHaveBeenCalledWith('FailedToMerge', undefined);
-
- const params = vm.service.merge.calls.argsFor(0)[0];
-
- expect(params.should_remove_source_branch).toBeTruthy();
- expect(params.auto_merge_strategy).toBeUndefined();
- done();
- }, 333);
- });
-
- it('should handle merge action accepted case', done => {
- spyOn(vm.service, 'merge').and.returnValue(returnPromise('success'));
- spyOn(vm, 'initiateMergePolling');
- vm.handleMergeButtonClick();
-
- setTimeout(() => {
- expect(vm.isMakingRequest).toBeTruthy();
- expect(vm.initiateMergePolling).toHaveBeenCalled();
-
- const params = vm.service.merge.calls.argsFor(0)[0];
-
- expect(params.should_remove_source_branch).toBeTruthy();
- expect(params.auto_merge_strategy).toBeUndefined();
- done();
- }, 333);
- });
- });
-
- describe('initiateMergePolling', () => {
- beforeEach(() => {
- jasmine.clock().install();
- });
-
- afterEach(() => {
- jasmine.clock().uninstall();
- });
-
- it('should call simplePoll', () => {
- const simplePoll = spyOnDependency(ReadyToMerge, 'simplePoll');
- vm.initiateMergePolling();
-
- expect(simplePoll).toHaveBeenCalledWith(jasmine.any(Function), { timeout: 0 });
- });
-
- it('should call handleMergePolling', () => {
- spyOn(vm, 'handleMergePolling');
-
- vm.initiateMergePolling();
-
- jasmine.clock().tick(2000);
-
- expect(vm.handleMergePolling).toHaveBeenCalled();
- });
- });
-
- describe('handleMergePolling', () => {
- const returnPromise = state =>
- new Promise(resolve => {
- resolve({
- data: {
- state,
- source_branch_exists: true,
- },
- });
- });
-
- beforeEach(() => {
- loadFixtures('merge_requests/merge_request_of_current_user.html');
- });
-
- it('should call start and stop polling when MR merged', done => {
- spyOn(eventHub, '$emit');
- spyOn(vm.service, 'poll').and.returnValue(returnPromise('merged'));
- spyOn(vm, 'initiateRemoveSourceBranchPolling');
-
- let cpc = false; // continuePollingCalled
- let spc = false; // stopPollingCalled
-
- vm.handleMergePolling(
- () => {
- cpc = true;
- },
- () => {
- spc = true;
- },
- );
- setTimeout(() => {
- expect(vm.service.poll).toHaveBeenCalled();
- expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetUpdateRequested');
- expect(eventHub.$emit).toHaveBeenCalledWith('FetchActionsContent');
- expect(vm.initiateRemoveSourceBranchPolling).toHaveBeenCalled();
- expect(updateMrCountSpy).toHaveBeenCalled();
- expect(cpc).toBeFalsy();
- expect(spc).toBeTruthy();
-
- done();
- }, 333);
- });
-
- it('updates status box', done => {
- spyOn(vm.service, 'poll').and.returnValue(returnPromise('merged'));
- spyOn(vm, 'initiateRemoveSourceBranchPolling');
-
- vm.handleMergePolling(() => {}, () => {});
-
- setTimeout(() => {
- const statusBox = document.querySelector('.status-box');
-
- expect(statusBox.classList.contains('status-box-mr-merged')).toBeTruthy();
- expect(statusBox.textContent).toContain('Merged');
-
- done();
- });
- });
-
- it('hides close button', done => {
- spyOn(vm.service, 'poll').and.returnValue(returnPromise('merged'));
- spyOn(vm, 'initiateRemoveSourceBranchPolling');
-
- vm.handleMergePolling(() => {}, () => {});
-
- setTimeout(() => {
- expect(document.querySelector('.btn-close').classList.contains('hidden')).toBeTruthy();
-
- done();
- });
- });
-
- it('updates merge request count badge', done => {
- spyOn(vm.service, 'poll').and.returnValue(returnPromise('merged'));
- spyOn(vm, 'initiateRemoveSourceBranchPolling');
-
- vm.handleMergePolling(() => {}, () => {});
-
- setTimeout(() => {
- expect(document.querySelector('.js-merge-counter').textContent).toBe('0');
-
- done();
- });
- });
-
- it('should continue polling until MR is merged', done => {
- spyOn(vm.service, 'poll').and.returnValue(returnPromise('some_other_state'));
- spyOn(vm, 'initiateRemoveSourceBranchPolling');
-
- let cpc = false; // continuePollingCalled
- let spc = false; // stopPollingCalled
-
- vm.handleMergePolling(
- () => {
- cpc = true;
- },
- () => {
- spc = true;
- },
- );
- setTimeout(() => {
- expect(cpc).toBeTruthy();
- expect(spc).toBeFalsy();
-
- done();
- }, 333);
- });
- });
-
- describe('initiateRemoveSourceBranchPolling', () => {
- it('should emit event and call simplePoll', () => {
- spyOn(eventHub, '$emit');
- const simplePoll = spyOnDependency(ReadyToMerge, 'simplePoll');
-
- vm.initiateRemoveSourceBranchPolling();
-
- expect(eventHub.$emit).toHaveBeenCalledWith('SetBranchRemoveFlag', [true]);
- expect(simplePoll).toHaveBeenCalled();
- });
- });
-
- describe('handleRemoveBranchPolling', () => {
- const returnPromise = state =>
- new Promise(resolve => {
- resolve({
- data: {
- source_branch_exists: state,
- },
- });
- });
-
- it('should call start and stop polling when MR merged', done => {
- spyOn(eventHub, '$emit');
- spyOn(vm.service, 'poll').and.returnValue(returnPromise(false));
-
- let cpc = false; // continuePollingCalled
- let spc = false; // stopPollingCalled
-
- vm.handleRemoveBranchPolling(
- () => {
- cpc = true;
- },
- () => {
- spc = true;
- },
- );
- setTimeout(() => {
- expect(vm.service.poll).toHaveBeenCalled();
-
- const args = eventHub.$emit.calls.argsFor(0);
-
- expect(args[0]).toEqual('MRWidgetUpdateRequested');
- expect(args[1]).toBeDefined();
- args[1]();
-
- expect(eventHub.$emit).toHaveBeenCalledWith('SetBranchRemoveFlag', [false]);
-
- expect(cpc).toBeFalsy();
- expect(spc).toBeTruthy();
-
- done();
- }, 333);
- });
-
- it('should continue polling until MR is merged', done => {
- spyOn(vm.service, 'poll').and.returnValue(returnPromise(true));
-
- let cpc = false; // continuePollingCalled
- let spc = false; // stopPollingCalled
-
- vm.handleRemoveBranchPolling(
- () => {
- cpc = true;
- },
- () => {
- spc = true;
- },
- );
- setTimeout(() => {
- expect(cpc).toBeTruthy();
- expect(spc).toBeFalsy();
-
- done();
- }, 333);
- });
- });
- });
-
- describe('Remove source branch checkbox', () => {
- describe('when user can merge but cannot delete branch', () => {
- it('should be disabled in the rendered output', () => {
- const checkboxElement = vm.$el.querySelector('#remove-source-branch-input');
-
- expect(checkboxElement).toBeNull();
- });
- });
-
- describe('when user can merge and can delete branch', () => {
- beforeEach(() => {
- vm = createComponent({
- mr: { canRemoveSourceBranch: true },
- });
- });
-
- it('isRemoveSourceBranchButtonDisabled should be false', () => {
- expect(vm.isRemoveSourceBranchButtonDisabled).toBe(false);
- });
-
- it('removed source branch should be enabled in rendered output', () => {
- const checkboxElement = vm.$el.querySelector('#remove-source-branch-input');
-
- expect(checkboxElement).not.toBeNull();
- });
- });
- });
-
- describe('render children components', () => {
- let wrapper;
- const localVue = createLocalVue();
-
- const createLocalComponent = (customConfig = {}) => {
- wrapper = shallowMount(localVue.extend(ReadyToMerge), {
- localVue,
- propsData: {
- mr: createTestMr(customConfig),
- service: createTestService(),
- },
- });
- };
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- const findCheckboxElement = () => wrapper.find(SquashBeforeMerge);
- const findCommitsHeaderElement = () => wrapper.find(CommitsHeader);
- const findCommitEditElements = () => wrapper.findAll(CommitEdit);
- const findCommitDropdownElement = () => wrapper.find(CommitMessageDropdown);
- const findFirstCommitEditLabel = () =>
- findCommitEditElements()
- .at(0)
- .props('label');
-
- describe('squash checkbox', () => {
- it('should be rendered when squash before merge is enabled and there is more than 1 commit', () => {
- createLocalComponent({
- mr: { commitsCount: 2, enableSquashBeforeMerge: true },
- });
-
- expect(findCheckboxElement().exists()).toBeTruthy();
- });
-
- it('should not be rendered when squash before merge is disabled', () => {
- createLocalComponent({ mr: { commitsCount: 2, enableSquashBeforeMerge: false } });
-
- expect(findCheckboxElement().exists()).toBeFalsy();
- });
-
- it('should not be rendered when there is only 1 commit', () => {
- createLocalComponent({ mr: { commitsCount: 1, enableSquashBeforeMerge: true } });
-
- expect(findCheckboxElement().exists()).toBeFalsy();
- });
- });
-
- describe('commits count collapsible header', () => {
- it('should be rendered when fast-forward is disabled', () => {
- createLocalComponent();
-
- expect(findCommitsHeaderElement().exists()).toBeTruthy();
- });
-
- describe('when fast-forward is enabled', () => {
- it('should be rendered if squash and squash before are enabled and there is more than 1 commit', () => {
- createLocalComponent({
- mr: {
- ffOnlyEnabled: true,
- enableSquashBeforeMerge: true,
- squash: true,
- commitsCount: 2,
- },
- });
-
- expect(findCommitsHeaderElement().exists()).toBeTruthy();
- });
-
- it('should not be rendered if squash before merge is disabled', () => {
- createLocalComponent({
- mr: {
- ffOnlyEnabled: true,
- enableSquashBeforeMerge: false,
- squash: true,
- commitsCount: 2,
- },
- });
-
- expect(findCommitsHeaderElement().exists()).toBeFalsy();
- });
-
- it('should not be rendered if squash is disabled', () => {
- createLocalComponent({
- mr: {
- ffOnlyEnabled: true,
- squash: false,
- enableSquashBeforeMerge: true,
- commitsCount: 2,
- },
- });
-
- expect(findCommitsHeaderElement().exists()).toBeFalsy();
- });
-
- it('should not be rendered if commits count is 1', () => {
- createLocalComponent({
- mr: {
- ffOnlyEnabled: true,
- squash: true,
- enableSquashBeforeMerge: true,
- commitsCount: 1,
- },
- });
-
- expect(findCommitsHeaderElement().exists()).toBeFalsy();
- });
- });
- });
-
- describe('commits edit components', () => {
- describe('when fast-forward merge is enabled', () => {
- it('should not be rendered if squash is disabled', () => {
- createLocalComponent({
- mr: {
- ffOnlyEnabled: true,
- squash: false,
- enableSquashBeforeMerge: true,
- commitsCount: 2,
- },
- });
-
- expect(findCommitEditElements().length).toBe(0);
- });
-
- it('should not be rendered if squash before merge is disabled', () => {
- createLocalComponent({
- mr: {
- ffOnlyEnabled: true,
- squash: true,
- enableSquashBeforeMerge: false,
- commitsCount: 2,
- },
- });
-
- expect(findCommitEditElements().length).toBe(0);
- });
-
- it('should not be rendered if there is only one commit', () => {
- createLocalComponent({
- mr: {
- ffOnlyEnabled: true,
- squash: true,
- enableSquashBeforeMerge: true,
- commitsCount: 1,
- },
- });
-
- expect(findCommitEditElements().length).toBe(0);
- });
-
- it('should have one edit component if squash is enabled and there is more than 1 commit', () => {
- createLocalComponent({
- mr: {
- ffOnlyEnabled: true,
- squash: true,
- enableSquashBeforeMerge: true,
- commitsCount: 2,
- },
- });
-
- expect(findCommitEditElements().length).toBe(1);
- expect(findFirstCommitEditLabel()).toBe('Squash commit message');
- });
- });
-
- it('should have one edit component when squash is disabled', () => {
- createLocalComponent();
-
- expect(findCommitEditElements().length).toBe(1);
- });
-
- it('should have two edit components when squash is enabled and there is more than 1 commit', () => {
- createLocalComponent({
- mr: {
- commitsCount: 2,
- squash: true,
- enableSquashBeforeMerge: true,
- },
- });
-
- expect(findCommitEditElements().length).toBe(2);
- });
-
- it('should have one edit components when squash is enabled and there is 1 commit only', () => {
- createLocalComponent({
- mr: {
- commitsCount: 1,
- squash: true,
- enableSquashBeforeMerge: true,
- },
- });
-
- expect(findCommitEditElements().length).toBe(1);
- });
-
- it('should have correct edit merge commit label', () => {
- createLocalComponent();
-
- expect(findFirstCommitEditLabel()).toBe('Merge commit message');
- });
-
- it('should have correct edit squash commit label', () => {
- createLocalComponent({
- mr: {
- commitsCount: 2,
- squash: true,
- enableSquashBeforeMerge: true,
- },
- });
-
- expect(findFirstCommitEditLabel()).toBe('Squash commit message');
- });
- });
-
- describe('commits dropdown', () => {
- it('should not be rendered if squash is disabled', () => {
- createLocalComponent();
-
- expect(findCommitDropdownElement().exists()).toBeFalsy();
- });
-
- it('should be rendered if squash is enabled and there is more than 1 commit', () => {
- createLocalComponent({
- mr: { enableSquashBeforeMerge: true, squash: true, commitsCount: 2 },
- });
-
- expect(findCommitDropdownElement().exists()).toBeTruthy();
- });
- });
- });
-
- describe('Merge controls', () => {
- describe('when allowed to merge', () => {
- beforeEach(() => {
- vm = createComponent({
- mr: { isMergeAllowed: true, canRemoveSourceBranch: true },
- });
- });
-
- it('shows remove source branch checkbox', () => {
- expect(vm.$el.querySelector('.js-remove-source-branch-checkbox')).not.toBeNull();
- });
-
- it('shows modify commit message button', () => {
- expect(vm.$el.querySelector('.js-modify-commit-message-button')).toBeDefined();
- });
-
- it('does not show message about needing to resolve items', () => {
- expect(vm.$el.querySelector('.js-resolve-mr-widget-items-message')).toBeNull();
- });
- });
-
- describe('when not allowed to merge', () => {
- beforeEach(() => {
- vm = createComponent({
- mr: { isMergeAllowed: false },
- });
- });
-
- it('does not show remove source branch checkbox', () => {
- expect(vm.$el.querySelector('.js-remove-source-branch-checkbox')).toBeNull();
- });
-
- it('shows message to resolve all items before being allowed to merge', () => {
- expect(vm.$el.querySelector('.js-resolve-mr-widget-items-message')).toBeDefined();
- });
- });
- });
-
- describe('Merge request project settings', () => {
- describe('when the merge commit merge method is enabled', () => {
- beforeEach(() => {
- vm = createComponent({
- mr: { ffOnlyEnabled: false },
- });
- });
-
- it('should not show fast forward message', () => {
- expect(vm.$el.querySelector('.mr-fast-forward-message')).toBeNull();
- });
-
- it('should show "Modify commit message" button', () => {
- expect(vm.$el.querySelector('.js-modify-commit-message-button')).toBeDefined();
- });
- });
-
- describe('when the fast-forward merge method is enabled', () => {
- beforeEach(() => {
- vm = createComponent({
- mr: { ffOnlyEnabled: true },
- });
- });
-
- it('should show fast forward message', () => {
- expect(vm.$el.querySelector('.mr-fast-forward-message')).toBeDefined();
- });
-
- it('should not show "Modify commit message" button', () => {
- expect(vm.$el.querySelector('.js-modify-commit-message-button')).toBeNull();
- });
- });
- });
-
- describe('with a mismatched SHA', () => {
- const findMismatchShaBlock = () => vm.$el.querySelector('.js-sha-mismatch');
-
- beforeEach(() => {
- vm = createComponent({
- mr: {
- isSHAMismatch: true,
- mergeRequestDiffsPath: '/merge_requests/1/diffs',
- },
- });
- });
-
- it('displays a warning message', () => {
- expect(findMismatchShaBlock()).toExist();
- });
-
- it('warns the user to refresh to review', () => {
- expect(findMismatchShaBlock().textContent.trim()).toBe(
- 'New changes were added. Reload the page to review them',
- );
- });
-
- it('displays link to the diffs tab', () => {
- expect(findMismatchShaBlock().querySelector('a').href).toContain(vm.mr.mergeRequestDiffsPath);
- });
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js
deleted file mode 100644
index 11eb0fef9b2..00000000000
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import { removeBreakLine } from 'spec/helpers/text_helper';
-import ShaMismatch from '~/vue_merge_request_widget/components/states/sha_mismatch.vue';
-
-describe('ShaMismatch', () => {
- let vm;
-
- beforeEach(() => {
- const Component = Vue.extend(ShaMismatch);
- vm = mountComponent(Component);
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('should render information message', () => {
- expect(vm.$el.querySelector('button').disabled).toEqual(true);
-
- expect(removeBreakLine(vm.$el.textContent).trim()).toContain(
- 'The source branch HEAD has recently changed. Please reload the page and review the changes before merging',
- );
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_unresolved_discussions_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_unresolved_discussions_spec.js
deleted file mode 100644
index e8367caa438..00000000000
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_unresolved_discussions_spec.js
+++ /dev/null
@@ -1,45 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import UnresolvedDiscussions from '~/vue_merge_request_widget/components/states/unresolved_discussions.vue';
-
-describe('UnresolvedDiscussions', () => {
- const Component = Vue.extend(UnresolvedDiscussions);
- let vm;
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('with threads path', () => {
- beforeEach(() => {
- vm = mountComponent(Component, {
- mr: {
- createIssueToResolveDiscussionsPath: gl.TEST_HOST,
- },
- });
- });
-
- it('should have correct elements', () => {
- expect(vm.$el.innerText).toContain(
- 'There are unresolved threads. Please resolve these threads',
- );
-
- expect(vm.$el.innerText).toContain('Create an issue to resolve them later');
- expect(vm.$el.querySelector('.js-create-issue').getAttribute('href')).toEqual(gl.TEST_HOST);
- });
- });
-
- describe('without threads path', () => {
- beforeEach(() => {
- vm = mountComponent(Component, { mr: {} });
- });
-
- it('should not show create issue link if user cannot create issue', () => {
- expect(vm.$el.innerText).toContain(
- 'There are unresolved threads. Please resolve these threads',
- );
-
- expect(vm.$el.querySelector('.js-create-issue')).toEqual(null);
- });
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js
deleted file mode 100644
index 9153231b974..00000000000
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js
+++ /dev/null
@@ -1,99 +0,0 @@
-import Vue from 'vue';
-import WorkInProgress from '~/vue_merge_request_widget/components/states/work_in_progress.vue';
-import eventHub from '~/vue_merge_request_widget/event_hub';
-
-const createComponent = () => {
- const Component = Vue.extend(WorkInProgress);
- const mr = {
- title: 'The best MR ever',
- removeWIPPath: '/path/to/remove/wip',
- };
- const service = {
- removeWIP() {},
- };
- return new Component({
- el: document.createElement('div'),
- propsData: { mr, service },
- });
-};
-
-describe('Wip', () => {
- describe('props', () => {
- it('should have props', () => {
- const { mr, service } = WorkInProgress.props;
-
- expect(mr.type instanceof Object).toBeTruthy();
- expect(mr.required).toBeTruthy();
-
- expect(service.type instanceof Object).toBeTruthy();
- expect(service.required).toBeTruthy();
- });
- });
-
- describe('data', () => {
- it('should have default data', () => {
- const vm = createComponent();
-
- expect(vm.isMakingRequest).toBeFalsy();
- });
- });
-
- describe('methods', () => {
- const mrObj = {
- is_new_mr_data: true,
- };
-
- describe('handleRemoveWIP', () => {
- it('should make a request to service and handle response', done => {
- const vm = createComponent();
-
- const flashSpy = spyOnDependency(WorkInProgress, 'createFlash').and.returnValue(true);
- spyOn(eventHub, '$emit');
- spyOn(vm.service, 'removeWIP').and.returnValue(
- new Promise(resolve => {
- resolve({
- data: mrObj,
- });
- }),
- );
-
- vm.handleRemoveWIP();
- setTimeout(() => {
- expect(vm.isMakingRequest).toBeTruthy();
- expect(eventHub.$emit).toHaveBeenCalledWith('UpdateWidgetData', mrObj);
- expect(flashSpy).toHaveBeenCalledWith('The merge request can now be merged.', 'notice');
- done();
- }, 333);
- });
- });
- });
-
- describe('template', () => {
- let vm;
- let el;
-
- beforeEach(() => {
- vm = createComponent();
- el = vm.$el;
- });
-
- it('should have correct elements', () => {
- expect(el.classList.contains('mr-widget-body')).toBeTruthy();
- expect(el.innerText).toContain('This is a Work in Progress');
- expect(el.querySelector('button').getAttribute('disabled')).toBeTruthy();
- expect(el.querySelector('button').innerText).toContain('Merge');
- expect(el.querySelector('.js-remove-wip').innerText.replace(/\s\s+/g, ' ')).toContain(
- 'Resolve WIP status',
- );
- });
-
- it('should not show removeWIP button is user cannot update MR', done => {
- vm.mr.removeWIPPath = '';
-
- Vue.nextTick(() => {
- expect(el.querySelector('.js-remove-wip')).toEqual(null);
- done();
- });
- });
- });
-});
diff --git a/spec/javascripts/vue_mr_widget/mock_data.js b/spec/javascripts/vue_mr_widget/mock_data.js
deleted file mode 100644
index 7783fcb6f93..00000000000
--- a/spec/javascripts/vue_mr_widget/mock_data.js
+++ /dev/null
@@ -1,2 +0,0 @@
-export { default } from '../../frontend/vue_mr_widget/mock_data';
-export * from '../../frontend/vue_mr_widget/mock_data';
diff --git a/spec/javascripts/vue_shared/components/deprecated_modal_2_spec.js b/spec/javascripts/vue_shared/components/deprecated_modal_2_spec.js
deleted file mode 100644
index e031583b43a..00000000000
--- a/spec/javascripts/vue_shared/components/deprecated_modal_2_spec.js
+++ /dev/null
@@ -1,261 +0,0 @@
-import $ from 'jquery';
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import DeprecatedModal2 from '~/vue_shared/components/deprecated_modal_2.vue';
-
-const modalComponent = Vue.extend(DeprecatedModal2);
-
-describe('DeprecatedModal2', () => {
- let vm;
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('props', () => {
- describe('with id', () => {
- const props = {
- id: 'my-modal',
- };
-
- beforeEach(() => {
- vm = mountComponent(modalComponent, props);
- });
-
- it('assigns the id to the modal', () => {
- expect(vm.$el.id).toBe(props.id);
- });
- });
-
- describe('without id', () => {
- beforeEach(() => {
- vm = mountComponent(modalComponent, {});
- });
-
- it('does not add an id attribute to the modal', () => {
- expect(vm.$el.hasAttribute('id')).toBe(false);
- });
- });
-
- describe('with headerTitleText', () => {
- const props = {
- headerTitleText: 'my title text',
- };
-
- beforeEach(() => {
- vm = mountComponent(modalComponent, props);
- });
-
- it('sets the modal title', () => {
- const modalTitle = vm.$el.querySelector('.modal-title');
-
- expect(modalTitle.innerHTML.trim()).toBe(props.headerTitleText);
- });
- });
-
- describe('with footerPrimaryButtonVariant', () => {
- const props = {
- footerPrimaryButtonVariant: 'danger',
- };
-
- beforeEach(() => {
- vm = mountComponent(modalComponent, props);
- });
-
- it('sets the primary button class', () => {
- const primaryButton = vm.$el.querySelector('.modal-footer button:last-of-type');
-
- expect(primaryButton).toHaveClass(`btn-${props.footerPrimaryButtonVariant}`);
- });
- });
-
- describe('with footerPrimaryButtonText', () => {
- const props = {
- footerPrimaryButtonText: 'my button text',
- };
-
- beforeEach(() => {
- vm = mountComponent(modalComponent, props);
- });
-
- it('sets the primary button text', () => {
- const primaryButton = vm.$el.querySelector('.modal-footer button:last-of-type');
-
- expect(primaryButton.innerHTML.trim()).toBe(props.footerPrimaryButtonText);
- });
- });
- });
-
- it('works with data-toggle="modal"', done => {
- setFixtures(`
- <button id="modal-button" data-toggle="modal" data-target="#my-modal"></button>
- <div id="modal-container"></div>
- `);
-
- const modalContainer = document.getElementById('modal-container');
- const modalButton = document.getElementById('modal-button');
- vm = mountComponent(
- modalComponent,
- {
- id: 'my-modal',
- },
- modalContainer,
- );
- $(vm.$el).on('shown.bs.modal', () => done());
-
- modalButton.click();
- });
-
- describe('methods', () => {
- const dummyEvent = 'not really an event';
-
- beforeEach(() => {
- vm = mountComponent(modalComponent, {});
- spyOn(vm, '$emit');
- });
-
- describe('emitCancel', () => {
- it('emits a cancel event', () => {
- vm.emitCancel(dummyEvent);
-
- expect(vm.$emit).toHaveBeenCalledWith('cancel', dummyEvent);
- });
- });
-
- describe('emitSubmit', () => {
- it('emits a submit event', () => {
- vm.emitSubmit(dummyEvent);
-
- expect(vm.$emit).toHaveBeenCalledWith('submit', dummyEvent);
- });
- });
-
- describe('opened', () => {
- it('emits a open event', () => {
- vm.opened();
-
- expect(vm.$emit).toHaveBeenCalledWith('open');
- });
- });
-
- describe('closed', () => {
- it('emits a closed event', () => {
- vm.closed();
-
- expect(vm.$emit).toHaveBeenCalledWith('closed');
- });
- });
- });
-
- describe('slots', () => {
- const slotContent = 'this should go into the slot';
- const modalWithSlot = slotName => {
- let template;
- if (slotName) {
- template = `
- <deprecated-modal-2>
- <template slot="${slotName}">${slotContent}</template>
- </deprecated-modal-2>
- `;
- } else {
- template = `<deprecated-modal-2>${slotContent}</deprecated-modal-2>`;
- }
-
- return Vue.extend({
- components: {
- DeprecatedModal2,
- },
- template,
- });
- };
-
- describe('default slot', () => {
- beforeEach(() => {
- vm = mountComponent(modalWithSlot());
- });
-
- it('sets the modal body', () => {
- const modalBody = vm.$el.querySelector('.modal-body');
-
- expect(modalBody.innerHTML).toBe(slotContent);
- });
- });
-
- describe('header slot', () => {
- beforeEach(() => {
- vm = mountComponent(modalWithSlot('header'));
- });
-
- it('sets the modal header', () => {
- const modalHeader = vm.$el.querySelector('.modal-header');
-
- expect(modalHeader.innerHTML).toBe(slotContent);
- });
- });
-
- describe('title slot', () => {
- beforeEach(() => {
- vm = mountComponent(modalWithSlot('title'));
- });
-
- it('sets the modal title', () => {
- const modalTitle = vm.$el.querySelector('.modal-title');
-
- expect(modalTitle.innerHTML).toBe(slotContent);
- });
- });
-
- describe('footer slot', () => {
- beforeEach(() => {
- vm = mountComponent(modalWithSlot('footer'));
- });
-
- it('sets the modal footer', () => {
- const modalFooter = vm.$el.querySelector('.modal-footer');
-
- expect(modalFooter.innerHTML).toBe(slotContent);
- });
- });
- });
-
- describe('handling sizes', () => {
- it('should render modal-sm', () => {
- vm = mountComponent(modalComponent, {
- modalSize: 'sm',
- });
-
- expect(vm.$el.querySelector('.modal-dialog').classList.contains('modal-sm')).toEqual(true);
- });
-
- it('should render modal-lg', () => {
- vm = mountComponent(modalComponent, {
- modalSize: 'lg',
- });
-
- expect(vm.$el.querySelector('.modal-dialog').classList.contains('modal-lg')).toEqual(true);
- });
-
- it('should render modal-xl', () => {
- vm = mountComponent(modalComponent, {
- modalSize: 'xl',
- });
-
- expect(vm.$el.querySelector('.modal-dialog').classList.contains('modal-xl')).toEqual(true);
- });
-
- it('should not add modal size classes when md size is passed', () => {
- vm = mountComponent(modalComponent, {
- modalSize: 'md',
- });
-
- expect(vm.$el.querySelector('.modal-dialog').classList.contains('modal-md')).toEqual(false);
- });
-
- it('should not add modal size classes by default', () => {
- vm = mountComponent(modalComponent, {});
-
- expect(vm.$el.querySelector('.modal-dialog').classList.contains('modal-sm')).toEqual(false);
- expect(vm.$el.querySelector('.modal-dialog').classList.contains('modal-lg')).toEqual(false);
- });
- });
-});
diff --git a/spec/javascripts/vue_shared/components/deprecated_modal_spec.js b/spec/javascripts/vue_shared/components/deprecated_modal_spec.js
deleted file mode 100644
index d6c10e32794..00000000000
--- a/spec/javascripts/vue_shared/components/deprecated_modal_spec.js
+++ /dev/null
@@ -1,71 +0,0 @@
-import $ from 'jquery';
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import DeprecatedModal from '~/vue_shared/components/deprecated_modal.vue';
-
-const modalComponent = Vue.extend(DeprecatedModal);
-
-describe('DeprecatedModal', () => {
- let vm;
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('props', () => {
- describe('without primaryButtonLabel', () => {
- beforeEach(() => {
- vm = mountComponent(modalComponent, {
- primaryButtonLabel: null,
- });
- });
-
- it('does not render a primary button', () => {
- expect(vm.$el.querySelector('.js-primary-button')).toBeNull();
- });
- });
-
- describe('with id', () => {
- describe('does not render a primary button', () => {
- beforeEach(() => {
- vm = mountComponent(modalComponent, {
- id: 'my-modal',
- });
- });
-
- it('assigns the id to the modal', () => {
- expect(vm.$el.querySelector('#my-modal.modal')).not.toBeNull();
- });
-
- it('does not show the modal immediately', () => {
- expect(vm.$el.querySelector('#my-modal.modal')).not.toHaveClass('show');
- });
-
- it('does not show a backdrop', () => {
- expect(vm.$el.querySelector('modal-backdrop')).toBeNull();
- });
- });
- });
-
- it('works with data-toggle="modal"', done => {
- setFixtures(`
- <button id="modal-button" data-toggle="modal" data-target="#my-modal"></button>
- <div id="modal-container"></div>
- `);
-
- const modalContainer = document.getElementById('modal-container');
- const modalButton = document.getElementById('modal-button');
- vm = mountComponent(
- modalComponent,
- {
- id: 'my-modal',
- },
- modalContainer,
- );
- const modalElement = vm.$el.querySelector('#my-modal');
- $(modalElement).on('shown.bs.modal', () => done());
-
- modalButton.click();
- });
- });
-});
diff --git a/spec/javascripts/vue_shared/components/file_finder/index_spec.js b/spec/javascripts/vue_shared/components/file_finder/index_spec.js
deleted file mode 100644
index 7ded228d3ea..00000000000
--- a/spec/javascripts/vue_shared/components/file_finder/index_spec.js
+++ /dev/null
@@ -1,368 +0,0 @@
-import Vue from 'vue';
-import Mousetrap from 'mousetrap';
-import { file } from 'spec/ide/helpers';
-import timeoutPromise from 'spec/helpers/set_timeout_promise_helper';
-import FindFileComponent from '~/vue_shared/components/file_finder/index.vue';
-import { UP_KEY_CODE, DOWN_KEY_CODE, ENTER_KEY_CODE, ESC_KEY_CODE } from '~/lib/utils/keycodes';
-
-describe('File finder item spec', () => {
- const Component = Vue.extend(FindFileComponent);
- let vm;
-
- function createComponent(props) {
- vm = new Component({
- propsData: {
- files: [],
- visible: true,
- loading: false,
- ...props,
- },
- });
-
- vm.$mount('#app');
- }
-
- beforeEach(() => {
- setFixtures('<div id="app"></div>');
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('with entries', () => {
- beforeEach(done => {
- createComponent({
- files: [
- {
- ...file('index.js'),
- path: 'index.js',
- type: 'blob',
- url: '/index.jsurl',
- },
- {
- ...file('component.js'),
- path: 'component.js',
- type: 'blob',
- },
- ],
- });
-
- setTimeout(done);
- });
-
- it('renders list of blobs', () => {
- expect(vm.$el.textContent).toContain('index.js');
- expect(vm.$el.textContent).toContain('component.js');
- expect(vm.$el.textContent).not.toContain('folder');
- });
-
- it('filters entries', done => {
- vm.searchText = 'index';
-
- setTimeout(() => {
- expect(vm.$el.textContent).toContain('index.js');
- expect(vm.$el.textContent).not.toContain('component.js');
-
- done();
- });
- });
-
- it('shows clear button when searchText is not empty', done => {
- vm.searchText = 'index';
-
- setTimeout(() => {
- expect(vm.$el.querySelector('.dropdown-input').classList).toContain('has-value');
- expect(vm.$el.querySelector('.dropdown-input-search').classList).toContain('hidden');
-
- done();
- });
- });
-
- it('clear button resets searchText', done => {
- vm.searchText = 'index';
-
- timeoutPromise()
- .then(() => {
- vm.$el.querySelector('.dropdown-input-clear').click();
- })
- .then(timeoutPromise)
- .then(() => {
- expect(vm.searchText).toBe('');
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('clear button focues search input', done => {
- spyOn(vm.$refs.searchInput, 'focus');
- vm.searchText = 'index';
-
- timeoutPromise()
- .then(() => {
- vm.$el.querySelector('.dropdown-input-clear').click();
- })
- .then(timeoutPromise)
- .then(() => {
- expect(vm.$refs.searchInput.focus).toHaveBeenCalled();
- })
- .then(done)
- .catch(done.fail);
- });
-
- describe('listShowCount', () => {
- it('returns 1 when no filtered entries exist', done => {
- vm.searchText = 'testing 123';
-
- setTimeout(() => {
- expect(vm.listShowCount).toBe(1);
-
- done();
- });
- });
-
- it('returns entries length when not filtered', () => {
- expect(vm.listShowCount).toBe(2);
- });
- });
-
- describe('listHeight', () => {
- it('returns 55 when entries exist', () => {
- expect(vm.listHeight).toBe(55);
- });
-
- it('returns 33 when entries dont exist', done => {
- vm.searchText = 'testing 123';
-
- setTimeout(() => {
- expect(vm.listHeight).toBe(33);
-
- done();
- });
- });
- });
-
- describe('filteredBlobsLength', () => {
- it('returns length of filtered blobs', done => {
- vm.searchText = 'index';
-
- setTimeout(() => {
- expect(vm.filteredBlobsLength).toBe(1);
-
- done();
- });
- });
- });
-
- describe('watches', () => {
- describe('searchText', () => {
- it('resets focusedIndex when updated', done => {
- vm.focusedIndex = 1;
- vm.searchText = 'test';
-
- setTimeout(() => {
- expect(vm.focusedIndex).toBe(0);
-
- done();
- });
- });
- });
-
- describe('visible', () => {
- it('returns searchText when false', done => {
- vm.searchText = 'test';
- vm.visible = true;
-
- timeoutPromise()
- .then(() => {
- vm.visible = false;
- })
- .then(timeoutPromise)
- .then(() => {
- expect(vm.searchText).toBe('');
- })
- .then(done)
- .catch(done.fail);
- });
- });
- });
-
- describe('openFile', () => {
- beforeEach(() => {
- spyOn(vm, '$emit');
- });
-
- it('closes file finder', () => {
- vm.openFile(vm.files[0]);
-
- expect(vm.$emit).toHaveBeenCalledWith('toggle', false);
- });
-
- it('pushes to router', () => {
- vm.openFile(vm.files[0]);
-
- expect(vm.$emit).toHaveBeenCalledWith('click', vm.files[0]);
- });
- });
-
- describe('onKeyup', () => {
- it('opens file on enter key', done => {
- const event = new CustomEvent('keyup');
- event.keyCode = ENTER_KEY_CODE;
-
- spyOn(vm, 'openFile');
-
- vm.$refs.searchInput.dispatchEvent(event);
-
- setTimeout(() => {
- expect(vm.openFile).toHaveBeenCalledWith(vm.files[0]);
-
- done();
- });
- });
-
- it('closes file finder on esc key', done => {
- const event = new CustomEvent('keyup');
- event.keyCode = ESC_KEY_CODE;
-
- spyOn(vm, '$emit');
-
- vm.$refs.searchInput.dispatchEvent(event);
-
- setTimeout(() => {
- expect(vm.$emit).toHaveBeenCalledWith('toggle', false);
-
- done();
- });
- });
- });
-
- describe('onKeyDown', () => {
- let el;
-
- beforeEach(() => {
- el = vm.$refs.searchInput;
- });
-
- describe('up key', () => {
- const event = new CustomEvent('keydown');
- event.keyCode = UP_KEY_CODE;
-
- it('resets to last index when at top', () => {
- el.dispatchEvent(event);
-
- expect(vm.focusedIndex).toBe(1);
- });
-
- it('minus 1 from focusedIndex', () => {
- vm.focusedIndex = 1;
-
- el.dispatchEvent(event);
-
- expect(vm.focusedIndex).toBe(0);
- });
- });
-
- describe('down key', () => {
- const event = new CustomEvent('keydown');
- event.keyCode = DOWN_KEY_CODE;
-
- it('resets to first index when at bottom', () => {
- vm.focusedIndex = 1;
- el.dispatchEvent(event);
-
- expect(vm.focusedIndex).toBe(0);
- });
-
- it('adds 1 to focusedIndex', () => {
- el.dispatchEvent(event);
-
- expect(vm.focusedIndex).toBe(1);
- });
- });
- });
- });
-
- describe('without entries', () => {
- it('renders loading text when loading', () => {
- createComponent({
- loading: true,
- });
-
- expect(vm.$el.textContent).toContain('Loading...');
- });
-
- it('renders no files text', () => {
- createComponent();
-
- expect(vm.$el.textContent).toContain('No files found.');
- });
- });
-
- describe('keyboard shortcuts', () => {
- beforeEach(done => {
- createComponent();
-
- spyOn(vm, 'toggle');
-
- vm.$nextTick(done);
- });
-
- it('calls toggle on `t` key press', done => {
- Mousetrap.trigger('t');
-
- vm.$nextTick()
- .then(() => {
- expect(vm.toggle).toHaveBeenCalled();
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('calls toggle on `command+p` key press', done => {
- Mousetrap.trigger('command+p');
-
- vm.$nextTick()
- .then(() => {
- expect(vm.toggle).toHaveBeenCalled();
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('calls toggle on `ctrl+p` key press', done => {
- Mousetrap.trigger('ctrl+p');
-
- vm.$nextTick()
- .then(() => {
- expect(vm.toggle).toHaveBeenCalled();
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('always allows `command+p` to trigger toggle', () => {
- expect(
- vm.mousetrapStopCallback(null, vm.$el.querySelector('.dropdown-input-field'), 'command+p'),
- ).toBe(false);
- });
-
- it('always allows `ctrl+p` to trigger toggle', () => {
- expect(
- vm.mousetrapStopCallback(null, vm.$el.querySelector('.dropdown-input-field'), 'ctrl+p'),
- ).toBe(false);
- });
-
- it('onlys handles `t` when focused in input-field', () => {
- expect(
- vm.mousetrapStopCallback(null, vm.$el.querySelector('.dropdown-input-field'), 't'),
- ).toBe(true);
- });
-
- it('stops callback in monaco editor', () => {
- setFixtures('<div class="inputarea"></div>');
-
- expect(vm.mousetrapStopCallback(null, document.querySelector('.inputarea'), 't')).toBe(true);
- });
- });
-});
diff --git a/spec/javascripts/vue_shared/components/icon_spec.js b/spec/javascripts/vue_shared/components/icon_spec.js
deleted file mode 100644
index 5a3e483fb03..00000000000
--- a/spec/javascripts/vue_shared/components/icon_spec.js
+++ /dev/null
@@ -1,73 +0,0 @@
-import Vue from 'vue';
-import { mount } from '@vue/test-utils';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import Icon from '~/vue_shared/components/icon.vue';
-
-describe('Sprite Icon Component', function() {
- describe('Initialization', function() {
- let icon;
-
- beforeEach(function() {
- const IconComponent = Vue.extend(Icon);
-
- icon = mountComponent(IconComponent, {
- name: 'commit',
- size: 32,
- });
- });
-
- afterEach(() => {
- icon.$destroy();
- });
-
- it('should return a defined Vue component', function() {
- expect(icon).toBeDefined();
- });
-
- it('should have <svg> as a child element', function() {
- expect(icon.$el.tagName).toBe('svg');
- });
-
- it('should have <use> as a child element with the correct href', function() {
- expect(icon.$el.firstChild.tagName).toBe('use');
- expect(icon.$el.firstChild.getAttribute('xlink:href')).toBe(`${gon.sprite_icons}#commit`);
- });
-
- it('should properly compute iconSizeClass', function() {
- expect(icon.iconSizeClass).toBe('s32');
- });
-
- it('forbids invalid size prop', () => {
- expect(icon.$options.props.size.validator(NaN)).toBeFalsy();
- expect(icon.$options.props.size.validator(0)).toBeFalsy();
- expect(icon.$options.props.size.validator(9001)).toBeFalsy();
- });
-
- it('should properly render img css', function() {
- const { classList } = icon.$el;
- const containsSizeClass = classList.contains('s32');
-
- expect(containsSizeClass).toBe(true);
- });
-
- it('`name` validator should return false for non existing icons', () => {
- expect(Icon.props.name.validator('non_existing_icon_sprite')).toBe(false);
- });
-
- it('`name` validator should return false for existing icons', () => {
- expect(Icon.props.name.validator('commit')).toBe(true);
- });
- });
-
- it('should call registered listeners when they are triggered', () => {
- const clickHandler = jasmine.createSpy('clickHandler');
- const wrapper = mount(Icon, {
- propsData: { name: 'commit' },
- listeners: { click: clickHandler },
- });
-
- wrapper.find('svg').trigger('click');
-
- expect(clickHandler).toHaveBeenCalled();
- });
-});
diff --git a/spec/javascripts/vue_shared/components/issue/related_issuable_mock_data.js b/spec/javascripts/vue_shared/components/issue/related_issuable_mock_data.js
deleted file mode 100644
index 3c42f0c2aa9..00000000000
--- a/spec/javascripts/vue_shared/components/issue/related_issuable_mock_data.js
+++ /dev/null
@@ -1 +0,0 @@
-export * from '../../../../frontend/vue_shared/components/issue/related_issuable_mock_data';
diff --git a/spec/javascripts/vue_shared/components/panel_resizer_spec.js b/spec/javascripts/vue_shared/components/panel_resizer_spec.js
deleted file mode 100644
index d65ee8eeb2d..00000000000
--- a/spec/javascripts/vue_shared/components/panel_resizer_spec.js
+++ /dev/null
@@ -1,85 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import panelResizer from '~/vue_shared/components/panel_resizer.vue';
-
-describe('Panel Resizer component', () => {
- let vm;
- let PanelResizer;
-
- const triggerEvent = (eventName, el = vm.$el, clientX = 0) => {
- const event = document.createEvent('MouseEvents');
- event.initMouseEvent(
- eventName,
- true,
- true,
- window,
- 1,
- clientX,
- 0,
- clientX,
- 0,
- false,
- false,
- false,
- false,
- 0,
- null,
- );
-
- el.dispatchEvent(event);
- };
-
- beforeEach(() => {
- PanelResizer = Vue.extend(panelResizer);
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('should render a div element with the correct classes and styles', () => {
- vm = mountComponent(PanelResizer, {
- startSize: 100,
- side: 'left',
- });
-
- expect(vm.$el.tagName).toEqual('DIV');
- expect(vm.$el.getAttribute('class')).toBe(
- 'position-absolute position-top-0 position-bottom-0 drag-handle position-left-0',
- );
-
- expect(vm.$el.getAttribute('style')).toBe('cursor: ew-resize;');
- });
-
- it('should render a div element with the correct classes for a right side panel', () => {
- vm = mountComponent(PanelResizer, {
- startSize: 100,
- side: 'right',
- });
-
- expect(vm.$el.tagName).toEqual('DIV');
- expect(vm.$el.getAttribute('class')).toBe(
- 'position-absolute position-top-0 position-bottom-0 drag-handle position-right-0',
- );
- });
-
- it('drag the resizer', () => {
- vm = mountComponent(PanelResizer, {
- startSize: 100,
- side: 'left',
- });
-
- spyOn(vm, '$emit');
- triggerEvent('mousedown', vm.$el);
- triggerEvent('mousemove', document);
- triggerEvent('mouseup', document);
-
- expect(vm.$emit.calls.allArgs()).toEqual([
- ['resize-start', 100],
- ['update:size', 100],
- ['resize-end', 100],
- ]);
-
- expect(vm.size).toBe(100);
- });
-});
diff --git a/spec/javascripts/vue_shared/components/smart_virtual_list_spec.js b/spec/javascripts/vue_shared/components/smart_virtual_list_spec.js
deleted file mode 100644
index 47ebdc505c9..00000000000
--- a/spec/javascripts/vue_shared/components/smart_virtual_list_spec.js
+++ /dev/null
@@ -1,83 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import SmartVirtualScrollList from '~/vue_shared/components/smart_virtual_list.vue';
-
-describe('Toggle Button', () => {
- let vm;
-
- const createComponent = ({ length, remain }) => {
- const smartListProperties = {
- rtag: 'section',
- wtag: 'ul',
- wclass: 'test-class',
- // Size in pixels does not matter for our tests here
- size: 35,
- length,
- remain,
- };
-
- const Component = Vue.extend({
- components: {
- SmartVirtualScrollList,
- },
- smartListProperties,
- items: Array(length).fill(1),
- template: `
- <smart-virtual-scroll-list v-bind="$options.smartListProperties">
- <li v-for="(val, key) in $options.items" :key="key">{{ key + 1 }}</li>
- </smart-virtual-scroll-list>`,
- });
-
- return mountComponent(Component);
- };
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('if the list is shorter than the maximum shown elements', () => {
- const listLength = 10;
-
- beforeEach(() => {
- vm = createComponent({ length: listLength, remain: 20 });
- });
-
- it('renders without the vue-virtual-scroll-list component', () => {
- expect(vm.$el.classList).not.toContain('js-virtual-list');
- expect(vm.$el.classList).toContain('js-plain-element');
- });
-
- it('renders list with provided tags and classes for the wrapper elements', () => {
- expect(vm.$el.tagName).toEqual('SECTION');
- expect(vm.$el.firstChild.tagName).toEqual('UL');
- expect(vm.$el.firstChild.classList).toContain('test-class');
- });
-
- it('renders all children list elements', () => {
- expect(vm.$el.querySelectorAll('li').length).toEqual(listLength);
- });
- });
-
- describe('if the list is longer than the maximum shown elements', () => {
- const maxItemsShown = 20;
-
- beforeEach(() => {
- vm = createComponent({ length: 1000, remain: maxItemsShown });
- });
-
- it('uses the vue-virtual-scroll-list component', () => {
- expect(vm.$el.classList).toContain('js-virtual-list');
- expect(vm.$el.classList).not.toContain('js-plain-element');
- });
-
- it('renders list with provided tags and classes for the wrapper elements', () => {
- expect(vm.$el.tagName).toEqual('SECTION');
- expect(vm.$el.firstChild.tagName).toEqual('UL');
- expect(vm.$el.firstChild.classList).toContain('test-class');
- });
-
- it('renders at max twice the maximum shown elements', () => {
- expect(vm.$el.querySelectorAll('li').length).toBeLessThanOrEqual(2 * maxItemsShown);
- });
- });
-});
diff --git a/spec/javascripts/vue_shared/directives/autofocusonshow_spec.js b/spec/javascripts/vue_shared/directives/autofocusonshow_spec.js
deleted file mode 100644
index f1ca5f61496..00000000000
--- a/spec/javascripts/vue_shared/directives/autofocusonshow_spec.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import autofocusonshow from '~/vue_shared/directives/autofocusonshow';
-
-/**
- * We're testing this directive's hooks as pure functions
- * since behaviour of this directive is highly-dependent
- * on underlying DOM methods.
- */
-describe('AutofocusOnShow directive', () => {
- describe('with input invisible on component render', () => {
- let el;
-
- beforeAll(() => {
- setFixtures('<div id="container" style="display: none;"><input id="inputel"/></div>');
- el = document.querySelector('#inputel');
- });
-
- it('should bind IntersectionObserver on input element', () => {
- spyOn(el, 'focus');
-
- autofocusonshow.inserted(el);
-
- expect(el.visibilityObserver).toBeDefined();
- expect(el.focus).not.toHaveBeenCalled();
- });
-
- it('should stop IntersectionObserver on input element on unbind hook', () => {
- el.visibilityObserver = {
- disconnect: () => {},
- };
- spyOn(el.visibilityObserver, 'disconnect');
-
- autofocusonshow.unbind(el);
-
- expect(el.visibilityObserver).toBeDefined();
- expect(el.visibilityObserver.disconnect).toHaveBeenCalled();
- });
- });
-});
diff --git a/spec/javascripts/vue_shared/directives/tooltip_spec.js b/spec/javascripts/vue_shared/directives/tooltip_spec.js
deleted file mode 100644
index 1d516a280b0..00000000000
--- a/spec/javascripts/vue_shared/directives/tooltip_spec.js
+++ /dev/null
@@ -1,89 +0,0 @@
-import $ from 'jquery';
-import Vue from 'vue';
-import tooltip from '~/vue_shared/directives/tooltip';
-
-describe('Tooltip directive', () => {
- let vm;
-
- afterEach(() => {
- if (vm) {
- vm.$destroy();
- }
- });
-
- describe('with a single tooltip', () => {
- beforeEach(() => {
- setFixtures('<div id="dummy-element"></div>');
- vm = new Vue({
- el: '#dummy-element',
- directives: {
- tooltip,
- },
- data() {
- return {
- tooltip: 'some text',
- };
- },
- template: '<div v-tooltip :title="tooltip"></div>',
- });
- });
-
- it('should have tooltip plugin applied', () => {
- expect($(vm.$el).data('bs.tooltip')).toBeDefined();
- });
-
- it('displays the title as tooltip', () => {
- $(vm.$el).tooltip('show');
- const tooltipElement = document.querySelector('.tooltip-inner');
-
- expect(tooltipElement.innerText).toContain('some text');
- });
-
- it('updates a visible tooltip', done => {
- $(vm.$el).tooltip('show');
- const tooltipElement = document.querySelector('.tooltip-inner');
-
- vm.tooltip = 'other text';
-
- Vue.nextTick()
- .then(() => {
- expect(tooltipElement).toContainText('other text');
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('with multiple tooltips', () => {
- beforeEach(() => {
- const SomeComponent = Vue.extend({
- directives: {
- tooltip,
- },
- template: `
- <div>
- <div
- v-tooltip
- class="js-look-for-tooltip"
- title="foo">
- </div>
- <div
- v-tooltip
- title="bar">
- </div>
- </div>
- `,
- });
-
- vm = new SomeComponent().$mount();
- });
-
- it('should have tooltip plugin applied to all instances', () => {
- expect(
- $(vm.$el)
- .find('.js-look-for-tooltip')
- .data('bs.tooltip'),
- ).toBeDefined();
- });
- });
-});
diff --git a/spec/javascripts/vue_shared/translate_spec.js b/spec/javascripts/vue_shared/translate_spec.js
deleted file mode 100644
index adca7cd64a1..00000000000
--- a/spec/javascripts/vue_shared/translate_spec.js
+++ /dev/null
@@ -1,251 +0,0 @@
-import Vue from 'vue';
-import Jed from 'jed';
-
-import { trimText } from 'spec/helpers/text_helper';
-import locale from '~/locale';
-import Translate from '~/vue_shared/translate';
-
-describe('Vue translate filter', () => {
- let el;
-
- const createTranslationMock = (key, ...translations) => {
- const fakeLocale = new Jed({
- domain: 'app',
- locale_data: {
- app: {
- '': {
- domain: 'app',
- lang: 'vo',
- plural_forms: 'nplurals=2; plural=(n != 1);',
- },
- [key]: translations,
- },
- },
- });
-
- // eslint-disable-next-line no-underscore-dangle
- locale.__Rewire__('locale', fakeLocale);
- };
-
- afterEach(() => {
- // eslint-disable-next-line no-underscore-dangle
- locale.__ResetDependency__('locale');
- });
-
- beforeEach(() => {
- Vue.use(Translate);
-
- el = document.createElement('div');
-
- document.body.appendChild(el);
- });
-
- it('translate singular text (`__`)', done => {
- const key = 'singular';
- const translation = 'singular_translated';
- createTranslationMock(key, translation);
-
- const vm = new Vue({
- el,
- template: `
- <span>
- {{ __('${key}') }}
- </span>
- `,
- }).$mount();
-
- Vue.nextTick(() => {
- expect(trimText(vm.$el.textContent)).toBe(translation);
-
- done();
- });
- });
-
- it('translate plural text (`n__`) without any substituting text', done => {
- const key = 'plural';
- const translationPlural = 'plural_multiple translation';
- createTranslationMock(key, 'plural_singular translation', translationPlural);
-
- const vm = new Vue({
- el,
- template: `
- <span>
- {{ n__('${key}', 'plurals', 2) }}
- </span>
- `,
- }).$mount();
-
- Vue.nextTick(() => {
- expect(trimText(vm.$el.textContent)).toBe(translationPlural);
-
- done();
- });
- });
-
- describe('translate plural text (`n__`) with substituting %d', () => {
- const key = '%d day';
-
- beforeEach(() => {
- createTranslationMock(key, '%d singular translated', '%d plural translated');
- });
-
- it('and n === 1', done => {
- const vm = new Vue({
- el,
- template: `
- <span>
- {{ n__('${key}', '%d days', 1) }}
- </span>
- `,
- }).$mount();
-
- Vue.nextTick(() => {
- expect(trimText(vm.$el.textContent)).toBe('1 singular translated');
-
- done();
- });
- });
-
- it('and n > 1', done => {
- const vm = new Vue({
- el,
- template: `
- <span>
- {{ n__('${key}', '%d days', 2) }}
- </span>
- `,
- }).$mount();
-
- Vue.nextTick(() => {
- expect(trimText(vm.$el.textContent)).toBe('2 plural translated');
-
- done();
- });
- });
- });
-
- describe('translates text with context `s__`', () => {
- const key = 'Context|Foobar';
- const translation = 'Context|Foobar translated';
- const expectation = 'Foobar translated';
-
- beforeEach(() => {
- createTranslationMock(key, translation);
- });
-
- it('and using two parameters', done => {
- const vm = new Vue({
- el,
- template: `
- <span>
- {{ s__('Context', 'Foobar') }}
- </span>
- `,
- }).$mount();
-
- Vue.nextTick(() => {
- expect(trimText(vm.$el.textContent)).toBe(expectation);
-
- done();
- });
- });
-
- it('and using the pipe syntax', done => {
- const vm = new Vue({
- el,
- template: `
- <span>
- {{ s__('${key}') }}
- </span>
- `,
- }).$mount();
-
- Vue.nextTick(() => {
- expect(trimText(vm.$el.textContent)).toBe(expectation);
-
- done();
- });
- });
- });
-
- it('translate multi line text', done => {
- const translation = 'multiline string translated';
- createTranslationMock('multiline string', translation);
-
- const vm = new Vue({
- el,
- template: `
- <span>
- {{ __(\`
- multiline
- string
- \`) }}
- </span>
- `,
- }).$mount();
-
- Vue.nextTick(() => {
- expect(trimText(vm.$el.textContent)).toBe(translation);
-
- done();
- });
- });
-
- it('translate pluralized multi line text', done => {
- const translation = 'multiline string plural';
-
- createTranslationMock('multiline string', 'multiline string singular', translation);
-
- const vm = new Vue({
- el,
- template: `
- <span>
- {{ n__(
- \`
- multiline
- string
- \`,
- \`
- multiline
- strings
- \`,
- 2
- ) }}
- </span>
- `,
- }).$mount();
-
- Vue.nextTick(() => {
- expect(trimText(vm.$el.textContent)).toBe(translation);
-
- done();
- });
- });
-
- it('translate pluralized multi line text with context', done => {
- const translation = 'multiline string with context';
-
- createTranslationMock('Context| multiline string', translation);
-
- const vm = new Vue({
- el,
- template: `
- <span>
- {{ s__(
- \`
- Context|
- multiline
- string
- \`
- ) }}
- </span>
- `,
- }).$mount();
-
- Vue.nextTick(() => {
- expect(trimText(vm.$el.textContent)).toBe(translation);
-
- done();
- });
- });
-});
diff --git a/spec/javascripts/vuex_shared/modules/modal/actions_spec.js b/spec/javascripts/vuex_shared/modules/modal/actions_spec.js
deleted file mode 100644
index 2c4cb845424..00000000000
--- a/spec/javascripts/vuex_shared/modules/modal/actions_spec.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import testAction from 'spec/helpers/vuex_action_helper';
-import * as types from '~/vuex_shared/modules/modal/mutation_types';
-import * as actions from '~/vuex_shared/modules/modal/actions';
-
-describe('Vuex ModalModule actions', () => {
- describe('open', () => {
- it('works', done => {
- const data = { id: 7 };
-
- testAction(actions.open, data, {}, [{ type: types.OPEN, payload: data }], [], done);
- });
- });
-
- describe('close', () => {
- it('works', done => {
- testAction(actions.close, null, {}, [{ type: types.CLOSE }], [], done);
- });
- });
-
- describe('show', () => {
- it('works', done => {
- testAction(actions.show, null, {}, [{ type: types.SHOW }], [], done);
- });
- });
-
- describe('hide', () => {
- it('works', done => {
- testAction(actions.hide, null, {}, [{ type: types.HIDE }], [], done);
- });
- });
-});
diff --git a/spec/javascripts/zen_mode_spec.js b/spec/javascripts/zen_mode_spec.js
deleted file mode 100644
index 5dee11b3810..00000000000
--- a/spec/javascripts/zen_mode_spec.js
+++ /dev/null
@@ -1,106 +0,0 @@
-import $ from 'jquery';
-import Dropzone from 'dropzone';
-import Mousetrap from 'mousetrap';
-import ZenMode from '~/zen_mode';
-import initNotes from '~/init_notes';
-
-describe('ZenMode', () => {
- let zen;
- let dropzoneForElementSpy;
- const fixtureName = 'snippets/show.html';
-
- preloadFixtures(fixtureName);
-
- function enterZen() {
- $('.notes-form .js-zen-enter').click();
- }
-
- function exitZen() {
- $('.notes-form .js-zen-leave').click();
- }
-
- function escapeKeydown() {
- $('.notes-form textarea').trigger(
- $.Event('keydown', {
- keyCode: 27,
- }),
- );
- }
-
- beforeEach(() => {
- loadFixtures(fixtureName);
- initNotes();
-
- dropzoneForElementSpy = spyOn(Dropzone, 'forElement').and.callFake(() => ({
- enable: () => true,
- }));
- zen = new ZenMode();
-
- // Set this manually because we can't actually scroll the window
- zen.scroll_position = 456;
- });
-
- describe('enabling dropzone', () => {
- beforeEach(() => {
- enterZen();
- });
-
- it('should not call dropzone if element is not dropzone valid', () => {
- $('.div-dropzone').addClass('js-invalid-dropzone');
- exitZen();
-
- expect(dropzoneForElementSpy.calls.count()).toEqual(0);
- });
-
- it('should call dropzone if element is dropzone valid', () => {
- $('.div-dropzone').removeClass('js-invalid-dropzone');
- exitZen();
-
- expect(dropzoneForElementSpy.calls.count()).toEqual(2);
- });
- });
-
- describe('on enter', () => {
- it('pauses Mousetrap', () => {
- const mouseTrapPauseSpy = spyOn(Mousetrap, 'pause');
- enterZen();
-
- expect(mouseTrapPauseSpy).toHaveBeenCalled();
- });
-
- it('removes textarea styling', () => {
- $('.notes-form textarea').attr('style', 'height: 400px');
- enterZen();
-
- expect($('.notes-form textarea')).not.toHaveAttr('style');
- });
- });
-
- describe('in use', () => {
- beforeEach(enterZen);
-
- it('exits on Escape', () => {
- escapeKeydown();
-
- expect($('.notes-form .zen-backdrop')).not.toHaveClass('fullscreen');
- });
- });
-
- describe('on exit', () => {
- beforeEach(enterZen);
-
- it('unpauses Mousetrap', () => {
- const mouseTrapUnpauseSpy = spyOn(Mousetrap, 'unpause');
- exitZen();
-
- expect(mouseTrapUnpauseSpy).toHaveBeenCalled();
- });
-
- it('restores the scroll position', () => {
- spyOn(zen, 'scrollTo');
- exitZen();
-
- expect(zen.scrollTo).toHaveBeenCalled();
- });
- });
-});
diff --git a/spec/lib/api/entities/release_spec.rb b/spec/lib/api/entities/release_spec.rb
index c45dbc15856..fa9e1e74f9b 100644
--- a/spec/lib/api/entities/release_spec.rb
+++ b/spec/lib/api/entities/release_spec.rb
@@ -4,11 +4,15 @@ require 'spec_helper'
describe API::Entities::Release do
let_it_be(:project) { create(:project) }
- let_it_be(:release) { create(:release, :with_evidence, project: project) }
+ let(:release) { create(:release, project: project) }
let(:evidence) { release.evidences.first }
let(:user) { create(:user) }
let(:entity) { described_class.new(release, current_user: user).as_json }
+ before do
+ ::Releases::CreateEvidenceService.new(release).execute
+ end
+
describe 'evidences' do
context 'when the current user can download code' do
let(:entity_evidence) { entity[:evidences].first }
diff --git a/spec/lib/api/validations/validators/untrusted_regexp_spec.rb b/spec/lib/api/validations/validators/untrusted_regexp_spec.rb
new file mode 100644
index 00000000000..491bf94fd79
--- /dev/null
+++ b/spec/lib/api/validations/validators/untrusted_regexp_spec.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe API::Validations::Validators::UntrustedRegexp do
+ include ApiValidatorsHelpers
+
+ subject do
+ described_class.new(['test'], {}, false, scope.new)
+ end
+
+ context 'valid regex' do
+ it 'does not raise a validation error' do
+ expect_no_validation_error('test' => 'test')
+ expect_no_validation_error('test' => '.*')
+ expect_no_validation_error('test' => Gitlab::Regex.environment_name_regex_chars)
+ end
+ end
+
+ context 'invalid regex' do
+ it 'raises a validation error' do
+ expect_validation_error('test' => '[')
+ expect_validation_error('test' => '*foobar')
+ expect_validation_error('test' => '?foobar')
+ expect_validation_error('test' => '\A[^/%\s]+(..\z')
+ end
+ end
+end
diff --git a/spec/lib/banzai/filter/design_reference_filter_spec.rb b/spec/lib/banzai/filter/design_reference_filter_spec.rb
new file mode 100644
index 00000000000..8a6c2e3b3f9
--- /dev/null
+++ b/spec/lib/banzai/filter/design_reference_filter_spec.rb
@@ -0,0 +1,307 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Banzai::Filter::DesignReferenceFilter do
+ include FilterSpecHelper
+ include DesignManagementTestHelpers
+
+ let_it_be(:issue) { create(:issue, iid: 10) }
+ let_it_be(:issue_proj_2) { create(:issue, iid: 20) }
+ let_it_be(:issue_b) { create(:issue, project: issue.project) }
+ let_it_be(:developer) { create(:user, developer_projects: [issue.project, issue_proj_2.project]) }
+ let_it_be(:design_a) { create(:design, :with_versions, issue: issue) }
+ let_it_be(:design_b) { create(:design, :with_versions, issue: issue_b) }
+ let_it_be(:design_proj_2) { create(:design, :with_versions, issue: issue_proj_2) }
+ let_it_be(:project_with_no_lfs) { create(:project, :public, lfs_enabled: false) }
+
+ let(:design) { design_a }
+ let(:project) { issue.project }
+ let(:project_2) { issue_proj_2.project }
+ let(:reference) { design.to_reference }
+ let(:design_url) { url_for_design(design) }
+ let(:input_text) { "Added #{design_url}" }
+ let(:doc) { process_doc(input_text) }
+ let(:current_user) { developer }
+
+ before do
+ enable_design_management
+ end
+
+ shared_examples 'a no-op filter' do
+ it 'does nothing' do
+ expect(process(input_text)).to eq(baseline(input_text).to_html)
+ end
+ end
+
+ shared_examples 'a good link reference' do
+ let(:link) { doc.css('a').first }
+ let(:href) { url_for_design(design) }
+ let(:title) { design.filename }
+
+ it 'produces a good link', :aggregate_failures do
+ expect(link.attr('href')).to eq(href)
+ expect(link.attr('title')).to eq(title)
+ expect(link.attr('class')).to eq('gfm gfm-design has-tooltip')
+ expect(link.attr('data-project')).to eq(design.project.id.to_s)
+ expect(link.attr('data-issue')).to eq(design.issue.id.to_s)
+ expect(link.attr('data-original')).to eq(href)
+ expect(link.attr('data-reference-type')).to eq('design')
+ expect(link.text).to eq(design.to_reference(project))
+ end
+ end
+
+ describe '.call' do
+ it 'requires project context' do
+ expect { described_class.call('') }.to raise_error(ArgumentError, /:project/)
+ end
+ end
+
+ it 'does not error when we add redaction to the pipeline' do
+ enable_design_management
+
+ res = reference_pipeline(redact: true).to_document(input_text)
+
+ expect(res.css('a').first).to be_present
+ end
+
+ describe '#call' do
+ describe 'feature flags' do
+ context 'design management is not enabled' do
+ before do
+ enable_design_management(false)
+ end
+
+ it_behaves_like 'a no-op filter'
+ end
+
+ context 'design reference filter is not enabled' do
+ before do
+ stub_feature_flags(described_class::FEATURE_FLAG => false)
+ end
+
+ it_behaves_like 'a no-op filter'
+
+ it 'issues no queries' do
+ expect { process(input_text) }.not_to exceed_query_limit(0)
+ end
+ end
+
+ context 'the filter is enabled for the context project' do
+ before do
+ stub_feature_flags(described_class::FEATURE_FLAG => project)
+ end
+
+ it_behaves_like 'a good link reference'
+ end
+ end
+ end
+
+ %w(pre code a style).each do |elem|
+ context "wrapped in a <#{elem}/>" do
+ let(:input_text) { "<#{elem}>Design #{url_for_design(design)}</#{elem}>" }
+
+ it_behaves_like 'a no-op filter'
+ end
+ end
+
+ describe '.identifier' do
+ where(:filename) do
+ [
+ ['simple.png'],
+ ['SIMPLE.PNG'],
+ ['has spaces.png'],
+ ['has-hyphen.jpg'],
+ ['snake_case.svg'],
+ ['has "quotes".svg'],
+ ['has <special> characters [o].svg']
+ ]
+ end
+
+ with_them do
+ let(:design) { build(:design, issue: issue, filename: filename) }
+ let(:url) { url_for_design(design) }
+ let(:pattern) { described_class.object_class.link_reference_pattern }
+ let(:parsed) do
+ m = pattern.match(url)
+ described_class.identifier(m) if m
+ end
+
+ it 'can parse the reference' do
+ expect(parsed).to have_attributes(
+ filename: filename,
+ issue_iid: issue.iid
+ )
+ end
+ end
+ end
+
+ describe 'static properties' do
+ specify do
+ expect(described_class).to have_attributes(
+ object_sym: :design,
+ object_class: ::DesignManagement::Design
+ )
+ end
+ end
+
+ describe '#data_attributes_for' do
+ let(:subject) { filter_instance.data_attributes_for(input_text, project, design) }
+
+ specify do
+ is_expected.to include(issue: design.issue_id,
+ original: input_text,
+ project: project.id,
+ design: design.id)
+ end
+ end
+
+ context 'a design with a quoted filename' do
+ let(:filename) { %q{A "very" good file.png} }
+ let(:design) { create(:design, :with_versions, issue: issue, filename: filename) }
+
+ it 'links to the design' do
+ expect(doc.css('a').first.attr('href'))
+ .to eq url_for_design(design)
+ end
+ end
+
+ context 'internal reference' do
+ it_behaves_like 'a reference containing an element node'
+
+ context 'the reference is valid' do
+ it_behaves_like 'a good link reference'
+
+ context 'the filename needs to be escaped' do
+ where(:filename) do
+ [
+ ['with some spaces.png'],
+ ['with <script>console.log("pwded")<%2Fscript>.png']
+ ]
+ end
+
+ with_them do
+ let(:design) { create(:design, :with_versions, filename: filename, issue: issue) }
+ let(:link) { doc.css('a').first }
+
+ it 'replaces the content with the reference, but keeps the link', :aggregate_failures do
+ expect(doc.text).to eq(CGI.unescapeHTML("Added #{design.to_reference}"))
+ expect(link.attr('title')).to eq(design.filename)
+ expect(link.attr('href')).to eq(design_url)
+ end
+ end
+ end
+ end
+
+ context 'the reference is to a non-existant design' do
+ let(:design_url) { url_for_design(build(:design, issue: issue)) }
+
+ it_behaves_like 'a no-op filter'
+ end
+
+ context 'design management is disabled for the referenced project' do
+ let(:public_issue) { create(:issue, project: project_with_no_lfs) }
+ let(:design) { create(:design, :with_versions, issue: public_issue) }
+
+ it_behaves_like 'a no-op filter'
+ end
+ end
+
+ describe 'link pattern' do
+ let(:reference) { url_for_design(design) }
+
+ it 'matches' do
+ expect(reference).to match(DesignManagement::Design.link_reference_pattern)
+ end
+ end
+
+ context 'cross-project / cross-namespace complete reference' do
+ let(:design) { design_proj_2 }
+
+ it_behaves_like 'a reference containing an element node'
+
+ it_behaves_like 'a good link reference'
+
+ it 'links to a valid reference' do
+ expect(doc.css('a').first.attr('href')).to eq(design_url)
+ end
+
+ context 'design management is disabled for that project' do
+ let(:design) { create(:design, project: project_with_no_lfs) }
+
+ it_behaves_like 'a no-op filter'
+ end
+
+ it 'link has valid text' do
+ ref = "#{design.project.full_path}##{design.issue.iid}[#{design.filename}]"
+
+ expect(doc.css('a').first.text).to eql(ref)
+ end
+
+ it 'includes default classes' do
+ expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-design has-tooltip'
+ end
+
+ context 'the reference is invalid' do
+ let(:design_url) { url_for_design(design).gsub(/jpg/, 'gif') }
+
+ it_behaves_like 'a no-op filter'
+ end
+ end
+
+ describe 'performance' do
+ it 'is linear in the number of projects with design management enabled each design refers to' do
+ design_c = build(:design, :with_versions, issue: issue)
+ design_d = build(:design, :with_versions, issue: issue_b)
+ design_e = build(:design, :with_versions, issue: build_stubbed(:issue, project: project_2))
+
+ one_ref_per_project = <<~MD
+ Design #{url_for_design(design_a)}, #{url_for_design(design_proj_2)}
+ MD
+
+ multiple_references = <<~MD
+ Designs that affect the count:
+ * #{url_for_design(design_a)}
+ * #{url_for_design(design_b)}
+ * #{url_for_design(design_c)}
+ * #{url_for_design(design_d)}
+ * #{url_for_design(design_proj_2)}
+ * #{url_for_design(design_e)}
+
+ Things that do not affect the count:
+ * #{url_for_design(build_stubbed(:design, project: project_with_no_lfs))}
+ * #{url_for_designs(issue)}
+ * #1[not a valid reference.gif]
+ MD
+
+ baseline = ActiveRecord::QueryRecorder.new { process(one_ref_per_project) }
+
+ # each project mentioned requires 2 queries:
+ #
+ # * SELECT "issues".* FROM "issues" WHERE "issues"."project_id" = 1 AND ...
+ # :in `parent_records'*/
+ # * SELECT "_designs".* FROM "_designs"
+ # WHERE (issue_id = ? AND filename = ?) OR ...
+ # :in `parent_records'*/
+ #
+ # In addition there is a 1 query overhead for all the projects at the
+ # start. Currently, the baseline for 2 projects is `2 * 2 + 1 = 5` queries
+ #
+ expect { process(multiple_references) }.not_to exceed_query_limit(baseline.count)
+ end
+ end
+
+ private
+
+ def process_doc(text)
+ reference_filter(text, project: project)
+ end
+
+ def baseline(text)
+ null_filter(text, project: project)
+ end
+
+ def process(text)
+ process_doc(text).to_html
+ end
+end
diff --git a/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb b/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb
index 78795a157f8..a70c820f97a 100644
--- a/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb
@@ -5,10 +5,6 @@ require 'spec_helper'
describe Banzai::Filter::ExternalIssueReferenceFilter do
include FilterSpecHelper
- def helper
- IssuesHelper
- end
-
shared_examples_for "external issue tracker" do
it_behaves_like 'a reference containing an element node'
@@ -36,7 +32,7 @@ describe Banzai::Filter::ExternalIssueReferenceFilter do
issue_id = doc.css('a').first.attr("data-external-issue")
expect(doc.css('a').first.attr('href'))
- .to eq helper.url_for_issue(issue_id, project)
+ .to eq project.external_issue_tracker.issue_url(issue_id)
end
it 'links to the external tracker' do
@@ -45,7 +41,7 @@ describe Banzai::Filter::ExternalIssueReferenceFilter do
link = doc.css('a').first.attr('href')
issue_id = doc.css('a').first.attr("data-external-issue")
- expect(link).to eq(helper.url_for_issue(issue_id, project))
+ expect(link).to eq(project.external_issue_tracker.issue_url(issue_id))
end
it 'links with adjacent text' do
@@ -56,7 +52,7 @@ describe Banzai::Filter::ExternalIssueReferenceFilter do
it 'includes a title attribute' do
doc = filter("Issue #{reference}")
- expect(doc.css('a').first.attr('title')).to include("Issue in #{project.issues_tracker.title}")
+ expect(doc.css('a').first.attr('title')).to include("Issue in #{project.external_issue_tracker.title}")
end
it 'escapes the title attribute' do
@@ -78,7 +74,25 @@ describe Banzai::Filter::ExternalIssueReferenceFilter do
link = doc.css('a').first.attr('href')
issue_id = doc.css('a').first["data-external-issue"]
- expect(link).to eq helper.url_for_issue(issue_id, project, only_path: true)
+ expect(link).to eq project.external_issue_tracker.issue_path(issue_id)
+ end
+
+ it 'has an empty link if issue_url is invalid' do
+ expect_any_instance_of(project.external_issue_tracker.class).to receive(:issue_url) { 'javascript:alert("foo");' }
+
+ doc = filter("Issue #{reference}")
+ link = doc.css('a').first.attr('href')
+
+ expect(link).to eq ''
+ end
+
+ it 'has an empty link if issue_path is invalid' do
+ expect_any_instance_of(project.external_issue_tracker.class).to receive(:issue_path) { 'javascript:alert("foo");' }
+
+ doc = filter("Issue #{reference}", only_path: true)
+ link = doc.css('a').first.attr('href')
+
+ expect(link).to eq ''
end
context 'with RequestStore enabled', :request_store do
diff --git a/spec/lib/banzai/filter/gollum_tags_filter_spec.rb b/spec/lib/banzai/filter/gollum_tags_filter_spec.rb
index 1580177eaad..00d8b871224 100644
--- a/spec/lib/banzai/filter/gollum_tags_filter_spec.rb
+++ b/spec/lib/banzai/filter/gollum_tags_filter_spec.rb
@@ -7,11 +7,11 @@ describe Banzai::Filter::GollumTagsFilter do
let(:project) { create(:project) }
let(:user) { double }
- let(:project_wiki) { ProjectWiki.new(project, user) }
+ let(:wiki) { ProjectWiki.new(project, user) }
describe 'validation' do
- it 'ensure that a :project_wiki key exists in context' do
- expect { filter("See [[images/image.jpg]]", {}) }.to raise_error ArgumentError, "Missing context keys for Banzai::Filter::GollumTagsFilter: :project_wiki"
+ it 'ensure that a :wiki key exists in context' do
+ expect { filter("See [[images/image.jpg]]", {}) }.to raise_error ArgumentError, "Missing context keys for Banzai::Filter::GollumTagsFilter: :wiki"
end
end
@@ -23,19 +23,19 @@ describe Banzai::Filter::GollumTagsFilter do
path: 'images/image.jpg',
raw_data: '')
wiki_file = Gitlab::Git::WikiFile.new(gollum_file_double)
- expect(project_wiki).to receive(:find_file).with('images/image.jpg').and_return(wiki_file)
+ expect(wiki).to receive(:find_file).with('images/image.jpg').and_return(wiki_file)
tag = '[[images/image.jpg]]'
- doc = filter("See #{tag}", project_wiki: project_wiki)
+ doc = filter("See #{tag}", wiki: wiki)
- expect(doc.at_css('img')['data-src']).to eq "#{project_wiki.wiki_base_path}/images/image.jpg"
+ expect(doc.at_css('img')['data-src']).to eq "#{wiki.wiki_base_path}/images/image.jpg"
end
it 'does not creates img tag if image does not exist' do
- expect(project_wiki).to receive(:find_file).with('images/image.jpg').and_return(nil)
+ expect(wiki).to receive(:find_file).with('images/image.jpg').and_return(nil)
tag = '[[images/image.jpg]]'
- doc = filter("See #{tag}", project_wiki: project_wiki)
+ doc = filter("See #{tag}", wiki: wiki)
expect(doc.css('img').size).to eq 0
end
@@ -44,14 +44,14 @@ describe Banzai::Filter::GollumTagsFilter do
context 'linking external images' do
it 'creates img tag for valid URL' do
tag = '[[http://example.com/image.jpg]]'
- doc = filter("See #{tag}", project_wiki: project_wiki)
+ doc = filter("See #{tag}", wiki: wiki)
expect(doc.at_css('img')['data-src']).to eq "http://example.com/image.jpg"
end
it 'does not creates img tag for invalid URL' do
tag = '[[http://example.com/image.pdf]]'
- doc = filter("See #{tag}", project_wiki: project_wiki)
+ doc = filter("See #{tag}", wiki: wiki)
expect(doc.css('img').size).to eq 0
end
@@ -60,7 +60,7 @@ describe Banzai::Filter::GollumTagsFilter do
context 'linking external resources' do
it "the created link's text will be equal to the resource's text" do
tag = '[[http://example.com]]'
- doc = filter("See #{tag}", project_wiki: project_wiki)
+ doc = filter("See #{tag}", wiki: wiki)
expect(doc.at_css('a').text).to eq 'http://example.com'
expect(doc.at_css('a')['href']).to eq 'http://example.com'
@@ -68,7 +68,7 @@ describe Banzai::Filter::GollumTagsFilter do
it "the created link's text will be link-text" do
tag = '[[link-text|http://example.com/pdfs/gollum.pdf]]'
- doc = filter("See #{tag}", project_wiki: project_wiki)
+ doc = filter("See #{tag}", wiki: wiki)
expect(doc.at_css('a').text).to eq 'link-text'
expect(doc.at_css('a')['href']).to eq 'http://example.com/pdfs/gollum.pdf'
@@ -78,8 +78,8 @@ describe Banzai::Filter::GollumTagsFilter do
context 'linking internal resources' do
it "the created link's text includes the resource's text and wiki base path" do
tag = '[[wiki-slug]]'
- doc = filter("See #{tag}", project_wiki: project_wiki)
- expected_path = ::File.join(project_wiki.wiki_base_path, 'wiki-slug')
+ doc = filter("See #{tag}", wiki: wiki)
+ expected_path = ::File.join(wiki.wiki_base_path, 'wiki-slug')
expect(doc.at_css('a').text).to eq 'wiki-slug'
expect(doc.at_css('a')['href']).to eq expected_path
@@ -87,15 +87,15 @@ describe Banzai::Filter::GollumTagsFilter do
it "the created link's text will be link-text" do
tag = '[[link-text|wiki-slug]]'
- doc = filter("See #{tag}", project_wiki: project_wiki)
- expected_path = ::File.join(project_wiki.wiki_base_path, 'wiki-slug')
+ doc = filter("See #{tag}", wiki: wiki)
+ expected_path = ::File.join(wiki.wiki_base_path, 'wiki-slug')
expect(doc.at_css('a').text).to eq 'link-text'
expect(doc.at_css('a')['href']).to eq expected_path
end
it "inside back ticks will be exempt from linkification" do
- doc = filter('<code>[[link-in-backticks]]</code>', project_wiki: project_wiki)
+ doc = filter('<code>[[link-in-backticks]]</code>', wiki: wiki)
expect(doc.at_css('code').text).to eq '[[link-in-backticks]]'
end
diff --git a/spec/lib/banzai/filter/issue_reference_filter_spec.rb b/spec/lib/banzai/filter/issue_reference_filter_spec.rb
index 61c59162a30..603da2b4421 100644
--- a/spec/lib/banzai/filter/issue_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/issue_reference_filter_spec.rb
@@ -11,7 +11,9 @@ describe Banzai::Filter::IssueReferenceFilter do
end
let(:project) { create(:project, :public) }
- let(:issue) { create(:issue, project: project) }
+ let(:issue) { create(:issue, project: project) }
+ let(:issue_path) { "/#{issue.project.namespace.path}/#{issue.project.path}/-/issues/#{issue.iid}" }
+ let(:issue_url) { "http://#{Gitlab.config.gitlab.host}#{issue_path}" }
it 'requires project context' do
expect { described_class.call('') }.to raise_error(ArgumentError, /:project/)
@@ -46,7 +48,7 @@ describe Banzai::Filter::IssueReferenceFilter do
doc = reference_filter("Fixed #{reference}")
expect(doc.css('a').first.attr('href'))
- .to eq helper.url_for_issue(issue.iid, project)
+ .to eq issue_url
end
it 'links with adjacent text' do
@@ -113,7 +115,7 @@ describe Banzai::Filter::IssueReferenceFilter do
link = doc.css('a').first.attr('href')
expect(link).not_to match %r(https?://)
- expect(link).to eq helper.url_for_issue(issue.iid, project, only_path: true)
+ expect(link).to eq issue_path
end
it 'does not process links containing issue numbers followed by text' do
@@ -145,7 +147,7 @@ describe Banzai::Filter::IssueReferenceFilter do
doc = reference_filter("See #{reference}")
expect(doc.css('a').first.attr('href'))
- .to eq helper.url_for_issue(issue.iid, project2)
+ .to eq issue_url
end
it 'link has valid text' do
@@ -195,7 +197,7 @@ describe Banzai::Filter::IssueReferenceFilter do
doc = reference_filter("See #{reference}")
expect(doc.css('a').first.attr('href'))
- .to eq helper.url_for_issue(issue.iid, project2)
+ .to eq issue_url
end
it 'link has valid text' do
@@ -245,7 +247,7 @@ describe Banzai::Filter::IssueReferenceFilter do
doc = reference_filter("See #{reference}")
expect(doc.css('a').first.attr('href'))
- .to eq helper.url_for_issue(issue.iid, project2)
+ .to eq issue_url
end
it 'link has valid text' do
@@ -279,7 +281,7 @@ describe Banzai::Filter::IssueReferenceFilter do
let(:namespace) { create(:namespace, name: 'cross-reference') }
let(:project2) { create(:project, :public, namespace: namespace) }
let(:issue) { create(:issue, project: project2) }
- let(:reference) { helper.url_for_issue(issue.iid, project2) + "#note_123" }
+ let(:reference) { issue_url + "#note_123" }
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
@@ -314,7 +316,7 @@ describe Banzai::Filter::IssueReferenceFilter do
doc = reference_filter("See #{reference_link}")
expect(doc.css('a').first.attr('href'))
- .to eq helper.url_for_issue(issue.iid, project2)
+ .to eq issue_url
end
it 'links with adjacent text' do
@@ -336,14 +338,14 @@ describe Banzai::Filter::IssueReferenceFilter do
let(:namespace) { create(:namespace, name: 'cross-reference') }
let(:project2) { create(:project, :public, namespace: namespace) }
let(:issue) { create(:issue, project: project2) }
- let(:reference) { "#{helper.url_for_issue(issue.iid, project2) + "#note_123"}" }
+ let(:reference) { "#{issue_url + "#note_123"}" }
let(:reference_link) { %{<a href="#{reference}">Reference</a>} }
it 'links to a valid reference' do
doc = reference_filter("See #{reference_link}")
expect(doc.css('a').first.attr('href'))
- .to eq helper.url_for_issue(issue.iid, project2) + "#note_123"
+ .to eq issue_url + "#note_123"
end
it 'links with adjacent text' do
@@ -374,6 +376,16 @@ describe Banzai::Filter::IssueReferenceFilter do
expect(link.attr('href')).to eq(designs_tab_url)
expect(link.text).to eq("#{issue.to_reference} (designs)")
end
+
+ context 'design management is not available' do
+ before do
+ enable_design_management(false)
+ end
+
+ it 'links to the issue, but not to the designs tab' do
+ expect(link.text).to eq(issue.to_reference)
+ end
+ end
end
context 'group context' do
@@ -403,7 +415,7 @@ describe Banzai::Filter::IssueReferenceFilter do
doc = reference_filter("See #{reference}", context)
link = doc.css('a').first
- expect(link.attr('href')).to eq(helper.url_for_issue(issue.iid, project))
+ expect(link.attr('href')).to eq(issue_url)
expect(link.text).to include("#{project.full_path}##{issue.iid}")
end
@@ -415,23 +427,23 @@ describe Banzai::Filter::IssueReferenceFilter do
end
it 'links to a valid reference for url cross-reference' do
- reference = helper.url_for_issue(issue.iid, project) + "#note_123"
+ reference = issue_url + "#note_123"
doc = reference_filter("See #{reference}", context)
link = doc.css('a').first
- expect(link.attr('href')).to eq(helper.url_for_issue(issue.iid, project) + "#note_123")
+ expect(link.attr('href')).to eq(issue_url + "#note_123")
expect(link.text).to include("#{project.full_path}##{issue.iid}")
end
it 'links to a valid reference for cross-reference in link href' do
- reference = "#{helper.url_for_issue(issue.iid, project) + "#note_123"}"
+ reference = "#{issue_url + "#note_123"}"
reference_link = %{<a href="#{reference}">Reference</a>}
doc = reference_filter("See #{reference_link}", context)
link = doc.css('a').first
- expect(link.attr('href')).to eq(helper.url_for_issue(issue.iid, project) + "#note_123")
+ expect(link.attr('href')).to eq(issue_url + "#note_123")
expect(link.text).to include('Reference')
end
@@ -441,7 +453,7 @@ describe Banzai::Filter::IssueReferenceFilter do
doc = reference_filter("See #{reference_link}", context)
link = doc.css('a').first
- expect(link.attr('href')).to eq(helper.url_for_issue(issue.iid, project))
+ expect(link.attr('href')).to eq(issue_url)
expect(link.text).to include('Reference')
end
end
diff --git a/spec/lib/banzai/filter/label_reference_filter_spec.rb b/spec/lib/banzai/filter/label_reference_filter_spec.rb
index de7a70db1ac..0b697ab2040 100644
--- a/spec/lib/banzai/filter/label_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/label_reference_filter_spec.rb
@@ -47,14 +47,34 @@ describe Banzai::Filter::LabelReferenceFilter do
expect(link.attr('data-label')).to eq label.id.to_s
end
- it 'supports an :only_path context' do
+ it 'includes protocol when :only_path not present' do
+ doc = reference_filter("Label #{reference}")
+ link = doc.css('a').first.attr('href')
+
+ expect(link).to match %r(https?://)
+ end
+
+ it 'does not include protocol when :only_path true' do
doc = reference_filter("Label #{reference}", only_path: true)
link = doc.css('a').first.attr('href')
expect(link).not_to match %r(https?://)
+ end
+
+ it 'links to issue list when :label_url_method is not present' do
+ doc = reference_filter("Label #{reference}", only_path: true)
+ link = doc.css('a').first.attr('href')
+
expect(link).to eq urls.project_issues_path(project, label_name: label.name)
end
+ it 'links to merge request list when `label_url_method: :project_merge_requests_url`' do
+ doc = reference_filter("Label #{reference}", { only_path: true, label_url_method: "project_merge_requests_url" })
+ link = doc.css('a').first.attr('href')
+
+ expect(link).to eq urls.project_merge_requests_path(project, label_name: label.name)
+ end
+
context 'project that does not exist referenced' do
let(:result) { reference_filter('aaa/bbb~ccc') }
diff --git a/spec/lib/banzai/filter/repository_link_filter_spec.rb b/spec/lib/banzai/filter/repository_link_filter_spec.rb
index 460c76acd78..81f93f885f7 100644
--- a/spec/lib/banzai/filter/repository_link_filter_spec.rb
+++ b/spec/lib/banzai/filter/repository_link_filter_spec.rb
@@ -12,7 +12,7 @@ describe Banzai::Filter::RepositoryLinkFilter do
project: project,
current_user: user,
group: group,
- project_wiki: project_wiki,
+ wiki: wiki,
ref: ref,
requested_path: requested_path,
only_path: only_path
@@ -53,7 +53,7 @@ describe Banzai::Filter::RepositoryLinkFilter do
let(:project_path) { project.full_path }
let(:ref) { 'markdown' }
let(:commit) { project.commit(ref) }
- let(:project_wiki) { nil }
+ let(:wiki) { nil }
let(:requested_path) { '/' }
let(:only_path) { true }
@@ -94,8 +94,8 @@ describe Banzai::Filter::RepositoryLinkFilter do
end
end
- context 'with a project_wiki' do
- let(:project_wiki) { double('ProjectWiki') }
+ context 'with a wiki' do
+ let(:wiki) { double('ProjectWiki') }
include_examples :preserve_unchanged
end
diff --git a/spec/lib/banzai/filter/wiki_link_filter_spec.rb b/spec/lib/banzai/filter/wiki_link_filter_spec.rb
index 4587bd85939..827f38ef717 100644
--- a/spec/lib/banzai/filter/wiki_link_filter_spec.rb
+++ b/spec/lib/banzai/filter/wiki_link_filter_spec.rb
@@ -12,13 +12,13 @@ describe Banzai::Filter::WikiLinkFilter do
let(:repository_upload_folder) { Wikis::CreateAttachmentService::ATTACHMENT_PATH }
it "doesn't rewrite absolute links" do
- filtered_link = filter("<a href='http://example.com:8000/'>Link</a>", project_wiki: wiki).children[0]
+ filtered_link = filter("<a href='http://example.com:8000/'>Link</a>", wiki: wiki).children[0]
expect(filtered_link.attribute('href').value).to eq('http://example.com:8000/')
end
it "doesn't rewrite links to project uploads" do
- filtered_link = filter("<a href='/uploads/a.test'>Link</a>", project_wiki: wiki).children[0]
+ filtered_link = filter("<a href='/uploads/a.test'>Link</a>", wiki: wiki).children[0]
expect(filtered_link.attribute('href').value).to eq('/uploads/a.test')
end
@@ -26,7 +26,7 @@ describe Banzai::Filter::WikiLinkFilter do
describe "when links point to the #{Wikis::CreateAttachmentService::ATTACHMENT_PATH} folder" do
context 'with an "a" html tag' do
it 'rewrites links' do
- filtered_link = filter("<a href='#{repository_upload_folder}/a.test'>Link</a>", project_wiki: wiki).children[0]
+ filtered_link = filter("<a href='#{repository_upload_folder}/a.test'>Link</a>", wiki: wiki).children[0]
expect(filtered_link.attribute('href').value).to eq("#{wiki.wiki_base_path}/#{repository_upload_folder}/a.test")
end
@@ -37,7 +37,7 @@ describe Banzai::Filter::WikiLinkFilter do
context 'inside an "a" html tag' do
it 'rewrites links' do
- filtered_elements = filter("<a href='#{repository_upload_folder}/a.jpg'><img src='#{repository_upload_folder}/a.jpg'>example</img></a>", project_wiki: wiki)
+ filtered_elements = filter("<a href='#{repository_upload_folder}/a.jpg'><img src='#{repository_upload_folder}/a.jpg'>example</img></a>", wiki: wiki)
expect(filtered_elements.search('img').first.attribute('src').value).to eq(path)
expect(filtered_elements.search('a').first.attribute('href').value).to eq(path)
@@ -46,7 +46,7 @@ describe Banzai::Filter::WikiLinkFilter do
context 'outside an "a" html tag' do
it 'rewrites links' do
- filtered_link = filter("<img src='#{repository_upload_folder}/a.jpg'>example</img>", project_wiki: wiki).children[0]
+ filtered_link = filter("<img src='#{repository_upload_folder}/a.jpg'>example</img>", wiki: wiki).children[0]
expect(filtered_link.attribute('src').value).to eq(path)
end
@@ -55,7 +55,7 @@ describe Banzai::Filter::WikiLinkFilter do
context 'with "video" html tag' do
it 'rewrites links' do
- filtered_link = filter("<video src='#{repository_upload_folder}/a.mp4'></video>", project_wiki: wiki).children[0]
+ filtered_link = filter("<video src='#{repository_upload_folder}/a.mp4'></video>", wiki: wiki).children[0]
expect(filtered_link.attribute('src').value).to eq("#{wiki.wiki_base_path}/#{repository_upload_folder}/a.mp4")
end
@@ -63,7 +63,7 @@ describe Banzai::Filter::WikiLinkFilter do
context 'with "audio" html tag' do
it 'rewrites links' do
- filtered_link = filter("<audio src='#{repository_upload_folder}/a.wav'></audio>", project_wiki: wiki).children[0]
+ filtered_link = filter("<audio src='#{repository_upload_folder}/a.wav'></audio>", wiki: wiki).children[0]
expect(filtered_link.attribute('src').value).to eq("#{wiki.wiki_base_path}/#{repository_upload_folder}/a.wav")
end
@@ -75,7 +75,7 @@ describe Banzai::Filter::WikiLinkFilter do
invalid_links.each do |invalid_link|
it "doesn't rewrite invalid invalid_links like #{invalid_link}" do
- filtered_link = filter("<a href='#{invalid_link}'>Link</a>", project_wiki: wiki).children[0]
+ filtered_link = filter("<a href='#{invalid_link}'>Link</a>", wiki: wiki).children[0]
expect(filtered_link.attribute('href').value).to eq(invalid_link)
end
diff --git a/spec/lib/banzai/pipeline/description_pipeline_spec.rb b/spec/lib/banzai/pipeline/description_pipeline_spec.rb
index 5ecd3df5151..6778a273bba 100644
--- a/spec/lib/banzai/pipeline/description_pipeline_spec.rb
+++ b/spec/lib/banzai/pipeline/description_pipeline_spec.rb
@@ -3,12 +3,14 @@
require 'spec_helper'
describe Banzai::Pipeline::DescriptionPipeline do
+ let_it_be(:project) { create(:project) }
+
def parse(html)
# When we pass HTML to Redcarpet, it gets wrapped in `p` tags...
# ...except when we pass it pre-wrapped text. Rabble rabble.
unwrap = !html.start_with?('<p ')
- output = described_class.to_html(html, project: spy)
+ output = described_class.to_html(html, project: project)
output.gsub!(%r{\A<p dir="auto">(.*)</p>(.*)\z}, '\1\2') if unwrap
diff --git a/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb b/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb
index 4d16c568c13..b2c24284eb9 100644
--- a/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb
+++ b/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb
@@ -3,6 +3,11 @@
require 'spec_helper'
describe Banzai::Pipeline::WikiPipeline do
+ let_it_be(:namespace) { create(:namespace, name: "wiki_link_ns") }
+ let_it_be(:project) { create(:project, :public, name: "wiki_link_project", namespace: namespace) }
+ let_it_be(:wiki) { ProjectWiki.new(project, double(:user)) }
+ let_it_be(:page) { build(:wiki_page, wiki: wiki, title: 'nested/twice/start-page') }
+
describe 'TableOfContents' do
it 'replaces the tag with the TableOfContentsFilter result' do
markdown = <<-MD.strip_heredoc
@@ -13,7 +18,7 @@ describe Banzai::Pipeline::WikiPipeline do
Foo
MD
- result = described_class.call(markdown, project: spy, project_wiki: spy)
+ result = described_class.call(markdown, project: project, wiki: wiki)
aggregate_failures do
expect(result[:output].text).not_to include '[['
@@ -31,7 +36,7 @@ describe Banzai::Pipeline::WikiPipeline do
Foo
MD
- output = described_class.to_html(markdown, project: spy, project_wiki: spy)
+ output = described_class.to_html(markdown, project: project, wiki: wiki)
expect(output).to include('[[<em>toc</em>]]')
end
@@ -44,7 +49,7 @@ describe Banzai::Pipeline::WikiPipeline do
Foo
MD
- output = described_class.to_html(markdown, project: spy, project_wiki: spy)
+ output = described_class.to_html(markdown, project: project, wiki: wiki)
aggregate_failures do
expect(output).not_to include('<ul>')
@@ -54,30 +59,25 @@ describe Banzai::Pipeline::WikiPipeline do
end
describe "Links" do
- let(:namespace) { create(:namespace, name: "wiki_link_ns") }
- let(:project) { create(:project, :public, name: "wiki_link_project", namespace: namespace) }
- let(:project_wiki) { ProjectWiki.new(project, double(:user)) }
- let(:page) { build(:wiki_page, wiki: project_wiki, title: 'nested/twice/start-page') }
-
{ 'when GitLab is hosted at a root URL' => '',
'when GitLab is hosted at a relative URL' => '/nested/relative/gitlab' }.each do |test_name, relative_url_root|
context test_name do
before do
- allow(Gitlab.config.gitlab).to receive(:relative_url_root).and_return(relative_url_root)
+ allow(Rails.application.routes).to receive(:default_url_options).and_return(script_name: relative_url_root)
end
describe "linking to pages within the wiki" do
context "when creating hierarchical links to the current directory" do
it "rewrites non-file links to be at the scope of the current directory" do
markdown = "[Page](./page)"
- output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
+ output = described_class.to_html(markdown, project: project, wiki: wiki, page_slug: page.slug)
expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/nested/twice/page\"")
end
it "rewrites file links to be at the scope of the current directory" do
markdown = "[Link to Page](./page.md)"
- output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
+ output = described_class.to_html(markdown, project: project, wiki: wiki, page_slug: page.slug)
expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/nested/twice/page.md\"")
end
@@ -86,14 +86,14 @@ describe Banzai::Pipeline::WikiPipeline do
context "when creating hierarchical links to the parent directory" do
it "rewrites non-file links to be at the scope of the parent directory" do
markdown = "[Link to Page](../page)"
- output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
+ output = described_class.to_html(markdown, project: project, wiki: wiki, page_slug: page.slug)
expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/nested/page\"")
end
it "rewrites file links to be at the scope of the parent directory" do
markdown = "[Link to Page](../page.md)"
- output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
+ output = described_class.to_html(markdown, project: project, wiki: wiki, page_slug: page.slug)
expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/nested/page.md\"")
end
@@ -102,14 +102,14 @@ describe Banzai::Pipeline::WikiPipeline do
context "when creating hierarchical links to a sub-directory" do
it "rewrites non-file links to be at the scope of the sub-directory" do
markdown = "[Link to Page](./subdirectory/page)"
- output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
+ output = described_class.to_html(markdown, project: project, wiki: wiki, page_slug: page.slug)
expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/nested/twice/subdirectory/page\"")
end
it "rewrites file links to be at the scope of the sub-directory" do
markdown = "[Link to Page](./subdirectory/page.md)"
- output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
+ output = described_class.to_html(markdown, project: project, wiki: wiki, page_slug: page.slug)
expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/nested/twice/subdirectory/page.md\"")
end
@@ -118,35 +118,35 @@ describe Banzai::Pipeline::WikiPipeline do
describe "when creating non-hierarchical links" do
it 'rewrites non-file links to be at the scope of the wiki root' do
markdown = "[Link to Page](page)"
- output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
+ output = described_class.to_html(markdown, project: project, wiki: wiki, page_slug: page.slug)
expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/page\"")
end
it 'rewrites non-file links (with spaces) to be at the scope of the wiki root' do
markdown = "[Link to Page](page slug)"
- output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
+ output = described_class.to_html(markdown, project: project, wiki: wiki, page_slug: page.slug)
expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/page%20slug\"")
end
it "rewrites file links to be at the scope of the current directory" do
markdown = "[Link to Page](page.md)"
- output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
+ output = described_class.to_html(markdown, project: project, wiki: wiki, page_slug: page.slug)
expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/nested/twice/page.md\"")
end
it 'rewrites links with anchor' do
markdown = '[Link to Header](start-page#title)'
- output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
+ output = described_class.to_html(markdown, project: project, wiki: wiki, page_slug: page.slug)
expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/start-page#title\"")
end
it 'rewrites links (with spaces) with anchor' do
markdown = '[Link to Header](start page#title)'
- output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
+ output = described_class.to_html(markdown, project: project, wiki: wiki, page_slug: page.slug)
expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/start%20page#title\"")
end
@@ -155,14 +155,14 @@ describe Banzai::Pipeline::WikiPipeline do
describe "when creating root links" do
it 'rewrites non-file links to be at the scope of the wiki root' do
markdown = "[Link to Page](/page)"
- output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
+ output = described_class.to_html(markdown, project: project, wiki: wiki, page_slug: page.slug)
expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/page\"")
end
it 'rewrites file links to be at the scope of the wiki root' do
markdown = "[Link to Page](/page.md)"
- output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
+ output = described_class.to_html(markdown, project: project, wiki: wiki, page_slug: page.slug)
expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/-/wikis/page.md\"")
end
@@ -172,7 +172,7 @@ describe Banzai::Pipeline::WikiPipeline do
describe "linking to pages outside the wiki (absolute)" do
it "doesn't rewrite links" do
markdown = "[Link to Page](http://example.com/page)"
- output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
+ output = described_class.to_html(markdown, project: project, wiki: wiki, page_slug: page.slug)
expect(output).to include('href="http://example.com/page"')
end
@@ -188,7 +188,7 @@ describe Banzai::Pipeline::WikiPipeline do
output = described_class.to_html(
"[Link](./alert(1);)",
project: project,
- project_wiki: project_wiki,
+ wiki: wiki,
page_slug: valid_slug
)
@@ -199,7 +199,7 @@ describe Banzai::Pipeline::WikiPipeline do
output = described_class.to_html(
"[Link](../alert(1);)",
project: project,
- project_wiki: project_wiki,
+ wiki: wiki,
page_slug: valid_slug
)
@@ -236,7 +236,7 @@ describe Banzai::Pipeline::WikiPipeline do
output = described_class.to_html(
"[Link](./#{link})",
project: project,
- project_wiki: project_wiki,
+ wiki: wiki,
page_slug: slug
)
@@ -247,7 +247,7 @@ describe Banzai::Pipeline::WikiPipeline do
output = described_class.to_html(
"[Link](../#{link})",
project: project,
- project_wiki: project_wiki,
+ wiki: wiki,
page_slug: slug
)
@@ -261,35 +261,30 @@ describe Banzai::Pipeline::WikiPipeline do
end
describe 'videos and audio' do
- let_it_be(:namespace) { create(:namespace, name: "wiki_link_ns") }
- let_it_be(:project) { create(:project, :public, name: "wiki_link_project", namespace: namespace) }
- let_it_be(:project_wiki) { ProjectWiki.new(project, double(:user)) }
- let_it_be(:page) { build(:wiki_page, wiki: project_wiki, title: 'nested/twice/start-page') }
-
it 'generates video html structure' do
markdown = "![video_file](video_file_name.mp4)"
- output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
+ output = described_class.to_html(markdown, project: project, wiki: wiki, page_slug: page.slug)
expect(output).to include('<video src="/wiki_link_ns/wiki_link_project/-/wikis/nested/twice/video_file_name.mp4"')
end
it 'rewrites and replaces video links names with white spaces to %20' do
markdown = "![video file](video file name.mp4)"
- output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
+ output = described_class.to_html(markdown, project: project, wiki: wiki, page_slug: page.slug)
expect(output).to include('<video src="/wiki_link_ns/wiki_link_project/-/wikis/nested/twice/video%20file%20name.mp4"')
end
it 'generates audio html structure' do
markdown = "![audio_file](audio_file_name.wav)"
- output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
+ output = described_class.to_html(markdown, project: project, wiki: wiki, page_slug: page.slug)
expect(output).to include('<audio src="/wiki_link_ns/wiki_link_project/-/wikis/nested/twice/audio_file_name.wav"')
end
it 'rewrites and replaces audio links names with white spaces to %20' do
markdown = "![audio file](audio file name.wav)"
- output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
+ output = described_class.to_html(markdown, project: project, wiki: wiki, page_slug: page.slug)
expect(output).to include('<audio src="/wiki_link_ns/wiki_link_project/-/wikis/nested/twice/audio%20file%20name.wav"')
end
diff --git a/spec/lib/constraints/feature_constrainer_spec.rb b/spec/lib/constraints/feature_constrainer_spec.rb
index 0739da801a7..7665d5b3547 100644
--- a/spec/lib/constraints/feature_constrainer_spec.rb
+++ b/spec/lib/constraints/feature_constrainer_spec.rb
@@ -5,9 +5,12 @@ require 'spec_helper'
describe Constraints::FeatureConstrainer do
describe '#matches' do
it 'calls Feature.enabled? with the correct arguments' do
- expect(Feature).to receive(:enabled?).with(:feature_name, "an object", default_enabled: true)
+ gate = stub_feature_flag_gate("an object")
- described_class.new(:feature_name, "an object", default_enabled: true).matches?(double('request'))
+ expect(Feature).to receive(:enabled?)
+ .with(:feature_name, gate, default_enabled: true)
+
+ described_class.new(:feature_name, gate, default_enabled: true).matches?(double('request'))
end
end
end
diff --git a/spec/lib/extracts_path_spec.rb b/spec/lib/extracts_path_spec.rb
index ef9929a9dce..a56768a1a88 100644
--- a/spec/lib/extracts_path_spec.rb
+++ b/spec/lib/extracts_path_spec.rb
@@ -7,17 +7,15 @@ describe ExtractsPath do
include RepoHelpers
include Gitlab::Routing
- let(:project) { double('project') }
+ let_it_be(:owner) { create(:user) }
+ let_it_be(:container) { create(:project, :repository, creator: owner) }
let(:request) { double('request') }
before do
- @project = project
+ @project = container
+ ref_names = ['master', 'foo/bar/baz', 'v1.0.0', 'v2.0.0', 'release/app', 'release/app/v1.0.0']
- repo = double(ref_names: ['master', 'foo/bar/baz', 'v1.0.0', 'v2.0.0',
- 'release/app', 'release/app/v1.0.0'])
- allow(project).to receive(:repository).and_return(repo)
- allow(project).to receive(:full_path)
- .and_return('gitlab/gitlab-ci')
+ allow(container.repository).to receive(:ref_names).and_return(ref_names)
allow(request).to receive(:format=)
end
@@ -25,45 +23,12 @@ describe ExtractsPath do
let(:ref) { sample_commit[:id] }
let(:params) { { path: sample_commit[:line_code_path], ref: ref } }
- before do
- @project = create(:project, :repository)
- end
+ it_behaves_like 'assigns ref vars'
- it "log tree path has no escape sequences" do
+ it 'log tree path has no escape sequences' do
assign_ref_vars
- expect(@logs_path).to eq("/#{@project.full_path}/-/refs/#{ref}/logs_tree/files/ruby/popen.rb")
- end
-
- context 'ref contains %20' do
- let(:ref) { 'foo%20bar' }
-
- it 'is not converted to a space in @id' do
- @project.repository.add_branch(@project.owner, 'foo%20bar', 'master')
-
- assign_ref_vars
-
- expect(@id).to start_with('foo%20bar/')
- end
- end
-
- context 'ref contains trailing space' do
- let(:ref) { 'master ' }
-
- it 'strips surrounding space' do
- assign_ref_vars
- expect(@ref).to eq('master')
- end
- end
-
- context 'ref contains leading space' do
- let(:ref) { ' master ' }
-
- it 'strips surrounding space' do
- assign_ref_vars
-
- expect(@ref).to eq('master')
- end
+ expect(@logs_path).to eq("/#{@project.full_path}/-/refs/#{ref}/logs_tree/files/ruby/popen.rb")
end
context 'ref contains space in the middle' do
@@ -76,28 +41,6 @@ describe ExtractsPath do
end
end
- context 'path contains space' do
- let(:params) { { path: 'with space', ref: '38008cb17ce1466d8fec2dfa6f6ab8dcfe5cf49e' } }
-
- it 'is not converted to %20 in @path' do
- assign_ref_vars
-
- expect(@path).to eq(params[:path])
- end
- end
-
- context 'subclass overrides get_id' do
- it 'uses ref returned by get_id' do
- allow_next_instance_of(self.class) do |instance|
- allow(instance).to receive(:get_id) { '38008cb17ce1466d8fec2dfa6f6ab8dcfe5cf49e' }
- end
-
- assign_ref_vars
-
- expect(@id).to eq(get_id)
- end
- end
-
context 'ref only exists without .atom suffix' do
context 'with a path' do
let(:params) { { ref: 'v1.0.0.atom', path: 'README.md' } }
@@ -171,58 +114,7 @@ describe ExtractsPath do
end
end
- describe '#extract_ref' do
- it "returns an empty pair when no @project is set" do
- @project = nil
- expect(extract_ref('master/CHANGELOG')).to eq(['', ''])
- end
-
- context "without a path" do
- it "extracts a valid branch" do
- expect(extract_ref('master')).to eq(['master', ''])
- end
-
- it "extracts a valid tag" do
- expect(extract_ref('v2.0.0')).to eq(['v2.0.0', ''])
- end
-
- it "extracts a valid commit ref without a path" do
- expect(extract_ref('f4b14494ef6abf3d144c28e4af0c20143383e062')).to eq(
- ['f4b14494ef6abf3d144c28e4af0c20143383e062', '']
- )
- end
-
- it "falls back to a primitive split for an invalid ref" do
- expect(extract_ref('stable')).to eq(['stable', ''])
- end
-
- it "extracts the longest matching ref" do
- expect(extract_ref('release/app/v1.0.0/README.md')).to eq(
- ['release/app/v1.0.0', 'README.md'])
- end
- end
-
- context "with a path" do
- it "extracts a valid branch" do
- expect(extract_ref('foo/bar/baz/CHANGELOG')).to eq(
- ['foo/bar/baz', 'CHANGELOG'])
- end
-
- it "extracts a valid tag" do
- expect(extract_ref('v2.0.0/CHANGELOG')).to eq(['v2.0.0', 'CHANGELOG'])
- end
-
- it "extracts a valid commit SHA" do
- expect(extract_ref('f4b14494ef6abf3d144c28e4af0c20143383e062/CHANGELOG')).to eq(
- %w(f4b14494ef6abf3d144c28e4af0c20143383e062 CHANGELOG)
- )
- end
-
- it "falls back to a primitive split for an invalid ref" do
- expect(extract_ref('stable/CHANGELOG')).to eq(%w(stable CHANGELOG))
- end
- end
- end
+ it_behaves_like 'extracts refs'
describe '#extract_ref_without_atom' do
it 'ignores any matching refs suffixed with atom' do
diff --git a/spec/lib/extracts_ref_spec.rb b/spec/lib/extracts_ref_spec.rb
new file mode 100644
index 00000000000..1867f639711
--- /dev/null
+++ b/spec/lib/extracts_ref_spec.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe ExtractsRef do
+ include described_class
+ include RepoHelpers
+
+ let_it_be(:owner) { create(:user) }
+ let_it_be(:container) { create(:snippet, :repository, author: owner) }
+ let(:ref) { sample_commit[:id] }
+ let(:params) { { path: sample_commit[:line_code_path], ref: ref } }
+
+ before do
+ ref_names = ['master', 'foo/bar/baz', 'v1.0.0', 'v2.0.0', 'release/app', 'release/app/v1.0.0']
+
+ allow(container.repository).to receive(:ref_names).and_return(ref_names)
+ allow_any_instance_of(described_class).to receive(:repository_container).and_return(container)
+ end
+
+ it_behaves_like 'assigns ref vars'
+ it_behaves_like 'extracts refs'
+end
diff --git a/spec/lib/feature/gitaly_spec.rb b/spec/lib/feature/gitaly_spec.rb
index 08651c42276..6654b7627cd 100644
--- a/spec/lib/feature/gitaly_spec.rb
+++ b/spec/lib/feature/gitaly_spec.rb
@@ -25,7 +25,7 @@ describe Feature::Gitaly do
describe ".server_feature_flags" do
before do
- allow(Feature).to receive(:persisted_names).and_return(%w[gitaly_mep_mep foo])
+ stub_feature_flags(gitaly_mep_mep: true, foo: true)
end
subject { described_class.server_feature_flags }
diff --git a/spec/lib/feature_spec.rb b/spec/lib/feature_spec.rb
index 81fa2dc5cad..37f8d3ad47d 100644
--- a/spec/lib/feature_spec.rb
+++ b/spec/lib/feature_spec.rb
@@ -2,12 +2,10 @@
require 'spec_helper'
-describe Feature do
+describe Feature, stub_feature_flags: false do
before do
- # We mock all calls to .enabled? to return true in order to force all
- # specs to run the feature flag gated behavior, but here we need a clean
- # behavior from the class
- allow(described_class).to receive(:enabled?).and_call_original
+ # reset Flipper AR-engine
+ Feature.reset
end
describe '.get' do
@@ -23,67 +21,106 @@ describe Feature do
end
describe '.persisted_names' do
- it 'returns the names of the persisted features' do
- Feature::FlipperFeature.create!(key: 'foo')
+ context 'when FF_LEGACY_PERSISTED_NAMES=false' do
+ before do
+ stub_env('FF_LEGACY_PERSISTED_NAMES', 'false')
+ end
- expect(described_class.persisted_names).to eq(%w[foo])
- end
+ it 'returns the names of the persisted features' do
+ Feature.enable('foo')
+
+ expect(described_class.persisted_names).to contain_exactly('foo')
+ end
+
+ it 'returns an empty Array when no features are presisted' do
+ expect(described_class.persisted_names).to be_empty
+ end
+
+ it 'caches the feature names when request store is active',
+ :request_store, :use_clean_rails_memory_store_caching do
+ Feature.enable('foo')
- it 'returns an empty Array when no features are presisted' do
- expect(described_class.persisted_names).to be_empty
+ expect(Gitlab::ProcessMemoryCache.cache_backend)
+ .to receive(:fetch)
+ .once
+ .with('flipper/v1/features', expires_in: 1.minute)
+ .and_call_original
+
+ 2.times do
+ expect(described_class.persisted_names).to contain_exactly('foo')
+ end
+ end
end
- it 'caches the feature names when request store is active',
+ context 'when FF_LEGACY_PERSISTED_NAMES=true' do
+ before do
+ stub_env('FF_LEGACY_PERSISTED_NAMES', 'true')
+ end
+
+ it 'returns the names of the persisted features' do
+ Feature.enable('foo')
+
+ expect(described_class.persisted_names).to contain_exactly('foo')
+ end
+
+ it 'returns an empty Array when no features are presisted' do
+ expect(described_class.persisted_names).to be_empty
+ end
+
+ it 'caches the feature names when request store is active',
:request_store, :use_clean_rails_memory_store_caching do
- Feature::FlipperFeature.create!(key: 'foo')
+ Feature.enable('foo')
- expect(Feature::FlipperFeature)
- .to receive(:feature_names)
- .once
- .and_call_original
+ expect(Gitlab::ProcessMemoryCache.cache_backend)
+ .to receive(:fetch)
+ .once
+ .with('flipper:persisted_names', expires_in: 1.minute)
+ .and_call_original
- expect(Gitlab::ProcessMemoryCache.cache_backend)
- .to receive(:fetch)
- .once
- .with('flipper:persisted_names', expires_in: 1.minute)
- .and_call_original
+ 2.times do
+ expect(described_class.persisted_names).to contain_exactly('foo')
+ end
+ end
+ end
- 2.times do
- expect(described_class.persisted_names).to eq(%w[foo])
+ it 'fetches all flags once in a single query', :request_store do
+ Feature.enable('foo1')
+ Feature.enable('foo2')
+
+ queries = ActiveRecord::QueryRecorder.new(skip_cached: false) do
+ expect(described_class.persisted_names).to contain_exactly('foo1', 'foo2')
+
+ RequestStore.clear!
+
+ expect(described_class.persisted_names).to contain_exactly('foo1', 'foo2')
end
+
+ expect(queries.count).to eq(1)
end
end
- describe '.persisted?' do
+ describe '.persisted_name?' do
context 'when the feature is persisted' do
it 'returns true when feature name is a string' do
- Feature::FlipperFeature.create!(key: 'foo')
-
- feature = double(:feature, name: 'foo')
+ Feature.enable('foo')
- expect(described_class.persisted?(feature)).to eq(true)
+ expect(described_class.persisted_name?('foo')).to eq(true)
end
it 'returns true when feature name is a symbol' do
- Feature::FlipperFeature.create!(key: 'foo')
+ Feature.enable('foo')
- feature = double(:feature, name: :foo)
-
- expect(described_class.persisted?(feature)).to eq(true)
+ expect(described_class.persisted_name?(:foo)).to eq(true)
end
end
context 'when the feature is not persisted' do
it 'returns false when feature name is a string' do
- feature = double(:feature, name: 'foo')
-
- expect(described_class.persisted?(feature)).to eq(false)
+ expect(described_class.persisted_name?('foo')).to eq(false)
end
it 'returns false when feature name is a symbol' do
- feature = double(:feature, name: :bar)
-
- expect(described_class.persisted?(feature)).to eq(false)
+ expect(described_class.persisted_name?(:bar)).to eq(false)
end
end
end
@@ -100,16 +137,12 @@ describe Feature do
end
describe '.flipper' do
- before do
- described_class.instance_variable_set(:@flipper, nil)
- end
-
context 'when request store is inactive' do
it 'memoizes the Flipper instance' do
expect(Flipper).to receive(:new).once.and_call_original
2.times do
- described_class.flipper
+ described_class.send(:flipper)
end
end
end
@@ -118,9 +151,9 @@ describe Feature do
it 'memoizes the Flipper instance' do
expect(Flipper).to receive(:new).once.and_call_original
- described_class.flipper
+ described_class.send(:flipper)
described_class.instance_variable_set(:@flipper, nil)
- described_class.flipper
+ described_class.send(:flipper)
end
end
end
@@ -146,21 +179,21 @@ describe Feature do
expect(described_class.enabled?(:enabled_feature_flag)).to be_truthy
end
- it { expect(described_class.l1_cache_backend).to eq(Gitlab::ProcessMemoryCache.cache_backend) }
- it { expect(described_class.l2_cache_backend).to eq(Rails.cache) }
+ it { expect(described_class.send(:l1_cache_backend)).to eq(Gitlab::ProcessMemoryCache.cache_backend) }
+ it { expect(described_class.send(:l2_cache_backend)).to eq(Rails.cache) }
it 'caches the status in L1 and L2 caches',
:request_store, :use_clean_rails_memory_store_caching do
described_class.enable(:enabled_feature_flag)
flipper_key = "flipper/v1/feature/enabled_feature_flag"
- expect(described_class.l2_cache_backend)
+ expect(described_class.send(:l2_cache_backend))
.to receive(:fetch)
.once
.with(flipper_key, expires_in: 1.hour)
.and_call_original
- expect(described_class.l1_cache_backend)
+ expect(described_class.send(:l1_cache_backend))
.to receive(:fetch)
.once
.with(flipper_key, expires_in: 1.minute)
@@ -182,14 +215,14 @@ describe Feature do
let(:flag) { :some_feature_flag }
before do
- described_class.flipper.memoize = false
+ described_class.send(:flipper).memoize = false
described_class.enabled?(flag)
end
it 'caches the status in L1 cache for the first minute' do
expect do
- expect(described_class.l1_cache_backend).to receive(:fetch).once.and_call_original
- expect(described_class.l2_cache_backend).not_to receive(:fetch)
+ expect(described_class.send(:l1_cache_backend)).to receive(:fetch).once.and_call_original
+ expect(described_class.send(:l2_cache_backend)).not_to receive(:fetch)
expect(described_class.enabled?(flag)).to be_truthy
end.not_to exceed_query_limit(0)
end
@@ -197,8 +230,8 @@ describe Feature do
it 'caches the status in L2 cache after 2 minutes' do
Timecop.travel 2.minutes do
expect do
- expect(described_class.l1_cache_backend).to receive(:fetch).once.and_call_original
- expect(described_class.l2_cache_backend).to receive(:fetch).once.and_call_original
+ expect(described_class.send(:l1_cache_backend)).to receive(:fetch).once.and_call_original
+ expect(described_class.send(:l2_cache_backend)).to receive(:fetch).once.and_call_original
expect(described_class.enabled?(flag)).to be_truthy
end.not_to exceed_query_limit(0)
end
@@ -207,8 +240,8 @@ describe Feature do
it 'fetches the status after an hour' do
Timecop.travel 61.minutes do
expect do
- expect(described_class.l1_cache_backend).to receive(:fetch).once.and_call_original
- expect(described_class.l2_cache_backend).to receive(:fetch).once.and_call_original
+ expect(described_class.send(:l1_cache_backend)).to receive(:fetch).once.and_call_original
+ expect(described_class.send(:l2_cache_backend)).to receive(:fetch).once.and_call_original
expect(described_class.enabled?(flag)).to be_truthy
end.not_to exceed_query_limit(1)
end
@@ -216,10 +249,8 @@ describe Feature do
end
context 'with an individual actor' do
- CustomActor = Struct.new(:flipper_id)
-
- let(:actor) { CustomActor.new(flipper_id: 'CustomActor:5') }
- let(:another_actor) { CustomActor.new(flipper_id: 'CustomActor:10') }
+ let(:actor) { stub_feature_flag_gate('CustomActor:5') }
+ let(:another_actor) { stub_feature_flag_gate('CustomActor:10') }
before do
described_class.enable(:enabled_feature_flag, actor)
@@ -237,6 +268,17 @@ describe Feature do
expect(described_class.enabled?(:enabled_feature_flag)).to be_falsey
end
end
+
+ context 'with invalid actor' do
+ let(:actor) { double('invalid actor') }
+
+ context 'when is dev_or_test_env' do
+ it 'does raise exception' do
+ expect { described_class.enabled?(:enabled_feature_flag, actor) }
+ .to raise_error /needs to include `FeatureGate` or implement `flipper_id`/
+ end
+ end
+ end
end
describe '.disable?' do
diff --git a/spec/lib/gitaly/server_spec.rb b/spec/lib/gitaly/server_spec.rb
index 5142f705251..390855b30ad 100644
--- a/spec/lib/gitaly/server_spec.rb
+++ b/spec/lib/gitaly/server_spec.rb
@@ -20,6 +20,7 @@ describe Gitaly::Server do
it { is_expected.to respond_to(:git_binary_version) }
it { is_expected.to respond_to(:up_to_date?) }
it { is_expected.to respond_to(:address) }
+ it { is_expected.to respond_to(:replication_factor) }
describe 'readable?' do
context 'when the storage is readable' do
@@ -134,4 +135,22 @@ describe Gitaly::Server do
end
end
end
+
+ describe 'replication_factor' do
+ context 'when examining for a given server' do
+ let(:storage_status) { double('storage_status', storage_name: 'default') }
+
+ before do
+ response = double('response', storage_statuses: [storage_status])
+ allow_next_instance_of(Gitlab::GitalyClient::ServerService) do |instance|
+ allow(instance).to receive(:info).and_return(response)
+ end
+ end
+
+ it do
+ allow(storage_status).to receive(:replication_factor).and_return(2)
+ expect(server.replication_factor).to eq(2)
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/alert_management/alert_params_spec.rb b/spec/lib/gitlab/alert_management/alert_params_spec.rb
index 5cf34038f68..284af421f05 100644
--- a/spec/lib/gitlab/alert_management/alert_params_spec.rb
+++ b/spec/lib/gitlab/alert_management/alert_params_spec.rb
@@ -32,7 +32,8 @@ describe Gitlab::AlertManagement::AlertParams do
severity: 'critical',
hosts: ['gitlab.com'],
payload: payload,
- started_at: started_at
+ started_at: started_at,
+ fingerprint: nil
)
end
diff --git a/spec/lib/gitlab/alert_management/alert_status_counts_spec.rb b/spec/lib/gitlab/alert_management/alert_status_counts_spec.rb
index 816ed918fe8..728cbf11cda 100644
--- a/spec/lib/gitlab/alert_management/alert_status_counts_spec.rb
+++ b/spec/lib/gitlab/alert_management/alert_status_counts_spec.rb
@@ -50,6 +50,19 @@ describe Gitlab::AlertManagement::AlertStatusCounts do
expect(counts.acknowledged).to eq(0)
end
end
+
+ context 'when search param is included' do
+ let(:params) { { search: alert_1.title } }
+
+ it 'returns the correct countss' do
+ expect(counts.open).to eq(0)
+ expect(counts.all).to eq(1)
+ expect(counts.resolved).to eq(1)
+ expect(counts.ignored).to eq(0)
+ expect(counts.triggered).to eq(0)
+ expect(counts.acknowledged).to eq(0)
+ end
+ end
end
end
end
diff --git a/spec/lib/gitlab/alert_management/fingerprint_spec.rb b/spec/lib/gitlab/alert_management/fingerprint_spec.rb
new file mode 100644
index 00000000000..7865d667f71
--- /dev/null
+++ b/spec/lib/gitlab/alert_management/fingerprint_spec.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::AlertManagement::Fingerprint do
+ using RSpec::Parameterized::TableSyntax
+
+ let_it_be(:alert) { create(:alert_management_alert) }
+
+ describe '.generate' do
+ subject { described_class.generate(data) }
+
+ context 'when data is an array' do
+ let(:data) { [1, 'fingerprint', 'given'] }
+
+ it 'flattens the array' do
+ expect_next_instance_of(described_class) do |obj|
+ expect(obj).to receive(:flatten_array)
+ end
+
+ subject
+ end
+
+ it 'returns the hashed fingerprint' do
+ expected_fingerprint = Digest::SHA1.hexdigest(data.flatten.map!(&:to_s).join)
+ expect(subject).to eq(expected_fingerprint)
+ end
+ end
+
+ context 'when data is a non-array type' do
+ where(:data) do
+ [
+ 111,
+ 'fingerprint',
+ :fingerprint,
+ true,
+ { test: true }
+ ]
+ end
+
+ with_them do
+ it 'performs like a hashed fingerprint' do
+ expect(subject).to eq(Digest::SHA1.hexdigest(data.to_s))
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/alerting/alert_spec.rb b/spec/lib/gitlab/alerting/alert_spec.rb
index a0582515f3d..d582ff6f32a 100644
--- a/spec/lib/gitlab/alerting/alert_spec.rb
+++ b/spec/lib/gitlab/alerting/alert_spec.rb
@@ -253,7 +253,7 @@ describe Gitlab::Alerting::Alert do
include_context 'gitlab alert'
it 'returns a fingerprint' do
- plain_fingerprint = [alert.metric_id, alert.starts_at].join('/')
+ plain_fingerprint = [alert.metric_id, alert.starts_at_raw].join('/')
is_expected.to eq(Digest::SHA1.hexdigest(plain_fingerprint))
end
@@ -263,7 +263,7 @@ describe Gitlab::Alerting::Alert do
include_context 'full query'
it 'returns a fingerprint' do
- plain_fingerprint = [alert.starts_at, alert.title, alert.full_query].join('/')
+ plain_fingerprint = [alert.starts_at_raw, alert.title, alert.full_query].join('/')
is_expected.to eq(Digest::SHA1.hexdigest(plain_fingerprint))
end
diff --git a/spec/lib/gitlab/alerting/notification_payload_parser_spec.rb b/spec/lib/gitlab/alerting/notification_payload_parser_spec.rb
index f32095b3c86..889efae9585 100644
--- a/spec/lib/gitlab/alerting/notification_payload_parser_spec.rb
+++ b/spec/lib/gitlab/alerting/notification_payload_parser_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require 'fast_spec_helper'
+require 'spec_helper'
describe Gitlab::Alerting::NotificationPayloadParser do
describe '.call' do
@@ -89,6 +89,39 @@ describe Gitlab::Alerting::NotificationPayloadParser do
end
end
+ context 'with fingerprint' do
+ before do
+ payload[:fingerprint] = data
+ end
+
+ shared_examples 'fingerprint generation' do
+ it 'generates the fingerprint correctly' do
+ expect(result).to eq(Gitlab::AlertManagement::Fingerprint.generate(data))
+ end
+ end
+
+ context 'with blank fingerprint' do
+ it_behaves_like 'fingerprint generation' do
+ let(:data) { ' ' }
+ let(:result) { subject.dig('annotations', 'fingerprint') }
+ end
+ end
+
+ context 'with fingerprint given' do
+ it_behaves_like 'fingerprint generation' do
+ let(:data) { 'fingerprint' }
+ let(:result) { subject.dig('annotations', 'fingerprint') }
+ end
+ end
+
+ context 'with array fingerprint given' do
+ it_behaves_like 'fingerprint generation' do
+ let(:data) { [1, 'fingerprint', 'given'] }
+ let(:result) { subject.dig('annotations', 'fingerprint') }
+ end
+ end
+ end
+
context 'when payload attributes have blank lines' do
let(:payload) do
{
diff --git a/spec/lib/gitlab/analytics/cycle_analytics/base_query_builder_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/base_query_builder_spec.rb
index 0fc9d3c1e9e..250e2f16aec 100644
--- a/spec/lib/gitlab/analytics/cycle_analytics/base_query_builder_spec.rb
+++ b/spec/lib/gitlab/analytics/cycle_analytics/base_query_builder_spec.rb
@@ -6,7 +6,8 @@ describe Gitlab::Analytics::CycleAnalytics::BaseQueryBuilder do
let_it_be(:project) { create(:project, :empty_repo) }
let_it_be(:mr1) { create(:merge_request, target_project: project, source_project: project, allow_broken: true, created_at: 3.months.ago) }
let_it_be(:mr2) { create(:merge_request, target_project: project, source_project: project, allow_broken: true, created_at: 1.month.ago) }
- let(:params) { {} }
+ let_it_be(:user) { create(:user) }
+ let(:params) { { current_user: user } }
let(:records) do
stage = build(:cycle_analytics_project_stage, {
start_event_identifier: :merge_request_created,
@@ -17,6 +18,7 @@ describe Gitlab::Analytics::CycleAnalytics::BaseQueryBuilder do
end
before do
+ project.add_maintainer(user)
mr1.metrics.update!(merged_at: 1.month.ago)
mr2.metrics.update!(merged_at: Time.now)
end
diff --git a/spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb
index 334cab0b799..e3429b0ca57 100644
--- a/spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb
+++ b/spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb
@@ -23,7 +23,7 @@ describe Gitlab::Analytics::CycleAnalytics::RecordsFetcher do
describe '#serialized_records' do
shared_context 'when records are loaded by maintainer' do
before do
- project.add_user(user, Gitlab::Access::MAINTAINER)
+ project.add_user(user, Gitlab::Access::DEVELOPER)
end
it 'returns all records' do
@@ -103,6 +103,8 @@ describe Gitlab::Analytics::CycleAnalytics::RecordsFetcher do
latest_build_finished_at: 7.days.ago,
pipeline: ci_build2.pipeline
})
+
+ project.add_user(user, Gitlab::Access::MAINTAINER)
end
context 'returns build records' do
diff --git a/spec/lib/gitlab/auth/auth_finders_spec.rb b/spec/lib/gitlab/auth/auth_finders_spec.rb
index 774a87752b9..2aef206c7fd 100644
--- a/spec/lib/gitlab/auth/auth_finders_spec.rb
+++ b/spec/lib/gitlab/auth/auth_finders_spec.rb
@@ -4,6 +4,7 @@ require 'spec_helper'
describe Gitlab::Auth::AuthFinders do
include described_class
+ include HttpBasicAuthHelpers
let(:user) { create(:user) }
let(:env) do
@@ -22,10 +23,7 @@ describe Gitlab::Auth::AuthFinders do
end
def set_basic_auth_header(username, password)
- set_header(
- 'HTTP_AUTHORIZATION',
- ActionController::HttpAuthentication::Basic.encode_credentials(username, password)
- )
+ env.merge!(basic_auth_header(username, password))
end
describe '#find_user_from_warden' do
@@ -653,6 +651,24 @@ describe Gitlab::Auth::AuthFinders do
it_behaves_like 'job token params', described_class::JOB_TOKEN_PARAM
it_behaves_like 'job token params', described_class::RUNNER_JOB_TOKEN_PARAM
end
+
+ context 'when the job token is provided via basic auth' do
+ let(:route_authentication_setting) { { job_token_allowed: :basic_auth } }
+ let(:username) { Ci::Build::CI_REGISTRY_USER }
+ let(:token) { job.token }
+
+ before do
+ set_basic_auth_header(username, token)
+ end
+
+ it { is_expected.to eq(user) }
+
+ context 'credentials are provided but route setting is incorrect' do
+ let(:route_authentication_setting) { { job_token_allowed: :unknown } }
+
+ it { is_expected.to be_nil }
+ end
+ end
end
describe '#find_runner_from_token' do
diff --git a/spec/lib/gitlab/auth/ldap/person_spec.rb b/spec/lib/gitlab/auth/ldap/person_spec.rb
index e90917cfce1..403a48d40ef 100644
--- a/spec/lib/gitlab/auth/ldap/person_spec.rb
+++ b/spec/lib/gitlab/auth/ldap/person_spec.rb
@@ -57,14 +57,17 @@ describe Gitlab::Auth::Ldap::Person do
'attributes' => {
'name' => 'cn',
'email' => 'mail',
- 'username' => %w(uid mail memberof)
+ 'username' => %w(uid mail),
+ 'first_name' => ''
}
}
)
config = Gitlab::Auth::Ldap::Config.new('ldapmain')
ldap_attributes = described_class.ldap_attributes(config)
- expect(ldap_attributes).to match_array(%w(dn uid cn mail memberof))
+ expect(ldap_attributes).to include('dn', 'uid', 'cn', 'mail')
+ expect(ldap_attributes).to be_present
+ expect(ldap_attributes.uniq!).to eq(nil)
end
end
diff --git a/spec/lib/gitlab/background_migration/merge_request_assignees_migration_progress_check_spec.rb b/spec/lib/gitlab/background_migration/merge_request_assignees_migration_progress_check_spec.rb
index eecd290e3ca..9dd97b58014 100644
--- a/spec/lib/gitlab/background_migration/merge_request_assignees_migration_progress_check_spec.rb
+++ b/spec/lib/gitlab/background_migration/merge_request_assignees_migration_progress_check_spec.rb
@@ -54,6 +54,10 @@ describe Gitlab::BackgroundMigration::MergeRequestAssigneesMigrationProgressChec
end
context 'when there are no scheduled, or retrying or dead' do
+ before do
+ stub_feature_flags(multiple_merge_request_assignees: false)
+ end
+
it 'enables feature' do
allow(Gitlab::BackgroundMigration).to receive(:exists?)
.with('PopulateMergeRequestAssigneesTable')
@@ -67,9 +71,9 @@ describe Gitlab::BackgroundMigration::MergeRequestAssigneesMigrationProgressChec
.with('PopulateMergeRequestAssigneesTable')
.and_return(false)
- expect(Feature).to receive(:enable).with(:multiple_merge_request_assignees)
-
described_class.new.perform
+
+ expect(Feature.enabled?(:multiple_merge_request_assignees)).to eq(true)
end
end
diff --git a/spec/lib/gitlab/background_migration/reset_merge_status_spec.rb b/spec/lib/gitlab/background_migration/reset_merge_status_spec.rb
index 40340f89448..e057aea6bb3 100644
--- a/spec/lib/gitlab/background_migration/reset_merge_status_spec.rb
+++ b/spec/lib/gitlab/background_migration/reset_merge_status_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Gitlab::BackgroundMigration::ResetMergeStatus, schema: 20190528180441 do
+describe Gitlab::BackgroundMigration::ResetMergeStatus do
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
let(:namespace) { namespaces.create(name: 'gitlab', path: 'gitlab-org') }
@@ -23,24 +23,24 @@ describe Gitlab::BackgroundMigration::ResetMergeStatus, schema: 20190528180441 d
end
it 'correctly updates opened mergeable MRs to unchecked' do
- create_merge_request(1, state: 'opened', merge_status: 'can_be_merged')
- create_merge_request(2, state: 'opened', merge_status: 'can_be_merged')
- create_merge_request(3, state: 'opened', merge_status: 'can_be_merged')
- create_merge_request(4, state: 'merged', merge_status: 'can_be_merged')
- create_merge_request(5, state: 'opened', merge_status: 'cannot_be_merged')
+ create_merge_request(1, state_id: MergeRequest.available_states[:opened], merge_status: 'can_be_merged')
+ create_merge_request(2, state_id: MergeRequest.available_states[:opened], merge_status: 'can_be_merged')
+ create_merge_request(3, state_id: MergeRequest.available_states[:opened], merge_status: 'can_be_merged')
+ create_merge_request(4, state_id: MergeRequest.available_states[:merged], merge_status: 'can_be_merged')
+ create_merge_request(5, state_id: MergeRequest.available_states[:opened], merge_status: 'cannot_be_merged')
subject.perform(1, 5)
expected_rows = [
- { id: 1, state: 'opened', merge_status: 'unchecked' },
- { id: 2, state: 'opened', merge_status: 'unchecked' },
- { id: 3, state: 'opened', merge_status: 'unchecked' },
- { id: 4, state: 'merged', merge_status: 'can_be_merged' },
- { id: 5, state: 'opened', merge_status: 'cannot_be_merged' }
+ { id: 1, state_id: MergeRequest.available_states[:opened], merge_status: 'unchecked' },
+ { id: 2, state_id: MergeRequest.available_states[:opened], merge_status: 'unchecked' },
+ { id: 3, state_id: MergeRequest.available_states[:opened], merge_status: 'unchecked' },
+ { id: 4, state_id: MergeRequest.available_states[:merged], merge_status: 'can_be_merged' },
+ { id: 5, state_id: MergeRequest.available_states[:opened], merge_status: 'cannot_be_merged' }
]
rows = merge_requests.order(:id).map do |row|
- row.attributes.slice('id', 'state', 'merge_status').symbolize_keys
+ row.attributes.slice('id', 'state_id', 'merge_status').symbolize_keys
end
expect(rows).to eq(expected_rows)
diff --git a/spec/lib/gitlab/badge/coverage/report_spec.rb b/spec/lib/gitlab/badge/coverage/report_spec.rb
index 560072a3d83..284ca53a996 100644
--- a/spec/lib/gitlab/badge/coverage/report_spec.rb
+++ b/spec/lib/gitlab/badge/coverage/report_spec.rb
@@ -7,7 +7,7 @@ describe Gitlab::Badge::Coverage::Report do
let(:job_name) { nil }
let(:badge) do
- described_class.new(project, 'master', job_name)
+ described_class.new(project, 'master', opts: { job: job_name })
end
describe '#entity' do
diff --git a/spec/lib/gitlab/badge/coverage/template_spec.rb b/spec/lib/gitlab/badge/coverage/template_spec.rb
index b51d707a61d..3940b37830e 100644
--- a/spec/lib/gitlab/badge/coverage/template_spec.rb
+++ b/spec/lib/gitlab/badge/coverage/template_spec.rb
@@ -3,13 +3,33 @@
require 'spec_helper'
describe Gitlab::Badge::Coverage::Template do
- let(:badge) { double(entity: 'coverage', status: 90.00) }
+ let(:badge) { double(entity: 'coverage', status: 90.00, customization: {}) }
let(:template) { described_class.new(badge) }
describe '#key_text' do
- it 'is always says coverage' do
+ it 'says coverage by default' do
expect(template.key_text).to eq 'coverage'
end
+
+ context 'when custom key_text is defined' do
+ before do
+ allow(badge).to receive(:customization).and_return({ key_text: "custom text" })
+ end
+
+ it 'returns custom value' do
+ expect(template.key_text).to eq "custom text"
+ end
+
+ context 'when its size is larger than the max allowed value' do
+ before do
+ allow(badge).to receive(:customization).and_return({ key_text: 't' * 129 })
+ end
+
+ it 'returns default value' do
+ expect(template.key_text).to eq 'coverage'
+ end
+ end
+ end
end
describe '#value_text' do
@@ -41,9 +61,29 @@ describe Gitlab::Badge::Coverage::Template do
end
describe '#key_width' do
- it 'has a fixed key width' do
+ it 'is fixed by default' do
expect(template.key_width).to eq 62
end
+
+ context 'when custom key_width is defined' do
+ before do
+ allow(badge).to receive(:customization).and_return({ key_width: 101 })
+ end
+
+ it 'returns custom value' do
+ expect(template.key_width).to eq 101
+ end
+
+ context 'when it is larger than the max allowed value' do
+ before do
+ allow(badge).to receive(:customization).and_return({ key_width: 129 })
+ end
+
+ it 'returns default value' do
+ expect(template.key_width).to eq 62
+ end
+ end
+ end
end
describe '#value_width' do
diff --git a/spec/lib/gitlab/badge/pipeline/template_spec.rb b/spec/lib/gitlab/badge/pipeline/template_spec.rb
index da95c7219a4..751a5d6645e 100644
--- a/spec/lib/gitlab/badge/pipeline/template_spec.rb
+++ b/spec/lib/gitlab/badge/pipeline/template_spec.rb
@@ -3,13 +3,33 @@
require 'spec_helper'
describe Gitlab::Badge::Pipeline::Template do
- let(:badge) { double(entity: 'pipeline', status: 'success') }
+ let(:badge) { double(entity: 'pipeline', status: 'success', customization: {}) }
let(:template) { described_class.new(badge) }
describe '#key_text' do
- it 'is always says pipeline' do
+ it 'says pipeline by default' do
expect(template.key_text).to eq 'pipeline'
end
+
+ context 'when custom key_text is defined' do
+ before do
+ allow(badge).to receive(:customization).and_return({ key_text: 'custom text' })
+ end
+
+ it 'returns custom value' do
+ expect(template.key_text).to eq 'custom text'
+ end
+
+ context 'when its size is larger than the max allowed value' do
+ before do
+ allow(badge).to receive(:customization).and_return({ key_text: 't' * 129 })
+ end
+
+ it 'returns default value' do
+ expect(template.key_text).to eq 'pipeline'
+ end
+ end
+ end
end
describe '#value_text' do
@@ -18,6 +38,32 @@ describe Gitlab::Badge::Pipeline::Template do
end
end
+ describe '#key_width' do
+ it 'is fixed by default' do
+ expect(template.key_width).to eq 62
+ end
+
+ context 'when custom key_width is defined' do
+ before do
+ allow(badge).to receive(:customization).and_return({ key_width: 101 })
+ end
+
+ it 'returns custom value' do
+ expect(template.key_width).to eq 101
+ end
+
+ context 'when it is larger than the max allowed value' do
+ before do
+ allow(badge).to receive(:customization).and_return({ key_width: 129 })
+ end
+
+ it 'returns default value' do
+ expect(template.key_width).to eq 62
+ end
+ end
+ end
+ end
+
describe 'widths and text anchors' do
it 'has fixed width and text anchors' do
expect(template.width).to eq 116
diff --git a/spec/lib/gitlab/bitbucket_import/importer_spec.rb b/spec/lib/gitlab/bitbucket_import/importer_spec.rb
index b3c1f86c5ee..137d0fd4f9e 100644
--- a/spec/lib/gitlab/bitbucket_import/importer_spec.rb
+++ b/spec/lib/gitlab/bitbucket_import/importer_spec.rb
@@ -190,11 +190,14 @@ describe Gitlab::BitbucketImport::Importer do
context 'when importing a pull request throws an exception' do
before do
- allow(pull_request).to receive(:raw).and_return('hello world')
+ allow(pull_request).to receive(:raw).and_return({ error: "broken" })
allow(subject.client).to receive(:pull_request_comments).and_raise(Gitlab::HTTP::Error)
end
it 'logs an error without the backtrace' do
+ expect(Gitlab::ErrorTracking).to receive(:log_exception)
+ .with(instance_of(Gitlab::HTTP::Error), hash_including(raw_response: '{"error":"broken"}'))
+
subject.execute
expect(subject.errors.count).to eq(1)
diff --git a/spec/lib/gitlab/cache/import/caching_spec.rb b/spec/lib/gitlab/cache/import/caching_spec.rb
index e4aec0f4dec..7b4308d32ae 100644
--- a/spec/lib/gitlab/cache/import/caching_spec.rb
+++ b/spec/lib/gitlab/cache/import/caching_spec.rb
@@ -89,7 +89,7 @@ describe Gitlab::Cache::Import::Caching, :clean_gitlab_redis_cache do
end
describe '.write_multiple' do
- it 'sets multiple keys' do
+ it 'sets multiple keys when key_prefix not set' do
mapping = { 'foo' => 10, 'bar' => 20 }
described_class.write_multiple(mapping)
@@ -101,6 +101,19 @@ describe Gitlab::Cache::Import::Caching, :clean_gitlab_redis_cache do
expect(found).to eq(value.to_s)
end
end
+
+ it 'sets multiple keys with correct prefix' do
+ mapping = { 'foo' => 10, 'bar' => 20 }
+
+ described_class.write_multiple(mapping, key_prefix: 'pref/')
+
+ mapping.each do |key, value|
+ full_key = described_class.cache_key_for("pref/#{key}")
+ found = Gitlab::Redis::Cache.with { |r| r.get(full_key) }
+
+ expect(found).to eq(value.to_s)
+ end
+ end
end
describe '.expire' do
diff --git a/spec/lib/gitlab/chat_spec.rb b/spec/lib/gitlab/chat_spec.rb
index 08cc16314c5..be606fe6db1 100644
--- a/spec/lib/gitlab/chat_spec.rb
+++ b/spec/lib/gitlab/chat_spec.rb
@@ -5,19 +5,13 @@ require 'spec_helper'
describe Gitlab::Chat, :use_clean_rails_memory_store_caching do
describe '.available?' do
it 'returns true when the chatops feature is available' do
- allow(Feature)
- .to receive(:enabled?)
- .with(:chatops, default_enabled: true)
- .and_return(true)
+ stub_feature_flags(chatops: true)
expect(described_class).to be_available
end
it 'returns false when the chatops feature is not available' do
- allow(Feature)
- .to receive(:enabled?)
- .with(:chatops, default_enabled: true)
- .and_return(false)
+ stub_feature_flags(chatops: false)
expect(described_class).not_to be_available
end
diff --git a/spec/lib/gitlab/ci/build/credentials/factory_spec.rb b/spec/lib/gitlab/ci/build/credentials/factory_spec.rb
index 848adb2e6e5..159f89f4985 100644
--- a/spec/lib/gitlab/ci/build/credentials/factory_spec.rb
+++ b/spec/lib/gitlab/ci/build/credentials/factory_spec.rb
@@ -7,11 +7,13 @@ describe Gitlab::Ci::Build::Credentials::Factory do
subject { described_class.new(build).create! }
- class TestProvider
- def initialize(build); end
- end
-
before do
+ stub_const('TestProvider', Class.new)
+
+ TestProvider.class_eval do
+ def initialize(build); end
+ end
+
allow_next_instance_of(described_class) do |instance|
allow(instance).to receive(:providers).and_return([TestProvider])
end
diff --git a/spec/lib/gitlab/ci/build/releaser_spec.rb b/spec/lib/gitlab/ci/build/releaser_spec.rb
new file mode 100644
index 00000000000..2f7bca777dd
--- /dev/null
+++ b/spec/lib/gitlab/ci/build/releaser_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Ci::Build::Releaser do
+ subject { described_class.new(config: config[:release]).script }
+
+ describe '#script' do
+ context 'all nodes' do
+ let(:config) do
+ {
+ release: {
+ name: 'Release $CI_COMMIT_SHA',
+ description: 'Created using the release-cli $EXTRA_DESCRIPTION',
+ tag_name: 'release-$CI_COMMIT_SHA',
+ ref: '$CI_COMMIT_SHA'
+ }
+ }
+ end
+
+ it 'generates the script' do
+ expect(subject).to eq('release-cli create --name "Release $CI_COMMIT_SHA" --description "Created using the release-cli $EXTRA_DESCRIPTION" --tag-name "release-$CI_COMMIT_SHA" --ref "$CI_COMMIT_SHA"')
+ end
+ end
+
+ context 'individual nodes' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:node_name, :node_value, :result) do
+ 'name' | 'Release $CI_COMMIT_SHA' | 'release-cli create --name "Release $CI_COMMIT_SHA"'
+ 'description' | 'Release-cli $EXTRA_DESCRIPTION' | 'release-cli create --description "Release-cli $EXTRA_DESCRIPTION"'
+ 'tag_name' | 'release-$CI_COMMIT_SHA' | 'release-cli create --tag-name "release-$CI_COMMIT_SHA"'
+ 'ref' | '$CI_COMMIT_SHA' | 'release-cli create --ref "$CI_COMMIT_SHA"'
+ end
+
+ with_them do
+ let(:config) do
+ {
+ release: {
+ node_name => node_value
+ }
+ }
+ end
+
+ it 'generates the script' do
+ expect(subject).to eq(result)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/build/step_spec.rb b/spec/lib/gitlab/ci/build/step_spec.rb
index 9c1a8cf5e91..1cebda2cc7e 100644
--- a/spec/lib/gitlab/ci/build/step_spec.rb
+++ b/spec/lib/gitlab/ci/build/step_spec.rb
@@ -51,6 +51,30 @@ describe Gitlab::Ci::Build::Step do
end
end
+ describe '#from_release' do
+ subject { described_class.from_release(job) }
+
+ before do
+ job.run!
+ end
+
+ context 'with release' do
+ let(:job) { create(:ci_build, :release_options) }
+
+ it 'returns the release-cli command line' do
+ expect(subject.script).to eq("release-cli create --name \"Release $CI_COMMIT_SHA\" --description \"Created using the release-cli $EXTRA_DESCRIPTION\" --tag-name \"release-$CI_COMMIT_SHA\" --ref \"$CI_COMMIT_SHA\"")
+ end
+ end
+
+ context 'when release is empty' do
+ let(:job) { create(:ci_build) }
+
+ it 'does not fabricate an object' do
+ is_expected.to be_nil
+ end
+ end
+ end
+
describe '#from_after_script' do
let(:job) { create(:ci_build) }
@@ -61,7 +85,7 @@ describe Gitlab::Ci::Build::Step do
end
context 'when after_script is empty' do
- it 'doesn not fabricate an object' do
+ it 'does not fabricate an object' do
is_expected.to be_nil
end
end
diff --git a/spec/lib/gitlab/ci/config/entry/reports_spec.rb b/spec/lib/gitlab/ci/config/entry/reports_spec.rb
index 8c6c91d919e..2c12a88dedb 100644
--- a/spec/lib/gitlab/ci/config/entry/reports_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/reports_spec.rb
@@ -37,6 +37,7 @@ describe Gitlab::Ci::Config::Entry::Reports do
:junit | 'junit.xml'
:codequality | 'gl-code-quality-report.json'
:sast | 'gl-sast-report.json'
+ :secret_detection | 'gl-secret-detection-report.json'
:dependency_scanning | 'gl-dependency-scanning-report.json'
:container_scanning | 'gl-container-scanning-report.json'
:dast | 'gl-dast-report.json'
diff --git a/spec/lib/gitlab/ci/config/entry/retry_spec.rb b/spec/lib/gitlab/ci/config/entry/retry_spec.rb
index bb3c0b0004d..67253c71f6b 100644
--- a/spec/lib/gitlab/ci/config/entry/retry_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/retry_spec.rb
@@ -94,7 +94,7 @@ describe Gitlab::Ci::Config::Entry::Retry do
# sure this is catched, check explicitly that all of the documented
# values are valid. If they are not it means the documentation and this
# array must be updated.
- RETRY_WHEN_IN_DOCUMENTATION = %w[
+ retry_when_in_documentation = %w[
always
unknown_failure
script_failure
@@ -111,7 +111,7 @@ describe Gitlab::Ci::Config::Entry::Retry do
data_integrity_failure
].freeze
- RETRY_WHEN_IN_DOCUMENTATION.each do |reason|
+ retry_when_in_documentation.each do |reason|
context "with when from documentation `#{reason}`" do
let(:when) { reason }
diff --git a/spec/lib/gitlab/ci/parsers/terraform/tfplan_spec.rb b/spec/lib/gitlab/ci/parsers/terraform/tfplan_spec.rb
index 19cd75e586c..fec27c0f31a 100644
--- a/spec/lib/gitlab/ci/parsers/terraform/tfplan_spec.rb
+++ b/spec/lib/gitlab/ci/parsers/terraform/tfplan_spec.rb
@@ -8,7 +8,7 @@ describe Gitlab::Ci::Parsers::Terraform::Tfplan do
let(:reports) { Gitlab::Ci::Reports::TerraformReports.new }
- context 'when data is tfplan.json' do
+ context 'when data is invalid' do
context 'when there is no data' do
it 'raises an error' do
plan = '{}'
@@ -19,31 +19,67 @@ describe Gitlab::Ci::Parsers::Terraform::Tfplan do
end
end
- context 'when there is data' do
- it 'parses JSON and returns a report' do
- plan = '{ "create": 0, "update": 1, "delete": 0 }'
+ context 'when data is not a JSON file' do
+ it 'raises an error' do
+ plan = { 'create' => 0, 'update' => 1, 'delete' => 0 }.to_s
- expect { subject.parse!(plan, reports, artifact: artifact) }.not_to raise_error
+ expect { subject.parse!(plan, reports, artifact: artifact) }.to raise_error(
+ described_class::TfplanParserError
+ )
+ end
+ end
- expect(reports.plans).to match(
- a_hash_including(
- 'tfplan.json' => a_hash_including(
- 'create' => 0,
- 'update' => 1,
- 'delete' => 0
- )
- )
+ context 'when JSON is missing a required key' do
+ it 'raises an error' do
+ plan = '{ "wrong_key": 1 }'
+
+ expect { subject.parse!(plan, reports, artifact: artifact) }.to raise_error(
+ described_class::TfplanParserError
)
end
end
end
- context 'when data is not tfplan.json' do
- it 'raises an error' do
- plan = { 'create' => 0, 'update' => 1, 'delete' => 0 }.to_s
+ context 'when data is valid' do
+ it 'parses JSON and returns a report' do
+ plan = '{ "create": 0, "update": 1, "delete": 0 }'
+
+ expect { subject.parse!(plan, reports, artifact: artifact) }.not_to raise_error
- expect { subject.parse!(plan, reports, artifact: artifact) }.to raise_error(
- described_class::TfplanParserError
+ reports.plans.each do |key, hash_value|
+ expect(hash_value.keys).to match_array(%w[create delete job_name job_path update])
+ end
+
+ expect(reports.plans).to match(
+ a_hash_including(
+ artifact.job.id.to_s => a_hash_including(
+ 'create' => 0,
+ 'update' => 1,
+ 'delete' => 0,
+ 'job_name' => artifact.job.options.dig(:artifacts, :name).to_s
+ )
+ )
+ )
+ end
+
+ it 'parses JSON when extra keys are present' do
+ plan = '{ "create": 0, "update": 1, "delete": 0, "extra_key": 4 }'
+
+ expect { subject.parse!(plan, reports, artifact: artifact) }.not_to raise_error
+
+ reports.plans.each do |key, hash_value|
+ expect(hash_value.keys).to match_array(%w[create delete job_name job_path update])
+ end
+
+ expect(reports.plans).to match(
+ a_hash_including(
+ artifact.job.id.to_s => a_hash_including(
+ 'create' => 0,
+ 'update' => 1,
+ 'delete' => 0,
+ 'job_name' => artifact.job.options.dig(:artifacts, :name).to_s
+ )
+ )
)
end
end
diff --git a/spec/lib/gitlab/ci/pipeline/chain/seed_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/seed_spec.rb
index aa54f19b26c..1e1d5c2a724 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/seed_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/seed_spec.rb
@@ -39,6 +39,10 @@ describe Gitlab::Ci::Pipeline::Chain::Seed do
expect(pipeline.iid).to be_present
end
+ it 'ensures ci_ref' do
+ expect(pipeline.ci_ref).to be_present
+ end
+
it 'sets the seeds in the command object' do
expect(command.stage_seeds).to all(be_a Gitlab::Ci::Pipeline::Seed::Base)
expect(command.stage_seeds.count).to eq 1
diff --git a/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb
index f82e49f9323..ea04862ed74 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb
@@ -56,11 +56,24 @@ describe Gitlab::Ci::Pipeline::Chain::Sequence do
end
it 'adds sequence duration to duration histogram' do
- allow(command).to receive(:duration_histogram).and_return(histogram)
+ allow(command.metrics)
+ .to receive(:pipeline_creation_duration_histogram)
+ .and_return(histogram)
subject.build!
expect(histogram).to have_received(:observe)
end
+
+ it 'records pipeline size by pipeline source in a histogram' do
+ allow(command.metrics)
+ .to receive(:pipeline_size_histogram)
+ .and_return(histogram)
+
+ subject.build!
+
+ expect(histogram).to have_received(:observe)
+ .with({ source: 'push' }, 0)
+ end
end
end
diff --git a/spec/lib/gitlab/ci/pipeline/seed/build/cache_spec.rb b/spec/lib/gitlab/ci/pipeline/seed/build/cache_spec.rb
index fe19244659f..f5b43b5aeab 100644
--- a/spec/lib/gitlab/ci/pipeline/seed/build/cache_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/seed/build/cache_spec.rb
@@ -134,7 +134,7 @@ describe Gitlab::Ci::Pipeline::Seed::Build::Cache do
it_behaves_like 'foo/bar directory key'
end
- context 'with directories ending in slash star' do
+ context 'with directories ending in slash star', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/222356' do
let(:files) { ['foo/bar/*'] }
it_behaves_like 'foo/bar directory key'
diff --git a/spec/lib/gitlab/ci/reports/terraform_reports_spec.rb b/spec/lib/gitlab/ci/reports/terraform_reports_spec.rb
index 061029299ac..bfab30543ed 100644
--- a/spec/lib/gitlab/ci/reports/terraform_reports_spec.rb
+++ b/spec/lib/gitlab/ci/reports/terraform_reports_spec.rb
@@ -10,23 +10,23 @@ describe Gitlab::Ci::Reports::TerraformReports do
describe '#add_plan' do
context 'when providing two unique plans' do
it 'returns two plans' do
- subject.add_plan('a/tfplan.json', { 'create' => 0, 'update' => 1, 'delete' => 0 })
- subject.add_plan('b/tfplan.json', { 'create' => 0, 'update' => 1, 'delete' => 0 })
+ subject.add_plan('123', { 'create' => 1, 'update' => 2, 'delete' => 3 })
+ subject.add_plan('456', { 'create' => 4, 'update' => 5, 'delete' => 6 })
expect(subject.plans).to eq({
- 'a/tfplan.json' => { 'create' => 0, 'update' => 1, 'delete' => 0 },
- 'b/tfplan.json' => { 'create' => 0, 'update' => 1, 'delete' => 0 }
+ '123' => { 'create' => 1, 'update' => 2, 'delete' => 3 },
+ '456' => { 'create' => 4, 'update' => 5, 'delete' => 6 }
})
end
end
context 'when providing the same plan twice' do
it 'returns the last added plan' do
- subject.add_plan('tfplan.json', { 'create' => 0, 'update' => 0, 'delete' => 0 })
- subject.add_plan('tfplan.json', { 'create' => 0, 'update' => 1, 'delete' => 0 })
+ subject.add_plan('123', { 'create' => 0, 'update' => 0, 'delete' => 0 })
+ subject.add_plan('123', { 'create' => 1, 'update' => 2, 'delete' => 3 })
expect(subject.plans).to eq({
- 'tfplan.json' => { 'create' => 0, 'update' => 1, 'delete' => 0 }
+ '123' => { 'create' => 1, 'update' => 2, 'delete' => 3 }
})
end
end
diff --git a/spec/lib/gitlab/ci/status/bridge/factory_spec.rb b/spec/lib/gitlab/ci/status/bridge/factory_spec.rb
index 1f417781988..6c67864855d 100644
--- a/spec/lib/gitlab/ci/status/bridge/factory_spec.rb
+++ b/spec/lib/gitlab/ci/status/bridge/factory_spec.rb
@@ -59,12 +59,13 @@ describe Gitlab::Ci::Status::Bridge::Factory do
context 'failed with downstream_pipeline_creation_failed' do
before do
+ bridge.options = { downstream_errors: ['No stages / jobs for this pipeline.', 'other error'] }
bridge.failure_reason = 'downstream_pipeline_creation_failed'
end
it 'fabricates correct status_tooltip' do
expect(status.status_tooltip).to eq(
- "#{s_('CiStatusText|failed')} - (downstream pipeline can not be created)"
+ "#{s_('CiStatusText|failed')} - (downstream pipeline can not be created, No stages / jobs for this pipeline., other error)"
)
end
end
diff --git a/spec/lib/gitlab/ci/status/stage/play_manual_spec.rb b/spec/lib/gitlab/ci/status/stage/play_manual_spec.rb
index b0113b00ef0..bdcbfed918f 100644
--- a/spec/lib/gitlab/ci/status/stage/play_manual_spec.rb
+++ b/spec/lib/gitlab/ci/status/stage/play_manual_spec.rb
@@ -31,7 +31,7 @@ describe Gitlab::Ci::Status::Stage::PlayManual do
subject { play_manual.action_path }
- it { is_expected.to eq("/#{pipeline.project.full_path}/pipelines/#{pipeline.id}/stages/#{stage.name}/play_manual") }
+ it { is_expected.to eq("/#{pipeline.project.full_path}/-/pipelines/#{pipeline.id}/stages/#{stage.name}/play_manual") }
end
describe '#action_method' do
diff --git a/spec/lib/gitlab/ci/yaml_processor_spec.rb b/spec/lib/gitlab/ci/yaml_processor_spec.rb
index c93bb901981..1668149d8f5 100644
--- a/spec/lib/gitlab/ci/yaml_processor_spec.rb
+++ b/spec/lib/gitlab/ci/yaml_processor_spec.rb
@@ -1388,7 +1388,7 @@ module Gitlab
let(:processor) { Gitlab::Ci::YamlProcessor.new(YAML.dump(config)) }
let(:config) do
{
- stages: ["build", "test", "release"], # rubocop:disable Style/WordArray
+ stages: %w[build test release],
release: {
stage: "release",
only: ["tags"],
diff --git a/spec/lib/gitlab/cleanup/orphan_lfs_file_references_spec.rb b/spec/lib/gitlab/cleanup/orphan_lfs_file_references_spec.rb
new file mode 100644
index 00000000000..01cc0b30784
--- /dev/null
+++ b/spec/lib/gitlab/cleanup/orphan_lfs_file_references_spec.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Cleanup::OrphanLfsFileReferences do
+ let(:null_logger) { Logger.new('/dev/null') }
+ let(:project) { create(:project, :repository, lfs_enabled: true) }
+ let(:lfs_object) { create(:lfs_object) }
+
+ let!(:invalid_reference) { create(:lfs_objects_project, project: project, lfs_object: lfs_object) }
+
+ before do
+ allow(null_logger).to receive(:info)
+
+ allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
+
+ # Create a valid reference
+ oid = project.repository.gitaly_blob_client.get_all_lfs_pointers.first.lfs_oid
+ lfs_object2 = create(:lfs_object, oid: oid)
+ create(:lfs_objects_project, project: project, lfs_object: lfs_object2)
+ end
+
+ context 'dry run' do
+ it 'prints messages and does not delete references' do
+ expect(null_logger).to receive(:info).with("[DRY RUN] Looking for orphan LFS files for project #{project.name_with_namespace}")
+ expect(null_logger).to receive(:info).with("[DRY RUN] Found invalid references: 1")
+
+ expect { described_class.new(project, logger: null_logger).run! }
+ .not_to change { project.lfs_objects.count }
+ end
+ end
+
+ context 'regular run' do
+ it 'prints messages and deletes invalid reference' do
+ expect(null_logger).to receive(:info).with("Looking for orphan LFS files for project #{project.name_with_namespace}")
+ expect(null_logger).to receive(:info).with("Removed invalid references: 1")
+ expect(ProjectCacheWorker).to receive(:perform_async).with(project.id, [], [:lfs_objects_size])
+
+ expect { described_class.new(project, logger: null_logger, dry_run: false).run! }
+ .to change { project.lfs_objects.count }.from(2).to(1)
+
+ expect(LfsObjectsProject.exists?(invalid_reference.id)).to be_falsey
+ end
+ end
+end
diff --git a/spec/lib/gitlab/cluster/mixins/puma_cluster_spec.rb b/spec/lib/gitlab/cluster/mixins/puma_cluster_spec.rb
index b8ac8c5b95c..864529a6bf6 100644
--- a/spec/lib/gitlab/cluster/mixins/puma_cluster_spec.rb
+++ b/spec/lib/gitlab/cluster/mixins/puma_cluster_spec.rb
@@ -5,7 +5,9 @@ require 'spec_helper'
# For easier debugging set `PUMA_DEBUG=1`
describe Gitlab::Cluster::Mixins::PumaCluster do
- PUMA_STARTUP_TIMEOUT = 30
+ before do
+ stub_const('PUMA_STARTUP_TIMEOUT', 30)
+ end
context 'when running Puma in Cluster-mode' do
using RSpec::Parameterized::TableSyntax
diff --git a/spec/lib/gitlab/cluster/mixins/unicorn_http_server_spec.rb b/spec/lib/gitlab/cluster/mixins/unicorn_http_server_spec.rb
index ebe019924d5..3965eb722a0 100644
--- a/spec/lib/gitlab/cluster/mixins/unicorn_http_server_spec.rb
+++ b/spec/lib/gitlab/cluster/mixins/unicorn_http_server_spec.rb
@@ -5,7 +5,9 @@ require 'spec_helper'
# For easier debugging set `UNICORN_DEBUG=1`
describe Gitlab::Cluster::Mixins::UnicornHttpServer do
- UNICORN_STARTUP_TIMEOUT = 30
+ before do
+ stub_const('UNICORN_STARTUP_TIMEOUT', 30)
+ end
context 'when running Unicorn' do
using RSpec::Parameterized::TableSyntax
diff --git a/spec/lib/gitlab/code_navigation_path_spec.rb b/spec/lib/gitlab/code_navigation_path_spec.rb
index 938a2f821fd..07d4dfba622 100644
--- a/spec/lib/gitlab/code_navigation_path_spec.rb
+++ b/spec/lib/gitlab/code_navigation_path_spec.rb
@@ -12,12 +12,25 @@ describe Gitlab::CodeNavigationPath do
let(:commit_sha) { sha }
let(:path) { 'lib/app.rb' }
+ let(:lsif_path) { "/#{project.full_path}/-/jobs/#{job.id}/artifacts/raw/lsif/#{path}.json?file_type=lsif" }
subject { described_class.new(project, commit_sha).full_json_path_for(path) }
+ before do
+ stub_feature_flags(code_navigation: project)
+ end
+
context 'when a pipeline exist for a sha' do
it 'returns path to a file in the artifact' do
- expect(subject).to eq("/#{project.full_path}/-/jobs/#{job.id}/artifacts/raw/lsif/#{path}.json?file_type=lsif")
+ expect(subject).to eq(lsif_path)
+ end
+
+ context 'when passed commit sha is nil' do
+ let(:commit_sha) { nil }
+
+ it 'returns path to a file in the artifact' do
+ expect(subject).to eq(lsif_path)
+ end
end
end
@@ -25,7 +38,7 @@ describe Gitlab::CodeNavigationPath do
let(:commit_sha) { project.commit.id }
it 'returns path to a file in the artifact' do
- expect(subject).to eq("/#{project.full_path}/-/jobs/#{job.id}/artifacts/raw/lsif/#{path}.json?file_type=lsif")
+ expect(subject).to eq(lsif_path)
end
end
diff --git a/spec/lib/gitlab/config/entry/factory_spec.rb b/spec/lib/gitlab/config/entry/factory_spec.rb
index a614ef56a78..81ca5f2cba1 100644
--- a/spec/lib/gitlab/config/entry/factory_spec.rb
+++ b/spec/lib/gitlab/config/entry/factory_spec.rb
@@ -4,11 +4,14 @@ require 'spec_helper'
describe Gitlab::Config::Entry::Factory do
describe '#create!' do
- class Script < Gitlab::Config::Entry::Node
- include Gitlab::Config::Entry::Validatable
+ before do
+ stub_const('Script', Class.new(Gitlab::Config::Entry::Node))
+ Script.class_eval do
+ include Gitlab::Config::Entry::Validatable
- validations do
- validates :config, array_of_strings: true
+ validations do
+ validates :config, array_of_strings: true
+ end
end
end
diff --git a/spec/lib/gitlab/config/loader/yaml_spec.rb b/spec/lib/gitlab/config/loader/yaml_spec.rb
index a52c1c362e1..623fe927233 100644
--- a/spec/lib/gitlab/config/loader/yaml_spec.rb
+++ b/spec/lib/gitlab/config/loader/yaml_spec.rb
@@ -5,6 +5,16 @@ require 'spec_helper'
describe Gitlab::Config::Loader::Yaml do
let(:loader) { described_class.new(yml) }
+ let(:yml) do
+ <<~YAML
+ image: 'ruby:2.7'
+ texts:
+ nested_key: 'value1'
+ more_text:
+ more_nested_key: 'value2'
+ YAML
+ end
+
context 'when yaml syntax is correct' do
let(:yml) { 'image: ruby:2.7' }
@@ -61,6 +71,15 @@ describe Gitlab::Config::Loader::Yaml do
expect(loader).not_to be_valid
end
end
+
+ describe '#load_raw!' do
+ it 'raises error' do
+ expect { loader.load_raw! }.to raise_error(
+ Gitlab::Config::Loader::FormatError,
+ 'Invalid configuration format'
+ )
+ end
+ end
end
# Prevent Billion Laughs attack: https://gitlab.com/gitlab-org/gitlab-foss/issues/56018
@@ -123,4 +142,32 @@ describe Gitlab::Config::Loader::Yaml do
end
end
end
+
+ describe '#load_raw!' do
+ it 'loads keys as strings' do
+ expect(loader.load_raw!).to eq(
+ 'image' => 'ruby:2.7',
+ 'texts' => {
+ 'nested_key' => 'value1',
+ 'more_text' => {
+ 'more_nested_key' => 'value2'
+ }
+ }
+ )
+ end
+ end
+
+ describe '#load!' do
+ it 'symbolizes keys' do
+ expect(loader.load!).to eq(
+ image: 'ruby:2.7',
+ texts: {
+ nested_key: 'value1',
+ more_text: {
+ more_nested_key: 'value2'
+ }
+ }
+ )
+ end
+ end
end
diff --git a/spec/lib/gitlab/contributions_calendar_spec.rb b/spec/lib/gitlab/contributions_calendar_spec.rb
index 1154f029a8d..97742a3e815 100644
--- a/spec/lib/gitlab/contributions_calendar_spec.rb
+++ b/spec/lib/gitlab/contributions_calendar_spec.rb
@@ -42,7 +42,7 @@ describe Gitlab::ContributionsCalendar do
described_class.new(contributor, current_user)
end
- def create_event(project, day, hour = 0, action = Event::CREATED, target_symbol = :issue)
+ def create_event(project, day, hour = 0, action = :created, target_symbol = :issue)
@targets ||= {}
@targets[project] ||= create(target_symbol, project: project, author: contributor)
@@ -77,14 +77,14 @@ describe Gitlab::ContributionsCalendar do
end
it "counts the diff notes on merge request" do
- create_event(public_project, today, 0, Event::COMMENTED, :diff_note_on_merge_request)
+ create_event(public_project, today, 0, :commented, :diff_note_on_merge_request)
expect(calendar(contributor).activity_dates[today]).to eq(1)
end
it "counts the discussions on merge requests and issues" do
- create_event(public_project, today, 0, Event::COMMENTED, :discussion_note_on_merge_request)
- create_event(public_project, today, 2, Event::COMMENTED, :discussion_note_on_issue)
+ create_event(public_project, today, 0, :commented, :discussion_note_on_merge_request)
+ create_event(public_project, today, 2, :commented, :discussion_note_on_issue)
expect(calendar(contributor).activity_dates[today]).to eq(2)
end
diff --git a/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb b/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb
index a86278871ff..ccc99017e37 100644
--- a/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb
@@ -14,19 +14,29 @@ describe Gitlab::CycleAnalytics::StageSummary do
let(:stage_summary) { described_class.new(project, options).data }
describe "#new_issues" do
- subject { stage_summary.first[:value] }
+ subject { stage_summary.first }
- it "finds the number of issues created after the 'from date'" do
- Timecop.freeze(5.days.ago) { create(:issue, project: project) }
- Timecop.freeze(5.days.from_now) { create(:issue, project: project) }
+ context 'when from date is given' do
+ before do
+ Timecop.freeze(5.days.ago) { create(:issue, project: project) }
+ Timecop.freeze(5.days.from_now) { create(:issue, project: project) }
+ end
- expect(subject).to eq('1')
+ it "finds the number of issues 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_('New Issue', 'New Issues', 1))
+ end
+ end
end
it "doesn't find issues from other projects" do
Timecop.freeze(5.days.from_now) { create(:issue, project: create(:project)) }
- expect(subject).to eq('-')
+ expect(subject[:value]).to eq('-')
end
context 'when `to` parameter is given' do
@@ -38,38 +48,48 @@ describe Gitlab::CycleAnalytics::StageSummary do
it "doesn't find any record" do
options[:to] = Time.now
- expect(subject).to eq('-')
+ 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).to eq('2')
+ expect(subject[:value]).to eq('2')
end
end
end
describe "#commits" do
- subject { stage_summary.second[:value] }
+ subject { stage_summary.second }
+
+ context 'when from date is given' do
+ before do
+ Timecop.freeze(5.days.ago) { create_commit("Test message", project, user, 'master') }
+ Timecop.freeze(5.days.from_now) { create_commit("Test message", project, user, 'master') }
+ end
- it "finds the number of commits created after the 'from date'" do
- Timecop.freeze(5.days.ago) { create_commit("Test message", project, user, 'master') }
- Timecop.freeze(5.days.from_now) { create_commit("Test message", project, user, 'master') }
+ it "finds the number of commits created after the 'from date'" do
+ expect(subject[:value]).to eq('1')
+ end
- expect(subject).to eq('1')
+ it 'returns the localized title' do
+ Gitlab::I18n.with_locale(:ru) do
+ expect(subject[:title]).to eq(n_('Commit', 'Commits', 1))
+ end
+ end
end
it "doesn't find commits from other projects" do
Timecop.freeze(5.days.from_now) { create_commit("Test message", create(:project, :repository), user, 'master') }
- expect(subject).to eq('-')
+ expect(subject[:value]).to eq('-')
end
it "finds a large (> 100) number of commits if present" do
Timecop.freeze(5.days.from_now) { create_commit("Test message", project, user, 'master', count: 100) }
- expect(subject).to eq('100')
+ expect(subject[:value]).to eq('100')
end
context 'when `to` parameter is given' do
@@ -81,14 +101,14 @@ describe Gitlab::CycleAnalytics::StageSummary do
it "doesn't find any record" do
options[:to] = Time.now
- expect(subject).to eq('-')
+ 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).to eq('2')
+ expect(subject[:value]).to eq('2')
end
end
@@ -112,13 +132,23 @@ describe Gitlab::CycleAnalytics::StageSummary do
end
describe "#deploys" do
- subject { stage_summary.third[:value] }
+ subject { stage_summary.third }
- it "finds the number of deploys made created after the 'from date'" do
- Timecop.freeze(5.days.ago) { create(:deployment, :success, project: project) }
- Timecop.freeze(5.days.from_now) { create(:deployment, :success, project: project) }
+ 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
- expect(subject).to eq('1')
+ 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
@@ -126,7 +156,7 @@ describe Gitlab::CycleAnalytics::StageSummary do
create(:deployment, :success, project: create(:project, :repository))
end
- expect(subject).to eq('-')
+ expect(subject[:value]).to eq('-')
end
context 'when `to` parameter is given' do
@@ -138,14 +168,14 @@ describe Gitlab::CycleAnalytics::StageSummary do
it "doesn't find any record" do
options[:to] = Time.now
- expect(subject).to eq('-')
+ 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).to eq('2')
+ expect(subject[:value]).to eq('2')
end
end
end
diff --git a/spec/lib/gitlab/danger/changelog_spec.rb b/spec/lib/gitlab/danger/changelog_spec.rb
index 8929374fb87..130a4708cec 100644
--- a/spec/lib/gitlab/danger/changelog_spec.rb
+++ b/spec/lib/gitlab/danger/changelog_spec.rb
@@ -65,9 +65,7 @@ describe Gitlab::Danger::Changelog do
context 'added files contain a changelog' do
[
'changelogs/unreleased/entry.yml',
- 'ee/changelogs/unreleased/entry.yml',
- 'changelogs/unreleased-ee/entry.yml',
- 'ee/changelogs/unreleased-ee/entry.yml'
+ 'ee/changelogs/unreleased/entry.yml'
].each do |file_path|
let(:added_files) { [file_path] }
diff --git a/spec/lib/gitlab/danger/helper_spec.rb b/spec/lib/gitlab/danger/helper_spec.rb
index c2c881fd589..809064a540c 100644
--- a/spec/lib/gitlab/danger/helper_spec.rb
+++ b/spec/lib/gitlab/danger/helper_spec.rb
@@ -213,6 +213,7 @@ describe Gitlab::Danger::Helper do
'generator_templates/foo' | :backend
'vendor/languages.yml' | :backend
'vendor/licenses.csv' | :backend
+ 'file_hooks/examples/' | :backend
'Gemfile' | :backend
'Gemfile.lock' | :backend
@@ -233,6 +234,7 @@ describe Gitlab::Danger::Helper do
'.overcommit.yml.example' | :engineering_productivity
'.editorconfig' | :engineering_productivity
'tooling/overcommit/foo' | :engineering_productivity
+ '.codeclimate.yml' | :engineering_productivity
'lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml' | :backend
diff --git a/spec/lib/gitlab/danger/roulette_spec.rb b/spec/lib/gitlab/danger/roulette_spec.rb
index 4d41e2c45aa..b6148cd1407 100644
--- a/spec/lib/gitlab/danger/roulette_spec.rb
+++ b/spec/lib/gitlab/danger/roulette_spec.rb
@@ -6,40 +6,149 @@ require 'webmock/rspec'
require 'gitlab/danger/roulette'
describe Gitlab::Danger::Roulette do
+ let(:backend_maintainer) do
+ {
+ username: 'backend-maintainer',
+ name: 'Backend maintainer',
+ role: 'Backend engineer',
+ projects: { 'gitlab' => 'maintainer backend' }
+ }
+ end
+ let(:frontend_reviewer) do
+ {
+ username: 'frontend-reviewer',
+ name: 'Frontend reviewer',
+ role: 'Frontend engineer',
+ projects: { 'gitlab' => 'reviewer frontend' }
+ }
+ end
+ let(:frontend_maintainer) do
+ {
+ username: 'frontend-maintainer',
+ name: 'Frontend maintainer',
+ role: 'Frontend engineer',
+ projects: { 'gitlab' => "maintainer frontend" }
+ }
+ end
+ let(:software_engineer_in_test) do
+ {
+ username: 'software-engineer-in-test',
+ name: 'Software Engineer in Test',
+ role: 'Software Engineer in Test, Create:Source Code',
+ projects: {
+ 'gitlab' => 'reviewer qa',
+ 'gitlab-qa' => 'maintainer'
+ }
+ }
+ end
+ let(:engineering_productivity_reviewer) do
+ {
+ username: 'eng-prod-reviewer',
+ name: 'EP engineer',
+ role: 'Engineering Productivity',
+ projects: { 'gitlab' => 'reviewer backend' }
+ }
+ end
+
let(:teammate_json) do
- <<~JSON
[
- {
- "username": "in-gitlab-ce",
- "name": "CE maintainer",
- "projects":{ "gitlab-ce": "maintainer backend" }
- },
- {
- "username": "in-gitlab-ee",
- "name": "EE reviewer",
- "projects":{ "gitlab-ee": "reviewer frontend" }
- }
- ]
- JSON
+ backend_maintainer,
+ frontend_maintainer,
+ frontend_reviewer,
+ software_engineer_in_test,
+ engineering_productivity_reviewer
+ ].to_json
end
- let(:ce_teammate_matcher) do
+ subject(:roulette) { Object.new.extend(described_class) }
+
+ def matching_teammate(person)
satisfy do |teammate|
- teammate.username == 'in-gitlab-ce' &&
- teammate.name == 'CE maintainer' &&
- teammate.projects == { 'gitlab-ce' => 'maintainer backend' }
+ teammate.username == person[:username] &&
+ teammate.name == person[:name] &&
+ teammate.role == person[:role] &&
+ teammate.projects == person[:projects]
end
end
- let(:ee_teammate_matcher) do
- satisfy do |teammate|
- teammate.username == 'in-gitlab-ee' &&
- teammate.name == 'EE reviewer' &&
- teammate.projects == { 'gitlab-ee' => 'reviewer frontend' }
+ def matching_spin(category, reviewer: { username: nil }, maintainer: { username: nil }, optional: nil)
+ satisfy do |spin|
+ spin.category == category &&
+ spin.reviewer&.username == reviewer[:username] &&
+ spin.maintainer&.username == maintainer[:username] &&
+ spin.optional_role == optional
end
end
- subject(:roulette) { Object.new.extend(described_class) }
+ describe '#spin' do
+ let!(:project) { 'gitlab' }
+ let!(:branch_name) { 'a-branch' }
+ let!(:mr_labels) { ['backend', 'devops::create'] }
+ let!(:author) { Gitlab::Danger::Teammate.new('username' => 'filipa') }
+
+ before do
+ [
+ backend_maintainer,
+ frontend_reviewer,
+ frontend_maintainer,
+ software_engineer_in_test,
+ engineering_productivity_reviewer
+ ].each do |person|
+ stub_person_status(instance_double(Gitlab::Danger::Teammate, username: person[:username]), message: 'making GitLab magic')
+ end
+
+ WebMock
+ .stub_request(:get, described_class::ROULETTE_DATA_URL)
+ .to_return(body: teammate_json)
+ allow(subject).to receive_message_chain(:gitlab, :mr_author).and_return(author.username)
+ allow(subject).to receive_message_chain(:gitlab, :mr_labels).and_return(mr_labels)
+ end
+
+ context 'when change contains backend category' do
+ it 'assigns backend reviewer and maintainer' do
+ categories = [:backend]
+ spins = subject.spin(project, categories, branch_name)
+
+ expect(spins).to contain_exactly(matching_spin(:backend, reviewer: engineering_productivity_reviewer, maintainer: backend_maintainer))
+ end
+ end
+
+ context 'when change contains frontend category' do
+ it 'assigns frontend reviewer and maintainer' do
+ categories = [:frontend]
+ spins = subject.spin(project, categories, branch_name)
+
+ expect(spins).to contain_exactly(matching_spin(:frontend, reviewer: frontend_reviewer, maintainer: frontend_maintainer))
+ end
+ end
+
+ context 'when change contains QA category' do
+ it 'assigns QA reviewer and sets optional QA maintainer' do
+ categories = [:qa]
+ spins = subject.spin(project, categories, branch_name)
+
+ expect(spins).to contain_exactly(matching_spin(:qa, reviewer: software_engineer_in_test, optional: :maintainer))
+ end
+ end
+
+ context 'when change contains Engineering Productivity category' do
+ it 'assigns Engineering Productivity reviewer and fallback to backend maintainer' do
+ categories = [:engineering_productivity]
+ spins = subject.spin(project, categories, branch_name)
+
+ expect(spins).to contain_exactly(matching_spin(:engineering_productivity, reviewer: engineering_productivity_reviewer, maintainer: backend_maintainer))
+ end
+ end
+
+ context 'when change contains test category' do
+ it 'assigns corresponding SET and sets optional test maintainer' do
+ categories = [:test]
+ spins = subject.spin(project, categories, branch_name)
+
+ expect(spins).to contain_exactly(matching_spin(:test, reviewer: software_engineer_in_test, optional: :maintainer))
+ end
+ end
+ end
describe '#team' do
subject(:team) { roulette.team }
@@ -76,7 +185,15 @@ describe Gitlab::Danger::Roulette do
end
it 'returns an array of teammates' do
- is_expected.to contain_exactly(ce_teammate_matcher, ee_teammate_matcher)
+ expected_teammates = [
+ matching_teammate(backend_maintainer),
+ matching_teammate(frontend_reviewer),
+ matching_teammate(frontend_maintainer),
+ matching_teammate(software_engineer_in_test),
+ matching_teammate(engineering_productivity_reviewer)
+ ]
+
+ is_expected.to contain_exactly(*expected_teammates)
end
it 'memoizes the result' do
@@ -86,7 +203,7 @@ describe Gitlab::Danger::Roulette do
end
describe '#project_team' do
- subject { roulette.project_team('gitlab-ce') }
+ subject { roulette.project_team('gitlab-qa') }
before do
WebMock
@@ -95,7 +212,7 @@ describe Gitlab::Danger::Roulette do
end
it 'filters team by project_name' do
- is_expected.to contain_exactly(ce_teammate_matcher)
+ is_expected.to contain_exactly(matching_teammate(software_engineer_in_test))
end
end
@@ -136,15 +253,15 @@ describe Gitlab::Danger::Roulette do
it 'excludes person with no capacity' do
expect(subject.spin_for_person([no_capacity], random: Random.new)).to be_nil
end
+ end
- private
+ private
- def stub_person_status(person, message: 'dummy message', emoji: 'unicorn')
- body = { message: message, emoji: emoji }.to_json
+ def stub_person_status(person, message: 'dummy message', emoji: 'unicorn')
+ body = { message: message, emoji: emoji }.to_json
- WebMock
- .stub_request(:get, "https://gitlab.com/api/v4/users/#{person.username}/status")
- .to_return(body: body)
- end
+ WebMock
+ .stub_request(:get, "https://gitlab.com/api/v4/users/#{person.username}/status")
+ .to_return(body: body)
end
end
diff --git a/spec/lib/gitlab/data_builder/alert_spec.rb b/spec/lib/gitlab/data_builder/alert_spec.rb
new file mode 100644
index 00000000000..b881fb8139b
--- /dev/null
+++ b/spec/lib/gitlab/data_builder/alert_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::DataBuilder::Alert do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:alert) { create(:alert_management_alert, project: project) }
+
+ describe '.build' do
+ let_it_be(:data) { described_class.build(alert) }
+
+ it { expect(data).to be_a(Hash) }
+ it { expect(data[:object_kind]).to eq('alert') }
+
+ it 'contains the correct object attributes', :aggregate_failures do
+ object_attributes = data[:object_attributes]
+
+ expect(object_attributes[:title]).to eq(alert.title)
+ expect(object_attributes[:url]).to eq(Gitlab::Routing.url_helpers.details_project_alert_management_url(project, alert.iid))
+ expect(object_attributes[:severity]).to eq(alert.severity)
+ expect(object_attributes[:events]).to eq(alert.events)
+ expect(object_attributes[:status]).to eq(alert.status_name)
+ expect(object_attributes[:started_at]).to eq(alert.started_at)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/database/custom_structure_spec.rb b/spec/lib/gitlab/database/custom_structure_spec.rb
new file mode 100644
index 00000000000..f03b5ed0a7f
--- /dev/null
+++ b/spec/lib/gitlab/database/custom_structure_spec.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Database::CustomStructure do
+ let_it_be(:structure) { described_class.new }
+ let_it_be(:filepath) { Rails.root.join(described_class::CUSTOM_DUMP_FILE) }
+ let_it_be(:file_header) do
+ <<~DATA
+ -- this file tracks custom GitLab data, such as foreign keys referencing partitioned tables
+ -- more details can be found in the issue: https://gitlab.com/gitlab-org/gitlab/-/issues/201872
+ SET search_path=public;
+ DATA
+ end
+
+ let(:io) { StringIO.new }
+
+ before do
+ allow(File).to receive(:open).with(filepath, anything).and_yield(io)
+ end
+
+ context 'when there are no partitioned_foreign_keys' do
+ it 'dumps a valid structure file' do
+ structure.dump
+
+ expect(io.string).to eq("#{file_header}\n")
+ end
+ end
+
+ context 'when there are partitioned_foreign_keys' do
+ let!(:first_fk) do
+ Gitlab::Database::PartitioningMigrationHelpers::PartitionedForeignKey.create(
+ cascade_delete: true, from_table: 'issues', from_column: 'project_id', to_table: 'projects', to_column: 'id')
+ end
+ let!(:second_fk) do
+ Gitlab::Database::PartitioningMigrationHelpers::PartitionedForeignKey.create(
+ cascade_delete: false, from_table: 'issues', from_column: 'moved_to_id', to_table: 'issues', to_column: 'id')
+ end
+
+ it 'dumps a file with the command to restore the current keys' do
+ structure.dump
+
+ expect(io.string).to eq(<<~DATA)
+ #{file_header}
+ COPY partitioned_foreign_keys (id, cascade_delete, from_table, from_column, to_table, to_column) FROM STDIN;
+ #{first_fk.id}\ttrue\tissues\tproject_id\tprojects\tid
+ #{second_fk.id}\tfalse\tissues\tmoved_to_id\tissues\tid
+ \\.
+ DATA
+
+ first_fk.destroy
+ io.truncate(0)
+ io.rewind
+
+ structure.dump
+
+ expect(io.string).to eq(<<~DATA)
+ #{file_header}
+ COPY partitioned_foreign_keys (id, cascade_delete, from_table, from_column, to_table, to_column) FROM STDIN;
+ #{second_fk.id}\tfalse\tissues\tmoved_to_id\tissues\tid
+ \\.
+ DATA
+ end
+ end
+end
diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb
index 203d39be22b..bed444ee7c7 100644
--- a/spec/lib/gitlab/database/migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migration_helpers_spec.rb
@@ -1539,12 +1539,17 @@ describe Gitlab::Database::MigrationHelpers do
end
describe '#create_or_update_plan_limit' do
- class self::Plan < ActiveRecord::Base
- self.table_name = 'plans'
- end
+ before do
+ stub_const('Plan', Class.new(ActiveRecord::Base))
+ stub_const('PlanLimits', Class.new(ActiveRecord::Base))
+
+ Plan.class_eval do
+ self.table_name = 'plans'
+ end
- class self::PlanLimits < ActiveRecord::Base
- self.table_name = 'plan_limits'
+ PlanLimits.class_eval do
+ self.table_name = 'plan_limits'
+ end
end
it 'properly escapes names' do
@@ -1560,28 +1565,28 @@ describe Gitlab::Database::MigrationHelpers do
context 'when plan does not exist' do
it 'does not create any plan limits' do
expect { model.create_or_update_plan_limit('project_hooks', 'plan_name', 10) }
- .not_to change { self.class::PlanLimits.count }
+ .not_to change { PlanLimits.count }
end
end
context 'when plan does exist' do
- let!(:plan) { self.class::Plan.create!(name: 'plan_name') }
+ let!(:plan) { Plan.create!(name: 'plan_name') }
context 'when limit does not exist' do
it 'inserts a new plan limits' do
expect { model.create_or_update_plan_limit('project_hooks', 'plan_name', 10) }
- .to change { self.class::PlanLimits.count }.by(1)
+ .to change { PlanLimits.count }.by(1)
- expect(self.class::PlanLimits.pluck(:project_hooks)).to contain_exactly(10)
+ expect(PlanLimits.pluck(:project_hooks)).to contain_exactly(10)
end
end
context 'when limit does exist' do
- let!(:plan_limit) { self.class::PlanLimits.create!(plan_id: plan.id) }
+ let!(:plan_limit) { PlanLimits.create!(plan_id: plan.id) }
it 'updates an existing plan limits' do
expect { model.create_or_update_plan_limit('project_hooks', 'plan_name', 999) }
- .not_to change { self.class::PlanLimits.count }
+ .not_to change { PlanLimits.count }
expect(plan_limit.reload.project_hooks).to eq(999)
end
@@ -1605,19 +1610,23 @@ describe Gitlab::Database::MigrationHelpers do
describe '#backfill_iids' do
include MigrationsHelpers
- class self::Issue < ActiveRecord::Base
- include AtomicInternalId
+ before do
+ stub_const('Issue', Class.new(ActiveRecord::Base))
+
+ Issue.class_eval do
+ include AtomicInternalId
- self.table_name = 'issues'
- self.inheritance_column = :_type_disabled
+ self.table_name = 'issues'
+ self.inheritance_column = :_type_disabled
- belongs_to :project, class_name: "::Project"
+ belongs_to :project, class_name: "::Project"
- has_internal_id :iid,
- scope: :project,
- init: ->(s) { s&.project&.issues&.maximum(:iid) },
- backfill: true,
- presence: false
+ has_internal_id :iid,
+ scope: :project,
+ init: ->(s) { s&.project&.issues&.maximum(:iid) },
+ backfill: true,
+ presence: false
+ end
end
let(:namespaces) { table(:namespaces) }
@@ -1636,7 +1645,7 @@ describe Gitlab::Database::MigrationHelpers do
model.backfill_iids('issues')
- issue = self.class::Issue.create!(project_id: project.id)
+ issue = Issue.create!(project_id: project.id)
expect(issue.iid).to eq(1)
end
@@ -1647,7 +1656,7 @@ describe Gitlab::Database::MigrationHelpers do
model.backfill_iids('issues')
- issue_b = self.class::Issue.create!(project_id: project.id)
+ issue_b = Issue.create!(project_id: project.id)
expect(issue_a.reload.iid).to eq(1)
expect(issue_b.iid).to eq(2)
@@ -1662,8 +1671,8 @@ describe Gitlab::Database::MigrationHelpers do
model.backfill_iids('issues')
- issue_a = self.class::Issue.create!(project_id: project_a.id)
- issue_b = self.class::Issue.create!(project_id: project_b.id)
+ issue_a = Issue.create!(project_id: project_a.id)
+ issue_b = Issue.create!(project_id: project_b.id)
expect(issue_a.iid).to eq(2)
expect(issue_b.iid).to eq(3)
@@ -1672,7 +1681,7 @@ describe Gitlab::Database::MigrationHelpers do
context 'when the new code creates a row post deploy but before the migration runs' do
it 'does not change the row iid' do
project = setup
- issue = self.class::Issue.create!(project_id: project.id)
+ issue = Issue.create!(project_id: project.id)
model.backfill_iids('issues')
@@ -1683,7 +1692,7 @@ describe Gitlab::Database::MigrationHelpers do
project = setup
issue_a = issues.create!(project_id: project.id)
issue_b = issues.create!(project_id: project.id)
- issue_c = self.class::Issue.create!(project_id: project.id)
+ issue_c = Issue.create!(project_id: project.id)
model.backfill_iids('issues')
@@ -1697,8 +1706,8 @@ describe Gitlab::Database::MigrationHelpers do
project_b = setup
issue_a = issues.create!(project_id: project_a.id)
issue_b = issues.create!(project_id: project_b.id)
- issue_c = self.class::Issue.create!(project_id: project_a.id)
- issue_d = self.class::Issue.create!(project_id: project_b.id)
+ issue_c = Issue.create!(project_id: project_a.id)
+ issue_d = Issue.create!(project_id: project_b.id)
model.backfill_iids('issues')
@@ -1712,12 +1721,12 @@ describe Gitlab::Database::MigrationHelpers do
project = setup
issue_a = issues.create!(project_id: project.id)
issue_b = issues.create!(project_id: project.id)
- issue_c = self.class::Issue.create!(project_id: project.id)
+ issue_c = Issue.create!(project_id: project.id)
model.backfill_iids('issues')
- issue_d = self.class::Issue.create!(project_id: project.id)
- issue_e = self.class::Issue.create!(project_id: project.id)
+ issue_d = Issue.create!(project_id: project.id)
+ issue_e = Issue.create!(project_id: project.id)
expect(issue_a.reload.iid).to eq(1)
expect(issue_b.reload.iid).to eq(2)
@@ -1731,14 +1740,14 @@ describe Gitlab::Database::MigrationHelpers do
project_b = setup
issue_a = issues.create!(project_id: project_a.id)
issue_b = issues.create!(project_id: project_b.id)
- issue_c = self.class::Issue.create!(project_id: project_a.id)
- issue_d = self.class::Issue.create!(project_id: project_b.id)
+ issue_c = Issue.create!(project_id: project_a.id)
+ issue_d = Issue.create!(project_id: project_b.id)
model.backfill_iids('issues')
- issue_e = self.class::Issue.create!(project_id: project_a.id)
- issue_f = self.class::Issue.create!(project_id: project_b.id)
- issue_g = self.class::Issue.create!(project_id: project_a.id)
+ issue_e = Issue.create!(project_id: project_a.id)
+ issue_f = Issue.create!(project_id: project_b.id)
+ issue_g = Issue.create!(project_id: project_a.id)
expect(issue_a.reload.iid).to eq(1)
expect(issue_b.reload.iid).to eq(1)
@@ -1754,7 +1763,7 @@ describe Gitlab::Database::MigrationHelpers do
it 'backfills iids' do
project = setup
issue_a = issues.create!(project_id: project.id)
- issue_b = self.class::Issue.create!(project_id: project.id)
+ issue_b = Issue.create!(project_id: project.id)
issue_c = issues.create!(project_id: project.id)
model.backfill_iids('issues')
@@ -1768,12 +1777,12 @@ describe Gitlab::Database::MigrationHelpers do
project = setup
issue_a = issues.create!(project_id: project.id)
issue_b = issues.create!(project_id: project.id)
- issue_c = self.class::Issue.create!(project_id: project.id)
+ issue_c = Issue.create!(project_id: project.id)
issue_d = issues.create!(project_id: project.id)
model.backfill_iids('issues')
- issue_e = self.class::Issue.create!(project_id: project.id)
+ issue_e = Issue.create!(project_id: project.id)
expect(issue_a.reload.iid).to eq(1)
expect(issue_b.reload.iid).to eq(2)
@@ -1787,9 +1796,9 @@ describe Gitlab::Database::MigrationHelpers do
it 'backfills iids' do
project = setup
issue_a = issues.create!(project_id: project.id)
- issue_b = self.class::Issue.create!(project_id: project.id)
+ issue_b = Issue.create!(project_id: project.id)
issue_c = issues.create!(project_id: project.id)
- issue_d = self.class::Issue.create!(project_id: project.id)
+ issue_d = Issue.create!(project_id: project.id)
model.backfill_iids('issues')
@@ -1803,13 +1812,13 @@ describe Gitlab::Database::MigrationHelpers do
project = setup
issue_a = issues.create!(project_id: project.id)
issue_b = issues.create!(project_id: project.id)
- issue_c = self.class::Issue.create!(project_id: project.id)
+ issue_c = Issue.create!(project_id: project.id)
issue_d = issues.create!(project_id: project.id)
- issue_e = self.class::Issue.create!(project_id: project.id)
+ issue_e = Issue.create!(project_id: project.id)
model.backfill_iids('issues')
- issue_f = self.class::Issue.create!(project_id: project.id)
+ issue_f = Issue.create!(project_id: project.id)
expect(issue_a.reload.iid).to eq(1)
expect(issue_b.reload.iid).to eq(2)
@@ -1825,7 +1834,7 @@ describe Gitlab::Database::MigrationHelpers do
project = setup
issue_a = issues.create!(project_id: project.id)
issue_b = issues.create!(project_id: project.id)
- issue_c = self.class::Issue.create!(project_id: project.id)
+ issue_c = Issue.create!(project_id: project.id)
issue_c.delete
model.backfill_iids('issues')
@@ -1838,12 +1847,12 @@ describe Gitlab::Database::MigrationHelpers do
project = setup
issue_a = issues.create!(project_id: project.id)
issue_b = issues.create!(project_id: project.id)
- issue_c = self.class::Issue.create!(project_id: project.id)
+ issue_c = Issue.create!(project_id: project.id)
issue_c.delete
model.backfill_iids('issues')
- issue_d = self.class::Issue.create!(project_id: project.id)
+ issue_d = Issue.create!(project_id: project.id)
expect(issue_a.reload.iid).to eq(1)
expect(issue_b.reload.iid).to eq(2)
@@ -1856,7 +1865,7 @@ describe Gitlab::Database::MigrationHelpers do
project = setup
issue_a = issues.create!(project_id: project.id)
issue_b = issues.create!(project_id: project.id)
- issue_c = self.class::Issue.create!(project_id: project.id)
+ issue_c = Issue.create!(project_id: project.id)
issue_c.delete
issue_d = issues.create!(project_id: project.id)
@@ -1871,13 +1880,13 @@ describe Gitlab::Database::MigrationHelpers do
project = setup
issue_a = issues.create!(project_id: project.id)
issue_b = issues.create!(project_id: project.id)
- issue_c = self.class::Issue.create!(project_id: project.id)
+ issue_c = Issue.create!(project_id: project.id)
issue_c.delete
issue_d = issues.create!(project_id: project.id)
model.backfill_iids('issues')
- issue_e = self.class::Issue.create!(project_id: project.id)
+ issue_e = Issue.create!(project_id: project.id)
expect(issue_a.reload.iid).to eq(1)
expect(issue_b.reload.iid).to eq(2)
@@ -1891,9 +1900,9 @@ describe Gitlab::Database::MigrationHelpers do
project = setup
issue_a = issues.create!(project_id: project.id)
issue_b = issues.create!(project_id: project.id)
- issue_c = self.class::Issue.create!(project_id: project.id)
+ issue_c = Issue.create!(project_id: project.id)
issue_c.delete
- issue_d = self.class::Issue.create!(project_id: project.id)
+ issue_d = Issue.create!(project_id: project.id)
model.backfill_iids('issues')
@@ -1906,13 +1915,13 @@ describe Gitlab::Database::MigrationHelpers do
project = setup
issue_a = issues.create!(project_id: project.id)
issue_b = issues.create!(project_id: project.id)
- issue_c = self.class::Issue.create!(project_id: project.id)
+ issue_c = Issue.create!(project_id: project.id)
issue_c.delete
- issue_d = self.class::Issue.create!(project_id: project.id)
+ issue_d = Issue.create!(project_id: project.id)
model.backfill_iids('issues')
- issue_e = self.class::Issue.create!(project_id: project.id)
+ issue_e = Issue.create!(project_id: project.id)
expect(issue_a.reload.iid).to eq(1)
expect(issue_b.reload.iid).to eq(2)
@@ -1929,7 +1938,7 @@ describe Gitlab::Database::MigrationHelpers do
model.backfill_iids('issues')
- issue_b = self.class::Issue.create!(project_id: project_b.id)
+ issue_b = Issue.create!(project_id: project_b.id)
expect(issue_a.reload.iid).to eq(1)
expect(issue_b.reload.iid).to eq(1)
@@ -2066,6 +2075,34 @@ describe Gitlab::Database::MigrationHelpers do
allow(model).to receive(:check_constraint_exists?).and_return(false)
end
+ context 'constraint name validation' do
+ it 'raises an error when too long' do
+ expect do
+ model.add_check_constraint(
+ :test_table,
+ 'name IS NOT NULL',
+ 'a' * (Gitlab::Database::MigrationHelpers::MAX_IDENTIFIER_NAME_LENGTH + 1)
+ )
+ end.to raise_error(RuntimeError)
+ end
+
+ it 'does not raise error when the length is acceptable' do
+ constraint_name = 'a' * Gitlab::Database::MigrationHelpers::MAX_IDENTIFIER_NAME_LENGTH
+
+ expect(model).to receive(:transaction_open?).and_return(false)
+ expect(model).to receive(:check_constraint_exists?).and_return(false)
+ expect(model).to receive(:with_lock_retries).and_call_original
+ expect(model).to receive(:execute).with(/ADD CONSTRAINT/)
+
+ model.add_check_constraint(
+ :test_table,
+ 'name IS NOT NULL',
+ constraint_name,
+ validate: false
+ )
+ end
+ end
+
context 'inside a transaction' do
it 'raises an error' do
expect(model).to receive(:transaction_open?).and_return(true)
diff --git a/spec/lib/gitlab/database/obsolete_ignored_columns_spec.rb b/spec/lib/gitlab/database/obsolete_ignored_columns_spec.rb
index 0f68201a153..dee1d7df1a9 100644
--- a/spec/lib/gitlab/database/obsolete_ignored_columns_spec.rb
+++ b/spec/lib/gitlab/database/obsolete_ignored_columns_spec.rb
@@ -3,39 +3,48 @@
require 'spec_helper'
describe Gitlab::Database::ObsoleteIgnoredColumns do
- module Testing
+ before do
+ stub_const('Testing', Module.new)
+ stub_const('Testing::MyBase', Class.new(ActiveRecord::Base))
+ stub_const('SomeAbstract', Class.new(Testing::MyBase))
+ stub_const('Testing::B', Class.new(Testing::MyBase))
+ stub_const('Testing::A', Class.new(SomeAbstract))
+ stub_const('Testing::C', Class.new(Testing::MyBase))
+
# Used a fixed date to prevent tests failing across date boundaries
- REMOVE_DATE = Date.new(2019, 12, 16)
+ stub_const('REMOVE_DATE', Date.new(2019, 12, 16))
- class MyBase < ApplicationRecord
- end
+ Testing.module_eval do
+ Testing::MyBase.class_eval do
+ end
- class SomeAbstract < MyBase
- include IgnorableColumns
+ SomeAbstract.class_eval do
+ include IgnorableColumns
- self.abstract_class = true
+ self.abstract_class = true
- self.table_name = 'projects'
+ self.table_name = 'projects'
- ignore_column :unused, remove_after: '2019-01-01', remove_with: '12.0'
- end
+ ignore_column :unused, remove_after: '2019-01-01', remove_with: '12.0'
+ end
- class B < MyBase
- include IgnorableColumns
+ Testing::B.class_eval do
+ include IgnorableColumns
- self.table_name = 'issues'
+ self.table_name = 'issues'
- ignore_column :id, :other, remove_after: '2019-01-01', remove_with: '12.0'
- ignore_column :not_used_but_still_ignored, remove_after: REMOVE_DATE.to_s, remove_with: '12.1'
- end
+ ignore_column :id, :other, remove_after: '2019-01-01', remove_with: '12.0'
+ ignore_column :not_used_but_still_ignored, remove_after: REMOVE_DATE.to_s, remove_with: '12.1'
+ end
- class A < SomeAbstract
- ignore_column :also_unused, remove_after: '2019-02-01', remove_with: '12.1'
- ignore_column :not_used_but_still_ignored, remove_after: REMOVE_DATE.to_s, remove_with: '12.1'
- end
+ Testing::A.class_eval do
+ ignore_column :also_unused, remove_after: '2019-02-01', remove_with: '12.1'
+ ignore_column :not_used_but_still_ignored, remove_after: REMOVE_DATE.to_s, remove_with: '12.1'
+ end
- class C < MyBase
- self.table_name = 'users'
+ Testing::C.class_eval do
+ self.table_name = 'users'
+ end
end
end
@@ -43,7 +52,7 @@ describe Gitlab::Database::ObsoleteIgnoredColumns do
describe '#execute' do
it 'returns a list of class names and columns pairs' do
- Timecop.freeze(Testing::REMOVE_DATE) do
+ Timecop.freeze(REMOVE_DATE) do
expect(subject.execute).to eq([
['Testing::A', {
'unused' => IgnorableColumns::ColumnIgnore.new(Date.parse('2019-01-01'), '12.0'),
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
new file mode 100644
index 00000000000..9cec77b434d
--- /dev/null
+++ b/spec/lib/gitlab/database/partitioning_migration_helpers/foreign_key_helpers_spec.rb
@@ -0,0 +1,193 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Database::PartitioningMigrationHelpers::ForeignKeyHelpers do
+ include TriggerHelpers
+
+ let(:model) do
+ ActiveRecord::Migration.new.extend(described_class)
+ end
+ let_it_be(:connection) { ActiveRecord::Base.connection }
+ let(:referenced_table) { :issues }
+ let(:function_name) { '_test_partitioned_foreign_keys_function' }
+ let(:trigger_name) { '_test_partitioned_foreign_keys_trigger' }
+
+ before do
+ allow(model).to receive(:puts)
+ allow(model).to receive(:fk_function_name).and_return(function_name)
+ allow(model).to receive(:fk_trigger_name).and_return(trigger_name)
+ end
+
+ describe 'adding a foreign key' do
+ before do
+ allow(model).to receive(:transaction_open?).and_return(false)
+ end
+
+ context 'when the table has no foreign keys' do
+ it 'creates a trigger function to handle the single cascade' do
+ model.add_partitioned_foreign_key :issue_assignees, referenced_table
+
+ expect_function_to_contain(function_name, 'delete from issue_assignees where issue_id = old.id')
+ expect_valid_function_trigger(referenced_table, trigger_name, function_name, after: 'delete')
+ end
+ end
+
+ context 'when the table already has foreign keys' do
+ context 'when the foreign key is from a different table' do
+ before do
+ model.add_partitioned_foreign_key :issue_assignees, referenced_table
+ end
+
+ it 'creates a trigger function to handle the multiple cascades' do
+ model.add_partitioned_foreign_key :epic_issues, referenced_table
+
+ expect_function_to_contain(function_name,
+ 'delete from issue_assignees where issue_id = old.id',
+ 'delete from epic_issues where issue_id = old.id')
+ expect_valid_function_trigger(referenced_table, trigger_name, function_name, after: 'delete')
+ end
+ end
+
+ context 'when the foreign key is from the same table' do
+ before do
+ model.add_partitioned_foreign_key :issues, referenced_table, column: :moved_to_id
+ end
+
+ context 'when the foreign key is from a different column' do
+ it 'creates a trigger function to handle the multiple cascades' do
+ model.add_partitioned_foreign_key :issues, referenced_table, column: :duplicated_to_id
+
+ expect_function_to_contain(function_name,
+ 'delete from issues where moved_to_id = old.id',
+ 'delete from issues where duplicated_to_id = old.id')
+ expect_valid_function_trigger(referenced_table, trigger_name, function_name, after: 'delete')
+ end
+ end
+
+ context 'when the foreign key is from the same column' do
+ it 'ignores the duplicate and properly recreates the trigger function' do
+ model.add_partitioned_foreign_key :issues, referenced_table, column: :moved_to_id
+
+ expect_function_to_contain(function_name, 'delete from issues where moved_to_id = old.id')
+ expect_valid_function_trigger(referenced_table, trigger_name, function_name, after: 'delete')
+ end
+ end
+ end
+ end
+
+ context 'when the foreign key is set to nullify' do
+ it 'creates a trigger function that nullifies the foreign key' do
+ model.add_partitioned_foreign_key :issue_assignees, referenced_table, on_delete: :nullify
+
+ expect_function_to_contain(function_name, 'update issue_assignees set issue_id = null where issue_id = old.id')
+ expect_valid_function_trigger(referenced_table, trigger_name, function_name, after: 'delete')
+ end
+ end
+
+ context 'when the referencing column is a custom value' do
+ it 'creates a trigger function with the correct column name' do
+ model.add_partitioned_foreign_key :issues, referenced_table, column: :duplicated_to_id
+
+ expect_function_to_contain(function_name, 'delete from issues where duplicated_to_id = old.id')
+ expect_valid_function_trigger(referenced_table, trigger_name, function_name, after: 'delete')
+ end
+ end
+
+ context 'when the referenced column is a custom value' do
+ let(:referenced_table) { :user_details }
+
+ it 'creates a trigger function with the correct column name' do
+ model.add_partitioned_foreign_key :user_preferences, referenced_table, column: :user_id, primary_key: :user_id
+
+ expect_function_to_contain(function_name, 'delete from user_preferences where user_id = old.user_id')
+ expect_valid_function_trigger(referenced_table, trigger_name, function_name, after: 'delete')
+ end
+ end
+
+ context 'when the given key definition is invalid' do
+ it 'raises an error with the appropriate message' do
+ expect do
+ model.add_partitioned_foreign_key :issue_assignees, referenced_table, column: :not_a_real_issue_id
+ end.to raise_error(/From column must be a valid column/)
+ end
+ end
+
+ context 'when run inside a transaction' do
+ it 'raises an error' do
+ expect(model).to receive(:transaction_open?).and_return(true)
+
+ expect do
+ model.add_partitioned_foreign_key :issue_assignees, referenced_table
+ end.to raise_error(/can not be run inside a transaction/)
+ end
+ end
+ end
+
+ context 'removing a foreign key' do
+ before do
+ allow(model).to receive(:transaction_open?).and_return(false)
+ end
+
+ context 'when the table has multiple foreign keys' do
+ before do
+ model.add_partitioned_foreign_key :issue_assignees, referenced_table
+ model.add_partitioned_foreign_key :epic_issues, referenced_table
+ end
+
+ it 'creates a trigger function without the removed cascade' do
+ expect_function_to_contain(function_name,
+ 'delete from issue_assignees where issue_id = old.id',
+ 'delete from epic_issues where issue_id = old.id')
+ expect_valid_function_trigger(referenced_table, trigger_name, function_name, after: 'delete')
+
+ model.remove_partitioned_foreign_key :issue_assignees, referenced_table
+
+ expect_function_to_contain(function_name, 'delete from epic_issues where issue_id = old.id')
+ expect_valid_function_trigger(referenced_table, trigger_name, function_name, after: 'delete')
+ end
+ end
+
+ context 'when the table has only one remaining foreign key' do
+ before do
+ model.add_partitioned_foreign_key :issue_assignees, referenced_table
+ end
+
+ it 'removes the trigger function altogether' do
+ expect_function_to_contain(function_name, 'delete from issue_assignees where issue_id = old.id')
+ expect_valid_function_trigger(referenced_table, trigger_name, function_name, after: 'delete')
+
+ model.remove_partitioned_foreign_key :issue_assignees, referenced_table
+
+ expect_function_not_to_exist(function_name)
+ expect_trigger_not_to_exist(referenced_table, trigger_name)
+ end
+ end
+
+ context 'when the foreign key does not exist' do
+ before do
+ model.add_partitioned_foreign_key :issue_assignees, referenced_table
+ end
+
+ it 'ignores the invalid key and properly recreates the trigger function' do
+ expect_function_to_contain(function_name, 'delete from issue_assignees where issue_id = old.id')
+ expect_valid_function_trigger(referenced_table, trigger_name, function_name, after: 'delete')
+
+ model.remove_partitioned_foreign_key :issues, referenced_table, column: :moved_to_id
+
+ expect_function_to_contain(function_name, 'delete from issue_assignees where issue_id = old.id')
+ expect_valid_function_trigger(referenced_table, trigger_name, function_name, after: 'delete')
+ end
+ end
+
+ context 'when run outside a transaction' do
+ it 'raises an error' do
+ expect(model).to receive(:transaction_open?).and_return(true)
+
+ expect do
+ model.remove_partitioned_foreign_key :issue_assignees, referenced_table
+ 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/table_management_helpers_spec.rb b/spec/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers_spec.rb
new file mode 100644
index 00000000000..586b57d2002
--- /dev/null
+++ b/spec/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers_spec.rb
@@ -0,0 +1,289 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Database::PartitioningMigrationHelpers::TableManagementHelpers do
+ include PartitioningHelpers
+ include TriggerHelpers
+
+ let(:migration) do
+ ActiveRecord::Migration.new.extend(described_class)
+ end
+
+ let_it_be(:connection) { ActiveRecord::Base.connection }
+ let(:template_table) { :audit_events }
+ let(:partitioned_table) { '_test_migration_partitioned_table' }
+ let(:function_name) { '_test_migration_function_name' }
+ let(:trigger_name) { '_test_migration_trigger_name' }
+ let(:partition_column) { 'created_at' }
+ let(:min_date) { Date.new(2019, 12) }
+ let(:max_date) { Date.new(2020, 3) }
+
+ before do
+ allow(migration).to receive(:puts)
+ allow(migration).to receive(:transaction_open?).and_return(false)
+ allow(migration).to receive(:partitioned_table_name).and_return(partitioned_table)
+ allow(migration).to receive(:sync_function_name).and_return(function_name)
+ allow(migration).to receive(:sync_trigger_name).and_return(trigger_name)
+ allow(migration).to receive(:assert_table_is_whitelisted)
+ end
+
+ describe '#partition_table_by_date' do
+ let(:partition_column) { 'created_at' }
+ let(:old_primary_key) { 'id' }
+ let(:new_primary_key) { [old_primary_key, partition_column] }
+
+ context 'when the table is not whitelisted' do
+ let(:template_table) { :this_table_is_not_whitelisted }
+
+ it 'raises an error' do
+ expect(migration).to receive(:assert_table_is_whitelisted).with(template_table).and_call_original
+
+ expect do
+ migration.partition_table_by_date template_table, partition_column, min_date: min_date, max_date: max_date
+ end.to raise_error(/#{template_table} is not whitelisted for use/)
+ 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.partition_table_by_date template_table, partition_column, min_date: min_date, max_date: max_date
+ end.to raise_error(/can not be run inside a transaction/)
+ end
+ end
+
+ context 'when the the max_date is less than the min_date' do
+ let(:max_date) { Time.utc(2019, 6) }
+
+ it 'raises an error' do
+ expect do
+ migration.partition_table_by_date template_table, partition_column, min_date: min_date, max_date: max_date
+ end.to raise_error(/max_date #{max_date} must be greater than min_date #{min_date}/)
+ end
+ end
+
+ context 'when the max_date is equal to the min_date' do
+ let(:max_date) { min_date }
+
+ it 'raises an error' do
+ expect do
+ migration.partition_table_by_date template_table, partition_column, min_date: min_date, max_date: max_date
+ end.to raise_error(/max_date #{max_date} must be greater than min_date #{min_date}/)
+ end
+ end
+
+ context 'when the given table does not have a primary key' do
+ let(:template_table) { :_partitioning_migration_helper_test_table }
+ let(:partition_column) { :some_field }
+
+ it 'raises an error' do
+ migration.create_table template_table, id: false do |t|
+ t.integer :id
+ t.datetime partition_column
+ end
+
+ expect do
+ migration.partition_table_by_date template_table, partition_column, min_date: min_date, max_date: max_date
+ end.to raise_error(/primary key not defined for #{template_table}/)
+ end
+ end
+
+ context 'when an invalid partition column is given' do
+ let(:partition_column) { :_this_is_not_real }
+
+ it 'raises an error' do
+ expect do
+ migration.partition_table_by_date template_table, partition_column, min_date: min_date, max_date: max_date
+ end.to raise_error(/partition column #{partition_column} does not exist/)
+ end
+ end
+
+ describe 'constructing the partitioned table' do
+ it 'creates a table partitioned by the proper column' do
+ migration.partition_table_by_date template_table, partition_column, min_date: min_date, max_date: max_date
+
+ expect(connection.table_exists?(partitioned_table)).to be(true)
+ expect(connection.primary_key(partitioned_table)).to eq(new_primary_key)
+
+ expect_table_partitioned_by(partitioned_table, [partition_column])
+ end
+
+ it 'changes the primary key datatype to bigint' do
+ migration.partition_table_by_date template_table, partition_column, min_date: min_date, max_date: max_date
+
+ pk_column = connection.columns(partitioned_table).find { |c| c.name == old_primary_key }
+
+ expect(pk_column.sql_type).to eq('bigint')
+ end
+
+ context 'with a non-integer primary key datatype' do
+ before do
+ connection.create_table :another_example, id: false do |t|
+ t.string :identifier, primary_key: true
+ t.timestamp :created_at
+ end
+ end
+
+ let(:template_table) { :another_example }
+ let(:old_primary_key) { 'identifier' }
+
+ it 'does not change the primary key datatype' do
+ migration.partition_table_by_date template_table, partition_column, min_date: min_date, max_date: max_date
+
+ original_pk_column = connection.columns(template_table).find { |c| c.name == old_primary_key }
+ pk_column = connection.columns(partitioned_table).find { |c| c.name == old_primary_key }
+
+ expect(pk_column).not_to be_nil
+ expect(pk_column).to eq(original_pk_column)
+ end
+ end
+
+ it 'removes the default from the primary key column' do
+ migration.partition_table_by_date template_table, partition_column, min_date: min_date, max_date: max_date
+
+ pk_column = connection.columns(partitioned_table).find { |c| c.name == old_primary_key }
+
+ expect(pk_column.default_function).to be_nil
+ end
+
+ it 'creates the partitioned table with the same non-key columns' do
+ migration.partition_table_by_date template_table, partition_column, min_date: min_date, max_date: max_date
+
+ copied_columns = filter_columns_by_name(connection.columns(partitioned_table), new_primary_key)
+ original_columns = filter_columns_by_name(connection.columns(template_table), new_primary_key)
+
+ expect(copied_columns).to match_array(original_columns)
+ end
+
+ it 'creates a partition spanning over each month in the range given' do
+ migration.partition_table_by_date template_table, partition_column, min_date: min_date, max_date: max_date
+
+ expect_range_partition_of("#{partitioned_table}_000000", partitioned_table, 'MINVALUE', "'2019-12-01 00:00:00'")
+ expect_range_partition_of("#{partitioned_table}_201912", partitioned_table, "'2019-12-01 00:00:00'", "'2020-01-01 00:00:00'")
+ expect_range_partition_of("#{partitioned_table}_202001", partitioned_table, "'2020-01-01 00:00:00'", "'2020-02-01 00:00:00'")
+ expect_range_partition_of("#{partitioned_table}_202002", partitioned_table, "'2020-02-01 00:00:00'", "'2020-03-01 00:00:00'")
+ end
+ end
+
+ describe 'keeping data in sync with the partitioned table' do
+ let(:template_table) { :todos }
+ let(:model) { Class.new(ActiveRecord::Base) }
+ let(:timestamp) { Time.utc(2019, 12, 1, 12).round }
+
+ before do
+ model.primary_key = :id
+ model.table_name = partitioned_table
+ end
+
+ it 'creates a trigger function on the original table' do
+ expect_function_not_to_exist(function_name)
+ expect_trigger_not_to_exist(template_table, trigger_name)
+
+ migration.partition_table_by_date template_table, partition_column, min_date: min_date, max_date: max_date
+
+ expect_function_to_exist(function_name)
+ expect_valid_function_trigger(template_table, trigger_name, function_name, after: %w[delete insert update])
+ end
+
+ it 'syncs inserts to the partitioned tables' do
+ migration.partition_table_by_date template_table, partition_column, min_date: min_date, max_date: max_date
+
+ expect(model.count).to eq(0)
+
+ first_todo = create(:todo, created_at: timestamp, updated_at: timestamp)
+ second_todo = create(:todo, created_at: timestamp, updated_at: timestamp)
+
+ expect(model.count).to eq(2)
+ expect(model.find(first_todo.id).attributes).to eq(first_todo.attributes)
+ expect(model.find(second_todo.id).attributes).to eq(second_todo.attributes)
+ end
+
+ it 'syncs updates to the partitioned tables' do
+ migration.partition_table_by_date template_table, partition_column, min_date: min_date, max_date: max_date
+
+ first_todo = create(:todo, :pending, commit_id: nil, created_at: timestamp, updated_at: timestamp)
+ second_todo = create(:todo, created_at: timestamp, updated_at: timestamp)
+
+ expect(model.count).to eq(2)
+
+ first_copy = model.find(first_todo.id)
+ second_copy = model.find(second_todo.id)
+
+ expect(first_copy.attributes).to eq(first_todo.attributes)
+ expect(second_copy.attributes).to eq(second_todo.attributes)
+
+ first_todo.update(state_event: 'done', commit_id: 'abc123', updated_at: timestamp + 1.second)
+
+ expect(model.count).to eq(2)
+ expect(first_copy.reload.attributes).to eq(first_todo.attributes)
+ expect(second_copy.reload.attributes).to eq(second_todo.attributes)
+ end
+
+ it 'syncs deletes to the partitioned tables' do
+ migration.partition_table_by_date template_table, partition_column, min_date: min_date, max_date: max_date
+
+ first_todo = create(:todo, created_at: timestamp, updated_at: timestamp)
+ second_todo = create(:todo, created_at: timestamp, updated_at: timestamp)
+
+ expect(model.count).to eq(2)
+
+ first_todo.destroy
+
+ expect(model.count).to eq(1)
+ expect(model.find_by_id(first_todo.id)).to be_nil
+ expect(model.find(second_todo.id).attributes).to eq(second_todo.attributes)
+ end
+ end
+ end
+
+ describe '#drop_partitioned_table_for' do
+ let(:expected_tables) do
+ %w[000000 201912 202001 202002].map { |suffix| "#{partitioned_table}_#{suffix}" }.unshift(partitioned_table)
+ end
+
+ context 'when the table is not whitelisted' do
+ let(:template_table) { :this_table_is_not_whitelisted }
+
+ it 'raises an error' do
+ expect(migration).to receive(:assert_table_is_whitelisted).with(template_table).and_call_original
+
+ expect do
+ migration.drop_partitioned_table_for template_table
+ end.to raise_error(/#{template_table} is not whitelisted for use/)
+ end
+ end
+
+ it 'drops the trigger syncing to the partitioned table' do
+ migration.partition_table_by_date template_table, partition_column, min_date: min_date, max_date: max_date
+
+ expect_function_to_exist(function_name)
+ expect_valid_function_trigger(template_table, trigger_name, function_name, after: %w[delete insert update])
+
+ migration.drop_partitioned_table_for template_table
+
+ expect_function_not_to_exist(function_name)
+ expect_trigger_not_to_exist(template_table, trigger_name)
+ end
+
+ it 'drops the partitioned copy and all partitions' do
+ migration.partition_table_by_date template_table, partition_column, min_date: min_date, max_date: max_date
+
+ expected_tables.each do |table|
+ expect(connection.table_exists?(table)).to be(true)
+ end
+
+ migration.drop_partitioned_table_for template_table
+
+ expected_tables.each do |table|
+ expect(connection.table_exists?(table)).to be(false)
+ end
+ end
+ end
+
+ def filter_columns_by_name(columns, names)
+ columns.reject { |c| names.include?(c.name) }
+ end
+end
diff --git a/spec/lib/gitlab/database/partitioning_migration_helpers_spec.rb b/spec/lib/gitlab/database/partitioning_migration_helpers_spec.rb
deleted file mode 100644
index 0e2fb047469..00000000000
--- a/spec/lib/gitlab/database/partitioning_migration_helpers_spec.rb
+++ /dev/null
@@ -1,230 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe Gitlab::Database::PartitioningMigrationHelpers do
- let(:model) do
- ActiveRecord::Migration.new.extend(described_class)
- end
- let_it_be(:connection) { ActiveRecord::Base.connection }
- let(:referenced_table) { :issues }
- let(:function_name) { model.fk_function_name(referenced_table) }
- let(:trigger_name) { model.fk_trigger_name(referenced_table) }
-
- before do
- allow(model).to receive(:puts)
- end
-
- describe 'adding a foreign key' do
- before do
- allow(model).to receive(:transaction_open?).and_return(false)
- end
-
- context 'when the table has no foreign keys' do
- it 'creates a trigger function to handle the single cascade' do
- model.add_partitioned_foreign_key :issue_assignees, referenced_table
-
- expect_function_to_contain(function_name, 'delete from issue_assignees where issue_id = old.id')
- expect_valid_function_trigger(trigger_name, function_name)
- end
- end
-
- context 'when the table already has foreign keys' do
- context 'when the foreign key is from a different table' do
- before do
- model.add_partitioned_foreign_key :issue_assignees, referenced_table
- end
-
- it 'creates a trigger function to handle the multiple cascades' do
- model.add_partitioned_foreign_key :epic_issues, referenced_table
-
- expect_function_to_contain(function_name,
- 'delete from issue_assignees where issue_id = old.id',
- 'delete from epic_issues where issue_id = old.id')
- expect_valid_function_trigger(trigger_name, function_name)
- end
- end
-
- context 'when the foreign key is from the same table' do
- before do
- model.add_partitioned_foreign_key :issues, referenced_table, column: :moved_to_id
- end
-
- context 'when the foreign key is from a different column' do
- it 'creates a trigger function to handle the multiple cascades' do
- model.add_partitioned_foreign_key :issues, referenced_table, column: :duplicated_to_id
-
- expect_function_to_contain(function_name,
- 'delete from issues where moved_to_id = old.id',
- 'delete from issues where duplicated_to_id = old.id')
- expect_valid_function_trigger(trigger_name, function_name)
- end
- end
-
- context 'when the foreign key is from the same column' do
- it 'ignores the duplicate and properly recreates the trigger function' do
- model.add_partitioned_foreign_key :issues, referenced_table, column: :moved_to_id
-
- expect_function_to_contain(function_name, 'delete from issues where moved_to_id = old.id')
- expect_valid_function_trigger(trigger_name, function_name)
- end
- end
- end
- end
-
- context 'when the foreign key is set to nullify' do
- it 'creates a trigger function that nullifies the foreign key' do
- model.add_partitioned_foreign_key :issue_assignees, referenced_table, on_delete: :nullify
-
- expect_function_to_contain(function_name, 'update issue_assignees set issue_id = null where issue_id = old.id')
- expect_valid_function_trigger(trigger_name, function_name)
- end
- end
-
- context 'when the referencing column is a custom value' do
- it 'creates a trigger function with the correct column name' do
- model.add_partitioned_foreign_key :issues, referenced_table, column: :duplicated_to_id
-
- expect_function_to_contain(function_name, 'delete from issues where duplicated_to_id = old.id')
- expect_valid_function_trigger(trigger_name, function_name)
- end
- end
-
- context 'when the referenced column is a custom value' do
- let(:referenced_table) { :user_details }
-
- it 'creates a trigger function with the correct column name' do
- model.add_partitioned_foreign_key :user_preferences, referenced_table, column: :user_id, primary_key: :user_id
-
- expect_function_to_contain(function_name, 'delete from user_preferences where user_id = old.user_id')
- expect_valid_function_trigger(trigger_name, function_name)
- end
- end
-
- context 'when the given key definition is invalid' do
- it 'raises an error with the appropriate message' do
- expect do
- model.add_partitioned_foreign_key :issue_assignees, referenced_table, column: :not_a_real_issue_id
- end.to raise_error(/From column must be a valid column/)
- end
- end
-
- context 'when run inside a transaction' do
- it 'raises an error' do
- expect(model).to receive(:transaction_open?).and_return(true)
-
- expect do
- model.add_partitioned_foreign_key :issue_assignees, referenced_table
- end.to raise_error(/can not be run inside a transaction/)
- end
- end
- end
-
- context 'removing a foreign key' do
- before do
- allow(model).to receive(:transaction_open?).and_return(false)
- end
-
- context 'when the table has multiple foreign keys' do
- before do
- model.add_partitioned_foreign_key :issue_assignees, referenced_table
- model.add_partitioned_foreign_key :epic_issues, referenced_table
- end
-
- it 'creates a trigger function without the removed cascade' do
- expect_function_to_contain(function_name,
- 'delete from issue_assignees where issue_id = old.id',
- 'delete from epic_issues where issue_id = old.id')
- expect_valid_function_trigger(trigger_name, function_name)
-
- model.remove_partitioned_foreign_key :issue_assignees, referenced_table
-
- expect_function_to_contain(function_name, 'delete from epic_issues where issue_id = old.id')
- expect_valid_function_trigger(trigger_name, function_name)
- end
- end
-
- context 'when the table has only one remaining foreign key' do
- before do
- model.add_partitioned_foreign_key :issue_assignees, referenced_table
- end
-
- it 'removes the trigger function altogether' do
- expect_function_to_contain(function_name, 'delete from issue_assignees where issue_id = old.id')
- expect_valid_function_trigger(trigger_name, function_name)
-
- model.remove_partitioned_foreign_key :issue_assignees, referenced_table
-
- expect(find_function_def(function_name)).to be_nil
- expect(find_trigger_def(trigger_name)).to be_nil
- end
- end
-
- context 'when the foreign key does not exist' do
- before do
- model.add_partitioned_foreign_key :issue_assignees, referenced_table
- end
-
- it 'ignores the invalid key and properly recreates the trigger function' do
- expect_function_to_contain(function_name, 'delete from issue_assignees where issue_id = old.id')
- expect_valid_function_trigger(trigger_name, function_name)
-
- model.remove_partitioned_foreign_key :issues, referenced_table, column: :moved_to_id
-
- expect_function_to_contain(function_name, 'delete from issue_assignees where issue_id = old.id')
- expect_valid_function_trigger(trigger_name, function_name)
- end
- end
-
- context 'when run outside a transaction' do
- it 'raises an error' do
- expect(model).to receive(:transaction_open?).and_return(true)
-
- expect do
- model.remove_partitioned_foreign_key :issue_assignees, referenced_table
- end.to raise_error(/can not be run inside a transaction/)
- end
- end
- end
-
- def expect_function_to_contain(name, *statements)
- return_stmt, *body_stmts = parsed_function_statements(name).reverse
-
- expect(return_stmt).to eq('return old')
- expect(body_stmts).to contain_exactly(*statements)
- end
-
- def expect_valid_function_trigger(name, fn_name)
- event, activation, definition = cleaned_trigger_def(name)
-
- expect(event).to eq('delete')
- expect(activation).to eq('after')
- expect(definition).to eq("execute procedure #{fn_name}()")
- end
-
- def parsed_function_statements(name)
- cleaned_definition = find_function_def(name)['fn_body'].downcase.gsub(/\s+/, ' ')
- statements = cleaned_definition.sub(/\A\s*begin\s*(.*)\s*end\s*\Z/, "\\1")
- statements.split(';').map! { |stmt| stmt.strip.presence }.compact!
- end
-
- def find_function_def(name)
- connection.execute("select prosrc as fn_body from pg_proc where proname = '#{name}';").first
- end
-
- def cleaned_trigger_def(name)
- find_trigger_def(name).values_at('event', 'activation', 'definition').map!(&:downcase)
- end
-
- def find_trigger_def(name)
- connection.execute(<<~SQL).first
- select
- string_agg(event_manipulation, ',') as event,
- action_timing as activation,
- action_statement as definition
- from information_schema.triggers
- where trigger_name = '#{name}'
- group by 2, 3
- SQL
- end
-end
diff --git a/spec/lib/gitlab/database/schema_cleaner_spec.rb b/spec/lib/gitlab/database/schema_cleaner_spec.rb
index ee9477156fb..adaeb85d52d 100644
--- a/spec/lib/gitlab/database/schema_cleaner_spec.rb
+++ b/spec/lib/gitlab/database/schema_cleaner_spec.rb
@@ -15,10 +15,6 @@ describe Gitlab::Database::SchemaCleaner do
expect(subject).not_to include('COMMENT ON EXTENSION')
end
- it 'includes the plpgsql extension' do
- expect(subject).to include('CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;')
- end
-
it 'sets the search_path' do
expect(subject.split("\n").first).to eq('SET search_path=public;')
end
diff --git a/spec/lib/gitlab/database/with_lock_retries_spec.rb b/spec/lib/gitlab/database/with_lock_retries_spec.rb
index 9c8c9749125..d7eee594631 100644
--- a/spec/lib/gitlab/database/with_lock_retries_spec.rb
+++ b/spec/lib/gitlab/database/with_lock_retries_spec.rb
@@ -35,9 +35,6 @@ describe Gitlab::Database::WithLockRetries do
end
context 'when lock retry is enabled' do
- class ActiveRecordSecond < ActiveRecord::Base
- end
-
let(:lock_fiber) do
Fiber.new do
# Initiating a second DB connection for the lock
@@ -52,6 +49,8 @@ describe Gitlab::Database::WithLockRetries do
end
before do
+ stub_const('ActiveRecordSecond', Class.new(ActiveRecord::Base))
+
lock_fiber.resume # start the transaction and lock the table
end
diff --git a/spec/lib/gitlab/dependency_linker/go_mod_linker_spec.rb b/spec/lib/gitlab/dependency_linker/go_mod_linker_spec.rb
new file mode 100644
index 00000000000..769daa0b3a6
--- /dev/null
+++ b/spec/lib/gitlab/dependency_linker/go_mod_linker_spec.rb
@@ -0,0 +1,94 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::DependencyLinker::GoModLinker do
+ let(:file_name) { 'go.mod' }
+ let(:file_content) do
+ <<-CONTENT.strip_heredoc
+ module gitlab.com/gitlab-org/gitlab-workhorse
+
+ go 1.12
+
+ require (
+ github.com/BurntSushi/toml v0.3.1
+ github.com/FZambia/sentinel v1.0.0
+ github.com/alecthomas/chroma v0.7.3
+ github.com/dgrijalva/jwt-go v3.2.0+incompatible
+ github.com/getsentry/raven-go v0.1.2
+ github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721
+ github.com/golang/protobuf v1.3.2
+ github.com/gomodule/redigo v2.0.0+incompatible
+ github.com/gorilla/websocket v1.4.0
+ github.com/grpc-ecosystem/go-grpc-middleware v1.0.0
+ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
+ github.com/jfbus/httprs v0.0.0-20190827093123-b0af8319bb15
+ github.com/jpillora/backoff v0.0.0-20170918002102-8eab2debe79d
+ github.com/prometheus/client_golang v1.0.0
+ github.com/rafaeljusto/redigomock v0.0.0-20190202135759-257e089e14a1
+ github.com/sebest/xff v0.0.0-20160910043805-6c115e0ffa35
+ github.com/sirupsen/logrus v1.3.0
+ github.com/stretchr/testify v1.5.1
+ gitlab.com/gitlab-org/gitaly v1.74.0
+ gitlab.com/gitlab-org/labkit v0.0.0-20200520155818-96e583c57891
+ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f
+ golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa
+ golang.org/x/tools v0.0.0-20200117161641-43d50277825c
+ google.golang.org/grpc v1.24.0
+ gopkg.in/yaml.v2 v2.2.8 // indirect
+ honnef.co/go/tools v0.0.1-2019.2.3
+ )
+ CONTENT
+ end
+
+ describe '.support?' do
+ it 'supports go.mod' do
+ expect(described_class.support?('go.mod')).to be_truthy
+ end
+
+ it 'does not support other files' do
+ expect(described_class.support?('go.mod.example')).to be_falsey
+ end
+ end
+
+ describe '#link' do
+ subject { Gitlab::Highlight.highlight(file_name, file_content) }
+
+ def link(name, url)
+ %{<a href="#{url}" rel="nofollow noreferrer noopener" target="_blank">#{name}</a>}
+ end
+
+ it 'links the module name' do
+ expect(subject).to include(link('gitlab.com/gitlab-org/gitlab-workhorse', 'https://pkg.go.dev/gitlab.com/gitlab-org/gitlab-workhorse'))
+ end
+
+ it 'links dependencies' do
+ expect(subject).to include(link('github.com/BurntSushi/toml', 'https://pkg.go.dev/github.com/BurntSushi/toml@v0.3.1'))
+ expect(subject).to include(link('github.com/FZambia/sentinel', 'https://pkg.go.dev/github.com/FZambia/sentinel@v1.0.0'))
+ expect(subject).to include(link('github.com/alecthomas/chroma', 'https://pkg.go.dev/github.com/alecthomas/chroma@v0.7.3'))
+ expect(subject).to include(link('github.com/dgrijalva/jwt-go', 'https://pkg.go.dev/github.com/dgrijalva/jwt-go@v3.2.0+incompatible'))
+ expect(subject).to include(link('github.com/getsentry/raven-go', 'https://pkg.go.dev/github.com/getsentry/raven-go@v0.1.2'))
+ expect(subject).to include(link('github.com/golang/gddo', 'https://pkg.go.dev/github.com/golang/gddo@v0.0.0-20190419222130-af0f2af80721'))
+ expect(subject).to include(link('github.com/golang/protobuf', 'https://pkg.go.dev/github.com/golang/protobuf@v1.3.2'))
+ expect(subject).to include(link('github.com/gomodule/redigo', 'https://pkg.go.dev/github.com/gomodule/redigo@v2.0.0+incompatible'))
+ expect(subject).to include(link('github.com/gorilla/websocket', 'https://pkg.go.dev/github.com/gorilla/websocket@v1.4.0'))
+ expect(subject).to include(link('github.com/grpc-ecosystem/go-grpc-middleware', 'https://pkg.go.dev/github.com/grpc-ecosystem/go-grpc-middleware@v1.0.0'))
+ expect(subject).to include(link('github.com/grpc-ecosystem/go-grpc-prometheus', 'https://pkg.go.dev/github.com/grpc-ecosystem/go-grpc-prometheus@v1.2.0'))
+ expect(subject).to include(link('github.com/jfbus/httprs', 'https://pkg.go.dev/github.com/jfbus/httprs@v0.0.0-20190827093123-b0af8319bb15'))
+ expect(subject).to include(link('github.com/jpillora/backoff', 'https://pkg.go.dev/github.com/jpillora/backoff@v0.0.0-20170918002102-8eab2debe79d'))
+ expect(subject).to include(link('github.com/prometheus/client_golang', 'https://pkg.go.dev/github.com/prometheus/client_golang@v1.0.0'))
+ expect(subject).to include(link('github.com/rafaeljusto/redigomock', 'https://pkg.go.dev/github.com/rafaeljusto/redigomock@v0.0.0-20190202135759-257e089e14a1'))
+ expect(subject).to include(link('github.com/sebest/xff', 'https://pkg.go.dev/github.com/sebest/xff@v0.0.0-20160910043805-6c115e0ffa35'))
+ expect(subject).to include(link('github.com/sirupsen/logrus', 'https://pkg.go.dev/github.com/sirupsen/logrus@v1.3.0'))
+ expect(subject).to include(link('github.com/stretchr/testify', 'https://pkg.go.dev/github.com/stretchr/testify@v1.5.1'))
+ expect(subject).to include(link('gitlab.com/gitlab-org/gitaly', 'https://pkg.go.dev/gitlab.com/gitlab-org/gitaly@v1.74.0'))
+ expect(subject).to include(link('gitlab.com/gitlab-org/labkit', 'https://pkg.go.dev/gitlab.com/gitlab-org/labkit@v0.0.0-20200520155818-96e583c57891'))
+ expect(subject).to include(link('golang.org/x/lint', 'https://pkg.go.dev/golang.org/x/lint@v0.0.0-20191125180803-fdd1cda4f05f'))
+ expect(subject).to include(link('golang.org/x/net', 'https://pkg.go.dev/golang.org/x/net@v0.0.0-20200114155413-6afb5195e5aa'))
+ expect(subject).to include(link('golang.org/x/tools', 'https://pkg.go.dev/golang.org/x/tools@v0.0.0-20200117161641-43d50277825c'))
+ expect(subject).to include(link('google.golang.org/grpc', 'https://pkg.go.dev/google.golang.org/grpc@v1.24.0'))
+ expect(subject).to include(link('gopkg.in/yaml.v2', 'https://pkg.go.dev/gopkg.in/yaml.v2@v2.2.8'))
+ expect(subject).to include(link('honnef.co/go/tools', 'https://pkg.go.dev/honnef.co/go/tools@v0.0.1-2019.2.3'))
+ end
+ end
+end
diff --git a/spec/lib/gitlab/dependency_linker/go_sum_linker_spec.rb b/spec/lib/gitlab/dependency_linker/go_sum_linker_spec.rb
new file mode 100644
index 00000000000..f5cb7809ad3
--- /dev/null
+++ b/spec/lib/gitlab/dependency_linker/go_sum_linker_spec.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::DependencyLinker::GoSumLinker do
+ let(:file_name) { 'go.sum' }
+ let(:file_content) do
+ <<-CONTENT.strip_heredoc
+ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
+ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+ github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
+ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
+ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+ gitlab.com/go-utils/io v0.0.0-20190408212915-156add3f8f97 h1:9EKx8vX3kJzyj977yiWB8iIOXHyvbg8SmfOScw7OcN0=
+ gitlab.com/go-utils/io v0.0.0-20190408212915-156add3f8f97/go.mod h1:cF4ez5kIKPWU1BB1Z4qgu6dQkT3pvknXff8PSlGaNo8=
+ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
+ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+ CONTENT
+ end
+
+ describe '.support?' do
+ it 'supports go.sum' do
+ expect(described_class.support?('go.sum')).to be_truthy
+ end
+
+ it 'does not support other files' do
+ expect(described_class.support?('go.sum.example')).to be_falsey
+ end
+ end
+
+ describe '#link' do
+ subject { Gitlab::Highlight.highlight(file_name, file_content) }
+
+ def link(name, url)
+ %{<a href="#{url}" rel="nofollow noreferrer noopener" target="_blank">#{name}</a>}
+ end
+
+ it 'links modules' do
+ expect(subject).to include(link('github.com/davecgh/go-spew', 'https://pkg.go.dev/github.com/davecgh/go-spew@v1.1.0'))
+ expect(subject).to include(link('github.com/pmezard/go-difflib', 'https://pkg.go.dev/github.com/pmezard/go-difflib@v1.0.0'))
+ expect(subject).to include(link('github.com/stretchr/objx', 'https://pkg.go.dev/github.com/stretchr/objx@v0.1.0'))
+ expect(subject).to include(link('github.com/stretchr/testify', 'https://pkg.go.dev/github.com/stretchr/testify@v1.3.0'))
+ expect(subject).to include(link('gitlab.com/go-utils/io', 'https://pkg.go.dev/gitlab.com/go-utils/io@v0.0.0-20190408212915-156add3f8f97'))
+ expect(subject).to include(link('golang.org/x/xerrors', 'https://pkg.go.dev/golang.org/x/xerrors@v0.0.0-20190717185122-a985d3407aa7'))
+ end
+
+ it 'links checksums' do
+ expect(subject).to include(link('ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=', 'https://sum.golang.org/lookup/github.com/davecgh/go-spew@v1.1.0'))
+ expect(subject).to include(link('J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=', 'https://sum.golang.org/lookup/github.com/davecgh/go-spew@v1.1.0'))
+ expect(subject).to include(link('4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=', 'https://sum.golang.org/lookup/github.com/pmezard/go-difflib@v1.0.0'))
+ expect(subject).to include(link('iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=', 'https://sum.golang.org/lookup/github.com/pmezard/go-difflib@v1.0.0'))
+ expect(subject).to include(link('4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=', 'https://sum.golang.org/lookup/github.com/stretchr/objx@v0.1.0'))
+ expect(subject).to include(link('HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=', 'https://sum.golang.org/lookup/github.com/stretchr/objx@v0.1.0'))
+ expect(subject).to include(link('TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=', 'https://sum.golang.org/lookup/github.com/stretchr/testify@v1.3.0'))
+ expect(subject).to include(link('M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=', 'https://sum.golang.org/lookup/github.com/stretchr/testify@v1.3.0'))
+ expect(subject).to include(link('9EKx8vX3kJzyj977yiWB8iIOXHyvbg8SmfOScw7OcN0=', 'https://sum.golang.org/lookup/gitlab.com/go-utils/io@v0.0.0-20190408212915-156add3f8f97'))
+ expect(subject).to include(link('cF4ez5kIKPWU1BB1Z4qgu6dQkT3pvknXff8PSlGaNo8=', 'https://sum.golang.org/lookup/gitlab.com/go-utils/io@v0.0.0-20190408212915-156add3f8f97'))
+ expect(subject).to include(link('9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=', 'https://sum.golang.org/lookup/golang.org/x/xerrors@v0.0.0-20190717185122-a985d3407aa7'))
+ expect(subject).to include(link('I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=', 'https://sum.golang.org/lookup/golang.org/x/xerrors@v0.0.0-20190717185122-a985d3407aa7'))
+ end
+ end
+end
diff --git a/spec/lib/gitlab/dependency_linker_spec.rb b/spec/lib/gitlab/dependency_linker_spec.rb
index 570a994f520..acd4376615c 100644
--- a/spec/lib/gitlab/dependency_linker_spec.rb
+++ b/spec/lib/gitlab/dependency_linker_spec.rb
@@ -91,5 +91,21 @@ describe Gitlab::DependencyLinker do
described_class.link(blob_name, nil, nil)
end
+
+ it 'links using GoModLinker' do
+ blob_name = 'go.mod'
+
+ expect(described_class::GoModLinker).to receive(:link)
+
+ described_class.link(blob_name, nil, nil)
+ end
+
+ it 'links using GoSumLinker' do
+ blob_name = 'go.sum'
+
+ expect(described_class::GoSumLinker).to receive(:link)
+
+ described_class.link(blob_name, nil, nil)
+ end
end
end
diff --git a/spec/lib/gitlab/diff/file_spec.rb b/spec/lib/gitlab/diff/file_spec.rb
index d1592e60d3d..8dbedcf26b9 100644
--- a/spec/lib/gitlab/diff/file_spec.rb
+++ b/spec/lib/gitlab/diff/file_spec.rb
@@ -282,6 +282,18 @@ describe Gitlab::Diff::File do
end
end
+ describe '#file_hash' do
+ it 'returns a hash of file_path' do
+ expect(diff_file.file_hash).to eq(Digest::SHA1.hexdigest(diff_file.file_path))
+ end
+ end
+
+ describe '#file_identifier_hash' do
+ it 'returns a hash of file_identifier' do
+ expect(diff_file.file_identifier_hash).to eq(Digest::SHA1.hexdigest(diff_file.file_identifier))
+ end
+ end
+
context 'diff file stats' do
let(:diff_file) do
described_class.new(diff,
diff --git a/spec/lib/gitlab/diff/formatters/image_formatter_spec.rb b/spec/lib/gitlab/diff/formatters/image_formatter_spec.rb
index edf30ffc56f..3f88f39ba92 100644
--- a/spec/lib/gitlab/diff/formatters/image_formatter_spec.rb
+++ b/spec/lib/gitlab/diff/formatters/image_formatter_spec.rb
@@ -10,6 +10,7 @@ describe Gitlab::Diff::Formatters::ImageFormatter do
head_sha: 789,
old_path: 'old_image.png',
new_path: 'new_image.png',
+ file_identifier_hash: '777',
position_type: 'image'
}
end
diff --git a/spec/lib/gitlab/diff/formatters/text_formatter_spec.rb b/spec/lib/gitlab/diff/formatters/text_formatter_spec.rb
index fa129a20e58..50dd597c5a7 100644
--- a/spec/lib/gitlab/diff/formatters/text_formatter_spec.rb
+++ b/spec/lib/gitlab/diff/formatters/text_formatter_spec.rb
@@ -10,6 +10,7 @@ describe Gitlab::Diff::Formatters::TextFormatter do
head_sha: 789,
old_path: 'old_path.txt',
new_path: 'new_path.txt',
+ file_identifier_hash: '777',
line_range: nil
}
end
diff --git a/spec/lib/gitlab/diff/position_spec.rb b/spec/lib/gitlab/diff/position_spec.rb
index 10749ec024d..b32a2c59bb9 100644
--- a/spec/lib/gitlab/diff/position_spec.rb
+++ b/spec/lib/gitlab/diff/position_spec.rb
@@ -574,6 +574,86 @@ describe Gitlab::Diff::Position do
end
end
+ describe '#find_diff_file_from' do
+ context "position for a diff file that has changed from symlink to regular file" do
+ let(:commit) { project.commit("81e6355ce4e1544a3524b230952c12455de0777b") }
+
+ let(:old_symlink_file_identifier_hash) { "bfa430463f33619872d52a6b85ced59c973e42dc" }
+ let(:new_regular_file_identifier_hash) { "e25b60c2e5ffb977d2b1431b96c6f7800c3c3529" }
+ let(:file_identifier_hash) { new_regular_file_identifier_hash }
+
+ let(:args) do
+ {
+ file_identifier_hash: file_identifier_hash,
+ old_path: "symlink",
+ new_path: "symlink",
+ old_line: nil,
+ new_line: 1,
+ diff_refs: commit.diff_refs
+ }
+ end
+
+ let(:diffable) { commit.diff_refs.compare_in(project) }
+
+ subject(:diff_file) { described_class.new(args).find_diff_file_from(diffable) }
+
+ context 'when file_identifier_hash is disabled' do
+ before do
+ stub_feature_flags(file_identifier_hash: false)
+ end
+
+ it "returns the first diff file" do
+ expect(diff_file.file_identifier_hash).to eq(old_symlink_file_identifier_hash)
+ end
+ end
+
+ context 'when file_identifier_hash is enabled' do
+ before do
+ stub_feature_flags(file_identifier_hash: true)
+ end
+
+ context 'for new regular file' do
+ it "returns the correct diff file" do
+ expect(diff_file.file_identifier_hash).to eq(new_regular_file_identifier_hash)
+ end
+ end
+
+ context 'for old symlink file' do
+ let(:args) do
+ {
+ file_identifier_hash: old_symlink_file_identifier_hash,
+ old_path: "symlink",
+ new_path: "symlink",
+ old_line: 1,
+ new_line: nil,
+ diff_refs: commit.diff_refs
+ }
+ end
+
+ it "returns the correct diff file" do
+ expect(diff_file.file_identifier_hash).to eq(old_symlink_file_identifier_hash)
+ end
+ end
+
+ context 'when file_identifier_hash is missing' do
+ let(:file_identifier_hash) { nil }
+
+ it "returns the first diff file" do
+ expect(diff_file.file_identifier_hash).to eq(old_symlink_file_identifier_hash)
+ end
+ end
+
+ context 'when file_identifier_hash cannot be found' do
+ let(:file_identifier_hash) { "missingidentifier" }
+
+ it "returns nil" do
+ expect(diff_file).to be_nil
+ end
+ end
+ end
+ end
+ end
+
describe '#==' do
let(:commit) { project.commit("570e7b2abdd848b95f2f578043fc23bd6f6fd24d") }
diff --git a/spec/lib/gitlab/doctor/secrets_spec.rb b/spec/lib/gitlab/doctor/secrets_spec.rb
new file mode 100644
index 00000000000..f118519fd9f
--- /dev/null
+++ b/spec/lib/gitlab/doctor/secrets_spec.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Doctor::Secrets do
+ let!(:user) { create(:user, otp_secret: "test") }
+ let!(:group) { create(:group, runners_token: "test") }
+ let(:logger) { double(:logger).as_null_object }
+
+ subject { described_class.new(logger).run! }
+
+ context 'when encrypted attributes are properly set' do
+ it 'detects decryptable secrets' do
+ expect(logger).to receive(:info).with(/User failures: 0/)
+ expect(logger).to receive(:info).with(/Group failures: 0/)
+
+ subject
+ end
+ end
+
+ context 'when attr_encrypted values are not decrypting' do
+ it 'marks undecryptable values as bad' do
+ user.encrypted_otp_secret = "invalid"
+ user.save!
+
+ expect(logger).to receive(:info).with(/User failures: 1/)
+
+ subject
+ end
+ end
+
+ context 'when TokenAuthenticatable values are not decrypting' do
+ it 'marks undecryptable values as bad' do
+ group.runners_token_encrypted = "invalid"
+ group.save!
+
+ expect(logger).to receive(:info).with(/Group failures: 1/)
+
+ subject
+ end
+ end
+end
diff --git a/spec/lib/gitlab/email/handler/create_note_handler_spec.rb b/spec/lib/gitlab/email/handler/create_note_handler_spec.rb
index 909a7618df4..af963e1b695 100644
--- a/spec/lib/gitlab/email/handler/create_note_handler_spec.rb
+++ b/spec/lib/gitlab/email/handler/create_note_handler_spec.rb
@@ -65,16 +65,24 @@ describe Gitlab::Email::Handler::CreateNoteHandler do
end
end
- context 'and current user can update noteable' do
- before do
- project.add_developer(user)
- end
-
- it 'does not raise an error' do
- # One system note is created for the 'close' event
- expect { receiver.execute }.to change { noteable.notes.count }.by(1)
-
- expect(noteable.reload).to be_closed
+ [true, false].each do |state_tracking_enabled|
+ context "and current user can update noteable #{state_tracking_enabled ? 'enabled' : 'disabled'}" do
+ before do
+ stub_feature_flags(track_resource_state_change_events: state_tracking_enabled)
+
+ project.add_developer(user)
+ end
+
+ it 'does not raise an error' do
+ if state_tracking_enabled
+ expect { receiver.execute }.to change { noteable.resource_state_events.count }.by(1)
+ else
+ # One system note is created for the 'close' event
+ expect { receiver.execute }.to change { noteable.notes.count }.by(1)
+ end
+
+ expect(noteable.reload).to be_closed
+ end
end
end
end
diff --git a/spec/lib/gitlab/error_tracking/processor/sidekiq_processor_spec.rb b/spec/lib/gitlab/error_tracking/processor/sidekiq_processor_spec.rb
new file mode 100644
index 00000000000..da7205c7f4f
--- /dev/null
+++ b/spec/lib/gitlab/error_tracking/processor/sidekiq_processor_spec.rb
@@ -0,0 +1,165 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'rspec-parameterized'
+
+RSpec.describe Gitlab::ErrorTracking::Processor::SidekiqProcessor do
+ after do
+ if described_class.instance_variable_defined?(:@permitted_arguments_for_worker)
+ described_class.remove_instance_variable(:@permitted_arguments_for_worker)
+ end
+ end
+
+ describe '.filter_arguments' do
+ it 'returns a lazy enumerator' do
+ filtered = described_class.filter_arguments([1, 'string'], 'TestWorker')
+
+ expect(filtered).to be_a(Enumerator::Lazy)
+ expect(filtered.to_a).to eq([1, described_class::FILTERED_STRING])
+ end
+
+ context 'arguments filtering' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:klass, :expected) do
+ 'UnknownWorker' | [1, described_class::FILTERED_STRING, described_class::FILTERED_STRING, described_class::FILTERED_STRING]
+ 'NoPermittedArguments' | [1, described_class::FILTERED_STRING, described_class::FILTERED_STRING, described_class::FILTERED_STRING]
+ 'OnePermittedArgument' | [1, 'string', described_class::FILTERED_STRING, described_class::FILTERED_STRING]
+ 'AllPermittedArguments' | [1, 'string', [1, 2], { a: 1 }]
+ end
+
+ with_them do
+ before do
+ stub_const('NoPermittedArguments', double(loggable_arguments: []))
+ stub_const('OnePermittedArgument', double(loggable_arguments: [1]))
+ stub_const('AllPermittedArguments', double(loggable_arguments: [0, 1, 2, 3]))
+ end
+
+ it do
+ expect(described_class.filter_arguments([1, 'string', [1, 2], { a: 1 }], klass).to_a)
+ .to eq(expected)
+ end
+ end
+ end
+ end
+
+ describe '.permitted_arguments_for_worker' do
+ it 'returns the loggable_arguments for a worker class as a set' do
+ stub_const('TestWorker', double(loggable_arguments: [1, 1]))
+
+ expect(described_class.permitted_arguments_for_worker('TestWorker'))
+ .to eq([1].to_set)
+ end
+
+ it 'returns an empty set when the worker class does not exist' do
+ expect(described_class.permitted_arguments_for_worker('TestWorker'))
+ .to eq(Set.new)
+ end
+
+ it 'returns an empty set when the worker class does not respond to loggable_arguments' do
+ stub_const('TestWorker', 1)
+
+ expect(described_class.permitted_arguments_for_worker('TestWorker'))
+ .to eq(Set.new)
+ end
+
+ it 'returns an empty set when loggable_arguments cannot be converted to a set' do
+ stub_const('TestWorker', double(loggable_arguments: 1))
+
+ expect(described_class.permitted_arguments_for_worker('TestWorker'))
+ .to eq(Set.new)
+ end
+
+ it 'memoizes the results' do
+ worker_class = double
+
+ stub_const('TestWorker', worker_class)
+
+ expect(worker_class).to receive(:loggable_arguments).once.and_return([])
+
+ described_class.permitted_arguments_for_worker('TestWorker')
+ described_class.permitted_arguments_for_worker('TestWorker')
+ end
+ end
+
+ describe '.loggable_arguments' do
+ it 'filters and limits the arguments, then converts to strings' do
+ half_limit = Gitlab::Utils::LogLimitedArray::MAXIMUM_ARRAY_LENGTH / 2
+ args = [[1, 2], 'a' * half_limit, 'b' * half_limit, 'c' * half_limit, 'd']
+
+ stub_const('LoggableArguments', double(loggable_arguments: [0, 1, 3, 4]))
+
+ expect(described_class.loggable_arguments(args, 'LoggableArguments'))
+ .to eq(['[1, 2]', 'a' * half_limit, '[FILTERED]', '...'])
+ end
+ end
+
+ describe '#process' do
+ context 'when there is Sidekiq data' do
+ shared_examples 'Sidekiq arguments' do |args_in_job_hash: true|
+ let(:path) { [:extra, :sidekiq, args_in_job_hash ? :job : nil, 'args'].compact }
+ let(:args) { [1, 'string', { a: 1 }, [1, 2]] }
+
+ it 'only allows numeric arguments for an unknown worker' do
+ value = { 'args' => args, 'class' => 'UnknownWorker' }
+
+ value = { job: value } if args_in_job_hash
+
+ expect(subject.process(extra_sidekiq(value)).dig(*path))
+ .to eq([1, described_class::FILTERED_STRING, described_class::FILTERED_STRING, described_class::FILTERED_STRING])
+ end
+
+ it 'allows all argument types for a permitted worker' do
+ value = { 'args' => args, 'class' => 'PostReceive' }
+
+ value = { job: value } if args_in_job_hash
+
+ expect(subject.process(extra_sidekiq(value)).dig(*path))
+ .to eq(args)
+ end
+ end
+
+ context 'when processing via the default error handler' do
+ include_examples 'Sidekiq arguments', args_in_job_hash: true
+ end
+
+ context 'when processing via Gitlab::ErrorTracking' do
+ include_examples 'Sidekiq arguments', args_in_job_hash: false
+ end
+
+ it 'removes a jobstr field if present' do
+ value = {
+ job: { 'args' => [1] },
+ jobstr: { 'args' => [1] }.to_json
+ }
+
+ expect(subject.process(extra_sidekiq(value)))
+ .to eq(extra_sidekiq(value.except(:jobstr)))
+ end
+
+ it 'does nothing with no jobstr' do
+ value = { job: { 'args' => [1] } }
+
+ expect(subject.process(extra_sidekiq(value)))
+ .to eq(extra_sidekiq(value))
+ end
+ end
+
+ context 'when there is no Sidekiq data' do
+ it 'does nothing' do
+ value = {
+ request: {
+ method: 'POST',
+ data: { 'key' => 'value' }
+ }
+ }
+
+ expect(subject.process(value)).to eq(value)
+ end
+ end
+
+ def extra_sidekiq(hash)
+ { extra: { sidekiq: hash } }
+ end
+ end
+end
diff --git a/spec/lib/gitlab/error_tracking_spec.rb b/spec/lib/gitlab/error_tracking_spec.rb
index 6764d48d14b..c40369f5965 100644
--- a/spec/lib/gitlab/error_tracking_spec.rb
+++ b/spec/lib/gitlab/error_tracking_spec.rb
@@ -2,6 +2,8 @@
require 'spec_helper'
+require 'raven/transports/dummy'
+
describe Gitlab::ErrorTracking do
let(:exception) { RuntimeError.new('boom') }
let(:issue_url) { 'http://gitlab.com/gitlab-org/gitlab-foss/issues/1' }
@@ -22,7 +24,9 @@ describe Gitlab::ErrorTracking do
allow(described_class).to receive(:sentry_dsn).and_return(Gitlab.config.sentry.dsn)
allow(Labkit::Correlation::CorrelationId).to receive(:current_id).and_return('cid')
- described_class.configure
+ described_class.configure do |config|
+ config.encoding = 'json'
+ end
end
describe '.with_context' do
@@ -179,5 +183,29 @@ describe Gitlab::ErrorTracking do
described_class.track_exception(exception, extra_info)
end
end
+
+ context 'with sidekiq args' do
+ it 'ensures extra.sidekiq.args is a string' do
+ extra = { sidekiq: { 'class' => 'PostReceive', 'args' => [1, { 'id' => 2, 'name' => 'hello' }, 'some-value', 'another-value'] } }
+
+ expect(Gitlab::ErrorTracking::Logger).to receive(:error).with(
+ hash_including({ 'extra.sidekiq' => { 'class' => 'PostReceive', 'args' => ['1', '{"id"=>2, "name"=>"hello"}', 'some-value', 'another-value'] } }))
+
+ described_class.track_exception(exception, extra)
+ end
+
+ it 'filters sensitive arguments before sending' do
+ extra = { sidekiq: { 'class' => 'UnknownWorker', 'args' => ['sensitive string', 1, 2] } }
+
+ expect(Gitlab::ErrorTracking::Logger).to receive(:error).with(
+ hash_including('extra.sidekiq' => { 'class' => 'UnknownWorker', 'args' => ['[FILTERED]', '1', '2'] }))
+
+ described_class.track_exception(exception, extra)
+
+ sentry_event = Gitlab::Json.parse(Raven.client.transport.events.last[1])
+
+ expect(sentry_event.dig('extra', 'sidekiq', 'args')).to eq(['[FILTERED]', 1, 2])
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/etag_caching/router_spec.rb b/spec/lib/gitlab/etag_caching/router_spec.rb
index b69e4668d61..d9eeb5b9a2b 100644
--- a/spec/lib/gitlab/etag_caching/router_spec.rb
+++ b/spec/lib/gitlab/etag_caching/router_spec.rb
@@ -23,7 +23,7 @@ describe Gitlab::EtagCaching::Router do
it 'matches issue title endpoint' do
result = described_class.match(
- '/my-group/my-project/issues/123/realtime_changes'
+ '/my-group/my-project/-/issues/123/realtime_changes'
)
expect(result).to be_present
@@ -32,7 +32,7 @@ describe Gitlab::EtagCaching::Router do
it 'matches with a project name that includes a suffix of create' do
result = described_class.match(
- '/group/test-create/issues/123/realtime_changes'
+ '/group/test-create/-/issues/123/realtime_changes'
)
expect(result).to be_present
@@ -41,7 +41,7 @@ describe Gitlab::EtagCaching::Router do
it 'matches with a project name that includes a prefix of create' do
result = described_class.match(
- '/group/create-test/issues/123/realtime_changes'
+ '/group/create-test/-/issues/123/realtime_changes'
)
expect(result).to be_present
@@ -50,7 +50,7 @@ describe Gitlab::EtagCaching::Router do
it 'matches project pipelines endpoint' do
result = described_class.match(
- '/my-group/my-project/pipelines.json'
+ '/my-group/my-project/-/pipelines.json'
)
expect(result).to be_present
@@ -95,7 +95,7 @@ describe Gitlab::EtagCaching::Router do
it 'does not match blob with confusing name' do
result = described_class.match(
- '/my-group/my-project/blob/master/pipelines.json'
+ '/my-group/my-project/-/blob/master/pipelines.json'
)
expect(result).to be_blank
@@ -121,7 +121,7 @@ describe Gitlab::EtagCaching::Router do
it 'matches pipeline#show endpoint' do
result = described_class.match(
- '/my-group/my-project/pipelines/2.json'
+ '/my-group/my-project/-/pipelines/2.json'
)
expect(result).to be_present
diff --git a/spec/lib/gitlab/experimentation_spec.rb b/spec/lib/gitlab/experimentation_spec.rb
index 99442cb0ca6..f6e6c031624 100644
--- a/spec/lib/gitlab/experimentation_spec.rb
+++ b/spec/lib/gitlab/experimentation_spec.rb
@@ -11,7 +11,7 @@ describe Gitlab::Experimentation do
}
})
- allow(Feature).to receive(:get).with(:test_experiment_experiment_percentage).and_return double(percentage_of_time_value: enabled_percentage)
+ Feature.enable_percentage_of_time(:test_experiment_experiment_percentage, enabled_percentage)
end
let(:environment) { Rails.env.test? }
diff --git a/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb b/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb
index 0bf46217d60..7279399d1b8 100644
--- a/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb
+++ b/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb
@@ -54,6 +54,14 @@ describe Gitlab::Gfm::UploadsRewriter do
expect(new_paths).not_to include image_uploader.secret
expect(new_paths).not_to include zip_uploader.secret
end
+
+ it 'skips nil files do' do
+ allow_next_instance_of(UploaderFinder) do |finder|
+ allow(finder).to receive(:execute).and_return(nil)
+ end
+
+ expect(new_files).to be_empty
+ end
end
end
@@ -68,16 +76,6 @@ describe Gitlab::Gfm::UploadsRewriter do
expect(moved_text.scan(/\A\[.*?\]/).count).to eq(1)
end
- context 'path traversal in file name' do
- let(:text) do
- "![a](/uploads/11111111111111111111111111111111/../../../../../../../../../../../../../../etc/passwd)"
- end
-
- it 'throw an error' do
- expect { rewriter.rewrite(new_project) }.to raise_error(an_instance_of(StandardError).and(having_attributes(message: "Invalid path")))
- end
- end
-
context "file are stored locally" do
include_examples "files are accessible"
end
diff --git a/spec/lib/gitlab/git/diff_collection_spec.rb b/spec/lib/gitlab/git/diff_collection_spec.rb
index 0d19d35bc52..6aa4f884d20 100644
--- a/spec/lib/gitlab/git/diff_collection_spec.rb
+++ b/spec/lib/gitlab/git/diff_collection_spec.rb
@@ -3,6 +3,31 @@
require 'spec_helper'
describe Gitlab::Git::DiffCollection, :seed_helper do
+ before do
+ stub_const('MutatingConstantIterator', Class.new)
+
+ MutatingConstantIterator.class_eval do
+ include Enumerable
+
+ def initialize(count, value)
+ @count = count
+ @value = value
+ end
+
+ def each
+ return enum_for(:each) unless block_given?
+
+ loop do
+ break if @count.zero?
+
+ # It is critical to decrement before yielding. We may never reach the lines after 'yield'.
+ @count -= 1
+ yield @value
+ end
+ end
+ end
+ end
+
subject do
Gitlab::Git::DiffCollection.new(
iterator,
@@ -659,25 +684,4 @@ describe Gitlab::Git::DiffCollection, :seed_helper do
def fake_diff(line_length, line_count)
{ 'diff' => "#{'a' * line_length}\n" * line_count }
end
-
- class MutatingConstantIterator
- include Enumerable
-
- def initialize(count, value)
- @count = count
- @value = value
- end
-
- def each
- return enum_for(:each) unless block_given?
-
- loop do
- break if @count.zero?
-
- # It is critical to decrement before yielding. We may never reach the lines after 'yield'.
- @count -= 1
- yield @value
- end
- end
- end
end
diff --git a/spec/lib/gitlab/git/diff_spec.rb b/spec/lib/gitlab/git/diff_spec.rb
index ac606da5cc1..ff54d7fbcd3 100644
--- a/spec/lib/gitlab/git/diff_spec.rb
+++ b/spec/lib/gitlab/git/diff_spec.rb
@@ -122,6 +122,36 @@ EOT
end
end
end
+
+ context 'using a Gitaly::CommitDelta' do
+ let(:commit_delta) do
+ Gitaly::CommitDelta.new(
+ to_path: ".gitmodules",
+ from_path: ".gitmodules",
+ old_mode: 0100644,
+ new_mode: 0100644,
+ from_id: '357406f3075a57708d0163752905cc1576fceacc',
+ to_id: '8e5177d718c561d36efde08bad36b43687ee6bf0'
+ )
+ end
+ let(:diff) { described_class.new(commit_delta) }
+
+ it 'initializes the diff' do
+ expect(diff.to_hash).to eq(@raw_diff_hash.merge(diff: ''))
+ end
+
+ it 'is not too large' do
+ expect(diff).not_to be_too_large
+ end
+
+ it 'has an empty diff' do
+ expect(diff.diff).to be_empty
+ end
+
+ it 'is not a binary' do
+ expect(diff).not_to have_binary_notice
+ end
+ end
end
describe 'straight diffs' do
diff --git a/spec/lib/gitlab/git/rugged_impl/use_rugged_spec.rb b/spec/lib/gitlab/git/rugged_impl/use_rugged_spec.rb
index b396e5d22c3..8339006fe9f 100644
--- a/spec/lib/gitlab/git/rugged_impl/use_rugged_spec.rb
+++ b/spec/lib/gitlab/git/rugged_impl/use_rugged_spec.rb
@@ -8,7 +8,6 @@ describe Gitlab::Git::RuggedImpl::UseRugged, :seed_helper do
let(:project) { create(:project, :repository) }
let(:repository) { project.repository }
let(:feature_flag_name) { 'feature-flag-name' }
- let(:feature_flag) { Feature.get(feature_flag_name) }
let(:temp_gitaly_metadata_file) { create_temporary_gitaly_metadata_file }
before(:all) do
@@ -49,10 +48,6 @@ describe Gitlab::Git::RuggedImpl::UseRugged, :seed_helper do
end
context 'when feature flag is not persisted' do
- before do
- allow(Feature).to receive(:persisted?).with(feature_flag).and_return(false)
- end
-
context 'when running puma with multiple threads' do
before do
allow(subject).to receive(:running_puma_with_multiple_threads?).and_return(true)
@@ -97,18 +92,15 @@ describe Gitlab::Git::RuggedImpl::UseRugged, :seed_helper do
end
context 'when feature flag is persisted' do
- before do
- allow(Feature).to receive(:persisted?).with(feature_flag).and_return(true)
- end
-
it 'returns false when the feature flag is off' do
- allow(feature_flag).to receive(:enabled?).and_return(false)
+ Feature.disable(feature_flag_name)
expect(subject.use_rugged?(repository, feature_flag_name)).to be_falsey
end
it "returns true when feature flag is on" do
- allow(feature_flag).to receive(:enabled?).and_return(true)
+ Feature.enable(feature_flag_name)
+
allow(Gitlab::GitalyClient).to receive(:can_use_disk?).and_return(false)
expect(subject.use_rugged?(repository, feature_flag_name)).to be true
diff --git a/spec/lib/gitlab/git_access_project_spec.rb b/spec/lib/gitlab/git_access_project_spec.rb
new file mode 100644
index 00000000000..f7f7976ccb8
--- /dev/null
+++ b/spec/lib/gitlab/git_access_project_spec.rb
@@ -0,0 +1,166 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::GitAccessProject do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :repository) }
+ let(:actor) { user }
+ let(:project_path) { project.path }
+ let(:namespace_path) { project&.namespace&.path }
+ let(:protocol) { 'ssh' }
+ let(:authentication_abilities) { %i[read_project download_code push_code] }
+ let(:changes) { Gitlab::GitAccess::ANY }
+ let(:push_access_check) { access.check('git-receive-pack', changes) }
+ let(:pull_access_check) { access.check('git-upload-pack', changes) }
+
+ describe '#check_project_accessibility!' do
+ context 'when the project is nil' do
+ let(:project) { nil }
+ let(:project_path) { "new-project" }
+
+ context 'when user is allowed to create project in namespace' do
+ let(:namespace_path) { user.namespace.path }
+ let(:access) do
+ described_class.new(actor, nil,
+ protocol, authentication_abilities: authentication_abilities,
+ repository_path: project_path, namespace_path: namespace_path)
+ end
+
+ it 'blocks pull access with "not found"' do
+ expect { pull_access_check }.to raise_not_found
+ end
+
+ it 'allows push access' do
+ expect { push_access_check }.not_to raise_error
+ end
+ end
+
+ context 'when user is not allowed to create project in namespace' do
+ let(:user2) { create(:user) }
+ let(:namespace_path) { user2.namespace.path }
+ let(:access) do
+ described_class.new(actor, nil,
+ protocol, authentication_abilities: authentication_abilities,
+ repository_path: project_path, namespace_path: namespace_path)
+ end
+
+ it 'blocks push and pull with "not found"' do
+ aggregate_failures do
+ expect { pull_access_check }.to raise_not_found
+ expect { push_access_check }.to raise_not_found
+ end
+ end
+ end
+ end
+ end
+
+ describe '#ensure_project_on_push!' do
+ let(:access) do
+ described_class.new(actor, project,
+ protocol, authentication_abilities: authentication_abilities,
+ repository_path: project_path, namespace_path: namespace_path)
+ end
+
+ before do
+ allow(access).to receive(:changes).and_return(changes)
+ end
+
+ context 'when push' do
+ let(:cmd) { 'git-receive-pack' }
+
+ context 'when project does not exist' do
+ let(:project_path) { "nonexistent" }
+ let(:project) { nil }
+
+ context 'when changes is _any' do
+ let(:changes) { Gitlab::GitAccess::ANY }
+
+ context 'when authentication abilities include push code' do
+ let(:authentication_abilities) { [:push_code] }
+
+ context 'when user can create project in namespace' do
+ let(:namespace_path) { user.namespace.path }
+
+ it 'creates a new project' do
+ expect { access.send(:ensure_project_on_push!, cmd) }
+ .to change { Project.count }.by(1)
+ .and change { Project.where(namespace: user.namespace, name: project_path).count }.by(1)
+ end
+ end
+
+ context 'when user cannot create project in namespace' do
+ let(:user2) { create(:user) }
+ let(:namespace_path) { user2.namespace.path }
+
+ it 'does not create a new project' do
+ expect { access.send(:ensure_project_on_push!, cmd) }.not_to change { Project.count }
+ end
+ end
+ end
+
+ context 'when authentication abilities do not include push code' do
+ let(:authentication_abilities) { [] }
+
+ context 'when user can create project in namespace' do
+ let(:namespace_path) { user.namespace.path }
+
+ it 'does not create a new project' do
+ expect { access.send(:ensure_project_on_push!, cmd) }.not_to change { Project.count }
+ end
+ end
+ end
+ end
+
+ context 'when check contains actual changes' do
+ let(:changes) { "#{Gitlab::Git::BLANK_SHA} 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/new_branch" }
+
+ it 'does not create a new project' do
+ expect { access.send(:ensure_project_on_push!, cmd) }.not_to change { Project.count }
+ end
+ end
+ end
+
+ context 'when project exists' do
+ let(:changes) { Gitlab::GitAccess::ANY }
+ let!(:project) { create(:project) }
+
+ it 'does not create a new project' do
+ expect { access.send(:ensure_project_on_push!, cmd) }.not_to change { Project.count }
+ end
+ end
+
+ context 'when deploy key is used' do
+ let(:key) { create(:deploy_key, user: user) }
+ let(:actor) { key }
+ let(:project_path) { "nonexistent" }
+ let(:project) { nil }
+ let(:namespace_path) { user.namespace.path }
+ let(:changes) { Gitlab::GitAccess::ANY }
+
+ it 'does not create a new project' do
+ expect { access.send(:ensure_project_on_push!, cmd) }.not_to change { Project.count }
+ end
+ end
+ end
+
+ context 'when pull' do
+ let(:cmd) { 'git-upload-pack' }
+ let(:changes) { Gitlab::GitAccess::ANY }
+
+ context 'when project does not exist' do
+ let(:project_path) { "new-project" }
+ let(:namespace_path) { user.namespace.path }
+ let(:project) { nil }
+
+ it 'does not create a new project' do
+ expect { access.send(:ensure_project_on_push!, cmd) }.not_to change { Project.count }
+ end
+ end
+ end
+ end
+
+ def raise_not_found
+ raise_error(Gitlab::GitAccess::NotFoundError, Gitlab::GitAccess::ERROR_MESSAGES[:project_not_found])
+ end
+end
diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb
index a29c56c598f..7c09fc5cc79 100644
--- a/spec/lib/gitlab/git_access_spec.rb
+++ b/spec/lib/gitlab/git_access_spec.rb
@@ -10,7 +10,7 @@ describe Gitlab::GitAccess do
let(:actor) { user }
let(:project) { create(:project, :repository) }
- let(:project_path) { project.path }
+ let(:project_path) { project&.path }
let(:namespace_path) { project&.namespace&.path }
let(:protocol) { 'ssh' }
let(:authentication_abilities) { %i[read_project download_code push_code] }
@@ -89,13 +89,14 @@ describe Gitlab::GitAccess do
end
end
- context 'when namespace does not exist' do
+ context 'when namespace and project are nil' do
+ let(:project) { nil }
let(:namespace_path) { nil }
it 'does not allow push and pull access' do
aggregate_failures do
- expect { push_access_check }.to raise_not_found
- expect { pull_access_check }.to raise_not_found
+ expect { push_access_check }.to raise_namespace_not_found
+ expect { pull_access_check }.to raise_namespace_not_found
end
end
end
@@ -227,6 +228,7 @@ describe Gitlab::GitAccess do
context 'when the project is nil' do
let(:project) { nil }
let(:project_path) { "new-project" }
+ let(:namespace_path) { user.namespace.path }
it 'blocks push and pull with "not found"' do
aggregate_failures do
@@ -234,42 +236,6 @@ describe Gitlab::GitAccess do
expect { push_access_check }.to raise_not_found
end
end
-
- context 'when user is allowed to create project in namespace' do
- let(:namespace_path) { user.namespace.path }
- let(:access) do
- described_class.new(actor, nil,
- protocol, authentication_abilities: authentication_abilities,
- repository_path: project_path, namespace_path: namespace_path,
- redirected_path: redirected_path)
- end
-
- it 'blocks pull access with "not found"' do
- expect { pull_access_check }.to raise_not_found
- end
-
- it 'allows push access' do
- expect { push_access_check }.not_to raise_error
- end
- end
-
- context 'when user is not allowed to create project in namespace' do
- let(:user2) { create(:user) }
- let(:namespace_path) { user2.namespace.path }
- let(:access) do
- described_class.new(actor, nil,
- protocol, authentication_abilities: authentication_abilities,
- repository_path: project_path, namespace_path: namespace_path,
- redirected_path: redirected_path)
- end
-
- it 'blocks push and pull with "not found"' do
- aggregate_failures do
- expect { pull_access_check }.to raise_not_found
- expect { push_access_check }.to raise_not_found
- end
- end
- end
end
end
@@ -449,106 +415,6 @@ describe Gitlab::GitAccess do
end
end
- describe '#ensure_project_on_push!' do
- let(:access) do
- described_class.new(actor, project,
- protocol, authentication_abilities: authentication_abilities,
- repository_path: project_path, namespace_path: namespace_path,
- redirected_path: redirected_path)
- end
-
- context 'when push' do
- let(:cmd) { 'git-receive-pack' }
-
- context 'when project does not exist' do
- let(:project_path) { "nonexistent" }
- let(:project) { nil }
-
- context 'when changes is _any' do
- let(:changes) { Gitlab::GitAccess::ANY }
-
- context 'when authentication abilities include push code' do
- let(:authentication_abilities) { [:push_code] }
-
- context 'when user can create project in namespace' do
- let(:namespace_path) { user.namespace.path }
-
- it 'creates a new project' do
- expect { access.send(:ensure_project_on_push!, cmd, changes) }.to change { Project.count }.by(1)
- end
- end
-
- context 'when user cannot create project in namespace' do
- let(:user2) { create(:user) }
- let(:namespace_path) { user2.namespace.path }
-
- it 'does not create a new project' do
- expect { access.send(:ensure_project_on_push!, cmd, changes) }.not_to change { Project.count }
- end
- end
- end
-
- context 'when authentication abilities do not include push code' do
- let(:authentication_abilities) { [] }
-
- context 'when user can create project in namespace' do
- let(:namespace_path) { user.namespace.path }
-
- it 'does not create a new project' do
- expect { access.send(:ensure_project_on_push!, cmd, changes) }.not_to change { Project.count }
- end
- end
- end
- end
-
- context 'when check contains actual changes' do
- let(:changes) { "#{Gitlab::Git::BLANK_SHA} 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/new_branch" }
-
- it 'does not create a new project' do
- expect { access.send(:ensure_project_on_push!, cmd, changes) }.not_to change { Project.count }
- end
- end
- end
-
- context 'when project exists' do
- let(:changes) { Gitlab::GitAccess::ANY }
- let!(:project) { create(:project) }
-
- it 'does not create a new project' do
- expect { access.send(:ensure_project_on_push!, cmd, changes) }.not_to change { Project.count }
- end
- end
-
- context 'when deploy key is used' do
- let(:key) { create(:deploy_key, user: user) }
- let(:actor) { key }
- let(:project_path) { "nonexistent" }
- let(:project) { nil }
- let(:namespace_path) { user.namespace.path }
- let(:changes) { Gitlab::GitAccess::ANY }
-
- it 'does not create a new project' do
- expect { access.send(:ensure_project_on_push!, cmd, changes) }.not_to change { Project.count }
- end
- end
- end
-
- context 'when pull' do
- let(:cmd) { 'git-upload-pack' }
- let(:changes) { Gitlab::GitAccess::ANY }
-
- context 'when project does not exist' do
- let(:project_path) { "new-project" }
- let(:namespace_path) { user.namespace.path }
- let(:project) { nil }
-
- it 'does not create a new project' do
- expect { access.send(:ensure_project_on_push!, cmd, changes) }.not_to change { Project.count }
- end
- end
- end
- end
-
describe '#check_download_access!' do
it 'allows maintainers to pull' do
project.add_maintainer(user)
@@ -1219,6 +1085,10 @@ describe Gitlab::GitAccess do
raise_error(Gitlab::GitAccess::NotFoundError, Gitlab::GitAccess::ERROR_MESSAGES[:project_not_found])
end
+ def raise_namespace_not_found
+ raise_error(Gitlab::GitAccess::NotFoundError, Gitlab::GitAccess::ERROR_MESSAGES[:namespace_not_found])
+ end
+
def build_authentication_abilities
[
:read_project,
diff --git a/spec/lib/gitlab/gitaly_client/commit_service_spec.rb b/spec/lib/gitlab/gitaly_client/commit_service_spec.rb
index 00182983418..29a5ef0d2fc 100644
--- a/spec/lib/gitlab/gitaly_client/commit_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/commit_service_spec.rb
@@ -124,15 +124,20 @@ describe Gitlab::GitalyClient::CommitService do
let(:left_commit_id) { 'master' }
let(:right_commit_id) { 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660' }
- it 'sends an RPC request' do
+ it 'sends an RPC request and returns the stats' do
request = Gitaly::DiffStatsRequest.new(repository: repository_message,
left_commit_id: left_commit_id,
right_commit_id: right_commit_id)
+ diff_stat_response = Gitaly::DiffStatsResponse.new(
+ stats: [{ additions: 1, deletions: 2, path: 'test' }])
+
expect_any_instance_of(Gitaly::DiffService::Stub).to receive(:diff_stats)
- .with(request, kind_of(Hash)).and_return([])
+ .with(request, kind_of(Hash)).and_return([diff_stat_response])
+
+ returned_value = described_class.new(repository).diff_stats(left_commit_id, right_commit_id)
- described_class.new(repository).diff_stats(left_commit_id, right_commit_id)
+ expect(returned_value).to eq(diff_stat_response.stats)
end
end
@@ -321,4 +326,59 @@ describe Gitlab::GitalyClient::CommitService do
client.find_commits(order: 'default', author: "Billy Baggins <bilbo@shire.com>")
end
end
+
+ describe '#commits_by_message' do
+ shared_examples 'a CommitsByMessageRequest' do
+ let(:commits) { create_list(:gitaly_commit, 2) }
+
+ before do
+ request = Gitaly::CommitsByMessageRequest.new(
+ repository: repository_message,
+ query: query,
+ revision: (options[:revision] || '').dup.force_encoding(Encoding::ASCII_8BIT),
+ path: (options[:path] || '').dup.force_encoding(Encoding::ASCII_8BIT),
+ limit: (options[:limit] || 1000).to_i,
+ offset: (options[:offset] || 0).to_i
+ )
+
+ allow_any_instance_of(Gitaly::CommitService::Stub)
+ .to receive(:commits_by_message)
+ .with(request, kind_of(Hash))
+ .and_return([Gitaly::CommitsByMessageResponse.new(commits: commits)])
+ end
+
+ it 'sends an RPC request with the correct payload' do
+ expect(client.commits_by_message(query, options)).to match_array(wrap_commits(commits))
+ end
+ end
+
+ let(:query) { 'Add a feature' }
+ let(:options) { {} }
+
+ context 'when only the query is provided' do
+ include_examples 'a CommitsByMessageRequest'
+ end
+
+ context 'when all arguments are provided' do
+ let(:options) { { revision: 'feature-branch', path: 'foo.txt', limit: 10, offset: 20 } }
+
+ include_examples 'a CommitsByMessageRequest'
+ end
+
+ context 'when limit and offset are not integers' do
+ let(:options) { { limit: '10', offset: '60' } }
+
+ include_examples 'a CommitsByMessageRequest'
+ end
+
+ context 'when revision and path contain non-ASCII characters' do
+ let(:options) { { revision: "branch\u011F", path: "foo/\u011F.txt" } }
+
+ include_examples 'a CommitsByMessageRequest'
+ end
+
+ def wrap_commits(commits)
+ commits.map { |commit| Gitlab::Git::Commit.new(repository, commit) }
+ end
+ end
end
diff --git a/spec/lib/gitlab/gitaly_client_spec.rb b/spec/lib/gitlab/gitaly_client_spec.rb
index 2c6aee58326..c2b989c2fdc 100644
--- a/spec/lib/gitlab/gitaly_client_spec.rb
+++ b/spec/lib/gitlab/gitaly_client_spec.rb
@@ -21,10 +21,10 @@ describe Gitlab::GitalyClient do
describe '.query_time', :request_store do
it 'increments query times' do
- subject.query_time += 0.451
- subject.query_time += 0.322
+ subject.add_query_time(0.4510004)
+ subject.add_query_time(0.3220004)
- expect(subject.query_time).to eq(0.773)
+ expect(subject.query_time).to eq(0.773001)
end
end
diff --git a/spec/lib/gitlab/github_import/importer/pull_requests_importer_spec.rb b/spec/lib/gitlab/github_import/importer/pull_requests_importer_spec.rb
index e2d810d5ddc..526a5589743 100644
--- a/spec/lib/gitlab/github_import/importer/pull_requests_importer_spec.rb
+++ b/spec/lib/gitlab/github_import/importer/pull_requests_importer_spec.rb
@@ -154,9 +154,11 @@ describe Gitlab::GithubImport::Importer::PullRequestsImporter do
.to receive(:fetch_remote)
.with('github', forced: false)
- expect(Rails.logger)
- .to receive(:info)
- .with(an_instance_of(String))
+ expect_next_instance_of(Gitlab::Import::Logger) do |logger|
+ expect(logger)
+ .to receive(:info)
+ .with(an_instance_of(Hash))
+ end
expect(importer.repository_updates_counter)
.to receive(:increment)
diff --git a/spec/lib/gitlab/gl_repository/identifier_spec.rb b/spec/lib/gitlab/gl_repository/identifier_spec.rb
new file mode 100644
index 00000000000..c36f296702e
--- /dev/null
+++ b/spec/lib/gitlab/gl_repository/identifier_spec.rb
@@ -0,0 +1,82 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::GlRepository::Identifier do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:personal_snippet) { create(:personal_snippet, author: project.owner) }
+ let_it_be(:project_snippet) { create(:project_snippet, project: project, author: project.owner) }
+
+ describe 'project repository' do
+ it_behaves_like 'parsing gl_repository identifier' do
+ let(:record_id) { project.id }
+ let(:identifier) { "project-#{record_id}" }
+ let(:expected_container) { project }
+ let(:expected_type) { Gitlab::GlRepository::PROJECT }
+ end
+ end
+
+ describe 'wiki' do
+ it_behaves_like 'parsing gl_repository identifier' do
+ let(:record_id) { project.id }
+ let(:identifier) { "wiki-#{record_id}" }
+ let(:expected_container) { project }
+ let(:expected_type) { Gitlab::GlRepository::WIKI }
+ end
+ end
+
+ describe 'snippet' do
+ context 'when PersonalSnippet' do
+ it_behaves_like 'parsing gl_repository identifier' do
+ let(:record_id) { personal_snippet.id }
+ let(:identifier) { "snippet-#{record_id}" }
+ let(:expected_container) { personal_snippet }
+ let(:expected_type) { Gitlab::GlRepository::SNIPPET }
+ end
+ end
+
+ context 'when ProjectSnippet' do
+ it_behaves_like 'parsing gl_repository identifier' do
+ let(:record_id) { project_snippet.id }
+ let(:identifier) { "snippet-#{record_id}" }
+ let(:expected_container) { project_snippet }
+ let(:expected_type) { Gitlab::GlRepository::SNIPPET }
+ end
+ end
+ end
+
+ describe 'design' do
+ it_behaves_like 'parsing gl_repository identifier' do
+ let(:record_id) { project.id }
+ let(:identifier) { "design-#{project.id}" }
+ let(:expected_container) { project }
+ let(:expected_type) { Gitlab::GlRepository::DESIGN }
+ end
+ end
+
+ describe 'incorrect format' do
+ def expect_error_raised_for(identifier)
+ expect { described_class.new(identifier) }.to raise_error(ArgumentError)
+ end
+
+ it 'raises error for incorrect id' do
+ expect_error_raised_for('wiki-noid')
+ end
+
+ it 'raises error for incorrect type' do
+ expect_error_raised_for('foo-2')
+ end
+
+ it 'raises error for incorrect three-segment container' do
+ expect_error_raised_for('snippet-2-wiki')
+ end
+
+ it 'raises error for one segment' do
+ expect_error_raised_for('snippet')
+ end
+
+ it 'raises error for more than three segments' do
+ expect_error_raised_for('project-1-wiki-bar')
+ end
+ end
+end
diff --git a/spec/lib/gitlab/gl_repository/repo_type_spec.rb b/spec/lib/gitlab/gl_repository/repo_type_spec.rb
index bf6df55b71e..f5270104d2f 100644
--- a/spec/lib/gitlab/gl_repository/repo_type_spec.rb
+++ b/spec/lib/gitlab/gl_repository/repo_type_spec.rb
@@ -13,7 +13,7 @@ describe Gitlab::GlRepository::RepoType do
describe Gitlab::GlRepository::PROJECT do
it_behaves_like 'a repo type' do
- let(:expected_id) { project.id.to_s }
+ let(:expected_id) { project.id }
let(:expected_identifier) { "project-#{expected_id}" }
let(:expected_suffix) { '' }
let(:expected_container) { project }
@@ -42,7 +42,7 @@ describe Gitlab::GlRepository::RepoType do
describe Gitlab::GlRepository::WIKI do
it_behaves_like 'a repo type' do
- let(:expected_id) { project.id.to_s }
+ let(:expected_id) { project.id }
let(:expected_identifier) { "wiki-#{expected_id}" }
let(:expected_suffix) { '.wiki' }
let(:expected_container) { project }
@@ -72,7 +72,7 @@ describe Gitlab::GlRepository::RepoType do
describe Gitlab::GlRepository::SNIPPET do
context 'when PersonalSnippet' do
it_behaves_like 'a repo type' do
- let(:expected_id) { personal_snippet.id.to_s }
+ let(:expected_id) { personal_snippet.id }
let(:expected_identifier) { "snippet-#{expected_id}" }
let(:expected_suffix) { '' }
let(:expected_repository) { personal_snippet.repository }
@@ -101,7 +101,7 @@ describe Gitlab::GlRepository::RepoType do
context 'when ProjectSnippet' do
it_behaves_like 'a repo type' do
- let(:expected_id) { project_snippet.id.to_s }
+ let(:expected_id) { project_snippet.id }
let(:expected_identifier) { "snippet-#{expected_id}" }
let(:expected_suffix) { '' }
let(:expected_repository) { project_snippet.repository }
@@ -131,7 +131,7 @@ describe Gitlab::GlRepository::RepoType do
describe Gitlab::GlRepository::DESIGN do
it_behaves_like 'a repo type' do
let(:expected_identifier) { "design-#{project.id}" }
- let(:expected_id) { project.id.to_s }
+ let(:expected_id) { project.id }
let(:expected_suffix) { '.design' }
let(:expected_repository) { project.design_repository }
let(:expected_container) { project }
diff --git a/spec/lib/gitlab/gl_repository_spec.rb b/spec/lib/gitlab/gl_repository_spec.rb
index 5f5244b7116..413540b4db8 100644
--- a/spec/lib/gitlab/gl_repository_spec.rb
+++ b/spec/lib/gitlab/gl_repository_spec.rb
@@ -11,7 +11,7 @@ describe ::Gitlab::GlRepository do
expect(described_class.parse("project-#{project.id}")).to eq([project, project, Gitlab::GlRepository::PROJECT])
end
- it 'parses a wiki gl_repository' do
+ it 'parses a project wiki gl_repository' do
expect(described_class.parse("wiki-#{project.id}")).to eq([project, project, Gitlab::GlRepository::WIKI])
end
diff --git a/spec/lib/gitlab/gon_helper_spec.rb b/spec/lib/gitlab/gon_helper_spec.rb
index 1ff2334bacf..7b0e0d01257 100644
--- a/spec/lib/gitlab/gon_helper_spec.rb
+++ b/spec/lib/gitlab/gon_helper_spec.rb
@@ -12,21 +12,19 @@ describe Gitlab::GonHelper do
describe '#push_frontend_feature_flag' do
it 'pushes a feature flag to the frontend' do
gon = instance_double('gon')
+ thing = stub_feature_flag_gate('thing')
+
+ stub_feature_flags(my_feature_flag: thing)
allow(helper)
.to receive(:gon)
.and_return(gon)
- expect(Feature)
- .to receive(:enabled?)
- .with(:my_feature_flag, 10)
- .and_return(true)
-
expect(gon)
.to receive(:push)
.with({ features: { 'myFeatureFlag' => true } }, true)
- helper.push_frontend_feature_flag(:my_feature_flag, 10)
+ helper.push_frontend_feature_flag(:my_feature_flag, thing)
end
end
diff --git a/spec/lib/gitlab/graphql/pagination/filterable_array_connection_spec.rb b/spec/lib/gitlab/graphql/pagination/filterable_array_connection_spec.rb
deleted file mode 100644
index c82e3ad3019..00000000000
--- a/spec/lib/gitlab/graphql/pagination/filterable_array_connection_spec.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe Gitlab::Graphql::Pagination::FilterableArrayConnection do
- let(:callback) { proc { |nodes| nodes } }
- let(:all_nodes) { Gitlab::Graphql::FilterableArray.new(callback, 1, 2, 3, 4, 5) }
- let(:arguments) { {} }
-
- subject(:connection) do
- described_class.new(all_nodes, { max_page_size: 3 }.merge(arguments))
- end
-
- describe '#nodes' do
- let(:paged_nodes) { subject.nodes }
-
- it_behaves_like 'connection with paged nodes' do
- let(:paged_nodes_size) { 3 }
- end
-
- context 'when callback filters some nodes' do
- let(:callback) { proc { |nodes| nodes[1..-1] } }
-
- it 'does not return filtered elements' do
- expect(subject.nodes).to contain_exactly(all_nodes[1], all_nodes[2])
- end
- end
- end
-end
diff --git a/spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb b/spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb
index ba77bc95bb5..ed728444b17 100644
--- a/spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb
+++ b/spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb
@@ -9,14 +9,6 @@ describe Gitlab::Graphql::Pagination::Keyset::Connection do
let(:schema) { GraphQL::Schema.define(query: query_type, mutation: nil)}
let(:context) { GraphQL::Query::Context.new(query: OpenStruct.new(schema: schema), values: nil, object: nil) }
- before do
- stub_const('NoPrimaryKey', Class.new(ActiveRecord::Base))
- NoPrimaryKey.class_eval do
- self.table_name = 'no_primary_key'
- self.primary_key = nil
- end
- end
-
subject(:connection) do
described_class.new(nodes, { context: context, max_page_size: 3 }.merge(arguments))
end
@@ -41,7 +33,7 @@ describe Gitlab::Graphql::Pagination::Keyset::Connection do
let(:nodes) { Project.order(:updated_at) }
it 'returns the encoded value of the order' do
- expect(decoded_cursor(cursor)).to include('updated_at' => project.updated_at.to_s)
+ expect(decoded_cursor(cursor)).to include('updated_at' => project.updated_at.strftime('%Y-%m-%d %H:%M:%S.%N %Z'))
end
it 'includes the :id even when not specified in the order' do
@@ -53,7 +45,7 @@ describe Gitlab::Graphql::Pagination::Keyset::Connection do
let(:nodes) { Project.order(:updated_at).order(:created_at) }
it 'returns the encoded value of the order' do
- expect(decoded_cursor(cursor)).to include('updated_at' => project.updated_at.to_s)
+ expect(decoded_cursor(cursor)).to include('updated_at' => project.updated_at.strftime('%Y-%m-%d %H:%M:%S.%N %Z'))
end
end
@@ -61,7 +53,7 @@ describe Gitlab::Graphql::Pagination::Keyset::Connection do
let(:nodes) { Project.order(Arel.sql('projects.updated_at IS NULL')).order(:updated_at).order(:id) }
it 'returns the encoded value of the order' do
- expect(decoded_cursor(cursor)).to include('updated_at' => project.updated_at.to_s)
+ expect(decoded_cursor(cursor)).to include('updated_at' => project.updated_at.strftime('%Y-%m-%d %H:%M:%S.%N %Z'))
end
end
end
@@ -303,6 +295,14 @@ describe Gitlab::Graphql::Pagination::Keyset::Connection do
end
context 'when there is no primary key' do
+ before do
+ stub_const('NoPrimaryKey', Class.new(ActiveRecord::Base))
+ NoPrimaryKey.class_eval do
+ self.table_name = 'no_primary_key'
+ self.primary_key = nil
+ end
+ end
+
let(:nodes) { NoPrimaryKey.all }
it 'raises an error' do
@@ -311,4 +311,96 @@ describe Gitlab::Graphql::Pagination::Keyset::Connection do
end
end
end
+
+ describe '#has_previous_page and #has_next_page' do
+ # using a list of 5 items with a max_page of 3
+ let_it_be(:project_list) { create_list(:project, 5) }
+ let_it_be(:nodes) { Project.order(:id) }
+
+ context 'when default query' do
+ let(:arguments) { {} }
+
+ it 'has no previous, but a next' do
+ expect(subject.has_previous_page).to be_falsey
+ expect(subject.has_next_page).to be_truthy
+ end
+ end
+
+ context 'when before is first item' do
+ let(:arguments) { { before: encoded_cursor(project_list.first) } }
+
+ it 'has no previous, but a next' do
+ expect(subject.has_previous_page).to be_falsey
+ expect(subject.has_next_page).to be_truthy
+ end
+ end
+
+ describe 'using `before`' do
+ context 'when before is the last item' do
+ let(:arguments) { { before: encoded_cursor(project_list.last) } }
+
+ it 'has no previous, but a next' do
+ expect(subject.has_previous_page).to be_falsey
+ expect(subject.has_next_page).to be_truthy
+ end
+ end
+
+ context 'when before and last specified' do
+ let(:arguments) { { before: encoded_cursor(project_list.last), last: 2 } }
+
+ it 'has a previous and a next' do
+ expect(subject.has_previous_page).to be_truthy
+ expect(subject.has_next_page).to be_truthy
+ end
+ end
+
+ context 'when before and last does not request all remaining nodes' do
+ let(:arguments) { { before: encoded_cursor(project_list.last), last: 2 } }
+
+ it 'has a previous and a next' do
+ expect(subject.has_previous_page).to be_truthy
+ expect(subject.has_next_page).to be_truthy
+ end
+ end
+
+ context 'when before and last does request all remaining nodes' do
+ let(:arguments) { { before: encoded_cursor(project_list[1]), last: 3 } }
+
+ it 'has a previous and a next' do
+ expect(subject.has_previous_page).to be_falsey
+ expect(subject.has_next_page).to be_truthy
+ expect(subject.nodes).to eq [project_list[0]]
+ end
+ end
+ end
+
+ describe 'using `after`' do
+ context 'when after is the first item' do
+ let(:arguments) { { after: encoded_cursor(project_list.first) } }
+
+ it 'has a previous, and a next' do
+ expect(subject.has_previous_page).to be_truthy
+ expect(subject.has_next_page).to be_truthy
+ end
+ end
+
+ context 'when after and first specified' do
+ let(:arguments) { { after: encoded_cursor(project_list.first), first: 2 } }
+
+ it 'has a previous and a next' do
+ expect(subject.has_previous_page).to be_truthy
+ expect(subject.has_next_page).to be_truthy
+ end
+ end
+
+ context 'when before and last does request all remaining nodes' do
+ let(:arguments) { { after: encoded_cursor(project_list[2]), last: 3 } }
+
+ it 'has a previous but no next' do
+ expect(subject.has_previous_page).to be_truthy
+ expect(subject.has_next_page).to be_falsey
+ end
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/import/merge_request_creator_spec.rb b/spec/lib/gitlab/import/merge_request_creator_spec.rb
index ff2c3032dbf..48a57f9b251 100644
--- a/spec/lib/gitlab/import/merge_request_creator_spec.rb
+++ b/spec/lib/gitlab/import/merge_request_creator_spec.rb
@@ -15,7 +15,7 @@ describe Gitlab::Import::MergeRequestCreator do
it 'updates the data' do
commits_count = commits.count
- merge_request.merge_request_diffs.destroy_all # rubocop: disable DestroyAll
+ merge_request.merge_request_diffs.destroy_all # rubocop: disable Cop/DestroyAll
expect(merge_request.merge_request_diffs.count).to eq(0)
diff --git a/spec/lib/gitlab/import/set_async_jid_spec.rb b/spec/lib/gitlab/import/set_async_jid_spec.rb
index f1ae23a4a6a..d2933cfd371 100644
--- a/spec/lib/gitlab/import/set_async_jid_spec.rb
+++ b/spec/lib/gitlab/import/set_async_jid_spec.rb
@@ -8,7 +8,7 @@ describe Gitlab::Import::SetAsyncJid do
it 'sets the JID in Redis' do
expect(Gitlab::SidekiqStatus)
.to receive(:set)
- .with("async-import/project-import-state/#{project.id}", StuckImportJobsWorker::IMPORT_JOBS_EXPIRATION)
+ .with("async-import/project-import-state/#{project.id}", Gitlab::Import::StuckImportJob::IMPORT_JOBS_EXPIRATION)
.and_call_original
described_class.set_jid(project.import_state)
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index c78b4501310..ef9321dc1fc 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -179,10 +179,12 @@ merge_request_context_commits:
ci_pipelines:
- project
- user
+- ci_ref
- stages
- statuses
- latest_statuses_ordered_by_stage
- builds
+- bridges
- processables
- trigger_requests
- variables
@@ -195,7 +197,7 @@ ci_pipelines:
- cancelable_statuses
- manual_actions
- scheduled_actions
-- artifacts
+- downloadable_artifacts
- pipeline_schedule
- merge_requests_as_head_pipeline
- merge_request
@@ -220,6 +222,11 @@ ci_pipelines:
- pipeline_config
- security_scans
- daily_build_group_report_results
+- latest_builds
+- daily_report_results
+ci_refs:
+- project
+- ci_pipelines
pipeline_variables:
- pipeline
stages:
@@ -236,6 +243,7 @@ statuses:
- stage
- user
- auto_canceled_by
+- needs
variables:
- project
triggers:
@@ -417,6 +425,7 @@ project:
- deploy_tokens
- settings
- ci_cd_settings
+- project_settings
- import_export_upload
- repository_languages
- pool_repository
@@ -479,6 +488,7 @@ project:
- upstream_project_subscriptions
- downstream_project_subscriptions
- service_desk_setting
+- security_setting
- import_failures
- container_expiration_policy
- resource_groups
@@ -494,6 +504,7 @@ project:
- repository_storage_moves
- freeze_periods
- webex_teams_service
+- build_report_results
award_emoji:
- awardable
- user
@@ -579,6 +590,7 @@ boards:
- board_assignee
- assignee
- labels
+- user_preferences
lists:
- user
- milestone
@@ -596,6 +608,7 @@ design: &design
- versions
- notes
- user_mentions
+- events
designs: *design
actions:
- design
diff --git a/spec/lib/gitlab/import_export/attributes_permitter_spec.rb b/spec/lib/gitlab/import_export/attributes_permitter_spec.rb
new file mode 100644
index 00000000000..d6217811b9c
--- /dev/null
+++ b/spec/lib/gitlab/import_export/attributes_permitter_spec.rb
@@ -0,0 +1,77 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::ImportExport::AttributesPermitter do
+ let(:yml_config) do
+ <<-EOF
+ tree:
+ project:
+ - labels:
+ - :priorities
+ - milestones:
+ - events:
+ - :push_event_payload
+
+ included_attributes:
+ labels:
+ - :title
+ - :description
+
+ methods:
+ labels:
+ - :type
+ EOF
+ end
+
+ let(:file) { Tempfile.new(%w(import_export .yml)) }
+ let(:config_hash) { Gitlab::ImportExport::Config.new(config: file.path).to_h }
+
+ before do
+ file.write(yml_config)
+ file.rewind
+ end
+
+ after do
+ file.close
+ file.unlink
+ end
+
+ subject { described_class.new(config: config_hash) }
+
+ describe '#permitted_attributes' do
+ it 'builds permitted attributes hash' do
+ expect(subject.permitted_attributes).to match(
+ a_hash_including(
+ project: [:labels, :milestones],
+ labels: [:priorities, :title, :description, :type],
+ events: [:push_event_payload],
+ milestones: [:events],
+ priorities: [],
+ push_event_payload: []
+ )
+ )
+ end
+ end
+
+ describe '#permit' do
+ let(:unfiltered_hash) do
+ {
+ title: 'Title',
+ description: 'Description',
+ undesired_attribute: 'Undesired Attribute',
+ another_attribute: 'Another Attribute'
+ }
+ end
+
+ it 'only allows permitted attributes' do
+ expect(subject.permit(:labels, unfiltered_hash)).to eq(title: 'Title', description: 'Description')
+ end
+ end
+
+ describe '#permitted_attributes_for' do
+ it 'returns an array of permitted attributes for a relation' do
+ expect(subject.permitted_attributes_for(:labels)).to contain_exactly(:title, :description, :type, :priorities)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/import_export/import_test_coverage_spec.rb b/spec/lib/gitlab/import_export/import_test_coverage_spec.rb
index 038b95809b4..c5a7327332e 100644
--- a/spec/lib/gitlab/import_export/import_test_coverage_spec.rb
+++ b/spec/lib/gitlab/import_export/import_test_coverage_spec.rb
@@ -10,61 +10,66 @@ require 'spec_helper'
describe 'Test coverage of the Project Import' do
include ConfigurationHelper
- # `MUTED_RELATIONS` is a technical debt.
+ # `muted_relations` is a technical debt.
# This list expected to be empty or used as a workround
# in case this spec blocks an important urgent MR.
# It is also expected that adding a relation in the list should lead to
# opening a follow-up issue to fix this.
- MUTED_RELATIONS = %w[
- project.milestones.events.push_event_payload
- project.issues.events
- project.issues.events.push_event_payload
- project.issues.notes.events
- project.issues.notes.events.push_event_payload
- project.issues.milestone.events.push_event_payload
- project.issues.issue_milestones
- project.issues.issue_milestones.milestone
- project.issues.resource_label_events.label.priorities
- project.issues.designs.notes
- project.issues.designs.notes.author
- project.issues.designs.notes.events
- project.issues.designs.notes.events.push_event_payload
- project.merge_requests.metrics
- project.merge_requests.notes.events.push_event_payload
- project.merge_requests.events.push_event_payload
- project.merge_requests.timelogs
- project.merge_requests.label_links
- project.merge_requests.label_links.label
- project.merge_requests.label_links.label.priorities
- project.merge_requests.milestone
- project.merge_requests.milestone.events
- project.merge_requests.milestone.events.push_event_payload
- project.merge_requests.merge_request_milestones
- project.merge_requests.merge_request_milestones.milestone
- project.merge_requests.resource_label_events.label
- project.merge_requests.resource_label_events.label.priorities
- project.ci_pipelines.notes.events
- project.ci_pipelines.notes.events.push_event_payload
- project.protected_branches.unprotect_access_levels
- project.prometheus_metrics
- project.metrics_setting
- project.boards.lists.label.priorities
- project.service_desk_setting
- ].freeze
+ let(:muted_relations) do
+ %w[
+ project.milestones.events.push_event_payload
+ project.issues.events
+ project.issues.events.push_event_payload
+ project.issues.notes.events
+ project.issues.notes.events.push_event_payload
+ project.issues.milestone.events.push_event_payload
+ project.issues.issue_milestones
+ project.issues.issue_milestones.milestone
+ project.issues.resource_label_events.label.priorities
+ project.issues.designs.notes
+ project.issues.designs.notes.author
+ project.issues.designs.notes.events
+ project.issues.designs.notes.events.push_event_payload
+ project.merge_requests.metrics
+ project.merge_requests.notes.events.push_event_payload
+ project.merge_requests.events.push_event_payload
+ project.merge_requests.timelogs
+ project.merge_requests.label_links
+ project.merge_requests.label_links.label
+ project.merge_requests.label_links.label.priorities
+ project.merge_requests.milestone
+ project.merge_requests.milestone.events
+ project.merge_requests.milestone.events.push_event_payload
+ project.merge_requests.merge_request_milestones
+ project.merge_requests.merge_request_milestones.milestone
+ project.merge_requests.resource_label_events.label
+ project.merge_requests.resource_label_events.label.priorities
+ project.ci_pipelines.notes.events
+ project.ci_pipelines.notes.events.push_event_payload
+ project.protected_branches.unprotect_access_levels
+ project.prometheus_metrics
+ project.metrics_setting
+ project.boards.lists.label.priorities
+ project.service_desk_setting
+ project.security_setting
+ ].freeze
+ end
# A list of JSON fixture files we use to test Import.
# Most of the relations are present in `complex/project.json`
# which is our main fixture.
- PROJECT_JSON_FIXTURES = [
- 'spec/fixtures/lib/gitlab/import_export/complex/project.json',
- 'spec/fixtures/lib/gitlab/import_export/group/project.json',
- 'spec/fixtures/lib/gitlab/import_export/light/project.json',
- 'spec/fixtures/lib/gitlab/import_export/milestone-iid/project.json',
- 'spec/fixtures/lib/gitlab/import_export/designs/project.json'
- ].freeze
+ let(:project_json_fixtures) do
+ [
+ 'spec/fixtures/lib/gitlab/import_export/complex/project.json',
+ 'spec/fixtures/lib/gitlab/import_export/group/project.json',
+ 'spec/fixtures/lib/gitlab/import_export/light/project.json',
+ 'spec/fixtures/lib/gitlab/import_export/milestone-iid/project.json',
+ 'spec/fixtures/lib/gitlab/import_export/designs/project.json'
+ ].freeze
+ end
it 'ensures that all imported/exported relations are present in test JSONs' do
- not_tested_relations = (relations_from_config - tested_relations) - MUTED_RELATIONS
+ not_tested_relations = (relations_from_config - tested_relations) - muted_relations
expect(not_tested_relations).to be_empty, failure_message(not_tested_relations)
end
@@ -76,7 +81,7 @@ describe 'Test coverage of the Project Import' do
end
def tested_relations
- PROJECT_JSON_FIXTURES.flat_map(&method(:relations_from_json)).to_set
+ project_json_fixtures.flat_map(&method(:relations_from_json)).to_set
end
def relations_from_json(json_file)
@@ -106,7 +111,7 @@ describe 'Test coverage of the Project Import' do
These relations seem to be added recenty and
they expected to be covered in our Import specs: #{not_tested_relations}.
- To do that, expand one of the files listed in `PROJECT_JSON_FIXTURES`
+ To do that, expand one of the files listed in `project_json_fixtures`
(or expand the list if you consider adding a new fixture file).
After that, add a new spec into
@@ -114,7 +119,7 @@ describe 'Test coverage of the Project Import' do
to check that the relation is being imported correctly.
In case the spec breaks the master or there is a sense of urgency,
- you could include the relations into the `MUTED_RELATIONS` list.
+ you could include the relations into the `muted_relations` list.
Muting relations is considered to be a temporary solution, so please
open a follow-up issue and try to fix that when it is possible.
diff --git a/spec/lib/gitlab/import_export/importer_spec.rb b/spec/lib/gitlab/import_export/importer_spec.rb
index 60179146416..494f7e3a00d 100644
--- a/spec/lib/gitlab/import_export/importer_spec.rb
+++ b/spec/lib/gitlab/import_export/importer_spec.rb
@@ -18,6 +18,7 @@ describe Gitlab::ImportExport::Importer do
FileUtils.mkdir_p(shared.export_path)
ImportExportUpload.create(project: project, import_file: import_file)
+ allow(FileUtils).to receive(:rm_rf).and_call_original
end
after do
@@ -78,6 +79,13 @@ describe Gitlab::ImportExport::Importer do
expect(project.import_export_upload.import_file&.file).to be_nil
end
+ it 'removes tmp files' do
+ importer.execute
+
+ expect(FileUtils).to have_received(:rm_rf).with(shared.base_path)
+ expect(Dir.exist?(shared.base_path)).to eq(false)
+ end
+
it 'sets the correct visibility_level when visibility level is a string' do
project.create_or_update_import_data(
data: { override_params: { visibility_level: Gitlab::VisibilityLevel::PRIVATE.to_s } }
@@ -89,6 +97,49 @@ describe Gitlab::ImportExport::Importer do
end
end
+ context 'when import fails' do
+ let(:error_message) { 'foo' }
+
+ shared_examples 'removes any non migrated snippet' do
+ specify do
+ create_list(:project_snippet, 2, project: project)
+ snippet_with_repo = create(:project_snippet, :repository, project: project)
+
+ expect { importer.execute }.to change(Snippet, :count).by(-2).and(raise_error(Projects::ImportService::Error))
+
+ expect(snippet_with_repo.reload).to be_present
+ end
+ end
+
+ context 'when there is a graceful error' do
+ before do
+ allow_next_instance_of(Gitlab::ImportExport::AvatarRestorer) do |instance|
+ allow(instance).to receive(:avatar_export_file).and_raise(StandardError, error_message)
+ end
+ end
+
+ it 'raises and exception' do
+ expect { importer.execute }.to raise_error(Projects::ImportService::Error, error_message)
+ end
+
+ it_behaves_like 'removes any non migrated snippet'
+ end
+
+ context 'when an unexpected exception is raised' do
+ before do
+ allow_next_instance_of(Gitlab::ImportExport::AvatarRestorer) do |instance|
+ allow(instance).to receive(:restore).and_raise(StandardError, error_message)
+ end
+ end
+
+ it 'captures it and raises the Projects::ImportService::Error exception' do
+ expect { importer.execute }.to raise_error(Projects::ImportService::Error, error_message)
+ end
+
+ it_behaves_like 'removes any non migrated snippet'
+ end
+ end
+
context 'when project successfully restored' do
context "with a project in a user's namespace" do
let!(:existing_project) { create(:project, namespace: user.namespace) }
diff --git a/spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb b/spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb
index 076f454895f..30f8280fda3 100644
--- a/spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb
+++ b/spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb
@@ -95,4 +95,26 @@ describe Gitlab::ImportExport::JSON::StreamingSerializer do
end
end
end
+
+ describe '.batch_size' do
+ context 'when export_reduce_relation_batch_size feature flag is enabled' do
+ before do
+ stub_feature_flags(export_reduce_relation_batch_size: true)
+ end
+
+ it 'returns 20' do
+ expect(described_class.batch_size(exportable)).to eq(described_class::SMALLER_BATCH_SIZE)
+ end
+ end
+
+ context 'when export_reduce_relation_batch_size feature flag is disabled' do
+ before do
+ stub_feature_flags(export_reduce_relation_batch_size: false)
+ end
+
+ it 'returns default batch size' do
+ expect(described_class.batch_size(exportable)).to eq(described_class::BATCH_SIZE)
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/import_export/legacy_relation_tree_saver_spec.rb b/spec/lib/gitlab/import_export/legacy_relation_tree_saver_spec.rb
index 958865f52a0..6562aa5b8a6 100644
--- a/spec/lib/gitlab/import_export/legacy_relation_tree_saver_spec.rb
+++ b/spec/lib/gitlab/import_export/legacy_relation_tree_saver_spec.rb
@@ -8,17 +8,35 @@ describe Gitlab::ImportExport::LegacyRelationTreeSaver do
let(:tree) { {} }
describe '#serialize' do
- let(:serializer) { instance_double(Gitlab::ImportExport::FastHashSerializer) }
+ shared_examples 'FastHashSerializer with batch size' do |batch_size|
+ let(:serializer) { instance_double(Gitlab::ImportExport::FastHashSerializer) }
- it 'uses FastHashSerializer' do
- expect(Gitlab::ImportExport::FastHashSerializer)
- .to receive(:new)
- .with(exportable, tree)
- .and_return(serializer)
+ it 'uses FastHashSerializer' do
+ expect(Gitlab::ImportExport::FastHashSerializer)
+ .to receive(:new)
+ .with(exportable, tree, batch_size: batch_size)
+ .and_return(serializer)
- expect(serializer).to receive(:execute)
+ expect(serializer).to receive(:execute)
- relation_tree_saver.serialize(exportable, tree)
+ relation_tree_saver.serialize(exportable, tree)
+ end
+ end
+
+ context 'when export_reduce_relation_batch_size feature flag is enabled' do
+ before do
+ stub_feature_flags(export_reduce_relation_batch_size: true)
+ end
+
+ include_examples 'FastHashSerializer with batch size', Gitlab::ImportExport::JSON::StreamingSerializer::SMALLER_BATCH_SIZE
+ end
+
+ context 'when export_reduce_relation_batch_size feature flag is disabled' do
+ before do
+ stub_feature_flags(export_reduce_relation_batch_size: false)
+ end
+
+ include_examples 'FastHashSerializer with batch size', Gitlab::ImportExport::JSON::StreamingSerializer::BATCH_SIZE
end
end
end
diff --git a/spec/lib/gitlab/import_export/project/relation_factory_spec.rb b/spec/lib/gitlab/import_export/project/relation_factory_spec.rb
index 175da623c1b..3339129cb8f 100644
--- a/spec/lib/gitlab/import_export/project/relation_factory_spec.rb
+++ b/spec/lib/gitlab/import_export/project/relation_factory_spec.rb
@@ -18,6 +18,22 @@ describe Gitlab::ImportExport::Project::RelationFactory do
excluded_keys: excluded_keys)
end
+ before do
+ # Mocks an ActiveRecordish object with the dodgy columns
+ stub_const('FooModel', Class.new)
+ FooModel.class_eval do
+ include ActiveModel::Model
+
+ def initialize(params = {})
+ params.each { |key, value| send("#{key}=", value) }
+ end
+
+ def values
+ instance_variables.map { |ivar| instance_variable_get(ivar) }
+ end
+ end
+ end
+
context 'hook object' do
let(:relation_sym) { :hooks }
let(:id) { 999 }
@@ -83,19 +99,6 @@ describe Gitlab::ImportExport::Project::RelationFactory do
end
end
- # Mocks an ActiveRecordish object with the dodgy columns
- class FooModel
- include ActiveModel::Model
-
- def initialize(params = {})
- params.each { |key, value| send("#{key}=", value) }
- end
-
- def values
- instance_variables.map { |ivar| instance_variable_get(ivar) }
- end
- end
-
context 'merge_request object' do
let(:relation_sym) { :merge_requests }
@@ -208,11 +211,12 @@ describe Gitlab::ImportExport::Project::RelationFactory do
}
end
- class HazardousFooModel < FooModel
- attr_accessor :service_id, :moved_to_id, :namespace_id, :ci_id, :random_project_id, :random_id, :milestone_id, :project_id
- end
-
before do
+ stub_const('HazardousFooModel', Class.new(FooModel))
+ HazardousFooModel.class_eval do
+ attr_accessor :service_id, :moved_to_id, :namespace_id, :ci_id, :random_project_id, :random_id, :milestone_id, :project_id
+ end
+
allow(HazardousFooModel).to receive(:reflect_on_association).and_return(nil)
end
@@ -246,11 +250,12 @@ describe Gitlab::ImportExport::Project::RelationFactory do
Gitlab::ImportExport::Project::RelationFactory::PROJECT_REFERENCES.map { |ref| { ref => 99 } }.inject(:merge)
end
- class ProjectFooModel < FooModel
- attr_accessor(*Gitlab::ImportExport::Project::RelationFactory::PROJECT_REFERENCES)
- end
-
before do
+ stub_const('ProjectFooModel', Class.new(FooModel))
+ ProjectFooModel.class_eval do
+ attr_accessor(*Gitlab::ImportExport::Project::RelationFactory::PROJECT_REFERENCES)
+ end
+
allow(ProjectFooModel).to receive(:reflect_on_association).and_return(nil)
end
diff --git a/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb
index 58589a7bbbe..867dc37c5c5 100644
--- a/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb
@@ -26,7 +26,7 @@ describe Gitlab::ImportExport::Project::TreeRestorer do
@project = create(:project, :builds_enabled, :issues_disabled, name: 'project', path: 'project')
@shared = @project.import_export_shared
- allow(Feature).to receive(:enabled?) { true }
+ stub_all_feature_flags
stub_feature_flags(project_import_ndjson: ndjson_enabled)
setup_import_export_config('complex')
diff --git a/spec/lib/gitlab/import_export/project/tree_saver_spec.rb b/spec/lib/gitlab/import_export/project/tree_saver_spec.rb
index b9bfe253f10..533d1097928 100644
--- a/spec/lib/gitlab/import_export/project/tree_saver_spec.rb
+++ b/spec/lib/gitlab/import_export/project/tree_saver_spec.rb
@@ -29,7 +29,7 @@ describe Gitlab::ImportExport::Project::TreeSaver do
before_all do
RSpec::Mocks.with_temporary_scope do
- allow(Feature).to receive(:enabled?) { true }
+ stub_all_feature_flags
stub_feature_flags(project_export_as_ndjson: ndjson_enabled)
project.add_maintainer(user)
diff --git a/spec/lib/gitlab/import_export/repo_restorer_spec.rb b/spec/lib/gitlab/import_export/repo_restorer_spec.rb
index a61d966bdfa..d5839589633 100644
--- a/spec/lib/gitlab/import_export/repo_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/repo_restorer_spec.rb
@@ -13,11 +13,8 @@ describe Gitlab::ImportExport::RepoRestorer do
let(:shared) { project.import_export_shared }
let(:bundler) { Gitlab::ImportExport::RepoSaver.new(project: project_with_repo, shared: shared) }
let(:bundle_path) { File.join(shared.export_path, Gitlab::ImportExport.project_bundle_filename) }
- let(:restorer) do
- described_class.new(path_to_bundle: bundle_path,
- shared: shared,
- project: project)
- end
+
+ subject { described_class.new(path_to_bundle: bundle_path, shared: shared, project: project) }
before do
allow_next_instance_of(Gitlab::ImportExport) do |instance|
@@ -36,7 +33,25 @@ describe Gitlab::ImportExport::RepoRestorer do
end
it 'restores the repo successfully' do
- expect(restorer.restore).to be_truthy
+ expect(subject.restore).to be_truthy
+ end
+
+ context 'when the repository creation fails' do
+ before do
+ allow_next_instance_of(Repositories::DestroyService) do |instance|
+ expect(instance).to receive(:execute).and_call_original
+ end
+ end
+
+ it 'logs the error' do
+ allow(project.repository)
+ .to receive(:create_from_bundle)
+ .and_raise('9:CreateRepositoryFromBundle: target directory is non-empty')
+
+ expect(shared).to receive(:error).and_call_original
+
+ expect(subject.restore).to be_falsey
+ 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 c29a85ce624..0d112bfdb2a 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -144,6 +144,7 @@ Releases::Link:
- url
- name
- filepath
+- link_type
- created_at
- updated_at
ProjectMember:
@@ -471,6 +472,7 @@ Service:
- properties
- template
- instance
+- alert_events
- push_events
- issues_events
- commit_events
@@ -701,6 +703,8 @@ Badge:
- type
ProjectCiCdSetting:
- group_runners_enabled
+ProjectSetting:
+- allow_merge_on_skipped_pipeline
ProtectedEnvironment:
- id
- project_id
@@ -749,6 +753,7 @@ ProjectMetricsSetting:
- external_dashboard_url
- created_at
- updated_at
+- dashboard_timezone
Board:
- id
- project_id
@@ -861,3 +866,11 @@ SystemNoteMetadata:
- action
- created_at
- updated_at
+ProjectSecuritySetting:
+ - project_id
+ - auto_fix_container_scanning
+ - auto_fix_dast
+ - auto_fix_dependency_scanning
+ - auto_fix_sast
+ - created_at
+ - updated_at
diff --git a/spec/lib/gitlab/import_export/saver_spec.rb b/spec/lib/gitlab/import_export/saver_spec.rb
index a59cf7a1260..18e9d7da32d 100644
--- a/spec/lib/gitlab/import_export/saver_spec.rb
+++ b/spec/lib/gitlab/import_export/saver_spec.rb
@@ -5,18 +5,21 @@ require 'fileutils'
describe Gitlab::ImportExport::Saver do
let!(:project) { create(:project, :public, name: 'project') }
- let(:export_path) { "#{Dir.tmpdir}/project_tree_saver_spec" }
+ let(:base_path) { "#{Dir.tmpdir}/project_tree_saver_spec" }
+ let(:export_path) { "#{base_path}/project_tree_saver_spec/export" }
let(:shared) { project.import_export_shared }
subject { described_class.new(exportable: project, shared: shared) }
before do
+ allow(shared).to receive(:base_path).and_return(base_path)
allow_next_instance_of(Gitlab::ImportExport) do |instance|
allow(instance).to receive(:storage_path).and_return(export_path)
end
FileUtils.mkdir_p(shared.export_path)
FileUtils.touch("#{shared.export_path}/tmp.bundle")
+ allow(FileUtils).to receive(:rm_rf).and_call_original
end
after do
@@ -31,4 +34,11 @@ describe Gitlab::ImportExport::Saver do
expect(ImportExportUpload.find_by(project: project).export_file.url)
.to match(%r[\/uploads\/-\/system\/import_export_upload\/export_file.*])
end
+
+ it 'removes tmp files' do
+ subject.save
+
+ expect(FileUtils).to have_received(:rm_rf).with(base_path)
+ expect(Dir.exist?(base_path)).to eq(false)
+ end
end
diff --git a/spec/lib/gitlab/import_export/snippet_repo_restorer_spec.rb b/spec/lib/gitlab/import_export/snippet_repo_restorer_spec.rb
index 3ce950d6a64..779b65e33d8 100644
--- a/spec/lib/gitlab/import_export/snippet_repo_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/snippet_repo_restorer_spec.rb
@@ -25,16 +25,24 @@ describe Gitlab::ImportExport::SnippetRepoRestorer do
expect(snippet.repository_exists?).to be_falsey
aggregate_failures do
- expect(restorer.restore).to be_truthy
-
- expect(snippet.repository_exists?).to be_truthy
- expect(snippet.snippet_repository).not_to be_nil
+ expect do
+ expect(restorer.restore).to be_truthy
+ end.to change { SnippetRepository.count }.by(1)
blob = snippet.repository.blob_at('HEAD', snippet.file_name)
expect(blob).not_to be_nil
expect(blob.data).to eq(snippet.content)
end
end
+
+ context 'when the repository creation fails' do
+ it 'returns false' do
+ allow_any_instance_of(Gitlab::BackgroundMigration::BackfillSnippetRepositories).to receive(:perform_by_ids).and_return(nil)
+
+ expect(restorer.restore).to be false
+ expect(shared.errors.first).to match(/Error creating repository for snippet/)
+ end
+ end
end
context 'when the snippet does not have a bundle file path' do
diff --git a/spec/lib/gitlab/import_export/snippets_repo_restorer_spec.rb b/spec/lib/gitlab/import_export/snippets_repo_restorer_spec.rb
index 242f6f6b58c..fdae259c2f1 100644
--- a/spec/lib/gitlab/import_export/snippets_repo_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/snippets_repo_restorer_spec.rb
@@ -8,43 +8,92 @@ describe Gitlab::ImportExport::SnippetsRepoRestorer do
describe 'bundle a snippet Git repo' do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, namespace: user.namespace) }
- let_it_be(:snippet_with_repo) { create(:project_snippet, :repository, project: project, author: user) }
- let_it_be(:snippet_without_repo) { create(:project_snippet, project: project, author: user) }
+ let!(:snippet1) { create(:project_snippet, project: project, author: user) }
+ let!(:snippet2) { create(:project_snippet, project: project, author: user) }
let(:shared) { project.import_export_shared }
let(:exporter) { Gitlab::ImportExport::SnippetsRepoSaver.new(current_user: user, project: project, shared: shared) }
let(:bundle_dir) { ::Gitlab::ImportExport.snippets_repo_bundle_path(shared.export_path) }
+ let(:service) { instance_double(Gitlab::ImportExport::SnippetRepoRestorer) }
let(:restorer) do
described_class.new(user: user,
shared: shared,
project: project)
end
- let(:service) { instance_double(Gitlab::ImportExport::SnippetRepoRestorer) }
-
- before do
- exporter.save
- end
after do
FileUtils.rm_rf(shared.export_path)
end
- it 'calls SnippetRepoRestorer per each snippet with the bundle path' do
- allow(service).to receive(:restore).and_return(true)
+ shared_examples 'imports snippet repositories' do
+ before do
+ snippet1.snippet_repository&.delete
+ snippet1.repository.remove
+
+ snippet2.snippet_repository&.delete
+ snippet2.repository.remove
+ end
+
+ specify do
+ expect(snippet1.repository_exists?).to be false
+ expect(snippet2.repository_exists?).to be false
+
+ expect(Gitlab::ImportExport::SnippetRepoRestorer).to receive(:new).with(hash_including(snippet: snippet1, path_to_bundle: bundle_path(snippet1))).and_call_original
+ expect(Gitlab::ImportExport::SnippetRepoRestorer).to receive(:new).with(hash_including(snippet: snippet2, path_to_bundle: bundle_path(snippet2))).and_call_original
+ expect(restorer.restore).to be_truthy
+
+ snippet1.repository.expire_exists_cache
+ snippet2.repository.expire_exists_cache
+
+ expect(snippet1.blobs).not_to be_empty
+ expect(snippet2.blobs).not_to be_empty
+ end
+ end
+
+ context 'when export has no snippet repository bundle' do
+ before do
+ expect(Dir.exist?(bundle_dir)).to be false
+ end
+
+ it_behaves_like 'imports snippet repositories'
+ end
+
+ context 'when export has snippet repository bundles and snippets without them' do
+ let!(:snippet1) { create(:project_snippet, :repository, project: project, author: user) }
+ let!(:snippet2) { create(:project_snippet, project: project, author: user) }
- expect(Gitlab::ImportExport::SnippetRepoRestorer).to receive(:new).with(hash_including(snippet: snippet_with_repo, path_to_bundle: bundle_path(snippet_with_repo))).and_return(service)
- expect(Gitlab::ImportExport::SnippetRepoRestorer).to receive(:new).with(hash_including(snippet: snippet_without_repo, path_to_bundle: bundle_path(snippet_without_repo))).and_return(service)
+ before do
+ exporter.save
- expect(restorer.restore).to be_truthy
+ expect(File.exist?(bundle_path(snippet1))).to be true
+ expect(File.exist?(bundle_path(snippet2))).to be false
+ end
+
+ it_behaves_like 'imports snippet repositories'
end
- context 'when one snippet cannot be saved' do
- it 'returns false and do not process other snippets' do
- allow(Gitlab::ImportExport::SnippetRepoRestorer).to receive(:new).with(hash_including(snippet: snippet_with_repo)).and_return(service)
+ context 'when export has only snippet bundles' do
+ let!(:snippet1) { create(:project_snippet, :repository, project: project, author: user) }
+ let!(:snippet2) { create(:project_snippet, :repository, project: project, author: user) }
+
+ before do
+ exporter.save
+
+ expect(File.exist?(bundle_path(snippet1))).to be true
+ expect(File.exist?(bundle_path(snippet2))).to be true
+ end
+
+ it_behaves_like 'imports snippet repositories'
+ end
+
+ context 'when any of the snippet repositories cannot be created' do
+ it 'continues processing other snippets and returns false' do
+ allow(Gitlab::ImportExport::SnippetRepoRestorer).to receive(:new).with(hash_including(snippet: snippet1)).and_return(service)
allow(service).to receive(:restore).and_return(false)
- expect(Gitlab::ImportExport::SnippetRepoRestorer).not_to receive(:new).with(hash_including(snippet: snippet_without_repo))
- expect(restorer.restore).to be_falsey
+ expect(Gitlab::ImportExport::SnippetRepoRestorer).to receive(:new).with(hash_including(snippet: snippet2)).and_call_original
+
+ expect(restorer.restore).to be false
end
end
diff --git a/spec/lib/gitlab/instrumentation/redis_base_spec.rb b/spec/lib/gitlab/instrumentation/redis_base_spec.rb
new file mode 100644
index 00000000000..5ea8f00114e
--- /dev/null
+++ b/spec/lib/gitlab/instrumentation/redis_base_spec.rb
@@ -0,0 +1,144 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Instrumentation::RedisBase, :request_store do
+ let(:instrumentation_class_a) do
+ stub_const('InstanceA', Class.new(described_class))
+ end
+
+ let(:instrumentation_class_b) do
+ stub_const('InstanceB', Class.new(described_class))
+ end
+
+ describe '.storage_key' do
+ it 'returns the class name with underscore' do
+ expect(instrumentation_class_a.storage_key).to eq('instance_a')
+ expect(instrumentation_class_b.storage_key).to eq('instance_b')
+ end
+ end
+
+ describe '.known_payload_keys' do
+ it 'returns generated payload keys' do
+ expect(instrumentation_class_a.known_payload_keys).to eq([:redis_instance_a_calls,
+ :redis_instance_a_duration_s,
+ :redis_instance_a_read_bytes,
+ :redis_instance_a_write_bytes])
+ end
+
+ it 'does not call calculation methods' do
+ expect(instrumentation_class_a).not_to receive(:get_request_count)
+ expect(instrumentation_class_a).not_to receive(:query_time)
+ expect(instrumentation_class_a).not_to receive(:read_bytes)
+ expect(instrumentation_class_a).not_to receive(:write_bytes)
+
+ instrumentation_class_a.known_payload_keys
+ end
+ end
+
+ describe '.payload' do
+ it 'returns values that are higher than 0' do
+ allow(instrumentation_class_a).to receive(:get_request_count) { 1 }
+ allow(instrumentation_class_a).to receive(:query_time) { 0.1 }
+ allow(instrumentation_class_a).to receive(:read_bytes) { 0.0 }
+ allow(instrumentation_class_a).to receive(:write_bytes) { 123 }
+
+ expected_payload = {
+ redis_instance_a_calls: 1,
+ redis_instance_a_write_bytes: 123,
+ redis_instance_a_duration_s: 0.1
+ }
+
+ expect(instrumentation_class_a.payload).to eq(expected_payload)
+ end
+ end
+
+ describe '.add_duration' do
+ it 'does not lose precision while adding' do
+ precision = 1.0 / (10**::Gitlab::InstrumentationHelper::DURATION_PRECISION)
+ 2.times { instrumentation_class_a.add_duration(0.4 * precision) }
+
+ # 2 * 0.4 should be 0.8 and get rounded to 1
+ expect(instrumentation_class_a.query_time).to eq(1 * precision)
+ end
+
+ context 'storage key overlapping' do
+ it 'keys do not overlap across storages' do
+ instrumentation_class_a.add_duration(0.4)
+ instrumentation_class_b.add_duration(0.5)
+
+ expect(instrumentation_class_a.query_time).to eq(0.4)
+ expect(instrumentation_class_b.query_time).to eq(0.5)
+ end
+ end
+ end
+
+ describe '.increment_request_count' do
+ context 'storage key overlapping' do
+ it 'keys do not overlap across storages' do
+ 3.times { instrumentation_class_a.increment_request_count }
+ 2.times { instrumentation_class_b.increment_request_count }
+
+ expect(instrumentation_class_a.get_request_count).to eq(3)
+ expect(instrumentation_class_b.get_request_count).to eq(2)
+ end
+ end
+ end
+
+ describe '.increment_write_bytes' do
+ context 'storage key overlapping' do
+ it 'keys do not overlap across storages' do
+ 2.times do
+ instrumentation_class_a.increment_write_bytes(42)
+ instrumentation_class_b.increment_write_bytes(77)
+ end
+
+ expect(instrumentation_class_a.write_bytes).to eq(42 * 2)
+ expect(instrumentation_class_b.write_bytes).to eq(77 * 2)
+ end
+ end
+ end
+
+ describe '.increment_read_bytes' do
+ context 'storage key overlapping' do
+ it 'keys do not overlap across storages' do
+ 2.times do
+ instrumentation_class_a.increment_read_bytes(42)
+ instrumentation_class_b.increment_read_bytes(77)
+ end
+
+ expect(instrumentation_class_a.read_bytes).to eq(42 * 2)
+ expect(instrumentation_class_b.read_bytes).to eq(77 * 2)
+ end
+ end
+ end
+
+ describe '.add_call_details' do
+ before do
+ allow(Gitlab::PerformanceBar).to receive(:enabled_for_request?) { true }
+ end
+
+ context 'storage key overlapping' do
+ it 'keys do not overlap across storages' do
+ 2.times do
+ instrumentation_class_a.add_call_details(0.3, [:set])
+ instrumentation_class_b.add_call_details(0.4, [:set])
+ end
+
+ expect(instrumentation_class_a.detail_store).to match(
+ [
+ a_hash_including(cmd: :set, duration: 0.3, backtrace: an_instance_of(Array)),
+ a_hash_including(cmd: :set, duration: 0.3, backtrace: an_instance_of(Array))
+ ]
+ )
+
+ expect(instrumentation_class_b.detail_store).to match(
+ [
+ a_hash_including(cmd: :set, duration: 0.4, backtrace: an_instance_of(Array)),
+ a_hash_including(cmd: :set, duration: 0.4, backtrace: an_instance_of(Array))
+ ]
+ )
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/instrumentation/redis_interceptor_spec.rb b/spec/lib/gitlab/instrumentation/redis_interceptor_spec.rb
new file mode 100644
index 00000000000..25506d63091
--- /dev/null
+++ b/spec/lib/gitlab/instrumentation/redis_interceptor_spec.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'rspec-parameterized'
+
+describe Gitlab::Instrumentation::RedisInterceptor, :clean_gitlab_redis_shared_state, :request_store do
+ using RSpec::Parameterized::TableSyntax
+
+ describe 'read and write' do
+ where(:setup, :command, :expect_write, :expect_read) do
+ # The response is 'OK', the request size is the combined size of array
+ # elements. Exercise counting of a status reply.
+ [] | [:set, 'foo', 'bar'] | 3 + 3 + 3 | 2
+
+ # The response is 1001, so 4 bytes. Exercise counting an integer reply.
+ [[:set, 'foobar', 1000]] | [:incr, 'foobar'] | 4 + 6 | 4
+
+ # Exercise counting empty multi bulk reply
+ [] | [:hgetall, 'foobar'] | 7 + 6 | 0
+
+ # Hgetall response length is combined length of keys and values in the
+ # hash. Exercises counting of a multi bulk reply
+ [[:hset, 'myhash', 'field', 'hello world']] | [:hgetall, 'myhash'] | 7 + 6 | 5 + 11
+
+ # Exercise counting of a bulk reply
+ [[:set, 'foo', 'bar' * 100]] | [:get, 'foo'] | 3 + 3 | 3 * 100
+
+ # Nested array response: ['123456-89', ['foo', 'bar']]
+ [[:xadd, 'mystream', '123456-89', 'foo', 'bar']] | [:xrange, 'mystream', '-', '+'] | 6 + 8 + 1 + 1 | 9 + 3 + 3
+ end
+
+ with_them do
+ it 'counts bytes read and written' do
+ Gitlab::Redis::SharedState.with do |redis|
+ setup.each { |cmd| redis.call(cmd) }
+ RequestStore.clear!
+ redis.call(command)
+ end
+
+ expect(Gitlab::Instrumentation::Redis.read_bytes).to eq(expect_read)
+ expect(Gitlab::Instrumentation::Redis.write_bytes).to eq(expect_write)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/instrumentation/redis_spec.rb b/spec/lib/gitlab/instrumentation/redis_spec.rb
new file mode 100644
index 00000000000..8311c4f5bbb
--- /dev/null
+++ b/spec/lib/gitlab/instrumentation/redis_spec.rb
@@ -0,0 +1,114 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Instrumentation::Redis do
+ def stub_storages(method, value)
+ described_class::STORAGES.each do |storage|
+ allow(storage).to receive(method) { value }
+ end
+ end
+
+ shared_examples 'aggregation of redis storage data' do |method|
+ describe "#{method} sum" do
+ it "sums data from all Redis storages" do
+ amount = 0.3
+
+ stub_storages(method, amount)
+
+ expect(described_class.public_send(method)).to eq(described_class::STORAGES.size * amount)
+ end
+ end
+ end
+
+ it_behaves_like 'aggregation of redis storage data', :get_request_count
+ it_behaves_like 'aggregation of redis storage data', :query_time
+ it_behaves_like 'aggregation of redis storage data', :read_bytes
+ it_behaves_like 'aggregation of redis storage data', :write_bytes
+
+ describe '.known_payload_keys' do
+ it 'returns all known payload keys' do
+ expected_keys = [
+ :redis_calls,
+ :redis_duration_s,
+ :redis_read_bytes,
+ :redis_write_bytes,
+ :redis_action_cable_calls,
+ :redis_action_cable_duration_s,
+ :redis_action_cable_read_bytes,
+ :redis_action_cable_write_bytes,
+ :redis_cache_calls,
+ :redis_cache_duration_s,
+ :redis_cache_read_bytes,
+ :redis_cache_write_bytes,
+ :redis_queues_calls,
+ :redis_queues_duration_s,
+ :redis_queues_read_bytes,
+ :redis_queues_write_bytes,
+ :redis_shared_state_calls,
+ :redis_shared_state_duration_s,
+ :redis_shared_state_read_bytes,
+ :redis_shared_state_write_bytes
+ ]
+
+ expect(described_class.known_payload_keys).to eq(expected_keys)
+ end
+
+ it 'does not call storage calculation methods' do
+ described_class::STORAGES.each do |storage|
+ expect(storage).not_to receive(:get_request_count)
+ expect(storage).not_to receive(:query_time)
+ expect(storage).not_to receive(:read_bytes)
+ expect(storage).not_to receive(:write_bytes)
+ end
+
+ described_class.known_payload_keys
+ end
+ end
+
+ describe '.payload', :request_store do
+ before do
+ Gitlab::Redis::Cache.with { |redis| redis.set('cache-test', 321) }
+ Gitlab::Redis::SharedState.with { |redis| redis.set('shared-state-test', 123) }
+ end
+
+ it 'returns payload filtering out zeroed values' do
+ expected_payload = {
+ # Aggregated results
+ redis_calls: 2,
+ redis_duration_s: be >= 0,
+ redis_read_bytes: be >= 0,
+ redis_write_bytes: be >= 0,
+
+ # Cache results
+ redis_cache_calls: 1,
+ redis_cache_duration_s: be >= 0,
+ redis_cache_read_bytes: be >= 0,
+ redis_cache_write_bytes: be >= 0,
+
+ # Shared state results
+ redis_shared_state_calls: 1,
+ redis_shared_state_duration_s: be >= 0,
+ redis_shared_state_read_bytes: be >= 0,
+ redis_shared_state_write_bytes: be >= 0
+ }
+
+ expect(described_class.payload).to include(expected_payload)
+ expect(described_class.payload.keys).to match_array(expected_payload.keys)
+ end
+ end
+
+ describe '.detail_store' do
+ it 'returns a flat array of detail stores with the storage name added to each item' do
+ details_row = { cmd: 'GET foo', duration: 1 }
+
+ stub_storages(:detail_store, [details_row])
+
+ expect(described_class.detail_store)
+ .to contain_exactly(details_row.merge(storage: 'ActionCable'),
+ details_row.merge(storage: 'Cache'),
+ details_row.merge(storage: 'Queues'),
+ details_row.merge(storage: 'SharedState'))
+ end
+ end
+end
diff --git a/spec/lib/gitlab/instrumentation_helper_spec.rb b/spec/lib/gitlab/instrumentation_helper_spec.rb
index fdb842dac0f..15d377a16fc 100644
--- a/spec/lib/gitlab/instrumentation_helper_spec.rb
+++ b/spec/lib/gitlab/instrumentation_helper_spec.rb
@@ -6,6 +6,41 @@ require 'rspec-parameterized'
describe Gitlab::InstrumentationHelper do
using RSpec::Parameterized::TableSyntax
+ describe '.keys' do
+ it 'returns all available payload keys' do
+ expected_keys = [
+ :gitaly_calls,
+ :gitaly_duration_s,
+ :rugged_calls,
+ :rugged_duration_s,
+ :elasticsearch_calls,
+ :elasticsearch_duration_s,
+ :redis_calls,
+ :redis_duration_s,
+ :redis_read_bytes,
+ :redis_write_bytes,
+ :redis_action_cable_calls,
+ :redis_action_cable_duration_s,
+ :redis_action_cable_read_bytes,
+ :redis_action_cable_write_bytes,
+ :redis_cache_calls,
+ :redis_cache_duration_s,
+ :redis_cache_read_bytes,
+ :redis_cache_write_bytes,
+ :redis_queues_calls,
+ :redis_queues_duration_s,
+ :redis_queues_read_bytes,
+ :redis_queues_write_bytes,
+ :redis_shared_state_calls,
+ :redis_shared_state_duration_s,
+ :redis_shared_state_read_bytes,
+ :redis_shared_state_write_bytes
+ ]
+
+ expect(described_class.keys).to eq(expected_keys)
+ end
+ end
+
describe '.add_instrumentation_data', :request_store do
let(:payload) { {} }
@@ -34,12 +69,30 @@ describe Gitlab::InstrumentationHelper do
context 'when Redis calls are made' do
it 'adds Redis data and omits Gitaly data' do
- Gitlab::Redis::Cache.with { |redis| redis.get('test-instrumentation') }
+ Gitlab::Redis::Cache.with { |redis| redis.set('test-cache', 123) }
+ Gitlab::Redis::Queues.with { |redis| redis.set('test-queues', 321) }
subject
- expect(payload[:redis_calls]).to eq(1)
+ # Aggregated payload
+ expect(payload[:redis_calls]).to eq(2)
expect(payload[:redis_duration_s]).to be >= 0
+ expect(payload[:redis_read_bytes]).to be >= 0
+ expect(payload[:redis_write_bytes]).to be >= 0
+
+ # Shared state payload
+ expect(payload[:redis_queues_calls]).to eq(1)
+ expect(payload[:redis_queues_duration_s]).to be >= 0
+ expect(payload[:redis_queues_read_bytes]).to be >= 0
+ expect(payload[:redis_queues_write_bytes]).to be >= 0
+
+ # Cache payload
+ expect(payload[:redis_cache_calls]).to eq(1)
+ expect(payload[:redis_cache_duration_s]).to be >= 0
+ expect(payload[:redis_cache_read_bytes]).to be >= 0
+ expect(payload[:redis_cache_write_bytes]).to be >= 0
+
+ # Gitaly
expect(payload[:gitaly_calls]).to be_nil
expect(payload[:gitaly_duration]).to be_nil
end
diff --git a/spec/lib/gitlab/issuable_metadata_spec.rb b/spec/lib/gitlab/issuable_metadata_spec.rb
index 7632bc3060a..1920cecfc29 100644
--- a/spec/lib/gitlab/issuable_metadata_spec.rb
+++ b/spec/lib/gitlab/issuable_metadata_spec.rb
@@ -6,14 +6,12 @@ describe Gitlab::IssuableMetadata do
let(:user) { create(:user) }
let!(:project) { create(:project, :public, :repository, creator: user, namespace: user.namespace) }
- subject { Class.new { include Gitlab::IssuableMetadata }.new }
-
it 'returns an empty Hash if an empty collection is provided' do
- expect(subject.issuable_meta_data(Issue.none, 'Issue', user)).to eq({})
+ expect(described_class.new(user, Issue.none).data).to eq({})
end
it 'raises an error when given a collection with no limit' do
- expect { subject.issuable_meta_data(Issue.all, 'Issue', user) }.to raise_error(/must have a limit/)
+ expect { described_class.new(user, Issue.all) }.to raise_error(/must have a limit/)
end
context 'issues' do
@@ -25,7 +23,7 @@ describe Gitlab::IssuableMetadata do
let!(:closing_issues) { create(:merge_requests_closing_issues, issue: issue, merge_request: merge_request) }
it 'aggregates stats on issues' do
- data = subject.issuable_meta_data(Issue.all.limit(10), 'Issue', user)
+ data = described_class.new(user, Issue.all.limit(10)).data
expect(data.count).to eq(2)
expect(data[issue.id].upvotes).to eq(1)
@@ -48,7 +46,7 @@ describe Gitlab::IssuableMetadata do
let!(:note) { create(:note_on_merge_request, author: user, project: project, noteable: merge_request, note: "a comment on a MR") }
it 'aggregates stats on merge requests' do
- data = subject.issuable_meta_data(MergeRequest.all.limit(10), 'MergeRequest', user)
+ data = described_class.new(user, MergeRequest.all.limit(10)).data
expect(data.count).to eq(2)
expect(data[merge_request.id].upvotes).to eq(1)
diff --git a/spec/lib/gitlab/jira_import/base_importer_spec.rb b/spec/lib/gitlab/jira_import/base_importer_spec.rb
index ecaf3def589..cda491393e8 100644
--- a/spec/lib/gitlab/jira_import/base_importer_spec.rb
+++ b/spec/lib/gitlab/jira_import/base_importer_spec.rb
@@ -8,27 +8,13 @@ describe Gitlab::JiraImport::BaseImporter do
let(:project) { create(:project) }
describe 'with any inheriting class' do
- context 'when an error is returned from the project validation' do
- before do
- stub_feature_flags(jira_issue_import: false)
-
- allow(project).to receive(:validate_jira_import_settings!)
- .and_raise(Projects::ImportService::Error, 'Jira import feature is disabled.')
- end
-
- it 'raises exception' do
- expect { described_class.new(project) }.to raise_error(Projects::ImportService::Error, 'Jira import feature is disabled.')
- end
- end
-
context 'when project validation is ok' do
let!(:jira_service) { create(:jira_service, project: project) }
before do
- stub_feature_flags(jira_issue_import: true)
stub_jira_service_test
- allow(project).to receive(:validate_jira_import_settings!)
+ allow(Gitlab::JiraImport).to receive(:validate_project_settings!)
end
context 'when Jira service exists' do
diff --git a/spec/lib/gitlab/jira_import/issues_importer_spec.rb b/spec/lib/gitlab/jira_import/issues_importer_spec.rb
index 6cf06c20e19..0d790f49450 100644
--- a/spec/lib/gitlab/jira_import/issues_importer_spec.rb
+++ b/spec/lib/gitlab/jira_import/issues_importer_spec.rb
@@ -14,7 +14,6 @@ describe Gitlab::JiraImport::IssuesImporter do
subject { described_class.new(project) }
before do
- stub_feature_flags(jira_issue_import: true)
stub_jira_service_test
end
@@ -39,15 +38,22 @@ describe Gitlab::JiraImport::IssuesImporter do
end
context 'with results returned' do
- JiraIssue = Struct.new(:id)
- let_it_be(:jira_issues) { [JiraIssue.new(1), JiraIssue.new(2)] }
+ jira_issue = Struct.new(:id)
+ let_it_be(:jira_issues) { [jira_issue.new(1), jira_issue.new(2)] }
- def mock_issue_serializer(count)
+ def mock_issue_serializer(count, raise_exception_on_even_mocks: false)
serializer = instance_double(Gitlab::JiraImport::IssueSerializer, execute: { key: 'data' })
+ next_iid = project.issues.maximum(:iid).to_i
count.times do |i|
- expect(Gitlab::JiraImport::IssueSerializer).to receive(:new)
- .with(project, jira_issues[i], current_user.id, { iid: i + 1 }).and_return(serializer)
+ if raise_exception_on_even_mocks && i.even?
+ expect(Gitlab::JiraImport::IssueSerializer).to receive(:new)
+ .with(project, jira_issues[i], current_user.id, { iid: next_iid + 1 }).and_raise('Some error')
+ else
+ next_iid += 1
+ expect(Gitlab::JiraImport::IssueSerializer).to receive(:new)
+ .with(project, jira_issues[i], current_user.id, { iid: next_iid }).and_return(serializer)
+ end
end
end
@@ -70,21 +76,22 @@ describe Gitlab::JiraImport::IssuesImporter do
end
end
- context 'when there is more than one page of results' do
+ context 'when importing some issue raises an exception' do
before do
- stub_const("#{described_class.name}::BATCH_SIZE", 2)
+ stub_const("#{described_class.name}::BATCH_SIZE", 3)
end
- it 'schedules 3 import jobs' do
+ it 'schedules 2 import jobs' do
expect(subject).to receive(:fetch_issues).with(0).and_return([jira_issues[0], jira_issues[1]])
- expect(Gitlab::JiraImport::ImportIssueWorker).to receive(:perform_async).twice.times
- expect(Gitlab::Cache::Import::Caching).to receive(:set_add).twice.times.and_call_original
- expect(Gitlab::Cache::Import::Caching).to receive(:set_includes?).twice.times.and_call_original
- mock_issue_serializer(2)
+ expect(Gitlab::JiraImport::ImportIssueWorker).to receive(:perform_async).once
+ expect(Gitlab::Cache::Import::Caching).to receive(:set_add).once.and_call_original
+ expect(Gitlab::Cache::Import::Caching).to receive(:set_includes?).twice.and_call_original
+ expect(Gitlab::ErrorTracking).to receive(:track_exception).once
+ mock_issue_serializer(2, raise_exception_on_even_mocks: true)
job_waiter = subject.execute
- expect(job_waiter.jobs_remaining).to eq(2)
+ expect(job_waiter.jobs_remaining).to eq(1)
expect(Gitlab::JiraImport.get_issues_next_start_at(project.id)).to eq(2)
end
end
diff --git a/spec/lib/gitlab/jira_import/labels_importer_spec.rb b/spec/lib/gitlab/jira_import/labels_importer_spec.rb
index 67eb541d376..19661ff4e73 100644
--- a/spec/lib/gitlab/jira_import/labels_importer_spec.rb
+++ b/spec/lib/gitlab/jira_import/labels_importer_spec.rb
@@ -15,7 +15,6 @@ describe Gitlab::JiraImport::LabelsImporter do
subject { importer.execute }
before do
- stub_feature_flags(jira_issue_import: true)
stub_const('Gitlab::JiraImport::LabelsImporter::MAX_LABELS', 2)
end
diff --git a/spec/lib/gitlab/jira_import_spec.rb b/spec/lib/gitlab/jira_import_spec.rb
index c5c3d6ef4b9..5b95891c97e 100644
--- a/spec/lib/gitlab/jira_import_spec.rb
+++ b/spec/lib/gitlab/jira_import_spec.rb
@@ -5,9 +5,109 @@ require 'spec_helper'
describe Gitlab::JiraImport do
let(:project_id) { 321 }
+ describe '.validate_project_settings!' do
+ include JiraServiceHelper
+
+ let_it_be(:project, reload: true) { create(:project) }
+ let(:additional_params) { {} }
+
+ subject { described_class.validate_project_settings!(project, additional_params) }
+
+ shared_examples 'raise Jira import error' do |message|
+ it 'returns error' do
+ expect { subject }.to raise_error(Projects::ImportService::Error, message)
+ end
+ end
+
+ shared_examples 'jira configuration base checks' do
+ context 'with configuration_check set to false' do
+ before do
+ additional_params[:configuration_check] = false
+ end
+
+ it 'does not raise Jira integration error' do
+ expect { subject }.not_to raise_error
+ end
+ end
+
+ context 'when Jira service was not setup' do
+ it_behaves_like 'raise Jira import error', 'Jira integration not configured.'
+ end
+
+ context 'when Jira service exists' do
+ let!(:jira_service) { create(:jira_service, project: project, active: true) }
+
+ context 'when Jira connection is not valid' do
+ before do
+ WebMock.stub_request(:get, 'https://jira.example.com/rest/api/2/serverInfo')
+ .to_raise(JIRA::HTTPError.new(double(message: 'Some failure.')))
+ end
+
+ it_behaves_like 'raise Jira import error', 'Unable to connect to the Jira instance. Please check your Jira integration configuration.'
+ end
+ end
+ end
+
+ before do
+ stub_jira_service_test
+ end
+
+ context 'without user param' do
+ it_behaves_like 'jira configuration base checks'
+
+ context 'when jira connection is valid' do
+ let!(:jira_service) { create(:jira_service, project: project, active: true) }
+
+ it 'does not return any error' do
+ expect { subject }.not_to raise_error
+ end
+ end
+ end
+
+ context 'with user param provided' do
+ let_it_be(:user) { create(:user) }
+
+ let(:additional_params) { { user: user } }
+
+ context 'when user has permission to run import' do
+ before do
+ project.add_maintainer(user)
+ end
+
+ it_behaves_like 'jira configuration base checks'
+
+ context 'when jira service is configured' do
+ let!(:jira_service) { create(:jira_service, project: project, active: true) }
+
+ context 'when issues feature is disabled' do
+ let_it_be(:project, reload: true) { create(:project, :issues_disabled) }
+
+ it_behaves_like 'raise Jira import error', 'Cannot import because issues are not available in this project.'
+ end
+
+ context 'when everything is ok' do
+ it 'does not return any error' do
+ expect { subject }.not_to raise_error
+ end
+ end
+ end
+ end
+
+ context 'when user does not have permissions to run the import' do
+ before do
+ create(:jira_service, project: project, active: true)
+
+ project.add_developer(user)
+ end
+
+ it_behaves_like 'raise Jira import error', 'You do not have permissions to run the import.'
+ end
+ end
+ end
+
describe '.jira_issue_cache_key' do
it 'returns cache key for Jira issue imported to given project' do
- expect(described_class.jira_issue_cache_key(project_id, 'DEMO-123')).to eq("jira-import/items-mapper/#{project_id}/issues/DEMO-123")
+ expect(described_class.jira_item_cache_key(project_id, 'DEMO-123', :issues)).to eq("jira-import/items-mapper/#{project_id}/issues/DEMO-123")
end
end
@@ -44,6 +144,29 @@ describe Gitlab::JiraImport do
end
end
+ describe '.cache_users_mapping', :clean_gitlab_redis_cache do
+ let(:data) { { 'user1' => '456', 'user234' => '23' } }
+
+ it 'stores the data correctly' do
+ described_class.cache_users_mapping(project_id, data)
+
+ expect(Gitlab::Cache::Import::Caching.read("jira-import/items-mapper/#{project_id}/users/user1")).to eq('456')
+ expect(Gitlab::Cache::Import::Caching.read("jira-import/items-mapper/#{project_id}/users/user234")).to eq('23')
+ end
+ end
+
+ describe '.get_user_mapping', :clean_gitlab_redis_cache do
+ it 'reads the data correctly' do
+ Gitlab::Cache::Import::Caching.write("jira-import/items-mapper/#{project_id}/users/user-123", '456')
+
+ expect(described_class.get_user_mapping(project_id, 'user-123')).to eq(456)
+ end
+
+ it 'returns nil if value not found' do
+ expect(described_class.get_user_mapping(project_id, 'user-123')).to be_nil
+ end
+ end
+
describe '.store_issues_next_started_at', :clean_gitlab_redis_cache do
it 'stores nil value' do
described_class.store_issues_next_started_at(project_id, nil)
diff --git a/spec/lib/gitlab/kubernetes/helm/api_spec.rb b/spec/lib/gitlab/kubernetes/helm/api_spec.rb
index 1f925fd45af..0e4179d5887 100644
--- a/spec/lib/gitlab/kubernetes/helm/api_spec.rb
+++ b/spec/lib/gitlab/kubernetes/helm/api_spec.rb
@@ -17,7 +17,8 @@ describe Gitlab::Kubernetes::Helm::API do
name: application_name,
chart: 'chart-name',
rbac: rbac,
- files: files
+ files: files,
+ local_tiller_enabled: true
)
end
@@ -142,7 +143,7 @@ describe Gitlab::Kubernetes::Helm::API do
end
context 'with a service account' do
- let(:command) { Gitlab::Kubernetes::Helm::InitCommand.new(name: application_name, files: files, rbac: rbac) }
+ let(:command) { Gitlab::Kubernetes::Helm::InitCommand.new(name: application_name, files: files, rbac: rbac, local_tiller_enabled: true) }
context 'rbac-enabled cluster' do
let(:rbac) { true }
diff --git a/spec/lib/gitlab/kubernetes/helm/base_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/base_command_spec.rb
index 2a4a911cf38..f9bcb8abdb1 100644
--- a/spec/lib/gitlab/kubernetes/helm/base_command_spec.rb
+++ b/spec/lib/gitlab/kubernetes/helm/base_command_spec.rb
@@ -11,25 +11,14 @@ describe Gitlab::Kubernetes::Helm::BaseCommand do
let(:rbac) { false }
let(:test_class) do
- Class.new do
- include Gitlab::Kubernetes::Helm::BaseCommand
-
+ Class.new(Gitlab::Kubernetes::Helm::BaseCommand) do
def initialize(rbac)
- @rbac = rbac
- end
-
- def name
- "test-class-name"
- end
-
- def rbac?
- @rbac
- end
-
- def files
- {
- some: 'value'
- }
+ super(
+ name: 'test-class-name',
+ rbac: rbac,
+ files: { some: 'value' },
+ local_tiller_enabled: false
+ )
end
end
end
diff --git a/spec/lib/gitlab/kubernetes/helm/delete_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/delete_command_spec.rb
index 95d60c18d56..2bf8b294821 100644
--- a/spec/lib/gitlab/kubernetes/helm/delete_command_spec.rb
+++ b/spec/lib/gitlab/kubernetes/helm/delete_command_spec.rb
@@ -3,11 +3,12 @@
require 'spec_helper'
describe Gitlab::Kubernetes::Helm::DeleteCommand do
- subject(:delete_command) { described_class.new(name: app_name, rbac: rbac, files: files) }
+ subject(:delete_command) { described_class.new(name: app_name, rbac: rbac, files: files, local_tiller_enabled: local_tiller_enabled) }
let(:app_name) { 'app-name' }
let(:rbac) { true }
let(:files) { {} }
+ let(:local_tiller_enabled) { true }
it_behaves_like 'helm command generator' do
let(:commands) do
@@ -21,9 +22,7 @@ describe Gitlab::Kubernetes::Helm::DeleteCommand do
end
context 'tillerless feature disabled' do
- before do
- stub_feature_flags(managed_apps_local_tiller: false)
- end
+ let(:local_tiller_enabled) { false }
it_behaves_like 'helm command generator' do
let(:commands) do
diff --git a/spec/lib/gitlab/kubernetes/helm/init_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/init_command_spec.rb
index 05d9b63d12b..61b8eb30b42 100644
--- a/spec/lib/gitlab/kubernetes/helm/init_command_spec.rb
+++ b/spec/lib/gitlab/kubernetes/helm/init_command_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe Gitlab::Kubernetes::Helm::InitCommand do
- subject(:init_command) { described_class.new(name: application.name, files: files, rbac: rbac) }
+ subject(:init_command) { described_class.new(name: application.name, files: files, rbac: rbac, local_tiller_enabled: false) }
let(:application) { create(:clusters_applications_helm) }
let(:rbac) { false }
diff --git a/spec/lib/gitlab/kubernetes/helm/install_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/install_command_spec.rb
index abd29e97505..6fc91300f5b 100644
--- a/spec/lib/gitlab/kubernetes/helm/install_command_spec.rb
+++ b/spec/lib/gitlab/kubernetes/helm/install_command_spec.rb
@@ -12,7 +12,8 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
version: version,
repository: repository,
preinstall: preinstall,
- postinstall: postinstall
+ postinstall: postinstall,
+ local_tiller_enabled: local_tiller_enabled
)
end
@@ -22,6 +23,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
let(:version) { '1.2.3' }
let(:preinstall) { nil }
let(:postinstall) { nil }
+ let(:local_tiller_enabled) { true }
it_behaves_like 'helm command generator' do
let(:commands) do
@@ -51,9 +53,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
end
context 'tillerless feature disabled' do
- before do
- stub_feature_flags(managed_apps_local_tiller: false)
- end
+ let(:local_tiller_enabled) { false }
let(:tls_flags) do
<<~EOS.squish
diff --git a/spec/lib/gitlab/kubernetes/helm/patch_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/patch_command_spec.rb
index eee842fa7d6..8d965a25f84 100644
--- a/spec/lib/gitlab/kubernetes/helm/patch_command_spec.rb
+++ b/spec/lib/gitlab/kubernetes/helm/patch_command_spec.rb
@@ -7,6 +7,7 @@ describe Gitlab::Kubernetes::Helm::PatchCommand do
let(:repository) { 'https://repository.example.com' }
let(:rbac) { false }
let(:version) { '1.2.3' }
+ let(:local_tiller_enabled) { true }
subject(:patch_command) do
described_class.new(
@@ -15,14 +16,13 @@ describe Gitlab::Kubernetes::Helm::PatchCommand do
rbac: rbac,
files: files,
version: version,
- repository: repository
+ repository: repository,
+ local_tiller_enabled: local_tiller_enabled
)
end
context 'when local tiller feature is disabled' do
- before do
- stub_feature_flags(managed_apps_local_tiller: false)
- end
+ let(:local_tiller_enabled) { false }
let(:tls_flags) do
<<~EOS.squish
diff --git a/spec/lib/gitlab/kubernetes/helm/reset_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/reset_command_spec.rb
index 981bb4e4abf..3773c428713 100644
--- a/spec/lib/gitlab/kubernetes/helm/reset_command_spec.rb
+++ b/spec/lib/gitlab/kubernetes/helm/reset_command_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe Gitlab::Kubernetes::Helm::ResetCommand do
- subject(:reset_command) { described_class.new(name: name, rbac: rbac, files: files) }
+ subject(:reset_command) { described_class.new(name: name, rbac: rbac, files: files, local_tiller_enabled: false) }
let(:rbac) { true }
let(:name) { 'helm' }
diff --git a/spec/lib/gitlab/kubernetes/network_policy_spec.rb b/spec/lib/gitlab/kubernetes/network_policy_spec.rb
index f23d215a9a1..5a920d78436 100644
--- a/spec/lib/gitlab/kubernetes/network_policy_spec.rb
+++ b/spec/lib/gitlab/kubernetes/network_policy_spec.rb
@@ -39,28 +39,30 @@ describe Gitlab::Kubernetes::NetworkPolicy do
describe '.from_yaml' do
let(:manifest) do
- <<-POLICY
-apiVersion: networking.k8s.io/v1
-kind: NetworkPolicy
-metadata:
- name: example-name
- namespace: example-namespace
-spec:
- podSelector:
- matchLabels:
- role: db
- policyTypes:
- - Ingress
- ingress:
- - from:
- - namespaceSelector:
- matchLabels:
- project: myproject
+ <<~POLICY
+ apiVersion: networking.k8s.io/v1
+ kind: NetworkPolicy
+ metadata:
+ name: example-name
+ namespace: example-namespace
+ labels:
+ app: foo
+ spec:
+ podSelector:
+ matchLabels:
+ role: db
+ policyTypes:
+ - Ingress
+ ingress:
+ - from:
+ - namespaceSelector:
+ matchLabels:
+ project: myproject
POLICY
end
let(:resource) do
::Kubeclient::Resource.new(
- metadata: { name: name, namespace: namespace },
+ metadata: { name: name, namespace: namespace, labels: { app: 'foo' } },
spec: { podSelector: pod_selector, policyTypes: %w(Ingress), ingress: ingress, egress: nil }
)
end
@@ -83,20 +85,20 @@ spec:
context 'with manifest without metadata' do
let(:manifest) do
- <<-POLICY
-apiVersion: networking.k8s.io/v1
-kind: NetworkPolicy
-spec:
- podSelector:
- matchLabels:
- role: db
- policyTypes:
- - Ingress
- ingress:
- - from:
- - namespaceSelector:
- matchLabels:
- project: myproject
+ <<~POLICY
+ apiVersion: networking.k8s.io/v1
+ kind: NetworkPolicy
+ spec:
+ podSelector:
+ matchLabels:
+ role: db
+ policyTypes:
+ - Ingress
+ ingress:
+ - from:
+ - namespaceSelector:
+ matchLabels:
+ project: myproject
POLICY
end
@@ -105,12 +107,12 @@ spec:
context 'with manifest without spec' do
let(:manifest) do
- <<-POLICY
-apiVersion: networking.k8s.io/v1
-kind: NetworkPolicy
-metadata:
- name: example-name
- namespace: example-namespace
+ <<~POLICY
+ apiVersion: networking.k8s.io/v1
+ kind: NetworkPolicy
+ metadata:
+ name: example-name
+ namespace: example-namespace
POLICY
end
@@ -119,24 +121,24 @@ metadata:
context 'with disallowed class' do
let(:manifest) do
- <<-POLICY
-apiVersion: networking.k8s.io/v1
-kind: NetworkPolicy
-metadata:
- name: example-name
- namespace: example-namespace
- creationTimestamp: 2020-04-14T00:08:30Z
-spec:
- podSelector:
- matchLabels:
- role: db
- policyTypes:
- - Ingress
- ingress:
- - from:
- - namespaceSelector:
- matchLabels:
- project: myproject
+ <<~POLICY
+ apiVersion: networking.k8s.io/v1
+ kind: NetworkPolicy
+ metadata:
+ name: example-name
+ namespace: example-namespace
+ creationTimestamp: 2020-04-14T00:08:30Z
+ spec:
+ podSelector:
+ matchLabels:
+ role: db
+ policyTypes:
+ - Ingress
+ ingress:
+ - from:
+ - namespaceSelector:
+ matchLabels:
+ project: myproject
POLICY
end
@@ -147,13 +149,16 @@ spec:
describe '.from_resource' do
let(:resource) do
::Kubeclient::Resource.new(
- metadata: { name: name, namespace: namespace, creationTimestamp: '2020-04-14T00:08:30Z', resourceVersion: '4990' },
+ metadata: {
+ name: name, namespace: namespace, creationTimestamp: '2020-04-14T00:08:30Z',
+ labels: { app: 'foo' }, resourceVersion: '4990'
+ },
spec: { podSelector: pod_selector, policyTypes: %w(Ingress), ingress: ingress, egress: nil }
)
end
let(:generated_resource) do
::Kubeclient::Resource.new(
- metadata: { name: name, namespace: namespace },
+ metadata: { name: name, namespace: namespace, labels: { app: 'foo' } },
spec: { podSelector: pod_selector, policyTypes: %w(Ingress), ingress: ingress, egress: nil }
)
end
@@ -213,7 +218,9 @@ spec:
metadata: { name: name, namespace: namespace },
spec: { podSelector: pod_selector, policyTypes: %w(Ingress Egress), ingress: ingress, egress: egress }
}.deep_stringify_keys
- )
+ ),
+ is_autodevops: false,
+ is_enabled: true
}
end
@@ -221,4 +228,167 @@ spec:
it { is_expected.to eq(json_policy) }
end
+
+ describe '#autodevops?' do
+ subject { policy.autodevops? }
+
+ let(:chart) { nil }
+ let(:policy) do
+ described_class.new(
+ name: name,
+ namespace: namespace,
+ labels: { chart: chart },
+ pod_selector: pod_selector,
+ ingress: ingress
+ )
+ end
+
+ it { is_expected.to be false }
+
+ context 'with non-autodevops chart' do
+ let(:chart) { 'foo' }
+
+ it { is_expected.to be false }
+ end
+
+ context 'with autodevops chart' do
+ let(:chart) { 'auto-deploy-app-0.6.0' }
+
+ it { is_expected.to be true }
+ end
+ end
+
+ describe '#enabled?' do
+ subject { policy.enabled? }
+
+ let(:pod_selector) { nil }
+ let(:policy) do
+ described_class.new(
+ name: name,
+ namespace: namespace,
+ pod_selector: pod_selector,
+ ingress: ingress
+ )
+ end
+
+ it { is_expected.to be true }
+
+ context 'with empty pod_selector' do
+ let(:pod_selector) { {} }
+
+ it { is_expected.to be true }
+ end
+
+ context 'with nil matchLabels in pod_selector' do
+ let(:pod_selector) { { matchLabels: nil } }
+
+ it { is_expected.to be true }
+ end
+
+ context 'with empty matchLabels in pod_selector' do
+ let(:pod_selector) { { matchLabels: {} } }
+
+ it { is_expected.to be true }
+ end
+
+ context 'with disabled_by label in matchLabels in pod_selector' do
+ let(:pod_selector) do
+ { matchLabels: { Gitlab::Kubernetes::NetworkPolicy::DISABLED_BY_LABEL => 'gitlab' } }
+ end
+
+ it { is_expected.to be false }
+ end
+ end
+
+ describe '#enable' do
+ subject { policy.enabled? }
+
+ let(:pod_selector) { nil }
+ let(:policy) do
+ described_class.new(
+ name: name,
+ namespace: namespace,
+ pod_selector: pod_selector,
+ ingress: ingress
+ )
+ end
+
+ before do
+ policy.enable
+ end
+
+ it { is_expected.to be true }
+
+ context 'with empty pod_selector' do
+ let(:pod_selector) { {} }
+
+ it { is_expected.to be true }
+ end
+
+ context 'with nil matchLabels in pod_selector' do
+ let(:pod_selector) { { matchLabels: nil } }
+
+ it { is_expected.to be true }
+ end
+
+ context 'with empty matchLabels in pod_selector' do
+ let(:pod_selector) { { matchLabels: {} } }
+
+ it { is_expected.to be true }
+ end
+
+ context 'with disabled_by label in matchLabels in pod_selector' do
+ let(:pod_selector) do
+ { matchLabels: { Gitlab::Kubernetes::NetworkPolicy::DISABLED_BY_LABEL => 'gitlab' } }
+ end
+
+ it { is_expected.to be true }
+ end
+ end
+
+ describe '#disable' do
+ subject { policy.enabled? }
+
+ let(:pod_selector) { nil }
+ let(:policy) do
+ described_class.new(
+ name: name,
+ namespace: namespace,
+ pod_selector: pod_selector,
+ ingress: ingress
+ )
+ end
+
+ before do
+ policy.disable
+ end
+
+ it { is_expected.to be false }
+
+ context 'with empty pod_selector' do
+ let(:pod_selector) { {} }
+
+ it { is_expected.to be false }
+ end
+
+ context 'with nil matchLabels in pod_selector' do
+ let(:pod_selector) { { matchLabels: nil } }
+
+ it { is_expected.to be false }
+ end
+
+ context 'with empty matchLabels in pod_selector' do
+ let(:pod_selector) { { matchLabels: {} } }
+
+ it { is_expected.to be false }
+ end
+
+ context 'with disabled_by label in matchLabels in pod_selector' do
+ let(:pod_selector) do
+ { matchLabels: { Gitlab::Kubernetes::NetworkPolicy::DISABLED_BY_LABEL => 'gitlab' } }
+ end
+
+ it { is_expected.to be false }
+ end
+ end
end
diff --git a/spec/lib/gitlab/lfs_token_spec.rb b/spec/lib/gitlab/lfs_token_spec.rb
index b2fd7bdd307..58a3767b242 100644
--- a/spec/lib/gitlab/lfs_token_spec.rb
+++ b/spec/lib/gitlab/lfs_token_spec.rb
@@ -3,6 +3,13 @@
require 'spec_helper'
describe Gitlab::LfsToken, :clean_gitlab_redis_shared_state do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:deploy_key) { create(:deploy_key) }
+
+ let(:actor) { user }
+ let(:lfs_token) { described_class.new(actor) }
+
describe '#token' do
shared_examples 'a valid LFS token' do
it 'returns a computed token' do
@@ -10,14 +17,11 @@ describe Gitlab::LfsToken, :clean_gitlab_redis_shared_state do
expect(token).not_to be_nil
expect(token).to be_a String
- expect(described_class.new(actor).token_valid?(token)).to be_truthy
+ expect(described_class.new(actor).token_valid?(token)).to be true
end
end
context 'when the actor is a user' do
- let(:actor) { create(:user, username: 'test_user_lfs_1') }
- let(:lfs_token) { described_class.new(actor) }
-
it_behaves_like 'a valid LFS token'
it 'returns the correct username' do
@@ -30,9 +34,7 @@ describe Gitlab::LfsToken, :clean_gitlab_redis_shared_state do
end
context 'when the actor is a key' do
- let(:user) { create(:user, username: 'test_user_lfs_2') }
- let(:actor) { create(:key, user: user) }
- let(:lfs_token) { described_class.new(actor) }
+ let_it_be(:actor) { create(:key, user: user) }
it_behaves_like 'a valid LFS token'
@@ -46,10 +48,8 @@ describe Gitlab::LfsToken, :clean_gitlab_redis_shared_state do
end
context 'when the actor is a deploy key' do
+ let(:actor) { deploy_key }
let(:actor_id) { 1 }
- let(:actor) { create(:deploy_key) }
- let(:project) { create(:project) }
- let(:lfs_token) { described_class.new(actor) }
before do
allow(actor).to receive(:id).and_return(actor_id)
@@ -74,45 +74,45 @@ describe Gitlab::LfsToken, :clean_gitlab_redis_shared_state do
end
describe '#token_valid?' do
- let(:actor) { create(:user, username: 'test_user_lfs_1') }
- let(:lfs_token) { described_class.new(actor) }
-
context 'where the token is invalid' do
context "because it's junk" do
it 'returns false' do
- expect(lfs_token.token_valid?('junk')).to be_falsey
+ expect(lfs_token.token_valid?('junk')).to be false
end
end
context "because it's been fiddled with" do
it 'returns false' do
fiddled_token = lfs_token.token.tap { |token| token[0] = 'E' }
- expect(lfs_token.token_valid?(fiddled_token)).to be_falsey
+
+ expect(lfs_token.token_valid?(fiddled_token)).to be false
end
end
- context "because it was generated with a different secret" do
+ context 'because it was generated with a different secret' do
it 'returns false' do
different_actor = create(:user, username: 'test_user_lfs_2')
different_secret_token = described_class.new(different_actor).token
- expect(lfs_token.token_valid?(different_secret_token)).to be_falsey
+
+ expect(lfs_token.token_valid?(different_secret_token)).to be false
end
end
context "because it's expired" do
it 'returns false' do
expired_token = lfs_token.token
- # Needs to be at least 1860 seconds, because the default expiry is
- # 1800 seconds with an additional 60 second leeway.
- Timecop.freeze(Time.now + 1865) do
- expect(lfs_token.token_valid?(expired_token)).to be_falsey
+
+ # Needs to be at least LfsToken::DEFAULT_EXPIRE_TIME + 60 seconds
+ # in order to check whether it is valid 1 minute after it has expired
+ Timecop.freeze(Time.now + described_class::DEFAULT_EXPIRE_TIME + 60) do
+ expect(lfs_token.token_valid?(expired_token)).to be false
end
end
end
context 'where the token is valid' do
it 'returns true' do
- expect(lfs_token.token_valid?(lfs_token.token)).to be_truthy
+ expect(lfs_token.token_valid?(lfs_token.token)).to be true
end
end
@@ -121,7 +121,7 @@ describe Gitlab::LfsToken, :clean_gitlab_redis_shared_state do
let(:actor) { create(:user, :blocked) }
it 'returns false' do
- expect(lfs_token.token_valid?(lfs_token.token)).to be_falsey
+ expect(lfs_token.token_valid?(lfs_token.token)).to be false
end
end
@@ -129,7 +129,7 @@ describe Gitlab::LfsToken, :clean_gitlab_redis_shared_state do
let(:actor) { create(:user, password_expires_at: 1.minute.ago) }
it 'returns false' do
- expect(lfs_token.token_valid?(lfs_token.token)).to be_falsey
+ expect(lfs_token.token_valid?(lfs_token.token)).to be false
end
end
end
@@ -143,7 +143,7 @@ describe Gitlab::LfsToken, :clean_gitlab_redis_shared_state do
let(:actor) { create(:user, :blocked) }
it 'returns false' do
- expect(lfs_token.token_valid?(lfs_token.token)).to be_falsey
+ expect(lfs_token.token_valid?(lfs_token.token)).to be false
end
end
@@ -151,7 +151,7 @@ describe Gitlab::LfsToken, :clean_gitlab_redis_shared_state do
let(:actor) { create(:user, password_expires_at: 1.minute.ago) }
it 'returns true' do
- expect(lfs_token.token_valid?(lfs_token.token)).to be_truthy
+ expect(lfs_token.token_valid?(lfs_token.token)).to be true
end
end
end
@@ -159,27 +159,21 @@ describe Gitlab::LfsToken, :clean_gitlab_redis_shared_state do
end
describe '#deploy_key_pushable?' do
- let(:lfs_token) { described_class.new(actor) }
-
context 'when actor is not a DeployKey' do
- let(:actor) { create(:user) }
- let(:project) { create(:project) }
-
it 'returns false' do
- expect(lfs_token.deploy_key_pushable?(project)).to be_falsey
+ expect(lfs_token.deploy_key_pushable?(project)).to be false
end
end
context 'when actor is a DeployKey' do
- let(:deploy_keys_project) { create(:deploy_keys_project, can_push: can_push) }
- let(:project) { deploy_keys_project.project }
+ let(:deploy_keys_project) { create(:deploy_keys_project, project: project, can_push: can_push) }
let(:actor) { deploy_keys_project.deploy_key }
context 'but the DeployKey cannot push to the project' do
let(:can_push) { false }
it 'returns false' do
- expect(lfs_token.deploy_key_pushable?(project)).to be_falsey
+ expect(lfs_token.deploy_key_pushable?(project)).to be false
end
end
@@ -187,27 +181,23 @@ describe Gitlab::LfsToken, :clean_gitlab_redis_shared_state do
let(:can_push) { true }
it 'returns true' do
- expect(lfs_token.deploy_key_pushable?(project)).to be_truthy
+ expect(lfs_token.deploy_key_pushable?(project)).to be true
end
end
end
end
describe '#type' do
- let(:lfs_token) { described_class.new(actor) }
-
context 'when actor is not a User' do
- let(:actor) { create(:deploy_key) }
+ let(:actor) { deploy_key }
- it 'returns false' do
+ it 'returns :lfs_deploy_token type' do
expect(lfs_token.type).to eq(:lfs_deploy_token)
end
end
context 'when actor is a User' do
- let(:actor) { create(:user) }
-
- it 'returns false' do
+ it 'returns :lfs_token type' do
expect(lfs_token.type).to eq(:lfs_token)
end
end
@@ -215,8 +205,6 @@ describe Gitlab::LfsToken, :clean_gitlab_redis_shared_state do
describe '#authentication_payload' do
it 'returns a Hash designed for gitlab-shell' do
- actor = create(:user)
- lfs_token = described_class.new(actor)
repo_http_path = 'http://localhost/user/repo.git'
authentication_payload = lfs_token.authentication_payload(repo_http_path)
diff --git a/spec/lib/gitlab/lograge/custom_options_spec.rb b/spec/lib/gitlab/lograge/custom_options_spec.rb
index 7ae8baa31b5..ebf150d21ef 100644
--- a/spec/lib/gitlab/lograge/custom_options_spec.rb
+++ b/spec/lib/gitlab/lograge/custom_options_spec.rb
@@ -13,21 +13,16 @@ describe Gitlab::Lograge::CustomOptions do
}
end
- let(:event) do
- ActiveSupport::Notifications::Event.new(
- 'test',
- 1,
- 2,
- 'transaction_id',
- {
- params: params,
- user_id: 'test',
- cf_ray: SecureRandom.hex,
- cf_request_id: SecureRandom.hex,
- metadata: { 'meta.user' => 'jane.doe' }
- }
- )
+ let(:event_payload) do
+ {
+ params: params,
+ user_id: 'test',
+ cf_ray: SecureRandom.hex,
+ cf_request_id: SecureRandom.hex,
+ metadata: { 'meta.user' => 'jane.doe' }
+ }
end
+ let(:event) { ActiveSupport::Notifications::Event.new('test', 1, 2, 'transaction_id', event_payload) }
subject { described_class.call(event) }
@@ -49,6 +44,18 @@ describe Gitlab::Lograge::CustomOptions do
end
end
+ context 'with transaction' do
+ let(:transaction) { Gitlab::Metrics::WebTransaction.new({}) }
+
+ before do
+ allow(Gitlab::Metrics::Transaction).to receive(:current).and_return(transaction)
+ end
+
+ it 'adds db counters' do
+ expect(subject).to include(:db_count, :db_write_count, :db_cached_count)
+ end
+ end
+
it 'adds the user id' do
expect(subject[:user_id]).to eq('test')
end
@@ -63,19 +70,23 @@ describe Gitlab::Lograge::CustomOptions do
end
context 'when metadata is missing' do
- let(:event) do
- ActiveSupport::Notifications::Event.new(
- 'test',
- 1,
- 2,
- 'transaction_id',
- { params: {} }
- )
- end
+ let(:event_payload) { { params: {} } }
it 'does not break' do
expect { subject }.not_to raise_error
end
end
+
+ context 'when correlation_id is overriden' do
+ let(:correlation_id_key) { Labkit::Correlation::CorrelationId::LOG_KEY }
+
+ before do
+ event_payload[correlation_id_key] = '123456'
+ end
+
+ it 'sets the overriden value' do
+ expect(subject[correlation_id_key]).to eq('123456')
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/looping_batcher_spec.rb b/spec/lib/gitlab/looping_batcher_spec.rb
deleted file mode 100644
index b03e969c1e7..00000000000
--- a/spec/lib/gitlab/looping_batcher_spec.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe Gitlab::LoopingBatcher, :use_clean_rails_memory_store_caching do
- describe '#next_range!' do
- let(:model_class) { LfsObject }
- let(:key) { 'looping_batcher_spec' }
- let(:batch_size) { 2 }
-
- subject { described_class.new(model_class, key: key, batch_size: batch_size).next_range! }
-
- context 'when there are no records' do
- it { is_expected.to be_nil }
- end
-
- context 'when there are records' do
- let!(:records) { create_list(model_class.underscore, 3) }
-
- context 'when it has never been called before' do
- it { is_expected.to be_a Range }
-
- it 'starts from the beginning' do
- expect(subject.first).to eq(1)
- end
-
- it 'ends at a full batch' do
- expect(subject.last).to eq(records.second.id)
- end
-
- context 'when the batch size is greater than the number of records' do
- let(:batch_size) { 5 }
-
- it 'ends at the last ID' do
- expect(subject.last).to eq(records.last.id)
- end
- end
- end
-
- context 'when it was called before' do
- context 'when the previous batch included the end of the table' do
- before do
- described_class.new(model_class, key: key, batch_size: model_class.count).next_range!
- end
-
- it 'starts from the beginning' do
- expect(subject).to eq(1..records.second.id)
- end
- end
-
- context 'when the previous batch did not include the end of the table' do
- before do
- described_class.new(model_class, key: key, batch_size: model_class.count - 1).next_range!
- end
-
- it 'starts after the previous batch' do
- expect(subject).to eq(records.last.id..records.last.id)
- end
- end
-
- context 'if cache is cleared' do
- it 'starts from the beginning' do
- Rails.cache.clear
-
- expect(subject).to eq(1..records.second.id)
- end
- end
- end
- end
- end
-end
diff --git a/spec/lib/gitlab/metrics/dashboard/finder_spec.rb b/spec/lib/gitlab/metrics/dashboard/finder_spec.rb
index d772b0c7a5f..2703339d89c 100644
--- a/spec/lib/gitlab/metrics/dashboard/finder_spec.rb
+++ b/spec/lib/gitlab/metrics/dashboard/finder_spec.rb
@@ -142,7 +142,7 @@ describe Gitlab::Metrics::Dashboard::Finder, :use_clean_rails_memory_store_cachi
describe '.find_all_paths' do
let(:all_dashboard_paths) { described_class.find_all_paths(project) }
- let(:system_dashboard) { { path: system_dashboard_path, display_name: 'Default', default: true, system_dashboard: true } }
+ let(:system_dashboard) { { path: system_dashboard_path, display_name: 'Default dashboard', default: true, system_dashboard: true } }
it 'includes only the system dashboard by default' do
expect(all_dashboard_paths).to eq([system_dashboard])
@@ -163,7 +163,7 @@ describe Gitlab::Metrics::Dashboard::Finder, :use_clean_rails_memory_store_cachi
let(:self_monitoring_dashboard) do
{
path: self_monitoring_dashboard_path,
- display_name: 'Default',
+ display_name: 'Default dashboard',
default: true,
system_dashboard: false
}
diff --git a/spec/lib/gitlab/metrics/dashboard/processor_spec.rb b/spec/lib/gitlab/metrics/dashboard/processor_spec.rb
index b2fca0b5954..7250cefb9ff 100644
--- a/spec/lib/gitlab/metrics/dashboard/processor_spec.rb
+++ b/spec/lib/gitlab/metrics/dashboard/processor_spec.rb
@@ -16,7 +16,8 @@ describe Gitlab::Metrics::Dashboard::Processor do
Gitlab::Metrics::Dashboard::Stages::EndpointInserter,
Gitlab::Metrics::Dashboard::Stages::Sorter,
Gitlab::Metrics::Dashboard::Stages::AlertsInserter,
- Gitlab::Metrics::Dashboard::Stages::PanelIdsInserter
+ Gitlab::Metrics::Dashboard::Stages::PanelIdsInserter,
+ Gitlab::Metrics::Dashboard::Stages::UrlValidator
]
end
@@ -201,6 +202,27 @@ describe Gitlab::Metrics::Dashboard::Processor do
it_behaves_like 'errors with message', 'Each "metric" must define one of :query or :query_range'
end
+
+ describe 'validating links' do
+ context 'when the links contain a blocked url' do
+ let(:dashboard_yml_links) do
+ [{ 'url' => 'http://1.1.1.1.1' }, { 'url' => 'https://gitlab.com' }]
+ end
+
+ let(:expected) do
+ [{ url: '' }, { url: 'https://gitlab.com' }]
+ end
+
+ before do
+ stub_env('RSPEC_ALLOW_INVALID_URLS', 'false')
+ dashboard_yml['links'] = dashboard_yml_links
+ end
+
+ it 'replaces the blocked url with an empty string' do
+ expect(dashboard[:links]).to eq(expected)
+ end
+ end
+ end
end
private
diff --git a/spec/lib/gitlab/metrics/elasticsearch_rack_middleware_spec.rb b/spec/lib/gitlab/metrics/elasticsearch_rack_middleware_spec.rb
new file mode 100644
index 00000000000..305768ef060
--- /dev/null
+++ b/spec/lib/gitlab/metrics/elasticsearch_rack_middleware_spec.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Metrics::ElasticsearchRackMiddleware do
+ let(:app) { double(:app, call: 'app call result') }
+ let(:middleware) { described_class.new(app) }
+ let(:env) { {} }
+ let(:transaction) { Gitlab::Metrics::WebTransaction.new(env) }
+
+ describe '#call' do
+ let(:counter) { instance_double(Prometheus::Client::Counter, increment: nil) }
+ let(:histogram) { instance_double(Prometheus::Client::Histogram, observe: nil) }
+ let(:elasticsearch_query_time) { 0.1 }
+ let(:elasticsearch_requests_count) { 2 }
+
+ before do
+ allow(Gitlab::Instrumentation::ElasticsearchTransport).to receive(:query_time) { elasticsearch_query_time }
+ allow(Gitlab::Instrumentation::ElasticsearchTransport).to receive(:get_request_count) { elasticsearch_requests_count }
+
+ allow(Gitlab::Metrics).to receive(:counter)
+ .with(:http_elasticsearch_requests_total,
+ an_instance_of(String),
+ Gitlab::Metrics::Transaction::BASE_LABELS)
+ .and_return(counter)
+
+ allow(Gitlab::Metrics).to receive(:histogram)
+ .with(:http_elasticsearch_requests_duration_seconds,
+ an_instance_of(String),
+ Gitlab::Metrics::Transaction::BASE_LABELS,
+ described_class::HISTOGRAM_BUCKETS)
+ .and_return(histogram)
+
+ allow(Gitlab::Metrics).to receive(:current_transaction).and_return(transaction)
+ end
+
+ it 'calls the app' do
+ expect(middleware.call(env)).to eq('app call result')
+ end
+
+ it 'records elasticsearch metrics' do
+ expect(counter).to receive(:increment).with(transaction.labels, elasticsearch_requests_count)
+ expect(histogram).to receive(:observe).with(transaction.labels, elasticsearch_query_time)
+
+ middleware.call(env)
+ end
+
+ it 'records elasticsearch metrics if an error is raised' do
+ expect(counter).to receive(:increment).with(transaction.labels, elasticsearch_requests_count)
+ expect(histogram).to receive(:observe).with(transaction.labels, elasticsearch_query_time)
+
+ allow(app).to receive(:call).with(env).and_raise(StandardError)
+
+ expect { middleware.call(env) }.to raise_error(StandardError)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/metrics/method_call_spec.rb b/spec/lib/gitlab/metrics/method_call_spec.rb
index 229db67ec88..035d875258c 100644
--- a/spec/lib/gitlab/metrics/method_call_spec.rb
+++ b/spec/lib/gitlab/metrics/method_call_spec.rb
@@ -26,7 +26,7 @@ describe Gitlab::Metrics::MethodCall do
context 'prometheus instrumentation is enabled' do
before do
- Feature.get(:prometheus_metrics_method_instrumentation).enable
+ stub_feature_flags(prometheus_metrics_method_instrumentation: true)
end
around do |example|
@@ -50,7 +50,7 @@ describe Gitlab::Metrics::MethodCall do
context 'prometheus instrumentation is disabled' do
before do
- Feature.get(:prometheus_metrics_method_instrumentation).disable
+ stub_feature_flags(prometheus_metrics_method_instrumentation: false)
end
it 'observes using NullMetric' do
diff --git a/spec/lib/gitlab/metrics/methods_spec.rb b/spec/lib/gitlab/metrics/methods_spec.rb
index bca94deb1d8..5cf8db55142 100644
--- a/spec/lib/gitlab/metrics/methods_spec.rb
+++ b/spec/lib/gitlab/metrics/methods_spec.rb
@@ -104,7 +104,7 @@ describe Gitlab::Metrics::Methods do
context 'when feature is enabled' do
before do
- Feature.get(feature_name).enable
+ stub_feature_flags(feature_name => true)
end
it "initializes #{metric_type} metric" do
@@ -118,7 +118,7 @@ describe Gitlab::Metrics::Methods do
context 'when feature is disabled' do
before do
- Feature.get(feature_name).disable
+ stub_feature_flags(feature_name => false)
end
it "returns NullMetric" do
diff --git a/spec/lib/gitlab/metrics/redis_rack_middleware_spec.rb b/spec/lib/gitlab/metrics/redis_rack_middleware_spec.rb
new file mode 100644
index 00000000000..f2f36ccad20
--- /dev/null
+++ b/spec/lib/gitlab/metrics/redis_rack_middleware_spec.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Metrics::RedisRackMiddleware do
+ let(:app) { double(:app) }
+ let(:middleware) { described_class.new(app) }
+ let(:env) { {} }
+ let(:transaction) { Gitlab::Metrics::WebTransaction.new(env) }
+
+ before do
+ allow(app).to receive(:call).with(env).and_return('wub wub')
+ end
+
+ describe '#call' do
+ let(:counter) { double(Prometheus::Client::Counter, increment: nil) }
+ let(:histogram) { double(Prometheus::Client::Histogram, observe: nil) }
+ let(:redis_query_time) { 0.1 }
+ let(:redis_requests_count) { 2 }
+
+ before do
+ allow(Gitlab::Instrumentation::Redis).to receive(:query_time) { redis_query_time }
+ allow(Gitlab::Instrumentation::Redis).to receive(:get_request_count) { redis_requests_count }
+
+ allow(Gitlab::Metrics).to receive(:counter)
+ .with(:http_redis_requests_total,
+ an_instance_of(String),
+ Gitlab::Metrics::Transaction::BASE_LABELS)
+ .and_return(counter)
+
+ allow(Gitlab::Metrics).to receive(:histogram)
+ .with(:http_redis_requests_duration_seconds,
+ an_instance_of(String),
+ Gitlab::Metrics::Transaction::BASE_LABELS,
+ Gitlab::Instrumentation::Redis::QUERY_TIME_BUCKETS)
+ .and_return(histogram)
+
+ allow(Gitlab::Metrics).to receive(:current_transaction).and_return(transaction)
+ end
+
+ it 'calls the app' do
+ expect(middleware.call(env)).to eq('wub wub')
+ end
+
+ it 'records redis metrics' do
+ expect(counter).to receive(:increment).with(transaction.labels, redis_requests_count)
+ expect(histogram).to receive(:observe).with(transaction.labels, redis_query_time)
+
+ middleware.call(env)
+ end
+
+ it 'records redis metrics if an error is raised' do
+ expect(counter).to receive(:increment).with(transaction.labels, redis_requests_count)
+ expect(histogram).to receive(:observe).with(transaction.labels, redis_query_time)
+
+ allow(app).to receive(:call).with(env).and_raise(StandardError)
+
+ expect { middleware.call(env) }.to raise_error(StandardError)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/metrics/samplers/database_sampler_spec.rb b/spec/lib/gitlab/metrics/samplers/database_sampler_spec.rb
index fdf3b5bd045..087a0bfbac5 100644
--- a/spec/lib/gitlab/metrics/samplers/database_sampler_spec.rb
+++ b/spec/lib/gitlab/metrics/samplers/database_sampler_spec.rb
@@ -3,7 +3,17 @@
require 'spec_helper'
describe Gitlab::Metrics::Samplers::DatabaseSampler do
- subject { described_class.new(described_class::SAMPLING_INTERVAL_SECONDS) }
+ subject { described_class.new }
+
+ describe '#interval' do
+ it 'samples every five seconds by default' do
+ expect(subject.interval).to eq(5)
+ end
+
+ it 'samples at other intervals if requested' do
+ expect(described_class.new(11).interval).to eq(11)
+ end
+ end
describe '#sample' do
before do
diff --git a/spec/lib/gitlab/metrics/samplers/puma_sampler_spec.rb b/spec/lib/gitlab/metrics/samplers/puma_sampler_spec.rb
index 1097d26c320..df63f2ebe28 100644
--- a/spec/lib/gitlab/metrics/samplers/puma_sampler_spec.rb
+++ b/spec/lib/gitlab/metrics/samplers/puma_sampler_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe Gitlab::Metrics::Samplers::PumaSampler do
- subject { described_class.new(5) }
+ subject { described_class.new }
let(:null_metric) { double('null_metric', set: nil, observe: nil) }
@@ -11,6 +11,16 @@ describe Gitlab::Metrics::Samplers::PumaSampler do
allow(Gitlab::Metrics::NullMetric).to receive(:instance).and_return(null_metric)
end
+ describe '#interval' do
+ it 'samples every five seconds by default' do
+ expect(subject.interval).to eq(5)
+ end
+
+ it 'samples at other intervals if requested' do
+ expect(described_class.new(11).interval).to eq(11)
+ end
+ end
+
describe '#sample' do
before do
expect(subject).to receive(:puma_stats).and_return(puma_stats)
diff --git a/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb b/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb
index ead650a27f0..9fc8dd10922 100644
--- a/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb
+++ b/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe Gitlab::Metrics::Samplers::RubySampler do
- let(:sampler) { described_class.new(5) }
+ let(:sampler) { described_class.new }
let(:null_metric) { double('null_metric', set: nil, observe: nil) }
before do
@@ -18,6 +18,16 @@ describe Gitlab::Metrics::Samplers::RubySampler do
end
end
+ describe '#interval' do
+ it 'samples every sixty seconds by default' do
+ expect(subject.interval).to eq(60)
+ end
+
+ it 'samples at other intervals if requested' do
+ expect(described_class.new(11).interval).to eq(11)
+ end
+ end
+
describe '#sample' do
it 'adds a metric containing the process resident memory bytes' do
expect(Gitlab::Metrics::System).to receive(:memory_usage_rss).and_return(9000)
diff --git a/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb b/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb
index 67336cf83e6..ea9e8fa6795 100644
--- a/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb
+++ b/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb
@@ -10,17 +10,19 @@ describe Gitlab::Metrics::SidekiqMiddleware do
it 'tracks the transaction' do
worker = double(:worker, class: double(:class, name: 'TestWorker'))
- expect(Gitlab::Metrics::BackgroundTransaction).to receive(:new)
- .with(worker.class)
- .and_call_original
+ expect_next_instance_of(Gitlab::Metrics::BackgroundTransaction) do |transaction|
+ expect(transaction).to receive(:set).with(:sidekiq_queue_duration, instance_of(Float))
+ expect(transaction).to receive(:increment).with(:db_count, 1)
+ end
- expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:set)
- .with(:sidekiq_queue_duration, instance_of(Float))
+ middleware.call(worker, message, :test) do
+ ActiveRecord::Base.connection.execute('SELECT pg_sleep(0.1);')
+ end
- middleware.call(worker, message, :test) { nil }
+ expect(message).to include(:db_count, :db_write_count, :db_cached_count)
end
- it 'tracks the transaction (for messages without `enqueued_at`)' do
+ it 'tracks the transaction (for messages without `enqueued_at`)', :aggregate_failures do
worker = double(:worker, class: double(:class, name: 'TestWorker'))
expect(Gitlab::Metrics::BackgroundTransaction).to receive(:new)
@@ -33,7 +35,7 @@ describe Gitlab::Metrics::SidekiqMiddleware do
middleware.call(worker, {}, :test) { nil }
end
- it 'tracks any raised exceptions' do
+ it 'tracks any raised exceptions', :aggregate_failures do
worker = double(:worker, class: double(:class, name: 'TestWorker'))
expect_any_instance_of(Gitlab::Metrics::Transaction)
@@ -44,6 +46,8 @@ describe Gitlab::Metrics::SidekiqMiddleware do
expect { middleware.call(worker, message, :test) }
.to raise_error(RuntimeError)
+
+ expect(message).to include(:db_count, :db_write_count, :db_cached_count)
end
end
end
diff --git a/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb b/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb
index 1624cea8bda..a78d048908d 100644
--- a/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb
+++ b/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb
@@ -6,10 +6,15 @@ describe Gitlab::Metrics::Subscribers::ActiveRecord do
let(:env) { {} }
let(:transaction) { Gitlab::Metrics::WebTransaction.new(env) }
let(:subscriber) { described_class.new }
+ let(:payload) { { sql: 'SELECT * FROM users WHERE id = 10' } }
let(:event) do
- double(:event, duration: 2,
- payload: { sql: 'SELECT * FROM users WHERE id = 10' })
+ double(
+ :event,
+ name: 'sql.active_record',
+ duration: 2,
+ payload: payload
+ )
end
describe '#sql' do
@@ -23,6 +28,63 @@ describe Gitlab::Metrics::Subscribers::ActiveRecord do
end
describe 'with a current transaction' do
+ shared_examples 'read only query' do
+ it 'increments only db count value' do
+ allow(subscriber).to receive(:current_transaction)
+ .at_least(:once)
+ .and_return(transaction)
+
+ expect(transaction).to receive(:increment)
+ .with(:db_count, 1)
+
+ expect(transaction).not_to receive(:increment)
+ .with(:db_cached_count, 1)
+
+ expect(transaction).not_to receive(:increment)
+ .with(:db_write_count, 1)
+
+ subscriber.sql(event)
+ end
+ end
+
+ shared_examples 'write query' do
+ it 'increments db_write_count and db_count value' do
+ expect(subscriber).to receive(:current_transaction)
+ .at_least(:once)
+ .and_return(transaction)
+
+ expect(transaction).to receive(:increment)
+ .with(:db_count, 1)
+
+ expect(transaction).not_to receive(:increment)
+ .with(:db_cached_count, 1)
+
+ expect(transaction).to receive(:increment)
+ .with(:db_write_count, 1)
+
+ subscriber.sql(event)
+ end
+ end
+
+ shared_examples 'cached query' do
+ it 'increments db_cached_count and db_count value' do
+ expect(subscriber).to receive(:current_transaction)
+ .at_least(:once)
+ .and_return(transaction)
+
+ expect(transaction).to receive(:increment)
+ .with(:db_count, 1)
+
+ expect(transaction).to receive(:increment)
+ .with(:db_cached_count, 1)
+
+ expect(transaction).not_to receive(:increment)
+ .with(:db_write_count, 1)
+
+ subscriber.sql(event)
+ end
+ end
+
it 'observes sql_duration metric' do
expect(subscriber).to receive(:current_transaction)
.at_least(:once)
@@ -31,18 +93,66 @@ describe Gitlab::Metrics::Subscribers::ActiveRecord do
subscriber.sql(event)
end
- it 'increments the :sql_duration value' do
- expect(subscriber).to receive(:current_transaction)
- .at_least(:once)
- .and_return(transaction)
+ it_behaves_like 'read only query'
+
+ context 'with select for update sql event' do
+ let(:payload) { { sql: 'SELECT * FROM users WHERE id = 10 FOR UPDATE' } }
- expect(transaction).to receive(:increment)
- .with(:sql_duration, 2, false)
+ it_behaves_like 'write query'
+ end
- expect(transaction).to receive(:increment)
- .with(:sql_count, 1, false)
+ context 'with common table expression' do
+ context 'with insert' do
+ let(:payload) { { sql: 'WITH archived_rows AS (SELECT * FROM users WHERE archived = true) INSERT INTO products_log SELECT * FROM archived_rows' } }
- subscriber.sql(event)
+ it_behaves_like 'write query'
+ end
+
+ context 'with only select' do
+ let(:payload) { { sql: 'WITH active_milestones AS (SELECT COUNT(*), state FROM milestones GROUP BY state) SELECT * FROM active_milestones' } }
+
+ it_behaves_like 'read only query'
+ end
+ end
+
+ context 'with delete sql event' do
+ let(:payload) { { sql: 'DELETE FROM users where id = 10' } }
+
+ it_behaves_like 'write query'
+ end
+
+ context 'with insert sql event' do
+ let(:payload) { { sql: 'INSERT INTO project_ci_cd_settings (project_id) SELECT id FROM projects' } }
+
+ it_behaves_like 'write query'
+ end
+
+ context 'with update sql event' do
+ let(:payload) { { sql: 'UPDATE users SET admin = true WHERE id = 10' } }
+
+ it_behaves_like 'write query'
+ end
+
+ context 'with cached payload ' do
+ let(:payload) do
+ {
+ sql: 'SELECT * FROM users WHERE id = 10',
+ cached: true
+ }
+ end
+
+ it_behaves_like 'cached query'
+ end
+
+ context 'with cached payload name' do
+ let(:payload) do
+ {
+ sql: 'SELECT * FROM users WHERE id = 10',
+ name: 'CACHE'
+ }
+ end
+
+ it_behaves_like 'cached query'
end
context 'events are internal to Rails or irrelevant' do
diff --git a/spec/lib/gitlab/metrics/transaction_spec.rb b/spec/lib/gitlab/metrics/transaction_spec.rb
index cf46fa3e91c..693ec3cb7e7 100644
--- a/spec/lib/gitlab/metrics/transaction_spec.rb
+++ b/spec/lib/gitlab/metrics/transaction_spec.rb
@@ -65,18 +65,16 @@ describe Gitlab::Metrics::Transaction do
describe '#add_event' do
let(:prometheus_metric) { instance_double(Prometheus::Client::Counter, increment: nil) }
- before do
- allow(described_class).to receive(:transaction_metric).and_return(prometheus_metric)
- end
-
it 'adds a metric' do
expect(prometheus_metric).to receive(:increment)
+ expect(described_class).to receive(:fetch_metric).with(:counter, :gitlab_transaction_event_meow_total).and_return(prometheus_metric)
transaction.add_event(:meow)
end
it 'allows tracking of custom tags' do
expect(prometheus_metric).to receive(:increment).with(hash_including(animal: "dog"))
+ expect(described_class).to receive(:fetch_metric).with(:counter, :gitlab_transaction_event_bau_total).and_return(prometheus_metric)
transaction.add_event(:bau, animal: 'dog')
end
@@ -84,6 +82,7 @@ describe Gitlab::Metrics::Transaction do
context 'with sensitive tags' do
before do
transaction.add_event(:baubau, **sensitive_tags.merge(sane: 'yes'))
+ allow(described_class).to receive(:transaction_metric).and_return(prometheus_metric)
end
it 'filters tags' do
@@ -93,4 +92,37 @@ describe Gitlab::Metrics::Transaction do
end
end
end
+
+ describe '#increment' do
+ let(:prometheus_metric) { instance_double(Prometheus::Client::Counter, increment: nil) }
+
+ it 'adds a metric' do
+ expect(prometheus_metric).to receive(:increment).with(hash_including(:action, :controller), 1)
+ expect(described_class).to receive(:fetch_metric).with(:counter, :gitlab_transaction_meow_total).and_return(prometheus_metric)
+
+ transaction.increment(:meow, 1)
+ end
+ end
+
+ describe '#set' do
+ let(:prometheus_metric) { instance_double(Prometheus::Client::Gauge, set: nil) }
+
+ it 'adds a metric' do
+ expect(prometheus_metric).to receive(:set).with(hash_including(:action, :controller), 1)
+ expect(described_class).to receive(:fetch_metric).with(:gauge, :gitlab_transaction_meow_total).and_return(prometheus_metric)
+
+ transaction.set(:meow, 1)
+ end
+ end
+
+ describe '#get' do
+ let(:prometheus_metric) { instance_double(Prometheus::Client::Counter, get: nil) }
+
+ it 'gets a metric' do
+ expect(described_class).to receive(:fetch_metric).with(:counter, :gitlab_transaction_meow_total).and_return(prometheus_metric)
+ expect(prometheus_metric).to receive(:get)
+
+ transaction.get(:meow, :counter)
+ end
+ end
end
diff --git a/spec/lib/gitlab/middleware/handle_ip_spoof_attack_error_spec.rb b/spec/lib/gitlab/middleware/handle_ip_spoof_attack_error_spec.rb
new file mode 100644
index 00000000000..ccfc5e93887
--- /dev/null
+++ b/spec/lib/gitlab/middleware/handle_ip_spoof_attack_error_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Middleware::HandleIpSpoofAttackError do
+ let(:spoof_error) { ActionDispatch::RemoteIp::IpSpoofAttackError.new('sensitive') }
+ let(:standard_error) { StandardError.new('error') }
+ let(:app) { -> (env) { env.is_a?(Exception) ? raise(env) : env } }
+
+ subject(:middleware) { described_class.new(app) }
+
+ it 'passes through the response from a valid upstream' do
+ expect(middleware.call(:response)).to eq(:response)
+ end
+
+ it 'translates an ActionDispatch::IpSpoofAttackError to a 400 response' do
+ expect(middleware.call(spoof_error))
+ .to eq([400, { 'Content-Type' => 'text/plain' }, ['Bad Request']])
+ end
+
+ it 'passes through the exception raised by an invalid upstream' do
+ expect { middleware.call(standard_error) }.to raise_error(standard_error)
+ end
+end
diff --git a/spec/lib/gitlab/monitor/demo_projects_spec.rb b/spec/lib/gitlab/monitor/demo_projects_spec.rb
new file mode 100644
index 00000000000..92024a3f9c1
--- /dev/null
+++ b/spec/lib/gitlab/monitor/demo_projects_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Monitor::DemoProjects do
+ describe '#primary_keys' do
+ subject { described_class.primary_keys }
+
+ it 'fetches primary_keys when on gitlab.com' do
+ allow(Gitlab).to receive(:com?).and_return(true)
+ allow(Gitlab).to receive(:staging?).and_return(false)
+
+ expect(subject).to eq(Gitlab::Monitor::DemoProjects::DOT_COM_IDS)
+ end
+
+ it 'fetches primary_keys when on staging' do
+ allow(Gitlab).to receive(:com?).and_return(true)
+ allow(Gitlab).to receive(:staging?).and_return(true)
+
+ expect(subject).to eq(Gitlab::Monitor::DemoProjects::STAGING_IDS)
+ end
+
+ it 'fetches all keys when in the dev or test env' do
+ project = create(:project)
+ allow(Gitlab).to receive(:dev_or_test_env?).and_return(true)
+
+ expect(subject).to eq([project.id])
+ end
+
+ it 'falls back on empty array' do
+ stub_config_setting(url: 'https://helloworld')
+ allow(Gitlab).to receive(:dev_or_test_env?).and_return(false)
+
+ expect(subject).to eq([])
+ end
+ end
+end
diff --git a/spec/lib/gitlab/no_cache_headers_spec.rb b/spec/lib/gitlab/no_cache_headers_spec.rb
index f011b55006e..c7a73f0e2dc 100644
--- a/spec/lib/gitlab/no_cache_headers_spec.rb
+++ b/spec/lib/gitlab/no_cache_headers_spec.rb
@@ -3,8 +3,11 @@
require 'spec_helper'
describe Gitlab::NoCacheHeaders do
- class NoCacheTester
- include Gitlab::NoCacheHeaders
+ before do
+ stub_const('NoCacheTester', Class.new)
+ NoCacheTester.class_eval do
+ include Gitlab::NoCacheHeaders
+ end
end
describe "#no_cache_headers" do
diff --git a/spec/lib/gitlab/pagination/keyset/request_context_spec.rb b/spec/lib/gitlab/pagination/keyset/request_context_spec.rb
index 6cd5ccc3c19..d6d5340f38b 100644
--- a/spec/lib/gitlab/pagination/keyset/request_context_spec.rb
+++ b/spec/lib/gitlab/pagination/keyset/request_context_spec.rb
@@ -60,9 +60,7 @@ describe Gitlab::Pagination::Keyset::RequestContext do
it 'sets Links header with same host/path as the original request' do
orig_uri = URI.parse(request_context.request.url)
- expect(request_context).to receive(:header) do |name, header|
- expect(name).to eq('Links')
-
+ expect(request_context).to receive(:header).twice do |name, header|
first_link, _ = /<([^>]+)>; rel="next"/.match(header).captures
uri = URI.parse(first_link)
@@ -77,9 +75,7 @@ describe Gitlab::Pagination::Keyset::RequestContext do
it 'sets Links header with a link to the next page' do
orig_uri = URI.parse(request_context.request.url)
- expect(request_context).to receive(:header) do |name, header|
- expect(name).to eq('Links')
-
+ expect(request_context).to receive(:header).twice do |name, header|
first_link, _ = /<([^>]+)>; rel="next"/.match(header).captures
query = CGI.parse(URI.parse(first_link).query)
@@ -97,9 +93,7 @@ describe Gitlab::Pagination::Keyset::RequestContext do
it 'sets Links header with a link to the next page' do
orig_uri = URI.parse(request_context.request.url)
- expect(request_context).to receive(:header) do |name, header|
- expect(name).to eq('Links')
-
+ expect(request_context).to receive(:header).twice do |name, header|
first_link, _ = /<([^>]+)>; rel="next"/.match(header).captures
query = CGI.parse(URI.parse(first_link).query)
diff --git a/spec/lib/gitlab/patch/action_dispatch_journey_formatter_spec.rb b/spec/lib/gitlab/patch/action_dispatch_journey_formatter_spec.rb
index 5f0e1f40231..b1c7f73489d 100644
--- a/spec/lib/gitlab/patch/action_dispatch_journey_formatter_spec.rb
+++ b/spec/lib/gitlab/patch/action_dispatch_journey_formatter_spec.rb
@@ -7,7 +7,7 @@ describe Gitlab::Patch::ActionDispatchJourneyFormatter do
let(:project) { create(:project, namespace: group) }
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
let(:url) { Gitlab::Routing.url_helpers.project_pipeline_url(project, pipeline) }
- let(:expected_path) { "#{project.full_path}/pipelines/#{pipeline.id}" }
+ let(:expected_path) { "#{project.full_path}/-/pipelines/#{pipeline.id}" }
context 'custom implementation of #missing_keys' do
before do
diff --git a/spec/lib/gitlab/path_regex_spec.rb b/spec/lib/gitlab/path_regex_spec.rb
index 50b045c6aad..ac506c49100 100644
--- a/spec/lib/gitlab/path_regex_spec.rb
+++ b/spec/lib/gitlab/path_regex_spec.rb
@@ -3,6 +3,11 @@
require 'spec_helper'
describe Gitlab::PathRegex do
+ let(:starting_with_namespace) { %r{^/\*namespace_id/:(project_)?id} }
+ let(:non_param_parts) { %r{[^:*][a-z\-_/]*} }
+ let(:any_other_path_part) { %r{[a-z\-_/:]*} }
+ let(:wildcard_segment) { /\*/ }
+
# Pass in a full path to remove the format segment:
# `/ci/lint(.:format)` -> `/ci/lint`
def without_format(path)
@@ -14,7 +19,7 @@ describe Gitlab::PathRegex do
# `/*namespace_id/:project_id/builds/artifacts/*ref_name_and_path`
# -> 'builds/artifacts'
def path_before_wildcard(path)
- path = path.gsub(STARTING_WITH_NAMESPACE, "")
+ path = path.gsub(starting_with_namespace, "")
path_segments = path.split('/').reject(&:empty?)
wildcard_index = path_segments.index { |segment| parameter?(segment) }
@@ -121,13 +126,9 @@ describe Gitlab::PathRegex do
# - Followed by one or more path-parts not starting with `:` or `*`
# - Followed by a path-part that includes a wildcard parameter `*`
# At the time of writing these routes match: http://rubular.com/r/Rv2pDE5Dvw
- STARTING_WITH_NAMESPACE = %r{^/\*namespace_id/:(project_)?id}.freeze
- NON_PARAM_PARTS = %r{[^:*][a-z\-_/]*}.freeze
- ANY_OTHER_PATH_PART = %r{[a-z\-_/:]*}.freeze
- WILDCARD_SEGMENT = /\*/.freeze
let(:namespaced_wildcard_routes) do
routes_without_format.select do |p|
- p =~ %r{#{STARTING_WITH_NAMESPACE}/#{NON_PARAM_PARTS}/#{ANY_OTHER_PATH_PART}#{WILDCARD_SEGMENT}}
+ p =~ %r{#{starting_with_namespace}/#{non_param_parts}/#{any_other_path_part}#{wildcard_segment}}
end
end
@@ -145,16 +146,14 @@ describe Gitlab::PathRegex do
end.uniq
end
- STARTING_WITH_GROUP = %r{^/groups/\*(group_)?id/}.freeze
+ let(:starting_with_group) { %r{^/groups/\*(group_)?id/} }
let(:group_routes) do
- routes_without_format.select do |path|
- path =~ STARTING_WITH_GROUP
- end
+ routes_without_format.grep(starting_with_group)
end
let(:paths_after_group_id) do
group_routes.map do |route|
- route.gsub(STARTING_WITH_GROUP, '').split('/').first
+ route.gsub(starting_with_group, '').split('/').first
end.uniq
end
diff --git a/spec/lib/gitlab/phabricator_import/cache/map_spec.rb b/spec/lib/gitlab/phabricator_import/cache/map_spec.rb
index b2a63e4f026..4935ef1bd90 100644
--- a/spec/lib/gitlab/phabricator_import/cache/map_spec.rb
+++ b/spec/lib/gitlab/phabricator_import/cache/map_spec.rb
@@ -66,7 +66,7 @@ describe Gitlab::PhabricatorImport::Cache::Map, :clean_gitlab_redis_cache do
end
expect(set_data).to eq({ classname: 'Issue', database_id: issue.id.to_s })
- expect(ttl).to be_within(1.second).of(StuckImportJobsWorker::IMPORT_JOBS_EXPIRATION)
+ expect(ttl).to be_within(1.second).of(Gitlab::Import::StuckImportJob::IMPORT_JOBS_EXPIRATION)
end
end
diff --git a/spec/lib/gitlab/process_memory_cache/helper_spec.rb b/spec/lib/gitlab/process_memory_cache/helper_spec.rb
new file mode 100644
index 00000000000..890642b1d5e
--- /dev/null
+++ b/spec/lib/gitlab/process_memory_cache/helper_spec.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::ProcessMemoryCache::Helper, :use_clean_rails_memory_store_caching do
+ let(:minimal_test_class) do
+ Class.new do
+ include Gitlab::ProcessMemoryCache::Helper
+
+ def cached_content
+ fetch_memory_cache(:cached_content_instance_key) { expensive_computation }
+ end
+
+ def clear_cached_content
+ invalidate_memory_cache(:cached_content_instance_key)
+ end
+ end
+ end
+
+ before do
+ stub_const("MinimalTestClass", minimal_test_class)
+ end
+
+ subject { MinimalTestClass.new }
+
+ describe '.fetch_memory_cache' do
+ it 'memoizes the result' do
+ is_expected.to receive(:expensive_computation).once.and_return(1)
+
+ 2.times do
+ expect(subject.cached_content).to eq(1)
+ end
+ end
+
+ it 'resets the cache when the shared key is missing', :aggregate_failures do
+ expect(Rails.cache).to receive(:read).with(:cached_content_instance_key).twice.and_return(nil)
+ is_expected.to receive(:expensive_computation).thrice.and_return(1, 2, 3)
+
+ 3.times do |index|
+ expect(subject.cached_content).to eq(index + 1)
+ end
+ end
+ end
+
+ describe '.invalidate_memory_cache' do
+ it 'invalidates the cache' do
+ is_expected.to receive(:expensive_computation).twice.and_return(1, 2)
+
+ expect { subject.clear_cached_content }.to change { subject.cached_content }
+ end
+ end
+end
diff --git a/spec/lib/gitlab/project_search_results_spec.rb b/spec/lib/gitlab/project_search_results_spec.rb
index 64f80b5d736..aa52949ed60 100644
--- a/spec/lib/gitlab/project_search_results_spec.rb
+++ b/spec/lib/gitlab/project_search_results_spec.rb
@@ -34,7 +34,7 @@ describe Gitlab::ProjectSearchResults do
'blobs' | :limited_blobs_count | max_limited_count
'notes' | :limited_notes_count | max_limited_count
'wiki_blobs' | :wiki_blobs_count | '1234'
- 'commits' | :commits_count | '1234'
+ 'commits' | :commits_count | max_limited_count
'projects' | :limited_projects_count | max_limited_count
'unknown' | nil | nil
end
@@ -386,6 +386,19 @@ describe Gitlab::ProjectSearchResults do
end
end
+ describe '#commits_count' do
+ let(:project) { create(:project, :public, :repository) }
+
+ it 'limits the number of commits requested' do
+ expect(project.repository)
+ .to receive(:find_commits_by_message)
+ .with(anything, anything, anything, described_class::COUNT_LIMIT)
+ .and_call_original
+
+ described_class.new(user, project, '.').commits_count
+ end
+ end
+
# Examples for commit access level test
#
# params:
@@ -452,6 +465,54 @@ describe Gitlab::ProjectSearchResults do
end
describe 'commit search' do
+ context 'pagination' do
+ let(:project) { create(:project, :public, :repository) }
+
+ it 'returns the correct results for each page' do
+ expect(results_page(1)).to contain_exactly(commit('b83d6e391c22777fca1ed3012fce84f633d7fed0'))
+
+ expect(results_page(2)).to contain_exactly(commit('498214de67004b1da3d820901307bed2a68a8ef6'))
+
+ expect(results_page(3)).to contain_exactly(commit('1b12f15a11fc6e62177bef08f47bc7b5ce50b141'))
+ end
+
+ it 'returns the correct number of pages' do
+ expect(results_page(1).total_pages).to eq(project.repository.commit_count)
+ end
+
+ context 'limiting requested commits' do
+ context 'on page 1' do
+ it "limits to #{described_class::COUNT_LIMIT}" do
+ expect(project.repository)
+ .to receive(:find_commits_by_message)
+ .with(anything, anything, anything, described_class::COUNT_LIMIT)
+ .and_call_original
+
+ results_page(1)
+ end
+ end
+
+ context 'on subsequent pages' do
+ it "limits to #{described_class::COUNT_LIMIT} plus page offset" do
+ expect(project.repository)
+ .to receive(:find_commits_by_message)
+ .with(anything, anything, anything, described_class::COUNT_LIMIT + 1)
+ .and_call_original
+
+ results_page(2)
+ end
+ end
+ end
+
+ def results_page(page)
+ described_class.new(user, project, '.').objects('commits', per_page: 1, page: page)
+ end
+
+ def commit(hash)
+ project.repository.commit(hash)
+ end
+ end
+
context 'by commit message' do
let(:project) { create(:project, :public, :repository) }
let(:commit) { project.repository.commit('59e29889be61e6e0e5e223bfa9ac2721d31605b8') }
@@ -469,6 +530,18 @@ describe Gitlab::ProjectSearchResults do
expect(commits).to be_empty
end
+ context 'when repository_ref is provided' do
+ let(:message) { 'Feature added' }
+ let(:repository_ref) { 'feature' }
+
+ it 'searches in the specified ref' do
+ commits = described_class.new(user, project, message, repository_ref).objects('commits')
+
+ # This commit is unique to the feature branch
+ expect(commits).to contain_exactly(project.repository.commit('0b4bc9a49b562e85de7cc9e834518ea6828729b9'))
+ end
+ end
+
it_behaves_like 'access restricted commits' do
let(:search_phrase) { message }
let(:commit) { project.repository.commit('59e29889be61e6e0e5e223bfa9ac2721d31605b8') }
diff --git a/spec/lib/gitlab/project_template_spec.rb b/spec/lib/gitlab/project_template_spec.rb
index aa18a1a843c..35f79042df0 100644
--- a/spec/lib/gitlab/project_template_spec.rb
+++ b/spec/lib/gitlab/project_template_spec.rb
@@ -4,34 +4,17 @@ require 'spec_helper'
describe Gitlab::ProjectTemplate do
describe '.all' do
- it 'returns a all templates' do
- expected = [
- described_class.new('rails', 'Ruby on Rails', 'Includes an MVC structure, .gitignore, Gemfile, and more great stuff', 'https://gitlab.com/gitlab-org/project-templates/rails'),
- described_class.new('spring', 'Spring', 'Includes an MVC structure, .gitignore, Gemfile, and more great stuff', 'https://gitlab.com/gitlab-org/project-templates/spring'),
- described_class.new('express', 'NodeJS Express', 'Includes an MVC structure, .gitignore, Gemfile, and more great stuff', 'https://gitlab.com/gitlab-org/project-templates/express'),
- described_class.new('iosswift', 'iOS (Swift)', 'A ready-to-go template for use with iOS Swift apps.', 'https://gitlab.com/gitlab-org/project-templates/iosswift'),
- described_class.new('dotnetcore', '.NET Core', 'A .NET Core console application template, customizable for any .NET Core project', 'https://gitlab.com/gitlab-org/project-templates/dotnetcore'),
- described_class.new('android', 'Android', 'A ready-to-go template for use with Android apps.', 'https://gitlab.com/gitlab-org/project-templates/android'),
- described_class.new('gomicro', 'Go Micro', 'Go Micro is a framework for micro service development.', 'https://gitlab.com/gitlab-org/project-templates/go-micro'),
- described_class.new('gatsby', 'Pages/Gatsby', 'Everything you need to get started using a Gatsby site.', 'https://gitlab.com/pages/gatsby'),
- described_class.new('hugo', 'Pages/Hugo', 'Everything you need to get started using a Hugo Pages site.', 'https://gitlab.com/pages/hugo'),
- described_class.new('jekyll', 'Pages/Jekyll', 'Everything you need to get started using a Jekyll Pages site.', 'https://gitlab.com/pages/jekyll'),
- described_class.new('plainhtml', 'Pages/Plain HTML', 'Everything you need to get started using a plain HTML Pages site.', 'https://gitlab.com/pages/plain-html'),
- described_class.new('gitbook', 'Pages/GitBook', 'Everything you need to get started using a GitBook Pages site.', 'https://gitlab.com/pages/gitbook'),
- described_class.new('hexo', 'Pages/Hexo', 'Everything you need to get started using a Hexo Pages site.', 'https://gitlab.com/pages/hexo'),
- described_class.new('sse_middleman', 'Static Site Editor/Middleman', _('Middleman project with Static Site Editor support'), 'https://gitlab.com/gitlab-org/project-templates/static-site-editor-middleman'),
- described_class.new('nfhugo', 'Netlify/Hugo', _('A Hugo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features.'), 'https://gitlab.com/pages/nfhugo'),
- described_class.new('nfjekyll', 'Netlify/Jekyll', _('A Jekyll site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features.'), 'https://gitlab.com/pages/nfjekyll'),
- described_class.new('nfplainhtml', 'Netlify/Plain HTML', _('A plain HTML site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features.'), 'https://gitlab.com/pages/nfplain-html'),
- described_class.new('nfgitbook', 'Netlify/GitBook', _('A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features.'), 'https://gitlab.com/pages/nfgitbook'),
- described_class.new('nfhexo', 'Netlify/Hexo', _('A Hexo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features.'), 'https://gitlab.com/pages/nfhexo'),
- described_class.new('salesforcedx', 'SalesforceDX', _('A project boilerplate for Salesforce App development with Salesforce Developer tools.'), 'https://gitlab.com/gitlab-org/project-templates/salesforcedx'),
- described_class.new('serverless_framework', 'Serverless Framework/JS', _('A basic page and serverless function that uses AWS Lambda, AWS API Gateway, and GitLab Pages'), 'https://gitlab.com/gitlab-org/project-templates/serverless-framework', 'illustrations/logos/serverless_framework.svg'),
- described_class.new('cluster_management', 'GitLab Cluster Management', _('An example project for managing Kubernetes clusters integrated with GitLab.'), 'https://gitlab.com/gitlab-org/project-templates/cluster-management')
+ it 'returns all templates' do
+ expected = %w[
+ rails spring express iosswift dotnetcore android
+ gomicro gatsby hugo jekyll plainhtml gitbook
+ hexo sse_middleman nfhugo nfjekyll nfplainhtml
+ nfgitbook nfhexo salesforcedx serverless_framework
+ cluster_management
]
expect(described_class.all).to be_an(Array)
- expect(described_class.all).to eq(expected)
+ expect(described_class.all.map(&:name)).to match_array(expected)
end
end
diff --git a/spec/lib/gitlab/prometheus/query_variables_spec.rb b/spec/lib/gitlab/prometheus/query_variables_spec.rb
index d8f8a2b7e7c..7dfa4de35d6 100644
--- a/spec/lib/gitlab/prometheus/query_variables_spec.rb
+++ b/spec/lib/gitlab/prometheus/query_variables_spec.rb
@@ -7,8 +7,9 @@ describe Gitlab::Prometheus::QueryVariables do
let(:project) { environment.project }
let(:environment) { create(:environment) }
let(:slug) { environment.slug }
+ let(:params) { {} }
- subject { described_class.call(environment) }
+ subject { described_class.call(environment, params) }
it { is_expected.to include(ci_environment_slug: slug) }
it { is_expected.to include(ci_project_name: project.name) }
@@ -53,5 +54,42 @@ describe Gitlab::Prometheus::QueryVariables do
it { is_expected.to include(kube_namespace: kube_namespace) }
end
end
+
+ context '__range' do
+ context 'when start_time and end_time are present' do
+ let(:params) do
+ {
+ start_time: Time.rfc3339('2020-05-29T07:23:05.008Z'),
+ end_time: Time.rfc3339('2020-05-29T15:23:05.008Z')
+ }
+ end
+
+ it { is_expected.to include(__range: "#{8.hours.to_i}s") }
+ end
+
+ context 'when start_time and end_time are not present' do
+ it { is_expected.to include(__range: nil) }
+ end
+
+ context 'when end_time is not present' do
+ let(:params) do
+ {
+ start_time: Time.rfc3339('2020-05-29T07:23:05.008Z')
+ }
+ end
+
+ it { is_expected.to include(__range: nil) }
+ end
+
+ context 'when start_time is not present' do
+ let(:params) do
+ {
+ end_time: Time.rfc3339('2020-05-29T07:23:05.008Z')
+ }
+ end
+
+ it { is_expected.to include(__range: nil) }
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/prometheus_client_spec.rb b/spec/lib/gitlab/prometheus_client_spec.rb
index 4ff53b50a50..749192e5795 100644
--- a/spec/lib/gitlab/prometheus_client_spec.rb
+++ b/spec/lib/gitlab/prometheus_client_spec.rb
@@ -171,6 +171,58 @@ describe Gitlab::PrometheusClient do
end
end
+ describe '#aggregate' do
+ let(:query) { 'avg (metric) by (job)' }
+ let(:prometheus_response) do
+ {
+ "status": "success",
+ "data": {
+ "resultType": "vector",
+ "result": [
+ {
+ "metric": { "job" => "gitlab-rails" },
+ "value": [1488758662.506, "1"]
+ },
+ {
+ "metric": { "job" => "gitlab-sidekiq" },
+ "value": [1488758662.506, "2"]
+ }
+ ]
+ }
+ }
+ end
+ let(:query_url) { prometheus_query_with_time_url(query, Time.now.utc) }
+
+ around do |example|
+ Timecop.freeze { example.run }
+ end
+
+ context 'when request returns vector results' do
+ it 'returns data from the API call grouped by labels' do
+ req_stub = stub_prometheus_request(query_url, body: prometheus_response)
+
+ expect(subject.aggregate(query)).to eq({
+ { "job" => "gitlab-rails" } => 1,
+ { "job" => "gitlab-sidekiq" } => 2
+ })
+ expect(req_stub).to have_been_requested
+ end
+ end
+
+ context 'when request returns no data' do
+ it 'returns {}' do
+ req_stub = stub_prometheus_request(query_url, body: prometheus_empty_body('vector'))
+
+ expect(subject.aggregate(query)).to eq({})
+ expect(req_stub).to have_been_requested
+ end
+ end
+
+ it_behaves_like 'failure response' do
+ let(:execute_query) { subject.aggregate(query) }
+ end
+ end
+
describe '#series' do
let(:query_url) { prometheus_series_url('series_name', 'other_service') }
diff --git a/spec/lib/gitlab/redis/wrapper_spec.rb b/spec/lib/gitlab/redis/wrapper_spec.rb
index e4cc42130db..51a36eb062c 100644
--- a/spec/lib/gitlab/redis/wrapper_spec.rb
+++ b/spec/lib/gitlab/redis/wrapper_spec.rb
@@ -18,7 +18,21 @@ describe Gitlab::Redis::Wrapper do
let(:config_env_variable_url) {"TEST_GITLAB_REDIS_URL"}
let(:class_redis_url) { Gitlab::Redis::Wrapper::DEFAULT_REDIS_URL }
- include_examples "redis_shared_examples"
+ include_examples "redis_shared_examples" do
+ before do
+ allow(described_class).to receive(:instrumentation_class) do
+ ::Gitlab::Instrumentation::Redis::Cache
+ end
+ end
+ end
+
+ describe '.instrumentation_class' do
+ it 'raises a NotImplementedError' do
+ expect(described_class).to receive(:instrumentation_class).and_call_original
+
+ expect { described_class.instrumentation_class }.to raise_error(NotImplementedError)
+ end
+ end
describe '.config_file_path' do
it 'returns the absolute path to the configuration file' do
diff --git a/spec/lib/gitlab/reference_extractor_spec.rb b/spec/lib/gitlab/reference_extractor_spec.rb
index 8ea591c6f74..dd16f3c6035 100644
--- a/spec/lib/gitlab/reference_extractor_spec.rb
+++ b/spec/lib/gitlab/reference_extractor_spec.rb
@@ -204,7 +204,7 @@ describe Gitlab::ReferenceExtractor do
issue]
end
- it 'returns only Jira issues if the internal one does not exists' do
+ it 'returns only Jira issues if the internal one does not exist' do
subject.analyze("JIRA-123 and FOOBAR-4567 and ##{non_existing_record_iid}")
expect(subject.issues).to eq [ExternalIssue.new('JIRA-123', project),
ExternalIssue.new('FOOBAR-4567', project)]
@@ -236,7 +236,7 @@ describe Gitlab::ReferenceExtractor do
expect(subject.issues).to eq([issue])
end
- it 'does not return any issue if the internal one does not exists' do
+ it 'does not return any issue if the internal one does not exist' do
subject.analyze("JIRA-123 and FOOBAR-4567 and #999")
expect(subject.issues).to be_empty
end
@@ -296,7 +296,7 @@ describe Gitlab::ReferenceExtractor do
end
it 'returns all supported prefixes' do
- expect(prefixes.keys.uniq).to match_array(%w(@ # ~ % ! $ &))
+ expect(prefixes.keys.uniq).to match_array(%w(@ # ~ % ! $ & *iteration:))
end
it 'does not allow one prefix for multiple referables if not allowed specificly' do
diff --git a/spec/lib/gitlab/regex_spec.rb b/spec/lib/gitlab/regex_spec.rb
index 9e596400904..2f220272651 100644
--- a/spec/lib/gitlab/regex_spec.rb
+++ b/spec/lib/gitlab/regex_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require 'spec_helper'
+require 'fast_spec_helper'
describe Gitlab::Regex do
shared_examples_for 'project/group name regex' do
@@ -163,4 +163,136 @@ describe Gitlab::Regex do
it { is_expected.not_to match('-foo-') }
it { is_expected.not_to match('foo/bar') }
end
+
+ describe '.conan_file_name_regex' do
+ subject { described_class.conan_file_name_regex }
+
+ it { is_expected.to match('conanfile.py') }
+ it { is_expected.to match('conan_package.tgz') }
+ it { is_expected.not_to match('foo.txt') }
+ it { is_expected.not_to match('!!()()') }
+ end
+
+ describe '.conan_package_reference_regex' do
+ subject { described_class.conan_package_reference_regex }
+
+ it { is_expected.to match('123456789') }
+ it { is_expected.to match('asdf1234') }
+ it { is_expected.not_to match('@foo') }
+ it { is_expected.not_to match('0/pack+age/1@1/0') }
+ it { is_expected.not_to match('!!()()') }
+ end
+
+ describe '.conan_revision_regex' do
+ subject { described_class.conan_revision_regex }
+
+ it { is_expected.to match('0') }
+ it { is_expected.not_to match('foo') }
+ it { is_expected.not_to match('!!()()') }
+ end
+
+ describe '.conan_recipe_component_regex' do
+ subject { described_class.conan_recipe_component_regex }
+
+ let(:fifty_one_characters) { 'f_a' * 17}
+
+ it { is_expected.to match('foobar') }
+ it { is_expected.to match('foo_bar') }
+ it { is_expected.to match('foo+bar') }
+ it { is_expected.to match('_foo+bar-baz+1.0') }
+ it { is_expected.to match('1.0.0') }
+ it { is_expected.not_to match('-foo_bar') }
+ it { is_expected.not_to match('+foo_bar') }
+ it { is_expected.not_to match('.foo_bar') }
+ it { is_expected.not_to match('foo@bar') }
+ it { is_expected.not_to match('foo/bar') }
+ it { is_expected.not_to match('!!()()') }
+ it { is_expected.not_to match(fifty_one_characters) }
+ end
+
+ describe '.package_name_regex' do
+ subject { described_class.package_name_regex }
+
+ it { is_expected.to match('123') }
+ it { is_expected.to match('foo') }
+ it { is_expected.to match('foo/bar') }
+ it { is_expected.to match('@foo/bar') }
+ it { is_expected.to match('com/mycompany/app/my-app') }
+ it { is_expected.to match('my-package/1.0.0@my+project+path/beta') }
+ it { is_expected.not_to match('my-package/1.0.0@@@@@my+project+path/beta') }
+ it { is_expected.not_to match('$foo/bar') }
+ it { is_expected.not_to match('@foo/@/bar') }
+ it { is_expected.not_to match('@@foo/bar') }
+ it { is_expected.not_to match('my package name') }
+ it { is_expected.not_to match('!!()()') }
+ it { is_expected.not_to match("..\n..\foo") }
+ end
+
+ describe '.maven_file_name_regex' do
+ subject { described_class.maven_file_name_regex }
+
+ it { is_expected.to match('123') }
+ it { is_expected.to match('foo') }
+ it { is_expected.to match('foo+bar-2_0.pom') }
+ it { is_expected.to match('foo.bar.baz-2.0-20190901.47283-1.jar') }
+ it { is_expected.to match('maven-metadata.xml') }
+ it { is_expected.to match('1.0-SNAPSHOT') }
+ it { is_expected.not_to match('../../foo') }
+ it { is_expected.not_to match('..\..\foo') }
+ it { is_expected.not_to match('%2f%2e%2e%2f%2essh%2fauthorized_keys') }
+ it { is_expected.not_to match('$foo/bar') }
+ it { is_expected.not_to match('my file name') }
+ it { is_expected.not_to match('!!()()') }
+ end
+
+ describe '.maven_path_regex' do
+ subject { described_class.maven_path_regex }
+
+ it { is_expected.to match('123') }
+ it { is_expected.to match('foo') }
+ it { is_expected.to match('foo/bar') }
+ it { is_expected.to match('@foo/bar') }
+ it { is_expected.to match('com/mycompany/app/my-app') }
+ it { is_expected.to match('com/mycompany/app/my-app/1.0-SNAPSHOT') }
+ it { is_expected.to match('com/mycompany/app/my-app/1.0-SNAPSHOT+debian64') }
+ it { is_expected.not_to match('com/mycompany/app/my+app/1.0-SNAPSHOT') }
+ it { is_expected.not_to match('$foo/bar') }
+ it { is_expected.not_to match('@foo/@/bar') }
+ it { is_expected.not_to match('my package name') }
+ it { is_expected.not_to match('!!()()') }
+ end
+
+ describe '.semver_regex' do
+ subject { described_class.semver_regex }
+
+ it { is_expected.to match('1.2.3') }
+ it { is_expected.to match('1.2.3-beta') }
+ it { is_expected.to match('1.2.3-alpha.3') }
+ it { is_expected.not_to match('1') }
+ it { is_expected.not_to match('1.2') }
+ it { is_expected.not_to match('1./2.3') }
+ it { is_expected.not_to match('../../../../../1.2.3') }
+ it { is_expected.not_to match('%2e%2e%2f1.2.3') }
+ end
+
+ describe '.go_package_regex' do
+ subject { described_class.go_package_regex }
+
+ it { is_expected.to match('example.com') }
+ it { is_expected.to match('example.com/foo') }
+ it { is_expected.to match('example.com/foo/bar') }
+ it { is_expected.to match('example.com/foo/bar/baz') }
+ it { is_expected.to match('tl.dr.foo.bar.baz') }
+ end
+
+ describe '.unbounded_semver_regex' do
+ subject { described_class.unbounded_semver_regex }
+
+ it { is_expected.to match('1.2.3') }
+ it { is_expected.to match('1.2.3-beta') }
+ it { is_expected.to match('1.2.3-alpha.3') }
+ it { is_expected.not_to match('1') }
+ it { is_expected.not_to match('1.2') }
+ it { is_expected.not_to match('1./2.3') }
+ end
end
diff --git a/spec/lib/gitlab/routing_spec.rb b/spec/lib/gitlab/routing_spec.rb
index 965564cb83b..5446d6559fe 100644
--- a/spec/lib/gitlab/routing_spec.rb
+++ b/spec/lib/gitlab/routing_spec.rb
@@ -22,4 +22,25 @@ describe Gitlab::Routing do
expect(subject).to respond_to(:namespace_project_path)
end
end
+
+ describe Gitlab::Routing::LegacyRedirector do
+ subject { described_class.new(:wikis) }
+
+ let(:request) { double(:request, path: path, query_string: '') }
+ let(:path) { '/gitlab-org/gitlab-test/wikis/home' }
+
+ it 'returns "-" scoped url' do
+ expect(subject.call({}, request)).to eq('/gitlab-org/gitlab-test/-/wikis/home')
+ end
+
+ context 'invalid uri characters' do
+ let(:path) { '/gitlab-org/gitlab-test/wikis/home[' }
+
+ it 'raises error' do
+ expect do
+ subject.call({}, request)
+ end.to raise_error(ActionController::RoutingError)
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/rugged_instrumentation_spec.rb b/spec/lib/gitlab/rugged_instrumentation_spec.rb
index 64c0ce1b65e..d6f3fb9be55 100644
--- a/spec/lib/gitlab/rugged_instrumentation_spec.rb
+++ b/spec/lib/gitlab/rugged_instrumentation_spec.rb
@@ -7,10 +7,10 @@ describe Gitlab::RuggedInstrumentation, :request_store do
describe '.query_time' do
it 'increments query times' do
- subject.query_time += 0.451
- subject.query_time += 0.322
+ subject.add_query_time(0.4510004)
+ subject.add_query_time(0.3220004)
- expect(subject.query_time).to be_within(0.001).of(0.773)
+ expect(subject.query_time).to eq(0.773001)
expect(subject.query_time_ms).to eq(773.0)
end
end
diff --git a/spec/lib/gitlab/search_context/builder_spec.rb b/spec/lib/gitlab/search_context/builder_spec.rb
new file mode 100644
index 00000000000..1707b54b273
--- /dev/null
+++ b/spec/lib/gitlab/search_context/builder_spec.rb
@@ -0,0 +1,152 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::SearchContext::Builder, type: :controller do
+ controller(ApplicationController) { }
+
+ subject(:builder) { described_class.new(controller.view_context) }
+
+ shared_examples "has a fluid interface" do
+ it { is_expected.to be_instance_of(described_class) }
+ end
+
+ def expected_project_metadata(project)
+ return {} if project.nil?
+
+ a_hash_including(project_path: project.path,
+ name: project.name,
+ issues_path: a_string_including("/issues"),
+ mr_path: a_string_including("/merge_requests"),
+ issues_disabled: !project.issues_enabled?)
+ end
+
+ def expected_group_metadata(group)
+ return {} if group.nil?
+
+ a_hash_including(group_path: group.path,
+ name: group.name,
+ issues_path: a_string_including("/issues"),
+ mr_path: a_string_including("/merge_requests"))
+ end
+
+ def expected_search_url(project, group)
+ if project
+ search_path(project_id: project.id)
+ elsif group
+ search_path(group_id: group.id)
+ else
+ search_path
+ end
+ end
+
+ def be_search_context(project: nil, group: nil, snippets: [], ref: nil)
+ group = project ? project.group : group
+ snippets.compact!
+ ref = ref
+
+ have_attributes(
+ project: project,
+ group: group,
+ ref: ref,
+ snippets: snippets,
+ project_metadata: expected_project_metadata(project),
+ group_metadata: expected_group_metadata(group),
+ search_url: expected_search_url(project, group)
+ )
+ end
+
+ describe '#with_project' do
+ let(:project) { create(:project) }
+
+ subject { builder.with_project(project) }
+
+ it_behaves_like "has a fluid interface"
+
+ describe '#build!' do
+ subject(:context) { builder.with_project(project).build! }
+
+ context 'when a project is not owned by a group' do
+ it { is_expected.to be_for_project }
+ it { is_expected.to be_search_context(project: project) }
+ end
+
+ context 'when a project is owned by a group' do
+ let(:project) { create(:project, group: create(:group)) }
+
+ it 'delegates to `#with_group`' do
+ expect(builder).to receive(:with_group).with(project.group)
+ expect(context).to be
+ end
+
+ it { is_expected.to be_search_context(project: project, group: project.group) }
+ end
+ end
+ end
+
+ describe '#with_snippet' do
+ context 'when there is a single snippet' do
+ let(:snippet) { create(:snippet) }
+
+ subject { builder.with_snippet(snippet) }
+
+ it_behaves_like "has a fluid interface"
+
+ describe '#build!' do
+ subject(:context) { builder.with_snippet(snippet).build! }
+
+ it { is_expected.to be_for_snippet }
+ it { is_expected.to be_search_context(snippets: [snippet]) }
+ end
+ end
+
+ context 'when there are multiple snippets' do
+ let(:snippets) { create_list(:snippet, 3) }
+
+ describe '#build!' do
+ subject(:context) do
+ snippets.each(&builder.method(:with_snippet))
+ builder.build!
+ end
+
+ it { is_expected.to be_for_snippet }
+ it { is_expected.to be_search_context(snippets: snippets) }
+ end
+ end
+ end
+
+ describe '#with_group' do
+ let(:group) { create(:group) }
+
+ subject { builder.with_group(group) }
+
+ it_behaves_like "has a fluid interface"
+
+ describe '#build!' do
+ subject(:context) { builder.with_group(group).build! }
+
+ it { is_expected.to be_for_group }
+ it { is_expected.to be_search_context(group: group) }
+ end
+ end
+
+ describe '#with_ref' do
+ let(:ref) { Gitlab::Git::EMPTY_TREE_ID }
+
+ subject { builder.with_ref(ref) }
+
+ it_behaves_like "has a fluid interface"
+
+ describe '#build!' do
+ subject(:context) { builder.with_ref(ref).build! }
+
+ it { is_expected.to be_search_context(ref: ref) }
+ end
+ end
+
+ describe '#build!' do
+ subject(:context) { builder.build! }
+
+ it { is_expected.to be_a(Gitlab::SearchContext) }
+ end
+end
diff --git a/spec/lib/gitlab/search_context/controller_concern_spec.rb b/spec/lib/gitlab/search_context/controller_concern_spec.rb
new file mode 100644
index 00000000000..16784cafb76
--- /dev/null
+++ b/spec/lib/gitlab/search_context/controller_concern_spec.rb
@@ -0,0 +1,82 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::SearchContext::ControllerConcern, type: :controller do
+ controller(ApplicationController) do
+ include Gitlab::SearchContext::ControllerConcern
+ end
+
+ let(:project) { nil }
+ let(:group) { nil }
+ let(:snippet) { nil }
+ let(:snippets) { [] }
+ let(:ref) { nil }
+
+ let(:builder) { Gitlab::SearchContext::Builder.new(controller.view_context) }
+
+ subject(:search_context) { controller.search_context }
+
+ def weak_assign(ivar, value)
+ return if value.nil?
+
+ controller.instance_variable_set(ivar.to_sym, value)
+ end
+
+ before do
+ weak_assign(:@project, project)
+ weak_assign(:@group, group)
+ weak_assign(:@ref, ref)
+ weak_assign(:@snippet, snippet)
+ weak_assign(:@snippets, snippets)
+
+ allow(Gitlab::SearchContext::Builder).to receive(:new).and_return(builder)
+ end
+
+ shared_examples 'has the proper context' do
+ it :aggregate_failures do
+ expected_group = project ? project.group : group
+ expected_snippets = [snippet, *snippets].compact
+
+ expect(builder).to receive(:with_project).with(project).and_call_original if project
+ expect(builder).to receive(:with_group).with(expected_group).and_call_original if expected_group
+ expect(builder).to receive(:with_ref).with(ref).and_call_original if ref
+ expected_snippets.each do |snippet|
+ expect(builder).to receive(:with_snippet).with(snippet).and_call_original
+ end
+
+ is_expected.to be_a(Gitlab::SearchContext)
+ end
+ end
+
+ context 'exposing @project' do
+ let(:project) { create(:project) }
+
+ it_behaves_like 'has the proper context'
+
+ context 'when the project is owned by a group' do
+ let(:project) { create(:project, group: create(:group)) }
+
+ it_behaves_like 'has the proper context'
+ end
+ end
+
+ context 'exposing @group' do
+ let(:group) { create(:group) }
+
+ it_behaves_like 'has the proper context'
+ end
+
+ context 'exposing @snippet, @snippets' do
+ let(:snippet) { create(:snippet) }
+ let(:snippets) { create_list(:snippet, 3) }
+
+ it_behaves_like 'has the proper context'
+ end
+
+ context 'exposing @ref' do
+ let(:ref) { Gitlab::Git::EMPTY_TREE_ID }
+
+ it_behaves_like 'has the proper context'
+ end
+end
diff --git a/spec/lib/gitlab/sidekiq_config/cli_methods_spec.rb b/spec/lib/gitlab/sidekiq_config/cli_methods_spec.rb
index 80e8da58f23..7a8aba2d396 100644
--- a/spec/lib/gitlab/sidekiq_config/cli_methods_spec.rb
+++ b/spec/lib/gitlab/sidekiq_config/cli_methods_spec.rb
@@ -76,7 +76,12 @@ describe Gitlab::SidekiqConfig::CliMethods do
describe '.expand_queues' do
let(:worker_queues) do
- ['cronjob:stuck_import_jobs', 'cronjob:stuck_merge_jobs', 'post_receive']
+ [
+ 'cronjob:import_stuck_project_import_jobs',
+ 'cronjob:jira_import_stuck_jira_import_jobs',
+ 'cronjob:stuck_merge_jobs',
+ 'post_receive'
+ ]
end
it 'defaults the value of the second argument to .worker_queues' do
@@ -88,12 +93,22 @@ describe Gitlab::SidekiqConfig::CliMethods do
allow(described_class).to receive(:worker_queues).and_return(worker_queues)
expect(described_class.expand_queues(['cronjob']))
- .to contain_exactly('cronjob', 'cronjob:stuck_import_jobs', 'cronjob:stuck_merge_jobs')
+ .to contain_exactly(
+ 'cronjob',
+ 'cronjob:import_stuck_project_import_jobs',
+ 'cronjob:jira_import_stuck_jira_import_jobs',
+ 'cronjob:stuck_merge_jobs'
+ )
end
it 'expands queue namespaces to concrete queue names' do
expect(described_class.expand_queues(['cronjob'], worker_queues))
- .to contain_exactly('cronjob', 'cronjob:stuck_import_jobs', 'cronjob:stuck_merge_jobs')
+ .to contain_exactly(
+ 'cronjob',
+ 'cronjob:import_stuck_project_import_jobs',
+ 'cronjob:jira_import_stuck_jira_import_jobs',
+ 'cronjob:stuck_merge_jobs'
+ )
end
it 'lets concrete queue names pass through' do
@@ -117,28 +132,32 @@ describe Gitlab::SidekiqConfig::CliMethods do
feature_category: :category_a,
has_external_dependencies: false,
urgency: :low,
- resource_boundary: :cpu
+ resource_boundary: :cpu,
+ tags: [:no_disk_io, :git_access]
},
{
name: 'a:2',
feature_category: :category_a,
has_external_dependencies: false,
urgency: :high,
- resource_boundary: :none
+ resource_boundary: :none,
+ tags: [:git_access]
},
{
name: 'b',
feature_category: :category_b,
has_external_dependencies: true,
urgency: :high,
- resource_boundary: :memory
+ resource_boundary: :memory,
+ tags: [:no_disk_io]
},
{
name: 'c',
feature_category: :category_c,
has_external_dependencies: false,
urgency: :throttled,
- resource_boundary: :memory
+ resource_boundary: :memory,
+ tags: []
}
]
end
@@ -177,6 +196,18 @@ describe Gitlab::SidekiqConfig::CliMethods do
'resource_boundary=memory|resource_boundary=cpu' | %w(a b c)
'resource_boundary!=memory,cpu' | %w(a:2)
+ # tags
+ 'tags=no_disk_io' | %w(a b)
+ 'tags=no_disk_io,git_access' | %w(a a:2 b)
+ 'tags=no_disk_io|tags=git_access' | %w(a a:2 b)
+ 'tags=no_disk_io&tags=git_access' | %w(a)
+ 'tags!=no_disk_io' | %w(a:2 c)
+ 'tags!=no_disk_io,git_access' | %w(c)
+ 'tags=unknown_tag' | []
+ 'tags!=no_disk_io' | %w(a:2 c)
+ 'tags!=no_disk_io,git_access' | %w(c)
+ 'tags!=unknown_tag' | %w(a a:2 b c)
+
# combinations
'feature_category=category_a&urgency=high' | %w(a:2)
'feature_category=category_a&urgency=high|feature_category=category_c' | %w(a:2 c)
diff --git a/spec/lib/gitlab/sidekiq_config/worker_spec.rb b/spec/lib/gitlab/sidekiq_config/worker_spec.rb
index 817755e3507..00343a0264d 100644
--- a/spec/lib/gitlab/sidekiq_config/worker_spec.rb
+++ b/spec/lib/gitlab/sidekiq_config/worker_spec.rb
@@ -13,7 +13,8 @@ describe Gitlab::SidekiqConfig::Worker do
get_worker_resource_boundary: attributes[:resource_boundary],
get_urgency: attributes[:urgency],
worker_has_external_dependencies?: attributes[:has_external_dependencies],
- idempotent?: attributes[:idempotent]
+ idempotent?: attributes[:idempotent],
+ get_tags: attributes[:tags]
)
described_class.new(inner_worker, ee: false)
@@ -91,7 +92,8 @@ describe Gitlab::SidekiqConfig::Worker do
urgency: :low,
resource_boundary: :memory,
weight: 2,
- idempotent: true
+ idempotent: true,
+ tags: []
}
attributes_b = {
@@ -100,7 +102,8 @@ describe Gitlab::SidekiqConfig::Worker do
urgency: :high,
resource_boundary: :unknown,
weight: 3,
- idempotent: false
+ idempotent: false,
+ tags: [:no_disk_io]
}
worker_a = create_worker(queue: 'a', **attributes_a)
diff --git a/spec/lib/gitlab/sidekiq_config_spec.rb b/spec/lib/gitlab/sidekiq_config_spec.rb
index 85de1d029c3..66744d07aaa 100644
--- a/spec/lib/gitlab/sidekiq_config_spec.rb
+++ b/spec/lib/gitlab/sidekiq_config_spec.rb
@@ -18,7 +18,8 @@ describe Gitlab::SidekiqConfig do
expect(queues).to include('post_receive')
expect(queues).to include('merge')
- expect(queues).to include('cronjob:stuck_import_jobs')
+ expect(queues).to include('cronjob:import_stuck_project_import_jobs')
+ expect(queues).to include('cronjob:jira_import_stuck_jira_import_jobs')
expect(queues).to include('mailers')
expect(queues).to include('default')
end
diff --git a/spec/lib/gitlab/sidekiq_logging/json_formatter_spec.rb b/spec/lib/gitlab/sidekiq_logging/json_formatter_spec.rb
index 283140d7fdf..10354147cf9 100644
--- a/spec/lib/gitlab/sidekiq_logging/json_formatter_spec.rb
+++ b/spec/lib/gitlab/sidekiq_logging/json_formatter_spec.rb
@@ -14,6 +14,7 @@ describe Gitlab::SidekiqLogging::JSONFormatter do
let(:hash_input) do
{
foo: 1,
+ 'class' => 'PostReceive',
'bar' => 'test',
'created_at' => timestamp,
'enqueued_at' => timestamp,
@@ -42,21 +43,47 @@ describe Gitlab::SidekiqLogging::JSONFormatter do
expect(subject).to eq(expected_output)
end
- context 'when the job args are bigger than the maximum allowed' do
- it 'keeps args from the front until they exceed the limit' do
- half_limit = Gitlab::Utils::LogLimitedArray::MAXIMUM_ARRAY_LENGTH / 2
- hash_input['args'] = [1, 2, 'a' * half_limit, 'b' * half_limit, 3]
+ it 'removes jobstr from the hash' do
+ hash_input[:jobstr] = 'job string'
- expected_args = hash_input['args'].take(3).map(&:to_s) + ['...']
+ expect(subject).not_to include('jobstr')
+ end
- expect(subject['args']).to eq(expected_args)
- end
+ it 'does not modify the input hash' do
+ input = { 'args' => [1, 'string'] }
+
+ output = Gitlab::Json.parse(described_class.new.call('INFO', now, 'my program', input))
+
+ expect(input['args']).to eq([1, 'string'])
+ expect(output['args']).to eq(['1', '[FILTERED]'])
end
- it 'properly flattens arguments to a String' do
- hash_input['args'] = [1, "test", 2, { 'test' => 1 }]
+ context 'job arguments' do
+ context 'when the arguments are bigger than the maximum allowed' do
+ it 'keeps args from the front until they exceed the limit' do
+ half_limit = Gitlab::Utils::LogLimitedArray::MAXIMUM_ARRAY_LENGTH / 2
+ hash_input['args'] = [1, 2, 'a' * half_limit, 'b' * half_limit, 3]
+
+ expected_args = hash_input['args'].take(3).map(&:to_s) + ['...']
+
+ expect(subject['args']).to eq(expected_args)
+ end
+ end
+
+ context 'when the job has non-integer arguments' do
+ it 'only allows permitted non-integer arguments through' do
+ hash_input['args'] = [1, 'foo', 'bar']
+ hash_input['class'] = 'WebHookWorker'
- expect(subject['args']).to eq(["1", "test", "2", %({"test"=>1})])
+ expect(subject['args']).to eq(['1', '[FILTERED]', 'bar'])
+ end
+ end
+
+ it 'properly flattens arguments to a String' do
+ hash_input['args'] = [1, "test", 2, { 'test' => 1 }]
+
+ expect(subject['args']).to eq(["1", "test", "2", %({"test"=>1})])
+ end
end
context 'when the job has a non-integer value for retry' do
diff --git a/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb b/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb
index a4bbb51baae..a456f814e78 100644
--- a/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb
+++ b/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb
@@ -21,7 +21,10 @@ describe Gitlab::SidekiqLogging::StructuredLogger do
"correlation_id" => 'cid',
"error_message" => "wrong number of arguments (2 for 3)",
"error_class" => "ArgumentError",
- "error_backtrace" => []
+ "error_backtrace" => [],
+ "db_count" => 1,
+ "db_write_count" => 0,
+ "db_cached_count" => 0
}
end
@@ -197,7 +200,10 @@ describe Gitlab::SidekiqLogging::StructuredLogger do
let(:expected_end_payload_with_db) do
expected_end_payload.merge(
- 'db_duration_s' => a_value >= 0.1
+ 'db_duration_s' => a_value >= 0.1,
+ 'db_count' => 1,
+ 'db_cached_count' => 0,
+ 'db_write_count' => 0
)
end
diff --git a/spec/lib/gitlab/sidekiq_middleware/client_metrics_spec.rb b/spec/lib/gitlab/sidekiq_middleware/client_metrics_spec.rb
index 5f80ef9538a..1d45b70ec3e 100644
--- a/spec/lib/gitlab/sidekiq_middleware/client_metrics_spec.rb
+++ b/spec/lib/gitlab/sidekiq_middleware/client_metrics_spec.rb
@@ -47,8 +47,11 @@ describe Gitlab::SidekiqMiddleware::ClientMetrics do
end
context "when workers are not attributed" do
- class TestNonAttributedWorker
- include Sidekiq::Worker
+ before do
+ stub_const('TestNonAttributedWorker', Class.new)
+ TestNonAttributedWorker.class_eval do
+ include Sidekiq::Worker
+ end
end
it_behaves_like "a metrics client middleware" do
diff --git a/spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/client_spec.rb b/spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/client_spec.rb
index 9c7f6638913..a1e4cbb1e31 100644
--- a/spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/client_spec.rb
+++ b/spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/client_spec.rb
@@ -31,14 +31,51 @@ describe Gitlab::SidekiqMiddleware::DuplicateJobs::Client, :clean_gitlab_redis_q
expect(job3['duplicate-of']).to eq(job1['jid'])
end
- it "does not mark a job that's scheduled in the future as a duplicate" do
- TestDeduplicationWorker.perform_async('args1')
- TestDeduplicationWorker.perform_at(1.day.from_now, 'args1')
- TestDeduplicationWorker.perform_in(3.hours, 'args1')
+ context 'without scheduled deduplication' do
+ it "does not mark a job that's scheduled in the future as a duplicate" do
+ TestDeduplicationWorker.perform_async('args1')
+ TestDeduplicationWorker.perform_at(1.day.from_now, 'args1')
+ TestDeduplicationWorker.perform_in(3.hours, 'args1')
- duplicates = TestDeduplicationWorker.jobs.map { |job| job['duplicate-of'] }
+ duplicates = TestDeduplicationWorker.jobs.map { |job| job['duplicate-of'] }
- expect(duplicates).to all(be_nil)
+ expect(duplicates).to all(be_nil)
+ end
+ end
+
+ context 'with scheduled deduplication' do
+ let(:scheduled_worker_class) do
+ Class.new do
+ def self.name
+ 'TestDeduplicationWorker'
+ end
+
+ include ApplicationWorker
+
+ deduplicate :until_executing, including_scheduled: true
+
+ def perform(*args)
+ end
+ end
+ end
+
+ before do
+ stub_const('TestDeduplicationWorker', scheduled_worker_class)
+ end
+
+ it 'adds a correct duplicate tag to the jobs', :aggregate_failures do
+ TestDeduplicationWorker.perform_async('args1')
+ TestDeduplicationWorker.perform_at(1.day.from_now, 'args1')
+ TestDeduplicationWorker.perform_in(3.hours, 'args1')
+ TestDeduplicationWorker.perform_in(3.hours, 'args2')
+
+ job1, job2, job3, job4 = TestDeduplicationWorker.jobs
+
+ expect(job1['duplicate-of']).to be_nil
+ expect(job2['duplicate-of']).to eq(job1['jid'])
+ expect(job3['duplicate-of']).to eq(job1['jid'])
+ expect(job4['duplicate-of']).to be_nil
+ end
end
end
end
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 929df0a7ffb..13c86563be7 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
@@ -93,6 +93,25 @@ describe Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob, :clean_gitlab_r
end
end
+ describe '#scheduled?' do
+ it 'returns false for non-scheduled jobs' do
+ expect(duplicate_job.scheduled?).to be(false)
+ end
+
+ context 'scheduled jobs' do
+ let(:job) do
+ { 'class' => 'AuthorizedProjectsWorker',
+ 'args' => [1],
+ 'jid' => '123',
+ 'at' => 42 }
+ end
+
+ it 'returns true' do
+ expect(duplicate_job.scheduled?).to be(true)
+ end
+ end
+ end
+
describe '#duplicate?' do
it "raises an error if the check wasn't performed" do
expect { duplicate_job.duplicate? }.to raise_error /Call `#check!` first/
@@ -112,28 +131,23 @@ describe Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob, :clean_gitlab_r
end
end
- describe 'droppable?' do
- where(:idempotent, :duplicate, :prevent_deduplication) do
- # [true, false].repeated_permutation(3)
- [[true, true, true],
- [true, true, false],
- [true, false, true],
- [true, false, false],
- [false, true, true],
- [false, true, false],
- [false, false, true],
- [false, false, false]]
+ describe '#droppable?' do
+ where(:idempotent, :prevent_deduplication) do
+ # [true, false].repeated_permutation(2)
+ [[true, true],
+ [true, false],
+ [false, true],
+ [false, false]]
end
with_them do
before do
allow(AuthorizedProjectsWorker).to receive(:idempotent?).and_return(idempotent)
- allow(duplicate_job).to receive(:duplicate?).and_return(duplicate)
stub_feature_flags("disable_#{queue}_deduplication" => prevent_deduplication)
end
it 'is droppable when all conditions are met' do
- if idempotent && duplicate && !prevent_deduplication
+ if idempotent && !prevent_deduplication
expect(duplicate_job).to be_droppable
else
expect(duplicate_job).not_to be_droppable
@@ -142,6 +156,31 @@ describe Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob, :clean_gitlab_r
end
end
+ describe '#scheduled_at' do
+ let(:scheduled_at) { 42 }
+ let(:job) do
+ { 'class' => 'AuthorizedProjectsWorker',
+ 'args' => [1],
+ 'jid' => '123',
+ 'at' => scheduled_at }
+ end
+
+ it 'returns when the job is scheduled at' do
+ expect(duplicate_job.scheduled_at).to eq(scheduled_at)
+ end
+ end
+
+ describe '#options' do
+ let(:worker_options) { { foo: true } }
+
+ it 'returns worker options' do
+ allow(AuthorizedProjectsWorker).to(
+ receive(:get_deduplication_options).and_return(worker_options))
+
+ expect(duplicate_job.options).to eq(worker_options)
+ end
+ end
+
def set_idempotency_key(key, value = '1')
Sidekiq.redis { |r| r.set(key, value) }
end
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 31b51260ebd..eb8b0a951a8 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
@@ -1,6 +1,7 @@
# frozen_string_literal: true
require 'fast_spec_helper'
+require 'timecop'
describe Gitlab::SidekiqMiddleware::DuplicateJobs::Strategies::UntilExecuting do
let(:fake_duplicate_job) do
@@ -15,28 +16,90 @@ describe Gitlab::SidekiqMiddleware::DuplicateJobs::Strategies::UntilExecuting do
end
it 'checks for duplicates before yielding' do
- expect(fake_duplicate_job).to receive(:check!).ordered.and_return('a jid')
+ expect(fake_duplicate_job).to receive(:scheduled?).twice.ordered.and_return(false)
+ expect(fake_duplicate_job).to(
+ receive(:check!)
+ .with(Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob::DUPLICATE_KEY_TTL)
+ .ordered
+ .and_return('a jid'))
expect(fake_duplicate_job).to receive(:duplicate?).ordered.and_return(false)
- expect(fake_duplicate_job).to receive(:droppable?).ordered.and_return(false)
expect { |b| strategy.schedule({}, &b) }.to yield_control
end
- it 'adds the jid of the existing job to the job hash' do
- allow(fake_duplicate_job).to receive(:check!).and_return('the jid')
- allow(fake_duplicate_job).to receive(:droppable?).and_return(true)
- job_hash = {}
+ it 'checks worker options for scheduled jobs' do
+ expect(fake_duplicate_job).to receive(:scheduled?).ordered.and_return(true)
+ expect(fake_duplicate_job).to receive(:options).ordered.and_return({})
+ expect(fake_duplicate_job).not_to receive(:check!)
- expect(fake_duplicate_job).to receive(:duplicate?).and_return(true)
- expect(fake_duplicate_job).to receive(:existing_jid).and_return('the jid')
+ expect { |b| strategy.schedule({}, &b) }.to yield_control
+ end
+
+ context 'job marking' do
+ it 'adds the jid of the existing job to the job hash' do
+ 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(:droppable?).and_return(true)
+ job_hash = {}
- strategy.schedule(job_hash) {}
+ expect(fake_duplicate_job).to receive(:duplicate?).and_return(true)
+ expect(fake_duplicate_job).to receive(:existing_jid).and_return('the jid')
- expect(job_hash).to include('duplicate-of' => 'the jid')
+ strategy.schedule(job_hash) {}
+
+ expect(job_hash).to include('duplicate-of' => 'the jid')
+ end
+
+ context 'scheduled jobs' do
+ let(:time_diff) { 1.minute }
+
+ context 'scheduled in the past' do
+ it 'adds the jid of the existing job to the job hash' do
+ allow(fake_duplicate_job).to receive(:scheduled?).twice.and_return(true)
+ allow(fake_duplicate_job).to receive(:scheduled_at).and_return(Time.now - time_diff)
+ allow(fake_duplicate_job).to receive(:options).and_return({ including_scheduled: true })
+ allow(fake_duplicate_job).to(
+ receive(:check!)
+ .with(Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob::DUPLICATE_KEY_TTL)
+ .and_return('the jid'))
+ allow(fake_duplicate_job).to receive(:droppable?).and_return(true)
+ job_hash = {}
+
+ expect(fake_duplicate_job).to receive(:duplicate?).and_return(true)
+ expect(fake_duplicate_job).to receive(:existing_jid).and_return('the jid')
+
+ strategy.schedule(job_hash) {}
+
+ expect(job_hash).to include('duplicate-of' => 'the jid')
+ end
+ end
+
+ context 'scheduled in the future' do
+ it 'adds the jid of the existing job to the job hash' do
+ Timecop.freeze do
+ allow(fake_duplicate_job).to receive(:scheduled?).twice.and_return(true)
+ allow(fake_duplicate_job).to receive(:scheduled_at).and_return(Time.now + time_diff)
+ allow(fake_duplicate_job).to receive(:options).and_return({ including_scheduled: true })
+ allow(fake_duplicate_job).to(
+ receive(:check!).with(time_diff.to_i).and_return('the jid'))
+ allow(fake_duplicate_job).to receive(:droppable?).and_return(true)
+ job_hash = {}
+
+ expect(fake_duplicate_job).to receive(:duplicate?).and_return(true)
+ expect(fake_duplicate_job).to receive(:existing_jid).and_return('the jid')
+
+ strategy.schedule(job_hash) {}
+
+ expect(job_hash).to include('duplicate-of' => 'the jid')
+ end
+ end
+ end
+ end
end
context "when the job is droppable" do
before do
+ 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(:duplicate?).and_return(true)
allow(fake_duplicate_job).to receive(:existing_jid).and_return('the jid')
@@ -52,7 +115,7 @@ describe Gitlab::SidekiqMiddleware::DuplicateJobs::Strategies::UntilExecuting do
expect(schedule_result).to be(false)
end
- it 'logs that the job wass dropped' do
+ it 'logs that the job was dropped' do
fake_logger = instance_double(Gitlab::SidekiqLogging::DeduplicationLogger)
expect(Gitlab::SidekiqLogging::DeduplicationLogger).to receive(:instance).and_return(fake_logger)
diff --git a/spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb b/spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb
index 3214bd758e7..4b7baea25e8 100644
--- a/spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb
+++ b/spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb
@@ -31,7 +31,11 @@ describe Gitlab::SidekiqMiddleware::ServerMetrics do
let(:gitaly_seconds_metric) { double('gitaly seconds metric') }
let(:failed_total_metric) { double('failed total metric') }
let(:retried_total_metric) { double('retried total metric') }
+ let(:redis_requests_total) { double('redis calls total metric') }
let(:running_jobs_metric) { double('running jobs metric') }
+ let(:redis_seconds_metric) { double('redis seconds metric') }
+ let(:elasticsearch_seconds_metric) { double('elasticsearch seconds metric') }
+ let(:elasticsearch_requests_total) { double('elasticsearch calls total metric') }
before do
allow(Gitlab::Metrics).to receive(:histogram).with(:sidekiq_jobs_queue_duration_seconds, anything, anything, anything).and_return(queue_duration_seconds)
@@ -39,8 +43,12 @@ describe Gitlab::SidekiqMiddleware::ServerMetrics do
allow(Gitlab::Metrics).to receive(:histogram).with(:sidekiq_jobs_cpu_seconds, anything, anything, anything).and_return(user_execution_seconds_metric)
allow(Gitlab::Metrics).to receive(:histogram).with(:sidekiq_jobs_db_seconds, anything, anything, anything).and_return(db_seconds_metric)
allow(Gitlab::Metrics).to receive(:histogram).with(:sidekiq_jobs_gitaly_seconds, anything, anything, anything).and_return(gitaly_seconds_metric)
+ allow(Gitlab::Metrics).to receive(:histogram).with(:sidekiq_redis_requests_duration_seconds, anything, anything, anything).and_return(redis_seconds_metric)
+ allow(Gitlab::Metrics).to receive(:histogram).with(:sidekiq_elasticsearch_requests_duration_seconds, anything, anything, anything).and_return(elasticsearch_seconds_metric)
allow(Gitlab::Metrics).to receive(:counter).with(:sidekiq_jobs_failed_total, anything).and_return(failed_total_metric)
allow(Gitlab::Metrics).to receive(:counter).with(:sidekiq_jobs_retried_total, anything).and_return(retried_total_metric)
+ allow(Gitlab::Metrics).to receive(:counter).with(:sidekiq_redis_requests_total, anything).and_return(redis_requests_total)
+ allow(Gitlab::Metrics).to receive(:counter).with(:sidekiq_elasticsearch_requests_total, anything).and_return(elasticsearch_requests_total)
allow(Gitlab::Metrics).to receive(:gauge).with(:sidekiq_running_jobs, anything, {}, :all).and_return(running_jobs_metric)
allow(Gitlab::Metrics).to receive(:gauge).with(:sidekiq_concurrency, anything, {}, :all).and_return(concurrency_metric)
@@ -69,21 +77,35 @@ describe Gitlab::SidekiqMiddleware::ServerMetrics do
let(:db_duration) { 3 }
let(:gitaly_duration) { 4 }
+ let(:redis_calls) { 2 }
+ let(:redis_duration) { 0.01 }
+
+ let(:elasticsearch_calls) { 8 }
+ let(:elasticsearch_duration) { 0.54 }
+
before do
allow(subject).to receive(:get_thread_cputime).and_return(thread_cputime_before, thread_cputime_after)
allow(Gitlab::Metrics::System).to receive(:monotonic_time).and_return(monotonic_time_before, monotonic_time_after)
allow(Gitlab::InstrumentationHelper).to receive(:queue_duration_for_job).with(job).and_return(queue_duration_for_job)
allow(ActiveRecord::LogSubscriber).to receive(:runtime).and_return(db_duration * 1000)
- allow(subject).to receive(:get_gitaly_time).and_return(gitaly_duration)
-
- expect(running_jobs_metric).to receive(:increment).with(labels, 1)
- expect(running_jobs_metric).to receive(:increment).with(labels, -1)
- expect(queue_duration_seconds).to receive(:observe).with(labels, queue_duration_for_job) if queue_duration_for_job
- expect(user_execution_seconds_metric).to receive(:observe).with(labels_with_job_status, thread_cputime_duration)
- expect(db_seconds_metric).to receive(:observe).with(labels_with_job_status, db_duration)
- expect(gitaly_seconds_metric).to receive(:observe).with(labels_with_job_status, gitaly_duration)
- expect(completion_seconds_metric).to receive(:observe).with(labels_with_job_status, monotonic_time_duration)
+ job[:gitaly_duration_s] = gitaly_duration
+ job[:redis_calls] = redis_calls
+ job[:redis_duration_s] = redis_duration
+
+ job[:elasticsearch_calls] = elasticsearch_calls
+ job[:elasticsearch_duration_s] = elasticsearch_duration
+
+ allow(running_jobs_metric).to receive(:increment)
+ allow(redis_requests_total).to receive(:increment)
+ allow(elasticsearch_requests_total).to receive(:increment)
+ allow(queue_duration_seconds).to receive(:observe)
+ allow(user_execution_seconds_metric).to receive(:observe)
+ allow(db_seconds_metric).to receive(:observe)
+ allow(gitaly_seconds_metric).to receive(:observe)
+ allow(completion_seconds_metric).to receive(:observe)
+ allow(redis_seconds_metric).to receive(:observe)
+ allow(elasticsearch_seconds_metric).to receive(:observe)
end
it 'yields block' do
@@ -91,6 +113,18 @@ describe Gitlab::SidekiqMiddleware::ServerMetrics do
end
it 'sets queue specific metrics' do
+ expect(running_jobs_metric).to receive(:increment).with(labels, -1)
+ expect(running_jobs_metric).to receive(:increment).with(labels, 1)
+ expect(queue_duration_seconds).to receive(:observe).with(labels, queue_duration_for_job) if queue_duration_for_job
+ expect(user_execution_seconds_metric).to receive(:observe).with(labels_with_job_status, thread_cputime_duration)
+ expect(db_seconds_metric).to receive(:observe).with(labels_with_job_status, db_duration)
+ expect(gitaly_seconds_metric).to receive(:observe).with(labels_with_job_status, gitaly_duration)
+ expect(completion_seconds_metric).to receive(:observe).with(labels_with_job_status, monotonic_time_duration)
+ expect(redis_seconds_metric).to receive(:observe).with(labels_with_job_status, redis_duration)
+ expect(elasticsearch_seconds_metric).to receive(:observe).with(labels_with_job_status, elasticsearch_duration)
+ expect(redis_requests_total).to receive(:increment).with(labels_with_job_status, redis_calls)
+ expect(elasticsearch_requests_total).to receive(:increment).with(labels_with_job_status, elasticsearch_calls)
+
subject.call(worker, job, :test) { nil }
end
@@ -144,9 +178,13 @@ describe Gitlab::SidekiqMiddleware::ServerMetrics do
end
context "when workers are not attributed" do
- class TestNonAttributedWorker
- include Sidekiq::Worker
+ before do
+ stub_const('TestNonAttributedWorker', Class.new)
+ TestNonAttributedWorker.class_eval do
+ include Sidekiq::Worker
+ end
end
+
let(:worker) { TestNonAttributedWorker.new }
let(:labels) { default_labels.merge(urgency: "") }
diff --git a/spec/lib/gitlab/sidekiq_middleware_spec.rb b/spec/lib/gitlab/sidekiq_middleware_spec.rb
index 6fe61fb42a5..5ca0abeb132 100644
--- a/spec/lib/gitlab/sidekiq_middleware_spec.rb
+++ b/spec/lib/gitlab/sidekiq_middleware_spec.rb
@@ -13,7 +13,7 @@ describe Gitlab::SidekiqMiddleware do
def perform(_arg)
Gitlab::SafeRequestStore['gitaly_call_actual'] = 1
- Gitlab::GitalyClient.query_time = 5
+ Gitlab::SafeRequestStore[:gitaly_query_time] = 5
end
end
end
diff --git a/spec/lib/gitlab/sidekiq_versioning/manager_spec.rb b/spec/lib/gitlab/sidekiq_versioning/manager_spec.rb
index 2aa7d1fd6d8..a528ce201a2 100644
--- a/spec/lib/gitlab/sidekiq_versioning/manager_spec.rb
+++ b/spec/lib/gitlab/sidekiq_versioning/manager_spec.rb
@@ -16,7 +16,8 @@ describe Gitlab::SidekiqVersioning::Manager do
expect(queues).to include('post_receive')
expect(queues).to include('repository_fork')
expect(queues).to include('cronjob')
- expect(queues).to include('cronjob:stuck_import_jobs')
+ expect(queues).to include('cronjob:import_stuck_project_import_jobs')
+ expect(queues).to include('cronjob:jira_import_stuck_jira_import_jobs')
expect(queues).to include('cronjob:stuck_merge_jobs')
expect(queues).to include('unknown')
end
diff --git a/spec/lib/gitlab/sourcegraph_spec.rb b/spec/lib/gitlab/sourcegraph_spec.rb
index e081ae32175..ef4008960a9 100644
--- a/spec/lib/gitlab/sourcegraph_spec.rb
+++ b/spec/lib/gitlab/sourcegraph_spec.rb
@@ -7,7 +7,7 @@ describe Gitlab::Sourcegraph do
let(:feature_scope) { true }
before do
- Feature.enable(:sourcegraph, feature_scope)
+ stub_feature_flags(sourcegraph: feature_scope)
end
describe '.feature_conditional?' do
diff --git a/spec/lib/gitlab/suggestions/commit_message_spec.rb b/spec/lib/gitlab/suggestions/commit_message_spec.rb
new file mode 100644
index 00000000000..0774fc80528
--- /dev/null
+++ b/spec/lib/gitlab/suggestions/commit_message_spec.rb
@@ -0,0 +1,87 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Suggestions::CommitMessage do
+ def create_suggestion(file_path, new_line, to_content)
+ position = Gitlab::Diff::Position.new(old_path: file_path,
+ new_path: file_path,
+ old_line: nil,
+ new_line: new_line,
+ diff_refs: merge_request.diff_refs)
+
+ diff_note = create(:diff_note_on_merge_request,
+ noteable: merge_request,
+ position: position,
+ project: project)
+
+ create(:suggestion,
+ :content_from_repo,
+ note: diff_note,
+ to_content: to_content)
+ end
+
+ let_it_be(:user) do
+ create(:user, :commit_email, name: 'Test User', username: 'test.user')
+ end
+
+ let_it_be(:project) do
+ create(:project, :repository, path: 'project-1', name: 'Project_1')
+ end
+
+ let_it_be(:merge_request) do
+ create(:merge_request, source_project: project, target_project: project)
+ end
+
+ let_it_be(:suggestion_set) do
+ suggestion1 = create_suggestion('files/ruby/popen.rb', 9, '*** SUGGESTION 1 ***')
+ suggestion2 = create_suggestion('files/ruby/popen.rb', 13, '*** SUGGESTION 2 ***')
+ suggestion3 = create_suggestion('files/ruby/regex.rb', 22, '*** SUGGESTION 3 ***')
+
+ Gitlab::Suggestions::SuggestionSet.new([suggestion1, suggestion2, suggestion3])
+ end
+
+ describe '#message' do
+ before do
+ # Updating the suggestion_commit_message on a project shared across specs
+ # avoids recreating the repository for each spec.
+ project.update!(suggestion_commit_message: message)
+ end
+
+ context 'when a custom commit message is not specified' do
+ let(:expected_message) { 'Apply 3 suggestion(s) to 2 file(s)' }
+
+ context 'and is nil' do
+ let(:message) { nil }
+
+ it 'uses the default commit message' do
+ expect(described_class
+ .new(user, suggestion_set)
+ .message).to eq(expected_message)
+ end
+ end
+
+ context 'and is an empty string' do
+ let(:message) { '' }
+
+ it 'uses the default commit message' do
+ expect(described_class
+ .new(user, suggestion_set)
+ .message).to eq(expected_message)
+ end
+ end
+ end
+
+ context 'is specified and includes all placeholders' do
+ let(:message) do
+ '*** %{branch_name} %{files_count} %{file_paths} %{project_name} %{project_path} %{user_full_name} %{username} %{suggestions_count} ***'
+ end
+
+ it 'generates a custom commit message' do
+ expect(Gitlab::Suggestions::CommitMessage
+ .new(user, suggestion_set)
+ .message).to eq('*** master 2 files/ruby/popen.rb, files/ruby/regex.rb Project_1 project-1 Test User test.user 3 ***')
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/suggestions/file_suggestion_spec.rb b/spec/lib/gitlab/suggestions/file_suggestion_spec.rb
new file mode 100644
index 00000000000..6fbbad017c5
--- /dev/null
+++ b/spec/lib/gitlab/suggestions/file_suggestion_spec.rb
@@ -0,0 +1,241 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Suggestions::FileSuggestion do
+ def create_suggestion(new_line, to_content)
+ position = Gitlab::Diff::Position.new(old_path: file_path,
+ new_path: file_path,
+ old_line: nil,
+ new_line: new_line,
+ diff_refs: merge_request.diff_refs)
+
+ diff_note = create(:diff_note_on_merge_request,
+ noteable: merge_request,
+ position: position,
+ project: project)
+
+ create(:suggestion,
+ :content_from_repo,
+ note: diff_note,
+ to_content: to_content)
+ end
+
+ let_it_be(:user) { create(:user) }
+
+ let_it_be(:file_path) { 'files/ruby/popen.rb'}
+
+ let_it_be(:project) { create(:project, :repository) }
+
+ let_it_be(:merge_request) do
+ create(:merge_request, source_project: project, target_project: project)
+ end
+
+ let_it_be(:suggestion1) do
+ create_suggestion(9, " *** SUGGESTION 1 ***\n")
+ end
+
+ let_it_be(:suggestion2) do
+ create_suggestion(15, " *** SUGGESTION 2 ***\n")
+ end
+
+ let(:file_suggestion) { described_class.new }
+
+ describe '#add_suggestion' do
+ it 'succeeds when adding a suggestion for the same file as the original' do
+ file_suggestion.add_suggestion(suggestion1)
+
+ expect { file_suggestion.add_suggestion(suggestion2) }.not_to raise_error
+ end
+
+ it 'raises an error when adding a suggestion for a different file' do
+ allow(suggestion2)
+ .to(receive_message_chain(:diff_file, :file_path)
+ .and_return('path/to/different/file'))
+
+ file_suggestion.add_suggestion(suggestion1)
+
+ expect { file_suggestion.add_suggestion(suggestion2) }.to(
+ raise_error(described_class::SuggestionForDifferentFileError)
+ )
+ end
+ end
+
+ describe '#line_conflict' do
+ def stub_suggestions(line_index_spans)
+ fake_suggestions = line_index_spans.map do |span|
+ double("Suggestion",
+ from_line_index: span[:from_line_index],
+ to_line_index: span[:to_line_index])
+ end
+
+ allow(file_suggestion).to(receive(:suggestions).and_return(fake_suggestions))
+ end
+
+ context 'when line ranges do not overlap' do
+ it 'return false' do
+ stub_suggestions(
+ [
+ {
+ from_line_index: 0,
+ to_line_index: 10
+ },
+ {
+ from_line_index: 11,
+ to_line_index: 20
+ }
+ ]
+ )
+
+ expect(file_suggestion.line_conflict?).to be(false)
+ end
+ end
+
+ context 'when line ranges are identical' do
+ it 'returns true' do
+ stub_suggestions(
+ [
+ {
+ from_line_index: 0,
+ to_line_index: 10
+ },
+ {
+ from_line_index: 0,
+ to_line_index: 10
+ }
+ ]
+ )
+
+ expect(file_suggestion.line_conflict?).to be(true)
+ end
+ end
+
+ context 'when one range starts, and the other ends, on the same line' do
+ it 'returns true' do
+ stub_suggestions(
+ [
+ {
+ from_line_index: 0,
+ to_line_index: 10
+ },
+ {
+ from_line_index: 10,
+ to_line_index: 20
+ }
+ ]
+ )
+
+ expect(file_suggestion.line_conflict?).to be(true)
+ end
+ end
+
+ context 'when one line range contains the other' do
+ it 'returns true' do
+ stub_suggestions(
+ [
+ {
+ from_line_index: 0,
+ to_line_index: 10
+ },
+ {
+ from_line_index: 5,
+ to_line_index: 7
+ }
+ ]
+ )
+
+ expect(file_suggestion.line_conflict?).to be(true)
+ end
+ end
+
+ context 'when line ranges overlap' do
+ it 'returns true' do
+ stub_suggestions(
+ [
+ {
+ from_line_index: 0,
+ to_line_index: 10
+ },
+ {
+ from_line_index: 8,
+ to_line_index: 15
+ }
+ ]
+ )
+
+ expect(file_suggestion.line_conflict?).to be(true)
+ end
+ end
+
+ context 'when no suggestions have been added' do
+ it 'returns false' do
+ expect(file_suggestion.line_conflict?).to be(false)
+ end
+ end
+ end
+
+ describe '#new_content' do
+ it 'returns a blob with the suggestions applied to it' do
+ file_suggestion.add_suggestion(suggestion1)
+ file_suggestion.add_suggestion(suggestion2)
+
+ expected_content = <<-CONTENT.strip_heredoc
+ require 'fileutils'
+ require 'open3'
+
+ module Popen
+ extend self
+
+ def popen(cmd, path=nil)
+ unless cmd.is_a?(Array)
+ *** SUGGESTION 1 ***
+ end
+
+ path ||= Dir.pwd
+
+ vars = {
+ *** SUGGESTION 2 ***
+ }
+
+ options = {
+ chdir: path
+ }
+
+ unless File.directory?(path)
+ FileUtils.mkdir_p(path)
+ end
+
+ @cmd_output = ""
+ @cmd_status = 0
+
+ Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|
+ @cmd_output << stdout.read
+ @cmd_output << stderr.read
+ @cmd_status = wait_thr.value.exitstatus
+ end
+
+ return @cmd_output, @cmd_status
+ end
+ end
+ CONTENT
+
+ expect(file_suggestion.new_content).to eq(expected_content)
+ end
+
+ it 'returns an empty string when no suggestions have been added' do
+ expect(file_suggestion.new_content).to eq('')
+ end
+ end
+
+ describe '#file_path' do
+ it 'returns the path of the file associated with the suggestions' do
+ file_suggestion.add_suggestion(suggestion1)
+
+ expect(file_suggestion.file_path).to eq(file_path)
+ end
+
+ it 'returns nil if no suggestions have been added' do
+ expect(file_suggestion.file_path).to be(nil)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/suggestions/suggestion_set_spec.rb b/spec/lib/gitlab/suggestions/suggestion_set_spec.rb
new file mode 100644
index 00000000000..8c61e6c42a6
--- /dev/null
+++ b/spec/lib/gitlab/suggestions/suggestion_set_spec.rb
@@ -0,0 +1,110 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Suggestions::SuggestionSet do
+ def create_suggestion(file_path, new_line, to_content)
+ position = Gitlab::Diff::Position.new(old_path: file_path,
+ new_path: file_path,
+ old_line: nil,
+ new_line: new_line,
+ diff_refs: merge_request.diff_refs)
+
+ diff_note = create(:diff_note_on_merge_request,
+ noteable: merge_request,
+ position: position,
+ project: project)
+
+ create(:suggestion,
+ :content_from_repo,
+ note: diff_note,
+ to_content: to_content)
+ end
+
+ let_it_be(:user) { create(:user) }
+
+ let_it_be(:project) { create(:project, :repository) }
+
+ let_it_be(:merge_request) do
+ create(:merge_request, source_project: project, target_project: project)
+ end
+
+ let_it_be(:suggestion) { create(:suggestion)}
+
+ let_it_be(:suggestion2) do
+ create_suggestion('files/ruby/popen.rb', 13, "*** SUGGESTION 2 ***")
+ end
+
+ let_it_be(:suggestion3) do
+ create_suggestion('files/ruby/regex.rb', 22, "*** SUGGESTION 3 ***")
+ end
+
+ let_it_be(:unappliable_suggestion) { create(:suggestion, :unappliable) }
+
+ let(:suggestion_set) { described_class.new([suggestion]) }
+
+ describe '#project' do
+ it 'returns the project associated with the suggestions' do
+ expected_project = suggestion.project
+
+ expect(suggestion_set.project).to be(expected_project)
+ end
+ end
+
+ describe '#branch' do
+ it 'returns the branch associated with the suggestions' do
+ expected_branch = suggestion.branch
+
+ expect(suggestion_set.branch).to be(expected_branch)
+ end
+ end
+
+ describe '#valid?' do
+ it 'returns true if no errors are found' do
+ expect(suggestion_set.valid?).to be(true)
+ end
+
+ it 'returns false if an error is found' do
+ suggestion_set = described_class.new([unappliable_suggestion])
+
+ expect(suggestion_set.valid?).to be(false)
+ end
+ end
+
+ describe '#error_message' do
+ it 'returns an error message if an error is found' do
+ suggestion_set = described_class.new([unappliable_suggestion])
+
+ expect(suggestion_set.error_message).to be_a(String)
+ end
+
+ it 'returns nil if no errors are found' do
+ expect(suggestion_set.error_message).to be(nil)
+ end
+ end
+
+ describe '#actions' do
+ it 'returns an array of hashes with proper key/value pairs' do
+ first_action = suggestion_set.actions.first
+
+ file_path, file_suggestion = suggestion_set
+ .send(:suggestions_per_file).first
+
+ expect(first_action[:action]).to be('update')
+ expect(first_action[:file_path]).to eq(file_path)
+ expect(first_action[:content]).to eq(file_suggestion.new_content)
+ end
+ end
+
+ describe '#file_paths' do
+ it 'returns an array of unique file paths associated with the suggestions' do
+ suggestion_set = described_class.new([suggestion, suggestion2, suggestion3])
+
+ expected_paths = %w(files/ruby/popen.rb files/ruby/regex.rb)
+
+ actual_paths = suggestion_set.file_paths
+
+ expect(actual_paths.sort).to eq(expected_paths)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/tracking_spec.rb b/spec/lib/gitlab/tracking_spec.rb
index 2e65f98a085..82828c2dcce 100644
--- a/spec/lib/gitlab/tracking_spec.rb
+++ b/spec/lib/gitlab/tracking_spec.rb
@@ -27,14 +27,13 @@ describe Gitlab::Tracking do
expect(subject.snowplow_options(nil)).to match(expected_fields)
end
- it 'enables features using feature flags' do
- stub_feature_flags(additional_snowplow_tracking: :__group__)
- addition_feature_fields = {
+ it 'when feature flag is disabled' do
+ stub_feature_flags(additional_snowplow_tracking: false)
+
+ expect(subject.snowplow_options(nil)).to include(
formTracking: false,
linkClickTracking: false
- }
-
- expect(subject.snowplow_options(:_group_)).to include(addition_feature_fields)
+ )
end
end
diff --git a/spec/lib/gitlab/url_builder_spec.rb b/spec/lib/gitlab/url_builder_spec.rb
index 66826bcb3b1..e91d17bfbe8 100644
--- a/spec/lib/gitlab/url_builder_spec.rb
+++ b/spec/lib/gitlab/url_builder_spec.rb
@@ -96,6 +96,38 @@ describe Gitlab::UrlBuilder do
end
end
+ context 'when passing a Wiki' do
+ let(:wiki) { build_stubbed(:project_wiki) }
+
+ describe '#wiki_url' do
+ it 'uses the default collection action' do
+ url = subject.wiki_url(wiki)
+
+ expect(url).to eq "#{Gitlab.config.gitlab.url}/#{wiki.project.full_path}/-/wikis/home"
+ end
+
+ it 'supports a custom collection action' do
+ url = subject.wiki_url(wiki, action: :pages)
+
+ expect(url).to eq "#{Gitlab.config.gitlab.url}/#{wiki.project.full_path}/-/wikis/pages"
+ end
+ end
+
+ describe '#wiki_page_url' do
+ it 'uses the default member action' do
+ url = subject.wiki_page_url(wiki, 'foo')
+
+ expect(url).to eq "#{Gitlab.config.gitlab.url}/#{wiki.project.full_path}/-/wikis/foo"
+ end
+
+ it 'supports a custom member action' do
+ url = subject.wiki_page_url(wiki, 'foo', action: :edit)
+
+ expect(url).to eq "#{Gitlab.config.gitlab.url}/#{wiki.project.full_path}/-/wikis/foo/edit"
+ end
+ end
+ end
+
context 'when passing a DesignManagement::Design' do
let(:design) { build_stubbed(:design) }
diff --git a/spec/lib/gitlab/usage_data_concerns/topology_spec.rb b/spec/lib/gitlab/usage_data_concerns/topology_spec.rb
new file mode 100644
index 00000000000..0428900690c
--- /dev/null
+++ b/spec/lib/gitlab/usage_data_concerns/topology_spec.rb
@@ -0,0 +1,220 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::UsageDataConcerns::Topology do
+ include UsageDataHelpers
+
+ describe '#topology_usage_data' do
+ subject { Class.new.extend(described_class).topology_usage_data }
+
+ before do
+ # this pins down time shifts when benchmarking durations
+ allow(Process).to receive(:clock_gettime).and_return(0)
+ end
+
+ context 'when embedded Prometheus server is enabled' do
+ before do
+ expect(Gitlab::Prometheus::Internal).to receive(:prometheus_enabled?).and_return(true)
+ expect(Gitlab::Prometheus::Internal).to receive(:uri).and_return('http://prom:9090')
+ end
+
+ it 'contains a topology element' do
+ allow_prometheus_queries
+
+ expect(subject).to have_key(:topology)
+ end
+
+ context 'tracking node metrics' do
+ it 'contains node level metrics for each instance' do
+ expect_prometheus_api_to(
+ receive_node_memory_query,
+ receive_node_cpu_count_query,
+ receive_node_service_memory_query,
+ receive_node_service_process_count_query
+ )
+
+ expect(subject[:topology]).to eq({
+ duration_s: 0,
+ nodes: [
+ {
+ node_memory_total_bytes: 512,
+ node_cpus: 8,
+ node_services: [
+ {
+ name: 'web',
+ process_count: 10,
+ process_memory_rss: 300,
+ process_memory_uss: 301,
+ process_memory_pss: 302
+ },
+ {
+ name: 'sidekiq',
+ process_count: 5,
+ process_memory_rss: 303
+ }
+ ]
+ },
+ {
+ node_memory_total_bytes: 1024,
+ node_cpus: 16,
+ node_services: [
+ {
+ name: 'sidekiq',
+ process_count: 15,
+ process_memory_rss: 400,
+ process_memory_pss: 401
+ },
+ {
+ name: 'redis',
+ process_count: 1,
+ process_memory_rss: 402
+ }
+ ]
+ }
+ ]
+ })
+ end
+ end
+
+ context 'and some node memory metrics are missing' do
+ it 'removes the respective entries' do
+ expect_prometheus_api_to(
+ receive_node_memory_query(result: []),
+ receive_node_cpu_count_query,
+ receive_node_service_memory_query,
+ receive_node_service_process_count_query
+ )
+
+ keys = subject[:topology][:nodes].flat_map(&:keys)
+ expect(keys).not_to include(:node_memory_total_bytes)
+ expect(keys).to include(:node_cpus, :node_services)
+ end
+ end
+
+ context 'and no results are found' do
+ it 'does not report anything' do
+ expect_prometheus_api_to receive(:aggregate).at_least(:once).and_return({})
+
+ expect(subject[:topology]).to eq({
+ duration_s: 0,
+ nodes: []
+ })
+ end
+ end
+
+ context 'and a connection error is raised' do
+ it 'does not report anything' do
+ expect_prometheus_api_to receive(:aggregate).and_raise('Connection failed')
+
+ expect(subject[:topology]).to eq({ duration_s: 0 })
+ end
+ end
+ end
+
+ context 'when embedded Prometheus server is disabled' do
+ it 'does not report anything' do
+ expect(Gitlab::Prometheus::Internal).to receive(:prometheus_enabled?).and_return(false)
+
+ expect(subject[:topology]).to eq({ duration_s: 0 })
+ end
+ end
+ end
+
+ def receive_node_memory_query(result: nil)
+ receive(:query)
+ .with(/node_memory_MemTotal_bytes/, an_instance_of(Hash))
+ .and_return(result || [
+ {
+ 'metric' => { 'instance' => 'instance1:8080' },
+ 'value' => [1000, '512']
+ },
+ {
+ 'metric' => { 'instance' => 'instance2:8090' },
+ 'value' => [1000, '1024']
+ }
+ ])
+ end
+
+ def receive_node_cpu_count_query(result: nil)
+ receive(:query)
+ .with(/node_cpu_seconds_total/, an_instance_of(Hash))
+ .and_return(result || [
+ {
+ 'metric' => { 'instance' => 'instance2:8090' },
+ 'value' => [1000, '16']
+ },
+ {
+ 'metric' => { 'instance' => 'instance1:8080' },
+ 'value' => [1000, '8']
+ }
+ ])
+ end
+
+ def receive_node_service_memory_query(result: nil)
+ receive(:query)
+ .with(/process_.+_memory_bytes/, an_instance_of(Hash))
+ .and_return(result || [
+ # instance 1: runs Puma + a small Sidekiq
+ {
+ 'metric' => { 'instance' => 'instance1:8080', 'job' => 'gitlab-rails', '__name__' => 'ruby_process_resident_memory_bytes' },
+ 'value' => [1000, '300']
+ },
+ {
+ 'metric' => { 'instance' => 'instance1:8080', 'job' => 'gitlab-rails', '__name__' => 'ruby_process_unique_memory_bytes' },
+ 'value' => [1000, '301']
+ },
+ {
+ 'metric' => { 'instance' => 'instance1:8080', 'job' => 'gitlab-rails', '__name__' => 'ruby_process_proportional_memory_bytes' },
+ 'value' => [1000, '302']
+ },
+ {
+ 'metric' => { 'instance' => 'instance1:8090', 'job' => 'gitlab-sidekiq', '__name__' => 'ruby_process_resident_memory_bytes' },
+ 'value' => [1000, '303']
+ },
+ # instance 2: runs a dedicated Sidekiq + Redis (which uses a different metric name)
+ {
+ 'metric' => { 'instance' => 'instance2:8090', 'job' => 'gitlab-sidekiq', '__name__' => 'ruby_process_resident_memory_bytes' },
+ 'value' => [1000, '400']
+ },
+ {
+ 'metric' => { 'instance' => 'instance2:8090', 'job' => 'gitlab-sidekiq', '__name__' => 'ruby_process_proportional_memory_bytes' },
+ 'value' => [1000, '401']
+ },
+ {
+ 'metric' => { 'instance' => 'instance2:9121', 'job' => 'redis', '__name__' => 'process_resident_memory_bytes' },
+ 'value' => [1000, '402']
+ }
+ ])
+ end
+
+ def receive_node_service_process_count_query(result: nil)
+ receive(:query)
+ .with(/process_start_time_seconds/, an_instance_of(Hash))
+ .and_return(result || [
+ # instance 1
+ {
+ 'metric' => { 'instance' => 'instance1:8080', 'job' => 'gitlab-rails' },
+ 'value' => [1000, '10']
+ },
+ {
+ 'metric' => { 'instance' => 'instance1:8090', 'job' => 'gitlab-sidekiq' },
+ 'value' => [1000, '5']
+ },
+ # instance 2
+ {
+ 'metric' => { 'instance' => 'instance2:8090', 'job' => 'gitlab-sidekiq' },
+ 'value' => [1000, '15']
+ },
+ {
+ 'metric' => { 'instance' => 'instance2:9121', 'job' => 'redis' },
+ 'value' => [1000, '1']
+ },
+ # unknown service => should be stripped out
+ {
+ 'metric' => { 'instance' => 'instance2:9000', 'job' => 'not-a-gitlab-service' },
+ 'value' => [1000, '42']
+ }
+ ])
+ end
+end
diff --git a/spec/lib/gitlab/usage_data_counters/search_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/search_counter_spec.rb
index 50a9f980dc7..35b0f9a67f4 100644
--- a/spec/lib/gitlab/usage_data_counters/search_counter_spec.rb
+++ b/spec/lib/gitlab/usage_data_counters/search_counter_spec.rb
@@ -3,11 +3,21 @@
require 'spec_helper'
describe Gitlab::UsageDataCounters::SearchCounter, :clean_gitlab_redis_shared_state do
- it 'increments counter and return the total count' do
- expect(described_class.total_navbar_searches_count).to eq(0)
+ shared_examples_for 'usage counter with totals' do |counter|
+ it 'increments counter and returns total count' do
+ expect(described_class.read(counter)).to eq(0)
- 2.times { described_class.increment_navbar_searches_count }
+ 2.times { described_class.count(counter) }
- expect(described_class.total_navbar_searches_count).to eq(2)
+ expect(described_class.read(counter)).to eq(2)
+ end
+ end
+
+ context 'all_searches counter' do
+ it_behaves_like 'usage counter with totals', :all_searches
+ end
+
+ context 'navbar_searches counter' do
+ it_behaves_like 'usage counter with totals', :navbar_searches
end
end
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index 9c6aab10083..31176999333 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -6,637 +6,600 @@ describe Gitlab::UsageData, :aggregate_failures do
include UsageDataHelpers
before do
- allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false)
-
+ stub_usage_data_connections
stub_object_store_settings
end
- shared_examples "usage data execution" do
- describe '#data' do
- let!(:ud) { build(:usage_data) }
-
- before do
- allow(described_class).to receive(:grafana_embed_usage_data).and_return(2)
+ describe '#uncached_data' do
+ it 'ensures recorded_at is set before any other usage data calculation' do
+ %i(alt_usage_data redis_usage_data distinct_count count).each do |method|
+ expect(described_class).not_to receive(method)
end
+ expect(described_class).to receive(:recorded_at).and_raise(Exception.new('Stopped calculating recorded_at'))
- subject { described_class.data }
+ expect { described_class.uncached_data }.to raise_error('Stopped calculating recorded_at')
+ end
+ end
- it 'gathers usage data' do
- expect(subject.keys).to include(*UsageDataHelpers::USAGE_DATA_KEYS)
- end
+ describe '#data' do
+ let!(:ud) { build(:usage_data) }
- it 'gathers usage counts' do
- count_data = subject[:counts]
+ before do
+ allow(described_class).to receive(:grafana_embed_usage_data).and_return(2)
+ end
- expect(count_data[:boards]).to eq(1)
- expect(count_data[:projects]).to eq(4)
- expect(count_data.values_at(*UsageDataHelpers::SMAU_KEYS)).to all(be_an(Integer))
- expect(count_data.keys).to include(*UsageDataHelpers::COUNTS_KEYS)
- expect(UsageDataHelpers::COUNTS_KEYS - count_data.keys).to be_empty
- end
+ subject { described_class.data }
- it 'gathers projects data correctly' do
- count_data = subject[:counts]
-
- expect(count_data[:projects]).to eq(4)
- expect(count_data[:projects_asana_active]).to eq(0)
- expect(count_data[:projects_prometheus_active]).to eq(1)
- expect(count_data[:projects_jira_active]).to eq(4)
- expect(count_data[:projects_jira_server_active]).to eq(2)
- expect(count_data[:projects_jira_cloud_active]).to eq(2)
- expect(count_data[:jira_imports_projects_count]).to eq(2)
- expect(count_data[:jira_imports_total_imported_count]).to eq(3)
- expect(count_data[:jira_imports_total_imported_issues_count]).to eq(13)
- expect(count_data[:projects_slack_notifications_active]).to eq(2)
- expect(count_data[:projects_slack_slash_active]).to eq(1)
- expect(count_data[:projects_slack_active]).to eq(2)
- expect(count_data[:projects_slack_slash_commands_active]).to eq(1)
- expect(count_data[:projects_custom_issue_tracker_active]).to eq(1)
- expect(count_data[:projects_mattermost_active]).to eq(0)
- expect(count_data[:projects_with_repositories_enabled]).to eq(3)
- expect(count_data[:projects_with_error_tracking_enabled]).to eq(1)
- expect(count_data[:projects_with_alerts_service_enabled]).to eq(1)
- expect(count_data[:projects_with_prometheus_alerts]).to eq(2)
- expect(count_data[:issues_created_from_gitlab_error_tracking_ui]).to eq(1)
- expect(count_data[:issues_with_associated_zoom_link]).to eq(2)
- expect(count_data[:issues_using_zoom_quick_actions]).to eq(3)
- expect(count_data[:issues_with_embedded_grafana_charts_approx]).to eq(2)
- expect(count_data[:incident_issues]).to eq(4)
- expect(count_data[:issues_created_gitlab_alerts]).to eq(1)
- expect(count_data[:alert_bot_incident_issues]).to eq(4)
- expect(count_data[:incident_labeled_issues]).to eq(3)
-
- expect(count_data[:clusters_enabled]).to eq(6)
- expect(count_data[:project_clusters_enabled]).to eq(4)
- expect(count_data[:group_clusters_enabled]).to eq(1)
- expect(count_data[:instance_clusters_enabled]).to eq(1)
- expect(count_data[:clusters_disabled]).to eq(3)
- expect(count_data[:project_clusters_disabled]).to eq(1)
- expect(count_data[:group_clusters_disabled]).to eq(1)
- expect(count_data[:instance_clusters_disabled]).to eq(1)
- expect(count_data[:clusters_platforms_eks]).to eq(1)
- expect(count_data[:clusters_platforms_gke]).to eq(1)
- expect(count_data[:clusters_platforms_user]).to eq(1)
- expect(count_data[:clusters_applications_helm]).to eq(1)
- expect(count_data[:clusters_applications_ingress]).to eq(1)
- expect(count_data[:clusters_applications_cert_managers]).to eq(1)
- expect(count_data[:clusters_applications_crossplane]).to eq(1)
- expect(count_data[:clusters_applications_prometheus]).to eq(1)
- expect(count_data[:clusters_applications_runner]).to eq(1)
- expect(count_data[:clusters_applications_knative]).to eq(1)
- expect(count_data[:clusters_applications_elastic_stack]).to eq(1)
- expect(count_data[:grafana_integrated_projects]).to eq(2)
- expect(count_data[:clusters_applications_jupyter]).to eq(1)
- expect(count_data[:clusters_management_project]).to eq(1)
- end
+ it 'gathers usage data' do
+ expect(subject.keys).to include(*UsageDataHelpers::USAGE_DATA_KEYS)
+ end
- it 'gathers object store usage correctly' do
- expect(subject[:object_store]).to eq(
- { artifacts: { enabled: true, object_store: { enabled: true, direct_upload: true, background_upload: false, provider: "AWS" } },
- external_diffs: { enabled: false },
- lfs: { enabled: true, object_store: { enabled: false, direct_upload: true, background_upload: false, provider: "AWS" } },
- uploads: { enabled: nil, object_store: { enabled: false, direct_upload: true, background_upload: false, provider: "AWS" } },
- packages: { enabled: true, object_store: { enabled: false, direct_upload: false, background_upload: true, provider: "AWS" } } }
- )
- end
+ it 'gathers usage counts' do
+ count_data = subject[:counts]
- context 'with existing container expiration policies' do
- let_it_be(:disabled) { create(:container_expiration_policy, enabled: false) }
- let_it_be(:enabled) { create(:container_expiration_policy, enabled: true) }
+ expect(count_data[:boards]).to eq(1)
+ expect(count_data[:projects]).to eq(4)
+ expect(count_data.values_at(*UsageDataHelpers::SMAU_KEYS)).to all(be_an(Integer))
+ expect(count_data.keys).to include(*UsageDataHelpers::COUNTS_KEYS)
+ expect(UsageDataHelpers::COUNTS_KEYS - count_data.keys).to be_empty
+ end
- %i[keep_n cadence older_than].each do |attribute|
- ContainerExpirationPolicy.send("#{attribute}_options").keys.each do |value|
- let_it_be("container_expiration_policy_with_#{attribute}_set_to_#{value}") { create(:container_expiration_policy, attribute => value) }
- end
- end
+ it 'gathers projects data correctly' do
+ count_data = subject[:counts]
+
+ expect(count_data[:projects]).to eq(4)
+ expect(count_data[:projects_asana_active]).to eq(0)
+ expect(count_data[:projects_prometheus_active]).to eq(1)
+ expect(count_data[:projects_jira_active]).to eq(4)
+ expect(count_data[:projects_jira_server_active]).to eq(2)
+ expect(count_data[:projects_jira_cloud_active]).to eq(2)
+ expect(count_data[:jira_imports_projects_count]).to eq(2)
+ expect(count_data[:jira_imports_total_imported_count]).to eq(3)
+ expect(count_data[:jira_imports_total_imported_issues_count]).to eq(13)
+ expect(count_data[:projects_slack_notifications_active]).to eq(2)
+ expect(count_data[:projects_slack_slash_active]).to eq(1)
+ expect(count_data[:projects_slack_active]).to eq(2)
+ expect(count_data[:projects_slack_slash_commands_active]).to eq(1)
+ expect(count_data[:projects_custom_issue_tracker_active]).to eq(1)
+ expect(count_data[:projects_mattermost_active]).to eq(0)
+ expect(count_data[:projects_with_repositories_enabled]).to eq(3)
+ expect(count_data[:projects_with_error_tracking_enabled]).to eq(1)
+ expect(count_data[:projects_with_alerts_service_enabled]).to eq(1)
+ expect(count_data[:projects_with_prometheus_alerts]).to eq(2)
+ expect(count_data[:projects_with_terraform_reports]).to eq(2)
+ expect(count_data[:projects_with_terraform_states]).to eq(2)
+ expect(count_data[:terraform_reports]).to eq(6)
+ expect(count_data[:terraform_states]).to eq(3)
+ expect(count_data[:issues_created_from_gitlab_error_tracking_ui]).to eq(1)
+ expect(count_data[:issues_with_associated_zoom_link]).to eq(2)
+ expect(count_data[:issues_using_zoom_quick_actions]).to eq(3)
+ expect(count_data[:issues_with_embedded_grafana_charts_approx]).to eq(2)
+ expect(count_data[:incident_issues]).to eq(4)
+ expect(count_data[:issues_created_gitlab_alerts]).to eq(1)
+ expect(count_data[:issues_created_from_alerts]).to eq(3)
+ expect(count_data[:issues_created_manually_from_alerts]).to eq(1)
+ expect(count_data[:alert_bot_incident_issues]).to eq(4)
+ expect(count_data[:incident_labeled_issues]).to eq(3)
+
+ expect(count_data[:clusters_enabled]).to eq(6)
+ expect(count_data[:project_clusters_enabled]).to eq(4)
+ expect(count_data[:group_clusters_enabled]).to eq(1)
+ expect(count_data[:instance_clusters_enabled]).to eq(1)
+ expect(count_data[:clusters_disabled]).to eq(3)
+ expect(count_data[:project_clusters_disabled]).to eq(1)
+ expect(count_data[:group_clusters_disabled]).to eq(1)
+ expect(count_data[:instance_clusters_disabled]).to eq(1)
+ expect(count_data[:clusters_platforms_eks]).to eq(1)
+ expect(count_data[:clusters_platforms_gke]).to eq(1)
+ expect(count_data[:clusters_platforms_user]).to eq(1)
+ expect(count_data[:clusters_applications_helm]).to eq(1)
+ expect(count_data[:clusters_applications_ingress]).to eq(1)
+ expect(count_data[:clusters_applications_cert_managers]).to eq(1)
+ expect(count_data[:clusters_applications_crossplane]).to eq(1)
+ expect(count_data[:clusters_applications_prometheus]).to eq(1)
+ expect(count_data[:clusters_applications_runner]).to eq(1)
+ expect(count_data[:clusters_applications_knative]).to eq(1)
+ expect(count_data[:clusters_applications_elastic_stack]).to eq(1)
+ expect(count_data[:grafana_integrated_projects]).to eq(2)
+ expect(count_data[:clusters_applications_jupyter]).to eq(1)
+ expect(count_data[:clusters_management_project]).to eq(1)
+ end
+
+ it 'gathers object store usage correctly' do
+ expect(subject[:object_store]).to eq(
+ { artifacts: { enabled: true, object_store: { enabled: true, direct_upload: true, background_upload: false, provider: "AWS" } },
+ external_diffs: { enabled: false },
+ lfs: { enabled: true, object_store: { enabled: false, direct_upload: true, background_upload: false, provider: "AWS" } },
+ uploads: { enabled: nil, object_store: { enabled: false, direct_upload: true, background_upload: false, provider: "AWS" } },
+ packages: { enabled: true, object_store: { enabled: false, direct_upload: false, background_upload: true, provider: "AWS" } } }
+ )
+ end
+
+ it 'gathers topology data' do
+ expect(subject.keys).to include(:topology)
+ end
+
+ context 'with existing container expiration policies' do
+ let_it_be(:disabled) { create(:container_expiration_policy, enabled: false) }
+ let_it_be(:enabled) { create(:container_expiration_policy, enabled: true) }
- let(:inactive_policies) { ::ContainerExpirationPolicy.where(enabled: false) }
- let(:active_policies) { ::ContainerExpirationPolicy.active }
-
- subject { described_class.data[:counts] }
-
- it 'gathers usage data' do
- expect(subject[:projects_with_expiration_policy_enabled]).to eq 20
- expect(subject[:projects_with_expiration_policy_disabled]).to eq 1
-
- expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_unset]).to eq 14
- expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_1]).to eq 1
- expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_5]).to eq 1
- expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_10]).to eq 1
- expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_25]).to eq 1
- expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_50]).to eq 1
-
- expect(subject[:projects_with_expiration_policy_enabled_with_older_than_unset]).to eq 16
- expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_7d]).to eq 1
- expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_14d]).to eq 1
- expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_30d]).to eq 1
- expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_90d]).to eq 1
-
- expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_1d]).to eq 12
- expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_7d]).to eq 5
- expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_14d]).to eq 1
- expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_1month]).to eq 1
- expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_3month]).to eq 1
+ %i[keep_n cadence older_than].each do |attribute|
+ ContainerExpirationPolicy.send("#{attribute}_options").keys.each do |value|
+ let_it_be("container_expiration_policy_with_#{attribute}_set_to_#{value}") { create(:container_expiration_policy, attribute => value) }
end
end
- it 'works when queries time out' do
- allow_any_instance_of(ActiveRecord::Relation)
- .to receive(:count).and_raise(ActiveRecord::StatementInvalid.new(''))
+ let_it_be('container_expiration_policy_with_keep_n_set_to_null') { create(:container_expiration_policy, keep_n: nil) }
+ let_it_be('container_expiration_policy_with_older_than_set_to_null') { create(:container_expiration_policy, older_than: nil) }
- expect { subject }.not_to raise_error
- end
+ let(:inactive_policies) { ::ContainerExpirationPolicy.where(enabled: false) }
+ let(:active_policies) { ::ContainerExpirationPolicy.active }
- it 'jira usage works when queries time out' do
- allow_any_instance_of(ActiveRecord::Relation)
- .to receive(:find_in_batches).and_raise(ActiveRecord::StatementInvalid.new(''))
+ subject { described_class.data[:counts] }
- expect { described_class.jira_usage }.not_to raise_error
+ it 'gathers usage data' do
+ expect(subject[:projects_with_expiration_policy_enabled]).to eq 22
+ expect(subject[:projects_with_expiration_policy_disabled]).to eq 1
+
+ expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_unset]).to eq 1
+ expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_1]).to eq 1
+ expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_5]).to eq 1
+ expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_10]).to eq 16
+ expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_25]).to eq 1
+ expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_50]).to eq 1
+
+ expect(subject[:projects_with_expiration_policy_enabled_with_older_than_unset]).to eq 1
+ expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_7d]).to eq 1
+ expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_14d]).to eq 1
+ expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_30d]).to eq 1
+ expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_90d]).to eq 18
+
+ expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_1d]).to eq 18
+ expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_7d]).to eq 1
+ expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_14d]).to eq 1
+ expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_1month]).to eq 1
+ expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_3month]).to eq 1
end
end
- describe '#usage_data_counters' do
- subject { described_class.usage_data_counters }
+ it 'works when queries time out' do
+ allow_any_instance_of(ActiveRecord::Relation)
+ .to receive(:count).and_raise(ActiveRecord::StatementInvalid.new(''))
- it { is_expected.to all(respond_to :totals) }
- it { is_expected.to all(respond_to :fallback_totals) }
+ expect { subject }.not_to raise_error
+ end
- describe 'the results of calling #totals on all objects in the array' do
- subject { described_class.usage_data_counters.map(&:totals) }
+ it 'jira usage works when queries time out' do
+ allow_any_instance_of(ActiveRecord::Relation)
+ .to receive(:find_in_batches).and_raise(ActiveRecord::StatementInvalid.new(''))
- it { is_expected.to all(be_a Hash) }
- it { is_expected.to all(have_attributes(keys: all(be_a Symbol), values: all(be_a Integer))) }
- end
+ expect { described_class.jira_usage }.not_to raise_error
+ end
+ end
- describe 'the results of calling #fallback_totals on all objects in the array' do
- subject { described_class.usage_data_counters.map(&:fallback_totals) }
+ describe '#usage_data_counters' do
+ subject { described_class.usage_data_counters }
- it { is_expected.to all(be_a Hash) }
- it { is_expected.to all(have_attributes(keys: all(be_a Symbol), values: all(eq(-1)))) }
- end
+ it { is_expected.to all(respond_to :totals) }
+ it { is_expected.to all(respond_to :fallback_totals) }
- it 'does not have any conflicts' do
- all_keys = subject.flat_map { |counter| counter.totals.keys }
+ describe 'the results of calling #totals on all objects in the array' do
+ subject { described_class.usage_data_counters.map(&:totals) }
- expect(all_keys.size).to eq all_keys.to_set.size
- end
+ it { is_expected.to all(be_a Hash) }
+ it { is_expected.to all(have_attributes(keys: all(be_a Symbol), values: all(be_a Integer))) }
end
- describe '#license_usage_data' do
- subject { described_class.license_usage_data }
+ describe 'the results of calling #fallback_totals on all objects in the array' do
+ subject { described_class.usage_data_counters.map(&:fallback_totals) }
- it 'gathers license data' do
- expect(subject[:uuid]).to eq(Gitlab::CurrentSettings.uuid)
- expect(subject[:version]).to eq(Gitlab::VERSION)
- expect(subject[:installation_type]).to eq('gitlab-development-kit')
- expect(subject[:active_user_count]).to eq(User.active.size)
- expect(subject[:recorded_at]).to be_a(Time)
- end
+ it { is_expected.to all(be_a Hash) }
+ it { is_expected.to all(have_attributes(keys: all(be_a Symbol), values: all(eq(-1)))) }
end
- describe '.recording_ce_finished_at' do
- subject { described_class.recording_ce_finish_data }
+ it 'does not have any conflicts' do
+ all_keys = subject.flat_map { |counter| counter.totals.keys }
- it 'gathers time ce recording finishes at' do
- expect(subject[:recording_ce_finished_at]).to be_a(Time)
- end
+ expect(all_keys.size).to eq all_keys.to_set.size
end
+ end
- context 'when not relying on database records' do
- describe '#features_usage_data_ce' do
- subject { described_class.features_usage_data_ce }
-
- it 'gathers feature usage data' do
- expect(subject[:mattermost_enabled]).to eq(Gitlab.config.mattermost.enabled)
- expect(subject[:signup_enabled]).to eq(Gitlab::CurrentSettings.allow_signup?)
- expect(subject[:ldap_enabled]).to eq(Gitlab.config.ldap.enabled)
- expect(subject[:gravatar_enabled]).to eq(Gitlab::CurrentSettings.gravatar_enabled?)
- expect(subject[:omniauth_enabled]).to eq(Gitlab::Auth.omniauth_enabled?)
- expect(subject[:reply_by_email_enabled]).to eq(Gitlab::IncomingEmail.enabled?)
- expect(subject[:container_registry_enabled]).to eq(Gitlab.config.registry.enabled)
- expect(subject[:dependency_proxy_enabled]).to eq(Gitlab.config.dependency_proxy.enabled)
- expect(subject[:gitlab_shared_runners_enabled]).to eq(Gitlab.config.gitlab_ci.shared_runners_enabled)
- expect(subject[:web_ide_clientside_preview_enabled]).to eq(Gitlab::CurrentSettings.web_ide_clientside_preview_enabled?)
- expect(subject[:grafana_link_enabled]).to eq(Gitlab::CurrentSettings.grafana_enabled?)
- end
+ describe '#license_usage_data' do
+ subject { described_class.license_usage_data }
- context 'with embedded grafana' do
- it 'returns true when embedded grafana is enabled' do
- stub_application_setting(grafana_enabled: true)
+ it 'gathers license data' do
+ expect(subject[:uuid]).to eq(Gitlab::CurrentSettings.uuid)
+ expect(subject[:version]).to eq(Gitlab::VERSION)
+ expect(subject[:installation_type]).to eq('gitlab-development-kit')
+ expect(subject[:active_user_count]).to eq(User.active.size)
+ expect(subject[:recorded_at]).to be_a(Time)
+ end
+ end
- expect(subject[:grafana_link_enabled]).to eq(true)
- end
+ describe '.recording_ce_finished_at' do
+ subject { described_class.recording_ce_finish_data }
+
+ it 'gathers time ce recording finishes at' do
+ expect(subject[:recording_ce_finished_at]).to be_a(Time)
+ end
+ end
- it 'returns false when embedded grafana is disabled' do
- stub_application_setting(grafana_enabled: false)
+ context 'when not relying on database records' do
+ describe '#features_usage_data_ce' do
+ subject { described_class.features_usage_data_ce }
+
+ it 'gathers feature usage data', :aggregate_failures do
+ expect(subject[:instance_auto_devops_enabled]).to eq(Gitlab::CurrentSettings.auto_devops_enabled?)
+ expect(subject[:mattermost_enabled]).to eq(Gitlab.config.mattermost.enabled)
+ expect(subject[:signup_enabled]).to eq(Gitlab::CurrentSettings.allow_signup?)
+ expect(subject[:ldap_enabled]).to eq(Gitlab.config.ldap.enabled)
+ expect(subject[:gravatar_enabled]).to eq(Gitlab::CurrentSettings.gravatar_enabled?)
+ expect(subject[:omniauth_enabled]).to eq(Gitlab::Auth.omniauth_enabled?)
+ expect(subject[:reply_by_email_enabled]).to eq(Gitlab::IncomingEmail.enabled?)
+ expect(subject[:container_registry_enabled]).to eq(Gitlab.config.registry.enabled)
+ expect(subject[:dependency_proxy_enabled]).to eq(Gitlab.config.dependency_proxy.enabled)
+ expect(subject[:gitlab_shared_runners_enabled]).to eq(Gitlab.config.gitlab_ci.shared_runners_enabled)
+ expect(subject[:web_ide_clientside_preview_enabled]).to eq(Gitlab::CurrentSettings.web_ide_clientside_preview_enabled?)
+ expect(subject[:grafana_link_enabled]).to eq(Gitlab::CurrentSettings.grafana_enabled?)
+ end
- expect(subject[:grafana_link_enabled]).to eq(false)
- end
+ context 'with embedded grafana' do
+ it 'returns true when embedded grafana is enabled' do
+ stub_application_setting(grafana_enabled: true)
+
+ expect(subject[:grafana_link_enabled]).to eq(true)
end
- end
- describe '#components_usage_data' do
- subject { described_class.components_usage_data }
-
- it 'gathers components usage data' do
- expect(Gitlab::UsageData).to receive(:app_server_type).and_return('server_type')
- expect(subject[:app_server][:type]).to eq('server_type')
- expect(subject[:gitlab_pages][:enabled]).to eq(Gitlab.config.pages.enabled)
- expect(subject[:gitlab_pages][:version]).to eq(Gitlab::Pages::VERSION)
- expect(subject[:git][:version]).to eq(Gitlab::Git.version)
- expect(subject[:database][:adapter]).to eq(Gitlab::Database.adapter_name)
- expect(subject[:database][:version]).to eq(Gitlab::Database.version)
- expect(subject[:gitaly][:version]).to be_present
- expect(subject[:gitaly][:servers]).to be >= 1
- expect(subject[:gitaly][:filesystems]).to be_an(Array)
- expect(subject[:gitaly][:filesystems].first).to be_a(String)
+ it 'returns false when embedded grafana is disabled' do
+ stub_application_setting(grafana_enabled: false)
+
+ expect(subject[:grafana_link_enabled]).to eq(false)
end
end
+ end
- describe '#app_server_type' do
- subject { described_class.app_server_type }
+ describe '#components_usage_data' do
+ subject { described_class.components_usage_data }
+
+ it 'gathers basic components usage data' do
+ stub_runtime(:puma)
+
+ expect(subject[:app_server][:type]).to eq('puma')
+ expect(subject[:gitlab_pages][:enabled]).to eq(Gitlab.config.pages.enabled)
+ expect(subject[:gitlab_pages][:version]).to eq(Gitlab::Pages::VERSION)
+ expect(subject[:git][:version]).to eq(Gitlab::Git.version)
+ expect(subject[:database][:adapter]).to eq(Gitlab::Database.adapter_name)
+ expect(subject[:database][:version]).to eq(Gitlab::Database.version)
+ expect(subject[:gitaly][:version]).to be_present
+ expect(subject[:gitaly][:servers]).to be >= 1
+ expect(subject[:gitaly][:clusters]).to be >= 0
+ expect(subject[:gitaly][:filesystems]).to be_an(Array)
+ expect(subject[:gitaly][:filesystems].first).to be_a(String)
+ end
- it 'successfully identifies runtime and returns the identifier' do
- expect(Gitlab::Runtime).to receive(:identify).and_return(:runtime_identifier)
+ def stub_runtime(runtime)
+ allow(Gitlab::Runtime).to receive(:identify).and_return(runtime)
+ end
+ end
- is_expected.to eq('runtime_identifier')
- end
+ describe '#app_server_type' do
+ subject { described_class.app_server_type }
- context 'when runtime is not identified' do
- let(:exception) { Gitlab::Runtime::IdentificationError.new('exception message from runtime identify') }
+ it 'successfully identifies runtime and returns the identifier' do
+ expect(Gitlab::Runtime).to receive(:identify).and_return(:runtime_identifier)
- it 'logs the exception and returns unknown app server type' do
- expect(Gitlab::Runtime).to receive(:identify).and_raise(exception)
+ is_expected.to eq('runtime_identifier')
+ end
- expect(Gitlab::AppLogger).to receive(:error).with(exception.message)
- expect(Gitlab::ErrorTracking).to receive(:track_exception).with(exception)
- expect(subject).to eq('unknown_app_server_type')
- end
+ context 'when runtime is not identified' do
+ let(:exception) { Gitlab::Runtime::IdentificationError.new('exception message from runtime identify') }
+
+ it 'logs the exception and returns unknown app server type' do
+ expect(Gitlab::Runtime).to receive(:identify).and_raise(exception)
+
+ expect(Gitlab::AppLogger).to receive(:error).with(exception.message)
+ expect(Gitlab::ErrorTracking).to receive(:track_exception).with(exception)
+ expect(subject).to eq('unknown_app_server_type')
end
end
+ end
- describe '#object_store_config' do
- let(:component) { 'lfs' }
+ describe '#object_store_config' do
+ let(:component) { 'lfs' }
- subject { described_class.object_store_config(component) }
+ subject { described_class.object_store_config(component) }
- context 'when object_store is not configured' do
- it 'returns component enable status only' do
- allow(Settings).to receive(:[]).with(component).and_return({ 'enabled' => false })
+ context 'when object_store is not configured' do
+ it 'returns component enable status only' do
+ allow(Settings).to receive(:[]).with(component).and_return({ 'enabled' => false })
- expect(subject).to eq({ enabled: false })
- end
+ expect(subject).to eq({ enabled: false })
end
+ end
- context 'when object_store is configured' do
- it 'returns filtered object store config' do
- allow(Settings).to receive(:[]).with(component)
- .and_return(
+ context 'when object_store is configured' do
+ it 'returns filtered object store config' do
+ allow(Settings).to receive(:[]).with(component)
+ .and_return(
+ { 'enabled' => true,
+ 'object_store' =>
{ 'enabled' => true,
- 'object_store' =>
- { 'enabled' => true,
- 'remote_directory' => component,
- 'direct_upload' => true,
- 'connection' =>
- { 'provider' => 'AWS', 'aws_access_key_id' => 'minio', 'aws_secret_access_key' => 'gdk-minio', 'region' => 'gdk', 'endpoint' => 'http://127.0.0.1:9000', 'path_style' => true },
- 'background_upload' => false,
- 'proxy_download' => false } })
-
- expect(subject).to eq(
- { enabled: true, object_store: { enabled: true, direct_upload: true, background_upload: false, provider: "AWS" } })
- end
+ 'remote_directory' => component,
+ 'direct_upload' => true,
+ 'connection' =>
+ { 'provider' => 'AWS', 'aws_access_key_id' => 'minio', 'aws_secret_access_key' => 'gdk-minio', 'region' => 'gdk', 'endpoint' => 'http://127.0.0.1:9000', 'path_style' => true },
+ 'background_upload' => false,
+ 'proxy_download' => false } })
+
+ expect(subject).to eq(
+ { enabled: true, object_store: { enabled: true, direct_upload: true, background_upload: false, provider: "AWS" } })
end
+ end
- context 'when retrieve component setting meets exception' do
- it 'returns -1 for component enable status' do
- allow(Settings).to receive(:[]).with(component).and_raise(StandardError)
+ context 'when retrieve component setting meets exception' do
+ it 'returns -1 for component enable status' do
+ allow(Settings).to receive(:[]).with(component).and_raise(StandardError)
- expect(subject).to eq({ enabled: -1 })
- end
+ expect(subject).to eq({ enabled: -1 })
end
end
+ end
- describe '#object_store_usage_data' do
- subject { described_class.object_store_usage_data }
-
- it 'fetches object store config of five components' do
- %w(artifacts external_diffs lfs uploads packages).each do |component|
- expect(described_class).to receive(:object_store_config).with(component).and_return("#{component}_object_store_config")
- end
+ describe '#object_store_usage_data' do
+ subject { described_class.object_store_usage_data }
- expect(subject).to eq(
- object_store: {
- artifacts: 'artifacts_object_store_config',
- external_diffs: 'external_diffs_object_store_config',
- lfs: 'lfs_object_store_config',
- uploads: 'uploads_object_store_config',
- packages: 'packages_object_store_config'
- })
+ it 'fetches object store config of five components' do
+ %w(artifacts external_diffs lfs uploads packages).each do |component|
+ expect(described_class).to receive(:object_store_config).with(component).and_return("#{component}_object_store_config")
end
+
+ expect(subject).to eq(
+ object_store: {
+ artifacts: 'artifacts_object_store_config',
+ external_diffs: 'external_diffs_object_store_config',
+ lfs: 'lfs_object_store_config',
+ uploads: 'uploads_object_store_config',
+ packages: 'packages_object_store_config'
+ })
end
+ end
- describe '#cycle_analytics_usage_data' do
- subject { described_class.cycle_analytics_usage_data }
+ describe '#cycle_analytics_usage_data' do
+ subject { described_class.cycle_analytics_usage_data }
- it 'works when queries time out in new' do
- allow(Gitlab::CycleAnalytics::UsageData)
- .to receive(:new).and_raise(ActiveRecord::StatementInvalid.new(''))
+ it 'works when queries time out in new' do
+ allow(Gitlab::CycleAnalytics::UsageData)
+ .to receive(:new).and_raise(ActiveRecord::StatementInvalid.new(''))
- expect { subject }.not_to raise_error
- end
+ expect { subject }.not_to raise_error
+ end
- it 'works when queries time out in to_json' do
- allow_any_instance_of(Gitlab::CycleAnalytics::UsageData)
- .to receive(:to_json).and_raise(ActiveRecord::StatementInvalid.new(''))
+ it 'works when queries time out in to_json' do
+ allow_any_instance_of(Gitlab::CycleAnalytics::UsageData)
+ .to receive(:to_json).and_raise(ActiveRecord::StatementInvalid.new(''))
- expect { subject }.not_to raise_error
+ expect { subject }.not_to raise_error
+ end
+ end
+
+ describe '#ingress_modsecurity_usage' do
+ subject { described_class.ingress_modsecurity_usage }
+
+ let(:environment) { create(:environment) }
+ let(:project) { environment.project }
+ let(:environment_scope) { '*' }
+ let(:deployment) { create(:deployment, :success, environment: environment, project: project, cluster: cluster) }
+ let(:cluster) { create(:cluster, environment_scope: environment_scope, projects: [project]) }
+ let(:ingress_mode) { :modsecurity_blocking }
+ let!(:ingress) { create(:clusters_applications_ingress, ingress_mode, cluster: cluster) }
+
+ context 'when cluster is disabled' do
+ let(:cluster) { create(:cluster, :disabled, projects: [project]) }
+
+ it 'gathers ingress data' do
+ expect(subject[:ingress_modsecurity_logging]).to eq(0)
+ expect(subject[:ingress_modsecurity_blocking]).to eq(0)
+ expect(subject[:ingress_modsecurity_disabled]).to eq(0)
+ expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
end
end
- describe '#ingress_modsecurity_usage' do
- subject { described_class.ingress_modsecurity_usage }
+ context 'when deployment is unsuccessful' do
+ let!(:deployment) { create(:deployment, :failed, environment: environment, project: project, cluster: cluster) }
- let(:environment) { create(:environment) }
- let(:project) { environment.project }
- let(:environment_scope) { '*' }
- let(:deployment) { create(:deployment, :success, environment: environment, project: project, cluster: cluster) }
- let(:cluster) { create(:cluster, environment_scope: environment_scope, projects: [project]) }
- let(:ingress_mode) { :modsecurity_blocking }
- let!(:ingress) { create(:clusters_applications_ingress, ingress_mode, cluster: cluster) }
+ it 'gathers ingress data' do
+ expect(subject[:ingress_modsecurity_logging]).to eq(0)
+ expect(subject[:ingress_modsecurity_blocking]).to eq(0)
+ expect(subject[:ingress_modsecurity_disabled]).to eq(0)
+ expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
+ end
+ end
- context 'when cluster is disabled' do
- let(:cluster) { create(:cluster, :disabled, projects: [project]) }
+ context 'when deployment is successful' do
+ let!(:deployment) { create(:deployment, :success, environment: environment, project: project, cluster: cluster) }
+ context 'when modsecurity is in blocking mode' do
it 'gathers ingress data' do
expect(subject[:ingress_modsecurity_logging]).to eq(0)
- expect(subject[:ingress_modsecurity_blocking]).to eq(0)
+ expect(subject[:ingress_modsecurity_blocking]).to eq(1)
expect(subject[:ingress_modsecurity_disabled]).to eq(0)
expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
end
end
- context 'when deployment is unsuccessful' do
- let!(:deployment) { create(:deployment, :failed, environment: environment, project: project, cluster: cluster) }
+ context 'when modsecurity is in logging mode' do
+ let(:ingress_mode) { :modsecurity_logging }
it 'gathers ingress data' do
- expect(subject[:ingress_modsecurity_logging]).to eq(0)
+ expect(subject[:ingress_modsecurity_logging]).to eq(1)
expect(subject[:ingress_modsecurity_blocking]).to eq(0)
expect(subject[:ingress_modsecurity_disabled]).to eq(0)
expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
end
end
- context 'when deployment is successful' do
- let!(:deployment) { create(:deployment, :success, environment: environment, project: project, cluster: cluster) }
+ context 'when modsecurity is disabled' do
+ let(:ingress_mode) { :modsecurity_disabled }
- context 'when modsecurity is in blocking mode' do
- it 'gathers ingress data' do
- expect(subject[:ingress_modsecurity_logging]).to eq(0)
- expect(subject[:ingress_modsecurity_blocking]).to eq(1)
- expect(subject[:ingress_modsecurity_disabled]).to eq(0)
- expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
- end
+ it 'gathers ingress data' do
+ expect(subject[:ingress_modsecurity_logging]).to eq(0)
+ expect(subject[:ingress_modsecurity_blocking]).to eq(0)
+ expect(subject[:ingress_modsecurity_disabled]).to eq(1)
+ expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
end
+ end
- context 'when modsecurity is in logging mode' do
- let(:ingress_mode) { :modsecurity_logging }
+ context 'when modsecurity is not installed' do
+ let(:ingress_mode) { :modsecurity_not_installed }
- it 'gathers ingress data' do
- expect(subject[:ingress_modsecurity_logging]).to eq(1)
- expect(subject[:ingress_modsecurity_blocking]).to eq(0)
- expect(subject[:ingress_modsecurity_disabled]).to eq(0)
- expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
- end
+ it 'gathers ingress data' do
+ expect(subject[:ingress_modsecurity_logging]).to eq(0)
+ expect(subject[:ingress_modsecurity_blocking]).to eq(0)
+ expect(subject[:ingress_modsecurity_disabled]).to eq(0)
+ expect(subject[:ingress_modsecurity_not_installed]).to eq(1)
end
+ end
- context 'when modsecurity is disabled' do
- let(:ingress_mode) { :modsecurity_disabled }
+ context 'with multiple projects' do
+ let(:environment_2) { create(:environment) }
+ let(:project_2) { environment_2.project }
+ let(:cluster_2) { create(:cluster, environment_scope: environment_scope, projects: [project_2]) }
+ let!(:ingress_2) { create(:clusters_applications_ingress, :modsecurity_logging, cluster: cluster_2) }
+ let!(:deployment_2) { create(:deployment, :success, environment: environment_2, project: project_2, cluster: cluster_2) }
- it 'gathers ingress data' do
- expect(subject[:ingress_modsecurity_logging]).to eq(0)
- expect(subject[:ingress_modsecurity_blocking]).to eq(0)
- expect(subject[:ingress_modsecurity_disabled]).to eq(1)
- expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
- end
+ it 'gathers non-duplicated ingress data' do
+ expect(subject[:ingress_modsecurity_logging]).to eq(1)
+ expect(subject[:ingress_modsecurity_blocking]).to eq(1)
+ expect(subject[:ingress_modsecurity_disabled]).to eq(0)
+ expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
end
+ end
- context 'when modsecurity is not installed' do
- let(:ingress_mode) { :modsecurity_not_installed }
-
- it 'gathers ingress data' do
- expect(subject[:ingress_modsecurity_logging]).to eq(0)
- expect(subject[:ingress_modsecurity_blocking]).to eq(0)
- expect(subject[:ingress_modsecurity_disabled]).to eq(0)
- expect(subject[:ingress_modsecurity_not_installed]).to eq(1)
- end
- end
+ context 'with multiple deployments' do
+ let!(:deployment_2) { create(:deployment, :success, environment: environment, project: project, cluster: cluster) }
- context 'with multiple projects' do
- let(:environment_2) { create(:environment) }
- let(:project_2) { environment_2.project }
- let(:cluster_2) { create(:cluster, environment_scope: environment_scope, projects: [project_2]) }
- let!(:ingress_2) { create(:clusters_applications_ingress, :modsecurity_logging, cluster: cluster_2) }
- let!(:deployment_2) { create(:deployment, :success, environment: environment_2, project: project_2, cluster: cluster_2) }
-
- it 'gathers non-duplicated ingress data' do
- expect(subject[:ingress_modsecurity_logging]).to eq(1)
- expect(subject[:ingress_modsecurity_blocking]).to eq(1)
- expect(subject[:ingress_modsecurity_disabled]).to eq(0)
- expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
- end
+ it 'gathers non-duplicated ingress data' do
+ expect(subject[:ingress_modsecurity_logging]).to eq(0)
+ expect(subject[:ingress_modsecurity_blocking]).to eq(1)
+ expect(subject[:ingress_modsecurity_disabled]).to eq(0)
+ expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
end
+ end
- context 'with multiple deployments' do
- let!(:deployment_2) { create(:deployment, :success, environment: environment, project: project, cluster: cluster) }
-
- it 'gathers non-duplicated ingress data' do
- expect(subject[:ingress_modsecurity_logging]).to eq(0)
- expect(subject[:ingress_modsecurity_blocking]).to eq(1)
- expect(subject[:ingress_modsecurity_disabled]).to eq(0)
- expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
- end
- end
+ context 'with multiple projects' do
+ let(:environment_2) { create(:environment) }
+ let(:project_2) { environment_2.project }
+ let!(:deployment_2) { create(:deployment, :success, environment: environment_2, project: project_2, cluster: cluster) }
+ let(:cluster) { create(:cluster, environment_scope: environment_scope, projects: [project, project_2]) }
- context 'with multiple projects' do
- let(:environment_2) { create(:environment) }
- let(:project_2) { environment_2.project }
- let!(:deployment_2) { create(:deployment, :success, environment: environment_2, project: project_2, cluster: cluster) }
- let(:cluster) { create(:cluster, environment_scope: environment_scope, projects: [project, project_2]) }
-
- it 'gathers ingress data' do
- expect(subject[:ingress_modsecurity_logging]).to eq(0)
- expect(subject[:ingress_modsecurity_blocking]).to eq(2)
- expect(subject[:ingress_modsecurity_disabled]).to eq(0)
- expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
- end
+ it 'gathers ingress data' do
+ expect(subject[:ingress_modsecurity_logging]).to eq(0)
+ expect(subject[:ingress_modsecurity_blocking]).to eq(2)
+ expect(subject[:ingress_modsecurity_disabled]).to eq(0)
+ expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
end
+ end
- context 'with multiple environments' do
- let!(:environment_2) { create(:environment, project: project) }
- let!(:deployment_2) { create(:deployment, :success, environment: environment_2, project: project, cluster: cluster) }
+ context 'with multiple environments' do
+ let!(:environment_2) { create(:environment, project: project) }
+ let!(:deployment_2) { create(:deployment, :success, environment: environment_2, project: project, cluster: cluster) }
- it 'gathers ingress data' do
- expect(subject[:ingress_modsecurity_logging]).to eq(0)
- expect(subject[:ingress_modsecurity_blocking]).to eq(2)
- expect(subject[:ingress_modsecurity_disabled]).to eq(0)
- expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
- end
+ it 'gathers ingress data' do
+ expect(subject[:ingress_modsecurity_logging]).to eq(0)
+ expect(subject[:ingress_modsecurity_blocking]).to eq(2)
+ expect(subject[:ingress_modsecurity_disabled]).to eq(0)
+ expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
end
end
end
+ end
- describe '#grafana_embed_usage_data' do
- subject { described_class.grafana_embed_usage_data }
+ describe '#grafana_embed_usage_data' do
+ subject { described_class.grafana_embed_usage_data }
- let(:project) { create(:project) }
- let(:description_with_embed) { "Some comment\n\nhttps://grafana.example.com/d/xvAk4q0Wk/go-processes?orgId=1&from=1573238522762&to=1573240322762&var-job=prometheus&var-interval=10m&panelId=1&fullscreen" }
- let(:description_with_unintegrated_embed) { "Some comment\n\nhttps://grafana.exp.com/d/xvAk4q0Wk/go-processes?orgId=1&from=1573238522762&to=1573240322762&var-job=prometheus&var-interval=10m&panelId=1&fullscreen" }
- let(:description_with_non_grafana_inline_metric) { "Some comment\n\n#{Gitlab::Routing.url_helpers.metrics_namespace_project_environment_url(*['foo', 'bar', 12])}" }
+ let(:project) { create(:project) }
+ let(:description_with_embed) { "Some comment\n\nhttps://grafana.example.com/d/xvAk4q0Wk/go-processes?orgId=1&from=1573238522762&to=1573240322762&var-job=prometheus&var-interval=10m&panelId=1&fullscreen" }
+ let(:description_with_unintegrated_embed) { "Some comment\n\nhttps://grafana.exp.com/d/xvAk4q0Wk/go-processes?orgId=1&from=1573238522762&to=1573240322762&var-job=prometheus&var-interval=10m&panelId=1&fullscreen" }
+ let(:description_with_non_grafana_inline_metric) { "Some comment\n\n#{Gitlab::Routing.url_helpers.metrics_namespace_project_environment_url(*['foo', 'bar', 12])}" }
- shared_examples "zero count" do
- it "does not count the issue" do
- expect(subject).to eq(0)
- end
+ shared_examples "zero count" do
+ it "does not count the issue" do
+ expect(subject).to eq(0)
end
+ end
- context 'with project grafana integration enabled' do
- before do
- create(:grafana_integration, project: project, enabled: true)
- end
-
- context 'with valid and invalid embeds' do
- before do
- # Valid
- create(:issue, project: project, description: description_with_embed)
- create(:issue, project: project, description: description_with_embed)
- # In-Valid
- create(:issue, project: project, description: description_with_unintegrated_embed)
- create(:issue, project: project, description: description_with_non_grafana_inline_metric)
- create(:issue, project: project, description: nil)
- create(:issue, project: project, description: '')
- create(:issue, project: project)
- end
-
- it 'counts only the issues with embeds' do
- expect(subject).to eq(2)
- end
- end
+ context 'with project grafana integration enabled' do
+ before do
+ create(:grafana_integration, project: project, enabled: true)
end
- context 'with project grafana integration disabled' do
+ context 'with valid and invalid embeds' do
before do
- create(:grafana_integration, project: project, enabled: false)
- end
-
- context 'with one issue having a grafana link in the description and one without' do
- before do
- create(:issue, project: project, description: description_with_embed)
- create(:issue, project: project)
- end
-
- it_behaves_like('zero count')
+ # Valid
+ create(:issue, project: project, description: description_with_embed)
+ create(:issue, project: project, description: description_with_embed)
+ # In-Valid
+ create(:issue, project: project, description: description_with_unintegrated_embed)
+ create(:issue, project: project, description: description_with_non_grafana_inline_metric)
+ create(:issue, project: project, description: nil)
+ create(:issue, project: project, description: '')
+ create(:issue, project: project)
end
- end
-
- context 'with an un-integrated project' do
- context 'with one issue having a grafana link in the description and one without' do
- before do
- create(:issue, project: project, description: description_with_embed)
- create(:issue, project: project)
- end
- it_behaves_like('zero count')
+ it 'counts only the issues with embeds' do
+ expect(subject).to eq(2)
end
end
end
- describe '#count' do
- let(:relation) { double(:relation) }
-
- it 'returns the count when counting succeeds' do
- allow(relation).to receive(:count).and_return(1)
-
- expect(described_class.count(relation, batch: false)).to eq(1)
+ context 'with project grafana integration disabled' do
+ before do
+ create(:grafana_integration, project: project, enabled: false)
end
- it 'returns the fallback value when counting fails' do
- stub_const("Gitlab::UsageData::FALLBACK", 15)
- allow(relation).to receive(:count).and_raise(ActiveRecord::StatementInvalid.new(''))
+ context 'with one issue having a grafana link in the description and one without' do
+ before do
+ create(:issue, project: project, description: description_with_embed)
+ create(:issue, project: project)
+ end
- expect(described_class.count(relation, batch: false)).to eq(15)
+ it_behaves_like('zero count')
end
end
- describe '#distinct_count' do
- let(:relation) { double(:relation) }
-
- it 'returns the count when counting succeeds' do
- allow(relation).to receive(:distinct_count_by).and_return(1)
-
- expect(described_class.distinct_count(relation, batch: false)).to eq(1)
- end
-
- it 'returns the fallback value when counting fails' do
- stub_const("Gitlab::UsageData::FALLBACK", 15)
- allow(relation).to receive(:distinct_count_by).and_raise(ActiveRecord::StatementInvalid.new(''))
+ context 'with an un-integrated project' do
+ context 'with one issue having a grafana link in the description and one without' do
+ before do
+ create(:issue, project: project, description: description_with_embed)
+ create(:issue, project: project)
+ end
- expect(described_class.distinct_count(relation, batch: false)).to eq(15)
+ it_behaves_like('zero count')
end
end
end
end
- context 'when usage usage_ping_batch_counter is true' do
- before do
- stub_feature_flags(usage_ping_batch_counter: true)
- end
-
- it_behaves_like 'usage data execution'
- end
+ describe '#merge_requests_usage' do
+ let(:time_period) { { created_at: 2.days.ago..Time.current } }
+ let(:merge_request) { create(:merge_request) }
+ let(:other_user) { create(:user) }
+ let(:another_user) { create(:user) }
- context 'when usage usage_ping_batch_counter is false' do
before do
- stub_feature_flags(usage_ping_batch_counter: false)
- end
-
- it_behaves_like 'usage data execution'
- end
-
- describe '#alt_usage_data' do
- it 'returns the fallback when it gets an error' do
- expect(described_class.alt_usage_data { raise StandardError } ).to eq(-1)
- end
-
- it 'returns the evaluated block when give' do
- expect(described_class.alt_usage_data { Gitlab::CurrentSettings.uuid } ).to eq(Gitlab::CurrentSettings.uuid)
+ create(:event, target: merge_request, author: merge_request.author, created_at: 1.day.ago)
+ create(:event, target: merge_request, author: merge_request.author, created_at: 1.hour.ago)
+ create(:event, target: merge_request, author: merge_request.author, created_at: 3.days.ago)
+ create(:event, target: merge_request, author: other_user, created_at: 1.day.ago)
+ create(:event, target: merge_request, author: other_user, created_at: 1.hour.ago)
+ create(:event, target: merge_request, author: other_user, created_at: 3.days.ago)
+ create(:event, target: merge_request, author: another_user, created_at: 4.days.ago)
end
- it 'returns the value when given' do
- expect(described_class.alt_usage_data(1)).to eq 1
- end
- end
-
- describe '#redis_usage_data' do
- context 'with block given' do
- it 'returns the fallback when it gets an error' do
- expect(described_class.redis_usage_data { raise ::Redis::CommandError } ).to eq(-1)
- end
-
- it 'returns the evaluated block when given' do
- expect(described_class.redis_usage_data { 1 }).to eq(1)
- end
- end
-
- context 'with counter given' do
- it 'returns the falback values for all counter keys when it gets an error' do
- allow(::Gitlab::UsageDataCounters::WikiPageCounter).to receive(:totals).and_raise(::Redis::CommandError)
- expect(described_class.redis_usage_data(::Gitlab::UsageDataCounters::WikiPageCounter)).to eql(::Gitlab::UsageDataCounters::WikiPageCounter.fallback_totals)
- end
-
- it 'returns the totals when couter is given' do
- allow(::Gitlab::UsageDataCounters::WikiPageCounter).to receive(:totals).and_return({ wiki_pages_create: 2 })
- expect(described_class.redis_usage_data(::Gitlab::UsageDataCounters::WikiPageCounter)).to eql({ wiki_pages_create: 2 })
- end
+ it 'returns the distinct count of users using merge requests (via events table) within the specified time period' do
+ expect(described_class.merge_requests_usage(time_period)).to eq(
+ merge_requests_users: 2
+ )
end
end
end
diff --git a/spec/lib/gitlab/utils/usage_data_spec.rb b/spec/lib/gitlab/utils/usage_data_spec.rb
new file mode 100644
index 00000000000..7de615384c5
--- /dev/null
+++ b/spec/lib/gitlab/utils/usage_data_spec.rb
@@ -0,0 +1,111 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Utils::UsageData do
+ describe '#count' do
+ let(:relation) { double(:relation) }
+
+ it 'returns the count when counting succeeds' do
+ allow(relation).to receive(:count).and_return(1)
+
+ expect(described_class.count(relation, batch: false)).to eq(1)
+ end
+
+ it 'returns the fallback value when counting fails' do
+ stub_const("Gitlab::Utils::UsageData::FALLBACK", 15)
+ allow(relation).to receive(:count).and_raise(ActiveRecord::StatementInvalid.new(''))
+
+ expect(described_class.count(relation, batch: false)).to eq(15)
+ end
+ end
+
+ describe '#distinct_count' do
+ let(:relation) { double(:relation) }
+
+ it 'returns the count when counting succeeds' do
+ allow(relation).to receive(:distinct_count_by).and_return(1)
+
+ expect(described_class.distinct_count(relation, batch: false)).to eq(1)
+ end
+
+ it 'returns the fallback value when counting fails' do
+ stub_const("Gitlab::Utils::UsageData::FALLBACK", 15)
+ allow(relation).to receive(:distinct_count_by).and_raise(ActiveRecord::StatementInvalid.new(''))
+
+ expect(described_class.distinct_count(relation, batch: false)).to eq(15)
+ end
+ end
+
+ describe '#alt_usage_data' do
+ it 'returns the fallback when it gets an error' do
+ expect(described_class.alt_usage_data { raise StandardError } ).to eq(-1)
+ end
+
+ it 'returns the evaluated block when give' do
+ expect(described_class.alt_usage_data { Gitlab::CurrentSettings.uuid } ).to eq(Gitlab::CurrentSettings.uuid)
+ end
+
+ it 'returns the value when given' do
+ expect(described_class.alt_usage_data(1)).to eq 1
+ end
+ end
+
+ describe '#redis_usage_data' do
+ context 'with block given' do
+ it 'returns the fallback when it gets an error' do
+ expect(described_class.redis_usage_data { raise ::Redis::CommandError } ).to eq(-1)
+ end
+
+ it 'returns the evaluated block when given' do
+ expect(described_class.redis_usage_data { 1 }).to eq(1)
+ end
+ end
+
+ context 'with counter given' do
+ it 'returns the falback values for all counter keys when it gets an error' do
+ allow(::Gitlab::UsageDataCounters::WikiPageCounter).to receive(:totals).and_raise(::Redis::CommandError)
+ expect(described_class.redis_usage_data(::Gitlab::UsageDataCounters::WikiPageCounter)).to eql(::Gitlab::UsageDataCounters::WikiPageCounter.fallback_totals)
+ end
+
+ it 'returns the totals when couter is given' do
+ allow(::Gitlab::UsageDataCounters::WikiPageCounter).to receive(:totals).and_return({ wiki_pages_create: 2 })
+ expect(described_class.redis_usage_data(::Gitlab::UsageDataCounters::WikiPageCounter)).to eql({ wiki_pages_create: 2 })
+ end
+ end
+ end
+
+ describe '#with_prometheus_client' do
+ context 'when Prometheus is enabled' do
+ it 'yields a client instance and returns the block result' do
+ expect(Gitlab::Prometheus::Internal).to receive(:prometheus_enabled?).and_return(true)
+ expect(Gitlab::Prometheus::Internal).to receive(:uri).and_return('http://prom:9090')
+
+ result = described_class.with_prometheus_client { |client| client }
+
+ expect(result).to be_an_instance_of(Gitlab::PrometheusClient)
+ end
+ end
+
+ context 'when Prometheus is disabled' do
+ it 'returns nil' do
+ expect(Gitlab::Prometheus::Internal).to receive(:prometheus_enabled?).and_return(false)
+
+ result = described_class.with_prometheus_client { |client| client }
+
+ expect(result).to be nil
+ end
+ end
+ end
+
+ describe '#measure_duration' do
+ it 'returns block result and execution duration' do
+ allow(Process).to receive(:clock_gettime).and_return(1, 3)
+
+ result, duration = described_class.measure_duration { 42 }
+
+ expect(result).to eq(42)
+ expect(duration).to eq(2)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/utils_spec.rb b/spec/lib/gitlab/utils_spec.rb
index 0f0d6a93c97..3a2430d1f2d 100644
--- a/spec/lib/gitlab/utils_spec.rb
+++ b/spec/lib/gitlab/utils_spec.rb
@@ -345,4 +345,17 @@ describe Gitlab::Utils do
expect(described_class.parse_url(1)).to be nil
end
end
+
+ describe 'multiple_key_invert' do
+ it 'invert keys with array values' do
+ hash = {
+ dast: [:vulnerabilities_count, :scanned_resources_count],
+ sast: [:vulnerabilities_count]
+ }
+ expect(described_class.multiple_key_invert(hash)).to eq({
+ vulnerabilities_count: [:dast, :sast],
+ scanned_resources_count: [:dast]
+ })
+ end
+ end
end
diff --git a/spec/lib/gitlab/web_ide/config/entry/global_spec.rb b/spec/lib/gitlab/web_ide/config/entry/global_spec.rb
new file mode 100644
index 00000000000..04b0752c6fe
--- /dev/null
+++ b/spec/lib/gitlab/web_ide/config/entry/global_spec.rb
@@ -0,0 +1,164 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::WebIde::Config::Entry::Global do
+ let(:global) { described_class.new(hash) }
+
+ describe '.nodes' do
+ it 'returns a hash' do
+ expect(described_class.nodes).to be_a(Hash)
+ end
+
+ context 'when filtering all the entry/node names' do
+ it 'contains the expected node names' do
+ expect(described_class.nodes.keys)
+ .to match_array(%i[terminal])
+ end
+ end
+ end
+
+ context 'when configuration is valid' do
+ context 'when some entries defined' do
+ let(:hash) do
+ { terminal: { before_script: ['ls'], variables: {}, script: 'sleep 10s', services: ['mysql'] } }
+ end
+
+ describe '#compose!' do
+ before do
+ global.compose!
+ end
+
+ it 'creates nodes hash' do
+ expect(global.descendants).to be_an Array
+ end
+
+ it 'creates node object for each entry' do
+ expect(global.descendants.count).to eq 1
+ end
+
+ it 'creates node object using valid class' do
+ expect(global.descendants.first)
+ .to be_an_instance_of Gitlab::WebIde::Config::Entry::Terminal
+ end
+
+ it 'sets correct description for nodes' do
+ expect(global.descendants.first.description)
+ .to eq 'Configuration of the webide terminal.'
+ end
+
+ describe '#leaf?' do
+ it 'is not leaf' do
+ expect(global).not_to be_leaf
+ end
+ end
+ end
+
+ context 'when not composed' do
+ describe '#terminal_value' do
+ it 'returns nil' do
+ expect(global.terminal_value).to be nil
+ end
+ end
+
+ describe '#leaf?' do
+ it 'is leaf' do
+ expect(global).to be_leaf
+ end
+ end
+ end
+
+ context 'when composed' do
+ before do
+ global.compose!
+ end
+
+ describe '#errors' do
+ it 'has no errors' do
+ expect(global.errors).to be_empty
+ end
+ end
+
+ describe '#terminal_value' do
+ it 'returns correct script' do
+ expect(global.terminal_value).to eq({
+ tag_list: [],
+ yaml_variables: [],
+ options: {
+ before_script: ['ls'],
+ script: ['sleep 10s'],
+ services: [{ name: "mysql" }]
+ }
+ })
+ end
+ end
+ end
+ end
+ end
+
+ context 'when configuration is not valid' do
+ before do
+ global.compose!
+ end
+
+ context 'when job does not have valid before script' do
+ let(:hash) do
+ { terminal: { before_script: 100 } }
+ end
+
+ describe '#errors' do
+ it 'reports errors about missing script' do
+ expect(global.errors)
+ .to include "terminal:before_script config should be an array containing strings and arrays of strings"
+ end
+ end
+ end
+ end
+
+ context 'when value is not a hash' do
+ let(:hash) { [] }
+
+ describe '#valid?' do
+ it 'is not valid' do
+ expect(global).not_to be_valid
+ end
+ end
+
+ describe '#errors' do
+ it 'returns error about invalid type' do
+ expect(global.errors.first).to match /should be a hash/
+ end
+ end
+ end
+
+ describe '#specified?' do
+ it 'is concrete entry that is defined' do
+ expect(global.specified?).to be true
+ end
+ end
+
+ describe '#[]' do
+ before do
+ global.compose!
+ end
+
+ let(:hash) do
+ { terminal: { before_script: ['ls'] } }
+ end
+
+ context 'when entry exists' do
+ it 'returns correct entry' do
+ expect(global[:terminal])
+ .to be_an_instance_of Gitlab::WebIde::Config::Entry::Terminal
+ expect(global[:terminal][:before_script].value).to eq ['ls']
+ end
+ end
+
+ context 'when entry does not exist' do
+ it 'always return unspecified node' do
+ expect(global[:some][:unknown][:node])
+ .not_to be_specified
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/web_ide/config/entry/terminal_spec.rb b/spec/lib/gitlab/web_ide/config/entry/terminal_spec.rb
new file mode 100644
index 00000000000..882e389e040
--- /dev/null
+++ b/spec/lib/gitlab/web_ide/config/entry/terminal_spec.rb
@@ -0,0 +1,156 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::WebIde::Config::Entry::Terminal do
+ let(:entry) { described_class.new(config, with_image_ports: true) }
+
+ describe '.nodes' do
+ context 'when filtering all the entry/node names' do
+ subject { described_class.nodes.keys }
+
+ let(:result) do
+ %i[before_script script image services variables]
+ end
+
+ it { is_expected.to match_array result }
+ end
+ end
+
+ describe 'validations' do
+ before do
+ entry.compose!
+ end
+
+ context 'when entry config value is correct' do
+ let(:config) { { script: 'rspec' } }
+
+ describe '#valid?' do
+ it 'is valid' do
+ expect(entry).to be_valid
+ end
+ end
+
+ context 'when the same port is not duplicated' do
+ let(:config) do
+ {
+ image: { name: "ruby", ports: [80] },
+ services: [{ name: "mysql", alias: "service1", ports: [81] }, { name: "mysql", alias: "service2", ports: [82] }]
+ }
+ end
+
+ describe '#valid?' do
+ it 'is valid' do
+ expect(entry).to be_valid
+ end
+ end
+ end
+
+ context 'when unknown port keys detected' do
+ let(:config) do
+ {
+ image: { name: "ruby", ports: [80] },
+ services: [{ name: "mysql", alias: "service2", ports: [{ number: 81, invalid_key: 'foobar' }] }]
+ }
+ end
+
+ it 'is not valid' do
+ expect(entry).not_to be_valid
+ expect(entry.errors.first)
+ .to match /port config contains unknown keys: invalid_key/
+ end
+ end
+ end
+
+ context 'when entry value is not correct' do
+ context 'incorrect config value type' do
+ let(:config) { ['incorrect'] }
+
+ describe '#errors' do
+ it 'reports error about a config type' do
+ expect(entry.errors)
+ .to include 'terminal config should be a hash'
+ end
+ end
+ end
+
+ context 'when config is empty' do
+ let(:config) { {} }
+
+ describe '#valid' do
+ it 'is valid' do
+ expect(entry).to be_valid
+ end
+ end
+ end
+
+ context 'when unknown keys detected' do
+ let(:config) { { unknown: true } }
+
+ describe '#valid' do
+ it 'is not valid' do
+ expect(entry).not_to be_valid
+ end
+ end
+ end
+
+ context 'when the same port is duplicated' do
+ let(:config) do
+ {
+ image: { name: "ruby", ports: [80] },
+ services: [{ name: "mysql", ports: [80] }, { name: "mysql", ports: [81] }]
+ }
+ end
+
+ describe '#valid?' do
+ it 'is invalid' do
+ expect(entry).not_to be_valid
+ expect(entry.errors.count).to eq 1
+ expect(entry.errors.first).to match "each port number can only be referenced once"
+ end
+ end
+ end
+ end
+ end
+
+ describe '#relevant?' do
+ it 'is a relevant entry' do
+ entry = described_class.new({ script: 'rspec' })
+
+ expect(entry).to be_relevant
+ end
+ end
+
+ context 'when composed' do
+ before do
+ entry.compose!
+ end
+
+ describe '#value' do
+ context 'when entry is correct' do
+ let(:config) do
+ { before_script: %w[ls pwd],
+ script: 'sleep 100',
+ tags: ['webide'],
+ image: 'ruby:2.5',
+ services: ['mysql'],
+ variables: { KEY: 'value' } }
+ end
+
+ it 'returns correct value' do
+ expect(entry.value)
+ .to eq(
+ tag_list: ['webide'],
+ yaml_variables: [{ key: 'KEY', value: 'value', public: true }],
+ options: {
+ image: { name: "ruby:2.5" },
+ services: [{ name: "mysql" }],
+ before_script: %w[ls pwd],
+ script: ['sleep 100']
+ }
+ )
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/web_ide/config_spec.rb b/spec/lib/gitlab/web_ide/config_spec.rb
new file mode 100644
index 00000000000..c1dafd01197
--- /dev/null
+++ b/spec/lib/gitlab/web_ide/config_spec.rb
@@ -0,0 +1,78 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::WebIde::Config do
+ let(:config) do
+ described_class.new(yml)
+ end
+
+ context 'when config is valid' do
+ let(:yml) do
+ <<-EOS
+ terminal:
+ image: ruby:2.7
+ before_script:
+ - gem install rspec
+ EOS
+ end
+
+ describe '#to_hash' do
+ it 'returns hash created from string' do
+ hash = {
+ terminal: {
+ image: 'ruby:2.7',
+ before_script: ['gem install rspec']
+ }
+ }
+
+ expect(config.to_hash).to eq hash
+ end
+
+ describe '#valid?' do
+ it 'is valid' do
+ expect(config).to be_valid
+ end
+
+ it 'has no errors' do
+ expect(config.errors).to be_empty
+ end
+ end
+ end
+ end
+
+ context 'when config is invalid' do
+ context 'when yml is incorrect' do
+ let(:yml) { '// invalid' }
+
+ describe '.new' do
+ it 'raises error' do
+ expect { config }.to raise_error(
+ described_class::ConfigError,
+ /Invalid configuration format/
+ )
+ end
+ end
+ end
+
+ context 'when config logic is incorrect' do
+ let(:yml) { 'terminal: { before_script: "ls" }' }
+
+ describe '#valid?' do
+ it 'is not valid' do
+ expect(config).not_to be_valid
+ end
+
+ it 'has errors' do
+ expect(config.errors).not_to be_empty
+ end
+ end
+
+ describe '#errors' do
+ it 'returns an array of strings' do
+ expect(config.errors).to all(be_an_instance_of(String))
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/wiki_pages/front_matter_parser_spec.rb b/spec/lib/gitlab/wiki_pages/front_matter_parser_spec.rb
index f9ed769f2d9..01701589e63 100644
--- a/spec/lib/gitlab/wiki_pages/front_matter_parser_spec.rb
+++ b/spec/lib/gitlab/wiki_pages/front_matter_parser_spec.rb
@@ -7,7 +7,7 @@ describe Gitlab::WikiPages::FrontMatterParser do
let(:content) { 'This is the content' }
let(:end_divider) { '---' }
- let(:gate) { double('Gate') }
+ let(:gate) { stub_feature_flag_gate('Gate') }
let(:with_front_matter) do
<<~MD
diff --git a/spec/lib/gitlab_spec.rb b/spec/lib/gitlab_spec.rb
index 9362ff72fbc..84d072a50ec 100644
--- a/spec/lib/gitlab_spec.rb
+++ b/spec/lib/gitlab_spec.rb
@@ -96,6 +96,28 @@ describe Gitlab do
end
end
+ describe '.staging?' do
+ subject { described_class.staging? }
+
+ it 'is false when on GitLab.com' do
+ stub_config_setting(url: 'https://gitlab.com')
+
+ expect(subject).to eq false
+ end
+
+ it 'is true when on staging' do
+ stub_config_setting(url: 'https://staging.gitlab.com')
+
+ expect(subject).to eq true
+ end
+
+ it 'is false when not on staging' do
+ stub_config_setting(url: 'https://example.gitlab.com')
+
+ expect(subject).to eq false
+ end
+ end
+
describe '.canary?' do
it 'is true when CANARY env var is set to true' do
stub_env('CANARY', '1')
@@ -186,6 +208,26 @@ describe Gitlab do
end
end
+ describe '.dev_or_test_env?' do
+ subject { described_class.dev_or_test_env? }
+
+ it 'is true when test env' do
+ expect(subject).to eq true
+ end
+
+ it 'is true when dev env' do
+ allow(Rails).to receive(:env).and_return(ActiveSupport::StringInquirer.new('development'))
+
+ expect(subject).to eq true
+ end
+
+ it 'is false when env is not dev or test' do
+ allow(Rails).to receive(:env).and_return(ActiveSupport::StringInquirer.new('production'))
+
+ expect(subject).to eq false
+ end
+ end
+
describe '.ee?' do
before do
stub_env('FOSS_ONLY', nil) # Make sure the ENV is clean
diff --git a/spec/lib/milestone_array_spec.rb b/spec/lib/milestone_array_spec.rb
deleted file mode 100644
index 375cb87dde6..00000000000
--- a/spec/lib/milestone_array_spec.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe MilestoneArray do
- let(:object1) { instance_double("BirdMilestone", due_date: Time.now, start_date: Time.now - 15.days, title: 'v2.0') }
- let(:object2) { instance_double("CatMilestone", due_date: Time.now - 1.day, start_date: nil, title: 'v1.0') }
- let(:object3) { instance_double("DogMilestone", due_date: nil, start_date: Time.now - 30.days, title: 'v3.0') }
- let(:array) { [object1, object3, object2] }
-
- describe '#sort' do
- it 'reorders array with due date in ascending order with nulls last' do
- expect(described_class.sort(array, 'due_date_asc')).to eq([object2, object1, object3])
- end
-
- it 'reorders array with due date in desc order with nulls last' do
- expect(described_class.sort(array, 'due_date_desc')).to eq([object1, object2, object3])
- end
-
- it 'reorders array with start date in ascending order with nulls last' do
- expect(described_class.sort(array, 'start_date_asc')).to eq([object3, object1, object2])
- end
-
- it 'reorders array with start date in descending order with nulls last' do
- expect(described_class.sort(array, 'start_date_desc')).to eq([object1, object3, object2])
- end
-
- it 'reorders array with title in ascending order' do
- expect(described_class.sort(array, 'name_asc')).to eq([object2, object1, object3])
- end
-
- it 'reorders array with title in descending order' do
- expect(described_class.sort(array, 'name_desc')).to eq([object3, object1, object2])
- end
- end
-end
diff --git a/spec/lib/object_storage/direct_upload_spec.rb b/spec/lib/object_storage/direct_upload_spec.rb
index fae0c636bdc..c3890c72852 100644
--- a/spec/lib/object_storage/direct_upload_spec.rb
+++ b/spec/lib/object_storage/direct_upload_spec.rb
@@ -3,11 +3,17 @@
require 'spec_helper'
describe ObjectStorage::DirectUpload do
+ let(:region) { 'us-east-1' }
+ let(:path_style) { false }
+ let(:use_iam_profile) { false }
let(:credentials) do
{
provider: 'AWS',
aws_access_key_id: 'AWS_ACCESS_KEY_ID',
- aws_secret_access_key: 'AWS_SECRET_ACCESS_KEY'
+ aws_secret_access_key: 'AWS_SECRET_ACCESS_KEY',
+ region: region,
+ path_style: path_style,
+ use_iam_profile: use_iam_profile
}
end
@@ -57,6 +63,62 @@ describe ObjectStorage::DirectUpload do
describe '#to_hash' do
subject { direct_upload.to_hash }
+ shared_examples 'a valid S3 upload' do
+ it_behaves_like 'a valid upload'
+
+ it 'sets Workhorse client data' do
+ expect(subject[:UseWorkhorseClient]).to eq(use_iam_profile)
+ expect(subject[:RemoteTempObjectID]).to eq(object_name)
+
+ object_store_config = subject[:ObjectStorage]
+ expect(object_store_config[:Provider]).to eq 'AWS'
+
+ s3_config = object_store_config[:S3Config]
+ expect(s3_config[:Bucket]).to eq(bucket_name)
+ expect(s3_config[:Region]).to eq(region)
+ expect(s3_config[:PathStyle]).to eq(path_style)
+ expect(s3_config[:UseIamProfile]).to eq(use_iam_profile)
+ end
+
+ context 'when feature flag is disabled' do
+ before do
+ stub_feature_flags(use_workhorse_s3_client: false)
+ end
+
+ it 'does not enable Workhorse client' do
+ expect(subject[:UseWorkhorseClient]).to be false
+ end
+ end
+
+ context 'when V2 signatures are used' do
+ before do
+ credentials[:aws_signature_version] = 2
+ end
+
+ it 'does not enable Workhorse client' do
+ expect(subject[:UseWorkhorseClient]).to be false
+ end
+ end
+
+ context 'when V4 signatures are used' do
+ before do
+ credentials[:aws_signature_version] = 4
+ end
+
+ it 'enables the Workhorse client for instance profiles' do
+ expect(subject[:UseWorkhorseClient]).to eq(use_iam_profile)
+ end
+ end
+ end
+
+ shared_examples 'a valid Google upload' do
+ it_behaves_like 'a valid upload'
+
+ it 'does not set Workhorse client data' do
+ expect(subject.keys).not_to include(:UseWorkhorseClient, :RemoteTempObjectID, :ObjectStorage)
+ end
+ end
+
shared_examples 'a valid upload' do
it "returns valid structure" do
expect(subject).to have_key(:Timeout)
@@ -97,6 +159,16 @@ describe ObjectStorage::DirectUpload do
end
end
+ shared_examples 'a valid S3 upload without multipart data' do
+ it_behaves_like 'a valid S3 upload'
+ it_behaves_like 'a valid upload without multipart data'
+ end
+
+ shared_examples 'a valid S3 upload with multipart data' do
+ it_behaves_like 'a valid S3 upload'
+ it_behaves_like 'a valid upload with multipart data'
+ end
+
shared_examples 'a valid upload without multipart data' do
it_behaves_like 'a valid upload'
@@ -109,13 +181,50 @@ describe ObjectStorage::DirectUpload do
context 'when length is known' do
let(:has_length) { true }
- it_behaves_like 'a valid upload without multipart data'
+ it_behaves_like 'a valid S3 upload without multipart data'
+
+ context 'when path style is true' do
+ let(:path_style) { true }
+ let(:storage_url) { 'https://s3.amazonaws.com/uploads' }
+
+ before do
+ stub_object_storage_multipart_init(storage_url, "myUpload")
+ end
+
+ it_behaves_like 'a valid S3 upload without multipart data'
+ end
+
+ context 'when IAM profile is true' do
+ let(:use_iam_profile) { true }
+ let(:iam_credentials_url) { "http://169.254.169.254/latest/meta-data/iam/security-credentials/" }
+ let(:iam_credentials) do
+ {
+ 'AccessKeyId' => 'dummykey',
+ 'SecretAccessKey' => 'dummysecret',
+ 'Token' => 'dummytoken',
+ 'Expiration' => 1.day.from_now.xmlschema
+ }
+ end
+
+ before do
+ stub_request(:get, iam_credentials_url)
+ .to_return(status: 200, body: "somerole", headers: {})
+ stub_request(:get, "#{iam_credentials_url}somerole")
+ .to_return(status: 200, body: iam_credentials.to_json, headers: {})
+ end
+
+ it_behaves_like 'a valid S3 upload without multipart data'
+ end
end
context 'when length is unknown' do
let(:has_length) { false }
- it_behaves_like 'a valid upload with multipart data' do
+ it_behaves_like 'a valid S3 upload with multipart data' do
+ before do
+ stub_object_storage_multipart_init(storage_url, "myUpload")
+ end
+
context 'when maximum upload size is 10MB' do
let(:maximum_size) { 10.megabyte }
@@ -169,12 +278,14 @@ describe ObjectStorage::DirectUpload do
context 'when length is known' do
let(:has_length) { true }
+ it_behaves_like 'a valid Google upload'
it_behaves_like 'a valid upload without multipart data'
end
context 'when length is unknown' do
let(:has_length) { false }
+ it_behaves_like 'a valid Google upload'
it_behaves_like 'a valid upload without multipart data'
end
end
diff --git a/spec/lib/peek/views/bullet_detailed_spec.rb b/spec/lib/peek/views/bullet_detailed_spec.rb
new file mode 100644
index 00000000000..a482cadc7db
--- /dev/null
+++ b/spec/lib/peek/views/bullet_detailed_spec.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Peek::Views::BulletDetailed do
+ subject { described_class.new }
+
+ before do
+ allow(Bullet).to receive(:enable?).and_return(bullet_enabled)
+ end
+
+ context 'bullet disabled' do
+ let(:bullet_enabled) { false }
+
+ it 'returns empty results' do
+ expect(subject.results).to eq({})
+ end
+ end
+
+ context 'bullet enabled' do
+ let(:bullet_enabled) { true }
+
+ before do
+ allow(Bullet).to receive_message_chain(:notification_collector, :collection).and_return(notifications)
+ end
+
+ context 'where there are no notifications' do
+ let(:notifications) { [] }
+
+ it 'returns empty results' do
+ expect(subject.results).to eq({})
+ end
+ end
+
+ context 'when notifications exist' do
+ let(:notifications) do
+ [
+ double(title: 'Title 1', body: 'Body 1', body_with_caller: "first\nsecond\n"),
+ double(title: 'Title 2', body: 'Body 2', body_with_caller: "first\nsecond\n")
+ ]
+ end
+
+ it 'returns empty results' do
+ expect(subject.key).to eq('bullet')
+ expect(subject.results[:calls]).to eq(2)
+ expect(subject.results[:warnings]).to eq([Peek::Views::BulletDetailed::WARNING_MESSAGE])
+ expect(subject.results[:details]).to eq([
+ { notification: 'Title 1: Body 1', backtrace: "first\nsecond\n" },
+ { notification: 'Title 2: Body 2', backtrace: "first\nsecond\n" }
+ ])
+ end
+ end
+ end
+end
diff --git a/spec/lib/peek/views/redis_detailed_spec.rb b/spec/lib/peek/views/redis_detailed_spec.rb
index fa9532226f2..a270c006a43 100644
--- a/spec/lib/peek/views/redis_detailed_spec.rb
+++ b/spec/lib/peek/views/redis_detailed_spec.rb
@@ -17,7 +17,7 @@ describe Peek::Views::RedisDetailed, :request_store do
with_them do
it 'scrubs Redis commands' do
- subject.detail_store << { cmd: cmd, duration: 1.second }
+ Gitlab::Instrumentation::Redis::SharedState.detail_store << { cmd: cmd, duration: 1.second }
expect(subject.results[:details].count).to eq(1)
expect(subject.results[:details].first)
@@ -29,11 +29,12 @@ describe Peek::Views::RedisDetailed, :request_store do
end
it 'returns aggregated results' do
- subject.detail_store << { cmd: [:get, 'test'], duration: 0.001 }
- subject.detail_store << { cmd: [:get, 'test'], duration: 1.second }
+ Gitlab::Instrumentation::Redis::Cache.detail_store << { cmd: [:get, 'test'], duration: 0.001 }
+ Gitlab::Instrumentation::Redis::Cache.detail_store << { cmd: [:get, 'test'], duration: 1.second }
+ Gitlab::Instrumentation::Redis::SharedState.detail_store << { cmd: [:get, 'test'], duration: 1.second }
- expect(subject.results[:calls]).to eq(2)
- expect(subject.results[:duration]).to eq('1001.00ms')
- expect(subject.results[:details].count).to eq(2)
+ expect(subject.results[:calls]).to eq(3)
+ expect(subject.results[:duration]).to eq('2001.00ms')
+ expect(subject.results[:details].count).to eq(3)
end
end
diff --git a/spec/lib/peek/views/rugged_spec.rb b/spec/lib/peek/views/rugged_spec.rb
index b9507f772d2..39968afed39 100644
--- a/spec/lib/peek/views/rugged_spec.rb
+++ b/spec/lib/peek/views/rugged_spec.rb
@@ -16,7 +16,7 @@ describe Peek::Views::Rugged, :request_store do
end
it 'returns aggregated results' do
- ::Gitlab::RuggedInstrumentation.query_time += 1.234
+ ::Gitlab::RuggedInstrumentation.add_query_time(1.234)
::Gitlab::RuggedInstrumentation.increment_query_count
::Gitlab::RuggedInstrumentation.increment_query_count
diff --git a/spec/lib/quality/test_level_spec.rb b/spec/lib/quality/test_level_spec.rb
index b784a92fa85..ad29c80b07a 100644
--- a/spec/lib/quality/test_level_spec.rb
+++ b/spec/lib/quality/test_level_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe Quality::TestLevel do
context 'when level is unit' do
it 'returns a pattern' do
expect(subject.pattern(:unit))
- .to eq("spec/{bin,channels,config,db,dependencies,factories,finders,frontend,graphql,haml_lint,helpers,initializers,javascripts,lib,models,policies,presenters,rack_servers,replicators,routing,rubocop,serializers,services,sidekiq,support_specs,tasks,uploaders,validators,views,workers,elastic_integration}{,/**/}*_spec.rb")
+ .to eq("spec/{bin,channels,config,db,dependencies,factories,finders,frontend,graphql,haml_lint,helpers,initializers,javascripts,lib,models,policies,presenters,rack_servers,replicators,routing,rubocop,serializers,services,sidekiq,support_specs,tasks,uploaders,validators,views,workers,elastic_integration,tooling}{,/**/}*_spec.rb")
end
end
@@ -89,7 +89,7 @@ RSpec.describe Quality::TestLevel do
context 'when level is unit' do
it 'returns a regexp' do
expect(subject.regexp(:unit))
- .to eq(%r{spec/(bin|channels|config|db|dependencies|factories|finders|frontend|graphql|haml_lint|helpers|initializers|javascripts|lib|models|policies|presenters|rack_servers|replicators|routing|rubocop|serializers|services|sidekiq|support_specs|tasks|uploaders|validators|views|workers|elastic_integration)})
+ .to eq(%r{spec/(bin|channels|config|db|dependencies|factories|finders|frontend|graphql|haml_lint|helpers|initializers|javascripts|lib|models|policies|presenters|rack_servers|replicators|routing|rubocop|serializers|services|sidekiq|support_specs|tasks|uploaders|validators|views|workers|elastic_integration|tooling)})
end
end
@@ -144,6 +144,10 @@ RSpec.describe Quality::TestLevel do
expect(subject.level_for('spec/models/abuse_report_spec.rb')).to eq(:unit)
end
+ it 'returns the correct level for a tooling test' do
+ expect(subject.level_for('spec/tooling/lib/tooling/test_file_finder_spec.rb')).to eq(:unit)
+ end
+
it 'returns the correct level for a migration test' do
expect(subject.level_for('spec/migrations/add_default_and_free_plans_spec.rb')).to eq(:migration)
end
diff --git a/spec/mailers/emails/profile_spec.rb b/spec/mailers/emails/profile_spec.rb
index f84bf43b9c4..cbf42da2085 100644
--- a/spec/mailers/emails/profile_spec.rb
+++ b/spec/mailers/emails/profile_spec.rb
@@ -160,38 +160,48 @@ describe Emails::Profile do
describe 'user unknown sign in email' do
let_it_be(:user) { create(:user) }
let_it_be(:ip) { '169.0.0.1' }
+ let_it_be(:current_time) { Time.current }
+ let_it_be(:email) { Notify.unknown_sign_in_email(user, ip, current_time) }
- subject { Notify.unknown_sign_in_email(user, ip) }
+ subject { email }
it_behaves_like 'an email sent from GitLab'
it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like 'a user cannot unsubscribe through footer link'
it 'is sent to the user' do
- expect(subject).to deliver_to user.email
+ is_expected.to deliver_to user.email
end
it 'has the correct subject' do
- expect(subject).to have_subject /^Unknown sign-in from new location$/
+ is_expected.to have_subject "#{Gitlab.config.gitlab.host} sign-in from new location"
+ end
+
+ it 'mentions the new sign-in IP' do
+ is_expected.to have_body_text ip
end
- it 'mentions the unknown sign-in IP' do
- expect(subject).to have_body_text /A sign-in to your account has been made from the following IP address: #{ip}./
+ it 'mentioned the time' do
+ is_expected.to have_body_text current_time.strftime('%Y-%m-%d %l:%M:%S %p %Z')
end
- it 'includes a link to the change password page' do
- expect(subject).to have_body_text /#{edit_profile_password_path}/
+ it 'includes a link to the change password documentation' do
+ is_expected.to have_body_text 'https://docs.gitlab.com/ee/user/profile/#changing-your-password'
end
it 'mentions two factor authentication when two factor is not enabled' do
- expect(subject).to have_body_text /two-factor authentication/
+ is_expected.to have_body_text 'two-factor authentication'
+ end
+
+ it 'includes a link to two-factor authentication documentation' do
+ is_expected.to have_body_text 'https://docs.gitlab.com/ee/user/profile/account/two_factor_authentication.html'
end
context 'when two factor authentication is enabled' do
- it 'does not mention two factor authentication' do
- two_factor_user = create(:user, :two_factor)
+ let(:user) { create(:user, :two_factor) }
- expect( Notify.unknown_sign_in_email(two_factor_user, ip) )
+ it 'does not mention two factor authentication' do
+ expect( Notify.unknown_sign_in_email(user, ip, current_time) )
.not_to have_body_text /two-factor authentication/
end
end
diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb
index 3c66902bb2e..8b99cc41a53 100644
--- a/spec/mailers/notify_spec.rb
+++ b/spec/mailers/notify_spec.rb
@@ -104,7 +104,11 @@ describe Notify do
it 'contains a link to issue author' do
is_expected.to have_body_text(issue.author_name)
- is_expected.to have_body_text 'created an issue:'
+ is_expected.to have_body_text 'created an issue'
+ end
+
+ it 'contains a link to the issue' do
+ is_expected.to have_body_text(issue.to_reference(full: false))
end
end
@@ -1722,4 +1726,59 @@ describe Notify do
is_expected.to have_body_text target_url
end
end
+
+ describe 'merge request reviews' do
+ let!(:review) { create(:review, project: project, merge_request: merge_request) }
+ let!(:notes) { create_list(:note, 3, review: review, project: project, author: review.author, noteable: merge_request) }
+
+ subject { described_class.new_review_email(recipient.id, review.id) }
+
+ it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
+ let(:model) { review.merge_request }
+ end
+
+ it_behaves_like 'it should show Gmail Actions View Merge request link'
+ it_behaves_like 'an unsubscribeable thread'
+
+ it 'is sent to the given recipient as the author' do
+ sender = subject.header[:from].addrs[0]
+
+ aggregate_failures do
+ expect(sender.display_name).to eq(review.author_name)
+ expect(sender.address).to eq(gitlab_sender)
+ expect(subject).to deliver_to(recipient.notification_email)
+ end
+ end
+
+ it 'contains the message from the notes of the review' do
+ review.notes.each do |note|
+ is_expected.to have_body_text note.note
+ end
+ end
+
+ context 'when diff note' do
+ let!(:notes) { create_list(:diff_note_on_merge_request, 3, review: review, project: project, author: review.author, noteable: merge_request) }
+
+ it 'links to notes' do
+ review.notes.each do |note|
+ # Text part
+ expect(subject.text_part.body.raw_source).to include(
+ project_merge_request_url(project, merge_request, anchor: "note_#{note.id}")
+ )
+ end
+ end
+ end
+
+ it 'contains review author name' do
+ is_expected.to have_body_text review.author_name
+ end
+
+ it 'has the correct subject and body' do
+ aggregate_failures do
+ is_expected.to have_subject "Re: #{project.name} | #{merge_request.title} (#{merge_request.to_reference})"
+
+ is_expected.to have_body_text project_merge_request_path(project, merge_request)
+ end
+ end
+ end
end
diff --git a/spec/migrations/20191125114345_add_admin_mode_protected_path_spec.rb b/spec/migrations/20191125114345_add_admin_mode_protected_path_spec.rb
index 669e31618a3..77d8dd002e3 100644
--- a/spec/migrations/20191125114345_add_admin_mode_protected_path_spec.rb
+++ b/spec/migrations/20191125114345_add_admin_mode_protected_path_spec.rb
@@ -4,10 +4,9 @@ require 'spec_helper'
require Rails.root.join('db', 'migrate', '20191125114345_add_admin_mode_protected_path.rb')
describe AddAdminModeProtectedPath do
- ADMIN_MODE_ENDPOINT = '/admin/session'
-
subject(:migration) { described_class.new }
+ let(:admin_mode_endpoint) { '/admin/session' }
let(:application_settings) { table(:application_settings) }
context 'no settings available' do
@@ -30,7 +29,7 @@ describe AddAdminModeProtectedPath do
application_settings.create!(protected_paths: '{a,b,c}')
protected_paths_before = %w[a b c]
- protected_paths_after = protected_paths_before.dup << ADMIN_MODE_ENDPOINT
+ protected_paths_after = protected_paths_before.dup << admin_mode_endpoint
expect { migrate! }.to change { application_settings.first.protected_paths }.from(protected_paths_before).to(protected_paths_after)
end
@@ -38,13 +37,13 @@ describe AddAdminModeProtectedPath do
it 'new default includes admin mode endpoint' do
settings_before = application_settings.create!
- expect(settings_before.protected_paths).not_to include(ADMIN_MODE_ENDPOINT)
+ expect(settings_before.protected_paths).not_to include(admin_mode_endpoint)
migrate!
application_settings.reset_column_information
settings_after = application_settings.create!
- expect(settings_after.protected_paths).to include(ADMIN_MODE_ENDPOINT)
+ expect(settings_after.protected_paths).to include(admin_mode_endpoint)
end
end
diff --git a/spec/migrations/active_record/schedule_set_confidential_note_events_on_services_spec.rb b/spec/migrations/active_record/schedule_set_confidential_note_events_on_services_spec.rb
deleted file mode 100644
index e973454ecc8..00000000000
--- a/spec/migrations/active_record/schedule_set_confidential_note_events_on_services_spec.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20180122154930_schedule_set_confidential_note_events_on_services.rb')
-
-describe ScheduleSetConfidentialNoteEventsOnServices do
- let(:services_table) { table(:services) }
- let(:migration_class) { Gitlab::BackgroundMigration::SetConfidentialNoteEventsOnServices }
- let(:migration_name) { migration_class.to_s.demodulize }
-
- let!(:service_1) { services_table.create!(confidential_note_events: nil, note_events: true) }
- let!(:service_2) { services_table.create!(confidential_note_events: nil, note_events: true) }
- let!(:service_migrated) { services_table.create!(confidential_note_events: true, note_events: true) }
- let!(:service_skip) { services_table.create!(confidential_note_events: nil, note_events: false) }
- let!(:service_new) { services_table.create!(confidential_note_events: false, note_events: true) }
- let!(:service_4) { services_table.create!(confidential_note_events: nil, note_events: true) }
-
- before do
- stub_const("#{described_class}::BATCH_SIZE", 1)
- end
-
- it 'schedules background migrations at correct time' do
- Sidekiq::Testing.fake! do
- Timecop.freeze do
- migrate!
-
- expect(migration_name).to be_scheduled_delayed_migration(20.minutes, service_1.id, service_1.id)
- expect(migration_name).to be_scheduled_delayed_migration(40.minutes, service_2.id, service_2.id)
- expect(migration_name).to be_scheduled_delayed_migration(60.minutes, service_4.id, service_4.id)
- expect(BackgroundMigrationWorker.jobs.size).to eq 3
- end
- end
- end
-
- it 'correctly processes services', :sidekiq_might_not_need_inline do
- perform_enqueued_jobs do
- expect(services_table.where(confidential_note_events: nil).count).to eq 4
- expect(services_table.where(confidential_note_events: true).count).to eq 1
-
- migrate!
-
- expect(services_table.where(confidential_note_events: nil).count).to eq 1
- expect(services_table.where(confidential_note_events: true).count).to eq 4
- end
- end
-end
diff --git a/spec/migrations/add_foreign_key_from_notification_settings_to_users_spec.rb b/spec/migrations/add_foreign_key_from_notification_settings_to_users_spec.rb
deleted file mode 100644
index ceca38b148e..00000000000
--- a/spec/migrations/add_foreign_key_from_notification_settings_to_users_spec.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'migrate', '20180710162338_add_foreign_key_from_notification_settings_to_users.rb')
-
-describe AddForeignKeyFromNotificationSettingsToUsers do
- let(:notification_settings) { table(:notification_settings) }
- let(:users) { table(:users) }
- let(:projects) { table(:projects) }
-
- before do
- users.create!(email: 'email@email.com', name: 'foo', username: 'foo', projects_limit: 0)
- projects.create!(name: 'gitlab', path: 'gitlab-org/gitlab-ce', namespace_id: 1)
- end
-
- describe 'removal of orphans without user' do
- let!(:notification_setting_without_user) { create_notification_settings!(user_id: 123) }
- let!(:notification_setting_with_user) { create_notification_settings!(user_id: users.last.id) }
-
- it 'removes orphaned notification_settings without user' do
- expect { migrate! }.to change { notification_settings.count }.by(-1)
- end
-
- it "doesn't remove notification_settings with valid user" do
- expect { migrate! }.not_to change { notification_setting_with_user.reload }
- end
- end
-
- def create_notification_settings!(**opts)
- notification_settings.create!(
- source_id: projects.last.id,
- source_type: 'Project',
- user_id: users.last.id,
- **opts)
- end
-end
diff --git a/spec/migrations/add_foreign_keys_to_todos_spec.rb b/spec/migrations/add_foreign_keys_to_todos_spec.rb
deleted file mode 100644
index 49fb3c1a911..00000000000
--- a/spec/migrations/add_foreign_keys_to_todos_spec.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'migrate', '20180201110056_add_foreign_keys_to_todos.rb')
-
-describe AddForeignKeysToTodos do
- let(:todos) { table(:todos) }
- let(:users) { table(:users) }
- let(:projects) { table(:projects) }
-
- let(:project) { projects.create!(name: 'gitlab', path: 'gitlab-org/gitlab-ce', namespace_id: 1) }
- let(:user) { users.create!(email: 'email@email.com', name: 'foo', username: 'foo', projects_limit: 0) }
-
- context 'add foreign key on user_id' do
- let!(:todo_with_user) { create_todo(user_id: user.id) }
- let!(:todo_without_user) { create_todo(user_id: 4711) }
-
- it 'removes orphaned todos without corresponding user' do
- expect { migrate! }.to change { Todo.count }.from(2).to(1)
- end
-
- it 'does not remove entries with valid user_id' do
- expect { migrate! }.not_to change { todo_with_user.reload }
- end
- end
-
- context 'add foreign key on author_id' do
- let!(:todo_with_author) { create_todo(author_id: user.id) }
- let!(:todo_with_invalid_author) { create_todo(author_id: 4711) }
-
- it 'removes orphaned todos by author_id' do
- expect { migrate! }.to change { Todo.count }.from(2).to(1)
- end
-
- it 'does not touch author_id for valid entries' do
- expect { migrate! }.not_to change { todo_with_author.reload }
- end
- end
-
- context 'add foreign key on note_id' do
- let(:note) { table(:notes).create! }
- let!(:todo_with_note) { create_todo(note_id: note.id) }
- let!(:todo_with_invalid_note) { create_todo(note_id: 4711) }
- let!(:todo_without_note) { create_todo(note_id: nil) }
-
- it 'deletes todo if note_id is set but does not exist in notes table' do
- expect { migrate! }.to change { Todo.count }.from(3).to(2)
- end
-
- it 'does not touch entry if note_id is nil' do
- expect { migrate! }.not_to change { todo_without_note.reload }
- end
-
- it 'does not touch note_id for valid entries' do
- expect { migrate! }.not_to change { todo_with_note.reload }
- end
- end
-
- def create_todo(**opts)
- todos.create!(
- project_id: project.id,
- user_id: user.id,
- author_id: user.id,
- target_type: '',
- action: 0,
- state: '', **opts
- )
- end
-end
diff --git a/spec/migrations/add_incident_settings_to_all_existing_projects_spec.rb b/spec/migrations/add_incident_settings_to_all_existing_projects_spec.rb
new file mode 100644
index 00000000000..507b1a8d580
--- /dev/null
+++ b/spec/migrations/add_incident_settings_to_all_existing_projects_spec.rb
@@ -0,0 +1,93 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'migrate', '20200609212701_add_incident_settings_to_all_existing_projects.rb')
+
+describe AddIncidentSettingsToAllExistingProjects, :migration do
+ let(:project_incident_management_settings) { table(:project_incident_management_settings) }
+ let(:labels) { table(:labels) }
+ let(:label_links) { table(:label_links) }
+ let(:issues) { table(:issues) }
+ let(:projects) { table(:projects) }
+ let(:namespaces) { table(:namespaces) }
+
+ RSpec.shared_examples 'setting not added' do
+ it 'does not add settings' do
+ migrate!
+
+ expect { migrate! }.not_to change { IncidentManagement::ProjectIncidentManagementSetting.count }
+ end
+ end
+
+ RSpec.shared_examples 'project has no incident settings' do
+ it 'has no settings' do
+ migrate!
+
+ expect(settings).to eq(nil)
+ end
+ end
+
+ RSpec.shared_examples 'no change to incident settings' do
+ it 'does not change existing settings' do
+ migrate!
+
+ expect(settings.create_issue).to eq(existing_create_issue)
+ end
+ end
+
+ RSpec.shared_context 'with incident settings' do
+ let(:existing_create_issue) { false }
+ before do
+ project_incident_management_settings.create(
+ project_id: project.id,
+ create_issue: existing_create_issue
+ )
+ end
+ end
+
+ describe 'migrate!' do
+ let(:namespace) { namespaces.create!(name: 'foo', path: 'foo') }
+ let!(:project) { projects.create!(namespace_id: namespace.id) }
+ let(:settings) { project_incident_management_settings.find_by(project_id: project.id) }
+
+ context 'when project does not have incident label' do
+ context 'does not have incident settings' do
+ include_examples 'setting not added'
+ include_examples 'project has no incident settings'
+ end
+
+ context 'and has incident settings' do
+ include_context 'with incident settings'
+
+ include_examples 'setting not added'
+ include_examples 'no change to incident settings'
+ end
+ end
+
+ context 'when project has incident labels' do
+ before do
+ issue = issues.create!(project_id: project.id)
+ incident_label_attrs = IncidentManagement::CreateIssueService::INCIDENT_LABEL
+ incident_label = labels.create!(project_id: project.id, **incident_label_attrs)
+ label_links.create!(target_id: issue.id, label_id: incident_label.id, target_type: 'Issue')
+ end
+
+ context 'when project has incident settings' do
+ include_context 'with incident settings'
+
+ include_examples 'setting not added'
+ include_examples 'no change to incident settings'
+ end
+
+ context 'does not have incident settings' do
+ it 'adds incident settings with old defaults' do
+ migrate!
+
+ expect(settings.create_issue).to eq(true)
+ expect(settings.send_email).to eq(false)
+ expect(settings.issue_template_key).to eq(nil)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/migrations/add_not_null_constraint_to_project_mirror_data_foreign_key_spec.rb b/spec/migrations/add_not_null_constraint_to_project_mirror_data_foreign_key_spec.rb
deleted file mode 100644
index 03f65aba7c0..00000000000
--- a/spec/migrations/add_not_null_constraint_to_project_mirror_data_foreign_key_spec.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'migrate', '20180508100222_add_not_null_constraint_to_project_mirror_data_foreign_key.rb')
-
-describe AddNotNullConstraintToProjectMirrorDataForeignKey do
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:import_state) { table(:project_mirror_data) }
-
- before do
- import_state.create!(id: 1, project_id: nil, status: :started)
- end
-
- it 'removes every import state without an associated project_id' do
- expect do
- subject.up
- end.to change { import_state.count }.from(1).to(0)
- end
-end
diff --git a/spec/migrations/add_pages_access_level_to_project_feature_spec.rb b/spec/migrations/add_pages_access_level_to_project_feature_spec.rb
deleted file mode 100644
index 69f1e3ba3d0..00000000000
--- a/spec/migrations/add_pages_access_level_to_project_feature_spec.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'migrate', '20180423204600_add_pages_access_level_to_project_feature.rb')
-
-describe AddPagesAccessLevelToProjectFeature do
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:features) { table(:project_features) }
- let!(:namespace) { namespaces.create(name: 'gitlab', path: 'gitlab') }
- let!(:first_project) { projects.create(name: 'gitlab1', path: 'gitlab1', namespace_id: namespace.id) }
- let!(:first_project_features) { features.create(project_id: first_project.id) }
- let!(:second_project) { projects.create(name: 'gitlab2', path: 'gitlab2', namespace_id: namespace.id) }
- let!(:second_project_features) { features.create(project_id: second_project.id) }
-
- it 'correctly migrate pages for old projects to be public' do
- migrate!
-
- # For old projects pages should be public
- expect(first_project_features.reload.pages_access_level).to eq ProjectFeature::PUBLIC
- expect(second_project_features.reload.pages_access_level).to eq ProjectFeature::PUBLIC
- end
-
- it 'after migration pages are enabled as default' do
- migrate!
-
- # For new project default is enabled
- third_project = projects.create(name: 'gitlab3', path: 'gitlab3', namespace_id: namespace.id)
- third_project_features = features.create(project_id: third_project.id)
- expect(third_project_features.reload.pages_access_level).to eq ProjectFeature::ENABLED
- end
-end
diff --git a/spec/migrations/add_pipeline_build_foreign_key_spec.rb b/spec/migrations/add_pipeline_build_foreign_key_spec.rb
deleted file mode 100644
index dd0189b6bfc..00000000000
--- a/spec/migrations/add_pipeline_build_foreign_key_spec.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'migrate', '20180420010016_add_pipeline_build_foreign_key.rb')
-
-describe AddPipelineBuildForeignKey do
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:pipelines) { table(:ci_pipelines) }
- let(:builds) { table(:ci_builds) }
-
- before do
- namespaces.create(id: 10, name: 'gitlab-org', path: 'gitlab-org')
- projects.create!(id: 11, namespace_id: 10, name: 'gitlab', path: 'gitlab')
- pipelines.create!(id: 12, project_id: 11, ref: 'master', sha: 'adf43c3a')
-
- builds.create!(id: 101, commit_id: 12, project_id: 11)
- builds.create!(id: 102, commit_id: 222, project_id: 11)
- builds.create!(id: 103, commit_id: 333, project_id: 11)
- builds.create!(id: 104, commit_id: 12, project_id: 11)
- builds.create!(id: 106, commit_id: nil, project_id: 11)
- builds.create!(id: 107, commit_id: 12, project_id: nil)
- end
-
- it 'adds foreign key after removing orphans' do
- expect(builds.all.count).to eq 6
- expect(foreign_key_exists?(:ci_builds, :ci_pipelines, column: :commit_id)).to be_falsey
-
- migrate!
-
- expect(builds.all.pluck(:id)).to eq [101, 104]
- expect(foreign_key_exists?(:ci_builds, :ci_pipelines, column: :commit_id)).to be_truthy
- end
-end
diff --git a/spec/migrations/add_unique_constraint_to_project_features_project_id_spec.rb b/spec/migrations/add_unique_constraint_to_project_features_project_id_spec.rb
deleted file mode 100644
index 91abf0f7d1c..00000000000
--- a/spec/migrations/add_unique_constraint_to_project_features_project_id_spec.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20180511174224_add_unique_constraint_to_project_features_project_id.rb')
-
-describe AddUniqueConstraintToProjectFeaturesProjectId do
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:features) { table(:project_features) }
- let(:migration) { described_class.new }
-
- describe '#up' do
- before do
- (1..3).each do |i|
- namespaces.create(id: i, name: "ns-test-#{i}", path: "ns-test-i#{i}")
- projects.create!(id: i, name: "test-#{i}", path: "test-#{i}", namespace_id: i)
- end
-
- features.create!(id: 1, project_id: 1)
- features.create!(id: 2, project_id: 1)
- features.create!(id: 3, project_id: 2)
- features.create!(id: 4, project_id: 2)
- features.create!(id: 5, project_id: 2)
- features.create!(id: 6, project_id: 3)
- end
-
- it 'creates a unique index and removes duplicates' do
- expect(migration.index_exists?(:project_features, :project_id, unique: false, name: 'index_project_features_on_project_id')).to be true
-
- expect { migration.up }.to change { features.count }.from(6).to(3)
-
- expect(migration.index_exists?(:project_features, :project_id, unique: true, name: 'index_project_features_on_project_id')).to be true
- expect(migration.index_exists?(:project_features, :project_id, name: 'index_project_features_on_project_id_unique')).to be false
-
- project_1_features = features.where(project_id: 1)
- expect(project_1_features.count).to eq(1)
- expect(project_1_features.first.id).to eq(2)
-
- project_2_features = features.where(project_id: 2)
- expect(project_2_features.count).to eq(1)
- expect(project_2_features.first.id).to eq(5)
-
- project_3_features = features.where(project_id: 3)
- expect(project_3_features.count).to eq(1)
- expect(project_3_features.first.id).to eq(6)
- end
- end
-
- describe '#down' do
- it 'restores the original index' do
- migration.up
-
- expect(migration.index_exists?(:project_features, :project_id, unique: true, name: 'index_project_features_on_project_id')).to be true
-
- migration.down
-
- expect(migration.index_exists?(:project_features, :project_id, unique: false, name: 'index_project_features_on_project_id')).to be true
- expect(migration.index_exists?(:project_features, :project_id, name: 'index_project_features_on_project_id_old')).to be false
- end
- end
-end
diff --git a/spec/migrations/assure_commits_count_for_merge_request_diff_spec.rb b/spec/migrations/assure_commits_count_for_merge_request_diff_spec.rb
deleted file mode 100644
index e9ef6bf3e2d..00000000000
--- a/spec/migrations/assure_commits_count_for_merge_request_diff_spec.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'migrate', '20180425131009_assure_commits_count_for_merge_request_diff.rb')
-
-describe AssureCommitsCountForMergeRequestDiff, :redis do
- let(:migration) { spy('migration') }
-
- before do
- allow(Gitlab::BackgroundMigration::AddMergeRequestDiffCommitsCount)
- .to receive(:new).and_return(migration)
- end
-
- context 'when there are still unmigrated commit_counts afterwards' do
- let(:namespaces) { table('namespaces') }
- let(:projects) { table('projects') }
- let(:merge_requests) { table('merge_requests') }
- let(:diffs) { table('merge_request_diffs') }
-
- before do
- namespace = namespaces.create(name: 'foo', path: 'foo')
- project = projects.create!(namespace_id: namespace.id)
- merge_request = merge_requests.create!(source_branch: 'x', target_branch: 'y', target_project_id: project.id)
- diffs.create!(commits_count: nil, merge_request_id: merge_request.id)
- diffs.create!(commits_count: nil, merge_request_id: merge_request.id)
- end
-
- it 'migrates commit_counts sequentially in batches' do
- migrate!
-
- expect(migration).to have_received(:perform).once
- end
- end
-end
diff --git a/spec/migrations/backfill_imported_snippet_repositories_spec.rb b/spec/migrations/backfill_imported_snippet_repositories_spec.rb
new file mode 100644
index 00000000000..c77978b23e4
--- /dev/null
+++ b/spec/migrations/backfill_imported_snippet_repositories_spec.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20200608072931_backfill_imported_snippet_repositories.rb')
+
+describe BackfillImportedSnippetRepositories do
+ let(:users) { table(:users) }
+ let(:snippets) { table(:snippets) }
+ let(:user) { users.create(id: 1, email: 'user@example.com', projects_limit: 10, username: 'test', name: 'Test', state: 'active') }
+
+ def create_snippet(id)
+ params = {
+ id: id,
+ type: 'PersonalSnippet',
+ author_id: user.id,
+ file_name: 'foo',
+ content: 'bar'
+ }
+
+ snippets.create!(params)
+ end
+
+ it 'correctly schedules background migrations' do
+ create_snippet(1)
+ create_snippet(2)
+ create_snippet(3)
+ create_snippet(5)
+ create_snippet(7)
+ create_snippet(8)
+ create_snippet(10)
+
+ Sidekiq::Testing.fake! do
+ Timecop.freeze do
+ migrate!
+
+ expect(described_class::MIGRATION)
+ .to be_scheduled_delayed_migration(2.minutes, 1, 3)
+
+ expect(described_class::MIGRATION)
+ .to be_scheduled_delayed_migration(4.minutes, 5, 5)
+
+ expect(described_class::MIGRATION)
+ .to be_scheduled_delayed_migration(6.minutes, 7, 8)
+
+ expect(described_class::MIGRATION)
+ .to be_scheduled_delayed_migration(8.minutes, 10, 10)
+
+ expect(BackgroundMigrationWorker.jobs.size).to eq(4)
+ end
+ end
+ end
+end
diff --git a/spec/migrations/backfill_releases_name_with_tag_name_spec.rb b/spec/migrations/backfill_releases_name_with_tag_name_spec.rb
deleted file mode 100644
index b38b8dff3fa..00000000000
--- a/spec/migrations/backfill_releases_name_with_tag_name_spec.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'migrate', '20181212104941_backfill_releases_name_with_tag_name.rb')
-
-describe BackfillReleasesNameWithTagName do
- let(:releases) { table(:releases) }
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
-
- let(:namespace) { namespaces.create(name: 'foo', path: 'foo') }
- let(:project) { projects.create!(namespace_id: namespace.id) }
- let(:release) { releases.create!(project_id: project.id, tag: 'v1.0.0') }
-
- it 'defaults name to tag value' do
- expect(release.tag).to be_present
-
- migrate!
-
- release.reload
- expect(release.name).to eq(release.tag)
- end
-end
diff --git a/spec/migrations/backfill_status_page_published_incidents_spec.rb b/spec/migrations/backfill_status_page_published_incidents_spec.rb
new file mode 100644
index 00000000000..ccdc8be4168
--- /dev/null
+++ b/spec/migrations/backfill_status_page_published_incidents_spec.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20200421195234_backfill_status_page_published_incidents.rb')
+
+describe BackfillStatusPagePublishedIncidents, :migration do
+ subject(:migration) { described_class.new }
+
+ describe '#up' do
+ let(:projects) { table(:projects) }
+ let(:status_page_settings) { table(:status_page_settings) }
+ let(:issues) { table(:issues) }
+ let(:incidents) { table(:status_page_published_incidents) }
+
+ let(:namespace) { table(:namespaces).create!(name: 'gitlab', path: 'gitlab') }
+ let(:project_without_status_page) { projects.create!(namespace_id: namespace.id) }
+ let(:enabled_project) { projects.create!(namespace_id: namespace.id) }
+ let(:disabled_project) { projects.create!(namespace_id: namespace.id) }
+
+ let!(:enabled_setting) { status_page_settings.create!(enabled: true, project_id: enabled_project.id, **status_page_setting_attrs) }
+ let!(:disabled_setting) { status_page_settings.create!(enabled: false, project_id: disabled_project.id, **status_page_setting_attrs) }
+
+ let!(:published_issue) { issues.create!(confidential: false, project_id: enabled_project.id) }
+ let!(:nonpublished_issue_1) { issues.create!(confidential: true, project_id: enabled_project.id) }
+ let!(:nonpublished_issue_2) { issues.create!(confidential: false, project_id: disabled_project.id) }
+ let!(:nonpublished_issue_3) { issues.create!(confidential: false, project_id: project_without_status_page.id) }
+
+ let(:current_time) { Time.current.change(usec: 0) }
+ let(:status_page_setting_attrs) do
+ {
+ aws_s3_bucket_name: 'bucket',
+ aws_region: 'region',
+ aws_access_key: 'key',
+ encrypted_aws_secret_key: 'abc123',
+ encrypted_aws_secret_key_iv: 'abc123'
+ }
+ end
+
+ it 'creates a StatusPage::PublishedIncident record for each published issue' do
+ Timecop.freeze(current_time) do
+ expect(incidents.all).to be_empty
+
+ migrate!
+
+ incident = incidents.first
+
+ expect(incidents.count).to eq(1)
+ expect(incident.issue_id).to eq(published_issue.id)
+ expect(incident.created_at).to eq(current_time)
+ expect(incident.updated_at).to eq(current_time)
+ end
+ end
+ end
+end
diff --git a/spec/migrations/backfill_store_project_full_path_in_repo_spec.rb b/spec/migrations/backfill_store_project_full_path_in_repo_spec.rb
deleted file mode 100644
index a2adde37f11..00000000000
--- a/spec/migrations/backfill_store_project_full_path_in_repo_spec.rb
+++ /dev/null
@@ -1,98 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-require Rails.root.join('db', 'post_migrate', '20181010133639_backfill_store_project_full_path_in_repo.rb')
-
-describe BackfillStoreProjectFullPathInRepo do
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:group) { namespaces.create!(name: 'foo', path: 'foo') }
- let(:subgroup) { namespaces.create!(name: 'bar', path: 'bar', parent_id: group.id) }
-
- subject(:migration) { described_class.new }
-
- around do |example|
- perform_enqueued_jobs do
- example.run
- end
- end
-
- describe '#up' do
- shared_examples_for 'writes the full path to git config' do
- it 'writes the git config', :sidekiq_might_not_need_inline do
- expect_next_instance_of(Gitlab::GitalyClient::RepositoryService) do |repository_service|
- allow(repository_service).to receive(:cleanup)
- expect(repository_service).to receive(:set_config).with('gitlab.fullpath' => expected_path)
- end
-
- migration.up
- end
-
- it 'retries in case of failure', :sidekiq_might_not_need_inline do
- repository_service = spy(:repository_service)
-
- allow(Gitlab::GitalyClient::RepositoryService).to receive(:new).and_return(repository_service)
-
- allow(repository_service).to receive(:set_config).and_raise(GRPC::BadStatus, 'Retry me')
- expect(repository_service).to receive(:set_config).exactly(3).times
-
- migration.up
- end
-
- it 'cleans up repository before writing the config', :sidekiq_might_not_need_inline do
- expect_next_instance_of(Gitlab::GitalyClient::RepositoryService) do |repository_service|
- expect(repository_service).to receive(:cleanup).ordered
- expect(repository_service).to receive(:set_config).ordered
- end
-
- migration.up
- end
-
- context 'legacy storage' do
- it 'finds the repository at the correct location' do
- Project.find(project.id).create_repository
-
- expect { migration.up }.not_to raise_error
- end
- end
-
- context 'hashed storage' do
- it 'finds the repository at the correct location' do
- project.update_attribute(:storage_version, 1)
-
- Project.find(project.id).create_repository
-
- expect { migration.up }.not_to raise_error
- end
- end
- end
-
- context 'project in group' do
- let!(:project) { projects.create!(namespace_id: group.id, name: 'baz', path: 'baz') }
- let(:expected_path) { 'foo/baz' }
-
- it_behaves_like 'writes the full path to git config'
- end
-
- context 'project in subgroup' do
- let!(:project) { projects.create!(namespace_id: subgroup.id, name: 'baz', path: 'baz') }
- let(:expected_path) { 'foo/bar/baz' }
-
- it_behaves_like 'writes the full path to git config'
- end
- end
-
- describe '#down' do
- context 'project in group' do
- let!(:project) { projects.create!(namespace_id: group.id, name: 'baz', path: 'baz') }
-
- it 'deletes the gitlab full config value', :sidekiq_might_not_need_inline do
- expect_any_instance_of(Gitlab::GitalyClient::RepositoryService)
- .to receive(:delete_config).with(['gitlab.fullpath'])
-
- migration.down
- end
- end
- end
-end
diff --git a/spec/migrations/cap_designs_filename_length_to_new_limit_spec.rb b/spec/migrations/cap_designs_filename_length_to_new_limit_spec.rb
new file mode 100644
index 00000000000..daa07953cb5
--- /dev/null
+++ b/spec/migrations/cap_designs_filename_length_to_new_limit_spec.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20200602013901_cap_designs_filename_length_to_new_limit')
+
+describe CapDesignsFilenameLengthToNewLimit, :migration, schema: 20200528125905 do
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:issues) { table(:issues) }
+ let(:designs) { table(:design_management_designs) }
+
+ let(:filename_below_limit) { generate_filename(254) }
+ let(:filename_at_limit) { generate_filename(255) }
+ let(:filename_above_limit) { generate_filename(256) }
+
+ let!(:namespace) { namespaces.create!(name: 'foo', path: 'foo') }
+ let!(:project) { projects.create!(name: 'gitlab', path: 'gitlab-org/gitlab', namespace_id: namespace.id) }
+ let!(:issue) { issues.create!(description: 'issue', project_id: project.id) }
+
+ def generate_filename(length, extension: '.png')
+ name = 'a' * (length - extension.length)
+
+ "#{name}#{extension}"
+ end
+
+ def create_design(filename)
+ designs.create!(
+ issue_id: issue.id,
+ project_id: project.id,
+ filename: filename
+ )
+ end
+
+ it 'correctly sets filenames that are above the limit' do
+ [
+ filename_below_limit,
+ filename_at_limit,
+ filename_above_limit
+ ].each(&method(:create_design))
+
+ migrate!
+
+ expect(designs.find(1).filename).to eq(filename_below_limit)
+ expect(designs.find(2).filename).to eq(filename_at_limit)
+ expect(designs.find(3).filename).to eq([described_class::MODIFIED_NAME, 3, described_class::MODIFIED_EXTENSION].join)
+ end
+
+ it 'runs after filename limit has been set' do
+ # This spec file uses the `schema:` keyword to run these tests
+ # against a schema version before the one that sets the limit,
+ # as otherwise we can't create the design data with filenames greater
+ # than the limit.
+ #
+ # For this test, we migrate any skipped versions up to this migration.
+ migration_context.migrate(20200602013901)
+
+ create_design(filename_at_limit)
+ expect { create_design(filename_above_limit) }.to raise_error(ActiveRecord::StatementInvalid)
+ end
+end
diff --git a/spec/migrations/change_default_value_for_dsa_key_restriction_spec.rb b/spec/migrations/change_default_value_for_dsa_key_restriction_spec.rb
deleted file mode 100644
index 448f1e2106e..00000000000
--- a/spec/migrations/change_default_value_for_dsa_key_restriction_spec.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'migrate', '20180531220618_change_default_value_for_dsa_key_restriction.rb')
-
-describe ChangeDefaultValueForDsaKeyRestriction do
- let(:application_settings) { table(:application_settings) }
-
- before do
- application_settings.create!
- end
-
- it 'changes the default value for dsa_key_restriction' do
- expect(application_settings.first.dsa_key_restriction).to eq(0)
-
- migrate!
-
- application_settings.reset_column_information
- new_setting = application_settings.create!
-
- expect(application_settings.count).to eq(2)
- expect(new_setting.dsa_key_restriction).to eq(-1)
- end
-
- it 'changes the existing setting' do
- setting = application_settings.last
-
- expect(setting.dsa_key_restriction).to eq(0)
-
- migrate!
-
- expect(application_settings.count).to eq(1)
- expect(setting.reload.dsa_key_restriction).to eq(-1)
- end
-end
diff --git a/spec/migrations/cleanup_build_stage_migration_spec.rb b/spec/migrations/cleanup_build_stage_migration_spec.rb
deleted file mode 100644
index 961e719e2fc..00000000000
--- a/spec/migrations/cleanup_build_stage_migration_spec.rb
+++ /dev/null
@@ -1,55 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'migrate', '20180420010616_cleanup_build_stage_migration.rb')
-
-describe CleanupBuildStageMigration, :redis do
- let(:migration) { spy('migration') }
-
- before do
- allow(Gitlab::BackgroundMigration::MigrateBuildStage)
- .to receive(:new).and_return(migration)
- end
-
- context 'when there are pending background migrations' do
- it 'processes pending jobs synchronously' do
- Sidekiq::Testing.disable! do
- BackgroundMigrationWorker
- .perform_in(2.minutes, 'MigrateBuildStage', [1, 1])
- BackgroundMigrationWorker
- .perform_async('MigrateBuildStage', [1, 1])
-
- migrate!
-
- expect(migration).to have_received(:perform).with(1, 1).twice
- end
- end
- end
-
- context 'when there are no background migrations pending' do
- it 'does nothing' do
- Sidekiq::Testing.disable! do
- migrate!
-
- expect(migration).not_to have_received(:perform)
- end
- end
- end
-
- context 'when there are still unmigrated builds present' do
- let(:builds) { table('ci_builds') }
-
- before do
- builds.create!(name: 'test:1', ref: 'master')
- builds.create!(name: 'test:2', ref: 'master')
- end
-
- it 'migrates stages sequentially in batches' do
- expect(builds.all).to all(have_attributes(stage_id: nil))
-
- migrate!
-
- expect(migration).to have_received(:perform).once
- end
- end
-end
diff --git a/spec/migrations/cleanup_environments_external_url_spec.rb b/spec/migrations/cleanup_environments_external_url_spec.rb
deleted file mode 100644
index 54fcb8c62cd..00000000000
--- a/spec/migrations/cleanup_environments_external_url_spec.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'migrate', '20181108091549_cleanup_environments_external_url.rb')
-
-describe CleanupEnvironmentsExternalUrl do
- let(:environments) { table(:environments) }
- let(:invalid_entries) { environments.where(environments.arel_table[:external_url].matches('javascript://%')) }
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
-
- before do
- namespace = namespaces.create(name: 'foo', path: 'foo')
- project = projects.create!(namespace_id: namespace.id)
-
- environments.create!(id: 1, project_id: project.id, name: 'poisoned', slug: 'poisoned', external_url: 'javascript://alert("1")')
- end
-
- it 'clears every environment with a javascript external_url' do
- expect do
- subject.up
- end.to change { invalid_entries.count }.from(1).to(0)
- end
-
- it 'do not removes environments' do
- expect do
- subject.up
- end.not_to change { environments.count }
- end
-end
diff --git a/spec/migrations/cleanup_projects_with_missing_namespace_spec.rb b/spec/migrations/cleanup_projects_with_missing_namespace_spec.rb
index 06b6d5e3b46..27c954d2984 100644
--- a/spec/migrations/cleanup_projects_with_missing_namespace_spec.rb
+++ b/spec/migrations/cleanup_projects_with_missing_namespace_spec.rb
@@ -5,10 +5,6 @@ require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20200511080113_add_projects_foreign_key_to_namespaces.rb')
require Rails.root.join('db', 'post_migrate', '20200511083541_cleanup_projects_with_missing_namespace.rb')
-LOST_AND_FOUND_GROUP = 'lost-and-found'
-USER_TYPE_GHOST = 5
-ACCESS_LEVEL_OWNER = 50
-
# In order to test the CleanupProjectsWithMissingNamespace migration, we need
# to first create an orphaned project (one with an invalid namespace_id)
# and then run the migration to check that the project was properly cleaned up
@@ -77,31 +73,39 @@ describe CleanupProjectsWithMissingNamespace, :migration, schema: SchemaVersionF
end
it 'creates the ghost user' do
- expect(users.where(user_type: USER_TYPE_GHOST).count).to eq(0)
+ expect(users.where(user_type: described_class::User::USER_TYPE_GHOST).count).to eq(0)
disable_migrations_output { migrate! }
- expect(users.where(user_type: USER_TYPE_GHOST).count).to eq(1)
+ expect(users.where(user_type: described_class::User::USER_TYPE_GHOST).count).to eq(1)
end
it 'creates the lost-and-found group, owned by the ghost user' do
expect(
- Group.where(Group.arel_table[:name].matches("#{LOST_AND_FOUND_GROUP}%")).count
+ described_class::Group.where(
+ described_class::Group
+ .arel_table[:name]
+ .matches("#{described_class::User::LOST_AND_FOUND_GROUP}%")
+ ).count
).to eq(0)
disable_migrations_output { migrate! }
- ghost_user = users.find_by(user_type: USER_TYPE_GHOST)
+ ghost_user = users.find_by(user_type: described_class::User::USER_TYPE_GHOST)
expect(
- Group
+ described_class::Group
.joins('INNER JOIN members ON namespaces.id = members.source_id')
.where('namespaces.type = ?', 'Group')
.where('members.type = ?', 'GroupMember')
.where('members.source_type = ?', 'Namespace')
.where('members.user_id = ?', ghost_user.id)
.where('members.requested_at IS NULL')
- .where('members.access_level = ?', ACCESS_LEVEL_OWNER)
- .where(Group.arel_table[:name].matches("#{LOST_AND_FOUND_GROUP}%"))
+ .where('members.access_level = ?', described_class::ACCESS_LEVEL_OWNER)
+ .where(
+ described_class::Group
+ .arel_table[:name]
+ .matches("#{described_class::User::LOST_AND_FOUND_GROUP}%")
+ )
.count
).to eq(1)
end
@@ -114,7 +118,11 @@ describe CleanupProjectsWithMissingNamespace, :migration, schema: SchemaVersionF
disable_migrations_output { migrate! }
- lost_and_found_group = Group.find_by(Group.arel_table[:name].matches("#{LOST_AND_FOUND_GROUP}%"))
+ lost_and_found_group = described_class::Group.find_by(
+ described_class::Group
+ .arel_table[:name]
+ .matches("#{described_class::User::LOST_AND_FOUND_GROUP}%")
+ )
orphaned_project = projects.find_by(id: orphaned_project.id)
expect(orphaned_project.visibility_level).to eq(0)
diff --git a/spec/migrations/cleanup_stages_position_migration_spec.rb b/spec/migrations/cleanup_stages_position_migration_spec.rb
deleted file mode 100644
index 62b9c4e84e3..00000000000
--- a/spec/migrations/cleanup_stages_position_migration_spec.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20180604123514_cleanup_stages_position_migration.rb')
-
-describe CleanupStagesPositionMigration, :redis do
- let(:migration) { spy('migration') }
-
- before do
- allow(Gitlab::BackgroundMigration::MigrateStageIndex)
- .to receive(:new).and_return(migration)
- end
-
- context 'when there are pending background migrations' do
- it 'processes pending jobs synchronously' do
- Sidekiq::Testing.disable! do
- BackgroundMigrationWorker
- .perform_in(2.minutes, 'MigrateStageIndex', [1, 1])
- BackgroundMigrationWorker
- .perform_async('MigrateStageIndex', [1, 1])
-
- migrate!
-
- expect(migration).to have_received(:perform).with(1, 1).twice
- end
- end
- end
-
- context 'when there are no background migrations pending' do
- it 'does nothing' do
- Sidekiq::Testing.disable! do
- migrate!
-
- expect(migration).not_to have_received(:perform)
- end
- end
- end
-
- context 'when there are still unmigrated stages present' do
- let(:stages) { table('ci_stages') }
- let(:builds) { table('ci_builds') }
-
- let!(:entities) do
- %w[build test broken].map do |name|
- stages.create(name: name)
- end
- end
-
- before do
- stages.update_all(position: nil)
-
- builds.create(name: 'unit', stage_id: entities.first.id, stage_idx: 1, ref: 'master')
- builds.create(name: 'unit', stage_id: entities.second.id, stage_idx: 1, ref: 'master')
- end
-
- it 'migrates stages sequentially for every stage' do
- expect(stages.all).to all(have_attributes(position: nil))
-
- migrate!
-
- expect(migration).to have_received(:perform)
- .with(entities.first.id, entities.first.id)
- expect(migration).to have_received(:perform)
- .with(entities.second.id, entities.second.id)
- expect(migration).not_to have_received(:perform)
- .with(entities.third.id, entities.third.id)
- end
- end
-end
diff --git a/spec/migrations/create_missing_namespace_for_internal_users_spec.rb b/spec/migrations/create_missing_namespace_for_internal_users_spec.rb
deleted file mode 100644
index 0872f23c02e..00000000000
--- a/spec/migrations/create_missing_namespace_for_internal_users_spec.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'migrate', '20180413022611_create_missing_namespace_for_internal_users.rb')
-
-describe CreateMissingNamespaceForInternalUsers do
- let(:users) { table(:users) }
- let(:namespaces) { table(:namespaces) }
- let(:routes) { table(:routes) }
-
- context "for ghost user" do
- let(:internal_user) do
- users.create!(email: 'test@example.com', projects_limit: 100, username: 'test', ghost: true)
- end
-
- it 'creates the missing namespace' do
- expect(namespaces.find_by(owner_id: internal_user.id)).to be_nil
-
- migrate!
-
- namespace = Namespace.find_by(type: nil, owner_id: internal_user.id)
- route = namespace.route
-
- expect(namespace.path).to eq(route.path)
- expect(namespace.name).to eq(route.name)
- end
-
- it 'sets notification email' do
- users.update(internal_user.id, notification_email: nil)
-
- expect(users.find(internal_user.id).notification_email).to be_nil
-
- migrate!
-
- user = users.find(internal_user.id)
- expect(user.notification_email).to eq(user.email)
- end
- end
-end
diff --git a/spec/migrations/drop_duplicate_protected_tags_spec.rb b/spec/migrations/drop_duplicate_protected_tags_spec.rb
deleted file mode 100644
index 7135a15484c..00000000000
--- a/spec/migrations/drop_duplicate_protected_tags_spec.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'migrate', '20180711103851_drop_duplicate_protected_tags.rb')
-
-describe DropDuplicateProtectedTags do
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:protected_tags) { table(:protected_tags) }
-
- before do
- stub_const("#{described_class}::BATCH_SIZE", 2)
-
- namespaces.create(id: 1, name: 'gitlab-org', path: 'gitlab-org')
- projects.create!(id: 1, namespace_id: 1, name: 'gitlab1', path: 'gitlab1')
- projects.create!(id: 2, namespace_id: 1, name: 'gitlab2', path: 'gitlab2')
- end
-
- it 'removes duplicated protected tags' do
- protected_tags.create!(id: 1, project_id: 1, name: 'foo')
- tag2 = protected_tags.create!(id: 2, project_id: 1, name: 'foo1')
- protected_tags.create!(id: 3, project_id: 1, name: 'foo')
- tag4 = protected_tags.create!(id: 4, project_id: 1, name: 'foo')
- tag5 = protected_tags.create!(id: 5, project_id: 2, name: 'foo')
-
- migrate!
-
- expect(protected_tags.all.count).to eq 3
- expect(protected_tags.all.pluck(:id)).to contain_exactly(tag2.id, tag4.id, tag5.id)
- end
-
- it 'does not remove unique protected tags' do
- tag1 = protected_tags.create!(id: 1, project_id: 1, name: 'foo1')
- tag2 = protected_tags.create!(id: 2, project_id: 1, name: 'foo2')
- tag3 = protected_tags.create!(id: 3, project_id: 1, name: 'foo3')
-
- migrate!
-
- expect(protected_tags.all.count).to eq 3
- expect(protected_tags.all.pluck(:id)).to contain_exactly(tag1.id, tag2.id, tag3.id)
- end
-end
diff --git a/spec/migrations/encrypt_deploy_tokens_tokens_spec.rb b/spec/migrations/encrypt_deploy_tokens_tokens_spec.rb
deleted file mode 100644
index 4d0a0b31571..00000000000
--- a/spec/migrations/encrypt_deploy_tokens_tokens_spec.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-require Rails.root.join('db', 'post_migrate', '20190711201818_encrypt_deploy_tokens_tokens.rb')
-
-describe EncryptDeployTokensTokens do
- let(:migration) { described_class.new }
- let(:deployment_tokens) { table(:deploy_tokens) }
- let(:plaintext) { "secret-token" }
- let(:expires_at) { DateTime.now + 1.year }
- let(:ciphertext) { Gitlab::CryptoHelper.aes256_gcm_encrypt(plaintext) }
-
- describe '#up' do
- it 'keeps plaintext token the same and populates token_encrypted if not present' do
- deploy_token = deployment_tokens.create!(
- name: 'test_token',
- read_repository: true,
- expires_at: expires_at,
- username: 'gitlab-token-1',
- token: plaintext
- )
-
- migration.up
-
- expect(deploy_token.reload.token).to eq(plaintext)
- expect(deploy_token.reload.token_encrypted).to eq(ciphertext)
- end
- end
-
- describe '#down' do
- it 'decrypts encrypted token and saves it' do
- deploy_token = deployment_tokens.create!(
- name: 'test_token',
- read_repository: true,
- expires_at: expires_at,
- username: 'gitlab-token-1',
- token_encrypted: ciphertext
- )
-
- migration.down
-
- expect(deploy_token.reload.token).to eq(plaintext)
- expect(deploy_token.reload.token_encrypted).to eq(ciphertext)
- end
- end
-end
diff --git a/spec/migrations/enqueue_verify_pages_domain_workers_spec.rb b/spec/migrations/enqueue_verify_pages_domain_workers_spec.rb
deleted file mode 100644
index ffb1c04a6c5..00000000000
--- a/spec/migrations/enqueue_verify_pages_domain_workers_spec.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20180216121030_enqueue_verify_pages_domain_workers')
-
-describe EnqueueVerifyPagesDomainWorkers do
- around do |example|
- Sidekiq::Testing.fake! do
- example.run
- end
- end
-
- let(:domains_table) { table(:pages_domains) }
-
- describe '#up' do
- it 'enqueues a verification worker for every domain' do
- domains = Array.new(3) do |i|
- domains_table.create!(domain: "my#{i}.domain.com", verification_code: "123#{i}")
- end
-
- expect { migrate! }.to change(PagesDomainVerificationWorker.jobs, :size).by(3)
-
- enqueued_ids = PagesDomainVerificationWorker.jobs.map { |job| job['args'] }
- expected_ids = domains.map { |domain| [domain.id] }
-
- expect(enqueued_ids).to match_array(expected_ids)
- end
- end
-end
diff --git a/spec/migrations/fill_empty_finished_at_in_deployments_spec.rb b/spec/migrations/fill_empty_finished_at_in_deployments_spec.rb
deleted file mode 100644
index 546a805dec8..00000000000
--- a/spec/migrations/fill_empty_finished_at_in_deployments_spec.rb
+++ /dev/null
@@ -1,72 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20181030135124_fill_empty_finished_at_in_deployments')
-
-describe FillEmptyFinishedAtInDeployments do
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:environments) { table(:environments) }
- let(:deployments) { table(:deployments) }
-
- context 'when a deployment row does not have a value on finished_at' do
- context 'when a deployment succeeded' do
- before do
- namespaces.create!(id: 123, name: 'gitlab1', path: 'gitlab1')
- projects.create!(id: 1, name: 'gitlab1', path: 'gitlab1', namespace_id: 123)
- environments.create!(id: 1, name: 'production', slug: 'production', project_id: 1)
- deployments.create!(id: 1, iid: 1, project_id: 1, environment_id: 1, ref: 'master', sha: 'xxx', tag: false)
- end
-
- it 'correctly replicates finished_at by created_at' do
- expect(deployments.last.created_at).not_to be_nil
- expect(deployments.last.finished_at).to be_nil
-
- migrate!
-
- expect(deployments.last.created_at).not_to be_nil
- expect(deployments.last.finished_at).to eq(deployments.last.created_at)
- end
- end
-
- context 'when a deployment is running' do
- before do
- namespaces.create!(id: 123, name: 'gitlab1', path: 'gitlab1')
- projects.create!(id: 1, name: 'gitlab1', path: 'gitlab1', namespace_id: 123)
- environments.create!(id: 1, name: 'production', slug: 'production', project_id: 1)
- deployments.create!(id: 1, iid: 1, project_id: 1, environment_id: 1, ref: 'master', sha: 'xxx', tag: false, status: 1)
- end
-
- it 'does not fill finished_at' do
- expect(deployments.last.created_at).not_to be_nil
- expect(deployments.last.finished_at).to be_nil
-
- migrate!
-
- expect(deployments.last.created_at).not_to be_nil
- expect(deployments.last.finished_at).to be_nil
- end
- end
- end
-
- context 'when a deployment row does has a value on finished_at' do
- let(:finished_at) { '2018-10-30 11:12:02 UTC' }
-
- before do
- namespaces.create!(id: 123, name: 'gitlab1', path: 'gitlab1')
- projects.create!(id: 1, name: 'gitlab1', path: 'gitlab1', namespace_id: 123)
- environments.create!(id: 1, name: 'production', slug: 'production', project_id: 1)
- deployments.create!(id: 1, iid: 1, project_id: 1, environment_id: 1, ref: 'master', sha: 'xxx', tag: false, finished_at: finished_at)
- end
-
- it 'does not affect existing value' do
- expect(deployments.last.created_at).not_to be_nil
- expect(deployments.last.finished_at).not_to be_nil
-
- migrate!
-
- expect(deployments.last.created_at).not_to be_nil
- expect(deployments.last.finished_at).to eq(finished_at)
- end
- end
-end
diff --git a/spec/migrations/fill_file_store_spec.rb b/spec/migrations/fill_file_store_spec.rb
deleted file mode 100644
index 732fdc2a0bb..00000000000
--- a/spec/migrations/fill_file_store_spec.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20180424151928_fill_file_store')
-
-describe FillFileStore do
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:builds) { table(:ci_builds) }
- let(:job_artifacts) { table(:ci_job_artifacts) }
- let(:lfs_objects) { table(:lfs_objects) }
- let(:uploads) { table(:uploads) }
-
- before do
- namespaces.create!(id: 123, name: 'gitlab1', path: 'gitlab1')
- projects.create!(id: 123, name: 'gitlab1', path: 'gitlab1', namespace_id: 123)
- builds.create!(id: 1)
-
- ##
- # Create rows that have nullfied `file_store` column
- job_artifacts.create!(project_id: 123, job_id: 1, file_type: 1, file_store: nil)
- lfs_objects.create!(oid: 123, size: 10, file: 'file_name', file_store: nil)
- uploads.create!(size: 10, path: 'path', uploader: 'uploader', mount_point: 'file_name', store: nil)
- end
-
- it 'correctly migrates nullified file_store/store column', :sidekiq_might_not_need_inline do
- expect(job_artifacts.where(file_store: nil).count).to eq(1)
- expect(lfs_objects.where(file_store: nil).count).to eq(1)
- expect(uploads.where(store: nil).count).to eq(1)
-
- expect(job_artifacts.where(file_store: 1).count).to eq(0)
- expect(lfs_objects.where(file_store: 1).count).to eq(0)
- expect(uploads.where(store: 1).count).to eq(0)
-
- migrate!
-
- expect(job_artifacts.where(file_store: nil).count).to eq(0)
- expect(lfs_objects.where(file_store: nil).count).to eq(0)
- expect(uploads.where(store: nil).count).to eq(0)
-
- expect(job_artifacts.where(file_store: 1).count).to eq(1)
- expect(lfs_objects.where(file_store: 1).count).to eq(1)
- expect(uploads.where(store: 1).count).to eq(1)
- end
-end
diff --git a/spec/migrations/generate_missing_routes_spec.rb b/spec/migrations/generate_missing_routes_spec.rb
deleted file mode 100644
index bc7cd3bd55e..00000000000
--- a/spec/migrations/generate_missing_routes_spec.rb
+++ /dev/null
@@ -1,86 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'migrate', '20180702134423_generate_missing_routes.rb')
-
-describe GenerateMissingRoutes do
- describe '#up' do
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:routes) { table(:routes) }
-
- it 'creates routes for projects without a route' do
- namespace = namespaces.create!(name: 'GitLab', path: 'gitlab', type: 'Group')
-
- routes.create!(
- path: 'gitlab',
- source_type: 'Namespace',
- source_id: namespace.id
- )
-
- project = projects.create!(
- name: 'GitLab CE',
- path: 'gitlab-ce',
- namespace_id: namespace.id
- )
-
- described_class.new.up
-
- route = routes.find_by(source_type: 'Project')
-
- expect(route.source_id).to eq(project.id)
- expect(route.path).to eq("gitlab/gitlab-ce-#{project.id}")
- end
-
- it 'creates routes for namespaces without a route' do
- namespace = namespaces.create!(name: 'GitLab', path: 'gitlab')
-
- described_class.new.up
-
- route = routes.find_by(source_type: 'Namespace')
-
- expect(route.source_id).to eq(namespace.id)
- expect(route.path).to eq("gitlab-#{namespace.id}")
- end
-
- it 'does not create routes for namespaces that already have a route' do
- namespace = namespaces.create!(name: 'GitLab', path: 'gitlab')
-
- routes.create!(
- path: 'gitlab',
- source_type: 'Namespace',
- source_id: namespace.id
- )
-
- described_class.new.up
-
- expect(routes.count).to eq(1)
- end
-
- it 'does not create routes for projects that already have a route' do
- namespace = namespaces.create!(name: 'GitLab', path: 'gitlab')
-
- routes.create!(
- path: 'gitlab',
- source_type: 'Namespace',
- source_id: namespace.id
- )
-
- project = projects.create!(
- name: 'GitLab CE',
- path: 'gitlab-ce',
- namespace_id: namespace.id
- )
-
- routes.create!(
- path: 'gitlab/gitlab-ce',
- source_type: 'Project',
- source_id: project.id
- )
-
- described_class.new.up
-
- expect(routes.count).to eq(2)
- end
- end
-end
diff --git a/spec/migrations/import_common_metrics_spec.rb b/spec/migrations/import_common_metrics_spec.rb
deleted file mode 100644
index 8c28b46cb38..00000000000
--- a/spec/migrations/import_common_metrics_spec.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'migrate', '20180831164910_import_common_metrics.rb')
-
-describe ImportCommonMetrics do
- describe '#up' do
- it "imports all prometheus metrics" do
- expect(PrometheusMetric.common).to be_empty
-
- migrate!
-
- expect(PrometheusMetric.common).not_to be_empty
- end
- end
-end
diff --git a/spec/migrations/migrate_cluster_configure_worker_sidekiq_queue_spec.rb b/spec/migrations/migrate_cluster_configure_worker_sidekiq_queue_spec.rb
deleted file mode 100644
index a3ed9b722d5..00000000000
--- a/spec/migrations/migrate_cluster_configure_worker_sidekiq_queue_spec.rb
+++ /dev/null
@@ -1,64 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20181219145520_migrate_cluster_configure_worker_sidekiq_queue.rb')
-
-describe MigrateClusterConfigureWorkerSidekiqQueue, :redis do
- include Gitlab::Database::MigrationHelpers
- include StubWorker
-
- context 'when there are jobs in the queue' do
- it 'correctly migrates queue when migrating up' do
- Sidekiq::Testing.disable! do
- stub_worker(queue: 'gcp_cluster:cluster_platform_configure').perform_async('Something', [1])
- stub_worker(queue: 'gcp_cluster:cluster_configure').perform_async('Something', [1])
-
- described_class.new.up
-
- expect(sidekiq_queue_length('gcp_cluster:cluster_platform_configure')).to eq 0
- expect(sidekiq_queue_length('gcp_cluster:cluster_configure')).to eq 2
- end
- end
-
- it 'does not affect other queues under the same namespace' do
- Sidekiq::Testing.disable! do
- stub_worker(queue: 'gcp_cluster:cluster_install_app').perform_async('Something', [1])
- stub_worker(queue: 'gcp_cluster:cluster_provision').perform_async('Something', [1])
- stub_worker(queue: 'gcp_cluster:cluster_wait_for_app_installation').perform_async('Something', [1])
- stub_worker(queue: 'gcp_cluster:wait_for_cluster_creation').perform_async('Something', [1])
- stub_worker(queue: 'gcp_cluster:cluster_wait_for_ingress_ip_address').perform_async('Something', [1])
- stub_worker(queue: 'gcp_cluster:cluster_project_configure').perform_async('Something', [1])
-
- described_class.new.up
-
- expect(sidekiq_queue_length('gcp_cluster:cluster_install_app')).to eq 1
- expect(sidekiq_queue_length('gcp_cluster:cluster_provision')).to eq 1
- expect(sidekiq_queue_length('gcp_cluster:cluster_wait_for_app_installation')).to eq 1
- expect(sidekiq_queue_length('gcp_cluster:wait_for_cluster_creation')).to eq 1
- expect(sidekiq_queue_length('gcp_cluster:cluster_wait_for_ingress_ip_address')).to eq 1
- expect(sidekiq_queue_length('gcp_cluster:cluster_project_configure')).to eq 1
- end
- end
-
- it 'correctly migrates queue when migrating down' do
- Sidekiq::Testing.disable! do
- stub_worker(queue: 'gcp_cluster:cluster_configure').perform_async('Something', [1])
-
- described_class.new.down
-
- expect(sidekiq_queue_length('gcp_cluster:cluster_platform_configure')).to eq 1
- expect(sidekiq_queue_length('gcp_cluster:cluster_configure')).to eq 0
- end
- end
- end
-
- context 'when there are no jobs in the queues' do
- it 'does not raise error when migrating up' do
- expect { described_class.new.up }.not_to raise_error
- end
-
- it 'does not raise error when migrating down' do
- expect { described_class.new.down }.not_to raise_error
- end
- end
-end
diff --git a/spec/migrations/migrate_create_trace_artifact_sidekiq_queue_spec.rb b/spec/migrations/migrate_create_trace_artifact_sidekiq_queue_spec.rb
deleted file mode 100644
index 6e0bd487d1f..00000000000
--- a/spec/migrations/migrate_create_trace_artifact_sidekiq_queue_spec.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20180306074045_migrate_create_trace_artifact_sidekiq_queue.rb')
-
-describe MigrateCreateTraceArtifactSidekiqQueue, :redis do
- include Gitlab::Database::MigrationHelpers
- include StubWorker
-
- context 'when there are jobs in the queues' do
- it 'correctly migrates queue when migrating up' do
- Sidekiq::Testing.disable! do
- stub_worker(queue: 'pipeline_default:create_trace_artifact').perform_async('Something', [1])
- stub_worker(queue: 'pipeline_background:archive_trace').perform_async('Something', [1])
-
- described_class.new.up
-
- expect(sidekiq_queue_length('pipeline_default:create_trace_artifact')).to eq 0
- expect(sidekiq_queue_length('pipeline_background:archive_trace')).to eq 2
- end
- end
-
- it 'does not affect other queues under the same namespace' do
- Sidekiq::Testing.disable! do
- stub_worker(queue: 'pipeline_default:build_coverage').perform_async('Something', [1])
- stub_worker(queue: 'pipeline_default:build_trace_sections').perform_async('Something', [1])
- stub_worker(queue: 'pipeline_default:pipeline_metrics').perform_async('Something', [1])
- stub_worker(queue: 'pipeline_default:pipeline_notification').perform_async('Something', [1])
- stub_worker(queue: 'pipeline_default:update_head_pipeline_for_merge_request').perform_async('Something', [1])
-
- described_class.new.up
-
- expect(sidekiq_queue_length('pipeline_default:build_coverage')).to eq 1
- expect(sidekiq_queue_length('pipeline_default:build_trace_sections')).to eq 1
- expect(sidekiq_queue_length('pipeline_default:pipeline_metrics')).to eq 1
- expect(sidekiq_queue_length('pipeline_default:pipeline_notification')).to eq 1
- expect(sidekiq_queue_length('pipeline_default:update_head_pipeline_for_merge_request')).to eq 1
- end
- end
-
- it 'correctly migrates queue when migrating down' do
- Sidekiq::Testing.disable! do
- stub_worker(queue: 'pipeline_background:archive_trace').perform_async('Something', [1])
-
- described_class.new.down
-
- expect(sidekiq_queue_length('pipeline_default:create_trace_artifact')).to eq 1
- expect(sidekiq_queue_length('pipeline_background:archive_trace')).to eq 0
- end
- end
- end
-
- context 'when there are no jobs in the queues' do
- it 'does not raise error when migrating up' do
- expect { described_class.new.up }.not_to raise_error
- end
-
- it 'does not raise error when migrating down' do
- expect { described_class.new.down }.not_to raise_error
- end
- end
-end
diff --git a/spec/migrations/migrate_forbidden_redirect_uris_spec.rb b/spec/migrations/migrate_forbidden_redirect_uris_spec.rb
deleted file mode 100644
index 7c3cc9f07c8..00000000000
--- a/spec/migrations/migrate_forbidden_redirect_uris_spec.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20181026091631_migrate_forbidden_redirect_uris.rb')
-
-describe MigrateForbiddenRedirectUris do
- let(:oauth_application) { table(:oauth_applications) }
- let(:oauth_access_grant) { table(:oauth_access_grants) }
-
- let!(:control_app) { oauth_application.create(random_params) }
- let!(:control_access_grant) { oauth_application.create(random_params) }
- let!(:forbidden_js_app) { oauth_application.create(random_params.merge(redirect_uri: 'javascript://alert()')) }
- let!(:forbidden_vb_app) { oauth_application.create(random_params.merge(redirect_uri: 'VBSCRIPT://alert()')) }
- let!(:forbidden_access_grant) { oauth_application.create(random_params.merge(redirect_uri: 'vbscript://alert()')) }
-
- context 'oauth application' do
- it 'migrates forbidden javascript URI' do
- expect { migrate! }.to change { forbidden_js_app.reload.redirect_uri }.to('http://forbidden-scheme-has-been-overwritten')
- end
-
- it 'migrates forbidden VBScript URI' do
- expect { migrate! }.to change { forbidden_vb_app.reload.redirect_uri }.to('http://forbidden-scheme-has-been-overwritten')
- end
-
- it 'does not migrate a valid URI' do
- expect { migrate! }.not_to change { control_app.reload.redirect_uri }
- end
- end
-
- context 'access grant' do
- it 'migrates forbidden VBScript URI' do
- expect { migrate! }.to change { forbidden_access_grant.reload.redirect_uri }.to('http://forbidden-scheme-has-been-overwritten')
- end
-
- it 'does not migrate a valid URI' do
- expect { migrate! }.not_to change { control_access_grant.reload.redirect_uri }
- end
- end
-
- def random_params
- {
- name: 'test',
- secret: 'test',
- uid: Doorkeeper::OAuth::Helpers::UniqueToken.generate,
- redirect_uri: 'http://valid.com'
- }
- end
-end
diff --git a/spec/migrations/migrate_legacy_artifacts_to_job_artifacts_spec.rb b/spec/migrations/migrate_legacy_artifacts_to_job_artifacts_spec.rb
deleted file mode 100644
index 5133afdf5b0..00000000000
--- a/spec/migrations/migrate_legacy_artifacts_to_job_artifacts_spec.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20180816161409_migrate_legacy_artifacts_to_job_artifacts.rb')
-
-describe MigrateLegacyArtifactsToJobArtifacts do
- let(:migration_class) { Gitlab::BackgroundMigration::MigrateLegacyArtifacts }
- let(:migration_name) { migration_class.to_s.demodulize }
-
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:pipelines) { table(:ci_pipelines) }
- let(:jobs) { table(:ci_builds) }
- let(:job_artifacts) { table(:ci_job_artifacts) }
- let(:namespace) { namespaces.create!(name: 'gitlab', path: 'gitlab-org') }
- let(:project) { projects.create!(name: 'gitlab', path: 'gitlab-ce', namespace_id: namespace.id) }
- let(:pipeline) { pipelines.create!(project_id: project.id, ref: 'master', sha: 'adf43c3a') }
- let(:archive_file_type) { Gitlab::BackgroundMigration::MigrateLegacyArtifacts::ARCHIVE_FILE_TYPE }
- let(:metadata_file_type) { Gitlab::BackgroundMigration::MigrateLegacyArtifacts::METADATA_FILE_TYPE }
- let(:local_store) { ::ObjectStorage::Store::LOCAL }
- let(:remote_store) { ::ObjectStorage::Store::REMOTE }
- let(:legacy_location) { Gitlab::BackgroundMigration::MigrateLegacyArtifacts::LEGACY_PATH_FILE_LOCATION }
-
- context 'when legacy artifacts exist' do
- before do
- jobs.create!(id: 1, commit_id: pipeline.id, project_id: project.id, status: :success, artifacts_file: 'archive.zip')
- jobs.create!(id: 2, commit_id: pipeline.id, project_id: project.id, status: :failed, artifacts_metadata: 'metadata.gz')
- jobs.create!(id: 3, commit_id: pipeline.id, project_id: project.id, status: :failed, artifacts_file: 'archive.zip', artifacts_metadata: 'metadata.gz')
- jobs.create!(id: 4, commit_id: pipeline.id, project_id: project.id, status: :running)
- jobs.create!(id: 5, commit_id: pipeline.id, project_id: project.id, status: :success, artifacts_file: 'archive.zip', artifacts_file_store: remote_store, artifacts_metadata: 'metadata.gz')
- jobs.create!(id: 6, commit_id: pipeline.id, project_id: project.id, status: :failed, artifacts_file: 'archive.zip', artifacts_metadata: 'metadata.gz')
- end
-
- it 'schedules a background migration' do
- Sidekiq::Testing.fake! do
- Timecop.freeze do
- migrate!
-
- expect(migration_name).to be_scheduled_delayed_migration(5.minutes, 1, 6)
- expect(BackgroundMigrationWorker.jobs.size).to eq 1
- end
- end
- end
-
- it 'migrates legacy artifacts to ci_job_artifacts table', :sidekiq_might_not_need_inline do
- migrate!
-
- expect(job_artifacts.order(:job_id, :file_type).pluck('project_id, job_id, file_type, file_store, size, expire_at, file, file_sha256, file_location'))
- .to eq([[project.id, 1, archive_file_type, local_store, nil, nil, 'archive.zip', nil, legacy_location],
- [project.id, 3, archive_file_type, local_store, nil, nil, 'archive.zip', nil, legacy_location],
- [project.id, 3, metadata_file_type, local_store, nil, nil, 'metadata.gz', nil, legacy_location],
- [project.id, 5, archive_file_type, remote_store, nil, nil, 'archive.zip', nil, legacy_location],
- [project.id, 5, metadata_file_type, local_store, nil, nil, 'metadata.gz', nil, legacy_location],
- [project.id, 6, archive_file_type, local_store, nil, nil, 'archive.zip', nil, legacy_location],
- [project.id, 6, metadata_file_type, local_store, nil, nil, 'metadata.gz', nil, legacy_location]])
- end
- end
-
- context 'when legacy artifacts do not exist' do
- before do
- jobs.create!(id: 1, commit_id: pipeline.id, project_id: project.id, status: :success)
- jobs.create!(id: 2, commit_id: pipeline.id, project_id: project.id, status: :failed, artifacts_metadata: 'metadata.gz')
- end
-
- it 'does not schedule background migrations' do
- Sidekiq::Testing.fake! do
- Timecop.freeze do
- migrate!
-
- expect(BackgroundMigrationWorker.jobs.size).to eq 0
- end
- end
- end
- end
-end
diff --git a/spec/migrations/migrate_null_wiki_access_levels_spec.rb b/spec/migrations/migrate_null_wiki_access_levels_spec.rb
deleted file mode 100644
index f4753f67e17..00000000000
--- a/spec/migrations/migrate_null_wiki_access_levels_spec.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20180809195358_migrate_null_wiki_access_levels.rb')
-
-describe MigrateNullWikiAccessLevels do
- let(:namespaces) { table('namespaces') }
- let(:projects) { table(:projects) }
- let(:project_features) { table(:project_features) }
- let(:migration) { described_class.new }
-
- before do
- namespace = namespaces.create(name: 'foo', path: 'foo')
-
- projects.create!(id: 1, name: 'gitlab1', path: 'gitlab1', namespace_id: namespace.id)
- projects.create!(id: 2, name: 'gitlab2', path: 'gitlab2', namespace_id: namespace.id)
- projects.create!(id: 3, name: 'gitlab3', path: 'gitlab3', namespace_id: namespace.id)
-
- project_features.create!(id: 1, project_id: 1, wiki_access_level: nil)
- project_features.create!(id: 2, project_id: 2, wiki_access_level: 10)
- project_features.create!(id: 3, project_id: 3, wiki_access_level: 20)
- end
-
- describe '#up' do
- it 'migrates existing project_features with wiki_access_level NULL to 20' do
- expect { migration.up }.to change { project_features.where(wiki_access_level: 20).count }.by(1)
- end
- end
-end
diff --git a/spec/migrations/migrate_object_storage_upload_sidekiq_queue_spec.rb b/spec/migrations/migrate_object_storage_upload_sidekiq_queue_spec.rb
deleted file mode 100644
index aa4951b2f14..00000000000
--- a/spec/migrations/migrate_object_storage_upload_sidekiq_queue_spec.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20180603190921_migrate_object_storage_upload_sidekiq_queue.rb')
-
-describe MigrateObjectStorageUploadSidekiqQueue, :redis do
- include Gitlab::Database::MigrationHelpers
- include StubWorker
-
- context 'when there are jobs in the queue' do
- it 'correctly migrates queue when migrating up' do
- Sidekiq::Testing.disable! do
- stub_worker(queue: 'object_storage_upload').perform_async('Something', [1])
- stub_worker(queue: 'object_storage:object_storage_background_move').perform_async('Something', [1])
-
- described_class.new.up
-
- expect(sidekiq_queue_length('object_storage_upload')).to eq 0
- expect(sidekiq_queue_length('object_storage:object_storage_background_move')).to eq 2
- end
- end
- end
-
- context 'when there are no jobs in the queues' do
- it 'does not raise error when migrating up' do
- expect { described_class.new.up }.not_to raise_error
- end
- end
-end
diff --git a/spec/migrations/migrate_update_head_pipeline_for_merge_request_sidekiq_queue_spec.rb b/spec/migrations/migrate_update_head_pipeline_for_merge_request_sidekiq_queue_spec.rb
deleted file mode 100644
index 204c38b3fc5..00000000000
--- a/spec/migrations/migrate_update_head_pipeline_for_merge_request_sidekiq_queue_spec.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20180307012445_migrate_update_head_pipeline_for_merge_request_sidekiq_queue.rb')
-
-describe MigrateUpdateHeadPipelineForMergeRequestSidekiqQueue, :redis do
- include Gitlab::Database::MigrationHelpers
- include StubWorker
-
- context 'when there are jobs in the queues' do
- it 'correctly migrates queue when migrating up' do
- Sidekiq::Testing.disable! do
- stub_worker(queue: 'pipeline_default:update_head_pipeline_for_merge_request').perform_async('Something', [1])
- stub_worker(queue: 'pipeline_processing:update_head_pipeline_for_merge_request').perform_async('Something', [1])
-
- described_class.new.up
-
- expect(sidekiq_queue_length('pipeline_default:update_head_pipeline_for_merge_request')).to eq 0
- expect(sidekiq_queue_length('pipeline_processing:update_head_pipeline_for_merge_request')).to eq 2
- end
- end
-
- it 'does not affect other queues under the same namespace' do
- Sidekiq::Testing.disable! do
- stub_worker(queue: 'pipeline_default:build_coverage').perform_async('Something', [1])
- stub_worker(queue: 'pipeline_default:build_trace_sections').perform_async('Something', [1])
- stub_worker(queue: 'pipeline_default:pipeline_metrics').perform_async('Something', [1])
- stub_worker(queue: 'pipeline_default:pipeline_notification').perform_async('Something', [1])
-
- described_class.new.up
-
- expect(sidekiq_queue_length('pipeline_default:build_coverage')).to eq 1
- expect(sidekiq_queue_length('pipeline_default:build_trace_sections')).to eq 1
- expect(sidekiq_queue_length('pipeline_default:pipeline_metrics')).to eq 1
- expect(sidekiq_queue_length('pipeline_default:pipeline_notification')).to eq 1
- end
- end
-
- it 'correctly migrates queue when migrating down' do
- Sidekiq::Testing.disable! do
- stub_worker(queue: 'pipeline_processing:update_head_pipeline_for_merge_request').perform_async('Something', [1])
-
- described_class.new.down
-
- expect(sidekiq_queue_length('pipeline_default:update_head_pipeline_for_merge_request')).to eq 1
- expect(sidekiq_queue_length('pipeline_processing:update_head_pipeline_for_merge_request')).to eq 0
- end
- end
- end
-
- context 'when there are no jobs in the queues' do
- it 'does not raise error when migrating up' do
- expect { described_class.new.up }.not_to raise_error
- end
-
- it 'does not raise error when migrating down' do
- expect { described_class.new.down }.not_to raise_error
- end
- end
-end
diff --git a/spec/migrations/remove_empty_extern_uid_auth0_identities_spec.rb b/spec/migrations/remove_empty_extern_uid_auth0_identities_spec.rb
deleted file mode 100644
index 5be8706cacf..00000000000
--- a/spec/migrations/remove_empty_extern_uid_auth0_identities_spec.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20180220150310_remove_empty_extern_uid_auth0_identities.rb')
-
-describe RemoveEmptyExternUidAuth0Identities do
- let(:identities) { table(:identities) }
-
- before do
- identities.create(provider: 'auth0', extern_uid: '')
- identities.create(provider: 'auth0', extern_uid: 'valid')
- identities.create(provider: 'github', extern_uid: '')
-
- migrate!
- end
-
- it 'leaves the correct auth0 identity' do
- expect(identities.where(provider: 'auth0').pluck(:extern_uid)).to eq(['valid'])
- end
-
- it 'leaves the correct github identity' do
- expect(identities.where(provider: 'github').count).to eq(1)
- end
-end
diff --git a/spec/migrations/remove_redundant_pipeline_stages_spec.rb b/spec/migrations/remove_redundant_pipeline_stages_spec.rb
deleted file mode 100644
index 9bcbb6022a7..00000000000
--- a/spec/migrations/remove_redundant_pipeline_stages_spec.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20180119121225_remove_redundant_pipeline_stages.rb')
-
-describe RemoveRedundantPipelineStages do
- let(:projects) { table(:projects) }
- let(:pipelines) { table(:ci_pipelines) }
- let(:stages) { table(:ci_stages) }
- let(:builds) { table(:ci_builds) }
-
- before do
- projects.create!(id: 123, name: 'gitlab', path: 'gitlab-ce')
- pipelines.create!(id: 234, project_id: 123, ref: 'master', sha: 'adf43c3a')
-
- stages.create!(id: 6, project_id: 123, pipeline_id: 234, name: 'build')
- stages.create!(id: 10, project_id: 123, pipeline_id: 234, name: 'build')
- stages.create!(id: 21, project_id: 123, pipeline_id: 234, name: 'build')
- stages.create!(id: 41, project_id: 123, pipeline_id: 234, name: 'test')
- stages.create!(id: 62, project_id: 123, pipeline_id: 234, name: 'test')
- stages.create!(id: 102, project_id: 123, pipeline_id: 234, name: 'deploy')
-
- builds.create!(id: 1, commit_id: 234, project_id: 123, stage_id: 10)
- builds.create!(id: 2, commit_id: 234, project_id: 123, stage_id: 21)
- builds.create!(id: 3, commit_id: 234, project_id: 123, stage_id: 21)
- builds.create!(id: 4, commit_id: 234, project_id: 123, stage_id: 41)
- builds.create!(id: 5, commit_id: 234, project_id: 123, stage_id: 62)
- builds.create!(id: 6, commit_id: 234, project_id: 123, stage_id: 102)
- end
-
- it 'removes ambiguous stages and preserves builds' do
- expect(stages.all.count).to eq 6
- expect(builds.all.count).to eq 6
-
- migrate!
-
- expect(stages.all.count).to eq 1
- expect(builds.all.count).to eq 6
- expect(builds.all.pluck(:stage_id).compact).to eq [102]
- end
-
- it 'retries when incorrectly added index exception is caught' do
- allow_any_instance_of(described_class)
- .to receive(:remove_redundant_pipeline_stages!)
-
- expect_any_instance_of(described_class)
- .to receive(:remove_outdated_index!)
- .exactly(100).times.and_call_original
-
- expect { migrate! }
- .to raise_error StandardError, /Failed to add an unique index/
- end
-
- it 'does not retry when unknown exception is being raised' do
- allow(subject).to receive(:remove_outdated_index!)
- expect(subject).to receive(:remove_redundant_pipeline_stages!).once
- allow(subject).to receive(:add_unique_index!).and_raise(StandardError)
-
- expect { subject.up(attempts: 3) }.to raise_error StandardError
- end
-end
diff --git a/spec/migrations/reschedule_builds_stages_migration_spec.rb b/spec/migrations/reschedule_builds_stages_migration_spec.rb
deleted file mode 100644
index 18ea16f97bc..00000000000
--- a/spec/migrations/reschedule_builds_stages_migration_spec.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20180405101928_reschedule_builds_stages_migration')
-
-describe RescheduleBuildsStagesMigration do
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:pipelines) { table(:ci_pipelines) }
- let(:stages) { table(:ci_stages) }
- let(:jobs) { table(:ci_builds) }
-
- before do
- stub_const("#{described_class}::BATCH_SIZE", 1)
-
- namespaces.create(id: 12, name: 'gitlab-org', path: 'gitlab-org')
- projects.create!(id: 123, namespace_id: 12, name: 'gitlab', path: 'gitlab')
- pipelines.create!(id: 1, project_id: 123, ref: 'master', sha: 'adf43c3a')
- stages.create!(id: 1, project_id: 123, pipeline_id: 1, name: 'test')
-
- jobs.create!(id: 11, commit_id: 1, project_id: 123, stage_id: nil)
- jobs.create!(id: 206, commit_id: 1, project_id: 123, stage_id: nil)
- jobs.create!(id: 3413, commit_id: 1, project_id: 123, stage_id: nil)
- jobs.create!(id: 4109, commit_id: 1, project_id: 123, stage_id: 1)
- end
-
- it 'schedules delayed background migrations in batches in bulk' do
- Sidekiq::Testing.fake! do
- Timecop.freeze do
- migrate!
-
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(5.minutes, 11, 11)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(10.minutes, 206, 206)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(15.minutes, 3413, 3413)
- expect(BackgroundMigrationWorker.jobs.size).to eq 3
- end
- end
- end
-end
diff --git a/spec/migrations/reschedule_commits_count_for_merge_request_diff_spec.rb b/spec/migrations/reschedule_commits_count_for_merge_request_diff_spec.rb
deleted file mode 100644
index dcb31dff9b7..00000000000
--- a/spec/migrations/reschedule_commits_count_for_merge_request_diff_spec.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'migrate', '20180309121820_reschedule_commits_count_for_merge_request_diff')
-
-describe RescheduleCommitsCountForMergeRequestDiff do
- let(:merge_request_diffs) { table(:merge_request_diffs) }
- let(:merge_requests) { table(:merge_requests) }
- let(:projects) { table(:projects) }
- let(:namespaces) { table(:namespaces) }
-
- before do
- stub_const("#{described_class.name}::BATCH_SIZE", 1)
-
- namespaces.create!(id: 1, name: 'gitlab', path: 'gitlab')
-
- projects.create!(id: 1, namespace_id: 1)
-
- merge_requests.create!(id: 1, target_project_id: 1, source_project_id: 1, target_branch: 'feature', source_branch: 'master')
-
- merge_request_diffs.create!(id: 1, merge_request_id: 1)
- merge_request_diffs.create!(id: 2, merge_request_id: 1)
- merge_request_diffs.create!(id: 3, merge_request_id: 1, commits_count: 0)
- merge_request_diffs.create!(id: 4, merge_request_id: 1)
- end
-
- it 'correctly schedules background migrations' do
- Sidekiq::Testing.fake! do
- Timecop.freeze do
- migrate!
-
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(5.minutes, 1, 1)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(10.minutes, 2, 2)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(15.minutes, 4, 4)
- expect(BackgroundMigrationWorker.jobs.size).to eq 3
- end
- end
- end
-end
diff --git a/spec/migrations/schedule_digest_personal_access_tokens_spec.rb b/spec/migrations/schedule_digest_personal_access_tokens_spec.rb
deleted file mode 100644
index d8e1b089d31..00000000000
--- a/spec/migrations/schedule_digest_personal_access_tokens_spec.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20180913142237_schedule_digest_personal_access_tokens.rb')
-
-describe ScheduleDigestPersonalAccessTokens do
- let(:personal_access_tokens) { table(:personal_access_tokens) }
- let(:users) { table(:users) }
-
- before do
- stub_const("#{described_class.name}::BATCH_SIZE", 4)
-
- users.create(id: 1, email: 'user@example.com', projects_limit: 10)
-
- personal_access_tokens.create!(id: 1, user_id: 1, name: 'pat-01', token: 'token-01')
- personal_access_tokens.create!(id: 2, user_id: 1, name: 'pat-02', token: 'token-02')
- personal_access_tokens.create!(id: 3, user_id: 1, name: 'pat-03', token_digest: 'token_digest')
- personal_access_tokens.create!(id: 4, user_id: 1, name: 'pat-04', token: 'token-04')
- personal_access_tokens.create!(id: 5, user_id: 1, name: 'pat-05', token: 'token-05')
- personal_access_tokens.create!(id: 6, user_id: 1, name: 'pat-06', token: 'token-06')
- end
-
- it 'correctly schedules background migrations' do
- Sidekiq::Testing.fake! do
- migrate!
-
- expect(described_class::MIGRATION).to(
- be_scheduled_delayed_migration(
- 5.minutes, 'PersonalAccessToken', 'token', 'token_digest', 1, 5))
- expect(described_class::MIGRATION).to(
- be_scheduled_delayed_migration(
- 10.minutes, 'PersonalAccessToken', 'token', 'token_digest', 6, 6))
- expect(BackgroundMigrationWorker.jobs.size).to eq 2
- end
- end
-
- it 'schedules background migrations', :sidekiq_might_not_need_inline do
- perform_enqueued_jobs do
- plain_text_token = 'token IS NOT NULL'
-
- expect(personal_access_tokens.where(plain_text_token).count).to eq 5
-
- migrate!
-
- expect(personal_access_tokens.where(plain_text_token).count).to eq 0
- end
- end
-end
diff --git a/spec/migrations/schedule_runners_token_encryption_spec.rb b/spec/migrations/schedule_runners_token_encryption_spec.rb
deleted file mode 100644
index 4121a8409b4..00000000000
--- a/spec/migrations/schedule_runners_token_encryption_spec.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20181121111200_schedule_runners_token_encryption')
-
-describe ScheduleRunnersTokenEncryption do
- let(:settings) { table(:application_settings) }
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:runners) { table(:ci_runners) }
-
- before do
- stub_const("#{described_class.name}::BATCH_SIZE", 1)
-
- settings.create!(id: 1, runners_registration_token: 'plain-text-token1')
- namespaces.create!(id: 11, name: 'gitlab', path: 'gitlab-org', runners_token: 'my-token1')
- namespaces.create!(id: 12, name: 'gitlab', path: 'gitlab-org', runners_token: 'my-token2')
- projects.create!(id: 111, namespace_id: 11, name: 'gitlab', path: 'gitlab-ce', runners_token: 'my-token1')
- projects.create!(id: 114, namespace_id: 11, name: 'gitlab', path: 'gitlab-ce', runners_token: 'my-token2')
- runners.create!(id: 201, runner_type: 1, token: 'plain-text-token1')
- runners.create!(id: 202, runner_type: 1, token: 'plain-text-token2')
- end
-
- it 'schedules runners token encryption migration for multiple resources' do
- Sidekiq::Testing.fake! do
- Timecop.freeze do
- migrate!
-
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, 'settings', 1, 1)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, 'namespace', 11, 11)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(8.minutes, 'namespace', 12, 12)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, 'project', 111, 111)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(8.minutes, 'project', 114, 114)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, 'runner', 201, 201)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(8.minutes, 'runner', 202, 202)
- expect(BackgroundMigrationWorker.jobs.size).to eq 7
- end
- end
- end
-end
diff --git a/spec/migrations/schedule_set_confidential_note_events_on_webhooks_spec.rb b/spec/migrations/schedule_set_confidential_note_events_on_webhooks_spec.rb
deleted file mode 100644
index ea1e16a0a35..00000000000
--- a/spec/migrations/schedule_set_confidential_note_events_on_webhooks_spec.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20180104131052_schedule_set_confidential_note_events_on_webhooks.rb')
-
-describe ScheduleSetConfidentialNoteEventsOnWebhooks do
- let(:web_hooks_table) { table(:web_hooks) }
- let(:migration_class) { Gitlab::BackgroundMigration::SetConfidentialNoteEventsOnWebhooks }
- let(:migration_name) { migration_class.to_s.demodulize }
-
- let!(:web_hook_1) { web_hooks_table.create!(confidential_note_events: nil, note_events: true) }
- let!(:web_hook_2) { web_hooks_table.create!(confidential_note_events: nil, note_events: true) }
- let!(:web_hook_migrated) { web_hooks_table.create!(confidential_note_events: true, note_events: true) }
- let!(:web_hook_skip) { web_hooks_table.create!(confidential_note_events: nil, note_events: false) }
- let!(:web_hook_new) { web_hooks_table.create!(confidential_note_events: false, note_events: true) }
- let!(:web_hook_4) { web_hooks_table.create!(confidential_note_events: nil, note_events: true) }
-
- before do
- stub_const("#{described_class}::BATCH_SIZE", 1)
- end
-
- it 'schedules background migrations at correct time' do
- Sidekiq::Testing.fake! do
- Timecop.freeze do
- migrate!
-
- expect(migration_name).to be_scheduled_delayed_migration(5.minutes, web_hook_1.id, web_hook_1.id)
- expect(migration_name).to be_scheduled_delayed_migration(10.minutes, web_hook_2.id, web_hook_2.id)
- expect(migration_name).to be_scheduled_delayed_migration(15.minutes, web_hook_4.id, web_hook_4.id)
- expect(BackgroundMigrationWorker.jobs.size).to eq 3
- end
- end
- end
-
- it 'correctly processes web hooks', :sidekiq_might_not_need_inline do
- perform_enqueued_jobs do
- expect(web_hooks_table.where(confidential_note_events: nil).count).to eq 4
- expect(web_hooks_table.where(confidential_note_events: true).count).to eq 1
-
- migrate!
-
- expect(web_hooks_table.where(confidential_note_events: nil).count).to eq 1
- expect(web_hooks_table.where(confidential_note_events: true).count).to eq 4
- end
- end
-end
diff --git a/spec/migrations/schedule_stages_index_migration_spec.rb b/spec/migrations/schedule_stages_index_migration_spec.rb
deleted file mode 100644
index 5ca857087e7..00000000000
--- a/spec/migrations/schedule_stages_index_migration_spec.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20180420080616_schedule_stages_index_migration')
-
-describe ScheduleStagesIndexMigration do
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:pipelines) { table(:ci_pipelines) }
- let(:stages) { table(:ci_stages) }
-
- before do
- stub_const("#{described_class}::BATCH_SIZE", 1)
-
- namespaces.create(id: 12, name: 'gitlab-org', path: 'gitlab-org')
- projects.create!(id: 123, namespace_id: 12, name: 'gitlab', path: 'gitlab')
- pipelines.create!(id: 1, project_id: 123, ref: 'master', sha: 'adf43c3a')
- stages.create!(id: 121, project_id: 123, pipeline_id: 1, name: 'build')
- stages.create!(id: 122, project_id: 123, pipeline_id: 1, name: 'test')
- stages.create!(id: 123, project_id: 123, pipeline_id: 1, name: 'deploy')
- end
-
- it 'schedules delayed background migrations in batches' do
- Sidekiq::Testing.fake! do
- Timecop.freeze do
- expect(stages.all).to all(have_attributes(position: be_nil))
-
- migrate!
-
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(5.minutes, 121, 121)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(10.minutes, 122, 122)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(15.minutes, 123, 123)
- expect(BackgroundMigrationWorker.jobs.size).to eq 3
- end
- end
- end
-end
diff --git a/spec/migrations/schedule_to_archive_legacy_traces_spec.rb b/spec/migrations/schedule_to_archive_legacy_traces_spec.rb
deleted file mode 100644
index 69c4b15a74f..00000000000
--- a/spec/migrations/schedule_to_archive_legacy_traces_spec.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20180529152628_schedule_to_archive_legacy_traces')
-
-describe ScheduleToArchiveLegacyTraces do
- include TraceHelpers
-
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:builds) { table(:ci_builds) }
- let(:job_artifacts) { table(:ci_job_artifacts) }
-
- before do
- namespaces.create!(id: 123, name: 'gitlab1', path: 'gitlab1')
- projects.create!(id: 123, name: 'gitlab1', path: 'gitlab1', namespace_id: 123)
- @build_success = builds.create!(id: 1, project_id: 123, status: 'success', type: 'Ci::Build')
- @build_failed = builds.create!(id: 2, project_id: 123, status: 'failed', type: 'Ci::Build')
- @builds_canceled = builds.create!(id: 3, project_id: 123, status: 'canceled', type: 'Ci::Build')
- @build_running = builds.create!(id: 4, project_id: 123, status: 'running', type: 'Ci::Build')
-
- create_legacy_trace(@build_success, 'This job is done')
- create_legacy_trace(@build_failed, 'This job is done')
- create_legacy_trace(@builds_canceled, 'This job is done')
- create_legacy_trace(@build_running, 'This job is not done yet')
- end
-
- it 'correctly archive legacy traces', :sidekiq_might_not_need_inline do
- expect(job_artifacts.count).to eq(0)
- expect(File.exist?(legacy_trace_path(@build_success))).to be_truthy
- expect(File.exist?(legacy_trace_path(@build_failed))).to be_truthy
- expect(File.exist?(legacy_trace_path(@builds_canceled))).to be_truthy
- expect(File.exist?(legacy_trace_path(@build_running))).to be_truthy
-
- migrate!
-
- expect(job_artifacts.count).to eq(3)
- expect(File.exist?(legacy_trace_path(@build_success))).to be_falsy
- expect(File.exist?(legacy_trace_path(@build_failed))).to be_falsy
- expect(File.exist?(legacy_trace_path(@builds_canceled))).to be_falsy
- expect(File.exist?(legacy_trace_path(@build_running))).to be_truthy
- expect(File.exist?(archived_trace_path(job_artifacts.find_by(job_id: @build_success.id)))).to be_truthy
- expect(File.exist?(archived_trace_path(job_artifacts.find_by(job_id: @build_failed.id)))).to be_truthy
- expect(File.exist?(archived_trace_path(job_artifacts.find_by(job_id: @builds_canceled.id)))).to be_truthy
- expect(job_artifacts.where(job_id: @build_running.id)).not_to be_exist
- end
-end
diff --git a/spec/migrations/seed_repository_storages_weighted_spec.rb b/spec/migrations/seed_repository_storages_weighted_spec.rb
new file mode 100644
index 00000000000..9a68ff5fb2f
--- /dev/null
+++ b/spec/migrations/seed_repository_storages_weighted_spec.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20200526000407_seed_repository_storages_weighted.rb')
+
+describe SeedRepositoryStoragesWeighted do
+ let(:storages) { { "foo" => {}, "baz" => {} } }
+ let(:application_settings) do
+ table(:application_settings).tap do |klass|
+ klass.class_eval do
+ serialize :repository_storages
+ end
+ end
+ end
+
+ before do
+ allow(Gitlab.config.repositories).to receive(:storages).and_return(storages)
+ end
+
+ let(:application_setting) { application_settings.create }
+ let(:repository_storages) { ["foo"] }
+
+ it 'correctly schedules background migrations' do
+ application_setting.repository_storages = repository_storages
+ application_setting.save!
+
+ migrate!
+
+ expect(application_settings.find(application_setting.id).repository_storages_weighted).to eq({ "foo" => 100, "baz" => 0 })
+ end
+end
diff --git a/spec/migrations/steal_fill_store_upload_spec.rb b/spec/migrations/steal_fill_store_upload_spec.rb
deleted file mode 100644
index b5e3de1864c..00000000000
--- a/spec/migrations/steal_fill_store_upload_spec.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20181105201455_steal_fill_store_upload.rb')
-
-describe StealFillStoreUpload do
- let(:uploads) { table(:uploads) }
-
- describe '#up' do
- it 'steals the FillStoreUpload background migration' do
- expect(Gitlab::BackgroundMigration).to receive(:steal).with('FillStoreUpload').and_call_original
-
- migrate!
- end
-
- it 'does not run migration if not needed' do
- uploads.create(size: 100.kilobytes,
- uploader: 'AvatarUploader',
- path: 'uploads/-/system/avatar.jpg',
- store: 1)
-
- expect_any_instance_of(Gitlab::BackgroundMigration::FillStoreUpload).not_to receive(:perform)
-
- migrate!
- end
-
- it 'ensures all rows are migrated' do
- uploads.create(size: 100.kilobytes,
- uploader: 'AvatarUploader',
- path: 'uploads/-/system/avatar.jpg',
- store: nil)
-
- expect_any_instance_of(Gitlab::BackgroundMigration::FillStoreUpload).to receive(:perform).and_call_original
-
- expect do
- migrate!
- end.to change { uploads.where(store: nil).count }.from(1).to(0)
- end
- end
-end
diff --git a/spec/migrations/update_project_import_visibility_level_spec.rb b/spec/migrations/update_project_import_visibility_level_spec.rb
deleted file mode 100644
index f8439fc4204..00000000000
--- a/spec/migrations/update_project_import_visibility_level_spec.rb
+++ /dev/null
@@ -1,86 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20181219130552_update_project_import_visibility_level.rb')
-
-describe UpdateProjectImportVisibilityLevel do
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:project) { projects.find_by_name(name) }
-
- before do
- stub_const("#{described_class}::BATCH_SIZE", 1)
- end
-
- context 'private visibility level' do
- let(:name) { 'private-public' }
-
- it 'updates the project visibility' do
- create_namespace(name, Gitlab::VisibilityLevel::PRIVATE)
- create_project(name, Gitlab::VisibilityLevel::PUBLIC)
-
- expect { migrate! }.to change { project.reload.visibility_level }.to(Gitlab::VisibilityLevel::PRIVATE)
- end
- end
-
- context 'internal visibility level' do
- let(:name) { 'internal-public' }
-
- it 'updates the project visibility' do
- create_namespace(name, Gitlab::VisibilityLevel::INTERNAL)
- create_project(name, Gitlab::VisibilityLevel::PUBLIC)
-
- expect { migrate! }.to change { project.reload.visibility_level }.to(Gitlab::VisibilityLevel::INTERNAL)
- end
- end
-
- context 'public visibility level' do
- let(:name) { 'public-public' }
-
- it 'does not update the project visibility' do
- create_namespace(name, Gitlab::VisibilityLevel::PUBLIC)
- create_project(name, Gitlab::VisibilityLevel::PUBLIC)
-
- expect { migrate! }.not_to change { project.reload.visibility_level }
- end
- end
-
- context 'private project visibility level' do
- let(:name) { 'public-private' }
-
- it 'does not update the project visibility' do
- create_namespace(name, Gitlab::VisibilityLevel::PUBLIC)
- create_project(name, Gitlab::VisibilityLevel::PRIVATE)
-
- expect { migrate! }.not_to change { project.reload.visibility_level }
- end
- end
-
- context 'no namespace' do
- let(:name) { 'no-namespace' }
-
- it 'does not update the project visibility' do
- create_namespace(name, Gitlab::VisibilityLevel::PRIVATE, type: nil)
- create_project(name, Gitlab::VisibilityLevel::PUBLIC)
-
- expect { migrate! }.not_to change { project.reload.visibility_level }
- end
- end
-
- def create_namespace(name, visibility, options = {})
- namespaces.create({
- name: name,
- path: name,
- type: 'Group',
- visibility_level: visibility
- }.merge(options))
- end
-
- def create_project(name, visibility)
- projects.create!(namespace_id: namespaces.find_by_name(name).id,
- name: name,
- path: name,
- import_type: 'gitlab_project',
- visibility_level: visibility)
- end
-end
diff --git a/spec/migrations/update_routes_for_lost_and_found_group_and_orphaned_projects_spec.rb b/spec/migrations/update_routes_for_lost_and_found_group_and_orphaned_projects_spec.rb
new file mode 100644
index 00000000000..4cf096b9df6
--- /dev/null
+++ b/spec/migrations/update_routes_for_lost_and_found_group_and_orphaned_projects_spec.rb
@@ -0,0 +1,182 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require Rails.root.join('db', 'post_migrate', '20200602143020_update_routes_for_lost_and_found_group_and_orphaned_projects.rb')
+
+describe UpdateRoutesForLostAndFoundGroupAndOrphanedProjects, :migration do
+ let(:users) { table(:users) }
+ let(:namespaces) { table(:namespaces) }
+ let(:members) { table(:members) }
+ let(:projects) { table(:projects) }
+ let(:routes) { table(:routes) }
+
+ before do
+ # Create a Ghost User and its namnespace, but skip the route
+ ghost_user = users.create!(
+ name: 'Ghost User',
+ username: 'ghost',
+ email: 'ghost@example.com',
+ user_type: described_class::User::USER_TYPE_GHOST,
+ projects_limit: 100,
+ state: :active,
+ bio: 'This is a "Ghost User"'
+ )
+
+ namespaces.create!(
+ name: 'Ghost User',
+ path: 'ghost',
+ owner_id: ghost_user.id,
+ visibility_level: 20
+ )
+
+ # Create the 'lost-and-found', owned by the Ghost user, but with no route
+ lost_and_found_group = namespaces.create!(
+ name: described_class::User::LOST_AND_FOUND_GROUP,
+ path: described_class::User::LOST_AND_FOUND_GROUP,
+ type: 'Group',
+ description: 'Group to store orphaned projects',
+ visibility_level: 0
+ )
+
+ members.create!(
+ type: 'GroupMember',
+ source_id: lost_and_found_group.id,
+ user_id: ghost_user.id,
+ source_type: 'Namespace',
+ access_level: described_class::User::ACCESS_LEVEL_OWNER,
+ notification_level: 3
+ )
+
+ # Add an orphaned project under 'lost-and-found' but with the wrong path in its route
+ orphaned_project = projects.create!(
+ name: 'orphaned_project',
+ path: 'orphaned_project',
+ visibility_level: 20,
+ archived: false,
+ namespace_id: lost_and_found_group.id
+ )
+
+ routes.create!(
+ source_id: orphaned_project.id,
+ source_type: 'Project',
+ path: 'orphaned_project',
+ name: 'orphaned_project',
+ created_at: Time.zone.now,
+ updated_at: Time.zone.now
+ )
+
+ # Create another user named ghost which is not the Ghost User
+ # Also create a 'lost-and-found' group for them and add projects to it
+ # Purpose: test that the routes added for the 'lost-and-found' group and
+ # its projects are unique
+ fake_ghost_user = users.create!(
+ name: 'Ghost User',
+ username: 'ghost1',
+ email: 'ghost1@example.com',
+ user_type: nil,
+ projects_limit: 100,
+ state: :active,
+ bio: 'This is NOT a "Ghost User"'
+ )
+
+ fake_ghost_user_namespace = namespaces.create!(
+ name: 'Ghost User',
+ path: 'ghost1',
+ owner_id: fake_ghost_user.id,
+ visibility_level: 20
+ )
+
+ routes.create!(
+ source_id: fake_ghost_user_namespace.id,
+ source_type: 'Namespace',
+ path: 'Ghost User',
+ name: 'ghost1',
+ created_at: Time.zone.now,
+ updated_at: Time.zone.now
+ )
+
+ fake_lost_and_found_group = namespaces.create!(
+ name: 'Lost and Found',
+ path: described_class::User::LOST_AND_FOUND_GROUP, # same path as the lost-and-found group
+ type: 'Group',
+ description: 'Fake lost and found group with the same path as the real one',
+ visibility_level: 20
+ )
+
+ routes.create!(
+ source_id: fake_lost_and_found_group.id,
+ source_type: 'Namespace',
+ path: described_class::User::LOST_AND_FOUND_GROUP, # same path as the lost-and-found group
+ name: 'Lost and Found',
+ created_at: Time.zone.now,
+ updated_at: Time.zone.now
+ )
+
+ members.create!(
+ type: 'GroupMember',
+ source_id: fake_lost_and_found_group.id,
+ user_id: fake_ghost_user.id,
+ source_type: 'Namespace',
+ access_level: described_class::User::ACCESS_LEVEL_OWNER,
+ notification_level: 3
+ )
+
+ normal_project = projects.create!(
+ name: 'normal_project',
+ path: 'normal_project',
+ visibility_level: 20,
+ archived: false,
+ namespace_id: fake_lost_and_found_group.id
+ )
+
+ routes.create!(
+ source_id: normal_project.id,
+ source_type: 'Project',
+ path: "#{described_class::User::LOST_AND_FOUND_GROUP}/normal_project",
+ name: 'Lost and Found / normal_project',
+ created_at: Time.zone.now,
+ updated_at: Time.zone.now
+ )
+ end
+
+ it 'creates the route for the ghost user namespace' do
+ expect(routes.where(path: 'ghost').count).to eq(0)
+
+ disable_migrations_output { migrate! }
+
+ expect(routes.where(path: 'ghost').count).to eq(1)
+ end
+
+ it 'fixes the path for the lost-and-found group by generating a unique one' do
+ expect(namespaces.where(path: described_class::User::LOST_AND_FOUND_GROUP).count).to eq(2)
+
+ disable_migrations_output { migrate! }
+
+ expect(namespaces.where(path: described_class::User::LOST_AND_FOUND_GROUP).count).to eq(1)
+
+ lost_and_found_group = namespaces.find_by(name: described_class::User::LOST_AND_FOUND_GROUP)
+ expect(lost_and_found_group.path).to eq('lost-and-found1')
+ end
+
+ it 'creates the route for the lost-and-found group' do
+ expect(routes.where(path: described_class::User::LOST_AND_FOUND_GROUP).count).to eq(1)
+ expect(routes.where(path: 'lost-and-found1').count).to eq(0)
+
+ disable_migrations_output { migrate! }
+
+ expect(routes.where(path: described_class::User::LOST_AND_FOUND_GROUP).count).to eq(1)
+ expect(routes.where(path: 'lost-and-found1').count).to eq(1)
+ end
+
+ it 'updates the route for the orphaned project' do
+ orphaned_project_route = routes.find_by(path: 'orphaned_project')
+ expect(orphaned_project_route.name).to eq('orphaned_project')
+
+ disable_migrations_output { migrate! }
+
+ updated_route = routes.find_by(id: orphaned_project_route.id)
+ expect(updated_route.path).to eq('lost-and-found1/orphaned_project')
+ expect(updated_route.name).to eq("#{described_class::User::LOST_AND_FOUND_GROUP} / orphaned_project")
+ end
+end
diff --git a/spec/models/active_session_spec.rb b/spec/models/active_session_spec.rb
index 6a97d91b3ca..24b47be3c69 100644
--- a/spec/models/active_session_spec.rb
+++ b/spec/models/active_session_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe ActiveSession, :clean_gitlab_redis_shared_state do
double(:request, {
user_agent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_3 like Mac OS X) AppleWebKit/600.1.4 ' \
'(KHTML, like Gecko) Mobile/12B466 [FBDV/iPhone7,2]',
- ip: '127.0.0.1',
+ remote_ip: '127.0.0.1',
session: session
})
end
diff --git a/spec/models/alert_management/alert_assignee_spec.rb b/spec/models/alert_management/alert_assignee_spec.rb
new file mode 100644
index 00000000000..c51a5d543ab
--- /dev/null
+++ b/spec/models/alert_management/alert_assignee_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe AlertManagement::AlertAssignee do
+ describe 'associations' do
+ it { is_expected.to belong_to(:alert) }
+ it { is_expected.to belong_to(:assignee) }
+ end
+
+ describe 'validations' do
+ let(:alert) { create(:alert_management_alert) }
+ let(:user) { create(:user) }
+
+ subject { alert.alert_assignees.build(assignee: user) }
+
+ it { is_expected.to validate_presence_of(:alert) }
+ it { is_expected.to validate_presence_of(:assignee) }
+ it { is_expected.to validate_uniqueness_of(:assignee).scoped_to(:alert_id) }
+ end
+end
diff --git a/spec/models/alert_management/alert_spec.rb b/spec/models/alert_management/alert_spec.rb
index 1da0c6d4071..27b8bb48073 100644
--- a/spec/models/alert_management/alert_spec.rb
+++ b/spec/models/alert_management/alert_spec.rb
@@ -6,6 +6,10 @@ describe AlertManagement::Alert do
describe 'associations' do
it { is_expected.to belong_to(:project) }
it { is_expected.to belong_to(:issue) }
+ it { is_expected.to have_many(:assignees).through(:alert_assignees) }
+ it { is_expected.to have_many(:notes) }
+ it { is_expected.to have_many(:ordered_notes) }
+ it { is_expected.to have_many(:user_mentions) }
end
describe 'validations' do
@@ -241,6 +245,12 @@ describe AlertManagement::Alert do
end
end
+ describe '#to_reference' do
+ let(:alert) { build(:alert_management_alert) }
+
+ it { expect(alert.to_reference).to eq('') }
+ end
+
describe '#trigger' do
subject { alert.trigger }
@@ -317,4 +327,14 @@ describe AlertManagement::Alert do
expect { subject }.to change { alert.reload.ended_at }.to nil
end
end
+
+ describe '#register_new_event!' do
+ subject { alert.register_new_event! }
+
+ let(:alert) { create(:alert_management_alert) }
+
+ it 'increments the events count by 1' do
+ expect { subject }.to change { alert.events }.by(1)
+ end
+ end
end
diff --git a/spec/models/alert_management/alert_user_mention_spec.rb b/spec/models/alert_management/alert_user_mention_spec.rb
new file mode 100644
index 00000000000..cce090a2231
--- /dev/null
+++ b/spec/models/alert_management/alert_user_mention_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe AlertManagement::AlertUserMention do
+ describe 'associations' do
+ it { is_expected.to belong_to(:alert_management_alert) }
+ it { is_expected.to belong_to(:note) }
+ end
+
+ it_behaves_like 'has user mentions'
+end
diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb
index 64308af38f9..96bf19439a1 100644
--- a/spec/models/application_setting_spec.rb
+++ b/spec/models/application_setting_spec.rb
@@ -105,6 +105,14 @@ describe ApplicationSetting do
it { is_expected.not_to allow_value(false).for(:hashed_storage_enabled) }
+ it { is_expected.not_to allow_value(101).for(:repository_storages_weighted_default) }
+ it { is_expected.not_to allow_value(-1).for(:repository_storages_weighted_default) }
+ it { is_expected.to allow_value(100).for(:repository_storages_weighted_default) }
+ it { is_expected.to allow_value(0).for(:repository_storages_weighted_default) }
+ it { is_expected.to allow_value(50).for(:repository_storages_weighted_default) }
+ it { is_expected.to allow_value(nil).for(:repository_storages_weighted_default) }
+ it { is_expected.not_to allow_value({ default: 100, shouldntexist: 50 }).for(:repository_storages_weighted) }
+
context 'grafana_url validations' do
before do
subject.instance_variable_set(:@parsed_grafana_url, nil)
@@ -152,6 +160,30 @@ describe ApplicationSetting do
end
end
+ describe 'spam_check_endpoint' do
+ context 'when spam_check_endpoint is enabled' do
+ before do
+ setting.spam_check_endpoint_enabled = true
+ end
+
+ it { is_expected.to allow_value('https://example.org/spam_check').for(:spam_check_endpoint_url) }
+ it { is_expected.not_to allow_value('nonsense').for(:spam_check_endpoint_url) }
+ it { is_expected.not_to allow_value(nil).for(:spam_check_endpoint_url) }
+ it { is_expected.not_to allow_value('').for(:spam_check_endpoint_url) }
+ end
+
+ context 'when spam_check_endpoint is NOT enabled' do
+ before do
+ setting.spam_check_endpoint_enabled = false
+ end
+
+ it { is_expected.to allow_value('https://example.org/spam_check').for(:spam_check_endpoint_url) }
+ it { is_expected.not_to allow_value('nonsense').for(:spam_check_endpoint_url) }
+ it { is_expected.to allow_value(nil).for(:spam_check_endpoint_url) }
+ it { is_expected.to allow_value('').for(:spam_check_endpoint_url) }
+ end
+ end
+
context 'when snowplow is enabled' do
before do
setting.snowplow_enabled = true
@@ -251,6 +283,14 @@ describe ApplicationSetting do
.is_greater_than(0)
end
+ it { is_expected.to validate_presence_of(:max_import_size) }
+
+ it do
+ is_expected.to validate_numericality_of(:max_import_size)
+ .only_integer
+ .is_greater_than_or_equal_to(0)
+ end
+
it do
is_expected.to validate_numericality_of(:local_markdown_version)
.only_integer
@@ -762,4 +802,17 @@ describe ApplicationSetting do
end
it_behaves_like 'application settings examples'
+
+ describe 'repository_storages_weighted_attributes' do
+ it 'returns the keys for repository_storages_weighted' do
+ expect(subject.class.repository_storages_weighted_attributes).to eq([:repository_storages_weighted_default])
+ end
+ end
+
+ it 'does not allow to set weight for non existing storage' do
+ setting.repository_storages_weighted = { invalid_storage: 100 }
+
+ expect(setting).not_to be_valid
+ expect(setting.errors.messages[:repository_storages_weighted]).to match_array(["can't include: invalid_storage"])
+ end
end
diff --git a/spec/models/blob_viewer/go_mod_spec.rb b/spec/models/blob_viewer/go_mod_spec.rb
new file mode 100644
index 00000000000..ba6038533ea
--- /dev/null
+++ b/spec/models/blob_viewer/go_mod_spec.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe BlobViewer::GoMod do
+ include FakeBlobHelpers
+
+ let(:project) { build_stubbed(:project) }
+ let(:data) do
+ <<-SPEC.strip_heredoc
+ module #{Settings.build_gitlab_go_url}/#{project.full_path}
+ SPEC
+ end
+ let(:blob) { fake_blob(path: 'go.mod', data: data) }
+
+ subject { described_class.new(blob) }
+
+ describe '#package_name' do
+ it 'returns the package name' do
+ expect(subject.package_name).to eq("#{Settings.build_gitlab_go_url}/#{project.full_path}")
+ end
+ end
+
+ describe '#package_url' do
+ it 'returns the package URL' do
+ expect(subject.package_url).to eq("#{Gitlab.config.gitlab.protocol}://#{Settings.build_gitlab_go_url}/#{project.full_path}/")
+ end
+
+ context 'when the homepage has an invalid URL' do
+ let(:data) do
+ <<-SPEC.strip_heredoc
+ module javascript:alert()
+ SPEC
+ end
+
+ it 'returns nil' do
+ expect(subject.package_url).to be_nil
+ end
+ end
+ end
+
+ describe '#package_type' do
+ it 'returns "package"' do
+ expect(subject.package_type).to eq('go')
+ end
+ end
+
+ context 'when the module name does not start with the instance URL' do
+ let(:data) do
+ <<-SPEC.strip_heredoc
+ module example.com/foo/bar
+ SPEC
+ end
+
+ subject { described_class.new(blob) }
+
+ describe '#package_url' do
+ it 'returns the pkg.go.dev URL' do
+ expect(subject.package_url).to eq("https://pkg.go.dev/example.com/foo/bar")
+ end
+ end
+ end
+end
diff --git a/spec/models/blob_viewer/metrics_dashboard_yml_spec.rb b/spec/models/blob_viewer/metrics_dashboard_yml_spec.rb
new file mode 100644
index 00000000000..f5b8586975d
--- /dev/null
+++ b/spec/models/blob_viewer/metrics_dashboard_yml_spec.rb
@@ -0,0 +1,127 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe BlobViewer::MetricsDashboardYml do
+ include FakeBlobHelpers
+ include RepoHelpers
+
+ let_it_be(:project) { create(:project, :repository) }
+ let(:blob) { fake_blob(path: '.gitlab/dashboards/custom-dashboard.yml', data: data) }
+ let(:sha) { sample_commit.id }
+
+ subject(:viewer) { described_class.new(blob) }
+
+ context 'when the definition is valid' do
+ let(:data) { File.read(Rails.root.join('config/prometheus/common_metrics.yml')) }
+
+ describe '#valid?' do
+ it 'calls prepare! on the viewer' do
+ allow(PerformanceMonitoring::PrometheusDashboard).to receive(:from_json)
+
+ expect(viewer).to receive(:prepare!)
+
+ viewer.valid?
+ end
+
+ it 'returns true', :aggregate_failures do
+ yml = ::Gitlab::Config::Loader::Yaml.new(data).load_raw!
+
+ expect_next_instance_of(::Gitlab::Config::Loader::Yaml, data) do |loader|
+ expect(loader).to receive(:load_raw!).and_call_original
+ end
+ expect(PerformanceMonitoring::PrometheusDashboard)
+ .to receive(:from_json)
+ .with(yml)
+ .and_call_original
+ expect(viewer.valid?).to be_truthy
+ end
+ end
+
+ describe '#errors' do
+ it 'returns nil' do
+ allow(PerformanceMonitoring::PrometheusDashboard).to receive(:from_json)
+
+ expect(viewer.errors).to be nil
+ end
+ end
+ end
+
+ context 'when definition is invalid' do
+ let(:error) { ActiveModel::ValidationError.new(PerformanceMonitoring::PrometheusDashboard.new.tap(&:validate)) }
+ let(:data) do
+ <<~YAML
+ dashboard:
+ YAML
+ end
+
+ describe '#valid?' do
+ it 'returns false' do
+ expect(PerformanceMonitoring::PrometheusDashboard)
+ .to receive(:from_json).and_raise(error)
+
+ expect(viewer.valid?).to be_falsey
+ end
+ end
+
+ describe '#errors' do
+ it 'returns validation errors' do
+ allow(PerformanceMonitoring::PrometheusDashboard)
+ .to receive(:from_json).and_raise(error)
+
+ expect(viewer.errors).to be error.model.errors
+ end
+ end
+ end
+
+ context 'when YAML syntax is invalid' do
+ let(:data) do
+ <<~YAML
+ dashboard: 'empty metrics'
+ panel_groups:
+ - group: 'Group Title'
+ YAML
+ end
+
+ describe '#valid?' do
+ it 'returns false' do
+ expect(PerformanceMonitoring::PrometheusDashboard).not_to receive(:from_json)
+ expect(viewer.valid?).to be_falsey
+ end
+ end
+
+ describe '#errors' do
+ it 'returns validation errors' do
+ yaml_wrapped_errors = { 'YAML syntax': ["(<unknown>): did not find expected key while parsing a block mapping at line 1 column 1"] }
+
+ expect(viewer.errors).to be_kind_of ActiveModel::Errors
+ expect(viewer.errors.messages).to eql(yaml_wrapped_errors)
+ end
+ end
+ end
+
+ context 'when YAML loader raises error' do
+ let(:data) do
+ <<~YAML
+ large yaml file
+ YAML
+ end
+
+ before do
+ allow(::Gitlab::Config::Loader::Yaml).to receive(:new)
+ .and_raise(::Gitlab::Config::Loader::Yaml::DataTooLargeError, 'The parsed YAML is too big')
+ end
+
+ it 'is invalid' do
+ expect(PerformanceMonitoring::PrometheusDashboard).not_to receive(:from_json)
+ expect(viewer.valid?).to be(false)
+ end
+
+ it 'returns validation errors' do
+ yaml_wrapped_errors = { 'YAML syntax': ["The parsed YAML is too big"] }
+
+ expect(viewer.errors).to be_kind_of(ActiveModel::Errors)
+ expect(viewer.errors.messages).to eq(yaml_wrapped_errors)
+ end
+ end
+end
diff --git a/spec/models/broadcast_message_spec.rb b/spec/models/broadcast_message_spec.rb
index 127faa5e8e2..8032f913d86 100644
--- a/spec/models/broadcast_message_spec.rb
+++ b/spec/models/broadcast_message_spec.rb
@@ -66,7 +66,7 @@ describe BroadcastMessage do
end
it 'expires the value if a broadcast message has ended', :request_store do
- message = create(:broadcast_message, broadcast_type: broadcast_type, ends_at: Time.now.utc + 1.day)
+ message = create(:broadcast_message, broadcast_type: broadcast_type, ends_at: Time.current.utc + 1.day)
expect(subject.call).to match_array([message])
expect(described_class.cache).to receive(:expire).and_call_original
@@ -87,8 +87,8 @@ describe BroadcastMessage do
future = create(
:broadcast_message,
- starts_at: Time.now + 10.minutes,
- ends_at: Time.now + 20.minutes,
+ starts_at: Time.current + 10.minutes,
+ ends_at: Time.current + 20.minutes,
broadcast_type: broadcast_type
)
diff --git a/spec/models/ci/bridge_spec.rb b/spec/models/ci/bridge_spec.rb
index 34f89d9cdae..385261e0ee9 100644
--- a/spec/models/ci/bridge_spec.rb
+++ b/spec/models/ci/bridge_spec.rb
@@ -21,6 +21,11 @@ describe Ci::Bridge do
expect(bridge).to have_many(:sourced_pipelines)
end
+ it 'has one downstream pipeline' do
+ expect(bridge).to have_one(:sourced_pipeline)
+ expect(bridge).to have_one(:downstream_pipeline)
+ end
+
describe '#tags' do
it 'only has a bridge tag' do
expect(bridge.tags).to eq [:bridge]
diff --git a/spec/models/ci/build_report_result_spec.rb b/spec/models/ci/build_report_result_spec.rb
new file mode 100644
index 00000000000..078b0d100a1
--- /dev/null
+++ b/spec/models/ci/build_report_result_spec.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Ci::BuildReportResult do
+ let(:build_report_result) { build(:ci_build_report_result, :with_junit_success) }
+
+ describe 'associations' do
+ it { is_expected.to belong_to(:build) }
+ it { is_expected.to belong_to(:project) }
+ end
+
+ describe 'validations' do
+ it { is_expected.to validate_presence_of(:project) }
+ it { is_expected.to validate_presence_of(:build) }
+
+ context 'when attributes are valid' do
+ it 'returns no errors' do
+ expect(build_report_result).to be_valid
+ end
+ end
+
+ context 'when data is invalid' do
+ it 'returns errors' do
+ build_report_result.data = { invalid: 'data' }
+
+ expect(build_report_result).to be_invalid
+ expect(build_report_result.errors.full_messages).to eq(["Data must be a valid json schema"])
+ end
+ end
+ end
+
+ describe '#tests_name' do
+ it 'returns the suite name' do
+ expect(build_report_result.tests_name).to eq("rspec")
+ end
+ end
+
+ describe '#tests_duration' do
+ it 'returns the suite duration' do
+ expect(build_report_result.tests_duration).to eq(0.42)
+ end
+ end
+
+ describe '#tests_success' do
+ it 'returns the success count' do
+ expect(build_report_result.tests_success).to eq(2)
+ end
+ end
+
+ describe '#tests_failed' do
+ it 'returns the failed count' do
+ expect(build_report_result.tests_failed).to eq(0)
+ end
+ end
+
+ describe '#tests_errored' do
+ it 'returns the errored count' do
+ expect(build_report_result.tests_errored).to eq(0)
+ end
+ end
+
+ describe '#tests_skipped' do
+ it 'returns the skipped count' do
+ expect(build_report_result.tests_skipped).to eq(0)
+ end
+ end
+
+ describe '#tests_total' do
+ it 'returns the total count' do
+ expect(build_report_result.tests_total).to eq(2)
+ end
+ end
+end
diff --git a/spec/models/ci/build_runner_session_spec.rb b/spec/models/ci/build_runner_session_spec.rb
index cdf56f24cd7..3e520407884 100644
--- a/spec/models/ci/build_runner_session_spec.rb
+++ b/spec/models/ci/build_runner_session_spec.rb
@@ -63,4 +63,64 @@ describe Ci::BuildRunnerSession, model: true do
end
end
end
+
+ describe '#service_specification' do
+ let(:service) { 'foo'}
+ let(:port) { 80 }
+ let(:path) { 'path' }
+ let(:subprotocols) { nil }
+ let(:specification) { subject.service_specification(service: service, port: port, path: path, subprotocols: subprotocols) }
+
+ it 'returns service proxy url' do
+ expect(specification[:url]).to eq "https://localhost/proxy/#{service}/#{port}/#{path}"
+ end
+
+ it 'returns default service proxy websocket subprotocol' do
+ expect(specification[:subprotocols]).to eq %w[terminal.gitlab.com]
+ end
+
+ it 'returns empty hash if no url' do
+ subject.url = ''
+
+ expect(specification).to be_empty
+ end
+
+ context 'when port is not present' do
+ let(:port) { nil }
+
+ it 'uses the default port name' do
+ expect(specification[:url]).to eq "https://localhost/proxy/#{service}/default_port/#{path}"
+ end
+ end
+
+ context 'when the service is not present' do
+ let(:service) { '' }
+
+ it 'uses the service name "build" as default' do
+ expect(specification[:url]).to eq "https://localhost/proxy/build/#{port}/#{path}"
+ end
+ end
+
+ context 'when url is present' do
+ it 'returns ca_pem nil if empty certificate' do
+ subject.certificate = ''
+
+ expect(specification[:ca_pem]).to be_nil
+ end
+
+ it 'adds Authorization header if authorization is present' do
+ subject.authorization = 'foobar'
+
+ expect(specification[:headers]).to include(Authorization: ['foobar'])
+ end
+ end
+
+ context 'when subprotocol is present' do
+ let(:subprotocols) { 'foobar' }
+
+ it 'returns the new subprotocol' do
+ expect(specification[:subprotocols]).to eq [subprotocols]
+ end
+ end
+ end
end
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index 6605866d9c0..6fdd8463329 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -24,6 +24,7 @@ describe Ci::Build do
it { is_expected.to have_many(:needs) }
it { is_expected.to have_many(:sourced_pipelines) }
it { is_expected.to have_many(:job_variables) }
+ it { is_expected.to have_many(:report_results) }
it { is_expected.to have_one(:deployment) }
it { is_expected.to have_one(:runner_session) }
@@ -626,7 +627,7 @@ describe Ci::Build do
context 'is expired' do
before do
- build.update(artifacts_expire_at: Time.now - 7.days)
+ build.update(artifacts_expire_at: Time.current - 7.days)
end
it { is_expected.to be_truthy }
@@ -634,7 +635,7 @@ describe Ci::Build do
context 'is not expired' do
before do
- build.update(artifacts_expire_at: Time.now + 7.days)
+ build.update(artifacts_expire_at: Time.current + 7.days)
end
it { is_expected.to be_falsey }
@@ -661,13 +662,13 @@ describe Ci::Build do
it { is_expected.to be_nil }
context 'when artifacts_expire_at is specified' do
- let(:expire_at) { Time.now + 7.days }
+ let(:expire_at) { Time.current + 7.days }
before do
build.artifacts_expire_at = expire_at
end
- it { is_expected.to be_within(5).of(expire_at - Time.now) }
+ it { is_expected.to be_within(5).of(expire_at - Time.current) }
end
end
@@ -874,6 +875,22 @@ describe Ci::Build do
end
end
+ describe '#has_test_reports?' do
+ subject { build.has_test_reports? }
+
+ context 'when build has a test report' do
+ let(:build) { create(:ci_build, :test_reports) }
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'when build does not have a test report' do
+ let(:build) { create(:ci_build) }
+
+ it { is_expected.to be_falsey }
+ end
+ end
+
describe '#has_old_trace?' do
subject { build.has_old_trace? }
@@ -1795,7 +1812,7 @@ describe Ci::Build do
end
describe '#keep_artifacts!' do
- let(:build) { create(:ci_build, artifacts_expire_at: Time.now + 7.days) }
+ let(:build) { create(:ci_build, artifacts_expire_at: Time.current + 7.days) }
subject { build.keep_artifacts! }
@@ -2285,7 +2302,7 @@ describe Ci::Build do
let(:predefined_variables) do
[
{ key: 'CI_PIPELINE_ID', value: pipeline.id.to_s, public: true, masked: false },
- { key: 'CI_PIPELINE_URL', value: project.web_url + "/pipelines/#{pipeline.id}", public: true, masked: false },
+ { key: 'CI_PIPELINE_URL', value: project.web_url + "/-/pipelines/#{pipeline.id}", public: true, masked: false },
{ key: 'CI_JOB_ID', value: build.id.to_s, public: true, masked: false },
{ key: 'CI_JOB_URL', value: project.web_url + "/-/jobs/#{build.id}", public: true, masked: false },
{ key: 'CI_JOB_TOKEN', value: 'my-token', public: false, masked: true },
@@ -2390,13 +2407,13 @@ describe Ci::Build do
allow(build).to receive(:job_jwt_variables) { [job_jwt_var] }
allow(build).to receive(:dependency_variables) { [job_dependency_var] }
- allow_any_instance_of(Project)
+ allow(build.project)
.to receive(:predefined_variables) { [project_pre_var] }
project.variables.create!(key: 'secret', value: 'value')
- allow_any_instance_of(Ci::Pipeline)
- .to receive(:predefined_variables) { [pipeline_pre_var] }
+ allow(build.pipeline)
+ .to receive(:predefined_variables).and_return([pipeline_pre_var])
end
it 'returns variables in order depending on resource hierarchy' do
@@ -2512,6 +2529,17 @@ describe Ci::Build do
end
end
end
+
+ context 'with the :modified_path_ci_variables feature flag disabled' do
+ before do
+ stub_feature_flags(modified_path_ci_variables: false)
+ end
+
+ it 'does not set CI_MERGE_REQUEST_CHANGED_PAGES_* variables' do
+ expect(subject.find { |var| var[:key] == 'CI_MERGE_REQUEST_CHANGED_PAGE_PATHS' }).to be_nil
+ expect(subject.find { |var| var[:key] == 'CI_MERGE_REQUEST_CHANGED_PAGE_URLS' }).to be_nil
+ end
+ end
end
context 'when build has user' do
@@ -3095,24 +3123,8 @@ describe Ci::Build do
let!(:job_variable) { create(:ci_job_variable, :dotenv_source, job: prepare) }
- context 'FF ci_dependency_variables is enabled' do
- before do
- stub_feature_flags(ci_dependency_variables: true)
- end
-
- it 'inherits dependent variables' do
- expect(build.scoped_variables.to_hash).to include(job_variable.key => job_variable.value)
- end
- end
-
- context 'FF ci_dependency_variables is disabled' do
- before do
- stub_feature_flags(ci_dependency_variables: false)
- end
-
- it 'does not inherit dependent variables' do
- expect(build.scoped_variables.to_hash).not_to include(job_variable.key => job_variable.value)
- end
+ it 'inherits dependent variables' do
+ expect(build.scoped_variables.to_hash).to include(job_variable.key => job_variable.value)
end
end
end
@@ -3601,7 +3613,7 @@ describe Ci::Build do
.to receive(:execute)
.with(subject)
.and_raise(Gitlab::Access::AccessDeniedError)
- allow(Rails.logger).to receive(:error)
+ allow(Gitlab::AppLogger).to receive(:error)
end
it 'handles raised exception' do
@@ -3611,7 +3623,7 @@ describe Ci::Build do
it 'logs the error' do
subject.drop!
- expect(Rails.logger)
+ expect(Gitlab::AppLogger)
.to have_received(:error)
.with(a_string_matching("Unable to auto-retry job #{subject.id}"))
end
@@ -4040,10 +4052,11 @@ describe Ci::Build do
expect(terraform_reports.plans).to match(
a_hash_including(
- 'tfplan.json' => a_hash_including(
+ build.id.to_s => a_hash_including(
'create' => 0,
'update' => 1,
- 'delete' => 0
+ 'delete' => 0,
+ 'job_name' => build.options.dig(:artifacts, :name).to_s
)
)
)
@@ -4203,7 +4216,7 @@ describe Ci::Build do
subject { build.supported_runner?(runner_features) }
- context 'when feature is required by build' do
+ context 'when `upload_multiple_artifacts` feature is required by build' do
before do
expect(build).to receive(:runner_required_feature_names) do
[:upload_multiple_artifacts]
@@ -4227,7 +4240,7 @@ describe Ci::Build do
end
end
- context 'when refspecs feature is required by build' do
+ context 'when `refspecs` feature is required by build' do
before do
allow(build).to receive(:merge_request_ref?) { true }
end
@@ -4244,6 +4257,26 @@ describe Ci::Build do
it { is_expected.to be_falsey }
end
end
+
+ context 'when `release_steps` feature is required by build' do
+ before do
+ expect(build).to receive(:runner_required_feature_names) do
+ [:release_steps]
+ end
+ end
+
+ context 'when runner provides given feature' do
+ let(:runner_features) { { release_steps: true } }
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'when runner does not provide given feature' do
+ let(:runner_features) { {} }
+
+ it { is_expected.to be_falsey }
+ end
+ end
end
describe '#deployment_status' do
diff --git a/spec/models/ci/build_trace_chunk_spec.rb b/spec/models/ci/build_trace_chunk_spec.rb
index f08f05a09bf..85873847fca 100644
--- a/spec/models/ci/build_trace_chunk_spec.rb
+++ b/spec/models/ci/build_trace_chunk_spec.rb
@@ -33,7 +33,7 @@ describe Ci::BuildTraceChunk, :clean_gitlab_redis_shared_state do
expect(subjects.count).to be > 0
expect { subjects.first.destroy }.to raise_error('`destroy` and `destroy_all` are forbidden. Please use `fast_destroy_all`')
- expect { subjects.destroy_all }.to raise_error('`destroy` and `destroy_all` are forbidden. Please use `fast_destroy_all`') # rubocop: disable DestroyAll
+ expect { subjects.destroy_all }.to raise_error('`destroy` and `destroy_all` are forbidden. Please use `fast_destroy_all`') # rubocop: disable Cop/DestroyAll
expect(subjects.count).to be > 0
expect(external_data_counter).to be > 0
diff --git a/spec/models/ci/daily_build_group_report_result_spec.rb b/spec/models/ci/daily_build_group_report_result_spec.rb
index d4c305c649a..f2ce1b5775f 100644
--- a/spec/models/ci/daily_build_group_report_result_spec.rb
+++ b/spec/models/ci/daily_build_group_report_result_spec.rb
@@ -3,6 +3,30 @@
require 'spec_helper'
describe Ci::DailyBuildGroupReportResult do
+ let(:daily_build_group_report_result) { build(:ci_daily_build_group_report_result)}
+
+ describe 'associations' do
+ it { is_expected.to belong_to(:last_pipeline) }
+ it { is_expected.to belong_to(:project) }
+ end
+
+ describe 'validations' do
+ context 'when attributes are valid' do
+ it 'returns no errors' do
+ expect(daily_build_group_report_result).to be_valid
+ end
+ end
+
+ context 'when data is invalid' do
+ it 'returns errors' do
+ daily_build_group_report_result.data = { invalid: 'data' }
+
+ expect(daily_build_group_report_result).to be_invalid
+ expect(daily_build_group_report_result.errors.full_messages).to eq(["Data must be a valid json schema"])
+ end
+ end
+ end
+
describe '.upsert_reports' do
let!(:rspec_coverage) do
create(
diff --git a/spec/models/ci/instance_variable_spec.rb b/spec/models/ci/instance_variable_spec.rb
index ff8676e1424..4d69b7ac2f8 100644
--- a/spec/models/ci/instance_variable_spec.rb
+++ b/spec/models/ci/instance_variable_spec.rb
@@ -9,6 +9,26 @@ describe Ci::InstanceVariable do
it { is_expected.to include_module(Ci::Maskable) }
it { is_expected.to validate_uniqueness_of(:key).with_message(/\(\w+\) has already been taken/) }
+ it { is_expected.to validate_length_of(:encrypted_value).is_at_most(1024).with_message(/Variables over 700 characters risk exceeding the limit/) }
+
+ it_behaves_like 'includes Limitable concern' do
+ subject { build(:ci_instance_variable) }
+ end
+
+ context 'with instance level variable feature flag disabled' do
+ let(:plan_limits) { create(:plan_limits, :default_plan) }
+
+ before do
+ stub_feature_flags(ci_instance_level_variables_limit: false)
+ plan_limits.update(described_class.limit_name => 1)
+ create(:ci_instance_variable)
+ end
+
+ it 'can create new models exceeding the plan limits', :aggregate_failures do
+ expect { subject.save }.to change { described_class.count }
+ expect(subject.errors[:base]).to be_empty
+ end
+ end
describe '.unprotected' do
subject { described_class.unprotected }
@@ -39,7 +59,7 @@ describe Ci::InstanceVariable do
it { expect(described_class.all_cached).to contain_exactly(protected_variable, unprotected_variable) }
it 'memoizes the result' do
- expect(described_class).to receive(:store_cache).with(:ci_instance_variable_data).once.and_call_original
+ expect(described_class).to receive(:unscoped).once.and_call_original
2.times do
expect(described_class.all_cached).to contain_exactly(protected_variable, unprotected_variable)
@@ -65,15 +85,6 @@ describe Ci::InstanceVariable do
expect(described_class.all_cached).to contain_exactly(protected_variable, unprotected_variable, variable)
end
-
- it 'resets the cache when the shared key is missing' do
- expect(Rails.cache).to receive(:read).with(:ci_instance_variable_changed_at).twice.and_return(nil)
- expect(described_class).to receive(:store_cache).with(:ci_instance_variable_data).thrice.and_call_original
-
- 3.times do
- expect(described_class.all_cached).to contain_exactly(protected_variable, unprotected_variable)
- end
- end
end
describe '.unprotected_cached', :use_clean_rails_memory_store_caching do
@@ -83,7 +94,7 @@ describe Ci::InstanceVariable do
it { expect(described_class.unprotected_cached).to contain_exactly(unprotected_variable) }
it 'memoizes the result' do
- expect(described_class).to receive(:store_cache).with(:ci_instance_variable_data).once.and_call_original
+ expect(described_class).to receive(:unscoped).once.and_call_original
2.times do
expect(described_class.unprotected_cached).to contain_exactly(unprotected_variable)
diff --git a/spec/models/ci/job_artifact_spec.rb b/spec/models/ci/job_artifact_spec.rb
index 4cdc74d7a41..17e00533ac3 100644
--- a/spec/models/ci/job_artifact_spec.rb
+++ b/spec/models/ci/job_artifact_spec.rb
@@ -23,6 +23,14 @@ describe Ci::JobArtifact do
subject { build(:ci_job_artifact, :archive, size: 107464) }
end
+ describe '.not_expired' do
+ it 'returns artifacts that have not expired' do
+ _expired_artifact = create(:ci_job_artifact, :expired)
+
+ expect(described_class.not_expired).to contain_exactly(artifact)
+ end
+ end
+
describe '.with_reports' do
let!(:artifact) { create(:ci_job_artifact, :archive) }
@@ -118,6 +126,17 @@ describe Ci::JobArtifact do
end
end
+ describe '.downloadable' do
+ subject { described_class.downloadable }
+
+ it 'filters for downloadable artifacts' do
+ downloadable_artifact = create(:ci_job_artifact, :codequality)
+ _not_downloadable_artifact = create(:ci_job_artifact, :trace)
+
+ expect(subject).to contain_exactly(downloadable_artifact)
+ end
+ end
+
describe '.archived_trace_exists_for?' do
subject { described_class.archived_trace_exists_for?(job_id) }
@@ -357,19 +376,75 @@ describe Ci::JobArtifact do
end
end
+ describe 'expired?' do
+ subject { artifact.expired? }
+
+ context 'when expire_at is nil' do
+ let(:artifact) { build(:ci_job_artifact, expire_at: nil) }
+
+ it 'returns false' do
+ is_expected.to be_falsy
+ end
+ end
+
+ context 'when expire_at is in the past' do
+ let(:artifact) { build(:ci_job_artifact, expire_at: Date.yesterday) }
+
+ it 'returns true' do
+ is_expected.to be_truthy
+ end
+ end
+
+ context 'when expire_at is in the future' do
+ let(:artifact) { build(:ci_job_artifact, expire_at: Date.tomorrow) }
+
+ it 'returns false' do
+ is_expected.to be_falsey
+ end
+ end
+ end
+
+ describe '#expiring?' do
+ subject { artifact.expiring? }
+
+ context 'when expire_at is nil' do
+ let(:artifact) { build(:ci_job_artifact, expire_at: nil) }
+
+ it 'returns false' do
+ is_expected.to be_falsy
+ end
+ end
+
+ context 'when expire_at is in the past' do
+ let(:artifact) { build(:ci_job_artifact, expire_at: Date.yesterday) }
+
+ it 'returns false' do
+ is_expected.to be_falsy
+ end
+ end
+
+ context 'when expire_at is in the future' do
+ let(:artifact) { build(:ci_job_artifact, expire_at: Date.tomorrow) }
+
+ it 'returns true' do
+ is_expected.to be_truthy
+ end
+ end
+ end
+
describe '#expire_in' do
subject { artifact.expire_in }
it { is_expected.to be_nil }
context 'when expire_at is specified' do
- let(:expire_at) { Time.now + 7.days }
+ let(:expire_at) { Time.current + 7.days }
before do
artifact.expire_at = expire_at
end
- it { is_expected.to be_within(5).of(expire_at - Time.now) }
+ it { is_expected.to be_within(5).of(expire_at - Time.current) }
end
end
diff --git a/spec/models/ci/pipeline_schedule_spec.rb b/spec/models/ci/pipeline_schedule_spec.rb
index 9a10c7629b2..4ba70552f01 100644
--- a/spec/models/ci/pipeline_schedule_spec.rb
+++ b/spec/models/ci/pipeline_schedule_spec.rb
@@ -118,7 +118,7 @@ describe Ci::PipelineSchedule do
let(:pipeline_schedule) { create(:ci_pipeline_schedule, :every_minute) }
it "updates next_run_at to the sidekiq worker's execution time" do
- Timecop.freeze(Time.parse("2019-06-01 12:18:00+0000")) do
+ Timecop.freeze(Time.zone.parse("2019-06-01 12:18:00+0000")) do
expect(pipeline_schedule.next_run_at).to eq(cron_worker_next_run_at)
end
end
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 4f53b6b4418..782a4206c36 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -26,6 +26,8 @@ describe Ci::Pipeline, :mailer do
it { is_expected.to have_many(:trigger_requests) }
it { is_expected.to have_many(:variables) }
it { is_expected.to have_many(:builds) }
+ it { is_expected.to have_many(:bridges) }
+ it { is_expected.to have_many(:job_artifacts).through(:builds) }
it { is_expected.to have_many(:auto_canceled_pipelines) }
it { is_expected.to have_many(:auto_canceled_jobs) }
it { is_expected.to have_many(:sourced_pipelines) }
@@ -51,6 +53,27 @@ describe Ci::Pipeline, :mailer do
expect(Project.reflect_on_association(:all_pipelines).has_inverse?).to eq(:project)
expect(Project.reflect_on_association(:ci_pipelines).has_inverse?).to eq(:project)
end
+
+ describe '#latest_builds' do
+ it 'has a one to many relationship with its latest builds' do
+ _old_build = create(:ci_build, :retried, pipeline: pipeline)
+ latest_build = create(:ci_build, :expired, pipeline: pipeline)
+
+ expect(pipeline.latest_builds).to contain_exactly(latest_build)
+ end
+ end
+
+ describe '#downloadable_artifacts' do
+ let(:build) { create(:ci_build, pipeline: pipeline) }
+
+ it 'returns downloadable artifacts that have not expired' do
+ downloadable_artifact = create(:ci_job_artifact, :codequality, job: build)
+ _expired_artifact = create(:ci_job_artifact, :junit, :expired, job: build)
+ _undownloadable_artifact = create(:ci_job_artifact, :trace, job: build)
+
+ expect(pipeline.downloadable_artifacts).to contain_exactly(downloadable_artifact)
+ end
+ end
end
describe '#set_status' do
@@ -99,6 +122,17 @@ describe Ci::Pipeline, :mailer do
end
end
+ describe '.for_iid' do
+ subject { described_class.for_iid(iid) }
+
+ let(:iid) { '1234' }
+ let!(:pipeline) { create(:ci_pipeline, iid: '1234') }
+
+ it 'returns the pipeline' do
+ is_expected.to contain_exactly(pipeline)
+ end
+ end
+
describe '.for_sha' do
subject { described_class.for_sha(sha) }
@@ -1007,19 +1041,6 @@ describe Ci::Pipeline, :mailer do
subject { pipeline.ordered_stages }
- context 'when using legacy stages' do
- before do
- stub_feature_flags(
- ci_pipeline_persisted_stages: false,
- ci_atomic_processing: false
- )
- end
-
- it 'returns legacy stages in valid order' do
- expect(subject.map(&:name)).to eq %w[build test]
- end
- end
-
context 'when using atomic processing' do
before do
stub_feature_flags(
@@ -1051,7 +1072,6 @@ describe Ci::Pipeline, :mailer do
context 'when using persisted stages' do
before do
stub_feature_flags(
- ci_pipeline_persisted_stages: true,
ci_atomic_processing: false
)
end
@@ -1079,7 +1099,7 @@ describe Ci::Pipeline, :mailer do
end
describe 'state machine' do
- let(:current) { Time.now.change(usec: 0) }
+ let(:current) { Time.current.change(usec: 0) }
let(:build) { create_build('build1', queued_at: 0) }
let(:build_b) { create_build('build2', queued_at: 0) }
let(:build_c) { create_build('build3', queued_at: 0) }
@@ -2633,38 +2653,34 @@ describe Ci::Pipeline, :mailer do
end
end
- shared_examples 'enqueues the notification worker' do
- it 'enqueues PipelineUpdateCiRefStatusWorker' do
- expect(PipelineUpdateCiRefStatusWorker).to receive(:perform_async).with(pipeline.id)
- expect(PipelineNotificationWorker).not_to receive(:perform_async).with(pipeline.id)
+ context 'with success pipeline' do
+ it_behaves_like 'sending a notification' do
+ before do
+ perform_enqueued_jobs do
+ pipeline.succeed
+ end
+ end
+ end
+
+ it 'enqueues PipelineNotificationWorker' do
+ expect(PipelineNotificationWorker)
+ .to receive(:perform_async).with(pipeline.id, ref_status: :success)
pipeline.succeed
end
- context 'when ci_pipeline_fixed_notifications is disabled' do
+ context 'when pipeline is not the latest' do
before do
- stub_feature_flags(ci_pipeline_fixed_notifications: false)
+ create(:ci_pipeline, :success, project: project, ci_ref: pipeline.ci_ref)
end
- it 'enqueues PipelineNotificationWorker' do
- expect(PipelineUpdateCiRefStatusWorker).not_to receive(:perform_async).with(pipeline.id)
- expect(PipelineNotificationWorker).to receive(:perform_async).with(pipeline.id)
+ it 'does not pass ref_status' do
+ expect(PipelineNotificationWorker)
+ .to receive(:perform_async).with(pipeline.id, ref_status: nil)
- pipeline.succeed
- end
- end
- end
-
- context 'with success pipeline' do
- it_behaves_like 'sending a notification' do
- before do
- perform_enqueued_jobs do
- pipeline.succeed
- end
+ pipeline.succeed!
end
end
-
- it_behaves_like 'enqueues the notification worker'
end
context 'with failed pipeline' do
@@ -2679,7 +2695,12 @@ describe Ci::Pipeline, :mailer do
end
end
- it_behaves_like 'enqueues the notification worker'
+ it 'enqueues PipelineNotificationWorker' do
+ expect(PipelineNotificationWorker)
+ .to receive(:perform_async).with(pipeline.id, ref_status: :failed)
+
+ pipeline.drop
+ end
end
context 'with skipped pipeline' do
@@ -2703,6 +2724,69 @@ describe Ci::Pipeline, :mailer do
end
end
+ describe 'updates ci_ref when pipeline finished' do
+ context 'when ci_ref exists' do
+ let!(:pipeline) { create(:ci_pipeline, :running) }
+
+ it 'updates the ci_ref' do
+ expect(pipeline.ci_ref)
+ .to receive(:update_status_by!).with(pipeline).and_call_original
+
+ pipeline.succeed!
+ end
+ end
+
+ context 'when ci_ref does not exist' do
+ let!(:pipeline) { create(:ci_pipeline, :running, ci_ref_presence: false) }
+
+ it 'does not raise an exception' do
+ expect { pipeline.succeed! }.not_to raise_error
+ end
+ end
+ end
+
+ describe '#ensure_ci_ref!' do
+ subject { pipeline.ensure_ci_ref! }
+
+ shared_examples_for 'protected by feature flag' do
+ context 'when feature flag is disabled' do
+ before do
+ stub_feature_flags(ci_pipeline_fixed_notifications: false)
+ end
+
+ it 'does not do anything' do
+ expect(Ci::Ref).not_to receive(:ensure_for)
+
+ subject
+ end
+ end
+ end
+
+ context 'when ci_ref does not exist yet' do
+ let!(:pipeline) { create(:ci_pipeline, ci_ref_presence: false) }
+
+ it_behaves_like 'protected by feature flag'
+
+ it 'creates a new ci_ref and assigns it' do
+ expect { subject }.to change { Ci::Ref.count }.by(1)
+
+ expect(pipeline.ci_ref).to be_present
+ end
+ end
+
+ context 'when ci_ref already exists' do
+ let!(:pipeline) { create(:ci_pipeline) }
+
+ it_behaves_like 'protected by feature flag'
+
+ it 'fetches a new ci_ref and assigns it' do
+ expect { subject }.not_to change { Ci::Ref.count }
+
+ expect(pipeline.ci_ref).to be_present
+ end
+ end
+ end
+
describe '#find_job_with_archive_artifacts' do
let!(:old_job) { create(:ci_build, name: 'rspec', retried: true, pipeline: pipeline) }
let!(:job_without_artifacts) { create(:ci_build, name: 'rspec', pipeline: pipeline) }
@@ -2741,6 +2825,30 @@ describe Ci::Pipeline, :mailer do
end
end
+ describe '#latest_report_builds' do
+ it 'returns build with test artifacts' do
+ test_build = create(:ci_build, :test_reports, pipeline: pipeline, project: project)
+ coverage_build = create(:ci_build, :coverage_reports, pipeline: pipeline, project: project)
+ create(:ci_build, :artifacts, pipeline: pipeline, project: project)
+
+ expect(pipeline.latest_report_builds).to contain_exactly(test_build, coverage_build)
+ end
+
+ it 'filters builds by scope' do
+ test_build = create(:ci_build, :test_reports, pipeline: pipeline, project: project)
+ create(:ci_build, :coverage_reports, pipeline: pipeline, project: project)
+
+ expect(pipeline.latest_report_builds(Ci::JobArtifact.test_reports)).to contain_exactly(test_build)
+ end
+
+ it 'only returns not retried builds' do
+ test_build = create(:ci_build, :test_reports, pipeline: pipeline, project: project)
+ create(:ci_build, :test_reports, :retried, pipeline: pipeline, project: project)
+
+ expect(pipeline.latest_report_builds).to contain_exactly(test_build)
+ end
+ end
+
describe '#has_reports?' do
subject { pipeline.has_reports?(Ci::JobArtifact.test_reports) }
diff --git a/spec/models/ci/ref_spec.rb b/spec/models/ci/ref_spec.rb
index aa3b8cdbc3e..3d75cb63141 100644
--- a/spec/models/ci/ref_spec.rb
+++ b/spec/models/ci/ref_spec.rb
@@ -4,8 +4,155 @@ require 'spec_helper'
describe Ci::Ref do
it { is_expected.to belong_to(:project) }
- it { is_expected.to belong_to(:last_updated_by_pipeline) }
- it { is_expected.to validate_inclusion_of(:status).in_array(%w[success failed fixed]) }
- it { is_expected.to validate_presence_of(:last_updated_by_pipeline) }
+ describe '.ensure_for' do
+ let_it_be(:project) { create(:project, :repository) }
+
+ subject { described_class.ensure_for(pipeline) }
+
+ shared_examples_for 'ensures ci_ref' do
+ context 'when ci_ref already exists' do
+ let(:options) { {} }
+
+ it 'returns an existing ci_ref' do
+ expect { subject }.not_to change { described_class.count }
+
+ expect(subject).to eq(Ci::Ref.find_by(project_id: project.id, ref_path: expected_ref_path))
+ end
+ end
+
+ context 'when ci_ref does not exist yet' do
+ let(:options) { { ci_ref_presence: false } }
+
+ it 'creates a new ci_ref' do
+ expect { subject }.to change { described_class.count }.by(1)
+
+ expect(subject).to eq(Ci::Ref.find_by(project_id: project.id, ref_path: expected_ref_path))
+ end
+ end
+ end
+
+ context 'when pipeline is a branch pipeline' do
+ let!(:pipeline) { create(:ci_pipeline, ref: 'master', project: project, **options) }
+ let(:expected_ref_path) { 'refs/heads/master' }
+
+ it_behaves_like 'ensures ci_ref'
+ end
+
+ context 'when pipeline is a tag pipeline' do
+ let!(:pipeline) { create(:ci_pipeline, ref: 'v1.1.0', tag: true, project: project, **options) }
+ let(:expected_ref_path) { 'refs/tags/v1.1.0' }
+
+ it_behaves_like 'ensures ci_ref'
+ end
+
+ context 'when pipeline is a detached merge request pipeline' do
+ let(:merge_request) do
+ create(:merge_request, target_project: project, target_branch: 'master',
+ source_project: project, source_branch: 'feature')
+ end
+
+ let!(:pipeline) do
+ create(:ci_pipeline, :detached_merge_request_pipeline, merge_request: merge_request, project: project, **options)
+ end
+
+ let(:expected_ref_path) { 'refs/heads/feature' }
+
+ it_behaves_like 'ensures ci_ref'
+ end
+ end
+
+ describe '#update_status_by!' do
+ subject { ci_ref.update_status_by!(pipeline) }
+
+ let!(:ci_ref) { create(:ci_ref) }
+
+ shared_examples_for 'no-op' do
+ it 'does nothing and returns nil' do
+ expect { subject }.not_to change { ci_ref.status_name }
+
+ is_expected.to be_nil
+ end
+ end
+
+ context 'when pipeline status is success or failed' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:pipeline_status, :current_ref_status, :expected_ref_status) do
+ :success | :unknown | :success
+ :success | :success | :success
+ :success | :failed | :fixed
+ :success | :fixed | :success
+ :success | :broken | :fixed
+ :success | :still_failing | :fixed
+ :failed | :unknown | :failed
+ :failed | :success | :broken
+ :failed | :failed | :still_failing
+ :failed | :fixed | :broken
+ :failed | :broken | :still_failing
+ :failed | :still_failing | :still_failing
+ end
+
+ with_them do
+ let(:ci_ref) { create(:ci_ref, status: described_class.state_machines[:status].states[current_ref_status].value) }
+ let(:pipeline) { create(:ci_pipeline, status: pipeline_status, ci_ref: ci_ref) }
+
+ it 'transitions the status via state machine' do
+ expect(subject).to eq(expected_ref_status)
+ expect(ci_ref.status_name).to eq(expected_ref_status)
+ end
+ end
+ end
+
+ context 'when pipeline status is success' do
+ let(:pipeline) { create(:ci_pipeline, :success, ci_ref: ci_ref) }
+
+ it 'updates the status' do
+ expect { subject }.to change { ci_ref.status_name }.from(:unknown).to(:success)
+
+ is_expected.to eq(:success)
+ end
+ end
+
+ context 'when pipeline status is canceled' do
+ let(:pipeline) { create(:ci_pipeline, status: :canceled, ci_ref: ci_ref) }
+
+ it { is_expected.to eq(:unknown) }
+ end
+
+ context 'when pipeline status is skipped' do
+ let(:pipeline) { create(:ci_pipeline, status: :skipped, ci_ref: ci_ref) }
+
+ it_behaves_like 'no-op'
+ end
+
+ context 'when pipeline status is not complete' do
+ let(:pipeline) { create(:ci_pipeline, :running, ci_ref: ci_ref) }
+
+ it_behaves_like 'no-op'
+ end
+
+ context 'when feature flag is disabled' do
+ let(:pipeline) { create(:ci_pipeline, :success, ci_ref: ci_ref) }
+
+ before do
+ stub_feature_flags(ci_pipeline_fixed_notifications: false)
+ end
+
+ it_behaves_like 'no-op'
+ end
+
+ context 'when pipeline is not the latest pipeline' do
+ let!(:pipeline) { create(:ci_pipeline, :success, ci_ref: ci_ref) }
+ let!(:latest_pipeline) { create(:ci_pipeline, :success, ci_ref: ci_ref) }
+
+ it_behaves_like 'no-op'
+ end
+
+ context 'when pipeline does not belong to the ci_ref' do
+ let(:pipeline) { create(:ci_pipeline, :success, ci_ref: create(:ci_ref)) }
+
+ it_behaves_like 'no-op'
+ end
+ end
end
diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb
index 8b6a4fa6ade..296240b1602 100644
--- a/spec/models/ci/runner_spec.rb
+++ b/spec/models/ci/runner_spec.rb
@@ -263,7 +263,7 @@ describe Ci::Runner do
subject { described_class.online }
before do
- @runner1 = create(:ci_runner, :instance, contacted_at: 1.hour.ago)
+ @runner1 = create(:ci_runner, :instance, contacted_at: 2.hours.ago)
@runner2 = create(:ci_runner, :instance, contacted_at: 1.second.ago)
end
@@ -344,7 +344,7 @@ describe Ci::Runner do
subject { described_class.offline }
before do
- @runner1 = create(:ci_runner, :instance, contacted_at: 1.hour.ago)
+ @runner1 = create(:ci_runner, :instance, contacted_at: 2.hours.ago)
@runner2 = create(:ci_runner, :instance, contacted_at: 1.second.ago)
end
@@ -598,14 +598,14 @@ describe Ci::Runner do
end
end
- describe '#update_cached_info' do
+ describe '#heartbeat' do
let(:runner) { create(:ci_runner, :project) }
- subject { runner.update_cached_info(architecture: '18-bit') }
+ subject { runner.heartbeat(architecture: '18-bit') }
context 'when database was updated recently' do
before do
- runner.contacted_at = Time.now
+ runner.contacted_at = Time.current
end
it 'updates cache' do
diff --git a/spec/models/clusters/applications/elastic_stack_spec.rb b/spec/models/clusters/applications/elastic_stack_spec.rb
index 02ada219e32..50042a4e29a 100644
--- a/spec/models/clusters/applications/elastic_stack_spec.rb
+++ b/spec/models/clusters/applications/elastic_stack_spec.rb
@@ -175,6 +175,7 @@ describe Clusters::Applications::ElasticStack do
expect(faraday_connection.headers["Authorization"]).to eq(kube_client.headers[:Authorization])
expect(faraday_connection.ssl.cert_store).to be_instance_of(OpenSSL::X509::Store)
expect(faraday_connection.ssl.verify).to eq(1)
+ expect(faraday_connection.options.timeout).to be_nil
end
context 'when cluster is not reachable' do
@@ -186,6 +187,15 @@ describe Clusters::Applications::ElasticStack do
expect(subject.elasticsearch_client).to be_nil
end
end
+
+ context 'when timeout is provided' do
+ it 'sets timeout in elasticsearch_client' do
+ client = subject.elasticsearch_client(timeout: 123)
+ faraday_connection = client.transport.connections.first.connection
+
+ expect(faraday_connection.options.timeout).to eq(123)
+ end
+ end
end
end
end
diff --git a/spec/models/clusters/applications/prometheus_spec.rb b/spec/models/clusters/applications/prometheus_spec.rb
index ce341e67c14..1ed9e207b6b 100644
--- a/spec/models/clusters/applications/prometheus_spec.rb
+++ b/spec/models/clusters/applications/prometheus_spec.rb
@@ -47,7 +47,7 @@ describe Clusters::Applications::Prometheus do
it 'sets last_update_started_at to now' do
Timecop.freeze do
- expect { subject.make_updating }.to change { subject.reload.last_update_started_at }.to be_within(1.second).of(Time.now)
+ expect { subject.make_updating }.to change { subject.reload.last_update_started_at }.to be_within(1.second).of(Time.current)
end
end
end
@@ -347,14 +347,14 @@ describe Clusters::Applications::Prometheus do
describe '#updated_since?' do
let(:cluster) { create(:cluster) }
let(:prometheus_app) { build(:clusters_applications_prometheus, cluster: cluster) }
- let(:timestamp) { Time.now - 5.minutes }
+ let(:timestamp) { Time.current - 5.minutes }
around do |example|
Timecop.freeze { example.run }
end
before do
- prometheus_app.last_update_started_at = Time.now
+ prometheus_app.last_update_started_at = Time.current
end
context 'when app does not have status failed' do
@@ -363,7 +363,7 @@ describe Clusters::Applications::Prometheus do
end
it 'returns false when last update started before the timestamp' do
- expect(prometheus_app.updated_since?(Time.now + 5.minutes)).to be false
+ expect(prometheus_app.updated_since?(Time.current + 5.minutes)).to be false
end
end
diff --git a/spec/models/clusters/cluster_spec.rb b/spec/models/clusters/cluster_spec.rb
index 521ed98f637..4dd74976028 100644
--- a/spec/models/clusters/cluster_spec.rb
+++ b/spec/models/clusters/cluster_spec.rb
@@ -28,6 +28,8 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
it { is_expected.to have_one(:cluster_project) }
it { is_expected.to have_many(:deployment_clusters) }
it { is_expected.to have_many(:metrics_dashboard_annotations) }
+ it { is_expected.to have_many(:successful_deployments) }
+ it { is_expected.to have_many(:environments).through(:deployments) }
it { is_expected.to delegate_method(:status).to(:provider) }
it { is_expected.to delegate_method(:status_reason).to(:provider) }
@@ -172,6 +174,108 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
end
end
+ describe '.with_application_prometheus' do
+ subject { described_class.with_application_prometheus }
+
+ let!(:cluster) { create(:cluster) }
+
+ context 'cluster has prometheus application' do
+ let!(:application) { create(:clusters_applications_prometheus, :installed, cluster: cluster) }
+
+ it { is_expected.to include(cluster) }
+ end
+
+ context 'cluster does not have prometheus application' do
+ let(:cluster) { create(:cluster) }
+
+ it { is_expected.not_to include(cluster) }
+ end
+ end
+
+ describe '.with_enabled_modsecurity' do
+ subject { described_class.with_enabled_modsecurity }
+
+ let_it_be(:cluster) { create(:cluster) }
+
+ context 'cluster has ingress application with enabled modsecurity' do
+ let!(:application) { create(:clusters_applications_ingress, :installed, :modsecurity_logging, cluster: cluster) }
+
+ it { is_expected.to include(cluster) }
+ end
+
+ context 'cluster has ingress application with disabled modsecurity' do
+ let!(:application) { create(:clusters_applications_ingress, :installed, :modsecurity_disabled, cluster: cluster) }
+
+ it { is_expected.not_to include(cluster) }
+ end
+
+ context 'cluster does not have ingress application' do
+ it { is_expected.not_to include(cluster) }
+ end
+ end
+
+ describe '.with_available_elasticstack' do
+ subject { described_class.with_available_elasticstack }
+
+ let_it_be(:cluster) { create(:cluster) }
+
+ context 'cluster has ElasticStack application' do
+ let!(:application) { create(:clusters_applications_elastic_stack, :installed, cluster: cluster) }
+
+ it { is_expected.to include(cluster) }
+ end
+
+ context 'cluster does not have ElasticStack application' do
+ it { is_expected.not_to include(cluster) }
+ end
+ end
+
+ describe '.distinct_with_deployed_environments' do
+ subject { described_class.distinct_with_deployed_environments }
+
+ let_it_be(:cluster) { create(:cluster) }
+
+ context 'cluster has multiple successful deployment with environment' do
+ let!(:environment) { create(:environment) }
+ let!(:deployment) { create(:deployment, :success, cluster: cluster, environment: environment) }
+ let!(:deployment_2) { create(:deployment, :success, cluster: cluster, environment: environment) }
+
+ it { is_expected.to include(cluster) }
+
+ it 'lists only distinct environments' do
+ expect(subject.first.environments.count).to eq(1)
+ end
+ end
+
+ context 'cluster has only failed deployment with environment' do
+ let!(:environment) { create(:environment) }
+ let!(:deployment) { create(:deployment, :failed, cluster: cluster, environment: environment) }
+
+ it { is_expected.not_to include(cluster) }
+ end
+
+ context 'cluster does not have any deployment' do
+ it { is_expected.not_to include(cluster) }
+ end
+ end
+
+ describe '.with_project_alert_service_data' do
+ subject { described_class.with_project_alert_service_data(project_id) }
+
+ let!(:cluster) { create(:cluster, :project) }
+ let!(:project_id) { cluster.first_project.id }
+
+ context 'project has alert service data' do
+ let!(:alerts_service) { create(:alerts_service, project: cluster.clusterable) }
+
+ it { is_expected.to include(cluster) }
+ end
+
+ context 'project has no alert service data' do
+ it { is_expected.not_to include(cluster) }
+ end
+ end
+
describe '.for_project_namespace' do
subject { described_class.for_project_namespace(namespace_id) }
@@ -573,19 +677,12 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
end
context 'when applications are created' do
- let!(:helm) { create(:clusters_applications_helm, cluster: cluster) }
- let!(:ingress) { create(:clusters_applications_ingress, cluster: cluster) }
- let!(:cert_manager) { create(:clusters_applications_cert_manager, cluster: cluster) }
- let!(:crossplane) { create(:clusters_applications_crossplane, cluster: cluster) }
- let!(:prometheus) { create(:clusters_applications_prometheus, cluster: cluster) }
- let!(:runner) { create(:clusters_applications_runner, cluster: cluster) }
- let!(:jupyter) { create(:clusters_applications_jupyter, cluster: cluster) }
- let!(:knative) { create(:clusters_applications_knative, cluster: cluster) }
- let!(:elastic_stack) { create(:clusters_applications_elastic_stack, cluster: cluster) }
- let!(:fluentd) { create(:clusters_applications_fluentd, cluster: cluster) }
+ let(:cluster) { create(:cluster, :with_all_applications) }
- it 'returns a list of created applications' do
- is_expected.to contain_exactly(helm, ingress, cert_manager, crossplane, prometheus, runner, jupyter, knative, elastic_stack, fluentd)
+ it 'returns a list of created applications', :aggregate_failures do
+ is_expected.to have_attributes(size: described_class::APPLICATIONS.size)
+ is_expected.to all(be_kind_of(::Clusters::Concerns::ApplicationCore))
+ is_expected.to all(be_persisted)
end
end
end
@@ -611,33 +708,13 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
end
context 'when application is persisted' do
- let!(:helm) { create(:clusters_applications_helm, cluster: cluster) }
- let!(:ingress) { create(:clusters_applications_ingress, cluster: cluster) }
- let!(:cert_manager) { create(:clusters_applications_cert_manager, cluster: cluster) }
- let!(:crossplane) { create(:clusters_applications_crossplane, cluster: cluster) }
- let!(:prometheus) { create(:clusters_applications_prometheus, cluster: cluster) }
- let!(:runner) { create(:clusters_applications_runner, cluster: cluster) }
- let!(:jupyter) { create(:clusters_applications_jupyter, cluster: cluster) }
- let!(:knative) { create(:clusters_applications_knative, cluster: cluster) }
- let!(:elastic_stack) { create(:clusters_applications_elastic_stack, cluster: cluster) }
- let!(:fluentd) { create(:clusters_applications_fluentd, cluster: cluster) }
+ let(:cluster) { create(:cluster, :with_all_applications) }
it 'returns the persisted application', :aggregate_failures do
- {
- Clusters::Applications::Helm => helm,
- Clusters::Applications::Ingress => ingress,
- Clusters::Applications::CertManager => cert_manager,
- Clusters::Applications::Crossplane => crossplane,
- Clusters::Applications::Prometheus => prometheus,
- Clusters::Applications::Runner => runner,
- Clusters::Applications::Jupyter => jupyter,
- Clusters::Applications::Knative => knative,
- Clusters::Applications::ElasticStack => elastic_stack,
- Clusters::Applications::Fluentd => fluentd
- }.each do |application_class, expected_object|
+ described_class::APPLICATIONS.each_value do |application_class|
application = cluster.find_or_build_application(application_class)
- expect(application).to eq(expected_object)
+ expect(application).to be_kind_of(::Clusters::Concerns::ApplicationCore)
expect(application).to be_persisted
end
end
@@ -1049,7 +1126,7 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
.and_raise(SocketError)
end
- it { is_expected.to eq(connection_status: :unreachable, nodes: []) }
+ it { is_expected.to eq(connection_status: :unreachable, nodes: nil) }
end
context 'cluster cannot be authenticated to' do
@@ -1058,7 +1135,7 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
.and_raise(OpenSSL::X509::CertificateError.new("Certificate error"))
end
- it { is_expected.to eq(connection_status: :authentication_failure, nodes: []) }
+ it { is_expected.to eq(connection_status: :authentication_failure, nodes: nil) }
end
describe 'Kubeclient::HttpError' do
@@ -1070,18 +1147,18 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
.and_raise(Kubeclient::HttpError.new(error_code, error_message, nil))
end
- it { is_expected.to eq(connection_status: :authentication_failure, nodes: []) }
+ it { is_expected.to eq(connection_status: :authentication_failure, nodes: nil) }
context 'generic timeout' do
let(:error_message) { 'Timed out connecting to server'}
- it { is_expected.to eq(connection_status: :unreachable, nodes: []) }
+ it { is_expected.to eq(connection_status: :unreachable, nodes: nil) }
end
context 'gateway timeout' do
let(:error_message) { '504 Gateway Timeout for GET https://kubernetes.example.com/api/v1'}
- it { is_expected.to eq(connection_status: :unreachable, nodes: []) }
+ it { is_expected.to eq(connection_status: :unreachable, nodes: nil) }
end
end
@@ -1091,7 +1168,7 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
.and_raise(StandardError)
end
- it { is_expected.to eq(connection_status: :unknown_failure, nodes: []) }
+ it { is_expected.to eq(connection_status: :unknown_failure, nodes: nil) }
it 'notifies Sentry' do
expect(Gitlab::ErrorTracking).to receive(:track_exception)
diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb
index 05d3329215a..85fc503a1ca 100644
--- a/spec/models/commit_status_spec.rb
+++ b/spec/models/commit_status_spec.rb
@@ -96,6 +96,21 @@ describe CommitStatus do
it { is_expected.to be_truthy }
end
+
+ it "processed state is always persisted" do
+ commit_status.update!(retried: false, status: :pending)
+
+ # another process does mark object as processed
+ CommitStatus.find(commit_status.id).update_column(:processed, true)
+
+ # subsequent status transitions on the same instance
+ # always saves processed=false to DB even though
+ # the current value did not change
+ commit_status.update!(retried: false, status: :running)
+
+ # we look at a persisted state in DB
+ expect(CommitStatus.find(commit_status.id).processed).to eq(false)
+ end
end
end
@@ -235,7 +250,7 @@ describe CommitStatus do
context 'if the building process has started' do
before do
- commit_status.started_at = Time.now - 1.minute
+ commit_status.started_at = Time.current - 1.minute
commit_status.finished_at = nil
end
@@ -708,7 +723,7 @@ describe CommitStatus do
end
describe '#enqueue' do
- let!(:current_time) { Time.new(2018, 4, 5, 14, 0, 0) }
+ let!(:current_time) { Time.zone.local(2018, 4, 5, 14, 0, 0) }
before do
allow(Time).to receive(:now).and_return(current_time)
diff --git a/spec/models/concerns/bulk_insert_safe_spec.rb b/spec/models/concerns/bulk_insert_safe_spec.rb
index 5d65d614ac5..07d6cee487f 100644
--- a/spec/models/concerns/bulk_insert_safe_spec.rb
+++ b/spec/models/concerns/bulk_insert_safe_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe BulkInsertSafe do
- class BulkInsertItem < ApplicationRecord
+ class BulkInsertItem < ActiveRecord::Base
include BulkInsertSafe
include ShaAttribute
@@ -74,6 +74,8 @@ describe BulkInsertSafe do
ActiveRecord::Schema.define do
drop_table :bulk_insert_items, force: true
end
+
+ BulkInsertItem.reset_column_information
end
describe BulkInsertItem do
diff --git a/spec/models/concerns/cacheable_attributes_spec.rb b/spec/models/concerns/cacheable_attributes_spec.rb
index 56e0d044247..6694b2aba22 100644
--- a/spec/models/concerns/cacheable_attributes_spec.rb
+++ b/spec/models/concerns/cacheable_attributes_spec.rb
@@ -135,7 +135,7 @@ describe CacheableAttributes do
end
it 'returns an uncached record and logs a warning' do
- expect(Rails.logger).to receive(:warn).with("Cached record for TestClass couldn't be loaded, falling back to uncached record: Redis::BaseError")
+ expect(Gitlab::AppLogger).to receive(:warn).with("Cached record for TestClass couldn't be loaded, falling back to uncached record: Redis::BaseError")
expect(MinimalTestClass.current).to eq(:last)
end
@@ -147,7 +147,7 @@ describe CacheableAttributes do
end
it 'returns an uncached record and logs a warning' do
- expect(Rails.logger).not_to receive(:warn)
+ expect(Gitlab::AppLogger).not_to receive(:warn)
expect { MinimalTestClass.current }.to raise_error(Redis::BaseError)
end
diff --git a/spec/models/concerns/each_batch_spec.rb b/spec/models/concerns/each_batch_spec.rb
index 294fde4f8e6..ee3d9aea505 100644
--- a/spec/models/concerns/each_batch_spec.rb
+++ b/spec/models/concerns/each_batch_spec.rb
@@ -44,7 +44,7 @@ describe EachBatch do
end
it 'allows updating of the yielded relations' do
- time = Time.now
+ time = Time.current
model.each_batch do |relation|
relation.update_all(updated_at: time)
diff --git a/spec/models/concerns/featurable_spec.rb b/spec/models/concerns/featurable_spec.rb
new file mode 100644
index 00000000000..89720e3652c
--- /dev/null
+++ b/spec/models/concerns/featurable_spec.rb
@@ -0,0 +1,184 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Featurable do
+ let_it_be(:user) { create(:user) }
+ let(:project) { create(:project) }
+ let(:feature_class) { subject.class }
+ let(:features) { feature_class::FEATURES }
+
+ subject { project.project_feature }
+
+ describe '.quoted_access_level_column' do
+ it 'returns the table name and quoted column name for a feature' do
+ expected = '"project_features"."issues_access_level"'
+
+ expect(feature_class.quoted_access_level_column(:issues)).to eq(expected)
+ end
+ end
+
+ describe '.access_level_attribute' do
+ it { expect(feature_class.access_level_attribute(:wiki)).to eq :wiki_access_level }
+
+ it 'raises error for unspecified feature' do
+ expect { feature_class.access_level_attribute(:unknown) }
+ .to raise_error(ArgumentError, /invalid feature: unknown/)
+ end
+ end
+
+ describe '.set_available_features' do
+ let!(:klass) do
+ Class.new do
+ include Featurable
+ set_available_features %i(feature1 feature2)
+
+ def feature1_access_level
+ Featurable::DISABLED
+ end
+
+ def feature2_access_level
+ Featurable::ENABLED
+ end
+ end
+ end
+ let!(:instance) { klass.new }
+
+ it { expect(klass.available_features).to eq [:feature1, :feature2] }
+ it { expect(instance.feature1_enabled?).to be_falsey }
+ it { expect(instance.feature2_enabled?).to be_truthy }
+ end
+
+ describe '.available_features' do
+ it { expect(feature_class.available_features).to include(*features) }
+ end
+
+ describe '#access_level' do
+ it 'returns access level' do
+ expect(subject.access_level(:wiki)).to eq(subject.wiki_access_level)
+ end
+ end
+
+ describe '#feature_available?' do
+ let(:features) { %w(issues wiki builds merge_requests snippets repository pages metrics_dashboard) }
+
+ context 'when features are disabled' do
+ it "returns false" do
+ update_all_project_features(project, features, ProjectFeature::DISABLED)
+
+ features.each do |feature|
+ expect(project.feature_available?(feature.to_sym, user)).to eq(false), "#{feature} failed"
+ end
+ end
+ end
+
+ context 'when features are enabled only for team members' do
+ it "returns false when user is not a team member" do
+ update_all_project_features(project, features, ProjectFeature::PRIVATE)
+
+ features.each do |feature|
+ expect(project.feature_available?(feature.to_sym, user)).to eq(false), "#{feature} failed"
+ end
+ end
+
+ it "returns true when user is a team member" do
+ project.add_developer(user)
+
+ update_all_project_features(project, features, ProjectFeature::PRIVATE)
+
+ features.each do |feature|
+ expect(project.feature_available?(feature.to_sym, user)).to eq(true), "#{feature} failed"
+ end
+ end
+
+ it "returns true when user is a member of project group" do
+ group = create(:group)
+ project = create(:project, namespace: group)
+ group.add_developer(user)
+
+ update_all_project_features(project, features, ProjectFeature::PRIVATE)
+
+ features.each do |feature|
+ expect(project.feature_available?(feature.to_sym, user)).to eq(true), "#{feature} failed"
+ end
+ end
+
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it "returns true if user is an admin" do
+ user.update_attribute(:admin, true)
+
+ update_all_project_features(project, features, ProjectFeature::PRIVATE)
+
+ features.each do |feature|
+ expect(project.feature_available?(feature.to_sym, user)).to eq(true), "#{feature} failed"
+ end
+ end
+ end
+
+ context 'when admin mode is disabled' do
+ it "returns false when user is an admin" do
+ user.update_attribute(:admin, true)
+
+ update_all_project_features(project, features, ProjectFeature::PRIVATE)
+
+ features.each do |feature|
+ expect(project.feature_available?(feature.to_sym, user)).to eq(false), "#{feature} failed"
+ end
+ end
+ end
+ end
+
+ context 'when feature is enabled for everyone' do
+ it "returns true" do
+ expect(project.feature_available?(:issues, user)).to eq(true)
+ end
+ end
+
+ context 'when feature is disabled by a feature flag' do
+ it 'returns false' do
+ stub_feature_flags(issues: false)
+
+ expect(project.feature_available?(:issues, user)).to eq(false)
+ end
+ end
+
+ context 'when feature is enabled by a feature flag' do
+ it 'returns true' do
+ stub_feature_flags(issues: true)
+
+ expect(project.feature_available?(:issues, user)).to eq(true)
+ end
+ end
+ end
+
+ describe '#*_enabled?' do
+ let(:features) { %w(wiki builds merge_requests) }
+
+ it "returns false when feature is disabled" do
+ update_all_project_features(project, features, ProjectFeature::DISABLED)
+
+ features.each do |feature|
+ expect(project.public_send("#{feature}_enabled?")).to eq(false), "#{feature} failed"
+ end
+ end
+
+ it "returns true when feature is enabled only for team members" do
+ update_all_project_features(project, features, ProjectFeature::PRIVATE)
+
+ features.each do |feature|
+ expect(project.public_send("#{feature}_enabled?")).to eq(true), "#{feature} failed"
+ end
+ end
+
+ it "returns true when feature is enabled for everyone" do
+ features.each do |feature|
+ expect(project.public_send("#{feature}_enabled?")).to eq(true), "#{feature} failed"
+ end
+ end
+ end
+
+ def update_all_project_features(project, features, value)
+ project_feature_attributes = features.map { |f| ["#{f}_access_level", value] }.to_h
+ project.project_feature.update(project_feature_attributes)
+ end
+end
diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb
index 24908785320..74ee7a87b7b 100644
--- a/spec/models/concerns/issuable_spec.rb
+++ b/spec/models/concerns/issuable_spec.rb
@@ -102,6 +102,22 @@ describe Issuable do
end
end
+ describe '.any_label' do
+ let_it_be(:issue_with_label) { create(:labeled_issue, labels: [create(:label)]) }
+ let_it_be(:issue_with_multiple_labels) { create(:labeled_issue, labels: [create(:label), create(:label)]) }
+ let_it_be(:issue_without_label) { create(:issue) }
+
+ it 'returns an issuable with at least one label' do
+ expect(issuable_class.any_label).to match_array([issue_with_label, issue_with_multiple_labels])
+ end
+
+ context 'for custom sorting' do
+ it 'returns an issuable with at least one label' do
+ expect(issuable_class.any_label('created_at')).to eq([issue_with_label, issue_with_multiple_labels])
+ end
+ end
+ end
+
describe ".search" do
let!(:searchable_issue) { create(:issue, title: "Searchable awesome issue") }
let!(:searchable_issue2) { create(:issue, title: 'Aw') }
@@ -422,7 +438,7 @@ describe Issuable do
context 'total_time_spent is updated' do
before do
- issue.spend_time(duration: 2, user_id: user.id, spent_at: Time.now)
+ issue.spend_time(duration: 2, user_id: user.id, spent_at: Time.current)
issue.save
expect(Gitlab::HookData::IssuableBuilder)
.to receive(:new).with(issue).and_return(builder)
@@ -572,8 +588,8 @@ describe Issuable do
second_priority = create(:label, project: project, priority: 2)
no_priority = create(:label, project: project)
- first_milestone = create(:milestone, project: project, due_date: Time.now)
- second_milestone = create(:milestone, project: project, due_date: Time.now + 1.month)
+ first_milestone = create(:milestone, project: project, due_date: Time.current)
+ second_milestone = create(:milestone, project: project, due_date: Time.current + 1.month)
third_milestone = create(:milestone, project: project)
# The issues here are ordered by label priority, to ensure that we don't
diff --git a/spec/models/concerns/limitable_spec.rb b/spec/models/concerns/limitable_spec.rb
new file mode 100644
index 00000000000..ca0a257be7a
--- /dev/null
+++ b/spec/models/concerns/limitable_spec.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Limitable do
+ let(:minimal_test_class) do
+ Class.new do
+ include ActiveModel::Model
+
+ def self.name
+ 'TestClass'
+ end
+
+ include Limitable
+ end
+ end
+
+ before do
+ stub_const("MinimalTestClass", minimal_test_class)
+ end
+
+ it { expect(MinimalTestClass.limit_name).to eq('test_classes') }
+
+ context 'with scoped limit' do
+ before do
+ MinimalTestClass.limit_scope = :project
+ end
+
+ it { expect(MinimalTestClass.limit_scope).to eq(:project) }
+
+ it 'triggers scoped validations' do
+ instance = MinimalTestClass.new
+
+ expect(instance).to receive(:validate_scoped_plan_limit_not_exceeded)
+
+ instance.valid?(:create)
+ end
+ end
+
+ context 'with global limit' do
+ before do
+ MinimalTestClass.limit_scope = Limitable::GLOBAL_SCOPE
+ end
+
+ it { expect(MinimalTestClass.limit_scope).to eq(Limitable::GLOBAL_SCOPE) }
+
+ it 'triggers scoped validations' do
+ instance = MinimalTestClass.new
+
+ expect(instance).to receive(:validate_global_plan_limit_not_exceeded)
+
+ instance.valid?(:create)
+ end
+ end
+end
diff --git a/spec/models/concerns/milestoneish_spec.rb b/spec/models/concerns/milestoneish_spec.rb
index 81f173cd23a..8c43a12aa15 100644
--- a/spec/models/concerns/milestoneish_spec.rb
+++ b/spec/models/concerns/milestoneish_spec.rb
@@ -290,13 +290,13 @@ describe Milestone, 'Milestoneish' do
end
it 'shows 0 if start_date is a future' do
- milestone = build_stubbed(:milestone, start_date: Time.now + 2.days)
+ milestone = build_stubbed(:milestone, start_date: Time.current + 2.days)
expect(milestone.elapsed_days).to eq(0)
end
it 'shows correct amount of days' do
- milestone = build_stubbed(:milestone, start_date: Time.now - 2.days)
+ milestone = build_stubbed(:milestone, start_date: Time.current - 2.days)
expect(milestone.elapsed_days).to eq(2)
end
diff --git a/spec/models/concerns/resolvable_discussion_spec.rb b/spec/models/concerns/resolvable_discussion_spec.rb
index 9ea01ca9002..95553fb13a6 100644
--- a/spec/models/concerns/resolvable_discussion_spec.rb
+++ b/spec/models/concerns/resolvable_discussion_spec.rb
@@ -6,10 +6,10 @@ describe Discussion, ResolvableDiscussion do
subject { described_class.new([first_note, second_note, third_note]) }
let(:first_note) { create(:discussion_note_on_merge_request) }
- let(:merge_request) { first_note.noteable }
+ let(:noteable) { first_note.noteable }
let(:project) { first_note.project }
- let(:second_note) { create(:discussion_note_on_merge_request, noteable: merge_request, project: project, in_reply_to: first_note) }
- let(:third_note) { create(:discussion_note_on_merge_request, noteable: merge_request, project: project) }
+ let(:second_note) { create(:discussion_note_on_merge_request, noteable: noteable, project: project, in_reply_to: first_note) }
+ let(:third_note) { create(:discussion_note_on_merge_request, noteable: noteable, project: project) }
describe "#resolvable?" do
context "when potentially resolvable" do
@@ -198,12 +198,26 @@ describe Discussion, ResolvableDiscussion do
it "returns true" do
expect(subject.can_resolve?(current_user)).to be true
end
+
+ context "when the noteable has no author" do
+ it "returns true" do
+ expect(noteable).to receive(:author).and_return(nil)
+ expect(subject.can_resolve?(current_user)).to be true
+ end
+ end
end
context "when the signed in user is a random user" do
it "returns false" do
expect(subject.can_resolve?(current_user)).to be false
end
+
+ context "when the noteable has no author" do
+ it "returns false" do
+ expect(noteable).to receive(:author).and_return(nil)
+ expect(subject.can_resolve?(current_user)).to be false
+ end
+ end
end
end
end
@@ -536,7 +550,7 @@ describe Discussion, ResolvableDiscussion do
describe "#last_resolved_note" do
let(:current_user) { create(:user) }
- let(:time) { Time.now.utc }
+ let(:time) { Time.current.utc }
before do
Timecop.freeze(time - 1.second) do
diff --git a/spec/models/concerns/sortable_spec.rb b/spec/models/concerns/sortable_spec.rb
index 18ac4d19938..a1fe5c0928d 100644
--- a/spec/models/concerns/sortable_spec.rb
+++ b/spec/models/concerns/sortable_spec.rb
@@ -91,7 +91,7 @@ describe Sortable do
Group.all.order_by(order).map(&:name)
end
- let!(:ref_time) { Time.parse('2018-05-01 00:00:00') }
+ let!(:ref_time) { Time.zone.parse('2018-05-01 00:00:00') }
let!(:group1) { create(:group, name: 'aa', id: 1, created_at: ref_time - 15.seconds, updated_at: ref_time) }
let!(:group2) { create(:group, name: 'AAA', id: 2, created_at: ref_time - 10.seconds, updated_at: ref_time - 5.seconds) }
let!(:group3) { create(:group, name: 'BB', id: 3, created_at: ref_time - 5.seconds, updated_at: ref_time - 10.seconds) }
diff --git a/spec/models/container_expiration_policy_spec.rb b/spec/models/container_expiration_policy_spec.rb
index c22362ed5d4..588685b04bf 100644
--- a/spec/models/container_expiration_policy_spec.rb
+++ b/spec/models/container_expiration_policy_spec.rb
@@ -37,6 +37,37 @@ RSpec.describe ContainerExpirationPolicy, type: :model do
it { is_expected.to allow_value(nil).for(:keep_n) }
it { is_expected.not_to allow_value('foo').for(:keep_n) }
end
+
+ context 'with a set of regexps' do
+ valid_regexps = %w[master .* v.+ v10.1.* (?:v.+|master|release)]
+ invalid_regexps = ['[', '(?:v.+|master|release']
+
+ valid_regexps.each do |valid_regexp|
+ it { is_expected.to allow_value(valid_regexp).for(:name_regex) }
+ it { is_expected.to allow_value(valid_regexp).for(:name_regex_keep) }
+ end
+
+ invalid_regexps.each do |invalid_regexp|
+ it { is_expected.not_to allow_value(invalid_regexp).for(:name_regex) }
+ it { is_expected.not_to allow_value(invalid_regexp).for(:name_regex_keep) }
+ end
+
+ context 'with a disabled container expiration policy' do
+ let_it_be(:container_expiration_policy) { create(:container_expiration_policy, :disabled) }
+
+ subject { container_expiration_policy }
+
+ valid_regexps.each do |valid_regexp|
+ it { is_expected.to allow_value(valid_regexp).for(:name_regex) }
+ it { is_expected.to allow_value(valid_regexp).for(:name_regex_keep) }
+ end
+
+ invalid_regexps.each do |invalid_regexp|
+ it { is_expected.to allow_value(invalid_regexp).for(:name_regex) }
+ it { is_expected.to allow_value(invalid_regexp).for(:name_regex_keep) }
+ end
+ end
+ end
end
describe '.preloaded' do
@@ -72,4 +103,14 @@ RSpec.describe ContainerExpirationPolicy, type: :model do
end
end
end
+
+ describe '#disable!' do
+ let_it_be(:container_expiration_policy) { create(:container_expiration_policy) }
+
+ subject { container_expiration_policy.disable! }
+
+ it 'disables the container expiration policy' do
+ expect { subject }.to change { container_expiration_policy.reload.enabled }.from(true).to(false)
+ end
+ end
end
diff --git a/spec/models/container_repository_spec.rb b/spec/models/container_repository_spec.rb
index 1eecefe5d4a..4f23a905e93 100644
--- a/spec/models/container_repository_spec.rb
+++ b/spec/models/container_repository_spec.rb
@@ -81,6 +81,12 @@ describe ContainerRepository do
end
end
+ describe '#tags_count' do
+ it 'returns the count of tags' do
+ expect(repository.tags_count).to eq(1)
+ end
+ end
+
describe '#has_tags?' do
it 'has tags' do
expect(repository).to have_tags
diff --git a/spec/models/deployment_spec.rb b/spec/models/deployment_spec.rb
index 6eb006a5d67..ac2a4c9877d 100644
--- a/spec/models/deployment_spec.rb
+++ b/spec/models/deployment_spec.rb
@@ -114,7 +114,7 @@ describe Deployment do
deployment.succeed!
expect(deployment).to be_success
- expect(deployment.finished_at).to be_like_time(Time.now)
+ expect(deployment.finished_at).to be_like_time(Time.current)
end
end
@@ -141,7 +141,7 @@ describe Deployment do
deployment.drop!
expect(deployment).to be_failed
- expect(deployment.finished_at).to be_like_time(Time.now)
+ expect(deployment.finished_at).to be_like_time(Time.current)
end
end
@@ -161,7 +161,7 @@ describe Deployment do
deployment.cancel!
expect(deployment).to be_canceled
- expect(deployment.finished_at).to be_like_time(Time.now)
+ expect(deployment.finished_at).to be_like_time(Time.current)
end
end
@@ -587,7 +587,7 @@ describe Deployment do
Timecop.freeze do
deploy.update_status('success')
- expect(deploy.read_attribute(:finished_at)).to eq(Time.now)
+ expect(deploy.read_attribute(:finished_at)).to eq(Time.current)
end
end
end
diff --git a/spec/models/design_management/design_spec.rb b/spec/models/design_management/design_spec.rb
index 95782c1f674..bc1f54f057e 100644
--- a/spec/models/design_management/design_spec.rb
+++ b/spec/models/design_management/design_spec.rb
@@ -27,6 +27,7 @@ describe DesignManagement::Design do
it { is_expected.to validate_presence_of(:project) }
it { is_expected.to validate_presence_of(:issue) }
it { is_expected.to validate_presence_of(:filename) }
+ it { is_expected.to validate_length_of(:filename).is_at_most(255) }
it { is_expected.to validate_uniqueness_of(:filename).scoped_to(:issue_id) }
it "validates that the extension is an image" do
@@ -460,38 +461,6 @@ describe DesignManagement::Design do
it 'uses the simple format' do
expect(reference).to eq "#1[homescreen.jpg]"
end
-
- context 'when the filename contains spaces, hyphens, periods, single-quotes, underscores and colons' do
- let(:filename) { %q{a complex filename: containing - _ : etc., but still 'simple'.gif} }
-
- it 'uses the simple format' do
- expect(reference).to eq "#1[#{filename}]"
- end
- end
-
- context 'when the filename contains HTML angle brackets' do
- let(:filename) { 'a <em>great</em> filename.jpg' }
-
- it 'uses Base64 encoding' do
- expect(reference).to eq "#1[base64:#{Base64.strict_encode64(filename)}]"
- end
- end
-
- context 'when the filename contains quotation marks' do
- let(:filename) { %q{a "great" filename.jpg} }
-
- it 'uses enclosing quotes, with backslash encoding' do
- expect(reference).to eq %q{#1["a \"great\" filename.jpg"]}
- end
- end
-
- context 'when the filename contains square brackets' do
- let(:filename) { %q{a [great] filename.jpg} }
-
- it 'uses enclosing quotes' do
- expect(reference).to eq %q{#1["a [great] filename.jpg"]}
- end
- end
end
context 'when full is true' do
@@ -525,31 +494,55 @@ describe DesignManagement::Design do
end
describe 'reference_pattern' do
- let(:match) { described_class.reference_pattern.match(ref) }
- let(:ref) { design.to_reference }
- let(:design) { build(:design, filename: filename) }
+ it 'is nil' do
+ expect(described_class.reference_pattern).to be_nil
+ end
+ end
- context 'simple_file_name' do
- let(:filename) { 'simple-file-name.jpg' }
+ describe 'link_reference_pattern' do
+ it 'is not nil' do
+ expect(described_class.link_reference_pattern).not_to be_nil
+ end
+
+ it 'does not match the designs tab' do
+ expect(described_class.link_reference_pattern).not_to match(url_for_designs(issue))
+ end
- it 'matches :simple_file_name' do
- expect(match[:simple_file_name]).to eq(filename)
+ where(:ext) do
+ (described_class::SAFE_IMAGE_EXT + described_class::DANGEROUS_IMAGE_EXT).flat_map do |ext|
+ [[ext], [ext.upcase]]
end
end
- context 'quoted_file_name' do
- let(:filename) { 'simple "file" name.jpg' }
+ with_them do
+ let(:filename) { "my-file.#{ext}" }
+ let(:design) { build(:design, filename: filename) }
+ let(:url) { url_for_design(design) }
+ let(:captures) { described_class.link_reference_pattern.match(url)&.named_captures }
- it 'matches :simple_file_name' do
- expect(match[:escaped_filename].gsub(/\\"/, '"')).to eq(filename)
+ it 'matches the URL' do
+ expect(captures).to include(
+ 'url_filename' => filename,
+ 'issue' => design.issue.iid.to_s,
+ 'namespace' => design.project.namespace.to_param,
+ 'project' => design.project.name
+ )
end
- end
- context 'Base64 name' do
- let(:filename) { '<>.png' }
+ context 'the file needs to be encoded' do
+ let(:filename) { "my file.#{ext}" }
- it 'matches base_64_encoded_name' do
- expect(Base64.decode64(match[:base_64_encoded_name])).to eq(filename)
+ it 'extracts the encoded filename' do
+ expect(captures).to include('url_filename' => 'my%20file.' + ext)
+ end
+ end
+
+ context 'the file is all upper case' do
+ let(:filename) { "file.#{ext}".upcase }
+
+ it 'extracts the encoded filename' do
+ expect(captures).to include('url_filename' => filename)
+ end
end
end
end
diff --git a/spec/models/diff_note_spec.rb b/spec/models/diff_note_spec.rb
index 65f06a5b270..8bfe2ac7a6c 100644
--- a/spec/models/diff_note_spec.rb
+++ b/spec/models/diff_note_spec.rb
@@ -238,12 +238,32 @@ describe DiffNote do
end
context 'when the discussion was created in the diff' do
- it 'returns correct diff file' do
- diff_file = subject.diff_file
+ context 'when file_identifier_hash is disabled' do
+ before do
+ stub_feature_flags(file_identifier_hash: false)
+ end
- expect(diff_file.old_path).to eq(position.old_path)
- expect(diff_file.new_path).to eq(position.new_path)
- expect(diff_file.diff_refs).to eq(position.diff_refs)
+ it 'returns correct diff file' do
+ diff_file = subject.diff_file
+
+ expect(diff_file.old_path).to eq(position.old_path)
+ expect(diff_file.new_path).to eq(position.new_path)
+ expect(diff_file.diff_refs).to eq(position.diff_refs)
+ end
+ end
+
+ context 'when file_identifier_hash is enabled' do
+ before do
+ stub_feature_flags(file_identifier_hash: true)
+ end
+
+ it 'returns correct diff file' do
+ diff_file = subject.diff_file
+
+ expect(diff_file.old_path).to eq(position.old_path)
+ expect(diff_file.new_path).to eq(position.new_path)
+ expect(diff_file.diff_refs).to eq(position.diff_refs)
+ end
end
end
diff --git a/spec/models/draft_note_spec.rb b/spec/models/draft_note_spec.rb
new file mode 100644
index 00000000000..b880d3c5b97
--- /dev/null
+++ b/spec/models/draft_note_spec.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe DraftNote do
+ include RepoHelpers
+
+ let(:project) { create(:project, :repository) }
+ let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) }
+
+ describe 'validations' do
+ it_behaves_like 'a valid diff positionable note', :draft_note
+ end
+
+ describe 'delegations' do
+ it { is_expected.to delegate_method(:file_path).to(:diff_file).allow_nil }
+ it { is_expected.to delegate_method(:file_hash).to(:diff_file).allow_nil }
+ it { is_expected.to delegate_method(:file_identifier_hash).to(:diff_file).allow_nil }
+ end
+
+ describe '#diff_file' do
+ let(:draft_note) { build(:draft_note, merge_request: merge_request) }
+
+ context 'when diff_file exists' do
+ it "returns an unfolded diff_file" do
+ diff_file = instance_double(Gitlab::Diff::File)
+ expect(draft_note.original_position).to receive(:diff_file).with(project.repository).and_return(diff_file)
+ expect(diff_file).to receive(:unfold_diff_lines).with(draft_note.original_position)
+
+ expect(draft_note.diff_file).to be diff_file
+ end
+ end
+
+ context 'when diff_file does not exist' do
+ it 'returns nil' do
+ expect(draft_note.original_position).to receive(:diff_file).with(project.repository).and_return(nil)
+
+ expect(draft_note.diff_file).to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb
index c0b2a4ae984..b93da518b68 100644
--- a/spec/models/environment_spec.rb
+++ b/spec/models/environment_spec.rb
@@ -1061,7 +1061,7 @@ describe Environment, :use_clean_rails_memory_store_caching do
end
context 'when time window arguments are provided' do
- let(:metric_params) { [1552642245.067, Time.now] }
+ let(:metric_params) { [1552642245.067, Time.current] }
it 'queries with the expected parameters' do
expect(environment.prometheus_adapter)
diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb
index ac89f8fe9e1..14066b1e9d2 100644
--- a/spec/models/event_spec.rb
+++ b/spec/models/event_spec.rb
@@ -13,6 +13,7 @@ describe Event do
it { is_expected.to respond_to(:author_email) }
it { is_expected.to respond_to(:issue_title) }
it { is_expected.to respond_to(:merge_request_title) }
+ it { is_expected.to respond_to(:design_title) }
end
describe 'Callbacks' do
@@ -37,7 +38,7 @@ describe Event do
project.reload
- expect(project.last_repository_updated_at).to be_within(1.minute).of(Time.now)
+ expect(project.last_repository_updated_at).to be_within(1.minute).of(Time.current)
end
end
@@ -67,19 +68,32 @@ describe Event do
end
end
- describe 'after_create :track_user_interacted_projects' do
+ describe 'after_create UserInteractedProject.track' do
let(:event) { build(:push_event, project: project, author: project.owner) }
it 'passes event to UserInteractedProject.track' do
- expect(UserInteractedProject).to receive(:available?).and_return(true)
expect(UserInteractedProject).to receive(:track).with(event)
event.save
end
+ end
+ end
- it 'does not call UserInteractedProject.track if its not yet available' do
- expect(UserInteractedProject).to receive(:available?).and_return(false)
- expect(UserInteractedProject).not_to receive(:track)
- event.save
+ describe 'validations' do
+ describe 'action' do
+ context 'for a design' do
+ where(:action, :valid) do
+ valid = described_class::DESIGN_ACTIONS.map(&:to_s).to_set
+
+ described_class.actions.keys.map do |action|
+ [action, valid.include?(action)]
+ end
+ end
+
+ with_them do
+ let(:event) { build(:design_event, action: action) }
+
+ specify { expect(event.valid?).to eq(valid) }
+ end
end
end
end
@@ -552,7 +566,7 @@ describe Event do
end
end
- context 'design event' do
+ context 'design note event' do
include DesignManagementTestHelpers
let(:target) { note_on_design }
@@ -577,6 +591,32 @@ describe Event do
include_examples 'visible to assignee and author', true
end
end
+
+ context 'design event' do
+ include DesignManagementTestHelpers
+
+ let(:target) { design }
+
+ before do
+ enable_design_management
+ end
+
+ include_examples 'visibility examples' do
+ let(:visibility) { visible_to_all }
+ end
+
+ include_examples 'visible to assignee and author', true
+
+ context 'the event refers to a design on a confidential issue' do
+ let(:design) { create(:design, issue: confidential_issue, project: project) }
+
+ include_examples 'visibility examples' do
+ let(:visibility) { visible_to_none_except(:member, :admin) }
+ end
+
+ include_examples 'visible to assignee and author', true
+ end
+ end
end
describe 'wiki_page predicate scopes' do
@@ -587,10 +627,31 @@ describe Event do
create(:wiki_page_event),
create(:closed_issue_event),
create(:event, :created),
- create(:wiki_page_event)
+ create(:design_event, :destroyed),
+ create(:wiki_page_event),
+ create(:design_event)
]
end
+ describe '.for_design' do
+ it 'only includes design events' do
+ design_events = events.select(&:design?)
+
+ expect(described_class.for_design)
+ .to be_present
+ .and match_array(design_events)
+ end
+ end
+
+ describe '.not_design' do
+ it 'does not contain the design events' do
+ non_design_events = events.reject(&:design?)
+
+ expect(events).not_to match_array(non_design_events)
+ expect(described_class.not_design).to match_array(non_design_events)
+ end
+ end
+
describe '.for_wiki_page' do
it 'only contains the wiki page events' do
wiki_events = events.select(&:wiki_page?)
@@ -618,26 +679,76 @@ describe Event do
end
end
- describe '#wiki_page and #wiki_page?' do
+ describe 'categorization' do
let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:all_valid_events) do
+ # mapping from factory name to whether we need to supply the project
+ valid_target_factories = {
+ issue: true,
+ note_on_issue: true,
+ user: false,
+ merge_request: true,
+ note_on_merge_request: true,
+ project_snippet: true,
+ personal_snippet: false,
+ note_on_project_snippet: true,
+ note_on_personal_snippet: false,
+ wiki_page_meta: true,
+ milestone: true,
+ project: false,
+ design: true,
+ note_on_design: true,
+ note_on_commit: true
+ }
+ valid_target_factories.map do |kind, needs_project|
+ extra_data = needs_project ? { project: project } : {}
+ target = kind == :project ? nil : build(kind, **extra_data)
+ [kind, build(:event, :created, project: project, target: target)]
+ end.to_h
+ end
+
+ it 'passes a sanity check', :aggregate_failures do
+ expect(all_valid_events.values).to all(be_valid)
+ end
- context 'for a wiki page event' do
- let(:wiki_page) do
- create(:wiki_page, project: project)
+ describe '#wiki_page and #wiki_page?' do
+ context 'for a wiki page event' do
+ let(:wiki_page) do
+ create(:wiki_page, project: project)
+ end
+
+ subject(:event) { create(:wiki_page_event, project: project, wiki_page: wiki_page) }
+
+ it { is_expected.to have_attributes(wiki_page?: be_truthy, wiki_page: wiki_page) }
end
- subject(:event) { create(:wiki_page_event, project: project, wiki_page: wiki_page) }
+ context 'for any other event' do
+ it 'has no wiki_page and is not a wiki_page', :aggregate_failures do
+ all_valid_events.each do |k, event|
+ next if k == :wiki_page_meta
- it { is_expected.to have_attributes(wiki_page?: be_truthy, wiki_page: wiki_page) }
+ expect(event).to have_attributes(wiki_page: be_nil, wiki_page?: be_falsy)
+ end
+ end
+ end
end
- [:issue, :user, :merge_request, :snippet, :milestone, nil].each do |kind|
- context "for a #{kind} event" do
- it 'is nil' do
- target = create(kind) if kind
- event = create(:event, project: project, target: target)
+ describe '#design and #design?' do
+ context 'for a design event' do
+ let(:design) { build(:design, project: project) }
+
+ subject(:event) { build(:design_event, target: design, project: project) }
+
+ it { is_expected.to have_attributes(design?: be_truthy, design: design) }
+ end
+
+ context 'for any other event' do
+ it 'has no design and is not a design', :aggregate_failures do
+ all_valid_events.each do |k, event|
+ next if k == :design
- expect(event).to have_attributes(wiki_page: be_nil, wiki_page?: be_falsy)
+ expect(event).to have_attributes(design: be_nil, design?: be_falsy)
+ end
end
end
end
@@ -665,7 +776,7 @@ describe Event do
context 'when a project was updated less than 1 hour ago' do
it 'does not update the project' do
- project.update(last_activity_at: Time.now)
+ project.update(last_activity_at: Time.current)
expect(project).not_to receive(:update_column)
.with(:last_activity_at, a_kind_of(Time))
@@ -682,7 +793,7 @@ describe Event do
project.reload
- expect(project.last_activity_at).to be_within(1.minute).of(Time.now)
+ expect(project.last_activity_at).to be_within(1.minute).of(Time.current)
end
end
end
@@ -765,6 +876,19 @@ describe Event do
end
end
+ describe '#action_name' do
+ it 'handles all valid design events' do
+ created, updated, destroyed, archived = %i[created updated destroyed archived].map do |trait|
+ build(:design_event, trait).action_name
+ end
+
+ expect(created).to eq('uploaded')
+ expect(updated).to eq('revised')
+ expect(destroyed).to eq('deleted')
+ expect(archived).to eq('archived')
+ end
+ end
+
def create_push_event(project, user)
event = create(:push_event, project: project, author: user)
diff --git a/spec/models/fork_network_member_spec.rb b/spec/models/fork_network_member_spec.rb
index eab758248de..d7a0dd5be65 100644
--- a/spec/models/fork_network_member_spec.rb
+++ b/spec/models/fork_network_member_spec.rb
@@ -13,7 +13,7 @@ describe ForkNetworkMember do
let(:fork_network) { fork_network_member.fork_network }
it 'removes the fork network if it was the last member' do
- fork_network.fork_network_members.destroy_all # rubocop: disable DestroyAll
+ fork_network.fork_network_members.destroy_all # rubocop: disable Cop/DestroyAll
expect(ForkNetwork.count).to eq(0)
end
diff --git a/spec/models/global_milestone_spec.rb b/spec/models/global_milestone_spec.rb
deleted file mode 100644
index 34dbdfec60d..00000000000
--- a/spec/models/global_milestone_spec.rb
+++ /dev/null
@@ -1,208 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe GlobalMilestone do
- let(:user) { create(:user) }
- let(:user2) { create(:user) }
- let(:group) { create(:group) }
- let(:project1) { create(:project, group: group) }
- let(:project2) { create(:project, path: 'gitlab-ci', group: group) }
- let(:project3) { create(:project, path: 'cookbook-gitlab', group: group) }
-
- describe '.build_collection' do
- let(:milestone1_due_date) { 2.weeks.from_now.to_date }
-
- let!(:milestone1_project1) do
- create(
- :milestone,
- title: "Milestone v1.2",
- project: project1,
- due_date: milestone1_due_date
- )
- end
-
- let!(:milestone1_project2) do
- create(
- :milestone,
- title: "Milestone v1.2",
- project: project2,
- due_date: milestone1_due_date
- )
- end
-
- let!(:milestone1_project3) do
- create(
- :milestone,
- title: "Milestone v1.2",
- project: project3,
- due_date: milestone1_due_date
- )
- end
-
- let!(:milestone2_project1) do
- create(
- :milestone,
- title: "VD-123",
- project: project1,
- due_date: nil
- )
- end
-
- let!(:milestone2_project2) do
- create(
- :milestone,
- title: "VD-123",
- project: project2,
- due_date: nil
- )
- end
-
- let!(:milestone2_project3) do
- create(
- :milestone,
- title: "VD-123",
- project: project3,
- due_date: nil
- )
- end
-
- let!(:projects) do
- [
- project1,
- project2,
- project3
- ]
- end
-
- let!(:global_milestones) { described_class.build_collection(projects, {}) }
-
- context 'when building a collection of milestones' do
- it 'has all project milestones' do
- expect(global_milestones.count).to eq(6)
- end
-
- it 'has all project milestones titles' do
- expect(global_milestones.map(&:title)).to match_array(['Milestone v1.2', 'Milestone v1.2', 'Milestone v1.2', 'VD-123', 'VD-123', 'VD-123'])
- end
-
- it 'has all project milestones' do
- expect(global_milestones.size).to eq(6)
- end
-
- it 'sorts collection by due date' do
- expect(global_milestones.map(&:due_date)).to eq [milestone1_due_date, milestone1_due_date, milestone1_due_date, nil, nil, nil]
- end
-
- it 'filters milestones by search_title when params[:search_title] is present' do
- global_milestones = described_class.build_collection(projects, { search_title: 'v1.2' })
-
- expect(global_milestones.map(&:title)).to match_array(['Milestone v1.2', 'Milestone v1.2', 'Milestone v1.2'])
- end
- end
-
- context 'when adding new milestones' do
- it 'does not add more queries' do
- control_count = ActiveRecord::QueryRecorder.new do
- described_class.build_collection(projects, {})
- end.count
-
- create_list(:milestone, 3, project: project3)
-
- expect do
- described_class.build_collection(projects, {})
- end.not_to exceed_all_query_limit(control_count)
- end
- end
- end
-
- describe '.states_count' do
- context 'when the projects have milestones' do
- before do
- create(:closed_milestone, title: 'Active Group Milestone', project: project3)
- create(:active_milestone, title: 'Active Group Milestone', project: project1)
- create(:active_milestone, title: 'Active Group Milestone', project: project2)
- create(:closed_milestone, title: 'Closed Group Milestone', project: project1)
- create(:closed_milestone, title: 'Closed Group Milestone', project: project2)
- create(:closed_milestone, title: 'Closed Group Milestone', project: project3)
- create(:closed_milestone, title: 'Closed Group Milestone 4', group: group)
- end
-
- it 'returns the quantity of global milestones and group milestones in each possible state' do
- expected_count = { opened: 2, closed: 5, all: 7 }
-
- count = described_class.states_count(Project.all, group)
-
- expect(count).to eq(expected_count)
- end
-
- it 'returns the quantity of global milestones in each possible state' do
- expected_count = { opened: 2, closed: 4, all: 6 }
-
- count = described_class.states_count(Project.all)
-
- expect(count).to eq(expected_count)
- end
- end
-
- context 'when the projects do not have milestones' do
- before do
- project1
- end
-
- it 'returns 0 as the quantity of global milestones in each state' do
- expected_count = { opened: 0, closed: 0, all: 0 }
-
- count = described_class.states_count(Project.all)
-
- expect(count).to eq(expected_count)
- end
- end
- end
-
- describe '#initialize' do
- let(:milestone1_project1) { create(:milestone, title: "Milestone v1.2", project: project1) }
-
- subject(:global_milestone) { described_class.new(milestone1_project1) }
-
- it 'has exactly one group milestone' do
- expect(global_milestone.title).to eq('Milestone v1.2')
- end
-
- it 'has all project milestones with the same title' do
- expect(global_milestone.milestone).to eq(milestone1_project1)
- end
- end
-
- describe '#safe_title' do
- let(:milestone) { create(:milestone, title: "git / test", project: project1) }
-
- it 'strips out slashes and spaces' do
- global_milestone = described_class.new(milestone)
-
- expect(global_milestone.safe_title).to eq('git-test')
- end
- end
-
- describe '#state' do
- context 'when at least one milestone is active' do
- it 'returns active' do
- title = 'Active Group Milestone'
-
- global_milestone = described_class.new(create(:active_milestone, title: title))
-
- expect(global_milestone.state).to eq('active')
- end
- end
-
- context 'when all milestones are closed' do
- it 'returns closed' do
- title = 'Closed Group Milestone'
-
- global_milestone = described_class.new(create(:closed_milestone, title: title))
-
- expect(global_milestone.state).to eq('closed')
- end
- end
- end
-end
diff --git a/spec/models/group_deploy_key_spec.rb b/spec/models/group_deploy_key_spec.rb
new file mode 100644
index 00000000000..3ba56c7e504
--- /dev/null
+++ b/spec/models/group_deploy_key_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GroupDeployKey do
+ it { is_expected.to validate_presence_of(:user) }
+
+ it 'is of type DeployKey' do
+ expect(build(:group_deploy_key).type).to eq('DeployKey')
+ end
+end
diff --git a/spec/models/group_group_link_spec.rb b/spec/models/group_group_link_spec.rb
index 1fbd399e82b..54e622b2f22 100644
--- a/spec/models/group_group_link_spec.rb
+++ b/spec/models/group_group_link_spec.rb
@@ -29,6 +29,32 @@ describe GroupGroupLink do
])
end
end
+
+ describe '.public_or_visible_to_user' do
+ let!(:user_with_access) { create :user }
+ let!(:user_without_access) { create :user }
+ let!(:shared_with_group) { create :group, :private }
+ let!(:shared_group) { create :group }
+ let!(:private_group_group_link) { create(:group_group_link, shared_group: shared_group, shared_with_group: shared_with_group) }
+
+ before do
+ shared_group.add_owner(user_with_access)
+ shared_group.add_owner(user_without_access)
+ shared_with_group.add_developer(user_with_access)
+ end
+
+ context 'when user can access shared group' do
+ it 'returns the private group' do
+ expect(described_class.public_or_visible_to_user(shared_group, user_with_access)).to include(private_group_group_link)
+ end
+ end
+
+ context 'when user does not have access to shared group' do
+ it 'does not return private group' do
+ expect(described_class.public_or_visible_to_user(shared_group, user_without_access)).not_to include(private_group_group_link)
+ end
+ end
+ end
end
describe 'validation' do
diff --git a/spec/models/group_import_state_spec.rb b/spec/models/group_import_state_spec.rb
new file mode 100644
index 00000000000..9d9cb1e8391
--- /dev/null
+++ b/spec/models/group_import_state_spec.rb
@@ -0,0 +1,72 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GroupImportState do
+ describe 'validations' do
+ let_it_be(:group) { create(:group) }
+
+ it { is_expected.to validate_presence_of(:group) }
+ it { is_expected.to validate_presence_of(:status) }
+
+ it 'can be created without a jid' do
+ import_state = build(:group_import_state, :created, group: group, jid: nil)
+
+ expect(import_state).to be_valid
+ end
+
+ it 'cannot be started without a jid' do
+ import_state = build(:group_import_state, :started, group: group, jid: nil)
+
+ expect(import_state).not_to be_valid
+ expect(import_state.errors[:jid]).to include "can't be blank"
+ end
+
+ it 'cannot be finished without a jid' do
+ import_state = build(:group_import_state, :finished, group: group, jid: nil)
+
+ expect(import_state).not_to be_valid
+ expect(import_state.errors[:jid]).to include "can't be blank"
+ end
+
+ it 'can fail without a jid' do
+ import_state = build(:group_import_state, :failed, group: group, jid: nil)
+
+ expect(import_state).to be_valid
+ end
+ end
+
+ describe '#in_progress?' do
+ context "when the import is 'created'" do
+ it "returns true" do
+ group_import_state = build(:group_import_state, :created)
+
+ expect(group_import_state.in_progress?).to eq true
+ end
+ end
+
+ context "when the import is 'started'" do
+ it "returns true" do
+ group_import_state = build(:group_import_state, :started)
+
+ expect(group_import_state.in_progress?).to eq true
+ end
+ end
+
+ context "when the import is 'finished'" do
+ it "returns false" do
+ group_import_state = build(:group_import_state, :finished)
+
+ expect(group_import_state.in_progress?).to eq false
+ end
+ end
+
+ context "when the import is 'failed'" do
+ it "returns false" do
+ group_import_state = build(:group_import_state, :failed)
+
+ expect(group_import_state.in_progress?).to eq false
+ end
+ end
+ end
+end
diff --git a/spec/models/group_milestone_spec.rb b/spec/models/group_milestone_spec.rb
deleted file mode 100644
index 01856870fe0..00000000000
--- a/spec/models/group_milestone_spec.rb
+++ /dev/null
@@ -1,57 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe GroupMilestone do
- let(:group) { create(:group) }
- let(:project) { create(:project, group: group) }
- let(:project_milestone) do
- create(:milestone, title: "Milestone v1.2", project: project)
- end
-
- describe '.build' do
- it 'returns milestone with group assigned' do
- milestone = described_class.build(
- group,
- [project],
- project_milestone.title
- )
-
- expect(milestone.group).to eq group
- end
- end
-
- describe '.build_collection' do
- let(:group) { create(:group) }
- let(:project1) { create(:project, group: group) }
- let(:project2) { create(:project, path: 'gitlab-ci', group: group) }
- let(:project3) { create(:project, path: 'cookbook-gitlab', group: group) }
-
- let!(:projects) do
- [
- project1,
- project2,
- project3
- ]
- end
-
- it 'returns array of milestones, each with group assigned' do
- milestones = described_class.build_collection(group, [project], {})
- expect(milestones).to all(have_attributes(group: group))
- end
-
- context 'when adding new milestones' do
- it 'does not add more queries' do
- control_count = ActiveRecord::QueryRecorder.new do
- described_class.build_collection(group, projects, {})
- end.count
-
- create(:milestone, title: 'This title', project: project1)
-
- expect do
- described_class.build_collection(group, projects, {})
- end.not_to exceed_all_query_limit(control_count)
- end
- end
- end
-end
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index d6e76258491..93cb6d83489 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -662,6 +662,19 @@ describe Group do
expect(group.members_with_parents).to include(developer)
expect(group.members_with_parents).to include(maintainer)
end
+
+ context 'group sharing' do
+ let!(:shared_group) { create(:group) }
+
+ before do
+ create(:group_group_link, shared_group: shared_group, shared_with_group: group)
+ end
+
+ it 'returns shared with group members' do
+ expect(shared_group.members_with_parents).to(
+ include(developer))
+ end
+ end
end
describe '#members_from_self_and_ancestors_with_effective_access_level' do
@@ -800,6 +813,22 @@ describe Group do
expect(group.user_ids_for_project_authorizations)
.to include(maintainer.id, developer.id)
end
+
+ context 'group sharing' do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:group_user) { create(:user) }
+ let_it_be(:shared_group) { create(:group) }
+
+ before do
+ group.add_developer(group_user)
+ create(:group_group_link, shared_group: shared_group, shared_with_group: group)
+ end
+
+ it 'returns the user IDs for shared with group members' do
+ expect(shared_group.user_ids_for_project_authorizations).to(
+ include(group_user.id))
+ end
+ end
end
describe '#update_two_factor_requirement' do
diff --git a/spec/models/hooks/system_hook_spec.rb b/spec/models/hooks/system_hook_spec.rb
index 94f1b0cba2e..2e836c19e3c 100644
--- a/spec/models/hooks/system_hook_spec.rb
+++ b/spec/models/hooks/system_hook_spec.rb
@@ -75,7 +75,7 @@ describe SystemHook do
it "project member destroy hook" do
project.add_maintainer(user)
- project.project_members.destroy_all # rubocop: disable DestroyAll
+ project.project_members.destroy_all # rubocop: disable Cop/DestroyAll
expect(WebMock).to have_requested(:post, system_hook.url).with(
body: /user_remove_from_team/,
@@ -121,7 +121,7 @@ describe SystemHook do
it 'group member destroy hook' do
group.add_maintainer(user)
- group.group_members.destroy_all # rubocop: disable DestroyAll
+ group.group_members.destroy_all # rubocop: disable Cop/DestroyAll
expect(WebMock).to have_requested(:post, system_hook.url).with(
body: /user_remove_from_group/,
diff --git a/spec/models/instance_configuration_spec.rb b/spec/models/instance_configuration_spec.rb
index 3e0181b8846..747e9dc2faa 100644
--- a/spec/models/instance_configuration_spec.rb
+++ b/spec/models/instance_configuration_spec.rb
@@ -110,7 +110,7 @@ describe InstanceConfiguration do
end
it 'expires after EXPIRATION_TIME' do
- allow(Time).to receive(:now).and_return(Time.now + described_class::EXPIRATION_TIME)
+ allow(Time).to receive(:now).and_return(Time.current + described_class::EXPIRATION_TIME)
Rails.cache.cleanup
expect(Rails.cache.read(described_class::CACHE_KEY)).to eq(nil)
diff --git a/spec/models/integration_spec.rb b/spec/models/integration_spec.rb
new file mode 100644
index 00000000000..3042fd15a7b
--- /dev/null
+++ b/spec/models/integration_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Integration do
+ let(:project_1) { create(:project) }
+ let(:project_2) { create(:project) }
+ let(:instance_integration) { create(:jira_service, :instance) }
+
+ before do
+ create(:jira_service, project: project_1, inherit_from_id: instance_integration.id)
+ create(:jira_service, project: project_2, inherit_from_id: nil)
+ create(:slack_service, project: project_1, inherit_from_id: nil)
+ end
+
+ describe '#with_custom_integration_for' do
+ it 'returns projects with custom integrations' do
+ expect(Project.with_custom_integration_for(instance_integration)).to contain_exactly(project_2)
+ end
+ end
+end
diff --git a/spec/models/internal_id_spec.rb b/spec/models/internal_id_spec.rb
index 33d03bfc0f5..0dfb59cf43a 100644
--- a/spec/models/internal_id_spec.rb
+++ b/spec/models/internal_id_spec.rb
@@ -88,33 +88,6 @@ describe InternalId do
expect(normalized).to eq((0..seq.size - 1).to_a)
end
-
- context 'with an insufficient schema version' do
- before do
- described_class.reset_column_information
- # Project factory will also call the current_version
- expect(ActiveRecord::Migrator).to receive(:current_version).at_least(:once).and_return(InternalId::REQUIRED_SCHEMA_VERSION - 1)
- end
-
- let(:init) { double('block') }
-
- it 'calculates next internal ids on the fly' do
- val = rand(1..100)
-
- expect(init).to receive(:call).with(issue).and_return(val)
- expect(subject).to eq(val + 1)
- end
-
- it 'always attempts to generate internal IDs in production mode' do
- stub_rails_env('production')
-
- val = rand(1..100)
- generator = double(generate: val)
- expect(InternalId::InternalIdGenerator).to receive(:new).and_return(generator)
-
- expect(subject).to eq(val)
- end
- end
end
describe '.reset' do
@@ -152,20 +125,6 @@ describe InternalId do
described_class.generate_next(issue, scope, usage, init)
end
end
-
- context 'with an insufficient schema version' do
- let(:value) { 2 }
-
- before do
- described_class.reset_column_information
- # Project factory will also call the current_version
- expect(ActiveRecord::Migrator).to receive(:current_version).at_least(:once).and_return(InternalId::REQUIRED_SCHEMA_VERSION - 1)
- end
-
- it 'does not reset any of the iids' do
- expect(subject).to be_falsey
- end
- end
end
describe '.track_greatest' do
diff --git a/spec/models/issue/metrics_spec.rb b/spec/models/issue/metrics_spec.rb
index 0d0628277a6..dc22d26e2f9 100644
--- a/spec/models/issue/metrics_spec.rb
+++ b/spec/models/issue/metrics_spec.rb
@@ -23,7 +23,7 @@ describe Issue::Metrics do
describe '.with_first_mention_not_earlier_than' do
subject(:scope) { described_class.with_first_mention_not_earlier_than(timestamp) }
- let(:timestamp) { DateTime.now }
+ let(:timestamp) { DateTime.current }
it 'returns metrics without mentioning in commit or with mentioning after given timestamp' do
issue1 = create(:issue)
@@ -37,7 +37,7 @@ describe Issue::Metrics do
describe "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.now
+ time = Time.current
Timecop.freeze(time) { subject.update(milestone: create(:milestone, project: project)) }
metrics = subject.metrics
@@ -46,7 +46,7 @@ describe Issue::Metrics do
end
it "does not record the second time an issue is associated with a milestone" do
- time = Time.now
+ time = Time.current
Timecop.freeze(time) { subject.update(milestone: create(:milestone, project: project)) }
Timecop.freeze(time + 2.hours) { subject.update(milestone: nil) }
Timecop.freeze(time + 6.hours) { subject.update(milestone: create(:milestone, project: project)) }
@@ -60,7 +60,7 @@ describe Issue::Metrics do
context "list labels" do
it "records the first time an issue is associated with a list label" do
list_label = create(:list).label
- time = Time.now
+ time = Time.current
Timecop.freeze(time) { subject.update(label_ids: [list_label.id]) }
metrics = subject.metrics
@@ -69,7 +69,7 @@ describe Issue::Metrics do
end
it "does not record the second time an issue is associated with a list label" do
- time = Time.now
+ time = Time.current
first_list_label = create(:list).label
Timecop.freeze(time) { subject.update(label_ids: [first_list_label.id]) }
second_list_label = create(:list).label
diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb
index dd5ff3dbdde..291cccd72db 100644
--- a/spec/models/issue_spec.rb
+++ b/spec/models/issue_spec.rb
@@ -21,6 +21,9 @@ describe Issue do
it { is_expected.to have_one(:alert_management_alert) }
it { is_expected.to have_many(:resource_milestone_events) }
it { is_expected.to have_many(:resource_state_events) }
+ it { is_expected.to have_and_belong_to_many(:prometheus_alert_events) }
+ it { is_expected.to have_and_belong_to_many(:self_managed_prometheus_alert_events) }
+ it { is_expected.to have_many(:prometheus_alerts) }
describe 'versions.most_recent' do
it 'returns the most recent version' do
@@ -176,7 +179,7 @@ describe Issue do
describe '#close' do
subject(:issue) { create(:issue, state: 'opened') }
- it 'sets closed_at to Time.now when an issue is closed' do
+ it 'sets closed_at to Time.current when an issue is closed' do
expect { issue.close }.to change { issue.closed_at }.from(nil)
end
@@ -186,11 +189,40 @@ describe Issue do
expect { issue.close }.to change { issue.state_id }.from(open_state).to(closed_state)
end
+
+ context 'when there is an associated Alert Management Alert' do
+ context 'when alert can be resolved' do
+ let!(:alert) { create(:alert_management_alert, project: issue.project, issue: issue) }
+
+ it 'resolves an alert' do
+ expect { issue.close }.to change { alert.reload.resolved? }.to(true)
+ end
+ end
+
+ context 'when alert cannot be resolved' do
+ let!(:alert) { create(:alert_management_alert, :with_validation_errors, project: issue.project, issue: issue) }
+
+ before do
+ allow(Gitlab::AppLogger).to receive(:warn).and_call_original
+ end
+
+ it 'writes a warning into the log' do
+ issue.close
+
+ expect(Gitlab::AppLogger).to have_received(:warn).with(
+ message: 'Cannot resolve an associated Alert Management alert',
+ issue_id: issue.id,
+ alert_id: alert.id,
+ alert_errors: { hosts: ['hosts array is over 255 chars'] }
+ )
+ end
+ end
+ end
end
describe '#reopen' do
let(:user) { create(:user) }
- let(:issue) { create(:issue, state: 'closed', closed_at: Time.now, closed_by: user) }
+ let(:issue) { create(:issue, state: 'closed', closed_at: Time.current, closed_by: user) }
it 'sets closed_at to nil when an issue is reopend' do
expect { issue.reopen }.to change { issue.closed_at }.to(nil)
@@ -994,7 +1026,7 @@ describe Issue do
it_behaves_like 'versioned description'
describe "#previous_updated_at" do
- let_it_be(:updated_at) { Time.new(2012, 01, 06) }
+ let_it_be(:updated_at) { Time.zone.local(2012, 01, 06) }
let_it_be(:issue) { create(:issue, updated_at: updated_at) }
it 'returns updated_at value if updated_at did not change at all' do
@@ -1010,15 +1042,15 @@ describe Issue do
end
it 'returns updated_at value if previous updated_at value is not present' do
- allow(issue).to receive(:previous_changes).and_return({ 'updated_at' => [nil, Time.new(2013, 02, 06)] })
+ allow(issue).to receive(:previous_changes).and_return({ 'updated_at' => [nil, Time.zone.local(2013, 02, 06)] })
expect(issue.previous_updated_at).to eq(updated_at)
end
it 'returns previous updated_at when present' do
- allow(issue).to receive(:previous_changes).and_return({ 'updated_at' => [Time.new(2013, 02, 06), Time.new(2013, 03, 06)] })
+ allow(issue).to receive(:previous_changes).and_return({ 'updated_at' => [Time.zone.local(2013, 02, 06), Time.zone.local(2013, 03, 06)] })
- expect(issue.previous_updated_at).to eq(Time.new(2013, 02, 06))
+ expect(issue.previous_updated_at).to eq(Time.zone.local(2013, 02, 06))
end
end
@@ -1085,4 +1117,15 @@ describe Issue do
expect(subject).not_to include(labeled_issue)
end
end
+
+ describe 'banzai_render_context' do
+ let(:project) { build(:project_empty_repo) }
+ let(:issue) { build :issue, project: project }
+
+ subject(:context) { issue.banzai_render_context(:title) }
+
+ it 'sets the label_url_method in the context' do
+ expect(context[:label_url_method]).to eq(:project_issues_url)
+ end
+ end
end
diff --git a/spec/models/iteration_spec.rb b/spec/models/iteration_spec.rb
index e5b7b746639..ae14adf9106 100644
--- a/spec/models/iteration_spec.rb
+++ b/spec/models/iteration_spec.rb
@@ -6,10 +6,6 @@ describe Iteration do
let_it_be(:project) { create(:project) }
let_it_be(:group) { create(:group) }
- it_behaves_like 'a timebox', :iteration do
- let(:timebox_table_name) { described_class.table_name.to_sym }
- end
-
describe "#iid" do
it "is properly scoped on project and group" do
iteration1 = create(:iteration, project: project)
@@ -62,7 +58,7 @@ describe Iteration do
end
context 'when end_date is in range' do
- let(:start_date) { Time.now }
+ let(:start_date) { Time.current }
let(:due_date) { 6.days.from_now }
it 'is not valid' do
@@ -94,7 +90,7 @@ describe Iteration do
describe '#future_date' do
context 'when dates are in the future' do
- let(:start_date) { Time.now }
+ let(:start_date) { Time.current }
let(:due_date) { 1.week.from_now }
it { is_expected.to be_valid }
@@ -111,7 +107,7 @@ describe Iteration do
end
context 'when due_date is in the past' do
- let(:start_date) { Time.now }
+ let(:start_date) { Time.current }
let(:due_date) { 1.week.ago }
it 'is not valid' do
@@ -122,7 +118,7 @@ describe Iteration do
context 'when start_date is over 500 years in the future' do
let(:start_date) { 501.years.from_now }
- let(:due_date) { Time.now }
+ let(:due_date) { Time.current }
it 'is not valid' do
expect(subject).not_to be_valid
@@ -131,7 +127,7 @@ describe Iteration do
end
context 'when due_date is over 500 years in the future' do
- let(:start_date) { Time.now }
+ let(:start_date) { Time.current }
let(:due_date) { 501.years.from_now }
it 'is not valid' do
@@ -143,7 +139,7 @@ describe Iteration do
end
describe '.within_timeframe' do
- let_it_be(:now) { Time.now }
+ let_it_be(:now) { Time.current }
let_it_be(:project) { create(:project, :empty_repo) }
let_it_be(:iteration_1) { create(:iteration, project: project, start_date: now, due_date: 1.day.from_now) }
let_it_be(:iteration_2) { create(:iteration, project: project, start_date: 2.days.from_now, due_date: 3.days.from_now) }
diff --git a/spec/models/jira_import_state_spec.rb b/spec/models/jira_import_state_spec.rb
index 99f9e035205..d2535636c63 100644
--- a/spec/models/jira_import_state_spec.rb
+++ b/spec/models/jira_import_state_spec.rb
@@ -124,7 +124,7 @@ describe JiraImportState do
jira_import.schedule
expect(jira_import.jid).to eq('some-job-id')
- expect(jira_import.scheduled_at).to be_within(1.second).of(Time.now)
+ expect(jira_import.scheduled_at).to be_within(1.second).of(Time.current)
end
end
@@ -163,4 +163,39 @@ describe JiraImportState do
end
end
end
+
+ context 'ensure error_message size on save' do
+ let_it_be(:project) { create(:project) }
+
+ before do
+ stub_const('JiraImportState::ERROR_MESSAGE_SIZE', 10)
+ end
+
+ context 'when jira import has no error_message' do
+ let(:jira_import) { build(:jira_import_state, project: project)}
+
+ it 'does not run the callback', :aggregate_failures do
+ expect { jira_import.save }.to change { JiraImportState.count }.by(1)
+ expect(jira_import.reload.error_message).to be_nil
+ end
+ end
+
+ context 'when jira import error_message does not exceed the limit' do
+ let(:jira_import) { build(:jira_import_state, project: project, error_message: 'error')}
+
+ it 'does not run the callback', :aggregate_failures do
+ expect { jira_import.save }.to change { JiraImportState.count }.by(1)
+ expect(jira_import.reload.error_message).to eq('error')
+ end
+ end
+
+ context 'when error_message exceeds limit' do
+ let(:jira_import) { build(:jira_import_state, project: project, error_message: 'error message longer than the limit')}
+
+ it 'truncates error_message to the limit', :aggregate_failures do
+ expect { jira_import.save! }.to change { JiraImportState.count }.by(1)
+ expect(jira_import.reload.error_message.size).to eq 10
+ end
+ end
+ end
end
diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb
index a8d864ad3f0..7c40bb24b56 100644
--- a/spec/models/member_spec.rb
+++ b/spec/models/member_spec.rb
@@ -494,7 +494,7 @@ describe Member do
end
describe '#accept_request' do
- let(:member) { create(:project_member, requested_at: Time.now.utc) }
+ let(:member) { create(:project_member, requested_at: Time.current.utc) }
it { expect(member.accept_request).to be_truthy }
@@ -518,14 +518,14 @@ describe Member do
end
describe '#request?' do
- subject { create(:project_member, requested_at: Time.now.utc) }
+ subject { create(:project_member, requested_at: Time.current.utc) }
it { is_expected.to be_request }
end
describe '#pending?' do
let(:invited_member) { create(:project_member, invite_email: "user@example.com", user: nil) }
- let(:requester) { create(:project_member, requested_at: Time.now.utc) }
+ let(:requester) { create(:project_member, requested_at: Time.current.utc) }
it { expect(invited_member).to be_invite }
it { expect(requester).to be_pending }
diff --git a/spec/models/members/group_member_spec.rb b/spec/models/members/group_member_spec.rb
index 9b5cce1aebf..fdb71b7ec7d 100644
--- a/spec/models/members/group_member_spec.rb
+++ b/spec/models/members/group_member_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
describe GroupMember do
context 'scopes' do
- describe '.count_users_by_group_id' do
+ shared_examples '.count_users_by_group_id' do
it 'counts users by group ID' do
user_1 = create(:user)
user_2 = create(:user)
@@ -20,6 +20,36 @@ describe GroupMember do
end
end
+ describe '.count_users_by_group_id with optimized_count_users_by_group_id feature flag on' do
+ before do
+ stub_feature_flags(optimized_count_users_by_group_id: true)
+ end
+
+ it_behaves_like '.count_users_by_group_id'
+
+ it 'does not JOIN users' do
+ scope = described_class.all
+ expect(scope).not_to receive(:joins).with(:user)
+
+ scope.count_users_by_group_id
+ end
+ end
+
+ describe '.count_users_by_group_id with optimized_count_users_by_group_id feature flag off' do
+ before do
+ stub_feature_flags(optimized_count_users_by_group_id: false)
+ end
+
+ it_behaves_like '.count_users_by_group_id'
+
+ it 'does JOIN users' do
+ scope = described_class.all
+ expect(scope).to receive(:joins).with(:user).and_call_original
+
+ scope.count_users_by_group_id
+ end
+ end
+
describe '.of_ldap_type' do
it 'returns ldap type users' do
group_member = create(:group_member, :ldap)
diff --git a/spec/models/members/project_member_spec.rb b/spec/models/members/project_member_spec.rb
index 79c39b81196..fdb9457b211 100644
--- a/spec/models/members/project_member_spec.rb
+++ b/spec/models/members/project_member_spec.rb
@@ -44,14 +44,14 @@ describe ProjectMember do
let(:maintainer) { create(:project_member, project: project) }
it "creates an expired event when left due to expiry" do
- expired = create(:project_member, project: project, expires_at: Time.now - 6.days)
+ expired = create(:project_member, project: project, expires_at: Time.current - 6.days)
expired.destroy
- expect(Event.recent.first.action).to eq(Event::EXPIRED)
+ expect(Event.recent.first).to be_expired_action
end
it "creates a left event when left due to leave" do
maintainer.destroy
- expect(Event.recent.first.action).to eq(Event::LEFT)
+ expect(Event.recent.first).to be_left_action
end
end
diff --git a/spec/models/merge_request_diff_commit_spec.rb b/spec/models/merge_request_diff_commit_spec.rb
index 8b51c6fae08..62430b08c5c 100644
--- a/spec/models/merge_request_diff_commit_spec.rb
+++ b/spec/models/merge_request_diff_commit_spec.rb
@@ -73,7 +73,7 @@ describe MergeRequestDiffCommit do
# This commit's date is "Sun Aug 17 07:12:55 292278994 +0000"
[project.commit('ba3343bc4fa403a8dfbfcab7fc1a8c29ee34bd69')]
end
- let(:timestamp) { Time.at((1 << 31) - 1) }
+ let(:timestamp) { Time.zone.at((1 << 31) - 1) }
let(:rows) do
[{
"message": "Weird commit date\n",
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index fc4590f7b22..c70ddac5da6 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -22,6 +22,8 @@ describe MergeRequest do
it { is_expected.to belong_to(:iteration) }
it { is_expected.to have_many(:resource_milestone_events) }
it { is_expected.to have_many(:resource_state_events) }
+ it { is_expected.to have_many(:draft_notes) }
+ it { is_expected.to have_many(:reviews).inverse_of(:merge_request) }
context 'for forks' do
let!(:project) { create(:project) }
@@ -721,11 +723,15 @@ describe MergeRequest do
end
describe '#note_positions_for_paths' do
+ let(:user) { create(:user) }
let(:merge_request) { create(:merge_request, :with_diffs) }
let(:project) { merge_request.project }
let!(:diff_note) do
create(:diff_note_on_merge_request, project: project, noteable: merge_request)
end
+ let!(:draft_note) do
+ create(:draft_note_on_text_diff, author: user, merge_request: merge_request)
+ end
let(:file_paths) { merge_request.diffs.diff_files.map(&:file_path) }
@@ -758,6 +764,26 @@ describe MergeRequest do
expect(subject.to_a).to be_empty
end
end
+
+ context 'when user is given' do
+ subject do
+ merge_request.note_positions_for_paths(file_paths, user)
+ end
+
+ it 'returns notes and draft notes positions' do
+ expect(subject).to match_array([draft_note.position, diff_note.position])
+ end
+ end
+
+ context 'when user is not given' do
+ subject do
+ merge_request.note_positions_for_paths(file_paths)
+ end
+
+ it 'returns notes positions' do
+ expect(subject).to match_array([diff_note.position])
+ end
+ end
end
describe '#discussions_diffs' do
@@ -1625,14 +1651,6 @@ describe MergeRequest do
let(:merge_request) { create(:merge_request, :with_accessibility_reports, source_project: project) }
it { is_expected.to be_truthy }
-
- context 'when feature flag is disabled' do
- before do
- stub_feature_flags(accessibility_report_view: false)
- end
-
- it { is_expected.to be_falsey }
- end
end
context 'when head pipeline does not have accessibility reports' do
@@ -2018,7 +2036,7 @@ describe MergeRequest do
describe '#can_be_reverted?' do
context 'when there is no merge_commit for the MR' do
before do
- subject.metrics.update!(merged_at: Time.now.utc)
+ subject.metrics.update!(merged_at: Time.current.utc)
end
it 'returns false' do
@@ -2157,7 +2175,34 @@ describe MergeRequest do
end
end
- context 'when merging note is persisted, but no metrics or merge event exists' do
+ context 'when state event tracking is disabled' do
+ before do
+ stub_feature_flags(track_resource_state_change_events: false)
+ end
+
+ context 'when merging note is persisted, but no metrics or merge event exists' do
+ let(:user) { create(:user) }
+ let(:merge_request) { create(:merge_request, :merged) }
+
+ before do
+ merge_request.metrics.destroy!
+
+ SystemNoteService.change_status(merge_request,
+ merge_request.target_project,
+ user,
+ merge_request.state, nil)
+ end
+
+ it 'returns merging note creation date' do
+ expect(merge_request.reload.metrics).to be_nil
+ expect(merge_request.merge_event).to be_nil
+ expect(merge_request.notes.count).to eq(1)
+ expect(merge_request.merged_at).to eq(merge_request.notes.first.created_at)
+ end
+ end
+ end
+
+ context 'when state event tracking is enabled' do
let(:user) { create(:user) }
let(:merge_request) { create(:merge_request, :merged) }
@@ -2170,11 +2215,8 @@ describe MergeRequest do
merge_request.state, nil)
end
- it 'returns merging note creation date' do
- expect(merge_request.reload.metrics).to be_nil
- expect(merge_request.merge_event).to be_nil
- expect(merge_request.notes.count).to eq(1)
- expect(merge_request.merged_at).to eq(merge_request.notes.first.created_at)
+ it 'does not create a system note' do
+ expect(merge_request.notes).to be_empty
end
end
end
@@ -2327,24 +2369,10 @@ describe MergeRequest do
end
context 'when async is true' do
- context 'and async_merge_request_check_mergeability feature flag is enabled' do
- it 'executes MergeabilityCheckService asynchronously' do
- expect(mergeability_service).to receive(:async_execute)
-
- subject.check_mergeability(async: true)
- end
- end
-
- context 'and async_merge_request_check_mergeability feature flag is disabled' do
- before do
- stub_feature_flags(async_merge_request_check_mergeability: false)
- end
-
- it 'executes MergeabilityCheckService' do
- expect(mergeability_service).to receive(:execute)
+ it 'executes MergeabilityCheckService asynchronously' do
+ expect(mergeability_service).to receive(:async_execute)
- subject.check_mergeability(async: true)
- end
+ subject.check_mergeability(async: true)
end
end
end
@@ -2489,12 +2517,13 @@ describe MergeRequest do
end
describe '#mergeable_ci_state?' do
- let(:project) { create(:project, only_allow_merge_if_pipeline_succeeds: true) }
let(:pipeline) { create(:ci_empty_pipeline) }
- subject { build(:merge_request, target_project: project) }
-
context 'when it is only allowed to merge when build is green' do
+ let(:project) { create(:project, only_allow_merge_if_pipeline_succeeds: true) }
+
+ subject { build(:merge_request, target_project: project) }
+
context 'and a failed pipeline is associated' do
before do
pipeline.update(status: 'failed', sha: subject.diff_head_sha)
@@ -2516,7 +2545,7 @@ describe MergeRequest do
context 'and a skipped pipeline is associated' do
before do
pipeline.update(status: 'skipped', sha: subject.diff_head_sha)
- allow(subject).to receive(:head_pipeline) { pipeline }
+ allow(subject).to receive(:head_pipeline).and_return(pipeline)
end
it { expect(subject.mergeable_ci_state?).to be_falsey }
@@ -2524,7 +2553,48 @@ describe MergeRequest do
context 'when no pipeline is associated' do
before do
- allow(subject).to receive(:head_pipeline) { nil }
+ allow(subject).to receive(:head_pipeline).and_return(nil)
+ end
+
+ it { expect(subject.mergeable_ci_state?).to be_falsey }
+ end
+ end
+
+ context 'when it is only allowed to merge when build is green or skipped' do
+ let(:project) { create(:project, only_allow_merge_if_pipeline_succeeds: true, allow_merge_on_skipped_pipeline: true) }
+
+ subject { build(:merge_request, target_project: project) }
+
+ context 'and a failed pipeline is associated' do
+ before do
+ pipeline.update!(status: 'failed', sha: subject.diff_head_sha)
+ allow(subject).to receive(:head_pipeline).and_return(pipeline)
+ end
+
+ it { expect(subject.mergeable_ci_state?).to be_falsey }
+ end
+
+ context 'and a successful pipeline is associated' do
+ before do
+ pipeline.update!(status: 'success', sha: subject.diff_head_sha)
+ allow(subject).to receive(:head_pipeline).and_return(pipeline)
+ end
+
+ it { expect(subject.mergeable_ci_state?).to be_truthy }
+ end
+
+ context 'and a skipped pipeline is associated' do
+ before do
+ pipeline.update!(status: 'skipped', sha: subject.diff_head_sha)
+ allow(subject).to receive(:head_pipeline).and_return(pipeline)
+ end
+
+ it { expect(subject.mergeable_ci_state?).to be_truthy }
+ end
+
+ context 'when no pipeline is associated' do
+ before do
+ allow(subject).to receive(:head_pipeline).and_return(nil)
end
it { expect(subject.mergeable_ci_state?).to be_falsey }
@@ -2532,7 +2602,9 @@ describe MergeRequest do
end
context 'when merges are not restricted to green builds' do
- subject { build(:merge_request, target_project: create(:project, only_allow_merge_if_pipeline_succeeds: false)) }
+ let(:project) { create(:project, only_allow_merge_if_pipeline_succeeds: false) }
+
+ subject { build(:merge_request, target_project: project) }
context 'and a failed pipeline is associated' do
before do
@@ -2550,6 +2622,23 @@ describe MergeRequest do
it { expect(subject.mergeable_ci_state?).to be_truthy }
end
+
+ context 'and a skipped pipeline is associated' do
+ before do
+ pipeline.update!(status: 'skipped', sha: subject.diff_head_sha)
+ allow(subject).to receive(:head_pipeline).and_return(pipeline)
+ end
+
+ it { expect(subject.mergeable_ci_state?).to be_truthy }
+ end
+
+ context 'when no pipeline is associated' do
+ before do
+ allow(subject).to receive(:head_pipeline).and_return(nil)
+ end
+
+ it { expect(subject.mergeable_ci_state?).to be_truthy }
+ end
end
end
@@ -2581,7 +2670,7 @@ describe MergeRequest do
context 'with no discussions' do
before do
- merge_request.notes.destroy_all # rubocop: disable DestroyAll
+ merge_request.notes.destroy_all # rubocop: disable Cop/DestroyAll
end
it 'returns true' do
@@ -3876,4 +3965,15 @@ describe MergeRequest do
expect(count).to eq(0)
end
end
+
+ describe 'banzai_render_context' do
+ let(:project) { build(:project_empty_repo) }
+ let(:merge_request) { build :merge_request, target_project: project, source_project: project }
+
+ subject(:context) { merge_request.banzai_render_context(:title) }
+
+ it 'sets the label_url_method in the context' do
+ expect(context[:label_url_method]).to eq(:project_merge_requests_url)
+ end
+ end
end
diff --git a/spec/models/metrics/dashboard/annotation_spec.rb b/spec/models/metrics/dashboard/annotation_spec.rb
index f7fd7ded7e6..3cba31ffdfe 100644
--- a/spec/models/metrics/dashboard/annotation_spec.rb
+++ b/spec/models/metrics/dashboard/annotation_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
describe Metrics::Dashboard::Annotation do
+ using RSpec::Parameterized::TableSyntax
+
describe 'associations' do
it { is_expected.to belong_to(:environment).inverse_of(:metrics_dashboard_annotations) }
it { is_expected.to belong_to(:cluster).class_name('Clusters::Cluster').inverse_of(:metrics_dashboard_annotations) }
@@ -28,6 +30,26 @@ describe Metrics::Dashboard::Annotation do
end
end
+ context 'ending_at_after_starting_at' do
+ where(:starting_at, :ending_at, :valid?, :message) do
+ 2.days.ago.beginning_of_day | 1.day.ago.beginning_of_day | true | nil
+ 1.day.ago.beginning_of_day | nil | true | nil
+ 1.day.ago.beginning_of_day | 1.day.ago.beginning_of_day | true | nil
+ 1.day.ago.beginning_of_day | 2.days.ago.beginning_of_day | false | /Ending at can't be before starting_at time/
+ nil | 2.days.ago.beginning_of_day | false | /Starting at can't be blank/ # validation is covered by other method, be we need to assure, that ending_at_after_starting_at will not break with nil as starting_at
+ nil | nil | false | /Starting at can't be blank/ # validation is covered by other method, be we need to assure, that ending_at_after_starting_at will not break with nil as starting_at
+ end
+
+ with_them do
+ subject(:annotation) { build(:metrics_dashboard_annotation, starting_at: starting_at, ending_at: ending_at) }
+
+ it do
+ expect(annotation.valid?).to be(valid?)
+ expect(annotation.errors.full_messages).to include(message) if message
+ end
+ end
+ end
+
context 'environments annotation' do
subject { build(:metrics_dashboard_annotation) }
@@ -75,5 +97,16 @@ describe Metrics::Dashboard::Annotation do
expect(described_class.for_dashboard('other_dashboard.yml')).to match_array [other_dashboard_annotation]
end
end
+
+ describe '#ending_before' do
+ it 'returns annotations only for appointed dashboard' do
+ Timecop.freeze do
+ twelve_minutes_old_annotation = create(:metrics_dashboard_annotation, starting_at: 15.minutes.ago, ending_at: 12.minutes.ago)
+ create(:metrics_dashboard_annotation, starting_at: 15.minutes.ago, ending_at: 11.minutes.ago)
+
+ expect(described_class.ending_before(11.minutes.ago)).to match_array [fifteen_minutes_old_annotation, twelve_minutes_old_annotation]
+ end
+ end
+ end
end
end
diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb
index e51108947a7..33f84da27f6 100644
--- a/spec/models/milestone_spec.rb
+++ b/spec/models/milestone_spec.rb
@@ -81,7 +81,7 @@ describe Milestone do
end
it_behaves_like 'within_timeframe scope' do
- let_it_be(:now) { Time.now }
+ let_it_be(:now) { Time.current }
let_it_be(:project) { create(:project, :empty_repo) }
let_it_be(:resource_1) { create(:milestone, project: project, start_date: now - 1.day, due_date: now + 1.day) }
let_it_be(:resource_2) { create(:milestone, project: project, start_date: now + 2.days, due_date: now + 3.days) }
@@ -130,7 +130,7 @@ describe Milestone do
describe '#upcoming?' do
it 'returns true when start_date is in the future' do
- milestone = build(:milestone, start_date: Time.now + 1.month)
+ milestone = build(:milestone, start_date: Time.current + 1.month)
expect(milestone.upcoming?).to be_truthy
end
@@ -225,70 +225,88 @@ describe Milestone do
end
end
- describe '#for_projects_and_groups' do
- let(:project) { create(:project) }
- let(:project_other) { create(:project) }
- let(:group) { create(:group) }
- let(:group_other) { create(:group) }
+ shared_examples '#for_projects_and_groups' do
+ describe '#for_projects_and_groups' do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:project_other) { create(:project) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:group_other) { create(:group) }
+
+ before(:all) do
+ create(:milestone, project: project)
+ create(:milestone, project: project_other)
+ create(:milestone, group: group)
+ create(:milestone, group: group_other)
+ end
- before do
- create(:milestone, project: project)
- create(:milestone, project: project_other)
- create(:milestone, group: group)
- create(:milestone, group: group_other)
- end
+ subject { described_class.for_projects_and_groups(projects, groups) }
+
+ shared_examples 'filters by projects and groups' do
+ it 'returns milestones filtered by project' do
+ milestones = described_class.for_projects_and_groups(projects, [])
- subject { described_class.for_projects_and_groups(projects, groups) }
+ expect(milestones.count).to eq(1)
+ expect(milestones.first.project_id).to eq(project.id)
+ end
+
+ it 'returns milestones filtered by group' do
+ milestones = described_class.for_projects_and_groups([], groups)
+
+ expect(milestones.count).to eq(1)
+ expect(milestones.first.group_id).to eq(group.id)
+ end
- shared_examples 'filters by projects and groups' do
- it 'returns milestones filtered by project' do
- milestones = described_class.for_projects_and_groups(projects, [])
+ it 'returns milestones filtered by both project and group' do
+ milestones = described_class.for_projects_and_groups(projects, groups)
- expect(milestones.count).to eq(1)
- expect(milestones.first.project_id).to eq(project.id)
+ expect(milestones.count).to eq(2)
+ expect(milestones).to contain_exactly(project.milestones.first, group.milestones.first)
+ end
end
- it 'returns milestones filtered by group' do
- milestones = described_class.for_projects_and_groups([], groups)
+ context 'ids as params' do
+ let(:projects) { [project.id] }
+ let(:groups) { [group.id] }
- expect(milestones.count).to eq(1)
- expect(milestones.first.group_id).to eq(group.id)
+ it_behaves_like 'filters by projects and groups'
end
- it 'returns milestones filtered by both project and group' do
- milestones = described_class.for_projects_and_groups(projects, groups)
+ context 'relations as params' do
+ let(:projects) { Project.where(id: project.id).select(:id) }
+ let(:groups) { Group.where(id: group.id).select(:id) }
- expect(milestones.count).to eq(2)
- expect(milestones).to contain_exactly(project.milestones.first, group.milestones.first)
+ it_behaves_like 'filters by projects and groups'
end
- end
- context 'ids as params' do
- let(:projects) { [project.id] }
- let(:groups) { [group.id] }
+ context 'objects as params' do
+ let(:projects) { [project] }
+ let(:groups) { [group] }
- it_behaves_like 'filters by projects and groups'
- end
+ it_behaves_like 'filters by projects and groups'
+ end
- context 'relations as params' do
- let(:projects) { Project.where(id: project.id).select(:id) }
- let(:groups) { Group.where(id: group.id).select(:id) }
+ it 'returns no records if projects and groups are nil' do
+ milestones = described_class.for_projects_and_groups(nil, nil)
- it_behaves_like 'filters by projects and groups'
+ expect(milestones).to be_empty
+ end
end
+ end
- context 'objects as params' do
- let(:projects) { [project] }
- let(:groups) { [group] }
-
- it_behaves_like 'filters by projects and groups'
+ context 'when `optimized_timebox_queries` feature flag is enabled' do
+ before do
+ stub_feature_flags(optimized_timebox_queries: true)
end
- it 'returns no records if projects and groups are nil' do
- milestones = described_class.for_projects_and_groups(nil, nil)
+ it_behaves_like '#for_projects_and_groups'
+ end
- expect(milestones).to be_empty
+ context 'when `optimized_timebox_queries` feature flag is disabled' do
+ before do
+ stub_feature_flags(optimized_timebox_queries: false)
end
+
+ it_behaves_like '#for_projects_and_groups'
end
describe '.upcoming_ids' do
@@ -297,30 +315,30 @@ describe Milestone do
let(:group_3) { create(:group) }
let(:groups) { [group_1, group_2, group_3] }
- let!(:past_milestone_group_1) { create(:milestone, group: group_1, due_date: Time.now - 1.day) }
- let!(:current_milestone_group_1) { create(:milestone, group: group_1, due_date: Time.now + 1.day) }
- let!(:future_milestone_group_1) { create(:milestone, group: group_1, due_date: Time.now + 2.days) }
+ let!(:past_milestone_group_1) { create(:milestone, group: group_1, due_date: Time.current - 1.day) }
+ let!(:current_milestone_group_1) { create(:milestone, group: group_1, due_date: Time.current + 1.day) }
+ let!(:future_milestone_group_1) { create(:milestone, group: group_1, due_date: Time.current + 2.days) }
- let!(:past_milestone_group_2) { create(:milestone, group: group_2, due_date: Time.now - 1.day) }
- let!(:closed_milestone_group_2) { create(:milestone, :closed, group: group_2, due_date: Time.now + 1.day) }
- let!(:current_milestone_group_2) { create(:milestone, group: group_2, due_date: Time.now + 2.days) }
+ let!(:past_milestone_group_2) { create(:milestone, group: group_2, due_date: Time.current - 1.day) }
+ let!(:closed_milestone_group_2) { create(:milestone, :closed, group: group_2, due_date: Time.current + 1.day) }
+ let!(:current_milestone_group_2) { create(:milestone, group: group_2, due_date: Time.current + 2.days) }
- let!(:past_milestone_group_3) { create(:milestone, group: group_3, due_date: Time.now - 1.day) }
+ let!(:past_milestone_group_3) { create(:milestone, group: group_3, due_date: Time.current - 1.day) }
let(:project_1) { create(:project) }
let(:project_2) { create(:project) }
let(:project_3) { create(:project) }
let(:projects) { [project_1, project_2, project_3] }
- let!(:past_milestone_project_1) { create(:milestone, project: project_1, due_date: Time.now - 1.day) }
- let!(:current_milestone_project_1) { create(:milestone, project: project_1, due_date: Time.now + 1.day) }
- let!(:future_milestone_project_1) { create(:milestone, project: project_1, due_date: Time.now + 2.days) }
+ let!(:past_milestone_project_1) { create(:milestone, project: project_1, due_date: Time.current - 1.day) }
+ let!(:current_milestone_project_1) { create(:milestone, project: project_1, due_date: Time.current + 1.day) }
+ let!(:future_milestone_project_1) { create(:milestone, project: project_1, due_date: Time.current + 2.days) }
- let!(:past_milestone_project_2) { create(:milestone, project: project_2, due_date: Time.now - 1.day) }
- let!(:closed_milestone_project_2) { create(:milestone, :closed, project: project_2, due_date: Time.now + 1.day) }
- let!(:current_milestone_project_2) { create(:milestone, project: project_2, due_date: Time.now + 2.days) }
+ let!(:past_milestone_project_2) { create(:milestone, project: project_2, due_date: Time.current - 1.day) }
+ let!(:closed_milestone_project_2) { create(:milestone, :closed, project: project_2, due_date: Time.current + 1.day) }
+ let!(:current_milestone_project_2) { create(:milestone, project: project_2, due_date: Time.current + 2.days) }
- let!(:past_milestone_project_3) { create(:milestone, project: project_3, due_date: Time.now - 1.day) }
+ let!(:past_milestone_project_3) { create(:milestone, project: project_3, due_date: Time.current - 1.day) }
let(:milestone_ids) { described_class.upcoming_ids(projects, groups).map(&:id) }
@@ -498,4 +516,23 @@ describe Milestone do
end
end
end
+
+ describe '#subgroup_milestone' do
+ context 'parent is subgroup' do
+ it 'returns true' do
+ group = create(:group)
+ subgroup = create(:group, :private, parent: group)
+
+ expect(build(:milestone, group: subgroup).subgroup_milestone?).to eq(true)
+ end
+ end
+
+ context 'parent is not subgroup' do
+ it 'returns false' do
+ group = create(:group)
+
+ expect(build(:milestone, group: group).subgroup_milestone?).to eq(false)
+ end
+ end
+ end
end
diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb
index 6dd295ca915..af3fdcfaa2e 100644
--- a/spec/models/note_spec.rb
+++ b/spec/models/note_spec.rb
@@ -11,6 +11,7 @@ describe Note do
it { is_expected.to belong_to(:author).class_name('User') }
it { is_expected.to have_many(:todos) }
+ it { is_expected.to belong_to(:review).inverse_of(:notes) }
end
describe 'modules' do
@@ -285,7 +286,7 @@ describe Note do
end
describe "edited?" do
- let(:note) { build(:note, updated_by_id: nil, created_at: Time.now, updated_at: Time.now + 5.hours) }
+ let(:note) { build(:note, updated_by_id: nil, created_at: Time.current, updated_at: Time.current + 5.hours) }
context "with updated_by" do
it "returns true" do
@@ -304,11 +305,22 @@ describe Note do
describe '#confidential?' do
context 'when note is not confidential' do
- it 'is true when a noteable is confidential' do
- issue = create(:issue, :confidential)
- note = build(:note, noteable: issue, project: issue.project)
+ context 'when include_noteable is set to true' do
+ it 'is true when a noteable is confidential ' do
+ issue = create(:issue, :confidential)
+ note = build(:note, noteable: issue, project: issue.project)
- expect(note.confidential?).to be_truthy
+ expect(note.confidential?(include_noteable: true)).to be_truthy
+ end
+ end
+
+ context 'when include_noteable is not set to true' do
+ it 'is false when a noteable is confidential ' do
+ issue = create(:issue, :confidential)
+ note = build(:note, noteable: issue, project: issue.project)
+
+ expect(note.confidential?).to be_falsey
+ end
end
it 'is false when a noteable is not confidential' do
@@ -318,7 +330,7 @@ describe Note do
expect(note.confidential?).to be_falsy
end
- it "is falsey when noteable can't be confidential" do
+ it "is false when noteable can't be confidential" do
commit_note = build(:note_on_commit)
expect(commit_note.confidential?).to be_falsy
@@ -817,6 +829,10 @@ describe Note do
it 'returns commit for a commit note' do
expect(build(:note_on_commit).noteable_ability_name).to eq('commit')
end
+
+ it 'returns alert_management_alert for an alert note' do
+ expect(build(:note_on_alert).noteable_ability_name).to eq('alert_management_alert')
+ end
end
describe '#cache_markdown_field' do
@@ -1352,4 +1368,28 @@ describe Note do
end
end
end
+
+ describe 'banzai_render_context' do
+ let(:project) { build(:project_empty_repo) }
+
+ context 'when noteable is a merge request' do
+ let(:noteable) { build :merge_request, target_project: project, source_project: project }
+
+ subject(:context) { noteable.banzai_render_context(:title) }
+
+ it 'sets the label_url_method in the context' do
+ expect(context[:label_url_method]).to eq(:project_merge_requests_url)
+ end
+ end
+
+ context 'when noteable is an issue' do
+ let(:noteable) { build :issue, project: project }
+
+ subject(:context) { noteable.banzai_render_context(:title) }
+
+ it 'sets the label_url_method in the context' do
+ expect(context[:label_url_method]).to eq(:project_issues_url)
+ end
+ end
+ end
end
diff --git a/spec/models/pages_domain_spec.rb b/spec/models/pages_domain_spec.rb
index 54747ddf525..fc7694530d0 100644
--- a/spec/models/pages_domain_spec.rb
+++ b/spec/models/pages_domain_spec.rb
@@ -97,8 +97,8 @@ describe PagesDomain do
it 'saves validity time' do
domain.save
- expect(domain.certificate_valid_not_before).to be_like_time(Time.parse("2020-03-16 14:20:34 UTC"))
- expect(domain.certificate_valid_not_after).to be_like_time(Time.parse("2220-01-28 14:20:34 UTC"))
+ expect(domain.certificate_valid_not_before).to be_like_time(Time.zone.parse("2020-03-16 14:20:34 UTC"))
+ expect(domain.certificate_valid_not_after).to be_like_time(Time.zone.parse("2220-01-28 14:20:34 UTC"))
end
end
@@ -366,7 +366,7 @@ describe PagesDomain do
let_it_be(:domain) { create(:pages_domain) }
where(:attribute, :old_value, :new_value, :update_expected) do
- now = Time.now
+ now = Time.current
future = now + 1.day
:project | nil | :project1 | true
@@ -548,7 +548,7 @@ describe PagesDomain do
it 'does not clear failure on unrelated updates' do
expect do
- domain.update!(verified_at: Time.now)
+ domain.update!(verified_at: Time.current)
end.not_to change { domain.auto_ssl_failed }.from(true)
end
end
diff --git a/spec/models/performance_monitoring/prometheus_dashboard_spec.rb b/spec/models/performance_monitoring/prometheus_dashboard_spec.rb
index e6fc03a0fb6..ef7298c3d8c 100644
--- a/spec/models/performance_monitoring/prometheus_dashboard_spec.rb
+++ b/spec/models/performance_monitoring/prometheus_dashboard_spec.rb
@@ -38,24 +38,141 @@ describe PerformanceMonitoring::PrometheusDashboard do
end
describe 'validations' do
- context 'when dashboard is missing' do
- before do
- json_content['dashboard'] = nil
+ shared_examples 'validation failed' do |errors_messages|
+ it 'raises error with corresponding messages', :aggregate_failures do
+ expect { subject }.to raise_error do |error|
+ expect(error).to be_kind_of(ActiveModel::ValidationError)
+ expect(error.model.errors.messages).to eq(errors_messages)
+ end
end
+ end
+
+ context 'dashboard content is missing' do
+ let(:json_content) { nil }
+
+ it_behaves_like 'validation failed', panel_groups: ["can't be blank"], dashboard: ["can't be blank"]
+ end
+
+ context 'dashboard content is NOT a hash' do
+ let(:json_content) { YAML.safe_load("'test'") }
+
+ it_behaves_like 'validation failed', panel_groups: ["can't be blank"], dashboard: ["can't be blank"]
+ end
+
+ context 'content is an array' do
+ let(:json_content) { [{ "dashboard" => "Dashboard Title" }] }
+
+ it_behaves_like 'validation failed', panel_groups: ["can't be blank"], dashboard: ["can't be blank"]
+ end
- subject { described_class.from_json(json_content) }
+ context 'dashboard definition is missing panels_groups and dashboard keys' do
+ let(:json_content) do
+ {
+ "dashboard" => nil
+ }
+ end
+
+ it_behaves_like 'validation failed', panel_groups: ["can't be blank"], dashboard: ["can't be blank"]
+ end
+
+ context 'group definition is missing panels and group keys' do
+ let(:json_content) do
+ {
+ "dashboard" => "Dashboard Title",
+ "templating" => {
+ "variables" => {
+ "variable1" => %w(value1 value2 value3)
+ }
+ },
+ "panel_groups" => [{ "group" => nil }]
+ }
+ end
+
+ it_behaves_like 'validation failed', panels: ["can't be blank"], group: ["can't be blank"]
+ end
+
+ context 'panel definition is missing metrics and title keys' do
+ let(:json_content) do
+ {
+ "dashboard" => "Dashboard Title",
+ "templating" => {
+ "variables" => {
+ "variable1" => %w(value1 value2 value3)
+ }
+ },
+ "panel_groups" => [{
+ "group" => "Group Title",
+ "panels" => [{
+ "type" => "area-chart",
+ "y_label" => "Y-Axis"
+ }]
+ }]
+ }
+ end
- it { expect { subject }.to raise_error(ActiveModel::ValidationError) }
+ it_behaves_like 'validation failed', metrics: ["can't be blank"], title: ["can't be blank"]
end
- context 'when panel groups are missing' do
- before do
- json_content['panel_groups'] = []
+ context 'metrics definition is missing unit, query and query_range keys' do
+ let(:json_content) do
+ {
+ "dashboard" => "Dashboard Title",
+ "templating" => {
+ "variables" => {
+ "variable1" => %w(value1 value2 value3)
+ }
+ },
+ "panel_groups" => [{
+ "group" => "Group Title",
+ "panels" => [{
+ "type" => "area-chart",
+ "title" => "Chart Title",
+ "y_label" => "Y-Axis",
+ "metrics" => [{
+ "id" => "metric_of_ages",
+ "label" => "Metric of Ages",
+ "query_range" => nil
+ }]
+ }]
+ }]
+ }
end
- subject { described_class.from_json(json_content) }
+ it_behaves_like 'validation failed', unit: ["can't be blank"], query_range: ["can't be blank"], query: ["can't be blank"]
+ end
+
+ # for each parent entry validation first is done to its children,
+ # whole execution is stopped on first encountered error
+ # which is the one that is reported
+ context 'multiple offences on different levels' do
+ let(:json_content) do
+ {
+ "dashboard" => nil,
+ "panel_groups" => [{
+ "group" => nil,
+ "panels" => [{
+ "type" => "area-chart",
+ "title" => nil,
+ "y_label" => "Y-Axis",
+ "metrics" => [{
+ "id" => "metric_of_ages",
+ "label" => "Metric of Ages",
+ "query_range" => 'query'
+ }, {
+ "id" => "metric_of_ages",
+ "unit" => "count",
+ "label" => "Metric of Ages",
+ "query_range" => nil
+ }]
+ }]
+ }, {
+ "group" => 'group',
+ "panels" => nil
+ }]
+ }
+ end
- it { expect { subject }.to raise_error(ActiveModel::ValidationError) }
+ it_behaves_like 'validation failed', unit: ["can't be blank"]
end
end
end
@@ -73,20 +190,51 @@ describe PerformanceMonitoring::PrometheusDashboard do
dashboard_instance = described_class.find_for(project: project, user: user, path: path, options: { environment: environment })
expect(dashboard_instance).to be_instance_of described_class
- expect(dashboard_instance.environment).to be environment
- expect(dashboard_instance.path).to be path
+ expect(dashboard_instance.environment).to eq environment
+ expect(dashboard_instance.path).to eq path
end
end
context 'dashboard has NOT been found' do
it 'returns nil' do
- allow(Gitlab::Metrics::Dashboard::Finder).to receive(:find).and_return(status: :error)
+ allow(Gitlab::Metrics::Dashboard::Finder).to receive(:find).and_return(http_status: :not_found)
dashboard_instance = described_class.find_for(project: project, user: user, path: path, options: { environment: environment })
expect(dashboard_instance).to be_nil
end
end
+
+ context 'dashboard has invalid schema', :aggregate_failures do
+ it 'still returns dashboard object' do
+ expect(Gitlab::Metrics::Dashboard::Finder).to receive(:find).and_return(http_status: :unprocessable_entity)
+
+ dashboard_instance = described_class.find_for(project: project, user: user, path: path, options: { environment: environment })
+
+ expect(dashboard_instance).to be_instance_of described_class
+ expect(dashboard_instance.environment).to eq environment
+ expect(dashboard_instance.path).to eq path
+ end
+ end
+ end
+
+ describe '#schema_validation_warnings' do
+ context 'when schema is valid' do
+ it 'returns nil' do
+ expect(described_class).to receive(:from_json)
+ expect(described_class.new.schema_validation_warnings).to be_nil
+ end
+ end
+
+ context 'when schema is invalid' do
+ it 'returns array with errors messages' do
+ instance = described_class.new
+ instance.errors.add(:test, 'test error')
+
+ expect(described_class).to receive(:from_json).and_raise(ActiveModel::ValidationError.new(instance))
+ expect(described_class.new.schema_validation_warnings).to eq ['test: test error']
+ end
+ end
end
describe '#to_yaml' do
diff --git a/spec/models/performance_monitoring/prometheus_metric_spec.rb b/spec/models/performance_monitoring/prometheus_metric_spec.rb
index 08288e5d993..83f687aa90e 100644
--- a/spec/models/performance_monitoring/prometheus_metric_spec.rb
+++ b/spec/models/performance_monitoring/prometheus_metric_spec.rb
@@ -24,6 +24,14 @@ describe PerformanceMonitoring::PrometheusMetric do
end
describe 'validations' do
+ context 'json_content is not a hash' do
+ let(:json_content) { nil }
+
+ subject { described_class.from_json(json_content) }
+
+ it { expect { subject }.to raise_error(ActiveModel::ValidationError) }
+ end
+
context 'when unit is missing' do
before do
json_content['unit'] = nil
diff --git a/spec/models/performance_monitoring/prometheus_panel_group_spec.rb b/spec/models/performance_monitoring/prometheus_panel_group_spec.rb
index 2447bb5df94..ecf7e13a9a3 100644
--- a/spec/models/performance_monitoring/prometheus_panel_group_spec.rb
+++ b/spec/models/performance_monitoring/prometheus_panel_group_spec.rb
@@ -30,9 +30,17 @@ describe PerformanceMonitoring::PrometheusPanelGroup do
end
describe 'validations' do
+ context 'json_content is not a hash' do
+ let(:json_content) { nil }
+
+ subject { described_class.from_json(json_content) }
+
+ it { expect { subject }.to raise_error(ActiveModel::ValidationError) }
+ end
+
context 'when group is missing' do
before do
- json_content['group'] = nil
+ json_content.delete('group')
end
subject { described_class.from_json(json_content) }
diff --git a/spec/models/performance_monitoring/prometheus_panel_spec.rb b/spec/models/performance_monitoring/prometheus_panel_spec.rb
index f5e04ec91e2..127b9e8183a 100644
--- a/spec/models/performance_monitoring/prometheus_panel_spec.rb
+++ b/spec/models/performance_monitoring/prometheus_panel_spec.rb
@@ -42,6 +42,14 @@ describe PerformanceMonitoring::PrometheusPanel do
end
describe 'validations' do
+ context 'json_content is not a hash' do
+ let(:json_content) { nil }
+
+ subject { described_class.from_json(json_content) }
+
+ it { expect { subject }.to raise_error(ActiveModel::ValidationError) }
+ end
+
context 'when title is missing' do
before do
json_content['title'] = nil
@@ -54,7 +62,7 @@ describe PerformanceMonitoring::PrometheusPanel do
context 'when metrics are missing' do
before do
- json_content['metrics'] = []
+ json_content.delete('metrics')
end
subject { described_class.from_json(json_content) }
diff --git a/spec/models/personal_access_token_spec.rb b/spec/models/personal_access_token_spec.rb
index 596b11613b3..a3f5eb38511 100644
--- a/spec/models/personal_access_token_spec.rb
+++ b/spec/models/personal_access_token_spec.rb
@@ -178,6 +178,15 @@ describe PersonalAccessToken do
end
end
end
+
+ describe '.without_impersonation' do
+ let_it_be(:impersonation_token) { create(:personal_access_token, :impersonation) }
+ let_it_be(:personal_access_token) { create(:personal_access_token) }
+
+ it 'returns only non-impersonation tokens' do
+ expect(described_class.without_impersonation).to contain_exactly(personal_access_token)
+ end
+ end
end
describe '.simple_sorts' do
diff --git a/spec/models/project_ci_cd_setting_spec.rb b/spec/models/project_ci_cd_setting_spec.rb
index 86115a61aa7..ecca371ce4e 100644
--- a/spec/models/project_ci_cd_setting_spec.rb
+++ b/spec/models/project_ci_cd_setting_spec.rb
@@ -3,25 +3,6 @@
require 'spec_helper'
describe ProjectCiCdSetting do
- describe '.available?' do
- before do
- described_class.reset_column_information
- end
-
- it 'returns true' do
- expect(described_class).to be_available
- end
-
- it 'memoizes the schema version' do
- expect(ActiveRecord::Migrator)
- .to receive(:current_version)
- .and_call_original
- .once
-
- 2.times { described_class.available? }
- end
- end
-
describe 'validations' do
it 'validates default_git_depth is between 0 and 1000 or nil' do
expect(subject).to validate_numericality_of(:default_git_depth)
diff --git a/spec/models/project_feature_spec.rb b/spec/models/project_feature_spec.rb
index e072cc21b38..e33ea75bc5d 100644
--- a/spec/models/project_feature_spec.rb
+++ b/spec/models/project_feature_spec.rb
@@ -18,106 +18,6 @@ describe ProjectFeature do
end
end
- describe '.quoted_access_level_column' do
- it 'returns the table name and quoted column name for a feature' do
- expected = '"project_features"."issues_access_level"'
-
- expect(described_class.quoted_access_level_column(:issues)).to eq(expected)
- end
- end
-
- describe '#feature_available?' do
- let(:features) { %w(issues wiki builds merge_requests snippets repository pages metrics_dashboard) }
-
- context 'when features are disabled' do
- it "returns false" do
- update_all_project_features(project, features, ProjectFeature::DISABLED)
-
- features.each do |feature|
- expect(project.feature_available?(feature.to_sym, user)).to eq(false), "#{feature} failed"
- end
- end
- end
-
- context 'when features are enabled only for team members' do
- it "returns false when user is not a team member" do
- update_all_project_features(project, features, ProjectFeature::PRIVATE)
-
- features.each do |feature|
- expect(project.feature_available?(feature.to_sym, user)).to eq(false), "#{feature} failed"
- end
- end
-
- it "returns true when user is a team member" do
- project.add_developer(user)
-
- update_all_project_features(project, features, ProjectFeature::PRIVATE)
-
- features.each do |feature|
- expect(project.feature_available?(feature.to_sym, user)).to eq(true), "#{feature} failed"
- end
- end
-
- it "returns true when user is a member of project group" do
- group = create(:group)
- project = create(:project, namespace: group)
- group.add_developer(user)
-
- update_all_project_features(project, features, ProjectFeature::PRIVATE)
-
- features.each do |feature|
- expect(project.feature_available?(feature.to_sym, user)).to eq(true), "#{feature} failed"
- end
- end
-
- context 'when admin mode is enabled', :enable_admin_mode do
- it "returns true if user is an admin" do
- user.update_attribute(:admin, true)
-
- update_all_project_features(project, features, ProjectFeature::PRIVATE)
-
- features.each do |feature|
- expect(project.feature_available?(feature.to_sym, user)).to eq(true), "#{feature} failed"
- end
- end
- end
-
- context 'when admin mode is disabled' do
- it "returns false when user is an admin" do
- user.update_attribute(:admin, true)
-
- update_all_project_features(project, features, ProjectFeature::PRIVATE)
-
- features.each do |feature|
- expect(project.feature_available?(feature.to_sym, user)).to eq(false), "#{feature} failed"
- end
- end
- end
- end
-
- context 'when feature is enabled for everyone' do
- it "returns true" do
- expect(project.feature_available?(:issues, user)).to eq(true)
- end
- end
-
- context 'when feature is disabled by a feature flag' do
- it 'returns false' do
- stub_feature_flags(issues: false)
-
- expect(project.feature_available?(:issues, user)).to eq(false)
- end
- end
-
- context 'when feature is enabled by a feature flag' do
- it 'returns true' do
- stub_feature_flags(issues: true)
-
- expect(project.feature_available?(:issues, user)).to eq(true)
- end
- end
- end
-
context 'repository related features' do
before do
project.project_feature.update(
@@ -153,32 +53,6 @@ describe ProjectFeature do
end
end
- describe '#*_enabled?' do
- let(:features) { %w(wiki builds merge_requests) }
-
- it "returns false when feature is disabled" do
- update_all_project_features(project, features, ProjectFeature::DISABLED)
-
- features.each do |feature|
- expect(project.public_send("#{feature}_enabled?")).to eq(false), "#{feature} failed"
- end
- end
-
- it "returns true when feature is enabled only for team members" do
- update_all_project_features(project, features, ProjectFeature::PRIVATE)
-
- features.each do |feature|
- expect(project.public_send("#{feature}_enabled?")).to eq(true), "#{feature} failed"
- end
- end
-
- it "returns true when feature is enabled for everyone" do
- features.each do |feature|
- expect(project.public_send("#{feature}_enabled?")).to eq(true), "#{feature} failed"
- end
- end
- end
-
describe 'default pages access level' do
subject { project_feature.pages_access_level }
@@ -313,9 +187,4 @@ describe ProjectFeature do
expect(described_class.required_minimum_access_level_for_private_project(:issues)).to eq(Gitlab::Access::GUEST)
end
end
-
- def update_all_project_features(project, features, value)
- project_feature_attributes = features.map { |f| ["#{f}_access_level", value] }.to_h
- project.project_feature.update(project_feature_attributes)
- end
end
diff --git a/spec/models/project_group_link_spec.rb b/spec/models/project_group_link_spec.rb
index 9c51180b55b..8ef29e8a876 100644
--- a/spec/models/project_group_link_spec.rb
+++ b/spec/models/project_group_link_spec.rb
@@ -49,22 +49,6 @@ describe ProjectGroupLink do
end
end
- describe "destroying a record", :delete do
- it "refreshes group users' authorized projects" do
- project = create(:project, :private)
- group = create(:group)
- reporter = create(:user)
- group_users = group.users
-
- group.add_reporter(reporter)
- project.project_group_links.create(group: group)
- group_users.each { |user| expect(user.authorized_projects).to include(project) }
-
- project.project_group_links.destroy_all # rubocop: disable DestroyAll
- group_users.each { |user| expect(user.authorized_projects).not_to include(project) }
- end
- end
-
describe 'search by group name' do
let_it_be(:project_group_link) { create(:project_group_link) }
let_it_be(:group) { project_group_link.group }
diff --git a/spec/models/project_import_state_spec.rb b/spec/models/project_import_state_spec.rb
index cb34d898a6e..f3b83c036b5 100644
--- a/spec/models/project_import_state_spec.rb
+++ b/spec/models/project_import_state_spec.rb
@@ -57,6 +57,30 @@ describe ProjectImportState, type: :model do
end
end
+ describe '#mark_as_failed' do
+ let(:error_message) { 'some message' }
+
+ it 'logs error when update column fails' do
+ allow(import_state).to receive(:update_column).and_raise(ActiveRecord::ActiveRecordError)
+
+ expect_next_instance_of(Gitlab::Import::Logger) do |logger|
+ expect(logger).to receive(:error).with(
+ error: 'ActiveRecord::ActiveRecordError',
+ message: 'Error setting import status to failed',
+ original_error: error_message
+ )
+ end
+
+ import_state.mark_as_failed(error_message)
+ end
+
+ it 'updates last_error with error message' do
+ import_state.mark_as_failed(error_message)
+
+ expect(import_state.last_error).to eq(error_message)
+ end
+ end
+
describe '#human_status_name' do
context 'when import_state exists' do
it 'returns the humanized status name' do
diff --git a/spec/models/project_metrics_setting_spec.rb b/spec/models/project_metrics_setting_spec.rb
index 7df01625ba1..adfbbbc3a45 100644
--- a/spec/models/project_metrics_setting_spec.rb
+++ b/spec/models/project_metrics_setting_spec.rb
@@ -44,12 +44,20 @@ describe ProjectMetricsSetting do
it { is_expected.to be_valid }
end
- context 'external_dashboard_url is blank' do
- before do
- subject.external_dashboard_url = ''
+ context 'dashboard_timezone' do
+ it { is_expected.to define_enum_for(:dashboard_timezone).with_values({ local: 0, utc: 1 }) }
+
+ it 'defaults to local' do
+ expect(subject.dashboard_timezone).to eq('local')
end
+ end
+ end
- it { is_expected.to be_invalid }
+ describe '#dashboard_timezone=' do
+ it 'downcases string' do
+ subject.dashboard_timezone = 'UTC'
+
+ expect(subject.dashboard_timezone).to eq('utc')
end
end
end
diff --git a/spec/models/project_repository_storage_move_spec.rb b/spec/models/project_repository_storage_move_spec.rb
index 146fc13bee0..83711085c92 100644
--- a/spec/models/project_repository_storage_move_spec.rb
+++ b/spec/models/project_repository_storage_move_spec.rb
@@ -30,25 +30,36 @@ RSpec.describe ProjectRepositoryStorageMove, type: :model do
expect(subject.errors[:destination_storage_name].first).to match(/is not included in the list/)
end
end
+
+ context 'project repository read-only' do
+ subject { build(:project_repository_storage_move, project: project) }
+
+ let(:project) { build(:project, repository_read_only: true) }
+
+ it "does not allow the project to be read-only on create" do
+ expect(subject).not_to be_valid
+ expect(subject.errors[:project].first).to match(/is read only/)
+ end
+ end
end
describe 'state transitions' do
- using RSpec::Parameterized::TableSyntax
+ let(:project) { create(:project) }
+
+ before do
+ stub_storage_settings('test_second_storage' => { 'path' => 'tmp/tests/extra_storage' })
+ end
context 'when in the default state' do
subject(:storage_move) { create(:project_repository_storage_move, project: project, destination_storage_name: 'test_second_storage') }
- let(:project) { create(:project) }
-
- before do
- stub_storage_settings('test_second_storage' => { 'path' => 'tmp/tests/extra_storage' })
- end
-
context 'and transits to scheduled' do
it 'triggers ProjectUpdateRepositoryStorageWorker' do
expect(ProjectUpdateRepositoryStorageWorker).to receive(:perform_async).with(project.id, 'test_second_storage', storage_move.id)
storage_move.schedule!
+
+ expect(project).to be_repository_read_only
end
end
@@ -59,5 +70,26 @@ RSpec.describe ProjectRepositoryStorageMove, type: :model do
end
end
end
+
+ context 'when started' do
+ subject(:storage_move) { create(:project_repository_storage_move, :started, project: project, destination_storage_name: 'test_second_storage') }
+
+ context 'and transits to finished' do
+ it 'sets the repository storage and marks the project as writable' do
+ storage_move.finish!
+
+ expect(project.repository_storage).to eq('test_second_storage')
+ expect(project).not_to be_repository_read_only
+ end
+ end
+
+ context 'and transits to failed' do
+ it 'marks the project as writable' do
+ storage_move.do_fail!
+
+ expect(project).not_to be_repository_read_only
+ end
+ end
+ end
end
end
diff --git a/spec/models/project_services/chat_message/alert_message_spec.rb b/spec/models/project_services/chat_message/alert_message_spec.rb
new file mode 100644
index 00000000000..a1dd332c005
--- /dev/null
+++ b/spec/models/project_services/chat_message/alert_message_spec.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe ChatMessage::AlertMessage do
+ subject { described_class.new(args) }
+
+ let_it_be(:start_time) { Time.current }
+ let(:alert) { create(:alert_management_alert, started_at: start_time) }
+
+ let(:args) do
+ {
+ project_name: 'project_name',
+ project_url: 'http://example.com'
+ }.merge(Gitlab::DataBuilder::Alert.build(alert))
+ end
+
+ describe '#message' do
+ it 'returns the correct message' do
+ expect(subject.message).to eq("Alert firing in #{args[:project_name]}")
+ end
+ end
+
+ describe '#attachments' do
+ it 'returns an array of one' do
+ expect(subject.attachments).to be_a(Array)
+ expect(subject.attachments.size).to eq(1)
+ end
+
+ it 'contains the correct attributes' do
+ attachments_item = subject.attachments.first
+ expect(attachments_item).to have_key(:title)
+ expect(attachments_item).to have_key(:title_link)
+ expect(attachments_item).to have_key(:color)
+ expect(attachments_item).to have_key(:fields)
+ end
+
+ it 'returns the correct color' do
+ expect(subject.attachments.first[:color]).to eq("#C95823")
+ end
+
+ it 'returns the correct attachment fields' do
+ attachments_item = subject.attachments.first
+ fields = attachments_item[:fields].map { |h| h[:title] }
+
+ expect(fields).to match_array(['Severity', 'Events', 'Status', 'Start time'])
+ end
+
+ it 'returns the correctly formatted time' do
+ time_item = subject.attachments.first[:fields].detect { |h| h[:title] == 'Start time' }
+
+ expected_time = start_time.strftime("%B #{start_time.day.ordinalize}, %Y %l:%M%p %Z")
+
+ expect(time_item[:value]).to eq(expected_time)
+ end
+ end
+end
diff --git a/spec/models/project_services/chat_message/merge_message_spec.rb b/spec/models/project_services/chat_message/merge_message_spec.rb
index 150ee6f7472..6063ef4ecb3 100644
--- a/spec/models/project_services/chat_message/merge_message_spec.rb
+++ b/spec/models/project_services/chat_message/merge_message_spec.rb
@@ -52,7 +52,7 @@ describe ChatMessage::MergeMessage do
context 'open' do
it 'returns a message regarding opening of merge requests' do
expect(subject.pretext).to eq(
- 'Test User (test.user) opened <http://somewhere.com/-/merge_requests/100|!100 *Merge Request title*> in <http://somewhere.com|project_name>')
+ 'Test User (test.user) opened merge request <http://somewhere.com/-/merge_requests/100|!100 *Merge Request title*> in <http://somewhere.com|project_name>')
expect(subject.attachments).to be_empty
end
end
@@ -63,7 +63,7 @@ describe ChatMessage::MergeMessage do
end
it 'returns a message regarding closing of merge requests' do
expect(subject.pretext).to eq(
- 'Test User (test.user) closed <http://somewhere.com/-/merge_requests/100|!100 *Merge Request title*> in <http://somewhere.com|project_name>')
+ 'Test User (test.user) closed merge request <http://somewhere.com/-/merge_requests/100|!100 *Merge Request title*> in <http://somewhere.com|project_name>')
expect(subject.attachments).to be_empty
end
end
@@ -77,7 +77,7 @@ describe ChatMessage::MergeMessage do
context 'open' do
it 'returns a message regarding opening of merge requests' do
expect(subject.pretext).to eq(
- 'Test User (test.user) opened [!100 *Merge Request title*](http://somewhere.com/-/merge_requests/100) in [project_name](http://somewhere.com)')
+ 'Test User (test.user) opened merge request [!100 *Merge Request title*](http://somewhere.com/-/merge_requests/100) in [project_name](http://somewhere.com)')
expect(subject.attachments).to be_empty
expect(subject.activity).to eq({
title: 'Merge Request opened by Test User (test.user)',
@@ -95,7 +95,7 @@ describe ChatMessage::MergeMessage do
it 'returns a message regarding closing of merge requests' do
expect(subject.pretext).to eq(
- 'Test User (test.user) closed [!100 *Merge Request title*](http://somewhere.com/-/merge_requests/100) in [project_name](http://somewhere.com)')
+ 'Test User (test.user) closed merge request [!100 *Merge Request title*](http://somewhere.com/-/merge_requests/100) in [project_name](http://somewhere.com)')
expect(subject.attachments).to be_empty
expect(subject.activity).to eq({
title: 'Merge Request closed by Test User (test.user)',
diff --git a/spec/models/project_services/chat_message/pipeline_message_spec.rb b/spec/models/project_services/chat_message/pipeline_message_spec.rb
index 7c3e48f572a..a7171577063 100644
--- a/spec/models/project_services/chat_message/pipeline_message_spec.rb
+++ b/spec/models/project_services/chat_message/pipeline_message_spec.rb
@@ -61,8 +61,8 @@ describe ChatMessage::PipelineMessage do
it "returns the pipeline summary in the activity's title" do
expect(subject.activity[:title]).to eq(
- "Pipeline [#123](http://example.gitlab.com/pipelines/123)" \
- " of branch [develop](http://example.gitlab.com/commits/develop)" \
+ "Pipeline [#123](http://example.gitlab.com/-/pipelines/123)" \
+ " of branch [develop](http://example.gitlab.com/-/commits/develop)" \
" by The Hacker (hacker) has passed"
)
end
@@ -74,8 +74,8 @@ describe ChatMessage::PipelineMessage do
it "returns the summary with a 'failed' status" do
expect(subject.activity[:title]).to eq(
- "Pipeline [#123](http://example.gitlab.com/pipelines/123)" \
- " of branch [develop](http://example.gitlab.com/commits/develop)" \
+ "Pipeline [#123](http://example.gitlab.com/-/pipelines/123)" \
+ " of branch [develop](http://example.gitlab.com/-/commits/develop)" \
" by The Hacker (hacker) has failed"
)
end
@@ -88,8 +88,8 @@ describe ChatMessage::PipelineMessage do
it "returns the summary with a 'passed with warnings' status" do
expect(subject.activity[:title]).to eq(
- "Pipeline [#123](http://example.gitlab.com/pipelines/123)" \
- " of branch [develop](http://example.gitlab.com/commits/develop)" \
+ "Pipeline [#123](http://example.gitlab.com/-/pipelines/123)" \
+ " of branch [develop](http://example.gitlab.com/-/commits/develop)" \
" by The Hacker (hacker) has passed with warnings"
)
end
@@ -102,8 +102,8 @@ describe ChatMessage::PipelineMessage do
it "returns the summary with 'API' as the username" do
expect(subject.activity[:title]).to eq(
- "Pipeline [#123](http://example.gitlab.com/pipelines/123)" \
- " of branch [develop](http://example.gitlab.com/commits/develop)" \
+ "Pipeline [#123](http://example.gitlab.com/-/pipelines/123)" \
+ " of branch [develop](http://example.gitlab.com/-/commits/develop)" \
" by API has passed"
)
end
@@ -134,8 +134,8 @@ describe ChatMessage::PipelineMessage do
it "returns the pipeline summary as the attachment's fallback property" do
expect(subject.attachments.first[:fallback]).to eq(
"<http://example.gitlab.com|project_name>:" \
- " Pipeline <http://example.gitlab.com/pipelines/123|#123>" \
- " of branch <http://example.gitlab.com/commits/develop|develop>" \
+ " Pipeline <http://example.gitlab.com/-/pipelines/123|#123>" \
+ " of branch <http://example.gitlab.com/-/commits/develop|develop>" \
" by The Hacker (hacker) has passed in 02:00:10"
)
end
@@ -199,7 +199,7 @@ describe ChatMessage::PipelineMessage do
end
it "returns the pipeline URL as the attachment's title_link property" do
- expect(subject.attachments.first[:title_link]).to eq("http://example.gitlab.com/pipelines/123")
+ expect(subject.attachments.first[:title_link]).to eq("http://example.gitlab.com/-/pipelines/123")
end
it "returns two attachment fields" do
@@ -209,7 +209,7 @@ describe ChatMessage::PipelineMessage do
it "returns the commit message as the attachment's second field property" do
expect(subject.attachments.first[:fields][0]).to eq({
title: "Branch",
- value: "<http://example.gitlab.com/commits/develop|develop>",
+ value: "<http://example.gitlab.com/-/commits/develop|develop>",
short: true
})
end
@@ -237,7 +237,7 @@ describe ChatMessage::PipelineMessage do
it "returns the stage name and link to the 'Failed jobs' tab on the pipeline's page as the attachment's third field property" do
expect(subject.attachments.first[:fields][2]).to eq({
title: "Failed stage",
- value: "<http://example.gitlab.com/pipelines/123/failures|test>",
+ value: "<http://example.gitlab.com/-/pipelines/123/failures|test>",
short: true
})
end
@@ -261,7 +261,7 @@ describe ChatMessage::PipelineMessage do
it "returns the stage names and links to the 'Failed jobs' tab on the pipeline's page as the attachment's third field property" do
expect(subject.attachments.first[:fields][2]).to eq({
title: "Failed stages",
- value: "<http://example.gitlab.com/pipelines/123/failures|stage-2>, <http://example.gitlab.com/pipelines/123/failures|stage-1>, <http://example.gitlab.com/pipelines/123/failures|stage-3>",
+ value: "<http://example.gitlab.com/-/pipelines/123/failures|stage-2>, <http://example.gitlab.com/-/pipelines/123/failures|stage-1>, <http://example.gitlab.com/-/pipelines/123/failures|stage-3>",
short: true
})
end
@@ -271,7 +271,7 @@ describe ChatMessage::PipelineMessage do
"<http://example.gitlab.com/-/jobs/#{i}|job-#{i}>"
end
- expected_jobs << "and <http://example.gitlab.com/pipelines/123/failures|15 more>"
+ expected_jobs << "and <http://example.gitlab.com/-/pipelines/123/failures|15 more>"
expect(subject.attachments.first[:fields][3]).to eq({
title: "Failed jobs",
@@ -369,8 +369,8 @@ describe ChatMessage::PipelineMessage do
it 'returns the pipeline summary as the attachments in markdown format' do
expect(subject.attachments).to eq(
"[project_name](http://example.gitlab.com):" \
- " Pipeline [#123](http://example.gitlab.com/pipelines/123)" \
- " of branch [develop](http://example.gitlab.com/commits/develop)" \
+ " Pipeline [#123](http://example.gitlab.com/-/pipelines/123)" \
+ " of branch [develop](http://example.gitlab.com/-/commits/develop)" \
" by The Hacker (hacker) has passed in 02:00:10"
)
end
diff --git a/spec/models/project_services/emails_on_push_service_spec.rb b/spec/models/project_services/emails_on_push_service_spec.rb
index ce1952b503f..44db95afc57 100644
--- a/spec/models/project_services/emails_on_push_service_spec.rb
+++ b/spec/models/project_services/emails_on_push_service_spec.rb
@@ -21,23 +21,25 @@ describe EmailsOnPushService do
end
end
- context 'when properties is missing branches_to_be_notified' do
- subject { described_class.new(properties: {}) }
+ describe '.new' do
+ context 'when properties is missing branches_to_be_notified' do
+ subject { described_class.new(properties: {}) }
- it 'sets the default value to all' do
- expect(subject.branches_to_be_notified).to eq('all')
+ it 'sets the default value to all' do
+ expect(subject.branches_to_be_notified).to eq('all')
+ end
end
- end
- context 'when branches_to_be_notified is already set' do
- subject { described_class.new(properties: { branches_to_be_notified: 'protected' }) }
+ context 'when branches_to_be_notified is already set' do
+ subject { described_class.new(properties: { branches_to_be_notified: 'protected' }) }
- it 'does not overwrite it with the default value' do
- expect(subject.branches_to_be_notified).to eq('protected')
+ it 'does not overwrite it with the default value' do
+ expect(subject.branches_to_be_notified).to eq('protected')
+ end
end
end
- context 'project emails' do
+ describe '#execute' do
let(:push_data) { { object_kind: 'push' } }
let(:project) { create(:project, :repository) }
let(:service) { create(:emails_on_push_service, project: project) }
diff --git a/spec/models/project_services/hipchat_service_spec.rb b/spec/models/project_services/hipchat_service_spec.rb
index ae6e93cfe3a..c25edf81352 100644
--- a/spec/models/project_services/hipchat_service_spec.rb
+++ b/spec/models/project_services/hipchat_service_spec.rb
@@ -327,8 +327,8 @@ describe HipchatService do
user_name = data[:user][:name]
expect(message).to eq("<a href=\"#{project_url}\">#{project_name}</a>: " \
- "Pipeline <a href=\"#{project_url}/pipelines/#{pipeline.id}\">##{pipeline.id}</a> " \
- "of <a href=\"#{project_url}/commits/#{ref}\">#{ref}</a> #{ref_type} " \
+ "Pipeline <a href=\"#{project_url}/-/pipelines/#{pipeline.id}\">##{pipeline.id}</a> " \
+ "of <a href=\"#{project_url}/-/commits/#{ref}\">#{ref}</a> #{ref_type} " \
"by #{user_name} failed in #{duration} second(s)")
end
end
diff --git a/spec/models/project_services/jira_service_spec.rb b/spec/models/project_services/jira_service_spec.rb
index a0d36f0a238..20e85f0fd4b 100644
--- a/spec/models/project_services/jira_service_spec.rb
+++ b/spec/models/project_services/jira_service_spec.rb
@@ -688,22 +688,18 @@ describe JiraService do
context 'when the test fails' do
it 'returns result with the error' do
test_url = 'http://jira.example.com/rest/api/2/serverInfo'
+ error_message = 'Some specific failure.'
WebMock.stub_request(:get, test_url).with(basic_auth: [username, password])
- .to_raise(JIRA::HTTPError.new(double(message: 'Some specific failure.')))
+ .to_raise(JIRA::HTTPError.new(double(message: error_message)))
expect(jira_service).to receive(:log_error).with(
- "Error sending message",
- hash_including(
- client_url: url,
- error: hash_including(
- exception_class: 'JIRA::HTTPError',
- exception_message: 'Some specific failure.'
- )
- )
+ 'Error sending message',
+ client_url: 'http://jira.example.com',
+ error: error_message
)
- expect(jira_service.test(nil)).to eq(success: false, result: 'Some specific failure.')
+ expect(jira_service.test(nil)).to eq(success: false, result: error_message)
end
end
end
diff --git a/spec/models/project_services/pipelines_email_service_spec.rb b/spec/models/project_services/pipelines_email_service_spec.rb
index f29414c80c9..de1edf2099a 100644
--- a/spec/models/project_services/pipelines_email_service_spec.rb
+++ b/spec/models/project_services/pipelines_email_service_spec.rb
@@ -37,22 +37,6 @@ describe PipelinesEmailService, :mailer do
end
end
- describe '#test_data' do
- let(:build) { create(:ci_build) }
- let(:project) { build.project }
- let(:user) { create(:user) }
-
- before do
- project.add_developer(user)
- end
-
- it 'builds test data' do
- data = subject.test_data(project, user)
-
- expect(data[:object_kind]).to eq('pipeline')
- end
- end
-
shared_examples 'sending email' do |branches_to_be_notified: nil|
before do
subject.recipients = recipients
diff --git a/spec/models/project_services/prometheus_service_spec.rb b/spec/models/project_services/prometheus_service_spec.rb
index a85dbe3a7df..db3cbe23ad3 100644
--- a/spec/models/project_services/prometheus_service_spec.rb
+++ b/spec/models/project_services/prometheus_service_spec.rb
@@ -252,6 +252,26 @@ describe PrometheusService, :use_clean_rails_memory_store_caching do
end
end
end
+
+ context 'behind IAP' do
+ let(:manual_configuration) { true }
+
+ before do
+ # dummy private key generated only for this test to pass openssl validation
+ service.google_iap_service_account_json = '{"type":"service_account","private_key":"-----BEGIN RSA PRIVATE KEY-----\nMIIBOAIBAAJAU85LgUY5o6j6j/07GMLCNUcWJOBA1buZnNgKELayA6mSsHrIv31J\nY8kS+9WzGPQninea7DcM4hHA7smMgQD1BwIDAQABAkAqKxMy6PL3tn7dFL43p0ex\nJyOtSmlVIiAZG1t1LXhE/uoLpYi5DnbYqGgu0oih+7nzLY/dXpNpXUmiRMOUEKmB\nAiEAoTi2rBXbrLSi2C+H7M/nTOjMQQDuZ8Wr4uWpKcjYJTMCIQCFEskL565oFl/7\nRRQVH+cARrAsAAoJSbrOBAvYZ0PI3QIgIEFwis10vgEF86rOzxppdIG/G+JL0IdD\n9IluZuXAGPECIGUo7qSaLr75o2VEEgwtAFH5aptIPFjrL5LFCKwtdB4RAiAYZgFV\nHCMmaooAw/eELuMoMWNYmujZ7VaAnOewGDW0uw==\n-----END RSA PRIVATE KEY-----\n"}'
+ service.google_iap_audience_client_id = "IAP_CLIENT_ID.apps.googleusercontent.com"
+
+ stub_request(:post, "https://oauth2.googleapis.com/token").to_return(status: 200, body: '{"id_token": "FOO"}', headers: { 'Content-Type': 'application/json; charset=UTF-8' })
+
+ stub_feature_flags(prometheus_service_iap_auth: true)
+ end
+
+ it 'includes the authorization header' do
+ expect(service.prometheus_client).not_to be_nil
+ expect(service.prometheus_client.send(:options)).to have_key(:headers)
+ expect(service.prometheus_client.send(:options)[:headers]).to eq(authorization: "Bearer FOO")
+ end
+ end
end
describe '#prometheus_available?' do
@@ -457,9 +477,34 @@ describe PrometheusService, :use_clean_rails_memory_store_caching do
}
]
end
+ let(:feature_flagged_fields) do
+ [
+ {
+ type: 'text',
+ name: 'google_iap_audience_client_id',
+ title: 'Google IAP Audience Client ID',
+ placeholder: s_('PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)'),
+ autocomplete: 'off',
+ required: false
+ },
+ {
+ type: 'textarea',
+ name: 'google_iap_service_account_json',
+ title: 'Google IAP Service Account JSON',
+ placeholder: s_('PrometheusService|Contents of the credentials.json file of your service account, like: { "type": "service_account", "project_id": ... }'),
+ required: false
+ }
+ ]
+ end
it 'returns fields' do
+ stub_feature_flags(prometheus_service_iap_auth: false)
expect(service.fields).to eq(expected_fields)
end
+
+ it 'returns fields with feature flag on' do
+ stub_feature_flags(prometheus_service_iap_auth: true)
+ expect(service.fields).to eq(expected_fields + feature_flagged_fields)
+ end
end
end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 5f8b51c250d..9ec306d297e 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -79,6 +79,7 @@ describe Project do
it { is_expected.to have_many(:ci_refs) }
it { is_expected.to have_many(:builds) }
it { is_expected.to have_many(:build_trace_section_names)}
+ it { is_expected.to have_many(:build_report_results) }
it { is_expected.to have_many(:runner_projects) }
it { is_expected.to have_many(:runners) }
it { is_expected.to have_many(:variables) }
@@ -117,6 +118,7 @@ describe Project do
it { is_expected.to have_many(:jira_imports) }
it { is_expected.to have_many(:metrics_users_starred_dashboards).inverse_of(:project) }
it { is_expected.to have_many(:repository_storage_moves) }
+ it { is_expected.to have_many(:reviews).inverse_of(:project) }
it_behaves_like 'model with repository' do
let_it_be(:container) { create(:project, :repository, path: 'somewhere') }
@@ -181,9 +183,9 @@ describe Project do
expect(project.pages_metadatum).to be_persisted
end
- it 'automatically creates a project setting row' do
+ it 'automatically builds a project setting row' do
expect(project.project_setting).to be_an_instance_of(ProjectSetting)
- expect(project.project_setting).to be_persisted
+ expect(project.project_setting).to be_new_record
end
end
@@ -770,7 +772,7 @@ describe Project do
describe 'last_activity_date' do
it 'returns the creation date of the project\'s last event if present' do
- new_event = create(:event, :closed, project: project, created_at: Time.now)
+ new_event = create(:event, :closed, project: project, created_at: Time.current)
project.reload
expect(project.last_activity_at.to_i).to eq(new_event.created_at.to_i)
@@ -2836,48 +2838,6 @@ describe Project do
end
end
- describe '#change_repository_storage' do
- let(:project) { create(:project, :repository) }
- let(:read_only_project) { create(:project, :repository, repository_read_only: true) }
-
- before do
- stub_storage_settings('test_second_storage' => { 'path' => 'tmp/tests/extra_storage' })
- end
-
- it 'schedules the transfer of the repository to the new storage and locks the project' do
- expect(ProjectUpdateRepositoryStorageWorker).to receive(:perform_async).with(project.id, 'test_second_storage', anything)
-
- project.change_repository_storage('test_second_storage')
- project.save!
-
- expect(project).to be_repository_read_only
- expect(project.repository_storage_moves.last).to have_attributes(
- source_storage_name: "default",
- destination_storage_name: "test_second_storage"
- )
- end
-
- it "doesn't schedule the transfer if the repository is already read-only" do
- expect(ProjectUpdateRepositoryStorageWorker).not_to receive(:perform_async)
-
- read_only_project.change_repository_storage('test_second_storage')
- read_only_project.save!
- end
-
- it "doesn't lock or schedule the transfer if the storage hasn't changed" do
- expect(ProjectUpdateRepositoryStorageWorker).not_to receive(:perform_async)
-
- project.change_repository_storage(project.repository_storage)
- project.save!
-
- expect(project).not_to be_repository_read_only
- end
-
- it 'throws an error if an invalid repository storage is provided' do
- expect { project.change_repository_storage('unknown') }.to raise_error(ArgumentError)
- end
- end
-
describe '#pushes_since_gc' do
let(:project) { create(:project) }
@@ -3620,7 +3580,7 @@ describe Project do
expect(project).not_to receive(:visibility_level_allowed_as_fork).and_call_original
expect(project).not_to receive(:visibility_level_allowed_by_group).and_call_original
- project.update(updated_at: Time.now)
+ project.update(updated_at: Time.current)
end
end
@@ -3766,7 +3726,7 @@ describe Project do
context 'when feature is private' do
let(:project) { create(:project, :public, :merge_requests_private) }
- context 'when user does not has access to the feature' do
+ context 'when user does not have access to the feature' do
it 'does not return projects with the project feature private' do
is_expected.not_to include(project)
end
@@ -4302,8 +4262,7 @@ describe Project do
describe '#auto_devops_enabled?' do
before do
- allow(Feature).to receive(:enabled?).and_call_original
- Feature.get(:force_autodevops_on_by_default).enable_percentage_of_actors(0)
+ Feature.enable_percentage_of_actors(:force_autodevops_on_by_default, 0)
end
let_it_be(:project, reload: true) { create(:project) }
@@ -4505,8 +4464,7 @@ describe Project do
let_it_be(:project, reload: true) { create(:project) }
before do
- allow(Feature).to receive(:enabled?).and_call_original
- Feature.get(:force_autodevops_on_by_default).enable_percentage_of_actors(0)
+ Feature.enable_percentage_of_actors(:force_autodevops_on_by_default, 0)
end
context 'when explicitly disabled' do
@@ -4552,7 +4510,7 @@ describe Project do
before do
create(:project_auto_devops, project: project, enabled: false)
- Feature.get(:force_autodevops_on_by_default).enable_percentage_of_actors(100)
+ Feature.enable_percentage_of_actors(:force_autodevops_on_by_default, 100)
end
it 'does not have auto devops implicitly disabled' do
@@ -4854,6 +4812,32 @@ describe Project do
end
end
+ describe '#execute_services' do
+ let(:service) { create(:slack_service, push_events: true, merge_requests_events: false, active: true) }
+
+ it 'executes services with the specified scope' do
+ data = 'any data'
+
+ expect(SlackService).to receive(:allocate).and_wrap_original do |method|
+ method.call.tap do |instance|
+ expect(instance).to receive(:async_execute).with(data).once
+ end
+ end
+
+ service.project.execute_services(data, :push_hooks)
+ end
+
+ it 'does not execute services that don\'t match the specified scope' do
+ expect(SlackService).not_to receive(:allocate).and_wrap_original do |method|
+ method.call.tap do |instance|
+ expect(instance).not_to receive(:async_execute)
+ end
+ end
+
+ service.project.execute_services(anything, :merge_request_hooks)
+ end
+ end
+
describe '#has_active_hooks?' do
let_it_be(:project) { create(:project) }
@@ -5241,25 +5225,21 @@ describe Project do
end
end
- describe "#find_or_initialize_services" do
- subject { build(:project) }
-
+ describe '#find_or_initialize_services' do
it 'returns only enabled services' do
- allow(Service).to receive(:available_services_names).and_return(%w(prometheus pushover))
- allow(subject).to receive(:disabled_services).and_return(%w(prometheus))
+ allow(Service).to receive(:available_services_names).and_return(%w[prometheus pushover teamcity])
+ allow(subject).to receive(:disabled_services).and_return(%w[prometheus])
services = subject.find_or_initialize_services
- expect(services.count).to eq 1
- expect(services).to include(PushoverService)
+ expect(services.count).to eq(2)
+ expect(services.map(&:title)).to eq(['JetBrains TeamCity CI', 'Pushover'])
end
end
- describe "#find_or_initialize_service" do
- subject { build(:project) }
-
+ describe '#find_or_initialize_service' do
it 'avoids N+1 database queries' do
- allow(Service).to receive(:available_services_names).and_return(%w(prometheus pushover))
+ allow(Service).to receive(:available_services_names).and_return(%w[prometheus pushover])
control_count = ActiveRecord::QueryRecorder.new { subject.find_or_initialize_service('prometheus') }.count
@@ -5268,11 +5248,51 @@ describe Project do
expect { subject.find_or_initialize_service('prometheus') }.not_to exceed_query_limit(control_count)
end
- it 'returns nil if service is disabled' do
- allow(subject).to receive(:disabled_services).and_return(%w(prometheus))
+ it 'returns nil if integration is disabled' do
+ allow(subject).to receive(:disabled_services).and_return(%w[prometheus])
expect(subject.find_or_initialize_service('prometheus')).to be_nil
end
+
+ context 'with an existing integration' do
+ subject { create(:project) }
+
+ before do
+ create(:prometheus_service, project: subject, api_url: 'https://prometheus.project.com/')
+ end
+
+ it 'retrieves the integration' do
+ expect(subject.find_or_initialize_service('prometheus').api_url).to eq('https://prometheus.project.com/')
+ end
+ end
+
+ context 'with an instance-level and template integrations' do
+ before do
+ create(:prometheus_service, :instance, api_url: 'https://prometheus.instance.com/')
+ create(:prometheus_service, :template, api_url: 'https://prometheus.template.com/')
+ end
+
+ it 'builds the service from the instance if exists' do
+ expect(subject.find_or_initialize_service('prometheus').api_url).to eq('https://prometheus.instance.com/')
+ end
+ end
+
+ context 'with an instance-level and template integrations' do
+ before do
+ create(:prometheus_service, :template, api_url: 'https://prometheus.template.com/')
+ end
+
+ it 'builds the service from the template if instance does not exists' do
+ expect(subject.find_or_initialize_service('prometheus').api_url).to eq('https://prometheus.template.com/')
+ end
+ end
+
+ context 'without an exisiting integration, nor instance-level or template' do
+ it 'builds the service if instance or template does not exists' do
+ expect(subject.find_or_initialize_service('prometheus')).to be_a(PrometheusService)
+ expect(subject.find_or_initialize_service('prometheus').api_url).to be_nil
+ end
+ end
end
describe '.for_group' do
@@ -6005,119 +6025,6 @@ describe Project do
end
end
- describe '#validate_jira_import_settings!' do
- include JiraServiceHelper
-
- let_it_be(:project, reload: true) { create(:project) }
-
- shared_examples 'raise Jira import error' do |message|
- it 'returns error' do
- expect { subject }.to raise_error(Projects::ImportService::Error, message)
- end
- end
-
- shared_examples 'jira configuration base checks' do
- context 'when feature flag is disabled' do
- before do
- stub_feature_flags(jira_issue_import: false)
- end
-
- it_behaves_like 'raise Jira import error', 'Jira import feature is disabled.'
- end
-
- context 'when feature flag is enabled' do
- before do
- stub_feature_flags(jira_issue_import: true)
- end
-
- context 'when Jira service was not setup' do
- it_behaves_like 'raise Jira import error', 'Jira integration not configured.'
- end
-
- context 'when Jira service exists' do
- let!(:jira_service) { create(:jira_service, project: project, active: true) }
-
- context 'when Jira connection is not valid' do
- before do
- WebMock.stub_request(:get, 'https://jira.example.com/rest/api/2/serverInfo')
- .to_raise(JIRA::HTTPError.new(double(message: 'Some failure.')))
- end
-
- it_behaves_like 'raise Jira import error', 'Unable to connect to the Jira instance. Please check your Jira integration configuration.'
- end
- end
- end
- end
-
- before do
- stub_jira_service_test
- end
-
- context 'without user param' do
- subject { project.validate_jira_import_settings! }
-
- it_behaves_like 'jira configuration base checks'
-
- context 'when jira connection is valid' do
- let!(:jira_service) { create(:jira_service, project: project, active: true) }
-
- it 'does not return any error' do
- expect { subject }.not_to raise_error
- end
- end
- end
-
- context 'with user param provided' do
- let_it_be(:user) { create(:user) }
-
- subject { project.validate_jira_import_settings!(user: user) }
-
- context 'when user has permission to run import' do
- before do
- project.add_maintainer(user)
- end
-
- it_behaves_like 'jira configuration base checks'
- end
-
- context 'when feature flag is enabled' do
- before do
- stub_feature_flags(jira_issue_import: true)
- end
-
- context 'when user does not have permissions to run the import' do
- before do
- create(:jira_service, project: project, active: true)
-
- project.add_developer(user)
- end
-
- it_behaves_like 'raise Jira import error', 'You do not have permissions to run the import.'
- end
-
- context 'when user has permission to run import' do
- before do
- project.add_maintainer(user)
- end
-
- let!(:jira_service) { create(:jira_service, project: project, active: true) }
-
- context 'when issues feature is disabled' do
- let_it_be(:project, reload: true) { create(:project, :issues_disabled) }
-
- it_behaves_like 'raise Jira import error', 'Cannot import because issues are not available in this project.'
- end
-
- context 'when everything is ok' do
- it 'does not return any error' do
- expect { subject }.not_to raise_error
- end
- end
- end
- end
- end
- end
-
describe '#design_management_enabled?' do
let(:project) { build(:project) }
@@ -6157,6 +6064,14 @@ describe Project do
it { is_expected.not_to include(user) }
end
+ describe "#metrics_setting" do
+ let(:project) { build(:project) }
+
+ it 'creates setting if it does not exist' do
+ expect(project.metrics_setting).to be_an_instance_of(ProjectMetricsSetting)
+ end
+ end
+
def finish_job(export_job)
export_job.start
export_job.finish
diff --git a/spec/models/project_team_spec.rb b/spec/models/project_team_spec.rb
index d62fa58739a..24652a1d706 100644
--- a/spec/models/project_team_spec.rb
+++ b/spec/models/project_team_spec.rb
@@ -96,11 +96,9 @@ describe ProjectTeam do
it 'returns invited members of a group' do
group_member = create(:group_member)
-
- project.project_group_links.create!(
- group: group_member.group,
- group_access: Gitlab::Access::GUEST
- )
+ create(:project_group_link, group: group_member.group,
+ project: project,
+ group_access: Gitlab::Access::GUEST)
expect(project.team.members)
.to contain_exactly(group_member.user, project.owner)
@@ -108,11 +106,9 @@ describe ProjectTeam do
it 'returns invited members of a group of a specified level' do
group_member = create(:group_member)
-
- project.project_group_links.create!(
- group: group_member.group,
- group_access: Gitlab::Access::REPORTER
- )
+ create(:project_group_link, group: group_member.group,
+ project: project,
+ group_access: Gitlab::Access::REPORTER)
expect(project.team.guests).to be_empty
expect(project.team.reporters).to contain_exactly(group_member.user)
diff --git a/spec/models/project_wiki_spec.rb b/spec/models/project_wiki_spec.rb
index a4181e3be9a..aff2b248642 100644
--- a/spec/models/project_wiki_spec.rb
+++ b/spec/models/project_wiki_spec.rb
@@ -27,8 +27,8 @@ describe ProjectWiki do
subject.create_page('Test Page', 'This is content')
wiki_container.reload
- expect(wiki_container.last_activity_at).to be_within(1.minute).of(Time.now)
- expect(wiki_container.last_repository_updated_at).to be_within(1.minute).of(Time.now)
+ expect(wiki_container.last_activity_at).to be_within(1.minute).of(Time.current)
+ expect(wiki_container.last_repository_updated_at).to be_within(1.minute).of(Time.current)
end
end
end
diff --git a/spec/models/prometheus_alert_event_spec.rb b/spec/models/prometheus_alert_event_spec.rb
index 040113643dd..85e57cb08c3 100644
--- a/spec/models/prometheus_alert_event_spec.rb
+++ b/spec/models/prometheus_alert_event_spec.rb
@@ -49,7 +49,7 @@ describe PrometheusAlertEvent do
describe 'transaction' do
describe 'fire' do
- let(:started_at) { Time.now }
+ let(:started_at) { Time.current }
context 'when status is none' do
subject { build(:prometheus_alert_event, :none) }
@@ -75,7 +75,7 @@ describe PrometheusAlertEvent do
end
describe 'resolve' do
- let(:ended_at) { Time.now }
+ let(:ended_at) { Time.current }
context 'when firing' do
subject { build(:prometheus_alert_event) }
diff --git a/spec/models/push_event_spec.rb b/spec/models/push_event_spec.rb
index 8682e1c797b..5c1802669c1 100644
--- a/spec/models/push_event_spec.rb
+++ b/spec/models/push_event_spec.rb
@@ -118,8 +118,8 @@ describe PushEvent do
end
describe '.sti_name' do
- it 'returns Event::PUSHED' do
- expect(described_class.sti_name).to eq(Event::PUSHED)
+ it 'returns the integer representation of the :pushed event action' do
+ expect(described_class.sti_name).to eq(Event.actions[:pushed])
end
end
@@ -299,7 +299,7 @@ describe PushEvent do
describe '#validate_push_action' do
it 'adds an error when the action is not PUSHED' do
- event.action = Event::CREATED
+ event.action = :created
event.validate_push_action
expect(event.errors.count).to eq(1)
diff --git a/spec/models/release_spec.rb b/spec/models/release_spec.rb
index d72fd137f3f..716e7dc786e 100644
--- a/spec/models/release_spec.rb
+++ b/spec/models/release_spec.rb
@@ -94,14 +94,6 @@ RSpec.describe Release do
describe 'evidence' do
let(:release_with_evidence) { create(:release, :with_evidence, project: project) }
- describe '#create_evidence!' do
- context 'when a release is created' do
- it 'creates one Evidence object too' do
- expect { release_with_evidence }.to change(Releases::Evidence, :count).by(1)
- end
- end
- end
-
context 'when a release is deleted' do
it 'also deletes the associated evidence' do
release_with_evidence
diff --git a/spec/models/releases/evidence_spec.rb b/spec/models/releases/evidence_spec.rb
index d38d2021117..927e2e9bbe6 100644
--- a/spec/models/releases/evidence_spec.rb
+++ b/spec/models/releases/evidence_spec.rb
@@ -5,83 +5,21 @@ require 'spec_helper'
describe Releases::Evidence do
let_it_be(:project) { create(:project) }
let(:release) { create(:release, project: project) }
- let(:schema_file) { 'evidences/evidence' }
- let(:summary_json) { described_class.last.summary.to_json }
describe 'associations' do
it { is_expected.to belong_to(:release) }
end
- describe 'summary_sha' do
- it 'returns nil if summary is nil' do
- expect(build(:evidence, summary: nil).summary_sha).to be_nil
- end
- end
-
- describe '#generate_summary_and_sha' do
- before do
- described_class.create!(release: release)
- end
-
- context 'when a release name is not provided' do
- let(:release) { create(:release, project: project, name: nil) }
-
- it 'creates a valid JSON object' do
- expect(release.name).to eq(release.tag)
- expect(summary_json).to match_schema(schema_file)
- end
- end
-
- context 'when a release is associated to a milestone' do
- let(:milestone) { create(:milestone, project: project) }
- let(:release) { create(:release, project: project, milestones: [milestone]) }
-
- context 'when a milestone has no issue associated with it' do
- it 'creates a valid JSON object' do
- expect(milestone.issues).to be_empty
- expect(summary_json).to match_schema(schema_file)
- end
- end
-
- context 'when a milestone has no description' do
- let(:milestone) { create(:milestone, project: project, description: nil) }
-
- it 'creates a valid JSON object' do
- expect(milestone.description).to be_nil
- expect(summary_json).to match_schema(schema_file)
- end
- end
-
- context 'when a milestone has no due_date' do
- let(:milestone) { create(:milestone, project: project, due_date: nil) }
-
- it 'creates a valid JSON object' do
- expect(milestone.due_date).to be_nil
- expect(summary_json).to match_schema(schema_file)
- end
- end
-
- context 'when a milestone has an issue' do
- context 'when the issue has no description' do
- let(:issue) { create(:issue, project: project, description: nil, state: 'closed') }
-
- before do
- milestone.issues << issue
- end
+ it 'filters out issues from summary json' do
+ milestone = create(:milestone, project: project, due_date: nil)
+ issue = create(:issue, project: project, description: nil, state: 'closed')
+ milestone.issues << issue
+ release.milestones << milestone
- it 'creates a valid JSON object' do
- expect(milestone.issues.first.description).to be_nil
- expect(summary_json).to match_schema(schema_file)
- end
- end
- end
- end
+ ::Releases::CreateEvidenceService.new(release).execute
+ evidence = release.evidences.last
- context 'when a release is not associated to any milestone' do
- it 'creates a valid JSON object' do
- expect(release.milestones).to be_empty
- expect(summary_json).to match_schema(schema_file)
- end
- end
+ expect(evidence.read_attribute(:summary)["release"]["milestones"].first["issues"].first["title"]).to be_present
+ expect(evidence.summary["release"]["milestones"].first["issues"]).to be_nil
end
end
diff --git a/spec/models/remote_mirror_spec.rb b/spec/models/remote_mirror_spec.rb
index a87cdcf9344..6d163a16e63 100644
--- a/spec/models/remote_mirror_spec.rb
+++ b/spec/models/remote_mirror_spec.rb
@@ -306,7 +306,7 @@ describe RemoteMirror, :mailer do
context 'when it did not update in the last minute' do
it 'schedules a RepositoryUpdateRemoteMirrorWorker to run now' do
- expect(RepositoryUpdateRemoteMirrorWorker).to receive(:perform_async).with(remote_mirror.id, Time.now)
+ expect(RepositoryUpdateRemoteMirrorWorker).to receive(:perform_async).with(remote_mirror.id, Time.current)
remote_mirror.sync
end
@@ -314,9 +314,9 @@ describe RemoteMirror, :mailer do
context 'when it did update in the last minute' do
it 'schedules a RepositoryUpdateRemoteMirrorWorker to run in the next minute' do
- remote_mirror.last_update_started_at = Time.now - 30.seconds
+ remote_mirror.last_update_started_at = Time.current - 30.seconds
- expect(RepositoryUpdateRemoteMirrorWorker).to receive(:perform_in).with(RemoteMirror::PROTECTED_BACKOFF_DELAY, remote_mirror.id, Time.now)
+ expect(RepositoryUpdateRemoteMirrorWorker).to receive(:perform_in).with(RemoteMirror::PROTECTED_BACKOFF_DELAY, remote_mirror.id, Time.current)
remote_mirror.sync
end
@@ -330,7 +330,7 @@ describe RemoteMirror, :mailer do
context 'when it did not update in the last 5 minutes' do
it 'schedules a RepositoryUpdateRemoteMirrorWorker to run now' do
- expect(RepositoryUpdateRemoteMirrorWorker).to receive(:perform_async).with(remote_mirror.id, Time.now)
+ expect(RepositoryUpdateRemoteMirrorWorker).to receive(:perform_async).with(remote_mirror.id, Time.current)
remote_mirror.sync
end
@@ -338,9 +338,9 @@ describe RemoteMirror, :mailer do
context 'when it did update within the last 5 minutes' do
it 'schedules a RepositoryUpdateRemoteMirrorWorker to run in the next 5 minutes' do
- remote_mirror.last_update_started_at = Time.now - 30.seconds
+ remote_mirror.last_update_started_at = Time.current - 30.seconds
- expect(RepositoryUpdateRemoteMirrorWorker).to receive(:perform_in).with(RemoteMirror::UNPROTECTED_BACKOFF_DELAY, remote_mirror.id, Time.now)
+ expect(RepositoryUpdateRemoteMirrorWorker).to receive(:perform_in).with(RemoteMirror::UNPROTECTED_BACKOFF_DELAY, remote_mirror.id, Time.current)
remote_mirror.sync
end
@@ -377,9 +377,9 @@ describe RemoteMirror, :mailer do
let(:remote_mirror) { create(:project, :repository, :remote_mirror).remote_mirrors.first }
it 'resets all the columns when URL changes' do
- remote_mirror.update(last_error: Time.now,
- last_update_at: Time.now,
- last_successful_update_at: Time.now,
+ remote_mirror.update(last_error: Time.current,
+ last_update_at: Time.current,
+ last_successful_update_at: Time.current,
update_status: 'started',
error_notification_sent: true)
@@ -394,14 +394,14 @@ describe RemoteMirror, :mailer do
describe '#updated_since?' do
let(:remote_mirror) { create(:project, :repository, :remote_mirror).remote_mirrors.first }
- let(:timestamp) { Time.now - 5.minutes }
+ let(:timestamp) { Time.current - 5.minutes }
around do |example|
Timecop.freeze { example.run }
end
before do
- remote_mirror.update(last_update_started_at: Time.now)
+ remote_mirror.update(last_update_started_at: Time.current)
end
context 'when remote mirror does not have status failed' do
@@ -410,7 +410,7 @@ describe RemoteMirror, :mailer do
end
it 'returns false when last update started before the timestamp' do
- expect(remote_mirror.updated_since?(Time.now + 5.minutes)).to be false
+ expect(remote_mirror.updated_since?(Time.current + 5.minutes)).to be false
end
end
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index be626dd6e32..c698b40a4c0 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -88,8 +88,8 @@ describe Repository do
subject { repository.tags_sorted_by('updated_desc').map(&:name) }
before do
- double_first = double(committed_date: Time.now)
- double_last = double(committed_date: Time.now - 1.second)
+ double_first = double(committed_date: Time.current)
+ double_last = double(committed_date: Time.current - 1.second)
allow(tag_a).to receive(:dereferenced_target).and_return(double_first)
allow(tag_b).to receive(:dereferenced_target).and_return(double_last)
@@ -103,8 +103,8 @@ describe Repository do
subject { repository.tags_sorted_by('updated_asc').map(&:name) }
before do
- double_first = double(committed_date: Time.now - 1.second)
- double_last = double(committed_date: Time.now)
+ double_first = double(committed_date: Time.current - 1.second)
+ double_last = double(committed_date: Time.current)
allow(tag_a).to receive(:dereferenced_target).and_return(double_last)
allow(tag_b).to receive(:dereferenced_target).and_return(double_first)
@@ -125,8 +125,8 @@ describe Repository do
rugged_repo(repository).tags.create(annotated_tag_name, 'a48e4fc218069f68ef2e769dd8dfea3991362175', options)
- double_first = double(committed_date: Time.now - 1.second)
- double_last = double(committed_date: Time.now)
+ double_first = double(committed_date: Time.current - 1.second)
+ double_last = double(committed_date: Time.current)
allow(tag_a).to receive(:dereferenced_target).and_return(double_last)
allow(tag_b).to receive(:dereferenced_target).and_return(double_first)
@@ -227,7 +227,7 @@ describe Repository do
tree_builder = Rugged::Tree::Builder.new(rugged)
tree_builder.insert({ oid: blob_id, name: "hello\x80world", filemode: 0100644 })
tree_id = tree_builder.write
- user = { email: "jcai@gitlab.com", time: Time.now, name: "John Cai" }
+ user = { email: "jcai@gitlab.com", time: Time.current.to_time, name: "John Cai" }
Rugged::Commit.create(rugged, message: 'some commit message', parents: [rugged.head.target.oid], tree: tree_id, committer: user, author: user)
end
@@ -974,7 +974,7 @@ describe Repository do
end
it 'returns nil' do
- expect(Rails.logger).to receive(:info).with("Remove remote job failed to create for #{project.id} with remote name joe.")
+ expect(Gitlab::AppLogger).to receive(:info).with("Remove remote job failed to create for #{project.id} with remote name joe.")
expect(repository.async_remove_remote('joe')).to be_nil
end
@@ -1446,17 +1446,13 @@ describe Repository do
let(:empty_repository) { create(:project_empty_repo).repository }
it 'returns empty array for an empty repository' do
- # rubocop:disable Style/WordArray
- expect(empty_repository.blobs_at(['master', 'foobar'])).to eq([])
- # rubocop:enable Style/WordArray
+ expect(empty_repository.blobs_at(%w[master foobar])).to eq([])
end
it 'returns blob array for a non-empty repository' do
repository.create_file(User.last, 'foobar', 'CONTENT', message: 'message', branch_name: 'master')
- # rubocop:disable Style/WordArray
- blobs = repository.blobs_at([['master', 'foobar']])
- # rubocop:enable Style/WordArray
+ blobs = repository.blobs_at([%w[master foobar]])
expect(blobs.first.name).to eq('foobar')
expect(blobs.size).to eq(1)
diff --git a/spec/models/resource_label_event_spec.rb b/spec/models/resource_label_event_spec.rb
index a1a2150f461..6a235d3aa17 100644
--- a/spec/models/resource_label_event_spec.rb
+++ b/spec/models/resource_label_event_spec.rb
@@ -96,4 +96,48 @@ RSpec.describe ResourceLabelEvent, type: :model do
expect(subject.outdated_markdown?).to be false
end
end
+
+ describe '.visible_to_user?' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:issue_project) { create(:project) }
+ let_it_be(:issue) { create(:issue, project: issue_project) }
+
+ subject { described_class.visible_to_user?(user, issue.resource_label_events.inc_relations) }
+
+ it 'returns events with labels accessible by user' do
+ label = create(:label, project: issue_project)
+ event = create_event(label)
+ issue_project.add_guest(user)
+
+ expect(subject).to eq [event]
+ end
+
+ it 'filters events with public project labels if issues and MRs are private' do
+ project = create(:project, :public, :issues_private, :merge_requests_private)
+ label = create(:label, project: project)
+ create_event(label)
+
+ expect(subject).to be_empty
+ end
+
+ it 'filters events with project labels not accessible by user' do
+ project = create(:project, :private)
+ label = create(:label, project: project)
+ create_event(label)
+
+ expect(subject).to be_empty
+ end
+
+ it 'filters events with group labels not accessible by user' do
+ group = create(:group, :private)
+ label = create(:group_label, group: group)
+ create_event(label)
+
+ expect(subject).to be_empty
+ end
+
+ def create_event(label)
+ create(:resource_label_event, issue: issue, label: label)
+ end
+ end
end
diff --git a/spec/models/resource_milestone_event_spec.rb b/spec/models/resource_milestone_event_spec.rb
index 3f8d8b4c1df..66686ec77d0 100644
--- a/spec/models/resource_milestone_event_spec.rb
+++ b/spec/models/resource_milestone_event_spec.rb
@@ -95,4 +95,34 @@ describe ResourceMilestoneEvent, type: :model do
end
end
end
+
+ describe '#milestone_parent' do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:group) { create(:group) }
+
+ let(:milestone) { create(:milestone, project: project) }
+ let(:event) { create(:resource_milestone_event, milestone: milestone) }
+
+ context 'when milestone parent is project' do
+ it 'returns the expected parent' do
+ expect(event.milestone_parent).to eq(project)
+ end
+ end
+
+ context 'when milestone parent is group' do
+ let(:milestone) { create(:milestone, group: group) }
+
+ it 'returns the expected parent' do
+ expect(event.milestone_parent).to eq(group)
+ end
+ end
+
+ context 'when milestone is nil' do
+ let(:event) { create(:resource_milestone_event, milestone: nil) }
+
+ it 'returns nil' do
+ expect(event.milestone_parent).to be_nil
+ end
+ end
+ end
end
diff --git a/spec/models/review_spec.rb b/spec/models/review_spec.rb
new file mode 100644
index 00000000000..9dd8b90feee
--- /dev/null
+++ b/spec/models/review_spec.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Review do
+ describe 'associations' do
+ it { is_expected.to belong_to(:author).class_name('User').with_foreign_key(:author_id).inverse_of(:reviews) }
+ it { is_expected.to belong_to(:merge_request).inverse_of(:reviews).touch(false) }
+ it { is_expected.to belong_to(:project).inverse_of(:reviews) }
+
+ it { is_expected.to have_many(:notes).order(:id).inverse_of(:review) }
+ end
+
+ describe 'modules' do
+ it { is_expected.to include_module(Participable) }
+ it { is_expected.to include_module(Mentionable) }
+ end
+
+ describe '#all_references' do
+ it 'returns an extractor with the correct referenced users' do
+ user1 = create(:user, username: "foo")
+ user2 = create(:user, username: "bar")
+ review = create(:review)
+ project = review.project
+ author = review.author
+
+ create(:note, review: review, project: project, author: author, note: "cc @foo @non_existent")
+ create(:note, review: review, project: project, author: author, note: "cc @bar")
+
+ expect(review.all_references(author).users).to match_array([user1, user2])
+ end
+ end
+
+ describe '#participants' do
+ it 'includes the review author' do
+ project = create(:project, :public)
+ merge_request = create(:merge_request, source_project: project)
+ review = create(:review, project: project, merge_request: merge_request)
+ create(:note, review: review, noteable: merge_request, project: project, author: review.author)
+
+ expect(review.participants).to include(review.author)
+ end
+ end
+end
diff --git a/spec/models/service_spec.rb b/spec/models/service_spec.rb
index 106f8def42d..8698a6cf3d3 100644
--- a/spec/models/service_spec.rb
+++ b/spec/models/service_spec.rb
@@ -114,6 +114,20 @@ describe Service do
expect(described_class.confidential_note_hooks.count).to eq 0
end
end
+
+ describe '.alert_hooks' do
+ it 'includes services where alert_events is true' do
+ create(:service, active: true, alert_events: true)
+
+ expect(described_class.alert_hooks.count).to eq 1
+ end
+
+ it 'excludes services where alert_events is false' do
+ create(:service, active: true, alert_events: false)
+
+ expect(described_class.alert_hooks.count).to eq 0
+ end
+ end
end
describe "Test Button" do
@@ -264,20 +278,32 @@ describe Service do
end
end
- describe '.build_from_template' do
- context 'when template is invalid' do
- it 'sets service template to inactive when template is invalid' do
- template = build(:prometheus_service, template: true, active: true, properties: {})
- template.save(validate: false)
+ describe '.build_from_integration' do
+ context 'when integration is invalid' do
+ let(:integration) do
+ build(:prometheus_service, :template, active: true, properties: {})
+ .tap { |integration| integration.save(validate: false) }
+ end
- service = described_class.build_from_template(project.id, template)
+ it 'sets service to inactive' do
+ service = described_class.build_from_integration(project.id, integration)
expect(service).to be_valid
expect(service.active).to be false
end
end
- describe 'build issue tracker from a template' do
+ context 'when integration is an instance' do
+ let(:integration) { create(:jira_service, :instance) }
+
+ it 'sets inherit_from_id from integration' do
+ service = described_class.build_from_integration(project.id, integration)
+
+ expect(service.inherit_from_id).to eq(integration.id)
+ end
+ end
+
+ describe 'build issue tracker from an integration' do
let(:title) { 'custom title' }
let(:description) { 'custom description' }
let(:url) { 'http://jira.example.com' }
@@ -291,9 +317,9 @@ describe Service do
}
end
- shared_examples 'service creation from a template' do
+ shared_examples 'service creation from an integration' do
it 'creates a correct service' do
- service = described_class.build_from_template(project.id, template)
+ service = described_class.build_from_integration(project.id, integration)
expect(service).to be_active
expect(service.title).to eq(title)
@@ -302,36 +328,38 @@ describe Service do
expect(service.api_url).to eq(api_url)
expect(service.username).to eq(username)
expect(service.password).to eq(password)
+ expect(service.template).to eq(false)
+ expect(service.instance).to eq(false)
end
end
# this will be removed as part of https://gitlab.com/gitlab-org/gitlab/issues/29404
context 'when data are stored in properties' do
let(:properties) { data_params.merge(title: title, description: description) }
- let!(:template) do
+ let!(:integration) do
create(:jira_service, :without_properties_callback, template: true, properties: properties.merge(additional: 'something'))
end
- it_behaves_like 'service creation from a template'
+ it_behaves_like 'service creation from an integration'
end
context 'when data are stored in separated fields' do
- let(:template) do
+ let(:integration) do
create(:jira_service, :template, data_params.merge(properties: {}, title: title, description: description))
end
- it_behaves_like 'service creation from a template'
+ it_behaves_like 'service creation from an integration'
end
context 'when data are stored in both properties and separated fields' do
let(:properties) { data_params.merge(title: title, description: description) }
- let(:template) do
+ let(:integration) do
create(:jira_service, :without_properties_callback, active: true, template: true, properties: properties).tap do |service|
create(:jira_tracker_data, data_params.merge(service: service))
end
end
- it_behaves_like 'service creation from a template'
+ it_behaves_like 'service creation from an integration'
end
end
end
diff --git a/spec/models/snippet_input_action_collection_spec.rb b/spec/models/snippet_input_action_collection_spec.rb
new file mode 100644
index 00000000000..ef18ab5a810
--- /dev/null
+++ b/spec/models/snippet_input_action_collection_spec.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe SnippetInputActionCollection do
+ let(:action_name) { 'create' }
+ let(:action) { { action: action_name, file_path: 'foo', content: 'bar', previous_path: 'foobar' } }
+ let(:data) { [action, action] }
+
+ it { is_expected.to delegate_method(:empty?).to(:actions) }
+ it { is_expected.to delegate_method(:any?).to(:actions) }
+ it { is_expected.to delegate_method(:[]).to(:actions) }
+
+ describe '#to_commit_actions' do
+ subject { described_class.new(data).to_commit_actions}
+
+ it 'translates all actions to commit actions' do
+ transformed_action = action.merge(action: action_name.to_sym)
+
+ expect(subject).to eq [transformed_action, transformed_action]
+ end
+ end
+
+ describe '#valid?' do
+ subject { described_class.new(data).valid?}
+
+ it 'returns true' do
+ expect(subject).to be true
+ end
+
+ context 'when any of the actions is invalid' do
+ let(:data) { [action, { action: 'foo' }, action]}
+
+ it 'returns false' do
+ expect(subject).to be false
+ end
+ end
+ end
+
+ context 'when allowed_actions param is passed' do
+ it 'builds SnippetInputAction with that param' do
+ expect(SnippetInputAction).to receive(:new).with(hash_including(allowed_actions: :create))
+
+ described_class.new([action], allowed_actions: :create)
+ end
+ end
+end
diff --git a/spec/models/snippet_input_action_spec.rb b/spec/models/snippet_input_action_spec.rb
new file mode 100644
index 00000000000..5e379a48171
--- /dev/null
+++ b/spec/models/snippet_input_action_spec.rb
@@ -0,0 +1,89 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe SnippetInputAction do
+ describe 'validations' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:action, :file_path, :content, :previous_path, :allowed_actions, :is_valid, :invalid_field) do
+ :create | 'foobar' | 'foobar' | 'foobar' | nil | true | nil
+ :move | 'foobar' | 'foobar' | 'foobar' | nil | true | nil
+ :delete | 'foobar' | 'foobar' | 'foobar' | nil | true | nil
+ :update | 'foobar' | 'foobar' | 'foobar' | nil | true | nil
+ :foo | 'foobar' | 'foobar' | 'foobar' | nil | false | :action
+ 'create' | 'foobar' | 'foobar' | 'foobar' | nil | true | nil
+ 'move' | 'foobar' | 'foobar' | 'foobar' | nil | true | nil
+ 'delete' | 'foobar' | 'foobar' | 'foobar' | nil | true | nil
+ 'update' | 'foobar' | 'foobar' | 'foobar' | nil | true | nil
+ 'foo' | 'foobar' | 'foobar' | 'foobar' | nil | false | :action
+ nil | 'foobar' | 'foobar' | 'foobar' | nil | false | :action
+ '' | 'foobar' | 'foobar' | 'foobar' | nil | false | :action
+ :move | 'foobar' | 'foobar' | nil | nil | false | :previous_path
+ :move | 'foobar' | 'foobar' | '' | nil | false | :previous_path
+ :create | 'foobar' | nil | 'foobar' | nil | false | :content
+ :create | 'foobar' | '' | 'foobar' | nil | false | :content
+ :create | nil | 'foobar' | 'foobar' | nil | false | :file_path
+ :create | '' | 'foobar' | 'foobar' | nil | false | :file_path
+ :update | 'foobar' | nil | 'foobar' | nil | false | :content
+ :update | 'foobar' | '' | 'foobar' | nil | false | :content
+ :update | 'other' | 'foobar' | 'foobar' | nil | false | :file_path
+ :update | 'foobar' | 'foobar' | nil | nil | true | nil
+ :update | 'foobar' | 'foobar' | '' | nil | true | nil
+ :update | 'foobar' | 'foobar' | '' | :update | true | nil
+ :update | 'foobar' | 'foobar' | '' | 'update' | true | nil
+ :update | 'foobar' | 'foobar' | '' | [:update] | true | nil
+ :update | 'foobar' | 'foobar' | '' | [:update, :create] | true | nil
+ :update | 'foobar' | 'foobar' | '' | :create | false | :action
+ :update | 'foobar' | 'foobar' | '' | 'create' | false | :action
+ :update | 'foobar' | 'foobar' | '' | [:create] | false | :action
+ :foo | 'foobar' | 'foobar' | '' | :foo | false | :action
+ end
+
+ with_them do
+ subject { described_class.new(action: action, file_path: file_path, content: content, previous_path: previous_path, allowed_actions: allowed_actions) }
+
+ specify do
+ expect(subject.valid?).to be is_valid
+
+ unless is_valid
+ expect(subject.errors).to include(invalid_field)
+ end
+ end
+ end
+ end
+
+ describe '#to_commit_action' do
+ let(:action) { 'create' }
+ let(:file_path) { 'foo' }
+ let(:content) { 'bar' }
+ let(:previous_path) { 'previous_path' }
+ let(:options) { { action: action, file_path: file_path, content: content, previous_path: previous_path } }
+ let(:expected_options) { options.merge(action: action.to_sym) }
+
+ subject { described_class.new(options).to_commit_action }
+
+ it 'transforms attributes to commit action' do
+ expect(subject).to eq(expected_options)
+ end
+
+ context 'action is update' do
+ let(:action) { 'update' }
+
+ context 'when previous_path is present' do
+ it 'returns the existing previous_path' do
+ expect(subject).to eq(expected_options)
+ end
+ end
+
+ context 'when previous_path is not present' do
+ let(:previous_path) { nil }
+ let(:expected_options) { options.merge(action: action.to_sym, previous_path: file_path) }
+
+ it 'assigns the file_path to the previous_path' do
+ expect(subject).to eq(expected_options)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/models/todo_spec.rb b/spec/models/todo_spec.rb
index e125f58399e..bda89fc01f3 100644
--- a/spec/models/todo_spec.rb
+++ b/spec/models/todo_spec.rb
@@ -100,6 +100,20 @@ describe Todo do
end
end
+ describe '#for_alert?' do
+ it 'returns true when target is a Alert' do
+ subject.target_type = 'AlertManagement::Alert'
+
+ expect(subject.for_alert?).to eq(true)
+ end
+
+ it 'returns false when target is not a Alert' do
+ subject.target_type = 'Issue'
+
+ expect(subject.for_alert?).to eq(false)
+ end
+ end
+
describe '#target' do
context 'for commits' do
let(:project) { create(:project, :repository) }
@@ -393,10 +407,10 @@ describe Todo do
end
end
- describe '.update_state' do
+ describe '.batch_update' do
it 'updates the state of todos' do
todo = create(:todo, :pending)
- ids = described_class.update_state(:done)
+ ids = described_class.batch_update(state: :done)
todo.reload
@@ -407,16 +421,16 @@ describe Todo do
it 'does not update todos that already have the given state' do
create(:todo, :pending)
- expect(described_class.update_state(:pending)).to be_empty
+ expect(described_class.batch_update(state: :pending)).to be_empty
end
it 'updates updated_at' do
create(:todo, :pending)
Timecop.freeze(1.day.from_now) do
- expected_update_date = Time.now.utc
+ expected_update_date = Time.current.utc
- ids = described_class.update_state(:done)
+ ids = described_class.batch_update(state: :done)
expect(Todo.where(id: ids).map(&:updated_at)).to all(be_like_time(expected_update_date))
end
diff --git a/spec/models/user_interacted_project_spec.rb b/spec/models/user_interacted_project_spec.rb
index e2c485343ae..83c66bf1969 100644
--- a/spec/models/user_interacted_project_spec.rb
+++ b/spec/models/user_interacted_project_spec.rb
@@ -8,7 +8,7 @@ describe UserInteractedProject do
let(:event) { build(:event) }
- Event::ACTIONS.each do |action|
+ Event.actions.each_key do |action|
context "for all actions (event types)" do
let(:event) { build(:event, action: action) }
@@ -44,21 +44,6 @@ describe UserInteractedProject do
end
end
- describe '.available?' do
- before do
- described_class.instance_variable_set('@available_flag', nil)
- end
-
- it 'checks schema version and properly caches positive result' do
- expect(ActiveRecord::Migrator).to receive(:current_version).and_return(described_class::REQUIRED_SCHEMA_VERSION - 1 - rand(1000))
- expect(described_class.available?).to be_falsey
- expect(ActiveRecord::Migrator).to receive(:current_version).and_return(described_class::REQUIRED_SCHEMA_VERSION + rand(1000))
- expect(described_class.available?).to be_truthy
- expect(ActiveRecord::Migrator).not_to receive(:current_version)
- expect(described_class.available?).to be_truthy # cached response
- end
- end
-
it { is_expected.to validate_presence_of(:project_id) }
it { is_expected.to validate_presence_of(:user_id) }
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index e82e8c1a21d..dd4b174a38f 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -23,8 +23,41 @@ describe User do
describe 'delegations' do
it { is_expected.to delegate_method(:path).to(:namespace).with_prefix }
+ it { is_expected.to delegate_method(:notes_filter_for).to(:user_preference) }
+ it { is_expected.to delegate_method(:set_notes_filter).to(:user_preference) }
+
+ it { is_expected.to delegate_method(:first_day_of_week).to(:user_preference) }
+ it { is_expected.to delegate_method(:first_day_of_week=).to(:user_preference).with_arguments(:args) }
+
+ it { is_expected.to delegate_method(:timezone).to(:user_preference) }
+ it { is_expected.to delegate_method(:timezone=).to(:user_preference).with_arguments(:args) }
+
+ it { is_expected.to delegate_method(:time_display_relative).to(:user_preference) }
+ it { is_expected.to delegate_method(:time_display_relative=).to(:user_preference).with_arguments(:args) }
+
+ it { is_expected.to delegate_method(:time_format_in_24h).to(:user_preference) }
+ it { is_expected.to delegate_method(:time_format_in_24h=).to(:user_preference).with_arguments(:args) }
+
+ it { is_expected.to delegate_method(:show_whitespace_in_diffs).to(:user_preference) }
+ it { is_expected.to delegate_method(:show_whitespace_in_diffs=).to(:user_preference).with_arguments(:args) }
+
it { is_expected.to delegate_method(:tab_width).to(:user_preference) }
- it { is_expected.to delegate_method(:tab_width=).to(:user_preference).with_arguments(5) }
+ it { is_expected.to delegate_method(:tab_width=).to(:user_preference).with_arguments(:args) }
+
+ it { is_expected.to delegate_method(:sourcegraph_enabled).to(:user_preference) }
+ it { is_expected.to delegate_method(:sourcegraph_enabled=).to(:user_preference).with_arguments(:args) }
+
+ it { is_expected.to delegate_method(:setup_for_company).to(:user_preference) }
+ it { is_expected.to delegate_method(:setup_for_company=).to(:user_preference).with_arguments(:args) }
+
+ 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(:job_title).to(:user_detail).allow_nil }
+ it { is_expected.to delegate_method(:job_title=).to(:user_detail).with_arguments(:args).allow_nil }
end
describe 'associations' do
@@ -56,6 +89,7 @@ describe User do
it { is_expected.to have_many(:custom_attributes).class_name('UserCustomAttribute') }
it { is_expected.to have_many(:releases).dependent(:nullify) }
it { is_expected.to have_many(:metrics_users_starred_dashboards).inverse_of(:user) }
+ it { is_expected.to have_many(:reviews).inverse_of(:author) }
describe "#bio" do
it 'syncs bio with `user_details.bio` on create' do
@@ -816,6 +850,7 @@ describe User do
let_it_be(:expired_token) { create(:personal_access_token, user: user1, expires_at: 2.days.ago) }
let_it_be(:revoked_token) { create(:personal_access_token, user: user1, revoked: true) }
+ let_it_be(:impersonation_token) { create(:personal_access_token, :impersonation, user: user1, expires_at: 2.days.from_now) }
let_it_be(:valid_token_and_notified) { create(:personal_access_token, user: user2, expires_at: 2.days.from_now, expire_notification_delivered: true) }
let_it_be(:valid_token1) { create(:personal_access_token, user: user2, expires_at: 2.days.from_now) }
let_it_be(:valid_token2) { create(:personal_access_token, user: user2, expires_at: 2.days.from_now) }
@@ -967,7 +1002,7 @@ describe User do
end
it 'has only one email association' do
- expect(user.emails.size).to be(1)
+ expect(user.emails.size).to eq(1)
end
end
end
@@ -1381,7 +1416,7 @@ describe User do
end
it 'is true when sent less than one minute ago' do
- user = build_stubbed(:user, reset_password_sent_at: Time.now)
+ user = build_stubbed(:user, reset_password_sent_at: Time.current)
expect(user.recently_sent_password_reset?).to eq true
end
@@ -2157,7 +2192,7 @@ describe User do
describe '#all_emails' do
let(:user) { create(:user) }
- let!(:email_confirmed) { create :email, user: user, confirmed_at: Time.now }
+ let!(:email_confirmed) { create :email, user: user, confirmed_at: Time.current }
let!(:email_unconfirmed) { create :email, user: user }
context 'when `include_private_email` is true' do
@@ -2186,7 +2221,7 @@ describe User do
let(:user) { create(:user) }
it 'returns only confirmed emails' do
- email_confirmed = create :email, user: user, confirmed_at: Time.now
+ email_confirmed = create :email, user: user, confirmed_at: Time.current
create :email, user: user
expect(user.verified_emails).to contain_exactly(
@@ -2226,7 +2261,7 @@ describe User do
let(:user) { create(:user) }
it 'returns true when the email is verified/confirmed' do
- email_confirmed = create :email, user: user, confirmed_at: Time.now
+ email_confirmed = create :email, user: user, confirmed_at: Time.current
create :email, user: user
user.reload
@@ -2350,26 +2385,6 @@ describe User do
end
end
- describe '#ultraauth_user?' do
- it 'is true if provider is ultraauth' do
- user = create(:omniauth_user, provider: 'ultraauth')
-
- expect(user.ultraauth_user?).to be_truthy
- end
-
- it 'is false with othe provider' do
- user = create(:omniauth_user, provider: 'not-ultraauth')
-
- expect(user.ultraauth_user?).to be_falsey
- end
-
- it 'is false if no extern_uid is provided' do
- user = create(:omniauth_user, extern_uid: nil)
-
- expect(user.ldap_user?).to be_falsey
- end
- end
-
describe '#full_website_url' do
let(:user) { create(:user) }
@@ -2863,10 +2878,10 @@ describe User do
it "includes projects shared with user's group" do
user = create(:user)
project = create(:project, :private)
- group = create(:group)
-
- group.add_reporter(user)
- project.project_group_links.create(group: group)
+ group = create(:group) do |group|
+ group.add_reporter(user)
+ end
+ create(:project_group_link, group: group, project: project)
expect(user.authorized_projects).to include(project)
end
@@ -3645,12 +3660,6 @@ describe User do
expect(user.allow_password_authentication_for_web?).to be_falsey
end
-
- it 'returns false for ultraauth user' do
- user = create(:omniauth_user, provider: 'ultraauth')
-
- expect(user.allow_password_authentication_for_web?).to be_falsey
- end
end
describe '#allow_password_authentication_for_git?' do
@@ -3673,12 +3682,6 @@ describe User do
expect(user.allow_password_authentication_for_git?).to be_falsey
end
-
- it 'returns false for ultraauth user' do
- user = create(:omniauth_user, provider: 'ultraauth')
-
- expect(user.allow_password_authentication_for_git?).to be_falsey
- end
end
describe '#assigned_open_merge_requests_count' do
diff --git a/spec/models/web_ide_terminal_spec.rb b/spec/models/web_ide_terminal_spec.rb
new file mode 100644
index 00000000000..4103a26c75a
--- /dev/null
+++ b/spec/models/web_ide_terminal_spec.rb
@@ -0,0 +1,82 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe WebIdeTerminal do
+ let(:build) { create(:ci_build) }
+
+ subject { described_class.new(build) }
+
+ it 'returns the show_path of the build' do
+ expect(subject.show_path).to end_with("/ide_terminals/#{build.id}")
+ end
+
+ it 'returns the retry_path of the build' do
+ expect(subject.retry_path).to end_with("/ide_terminals/#{build.id}/retry")
+ end
+
+ it 'returns the cancel_path of the build' do
+ expect(subject.cancel_path).to end_with("/ide_terminals/#{build.id}/cancel")
+ end
+
+ it 'returns the terminal_path of the build' do
+ expect(subject.terminal_path).to end_with("/jobs/#{build.id}/terminal.ws")
+ end
+
+ it 'returns the proxy_websocket_path of the build' do
+ expect(subject.proxy_websocket_path).to end_with("/jobs/#{build.id}/proxy.ws")
+ end
+
+ describe 'services' do
+ let(:services_with_aliases) do
+ {
+ services: [{ name: 'postgres', alias: 'postgres' },
+ { name: 'docker:stable-dind', alias: 'docker' }]
+ }
+ end
+
+ before do
+ allow(build).to receive(:options).and_return(config)
+ end
+
+ context 'when image does not have an alias' do
+ let(:config) do
+ { image: 'ruby:2.7' }.merge(services_with_aliases)
+ end
+
+ it 'returns services aliases' do
+ expect(subject.services).to eq %w(postgres docker)
+ end
+ end
+
+ context 'when both image and services have aliases' do
+ let(:config) do
+ { image: { name: 'ruby:2.7', alias: 'ruby' } }.merge(services_with_aliases)
+ end
+
+ it 'returns all aliases' do
+ expect(subject.services).to eq %w(postgres docker ruby)
+ end
+ end
+
+ context 'when image and services does not have any alias' do
+ let(:config) do
+ { image: 'ruby:2.7', services: ['postgres'] }
+ end
+
+ it 'returns an empty array' do
+ expect(subject.services).to be_empty
+ end
+ end
+
+ context 'when no image nor services' do
+ let(:config) do
+ { script: %w(echo) }
+ end
+
+ it 'returns an empty array' do
+ expect(subject.services).to be_empty
+ end
+ end
+ end
+end
diff --git a/spec/models/wiki_directory_spec.rb b/spec/models/wiki_directory_spec.rb
index 5fbcccf897e..4cac90786eb 100644
--- a/spec/models/wiki_directory_spec.rb
+++ b/spec/models/wiki_directory_spec.rb
@@ -40,7 +40,7 @@ RSpec.describe WikiDirectory do
it 'returns the relative path to the partial to be used' do
directory = build(:wiki_directory)
- expect(directory.to_partial_path).to eq('projects/wikis/wiki_directory')
+ expect(directory.to_partial_path).to eq('../shared/wikis/wiki_directory')
end
end
end
diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb
index 201dc85daf8..8f2da8ff9a1 100644
--- a/spec/models/wiki_page_spec.rb
+++ b/spec/models/wiki_page_spec.rb
@@ -651,6 +651,7 @@ describe WikiPage do
let(:untitled_page) { described_class.new(wiki) }
let(:directory_page) { create(:wiki_page, title: 'parent directory/child page') }
+ let(:page_with_special_characters) { create(:wiki_page, title: 'test+page') }
where(:page, :title, :changed) do
:untitled_page | nil | false
@@ -658,6 +659,8 @@ describe WikiPage do
:new_page | nil | true
:new_page | 'test page' | true
+ :new_page | 'test-page' | true
+ :new_page | 'test+page' | true
:new_page | 'new title' | true
:existing_page | nil | false
@@ -665,6 +668,7 @@ describe WikiPage do
:existing_page | 'test-page' | false
:existing_page | '/test page' | false
:existing_page | '/test-page' | false
+ :existing_page | 'test+page' | true
:existing_page | ' test page ' | true
:existing_page | 'new title' | true
:existing_page | 'new-title' | true
@@ -681,6 +685,11 @@ describe WikiPage do
:directory_page | 'parent-directory / child-page' | true
:directory_page | 'other directory/child page' | true
:directory_page | 'other-directory/child page' | true
+
+ :page_with_special_characters | nil | false
+ :page_with_special_characters | 'test+page' | false
+ :page_with_special_characters | 'test-page' | true
+ :page_with_special_characters | 'test page' | true
end
with_them do
@@ -772,7 +781,7 @@ describe WikiPage do
describe '#to_partial_path' do
it 'returns the relative path to the partial to be used' do
- expect(subject.to_partial_path).to eq('projects/wikis/wiki_page')
+ expect(subject.to_partial_path).to eq('../shared/wikis/wiki_page')
end
end
diff --git a/spec/policies/ci/build_policy_spec.rb b/spec/policies/ci/build_policy_spec.rb
index f29ed26f2aa..5857369a550 100644
--- a/spec/policies/ci/build_policy_spec.rb
+++ b/spec/policies/ci/build_policy_spec.rb
@@ -249,4 +249,129 @@ describe Ci::BuildPolicy do
end
end
end
+
+ describe 'manage a web ide terminal' do
+ let(:build_permissions) { %i[read_web_ide_terminal create_build_terminal update_web_ide_terminal create_build_service_proxy] }
+ let_it_be(:maintainer) { create(:user) }
+ let(:owner) { create(:owner) }
+ let(:admin) { create(:admin) }
+ let(:maintainer) { create(:user) }
+ let(:developer) { create(:user) }
+ let(:reporter) { create(:user) }
+ let(:guest) { create(:user) }
+ let(:project) { create(:project, :public, namespace: owner.namespace) }
+ let(:pipeline) { create(:ci_empty_pipeline, project: project, source: :webide) }
+ let(:build) { create(:ci_build, pipeline: pipeline) }
+
+ before do
+ allow(build).to receive(:has_terminal?).and_return(true)
+
+ project.add_maintainer(maintainer)
+ project.add_developer(developer)
+ project.add_reporter(reporter)
+ project.add_guest(guest)
+ end
+
+ subject { described_class.new(current_user, build) }
+
+ context 'when create_web_ide_terminal access enabled' do
+ context 'with admin' do
+ let(:current_user) { admin }
+
+ context 'when admin mode enabled', :enable_admin_mode do
+ it { expect_allowed(*build_permissions) }
+ end
+
+ context 'when admin mode disabled' do
+ it { expect_disallowed(*build_permissions) }
+ end
+
+ context 'when build is not from a webide pipeline' do
+ let(:pipeline) { create(:ci_empty_pipeline, project: project, source: :chat) }
+
+ it { expect_disallowed(:read_web_ide_terminal, :update_web_ide_terminal, :create_build_service_proxy) }
+ end
+
+ context 'when build has no runner terminal' do
+ before do
+ allow(build).to receive(:has_terminal?).and_return(false)
+ end
+
+ context 'when admin mode enabled', :enable_admin_mode do
+ it { expect_allowed(:read_web_ide_terminal, :update_web_ide_terminal) }
+ it { expect_disallowed(:create_build_terminal, :create_build_service_proxy) }
+ end
+
+ context 'when admin mode disabled' do
+ it { expect_disallowed(:read_web_ide_terminal, :update_web_ide_terminal) }
+ it { expect_disallowed(:create_build_terminal, :create_build_service_proxy) }
+ end
+ end
+
+ context 'feature flag "build_service_proxy" is disabled' do
+ before do
+ stub_feature_flags(build_service_proxy: false)
+ end
+
+ it { expect_disallowed(:create_build_service_proxy) }
+ end
+ end
+
+ shared_examples 'allowed build owner access' do
+ it { expect_disallowed(*build_permissions) }
+
+ context 'when user is the owner of the job' do
+ let(:build) { create(:ci_build, pipeline: pipeline, user: current_user) }
+
+ it { expect_allowed(*build_permissions) }
+ end
+ end
+
+ shared_examples 'forbidden access' do
+ it { expect_disallowed(*build_permissions) }
+
+ context 'when user is the owner of the job' do
+ let(:build) { create(:ci_build, pipeline: pipeline, user: current_user) }
+
+ it { expect_disallowed(*build_permissions) }
+ end
+ end
+
+ context 'with owner' do
+ let(:current_user) { owner }
+
+ it_behaves_like 'allowed build owner access'
+ end
+
+ context 'with maintainer' do
+ let(:current_user) { maintainer }
+
+ it_behaves_like 'allowed build owner access'
+ end
+
+ context 'with developer' do
+ let(:current_user) { developer }
+
+ it_behaves_like 'forbidden access'
+ end
+
+ context 'with reporter' do
+ let(:current_user) { reporter }
+
+ it_behaves_like 'forbidden access'
+ end
+
+ context 'with guest' do
+ let(:current_user) { guest }
+
+ it_behaves_like 'forbidden access'
+ end
+
+ context 'with non member' do
+ let(:current_user) { create(:user) }
+
+ it_behaves_like 'forbidden access'
+ end
+ end
+ end
end
diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb
index 9faddfd00e5..6b17a8285a2 100644
--- a/spec/policies/group_policy_spec.rb
+++ b/spec/policies/group_policy_spec.rb
@@ -175,7 +175,7 @@ describe GroupPolicy do
nested_group.add_guest(developer)
nested_group.add_guest(maintainer)
- group.owners.destroy_all # rubocop: disable DestroyAll
+ group.owners.destroy_all # rubocop: disable Cop/DestroyAll
group.add_guest(owner)
nested_group.add_owner(owner)
diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb
index f91d5658626..6ec63ba61ca 100644
--- a/spec/policies/project_policy_spec.rb
+++ b/spec/policies/project_policy_spec.rb
@@ -219,41 +219,16 @@ describe ProjectPolicy do
project.project_feature.update!(builds_access_level: ProjectFeature::DISABLED)
end
- context 'without metrics_dashboard_allowed' do
- before do
- project.project_feature.update(metrics_dashboard_access_level: ProjectFeature::DISABLED)
- end
-
- it 'disallows all permissions except pipeline when the feature is disabled' do
- builds_permissions = [
- :create_build, :read_build, :update_build, :admin_build, :destroy_build,
- :create_pipeline_schedule, :read_pipeline_schedule, :update_pipeline_schedule, :admin_pipeline_schedule, :destroy_pipeline_schedule,
- :create_environment, :read_environment, :update_environment, :admin_environment, :destroy_environment,
- :create_cluster, :read_cluster, :update_cluster, :admin_cluster, :destroy_cluster,
- :create_deployment, :read_deployment, :update_deployment, :admin_deployment, :destroy_deployment
- ]
-
- expect_disallowed(*builds_permissions)
- end
- end
-
- context 'with metrics_dashboard_allowed' do
- before do
- project.project_feature.update(metrics_dashboard_access_level: ProjectFeature::ENABLED)
- end
+ it 'disallows all permissions except pipeline when the feature is disabled' do
+ builds_permissions = [
+ :create_build, :read_build, :update_build, :admin_build, :destroy_build,
+ :create_pipeline_schedule, :read_pipeline_schedule, :update_pipeline_schedule, :admin_pipeline_schedule, :destroy_pipeline_schedule,
+ :create_environment, :read_environment, :update_environment, :admin_environment, :destroy_environment,
+ :create_cluster, :read_cluster, :update_cluster, :admin_cluster, :destroy_cluster,
+ :create_deployment, :read_deployment, :update_deployment, :admin_deployment, :destroy_deployment
+ ]
- it 'disallows all permissions except pipeline and read_environment when the feature is disabled' do
- builds_permissions = [
- :create_build, :read_build, :update_build, :admin_build, :destroy_build,
- :create_pipeline_schedule, :read_pipeline_schedule, :update_pipeline_schedule, :admin_pipeline_schedule, :destroy_pipeline_schedule,
- :create_environment, :update_environment, :admin_environment, :destroy_environment,
- :create_cluster, :read_cluster, :update_cluster, :admin_cluster, :destroy_cluster,
- :create_deployment, :read_deployment, :update_deployment, :admin_deployment, :destroy_deployment
- ]
-
- expect_disallowed(*builds_permissions)
- expect_allowed(:read_environment)
- end
+ expect_disallowed(*builds_permissions)
end
end
@@ -301,25 +276,8 @@ describe ProjectPolicy do
)
end
- context 'without metrics_dashboard_allowed' do
- before do
- project.project_feature.update(metrics_dashboard_access_level: ProjectFeature::DISABLED)
- end
-
- it 'disallows all permissions when the feature is disabled' do
- expect_disallowed(*repository_permissions)
- end
- end
-
- context 'with metrics_dashboard_allowed' do
- before do
- project.project_feature.update(metrics_dashboard_access_level: ProjectFeature::ENABLED)
- end
-
- it 'disallows all permissions but read_environment when the feature is disabled' do
- expect_disallowed(*(repository_permissions - [:read_environment]))
- expect_allowed(:read_environment)
- end
+ it 'disallows all permissions' do
+ expect_disallowed(*repository_permissions)
end
end
end
@@ -817,4 +775,121 @@ describe ProjectPolicy do
it { is_expected.to be_disallowed(:destroy_package) }
end
end
+
+ describe 'create_web_ide_terminal' do
+ subject { described_class.new(current_user, project) }
+
+ context 'with admin' do
+ let(:current_user) { admin }
+
+ context 'when admin mode enabled', :enable_admin_mode do
+ it { is_expected.to be_allowed(:create_web_ide_terminal) }
+ end
+
+ context 'when admin mode disabled' do
+ it { is_expected.to be_disallowed(:create_web_ide_terminal) }
+ end
+ end
+
+ context 'with owner' do
+ let(:current_user) { owner }
+
+ it { is_expected.to be_allowed(:create_web_ide_terminal) }
+ end
+
+ context 'with maintainer' do
+ let(:current_user) { maintainer }
+
+ it { is_expected.to be_allowed(:create_web_ide_terminal) }
+ end
+
+ context 'with developer' do
+ let(:current_user) { developer }
+
+ it { is_expected.to be_disallowed(:create_web_ide_terminal) }
+ end
+
+ context 'with reporter' do
+ let(:current_user) { reporter }
+
+ it { is_expected.to be_disallowed(:create_web_ide_terminal) }
+ end
+
+ context 'with guest' do
+ let(:current_user) { guest }
+
+ it { is_expected.to be_disallowed(:create_web_ide_terminal) }
+ end
+
+ context 'with non member' do
+ let(:current_user) { create(:user) }
+
+ it { is_expected.to be_disallowed(:create_web_ide_terminal) }
+ end
+
+ context 'with anonymous' do
+ let(:current_user) { nil }
+
+ it { is_expected.to be_disallowed(:create_web_ide_terminal) }
+ end
+ end
+
+ describe 'read_repository_graphs' do
+ subject { described_class.new(guest, project) }
+
+ before do
+ allow(subject).to receive(:allowed?).with(:read_repository_graphs).and_call_original
+ allow(subject).to receive(:allowed?).with(:download_code).and_return(can_download_code)
+ end
+
+ context 'when user can download_code' do
+ let(:can_download_code) { true }
+
+ it { is_expected.to be_allowed(:read_repository_graphs) }
+ end
+
+ context 'when user cannot download_code' do
+ let(:can_download_code) { false }
+
+ it { is_expected.to be_disallowed(:read_repository_graphs) }
+ end
+ end
+
+ describe 'read_build_report_results' do
+ subject { described_class.new(guest, project) }
+
+ before do
+ allow(subject).to receive(:allowed?).with(:read_build_report_results).and_call_original
+ allow(subject).to receive(:allowed?).with(:read_build).and_return(can_read_build)
+ allow(subject).to receive(:allowed?).with(:read_pipeline).and_return(can_read_pipeline)
+ end
+
+ context 'when user can read_build and read_pipeline' do
+ let(:can_read_build) { true }
+ let(:can_read_pipeline) { true }
+
+ it { is_expected.to be_allowed(:read_build_report_results) }
+ end
+
+ context 'when user can read_build but cannot read_pipeline' do
+ let(:can_read_build) { true }
+ let(:can_read_pipeline) { false }
+
+ it { is_expected.to be_disallowed(:read_build_report_results) }
+ end
+
+ context 'when user cannot read_build but can read_pipeline' do
+ let(:can_read_build) { false }
+ let(:can_read_pipeline) { true }
+
+ it { is_expected.to be_disallowed(:read_build_report_results) }
+ end
+
+ context 'when user cannot read_build and cannot read_pipeline' do
+ let(:can_read_build) { false }
+ let(:can_read_pipeline) { false }
+
+ it { is_expected.to be_disallowed(:read_build_report_results) }
+ end
+ end
end
diff --git a/spec/policies/releases/source_policy_spec.rb b/spec/policies/releases/source_policy_spec.rb
new file mode 100644
index 00000000000..1bc6d5415d3
--- /dev/null
+++ b/spec/policies/releases/source_policy_spec.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Releases::SourcePolicy do
+ using RSpec::Parameterized::TableSyntax
+
+ let(:policy) { described_class.new(user, source) }
+
+ let_it_be(:public_user) { create(:user) }
+ let_it_be(:guest) { create(:user) }
+ let_it_be(:reporter) { create(:user) }
+
+ let(:release) { create(:release, project: project) }
+ let(:source) { release.sources.first }
+
+ shared_examples 'source code access' do
+ it "allows access a release's source code" do
+ expect(policy).to be_allowed(:read_release_sources)
+ end
+ end
+
+ shared_examples 'no source code access' do
+ it "does not allow access a release's source code" do
+ expect(policy).to be_disallowed(:read_release_sources)
+ end
+ end
+
+ context 'a private project' do
+ let_it_be(:project) { create(:project, :private) }
+
+ context 'accessed by a public user' do
+ let(:user) { public_user }
+
+ it_behaves_like 'no source code access'
+ end
+
+ context 'accessed by a user with Guest permissions' do
+ let(:user) { guest }
+
+ before do
+ project.add_guest(user)
+ end
+
+ it_behaves_like 'no source code access'
+ end
+
+ context 'accessed by a user with Reporter permissions' do
+ let(:user) { reporter }
+
+ before do
+ project.add_reporter(user)
+ end
+
+ it_behaves_like 'source code access'
+ end
+ end
+
+ context 'a public project' do
+ let_it_be(:project) { create(:project, :public) }
+
+ context 'accessed by a public user' do
+ let(:user) { public_user }
+
+ it_behaves_like 'source code access'
+ end
+
+ context 'accessed by a user with Guest permissions' do
+ let(:user) { guest }
+
+ before do
+ project.add_guest(user)
+ end
+
+ it_behaves_like 'source code access'
+ end
+
+ context 'accessed by a user with Reporter permissions' do
+ let(:user) { reporter }
+
+ before do
+ project.add_reporter(user)
+ end
+
+ it_behaves_like 'source code access'
+ end
+ end
+end
diff --git a/spec/presenters/gitlab/blame_presenter_spec.rb b/spec/presenters/gitlab/blame_presenter_spec.rb
new file mode 100644
index 00000000000..d2a173b557c
--- /dev/null
+++ b/spec/presenters/gitlab/blame_presenter_spec.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::BlamePresenter do
+ let(:project) { create(:project, :repository) }
+ let(:path) { 'files/ruby/popen.rb' }
+ let(:commit) { project.commit('master') }
+ let(:blob) { project.repository.blob_at(commit.id, path) }
+ let(:blame) { Gitlab::Blame.new(blob, commit) }
+
+ subject { described_class.new(blame, project: project, path: path) }
+
+ it 'precalculates necessary data on init' do
+ expect_any_instance_of(described_class)
+ .to receive(:precalculate_data_by_commit!)
+ .and_call_original
+
+ subject
+ end
+
+ describe '#groups' do
+ it 'delegates #groups call to the blame' do
+ expect(blame).to receive(:groups).and_call_original
+
+ subject.groups
+ end
+ end
+
+ describe '#commit_data' do
+ it 'has the data necessary to render the view' do
+ commit = blame.groups.first[:commit]
+ data = subject.commit_data(commit)
+
+ aggregate_failures do
+ expect(data.author_avatar.to_s).to include('src="https://www.gravatar.com/')
+ expect(data.age_map_class).to include('blame-commit-age-')
+ expect(data.commit_link.to_s).to include '913c66a37b4a45b9769037c55c2d238bd0942d2e">Files, encoding and much more</a>'
+ expect(data.commit_author_link.to_s).to include('<a class="commit-author-link" href=')
+ expect(data.project_blame_link.to_s).to include('<a title="View blame prior to this change"')
+ expect(data.time_ago_tooltip.to_s).to include('data-container="body">Feb 27, 2014</time>')
+ end
+ end
+ end
+end
diff --git a/spec/presenters/projects/prometheus/alert_presenter_spec.rb b/spec/presenters/projects/prometheus/alert_presenter_spec.rb
index 967a0fb2c09..8ee5a4d7b3f 100644
--- a/spec/presenters/projects/prometheus/alert_presenter_spec.rb
+++ b/spec/presenters/projects/prometheus/alert_presenter_spec.rb
@@ -24,18 +24,25 @@ describe Projects::Prometheus::AlertPresenter do
it { is_expected.to eq(project.full_path) }
end
- describe '#starts_at' do
- subject { presenter.starts_at }
+ describe '#start_time' do
+ subject { presenter.start_time }
+
+ let(:starts_at) { '2020-10-31T14:02:04Z' }
before do
payload['startsAt'] = starts_at
end
- context 'with valid datetime' do
- let(:datetime) { Time.now }
- let(:starts_at) { datetime.rfc3339 }
+ context 'with valid utc datetime' do
+ it { is_expected.to eq('31 October 2020, 2:02PM (UTC)') }
- it { is_expected.to eq(datetime.rfc3339) }
+ context 'with admin time zone not UTC' do
+ before do
+ allow(Time).to receive(:zone).and_return(ActiveSupport::TimeZone.new('Perth'))
+ end
+
+ it { is_expected.to eq('31 October 2020, 2:02PM (UTC)') }
+ end
end
context 'with invalid datetime' do
@@ -56,7 +63,7 @@ describe Projects::Prometheus::AlertPresenter do
<<~MARKDOWN.chomp
#### Summary
- **Start time:** #{presenter.starts_at}
+ **Start time:** #{presenter.start_time}
MARKDOWN
)
@@ -73,7 +80,7 @@ describe Projects::Prometheus::AlertPresenter do
<<~MARKDOWN.chomp
#### Summary
- **Start time:** #{presenter.starts_at}
+ **Start time:** #{presenter.start_time}
#### Alert Details
@@ -94,7 +101,7 @@ describe Projects::Prometheus::AlertPresenter do
<<~MARKDOWN.chomp
#### Summary
- **Start time:** #{presenter.starts_at}#{markdown_line_break}
+ **Start time:** #{presenter.start_time}#{markdown_line_break}
**full_query:** `query`
MARKDOWN
@@ -122,7 +129,7 @@ describe Projects::Prometheus::AlertPresenter do
<<~MARKDOWN.chomp
#### Summary
- **Start time:** #{presenter.starts_at}#{markdown_line_break}
+ **Start time:** #{presenter.start_time}#{markdown_line_break}
**Service:** service_name#{markdown_line_break}
**Monitoring tool:** monitoring_tool_name#{markdown_line_break}
**Hosts:** http://localhost:3000 http://localhost:3001
@@ -144,7 +151,7 @@ describe Projects::Prometheus::AlertPresenter do
<<~MARKDOWN.chomp
#### Summary
- **Start time:** #{presenter.starts_at}#{markdown_line_break}
+ **Start time:** #{presenter.start_time}#{markdown_line_break}
**Hosts:** http://localhost:3000
MARKDOWN
@@ -161,7 +168,7 @@ describe Projects::Prometheus::AlertPresenter do
<<~MARKDOWN.chomp
#### Summary
- **Start time:** #{presenter.starts_at}#{markdown_line_break}
+ **Start time:** #{presenter.start_time}#{markdown_line_break}
**full_query:** `avg(metric) > 1.0`
[](#{url})
@@ -253,7 +260,7 @@ describe Projects::Prometheus::AlertPresenter do
<<~MARKDOWN.chomp
#### Summary
- **Start time:** #{presenter.starts_at}#{markdown_line_break}
+ **Start time:** #{presenter.start_time}#{markdown_line_break}
**full_query:** `avg(metric) > 1.0`
MARKDOWN
@@ -280,7 +287,7 @@ describe Projects::Prometheus::AlertPresenter do
<<~MARKDOWN.chomp
#### Summary
- **Start time:** #{presenter.starts_at}
+ **Start time:** #{presenter.start_time}
MARKDOWN
end
diff --git a/spec/presenters/snippet_presenter_spec.rb b/spec/presenters/snippet_presenter_spec.rb
index 591d86652b6..423e9edc219 100644
--- a/spec/presenters/snippet_presenter_spec.rb
+++ b/spec/presenters/snippet_presenter_spec.rb
@@ -163,4 +163,25 @@ describe SnippetPresenter do
end
end
end
+
+ describe '#blobs' do
+ let(:snippet) { personal_snippet }
+
+ subject { presenter.blobs }
+
+ context 'when snippet does not have a repository' do
+ it 'returns an array with one SnippetBlob' do
+ expect(subject.size).to eq(1)
+ expect(subject.first).to eq(snippet.blob)
+ end
+ end
+
+ context 'when snippet has a repository' do
+ let(:snippet) { create(:snippet, :repository, author: user) }
+
+ it 'returns an array with all repository blobs' do
+ expect(subject).to match_array(snippet.blobs)
+ end
+ end
+ end
end
diff --git a/spec/requests/api/admin/ci/variables_spec.rb b/spec/requests/api/admin/ci/variables_spec.rb
index bc2f0ba50a2..185fde17e1b 100644
--- a/spec/requests/api/admin/ci/variables_spec.rb
+++ b/spec/requests/api/admin/ci/variables_spec.rb
@@ -109,6 +109,22 @@ describe ::API::Admin::Ci::Variables do
expect(response).to have_gitlab_http_status(:bad_request)
end
+
+ it 'does not allow values above 700 characters' do
+ too_long_message = <<~MESSAGE.strip
+ The encrypted value of the provided variable exceeds 1024 bytes. \
+ Variables over 700 characters risk exceeding the limit.
+ MESSAGE
+
+ expect do
+ post api('/admin/ci/variables', admin),
+ params: { key: 'too_long', value: SecureRandom.hex(701) }
+ end.not_to change { ::Ci::InstanceVariable.count }
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response).to match('message' =>
+ a_hash_including('encrypted_value' => [too_long_message]))
+ end
end
context 'authorized user with invalid permissions' do
diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb
index 86b3dd4095f..a423c92e2fb 100644
--- a/spec/requests/api/commits_spec.rb
+++ b/spec/requests/api/commits_spec.rb
@@ -356,28 +356,35 @@ describe API::Commits do
}
end
+ shared_examples_for "successfully creates the commit" do
+ it "creates the commit" do
+ expect(response).to have_gitlab_http_status(:created)
+ expect(json_response['title']).to eq(message)
+ expect(json_response['committer_name']).to eq(user.name)
+ expect(json_response['committer_email']).to eq(user.email)
+ end
+ end
+
it 'does not increment the usage counters using access token authentication' do
expect(::Gitlab::UsageDataCounters::WebIdeCounter).not_to receive(:increment_commits_count)
post api(url, user), params: valid_c_params
end
- it 'a new file in project repo' do
- post api(url, user), params: valid_c_params
+ context 'a new file in project repo' do
+ before do
+ post api(url, user), params: valid_c_params
+ end
- expect(response).to have_gitlab_http_status(:created)
- expect(json_response['title']).to eq(message)
- expect(json_response['committer_name']).to eq(user.name)
- expect(json_response['committer_email']).to eq(user.email)
+ it_behaves_like "successfully creates the commit"
end
- it 'a new file with utf8 chars in project repo' do
- post api(url, user), params: valid_utf8_c_params
+ context 'a new file with utf8 chars in project repo' do
+ before do
+ post api(url, user), params: valid_utf8_c_params
+ end
- expect(response).to have_gitlab_http_status(:created)
- expect(json_response['title']).to eq(message)
- expect(json_response['committer_name']).to eq(user.name)
- expect(json_response['committer_email']).to eq(user.email)
+ it_behaves_like "successfully creates the commit"
end
it 'returns a 400 bad request if file exists' do
diff --git a/spec/requests/api/deploy_keys_spec.rb b/spec/requests/api/deploy_keys_spec.rb
index e8cc6bc71ae..1baa18b53ce 100644
--- a/spec/requests/api/deploy_keys_spec.rb
+++ b/spec/requests/api/deploy_keys_spec.rb
@@ -8,7 +8,7 @@ describe API::DeployKeys do
let(:admin) { create(:admin) }
let(:project) { create(:project, creator_id: user.id) }
let(:project2) { create(:project, creator_id: user.id) }
- let(:deploy_key) { create(:deploy_key, public: true) }
+ let(:deploy_key) { create(:deploy_key, public: true, user: user) }
let!(:deploy_keys_project) do
create(:deploy_keys_project, project: project, deploy_key: deploy_key)
@@ -40,6 +40,32 @@ describe API::DeployKeys do
expect(json_response).to be_an Array
expect(json_response.first['id']).to eq(deploy_keys_project.deploy_key.id)
end
+
+ it 'returns all deploy keys with comments replaced with'\
+ 'a simple identifier of username + hostname' do
+ get api('/deploy_keys', admin)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+
+ keys = json_response.map { |key_detail| key_detail['key'] }
+ expect(keys).to all(include("#{user.name} (#{Gitlab.config.gitlab.host}"))
+ end
+
+ context 'N+1 queries' do
+ before do
+ get api('/deploy_keys', admin)
+ end
+
+ it 'avoids N+1 queries', :request_store do
+ control_count = ActiveRecord::QueryRecorder.new { get api('/deploy_keys', admin) }.count
+
+ create_list(:deploy_key, 2, public: true, user: create(:user))
+
+ expect { get api('/deploy_keys', admin) }.not_to exceed_query_limit(control_count)
+ end
+ end
end
end
@@ -56,6 +82,25 @@ describe API::DeployKeys do
expect(json_response).to be_an Array
expect(json_response.first['title']).to eq(deploy_key.title)
end
+
+ context 'N+1 queries' do
+ before do
+ get api("/projects/#{project.id}/deploy_keys", admin)
+ end
+
+ it 'avoids N+1 queries', :request_store do
+ control_count = ActiveRecord::QueryRecorder.new do
+ get api("/projects/#{project.id}/deploy_keys", admin)
+ end.count
+
+ deploy_key = create(:deploy_key, user: create(:user))
+ create(:deploy_keys_project, project: project, deploy_key: deploy_key)
+
+ expect do
+ get api("/projects/#{project.id}/deploy_keys", admin)
+ end.not_to exceed_query_limit(control_count)
+ end
+ end
end
describe 'GET /projects/:id/deploy_keys/:key_id' do
@@ -66,6 +111,13 @@ describe API::DeployKeys do
expect(json_response['title']).to eq(deploy_key.title)
end
+ it 'exposes key comment as a simple identifier of username + hostname' do
+ get api("/projects/#{project.id}/deploy_keys/#{deploy_key.id}", admin)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['key']).to include("#{deploy_key.user_name} (#{Gitlab.config.gitlab.host})")
+ end
+
it 'returns 404 Not Found with invalid ID' do
get api("/projects/#{project.id}/deploy_keys/404", admin)
diff --git a/spec/requests/api/events_spec.rb b/spec/requests/api/events_spec.rb
index decdcc66327..0425e0791eb 100644
--- a/spec/requests/api/events_spec.rb
+++ b/spec/requests/api/events_spec.rb
@@ -7,9 +7,9 @@ describe API::Events do
let(:non_member) { create(:user) }
let(:private_project) { create(:project, :private, creator_id: user.id, namespace: user.namespace) }
let(:closed_issue) { create(:closed_issue, project: private_project, author: user) }
- let!(:closed_issue_event) { create(:event, project: private_project, author: user, target: closed_issue, action: Event::CLOSED, created_at: Date.new(2016, 12, 30)) }
+ let!(:closed_issue_event) { create(:event, :closed, project: private_project, author: user, target: closed_issue, created_at: Date.new(2016, 12, 30)) }
let(:closed_issue2) { create(:closed_issue, project: private_project, author: non_member) }
- let!(:closed_issue_event2) { create(:event, project: private_project, author: non_member, target: closed_issue2, action: Event::CLOSED, created_at: Date.new(2016, 12, 30)) }
+ let!(:closed_issue_event2) { create(:event, :closed, project: private_project, author: non_member, target: closed_issue2, created_at: Date.new(2016, 12, 30)) }
describe 'GET /events' do
context 'when unauthenticated' do
@@ -117,7 +117,7 @@ describe API::Events do
context 'when the list of events includes wiki page events' do
it 'returns information about the wiki event', :aggregate_failures do
page = create(:wiki_page, project: private_project)
- [Event::CREATED, Event::UPDATED, Event::DESTROYED].each do |action|
+ [:created, :updated, :destroyed].each do |action|
create(:wiki_page_event, wiki_page: page, action: action, author: user)
end
diff --git a/spec/requests/api/features_spec.rb b/spec/requests/api/features_spec.rb
index 4ad5b4f9d49..59a9ed2f77d 100644
--- a/spec/requests/api/features_spec.rb
+++ b/spec/requests/api/features_spec.rb
@@ -2,11 +2,12 @@
require 'spec_helper'
-describe API::Features do
+describe API::Features, stub_feature_flags: false do
let_it_be(:user) { create(:user) }
let_it_be(:admin) { create(:admin) }
before do
+ Feature.reset
Flipper.unregister_groups
Flipper.register(:perf_team) do |actor|
actor.respond_to?(:admin) && actor.admin?
@@ -38,9 +39,9 @@ describe API::Features do
end
before do
- Feature.get('feature_1').enable
- Feature.get('feature_2').disable
- Feature.get('feature_3').enable Feature.group(:perf_team)
+ Feature.enable('feature_1')
+ Feature.disable('feature_2')
+ Feature.enable('feature_3', Feature.group(:perf_team))
end
it 'returns a 401 for anonymous users' do
@@ -226,10 +227,8 @@ describe API::Features do
end
context 'when the feature exists' do
- let(:feature) { Feature.get(feature_name) }
-
before do
- feature.disable # This also persists the feature on the DB
+ Feature.disable(feature_name) # This also persists the feature on the DB
end
context 'when passed value=true' do
@@ -272,8 +271,8 @@ describe API::Features do
context 'when feature is enabled and value=false is passed' do
it 'disables the feature' do
- feature.enable
- expect(feature).to be_enabled
+ Feature.enable(feature_name)
+ expect(Feature.enabled?(feature_name)).to eq(true)
post api("/features/#{feature_name}", admin), params: { value: 'false' }
@@ -285,8 +284,8 @@ describe API::Features do
end
it 'disables the feature for the given Flipper group when passed feature_group=perf_team' do
- feature.enable(Feature.group(:perf_team))
- expect(Feature.get(feature_name).enabled?(admin)).to be_truthy
+ Feature.enable(feature_name, Feature.group(:perf_team))
+ expect(Feature.enabled?(feature_name, admin)).to be_truthy
post api("/features/#{feature_name}", admin), params: { value: 'false', feature_group: 'perf_team' }
@@ -298,8 +297,8 @@ describe API::Features do
end
it 'disables the feature for the given user when passed user=username' do
- feature.enable(user)
- expect(Feature.get(feature_name).enabled?(user)).to be_truthy
+ Feature.enable(feature_name, user)
+ expect(Feature.enabled?(feature_name, user)).to be_truthy
post api("/features/#{feature_name}", admin), params: { value: 'false', user: user.username }
@@ -313,7 +312,7 @@ describe API::Features do
context 'with a pre-existing percentage of time value' do
before do
- feature.enable_percentage_of_time(50)
+ Feature.enable_percentage_of_time(feature_name, 50)
end
it 'updates the percentage of time if passed an integer' do
@@ -332,7 +331,7 @@ describe API::Features do
context 'with a pre-existing percentage of actors value' do
before do
- feature.enable_percentage_of_actors(42)
+ Feature.enable_percentage_of_actors(feature_name, 42)
end
it 'updates the percentage of actors if passed an integer' do
@@ -377,14 +376,17 @@ describe API::Features do
context 'when the gate value was set' do
before do
- Feature.get(feature_name).enable
+ Feature.enable(feature_name)
end
it 'deletes an enabled feature' do
- delete api("/features/#{feature_name}", admin)
+ expect do
+ delete api("/features/#{feature_name}", admin)
+ Feature.reset
+ end.to change { Feature.persisted_name?(feature_name) }
+ .and change { Feature.enabled?(feature_name) }
expect(response).to have_gitlab_http_status(:no_content)
- expect(Feature.get(feature_name)).not_to be_enabled
end
end
end
diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb
index e6406174391..198e4f64bcc 100644
--- a/spec/requests/api/files_spec.rb
+++ b/spec/requests/api/files_spec.rb
@@ -134,7 +134,8 @@ describe API::Files do
context 'when PATs are used' do
it_behaves_like 'repository files' do
let(:token) { create(:personal_access_token, scopes: ['read_repository'], user: user) }
- let(:current_user) { { personal_access_token: token } }
+ let(:current_user) { user }
+ let(:api_user) { { personal_access_token: token } }
end
end
@@ -153,15 +154,17 @@ describe API::Files do
describe "GET /projects/:id/repository/files/:file_path" do
shared_examples_for 'repository files' do
+ let(:api_user) { current_user }
+
it 'returns 400 for invalid file path' do
- get api(route(rouge_file_path), current_user), params: params
+ get api(route(rouge_file_path), api_user), params: params
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['error']).to eq(invalid_file_message)
end
it 'returns file attributes as json' do
- get api(route(file_path), current_user), params: params
+ get api(route(file_path), api_user), params: params
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['file_path']).to eq(CGI.unescape(file_path))
@@ -174,7 +177,7 @@ describe API::Files do
it 'returns json when file has txt extension' do
file_path = "bar%2Fbranch-test.txt"
- get api(route(file_path), current_user), params: params
+ get api(route(file_path), api_user), params: params
expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type).to eq('application/json')
@@ -185,7 +188,7 @@ describe API::Files do
file_path = "files%2Fjs%2Fcommit%2Ejs%2Ecoffee"
params[:ref] = "6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9"
- get api(route(file_path), current_user), params: params
+ get api(route(file_path), api_user), params: params
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['file_name']).to eq('commit.js.coffee')
@@ -197,7 +200,7 @@ describe API::Files do
url = route(file_path) + "/raw"
expect(Gitlab::Workhorse).to receive(:send_git_blob)
- get api(url, current_user), params: params
+ get api(url, api_user), params: params
expect(response).to have_gitlab_http_status(:ok)
expect(headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
@@ -206,7 +209,7 @@ describe API::Files do
it 'returns blame file info' do
url = route(file_path) + '/blame'
- get api(url, current_user), params: params
+ get api(url, api_user), params: params
expect(response).to have_gitlab_http_status(:ok)
end
@@ -214,7 +217,7 @@ describe API::Files do
it 'sets inline content disposition by default' do
url = route(file_path) + "/raw"
- get api(url, current_user), params: params
+ get api(url, api_user), params: params
expect(headers['Content-Disposition']).to eq(%q(inline; filename="popen.rb"; filename*=UTF-8''popen.rb))
end
@@ -229,7 +232,7 @@ describe API::Files do
let(:params) { { ref: 'master' } }
it_behaves_like '404 response' do
- let(:request) { get api(route('app%2Fmodels%2Fapplication%2Erb'), current_user), params: params }
+ let(:request) { get api(route('app%2Fmodels%2Fapplication%2Erb'), api_user), params: params }
let(:message) { '404 File Not Found' }
end
end
@@ -238,7 +241,7 @@ describe API::Files do
include_context 'disabled repository'
it_behaves_like '403 response' do
- let(:request) { get api(route(file_path), current_user), params: params }
+ let(:request) { get api(route(file_path), api_user), params: params }
end
end
end
@@ -253,7 +256,8 @@ describe API::Files do
context 'when PATs are used' do
it_behaves_like 'repository files' do
let(:token) { create(:personal_access_token, scopes: ['read_repository'], user: user) }
- let(:current_user) { { personal_access_token: token } }
+ let(:current_user) { user }
+ let(:api_user) { { personal_access_token: token } }
end
end
diff --git a/spec/requests/api/graphql/boards/board_lists_query_spec.rb b/spec/requests/api/graphql/boards/board_lists_query_spec.rb
index f0927487f85..3cc1468be02 100644
--- a/spec/requests/api/graphql/boards/board_lists_query_spec.rb
+++ b/spec/requests/api/graphql/boards/board_lists_query_spec.rb
@@ -65,41 +65,41 @@ describe 'get board lists' do
end
describe 'sorting and pagination' do
+ let_it_be(:current_user) { user }
+ let(:data_path) { [board_parent_type, :boards, :edges, 0, :node, :lists] }
+
+ def pagination_query(params, page_info)
+ graphql_query_for(
+ board_parent_type,
+ { 'fullPath' => board_parent.full_path },
+ <<~BOARDS
+ boards(first: 1) {
+ edges {
+ node {
+ #{query_graphql_field('lists', params, "#{page_info} edges { node { id } }")}
+ }
+ }
+ }
+ BOARDS
+ )
+ end
+
+ def pagination_results_data(data)
+ data.map { |list| list.dig('node', 'id') }
+ end
+
context 'when using default sorting' do
let!(:label_list) { create(:list, board: board, label: label, position: 10) }
let!(:label_list2) { create(:list, board: board, label: label2, position: 2) }
let!(:backlog_list) { create(:backlog_list, board: board) }
let(:closed_list) { board.lists.find_by(list_type: :closed) }
-
- before do
- post_graphql(query, current_user: user)
- end
-
- it_behaves_like 'a working graphql query'
+ let(:lists) { [backlog_list, label_list2, label_list, closed_list] }
context 'when ascending' do
- let(:lists) { [backlog_list, label_list2, label_list, closed_list] }
- let(:expected_list_gids) do
- lists.map { |list| list.to_global_id.to_s }
- end
-
- it 'sorts lists' do
- expect(grab_ids).to eq expected_list_gids
- end
-
- context 'when paginating' do
- let(:params) { 'first: 2' }
-
- it 'sorts boards' do
- expect(grab_ids).to eq expected_list_gids.first(2)
-
- cursored_query = query("after: \"#{end_cursor}\"")
- post_graphql(cursored_query, current_user: user)
-
- response_data = grab_list_data(response.body)
-
- expect(grab_ids(response_data)).to eq expected_list_gids.drop(2).first(2)
- end
+ it_behaves_like 'sorted paginated query' do
+ let(:sort_param) { }
+ let(:first_param) { 2 }
+ let(:expected_results) { lists.map { |list| list.to_global_id.to_s } }
end
end
end
@@ -126,12 +126,4 @@ describe 'get board lists' do
it_behaves_like 'group and project board lists query'
end
-
- def grab_ids(data = lists_data)
- data.map { |list| list.dig('node', 'id') }
- end
-
- def grab_list_data(response_body)
- Gitlab::Json.parse(response_body)['data'][board_parent_type]['boards']['edges'][0]['node']['lists']['edges']
- end
end
diff --git a/spec/requests/api/graphql/group/labels_query_spec.rb b/spec/requests/api/graphql/group/labels_query_spec.rb
new file mode 100644
index 00000000000..6c34cbadf95
--- /dev/null
+++ b/spec/requests/api/graphql/group/labels_query_spec.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'getting group label information' do
+ include GraphqlHelpers
+
+ let_it_be(:group) { create(:group, :public) }
+ let_it_be(:label_factory) { :group_label }
+ let_it_be(:label_attrs) { { group: group } }
+
+ it_behaves_like 'querying a GraphQL type with labels' do
+ let(:path_prefix) { ['group'] }
+
+ def make_query(fields)
+ graphql_query_for('group', { full_path: group.full_path }, fields)
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/metrics/dashboard_query_spec.rb b/spec/requests/api/graphql/metrics/dashboard_query_spec.rb
index 8b0965a815b..d9d9ea9ad61 100644
--- a/spec/requests/api/graphql/metrics/dashboard_query_spec.rb
+++ b/spec/requests/api/graphql/metrics/dashboard_query_spec.rb
@@ -9,25 +9,19 @@ describe 'Getting Metrics Dashboard' do
let(:project) { create(:project) }
let!(:environment) { create(:environment, project: project) }
- let(:fields) do
- <<~QUERY
- #{all_graphql_fields_for('MetricsDashboard'.classify)}
- QUERY
- end
-
let(:query) do
- %(
- query {
- project(fullPath:"#{project.full_path}") {
- environments(name: "#{environment.name}") {
- nodes {
- metricsDashboard(path: "#{path}"){
- #{fields}
- }
- }
- }
- }
- }
+ graphql_query_for(
+ 'project', { 'fullPath' => project.full_path },
+ query_graphql_field(
+ :environments, { 'name' => environment.name },
+ query_graphql_field(
+ :nodes, nil,
+ query_graphql_field(
+ :metricsDashboard, { 'path' => path },
+ all_graphql_fields_for('MetricsDashboard'.classify)
+ )
+ )
+ )
)
end
@@ -63,7 +57,29 @@ describe 'Getting Metrics Dashboard' do
it 'returns metrics dashboard' do
dashboard = graphql_data.dig('project', 'environments', 'nodes')[0]['metricsDashboard']
- expect(dashboard).to eql("path" => path)
+ expect(dashboard).to eql("path" => path, "schemaValidationWarnings" => nil)
+ end
+
+ context 'invalid dashboard' do
+ let(:path) { '.gitlab/dashboards/metrics.yml' }
+ let(:project) { create(:project, :repository, :custom_repo, namespace: current_user.namespace, files: { path => "---\ndasboard: ''" }) }
+
+ it 'returns metrics dashboard' do
+ dashboard = graphql_data.dig('project', 'environments', 'nodes', 0, 'metricsDashboard')
+
+ expect(dashboard).to eql("path" => path, "schemaValidationWarnings" => ["dashboard: can't be blank", "panel_groups: can't be blank"])
+ end
+ end
+
+ context 'empty dashboard' do
+ let(:path) { '.gitlab/dashboards/metrics.yml' }
+ let(:project) { create(:project, :repository, :custom_repo, namespace: current_user.namespace, files: { path => "" }) }
+
+ it 'returns metrics dashboard' do
+ dashboard = graphql_data.dig('project', 'environments', 'nodes', 0, 'metricsDashboard')
+
+ expect(dashboard).to eql("path" => path, "schemaValidationWarnings" => ["dashboard: can't be blank", "panel_groups: can't be blank"])
+ end
end
end
@@ -72,7 +88,7 @@ describe 'Getting Metrics Dashboard' do
it_behaves_like 'a working graphql query'
- it 'return snil' do
+ it 'returns nil' do
dashboard = graphql_data.dig('project', 'environments', 'nodes')[0]['metricsDashboard']
expect(dashboard).to be_nil
diff --git a/spec/requests/api/graphql/mutations/alert_management/alerts/create_alert_issue_spec.rb b/spec/requests/api/graphql/mutations/alert_management/alerts/create_alert_issue_spec.rb
new file mode 100644
index 00000000000..5b5b2ec8788
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/alert_management/alerts/create_alert_issue_spec.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'Create an alert issue from an alert' do
+ include GraphqlHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:alert) { create(:alert_management_alert, project: project) }
+
+ let(:mutation) do
+ variables = {
+ project_path: project.full_path,
+ iid: alert.iid.to_s
+ }
+ graphql_mutation(:create_alert_issue, variables,
+ <<~QL
+ clientMutationId
+ errors
+ alert {
+ iid
+ issueIid
+ }
+ issue {
+ iid
+ title
+ }
+ QL
+ )
+ end
+
+ let(:mutation_response) { graphql_mutation_response(:create_alert_issue) }
+
+ before do
+ project.add_developer(user)
+ end
+
+ context 'when there is no issue associated with the alert' do
+ it 'creates an alert issue' do
+ post_graphql_mutation(mutation, current_user: user)
+
+ new_issue = Issue.last!
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(mutation_response.slice('alert', 'issue')).to eq(
+ 'alert' => {
+ 'iid' => alert.iid.to_s,
+ 'issueIid' => new_issue.iid.to_s
+ },
+ 'issue' => {
+ 'iid' => new_issue.iid.to_s,
+ 'title' => new_issue.title
+ }
+ )
+ end
+ end
+
+ context 'when there is an issue already associated with the alert' do
+ before do
+ AlertManagement::CreateAlertIssueService.new(alert, user).execute
+ end
+
+ it 'responds with an error' do
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(mutation_response.slice('errors', 'issue')).to eq(
+ 'errors' => ['An issue already exists'],
+ 'issue' => nil
+ )
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/alert_management/alerts/set_assignees_spec.rb b/spec/requests/api/graphql/mutations/alert_management/alerts/set_assignees_spec.rb
new file mode 100644
index 00000000000..6663281e093
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/alert_management/alerts/set_assignees_spec.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'Setting assignees of an alert' do
+ include GraphqlHelpers
+
+ let_it_be(:project) { create(:project) }
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:alert) { create(:alert_management_alert, project: project) }
+ let(:input) { { assignee_usernames: [current_user.username] } }
+
+ let(:mutation) do
+ graphql_mutation(
+ :alert_set_assignees,
+ { project_path: project.full_path, iid: alert.iid.to_s }.merge(input),
+ <<~QL
+ clientMutationId
+ errors
+ alert {
+ assignees {
+ nodes {
+ username
+ }
+ }
+ }
+ QL
+ )
+ end
+
+ let(:mutation_response) { graphql_mutation_response(:alert_set_assignees) }
+
+ before_all do
+ project.add_developer(current_user)
+ end
+
+ it 'updates the assignee of the alert' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(mutation_response['alert']['assignees']['nodes'].first['username']).to eq(current_user.username)
+ expect(alert.reload.assignees).to contain_exactly(current_user)
+ end
+
+ context 'with operation_mode specified' do
+ let(:input) do
+ {
+ assignee_usernames: [current_user.username],
+ operation_mode: Types::MutationOperationModeEnum.enum[:remove]
+ }
+ end
+
+ before do
+ alert.assignees = [current_user]
+ end
+
+ it 'updates the assignee of the alert' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(mutation_response['alert']['assignees']['nodes']).to be_empty
+ expect(alert.reload.assignees).to be_empty
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/alert_management/alerts/update_alert_status_spec.rb b/spec/requests/api/graphql/mutations/alert_management/alerts/update_alert_status_spec.rb
index fe50468134c..2a470bda689 100644
--- a/spec/requests/api/graphql/mutations/alert_management/alerts/update_alert_status_spec.rb
+++ b/spec/requests/api/graphql/mutations/alert_management/alerts/update_alert_status_spec.rb
@@ -15,16 +15,16 @@ describe 'Setting the status of an alert' do
project_path: project.full_path,
iid: alert.iid.to_s
}
- graphql_mutation(:update_alert_status, variables.merge(input),
- <<~QL
- clientMutationId
- errors
- alert {
- iid
- status
- }
- QL
- )
+ graphql_mutation(:update_alert_status, variables.merge(input)) do
+ <<~QL
+ clientMutationId
+ errors
+ alert {
+ iid
+ status
+ }
+ QL
+ end
end
let(:mutation_response) { graphql_mutation_response(:update_alert_status) }
diff --git a/spec/requests/api/graphql/mutations/commits/create_spec.rb b/spec/requests/api/graphql/mutations/commits/create_spec.rb
new file mode 100644
index 00000000000..10a69932948
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/commits/create_spec.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'Creation of a new commit' do
+ include GraphqlHelpers
+
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:project) { create(:project, :public, :repository) }
+ let(:input) { { project_path: project.full_path, branch: branch, message: message, actions: actions } }
+ let(:branch) { 'master' }
+ let(:message) { 'Commit message' }
+ let(:actions) do
+ [
+ {
+ action: 'CREATE',
+ filePath: 'NEW_FILE.md',
+ content: 'Hello'
+ }
+ ]
+ end
+
+ let(:mutation) { graphql_mutation(:commit_create, input) }
+ let(:mutation_response) { graphql_mutation_response(:commit_create) }
+
+ context 'the user is not allowed to create a commit' do
+ it_behaves_like 'a mutation that returns top-level errors',
+ errors: ['The resource that you are attempting to access does not exist or you don\'t have permission to perform this action']
+ end
+
+ context 'when user has permissions to create a commit' do
+ before do
+ project.add_developer(current_user)
+ end
+
+ it 'creates a new commit' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(mutation_response['commit']).to include(
+ 'title' => message
+ )
+ end
+
+ context 'when branch is not correct' do
+ let(:branch) { 'unknown' }
+
+ it_behaves_like 'a mutation that returns errors in the response',
+ errors: ['You can only create or edit files when you are on a branch']
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/container_expiration_policy/update_spec.rb b/spec/requests/api/graphql/mutations/container_expiration_policy/update_spec.rb
new file mode 100644
index 00000000000..bc256a08f00
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/container_expiration_policy/update_spec.rb
@@ -0,0 +1,110 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'Updating the container expiration policy' do
+ include GraphqlHelpers
+ using RSpec::Parameterized::TableSyntax
+
+ let_it_be(:project, reload: true) { create(:project) }
+ let_it_be(:user) { create(:user) }
+
+ let(:container_expiration_policy) { project.container_expiration_policy.reload }
+ let(:params) do
+ {
+ project_path: project.full_path,
+ cadence: 'EVERY_THREE_MONTHS',
+ keep_n: 'ONE_HUNDRED_TAGS',
+ older_than: 'FOURTEEN_DAYS'
+ }
+ end
+ let(:mutation) do
+ graphql_mutation(:update_container_expiration_policy, params,
+ <<~QL
+ containerExpirationPolicy {
+ cadence
+ keepN
+ nameRegexKeep
+ nameRegex
+ olderThan
+ }
+ errors
+ QL
+ )
+ end
+ let(:mutation_response) { graphql_mutation_response(:update_container_expiration_policy) }
+ let(:container_expiration_policy_response) { mutation_response['containerExpirationPolicy'] }
+
+ RSpec.shared_examples 'returning a success' do
+ it_behaves_like 'returning response status', :success
+
+ it 'returns the updated container expiration policy' do
+ subject
+
+ expect(mutation_response['errors']).to be_empty
+ expect(container_expiration_policy_response['cadence']).to eq(params[:cadence])
+ expect(container_expiration_policy_response['keepN']).to eq(params[:keep_n])
+ expect(container_expiration_policy_response['olderThan']).to eq(params[:older_than])
+ end
+ end
+
+ RSpec.shared_examples 'updating the container expiration policy' do
+ it_behaves_like 'updating the container expiration policy attributes', mode: :update, from: { cadence: '1d', keep_n: 10, older_than: '90d' }, to: { cadence: '3month', keep_n: 100, older_than: '14d' }
+
+ it_behaves_like 'returning a success'
+ end
+
+ RSpec.shared_examples 'denying access to container expiration policy' do
+ it_behaves_like 'not creating the container expiration policy'
+
+ it_behaves_like 'returning response status', :success
+
+ it 'returns no response' do
+ subject
+
+ expect(mutation_response).to be_nil
+ end
+ end
+
+ describe 'post graphql mutation' do
+ subject { post_graphql_mutation(mutation, current_user: user) }
+
+ context 'with existing container expiration policy' do
+ where(:user_role, :shared_examples_name) do
+ :maintainer | 'updating the container expiration policy'
+ :developer | 'updating the container expiration policy'
+ :reporter | 'denying access to container expiration policy'
+ :guest | 'denying access to container expiration policy'
+ :anonymous | 'denying access to container expiration policy'
+ end
+
+ with_them do
+ before do
+ project.send("add_#{user_role}", user) unless user_role == :anonymous
+ end
+
+ it_behaves_like params[:shared_examples_name]
+ end
+ end
+
+ context 'without existing container expiration policy' do
+ let_it_be(:project, reload: true) { create(:project, :without_container_expiration_policy) }
+
+ where(:user_role, :shared_examples_name) do
+ :maintainer | 'creating the container expiration policy'
+ :developer | 'creating the container expiration policy'
+ :reporter | 'denying access to container expiration policy'
+ :guest | 'denying access to container expiration policy'
+ :anonymous | 'denying access to container expiration policy'
+ end
+
+ with_them do
+ before do
+ project.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/requests/api/graphql/mutations/discussions/toggle_resolve_spec.rb b/spec/requests/api/graphql/mutations/discussions/toggle_resolve_spec.rb
new file mode 100644
index 00000000000..95e967c039d
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/discussions/toggle_resolve_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'Toggling the resolve status of a discussion' do
+ include GraphqlHelpers
+
+ let_it_be(:project) { create(:project, :public, :repository) }
+ let_it_be(:noteable) { create(:merge_request, source_project: project) }
+ let(:discussion) do
+ create(:diff_note_on_merge_request, noteable: noteable, project: project).to_discussion
+ end
+ let(:mutation) do
+ graphql_mutation(:discussion_toggle_resolve, { id: discussion.to_global_id.to_s, resolve: true })
+ end
+ let(:mutation_response) { graphql_mutation_response(:discussion_toggle_resolve) }
+
+ context 'when the user does not have permission' do
+ let_it_be(:current_user) { create(:user) }
+
+ it_behaves_like 'a mutation that returns top-level errors',
+ errors: ["The resource that you are attempting to access does not exist or you don't have permission to perform this action"]
+ end
+
+ context 'when user has permission' do
+ let_it_be(:current_user) { create(:user, developer_projects: [project]) }
+
+ it 'returns the discussion without errors', :aggregate_failures do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(mutation_response).to include(
+ 'discussion' => be_present,
+ 'errors' => be_empty
+ )
+ end
+
+ context 'when an error is encountered' do
+ before do
+ allow_next_instance_of(::Discussions::ResolveService) do |service|
+ allow(service).to receive(:execute).and_raise(ActiveRecord::RecordNotSaved)
+ end
+ end
+
+ it_behaves_like 'a mutation that returns errors in the response',
+ errors: ['Discussion failed to be resolved']
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/jira_import/import_users_spec.rb b/spec/requests/api/graphql/mutations/jira_import/import_users_spec.rb
new file mode 100644
index 00000000000..be0d843d5ff
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/jira_import/import_users_spec.rb
@@ -0,0 +1,104 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'Importing Jira Users' do
+ include JiraServiceHelper
+ include GraphqlHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let(:project_path) { project.full_path }
+ let(:start_at) { 7 }
+
+ let(:mutation) do
+ variables = {
+ start_at: start_at,
+ project_path: project_path
+ }
+
+ graphql_mutation(:jira_import_users, variables)
+ end
+
+ def mutation_response
+ graphql_mutation_response(:jira_import_users)
+ end
+
+ def jira_import
+ mutation_response['jiraUsers']
+ end
+
+ context 'with anonymous user' do
+ let(:current_user) { nil }
+
+ it_behaves_like 'a mutation that returns top-level errors',
+ errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR]
+ end
+
+ context 'with user without permissions' do
+ let(:current_user) { user }
+
+ before do
+ project.add_developer(current_user)
+ end
+
+ it_behaves_like 'a mutation that returns top-level errors',
+ errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR]
+ end
+
+ context 'when the user has permissions' do
+ let(:current_user) { user }
+
+ before do
+ project.add_maintainer(current_user)
+ end
+
+ context 'when the project path is invalid' do
+ let(:project_path) { 'foobar' }
+
+ it 'returns an an error' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ errors = json_response['errors']
+
+ expect(errors.first['message']).to eq(Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR)
+ end
+ end
+
+ context 'when all params and permissions are ok' do
+ let(:importer) { instance_double(JiraImport::UsersImporter) }
+
+ before do
+ expect(JiraImport::UsersImporter).to receive(:new).with(current_user, project, 7)
+ .and_return(importer)
+ end
+
+ context 'when service returns a successful response' do
+ it 'returns imported users' do
+ users = [{ jira_account_id: '12a', jira_display_name: 'user 1' }]
+ result = ServiceResponse.success(payload: users)
+
+ expect(importer).to receive(:execute).and_return(result)
+
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect(jira_import.length).to eq(1)
+ expect(jira_import.first['jiraAccountId']).to eq('12a')
+ expect(jira_import.first['jiraDisplayName']).to eq('user 1')
+ end
+ end
+
+ context 'when service returns an error response' do
+ it 'returns an error messaege' do
+ result = ServiceResponse.error(message: 'Some error')
+
+ expect(importer).to receive(:execute).and_return(result)
+
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect(mutation_response['errors']).to eq(['Some error'])
+ end
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/jira_import/start_spec.rb b/spec/requests/api/graphql/mutations/jira_import/start_spec.rb
index 84110098400..296d33aec5d 100644
--- a/spec/requests/api/graphql/mutations/jira_import/start_spec.rb
+++ b/spec/requests/api/graphql/mutations/jira_import/start_spec.rb
@@ -29,10 +29,6 @@ describe 'Starting a Jira Import' do
end
context 'when the user does not have permission' do
- before do
- stub_feature_flags(jira_issue_import: true)
- end
-
shared_examples 'Jira import does not start' do
it 'does not start the Jira import' do
post_graphql_mutation(mutation, current_user: current_user)
@@ -83,53 +79,39 @@ describe 'Starting a Jira Import' do
end
end
- context 'when feature jira_issue_import feature flag is disabled' do
- before do
- stub_feature_flags(jira_issue_import: false)
- end
-
- it_behaves_like 'a mutation that returns errors in the response', errors: ['Jira import feature is disabled.']
+ context 'when project has no Jira service' do
+ it_behaves_like 'a mutation that returns errors in the response', errors: ['Jira integration not configured.']
end
- context 'when feature jira_issue_import feature flag is enabled' do
+ context 'when when project has Jira service' do
+ let!(:service) { create(:jira_service, project: project) }
+
before do
- stub_feature_flags(jira_issue_import: true)
- end
+ project.reload
- context 'when project has no Jira service' do
- it_behaves_like 'a mutation that returns errors in the response', errors: ['Jira integration not configured.']
+ stub_jira_service_test
end
- context 'when when project has Jira service' do
- let!(:service) { create(:jira_service, project: project) }
+ context 'when issues feature are disabled' do
+ let_it_be(:project, reload: true) { create(:project, :issues_disabled) }
- before do
- project.reload
-
- stub_jira_service_test
- end
-
- context 'when issues feature are disabled' do
- let_it_be(:project, reload: true) { create(:project, :issues_disabled) }
-
- it_behaves_like 'a mutation that returns errors in the response', errors: ['Cannot import because issues are not available in this project.']
- end
+ it_behaves_like 'a mutation that returns errors in the response', errors: ['Cannot import because issues are not available in this project.']
+ end
- context 'when jira_project_key not provided' do
- let(:jira_project_key) { '' }
+ context 'when jira_project_key not provided' do
+ let(:jira_project_key) { '' }
- it_behaves_like 'a mutation that returns errors in the response', errors: ['Unable to find Jira project to import data from.']
- end
+ it_behaves_like 'a mutation that returns errors in the response', errors: ['Unable to find Jira project to import data from.']
+ end
- context 'when Jira import successfully scheduled' do
- it 'schedules a Jira import' do
- post_graphql_mutation(mutation, current_user: current_user)
+ context 'when Jira import successfully scheduled' do
+ it 'schedules a Jira import' do
+ post_graphql_mutation(mutation, current_user: current_user)
- expect(jira_import['jiraProjectKey']).to eq 'AA'
- expect(jira_import['scheduledBy']['username']).to eq current_user.username
- expect(project.latest_jira_import).not_to be_nil
- expect(project.latest_jira_import).to be_scheduled
- end
+ expect(jira_import['jiraProjectKey']).to eq 'AA'
+ expect(jira_import['scheduledBy']['username']).to eq current_user.username
+ expect(project.latest_jira_import).not_to be_nil
+ expect(project.latest_jira_import).to be_scheduled
end
end
end
diff --git a/spec/requests/api/graphql/mutations/merge_requests/create_spec.rb b/spec/requests/api/graphql/mutations/merge_requests/create_spec.rb
new file mode 100644
index 00000000000..5c63f655f1d
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/merge_requests/create_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'Creation of a new merge request' do
+ include GraphqlHelpers
+
+ let_it_be(:current_user) { create(:user) }
+ let(:project) { create(:project, :public, :repository) }
+ let(:input) do
+ {
+ project_path: project.full_path,
+ title: title,
+ source_branch: source_branch,
+ target_branch: target_branch
+ }
+ end
+ let(:title) { 'MergeRequest' }
+ let(:source_branch) { 'new_branch' }
+ let(:target_branch) { 'master' }
+
+ let(:mutation) { graphql_mutation(:merge_request_create, input) }
+ let(:mutation_response) { graphql_mutation_response(:merge_request_create) }
+
+ context 'the user is not allowed to create a branch' do
+ it_behaves_like 'a mutation that returns top-level errors',
+ errors: ['The resource that you are attempting to access does not exist or you don\'t have permission to perform this action']
+ end
+
+ context 'when user has permissions to create a merge request' do
+ before do
+ project.add_developer(current_user)
+ end
+
+ it 'creates a new merge request' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(mutation_response['mergeRequest']).to include(
+ 'title' => title
+ )
+ end
+
+ context 'when source branch is equal to the target branch' do
+ let(:source_branch) { target_branch }
+
+ it_behaves_like 'a mutation that returns errors in the response',
+ errors: ['Branch conflict You can\'t use same project/branch for source and target']
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/metrics/dashboard/annotations/delete_spec.rb b/spec/requests/api/graphql/mutations/metrics/dashboard/annotations/delete_spec.rb
new file mode 100644
index 00000000000..217f538c53e
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/metrics/dashboard/annotations/delete_spec.rb
@@ -0,0 +1,80 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Mutations::Metrics::Dashboard::Annotations::Delete do
+ include GraphqlHelpers
+
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:project) { create(:project, :private, :repository) }
+ let_it_be(:environment) { create(:environment, project: project) }
+ let_it_be(:annotation) { create(:metrics_dashboard_annotation, environment: environment) }
+ let(:mutation) do
+ variables = {
+ id: GitlabSchema.id_from_object(annotation).to_s
+ }
+
+ graphql_mutation(:delete_annotation, variables)
+ end
+
+ def mutation_response
+ graphql_mutation_response(:delete_annotation)
+ end
+
+ specify { expect(described_class).to require_graphql_authorizations(:delete_metrics_dashboard_annotation) }
+
+ context 'when the user has permission to delete the annotation' do
+ before do
+ project.add_developer(current_user)
+ end
+
+ context 'with valid params' do
+ it 'deletes the annotation' do
+ expect do
+ post_graphql_mutation(mutation, current_user: current_user)
+ end.to change { Metrics::Dashboard::Annotation.count }.by(-1)
+ end
+ end
+
+ context 'with invalid params' do
+ let(:mutation) do
+ variables = {
+ id: 'invalid_id'
+ }
+
+ graphql_mutation(:delete_annotation, variables)
+ end
+
+ it_behaves_like 'a mutation that returns top-level errors', errors: ['invalid_id is not a valid GitLab id.']
+ end
+
+ context 'when the delete fails' do
+ let(:service_response) { { message: 'Annotation has not been deleted', status: :error, last_step: :delete } }
+
+ before do
+ allow_next_instance_of(Metrics::Dashboard::Annotations::DeleteService) do |delete_service|
+ allow(delete_service).to receive(:execute).and_return(service_response)
+ end
+ end
+ it 'returns the error' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect(mutation_response['errors']).to eq([service_response[:message]])
+ end
+ end
+ end
+
+ context 'when the user does not have permission to delete the annotation' do
+ before do
+ project.add_reporter(current_user)
+ end
+
+ it_behaves_like 'a mutation that returns top-level errors', errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR]
+
+ it 'does not delete the annotation' do
+ expect do
+ post_graphql_mutation(mutation, current_user: current_user)
+ end.not_to change { Metrics::Dashboard::Annotation.count }
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/snippets/create_spec.rb b/spec/requests/api/graphql/mutations/snippets/create_spec.rb
index e1e5fe22887..9052f54b171 100644
--- a/spec/requests/api/graphql/mutations/snippets/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/snippets/create_spec.rb
@@ -109,31 +109,21 @@ describe 'Creating a Snippet' do
context 'when the project path is invalid' do
let(:project_path) { 'foobar' }
- it 'returns an an error' do
- subject
- errors = json_response['errors']
-
- expect(errors.first['message']).to eq(Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR)
- end
+ it_behaves_like 'a mutation that returns top-level errors',
+ errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR]
end
context 'when the feature is disabled' do
- it 'returns an an error' do
+ before do
project.project_feature.update_attribute(:snippets_access_level, ProjectFeature::DISABLED)
-
- subject
- errors = json_response['errors']
-
- expect(errors.first['message']).to eq(Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR)
end
+
+ it_behaves_like 'a mutation that returns top-level errors',
+ errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR]
end
end
- context 'when there are ActiveRecord validation errors' do
- let(:title) { '' }
-
- it_behaves_like 'a mutation that returns errors in the response', errors: ["Title can't be blank"]
-
+ shared_examples 'does not create snippet' do
it 'does not create the Snippet' do
expect do
subject
@@ -147,7 +137,21 @@ describe 'Creating a Snippet' do
end
end
- context 'when there uploaded files' do
+ context 'when there are ActiveRecord validation errors' do
+ let(:title) { '' }
+
+ it_behaves_like 'a mutation that returns errors in the response', errors: ["Title can't be blank"]
+ it_behaves_like 'does not create snippet'
+ end
+
+ context 'when there non ActiveRecord errors' do
+ let(:file_name) { 'invalid://file/path' }
+
+ it_behaves_like 'a mutation that returns errors in the response', errors: ['Repository Error creating the snippet - Invalid file name']
+ it_behaves_like 'does not create snippet'
+ end
+
+ context 'when there are uploaded files' do
shared_examples 'expected files argument' do |file_value, expected_value|
let(:uploaded_files) { file_value }
diff --git a/spec/requests/api/graphql/project/alert_management/alert/assignees_spec.rb b/spec/requests/api/graphql/project/alert_management/alert/assignees_spec.rb
new file mode 100644
index 00000000000..4c048caaeee
--- /dev/null
+++ b/spec/requests/api/graphql/project/alert_management/alert/assignees_spec.rb
@@ -0,0 +1,78 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'getting Alert Management Alert Assignees' do
+ include GraphqlHelpers
+
+ let_it_be(:project) { create(:project) }
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:first_alert) { create(:alert_management_alert, project: project, assignees: [current_user]) }
+ let_it_be(:second_alert) { create(:alert_management_alert, project: project) }
+
+ let(:params) { {} }
+
+ let(:fields) do
+ <<~QUERY
+ nodes {
+ iid
+ assignees {
+ nodes {
+ username
+ }
+ }
+ }
+ QUERY
+ end
+
+ let(:query) do
+ graphql_query_for(
+ 'project',
+ { 'fullPath' => project.full_path },
+ query_graphql_field('alertManagementAlerts', params, fields)
+ )
+ end
+
+ let(:alerts) { graphql_data.dig('project', 'alertManagementAlerts', 'nodes') }
+ let(:assignees) { alerts.map { |alert| [alert['iid'], alert['assignees']['nodes']] }.to_h }
+ let(:first_assignees) { assignees[first_alert.iid.to_s] }
+ let(:second_assignees) { assignees[second_alert.iid.to_s] }
+
+ before do
+ project.add_developer(current_user)
+ end
+
+ it 'returns the correct assignees' do
+ post_graphql(query, current_user: current_user)
+
+ expect(first_assignees.length).to eq(1)
+ expect(first_assignees.first).to include('username' => current_user.username)
+ expect(second_assignees).to be_empty
+ end
+
+ it 'applies appropriate filters for non-visible users' do
+ allow(Ability).to receive(:allowed?).and_call_original
+ allow(Ability).to receive(:allowed?).with(current_user, :read_user, current_user).and_return(false)
+
+ post_graphql(query, current_user: current_user)
+
+ expect(first_assignees).to be_empty
+ expect(second_assignees).to be_empty
+ end
+
+ it 'avoids N+1 queries' do
+ base_count = ActiveRecord::QueryRecorder.new do
+ post_graphql(query, current_user: current_user)
+ end
+
+ # An N+1 would mean a new alert would increase the query count
+ third_alert = create(:alert_management_alert, project: project, assignees: [current_user])
+
+ expect { post_graphql(query, current_user: current_user) }.not_to exceed_query_limit(base_count)
+
+ third_assignees = assignees[third_alert.iid.to_s]
+
+ expect(third_assignees.length).to eq(1)
+ expect(third_assignees.first).to include('username' => current_user.username)
+ end
+end
diff --git a/spec/requests/api/graphql/project/alert_management/alert/notes_spec.rb b/spec/requests/api/graphql/project/alert_management/alert/notes_spec.rb
new file mode 100644
index 00000000000..df6bfa8c97b
--- /dev/null
+++ b/spec/requests/api/graphql/project/alert_management/alert/notes_spec.rb
@@ -0,0 +1,67 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'getting Alert Management Alert Notes' do
+ include GraphqlHelpers
+
+ let_it_be(:project) { create(:project) }
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:first_alert) { create(:alert_management_alert, project: project, assignees: [current_user]) }
+ let_it_be(:second_alert) { create(:alert_management_alert, project: project) }
+ let_it_be(:first_system_note) { create(:note_on_alert, noteable: first_alert, project: project) }
+ let_it_be(:second_system_note) { create(:note_on_alert, noteable: first_alert, project: project) }
+
+ let(:params) { {} }
+
+ let(:fields) do
+ <<~QUERY
+ nodes {
+ iid
+ notes {
+ nodes {
+ id
+ }
+ }
+ }
+ QUERY
+ end
+
+ let(:query) do
+ graphql_query_for(
+ 'project',
+ { 'fullPath' => project.full_path },
+ query_graphql_field('alertManagementAlerts', params, fields)
+ )
+ end
+
+ let(:alerts_result) { graphql_data.dig('project', 'alertManagementAlerts', 'nodes') }
+ let(:notes_result) { alerts_result.map { |alert| [alert['iid'], alert['notes']['nodes']] }.to_h }
+ let(:first_notes_result) { notes_result[first_alert.iid.to_s] }
+ let(:second_notes_result) { notes_result[second_alert.iid.to_s] }
+
+ before do
+ project.add_developer(current_user)
+ end
+
+ it 'returns the notes ordered by createdAt' do
+ post_graphql(query, current_user: current_user)
+
+ expect(first_notes_result.length).to eq(2)
+ expect(first_notes_result.first).to include('id' => first_system_note.to_global_id.to_s)
+ expect(first_notes_result.second).to include('id' => second_system_note.to_global_id.to_s)
+ expect(second_notes_result).to be_empty
+ end
+
+ it 'avoids N+1 queries' do
+ base_count = ActiveRecord::QueryRecorder.new do
+ post_graphql(query, current_user: current_user)
+ end
+
+ # An N+1 would mean a new alert would increase the query count
+ create(:alert_management_alert, project: project)
+
+ expect { post_graphql(query, current_user: current_user) }.not_to exceed_query_limit(base_count)
+ expect(alerts_result.length).to eq(3)
+ end
+end
diff --git a/spec/requests/api/graphql/project/alert_management/alert_status_counts_spec.rb b/spec/requests/api/graphql/project/alert_management/alert_status_counts_spec.rb
index ffd328429ef..a0d1ff7efc5 100644
--- a/spec/requests/api/graphql/project/alert_management/alert_status_counts_spec.rb
+++ b/spec/requests/api/graphql/project/alert_management/alert_status_counts_spec.rb
@@ -56,6 +56,22 @@ describe 'getting Alert Management Alert counts by status' do
'ignored' => 0
)
end
+
+ context 'with search criteria' do
+ let(:params) { { search: alert_1.title } }
+
+ it_behaves_like 'a working graphql query'
+ it 'returns the correct counts for each status' do
+ expect(alert_counts).to eq(
+ 'open' => 0,
+ 'all' => 1,
+ 'triggered' => 0,
+ 'acknowledged' => 0,
+ 'resolved' => 1,
+ 'ignored' => 0
+ )
+ end
+ end
end
end
end
diff --git a/spec/requests/api/graphql/project/alert_management/alerts_spec.rb b/spec/requests/api/graphql/project/alert_management/alerts_spec.rb
index c226e659364..c591895f295 100644
--- a/spec/requests/api/graphql/project/alert_management/alerts_spec.rb
+++ b/spec/requests/api/graphql/project/alert_management/alerts_spec.rb
@@ -10,12 +10,13 @@ describe 'getting Alert Management Alerts' do
let_it_be(:resolved_alert) { create(:alert_management_alert, :all_fields, :resolved, project: project, issue: nil, severity: :low) }
let_it_be(:triggered_alert) { create(:alert_management_alert, :all_fields, project: project, severity: :critical, payload: payload) }
let_it_be(:other_project_alert) { create(:alert_management_alert, :all_fields) }
+
let(:params) { {} }
let(:fields) do
<<~QUERY
nodes {
- #{all_graphql_fields_for('AlertManagementAlert'.classify)}
+ #{all_graphql_fields_for('AlertManagementAlert', excluded: ['assignees'])}
}
QUERY
end
diff --git a/spec/requests/api/graphql/project/container_expiration_policy_spec.rb b/spec/requests/api/graphql/project/container_expiration_policy_spec.rb
new file mode 100644
index 00000000000..d0563f9ff05
--- /dev/null
+++ b/spec/requests/api/graphql/project/container_expiration_policy_spec.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+describe 'getting a repository in a project' do
+ include GraphqlHelpers
+
+ let_it_be(:project) { create(:project) }
+ let_it_be(:current_user) { project.owner }
+ let_it_be(:container_expiration_policy) { project.container_expiration_policy }
+
+ let(:fields) do
+ <<~QUERY
+ #{all_graphql_fields_for('container_expiration_policy'.classify)}
+ QUERY
+ end
+ let(:query) do
+ graphql_query_for(
+ 'project',
+ { 'fullPath' => project.full_path },
+ query_graphql_field('containerExpirationPolicy', {}, fields)
+ )
+ end
+
+ before do
+ stub_config(registry: { enabled: true })
+ post_graphql(query, current_user: current_user)
+ end
+
+ it_behaves_like 'a working graphql query'
+end
diff --git a/spec/requests/api/graphql/project/issues_spec.rb b/spec/requests/api/graphql/project/issues_spec.rb
index 91fce3eed92..3128f527356 100644
--- a/spec/requests/api/graphql/project/issues_spec.rb
+++ b/spec/requests/api/graphql/project/issues_spec.rb
@@ -124,7 +124,7 @@ describe 'getting an issue list for a project' do
graphql_query_for(
'project',
{ 'fullPath' => sort_project.full_path },
- "issues(#{params}) { #{page_info} edges { node { iid dueDate } } }"
+ query_graphql_field('issues', params, "#{page_info} edges { node { iid dueDate} }")
)
end
diff --git a/spec/requests/api/graphql/project/jira_import_spec.rb b/spec/requests/api/graphql/project/jira_import_spec.rb
index e063068eb1a..7be14696963 100644
--- a/spec/requests/api/graphql/project/jira_import_spec.rb
+++ b/spec/requests/api/graphql/project/jira_import_spec.rb
@@ -7,9 +7,30 @@ describe 'query Jira import data' do
let_it_be(:current_user) { create(:user) }
let_it_be(:project) { create(:project, :private, :import_started, import_type: 'jira') }
- let_it_be(:jira_import1) { create(:jira_import_state, :finished, project: project, jira_project_key: 'AA', user: current_user, created_at: 2.days.ago) }
- let_it_be(:jira_import2) { create(:jira_import_state, :finished, project: project, jira_project_key: 'BB', user: current_user, created_at: 5.days.ago) }
-
+ let_it_be(:jira_import1) do
+ create(
+ :jira_import_state, :finished,
+ project: project,
+ jira_project_key: 'AA',
+ user: current_user,
+ created_at: 2.days.ago,
+ failed_to_import_count: 2,
+ imported_issues_count: 2,
+ total_issue_count: 4
+ )
+ end
+ let_it_be(:jira_import2) do
+ create(
+ :jira_import_state, :finished,
+ project: project,
+ jira_project_key: 'BB',
+ user: current_user,
+ created_at: 5.days.ago,
+ failed_to_import_count: 1,
+ imported_issues_count: 2,
+ total_issue_count: 3
+ )
+ end
let(:query) do
%(
query {
@@ -23,6 +44,9 @@ describe 'query Jira import data' do
scheduledBy {
username
}
+ importedIssuesCount
+ failedToImportCount
+ totalIssueCount
}
}
}
@@ -64,10 +88,16 @@ describe 'query Jira import data' do
it 'retuns list of jira imports' do
jira_proket_keys = jira_imports.map {|ji| ji['jiraProjectKey']}
usernames = jira_imports.map {|ji| ji.dig('scheduledBy', 'username')}
+ imported_issues_count = jira_imports.map {|ji| ji.dig('importedIssuesCount')}
+ failed_issues_count = jira_imports.map {|ji| ji.dig('failedToImportCount')}
+ total_issue_count = jira_imports.map {|ji| ji.dig('totalIssueCount')}
expect(jira_imports.size).to eq 2
expect(jira_proket_keys).to eq %w(BB AA)
expect(usernames).to eq [current_user.username, current_user.username]
+ expect(imported_issues_count).to eq [2, 2]
+ expect(failed_issues_count).to eq [1, 2]
+ expect(total_issue_count).to eq [3, 4]
end
end
diff --git a/spec/requests/api/graphql/project/jira_projects_spec.rb b/spec/requests/api/graphql/project/jira_projects_spec.rb
new file mode 100644
index 00000000000..d67c89f18c9
--- /dev/null
+++ b/spec/requests/api/graphql/project/jira_projects_spec.rb
@@ -0,0 +1,114 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'query Jira projects' do
+ include GraphqlHelpers
+
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+
+ include_context 'jira projects request context'
+
+ let(:services) { graphql_data_at(:project, :services, :edges) }
+ let(:jira_projects) { services.first.dig('node', 'projects', 'nodes') }
+ let(:projects_query) { 'projects' }
+ let(:query) do
+ %(
+ query {
+ project(fullPath: "#{project.full_path}") {
+ services(active: true, type: JIRA_SERVICE) {
+ edges {
+ node {
+ ... on JiraService {
+ %{projects_query} {
+ nodes {
+ key
+ name
+ projectId
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ) % { projects_query: projects_query }
+ end
+
+ context 'when user does not have access' do
+ it_behaves_like 'unauthorized users cannot read services'
+ end
+
+ context 'when user can access project services' do
+ before do
+ project.add_maintainer(current_user)
+ post_graphql(query, current_user: current_user)
+ end
+
+ it_behaves_like 'a working graphql query'
+
+ it 'retuns list of jira projects' do
+ project_keys = jira_projects.map { |jp| jp['key'] }
+ project_names = jira_projects.map { |jp| jp['name'] }
+ project_ids = jira_projects.map { |jp| jp['projectId'] }
+
+ expect(jira_projects.size).to eq(2)
+ expect(project_keys).to eq(%w(EX ABC))
+ expect(project_names).to eq(%w(Example Alphabetical))
+ expect(project_ids).to eq([10000, 10001])
+ end
+
+ context 'with pagination' do
+ context 'when fetching limited number of projects' do
+ shared_examples_for 'fetches first project' do
+ it 'retuns first project from list of fetched projects' do
+ project_keys = jira_projects.map { |jp| jp['key'] }
+ project_names = jira_projects.map { |jp| jp['name'] }
+ project_ids = jira_projects.map { |jp| jp['projectId'] }
+
+ expect(jira_projects.size).to eq(1)
+ expect(project_keys).to eq(%w(EX))
+ expect(project_names).to eq(%w(Example))
+ expect(project_ids).to eq([10000])
+ end
+ end
+
+ context 'without cursor' do
+ let(:projects_query) { 'projects(first: 1)' }
+
+ it_behaves_like 'fetches first project'
+ end
+
+ context 'with before cursor' do
+ let(:projects_query) { 'projects(before: "Mg==", first: 1)' }
+
+ it_behaves_like 'fetches first project'
+ end
+
+ context 'with after cursor' do
+ let(:projects_query) { 'projects(after: "MA==", first: 1)' }
+
+ it_behaves_like 'fetches first project'
+ end
+ end
+
+ context 'with valid but inexistent after cursor' do
+ let(:projects_query) { 'projects(after: "MTk==")' }
+
+ it 'retuns empty list of jira projects' do
+ expect(jira_projects.size).to eq(0)
+ end
+ end
+
+ context 'with invalid after cursor' do
+ let(:projects_query) { 'projects(after: "invalid==")' }
+
+ it 'treats the invalid cursor as no cursor and returns list of jira projects' do
+ expect(jira_projects.size).to eq(2)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/project/labels_query_spec.rb b/spec/requests/api/graphql/project/labels_query_spec.rb
new file mode 100644
index 00000000000..ecc43e0a3db
--- /dev/null
+++ b/spec/requests/api/graphql/project/labels_query_spec.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'getting project label information' do
+ include GraphqlHelpers
+
+ let_it_be(:project) { create(:project, :public) }
+ let_it_be(:label_factory) { :label }
+ let_it_be(:label_attrs) { { project: project } }
+
+ it_behaves_like 'querying a GraphQL type with labels' do
+ let(:path_prefix) { ['project'] }
+
+ def make_query(fields)
+ graphql_query_for('project', { full_path: project.full_path }, fields)
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/project/merge_request_spec.rb b/spec/requests/api/graphql/project/merge_request_spec.rb
index 8d8c31c335d..643532bf2e2 100644
--- a/spec/requests/api/graphql/project/merge_request_spec.rb
+++ b/spec/requests/api/graphql/project/merge_request_spec.rb
@@ -37,6 +37,30 @@ describe 'getting merge request information nested in a project' do
expect(merge_request_graphql_data['webUrl']).to be_present
end
+ it 'includes author' do
+ post_graphql(query, current_user: current_user)
+
+ expect(merge_request_graphql_data['author']['username']).to eq(merge_request.author.username)
+ end
+
+ it 'includes correct mergedAt value when merged' do
+ time = 1.week.ago
+ merge_request.mark_as_merged
+ merge_request.metrics.update_columns(merged_at: time)
+
+ post_graphql(query, current_user: current_user)
+ retrieved = merge_request_graphql_data['mergedAt']
+
+ expect(Time.zone.parse(retrieved)).to be_within(1.second).of(time)
+ end
+
+ it 'includes nil mergedAt value when not merged' do
+ post_graphql(query, current_user: current_user)
+ retrieved = merge_request_graphql_data['mergedAt']
+
+ expect(retrieved).to be_nil
+ end
+
context 'permissions on the merge request' do
it 'includes the permissions for the current user on a public project' do
expected_permissions = {
diff --git a/spec/requests/api/graphql/project/merge_requests_spec.rb b/spec/requests/api/graphql/project/merge_requests_spec.rb
new file mode 100644
index 00000000000..49fdfe29874
--- /dev/null
+++ b/spec/requests/api/graphql/project/merge_requests_spec.rb
@@ -0,0 +1,174 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'getting merge request listings nested in a project' do
+ include GraphqlHelpers
+
+ let_it_be(:project) { create(:project, :repository, :public) }
+ let_it_be(:current_user) { create(:user) }
+
+ let_it_be(:label) { create(:label) }
+ let_it_be(:merge_request_a) { create(:labeled_merge_request, :unique_branches, source_project: project, labels: [label]) }
+ let_it_be(:merge_request_b) { create(:merge_request, :closed, :unique_branches, source_project: project) }
+ let_it_be(:merge_request_c) { create(:labeled_merge_request, :closed, :unique_branches, source_project: project, labels: [label]) }
+ let_it_be(:merge_request_d) { create(:merge_request, :locked, :unique_branches, source_project: project) }
+
+ let(:results) { graphql_data.dig('project', 'mergeRequests', 'nodes') }
+
+ let(:search_params) { nil }
+
+ def query_merge_requests(fields)
+ graphql_query_for(
+ :project,
+ { full_path: project.full_path },
+ query_graphql_field(:merge_requests, search_params, [
+ query_graphql_field(:nodes, nil, fields)
+ ])
+ )
+ end
+
+ let(:query) do
+ query_merge_requests(all_graphql_fields_for('MergeRequest', max_depth: 1))
+ end
+
+ it_behaves_like 'a working graphql query' do
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+ end
+
+ # The following tests are needed to guarantee that we have correctly annotated
+ # all the gitaly calls. Selecting combinations of fields may mask this due to
+ # memoization.
+ context 'requesting a single field' do
+ let_it_be(:fresh_mr) { create(:merge_request, :unique_branches, source_project: project) }
+ let(:search_params) { { iids: [fresh_mr.iid.to_s] } }
+
+ before do
+ project.repository.expire_branches_cache
+ end
+
+ context 'selecting any single scalar field' do
+ where(:field) do
+ scalar_fields_of('MergeRequest').map { |name| [name] }
+ end
+
+ with_them do
+ it_behaves_like 'a working graphql query' do
+ let(:query) do
+ query_merge_requests([:iid, field].uniq)
+ end
+
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+
+ it 'selects the correct MR' do
+ expect(results).to contain_exactly(a_hash_including('iid' => fresh_mr.iid.to_s))
+ end
+ end
+ end
+ end
+
+ context 'selecting any single nested field' do
+ where(:field, :subfield, :is_connection) do
+ nested_fields_of('MergeRequest').flat_map do |name, field|
+ type = field_type(field)
+ is_connection = type.name.ends_with?('Connection')
+ type = field_type(type.fields['nodes']) if is_connection
+
+ type.fields
+ .select { |_, field| !nested_fields?(field) && !required_arguments?(field) }
+ .map(&:first)
+ .map { |subfield| [name, subfield, is_connection] }
+ end
+ end
+
+ with_them do
+ it_behaves_like 'a working graphql query' do
+ let(:query) do
+ fld = is_connection ? query_graphql_field(:nodes, nil, [subfield]) : subfield
+ query_merge_requests([:iid, query_graphql_field(field, nil, [fld])])
+ end
+
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+
+ it 'selects the correct MR' do
+ expect(results).to contain_exactly(a_hash_including('iid' => fresh_mr.iid.to_s))
+ end
+ end
+ end
+ end
+ end
+
+ shared_examples 'searching with parameters' do
+ let(:expected) do
+ mrs.map { |mr| a_hash_including('iid' => mr.iid.to_s, 'title' => mr.title) }
+ end
+
+ it 'finds the right mrs' do
+ post_graphql(query, current_user: current_user)
+
+ expect(results).to match_array(expected)
+ end
+ end
+
+ context 'there are no search params' do
+ let(:search_params) { nil }
+ let(:mrs) { [merge_request_a, merge_request_b, merge_request_c, merge_request_d] }
+
+ it_behaves_like 'searching with parameters'
+ end
+
+ context 'the search params do not match anything' do
+ let(:search_params) { { iids: %w(foo bar baz) } }
+ let(:mrs) { [] }
+
+ it_behaves_like 'searching with parameters'
+ end
+
+ context 'searching by iids' do
+ let(:search_params) { { iids: mrs.map(&:iid).map(&:to_s) } }
+ let(:mrs) { [merge_request_a, merge_request_c] }
+
+ it_behaves_like 'searching with parameters'
+ end
+
+ context 'searching by state' do
+ let(:search_params) { { state: :closed } }
+ let(:mrs) { [merge_request_b, merge_request_c] }
+
+ it_behaves_like 'searching with parameters'
+ end
+
+ context 'searching by source_branch' do
+ let(:search_params) { { source_branches: mrs.map(&:source_branch) } }
+ let(:mrs) { [merge_request_b, merge_request_c] }
+
+ it_behaves_like 'searching with parameters'
+ end
+
+ context 'searching by target_branch' do
+ let(:search_params) { { target_branches: mrs.map(&:target_branch) } }
+ let(:mrs) { [merge_request_a, merge_request_d] }
+
+ it_behaves_like 'searching with parameters'
+ end
+
+ context 'searching by label' do
+ let(:search_params) { { labels: [label.title] } }
+ let(:mrs) { [merge_request_a, merge_request_c] }
+
+ it_behaves_like 'searching with parameters'
+ end
+
+ context 'searching by combination' do
+ let(:search_params) { { state: :closed, labels: [label.title] } }
+ let(:mrs) { [merge_request_c] }
+
+ it_behaves_like 'searching with parameters'
+ end
+end
diff --git a/spec/requests/api/graphql/project/pipeline_spec.rb b/spec/requests/api/graphql/project/pipeline_spec.rb
new file mode 100644
index 00000000000..bed9a18577f
--- /dev/null
+++ b/spec/requests/api/graphql/project/pipeline_spec.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'getting pipeline information nested in a project' do
+ include GraphqlHelpers
+
+ let(:project) { create(:project, :repository, :public) }
+ let(:pipeline) { create(:ci_pipeline, project: project) }
+ let(:current_user) { create(:user) }
+ let(:pipeline_graphql_data) { graphql_data['project']['pipeline'] }
+
+ let(:query) do
+ graphql_query_for(
+ 'project',
+ { 'fullPath' => project.full_path },
+ query_graphql_field('pipeline', iid: pipeline.iid.to_s)
+ )
+ end
+
+ it_behaves_like 'a working graphql query' do
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+ end
+
+ it 'contains pipeline information' do
+ post_graphql(query, current_user: current_user)
+
+ expect(pipeline_graphql_data).not_to be_nil
+ end
+end
diff --git a/spec/requests/api/graphql/project/release_spec.rb b/spec/requests/api/graphql/project/release_spec.rb
new file mode 100644
index 00000000000..f8624a97a2b
--- /dev/null
+++ b/spec/requests/api/graphql/project/release_spec.rb
@@ -0,0 +1,206 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'pp'
+
+describe 'Query.project(fullPath).release(tagName)' do
+ include GraphqlHelpers
+ include Presentable
+
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:milestone_1) { create(:milestone, project: project) }
+ let_it_be(:milestone_2) { create(:milestone, project: project) }
+ let_it_be(:release) { create(:release, :with_evidence, project: project, milestones: [milestone_1, milestone_2]) }
+ let_it_be(:release_link_1) { create(:release_link, release: release) }
+ let_it_be(:release_link_2) { create(:release_link, release: release) }
+ let_it_be(:developer) { create(:user) }
+
+ let(:current_user) { developer }
+
+ def query(rq = release_fields)
+ graphql_query_for(:project, { fullPath: project.full_path },
+ query_graphql_field(:release, { tagName: release.tag }, rq))
+ end
+
+ let(:post_query) { post_graphql(query, current_user: current_user) }
+ let(:path_prefix) { %w[project release] }
+
+ let(:data) { graphql_data.dig(*path) }
+
+ before do
+ project.add_developer(developer)
+ end
+
+ describe 'scalar fields' do
+ let(:path) { path_prefix }
+ let(:release_fields) do
+ query_graphql_field(%{
+ tagName
+ tagPath
+ description
+ descriptionHtml
+ name
+ createdAt
+ releasedAt
+ })
+ end
+
+ before do
+ post_query
+ end
+
+ it 'finds all release data' do
+ expect(data).to eq({
+ 'tagName' => release.tag,
+ 'tagPath' => project_tag_path(project, release.tag),
+ 'description' => release.description,
+ 'descriptionHtml' => release.description_html,
+ 'name' => release.name,
+ 'createdAt' => release.created_at.iso8601,
+ 'releasedAt' => release.released_at.iso8601
+ })
+ end
+ end
+
+ describe 'milestones' do
+ let(:path) { path_prefix + %w[milestones nodes] }
+ let(:release_fields) do
+ query_graphql_field(:milestones, nil, 'nodes { id title }')
+ end
+
+ it 'finds all milestones associated to a release' do
+ post_query
+
+ expected = release.milestones.map do |milestone|
+ { 'id' => global_id_of(milestone), 'title' => milestone.title }
+ end
+
+ expect(data).to match_array(expected)
+ end
+ end
+
+ describe 'author' do
+ let(:path) { path_prefix + %w[author] }
+ let(:release_fields) do
+ query_graphql_field(:author, nil, 'id username')
+ end
+
+ it 'finds the author of the release' do
+ post_query
+
+ expect(data).to eq({
+ 'id' => global_id_of(release.author),
+ 'username' => release.author.username
+ })
+ end
+ end
+
+ describe 'commit' do
+ let(:path) { path_prefix + %w[commit] }
+ let(:release_fields) do
+ query_graphql_field(:commit, nil, 'sha')
+ end
+
+ it 'finds the commit associated with the release' do
+ post_query
+
+ expect(data).to eq({ 'sha' => release.commit.sha })
+ end
+ end
+
+ describe 'assets' do
+ describe 'assetsCount' do
+ let(:path) { path_prefix + %w[assets] }
+ let(:release_fields) do
+ query_graphql_field(:assets, nil, 'assetsCount')
+ end
+
+ it 'returns the number of assets associated to the release' do
+ post_query
+
+ expect(data).to eq({ 'assetsCount' => release.sources.size + release.links.size })
+ end
+ end
+
+ describe 'links' do
+ let(:path) { path_prefix + %w[assets links nodes] }
+ let(:release_fields) do
+ query_graphql_field(:assets, nil,
+ query_graphql_field(:links, nil, 'nodes { id name url external }'))
+ end
+
+ it 'finds all release links' do
+ post_query
+
+ expected = release.links.map do |link|
+ {
+ 'id' => global_id_of(link),
+ 'name' => link.name,
+ 'url' => link.url,
+ 'external' => link.external?
+ }
+ end
+
+ expect(data).to match_array(expected)
+ end
+ end
+
+ describe 'sources' do
+ let(:path) { path_prefix + %w[assets sources nodes] }
+ let(:release_fields) do
+ query_graphql_field(:assets, nil,
+ query_graphql_field(:sources, nil, 'nodes { format url }'))
+ end
+
+ it 'finds all release sources' do
+ post_query
+
+ expected = release.sources.map do |source|
+ {
+ 'format' => source.format,
+ 'url' => source.url
+ }
+ end
+
+ expect(data).to match_array(expected)
+ end
+ end
+
+ describe 'evidences' do
+ let(:path) { path_prefix + %w[evidences] }
+ let(:release_fields) do
+ query_graphql_field(:evidences, nil, 'nodes { id sha filepath collectedAt }')
+ end
+
+ context 'for a developer' do
+ it 'finds all evidence fields' do
+ post_query
+
+ evidence = release.evidences.first.present
+ expected = {
+ 'id' => global_id_of(evidence),
+ 'sha' => evidence.sha,
+ 'filepath' => evidence.filepath,
+ 'collectedAt' => evidence.collected_at.utc.iso8601
+ }
+
+ expect(data["nodes"].first).to eq(expected)
+ end
+ end
+
+ context 'for a guest' do
+ let(:current_user) { create :user }
+
+ before do
+ project.add_guest(current_user)
+ end
+
+ it 'denies access' do
+ post_query
+
+ expect(data['node']).to be_nil
+ end
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/project_query_spec.rb b/spec/requests/api/graphql/project_query_spec.rb
index 035894c8022..9a88b47eea6 100644
--- a/spec/requests/api/graphql/project_query_spec.rb
+++ b/spec/requests/api/graphql/project_query_spec.rb
@@ -62,6 +62,54 @@ describe 'getting project information' do
end
end
+ describe 'performance' do
+ before do
+ project.add_developer(current_user)
+ mrs = create_list(:merge_request, 10, :closed, :with_head_pipeline,
+ source_project: project,
+ author: current_user)
+ mrs.each do |mr|
+ mr.assignees << create(:user)
+ mr.assignees << current_user
+ end
+ end
+
+ def run_query(number)
+ q = <<~GQL
+ query {
+ project(fullPath: "#{project.full_path}") {
+ mergeRequests(first: #{number}) {
+ nodes {
+ assignees { nodes { username } }
+ headPipeline { status }
+ }
+ }
+ }
+ }
+ GQL
+
+ post_graphql(q, current_user: current_user)
+ end
+
+ it 'returns appropriate results' do
+ run_query(2)
+
+ mrs = graphql_data.dig('project', 'mergeRequests', 'nodes')
+
+ expect(mrs.size).to eq(2)
+ expect(mrs).to all(
+ match(
+ a_hash_including(
+ 'assignees' => { 'nodes' => all(match(a_hash_including('username' => be_present))) },
+ 'headPipeline' => { 'status' => be_present }
+ )))
+ end
+
+ it 'can lookahead to eliminate N+1 queries', :use_clean_rails_memory_store_caching, :request_store do
+ expect { run_query(10) }.to issue_same_number_of_queries_as { run_query(1) }.or_fewer.ignoring_cached_queries
+ end
+ end
+
context 'when the user does not have access to the project' do
it 'returns an empty field' do
post_graphql(query, current_user: current_user)
diff --git a/spec/requests/api/graphql/tasks/task_completion_status_spec.rb b/spec/requests/api/graphql/tasks/task_completion_status_spec.rb
index c727750c0ce..c47406ea534 100644
--- a/spec/requests/api/graphql/tasks/task_completion_status_spec.rb
+++ b/spec/requests/api/graphql/tasks/task_completion_status_spec.rb
@@ -5,9 +5,9 @@ require 'spec_helper'
describe 'getting task completion status information' do
include GraphqlHelpers
- DESCRIPTION_0_DONE = '- [ ] task 1\n- [ ] task 2'
- DESCRIPTION_1_DONE = '- [x] task 1\n- [ ] task 2'
- DESCRIPTION_2_DONE = '- [x] task 1\n- [x] task 2'
+ description_0_done = '- [ ] task 1\n- [ ] task 2'
+ description_1_done = '- [x] task 1\n- [ ] task 2'
+ description_2_done = '- [x] task 1\n- [x] task 2'
let_it_be(:user1) { create(:user) }
let_it_be(:project) { create(:project, :repository, :public) }
@@ -42,7 +42,7 @@ describe 'getting task completion status information' do
end
end
- [DESCRIPTION_0_DONE, DESCRIPTION_1_DONE, DESCRIPTION_2_DONE].each do |desc|
+ [description_0_done, description_1_done, description_2_done].each do |desc|
context "with description #{desc}" do
context 'when type is issue' do
it_behaves_like 'graphql task completion status provider', 'issue' do
diff --git a/spec/requests/api/graphql/user/group_member_query_spec.rb b/spec/requests/api/graphql/user/group_member_query_spec.rb
new file mode 100644
index 00000000000..022ee79297c
--- /dev/null
+++ b/spec/requests/api/graphql/user/group_member_query_spec.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'GroupMember' do
+ include GraphqlHelpers
+
+ let_it_be(:member) { create(:group_member, :developer) }
+ let_it_be(:fields) do
+ <<~HEREDOC
+ nodes {
+ accessLevel {
+ integerValue
+ stringValue
+ }
+ group {
+ id
+ }
+ }
+ HEREDOC
+ end
+ let_it_be(:query) do
+ graphql_query_for('user', { id: member.user.to_global_id.to_s }, query_graphql_field("groupMemberships", {}, fields))
+ end
+
+ before do
+ post_graphql(query, current_user: member.user)
+ end
+
+ it_behaves_like 'a working graphql query'
+ it_behaves_like 'a working membership object query'
+end
diff --git a/spec/requests/api/graphql/user/project_member_query_spec.rb b/spec/requests/api/graphql/user/project_member_query_spec.rb
new file mode 100644
index 00000000000..397d2872189
--- /dev/null
+++ b/spec/requests/api/graphql/user/project_member_query_spec.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'ProjectMember' do
+ include GraphqlHelpers
+
+ let_it_be(:member) { create(:project_member, :developer) }
+ let_it_be(:fields) do
+ <<~HEREDOC
+ nodes {
+ accessLevel {
+ integerValue
+ stringValue
+ }
+ project {
+ id
+ }
+ }
+ HEREDOC
+ end
+ let_it_be(:query) do
+ graphql_query_for('user', { id: member.user.to_global_id.to_s }, query_graphql_field("projectMemberships", {}, fields))
+ end
+
+ before do
+ post_graphql(query, current_user: member.user)
+ end
+
+ it_behaves_like 'a working graphql query'
+ it_behaves_like 'a working membership object query'
+end
diff --git a/spec/requests/api/graphql/user_query_spec.rb b/spec/requests/api/graphql/user_query_spec.rb
new file mode 100644
index 00000000000..5ac94bc7323
--- /dev/null
+++ b/spec/requests/api/graphql/user_query_spec.rb
@@ -0,0 +1,260 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'getting user information' do
+ include GraphqlHelpers
+
+ let(:query) do
+ graphql_query_for(:user, user_params, user_fields)
+ end
+
+ let(:user_fields) { all_graphql_fields_for('User', max_depth: 2) }
+
+ context 'no parameters are provided' do
+ let(:user_params) { nil }
+
+ it 'mentions the missing required parameters' do
+ post_graphql(query)
+
+ expect_graphql_errors_to_include(/username/)
+ end
+ end
+
+ context 'looking up a user by username' do
+ let_it_be(:project_a) { create(:project, :repository) }
+ let_it_be(:project_b) { create(:project, :repository) }
+ let_it_be(:user, reload: true) { create(:user, developer_projects: [project_a, project_b]) }
+ let_it_be(:authorised_user) { create(:user, developer_projects: [project_a, project_b]) }
+ let_it_be(:unauthorized_user) { create(:user) }
+
+ let_it_be(:assigned_mr) do
+ create(:merge_request, :unique_branches,
+ source_project: project_a, assignees: [user])
+ end
+ let_it_be(:assigned_mr_b) do
+ create(:merge_request, :unique_branches,
+ source_project: project_b, assignees: [user])
+ end
+ let_it_be(:assigned_mr_c) do
+ create(:merge_request, :unique_branches,
+ source_project: project_b, assignees: [user])
+ end
+ let_it_be(:authored_mr) do
+ create(:merge_request, :unique_branches,
+ source_project: project_a, author: user)
+ end
+ let_it_be(:authored_mr_b) do
+ create(:merge_request, :unique_branches,
+ source_project: project_b, author: user)
+ end
+ let_it_be(:authored_mr_c) do
+ create(:merge_request, :unique_branches,
+ source_project: project_b, author: user)
+ end
+
+ let(:current_user) { authorised_user }
+ let(:authored_mrs) { graphql_data_at(:user, :authored_merge_requests, :nodes) }
+ let(:assigned_mrs) { graphql_data_at(:user, :assigned_merge_requests, :nodes) }
+ let(:user_params) { { username: user.username } }
+
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+
+ context 'the user is an active user' do
+ it_behaves_like 'a working graphql query'
+
+ it 'can access user profile fields' do
+ presenter = UserPresenter.new(user)
+
+ expect(graphql_data['user']).to match(
+ a_hash_including(
+ 'id' => global_id_of(user),
+ 'state' => presenter.state,
+ 'name' => presenter.name,
+ 'username' => presenter.username,
+ 'webUrl' => presenter.web_url,
+ 'avatarUrl' => presenter.avatar_url
+ ))
+ end
+
+ describe 'assignedMergeRequests' do
+ let(:user_fields) do
+ query_graphql_field(:assigned_merge_requests, mr_args, 'nodes { id }')
+ end
+ let(:mr_args) { nil }
+
+ it_behaves_like 'a working graphql query'
+
+ it 'can be found' do
+ expect(assigned_mrs).to contain_exactly(
+ a_hash_including('id' => global_id_of(assigned_mr)),
+ a_hash_including('id' => global_id_of(assigned_mr_b)),
+ a_hash_including('id' => global_id_of(assigned_mr_c))
+ )
+ end
+
+ context 'applying filters' do
+ context 'filtering by IID without specifying a project' do
+ let(:mr_args) do
+ { iids: [assigned_mr_b.iid.to_s] }
+ end
+
+ it 'return an argument error that mentions the missing fields' do
+ expect_graphql_errors_to_include(/projectPath/)
+ end
+ end
+
+ context 'filtering by project path and IID' do
+ let(:mr_args) do
+ { project_path: project_b.full_path, iids: [assigned_mr_b.iid.to_s] }
+ end
+
+ it 'selects the correct MRs' do
+ expect(assigned_mrs).to contain_exactly(
+ a_hash_including('id' => global_id_of(assigned_mr_b))
+ )
+ end
+ end
+
+ context 'filtering by project path' do
+ let(:mr_args) do
+ { project_path: project_b.full_path }
+ end
+
+ it 'selects the correct MRs' do
+ expect(assigned_mrs).to contain_exactly(
+ a_hash_including('id' => global_id_of(assigned_mr_b)),
+ a_hash_including('id' => global_id_of(assigned_mr_c))
+ )
+ end
+ end
+ end
+
+ context 'the current user does not have access' do
+ let(:current_user) { unauthorized_user }
+
+ it 'cannot be found' do
+ expect(assigned_mrs).to be_empty
+ end
+ end
+ end
+
+ describe 'authoredMergeRequests' do
+ let(:user_fields) do
+ query_graphql_field(:authored_merge_requests, mr_args, 'nodes { id }')
+ end
+ let(:mr_args) { nil }
+
+ it_behaves_like 'a working graphql query'
+
+ it 'can be found' do
+ expect(authored_mrs).to contain_exactly(
+ a_hash_including('id' => global_id_of(authored_mr)),
+ a_hash_including('id' => global_id_of(authored_mr_b)),
+ a_hash_including('id' => global_id_of(authored_mr_c))
+ )
+ end
+
+ context 'applying filters' do
+ context 'filtering by IID without specifying a project' do
+ let(:mr_args) do
+ { iids: [authored_mr_b.iid.to_s] }
+ end
+
+ it 'return an argument error that mentions the missing fields' do
+ expect_graphql_errors_to_include(/projectPath/)
+ end
+ end
+
+ context 'filtering by project path and IID' do
+ let(:mr_args) do
+ { project_path: project_b.full_path, iids: [authored_mr_b.iid.to_s] }
+ end
+
+ it 'selects the correct MRs' do
+ expect(authored_mrs).to contain_exactly(
+ a_hash_including('id' => global_id_of(authored_mr_b))
+ )
+ end
+ end
+
+ context 'filtering by project path' do
+ let(:mr_args) do
+ { project_path: project_b.full_path }
+ end
+
+ it 'selects the correct MRs' do
+ expect(authored_mrs).to contain_exactly(
+ a_hash_including('id' => global_id_of(authored_mr_b)),
+ a_hash_including('id' => global_id_of(authored_mr_c))
+ )
+ end
+ end
+ end
+
+ context 'the current user does not have access' do
+ let(:current_user) { unauthorized_user }
+
+ it 'cannot be found' do
+ expect(authored_mrs).to be_empty
+ end
+ end
+ end
+ end
+
+ context 'the user is private' do
+ before do
+ user.update(private_profile: true)
+ post_graphql(query, current_user: current_user)
+ end
+
+ context 'we only request basic fields' do
+ let(:user_fields) { %i[id name username state web_url avatar_url] }
+
+ it_behaves_like 'a working graphql query'
+ end
+
+ context 'we request the authoredMergeRequests' do
+ let(:user_fields) { 'authoredMergeRequests { nodes { id } }' }
+
+ it_behaves_like 'a working graphql query'
+
+ it 'cannot be found' do
+ expect(authored_mrs).to be_empty
+ end
+
+ context 'the current user is the user' do
+ let(:current_user) { user }
+
+ it 'can be found' do
+ expect(authored_mrs).to include(
+ a_hash_including('id' => global_id_of(authored_mr))
+ )
+ end
+ end
+ end
+
+ context 'we request the assignedMergeRequests' do
+ let(:user_fields) { 'assignedMergeRequests { nodes { id } }' }
+
+ it_behaves_like 'a working graphql query'
+
+ it 'cannot be found' do
+ expect(assigned_mrs).to be_empty
+ end
+
+ context 'the current user is the user' do
+ let(:current_user) { user }
+
+ it 'can be found' do
+ expect(assigned_mrs).to include(
+ a_hash_including('id' => global_id_of(assigned_mr))
+ )
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/user_spec.rb b/spec/requests/api/graphql/user_spec.rb
new file mode 100644
index 00000000000..097c75b3541
--- /dev/null
+++ b/spec/requests/api/graphql/user_spec.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'User' do
+ include GraphqlHelpers
+
+ let_it_be(:current_user) { create(:user) }
+
+ shared_examples 'a working user query' do
+ it_behaves_like 'a working graphql query' do
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+ end
+
+ it 'includes the user' do
+ post_graphql(query, current_user: current_user)
+
+ expect(graphql_data['user']).not_to be_nil
+ end
+
+ it 'returns no user when global restricted_visibility_levels includes PUBLIC' do
+ stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC])
+
+ post_graphql(query)
+
+ expect(graphql_data['user']).to be_nil
+ end
+ end
+
+ context 'when id parameter is used' do
+ let(:query) { graphql_query_for(:user, { id: current_user.to_global_id.to_s }) }
+
+ it_behaves_like 'a working user query'
+ end
+
+ context 'when username parameter is used' do
+ let(:query) { graphql_query_for(:user, { username: current_user.username.to_s }) }
+
+ it_behaves_like 'a working user query'
+ end
+
+ context 'when username and id parameter are used' do
+ let_it_be(:query) { graphql_query_for(:user, { id: current_user.to_global_id.to_s, username: current_user.username }, 'id') }
+
+ it 'displays an error' do
+ post_graphql(query)
+
+ expect(graphql_errors).to include(
+ a_hash_including('message' => a_string_matching(%r{Provide either a single username or id}))
+ )
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/users_spec.rb b/spec/requests/api/graphql/users_spec.rb
new file mode 100644
index 00000000000..1e6d73cbd7d
--- /dev/null
+++ b/spec/requests/api/graphql/users_spec.rb
@@ -0,0 +1,90 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'Users' do
+ include GraphqlHelpers
+
+ let_it_be(:current_user) { create(:user, created_at: 1.day.ago) }
+ let_it_be(:user1) { create(:user, created_at: 2.days.ago) }
+ let_it_be(:user2) { create(:user, created_at: 3.days.ago) }
+ let_it_be(:user3) { create(:user, created_at: 4.days.ago) }
+
+ describe '.users' do
+ shared_examples 'a working users query' do
+ it_behaves_like 'a working graphql query' do
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+ end
+
+ it 'includes a list of users' do
+ post_graphql(query)
+
+ expect(graphql_data.dig('users', 'nodes')).not_to be_empty
+ end
+ end
+
+ context 'with no arguments' do
+ let_it_be(:query) { graphql_query_for(:users, { usernames: [user1.username] }, 'nodes { id }') }
+
+ it_behaves_like 'a working users query'
+ end
+
+ context 'with a list of usernames' do
+ let(:query) { graphql_query_for(:users, { usernames: [user1.username] }, 'nodes { id }') }
+
+ it_behaves_like 'a working users query'
+ end
+
+ context 'with a list of IDs' do
+ let(:query) { graphql_query_for(:users, { ids: [user1.to_global_id.to_s] }, 'nodes { id }') }
+
+ it_behaves_like 'a working users query'
+ end
+
+ context 'when usernames and ids parameter are used' do
+ let_it_be(:query) { graphql_query_for(:users, { ids: user1.to_global_id.to_s, usernames: user1.username }, 'nodes { id }') }
+
+ it 'displays an error' do
+ post_graphql(query)
+
+ expect(graphql_errors).to include(
+ a_hash_including('message' => a_string_matching(%r{Provide either a list of usernames or ids}))
+ )
+ end
+ end
+ end
+
+ describe 'sorting and pagination' do
+ let_it_be(:data_path) { [:users] }
+
+ def pagination_query(params, page_info)
+ graphql_query_for("users", params, "#{page_info} edges { node { id } }")
+ end
+
+ def pagination_results_data(data)
+ data.map { |user| user.dig('node', 'id') }
+ end
+
+ context 'when sorting by created_at' do
+ let_it_be(:ascending_users) { [user3, user2, user1, current_user].map(&:to_global_id).map(&:to_s) }
+
+ context 'when ascending' do
+ it_behaves_like 'sorted paginated query' do
+ let(:sort_param) { 'created_asc' }
+ let(:first_param) { 1 }
+ let(:expected_results) { ascending_users }
+ end
+ end
+
+ context 'when descending' do
+ it_behaves_like 'sorted paginated query' do
+ let(:sort_param) { 'created_desc' }
+ let(:first_param) { 1 }
+ let(:expected_results) { ascending_users.reverse }
+ end
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/graphql_spec.rb b/spec/requests/api/graphql_spec.rb
index f5c7a820abe..84be5ab0951 100644
--- a/spec/requests/api/graphql_spec.rb
+++ b/spec/requests/api/graphql_spec.rb
@@ -187,4 +187,62 @@ describe 'GraphQL' do
end
end
end
+
+ describe 'keyset pagination' do
+ let_it_be(:project) { create(:project, :public) }
+ let_it_be(:issues) { create_list(:issue, 10, project: project, created_at: Time.now.change(usec: 200)) }
+
+ let(:page_size) { 6 }
+ let(:issues_edges) { %w(data project issues edges) }
+ let(:end_cursor) { %w(data project issues pageInfo endCursor) }
+ let(:query) do
+ <<~GRAPHQL
+ query project($fullPath: ID!, $first: Int, $after: String) {
+ project(fullPath: $fullPath) {
+ issues(first: $first, after: $after) {
+ edges { node { iid } }
+ pageInfo { endCursor }
+ }
+ }
+ }
+ GRAPHQL
+ end
+
+ # TODO: Switch this to use `post_graphql`
+ # This is not performing an actual GraphQL request because the
+ # variables end up being strings when passed through the `post_graphql`
+ # helper.
+ #
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/222432
+ def execute_query(after: nil)
+ GitlabSchema.execute(
+ query,
+ context: { current_user: nil },
+ variables: {
+ fullPath: project.full_path,
+ first: page_size,
+ after: after
+ }
+ )
+ end
+
+ it 'paginates datetimes correctly when they have millisecond data' do
+ # let's make sure we're actually querying a timestamp, just in case
+ expect(Gitlab::Graphql::Pagination::Keyset::QueryBuilder)
+ .to receive(:new).with(anything, anything, hash_including('created_at'), anything).and_call_original
+
+ first_page = execute_query
+ edges = first_page.dig(*issues_edges)
+ cursor = first_page.dig(*end_cursor)
+
+ expect(edges.count).to eq(6)
+ expect(edges.last['node']['iid']).to eq(issues[4].iid.to_s)
+
+ second_page = execute_query(after: cursor)
+ edges = second_page.dig(*issues_edges)
+
+ expect(edges.count).to eq(4)
+ expect(edges.last['node']['iid']).to eq(issues[0].iid.to_s)
+ end
+ end
end
diff --git a/spec/requests/api/group_export_spec.rb b/spec/requests/api/group_export_spec.rb
index 02ae9d71702..9dd7797c768 100644
--- a/spec/requests/api/group_export_spec.rb
+++ b/spec/requests/api/group_export_spec.rb
@@ -82,6 +82,22 @@ describe API::GroupExport do
expect(response).to have_gitlab_http_status(:not_found)
end
end
+
+ context 'when the requests have exceeded the rate limit' do
+ before do
+ allow(Gitlab::ApplicationRateLimiter)
+ .to receive(:increment)
+ .and_return(Gitlab::ApplicationRateLimiter.rate_limits[:group_download_export][:threshold] + 1)
+ end
+
+ it 'throttles the endpoint' do
+ get api(download_path, user)
+
+ expect(json_response["message"])
+ .to include('error' => 'This endpoint has been requested too many times. Try again later.')
+ expect(response).to have_gitlab_http_status :too_many_requests
+ end
+ end
end
describe 'POST /groups/:group_id/export' do
@@ -139,5 +155,23 @@ describe API::GroupExport do
expect(response).to have_gitlab_http_status(:not_found)
end
end
+
+ context 'when the requests have exceeded the rate limit' do
+ before do
+ group.add_owner(user)
+
+ allow(Gitlab::ApplicationRateLimiter)
+ .to receive(:increment)
+ .and_return(Gitlab::ApplicationRateLimiter.rate_limits[:group_export][:threshold] + 1)
+ end
+
+ it 'throttles the endpoint' do
+ post api(path, user)
+
+ expect(json_response["message"])
+ .to include('error' => 'This endpoint has been requested too many times. Try again later.')
+ expect(response).to have_gitlab_http_status :too_many_requests
+ end
+ end
end
end
diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb
index 18feff85482..9a449499576 100644
--- a/spec/requests/api/groups_spec.rb
+++ b/spec/requests/api/groups_spec.rb
@@ -231,6 +231,27 @@ describe API::Groups do
end
end
+ context "when using top_level_only" do
+ let(:top_level_group) { create(:group, name: 'top-level-group') }
+ let(:subgroup) { create(:group, :nested, name: 'subgroup') }
+ let(:response_groups) { json_response.map { |group| group['name'] } }
+
+ before do
+ top_level_group.add_owner(user1)
+ subgroup.add_owner(user1)
+ end
+
+ it "doesn't return subgroups" do
+ get api("/groups", user1), params: { top_level_only: true }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+ expect(response_groups).to include(top_level_group.name)
+ expect(response_groups).not_to include(subgroup.name)
+ end
+ end
+
context "when using sorting" do
let(:group3) { create(:group, name: "a#{group1.name}", path: "z#{group1.path}") }
let(:group4) { create(:group, name: "same-name", path: "y#{group1.path}") }
@@ -415,6 +436,8 @@ describe API::Groups do
it "returns one of user1's groups" do
project = create(:project, namespace: group2, path: 'Foo')
create(:project_group_link, project: project, group: group1)
+ group = create(:group)
+ link = create(:group_group_link, shared_group: group1, shared_with_group: group)
get api("/groups/#{group1.id}", user1)
@@ -439,6 +462,13 @@ describe API::Groups do
expect(json_response['full_path']).to eq(group1.full_path)
expect(json_response['parent_id']).to eq(group1.parent_id)
expect(json_response['created_at']).to be_present
+ expect(json_response['shared_with_groups']).to be_an Array
+ expect(json_response['shared_with_groups'].length).to eq(1)
+ expect(json_response['shared_with_groups'][0]['group_id']).to eq(group.id)
+ expect(json_response['shared_with_groups'][0]['group_name']).to eq(group.name)
+ expect(json_response['shared_with_groups'][0]['group_full_path']).to eq(group.full_path)
+ expect(json_response['shared_with_groups'][0]['group_access_level']).to eq(link.group_access)
+ expect(json_response['shared_with_groups'][0]).to have_key('expires_at')
expect(json_response['projects']).to be_an Array
expect(json_response['projects'].length).to eq(2)
expect(json_response['shared_projects']).to be_an Array
@@ -505,7 +535,7 @@ describe API::Groups do
.to contain_exactly(projects[:public].id, projects[:internal].id)
end
- it 'avoids N+1 queries' do
+ it 'avoids N+1 queries with project links' do
get api("/groups/#{group1.id}", admin)
control_count = ActiveRecord::QueryRecorder.new do
@@ -518,6 +548,24 @@ describe API::Groups do
get api("/groups/#{group1.id}", admin)
end.not_to exceed_query_limit(control_count)
end
+
+ it 'avoids N+1 queries with shared group links' do
+ # setup at least 1 shared group, so that we record the queries that preload the nested associations too.
+ create(:group_group_link, shared_group: group1, shared_with_group: create(:group))
+
+ control_count = ActiveRecord::QueryRecorder.new do
+ get api("/groups/#{group1.id}", admin)
+ end.count
+
+ # setup "n" more shared groups
+ create(:group_group_link, shared_group: group1, shared_with_group: create(:group))
+ create(:group_group_link, shared_group: group1, shared_with_group: create(:group))
+
+ # test that no of queries for 1 shared group is same as for n shared groups
+ expect do
+ get api("/groups/#{group1.id}", admin)
+ end.not_to exceed_query_limit(control_count)
+ end
end
context "when authenticated as admin" do
@@ -1507,4 +1555,173 @@ describe API::Groups do
group2.add_owner(user1)
end
end
+
+ describe "POST /groups/:id/share" do
+ shared_examples 'shares group with group' do
+ it "shares group with group" do
+ expires_at = 10.days.from_now.to_date
+
+ expect do
+ post api("/groups/#{group.id}/share", user), params: { group_id: shared_with_group.id, group_access: Gitlab::Access::DEVELOPER, expires_at: expires_at }
+ end.to change { group.shared_with_group_links.count }.by(1)
+
+ expect(response).to have_gitlab_http_status(:created)
+ expect(json_response['shared_with_groups']).to be_an Array
+ expect(json_response['shared_with_groups'].length).to eq(1)
+ expect(json_response['shared_with_groups'][0]['group_id']).to eq(shared_with_group.id)
+ expect(json_response['shared_with_groups'][0]['group_name']).to eq(shared_with_group.name)
+ expect(json_response['shared_with_groups'][0]['group_full_path']).to eq(shared_with_group.full_path)
+ expect(json_response['shared_with_groups'][0]['group_access_level']).to eq(Gitlab::Access::DEVELOPER)
+ expect(json_response['shared_with_groups'][0]['expires_at']).to eq(expires_at.to_s)
+ end
+
+ it "returns a 400 error when group id is not given" do
+ post api("/groups/#{group.id}/share", user), params: { group_access: Gitlab::Access::DEVELOPER }
+ expect(response).to have_gitlab_http_status(:bad_request)
+ end
+
+ it "returns a 400 error when access level is not given" do
+ post api("/groups/#{group.id}/share", user), params: { group_id: shared_with_group.id }
+ expect(response).to have_gitlab_http_status(:bad_request)
+ end
+
+ it 'returns a 404 error when group does not exist' do
+ post api("/groups/#{group.id}/share", user), params: { group_id: non_existing_record_id, group_access: Gitlab::Access::DEVELOPER }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+
+ it "returns a 400 error when wrong params passed" do
+ post api("/groups/#{group.id}/share", user), params: { group_id: shared_with_group.id, group_access: non_existing_record_access_level }
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response['error']).to eq 'group_access does not have a valid value'
+ end
+
+ it "returns a 409 error when link is not saved" do
+ allow(::Groups::GroupLinks::CreateService).to receive_message_chain(:new, :execute)
+ .and_return({ status: :error, http_status: 409, message: 'error' })
+
+ post api("/groups/#{group.id}/share", user), params: { group_id: shared_with_group.id, group_access: Gitlab::Access::DEVELOPER }
+
+ expect(response).to have_gitlab_http_status(:conflict)
+ end
+ end
+
+ context 'when authenticated as owner' do
+ let(:owner_group) { create(:group) }
+ let(:owner_user) { create(:user) }
+
+ before do
+ owner_group.add_owner(owner_user)
+ end
+
+ it_behaves_like 'shares group with group' do
+ let(:user) { owner_user }
+ let(:group) { owner_group }
+ let(:shared_with_group) { create(:group) }
+ end
+ end
+
+ context 'when the user is not the owner of the group' do
+ let(:group) { create(:group) }
+ let(:user4) { create(:user) }
+ let(:expires_at) { 10.days.from_now.to_date }
+
+ before do
+ group1.add_maintainer(user4)
+ end
+
+ it 'does not create group share' do
+ post api("/groups/#{group1.id}/share", user4), params: { group_id: group.id, group_access: Gitlab::Access::DEVELOPER, expires_at: expires_at }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'when authenticated as admin' do
+ it_behaves_like 'shares group with group' do
+ let(:user) { admin }
+ let(:group) { create(:group) }
+ let(:shared_with_group) { create(:group) }
+ end
+ end
+ end
+
+ describe 'DELETE /groups/:id/share/:group_id' do
+ shared_examples 'deletes group share' do
+ it 'deletes a group share' do
+ expect do
+ delete api("/groups/#{shared_group.id}/share/#{shared_with_group.id}", user)
+
+ expect(response).to have_gitlab_http_status(:no_content)
+ expect(shared_group.shared_with_group_links).to be_empty
+ end.to change { shared_group.shared_with_group_links.count }.by(-1)
+ end
+
+ it 'requires the group id to be an integer' do
+ delete api("/groups/#{shared_group.id}/share/foo", user)
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ end
+
+ it 'returns a 404 error when group link does not exist' do
+ delete api("/groups/#{shared_group.id}/share/#{non_existing_record_id}", user)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+
+ it 'returns a 404 error when group does not exist' do
+ delete api("/groups/123/share/#{non_existing_record_id}", user)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'when authenticated as owner' do
+ let(:group_a) { create(:group) }
+
+ before do
+ create(:group_group_link, shared_group: group1, shared_with_group: group_a)
+ end
+
+ it_behaves_like 'deletes group share' do
+ let(:user) { user1 }
+ let(:shared_group) { group1 }
+ let(:shared_with_group) { group_a }
+ end
+ end
+
+ context 'when the user is not the owner of the group' do
+ let(:group_a) { create(:group) }
+ let(:user4) { create(:user) }
+
+ before do
+ group1.add_maintainer(user4)
+ create(:group_group_link, shared_group: group1, shared_with_group: group_a)
+ end
+
+ it 'does not remove group share' do
+ expect do
+ delete api("/groups/#{group1.id}/share/#{group_a.id}", user4)
+
+ expect(response).to have_gitlab_http_status(:no_content)
+ end.not_to change { group1.shared_with_group_links }
+ end
+ end
+
+ context 'when authenticated as admin' do
+ let(:group_b) { create(:group) }
+
+ before do
+ create(:group_group_link, shared_group: group2, shared_with_group: group_b)
+ end
+
+ it_behaves_like 'deletes group share' do
+ let(:user) { admin }
+ let(:shared_group) { group2 }
+ let(:shared_with_group) { group_b }
+ end
+ end
+ end
end
diff --git a/spec/requests/api/internal/base_spec.rb b/spec/requests/api/internal/base_spec.rb
index 684f0329909..aa5e2367a2b 100644
--- a/spec/requests/api/internal/base_spec.rb
+++ b/spec/requests/api/internal/base_spec.rb
@@ -218,7 +218,15 @@ describe API::Internal::Base do
get(api('/internal/authorized_keys'), params: { fingerprint: key.fingerprint, secret_token: secret_token })
expect(response).to have_gitlab_http_status(:ok)
- expect(json_response["key"]).to eq(key.key)
+ expect(json_response['id']).to eq(key.id)
+ expect(json_response['key'].split[1]).to eq(key.key.split[1])
+ end
+
+ it 'exposes the comment of the key as a simple identifier of username + hostname' do
+ get(api('/internal/authorized_keys'), params: { fingerprint: key.fingerprint, secret_token: secret_token })
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['key']).to include("#{key.user_name} (#{Gitlab.config.gitlab.host})")
end
end
@@ -239,11 +247,21 @@ describe API::Internal::Base do
end
context "sending the key" do
- it "finds the key" do
- get(api('/internal/authorized_keys'), params: { key: key.key.split[1], secret_token: secret_token })
+ context "using an existing key" do
+ it "finds the key" do
+ get(api('/internal/authorized_keys'), params: { key: key.key.split[1], secret_token: secret_token })
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response["key"]).to eq(key.key)
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['id']).to eq(key.id)
+ expect(json_response['key'].split[1]).to eq(key.key.split[1])
+ end
+
+ it 'exposes the comment of the key as a simple identifier of username + hostname' do
+ get(api('/internal/authorized_keys'), params: { fingerprint: key.fingerprint, secret_token: secret_token })
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['key']).to include("#{key.user_name} (#{Gitlab.config.gitlab.host})")
+ end
end
it "returns 404 with a partial key" do
@@ -396,7 +414,7 @@ describe API::Internal::Base do
context "git pull" do
before do
- allow(Feature).to receive(:persisted_names).and_return(%w[gitaly_mep_mep])
+ stub_feature_flags(gitaly_mep_mep: true)
end
it "has the correct payload" do
diff --git a/spec/requests/api/issues/issues_spec.rb b/spec/requests/api/issues/issues_spec.rb
index 06878f57d43..315396c89c3 100644
--- a/spec/requests/api/issues/issues_spec.rb
+++ b/spec/requests/api/issues/issues_spec.rb
@@ -834,6 +834,12 @@ describe API::Issues do
end
end
+ describe 'PUT /projects/:id/issues/:issue_id' do
+ it_behaves_like 'issuable update endpoint' do
+ let(:entity) { issue }
+ end
+ end
+
describe 'DELETE /projects/:id/issues/:issue_iid' do
it 'rejects a non member from deleting an issue' do
delete api("/projects/#{project.id}/issues/#{issue.iid}", non_member)
diff --git a/spec/requests/api/issues/put_projects_issues_spec.rb b/spec/requests/api/issues/put_projects_issues_spec.rb
index 2ab8b9d7877..62a4d3b48b2 100644
--- a/spec/requests/api/issues/put_projects_issues_spec.rb
+++ b/spec/requests/api/issues/put_projects_issues_spec.rb
@@ -5,10 +5,6 @@ require 'spec_helper'
describe API::Issues do
let_it_be(:user) { create(:user) }
let_it_be(:owner) { create(:owner) }
- let_it_be(:project, reload: true) do
- create(:project, :public, creator_id: owner.id, namespace: owner.namespace)
- end
-
let(:user2) { create(:user) }
let(:non_member) { create(:user) }
let_it_be(:guest) { create(:user) }
@@ -17,6 +13,11 @@ describe API::Issues do
let(:admin) { create(:user, :admin) }
let(:issue_title) { 'foo' }
let(:issue_description) { 'closed' }
+
+ let_it_be(:project, reload: true) do
+ create(:project, :public, creator_id: owner.id, namespace: owner.namespace)
+ end
+
let!(:closed_issue) do
create :closed_issue,
author: user,
@@ -28,6 +29,7 @@ describe API::Issues do
updated_at: 3.hours.ago,
closed_at: 1.hour.ago
end
+
let!(:confidential_issue) do
create :issue,
:confidential,
@@ -37,6 +39,7 @@ describe API::Issues do
created_at: generate(:past_time),
updated_at: 2.hours.ago
end
+
let!(:issue) do
create :issue,
author: user,
@@ -48,18 +51,24 @@ describe API::Issues do
title: issue_title,
description: issue_description
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!(:note) { create(:note_on_issue, author: user, project: project, noteable: issue) }
let(:no_milestone_title) { 'None' }
let(:any_milestone_title) { 'Any' }
+ let(:updated_title) { 'updated title' }
+ let(:issue_path) { "/projects/#{project.id}/issues/#{issue.iid}" }
+ let(:api_for_user) { api(issue_path, user) }
before_all do
project.add_reporter(user)
@@ -72,108 +81,97 @@ describe API::Issues do
describe 'PUT /projects/:id/issues/:issue_iid to update only title' do
it 'updates a project issue' do
- put api("/projects/#{project.id}/issues/#{issue.iid}", user),
- params: { title: 'updated title' }
- expect(response).to have_gitlab_http_status(:ok)
+ put api_for_user, params: { title: updated_title }
- expect(json_response['title']).to eq('updated title')
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['title']).to eq(updated_title)
end
it 'returns 404 error if issue iid not found' do
- put api("/projects/#{project.id}/issues/44444", user),
- params: { title: 'updated title' }
+ put api("/projects/#{project.id}/issues/44444", user), params: { title: updated_title }
+
expect(response).to have_gitlab_http_status(:not_found)
end
it 'returns 404 error if issue id is used instead of the iid' do
- put api("/projects/#{project.id}/issues/#{issue.id}", user),
- params: { title: 'updated title' }
+ put api("/projects/#{project.id}/issues/#{issue.id}", user), params: { title: updated_title }
+
expect(response).to have_gitlab_http_status(:not_found)
end
it 'allows special label names' do
- put api("/projects/#{project.id}/issues/#{issue.iid}", user),
+ put api_for_user,
params: {
- title: 'updated title',
+ title: updated_title,
labels: 'label, label?, label&foo, ?, &'
}
expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['labels']).to include 'label'
- expect(json_response['labels']).to include 'label?'
- expect(json_response['labels']).to include 'label&foo'
- expect(json_response['labels']).to include '?'
- expect(json_response['labels']).to include '&'
end
it 'allows special label names with labels param as array' do
- put api("/projects/#{project.id}/issues/#{issue.iid}", user),
+ put api_for_user,
params: {
- title: 'updated title',
+ title: updated_title,
labels: ['label', 'label?', 'label&foo, ?, &']
}
expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['labels']).to include 'label'
- expect(json_response['labels']).to include 'label?'
- expect(json_response['labels']).to include 'label&foo'
- expect(json_response['labels']).to include '?'
- expect(json_response['labels']).to include '&'
+ expect(json_response['labels']).to contain_exactly('label', 'label?', 'label&foo', '?', '&')
end
context 'confidential issues' do
+ let(:confidential_issue_path) { "/projects/#{project.id}/issues/#{confidential_issue.iid}" }
+
it 'returns 403 for non project members' do
- put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", non_member),
- params: { title: 'updated title' }
+ put api(confidential_issue_path, non_member), params: { title: updated_title }
+
expect(response).to have_gitlab_http_status(:forbidden)
end
it 'returns 403 for project members with guest role' do
- put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", guest),
- params: { title: 'updated title' }
+ put api(confidential_issue_path, guest), params: { title: updated_title }
+
expect(response).to have_gitlab_http_status(:forbidden)
end
it 'updates a confidential issue for project members' do
- put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", user),
- params: { title: 'updated title' }
+ put api(confidential_issue_path, user), params: { title: updated_title }
+
expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['title']).to eq('updated title')
+ expect(json_response['title']).to eq(updated_title)
end
it 'updates a confidential issue for author' do
- put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", author),
- params: { title: 'updated title' }
+ put api(confidential_issue_path, author), params: { title: updated_title }
+
expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['title']).to eq('updated title')
+ expect(json_response['title']).to eq(updated_title)
end
it 'updates a confidential issue for admin' do
- put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", admin),
- params: { title: 'updated title' }
+ put api(confidential_issue_path, admin), params: { title: updated_title }
+
expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['title']).to eq('updated title')
+ expect(json_response['title']).to eq(updated_title)
end
it 'sets an issue to confidential' do
- put api("/projects/#{project.id}/issues/#{issue.iid}", user),
- params: { confidential: true }
+ put api_for_user, params: { confidential: true }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['confidential']).to be_truthy
end
it 'makes a confidential issue public' do
- put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", user),
- params: { confidential: false }
+ put api(confidential_issue_path, user), params: { confidential: false }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['confidential']).to be_falsy
end
it 'does not update a confidential issue with wrong confidential flag' do
- put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", user),
- params: { confidential: 'foo' }
+ put api(confidential_issue_path, user), params: { confidential: 'foo' }
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['error']).to eq('confidential is invalid')
@@ -185,12 +183,12 @@ describe API::Issues do
include_context 'includes Spam constants'
def update_issue
- put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: params
+ put api_for_user, params: params
end
let(:params) do
{
- title: 'updated title',
+ title: updated_title,
description: 'content here',
labels: 'label, label2'
}
@@ -224,7 +222,7 @@ describe API::Issues do
it 'creates a new spam log entry' do
expect { update_issue }
- .to log_spam(title: 'updated title', description: 'content here', user_id: user.id, noteable_type: 'Issue')
+ .to log_spam(title: updated_title, description: 'content here', user_id: user.id, noteable_type: 'Issue')
end
end
@@ -241,7 +239,7 @@ describe API::Issues do
it 'creates a new spam log entry' do
expect { update_issue }
- .to log_spam(title: 'updated title', description: 'content here', user_id: user.id, noteable_type: 'Issue')
+ .to log_spam(title: updated_title, description: 'content here', user_id: user.id, noteable_type: 'Issue')
end
end
end
@@ -249,49 +247,39 @@ describe API::Issues do
describe 'PUT /projects/:id/issues/:issue_iid to update assignee' do
context 'support for deprecated assignee_id' do
it 'removes assignee' do
- put api("/projects/#{project.id}/issues/#{issue.iid}", user),
- params: { assignee_id: 0 }
+ put api_for_user, params: { assignee_id: 0 }
expect(response).to have_gitlab_http_status(:ok)
-
expect(json_response['assignee']).to be_nil
end
it 'updates an issue with new assignee' do
- put api("/projects/#{project.id}/issues/#{issue.iid}", user),
- params: { assignee_id: user2.id }
+ put api_for_user, params: { assignee_id: user2.id }
expect(response).to have_gitlab_http_status(:ok)
-
expect(json_response['assignee']['name']).to eq(user2.name)
end
end
it 'removes assignee' do
- put api("/projects/#{project.id}/issues/#{issue.iid}", user),
- params: { assignee_ids: [0] }
+ put api_for_user, params: { assignee_ids: [0] }
expect(response).to have_gitlab_http_status(:ok)
-
expect(json_response['assignees']).to be_empty
end
it 'updates an issue with new assignee' do
- put api("/projects/#{project.id}/issues/#{issue.iid}", user),
- params: { assignee_ids: [user2.id] }
+ put api_for_user, params: { assignee_ids: [user2.id] }
expect(response).to have_gitlab_http_status(:ok)
-
expect(json_response['assignees'].first['name']).to eq(user2.name)
end
context 'single assignee restrictions' do
it 'updates an issue with several assignees but only one has been applied' do
- put api("/projects/#{project.id}/issues/#{issue.iid}", user),
- params: { assignee_ids: [user2.id, guest.id] }
+ put api_for_user, params: { assignee_ids: [user2.id, guest.id] }
expect(response).to have_gitlab_http_status(:ok)
-
expect(json_response['assignees'].size).to eq(1)
end
end
@@ -301,16 +289,42 @@ describe API::Issues do
let!(:label) { create(:label, title: 'dummy', project: project) }
let!(:label_link) { create(:label_link, label: label, target: issue) }
+ it 'adds relevant labels' do
+ put api_for_user, params: { add_labels: '1, 2' }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['labels']).to contain_exactly(label.title, '1', '2')
+ end
+
+ context 'removes' do
+ let!(:label2) { create(:label, title: 'a-label', project: project) }
+ let!(:label_link2) { create(:label_link, label: label2, target: issue) }
+
+ it 'removes relevant labels' do
+ put api_for_user, params: { remove_labels: label2.title }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['labels']).to eq([label.title])
+ end
+
+ it 'removes all labels' do
+ put api_for_user, params: { remove_labels: "#{label.title}, #{label2.title}" }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['labels']).to be_empty
+ end
+ end
+
it 'does not update labels if not present' do
- put api("/projects/#{project.id}/issues/#{issue.iid}", user),
- params: { title: 'updated title' }
+ put api_for_user, params: { title: updated_title }
+
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['labels']).to eq([label.title])
end
it 'removes all labels and touches the record' do
Timecop.travel(1.minute.from_now) do
- put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { labels: '' }
+ put api_for_user, params: { labels: '' }
end
expect(response).to have_gitlab_http_status(:ok)
@@ -320,7 +334,7 @@ describe API::Issues do
it 'removes all labels and touches the record with labels param as array' do
Timecop.travel(1.minute.from_now) do
- put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { labels: [''] }
+ put api_for_user, params: { labels: [''] }
end
expect(response).to have_gitlab_http_status(:ok)
@@ -330,20 +344,19 @@ describe API::Issues do
it 'updates labels and touches the record' do
Timecop.travel(1.minute.from_now) do
- put api("/projects/#{project.id}/issues/#{issue.iid}", user),
- params: { labels: 'foo,bar' }
+ put api_for_user, params: { labels: 'foo,bar' }
end
+
expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['labels']).to include 'foo'
- expect(json_response['labels']).to include 'bar'
+ expect(json_response['labels']).to contain_exactly('foo', 'bar')
expect(json_response['updated_at']).to be > Time.now
end
it 'updates labels and touches the record with labels param as array' do
Timecop.travel(1.minute.from_now) do
- put api("/projects/#{project.id}/issues/#{issue.iid}", user),
- params: { labels: %w(foo bar) }
+ put api_for_user, params: { labels: %w(foo bar) }
end
+
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['labels']).to include 'foo'
expect(json_response['labels']).to include 'bar'
@@ -351,36 +364,22 @@ describe API::Issues do
end
it 'allows special label names' do
- put api("/projects/#{project.id}/issues/#{issue.iid}", user),
- params: { labels: 'label:foo, label-bar,label_bar,label/bar,label?bar,label&bar,?,&' }
+ put api_for_user, params: { labels: 'label:foo, label-bar,label_bar,label/bar,label?bar,label&bar,?,&' }
+
expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['labels']).to include 'label:foo'
- expect(json_response['labels']).to include 'label-bar'
- expect(json_response['labels']).to include 'label_bar'
- expect(json_response['labels']).to include 'label/bar'
- expect(json_response['labels']).to include 'label?bar'
- expect(json_response['labels']).to include 'label&bar'
- expect(json_response['labels']).to include '?'
- expect(json_response['labels']).to include '&'
+ expect(json_response['labels']).to contain_exactly('label:foo', 'label-bar', 'label_bar', 'label/bar', 'label?bar', 'label&bar', '?', '&')
end
it 'allows special label names with labels param as array' do
- put api("/projects/#{project.id}/issues/#{issue.iid}", user),
- params: { labels: ['label:foo', 'label-bar', 'label_bar', 'label/bar,label?bar,label&bar,?,&'] }
+ put api_for_user, params: { labels: ['label:foo', 'label-bar', 'label_bar', 'label/bar,label?bar,label&bar,?,&'] }
+
expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['labels']).to include 'label:foo'
- expect(json_response['labels']).to include 'label-bar'
- expect(json_response['labels']).to include 'label_bar'
- expect(json_response['labels']).to include 'label/bar'
- expect(json_response['labels']).to include 'label?bar'
- expect(json_response['labels']).to include 'label&bar'
- expect(json_response['labels']).to include '?'
- expect(json_response['labels']).to include '&'
+ expect(json_response['labels']).to contain_exactly('label:foo', 'label-bar', 'label_bar', 'label/bar', 'label?bar', 'label&bar', '?', '&')
end
it 'returns 400 if title is too long' do
- put api("/projects/#{project.id}/issues/#{issue.iid}", user),
- params: { title: 'g' * 256 }
+ put api_for_user, params: { title: 'g' * 256 }
+
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['message']['title']).to eq([
'is too long (maximum is 255 characters)'
@@ -390,16 +389,15 @@ describe API::Issues do
describe 'PUT /projects/:id/issues/:issue_iid to update state and label' do
it 'updates a project issue' do
- put api("/projects/#{project.id}/issues/#{issue.iid}", user),
- params: { labels: 'label2', state_event: 'close' }
- expect(response).to have_gitlab_http_status(:ok)
+ put api_for_user, params: { labels: 'label2', state_event: 'close' }
- expect(json_response['labels']).to include 'label2'
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['labels']).to contain_exactly('label2')
expect(json_response['state']).to eq 'closed'
end
it 'reopens a project isssue' do
- put api("/projects/#{project.id}/issues/#{closed_issue.iid}", user), params: { state_event: 'reopen' }
+ put api(issue_path, user), params: { state_event: 'reopen' }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['state']).to eq 'opened'
@@ -411,42 +409,41 @@ describe API::Issues do
it 'accepts the update date to be set' do
update_time = 2.weeks.ago
- put api("/projects/#{project.id}/issues/#{issue.iid}", user),
- params: { title: 'some new title', updated_at: update_time }
+ put api_for_user, params: { title: 'some new title', updated_at: update_time }
expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['title']).to include 'some new title'
+ expect(json_response['title']).to eq('some new title')
expect(Time.parse(json_response['updated_at'])).not_to be_like_time(update_time)
end
end
context 'when admin or owner makes the request' do
+ let(:api_for_owner) { api(issue_path, owner) }
+
it 'not allow to set null for updated_at' do
- put api("/projects/#{project.id}/issues/#{issue.iid}", owner), params: { updated_at: nil }
+ put api_for_owner, params: { updated_at: nil }
expect(response).to have_gitlab_http_status(:bad_request)
end
it 'not allow to set blank for updated_at' do
- put api("/projects/#{project.id}/issues/#{issue.iid}", owner), params: { updated_at: '' }
+ put api_for_owner, params: { updated_at: '' }
expect(response).to have_gitlab_http_status(:bad_request)
end
it 'not allow to set invalid format for updated_at' do
- put api("/projects/#{project.id}/issues/#{issue.iid}", owner), params: { updated_at: 'invalid-format' }
+ put api_for_owner, params: { updated_at: 'invalid-format' }
expect(response).to have_gitlab_http_status(:bad_request)
end
it 'accepts the update date to be set' do
update_time = 2.weeks.ago
- put api("/projects/#{project.id}/issues/#{issue.iid}", owner),
- params: { title: 'some new title', updated_at: update_time }
+ put api_for_owner, params: { title: 'some new title', updated_at: update_time }
expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['title']).to include 'some new title'
-
+ expect(json_response['title']).to eq('some new title')
expect(Time.parse(json_response['updated_at'])).to be_like_time(update_time)
end
end
@@ -456,7 +453,7 @@ describe API::Issues do
it 'creates a new project issue' do
due_date = 2.weeks.from_now.strftime('%Y-%m-%d')
- put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { due_date: due_date }
+ put api_for_user, params: { due_date: due_date }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['due_date']).to eq(due_date)
diff --git a/spec/requests/api/jobs_spec.rb b/spec/requests/api/jobs_spec.rb
index bd8aeb65d3f..18b5c00d64f 100644
--- a/spec/requests/api/jobs_spec.rb
+++ b/spec/requests/api/jobs_spec.rb
@@ -271,6 +271,178 @@ describe API::Jobs do
end
end
+ describe 'GET /projects/:id/pipelines/:pipeline_id/bridges' do
+ let!(:bridge) { create(:ci_bridge, pipeline: pipeline) }
+ let(:downstream_pipeline) { create(:ci_pipeline) }
+
+ let!(:pipeline_source) do
+ create(:ci_sources_pipeline,
+ source_pipeline: pipeline,
+ source_project: project,
+ source_job: bridge,
+ pipeline: downstream_pipeline,
+ project: downstream_pipeline.project)
+ end
+
+ let(:query) { Hash.new }
+
+ before do |example|
+ unless example.metadata[:skip_before_request]
+ get api("/projects/#{project.id}/pipelines/#{pipeline.id}/bridges", api_user), params: query
+ end
+ end
+
+ context 'authorized user' do
+ it 'returns pipeline bridges' do
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+ end
+
+ it 'returns correct values' do
+ expect(json_response).not_to be_empty
+ expect(json_response.first['commit']['id']).to eq project.commit.id
+ expect(json_response.first['id']).to eq bridge.id
+ expect(json_response.first['name']).to eq bridge.name
+ expect(json_response.first['stage']).to eq bridge.stage
+ end
+
+ it 'returns pipeline data' do
+ json_bridge = json_response.first
+
+ expect(json_bridge['pipeline']).not_to be_empty
+ expect(json_bridge['pipeline']['id']).to eq bridge.pipeline.id
+ expect(json_bridge['pipeline']['ref']).to eq bridge.pipeline.ref
+ expect(json_bridge['pipeline']['sha']).to eq bridge.pipeline.sha
+ expect(json_bridge['pipeline']['status']).to eq bridge.pipeline.status
+ end
+
+ it 'returns downstream pipeline data' do
+ json_bridge = json_response.first
+
+ expect(json_bridge['downstream_pipeline']).not_to be_empty
+ expect(json_bridge['downstream_pipeline']['id']).to eq downstream_pipeline.id
+ expect(json_bridge['downstream_pipeline']['ref']).to eq downstream_pipeline.ref
+ expect(json_bridge['downstream_pipeline']['sha']).to eq downstream_pipeline.sha
+ expect(json_bridge['downstream_pipeline']['status']).to eq downstream_pipeline.status
+ end
+
+ context 'filter bridges' do
+ before do
+ create_bridge(pipeline, :pending)
+ create_bridge(pipeline, :running)
+ end
+
+ context 'with one scope element' do
+ let(:query) { { 'scope' => 'pending' } }
+
+ it :skip_before_request do
+ get api("/projects/#{project.id}/pipelines/#{pipeline.id}/bridges", api_user), params: query
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to be_an Array
+ expect(json_response.count).to eq 1
+ expect(json_response.first["status"]).to eq "pending"
+ end
+ end
+
+ context 'with array of scope elements' do
+ let(:query) { { scope: %w(pending running) } }
+
+ it :skip_before_request do
+ get api("/projects/#{project.id}/pipelines/#{pipeline.id}/bridges", api_user), params: query
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to be_an Array
+ expect(json_response.count).to eq 2
+ json_response.each { |r| expect(%w(pending running).include?(r['status'])).to be true }
+ end
+ end
+ end
+
+ context 'respond 400 when scope contains invalid state' do
+ let(:query) { { scope: %w(unknown running) } }
+
+ it { expect(response).to have_gitlab_http_status(:bad_request) }
+ end
+
+ context 'bridges in different pipelines' do
+ let!(:pipeline2) { create(:ci_empty_pipeline, project: project) }
+ let!(:bridge2) { create(:ci_bridge, pipeline: pipeline2) }
+
+ it 'excludes bridges from other pipelines' do
+ json_response.each { |bridge| expect(bridge['pipeline']['id']).to eq(pipeline.id) }
+ end
+ end
+
+ it 'avoids N+1 queries' do
+ control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do
+ get api("/projects/#{project.id}/pipelines/#{pipeline.id}/bridges", api_user), params: query
+ end.count
+
+ 3.times { create_bridge(pipeline) }
+
+ expect do
+ get api("/projects/#{project.id}/pipelines/#{pipeline.id}/bridges", api_user), params: query
+ end.not_to exceed_all_query_limit(control_count)
+ end
+ end
+
+ context 'unauthorized user' do
+ context 'when user is not logged in' do
+ let(:api_user) { nil }
+
+ it 'does not return bridges' do
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
+ end
+
+ context 'when user is guest' do
+ let(:api_user) { guest }
+
+ it 'does not return bridges' do
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
+ end
+
+ context 'when user has no read access for pipeline' do
+ before do
+ allow(Ability).to receive(:allowed?).and_call_original
+ allow(Ability).to receive(:allowed?).with(api_user, :read_pipeline, pipeline).and_return(false)
+ end
+
+ it 'does not return bridges' do
+ get api("/projects/#{project.id}/pipelines/#{pipeline.id}/bridges", api_user)
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
+ end
+
+ context 'when user has no read_build access for project' do
+ before do
+ allow(Ability).to receive(:allowed?).and_call_original
+ allow(Ability).to receive(:allowed?).with(api_user, :read_build, project).and_return(false)
+ end
+
+ it 'does not return bridges' do
+ get api("/projects/#{project.id}/pipelines/#{pipeline.id}/bridges", api_user)
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
+ end
+ end
+
+ def create_bridge(pipeline, status = :created)
+ create(:ci_bridge, status: status, pipeline: pipeline).tap do |bridge|
+ downstream_pipeline = create(:ci_pipeline)
+ create(:ci_sources_pipeline,
+ source_pipeline: pipeline,
+ source_project: pipeline.project,
+ source_job: bridge,
+ pipeline: downstream_pipeline,
+ project: downstream_pipeline.project)
+ end
+ end
+ end
+
describe 'GET /projects/:id/jobs/:job_id' do
before do |example|
unless example.metadata[:skip_before_request]
diff --git a/spec/requests/api/labels_spec.rb b/spec/requests/api/labels_spec.rb
index 1f17359a473..697f22e5f29 100644
--- a/spec/requests/api/labels_spec.rb
+++ b/spec/requests/api/labels_spec.rb
@@ -17,7 +17,7 @@ describe API::Labels do
let(:user) { create(:user) }
let(:project) { create(:project, creator_id: user.id, namespace: user.namespace) }
- let!(:label1) { create(:label, title: 'label1', project: project) }
+ let!(:label1) { create(:label, description: 'the best label', title: 'label1', project: project) }
let!(:priority_label) { create(:label, title: 'bug', project: project, priority: 3) }
route_types = [:deprecated, :rest]
@@ -219,7 +219,7 @@ describe API::Labels do
'closed_issues_count' => 1,
'open_merge_requests_count' => 0,
'name' => label1.name,
- 'description' => nil,
+ 'description' => 'the best label',
'color' => a_string_matching(/^#\h{6}$/),
'text_color' => a_string_matching(/^#\h{6}$/),
'priority' => nil,
diff --git a/spec/requests/api/lsif_data_spec.rb b/spec/requests/api/lsif_data_spec.rb
deleted file mode 100644
index a1516046e3e..00000000000
--- a/spec/requests/api/lsif_data_spec.rb
+++ /dev/null
@@ -1,95 +0,0 @@
-# frozen_string_literal: true
-
-require "spec_helper"
-
-describe API::LsifData do
- let_it_be(:user) { create(:user) }
- let_it_be(:project) { create(:project, :repository) }
-
- let(:commit) { project.commit }
-
- describe 'GET lsif/info' do
- subject do
- endpoint_path = "/projects/#{project.id}/commits/#{commit.id}/lsif/info"
-
- get api(endpoint_path, user), params: { paths: ['main.go', 'morestrings/reverse.go'] }
-
- response
- end
-
- context 'user does not have access to the project' do
- before do
- project.add_guest(user)
- end
-
- it { is_expected.to have_gitlab_http_status(:forbidden) }
- end
-
- context 'user has access to the project' do
- before do
- project.add_reporter(user)
- end
-
- context 'there is no job artifact for the passed commit' do
- it { is_expected.to have_gitlab_http_status(:not_found) }
- end
-
- context 'lsif data is stored as a job artifact' do
- let!(:pipeline) { create(:ci_pipeline, project: project, sha: commit.id) }
- let!(:artifact) { create(:ci_job_artifact, :lsif, job: create(:ci_build, pipeline: pipeline)) }
-
- context 'code_navigation feature is disabled' do
- before do
- stub_feature_flags(code_navigation: false)
- end
-
- it { is_expected.to have_gitlab_http_status(:not_found) }
- end
-
- it 'returns code navigation info for a given path', :aggregate_failures do
- expect(subject).to have_gitlab_http_status(:ok)
-
- data_for_main = response.parsed_body['main.go']
- expect(data_for_main.last).to eq({
- 'end_char' => 18,
- 'end_line' => 8,
- 'start_char' => 13,
- 'start_line' => 8,
- 'definition_url' => project_blob_path(project, "#{commit.id}/morestrings/reverse.go", anchor: 'L5'),
- 'hover' => [{
- 'language' => 'go',
- 'value' => Gitlab::Highlight.highlight(nil, 'func Func2(i int) string', language: 'go')
- }]
- })
-
- data_for_reverse = response.parsed_body['morestrings/reverse.go']
- expect(data_for_reverse.last).to eq({
- 'end_char' => 9,
- 'end_line' => 7,
- 'start_char' => 8,
- 'start_line' => 7,
- 'definition_url' => project_blob_path(project, "#{commit.id}/morestrings/reverse.go", anchor: 'L6'),
- 'hover' => [{
- 'language' => 'go',
- 'value' => Gitlab::Highlight.highlight(nil, 'var b string', language: 'go')
- }]
- })
- end
-
- context 'the stored file is too large' do
- before do
- allow_any_instance_of(JobArtifactUploader).to receive(:cached_size).and_return(20.megabytes)
- end
-
- it { is_expected.to have_gitlab_http_status(:payload_too_large) }
- end
-
- context 'the user does not have access to the pipeline' do
- let(:project) { create(:project, :repository, builds_access_level: ProjectFeature::DISABLED) }
-
- it { is_expected.to have_gitlab_http_status(:forbidden) }
- end
- end
- end
- end
-end
diff --git a/spec/requests/api/markdown_spec.rb b/spec/requests/api/markdown_spec.rb
index 09342b06744..53e43430b1f 100644
--- a/spec/requests/api/markdown_spec.rb
+++ b/spec/requests/api/markdown_spec.rb
@@ -52,6 +52,7 @@ describe API::Markdown do
context "when arguments are valid" do
let_it_be(:project) { create(:project) }
let_it_be(:issue) { create(:issue, project: project) }
+ let(:issue_url) { "http://#{Gitlab.config.gitlab.host}/#{issue.project.namespace.path}/#{issue.project.path}/-/issues/#{issue.iid}" }
let(:text) { ":tada: Hello world! :100: #{issue.to_reference}" }
context "when not using gfm" do
@@ -88,7 +89,7 @@ describe API::Markdown do
.and include('data-name="tada"')
.and include('data-name="100"')
.and include("#1")
- .and exclude("<a href=\"#{IssuesHelper.url_for_issue(issue.iid, project)}\"")
+ .and exclude("<a href=\"#{issue_url}\"")
.and exclude("#1</a>")
end
end
@@ -104,16 +105,16 @@ describe API::Markdown do
expect(json_response["html"]).to include("Hello world!")
.and include('data-name="tada"')
.and include('data-name="100"')
- .and include("<a href=\"#{IssuesHelper.url_for_issue(issue.iid, project)}\"")
+ .and include("<a href=\"#{issue_url}\"")
.and include("#1</a>")
end
end
context 'with a public project and confidential issue' do
- let(:public_project) { create(:project, :public) }
- let(:confidential_issue) { create(:issue, :confidential, project: public_project, title: 'Confidential title') }
+ let(:public_project) { create(:project, :public) }
+ let(:issue) { create(:issue, :confidential, project: public_project, title: 'Confidential title') }
- let(:text) { ":tada: Hello world! :100: #{confidential_issue.to_reference}" }
+ let(:text) { ":tada: Hello world! :100: #{issue.to_reference}" }
let(:params) { { text: text, gfm: true, project: public_project.full_path } }
shared_examples 'user without proper access' do
@@ -141,7 +142,7 @@ describe API::Markdown do
end
context 'when logged in as author' do
- let(:user) { confidential_issue.author }
+ let(:user) { issue.author }
it 'renders the title or link' do
expect(response).to have_gitlab_http_status(:created)
@@ -149,7 +150,7 @@ describe API::Markdown do
expect(json_response["html"]).to include('Hello world!')
.and include('data-name="tada"')
.and include('data-name="100"')
- .and include("<a href=\"#{IssuesHelper.url_for_issue(confidential_issue.iid, public_project)}\"")
+ .and include("<a href=\"#{issue_url}\"")
.and include("#1</a>")
end
end
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index 14b22de9661..7a0077f853a 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -1654,6 +1654,12 @@ describe API::MergeRequests do
end
end
+ describe 'PUT /projects/:id/merge_reuests/:merge_request_iid' do
+ it_behaves_like 'issuable update endpoint' do
+ let(:entity) { merge_request }
+ end
+ end
+
describe "POST /projects/:id/merge_requests/:merge_request_iid/context_commits" do
let(:merge_request_iid) { merge_request.iid }
let(:authenticated_user) { user }
@@ -2023,6 +2029,34 @@ describe API::MergeRequests do
end
end
+ context "with a merge request that has force_remove_source_branch enabled" do
+ let(:source_repository) { merge_request.source_project.repository }
+ let(:source_branch) { merge_request.source_branch }
+
+ before do
+ merge_request.update(merge_params: { 'force_remove_source_branch' => true })
+ end
+
+ it 'removes the source branch' do
+ put(
+ api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user)
+ )
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(source_repository.branch_exists?(source_branch)).to be_falsy
+ end
+
+ it 'does not remove the source branch' do
+ put(
+ api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user),
+ params: { should_remove_source_branch: false }
+ )
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(source_repository.branch_exists?(source_branch)).to be_truthy
+ end
+ end
+
context "performing a ff-merge with squash" do
let(:merge_request) { create(:merge_request, :rebased, source_project: project, squash: true) }
diff --git a/spec/requests/api/oauth_tokens_spec.rb b/spec/requests/api/oauth_tokens_spec.rb
index 80eae97f41a..5e775841f12 100644
--- a/spec/requests/api/oauth_tokens_spec.rb
+++ b/spec/requests/api/oauth_tokens_spec.rb
@@ -3,16 +3,22 @@
require 'spec_helper'
describe 'OAuth tokens' do
+ include HttpBasicAuthHelpers
+
context 'Resource Owner Password Credentials' do
- def request_oauth_token(user)
- post '/oauth/token', params: { username: user.username, password: user.password, grant_type: 'password' }
+ def request_oauth_token(user, headers = {})
+ post '/oauth/token',
+ params: { username: user.username, password: user.password, grant_type: 'password' },
+ headers: headers
end
+ let_it_be(:client) { create(:oauth_application) }
+
context 'when user has 2FA enabled' do
it 'does not create an access token' do
user = create(:user, :two_factor)
- request_oauth_token(user)
+ request_oauth_token(user, client_basic_auth_header(client))
expect(response).to have_gitlab_http_status(:unauthorized)
expect(json_response['error']).to eq('invalid_grant')
@@ -20,13 +26,46 @@ describe 'OAuth tokens' do
end
context 'when user does not have 2FA enabled' do
- it 'creates an access token' do
- user = create(:user)
+ # NOTE: using ROPS grant flow without client credentials will be deprecated
+ # and removed in the next version of Doorkeeper.
+ # See https://gitlab.com/gitlab-org/gitlab/-/issues/219137
+ context 'when no client credentials provided' do
+ it 'creates an access token' do
+ user = create(:user)
+
+ request_oauth_token(user)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['access_token']).not_to be_nil
+ end
+ end
+
+ context 'when client credentials provided' do
+ context 'with valid credentials' do
+ it 'creates an access token' do
+ user = create(:user)
+
+ request_oauth_token(user, client_basic_auth_header(client))
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['access_token']).not_to be_nil
+ end
+ end
+
+ context 'with invalid credentials' do
+ it 'does not create an access token' do
+ # NOTE: remove this after update to Doorkeeper 5.5 or newer, see
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/219137
+ pending 'Enable this example after upgrading Doorkeeper to 5.5 or newer'
+
+ user = create(:user)
- request_oauth_token(user)
+ request_oauth_token(user, basic_auth_header(client.uid, 'invalid secret'))
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['access_token']).not_to be_nil
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ expect(json_response['error']).to eq('invalid_client')
+ end
+ end
end
end
@@ -40,7 +79,7 @@ describe 'OAuth tokens' do
before do
user.block
- request_oauth_token(user)
+ request_oauth_token(user, client_basic_auth_header(client))
end
include_examples 'does not create an access token'
@@ -50,7 +89,7 @@ describe 'OAuth tokens' do
before do
user.ldap_block
- request_oauth_token(user)
+ request_oauth_token(user, client_basic_auth_header(client))
end
include_examples 'does not create an access token'
@@ -60,7 +99,7 @@ describe 'OAuth tokens' do
before do
user.update!(confirmed_at: nil)
- request_oauth_token(user)
+ request_oauth_token(user, client_basic_auth_header(client))
end
include_examples 'does not create an access token'
diff --git a/spec/requests/api/project_container_repositories_spec.rb b/spec/requests/api/project_container_repositories_spec.rb
index 91905635c3f..471fc99117b 100644
--- a/spec/requests/api/project_container_repositories_spec.rb
+++ b/spec/requests/api/project_container_repositories_spec.rb
@@ -223,6 +223,40 @@ describe API::ProjectContainerRepositories do
expect(response).to have_gitlab_http_status(:accepted)
end
end
+
+ context 'with invalid regex' do
+ let(:invalid_regex) { '*v10.' }
+ let(:lease_key) { "container_repository:cleanup_tags:#{root_repository.id}" }
+
+ RSpec.shared_examples 'rejecting the invalid regex' do |param_name|
+ it 'does not enqueue a job' do
+ expect(CleanupContainerRepositoryWorker).not_to receive(:perform_async)
+
+ subject
+ end
+
+ it_behaves_like 'returning response status', :bad_request
+
+ it 'returns an error message' do
+ subject
+
+ expect(json_response['error']).to include("#{param_name} is an invalid regexp")
+ end
+ end
+
+ before do
+ stub_last_activity_update
+ stub_exclusive_lease(lease_key, timeout: 1.hour)
+ end
+
+ %i[name_regex_delete name_regex name_regex_keep].each do |param_name|
+ context "for #{param_name}" do
+ let(:params) { { param_name => invalid_regex } }
+
+ it_behaves_like 'rejecting the invalid regex', param_name
+ end
+ end
+ end
end
end
diff --git a/spec/requests/api/project_events_spec.rb b/spec/requests/api/project_events_spec.rb
index 489b83de434..f65c62f9402 100644
--- a/spec/requests/api/project_events_spec.rb
+++ b/spec/requests/api/project_events_spec.rb
@@ -7,7 +7,7 @@ describe API::ProjectEvents do
let(:non_member) { create(:user) }
let(:private_project) { create(:project, :private, creator_id: user.id, namespace: user.namespace) }
let(:closed_issue) { create(:closed_issue, project: private_project, author: user) }
- let!(:closed_issue_event) { create(:event, project: private_project, author: user, target: closed_issue, action: Event::CLOSED, created_at: Date.new(2016, 12, 30)) }
+ let!(:closed_issue_event) { create(:event, project: private_project, author: user, target: closed_issue, action: :closed, created_at: Date.new(2016, 12, 30)) }
describe 'GET /projects/:id/events' do
context 'when unauthenticated ' do
@@ -29,9 +29,9 @@ describe API::ProjectEvents do
context 'with inaccessible events' do
let(:public_project) { create(:project, :public, creator_id: user.id, namespace: user.namespace) }
let(:confidential_issue) { create(:closed_issue, confidential: true, project: public_project, author: user) }
- let!(:confidential_event) { create(:event, project: public_project, author: user, target: confidential_issue, action: Event::CLOSED) }
+ let!(:confidential_event) { create(:event, project: public_project, author: user, target: confidential_issue, action: :closed) }
let(:public_issue) { create(:closed_issue, project: public_project, author: user) }
- let!(:public_event) { create(:event, project: public_project, author: user, target: public_issue, action: Event::CLOSED) }
+ let!(:public_event) { create(:event, project: public_project, author: user, target: public_issue, action: :closed) }
it 'returns only accessible events' do
get api("/projects/#{public_project.id}/events", non_member)
@@ -53,19 +53,19 @@ describe API::ProjectEvents do
before do
create(:event,
+ :closed,
project: public_project,
target: create(:issue, project: public_project, title: 'Issue 1'),
- action: Event::CLOSED,
created_at: Date.parse('2018-12-10'))
create(:event,
+ :closed,
project: public_project,
target: create(:issue, confidential: true, project: public_project, title: 'Confidential event'),
- action: Event::CLOSED,
created_at: Date.parse('2018-12-11'))
create(:event,
+ :closed,
project: public_project,
target: create(:issue, project: public_project, title: 'Issue 2'),
- action: Event::CLOSED,
created_at: Date.parse('2018-12-12'))
end
diff --git a/spec/requests/api/project_export_spec.rb b/spec/requests/api/project_export_spec.rb
index ad872b88664..58034322a13 100644
--- a/spec/requests/api/project_export_spec.rb
+++ b/spec/requests/api/project_export_spec.rb
@@ -44,19 +44,6 @@ describe API::ProjectExport, :clean_gitlab_redis_cache do
it_behaves_like '404 response'
end
- shared_examples_for 'when rate limit is exceeded' do
- before do
- allow(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).and_return(true)
- end
-
- it 'prevents requesting project export' do
- request
-
- expect(response).to have_gitlab_http_status(:too_many_requests)
- expect(json_response['message']['error']).to eq('This endpoint has been requested too many times. Try again later.')
- end
- end
-
describe 'GET /projects/:project_id/export' do
shared_examples_for 'get project export status not found' do
it_behaves_like '404 response' do
@@ -247,7 +234,18 @@ describe API::ProjectExport, :clean_gitlab_redis_cache do
context 'when rate limit is exceeded' do
let(:request) { get api(download_path, admin) }
- include_examples 'when rate limit is exceeded'
+ before do
+ allow(Gitlab::ApplicationRateLimiter)
+ .to receive(:increment)
+ .and_return(Gitlab::ApplicationRateLimiter.rate_limits[:project_download_export][:threshold] + 1)
+ end
+
+ it 'prevents requesting project export' do
+ request
+
+ expect(response).to have_gitlab_http_status(:too_many_requests)
+ expect(json_response['message']['error']).to eq('This endpoint has been requested too many times. Try again later.')
+ end
end
end
@@ -360,10 +358,19 @@ describe API::ProjectExport, :clean_gitlab_redis_cache do
it_behaves_like 'post project export start'
- context 'when rate limit is exceeded' do
- let(:request) { post api(path, admin) }
+ context 'when rate limit is exceeded across projects' do
+ before do
+ allow(Gitlab::ApplicationRateLimiter)
+ .to receive(:increment)
+ .and_return(Gitlab::ApplicationRateLimiter.rate_limits[:project_export][:threshold] + 1)
+ end
+
+ it 'prevents requesting project export' do
+ post api(path, admin)
- include_examples 'when rate limit is exceeded'
+ expect(response).to have_gitlab_http_status(:too_many_requests)
+ expect(json_response['message']['error']).to eq('This endpoint has been requested too many times. Try again later.')
+ end
end
end
diff --git a/spec/requests/api/project_repository_storage_moves_spec.rb b/spec/requests/api/project_repository_storage_moves_spec.rb
index 7ceea0178f3..40966e31d0d 100644
--- a/spec/requests/api/project_repository_storage_moves_spec.rb
+++ b/spec/requests/api/project_repository_storage_moves_spec.rb
@@ -5,12 +5,45 @@ require 'spec_helper'
describe API::ProjectRepositoryStorageMoves do
include AccessMatchersForRequest
- let(:user) { create(:admin) }
- let!(:storage_move) { create(:project_repository_storage_move, :scheduled) }
+ let_it_be(:user) { create(:admin) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:storage_move) { create(:project_repository_storage_move, :scheduled, project: project) }
- describe 'GET /project_repository_storage_moves' do
+ shared_examples 'get single project repository storage move' do
+ let(:project_repository_storage_move_id) { storage_move.id }
+
+ def get_project_repository_storage_move
+ get api(url, user)
+ end
+
+ it 'returns a project repository storage move' do
+ get_project_repository_storage_move
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to match_response_schema('public_api/v4/project_repository_storage_move')
+ expect(json_response['id']).to eq(storage_move.id)
+ expect(json_response['state']).to eq(storage_move.human_state_name)
+ end
+
+ context 'non-existent project repository storage move' do
+ let(:project_repository_storage_move_id) { non_existing_record_id }
+
+ it 'returns not found' do
+ get_project_repository_storage_move
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ describe 'permissions' do
+ it { expect { get_project_repository_storage_move }.to be_allowed_for(:admin) }
+ it { expect { get_project_repository_storage_move }.to be_denied_for(:user) }
+ end
+ end
+
+ shared_examples 'get project repository storage move list' do
def get_project_repository_storage_moves
- get api('/project_repository_storage_moves', user)
+ get api(url, user)
end
it 'returns project repository storage moves' do
@@ -30,16 +63,16 @@ describe API::ProjectRepositoryStorageMoves do
control = ActiveRecord::QueryRecorder.new { get_project_repository_storage_moves }
- create(:project_repository_storage_move, :scheduled)
+ create(:project_repository_storage_move, :scheduled, project: project)
expect { get_project_repository_storage_moves }.not_to exceed_query_limit(control)
end
it 'returns the most recently created first' do
- storage_move_oldest = create(:project_repository_storage_move, :scheduled, created_at: 2.days.ago)
- storage_move_middle = create(:project_repository_storage_move, :scheduled, created_at: 1.day.ago)
+ storage_move_oldest = create(:project_repository_storage_move, :scheduled, project: project, created_at: 2.days.ago)
+ storage_move_middle = create(:project_repository_storage_move, :scheduled, project: project, created_at: 1.day.ago)
- get api('/project_repository_storage_moves', user)
+ get_project_repository_storage_moves
json_ids = json_response.map {|storage_move| storage_move['id'] }
expect(json_ids).to eq([
@@ -55,35 +88,68 @@ describe API::ProjectRepositoryStorageMoves do
end
end
- describe 'GET /project_repository_storage_moves/:id' do
- let(:project_repository_storage_move_id) { storage_move.id }
+ describe 'GET /project_repository_storage_moves' do
+ it_behaves_like 'get project repository storage move list' do
+ let(:url) { '/project_repository_storage_moves' }
+ end
+ end
- def get_project_repository_storage_move
- get api("/project_repository_storage_moves/#{project_repository_storage_move_id}", user)
+ describe 'GET /project_repository_storage_moves/:repository_storage_move_id' do
+ it_behaves_like 'get single project repository storage move' do
+ let(:url) { "/project_repository_storage_moves/#{project_repository_storage_move_id}" }
end
+ end
- it 'returns a project repository storage move' do
- get_project_repository_storage_move
+ describe 'GET /projects/:id/repository_storage_moves' do
+ it_behaves_like 'get project repository storage move list' do
+ let(:url) { "/projects/#{project.id}/repository_storage_moves" }
+ end
+ end
- expect(response).to have_gitlab_http_status(:ok)
- expect(response).to match_response_schema('public_api/v4/project_repository_storage_move')
- expect(json_response['id']).to eq(storage_move.id)
- expect(json_response['state']).to eq(storage_move.human_state_name)
+ describe 'GET /projects/:id/repository_storage_moves/:repository_storage_move_id' do
+ it_behaves_like 'get single project repository storage move' do
+ let(:url) { "/projects/#{project.id}/repository_storage_moves/#{project_repository_storage_move_id}" }
end
+ end
- context 'non-existent project repository storage move' do
- let(:project_repository_storage_move_id) { non_existing_record_id }
+ describe 'POST /projects/:id/repository_storage_moves' do
+ let(:url) { "/projects/#{project.id}/repository_storage_moves" }
+ let(:destination_storage_name) { 'test_second_storage' }
- it 'returns not found' do
- get_project_repository_storage_move
+ def create_project_repository_storage_move
+ post api(url, user), params: { destination_storage_name: destination_storage_name }
+ end
- expect(response).to have_gitlab_http_status(:not_found)
- end
+ before do
+ stub_storage_settings('test_second_storage' => { 'path' => 'tmp/tests/extra_storage' })
+ end
+
+ it 'schedules a project repository storage move' do
+ create_project_repository_storage_move
+
+ storage_move = project.repository_storage_moves.last
+
+ expect(response).to have_gitlab_http_status(:created)
+ expect(response).to match_response_schema('public_api/v4/project_repository_storage_move')
+ expect(json_response['id']).to eq(storage_move.id)
+ expect(json_response['state']).to eq('scheduled')
+ expect(json_response['source_storage_name']).to eq('default')
+ expect(json_response['destination_storage_name']).to eq(destination_storage_name)
end
describe 'permissions' do
- it { expect { get_project_repository_storage_move }.to be_allowed_for(:admin) }
- it { expect { get_project_repository_storage_move }.to be_denied_for(:user) }
+ it { expect { create_project_repository_storage_move }.to be_allowed_for(:admin) }
+ it { expect { create_project_repository_storage_move }.to be_denied_for(:user) }
+ end
+
+ context 'destination_storage_name is missing' do
+ let(:destination_storage_name) { nil }
+
+ it 'returns a validation error' do
+ create_project_repository_storage_move
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ end
end
end
end
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 3abcf1cb7ed..c3f29ec47a9 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -597,6 +597,10 @@ describe API::Projects do
expect(response.header).to include('Links')
expect(response.header['Links']).to include('pagination=keyset')
expect(response.header['Links']).to include("id_after=#{public_project.id}")
+
+ expect(response.header).to include('Link')
+ expect(response.header['Link']).to include('pagination=keyset')
+ expect(response.header['Link']).to include("id_after=#{public_project.id}")
end
it 'contains only the first project with per_page = 1' do
@@ -613,12 +617,17 @@ describe API::Projects do
expect(response.header).to include('Links')
expect(response.header['Links']).to include('pagination=keyset')
expect(response.header['Links']).to include("id_after=#{project3.id}")
+
+ expect(response.header).to include('Link')
+ expect(response.header['Link']).to include('pagination=keyset')
+ expect(response.header['Link']).to include("id_after=#{project3.id}")
end
it 'does not include a next link when the page does not have any records' do
get api('/projects', current_user), params: params.merge(id_after: Project.maximum(:id))
expect(response.header).not_to include('Links')
+ expect(response.header).not_to include('Link')
end
it 'returns an empty array when the page does not have any records' do
@@ -644,6 +653,10 @@ describe API::Projects do
expect(response.header).to include('Links')
expect(response.header['Links']).to include('pagination=keyset')
expect(response.header['Links']).to include("id_before=#{project3.id}")
+
+ expect(response.header).to include('Link')
+ expect(response.header['Link']).to include('pagination=keyset')
+ expect(response.header['Link']).to include("id_before=#{project3.id}")
end
it 'contains only the last project with per_page = 1' do
@@ -672,6 +685,11 @@ describe API::Projects do
match[1]
end
+ link = response.header['Link']
+ url = link&.match(/<[^>]+(\/projects\?[^>]+)>; rel="next"/) do |match|
+ match[1]
+ end
+
ids += Gitlab::Json.parse(response.body).map { |p| p['id'] }
end
@@ -746,7 +764,8 @@ describe API::Projects do
resolve_outdated_diff_discussions: false,
remove_source_branch_after_merge: true,
autoclose_referenced_issues: true,
- only_allow_merge_if_pipeline_succeeds: false,
+ only_allow_merge_if_pipeline_succeeds: true,
+ allow_merge_on_skipped_pipeline: true,
request_access_enabled: true,
only_allow_merge_if_all_discussions_are_resolved: false,
ci_config_path: 'a/custom/path',
@@ -894,6 +913,22 @@ describe API::Projects do
expect(json_response['only_allow_merge_if_pipeline_succeeds']).to be_truthy
end
+ it 'sets a project as not allowing merge when pipeline is skipped' do
+ project_params = attributes_for(:project, allow_merge_on_skipped_pipeline: false)
+
+ post api('/projects', user), params: project_params
+
+ expect(json_response['allow_merge_on_skipped_pipeline']).to be_falsey
+ end
+
+ it 'sets a project as allowing merge when pipeline is skipped' do
+ project_params = attributes_for(:project, allow_merge_on_skipped_pipeline: true)
+
+ post api('/projects', user), params: project_params
+
+ expect(json_response['allow_merge_on_skipped_pipeline']).to be_truthy
+ end
+
it 'sets a project as allowing merge even if discussions are unresolved' do
project = attributes_for(:project, only_allow_merge_if_all_discussions_are_resolved: false)
@@ -1227,16 +1262,36 @@ describe API::Projects do
it 'sets a project as allowing merge even if build fails' do
project = attributes_for(:project, only_allow_merge_if_pipeline_succeeds: false)
+
post api("/projects/user/#{user.id}", admin), params: project
+
expect(json_response['only_allow_merge_if_pipeline_succeeds']).to be_falsey
end
it 'sets a project as allowing merge only if pipeline succeeds' do
project = attributes_for(:project, only_allow_merge_if_pipeline_succeeds: true)
+
post api("/projects/user/#{user.id}", admin), params: project
+
expect(json_response['only_allow_merge_if_pipeline_succeeds']).to be_truthy
end
+ it 'sets a project as not allowing merge when pipeline is skipped' do
+ project = attributes_for(:project, allow_merge_on_skipped_pipeline: false)
+
+ post api("/projects/user/#{user.id}", admin), params: project
+
+ expect(json_response['allow_merge_on_skipped_pipeline']).to be_falsey
+ end
+
+ it 'sets a project as allowing merge when pipeline is skipped' do
+ project = attributes_for(:project, allow_merge_on_skipped_pipeline: true)
+
+ post api("/projects/user/#{user.id}", admin), params: project
+
+ expect(json_response['allow_merge_on_skipped_pipeline']).to be_truthy
+ end
+
it 'sets a project as allowing merge even if discussions are unresolved' do
project = attributes_for(:project, only_allow_merge_if_all_discussions_are_resolved: false)
@@ -1376,6 +1431,7 @@ describe API::Projects do
expect(json_response['shared_with_groups'][0]['group_name']).to eq(group.name)
expect(json_response['shared_with_groups'][0]['group_access_level']).to eq(link.group_access)
expect(json_response['only_allow_merge_if_pipeline_succeeds']).to eq(project.only_allow_merge_if_pipeline_succeeds)
+ expect(json_response['allow_merge_on_skipped_pipeline']).to eq(project.allow_merge_on_skipped_pipeline)
expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to eq(project.only_allow_merge_if_all_discussions_are_resolved)
end
end
@@ -1443,6 +1499,7 @@ describe API::Projects do
expect(json_response['shared_with_groups'][0]['group_access_level']).to eq(link.group_access)
expect(json_response['shared_with_groups'][0]).to have_key('expires_at')
expect(json_response['only_allow_merge_if_pipeline_succeeds']).to eq(project.only_allow_merge_if_pipeline_succeeds)
+ expect(json_response['allow_merge_on_skipped_pipeline']).to eq(project.allow_merge_on_skipped_pipeline)
expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to eq(project.only_allow_merge_if_all_discussions_are_resolved)
expect(json_response['ci_default_git_depth']).to eq(project.ci_default_git_depth)
expect(json_response['merge_method']).to eq(project.merge_method.to_s)
@@ -2055,10 +2112,12 @@ describe API::Projects do
end
describe "POST /projects/:id/share" do
- let(:group) { create(:group) }
+ let_it_be(:group) { create(:group, :private) }
+ let_it_be(:group_user) { create(:user) }
before do
group.add_developer(user)
+ group.add_developer(group_user)
end
it "shares project with group" do
@@ -2074,6 +2133,14 @@ describe API::Projects do
expect(json_response['expires_at']).to eq(expires_at.to_s)
end
+ it 'updates project authorization' do
+ expect do
+ post api("/projects/#{project.id}/share", user), params: { group_id: group.id, group_access: Gitlab::Access::DEVELOPER }
+ end.to(
+ change { group_user.can?(:read_project, project) }.from(false).to(true)
+ )
+ end
+
it "returns a 400 error when group id is not given" do
post api("/projects/#{project.id}/share", user), params: { group_access: Gitlab::Access::DEVELOPER }
expect(response).to have_gitlab_http_status(:bad_request)
@@ -2123,9 +2190,12 @@ describe API::Projects do
describe 'DELETE /projects/:id/share/:group_id' do
context 'for a valid group' do
- let(:group) { create(:group, :public) }
+ let_it_be(:group) { create(:group, :private) }
+ let_it_be(:group_user) { create(:user) }
before do
+ group.add_developer(group_user)
+
create(:project_group_link, group: group, project: project)
end
@@ -2136,6 +2206,14 @@ describe API::Projects do
expect(project.project_group_links).to be_empty
end
+ it 'updates project authorization' do
+ expect do
+ delete api("/projects/#{project.id}/share/#{group.id}", user)
+ end.to(
+ change { group_user.can?(:read_project, project) }.from(true).to(false)
+ )
+ end
+
it_behaves_like '412 response' do
let(:request) { api("/projects/#{project.id}/share/#{group.id}", user) }
end
@@ -2438,6 +2516,21 @@ describe API::Projects do
expect(json_response['container_expiration_policy']['keep_n']).to eq(1)
expect(json_response['container_expiration_policy']['name_regex_keep']).to eq('foo.*')
end
+
+ it "doesn't update container_expiration_policy with invalid regex" do
+ project_param = {
+ container_expiration_policy_attributes: {
+ cadence: '1month',
+ keep_n: 1,
+ name_regex_keep: '['
+ }
+ }
+
+ put api("/projects/#{project3.id}", user4), params: project_param
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response['message']['container_expiration_policy.name_regex_keep']).to contain_exactly('not valid RE2 syntax: missing ]: [')
+ end
end
context 'when authenticated as project developer' do
@@ -2477,11 +2570,11 @@ describe API::Projects do
let(:admin) { create(:admin) }
- it 'returns 500 when repository storage is unknown' do
+ it 'returns 400 when repository storage is unknown' do
put(api("/projects/#{new_project.id}", admin), params: { repository_storage: unknown_storage })
- expect(response).to have_gitlab_http_status(:internal_server_error)
- expect(json_response['message']).to match('ArgumentError')
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response['message']['repository_storage_moves']).to eq(['is invalid'])
end
it 'returns 200 when repository storage has changed' do
diff --git a/spec/requests/api/releases_spec.rb b/spec/requests/api/releases_spec.rb
index 237782a681c..f4cb7f25990 100644
--- a/spec/requests/api/releases_spec.rb
+++ b/spec/requests/api/releases_spec.rb
@@ -10,7 +10,6 @@ describe API::Releases do
let(:guest) { create(:user) }
let(:non_project_member) { create(:user) }
let(:commit) { create(:commit, project: project) }
- let(:last_release) { project.releases.last }
before do
project.add_maintainer(maintainer)
@@ -733,109 +732,6 @@ describe API::Releases do
expect(response).to have_gitlab_http_status(:conflict)
end
end
-
- context 'Evidence collection' do
- let(:params) do
- {
- name: 'New release',
- tag_name: 'v0.1',
- description: 'Super nice release',
- released_at: released_at
- }.compact
- end
-
- around do |example|
- Timecop.freeze { example.run }
- end
-
- subject do
- post api("/projects/#{project.id}/releases", maintainer), params: params
- end
-
- context 'historical release' do
- let(:released_at) { 3.weeks.ago }
-
- it 'does not execute CreateEvidenceWorker' do
- expect { subject }.not_to change(CreateEvidenceWorker.jobs, :size)
- end
-
- it 'does not create an Evidence object', :sidekiq_inline do
- expect { subject }.not_to change(Releases::Evidence, :count)
- end
-
- it 'is a historical release' do
- subject
-
- expect(last_release.historical_release?).to be_truthy
- end
-
- it 'is not an upcoming release' do
- subject
-
- expect(last_release.upcoming_release?).to be_falsy
- end
- end
-
- context 'immediate release' do
- let(:released_at) { nil }
-
- it 'sets `released_at` to the current dttm' do
- subject
-
- expect(last_release.updated_at).to be_like_time(Time.now)
- end
-
- it 'queues CreateEvidenceWorker' do
- expect { subject }.to change(CreateEvidenceWorker.jobs, :size).by(1)
- end
-
- it 'creates Evidence', :sidekiq_inline do
- expect { subject }.to change(Releases::Evidence, :count).by(1)
- end
-
- it 'is not a historical release' do
- subject
-
- expect(last_release.historical_release?).to be_falsy
- end
-
- it 'is not an upcoming release' do
- subject
-
- expect(last_release.upcoming_release?).to be_falsy
- end
- end
-
- context 'upcoming release' do
- let(:released_at) { 1.day.from_now }
-
- it 'queues CreateEvidenceWorker' do
- expect { subject }.to change(CreateEvidenceWorker.jobs, :size).by(1)
- end
-
- it 'queues CreateEvidenceWorker at the released_at timestamp' do
- subject
-
- expect(CreateEvidenceWorker.jobs.last['at']).to eq(released_at.to_i)
- end
-
- it 'creates Evidence', :sidekiq_inline do
- expect { subject }.to change(Releases::Evidence, :count).by(1)
- end
-
- it 'is not a historical release' do
- subject
-
- expect(last_release.historical_release?).to be_falsy
- end
-
- it 'is an upcoming release' do
- subject
-
- expect(last_release.upcoming_release?).to be_truthy
- end
- end
- end
end
describe 'PUT /projects/:id/releases/:tag_name' do
diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb
index 0c66bfd6c4d..55243e83017 100644
--- a/spec/requests/api/repositories_spec.rb
+++ b/spec/requests/api/repositories_spec.rb
@@ -177,6 +177,12 @@ describe API::Repositories do
expect(headers['Content-Disposition']).to eq 'inline'
end
+ it_behaves_like 'uncached response' do
+ before do
+ get api(route, current_user)
+ end
+ end
+
context 'when sha does not exist' do
it_behaves_like '404 response' do
let(:request) { get api(route.sub(sample_blob.oid, 'abcd9876'), current_user) }
@@ -278,7 +284,7 @@ describe API::Repositories do
context "when hotlinking detection is enabled" do
before do
- Feature.enable(:repository_archive_hotlinking_interception)
+ stub_feature_flags(repository_archive_hotlinking_interception: true)
end
it_behaves_like "hotlink interceptor" do
diff --git a/spec/requests/api/resource_milestone_events_spec.rb b/spec/requests/api/resource_milestone_events_spec.rb
new file mode 100644
index 00000000000..b2e92fde5ee
--- /dev/null
+++ b/spec/requests/api/resource_milestone_events_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe API::ResourceMilestoneEvents do
+ let!(:user) { create(:user) }
+ let!(:project) { create(:project, :public, namespace: user.namespace) }
+ let!(:milestone) { create(:milestone, project: project) }
+
+ before do
+ project.add_developer(user)
+ end
+
+ context 'when eventable is an Issue' do
+ it_behaves_like 'resource_milestone_events API', 'projects', 'issues', 'iid' do
+ let(:parent) { project }
+ let(:eventable) { create(:issue, project: project, author: user) }
+ end
+ end
+
+ context 'when eventable is a Merge Request' do
+ it_behaves_like 'resource_milestone_events API', 'projects', 'merge_requests', 'iid' do
+ let(:parent) { project }
+ let(:eventable) { create(:merge_request, source_project: project, target_project: project, author: user) }
+ end
+ end
+end
diff --git a/spec/requests/api/runner_spec.rb b/spec/requests/api/runner_spec.rb
index 7284f33f3af..774615757b9 100644
--- a/spec/requests/api/runner_spec.rb
+++ b/spec/requests/api/runner_spec.rb
@@ -648,6 +648,44 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
end
end
+ context 'when job is for a release' do
+ let!(:job) { create(:ci_build, :release_options, pipeline: pipeline) }
+
+ context 'when `release_steps` is passed by the runner' do
+ it 'exposes release info' do
+ request_job info: { features: { release_steps: true } }
+
+ expect(response).to have_gitlab_http_status(:created)
+ expect(response.headers).not_to have_key('X-GitLab-Last-Update')
+ expect(json_response['steps']).to eq([
+ {
+ "name" => "script",
+ "script" => ["make changelog | tee release_changelog.txt"],
+ "timeout" => 3600,
+ "when" => "on_success",
+ "allow_failure" => false
+ },
+ {
+ "name" => "release",
+ "script" =>
+ "release-cli create --ref \"$CI_COMMIT_SHA\" --name \"Release $CI_COMMIT_SHA\" --tag-name \"release-$CI_COMMIT_SHA\" --description \"Created using the release-cli $EXTRA_DESCRIPTION\"",
+ "timeout" => 3600,
+ "when" => "on_success",
+ "allow_failure" => false
+ }
+ ])
+ end
+ end
+
+ context 'when `release_steps` is not passed by the runner' do
+ it 'drops the job' do
+ request_job
+
+ expect(response).to have_gitlab_http_status(:no_content)
+ end
+ end
+ end
+
context 'when job is made for merge request' do
let(:pipeline) { create(:ci_pipeline, source: :merge_request_event, project: project, ref: 'feature', merge_request: merge_request) }
let!(:job) { create(:ci_build, pipeline: pipeline, name: 'spinach', ref: 'feature', stage: 'test', stage_idx: 0) }
@@ -1055,6 +1093,65 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
post api('/jobs/request'), params: new_params, headers: { 'User-Agent' => user_agent }
end
end
+
+ context 'for web-ide job' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :repository) }
+
+ let(:runner) { create(:ci_runner, :project, projects: [project]) }
+ let(:service) { Ci::CreateWebIdeTerminalService.new(project, user, ref: 'master').execute }
+ let(:pipeline) { service[:pipeline] }
+ let(:build) { pipeline.builds.first }
+ let(:job) { {} }
+ let(:config_content) do
+ 'terminal: { image: ruby, services: [mysql], before_script: [ls], tags: [tag-1], variables: { KEY: value } }'
+ end
+
+ before do
+ stub_webide_config_file(config_content)
+ project.add_maintainer(user)
+
+ pipeline
+ end
+
+ context 'when runner has matching tag' do
+ before do
+ runner.update!(tag_list: ['tag-1'])
+ end
+
+ it 'successfully picks job' do
+ request_job
+
+ build.reload
+
+ expect(build).to be_running
+ expect(build.runner).to eq(runner)
+
+ expect(response).to have_gitlab_http_status(:created)
+ expect(json_response).to include(
+ "id" => build.id,
+ "variables" => include("key" => 'KEY', "value" => 'value', "public" => true, "masked" => false),
+ "image" => a_hash_including("name" => 'ruby'),
+ "services" => all(a_hash_including("name" => 'mysql')),
+ "job_info" => a_hash_including("name" => 'terminal', "stage" => 'terminal'))
+ end
+ end
+
+ context 'when runner does not have matching tags' do
+ it 'does not pick a job' do
+ request_job
+
+ build.reload
+
+ expect(build).to be_pending
+ expect(response).to have_gitlab_http_status(:no_content)
+ end
+ end
+
+ def request_job(token = runner.token, **params)
+ post api('/jobs/request'), params: params.merge(token: token)
+ end
+ end
end
describe 'PUT /api/v4/jobs/:id' do
@@ -1070,6 +1167,10 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
let(:send_request) { update_job(state: 'success') }
end
+ it 'updates runner info' do
+ expect { update_job(state: 'success') }.to change { runner.reload.contacted_at }
+ end
+
context 'when status is given' do
it 'mark job as succeeded' do
update_job(state: 'success')
@@ -1235,6 +1336,12 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
let(:send_request) { patch_the_trace }
end
+ it 'updates runner info' do
+ runner.update!(contacted_at: 1.year.ago)
+
+ expect { patch_the_trace }.to change { runner.reload.contacted_at }
+ end
+
context 'when request is valid' do
it 'gets correct response' do
expect(response).to have_gitlab_http_status(:accepted)
@@ -1496,6 +1603,10 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
let(:send_request) { subject }
end
+ it 'updates runner info' do
+ expect { subject }.to change { runner.reload.contacted_at }
+ end
+
shared_examples 'authorizes local file' do
it 'succeeds' do
subject
@@ -1634,6 +1745,35 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
end
end
+ context 'authorize uploading of an lsif artifact' do
+ before do
+ stub_feature_flags(code_navigation: job.project)
+ end
+
+ it 'adds ProcessLsif header' do
+ authorize_artifacts_with_token_in_headers(artifact_type: :lsif)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['ProcessLsif']).to be_truthy
+ end
+
+ it 'fails to authorize too large artifact' do
+ authorize_artifacts_with_token_in_headers(artifact_type: :lsif, filesize: 30.megabytes)
+
+ expect(response).to have_gitlab_http_status(:payload_too_large)
+ end
+
+ context 'code_navigation feature flag is disabled' do
+ it 'does not add ProcessLsif header' do
+ stub_feature_flags(code_navigation: false)
+
+ authorize_artifacts_with_token_in_headers(artifact_type: :lsif)
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
+ end
+ end
+
def authorize_artifacts(params = {}, request_headers = headers)
post api("/jobs/#{job.id}/artifacts/authorize"), params: params, headers: request_headers
end
@@ -1655,6 +1795,10 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
end
end
+ it 'updates runner info' do
+ expect { upload_artifacts(file_upload, headers_with_token) }.to change { runner.reload.contacted_at }
+ end
+
context 'when artifacts are being stored inside of tmp path' do
before do
# by configuring this path we allow to pass temp file from any path
@@ -2140,6 +2284,10 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
let(:send_request) { download_artifact }
end
+ it 'updates runner info' do
+ expect { download_artifact }.to change { runner.reload.contacted_at }
+ end
+
context 'when job has artifacts' do
let(:job) { create(:ci_build) }
let(:store) { JobArtifactUploader::Store::LOCAL }
@@ -2207,7 +2355,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
end
end
- context 'when job does not has artifacts' do
+ context 'when job does not have artifacts' do
it 'responds with not found' do
download_artifact
diff --git a/spec/requests/api/runners_spec.rb b/spec/requests/api/runners_spec.rb
index 261e54da6a8..67c258260bf 100644
--- a/spec/requests/api/runners_spec.rb
+++ b/spec/requests/api/runners_spec.rb
@@ -326,32 +326,6 @@ describe API::Runners do
expect(response).to have_gitlab_http_status(:unauthorized)
end
end
-
- context 'FF hide_token_from_runners_api is enabled' do
- before do
- stub_feature_flags(hide_token_from_runners_api: true)
- end
-
- it "does not return runner's token" do
- get api("/runners/#{shared_runner.id}", admin)
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response).not_to have_key('token')
- end
- end
-
- context 'FF hide_token_from_runners_api is disabled' do
- before do
- stub_feature_flags(hide_token_from_runners_api: false)
- end
-
- it "returns runner's token" do
- get api("/runners/#{shared_runner.id}", admin)
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response).to have_key('token')
- end
- end
end
describe 'PUT /runners/:id' do
diff --git a/spec/requests/api/search_spec.rb b/spec/requests/api/search_spec.rb
index 3894e0bf2d1..a02d804ee9b 100644
--- a/spec/requests/api/search_spec.rb
+++ b/spec/requests/api/search_spec.rb
@@ -15,6 +15,14 @@ describe API::Search do
it { expect(json_response.size).to eq(size) }
end
+ shared_examples 'ping counters' do |scope:, search: ''|
+ it 'increases usage ping searches counter' do
+ expect(Gitlab::UsageDataCounters::SearchCounter).to receive(:count).with(:all_searches)
+
+ get api(endpoint, user), params: { scope: scope, search: search }
+ end
+ end
+
shared_examples 'pagination' do |scope:, search: ''|
it 'returns a different result for each page' do
get api(endpoint, user), params: { scope: scope, search: search, page: 1, per_page: 1 }
@@ -75,6 +83,8 @@ describe API::Search do
it_behaves_like 'response is correct', schema: 'public_api/v4/projects'
it_behaves_like 'pagination', scope: :projects
+
+ it_behaves_like 'ping counters', scope: :projects
end
context 'for issues scope' do
@@ -86,6 +96,8 @@ describe API::Search do
it_behaves_like 'response is correct', schema: 'public_api/v4/issues'
+ it_behaves_like 'ping counters', scope: :issues
+
describe 'pagination' do
before do
create(:issue, project: project, title: 'another issue')
@@ -104,6 +116,8 @@ describe API::Search do
it_behaves_like 'response is correct', schema: 'public_api/v4/merge_requests'
+ it_behaves_like 'ping counters', scope: :merge_requests
+
describe 'pagination' do
before do
create(:merge_request, source_project: repo_project, title: 'another mr', target_branch: 'another_branch')
@@ -125,6 +139,8 @@ describe API::Search do
it_behaves_like 'response is correct', schema: 'public_api/v4/milestones'
+ it_behaves_like 'ping counters', scope: :milestones
+
describe 'pagination' do
before do
create(:milestone, project: project, title: 'another milestone')
@@ -161,6 +177,8 @@ describe API::Search do
it_behaves_like 'pagination', scope: :users
+ it_behaves_like 'ping counters', scope: :users
+
context 'when users search feature is disabled' do
before do
stub_feature_flags(users_search: false)
@@ -183,6 +201,8 @@ describe API::Search do
it_behaves_like 'response is correct', schema: 'public_api/v4/snippets'
+ it_behaves_like 'ping counters', scope: :snippet_titles
+
describe 'pagination' do
before do
create(:snippet, :public, title: 'another snippet', content: 'snippet content')
@@ -248,6 +268,8 @@ describe API::Search do
it_behaves_like 'response is correct', schema: 'public_api/v4/projects'
it_behaves_like 'pagination', scope: :projects
+
+ it_behaves_like 'ping counters', scope: :projects
end
context 'for issues scope' do
@@ -259,6 +281,8 @@ describe API::Search do
it_behaves_like 'response is correct', schema: 'public_api/v4/issues'
+ it_behaves_like 'ping counters', scope: :issues
+
describe 'pagination' do
before do
create(:issue, project: project, title: 'another issue')
@@ -277,6 +301,8 @@ describe API::Search do
it_behaves_like 'response is correct', schema: 'public_api/v4/merge_requests'
+ it_behaves_like 'ping counters', scope: :merge_requests
+
describe 'pagination' do
before do
create(:merge_request, source_project: repo_project, title: 'another mr', target_branch: 'another_branch')
@@ -295,6 +321,8 @@ describe API::Search do
it_behaves_like 'response is correct', schema: 'public_api/v4/milestones'
+ it_behaves_like 'ping counters', scope: :milestones
+
describe 'pagination' do
before do
create(:milestone, project: project, title: 'another milestone')
@@ -326,6 +354,8 @@ describe API::Search do
it_behaves_like 'response is correct', schema: 'public_api/v4/user/basics'
+ it_behaves_like 'ping counters', scope: :users
+
describe 'pagination' do
before do
create(:group_member, :developer, group: group)
@@ -395,7 +425,7 @@ describe API::Search do
end
end
- context 'when user does can not see the project' do
+ context 'when user can not see the project' do
it 'returns 404 error' do
project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
@@ -415,6 +445,8 @@ describe API::Search do
it_behaves_like 'response is correct', schema: 'public_api/v4/issues'
+ it_behaves_like 'ping counters', scope: :issues
+
describe 'pagination' do
before do
create(:issue, project: project, title: 'another issue')
@@ -435,6 +467,8 @@ describe API::Search do
it_behaves_like 'response is correct', schema: 'public_api/v4/merge_requests'
+ it_behaves_like 'ping counters', scope: :merge_requests
+
describe 'pagination' do
before do
create(:merge_request, source_project: repo_project, title: 'another mr', target_branch: 'another_branch')
@@ -456,6 +490,8 @@ describe API::Search do
it_behaves_like 'response is correct', schema: 'public_api/v4/milestones'
+ it_behaves_like 'ping counters', scope: :milestones
+
describe 'pagination' do
before do
create(:milestone, project: project, title: 'another milestone')
@@ -491,6 +527,8 @@ describe API::Search do
it_behaves_like 'response is correct', schema: 'public_api/v4/user/basics'
+ it_behaves_like 'ping counters', scope: :users
+
describe 'pagination' do
before do
create(:project_member, :developer, project: project)
@@ -521,6 +559,8 @@ describe API::Search do
it_behaves_like 'response is correct', schema: 'public_api/v4/notes'
+ it_behaves_like 'ping counters', scope: :notes
+
describe 'pagination' do
before do
mr = create(:merge_request, source_project: project, target_branch: 'another_branch')
@@ -542,6 +582,8 @@ describe API::Search do
it_behaves_like 'response is correct', schema: 'public_api/v4/blobs'
+ it_behaves_like 'ping counters', scope: :wiki_blobs
+
describe 'pagination' do
before do
create(:wiki_page, wiki: wiki, title: 'home 2', content: 'Another page')
@@ -561,6 +603,8 @@ describe API::Search do
it_behaves_like 'response is correct', schema: 'public_api/v4/commits_details'
it_behaves_like 'pagination', scope: :commits, search: 'merge'
+
+ it_behaves_like 'ping counters', scope: :commits
end
context 'for commits scope with project path as id' do
@@ -582,6 +626,8 @@ describe API::Search do
it_behaves_like 'pagination', scope: :blobs, search: 'monitors'
+ it_behaves_like 'ping counters', scope: :blobs
+
context 'filters' do
it 'by filename' do
get api(endpoint, user), params: { scope: 'blobs', search: 'mon filename:PROCESS.md' }
diff --git a/spec/requests/api/settings_spec.rb b/spec/requests/api/settings_spec.rb
index a5b95bc59a5..e6dd1fecb69 100644
--- a/spec/requests/api/settings_spec.rb
+++ b/spec/requests/api/settings_spec.rb
@@ -38,6 +38,8 @@ describe API::Settings, 'Settings' do
expect(json_response).not_to have_key('performance_bar_allowed_group_path')
expect(json_response).not_to have_key('performance_bar_enabled')
expect(json_response['snippet_size_limit']).to eq(50.megabytes)
+ expect(json_response['spam_check_endpoint_enabled']).to be_falsey
+ expect(json_response['spam_check_endpoint_url']).to be_nil
end
end
@@ -50,7 +52,7 @@ describe API::Settings, 'Settings' do
storages = Gitlab.config.repositories.storages
.merge({ 'custom' => 'tmp/tests/custom_repositories' })
allow(Gitlab.config.repositories).to receive(:storages).and_return(storages)
- Feature.get(:sourcegraph).enable
+ stub_feature_flags(sourcegraph: true)
end
it "updates application settings" do
@@ -90,7 +92,9 @@ describe API::Settings, 'Settings' do
push_event_activities_limit: 2,
snippet_size_limit: 5,
issues_create_limit: 300,
- raw_blob_request_limit: 300
+ raw_blob_request_limit: 300,
+ spam_check_endpoint_enabled: true,
+ spam_check_endpoint_url: 'https://example.com/spam_check'
}
expect(response).to have_gitlab_http_status(:ok)
@@ -129,6 +133,8 @@ describe API::Settings, 'Settings' do
expect(json_response['snippet_size_limit']).to eq(5)
expect(json_response['issues_create_limit']).to eq(300)
expect(json_response['raw_blob_request_limit']).to eq(300)
+ expect(json_response['spam_check_endpoint_enabled']).to be_truthy
+ expect(json_response['spam_check_endpoint_url']).to eq('https://example.com/spam_check')
end
end
@@ -390,5 +396,14 @@ describe API::Settings, 'Settings' do
expect(json_response['error']).to eq('sourcegraph_url is missing')
end
end
+
+ context "missing spam_check_endpoint_url value when spam_check_endpoint_enabled is true" do
+ it "returns a blank parameter error message" do
+ put api("/application/settings", admin), params: { spam_check_endpoint_enabled: true }
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response['error']).to eq('spam_check_endpoint_url is missing')
+ end
+ end
end
end
diff --git a/spec/requests/api/suggestions_spec.rb b/spec/requests/api/suggestions_spec.rb
index df3f72e3447..ffb8c811622 100644
--- a/spec/requests/api/suggestions_spec.rb
+++ b/spec/requests/api/suggestions_spec.rb
@@ -7,8 +7,7 @@ describe API::Suggestions do
let(:user) { create(:user) }
let(:merge_request) do
- create(:merge_request, source_project: project,
- target_project: project)
+ create(:merge_request, source_project: project, target_project: project)
end
let(:position) do
@@ -19,26 +18,45 @@ describe API::Suggestions do
diff_refs: merge_request.diff_refs)
end
+ let(:position2) do
+ Gitlab::Diff::Position.new(old_path: "files/ruby/popen.rb",
+ new_path: "files/ruby/popen.rb",
+ old_line: nil,
+ new_line: 15,
+ diff_refs: merge_request.diff_refs)
+ end
+
let(:diff_note) do
+ create(:diff_note_on_merge_request,
+ noteable: merge_request,
+ position: position,
+ project: project)
+ end
+
+ let(:diff_note2) do
create(:diff_note_on_merge_request, noteable: merge_request,
- position: position,
- project: project)
+ position: position2,
+ project: project)
+ end
+
+ let(:suggestion) do
+ create(:suggestion, note: diff_note,
+ from_content: " raise RuntimeError, \"System commands must be given as an array of strings\"\n",
+ to_content: " raise RuntimeError, 'Explosion'\n # explosion?")
+ end
+
+ let(:unappliable_suggestion) do
+ create(:suggestion, :unappliable, note: diff_note2)
end
describe "PUT /suggestions/:id/apply" do
let(:url) { "/suggestions/#{suggestion.id}/apply" }
context 'when successfully applies patch' do
- let(:suggestion) do
- create(:suggestion, note: diff_note,
- from_content: " raise RuntimeError, \"System commands must be given as an array of strings\"\n",
- to_content: " raise RuntimeError, 'Explosion'\n # explosion?")
- end
-
- it 'returns 200 with json content' do
+ it 'renders an ok response and returns json content' do
project.add_maintainer(user)
- put api(url, user), params: { id: suggestion.id }
+ put api(url, user)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response)
@@ -48,31 +66,105 @@ describe API::Suggestions do
end
context 'when not able to apply patch' do
- let(:suggestion) do
- create(:suggestion, :unappliable, note: diff_note)
- end
+ let(:url) { "/suggestions/#{unappliable_suggestion.id}/apply" }
- it 'returns 400 with json content' do
+ it 'renders a bad request error and returns json content' do
project.add_maintainer(user)
- put api(url, user), params: { id: suggestion.id }
+ put api(url, user)
expect(response).to have_gitlab_http_status(:bad_request)
- expect(json_response).to eq({ 'message' => 'Suggestion is not appliable' })
+ expect(json_response).to eq({ 'message' => 'A suggestion is not applicable.' })
+ end
+ end
+
+ context 'when suggestion is not found' do
+ let(:url) { "/suggestions/foo-123/apply" }
+
+ it 'renders a not found error and returns json content' do
+ project.add_maintainer(user)
+
+ put api(url, user)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ expect(json_response).to eq({ 'message' => 'Suggestion is not applicable as the suggestion was not found.' })
end
end
context 'when unauthorized' do
- let(:suggestion) do
- create(:suggestion, note: diff_note,
- from_content: " raise RuntimeError, \"System commands must be given as an array of strings\"\n",
- to_content: " raise RuntimeError, 'Explosion'\n # explosion?")
+ it 'renders a forbidden error and returns json content' do
+ project.add_reporter(user)
+
+ put api(url, user)
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ expect(json_response).to eq({ 'message' => '403 Forbidden' })
end
+ end
+ end
+
+ describe "PUT /suggestions/batch_apply" do
+ let(:suggestion2) do
+ create(:suggestion, note: diff_note2,
+ from_content: " \"PWD\" => path\n",
+ to_content: " *** FOO ***\n")
+ end
- it 'returns 403 with json content' do
+ let(:url) { "/suggestions/batch_apply" }
+
+ context 'when successfully applies multiple patches as a batch' do
+ it 'renders an ok response and returns json content' do
+ project.add_maintainer(user)
+
+ put api(url, user), params: { ids: [suggestion.id, suggestion2.id] }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to all(include('id', 'from_line', 'to_line',
+ 'appliable', 'applied',
+ 'from_content', 'to_content'))
+ end
+ end
+
+ context 'when not able to apply one or more of the patches' do
+ it 'renders a bad request error and returns json content' do
+ project.add_maintainer(user)
+
+ put api(url, user),
+ params: { ids: [suggestion.id, unappliable_suggestion.id] }
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response).to eq({ 'message' => 'A suggestion is not applicable.' })
+ end
+ end
+
+ context 'with missing suggestions' do
+ it 'renders a not found error and returns json content if any suggestion is not found' do
+ project.add_maintainer(user)
+
+ put api(url, user), params: { ids: [suggestion.id, 'foo-123'] }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ expect(json_response)
+ .to eq({ 'message' => 'Suggestions are not applicable as one or more suggestions were not found.' })
+ end
+
+ it 'renders a bad request error and returns json content when no suggestions are provided' do
+ project.add_maintainer(user)
+
+ put api(url, user), params: {}
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response)
+ .to eq({ 'error' => "ids is missing" })
+ end
+ end
+
+ context 'when unauthorized' do
+ it 'renders a forbidden error and returns json content' do
project.add_reporter(user)
- put api(url, user), params: { id: suggestion.id }
+ put api(url, user),
+ params: { ids: [suggestion.id, suggestion2.id] }
expect(response).to have_gitlab_http_status(:forbidden)
expect(json_response).to eq({ 'message' => '403 Forbidden' })
diff --git a/spec/requests/api/terraform/state_spec.rb b/spec/requests/api/terraform/state_spec.rb
index 844cd948411..ec9db5566e3 100644
--- a/spec/requests/api/terraform/state_spec.rb
+++ b/spec/requests/api/terraform/state_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
describe API::Terraform::State do
+ include HttpBasicAuthHelpers
+
let_it_be(:project) { create(:project) }
let_it_be(:developer) { create(:user, developer_projects: [project]) }
let_it_be(:maintainer) { create(:user, maintainer_projects: [project]) }
@@ -10,7 +12,7 @@ describe API::Terraform::State do
let!(:state) { create(:terraform_state, :with_file, project: project) }
let(:current_user) { maintainer }
- let(:auth_header) { basic_auth_header(current_user) }
+ let(:auth_header) { user_basic_auth_header(current_user) }
let(:project_id) { project.id }
let(:state_name) { state.name }
let(:state_path) { "/projects/#{project_id}/terraform/state/#{state_name}" }
@@ -23,7 +25,7 @@ describe API::Terraform::State do
subject(:request) { get api(state_path), headers: auth_header }
context 'without authentication' do
- let(:auth_header) { basic_auth_header('failing_token') }
+ let(:auth_header) { basic_auth_header('bad', 'token') }
it 'returns 401 if user is not authenticated' do
request
@@ -32,34 +34,71 @@ describe API::Terraform::State do
end
end
- context 'with maintainer permissions' do
- let(:current_user) { maintainer }
+ context 'personal acceess token authentication' do
+ context 'with maintainer permissions' do
+ let(:current_user) { maintainer }
- it 'returns terraform state belonging to a project of given state name' do
- request
+ it 'returns terraform state belonging to a project of given state name' do
+ request
- expect(response).to have_gitlab_http_status(:ok)
- expect(response.body).to eq(state.file.read)
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.body).to eq(state.file.read)
+ end
+
+ context 'for a project that does not exist' do
+ let(:project_id) { '0000' }
+
+ it 'returns not found' do
+ request
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
end
- context 'for a project that does not exist' do
- let(:project_id) { '0000' }
+ context 'with developer permissions' do
+ let(:current_user) { developer }
- it 'returns not found' do
+ it 'returns forbidden if the user cannot access the state' do
request
- expect(response).to have_gitlab_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:forbidden)
end
end
end
- context 'with developer permissions' do
- let(:current_user) { developer }
+ context 'job token authentication' do
+ let(:auth_header) { job_basic_auth_header(job) }
- it 'returns forbidden if the user cannot access the state' do
- request
+ context 'with maintainer permissions' do
+ let(:job) { create(:ci_build, project: project, user: maintainer) }
- expect(response).to have_gitlab_http_status(:forbidden)
+ it 'returns terraform state belonging to a project of given state name' do
+ request
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.body).to eq(state.file.read)
+ end
+
+ context 'for a project that does not exist' do
+ let(:project_id) { '0000' }
+
+ it 'returns not found' do
+ request
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ context 'with developer permissions' do
+ let(:job) { create(:ci_build, project: project, user: developer) }
+
+ it 'returns forbidden if the user cannot access the state' do
+ request
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
end
end
end
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index 4a0f0eea088..e780f67bcab 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -3,18 +3,186 @@
require 'spec_helper'
describe API::Users, :do_not_mock_admin_mode do
- let(:user) { create(:user, username: 'user.with.dot') }
- let(:admin) { create(:admin) }
- let(:key) { create(:key, user: user) }
- let(:gpg_key) { create(:gpg_key, user: user) }
- let(:email) { create(:email, user: user) }
+ let_it_be(:admin) { create(:admin) }
+ let_it_be(:user, reload: true) { create(:user, username: 'user.with.dot') }
+ let_it_be(:key) { create(:key, user: user) }
+ let_it_be(:gpg_key) { create(:gpg_key, user: user) }
+ let_it_be(:email) { create(:email, user: user) }
let(:omniauth_user) { create(:omniauth_user) }
- let(:ldap_user) { create(:omniauth_user, provider: 'ldapmain') }
let(:ldap_blocked_user) { create(:omniauth_user, provider: 'ldapmain', state: 'ldap_blocked') }
- let(:not_existing_user_id) { (User.maximum('id') || 0 ) + 10 }
- let(:not_existing_pat_id) { (PersonalAccessToken.maximum('id') || 0 ) + 10 }
let(:private_user) { create(:user, private_profile: true) }
+ context 'admin notes' do
+ let_it_be(:admin) { create(:admin, note: '2019-10-06 | 2FA added | user requested | www.gitlab.com') }
+ let_it_be(:user, reload: true) { create(:user, note: '2018-11-05 | 2FA removed | user requested | www.gitlab.com') }
+
+ describe 'POST /users' do
+ context 'when unauthenticated' do
+ it 'return authentication error' do
+ post api('/users')
+
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
+ end
+
+ context 'when authenticated' do
+ context 'as an admin' do
+ it 'contains the note of the user' do
+ optional_attributes = { note: 'Awesome Note' }
+ attributes = attributes_for(:user).merge(optional_attributes)
+
+ post api('/users', admin), params: attributes
+
+ expect(response).to have_gitlab_http_status(:created)
+ expect(json_response['note']).to eq(optional_attributes[:note])
+ end
+ end
+
+ context 'as a regular user' do
+ it 'does not allow creating new user' do
+ post api('/users', user), params: attributes_for(:user)
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
+ end
+ end
+ end
+
+ describe 'GET /users/:id' do
+ context 'when unauthenticated' do
+ it 'does not contain the note of the user' do
+ get api("/users/#{user.id}")
+
+ expect(json_response).not_to have_key('note')
+ end
+ end
+
+ context 'when authenticated' do
+ context 'as an admin' do
+ it 'contains the note of the user' do
+ get api("/users/#{user.id}", admin)
+
+ expect(json_response).to have_key('note')
+ expect(json_response['note']).to eq(user.note)
+ end
+ end
+
+ context 'as a regular user' do
+ it 'does not contain the note of the user' do
+ get api("/users/#{user.id}", user)
+
+ expect(json_response).not_to have_key('note')
+ end
+ end
+ end
+ end
+
+ describe "PUT /users/:id" do
+ context 'when user is an admin' do
+ it "updates note of the user" do
+ new_note = '2019-07-07 | Email changed | user requested | www.gitlab.com'
+
+ expect do
+ put api("/users/#{user.id}", admin), params: { note: new_note }
+ end.to change { user.reload.note }
+ .from('2018-11-05 | 2FA removed | user requested | www.gitlab.com')
+ .to(new_note)
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(json_response['note']).to eq(new_note)
+ end
+ end
+
+ context 'when user is not an admin' do
+ it "cannot update their own note" do
+ expect do
+ put api("/users/#{user.id}", user), params: { note: 'new note' }
+ end.not_to change { user.reload.note }
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
+ end
+ end
+
+ describe 'GET /users/' do
+ context 'when unauthenticated' do
+ it "does not contain the note of users" do
+ get api("/users"), params: { username: user.username }
+
+ expect(json_response.first).not_to have_key('note')
+ end
+ end
+
+ context 'when authenticated' do
+ context 'as a regular user' do
+ it 'does not contain the note of users' do
+ get api("/users", user), params: { username: user.username }
+
+ expect(json_response.first).not_to have_key('note')
+ end
+ end
+
+ context 'as an admin' do
+ it 'contains the note of users' do
+ get api("/users", admin), params: { username: user.username }
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(json_response.first).to have_key('note')
+ expect(json_response.first['note']).to eq '2018-11-05 | 2FA removed | user requested | www.gitlab.com'
+ end
+ end
+ end
+ end
+
+ describe 'GET /user' do
+ context 'when authenticated' do
+ context 'as an admin' do
+ context 'accesses their own profile' do
+ it 'contains the note of the user' do
+ get api("/user", admin)
+
+ expect(json_response).to have_key('note')
+ expect(json_response['note']).to eq(admin.note)
+ end
+ end
+
+ context 'sudo' do
+ let(:admin_personal_access_token) { create(:personal_access_token, user: admin, scopes: %w[api sudo]).token }
+
+ context 'accesses the profile of another regular user' do
+ it 'does not contain the note of the user' do
+ get api("/user?private_token=#{admin_personal_access_token}&sudo=#{user.id}")
+
+ expect(json_response['id']).to eq(user.id)
+ expect(json_response).not_to have_key('note')
+ end
+ end
+
+ context 'accesses the profile of another admin' do
+ let(:admin_2) {create(:admin, note: '2010-10-10 | 2FA added | admin requested | www.gitlab.com')}
+
+ it 'contains the note of the user' do
+ get api("/user?private_token=#{admin_personal_access_token}&sudo=#{admin_2.id}")
+
+ expect(json_response['id']).to eq(admin_2.id)
+ expect(json_response).to have_key('note')
+ expect(json_response['note']).to eq(admin_2.note)
+ end
+ end
+ end
+ end
+
+ context 'as a regular user' do
+ it 'does not contain the note of the user' do
+ get api("/user", user)
+
+ expect(json_response).not_to have_key('note')
+ end
+ end
+ end
+ end
+ end
+
shared_examples 'rendering user status' do
it 'returns the status if there was one' do
create(:user_status, user: user)
@@ -257,8 +425,9 @@ describe API::Users, :do_not_mock_admin_mode do
end
it 'returns the correct order when sorted by id' do
- admin
- user
+ # order of let_it_be definitions:
+ # - admin
+ # - user
get api('/users', admin), params: { order_by: 'id', sort: 'asc' }
@@ -269,8 +438,6 @@ describe API::Users, :do_not_mock_admin_mode do
end
it 'returns users with 2fa enabled' do
- admin
- user
user_with_2fa = create(:user, :two_factor_via_otp)
get api('/users', admin), params: { two_factor: 'enabled' }
@@ -298,18 +465,6 @@ describe API::Users, :do_not_mock_admin_mode do
expect(response).to have_gitlab_http_status(:bad_request)
end
end
-
- context "when authenticated and ldap is enabled" do
- it "returns non-ldap user" do
- create :omniauth_user, provider: "ldapserver1"
-
- get api("/users", user), params: { skip_ldap: "true" }
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response).to be_an Array
- expect(json_response.first["username"]).to eq user.username
- end
- end
end
describe "GET /users/:id" do
@@ -492,10 +647,6 @@ describe API::Users, :do_not_mock_admin_mode do
end
describe "POST /users" do
- before do
- admin
- end
-
it "creates user" do
expect do
post api("/users", admin), params: attributes_for(:user, projects_limit: 3)
@@ -734,8 +885,6 @@ describe API::Users, :do_not_mock_admin_mode do
end
describe "PUT /users/:id" do
- let_it_be(:admin_user) { create(:admin) }
-
it "returns 200 OK on success" do
put api("/users/#{user.id}", admin), params: { bio: 'new test bio' }
@@ -752,8 +901,7 @@ describe API::Users, :do_not_mock_admin_mode do
end
it "updates user with empty bio" do
- user.bio = 'previous bio'
- user.save!
+ user.update!(bio: 'previous bio')
put api("/users/#{user.id}", admin), params: { bio: '' }
@@ -870,7 +1018,7 @@ describe API::Users, :do_not_mock_admin_mode do
end
it "updates private profile to false when nil is given" do
- user.update(private_profile: true)
+ user.update!(private_profile: true)
put api("/users/#{user.id}", admin), params: { private_profile: nil }
@@ -879,7 +1027,7 @@ describe API::Users, :do_not_mock_admin_mode do
end
it "does not modify private profile when field is not provided" do
- user.update(private_profile: true)
+ user.update!(private_profile: true)
put api("/users/#{user.id}", admin), params: {}
@@ -891,7 +1039,7 @@ describe API::Users, :do_not_mock_admin_mode do
theme = Gitlab::Themes.each.find { |t| t.id != Gitlab::Themes.default.id }
scheme = Gitlab::ColorSchemes.each.find { |t| t.id != Gitlab::ColorSchemes.default.id }
- user.update(theme_id: theme.id, color_scheme_id: scheme.id)
+ user.update!(theme_id: theme.id, color_scheme_id: scheme.id)
put api("/users/#{user.id}", admin), params: {}
@@ -901,6 +1049,8 @@ describe API::Users, :do_not_mock_admin_mode do
end
it "does not update admin status" do
+ admin_user = create(:admin)
+
put api("/users/#{admin_user.id}", admin), params: { can_create_group: false }
expect(response).to have_gitlab_http_status(:ok)
@@ -1071,10 +1221,6 @@ describe API::Users, :do_not_mock_admin_mode do
end
describe "POST /users/:id/keys" do
- before do
- admin
- end
-
it "does not create invalid ssh key" do
post api("/users/#{user.id}/keys", admin), params: { title: "invalid key" }
@@ -1096,6 +1242,16 @@ describe API::Users, :do_not_mock_admin_mode do
end.to change { user.keys.count }.by(1)
end
+ it 'creates SSH key with `expires_at` attribute' do
+ optional_attributes = { expires_at: '2016-01-21T00:00:00.000Z' }
+ attributes = attributes_for(:key).merge(optional_attributes)
+
+ post api("/users/#{user.id}/keys", admin), params: attributes
+
+ expect(response).to have_gitlab_http_status(:created)
+ expect(json_response['expires_at']).to eq(optional_attributes[:expires_at])
+ end
+
it "returns 400 for invalid ID" do
post api("/users/0/keys", admin)
expect(response).to have_gitlab_http_status(:bad_request)
@@ -1104,9 +1260,7 @@ describe API::Users, :do_not_mock_admin_mode do
describe 'GET /user/:id/keys' do
it 'returns 404 for non-existing user' do
- user_id = not_existing_user_id
-
- get api("/users/#{user_id}/keys")
+ get api("/users/#{non_existing_record_id}/keys")
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 User Not Found')
@@ -1114,7 +1268,6 @@ describe API::Users, :do_not_mock_admin_mode do
it 'returns array of ssh keys' do
user.keys << key
- user.save
get api("/users/#{user.id}/keys")
@@ -1123,11 +1276,41 @@ describe API::Users, :do_not_mock_admin_mode do
expect(json_response).to be_an Array
expect(json_response.first['title']).to eq(key.title)
end
+
+ it 'returns array of ssh keys with comments replaced with'\
+ 'a simple identifier of username + hostname' do
+ get api("/users/#{user.id}/keys")
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+
+ keys = json_response.map { |key_detail| key_detail['key'] }
+ expect(keys).to all(include("#{user.name} (#{Gitlab.config.gitlab.host}"))
+ end
+
+ context 'N+1 queries' do
+ before do
+ get api("/users/#{user.id}/keys")
+ end
+
+ it 'avoids N+1 queries', :request_store do
+ control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do
+ get api("/users/#{user.id}/keys")
+ end.count
+
+ create_list(:key, 2, user: user)
+
+ expect do
+ get api("/users/#{user.id}/keys")
+ end.not_to exceed_all_query_limit(control_count)
+ end
+ end
end
describe 'GET /user/:user_id/keys' do
it 'returns 404 for non-existing user' do
- get api("/users/#{not_existing_user_id}/keys")
+ get api("/users/#{non_existing_record_id}/keys")
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 User Not Found')
@@ -1135,7 +1318,6 @@ describe API::Users, :do_not_mock_admin_mode do
it 'returns array of ssh keys' do
user.keys << key
- user.save
get api("/users/#{user.username}/keys")
@@ -1147,13 +1329,9 @@ describe API::Users, :do_not_mock_admin_mode do
end
describe 'DELETE /user/:id/keys/:key_id' do
- before do
- admin
- end
-
context 'when unauthenticated' do
it 'returns authentication error' do
- delete api("/users/#{user.id}/keys/42")
+ delete api("/users/#{user.id}/keys/#{non_existing_record_id}")
expect(response).to have_gitlab_http_status(:unauthorized)
end
end
@@ -1161,7 +1339,6 @@ describe API::Users, :do_not_mock_admin_mode do
context 'when authenticated' do
it 'deletes existing key' do
user.keys << key
- user.save
expect do
delete api("/users/#{user.id}/keys/#{key.id}", admin)
@@ -1176,14 +1353,14 @@ describe API::Users, :do_not_mock_admin_mode do
it 'returns 404 error if user not found' do
user.keys << key
- user.save
+
delete api("/users/0/keys/#{key.id}", admin)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 User Not Found')
end
it 'returns 404 error if key not foud' do
- delete api("/users/#{user.id}/keys/42", admin)
+ delete api("/users/#{user.id}/keys/#{non_existing_record_id}", admin)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Key Not Found')
end
@@ -1191,10 +1368,6 @@ describe API::Users, :do_not_mock_admin_mode do
end
describe 'POST /users/:id/keys' do
- before do
- admin
- end
-
it 'does not create invalid GPG key' do
post api("/users/#{user.id}/gpg_keys", admin)
@@ -1203,7 +1376,8 @@ describe API::Users, :do_not_mock_admin_mode do
end
it 'creates GPG key' do
- key_attrs = attributes_for :gpg_key
+ key_attrs = attributes_for :gpg_key, key: GpgHelpers::User2.public_key
+
expect do
post api("/users/#{user.id}/gpg_keys", admin), params: key_attrs
@@ -1219,10 +1393,6 @@ describe API::Users, :do_not_mock_admin_mode do
end
describe 'GET /user/:id/gpg_keys' do
- before do
- admin
- end
-
context 'when unauthenticated' do
it 'returns authentication error' do
get api("/users/#{user.id}/gpg_keys")
@@ -1240,7 +1410,7 @@ describe API::Users, :do_not_mock_admin_mode do
end
it 'returns 404 error if key not foud' do
- delete api("/users/#{user.id}/gpg_keys/42", admin)
+ delete api("/users/#{user.id}/gpg_keys/#{non_existing_record_id}", admin)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 GPG Key Not Found')
@@ -1248,7 +1418,6 @@ describe API::Users, :do_not_mock_admin_mode do
it 'returns array of GPG keys' do
user.gpg_keys << gpg_key
- user.save
get api("/users/#{user.id}/gpg_keys", admin)
@@ -1261,13 +1430,9 @@ describe API::Users, :do_not_mock_admin_mode do
end
describe 'DELETE /user/:id/gpg_keys/:key_id' do
- before do
- admin
- end
-
context 'when unauthenticated' do
it 'returns authentication error' do
- delete api("/users/#{user.id}/keys/42")
+ delete api("/users/#{user.id}/keys/#{non_existing_record_id}")
expect(response).to have_gitlab_http_status(:unauthorized)
end
@@ -1276,7 +1441,6 @@ describe API::Users, :do_not_mock_admin_mode do
context 'when authenticated' do
it 'deletes existing key' do
user.gpg_keys << gpg_key
- user.save
expect do
delete api("/users/#{user.id}/gpg_keys/#{gpg_key.id}", admin)
@@ -1287,7 +1451,6 @@ describe API::Users, :do_not_mock_admin_mode do
it 'returns 404 error if user not found' do
user.keys << key
- user.save
delete api("/users/0/gpg_keys/#{gpg_key.id}", admin)
@@ -1296,7 +1459,7 @@ describe API::Users, :do_not_mock_admin_mode do
end
it 'returns 404 error if key not foud' do
- delete api("/users/#{user.id}/gpg_keys/42", admin)
+ delete api("/users/#{user.id}/gpg_keys/#{non_existing_record_id}", admin)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 GPG Key Not Found')
@@ -1305,13 +1468,9 @@ describe API::Users, :do_not_mock_admin_mode do
end
describe 'POST /user/:id/gpg_keys/:key_id/revoke' do
- before do
- admin
- end
-
context 'when unauthenticated' do
it 'returns authentication error' do
- post api("/users/#{user.id}/gpg_keys/42/revoke")
+ post api("/users/#{user.id}/gpg_keys/#{non_existing_record_id}/revoke")
expect(response).to have_gitlab_http_status(:unauthorized)
end
@@ -1320,7 +1479,6 @@ describe API::Users, :do_not_mock_admin_mode do
context 'when authenticated' do
it 'revokes existing key' do
user.gpg_keys << gpg_key
- user.save
expect do
post api("/users/#{user.id}/gpg_keys/#{gpg_key.id}/revoke", admin)
@@ -1331,7 +1489,6 @@ describe API::Users, :do_not_mock_admin_mode do
it 'returns 404 error if user not found' do
user.gpg_keys << gpg_key
- user.save
post api("/users/0/gpg_keys/#{gpg_key.id}/revoke", admin)
@@ -1340,7 +1497,7 @@ describe API::Users, :do_not_mock_admin_mode do
end
it 'returns 404 error if key not foud' do
- post api("/users/#{user.id}/gpg_keys/42/revoke", admin)
+ post api("/users/#{user.id}/gpg_keys/#{non_existing_record_id}/revoke", admin)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 GPG Key Not Found')
@@ -1349,10 +1506,6 @@ describe API::Users, :do_not_mock_admin_mode do
end
describe "POST /users/:id/emails" do
- before do
- admin
- end
-
it "does not create invalid email" do
post api("/users/#{user.id}/emails", admin), params: {}
@@ -1390,10 +1543,6 @@ describe API::Users, :do_not_mock_admin_mode do
end
describe 'GET /user/:id/emails' do
- before do
- admin
- end
-
context 'when unauthenticated' do
it 'returns authentication error' do
get api("/users/#{user.id}/emails")
@@ -1410,7 +1559,6 @@ describe API::Users, :do_not_mock_admin_mode do
it 'returns array of emails' do
user.emails << email
- user.save
get api("/users/#{user.id}/emails", admin)
@@ -1429,13 +1577,9 @@ describe API::Users, :do_not_mock_admin_mode do
end
describe 'DELETE /user/:id/emails/:email_id' do
- before do
- admin
- end
-
context 'when unauthenticated' do
it 'returns authentication error' do
- delete api("/users/#{user.id}/emails/42")
+ delete api("/users/#{user.id}/emails/#{non_existing_record_id}")
expect(response).to have_gitlab_http_status(:unauthorized)
end
end
@@ -1443,7 +1587,6 @@ describe API::Users, :do_not_mock_admin_mode do
context 'when authenticated' do
it 'deletes existing email' do
user.emails << email
- user.save
expect do
delete api("/users/#{user.id}/emails/#{email.id}", admin)
@@ -1458,14 +1601,14 @@ describe API::Users, :do_not_mock_admin_mode do
it 'returns 404 error if user not found' do
user.emails << email
- user.save
+
delete api("/users/0/emails/#{email.id}", admin)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 User Not Found')
end
it 'returns 404 error if email not foud' do
- delete api("/users/#{user.id}/emails/42", admin)
+ delete api("/users/#{user.id}/emails/#{non_existing_record_id}", admin)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Email Not Found')
end
@@ -1479,19 +1622,16 @@ describe API::Users, :do_not_mock_admin_mode do
end
describe "DELETE /users/:id" do
- let!(:namespace) { user.namespace }
- let!(:issue) { create(:issue, author: user) }
-
- before do
- admin
- end
+ let_it_be(:issue) { create(:issue, author: user) }
it "deletes user", :sidekiq_might_not_need_inline do
+ namespace_id = user.namespace.id
+
perform_enqueued_jobs { delete api("/users/#{user.id}", admin) }
expect(response).to have_gitlab_http_status(:no_content)
expect { User.find(user.id) }.to raise_error ActiveRecord::RecordNotFound
- expect { Namespace.find(namespace.id) }.to raise_error ActiveRecord::RecordNotFound
+ expect { Namespace.find(namespace_id) }.to raise_error ActiveRecord::RecordNotFound
end
context "sole owner of a group" do
@@ -1560,11 +1700,11 @@ describe API::Users, :do_not_mock_admin_mode do
end
describe "GET /user" do
- let(:personal_access_token) { create(:personal_access_token, user: user).token }
-
shared_examples 'get user info' do |version|
context 'with regular user' do
context 'with personal access token' do
+ let(:personal_access_token) { create(:personal_access_token, user: user).token }
+
it 'returns 403 without private token when sudo is defined' do
get api("/user?private_token=#{personal_access_token}&sudo=123", version: version)
@@ -1632,7 +1772,6 @@ describe API::Users, :do_not_mock_admin_mode do
context "when authenticated" do
it "returns array of ssh keys" do
user.keys << key
- user.save
get api("/user/keys", user)
@@ -1642,6 +1781,36 @@ describe API::Users, :do_not_mock_admin_mode do
expect(json_response.first["title"]).to eq(key.title)
end
+ it 'returns array of ssh keys with comments replaced with'\
+ 'a simple identifier of username + hostname' do
+ get api("/user/keys", user)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+
+ keys = json_response.map { |key_detail| key_detail['key'] }
+ expect(keys).to all(include("#{user.name} (#{Gitlab.config.gitlab.host}"))
+ end
+
+ context 'N+1 queries' do
+ before do
+ get api("/user/keys", user)
+ end
+
+ it 'avoids N+1 queries', :request_store do
+ control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do
+ get api("/user/keys", user)
+ end.count
+
+ create_list(:key, 2, user: user)
+
+ expect do
+ get api("/user/keys", user)
+ end.not_to exceed_all_query_limit(control_count)
+ end
+ end
+
context "scopes" do
let(:path) { "/user/keys" }
let(:api_call) { method(:api) }
@@ -1654,14 +1823,21 @@ describe API::Users, :do_not_mock_admin_mode do
describe "GET /user/keys/:key_id" do
it "returns single key" do
user.keys << key
- user.save
+
get api("/user/keys/#{key.id}", user)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response["title"]).to eq(key.title)
end
+ it 'exposes SSH key comment as a simple identifier of username + hostname' do
+ get api("/user/keys/#{key.id}", user)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['key']).to include("#{key.user_name} (#{Gitlab.config.gitlab.host})")
+ end
+
it "returns 404 Not Found within invalid ID" do
- get api("/user/keys/42", user)
+ get api("/user/keys/#{non_existing_record_id}", user)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Key Not Found')
@@ -1669,8 +1845,8 @@ describe API::Users, :do_not_mock_admin_mode do
it "returns 404 error if admin accesses user's ssh key" do
user.keys << key
- user.save
admin
+
get api("/user/keys/#{key.id}", admin)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Key Not Found')
@@ -1699,6 +1875,16 @@ describe API::Users, :do_not_mock_admin_mode do
expect(response).to have_gitlab_http_status(:created)
end
+ it 'creates SSH key with `expires_at` attribute' do
+ optional_attributes = { expires_at: '2016-01-21T00:00:00.000Z' }
+ attributes = attributes_for(:key).merge(optional_attributes)
+
+ post api("/user/keys", user), params: attributes
+
+ expect(response).to have_gitlab_http_status(:created)
+ expect(json_response['expires_at']).to eq(optional_attributes[:expires_at])
+ end
+
it "returns a 401 error if unauthorized" do
post api("/user/keys"), params: { title: 'some title', key: 'some key' }
expect(response).to have_gitlab_http_status(:unauthorized)
@@ -1727,7 +1913,6 @@ describe API::Users, :do_not_mock_admin_mode do
describe "DELETE /user/keys/:key_id" do
it "deletes existed key" do
user.keys << key
- user.save
expect do
delete api("/user/keys/#{key.id}", user)
@@ -1741,7 +1926,7 @@ describe API::Users, :do_not_mock_admin_mode do
end
it "returns 404 if key ID not found" do
- delete api("/user/keys/42", user)
+ delete api("/user/keys/#{non_existing_record_id}", user)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Key Not Found')
@@ -1749,7 +1934,7 @@ describe API::Users, :do_not_mock_admin_mode do
it "returns 401 error if unauthorized" do
user.keys << key
- user.save
+
delete api("/user/keys/#{key.id}")
expect(response).to have_gitlab_http_status(:unauthorized)
end
@@ -1773,7 +1958,6 @@ describe API::Users, :do_not_mock_admin_mode do
context 'when authenticated' do
it 'returns array of GPG keys' do
user.gpg_keys << gpg_key
- user.save
get api('/user/gpg_keys', user)
@@ -1795,7 +1979,6 @@ describe API::Users, :do_not_mock_admin_mode do
describe 'GET /user/gpg_keys/:key_id' do
it 'returns a single key' do
user.gpg_keys << gpg_key
- user.save
get api("/user/gpg_keys/#{gpg_key.id}", user)
@@ -1804,7 +1987,7 @@ describe API::Users, :do_not_mock_admin_mode do
end
it 'returns 404 Not Found within invalid ID' do
- get api('/user/gpg_keys/42', user)
+ get api("/user/gpg_keys/#{non_existing_record_id}", user)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 GPG Key Not Found')
@@ -1812,7 +1995,6 @@ describe API::Users, :do_not_mock_admin_mode do
it "returns 404 error if admin accesses user's GPG key" do
user.gpg_keys << gpg_key
- user.save
get api("/user/gpg_keys/#{gpg_key.id}", admin)
@@ -1836,7 +2018,8 @@ describe API::Users, :do_not_mock_admin_mode do
describe 'POST /user/gpg_keys' do
it 'creates a GPG key' do
- key_attrs = attributes_for :gpg_key
+ key_attrs = attributes_for :gpg_key, key: GpgHelpers::User2.public_key
+
expect do
post api('/user/gpg_keys', user), params: key_attrs
@@ -1861,7 +2044,6 @@ describe API::Users, :do_not_mock_admin_mode do
describe 'POST /user/gpg_keys/:key_id/revoke' do
it 'revokes existing GPG key' do
user.gpg_keys << gpg_key
- user.save
expect do
post api("/user/gpg_keys/#{gpg_key.id}/revoke", user)
@@ -1871,7 +2053,7 @@ describe API::Users, :do_not_mock_admin_mode do
end
it 'returns 404 if key ID not found' do
- post api('/user/gpg_keys/42/revoke', user)
+ post api("/user/gpg_keys/#{non_existing_record_id}/revoke", user)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 GPG Key Not Found')
@@ -1879,7 +2061,6 @@ describe API::Users, :do_not_mock_admin_mode do
it 'returns 401 error if unauthorized' do
user.gpg_keys << gpg_key
- user.save
post api("/user/gpg_keys/#{gpg_key.id}/revoke")
@@ -1896,7 +2077,6 @@ describe API::Users, :do_not_mock_admin_mode do
describe 'DELETE /user/gpg_keys/:key_id' do
it 'deletes existing GPG key' do
user.gpg_keys << gpg_key
- user.save
expect do
delete api("/user/gpg_keys/#{gpg_key.id}", user)
@@ -1906,7 +2086,7 @@ describe API::Users, :do_not_mock_admin_mode do
end
it 'returns 404 if key ID not found' do
- delete api('/user/gpg_keys/42', user)
+ delete api("/user/gpg_keys/#{non_existing_record_id}", user)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 GPG Key Not Found')
@@ -1914,7 +2094,6 @@ describe API::Users, :do_not_mock_admin_mode do
it 'returns 401 error if unauthorized' do
user.gpg_keys << gpg_key
- user.save
delete api("/user/gpg_keys/#{gpg_key.id}")
@@ -1939,7 +2118,6 @@ describe API::Users, :do_not_mock_admin_mode do
context "when authenticated" do
it "returns array of emails" do
user.emails << email
- user.save
get api("/user/emails", user)
@@ -1961,22 +2139,22 @@ describe API::Users, :do_not_mock_admin_mode do
describe "GET /user/emails/:email_id" do
it "returns single email" do
user.emails << email
- user.save
+
get api("/user/emails/#{email.id}", user)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response["email"]).to eq(email.email)
end
it "returns 404 Not Found within invalid ID" do
- get api("/user/emails/42", user)
+ get api("/user/emails/#{non_existing_record_id}", user)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Email Not Found')
end
it "returns 404 error if admin accesses user's email" do
user.emails << email
- user.save
admin
+
get api("/user/emails/#{email.id}", admin)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Email Not Found')
@@ -2021,7 +2199,6 @@ describe API::Users, :do_not_mock_admin_mode do
describe "DELETE /user/emails/:email_id" do
it "deletes existed email" do
user.emails << email
- user.save
expect do
delete api("/user/emails/#{email.id}", user)
@@ -2035,7 +2212,7 @@ describe API::Users, :do_not_mock_admin_mode do
end
it "returns 404 if email ID not found" do
- delete api("/user/emails/42", user)
+ delete api("/user/emails/#{non_existing_record_id}", user)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Email Not Found')
@@ -2043,7 +2220,7 @@ describe API::Users, :do_not_mock_admin_mode do
it "returns 401 error if unauthorized" do
user.emails << email
- user.save
+
delete api("/user/emails/#{email.id}")
expect(response).to have_gitlab_http_status(:unauthorized)
end
@@ -2149,7 +2326,7 @@ describe API::Users, :do_not_mock_admin_mode do
context 'performed by an admin user' do
context 'for an active user' do
let(:activity) { {} }
- let(:user) { create(:user, username: 'user.with.dot', **activity) }
+ let(:user) { create(:user, **activity) }
context 'with no recent activity' do
let(:activity) { { last_activity_on: ::User::MINIMUM_INACTIVE_DAYS.next.days.ago } }
@@ -2234,10 +2411,6 @@ describe API::Users, :do_not_mock_admin_mode do
describe 'POST /users/:id/block' do
let(:blocked_user) { create(:user, state: 'blocked') }
- before do
- admin
- end
-
it 'blocks existing user' do
post api("/users/#{user.id}/block", admin)
@@ -2280,10 +2453,6 @@ describe API::Users, :do_not_mock_admin_mode do
let(:blocked_user) { create(:user, state: 'blocked') }
let(:deactivated_user) { create(:user, state: 'deactivated') }
- before do
- admin
- end
-
it 'unblocks existing user' do
post api("/users/#{user.id}/unblock", admin)
expect(response).to have_gitlab_http_status(:created)
@@ -2477,21 +2646,21 @@ describe API::Users, :do_not_mock_admin_mode do
end
describe 'GET /users/:user_id/impersonation_tokens' do
- let!(:active_personal_access_token) { create(:personal_access_token, user: user) }
- let!(:revoked_personal_access_token) { create(:personal_access_token, :revoked, user: user) }
- let!(:expired_personal_access_token) { create(:personal_access_token, :expired, user: user) }
- let!(:impersonation_token) { create(:personal_access_token, :impersonation, user: user) }
- let!(:revoked_impersonation_token) { create(:personal_access_token, :impersonation, :revoked, user: user) }
+ let_it_be(:active_personal_access_token) { create(:personal_access_token, user: user) }
+ let_it_be(:revoked_personal_access_token) { create(:personal_access_token, :revoked, user: user) }
+ let_it_be(:expired_personal_access_token) { create(:personal_access_token, :expired, user: user) }
+ let_it_be(:impersonation_token) { create(:personal_access_token, :impersonation, user: user) }
+ let_it_be(:revoked_impersonation_token) { create(:personal_access_token, :impersonation, :revoked, user: user) }
it 'returns a 404 error if user not found' do
- get api("/users/#{not_existing_user_id}/impersonation_tokens", admin)
+ get api("/users/#{non_existing_record_id}/impersonation_tokens", admin)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 User Not Found')
end
it 'returns a 403 error when authenticated as normal user' do
- get api("/users/#{not_existing_user_id}/impersonation_tokens", user)
+ get api("/users/#{non_existing_record_id}/impersonation_tokens", user)
expect(response).to have_gitlab_http_status(:forbidden)
expect(json_response['message']).to eq('403 Forbidden')
@@ -2540,7 +2709,7 @@ describe API::Users, :do_not_mock_admin_mode do
end
it 'returns a 404 error if user not found' do
- post api("/users/#{not_existing_user_id}/impersonation_tokens", admin),
+ post api("/users/#{non_existing_record_id}/impersonation_tokens", admin),
params: {
name: name,
expires_at: expires_at
@@ -2584,18 +2753,18 @@ describe API::Users, :do_not_mock_admin_mode do
end
describe 'GET /users/:user_id/impersonation_tokens/:impersonation_token_id' do
- let!(:personal_access_token) { create(:personal_access_token, user: user) }
- let!(:impersonation_token) { create(:personal_access_token, :impersonation, user: user) }
+ let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
+ let_it_be(:impersonation_token) { create(:personal_access_token, :impersonation, user: user) }
it 'returns 404 error if user not found' do
- get api("/users/#{not_existing_user_id}/impersonation_tokens/1", admin)
+ get api("/users/#{non_existing_record_id}/impersonation_tokens/1", admin)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 User Not Found')
end
it 'returns a 404 error if impersonation token not found' do
- get api("/users/#{user.id}/impersonation_tokens/#{not_existing_pat_id}", admin)
+ get api("/users/#{user.id}/impersonation_tokens/#{non_existing_record_id}", admin)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Impersonation Token Not Found')
@@ -2625,18 +2794,18 @@ describe API::Users, :do_not_mock_admin_mode do
end
describe 'DELETE /users/:user_id/impersonation_tokens/:impersonation_token_id' do
- let!(:personal_access_token) { create(:personal_access_token, user: user) }
- let!(:impersonation_token) { create(:personal_access_token, :impersonation, user: user) }
+ let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
+ let_it_be(:impersonation_token) { create(:personal_access_token, :impersonation, user: user) }
it 'returns a 404 error if user not found' do
- delete api("/users/#{not_existing_user_id}/impersonation_tokens/1", admin)
+ delete api("/users/#{non_existing_record_id}/impersonation_tokens/1", admin)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 User Not Found')
end
it 'returns a 404 error if impersonation token not found' do
- delete api("/users/#{user.id}/impersonation_tokens/#{not_existing_pat_id}", admin)
+ delete api("/users/#{user.id}/impersonation_tokens/#{non_existing_record_id}", admin)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Impersonation Token Not Found')
diff --git a/spec/requests/groups/registry/repositories_controller_spec.rb b/spec/requests/groups/registry/repositories_controller_spec.rb
index 25bd7aa862e..ab59b006be7 100644
--- a/spec/requests/groups/registry/repositories_controller_spec.rb
+++ b/spec/requests/groups/registry/repositories_controller_spec.rb
@@ -8,7 +8,7 @@ describe Groups::Registry::RepositoriesController do
before do
stub_container_registry_config(enabled: true)
-
+ stub_container_registry_tags(repository: :any, tags: [])
group.add_reporter(user)
login_as(user)
end
diff --git a/spec/requests/import/gitlab_groups_controller_spec.rb b/spec/requests/import/gitlab_groups_controller_spec.rb
new file mode 100644
index 00000000000..35f2bf0c2f7
--- /dev/null
+++ b/spec/requests/import/gitlab_groups_controller_spec.rb
@@ -0,0 +1,258 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Import::GitlabGroupsController do
+ include WorkhorseHelpers
+
+ let(:import_path) { "#{Dir.tmpdir}/gitlab_groups_controller_spec" }
+ let(:workhorse_token) { JWT.encode({ 'iss' => 'gitlab-workhorse' }, Gitlab::Workhorse.secret, 'HS256') }
+ let(:workhorse_headers) do
+ { 'GitLab-Workhorse' => '1.0', Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER => workhorse_token }
+ end
+
+ before do
+ allow_next_instance_of(Gitlab::ImportExport) do |import_export|
+ expect(import_export).to receive(:storage_path).and_return(import_path)
+ end
+
+ stub_uploads_object_storage(ImportExportUploader)
+ end
+
+ after do
+ FileUtils.rm_rf(import_path, secure: true)
+ end
+
+ describe 'POST create' do
+ subject(:import_request) { upload_archive(file_upload, workhorse_headers, request_params) }
+
+ let_it_be(:user) { create(:user) }
+
+ let(:file) { File.join('spec', %w[fixtures group_export.tar.gz]) }
+ let(:file_upload) { fixture_file_upload(file) }
+
+ before do
+ login_as(user)
+ end
+
+ def upload_archive(file, headers = {}, params = {})
+ workhorse_finalize(
+ import_gitlab_group_path,
+ method: :post,
+ file_key: :file,
+ params: params.merge(file: file),
+ headers: headers,
+ send_rewritten_field: true
+ )
+ end
+
+ context 'when importing without a parent group' do
+ let(:request_params) { { path: 'test-group-import', name: 'test-group-import' } }
+
+ it 'successfully creates the group' do
+ expect { import_request }.to change { Group.count }.by 1
+
+ group = Group.find_by(name: 'test-group-import')
+
+ expect(response).to have_gitlab_http_status(:found)
+ expect(response).to redirect_to(group_path(group))
+ expect(flash[:notice]).to include('is being imported')
+ end
+
+ it 'imports the group data', :sidekiq_inline do
+ allow(GroupImportWorker).to receive(:perform_async).and_call_original
+
+ import_request
+
+ group = Group.find_by(name: 'test-group-import')
+
+ expect(GroupImportWorker).to have_received(:perform_async).with(user.id, group.id)
+
+ expect(group.description).to eq 'A voluptate non sequi temporibus quam at.'
+ expect(group.visibility_level).to eq Gitlab::VisibilityLevel::PRIVATE
+ end
+ end
+
+ context 'when importing to a parent group' do
+ let(:request_params) { { path: 'test-group-import', name: 'test-group-import', parent_id: parent_group.id } }
+ let(:parent_group) { create(:group) }
+
+ before do
+ parent_group.add_owner(user)
+ end
+
+ it 'creates a new group under the parent' do
+ expect { import_request }
+ .to change { parent_group.children.reload.size }.by 1
+
+ expect(response).to have_gitlab_http_status(:found)
+ end
+
+ shared_examples 'is created with the parent visibility level' do |visibility_level|
+ before do
+ parent_group.update!(visibility_level: visibility_level)
+ end
+
+ it "imports a #{Gitlab::VisibilityLevel.level_name(visibility_level)} group" do
+ import_request
+
+ group = parent_group.children.find_by(name: 'test-group-import')
+ expect(group.visibility_level).to eq visibility_level
+ end
+ end
+
+ [
+ Gitlab::VisibilityLevel::PUBLIC,
+ Gitlab::VisibilityLevel::INTERNAL,
+ Gitlab::VisibilityLevel::PRIVATE
+ ].each do |visibility_level|
+ context "when the parent is #{Gitlab::VisibilityLevel.level_name(visibility_level)}" do
+ include_examples 'is created with the parent visibility level', visibility_level
+ end
+ end
+ end
+
+ context 'when supplied invalid params' do
+ subject(:import_request) do
+ upload_archive(
+ file_upload,
+ workhorse_headers,
+ { path: '', name: '' }
+ )
+ end
+
+ it 'responds with an error' do
+ expect { import_request }.not_to change { Group.count }
+
+ expect(flash[:alert])
+ .to include('Group could not be imported', "Name can't be blank", 'Group URL is too short')
+ end
+ end
+
+ context 'when the user is not authorized to create groups' do
+ let(:request_params) { { path: 'test-group-import', name: 'test-group-import' } }
+ let(:user) { create(:user, can_create_group: false) }
+
+ it 'returns an error' do
+ expect { import_request }.not_to change { Group.count }
+
+ expect(flash[:alert]).to eq 'Group could not be imported: You don’t have permission to create groups.'
+ end
+ end
+
+ context 'when the requests exceed the rate limit' do
+ let(:request_params) { { path: 'test-group-import', name: 'test-group-import' } }
+
+ before do
+ allow(Gitlab::ApplicationRateLimiter).to receive(:throttled?).and_return(true)
+ end
+
+ it 'throttles the requests' do
+ import_request
+
+ expect(response).to have_gitlab_http_status(:found)
+ expect(flash[:alert]).to eq 'This endpoint has been requested too many times. Try again later.'
+ end
+ end
+
+ context 'when group import FF is disabled' do
+ let(:request_params) { { path: 'test-group-import', name: 'test-group-import' } }
+
+ before do
+ stub_feature_flags(group_import_export: false)
+ end
+
+ it 'returns an error' do
+ expect { import_request }.not_to change { Group.count }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'when the parent group is invalid' do
+ let(:request_params) { { path: 'test-group-import', name: 'test-group-import', parent_id: -1 } }
+
+ it 'does not create a new group' do
+ expect { import_request }.not_to change { Group.count }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'when the user is not an owner of the parent group' do
+ let(:request_params) { { path: 'test-group-import', name: 'test-group-import', parent_id: parent_group.id } }
+ let(:parent_group) { create(:group) }
+
+ it 'returns an error' do
+ expect { import_request }.not_to change { parent_group.children.reload.count }
+
+ expect(flash[:alert]).to include "You don’t have permission to create a subgroup in this group"
+ end
+ end
+ end
+
+ describe 'POST authorize' do
+ let_it_be(:user) { create(:user) }
+
+ before do
+ login_as(user)
+ end
+
+ context 'when using a workhorse header' do
+ subject(:authorize_request) { post authorize_import_gitlab_group_path, headers: workhorse_headers }
+
+ it 'authorizes the request' do
+ authorize_request
+
+ expect(response).to have_gitlab_http_status :ok
+ expect(response.media_type).to eq Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE
+ expect(json_response['TempPath']).to eq ImportExportUploader.workhorse_local_upload_path
+ end
+ end
+
+ context 'when the request bypasses gitlab-workhorse' do
+ subject(:authorize_request) { post authorize_import_gitlab_group_path }
+
+ it 'rejects the request' do
+ expect { authorize_request }.to raise_error(JWT::DecodeError)
+ end
+ end
+
+ context 'when direct upload is enabled' do
+ subject(:authorize_request) { post authorize_import_gitlab_group_path, headers: workhorse_headers }
+
+ before do
+ stub_uploads_object_storage(ImportExportUploader, enabled: true, direct_upload: true)
+ end
+
+ it 'accepts the request and stores the files' do
+ authorize_request
+
+ expect(response).to have_gitlab_http_status :ok
+ expect(response.media_type).to eq Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE
+ expect(json_response).not_to have_key 'TempPath'
+
+ expect(json_response['RemoteObject'].keys)
+ .to include('ID', 'GetURL', 'StoreURL', 'DeleteURL', 'MultipartUpload')
+ end
+ end
+
+ context 'when direct upload is disabled' do
+ subject(:authorize_request) { post authorize_import_gitlab_group_path, headers: workhorse_headers }
+
+ before do
+ stub_uploads_object_storage(ImportExportUploader, enabled: true, direct_upload: false)
+ end
+
+ it 'handles the local file' do
+ authorize_request
+
+ expect(response).to have_gitlab_http_status :ok
+ expect(response.media_type).to eq Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE
+
+ expect(json_response['TempPath']).to eq ImportExportUploader.workhorse_local_upload_path
+ expect(json_response['RemoteObject']).to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/requests/user_spoofs_ip_spec.rb b/spec/requests/user_spoofs_ip_spec.rb
new file mode 100644
index 00000000000..8da15665132
--- /dev/null
+++ b/spec/requests/user_spoofs_ip_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'User spoofs their IP' do
+ it 'raises a 400 error' do
+ get '/nonexistent', headers: { 'Client-Ip' => '1.2.3.4', 'X-Forwarded-For' => '5.6.7.8' }
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(response.body).to eq('Bad Request')
+ end
+end
diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb
index f8e1ccac912..6150a9637c7 100644
--- a/spec/routing/project_routing_spec.rb
+++ b/spec/routing/project_routing_spec.rb
@@ -482,8 +482,6 @@ describe 'project routing' do
let(:controller) { 'project_members' }
let(:controller_path) { '/-/project_members' }
end
-
- it_behaves_like 'redirecting a legacy project path', "/gitlab/gitlabhq/-/settings/members", "/gitlab/gitlabhq/-/project_members"
end
# project_milestones GET /:project_id/milestones(.:format) milestones#index
diff --git a/spec/rubocop/cop/active_record_association_reload_spec.rb b/spec/rubocop/cop/active_record_association_reload_spec.rb
index 3cd7a35f12f..d9c8069f0c3 100644
--- a/spec/rubocop/cop/active_record_association_reload_spec.rb
+++ b/spec/rubocop/cop/active_record_association_reload_spec.rb
@@ -11,7 +11,7 @@ describe RuboCop::Cop::ActiveRecordAssociationReload do
context 'when using ActiveRecord::Base' do
it 'registers an offense on reload usage' do
- expect_offense(<<~PATTERN.strip_indent)
+ expect_offense(<<~PATTERN)
users = User.all
users.reload
^^^^^^ Use reset instead of reload. For more details check the https://gitlab.com/gitlab-org/gitlab-foss/issues/60218.
@@ -19,7 +19,7 @@ describe RuboCop::Cop::ActiveRecordAssociationReload do
end
it 'does not register an offense on reset usage' do
- expect_no_offenses(<<~PATTERN.strip_indent)
+ expect_no_offenses(<<~PATTERN)
users = User.all
users.reset
PATTERN
@@ -28,7 +28,7 @@ describe RuboCop::Cop::ActiveRecordAssociationReload do
context 'when using ActiveRecord::Relation' do
it 'registers an offense on reload usage' do
- expect_offense(<<~PATTERN.strip_indent)
+ expect_offense(<<~PATTERN)
user = User.new
user.reload
^^^^^^ Use reset instead of reload. For more details check the https://gitlab.com/gitlab-org/gitlab-foss/issues/60218.
@@ -36,7 +36,7 @@ describe RuboCop::Cop::ActiveRecordAssociationReload do
end
it 'does not register an offense on reset usage' do
- expect_no_offenses(<<~PATTERN.strip_indent)
+ expect_no_offenses(<<~PATTERN)
user = User.new
user.reset
PATTERN
@@ -45,14 +45,14 @@ describe RuboCop::Cop::ActiveRecordAssociationReload do
context 'when using on self' do
it 'registers an offense on reload usage' do
- expect_offense(<<~PATTERN.strip_indent)
+ expect_offense(<<~PATTERN)
reload
^^^^^^ Use reset instead of reload. For more details check the https://gitlab.com/gitlab-org/gitlab-foss/issues/60218.
PATTERN
end
it 'does not register an offense on reset usage' do
- expect_no_offenses(<<~PATTERN.strip_indent)
+ expect_no_offenses(<<~PATTERN)
reset
PATTERN
end
diff --git a/spec/rubocop/cop/avoid_route_redirect_leading_slash_spec.rb b/spec/rubocop/cop/avoid_route_redirect_leading_slash_spec.rb
index c9eb61ccc72..207c3420fbd 100644
--- a/spec/rubocop/cop/avoid_route_redirect_leading_slash_spec.rb
+++ b/spec/rubocop/cop/avoid_route_redirect_leading_slash_spec.rb
@@ -14,14 +14,14 @@ describe RuboCop::Cop::AvoidRouteRedirectLeadingSlash do
end
it 'registers an offense when redirect has a leading slash' do
- expect_offense(<<~PATTERN.strip_indent)
+ expect_offense(<<~PATTERN)
root to: redirect("/-/route")
^^^^^^^^^^^^^^^^^^^^ Do not use a leading "/" in route redirects
PATTERN
end
it 'does not register an offense when redirect does not have a leading slash' do
- expect_no_offenses(<<~PATTERN.strip_indent)
+ expect_no_offenses(<<~PATTERN)
root to: redirect("-/route")
PATTERN
end
diff --git a/spec/rubocop/cop/default_scope_spec.rb b/spec/rubocop/cop/default_scope_spec.rb
new file mode 100644
index 00000000000..9520915f900
--- /dev/null
+++ b/spec/rubocop/cop/default_scope_spec.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'rubocop'
+require 'rubocop/rspec/support'
+require_relative '../../../rubocop/cop/default_scope'
+
+describe RuboCop::Cop::DefaultScope do
+ include CopHelper
+
+ subject(:cop) { described_class.new }
+
+ it 'does not flag the use of default_scope with a send receiver' do
+ inspect_source('foo.default_scope')
+
+ expect(cop.offenses.size).to eq(0)
+ end
+
+ it 'flags the use of default_scope with a constant receiver' do
+ inspect_source('User.default_scope')
+
+ expect(cop.offenses.size).to eq(1)
+ end
+
+ it 'flags the use of default_scope with a nil receiver' do
+ inspect_source('class Foo ; default_scope ; end')
+
+ expect(cop.offenses.size).to eq(1)
+ end
+
+ it 'flags the use of default_scope when passing arguments' do
+ inspect_source('class Foo ; default_scope(:foo) ; end')
+
+ expect(cop.offenses.size).to eq(1)
+ end
+
+ it 'flags the use of default_scope when passing a block' do
+ inspect_source('class Foo ; default_scope { :foo } ; end')
+
+ expect(cop.offenses.size).to eq(1)
+ end
+
+ it 'ignores the use of default_scope with a local variable receiver' do
+ inspect_source('users = User.all ; users.default_scope')
+
+ expect(cop.offenses.size).to eq(0)
+ end
+end
diff --git a/spec/rubocop/cop/destroy_all_spec.rb b/spec/rubocop/cop/destroy_all_spec.rb
index ac8aa56e040..d06c0b2f3cf 100644
--- a/spec/rubocop/cop/destroy_all_spec.rb
+++ b/spec/rubocop/cop/destroy_all_spec.rb
@@ -11,13 +11,13 @@ describe RuboCop::Cop::DestroyAll do
subject(:cop) { described_class.new }
it 'flags the use of destroy_all with a send receiver' do
- inspect_source('foo.destroy_all # rubocop: disable DestroyAll')
+ inspect_source('foo.destroy_all # rubocop: disable Cop/DestroyAll')
expect(cop.offenses.size).to eq(1)
end
it 'flags the use of destroy_all with a constant receiver' do
- inspect_source('User.destroy_all # rubocop: disable DestroyAll')
+ inspect_source('User.destroy_all # rubocop: disable Cop/DestroyAll')
expect(cop.offenses.size).to eq(1)
end
@@ -31,7 +31,7 @@ describe RuboCop::Cop::DestroyAll do
it 'flags the use of destroy_all with a local variable receiver' do
inspect_source(<<~RUBY)
users = User.all
- users.destroy_all # rubocop: disable DestroyAll
+ users.destroy_all # rubocop: disable Cop/DestroyAll
RUBY
expect(cop.offenses.size).to eq(1)
diff --git a/spec/rubocop/cop/filename_length_spec.rb b/spec/rubocop/cop/filename_length_spec.rb
index 1a665440cbc..b1cc845787a 100644
--- a/spec/rubocop/cop/filename_length_spec.rb
+++ b/spec/rubocop/cop/filename_length_spec.rb
@@ -1,12 +1,11 @@
# frozen_string_literal: true
-require 'spec_helper'
+require 'fast_spec_helper'
require 'rubocop'
require 'rubocop/rspec/support'
require_relative '../../../rubocop/cop/filename_length'
-require_relative '../../support/helpers/expect_offense'
-describe RuboCop::Cop::FilenameLength do
+describe RuboCop::Cop::FilenameLength, type: :rubocop do
subject(:cop) { described_class.new }
it 'does not flag files with names 100 characters long' do
diff --git a/spec/rubocop/cop/gitlab/bulk_insert_spec.rb b/spec/rubocop/cop/gitlab/bulk_insert_spec.rb
new file mode 100644
index 00000000000..937c709218f
--- /dev/null
+++ b/spec/rubocop/cop/gitlab/bulk_insert_spec.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'rubocop'
+require 'rubocop/rspec/support'
+require_relative '../../../../rubocop/cop/gitlab/bulk_insert'
+
+describe RuboCop::Cop::Gitlab::BulkInsert do
+ include CopHelper
+
+ subject(:cop) { described_class.new }
+
+ it 'flags the use of Gitlab::Database.bulk_insert' do
+ expect_offense(<<~SOURCE)
+ Gitlab::Database.bulk_insert('merge_request_diff_files', rows)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use the `BulkInsertSafe` concern, instead of using `Gitlab::Database.bulk_insert`. See https://docs.gitlab.com/ee/development/insert_into_tables_in_batches.html
+ SOURCE
+ end
+end
diff --git a/spec/rubocop/cop/gitlab/change_timezone_spec.rb b/spec/rubocop/cop/gitlab/change_timezone_spec.rb
index af76559a9fa..1e4b4048cf4 100644
--- a/spec/rubocop/cop/gitlab/change_timezone_spec.rb
+++ b/spec/rubocop/cop/gitlab/change_timezone_spec.rb
@@ -12,7 +12,7 @@ describe RuboCop::Cop::Gitlab::ChangeTimezone do
context 'Time.zone=' do
it 'registers an offense with no 2nd argument' do
- expect_offense(<<~PATTERN.strip_indent)
+ expect_offense(<<~PATTERN)
Time.zone = 'Awkland'
^^^^^^^^^^^^^^^^^^^^^ Do not change timezone in the runtime (application or rspec), it could result in silently modifying other behavior.
PATTERN
diff --git a/spec/rubocop/cop/gitlab/const_get_inherit_false_spec.rb b/spec/rubocop/cop/gitlab/const_get_inherit_false_spec.rb
index 0ff06b431eb..bf0434e7afe 100644
--- a/spec/rubocop/cop/gitlab/const_get_inherit_false_spec.rb
+++ b/spec/rubocop/cop/gitlab/const_get_inherit_false_spec.rb
@@ -12,7 +12,7 @@ describe RuboCop::Cop::Gitlab::ConstGetInheritFalse do
context 'Object.const_get' do
it 'registers an offense with no 2nd argument' do
- expect_offense(<<~PATTERN.strip_indent)
+ expect_offense(<<~PATTERN)
Object.const_get(:CONSTANT)
^^^^^^^^^ Use inherit=false when using const_get.
PATTERN
@@ -24,7 +24,7 @@ describe RuboCop::Cop::Gitlab::ConstGetInheritFalse do
context 'inherit=false' do
it 'does not register an offense' do
- expect_no_offenses(<<~PATTERN.strip_indent)
+ expect_no_offenses(<<~PATTERN)
Object.const_get(:CONSTANT, false)
PATTERN
end
@@ -32,7 +32,7 @@ describe RuboCop::Cop::Gitlab::ConstGetInheritFalse do
context 'inherit=true' do
it 'registers an offense' do
- expect_offense(<<~PATTERN.strip_indent)
+ expect_offense(<<~PATTERN)
Object.const_get(:CONSTANT, true)
^^^^^^^^^ Use inherit=false when using const_get.
PATTERN
@@ -46,7 +46,7 @@ describe RuboCop::Cop::Gitlab::ConstGetInheritFalse do
context 'const_get for a nested class' do
it 'registers an offense on reload usage' do
- expect_offense(<<~PATTERN.strip_indent)
+ expect_offense(<<~PATTERN)
Nested::Blog.const_get(:CONSTANT)
^^^^^^^^^ Use inherit=false when using const_get.
PATTERN
@@ -58,7 +58,7 @@ describe RuboCop::Cop::Gitlab::ConstGetInheritFalse do
context 'inherit=false' do
it 'does not register an offense' do
- expect_no_offenses(<<~PATTERN.strip_indent)
+ expect_no_offenses(<<~PATTERN)
Nested::Blog.const_get(:CONSTANT, false)
PATTERN
end
@@ -66,7 +66,7 @@ describe RuboCop::Cop::Gitlab::ConstGetInheritFalse do
context 'inherit=true' do
it 'registers an offense if inherit is true' do
- expect_offense(<<~PATTERN.strip_indent)
+ expect_offense(<<~PATTERN)
Nested::Blog.const_get(:CONSTANT, true)
^^^^^^^^^ Use inherit=false when using const_get.
PATTERN
diff --git a/spec/rubocop/cop/gitlab/duplicate_spec_location_spec.rb b/spec/rubocop/cop/gitlab/duplicate_spec_location_spec.rb
index 87dd2f14b31..3a0a74a4713 100644
--- a/spec/rubocop/cop/gitlab/duplicate_spec_location_spec.rb
+++ b/spec/rubocop/cop/gitlab/duplicate_spec_location_spec.rb
@@ -20,7 +20,7 @@ describe RuboCop::Cop::Gitlab::DuplicateSpecLocation do
context 'Non-EE spec file' do
it 'registers no offenses' do
- expect_no_offenses(<<~SOURCE.strip_indent, full_path('spec/foo_spec.rb'))
+ expect_no_offenses(<<~SOURCE, full_path('spec/foo_spec.rb'))
describe 'Foo' do
end
SOURCE
@@ -29,7 +29,7 @@ describe RuboCop::Cop::Gitlab::DuplicateSpecLocation do
context 'Non-EE application file' do
it 'registers no offenses' do
- expect_no_offenses(<<~SOURCE.strip_indent, full_path('app/models/blog_post.rb'))
+ expect_no_offenses(<<~SOURCE, full_path('app/models/blog_post.rb'))
class BlogPost
end
SOURCE
@@ -38,7 +38,7 @@ describe RuboCop::Cop::Gitlab::DuplicateSpecLocation do
context 'EE application file' do
it 'registers no offenses' do
- expect_no_offenses(<<~SOURCE.strip_indent, full_path('ee/app/models/blog_post.rb'))
+ expect_no_offenses(<<~SOURCE, full_path('ee/app/models/blog_post.rb'))
class BlogPost
end
SOURCE
@@ -49,7 +49,7 @@ describe RuboCop::Cop::Gitlab::DuplicateSpecLocation do
let(:spec_file_path) { full_path('ee/spec/controllers/foo_spec.rb') }
it 'registers no offenses' do
- expect_no_offenses(<<~SOURCE.strip_indent, spec_file_path)
+ expect_no_offenses(<<~SOURCE, spec_file_path)
describe 'Foo' do
end
SOURCE
@@ -65,7 +65,7 @@ describe RuboCop::Cop::Gitlab::DuplicateSpecLocation do
end
it 'marks the describe as offending' do
- expect_offense(<<~SOURCE.strip_indent, spec_file_path)
+ expect_offense(<<~SOURCE, spec_file_path)
describe 'Foo' do
^^^^^^^^^^^^^^ Duplicate spec location in `ee/spec/controllers/ee/foo_spec.rb`.
end
@@ -78,7 +78,7 @@ describe RuboCop::Cop::Gitlab::DuplicateSpecLocation do
let(:spec_file_path) { full_path('ee/spec/controllers/ee/foo_spec.rb') }
it 'registers no offenses' do
- expect_no_offenses(<<~SOURCE.strip_indent, spec_file_path)
+ expect_no_offenses(<<~SOURCE, spec_file_path)
describe 'Foo' do
end
SOURCE
@@ -94,7 +94,7 @@ describe RuboCop::Cop::Gitlab::DuplicateSpecLocation do
end
it 'marks the describe as offending' do
- expect_offense(<<~SOURCE.strip_indent, spec_file_path)
+ expect_offense(<<~SOURCE, spec_file_path)
describe 'Foo' do
^^^^^^^^^^^^^^ Duplicate spec location in `ee/spec/controllers/foo_spec.rb`.
end
diff --git a/spec/rubocop/cop/inject_enterprise_edition_module_spec.rb b/spec/rubocop/cop/inject_enterprise_edition_module_spec.rb
index 3cb1dbbbc2c..f047baa3bc2 100644
--- a/spec/rubocop/cop/inject_enterprise_edition_module_spec.rb
+++ b/spec/rubocop/cop/inject_enterprise_edition_module_spec.rb
@@ -170,6 +170,20 @@ describe RuboCop::Cop::InjectEnterpriseEditionModule do
SOURCE
end
+ it 'does not flag the use of `prepend_if_ee EE` as long as all injections are at the end of the file' do
+ expect_no_offenses(<<~SOURCE)
+ class Foo
+ end
+
+ Foo.include_if_ee('EE::Foo')
+ Foo.prepend_if_ee('EE::Foo')
+
+ Foo.include(Bar)
+ # comment on prepending Bar
+ Foo.prepend(Bar)
+ SOURCE
+ end
+
it 'autocorrects offenses by just disabling the Cop' do
source = <<~SOURCE
class Foo
diff --git a/spec/rubocop/cop/migration/add_index_spec.rb b/spec/rubocop/cop/migration/add_index_spec.rb
index 0c3f87e5bf8..ca1aadb381b 100644
--- a/spec/rubocop/cop/migration/add_index_spec.rb
+++ b/spec/rubocop/cop/migration/add_index_spec.rb
@@ -18,7 +18,7 @@ describe RuboCop::Cop::Migration::AddIndex do
end
it 'registers an offense when add_index is used' do
- expect_offense(<<~PATTERN.strip_indent)
+ expect_offense(<<~PATTERN)
def change
add_index :table, :column
^^^^^^^^^ `add_index` requires downtime, use `add_concurrent_index` instead
@@ -29,7 +29,7 @@ describe RuboCop::Cop::Migration::AddIndex do
context 'outside of migration' do
it 'registers no offense' do
- expect_no_offenses(<<~PATTERN.strip_indent)
+ expect_no_offenses(<<~PATTERN)
def change
add_index :table, :column
end
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 514260a4306..39ca9ace73d 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
@@ -73,6 +73,27 @@ describe RuboCop::Cop::Migration::AddLimitToTextColumns do
end
end
+ context 'when text array columns are defined without a limit' do
+ it 'registers no offense' do
+ expect_no_offenses(<<~RUBY)
+ class TestTextLimits < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def up
+ create_table :test_text_limits, id: false do |t|
+ t.integer :test_id, null: false
+ t.text :name, array: true, default: [], null: false
+ end
+
+ add_column :test_text_limits, :email, :text, array: true
+ add_column_with_default :test_text_limits, :role, :text, default: [], array: true
+ change_column_type_concurrently :test_text_limits, :test_id, :text, array: true
+ end
+ end
+ RUBY
+ end
+ end
+
# Make sure that the cop is properly checking for an `add_text_limit`
# over the same {table, attribute} as the one that triggered the offence
context 'when the limit is defined for a same name attribute but different table' do
diff --git a/spec/rubocop/cop/migration/drop_table_spec.rb b/spec/rubocop/cop/migration/drop_table_spec.rb
new file mode 100644
index 00000000000..4fe7fc8c5a5
--- /dev/null
+++ b/spec/rubocop/cop/migration/drop_table_spec.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require 'rubocop'
+require 'rubocop/rspec/support'
+
+require_relative '../../../../rubocop/cop/migration/drop_table'
+
+describe RuboCop::Cop::Migration::DropTable do
+ include CopHelper
+
+ subject(:cop) { described_class.new }
+
+ context 'when in deployment migration' do
+ before do
+ allow(cop).to receive(:in_deployment_migration?).and_return(true)
+ end
+
+ it 'registers an offense' do
+ expect_offense(<<~PATTERN)
+ def change
+ drop_table :table
+ ^^^^^^^^^^ #{described_class::MSG}
+
+ add_column(:users, :username, :text)
+
+ execute "DROP TABLE table"
+ ^^^^^^^ #{described_class::MSG}
+
+ execute "CREATE UNIQUE INDEX email_index ON users (email);"
+ end
+ PATTERN
+ end
+ end
+
+ context 'when in post-deployment migration' do
+ before do
+ allow(cop).to receive(:in_post_deployment_migration?).and_return(true)
+ end
+
+ it 'registers no offense' do
+ expect_no_offenses(<<~PATTERN)
+ def change
+ drop_table :table
+ execute "DROP TABLE table"
+ end
+ PATTERN
+ end
+ end
+
+ context 'when outside of migration' do
+ it 'registers no offense' do
+ expect_no_offenses(<<~PATTERN)
+ def change
+ drop_table :table
+ execute "DROP TABLE table"
+ end
+ PATTERN
+ end
+ end
+end
diff --git a/spec/rubocop/cop/migration/prevent_strings_spec.rb b/spec/rubocop/cop/migration/prevent_strings_spec.rb
index 2702ce1c090..d0e97874aed 100644
--- a/spec/rubocop/cop/migration/prevent_strings_spec.rb
+++ b/spec/rubocop/cop/migration/prevent_strings_spec.rb
@@ -90,6 +90,27 @@ describe RuboCop::Cop::Migration::PreventStrings do
end
end
+ context 'when the string data type is used for arrays' do
+ it 'registers no offense' do
+ expect_no_offenses(<<~RUBY)
+ class TestStringArrays < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def up
+ create_table :test_string_arrays, id: false do |t|
+ t.integer :test_id, null: false
+ t.string :name, array: true, default: [], null: false
+ end
+
+ add_column :test_string_arrays, :email, :string, array: true
+ add_column_with_default :test_string_arrays, :role, :string, default: [], array: true
+ change_column_type_concurrently :test_string_arrays, :test_id, :string, array: true
+ end
+ end
+ RUBY
+ end
+ end
+
context 'on down' do
it 'registers no offense' do
expect_no_offenses(<<~RUBY)
diff --git a/spec/rubocop/cop/migration/update_large_table_spec.rb b/spec/rubocop/cop/migration/update_large_table_spec.rb
deleted file mode 100644
index 30cd84108df..00000000000
--- a/spec/rubocop/cop/migration/update_large_table_spec.rb
+++ /dev/null
@@ -1,91 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-require 'rubocop'
-require 'rubocop/rspec/support'
-
-require_relative '../../../../rubocop/cop/migration/update_large_table'
-
-describe RuboCop::Cop::Migration::UpdateLargeTable do
- include CopHelper
-
- subject(:cop) { described_class.new }
-
- context 'in migration' do
- before do
- allow(cop).to receive(:in_migration?).and_return(true)
- end
-
- shared_examples 'large tables' do |update_method|
- described_class::BLACKLISTED_TABLES.each do |table|
- it "registers an offense for the #{table} table" do
- inspect_source("#{update_method} :#{table}, :column, default: true")
-
- aggregate_failures do
- expect(cop.offenses.size).to eq(1)
- expect(cop.offenses.map(&:line)).to eq([1])
- end
- end
- end
- end
-
- context 'for the add_column_with_default method' do
- include_examples 'large tables', 'add_column_with_default'
- end
-
- context 'for the change_column_type_concurrently method' do
- include_examples 'large tables', 'change_column_type_concurrently'
- end
-
- context 'for the rename_column_concurrently method' do
- include_examples 'large tables', 'rename_column_concurrently'
- end
-
- context 'for the update_column_in_batches method' do
- include_examples 'large tables', 'update_column_in_batches'
- end
-
- it 'registers no offense for non-blacklisted tables' do
- inspect_source("add_column_with_default :table, :column, default: true")
-
- expect(cop.offenses).to be_empty
- end
-
- it 'registers no offense for non-blacklisted methods' do
- table = described_class::BLACKLISTED_TABLES.sample
-
- inspect_source("some_other_method :#{table}, :column, default: true")
-
- expect(cop.offenses).to be_empty
- end
- end
-
- context 'outside of migration' do
- let(:table) { described_class::BLACKLISTED_TABLES.sample }
-
- it 'registers no offense for add_column_with_default' do
- inspect_source("add_column_with_default :#{table}, :column, default: true")
-
- expect(cop.offenses).to be_empty
- end
-
- it 'registers no offense for change_column_type_concurrently' do
- inspect_source("change_column_type_concurrently :#{table}, :column, default: true")
-
- expect(cop.offenses).to be_empty
- end
-
- it 'registers no offense for rename_column_concurrently' do
- inspect_source("rename_column_concurrently :#{table}, :column, default: true")
-
- expect(cop.offenses).to be_empty
- end
-
- it 'registers no offense for update_column_concurrently' do
- inspect_source("update_column_concurrently :#{table}, :column, default: true")
-
- expect(cop.offenses).to be_empty
- end
- end
-end
diff --git a/spec/rubocop/cop/performance/ar_count_each_spec.rb b/spec/rubocop/cop/performance/ar_count_each_spec.rb
index f934a1fde48..534fa55dd45 100644
--- a/spec/rubocop/cop/performance/ar_count_each_spec.rb
+++ b/spec/rubocop/cop/performance/ar_count_each_spec.rb
@@ -1,10 +1,9 @@
# frozen_string_literal: true
require 'fast_spec_helper'
-require_relative '../../../support/helpers/expect_offense'
require_relative '../../../../rubocop/cop/performance/ar_count_each.rb'
-describe RuboCop::Cop::Performance::ARCountEach do
+describe RuboCop::Cop::Performance::ARCountEach, type: :rubocop do
include CopHelper
include ExpectOffense
diff --git a/spec/rubocop/cop/performance/ar_exists_and_present_blank_spec.rb b/spec/rubocop/cop/performance/ar_exists_and_present_blank_spec.rb
index ce4fdac56b0..da44004f947 100644
--- a/spec/rubocop/cop/performance/ar_exists_and_present_blank_spec.rb
+++ b/spec/rubocop/cop/performance/ar_exists_and_present_blank_spec.rb
@@ -1,10 +1,9 @@
# frozen_string_literal: true
require 'fast_spec_helper'
-require_relative '../../../support/helpers/expect_offense'
require_relative '../../../../rubocop/cop/performance/ar_exists_and_present_blank.rb'
-describe RuboCop::Cop::Performance::ARExistsAndPresentBlank do
+describe RuboCop::Cop::Performance::ARExistsAndPresentBlank, type: :rubocop do
include CopHelper
include ExpectOffense
diff --git a/spec/rubocop/cop/performance/readlines_each_spec.rb b/spec/rubocop/cop/performance/readlines_each_spec.rb
index 5b3691e2342..e71aaaf3056 100644
--- a/spec/rubocop/cop/performance/readlines_each_spec.rb
+++ b/spec/rubocop/cop/performance/readlines_each_spec.rb
@@ -1,10 +1,9 @@
# frozen_string_literal: true
require 'fast_spec_helper'
-require_relative '../../../support/helpers/expect_offense'
require_relative '../../../../rubocop/cop/performance/readlines_each'
-describe RuboCop::Cop::Performance::ReadlinesEach do
+describe RuboCop::Cop::Performance::ReadlinesEach, type: :rubocop do
include CopHelper
include ExpectOffense
diff --git a/spec/rubocop/cop/put_group_routes_under_scope_spec.rb b/spec/rubocop/cop/put_group_routes_under_scope_spec.rb
index fc4d0015dde..c77412f91b4 100644
--- a/spec/rubocop/cop/put_group_routes_under_scope_spec.rb
+++ b/spec/rubocop/cop/put_group_routes_under_scope_spec.rb
@@ -14,7 +14,7 @@ describe RuboCop::Cop::PutGroupRoutesUnderScope do
end
it 'registers an offense when route is outside scope' do
- expect_offense(<<~PATTERN.strip_indent)
+ expect_offense(<<~PATTERN)
scope(path: 'groups/*group_id/-', module: :groups) do
resource :issues
end
@@ -25,7 +25,7 @@ describe RuboCop::Cop::PutGroupRoutesUnderScope do
end
it 'does not register an offense when resource inside the scope' do
- expect_no_offenses(<<~PATTERN.strip_indent)
+ expect_no_offenses(<<~PATTERN)
scope(path: 'groups/*group_id/-', module: :groups) do
resource :issues
resource :notes
@@ -34,7 +34,7 @@ describe RuboCop::Cop::PutGroupRoutesUnderScope do
end
it 'does not register an offense when resource is deep inside the scope' do
- expect_no_offenses(<<~PATTERN.strip_indent)
+ expect_no_offenses(<<~PATTERN)
scope(path: 'groups/*group_id/-', module: :groups) do
resource :issues
resource :projects do
diff --git a/spec/rubocop/cop/put_project_routes_under_scope_spec.rb b/spec/rubocop/cop/put_project_routes_under_scope_spec.rb
index b0f1e52f397..80ac4cc52e9 100644
--- a/spec/rubocop/cop/put_project_routes_under_scope_spec.rb
+++ b/spec/rubocop/cop/put_project_routes_under_scope_spec.rb
@@ -14,7 +14,7 @@ describe RuboCop::Cop::PutProjectRoutesUnderScope do
end
it 'registers an offense when route is outside scope' do
- expect_offense(<<~PATTERN.strip_indent)
+ expect_offense(<<~PATTERN)
scope '-' do
resource :issues
end
@@ -25,7 +25,7 @@ describe RuboCop::Cop::PutProjectRoutesUnderScope do
end
it 'does not register an offense when resource inside the scope' do
- expect_no_offenses(<<~PATTERN.strip_indent)
+ expect_no_offenses(<<~PATTERN)
scope '-' do
resource :issues
resource :notes
@@ -34,7 +34,7 @@ describe RuboCop::Cop::PutProjectRoutesUnderScope do
end
it 'does not register an offense when resource is deep inside the scope' do
- expect_no_offenses(<<~PATTERN.strip_indent)
+ expect_no_offenses(<<~PATTERN)
scope '-' do
resource :issues
resource :projects do
diff --git a/spec/rubocop/cop/rspec/empty_line_after_shared_example_spec.rb b/spec/rubocop/cop/rspec/empty_line_after_shared_example_spec.rb
deleted file mode 100644
index cee593fe535..00000000000
--- a/spec/rubocop/cop/rspec/empty_line_after_shared_example_spec.rb
+++ /dev/null
@@ -1,86 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-require_relative '../../../../rubocop/cop/rspec/empty_line_after_shared_example'
-
-describe RuboCop::Cop::RSpec::EmptyLineAfterSharedExample do
- subject(:cop) { described_class.new }
-
- it 'flags a missing empty line after `it_behaves_like` block' do
- expect_offense(<<-RUBY)
- RSpec.describe Foo do
- it_behaves_like 'does this' do
- end
- ^^^ Add an empty line after `it_behaves_like` block.
- it_behaves_like 'does that' do
- end
- end
- RUBY
-
- expect_correction(<<-RUBY)
- RSpec.describe Foo do
- it_behaves_like 'does this' do
- end
-
- it_behaves_like 'does that' do
- end
- end
- RUBY
- end
-
- it 'ignores one-line shared examples before shared example blocks' do
- expect_no_offenses(<<-RUBY)
- RSpec.describe Foo do
- it_behaves_like 'does this'
- it_behaves_like 'does that' do
- end
- end
- RUBY
- end
-
- it 'flags a missing empty line after `shared_examples`' do
- expect_offense(<<-RUBY)
- RSpec.context 'foo' do
- shared_examples do
- end
- ^^^ Add an empty line after `shared_examples` block.
- shared_examples 'something gets done' do
- end
- end
- RUBY
-
- expect_correction(<<-RUBY)
- RSpec.context 'foo' do
- shared_examples do
- end
-
- shared_examples 'something gets done' do
- end
- end
- RUBY
- end
-
- it 'ignores consecutive one-liners' do
- expect_no_offenses(<<-RUBY)
- RSpec.describe Foo do
- it_behaves_like 'do this'
- it_behaves_like 'do that'
- end
- RUBY
- end
-
- it 'flags mixed one-line and multi-line shared examples' do
- expect_offense(<<-RUBY)
- RSpec.context 'foo' do
- it_behaves_like 'do this'
- it_behaves_like 'do that'
- it_behaves_like 'does this' do
- end
- ^^^ Add an empty line after `it_behaves_like` block.
- it_behaves_like 'do this'
- it_behaves_like 'do that'
- end
- RUBY
- end
-end
diff --git a/spec/rubocop/cop/rspec/modify_sidekiq_middleware_spec.rb b/spec/rubocop/cop/rspec/modify_sidekiq_middleware_spec.rb
index 938916d8d75..d3d323b6643 100644
--- a/spec/rubocop/cop/rspec/modify_sidekiq_middleware_spec.rb
+++ b/spec/rubocop/cop/rspec/modify_sidekiq_middleware_spec.rb
@@ -2,10 +2,9 @@
require 'fast_spec_helper'
require 'rubocop'
-require_relative '../../../support/helpers/expect_offense'
require_relative '../../../../rubocop/cop/rspec/modify_sidekiq_middleware'
-describe RuboCop::Cop::RSpec::ModifySidekiqMiddleware do
+describe RuboCop::Cop::RSpec::ModifySidekiqMiddleware, type: :rubocop do
include CopHelper
include ExpectOffense
diff --git a/spec/rubocop/cop/rspec/top_level_describe_path_spec.rb b/spec/rubocop/cop/rspec/top_level_describe_path_spec.rb
index 258144d4000..ee6b6d39cb4 100644
--- a/spec/rubocop/cop/rspec/top_level_describe_path_spec.rb
+++ b/spec/rubocop/cop/rspec/top_level_describe_path_spec.rb
@@ -15,7 +15,7 @@ describe RuboCop::Cop::RSpec::TopLevelDescribePath do
context 'when the file ends in _spec.rb' do
it 'registers no offenses' do
- expect_no_offenses(<<~SOURCE.strip_indent, 'spec/foo_spec.rb')
+ expect_no_offenses(<<~SOURCE, 'spec/foo_spec.rb')
describe 'Foo' do
end
SOURCE
@@ -24,7 +24,7 @@ describe RuboCop::Cop::RSpec::TopLevelDescribePath do
context 'when the file is a frontend fixture' do
it 'registers no offenses' do
- expect_no_offenses(<<~SOURCE.strip_indent, 'spec/frontend/fixtures/foo.rb')
+ expect_no_offenses(<<~SOURCE, 'spec/frontend/fixtures/foo.rb')
describe 'Foo' do
end
SOURCE
@@ -34,7 +34,7 @@ describe RuboCop::Cop::RSpec::TopLevelDescribePath do
context 'when the describe is in a shared example' do
context 'with shared_examples' do
it 'registers no offenses' do
- expect_no_offenses(<<~SOURCE.strip_indent, 'spec/foo.rb')
+ expect_no_offenses(<<~SOURCE, 'spec/foo.rb')
shared_examples 'Foo' do
describe '#bar' do
end
@@ -45,7 +45,7 @@ describe RuboCop::Cop::RSpec::TopLevelDescribePath do
context 'with shared_examples_for' do
it 'registers no offenses' do
- expect_no_offenses(<<~SOURCE.strip_indent, 'spec/foo.rb')
+ expect_no_offenses(<<~SOURCE, 'spec/foo.rb')
shared_examples_for 'Foo' do
describe '#bar' do
end
@@ -57,7 +57,7 @@ describe RuboCop::Cop::RSpec::TopLevelDescribePath do
context 'when the describe is at the top level' do
it 'marks the describe as offending' do
- expect_offense(<<~SOURCE.strip_indent, 'spec/foo.rb')
+ expect_offense(<<~SOURCE, 'spec/foo.rb')
describe 'Foo' do
^^^^^^^^^^^^^^ #{described_class::MESSAGE}
end
diff --git a/spec/rubocop/cop/scalability/bulk_perform_with_context_spec.rb b/spec/rubocop/cop/scalability/bulk_perform_with_context_spec.rb
index 8107cfa8957..61603d0100e 100644
--- a/spec/rubocop/cop/scalability/bulk_perform_with_context_spec.rb
+++ b/spec/rubocop/cop/scalability/bulk_perform_with_context_spec.rb
@@ -2,17 +2,16 @@
require 'fast_spec_helper'
require 'rubocop'
-require_relative '../../../support/helpers/expect_offense'
require_relative '../../../../rubocop/cop/scalability/bulk_perform_with_context'
-describe RuboCop::Cop::Scalability::BulkPerformWithContext do
+describe RuboCop::Cop::Scalability::BulkPerformWithContext, type: :rubocop do
include CopHelper
include ExpectOffense
subject(:cop) { described_class.new }
it "adds an offense when calling bulk_perform_async" do
- inspect_source(<<~CODE.strip_indent)
+ inspect_source(<<~CODE)
Worker.bulk_perform_async(args)
CODE
@@ -20,7 +19,7 @@ describe RuboCop::Cop::Scalability::BulkPerformWithContext do
end
it "adds an offense when calling bulk_perform_in" do
- inspect_source(<<~CODE.strip_indent)
+ inspect_source(<<~CODE)
diffs.each_batch(of: BATCH_SIZE) do |relation, index|
ids = relation.pluck_primary_key.map { |id| [id] }
DeleteDiffFilesWorker.bulk_perform_in(index * 5.minutes, ids)
@@ -33,7 +32,7 @@ describe RuboCop::Cop::Scalability::BulkPerformWithContext do
it "does not add an offense for migrations" do
allow(cop).to receive(:in_migration?).and_return(true)
- inspect_source(<<~CODE.strip_indent)
+ inspect_source(<<~CODE)
Worker.bulk_perform_in(args)
CODE
@@ -43,7 +42,7 @@ describe RuboCop::Cop::Scalability::BulkPerformWithContext do
it "does not add an offence for specs" do
allow(cop).to receive(:in_spec?).and_return(true)
- inspect_source(<<~CODE.strip_indent)
+ inspect_source(<<~CODE)
Worker.bulk_perform_in(args)
CODE
@@ -51,7 +50,7 @@ describe RuboCop::Cop::Scalability::BulkPerformWithContext do
end
it "does not add an offense for scheduling BackgroundMigrations" do
- inspect_source(<<~CODE.strip_indent)
+ inspect_source(<<~CODE)
BackgroundMigrationWorker.bulk_perform_in(args)
CODE
diff --git a/spec/rubocop/cop/scalability/cron_worker_context_spec.rb b/spec/rubocop/cop/scalability/cron_worker_context_spec.rb
index 460514d9bed..e917d33b1e5 100644
--- a/spec/rubocop/cop/scalability/cron_worker_context_spec.rb
+++ b/spec/rubocop/cop/scalability/cron_worker_context_spec.rb
@@ -2,17 +2,16 @@
require 'fast_spec_helper'
require 'rubocop'
-require_relative '../../../support/helpers/expect_offense'
require_relative '../../../../rubocop/cop/scalability/cron_worker_context'
-describe RuboCop::Cop::Scalability::CronWorkerContext do
+describe RuboCop::Cop::Scalability::CronWorkerContext, type: :rubocop do
include CopHelper
include ExpectOffense
subject(:cop) { described_class.new }
it 'adds an offense when including CronjobQueue' do
- inspect_source(<<~CODE.strip_indent)
+ inspect_source(<<~CODE)
class SomeWorker
include CronjobQueue
end
@@ -22,14 +21,14 @@ describe RuboCop::Cop::Scalability::CronWorkerContext do
end
it 'does not add offenses for other workers' do
- expect_no_offenses(<<~CODE.strip_indent)
+ expect_no_offenses(<<~CODE)
class SomeWorker
end
CODE
end
it 'does not add an offense when the class defines a context' do
- expect_no_offenses(<<~CODE.strip_indent)
+ expect_no_offenses(<<~CODE)
class SomeWorker
include CronjobQueue
@@ -39,7 +38,7 @@ describe RuboCop::Cop::Scalability::CronWorkerContext do
end
it 'does not add an offense when the worker calls `with_context`' do
- expect_no_offenses(<<~CODE.strip_indent)
+ expect_no_offenses(<<~CODE)
class SomeWorker
include CronjobQueue
@@ -53,7 +52,7 @@ describe RuboCop::Cop::Scalability::CronWorkerContext do
end
it 'does not add an offense when the worker calls `bulk_perform_async_with_contexts`' do
- expect_no_offenses(<<~CODE.strip_indent)
+ expect_no_offenses(<<~CODE)
class SomeWorker
include CronjobQueue
@@ -67,7 +66,7 @@ describe RuboCop::Cop::Scalability::CronWorkerContext do
end
it 'does not add an offense when the worker calls `bulk_perform_in_with_contexts`' do
- expect_no_offenses(<<~CODE.strip_indent)
+ expect_no_offenses(<<~CODE)
class SomeWorker
include CronjobQueue
diff --git a/spec/rubocop/cop/scalability/file_uploads_spec.rb b/spec/rubocop/cop/scalability/file_uploads_spec.rb
index a35d423581c..b0be9ac2b51 100644
--- a/spec/rubocop/cop/scalability/file_uploads_spec.rb
+++ b/spec/rubocop/cop/scalability/file_uploads_spec.rb
@@ -2,10 +2,9 @@
require 'fast_spec_helper'
require 'rubocop'
-require_relative '../../../support/helpers/expect_offense'
require_relative '../../../../rubocop/cop/scalability/file_uploads'
-describe RuboCop::Cop::Scalability::FileUploads do
+describe RuboCop::Cop::Scalability::FileUploads, type: :rubocop do
include CopHelper
include ExpectOffense
@@ -15,7 +14,7 @@ describe RuboCop::Cop::Scalability::FileUploads do
context 'with required params' do
it 'detects File in types array' do
- expect_offense(<<~PATTERN.strip_indent)
+ expect_offense(<<~PATTERN)
params do
requires :certificate, allow_blank: false, types: [String, File]
^^^^ #{message}
@@ -24,7 +23,7 @@ describe RuboCop::Cop::Scalability::FileUploads do
end
it 'detects File as type argument' do
- expect_offense(<<~PATTERN.strip_indent)
+ expect_offense(<<~PATTERN)
params do
requires :attachment, type: File
^^^^ #{message}
@@ -35,7 +34,7 @@ describe RuboCop::Cop::Scalability::FileUploads do
context 'with optional params' do
it 'detects File in types array' do
- expect_offense(<<~PATTERN.strip_indent)
+ expect_offense(<<~PATTERN)
params do
optional :certificate, allow_blank: false, types: [String, File]
^^^^ #{message}
@@ -44,7 +43,7 @@ describe RuboCop::Cop::Scalability::FileUploads do
end
it 'detects File as type argument' do
- expect_offense(<<~PATTERN.strip_indent)
+ expect_offense(<<~PATTERN)
params do
optional :attachment, type: File
^^^^ #{message}
diff --git a/spec/rubocop/cop/scalability/idempotent_worker_spec.rb b/spec/rubocop/cop/scalability/idempotent_worker_spec.rb
index 7abd602f8bc..73cacc984e9 100644
--- a/spec/rubocop/cop/scalability/idempotent_worker_spec.rb
+++ b/spec/rubocop/cop/scalability/idempotent_worker_spec.rb
@@ -2,10 +2,9 @@
require 'fast_spec_helper'
require 'rubocop'
-require_relative '../../../support/helpers/expect_offense'
require_relative '../../../../rubocop/cop/scalability/idempotent_worker'
-describe RuboCop::Cop::Scalability::IdempotentWorker do
+describe RuboCop::Cop::Scalability::IdempotentWorker, type: :rubocop do
include CopHelper
include ExpectOffense
@@ -18,7 +17,7 @@ describe RuboCop::Cop::Scalability::IdempotentWorker do
end
it 'adds an offense when not defining idempotent method' do
- inspect_source(<<~CODE.strip_indent)
+ inspect_source(<<~CODE)
class SomeWorker
end
CODE
@@ -27,7 +26,7 @@ describe RuboCop::Cop::Scalability::IdempotentWorker do
end
it 'adds an offense when not defining idempotent method' do
- inspect_source(<<~CODE.strip_indent)
+ inspect_source(<<~CODE)
class SomeWorker
idempotent!
end
diff --git a/spec/serializers/build_artifact_entity_spec.rb b/spec/serializers/build_artifact_entity_spec.rb
index c8995cbc5a2..afa2aa3d254 100644
--- a/spec/serializers/build_artifact_entity_spec.rb
+++ b/spec/serializers/build_artifact_entity_spec.rb
@@ -3,17 +3,18 @@
require 'spec_helper'
describe BuildArtifactEntity do
- let(:job) { create(:ci_build, :artifacts, name: 'test:job', artifacts_expire_at: 1.hour.from_now) }
+ let(:job) { create(:ci_build) }
+ let(:artifact) { create(:ci_job_artifact, :codequality, expire_at: 1.hour.from_now, job: job) }
let(:entity) do
- described_class.new(job, request: double)
+ described_class.new(artifact, request: double)
end
describe '#as_json' do
subject { entity.as_json }
it 'contains job name' do
- expect(subject[:name]).to eq 'test:job'
+ expect(subject[:name]).to eq "test:codequality"
end
it 'exposes information about expiration of artifacts' do
@@ -22,7 +23,7 @@ describe BuildArtifactEntity do
it 'contains paths to the artifacts' do
expect(subject[:path])
- .to include "jobs/#{job.id}/artifacts/download"
+ .to include "jobs/#{job.id}/artifacts/download?file_type=codequality"
expect(subject[:keep_path])
.to include "jobs/#{job.id}/artifacts/keep"
diff --git a/spec/serializers/ci/dag_job_entity_spec.rb b/spec/serializers/ci/dag_job_entity_spec.rb
index 19b849c3879..eaaf39d6bfc 100644
--- a/spec/serializers/ci/dag_job_entity_spec.rb
+++ b/spec/serializers/ci/dag_job_entity_spec.rb
@@ -16,14 +16,23 @@ describe Ci::DagJobEntity do
end
context 'when job is stage scheduled' do
+ it 'contains the name scheduling_type' do
+ expect(subject[:scheduling_type]).to eq 'stage'
+ end
+
it 'does not expose needs' do
expect(subject).not_to include(:needs)
end
end
context 'when job is dag scheduled' do
+ let(:job) { create(:ci_build, scheduling_type: 'dag') }
+
+ it 'contains the name scheduling_type' do
+ expect(subject[:scheduling_type]).to eq 'dag'
+ end
+
context 'when job has needs' do
- let(:job) { create(:ci_build, scheduling_type: 'dag') }
let!(:need) { create(:ci_build_need, build: job, name: 'compile') }
it 'exposes the array of needs' do
@@ -32,8 +41,6 @@ describe Ci::DagJobEntity do
end
context 'when job has empty needs' do
- let(:job) { create(:ci_build, scheduling_type: 'dag') }
-
it 'exposes an empty array of needs' do
expect(subject[:needs]).to eq []
end
diff --git a/spec/serializers/ci/dag_pipeline_entity_spec.rb b/spec/serializers/ci/dag_pipeline_entity_spec.rb
index 4645451e146..fab8798effc 100644
--- a/spec/serializers/ci/dag_pipeline_entity_spec.rb
+++ b/spec/serializers/ci/dag_pipeline_entity_spec.rb
@@ -32,13 +32,14 @@ describe Ci::DagPipelineEntity do
end
end
- context 'when pipeline has parallel jobs and DAG needs' do
+ context 'when pipeline has parallel jobs, DAG needs and GenericCommitStatus' do
let!(:stage_build) { create(:ci_stage_entity, name: 'build', position: 1, pipeline: pipeline) }
let!(:stage_test) { create(:ci_stage_entity, name: 'test', position: 2, pipeline: pipeline) }
let!(:stage_deploy) { create(:ci_stage_entity, name: 'deploy', position: 3, pipeline: pipeline) }
- let!(:job_build_1) { create(:ci_build, name: 'build 1', stage: 'build', pipeline: pipeline) }
- let!(:job_build_2) { create(:ci_build, name: 'build 2', stage: 'build', pipeline: pipeline) }
+ let!(:job_build_1) { create(:ci_build, name: 'build 1', stage: 'build', pipeline: pipeline) }
+ let!(:job_build_2) { create(:ci_build, name: 'build 2', stage: 'build', pipeline: pipeline) }
+ let!(:commit_status) { create(:generic_commit_status, stage: 'build', pipeline: pipeline) }
let!(:job_rspec_1) { create(:ci_build, name: 'rspec 1/2', stage: 'test', pipeline: pipeline) }
let!(:job_rspec_2) { create(:ci_build, name: 'rspec 2/2', stage: 'test', pipeline: pipeline) }
@@ -75,22 +76,52 @@ describe Ci::DagPipelineEntity do
{
name: 'build',
groups: [
- { name: 'build 1', size: 1, jobs: [{ name: 'build 1' }] },
- { name: 'build 2', size: 1, jobs: [{ name: 'build 2' }] }
+ {
+ name: 'build 1', size: 1, jobs: [
+ { name: 'build 1', scheduling_type: 'stage' }
+ ]
+ },
+ {
+ name: 'build 2', size: 1, jobs: [
+ { name: 'build 2', scheduling_type: 'stage' }
+ ]
+ },
+ {
+ name: 'generic', size: 1, jobs: [
+ { name: 'generic', scheduling_type: nil }
+ ]
+ }
]
},
{
name: 'test',
groups: [
- { name: 'jest', size: 1, jobs: [{ name: 'jest', needs: ['build 1'] }] },
- { name: 'rspec', size: 2, jobs: [{ name: 'rspec 1/2' }, { name: 'rspec 2/2' }] }
+ {
+ name: 'jest', size: 1, jobs: [
+ { name: 'jest', scheduling_type: 'dag', needs: ['build 1'] }
+ ]
+ },
+ {
+ name: 'rspec', size: 2, jobs: [
+ { name: 'rspec 1/2', scheduling_type: 'stage' },
+ { name: 'rspec 2/2', scheduling_type: 'stage' }
+ ]
+ }
]
},
{
name: 'deploy',
groups: [
- { name: 'deploy_js', size: 1, jobs: [{ name: 'deploy_js', needs: ['jest'] }] },
- { name: 'deploy_ruby', size: 1, jobs: [{ name: 'deploy_ruby', needs: ['rspec 1/2', 'rspec 2/2'] }] }
+ {
+ name: 'deploy_js', size: 1, jobs: [
+ { name: 'deploy_js', scheduling_type: 'dag', needs: ['jest'] }
+ ]
+ },
+ {
+ name: 'deploy_ruby', size: 1, jobs: [
+ { name: 'deploy_ruby', scheduling_type: 'dag', needs: ['rspec 1/2', 'rspec 2/2'] }
+ ]
+ }
]
}
]
diff --git a/spec/serializers/ci/daily_build_group_report_result_entity_spec.rb b/spec/serializers/ci/daily_build_group_report_result_entity_spec.rb
new file mode 100644
index 00000000000..cc35b3bc8b8
--- /dev/null
+++ b/spec/serializers/ci/daily_build_group_report_result_entity_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Ci::DailyBuildGroupReportResultEntity do
+ let(:report_result) { double(date: '2020-05-20', group_name: 'rspec', data: { 'coverage' => 79.1 }) }
+ let(:entity) { described_class.new(report_result, param_type: param_type) }
+ let(:param_type) { 'coverage' }
+
+ describe '#as_json' do
+ subject { entity.as_json }
+
+ it { is_expected.to include(:date) }
+
+ it { is_expected.not_to include(:group_name) }
+
+ it { is_expected.to include(:coverage) }
+
+ context 'when given param_type is not allowed' do
+ let(:param_type) { 'something_else' }
+
+ it { is_expected.not_to include(:coverage) }
+ it { is_expected.not_to include(:something_else) }
+ end
+ end
+end
diff --git a/spec/serializers/ci/daily_build_group_report_result_serializer_spec.rb b/spec/serializers/ci/daily_build_group_report_result_serializer_spec.rb
new file mode 100644
index 00000000000..4a781971ae0
--- /dev/null
+++ b/spec/serializers/ci/daily_build_group_report_result_serializer_spec.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Ci::DailyBuildGroupReportResultSerializer do
+ let(:report_result) do
+ [
+ double(date: '2020-05-20', group_name: 'rspec', data: { 'coverage' => 79.1 }),
+ double(date: '2020-05-20', group_name: 'karma', data: { 'coverage' => 90.1 }),
+ double(date: '2020-05-19', group_name: 'rspec', data: { 'coverage' => 77.1 }),
+ double(date: '2020-05-19', group_name: 'karma', data: { 'coverage' => 89.1 })
+ ]
+ end
+ let(:serializer) { described_class.new.represent(report_result, param_type: 'coverage') }
+
+ describe '#to_json' do
+ let(:json) { Gitlab::Json.parse(serializer.to_json) }
+
+ it 'returns an array of group results' do
+ expect(json).to eq([
+ {
+ 'group_name' => 'rspec',
+ 'data' => [
+ { 'date' => '2020-05-20', 'coverage' => 79.1 },
+ { 'date' => '2020-05-19', 'coverage' => 77.1 }
+ ]
+ },
+ {
+ 'group_name' => 'karma',
+ 'data' => [
+ { 'date' => '2020-05-20', 'coverage' => 90.1 },
+ { 'date' => '2020-05-19', 'coverage' => 89.1 }
+ ]
+ }
+ ])
+ end
+ end
+end
diff --git a/spec/serializers/cluster_serializer_spec.rb b/spec/serializers/cluster_serializer_spec.rb
index 39551649ff0..b7d7307d40b 100644
--- a/spec/serializers/cluster_serializer_spec.rb
+++ b/spec/serializers/cluster_serializer_spec.rb
@@ -16,6 +16,7 @@ describe ClusterSerializer do
:name,
:nodes,
:path,
+ :provider_type,
:status)
end
end
diff --git a/spec/serializers/commit_entity_spec.rb b/spec/serializers/commit_entity_spec.rb
index 03e1c89a5e6..6abe8504b93 100644
--- a/spec/serializers/commit_entity_spec.rb
+++ b/spec/serializers/commit_entity_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe CommitEntity do
- SIGNATURE_HTML = 'TEST'.freeze
+ let(:signature_html) { 'TEST' }
let(:entity) do
described_class.new(commit, request: request)
@@ -16,7 +16,7 @@ describe CommitEntity do
before do
render = double('render')
- allow(render).to receive(:call).and_return(SIGNATURE_HTML)
+ allow(render).to receive(:call).and_return(signature_html)
allow(request).to receive(:project).and_return(project)
allow(request).to receive(:render).and_return(render)
@@ -83,7 +83,7 @@ describe CommitEntity do
it 'exposes "signature_html"' do
expect(request.render).to receive(:call)
- expect(subject.fetch(:signature_html)).to be SIGNATURE_HTML
+ expect(subject.fetch(:signature_html)).to be signature_html
end
end
diff --git a/spec/serializers/container_repository_entity_spec.rb b/spec/serializers/container_repository_entity_spec.rb
index 96c80331f41..1f85c6e6a46 100644
--- a/spec/serializers/container_repository_entity_spec.rb
+++ b/spec/serializers/container_repository_entity_spec.rb
@@ -13,12 +13,14 @@ describe ContainerRepositoryEntity do
before do
stub_container_registry_config(enabled: true)
+ stub_container_registry_tags(repository: :any,
+ tags: %w[stable latest])
allow(request).to receive(:project).and_return(project)
allow(request).to receive(:current_user).and_return(user)
end
it 'exposes required informations' do
- expect(subject).to include(:id, :path, :location, :tags_path)
+ expect(subject).to include(:id, :path, :location, :tags_path, :tags_count)
end
context 'when project is not preset in the request' do
diff --git a/spec/serializers/diffs_entity_spec.rb b/spec/serializers/diffs_entity_spec.rb
index 482f9e76c62..435d8a6aff2 100644
--- a/spec/serializers/diffs_entity_spec.rb
+++ b/spec/serializers/diffs_entity_spec.rb
@@ -68,5 +68,15 @@ describe DiffsEntity do
end
end
end
+
+ context 'when code_navigation feature flag is disabled' do
+ it 'does not include code navigation properties' do
+ stub_feature_flags(code_navigation: false)
+
+ expect(Gitlab::CodeNavigationPath).not_to receive(:new)
+
+ expect(subject).not_to include(:definition_path_prefix)
+ end
+ end
end
end
diff --git a/spec/serializers/evidences/evidence_entity_spec.rb b/spec/serializers/evidences/evidence_entity_spec.rb
index 531708e3be6..fa13bd21edd 100644
--- a/spec/serializers/evidences/evidence_entity_spec.rb
+++ b/spec/serializers/evidences/evidence_entity_spec.rb
@@ -3,12 +3,66 @@
require 'spec_helper'
describe Evidences::EvidenceEntity do
- let(:evidence) { build(:evidence) }
- let(:entity) { described_class.new(evidence) }
+ let_it_be(:project) { create(:project) }
+ let(:release) { create(:release, project: project) }
+ let(:evidence) { build(:evidence, release: release) }
+ let(:schema_file) { 'evidences/evidence' }
- subject { entity.as_json }
+ subject { described_class.new(evidence).as_json }
it 'exposes the expected fields' do
expect(subject.keys).to contain_exactly(:release)
end
+
+ context 'when a release is associated to a milestone' do
+ let(:milestone) { create(:milestone, project: project) }
+ let(:release) { create(:release, project: project, milestones: [milestone]) }
+
+ context 'when a milestone has no issue associated with it' do
+ it 'creates a valid JSON object' do
+ expect(subject[:release][:milestones].first[:issues]).to be_empty
+ expect(subject.to_json).to match_schema(schema_file)
+ end
+ end
+
+ context 'when a milestone has no description' do
+ let(:milestone) { create(:milestone, project: project, description: nil) }
+
+ it 'creates a valid JSON object' do
+ expect(subject[:release][:milestones].first[:description]).to be_nil
+ expect(subject.to_json).to match_schema(schema_file)
+ end
+ end
+
+ context 'when a milestone has no due_date' do
+ let(:milestone) { create(:milestone, project: project, due_date: nil) }
+
+ it 'creates a valid JSON object' do
+ expect(subject[:release][:milestones].first[:due_date]).to be_nil
+ expect(subject.to_json).to match_schema(schema_file)
+ end
+ end
+
+ context 'when a milestone has an issue' do
+ context 'when the issue has no description' do
+ let(:issue) { create(:issue, project: project, description: nil, state: 'closed') }
+
+ before do
+ milestone.issues << issue
+ end
+
+ it 'creates a valid JSON object' do
+ expect(subject[:release][:milestones].first[:issues].first[:title]).to be_present
+ expect(subject.to_json).to match_schema(schema_file)
+ end
+ end
+ end
+ end
+
+ context 'when a release is not associated to any milestone' do
+ it 'creates a valid JSON object' do
+ expect(subject[:release][:milestones]).to be_empty
+ expect(subject.to_json).to match_schema(schema_file)
+ end
+ end
end
diff --git a/spec/serializers/import/bitbucket_provider_repo_entity_spec.rb b/spec/serializers/import/bitbucket_provider_repo_entity_spec.rb
new file mode 100644
index 00000000000..ed3ef26db65
--- /dev/null
+++ b/spec/serializers/import/bitbucket_provider_repo_entity_spec.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Import::BitbucketProviderRepoEntity do
+ let(:repo_data) do
+ {
+ 'name' => 'repo_name',
+ 'full_name' => 'owner/repo_name',
+ 'links' => {
+ 'clone' => [
+ {
+ 'href' => 'https://bitbucket.org/owner/repo_name',
+ 'name' => 'https'
+ }
+ ]
+ }
+ }
+ end
+ let(:repo) { Bitbucket::Representation::Repo.new(repo_data) }
+
+ subject { described_class.new(repo).as_json }
+
+ it_behaves_like 'exposes required fields for import entity' do
+ let(:expected_values) do
+ {
+ id: 'owner/repo_name',
+ full_name: 'owner/repo_name',
+ sanitized_name: 'repo_name',
+ provider_link: 'https://bitbucket.org/owner/repo_name'
+ }
+ end
+ end
+end
diff --git a/spec/serializers/import/bitbucket_server_provider_repo_entity_spec.rb b/spec/serializers/import/bitbucket_server_provider_repo_entity_spec.rb
new file mode 100644
index 00000000000..9891809cc67
--- /dev/null
+++ b/spec/serializers/import/bitbucket_server_provider_repo_entity_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Import::BitbucketServerProviderRepoEntity do
+ let(:repo_data) do
+ {
+ 'name' => 'test',
+ 'project' => {
+ 'name' => 'demo'
+ },
+ 'links' => {
+ 'self' => [
+ {
+ 'href' => 'http://local.bitbucket.server/demo/test.git',
+ 'name' => 'http'
+ }
+ ]
+ }
+ }
+ end
+ let(:repo) { BitbucketServer::Representation::Repo.new(repo_data) }
+
+ subject { described_class.new(repo).as_json }
+
+ it_behaves_like 'exposes required fields for import entity' do
+ let(:expected_values) do
+ {
+ id: 'demo/test',
+ full_name: 'demo/test',
+ sanitized_name: 'test',
+ provider_link: 'http://local.bitbucket.server/demo/test.git'
+ }
+ end
+ end
+end
diff --git a/spec/serializers/import/fogbugz_provider_repo_entity_spec.rb b/spec/serializers/import/fogbugz_provider_repo_entity_spec.rb
new file mode 100644
index 00000000000..b9029b67aab
--- /dev/null
+++ b/spec/serializers/import/fogbugz_provider_repo_entity_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Import::FogbugzProviderRepoEntity do
+ let(:provider_url) { 'https://demo.fogbugz.com/' }
+ let(:repo_data) do
+ {
+ 'ixProject' => 'foo',
+ 'sProject' => 'demo'
+ }
+ end
+ let(:repo) { Gitlab::FogbugzImport::Repository.new(repo_data) }
+
+ subject { described_class.represent(repo, { provider_url: provider_url }).as_json }
+
+ it_behaves_like 'exposes required fields for import entity' do
+ let(:expected_values) do
+ {
+ id: 'foo',
+ full_name: 'demo',
+ sanitized_name: 'demo',
+ provider_link: 'https://demo.fogbugz.com/demo'
+ }
+ end
+ end
+end
diff --git a/spec/serializers/import/githubish_provider_repo_entity_spec.rb b/spec/serializers/import/githubish_provider_repo_entity_spec.rb
new file mode 100644
index 00000000000..c6a07b2d64a
--- /dev/null
+++ b/spec/serializers/import/githubish_provider_repo_entity_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Import::GithubishProviderRepoEntity do
+ let(:provider_url) { 'https://github.com/' }
+ let(:repo) do
+ {
+ id: 1,
+ full_name: 'full/name',
+ name: 'name'
+ }
+ end
+
+ subject { described_class.represent(repo, { provider_url: provider_url }).as_json }
+
+ it_behaves_like 'exposes required fields for import entity' do
+ let(:expected_values) do
+ {
+ id: 1,
+ full_name: 'full/name',
+ sanitized_name: 'name',
+ provider_link: 'https://github.com/full/name'
+ }
+ end
+ end
+end
diff --git a/spec/serializers/import/gitlab_provider_repo_entity_spec.rb b/spec/serializers/import/gitlab_provider_repo_entity_spec.rb
new file mode 100644
index 00000000000..3f862c16fe2
--- /dev/null
+++ b/spec/serializers/import/gitlab_provider_repo_entity_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Import::GitlabProviderRepoEntity do
+ let(:repo_data) do
+ {
+ 'id' => 1,
+ 'path_with_namespace' => 'demo/test',
+ 'path' => 'test',
+ 'web_url' => 'https://gitlab.com/demo/test'
+ }
+ end
+
+ subject { described_class.new(repo_data).as_json }
+
+ it_behaves_like 'exposes required fields for import entity' do
+ let(:expected_values) do
+ {
+ id: 1,
+ full_name: 'demo/test',
+ sanitized_name: 'test',
+ provider_link: 'https://gitlab.com/demo/test'
+ }
+ end
+ end
+end
diff --git a/spec/serializers/import/provider_repo_serializer_spec.rb b/spec/serializers/import/provider_repo_serializer_spec.rb
new file mode 100644
index 00000000000..9bf55e6c65d
--- /dev/null
+++ b/spec/serializers/import/provider_repo_serializer_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Import::ProviderRepoSerializer do
+ using RSpec::Parameterized::TableSyntax
+
+ describe '#represent' do
+ where(:provider, :class_name) do
+ :github | 'Import::GithubishProviderRepoEntity'
+ :gitea | 'Import::GithubishProviderRepoEntity'
+ :bitbucket | 'Import::BitbucketProviderRepoEntity'
+ :bitbucket_server | 'Import::BitbucketServerProviderRepoEntity'
+ :fogbugz | 'Import::FogbugzProviderRepoEntity'
+ end
+
+ with_them do
+ it 'uses correct entity class' do
+ opts = { provider: provider }
+ expect(class_name.constantize).to receive(:represent)
+ described_class.new.represent({}, opts)
+ end
+ end
+
+ it 'raises an error if invalid provider supplied' do
+ expect { described_class.new.represent({}, { provider: :invalid })}.to raise_error { NotImplementedError }
+ end
+ end
+end
diff --git a/spec/serializers/merge_request_widget_entity_spec.rb b/spec/serializers/merge_request_widget_entity_spec.rb
index 40a0f09d1f3..039fb311bfc 100644
--- a/spec/serializers/merge_request_widget_entity_spec.rb
+++ b/spec/serializers/merge_request_widget_entity_spec.rb
@@ -178,7 +178,7 @@ describe MergeRequestWidgetEntity do
project.add_maintainer(user)
expect(subject[:new_project_pipeline_path])
- .to eq("/#{resource.project.full_path}/pipelines/new")
+ .to eq("/#{resource.project.full_path}/-/pipelines/new")
end
describe 'when source project is deleted' do
diff --git a/spec/serializers/paginated_diff_entity_spec.rb b/spec/serializers/paginated_diff_entity_spec.rb
index 77569aaa4bc..a6b83cb4286 100644
--- a/spec/serializers/paginated_diff_entity_spec.rb
+++ b/spec/serializers/paginated_diff_entity_spec.rb
@@ -30,4 +30,14 @@ describe PaginatedDiffEntity do
total_pages: 7
)
end
+
+ context 'when code_navigation feature flag is disabled' do
+ it 'does not execute Gitlab::CodeNavigationPath' do
+ stub_feature_flags(code_navigation: false)
+
+ expect(Gitlab::CodeNavigationPath).not_to receive(:new)
+
+ subject
+ end
+ end
end
diff --git a/spec/serializers/pipeline_details_entity_spec.rb b/spec/serializers/pipeline_details_entity_spec.rb
index a154bcac635..849dab102c2 100644
--- a/spec/serializers/pipeline_details_entity_spec.rb
+++ b/spec/serializers/pipeline_details_entity_spec.rb
@@ -173,44 +173,5 @@ describe PipelineDetailsEntity do
expect(subject[:triggered].first[:project]).not_to be_nil
end
end
-
- context 'when pipeline has expiring archive artifacts' do
- let(:pipeline) { create(:ci_empty_pipeline) }
- let!(:build_1) { create(:ci_build, :artifacts, pipeline: pipeline, artifacts_expire_at: 2.days.from_now, name: 'build_1') }
- let!(:build_2) { create(:ci_build, :artifacts, pipeline: pipeline, artifacts_expire_at: 2.days.from_now, name: 'build_2') }
- let!(:build_3) { create(:ci_build, :artifacts, pipeline: pipeline, artifacts_expire_at: 2.days.from_now, name: 'build_3') }
-
- let(:names) { subject[:details][:artifacts].map { |a| a[:name] } }
-
- context 'and preload_job_artifacts_archive is not defined in the options' do
- it 'defaults to true and eager loads the job_artifacts_archive' do
- recorder = ActiveRecord::QueryRecorder.new do
- expect(names).to match_array(%w[build_1 build_2 build_3])
- end
-
- expected_queries = Gitlab.ee? ? 42 : 29
-
- # This makes only one query to fetch all job artifacts
- expect(recorder.count).to eq(expected_queries)
- end
- end
-
- context 'and preload_job_artifacts_archive is set to false' do
- let(:entity) do
- described_class.represent(pipeline, request: request, preload_job_artifacts_archive: false)
- end
-
- it 'does not eager load the job_artifacts_archive' do
- recorder = ActiveRecord::QueryRecorder.new do
- expect(names).to match_array(%w[build_1 build_2 build_3])
- end
-
- expected_queries = Gitlab.ee? ? 44 : 31
-
- # This makes one query for each job artifact
- expect(recorder.count).to eq(expected_queries)
- end
- end
- end
end
end
diff --git a/spec/serializers/pipeline_serializer_spec.rb b/spec/serializers/pipeline_serializer_spec.rb
index 4e4cc9c35e6..c8f25423f85 100644
--- a/spec/serializers/pipeline_serializer_spec.rb
+++ b/spec/serializers/pipeline_serializer_spec.rb
@@ -10,10 +10,6 @@ describe PipelineSerializer do
described_class.new(current_user: user, project: project)
end
- before do
- stub_feature_flags(ci_pipeline_persisted_stages: true)
- end
-
subject { serializer.represent(resource) }
describe '#represent' do
diff --git a/spec/serializers/provider_repo_entity_spec.rb b/spec/serializers/provider_repo_entity_spec.rb
deleted file mode 100644
index 9a1160d16d5..00000000000
--- a/spec/serializers/provider_repo_entity_spec.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe ProviderRepoEntity do
- include ImportHelper
-
- let(:provider_repo) { { id: 1, full_name: 'full/name', name: 'name', owner: { login: 'owner' } } }
- let(:provider) { :github }
- let(:provider_url) { 'https://github.com' }
- let(:entity) { described_class.represent(provider_repo, provider: provider, provider_url: provider_url) }
-
- describe '#as_json' do
- subject { entity.as_json }
-
- it 'includes required fields' do
- expect(subject[:id]).to eq(provider_repo[:id])
- expect(subject[:full_name]).to eq(provider_repo[:full_name])
- expect(subject[:owner_name]).to eq(provider_repo[:owner][:login])
- expect(subject[:sanitized_name]).to eq(sanitize_project_name(provider_repo[:name]))
- expect(subject[:provider_link]).to eq(provider_project_link_url(provider_url, provider_repo[:full_name]))
- end
- end
-end
diff --git a/spec/serializers/provider_repo_serializer_spec.rb b/spec/serializers/provider_repo_serializer_spec.rb
deleted file mode 100644
index f2be30c36d9..00000000000
--- a/spec/serializers/provider_repo_serializer_spec.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe ProviderRepoSerializer do
- it 'represents ProviderRepoEntity entities' do
- expect(described_class.entity_class).to eq(ProviderRepoEntity)
- end
-end
diff --git a/spec/serializers/service_field_entity_spec.rb b/spec/serializers/service_field_entity_spec.rb
new file mode 100644
index 00000000000..277890d143a
--- /dev/null
+++ b/spec/serializers/service_field_entity_spec.rb
@@ -0,0 +1,99 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe ServiceFieldEntity do
+ let(:request) { double('request') }
+
+ subject { described_class.new(field, request: request, service: service).as_json }
+
+ before do
+ allow(request).to receive(:service).and_return(service)
+ end
+
+ describe '#as_json' do
+ context 'Jira Service' do
+ let(:service) { create(:jira_service) }
+
+ context 'field with type text' do
+ let(:field) { service.global_fields.find { |field| field[:name] == 'username' } }
+
+ it 'exposes correct attributes' do
+ expected_hash = {
+ type: 'text',
+ name: 'username',
+ title: 'Username or Email',
+ placeholder: 'Use a username for server version and an email for cloud version',
+ required: true,
+ choices: nil,
+ help: nil,
+ value: 'jira_username'
+ }
+
+ is_expected.to eq(expected_hash)
+ end
+ end
+
+ context 'field with type password' do
+ let(:field) { service.global_fields.find { |field| field[:name] == 'password' } }
+
+ it 'exposes correct attributes but hides password' do
+ expected_hash = {
+ type: 'password',
+ name: 'password',
+ title: 'Password or API token',
+ placeholder: 'Use a password for server version and an API token for cloud version',
+ required: true,
+ choices: nil,
+ help: nil,
+ value: 'true'
+ }
+
+ is_expected.to eq(expected_hash)
+ end
+ end
+ end
+
+ context 'EmailsOnPush Service' do
+ let(:service) { create(:emails_on_push_service) }
+
+ context 'field with type checkbox' do
+ let(:field) { service.global_fields.find { |field| field[:name] == 'send_from_committer_email' } }
+
+ it 'exposes correct attributes' do
+ expected_hash = {
+ type: 'checkbox',
+ name: 'send_from_committer_email',
+ title: 'Send from committer',
+ placeholder: nil,
+ required: nil,
+ choices: nil,
+ value: true
+ }
+
+ is_expected.to include(expected_hash)
+ expect(subject[:help]).to include("Send notifications from the committer's email address if the domain is part of the domain GitLab is running on")
+ end
+ end
+
+ context 'field with type select' do
+ let(:field) { service.global_fields.find { |field| field[:name] == 'branches_to_be_notified' } }
+
+ it 'exposes correct attributes' do
+ expected_hash = {
+ type: 'select',
+ name: 'branches_to_be_notified',
+ title: nil,
+ placeholder: nil,
+ required: nil,
+ choices: [['All branches', 'all'], ['Default branch', 'default'], ['Protected branches', 'protected'], ['Default branch and protected branches', 'default_and_protected']],
+ help: nil,
+ value: nil
+ }
+
+ is_expected.to eq(expected_hash)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/serializers/web_ide_terminal_entity_spec.rb b/spec/serializers/web_ide_terminal_entity_spec.rb
new file mode 100644
index 00000000000..e163afa14ed
--- /dev/null
+++ b/spec/serializers/web_ide_terminal_entity_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe WebIdeTerminalEntity do
+ let(:build) { create(:ci_build) }
+ let(:entity) { described_class.new(WebIdeTerminal.new(build)) }
+
+ subject { entity.as_json }
+
+ it { is_expected.to have_key(:id) }
+ it { is_expected.to have_key(:status) }
+ it { is_expected.to have_key(:show_path) }
+ it { is_expected.to have_key(:cancel_path) }
+ it { is_expected.to have_key(:retry_path) }
+ it { is_expected.to have_key(:terminal_path) }
+ it { is_expected.to have_key(:services) }
+ it { is_expected.to have_key(:proxy_websocket_path) }
+
+ context 'when feature flag build_service_proxy is disabled' do
+ before do
+ stub_feature_flags(build_service_proxy: false)
+ end
+
+ it { is_expected.not_to have_key(:proxy_websocket_path) }
+ end
+end
diff --git a/spec/serializers/web_ide_terminal_serializer_spec.rb b/spec/serializers/web_ide_terminal_serializer_spec.rb
new file mode 100644
index 00000000000..01133deaf84
--- /dev/null
+++ b/spec/serializers/web_ide_terminal_serializer_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe WebIdeTerminalSerializer do
+ let(:build) { create(:ci_build) }
+
+ subject { described_class.new.represent(WebIdeTerminal.new(build)) }
+
+ it 'represents WebIdeTerminalEntity entities' do
+ expect(described_class.entity_class).to eq(WebIdeTerminalEntity)
+ end
+
+ it 'accepts WebIdeTerminal as a resource' do
+ expect(subject[:id]).to eq build.id
+ end
+
+ context 'when resource is a build' do
+ subject { described_class.new.represent(build) }
+
+ it 'transforms it into a WebIdeTerminal resource' do
+ expect(WebIdeTerminal).to receive(:new)
+
+ subject
+ end
+ end
+end
diff --git a/spec/services/admin/propagate_integration_service_spec.rb b/spec/services/admin/propagate_integration_service_spec.rb
new file mode 100644
index 00000000000..843b78a41e9
--- /dev/null
+++ b/spec/services/admin/propagate_integration_service_spec.rb
@@ -0,0 +1,149 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Admin::PropagateIntegrationService do
+ describe '.propagate' do
+ let(:excluded_attributes) { %w[id project_id inherit_from_id instance created_at updated_at title description] }
+ let!(:project) { create(:project) }
+ let!(:instance_integration) do
+ JiraService.create!(
+ instance: true,
+ active: true,
+ push_events: true,
+ url: 'http://update-jira.instance.com',
+ username: 'user',
+ password: 'secret'
+ )
+ end
+
+ let!(:inherited_integration) do
+ JiraService.create!(
+ project: create(:project),
+ inherit_from_id: instance_integration.id,
+ instance: false,
+ active: true,
+ push_events: false,
+ url: 'http://jira.instance.com',
+ username: 'user',
+ password: 'secret'
+ )
+ end
+
+ let!(:not_inherited_integration) do
+ JiraService.create!(
+ project: create(:project),
+ inherit_from_id: nil,
+ instance: false,
+ active: true,
+ push_events: false,
+ url: 'http://jira.instance.com',
+ username: 'user',
+ password: 'secret'
+ )
+ end
+
+ let!(:another_inherited_integration) do
+ BambooService.create!(
+ project: create(:project),
+ inherit_from_id: instance_integration.id,
+ instance: false,
+ active: true,
+ push_events: false,
+ bamboo_url: 'http://gitlab.com',
+ username: 'mic',
+ password: 'password',
+ build_key: 'build'
+ )
+ end
+
+ shared_examples 'inherits settings from integration' do
+ it 'updates the inherited integrations' do
+ described_class.propagate(integration: instance_integration, overwrite: overwrite)
+
+ expect(integration.reload.inherit_from_id).to eq(instance_integration.id)
+ expect(integration.attributes.except(*excluded_attributes))
+ .to eq(instance_integration.attributes.except(*excluded_attributes))
+ end
+
+ context 'integration with data fields' do
+ let(:excluded_attributes) { %w[id service_id created_at updated_at] }
+
+ it 'updates the data fields from inherited integrations' do
+ described_class.propagate(integration: instance_integration, overwrite: overwrite)
+
+ expect(integration.reload.data_fields.attributes.except(*excluded_attributes))
+ .to eq(instance_integration.data_fields.attributes.except(*excluded_attributes))
+ end
+ end
+ end
+
+ shared_examples 'does not inherit settings from integration' do
+ it 'does not update the not inherited integrations' do
+ described_class.propagate(integration: instance_integration, overwrite: overwrite)
+
+ expect(integration.reload.attributes.except(*excluded_attributes))
+ .not_to eq(instance_integration.attributes.except(*excluded_attributes))
+ end
+ end
+
+ context 'update only inherited integrations' do
+ let(:overwrite) { false }
+
+ it_behaves_like 'inherits settings from integration' do
+ let(:integration) { inherited_integration }
+ end
+
+ it_behaves_like 'does not inherit settings from integration' do
+ let(:integration) { not_inherited_integration }
+ end
+
+ it_behaves_like 'does not inherit settings from integration' do
+ let(:integration) { another_inherited_integration }
+ end
+
+ it_behaves_like 'inherits settings from integration' do
+ let(:integration) { project.jira_service }
+ end
+ end
+
+ context 'update all integrations' do
+ let(:overwrite) { true }
+
+ it_behaves_like 'inherits settings from integration' do
+ let(:integration) { inherited_integration }
+ end
+
+ it_behaves_like 'inherits settings from integration' do
+ let(:integration) { not_inherited_integration }
+ end
+
+ it_behaves_like 'does not inherit settings from integration' do
+ let(:integration) { another_inherited_integration }
+ end
+
+ it_behaves_like 'inherits settings from integration' do
+ let(:integration) { project.jira_service }
+ end
+ end
+
+ it 'updates project#has_external_issue_tracker for issue tracker services' do
+ described_class.propagate(integration: instance_integration, overwrite: true)
+
+ expect(project.reload.has_external_issue_tracker).to eq(true)
+ end
+
+ it 'updates project#has_external_wiki for external wiki services' do
+ instance_integration = ExternalWikiService.create!(
+ instance: true,
+ active: true,
+ push_events: false,
+ external_wiki_url: 'http://external-wiki-url.com'
+ )
+
+ described_class.propagate(integration: instance_integration, overwrite: true)
+
+ expect(project.reload.has_external_wiki).to eq(true)
+ end
+ end
+end
diff --git a/spec/services/alert_management/alerts/update_service_spec.rb b/spec/services/alert_management/alerts/update_service_spec.rb
new file mode 100644
index 00000000000..e185e67c5cf
--- /dev/null
+++ b/spec/services/alert_management/alerts/update_service_spec.rb
@@ -0,0 +1,134 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe AlertManagement::Alerts::UpdateService do
+ let_it_be(:user_with_permissions) { create(:user) }
+ let_it_be(:user_without_permissions) { create(:user) }
+ let_it_be(:alert, reload: true) { create(:alert_management_alert) }
+ let_it_be(:project) { alert.project }
+
+ let(:current_user) { user_with_permissions }
+ let(:params) { {} }
+
+ let(:service) { described_class.new(alert, current_user, params) }
+
+ before_all do
+ project.add_developer(user_with_permissions)
+ end
+
+ describe '#execute' do
+ subject(:response) { service.execute }
+
+ context 'when the current_user is nil' do
+ let(:current_user) { nil }
+
+ it 'results in an error' do
+ expect(response).to be_error
+ expect(response.message).to eq('You have no permissions')
+ end
+ end
+
+ context 'when user does not have permission to update alerts' do
+ let(:current_user) { user_without_permissions }
+
+ it 'results in an error' do
+ expect(response).to be_error
+ expect(response.message).to eq('You have no permissions')
+ end
+ end
+
+ context 'when no parameters are included' do
+ it 'results in an error' do
+ expect(response).to be_error
+ expect(response.message).to eq('Please provide attributes to update')
+ end
+ end
+
+ context 'when an error occures during update' do
+ let(:params) { { title: nil } }
+
+ it 'results in an error' do
+ expect { response }.not_to change { alert.reload.notes.count }
+ expect(response).to be_error
+ expect(response.message).to eq("Title can't be blank")
+ end
+ end
+
+ context 'when a model attribute is included without assignees' do
+ let(:params) { { title: 'This is an updated alert.' } }
+
+ it 'updates the attribute' do
+ original_title = alert.title
+
+ expect { response }.to change { alert.title }.from(original_title).to(params[:title])
+ expect(response).to be_success
+ end
+
+ it 'skips adding a todo' do
+ expect { response }.not_to change(Todo, :count)
+ end
+ end
+
+ context 'when assignees are included' do
+ let(:params) { { assignees: [user_with_permissions] } }
+
+ after do
+ alert.assignees = []
+ end
+
+ it 'assigns the user' do
+ expect { response }.to change { alert.reload.assignees }.from([]).to(params[:assignees])
+ expect(response).to be_success
+ end
+
+ it 'creates a system note for the assignment' do
+ expect { response }.to change { alert.reload.notes.count }.by(1)
+ end
+
+ it 'adds a todo' do
+ expect { response }.to change { Todo.where(user: user_with_permissions).count }.by(1)
+ end
+
+ context 'when current user is not the assignee' do
+ let(:assignee_user) { create(:user) }
+ let(:params) { { assignees: [assignee_user] } }
+
+ it 'skips adding todo for assignee without permission to read alert' do
+ expect { response }.not_to change(Todo, :count)
+ end
+
+ context 'when assignee has read permission' do
+ before do
+ project.add_developer(assignee_user)
+ end
+
+ it 'adds a todo' do
+ response
+
+ expect(Todo.first.author).to eq(current_user)
+ end
+ end
+
+ context 'when current_user is nil' do
+ let(:current_user) { nil }
+
+ it 'skips adding todo if current_user is nil' do
+ project.add_developer(assignee_user)
+
+ expect { response }.not_to change(Todo, :count)
+ end
+ end
+ end
+
+ context 'with multiple users included' do
+ let(:params) { { assignees: [user_with_permissions, user_without_permissions] } }
+
+ it 'assigns the first permissioned user' do
+ expect { response }.to change { alert.reload.assignees }.from([]).to([user_with_permissions])
+ expect(response).to be_success
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/alert_management/create_alert_issue_service_spec.rb b/spec/services/alert_management/create_alert_issue_service_spec.rb
index 62afe777165..9bc8b731dc1 100644
--- a/spec/services/alert_management/create_alert_issue_service_spec.rb
+++ b/spec/services/alert_management/create_alert_issue_service_spec.rb
@@ -94,11 +94,7 @@ RSpec.describe AlertManagement::CreateAlertIssueService do
end
context 'when alert cannot be updated' do
- before do
- # invalidate alert
- too_many_hosts = Array.new(AlertManagement::Alert::HOSTS_MAX_LENGTH + 1) { |_| 'host' }
- alert.update_columns(hosts: too_many_hosts)
- end
+ let(:alert) { create(:alert_management_alert, :with_validation_errors, :triggered, project: project, payload: payload) }
it 'responds with error' do
expect(execute).to be_error
@@ -122,17 +118,6 @@ RSpec.describe AlertManagement::CreateAlertIssueService do
expect(execute.message).to eq(_('An issue already exists'))
end
end
-
- context 'when alert_management_create_alert_issue feature flag is disabled' do
- before do
- stub_feature_flags(alert_management_create_alert_issue: false)
- end
-
- it 'responds with error' do
- expect(execute).to be_error
- expect(execute.message).to eq(_('You have no permissions'))
- end
- end
end
context 'when a user is not allowed to create an issue' do
diff --git a/spec/services/alert_management/process_prometheus_alert_service_spec.rb b/spec/services/alert_management/process_prometheus_alert_service_spec.rb
index 73f9f103902..5b4da5e9077 100644
--- a/spec/services/alert_management/process_prometheus_alert_service_spec.rb
+++ b/spec/services/alert_management/process_prometheus_alert_service_spec.rb
@@ -5,8 +5,12 @@ require 'spec_helper'
RSpec.describe AlertManagement::ProcessPrometheusAlertService do
let_it_be(:project) { create(:project) }
+ before do
+ allow(ProjectServiceWorker).to receive(:perform_async)
+ end
+
describe '#execute' do
- subject { described_class.new(project, nil, payload).execute }
+ subject(:execute) { described_class.new(project, nil, payload).execute }
context 'when alert payload is valid' do
let(:parsed_alert) { Gitlab::Alerting::Alert.new(project: project, payload: payload) }
@@ -37,12 +41,22 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do
context 'when alert with the same fingerprint already exists' do
let!(:alert) { create(:alert_management_alert, :resolved, project: project, fingerprint: parsed_alert.gitlab_fingerprint) }
+ it 'increases alert events count' do
+ expect { execute }.to change { alert.reload.events }.by(1)
+ end
+
context 'when status can be changed' do
it 'changes status to triggered' do
- expect { subject }.to change { alert.reload.triggered? }.to(true)
+ expect { execute }.to change { alert.reload.triggered? }.to(true)
end
end
+ it 'does not executes the alert service hooks' do
+ expect(alert).not_to receive(:execute_services)
+
+ subject
+ end
+
context 'when status change did not succeed' do
before do
allow(AlertManagement::Alert).to receive(:for_fingerprint).and_return([alert])
@@ -56,7 +70,7 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do
alert_id: alert.id
)
- subject
+ execute
end
end
@@ -66,7 +80,15 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do
context 'when alert does not exist' do
context 'when alert can be created' do
it 'creates a new alert' do
- expect { subject }.to change { AlertManagement::Alert.where(project: project).count }.by(1)
+ expect { execute }.to change { AlertManagement::Alert.where(project: project).count }.by(1)
+ end
+
+ it 'executes the alert service hooks' do
+ slack_service = create(:service, type: 'SlackService', project: project, alert_events: true, active: true)
+
+ subject
+
+ expect(ProjectServiceWorker).to have_received(:perform_async).with(slack_service.id, an_instance_of(Hash))
end
end
@@ -85,7 +107,7 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do
alert_errors: { hosts: ['hosts array is over 255 chars'] }
)
- subject
+ execute
end
end
@@ -99,7 +121,7 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do
context 'when status can be changed' do
it 'resolves an existing alert' do
- expect { subject }.to change { alert.reload.resolved? }.to(true)
+ expect { execute }.to change { alert.reload.resolved? }.to(true)
end
end
@@ -116,7 +138,7 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do
alert_id: alert.id
)
- subject
+ execute
end
end
@@ -128,8 +150,8 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do
let(:payload) { {} }
it 'responds with bad_request' do
- expect(subject).to be_error
- expect(subject.http_status).to eq(:bad_request)
+ expect(execute).to be_error
+ expect(execute.http_status).to eq(:bad_request)
end
end
end
diff --git a/spec/services/audit_event_service_spec.rb b/spec/services/audit_event_service_spec.rb
index 96df6689bb0..dc86735805c 100644
--- a/spec/services/audit_event_service_spec.rb
+++ b/spec/services/audit_event_service_spec.rb
@@ -4,12 +4,16 @@ require 'spec_helper'
describe AuditEventService do
let(:project) { create(:project) }
- let(:user) { create(:user) }
+ let(:user) { create(:user, :with_sign_ins) }
let(:project_member) { create(:project_member, user: user) }
let(:service) { described_class.new(user, project, { action: :destroy }) }
let(:logger) { instance_double(Gitlab::AuditJsonLogger) }
describe '#security_event' do
+ before do
+ stub_licensed_features(admin_audit_log: false)
+ end
+
it 'creates an event and logs to a file' do
expect(service).to receive(:file_logger).and_return(logger)
expect(logger).to receive(:info).with(author_id: user.id,
diff --git a/spec/services/authorized_project_update/project_create_service_spec.rb b/spec/services/authorized_project_update/project_create_service_spec.rb
index 49ea538d909..5b3e36af766 100644
--- a/spec/services/authorized_project_update/project_create_service_spec.rb
+++ b/spec/services/authorized_project_update/project_create_service_spec.rb
@@ -56,21 +56,47 @@ describe AuthorizedProjectUpdate::ProjectCreateService do
end
context 'membership overrides' do
- before do
- create(:group_member, access_level: Gitlab::Access::REPORTER, group: group_parent, user: group_user)
- create(:group_member, access_level: Gitlab::Access::DEVELOPER, group: group, user: group_user)
- ProjectAuthorization.delete_all
+ context 'group hierarchy' do
+ before do
+ create(:group_member, access_level: Gitlab::Access::REPORTER, group: group_parent, user: group_user)
+ create(:group_member, access_level: Gitlab::Access::DEVELOPER, group: group, user: group_user)
+ ProjectAuthorization.delete_all
+ end
+
+ it 'creates project authorization' do
+ expect { service.execute }.to(
+ change { ProjectAuthorization.count }.from(0).to(1))
+
+ project_authorization = ProjectAuthorization.where(
+ project_id: group_project.id,
+ user_id: group_user.id,
+ access_level: Gitlab::Access::DEVELOPER)
+ expect(project_authorization).to exist
+ end
end
- it 'creates project authorization' do
- expect { service.execute }.to(
- change { ProjectAuthorization.count }.from(0).to(1))
+ context 'group sharing' do
+ let!(:shared_with_group) { create(:group) }
- project_authorization = ProjectAuthorization.where(
- project_id: group_project.id,
- user_id: group_user.id,
- access_level: Gitlab::Access::DEVELOPER)
- expect(project_authorization).to exist
+ before do
+ create(:group_member, access_level: Gitlab::Access::REPORTER, group: group, user: group_user)
+ create(:group_member, access_level: Gitlab::Access::MAINTAINER, group: shared_with_group, user: group_user)
+
+ create(:group_group_link, shared_group: group, shared_with_group: shared_with_group, group_access: Gitlab::Access::DEVELOPER)
+
+ ProjectAuthorization.delete_all
+ end
+
+ it 'creates project authorization' do
+ expect { service.execute }.to(
+ change { ProjectAuthorization.count }.from(0).to(1))
+
+ project_authorization = ProjectAuthorization.where(
+ project_id: group_project.id,
+ user_id: group_user.id,
+ access_level: Gitlab::Access::DEVELOPER)
+ expect(project_authorization).to exist
+ end
end
end
diff --git a/spec/services/auto_merge/base_service_spec.rb b/spec/services/auto_merge/base_service_spec.rb
index 0a6bcb1badc..e08e1d670bf 100644
--- a/spec/services/auto_merge/base_service_spec.rb
+++ b/spec/services/auto_merge/base_service_spec.rb
@@ -82,9 +82,9 @@ describe AutoMerge::BaseService do
end
end
- context 'when failed to save' do
+ context 'when failed to save merge request' do
before do
- allow(merge_request).to receive(:save) { false }
+ allow(merge_request).to receive(:save!) { raise ActiveRecord::RecordInvalid.new }
end
it 'does not yield block' do
@@ -94,6 +94,39 @@ describe AutoMerge::BaseService do
it 'returns failed' do
is_expected.to eq(:failed)
end
+
+ it 'tracks the exception' do
+ expect(Gitlab::ErrorTracking)
+ .to receive(:track_exception).with(kind_of(ActiveRecord::RecordInvalid),
+ merge_request_id: merge_request.id)
+
+ subject
+ end
+ end
+
+ context 'when exception happens in yield block' do
+ def execute_with_error_in_yield
+ service.execute(merge_request) { raise 'Something went wrong' }
+ end
+
+ it 'returns failed status' do
+ expect(execute_with_error_in_yield).to eq(:failed)
+ end
+
+ it 'rollback the transaction' do
+ execute_with_error_in_yield
+
+ merge_request.reload
+ expect(merge_request).not_to be_auto_merge_enabled
+ end
+
+ it 'tracks the exception' do
+ expect(Gitlab::ErrorTracking)
+ .to receive(:track_exception).with(kind_of(RuntimeError),
+ merge_request_id: merge_request.id)
+
+ execute_with_error_in_yield
+ end
end
end
@@ -162,7 +195,7 @@ describe AutoMerge::BaseService do
context 'when failed to save' do
before do
- allow(merge_request).to receive(:save) { false }
+ allow(merge_request).to receive(:save!) { raise ActiveRecord::RecordInvalid.new }
end
it 'does not yield block' do
@@ -178,9 +211,9 @@ describe AutoMerge::BaseService do
it_behaves_like 'Canceled or Dropped'
- context 'when failed to save' do
+ context 'when failed to save merge request' do
before do
- allow(merge_request).to receive(:save) { false }
+ allow(merge_request).to receive(:save!) { raise ActiveRecord::RecordInvalid.new }
end
it 'returns error status' do
@@ -188,6 +221,33 @@ describe AutoMerge::BaseService do
expect(subject[:message]).to eq("Can't cancel the automatic merge")
end
end
+
+ context 'when exception happens in yield block' do
+ def cancel_with_error_in_yield
+ service.cancel(merge_request) { raise 'Something went wrong' }
+ end
+
+ it 'returns error' do
+ result = cancel_with_error_in_yield
+ expect(result[:status]).to eq(:error)
+ expect(result[:message]).to eq("Can't cancel the automatic merge")
+ end
+
+ it 'rollback the transaction' do
+ cancel_with_error_in_yield
+
+ merge_request.reload
+ expect(merge_request).to be_auto_merge_enabled
+ end
+
+ it 'tracks the exception' do
+ expect(Gitlab::ErrorTracking)
+ .to receive(:track_exception).with(kind_of(RuntimeError),
+ merge_request_id: merge_request.id)
+
+ cancel_with_error_in_yield
+ end
+ end
end
describe '#abort' do
@@ -200,7 +260,7 @@ describe AutoMerge::BaseService do
context 'when failed to save' do
before do
- allow(merge_request).to receive(:save) { false }
+ allow(merge_request).to receive(:save!) { raise ActiveRecord::RecordInvalid.new }
end
it 'returns error status' do
@@ -208,5 +268,32 @@ describe AutoMerge::BaseService do
expect(subject[:message]).to eq("Can't abort the automatic merge")
end
end
+
+ context 'when exception happens in yield block' do
+ def abort_with_error_in_yield
+ service.abort(merge_request, reason) { raise 'Something went wrong' }
+ end
+
+ it 'returns error' do
+ result = abort_with_error_in_yield
+ expect(result[:status]).to eq(:error)
+ expect(result[:message]).to eq("Can't abort the automatic merge")
+ end
+
+ it 'rollback the transaction' do
+ abort_with_error_in_yield
+
+ merge_request.reload
+ expect(merge_request).to be_auto_merge_enabled
+ end
+
+ it 'tracks the exception' do
+ expect(Gitlab::ErrorTracking)
+ .to receive(:track_exception).with(kind_of(RuntimeError),
+ merge_request_id: merge_request.id)
+
+ abort_with_error_in_yield
+ end
+ end
end
end
diff --git a/spec/services/ci/build_report_result_service_spec.rb b/spec/services/ci/build_report_result_service_spec.rb
new file mode 100644
index 00000000000..dbdfc774314
--- /dev/null
+++ b/spec/services/ci/build_report_result_service_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Ci::BuildReportResultService do
+ describe "#execute" do
+ subject(:build_report_result) { described_class.new.execute(build) }
+
+ context 'when build is finished' do
+ let(:build) { create(:ci_build, :success, :test_reports) }
+
+ it 'creates a build report result entry', :aggregate_failures do
+ expect(build_report_result.tests_name).to eq("test")
+ expect(build_report_result.tests_success).to eq(2)
+ expect(build_report_result.tests_failed).to eq(2)
+ expect(build_report_result.tests_errored).to eq(0)
+ expect(build_report_result.tests_skipped).to eq(0)
+ expect(build_report_result.tests_duration).to eq(0.010284)
+ expect(Ci::BuildReportResult.count).to eq(1)
+ end
+
+ context 'when feature is disable' do
+ it 'does not persist the data' do
+ stub_feature_flags(build_report_summary: false)
+
+ subject
+
+ expect(Ci::BuildReportResult.count).to eq(0)
+ end
+ end
+
+ context 'when data has already been persisted' do
+ it 'raises an error and do not persist the same data twice' do
+ expect { 2.times { described_class.new.execute(build) } }.to raise_error(ActiveRecord::RecordNotUnique)
+
+ expect(Ci::BuildReportResult.count).to eq(1)
+ end
+ end
+ end
+
+ context 'when build is running and test report does not exist' do
+ let(:build) { create(:ci_build, :running) }
+
+ it 'does not persist data' do
+ subject
+
+ expect(Ci::BuildReportResult.count).to eq(0)
+ end
+ end
+ end
+end
diff --git a/spec/services/ci/create_cross_project_pipeline_service_spec.rb b/spec/services/ci/create_cross_project_pipeline_service_spec.rb
index 5c59aaa4ce9..9e2497854bc 100644
--- a/spec/services/ci/create_cross_project_pipeline_service_spec.rb
+++ b/spec/services/ci/create_cross_project_pipeline_service_spec.rb
@@ -487,10 +487,11 @@ describe Ci::CreateCrossProjectPipelineService, '#execute' do
end
it 'does not create a pipeline and drops the bridge' do
- service.execute(bridge)
+ expect { service.execute(bridge) }.not_to change(downstream_project.ci_pipelines, :count)
expect(bridge.reload).to be_failed
expect(bridge.failure_reason).to eq('downstream_pipeline_creation_failed')
+ expect(bridge.options[:downstream_errors]).to eq(['Reference not found'])
end
end
@@ -509,10 +510,35 @@ describe Ci::CreateCrossProjectPipelineService, '#execute' do
end
it 'does not create a pipeline and drops the bridge' do
- service.execute(bridge)
+ expect { service.execute(bridge) }.not_to change(downstream_project.ci_pipelines, :count)
+
+ expect(bridge.reload).to be_failed
+ expect(bridge.failure_reason).to eq('downstream_pipeline_creation_failed')
+ expect(bridge.options[:downstream_errors]).to eq(['No stages / jobs for this pipeline.'])
+ end
+ end
+
+ context 'when downstream pipeline has invalid YAML' do
+ before do
+ stub_ci_pipeline_yaml_file(config)
+ end
+
+ let(:config) do
+ <<-EOY
+ test:
+ stage: testx
+ script: echo 1
+ EOY
+ end
+
+ it 'creates the pipeline but drops the bridge' do
+ expect { service.execute(bridge) }.to change(downstream_project.ci_pipelines, :count).by(1)
expect(bridge.reload).to be_failed
expect(bridge.failure_reason).to eq('downstream_pipeline_creation_failed')
+ expect(bridge.options[:downstream_errors]).to eq(
+ ['test job: chosen stage does not exist; available stages are .pre, build, test, deploy, .post']
+ )
end
end
end
diff --git a/spec/services/ci/create_pipeline_service_spec.rb b/spec/services/ci/create_pipeline_service_spec.rb
index 681ce9669e2..b9456d5fcd4 100644
--- a/spec/services/ci/create_pipeline_service_spec.rb
+++ b/spec/services/ci/create_pipeline_service_spec.rb
@@ -77,6 +77,18 @@ describe Ci::CreatePipelineService do
pipeline
end
+ it 'records pipeline size in a prometheus histogram' do
+ histogram = spy('pipeline size histogram')
+
+ allow(Gitlab::Ci::Pipeline::Chain::Metrics)
+ .to receive(:new).and_return(histogram)
+
+ execute_service
+
+ expect(histogram).to have_received(:observe)
+ .with({ source: 'push' }, 5)
+ end
+
context 'when merge requests already exist for this source branch' do
let(:merge_request_1) do
create(:merge_request, source_branch: 'feature', target_branch: "master", source_project: project)
diff --git a/spec/services/ci/create_web_ide_terminal_service_spec.rb b/spec/services/ci/create_web_ide_terminal_service_spec.rb
new file mode 100644
index 00000000000..2cc67c7cd1d
--- /dev/null
+++ b/spec/services/ci/create_web_ide_terminal_service_spec.rb
@@ -0,0 +1,143 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Ci::CreateWebIdeTerminalService do
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:user) { create(:user) }
+ let(:ref) { 'master' }
+
+ describe '#execute' do
+ subject { described_class.new(project, user, ref: ref).execute }
+
+ context 'for maintainer' do
+ shared_examples 'be successful' do
+ it 'returns a success with pipeline object' do
+ is_expected.to include(status: :success)
+
+ expect(subject[:pipeline]).to be_a(Ci::Pipeline)
+ expect(subject[:pipeline]).to be_persisted
+ expect(subject[:pipeline].stages.count).to eq(1)
+ expect(subject[:pipeline].builds.count).to eq(1)
+ end
+ end
+
+ before do
+ project.add_maintainer(user)
+ end
+
+ context 'when web-ide has valid configuration' do
+ before do
+ stub_webide_config_file(config_content)
+ end
+
+ context 'for empty configuration' do
+ let(:config_content) do
+ 'terminal: {}'
+ end
+
+ it_behaves_like 'be successful'
+ end
+
+ context 'for configuration with container image' do
+ let(:config_content) do
+ 'terminal: { image: ruby }'
+ end
+
+ it_behaves_like 'be successful'
+ end
+
+ context 'for configuration with ports' do
+ let(:config_content) do
+ <<-EOS
+ terminal:
+ image:
+ name: ruby:2.7
+ ports:
+ - 80
+ script: rspec
+ services:
+ - name: test
+ alias: test
+ ports:
+ - 8080
+ EOS
+ end
+
+ it_behaves_like 'be successful'
+ end
+ end
+ end
+
+ context 'error handling' do
+ shared_examples 'having an error' do |message|
+ it 'returns an error' do
+ is_expected.to eq(
+ status: :error,
+ message: message
+ )
+ end
+ end
+
+ shared_examples 'having insufficient permissions' do
+ it_behaves_like 'having an error', 'Insufficient permissions to create a terminal'
+ end
+
+ context 'when user is developer' do
+ before do
+ project.add_developer(user)
+ end
+
+ it_behaves_like 'having insufficient permissions'
+ end
+
+ context 'when user is maintainer' do
+ before do
+ project.add_maintainer(user)
+ end
+
+ context 'when terminal is already running' do
+ let!(:webide_pipeline) { create(:ci_pipeline, :webide, :running, project: project, user: user) }
+
+ it_behaves_like 'having an error', 'There is already a terminal running'
+ end
+
+ context 'when ref is non-existing' do
+ let(:ref) { 'non-existing-ref' }
+
+ it_behaves_like 'having an error', 'Ref does not exist'
+ end
+
+ context 'when ref is a tag' do
+ let(:ref) { 'v1.0.0' }
+
+ it_behaves_like 'having an error', 'Ref needs to be a branch'
+ end
+
+ context 'when terminal config is missing' do
+ let(:ref) { 'v1.0.0' }
+
+ it_behaves_like 'having an error', 'Ref needs to be a branch'
+ end
+
+ context 'when webide config is present' do
+ before do
+ stub_webide_config_file(config_content)
+ end
+
+ context 'config has invalid content' do
+ let(:config_content) { 'invalid' }
+
+ it_behaves_like 'having an error', 'Invalid configuration format'
+ end
+
+ context 'config is valid, but does not have terminal' do
+ let(:config_content) { '{}' }
+
+ it_behaves_like 'having an error', 'Terminal is not configured'
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/ci/expire_pipeline_cache_service_spec.rb b/spec/services/ci/expire_pipeline_cache_service_spec.rb
index 78e1ba0109a..2962e9dd31e 100644
--- a/spec/services/ci/expire_pipeline_cache_service_spec.rb
+++ b/spec/services/ci/expire_pipeline_cache_service_spec.rb
@@ -10,9 +10,9 @@ describe Ci::ExpirePipelineCacheService do
describe '#execute' do
it 'invalidates Etag caching for project pipelines path' do
- pipelines_path = "/#{project.full_path}/pipelines.json"
+ pipelines_path = "/#{project.full_path}/-/pipelines.json"
new_mr_pipelines_path = "/#{project.full_path}/-/merge_requests/new.json"
- pipeline_path = "/#{project.full_path}/pipelines/#{pipeline.id}.json"
+ pipeline_path = "/#{project.full_path}/-/pipelines/#{pipeline.id}.json"
expect_any_instance_of(Gitlab::EtagCaching::Store).to receive(:touch).with(pipelines_path)
expect_any_instance_of(Gitlab::EtagCaching::Store).to receive(:touch).with(new_mr_pipelines_path)
diff --git a/spec/services/ci/generate_terraform_reports_service_spec.rb b/spec/services/ci/generate_terraform_reports_service_spec.rb
index 4d2c60bed2c..008ecf17b3e 100644
--- a/spec/services/ci/generate_terraform_reports_service_spec.rb
+++ b/spec/services/ci/generate_terraform_reports_service_spec.rb
@@ -12,15 +12,23 @@ describe Ci::GenerateTerraformReportsService do
context 'when head pipeline has terraform reports' do
it 'returns status and data' do
- result = subject.execute(nil, merge_request.head_pipeline)
-
- expect(result).to match(
- status: :parsed,
- data: match(
- a_hash_including('tfplan.json' => a_hash_including('create' => 0, 'update' => 1, 'delete' => 0))
- ),
- key: an_instance_of(Array)
- )
+ pipeline = merge_request.head_pipeline
+ result = subject.execute(nil, pipeline)
+
+ pipeline.builds.each do |build|
+ expect(result).to match(
+ status: :parsed,
+ data: match(
+ a_hash_including(build.id.to_s => hash_including(
+ 'create' => 0,
+ 'delete' => 0,
+ 'update' => 1,
+ 'job_name' => build.options.dig(:artifacts, :name).to_s
+ ))
+ ),
+ key: an_instance_of(Array)
+ )
+ end
end
end
diff --git a/spec/services/ci/pipeline_bridge_status_service_spec.rb b/spec/services/ci/pipeline_bridge_status_service_spec.rb
index 0b6ae976d97..7e79d222349 100644
--- a/spec/services/ci/pipeline_bridge_status_service_spec.rb
+++ b/spec/services/ci/pipeline_bridge_status_service_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
describe Ci::PipelineBridgeStatusService do
let(:user) { build(:user) }
- let(:project) { build(:project) }
+ let_it_be(:project) { create(:project) }
let(:pipeline) { build(:ci_pipeline, project: project) }
describe '#execute' do
diff --git a/spec/services/ci/retry_build_service_spec.rb b/spec/services/ci/retry_build_service_spec.rb
index 0aa603b24ae..90c53d4a346 100644
--- a/spec/services/ci/retry_build_service_spec.rb
+++ b/spec/services/ci/retry_build_service_spec.rb
@@ -30,7 +30,7 @@ describe Ci::RetryBuildService do
created_at updated_at started_at finished_at queued_at erased_by
erased_at auto_canceled_by job_artifacts job_artifacts_archive
job_artifacts_metadata job_artifacts_trace job_artifacts_junit
- job_artifacts_sast job_artifacts_dependency_scanning
+ job_artifacts_sast job_artifacts_secret_detection job_artifacts_dependency_scanning
job_artifacts_container_scanning job_artifacts_dast
job_artifacts_license_management job_artifacts_license_scanning
job_artifacts_performance job_artifacts_lsif
@@ -38,7 +38,8 @@ describe Ci::RetryBuildService do
job_artifacts_codequality job_artifacts_metrics scheduled_at
job_variables waiting_for_resource_at job_artifacts_metrics_referee
job_artifacts_network_referee job_artifacts_dotenv
- job_artifacts_cobertura needs job_artifacts_accessibility].freeze
+ job_artifacts_cobertura needs job_artifacts_accessibility
+ job_artifacts_requirements].freeze
ignore_accessors =
%i[type lock_version target_url base_tags trace_sections
@@ -49,7 +50,7 @@ describe Ci::RetryBuildService do
metadata runner_session trace_chunks upstream_pipeline_id
artifacts_file artifacts_metadata artifacts_size commands
resource resource_group_id processed security_scans author
- pipeline_id].freeze
+ pipeline_id report_results].freeze
shared_examples 'build duplication' do
let(:another_pipeline) { create(:ci_empty_pipeline, project: project) }
diff --git a/spec/services/ci/update_ci_ref_status_service_spec.rb b/spec/services/ci/update_ci_ref_status_service_spec.rb
deleted file mode 100644
index 8b60586318d..00000000000
--- a/spec/services/ci/update_ci_ref_status_service_spec.rb
+++ /dev/null
@@ -1,169 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe Ci::UpdateCiRefStatusService do
- describe '#call' do
- subject { described_class.new(pipeline) }
-
- shared_examples 'creates ci_ref' do
- it 'creates a ci_ref with the pipeline attributes' do
- expect do
- expect(subject.call).to eq(true)
- end.to change { Ci::Ref.count }.by(1)
-
- created_ref = pipeline.reload.ref_status
- %w[ref tag project status].each do |attr|
- expect(created_ref[attr]).to eq(pipeline[attr])
- end
- end
-
- it 'calls PipelineNotificationWorker pasing the ref_status' do
- expect(PipelineNotificationWorker).to receive(:perform_async).with(pipeline.id, ref_status: pipeline.status)
-
- subject.call
- end
- end
-
- shared_examples 'updates ci_ref' do
- where(:ref_status, :pipeline_status, :next_status) do
- [
- %w[failed success fixed],
- %w[failed failed failed],
- %w[success success success],
- %w[success failed failed]
- ]
- end
-
- with_them do
- let(:ci_ref) { create(:ci_ref, status: ref_status) }
- let(:pipeline) { create(:ci_pipeline, status: pipeline_status, project: ci_ref.project, ref: ci_ref.ref) }
-
- it 'sets ci_ref.status to next_status' do
- expect do
- expect(subject.call).to eq(true)
- expect(ci_ref.reload.status).to eq(next_status)
- end.not_to change { Ci::Ref.count }
- end
-
- it 'calls PipelineNotificationWorker pasing the ref_status' do
- expect(PipelineNotificationWorker).to receive(:perform_async).with(pipeline.id, ref_status: next_status)
-
- subject.call
- end
- end
- end
-
- shared_examples 'does a noop' do
- it "doesn't change ci_ref" do
- expect do
- expect do
- expect(subject.call).to eq(false)
- end.not_to change { ci_ref.reload.status }
- end.not_to change { Ci::Ref.count }
- end
-
- it "doesn't call PipelineNotificationWorker" do
- expect(PipelineNotificationWorker).not_to receive(:perform_async)
-
- subject.call
- end
- end
-
- context "ci_ref doesn't exists" do
- let(:pipeline) { create(:ci_pipeline, :success, ref: 'new-ref') }
-
- it_behaves_like 'creates ci_ref'
-
- context 'when an ActiveRecord::RecordNotUnique validation is raised' do
- let(:ci_ref) { create(:ci_ref, status: 'failed') }
- let(:pipeline) { create(:ci_pipeline, status: :success, project: ci_ref.project, ref: ci_ref.ref) }
-
- it 'reloads the ci_ref and retries once' do
- subject.instance_variable_set("@ref", subject.send(:build_ref))
-
- expect do
- expect(subject.call).to eq(true)
- end.not_to change { Ci::Ref.count }
- expect(ci_ref.reload.status).to eq('fixed')
- end
-
- it 'raises error on multiple retries' do
- allow_any_instance_of(Ci::Ref).to receive(:update)
- .and_raise(ActiveRecord::RecordNotUnique)
-
- expect { subject.call }.to raise_error(ActiveRecord::RecordNotUnique)
- end
- end
- end
-
- context 'ci_ref exists' do
- let!(:ci_ref) { create(:ci_ref, status: 'failed') }
- let(:pipeline) { ci_ref.pipelines.first }
-
- it_behaves_like 'updates ci_ref'
-
- context 'pipeline status is invalid' do
- let!(:pipeline) { create(:ci_pipeline, :running, project: ci_ref.project, ref: ci_ref.ref, tag: ci_ref.tag) }
-
- it_behaves_like 'does a noop'
- end
-
- context 'newer pipeline finished' do
- let(:newer_pipeline) { create(:ci_pipeline, :success, project: ci_ref.project, ref: ci_ref.ref, tag: ci_ref.tag) }
-
- before do
- ci_ref.update!(last_updated_by_pipeline: newer_pipeline)
- end
-
- it_behaves_like 'does a noop'
- end
-
- context 'pipeline is retried' do
- before do
- ci_ref.update!(last_updated_by_pipeline: pipeline)
- end
-
- it_behaves_like 'updates ci_ref'
- end
-
- context 'ref is stale' do
- let(:pipeline1) { create(:ci_pipeline, :success, project: ci_ref.project, ref: ci_ref.ref, tag: ci_ref.tag) }
- let(:pipeline2) { create(:ci_pipeline, :success, project: ci_ref.project, ref: ci_ref.ref, tag: ci_ref.tag) }
-
- it 'reloads the ref and retry' do
- service1 = described_class.new(pipeline1)
- service2 = described_class.new(pipeline2)
-
- service2.send(:ref)
- service1.call
- expect(ci_ref.reload.status).to eq('fixed')
- expect do
- expect(service2.call).to eq(true)
- # We expect 'success' in this case rather than 'fixed' because
- # the ref is correctly reloaded on stale error.
- expect(ci_ref.reload.status).to eq('success')
- end.not_to change { Ci::Ref.count }
- end
-
- it 'aborts when a newer pipeline finished' do
- service1 = described_class.new(pipeline1)
- service2 = described_class.new(pipeline2)
-
- service2.call
- expect do
- expect(service1.call).to eq(false)
- expect(ci_ref.reload.status).to eq('fixed')
- end.not_to change { Ci::Ref.count }
- end
- end
-
- context 'ref exists as both tag/branch and tag' do
- let(:pipeline) { create(:ci_pipeline, :failed, project: ci_ref.project, ref: ci_ref.ref, tag: true) }
- let!(:branch_pipeline) { create(:ci_pipeline, :success, project: ci_ref.project, ref: ci_ref.ref, tag: false) }
-
- it_behaves_like 'creates ci_ref'
- end
- end
- end
-end
diff --git a/spec/services/ci/web_ide_config_service_spec.rb b/spec/services/ci/web_ide_config_service_spec.rb
new file mode 100644
index 00000000000..7522103ccb7
--- /dev/null
+++ b/spec/services/ci/web_ide_config_service_spec.rb
@@ -0,0 +1,91 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Ci::WebIdeConfigService do
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:user) { create(:user) }
+ let(:sha) { 'sha' }
+
+ describe '#execute' do
+ subject { described_class.new(project, user, sha: sha).execute }
+
+ context 'when insufficient permission' do
+ it 'returns an error' do
+ is_expected.to include(
+ status: :error,
+ message: 'Insufficient permissions to read configuration')
+ end
+ end
+
+ context 'for developer' do
+ before do
+ project.add_developer(user)
+ end
+
+ context 'when file is missing' do
+ it 'returns an error' do
+ is_expected.to include(
+ status: :error,
+ message: "Failed to load Web IDE config file '.gitlab/.gitlab-webide.yml' for sha")
+ end
+ end
+
+ context 'when file is present' do
+ before do
+ allow(project.repository).to receive(:blob_data_at).with('sha', anything) do
+ config_content
+ end
+ end
+
+ context 'content is not valid' do
+ let(:config_content) { 'invalid content' }
+
+ it 'returns an error' do
+ is_expected.to include(
+ status: :error,
+ message: "Invalid configuration format")
+ end
+ end
+
+ context 'content is valid, but terminal not defined' do
+ let(:config_content) { '{}' }
+
+ it 'returns success' do
+ is_expected.to include(
+ status: :success,
+ terminal: nil)
+ end
+ end
+
+ context 'content is valid, with enabled terminal' do
+ let(:config_content) { 'terminal: {}' }
+
+ it 'returns success' do
+ is_expected.to include(
+ status: :success,
+ terminal: {
+ tag_list: [],
+ yaml_variables: [],
+ options: { script: ["sleep 60"] }
+ })
+ end
+ end
+
+ context 'content is valid, with custom terminal' do
+ let(:config_content) { 'terminal: { before_script: [ls] }' }
+
+ it 'returns success' do
+ is_expected.to include(
+ status: :success,
+ terminal: {
+ tag_list: [],
+ yaml_variables: [],
+ options: { before_script: ["ls"], script: ["sleep 60"] }
+ })
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/clusters/applications/check_uninstall_progress_service_spec.rb b/spec/services/clusters/applications/check_uninstall_progress_service_spec.rb
index ffb658330d3..9dede1947f8 100644
--- a/spec/services/clusters/applications/check_uninstall_progress_service_spec.rb
+++ b/spec/services/clusters/applications/check_uninstall_progress_service_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe Clusters::Applications::CheckUninstallProgressService do
- RESCHEDULE_PHASES = Gitlab::Kubernetes::Pod::PHASES - [Gitlab::Kubernetes::Pod::SUCCEEDED, Gitlab::Kubernetes::Pod::FAILED].freeze
+ reschedule_phases = Gitlab::Kubernetes::Pod::PHASES - [Gitlab::Kubernetes::Pod::SUCCEEDED, Gitlab::Kubernetes::Pod::FAILED].freeze
let(:application) { create(:clusters_applications_prometheus, :uninstalling) }
let(:service) { described_class.new(application) }
@@ -42,7 +42,7 @@ describe Clusters::Applications::CheckUninstallProgressService do
end
context 'when application is uninstalling' do
- RESCHEDULE_PHASES.each { |phase| it_behaves_like 'a not yet terminated installation', phase }
+ reschedule_phases.each { |phase| it_behaves_like 'a not yet terminated installation', phase }
context 'when installation POD succeeded' do
let(:phase) { Gitlab::Kubernetes::Pod::SUCCEEDED }
diff --git a/spec/services/clusters/applications/prometheus_config_service_spec.rb b/spec/services/clusters/applications/prometheus_config_service_spec.rb
index 993a697b543..b9032e665ec 100644
--- a/spec/services/clusters/applications/prometheus_config_service_spec.rb
+++ b/spec/services/clusters/applications/prometheus_config_service_spec.rb
@@ -90,23 +90,25 @@ describe Clusters::Applications::PrometheusConfigService do
create(:prometheus_alert,
project: project,
environment: production,
- prometheus_metric: metric)
+ prometheus_metric: metric,
+ operator: PrometheusAlert.operators['gt'],
+ threshold: 0)
end
let(:metric) do
create(:prometheus_metric, query: query, project: project)
end
- let(:query) { '%{ci_environment_slug}' }
+ let(:query) { 'up{environment="{{ci_environment_slug}}"}' }
it 'substitutes query variables' do
expect(Gitlab::Prometheus::QueryVariables)
.to receive(:call)
- .with(production)
+ .with(production, start_time: nil, end_time: nil)
.and_call_original
expr = groups.dig(0, 'rules', 0, 'expr')
- expect(expr).to include(production.name)
+ expect(expr).to eq("up{environment=\"#{production.slug}\"} > 0.0")
end
end
@@ -127,13 +129,15 @@ describe Clusters::Applications::PrometheusConfigService do
end
it 'substitutes query variables once per environment' do
+ allow(Gitlab::Prometheus::QueryVariables).to receive(:call).and_call_original
+
expect(Gitlab::Prometheus::QueryVariables)
.to receive(:call)
- .with(production)
+ .with(production, start_time: nil, end_time: nil)
expect(Gitlab::Prometheus::QueryVariables)
.to receive(:call)
- .with(staging)
+ .with(staging, start_time: nil, end_time: nil)
subject
end
diff --git a/spec/services/clusters/parse_cluster_applications_artifact_service_spec.rb b/spec/services/clusters/parse_cluster_applications_artifact_service_spec.rb
index f14c929554a..bb0b107eba6 100644
--- a/spec/services/clusters/parse_cluster_applications_artifact_service_spec.rb
+++ b/spec/services/clusters/parse_cluster_applications_artifact_service_spec.rb
@@ -85,13 +85,25 @@ describe Clusters::ParseClusterApplicationsArtifactService do
end
end
- context 'job has no deployment cluster' do
+ context 'job has no deployment' do
let(:job) { build(:ci_build) }
it 'returns an error' do
result = described_class.new(job, user).execute(artifact)
expect(result[:status]).to eq(:error)
+ expect(result[:message]).to eq('No deployment found for this job')
+ end
+ end
+
+ context 'job has no deployment cluster' do
+ let(:deployment) { create(:deployment) }
+ let(:job) { deployment.deployable }
+
+ it 'returns an error' do
+ result = described_class.new(job, user).execute(artifact)
+
+ expect(result[:status]).to eq(:error)
expect(result[:message]).to eq('No deployment cluster found for this job')
end
end
diff --git a/spec/services/concerns/exclusive_lease_guard_spec.rb b/spec/services/concerns/exclusive_lease_guard_spec.rb
new file mode 100644
index 00000000000..a38facc7520
--- /dev/null
+++ b/spec/services/concerns/exclusive_lease_guard_spec.rb
@@ -0,0 +1,121 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ExclusiveLeaseGuard, :clean_gitlab_redis_shared_state do
+ subject :subject_class do
+ Class.new do
+ include ExclusiveLeaseGuard
+
+ def self.name
+ 'ExclusiveLeaseGuardTestClass'
+ end
+
+ def call(&block)
+ try_obtain_lease do
+ internal_method(&block)
+ end
+ end
+
+ def internal_method
+ yield
+ end
+
+ def lease_timeout
+ 1.second
+ end
+ end
+ end
+
+ describe '#try_obtain_lease' do
+ let(:subject) { subject_class.new }
+
+ it 'obtains the lease, calls internal_method and releases the lease', :aggregate_failures do
+ expect(subject).to receive(:internal_method).and_call_original
+
+ subject.call do
+ expect(subject.exclusive_lease.exists?).to be_truthy
+ end
+
+ expect(subject.exclusive_lease.exists?).to be_falsey
+ end
+
+ context 'when the lease is already obtained' do
+ before do
+ subject.exclusive_lease.try_obtain
+ end
+
+ after do
+ subject.exclusive_lease.cancel
+ end
+
+ it 'does not call internal_method but logs error', :aggregate_failures do
+ expect(subject).not_to receive(:internal_method)
+ expect(Gitlab::AppLogger).to receive(:error).with('Cannot obtain an exclusive lease. There must be another instance already in execution.')
+
+ subject.call
+ end
+ end
+
+ context 'with overwritten lease_release?' do
+ subject :overwritten_subject_class do
+ Class.new(subject_class) do
+ def lease_release?
+ false
+ end
+ end
+ end
+
+ let(:subject) { overwritten_subject_class.new }
+
+ it 'does not release the lease after execution', :aggregate_failures do
+ subject.call do
+ expect(subject.exclusive_lease.exists?).to be_truthy
+ end
+
+ expect(subject.exclusive_lease.exists?).to be_truthy
+ end
+ end
+ end
+
+ describe '#exclusive_lease' do
+ it 'uses the class name as lease key' do
+ expect(Gitlab::ExclusiveLease).to receive(:new).with('exclusive_lease_guard_test_class', timeout: 1.second)
+
+ subject_class.new.exclusive_lease
+ end
+
+ context 'with overwritten lease_key' do
+ subject :overwritten_class do
+ Class.new(subject_class) do
+ def lease_key
+ 'other_lease_key'
+ end
+ end
+ end
+
+ it 'uses the custom lease key' do
+ expect(Gitlab::ExclusiveLease).to receive(:new).with('other_lease_key', timeout: 1.second)
+
+ overwritten_class.new.exclusive_lease
+ end
+ end
+ end
+
+ describe '#release_lease' do
+ it 'sends a cancel message to ExclusiveLease' do
+ expect(Gitlab::ExclusiveLease).to receive(:cancel).with('exclusive_lease_guard_test_class', 'some_uuid')
+
+ subject_class.new.release_lease('some_uuid')
+ end
+ end
+
+ describe '#renew_lease!' do
+ let(:subject) { subject_class.new }
+
+ it 'sends a renew message to the exclusive_lease instance' do
+ expect(subject.exclusive_lease).to receive(:renew)
+ subject.renew_lease!
+ end
+ end
+end
diff --git a/spec/services/container_expiration_policies/update_service_spec.rb b/spec/services/container_expiration_policies/update_service_spec.rb
new file mode 100644
index 00000000000..ec178f3830f
--- /dev/null
+++ b/spec/services/container_expiration_policies/update_service_spec.rb
@@ -0,0 +1,101 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe ContainerExpirationPolicies::UpdateService do
+ using RSpec::Parameterized::TableSyntax
+
+ let_it_be(:project, reload: true) { create(:project) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:params) { { cadence: '3month', keep_n: 100, older_than: '14d', extra_key: 'will_not_be_processed' } }
+
+ let(:container_expiration_policy) { project.container_expiration_policy }
+
+ describe '#execute' do
+ subject { described_class.new(container: project, current_user: user, params: params).execute }
+
+ RSpec.shared_examples 'returning a success' do
+ it 'returns a success' do
+ result = subject
+
+ expect(result.payload[:container_expiration_policy]).to be_present
+ expect(result.success?).to be_truthy
+ end
+ end
+
+ RSpec.shared_examples 'returning an error' do |message, http_status|
+ it 'returns an error' do
+ result = subject
+
+ expect(result.message).to eq(message)
+ expect(result.status).to eq(:error)
+ expect(result.http_status).to eq(http_status)
+ end
+ end
+
+ RSpec.shared_examples 'updating the container expiration policy' do
+ it_behaves_like 'updating the container expiration policy attributes', mode: :update, from: { cadence: '1d', keep_n: 10, older_than: '90d' }, to: { cadence: '3month', keep_n: 100, older_than: '14d' }
+
+ it_behaves_like 'returning a success'
+
+ context 'with invalid params' do
+ let_it_be(:params) { { cadence: '20d' } }
+
+ it_behaves_like 'not creating the container expiration policy'
+
+ it "doesn't update the cadence" do
+ expect { subject }
+ .not_to change { container_expiration_policy.reload.cadence }
+ end
+
+ it_behaves_like 'returning an error', 'Cadence is not included in the list', 400
+ end
+ end
+
+ RSpec.shared_examples 'denying access to container expiration policy' do
+ context 'with existing container expiration policy' do
+ it_behaves_like 'not creating the container expiration policy'
+
+ it_behaves_like 'returning an error', 'Access Denied', 403
+ end
+ end
+
+ context 'with existing container expiration policy' do
+ where(:user_role, :shared_examples_name) do
+ :maintainer | 'updating the container expiration policy'
+ :developer | 'updating the container expiration policy'
+ :reporter | 'denying access to container expiration policy'
+ :guest | 'denying access to container expiration policy'
+ :anonymous | 'denying access to container expiration policy'
+ end
+
+ with_them do
+ before do
+ project.send("add_#{user_role}", user) unless user_role == :anonymous
+ end
+
+ it_behaves_like params[:shared_examples_name]
+ end
+ end
+
+ context 'without existing container expiration policy' do
+ let_it_be(:project, reload: true) { create(:project, :without_container_expiration_policy) }
+
+ where(:user_role, :shared_examples_name) do
+ :maintainer | 'creating the container expiration policy'
+ :developer | 'creating the container expiration policy'
+ :reporter | 'denying access to container expiration policy'
+ :guest | 'denying access to container expiration policy'
+ :anonymous | 'denying access to container expiration policy'
+ end
+
+ with_them do
+ before do
+ project.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/services/container_expiration_policy_service_spec.rb b/spec/services/container_expiration_policy_service_spec.rb
index b2f2b2e1236..97715b990ef 100644
--- a/spec/services/container_expiration_policy_service_spec.rb
+++ b/spec/services/container_expiration_policy_service_spec.rb
@@ -27,5 +27,20 @@ describe ContainerExpirationPolicyService do
expect(container_expiration_policy.next_run_at).to be > Time.zone.now
end
+
+ context 'with an invalid container expiration policy' do
+ before do
+ allow(container_expiration_policy).to receive(:valid?).and_return(false)
+ end
+
+ it 'disables it' do
+ expect(container_expiration_policy).not_to receive(:schedule_next_run!)
+ expect(CleanupContainerRepositoryWorker).not_to receive(:perform_async)
+
+ expect { subject }
+ .to change { container_expiration_policy.reload.enabled }.from(true).to(false)
+ .and raise_error(ContainerExpirationPolicyService::InvalidPolicyError)
+ 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 2c0c1570cb4..bf5d6b443e6 100644
--- a/spec/services/design_management/delete_designs_service_spec.rb
+++ b/spec/services/design_management/delete_designs_service_spec.rb
@@ -56,6 +56,10 @@ describe DesignManagement::DeleteDesignsService do
let(:enabled) { false }
it_behaves_like "a service error"
+
+ it 'does not create any events in the activity stream' do
+ expect { run_service rescue nil }.not_to change { Event.count }
+ end
end
context "when the feature is available" do
@@ -72,7 +76,9 @@ describe DesignManagement::DeleteDesignsService do
it 'does not log any events' do
counter = ::Gitlab::UsageDataCounters::DesignsCounter
- expect { run_service rescue nil }.not_to change { counter.totals }
+
+ expect { run_service rescue nil }
+ .not_to change { [counter.totals, Event.count] }
end
end
@@ -92,6 +98,12 @@ describe DesignManagement::DeleteDesignsService do
expect { run_service }.to change { counter.read(:delete) }.by(1)
end
+ it 'creates an event in the activity stream' do
+ expect { run_service }
+ .to change { Event.count }.by(1)
+ .and change { Event.destroyed_action.for_design.count }.by(1)
+ end
+
it 'informs the new-version-worker' do
expect(::DesignManagement::NewVersionWorker).to receive(:perform_async).with(Integer)
@@ -129,14 +141,14 @@ describe DesignManagement::DeleteDesignsService do
let!(:designs) { create_designs(2) }
- it 'removes those designs' do
+ it 'makes the correct changes' do
+ counter = ::Gitlab::UsageDataCounters::DesignsCounter
+
expect { run_service }
.to change { issue.designs.current.count }.from(3).to(1)
- end
-
- it 'logs the correct number of deletion events' do
- counter = ::Gitlab::UsageDataCounters::DesignsCounter
- expect { run_service }.to change { counter.read(:delete) }.by(2)
+ .and change { counter.read(:delete) }.by(2)
+ .and change { Event.count }.by(2)
+ .and change { Event.destroyed_action.for_design.count }.by(2)
end
it_behaves_like "a success"
diff --git a/spec/services/design_management/save_designs_service_spec.rb b/spec/services/design_management/save_designs_service_spec.rb
index 013d5473860..3be3ac9daca 100644
--- a/spec/services/design_management/save_designs_service_spec.rb
+++ b/spec/services/design_management/save_designs_service_spec.rb
@@ -65,6 +65,10 @@ describe DesignManagement::SaveDesignsService do
end
it_behaves_like 'a service error'
+
+ it 'does not create an event in the activity stream' do
+ expect { run_service }.not_to change { Event.count }
+ end
end
context 'when the feature is available' do
@@ -89,6 +93,12 @@ describe DesignManagement::SaveDesignsService do
expect { run_service }.to change { counter.read(:create) }.by(1)
end
+ it 'creates an event in the activity stream' do
+ expect { run_service }
+ .to change { Event.count }.by(1)
+ .and change { Event.for_design.created_action.count }.by(1)
+ end
+
it 'creates a commit in the repository' do
run_service
@@ -166,9 +176,12 @@ describe DesignManagement::SaveDesignsService do
expect(updated_designs.first.versions.size).to eq(2)
end
- it 'increments the update counter' do
+ it 'records the correct events' do
counter = Gitlab::UsageDataCounters::DesignsCounter
- expect { run_service }.to change { counter.read(:update) }.by 1
+ expect { run_service }
+ .to change { counter.read(:update) }.by(1)
+ .and change { Event.count }.by(1)
+ .and change { Event.for_design.updated_action.count }.by(1)
end
context 'when uploading a new design' do
@@ -217,6 +230,14 @@ describe DesignManagement::SaveDesignsService do
.and change { counter.read(:update) }.by(1)
end
+ it 'creates the correct activity stream events' do
+ expect { run_service }
+ .to change { Event.count }.by(2)
+ .and change { Event.for_design.count }.by(2)
+ .and change { Event.created_action.count }.by(1)
+ .and change { Event.updated_action.count }.by(1)
+ end
+
it 'creates a single commit' do
commit_count = -> do
design_repository.expire_all_method_caches
diff --git a/spec/services/discussions/resolve_service_spec.rb b/spec/services/discussions/resolve_service_spec.rb
index 2e9a7a293d1..7461934b455 100644
--- a/spec/services/discussions/resolve_service_spec.rb
+++ b/spec/services/discussions/resolve_service_spec.rb
@@ -4,28 +4,24 @@ require 'spec_helper'
describe Discussions::ResolveService do
describe '#execute' do
- let(:discussion) { create(:diff_note_on_merge_request).to_discussion }
- let(:project) { merge_request.project }
- let(:merge_request) { discussion.noteable }
- let(:user) { create(:user) }
- let(:service) { described_class.new(discussion.noteable.project, user, merge_request: merge_request) }
-
- before do
- project.add_maintainer(user)
- end
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:user) { create(:user, developer_projects: [project]) }
+ let_it_be(:merge_request) { create(:merge_request, :merge_when_pipeline_succeeds, source_project: project) }
+ let(:discussion) { create(:diff_note_on_merge_request, noteable: merge_request, project: project).to_discussion }
+ let(:service) { described_class.new(project, user, one_or_more_discussions: discussion) }
it "doesn't resolve discussions the user can't resolve" do
expect(discussion).to receive(:can_resolve?).with(user).and_return(false)
- service.execute(discussion)
+ service.execute
- expect(discussion.resolved?).to be(false)
+ expect(discussion).not_to be_resolved
end
it 'resolves the discussion' do
- service.execute(discussion)
+ service.execute
- expect(discussion.resolved?).to be(true)
+ expect(discussion).to be_resolved
end
it 'executes the notification service' do
@@ -33,24 +29,83 @@ describe Discussions::ResolveService do
expect(instance).to receive(:execute).with(discussion.noteable)
end
- service.execute(discussion)
+ service.execute
+ end
+
+ it 'schedules an auto-merge' do
+ expect(AutoMergeProcessWorker).to receive(:perform_async).with(discussion.noteable.id)
+
+ service.execute
+ end
+
+ context 'with a project that requires all discussion to be resolved' do
+ before do
+ project.update(only_allow_merge_if_all_discussions_are_resolved: true)
+ end
+
+ after do
+ project.update(only_allow_merge_if_all_discussions_are_resolved: false)
+ end
+
+ let_it_be(:other_discussion) { create(:diff_note_on_merge_request, noteable: merge_request, project: project).to_discussion }
+
+ it 'does not schedule an auto-merge' do
+ expect(AutoMergeProcessWorker).not_to receive(:perform_async)
+
+ service.execute
+ end
+
+ it 'schedules an auto-merge' do
+ expect(AutoMergeProcessWorker).to receive(:perform_async)
+
+ described_class.new(project, user, one_or_more_discussions: [discussion, other_discussion]).execute
+ end
end
it 'adds a system note to the discussion' do
issue = create(:issue, project: project)
expect(SystemNoteService).to receive(:discussion_continued_in_issue).with(discussion, project, user, issue)
- service = described_class.new(project, user, merge_request: merge_request, follow_up_issue: issue)
- service.execute(discussion)
+ service = described_class.new(project, user, one_or_more_discussions: discussion, follow_up_issue: issue)
+ service.execute
end
it 'can resolve multiple discussions at once' do
- other_discussion = create(:diff_note_on_merge_request, noteable: discussion.noteable, project: discussion.noteable.source_project).to_discussion
+ other_discussion = create(:diff_note_on_merge_request, noteable: merge_request, project: project).to_discussion
+ service = described_class.new(project, user, one_or_more_discussions: [discussion, other_discussion])
+ service.execute
- service.execute([discussion, other_discussion])
+ expect([discussion, other_discussion]).to all(be_resolved)
+ end
+
+ it 'raises an argument error if discussions do not belong to the same noteable' do
+ other_merge_request = create(:merge_request)
+ other_discussion = create(:diff_note_on_merge_request,
+ noteable: other_merge_request,
+ project: other_merge_request.source_project).to_discussion
+ expect do
+ described_class.new(project, user, one_or_more_discussions: [discussion, other_discussion])
+ end.to raise_error(
+ ArgumentError,
+ 'Discussions must be all for the same noteable'
+ )
+ end
- expect(discussion.resolved?).to be(true)
- expect(other_discussion.resolved?).to be(true)
+ context 'when discussion is not for a merge request' do
+ let_it_be(:design) { create(:design, :with_file, issue: create(:issue, project: project)) }
+ let(:discussion) { create(:diff_note_on_design, noteable: design, project: project).to_discussion }
+
+ it 'does not execute the notification service' do
+ expect(MergeRequests::ResolvedDiscussionNotificationService).not_to receive(:new)
+
+ service.execute
+ end
+
+ it 'does not schedule an auto-merge' do
+ expect(AutoMergeProcessWorker).not_to receive(:perform_async)
+
+ service.execute
+ end
end
end
end
diff --git a/spec/services/draft_notes/create_service_spec.rb b/spec/services/draft_notes/create_service_spec.rb
new file mode 100644
index 00000000000..8f244ed386b
--- /dev/null
+++ b/spec/services/draft_notes/create_service_spec.rb
@@ -0,0 +1,94 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+describe DraftNotes::CreateService do
+ let(:merge_request) { create(:merge_request) }
+ let(:project) { merge_request.target_project }
+ let(:user) { merge_request.author }
+
+ def create_draft(params)
+ described_class.new(merge_request, user, params).execute
+ end
+
+ it 'creates a simple draft note' do
+ draft = create_draft(note: 'This is a test')
+
+ expect(draft).to be_an_instance_of(DraftNote)
+ expect(draft.note).to eq('This is a test')
+ expect(draft.author).to eq(user)
+ expect(draft.project).to eq(merge_request.target_project)
+ expect(draft.discussion_id).to be_nil
+ end
+
+ it 'cannot resolve when there is nothing to resolve' do
+ draft = create_draft(note: 'Not a reply!', resolve_discussion: true)
+
+ expect(draft.errors[:base]).to include('User is not allowed to resolve thread')
+ expect(draft).not_to be_persisted
+ end
+
+ context 'in a thread' do
+ it 'creates a draft note with discussion_id' do
+ discussion = create(:discussion_note_on_merge_request, noteable: merge_request, project: project).discussion
+
+ draft = create_draft(note: 'A reply!', in_reply_to_discussion_id: discussion.reply_id)
+
+ expect(draft.note).to eq('A reply!')
+ expect(draft.discussion_id).to eq(discussion.reply_id)
+ expect(draft.resolve_discussion).to be_falsey
+ end
+
+ it 'creates a draft that resolves the thread' do
+ discussion = create(:discussion_note_on_merge_request, noteable: merge_request, project: project).discussion
+
+ draft = create_draft(note: 'A reply!', in_reply_to_discussion_id: discussion.reply_id, resolve_discussion: true)
+
+ expect(draft.note).to eq('A reply!')
+ expect(draft.discussion_id).to eq(discussion.reply_id)
+ expect(draft.resolve_discussion).to be true
+ end
+ end
+
+ it 'creates a draft note with a position in a diff' do
+ diff_refs = project.commit(RepoHelpers.sample_commit.id).try(:diff_refs)
+
+ position = Gitlab::Diff::Position.new(
+ old_path: "files/ruby/popen.rb",
+ new_path: "files/ruby/popen.rb",
+ old_line: nil,
+ new_line: 14,
+ diff_refs: diff_refs
+ )
+
+ draft = create_draft(note: 'Comment on diff', position: position.to_json)
+
+ expect(draft.note).to eq('Comment on diff')
+ expect(draft.original_position.to_json).to eq(position.to_json)
+ end
+
+ context 'diff highlight cache clearing' do
+ context 'when diff file is unfolded and it is not a reply' do
+ it 'clears diff highlighting cache' do
+ expect_next_instance_of(DraftNote) do |draft|
+ allow(draft).to receive_message_chain(:diff_file, :unfolded?) { true }
+ end
+
+ expect(merge_request).to receive_message_chain(:diffs, :clear_cache)
+
+ create_draft(note: 'This is a test')
+ end
+ end
+
+ context 'when diff file is not unfolded and it is not a reply' do
+ it 'clears diff highlighting cache' do
+ expect_next_instance_of(DraftNote) do |draft|
+ allow(draft).to receive_message_chain(:diff_file, :unfolded?) { false }
+ end
+
+ expect(merge_request).not_to receive(:diffs)
+
+ create_draft(note: 'This is a test')
+ end
+ end
+ end
+end
diff --git a/spec/services/draft_notes/destroy_service_spec.rb b/spec/services/draft_notes/destroy_service_spec.rb
new file mode 100644
index 00000000000..d0bf88dcdbe
--- /dev/null
+++ b/spec/services/draft_notes/destroy_service_spec.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+describe DraftNotes::DestroyService do
+ let(:merge_request) { create(:merge_request) }
+ let(:project) { merge_request.target_project }
+ let(:user) { merge_request.author }
+
+ def destroy(draft_note = nil)
+ DraftNotes::DestroyService.new(merge_request, user).execute(draft_note)
+ end
+
+ it 'destroys a single draft note' do
+ drafts = create_list(:draft_note, 2, merge_request: merge_request, author: user)
+
+ expect { destroy(drafts.first) }
+ .to change { DraftNote.count }.by(-1)
+
+ expect(DraftNote.count).to eq(1)
+ end
+
+ it 'destroys all draft notes for a user in a merge request' do
+ create_list(:draft_note, 2, merge_request: merge_request, author: user)
+
+ expect { destroy }.to change { DraftNote.count }.by(-2)
+ expect(DraftNote.count).to eq(0)
+ end
+
+ context 'diff highlight cache clearing' do
+ context 'when destroying all draft notes of a user' do
+ it 'clears highlighting cache if unfold required for any' do
+ drafts = create_list(:draft_note, 2, merge_request: merge_request, author: user)
+
+ allow_any_instance_of(DraftNote).to receive_message_chain(:diff_file, :unfolded?) { true }
+ expect(merge_request).to receive_message_chain(:diffs, :clear_cache)
+
+ destroy(drafts.first)
+ end
+ end
+
+ context 'when destroying one draft note' do
+ it 'clears highlighting cache if unfold required' do
+ create_list(:draft_note, 2, merge_request: merge_request, author: user)
+
+ allow_any_instance_of(DraftNote).to receive_message_chain(:diff_file, :unfolded?) { true }
+ expect(merge_request).to receive_message_chain(:diffs, :clear_cache)
+
+ destroy
+ end
+ end
+ end
+end
diff --git a/spec/services/draft_notes/publish_service_spec.rb b/spec/services/draft_notes/publish_service_spec.rb
new file mode 100644
index 00000000000..4ebae2f9aa2
--- /dev/null
+++ b/spec/services/draft_notes/publish_service_spec.rb
@@ -0,0 +1,261 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+describe DraftNotes::PublishService do
+ include RepoHelpers
+
+ let(:merge_request) { create(:merge_request) }
+ let(:project) { merge_request.target_project }
+ let(:user) { merge_request.author }
+ let(:commit) { project.commit(sample_commit.id) }
+
+ let(:position) do
+ Gitlab::Diff::Position.new(
+ old_path: "files/ruby/popen.rb",
+ new_path: "files/ruby/popen.rb",
+ old_line: nil,
+ new_line: 14,
+ diff_refs: commit.diff_refs
+ )
+ end
+
+ def publish(draft: nil)
+ DraftNotes::PublishService.new(merge_request, user).execute(draft)
+ end
+
+ context 'single draft note' do
+ let(:commit_id) { nil }
+ let!(:drafts) { create_list(:draft_note, 2, merge_request: merge_request, author: user, commit_id: commit_id, position: position) }
+
+ it 'publishes' do
+ expect { publish(draft: drafts.first) }.to change { DraftNote.count }.by(-1).and change { Note.count }.by(1)
+ expect(DraftNote.count).to eq(1)
+ 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
+ expect_next_instance_of(NotificationService) do |notification_service|
+ expect(notification_service).to receive(:new_note)
+ end
+
+ result = publish(draft: drafts.first)
+
+ expect(result[:status]).to eq(:success)
+ end
+
+ context 'commit_id is set' do
+ let(:commit_id) { commit.id }
+
+ it 'creates note from draft with commit_id' do
+ result = publish(draft: drafts.first)
+
+ expect(result[:status]).to eq(:success)
+ expect(merge_request.notes.first.commit_id).to eq(commit_id)
+ end
+ end
+ end
+
+ context 'multiple draft notes' do
+ let(:commit_id) { nil }
+
+ before do
+ create(:draft_note, merge_request: merge_request, author: user, note: 'first note', commit_id: commit_id, position: position)
+ create(:draft_note, merge_request: merge_request, author: user, note: 'second note', commit_id: commit_id, position: position)
+ end
+
+ context 'when review fails to create' do
+ before do
+ expect_next_instance_of(Review) do |review|
+ allow(review).to receive(:save!).and_raise(ActiveRecord::RecordInvalid.new(review))
+ end
+ end
+
+ it 'does not publish any draft note' do
+ expect { publish }.not_to change { DraftNote.count }
+ end
+
+ it 'returns an error' do
+ result = publish
+
+ expect(result[:status]).to eq(:error)
+ expect(result[:message]).to match(/Unable to save Review/)
+ end
+ end
+
+ it 'returns success' do
+ result = publish
+
+ expect(result[:status]).to eq(:success)
+ end
+
+ it 'publishes all draft notes for a user in a merge request' do
+ expect { publish }.to change { DraftNote.count }.by(-2).and change { Note.count }.by(2).and change { Review.count }.by(1)
+ expect(DraftNote.count).to eq(0)
+
+ notes = merge_request.notes.order(id: :asc)
+ expect(notes.first.note).to eq('first note')
+ expect(notes.last.note).to eq('second note')
+ end
+
+ it 'sends batch notification' do
+ expect_next_instance_of(NotificationService) do |notification_service|
+ expect(notification_service).to receive_message_chain(:async, :new_review).with(kind_of(Review))
+ end
+
+ publish
+ end
+
+ context 'commit_id is set' do
+ let(:commit_id) { commit.id }
+
+ it 'creates note from draft with commit_id' do
+ result = publish
+
+ expect(result[:status]).to eq(:success)
+
+ merge_request.notes.each do |note|
+ expect(note.commit_id).to eq(commit_id)
+ end
+ end
+ end
+ end
+
+ context 'draft notes with suggestions' do
+ let(:project) { create(:project, :repository) }
+ let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
+
+ let(:suggestion_note) do
+ <<-MARKDOWN.strip_heredoc
+ ```suggestion
+ foo
+ ```
+ MARKDOWN
+ end
+
+ let!(:draft) { create(:draft_note_on_text_diff, note: suggestion_note, merge_request: merge_request, author: user) }
+
+ it 'creates a suggestion with correct content' do
+ expect { publish(draft: draft) }.to change { Suggestion.count }.by(1)
+ .and change { DiffNote.count }.from(0).to(1)
+
+ suggestion = Suggestion.last
+
+ expect(suggestion.from_line).to eq(14)
+ expect(suggestion.to_line).to eq(14)
+ expect(suggestion.from_content).to eq(" vars = {\n")
+ expect(suggestion.to_content).to eq(" foo\n")
+ end
+
+ context 'when the diff is changed' do
+ let(:file_path) { 'files/ruby/popen.rb' }
+ let(:branch_name) { project.default_branch }
+ let(:commit) { project.repository.commit }
+
+ def update_file(file_path, new_content)
+ params = {
+ file_path: file_path,
+ commit_message: "Update File",
+ file_content: new_content,
+ start_project: project,
+ start_branch: project.default_branch,
+ branch_name: branch_name
+ }
+
+ Files::UpdateService.new(project, user, params).execute
+ end
+
+ before do
+ project.add_developer(user)
+ end
+
+ it 'creates a suggestion based on the latest diff content and positions' do
+ diff_file = merge_request.diffs(paths: [file_path]).diff_files.first
+ raw_data = diff_file.new_blob.data
+
+ # Add a line break to the beginning of the file
+ result = update_file(file_path, raw_data.prepend("\n"))
+ oldrev = merge_request.diff_head_sha
+ newrev = result[:result]
+
+ expect(newrev).to be_present
+
+ # Generates new MR revision at DB level
+ refresh = MergeRequests::RefreshService.new(project, user)
+ refresh.execute(oldrev, newrev, merge_request.source_branch_ref)
+
+ expect { publish(draft: draft) }.to change { Suggestion.count }.by(1)
+ .and change { DiffNote.count }.from(0).to(1)
+
+ suggestion = Suggestion.last
+
+ expect(suggestion.from_line).to eq(15)
+ expect(suggestion.to_line).to eq(15)
+ expect(suggestion.from_content).to eq(" vars = {\n")
+ expect(suggestion.to_content).to eq(" foo\n")
+ end
+ end
+ end
+
+ it 'only publishes the draft notes belonging to the current user' do
+ other_user = create(:user)
+ project.add_maintainer(other_user)
+
+ create_list(:draft_note, 2, merge_request: merge_request, author: user)
+ create_list(:draft_note, 2, merge_request: merge_request, author: other_user)
+
+ expect { publish }.to change { DraftNote.count }.by(-2).and change { Note.count }.by(2)
+ expect(DraftNote.count).to eq(2)
+ end
+
+ context 'with quick actions' do
+ it 'performs quick actions' do
+ other_user = create(:user)
+ project.add_developer(other_user)
+
+ create(:draft_note, merge_request: merge_request,
+ author: user,
+ note: "thanks\n/assign #{other_user.to_reference}")
+
+ expect { publish }.to change { DraftNote.count }.by(-1).and change { Note.count }.by(2)
+ expect(merge_request.reload.assignees).to match_array([other_user])
+ expect(merge_request.notes.last).to be_system
+ end
+
+ it 'does not create a note if it only contains quick actions' do
+ create(:draft_note, merge_request: merge_request, author: user, note: "/assign #{user.to_reference}")
+
+ expect { publish }.to change { DraftNote.count }.by(-1).and change { Note.count }.by(1)
+ expect(merge_request.reload.assignees).to eq([user])
+ expect(merge_request.notes.last).to be_system
+ end
+ end
+
+ context 'with drafts that resolve threads' do
+ let!(:note) { create(:discussion_note_on_merge_request, noteable: merge_request, project: project) }
+ let!(:draft_note) { create(:draft_note, merge_request: merge_request, author: user, resolve_discussion: true, discussion_id: note.discussion.reply_id) }
+
+ it 'resolves the thread' do
+ publish(draft: draft_note)
+
+ expect(note.discussion.resolved?).to be true
+ end
+
+ it 'sends notifications if all threads are resolved' do
+ expect_next_instance_of(MergeRequests::ResolvedDiscussionNotificationService) do |instance|
+ expect(instance).to receive(:execute).with(merge_request)
+ end
+
+ publish
+ end
+ end
+
+ context 'user cannot create notes' do
+ before do
+ allow(Ability).to receive(:allowed?).with(user, :create_note, merge_request).and_return(false)
+ end
+
+ it 'returns an error' do
+ expect(publish[:status]).to eq(:error)
+ end
+ end
+end
diff --git a/spec/services/event_create_service_spec.rb b/spec/services/event_create_service_spec.rb
index 987b4ad68f7..73c089334ed 100644
--- a/spec/services/event_create_service_spec.rb
+++ b/spec/services/event_create_service_spec.rb
@@ -5,6 +5,9 @@ require 'spec_helper'
describe EventCreateService do
let(:service) { described_class.new }
+ let_it_be(:user, reload: true) { create :user }
+ let_it_be(:project) { create(:project) }
+
describe 'Issues' do
describe '#open_issue' do
let(:issue) { create(:issue) }
@@ -13,6 +16,7 @@ describe EventCreateService do
it "creates new event" do
expect { service.open_issue(issue, issue.author) }.to change { Event.count }
+ expect { service.open_issue(issue, issue.author) }.to change { ResourceStateEvent.count }
end
end
@@ -23,6 +27,7 @@ describe EventCreateService do
it "creates new event" do
expect { service.close_issue(issue, issue.author) }.to change { Event.count }
+ expect { service.close_issue(issue, issue.author) }.to change { ResourceStateEvent.count }
end
end
@@ -33,6 +38,7 @@ describe EventCreateService do
it "creates new event" do
expect { service.reopen_issue(issue, issue.author) }.to change { Event.count }
+ expect { service.reopen_issue(issue, issue.author) }.to change { ResourceStateEvent.count }
end
end
end
@@ -45,6 +51,7 @@ describe EventCreateService do
it "creates new event" do
expect { service.open_mr(merge_request, merge_request.author) }.to change { Event.count }
+ expect { service.open_mr(merge_request, merge_request.author) }.to change { ResourceStateEvent.count }
end
end
@@ -55,6 +62,7 @@ describe EventCreateService do
it "creates new event" do
expect { service.close_mr(merge_request, merge_request.author) }.to change { Event.count }
+ expect { service.close_mr(merge_request, merge_request.author) }.to change { ResourceStateEvent.count }
end
end
@@ -65,6 +73,7 @@ describe EventCreateService do
it "creates new event" do
expect { service.merge_mr(merge_request, merge_request.author) }.to change { Event.count }
+ expect { service.merge_mr(merge_request, merge_request.author) }.to change { ResourceStateEvent.count }
end
end
@@ -75,13 +84,12 @@ describe EventCreateService do
it "creates new event" do
expect { service.reopen_mr(merge_request, merge_request.author) }.to change { Event.count }
+ expect { service.reopen_mr(merge_request, merge_request.author) }.to change { ResourceStateEvent.count }
end
end
end
describe 'Milestone' do
- let(:user) { create :user }
-
describe '#open_milestone' do
let(:milestone) { create(:milestone) }
@@ -167,7 +175,7 @@ describe EventCreateService do
wiki_page?: true,
valid?: true,
persisted?: true,
- action: action,
+ action: action.to_s,
wiki_page: wiki_page,
author: user
)
@@ -193,7 +201,7 @@ describe EventCreateService do
end
end
- (Event::ACTIONS.values - Event::WIKI_ACTIONS).each do |bad_action|
+ (Event.actions.keys - Event::WIKI_ACTIONS).each do |bad_action|
context "The action is #{bad_action}" do
it 'raises an error' do
expect { service.wiki_event(meta, user, bad_action) }.to raise_error(described_class::IllegalActionError)
@@ -203,9 +211,6 @@ describe EventCreateService do
end
describe '#push', :clean_gitlab_redis_shared_state do
- let(:project) { create(:project) }
- let(:user) { create(:user) }
-
let(:push_data) do
{
commits: [
@@ -227,9 +232,6 @@ describe EventCreateService do
end
describe '#bulk_push', :clean_gitlab_redis_shared_state do
- let(:project) { create(:project) }
- let(:user) { create(:user) }
-
let(:push_data) do
{
action: :created,
@@ -244,9 +246,6 @@ describe EventCreateService do
end
describe 'Project' do
- let(:user) { create :user }
- let(:project) { create(:project) }
-
describe '#join_project' do
subject { service.join_project(project, user) }
@@ -261,4 +260,81 @@ describe EventCreateService do
it { expect { subject }.to change { Event.count }.from(0).to(1) }
end
end
+
+ describe 'design events' do
+ let_it_be(:design) { create(:design, project: project) }
+ let_it_be(:author) { user }
+
+ shared_examples 'feature flag gated multiple event creation' do
+ context 'the feature flag is off' do
+ before do
+ stub_feature_flags(design_activity_events: false)
+ end
+
+ specify { expect(result).to be_empty }
+ specify { expect { result }.not_to change { Event.count } }
+ specify { expect { result }.not_to exceed_query_limit(0) }
+ end
+
+ context 'the feature flag is enabled for a single project' do
+ before do
+ stub_feature_flags(design_activity_events: project)
+ end
+
+ specify { expect(result).not_to be_empty }
+ specify { expect { result }.to change { Event.count }.by(1) }
+ end
+ end
+
+ describe '#save_designs' do
+ let_it_be(:updated) { create_list(:design, 5) }
+ let_it_be(:created) { create_list(:design, 3) }
+
+ let(:result) { service.save_designs(author, create: created, update: updated) }
+
+ specify { expect { result }.to change { Event.count }.by(8) }
+
+ specify { expect { result }.not_to exceed_query_limit(1) }
+
+ it 'creates 3 created design events' do
+ ids = result.pluck('id')
+ events = Event.created_action.where(id: ids)
+
+ expect(events.map(&:design)).to match_array(created)
+ end
+
+ it 'creates 5 created design events' do
+ ids = result.pluck('id')
+ events = Event.updated_action.where(id: ids)
+
+ expect(events.map(&:design)).to match_array(updated)
+ end
+
+ it_behaves_like 'feature flag gated multiple event creation' do
+ let(:project) { created.first.project }
+ end
+ end
+
+ describe '#destroy_designs' do
+ let_it_be(:designs) { create_list(:design, 5) }
+ let_it_be(:author) { create(:user) }
+
+ let(:result) { service.destroy_designs(designs, author) }
+
+ specify { expect { result }.to change { Event.count }.by(5) }
+
+ specify { expect { result }.not_to exceed_query_limit(1) }
+
+ it 'creates 5 destroyed design events' do
+ ids = result.pluck('id')
+ events = Event.destroyed_action.where(id: ids)
+
+ expect(events.map(&:design)).to match_array(designs)
+ end
+
+ it_behaves_like 'feature flag gated multiple event creation' do
+ let(:project) { designs.first.project }
+ end
+ end
+ end
end
diff --git a/spec/services/git/branch_hooks_service_spec.rb b/spec/services/git/branch_hooks_service_spec.rb
index ae0506ad442..908b9772c40 100644
--- a/spec/services/git/branch_hooks_service_spec.rb
+++ b/spec/services/git/branch_hooks_service_spec.rb
@@ -91,7 +91,7 @@ describe Git::BranchHooksService do
end
describe 'Push Event' do
- let(:event) { Event.find_by_action(Event::PUSHED) }
+ let(:event) { Event.pushed_action.first }
before do
service.execute
@@ -101,7 +101,7 @@ describe Git::BranchHooksService do
it 'generates a push event with one commit' do
expect(event).to be_an_instance_of(PushEvent)
expect(event.project).to eq(project)
- expect(event.action).to eq(Event::PUSHED)
+ expect(event).to be_pushed_action
expect(event.push_event_payload).to be_an_instance_of(PushEventPayload)
expect(event.push_event_payload.commit_from).to eq(oldrev)
expect(event.push_event_payload.commit_to).to eq(newrev)
@@ -117,7 +117,7 @@ describe Git::BranchHooksService do
it 'generates a push event with more than one commit' do
expect(event).to be_an_instance_of(PushEvent)
expect(event.project).to eq(project)
- expect(event.action).to eq(Event::PUSHED)
+ expect(event).to be_pushed_action
expect(event.push_event_payload).to be_an_instance_of(PushEventPayload)
expect(event.push_event_payload.commit_from).to be_nil
expect(event.push_event_payload.commit_to).to eq(newrev)
@@ -133,7 +133,7 @@ describe Git::BranchHooksService do
it 'generates a push event with no commits' do
expect(event).to be_an_instance_of(PushEvent)
expect(event.project).to eq(project)
- expect(event.action).to eq(Event::PUSHED)
+ expect(event).to be_pushed_action
expect(event.push_event_payload).to be_an_instance_of(PushEventPayload)
expect(event.push_event_payload.commit_from).to eq(oldrev)
expect(event.push_event_payload.commit_to).to be_nil
diff --git a/spec/services/git/wiki_push_service/change_spec.rb b/spec/services/git/wiki_push_service/change_spec.rb
index 547874270ab..4da3f0fc738 100644
--- a/spec/services/git/wiki_push_service/change_spec.rb
+++ b/spec/services/git/wiki_push_service/change_spec.rb
@@ -89,20 +89,20 @@ describe Git::WikiPushService::Change do
context 'the page is deleted' do
let(:operation) { :deleted }
- it { is_expected.to have_attributes(event_action: Event::DESTROYED) }
+ it { is_expected.to have_attributes(event_action: :destroyed) }
end
context 'the page is added' do
let(:operation) { :added }
- it { is_expected.to have_attributes(event_action: Event::CREATED) }
+ it { is_expected.to have_attributes(event_action: :created) }
end
%i[renamed modified].each do |op|
context "the page is #{op}" do
let(:operation) { op }
- it { is_expected.to have_attributes(event_action: Event::UPDATED) }
+ it { is_expected.to have_attributes(event_action: :updated) }
end
end
end
diff --git a/spec/services/git/wiki_push_service_spec.rb b/spec/services/git/wiki_push_service_spec.rb
index cdb1dc5a435..b2234c81c24 100644
--- a/spec/services/git/wiki_push_service_spec.rb
+++ b/spec/services/git/wiki_push_service_spec.rb
@@ -54,7 +54,7 @@ describe Git::WikiPushService, services: true do
it 'handles all known actions' do
run_service
- expect(Event.last(count).pluck(:action)).to match_array(Event::WIKI_ACTIONS)
+ expect(Event.last(count).pluck(:action)).to match_array(Event::WIKI_ACTIONS.map(&:to_s))
end
end
@@ -77,7 +77,7 @@ describe Git::WikiPushService, services: true do
it 'creates appropriate events' do
run_service
- expect(Event.last(2)).to all(have_attributes(wiki_page?: true, action: Event::CREATED))
+ expect(Event.last(2)).to all(have_attributes(wiki_page?: true, action: 'created'))
end
end
@@ -100,7 +100,7 @@ describe Git::WikiPushService, services: true do
it 'creates a wiki page creation event' do
expect { run_service }.to change(Event, :count).by(1)
- expect(Event.last).to have_attributes(wiki_page?: true, action: Event::CREATED)
+ expect(Event.last).to have_attributes(wiki_page?: true, action: 'created')
end
it 'creates one metadata record' do
@@ -129,7 +129,7 @@ describe Git::WikiPushService, services: true do
expect(Event.last).to have_attributes(
wiki_page?: true,
- action: Event::CREATED
+ action: 'created'
)
end
end
@@ -158,7 +158,7 @@ describe Git::WikiPushService, services: true do
expect(Event.last).to have_attributes(
wiki_page?: true,
- action: Event::UPDATED
+ action: 'updated'
)
end
end
@@ -182,7 +182,7 @@ describe Git::WikiPushService, services: true do
expect(Event.last).to have_attributes(
wiki_page?: true,
- action: Event::UPDATED
+ action: 'updated'
)
end
end
@@ -206,7 +206,7 @@ describe Git::WikiPushService, services: true do
expect(Event.last).to have_attributes(
wiki_page?: true,
- action: Event::DESTROYED
+ action: 'destroyed'
)
end
end
@@ -218,7 +218,7 @@ describe Git::WikiPushService, services: true do
message = 'something went very very wrong'
allow_next_instance_of(WikiPages::EventCreateService, current_user) do |service|
allow(service).to receive(:execute)
- .with(String, WikiPage, Integer)
+ .with(String, WikiPage, Symbol)
.and_return(ServiceResponse.error(message: message))
end
diff --git a/spec/services/groups/group_links/destroy_service_spec.rb b/spec/services/groups/group_links/destroy_service_spec.rb
index 284bcd0df2e..8989f024262 100644
--- a/spec/services/groups/group_links/destroy_service_spec.rb
+++ b/spec/services/groups/group_links/destroy_service_spec.rb
@@ -8,14 +8,20 @@ describe Groups::GroupLinks::DestroyService, '#execute' do
let_it_be(:group) { create(:group, :private) }
let_it_be(:shared_group) { create(:group, :private) }
let_it_be(:project) { create(:project, group: shared_group) }
+ let_it_be(:owner) { create(:user) }
- subject { described_class.new(nil, nil) }
+ before do
+ group.add_developer(owner)
+ shared_group.add_owner(owner)
+ end
+
+ subject { described_class.new(shared_group, owner) }
context 'single link' do
let!(:link) { create(:group_group_link, shared_group: shared_group, shared_with_group: group) }
it 'destroys link' do
- expect { subject.execute(link) }.to change { GroupGroupLink.count }.from(1).to(0)
+ expect { subject.execute(link) }.to change { shared_group.shared_with_group_links.count }.from(1).to(0)
end
it 'revokes project authorization' do
diff --git a/spec/services/groups/import_export/export_service_spec.rb b/spec/services/groups/import_export/export_service_spec.rb
index 7bad68b4e00..ea49b26cc7c 100644
--- a/spec/services/groups/import_export/export_service_spec.rb
+++ b/spec/services/groups/import_export/export_service_spec.rb
@@ -103,12 +103,14 @@ describe Groups::ImportExport::ExportService do
end
it 'logs the error' do
- expect(shared.logger).to receive(:error).with(
- group_id: group.id,
- group_name: group.name,
- error: expected_message,
- message: 'Group Import/Export: Export failed'
- )
+ expect_next_instance_of(Gitlab::Export::Logger) do |logger|
+ expect(logger).to receive(:error).with(
+ group_id: group.id,
+ group_name: group.name,
+ errors: expected_message,
+ message: 'Group Export failed'
+ )
+ end
expect { service.execute }.to raise_error(Gitlab::ImportExport::Error)
end
@@ -132,7 +134,7 @@ describe Groups::ImportExport::ExportService do
expect { service.execute }.to raise_error(Gitlab::ImportExport::Error)
expect(group.import_export_upload).to be_nil
- expect(File.exist?(shared.archive_path)).to eq(false)
+ expect(Dir.exist?(shared.base_path)).to eq(false)
end
it 'notifies the user about failed group export' do
@@ -157,12 +159,13 @@ describe Groups::ImportExport::ExportService do
expect { service.execute }.to raise_error(Gitlab::ImportExport::Error)
expect(group.import_export_upload).to be_nil
- expect(File.exist?(shared.archive_path)).to eq(false)
+ expect(Dir.exist?(shared.base_path)).to eq(false)
end
it 'notifies logger' do
allow(service).to receive_message_chain(:tree_exporter, :save).and_return(false)
- expect(shared.logger).to receive(:error)
+
+ expect(service.instance_variable_get(:@logger)).to receive(:error)
expect { service.execute }.to raise_error(Gitlab::ImportExport::Error)
end
diff --git a/spec/services/groups/import_export/import_service_spec.rb b/spec/services/groups/import_export/import_service_spec.rb
index 256e0a1b3c5..1f7eaccbdbd 100644
--- a/spec/services/groups/import_export/import_service_spec.rb
+++ b/spec/services/groups/import_export/import_service_spec.rb
@@ -3,6 +3,47 @@
require 'spec_helper'
describe Groups::ImportExport::ImportService do
+ describe '#async_execute' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+
+ context 'when the job can be successfully scheduled' do
+ subject(:import_service) { described_class.new(group: group, user: user) }
+
+ it 'enqueues an import job' do
+ expect(GroupImportWorker).to receive(:perform_async).with(user.id, group.id)
+
+ import_service.async_execute
+ end
+
+ it 'marks the group import as in progress' do
+ import_service.async_execute
+
+ expect(group.import_state.in_progress?).to eq true
+ end
+
+ it 'returns truthy' do
+ expect(import_service.async_execute).to be_truthy
+ end
+ end
+
+ context 'when the job cannot be scheduled' do
+ subject(:import_service) { described_class.new(group: group, user: user) }
+
+ before do
+ allow(GroupImportWorker).to receive(:perform_async).and_return(nil)
+ end
+
+ it 'returns falsey' do
+ expect(import_service.async_execute).to be_falsey
+ end
+
+ it 'does not mark the group import as created' do
+ expect { import_service.async_execute }.not_to change { group.import_state }
+ end
+ end
+ end
+
context 'with group_import_ndjson feature flag disabled' do
let(:user) { create(:admin) }
let(:group) { create(:group) }
@@ -60,6 +101,7 @@ describe Groups::ImportExport::ImportService do
allow(Gitlab::Import::Logger).to receive(:build).and_return(import_logger)
allow(import_logger).to receive(:error)
allow(import_logger).to receive(:info)
+ allow(FileUtils).to receive(:rm_rf).and_call_original
end
context 'when user has correct permissions' do
@@ -73,6 +115,16 @@ describe Groups::ImportExport::ImportService do
expect(group.import_export_upload.import_file.file).to be_nil
end
+ it 'removes tmp files' do
+ shared = Gitlab::ImportExport::Shared.new(group)
+ allow(Gitlab::ImportExport::Shared).to receive(:new).and_return(shared)
+
+ subject
+
+ expect(FileUtils).to have_received(:rm_rf).with(shared.base_path)
+ expect(Dir.exist?(shared.base_path)).to eq(false)
+ end
+
it 'logs the import success' do
expect(import_logger).to receive(:info).with(
group_id: group.id,
@@ -160,6 +212,7 @@ describe Groups::ImportExport::ImportService do
allow(Gitlab::Import::Logger).to receive(:build).and_return(import_logger)
allow(import_logger).to receive(:error)
allow(import_logger).to receive(:info)
+ allow(FileUtils).to receive(:rm_rf).and_call_original
end
context 'when user has correct permissions' do
@@ -173,6 +226,16 @@ describe Groups::ImportExport::ImportService do
expect(group.import_export_upload.import_file.file).to be_nil
end
+ it 'removes tmp files' do
+ shared = Gitlab::ImportExport::Shared.new(group)
+ allow(Gitlab::ImportExport::Shared).to receive(:new).and_return(shared)
+
+ subject
+
+ expect(FileUtils).to have_received(:rm_rf).with(shared.base_path)
+ expect(Dir.exist?(shared.base_path)).to eq(false)
+ end
+
it 'logs the import success' do
expect(import_logger).to receive(:info).with(
group_id: group.id,
diff --git a/spec/services/groups/transfer_service_spec.rb b/spec/services/groups/transfer_service_spec.rb
index bbf5bbbf814..d7f6bececfe 100644
--- a/spec/services/groups/transfer_service_spec.rb
+++ b/spec/services/groups/transfer_service_spec.rb
@@ -216,6 +216,15 @@ describe Groups::TransferService do
end
end
+ context 'when a group is transferred to its subgroup' do
+ let(:new_parent_group) { create(:group, parent: group) }
+
+ it 'does not execute the transfer' do
+ expect(transfer_service.execute(new_parent_group)).to be_falsy
+ expect(transfer_service.error).to match(/Cannot transfer group to one of its subgroup/)
+ end
+ end
+
context 'when transferring a group with group descendants' do
let!(:subgroup1) { create(:group, :private, parent: group) }
let!(:subgroup2) { create(:group, :internal, parent: group) }
diff --git a/spec/services/import/github_service_spec.rb b/spec/services/import/github_service_spec.rb
new file mode 100644
index 00000000000..461b17e0e33
--- /dev/null
+++ b/spec/services/import/github_service_spec.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Import::GithubService do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:token) { 'complex-token' }
+ let_it_be(:access_params) { { github_access_token: 'github-complex-token' } }
+ let_it_be(:client) { Gitlab::LegacyGithubImport::Client.new(token) }
+ let_it_be(:params) { { repo_id: 123, new_name: 'new_repo', target_namespace: 'root' } }
+
+ let(:subject) { described_class.new(client, user, params) }
+
+ before do
+ allow(subject).to receive(:authorized?).and_return(true)
+ end
+
+ context 'do not raise an exception on input error' do
+ let(:exception) { Octokit::ClientError.new(status: 404, body: 'Not Found') }
+
+ before do
+ expect(client).to receive(:repo).and_raise(exception)
+ end
+
+ it 'logs the original error' do
+ expect(Gitlab::Import::Logger).to receive(:error).with({
+ message: 'Import failed due to a GitHub error',
+ status: 404,
+ error: 'Not Found'
+ }).and_call_original
+
+ subject.execute(access_params, :github)
+ end
+
+ it 'returns an error' do
+ result = subject.execute(access_params, :github)
+
+ expect(result).to include(
+ message: 'Import failed due to a GitHub error: Not Found',
+ status: :error,
+ http_status: :unprocessable_entity
+ )
+ end
+ end
+
+ it 'raises an exception for unknown error causes' do
+ exception = StandardError.new('Not Implemented')
+
+ expect(client).to receive(:repo).and_raise(exception)
+
+ expect(Gitlab::Import::Logger).not_to receive(:error)
+
+ expect { subject.execute(access_params, :github) }.to raise_error(exception)
+ end
+end
diff --git a/spec/services/integrations/test/project_service_spec.rb b/spec/services/integrations/test/project_service_spec.rb
new file mode 100644
index 00000000000..fdb43ca345a
--- /dev/null
+++ b/spec/services/integrations/test/project_service_spec.rb
@@ -0,0 +1,195 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Integrations::Test::ProjectService do
+ let(:user) { double('user') }
+
+ describe '#execute' do
+ let(:project) { create(:project) }
+ let(:integration) { create(:slack_service, project: project) }
+ let(:event) { nil }
+ let(:sample_data) { { data: 'sample' } }
+ let(:success_result) { { success: true, result: {} } }
+
+ subject { described_class.new(integration, user, event).execute }
+
+ context 'without event specified' do
+ it 'tests the integration with default data' do
+ allow(Gitlab::DataBuilder::Push).to receive(:build_sample).and_return(sample_data)
+
+ expect(integration).to receive(:test).with(sample_data).and_return(success_result)
+ expect(subject).to eq(success_result)
+ end
+
+ context 'PipelinesEmailService' do
+ let(:integration) { create(:pipelines_email_service, project: project) }
+
+ it_behaves_like 'tests for integration with pipeline data'
+ end
+ end
+
+ context 'with event specified' do
+ context 'event not supported by integration' do
+ let(:integration) { create(:jira_service, project: project) }
+ let(:event) { 'push' }
+
+ it 'returns error message' do
+ expect(subject).to include({ status: :error, message: 'Testing not available for this event' })
+ end
+ end
+
+ context 'push' do
+ let(:event) { 'push' }
+
+ it 'executes integration' do
+ allow(Gitlab::DataBuilder::Push).to receive(:build_sample).and_return(sample_data)
+
+ expect(integration).to receive(:test).with(sample_data).and_return(success_result)
+ expect(subject).to eq(success_result)
+ end
+ end
+
+ context 'tag_push' do
+ let(:event) { 'tag_push' }
+
+ it 'executes integration' do
+ allow(Gitlab::DataBuilder::Push).to receive(:build_sample).and_return(sample_data)
+
+ expect(integration).to receive(:test).with(sample_data).and_return(success_result)
+ expect(subject).to eq(success_result)
+ end
+ end
+
+ context 'note' do
+ let(:event) { 'note' }
+
+ it 'returns error message if not enough data' do
+ expect(integration).not_to receive(:test)
+ expect(subject).to include({ status: :error, message: 'Ensure the project has notes.' })
+ end
+
+ it 'executes integration' do
+ allow(project).to receive(:notes).and_return([Note.new])
+ allow(Gitlab::DataBuilder::Note).to receive(:build).and_return(sample_data)
+
+ expect(integration).to receive(:test).with(sample_data).and_return(success_result)
+ expect(subject).to eq(success_result)
+ end
+ end
+
+ context 'issue' do
+ let(:event) { 'issue' }
+ let(:issue) { build(:issue) }
+
+ it 'returns error message if not enough data' do
+ expect(integration).not_to receive(:test)
+ expect(subject).to include({ status: :error, message: 'Ensure the project has issues.' })
+ end
+
+ it 'executes integration' do
+ allow(project).to receive(:issues).and_return([issue])
+ allow(issue).to receive(:to_hook_data).and_return(sample_data)
+
+ expect(integration).to receive(:test).with(sample_data).and_return(success_result)
+ expect(subject).to eq(success_result)
+ end
+ end
+
+ context 'confidential_issue' do
+ let(:event) { 'confidential_issue' }
+ let(:issue) { build(:issue) }
+
+ it 'returns error message if not enough data' do
+ expect(integration).not_to receive(:test)
+ expect(subject).to include({ status: :error, message: 'Ensure the project has issues.' })
+ end
+
+ it 'executes integration' do
+ allow(project).to receive(:issues).and_return([issue])
+ allow(issue).to receive(:to_hook_data).and_return(sample_data)
+
+ expect(integration).to receive(:test).with(sample_data).and_return(success_result)
+ expect(subject).to eq(success_result)
+ end
+ end
+
+ context 'merge_request' do
+ let(:event) { 'merge_request' }
+
+ it 'returns error message if not enough data' do
+ expect(integration).not_to receive(:test)
+ expect(subject).to include({ status: :error, message: 'Ensure the project has merge requests.' })
+ end
+
+ it 'executes integration' do
+ create(:merge_request, source_project: project)
+ allow_any_instance_of(MergeRequest).to receive(:to_hook_data).and_return(sample_data)
+
+ expect(integration).to receive(:test).with(sample_data).and_return(success_result)
+ expect(subject).to eq(success_result)
+ end
+ end
+
+ context 'deployment' do
+ let(:project) { create(:project, :test_repo) }
+ let(:event) { 'deployment' }
+
+ it 'returns error message if not enough data' do
+ expect(integration).not_to receive(:test)
+ expect(subject).to include({ status: :error, message: 'Ensure the project has deployments.' })
+ end
+
+ it 'executes integration' do
+ create(:deployment, project: project)
+ allow(Gitlab::DataBuilder::Deployment).to receive(:build).and_return(sample_data)
+
+ expect(integration).to receive(:test).with(sample_data).and_return(success_result)
+ expect(subject).to eq(success_result)
+ end
+ end
+
+ context 'pipeline' do
+ let(:event) { 'pipeline' }
+
+ it 'returns error message if not enough data' do
+ expect(integration).not_to receive(:test)
+ expect(subject).to include({ status: :error, message: 'Ensure the project has CI pipelines.' })
+ end
+
+ it 'executes integration' do
+ create(:ci_empty_pipeline, project: project)
+ allow(Gitlab::DataBuilder::Pipeline).to receive(:build).and_return(sample_data)
+
+ expect(integration).to receive(:test).with(sample_data).and_return(success_result)
+ expect(subject).to eq(success_result)
+ end
+ end
+
+ context 'wiki_page' do
+ let(:project) { create(:project, :wiki_repo) }
+ let(:event) { 'wiki_page' }
+
+ it 'returns error message if wiki disabled' do
+ allow(project).to receive(:wiki_enabled?).and_return(false)
+
+ expect(integration).not_to receive(:test)
+ expect(subject).to include({ status: :error, message: 'Ensure the wiki is enabled and has pages.' })
+ end
+
+ it 'returns error message if not enough data' do
+ expect(integration).not_to receive(:test)
+ expect(subject).to include({ status: :error, message: 'Ensure the wiki is enabled and has pages.' })
+ end
+
+ it 'executes integration' do
+ create(:wiki_page, wiki: project.wiki)
+ allow(Gitlab::DataBuilder::WikiPage).to receive(:build).and_return(sample_data)
+
+ expect(integration).to receive(:test).with(sample_data).and_return(success_result)
+ expect(subject).to eq(success_result)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/issuable/bulk_update_service_spec.rb b/spec/services/issuable/bulk_update_service_spec.rb
index f82a3cee1d9..c791c454d70 100644
--- a/spec/services/issuable/bulk_update_service_spec.rb
+++ b/spec/services/issuable/bulk_update_service_spec.rb
@@ -42,13 +42,11 @@ describe Issuable::BulkUpdateService do
let(:issue_no_labels) { create(:issue, project: project) }
let(:issues) { [issue_all_labels, issue_bug_and_regression, issue_bug_and_merge_requests, issue_no_labels] }
- let(:labels) { [] }
let(:add_labels) { [] }
let(:remove_labels) { [] }
let(:bulk_update_params) do
{
- label_ids: labels.map(&:id),
add_label_ids: add_labels.map(&:id),
remove_label_ids: remove_labels.map(&:id)
}
@@ -58,27 +56,6 @@ describe Issuable::BulkUpdateService do
bulk_update(issues, bulk_update_params)
end
- context 'when label_ids are passed' do
- let(:issues) { [issue_all_labels, issue_no_labels] }
- let(:labels) { [bug, regression] }
-
- it 'updates the labels of all issues passed to the labels passed' do
- expect(issues.map(&:reload).map(&:label_ids)).to all(match_array(labels.map(&:id)))
- end
-
- it 'does not update issues not passed in' do
- expect(issue_bug_and_regression.label_ids).to contain_exactly(bug.id, regression.id)
- end
-
- context 'when those label IDs are empty' do
- let(:labels) { [] }
-
- it 'updates the issues passed to have no labels' do
- expect(issues.map(&:reload).map(&:label_ids)).to all(be_empty)
- end
- end
- end
-
context 'when add_label_ids are passed' do
let(:issues) { [issue_all_labels, issue_bug_and_merge_requests, issue_no_labels] }
let(:add_labels) { [bug, regression, merge_requests] }
@@ -122,69 +99,21 @@ describe Issuable::BulkUpdateService do
expect(issue_bug_and_regression.label_ids).to contain_exactly(bug.id, regression.id)
end
end
+ end
- context 'when add_label_ids and label_ids are passed' do
- let(:issues) { [issue_all_labels, issue_bug_and_regression, issue_bug_and_merge_requests] }
- let(:labels) { [merge_requests] }
- let(:add_labels) { [regression] }
-
- it 'adds the label IDs to all issues passed' do
- expect(issues.map(&:reload).map(&:label_ids)).to all(include(regression.id))
- end
-
- it 'ignores the label IDs parameter' do
- expect(issues.map(&:reload).map(&:label_ids)).to all(include(bug.id))
- end
-
- it 'does not update issues not passed in' do
- expect(issue_no_labels.label_ids).to be_empty
- end
- end
-
- context 'when remove_label_ids and label_ids are passed' do
- let(:issues) { [issue_no_labels, issue_bug_and_regression] }
- let(:labels) { [merge_requests] }
- let(:remove_labels) { [regression] }
-
- it 'removes the label IDs from all issues passed' do
- expect(issues.map(&:reload).flat_map(&:label_ids)).not_to include(regression.id)
- end
-
- it 'ignores the label IDs parameter' do
- expect(issues.map(&:reload).flat_map(&:label_ids)).not_to include(merge_requests.id)
- end
-
- it 'does not update issues not passed in' do
- expect(issue_all_labels.label_ids).to contain_exactly(bug.id, regression.id, merge_requests.id)
- end
- end
-
- context 'when add_label_ids, remove_label_ids, and label_ids are passed' do
- let(:issues) { [issue_bug_and_merge_requests, issue_no_labels] }
- let(:labels) { [regression] }
- let(:add_labels) { [bug] }
- let(:remove_labels) { [merge_requests] }
-
- it 'adds the label IDs to all issues passed' do
- expect(issues.map(&:reload).map(&:label_ids)).to all(include(bug.id))
- end
+ context 'with issuables at a project level' do
+ let(:parent) { project }
- it 'removes the label IDs from all issues passed' do
- expect(issues.map(&:reload).flat_map(&:label_ids)).not_to include(merge_requests.id)
- end
+ context 'with unpermitted attributes' do
+ let(:issues) { create_list(:issue, 2, project: project) }
+ let(:label) { create(:label, project: project) }
- it 'ignores the label IDs parameter' do
- expect(issues.map(&:reload).flat_map(&:label_ids)).not_to include(regression.id)
- end
+ it 'does not update the issues' do
+ bulk_update(issues, label_ids: [label.id])
- it 'does not update issues not passed in' do
- expect(issue_bug_and_regression.label_ids).to contain_exactly(bug.id, regression.id)
+ expect(issues.map(&:reload).map(&:label_ids)).not_to include(label.id)
end
end
- end
-
- context 'with issuables at a project level' do
- let(:parent) { project }
describe 'close issues' do
let(:issues) { create_list(:issue, 2, project: project) }
diff --git a/spec/services/issues/close_service_spec.rb b/spec/services/issues/close_service_spec.rb
index 6fc1928d47b..78eba565de4 100644
--- a/spec/services/issues/close_service_spec.rb
+++ b/spec/services/issues/close_service_spec.rb
@@ -224,11 +224,26 @@ describe Issues::CloseService do
expect(email.subject).to include(issue.title)
end
- it 'creates system note about issue reassign' do
- close_issue
+ context 'when resource state events are disabled' do
+ before do
+ stub_feature_flags(track_resource_state_change_events: false)
+ end
+
+ it 'creates system note about the issue being closed' do
+ close_issue
+
+ note = issue.notes.last
+ expect(note.note).to include "closed"
+ end
+ end
- note = issue.notes.last
- expect(note.note).to include "closed"
+ context 'when resource state events are enabled' do
+ it 'creates resource state event about the issue being closed' do
+ close_issue
+
+ event = issue.resource_state_events.last
+ expect(event.state).to eq('closed')
+ end
end
it 'marks todos as done' do
diff --git a/spec/services/issues/create_service_spec.rb b/spec/services/issues/create_service_spec.rb
index 7a251e03e51..bb02941576a 100644
--- a/spec/services/issues/create_service_spec.rb
+++ b/spec/services/issues/create_service_spec.rb
@@ -458,7 +458,7 @@ describe Issues::CreateService do
context 'when SpamVerdictService requires reCAPTCHA' do
before do
expect_next_instance_of(Spam::SpamVerdictService) do |verdict_service|
- expect(verdict_service).to receive(:execute).and_return(REQUIRE_RECAPTCHA)
+ expect(verdict_service).to receive(:execute).and_return(CONDITIONAL_ALLOW)
end
end
diff --git a/spec/services/issues/import_csv_service_spec.rb b/spec/services/issues/import_csv_service_spec.rb
index aa43892a36d..92b88489af9 100644
--- a/spec/services/issues/import_csv_service_spec.rb
+++ b/spec/services/issues/import_csv_service_spec.rb
@@ -18,9 +18,7 @@ describe Issues::ImportCsvService do
let(:file) { fixture_file_upload('spec/fixtures/banana_sample.gif') }
it 'returns invalid file error' do
- expect_next_instance_of(Notify) do |instance|
- expect(instance).to receive(:import_issues_csv_email)
- end
+ expect(Notify).to receive_message_chain(:import_issues_csv_email, :deliver_later)
expect(subject[:success]).to eq(0)
expect(subject[:parse_error]).to eq(true)
@@ -31,9 +29,7 @@ describe Issues::ImportCsvService do
let(:file) { fixture_file_upload('spec/fixtures/csv_gitlab_export.csv') }
it 'imports the CSV without errors' do
- expect_next_instance_of(Notify) do |instance|
- expect(instance).to receive(:import_issues_csv_email)
- end
+ expect(Notify).to receive_message_chain(:import_issues_csv_email, :deliver_later)
expect(subject[:success]).to eq(4)
expect(subject[:error_lines]).to eq([])
@@ -54,9 +50,7 @@ describe Issues::ImportCsvService do
let(:file) { fixture_file_upload('spec/fixtures/csv_comma.csv') }
it 'imports CSV without errors' do
- expect_next_instance_of(Notify) do |instance|
- expect(instance).to receive(:import_issues_csv_email)
- end
+ expect(Notify).to receive_message_chain(:import_issues_csv_email, :deliver_later)
expect(subject[:success]).to eq(3)
expect(subject[:error_lines]).to eq([])
@@ -77,9 +71,7 @@ describe Issues::ImportCsvService do
let(:file) { fixture_file_upload('spec/fixtures/csv_tab.csv') }
it 'imports CSV with some error rows' do
- expect_next_instance_of(Notify) do |instance|
- expect(instance).to receive(:import_issues_csv_email)
- end
+ expect(Notify).to receive_message_chain(:import_issues_csv_email, :deliver_later)
expect(subject[:success]).to eq(2)
expect(subject[:error_lines]).to eq([3])
@@ -100,9 +92,7 @@ describe Issues::ImportCsvService do
let(:file) { fixture_file_upload('spec/fixtures/csv_semicolon.csv') }
it 'imports CSV with a blank row' do
- expect_next_instance_of(Notify) do |instance|
- expect(instance).to receive(:import_issues_csv_email)
- end
+ expect(Notify).to receive_message_chain(:import_issues_csv_email, :deliver_later)
expect(subject[:success]).to eq(3)
expect(subject[:error_lines]).to eq([4])
diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb
index 80039049bc3..33ae2682d01 100644
--- a/spec/services/issues/update_service_spec.rb
+++ b/spec/services/issues/update_service_spec.rb
@@ -3,13 +3,13 @@
require 'spec_helper'
describe Issues::UpdateService, :mailer do
- let(:user) { create(:user) }
- let(:user2) { create(:user) }
- let(:user3) { create(:user) }
- let(:group) { create(:group, :public) }
- let(:project) { create(:project, :repository, group: group) }
- let(:label) { create(:label, project: project) }
- let(:label2) { create(:label) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:user2) { create(:user) }
+ let_it_be(:user3) { create(:user) }
+ let_it_be(:group) { create(:group, :public) }
+ let_it_be(:project, reload: true) { create(:project, :repository, group: group) }
+ let_it_be(:label) { create(:label, project: project) }
+ let_it_be(:label2) { create(:label, project: project) }
let(:issue) do
create(:issue, title: 'Old title',
@@ -19,7 +19,7 @@ describe Issues::UpdateService, :mailer do
author: create(:user))
end
- before do
+ before_all do
project.add_maintainer(user)
project.add_developer(user2)
project.add_developer(user3)
@@ -669,28 +669,24 @@ describe Issues::UpdateService, :mailer do
context 'when add_label_ids and label_ids are passed' do
let(:params) { { label_ids: [label.id], add_label_ids: [label3.id] } }
- it 'ignores the label_ids parameter' do
- expect(result.label_ids).not_to include(label.id)
+ before do
+ issue.update(labels: [label2])
end
- it 'adds the passed labels' do
- expect(result.label_ids).to include(label3.id)
+ it 'replaces the labels with the ones in label_ids and adds those in add_label_ids' do
+ expect(result.label_ids).to contain_exactly(label.id, label3.id)
end
end
context 'when remove_label_ids and label_ids are passed' do
- let(:params) { { label_ids: [], remove_label_ids: [label.id] } }
+ let(:params) { { label_ids: [label.id, label2.id, label3.id], remove_label_ids: [label.id] } }
before do
issue.update(labels: [label, label3])
end
- it 'ignores the label_ids parameter' do
- expect(result.label_ids).not_to be_empty
- end
-
- it 'removes the passed labels' do
- expect(result.label_ids).not_to include(label.id)
+ it 'replaces the labels with the ones in label_ids and removes those in remove_label_ids' do
+ expect(result.label_ids).to contain_exactly(label2.id, label3.id)
end
end
diff --git a/spec/services/jira/requests/projects_spec.rb b/spec/services/jira/requests/projects_spec.rb
new file mode 100644
index 00000000000..f7b9aa7c00c
--- /dev/null
+++ b/spec/services/jira/requests/projects_spec.rb
@@ -0,0 +1,95 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Jira::Requests::Projects do
+ let(:jira_service) { create(:jira_service) }
+ let(:params) { {} }
+
+ describe '#execute' do
+ let(:service) { described_class.new(jira_service, params) }
+
+ subject { service.execute }
+
+ context 'without jira_service' do
+ before do
+ jira_service.update!(active: false)
+ end
+
+ it 'returns an error response' do
+ expect(subject.error?).to be_truthy
+ expect(subject.message).to eq('Jira service not configured.')
+ end
+ end
+
+ context 'when jira_service is nil' do
+ let(:jira_service) { nil }
+
+ it 'returns an error response' do
+ expect(subject.error?).to be_truthy
+ expect(subject.message).to eq('Jira service not configured.')
+ end
+ end
+
+ context 'with jira_service' do
+ context 'when limit is invalid' do
+ let(:params) { { limit: 0 } }
+
+ it 'returns a paylod with no projects returned' do
+ expect(subject.payload[:projects]).to be_empty
+ end
+ end
+
+ context 'when validations and params are ok' do
+ let(:client) { double(options: { site: 'https://jira.example.com' }) }
+
+ before do
+ expect(service).to receive(:client).at_least(:once).and_return(client)
+ end
+
+ context 'when the request to Jira returns an error' do
+ before do
+ expect(client).to receive(:get).and_raise(Timeout::Error)
+ end
+
+ it 'returns an error response' do
+ expect(subject.error?).to be_truthy
+ expect(subject.message).to eq('Jira request error: Timeout::Error')
+ end
+ end
+
+ context 'when the request does not return any values' do
+ before do
+ expect(client).to receive(:get).and_return({ 'someKey' => 'value' })
+ end
+
+ it 'returns a paylod with no projects returned' do
+ payload = subject.payload
+
+ expect(subject.success?).to be_truthy
+ expect(payload[:projects]).to be_empty
+ expect(payload[:is_last]).to be_truthy
+ end
+ end
+
+ context 'when the request returns values' do
+ before do
+ expect(client).to receive(:get).and_return(
+ { 'values' => %w(project1 project2), 'isLast' => false }
+ )
+ expect(JIRA::Resource::Project).to receive(:build).with(client, 'project1').and_return('jira_project1')
+ expect(JIRA::Resource::Project).to receive(:build).with(client, 'project2').and_return('jira_project2')
+ end
+
+ it 'returns a paylod with jira projets' do
+ payload = subject.payload
+
+ expect(subject.success?).to be_truthy
+ expect(payload[:projects]).to eq(%w(jira_project1 jira_project2))
+ expect(payload[:is_last]).to be_falsey
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/jira_import/start_import_service_spec.rb b/spec/services/jira_import/start_import_service_spec.rb
index 759e4f3363f..9dc8cdb1475 100644
--- a/spec/services/jira_import/start_import_service_spec.rb
+++ b/spec/services/jira_import/start_import_service_spec.rb
@@ -13,7 +13,7 @@ describe JiraImport::StartImportService do
context 'when an error is returned from the project validation' do
before do
- allow(project).to receive(:validate_jira_import_settings!)
+ allow(Gitlab::JiraImport).to receive(:validate_project_settings!)
.and_raise(Projects::ImportService::Error, 'Jira import feature is disabled.')
end
@@ -25,7 +25,7 @@ describe JiraImport::StartImportService do
before do
stub_jira_service_test
- allow(project).to receive(:validate_jira_import_settings!)
+ allow(Gitlab::JiraImport).to receive(:validate_project_settings!)
end
context 'when Jira project key is not provided' do
@@ -45,6 +45,22 @@ describe JiraImport::StartImportService do
it_behaves_like 'responds with error', 'Jira import is already running.'
end
+ context 'when an error is raised while scheduling import' do
+ before do
+ expect_next_instance_of(JiraImportState) do |jira_impport|
+ expect(jira_impport).to receive(:schedule!).and_raise(Projects::ImportService::Error, 'Unexpected failure.')
+ end
+ end
+
+ it_behaves_like 'responds with error', 'Unexpected failure.'
+
+ it 'saves the error message' do
+ subject
+
+ expect(JiraImportState.last.error_message).to eq('Unexpected failure.')
+ end
+ end
+
context 'when everything is ok' do
it 'returns success response' do
expect(subject).to be_a(ServiceResponse)
@@ -57,7 +73,7 @@ describe JiraImport::StartImportService do
expect(project.latest_jira_import).to be_scheduled
end
- it 'creates Jira import data' do
+ it 'creates Jira import data', :aggregate_failures do
jira_import = subject.payload[:import_data]
expect(jira_import.jira_project_xid).to eq(0)
@@ -72,8 +88,8 @@ describe JiraImport::StartImportService do
it 'creates Jira label title with correct number' do
jira_import = subject.payload[:import_data]
-
label_title = "jira-import::#{jira_import.jira_project_key}-1"
+
expect(jira_import.label.title).to eq(label_title)
end
end
@@ -83,8 +99,8 @@ describe JiraImport::StartImportService do
it 'creates Jira label title with correct number' do
jira_import = subject.payload[:import_data]
-
label_title = "jira-import::#{jira_import.jira_project_key}-4"
+
expect(jira_import.label.title).to eq(label_title)
end
end
diff --git a/spec/services/jira_import/users_importer_spec.rb b/spec/services/jira_import/users_importer_spec.rb
new file mode 100644
index 00000000000..28ce5f1b44b
--- /dev/null
+++ b/spec/services/jira_import/users_importer_spec.rb
@@ -0,0 +1,77 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe JiraImport::UsersImporter do
+ include JiraServiceHelper
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project, reload: true) { create(:project) }
+ let_it_be(:start_at) { 7 }
+
+ let(:importer) { described_class.new(user, project, start_at) }
+
+ subject { importer.execute }
+
+ describe '#execute' do
+ before do
+ stub_jira_service_test
+ project.add_maintainer(user)
+ end
+
+ context 'when Jira import is not configured properly' do
+ it 'returns an error' do
+ expect(subject.errors).to eq(['Jira integration not configured.'])
+ end
+ end
+
+ context 'when Jira import is configured correctly' do
+ let_it_be(:jira_service) { create(:jira_service, project: project, active: true) }
+ let(:client) { double }
+
+ before do
+ expect(importer).to receive(:client).and_return(client)
+ end
+
+ context 'when jira client raises an error' do
+ it 'returns an error response' do
+ expect(client).to receive(:get).and_raise(Timeout::Error)
+
+ expect(subject.error?).to be_truthy
+ expect(subject.message).to include('There was an error when communicating to Jira')
+ end
+ end
+
+ context 'when jira client returns result' do
+ before do
+ allow(client).to receive(:get).with('/rest/api/2/users?maxResults=50&startAt=7')
+ .and_return(jira_users)
+ end
+
+ context 'when jira client returns an empty array' do
+ let(:jira_users) { [] }
+
+ it 'retturns nil payload' do
+ expect(subject.success?).to be_truthy
+ expect(subject.payload).to be_nil
+ end
+ end
+
+ context 'when jira client returns an results' do
+ let(:jira_users) { [{ 'name' => 'user1' }, { 'name' => 'user2' }] }
+ let(:mapped_users) { [{ jira_display_name: 'user1', gitlab_id: 5 }] }
+
+ before do
+ expect(JiraImport::UsersMapper).to receive(:new).with(project, jira_users)
+ .and_return(double(execute: mapped_users))
+ end
+
+ it 'returns the mapped users' do
+ expect(subject.success?).to be_truthy
+ expect(subject.payload).to eq(mapped_users)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/jira_import/users_mapper_spec.rb b/spec/services/jira_import/users_mapper_spec.rb
new file mode 100644
index 00000000000..75dbc41aa2e
--- /dev/null
+++ b/spec/services/jira_import/users_mapper_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe JiraImport::UsersMapper do
+ let_it_be(:project) { create(:project) }
+
+ subject { described_class.new(project, jira_users).execute }
+
+ describe '#execute' do
+ context 'jira_users is nil' do
+ let(:jira_users) { nil }
+
+ it 'returns an empty array' do
+ expect(subject).to be_empty
+ end
+ end
+
+ context 'when jira_users is present' do
+ let(:jira_users) do
+ [
+ { 'accountId' => 'abcd', 'displayName' => 'user1' },
+ { 'accountId' => 'efg' },
+ { 'accountId' => 'hij', 'displayName' => 'user3', 'emailAddress' => 'user3@example.com' }
+ ]
+ end
+
+ # TODO: now we only create an array in a proper format
+ # mapping is tracked in https://gitlab.com/gitlab-org/gitlab/-/issues/219023
+ let(:mapped_users) do
+ [
+ { jira_account_id: 'abcd', jira_display_name: 'user1', jira_email: nil, gitlab_id: nil },
+ { jira_account_id: 'efg', jira_display_name: nil, jira_email: nil, gitlab_id: nil },
+ { jira_account_id: 'hij', jira_display_name: 'user3', jira_email: 'user3@example.com', gitlab_id: nil }
+ ]
+ end
+
+ it 'returns users mapped to Gitlab' do
+ expect(subject).to eq(mapped_users)
+ end
+ end
+ end
+end
diff --git a/spec/services/labels/available_labels_service_spec.rb b/spec/services/labels/available_labels_service_spec.rb
index 3ba1add121d..56826257d6f 100644
--- a/spec/services/labels/available_labels_service_spec.rb
+++ b/spec/services/labels/available_labels_service_spec.rb
@@ -73,6 +73,12 @@ describe Labels::AvailableLabelsService do
expect(result).to match_array([project_label.id, group_label.id])
end
+
+ it 'returns labels in preserved order' do
+ result = described_class.new(user, project, ids: label_ids.reverse).filter_labels_ids_in_param(:ids)
+
+ expect(result).to eq([group_label.id, project_label.id])
+ end
end
context 'when parent is a group' do
diff --git a/spec/services/merge_requests/close_service_spec.rb b/spec/services/merge_requests/close_service_spec.rb
index b037b73752e..0e51de48fb1 100644
--- a/spec/services/merge_requests/close_service_spec.rb
+++ b/spec/services/merge_requests/close_service_spec.rb
@@ -19,45 +19,54 @@ describe MergeRequests::CloseService do
describe '#execute' do
it_behaves_like 'cache counters invalidator'
- context 'valid params' do
- let(:service) { described_class.new(project, user, {}) }
+ [true, false].each do |state_tracking_enabled|
+ context "valid params with state_tracking #{state_tracking_enabled ? 'enabled' : 'disabled'}" do
+ let(:service) { described_class.new(project, user, {}) }
- before do
- allow(service).to receive(:execute_hooks)
+ before do
+ stub_feature_flags(track_resource_state_change_events: state_tracking_enabled)
- perform_enqueued_jobs do
- @merge_request = service.execute(merge_request)
+ allow(service).to receive(:execute_hooks)
+
+ perform_enqueued_jobs do
+ @merge_request = service.execute(merge_request)
+ end
end
- end
- it { expect(@merge_request).to be_valid }
- it { expect(@merge_request).to be_closed }
+ it { expect(@merge_request).to be_valid }
+ it { expect(@merge_request).to be_closed }
- it 'executes hooks with close action' do
- expect(service).to have_received(:execute_hooks)
+ it 'executes hooks with close action' do
+ expect(service).to have_received(:execute_hooks)
.with(@merge_request, 'close')
- end
+ end
- it 'sends email to user2 about assign of new merge_request', :sidekiq_might_not_need_inline do
- email = ActionMailer::Base.deliveries.last
- expect(email.to.first).to eq(user2.email)
- expect(email.subject).to include(merge_request.title)
- end
+ it 'sends email to user2 about assign of new merge_request', :sidekiq_might_not_need_inline do
+ email = ActionMailer::Base.deliveries.last
+ expect(email.to.first).to eq(user2.email)
+ expect(email.subject).to include(merge_request.title)
+ end
- it 'creates system note about merge_request reassign' do
- note = @merge_request.notes.last
- expect(note.note).to include 'closed'
- end
+ it 'creates system note about merge_request reassign' do
+ if state_tracking_enabled
+ event = @merge_request.resource_state_events.last
+ expect(event.state).to eq('closed')
+ else
+ note = @merge_request.notes.last
+ expect(note.note).to include 'closed'
+ end
+ end
- it 'marks todos as done' do
- expect(todo.reload).to be_done
- end
+ it 'marks todos as done' do
+ expect(todo.reload).to be_done
+ end
- context 'when auto merge is enabled' do
- let(:merge_request) { create(:merge_request, :merge_when_pipeline_succeeds) }
+ context 'when auto merge is enabled' do
+ let(:merge_request) { create(:merge_request, :merge_when_pipeline_succeeds) }
- it 'cancels the auto merge' do
- expect(@merge_request).not_to be_auto_merge_enabled
+ it 'cancels the auto merge' do
+ expect(@merge_request).not_to be_auto_merge_enabled
+ end
end
end
end
diff --git a/spec/services/merge_requests/create_service_spec.rb b/spec/services/merge_requests/create_service_spec.rb
index 9155db16d17..bb40c399b6e 100644
--- a/spec/services/merge_requests/create_service_spec.rb
+++ b/spec/services/merge_requests/create_service_spec.rb
@@ -59,7 +59,7 @@ describe MergeRequests::CreateService, :clean_gitlab_redis_shared_state do
it 'creates exactly 1 create MR event', :sidekiq_might_not_need_inline do
attributes = {
- action: Event::CREATED,
+ action: :created,
target_id: merge_request.id,
target_type: merge_request.class.name
}
@@ -136,11 +136,11 @@ describe MergeRequests::CreateService, :clean_gitlab_redis_shared_state do
let!(:pipeline_3) { create(:ci_pipeline, project: project, ref: "other_branch", project_id: project.id) }
before do
- # rubocop: disable DestroyAll
+ # rubocop: disable Cop/DestroyAll
project.merge_requests
.where(source_branch: opts[:source_branch], target_branch: opts[:target_branch])
.destroy_all
- # rubocop: enable DestroyAll
+ # rubocop: enable Cop/DestroyAll
end
it 'sets head pipeline' do
diff --git a/spec/services/merge_requests/delete_non_latest_diffs_service_spec.rb b/spec/services/merge_requests/delete_non_latest_diffs_service_spec.rb
index a1c86467f34..2adf808619d 100644
--- a/spec/services/merge_requests/delete_non_latest_diffs_service_spec.rb
+++ b/spec/services/merge_requests/delete_non_latest_diffs_service_spec.rb
@@ -48,12 +48,12 @@ describe MergeRequests::DeleteNonLatestDiffsService, :clean_gitlab_redis_shared_
end
it 'schedules no removal if there is no non-latest diffs' do
- # rubocop: disable DestroyAll
+ # rubocop: disable Cop/DestroyAll
merge_request
.merge_request_diffs
.where.not(id: merge_request.latest_merge_request_diff_id)
.destroy_all
- # rubocop: enable DestroyAll
+ # rubocop: enable Cop/DestroyAll
expect(DeleteDiffFilesWorker).not_to receive(:bulk_perform_in)
diff --git a/spec/services/merge_requests/ff_merge_service_spec.rb b/spec/services/merge_requests/ff_merge_service_spec.rb
index 87fcd70a298..415b351e13a 100644
--- a/spec/services/merge_requests/ff_merge_service_spec.rb
+++ b/spec/services/merge_requests/ff_merge_service_spec.rb
@@ -21,65 +21,74 @@ describe MergeRequests::FfMergeService do
end
describe '#execute' do
- context 'valid params' do
- let(:service) { described_class.new(project, user, valid_merge_params) }
-
- def execute_ff_merge
- perform_enqueued_jobs do
- service.execute(merge_request)
+ [true, false].each do |state_tracking_enabled|
+ context "valid params with state_tracking #{state_tracking_enabled ? 'enabled' : 'disabled'}" do
+ let(:service) { described_class.new(project, user, valid_merge_params) }
+
+ def execute_ff_merge
+ perform_enqueued_jobs do
+ service.execute(merge_request)
+ end
end
- end
- before do
- allow(service).to receive(:execute_hooks)
- end
+ before do
+ stub_feature_flags(track_resource_state_change_events: state_tracking_enabled)
- it "does not create merge commit" do
- execute_ff_merge
+ allow(service).to receive(:execute_hooks)
+ end
- source_branch_sha = merge_request.source_project.repository.commit(merge_request.source_branch).sha
- target_branch_sha = merge_request.target_project.repository.commit(merge_request.target_branch).sha
+ it "does not create merge commit" do
+ execute_ff_merge
- expect(source_branch_sha).to eq(target_branch_sha)
- end
+ source_branch_sha = merge_request.source_project.repository.commit(merge_request.source_branch).sha
+ target_branch_sha = merge_request.target_project.repository.commit(merge_request.target_branch).sha
- it 'keeps the merge request valid' do
- expect { execute_ff_merge }
- .not_to change { merge_request.valid? }
- end
+ expect(source_branch_sha).to eq(target_branch_sha)
+ end
- it 'updates the merge request to merged' do
- expect { execute_ff_merge }
- .to change { merge_request.merged? }
- .from(false)
- .to(true)
- end
+ it 'keeps the merge request valid' do
+ expect { execute_ff_merge }
+ .not_to change { merge_request.valid? }
+ end
- it 'sends email to user2 about merge of new merge_request' do
- execute_ff_merge
+ it 'updates the merge request to merged' do
+ expect { execute_ff_merge }
+ .to change { merge_request.merged? }
+ .from(false)
+ .to(true)
+ end
- email = ActionMailer::Base.deliveries.last
- expect(email.to.first).to eq(user2.email)
- expect(email.subject).to include(merge_request.title)
- end
+ it 'sends email to user2 about merge of new merge_request' do
+ execute_ff_merge
- it 'creates system note about merge_request merge' do
- execute_ff_merge
+ email = ActionMailer::Base.deliveries.last
+ expect(email.to.first).to eq(user2.email)
+ expect(email.subject).to include(merge_request.title)
+ end
- note = merge_request.notes.last
- expect(note.note).to include 'merged'
- end
+ it 'creates system note about merge_request merge' do
+ execute_ff_merge
- it 'does not update squash_commit_sha if it is not a squash' do
- expect { execute_ff_merge }.not_to change { merge_request.squash_commit_sha }
- end
+ if state_tracking_enabled
+ event = merge_request.resource_state_events.last
+ expect(event.state).to eq('merged')
+ else
+ note = merge_request.notes.last
+ expect(note.note).to include 'merged'
+ end
+ end
- it 'updates squash_commit_sha if it is a squash' do
- merge_request.update!(squash: true)
+ it 'does not update squash_commit_sha if it is not a squash' do
+ expect { execute_ff_merge }.not_to change { merge_request.squash_commit_sha }
+ end
- expect { execute_ff_merge }
- .to change { merge_request.squash_commit_sha }
- .from(nil)
+ it 'updates squash_commit_sha if it is a squash' do
+ merge_request.update!(squash: true)
+
+ expect { execute_ff_merge }
+ .to change { merge_request.squash_commit_sha }
+ .from(nil)
+ end
end
end
@@ -87,7 +96,7 @@ describe MergeRequests::FfMergeService do
let(:service) { described_class.new(project, user, valid_merge_params.merge(commit_message: 'Awesome message')) }
before do
- allow(Rails.logger).to receive(:error)
+ allow(Gitlab::AppLogger).to receive(:error)
end
it 'logs and saves error if there is an exception' do
@@ -99,7 +108,7 @@ describe MergeRequests::FfMergeService do
service.execute(merge_request)
expect(merge_request.merge_error).to include(error_message)
- expect(Rails.logger).to have_received(:error).with(a_string_matching(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
@@ -111,7 +120,7 @@ describe MergeRequests::FfMergeService do
service.execute(merge_request)
expect(merge_request.merge_error).to include(error_message)
- expect(Rails.logger).to have_received(:error).with(a_string_matching(error_message))
+ expect(Gitlab::AppLogger).to have_received(:error).with(a_string_matching(error_message))
end
it 'does not update squash_commit_sha if squash merge is not successful' do
diff --git a/spec/services/merge_requests/merge_service_spec.rb b/spec/services/merge_requests/merge_service_spec.rb
index bcad822b1dc..2274d917527 100644
--- a/spec/services/merge_requests/merge_service_spec.rb
+++ b/spec/services/merge_requests/merge_service_spec.rb
@@ -20,7 +20,11 @@ describe MergeRequests::MergeService do
end
context 'valid params' do
+ let(:state_tracking) { true }
+
before do
+ stub_feature_flags(track_resource_state_change_events: state_tracking)
+
allow(service).to receive(:execute_hooks)
perform_enqueued_jobs do
@@ -42,9 +46,22 @@ describe MergeRequests::MergeService do
expect(email.subject).to include(merge_request.title)
end
- it 'creates system note about merge_request merge' do
- note = merge_request.notes.last
- expect(note.note).to include 'merged'
+ context 'note creation' do
+ context 'when resource state event tracking is disabled' do
+ let(:state_tracking) { false }
+
+ it 'creates system note about merge_request merge' do
+ note = merge_request.notes.last
+ expect(note.note).to include 'merged'
+ end
+ end
+
+ context 'when resource state event tracking is enabled' do
+ it 'creates resource state event about merge_request merge' do
+ event = merge_request.resource_state_events.last
+ expect(event.state).to eq('merged')
+ end
+ end
end
context 'when squashing' do
@@ -55,7 +72,7 @@ describe MergeRequests::MergeService do
end
let(:merge_request) do
- # A merge reqeust with 5 commits
+ # A merge request with 5 commits
create(:merge_request, :simple,
author: user2,
assignees: [user2],
@@ -277,7 +294,7 @@ describe MergeRequests::MergeService do
context 'error handling' do
before do
- allow(Rails.logger).to receive(:error)
+ allow(Gitlab::AppLogger).to receive(:error)
end
context 'when source is missing' do
@@ -289,7 +306,7 @@ describe MergeRequests::MergeService do
service.execute(merge_request)
expect(merge_request.merge_error).to eq(error_message)
- expect(Rails.logger).to have_received(:error).with(a_string_matching(error_message))
+ expect(Gitlab::AppLogger).to have_received(:error).with(a_string_matching(error_message))
end
end
@@ -302,7 +319,7 @@ describe MergeRequests::MergeService do
service.execute(merge_request)
expect(merge_request.merge_error).to include('Something went wrong during merge')
- expect(Rails.logger).to have_received(:error).with(a_string_matching(error_message))
+ expect(Gitlab::AppLogger).to have_received(:error).with(a_string_matching(error_message))
end
it 'logs and saves error if user is not authorized' do
@@ -326,7 +343,7 @@ describe MergeRequests::MergeService do
service.execute(merge_request)
expect(merge_request.merge_error).to include('Something went wrong during merge pre-receive hook')
- expect(Rails.logger).to have_received(:error).with(a_string_matching(error_message))
+ expect(Gitlab::AppLogger).to have_received(:error).with(a_string_matching(error_message))
end
it 'logs and saves error if there is a merge conflict' do
@@ -340,7 +357,7 @@ describe MergeRequests::MergeService do
expect(merge_request).to be_open
expect(merge_request.merge_commit_sha).to be_nil
expect(merge_request.merge_error).to include(error_message)
- expect(Rails.logger).to have_received(:error).with(a_string_matching(error_message))
+ expect(Gitlab::AppLogger).to have_received(:error).with(a_string_matching(error_message))
end
context 'when squashing' do
@@ -359,7 +376,7 @@ describe MergeRequests::MergeService do
expect(merge_request).to be_open
expect(merge_request.merge_commit_sha).to be_nil
expect(merge_request.merge_error).to include(error_message)
- expect(Rails.logger).to have_received(:error).with(a_string_matching(error_message))
+ 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
@@ -373,7 +390,7 @@ describe MergeRequests::MergeService do
expect(merge_request).to be_open
expect(merge_request.merge_commit_sha).to be_nil
expect(merge_request.merge_error).to include(error_message)
- expect(Rails.logger).to have_received(:error).with(a_string_matching(error_message))
+ expect(Gitlab::AppLogger).to have_received(:error).with(a_string_matching(error_message))
end
context 'when fast-forward merge is not allowed' do
@@ -393,7 +410,7 @@ describe MergeRequests::MergeService do
expect(merge_request).to be_open
expect(merge_request.merge_commit_sha).to be_nil
expect(merge_request.merge_error).to include(error_message)
- expect(Rails.logger).to have_received(:error).with(a_string_matching(error_message))
+ expect(Gitlab::AppLogger).to have_received(:error).with(a_string_matching(error_message))
end
end
end
diff --git a/spec/services/merge_requests/refresh_service_spec.rb b/spec/services/merge_requests/refresh_service_spec.rb
index 94e65d895ac..e60ff6eb98a 100644
--- a/spec/services/merge_requests/refresh_service_spec.rb
+++ b/spec/services/merge_requests/refresh_service_spec.rb
@@ -362,76 +362,101 @@ describe MergeRequests::RefreshService do
end
end
- context 'push to origin repo target branch', :sidekiq_might_not_need_inline do
- context 'when all MRs to the target branch had diffs' do
+ [true, false].each do |state_tracking_enabled|
+ context "push to origin repo target branch with state tracking #{state_tracking_enabled ? 'enabled' : 'disabled'}", :sidekiq_might_not_need_inline do
before do
- service.new(@project, @user).execute(@oldrev, @newrev, 'refs/heads/feature')
- reload_mrs
+ stub_feature_flags(track_resource_state_change_events: state_tracking_enabled)
end
- it 'updates the merge state' do
- expect(@merge_request.notes.last.note).to include('merged')
- expect(@merge_request).to be_merged
- expect(@fork_merge_request).to be_merged
- expect(@fork_merge_request.notes.last.note).to include('merged')
- expect(@build_failed_todo).to be_done
- expect(@fork_build_failed_todo).to be_done
+ context 'when all MRs to the target branch had diffs' do
+ before do
+ service.new(@project, @user).execute(@oldrev, @newrev, 'refs/heads/feature')
+ reload_mrs
+ end
+
+ it 'updates the merge state' do
+ expect(@merge_request).to be_merged
+ expect(@fork_merge_request).to be_merged
+ expect(@build_failed_todo).to be_done
+ expect(@fork_build_failed_todo).to be_done
+
+ if state_tracking_enabled
+ expect(@merge_request.resource_state_events.last.state).to eq('merged')
+ expect(@fork_merge_request.resource_state_events.last.state).to eq('merged')
+ else
+ expect(@merge_request.notes.last.note).to include('merged')
+ expect(@fork_merge_request.notes.last.note).to include('merged')
+ end
+ end
end
- end
- context 'when an MR to be closed was empty already' do
- let!(:empty_fork_merge_request) do
- create(:merge_request,
- source_project: @fork_project,
- source_branch: 'master',
- target_branch: 'master',
- target_project: @project)
+ context 'when an MR to be closed was empty already' do
+ let!(:empty_fork_merge_request) do
+ create(:merge_request,
+ source_project: @fork_project,
+ source_branch: 'master',
+ target_branch: 'master',
+ target_project: @project)
+ end
+
+ before do
+ # This spec already has a fake push, so pretend that we were targeting
+ # feature all along.
+ empty_fork_merge_request.update_columns(target_branch: 'feature')
+
+ service.new(@project, @user).execute(@oldrev, @newrev, 'refs/heads/feature')
+ reload_mrs
+ empty_fork_merge_request.reload
+ end
+
+ it 'only updates the non-empty MRs' do
+ expect(@merge_request).to be_merged
+ expect(@fork_merge_request).to be_merged
+
+ expect(empty_fork_merge_request).to be_open
+ expect(empty_fork_merge_request.merge_request_diff.state).to eq('empty')
+ expect(empty_fork_merge_request.notes).to be_empty
+
+ if state_tracking_enabled
+ expect(@merge_request.resource_state_events.last.state).to eq('merged')
+ expect(@fork_merge_request.resource_state_events.last.state).to eq('merged')
+ else
+ expect(@merge_request.notes.last.note).to include('merged')
+ expect(@fork_merge_request.notes.last.note).to include('merged')
+ end
+ end
end
+ end
+ context "manual merge of source branch #{state_tracking_enabled ? 'enabled' : 'disabled'}", :sidekiq_might_not_need_inline do
before do
- # This spec already has a fake push, so pretend that we were targeting
- # feature all along.
- empty_fork_merge_request.update_columns(target_branch: 'feature')
+ stub_feature_flags(track_resource_state_change_events: state_tracking_enabled)
- service.new(@project, @user).execute(@oldrev, @newrev, 'refs/heads/feature')
+ # Merge master -> feature branch
+ @project.repository.merge(@user, @merge_request.diff_head_sha, @merge_request, 'Test message')
+ commit = @project.repository.commit('feature')
+ service.new(@project, @user).execute(@oldrev, commit.id, 'refs/heads/feature')
reload_mrs
- empty_fork_merge_request.reload
end
- it 'only updates the non-empty MRs' do
- expect(@merge_request).to be_merged
- expect(@merge_request.notes.last.note).to include('merged')
+ it 'updates the merge state' do
+ if state_tracking_enabled
+ expect(@merge_request.resource_state_events.last.state).to eq('merged')
+ expect(@fork_merge_request.resource_state_events.last.state).to eq('merged')
+ else
+ expect(@merge_request.notes.last.note).to include('merged')
+ expect(@fork_merge_request.notes.last.note).to include('merged')
+ end
+ expect(@merge_request).to be_merged
+ expect(@merge_request.diffs.size).to be > 0
expect(@fork_merge_request).to be_merged
- expect(@fork_merge_request.notes.last.note).to include('merged')
-
- expect(empty_fork_merge_request).to be_open
- expect(empty_fork_merge_request.merge_request_diff.state).to eq('empty')
- expect(empty_fork_merge_request.notes).to be_empty
+ expect(@build_failed_todo).to be_done
+ expect(@fork_build_failed_todo).to be_done
end
end
end
- context 'manual merge of source branch', :sidekiq_might_not_need_inline do
- before do
- # Merge master -> feature branch
- @project.repository.merge(@user, @merge_request.diff_head_sha, @merge_request, 'Test message')
- commit = @project.repository.commit('feature')
- service.new(@project, @user).execute(@oldrev, commit.id, 'refs/heads/feature')
- reload_mrs
- end
-
- it 'updates the merge state' do
- expect(@merge_request.notes.last.note).to include('merged')
- expect(@merge_request).to be_merged
- expect(@merge_request.diffs.size).to be > 0
- expect(@fork_merge_request).to be_merged
- expect(@fork_merge_request.notes.last.note).to include('merged')
- expect(@build_failed_todo).to be_done
- expect(@fork_build_failed_todo).to be_done
- end
- end
-
context 'push to fork repo source branch', :sidekiq_might_not_need_inline do
let(:refresh_service) { service.new(@fork_project, @user) }
@@ -583,20 +608,29 @@ describe MergeRequests::RefreshService do
end
end
- context 'push to origin repo target branch after fork project was removed' do
- before do
- @fork_project.destroy
- service.new(@project, @user).execute(@oldrev, @newrev, 'refs/heads/feature')
- reload_mrs
- end
+ [true, false].each do |state_tracking_enabled|
+ context "push to origin repo target branch after fork project was removed #{state_tracking_enabled ? 'enabled' : 'disabled'}" do
+ before do
+ stub_feature_flags(track_resource_state_change_events: state_tracking_enabled)
- it 'updates the merge request state' do
- expect(@merge_request.notes.last.note).to include('merged')
- expect(@merge_request).to be_merged
- expect(@fork_merge_request).to be_open
- expect(@fork_merge_request.notes).to be_empty
- expect(@build_failed_todo).to be_done
- expect(@fork_build_failed_todo).to be_done
+ @fork_project.destroy
+ service.new(@project, @user).execute(@oldrev, @newrev, 'refs/heads/feature')
+ reload_mrs
+ end
+
+ it 'updates the merge request state' do
+ if state_tracking_enabled
+ expect(@merge_request.resource_state_events.last.state).to eq('merged')
+ else
+ expect(@merge_request.notes.last.note).to include('merged')
+ end
+
+ expect(@merge_request).to be_merged
+ expect(@fork_merge_request).to be_open
+ expect(@fork_merge_request.notes).to be_empty
+ expect(@build_failed_todo).to be_done
+ expect(@fork_build_failed_todo).to be_done
+ end
end
end
diff --git a/spec/services/merge_requests/reopen_service_spec.rb b/spec/services/merge_requests/reopen_service_spec.rb
index 25ab79d70c3..3807c44b01f 100644
--- a/spec/services/merge_requests/reopen_service_spec.rb
+++ b/spec/services/merge_requests/reopen_service_spec.rb
@@ -20,8 +20,11 @@ describe MergeRequests::ReopenService do
context 'valid params' do
let(:service) { described_class.new(project, user, {}) }
+ let(:state_tracking) { true }
before do
+ stub_feature_flags(track_resource_state_change_events: state_tracking)
+
allow(service).to receive(:execute_hooks)
perform_enqueued_jobs do
@@ -43,9 +46,22 @@ describe MergeRequests::ReopenService do
expect(email.subject).to include(merge_request.title)
end
- it 'creates system note about merge_request reopen' do
- note = merge_request.notes.last
- expect(note.note).to include 'reopened'
+ context 'note creation' do
+ context 'when state event tracking is disabled' do
+ let(:state_tracking) { false }
+
+ it 'creates system note about merge_request reopen' do
+ note = merge_request.notes.last
+ expect(note.note).to include 'reopened'
+ end
+ end
+
+ context 'when state event tracking is enabled' do
+ it 'creates resource state event about merge_request reopen' do
+ event = merge_request.resource_state_events.last
+ expect(event.state).to eq('reopened')
+ end
+ end
end
end
diff --git a/spec/services/namespaces/check_storage_size_service_spec.rb b/spec/services/namespaces/check_storage_size_service_spec.rb
index 50359ef90ab..e192f897cf9 100644
--- a/spec/services/namespaces/check_storage_size_service_spec.rb
+++ b/spec/services/namespaces/check_storage_size_service_spec.rb
@@ -44,7 +44,7 @@ describe Namespaces::CheckStorageSizeService, '#execute' do
end
it 'errors when feature flag is activated for the current namespace' do
- stub_feature_flags(namespace_storage_limit: namespace )
+ stub_feature_flags(namespace_storage_limit: namespace)
expect(response).to be_error
expect(response.message).to be_present
@@ -156,4 +156,10 @@ describe Namespaces::CheckStorageSizeService, '#execute' do
expect(response).to include("60%")
end
end
+
+ describe 'payload root_namespace' do
+ subject(:response) { service.execute.payload[:root_namespace] }
+
+ it { is_expected.to eq(namespace) }
+ end
end
diff --git a/spec/services/notification_recipients/build_service_spec.rb b/spec/services/notification_recipients/build_service_spec.rb
index 2e848c2f04d..e203093623d 100644
--- a/spec/services/notification_recipients/build_service_spec.rb
+++ b/spec/services/notification_recipients/build_service_spec.rb
@@ -58,4 +58,56 @@ describe NotificationRecipients::BuildService do
end
end
end
+
+ describe '#build_new_review_recipients' do
+ let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
+ let(:review) { create(:review, merge_request: merge_request, project: project, author: merge_request.author) }
+ let(:notes) { create_list(:note_on_merge_request, 3, review: review, noteable: review.merge_request, project: review.project) }
+
+ shared_examples 'no N+1 queries' do
+ it 'avoids N+1 queries', :request_store do
+ create_user
+
+ service.build_new_review_recipients(review)
+
+ control_count = ActiveRecord::QueryRecorder.new do
+ service.build_new_review_recipients(review)
+ end
+
+ create_user
+
+ expect { service.build_new_review_recipients(review) }.not_to exceed_query_limit(control_count)
+ end
+ end
+
+ context 'when there are multiple watchers' do
+ def create_user
+ watcher = create(:user)
+ create(:notification_setting, source: project, user: watcher, level: :watch)
+
+ other_projects.each do |other_project|
+ create(:notification_setting, source: other_project, user: watcher, level: :watch)
+ end
+ end
+
+ include_examples 'no N+1 queries'
+ end
+
+ context 'when there are multiple subscribers' do
+ def create_user
+ subscriber = create(:user)
+ merge_request.subscriptions.create(user: subscriber, project: project, subscribed: true)
+ end
+
+ include_examples 'no N+1 queries'
+
+ context 'when the project is private' do
+ before do
+ project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
+ end
+
+ include_examples 'no N+1 queries'
+ end
+ end
+ end
end
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
index 46c80a86639..3c1c3e2dfc3 100644
--- a/spec/services/notification_service_spec.rb
+++ b/spec/services/notification_service_spec.rb
@@ -243,11 +243,12 @@ describe NotificationService, :mailer do
describe '#unknown_sign_in' do
let_it_be(:user) { create(:user) }
let_it_be(:ip) { '127.0.0.1' }
+ let_it_be(:time) { Time.current }
- subject { notification.unknown_sign_in(user, ip) }
+ subject { notification.unknown_sign_in(user, ip, time) }
it 'sends email to the user' do
- expect { subject }.to have_enqueued_email(user, ip, mail: 'unknown_sign_in_email')
+ expect { subject }.to have_enqueued_email(user, ip, time, mail: 'unknown_sign_in_email')
end
end
@@ -2867,6 +2868,57 @@ describe NotificationService, :mailer do
end
end
+ describe '#new_review' do
+ let(:project) { create(:project, :repository) }
+ let(:user) { create(:user) }
+ let(:user2) { create(:user) }
+ let(:reviewer) { create(:user) }
+ let(:merge_request) { create(:merge_request, source_project: project, assignees: [user, user2], author: create(:user)) }
+ let(:review) { create(:review, merge_request: merge_request, project: project, author: reviewer) }
+ let(:note) { create(:diff_note_on_merge_request, project: project, noteable: merge_request, author: reviewer, review: review) }
+
+ before do
+ build_team(review.project)
+ add_users(review.project)
+ add_user_subscriptions(merge_request)
+ project.add_maintainer(merge_request.author)
+ project.add_maintainer(reviewer)
+ merge_request.assignees.each { |assignee| project.add_maintainer(assignee) }
+
+ create(:diff_note_on_merge_request,
+ project: project,
+ noteable: merge_request,
+ author: reviewer,
+ review: review,
+ note: "cc @mention")
+ end
+
+ it 'sends emails' do
+ expect(Notify).not_to receive(:new_review_email).with(review.author.id, review.id)
+ expect(Notify).not_to receive(:new_review_email).with(@unsubscriber.id, review.id)
+ merge_request.assignee_ids.each do |assignee_id|
+ expect(Notify).to receive(:new_review_email).with(assignee_id, review.id).and_call_original
+ end
+ expect(Notify).to receive(:new_review_email).with(merge_request.author.id, review.id).and_call_original
+ expect(Notify).to receive(:new_review_email).with(@u_watcher.id, review.id).and_call_original
+ expect(Notify).to receive(:new_review_email).with(@u_mentioned.id, review.id).and_call_original
+ expect(Notify).to receive(:new_review_email).with(@subscriber.id, review.id).and_call_original
+ expect(Notify).to receive(:new_review_email).with(@watcher_and_subscriber.id, review.id).and_call_original
+ expect(Notify).to receive(:new_review_email).with(@subscribed_participant.id, review.id).and_call_original
+
+ subject.new_review(review)
+ end
+
+ it_behaves_like 'project emails are disabled' do
+ let(:notification_target) { review }
+ let(:notification_trigger) { subject.new_review(review) }
+
+ around do |example|
+ perform_enqueued_jobs { example.run }
+ end
+ end
+ end
+
def build_team(project)
@u_watcher = create_global_setting_for(create(:user), :watch)
@u_participating = create_global_setting_for(create(:user), :participating)
diff --git a/spec/services/projects/alerting/notify_service_spec.rb b/spec/services/projects/alerting/notify_service_spec.rb
index b88f0ef5149..2f8c2049f85 100644
--- a/spec/services/projects/alerting/notify_service_spec.rb
+++ b/spec/services/projects/alerting/notify_service_spec.rb
@@ -8,21 +8,21 @@ describe Projects::Alerting::NotifyService do
before do
# We use `let_it_be(:project)` so we make sure to clear caches
project.clear_memoization(:licensed_feature_available)
+ allow(ProjectServiceWorker).to receive(:perform_async)
end
- shared_examples 'processes incident issues' do |amount|
+ shared_examples 'processes incident issues' do
let(:create_incident_service) { spy }
- let(:new_alert) { instance_double(AlertManagement::Alert, id: 503, persisted?: true) }
- it 'processes issues' do
- expect(AlertManagement::Alert)
- .to receive(:create)
- .and_return(new_alert)
+ before do
+ allow_any_instance_of(AlertManagement::Alert).to receive(:execute_services)
+ end
+ it 'processes issues' do
expect(IncidentManagement::ProcessAlertWorker)
.to receive(:perform_async)
- .with(project.id, kind_of(Hash), new_alert.id)
- .exactly(amount).times
+ .with(project.id, kind_of(Hash), kind_of(Integer))
+ .once
Sidekiq::Testing.inline! do
expect(subject).to be_success
@@ -73,6 +73,7 @@ describe Projects::Alerting::NotifyService do
describe '#execute' do
let(:token) { 'invalid-token' }
let(:starts_at) { Time.current.change(usec: 0) }
+ let(:fingerprint) { 'testing' }
let(:service) { described_class.new(project, nil, payload) }
let(:payload_raw) do
{
@@ -82,7 +83,8 @@ describe Projects::Alerting::NotifyService do
monitoring_tool: 'GitLab RSpec',
service: 'GitLab Test Suite',
description: 'Very detailed description',
- hosts: ['1.1.1.1', '2.2.2.2']
+ hosts: ['1.1.1.1', '2.2.2.2'],
+ fingerprint: fingerprint
}.with_indifferent_access
end
let(:payload) { ActionController::Parameters.new(payload_raw).permit! }
@@ -131,11 +133,37 @@ describe Projects::Alerting::NotifyService do
description: payload_raw.fetch(:description),
monitoring_tool: payload_raw.fetch(:monitoring_tool),
service: payload_raw.fetch(:service),
- fingerprint: nil,
+ fingerprint: Digest::SHA1.hexdigest(fingerprint),
ended_at: nil
)
end
+ it 'executes the alert service hooks' do
+ slack_service = create(:service, type: 'SlackService', project: project, alert_events: true, active: true)
+ subject
+
+ expect(ProjectServiceWorker).to have_received(:perform_async).with(slack_service.id, an_instance_of(Hash))
+ end
+
+ context 'existing alert with same fingerprint' do
+ let(:fingerprint_sha) { Digest::SHA1.hexdigest(fingerprint) }
+ let!(:existing_alert) { create(:alert_management_alert, project: project, fingerprint: fingerprint_sha) }
+
+ it 'does not create AlertManagement::Alert' do
+ expect { subject }.not_to change(AlertManagement::Alert, :count)
+ end
+
+ it 'increments the existing alert count' do
+ expect { subject }.to change { existing_alert.reload.events }.from(1).to(2)
+ end
+
+ it 'does not executes the alert service hooks' do
+ subject
+
+ expect(ProjectServiceWorker).not_to have_received(:perform_async)
+ end
+ end
+
context 'with a minimal payload' do
let(:payload_raw) do
{
@@ -176,7 +204,7 @@ describe Projects::Alerting::NotifyService do
context 'issue enabled' do
let(:issue_enabled) { true }
- it_behaves_like 'processes incident issues', 1
+ it_behaves_like 'processes incident issues'
context 'with an invalid payload' do
before do
@@ -188,6 +216,21 @@ describe Projects::Alerting::NotifyService do
it_behaves_like 'does not process incident issues due to error', http_status: :bad_request
it_behaves_like 'NotifyService does not create alert'
end
+
+ context 'when alert already exists' do
+ let(:fingerprint_sha) { Digest::SHA1.hexdigest(fingerprint) }
+ let!(:existing_alert) { create(:alert_management_alert, project: project, fingerprint: fingerprint_sha) }
+
+ context 'when existing alert does not have an associated issue' do
+ it_behaves_like 'processes incident issues'
+ end
+
+ context 'when existing alert has an associated issue' do
+ let!(:existing_alert) { create(:alert_management_alert, :with_issue, project: project, fingerprint: fingerprint_sha) }
+
+ it_behaves_like 'does not process incident issues'
+ end
+ end
end
context 'with emails turned on' do
diff --git a/spec/services/projects/container_repository/cleanup_tags_service_spec.rb b/spec/services/projects/container_repository/cleanup_tags_service_spec.rb
index 01f09f208fd..11ea7d51673 100644
--- a/spec/services/projects/container_repository/cleanup_tags_service_spec.rb
+++ b/spec/services/projects/container_repository/cleanup_tags_service_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
describe Projects::ContainerRepository::CleanupTagsService do
let_it_be(:user) { create(:user) }
- let_it_be(:project) { create(:project, :private) }
+ let_it_be(:project, reload: true) { create(:project, :private) }
let_it_be(:repository) { create(:container_repository, :root, project: project) }
let(:service) { described_class.new(project, user, params) }
@@ -72,6 +72,47 @@ describe Projects::ContainerRepository::CleanupTagsService do
end
end
+ context 'with invalid regular expressions' do
+ RSpec.shared_examples 'handling an invalid regex' do
+ it 'keeps all tags' do
+ expect(Projects::ContainerRepository::DeleteTagsService)
+ .not_to receive(:new)
+ subject
+ end
+
+ it 'returns an error' do
+ response = subject
+
+ expect(response[:status]).to eq(:error)
+ expect(response[:message]).to eq('invalid regex')
+ end
+
+ it 'calls error tracking service' do
+ expect(Gitlab::ErrorTracking).to receive(:log_exception).and_call_original
+
+ subject
+ end
+ end
+
+ context 'when name_regex_delete is invalid' do
+ let(:params) { { 'name_regex_delete' => '*test*' } }
+
+ it_behaves_like 'handling an invalid regex'
+ end
+
+ context 'when name_regex is invalid' do
+ let(:params) { { 'name_regex' => '*test*' } }
+
+ it_behaves_like 'handling an invalid regex'
+ end
+
+ context 'when name_regex_keep is invalid' do
+ let(:params) { { 'name_regex_keep' => '*test*' } }
+
+ it_behaves_like 'handling an invalid regex'
+ end
+ end
+
context 'when delete regex matching specific tags is used' do
let(:params) do
{ 'name_regex_delete' => 'C|D' }
diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb
index e542f1e9108..e70ee05ed31 100644
--- a/spec/services/projects/create_service_spec.rb
+++ b/spec/services/projects/create_service_spec.rb
@@ -43,10 +43,10 @@ describe Projects::CreateService, '#execute' do
create_project(user, opts)
end
- it 'creates associated project settings' do
+ it 'builds associated project settings' do
project = create_project(user, opts)
- expect(project.project_setting).to be_persisted
+ expect(project.project_setting).to be_new_record
end
end
@@ -88,6 +88,116 @@ describe Projects::CreateService, '#execute' do
end
end
+ context 'group sharing', :sidekiq_inline do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:shared_group) { create(:group) }
+ let_it_be(:shared_group_user) { create(:user) }
+ let(:opts) do
+ {
+ name: 'GitLab',
+ namespace_id: shared_group.id
+ }
+ end
+
+ before do
+ create(:group_group_link, shared_group: shared_group, shared_with_group: group)
+
+ shared_group.add_maintainer(shared_group_user)
+ group.add_developer(user)
+ end
+
+ it 'updates authorization' do
+ shared_group_project = create_project(shared_group_user, opts)
+
+ expect(
+ Ability.allowed?(shared_group_user, :read_project, shared_group_project)
+ ).to be_truthy
+ expect(
+ Ability.allowed?(user, :read_project, shared_group_project)
+ ).to be_truthy
+ end
+ end
+
+ context 'membership overrides', :sidekiq_inline do
+ let_it_be(:group) { create(:group, :private) }
+ let_it_be(:subgroup_for_projects) { create(:group, :private, parent: group) }
+ let_it_be(:subgroup_for_access) { create(:group, :private, parent: group) }
+ let_it_be(:group_maintainer) { create(:user) }
+ let(:group_access_level) { Gitlab::Access::REPORTER }
+ let(:subgroup_access_level) { Gitlab::Access::DEVELOPER }
+ let(:share_max_access_level) { Gitlab::Access::MAINTAINER }
+ let(:opts) do
+ {
+ name: 'GitLab',
+ namespace_id: subgroup_for_projects.id
+ }
+ end
+
+ before do
+ group.add_maintainer(group_maintainer)
+
+ create(:group_group_link, shared_group: subgroup_for_projects,
+ shared_with_group: subgroup_for_access,
+ group_access: share_max_access_level)
+ end
+
+ context 'membership is higher from group hierarchy' do
+ let(:group_access_level) { Gitlab::Access::MAINTAINER }
+
+ it 'updates authorization' do
+ create(:group_member, access_level: subgroup_access_level, group: subgroup_for_access, user: user)
+ create(:group_member, access_level: group_access_level, group: group, user: user)
+
+ subgroup_project = create_project(group_maintainer, opts)
+
+ project_authorization = ProjectAuthorization.where(
+ project_id: subgroup_project.id,
+ user_id: user.id,
+ access_level: group_access_level)
+
+ expect(project_authorization).to exist
+ end
+ end
+
+ context 'membership is higher from group share' do
+ let(:subgroup_access_level) { Gitlab::Access::MAINTAINER }
+
+ context 'share max access level is not limiting' do
+ it 'updates authorization' do
+ create(:group_member, access_level: group_access_level, group: group, user: user)
+ create(:group_member, access_level: subgroup_access_level, group: subgroup_for_access, user: user)
+
+ subgroup_project = create_project(group_maintainer, opts)
+
+ project_authorization = ProjectAuthorization.where(
+ project_id: subgroup_project.id,
+ user_id: user.id,
+ access_level: subgroup_access_level)
+
+ expect(project_authorization).to exist
+ end
+ end
+
+ context 'share max access level is limiting' do
+ let(:share_max_access_level) { Gitlab::Access::DEVELOPER }
+
+ it 'updates authorization' do
+ create(:group_member, access_level: group_access_level, group: group, user: user)
+ create(:group_member, access_level: subgroup_access_level, group: subgroup_for_access, user: user)
+
+ subgroup_project = create_project(group_maintainer, opts)
+
+ project_authorization = ProjectAuthorization.where(
+ project_id: subgroup_project.id,
+ user_id: user.id,
+ access_level: share_max_access_level)
+
+ expect(project_authorization).to exist
+ end
+ end
+ end
+ end
+
context 'error handling' do
it 'handles invalid options' do
opts[:default_branch] = 'master'
@@ -339,29 +449,39 @@ describe Projects::CreateService, '#execute' do
end
end
- context 'when there is an active service template' do
- before do
- create(:prometheus_service, project: nil, template: true, active: true)
- end
+ describe 'create service for the project' do
+ subject(:project) { create_project(user, opts) }
- it 'creates a service from this template' do
- project = create_project(user, opts)
+ context 'when there is an active instance-level and an active template integration' do
+ let!(:template_integration) { create(:prometheus_service, :template, api_url: 'https://prometheus.template.com/') }
+ let!(:instance_integration) { create(:prometheus_service, :instance, api_url: 'https://prometheus.instance.com/') }
- expect(project.services.count).to eq 1
- expect(project.errors).to be_empty
+ it 'creates a service from the instance-level integration' do
+ expect(project.services.count).to eq(1)
+ expect(project.services.first.api_url).to eq(instance_integration.api_url)
+ expect(project.services.first.inherit_from_id).to eq(instance_integration.id)
+ end
end
- end
- context 'when a bad service template is created' do
- it 'sets service to be inactive' do
- opts[:import_url] = 'http://www.gitlab.com/gitlab-org/gitlab-foss'
- create(:service, type: 'DroneCiService', project: nil, template: true, active: true)
+ context 'when there is an active service template' do
+ let!(:template_integration) { create(:prometheus_service, :template, api_url: 'https://prometheus.template.com/') }
- project = create_project(user, opts)
- service = project.services.first
+ it 'creates a service from the template' do
+ expect(project.services.count).to eq(1)
+ expect(project.services.first.api_url).to eq(template_integration.api_url)
+ expect(project.services.first.inherit_from_id).to be_nil
+ end
+ end
- expect(project).to be_persisted
- expect(service.active).to be false
+ context 'when there is an invalid integration' do
+ before do
+ create(:service, :template, type: 'DroneCiService', active: true)
+ end
+
+ it 'creates an inactive service' do
+ expect(project).to be_persisted
+ expect(project.services.first.active).to be false
+ end
end
end
@@ -547,7 +667,9 @@ describe Projects::CreateService, '#execute' do
)
expect(AuthorizedProjectUpdate::UserRefreshWithLowUrgencyWorker).to(
receive(:bulk_perform_in)
- .with(1.hour, array_including([user.id], [other_user.id]))
+ .with(1.hour,
+ array_including([user.id], [other_user.id]),
+ batch_delay: 30.seconds, batch_size: 100)
.and_call_original
)
diff --git a/spec/services/projects/group_links/create_service_spec.rb b/spec/services/projects/group_links/create_service_spec.rb
index 92667184be8..22f7c8bdcb4 100644
--- a/spec/services/projects/group_links/create_service_spec.rb
+++ b/spec/services/projects/group_links/create_service_spec.rb
@@ -3,16 +3,17 @@
require 'spec_helper'
describe Projects::GroupLinks::CreateService, '#execute' do
- let(:user) { create :user }
- let(:group) { create :group }
- let(:project) { create :project }
+ let_it_be(:user) { create :user }
+ let_it_be(:group) { create :group }
+ let_it_be(:project) { create :project }
let(:opts) do
{
link_group_access: '30',
expires_at: nil
}
end
- let(:subject) { described_class.new(project, user, opts) }
+
+ subject { described_class.new(project, user, opts) }
before do
group.add_developer(user)
@@ -22,6 +23,12 @@ describe Projects::GroupLinks::CreateService, '#execute' do
expect { subject.execute(group) }.to change { project.project_group_links.count }.from(0).to(1)
end
+ it 'updates authorization' do
+ expect { subject.execute(group) }.to(
+ change { Ability.allowed?(user, :read_project, project) }
+ .from(false).to(true))
+ end
+
it 'returns false if group is blank' do
expect { subject.execute(nil) }.not_to change { project.project_group_links.count }
end
diff --git a/spec/services/projects/group_links/destroy_service_spec.rb b/spec/services/projects/group_links/destroy_service_spec.rb
index 0fd1fcfe1a5..0a8c9580e70 100644
--- a/spec/services/projects/group_links/destroy_service_spec.rb
+++ b/spec/services/projects/group_links/destroy_service_spec.rb
@@ -3,15 +3,25 @@
require 'spec_helper'
describe Projects::GroupLinks::DestroyService, '#execute' do
- let(:project) { create(:project, :private) }
- let!(:group_link) { create(:project_group_link, project: project) }
- let(:user) { create :user }
- let(:subject) { described_class.new(project, user) }
+ let_it_be(:user) { create :user }
+ let_it_be(:project) { create(:project, :private) }
+ let_it_be(:group) { create(:group) }
+ let!(:group_link) { create(:project_group_link, project: project, group: group) }
+
+ subject { described_class.new(project, user) }
it 'removes group from project' do
expect { subject.execute(group_link) }.to change { project.project_group_links.count }.from(1).to(0)
end
+ it 'updates authorization' do
+ group.add_maintainer(user)
+
+ expect { subject.execute(group_link) }.to(
+ change { Ability.allowed?(user, :read_project, project) }
+ .from(true).to(false))
+ end
+
it 'returns false if group_link is blank' do
expect { subject.execute(nil) }.not_to change { project.project_group_links.count }
end
diff --git a/spec/services/projects/group_links/update_service_spec.rb b/spec/services/projects/group_links/update_service_spec.rb
new file mode 100644
index 00000000000..5be2ae1e0f7
--- /dev/null
+++ b/spec/services/projects/group_links/update_service_spec.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Projects::GroupLinks::UpdateService, '#execute' do
+ let_it_be(:user) { create :user }
+ let_it_be(:group) { create :group }
+ let_it_be(:project) { create :project }
+ let!(:link) { create(:project_group_link, project: project, group: group) }
+
+ let(:expiry_date) { 1.month.from_now.to_date }
+ let(:group_link_params) do
+ { group_access: Gitlab::Access::GUEST,
+ expires_at: expiry_date }
+ end
+
+ subject { described_class.new(link).execute(group_link_params) }
+
+ before do
+ group.add_developer(user)
+ end
+
+ it 'updates existing link' do
+ expect(link.group_access).to eq(Gitlab::Access::DEVELOPER)
+ expect(link.expires_at).to be_nil
+
+ subject
+
+ link.reload
+
+ expect(link.group_access).to eq(Gitlab::Access::GUEST)
+ expect(link.expires_at).to eq(expiry_date)
+ end
+
+ it 'updates project permissions' do
+ expect { subject }.to change { user.can?(:create_release, project) }.from(true).to(false)
+ end
+
+ it 'executes UserProjectAccessChangedService' do
+ expect_next_instance_of(UserProjectAccessChangedService) do |service|
+ expect(service).to receive(:execute)
+ end
+
+ subject
+ end
+
+ context 'with only param not requiring authorization refresh' do
+ let(:group_link_params) { { expires_at: Date.tomorrow } }
+
+ it 'does not execute UserProjectAccessChangedService' do
+ expect(UserProjectAccessChangedService).not_to receive(:new)
+
+ subject
+ end
+ end
+end
diff --git a/spec/services/projects/import_export/export_service_spec.rb b/spec/services/projects/import_export/export_service_spec.rb
index 5f496cb1e56..19891341311 100644
--- a/spec/services/projects/import_export/export_service_spec.rb
+++ b/spec/services/projects/import_export/export_service_spec.rb
@@ -119,9 +119,7 @@ describe Projects::ImportExport::ExportService do
end
it 'notifies logger' do
- allow(Rails.logger).to receive(:error)
-
- expect(Rails.logger).to receive(:error)
+ expect(service.instance_variable_get(:@logger)).to receive(:error)
end
end
end
@@ -149,7 +147,7 @@ describe Projects::ImportExport::ExportService do
end
it 'notifies logger' do
- expect(Rails.logger).to receive(:error)
+ expect(service.instance_variable_get(:@logger)).to receive(:error)
end
it 'does not call the export strategy' do
diff --git a/spec/services/projects/lsif_data_service_spec.rb b/spec/services/projects/lsif_data_service_spec.rb
deleted file mode 100644
index 4866f848121..00000000000
--- a/spec/services/projects/lsif_data_service_spec.rb
+++ /dev/null
@@ -1,126 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe Projects::LsifDataService do
- let(:artifact) { create(:ci_job_artifact, :lsif) }
- let(:project) { build_stubbed(:project) }
- let(:path) { 'main.go' }
- let(:commit_id) { Digest::SHA1.hexdigest(SecureRandom.hex) }
-
- let(:service) { described_class.new(artifact.file, project, commit_id) }
-
- describe '#execute' do
- def highlighted_value(value)
- [{ language: 'go', value: Gitlab::Highlight.highlight(nil, value, language: 'go') }]
- end
-
- context 'fetched lsif file', :use_clean_rails_memory_store_caching do
- it 'is cached' do
- service.execute(path)
-
- cached_data = Rails.cache.fetch("project:#{project.id}:lsif:#{commit_id}")
-
- expect(cached_data.keys).to eq(%w[def_refs doc_ranges docs hover_refs ranges])
- end
- end
-
- context 'for main.go' do
- let(:path_prefix) { "/#{project.full_path}/-/blob/#{commit_id}" }
-
- it 'returns lsif ranges for the file' do
- expect(service.execute(path)).to eq([
- {
- end_char: 9,
- end_line: 6,
- start_char: 5,
- start_line: 6,
- definition_url: "#{path_prefix}/main.go#L7",
- hover: highlighted_value('func main()')
- },
- {
- end_char: 36,
- end_line: 3,
- start_char: 1,
- start_line: 3,
- definition_url: "#{path_prefix}/main.go#L4",
- hover: highlighted_value('package "github.com/user/hello/morestrings" ("github.com/user/hello/morestrings")')
- },
- {
- end_char: 12,
- end_line: 7,
- start_char: 1,
- start_line: 7,
- definition_url: "#{path_prefix}/main.go#L4",
- hover: highlighted_value('package "github.com/user/hello/morestrings" ("github.com/user/hello/morestrings")')
- },
- {
- end_char: 20,
- end_line: 7,
- start_char: 13,
- start_line: 7,
- definition_url: "#{path_prefix}/morestrings/reverse.go#L11",
- hover: highlighted_value('func Reverse(s string) string') + [{ value: "This method reverses a string \n\n" }]
- },
- {
- end_char: 12,
- end_line: 8,
- start_char: 1,
- start_line: 8,
- definition_url: "#{path_prefix}/main.go#L4",
- hover: highlighted_value('package "github.com/user/hello/morestrings" ("github.com/user/hello/morestrings")')
- },
- {
- end_char: 18,
- end_line: 8,
- start_char: 13,
- start_line: 8,
- definition_url: "#{path_prefix}/morestrings/reverse.go#L5",
- hover: highlighted_value('func Func2(i int) string')
- }
- ])
- end
- end
-
- context 'for morestring/reverse.go' do
- let(:path) { 'morestrings/reverse.go' }
-
- it 'returns lsif ranges for the file' do
- expect(service.execute(path).first).to eq({
- end_char: 2,
- end_line: 11,
- start_char: 1,
- start_line: 11,
- definition_url: "/#{project.full_path}/-/blob/#{commit_id}/morestrings/reverse.go#L12",
- hover: highlighted_value('var a string')
- })
- end
- end
-
- context 'for an unknown file' do
- let(:path) { 'unknown.go' }
-
- it 'returns nil' do
- expect(service.execute(path)).to eq(nil)
- end
- end
- end
-
- describe '#doc_id' do
- context 'when the passed path matches multiple files' do
- let(:path) { 'check/main.go' }
- let(:docs) do
- {
- 1 => 'cmd/check/main.go',
- 2 => 'cmd/command.go',
- 3 => 'check/main.go',
- 4 => 'cmd/nested/check/main.go'
- }
- end
-
- it 'fetches the document with the shortest absolute path' do
- expect(service.__send__(:find_doc_id, docs, path)).to eq(3)
- end
- end
- end
-end
diff --git a/spec/services/projects/operations/update_service_spec.rb b/spec/services/projects/operations/update_service_spec.rb
index 99a9fdd4184..f4d62b48fe5 100644
--- a/spec/services/projects/operations/update_service_spec.rb
+++ b/spec/services/projects/operations/update_service_spec.rb
@@ -96,7 +96,8 @@ describe Projects::Operations::UpdateService do
let(:params) do
{
metrics_setting_attributes: {
- external_dashboard_url: 'http://gitlab.com'
+ external_dashboard_url: 'http://gitlab.com',
+ dashboard_timezone: 'utc'
}
}
end
@@ -108,6 +109,7 @@ describe Projects::Operations::UpdateService do
expect(project.reload.metrics_setting.external_dashboard_url).to eq(
'http://gitlab.com'
)
+ expect(project.metrics_setting.dashboard_timezone).to eq('utc')
end
end
@@ -122,22 +124,25 @@ describe Projects::Operations::UpdateService do
expect(project.reload.metrics_setting.external_dashboard_url).to eq(
'http://gitlab.com'
)
+ expect(project.metrics_setting.dashboard_timezone).to eq('utc')
end
+ end
- context 'with blank external_dashboard_url in params' do
- let(:params) do
- {
- metrics_setting_attributes: {
- external_dashboard_url: ''
- }
+ context 'with blank external_dashboard_url' do
+ let(:params) do
+ {
+ metrics_setting_attributes: {
+ external_dashboard_url: '',
+ dashboard_timezone: 'utc'
}
- end
+ }
+ end
- it 'destroys the metrics_setting entry in DB' do
- expect(result[:status]).to eq(:success)
+ it 'updates dashboard_timezone' do
+ expect(result[:status]).to eq(:success)
- expect(project.reload.metrics_setting).to be_nil
- end
+ expect(project.reload.metrics_setting.external_dashboard_url).to be(nil)
+ expect(project.metrics_setting.dashboard_timezone).to eq('utc')
end
end
end
diff --git a/spec/services/projects/prometheus/alerts/create_events_service_spec.rb b/spec/services/projects/prometheus/alerts/create_events_service_spec.rb
index 35f23afd7a2..61236b5bbdb 100644
--- a/spec/services/projects/prometheus/alerts/create_events_service_spec.rb
+++ b/spec/services/projects/prometheus/alerts/create_events_service_spec.rb
@@ -89,9 +89,9 @@ describe Projects::Prometheus::Alerts::CreateEventsService do
context 'with a resolved payload' do
let(:started_at) { truncate_to_second(Time.current) }
let(:ended_at) { started_at + 1 }
- let(:payload_key) { PrometheusAlertEvent.payload_key_for(alert.prometheus_metric_id, utc_rfc3339(started_at)) }
let(:resolved_event) { alert_payload(status: 'resolved', started_at: started_at, ended_at: ended_at) }
let(:alerts_payload) { { 'alerts' => [resolved_event] } }
+ let(:payload_key) { Gitlab::Alerting::Alert.new(project: project, payload: resolved_event).gitlab_fingerprint }
context 'with a matching firing event' do
before do
diff --git a/spec/services/projects/prometheus/alerts/notify_service_spec.rb b/spec/services/projects/prometheus/alerts/notify_service_spec.rb
index 009543f9016..95acedb1e76 100644
--- a/spec/services/projects/prometheus/alerts/notify_service_spec.rb
+++ b/spec/services/projects/prometheus/alerts/notify_service_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
describe Projects::Prometheus::Alerts::NotifyService do
+ include PrometheusHelpers
+
let_it_be(:project, reload: true) { create(:project) }
let(:service) { described_class.new(project, nil, payload) }
@@ -92,9 +94,10 @@ describe Projects::Prometheus::Alerts::NotifyService do
end
context 'with valid payload' do
- let(:alert_firing) { create(:prometheus_alert, project: project) }
- let(:alert_resolved) { create(:prometheus_alert, project: project) }
- let(:payload_raw) { payload_for(firing: [alert_firing], resolved: [alert_resolved]) }
+ let_it_be(:alert_firing) { create(:prometheus_alert, project: project) }
+ let_it_be(:alert_resolved) { create(:prometheus_alert, project: project) }
+ let_it_be(:cluster) { create(:cluster, :provided_by_user, projects: [project]) }
+ let(:payload_raw) { prometheus_alert_payload(firing: [alert_firing], resolved: [alert_resolved]) }
let(:payload) { ActionController::Parameters.new(payload_raw).permit! }
let(:payload_alert_firing) { payload_raw['alerts'].first }
let(:token) { 'token' }
@@ -116,9 +119,7 @@ describe Projects::Prometheus::Alerts::NotifyService do
with_them do
before do
- cluster = create(:cluster, :provided_by_user,
- projects: [project],
- enabled: cluster_enabled)
+ cluster.update!(enabled: cluster_enabled)
if status
create(:clusters_applications_prometheus, status,
@@ -179,6 +180,39 @@ describe Projects::Prometheus::Alerts::NotifyService do
end
end
+ context 'with generic alerts integration' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:alerts_service, :token, :result) do
+ :active | :valid | :success
+ :active | :invalid | :failure
+ :active | nil | :failure
+ :inactive | :valid | :failure
+ nil | nil | :failure
+ end
+
+ with_them do
+ let(:valid) { project.alerts_service.token }
+ let(:invalid) { 'invalid token' }
+ let(:token_input) { public_send(token) if token }
+
+ before do
+ if alerts_service
+ create(:alerts_service, alerts_service, project: project)
+ end
+ end
+
+ case result = params[:result]
+ when :success
+ it_behaves_like 'notifies alerts'
+ when :failure
+ it_behaves_like 'no notifications', http_status: :unauthorized
+ else
+ raise "invalid result: #{result.inspect}"
+ end
+ end
+ end
+
context 'alert emails' do
before do
create(:prometheus_service, project: project)
@@ -227,7 +261,7 @@ describe Projects::Prometheus::Alerts::NotifyService do
context 'with multiple firing alerts and resolving alerts' do
let(:payload_raw) do
- payload_for(firing: [alert_firing, alert_firing], resolved: [alert_resolved])
+ prometheus_alert_payload(firing: [alert_firing, alert_firing], resolved: [alert_resolved])
end
it 'processes Prometheus alerts' do
@@ -258,7 +292,7 @@ describe Projects::Prometheus::Alerts::NotifyService do
context 'multiple firing alerts' do
let(:payload_raw) do
- payload_for(firing: [alert_firing, alert_firing], resolved: [])
+ prometheus_alert_payload(firing: [alert_firing, alert_firing], resolved: [])
end
it_behaves_like 'processes incident issues', 2
@@ -266,7 +300,7 @@ describe Projects::Prometheus::Alerts::NotifyService do
context 'without firing alerts' do
let(:payload_raw) do
- payload_for(firing: [], resolved: [alert_resolved])
+ prometheus_alert_payload(firing: [], resolved: [alert_resolved])
end
it_behaves_like 'processes incident issues', 1
@@ -284,24 +318,17 @@ describe Projects::Prometheus::Alerts::NotifyService do
end
context 'with invalid payload' do
- context 'without version' do
+ context 'when payload is not processable' do
let(:payload) { {} }
- it_behaves_like 'no notifications', http_status: :unprocessable_entity
- end
-
- context 'when version is not "4"' do
- let(:payload) { { 'version' => '5' } }
+ before do
+ allow(described_class).to receive(:processable?).with(payload)
+ .and_return(false)
+ end
it_behaves_like 'no notifications', http_status: :unprocessable_entity
end
- context 'with missing alerts' do
- let(:payload) { { 'version' => '4' } }
-
- it_behaves_like 'no notifications', http_status: :unauthorized
- end
-
context 'when the payload is too big' do
let(:payload) { { 'the-payload-is-too-big' => true } }
let(:deep_size_object) { instance_double(Gitlab::Utils::DeepSize, valid?: false) }
@@ -328,50 +355,39 @@ describe Projects::Prometheus::Alerts::NotifyService do
end
end
- private
-
- def payload_for(firing: [], resolved: [])
- status = firing.any? ? 'firing' : 'resolved'
- alerts = firing + resolved
- alert_name = alerts.first.title
- prometheus_metric_id = alerts.first.prometheus_metric_id.to_s
-
- alerts_map = \
- firing.map { |alert| map_alert_payload('firing', alert) } +
- resolved.map { |alert| map_alert_payload('resolved', alert) }
-
- # See https://prometheus.io/docs/alerting/configuration/#%3Cwebhook_config%3E
- {
- 'version' => '4',
- 'receiver' => 'gitlab',
- 'status' => status,
- 'alerts' => alerts_map,
- 'groupLabels' => {
- 'alertname' => alert_name
- },
- 'commonLabels' => {
- 'alertname' => alert_name,
- 'gitlab' => 'hook',
- 'gitlab_alert_id' => prometheus_metric_id
- },
- 'commonAnnotations' => {},
- 'externalURL' => '',
- 'groupKey' => "{}:{alertname=\'#{alert_name}\'}"
- }
- end
+ describe '.processable?' do
+ let(:valid_payload) { prometheus_alert_payload }
+
+ subject { described_class.processable?(payload) }
+
+ context 'with valid payload' do
+ let(:payload) { valid_payload }
+
+ it { is_expected.to eq(true) }
+
+ context 'containing unrelated keys' do
+ let(:payload) { valid_payload.merge('unrelated' => 'key') }
- def map_alert_payload(status, alert)
- {
- 'status' => status,
- 'labels' => {
- 'alertname' => alert.title,
- 'gitlab' => 'hook',
- 'gitlab_alert_id' => alert.prometheus_metric_id.to_s
- },
- 'annotations' => {},
- 'startsAt' => '2018-09-24T08:57:31.095725221Z',
- 'endsAt' => '0001-01-01T00:00:00Z',
- 'generatorURL' => 'http://prometheus-prometheus-server-URL'
- }
+ it { is_expected.to eq(true) }
+ end
+ end
+
+ context 'with invalid payload' do
+ where(:missing_key) do
+ described_class::REQUIRED_PAYLOAD_KEYS.to_a
+ end
+
+ with_them do
+ let(:payload) { valid_payload.except(missing_key) }
+
+ it { is_expected.to eq(false) }
+ end
+ end
+
+ context 'with unsupported version' do
+ let(:payload) { valid_payload.merge('version' => '5') }
+
+ it { is_expected.to eq(false) }
+ end
end
end
diff --git a/spec/services/projects/propagate_service_template_spec.rb b/spec/services/projects/propagate_service_template_spec.rb
index 7188ac5f733..ddc27c037f8 100644
--- a/spec/services/projects/propagate_service_template_spec.rb
+++ b/spec/services/projects/propagate_service_template_spec.rb
@@ -62,8 +62,8 @@ describe Projects::PropagateServiceTemplate do
}
)
- Service.build_from_template(project.id, service_template).save!
- Service.build_from_template(project.id, other_service).save!
+ Service.build_from_integration(project.id, service_template).save!
+ Service.build_from_integration(project.id, other_service).save!
expect { described_class.propagate(service_template) }
.not_to change { Service.count }
diff --git a/spec/services/projects/update_pages_service_spec.rb b/spec/services/projects/update_pages_service_spec.rb
index f561a303be4..29c3c300d1b 100644
--- a/spec/services/projects/update_pages_service_spec.rb
+++ b/spec/services/projects/update_pages_service_spec.rb
@@ -158,6 +158,23 @@ describe Projects::UpdatePagesService do
expect(project.pages_metadatum).not_to be_deployed
end
end
+
+ context 'with background jobs running', :sidekiq_inline do
+ where(:ci_atomic_processing) do
+ [true, false]
+ end
+
+ with_them do
+ before do
+ stub_feature_flags(ci_atomic_processing: ci_atomic_processing)
+ end
+
+ it 'succeeds' do
+ expect(project.pages_deployed?).to be_falsey
+ expect(execute).to eq(:success)
+ end
+ end
+ end
end
end
diff --git a/spec/services/projects/update_remote_mirror_service_spec.rb b/spec/services/projects/update_remote_mirror_service_spec.rb
index 38c2dc0780e..418973fb0a6 100644
--- a/spec/services/projects/update_remote_mirror_service_spec.rb
+++ b/spec/services/projects/update_remote_mirror_service_spec.rb
@@ -10,6 +10,10 @@ describe Projects::UpdateRemoteMirrorService do
subject(:service) { described_class.new(project, project.creator) }
+ before do
+ stub_feature_flags(gitaly_ruby_remote_branches_ls_remote: false)
+ end
+
describe '#execute' do
subject(:execute!) { service.execute(remote_mirror, 0) }
@@ -102,6 +106,19 @@ describe Projects::UpdateRemoteMirrorService do
expect(remote_mirror.last_error).to include("refs/heads/develop")
end
end
+
+ # https://gitlab.com/gitlab-org/gitaly/-/issues/2670
+ context 'when `gitaly_ruby_remote_branches_ls_remote` is enabled' do
+ before do
+ stub_feature_flags(gitaly_ruby_remote_branches_ls_remote: true)
+ end
+
+ it 'does not perform a fetch' do
+ expect(project.repository).not_to receive(:fetch_remote)
+
+ execute!
+ end
+ end
end
def stub_fetch_remote(project, remote_name:, ssh_auth:)
diff --git a/spec/services/projects/update_repository_storage_service_spec.rb b/spec/services/projects/update_repository_storage_service_spec.rb
index 28b79bc61d9..e37580e7367 100644
--- a/spec/services/projects/update_repository_storage_service_spec.rb
+++ b/spec/services/projects/update_repository_storage_service_spec.rb
@@ -16,7 +16,7 @@ describe Projects::UpdateRepositoryStorageService do
end
context 'without wiki and design repository' do
- let(:project) { create(:project, :repository, repository_read_only: true, wiki_enabled: false) }
+ let(:project) { create(:project, :repository, wiki_enabled: false) }
let(:destination) { 'test_second_storage' }
let(:repository_storage_move) { create(:project_repository_storage_move, :scheduled, project: project, destination_storage_name: destination) }
let!(:checksum) { project.repository.checksum }
@@ -131,7 +131,7 @@ describe Projects::UpdateRepositoryStorageService do
context 'with wiki repository' do
include_examples 'moves repository to another storage', 'wiki' do
- let(:project) { create(:project, :repository, repository_read_only: true, wiki_enabled: true) }
+ let(:project) { create(:project, :repository, wiki_enabled: true) }
let(:repository) { project.wiki.repository }
let(:destination) { 'test_second_storage' }
let(:repository_storage_move) { create(:project_repository_storage_move, :scheduled, project: project, destination_storage_name: destination) }
@@ -144,7 +144,7 @@ describe Projects::UpdateRepositoryStorageService do
context 'with design repository' do
include_examples 'moves repository to another storage', 'design' do
- let(:project) { create(:project, :repository, repository_read_only: true) }
+ let(:project) { create(:project, :repository) }
let(:repository) { project.design_repository }
let(:destination) { 'test_second_storage' }
let(:repository_storage_move) { create(:project_repository_storage_move, :scheduled, project: project, destination_storage_name: destination) }
diff --git a/spec/services/projects/update_service_spec.rb b/spec/services/projects/update_service_spec.rb
index ce9765a36ba..8a17884f641 100644
--- a/spec/services/projects/update_service_spec.rb
+++ b/spec/services/projects/update_service_spec.rb
@@ -254,7 +254,7 @@ describe Projects::UpdateService do
it 'logs an error and creates a metric when wiki can not be created' do
project.project_feature.update(wiki_access_level: ProjectFeature::DISABLED)
- expect_any_instance_of(ProjectWiki).to receive(:wiki).and_raise(ProjectWiki::CouldNotCreateWikiError)
+ expect_any_instance_of(ProjectWiki).to receive(:wiki).and_raise(Wiki::CouldNotCreateWikiError)
expect_any_instance_of(described_class).to receive(:log_error).with("Could not create wiki for #{project.full_name}")
counter = double(:counter)
@@ -552,6 +552,63 @@ describe Projects::UpdateService do
end
end
end
+
+ describe 'when changing repository_storage' do
+ let(:repository_read_only) { false }
+ let(:project) { create(:project, :repository, repository_read_only: repository_read_only) }
+ let(:opts) { { repository_storage: 'test_second_storage' } }
+
+ before do
+ stub_storage_settings('test_second_storage' => { 'path' => 'tmp/tests/extra_storage' })
+ end
+
+ shared_examples 'the transfer was not scheduled' do
+ it 'does not schedule the transfer' do
+ expect do
+ update_project(project, user, opts)
+ end.not_to change(project.repository_storage_moves, :count)
+ end
+ end
+
+ context 'authenticated as admin' do
+ let(:user) { create(:admin) }
+
+ it 'schedules the transfer of the repository to the new storage and locks the project' do
+ update_project(project, admin, opts)
+
+ expect(project).to be_repository_read_only
+ expect(project.repository_storage_moves.last).to have_attributes(
+ state: ::ProjectRepositoryStorageMove.state_machines[:state].states[:scheduled].value,
+ source_storage_name: 'default',
+ destination_storage_name: 'test_second_storage'
+ )
+ end
+
+ context 'the repository is read-only' do
+ let(:repository_read_only) { true }
+
+ it_behaves_like 'the transfer was not scheduled'
+ end
+
+ context 'the storage has not changed' do
+ let(:opts) { { repository_storage: 'default' } }
+
+ it_behaves_like 'the transfer was not scheduled'
+ end
+
+ context 'the storage does not exist' do
+ let(:opts) { { repository_storage: 'nonexistent' } }
+
+ it_behaves_like 'the transfer was not scheduled'
+ end
+ end
+
+ context 'authenticated as user' do
+ let(:user) { create(:user) }
+
+ it_behaves_like 'the transfer was not scheduled'
+ end
+ end
end
describe '#run_auto_devops_pipeline?' do
@@ -611,25 +668,6 @@ describe Projects::UpdateService do
end
end
- describe 'repository_storage' do
- let(:admin) { create(:admin) }
- let(:user) { create(:user) }
- let(:project) { create(:project, :repository) }
- let(:opts) { { repository_storage: 'test_second_storage' } }
-
- it 'calls the change repository storage method if the storage changed' do
- expect(project).to receive(:change_repository_storage).with('test_second_storage')
-
- update_project(project, admin, opts).inspect
- end
-
- it "doesn't call the change repository storage for non-admin users" do
- expect(project).not_to receive(:change_repository_storage)
-
- update_project(project, user, opts).inspect
- end
- end
-
def update_project(project, user, opts)
described_class.new(project, user, opts).execute
end
diff --git a/spec/services/prometheus/create_default_alerts_service_spec.rb b/spec/services/prometheus/create_default_alerts_service_spec.rb
index 3382844c99a..a28c38491de 100644
--- a/spec/services/prometheus/create_default_alerts_service_spec.rb
+++ b/spec/services/prometheus/create_default_alerts_service_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe Prometheus::CreateDefaultAlertsService do
- let_it_be(:project) { create(:project) }
+ let_it_be(:project) { create(:project, :repository) }
let(:instance) { described_class.new(project: project) }
let(:expected_alerts) { described_class::DEFAULT_ALERTS }
@@ -45,6 +45,23 @@ describe Prometheus::CreateDefaultAlertsService do
.by(expected_alerts.size)
end
+ it 'does not schedule an update to prometheus' do
+ expect(::Clusters::Applications::ScheduleUpdateService).not_to receive(:new)
+ execute
+ end
+
+ context 'cluster with prometheus exists' do
+ let!(:cluster) { create(:cluster, :with_installed_prometheus, :provided_by_user, projects: [project]) }
+
+ it 'schedules an update to prometheus' do
+ expect_next_instance_of(::Clusters::Applications::ScheduleUpdateService) do |instance|
+ expect(instance).to receive(:execute)
+ end
+
+ execute
+ end
+ end
+
context 'multiple environments' do
let!(:production) { create(:environment, project: project, name: 'production') }
diff --git a/spec/services/prometheus/proxy_service_spec.rb b/spec/services/prometheus/proxy_service_spec.rb
index 656ccea10de..bd451ff00a1 100644
--- a/spec/services/prometheus/proxy_service_spec.rb
+++ b/spec/services/prometheus/proxy_service_spec.rb
@@ -41,6 +41,27 @@ describe Prometheus::ProxyService do
expect(result.params).to eq('query' => '1')
end
end
+
+ context 'with series method' do
+ let(:params) do
+ ActionController::Parameters.new(
+ match: ['1'],
+ start: "2020-06-11T10:15:51Z",
+ end: "2020-06-11T11:16:06Z",
+ unknown_param: 'val'
+ ).permit!
+ end
+
+ it 'allows match, start and end parameters' do
+ result = described_class.new(environment, 'GET', 'series', params)
+
+ expect(result.params).to eq(
+ 'match' => ['1'],
+ 'start' => "2020-06-11T10:15:51Z",
+ 'end' => "2020-06-11T11:16:06Z"
+ )
+ end
+ end
end
describe '#execute' do
@@ -182,6 +203,24 @@ describe Prometheus::ProxyService do
end
end
end
+
+ context 'with series API' do
+ let(:rest_client_response) { instance_double(RestClient::Response, code: 200, body: '') }
+
+ let(:params) do
+ ActionController::Parameters.new(match: ['1'], start: 1.hour.ago.rfc3339, end: Time.current.rfc3339).permit!
+ end
+
+ subject { described_class.new(environment, 'GET', 'series', params) }
+
+ it 'calls PrometheusClient with given parameters' do
+ expect(prometheus_client).to receive(:proxy)
+ .with('series', params.to_h)
+ .and_return(rest_client_response)
+
+ subject.execute
+ end
+ end
end
end
diff --git a/spec/services/prometheus/proxy_variable_substitution_service_spec.rb b/spec/services/prometheus/proxy_variable_substitution_service_spec.rb
index 5982dcbc404..2435dda07b4 100644
--- a/spec/services/prometheus/proxy_variable_substitution_service_spec.rb
+++ b/spec/services/prometheus/proxy_variable_substitution_service_spec.rb
@@ -186,5 +186,19 @@ describe Prometheus::ProxyVariableSubstitutionService do
end
end
end
+
+ context '__range' do
+ let(:params_keys) do
+ {
+ query: 'topk(5, sum by (method) (rate(rest_client_requests_total[{{__range}}])))',
+ start_time: '2020-05-29T08:19:07.142Z',
+ end_time: '2020-05-29T16:19:07.142Z'
+ }
+ end
+
+ it_behaves_like 'success' do
+ let(:expected_query) { "topk(5, sum by (method) (rate(rest_client_requests_total[#{8.hours.to_i}s])))" }
+ end
+ end
end
end
diff --git a/spec/services/quick_actions/interpret_service_spec.rb b/spec/services/quick_actions/interpret_service_spec.rb
index a9de0a747f6..1bd402e38be 100644
--- a/spec/services/quick_actions/interpret_service_spec.rb
+++ b/spec/services/quick_actions/interpret_service_spec.rb
@@ -1621,6 +1621,29 @@ describe QuickActions::InterpretService do
expect(message).to eq("Created branch '#{branch_name}' and a merge request to resolve this issue.")
end
end
+
+ context 'submit_review command' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:note) do
+ [
+ 'I like it',
+ '/submit_review'
+ ]
+ end
+
+ with_them do
+ let(:content) { '/submit_review' }
+ let!(:draft_note) { create(:draft_note, note: note, merge_request: merge_request, author: developer) }
+
+ it 'submits the users current review' do
+ _, _, message = service.execute(content, merge_request)
+
+ expect { draft_note.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ expect(message).to eq('Submitted the current review.')
+ end
+ end
+ end
end
describe '#explain' do
diff --git a/spec/services/releases/create_evidence_service_spec.rb b/spec/services/releases/create_evidence_service_spec.rb
new file mode 100644
index 00000000000..caa36a6b21d
--- /dev/null
+++ b/spec/services/releases/create_evidence_service_spec.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Releases::CreateEvidenceService do
+ let_it_be(:project) { create(:project) }
+ let(:release) { create(:release, project: project) }
+ let(:service) { described_class.new(release) }
+
+ it 'creates evidence' do
+ expect { service.execute }.to change { release.reload.evidences.count }.by(1)
+ end
+
+ it 'saves evidence summary' do
+ service.execute
+ evidence = Releases::Evidence.last
+
+ expect(release.tag).not_to be_nil
+ expect(evidence.summary["release"]["tag_name"]).to eq(release.tag)
+ end
+
+ it 'saves sha' do
+ service.execute
+ evidence = Releases::Evidence.last
+
+ expect(evidence.summary_sha).not_to be_nil
+ end
+end
diff --git a/spec/services/releases/create_service_spec.rb b/spec/services/releases/create_service_spec.rb
index d0859500440..4e3d9d5f108 100644
--- a/spec/services/releases/create_service_spec.rb
+++ b/spec/services/releases/create_service_spec.rb
@@ -186,4 +186,181 @@ describe Releases::CreateService do
end
end
end
+
+ context 'Evidence collection' do
+ let(:sha) { project.repository.commit('master').sha }
+ let(:params) do
+ {
+ name: 'New release',
+ ref: 'master',
+ tag: 'v0.1',
+ description: 'Super nice release',
+ released_at: released_at
+ }.compact
+ end
+ let(:last_release) { project.releases.last }
+
+ around do |example|
+ Timecop.freeze { example.run }
+ end
+
+ subject { service.execute }
+
+ context 'historical release' do
+ let(:released_at) { 3.weeks.ago }
+
+ it 'does not execute CreateEvidenceWorker' do
+ expect { subject }.not_to change(CreateEvidenceWorker.jobs, :size)
+ end
+
+ it 'does not create an Evidence object', :sidekiq_inline do
+ expect { subject }.not_to change(Releases::Evidence, :count)
+ end
+
+ it 'is a historical release' do
+ subject
+
+ expect(last_release.historical_release?).to be_truthy
+ end
+
+ it 'is not an upcoming release' do
+ subject
+
+ expect(last_release.upcoming_release?).to be_falsy
+ end
+ end
+
+ shared_examples 'uses the right pipeline for evidence' do
+ it 'creates evidence without pipeline if it does not exist', :sidekiq_inline do
+ expect_next_instance_of(Releases::CreateEvidenceService, anything, pipeline: nil) do |service|
+ expect(service).to receive(:execute).and_call_original
+ end
+
+ expect { subject }.to change(Releases::Evidence, :count).by(1)
+ end
+
+ it 'uses the last pipeline for evidence', :sidekiq_inline do
+ create(:ci_empty_pipeline, sha: sha, project: project) # old pipeline
+ pipeline = create(:ci_empty_pipeline, sha: sha, project: project)
+
+ expect_next_instance_of(Releases::CreateEvidenceService, anything, pipeline: pipeline) do |service|
+ expect(service).to receive(:execute).and_call_original
+ end
+
+ expect { subject }.to change(Releases::Evidence, :count).by(1)
+ end
+
+ context 'when old evidence_pipeline is passed to service' do
+ let!(:old_pipeline) { create(:ci_empty_pipeline, sha: sha, project: project) }
+ let!(:new_pipeline) { create(:ci_empty_pipeline, sha: sha, project: project) }
+ let(:params) do
+ super().merge(
+ evidence_pipeline: old_pipeline
+ )
+ end
+
+ it 'uses the old pipeline for evidence', :sidekiq_inline do
+ expect_next_instance_of(Releases::CreateEvidenceService, anything, pipeline: old_pipeline) do |service|
+ expect(service).to receive(:execute).and_call_original
+ end
+
+ expect { subject }.to change(Releases::Evidence, :count).by(1)
+ end
+ end
+
+ it 'pipeline is still being used for evidence if new pipeline is being created for tag', :sidekiq_inline do
+ pipeline = create(:ci_empty_pipeline, sha: sha, project: project)
+
+ expect(project.repository).to receive(:add_tag).and_wrap_original do |m, *args|
+ create(:ci_empty_pipeline, sha: sha, project: project)
+ m.call(*args)
+ end
+
+ expect_next_instance_of(Releases::CreateEvidenceService, anything, pipeline: pipeline) do |service|
+ expect(service).to receive(:execute).and_call_original
+ end
+
+ expect { subject }.to change(Releases::Evidence, :count).by(1)
+ end
+
+ it 'uses the last pipeline for evidence when tag is already created', :sidekiq_inline do
+ Tags::CreateService.new(project, user).execute('v0.1', 'master', nil)
+
+ expect(project.repository.find_tag('v0.1')).to be_present
+
+ create(:ci_empty_pipeline, sha: sha, project: project) # old pipeline
+ pipeline = create(:ci_empty_pipeline, sha: sha, project: project)
+
+ expect_next_instance_of(Releases::CreateEvidenceService, anything, pipeline: pipeline) do |service|
+ expect(service).to receive(:execute).and_call_original
+ end
+
+ expect { subject }.to change(Releases::Evidence, :count).by(1)
+ end
+ end
+
+ context 'immediate release' do
+ let(:released_at) { nil }
+
+ it 'sets `released_at` to the current dttm' do
+ subject
+
+ expect(last_release.updated_at).to be_like_time(Time.current)
+ end
+
+ it 'queues CreateEvidenceWorker' do
+ expect { subject }.to change(CreateEvidenceWorker.jobs, :size).by(1)
+ end
+
+ it 'creates Evidence', :sidekiq_inline do
+ expect { subject }.to change(Releases::Evidence, :count).by(1)
+ end
+
+ it 'is not a historical release' do
+ subject
+
+ expect(last_release.historical_release?).to be_falsy
+ end
+
+ it 'is not an upcoming release' do
+ subject
+
+ expect(last_release.upcoming_release?).to be_falsy
+ end
+
+ include_examples 'uses the right pipeline for evidence'
+ end
+
+ context 'upcoming release' do
+ let(:released_at) { 1.day.from_now }
+
+ it 'queues CreateEvidenceWorker' do
+ expect { subject }.to change(CreateEvidenceWorker.jobs, :size).by(1)
+ end
+
+ it 'queues CreateEvidenceWorker at the released_at timestamp' do
+ subject
+
+ expect(CreateEvidenceWorker.jobs.last['at'].to_i).to eq(released_at.to_i)
+ end
+
+ it 'creates Evidence', :sidekiq_inline do
+ expect { subject }.to change(Releases::Evidence, :count).by(1)
+ end
+
+ it 'is not a historical release' do
+ subject
+
+ expect(last_release.historical_release?).to be_falsy
+ end
+
+ it 'is an upcoming release' do
+ subject
+
+ expect(last_release.upcoming_release?).to be_truthy
+ end
+
+ include_examples 'uses the right pipeline for evidence'
+ end
+ end
end
diff --git a/spec/services/resource_events/change_state_service_spec.rb b/spec/services/resource_events/change_state_service_spec.rb
new file mode 100644
index 00000000000..e5d2a4ab11e
--- /dev/null
+++ b/spec/services/resource_events/change_state_service_spec.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe ResourceEvents::ChangeStateService do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:user) { create(:user) }
+
+ let(:issue) { create(:issue, project: project) }
+ let(:merge_request) { create(:merge_request, source_project: project) }
+
+ describe '#execute' do
+ context 'when resource is an issue' do
+ %w[opened reopened closed locked].each do |state|
+ it "creates the expected event if issue has #{state} state" do
+ described_class.new(user: user, resource: issue).execute(state)
+
+ event = issue.resource_state_events.last
+ expect(event.issue).to eq(issue)
+ expect(event.merge_request).to be_nil
+ expect(event.state).to eq(state)
+ end
+ end
+ end
+
+ context 'when resource is a merge request' do
+ %w[opened reopened closed locked merged].each do |state|
+ it "creates the expected event if merge request has #{state} state" do
+ described_class.new(user: user, resource: merge_request).execute(state)
+
+ event = merge_request.resource_state_events.last
+ expect(event.issue).to be_nil
+ expect(event.merge_request).to eq(merge_request)
+ expect(event.state).to eq(state)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/service_response_spec.rb b/spec/services/service_response_spec.rb
index a6567f52c6f..2c944a63ebb 100644
--- a/spec/services/service_response_spec.rb
+++ b/spec/services/service_response_spec.rb
@@ -84,4 +84,14 @@ describe ServiceResponse do
expect(described_class.error(message: 'Bad apple').error?).to eq(true)
end
end
+
+ describe '#errors' do
+ it 'returns an empty array for a successful response' do
+ expect(described_class.success.errors).to be_empty
+ end
+
+ it 'returns an array with a correct message for an error response' do
+ expect(described_class.error(message: 'error message').errors).to eq(['error message'])
+ end
+ end
end
diff --git a/spec/services/snippets/bulk_destroy_service_spec.rb b/spec/services/snippets/bulk_destroy_service_spec.rb
index f03d7496f94..6e5623e575f 100644
--- a/spec/services/snippets/bulk_destroy_service_spec.rb
+++ b/spec/services/snippets/bulk_destroy_service_spec.rb
@@ -69,6 +69,18 @@ describe Snippets::BulkDestroyService do
it_behaves_like 'error is raised' do
let(:error_message) { "You don't have access to delete these snippets." }
end
+
+ context 'when hard_delete option is passed' do
+ subject { described_class.new(service_user, snippets).execute(hard_delete: true) }
+
+ it 'returns a ServiceResponse success response' do
+ expect(subject).to be_success
+ end
+
+ it 'deletes all the snippets that belong to the user' do
+ expect { subject }.to change(Snippet, :count).by(-2)
+ end
+ end
end
context 'when an error is raised deleting the repository' do
diff --git a/spec/services/snippets/create_service_spec.rb b/spec/services/snippets/create_service_spec.rb
index 786fc3ec8dd..fa8cbc87563 100644
--- a/spec/services/snippets/create_service_spec.rb
+++ b/spec/services/snippets/create_service_spec.rb
@@ -109,7 +109,7 @@ describe Snippets::CreateService do
expect(snippet.repository.exists?).to be_truthy
end
- it 'commit the files to the repository' do
+ it 'commits the files to the repository' do
subject
blob = snippet.repository.blob_at('master', base_opts[:file_name])
@@ -230,6 +230,61 @@ describe Snippets::CreateService do
end
end
+ shared_examples 'when snippet_files param is present' do
+ let(:file_path) { 'snippet_file_path.rb' }
+ let(:content) { 'snippet_content' }
+ let(:snippet_files) { [{ action: 'create', file_path: file_path, content: content }] }
+ let(:base_opts) do
+ {
+ title: 'Test snippet',
+ visibility_level: Gitlab::VisibilityLevel::PRIVATE,
+ snippet_files: snippet_files
+ }
+ end
+
+ it 'creates a snippet with the provided attributes' do
+ expect(snippet.title).to eq(opts[:title])
+ expect(snippet.visibility_level).to eq(opts[:visibility_level])
+ expect(snippet.file_name).to eq(file_path)
+ expect(snippet.content).to eq(content)
+ end
+
+ it 'commit the files to the repository' do
+ subject
+
+ blob = snippet.repository.blob_at('master', file_path)
+
+ expect(blob.data).to eq content
+ end
+
+ context 'when content or file_name params are present' do
+ let(:extra_opts) { { content: 'foo', file_name: 'path' } }
+
+ it 'a validation error is raised' do
+ response = subject
+ snippet = response.payload[:snippet]
+
+ expect(response).to be_error
+ expect(snippet.errors.full_messages_for(:content)).to eq ['Content and snippet files cannot be used together']
+ expect(snippet.errors.full_messages_for(:file_name)).to eq ['File name and snippet files cannot be used together']
+ expect(snippet.repository.exists?).to be_falsey
+ end
+ end
+
+ context 'when snippet_files param is invalid' do
+ let(:snippet_files) { [{ action: 'invalid_action', file_path: 'snippet_file_path.rb', content: 'snippet_content' }] }
+
+ it 'a validation error is raised' do
+ response = subject
+ snippet = response.payload[:snippet]
+
+ expect(response).to be_error
+ expect(snippet.errors.full_messages_for(:snippet_files)).to eq ['Snippet files have invalid data']
+ expect(snippet.repository.exists?).to be_falsey
+ end
+ end
+ end
+
context 'when ProjectSnippet' do
let_it_be(:project) { create(:project) }
@@ -244,6 +299,7 @@ describe Snippets::CreateService do
it_behaves_like 'an error service response when save fails'
it_behaves_like 'creates repository and files'
it_behaves_like 'after_save callback to store_mentions', ProjectSnippet
+ it_behaves_like 'when snippet_files param is present'
context 'when uploaded files are passed to the service' do
let(:extra_opts) { { files: ['foo'] } }
@@ -270,6 +326,7 @@ describe Snippets::CreateService do
it_behaves_like 'an error service response when save fails'
it_behaves_like 'creates repository and files'
it_behaves_like 'after_save callback to store_mentions', PersonalSnippet
+ it_behaves_like 'when snippet_files param is present'
context 'when the snippet description contains files' do
include FileMoverHelpers
diff --git a/spec/services/snippets/update_service_spec.rb b/spec/services/snippets/update_service_spec.rb
index 6c3ae52befc..7e6441ad2f9 100644
--- a/spec/services/snippets/update_service_spec.rb
+++ b/spec/services/snippets/update_service_spec.rb
@@ -302,6 +302,82 @@ describe Snippets::UpdateService do
end
end
+ shared_examples 'when snippet_files param is present' do
+ let(:file_path) { 'CHANGELOG' }
+ let(:content) { 'snippet_content' }
+ let(:new_title) { 'New title' }
+ let(:snippet_files) { [{ action: 'update', previous_path: file_path, file_path: file_path, content: content }] }
+ let(:base_opts) do
+ {
+ title: new_title,
+ snippet_files: snippet_files
+ }
+ end
+
+ it 'updates a snippet with the provided attributes' do
+ file_path = 'foo'
+ snippet_files[0][:action] = 'move'
+ snippet_files[0][:file_path] = file_path
+
+ response = subject
+ snippet = response.payload[:snippet]
+
+ expect(response).to be_success
+ expect(snippet.title).to eq(new_title)
+ expect(snippet.file_name).to eq(file_path)
+ expect(snippet.content).to eq(content)
+ end
+
+ it 'commit the files to the repository' do
+ subject
+
+ blob = snippet.repository.blob_at('master', file_path)
+
+ expect(blob.data).to eq content
+ end
+
+ context 'when content or file_name params are present' do
+ let(:extra_opts) { { content: 'foo', file_name: 'path' } }
+
+ it 'raises a validation error' do
+ response = subject
+ snippet = response.payload[:snippet]
+
+ expect(response).to be_error
+ expect(snippet.errors.full_messages_for(:content)).to eq ['Content and snippet files cannot be used together']
+ expect(snippet.errors.full_messages_for(:file_name)).to eq ['File name and snippet files cannot be used together']
+ end
+ end
+
+ context 'when snippet_files param is invalid' do
+ let(:snippet_files) { [{ action: 'invalid_action' }] }
+
+ it 'raises a validation error' do
+ response = subject
+ snippet = response.payload[:snippet]
+
+ expect(response).to be_error
+ expect(snippet.errors.full_messages_for(:snippet_files)).to eq ['Snippet files have invalid data']
+ end
+ end
+
+ context 'when an error is raised committing the file' do
+ it 'keeps any snippet modifications' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:create_repository_for).and_raise(StandardError)
+ end
+
+ response = subject
+ snippet = response.payload[:snippet]
+
+ expect(response).to be_error
+ expect(snippet.title).to eq(new_title)
+ expect(snippet.file_name).to eq(file_path)
+ expect(snippet.content).to eq(content)
+ end
+ end
+ end
+
shared_examples 'only file_name is present' do
let(:base_opts) do
{
@@ -370,6 +446,7 @@ describe Snippets::UpdateService do
it_behaves_like 'updates repository content'
it_behaves_like 'commit operation fails'
it_behaves_like 'committable attributes'
+ it_behaves_like 'when snippet_files param is present'
it_behaves_like 'only file_name is present'
it_behaves_like 'only content is present'
it_behaves_like 'snippets spam check is performed' do
@@ -396,6 +473,7 @@ describe Snippets::UpdateService do
it_behaves_like 'updates repository content'
it_behaves_like 'commit operation fails'
it_behaves_like 'committable attributes'
+ it_behaves_like 'when snippet_files param is present'
it_behaves_like 'only file_name is present'
it_behaves_like 'only content is present'
it_behaves_like 'snippets spam check is performed' do
diff --git a/spec/services/spam/akismet_service_spec.rb b/spec/services/spam/akismet_service_spec.rb
index a496cd1890e..413b43d0156 100644
--- a/spec/services/spam/akismet_service_spec.rb
+++ b/spec/services/spam/akismet_service_spec.rb
@@ -45,9 +45,7 @@ describe Spam::AkismetService do
end
it 'logs an error' do
- logger_spy = double(:logger)
- expect(Rails).to receive(:logger).and_return(logger_spy)
- expect(logger_spy).to receive(:error).with(/skipping/)
+ expect(Gitlab::AppLogger).to receive(:error).with(/skipping/)
subject.send(method_call)
end
@@ -98,9 +96,7 @@ describe Spam::AkismetService do
end
it 'logs an error' do
- logger_spy = double(:logger)
- expect(Rails).to receive(:logger).and_return(logger_spy)
- expect(logger_spy).to receive(:error).with(/skipping check/)
+ expect(Gitlab::AppLogger).to receive(:error).with(/skipping check/)
subject.spam?
end
diff --git a/spec/services/spam/spam_action_service_spec.rb b/spec/services/spam/spam_action_service_spec.rb
index 560833aba97..7b6b65c82b1 100644
--- a/spec/services/spam/spam_action_service_spec.rb
+++ b/spec/services/spam/spam_action_service_spec.rb
@@ -24,7 +24,7 @@ describe Spam::SpamActionService do
end
describe '#initialize' do
- subject { described_class.new(spammable: issue, request: request) }
+ subject { described_class.new(spammable: issue, request: request, user: user) }
context 'when the request is nil' do
let(:request) { nil }
@@ -53,7 +53,7 @@ describe Spam::SpamActionService do
shared_examples 'only checks for spam if a request is provided' do
context 'when request is missing' do
- subject { described_class.new(spammable: issue, request: nil) }
+ subject { described_class.new(spammable: issue, request: nil, user: user) }
it "doesn't check as spam" do
subject
@@ -78,9 +78,9 @@ describe Spam::SpamActionService do
let_it_be(:existing_spam_log) { create(:spam_log, user: user, recaptcha_verified: false) }
subject do
- described_service = described_class.new(spammable: issue, request: request)
+ described_service = described_class.new(spammable: issue, request: request, user: user)
allow(described_service).to receive(:allowlisted?).and_return(allowlisted)
- described_service.execute(user: user, api: nil, recaptcha_verified: recaptcha_verified, spam_log_id: existing_spam_log.id)
+ described_service.execute(api: nil, recaptcha_verified: recaptcha_verified, spam_log_id: existing_spam_log.id)
end
before do
@@ -163,9 +163,9 @@ describe Spam::SpamActionService do
end
end
- context 'when spam verdict service requires reCAPTCHA' do
+ context 'when spam verdict service conditionally allows' do
before do
- allow(fake_verdict_service).to receive(:execute).and_return(REQUIRE_RECAPTCHA)
+ allow(fake_verdict_service).to receive(:execute).and_return(CONDITIONAL_ALLOW)
end
context 'when allow_possible_spam feature flag is false' do
diff --git a/spec/services/spam/spam_verdict_service_spec.rb b/spec/services/spam/spam_verdict_service_spec.rb
index 93460a5e7d7..f6d9cd96da5 100644
--- a/spec/services/spam/spam_verdict_service_spec.rb
+++ b/spec/services/spam/spam_verdict_service_spec.rb
@@ -16,50 +16,266 @@ describe Spam::SpamVerdictService do
let(:request) { double(:request, env: env) }
let(:check_for_spam) { true }
- let(:issue) { build(:issue) }
+ let_it_be(:user) { create(:user) }
+ let(:issue) { build(:issue, author: user) }
let(:service) do
- described_class.new(target: issue, request: request, options: {})
+ described_class.new(user: user, target: issue, request: request, options: {})
end
describe '#execute' do
subject { service.execute }
before do
- allow_next_instance_of(Spam::AkismetService) do |service|
- allow(service).to receive(:spam?).and_return(spam_verdict)
+ allow(service).to receive(:akismet_verdict).and_return(nil)
+ allow(service).to receive(:spam_verdict_verdict).and_return(nil)
+ end
+
+ context 'if all services return nil' do
+ it 'renders ALLOW verdict' do
+ expect(subject).to eq ALLOW
end
end
- context 'if Akismet considers it spam' do
- let(:spam_verdict) { true }
+ context 'if only one service returns a verdict' do
+ context 'and it is supported' do
+ before do
+ allow(service).to receive(:akismet_verdict).and_return(DISALLOW)
+ end
- context 'if reCAPTCHA is enabled' do
+ it 'renders that verdict' do
+ expect(subject).to eq DISALLOW
+ end
+ end
+
+ context 'and it is unexpected' do
before do
- stub_application_setting(recaptcha_enabled: true)
+ allow(service).to receive(:akismet_verdict).and_return("unexpected")
end
- it 'requires reCAPTCHA' do
- expect(subject).to eq REQUIRE_RECAPTCHA
+ it 'allows' do
+ expect(subject).to eq ALLOW
end
end
+ end
- context 'if reCAPTCHA is not enabled' do
+ context 'if more than one service returns a verdict' do
+ context 'and they are supported' do
before do
- stub_application_setting(recaptcha_enabled: false)
+ allow(service).to receive(:akismet_verdict).and_return(DISALLOW)
+ allow(service).to receive(:spam_verdict).and_return(BLOCK_USER)
end
- it 'disallows the change' do
- expect(subject).to eq DISALLOW
+ it 'renders the more restrictive verdict' do
+ expect(subject).to eq BLOCK_USER
+ end
+ end
+
+ context 'and one is supported' do
+ before do
+ allow(service).to receive(:akismet_verdict).and_return('nonsense')
+ allow(service).to receive(:spam_verdict).and_return(BLOCK_USER)
+ end
+
+ it 'renders the more restrictive verdict' do
+ expect(subject).to eq BLOCK_USER
+ end
+ end
+
+ context 'and one is supported' do
+ before do
+ allow(service).to receive(:akismet_verdict).and_return('nonsense')
+ allow(service).to receive(:spam_verdict).and_return(BLOCK_USER)
+ end
+
+ it 'renders the more restrictive verdict' do
+ expect(subject).to eq BLOCK_USER
+ end
+ end
+
+ context 'and none are supported' do
+ before do
+ allow(service).to receive(:akismet_verdict).and_return('nonsense')
+ allow(service).to receive(:spam_verdict).and_return('rubbish')
+ end
+
+ it 'renders the more restrictive verdict' do
+ expect(subject).to eq ALLOW
+ end
+ end
+ end
+ end
+
+ describe '#akismet_verdict' do
+ subject { service.send(:akismet_verdict) }
+
+ context 'if Akismet is enabled' do
+ before do
+ stub_application_setting(akismet_enabled: true)
+ allow_next_instance_of(Spam::AkismetService) do |service|
+ allow(service).to receive(:spam?).and_return(akismet_result)
+ end
+ end
+
+ context 'if Akismet considers it spam' do
+ let(:akismet_result) { true }
+
+ context 'if reCAPTCHA is enabled' do
+ before do
+ stub_application_setting(recaptcha_enabled: true)
+ end
+
+ it 'returns conditionally allow verdict' do
+ expect(subject).to eq CONDITIONAL_ALLOW
+ end
+ end
+
+ context 'if reCAPTCHA is not enabled' do
+ before do
+ stub_application_setting(recaptcha_enabled: false)
+ end
+
+ it 'renders disallow verdict' do
+ expect(subject).to eq DISALLOW
+ end
+ end
+ end
+
+ context 'if Akismet does not consider it spam' do
+ let(:akismet_result) { false }
+
+ it 'renders allow verdict' do
+ expect(subject).to eq ALLOW
end
end
end
- context 'if Akismet does not consider it spam' do
- let(:spam_verdict) { false }
+ context 'if Akismet is not enabled' do
+ before do
+ stub_application_setting(akismet_enabled: false)
+ end
- it 'allows the change' do
+ it 'renders allow verdict' do
expect(subject).to eq ALLOW
end
end
end
+
+ describe '#spam_verdict' do
+ subject { service.send(:spam_verdict) }
+
+ context 'if a Spam Check endpoint enabled and set to a URL' do
+ let(:spam_check_body) { {} }
+ let(:spam_check_http_status) { nil }
+
+ before do
+ stub_application_setting(spam_check_endpoint_enabled: true)
+ stub_application_setting(spam_check_endpoint_url: "http://www.spamcheckurl.com/spam_check")
+ stub_request(:post, /.*spamcheckurl.com.*/).to_return( body: spam_check_body.to_json, status: spam_check_http_status )
+ end
+
+ context 'if the endpoint is accessible' do
+ let(:spam_check_http_status) { 200 }
+ let(:error) { nil }
+ let(:verdict) { nil }
+ let(:spam_check_body) do
+ { verdict: verdict, error: error }
+ end
+
+ context 'the result is a valid verdict' do
+ let(:verdict) { 'allow' }
+
+ it 'returns the verdict' do
+ expect(subject).to eq ALLOW
+ end
+ end
+
+ context 'the verdict is an unexpected string' do
+ let(:verdict) { 'this is fine' }
+
+ it 'returns nil' do
+ expect(subject).to be_nil
+ end
+ end
+
+ context 'the JSON is malformed' do
+ let(:spam_check_body) { 'this is fine' }
+
+ it 'returns allow' do
+ expect(subject).to eq ALLOW
+ end
+ end
+
+ context 'the verdict is an empty string' do
+ let(:verdict) { '' }
+
+ it 'returns nil' do
+ expect(subject).to be_nil
+ end
+ end
+
+ context 'the verdict is nil' do
+ let(:verdict) { nil }
+
+ it 'returns nil' do
+ expect(subject).to be_nil
+ end
+ end
+
+ context 'there is an error' do
+ let(:error) { "Sorry Dave, I can't do that" }
+
+ it 'returns nil' do
+ expect(subject).to be_nil
+ end
+ end
+
+ context 'the HTTP status is not 200' do
+ let(:spam_check_http_status) { 500 }
+
+ it 'returns nil' do
+ expect(subject).to be_nil
+ end
+ end
+
+ context 'the confused API endpoint returns both an error and a verdict' do
+ let(:verdict) { 'disallow' }
+ let(:error) { 'oh noes!' }
+
+ it 'renders the verdict' do
+ expect(subject).to eq DISALLOW
+ end
+ end
+ end
+
+ context 'if the endpoint times out' do
+ before do
+ stub_request(:post, /.*spamcheckurl.com.*/).to_timeout
+ end
+
+ it 'returns nil' do
+ expect(subject).to be_nil
+ end
+ end
+ end
+
+ context 'if a Spam Check endpoint is not set' do
+ before do
+ stub_application_setting(spam_check_endpoint_url: nil)
+ end
+
+ it 'returns nil' do
+ expect(subject).to be_nil
+ end
+ end
+
+ context 'if Spam Check endpoint is not enabled' do
+ before do
+ stub_application_setting(spam_check_endpoint_enabled: false)
+ end
+
+ it 'returns nil' do
+ expect(subject).to be_nil
+ end
+ end
+ end
end
diff --git a/spec/services/submit_usage_ping_service_spec.rb b/spec/services/submit_usage_ping_service_spec.rb
index 26ce5968ad6..981ea0dbec1 100644
--- a/spec/services/submit_usage_ping_service_spec.rb
+++ b/spec/services/submit_usage_ping_service_spec.rb
@@ -4,6 +4,7 @@ require 'spec_helper'
describe SubmitUsagePingService do
include StubRequests
+ include UsageDataHelpers
let(:score_params) do
{
@@ -76,7 +77,7 @@ describe SubmitUsagePingService do
context 'when usage ping is enabled' do
before do
- allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false)
+ stub_usage_data_connections
stub_application_setting(usage_ping_enabled: true)
end
diff --git a/spec/services/suggestions/apply_service_spec.rb b/spec/services/suggestions/apply_service_spec.rb
index b04c3278eaa..678e2129181 100644
--- a/spec/services/suggestions/apply_service_spec.rb
+++ b/spec/services/suggestions/apply_service_spec.rb
@@ -5,41 +5,66 @@ require 'spec_helper'
describe Suggestions::ApplyService do
include ProjectForksHelper
- def build_position(args = {})
- default_args = { old_path: "files/ruby/popen.rb",
- new_path: "files/ruby/popen.rb",
- old_line: nil,
- new_line: 9,
- diff_refs: merge_request.diff_refs }
-
- Gitlab::Diff::Position.new(default_args.merge(args))
+ def build_position(**optional_args)
+ args = { old_path: "files/ruby/popen.rb",
+ new_path: "files/ruby/popen.rb",
+ old_line: nil,
+ new_line: 9,
+ diff_refs: merge_request.diff_refs,
+ **optional_args }
+
+ Gitlab::Diff::Position.new(args)
end
- shared_examples 'successfully creates commit and updates suggestion' do
- def apply(suggestion)
- result = subject.execute(suggestion)
- expect(result[:status]).to eq(:success)
- end
+ def create_suggestion(args)
+ position_args = args.slice(:old_path, :new_path, :old_line, :new_line)
+ content_args = args.slice(:from_content, :to_content)
+
+ position = build_position(position_args)
+
+ diff_note = create(:diff_note_on_merge_request,
+ noteable: merge_request,
+ position: position,
+ project: project)
+
+ suggestion_args = { note: diff_note }.merge(content_args)
+
+ create(:suggestion, :content_from_repo, suggestion_args)
+ end
+
+ def apply(suggestions)
+ result = apply_service.new(user, *suggestions).execute
- it 'updates the file with the new contents' do
- apply(suggestion)
+ suggestions.map { |suggestion| suggestion.reload }
- blob = project.repository.blob_at_branch(merge_request.source_branch,
- position.new_path)
+ expect(result[:status]).to eq(:success)
+ end
+
+ shared_examples 'successfully creates commit and updates suggestions' do
+ it 'updates the files with the new content' do
+ apply(suggestions)
- expect(blob.data).to eq(expected_content)
+ suggestions.each do |suggestion|
+ path = suggestion.diff_file.file_path
+ blob = project.repository.blob_at_branch(merge_request.source_branch,
+ path)
+
+ expect(blob.data).to eq(expected_content_by_path[path.to_sym])
+ end
end
it 'updates suggestion applied and commit_id columns' do
- expect { apply(suggestion) }
- .to change(suggestion, :applied)
- .from(false).to(true)
- .and change(suggestion, :commit_id)
- .from(nil)
+ expect(suggestions.map(&:applied)).to all(be false)
+ expect(suggestions.map(&:commit_id)).to all(be nil)
+
+ apply(suggestions)
+
+ expect(suggestions.map(&:applied)).to all(be true)
+ expect(suggestions.map(&:commit_id)).to all(be_present)
end
it 'created commit has users email and name' do
- apply(suggestion)
+ apply(suggestions)
commit = project.repository.commit
@@ -53,125 +78,214 @@ describe Suggestions::ApplyService do
before do
project.update!(suggestion_commit_message: message)
- apply(suggestion)
+ apply(suggestions)
end
context 'is not specified' do
- let(:expected_value) { "Apply suggestion to files/ruby/popen.rb" }
-
- context 'is nil' do
- let(:message) { nil }
+ let(:message) { '' }
- it 'sets default commit message' do
- expect(project.repository.commit.message).to eq(expected_value)
- end
- end
-
- context 'is an empty string' do
- let(:message) { '' }
-
- it 'sets default commit message' do
- expect(project.repository.commit.message).to eq(expected_value)
- end
+ it 'uses the default commit message' do
+ expect(project.repository.commit.message).to(
+ match(/\AApply #{suggestions.size} suggestion\(s\) to \d+ file\(s\)\z/)
+ )
end
end
context 'is specified' do
- let(:message) { 'refactor: %{project_path} %{project_name} %{file_path} %{branch_name} %{username} %{user_full_name}' }
+ let(:message) do
+ 'refactor: %{project_name} %{branch_name} %{username}'
+ end
- it 'sets custom commit message' do
- expect(project.repository.commit.message).to eq("refactor: project-1 Project_1 files/ruby/popen.rb master test.user Test User")
+ it 'generates a custom commit message' do
+ expect(project.repository.commit.message).to(
+ eq("refactor: Project_1 master test.user")
+ )
end
end
end
end
- let(:project) { create(:project, :repository, path: 'project-1', name: 'Project_1') }
- let(:user) { create(:user, :commit_email, name: 'Test User', username: 'test.user') }
+ subject(:apply_service) { described_class }
+
+ let_it_be(:user) do
+ create(:user, :commit_email, name: 'Test User', username: 'test.user')
+ end
+
+ let(:project) do
+ create(:project, :repository, path: 'project-1', name: 'Project_1')
+ end
+
+ let(:merge_request) do
+ create(:merge_request, source_project: project,
+ target_project: project,
+ source_branch: 'master')
+ end
let(:position) { build_position }
let(:diff_note) do
- create(:diff_note_on_merge_request, noteable: merge_request, position: position, project: project)
+ create(:diff_note_on_merge_request, noteable: merge_request,
+ position: position, project: project)
end
let(:suggestion) do
create(:suggestion, :content_from_repo, note: diff_note,
- to_content: " raise RuntimeError, 'Explosion'\n # explosion?\n")
+ to_content: " raise RuntimeError, 'Explosion'\n # explosion?\n")
end
- subject { described_class.new(user) }
+ let(:suggestion2) do
+ create_suggestion(
+ to_content: " *** SUGGESTION CHANGE ***\n",
+ new_line: 15)
+ end
+
+ let(:suggestion3) do
+ create_suggestion(
+ to_content: " *** ANOTHER SUGGESTION CHANGE ***\n",
+ old_path: "files/ruby/regex.rb",
+ new_path: "files/ruby/regex.rb",
+ new_line: 22)
+ end
+
+ let(:suggestions) { [suggestion, suggestion2, suggestion3] }
context 'patch is appliable' do
- let(:expected_content) do
+ let(:popen_content) do
<<-CONTENT.strip_heredoc
- require 'fileutils'
- require 'open3'
+ require 'fileutils'
+ require 'open3'
+
+ module Popen
+ extend self
+
+ def popen(cmd, path=nil)
+ unless cmd.is_a?(Array)
+ raise RuntimeError, 'Explosion'
+ # explosion?
+ end
+
+ path ||= Dir.pwd
+
+ vars = {
+ *** SUGGESTION CHANGE ***
+ }
+
+ options = {
+ chdir: path
+ }
+
+ unless File.directory?(path)
+ FileUtils.mkdir_p(path)
+ end
+
+ @cmd_output = ""
+ @cmd_status = 0
+
+ Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|
+ @cmd_output << stdout.read
+ @cmd_output << stderr.read
+ @cmd_status = wait_thr.value.exitstatus
+ end
- module Popen
+ return @cmd_output, @cmd_status
+ end
+ end
+ CONTENT
+ end
+
+ let(:regex_content) do
+ <<-CONTENT.strip_heredoc
+ module Gitlab
+ module Regex
extend self
- def popen(cmd, path=nil)
- unless cmd.is_a?(Array)
- raise RuntimeError, 'Explosion'
- # explosion?
- end
+ def username_regex
+ default_regex
+ end
- path ||= Dir.pwd
+ def project_name_regex
+ /\\A[a-zA-Z0-9][a-zA-Z0-9_\\-\\. ]*\\z/
+ end
- vars = {
- "PWD" => path
- }
+ def name_regex
+ /\\A[a-zA-Z0-9_\\-\\. ]*\\z/
+ end
- options = {
- chdir: path
- }
+ def path_regex
+ default_regex
+ end
- unless File.directory?(path)
- FileUtils.mkdir_p(path)
- end
+ def archive_formats_regex
+ *** ANOTHER SUGGESTION CHANGE ***
+ end
- @cmd_output = ""
- @cmd_status = 0
+ def git_reference_regex
+ # Valid git ref regex, see:
+ # https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html
+ %r{
+ (?!
+ (?# doesn't begins with)
+ \\/| (?# rule #6)
+ (?# doesn't contain)
+ .*(?:
+ [\\\/.]\\\.| (?# rule #1,3)
+ \\/\\/| (?# rule #6)
+ @\\{| (?# rule #8)
+ \\\\ (?# rule #9)
+ )
+ )
+ [^\\000-\\040\\177~^:?*\\[]+ (?# rule #4-5)
+ (?# doesn't end with)
+ (?<!\\.lock) (?# rule #1)
+ (?<![\\/.]) (?# rule #6-7)
+ }x
+ end
- Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|
- @cmd_output << stdout.read
- @cmd_output << stderr.read
- @cmd_status = wait_thr.value.exitstatus
- end
+ protected
- return @cmd_output, @cmd_status
+ def default_regex
+ /\\A[.?]?[a-zA-Z0-9][a-zA-Z0-9_\\-\\.]*(?<!\\.git)\\z/
end
end
+ end
CONTENT
end
- context 'non-fork project' do
- let(:merge_request) do
- create(:merge_request, source_project: project,
- target_project: project,
- source_branch: 'master')
- end
+ let(:expected_content_by_path) do
+ {
+ "files/ruby/popen.rb": popen_content,
+ "files/ruby/regex.rb": regex_content
+ }
+ end
+ context 'non-fork project' do
before do
project.add_maintainer(user)
end
- it_behaves_like 'successfully creates commit and updates suggestion'
+ it_behaves_like 'successfully creates commit and updates suggestions'
- context 'when it fails to apply because the file was changed' do
- it 'returns error message' do
- service = instance_double(Files::UpdateService)
+ context 'when it fails to apply because a file was changed' do
+ before do
+ params = {
+ file_path: suggestion3.diff_file.file_path,
+ start_branch: suggestion3.branch,
+ branch_name: suggestion3.branch,
+ commit_message: 'Update file',
+ file_content: 'New content'
+ }
- expect(Files::UpdateService).to receive(:new)
- .and_return(service)
+ # Reload the suggestion so it's memoized values get reset after the
+ # file was changed.
+ suggestion3.reload
- allow(service).to receive(:execute)
- .and_raise(Files::UpdateService::FileChangedError)
+ Files::UpdateService.new(project, user, params).execute
+ end
- result = subject.execute(suggestion)
+ it 'returns error message' do
+ result = apply_service.new(user, suggestion, suggestion3, suggestion2).execute
- expect(result).to eq(message: 'The file has been changed', status: :error)
+ expect(result).to eq(message: 'A file has been changed.', status: :error)
end
end
@@ -181,78 +295,20 @@ describe Suggestions::ApplyService do
allow(suggestion.position).to receive(:head_sha) { 'old-sha' }
allow(suggestion.noteable).to receive(:source_branch_sha) { 'new-sha' }
- result = subject.execute(suggestion)
+ result = apply_service.new(user, suggestion).execute
- expect(result).to eq(message: 'The file has been changed', status: :error)
+ expect(result).to eq(message: 'A file has been changed.', status: :error)
end
end
- context 'multiple suggestions applied' do
- let(:expected_content) do
- <<-CONTENT.strip_heredoc
- require 'fileutils'
- require 'open3'
-
- module Popen
- extend self
-
-
- def popen(cmd, path=nil)
- unless cmd.is_a?(Array)
- # v1 change
- end
-
- path ||= Dir.pwd
- # v1 change
- vars = {
- "PWD" => path
- }
-
- options = {
- chdir: path
- }
- # v2 change
- unless File.directory?(path)
- FileUtils.mkdir_p(path)
- end
-
- @cmd_output = ""
- # v2 change
-
- Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|
- @cmd_output << stdout.read
- @cmd_output << stderr.read
- @cmd_status = wait_thr.value.exitstatus
- end
-
- return @cmd_output, @cmd_status
- end
- end
- CONTENT
- end
-
- def create_suggestion(diff, old_line: nil, new_line: nil, from_content:, to_content:, path:)
- position = Gitlab::Diff::Position.new(old_path: path,
- new_path: path,
- old_line: old_line,
- new_line: new_line,
- diff_refs: diff.diff_refs)
-
- suggestion_note = create(:diff_note_on_merge_request, noteable: merge_request,
- original_position: position,
- position: position,
- project: project)
- create(:suggestion, note: suggestion_note,
- from_content: from_content,
- to_content: to_content)
- end
-
+ context 'multiple suggestions applied sequentially' do
def apply_suggestion(suggestion)
suggestion.reload
merge_request.reload
merge_request.clear_memoized_shas
- result = subject.execute(suggestion)
+ result = apply_service.new(user, suggestion).execute
+ suggestion.reload
expect(result[:status]).to eq(:success)
refresh = MergeRequests::RefreshService.new(project, user)
@@ -264,34 +320,31 @@ describe Suggestions::ApplyService do
end
def fetch_raw_diff(suggestion)
- project.reload.commit(suggestion.commit_id).diffs.diff_files.first.diff.diff
+ project.reload.commit(suggestion.commit_id)
+ .diffs.diff_files.first.diff.diff
end
it 'applies multiple suggestions in subsequent versions correctly' do
- diff = merge_request.merge_request_diff
- path = 'files/ruby/popen.rb'
+ suggestion1 = create_suggestion(
+ from_content: "\n",
+ to_content: "# v1 change\n",
+ old_line: nil,
+ new_line: 13)
- suggestion_1_changes = { old_line: nil,
- new_line: 13,
- from_content: "\n",
- to_content: "# v1 change\n",
- path: path }
+ suggestion2 = create_suggestion(
+ from_content: " @cmd_output << stderr.read\n",
+ to_content: "# v2 change\n",
+ old_line: 24,
+ new_line: 31)
- suggestion_2_changes = { old_line: 24,
- new_line: 31,
- from_content: " @cmd_output << stderr.read\n",
- to_content: "# v2 change\n",
- path: path }
+ apply_suggestion(suggestion1)
+ apply_suggestion(suggestion2)
- suggestion_1 = create_suggestion(diff, suggestion_1_changes)
- suggestion_2 = create_suggestion(diff, suggestion_2_changes)
-
- apply_suggestion(suggestion_1)
-
- suggestion_1_diff = fetch_raw_diff(suggestion_1)
+ suggestion1_diff = fetch_raw_diff(suggestion1)
+ suggestion2_diff = fetch_raw_diff(suggestion2)
# rubocop: disable Layout/TrailingWhitespace
- expected_suggestion_1_diff = <<-CONTENT.strip_heredoc
+ expected_suggestion1_diff = <<-CONTENT.strip_heredoc
@@ -10,7 +10,7 @@ module Popen
end
@@ -304,12 +357,8 @@ describe Suggestions::ApplyService do
CONTENT
# rubocop: enable Layout/TrailingWhitespace
- apply_suggestion(suggestion_2)
-
- suggestion_2_diff = fetch_raw_diff(suggestion_2)
-
# rubocop: disable Layout/TrailingWhitespace
- expected_suggestion_2_diff = <<-CONTENT.strip_heredoc
+ expected_suggestion2_diff = <<-CONTENT.strip_heredoc
@@ -28,7 +28,7 @@ module Popen
Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|
@@ -321,14 +370,14 @@ describe Suggestions::ApplyService do
CONTENT
# rubocop: enable Layout/TrailingWhitespace
- expect(suggestion_1_diff.strip).to eq(expected_suggestion_1_diff.strip)
- expect(suggestion_2_diff.strip).to eq(expected_suggestion_2_diff.strip)
+ expect(suggestion1_diff.strip).to eq(expected_suggestion1_diff.strip)
+ expect(suggestion2_diff.strip).to eq(expected_suggestion2_diff.strip)
end
end
context 'multi-line suggestion' do
- let(:expected_content) do
- <<~CONTENT
+ let(:popen_content) do
+ <<~CONTENT.strip_heredoc
require 'fileutils'
require 'open3'
@@ -365,19 +414,27 @@ describe Suggestions::ApplyService do
CONTENT
end
+ let(:expected_content_by_path) do
+ {
+ "files/ruby/popen.rb": popen_content
+ }
+ end
+
let(:suggestion) do
create(:suggestion, :content_from_repo, note: diff_note,
- lines_above: 2,
- lines_below: 3,
- to_content: "# multi\n# line\n")
+ lines_above: 2,
+ lines_below: 3,
+ to_content: "# multi\n# line\n")
end
- it_behaves_like 'successfully creates commit and updates suggestion'
+ let(:suggestions) { [suggestion] }
+
+ it_behaves_like 'successfully creates commit and updates suggestions'
end
context 'remove an empty line suggestion' do
- let(:expected_content) do
- <<~CONTENT
+ let(:popen_content) do
+ <<~CONTENT.strip_heredoc
require 'fileutils'
require 'open3'
@@ -417,12 +474,19 @@ describe Suggestions::ApplyService do
CONTENT
end
- let(:position) { build_position(new_line: 13) }
+ let(:expected_content_by_path) do
+ {
+ "files/ruby/popen.rb": popen_content
+ }
+ end
+
let(:suggestion) do
- create(:suggestion, :content_from_repo, note: diff_note, to_content: "")
+ create_suggestion( to_content: "", new_line: 13)
end
- it_behaves_like 'successfully creates commit and updates suggestion'
+ let(:suggestions) { [suggestion] }
+
+ it_behaves_like 'successfully creates commit and updates suggestions'
end
end
@@ -430,17 +494,23 @@ describe Suggestions::ApplyService do
let(:project) { create(:project, :public, :repository) }
let(:forked_project) do
- fork_project_with_submodules(project, user, repository: project.repository)
+ fork_project_with_submodules(project,
+ user, repository: project.repository)
end
let(:merge_request) do
create(:merge_request,
- source_branch: 'conflict-resolvable-fork', source_project: forked_project,
- target_branch: 'conflict-start', target_project: project)
+ source_branch: 'conflict-resolvable-fork',
+ source_project: forked_project,
+ target_branch: 'conflict-start',
+ target_project: project)
end
let!(:diff_note) do
- create(:diff_note_on_merge_request, noteable: merge_request, position: position, project: project)
+ create(:diff_note_on_merge_request,
+ noteable: merge_request,
+ position: position,
+ project: project)
end
before do
@@ -448,11 +518,12 @@ describe Suggestions::ApplyService do
end
it 'updates file in the source project' do
- expect(Files::UpdateService).to receive(:new)
- .with(merge_request.source_project, user, anything)
- .and_call_original
+ expect(Files::MultiService).to receive(:new)
+ .with(merge_request.source_project,
+ user,
+ anything).and_call_original
- subject.execute(suggestion)
+ apply_service.new(user, suggestion).execute
end
end
end
@@ -460,13 +531,13 @@ describe Suggestions::ApplyService do
context 'no permission' do
let(:merge_request) do
create(:merge_request, source_project: project,
- target_project: project)
+ target_project: project)
end
let(:diff_note) do
create(:diff_note_on_merge_request, noteable: merge_request,
- position: position,
- project: project)
+ position: position,
+ project: project)
end
context 'user cannot write in project repo' do
@@ -475,7 +546,7 @@ describe Suggestions::ApplyService do
end
it 'returns error' do
- result = subject.execute(suggestion)
+ result = apply_service.new(user, suggestion).execute
expect(result).to eq(message: "You are not allowed to push into this branch",
status: :error)
@@ -486,13 +557,13 @@ describe Suggestions::ApplyService do
context 'patch is not appliable' do
let(:merge_request) do
create(:merge_request, source_project: project,
- target_project: project)
+ target_project: project)
end
let(:diff_note) do
create(:diff_note_on_merge_request, noteable: merge_request,
- position: position,
- project: project)
+ position: position,
+ project: project)
end
before do
@@ -503,29 +574,49 @@ describe Suggestions::ApplyService do
it 'returns error message' do
expect(suggestion.note).to receive(:latest_diff_file) { nil }
- result = subject.execute(suggestion)
+ result = apply_service.new(user, suggestion).execute
- expect(result).to eq(message: 'Suggestion is not appliable',
+ expect(result).to eq(message: 'A file was not found.',
status: :error)
end
end
- context 'suggestion is eligible to be outdated' do
- it 'returns error message' do
- expect(suggestion).to receive(:outdated?) { true }
+ context 'when not all suggestions belong to the same branch' do
+ it 'renders error message' do
+ merge_request2 = create(:merge_request,
+ :conflict,
+ source_project: project,
+ target_project: project)
- result = subject.execute(suggestion)
+ position2 = Gitlab::Diff::Position.new(old_path: "files/ruby/popen.rb",
+ new_path: "files/ruby/popen.rb",
+ old_line: nil,
+ new_line: 15,
+ diff_refs: merge_request2
+ .diff_refs)
- expect(result).to eq(message: 'Suggestion is not appliable',
+ diff_note2 = create(:diff_note_on_merge_request,
+ noteable: merge_request2,
+ position: position2,
+ project: project)
+
+ other_branch_suggestion = create(:suggestion, note: diff_note2)
+
+ result = apply_service.new(user, suggestion, other_branch_suggestion).execute
+
+ expect(result).to eq(message: 'Suggestions must all be on the same branch.',
status: :error)
end
end
- context 'suggestion was already applied' do
- it 'returns success status' do
- result = subject.execute(suggestion)
+ context 'suggestion is eligible to be outdated' do
+ it 'returns error message' do
+ expect(suggestion).to receive(:outdated?) { true }
+
+ result = apply_service.new(user, suggestion).execute
- expect(result[:status]).to eq(:success)
+ expect(result).to eq(message: 'A suggestion is not applicable.',
+ status: :error)
end
end
@@ -535,9 +626,9 @@ describe Suggestions::ApplyService do
end
it 'returns error message' do
- result = subject.execute(suggestion)
+ result = apply_service.new(user, suggestion).execute
- expect(result).to eq(message: 'Suggestion is not appliable',
+ expect(result).to eq(message: 'A suggestion is not applicable.',
status: :error)
end
end
@@ -548,9 +639,27 @@ describe Suggestions::ApplyService do
end
it 'returns error message' do
- result = subject.execute(suggestion)
+ result = apply_service.new(user, suggestion).execute
+
+ expect(result).to eq(message: 'A suggestion is not applicable.',
+ status: :error)
+ end
+ end
+
+ context 'lines of suggestions overlap' do
+ let(:suggestion) do
+ create_suggestion(
+ to_content: " raise RuntimeError, 'Explosion'\n # explosion?\n")
+ end
+
+ let(:overlapping_suggestion) do
+ create_suggestion(to_content: "I Overlap!")
+ end
+
+ it 'returns error message' do
+ result = apply_service.new(user, suggestion, overlapping_suggestion).execute
- expect(result).to eq(message: 'Suggestion is not appliable',
+ expect(result).to eq(message: 'Suggestions are not applicable as their lines cannot overlap.',
status: :error)
end
end
diff --git a/spec/services/system_notes/issuables_service_spec.rb b/spec/services/system_notes/issuables_service_spec.rb
index 477f9eae39e..c3b3c877583 100644
--- a/spec/services/system_notes/issuables_service_spec.rb
+++ b/spec/services/system_notes/issuables_service_spec.rb
@@ -157,7 +157,18 @@ describe ::SystemNotes::IssuablesService do
describe '#change_status' do
subject { service.change_status(status, source) }
+ context 'when resource state event tracking is enabled' do
+ let(:status) { 'reopened' }
+ let(:source) { nil }
+
+ it { is_expected.to be_nil }
+ end
+
context 'with status reopened' do
+ before do
+ stub_feature_flags(track_resource_state_change_events: false)
+ end
+
let(:status) { 'reopened' }
let(:source) { nil }
@@ -169,6 +180,10 @@ describe ::SystemNotes::IssuablesService do
end
context 'with a source' do
+ before do
+ stub_feature_flags(track_resource_state_change_events: false)
+ end
+
let(:status) { 'opened' }
let(:source) { double('commit', gfm_reference: 'commit 123456') }
diff --git a/spec/services/test_hooks/project_service_spec.rb b/spec/services/test_hooks/project_service_spec.rb
index 8d30f5018dd..3c5bc0d85f2 100644
--- a/spec/services/test_hooks/project_service_spec.rb
+++ b/spec/services/test_hooks/project_service_spec.rb
@@ -31,15 +31,7 @@ describe TestHooks::ProjectService do
let(:trigger) { 'push_events' }
let(:trigger_key) { :push_hooks }
- it 'returns error message if not enough data' do
- allow(project).to receive(:empty_repo?).and_return(true)
-
- expect(hook).not_to receive(:execute)
- expect(service.execute).to include({ status: :error, message: 'Ensure the project has at least one commit.' })
- end
-
it 'executes hook' do
- allow(project).to receive(:empty_repo?).and_return(false)
allow(Gitlab::DataBuilder::Push).to receive(:build_sample).and_return(sample_data)
expect(hook).to receive(:execute).with(sample_data, trigger_key).and_return(success_result)
@@ -51,15 +43,7 @@ describe TestHooks::ProjectService do
let(:trigger) { 'tag_push_events' }
let(:trigger_key) { :tag_push_hooks }
- it 'returns error message if not enough data' do
- allow(project).to receive(:empty_repo?).and_return(true)
-
- expect(hook).not_to receive(:execute)
- expect(service.execute).to include({ status: :error, message: 'Ensure the project has at least one commit.' })
- end
-
it 'executes hook' do
- allow(project).to receive(:empty_repo?).and_return(false)
allow(Gitlab::DataBuilder::Push).to receive(:build_sample).and_return(sample_data)
expect(hook).to receive(:execute).with(sample_data, trigger_key).and_return(success_result)
diff --git a/spec/services/test_hooks/system_service_spec.rb b/spec/services/test_hooks/system_service_spec.rb
index 799b57eb04e..8a86b14a2a1 100644
--- a/spec/services/test_hooks/system_service_spec.rb
+++ b/spec/services/test_hooks/system_service_spec.rb
@@ -29,7 +29,6 @@ describe TestHooks::SystemService do
let(:trigger_key) { :push_hooks }
it 'executes hook' do
- allow(project).to receive(:empty_repo?).and_return(false)
expect(Gitlab::DataBuilder::Push).to receive(:sample_data).and_call_original
expect(hook).to receive(:execute).with(Gitlab::DataBuilder::Push::SAMPLE_DATA, trigger_key).and_return(success_result)
@@ -55,7 +54,6 @@ describe TestHooks::SystemService do
let(:trigger_key) { :repository_update_hooks }
it 'executes hook' do
- allow(project).to receive(:empty_repo?).and_return(false)
expect(Gitlab::DataBuilder::Repository).to receive(:sample_data).and_call_original
expect(hook).to receive(:execute).with(Gitlab::DataBuilder::Repository::SAMPLE_DATA, trigger_key).and_return(success_result)
diff --git a/spec/services/todo_service_spec.rb b/spec/services/todo_service_spec.rb
index 4894cf12372..f6e1608acbe 100644
--- a/spec/services/todo_service_spec.rb
+++ b/spec/services/todo_service_spec.rb
@@ -27,6 +27,39 @@ describe TodoService do
project.add_developer(skipped)
end
+ shared_examples 'reassigned target' do
+ it 'creates a pending todo for new assignee' do
+ target_unassigned.assignees = [john_doe]
+ service.send(described_method, target_unassigned, author)
+
+ should_create_todo(user: john_doe, target: target_unassigned, action: Todo::ASSIGNED)
+ end
+
+ it 'does not create a todo if unassigned' do
+ target_assigned.assignees = []
+
+ should_not_create_any_todo { service.send(described_method, target_assigned, author) }
+ end
+
+ it 'creates a todo if new assignee is the current user' do
+ target_assigned.assignees = [john_doe]
+ service.send(described_method, target_assigned, john_doe)
+
+ should_create_todo(user: john_doe, target: target_assigned, author: john_doe, action: Todo::ASSIGNED)
+ end
+
+ it 'does not create a todo for guests' do
+ service.send(described_method, target_assigned, author)
+ should_not_create_todo(user: guest, target: target_assigned, action: Todo::MENTIONED)
+ end
+
+ it 'does not create a directly addressed todo for guests' do
+ service.send(described_method, addressed_target_assigned, author)
+
+ should_not_create_todo(user: guest, target: addressed_target_assigned, action: Todo::DIRECTLY_ADDRESSED)
+ end
+ end
+
describe 'Issues' do
let(:issue) { create(:issue, project: project, assignees: [john_doe], author: author, description: "- [ ] Task 1\n- [ ] Task 2 #{mentions}") }
let(:addressed_issue) { create(:issue, project: project, assignees: [john_doe], author: author, description: "#{directly_addressed}\n- [ ] Task 1\n- [ ] Task 2") }
@@ -274,12 +307,12 @@ describe TodoService do
end
end
- describe '#mark_pending_todos_as_done' do
+ describe '#resolve_todos_for_target' do
it 'marks related pending todos to the target for the user as done' do
first_todo = create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author)
second_todo = create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author)
- service.mark_pending_todos_as_done(issue, john_doe)
+ service.resolve_todos_for_target(issue, john_doe)
expect(first_todo.reload).to be_done
expect(second_todo.reload).to be_done
@@ -293,7 +326,7 @@ describe TodoService do
expect(john_doe.todos_pending_count).to eq(1)
expect(john_doe).to receive(:update_todos_count_cache).and_call_original
- service.mark_pending_todos_as_done(issue, john_doe)
+ service.resolve_todos_for_target(issue, john_doe)
expect(john_doe.todos_done_count).to eq(1)
expect(john_doe.todos_pending_count).to eq(0)
@@ -301,59 +334,6 @@ describe TodoService do
end
end
- shared_examples 'updating todos state' do |meth, state, new_state|
- let!(:first_todo) { create(:todo, state, user: john_doe, project: project, target: issue, author: author) }
- let!(:second_todo) { create(:todo, state, user: john_doe, project: project, target: issue, author: author) }
-
- it 'updates related todos for the user with the new_state' do
- service.send(meth, collection, john_doe)
-
- expect(first_todo.reload.state?(new_state)).to be true
- expect(second_todo.reload.state?(new_state)).to be true
- end
-
- it 'returns the updated ids' do
- expect(service.send(meth, collection, john_doe)).to match_array([first_todo.id, second_todo.id])
- end
-
- describe 'cached counts' do
- it 'updates when todos change' do
- expect(john_doe.todos.where(state: new_state).count).to eq(0)
- expect(john_doe.todos.where(state: state).count).to eq(2)
- expect(john_doe).to receive(:update_todos_count_cache).and_call_original
-
- service.send(meth, collection, john_doe)
-
- expect(john_doe.todos.where(state: new_state).count).to eq(2)
- expect(john_doe.todos.where(state: state).count).to eq(0)
- end
- end
- end
-
- describe '#mark_todos_as_done' do
- it_behaves_like 'updating todos state', :mark_todos_as_done, :pending, :done do
- let(:collection) { Todo.all }
- end
- end
-
- describe '#mark_todos_as_done_by_ids' do
- it_behaves_like 'updating todos state', :mark_todos_as_done_by_ids, :pending, :done do
- let(:collection) { [first_todo, second_todo].map(&:id) }
- end
- end
-
- describe '#mark_todos_as_pending' do
- it_behaves_like 'updating todos state', :mark_todos_as_pending, :done, :pending do
- let(:collection) { Todo.all }
- end
- end
-
- describe '#mark_todos_as_pending_by_ids' do
- it_behaves_like 'updating todos state', :mark_todos_as_pending_by_ids, :done, :pending do
- let(:collection) { [first_todo, second_todo].map(&:id) }
- end
- end
-
describe '#new_note' do
let!(:first_todo) { create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author) }
let!(:second_todo) { create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author) }
@@ -575,51 +555,21 @@ describe TodoService do
end
describe '#reassigned_issuable' do
- shared_examples 'reassigned issuable' do
- it 'creates a pending todo for new assignee' do
- issuable_unassigned.assignees = [john_doe]
- service.reassigned_issuable(issuable_unassigned, author)
-
- should_create_todo(user: john_doe, target: issuable_unassigned, action: Todo::ASSIGNED)
- end
-
- it 'does not create a todo if unassigned' do
- issuable_assigned.assignees = []
-
- should_not_create_any_todo { service.reassigned_issuable(issuable_assigned, author) }
- end
-
- it 'creates a todo if new assignee is the current user' do
- issuable_assigned.assignees = [john_doe]
- service.reassigned_issuable(issuable_assigned, john_doe)
-
- should_create_todo(user: john_doe, target: issuable_assigned, author: john_doe, action: Todo::ASSIGNED)
- end
-
- it 'does not create a todo for guests' do
- service.reassigned_issuable(issuable_assigned, author)
- should_not_create_todo(user: guest, target: issuable_assigned, action: Todo::MENTIONED)
- end
-
- it 'does not create a directly addressed todo for guests' do
- service.reassigned_issuable(addressed_issuable_assigned, author)
- should_not_create_todo(user: guest, target: addressed_issuable_assigned, action: Todo::DIRECTLY_ADDRESSED)
- end
- end
+ let(:described_method) { :reassigned_issuable }
context 'issuable is a merge request' do
- it_behaves_like 'reassigned issuable' do
- let(:issuable_assigned) { create(:merge_request, source_project: project, author: author, assignees: [john_doe], description: "- [ ] Task 1\n- [ ] Task 2 #{mentions}") }
- let(:addressed_issuable_assigned) { create(:merge_request, source_project: project, author: author, assignees: [john_doe], description: "#{directly_addressed}\n- [ ] Task 1\n- [ ] Task 2") }
- let(:issuable_unassigned) { create(:merge_request, source_project: project, author: author, assignees: []) }
+ it_behaves_like 'reassigned target' do
+ let(:target_assigned) { create(:merge_request, source_project: project, author: author, assignees: [john_doe], description: "- [ ] Task 1\n- [ ] Task 2 #{mentions}") }
+ let(:addressed_target_assigned) { create(:merge_request, source_project: project, author: author, assignees: [john_doe], description: "#{directly_addressed}\n- [ ] Task 1\n- [ ] Task 2") }
+ let(:target_unassigned) { create(:merge_request, source_project: project, author: author, assignees: []) }
end
end
context 'issuable is an issue' do
- it_behaves_like 'reassigned issuable' do
- let(:issuable_assigned) { create(:issue, project: project, author: author, assignees: [john_doe], description: "- [ ] Task 1\n- [ ] Task 2 #{mentions}") }
- let(:addressed_issuable_assigned) { create(:issue, project: project, author: author, assignees: [john_doe], description: "#{directly_addressed}\n- [ ] Task 1\n- [ ] Task 2") }
- let(:issuable_unassigned) { create(:issue, project: project, author: author, assignees: []) }
+ it_behaves_like 'reassigned target' do
+ let(:target_assigned) { create(:issue, project: project, author: author, assignees: [john_doe], description: "- [ ] Task 1\n- [ ] Task 2 #{mentions}") }
+ let(:addressed_target_assigned) { create(:issue, project: project, author: author, assignees: [john_doe], description: "#{directly_addressed}\n- [ ] Task 1\n- [ ] Task 2") }
+ let(:target_unassigned) { create(:issue, project: project, author: author, assignees: []) }
end
end
end
@@ -809,6 +759,16 @@ describe TodoService do
end
end
+ describe '#assign_alert' do
+ let(:described_method) { :assign_alert }
+
+ it_behaves_like 'reassigned target' do
+ let(:target_assigned) { create(:alert_management_alert, project: project, assignees: [john_doe]) }
+ let(:addressed_target_assigned) { create(:alert_management_alert, project: project, assignees: [john_doe]) }
+ let(:target_unassigned) { create(:alert_management_alert, project: project, assignees: []) }
+ end
+ end
+
describe '#merge_request_build_failed' do
let(:merge_participants) { [mr_unassigned.author, admin] }
@@ -1000,121 +960,111 @@ describe TodoService do
expect(john_doe.todos_pending_count).to eq(1)
end
- describe '#mark_todos_as_done' do
- let(:issue) { create(:issue, project: project, author: author, assignees: [john_doe]) }
- let(:another_issue) { create(:issue, project: project, author: author, assignees: [john_doe]) }
+ shared_examples 'updating todos state' do |state, new_state, new_resolved_by = nil|
+ let!(:first_todo) { create(:todo, state, user: john_doe) }
+ let!(:second_todo) { create(:todo, state, user: john_doe) }
+ let(:collection) { Todo.all }
- it 'marks a relation of todos as done' do
- create(:todo, :mentioned, user: john_doe, target: issue, project: project)
+ it 'updates related todos for the user with the new_state' do
+ method_call
- todos = TodosFinder.new(john_doe, {}).execute
- expect { described_class.new.mark_todos_as_done(todos, john_doe) }
- .to change { john_doe.todos.done.count }.from(0).to(1)
+ expect(collection.all? { |todo| todo.reload.state?(new_state)}).to be_truthy
end
- it 'marks an array of todos as done' do
- todo = create(:todo, :mentioned, user: john_doe, target: issue, project: project)
+ if new_resolved_by
+ it 'updates resolution mechanism' do
+ method_call
- todos = TodosFinder.new(john_doe, {}).execute
- expect { described_class.new.mark_todos_as_done(todos, john_doe) }
- .to change { todo.reload.state }.from('pending').to('done')
+ expect(collection.all? { |todo| todo.reload.resolved_by_action == new_resolved_by }).to be_truthy
+ end
end
- it 'returns the ids of updated todos' do # Needed on API
- todo = create(:todo, :mentioned, user: john_doe, target: issue, project: project)
-
- todos = TodosFinder.new(john_doe, {}).execute
- expect(described_class.new.mark_todos_as_done(todos, john_doe)).to eq([todo.id])
+ it 'returns the updated ids' do
+ expect(method_call).to match_array([first_todo.id, second_todo.id])
end
- context 'when some of the todos are done already' do
- let!(:first_todo) { create(:todo, :mentioned, user: john_doe, target: issue, project: project) }
- let!(:second_todo) { create(:todo, :mentioned, user: john_doe, target: another_issue, project: project) }
-
- it 'returns the ids of those still pending' do
- described_class.new.mark_pending_todos_as_done(issue, john_doe)
-
- expect(described_class.new.mark_todos_as_done(Todo.all, john_doe)).to eq([second_todo.id])
- end
+ describe 'cached counts' do
+ it 'updates when todos change' do
+ expect(john_doe.todos.where(state: new_state).count).to eq(0)
+ expect(john_doe.todos.where(state: state).count).to eq(2)
+ expect(john_doe).to receive(:update_todos_count_cache).and_call_original
- it 'returns an empty array if all are done' do
- described_class.new.mark_pending_todos_as_done(issue, john_doe)
- described_class.new.mark_pending_todos_as_done(another_issue, john_doe)
+ method_call
- expect(described_class.new.mark_todos_as_done(Todo.all, john_doe)).to eq([])
+ expect(john_doe.todos.where(state: new_state).count).to eq(2)
+ expect(john_doe.todos.where(state: state).count).to eq(0)
end
end
end
- describe '#mark_todo_as_done' do
- it 'marks a todo done' do
- todo1 = create(:todo, :pending, user: john_doe)
-
- described_class.new.mark_todo_as_done(todo1, john_doe)
-
- expect(todo1.reload.state).to eq('done')
- end
-
- context 'when todo is already in state done' do
- let(:todo1) { create(:todo, :done, user: john_doe) }
-
- it 'does not update the todo' do
- expect { described_class.new.mark_todo_as_done(todo1, john_doe) }.not_to change(todo1.reload, :state)
+ describe '#resolve_todos' do
+ it_behaves_like 'updating todos state', :pending, :done, 'mark_done' do
+ subject(:method_call) do
+ service.resolve_todos(collection, john_doe, resolution: :done, resolved_by_action: :mark_done)
end
+ end
+ end
- it 'does not update cache count' do
- expect(john_doe).not_to receive(:update_todos_count_cache)
-
- described_class.new.mark_todo_as_done(todo1, john_doe)
+ describe '#restore_todos' do
+ it_behaves_like 'updating todos state', :done, :pending do
+ subject(:method_call) do
+ service.restore_todos(collection, john_doe)
end
end
end
- describe '#mark_all_todos_as_done_by_user' do
- it 'marks all todos done' do
- todo1 = create(:todo, user: john_doe, state: :pending)
- todo2 = create(:todo, user: john_doe, state: :done)
- todo3 = create(:todo, user: john_doe, state: :pending)
+ describe '#resolve_todo' do
+ let!(:todo) { create(:todo, :assigned, user: john_doe) }
- ids = described_class.new.mark_all_todos_as_done_by_user(john_doe)
+ it 'marks pending todo as done' do
+ expect do
+ service.resolve_todo(todo, john_doe)
+ todo.reload
+ end.to change { todo.done? }.to(true)
+ end
- expect(ids).to contain_exactly(todo1.id, todo3.id)
- expect(todo1.reload.state).to eq('done')
- expect(todo2.reload.state).to eq('done')
- expect(todo3.reload.state).to eq('done')
+ it 'saves resolution mechanism' do
+ expect do
+ service.resolve_todo(todo, john_doe, resolved_by_action: :mark_done)
+ todo.reload
+ end.to change { todo.resolved_by_mark_done? }.to(true)
end
- end
- describe '#mark_todos_as_done_by_ids' do
- let(:issue) { create(:issue, project: project, author: author, assignees: [john_doe]) }
- let(:another_issue) { create(:issue, project: project, author: author, assignees: [john_doe]) }
+ context 'cached counts' do
+ it 'updates when todos change' do
+ expect(john_doe.todos_done_count).to eq(0)
+ expect(john_doe.todos_pending_count).to eq(1)
+ expect(john_doe).to receive(:update_todos_count_cache).and_call_original
- it 'marks an array of todo ids as done' do
- todo = create(:todo, :mentioned, user: john_doe, target: issue, project: project)
- another_todo = create(:todo, :mentioned, user: john_doe, target: another_issue, project: project)
+ service.resolve_todo(todo, john_doe)
- expect { described_class.new.mark_todos_as_done_by_ids([todo.id, another_todo.id], john_doe) }
- .to change { john_doe.todos.done.count }.from(0).to(2)
+ expect(john_doe.todos_done_count).to eq(1)
+ expect(john_doe.todos_pending_count).to eq(0)
+ end
end
+ end
- it 'marks a single todo id as done' do
- todo = create(:todo, :mentioned, user: john_doe, target: issue, project: project)
+ describe '#restore_todo' do
+ let!(:todo) { create(:todo, :done, user: john_doe) }
- expect { described_class.new.mark_todos_as_done_by_ids(todo.id, john_doe) }
- .to change { todo.reload.state }.from('pending').to('done')
+ it 'marks resolved todo as pending' do
+ expect do
+ service.restore_todo(todo, john_doe)
+ todo.reload
+ end.to change { todo.pending? }.to(true)
end
- it 'caches the number of todos of a user', :use_clean_rails_memory_store_caching do
- create(:todo, :mentioned, user: john_doe, target: issue, project: project)
- todo = create(:todo, :mentioned, user: john_doe, target: issue, project: project)
+ context 'cached counts' do
+ it 'updates when todos change' do
+ expect(john_doe.todos_done_count).to eq(1)
+ expect(john_doe.todos_pending_count).to eq(0)
+ expect(john_doe).to receive(:update_todos_count_cache).and_call_original
- described_class.new.mark_todos_as_done_by_ids(todo, john_doe)
+ service.restore_todo(todo, john_doe)
- # Make sure no TodosFinder is inialized to perform counting
- expect(TodosFinder).not_to receive(:new)
-
- expect(john_doe.todos_done_count).to eq(1)
- expect(john_doe.todos_pending_count).to eq(1)
+ expect(john_doe.todos_done_count).to eq(0)
+ expect(john_doe.todos_pending_count).to eq(1)
+ end
end
end
diff --git a/spec/services/user_project_access_changed_service_spec.rb b/spec/services/user_project_access_changed_service_spec.rb
index f27eeb74265..e5ecdd123f7 100644
--- a/spec/services/user_project_access_changed_service_spec.rb
+++ b/spec/services/user_project_access_changed_service_spec.rb
@@ -20,7 +20,11 @@ describe UserProjectAccessChangedService do
it 'permits low-priority operation' do
expect(AuthorizedProjectUpdate::UserRefreshWithLowUrgencyWorker).to(
- receive(:bulk_perform_in).with(described_class::DELAY, [[1], [2]])
+ receive(:bulk_perform_in).with(
+ described_class::DELAY,
+ [[1], [2]],
+ { batch_delay: 30.seconds, batch_size: 100 }
+ )
)
described_class.new([1, 2]).execute(blocking: false,
diff --git a/spec/services/users/destroy_service_spec.rb b/spec/services/users/destroy_service_spec.rb
index 6e4b293286b..3db5e66fe05 100644
--- a/spec/services/users/destroy_service_spec.rb
+++ b/spec/services/users/destroy_service_spec.rb
@@ -67,6 +67,18 @@ describe Users::DestroyService do
end
end
+ it 'calls the bulk snippet destroy service with hard delete option if it is present' do
+ # this avoids getting into Projects::DestroyService as it would
+ # call Snippets::BulkDestroyService first!
+ allow(user).to receive(:personal_projects).and_return([])
+
+ expect_next_instance_of(Snippets::BulkDestroyService) do |bulk_destroy_service|
+ expect(bulk_destroy_service).to receive(:execute).with(hard_delete: true).and_call_original
+ end
+
+ service.execute(user, hard_delete: true)
+ end
+
it 'does not delete project snippets that the user is the author of' do
repo = create(:project_snippet, :repository, author: user).snippet_repository
service.execute(user)
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 a7d7c16a66f..c2a793b2368 100644
--- a/spec/services/users/migrate_to_ghost_user_service_spec.rb
+++ b/spec/services/users/migrate_to_ghost_user_service_spec.rb
@@ -84,6 +84,15 @@ describe Users::MigrateToGhostUserService do
end
end
+ context 'reviews' do
+ let!(:user) { create(:user) }
+ let(:service) { described_class.new(user) }
+
+ include_examples "migrating a deleted user's associated records to the ghost user", Review, [:author] 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)
diff --git a/spec/services/wiki_pages/event_create_service_spec.rb b/spec/services/wiki_pages/event_create_service_spec.rb
index cf971b0a02c..c725c67d7a7 100644
--- a/spec/services/wiki_pages/event_create_service_spec.rb
+++ b/spec/services/wiki_pages/event_create_service_spec.rb
@@ -11,7 +11,7 @@ describe WikiPages::EventCreateService do
describe '#execute' do
let_it_be(:page) { create(:wiki_page, project: project) }
let(:slug) { generate(:sluggified_title) }
- let(:action) { Event::CREATED }
+ let(:action) { :created }
let(:response) { subject.execute(slug, page, action) }
context 'feature flag is not enabled' do
@@ -38,7 +38,7 @@ describe WikiPages::EventCreateService do
end
context 'the action is illegal' do
- let(:action) { Event::WIKI_ACTIONS.max + 1 }
+ let(:action) { :illegal_action }
it 'returns an error' do
expect(response).to be_error
@@ -58,7 +58,7 @@ describe WikiPages::EventCreateService do
end
context 'the action is a deletion' do
- let(:action) { Event::DESTROYED }
+ let(:action) { :destroyed }
it 'does not synchronize the wiki metadata timestamps with the git commit' do
expect_next_instance_of(WikiPage::Meta) do |instance|
@@ -74,7 +74,7 @@ describe WikiPages::EventCreateService do
end
it 'returns an event in the payload' do
- expect(response.payload).to include(event: have_attributes(author: user, wiki_page?: true, action: action))
+ expect(response.payload).to include(event: have_attributes(author: user, wiki_page?: true, action: 'created'))
end
it 'records the slug for the page' do
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 80dfa20a2f1..84de5119505 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -139,6 +139,7 @@ RSpec.configure do |config|
config.include IdempotentWorkerHelper, type: :worker
config.include RailsHelpers
config.include SidekiqMiddleware
+ config.include StubActionCableConnection, type: :channel
if ENV['CI'] || ENV['RETRIES']
# This includes the first try, i.e. tests will be run 4 times before failing.
@@ -172,37 +173,39 @@ RSpec.configure do |config|
end
config.before do |example|
- # Enable all features by default for testing
- allow(Feature).to receive(:enabled?) { true }
+ if example.metadata.fetch(:stub_feature_flags, true)
+ # Enable all features by default for testing
+ stub_all_feature_flags
+
+ # The following can be removed when we remove the staged rollout strategy
+ # and we can just enable it using instance wide settings
+ # (ie. ApplicationSetting#auto_devops_enabled)
+ stub_feature_flags(force_autodevops_on_by_default: false)
+
+ # The following can be removed once Vue Issuable Sidebar
+ # is feature-complete and can be made default in place
+ # of older sidebar.
+ # See https://gitlab.com/groups/gitlab-org/-/epics/1863
+ stub_feature_flags(vue_issuable_sidebar: false)
+ stub_feature_flags(vue_issuable_epic_sidebar: false)
+
+ enable_rugged = example.metadata[:enable_rugged].present?
+
+ # Disable Rugged features by default
+ Gitlab::Git::RuggedImpl::Repository::FEATURE_FLAGS.each do |flag|
+ stub_feature_flags(flag => enable_rugged)
+ end
- enable_rugged = example.metadata[:enable_rugged].present?
+ # Disable the usage of file_identifier_hash by default until it is ready
+ # See https://gitlab.com/gitlab-org/gitlab/-/issues/33867
+ stub_feature_flags(file_identifier_hash: false)
- # Disable Rugged features by default
- Gitlab::Git::RuggedImpl::Repository::FEATURE_FLAGS.each do |flag|
- stub_feature_flags(flag => enable_rugged)
+ allow(Gitlab::GitalyClient).to receive(:can_use_disk?).and_return(enable_rugged)
end
- allow(Gitlab::GitalyClient).to receive(:can_use_disk?).and_return(enable_rugged)
-
- # The following can be removed when we remove the staged rollout strategy
- # and we can just enable it using instance wide settings
- # (ie. ApplicationSetting#auto_devops_enabled)
- stub_feature_flags(force_autodevops_on_by_default: false)
-
# Enable Marginalia feature for all specs in the test suite.
allow(Gitlab::Marginalia).to receive(:cached_feature_enabled?).and_return(true)
- # The following can be removed once Vue Issuable Sidebar
- # is feature-complete and can be made default in place
- # of older sidebar.
- # See https://gitlab.com/groups/gitlab-org/-/epics/1863
- stub_feature_flags(vue_issuable_sidebar: false)
- stub_feature_flags(vue_issuable_epic_sidebar: false)
-
- allow(Feature).to receive(:enabled?)
- .with(/\Apromo_\w+\z/, default_enabled: false)
- .and_return(false)
-
# Stub these calls due to being expensive operations
# It can be reenabled for specific tests via:
#
diff --git a/spec/support/action_cable.rb b/spec/support/action_cable.rb
new file mode 100644
index 00000000000..64cfc435875
--- /dev/null
+++ b/spec/support/action_cable.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+RSpec.configure do |config|
+ config.before(:each, type: :channel) do
+ stub_action_cable_connection
+ end
+end
diff --git a/spec/support/helpers/api_helpers.rb b/spec/support/helpers/api_helpers.rb
index eb9594a4fb6..b1e6078c4f2 100644
--- a/spec/support/helpers/api_helpers.rb
+++ b/spec/support/helpers/api_helpers.rb
@@ -40,17 +40,6 @@ module ApiHelpers
end
end
- def basic_auth_header(user = nil)
- return { 'HTTP_AUTHORIZATION' => user } unless user.respond_to?(:username)
-
- {
- 'HTTP_AUTHORIZATION' => ActionController::HttpAuthentication::Basic.encode_credentials(
- user.username,
- create(:personal_access_token, user: user).token
- )
- }
- end
-
def expect_empty_array_response
expect_successful_response_with_paginated_array
expect(json_response.length).to eq(0)
diff --git a/spec/support/helpers/design_management_test_helpers.rb b/spec/support/helpers/design_management_test_helpers.rb
index bf41e2f5079..1daa92e8ad4 100644
--- a/spec/support/helpers/design_management_test_helpers.rb
+++ b/spec/support/helpers/design_management_test_helpers.rb
@@ -1,9 +1,8 @@
# frozen_string_literal: true
module DesignManagementTestHelpers
- def enable_design_management(enabled = true, ref_filter = true)
+ def enable_design_management(enabled = true)
stub_lfs_setting(enabled: enabled)
- stub_feature_flags(design_management_reference_filter_gfm_pipeline: ref_filter)
end
def delete_designs(*designs)
diff --git a/spec/support/helpers/filter_spec_helper.rb b/spec/support/helpers/filter_spec_helper.rb
index c165128040f..ca844b33ba8 100644
--- a/spec/support/helpers/filter_spec_helper.rb
+++ b/spec/support/helpers/filter_spec_helper.rb
@@ -56,14 +56,11 @@ module FilterSpecHelper
pipeline.call(body)
end
- def reference_pipeline(context = {})
+ def reference_pipeline(filter: described_class, **context)
context.reverse_merge!(project: project) if defined?(project)
context.reverse_merge!(current_user: current_user) if defined?(current_user)
- filters = [
- Banzai::Filter::AutolinkFilter,
- described_class
- ]
+ filters = [Banzai::Filter::AutolinkFilter, filter].compact
redact = context.delete(:redact)
filters.push(Banzai::Filter::ReferenceRedactorFilter) if redact
@@ -75,8 +72,13 @@ module FilterSpecHelper
reference_pipeline(context).call(body)
end
- def reference_filter(html, context = {})
- reference_pipeline(context).to_document(html)
+ def reference_filter(text, context = {})
+ reference_pipeline(**context).to_document(text)
+ end
+
+ # Use to test no-ops
+ def null_filter(text, context = {})
+ reference_pipeline(filter: nil, **context).to_document(text)
end
# Modify a String reference to make it invalid
diff --git a/spec/support/helpers/graphql_helpers.rb b/spec/support/helpers/graphql_helpers.rb
index b3d7f7bcece..87525734490 100644
--- a/spec/support/helpers/graphql_helpers.rb
+++ b/spec/support/helpers/graphql_helpers.rb
@@ -11,9 +11,19 @@ module GraphqlHelpers
underscored_field_name.to_s.camelize(:lower)
end
- # Run a loader's named resolver
+ # Run a loader's named resolver in a way that closely mimics the framework.
+ #
+ # First the `ready?` method is called. If it turns out that the resolver is not
+ # ready, then the early return is returned instead.
+ #
+ # Then the resolve method is called.
def resolve(resolver_class, obj: nil, args: {}, ctx: {}, field: nil)
- resolver_class.new(object: obj, context: ctx, field: field).resolve(args)
+ resolver = resolver_class.new(object: obj, context: ctx, field: field)
+ ready, early_return = sync_all { resolver.ready?(**args) }
+
+ return early_return unless ready
+
+ resolver.resolve(args)
end
# Eagerly run a loader's named resolver
@@ -51,12 +61,12 @@ module GraphqlHelpers
# BatchLoader::GraphQL returns a wrapper, so we need to :sync in order
# to get the actual values
def batch_sync(max_queries: nil, &blk)
- wrapper = proc do
- lazy_vals = yield
- lazy_vals.is_a?(Array) ? lazy_vals.map { |val| sync(val) } : sync(lazy_vals)
- end
+ batch(max_queries: max_queries) { sync_all(&blk) }
+ end
- batch(max_queries: max_queries, &wrapper)
+ def sync_all(&blk)
+ lazy_vals = yield
+ lazy_vals.is_a?(Array) ? lazy_vals.map { |val| sync(val) } : sync(lazy_vals)
end
def graphql_query_for(name, attributes = {}, fields = nil)
@@ -67,10 +77,14 @@ module GraphqlHelpers
QUERY
end
- def graphql_mutation(name, input, fields = nil)
+ def graphql_mutation(name, input, fields = nil, &block)
+ raise ArgumentError, 'Please pass either `fields` parameter or a block to `#graphql_mutation`, but not both.' if fields.present? && block_given?
+
mutation_name = GraphqlHelpers.fieldnamerize(name)
input_variable_name = "$#{input_variable_name_for_mutation(name)}"
mutation_field = GitlabSchema.mutation.fields[mutation_name]
+
+ fields = yield if block_given?
fields ||= all_graphql_fields_for(mutation_field.type.to_graphql)
query = <<~MUTATION
@@ -139,7 +153,15 @@ module GraphqlHelpers
end
def wrap_fields(fields)
- fields = Array.wrap(fields).join("\n")
+ fields = Array.wrap(fields).map do |field|
+ case field
+ when Symbol
+ GraphqlHelpers.fieldnamerize(field)
+ else
+ field
+ end
+ end.join("\n")
+
return unless fields.present?
<<~FIELDS
@@ -257,8 +279,13 @@ module GraphqlHelpers
end
def graphql_dig_at(data, *path)
- keys = path.map { |segment| GraphqlHelpers.fieldnamerize(segment) }
- data.dig(*keys)
+ keys = path.map { |segment| segment.is_a?(Integer) ? segment : GraphqlHelpers.fieldnamerize(segment) }
+
+ # Allows for array indexing, like this
+ # ['project', 'boards', 'edges', 0, 'node', 'lists']
+ keys.reduce(data) do |memo, key|
+ memo.is_a?(Array) ? memo[key] : memo&.dig(key)
+ end
end
def graphql_errors
@@ -294,6 +321,22 @@ module GraphqlHelpers
graphql_data.fetch(GraphqlHelpers.fieldnamerize(mutation_name))
end
+ def scalar_fields_of(type_name)
+ GitlabSchema.types[type_name].fields.map do |name, field|
+ next if nested_fields?(field) || required_arguments?(field)
+
+ name
+ end.compact
+ end
+
+ def nested_fields_of(type_name)
+ GitlabSchema.types[type_name].fields.map do |name, field|
+ next if !nested_fields?(field) || required_arguments?(field)
+
+ [name, field]
+ end.compact
+ end
+
def nested_fields?(field)
!scalar?(field) && !enum?(field)
end
diff --git a/spec/support/helpers/http_basic_auth_helpers.rb b/spec/support/helpers/http_basic_auth_helpers.rb
new file mode 100644
index 00000000000..c0b24b3dfa4
--- /dev/null
+++ b/spec/support/helpers/http_basic_auth_helpers.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module HttpBasicAuthHelpers
+ def user_basic_auth_header(user)
+ access_token = create(:personal_access_token, user: user)
+
+ basic_auth_header(user.username, access_token.token)
+ end
+
+ def job_basic_auth_header(job)
+ basic_auth_header(Ci::Build::CI_REGISTRY_USER, job.token)
+ end
+
+ def client_basic_auth_header(client)
+ basic_auth_header(client.uid, client.secret)
+ end
+
+ def basic_auth_header(username, password)
+ {
+ 'HTTP_AUTHORIZATION' => ActionController::HttpAuthentication::Basic.encode_credentials(
+ username,
+ password
+ )
+ }
+ end
+end
diff --git a/spec/support/helpers/login_helpers.rb b/spec/support/helpers/login_helpers.rb
index cb880939b1c..92f6d673255 100644
--- a/spec/support/helpers/login_helpers.rb
+++ b/spec/support/helpers/login_helpers.rb
@@ -57,13 +57,13 @@ module LoginHelpers
def gitlab_sign_in_via(provider, user, uid, saml_response = nil)
mock_auth_hash_with_saml_xml(provider, uid, user.email, saml_response)
visit new_user_session_path
- click_link provider
+ click_button provider
end
def gitlab_enable_admin_mode_sign_in_via(provider, user, uid, saml_response = nil)
mock_auth_hash_with_saml_xml(provider, uid, user.email, saml_response)
visit new_admin_session_path
- click_link provider
+ click_button provider
end
# Requires Javascript driver.
@@ -103,7 +103,7 @@ module LoginHelpers
check 'remember_me' if remember_me
- click_link "oauth-login-#{provider}"
+ click_button "oauth-login-#{provider}"
end
def fake_successful_u2f_authentication
diff --git a/spec/support/helpers/markdown_feature.rb b/spec/support/helpers/markdown_feature.rb
index eea03fb9325..40e0d4413e2 100644
--- a/spec/support/helpers/markdown_feature.rb
+++ b/spec/support/helpers/markdown_feature.rb
@@ -36,12 +36,12 @@ class MarkdownFeature
end
end
- def project_wiki
- @project_wiki ||= ProjectWiki.new(project, user)
+ def wiki
+ @wiki ||= ProjectWiki.new(project, user)
end
- def project_wiki_page
- @project_wiki_page ||= build(:wiki_page, wiki: project_wiki)
+ def wiki_page
+ @wiki_page ||= build(:wiki_page, wiki: wiki)
end
def issue
diff --git a/spec/support/helpers/partitioning_helpers.rb b/spec/support/helpers/partitioning_helpers.rb
new file mode 100644
index 00000000000..98a13915d76
--- /dev/null
+++ b/spec/support/helpers/partitioning_helpers.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+module PartitioningHelpers
+ def expect_table_partitioned_by(table, columns, part_type: :range)
+ columns_with_part_type = columns.map { |c| [part_type.to_s, c] }
+ actual_columns = find_partitioned_columns(table)
+
+ expect(columns_with_part_type).to match_array(actual_columns)
+ end
+
+ def expect_range_partition_of(partition_name, table_name, min_value, max_value)
+ definition = find_partition_definition(partition_name)
+
+ expect(definition).not_to be_nil
+ expect(definition['base_table']).to eq(table_name.to_s)
+ expect(definition['condition']).to eq("FOR VALUES FROM (#{min_value}) TO (#{max_value})")
+ end
+
+ private
+
+ def find_partitioned_columns(table)
+ connection.select_rows(<<~SQL)
+ select
+ case partstrat
+ when 'l' then 'list'
+ when 'r' then 'range'
+ when 'h' then 'hash'
+ end as partstrat,
+ cols.column_name
+ from (
+ select partrelid, partstrat, unnest(partattrs) as col_pos
+ from pg_partitioned_table
+ ) pg_part
+ inner join pg_class
+ on pg_part.partrelid = pg_class.oid
+ inner join information_schema.columns cols
+ on cols.table_name = pg_class.relname
+ and cols.ordinal_position = pg_part.col_pos
+ where pg_class.relname = '#{table}';
+ SQL
+ end
+
+ def find_partition_definition(partition)
+ connection.select_one(<<~SQL)
+ select
+ parent_class.relname as base_table,
+ pg_get_expr(pg_class.relpartbound, inhrelid) as condition
+ from pg_class
+ inner join pg_inherits i on pg_class.oid = inhrelid
+ inner join pg_class parent_class on parent_class.oid = inhparent
+ where pg_class.relname = '#{partition}' and pg_class.relispartition;
+ SQL
+ end
+end
diff --git a/spec/support/helpers/prometheus_helpers.rb b/spec/support/helpers/prometheus_helpers.rb
index fdce00e7dec..d49abbf3f19 100644
--- a/spec/support/helpers/prometheus_helpers.rb
+++ b/spec/support/helpers/prometheus_helpers.rb
@@ -236,4 +236,51 @@ module PrometheusHelpers
]
}
end
+
+ def prometheus_alert_payload(firing: [], resolved: [])
+ status = firing.any? ? 'firing' : 'resolved'
+ alerts = firing + resolved
+ alert_name = alerts.first&.title || ''
+ prometheus_metric_id = alerts.first&.prometheus_metric_id&.to_s
+
+ alerts_map = \
+ firing.map { |alert| prometheus_map_alert_payload('firing', alert) } +
+ resolved.map { |alert| prometheus_map_alert_payload('resolved', alert) }
+
+ # See https://prometheus.io/docs/alerting/configuration/#%3Cwebhook_config%3E
+ {
+ 'version' => '4',
+ 'receiver' => 'gitlab',
+ 'status' => status,
+ 'alerts' => alerts_map,
+ 'groupLabels' => {
+ 'alertname' => alert_name
+ },
+ 'commonLabels' => {
+ 'alertname' => alert_name,
+ 'gitlab' => 'hook',
+ 'gitlab_alert_id' => prometheus_metric_id
+ },
+ 'commonAnnotations' => {},
+ 'externalURL' => '',
+ 'groupKey' => "{}:{alertname=\'#{alert_name}\'}"
+ }
+ end
+
+ private
+
+ def prometheus_map_alert_payload(status, alert)
+ {
+ 'status' => status,
+ 'labels' => {
+ 'alertname' => alert.title,
+ 'gitlab' => 'hook',
+ 'gitlab_alert_id' => alert.prometheus_metric_id.to_s
+ },
+ 'annotations' => {},
+ 'startsAt' => '2018-09-24T08:57:31.095725221Z',
+ 'endsAt' => '0001-01-01T00:00:00Z',
+ 'generatorURL' => 'http://prometheus-prometheus-server-URL'
+ }
+ end
end
diff --git a/spec/support/helpers/stub_action_cable_connection.rb b/spec/support/helpers/stub_action_cable_connection.rb
new file mode 100644
index 00000000000..b4e9c2ae48c
--- /dev/null
+++ b/spec/support/helpers/stub_action_cable_connection.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+module StubActionCableConnection
+ def stub_action_cable_connection(current_user: nil, request: ActionDispatch::TestRequest.create)
+ stub_connection(current_user: current_user, request: request)
+ end
+end
diff --git a/spec/support/helpers/stub_feature_flags.rb b/spec/support/helpers/stub_feature_flags.rb
index 5b8a85b206f..696148cacaf 100644
--- a/spec/support/helpers/stub_feature_flags.rb
+++ b/spec/support/helpers/stub_feature_flags.rb
@@ -1,6 +1,38 @@
# frozen_string_literal: true
module StubFeatureFlags
+ class StubFeatureGate
+ attr_reader :flipper_id
+
+ def initialize(flipper_id)
+ @flipper_id = flipper_id
+ end
+ end
+
+ def stub_all_feature_flags
+ adapter = Flipper::Adapters::Memory.new
+ flipper = Flipper.new(adapter)
+
+ allow(Feature).to receive(:flipper).and_return(flipper)
+
+ # All new requested flags are enabled by default
+ allow(Feature).to receive(:enabled?).and_wrap_original do |m, *args|
+ feature_flag = m.call(*args)
+
+ # If feature flag is not persisted we mark the feature flag as enabled
+ # We do `m.call` as we want to validate the execution of method arguments
+ # and a feature flag state if it is not persisted
+ unless Feature.persisted_name?(args.first)
+ # TODO: this is hack to support `promo_feature_available?`
+ # We enable all feature flags by default unless they are `promo_`
+ # Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/218667
+ feature_flag = true unless args.first.to_s.start_with?('promo_')
+ end
+
+ feature_flag
+ end
+ end
+
# Stub Feature flags with `flag_name: true/false`
#
# @param [Hash] features where key is feature name and value is boolean whether enabled or not.
@@ -14,23 +46,29 @@ module StubFeatureFlags
# Enable `ci_live_trace` feature flag only on the specified projects.
def stub_feature_flags(features)
features.each do |feature_name, actors|
- allow(Feature).to receive(:enabled?).with(feature_name, any_args).and_return(false)
- allow(Feature).to receive(:enabled?).with(feature_name.to_s, any_args).and_return(false)
+ # Remove feature flag overwrite
+ feature = Feature.get(feature_name) # rubocop:disable Gitlab/AvoidFeatureGet
+ feature.remove
Array(actors).each do |actor|
raise ArgumentError, "actor cannot be Hash" if actor.is_a?(Hash)
- case actor
- when false, true
- allow(Feature).to receive(:enabled?).with(feature_name, any_args).and_return(actor)
- allow(Feature).to receive(:enabled?).with(feature_name.to_s, any_args).and_return(actor)
- when nil, ActiveRecord::Base, Symbol, RSpec::Mocks::Double
- allow(Feature).to receive(:enabled?).with(feature_name, actor, any_args).and_return(true)
- allow(Feature).to receive(:enabled?).with(feature_name.to_s, actor, any_args).and_return(true)
+ # Control a state of feature flag
+ if actor == true || actor.nil? || actor.respond_to?(:flipper_id)
+ feature.enable(actor)
+ elsif actor == false
+ feature.disable
else
- raise ArgumentError, "#stub_feature_flags accepts only `nil`, `true`, `false`, `ActiveRecord::Base` or `Symbol` as actors"
+ raise ArgumentError, "#stub_feature_flags accepts only `nil`, `bool`, an object responding to `#flipper_id` or including `FeatureGate`."
end
end
end
end
+
+ def stub_feature_flag_gate(object)
+ return if object.nil?
+ return object if object.is_a?(FeatureGate)
+
+ StubFeatureGate.new(object)
+ end
end
diff --git a/spec/support/helpers/stub_gitlab_calls.rb b/spec/support/helpers/stub_gitlab_calls.rb
index 120d432655b..4da8f760056 100644
--- a/spec/support/helpers/stub_gitlab_calls.rb
+++ b/spec/support/helpers/stub_gitlab_calls.rb
@@ -141,6 +141,12 @@ module StubGitlabCalls
.to_return(status: 200, body: "", headers: {})
end
+ def stub_webide_config_file(content, sha: anything)
+ allow_any_instance_of(Repository)
+ .to receive(:blob_data_at).with(sha, '.gitlab/.gitlab-webide.yml')
+ .and_return(content)
+ end
+
def project_hash_array
f = File.read(Rails.root.join('spec/support/gitlab_stubs/projects.json'))
Gitlab::Json.parse(f)
diff --git a/spec/support/helpers/trigger_helpers.rb b/spec/support/helpers/trigger_helpers.rb
new file mode 100644
index 00000000000..fa4f499b900
--- /dev/null
+++ b/spec/support/helpers/trigger_helpers.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+module TriggerHelpers
+ def expect_function_to_exist(name)
+ expect(find_function_def(name)).not_to be_nil
+ end
+
+ def expect_function_not_to_exist(name)
+ expect(find_function_def(name)).to be_nil
+ end
+
+ def expect_function_to_contain(name, *statements)
+ return_stmt, *body_stmts = parsed_function_statements(name).reverse
+
+ expect(return_stmt).to eq('return old')
+ expect(body_stmts).to contain_exactly(*statements)
+ end
+
+ def expect_trigger_not_to_exist(table_name, name)
+ expect(find_trigger_def(table_name, name)).to be_nil
+ end
+
+ def expect_valid_function_trigger(table_name, name, fn_name, fires_on)
+ events, timing, definition = cleaned_trigger_def(table_name, name)
+
+ events = events&.split(',')
+ expected_timing, expected_events = fires_on.first
+ expect(timing).to eq(expected_timing.to_s)
+ expect(events).to match_array(Array.wrap(expected_events))
+ expect(definition).to eq("execute procedure #{fn_name}()")
+ end
+
+ private
+
+ def parsed_function_statements(name)
+ cleaned_definition = find_function_def(name)['body'].downcase.gsub(/\s+/, ' ')
+ statements = cleaned_definition.sub(/\A\s*begin\s*(.*)\s*end\s*\Z/, "\\1")
+ statements.split(';').map! { |stmt| stmt.strip.presence }.compact!
+ end
+
+ def find_function_def(name)
+ connection.select_one(<<~SQL)
+ SELECT prosrc AS body
+ FROM pg_proc
+ WHERE proname = '#{name}'
+ SQL
+ end
+
+ def cleaned_trigger_def(table_name, name)
+ find_trigger_def(table_name, name).values_at('event', 'action_timing', 'action_statement').map!(&:downcase)
+ end
+
+ def find_trigger_def(table_name, name)
+ connection.select_one(<<~SQL)
+ SELECT
+ string_agg(event_manipulation, ',') AS event,
+ action_timing,
+ action_statement
+ FROM information_schema.triggers
+ WHERE event_object_table = '#{table_name}'
+ AND trigger_name = '#{name}'
+ GROUP BY 2, 3
+ SQL
+ end
+end
diff --git a/spec/support/helpers/usage_data_helpers.rb b/spec/support/helpers/usage_data_helpers.rb
index 382e4f6a1a4..f6c415a75bc 100644
--- a/spec/support/helpers/usage_data_helpers.rb
+++ b/spec/support/helpers/usage_data_helpers.rb
@@ -78,6 +78,7 @@ module UsageDataHelpers
labels
lfs_objects
merge_requests
+ merge_requests_users
milestone_lists
milestones
notes
@@ -117,12 +118,18 @@ module UsageDataHelpers
projects_with_expiration_policy_enabled_with_cadence_set_to_14d
projects_with_expiration_policy_enabled_with_cadence_set_to_1month
projects_with_expiration_policy_enabled_with_cadence_set_to_3month
+ projects_with_terraform_reports
+ projects_with_terraform_states
pages_domains
protected_branches
releases
remote_mirrors
snippets
+ personal_snippets
+ project_snippets
suggestions
+ terraform_reports
+ terraform_states
todos
uploads
web_hooks
@@ -157,6 +164,11 @@ module UsageDataHelpers
object_store
).freeze
+ def stub_usage_data_connections
+ allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false)
+ allow(Gitlab::Prometheus::Internal).to receive(:prometheus_enabled?).and_return(false)
+ end
+
def stub_object_store_settings
allow(Settings).to receive(:[]).with('artifacts')
.and_return(
@@ -209,4 +221,16 @@ module UsageDataHelpers
'proxy_download' => false } }
)
end
+
+ def expect_prometheus_api_to(*receive_matchers)
+ expect_next_instance_of(Gitlab::PrometheusClient) do |client|
+ receive_matchers.each { |m| expect(client).to m }
+ end
+ end
+
+ def allow_prometheus_queries
+ allow_next_instance_of(Gitlab::PrometheusClient) do |client|
+ allow(client).to receive(:aggregate).and_return({})
+ end
+ end
end
diff --git a/spec/support/helpers/wiki_helpers.rb b/spec/support/helpers/wiki_helpers.rb
index e6818ff8f0c..ae0d53d1297 100644
--- a/spec/support/helpers/wiki_helpers.rb
+++ b/spec/support/helpers/wiki_helpers.rb
@@ -8,14 +8,14 @@ module WikiHelpers
find('.svg-content .js-lazy-loaded') if example.nil? || example.metadata.key?(:js)
end
- def upload_file_to_wiki(project, user, file_name)
+ def upload_file_to_wiki(container, user, file_name)
opts = {
file_name: file_name,
file_content: File.read(expand_fixture_path(file_name))
}
::Wikis::CreateAttachmentService.new(
- container: project,
+ container: container,
current_user: user,
params: opts
).execute[:result][:file_path]
diff --git a/spec/support/import_export/common_util.rb b/spec/support/import_export/common_util.rb
index 0069ae81b76..c0c3559cca0 100644
--- a/spec/support/import_export/common_util.rb
+++ b/spec/support/import_export/common_util.rb
@@ -19,7 +19,7 @@ module ImportExport
end
def setup_reader(reader)
- if reader == :ndjson_reader && Feature.enabled?(:project_import_ndjson)
+ if reader == :ndjson_reader && Feature.enabled?(:project_import_ndjson, default_enabled: true)
allow_any_instance_of(Gitlab::ImportExport::JSON::LegacyReader::File).to receive(:exist?).and_return(false)
allow_any_instance_of(Gitlab::ImportExport::JSON::NdjsonReader).to receive(:exist?).and_return(true)
else
diff --git a/spec/support/let_it_be.rb b/spec/support/let_it_be.rb
new file mode 100644
index 00000000000..ade585faaec
--- /dev/null
+++ b/spec/support/let_it_be.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+TestProf::LetItBe.configure do |config|
+ config.alias_to :let_it_be_with_refind, refind: true
+end
+
+TestProf::LetItBe.configure do |config|
+ config.alias_to :let_it_be_with_reload, reload: true
+end
diff --git a/spec/support/matchers/exceed_query_limit.rb b/spec/support/matchers/exceed_query_limit.rb
index b9630b00038..cc0abfa0dd6 100644
--- a/spec/support/matchers/exceed_query_limit.rb
+++ b/spec/support/matchers/exceed_query_limit.rb
@@ -59,11 +59,15 @@ module ExceedQueryLimitHelpers
def verify_count(&block)
@subject_block = block
- actual_count > expected_count + threshold
+ actual_count > maximum
+ end
+
+ def maximum
+ expected_count + threshold
end
def failure_message
- threshold_message = threshold > 0 ? " (+#{@threshold})" : ''
+ threshold_message = threshold > 0 ? " (+#{threshold})" : ''
counts = "#{expected_count}#{threshold_message}"
"Expected a maximum of #{counts} queries, got #{actual_count}:\n\n#{log_message}"
end
@@ -73,6 +77,55 @@ module ExceedQueryLimitHelpers
end
end
+RSpec::Matchers.define :issue_fewer_queries_than do
+ supports_block_expectations
+
+ include ExceedQueryLimitHelpers
+
+ def control
+ block_arg
+ end
+
+ def control_recorder
+ @control_recorder ||= ActiveRecord::QueryRecorder.new(&control)
+ end
+
+ def expected_count
+ control_recorder.count
+ end
+
+ def verify_count(&block)
+ @subject_block = block
+
+ # These blocks need to be evaluated in an expected order, in case
+ # the events in expected affect the counts in actual
+ expected_count
+ actual_count
+
+ actual_count < expected_count
+ end
+
+ match do |block|
+ verify_count(&block)
+ end
+
+ def failure_message
+ <<~MSG
+ Expected to issue fewer than #{expected_count} queries, but got #{actual_count}
+
+ #{log_message}
+ MSG
+ end
+
+ failure_message_when_negated do |actual|
+ <<~MSG
+ Expected query count of #{actual_count} to be less than #{expected_count}
+
+ #{log_message}
+ MSG
+ end
+end
+
RSpec::Matchers.define :issue_same_number_of_queries_as do
supports_block_expectations
@@ -82,30 +135,66 @@ RSpec::Matchers.define :issue_same_number_of_queries_as do
block_arg
end
+ chain :or_fewer do
+ @or_fewer = true
+ end
+
+ chain :ignoring_cached_queries do
+ @skip_cached = true
+ end
+
def control_recorder
@control_recorder ||= ActiveRecord::QueryRecorder.new(&control)
end
def expected_count
- @expected_count ||= control_recorder.count
+ control_recorder.count
end
def verify_count(&block)
@subject_block = block
- (expected_count - actual_count).abs <= threshold
+ # These blocks need to be evaluated in an expected order, in case
+ # the events in expected affect the counts in actual
+ expected_count
+ actual_count
+
+ if @or_fewer
+ actual_count <= expected_count
+ else
+ (expected_count - actual_count).abs <= threshold
+ end
end
match do |block|
verify_count(&block)
end
+ def failure_message
+ <<~MSG
+ Expected #{expected_count_message} queries, but got #{actual_count}
+
+ #{log_message}
+ MSG
+ end
+
failure_message_when_negated do |actual|
- failure_message
+ <<~MSG
+ Expected #{actual_count} not to equal #{expected_count_message}
+
+ #{log_message}
+ MSG
+ end
+
+ def expected_count_message
+ or_fewer_msg = "or fewer" if @or_fewer
+ threshold_msg = "(+/- #{threshold})" unless threshold.zero?
+
+ ["#{expected_count}", or_fewer_msg, threshold_msg].compact.join(' ')
end
def skip_cached
- false
+ @skip_cached || false
end
end
diff --git a/spec/support/matchers/graphql_matchers.rb b/spec/support/matchers/graphql_matchers.rb
index 3e2193a9069..7fa06e25405 100644
--- a/spec/support/matchers/graphql_matchers.rb
+++ b/spec/support/matchers/graphql_matchers.rb
@@ -82,12 +82,30 @@ RSpec::Matchers.define :have_graphql_mutation do |mutation_class|
end
end
+# note: connection arguments do not have to be named, they will be inferred.
RSpec::Matchers.define :have_graphql_arguments do |*expected|
include GraphqlHelpers
+ def expected_names(field)
+ @names ||= Array.wrap(expected).map { |name| GraphqlHelpers.fieldnamerize(name) }
+
+ if field.type.try(:ancestors)&.include?(GraphQL::Types::Relay::BaseConnection)
+ @names | %w(after before first last)
+ else
+ @names
+ end
+ end
+
match do |field|
- argument_names = expected.map { |name| GraphqlHelpers.fieldnamerize(name) }
- expect(field.arguments.keys).to contain_exactly(*argument_names)
+ names = expected_names(field)
+
+ expect(field.arguments.keys).to contain_exactly(*names)
+ end
+
+ failure_message do |field|
+ names = expected_names(field)
+
+ "expected that #{field.name} would have the following fields: #{names.inspect}, but it has #{field.arguments.keys.inspect}."
end
end
diff --git a/spec/support/rspec.rb b/spec/support/rspec.rb
index 1c9f9e5161e..7d011c5eb95 100644
--- a/spec/support/rspec.rb
+++ b/spec/support/rspec.rb
@@ -4,6 +4,7 @@ require_relative "helpers/stub_configuration"
require_relative "helpers/stub_metrics"
require_relative "helpers/stub_object_storage"
require_relative "helpers/stub_env"
+require_relative "helpers/expect_offense"
RSpec.configure do |config|
config.mock_with :rspec
@@ -13,4 +14,6 @@ RSpec.configure do |config|
config.include StubMetrics
config.include StubObjectStorage
config.include StubENV
+
+ config.include ExpectOffense, type: :rubocop
end
diff --git a/spec/support/shared_contexts/finders/merge_requests_finder_shared_contexts.rb b/spec/support/shared_contexts/finders/merge_requests_finder_shared_contexts.rb
index 617701abf27..2b8daa80ab4 100644
--- a/spec/support/shared_contexts/finders/merge_requests_finder_shared_contexts.rb
+++ b/spec/support/shared_contexts/finders/merge_requests_finder_shared_contexts.rb
@@ -45,11 +45,32 @@ RSpec.shared_context 'MergeRequestsFinder multiple projects with merge requests
allow_gitaly_n_plus_1 { create(:project, group: subgroup) }
end
- let!(:merge_request1) { create(:merge_request, assignees: [user], author: user, source_project: project2, target_project: project1, target_branch: 'merged-target') }
- let!(:merge_request2) { create(:merge_request, :conflict, assignees: [user], author: user, source_project: project2, target_project: project1, state: 'closed') }
- let!(:merge_request3) { create(:merge_request, :simple, author: user, assignees: [user2], source_project: project2, target_project: project2, state: 'locked', title: 'thing WIP thing') }
- let!(:merge_request4) { create(:merge_request, :simple, author: user, source_project: project3, target_project: project3, title: 'WIP thing') }
- let!(:merge_request5) { create(:merge_request, :simple, author: user, source_project: project4, target_project: project4, title: '[WIP]') }
+ let!(:merge_request1) do
+ create(:merge_request, assignees: [user], author: user,
+ source_project: project2, target_project: project1,
+ target_branch: 'merged-target')
+ end
+ let!(:merge_request2) do
+ create(:merge_request, :conflict, assignees: [user], author: user,
+ source_project: project2, target_project: project1,
+ state: 'closed')
+ end
+ let!(:merge_request3) do
+ create(:merge_request, :simple, author: user, assignees: [user2],
+ source_project: project2, target_project: project2,
+ state: 'locked',
+ title: 'thing WIP thing')
+ end
+ let!(:merge_request4) do
+ create(:merge_request, :simple, author: user,
+ source_project: project3, target_project: project3,
+ title: 'WIP thing')
+ end
+ let_it_be(:merge_request5) do
+ create(:merge_request, :simple, author: user,
+ source_project: project4, target_project: project4,
+ title: '[WIP]')
+ end
before do
project1.add_maintainer(user)
diff --git a/spec/support/shared_contexts/navbar_structure_context.rb b/spec/support/shared_contexts/navbar_structure_context.rb
index fe3c32ec0c5..79b5ff44d4f 100644
--- a/spec/support/shared_contexts/navbar_structure_context.rb
+++ b/spec/support/shared_contexts/navbar_structure_context.rb
@@ -80,10 +80,13 @@ RSpec.shared_context 'project navbar structure' do
nav_sub_items: []
},
{
+ nav_item: _('Members'),
+ nav_sub_items: []
+ },
+ {
nav_item: _('Settings'),
nav_sub_items: [
_('General'),
- _('Members'),
_('Integrations'),
_('Webhooks'),
_('Access Tokens'),
diff --git a/spec/support/shared_contexts/project_service_shared_context.rb b/spec/support/shared_contexts/project_service_shared_context.rb
index 21d67ea71a8..5b0dd26bd7b 100644
--- a/spec/support/shared_contexts/project_service_shared_context.rb
+++ b/spec/support/shared_contexts/project_service_shared_context.rb
@@ -5,7 +5,6 @@ shared_context 'project service activation' do
let(:user) { create(:user) }
before do
- stub_feature_flags(integration_form_refactor: false)
project.add_maintainer(user)
sign_in(user)
end
diff --git a/spec/support/shared_contexts/requests/api/graphql/jira_import/jira_projects_context.rb b/spec/support/shared_contexts/requests/api/graphql/jira_import/jira_projects_context.rb
new file mode 100644
index 00000000000..f0722beb3ed
--- /dev/null
+++ b/spec/support/shared_contexts/requests/api/graphql/jira_import/jira_projects_context.rb
@@ -0,0 +1,104 @@
+# frozen_string_literal: true
+
+shared_context 'jira projects request context' do
+ let(:url) { 'https://jira.example.com' }
+ let(:username) { 'jira-username' }
+ let(:password) { 'jira-password' }
+ let!(:jira_service) do
+ create(:jira_service,
+ project: project,
+ url: url,
+ username: username,
+ password: password
+ )
+ end
+
+ let_it_be(:jira_projects_json) do
+ '{
+ "self": "https://your-domain.atlassian.net/rest/api/2/project/search?startAt=0&maxResults=2",
+ "nextPage": "https://your-domain.atlassian.net/rest/api/2/project/search?startAt=2&maxResults=2",
+ "maxResults": 2,
+ "startAt": 0,
+ "total": 7,
+ "isLast": false,
+ "values": [
+ {
+ "self": "https://your-domain.atlassian.net/rest/api/2/project/EX",
+ "id": "10000",
+ "key": "EX",
+ "name": "Example",
+ "avatarUrls": {
+ "48x48": "https://your-domain.atlassian.net/secure/projectavatar?size=large&pid=10000",
+ "24x24": "https://your-domain.atlassian.net/secure/projectavatar?size=small&pid=10000",
+ "16x16": "https://your-domain.atlassian.net/secure/projectavatar?size=xsmall&pid=10000",
+ "32x32": "https://your-domain.atlassian.net/secure/projectavatar?size=medium&pid=10000"
+ },
+ "projectCategory": {
+ "self": "https://your-domain.atlassian.net/rest/api/2/projectCategory/10000",
+ "id": "10000",
+ "name": "FIRST",
+ "description": "First Project Category"
+ },
+ "simplified": false,
+ "style": "classic",
+ "insight": {
+ "totalIssueCount": 100,
+ "lastIssueUpdateTime": "2020-03-31T05:45:24.792+0000"
+ }
+ },
+ {
+ "self": "https://your-domain.atlassian.net/rest/api/2/project/ABC",
+ "id": "10001",
+ "key": "ABC",
+ "name": "Alphabetical",
+ "avatarUrls": {
+ "48x48": "https://your-domain.atlassian.net/secure/projectavatar?size=large&pid=10001",
+ "24x24": "https://your-domain.atlassian.net/secure/projectavatar?size=small&pid=10001",
+ "16x16": "https://your-domain.atlassian.net/secure/projectavatar?size=xsmall&pid=10001",
+ "32x32": "https://your-domain.atlassian.net/secure/projectavatar?size=medium&pid=10001"
+ },
+ "projectCategory": {
+ "self": "https://your-domain.atlassian.net/rest/api/2/projectCategory/10000",
+ "id": "10000",
+ "name": "FIRST",
+ "description": "First Project Category"
+ },
+ "simplified": false,
+ "style": "classic",
+ "insight": {
+ "totalIssueCount": 100,
+ "lastIssueUpdateTime": "2020-03-31T05:45:24.792+0000"
+ }
+ }
+ ]
+ }'
+ end
+
+ let_it_be(:empty_jira_projects_json) do
+ '{
+ "self": "https://your-domain.atlassian.net/rest/api/2/project/search?startAt=0&maxResults=2",
+ "nextPage": "https://your-domain.atlassian.net/rest/api/2/project/search?startAt=2&maxResults=2",
+ "maxResults": 2,
+ "startAt": 0,
+ "total": 7,
+ "isLast": false,
+ "values": []
+ }'
+ end
+
+ let(:test_url) { "#{url}/rest/api/2/project/search?maxResults=50&query=&startAt=0" }
+ let(:start_at_20_url) { "#{url}/rest/api/2/project/search?maxResults=50&query=&startAt=20" }
+ let(:start_at_1_url) { "#{url}/rest/api/2/project/search?maxResults=50&query=&startAt=1" }
+ let(:max_results_1_url) { "#{url}/rest/api/2/project/search?maxResults=1&query=&startAt=0" }
+
+ before do
+ WebMock.stub_request(:get, test_url).with(basic_auth: [username, password])
+ .to_return(body: jira_projects_json, headers: { "Content-Type": "application/json" })
+ WebMock.stub_request(:get, start_at_20_url).with(basic_auth: [username, password])
+ .to_return(body: empty_jira_projects_json, headers: { "Content-Type": "application/json" })
+ WebMock.stub_request(:get, start_at_1_url).with(basic_auth: [username, password])
+ .to_return(body: jira_projects_json, headers: { "Content-Type": "application/json" })
+ WebMock.stub_request(:get, max_results_1_url).with(basic_auth: [username, password])
+ .to_return(body: jira_projects_json, headers: { "Content-Type": "application/json" })
+ end
+end
diff --git a/spec/support/shared_contexts/spam_constants.rb b/spec/support/shared_contexts/spam_constants.rb
index b6e92ea3050..32371f4b92f 100644
--- a/spec/support/shared_contexts/spam_constants.rb
+++ b/spec/support/shared_contexts/spam_constants.rb
@@ -1,7 +1,10 @@
# frozen_string_literal: true
shared_context 'includes Spam constants' do
- REQUIRE_RECAPTCHA = Spam::SpamConstants::REQUIRE_RECAPTCHA
- DISALLOW = Spam::SpamConstants::DISALLOW
- ALLOW = Spam::SpamConstants::ALLOW
+ before do
+ stub_const('CONDITIONAL_ALLOW', Spam::SpamConstants::CONDITIONAL_ALLOW)
+ stub_const('DISALLOW', Spam::SpamConstants::DISALLOW)
+ stub_const('ALLOW', Spam::SpamConstants::ALLOW)
+ stub_const('BLOCK_USER', Spam::SpamConstants::BLOCK_USER)
+ end
end
diff --git a/spec/support/shared_examples/controllers/import_controller_new_import_ui_shared_examples.rb b/spec/support/shared_examples/controllers/import_controller_new_import_ui_shared_examples.rb
new file mode 100644
index 00000000000..88ad1f6cde2
--- /dev/null
+++ b/spec/support/shared_examples/controllers/import_controller_new_import_ui_shared_examples.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'import controller with new_import_ui feature flag' do
+ include ImportSpecHelper
+
+ context 'with new_import_ui feature flag enabled' do
+ let(:group) { create(:group) }
+
+ before do
+ stub_feature_flags(new_import_ui: true)
+ group.add_owner(user)
+ end
+
+ it "returns variables for json request" do
+ project = create(:project, import_type: provider_name, creator_id: user.id)
+ stub_client(client_repos_field => [repo])
+
+ get :status, format: :json
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response.dig("imported_projects", 0, "id")).to eq(project.id)
+ expect(json_response.dig("provider_repos", 0, "id")).to eq(repo_id)
+ expect(json_response.dig("namespaces", 0, "id")).to eq(group.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
+end
diff --git a/spec/support/shared_examples/controllers/issuables_list_metadata_shared_examples.rb b/spec/support/shared_examples/controllers/issuables_list_metadata_shared_examples.rb
index 2dbaea57c44..62a1a07b6c1 100644
--- a/spec/support/shared_examples/controllers/issuables_list_metadata_shared_examples.rb
+++ b/spec/support/shared_examples/controllers/issuables_list_metadata_shared_examples.rb
@@ -34,7 +34,7 @@ RSpec.shared_examples 'issuables list meta-data' do |issuable_type, action = nil
aggregate_failures do
expect(meta_data.keys).to match_array(issuables.map(&:id))
- expect(meta_data.values).to all(be_kind_of(Issuable::IssuableMeta))
+ expect(meta_data.values).to all(be_kind_of(Gitlab::IssuableMetadata::IssuableMeta))
end
end
diff --git a/spec/support/shared_examples/controllers/milestone_tabs_shared_examples.rb b/spec/support/shared_examples/controllers/milestone_tabs_shared_examples.rb
index d9656824452..925c45005f0 100644
--- a/spec/support/shared_examples/controllers/milestone_tabs_shared_examples.rb
+++ b/spec/support/shared_examples/controllers/milestone_tabs_shared_examples.rb
@@ -2,15 +2,7 @@
RSpec.shared_examples 'milestone tabs' do
def go(path, extra_params = {})
- params =
- case milestone
- when DashboardMilestone
- { id: milestone.safe_title, title: milestone.title }
- when GroupMilestone
- { group_id: group.to_param, id: milestone.safe_title, title: milestone.title }
- else
- { namespace_id: project.namespace.to_param, project_id: project, id: milestone.iid }
- end
+ params = { namespace_id: project.namespace.to_param, project_id: project, id: milestone.iid }
get path, params: params.merge(extra_params)
end
diff --git a/spec/support/shared_examples/controllers/namespace_storage_limit_alert_shared_examples.rb b/spec/support/shared_examples/controllers/namespace_storage_limit_alert_shared_examples.rb
new file mode 100644
index 00000000000..7885eb6c1f8
--- /dev/null
+++ b/spec/support/shared_examples/controllers/namespace_storage_limit_alert_shared_examples.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'namespace storage limit alert' do
+ let(:alert_level) { :info }
+
+ before do
+ allow_next_instance_of(Namespaces::CheckStorageSizeService, namespace, user) do |check_storage_size_service|
+ expect(check_storage_size_service).to receive(:execute).and_return(
+ ServiceResponse.success(
+ payload: {
+ alert_level: alert_level,
+ usage_message: "Usage",
+ explanation_message: "Explanation",
+ root_namespace: namespace
+ }
+ )
+ )
+ end
+
+ allow(controller).to receive(:current_user).and_return(user)
+ end
+
+ render_views
+
+ it 'does render' do
+ subject
+
+ expect(response.body).to match(/Explanation/)
+ expect(response.body).to have_css('.js-namespace-storage-alert-dismiss')
+ end
+
+ context 'when alert_level is error' do
+ let(:alert_level) { :error }
+
+ it 'does not render a dismiss button' do
+ subject
+
+ expect(response.body).not_to have_css('.js-namespace-storage-alert-dismiss')
+ end
+ end
+
+ context 'when cookie is set' do
+ before do
+ cookies["hide_storage_limit_alert_#{namespace.id}_info"] = 'true'
+ end
+
+ it 'does not render alert' do
+ subject
+
+ expect(response.body).not_to match(/Explanation/)
+ end
+ end
+end
diff --git a/spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb b/spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb
new file mode 100644
index 00000000000..c128bbe5e02
--- /dev/null
+++ b/spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb
@@ -0,0 +1,302 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'wiki controller actions' do
+ let(:container) { raise NotImplementedError }
+ let(:routing_params) { raise NotImplementedError }
+
+ let_it_be(:user) { create(:user) }
+ let(:wiki) { Wiki.for_container(container, user) }
+ let(:wiki_title) { 'page title test' }
+
+ before do
+ create(:wiki_page, wiki: wiki, title: wiki_title, content: 'hello world')
+
+ sign_in(user)
+ end
+
+ describe 'GET #new' do
+ subject { get :new, params: routing_params }
+
+ it 'redirects to #show and appends a `random_title` param' do
+ subject
+
+ expect(response).to be_redirect
+ expect(response.redirect_url).to match(%r{
+ #{Regexp.quote(wiki.wiki_base_path)} # wiki base path
+ /[-\h]{36} # page slug
+ \?random_title=true\Z # random_title param
+ }x)
+ end
+
+ context 'when the wiki repository cannot be created' do
+ before do
+ expect(Wiki).to receive(:for_container).and_return(wiki)
+ expect(wiki).to receive(:wiki) { raise Wiki::CouldNotCreateWikiError }
+ end
+
+ it 'redirects to the wiki container and displays an error message' do
+ subject
+
+ expect(response).to redirect_to(container)
+ expect(flash[:notice]).to eq('Could not create Wiki Repository at this time. Please try again later.')
+ end
+ end
+ end
+
+ describe 'GET #pages' do
+ before do
+ get :pages, params: routing_params.merge(id: wiki_title)
+ end
+
+ it 'assigns the page collections' do
+ expect(assigns(:wiki_pages)).to contain_exactly(an_instance_of(WikiPage))
+ expect(assigns(:wiki_entries)).to contain_exactly(an_instance_of(WikiPage))
+ end
+
+ it 'does not load the page content' do
+ expect(assigns(:page)).to be_nil
+ end
+
+ it 'does not load the sidebar' do
+ expect(assigns(:sidebar_wiki_entries)).to be_nil
+ expect(assigns(:sidebar_limited)).to be_nil
+ end
+ end
+
+ describe 'GET #history' do
+ before do
+ allow(controller)
+ .to receive(:can?)
+ .with(any_args)
+ .and_call_original
+
+ # The :create_wiki permission is irrelevant to reading history.
+ expect(controller)
+ .not_to receive(:can?)
+ .with(anything, :create_wiki, any_args)
+
+ allow(controller)
+ .to receive(:can?)
+ .with(anything, :read_wiki, any_args)
+ .and_return(allow_read_wiki)
+ end
+
+ shared_examples 'fetching history' do |expected_status|
+ before do
+ get :history, params: routing_params.merge(id: wiki_title)
+ end
+
+ it "returns status #{expected_status}" do
+ expect(response).to have_gitlab_http_status(expected_status)
+ end
+ end
+
+ it_behaves_like 'fetching history', :ok do
+ let(:allow_read_wiki) { true }
+
+ it 'assigns @page_versions' do
+ expect(assigns(:page_versions)).to be_present
+ end
+ end
+
+ it_behaves_like 'fetching history', :not_found do
+ let(:allow_read_wiki) { false }
+ end
+ end
+
+ describe 'GET #show' do
+ render_views
+
+ let(:random_title) { nil }
+
+ subject { get :show, params: routing_params.merge(id: id, random_title: random_title) }
+
+ context 'when page exists' do
+ let(:id) { wiki_title }
+
+ it 'renders the page' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(assigns(:page).title).to eq(wiki_title)
+ expect(assigns(:sidebar_wiki_entries)).to contain_exactly(an_instance_of(WikiPage))
+ expect(assigns(:sidebar_limited)).to be(false)
+ end
+
+ context 'when page content encoding is invalid' do
+ it 'sets flash error' do
+ allow(controller).to receive(:valid_encoding?).and_return(false)
+
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(flash[:notice]).to eq(_('The content of this page is not encoded in UTF-8. Edits can only be made via the Git repository.'))
+ end
+ end
+ end
+
+ context 'when the page does not exist' do
+ let(:id) { 'does not exist' }
+
+ before do
+ subject
+ end
+
+ it 'builds a new wiki page with the id as the title' do
+ expect(assigns(:page).title).to eq(id)
+ end
+
+ context 'when a random_title param is present' do
+ let(:random_title) { true }
+
+ it 'builds a new wiki page with no title' do
+ expect(assigns(:page).title).to be_empty
+ end
+ end
+ end
+
+ context 'when page is a file' do
+ include WikiHelpers
+
+ let(:id) { upload_file_to_wiki(container, user, file_name) }
+
+ context 'when file is an image' do
+ let(:file_name) { 'dk.png' }
+
+ it 'delivers the image' do
+ subject
+
+ expect(response.headers['Content-Disposition']).to match(/^inline/)
+ expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
+ end
+
+ context 'when file is a svg' do
+ let(:file_name) { 'unsanitized.svg' }
+
+ it 'delivers the image' do
+ subject
+
+ expect(response.headers['Content-Disposition']).to match(/^inline/)
+ expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
+ end
+ end
+
+ it_behaves_like 'project cache control headers' do
+ let(:project) { container }
+ end
+ end
+
+ context 'when file is a pdf' do
+ let(:file_name) { 'git-cheat-sheet.pdf' }
+
+ it 'sets the content type to sets the content response headers' do
+ subject
+
+ expect(response.headers['Content-Disposition']).to match(/^inline/)
+ expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
+ end
+
+ it_behaves_like 'project cache control headers' do
+ let(:project) { container }
+ end
+ end
+ end
+ end
+
+ describe 'POST #preview_markdown' do
+ it 'renders json in a correct format' do
+ post :preview_markdown, params: routing_params.merge(id: 'page/path', text: '*Markdown* text')
+
+ expect(json_response.keys).to match_array(%w(body references))
+ end
+ end
+
+ describe 'GET #edit' do
+ subject { get(:edit, params: routing_params.merge(id: wiki_title)) }
+
+ context 'when page content encoding is invalid' do
+ it 'redirects to show' do
+ allow(controller).to receive(:valid_encoding?).and_return(false)
+
+ subject
+
+ expect(response).to redirect_to_wiki(wiki, wiki.list_pages.first)
+ end
+ end
+
+ context 'when the page has nil content' do
+ let(:page) { create(:wiki_page) }
+
+ it 'redirects to show' do
+ allow(page).to receive(:content).and_return(nil)
+ allow(controller).to receive(:page).and_return(page)
+
+ subject
+
+ expect(response).to redirect_to_wiki(wiki, page)
+ end
+ end
+
+ context 'when page content encoding is valid' do
+ render_views
+
+ it 'shows the edit page' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.body).to include(s_('Wiki|Edit Page'))
+ end
+ end
+ end
+
+ describe 'PATCH #update' do
+ let(:new_title) { 'New title' }
+ let(:new_content) { 'New content' }
+
+ subject do
+ patch(:update,
+ params: routing_params.merge(
+ id: wiki_title,
+ wiki: { title: new_title, content: new_content }
+ ))
+ end
+
+ context 'when page content encoding is invalid' do
+ it 'redirects to show' do
+ allow(controller).to receive(:valid_encoding?).and_return(false)
+
+ subject
+ expect(response).to redirect_to_wiki(wiki, wiki.list_pages.first)
+ end
+ end
+
+ context 'when page content encoding is valid' do
+ render_views
+
+ it 'updates the page' do
+ subject
+
+ wiki_page = wiki.list_pages(load_content: true).first
+
+ expect(wiki_page.title).to eq new_title
+ expect(wiki_page.content).to eq new_content
+ end
+ end
+
+ context 'when user does not have edit permissions' do
+ before do
+ sign_out(:user)
+ end
+
+ it 'renders the empty state' do
+ subject
+
+ expect(response).to render_template('shared/wikis/empty')
+ end
+ end
+ end
+
+ def redirect_to_wiki(wiki, page)
+ redirect_to(controller.wiki_page_path(wiki, page))
+ end
+end
diff --git a/spec/support/shared_examples/features/comments_on_merge_request_files_shared_examples.rb b/spec/support/shared_examples/features/comments_on_merge_request_files_shared_examples.rb
index fb3b17d05ee..e0a032b1a43 100644
--- a/spec/support/shared_examples/features/comments_on_merge_request_files_shared_examples.rb
+++ b/spec/support/shared_examples/features/comments_on_merge_request_files_shared_examples.rb
@@ -6,13 +6,14 @@ RSpec.shared_examples 'comment on merge request file' do
page.within('.js-discussion-note-form') do
fill_in(:note_note, with: 'Line is wrong')
- click_button('Comment')
+ find('.js-comment-button').click
end
wait_for_requests
page.within('.notes_holder') do
expect(page).to have_content('Line is wrong')
+ expect(page).not_to have_content('Comment on lines')
end
visit(merge_request_path(merge_request))
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 81433d124c9..6007798c290 100644
--- a/spec/support/shared_examples/features/discussion_comments_shared_example.rb
+++ b/spec/support/shared_examples/features/discussion_comments_shared_example.rb
@@ -15,7 +15,7 @@ RSpec.shared_examples 'thread comments' do |resource_name|
find("#{form_selector} .note-textarea").send_keys(comment)
- click_button 'Comment'
+ find('.js-comment-button').click
expect(page).to have_content(comment)
@@ -30,6 +30,8 @@ RSpec.shared_examples 'thread comments' do |resource_name|
click_button 'Comment & close issue'
+ wait_for_all_requests
+
expect(page).to have_content(comment)
expect(page).to have_content "@#{user.username} closed"
@@ -144,7 +146,7 @@ RSpec.shared_examples 'thread comments' do |resource_name|
find("#{comments_selector} .js-vue-discussion-reply").click
find("#{comments_selector} .note-textarea").send_keys(text)
- click_button "Comment"
+ find("#{comments_selector} .js-comment-button").click
wait_for_requests
end
diff --git a/spec/support/shared_examples/graphql/container_expiration_policy_shared_examples.rb b/spec/support/shared_examples/graphql/container_expiration_policy_shared_examples.rb
new file mode 100644
index 00000000000..9914de7c847
--- /dev/null
+++ b/spec/support/shared_examples/graphql/container_expiration_policy_shared_examples.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'exposing container expiration policy option' do |model_option|
+ it 'exposes all options' do
+ expect(described_class.values.keys).to contain_exactly(*expected_values)
+ end
+
+ it 'uses all possible options from model' do
+ all_options = ContainerExpirationPolicy.public_send("#{model_option}_options").keys
+ expect(described_class::OPTIONS_MAPPING.keys).to contain_exactly(*all_options)
+ end
+end
diff --git a/spec/support/shared_examples/graphql/label_fields.rb b/spec/support/shared_examples/graphql/label_fields.rb
new file mode 100644
index 00000000000..b1bfb395bc6
--- /dev/null
+++ b/spec/support/shared_examples/graphql/label_fields.rb
@@ -0,0 +1,124 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'a GraphQL type with labels' do
+ it 'has label fields' do
+ expected_fields = %w[label labels]
+
+ expect(described_class).to include_graphql_fields(*expected_fields)
+ end
+
+ describe 'label field' do
+ subject { described_class.fields['label'] }
+
+ it { is_expected.to have_graphql_type(Types::LabelType) }
+ it { is_expected.to have_graphql_arguments(:title) }
+ end
+
+ describe 'labels field' do
+ subject { described_class.fields['labels'] }
+
+ it { is_expected.to have_graphql_type(Types::LabelType.connection_type) }
+ it { is_expected.to have_graphql_arguments(:search_term) }
+ end
+end
+
+RSpec.shared_examples 'querying a GraphQL type with labels' do
+ let_it_be(:current_user) { create(:user) }
+
+ let_it_be(:label_a) { create(label_factory, :described, **label_attrs) }
+ let_it_be(:label_b) { create(label_factory, :described, **label_attrs) }
+ let_it_be(:label_c) { create(label_factory, :described, :scoped, prefix: 'matching', **label_attrs) }
+ let_it_be(:label_d) { create(label_factory, :described, :scoped, prefix: 'matching', **label_attrs) }
+
+ let(:label_title) { label_b.title }
+
+ let(:label_params) { { title: label_title } }
+ let(:labels_params) { nil }
+
+ let(:label_response) { graphql_data.dig(*path_prefix, 'label') }
+ let(:labels_response) { graphql_data.dig(*path_prefix, 'labels', 'nodes') }
+
+ let(:query) do
+ make_query(
+ [
+ query_graphql_field(:label, label_params, all_graphql_fields_for(Label)),
+ query_graphql_field(:labels, labels_params, [
+ query_graphql_field(:nodes, nil, all_graphql_fields_for(Label))
+ ])
+ ]
+ )
+ end
+
+ context 'running a query' do
+ before do
+ run_query(query)
+ end
+
+ context 'minimum required arguments' do
+ it 'returns the label information' do
+ expect(label_response).to include(
+ 'title' => label_title,
+ 'description' => label_b.description
+ )
+ end
+
+ it 'returns the labels information' do
+ expect(labels_response.pluck('title')).to contain_exactly(
+ label_a.title,
+ label_b.title,
+ label_c.title,
+ label_d.title
+ )
+ end
+ end
+
+ context 'with a search param' do
+ let(:labels_params) { { search_term: 'matching' } }
+
+ it 'finds the matching labels' do
+ expect(labels_response.pluck('title')).to contain_exactly(
+ label_c.title,
+ label_d.title
+ )
+ end
+ end
+
+ context 'the label does not exist' do
+ let(:label_title) { 'not-a-label' }
+
+ it 'returns nil' do
+ expect(label_response).to be_nil
+ end
+ end
+ end
+
+ describe 'performance' do
+ def query_for(*labels)
+ selections = labels.map do |label|
+ %Q[#{label.title.gsub(/:+/, '_')}: label(title: "#{label.title}") { description }]
+ end
+
+ make_query(selections)
+ end
+
+ before do
+ run_query(query_for(label_a))
+ end
+
+ it 'batches queries for labels by title' do
+ pending('See: https://gitlab.com/gitlab-org/gitlab/-/issues/217767')
+
+ multi_selection = query_for(label_b, label_c)
+ single_selection = query_for(label_d)
+
+ expect { run_query(multi_selection) }
+ .to issue_same_number_of_queries_as { run_query(single_selection) }
+ end
+ end
+
+ # Run a known good query with the current user
+ def run_query(query)
+ post_graphql(query, current_user: current_user)
+ expect(graphql_errors).not_to be_present
+ end
+end
diff --git a/spec/support/shared_examples/graphql/members_shared_examples.rb b/spec/support/shared_examples/graphql/members_shared_examples.rb
new file mode 100644
index 00000000000..a58e716efd2
--- /dev/null
+++ b/spec/support/shared_examples/graphql/members_shared_examples.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'a working membership object query' do |model_option|
+ let_it_be(:member_source) { member.source }
+ let_it_be(:member_source_type) { member_source.class.to_s.downcase }
+
+ it 'contains edge to expected project' do
+ expect(
+ graphql_data.dig('user', "#{member_source_type}Memberships", 'nodes', 0, member_source_type, 'id')
+ ).to eq(member.send(member_source_type).to_global_id.to_s)
+ end
+
+ it 'contains correct access level' do
+ expect(
+ graphql_data.dig('user', "#{member_source_type}Memberships", 'nodes', 0, 'accessLevel', 'integerValue')
+ ).to eq(30)
+
+ expect(
+ graphql_data.dig('user', "#{member_source_type}Memberships", 'nodes', 0, 'accessLevel', 'stringValue')
+ ).to eq('DEVELOPER')
+ end
+end
diff --git a/spec/support/shared_examples/graphql/resolves_issuable_shared_examples.rb b/spec/support/shared_examples/graphql/resolves_issuable_shared_examples.rb
index b56181371c3..58cd3d21f66 100644
--- a/spec/support/shared_examples/graphql/resolves_issuable_shared_examples.rb
+++ b/spec/support/shared_examples/graphql/resolves_issuable_shared_examples.rb
@@ -22,26 +22,16 @@ RSpec.shared_examples 'resolving an issuable in GraphQL' do |type|
.with(full_path: parent.full_path)
.and_return(resolved_parent)
- expect(resolver_class).to receive(:new)
+ expect(resolver_class.single).to receive(:new)
.with(object: resolved_parent, context: context, field: nil)
.and_call_original
subject
end
- it 'uses correct Resolver to resolve issuable parent' do
- resolver_class = type == :epic ? 'Resolvers::GroupResolver' : 'Resolvers::ProjectResolver'
-
- expect(resolver_class.constantize).to receive(:new)
- .with(object: nil, context: context, field: nil)
- .and_call_original
-
- subject
- end
-
it 'returns nil if issuable is not found' do
result = mutation.resolve_issuable(type: type, parent_path: parent.full_path, iid: "100")
- result = type == :merge_request ? result.sync : result
+ result = result.respond_to?(:sync) ? result.sync : result
expect(result).to be_nil
end
diff --git a/spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb b/spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb
index fb7e24eecf2..2ef71d275a2 100644
--- a/spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb
+++ b/spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb
@@ -23,7 +23,7 @@
# graphql_query_for(
# 'project',
# { 'fullPath' => sort_project.full_path },
-# "issues(#{params}) { #{page_info} edges { node { iid weight } } }"
+# query_graphql_field('issues', params, "#{page_info} edges { node { id } }")
# )
# end
#
@@ -47,11 +47,13 @@ RSpec.shared_examples 'sorted paginated query' do
end
describe do
- let(:params) { "sort: #{sort_param}" }
- let(:start_cursor) { graphql_data_at(*data_path, :pageInfo, :startCursor) }
- let(:end_cursor) { graphql_data_at(*data_path, :pageInfo, :endCursor) }
- let(:sorted_edges) { graphql_data_at(*data_path, :edges) }
- let(:page_info) { "pageInfo { startCursor endCursor }" }
+ let(:sort_argument) { "sort: #{sort_param}" if sort_param.present? }
+ let(:first_argument) { "first: #{first_param}" if first_param.present? }
+ let(:params) { sort_argument }
+ let(:start_cursor) { graphql_data_at(*data_path, :pageInfo, :startCursor) }
+ let(:end_cursor) { graphql_data_at(*data_path, :pageInfo, :endCursor) }
+ let(:sorted_edges) { graphql_data_at(*data_path, :edges) }
+ let(:page_info) { "pageInfo { startCursor endCursor }" }
def pagination_query(params, page_info)
raise('pagination_query(params, page_info) must be defined in the test, see example in comment') unless defined?(super)
@@ -75,12 +77,12 @@ RSpec.shared_examples 'sorted paginated query' do
end
context 'when paginating' do
- let(:params) { "sort: #{sort_param}, first: #{first_param}" }
+ let(:params) { [sort_argument, first_argument].compact.join(',') }
it 'paginates correctly' do
expect(pagination_results_data(sorted_edges)).to eq expected_results.first(first_param)
- cursored_query = pagination_query("sort: #{sort_param}, after: \"#{end_cursor}\"", page_info)
+ cursored_query = pagination_query([sort_argument, "after: \"#{end_cursor}\""].compact.join(','), page_info)
post_graphql(cursored_query, current_user: current_user)
response_data = graphql_dig_at(Gitlab::Json.parse(response.body), :data, *data_path, :edges)
diff --git a/spec/support/shared_examples/integrations/test_examples.rb b/spec/support/shared_examples/integrations/test_examples.rb
new file mode 100644
index 00000000000..eb2e83ce5d1
--- /dev/null
+++ b/spec/support/shared_examples/integrations/test_examples.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'tests for integration with pipeline data' do
+ it 'tests the integration with pipeline data' do
+ create(:ci_empty_pipeline, project: project)
+ allow(Gitlab::DataBuilder::Pipeline).to receive(:build).and_return(sample_data)
+
+ expect(integration).to receive(:test).with(sample_data).and_return(success_result)
+ expect(subject).to eq(success_result)
+ end
+end
diff --git a/spec/support/shared_examples/lib/gitlab/gl_repository_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/gl_repository_shared_examples.rb
new file mode 100644
index 00000000000..97f4341340d
--- /dev/null
+++ b/spec/support/shared_examples/lib/gitlab/gl_repository_shared_examples.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'parsing gl_repository identifier' do
+ subject { described_class.new(identifier) }
+
+ it 'returns correct information' do
+ aggregate_failures do
+ expect(subject.repo_type).to eq(expected_type)
+ expect(subject.fetch_container!).to eq(expected_container)
+ end
+ end
+end
diff --git a/spec/support/shared_examples/lib/gitlab/import/stuck_import_job_workers_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/import/stuck_import_job_workers_shared_examples.rb
new file mode 100644
index 00000000000..06ea540706a
--- /dev/null
+++ b/spec/support/shared_examples/lib/gitlab/import/stuck_import_job_workers_shared_examples.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+shared_examples 'stuck import job detection' do
+ context 'when the job has completed' do
+ context 'when the import status was already updated' do
+ before do
+ allow(Gitlab::SidekiqStatus).to receive(:completed_jids) do
+ import_state.start
+ import_state.finish
+
+ [import_state.jid]
+ end
+ end
+
+ it 'does not mark the import as failed' do
+ worker.perform
+
+ expect(import_state.reload.status).to eq('finished')
+ end
+ end
+
+ context 'when the import status was not updated' do
+ before do
+ allow(Gitlab::SidekiqStatus).to receive(:completed_jids).and_return([import_state.jid])
+ end
+
+ it 'marks the import as failed' do
+ worker.perform
+
+ expect(import_state.reload.status).to eq('failed')
+ end
+ end
+ end
+
+ context 'when the job is still in Sidekiq' do
+ before do
+ allow(Gitlab::SidekiqStatus).to receive(:completed_jids).and_return([])
+ end
+
+ it 'does not mark the import as failed' do
+ expect { worker.perform }.not_to change { import_state.reload.status }
+ end
+ end
+end
diff --git a/spec/support/shared_examples/lib/gitlab/position_formatters_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/position_formatters_shared_examples.rb
index c9300aff3e6..326800e6dc2 100644
--- a/spec/support/shared_examples/lib/gitlab/position_formatters_shared_examples.rb
+++ b/spec/support/shared_examples/lib/gitlab/position_formatters_shared_examples.rb
@@ -32,7 +32,21 @@ RSpec.shared_examples "position formatter" do
subject { formatter.to_h }
- it { is_expected.to eq(formatter_hash) }
+ context 'when file_identifier_hash is disabled' do
+ before do
+ stub_feature_flags(file_identifier_hash: false)
+ end
+
+ it { is_expected.to eq(formatter_hash.except(:file_identifier_hash)) }
+ end
+
+ context 'when file_identifier_hash is enabled' do
+ before do
+ stub_feature_flags(file_identifier_hash: true)
+ end
+
+ it { is_expected.to eq(formatter_hash) }
+ end
end
describe '#==' do
diff --git a/spec/support/shared_examples/lib/gitlab/repo_type_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/repo_type_shared_examples.rb
index 69ae9339f10..4aeae788114 100644
--- a/spec/support/shared_examples/lib/gitlab/repo_type_shared_examples.rb
+++ b/spec/support/shared_examples/lib/gitlab/repo_type_shared_examples.rb
@@ -7,26 +7,6 @@ RSpec.shared_examples 'a repo type' do
it { is_expected.to eq(expected_identifier) }
end
- describe '#fetch_id' do
- it 'finds an id match in the identifier' do
- expect(described_class.fetch_id(expected_identifier)).to eq(expected_id)
- end
-
- it 'does not break on other identifiers' do
- expect(described_class.fetch_id('wiki-noid')).to eq(nil)
- end
- end
-
- describe '#fetch_container!' do
- it 'returns the container' do
- expect(described_class.fetch_container!(expected_identifier)).to eq expected_container
- end
-
- it 'raises an exception if the identifier is invalid' do
- expect { described_class.fetch_container!('project-noid') }.to raise_error ArgumentError
- end
- end
-
describe '#path_suffix' do
subject { described_class.path_suffix }
diff --git a/spec/support/shared_examples/models/application_setting_shared_examples.rb b/spec/support/shared_examples/models/application_setting_shared_examples.rb
index aed85a6630a..01513161d24 100644
--- a/spec/support/shared_examples/models/application_setting_shared_examples.rb
+++ b/spec/support/shared_examples/models/application_setting_shared_examples.rb
@@ -288,11 +288,37 @@ RSpec.shared_examples 'application settings examples' do
end
describe '#pick_repository_storage' do
- it 'uses Array#sample to pick a random storage' do
- array = double('array', sample: 'random')
- expect(setting).to receive(:repository_storages).and_return(array)
+ before do
+ allow(setting).to receive(:repository_storages_weighted).and_return({ 'default' => 20, 'backup' => 80 })
+ end
+
+ it 'chooses repository based on weight' do
+ picked_storages = { 'default' => 0.0, 'backup' => 0.0 }
+ 10_000.times { picked_storages[setting.pick_repository_storage] += 1 }
+
+ expect(((picked_storages['default'] / 10_000) * 100).round.to_i).to be_between(19, 21)
+ expect(((picked_storages['backup'] / 10_000) * 100).round.to_i).to be_between(79, 81)
+ end
+ end
+
+ describe '#normalized_repository_storage_weights' do
+ using RSpec::Parameterized::TableSyntax
- expect(setting.pick_repository_storage).to eq('random')
+ where(:storages, :normalized) do
+ { 'default' => 0, 'backup' => 100 } | { 'default' => 0.0, 'backup' => 1.0 }
+ { 'default' => 100, 'backup' => 100 } | { 'default' => 0.5, 'backup' => 0.5 }
+ { 'default' => 20, 'backup' => 80 } | { 'default' => 0.2, 'backup' => 0.8 }
+ { 'default' => 0, 'backup' => 0 } | { 'default' => 0.0, 'backup' => 0.0 }
+ end
+
+ with_them do
+ before do
+ allow(setting).to receive(:repository_storages_weighted).and_return(storages)
+ end
+
+ it 'normalizes storage weights' do
+ expect(setting.normalized_repository_storage_weights).to eq(normalized)
+ end
end
end
diff --git a/spec/support/shared_examples/models/cluster_application_helm_cert_shared_examples.rb b/spec/support/shared_examples/models/cluster_application_helm_cert_shared_examples.rb
index fa6b0c3afdd..239588d3b2f 100644
--- a/spec/support/shared_examples/models/cluster_application_helm_cert_shared_examples.rb
+++ b/spec/support/shared_examples/models/cluster_application_helm_cert_shared_examples.rb
@@ -54,7 +54,7 @@ RSpec.shared_examples 'cluster application helm specs' do |application_name|
context 'managed_apps_local_tiller feature flag is enabled' do
before do
- stub_feature_flags(managed_apps_local_tiller: true)
+ stub_feature_flags(managed_apps_local_tiller: application.cluster.clusterable)
end
it 'does not include cert files' do
diff --git a/spec/support/shared_examples/models/cluster_application_initial_status_shared_examples.rb b/spec/support/shared_examples/models/cluster_application_initial_status_shared_examples.rb
index 0b21e9a3aa7..7f0c60d4204 100644
--- a/spec/support/shared_examples/models/cluster_application_initial_status_shared_examples.rb
+++ b/spec/support/shared_examples/models/cluster_application_initial_status_shared_examples.rb
@@ -18,7 +18,7 @@ RSpec.shared_examples 'cluster application initial status specs' do
context 'local tiller feature flag is enabled' do
before do
- stub_feature_flags(managed_apps_local_tiller: true)
+ stub_feature_flags(managed_apps_local_tiller: cluster.clusterable)
end
it 'sets a default status' do
diff --git a/spec/support/shared_examples/models/cluster_application_status_shared_examples.rb b/spec/support/shared_examples/models/cluster_application_status_shared_examples.rb
index c2fd04d648b..0efa5e56199 100644
--- a/spec/support/shared_examples/models/cluster_application_status_shared_examples.rb
+++ b/spec/support/shared_examples/models/cluster_application_status_shared_examples.rb
@@ -66,7 +66,7 @@ RSpec.shared_examples 'cluster application status specs' do |application_name|
context 'managed_apps_local_tiller feature flag enabled' do
before do
- stub_feature_flags(managed_apps_local_tiller: true)
+ stub_feature_flags(managed_apps_local_tiller: subject.cluster.clusterable)
end
it 'does not update the helm version' do
@@ -197,12 +197,73 @@ RSpec.shared_examples 'cluster application status specs' do |application_name|
describe '#make_externally_installed' do
subject { create(application_name, :installing) }
+ let(:old_helm) { create(:clusters_applications_helm, version: '1.2.3') }
+
it 'is installed' do
subject.make_externally_installed
expect(subject).to be_installed
end
+ context 'local tiller flag enabled' do
+ before do
+ stub_feature_flags(managed_apps_local_tiller: true)
+ end
+
+ context 'helm record does not exist' do
+ subject { build(application_name, :installing, :no_helm_installed) }
+
+ it 'does not create a helm record' do
+ subject.make_externally_installed!
+
+ subject.cluster.reload
+ expect(subject.cluster.application_helm).to be_nil
+ end
+ end
+
+ context 'helm record exists' do
+ subject { build(application_name, :installing, cluster: old_helm.cluster) }
+
+ it 'does not update helm version' do
+ subject.make_externally_installed!
+
+ subject.cluster.application_helm.reload
+
+ expect(subject.cluster.application_helm.version).to eq('1.2.3')
+ end
+ end
+ end
+
+ context 'local tiller flag disabled' do
+ before do
+ stub_feature_flags(managed_apps_local_tiller: false)
+ end
+
+ context 'helm record does not exist' do
+ subject { build(application_name, :installing, :no_helm_installed) }
+
+ it 'creates a helm record' do
+ subject.make_externally_installed!
+
+ subject.cluster.reload
+ expect(subject.cluster.application_helm).to be_present
+ expect(subject.cluster.application_helm).to be_persisted
+ end
+ end
+
+ context 'helm record exists' do
+ subject { build(application_name, :installing, cluster: old_helm.cluster) }
+
+ it 'does not update helm version' do
+ subject.make_externally_installed!
+
+ subject.cluster.application_helm.reload
+
+ expect(subject.cluster.application_helm.version).to eq('1.2.3')
+ end
+ end
+ end
+
context 'application is updated' do
subject { create(application_name, :updated) }
diff --git a/spec/support/shared_examples/models/concerns/blob_replicator_strategy_shared_examples.rb b/spec/support/shared_examples/models/concerns/blob_replicator_strategy_shared_examples.rb
deleted file mode 100644
index 76339837351..00000000000
--- a/spec/support/shared_examples/models/concerns/blob_replicator_strategy_shared_examples.rb
+++ /dev/null
@@ -1,117 +0,0 @@
-# frozen_string_literal: true
-
-# Include these shared examples in specs of Replicators that include
-# BlobReplicatorStrategy.
-#
-# A let variable called model_record should be defined in the spec. It should be
-# a valid, unpersisted instance of the model class.
-#
-RSpec.shared_examples 'a blob replicator' do
- include EE::GeoHelpers
-
- let_it_be(:primary) { create(:geo_node, :primary) }
- let_it_be(:secondary) { create(:geo_node) }
-
- subject(:replicator) { model_record.replicator }
-
- before do
- stub_current_geo_node(primary)
- end
-
- describe '#handle_after_create_commit' do
- it 'creates a Geo::Event' do
- expect do
- replicator.handle_after_create_commit
- end.to change { ::Geo::Event.count }.by(1)
-
- expect(::Geo::Event.last.attributes).to include(
- "replicable_name" => replicator.replicable_name, "event_name" => "created", "payload" => { "model_record_id" => replicator.model_record.id })
- end
-
- it 'schedules the checksum calculation if needed' do
- expect(Geo::BlobVerificationPrimaryWorker).to receive(:perform_async)
- expect(replicator).to receive(:needs_checksum?).and_return(true)
-
- replicator.handle_after_create_commit
- end
-
- it 'does not schedule the checksum calculation if feature flag is disabled' do
- stub_feature_flags(geo_self_service_framework: false)
-
- expect(Geo::BlobVerificationPrimaryWorker).not_to receive(:perform_async)
- allow(replicator).to receive(:needs_checksum?).and_return(true)
-
- replicator.handle_after_create_commit
- end
- end
-
- describe '#calculate_checksum!' do
- it 'calculates the checksum' do
- model_record.save!
-
- replicator.calculate_checksum!
-
- expect(model_record.reload.verification_checksum).not_to be_nil
- expect(model_record.reload.verified_at).not_to be_nil
- end
-
- it 'saves the error message and increments retry counter' do
- model_record.save!
-
- allow(model_record).to receive(:calculate_checksum!) do
- raise StandardError.new('Failure to calculate checksum')
- end
-
- replicator.calculate_checksum!
-
- expect(model_record.reload.verification_failure).to eq 'Failure to calculate checksum'
- expect(model_record.verification_retry_count).to be 1
- end
- end
-
- describe '#consume_created_event' do
- it 'invokes Geo::BlobDownloadService' do
- service = double(:service)
-
- expect(service).to receive(:execute)
- expect(::Geo::BlobDownloadService).to receive(:new).with(replicator: replicator).and_return(service)
-
- replicator.consume_event_created
- end
- end
-
- describe '#carrierwave_uploader' do
- it 'is implemented' do
- expect do
- replicator.carrierwave_uploader
- end.not_to raise_error
- end
- end
-
- describe '#model' do
- let(:invoke_model) { replicator.class.model }
-
- it 'is implemented' do
- expect do
- invoke_model
- end.not_to raise_error
- end
-
- it 'is a Class' do
- expect(invoke_model).to be_a(Class)
- end
-
- # For convenience (and reliability), instead of asking developers to include shared examples on each model spec as well
- context 'replicable model' do
- it 'defines #replicator' do
- expect(model_record).to respond_to(:replicator)
- end
-
- it 'invokes replicator.handle_after_create_commit on create' do
- expect(replicator).to receive(:handle_after_create_commit)
-
- model_record.save!
- end
- end
- end
-end
diff --git a/spec/support/shared_examples/models/concerns/has_repository_shared_examples.rb b/spec/support/shared_examples/models/concerns/has_repository_shared_examples.rb
index 30c8c7d0fe5..f37ef3533c3 100644
--- a/spec/support/shared_examples/models/concerns/has_repository_shared_examples.rb
+++ b/spec/support/shared_examples/models/concerns/has_repository_shared_examples.rb
@@ -148,18 +148,18 @@ RSpec.shared_examples 'model with repository' do
expect(subject).to eq('picked')
end
- it 'picks from the latest available storage', :request_store do
+ it 'picks from the available storages based on weight', :request_store do
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
Gitlab::CurrentSettings.expire_current_application_settings
Gitlab::CurrentSettings.current_application_settings
settings = ApplicationSetting.last
- settings.repository_storages = %w(picked)
+ settings.repository_storages_weighted = { 'picked' => 100, 'default' => 0 }
settings.save!
- expect(Gitlab::CurrentSettings.repository_storages).to eq(%w(default))
+ expect(Gitlab::CurrentSettings.repository_storages_weighted).to eq({ 'default' => 100 })
expect(subject).to eq('picked')
- expect(Gitlab::CurrentSettings.repository_storages).to eq(%w(picked))
+ expect(Gitlab::CurrentSettings.repository_storages_weighted).to eq({ 'default' => 0, 'picked' => 100 })
end
end
end
diff --git a/spec/support/shared_examples/models/concerns/limitable_shared_examples.rb b/spec/support/shared_examples/models/concerns/limitable_shared_examples.rb
index 4bcea36fd42..d21823661f8 100644
--- a/spec/support/shared_examples/models/concerns/limitable_shared_examples.rb
+++ b/spec/support/shared_examples/models/concerns/limitable_shared_examples.rb
@@ -26,7 +26,7 @@ RSpec.shared_examples 'includes Limitable concern' do
subject.dup.save
end
- it 'cannot create new models exceding the plan limits' do
+ it 'cannot create new models exceeding the plan limits' do
expect { subject.save }.not_to change { described_class.count }
expect(subject.errors[:base]).to contain_exactly("Maximum number of #{subject.class.limit_name.humanize(capitalize: false)} (1) exceeded")
end
diff --git a/spec/support/shared_examples/models/wiki_shared_examples.rb b/spec/support/shared_examples/models/wiki_shared_examples.rb
index 84569e95e11..a881d5f036c 100644
--- a/spec/support/shared_examples/models/wiki_shared_examples.rb
+++ b/spec/support/shared_examples/models/wiki_shared_examples.rb
@@ -32,6 +32,13 @@ RSpec.shared_examples 'wiki model' do
it 'returns the wiki base path' do
expect(subject.wiki_base_path).to eq("#{wiki_container.web_url(only_path: true)}/-/wikis")
end
+
+ it 'includes the relative URL root' do
+ allow(Rails.application.routes).to receive(:default_url_options).and_return(script_name: '/root')
+
+ expect(subject.wiki_base_path).to start_with('/root/')
+ expect(subject.wiki_base_path).not_to start_with('/root/root')
+ end
end
describe '#wiki' do
diff --git a/spec/support/shared_examples/path_extraction_shared_examples.rb b/spec/support/shared_examples/path_extraction_shared_examples.rb
new file mode 100644
index 00000000000..19c6f2404e5
--- /dev/null
+++ b/spec/support/shared_examples/path_extraction_shared_examples.rb
@@ -0,0 +1,118 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'assigns ref vars' do
+ it 'assigns the repository var' do
+ assign_ref_vars
+
+ expect(@repo).to eq container.repository
+ end
+
+ context 'ref contains %20' do
+ let(:ref) { 'foo%20bar' }
+
+ it 'is not converted to a space in @id' do
+ container.repository.add_branch(owner, 'foo%20bar', 'master')
+
+ assign_ref_vars
+
+ expect(@id).to start_with('foo%20bar/')
+ end
+ end
+
+ context 'ref contains trailing space' do
+ let(:ref) { 'master ' }
+
+ it 'strips surrounding space' do
+ assign_ref_vars
+
+ expect(@ref).to eq('master')
+ end
+ end
+
+ context 'ref contains leading space' do
+ let(:ref) { ' master ' }
+
+ it 'strips surrounding space' do
+ assign_ref_vars
+
+ expect(@ref).to eq('master')
+ end
+ end
+
+ context 'path contains space' do
+ let(:params) { { path: 'with space', ref: '38008cb17ce1466d8fec2dfa6f6ab8dcfe5cf49e' } }
+
+ it 'is not converted to %20 in @path' do
+ assign_ref_vars
+
+ expect(@path).to eq(params[:path])
+ end
+ end
+
+ context 'subclass overrides get_id' do
+ it 'uses ref returned by get_id' do
+ allow_next_instance_of(self.class) do |instance|
+ allow(instance).to receive(:get_id) { '38008cb17ce1466d8fec2dfa6f6ab8dcfe5cf49e' }
+ end
+
+ assign_ref_vars
+
+ expect(@id).to eq(get_id)
+ end
+ end
+end
+
+RSpec.shared_examples 'extracts refs' do
+ describe '#extract_ref' do
+ it 'returns an empty pair when no repository_container is set' do
+ allow_any_instance_of(described_class).to receive(:repository_container).and_return(nil)
+ expect(extract_ref('master/CHANGELOG')).to eq(['', ''])
+ end
+
+ context 'without a path' do
+ it 'extracts a valid branch' do
+ expect(extract_ref('master')).to eq(['master', ''])
+ end
+
+ it 'extracts a valid tag' do
+ expect(extract_ref('v2.0.0')).to eq(['v2.0.0', ''])
+ end
+
+ it 'extracts a valid commit ref without a path' do
+ expect(extract_ref('f4b14494ef6abf3d144c28e4af0c20143383e062')).to eq(
+ ['f4b14494ef6abf3d144c28e4af0c20143383e062', '']
+ )
+ end
+
+ it 'falls back to a primitive split for an invalid ref' do
+ expect(extract_ref('stable')).to eq(['stable', ''])
+ end
+
+ it 'extracts the longest matching ref' do
+ expect(extract_ref('release/app/v1.0.0/README.md')).to eq(
+ ['release/app/v1.0.0', 'README.md'])
+ end
+ end
+
+ context 'with a path' do
+ it 'extracts a valid branch' do
+ expect(extract_ref('foo/bar/baz/CHANGELOG')).to eq(
+ ['foo/bar/baz', 'CHANGELOG'])
+ end
+
+ it 'extracts a valid tag' do
+ expect(extract_ref('v2.0.0/CHANGELOG')).to eq(['v2.0.0', 'CHANGELOG'])
+ end
+
+ it 'extracts a valid commit SHA' do
+ expect(extract_ref('f4b14494ef6abf3d144c28e4af0c20143383e062/CHANGELOG')).to eq(
+ %w(f4b14494ef6abf3d144c28e4af0c20143383e062 CHANGELOG)
+ )
+ end
+
+ it 'falls back to a primitive split for an invalid ref' do
+ expect(extract_ref('stable/CHANGELOG')).to eq(%w(stable CHANGELOG))
+ end
+ end
+ end
+end
diff --git a/spec/support/shared_examples/quick_actions/issuable/time_tracking_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issuable/time_tracking_quick_action_shared_examples.rb
index 37a504cd56a..37ee2548dfe 100644
--- a/spec/support/shared_examples/quick_actions/issuable/time_tracking_quick_action_shared_examples.rb
+++ b/spec/support/shared_examples/quick_actions/issuable/time_tracking_quick_action_shared_examples.rb
@@ -86,7 +86,7 @@ RSpec.shared_examples 'issuable time tracker' do |issuable_type|
page.within '.time-tracking-component-wrap' do
find('.help-button').click
- expect(find_link('Learn more')[:href]).to have_content('/help/workflow/time_tracking.md')
+ expect(find_link('Learn more')[:href]).to have_content('/help/user/project/time_tracking.md')
end
end
end
diff --git a/spec/support/shared_examples/requests/api/container_repositories_shared_examples.rb b/spec/support/shared_examples/requests/api/container_repositories_shared_examples.rb
index 0f277c11913..3e058838773 100644
--- a/spec/support/shared_examples/requests/api/container_repositories_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/container_repositories_shared_examples.rb
@@ -54,6 +54,29 @@ RSpec.shared_examples 'returns repositories for allowed users' do |user_type, sc
expect(response).to match_response_schema('registry/repositories')
end
end
+
+ context 'with tags_count param' do
+ let(:url) { "/#{scope}s/#{object.id}/registry/repositories?tags_count=true" }
+
+ before do
+ stub_container_registry_tags(repository: root_repository.path, tags: %w(rootA latest), with_manifest: true)
+ stub_container_registry_tags(repository: test_repository.path, tags: %w(rootA latest), with_manifest: true)
+ end
+
+ it 'returns a list of repositories and their tags_count' do
+ subject
+
+ expect(response.body).to include('tags_count')
+ expect(json_response[0]['tags_count']).to eq(2)
+ end
+
+ it 'returns a matching schema' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to match_response_schema('registry/repositories')
+ end
+ end
end
end
diff --git a/spec/support/shared_examples/requests/api/diff_discussions_shared_examples.rb b/spec/support/shared_examples/requests/api/diff_discussions_shared_examples.rb
index 3d25b9076ad..518c5b8dc28 100644
--- a/spec/support/shared_examples/requests/api/diff_discussions_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/diff_discussions_shared_examples.rb
@@ -30,7 +30,9 @@ RSpec.shared_examples 'diff discussions API' do |parent_type, noteable_type, id_
it "creates a new diff note" do
line_range = {
"start_line_code" => Gitlab::Git.diff_line_code(diff_note.position.file_path, 1, 1),
- "end_line_code" => Gitlab::Git.diff_line_code(diff_note.position.file_path, 2, 2)
+ "end_line_code" => Gitlab::Git.diff_line_code(diff_note.position.file_path, 2, 2),
+ "start_line_type" => diff_note.position.type,
+ "end_line_type" => diff_note.position.type
}
position = diff_note.position.to_h.merge({ line_range: line_range })
diff --git a/spec/support/shared_examples/requests/api/graphql/group_and_project_boards_query_shared_examples.rb b/spec/support/shared_examples/requests/api/graphql/group_and_project_boards_query_shared_examples.rb
index feb3ba46353..f26af6cb766 100644
--- a/spec/support/shared_examples/requests/api/graphql/group_and_project_boards_query_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/graphql/group_and_project_boards_query_shared_examples.rb
@@ -45,44 +45,37 @@ RSpec.shared_examples 'group and project boards query' do
end
describe 'sorting and pagination' do
+ let(:data_path) { [board_parent_type, :boards] }
+
+ def pagination_query(params, page_info)
+ graphql_query_for(
+ board_parent_type,
+ { 'fullPath' => board_parent.full_path },
+ query_graphql_field('boards', params, "#{page_info} edges { node { id } }")
+ )
+ end
+
+ def pagination_results_data(data)
+ data.map { |board| board.dig('node', 'id') }
+ end
+
context 'when using default sorting' do
let!(:board_B) { create(:board, resource_parent: board_parent, name: 'B') }
let!(:board_C) { create(:board, resource_parent: board_parent, name: 'C') }
let!(:board_a) { create(:board, resource_parent: board_parent, name: 'a') }
let!(:board_A) { create(:board, resource_parent: board_parent, name: 'A') }
-
- before do
- post_graphql(query, current_user: current_user)
- end
-
- it_behaves_like 'a working graphql query'
+ let(:boards) { [board_a, board_A, board_B, board_C] }
context 'when ascending' do
- let(:boards) { [board_a, board_A, board_B, board_C] }
- let(:expected_boards) do
- if board_parent.multiple_issue_boards_available?
- boards
- else
- [boards.first]
- end
- end
-
- it 'sorts boards' do
- expect(grab_names).to eq expected_boards.map(&:name)
- end
-
- context 'when paginating' do
- let(:params) { 'first: 2' }
-
- it 'sorts boards' do
- expect(grab_names).to eq expected_boards.first(2).map(&:name)
-
- cursored_query = query("after: \"#{end_cursor}\"")
- post_graphql(cursored_query, current_user: current_user)
-
- response_data = Gitlab::Json.parse(response.body)['data'][board_parent_type]['boards']['edges']
-
- expect(grab_names(response_data)).to eq expected_boards.drop(2).first(2).map(&:name)
+ it_behaves_like 'sorted paginated query' do
+ let(:sort_param) { }
+ let(:first_param) { 2 }
+ let(:expected_results) do
+ if board_parent.multiple_issue_boards_available?
+ boards.map { |board| board.to_global_id.to_s }
+ else
+ [boards.first.to_global_id.to_s]
+ end
end
end
end
diff --git a/spec/support/shared_examples/requests/api/issuable_update_shared_examples.rb b/spec/support/shared_examples/requests/api/issuable_update_shared_examples.rb
new file mode 100644
index 00000000000..ded381fd402
--- /dev/null
+++ b/spec/support/shared_examples/requests/api/issuable_update_shared_examples.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'issuable update endpoint' do
+ let(:area) { entity.class.name.underscore.pluralize }
+
+ describe 'PUT /projects/:id/issues/:issue_id' do
+ let(:url) { "/projects/#{project.id}/#{area}/#{entity.iid}" }
+
+ it 'clears labels when labels param is nil' do
+ put api(url, user), params: { labels: 'label1' }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['labels']).to contain_exactly('label1')
+
+ put api(url, user), params: { labels: nil }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ json_response = Gitlab::Json.parse(response.body)
+ expect(json_response['labels']).to be_empty
+ end
+
+ it 'updates the issuable with labels param as array' do
+ stub_const("Gitlab::QueryLimiting::Transaction::THRESHOLD", 110)
+
+ params = { labels: ['label1', 'label2', 'foo, bar', '&,?'] }
+
+ put api(url, user), params: params
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['labels']).to include 'label1'
+ expect(json_response['labels']).to include 'label2'
+ expect(json_response['labels']).to include 'foo'
+ expect(json_response['labels']).to include 'bar'
+ expect(json_response['labels']).to include '&'
+ expect(json_response['labels']).to include '?'
+ end
+ end
+end
diff --git a/spec/support/shared_examples/requests/api/resource_label_events_api_shared_examples.rb b/spec/support/shared_examples/requests/api/resource_label_events_api_shared_examples.rb
index f49f944f38d..675b6c5cef6 100644
--- a/spec/support/shared_examples/requests/api/resource_label_events_api_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/resource_label_events_api_shared_examples.rb
@@ -93,6 +93,20 @@ RSpec.shared_examples 'resource_label_events API' do |parent_type, eventable_typ
end
end
+ describe 'pagination' do
+ let!(:event1) { create_event(label) }
+ let!(:event2) { create_event(label) }
+
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/220192
+ it "returns the second page" do
+ get api("/#{parent_type}/#{parent.id}/#{eventable_type}/#{eventable[id_name]}/resource_label_events?page=2&per_page=1", user)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response.count).to eq(1)
+ expect(json_response.first['id']).to eq(event2.id)
+ end
+ end
+
def create_event(label)
create(:resource_label_event, eventable.class.name.underscore => eventable, label: label)
end
diff --git a/spec/support/shared_examples/requests/api/resource_milestone_events_api_shared_examples.rb b/spec/support/shared_examples/requests/api/resource_milestone_events_api_shared_examples.rb
new file mode 100644
index 00000000000..bca51dab353
--- /dev/null
+++ b/spec/support/shared_examples/requests/api/resource_milestone_events_api_shared_examples.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'resource_milestone_events API' do |parent_type, eventable_type, id_name|
+ describe "GET /#{parent_type}/:id/#{eventable_type}/:noteable_id/resource_milestone_events" do
+ let!(:event) { create_event(milestone) }
+
+ it "returns an array of resource milestone events" do
+ url = "/#{parent_type}/#{parent.id}/#{eventable_type}/#{eventable[id_name]}/resource_milestone_events"
+ get api(url, user)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+ expect(json_response.first['id']).to eq(event.id)
+ expect(json_response.first['milestone']['id']).to eq(event.milestone.id)
+ expect(json_response.first['action']).to eq(event.action)
+ end
+
+ it "returns a 404 error when eventable id not found" do
+ get api("/#{parent_type}/#{parent.id}/#{eventable_type}/#{non_existing_record_id}/resource_milestone_events", user)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+
+ it "returns 404 when not authorized" do
+ parent.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
+ private_user = create(:user)
+
+ get api("/#{parent_type}/#{parent.id}/#{eventable_type}/#{eventable[id_name]}/resource_milestone_events", private_user)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ describe "GET /#{parent_type}/:id/#{eventable_type}/:noteable_id/resource_milestone_events/:event_id" do
+ let!(:event) { create_event(milestone) }
+
+ it "returns a resource milestone event by id" do
+ get api("/#{parent_type}/#{parent.id}/#{eventable_type}/#{eventable[id_name]}/resource_milestone_events/#{event.id}", user)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['id']).to eq(event.id)
+ expect(json_response['milestone']['id']).to eq(event.milestone.id)
+ expect(json_response['action']).to eq(event.action)
+ end
+
+ it "returns 404 when not authorized" do
+ parent.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
+ private_user = create(:user)
+
+ get api("/#{parent_type}/#{parent.id}/#{eventable_type}/#{eventable[id_name]}/resource_milestone_events/#{event.id}", private_user)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+
+ it "returns a 404 error if resource milestone event not found" do
+ get api("/#{parent_type}/#{parent.id}/#{eventable_type}/#{eventable[id_name]}/resource_milestone_events/#{non_existing_record_id}", user)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ def create_event(milestone, action: :add)
+ create(:resource_milestone_event, eventable.class.name.underscore => eventable, milestone: milestone, action: action)
+ end
+end
diff --git a/spec/support/shared_examples/serializers/diff_file_entity_shared_examples.rb b/spec/support/shared_examples/serializers/diff_file_entity_shared_examples.rb
index db5c4b45b70..1ef08de31a9 100644
--- a/spec/support/shared_examples/serializers/diff_file_entity_shared_examples.rb
+++ b/spec/support/shared_examples/serializers/diff_file_entity_shared_examples.rb
@@ -8,7 +8,7 @@ RSpec.shared_examples 'diff file base entity' do
:file_hash, :file_path, :old_path, :new_path,
:viewer, :diff_refs, :stored_externally,
:external_storage, :renamed_file, :deleted_file,
- :a_mode, :b_mode, :new_file)
+ :a_mode, :b_mode, :new_file, :file_identifier_hash)
end
# Converted diff files from GitHub import does not contain blob file
diff --git a/spec/support/shared_examples/serializers/import/import_entity_shared_examples.rb b/spec/support/shared_examples/serializers/import/import_entity_shared_examples.rb
new file mode 100644
index 00000000000..6422c4beb1d
--- /dev/null
+++ b/spec/support/shared_examples/serializers/import/import_entity_shared_examples.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'exposes required fields for import entity' do
+ describe 'exposes required fields' do
+ it 'correctly exposes id' do
+ expect(subject[:id]).to eql(expected_values[:id])
+ end
+
+ it 'correctly exposes full name' do
+ expect(subject[:full_name]).to eql(expected_values[:full_name])
+ end
+
+ it 'correctly exposes sanitized name' do
+ expect(subject[:sanitized_name]).to eql(expected_values[:sanitized_name])
+ end
+
+ it 'correctly exposes provider link' do
+ expect(subject[:provider_link]).to eql(expected_values[:provider_link])
+ end
+ end
+end
diff --git a/spec/support/shared_examples/services/container_expiration_policy_shared_examples.rb b/spec/support/shared_examples/services/container_expiration_policy_shared_examples.rb
new file mode 100644
index 00000000000..28bf46a57d5
--- /dev/null
+++ b/spec/support/shared_examples/services/container_expiration_policy_shared_examples.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'updating the container expiration policy attributes' do |mode:, from: {}, to:|
+ if mode == :create
+ it 'creates a new container expiration policy' do
+ expect { subject }
+ .to change { project.reload.container_expiration_policy.present? }.from(false).to(true)
+ .and change { ContainerExpirationPolicy.count }.by(1)
+ end
+ else
+ it_behaves_like 'not creating the container expiration policy'
+ end
+
+ it 'updates the container expiration policy' do
+ if from.empty?
+ subject
+
+ expect(container_expiration_policy.reload.cadence).to eq(to[:cadence])
+ expect(container_expiration_policy.keep_n).to eq(to[:keep_n])
+ expect(container_expiration_policy.older_than).to eq(to[:older_than])
+ else
+ expect { subject }
+ .to change { container_expiration_policy.reload.cadence }.from(from[:cadence]).to(to[:cadence])
+ .and change { container_expiration_policy.reload.keep_n }.from(from[:keep_n]).to(to[:keep_n])
+ .and change { container_expiration_policy.reload.older_than }.from(from[:older_than]).to(to[:older_than])
+ end
+ end
+end
+
+RSpec.shared_examples 'not creating the container expiration policy' do
+ it "doesn't create the container expiration policy" do
+ expect { subject }.not_to change { ContainerExpirationPolicy.count }
+ end
+end
+
+RSpec.shared_examples 'creating the container expiration policy' do
+ it_behaves_like 'updating the container expiration policy attributes', mode: :create, to: { cadence: '3month', keep_n: 100, older_than: '14d' }
+
+ it_behaves_like 'returning a success'
+end
diff --git a/spec/support/shared_examples/services/wiki_pages/create_service_shared_examples.rb b/spec/support/shared_examples/services/wiki_pages/create_service_shared_examples.rb
index 71bdd46572f..efcb83a34af 100644
--- a/spec/support/shared_examples/services/wiki_pages/create_service_shared_examples.rb
+++ b/spec/support/shared_examples/services/wiki_pages/create_service_shared_examples.rb
@@ -45,7 +45,7 @@ RSpec.shared_examples 'WikiPages::CreateService#execute' do |container_type|
expect { service.execute }.to change { Event.count }.by 1
expect(Event.recent.first).to have_attributes(
- action: Event::CREATED,
+ action: 'created',
target: have_attributes(canonical_slug: page_title)
)
end
diff --git a/spec/support/shared_examples/services/wiki_pages/destroy_service_shared_examples.rb b/spec/support/shared_examples/services/wiki_pages/destroy_service_shared_examples.rb
index 62541eb3da9..1231c012c31 100644
--- a/spec/support/shared_examples/services/wiki_pages/destroy_service_shared_examples.rb
+++ b/spec/support/shared_examples/services/wiki_pages/destroy_service_shared_examples.rb
@@ -27,7 +27,7 @@ RSpec.shared_examples 'WikiPages::DestroyService#execute' do |container_type|
expect { service.execute(page) }.to change { Event.count }.by 1
expect(Event.recent.first).to have_attributes(
- action: Event::DESTROYED,
+ action: 'destroyed',
target: have_attributes(canonical_slug: page.slug)
)
end
diff --git a/spec/support/shared_examples/services/wiki_pages/update_service_shared_examples.rb b/spec/support/shared_examples/services/wiki_pages/update_service_shared_examples.rb
index 0dfc99d043b..77354fec069 100644
--- a/spec/support/shared_examples/services/wiki_pages/update_service_shared_examples.rb
+++ b/spec/support/shared_examples/services/wiki_pages/update_service_shared_examples.rb
@@ -48,7 +48,7 @@ RSpec.shared_examples 'WikiPages::UpdateService#execute' do |container_type|
expect { service.execute(page) }.to change { Event.count }.by 1
expect(Event.recent.first).to have_attributes(
- action: Event::UPDATED,
+ action: 'updated',
wiki_page: page,
target_title: page.title
)
diff --git a/spec/support/shared_examples/uncached_response_shared_examples.rb b/spec/support/shared_examples/uncached_response_shared_examples.rb
new file mode 100644
index 00000000000..3997017ff35
--- /dev/null
+++ b/spec/support/shared_examples/uncached_response_shared_examples.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+#
+# Pairs with lib/gitlab/no_cache_headers.rb
+#
+
+RSpec.shared_examples 'uncached response' do
+ it 'defines an uncached header response' do
+ expect(response.headers["Cache-Control"]).to include("no-store", "no-cache")
+ expect(response.headers["Pragma"]).to eq("no-cache")
+ expect(response.headers["Expires"]).to eq("Fri, 01 Jan 1990 00:00:00 GMT")
+ end
+end
diff --git a/spec/support_specs/helpers/graphql_helpers_spec.rb b/spec/support_specs/helpers/graphql_helpers_spec.rb
new file mode 100644
index 00000000000..bfc71f519cf
--- /dev/null
+++ b/spec/support_specs/helpers/graphql_helpers_spec.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GraphqlHelpers do
+ include GraphqlHelpers
+
+ describe '.graphql_mutation' do
+ shared_examples 'correct mutation definition' do
+ it 'returns correct mutation definition' do
+ query = <<~MUTATION
+ mutation($updateAlertStatusInput: UpdateAlertStatusInput!) {
+ updateAlertStatus(input: $updateAlertStatusInput) {
+ clientMutationId
+ }
+ }
+ MUTATION
+ variables = %q({"updateAlertStatusInput":{"projectPath":"test/project"}})
+
+ is_expected.to eq(GraphqlHelpers::MutationDefinition.new(query, variables))
+ end
+ end
+
+ context 'when fields argument is passed' do
+ subject do
+ graphql_mutation(:update_alert_status, { project_path: 'test/project' }, 'clientMutationId')
+ end
+
+ it_behaves_like 'correct mutation definition'
+ end
+
+ context 'when block is passed' do
+ subject do
+ graphql_mutation(:update_alert_status, { project_path: 'test/project' }) do
+ 'clientMutationId'
+ end
+ end
+
+ it_behaves_like 'correct mutation definition'
+ end
+
+ context 'when both fields and a block are passed' do
+ subject do
+ graphql_mutation(:mutation_name, { variable_name: 'variable/value' }, 'fieldName') do
+ 'fieldName'
+ end
+ end
+
+ it 'raises an ArgumentError' do
+ expect { subject }.to raise_error(
+ ArgumentError,
+ 'Please pass either `fields` parameter or a block to `#graphql_mutation`, but not both.'
+ )
+ end
+ end
+ end
+end
diff --git a/spec/support_specs/helpers/stub_feature_flags_spec.rb b/spec/support_specs/helpers/stub_feature_flags_spec.rb
index b6e230075f2..e90a7f68a90 100644
--- a/spec/support_specs/helpers/stub_feature_flags_spec.rb
+++ b/spec/support_specs/helpers/stub_feature_flags_spec.rb
@@ -3,16 +3,7 @@
require 'spec_helper'
describe StubFeatureFlags do
- before do
- # reset stub introduced by `stub_feature_flags`
- allow(Feature).to receive(:enabled?).and_call_original
- end
-
- context 'if not stubbed' do
- it 'features are disabled by default' do
- expect(Feature.enabled?(:test_feature)).to eq(false)
- end
- end
+ let(:feature_name) { :test_feature }
describe '#stub_feature_flags' do
using RSpec::Parameterized::TableSyntax
@@ -30,7 +21,7 @@ describe StubFeatureFlags do
with_them do
before do
- stub_feature_flags(feature_name => feature_actors)
+ stub_feature_flags(feature_name => actor(feature_actors))
end
it { expect(Feature.enabled?(feature_name)).to eq(expected_result) }
@@ -62,15 +53,15 @@ describe StubFeatureFlags do
with_them do
before do
- stub_feature_flags(feature_name => feature_actors)
+ stub_feature_flags(feature_name => actor(feature_actors))
end
- it { expect(Feature.enabled?(feature_name, tested_actor)).to eq(expected_result) }
- it { expect(Feature.disabled?(feature_name, tested_actor)).not_to eq(expected_result) }
+ it { expect(Feature.enabled?(feature_name, actor(tested_actor))).to eq(expected_result) }
+ it { expect(Feature.disabled?(feature_name, actor(tested_actor))).not_to eq(expected_result) }
context 'default_enabled does not impact feature state' do
- it { expect(Feature.enabled?(feature_name, tested_actor, default_enabled: true)).to eq(expected_result) }
- it { expect(Feature.disabled?(feature_name, tested_actor, default_enabled: true)).not_to eq(expected_result) }
+ it { expect(Feature.enabled?(feature_name, actor(tested_actor), default_enabled: true)).to eq(expected_result) }
+ it { expect(Feature.disabled?(feature_name, actor(tested_actor), default_enabled: true)).not_to eq(expected_result) }
end
end
end
@@ -82,7 +73,7 @@ describe StubFeatureFlags do
end
with_them do
- subject { stub_feature_flags(feature_name => feature_actors) }
+ subject { stub_feature_flags(feature_name => actor(feature_actors)) }
it { expect { subject }.to raise_error(ArgumentError, /accepts only/) }
end
@@ -90,11 +81,11 @@ describe StubFeatureFlags do
context 'does not raise error' do
where(:feature_actors) do
- [true, false, nil, :symbol, double, User.new]
+ [true, false, nil, stub_feature_flag_gate(100), User.new]
end
with_them do
- subject { stub_feature_flags(feature_name => feature_actors) }
+ subject { stub_feature_flags(feature_name => actor(feature_actors)) }
it { expect { subject }.not_to raise_error }
end
@@ -103,28 +94,39 @@ describe StubFeatureFlags do
it 'subsquent run changes state' do
# enable FF only on A
- stub_feature_flags(test_feature: %i[A])
- expect(Feature.enabled?(:test_feature)).to eq(false)
- expect(Feature.enabled?(:test_feature, :A)).to eq(true)
- expect(Feature.enabled?(:test_feature, :B)).to eq(false)
+ stub_feature_flags({ feature_name => actor(%i[A]) })
+ expect(Feature.enabled?(feature_name)).to eq(false)
+ expect(Feature.enabled?(feature_name, actor(:A))).to eq(true)
+ expect(Feature.enabled?(feature_name, actor(:B))).to eq(false)
# enable FF only on B
- stub_feature_flags(test_feature: %i[B])
- expect(Feature.enabled?(:test_feature)).to eq(false)
- expect(Feature.enabled?(:test_feature, :A)).to eq(false)
- expect(Feature.enabled?(:test_feature, :B)).to eq(true)
+ stub_feature_flags({ feature_name => actor(%i[B]) })
+ expect(Feature.enabled?(feature_name)).to eq(false)
+ expect(Feature.enabled?(feature_name, actor(:A))).to eq(false)
+ expect(Feature.enabled?(feature_name, actor(:B))).to eq(true)
# enable FF on all
- stub_feature_flags(test_feature: true)
- expect(Feature.enabled?(:test_feature)).to eq(true)
- expect(Feature.enabled?(:test_feature, :A)).to eq(true)
- expect(Feature.enabled?(:test_feature, :B)).to eq(true)
+ stub_feature_flags({ feature_name => true })
+ expect(Feature.enabled?(feature_name)).to eq(true)
+ expect(Feature.enabled?(feature_name, actor(:A))).to eq(true)
+ expect(Feature.enabled?(feature_name, actor(:B))).to eq(true)
# disable FF on all
- stub_feature_flags(test_feature: false)
- expect(Feature.enabled?(:test_feature)).to eq(false)
- expect(Feature.enabled?(:test_feature, :A)).to eq(false)
- expect(Feature.enabled?(:test_feature, :B)).to eq(false)
+ stub_feature_flags({ feature_name => false })
+ expect(Feature.enabled?(feature_name)).to eq(false)
+ expect(Feature.enabled?(feature_name, actor(:A))).to eq(false)
+ expect(Feature.enabled?(feature_name, actor(:B))).to eq(false)
+ end
+ end
+
+ def actor(actor)
+ case actor
+ when Array
+ actor.map(&method(:actor))
+ when Symbol # convert to flipper compatible object
+ stub_feature_flag_gate(actor)
+ else
+ actor
end
end
end
diff --git a/spec/support_specs/matchers/exceed_query_limit_helpers_spec.rb b/spec/support_specs/matchers/exceed_query_limit_helpers_spec.rb
index 3b15d804d7c..4a711b43d9a 100644
--- a/spec/support_specs/matchers/exceed_query_limit_helpers_spec.rb
+++ b/spec/support_specs/matchers/exceed_query_limit_helpers_spec.rb
@@ -3,16 +3,21 @@
require 'spec_helper'
describe ExceedQueryLimitHelpers do
- class TestQueries < ActiveRecord::Base
- self.table_name = 'schema_migrations'
- end
+ before do
+ stub_const('TestQueries', Class.new(ActiveRecord::Base))
+ stub_const('TestMatcher', Class.new)
+
+ TestQueries.class_eval do
+ self.table_name = 'schema_migrations'
+ end
- class TestMatcher
- include ExceedQueryLimitHelpers
+ TestMatcher.class_eval do
+ include ExceedQueryLimitHelpers
- def expected
- ActiveRecord::QueryRecorder.new do
- 2.times { TestQueries.count }
+ def expected
+ ActiveRecord::QueryRecorder.new do
+ 2.times { TestQueries.count }
+ end
end
end
end
diff --git a/spec/tasks/gitlab/container_registry_rake_spec.rb b/spec/tasks/gitlab/container_registry_rake_spec.rb
new file mode 100644
index 00000000000..181d5c8b7c8
--- /dev/null
+++ b/spec/tasks/gitlab/container_registry_rake_spec.rb
@@ -0,0 +1,123 @@
+# frozen_string_literal: true
+
+require 'rake_helper'
+
+describe 'gitlab:container_registry namespace rake tasks' do
+ let_it_be(:application_settings) { Gitlab::CurrentSettings }
+ let_it_be(:api_url) { 'http://registry.gitlab' }
+
+ before :all do
+ Rake.application.rake_require 'tasks/gitlab/container_registry'
+ end
+
+ describe 'configure' do
+ before do
+ stub_access_token
+ stub_container_registry_config(enabled: true, api_url: api_url)
+ end
+
+ subject { run_rake_task('gitlab:container_registry:configure') }
+
+ shared_examples 'invalid config' do
+ it 'does not update the application settings' do
+ expect(application_settings).not_to receive(:update!)
+
+ subject
+ end
+
+ it 'does not raise an error' do
+ expect { subject }.not_to raise_error
+ end
+
+ it 'prints a warning message' do
+ expect { subject }.to output(/Registry is not enabled or registry api url is not present./).to_stdout
+ end
+ end
+
+ context 'when container registry is disabled' do
+ before do
+ stub_container_registry_config(enabled: false)
+ end
+
+ it_behaves_like 'invalid config'
+ end
+
+ context 'when container registry api_url is blank' do
+ before do
+ stub_container_registry_config(api_url: '')
+ end
+
+ it_behaves_like 'invalid config'
+ end
+
+ context 'when creating a registry client instance' do
+ let(:token) { 'foo' }
+ let(:client) { ContainerRegistry::Client.new(api_url, token: token) }
+
+ before do
+ stub_registry_info({})
+ end
+
+ it 'uses a token with no access permissions' do
+ expect(Auth::ContainerRegistryAuthenticationService)
+ .to receive(:access_token).with([], []).and_return(token)
+ expect(ContainerRegistry::Client)
+ .to receive(:new).with(api_url, token: token).and_return(client)
+
+ run_rake_task('gitlab:container_registry:configure')
+ end
+ end
+
+ context 'when unabled to detect the container registry type' do
+ it 'fails and raises an error message' do
+ stub_registry_info({})
+
+ run_rake_task('gitlab:container_registry:configure')
+
+ application_settings.reload
+ expect(application_settings.container_registry_vendor).to be_blank
+ expect(application_settings.container_registry_version).to be_blank
+ expect(application_settings.container_registry_features).to eq([])
+ end
+ end
+
+ context 'when able to detect the container registry type' do
+ context 'when using the GitLab container registry' do
+ it 'updates application settings accordingly' do
+ stub_registry_info(vendor: 'gitlab', version: '2.9.1-gitlab', features: %w[a,b,c])
+
+ run_rake_task('gitlab:container_registry:configure')
+
+ application_settings.reload
+ expect(application_settings.container_registry_vendor).to eq('gitlab')
+ expect(application_settings.container_registry_version).to eq('2.9.1-gitlab')
+ expect(application_settings.container_registry_features).to eq(%w[a,b,c])
+ end
+ end
+
+ context 'when using a third-party container registry' do
+ it 'updates application settings accordingly' do
+ stub_registry_info(vendor: 'other', version: nil, features: nil)
+
+ run_rake_task('gitlab:container_registry:configure')
+
+ application_settings.reload
+ expect(application_settings.container_registry_vendor).to eq('other')
+ expect(application_settings.container_registry_version).to be_blank
+ expect(application_settings.container_registry_features).to eq([])
+ end
+ end
+ end
+ end
+
+ def stub_access_token
+ allow(Auth::ContainerRegistryAuthenticationService)
+ .to receive(:access_token).with([], []).and_return('foo')
+ end
+
+ def stub_registry_info(output)
+ allow_next_instance_of(ContainerRegistry::Client) do |client|
+ allow(client).to receive(:registry_info).and_return(output)
+ end
+ end
+end
diff --git a/spec/tasks/gitlab/db_rake_spec.rb b/spec/tasks/gitlab/db_rake_spec.rb
index 1d2341bb46f..c3da5af5439 100644
--- a/spec/tasks/gitlab/db_rake_spec.rb
+++ b/spec/tasks/gitlab/db_rake_spec.rb
@@ -115,19 +115,52 @@ describe 'gitlab:db namespace rake task' do
end
it 'can be executed multiple times within another rake task' do
- Rake::Task.define_task(test_task_name => :environment) do
+ expect_multiple_executions_of_task(test_task_name, clean_rake_task) do
expect_next_instance_of(Gitlab::Database::SchemaCleaner) do |cleaner|
expect(cleaner).to receive(:clean).with(output)
end
- Rake::Task[clean_rake_task].invoke
+ end
+ end
+ end
- expect_next_instance_of(Gitlab::Database::SchemaCleaner) do |cleaner|
- expect(cleaner).to receive(:clean).with(output)
+ describe 'load_custom_structure' do
+ let_it_be(:db_config) { Rails.application.config_for(:database) }
+ let_it_be(:custom_load_task) { 'gitlab:db:load_custom_structure' }
+ let_it_be(:custom_filepath) { Pathname.new('db/directory') }
+
+ it 'uses the psql command to load the custom structure file' do
+ expect(Gitlab::Database::CustomStructure).to receive(:custom_dump_filepath).and_return(custom_filepath)
+
+ expect(Kernel).to receive(:system)
+ .with('psql', any_args, custom_filepath.to_path, db_config['database']).and_return(true)
+
+ run_rake_task(custom_load_task)
+ end
+
+ it 'raises an error when the call to the psql command fails' do
+ expect(Gitlab::Database::CustomStructure).to receive(:custom_dump_filepath).and_return(custom_filepath)
+
+ expect(Kernel).to receive(:system)
+ .with('psql', any_args, custom_filepath.to_path, db_config['database']).and_return(nil)
+
+ expect { run_rake_task(custom_load_task) }.to raise_error(/failed to execute:\s*psql/)
+ end
+ end
+
+ describe 'dump_custom_structure' do
+ let_it_be(:test_task_name) { 'gitlab:db:_test_multiple_task_executions' }
+ let_it_be(:custom_dump_task) { 'gitlab:db:dump_custom_structure' }
+
+ after do
+ Rake::Task[test_task_name].clear if Rake::Task.task_defined?(test_task_name)
+ end
+
+ it 'can be executed multiple times within another rake task' do
+ expect_multiple_executions_of_task(test_task_name, custom_dump_task) do
+ expect_next_instance_of(Gitlab::Database::CustomStructure) do |custom_structure|
+ expect(custom_structure).to receive(:dump)
end
- Rake::Task[clean_rake_task].invoke
end
-
- run_rake_task(test_task_name)
end
end
@@ -135,4 +168,16 @@ describe 'gitlab:db namespace rake task' do
Rake::Task[task_name].reenable
Rake.application.invoke_task task_name
end
+
+ def expect_multiple_executions_of_task(test_task_name, task_to_invoke, count: 2)
+ Rake::Task.define_task(test_task_name => :environment) do
+ count.times do
+ yield
+
+ Rake::Task[task_to_invoke].invoke
+ end
+ end
+
+ run_rake_task(test_task_name)
+ end
end
diff --git a/spec/tooling/lib/tooling/test_file_finder_spec.rb b/spec/tooling/lib/tooling/test_file_finder_spec.rb
new file mode 100644
index 00000000000..9c33f20877b
--- /dev/null
+++ b/spec/tooling/lib/tooling/test_file_finder_spec.rb
@@ -0,0 +1,111 @@
+# frozen_string_literal: true
+
+require_relative '../../../../tooling/lib/tooling/test_file_finder'
+
+RSpec.describe Tooling::TestFileFinder do
+ subject { Tooling::TestFileFinder.new(file) }
+
+ describe '#test_files' do
+ context 'when given non .rb files' do
+ let(:file) { 'app/assets/images/emoji.png' }
+
+ it 'does not return a test file' do
+ expect(subject.test_files).to be_empty
+ end
+ end
+
+ context 'when given file in app/' do
+ let(:file) { 'app/finders/admin/projects_finder.rb' }
+
+ it 'returns the matching app spec file' do
+ expect(subject.test_files).to contain_exactly('spec/finders/admin/projects_finder_spec.rb')
+ end
+ end
+
+ context 'when given file in lib/' do
+ let(:file) { 'lib/banzai/color_parser.rb' }
+
+ it 'returns the matching app spec file' do
+ expect(subject.test_files).to contain_exactly('spec/lib/banzai/color_parser_spec.rb')
+ end
+ end
+
+ context 'when given a file in tooling/' do
+ let(:file) { 'tooling/lib/tooling/test_file_finder.rb' }
+
+ it 'returns the matching tooling test' do
+ expect(subject.test_files).to contain_exactly('spec/tooling/lib/tooling/test_file_finder_spec.rb')
+ end
+ end
+
+ context 'when given a test file' do
+ let(:file) { 'spec/lib/banzai/color_parser_spec.rb' }
+
+ it 'returns the matching test file itself' do
+ expect(subject.test_files).to contain_exactly('spec/lib/banzai/color_parser_spec.rb')
+ end
+ end
+
+ context 'when given an app file in ee/' do
+ let(:file) { 'ee/app/models/analytics/cycle_analytics/group_level.rb' }
+
+ it 'returns the matching ee/ test file' do
+ expect(subject.test_files).to contain_exactly('ee/spec/models/analytics/cycle_analytics/group_level_spec.rb')
+ end
+ end
+
+ context 'when given an ee extension module file' do
+ let(:file) { 'ee/app/models/ee/user.rb' }
+
+ it 'returns the matching ee/ class test file, ee extension module test file and the foss class test file' do
+ test_files = ['ee/spec/models/user_spec.rb', 'ee/spec/models/ee/user_spec.rb', 'spec/app/models/user_spec.rb']
+ expect(subject.test_files).to contain_exactly(*test_files)
+ end
+ end
+
+ context 'when given a lib file in ee/' do
+ let(:file) { 'ee/lib/flipper_session.rb' }
+
+ it 'returns the matching ee/ lib test file' do
+ expect(subject.test_files).to contain_exactly('ee/spec/lib/flipper_session_spec.rb')
+ end
+ end
+
+ context 'when given a test file in ee/' do
+ let(:file) { 'ee/spec/models/container_registry/event_spec.rb' }
+
+ it 'returns the test file itself' do
+ expect(subject.test_files).to contain_exactly('ee/spec/models/container_registry/event_spec.rb')
+ end
+ end
+
+ context 'when given a module test file in ee/' do
+ let(:file) { 'ee/spec/models/ee/appearance_spec.rb' }
+
+ it 'returns the matching module test file itself and the corresponding spec model test file' do
+ test_files = ['ee/spec/models/ee/appearance_spec.rb', 'spec/models/appearance_spec.rb']
+ expect(subject.test_files).to contain_exactly(*test_files)
+ end
+ end
+
+ context 'with foss_test_only: true' do
+ subject { Tooling::TestFileFinder.new(file, foss_test_only: true) }
+
+ context 'when given a module file in ee/' do
+ let(:file) { 'ee/app/models/ee/user.rb' }
+
+ it 'returns only the corresponding spec model test file in foss' do
+ expect(subject.test_files).to contain_exactly('spec/app/models/user_spec.rb')
+ end
+ end
+
+ context 'when given an app file in ee/' do
+ let(:file) { 'ee/app/models/approval.rb' }
+
+ it 'returns no test file in foss' do
+ expect(subject.test_files).to be_empty
+ end
+ end
+ end
+ end
+end
diff --git a/spec/uploaders/uploader_helper_spec.rb b/spec/uploaders/uploader_helper_spec.rb
index 753f32a9570..7bc6caf8224 100644
--- a/spec/uploaders/uploader_helper_spec.rb
+++ b/spec/uploaders/uploader_helper_spec.rb
@@ -14,7 +14,7 @@ describe UploaderHelper do
end
describe '#extension_match?' do
- it 'returns false if file does not exists' do
+ it 'returns false if file does not exist' do
expect(uploader.file).to be_nil
expect(uploader.send(:extension_match?, 'jpg')).to eq false
end
diff --git a/spec/validators/json_schema_validator_spec.rb b/spec/validators/json_schema_validator_spec.rb
new file mode 100644
index 00000000000..3e3a9c0e6a8
--- /dev/null
+++ b/spec/validators/json_schema_validator_spec.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe JsonSchemaValidator do
+ describe '#validates_each' do
+ let(:build_report_result) { build(:ci_build_report_result, :with_junit_success) }
+
+ subject { validator.validate(build_report_result) }
+
+ context 'when filename is set' do
+ let(:validator) { described_class.new(attributes: [:data], filename: "build_report_result_data") }
+
+ context 'when data is valid' do
+ it 'returns no errors' do
+ subject
+
+ expect(build_report_result.errors).to be_empty
+ end
+ end
+
+ context 'when data is invalid' do
+ it 'returns json schema is invalid' do
+ build_report_result.data = { invalid: 'data' }
+
+ validator.validate(build_report_result)
+
+ expect(build_report_result.errors.size).to eq(1)
+ expect(build_report_result.errors.full_messages).to eq(["Data must be a valid json schema"])
+ end
+ end
+ end
+
+ context 'when filename is not set' do
+ let(:validator) { described_class.new(attributes: [:data]) }
+
+ it 'raises an ArgumentError' do
+ expect { subject }.to raise_error(ArgumentError)
+ end
+ end
+
+ context 'when filename is invalid' do
+ let(:validator) { described_class.new(attributes: [:data], filename: "invalid$filename") }
+
+ it 'raises a FilenameError' do
+ expect { subject }.to raise_error(described_class::FilenameError)
+ end
+ end
+ end
+end
diff --git a/spec/views/admin/application_settings/_repository_storage.html.haml_spec.rb b/spec/views/admin/application_settings/_repository_storage.html.haml_spec.rb
index 3029bfb6df5..63236dbb0c4 100644
--- a/spec/views/admin/application_settings/_repository_storage.html.haml_spec.rb
+++ b/spec/views/admin/application_settings/_repository_storage.html.haml_spec.rb
@@ -3,26 +3,34 @@
require 'spec_helper'
describe 'admin/application_settings/_repository_storage.html.haml' do
- let(:app_settings) { build(:application_setting) }
- let(:storages) do
+ let(:app_settings) { create(:application_setting) }
+ let(:repository_storages_weighted_attributes) { [:repository_storages_weighted_default, :repository_storages_weighted_mepmep, :repository_storages_weighted_foobar]}
+ let(:repository_storages_weighted) do
{
- "mepmep" => { "path" => "/tmp" },
- "foobar" => { "path" => "/tmp" }
+ "default" => 100,
+ "mepmep" => 50
}
end
before do
+ allow(app_settings).to receive(:repository_storages_weighted).and_return(repository_storages_weighted)
+ allow(app_settings).to receive(:repository_storages_weighted_mepmep).and_return(100)
+ allow(app_settings).to receive(:repository_storages_weighted_foobar).and_return(50)
assign(:application_setting, app_settings)
- stub_storage_settings(storages)
+ allow(ApplicationSetting).to receive(:repository_storages_weighted_attributes).and_return(repository_storages_weighted_attributes)
end
context 'when multiple storages are available' do
it 'lists them all' do
render
- storages.keys.each do |storage_name|
+ # lists storages that are saved with weights
+ repository_storages_weighted.each do |storage_name, storage_weight|
expect(rendered).to have_content(storage_name)
end
+
+ # lists storage not saved with weight
+ expect(rendered).to have_content('foobar')
end
end
end
diff --git a/spec/views/layouts/_head.html.haml_spec.rb b/spec/views/layouts/_head.html.haml_spec.rb
index 8d7dcfc2416..7011fa23327 100644
--- a/spec/views/layouts/_head.html.haml_spec.rb
+++ b/spec/views/layouts/_head.html.haml_spec.rb
@@ -50,7 +50,7 @@ describe 'layouts/_head' do
it 'adds a link preconnect tag' do
render
- expect(rendered).to match(%Q(<link crossorigin="" href="#{asset_host}" rel="preconnnect">))
+ expect(rendered).to match(%Q(<link crossorigin="" href="#{asset_host}" rel="preconnect">))
end
end
@@ -64,18 +64,25 @@ describe 'layouts/_head' do
context 'when an asset_host is set and snowplow url is set' do
let(:asset_host) { 'http://test.host' }
+ let(:snowplow_collector_hostname) { 'www.snow.plow' }
before do
allow(ActionController::Base).to receive(:asset_host).and_return(asset_host)
allow(Gitlab::CurrentSettings).to receive(:snowplow_enabled?).and_return(true)
- allow(Gitlab::CurrentSettings).to receive(:snowplow_collector_hostname).and_return('www.snow.plow')
+ allow(Gitlab::CurrentSettings).to receive(:snowplow_collector_hostname).and_return(snowplow_collector_hostname)
end
it 'adds a snowplow script tag with asset host' do
render
expect(rendered).to match('http://test.host/assets/snowplow/')
expect(rendered).to match('window.snowplow')
- expect(rendered).to match('www.snow.plow')
+ expect(rendered).to match(snowplow_collector_hostname)
+ end
+
+ it 'adds a link preconnect tag' do
+ render
+
+ expect(rendered).to match(%Q(<link crossorigin="" href="#{snowplow_collector_hostname}" rel="preconnect">))
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 3d5c34ae1e0..881ea818cb0 100644
--- a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb
+++ b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb
@@ -66,7 +66,7 @@ describe 'layouts/nav/sidebar/_project' do
it 'shows the wiki tab with the wiki internal link' do
render
- expect(rendered).to have_link('Wiki', href: project_wiki_path(project, :home))
+ expect(rendered).to have_link('Wiki', href: wiki_path(project.wiki))
end
end
@@ -76,7 +76,7 @@ describe 'layouts/nav/sidebar/_project' do
it 'does not show the wiki tab' do
render
- expect(rendered).not_to have_link('Wiki', href: project_wiki_path(project, :home))
+ expect(rendered).not_to have_link('Wiki', href: wiki_path(project.wiki))
end
end
end
@@ -104,7 +104,7 @@ describe 'layouts/nav/sidebar/_project' do
it 'does not show the external wiki tab' do
render
- expect(rendered).not_to have_link('External Wiki', href: project_wiki_path(project, :home))
+ expect(rendered).not_to have_link('External Wiki')
end
end
end
diff --git a/spec/views/profiles/preferences/show.html.haml_spec.rb b/spec/views/profiles/preferences/show.html.haml_spec.rb
index 16e4bd9c6d1..2e50e329cfd 100644
--- a/spec/views/profiles/preferences/show.html.haml_spec.rb
+++ b/spec/views/profiles/preferences/show.html.haml_spec.rb
@@ -32,8 +32,7 @@ describe 'profiles/preferences/show' do
end
before do
- # Can't use stub_feature_flags because we use Feature.get to check if conditinally applied
- Feature.get(:sourcegraph).enable sourcegraph_feature
+ stub_feature_flags(sourcegraph: sourcegraph_feature)
stub_application_setting(sourcegraph_enabled: sourcegraph_enabled)
end
diff --git a/spec/views/projects/edit.html.haml_spec.rb b/spec/views/projects/edit.html.haml_spec.rb
index e95dec56a2d..0c0f74a41f0 100644
--- a/spec/views/projects/edit.html.haml_spec.rb
+++ b/spec/views/projects/edit.html.haml_spec.rb
@@ -32,26 +32,28 @@ describe 'projects/edit' do
it 'displays all possible variables' do
render
- expect(rendered).to have_content('%{project_path}')
- expect(rendered).to have_content('%{project_name}')
- expect(rendered).to have_content('%{file_path}')
expect(rendered).to have_content('%{branch_name}')
- expect(rendered).to have_content('%{username}')
+ expect(rendered).to have_content('%{files_count}')
+ expect(rendered).to have_content('%{file_paths}')
+ expect(rendered).to have_content('%{project_name}')
+ expect(rendered).to have_content('%{project_path}')
expect(rendered).to have_content('%{user_full_name}')
+ expect(rendered).to have_content('%{username}')
+ expect(rendered).to have_content('%{suggestions_count}')
end
it 'displays a placeholder if none is set' do
render
- expect(rendered).to have_field('project[suggestion_commit_message]', placeholder: 'Apply suggestion to %{file_path}')
+ expect(rendered).to have_field('project[suggestion_commit_message]', placeholder: "Apply %{suggestions_count} suggestion(s) to %{files_count} file(s)")
end
it 'displays the user entered value' do
- project.update!(suggestion_commit_message: 'refactor: changed %{file_path}')
+ project.update!(suggestion_commit_message: 'refactor: changed %{file_paths}')
render
- expect(rendered).to have_field('project[suggestion_commit_message]', with: 'refactor: changed %{file_path}')
+ expect(rendered).to have_field('project[suggestion_commit_message]', with: 'refactor: changed %{file_paths}')
end
end
diff --git a/spec/views/projects/issues/import_csv/_button.html.haml_spec.rb b/spec/views/projects/issues/import_csv/_button.html.haml_spec.rb
new file mode 100644
index 00000000000..440edd376e0
--- /dev/null
+++ b/spec/views/projects/issues/import_csv/_button.html.haml_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'projects/issues/import_csv/_button' do
+ include Devise::Test::ControllerHelpers
+
+ context 'when the user does not have edit permissions' do
+ before do
+ render
+ end
+
+ it 'shows a dropdown button to import CSV' do
+ expect(rendered).to have_text('Import CSV')
+ end
+
+ it 'does not show a button to import from Jira' do
+ expect(rendered).not_to have_text('Import from Jira')
+ end
+ end
+
+ context 'when the user has edit permissions' do
+ let(:project) { create(:project) }
+ let(:current_user) { create(:user, maintainer_projects: [project]) }
+
+ before do
+ allow(view).to receive(:project_import_jira_path).and_return('import/jira')
+ allow(view).to receive(:current_user).and_return(current_user)
+
+ assign(:project, project)
+
+ render
+ end
+
+ it 'shows a dropdown button to import CSV' do
+ expect(rendered).to have_text('Import CSV')
+ end
+
+ it 'shows a button to import from Jira' do
+ expect(rendered).to have_text('Import from Jira')
+ end
+ end
+end
diff --git a/spec/views/projects/merge_requests/show.html.haml_spec.rb b/spec/views/projects/merge_requests/show.html.haml_spec.rb
index 665003d137a..e0acf5d1507 100644
--- a/spec/views/projects/merge_requests/show.html.haml_spec.rb
+++ b/spec/views/projects/merge_requests/show.html.haml_spec.rb
@@ -3,6 +3,10 @@
require 'spec_helper'
describe 'projects/merge_requests/show.html.haml' do
+ before do
+ allow(view).to receive(:experiment_enabled?).and_return(false)
+ end
+
include_context 'merge request show action'
describe 'merge request assignee sidebar' do
diff --git a/spec/views/projects/services/_form.haml_spec.rb b/spec/views/projects/services/_form.haml_spec.rb
index a3faa92b50e..720e0aaf450 100644
--- a/spec/views/projects/services/_form.haml_spec.rb
+++ b/spec/views/projects/services/_form.haml_spec.rb
@@ -15,7 +15,8 @@ describe 'projects/services/_form' do
allow(view).to receive_messages(current_user: user,
can?: true,
- current_application_settings: Gitlab::CurrentSettings.current_application_settings)
+ current_application_settings: Gitlab::CurrentSettings.current_application_settings,
+ request: double(referrer: '/services'))
end
context 'commit_events and merge_request_events' do
@@ -30,6 +31,7 @@ describe 'projects/services/_form' do
expect(rendered).to have_content('Event will be triggered when a commit is created/updated')
expect(rendered).to have_content('Event will be triggered when a merge request is created/updated/merged')
+ expect(rendered).to have_css("input[name='redirect_to'][value='/services']", count: 1, visible: false)
end
end
end
diff --git a/spec/views/shared/milestones/_top.html.haml_spec.rb b/spec/views/shared/milestones/_top.html.haml_spec.rb
index 1e209ad6f3f..2d72e278706 100644
--- a/spec/views/shared/milestones/_top.html.haml_spec.rb
+++ b/spec/views/shared/milestones/_top.html.haml_spec.rb
@@ -12,22 +12,6 @@ describe 'shared/milestones/_top.html.haml' do
allow(milestone).to receive(:milestone) { milestone }
end
- it 'renders a deprecation message for a legacy milestone' do
- allow(milestone).to receive(:legacy_group_milestone?) { true }
-
- render 'shared/milestones/top', milestone: milestone
-
- expect(rendered).to have_css('.milestone-deprecation-message')
- end
-
- it 'renders a deprecation message for a dashboard milestone' do
- allow(milestone).to receive(:dashboard_milestone?) { true }
-
- render 'shared/milestones/top', milestone: milestone
-
- expect(rendered).to have_css('.milestone-deprecation-message')
- end
-
it 'does not render a deprecation message for a non-legacy and non-dashboard milestone' do
assign :group, group
diff --git a/spec/workers/build_finished_worker_spec.rb b/spec/workers/build_finished_worker_spec.rb
index 4adb795b1d6..849563d9608 100644
--- a/spec/workers/build_finished_worker_spec.rb
+++ b/spec/workers/build_finished_worker_spec.rb
@@ -3,7 +3,11 @@
require 'spec_helper'
describe BuildFinishedWorker do
+ subject { described_class.new.perform(build.id) }
+
describe '#perform' do
+ let(:build) { create(:ci_build, :success, pipeline: create(:ci_pipeline)) }
+
context 'when build exists' do
let!(:build) { create(:ci_build) }
@@ -18,8 +22,10 @@ describe BuildFinishedWorker do
expect(BuildHooksWorker).to receive(:perform_async)
expect(ArchiveTraceWorker).to receive(:perform_async)
expect(ExpirePipelineCacheWorker).to receive(:perform_async)
+ expect(ChatNotificationWorker).not_to receive(:perform_async)
+ expect(Ci::BuildReportResultWorker).not_to receive(:perform)
- described_class.new.perform(build.id)
+ subject
end
end
@@ -30,23 +36,26 @@ describe BuildFinishedWorker do
end
end
- it 'schedules a ChatNotification job for a chat build' do
- build = create(:ci_build, :success, pipeline: create(:ci_pipeline, source: :chat))
+ context 'when build has a chat' do
+ let(:build) { create(:ci_build, :success, pipeline: create(:ci_pipeline, source: :chat)) }
- expect(ChatNotificationWorker)
- .to receive(:perform_async)
- .with(build.id)
+ it 'schedules a ChatNotification job' do
+ expect(ChatNotificationWorker).to receive(:perform_async).with(build.id)
- described_class.new.perform(build.id)
+ subject
+ end
end
- it 'does not schedule a ChatNotification job for a regular build' do
- build = create(:ci_build, :success, pipeline: create(:ci_pipeline))
+ context 'when build has a test report' do
+ let(:build) { create(:ci_build, :test_reports) }
- expect(ChatNotificationWorker)
- .not_to receive(:perform_async)
+ it 'schedules a BuildReportResult job' do
+ expect_next_instance_of(Ci::BuildReportResultWorker) do |worker|
+ expect(worker).to receive(:perform).with(build.id)
+ end
- described_class.new.perform(build.id)
+ subject
+ end
end
end
end
diff --git a/spec/workers/ci/build_report_result_worker_spec.rb b/spec/workers/ci/build_report_result_worker_spec.rb
new file mode 100644
index 00000000000..290a98366b4
--- /dev/null
+++ b/spec/workers/ci/build_report_result_worker_spec.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Ci::BuildReportResultWorker do
+ subject { described_class.new.perform(build_id) }
+
+ context 'when build exists' do
+ let(:build) { create(:ci_build) }
+ let(:build_id) { build.id }
+
+ it 'calls build report result service' do
+ expect_next_instance_of(Ci::BuildReportResultService) do |build_report_result_service|
+ expect(build_report_result_service).to receive(:execute)
+ end
+
+ subject
+ end
+ end
+
+ context 'when build does not exist' do
+ let(:build_id) { -1 }
+
+ it 'does not call build report result service' do
+ expect(Ci::BuildReportResultService).not_to receive(:execute)
+
+ subject
+ end
+ end
+end
diff --git a/spec/workers/clusters/applications/check_prometheus_health_worker_spec.rb b/spec/workers/clusters/applications/check_prometheus_health_worker_spec.rb
new file mode 100644
index 00000000000..a09b9ec4165
--- /dev/null
+++ b/spec/workers/clusters/applications/check_prometheus_health_worker_spec.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Clusters::Applications::CheckPrometheusHealthWorker, '#perform' do
+ subject { described_class.new.perform }
+
+ it 'triggers health service' do
+ cluster = create(:cluster)
+ allow(Gitlab::Monitor::DemoProjects).to receive(:primary_keys)
+ allow(Clusters::Cluster).to receive_message_chain(:with_application_prometheus, :with_project_alert_service_data).and_return([cluster])
+
+ service_instance = instance_double(Clusters::Applications::PrometheusHealthCheckService)
+ expect(Clusters::Applications::PrometheusHealthCheckService).to receive(:new).with(cluster).and_return(service_instance)
+ expect(service_instance).to receive(:execute)
+
+ subject
+ end
+end
diff --git a/spec/workers/concerns/application_worker_spec.rb b/spec/workers/concerns/application_worker_spec.rb
index ae311a54cd1..087a36d2bd0 100644
--- a/spec/workers/concerns/application_worker_spec.rb
+++ b/spec/workers/concerns/application_worker_spec.rb
@@ -118,5 +118,45 @@ describe ApplicationWorker do
.to raise_error(ArgumentError)
end
end
+
+ context 'with batches' do
+ let(:batch_delay) { 1.minute }
+
+ it 'correctly schedules jobs' do
+ expect(Sidekiq::Client).to(
+ receive(:push_bulk).with(hash_including('args' => [['Foo', [1]], ['Foo', [2]]]))
+ .ordered
+ .and_call_original)
+ expect(Sidekiq::Client).to(
+ receive(:push_bulk).with(hash_including('args' => [['Foo', [3]], ['Foo', [4]]]))
+ .ordered
+ .and_call_original)
+ expect(Sidekiq::Client).to(
+ receive(:push_bulk).with(hash_including('args' => [['Foo', [5]]]))
+ .ordered
+ .and_call_original)
+
+ worker.bulk_perform_in(
+ 1.minute,
+ [['Foo', [1]], ['Foo', [2]], ['Foo', [3]], ['Foo', [4]], ['Foo', [5]]],
+ batch_size: 2, batch_delay: batch_delay)
+
+ expect(worker.jobs.count).to eq 5
+ expect(worker.jobs[0]['at']).to eq(worker.jobs[1]['at'])
+ expect(worker.jobs[2]['at']).to eq(worker.jobs[3]['at'])
+ expect(worker.jobs[2]['at'] - worker.jobs[1]['at']).to eq(batch_delay)
+ expect(worker.jobs[4]['at'] - worker.jobs[3]['at']).to eq(batch_delay)
+ end
+
+ context 'when batch_size is invalid' do
+ it 'raises an ArgumentError exception' do
+ expect do
+ worker.bulk_perform_in(1.minute,
+ [['Foo']],
+ batch_size: -1, batch_delay: batch_delay)
+ end.to raise_error(ArgumentError)
+ end
+ end
+ end
end
end
diff --git a/spec/workers/concerns/project_import_options_spec.rb b/spec/workers/concerns/project_import_options_spec.rb
index 3ccfb21b653..c56dcc5ed82 100644
--- a/spec/workers/concerns/project_import_options_spec.rb
+++ b/spec/workers/concerns/project_import_options_spec.rb
@@ -17,7 +17,7 @@ describe ProjectImportOptions do
end
it 'sets default status expiration' do
- expect(worker_class.sidekiq_options['status_expiration']).to eq(StuckImportJobsWorker::IMPORT_JOBS_EXPIRATION)
+ expect(worker_class.sidekiq_options['status_expiration']).to eq(Gitlab::Import::StuckImportJob::IMPORT_JOBS_EXPIRATION)
end
describe '.sidekiq_retries_exhausted' do
diff --git a/spec/workers/container_expiration_policy_worker_spec.rb b/spec/workers/container_expiration_policy_worker_spec.rb
index 48ab1614633..b15a28dcdca 100644
--- a/spec/workers/container_expiration_policy_worker_spec.rb
+++ b/spec/workers/container_expiration_policy_worker_spec.rb
@@ -53,5 +53,22 @@ describe ContainerExpirationPolicyWorker do
subject
end
end
+
+ context 'an invalid policy' do
+ let_it_be(:container_expiration_policy) { create(:container_expiration_policy, :runnable) }
+ let_it_be(:user) {container_expiration_policy.project.owner }
+
+ before do
+ container_expiration_policy.update_column(:name_regex, '*production')
+ end
+
+ it 'runs the policy and tracks an error' do
+ expect(ContainerExpirationPolicyService)
+ .to receive(:new).with(container_expiration_policy.project, user).and_call_original
+ expect(Gitlab::ErrorTracking).to receive(:log_exception).with(instance_of(ContainerExpirationPolicyService::InvalidPolicyError), container_expiration_policy_id: container_expiration_policy.id)
+
+ expect { subject }.to change { container_expiration_policy.reload.enabled }.from(true).to(false)
+ end
+ end
end
end
diff --git a/spec/workers/create_evidence_worker_spec.rb b/spec/workers/create_evidence_worker_spec.rb
index 9b8314122cd..b8c622f7d1d 100644
--- a/spec/workers/create_evidence_worker_spec.rb
+++ b/spec/workers/create_evidence_worker_spec.rb
@@ -3,9 +3,24 @@
require 'spec_helper'
describe CreateEvidenceWorker do
- let!(:release) { create(:release) }
+ let(:project) { create(:project, :repository) }
+ let(:release) { create(:release, project: project) }
+ let(:pipeline) { create(:ci_empty_pipeline, sha: release.sha, project: project) }
+ # support old scheduled workers without pipeline
it 'creates a new Evidence record' do
+ expect_next_instance_of(::Releases::CreateEvidenceService, release, pipeline: nil) do |service|
+ expect(service).to receive(:execute).and_call_original
+ end
+
expect { described_class.new.perform(release.id) }.to change(Releases::Evidence, :count).by(1)
end
+
+ it 'creates a new Evidence record with pipeline' do
+ expect_next_instance_of(::Releases::CreateEvidenceService, release, pipeline: pipeline) do |service|
+ expect(service).to receive(:execute).and_call_original
+ end
+
+ expect { described_class.new.perform(release.id, pipeline.id) }.to change(Releases::Evidence, :count).by(1)
+ end
end
diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb
index d6e867ee407..195783c74df 100644
--- a/spec/workers/every_sidekiq_worker_spec.rb
+++ b/spec/workers/every_sidekiq_worker_spec.rb
@@ -40,6 +40,12 @@ describe 'Every Sidekiq worker' do
end
end
+ it 'has a value for loggable_arguments' do
+ workers_without_defaults.each do |worker|
+ expect(worker.klass.loggable_arguments).to be_an(Array)
+ end
+ end
+
describe "feature category declarations" do
let(:feature_categories) do
YAML.load_file(Rails.root.join('config', 'feature_categories.yml')).map(&:to_sym).to_set
diff --git a/spec/workers/expire_job_cache_worker_spec.rb b/spec/workers/expire_job_cache_worker_spec.rb
index 804a50e89fe..062926cf7aa 100644
--- a/spec/workers/expire_job_cache_worker_spec.rb
+++ b/spec/workers/expire_job_cache_worker_spec.rb
@@ -13,7 +13,7 @@ describe ExpireJobCacheWorker do
include_examples 'an idempotent worker' do
it 'invalidates Etag caching for the job path' do
- pipeline_path = "/#{project.full_path}/pipelines/#{pipeline.id}.json"
+ pipeline_path = "/#{project.full_path}/-/pipelines/#{pipeline.id}.json"
job_path = "/#{project.full_path}/builds/#{job.id}.json"
spy_store = Gitlab::EtagCaching::Store.new
diff --git a/spec/workers/gitlab/import/stuck_project_import_jobs_worker_spec.rb b/spec/workers/gitlab/import/stuck_project_import_jobs_worker_spec.rb
new file mode 100644
index 00000000000..5afc5717b82
--- /dev/null
+++ b/spec/workers/gitlab/import/stuck_project_import_jobs_worker_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Import::StuckProjectImportJobsWorker do
+ let(:worker) { described_class.new }
+
+ describe 'with scheduled import_status' do
+ it_behaves_like 'stuck import job detection' do
+ let(:import_state) { create(:project, :import_scheduled).import_state }
+
+ before do
+ import_state.update(jid: '123')
+ end
+ end
+ end
+
+ describe 'with started import_status' do
+ it_behaves_like 'stuck import job detection' do
+ let(:import_state) { create(:project, :import_started).import_state }
+
+ before do
+ import_state.update(jid: '123')
+ end
+ end
+ end
+end
diff --git a/spec/workers/gitlab/jira_import/stage/finish_import_worker_spec.rb b/spec/workers/gitlab/jira_import/stage/finish_import_worker_spec.rb
index 4cb6f5e28b8..084302be7d8 100644
--- a/spec/workers/gitlab/jira_import/stage/finish_import_worker_spec.rb
+++ b/spec/workers/gitlab/jira_import/stage/finish_import_worker_spec.rb
@@ -11,47 +11,33 @@ describe Gitlab::JiraImport::Stage::FinishImportWorker do
end
describe '#perform' do
- context 'when feature flag enabled' do
- before do
- stub_feature_flags(jira_issue_import: false)
- end
+ let_it_be(:jira_import, reload: true) { create(:jira_import_state, :scheduled, project: project) }
+ context 'when import did not start' do
it_behaves_like 'cannot do Jira import'
end
- context 'when feature flag enabled' do
- let_it_be(:jira_import, reload: true) { create(:jira_import_state, :scheduled, project: project) }
+ context 'when import started' do
+ let_it_be(:import_label) { create(:label, project: project, title: 'jira-import') }
+ let_it_be(:imported_issues) { create_list(:labeled_issue, 3, project: project, labels: [import_label]) }
before do
- stub_feature_flags(jira_issue_import: true)
- end
+ expect(Gitlab::JiraImport).to receive(:get_import_label_id).and_return(import_label.id)
+ expect(Gitlab::JiraImport).to receive(:issue_failures).and_return(2)
- context 'when import did not start' do
- it_behaves_like 'cannot do Jira import'
+ jira_import.start!
+ worker.perform(project.id)
end
- context 'when import started' do
- let_it_be(:import_label) { create(:label, project: project, title: 'jira-import') }
- let_it_be(:imported_issues) { create_list(:labeled_issue, 3, project: project, labels: [import_label]) }
-
- before do
- expect(Gitlab::JiraImport).to receive(:get_import_label_id).and_return(import_label.id)
- expect(Gitlab::JiraImport).to receive(:issue_failures).and_return(2)
-
- jira_import.start!
- worker.perform(project.id)
- end
-
- it 'changes import state to finished' do
- expect(project.jira_import_status).to eq('finished')
- end
+ it 'changes import state to finished' do
+ expect(project.jira_import_status).to eq('finished')
+ end
- it 'saves imported issues counts' do
- latest_jira_import = project.latest_jira_import
- expect(latest_jira_import.total_issue_count).to eq(5)
- expect(latest_jira_import.failed_to_import_count).to eq(2)
- expect(latest_jira_import.imported_issues_count).to eq(3)
- end
+ it 'saves imported issues counts' do
+ latest_jira_import = project.latest_jira_import
+ expect(latest_jira_import.total_issue_count).to eq(5)
+ expect(latest_jira_import.failed_to_import_count).to eq(2)
+ expect(latest_jira_import.imported_issues_count).to eq(3)
end
end
end
diff --git a/spec/workers/gitlab/jira_import/stage/import_attachments_worker_spec.rb b/spec/workers/gitlab/jira_import/stage/import_attachments_worker_spec.rb
index e6d41ae8bb4..34981d974cd 100644
--- a/spec/workers/gitlab/jira_import/stage/import_attachments_worker_spec.rb
+++ b/spec/workers/gitlab/jira_import/stage/import_attachments_worker_spec.rb
@@ -10,34 +10,19 @@ describe Gitlab::JiraImport::Stage::ImportAttachmentsWorker do
end
describe '#perform' do
- context 'when feature flag disabled' do
- before do
- stub_feature_flags(jira_issue_import: false)
- end
+ let_it_be(:jira_import) { create(:jira_import_state, :scheduled, project: project) }
+ context 'when import did not start' do
it_behaves_like 'cannot do Jira import'
it_behaves_like 'does not advance to next stage'
end
- context 'when feature flag enabled' do
- let_it_be(:jira_import) { create(:jira_import_state, :scheduled, project: project) }
-
+ context 'when import started' do
before do
- stub_feature_flags(jira_issue_import: true)
+ jira_import.start!
end
- context 'when import did not start' do
- it_behaves_like 'cannot do Jira import'
- it_behaves_like 'does not advance to next stage'
- end
-
- context 'when import started' do
- before do
- jira_import.start!
- end
-
- it_behaves_like 'advance to next stage', :notes
- end
+ it_behaves_like 'advance to next stage', :notes
end
end
end
diff --git a/spec/workers/gitlab/jira_import/stage/import_issues_worker_spec.rb b/spec/workers/gitlab/jira_import/stage/import_issues_worker_spec.rb
index f2067522af4..40f6cf75412 100644
--- a/spec/workers/gitlab/jira_import/stage/import_issues_worker_spec.rb
+++ b/spec/workers/gitlab/jira_import/stage/import_issues_worker_spec.rb
@@ -13,65 +13,53 @@ describe Gitlab::JiraImport::Stage::ImportIssuesWorker do
end
describe '#perform' do
- context 'when feature flag disabled' do
- before do
- stub_feature_flags(jira_issue_import: false)
- end
+ let_it_be(:jira_import, reload: true) { create(:jira_import_state, :scheduled, project: project) }
+
+ before do
+ stub_jira_service_test
+ end
+ context 'when import did not start' do
it_behaves_like 'cannot do Jira import'
it_behaves_like 'does not advance to next stage'
end
- context 'when feature flag enabled' do
- let_it_be(:jira_import, reload: true) { create(:jira_import_state, :scheduled, project: project) }
+ context 'when import started', :clean_gitlab_redis_cache do
+ let_it_be(:jira_service) { create(:jira_service, project: project) }
before do
- stub_feature_flags(jira_issue_import: true)
- stub_jira_service_test
+ jira_import.start!
+ allow_next_instance_of(Gitlab::JiraImport::IssuesImporter) do |instance|
+ allow(instance).to receive(:fetch_issues).and_return([])
+ end
end
- context 'when import did not start' do
- it_behaves_like 'cannot do Jira import'
- it_behaves_like 'does not advance to next stage'
+ context 'when start_at is nil' do
+ it_behaves_like 'advance to next stage', :attachments
end
- context 'when import started', :clean_gitlab_redis_cache do
- let_it_be(:jira_service) { create(:jira_service, project: project) }
-
+ context 'when start_at is zero' do
before do
- jira_import.start!
- allow_next_instance_of(Gitlab::JiraImport::IssuesImporter) do |instance|
- allow(instance).to receive(:fetch_issues).and_return([])
- end
- end
-
- context 'when start_at is nil' do
- it_behaves_like 'advance to next stage', :attachments
+ allow(Gitlab::Cache::Import::Caching).to receive(:read).and_return(0)
end
- context 'when start_at is zero' do
- before do
- allow(Gitlab::Cache::Import::Caching).to receive(:read).and_return(0)
- end
+ it_behaves_like 'advance to next stage', :issues
+ end
- it_behaves_like 'advance to next stage', :issues
+ context 'when start_at is greater than zero' do
+ before do
+ allow(Gitlab::Cache::Import::Caching).to receive(:read).and_return(25)
end
- context 'when start_at is greater than zero' do
- before do
- allow(Gitlab::Cache::Import::Caching).to receive(:read).and_return(25)
- end
+ it_behaves_like 'advance to next stage', :issues
+ end
- it_behaves_like 'advance to next stage', :issues
+ context 'when start_at is below zero' do
+ before do
+ allow(Gitlab::Cache::Import::Caching).to receive(:read).and_return(-1)
end
- context 'when start_at is below zero' do
- before do
- allow(Gitlab::Cache::Import::Caching).to receive(:read).and_return(-1)
- end
-
- it_behaves_like 'advance to next stage', :attachments
- end
+ it_behaves_like 'advance to next stage', :attachments
end
end
end
diff --git a/spec/workers/gitlab/jira_import/stage/import_labels_worker_spec.rb b/spec/workers/gitlab/jira_import/stage/import_labels_worker_spec.rb
index 7f289de5422..1215b41bd9f 100644
--- a/spec/workers/gitlab/jira_import/stage/import_labels_worker_spec.rb
+++ b/spec/workers/gitlab/jira_import/stage/import_labels_worker_spec.rb
@@ -13,48 +13,33 @@ describe Gitlab::JiraImport::Stage::ImportLabelsWorker do
end
describe '#perform' do
- context 'when feature flag disabled' do
- before do
- stub_feature_flags(jira_issue_import: false)
- end
+ let_it_be(:jira_import, reload: true) { create(:jira_import_state, :scheduled, project: project) }
+ context 'when import did not start' do
it_behaves_like 'cannot do Jira import'
it_behaves_like 'does not advance to next stage'
end
- context 'when feature flag enabled' do
- let_it_be(:jira_import, reload: true) { create(:jira_import_state, :scheduled, project: project) }
+ context 'when import started' do
+ let!(:jira_service) { create(:jira_service, project: project) }
before do
- stub_feature_flags(jira_issue_import: true)
- end
-
- context 'when import did not start' do
- it_behaves_like 'cannot do Jira import'
- it_behaves_like 'does not advance to next stage'
- end
+ stub_jira_service_test
- context 'when import started' do
- let!(:jira_service) { create(:jira_service, project: project) }
+ jira_import.start!
- before do
- stub_jira_service_test
+ WebMock.stub_request(:get, 'https://jira.example.com/rest/api/2/label?maxResults=500&startAt=0')
+ .to_return(body: {}.to_json )
+ end
- jira_import.start!
+ it_behaves_like 'advance to next stage', :issues
- WebMock.stub_request(:get, 'https://jira.example.com/rest/api/2/label?maxResults=500&startAt=0')
- .to_return(body: {}.to_json )
+ it 'executes labels importer' do
+ expect_next_instance_of(Gitlab::JiraImport::LabelsImporter) do |instance|
+ expect(instance).to receive(:execute).and_return(Gitlab::JobWaiter.new)
end
- it_behaves_like 'advance to next stage', :issues
-
- it 'executes labels importer' do
- expect_next_instance_of(Gitlab::JiraImport::LabelsImporter) do |instance|
- expect(instance).to receive(:execute).and_return(Gitlab::JobWaiter.new)
- end
-
- described_class.new.perform(project.id)
- end
+ described_class.new.perform(project.id)
end
end
end
diff --git a/spec/workers/gitlab/jira_import/stage/import_notes_worker_spec.rb b/spec/workers/gitlab/jira_import/stage/import_notes_worker_spec.rb
index f9bdbd669d8..a0a9ad6f695 100644
--- a/spec/workers/gitlab/jira_import/stage/import_notes_worker_spec.rb
+++ b/spec/workers/gitlab/jira_import/stage/import_notes_worker_spec.rb
@@ -10,34 +10,19 @@ describe Gitlab::JiraImport::Stage::ImportNotesWorker do
end
describe '#perform' do
- context 'when feature flag disabled' do
- before do
- stub_feature_flags(jira_issue_import: false)
- end
+ let_it_be(:jira_import) { create(:jira_import_state, :scheduled, project: project) }
+ context 'when import did not start' do
it_behaves_like 'cannot do Jira import'
it_behaves_like 'does not advance to next stage'
end
- context 'when feature flag enabled' do
- let_it_be(:jira_import) { create(:jira_import_state, :scheduled, project: project) }
-
+ context 'when import started' do
before do
- stub_feature_flags(jira_issue_import: true)
+ jira_import.start!
end
- context 'when import did not start' do
- it_behaves_like 'cannot do Jira import'
- it_behaves_like 'does not advance to next stage'
- end
-
- context 'when import started' do
- before do
- jira_import.start!
- end
-
- it_behaves_like 'advance to next stage', :finish
- end
+ it_behaves_like 'advance to next stage', :finish
end
end
end
diff --git a/spec/workers/gitlab/jira_import/stage/start_import_worker_spec.rb b/spec/workers/gitlab/jira_import/stage/start_import_worker_spec.rb
index 9cffe6e4ff7..a4fc761accf 100644
--- a/spec/workers/gitlab/jira_import/stage/start_import_worker_spec.rb
+++ b/spec/workers/gitlab/jira_import/stage/start_import_worker_spec.rb
@@ -12,80 +12,62 @@ describe Gitlab::JiraImport::Stage::StartImportWorker do
end
describe '#perform' do
- context 'when feature flag not disabled' do
- before do
- stub_feature_flags(jira_issue_import: false)
- end
+ let_it_be(:jira_import, reload: true) { create(:jira_import_state, project: project, jid: jid) }
- it 'exits because import not allowed' do
+ context 'when import is not scheduled' do
+ it 'exits because import not started' do
expect(Gitlab::JiraImport::Stage::ImportLabelsWorker).not_to receive(:perform_async)
worker.perform(project.id)
end
end
- context 'when feature flag enabled' do
- let_it_be(:jira_import, reload: true) { create(:jira_import_state, project: project, jid: jid) }
-
+ context 'when import is scheduled' do
before do
- stub_feature_flags(jira_issue_import: true)
+ jira_import.schedule!
end
- context 'when import is not scheduled' do
- it 'exits because import not started' do
- expect(Gitlab::JiraImport::Stage::ImportLabelsWorker).not_to receive(:perform_async)
+ it 'advances to importing labels' do
+ expect(Gitlab::JiraImport::Stage::ImportLabelsWorker).to receive(:perform_async)
- worker.perform(project.id)
- end
+ worker.perform(project.id)
end
+ end
- context 'when import is scheduled' do
- before do
- jira_import.schedule!
- end
+ context 'when import is started' do
+ before do
+ jira_import.update!(status: :started)
+ end
+ context 'when this is the same worker that stated import' do
it 'advances to importing labels' do
+ allow(worker).to receive(:jid).and_return(jid)
expect(Gitlab::JiraImport::Stage::ImportLabelsWorker).to receive(:perform_async)
worker.perform(project.id)
end
end
- context 'when import is started' do
- before do
- jira_import.update!(status: :started)
- end
-
- context 'when this is the same worker that stated import' do
- it 'advances to importing labels' do
- allow(worker).to receive(:jid).and_return(jid)
- expect(Gitlab::JiraImport::Stage::ImportLabelsWorker).to receive(:perform_async)
-
- worker.perform(project.id)
- end
- end
-
- context 'when this is a different worker that stated import' do
- it 'advances to importing labels' do
- allow(worker).to receive(:jid).and_return('87654321')
- expect(Gitlab::JiraImport::Stage::ImportLabelsWorker).not_to receive(:perform_async)
+ context 'when this is a different worker that stated import' do
+ it 'advances to importing labels' do
+ allow(worker).to receive(:jid).and_return('87654321')
+ expect(Gitlab::JiraImport::Stage::ImportLabelsWorker).not_to receive(:perform_async)
- worker.perform(project.id)
- end
+ worker.perform(project.id)
end
end
+ end
- context 'when import is finished' do
- before do
- jira_import.update!(status: :finished)
- end
+ context 'when import is finished' do
+ before do
+ jira_import.update!(status: :finished)
+ end
- it 'advances to importing labels' do
- allow(worker).to receive(:jid).and_return(jid)
- expect(Gitlab::JiraImport::Stage::ImportLabelsWorker).not_to receive(:perform_async)
+ it 'advances to importing labels' do
+ allow(worker).to receive(:jid).and_return(jid)
+ expect(Gitlab::JiraImport::Stage::ImportLabelsWorker).not_to receive(:perform_async)
- worker.perform(project.id)
- end
+ worker.perform(project.id)
end
end
end
diff --git a/spec/workers/gitlab/jira_import/stuck_jira_import_jobs_worker_spec.rb b/spec/workers/gitlab/jira_import/stuck_jira_import_jobs_worker_spec.rb
new file mode 100644
index 00000000000..fae52cec2b4
--- /dev/null
+++ b/spec/workers/gitlab/jira_import/stuck_jira_import_jobs_worker_spec.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe ::Gitlab::JiraImport::StuckJiraImportJobsWorker do
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let(:worker) { described_class.new }
+
+ describe 'with scheduled Jira import' do
+ it_behaves_like 'stuck import job detection' do
+ let(:import_state) { create(:jira_import_state, :scheduled, project: project) }
+
+ before do
+ import_state.update(jid: '123')
+ end
+ end
+ end
+
+ describe 'with started jira import' do
+ it_behaves_like 'stuck import job detection' do
+ let(:import_state) { create(:jira_import_state, :started, project: project) }
+
+ before do
+ import_state.update(jid: '123')
+ end
+ end
+ end
+
+ describe 'with failed jira import' do
+ let(:import_state) { create(:jira_import_state, :failed, project: project) }
+
+ it 'detects no stuck jobs' do
+ expect(worker).to receive(:track_metrics).with(0, 0)
+
+ worker.perform
+ end
+ end
+end
diff --git a/spec/workers/group_import_worker_spec.rb b/spec/workers/group_import_worker_spec.rb
index bb7dc116a08..324a5fa6978 100644
--- a/spec/workers/group_import_worker_spec.rb
+++ b/spec/workers/group_import_worker_spec.rb
@@ -26,7 +26,7 @@ describe GroupImportWorker do
subject.perform(user.id, group.id)
end
- context 'import state' do
+ context 'when the import state does not exist' do
it 'creates group import' do
expect(group.import_state).to be_nil
@@ -54,6 +54,17 @@ describe GroupImportWorker do
subject.perform(user.id, group.id)
end
end
+
+ context 'when the import state already exists' do
+ it 'updates the existing state' do
+ existing_state = create(:group_import_state, group: group)
+
+ expect { subject.perform(user.id, group.id) }
+ .not_to change { GroupImportState.count }
+
+ expect(existing_state.reload).to be_finished
+ end
+ end
end
context 'when it fails' do
diff --git a/spec/workers/incident_management/process_alert_worker_spec.rb b/spec/workers/incident_management/process_alert_worker_spec.rb
index 2d17a59c76f..0470552d933 100644
--- a/spec/workers/incident_management/process_alert_worker_spec.rb
+++ b/spec/workers/incident_management/process_alert_worker_spec.rb
@@ -4,6 +4,7 @@ require 'spec_helper'
describe IncidentManagement::ProcessAlertWorker do
let_it_be(:project) { create(:project) }
+ let_it_be(:settings) { create(:project_incident_management_setting, project: project, create_issue: true) }
describe '#perform' do
let(:alert_management_alert_id) { nil }
@@ -71,11 +72,7 @@ describe IncidentManagement::ProcessAlertWorker do
end
context 'when alert cannot be updated' do
- before do
- # invalidate alert
- too_many_hosts = Array.new(AlertManagement::Alert::HOSTS_MAX_LENGTH + 1) { |_| 'host' }
- alert.update_columns(hosts: too_many_hosts)
- end
+ let(:alert) { create(:alert_management_alert, :with_validation_errors, project: project) }
it 'updates AlertManagement::Alert#issue_id' do
expect { subject }.not_to change { alert.reload.issue_id }
diff --git a/spec/workers/incident_management/process_prometheus_alert_worker_spec.rb b/spec/workers/incident_management/process_prometheus_alert_worker_spec.rb
index 5fbc39cad4e..c9ea96df5c2 100644
--- a/spec/workers/incident_management/process_prometheus_alert_worker_spec.rb
+++ b/spec/workers/incident_management/process_prometheus_alert_worker_spec.rb
@@ -6,8 +6,9 @@ describe IncidentManagement::ProcessPrometheusAlertWorker do
describe '#perform' do
let_it_be(:project) { create(:project) }
let_it_be(:prometheus_alert) { create(:prometheus_alert, project: project) }
- let_it_be(:payload_key) { PrometheusAlertEvent.payload_key_for(prometheus_alert.prometheus_metric_id, prometheus_alert.created_at.rfc3339) }
+ let(:payload_key) { Gitlab::Alerting::Alert.new(project: project, payload: alert_params).gitlab_fingerprint }
let!(:prometheus_alert_event) { create(:prometheus_alert_event, prometheus_alert: prometheus_alert, payload_key: payload_key) }
+ let!(:settings) { create(:project_incident_management_setting, project: project, create_issue: true) }
let(:alert_params) do
{
@@ -107,7 +108,6 @@ describe IncidentManagement::ProcessPrometheusAlertWorker do
let(:starts_at) { Time.now.rfc3339 }
let!(:prometheus_alert_event) do
- payload_key = SelfManagedPrometheusAlertEvent.payload_key_for(starts_at, alert_name, 'vector(1)')
create(:self_managed_prometheus_alert_event, project: project, payload_key: payload_key)
end
diff --git a/spec/workers/irker_worker_spec.rb b/spec/workers/irker_worker_spec.rb
new file mode 100644
index 00000000000..6b58c04d909
--- /dev/null
+++ b/spec/workers/irker_worker_spec.rb
@@ -0,0 +1,99 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe IrkerWorker, '#perform' do
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:push_data) { HashWithIndifferentAccess.new(Gitlab::DataBuilder::Push.build_sample(project, user)) }
+ let_it_be(:channels) { ['irc://test.net/#test'] }
+
+ let_it_be(:server_settings) do
+ {
+ server_host: 'localhost',
+ server_port: 6659
+ }
+ end
+
+ let_it_be(:arguments) do
+ [
+ project.id,
+ channels,
+ false,
+ push_data,
+ server_settings
+ ]
+ end
+
+ let(:tcp_socket) { double('socket') }
+
+ subject(:worker) { described_class.new }
+
+ before do
+ allow(TCPSocket).to receive(:new).and_return(tcp_socket)
+ allow(tcp_socket).to receive(:puts).and_return(true)
+ allow(tcp_socket).to receive(:close).and_return(true)
+ end
+
+ context 'connection fails' do
+ before do
+ allow(TCPSocket).to receive(:new).and_raise(Errno::ECONNREFUSED.new('test'))
+ end
+
+ it { expect(subject.perform(*arguments)).to be_falsey }
+ end
+
+ context 'connection successful' do
+ it { expect(subject.perform(*arguments)).to be_truthy }
+
+ context 'new branch' do
+ it 'sends a correct message with branches url' do
+ branches_url = Gitlab::Routing.url_helpers
+ .project_branches_url(project)
+
+ push_data['before'] = '0000000000000000000000000000000000000000'
+
+ message = "has created a new branch master: #{branches_url}"
+
+ expect(tcp_socket).to receive(:puts).with(wrap_message(message))
+
+ subject.perform(*arguments)
+ end
+ end
+
+ context 'deleted branch' do
+ it 'sends a correct message' do
+ push_data['after'] = '0000000000000000000000000000000000000000'
+
+ message = "has deleted the branch master"
+
+ expect(tcp_socket).to receive(:puts).with(wrap_message(message))
+
+ subject.perform(*arguments)
+ end
+ end
+
+ context 'new commits to existing branch' do
+ it 'sends a correct message with a compare url' do
+ compare_url = Gitlab::Routing.url_helpers
+ .project_compare_url(project,
+ from: Commit.truncate_sha(push_data[:before]),
+ to: Commit.truncate_sha(push_data[:after]))
+
+ message = "pushed #{push_data['total_commits_count']} " \
+ "new commits to master: #{compare_url}"
+
+ expect(tcp_socket).to receive(:puts).with(wrap_message(message))
+
+ subject.perform(*arguments)
+ end
+ end
+ end
+
+ def wrap_message(text)
+ message = "[#{project.path}] #{push_data['user_name']} #{text}"
+ to_send = { to: channels, privmsg: message }
+
+ Gitlab::Json.dump(to_send)
+ end
+end
diff --git a/spec/workers/metrics/dashboard/prune_old_annotations_worker_spec.rb b/spec/workers/metrics/dashboard/prune_old_annotations_worker_spec.rb
new file mode 100644
index 00000000000..bab5a5d8740
--- /dev/null
+++ b/spec/workers/metrics/dashboard/prune_old_annotations_worker_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Metrics::Dashboard::PruneOldAnnotationsWorker do
+ let_it_be(:now) { DateTime.parse('2020-06-02T00:12:00Z') }
+ let_it_be(:two_weeks_old_annotation) { create(:metrics_dashboard_annotation, starting_at: now.advance(weeks: -2)) }
+ let_it_be(:one_day_old_annotation) { create(:metrics_dashboard_annotation, starting_at: now.advance(days: -1)) }
+ let_it_be(:month_old_annotation) { create(:metrics_dashboard_annotation, starting_at: now.advance(months: -1)) }
+
+ describe '#perform' do
+ it 'removes all annotations older than cut off', :aggregate_failures do
+ Timecop.freeze(now) do
+ described_class.new.perform
+
+ expect(Metrics::Dashboard::Annotation.all).to match_array([one_day_old_annotation, two_weeks_old_annotation])
+
+ # is idempotent in the scope of 24h
+ expect { described_class.new.perform }.not_to change { Metrics::Dashboard::Annotation.all.to_a }
+ Timecop.travel(24.hours.from_now) do
+ described_class.new.perform
+ expect(Metrics::Dashboard::Annotation.all).to match_array([one_day_old_annotation])
+ end
+ end
+ end
+
+ context 'batch to be deleted is bigger than upper limit' do
+ it 'schedules second job to clear remaining records' do
+ Timecop.freeze(now) do
+ create(:metrics_dashboard_annotation, starting_at: 1.month.ago)
+ stub_const("#{described_class}::DELETE_LIMIT", 1)
+
+ expect(described_class).to receive(:perform_async)
+
+ described_class.new.perform
+ end
+ end
+ end
+ end
+end
diff --git a/spec/workers/metrics/dashboard/schedule_annotations_prune_worker_spec.rb b/spec/workers/metrics/dashboard/schedule_annotations_prune_worker_spec.rb
new file mode 100644
index 00000000000..bfe6fe3a90e
--- /dev/null
+++ b/spec/workers/metrics/dashboard/schedule_annotations_prune_worker_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Metrics::Dashboard::ScheduleAnnotationsPruneWorker do
+ describe '#perform' do
+ it 'schedules annotations prune job with default cut off date' do
+ expect(Metrics::Dashboard::PruneOldAnnotationsWorker).to receive(:perform_async)
+
+ described_class.new.perform
+ end
+ end
+end
diff --git a/spec/workers/new_note_worker_spec.rb b/spec/workers/new_note_worker_spec.rb
index 387a0958d6b..57269355180 100644
--- a/spec/workers/new_note_worker_spec.rb
+++ b/spec/workers/new_note_worker_spec.rb
@@ -27,7 +27,7 @@ describe NewNoteWorker do
let(:unexistent_note_id) { non_existing_record_id }
it 'logs NewNoteWorker process skipping' do
- expect(Rails.logger).to receive(:error)
+ expect(Gitlab::AppLogger).to receive(:error)
.with("NewNoteWorker: couldn't find note with ID=#{unexistent_note_id}, skipping job")
described_class.new.perform(unexistent_note_id)
@@ -49,4 +49,14 @@ describe NewNoteWorker do
described_class.new.perform(unexistent_note_id)
end
end
+
+ context 'when note is with review' do
+ it 'does not create a new note notification' do
+ note = create(:note, :with_review)
+
+ expect_any_instance_of(NotificationService).not_to receive(:new_note)
+
+ subject.perform(note.id)
+ end
+ end
end
diff --git a/spec/workers/personal_access_tokens/expiring_worker_spec.rb b/spec/workers/personal_access_tokens/expiring_worker_spec.rb
index fcc09e2705c..c8bdf02f4d3 100644
--- a/spec/workers/personal_access_tokens/expiring_worker_spec.rb
+++ b/spec/workers/personal_access_tokens/expiring_worker_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe PersonalAccessTokens::ExpiringWorker, type: :worker do
describe '#perform' do
context 'when a token needs to be notified' do
- let!(:pat) { create(:personal_access_token, expires_at: 5.days.from_now) }
+ let_it_be(:pat) { create(:personal_access_token, expires_at: 5.days.from_now) }
it 'uses notification service to send the email' do
expect_next_instance_of(NotificationService) do |notification_service|
@@ -23,7 +23,7 @@ RSpec.describe PersonalAccessTokens::ExpiringWorker, type: :worker do
end
context 'when no tokens need to be notified' do
- let!(:pat) { create(:personal_access_token, expires_at: 5.days.from_now, expire_notification_delivered: true) }
+ let_it_be(:pat) { create(:personal_access_token, expires_at: 5.days.from_now, expire_notification_delivered: true) }
it "doesn't use notification service to send the email" do
expect_next_instance_of(NotificationService) do |notification_service|
@@ -33,7 +33,23 @@ RSpec.describe PersonalAccessTokens::ExpiringWorker, type: :worker do
worker.perform
end
- it "doesn't change the notificationd delivered of the token" do
+ it "doesn't change the notification delivered of the token" do
+ expect { worker.perform }.not_to change { pat.reload.expire_notification_delivered }
+ end
+ end
+
+ context 'when a token is an impersonation token' do
+ let_it_be(:pat) { create(:personal_access_token, :impersonation, expires_at: 5.days.from_now) }
+
+ it "doesn't use notification service to send the email" do
+ expect_next_instance_of(NotificationService) do |notification_service|
+ expect(notification_service).not_to receive(:access_token_about_to_expire).with(pat.user)
+ end
+
+ worker.perform
+ end
+
+ it "doesn't change the notification delivered of the token" do
expect { worker.perform }.not_to change { pat.reload.expire_notification_delivered }
end
end
diff --git a/spec/workers/pipeline_update_ci_ref_status_worker_service_spec.rb b/spec/workers/pipeline_update_ci_ref_status_worker_service_spec.rb
index 7228de4f895..3fe8aa55142 100644
--- a/spec/workers/pipeline_update_ci_ref_status_worker_service_spec.rb
+++ b/spec/workers/pipeline_update_ci_ref_status_worker_service_spec.rb
@@ -2,6 +2,7 @@
require 'spec_helper'
+# NOTE: This class is unused and to be removed in 13.1~
describe PipelineUpdateCiRefStatusWorker do
let(:worker) { described_class.new }
let(:pipeline) { create(:ci_pipeline) }
diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb
index aab7a36189a..18e06332eb3 100644
--- a/spec/workers/post_receive_spec.rb
+++ b/spec/workers/post_receive_spec.rb
@@ -355,7 +355,7 @@ describe PostReceive do
context "webhook" do
it "fetches the correct project" do
- expect(Project).to receive(:find_by).with(id: project.id.to_s)
+ expect(Project).to receive(:find_by).with(id: project.id)
perform
end
diff --git a/spec/workers/propagate_integration_worker_spec.rb b/spec/workers/propagate_integration_worker_spec.rb
new file mode 100644
index 00000000000..e49869a38e9
--- /dev/null
+++ b/spec/workers/propagate_integration_worker_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe PropagateIntegrationWorker do
+ describe '#perform' do
+ let(:integration) do
+ PushoverService.create(
+ template: true,
+ active: true,
+ device: 'MyDevice',
+ sound: 'mic',
+ priority: 4,
+ user_key: 'asdf',
+ api_key: '123456789'
+ )
+ end
+
+ it 'calls the propagate service with the integration' do
+ expect(Admin::PropagateIntegrationService).to receive(:propagate)
+ .with(integration: integration, overwrite: true)
+
+ subject.perform(integration.id, true)
+ end
+ end
+end
diff --git a/spec/workers/remove_expired_group_links_worker_spec.rb b/spec/workers/remove_expired_group_links_worker_spec.rb
index 9557aa3086c..b637802cd78 100644
--- a/spec/workers/remove_expired_group_links_worker_spec.rb
+++ b/spec/workers/remove_expired_group_links_worker_spec.rb
@@ -23,30 +23,53 @@ describe RemoveExpiredGroupLinksWorker do
subject.perform
expect(non_expiring_project_group_link.reload).to be_present
end
- end
- context 'GroupGroupLinks' do
- let(:mock_destroy_service) { instance_double(Groups::GroupLinks::DestroyService) }
+ it 'removes project authorization' do
+ user = create(:user)
+
+ project = expired_project_group_link.project
+ group = expired_project_group_link.group
+
+ group.add_maintainer(user)
- before do
- allow(Groups::GroupLinks::DestroyService).to(
- receive(:new).and_return(mock_destroy_service))
+ expect { subject.perform }.to(
+ change { user.can?(:read_project, project) }.from(true).to(false))
end
+ end
+ context 'GroupGroupLinks' do
context 'expired GroupGroupLink exists' do
- before do
- create(:group_group_link, expires_at: 1.hour.ago)
- end
+ let!(:group_group_link) { create(:group_group_link, expires_at: 1.hour.ago) }
it 'calls Groups::GroupLinks::DestroyService' do
+ mock_destroy_service = instance_double(Groups::GroupLinks::DestroyService)
+ allow(Groups::GroupLinks::DestroyService).to(
+ receive(:new).and_return(mock_destroy_service))
+
expect(mock_destroy_service).to receive(:execute).once
subject.perform
end
+
+ it 'removes project authorization' do
+ shared_group = group_group_link.shared_group
+ shared_with_group = group_group_link.shared_with_group
+ project = create(:project, group: shared_group)
+
+ user = create(:user)
+ shared_with_group.add_maintainer(user)
+
+ expect { subject.perform }.to(
+ change { user.can?(:read_project, project) }.from(true).to(false))
+ end
end
context 'expired GroupGroupLink does not exist' do
it 'does not call Groups::GroupLinks::DestroyService' do
+ mock_destroy_service = instance_double(Groups::GroupLinks::DestroyService)
+ allow(Groups::GroupLinks::DestroyService).to(
+ receive(:new).and_return(mock_destroy_service))
+
expect(mock_destroy_service).not_to receive(:execute)
subject.perform
diff --git a/spec/workers/repository_check/single_repository_worker_spec.rb b/spec/workers/repository_check/single_repository_worker_spec.rb
index 6870e15424f..43998f912ef 100644
--- a/spec/workers/repository_check/single_repository_worker_spec.rb
+++ b/spec/workers/repository_check/single_repository_worker_spec.rb
@@ -8,7 +8,7 @@ describe RepositoryCheck::SingleRepositoryWorker do
it 'skips when the project has no push events' do
project = create(:project, :repository, :wiki_disabled)
- project.events.destroy_all # rubocop: disable DestroyAll
+ project.events.destroy_all # rubocop: disable Cop/DestroyAll
break_project(project)
expect(worker).not_to receive(:git_fsck)
@@ -86,7 +86,7 @@ describe RepositoryCheck::SingleRepositoryWorker do
end
def create_push_event(project)
- project.events.create(action: Event::PUSHED, author_id: create(:user).id)
+ project.events.create(action: :pushed, author_id: create(:user).id)
end
def break_wiki(project)
diff --git a/spec/workers/stuck_import_jobs_worker_spec.rb b/spec/workers/stuck_import_jobs_worker_spec.rb
index dcb8e59ed28..f8d7f8747d5 100644
--- a/spec/workers/stuck_import_jobs_worker_spec.rb
+++ b/spec/workers/stuck_import_jobs_worker_spec.rb
@@ -5,51 +5,8 @@ require 'spec_helper'
describe StuckImportJobsWorker do
let(:worker) { described_class.new }
- shared_examples 'project import job detection' do
- context 'when the job has completed' do
- context 'when the import status was already updated' do
- before do
- allow(Gitlab::SidekiqStatus).to receive(:completed_jids) do
- import_state.start
- import_state.finish
-
- [import_state.jid]
- end
- end
-
- it 'does not mark the project as failed' do
- worker.perform
-
- expect(import_state.reload.status).to eq('finished')
- end
- end
-
- context 'when the import status was not updated' do
- before do
- allow(Gitlab::SidekiqStatus).to receive(:completed_jids).and_return([import_state.jid])
- end
-
- it 'marks the project as failed' do
- worker.perform
-
- expect(import_state.reload.status).to eq('failed')
- end
- end
- end
-
- context 'when the job is still in Sidekiq' do
- before do
- allow(Gitlab::SidekiqStatus).to receive(:completed_jids).and_return([])
- end
-
- it 'does not mark the project as failed' do
- expect { worker.perform }.not_to change { import_state.reload.status }
- end
- end
- end
-
describe 'with scheduled import_status' do
- it_behaves_like 'project import job detection' do
+ it_behaves_like 'stuck import job detection' do
let(:import_state) { create(:project, :import_scheduled).import_state }
before do
@@ -59,7 +16,7 @@ describe StuckImportJobsWorker do
end
describe 'with started import_status' do
- it_behaves_like 'project import job detection' do
+ it_behaves_like 'stuck import job detection' do
let(:import_state) { create(:project, :import_started).import_state }
before do
diff --git a/tooling/bin/find_foss_tests b/tooling/bin/find_foss_tests
new file mode 100755
index 00000000000..c694210ad40
--- /dev/null
+++ b/tooling/bin/find_foss_tests
@@ -0,0 +1,29 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+require_relative '../../lib/gitlab/popen'
+require_relative '../lib/tooling/test_file_finder'
+
+require 'gitlab'
+
+gitlab_token = ENV.fetch('DANGER_GITLAB_API_TOKEN', '')
+
+Gitlab.configure do |config|
+ config.endpoint = 'https://gitlab.com/api/v4'
+ config.private_token = gitlab_token
+end
+
+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'] }
+
+tests_to_run = changed_files.flat_map do |file|
+ test_files = Tooling::TestFileFinder.new(file, foss_test_only: true).test_files
+ test_files.select { |f| File.exist?(f) }
+end
+
+File.write(output_file, tests_to_run.uniq.join(' '))
diff --git a/tooling/lib/tooling/test_file_finder.rb b/tooling/lib/tooling/test_file_finder.rb
new file mode 100644
index 00000000000..4cf7ad35922
--- /dev/null
+++ b/tooling/lib/tooling/test_file_finder.rb
@@ -0,0 +1,78 @@
+# frozen_string_literal: true
+
+require 'set'
+
+module Tooling
+ class TestFileFinder
+ EE_PREFIX = 'ee/'
+
+ def initialize(file, foss_test_only: false)
+ @file = file
+ @foss_test_only = foss_test_only
+ end
+
+ def test_files
+ impacted_tests = ee_impact | non_ee_impact
+ impacted_tests.impact(@file)
+ end
+
+ private
+
+ attr_reader :file, :foss_test_only, :result
+
+ class ImpactedTestFile
+ attr_reader :pattern_matchers
+
+ def initialize
+ @pattern_matchers = {}
+
+ yield self if block_given?
+ end
+
+ def associate(pattern, &block)
+ @pattern_matchers[pattern] = block
+ end
+
+ def impact(file)
+ @pattern_matchers.each_with_object(Set.new) do |(pattern, block), result|
+ if (match = pattern.match(file))
+ result << block.call(match)
+ end
+ end.to_a
+ end
+
+ def |(other)
+ self.class.new do |combined_matcher|
+ self.pattern_matchers.each do |pattern, block|
+ combined_matcher.associate(pattern, &block)
+ end
+ other.pattern_matchers.each do |pattern, block|
+ combined_matcher.associate(pattern, &block)
+ end
+ end
+ end
+ end
+
+ def ee_impact
+ ImpactedTestFile.new do |impact|
+ unless foss_test_only
+ impact.associate(%r{^#{EE_PREFIX}app/(.+)\.rb$}) { |match| "#{EE_PREFIX}spec/#{match[1]}_spec.rb" }
+ impact.associate(%r{^#{EE_PREFIX}app/(.*/)ee/(.+)\.rb$}) { |match| "#{EE_PREFIX}spec/#{match[1]}#{match[2]}_spec.rb" }
+ impact.associate(%r{^#{EE_PREFIX}lib/(.+)\.rb$}) { |match| "#{EE_PREFIX}spec/lib/#{match[1]}_spec.rb" }
+ impact.associate(%r{^#{EE_PREFIX}spec/(.+)_spec.rb$}) { |match| match[0] }
+ end
+
+ impact.associate(%r{^#{EE_PREFIX}(?!spec)(.*/)ee/(.+)\.rb$}) { |match| "spec/#{match[1]}#{match[2]}_spec.rb" }
+ impact.associate(%r{^#{EE_PREFIX}spec/(.*/)ee/(.+)\.rb$}) { |match| "spec/#{match[1]}#{match[2]}.rb" }
+ end
+ end
+
+ def non_ee_impact
+ ImpactedTestFile.new do |impact|
+ impact.associate(%r{^app/(.+)\.rb$}) { |match| "spec/#{match[1]}_spec.rb" }
+ impact.associate(%r{^(tooling/)?lib/(.+)\.rb$}) { |match| "spec/#{match[1]}lib/#{match[2]}_spec.rb" }
+ impact.associate(%r{^spec/(.+)_spec.rb$}) { |match| match[0] }
+ end
+ end
+ end
+end
diff --git a/tooling/overcommit/Gemfile b/tooling/overcommit/Gemfile
index 5525662e43e..120cb1ad8d0 100644
--- a/tooling/overcommit/Gemfile
+++ b/tooling/overcommit/Gemfile
@@ -4,6 +4,6 @@
source 'https://rubygems.org'
gem 'overcommit'
-gem 'gitlab-styles', '~> 3.1.0', require: false
+gem 'gitlab-styles', '~> 4.2.0', require: false
gem 'scss_lint', '~> 0.56.0', require: false
gem 'haml_lint', '~> 0.34.0', require: false
diff --git a/tooling/overcommit/Gemfile.lock b/tooling/overcommit/Gemfile.lock
index 15b80426c03..7ab10f741ed 100644
--- a/tooling/overcommit/Gemfile.lock
+++ b/tooling/overcommit/Gemfile.lock
@@ -1,55 +1,68 @@
GEM
remote: https://rubygems.org/
specs:
+ activesupport (6.0.3)
+ concurrent-ruby (~> 1.0, >= 1.0.2)
+ i18n (>= 0.7, < 2)
+ minitest (~> 5.1)
+ tzinfo (~> 1.1)
+ zeitwerk (~> 2.2, >= 2.2.2)
ast (2.4.0)
childprocess (3.0.0)
- ffi (1.12.1)
- gitlab-styles (3.1.0)
- rubocop (~> 0.74.0)
+ concurrent-ruby (1.1.6)
+ ffi (1.12.2)
+ gitlab-styles (4.2.0)
+ rubocop (~> 0.82.0)
rubocop-gitlab-security (~> 0.1.0)
- rubocop-performance (~> 1.4.1)
- rubocop-rails (~> 2.0)
+ rubocop-performance (~> 1.5.2)
+ rubocop-rails (~> 2.5)
rubocop-rspec (~> 1.36)
haml (5.1.2)
temple (>= 0.8.0)
tilt
- haml_lint (0.34.1)
+ haml_lint (0.34.0)
haml (>= 4.0, < 5.2)
rainbow
rubocop (>= 0.50.0)
sysexits (~> 1.1)
- iniparse (1.4.4)
+ i18n (1.8.2)
+ concurrent-ruby (~> 1.0)
+ iniparse (1.5.0)
jaro_winkler (1.5.4)
- overcommit (0.52.1)
+ minitest (5.11.3)
+ overcommit (0.53.0)
childprocess (>= 0.6.3, < 4)
iniparse (~> 1.4)
parallel (1.19.1)
- parser (2.7.0.2)
+ parser (2.7.1.2)
ast (~> 2.4.0)
- rack (2.1.1)
+ rack (2.0.9)
rainbow (3.0.0)
rake (12.3.3)
- rb-fsevent (0.10.3)
- rb-inotify (0.10.1)
- ffi (~> 1.0)
- rubocop (0.74.0)
+ rb-fsevent (0.10.2)
+ rb-inotify (0.9.10)
+ ffi (>= 0.5.0, < 2)
+ rexml (3.2.4)
+ rubocop (0.82.0)
jaro_winkler (~> 1.5.1)
parallel (~> 1.10)
- parser (>= 2.6)
+ parser (>= 2.7.0.1)
rainbow (>= 2.2.2, < 4.0)
+ rexml
ruby-progressbar (~> 1.7)
- unicode-display_width (>= 1.4.0, < 1.7)
+ unicode-display_width (>= 1.4.0, < 2.0)
rubocop-gitlab-security (0.1.1)
rubocop (>= 0.51)
- rubocop-performance (1.4.1)
+ rubocop-performance (1.5.2)
rubocop (>= 0.71.0)
- rubocop-rails (2.4.1)
+ rubocop-rails (2.5.2)
+ activesupport
rack (>= 1.1)
rubocop (>= 0.72.0)
- rubocop-rspec (1.37.1)
+ rubocop-rspec (1.37.0)
rubocop (>= 0.68.1)
ruby-progressbar (1.10.1)
- sass (3.5.7)
+ sass (3.5.5)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
@@ -59,14 +72,18 @@ GEM
sass (~> 3.5.3)
sysexits (1.2.0)
temple (0.8.2)
+ thread_safe (0.3.6)
tilt (2.0.10)
- unicode-display_width (1.6.1)
+ tzinfo (1.2.7)
+ thread_safe (~> 0.1)
+ unicode-display_width (1.7.0)
+ zeitwerk (2.3.0)
PLATFORMS
ruby
DEPENDENCIES
- gitlab-styles (~> 3.1.0)
+ gitlab-styles (~> 4.2.0)
haml_lint (~> 0.34.0)
overcommit
scss_lint (~> 0.56.0)
diff --git a/vendor/gitignore/C++.gitignore b/vendor/gitignore/C++.gitignore
index 259148fa18f..259148fa18f 100755..100644
--- a/vendor/gitignore/C++.gitignore
+++ b/vendor/gitignore/C++.gitignore
diff --git a/vendor/gitignore/Java.gitignore b/vendor/gitignore/Java.gitignore
index a1c2a238a96..a1c2a238a96 100755..100644
--- a/vendor/gitignore/Java.gitignore
+++ b/vendor/gitignore/Java.gitignore
diff --git a/vendor/project_templates/learn_gitlab.tar.gz b/vendor/project_templates/learn_gitlab.tar.gz
new file mode 100644
index 00000000000..249f25bc85c
--- /dev/null
+++ b/vendor/project_templates/learn_gitlab.tar.gz
Binary files differ
diff --git a/yarn.lock b/yarn.lock
index f6672fc96c8..3b3766f540a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,342 +2,350 @@
# yarn lockfile v1
-"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e"
- integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==
+"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.1.tgz#d5481c5095daa1c57e16e54c6f9198443afb49ff"
+ integrity sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==
dependencies:
- "@babel/highlight" "^7.8.3"
+ "@babel/highlight" "^7.10.1"
-"@babel/compat-data@^7.8.4":
- version "7.8.5"
- resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.8.5.tgz#d28ce872778c23551cbb9432fc68d28495b613b9"
- integrity sha512-jWYUqQX/ObOhG1UiEkbH5SANsE/8oKXiQWjj7p7xgj9Zmnt//aUvyz4dBkK0HNsS8/cbyC5NmmH87VekW+mXFg==
+"@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.8.5"
+ browserslist "^4.12.0"
invariant "^2.2.4"
semver "^5.5.0"
-"@babel/core@>=7.2.2", "@babel/core@^7.1.0", "@babel/core@^7.8.4":
- version "7.8.4"
- resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.8.4.tgz#d496799e5c12195b3602d0fddd77294e3e38e80e"
- integrity sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA==
- dependencies:
- "@babel/code-frame" "^7.8.3"
- "@babel/generator" "^7.8.4"
- "@babel/helpers" "^7.8.4"
- "@babel/parser" "^7.8.4"
- "@babel/template" "^7.8.3"
- "@babel/traverse" "^7.8.4"
- "@babel/types" "^7.8.3"
+"@babel/core@>=7.2.2", "@babel/core@^7.1.0", "@babel/core@^7.10.1":
+ version "7.10.2"
+ resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.10.2.tgz#bd6786046668a925ac2bd2fd95b579b92a23b36a"
+ integrity sha512-KQmV9yguEjQsXqyOUGKjS4+3K8/DlOCE2pZcq4augdQmtTy5iv5EHtmMSJ7V4c1BIPjuwtZYqYLCq9Ga+hGBRQ==
+ dependencies:
+ "@babel/code-frame" "^7.10.1"
+ "@babel/generator" "^7.10.2"
+ "@babel/helper-module-transforms" "^7.10.1"
+ "@babel/helpers" "^7.10.1"
+ "@babel/parser" "^7.10.2"
+ "@babel/template" "^7.10.1"
+ "@babel/traverse" "^7.10.1"
+ "@babel/types" "^7.10.2"
convert-source-map "^1.7.0"
debug "^4.1.0"
gensync "^1.0.0-beta.1"
- json5 "^2.1.0"
+ json5 "^2.1.2"
lodash "^4.17.13"
resolve "^1.3.2"
semver "^5.4.1"
source-map "^0.5.0"
-"@babel/generator@^7.4.0", "@babel/generator@^7.8.4":
- version "7.8.4"
- resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.8.4.tgz#35bbc74486956fe4251829f9f6c48330e8d0985e"
- integrity sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==
+"@babel/generator@^7.10.1", "@babel/generator@^7.10.2", "@babel/generator@^7.4.0":
+ version "7.10.2"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.10.2.tgz#0fa5b5b2389db8bfdfcc3492b551ee20f5dd69a9"
+ integrity sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==
dependencies:
- "@babel/types" "^7.8.3"
+ "@babel/types" "^7.10.2"
jsesc "^2.5.1"
lodash "^4.17.13"
source-map "^0.5.0"
-"@babel/helper-annotate-as-pure@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz#60bc0bc657f63a0924ff9a4b4a0b24a13cf4deee"
- integrity sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw==
- dependencies:
- "@babel/types" "^7.8.3"
-
-"@babel/helper-builder-binary-assignment-operator-visitor@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.8.3.tgz#c84097a427a061ac56a1c30ebf54b7b22d241503"
- integrity sha512-5eFOm2SyFPK4Rh3XMMRDjN7lBH0orh3ss0g3rTYZnBQ+r6YPj7lgDyCvPphynHvUrobJmeMignBr6Acw9mAPlw==
+"@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==
dependencies:
- "@babel/helper-explode-assignable-expression" "^7.8.3"
- "@babel/types" "^7.8.3"
+ "@babel/types" "^7.10.1"
-"@babel/helper-call-delegate@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.8.3.tgz#de82619898aa605d409c42be6ffb8d7204579692"
- integrity sha512-6Q05px0Eb+N4/GTyKPPvnkig7Lylw+QzihMpws9iiZQv7ZImf84ZsZpQH7QoWN4n4tm81SnSzPgHw2qtO0Zf3A==
+"@babel/helper-builder-binary-assignment-operator-visitor@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.1.tgz#0ec7d9be8174934532661f87783eb18d72290059"
+ integrity sha512-cQpVq48EkYxUU0xozpGCLla3wlkdRRqLWu1ksFMXA9CM5KQmyyRpSEsYXbao7JUkOw/tAaYKCaYyZq6HOFYtyw==
dependencies:
- "@babel/helper-hoist-variables" "^7.8.3"
- "@babel/traverse" "^7.8.3"
- "@babel/types" "^7.8.3"
+ "@babel/helper-explode-assignable-expression" "^7.10.1"
+ "@babel/types" "^7.10.1"
-"@babel/helper-compilation-targets@^7.8.4":
- version "7.8.4"
- resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.4.tgz#03d7ecd454b7ebe19a254f76617e61770aed2c88"
- integrity sha512-3k3BsKMvPp5bjxgMdrFyq0UaEO48HciVrOVF0+lon8pp95cyJ2ujAh0TrBHNMnJGT2rr0iKOJPFFbSqjDyf/Pg==
+"@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==
dependencies:
- "@babel/compat-data" "^7.8.4"
- browserslist "^4.8.5"
+ "@babel/compat-data" "^7.10.1"
+ browserslist "^4.12.0"
invariant "^2.2.4"
levenary "^1.1.1"
semver "^5.5.0"
-"@babel/helper-create-class-features-plugin@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.8.3.tgz#5b94be88c255f140fd2c10dd151e7f98f4bff397"
- integrity sha512-qmp4pD7zeTxsv0JNecSBsEmG1ei2MqwJq4YQcK3ZWm/0t07QstWfvuV/vm3Qt5xNMFETn2SZqpMx2MQzbtq+KA==
- dependencies:
- "@babel/helper-function-name" "^7.8.3"
- "@babel/helper-member-expression-to-functions" "^7.8.3"
- "@babel/helper-optimise-call-expression" "^7.8.3"
- "@babel/helper-plugin-utils" "^7.8.3"
- "@babel/helper-replace-supers" "^7.8.3"
- "@babel/helper-split-export-declaration" "^7.8.3"
-
-"@babel/helper-create-regexp-features-plugin@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.3.tgz#c774268c95ec07ee92476a3862b75cc2839beb79"
- integrity sha512-Gcsm1OHCUr9o9TcJln57xhWHtdXbA2pgQ58S0Lxlks0WMGNXuki4+GLfX0p+L2ZkINUGZvfkz8rzoqJQSthI+Q==
- dependencies:
- "@babel/helper-regex" "^7.8.3"
- regexpu-core "^4.6.0"
-
-"@babel/helper-define-map@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.8.3.tgz#a0655cad5451c3760b726eba875f1cd8faa02c15"
- integrity sha512-PoeBYtxoZGtct3md6xZOCWPcKuMuk3IHhgxsRRNtnNShebf4C8YonTSblsK4tvDbm+eJAw2HAPOfCr+Q/YRG/g==
- dependencies:
- "@babel/helper-function-name" "^7.8.3"
- "@babel/types" "^7.8.3"
+"@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==
+ 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-create-regexp-features-plugin@^7.10.1", "@babel/helper-create-regexp-features-plugin@^7.8.3":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.1.tgz#1b8feeab1594cbcfbf3ab5a3bbcabac0468efdbd"
+ integrity sha512-Rx4rHS0pVuJn5pJOqaqcZR4XSgeF9G/pO/79t+4r7380tXFJdzImFnxMU19f83wjSrmKHq6myrM10pFHTGzkUA==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.10.1"
+ "@babel/helper-regex" "^7.10.1"
+ regexpu-core "^4.7.0"
+
+"@babel/helper-define-map@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.1.tgz#5e69ee8308648470dd7900d159c044c10285221d"
+ integrity sha512-+5odWpX+OnvkD0Zmq7panrMuAGQBu6aPUgvMzuMGo4R+jUOvealEj2hiqI6WhxgKrTpFoFj0+VdsuA8KDxHBDg==
+ dependencies:
+ "@babel/helper-function-name" "^7.10.1"
+ "@babel/types" "^7.10.1"
lodash "^4.17.13"
-"@babel/helper-explode-assignable-expression@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.8.3.tgz#a728dc5b4e89e30fc2dfc7d04fa28a930653f982"
- integrity sha512-N+8eW86/Kj147bO9G2uclsg5pwfs/fqqY5rwgIL7eTBklgXjcOJ3btzS5iM6AitJcftnY7pm2lGsrJVYLGjzIw==
- dependencies:
- "@babel/traverse" "^7.8.3"
- "@babel/types" "^7.8.3"
-
-"@babel/helper-function-name@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz#eeeb665a01b1f11068e9fb86ad56a1cb1a824cca"
- integrity sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==
+"@babel/helper-explode-assignable-expression@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.1.tgz#e9d76305ee1162ca467357ae25df94f179af2b7e"
+ integrity sha512-vcUJ3cDjLjvkKzt6rHrl767FeE7pMEYfPanq5L16GRtrXIoznc0HykNW2aEYkcnP76P0isoqJ34dDMFZwzEpJg==
dependencies:
- "@babel/helper-get-function-arity" "^7.8.3"
- "@babel/template" "^7.8.3"
- "@babel/types" "^7.8.3"
+ "@babel/traverse" "^7.10.1"
+ "@babel/types" "^7.10.1"
-"@babel/helper-get-function-arity@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz#b894b947bd004381ce63ea1db9f08547e920abd5"
- integrity sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==
+"@babel/helper-function-name@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz#92bd63829bfc9215aca9d9defa85f56b539454f4"
+ integrity sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==
dependencies:
- "@babel/types" "^7.8.3"
+ "@babel/helper-get-function-arity" "^7.10.1"
+ "@babel/template" "^7.10.1"
+ "@babel/types" "^7.10.1"
-"@babel/helper-hoist-variables@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.8.3.tgz#1dbe9b6b55d78c9b4183fc8cdc6e30ceb83b7134"
- integrity sha512-ky1JLOjcDUtSc+xkt0xhYff7Z6ILTAHKmZLHPxAhOP0Nd77O+3nCsd6uSVYur6nJnCI029CrNbYlc0LoPfAPQg==
+"@babel/helper-get-function-arity@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz#7303390a81ba7cb59613895a192b93850e373f7d"
+ integrity sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==
dependencies:
- "@babel/types" "^7.8.3"
+ "@babel/types" "^7.10.1"
-"@babel/helper-member-expression-to-functions@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz#659b710498ea6c1d9907e0c73f206eee7dadc24c"
- integrity sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==
+"@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==
dependencies:
- "@babel/types" "^7.8.3"
+ "@babel/types" "^7.10.1"
-"@babel/helper-module-imports@^7.0.0-beta.49", "@babel/helper-module-imports@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz#7fe39589b39c016331b6b8c3f441e8f0b1419498"
- integrity sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==
+"@babel/helper-member-expression-to-functions@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.1.tgz#432967fd7e12a4afef66c4687d4ca22bc0456f15"
+ integrity sha512-u7XLXeM2n50gb6PWJ9hoO5oO7JFPaZtrh35t8RqKLT1jFKj9IWeD1zrcrYp1q1qiZTdEarfDWfTIP8nGsu0h5g==
dependencies:
- "@babel/types" "^7.8.3"
+ "@babel/types" "^7.10.1"
-"@babel/helper-module-transforms@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.8.3.tgz#d305e35d02bee720fbc2c3c3623aa0c316c01590"
- integrity sha512-C7NG6B7vfBa/pwCOshpMbOYUmrYQDfCpVL/JCRu0ek8B5p8kue1+BCXpg2vOYs7w5ACB9GTOBYQ5U6NwrMg+3Q==
- dependencies:
- "@babel/helper-module-imports" "^7.8.3"
- "@babel/helper-simple-access" "^7.8.3"
- "@babel/helper-split-export-declaration" "^7.8.3"
- "@babel/template" "^7.8.3"
- "@babel/types" "^7.8.3"
- lodash "^4.17.13"
-
-"@babel/helper-optimise-call-expression@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz#7ed071813d09c75298ef4f208956006b6111ecb9"
- integrity sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==
+"@babel/helper-module-imports@^7.0.0-beta.49", "@babel/helper-module-imports@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz#dd331bd45bccc566ce77004e9d05fe17add13876"
+ integrity sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg==
dependencies:
- "@babel/types" "^7.8.3"
+ "@babel/types" "^7.10.1"
-"@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz#9ea293be19babc0f52ff8ca88b34c3611b208670"
- integrity sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==
-
-"@babel/helper-regex@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.8.3.tgz#139772607d51b93f23effe72105b319d2a4c6965"
- integrity sha512-BWt0QtYv/cg/NecOAZMdcn/waj/5P26DR4mVLXfFtDokSR6fyuG0Pj+e2FqtSME+MqED1khnSMulkmGl8qWiUQ==
+"@babel/helper-module-transforms@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.10.1.tgz#24e2f08ee6832c60b157bb0936c86bef7210c622"
+ integrity sha512-RLHRCAzyJe7Q7sF4oy2cB+kRnU4wDZY/H2xJFGof+M+SJEGhZsb+GFj5j1AD8NiSaVBJ+Pf0/WObiXu/zxWpFg==
dependencies:
+ "@babel/helper-module-imports" "^7.10.1"
+ "@babel/helper-replace-supers" "^7.10.1"
+ "@babel/helper-simple-access" "^7.10.1"
+ "@babel/helper-split-export-declaration" "^7.10.1"
+ "@babel/template" "^7.10.1"
+ "@babel/types" "^7.10.1"
lodash "^4.17.13"
-"@babel/helper-remap-async-to-generator@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.8.3.tgz#273c600d8b9bf5006142c1e35887d555c12edd86"
- integrity sha512-kgwDmw4fCg7AVgS4DukQR/roGp+jP+XluJE5hsRZwxCYGg+Rv9wSGErDWhlI90FODdYfd4xG4AQRiMDjjN0GzA==
- dependencies:
- "@babel/helper-annotate-as-pure" "^7.8.3"
- "@babel/helper-wrap-function" "^7.8.3"
- "@babel/template" "^7.8.3"
- "@babel/traverse" "^7.8.3"
- "@babel/types" "^7.8.3"
-
-"@babel/helper-replace-supers@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.8.3.tgz#91192d25f6abbcd41da8a989d4492574fb1530bc"
- integrity sha512-xOUssL6ho41U81etpLoT2RTdvdus4VfHamCuAm4AHxGr+0it5fnwoVdwUJ7GFEqCsQYzJUhcbsN9wB9apcYKFA==
- dependencies:
- "@babel/helper-member-expression-to-functions" "^7.8.3"
- "@babel/helper-optimise-call-expression" "^7.8.3"
- "@babel/traverse" "^7.8.3"
- "@babel/types" "^7.8.3"
-
-"@babel/helper-simple-access@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz#7f8109928b4dab4654076986af575231deb639ae"
- integrity sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==
+"@babel/helper-optimise-call-expression@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.1.tgz#b4a1f2561870ce1247ceddb02a3860fa96d72543"
+ integrity sha512-a0DjNS1prnBsoKx83dP2falChcs7p3i8VMzdrSbfLhuQra/2ENC4sbri34dz/rWmDADsmF1q5GbfaXydh0Jbjg==
dependencies:
- "@babel/template" "^7.8.3"
- "@babel/types" "^7.8.3"
+ "@babel/types" "^7.10.1"
-"@babel/helper-split-export-declaration@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz#31a9f30070f91368a7182cf05f831781065fc7a9"
- integrity sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==
- dependencies:
- "@babel/types" "^7.8.3"
-
-"@babel/helper-wrap-function@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz#9dbdb2bb55ef14aaa01fe8c99b629bd5352d8610"
- integrity sha512-LACJrbUET9cQDzb6kG7EeD7+7doC3JNvUgTEQOx2qaO1fKlzE/Bf05qs9w1oXQMmXlPO65lC3Tq9S6gZpTErEQ==
- dependencies:
- "@babel/helper-function-name" "^7.8.3"
- "@babel/template" "^7.8.3"
- "@babel/traverse" "^7.8.3"
- "@babel/types" "^7.8.3"
+"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.1", "@babel/helper-plugin-utils@^7.8.0":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.1.tgz#ec5a5cf0eec925b66c60580328b122c01230a127"
+ integrity sha512-fvoGeXt0bJc7VMWZGCAEBEMo/HAjW2mP8apF5eXK0wSqwLAVHAISCWRoLMBMUs2kqeaG77jltVqu4Hn8Egl3nA==
-"@babel/helpers@^7.8.4":
- version "7.8.4"
- resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.8.4.tgz#754eb3ee727c165e0a240d6c207de7c455f36f73"
- integrity sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==
+"@babel/helper-regex@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.10.1.tgz#021cf1a7ba99822f993222a001cc3fec83255b96"
+ integrity sha512-7isHr19RsIJWWLLFn21ubFt223PjQyg1HY7CZEMRr820HttHPpVvrsIN3bUOo44DEfFV4kBXO7Abbn9KTUZV7g==
dependencies:
- "@babel/template" "^7.8.3"
- "@babel/traverse" "^7.8.4"
- "@babel/types" "^7.8.3"
+ lodash "^4.17.13"
-"@babel/highlight@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.8.3.tgz#28f173d04223eaaa59bc1d439a3836e6d1265797"
- integrity sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==
- dependencies:
+"@babel/helper-remap-async-to-generator@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.1.tgz#bad6aaa4ff39ce8d4b82ccaae0bfe0f7dbb5f432"
+ integrity sha512-RfX1P8HqsfgmJ6CwaXGKMAqbYdlleqglvVtht0HGPMSsy2V6MqLlOJVF/0Qyb/m2ZCi2z3q3+s6Pv7R/dQuZ6A==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.10.1"
+ "@babel/helper-wrap-function" "^7.10.1"
+ "@babel/template" "^7.10.1"
+ "@babel/traverse" "^7.10.1"
+ "@babel/types" "^7.10.1"
+
+"@babel/helper-replace-supers@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz#ec6859d20c5d8087f6a2dc4e014db7228975f13d"
+ integrity sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A==
+ dependencies:
+ "@babel/helper-member-expression-to-functions" "^7.10.1"
+ "@babel/helper-optimise-call-expression" "^7.10.1"
+ "@babel/traverse" "^7.10.1"
+ "@babel/types" "^7.10.1"
+
+"@babel/helper-simple-access@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.10.1.tgz#08fb7e22ace9eb8326f7e3920a1c2052f13d851e"
+ integrity sha512-VSWpWzRzn9VtgMJBIWTZ+GP107kZdQ4YplJlCmIrjoLVSi/0upixezHCDG8kpPVTBJpKfxTH01wDhh+jS2zKbw==
+ dependencies:
+ "@babel/template" "^7.10.1"
+ "@babel/types" "^7.10.1"
+
+"@babel/helper-split-export-declaration@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz#c6f4be1cbc15e3a868e4c64a17d5d31d754da35f"
+ integrity sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==
+ dependencies:
+ "@babel/types" "^7.10.1"
+
+"@babel/helper-validator-identifier@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz#5770b0c1a826c4f53f5ede5e153163e0318e94b5"
+ integrity sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==
+
+"@babel/helper-wrap-function@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.10.1.tgz#956d1310d6696257a7afd47e4c42dfda5dfcedc9"
+ integrity sha512-C0MzRGteVDn+H32/ZgbAv5r56f2o1fZSA/rj/TYo8JEJNHg+9BdSmKBUND0shxWRztWhjlT2cvHYuynpPsVJwQ==
+ dependencies:
+ "@babel/helper-function-name" "^7.10.1"
+ "@babel/template" "^7.10.1"
+ "@babel/traverse" "^7.10.1"
+ "@babel/types" "^7.10.1"
+
+"@babel/helpers@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.1.tgz#a6827b7cb975c9d9cef5fd61d919f60d8844a973"
+ integrity sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw==
+ dependencies:
+ "@babel/template" "^7.10.1"
+ "@babel/traverse" "^7.10.1"
+ "@babel/types" "^7.10.1"
+
+"@babel/highlight@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.1.tgz#841d098ba613ba1a427a2b383d79e35552c38ae0"
+ integrity sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==
+ dependencies:
+ "@babel/helper-validator-identifier" "^7.10.1"
chalk "^2.0.0"
- esutils "^2.0.2"
js-tokens "^4.0.0"
-"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.8.3", "@babel/parser@^7.8.4":
- version "7.8.4"
- resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.4.tgz#d1dbe64691d60358a974295fa53da074dd2ce8e8"
- integrity sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==
+"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.10.1", "@babel/parser@^7.10.2", "@babel/parser@^7.4.3":
+ version "7.10.2"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.2.tgz#871807f10442b92ff97e4783b9b54f6a0ca812d0"
+ integrity sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==
-"@babel/plugin-proposal-async-generator-functions@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.8.3.tgz#bad329c670b382589721b27540c7d288601c6e6f"
- integrity sha512-NZ9zLv848JsV3hs8ryEh7Uaz/0KsmPLqv0+PdkDJL1cJy0K4kOCFa8zc1E3mp+RHPQcpdfb/6GovEsW4VDrOMw==
+"@babel/plugin-proposal-async-generator-functions@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.1.tgz#6911af5ba2e615c4ff3c497fe2f47b35bf6d7e55"
+ integrity sha512-vzZE12ZTdB336POZjmpblWfNNRpMSua45EYnRigE2XsZxcXcIyly2ixnTJasJE4Zq3U7t2d8rRF7XRUuzHxbOw==
dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
- "@babel/helper-remap-async-to-generator" "^7.8.3"
+ "@babel/helper-plugin-utils" "^7.10.1"
+ "@babel/helper-remap-async-to-generator" "^7.10.1"
"@babel/plugin-syntax-async-generators" "^7.8.0"
-"@babel/plugin-proposal-class-properties@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.8.3.tgz#5e06654af5cd04b608915aada9b2a6788004464e"
- integrity sha512-EqFhbo7IosdgPgZggHaNObkmO1kNUe3slaKu54d5OWvy+p9QIKOzK1GAEpAIsZtWVtPXUHSMcT4smvDrCfY4AA==
+"@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==
dependencies:
- "@babel/helper-create-class-features-plugin" "^7.8.3"
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-create-class-features-plugin" "^7.10.1"
+ "@babel/helper-plugin-utils" "^7.10.1"
-"@babel/plugin-proposal-dynamic-import@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.8.3.tgz#38c4fe555744826e97e2ae930b0fb4cc07e66054"
- integrity sha512-NyaBbyLFXFLT9FP+zk0kYlUlA8XtCUbehs67F0nnEg7KICgMc2mNkIeu9TYhKzyXMkrapZFwAhXLdnt4IYHy1w==
+"@babel/plugin-proposal-dynamic-import@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.1.tgz#e36979dc1dc3b73f6d6816fc4951da2363488ef0"
+ integrity sha512-Cpc2yUVHTEGPlmiQzXj026kqwjEQAD9I4ZC16uzdbgWgitg/UHKHLffKNCQZ5+y8jpIZPJcKcwsr2HwPh+w3XA==
dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-plugin-utils" "^7.10.1"
"@babel/plugin-syntax-dynamic-import" "^7.8.0"
-"@babel/plugin-proposal-json-strings@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.8.3.tgz#da5216b238a98b58a1e05d6852104b10f9a70d6b"
- integrity sha512-KGhQNZ3TVCQG/MjRbAUwuH+14y9q0tpxs1nWWs3pbSleRdDro9SAMMDyye8HhY1gqZ7/NqIc8SKhya0wRDgP1Q==
+"@babel/plugin-proposal-json-strings@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.1.tgz#b1e691ee24c651b5a5e32213222b2379734aff09"
+ integrity sha512-m8r5BmV+ZLpWPtMY2mOKN7wre6HIO4gfIiV+eOmsnZABNenrt/kzYBwrh+KOfgumSWpnlGs5F70J8afYMSJMBg==
dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-plugin-utils" "^7.10.1"
"@babel/plugin-syntax-json-strings" "^7.8.0"
-"@babel/plugin-proposal-nullish-coalescing-operator@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz#e4572253fdeed65cddeecfdab3f928afeb2fd5d2"
- integrity sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw==
+"@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==
dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-plugin-utils" "^7.10.1"
"@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0"
-"@babel/plugin-proposal-object-rest-spread@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.8.3.tgz#eb5ae366118ddca67bed583b53d7554cad9951bb"
- integrity sha512-8qvuPwU/xxUCt78HocNlv0mXXo0wdh9VT1R04WU8HGOfaOob26pF+9P5/lYjN/q7DHOX1bvX60hnhOvuQUJdbA==
+"@babel/plugin-proposal-numeric-separator@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.1.tgz#a9a38bc34f78bdfd981e791c27c6fdcec478c123"
+ integrity sha512-jjfym4N9HtCiNfyyLAVD8WqPYeHUrw4ihxuAynWj6zzp2gf9Ey2f7ImhFm6ikB3CLf5Z/zmcJDri6B4+9j9RsA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.10.1"
+ "@babel/plugin-syntax-numeric-separator" "^7.10.1"
+
+"@babel/plugin-proposal-object-rest-spread@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.1.tgz#cba44908ac9f142650b4a65b8aa06bf3478d5fb6"
+ integrity sha512-Z+Qri55KiQkHh7Fc4BW6o+QBuTagbOp9txE+4U1i79u9oWlf2npkiDx+Rf3iK3lbcHBuNy9UOkwuR5wOMH3LIQ==
dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-plugin-utils" "^7.10.1"
"@babel/plugin-syntax-object-rest-spread" "^7.8.0"
+ "@babel/plugin-transform-parameters" "^7.10.1"
-"@babel/plugin-proposal-optional-catch-binding@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.8.3.tgz#9dee96ab1650eed88646ae9734ca167ac4a9c5c9"
- integrity sha512-0gkX7J7E+AtAw9fcwlVQj8peP61qhdg/89D5swOkjYbkboA2CVckn3kiyum1DE0wskGb7KJJxBdyEBApDLLVdw==
+"@babel/plugin-proposal-optional-catch-binding@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.1.tgz#c9f86d99305f9fa531b568ff5ab8c964b8b223d2"
+ integrity sha512-VqExgeE62YBqI3ogkGoOJp1R6u12DFZjqwJhqtKc2o5m1YTUuUWnos7bZQFBhwkxIFpWYJ7uB75U7VAPPiKETA==
dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-plugin-utils" "^7.10.1"
"@babel/plugin-syntax-optional-catch-binding" "^7.8.0"
-"@babel/plugin-proposal-optional-chaining@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.8.3.tgz#ae10b3214cb25f7adb1f3bc87ba42ca10b7e2543"
- integrity sha512-QIoIR9abkVn+seDE3OjA08jWcs3eZ9+wJCKSRgo3WdEU2csFYgdScb+8qHB3+WXsGJD55u+5hWCISI7ejXS+kg==
+"@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==
dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-plugin-utils" "^7.10.1"
"@babel/plugin-syntax-optional-chaining" "^7.8.0"
-"@babel/plugin-proposal-private-methods@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.8.3.tgz#01248c6c8dc292116b3b4ebd746150f4f0728bab"
- integrity sha512-ysLAper960yy1TVXa2lMYdCQIGqtUXo8sVb+zYE7UTiZSLs6/wbZ0PrrXEKESJcK3SgFWrF8WpsaDzdslhuoZA==
+"@babel/plugin-proposal-private-methods@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.1.tgz#ed85e8058ab0fe309c3f448e5e1b73ca89cdb598"
+ integrity sha512-RZecFFJjDiQ2z6maFprLgrdnm0OzoC23Mx89xf1CcEsxmHuzuXOdniEuI+S3v7vjQG4F5sa6YtUp+19sZuSxHg==
dependencies:
- "@babel/helper-create-class-features-plugin" "^7.8.3"
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-create-class-features-plugin" "^7.10.1"
+ "@babel/helper-plugin-utils" "^7.10.1"
-"@babel/plugin-proposal-unicode-property-regex@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.3.tgz#b646c3adea5f98800c9ab45105ac34d06cd4a47f"
- integrity sha512-1/1/rEZv2XGweRwwSkLpY+s60za9OZ1hJs4YDqFHCw0kYWYwL5IFljVY1MYBL+weT1l9pokDO2uhSTLVxzoHkQ==
+"@babel/plugin-proposal-unicode-property-regex@^7.10.1", "@babel/plugin-proposal-unicode-property-regex@^7.4.4":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.1.tgz#dc04feb25e2dd70c12b05d680190e138fa2c0c6f"
+ integrity sha512-JjfngYRvwmPwmnbRZyNiPFI8zxCZb8euzbCG/LxyKdeTb59tVciKo9GK9bi6JYKInk1H11Dq9j/zRqIH4KigfQ==
dependencies:
- "@babel/helper-create-regexp-features-plugin" "^7.8.3"
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-create-regexp-features-plugin" "^7.10.1"
+ "@babel/helper-plugin-utils" "^7.10.1"
"@babel/plugin-syntax-async-generators@^7.8.0":
version "7.8.4"
@@ -346,6 +354,13 @@
dependencies:
"@babel/helper-plugin-utils" "^7.8.0"
+"@babel/plugin-syntax-class-properties@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.1.tgz#d5bc0645913df5b17ad7eda0fa2308330bde34c5"
+ integrity sha512-Gf2Yx/iRs1JREDtVZ56OrjjgFHCaldpTnuy9BHla10qyVT3YkIIGEtoDWhyop0ksu1GvNjHIoYRBqm3zoR1jyQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.10.1"
+
"@babel/plugin-syntax-dynamic-import@^7.8.0":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3"
@@ -353,12 +368,12 @@
dependencies:
"@babel/helper-plugin-utils" "^7.8.0"
-"@babel/plugin-syntax-import-meta@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.8.3.tgz#230afff79d3ccc215b5944b438e4e266daf3d84d"
- integrity sha512-vYiGd4wQ9gx0Lngb7+bPCwQXGK/PR6FeTIJ+TIOlq+OfOKG/kCAOO2+IBac3oMM9qV7/fU76hfcqxUaLKZf1hQ==
+"@babel/plugin-syntax-import-meta@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.1.tgz#3e59120ed8b3c2ccc5abb1cfc7aaa3ea01cd36b6"
+ integrity sha512-ypC4jwfIVF72og0dgvEcFRdOM2V9Qm1tu7RGmdZOlhsccyK0wisXmMObGuWEOd5jQ+K9wcIgSNftCpk2vkjUfQ==
dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-plugin-utils" "^7.10.1"
"@babel/plugin-syntax-json-strings@^7.8.0":
version "7.8.3"
@@ -374,6 +389,13 @@
dependencies:
"@babel/helper-plugin-utils" "^7.8.0"
+"@babel/plugin-syntax-numeric-separator@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.1.tgz#25761ee7410bc8cf97327ba741ee94e4a61b7d99"
+ integrity sha512-uTd0OsHrpe3tH5gRPTxG8Voh99/WCU78vIm5NMRYPAqC8lR4vajt6KkCAknCHrx24vkPdd/05yfdGSB4EIY2mg==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.10.1"
+
"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.8.0":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871"
@@ -395,160 +417,160 @@
dependencies:
"@babel/helper-plugin-utils" "^7.8.0"
-"@babel/plugin-syntax-top-level-await@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.8.3.tgz#3acdece695e6b13aaf57fc291d1a800950c71391"
- integrity sha512-kwj1j9lL/6Wd0hROD3b/OZZ7MSrZLqqn9RAZ5+cYYsflQ9HZBIKCUkr3+uL1MEJ1NePiUbf98jjiMQSv0NMR9g==
+"@babel/plugin-syntax-top-level-await@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.1.tgz#8b8733f8c57397b3eaa47ddba8841586dcaef362"
+ integrity sha512-hgA5RYkmZm8FTFT3yu2N9Bx7yVVOKYT6yEdXXo6j2JTm0wNxgqaGeQVaSHRjhfnQbX91DtjFB6McRFSlcJH3xQ==
dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-plugin-utils" "^7.10.1"
-"@babel/plugin-transform-arrow-functions@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz#82776c2ed0cd9e1a49956daeb896024c9473b8b6"
- integrity sha512-0MRF+KC8EqH4dbuITCWwPSzsyO3HIWWlm30v8BbbpOrS1B++isGxPnnuq/IZvOX5J2D/p7DQalQm+/2PnlKGxg==
+"@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"
+ integrity sha512-6AZHgFJKP3DJX0eCNJj01RpytUa3SOGawIxweHkNX2L6PYikOZmoh5B0d7hIHaIgveMjX990IAa/xK7jRTN8OA==
dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-plugin-utils" "^7.10.1"
-"@babel/plugin-transform-async-to-generator@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.8.3.tgz#4308fad0d9409d71eafb9b1a6ee35f9d64b64086"
- integrity sha512-imt9tFLD9ogt56Dd5CI/6XgpukMwd/fLGSrix2httihVe7LOGVPhyhMh1BU5kDM7iHD08i8uUtmV2sWaBFlHVQ==
+"@babel/plugin-transform-async-to-generator@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.1.tgz#e5153eb1a3e028f79194ed8a7a4bf55f862b2062"
+ integrity sha512-XCgYjJ8TY2slj6SReBUyamJn3k2JLUIiiR5b6t1mNCMSvv7yx+jJpaewakikp0uWFQSF7ChPPoe3dHmXLpISkg==
dependencies:
- "@babel/helper-module-imports" "^7.8.3"
- "@babel/helper-plugin-utils" "^7.8.3"
- "@babel/helper-remap-async-to-generator" "^7.8.3"
+ "@babel/helper-module-imports" "^7.10.1"
+ "@babel/helper-plugin-utils" "^7.10.1"
+ "@babel/helper-remap-async-to-generator" "^7.10.1"
-"@babel/plugin-transform-block-scoped-functions@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.8.3.tgz#437eec5b799b5852072084b3ae5ef66e8349e8a3"
- integrity sha512-vo4F2OewqjbB1+yaJ7k2EJFHlTP3jR634Z9Cj9itpqNjuLXvhlVxgnjsHsdRgASR8xYDrx6onw4vW5H6We0Jmg==
+"@babel/plugin-transform-block-scoped-functions@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.1.tgz#146856e756d54b20fff14b819456b3e01820b85d"
+ integrity sha512-B7K15Xp8lv0sOJrdVAoukKlxP9N59HS48V1J3U/JGj+Ad+MHq+am6xJVs85AgXrQn4LV8vaYFOB+pr/yIuzW8Q==
dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-plugin-utils" "^7.10.1"
-"@babel/plugin-transform-block-scoping@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.8.3.tgz#97d35dab66857a437c166358b91d09050c868f3a"
- integrity sha512-pGnYfm7RNRgYRi7bids5bHluENHqJhrV4bCZRwc5GamaWIIs07N4rZECcmJL6ZClwjDz1GbdMZFtPs27hTB06w==
+"@babel/plugin-transform-block-scoping@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.1.tgz#47092d89ca345811451cd0dc5d91605982705d5e"
+ integrity sha512-8bpWG6TtF5akdhIm/uWTyjHqENpy13Fx8chg7pFH875aNLwX8JxIxqm08gmAT+Whe6AOmaTeLPe7dpLbXt+xUw==
dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-plugin-utils" "^7.10.1"
lodash "^4.17.13"
-"@babel/plugin-transform-classes@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.8.3.tgz#46fd7a9d2bb9ea89ce88720477979fe0d71b21b8"
- integrity sha512-SjT0cwFJ+7Rbr1vQsvphAHwUHvSUPmMjMU/0P59G8U2HLFqSa082JO7zkbDNWs9kH/IUqpHI6xWNesGf8haF1w==
- dependencies:
- "@babel/helper-annotate-as-pure" "^7.8.3"
- "@babel/helper-define-map" "^7.8.3"
- "@babel/helper-function-name" "^7.8.3"
- "@babel/helper-optimise-call-expression" "^7.8.3"
- "@babel/helper-plugin-utils" "^7.8.3"
- "@babel/helper-replace-supers" "^7.8.3"
- "@babel/helper-split-export-declaration" "^7.8.3"
+"@babel/plugin-transform-classes@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.1.tgz#6e11dd6c4dfae70f540480a4702477ed766d733f"
+ integrity sha512-P9V0YIh+ln/B3RStPoXpEQ/CoAxQIhRSUn7aXqQ+FZJ2u8+oCtjIXR3+X0vsSD8zv+mb56K7wZW1XiDTDGiDRQ==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.10.1"
+ "@babel/helper-define-map" "^7.10.1"
+ "@babel/helper-function-name" "^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"
globals "^11.1.0"
-"@babel/plugin-transform-computed-properties@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.8.3.tgz#96d0d28b7f7ce4eb5b120bb2e0e943343c86f81b"
- integrity sha512-O5hiIpSyOGdrQZRQ2ccwtTVkgUDBBiCuK//4RJ6UfePllUTCENOzKxfh6ulckXKc0DixTFLCfb2HVkNA7aDpzA==
+"@babel/plugin-transform-computed-properties@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.1.tgz#59aa399064429d64dce5cf76ef9b90b7245ebd07"
+ integrity sha512-mqSrGjp3IefMsXIenBfGcPXxJxweQe2hEIwMQvjtiDQ9b1IBvDUjkAtV/HMXX47/vXf14qDNedXsIiNd1FmkaQ==
dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-plugin-utils" "^7.10.1"
-"@babel/plugin-transform-destructuring@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.8.3.tgz#20ddfbd9e4676906b1056ee60af88590cc7aaa0b"
- integrity sha512-H4X646nCkiEcHZUZaRkhE2XVsoz0J/1x3VVujnn96pSoGCtKPA99ZZA+va+gK+92Zycd6OBKCD8tDb/731bhgQ==
+"@babel/plugin-transform-destructuring@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.1.tgz#abd58e51337815ca3a22a336b85f62b998e71907"
+ integrity sha512-V/nUc4yGWG71OhaTH705pU8ZSdM6c1KmmLP8ys59oOYbT7RpMYAR3MsVOt6OHL0WzG7BlTU076va9fjJyYzJMA==
dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-plugin-utils" "^7.10.1"
-"@babel/plugin-transform-dotall-regex@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.8.3.tgz#c3c6ec5ee6125c6993c5cbca20dc8621a9ea7a6e"
- integrity sha512-kLs1j9Nn4MQoBYdRXH6AeaXMbEJFaFu/v1nQkvib6QzTj8MZI5OQzqmD83/2jEM1z0DLilra5aWO5YpyC0ALIw==
+"@babel/plugin-transform-dotall-regex@^7.10.1", "@babel/plugin-transform-dotall-regex@^7.4.4":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.1.tgz#920b9fec2d78bb57ebb64a644d5c2ba67cc104ee"
+ integrity sha512-19VIMsD1dp02RvduFUmfzj8uknaO3uiHHF0s3E1OHnVsNj8oge8EQ5RzHRbJjGSetRnkEuBYO7TG1M5kKjGLOA==
dependencies:
- "@babel/helper-create-regexp-features-plugin" "^7.8.3"
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-create-regexp-features-plugin" "^7.10.1"
+ "@babel/helper-plugin-utils" "^7.10.1"
-"@babel/plugin-transform-duplicate-keys@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.8.3.tgz#8d12df309aa537f272899c565ea1768e286e21f1"
- integrity sha512-s8dHiBUbcbSgipS4SMFuWGqCvyge5V2ZeAWzR6INTVC3Ltjig/Vw1G2Gztv0vU/hRG9X8IvKvYdoksnUfgXOEQ==
+"@babel/plugin-transform-duplicate-keys@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.1.tgz#c900a793beb096bc9d4d0a9d0cde19518ffc83b9"
+ integrity sha512-wIEpkX4QvX8Mo9W6XF3EdGttrIPZWozHfEaDTU0WJD/TDnXMvdDh30mzUl/9qWhnf7naicYartcEfUghTCSNpA==
dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-plugin-utils" "^7.10.1"
-"@babel/plugin-transform-exponentiation-operator@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.8.3.tgz#581a6d7f56970e06bf51560cd64f5e947b70d7b7"
- integrity sha512-zwIpuIymb3ACcInbksHaNcR12S++0MDLKkiqXHl3AzpgdKlFNhog+z/K0+TGW+b0w5pgTq4H6IwV/WhxbGYSjQ==
+"@babel/plugin-transform-exponentiation-operator@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.1.tgz#279c3116756a60dd6e6f5e488ba7957db9c59eb3"
+ integrity sha512-lr/przdAbpEA2BUzRvjXdEDLrArGRRPwbaF9rvayuHRvdQ7lUTTkZnhZrJ4LE2jvgMRFF4f0YuPQ20vhiPYxtA==
dependencies:
- "@babel/helper-builder-binary-assignment-operator-visitor" "^7.8.3"
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.1"
+ "@babel/helper-plugin-utils" "^7.10.1"
-"@babel/plugin-transform-for-of@^7.8.4":
- version "7.8.4"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.8.4.tgz#6fe8eae5d6875086ee185dd0b098a8513783b47d"
- integrity sha512-iAXNlOWvcYUYoV8YIxwS7TxGRJcxyl8eQCfT+A5j8sKUzRFvJdcyjp97jL2IghWSRDaL2PU2O2tX8Cu9dTBq5A==
+"@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"
+ integrity sha512-US8KCuxfQcn0LwSCMWMma8M2R5mAjJGsmoCBVwlMygvmDUMkTCykc84IqN1M7t+agSfOmLYTInLCHJM+RUoz+w==
dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-plugin-utils" "^7.10.1"
-"@babel/plugin-transform-function-name@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.8.3.tgz#279373cb27322aaad67c2683e776dfc47196ed8b"
- integrity sha512-rO/OnDS78Eifbjn5Py9v8y0aR+aSYhDhqAwVfsTl0ERuMZyr05L1aFSCJnbv2mmsLkit/4ReeQ9N2BgLnOcPCQ==
+"@babel/plugin-transform-function-name@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.1.tgz#4ed46fd6e1d8fde2a2ec7b03c66d853d2c92427d"
+ integrity sha512-//bsKsKFBJfGd65qSNNh1exBy5Y9gD9ZN+DvrJ8f7HXr4avE5POW6zB7Rj6VnqHV33+0vXWUwJT0wSHubiAQkw==
dependencies:
- "@babel/helper-function-name" "^7.8.3"
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-function-name" "^7.10.1"
+ "@babel/helper-plugin-utils" "^7.10.1"
-"@babel/plugin-transform-literals@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.8.3.tgz#aef239823d91994ec7b68e55193525d76dbd5dc1"
- integrity sha512-3Tqf8JJ/qB7TeldGl+TT55+uQei9JfYaregDcEAyBZ7akutriFrt6C/wLYIer6OYhleVQvH/ntEhjE/xMmy10A==
+"@babel/plugin-transform-literals@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.1.tgz#5794f8da82846b22e4e6631ea1658bce708eb46a"
+ integrity sha512-qi0+5qgevz1NHLZroObRm5A+8JJtibb7vdcPQF1KQE12+Y/xxl8coJ+TpPW9iRq+Mhw/NKLjm+5SHtAHCC7lAw==
dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-plugin-utils" "^7.10.1"
-"@babel/plugin-transform-member-expression-literals@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.8.3.tgz#963fed4b620ac7cbf6029c755424029fa3a40410"
- integrity sha512-3Wk2EXhnw+rP+IDkK6BdtPKsUE5IeZ6QOGrPYvw52NwBStw9V1ZVzxgK6fSKSxqUvH9eQPR3tm3cOq79HlsKYA==
+"@babel/plugin-transform-member-expression-literals@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.1.tgz#90347cba31bca6f394b3f7bd95d2bbfd9fce2f39"
+ integrity sha512-UmaWhDokOFT2GcgU6MkHC11i0NQcL63iqeufXWfRy6pUOGYeCGEKhvfFO6Vz70UfYJYHwveg62GS83Rvpxn+NA==
dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-plugin-utils" "^7.10.1"
-"@babel/plugin-transform-modules-amd@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.8.3.tgz#65606d44616b50225e76f5578f33c568a0b876a5"
- integrity sha512-MadJiU3rLKclzT5kBH4yxdry96odTUwuqrZM+GllFI/VhxfPz+k9MshJM+MwhfkCdxxclSbSBbUGciBngR+kEQ==
+"@babel/plugin-transform-modules-amd@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.1.tgz#65950e8e05797ebd2fe532b96e19fc5482a1d52a"
+ integrity sha512-31+hnWSFRI4/ACFr1qkboBbrTxoBIzj7qA69qlq8HY8p7+YCzkCT6/TvQ1a4B0z27VeWtAeJd6pr5G04dc1iHw==
dependencies:
- "@babel/helper-module-transforms" "^7.8.3"
- "@babel/helper-plugin-utils" "^7.8.3"
- babel-plugin-dynamic-import-node "^2.3.0"
+ "@babel/helper-module-transforms" "^7.10.1"
+ "@babel/helper-plugin-utils" "^7.10.1"
+ babel-plugin-dynamic-import-node "^2.3.3"
-"@babel/plugin-transform-modules-commonjs@^7.2.0", "@babel/plugin-transform-modules-commonjs@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.8.3.tgz#df251706ec331bd058a34bdd72613915f82928a5"
- integrity sha512-JpdMEfA15HZ/1gNuB9XEDlZM1h/gF/YOH7zaZzQu2xCFRfwc01NXBMHHSTT6hRjlXJJs5x/bfODM3LiCk94Sxg==
+"@babel/plugin-transform-modules-commonjs@^7.10.1", "@babel/plugin-transform-modules-commonjs@^7.2.0":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.1.tgz#d5ff4b4413ed97ffded99961056e1fb980fb9301"
+ integrity sha512-AQG4fc3KOah0vdITwt7Gi6hD9BtQP/8bhem7OjbaMoRNCH5Djx42O2vYMfau7QnAzQCa+RJnhJBmFFMGpQEzrg==
dependencies:
- "@babel/helper-module-transforms" "^7.8.3"
- "@babel/helper-plugin-utils" "^7.8.3"
- "@babel/helper-simple-access" "^7.8.3"
- babel-plugin-dynamic-import-node "^2.3.0"
+ "@babel/helper-module-transforms" "^7.10.1"
+ "@babel/helper-plugin-utils" "^7.10.1"
+ "@babel/helper-simple-access" "^7.10.1"
+ babel-plugin-dynamic-import-node "^2.3.3"
-"@babel/plugin-transform-modules-systemjs@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.8.3.tgz#d8bbf222c1dbe3661f440f2f00c16e9bb7d0d420"
- integrity sha512-8cESMCJjmArMYqa9AO5YuMEkE4ds28tMpZcGZB/jl3n0ZzlsxOAi3mC+SKypTfT8gjMupCnd3YiXCkMjj2jfOg==
+"@babel/plugin-transform-modules-systemjs@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.1.tgz#9962e4b0ac6aaf2e20431ada3d8ec72082cbffb6"
+ integrity sha512-ewNKcj1TQZDL3YnO85qh9zo1YF1CHgmSTlRQgHqe63oTrMI85cthKtZjAiZSsSNjPQ5NCaYo5QkbYqEw1ZBgZA==
dependencies:
- "@babel/helper-hoist-variables" "^7.8.3"
- "@babel/helper-module-transforms" "^7.8.3"
- "@babel/helper-plugin-utils" "^7.8.3"
- babel-plugin-dynamic-import-node "^2.3.0"
+ "@babel/helper-hoist-variables" "^7.10.1"
+ "@babel/helper-module-transforms" "^7.10.1"
+ "@babel/helper-plugin-utils" "^7.10.1"
+ babel-plugin-dynamic-import-node "^2.3.3"
-"@babel/plugin-transform-modules-umd@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.8.3.tgz#592d578ce06c52f5b98b02f913d653ffe972661a"
- integrity sha512-evhTyWhbwbI3/U6dZAnx/ePoV7H6OUG+OjiJFHmhr9FPn0VShjwC2kdxqIuQ/+1P50TMrneGzMeyMTFOjKSnAw==
+"@babel/plugin-transform-modules-umd@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.1.tgz#ea080911ffc6eb21840a5197a39ede4ee67b1595"
+ integrity sha512-EIuiRNMd6GB6ulcYlETnYYfgv4AxqrswghmBRQbWLHZxN4s7mupxzglnHqk9ZiUpDI4eRWewedJJNj67PWOXKA==
dependencies:
- "@babel/helper-module-transforms" "^7.8.3"
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-module-transforms" "^7.10.1"
+ "@babel/helper-plugin-utils" "^7.10.1"
"@babel/plugin-transform-named-capturing-groups-regex@^7.8.3":
version "7.8.3"
@@ -557,194 +579,225 @@
dependencies:
"@babel/helper-create-regexp-features-plugin" "^7.8.3"
-"@babel/plugin-transform-new-target@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.8.3.tgz#60cc2ae66d85c95ab540eb34babb6434d4c70c43"
- integrity sha512-QuSGysibQpyxexRyui2vca+Cmbljo8bcRckgzYV4kRIsHpVeyeC3JDO63pY+xFZ6bWOBn7pfKZTqV4o/ix9sFw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
-
-"@babel/plugin-transform-object-super@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.8.3.tgz#ebb6a1e7a86ffa96858bd6ac0102d65944261725"
- integrity sha512-57FXk+gItG/GejofIyLIgBKTas4+pEU47IXKDBWFTxdPd7F80H8zybyAY7UoblVfBhBGs2EKM+bJUu2+iUYPDQ==
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
- "@babel/helper-replace-supers" "^7.8.3"
-
-"@babel/plugin-transform-parameters@^7.8.4":
- version "7.8.4"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.8.4.tgz#1d5155de0b65db0ccf9971165745d3bb990d77d3"
- integrity sha512-IsS3oTxeTsZlE5KqzTbcC2sV0P9pXdec53SU+Yxv7o/6dvGM5AkTotQKhoSffhNgZ/dftsSiOoxy7evCYJXzVA==
- dependencies:
- "@babel/helper-call-delegate" "^7.8.3"
- "@babel/helper-get-function-arity" "^7.8.3"
- "@babel/helper-plugin-utils" "^7.8.3"
-
-"@babel/plugin-transform-property-literals@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.8.3.tgz#33194300d8539c1ed28c62ad5087ba3807b98263"
- integrity sha512-uGiiXAZMqEoQhRWMK17VospMZh5sXWg+dlh2soffpkAl96KAm+WZuJfa6lcELotSRmooLqg0MWdH6UUq85nmmg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
-
-"@babel/plugin-transform-regenerator@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.3.tgz#b31031e8059c07495bf23614c97f3d9698bc6ec8"
- integrity sha512-qt/kcur/FxrQrzFR432FGZznkVAjiyFtCOANjkAKwCbt465L6ZCiUQh2oMYGU3Wo8LRFJxNDFwWn106S5wVUNA==
- dependencies:
- regenerator-transform "^0.14.0"
-
-"@babel/plugin-transform-reserved-words@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.8.3.tgz#9a0635ac4e665d29b162837dd3cc50745dfdf1f5"
- integrity sha512-mwMxcycN3omKFDjDQUl+8zyMsBfjRFr0Zn/64I41pmjv4NJuqcYlEtezwYtw9TFd9WR1vN5kiM+O0gMZzO6L0A==
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
-
-"@babel/plugin-transform-shorthand-properties@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz#28545216e023a832d4d3a1185ed492bcfeac08c8"
- integrity sha512-I9DI6Odg0JJwxCHzbzW08ggMdCezoWcuQRz3ptdudgwaHxTjxw5HgdFJmZIkIMlRymL6YiZcped4TTCB0JcC8w==
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
-
-"@babel/plugin-transform-spread@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.8.3.tgz#9c8ffe8170fdfb88b114ecb920b82fb6e95fe5e8"
- integrity sha512-CkuTU9mbmAoFOI1tklFWYYbzX5qCIZVXPVy0jpXgGwkplCndQAa58s2jr66fTeQnA64bDox0HL4U56CFYoyC7g==
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
-
-"@babel/plugin-transform-sticky-regex@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.8.3.tgz#be7a1290f81dae767475452199e1f76d6175b100"
- integrity sha512-9Spq0vGCD5Bb4Z/ZXXSK5wbbLFMG085qd2vhL1JYu1WcQ5bXqZBAYRzU1d+p79GcHs2szYv5pVQCX13QgldaWw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
- "@babel/helper-regex" "^7.8.3"
-
-"@babel/plugin-transform-template-literals@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.8.3.tgz#7bfa4732b455ea6a43130adc0ba767ec0e402a80"
- integrity sha512-820QBtykIQOLFT8NZOcTRJ1UNuztIELe4p9DCgvj4NK+PwluSJ49we7s9FB1HIGNIYT7wFUJ0ar2QpCDj0escQ==
- dependencies:
- "@babel/helper-annotate-as-pure" "^7.8.3"
- "@babel/helper-plugin-utils" "^7.8.3"
-
-"@babel/plugin-transform-typeof-symbol@^7.8.4":
- version "7.8.4"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.4.tgz#ede4062315ce0aaf8a657a920858f1a2f35fc412"
- integrity sha512-2QKyfjGdvuNfHsb7qnBBlKclbD4CfshH2KvDabiijLMGXPHJXGxtDzwIF7bQP+T0ysw8fYTtxPafgfs/c1Lrqg==
+"@babel/plugin-transform-new-target@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.1.tgz#6ee41a5e648da7632e22b6fb54012e87f612f324"
+ integrity sha512-MBlzPc1nJvbmO9rPr1fQwXOM2iGut+JC92ku6PbiJMMK7SnQc1rytgpopveE3Evn47gzvGYeCdgfCDbZo0ecUw==
dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
+ "@babel/helper-plugin-utils" "^7.10.1"
-"@babel/plugin-transform-unicode-regex@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz#0cef36e3ba73e5c57273effb182f46b91a1ecaad"
- integrity sha512-+ufgJjYdmWfSQ+6NS9VGUR2ns8cjJjYbrbi11mZBTaWm+Fui/ncTLFF28Ei1okavY+xkojGr1eJxNsWYeA5aZw==
+"@babel/plugin-transform-object-super@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.1.tgz#2e3016b0adbf262983bf0d5121d676a5ed9c4fde"
+ integrity sha512-WnnStUDN5GL+wGQrJylrnnVlFhFmeArINIR9gjhSeYyvroGhBrSAXYg/RHsnfzmsa+onJrTJrEClPzgNmmQ4Gw==
dependencies:
- "@babel/helper-create-regexp-features-plugin" "^7.8.3"
- "@babel/helper-plugin-utils" "^7.8.3"
-
-"@babel/preset-env@^7.8.4":
- version "7.8.4"
- resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.8.4.tgz#9dac6df5f423015d3d49b6e9e5fa3413e4a72c4e"
- integrity sha512-HihCgpr45AnSOHRbS5cWNTINs0TwaR8BS8xIIH+QwiW8cKL0llV91njQMpeMReEPVs+1Ao0x3RLEBLtt1hOq4w==
- dependencies:
- "@babel/compat-data" "^7.8.4"
- "@babel/helper-compilation-targets" "^7.8.4"
- "@babel/helper-module-imports" "^7.8.3"
- "@babel/helper-plugin-utils" "^7.8.3"
- "@babel/plugin-proposal-async-generator-functions" "^7.8.3"
- "@babel/plugin-proposal-dynamic-import" "^7.8.3"
- "@babel/plugin-proposal-json-strings" "^7.8.3"
- "@babel/plugin-proposal-nullish-coalescing-operator" "^7.8.3"
- "@babel/plugin-proposal-object-rest-spread" "^7.8.3"
- "@babel/plugin-proposal-optional-catch-binding" "^7.8.3"
- "@babel/plugin-proposal-optional-chaining" "^7.8.3"
- "@babel/plugin-proposal-unicode-property-regex" "^7.8.3"
+ "@babel/helper-plugin-utils" "^7.10.1"
+ "@babel/helper-replace-supers" "^7.10.1"
+
+"@babel/plugin-transform-parameters@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.1.tgz#b25938a3c5fae0354144a720b07b32766f683ddd"
+ integrity sha512-tJ1T0n6g4dXMsL45YsSzzSDZCxiHXAQp/qHrucOq5gEHncTA3xDxnd5+sZcoQp+N1ZbieAaB8r/VUCG0gqseOg==
+ dependencies:
+ "@babel/helper-get-function-arity" "^7.10.1"
+ "@babel/helper-plugin-utils" "^7.10.1"
+
+"@babel/plugin-transform-property-literals@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.1.tgz#cffc7315219230ed81dc53e4625bf86815b6050d"
+ integrity sha512-Kr6+mgag8auNrgEpbfIWzdXYOvqDHZOF0+Bx2xh4H2EDNwcbRb9lY6nkZg8oSjsX+DH9Ebxm9hOqtKW+gRDeNA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.10.1"
+
+"@babel/plugin-transform-regenerator@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.1.tgz#10e175cbe7bdb63cc9b39f9b3f823c5c7c5c5490"
+ integrity sha512-B3+Y2prScgJ2Bh/2l9LJxKbb8C8kRfsG4AdPT+n7ixBHIxJaIG8bi8tgjxUMege1+WqSJ+7gu1YeoMVO3gPWzw==
+ dependencies:
+ regenerator-transform "^0.14.2"
+
+"@babel/plugin-transform-reserved-words@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.1.tgz#0fc1027312b4d1c3276a57890c8ae3bcc0b64a86"
+ integrity sha512-qN1OMoE2nuqSPmpTqEM7OvJ1FkMEV+BjVeZZm9V9mq/x1JLKQ4pcv8riZJMNN3u2AUGl0ouOMjRr2siecvHqUQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.10.1"
+
+"@babel/plugin-transform-shorthand-properties@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.1.tgz#e8b54f238a1ccbae482c4dce946180ae7b3143f3"
+ integrity sha512-AR0E/lZMfLstScFwztApGeyTHJ5u3JUKMjneqRItWeEqDdHWZwAOKycvQNCasCK/3r5YXsuNG25funcJDu7Y2g==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.10.1"
+
+"@babel/plugin-transform-spread@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.10.1.tgz#0c6d618a0c4461a274418460a28c9ccf5239a7c8"
+ integrity sha512-8wTPym6edIrClW8FI2IoaePB91ETOtg36dOkj3bYcNe7aDMN2FXEoUa+WrmPc4xa1u2PQK46fUX2aCb+zo9rfw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.10.1"
+
+"@babel/plugin-transform-sticky-regex@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.1.tgz#90fc89b7526228bed9842cff3588270a7a393b00"
+ integrity sha512-j17ojftKjrL7ufX8ajKvwRilwqTok4q+BjkknmQw9VNHnItTyMP5anPFzxFJdCQs7clLcWpCV3ma+6qZWLnGMA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.10.1"
+ "@babel/helper-regex" "^7.10.1"
+
+"@babel/plugin-transform-template-literals@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.1.tgz#914c7b7f4752c570ea00553b4284dad8070e8628"
+ integrity sha512-t7B/3MQf5M1T9hPCRG28DNGZUuxAuDqLYS03rJrIk2prj/UV7Z6FOneijhQhnv/Xa039vidXeVbvjK2SK5f7Gg==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.10.1"
+ "@babel/helper-plugin-utils" "^7.10.1"
+
+"@babel/plugin-transform-typeof-symbol@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.1.tgz#60c0239b69965d166b80a84de7315c1bc7e0bb0e"
+ integrity sha512-qX8KZcmbvA23zDi+lk9s6hC1FM7jgLHYIjuLgULgc8QtYnmB3tAVIYkNoKRQ75qWBeyzcoMoK8ZQmogGtC/w0g==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.10.1"
+
+"@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"
+ integrity sha512-zZ0Poh/yy1d4jeDWpx/mNwbKJVwUYJX73q+gyh4bwtG0/iUlzdEu0sLMda8yuDFS6LBQlT/ST1SJAR6zYwXWgw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.10.1"
+
+"@babel/plugin-transform-unicode-regex@^7.10.1":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.1.tgz#6b58f2aea7b68df37ac5025d9c88752443a6b43f"
+ integrity sha512-Y/2a2W299k0VIUdbqYm9X2qS6fE0CUBhhiPpimK6byy7OJ/kORLlIX+J6UrjgNu5awvs62k+6RSslxhcvVw2Tw==
+ dependencies:
+ "@babel/helper-create-regexp-features-plugin" "^7.10.1"
+ "@babel/helper-plugin-utils" "^7.10.1"
+
+"@babel/preset-env@^7.10.1":
+ version "7.10.2"
+ resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.10.2.tgz#715930f2cf8573b0928005ee562bed52fb65fdfb"
+ integrity sha512-MjqhX0RZaEgK/KueRzh+3yPSk30oqDKJ5HP5tqTSB1e2gzGS3PLy7K0BIpnp78+0anFuSwOeuCf1zZO7RzRvEA==
+ dependencies:
+ "@babel/compat-data" "^7.10.1"
+ "@babel/helper-compilation-targets" "^7.10.2"
+ "@babel/helper-module-imports" "^7.10.1"
+ "@babel/helper-plugin-utils" "^7.10.1"
+ "@babel/plugin-proposal-async-generator-functions" "^7.10.1"
+ "@babel/plugin-proposal-class-properties" "^7.10.1"
+ "@babel/plugin-proposal-dynamic-import" "^7.10.1"
+ "@babel/plugin-proposal-json-strings" "^7.10.1"
+ "@babel/plugin-proposal-nullish-coalescing-operator" "^7.10.1"
+ "@babel/plugin-proposal-numeric-separator" "^7.10.1"
+ "@babel/plugin-proposal-object-rest-spread" "^7.10.1"
+ "@babel/plugin-proposal-optional-catch-binding" "^7.10.1"
+ "@babel/plugin-proposal-optional-chaining" "^7.10.1"
+ "@babel/plugin-proposal-private-methods" "^7.10.1"
+ "@babel/plugin-proposal-unicode-property-regex" "^7.10.1"
"@babel/plugin-syntax-async-generators" "^7.8.0"
+ "@babel/plugin-syntax-class-properties" "^7.10.1"
"@babel/plugin-syntax-dynamic-import" "^7.8.0"
"@babel/plugin-syntax-json-strings" "^7.8.0"
"@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0"
+ "@babel/plugin-syntax-numeric-separator" "^7.10.1"
"@babel/plugin-syntax-object-rest-spread" "^7.8.0"
"@babel/plugin-syntax-optional-catch-binding" "^7.8.0"
"@babel/plugin-syntax-optional-chaining" "^7.8.0"
- "@babel/plugin-syntax-top-level-await" "^7.8.3"
- "@babel/plugin-transform-arrow-functions" "^7.8.3"
- "@babel/plugin-transform-async-to-generator" "^7.8.3"
- "@babel/plugin-transform-block-scoped-functions" "^7.8.3"
- "@babel/plugin-transform-block-scoping" "^7.8.3"
- "@babel/plugin-transform-classes" "^7.8.3"
- "@babel/plugin-transform-computed-properties" "^7.8.3"
- "@babel/plugin-transform-destructuring" "^7.8.3"
- "@babel/plugin-transform-dotall-regex" "^7.8.3"
- "@babel/plugin-transform-duplicate-keys" "^7.8.3"
- "@babel/plugin-transform-exponentiation-operator" "^7.8.3"
- "@babel/plugin-transform-for-of" "^7.8.4"
- "@babel/plugin-transform-function-name" "^7.8.3"
- "@babel/plugin-transform-literals" "^7.8.3"
- "@babel/plugin-transform-member-expression-literals" "^7.8.3"
- "@babel/plugin-transform-modules-amd" "^7.8.3"
- "@babel/plugin-transform-modules-commonjs" "^7.8.3"
- "@babel/plugin-transform-modules-systemjs" "^7.8.3"
- "@babel/plugin-transform-modules-umd" "^7.8.3"
+ "@babel/plugin-syntax-top-level-await" "^7.10.1"
+ "@babel/plugin-transform-arrow-functions" "^7.10.1"
+ "@babel/plugin-transform-async-to-generator" "^7.10.1"
+ "@babel/plugin-transform-block-scoped-functions" "^7.10.1"
+ "@babel/plugin-transform-block-scoping" "^7.10.1"
+ "@babel/plugin-transform-classes" "^7.10.1"
+ "@babel/plugin-transform-computed-properties" "^7.10.1"
+ "@babel/plugin-transform-destructuring" "^7.10.1"
+ "@babel/plugin-transform-dotall-regex" "^7.10.1"
+ "@babel/plugin-transform-duplicate-keys" "^7.10.1"
+ "@babel/plugin-transform-exponentiation-operator" "^7.10.1"
+ "@babel/plugin-transform-for-of" "^7.10.1"
+ "@babel/plugin-transform-function-name" "^7.10.1"
+ "@babel/plugin-transform-literals" "^7.10.1"
+ "@babel/plugin-transform-member-expression-literals" "^7.10.1"
+ "@babel/plugin-transform-modules-amd" "^7.10.1"
+ "@babel/plugin-transform-modules-commonjs" "^7.10.1"
+ "@babel/plugin-transform-modules-systemjs" "^7.10.1"
+ "@babel/plugin-transform-modules-umd" "^7.10.1"
"@babel/plugin-transform-named-capturing-groups-regex" "^7.8.3"
- "@babel/plugin-transform-new-target" "^7.8.3"
- "@babel/plugin-transform-object-super" "^7.8.3"
- "@babel/plugin-transform-parameters" "^7.8.4"
- "@babel/plugin-transform-property-literals" "^7.8.3"
- "@babel/plugin-transform-regenerator" "^7.8.3"
- "@babel/plugin-transform-reserved-words" "^7.8.3"
- "@babel/plugin-transform-shorthand-properties" "^7.8.3"
- "@babel/plugin-transform-spread" "^7.8.3"
- "@babel/plugin-transform-sticky-regex" "^7.8.3"
- "@babel/plugin-transform-template-literals" "^7.8.3"
- "@babel/plugin-transform-typeof-symbol" "^7.8.4"
- "@babel/plugin-transform-unicode-regex" "^7.8.3"
- "@babel/types" "^7.8.3"
- browserslist "^4.8.5"
+ "@babel/plugin-transform-new-target" "^7.10.1"
+ "@babel/plugin-transform-object-super" "^7.10.1"
+ "@babel/plugin-transform-parameters" "^7.10.1"
+ "@babel/plugin-transform-property-literals" "^7.10.1"
+ "@babel/plugin-transform-regenerator" "^7.10.1"
+ "@babel/plugin-transform-reserved-words" "^7.10.1"
+ "@babel/plugin-transform-shorthand-properties" "^7.10.1"
+ "@babel/plugin-transform-spread" "^7.10.1"
+ "@babel/plugin-transform-sticky-regex" "^7.10.1"
+ "@babel/plugin-transform-template-literals" "^7.10.1"
+ "@babel/plugin-transform-typeof-symbol" "^7.10.1"
+ "@babel/plugin-transform-unicode-escapes" "^7.10.1"
+ "@babel/plugin-transform-unicode-regex" "^7.10.1"
+ "@babel/preset-modules" "^0.1.3"
+ "@babel/types" "^7.10.2"
+ browserslist "^4.12.0"
core-js-compat "^3.6.2"
invariant "^2.2.2"
levenary "^1.1.1"
semver "^5.5.0"
-"@babel/standalone@^7.0.0":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/standalone/-/standalone-7.8.3.tgz#0674730a8c5fbb9352de5342bf0c0c040d658380"
- integrity sha512-WRYZUuGBYpmfUL50f2h3Cvw7s1F4wTVT5iIeT01tHo+LyB9QwrTJ6GF5J6YrtJHQqxMxt8zEl1d7I0Uhyz9NyQ==
+"@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"
+ integrity sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.0.0"
+ "@babel/plugin-proposal-unicode-property-regex" "^7.4.4"
+ "@babel/plugin-transform-dotall-regex" "^7.4.4"
+ "@babel/types" "^7.4.4"
+ esutils "^2.0.2"
-"@babel/template@^7.4.0", "@babel/template@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.3.tgz#e02ad04fe262a657809327f578056ca15fd4d1b8"
- integrity sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==
+"@babel/runtime@^7.8.4":
+ version "7.10.2"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.2.tgz#d103f21f2602497d38348a32e008637d506db839"
+ integrity sha512-6sF3uQw2ivImfVIl62RZ7MXhO2tap69WeWK57vAaimT6AZbE4FbqjdEJIN1UqoD6wI6B+1n9UiagafH1sxjOtg==
dependencies:
- "@babel/code-frame" "^7.8.3"
- "@babel/parser" "^7.8.3"
- "@babel/types" "^7.8.3"
+ regenerator-runtime "^0.13.4"
-"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.8.3", "@babel/traverse@^7.8.4":
- version "7.8.4"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.8.4.tgz#f0845822365f9d5b0e312ed3959d3f827f869e3c"
- integrity sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==
- dependencies:
- "@babel/code-frame" "^7.8.3"
- "@babel/generator" "^7.8.4"
- "@babel/helper-function-name" "^7.8.3"
- "@babel/helper-split-export-declaration" "^7.8.3"
- "@babel/parser" "^7.8.4"
- "@babel/types" "^7.8.3"
+"@babel/standalone@^7.0.0":
+ version "7.10.2"
+ 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.4.0":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.1.tgz#e167154a94cb5f14b28dc58f5356d2162f539811"
+ integrity sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==
+ dependencies:
+ "@babel/code-frame" "^7.10.1"
+ "@babel/parser" "^7.10.1"
+ "@babel/types" "^7.10.1"
+
+"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.10.1", "@babel/traverse@^7.4.3":
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.10.1.tgz#bbcef3031e4152a6c0b50147f4958df54ca0dd27"
+ integrity sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==
+ dependencies:
+ "@babel/code-frame" "^7.10.1"
+ "@babel/generator" "^7.10.1"
+ "@babel/helper-function-name" "^7.10.1"
+ "@babel/helper-split-export-declaration" "^7.10.1"
+ "@babel/parser" "^7.10.1"
+ "@babel/types" "^7.10.1"
debug "^4.1.0"
globals "^11.1.0"
lodash "^4.17.13"
-"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.3.tgz#5a383dffa5416db1b73dedffd311ffd0788fb31c"
- integrity sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==
+"@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.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4":
+ version "7.10.2"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.10.2.tgz#30283be31cad0dbf6fb00bd40641ca0ea675172d"
+ integrity sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==
dependencies:
- esutils "^2.0.2"
+ "@babel/helper-validator-identifier" "^7.10.1"
lodash "^4.17.13"
to-fast-properties "^2.0.0"
@@ -782,19 +835,19 @@
eslint-plugin-vue "^6.2.1"
vue-eslint-parser "^7.0.0"
-"@gitlab/svgs@1.127.0":
- version "1.127.0"
- resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.127.0.tgz#1f7ffdffe44d6a82b372535f93d78f3a895d1960"
- integrity sha512-Uv52DqkG2KwCB0VRlXUEHFZxJ/7Ql0t1YTdzICpXmDjltuUBrysFcdmWPVO6PgXQxk2ahryNsUjSOziMYTeSiw==
+"@gitlab/svgs@1.139.0":
+ version "1.139.0"
+ resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.139.0.tgz#8a4874e76000e2dd7d3ed3a8967d62bed47d7ea7"
+ integrity sha512-o1KAmQLYL727HodlPHkmj+d+Kdw8OIgHzlKmmPYMzeE+As2l1oz6CTilca56KqXGklOgrouC9P2puMwyX8e/6g==
-"@gitlab/ui@14.10.0":
- version "14.10.0"
- resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-14.10.0.tgz#39c04d62c914fcefe96c7ec32fdf31b1f98f1119"
- integrity sha512-k9w6z3/QBeUas++cH5BaozjxY4fVu+AggjGoh9QMKN5hpiGTiTPx5aQJIlOv8UX/kpUmgc4pHSWAbw30YVGGFw==
+"@gitlab/ui@16.12.1":
+ version "16.12.1"
+ resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-16.12.1.tgz#4d6865308596b09e36961210df7a8a489aaadb6d"
+ integrity sha512-jF6/I71Q0mjHetIRDO8O4VO2KIGWKL/yH2Mdb/CqQKaEasgnc/YpuyHGCsBXqDPxCjRbXPeKp0EywICQx4agZA==
dependencies:
"@babel/standalone" "^7.0.0"
"@gitlab/vue-toasted" "^1.3.0"
- bootstrap-vue "2.1.0"
+ bootstrap-vue "2.13.1"
copy-to-clipboard "^3.0.8"
echarts "^4.2.1"
highlight.js "^9.13.1"
@@ -876,6 +929,17 @@
jest-message-util "^24.8.0"
jest-mock "^24.8.0"
+"@jest/fake-timers@^25.1.0":
+ version "25.5.0"
+ resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-25.5.0.tgz#46352e00533c024c90c2bc2ad9f2959f7f114185"
+ integrity sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==
+ dependencies:
+ "@jest/types" "^25.5.0"
+ jest-message-util "^25.5.0"
+ jest-mock "^25.5.0"
+ jest-util "^25.5.0"
+ lolex "^5.0.0"
+
"@jest/reporters@^24.8.0":
version "24.8.0"
resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.8.0.tgz#075169cd029bddec54b8f2c0fc489fd0b9e05729"
@@ -961,6 +1025,16 @@
"@types/istanbul-reports" "^1.1.1"
"@types/yargs" "^12.0.9"
+"@jest/types@^25.5.0":
+ version "25.5.0"
+ resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.5.0.tgz#4d6a4793f7b9599fc3680877b856a97dbccf2a9d"
+ integrity sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==
+ dependencies:
+ "@types/istanbul-lib-coverage" "^2.0.0"
+ "@types/istanbul-reports" "^1.1.1"
+ "@types/yargs" "^15.0.0"
+ chalk "^3.0.0"
+
"@mrmlnc/readdir-enhanced@^2.2.1":
version "2.2.1"
resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde"
@@ -983,10 +1057,10 @@
consola "^2.10.1"
node-fetch "^2.6.0"
-"@rails/actioncable@^6.0.3":
- version "6.0.3"
- resolved "https://registry.yarnpkg.com/@rails/actioncable/-/actioncable-6.0.3.tgz#722b4b639936129307ddbab3a390f6bcacf3e7bc"
- integrity sha512-I01hgqxxnOgOtJTGlq0ZsGJYiTEEiSGVEGQn3vimZSqEP1HqzyFNbzGTq14Xdyeow2yGJjygjoFF1pmtE+SQaw==
+"@rails/actioncable@^6.0.3-1":
+ version "6.0.3-1"
+ resolved "https://registry.yarnpkg.com/@rails/actioncable/-/actioncable-6.0.3-1.tgz#9b9eb8858a6507162911007d355d9a206e1c5caa"
+ integrity sha512-szFhWD+V5TAxVNVIG16klgq+ypqA5k5AecLarTTrXgOG8cawVbQdOAwLbCmzkwiQ60rGSxAFoC1u2LrzxSK2Aw==
"@sentry/browser@^5.10.2":
version "5.10.2"
@@ -1040,10 +1114,29 @@
"@sentry/types" "5.10.0"
tslib "^1.9.3"
-"@sourcegraph/code-host-integration@0.0.46":
- version "0.0.46"
- resolved "https://registry.yarnpkg.com/@sourcegraph/code-host-integration/-/code-host-integration-0.0.46.tgz#05e4cda671ed00450be12461e6a3caff473675aa"
- integrity sha512-ghzfaV5ydSWTamLPIDLl5tRvTtM2MBDRmQbWTPg9ZoCP/eHk61uCTAFEq02lsefDQHISZHldeClqRYhZvGDZfw==
+"@sindresorhus/is@^0.14.0":
+ version "0.14.0"
+ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
+ integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==
+
+"@sinonjs/commons@^1.7.0":
+ version "1.8.0"
+ resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.0.tgz#c8d68821a854c555bba172f3b06959a0039b236d"
+ integrity sha512-wEj54PfsZ5jGSwMX68G8ZXFawcSglQSXqCftWX3ec8MDUzQdHgcKvw97awHbY0efQEL5iKUOAmmVtoYgmrSG4Q==
+ dependencies:
+ type-detect "4.0.8"
+
+"@sourcegraph/code-host-integration@0.0.48":
+ version "0.0.48"
+ resolved "https://registry.yarnpkg.com/@sourcegraph/code-host-integration/-/code-host-integration-0.0.48.tgz#327bd04182e8a9a8daabebc6f2b50c8186b19514"
+ integrity sha512-O4jQyfYmmZaZahLj2BbqjEh7MarQRhZHYdWhL4D3CdUGH4y3XOTGCmVHWEFb23UaV/izze1XoGDxbQeAnps7EA==
+
+"@szmarczak/http-timer@^1.1.2":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
+ integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==
+ dependencies:
+ defer-to-connect "^1.0.1"
"@toast-ui/editor@^2.0.1":
version "2.0.1"
@@ -1105,6 +1198,11 @@
dependencies:
"@types/tern" "*"
+"@types/color-name@^1.1.1":
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
+ integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
+
"@types/estree@*":
version "0.0.44"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.44.tgz#980cc5a29a3ef3bea6ff1f7d021047d7ea575e21"
@@ -1221,11 +1319,23 @@
"@types/uglify-js" "*"
source-map "^0.6.0"
+"@types/yargs-parser@*":
+ version "15.0.0"
+ resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d"
+ integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==
+
"@types/yargs@^12.0.2", "@types/yargs@^12.0.9":
version "12.0.12"
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-12.0.12.tgz#45dd1d0638e8c8f153e87d296907659296873916"
integrity sha512-SOhuU4wNBxhhTHxYaiG5NY4HBhDIDnJF60GU+2LqHAdKKer86//e4yg69aENCtQ04n0ovz+tq2YPME5t5yp4pw==
+"@types/yargs@^15.0.0":
+ version "15.0.5"
+ resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.5.tgz#947e9a6561483bdee9adffc983e91a6902af8b79"
+ integrity sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==
+ dependencies:
+ "@types/yargs-parser" "*"
+
"@types/zen-observable@^0.8.0":
version "0.8.0"
resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.0.tgz#8b63ab7f1aa5321248aad5ac890a485656dcea4d"
@@ -1469,10 +1579,10 @@
resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31"
integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==
-abab@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.0.tgz#aba0ab4c5eee2d4c79d3487d85450fb2376ebb0f"
- integrity sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w==
+abab@^2.0.0, abab@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a"
+ integrity sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==
abbrev@1:
version "1.0.9"
@@ -1495,6 +1605,14 @@ acorn-globals@^4.1.0:
acorn "^6.0.1"
acorn-walk "^6.0.1"
+acorn-globals@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45"
+ integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==
+ dependencies:
+ acorn "^7.1.1"
+ acorn-walk "^7.1.1"
+
acorn-jsx@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.1.0.tgz#294adb71b57398b0680015f0a38c563ee1db5384"
@@ -1505,20 +1623,25 @@ acorn-walk@^6.0.1, acorn-walk@^6.1.1:
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c"
integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==
+acorn-walk@^7.1.1:
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.1.1.tgz#345f0dffad5c735e7373d2fec9a1023e6a44b83e"
+ integrity sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==
+
acorn@^5.5.3:
version "5.7.3"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279"
integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==
-acorn@^6.0.1, acorn@^6.0.7, acorn@^6.2.1:
+acorn@^6.0.1, acorn@^6.0.7, acorn@^6.2.1, acorn@^6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e"
integrity sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==
-acorn@^7.1.0:
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.0.tgz#949d36f2c292535da602283586c2477c57eb2d6c"
- integrity sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==
+acorn@^7.1.0, acorn@^7.1.1:
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.2.0.tgz#17ea7e40d7c8640ff54a694c889c26f31704effe"
+ integrity sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==
after@0.8.2:
version "0.8.2"
@@ -1558,12 +1681,12 @@ amdefine@>=0.0.4:
resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=
-ansi-align@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f"
- integrity sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=
+ansi-align@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb"
+ integrity sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==
dependencies:
- string-width "^2.0.0"
+ string-width "^3.0.0"
ansi-colors@^3.0.0:
version "3.2.4"
@@ -1602,6 +1725,11 @@ ansi-regex@^4.0.0, ansi-regex@^4.1.0:
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
+ansi-regex@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
+ integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
+
ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
@@ -1614,6 +1742,14 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1:
dependencies:
color-convert "^1.9.0"
+ansi-styles@^4.1.0:
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359"
+ integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==
+ dependencies:
+ "@types/color-name" "^1.1.1"
+ color-convert "^2.0.1"
+
anymatch@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb"
@@ -1622,10 +1758,10 @@ anymatch@^2.0.0:
micromatch "^3.1.4"
normalize-path "^2.1.1"
-anymatch@^3.0.1:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.0.3.tgz#2fb624fe0e84bccab00afee3d0006ed310f22f09"
- integrity sha512-c6IvoeBECQlMVuYUjSwimnhmztImpErfxJzWZhIQinIvQWoGOnB0dLIgifbPHQt5heS6mNlaZG16f06H3C8t1g==
+anymatch@~3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142"
+ integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==
dependencies:
normalize-path "^3.0.0"
picomatch "^2.0.4"
@@ -1867,11 +2003,6 @@ astral-regex@^1.0.0:
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9"
integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==
-async-each@^1.0.1:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf"
- integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==
-
async-foreach@^0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542"
@@ -1992,10 +2123,10 @@ babel-loader@^8.0.6:
mkdirp "^0.5.1"
pify "^4.0.1"
-babel-plugin-dynamic-import-node@^2.2.0, babel-plugin-dynamic-import-node@^2.3.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz#f00f507bdaa3c3e3ff6e7e5e98d90a7acab96f7f"
- integrity sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==
+babel-plugin-dynamic-import-node@^2.2.0, babel-plugin-dynamic-import-node@^2.3.3:
+ version "2.3.3"
+ resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3"
+ integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==
dependencies:
object.assign "^4.1.0"
@@ -2121,11 +2252,6 @@ big.js@^5.2.2:
resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==
-binary-extensions@^1.0.0:
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205"
- integrity sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=
-
binary-extensions@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c"
@@ -2136,6 +2262,13 @@ binaryextensions@2:
resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.1.1.tgz#3209a51ca4a4ad541a3b8d3d6a6d5b83a2485935"
integrity sha512-XBaoWE9RW8pPdPQNibZsW2zh8TW6gcarXp1FZPwT8Uop8ScSNldJEWf2k9l3HeTqdrEwsOsFcq74RiJECW34yA==
+bindings@^1.5.0:
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df"
+ integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==
+ dependencies:
+ file-uri-to-path "1.0.0"
+
blob@0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.4.tgz#bcf13052ca54463f30f9fc7e95b9a47630a94921"
@@ -2186,34 +2319,35 @@ bonjour@^3.5.0:
multicast-dns "^6.0.1"
multicast-dns-service-types "^1.1.0"
-bootstrap-vue@2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/bootstrap-vue/-/bootstrap-vue-2.1.0.tgz#41c0cd265a6cea14ffe29eeea71543ec396d1789"
- integrity sha512-dftb5fc42x7QLv814nN+3Cx8MMuCB+xrGQjOmSXH81ET0+yo7KYb4lUN3/pOnf+8Tkv8oaawZ1OOth5/AZfktg==
+bootstrap-vue@2.13.1:
+ version "2.13.1"
+ resolved "https://registry.yarnpkg.com/bootstrap-vue/-/bootstrap-vue-2.13.1.tgz#dcefca78f2b0345508fbb85adb0a9897cce65fa1"
+ integrity sha512-FF1GLRvvj+TgpLkMG/A8+tCMQfWnfKpsPqt7s097VTX2lZv2/YmyhehRC1qraPHYqT7qQVy48TCxSw1H8hNh3Q==
dependencies:
"@nuxt/opencollective" "^0.3.0"
- bootstrap ">=4.3.1 <5.0.0"
- popper.js "^1.16.0"
- portal-vue "^2.1.6"
+ bootstrap ">=4.4.1 <5.0.0"
+ popper.js "^1.16.1"
+ portal-vue "^2.1.7"
vue-functional-data-merge "^3.1.0"
-bootstrap@4.3.1, "bootstrap@>=4.3.1 <5.0.0":
- version "4.3.1"
- resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.3.1.tgz#280ca8f610504d99d7b6b4bfc4b68cec601704ac"
- integrity sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag==
+bootstrap@4.4.1, "bootstrap@>=4.4.1 <5.0.0":
+ version "4.4.1"
+ resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.4.1.tgz#8582960eea0c5cd2bede84d8b0baf3789c3e8b01"
+ integrity sha512-tbx5cHubwE6e2ZG7nqM3g/FZ5PQEDMWmMGNrCUBVRPHXTJaH7CBDdsLeu3eCh3B1tzAxTnAbtmrzvWEvT2NNEA==
-boxen@^1.2.1:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b"
- integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==
+boxen@^4.2.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/boxen/-/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64"
+ integrity sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==
dependencies:
- ansi-align "^2.0.0"
- camelcase "^4.0.0"
- chalk "^2.0.1"
- cli-boxes "^1.0.0"
- string-width "^2.0.0"
- term-size "^1.2.0"
- widest-line "^2.0.0"
+ ansi-align "^3.0.0"
+ camelcase "^5.3.1"
+ chalk "^3.0.0"
+ cli-boxes "^2.2.0"
+ string-width "^4.1.0"
+ term-size "^2.1.0"
+ type-fest "^0.8.1"
+ widest-line "^3.1.0"
brace-expansion@^1.1.7, brace-expansion@^1.1.8:
version "1.1.11"
@@ -2223,7 +2357,7 @@ brace-expansion@^1.1.7, brace-expansion@^1.1.8:
balanced-match "^1.0.0"
concat-map "0.0.1"
-braces@^2.3.1, braces@^2.3.2:
+braces@^2.3.1:
version "2.3.2"
resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729"
integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==
@@ -2239,7 +2373,7 @@ braces@^2.3.1, braces@^2.3.2:
split-string "^3.0.2"
to-regex "^3.0.1"
-braces@^3.0.1, braces@^3.0.2:
+braces@^3.0.1, braces@^3.0.2, 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==
@@ -2251,10 +2385,10 @@ brorand@^1.0.1:
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=
-browser-process-hrtime@^0.1.2:
- version "0.1.3"
- resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz#616f00faef1df7ec1b5bf9cfe2bdc3170f26c7b4"
- integrity sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==
+browser-process-hrtime@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626"
+ integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==
browser-resolve@^1.11.3:
version "1.11.3"
@@ -2321,14 +2455,15 @@ browserify-zlib@^0.2.0:
dependencies:
pako "~1.0.5"
-browserslist@^4.6.3, browserslist@^4.8.3, browserslist@^4.8.5:
- version "4.8.7"
- resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.8.7.tgz#ec8301ff415e6a42c949d0e66b405eb539c532d0"
- integrity sha512-gFOnZNYBHrEyUML0xr5NJ6edFaaKbTFX9S9kQHlYfCP0Rit/boRIz4G+Avq6/4haEKJXdGGUnoolx+5MWW2BoA==
+browserslist@^4.12.0, browserslist@^4.6.3, browserslist@^4.8.3:
+ version "4.12.0"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.12.0.tgz#06c6d5715a1ede6c51fc39ff67fd647f740b656d"
+ integrity sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg==
dependencies:
- caniuse-lite "^1.0.30001027"
- electron-to-chromium "^1.3.349"
- node-releases "^1.1.49"
+ caniuse-lite "^1.0.30001043"
+ electron-to-chromium "^1.3.413"
+ node-releases "^1.1.53"
+ pkg-up "^2.0.0"
bs-logger@0.x:
version "0.2.6"
@@ -2460,6 +2595,19 @@ cache-loader@^4.1.0:
neo-async "^2.6.1"
schema-utils "^2.0.0"
+cacheable-request@^6.0.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912"
+ integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==
+ dependencies:
+ clone-response "^1.0.2"
+ get-stream "^5.1.0"
+ http-cache-semantics "^4.0.0"
+ keyv "^3.0.0"
+ lowercase-keys "^2.0.0"
+ normalize-url "^4.1.0"
+ responselike "^1.0.2"
+
call-me-maybe@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b"
@@ -2529,20 +2677,20 @@ camelcase@^3.0.0:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a"
integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo=
-camelcase@^4.0.0, camelcase@^4.1.0:
+camelcase@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=
-camelcase@^5.0.0, camelcase@^5.2.0:
+camelcase@^5.0.0, camelcase@^5.2.0, camelcase@^5.3.1:
version "5.3.1"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
-caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30001027:
- version "1.0.30001030"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001030.tgz#78076c4c6d67d3e41d6eb9399853fb27fe6e44ee"
- integrity sha512-QGK0W4Ft/Ac+zTjEiRJfwDNATvS3fodDczBXrH42784kcfqcDKpEPfN08N0HQjrAp8He/Jw8QiSS9QRn7XAbUw==
+caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30001043:
+ version "1.0.30001081"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001081.tgz#40615a3c416a047c5a4d45673e5257bf128eb3b5"
+ integrity sha512-iZdh3lu09jsUtLE6Bp8NAbJskco4Y3UDtkR3GTCJGsbMowBU5IWDFF79sV2ws7lSqTzWyKazxam2thasHymENQ==
capture-exit@^2.0.0:
version "2.0.0"
@@ -2551,11 +2699,6 @@ capture-exit@^2.0.0:
dependencies:
rsvp "^4.8.4"
-capture-stack-trace@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d"
- integrity sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=
-
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
@@ -2593,6 +2736,14 @@ chalk@^1.1.1:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
+chalk@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4"
+ integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==
+ dependencies:
+ ansi-styles "^4.1.0"
+ supports-color "^7.1.0"
+
character-entities-html4@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-1.1.2.tgz#c44fdde3ce66b52e8d321d6c1bf46101f0150610"
@@ -2623,67 +2774,25 @@ charenc@~0.0.1:
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=
-chart.js@2.7.2:
- version "2.7.2"
- resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-2.7.2.tgz#3c9fde4dc5b95608211bdefeda7e5d33dffa5714"
- integrity sha512-90wl3V9xRZ8tnMvMlpcW+0Yg13BelsGS9P9t0ClaDxv/hdypHDr/YAGf+728m11P5ljwyB0ZHfPKCapZFqSqYA==
- dependencies:
- chartjs-color "^2.1.0"
- moment "^2.10.2"
-
-chartjs-color-string@^0.5.0:
- version "0.5.0"
- resolved "https://registry.yarnpkg.com/chartjs-color-string/-/chartjs-color-string-0.5.0.tgz#8d3752d8581d86687c35bfe2cb80ac5213ceb8c1"
- integrity sha512-amWNvCOXlOUYxZVDSa0YOab5K/lmEhbFNKI55PWc4mlv28BDzA7zaoQTGxSBgJMHIW+hGX8YUrvw/FH4LyhwSQ==
- dependencies:
- color-name "^1.0.0"
-
-chartjs-color@^2.1.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/chartjs-color/-/chartjs-color-2.2.0.tgz#84a2fb755787ed85c39dd6dd8c7b1d88429baeae"
- integrity sha1-hKL7dVeH7YXDndbdjHsdiEKbrq4=
- dependencies:
- chartjs-color-string "^0.5.0"
- color-convert "^0.5.3"
-
check-types@^7.3.0:
version "7.3.0"
resolved "https://registry.yarnpkg.com/check-types/-/check-types-7.3.0.tgz#468f571a4435c24248f5fd0cb0e8d87c3c341e7d"
integrity sha1-Ro9XGkQ1wkJI9f0MsOjYfDw0Hn0=
-chokidar@^2.0.2, chokidar@^2.0.4, chokidar@^2.1.8:
- version "2.1.8"
- resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917"
- integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==
- dependencies:
- anymatch "^2.0.0"
- async-each "^1.0.1"
- braces "^2.3.2"
- glob-parent "^3.1.0"
- inherits "^2.0.3"
- is-binary-path "^1.0.0"
- is-glob "^4.0.0"
- normalize-path "^3.0.0"
- path-is-absolute "^1.0.0"
- readdirp "^2.2.1"
- upath "^1.1.1"
+chokidar@^2.1.8, chokidar@^3.0.0, chokidar@^3.2.2, chokidar@^3.4.0:
+ version "3.4.0"
+ resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.0.tgz#b30611423ce376357c765b9b8f904b9fba3c0be8"
+ integrity sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==
+ dependencies:
+ anymatch "~3.1.1"
+ braces "~3.0.2"
+ glob-parent "~5.1.0"
+ is-binary-path "~2.1.0"
+ is-glob "~4.0.1"
+ normalize-path "~3.0.0"
+ readdirp "~3.4.0"
optionalDependencies:
- fsevents "^1.2.7"
-
-chokidar@^3.0.0:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.0.2.tgz#0d1cd6d04eb2df0327446188cd13736a3367d681"
- integrity sha512-c4PR2egjNjI1um6bamCQ6bUNPDiyofNQruHvKgHQ4gDUP/ITSVSzNsiI5OWtHOsX323i5ha/kk4YmOZ1Ktg7KA==
- dependencies:
- anymatch "^3.0.1"
- braces "^3.0.2"
- glob-parent "^5.0.0"
- is-binary-path "^2.1.0"
- is-glob "^4.0.1"
- normalize-path "^3.0.0"
- readdirp "^3.1.1"
- optionalDependencies:
- fsevents "^2.0.6"
+ fsevents "~2.1.2"
chownr@^1.1.1, chownr@^1.1.2:
version "1.1.3"
@@ -2697,11 +2806,6 @@ chrome-trace-event@^1.0.2:
dependencies:
tslib "^1.9.0"
-ci-info@^1.5.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497"
- integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==
-
ci-info@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46"
@@ -2742,10 +2846,10 @@ clean-stack@^2.0.0:
resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b"
integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==
-cli-boxes@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143"
- integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM=
+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"
@@ -2811,6 +2915,13 @@ clone-regexp@^2.1.0:
dependencies:
is-regexp "^2.0.0"
+clone-response@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
+ integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=
+ dependencies:
+ mimic-response "^1.0.0"
+
co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
@@ -2858,11 +2969,6 @@ collection-visit@^1.0.0:
map-visit "^1.0.0"
object-visit "^1.0.0"
-color-convert@^0.5.3, color-convert@~0.5.0:
- version "0.5.3"
- resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-0.5.3.tgz#bdb6c69ce660fadffe0b0007cc447e1b9f7282bd"
- integrity sha1-vbbGnOZg+t/+CwAHzER+G59ygr0=
-
color-convert@^1.9.0:
version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
@@ -2870,11 +2976,28 @@ color-convert@^1.9.0:
dependencies:
color-name "1.1.3"
-color-name@1.1.3, color-name@^1.0.0:
+color-convert@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
+ integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
+ dependencies:
+ color-name "~1.1.4"
+
+color-convert@~0.5.0:
+ version "0.5.3"
+ resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-0.5.3.tgz#bdb6c69ce660fadffe0b0007cc447e1b9f7282bd"
+ integrity sha1-vbbGnOZg+t/+CwAHzER+G59ygr0=
+
+color-name@1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
+color-name@~1.1.4:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
+ integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
+
colors@^1.1.0:
version "1.3.3"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d"
@@ -2988,17 +3111,17 @@ config-chain@^1.1.12:
ini "^1.3.4"
proto-list "~1.2.1"
-configstore@^3.0.0:
- version "3.1.1"
- resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.1.tgz#094ee662ab83fad9917678de114faaea8fcdca90"
- integrity sha512-5oNkD/L++l0O6xGXxb1EWS7SivtjfGQlRyxJsYgE0Z495/L81e2h4/d3r969hoPXuFItzNOKMtsXgYG4c7dYvw==
+configstore@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96"
+ integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==
dependencies:
- dot-prop "^4.1.0"
+ dot-prop "^5.2.0"
graceful-fs "^4.1.2"
- make-dir "^1.0.0"
- unique-string "^1.0.0"
- write-file-atomic "^2.0.0"
- xdg-basedir "^3.0.0"
+ make-dir "^3.0.0"
+ unique-string "^2.0.0"
+ write-file-atomic "^3.0.0"
+ xdg-basedir "^4.0.0"
confusing-browser-globals@^1.0.7:
version "1.0.9"
@@ -3171,13 +3294,6 @@ create-ecdh@^4.0.0:
bn.js "^4.1.0"
elliptic "^6.0.0"
-create-error-class@^3.0.0:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6"
- integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=
- dependencies:
- capture-stack-trace "^1.0.0"
-
create-hash@^1.1.0, create-hash@^1.1.2:
version "1.1.3"
resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.1.3.tgz#606042ac8b9262750f483caddab0f5819172d8fd"
@@ -3226,15 +3342,6 @@ cross-spawn@^3.0.0:
lru-cache "^4.0.1"
which "^1.2.9"
-cross-spawn@^5.0.1:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
- integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=
- dependencies:
- lru-cache "^4.0.1"
- shebang-command "^1.2.0"
- which "^1.2.9"
-
crypt@~0.0.1:
version "0.0.2"
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
@@ -3257,10 +3364,10 @@ crypto-browserify@^3.11.0:
randombytes "^2.0.0"
randomfill "^1.0.3"
-crypto-random-string@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e"
- integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=
+crypto-random-string@^2.0.0:
+ version "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==
crypto-random-string@^3.0.1:
version "3.0.1"
@@ -3321,10 +3428,15 @@ cssfontparser@^1.2.1:
resolved "https://registry.yarnpkg.com/cssfontparser/-/cssfontparser-1.2.1.tgz#f4022fc8f9700c68029d542084afbaf425a3f3e3"
integrity sha1-9AIvyPlwDGgCnVQghK+69CWj8+M=
-cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0":
- version "0.3.4"
- resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.4.tgz#8cd52e8a3acfd68d3aed38ee0a640177d2f9d797"
- integrity sha512-+7prCSORpXNeR4/fUP3rL+TzqtiFfhMvTd7uEqMdgPvLPt4+uzFUeufx5RHjGTACCargg/DiEt/moMQmvnfkog==
+cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0", cssom@~0.3.6:
+ version "0.3.8"
+ resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a"
+ integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==
+
+cssom@^0.4.4:
+ version "0.4.4"
+ resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10"
+ integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==
cssstyle@^1.0.0:
version "1.1.1"
@@ -3333,6 +3445,13 @@ cssstyle@^1.0.0:
dependencies:
cssom "0.3.x"
+cssstyle@^2.2.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852"
+ integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==
+ dependencies:
+ cssom "~0.3.6"
+
currently-unhandled@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea"
@@ -3355,7 +3474,7 @@ cyclist@~0.2.2:
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640"
integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=
-d3-array@1, d3-array@^1.1.1, d3-array@^1.2.0:
+d3-array@1, "d3-array@1 - 2", d3-array@^1.1.1, d3-array@^1.2.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.1.tgz#d1ca33de2f6ac31efadb8e050a021d7e2396d5dc"
integrity sha512-CyINJQ0SOUHojDdFDH4JEM0552vCR1utGyLHegJHyYH0JyCpSeTPxi4OBqHMA2jJZq4NH782LtaJWBImqI/HBw==
@@ -3489,6 +3608,14 @@ d3-random@1:
resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-1.1.0.tgz#6642e506c6fa3a648595d2b2469788a8d12529d3"
integrity sha1-ZkLlBsb6OmSFldKyRpeIqNElKdM=
+d3-sankey@^0.12.3:
+ version "0.12.3"
+ resolved "https://registry.yarnpkg.com/d3-sankey/-/d3-sankey-0.12.3.tgz#b3c268627bd72e5d80336e8de6acbfec9d15d01d"
+ integrity sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==
+ dependencies:
+ d3-array "1 - 2"
+ d3-shape "^1.2.0"
+
d3-scale-chromatic@1:
version "1.3.3"
resolved "https://registry.yarnpkg.com/d3-scale-chromatic/-/d3-scale-chromatic-1.3.3.tgz#dad4366f0edcb288f490128979c3c793583ed3c0"
@@ -3514,10 +3641,10 @@ d3-selection@1, d3-selection@^1.1.0, d3-selection@^1.2.0:
resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.3.0.tgz#d53772382d3dc4f7507bfb28bcd2d6aed2a0ad6d"
integrity sha512-qgpUOg9tl5CirdqESUAu0t9MU/t3O9klYfGfyKsXEmhyxyzLpzpeh08gaxBUTQw1uXIOkr/30Ut2YRjSSxlmHA==
-d3-shape@1:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.2.0.tgz#45d01538f064bafd05ea3d6d2cb748fd8c41f777"
- integrity sha1-RdAVOPBkuv0F6j1tLLdI/YxB93c=
+d3-shape@1, d3-shape@^1.2.0:
+ version "1.3.7"
+ resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.7.tgz#df63801be07bc986bc54f63789b4fe502992b5d7"
+ integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==
dependencies:
d3-path "1"
@@ -3566,10 +3693,10 @@ d3-zoom@1:
d3-selection "1"
d3-transition "1"
-d3@^5.14, d3@^5.7.0:
- version "5.15.0"
- resolved "https://registry.yarnpkg.com/d3/-/d3-5.15.0.tgz#ffd44958e6a3cb8a59a84429c45429b8bca5677a"
- integrity sha512-C+E80SL2nLLtmykZ6klwYj5rPqB5nlfN5LdWEAVdWPppqTD8taoJi2PxLZjPeYT8FFRR2yucXq+kBlOnnvZeLg==
+d3@^5.14, d3@^5.16.0, d3@^5.7.0:
+ version "5.16.0"
+ resolved "https://registry.yarnpkg.com/d3/-/d3-5.16.0.tgz#9c5e8d3b56403c79d4ed42fbd62f6113f199c877"
+ integrity sha512-4PL5hHaHwX4m7Zr1UapXW23apo6pexCgdetdJ5kTmADpG/7T9Gkxw0M0tf/pjoB63ezCCm0u5UaFYy2aMt0Mcw==
dependencies:
d3-array "1"
d3-axis "1"
@@ -3637,6 +3764,15 @@ data-urls@^1.0.0:
whatwg-mimetype "^2.2.0"
whatwg-url "^7.0.0"
+data-urls@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b"
+ integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==
+ dependencies:
+ abab "^2.0.3"
+ 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"
@@ -3671,7 +3807,7 @@ debug@=3.1.0, debug@~3.1.0:
dependencies:
ms "2.0.0"
-debug@^3.1.0, debug@^3.1.1, debug@^3.2.5, debug@^3.2.6:
+debug@^3.1.1, debug@^3.2.5, debug@^3.2.6:
version "3.2.6"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
@@ -3698,6 +3834,11 @@ decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0:
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
+decimal.js@^10.2.0:
+ version "10.2.0"
+ resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.0.tgz#39466113a9e036111d02f82489b5fd6b0b5ed231"
+ integrity sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw==
+
deckar01-task_list@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/deckar01-task_list/-/deckar01-task_list-2.3.1.tgz#f3ffd5319d7b9e27c596dc8d823b13f617ed7db7"
@@ -3708,6 +3849,13 @@ decode-uri-component@^0.2.0:
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
+decompress-response@^3.3.0:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
+ integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=
+ dependencies:
+ mimic-response "^1.0.0"
+
deep-equal@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
@@ -3743,6 +3891,11 @@ default-require-extensions@^2.0.0:
dependencies:
strip-bom "^3.0.0"
+defer-to-connect@^1.0.1:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591"
+ integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==
+
define-properties@^1.1.2, define-properties@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
@@ -3828,11 +3981,6 @@ detect-file@^1.0.0:
resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7"
integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=
-detect-libc@^1.0.2:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
- integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
-
detect-newline@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2"
@@ -3944,6 +4092,11 @@ dom-serializer@0, dom-serializer@^0.2.1:
domelementtype "^2.0.1"
entities "^2.0.0"
+dom-walk@^0.1.0:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84"
+ integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==
+
domain-browser@^1.1.1:
version "1.1.7"
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc"
@@ -3966,6 +4119,13 @@ domexception@^1.0.1:
dependencies:
webidl-conversions "^4.0.2"
+domexception@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304"
+ integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==
+ dependencies:
+ webidl-conversions "^5.0.0"
+
domhandler@^2.3.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.1.tgz#892e47000a99be55bbf3774ffea0561d8879c259"
@@ -3997,13 +4157,20 @@ domutils@^2.0.0:
domelementtype "^2.0.1"
domhandler "^3.0.0"
-dot-prop@^4.1.0, dot-prop@^4.1.1:
+dot-prop@^4.1.1:
version "4.2.0"
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57"
integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==
dependencies:
is-obj "^1.0.0"
+dot-prop@^5.2.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.2.0.tgz#c34ecc29556dc45f1f4c22697b6f4904e0cc4fcb"
+ integrity sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==
+ dependencies:
+ is-obj "^2.0.0"
+
dropzone@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/dropzone/-/dropzone-4.2.0.tgz#fbe7acbb9918e0706489072ef663effeef8a79f3"
@@ -4069,10 +4236,10 @@ ejs@^2.6.1:
resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0"
integrity sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==
-electron-to-chromium@^1.3.349:
- version "1.3.360"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.360.tgz#1db9cb8d43f4c772546d94ea9be8b677a8ecb483"
- integrity sha512-RE1pv2sjQiDRRN1nI0fJ0eQHZ9le4oobu16OArnwEUV5ycAU5SNjFyvzjZ1gPUAqBa2Ud1XagtW8j3ZXfHuQHA==
+electron-to-chromium@^1.3.413:
+ version "1.3.466"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.466.tgz#89f716db3afc4bb482ea2aaaa16c4808f89f762a"
+ integrity sha512-eieqkoM2hCkZZRhETKyCouMziDV3l4XEKHRLuzcHG+HV+P7PeODU/z9HAmBgMQkzvHg2DoyQhfIDmmeguLZT/Q==
elliptic@^6.0.0:
version "6.4.0"
@@ -4197,6 +4364,13 @@ entities@^2.0.0:
resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4"
integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==
+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"
@@ -4242,6 +4416,11 @@ es6-promise@~3.0.2:
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.0.2.tgz#010d5858423a5f118979665f46486a95c6ee2bb6"
integrity sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=
+escape-goat@^2.0.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675"
+ integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==
+
escape-html@~1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
@@ -4257,12 +4436,12 @@ escaper@^2.5.3:
resolved "https://registry.yarnpkg.com/escaper/-/escaper-2.5.3.tgz#8b8fe90ba364054151ab7eff18b4ce43b1e13ab5"
integrity sha512-QGb9sFxBVpbzMggrKTX0ry1oiI4CSDAl9vIL702hzl1jGW8VZs7qfqTRX7WDOjoNDoEVGcEtu1ZOQgReSfT2kQ==
-escodegen@^1.9.1:
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.0.tgz#b27a9389481d5bfd5bec76f7bb1eb3f8f4556589"
- integrity sha512-IeMV45ReixHS53K/OmfKAIztN/igDHzTJUhZM3k1jMhIZWjk45SMwAtBsEXiJp3vSPmTcu6CXn7mDvFHRN66fw==
+escodegen@^1.14.1, escodegen@^1.9.1:
+ version "1.14.2"
+ resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.2.tgz#14ab71bf5026c2aa08173afba22c6f3173284a84"
+ integrity sha512-InuOIiKk8wwuOFg6x9BQXbzjrQhtyXh46K9bqVTPzSo2FnyMBaYGBMC6PhQy7yxxil9vIedFBweQBMK74/7o8A==
dependencies:
- esprima "^3.1.3"
+ esprima "^4.0.1"
estraverse "^4.2.0"
esutils "^2.0.2"
optionator "^0.8.1"
@@ -4484,12 +4663,7 @@ espree@^6.1.2:
acorn-jsx "^5.1.0"
eslint-visitor-keys "^1.1.0"
-esprima@^3.1.3:
- version "3.1.3"
- resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
- integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=
-
-esprima@^4.0.0:
+esprima@^4.0.0, esprima@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
@@ -4563,19 +4737,6 @@ exec-sh@^0.3.2:
resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.2.tgz#6738de2eb7c8e671d0366aea0b0db8c6f7d7391b"
integrity sha512-9sLAvzhI5nc8TpuQUh4ahMdCrWT00wPWz7j47/emR5+2qEfoZP5zzUXvx+vdx+H6ohhnsYC31iX04QLYJK8zTg==
-execa@^0.7.0:
- version "0.7.0"
- resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777"
- integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=
- dependencies:
- cross-spawn "^5.0.1"
- get-stream "^3.0.0"
- is-stream "^1.1.0"
- npm-run-path "^2.0.0"
- p-finally "^1.0.0"
- signal-exit "^3.0.0"
- strip-eof "^1.0.0"
-
execa@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8"
@@ -4819,6 +4980,11 @@ file-loader@^5.1.0:
loader-utils "^1.4.0"
schema-utils "^2.5.0"
+file-uri-to-path@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
+ integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==
+
fileset@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0"
@@ -5030,13 +5196,6 @@ fs-extra@^7.0.1:
jsonfile "^4.0.0"
universalify "^0.1.0"
-fs-minipass@^1.2.5:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.6.tgz#2c5cc30ded81282bfe8a0d7c7c1853ddeb102c07"
- integrity sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ==
- dependencies:
- minipass "^2.2.1"
-
fs-minipass@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.0.0.tgz#a6415edab02fae4b9e9230bc87ee2e4472003cd1"
@@ -5060,17 +5219,17 @@ fs.realpath@^1.0.0:
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
fsevents@^1.2.7:
- version "1.2.9"
- resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f"
- integrity sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==
+ version "1.2.13"
+ resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38"
+ integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==
dependencies:
+ bindings "^1.5.0"
nan "^2.12.1"
- node-pre-gyp "^0.12.0"
-fsevents@^2.0.6:
- version "2.0.7"
- resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.0.7.tgz#382c9b443c6cbac4c57187cdda23aa3bf1ccfc2a"
- integrity sha512-a7YT0SV3RB+DjYcppwVDLtn13UQnmg0SWZS7ezZD0UjnLwXmy8Zm21GMVGLaFGimIqcvyMQaOJBrop8MyOp1kQ==
+fsevents@~2.1.2:
+ version "2.1.3"
+ resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e"
+ integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==
fstream@^1.0.0, fstream@^1.0.12:
version "1.0.12"
@@ -5153,18 +5312,20 @@ get-stdin@~5.0.1:
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398"
integrity sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=
-get-stream@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
- integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=
-
-get-stream@^4.0.0:
+get-stream@^4.0.0, get-stream@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
dependencies:
pump "^3.0.0"
+get-stream@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9"
+ integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==
+ dependencies:
+ pump "^3.0.0"
+
get-value@^2.0.3, get-value@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
@@ -5207,10 +5368,10 @@ glob-parent@^3.1.0:
is-glob "^3.1.0"
path-dirname "^1.0.0"
-glob-parent@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.0.0.tgz#1dc99f0f39b006d3e92c2c284068382f0c20e954"
- integrity sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==
+glob-parent@^5.0.0, glob-parent@~5.1.0:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229"
+ integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==
dependencies:
is-glob "^4.0.1"
@@ -5236,12 +5397,12 @@ glob-to-regexp@^0.4.0:
once "^1.3.0"
path-is-absolute "^1.0.0"
-global-dirs@^0.1.0:
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445"
- integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=
+global-dirs@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.0.1.tgz#acdf3bb6685bcd55cb35e8a052266569e9469201"
+ integrity sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==
dependencies:
- ini "^1.3.4"
+ ini "^1.3.5"
global-modules@2.0.0, global-modules@^2.0.0:
version "2.0.0"
@@ -5279,6 +5440,14 @@ global-prefix@^3.0.0:
kind-of "^6.0.2"
which "^1.3.1"
+global@^4.3.0:
+ version "4.4.0"
+ resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406"
+ integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==
+ dependencies:
+ min-document "^2.19.0"
+ process "^0.11.10"
+
globals@^11.1.0:
version "11.12.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
@@ -5356,27 +5525,27 @@ good-listener@^1.2.2:
dependencies:
delegate "^3.1.2"
-got@^6.7.1:
- version "6.7.1"
- resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0"
- integrity sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=
+got@^9.6.0:
+ version "9.6.0"
+ resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85"
+ integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==
dependencies:
- create-error-class "^3.0.0"
+ "@sindresorhus/is" "^0.14.0"
+ "@szmarczak/http-timer" "^1.1.2"
+ cacheable-request "^6.0.0"
+ decompress-response "^3.3.0"
duplexer3 "^0.1.4"
- get-stream "^3.0.0"
- is-redirect "^1.0.0"
- is-retry-allowed "^1.0.0"
- is-stream "^1.0.0"
- lowercase-keys "^1.0.0"
- safe-buffer "^5.0.1"
- timed-out "^4.0.0"
- unzip-response "^2.0.1"
- url-parse-lax "^1.0.0"
-
-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.2:
- version "4.2.3"
- resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423"
- integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==
+ get-stream "^4.1.0"
+ lowercase-keys "^1.0.1"
+ mimic-response "^1.0.1"
+ p-cancelable "^1.0.0"
+ to-readable-stream "^1.0.0"
+ url-parse-lax "^3.0.0"
+
+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.2, 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-readlink@>= 1.0.0":
version "1.0.1"
@@ -5436,7 +5605,7 @@ har-schema@^2.0.0:
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
-har-validator@~5.1.0:
+har-validator@~5.1.3:
version "5.1.3"
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080"
integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==
@@ -5514,6 +5683,11 @@ has-values@^1.0.0:
is-number "^3.0.0"
kind-of "^4.0.0"
+has-yarn@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77"
+ integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==
+
has@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
@@ -5549,7 +5723,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.2.0:
+he@^1.1.0, he@^1.1.1, he@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
@@ -5602,6 +5776,13 @@ html-encoding-sniffer@^1.0.2:
dependencies:
whatwg-encoding "^1.0.1"
+html-encoding-sniffer@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3"
+ integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==
+ dependencies:
+ whatwg-encoding "^1.0.5"
+
html-entities@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f"
@@ -5652,6 +5833,11 @@ htmlparser2@^4.1.0:
domutils "^2.0.0"
entities "^2.0.0"
+http-cache-semantics@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390"
+ integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==
+
http-deceiver@^1.2.7:
version "1.2.7"
resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87"
@@ -5711,7 +5897,7 @@ https-browserify@^1.0.0:
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
-iconv-lite@0.4, iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4:
+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==
@@ -5745,13 +5931,6 @@ ignore-by-default@^1.0.1:
resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09"
integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk=
-ignore-walk@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8"
- integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==
- dependencies:
- minimatch "^3.0.4"
-
ignore@^3.3.5:
version "3.3.10"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043"
@@ -5990,14 +6169,7 @@ is-arrayish@^0.2.1:
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=
-is-binary-path@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898"
- integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=
- dependencies:
- binary-extensions "^1.0.0"
-
-is-binary-path@^2.1.0:
+is-binary-path@~2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
@@ -6019,13 +6191,6 @@ is-callable@^1.1.4, is-callable@^1.1.5:
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab"
integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==
-is-ci@^1.0.10:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c"
- integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==
- dependencies:
- ci-info "^1.5.0"
-
is-ci@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c"
@@ -6133,7 +6298,7 @@ is-glob@^3.1.0:
dependencies:
is-extglob "^2.1.0"
-is-glob@^4.0.0, is-glob@^4.0.1:
+is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc"
integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==
@@ -6145,18 +6310,18 @@ is-hexadecimal@^1.0.0:
resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.2.tgz#b6e710d7d07bb66b98cb8cece5c9b4921deeb835"
integrity sha512-but/G3sapV3MNyqiDBLrOi4x8uCIw0RY3o/Vb5GT0sMFHrVV7731wFSVy41T5FO1og7G0gXLJh0MkgPRouko/A==
-is-installed-globally@^0.1.0:
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80"
- integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=
+is-installed-globally@^0.3.1:
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.3.2.tgz#fd3efa79ee670d1187233182d5b0a1dd00313141"
+ integrity sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==
dependencies:
- global-dirs "^0.1.0"
- is-path-inside "^1.0.0"
+ global-dirs "^2.0.1"
+ is-path-inside "^3.0.1"
-is-npm@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4"
- integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ=
+is-npm@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-4.0.0.tgz#c90dd8380696df87a7a6d823c20d0b12bbe3c84d"
+ integrity sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==
is-number@^3.0.0:
version "3.0.0"
@@ -6175,6 +6340,11 @@ is-obj@^1.0.0:
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8=
+is-obj@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982"
+ integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==
+
is-path-cwd@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb"
@@ -6187,13 +6357,6 @@ is-path-in-cwd@^2.0.0:
dependencies:
is-path-inside "^2.1.0"
-is-path-inside@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f"
- integrity sha1-/AbloWg/vaE95mev9xe7wQpI838=
- dependencies:
- path-is-inside "^1.0.1"
-
is-path-inside@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2"
@@ -6201,6 +6364,11 @@ is-path-inside@^2.1.0:
dependencies:
path-is-inside "^1.0.2"
+is-path-inside@^3.0.1:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.2.tgz#f5220fc82a3e233757291dddc9c5877f2a1f3017"
+ integrity sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==
+
is-plain-obj@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
@@ -6213,16 +6381,16 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4:
dependencies:
isobject "^3.0.1"
+is-potential-custom-element-name@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz#0c52e54bcca391bb2c494b21e8626d7336c6e397"
+ integrity sha1-DFLlS8yjkbssSUsh6GJtczbG45c=
+
is-promise@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=
-is-redirect@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24"
- integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=
-
is-regex@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae"
@@ -6240,12 +6408,7 @@ is-regexp@^2.0.0:
resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-2.1.0.tgz#cd734a56864e23b956bf4e7c66c396a4c0b22c2d"
integrity sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==
-is-retry-allowed@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34"
- integrity sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=
-
-is-stream@^1.0.0, is-stream@^1.1.0:
+is-stream@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
@@ -6257,7 +6420,7 @@ is-symbol@^1.0.2:
dependencies:
has-symbols "^1.0.0"
-is-typedarray@~1.0.0:
+is-typedarray@^1.0.0, is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
@@ -6292,6 +6455,11 @@ is-wsl@^1.1.0:
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d"
integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=
+is-yarn-global@^0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232"
+ integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==
+
isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
@@ -6545,7 +6713,17 @@ jest-each@^24.8.0:
jest-util "^24.8.0"
pretty-format "^24.8.0"
-jest-environment-jsdom@^24.0.0, jest-environment-jsdom@^24.8.0:
+jest-environment-jsdom-sixteen@^1.0.0:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/jest-environment-jsdom-sixteen/-/jest-environment-jsdom-sixteen-1.0.3.tgz#e222228fac537ef15cca5ad470b19b47d9690165"
+ integrity sha512-CwMqDUUfSl808uGPWXlNA1UFkWFgRmhHvyAjhCmCry6mYq4b/nn80MMN7tglqo5XgrANIs/w+mzINPzbZ4ZZrQ==
+ dependencies:
+ "@jest/fake-timers" "^25.1.0"
+ jest-mock "^25.1.0"
+ jest-util "^25.1.0"
+ jsdom "^16.2.1"
+
+jest-environment-jsdom@^24.8.0:
version "24.8.0"
resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.8.0.tgz#300f6949a146cabe1c9357ad9e9ecf9f43f38857"
integrity sha512-qbvgLmR7PpwjoFjM/sbuqHJt/NCkviuq9vus9NBn/76hhSidO+Z6Bn9tU8friecegbJL8gzZQEMZBQlFWDCwAQ==
@@ -6655,6 +6833,20 @@ jest-message-util@^24.8.0:
slash "^2.0.0"
stack-utils "^1.0.1"
+jest-message-util@^25.5.0:
+ version "25.5.0"
+ resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-25.5.0.tgz#ea11d93204cc7ae97456e1d8716251185b8880ea"
+ integrity sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==
+ dependencies:
+ "@babel/code-frame" "^7.0.0"
+ "@jest/types" "^25.5.0"
+ "@types/stack-utils" "^1.0.1"
+ chalk "^3.0.0"
+ graceful-fs "^4.2.4"
+ micromatch "^4.0.2"
+ slash "^3.0.0"
+ stack-utils "^1.0.1"
+
jest-mock@^24.8.0:
version "24.8.0"
resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.8.0.tgz#2f9d14d37699e863f1febf4e4d5a33b7fdbbde56"
@@ -6662,6 +6854,13 @@ jest-mock@^24.8.0:
dependencies:
"@jest/types" "^24.8.0"
+jest-mock@^25.1.0, jest-mock@^25.5.0:
+ version "25.5.0"
+ resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-25.5.0.tgz#a91a54dabd14e37ecd61665d6b6e06360a55387a"
+ integrity sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==
+ dependencies:
+ "@jest/types" "^25.5.0"
+
jest-pnp-resolver@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz#ecdae604c077a7fbc70defb6d517c3c1c898923a"
@@ -6792,6 +6991,17 @@ jest-util@^24.0.0, jest-util@^24.8.0:
slash "^2.0.0"
source-map "^0.6.0"
+jest-util@^25.1.0, jest-util@^25.5.0:
+ version "25.5.0"
+ resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-25.5.0.tgz#31c63b5d6e901274d264a4fec849230aa3fa35b0"
+ integrity sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==
+ dependencies:
+ "@jest/types" "^25.5.0"
+ chalk "^3.0.0"
+ graceful-fs "^4.2.4"
+ is-ci "^2.0.0"
+ make-dir "^3.0.0"
+
jest-validate@^24.0.0, jest-validate@^24.8.0:
version "24.8.0"
resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.8.0.tgz#624c41533e6dfe356ffadc6e2423a35c2d3b4849"
@@ -6961,6 +7171,38 @@ jsdom@^11.5.1:
ws "^5.2.0"
xml-name-validator "^3.0.0"
+jsdom@^16.2.1:
+ version "16.2.2"
+ resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.2.2.tgz#76f2f7541646beb46a938f5dc476b88705bedf2b"
+ integrity sha512-pDFQbcYtKBHxRaP55zGXCJWgFHkDAYbKcsXEK/3Icu9nKYZkutUXfLBwbD+09XDutkYSHcgfQLZ0qvpAAm9mvg==
+ dependencies:
+ abab "^2.0.3"
+ acorn "^7.1.1"
+ acorn-globals "^6.0.0"
+ cssom "^0.4.4"
+ cssstyle "^2.2.0"
+ data-urls "^2.0.0"
+ decimal.js "^10.2.0"
+ domexception "^2.0.1"
+ escodegen "^1.14.1"
+ html-encoding-sniffer "^2.0.1"
+ is-potential-custom-element-name "^1.0.0"
+ nwsapi "^2.2.0"
+ parse5 "5.1.1"
+ request "^2.88.2"
+ request-promise-native "^1.0.8"
+ saxes "^5.0.0"
+ symbol-tree "^3.2.4"
+ tough-cookie "^3.0.1"
+ w3c-hr-time "^1.0.2"
+ w3c-xmlserializer "^2.0.0"
+ webidl-conversions "^6.0.0"
+ whatwg-encoding "^1.0.5"
+ whatwg-mimetype "^2.3.0"
+ whatwg-url "^8.0.0"
+ ws "^7.2.3"
+ xml-name-validator "^3.0.0"
+
jsesc@^2.5.1:
version "2.5.2"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
@@ -6971,6 +7213,11 @@ jsesc@~0.5.0:
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=
+json-buffer@3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"
+ integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=
+
json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
@@ -7001,12 +7248,12 @@ json3@^3.3.2:
resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1"
integrity sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=
-json5@2.x, json5@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850"
- integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==
+json5@2.x, json5@^2.1.2:
+ version "2.1.3"
+ resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43"
+ integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==
dependencies:
- minimist "^1.2.0"
+ minimist "^1.2.5"
json5@^1.0.1:
version "1.0.1"
@@ -7144,6 +7391,13 @@ katex@^0.10.0:
dependencies:
commander "^2.16.0"
+keyv@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9"
+ integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==
+ dependencies:
+ json-buffer "3.0.0"
+
killable@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892"
@@ -7190,12 +7444,12 @@ known-css-properties@^0.14.0:
resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.14.0.tgz#d7032b4334a32dc22e6e46b081ec789daf18756c"
integrity sha512-P+0a/gBzLgVlCnK8I7VcD0yuYJscmWn66wH9tlKsQnmVdg689tLEmziwB9PuazZYLkcm07fvWOKCJJqI55sD5Q==
-latest-version@^3.0.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15"
- integrity sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=
+latest-version@^5.0.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face"
+ integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==
dependencies:
- package-json "^4.0.0"
+ package-json "^6.3.0"
lcid@^1.0.0:
version "1.0.0"
@@ -7402,7 +7656,7 @@ lodash.upperfirst@4.3.1:
resolved "https://registry.yarnpkg.com/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz#1365edf431480481ef0d1c68957a5ed99d49f7ce"
integrity sha1-E2Xt9DFIBIHvDRxolXpe2Z1J984=
-lodash@^4.0.0, lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@~4.17.10:
+lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@~4.17.10:
version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
@@ -7437,6 +7691,13 @@ loglevel@^1.6.6:
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.7.tgz#b3e034233188c68b889f5b862415306f565e2c56"
integrity sha512-cY2eLFrQSAfVPhCgH1s7JI73tMbg9YC3v3+ZHVW67sBS7UxWzNEk/ZBbSfLykBWHp33dqqtOv82gjhKEi81T/A==
+lolex@^5.0.0:
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/lolex/-/lolex-5.1.2.tgz#953694d098ce7c07bc5ed6d0e42bc6c0c6d5a367"
+ integrity sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==
+ dependencies:
+ "@sinonjs/commons" "^1.7.0"
+
longest-streak@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.2.tgz#2421b6ba939a443bb9ffebf596585a50b4c38e2e"
@@ -7462,10 +7723,15 @@ lower-case@^1.1.1:
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac"
integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw=
-lowercase-keys@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306"
- integrity sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=
+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"
+ integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==
+
+lowercase-keys@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
+ integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
lowlight@^1.11.0:
version "1.11.0"
@@ -7495,13 +7761,6 @@ lz-string@^1.4.4:
resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26"
integrity sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=
-make-dir@^1.0.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"
- integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==
- dependencies:
- pify "^3.0.0"
-
make-dir@^2.0.0, make-dir@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5"
@@ -7739,23 +7998,28 @@ merge2@^1.2.3:
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5"
integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==
-mermaid@^8.4.8:
- version "8.4.8"
- resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-8.4.8.tgz#8adcfdbc505d6bca52df167cff690427c9727b60"
- integrity sha512-sumTNBFwMX7oMQgogdr3NhgTeQOiwcEsm23rQ4KHGW7tpmvMwER1S+1gjCSSnqlmM/zw7Ga7oesYCYicKboRwQ==
+mermaid@^8.5.2:
+ version "8.5.2"
+ resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-8.5.2.tgz#0f1914cda53d4ea5377380e5ce07a38bef2ea7e8"
+ integrity sha512-I+s+8/RzlazF3dGOhDUfU/ERkUV4zfIlTWb3703jNx+2lfACs+4AdY9ULQaw6BPWzW3gB+XlXFOOX/m/vqujIA==
dependencies:
"@braintree/sanitize-url" "^3.1.0"
crypto-random-string "^3.0.1"
d3 "^5.7.0"
dagre "^0.8.4"
dagre-d3 "^0.6.4"
+ entity-decode "^2.0.2"
graphlib "^2.1.7"
he "^1.2.0"
- lodash "^4.17.11"
minify "^4.1.1"
moment-mini "^2.22.1"
scope-css "^1.2.1"
+mersenne-twister@1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/mersenne-twister/-/mersenne-twister-1.1.0.tgz#f916618ee43d7179efcf641bec4531eb9670978a"
+ integrity sha1-+RZhjuQ9cXnvz2Qb7EUx65Zwl4o=
+
methods@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
@@ -7780,7 +8044,7 @@ micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.6:
snapdragon "^0.8.1"
to-regex "^3.0.2"
-micromatch@^4.0.0:
+micromatch@^4.0.0, micromatch@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259"
integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==
@@ -7823,6 +8087,18 @@ mimic-fn@^2.0.0, mimic-fn@^2.1.0:
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
+mimic-response@^1.0.0, mimic-response@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
+ integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
+
+min-document@^2.19.0:
+ version "2.19.0"
+ resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
+ integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=
+ dependencies:
+ dom-walk "^0.1.0"
+
minify@^4.1.1:
version "4.1.2"
resolved "https://registry.yarnpkg.com/minify/-/minify-4.1.2.tgz#88755f4faa5f7ab6d0c64fdd659aa34ea658f180"
@@ -7871,10 +8147,10 @@ minimist@1.1.x:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.1.3.tgz#3bedfd91a92d39016fcfaa1c681e8faa1a1efda8"
integrity sha1-O+39kaktOQFvz6ocaB6Pqhoe/ag=
-minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
- integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=
+minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5:
+ version "1.2.5"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
+ integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
minipass-collect@^1.0.2:
version "1.0.2"
@@ -7897,14 +8173,6 @@ minipass-pipeline@^1.2.2:
dependencies:
minipass "^3.0.0"
-minipass@^2.2.1, minipass@^2.3.4:
- version "2.3.5"
- resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848"
- integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==
- dependencies:
- safe-buffer "^5.1.2"
- yallist "^3.0.0"
-
minipass@^3.0.0, minipass@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.1.tgz#7607ce778472a185ad6d89082aa2070f79cedcd5"
@@ -7912,13 +8180,6 @@ minipass@^3.0.0, minipass@^3.1.1:
dependencies:
yallist "^4.0.0"
-minizlib@^1.1.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614"
- integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==
- dependencies:
- minipass "^2.2.1"
-
mississippi@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022"
@@ -7960,11 +8221,6 @@ moment-mini@^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@^2.10.2:
- version "2.24.0"
- resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
- integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==
-
monaco-editor-webpack-plugin@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-1.7.0.tgz#920cbeecca25f15d70d568a7e11b0ba4daf1ae83"
@@ -8023,9 +8279,9 @@ mute-stream@0.0.8:
integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
nan@^2.12.1, nan@^2.13.2:
- version "2.14.0"
- resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
- integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
+ version "2.14.1"
+ resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01"
+ integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==
nanomatch@^1.2.9:
version "1.2.13"
@@ -8049,15 +8305,6 @@ natural-compare@^1.4.0:
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
-needle@^2.2.1:
- version "2.4.0"
- resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c"
- integrity sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==
- dependencies:
- debug "^3.2.6"
- iconv-lite "^0.4.4"
- sax "^1.2.4"
-
negotiator@0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
@@ -8163,28 +8410,10 @@ node-notifier@^5.2.1:
shellwords "^0.1.1"
which "^1.3.0"
-node-pre-gyp@^0.12.0:
- version "0.12.0"
- resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149"
- integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==
- dependencies:
- detect-libc "^1.0.2"
- mkdirp "^0.5.1"
- needle "^2.2.1"
- nopt "^4.0.1"
- npm-packlist "^1.1.6"
- npmlog "^4.0.2"
- rc "^1.2.7"
- rimraf "^2.6.1"
- semver "^5.3.0"
- tar "^4"
-
-node-releases@^1.1.49:
- version "1.1.50"
- resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.50.tgz#803c40d2c45db172d0410e4efec83aa8c6ad0592"
- integrity sha512-lgAmPv9eYZ0bGwUYAKlr8MG6K4CvWliWqnkcT2P8mMAgVrH3lqfBPorFlxiG1pHQnqmavJZ9vbMXUTNyMLbrgQ==
- dependencies:
- semver "^6.3.0"
+node-releases@^1.1.53:
+ version "1.1.58"
+ resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.58.tgz#8ee20eef30fa60e52755fcc0942def5a734fe935"
+ integrity sha512-NxBudgVKiRh/2aPWMgPR7bPTX0VPmGx5QBwCtdHitnqFE5/O8DeBXuIMH1nwNnw/aMo6AjOrpsHzfY3UbUJ7yg==
node-sass@^4.12.0:
version "4.12.0"
@@ -8209,21 +8438,21 @@ node-sass@^4.12.0:
stdout-stream "^1.4.0"
"true-case-path" "^1.0.2"
-nodemon@^1.18.9:
- version "1.18.9"
- resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.18.9.tgz#90b467efd3b3c81b9453380aeb2a2cba535d0ead"
- integrity sha512-oj/eEVTEI47pzYAjGkpcNw0xYwTl4XSTUQv2NPQI6PpN3b75PhpuYk3Vb3U80xHCyM2Jm+1j68ULHXl4OR3Afw==
+nodemon@^2.0.4:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.4.tgz#55b09319eb488d6394aa9818148c0c2d1c04c416"
+ integrity sha512-Ltced+hIfTmaS28Zjv1BM552oQ3dbwPqI4+zI0SLgq+wpJhSyqgYude/aZa/3i31VCQWMfXJVxvu86abcam3uQ==
dependencies:
- chokidar "^2.0.4"
- debug "^3.1.0"
+ chokidar "^3.2.2"
+ debug "^3.2.6"
ignore-by-default "^1.0.1"
minimatch "^3.0.4"
- pstree.remy "^1.1.6"
- semver "^5.5.0"
- supports-color "^5.2.0"
+ pstree.remy "^1.1.7"
+ semver "^5.7.1"
+ supports-color "^5.5.0"
touch "^3.1.0"
undefsafe "^2.0.2"
- update-notifier "^2.5.0"
+ update-notifier "^4.0.0"
"nopt@2 || 3":
version "3.0.6"
@@ -8232,14 +8461,6 @@ nodemon@^1.18.9:
dependencies:
abbrev "1"
-nopt@^4.0.1, nopt@~4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d"
- integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=
- dependencies:
- abbrev "1"
- osenv "^0.1.4"
-
nopt@~1.0.10:
version "1.0.10"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee"
@@ -8247,6 +8468,14 @@ nopt@~1.0.10:
dependencies:
abbrev "1"
+nopt@~4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d"
+ integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=
+ dependencies:
+ abbrev "1"
+ osenv "^0.1.4"
+
normalize-package-data@^2.3.2, normalize-package-data@^2.3.4:
version "2.5.0"
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
@@ -8264,7 +8493,7 @@ normalize-path@^2.1.1:
dependencies:
remove-trailing-separator "^1.0.1"
-normalize-path@^3.0.0:
+normalize-path@^3.0.0, normalize-path@~3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
@@ -8279,18 +8508,10 @@ normalize-selector@^0.2.0:
resolved "https://registry.yarnpkg.com/normalize-selector/-/normalize-selector-0.2.0.tgz#d0b145eb691189c63a78d201dc4fdb1293ef0c03"
integrity sha1-0LFF62kRicY6eNIB3E/bEpPvDAM=
-npm-bundled@^1.0.1:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd"
- integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==
-
-npm-packlist@^1.1.6:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.1.tgz#19064cdf988da80ea3cee45533879d90192bbfbc"
- integrity sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==
- dependencies:
- ignore-walk "^3.0.1"
- npm-bundled "^1.0.1"
+normalize-url@^4.1.0:
+ version "4.5.0"
+ resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129"
+ integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==
npm-run-path@^2.0.0:
version "2.0.2"
@@ -8299,7 +8520,7 @@ npm-run-path@^2.0.0:
dependencies:
path-key "^2.0.0"
-"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0, npmlog@^4.0.2:
+"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0:
version "4.1.2"
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==
@@ -8319,10 +8540,10 @@ number-is-nan@^1.0.0:
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
-nwsapi@^2.0.7:
- version "2.0.9"
- resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.0.9.tgz#77ac0cdfdcad52b6a1151a84e73254edc33ed016"
- integrity sha512-nlWFSCTYQcHk/6A9FFnfhKc14c3aFhfdNBXgo8Qgi9QTBu/qg3Ww+Uiz9wMzXd1T8GFxPc2QIHB6Qtf2XFryFQ==
+nwsapi@^2.0.7, nwsapi@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7"
+ integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==
oauth-sign@~0.9.0:
version "0.9.0"
@@ -8531,6 +8752,11 @@ osenv@0, osenv@^0.1.4:
os-homedir "^1.0.0"
os-tmpdir "^1.0.0"
+p-cancelable@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc"
+ integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==
+
p-defer@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c"
@@ -8622,15 +8848,15 @@ p-try@^2.0.0:
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
-package-json@^4.0.0:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed"
- integrity sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=
+package-json@^6.3.0:
+ version "6.5.0"
+ resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0"
+ integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==
dependencies:
- got "^6.7.1"
- registry-auth-token "^3.0.1"
- registry-url "^3.0.3"
- semver "^5.1.0"
+ got "^9.6.0"
+ registry-auth-token "^4.0.0"
+ registry-url "^5.0.0"
+ semver "^6.2.0"
pako@~1.0.2, pako@~1.0.5:
version "1.0.6"
@@ -8715,10 +8941,10 @@ parse5@4.0.0:
resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608"
integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==
-parse5@^5:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.0.0.tgz#4d02710d44f3c3846197a11e205d4ef17842b81a"
- integrity sha512-0ywuiUOnpWWeil5grH2rxjyTJoeQVwyBuO2si6QIU9dWtj2npjuyK1HaY1RbLnVfDhEbhyAPNUBKRK0Xj2xE0w==
+parse5@5.1.1, parse5@^5:
+ version "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"
@@ -8776,7 +9002,7 @@ path-is-absolute@^1.0.0:
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
-path-is-inside@^1.0.1, path-is-inside@^1.0.2:
+path-is-inside@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=
@@ -8843,10 +9069,10 @@ performance-now@^2.1.0:
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
-picomatch@^2.0.4, picomatch@^2.0.5:
- version "2.0.7"
- resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.0.7.tgz#514169d8c7cd0bdbeecc8a2609e34a7163de69f6"
- integrity sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA==
+picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1:
+ version "2.2.2"
+ resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad"
+ integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==
pify@^2.0.0:
version "2.3.0"
@@ -8915,6 +9141,13 @@ pkg-dir@^4.1.0:
dependencies:
find-up "^4.0.0"
+pkg-up@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f"
+ integrity sha1-yBmscoBZpGHKscOImivjxJoATX8=
+ dependencies:
+ find-up "^2.1.0"
+
pn@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb"
@@ -8930,15 +9163,15 @@ pofile@^1:
resolved "https://registry.yarnpkg.com/pofile/-/pofile-1.0.11.tgz#35aff58c17491d127a07336d5522ebc9df57c954"
integrity sha512-Vy9eH1dRD9wHjYt/QqXcTz+RnX/zg53xK+KljFSX30PvdDMb2z+c6uDUeblUGqqJgz3QFsdlA0IJvHziPmWtQg==
-popper.js@^1.16.0, popper.js@^1.16.1:
+popper.js@^1.16.1:
version "1.16.1"
resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b"
integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==
-portal-vue@^2.1.6:
- version "2.1.6"
- resolved "https://registry.yarnpkg.com/portal-vue/-/portal-vue-2.1.6.tgz#a7d4790b14a79af7fd159a60ec88c30cddc6c639"
- integrity sha512-lvCF85D4e8whd0nN32D8FqKwwkk7nYUI3Ku8UAEx4Z1reomu75dv5evRUTZNaj1EalxxWNXiNl0EHRq36fG8WA==
+portal-vue@^2.1.6, portal-vue@^2.1.7:
+ version "2.1.7"
+ resolved "https://registry.yarnpkg.com/portal-vue/-/portal-vue-2.1.7.tgz#ea08069b25b640ca08a5b86f67c612f15f4e4ad4"
+ integrity sha512-+yCno2oB3xA7irTt0EU5Ezw22L2J51uKAacE/6hMPMoO/mx3h4rXFkkBkT4GFsMDv/vEe8TNKC3ujJJ0PTwb6g==
portfinder@^1.0.25:
version "1.0.25"
@@ -9099,16 +9332,7 @@ postcss-value-parser@^4.0.0:
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.0.tgz#99a983d365f7b2ad8d0f9b8c3094926eab4b936d"
integrity sha512-ESPktioptiSUchCKgggAkzdmkgzKfmp0EU8jXH+5kbIUB+unr0Y4CY9SRMvibuvYUBjNh1ACLbxqYNpdTQOteQ==
-postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.27, postcss@^7.0.7:
- version "7.0.27"
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.27.tgz#cc67cdc6b0daa375105b7c424a85567345fc54d9"
- integrity sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==
- dependencies:
- chalk "^2.4.2"
- source-map "^0.6.1"
- supports-color "^6.1.0"
-
-postcss@^7.0.5, postcss@^7.0.6:
+postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.27, postcss@^7.0.5, postcss@^7.0.6, postcss@^7.0.7:
version "7.0.30"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.30.tgz#cc9378beffe46a02cbc4506a0477d05fcea9a8e2"
integrity sha512-nu/0m+NtIzoubO+xdAlwZl/u5S5vi/y6BCsoL8D+8IxsD3XvBS8X4YEADNIVXKVuQvduiucnRv+vPIqj56EGMQ==
@@ -9122,10 +9346,10 @@ prelude-ls@~1.1.2:
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=
-prepend-http@^1.0.1:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
- integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=
+prepend-http@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
+ integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
prettier@1.16.3:
version "1.16.3"
@@ -9163,7 +9387,7 @@ prismjs@^1.6.0:
optionalDependencies:
clipboard "^1.5.5"
-private@^0.1.6:
+private@^0.1.8:
version "0.1.8"
resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==
@@ -9340,15 +9564,15 @@ pseudomap@^1.0.2:
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM=
-psl@^1.1.24:
- version "1.1.29"
- resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67"
- integrity sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==
+psl@^1.1.28:
+ version "1.8.0"
+ resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
+ integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==
-pstree.remy@^1.1.6:
- version "1.1.6"
- resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.6.tgz#73a55aad9e2d95814927131fbf4dc1b62d259f47"
- integrity sha512-NdF35+QsqD7EgNEI5mkI/X+UwaxVEbQaz9f4IooEmMUv6ZPmlTQYGjBPJGgrlzNdjSvIy4MWMg6Q6vCgBO2K+w==
+pstree.remy@^1.1.7:
+ version "1.1.8"
+ resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a"
+ integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==
public-encrypt@^4.0.0:
version "4.0.0"
@@ -9386,21 +9610,23 @@ pumpify@^1.3.3:
inherits "^2.0.3"
pump "^2.0.0"
-punycode@1.3.2:
+punycode@1.3.2, punycode@^1.2.4:
version "1.3.2"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=
-punycode@^1.2.4, punycode@^1.4.1:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
- integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
-
-punycode@^2.1.0:
+punycode@^2.1.0, punycode@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
+pupa@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.0.1.tgz#dbdc9ff48ffbea4a26a069b6f9f7abb051008726"
+ integrity sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA==
+ dependencies:
+ escape-goat "^2.0.0"
+
qjobs@^1.1.4:
version "1.2.0"
resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071"
@@ -9481,7 +9707,7 @@ raw-loader@^4.0.0:
loader-utils "^1.2.3"
schema-utils "^2.5.0"
-rc@^1.0.1, rc@^1.1.6, rc@^1.2.7, rc@~1.2.7:
+rc@^1.2.8, rc@~1.2.7:
version "1.2.8"
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
@@ -9597,21 +9823,12 @@ readdir-enhanced@^2.2.4:
call-me-maybe "^1.0.1"
glob-to-regexp "^0.4.0"
-readdirp@^2.2.1:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525"
- integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==
+readdirp@~3.4.0:
+ version "3.4.0"
+ resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.4.0.tgz#9fdccdf9e9155805449221ac645e8303ab5b9ada"
+ integrity sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==
dependencies:
- graceful-fs "^4.1.11"
- micromatch "^3.1.10"
- readable-stream "^2.0.2"
-
-readdirp@^3.1.1:
- version "3.1.1"
- resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.1.1.tgz#b158123ac343c8b0f31d65680269cc0fc1025db1"
- integrity sha512-XXdSXZrQuvqoETj50+JAitxz1UPdt5dupjT6T5nVB+WvjMv2XKYj+s7hPeAVCXvmJrL36O4YYyWlIC3an2ePiQ==
- dependencies:
- picomatch "^2.0.4"
+ picomatch "^2.2.1"
realpath-native@^1.1.0:
version "1.1.0"
@@ -9636,10 +9853,10 @@ redent@^2.0.0:
indent-string "^3.0.0"
strip-indent "^2.0.0"
-regenerate-unicode-properties@^8.1.0:
- version "8.1.0"
- resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e"
- integrity sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==
+regenerate-unicode-properties@^8.2.0:
+ version "8.2.0"
+ resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec"
+ integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==
dependencies:
regenerate "^1.4.0"
@@ -9648,12 +9865,18 @@ regenerate@^1.4.0:
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11"
integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==
-regenerator-transform@^0.14.0:
- version "0.14.1"
- resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.1.tgz#3b2fce4e1ab7732c08f665dfdb314749c7ddd2fb"
- integrity sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ==
+regenerator-runtime@^0.13.4:
+ version "0.13.5"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697"
+ integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==
+
+regenerator-transform@^0.14.2:
+ version "0.14.4"
+ resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.4.tgz#5266857896518d1616a78a0479337a30ea974cc7"
+ integrity sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw==
dependencies:
- private "^0.1.6"
+ "@babel/runtime" "^7.8.4"
+ private "^0.1.8"
regex-not@^1.0.0, regex-not@^1.0.2:
version "1.0.2"
@@ -9668,42 +9891,41 @@ regexpp@^2.0.1:
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f"
integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==
-regexpu-core@^4.6.0:
- version "4.6.0"
- resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.6.0.tgz#2037c18b327cfce8a6fea2a4ec441f2432afb8b6"
- integrity sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==
+regexpu-core@^4.7.0:
+ version "4.7.0"
+ resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.0.tgz#fcbf458c50431b0bb7b45d6967b8192d91f3d938"
+ integrity sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==
dependencies:
regenerate "^1.4.0"
- regenerate-unicode-properties "^8.1.0"
- regjsgen "^0.5.0"
- regjsparser "^0.6.0"
+ regenerate-unicode-properties "^8.2.0"
+ regjsgen "^0.5.1"
+ regjsparser "^0.6.4"
unicode-match-property-ecmascript "^1.0.4"
- unicode-match-property-value-ecmascript "^1.1.0"
+ unicode-match-property-value-ecmascript "^1.2.0"
-registry-auth-token@^3.0.1:
- version "3.3.2"
- resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20"
- integrity sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==
+registry-auth-token@^4.0.0:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.1.1.tgz#40a33be1e82539460f94328b0f7f0f84c16d9479"
+ integrity sha512-9bKS7nTl9+/A1s7tnPeGrUpRcVY+LUh7bfFgzpndALdPfXQBfQV77rQVtqgUV3ti4vc/Ik81Ex8UJDWDQ12zQA==
dependencies:
- rc "^1.1.6"
- safe-buffer "^5.0.1"
+ rc "^1.2.8"
-registry-url@^3.0.3:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942"
- integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI=
+registry-url@^5.0.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009"
+ integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==
dependencies:
- rc "^1.0.1"
+ rc "^1.2.8"
-regjsgen@^0.5.0:
- version "0.5.0"
- resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.0.tgz#a7634dc08f89209c2049adda3525711fb97265dd"
- integrity sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==
+regjsgen@^0.5.1:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733"
+ integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==
-regjsparser@^0.6.0:
- version "0.6.0"
- resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.0.tgz#f1e6ae8b7da2bae96c99399b868cd6c933a2ba9c"
- integrity sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==
+regjsparser@^0.6.4:
+ version "0.6.4"
+ resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272"
+ integrity sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==
dependencies:
jsesc "~0.5.0"
@@ -9789,26 +10011,26 @@ replace-ext@1.0.0:
resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb"
integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=
-request-promise-core@1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6"
- integrity sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=
+request-promise-core@1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.3.tgz#e9a3c081b51380dfea677336061fea879a829ee9"
+ integrity sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==
dependencies:
- lodash "^4.13.1"
+ lodash "^4.17.15"
-request-promise-native@^1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.5.tgz#5281770f68e0c9719e5163fd3fab482215f4fda5"
- integrity sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=
+request-promise-native@^1.0.5, request-promise-native@^1.0.8:
+ version "1.0.8"
+ resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.8.tgz#a455b960b826e44e2bf8999af64dff2bfe58cb36"
+ integrity sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==
dependencies:
- request-promise-core "1.1.1"
- stealthy-require "^1.1.0"
- tough-cookie ">=2.3.3"
+ request-promise-core "1.1.3"
+ stealthy-require "^1.1.1"
+ tough-cookie "^2.3.3"
-request@^2.87.0, request@^2.88.0:
- version "2.88.0"
- resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef"
- integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==
+request@^2.87.0, request@^2.88.0, request@^2.88.2:
+ version "2.88.2"
+ resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
+ integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
dependencies:
aws-sign2 "~0.7.0"
aws4 "^1.8.0"
@@ -9817,7 +10039,7 @@ request@^2.87.0, request@^2.88.0:
extend "~3.0.2"
forever-agent "~0.6.1"
form-data "~2.3.2"
- har-validator "~5.1.0"
+ har-validator "~5.1.3"
http-signature "~1.2.0"
is-typedarray "~1.0.0"
isstream "~0.1.2"
@@ -9827,7 +10049,7 @@ request@^2.87.0, request@^2.88.0:
performance-now "^2.1.0"
qs "~6.5.2"
safe-buffer "^5.1.2"
- tough-cookie "~2.4.3"
+ tough-cookie "~2.5.0"
tunnel-agent "^0.6.0"
uuid "^3.3.2"
@@ -9915,6 +10137,13 @@ resolve@1.x, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.3.2,
dependencies:
path-parse "^1.0.6"
+responselike@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7"
+ integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=
+ 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"
@@ -9938,7 +10167,7 @@ rfdc@^1.1.4:
resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.1.4.tgz#ba72cc1367a0ccd9cf81a870b3b58bd3ad07f8c2"
integrity sha512-5C9HXdzK8EAqN7JDif30jqsBzavB7wLpaubisuQIGHWf2gUXSpzy6ArX/+Da8RjFpagWsCn+pIgxTMAmKw9Zug==
-rimraf@2, rimraf@^2.5.4, rimraf@^2.6.0, rimraf@^2.6.1, rimraf@^2.6.3, rimraf@^2.7.1:
+rimraf@2, rimraf@^2.5.4, rimraf@^2.6.0, rimraf@^2.6.3, rimraf@^2.7.1:
version "2.7.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
@@ -10064,6 +10293,13 @@ sax@>=0.6.0, sax@^1.2.4:
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
+saxes@^5.0.0:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d"
+ integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==
+ dependencies:
+ xmlchars "^2.2.0"
+
schema-utils@^0.4.0:
version "0.4.5"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.5.tgz#21836f0608aac17b78f9e3e24daff14a5ca13a3e"
@@ -10128,14 +10364,14 @@ selfsigned@^1.10.7:
dependencies:
node-forge "0.9.0"
-semver-diff@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36"
- integrity sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=
+semver-diff@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b"
+ integrity sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==
dependencies:
- semver "^5.0.3"
+ semver "^6.3.0"
-"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1:
+"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.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==
@@ -10145,7 +10381,7 @@ semver@7.0.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e"
integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==
-semver@^6.0.0, semver@^6.1.2, semver@^6.3.0:
+semver@^6.0.0, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
@@ -10606,7 +10842,7 @@ stdout-stream@^1.4.0:
dependencies:
readable-stream "^2.0.1"
-stealthy-require@^1.1.0:
+stealthy-require@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b"
integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=
@@ -10659,6 +10895,11 @@ streamroller@^1.0.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"
+ integrity sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=
+
string-length@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed"
@@ -10693,14 +10934,14 @@ string-width@^3.0.0, string-width@^3.1.0:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^5.1.0"
-string-width@^4.1.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.1.0.tgz#ba846d1daa97c3c596155308063e075ed1c99aff"
- integrity sha512-NrX+1dVVh+6Y9dnQ19pR0pP4FiEIlUvdTGn8pw6CKTNq5sgib2nIhmUNT5TAmhWmvKr3WcxBcP3E8nWezuipuQ==
+string-width@^4.0.0, string-width@^4.1.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5"
+ integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
- strip-ansi "^5.2.0"
+ strip-ansi "^6.0.0"
string.prototype.trimleft@^2.1.1:
version "2.1.1"
@@ -10761,6 +11002,13 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0:
dependencies:
ansi-regex "^4.1.0"
+strip-ansi@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532"
+ integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==
+ dependencies:
+ ansi-regex "^5.0.0"
+
strip-bom@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e"
@@ -10909,7 +11157,7 @@ supports-color@^2.0.0:
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=
-supports-color@^5.2.0, supports-color@^5.3.0:
+supports-color@^5.3.0, supports-color@^5.5.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
@@ -10943,10 +11191,10 @@ symbol-observable@^1.0.2:
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==
-symbol-tree@^3.2.2:
- version "3.2.2"
- resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6"
- integrity sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=
+symbol-tree@^3.2.2, symbol-tree@^3.2.4:
+ version "3.2.4"
+ resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
+ integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
table@^5.2.3:
version "5.4.4"
@@ -10982,25 +11230,10 @@ tar@^2.0.0:
fstream "^1.0.12"
inherits "2"
-tar@^4:
- version "4.4.8"
- resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d"
- integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==
- dependencies:
- chownr "^1.1.1"
- fs-minipass "^1.2.5"
- minipass "^2.3.4"
- minizlib "^1.1.1"
- mkdirp "^0.5.0"
- safe-buffer "^5.1.2"
- yallist "^3.0.2"
-
-term-size@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69"
- integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=
- dependencies:
- execa "^0.7.0"
+term-size@^2.1.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.0.tgz#1f16adedfe9bdc18800e1776821734086fcc6753"
+ integrity sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw==
terser-webpack-plugin@^1.4.3:
version "1.4.3"
@@ -11094,11 +11327,6 @@ timeago.js@^4.0.2:
resolved "https://registry.yarnpkg.com/timeago.js/-/timeago.js-4.0.2.tgz#724e8c8833e3490676c7bb0a75f5daf20e558028"
integrity sha512-a7wPxPdVlQL7lqvitHGGRsofhdwtkoSXPGATFuSOA2i1ZNQEPLrGnj68vOp2sOJTCFAQVXPeNMX/GctBaO9L2w==
-timed-out@^4.0.0:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f"
- integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=
-
timers-browserify@^2.0.4:
version "2.0.10"
resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae"
@@ -11201,6 +11429,11 @@ to-object-path@^0.3.0:
dependencies:
kind-of "^3.0.2"
+to-readable-stream@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771"
+ integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==
+
to-regex-range@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38"
@@ -11243,13 +11476,22 @@ touch@^3.1.0:
dependencies:
nopt "~1.0.10"
-tough-cookie@>=2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.4.3:
- version "2.4.3"
- resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781"
- integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==
+tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.5.0:
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
+ integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
dependencies:
- psl "^1.1.24"
- punycode "^1.4.1"
+ psl "^1.1.28"
+ punycode "^2.1.1"
+
+tough-cookie@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-3.0.1.tgz#9df4f57e739c26930a018184887f4adb7dca73b2"
+ integrity sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==
+ dependencies:
+ ip-regex "^2.1.0"
+ psl "^1.1.28"
+ punycode "^2.1.1"
tr46@^1.0.1:
version "1.0.1"
@@ -11258,6 +11500,13 @@ tr46@^1.0.1:
dependencies:
punycode "^2.1.0"
+tr46@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.0.2.tgz#03273586def1595ae08fedb38d7733cee91d2479"
+ integrity sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==
+ dependencies:
+ punycode "^2.1.1"
+
tributejs@4.1.3:
version "4.1.3"
resolved "https://registry.yarnpkg.com/tributejs/-/tributejs-4.1.3.tgz#2e1be7d9a1e403ed4c394f91d859812267e4691c"
@@ -11375,6 +11624,11 @@ type-check@~0.3.2:
dependencies:
prelude-ls "~1.1.2"
+type-detect@4.0.8:
+ version "4.0.8"
+ resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
+ integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
+
type-fest@^0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.5.2.tgz#d6ef42a0356c6cd45f49485c3b6281fc148e48a2"
@@ -11393,6 +11647,13 @@ type-is@~1.6.17, type-is@~1.6.18:
media-typer "0.3.0"
mime-types "~2.1.24"
+typedarray-to-buffer@^3.1.5:
+ version "3.1.5"
+ resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
+ integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==
+ dependencies:
+ is-typedarray "^1.0.0"
+
typedarray@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
@@ -11471,10 +11732,10 @@ unicode-match-property-ecmascript@^1.0.4:
unicode-canonical-property-names-ecmascript "^1.0.4"
unicode-property-aliases-ecmascript "^1.0.4"
-unicode-match-property-value-ecmascript@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz#5b4b426e08d13a80365e0d657ac7a6c1ec46a277"
- integrity sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==
+unicode-match-property-value-ecmascript@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531"
+ integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==
unicode-property-aliases-ecmascript@^1.0.4:
version "1.0.4"
@@ -11524,12 +11785,12 @@ unique-slug@^2.0.0:
dependencies:
imurmurhash "^0.1.4"
-unique-string@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a"
- integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=
+unique-string@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d"
+ integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==
dependencies:
- crypto-random-string "^1.0.0"
+ crypto-random-string "^2.0.0"
unist-util-find-all-after@^1.0.2:
version "1.0.2"
@@ -11587,31 +11848,24 @@ unset-value@^1.0.0:
has-value "^0.3.1"
isobject "^3.0.0"
-unzip-response@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97"
- integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=
-
-upath@^1.1.1:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894"
- integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==
-
-update-notifier@^2.5.0:
- version "2.5.0"
- resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6"
- integrity sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==
+update-notifier@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.1.0.tgz#4866b98c3bc5b5473c020b1250583628f9a328f3"
+ integrity sha512-w3doE1qtI0/ZmgeoDoARmI5fjDoT93IfKgEGqm26dGUOh8oNpaSTsGNdYRN/SjOuo10jcJGwkEL3mroKzktkew==
dependencies:
- boxen "^1.2.1"
- chalk "^2.0.1"
- configstore "^3.0.0"
+ boxen "^4.2.0"
+ chalk "^3.0.0"
+ configstore "^5.0.1"
+ has-yarn "^2.1.0"
import-lazy "^2.1.0"
- is-ci "^1.0.10"
- is-installed-globally "^0.1.0"
- is-npm "^1.0.0"
- latest-version "^3.0.0"
- semver-diff "^2.0.0"
- xdg-basedir "^3.0.0"
+ is-ci "^2.0.0"
+ is-installed-globally "^0.3.1"
+ is-npm "^4.0.0"
+ is-yarn-global "^0.3.0"
+ latest-version "^5.0.0"
+ pupa "^2.0.1"
+ semver-diff "^3.1.1"
+ xdg-basedir "^4.0.0"
upper-case@^1.1.1:
version "1.1.3"
@@ -11639,12 +11893,12 @@ url-loader@^3.0.0:
mime "^2.4.4"
schema-utils "^2.5.0"
-url-parse-lax@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73"
- integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=
+url-parse-lax@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c"
+ integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=
dependencies:
- prepend-http "^1.0.1"
+ prepend-http "^2.0.0"
url-parse@^1.4.3:
version "1.4.4"
@@ -11725,6 +11979,11 @@ uuid@3.3.2, uuid@^3.0.1, uuid@^3.3.2:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
+uuid@8.1.0:
+ version "8.1.0"
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.1.0.tgz#6f1536eb43249f473abc6bd58ff983da1ca30d8d"
+ integrity sha512-CI18flHDznR0lq54xBycOVmphdCYnQLKn8abKn7PXUiKUGdEd+/l9LWNJmugXel4hXq7S+RMNl34ecyC9TntWg==
+
v8-compile-cache@2.0.3, v8-compile-cache@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe"
@@ -11896,18 +12155,25 @@ vuex@^3.1.0:
resolved "https://registry.yarnpkg.com/vuex/-/vuex-3.1.0.tgz#634b81515cf0cfe976bd1ffe9601755e51f843b9"
integrity sha512-mdHeHT/7u4BncpUZMlxNaIdcN/HIt1GsGG5LKByArvYG/v6DvHcOxvDCts+7SRdCoIRGllK8IMZvQtQXLppDYg==
-w3c-hr-time@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045"
- integrity sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=
+w3c-hr-time@^1.0.1, w3c-hr-time@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd"
+ integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==
dependencies:
- browser-process-hrtime "^0.1.2"
+ browser-process-hrtime "^1.0.0"
w3c-keyname@^1.1.8:
version "1.1.8"
resolved "https://registry.yarnpkg.com/w3c-keyname/-/w3c-keyname-1.1.8.tgz#4e2219663760fd6535b7a1550f1552d71fc9372c"
integrity sha512-2HAdug8GTiu3b4NYhssdtY8PXRue3ICnh1IlxvZYl+hiINRq0GfNWei3XOPDg8L0PsxbmYjWVLuLj6BMRR/9vA==
+w3c-xmlserializer@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a"
+ integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==
+ dependencies:
+ xml-name-validator "^3.0.0"
+
walker@^1.0.7, walker@~1.0.5:
version "1.0.7"
resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb"
@@ -11915,14 +12181,23 @@ walker@^1.0.7, walker@~1.0.5:
dependencies:
makeerror "1.0.x"
+watchpack-chokidar2@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz#9948a1866cbbd6cb824dea13a7ed691f6c8ddff0"
+ integrity sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==
+ dependencies:
+ chokidar "^2.1.8"
+
watchpack@^1.6.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00"
- integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==
+ version "1.7.2"
+ resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.2.tgz#c02e4d4d49913c3e7e122c3325365af9d331e9aa"
+ integrity sha512-ymVbbQP40MFTp+cNMvpyBpBtygHnPzPkHqoIwRRj/0B8KhqQwV8LaKjtbaxF2lK4vl8zN9wCxS46IFCU5K4W0g==
dependencies:
- chokidar "^2.0.2"
graceful-fs "^4.1.2"
neo-async "^2.5.0"
+ optionalDependencies:
+ chokidar "^3.4.0"
+ watchpack-chokidar2 "^2.0.0"
wbuf@^1.1.0, wbuf@^1.7.3:
version "1.7.3"
@@ -11936,6 +12211,16 @@ webidl-conversions@^4.0.2:
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==
+webidl-conversions@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff"
+ integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==
+
+webidl-conversions@^6.0.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514"
+ integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==
+
webpack-bundle-analyzer@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.6.0.tgz#39b3a8f829ca044682bc6f9e011c95deb554aefd"
@@ -12084,14 +12369,14 @@ websocket-extensions@>=0.1.1:
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.1.tgz#76899499c184b6ef754377c2dbb0cd6cb55d29e7"
integrity sha1-domUmcGEtu91Q3fC27DNbLVdKec=
-whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3:
+whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3, whatwg-encoding@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0"
integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==
dependencies:
iconv-lite "0.4.24"
-whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0:
+whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==
@@ -12114,6 +12399,15 @@ whatwg-url@^7.0.0:
tr46 "^1.0.1"
webidl-conversions "^4.0.2"
+whatwg-url@^8.0.0:
+ version "8.1.0"
+ resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.1.0.tgz#c628acdcf45b82274ce7281ee31dd3c839791771"
+ integrity sha512-vEIkwNi9Hqt4TV9RdnaBPNt+E2Sgmo3gePebCRgZ1R7g6d23+53zCTnuB0amKI4AXq6VM8jj2DUAa0S1vjJxkw==
+ dependencies:
+ lodash.sortby "^4.7.0"
+ tr46 "^2.0.2"
+ webidl-conversions "^5.0.0"
+
which-module@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f"
@@ -12138,12 +12432,12 @@ wide-align@^1.1.0:
dependencies:
string-width "^1.0.2 || 2"
-widest-line@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.0.tgz#0142a4e8a243f8882c0233aa0e0281aa76152273"
- integrity sha1-AUKk6KJD+IgsAjOqDgKBqnYVInM=
+widest-line@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca"
+ integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==
dependencies:
- string-width "^2.1.1"
+ string-width "^4.0.0"
word-wrap@~1.2.3:
version "1.2.3"
@@ -12192,7 +12486,7 @@ wrappy@1:
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
-write-file-atomic@2.4.1, write-file-atomic@^2.0.0:
+write-file-atomic@2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.1.tgz#d0b05463c188ae804396fd5ab2a370062af87529"
integrity sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg==
@@ -12201,6 +12495,16 @@ write-file-atomic@2.4.1, write-file-atomic@^2.0.0:
imurmurhash "^0.1.4"
signal-exit "^3.0.2"
+write-file-atomic@^3.0.0:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8"
+ integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==
+ dependencies:
+ imurmurhash "^0.1.4"
+ is-typedarray "^1.0.0"
+ signal-exit "^3.0.2"
+ typedarray-to-buffer "^3.1.5"
+
write@1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3"
@@ -12222,6 +12526,11 @@ ws@^6.0.0, ws@^6.2.1:
dependencies:
async-limiter "~1.0.0"
+ws@^7.2.3:
+ version "7.3.0"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-7.3.0.tgz#4b2f7f219b3d3737bc1a2fbf145d825b94d38ffd"
+ integrity sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==
+
ws@~3.3.1:
version "3.3.3"
resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2"
@@ -12236,10 +12545,18 @@ x-is-string@^0.1.0:
resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82"
integrity sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=
-xdg-basedir@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4"
- integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=
+xdg-basedir@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13"
+ integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==
+
+xhr-mock@^2.5.1:
+ version "2.5.1"
+ resolved "https://registry.yarnpkg.com/xhr-mock/-/xhr-mock-2.5.1.tgz#c591498a8269cc1ce5fefac20d590357affd348b"
+ integrity sha512-UKOjItqjFgPUwQGPmRAzNBn8eTfIhcGjBVGvKYAWxUQPQsXNGD6KEckGTiHwyaAUp9C9igQlnN1Mp79KWCg7CQ==
+ dependencies:
+ global "^4.3.0"
+ url "^0.11.0"
xml-name-validator@^3.0.0:
version "3.0.0"
@@ -12269,6 +12586,11 @@ xmlbuilder@~9.0.1:
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d"
integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=
+xmlchars@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
+ integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==
+
xmlcreate@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/xmlcreate/-/xmlcreate-1.0.2.tgz#fa6bf762a60a413fb3dd8f4b03c5b269238d308f"
@@ -12304,7 +12626,7 @@ yallist@^2.1.2:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=
-yallist@^3.0.0, yallist@^3.0.2:
+yallist@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9"
integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==